pax_global_header00006660000000000000000000000064122305741260014514gustar00rootroot0000000000000052 comment=0599a6b03e30c47b962ffa6cefa1cda99b5458ec openchange-2.0/000077500000000000000000000000001223057412600134645ustar00rootroot00000000000000openchange-2.0/.gitignore000066400000000000000000000015211223057412600154530ustar00rootroot00000000000000aclocal.m4 *.o *.po *.so.* *.so *~ configure Doxyfile bin/ config.h config.h.in config.log config.mk config.status apidocs/ gen_ndr/ libmapi++.pc libmapi++/Doxyfile libmapi++/examples/foldertree libmapi++/examples/messages libmapi.pc libmapi/Doxyfile libmapi/codepage_lcid.c libmapi/mapicode.c libmapi/version.h libmapiadmin.pc libmapiadmin/Doxyfile libocpf.pc libocpf/Doxyfile libocpf/lex.yy.c libocpf/ocpf.tab.c libocpf/ocpf.tab.h mapicodes_enum.h mapiproxy/Doxyfile mapiproxy/libmapiproxy.pc mapiproxy/libmapiserver.pc mapiproxy/libmapistore.pc mapiproxy/libmapistore/Doxyfile mapiproxy/libmapistore/mapistore_nameid.h mapiproxy/libmapistore/mgmt/gen_ndr/ pyopenchange/mapistore/errors.c setup/mapistore/ stamp-h1 utils/mapitest/Doxyfile utils/mapitest/mapitest_proto.h utils/mapitest/proto.h _trial_temp *.orig *.rej *.pyc samba4 samba-*.tar.gz openchange-2.0/COPYING000066400000000000000000001045131223057412600145230ustar00rootroot00000000000000 GNU GENERAL PUBLIC LICENSE Version 3, 29 June 2007 Copyright (C) 2007 Free Software Foundation, Inc. Everyone is permitted to copy and distribute verbatim copies of this license document, but changing it is not allowed. Preamble The GNU General Public License is a free, copyleft license for software and other kinds of works. The licenses for most software and other practical works are designed to take away your freedom to share and change the works. By contrast, the GNU General Public License is intended to guarantee your freedom to share and change all versions of a program--to make sure it remains free software for all its users. We, the Free Software Foundation, use the GNU General Public License for most of our software; it applies also to any other work released this way by its authors. You can apply it to your programs, too. When we speak of free software, we are referring to freedom, not price. Our General Public Licenses are designed to make sure that you have the freedom to distribute copies of free software (and charge for them if you wish), that you receive source code or can get it if you want it, that you can change the software or use pieces of it in new free programs, and that you know you can do these things. To protect your rights, we need to prevent others from denying you these rights or asking you to surrender the rights. Therefore, you have certain responsibilities if you distribute copies of the software, or if you modify it: responsibilities to respect the freedom of others. For example, if you distribute copies of such a program, whether gratis or for a fee, you must pass on to the recipients the same freedoms that you received. You must make sure that they, too, receive or can get the source code. And you must show them these terms so they know their rights. Developers that use the GNU GPL protect your rights with two steps: (1) assert copyright on the software, and (2) offer you this License giving you legal permission to copy, distribute and/or modify it. For the developers' and authors' protection, the GPL clearly explains that there is no warranty for this free software. For both users' and authors' sake, the GPL requires that modified versions be marked as changed, so that their problems will not be attributed erroneously to authors of previous versions. Some devices are designed to deny users access to install or run modified versions of the software inside them, although the manufacturer can do so. This is fundamentally incompatible with the aim of protecting users' freedom to change the software. The systematic pattern of such abuse occurs in the area of products for individuals to use, which is precisely where it is most unacceptable. Therefore, we have designed this version of the GPL to prohibit the practice for those products. If such problems arise substantially in other domains, we stand ready to extend this provision to those domains in future versions of the GPL, as needed to protect the freedom of users. Finally, every program is threatened constantly by software patents. States should not allow patents to restrict development and use of software on general-purpose computers, but in those that do, we wish to avoid the special danger that patents applied to a free program could make it effectively proprietary. To prevent this, the GPL assures that patents cannot be used to render the program non-free. The precise terms and conditions for copying, distribution and modification follow. TERMS AND CONDITIONS 0. Definitions. "This License" refers to version 3 of the GNU General Public License. "Copyright" also means copyright-like laws that apply to other kinds of works, such as semiconductor masks. "The Program" refers to any copyrightable work licensed under this License. Each licensee is addressed as "you". "Licensees" and "recipients" may be individuals or organizations. To "modify" a work means to copy from or adapt all or part of the work in a fashion requiring copyright permission, other than the making of an exact copy. The resulting work is called a "modified version" of the earlier work or a work "based on" the earlier work. A "covered work" means either the unmodified Program or a work based on the Program. To "propagate" a work means to do anything with it that, without permission, would make you directly or secondarily liable for infringement under applicable copyright law, except executing it on a computer or modifying a private copy. Propagation includes copying, distribution (with or without modification), making available to the public, and in some countries other activities as well. To "convey" a work means any kind of propagation that enables other parties to make or receive copies. Mere interaction with a user through a computer network, with no transfer of a copy, is not conveying. An interactive user interface displays "Appropriate Legal Notices" to the extent that it includes a convenient and prominently visible feature that (1) displays an appropriate copyright notice, and (2) tells the user that there is no warranty for the work (except to the extent that warranties are provided), that licensees may convey the work under this License, and how to view a copy of this License. If the interface presents a list of user commands or options, such as a menu, a prominent item in the list meets this criterion. 1. Source Code. The "source code" for a work means the preferred form of the work for making modifications to it. "Object code" means any non-source form of a work. A "Standard Interface" means an interface that either is an official standard defined by a recognized standards body, or, in the case of interfaces specified for a particular programming language, one that is widely used among developers working in that language. The "System Libraries" of an executable work include anything, other than the work as a whole, that (a) is included in the normal form of packaging a Major Component, but which is not part of that Major Component, and (b) serves only to enable use of the work with that Major Component, or to implement a Standard Interface for which an implementation is available to the public in source code form. A "Major Component", in this context, means a major essential component (kernel, window system, and so on) of the specific operating system (if any) on which the executable work runs, or a compiler used to produce the work, or an object code interpreter used to run it. The "Corresponding Source" for a work in object code form means all the source code needed to generate, install, and (for an executable work) run the object code and to modify the work, including scripts to control those activities. However, it does not include the work's System Libraries, or general-purpose tools or generally available free programs which are used unmodified in performing those activities but which are not part of the work. For example, Corresponding Source includes interface definition files associated with source files for the work, and the source code for shared libraries and dynamically linked subprograms that the work is specifically designed to require, such as by intimate data communication or control flow between those subprograms and other parts of the work. The Corresponding Source need not include anything that users can regenerate automatically from other parts of the Corresponding Source. The Corresponding Source for a work in source code form is that same work. 2. Basic Permissions. All rights granted under this License are granted for the term of copyright on the Program, and are irrevocable provided the stated conditions are met. This License explicitly affirms your unlimited permission to run the unmodified Program. The output from running a covered work is covered by this License only if the output, given its content, constitutes a covered work. This License acknowledges your rights of fair use or other equivalent, as provided by copyright law. You may make, run and propagate covered works that you do not convey, without conditions so long as your license otherwise remains in force. You may convey covered works to others for the sole purpose of having them make modifications exclusively for you, or provide you with facilities for running those works, provided that you comply with the terms of this License in conveying all material for which you do not control copyright. Those thus making or running the covered works for you must do so exclusively on your behalf, under your direction and control, on terms that prohibit them from making any copies of your copyrighted material outside their relationship with you. Conveying under any other circumstances is permitted solely under the conditions stated below. Sublicensing is not allowed; section 10 makes it unnecessary. 3. Protecting Users' Legal Rights From Anti-Circumvention Law. No covered work shall be deemed part of an effective technological measure under any applicable law fulfilling obligations under article 11 of the WIPO copyright treaty adopted on 20 December 1996, or similar laws prohibiting or restricting circumvention of such measures. When you convey a covered work, you waive any legal power to forbid circumvention of technological measures to the extent such circumvention is effected by exercising rights under this License with respect to the covered work, and you disclaim any intention to limit operation or modification of the work as a means of enforcing, against the work's users, your or third parties' legal rights to forbid circumvention of technological measures. 4. Conveying Verbatim Copies. You may convey verbatim copies of the Program's source code as you receive it, in any medium, provided that you conspicuously and appropriately publish on each copy an appropriate copyright notice; keep intact all notices stating that this License and any non-permissive terms added in accord with section 7 apply to the code; keep intact all notices of the absence of any warranty; and give all recipients a copy of this License along with the Program. You may charge any price or no price for each copy that you convey, and you may offer support or warranty protection for a fee. 5. Conveying Modified Source Versions. You may convey a work based on the Program, or the modifications to produce it from the Program, in the form of source code under the terms of section 4, provided that you also meet all of these conditions: a) The work must carry prominent notices stating that you modified it, and giving a relevant date. b) The work must carry prominent notices stating that it is released under this License and any conditions added under section 7. This requirement modifies the requirement in section 4 to "keep intact all notices". c) You must license the entire work, as a whole, under this License to anyone who comes into possession of a copy. This License will therefore apply, along with any applicable section 7 additional terms, to the whole of the work, and all its parts, regardless of how they are packaged. This License gives no permission to license the work in any other way, but it does not invalidate such permission if you have separately received it. d) If the work has interactive user interfaces, each must display Appropriate Legal Notices; however, if the Program has interactive interfaces that do not display Appropriate Legal Notices, your work need not make them do so. A compilation of a covered work with other separate and independent works, which are not by their nature extensions of the covered work, and which are not combined with it such as to form a larger program, in or on a volume of a storage or distribution medium, is called an "aggregate" if the compilation and its resulting copyright are not used to limit the access or legal rights of the compilation's users beyond what the individual works permit. Inclusion of a covered work in an aggregate does not cause this License to apply to the other parts of the aggregate. 6. Conveying Non-Source Forms. You may convey a covered work in object code form under the terms of sections 4 and 5, provided that you also convey the machine-readable Corresponding Source under the terms of this License, in one of these ways: a) Convey the object code in, or embodied in, a physical product (including a physical distribution medium), accompanied by the Corresponding Source fixed on a durable physical medium customarily used for software interchange. b) Convey the object code in, or embodied in, a physical product (including a physical distribution medium), accompanied by a written offer, valid for at least three years and valid for as long as you offer spare parts or customer support for that product model, to give anyone who possesses the object code either (1) a copy of the Corresponding Source for all the software in the product that is covered by this License, on a durable physical medium customarily used for software interchange, for a price no more than your reasonable cost of physically performing this conveying of source, or (2) access to copy the Corresponding Source from a network server at no charge. c) Convey individual copies of the object code with a copy of the written offer to provide the Corresponding Source. This alternative is allowed only occasionally and noncommercially, and only if you received the object code with such an offer, in accord with subsection 6b. d) Convey the object code by offering access from a designated place (gratis or for a charge), and offer equivalent access to the Corresponding Source in the same way through the same place at no further charge. You need not require recipients to copy the Corresponding Source along with the object code. If the place to copy the object code is a network server, the Corresponding Source may be on a different server (operated by you or a third party) that supports equivalent copying facilities, provided you maintain clear directions next to the object code saying where to find the Corresponding Source. Regardless of what server hosts the Corresponding Source, you remain obligated to ensure that it is available for as long as needed to satisfy these requirements. e) Convey the object code using peer-to-peer transmission, provided you inform other peers where the object code and Corresponding Source of the work are being offered to the general public at no charge under subsection 6d. A separable portion of the object code, whose source code is excluded from the Corresponding Source as a System Library, need not be included in conveying the object code work. A "User Product" is either (1) a "consumer product", which means any tangible personal property which is normally used for personal, family, or household purposes, or (2) anything designed or sold for incorporation into a dwelling. In determining whether a product is a consumer product, doubtful cases shall be resolved in favor of coverage. For a particular product received by a particular user, "normally used" refers to a typical or common use of that class of product, regardless of the status of the particular user or of the way in which the particular user actually uses, or expects or is expected to use, the product. A product is a consumer product regardless of whether the product has substantial commercial, industrial or non-consumer uses, unless such uses represent the only significant mode of use of the product. "Installation Information" for a User Product means any methods, procedures, authorization keys, or other information required to install and execute modified versions of a covered work in that User Product from a modified version of its Corresponding Source. The information must suffice to ensure that the continued functioning of the modified object code is in no case prevented or interfered with solely because modification has been made. If you convey an object code work under this section in, or with, or specifically for use in, a User Product, and the conveying occurs as part of a transaction in which the right of possession and use of the User Product is transferred to the recipient in perpetuity or for a fixed term (regardless of how the transaction is characterized), the Corresponding Source conveyed under this section must be accompanied by the Installation Information. But this requirement does not apply if neither you nor any third party retains the ability to install modified object code on the User Product (for example, the work has been installed in ROM). The requirement to provide Installation Information does not include a requirement to continue to provide support service, warranty, or updates for a work that has been modified or installed by the recipient, or for the User Product in which it has been modified or installed. Access to a network may be denied when the modification itself materially and adversely affects the operation of the network or violates the rules and protocols for communication across the network. Corresponding Source conveyed, and Installation Information provided, in accord with this section must be in a format that is publicly documented (and with an implementation available to the public in source code form), and must require no special password or key for unpacking, reading or copying. 7. Additional Terms. "Additional permissions" are terms that supplement the terms of this License by making exceptions from one or more of its conditions. Additional permissions that are applicable to the entire Program shall be treated as though they were included in this License, to the extent that they are valid under applicable law. If additional permissions apply only to part of the Program, that part may be used separately under those permissions, but the entire Program remains governed by this License without regard to the additional permissions. When you convey a copy of a covered work, you may at your option remove any additional permissions from that copy, or from any part of it. (Additional permissions may be written to require their own removal in certain cases when you modify the work.) You may place additional permissions on material, added by you to a covered work, for which you have or can give appropriate copyright permission. Notwithstanding any other provision of this License, for material you add to a covered work, you may (if authorized by the copyright holders of that material) supplement the terms of this License with terms: a) Disclaiming warranty or limiting liability differently from the terms of sections 15 and 16 of this License; or b) Requiring preservation of specified reasonable legal notices or author attributions in that material or in the Appropriate Legal Notices displayed by works containing it; or c) Prohibiting misrepresentation of the origin of that material, or requiring that modified versions of such material be marked in reasonable ways as different from the original version; or d) Limiting the use for publicity purposes of names of licensors or authors of the material; or e) Declining to grant rights under trademark law for use of some trade names, trademarks, or service marks; or f) Requiring indemnification of licensors and authors of that material by anyone who conveys the material (or modified versions of it) with contractual assumptions of liability to the recipient, for any liability that these contractual assumptions directly impose on those licensors and authors. All other non-permissive additional terms are considered "further restrictions" within the meaning of section 10. If the Program as you received it, or any part of it, contains a notice stating that it is governed by this License along with a term that is a further restriction, you may remove that term. If a license document contains a further restriction but permits relicensing or conveying under this License, you may add to a covered work material governed by the terms of that license document, provided that the further restriction does not survive such relicensing or conveying. If you add terms to a covered work in accord with this section, you must place, in the relevant source files, a statement of the additional terms that apply to those files, or a notice indicating where to find the applicable terms. Additional terms, permissive or non-permissive, may be stated in the form of a separately written license, or stated as exceptions; the above requirements apply either way. 8. Termination. You may not propagate or modify a covered work except as expressly provided under this License. Any attempt otherwise to propagate or modify it is void, and will automatically terminate your rights under this License (including any patent licenses granted under the third paragraph of section 11). However, if you cease all violation of this License, then your license from a particular copyright holder is reinstated (a) provisionally, unless and until the copyright holder explicitly and finally terminates your license, and (b) permanently, if the copyright holder fails to notify you of the violation by some reasonable means prior to 60 days after the cessation. Moreover, your license from a particular copyright holder is reinstated permanently if the copyright holder notifies you of the violation by some reasonable means, this is the first time you have received notice of violation of this License (for any work) from that copyright holder, and you cure the violation prior to 30 days after your receipt of the notice. Termination of your rights under this section does not terminate the licenses of parties who have received copies or rights from you under this License. If your rights have been terminated and not permanently reinstated, you do not qualify to receive new licenses for the same material under section 10. 9. Acceptance Not Required for Having Copies. You are not required to accept this License in order to receive or run a copy of the Program. Ancillary propagation of a covered work occurring solely as a consequence of using peer-to-peer transmission to receive a copy likewise does not require acceptance. However, nothing other than this License grants you permission to propagate or modify any covered work. These actions infringe copyright if you do not accept this License. Therefore, by modifying or propagating a covered work, you indicate your acceptance of this License to do so. 10. Automatic Licensing of Downstream Recipients. Each time you convey a covered work, the recipient automatically receives a license from the original licensors, to run, modify and propagate that work, subject to this License. You are not responsible for enforcing compliance by third parties with this License. An "entity transaction" is a transaction transferring control of an organization, or substantially all assets of one, or subdividing an organization, or merging organizations. If propagation of a covered work results from an entity transaction, each party to that transaction who receives a copy of the work also receives whatever licenses to the work the party's predecessor in interest had or could give under the previous paragraph, plus a right to possession of the Corresponding Source of the work from the predecessor in interest, if the predecessor has it or can get it with reasonable efforts. You may not impose any further restrictions on the exercise of the rights granted or affirmed under this License. For example, you may not impose a license fee, royalty, or other charge for exercise of rights granted under this License, and you may not initiate litigation (including a cross-claim or counterclaim in a lawsuit) alleging that any patent claim is infringed by making, using, selling, offering for sale, or importing the Program or any portion of it. 11. Patents. A "contributor" is a copyright holder who authorizes use under this License of the Program or a work on which the Program is based. The work thus licensed is called the contributor's "contributor version". A contributor's "essential patent claims" are all patent claims owned or controlled by the contributor, whether already acquired or hereafter acquired, that would be infringed by some manner, permitted by this License, of making, using, or selling its contributor version, but do not include claims that would be infringed only as a consequence of further modification of the contributor version. For purposes of this definition, "control" includes the right to grant patent sublicenses in a manner consistent with the requirements of this License. Each contributor grants you a non-exclusive, worldwide, royalty-free patent license under the contributor's essential patent claims, to make, use, sell, offer for sale, import and otherwise run, modify and propagate the contents of its contributor version. In the following three paragraphs, a "patent license" is any express agreement or commitment, however denominated, not to enforce a patent (such as an express permission to practice a patent or covenant not to sue for patent infringement). To "grant" such a patent license to a party means to make such an agreement or commitment not to enforce a patent against the party. If you convey a covered work, knowingly relying on a patent license, and the Corresponding Source of the work is not available for anyone to copy, free of charge and under the terms of this License, through a publicly available network server or other readily accessible means, then you must either (1) cause the Corresponding Source to be so available, or (2) arrange to deprive yourself of the benefit of the patent license for this particular work, or (3) arrange, in a manner consistent with the requirements of this License, to extend the patent license to downstream recipients. "Knowingly relying" means you have actual knowledge that, but for the patent license, your conveying the covered work in a country, or your recipient's use of the covered work in a country, would infringe one or more identifiable patents in that country that you have reason to believe are valid. If, pursuant to or in connection with a single transaction or arrangement, you convey, or propagate by procuring conveyance of, a covered work, and grant a patent license to some of the parties receiving the covered work authorizing them to use, propagate, modify or convey a specific copy of the covered work, then the patent license you grant is automatically extended to all recipients of the covered work and works based on it. A patent license is "discriminatory" if it does not include within the scope of its coverage, prohibits the exercise of, or is conditioned on the non-exercise of one or more of the rights that are specifically granted under this License. You may not convey a covered work if you are a party to an arrangement with a third party that is in the business of distributing software, under which you make payment to the third party based on the extent of your activity of conveying the work, and under which the third party grants, to any of the parties who would receive the covered work from you, a discriminatory patent license (a) in connection with copies of the covered work conveyed by you (or copies made from those copies), or (b) primarily for and in connection with specific products or compilations that contain the covered work, unless you entered into that arrangement, or that patent license was granted, prior to 28 March 2007. Nothing in this License shall be construed as excluding or limiting any implied license or other defenses to infringement that may otherwise be available to you under applicable patent law. 12. No Surrender of Others' Freedom. If conditions are imposed on you (whether by court order, agreement or otherwise) that contradict the conditions of this License, they do not excuse you from the conditions of this License. If you cannot convey a covered work so as to satisfy simultaneously your obligations under this License and any other pertinent obligations, then as a consequence you may not convey it at all. For example, if you agree to terms that obligate you to collect a royalty for further conveying from those to whom you convey the Program, the only way you could satisfy both those terms and this License would be to refrain entirely from conveying the Program. 13. Use with the GNU Affero General Public License. Notwithstanding any other provision of this License, you have permission to link or combine any covered work with a work licensed under version 3 of the GNU Affero General Public License into a single combined work, and to convey the resulting work. The terms of this License will continue to apply to the part which is the covered work, but the special requirements of the GNU Affero General Public License, section 13, concerning interaction through a network will apply to the combination as such. 14. Revised Versions of this License. The Free Software Foundation may publish revised and/or new versions of the GNU General Public License from time to time. Such new versions will be similar in spirit to the present version, but may differ in detail to address new problems or concerns. Each version is given a distinguishing version number. If the Program specifies that a certain numbered version of the GNU General Public License "or any later version" applies to it, you have the option of following the terms and conditions either of that numbered version or of any later version published by the Free Software Foundation. If the Program does not specify a version number of the GNU General Public License, you may choose any version ever published by the Free Software Foundation. If the Program specifies that a proxy can decide which future versions of the GNU General Public License can be used, that proxy's public statement of acceptance of a version permanently authorizes you to choose that version for the Program. Later license versions may give you additional or different permissions. However, no additional obligations are imposed on any author or copyright holder as a result of your choosing to follow a later version. 15. Disclaimer of Warranty. THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING, REPAIR OR CORRECTION. 16. Limitation of Liability. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MODIFIES AND/OR CONVEYS THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES. 17. Interpretation of Sections 15 and 16. If the disclaimer of warranty and limitation of liability provided above cannot be given local legal effect according to their terms, reviewing courts shall apply local law that most closely approximates an absolute waiver of all civil liability in connection with the Program, unless a warranty or assumption of liability accompanies a copy of the Program in return for a fee. END OF TERMS AND CONDITIONS How to Apply These Terms to Your New Programs If you develop a new program, and you want it to be of the greatest possible use to the public, the best way to achieve this is to make it free software which everyone can redistribute and change under these terms. To do so, attach the following notices to the program. It is safest to attach them to the start of each source file to most effectively state the exclusion of warranty; and each file should have at least the "copyright" line and a pointer to where the full notice is found. Copyright (C) This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see . Also add information on how to contact you by electronic and paper mail. If the program does terminal interaction, make it output a short notice like this when it starts in an interactive mode: Copyright (C) This program comes with ABSOLUTELY NO WARRANTY; for details type `show w'. This is free software, and you are welcome to redistribute it under certain conditions; type `show c' for details. The hypothetical commands `show w' and `show c' should show the appropriate parts of the General Public License. Of course, your program's commands might be different; for a GUI interface, you would use an "about box". You should also get your employer (if you work as a programmer) or school, if any, to sign a "copyright disclaimer" for the program, if necessary. For more information on this, and how to apply and follow the GNU GPL, see . The GNU General Public License does not permit incorporating your program into proprietary programs. If your program is a subroutine library, you may consider it more useful to permit linking proprietary applications with the library. If this is what you want to do, use the GNU Lesser General Public License instead of this License. But first, please read . openchange-2.0/ChangeLog000066400000000000000000006720131223057412600152470ustar00rootroot000000000000002010-08-29 jkerihuel [r2144] Add CopyProfile and DuplicateProfile to IProfAdmin interface 2010-08-27 jkerihuel [r2142] Add the localaddress patch prior Samba4 integration. Pending new Samba4 localaddress patch fixing memory leaks in the pipe. [r2141] Include a mapitest test suite / challenge for lzxpress The idea of this test is to check if lzxpress compressed blobs provided by OpenChange are the same than Outlook ones. The test takes a Outlook->Exchange capture file with compressed blob, pull the content, decompressed the content, recompress the content and check the output for differing bytes. This challenge code should give us good information when lzxpress compress code is fixed. Additionally you can uncomment the compression code in libmapi/emsmdb.c to do further testing. [r2140] - Add implementation for EcDoRpcExt2 (0xB) RPC opnum. Current code doesn't provide compression for request and use obfuscation instead. However mapi_response makes use of xpress and are decompressed properly. - EcDoRpcExt2 implemented without subcontexts but uint8_t array - add a wrapper for emsmdb transaction to switch between EcDoConnect/EcDoRpc and EcDoConnectEx/EcDoRpcExt2 depending on MAPI profile 'exchange version' attribute. NOTE: emsmdb.c implements the logic for using compressed blob and checks whether compressed or obfuscation should be used depending on blob length. However this behavior has been commented out because comrpessed blobs are rejected by Exchange (ecRpcFormat 0x4B6 error). 2010-08-26 jkerihuel [r2139] Reference profile structure in mapitest structure. Use profile->mailbox instead of szDisplayName for sending mapitest emails. This also fix ResolveNames mapitest issues when conflicts between usernames exist (e.g. user1, user11, user100). bradh [r2137] Prevent segfault if we don't have any appointments. Resolves issue #284. Also prevent leaking talloc context in a couple of error cases. [r2136] Merge Rev 2133 from branches/current-samba4 to trunk. I inadvertently committed this to the wrong branch. This pushes the fix for #229 into trunk. 2010-08-23 jelmer [r2134] Update bzr ignores. 2010-08-18 jkerihuel [r2131] Add a git update case in installsamba.sh script and make it available within OpenChange Makefile. 2010-08-17 jkerihuel [r2127] Manually commit remaining changes from current-samba4 into trunk [r2126] Merge current-samba4 branch back into trunk 2010-08-11 bradh [r2117] Microsoft confirmed that RopGetValidAttachments isn't supported in Exchange 2010. [r2114] fix missing part of r2113. [r2113] Fixes to better work with Exchange 2010. Still some open issues to resolving bug 227. [r2112] Fix handling of "not applicable" tests when using --mapi-calls Prior to this, if you asked for a test that was after a test that was flagged as suppressed, the test you asked for didn't get run, and the flagged test was reported instead. 2010-08-10 bradh [r2111] Correctly handle cases where the start date of the range is after the first calendar appointment. Resolves bug:272. Thanks to Eric Reischer for reporting the problem and testing the fix. 2010-08-03 bradh [r2107] trivial comment cleanup. 2010-08-01 jkerihuel [r2105] Move from auto-generated mapicode.h to static code. [r2104] Add configure.ac support for gthread implementation but give preferences to pthread Add THREAD_CFLAGS to config.mk.in ifdef between pthread and gthread in libmapi_private.h [r2103] Check for libpthread in configure.ac and make this lib optional Add references to config.h in libmapi_private.h Replace references to config.h with libmapi_private.h 2010-07-31 jkerihuel [r2101] - Add an exchange-version parameter to mapiprofile structure and tool which let user choose between 0x0/0x2 or 0xA/0xB - Tweak libmapi implementation to allow EcDoConnectEx usage - Improve mapiprofile --dump to show more useful parameters [r2100] - Add custom NDR implementation for EcDoConnectEx to bypass pointers/array problems - make use of mapi2k7_AuxInfo structure for rgbAuxOut - Create a subcontext for AUX_HEADER structures to jump over unknown cases properly. [r2099] Handle the no obfuscation nor compression RPC_HEADER_EXT flags case bradh [r2098] Trivial api documentation change. 2010-07-29 bradh [r2095] Another trivial API documentation fix. [r2094] More trivial API documentation fixes. [r2093] Minor API documentation fix. [r2092] Implement some null pointer checks. Also rewords some API documentation. Original issue and patch by Erik Hovland - thanks again. I implemented it with some slight changes. 2010-07-28 bradh [r2090] Fix RecipientRow IDL to match MS-OXCDATA 2.9.3 This allows handling of addresses that contain X400 format content. Patch by Samuel Sieb and I, resolves ticket #250. 2010-07-26 jkerihuel [r2087] Fix a crash in openchangeclient vs Exchange 2010: When Queryrows is called on Exchange 2010 and no rows are available, QueryRows returns MAPI_E_NOT_IMPLEMENTED error (0x8004FFFF). Ensure we have at least one message to fetch in openchangeclient --fetchmail prior calling QueryRows. 2010-07-24 jkerihuel [r2079] Very basic use of OpenUserMailbox in openchangeclient. Doesn't handle clustered Exchange servers. bradh [r2077] Rename a few function arguments to avoid doxygen warnings. This is a workaround, but will allow easier checking for the future. [r2076] Update doxygen configuration to match latest version [r2075] Add missing doxygen parameter information. [r2074] Fix a couple of doxygen issues. 2010-07-23 jkerihuel [r2072] Use sed in Makefile to replace local headers reference in installed headers [r2071] Use local headers rather than installed ones Propagate this behavior to torture test suites and bindings [r2070] Remove libmapi/defs_private.h Remove references to libmapi/defs_private.h in OpenChange tree [r2069] Remove auto-generated headers for libmapi: - Add libmapi_private.h for private definitions - Use libmapi.h for public definitions - Merge libmapi_private.h and defs_private.h Use local headers rather than installed ones Change libmapi compilation list to have ndr_exchange_c.h available for other libmapi C files. Remove references to libmapi/proto_private.h in OpenChange tree Remove references to libmapi/defs_private.h in OpenChange tree 2010-07-20 bradh [r2065] Modify the samba build script to make it more flexible. Heavily based on changes provided by Andrew Tridgell. Thanks! 2010-07-15 jkerihuel [r2063] Use local includes rather than installed ones for openchange tools/utils [r2062] Use local includes rather than installed ones for mparse.pl [r2061] Use local includes rather than installed ones for mapiproxy and server components [r2060] Use local includes rather than installed ones [r2059] Use local includes rather than installed ones for libexchange2ical Sanitize function declarations [r2058] Remove proto and proto_private.h from ignore list [r2057] Remove auto-generated headers for libmapiadmin Use local includes rather than installed ones for libmapiadmin [r2056] Remove proto and proto_private.h from ignore list [r2055] Remove auto-generated headers for libocpf Use local includes rather than installed ones for libocpf [r2054] Fix bug #248 misnamed PR_RECIPIENTS_FLAGS [r2053] Add IDL implementation for WritePerUserInformation. Note: This IDL suffers from the same problems than SetMessageReadFlags. It depends on logon_id and Logon flags. 2010-07-14 jkerihuel [r2051] Add server-side preliminary ReloadCachedInformation implementation. The Rop only support a specific case and it is expected to work better after integration of the OCPF contexts for message transaction. [r2050] Missing header for stat() 2010-07-06 bradh [r2048] Implement RopSetReceiveFolder There is a part of this missing (relating to modification times) that will be implemented as part of the RopGetReceiveFolderTable implementation. This updates the mapitest code, including a change to the function signature for the mapitest_print_retval_step() function to take an explicit MAPISTATUS value instead of relying on GetLastError(). 2010-07-04 bradh [r2046] Enhance the GetReceiveFolder ROP. This now tries all available MessageClass entries. [r2045] Enhance GetReceiveFolder mapitest. 2010-07-03 bradh [r2043] Make sure objects are correctly init()'d and release()'d even in fault condition. [r2042] Make sure objects are correctly init()'d and release()'d even in failure case. [r2041] Make sure all objects are initialised, even in failure cases. [r2040] Trivial comment change. [r2039] Add a few more null pointer protections into fsocpf backend. Trying to get mapitest running... 2010-07-02 bradh [r2037] Add mapitest unit test for DeleteMessages with multiple messages. [r2036] Implement DeleteMessages ROP. Adds message deletion support to mapistore core and fsocpf backend. I've been testing this with OXCMSG-SAVE-CHANGES-MESSAGE from mapitest. [r2035] Make it a bit easier to use alternative GIT tree. [r2034] Ensure we return the correct MID from SaveChangesMessage 2010-06-28 jkerihuel [r2031] Fix a segfault when releasing handles. We kept processing the handles list after releasing the element. bradh [r2030] Add some simple tests for openchangeclient. [r2029] Unbreak compilation problems from previous commit. [r2028] Ensure we don't duplicate folder names. This adds appropriate checks for both system (openchangedb) and normal (mapistore) folders. The mapitest code also checks that the OPEN_IF_EXISTS flag works. I had to add an additional mapitest_print_retval() variation, since successful operations don't reset errno. 2010-06-26 jkerihuel [r2026] add support for PT_CLSID and PT_SVREID in cast_mapi_SPropValue [r2024] Add a memory context argument to cast_mapi_SPropValue to be less dependent to libmapi and allow better memory allocation handling. Propagate API change among OpenChange source tree Add doxygen documentation for cast_mapi_SPropValue bradh [r2025] Make sure we always set the opnum and handle, even for error cases. [r2023] Suppress compilation noise in a few places for consistency with the rest of the Makefile 2010-06-25 jkerihuel [r2022] Add ocpf_write support for PT_MV_STRING8, PT_MV_UNICODE, PR_MV_BINARY and PT_MV_LONG [r2021] - Add documentation for PT_MV_LONG - Update PT_BINARY section [r2020] - Fix PT_BINARY to now parse uint8_t 0x00 - 0xFF instead of previous (and incorrect) long items - Add implementation for PT_MV_LONG - Clean up useless code [r2018] Add mapidump_SPropValue for PT_MV_LONG [r2017] Add support for PT_MV_UNICODE type [r2016] Add mapidump_SPropValue for PT_MV_UNICODE [r2015] Add support for PT_MV_BINARY type This implementation required to add a Binary_r within ocpf_context to union SPropValue_CTR content consistent among recursive parsing. [r2014] Add PT_MV_BINARY support in cast_SPropValue [r2013] Add mapidump_SPropValue entry for PT_MV_BINARY [r2012] Do not search context if context_id is NULL [r2011] - Add a function to synchronize data on filesystem after a write commit (close/fopen) and change open and context flags depending on their previous value. - If PR_MESSAGE_CLASS or PR_MESSAGE_CLASS_UNICODE is used for set_SPropValue, update context type. 2010-06-23 jkerihuel [r2009] Fix warnings generating by the incorrect .tp_new first argument type [r2007] - Implement server-side skeleton for ReadPerUserInformation (0x63) [r2006] - Use external TALLOC context for cast_SPropValue rather than global_mapi_ctx->mem_ctx. This was preventing from using this function properly in a context different from libmapi based application (server). - Add cast_SPropValue support for PT_CLSID and PT_MV_LONG - add message path + id in the indexing database for mapistore case in SaveChangesMessage [r2005] Add default owner/full rights to new root folders created. Works with Outlook 2003 (shift + delete for hard delete) [r2004] Add PT_SRVEID support in SPropValue (0xFB proptype) [r2003] Add owner / full-access rights for mailbox folders. It introduces less stabilitity but offers wider range of available features. [r2002] Generate PidTagRights for PR_RIGHTS (used in openchangedb) 2010-06-22 jkerihuel [r2001] - Complete fsocpf_get_path implementation - Register message into indexing.tdb after SubmitMessage [r2000] Add ocpf_server_set_type python bindings. Ohhh looks like we have reached r2000 ;-) .-. , `._ , \ \ o \ `-,. .'o . `.[] o <~- - , ,[].'.[] ~> ___ : : (-~.) ` ' `|' ` ' | `-. .-' | -----{. _ _ .}------------------- [r1998] - Add SetProps server side implementation for mapistore messages - Add a preliminary set of properties within CreateMessage (not complete yet) as stated in MS-OXCMSG 3.2.5.2 - Add SaveChangeMessages preliminary server side implementation - Add SubmitMessage preliminary server side implementation - add mapistore and fsocpf backend implementation for SaveChangeMessages and SubmitMessage. Note: SubmitMesage is just a hack for now. [r1997] - Add a wrapper to set OCPF file TYPE - Free/Allocate type on purpose [r1996] storing a mapistore_message within the message object is useless for the moment. Clean-up this bit introduced with last commit. [r1995] - Add preliminary OCPF API for server purposes (used by mapistore_fsocpf) - ocpf_server API now allows caller to dynamically update properties. If the properties was already existing, updates its value. - Update ocpf_test.py to reflect this behavior - Add preliminary server side implementation for CreateMessage (server + mapistore + fsocpf backedn) - Add preliminary mapistore + fsocpf backend skeleton for SetProps operation bradh [r1994] Typo fix in constant name. 2010-06-21 jkerihuel [r1993] - Only prevent file opened in read-only to use write_commit - Position the stream at the beginning of the file before writing [r1992] Defer ocpf file creation (fopen with w+) to ocpf_write_commit [r1990] Add rmdir support to mapistore python bindings [r1989] - Add mapistore python C/API support for: - add_context_indexing - add_context_ref_count - opendir - closedir - mkdir - errstr MAPISTORE error to string conversion - Update mapistore python test script to demonstrate how to create a new folder using mapistore [r1988] I may be wrong here, but that was the only way I could pass a folderID from python's layer to mapistore C/API [r1987] If context is manually deleted using public API, we need to remove the destructor we set during context init, otherwise talloc_free segfault occurs [r1986] talloc_strdup SPropValue strings [r1985] Add preliminary python bindings for mapistore 2010-06-20 jkerihuel [r1984] Add FILETIME support for SPropValue [r1982] Add TypeCheck on SPropValue rather than blind cast [r1981] Add python binding for ocpf_write Add quick test code to ensure it works as expected [r1980] - Use SPropValue python object in ocpf module - Add a function binding to retrieve SPropValue array from OCPF file - Modify sample to test this behavior [r1979] - Move OCPF python bindings to pyopenchange directory - Install ocpf module within openchange/ [r1978] - Check property type for SPropValue - Add auto-generated pyopenchange/pymapi_properties.c to the ignore list [r1977] - Add preliminary OCPF python bindings - Add a new pyopenchange python bindings directory: - Preliminary handling of SPropValue data structure - Add some python bindings test files - Add a mparse parser to generate python bindings declaration for mapi properties - Build automatically python bindings ** We need to add Python as a required dependency ** bradh [r1976] Implement EmptyFolder and enhance DeleteFolder. This still has quite a way to go, but it does mostly work for folders, including recursion. [r1975] Add extended test code for folder creation / deletion. [r1974] Add libmapiserver support for EmptyFolder size calculations. 2010-06-19 bradh [r1972] Trivial typo fix. [r1971] Fix comment. 2010-06-17 jkerihuel [r1969] New test. [r1968] Second test commit. [r1967] Test commit 2010-06-16 jkerihuel [r1964] Fix OOM used in sample_appointment.ocpf [r1963] Consolidate PSETID array and rely on libmapi definitions. 2010-06-14 jkerihuel [r1958] Add server-side skeleton for WriteStream Rop. [r1957] Add server-side skeleton for SetSearchCriteria and GetSearchCritera Rop. Improve GetSearchCriteria IDL and work around the null restriction response size in GetSearchCriteria reply by tweaking generated code into nopull,nopush,noprint Add generated mapistore ldif file to the ignore list [r1955] - Add preliminary implementation for named properties support in mapistore. The API is yet very preliminary (init + get mapped property ID), but is enough to return consistent data to Outlook and make its behavior more reliable. - mparse.pl now generates a LDIF file for the mapistore namedprops LDB database which maps named properties within namespaces and store default values for common/standard named properties Outlook is using. - add a custom ldb_connect wrapper in mapistore to allow mapistore to open multiple instances of the same mapi named properties ldb database. - Complete preliminary implementation of GetIDsFromNames in oxcprpt.c. 2010-06-13 jkerihuel [r1944] - Fix some named properties - Add a referenced propID value once it is mapped. Will be used by mapistore to populate/generate the initial nameid props database [r1938] Fix a bug with unmapped named properties lookup. For convenience purposes GetProps accepts within input SPropTagArray unmapped named properties we internally turn into mapped ones using GetIDsFroNames. This behavior was incorrect cause we were looking for properties within specific ranges. Replace this behavior with a global lookup over named properties we know about. One limitation of this fix is that custom nameid properties (not referenced within libmapi/conf/mapi-named-properties) won't be lookup. However it is acceptable for the moment. bradh [r1943] Fix signed / unsigned issue in openchangebackup utility. [r1942] Fix some signed/unsigned issues in libmapi. [r1941] Fix up signed / unsigned issues with libocpf. This changes the API to allow easy testing of failure vs results. [r1940] make sure that the 0 is interpreted as unsigned. [r1939] Fix a signed / unsigned comparison warning in libmapi. [r1937] Fix some signed / unsigned warnings in torture suite. [r1936] Avoid signed / unsigned comparison in libmapiadmin. [r1935] Avoid signed / unsigned comparison in openchangedb. [r1934] Avoid signed / unsigned comparisions in mapitest [r1933] Avoid signed / unsigned comparisons in FSOCPF backend. [r1932] Fill in initialisers. Avoids warning with gcc's -Wmissing-field-initializers option. jelmer [r1947] Fix imports, clean up. [r1946] Raise exception on invalid arguments to openchange_mapistore_url. 2010-06-12 jkerihuel [r1931] Fix duplicate bradh [r1930] Use calculated len inside the loop, instead of calling strlen each time. 2010-06-11 jkerihuel [r1929] Add new properties and PSETID 2010-06-10 bradh [r1928] Change variable name to avoid shadowed variable name warning with ICC. [r1927] Add newline at end of file to avoid compiler warning with ICC. 2010-06-09 bradh [r1922] Ensure server modules work when building with coverage enabled. jelmer [r1925] Consistently use spaces rather than tabs. [r1924] Remove string exception. [r1923] Remove duplication of openchange name in namespace. 2010-06-08 jkerihuel [r1921] We didn't set a valid error_code for FindRow skeleton. [r1920] - Add server-side skeleton for ReadStream ROP. - Add preliminary sanity checks on server-side FindRow 2010-06-07 jkerihuel [r1919] Activate correct handling of retval in CreateFolder, despite Outlook 2007 bad behavior. Currently working on fixing this. [r1918] My small Outlook 2007 'Search missing ROP implementation' shouldn't have been pushed ;-) [r1917] Add server-side skeleton for DeleteProperties Rop. [r1916] Implement server-size skeleton for GetPerUserGuid Rop. [r1915] Add server-side skeleton for GetPerUserLongTermIds Rop. [r1914] Add a preliminary stream object implementation Add stream to emsmdbp convenient functions Create a handle in OpenStream [r1913] Add skeleton server side implementation for OpenStream [r1912] Forgot to redo changes here. [r1911] - Undo the SetMessageReadFlag IDL change and add an explanation, so we don't make the same error twice and have pointers when we want to fix it. - Improve OpenMessage IDL and add the Reserved uint16_t bit. - Replace sizeof() with known types to prevent from IDL mismatch types getting used. [r1910] For single process implementation, this code was fine. For multi-process/contexts, when we need to cache information to limit disk access, we should be using the ocpf element as a memory context. This patch makes it possible. [r1909] Fix SetMessageReadFlag IDL. [r1908] Add server side skeleton for SetMessageReadFlag Rop. [r1907] the previous "or"ed value used in LogonType union was non handled properly by pidl. Replace them with static values instead. This prevent Outlook rom reconnecting in different situations. [r1906] This was causing the ndr push error. Outlook now receive OpenMessage replies. 2010-06-06 jkerihuel [r1905] With current implementation messages loaded and added to the mapistore fsocpf private list were never released/unloaded/free'd. Similar behavior would have occured in the future with folders. Add a mapistore release_record function which will free/delete information/data associated to a given folder/message. [r1904] - Add a preliminary OpenMessage reply implementation - Add a function to resolve recipients against AD - Add implementation of GetProps for mapistore messages - Add mapistore getprops semantic - Add fsocpf getprops implementation Note: current implementation does not free message object and memory allocation needs to be revised. Note 2: openchangeclient --fetchmail works with this version :-) [r1903] Fix OpenMessage response size calculation. Subcontext size is already calculated when we add the RecipientRow.length size to the global size. [r1902] - Make ocpf_recipClass public - Turn path to headers to local in the lexer bradh [r1901] Avoid leaking file descriptors on error. [r1900] Check return type for vasprintf in libocpf. 2010-06-05 jkerihuel [r1899] Change mapistore openmessage semantics to fetch/retrieve recipients and properties from mapistore. Modify OpenMessage ROP to dump mapistore_message structure contents retrieved from mapistore. [r1898] Add a function to retrieve recipients from a parsed OCPF message. [r1897] This is a wip commit, so there is a lot of DEBUG across the code. This will go away in further commits when the implementation is complete. - Add indexing API to mapistore. This API adds an indexing.tdb file within user's mapistore private space and associate MID and FID to their full mapistore path. Current implementation expects folder and mid are repsented under their hexadecimal representation and using the 0.16PRIx64 format string. It is not robust, but should do the trick for the moment. Among features available: - create/open the indexing database - search of existing indexing context - ref count assessors - add/delete fid/mid records - retrieve the list of folders pointing to an element (parsing of the mapistore URI) - Calls to the API have been added to the emsmdb provider implementation for initialization and automatic attempt to add entries whenever we open a folder. - Add preliminary code (relying on indexing API) for OpenMessage when parent handle is the store object. The entire set of cases for mailbox have been included. - Add mapistore code for op_openmessage operation. - Add message list to the fsocpf context - Add preliminary fsocpf backend code to open a message and store it within ocpf_context. bradh [r1896] Refactored some of the FSOCPF backend. Basically some Extract Method refactoring to improve code re-use. [r1895] Use PRIx64 macro to avoid compiler warning. 2010-06-03 jkerihuel [r1893] Add a new OCPF error OCPF_E_EXIST returned if a context already exist. Prevent ocpf_new_context from adding a context to the list if it already existed [r1892] Clean up debug code introduced while working on new libocpf version [r1891] - Make libocpf reentrant and use contexts/ref_count: No more globals are used in libocpf, they are all specific to contexts. libOCPF is now multi-process/thread friendly. - Remove Makefile bison compiling option with a bison %option in ocpf.y - Propagate libocpf changes to openchange server and utils - Fix a bug in file/folder listing when we have both folders and files. 2010-06-01 jkerihuel [r1889] Untested code: - add libmapiserver calculation for OpenMessage + related OXCDATA structures - add skeleton implementation for server-side OpenMessage ROP - add preliminary emsmdbp_object_message implementation/initialization [r1888] - Flush ocpf output when an error occurs - Fix retrieval of message list in fsocpf backend [r1887] Add QueryRows implementation for mapistore in fsocpf backend. [r1886] - Add implementation for mapistore GetContentsTable - Fix error reply for GetHierarchyTable [r1885] Fix how PT_DOUBLE data is passed among libmapi layers. [r1884] Fix an issue introduced in r1858. PT_DOUBLE patch is valid for EMSMDB, not for NSPI. Rollback change for SPropValue [r1883] Add IPM.Note as a default receive folder for Inbox. This is used by Outlook 2003 in the Send/Receive process. [r1882] Add server-side skeleton for GetAttachmentTable operation. [r1881] Implement SetSpooler server-side function. The function looks like a skeleton ... and is one until we figure out what should be the associated server-side mechanism when clients tells OpenChange server they want to act as a mail spooler. [r1880] The LogonType cases were not handled properly [r1879] Replace existing method to retrieve emsabp_ctx in NSPI server code with mpm session management API and comparison to actual dce_call structure. Replace MAPI_E_LOGON_FAILED rather than MAPI_E_NOT_ENOUGH_RESOURCES in emsmdb server code when session is not found. 2010-05-31 jkerihuel [r1878] Fix commit typo [r1877] We were adding context the list but were never removing them while the context_id was added to the free list. This was causing inconsistencies in mapistore context management + invalid record/pointers to remain and cause OpenChange server to crash. Also add commented code to CreateFolder ROP that will need to be enabled when we understand related Outlook behavior. [r1875] Patch from Bharath Acharya : Print calendar items created at half hours [r1874] Minor warning fix - unused variable, not initialized [r1873] Fix a bug with invalid session leading to OpenChange server crash. We are now retrieving the emsmdbp_context pointer from our session management API, after a comparison check vs dcesrv_call_state rather than blindling and directly from dce_call. bradh [r1876] Add better error path handling for the OXCFOLD-CREATE mapitest module. 2010-05-30 jkerihuel [r1872] Extend mapistore API to have a mapistore URI associated to the backend context. We want to limit creation of new contexts to the strict minimum. Propagate this change to emsmdbp_object_folder_init. Only create a new context if the uri intended to be opened is not already associated to an existing context. [r1870] Handle additional LogonFlags cases for mailbox store in Logon_repl [r1869] Fix empty EcDoRpc replies. Outlook 2007 is now happy and stops from disconnecting untimely. [r1868] Add server-side skeleton implementation for GetPermissionsTable [r1867] Pass parent mapi_handles to emsmdbp_object_folder_init rather than specific parameters. Improve emsmdbp_object_folder_init to handle all the different folder creation cases (root folder, mapistore or not, within mapistore or openchangedb etc.) OpenChange server now passes mapistest folder creation test properly. Fix a bug with context_id and mapistore. We were passing the parent context, then deleting it at some point, causing the parent object to be invalid. Now makes use of a reference counter we manage to keep consistency. Add a convenient function to emsmdbp_object API to retrieve the contextID associated to an object. It looks like we still have some issues when running both Outlook 2007 and Outlook 2003 at the same time with OpenChange server. There may be some additional session checks to perform in the future. [r1866] Fix a bug in session management API: The mpm_session API uses id, id2, node and context_id from the dcerpc session to uniquely identify a session context. However when Outlook calls EcDoConnect multiple times, it still uses the same dcerpc session. With previous API we were freeing the session while it was still in used - which lead in unstable and unpredictable crashes. The following patch adds a ref_count to the mpm_session API and server code has been changed for emsmdb and nspi server to increment the ref_count when the session already exists or create a new session if none is already stored. Also the mpm_session code checks for the ref_count value and ensures it is 0 before calling the destructor. [r1865] Call emsmdbp_object_folder_init in any case when creating a folder. The emsmdbp_object function now do required checks and initialize the folder's object properly. bradh [r1871] trivial comment cleanup. [r1864] Minor cleanups for RopCreateFolder in the server. Prefix the mapistore_uri folder name in the path with "0x" Use ulFolderType (the folder) instead of ulType (ansi vs unicode) when deciding which folder type to create. [r1863] Trivial comment fixes. 2010-05-29 jkerihuel [r1862] Complete the opendir implementation for mapistore folders. Outlook doesn't crash anymore when attempting to open mapistore folders. [r1861] was using the wrong function emsmdbp_is_mapistore instead of mailboxstore. [r1860] Commit Brad Hards's implementation for Public Folders support. Personal changes wrt initial patch: - remove mapistore_uri from openchangedb PF record at provisioning. Only new created folders should be mapistored. - Add a mailboxstore boolean to folder and mailbox emsmdbp so we can select the correct basedn for searches. - Fix GetProps to provide an accurate answer to Outlook when fetching public folder's store specific properties. - Use get_PublicFolderId rather than SpecialFolderId when we open a public folder store. 2010-05-28 jkerihuel [r1858] Patch from Milan Crha : Fix PT_DOUBLE support in openchange [r1857] Fix unicode ocpf format in ocpf_write [r1856] - Fix PT_I8 support in libocpf: PT_I8 support was incorrectly processed as PT_DOUBLE and prevented properties with 0x0014 proptag (e.g. PR_PARENT_FID) to be added properly to ocpf files. - Add PR_PARENT_FID to the set of properties when creating folders [r1855] Fix mkdir prototype in sqlite3 backend 2010-05-27 jkerihuel [r1853] Outlook uses GetProps with the PidTagSubFolders property to check if a folder has subfolders. Add this property at provisioning (set to FALSE), then set it to true on system/specialfolders if folder creation in mapistore went OK. [r1852] - Implement mkdir operation at mapistore level - Update PidTagFolderChildCount of parent folder when parent is the root folder of a mapistore context (folder attributes stored in openchange.ldb) - Improve RopCreateFolder implementation - Clean-up emsmdb_object_folder_init implementation - Add a convenient function to turn ROPs parameters into MAPI properties. This prevents from having endless number of parameters. - Commit remaining parts of the provision changes [r1851] This TODO doesn't belong here [r1850] Add a convenient function to retrieve the distinguishedName of a folder given its folder identifier. This function is useful when building dn for openchangedb ldb_add operations. [r1849] Add PidTagComment so it can be used in openchange.ldb when root folders are created with a comment CreateFolder parameter. [r1848] Make it possible to retrieve MailboxRoot folder using olFolderMailboxRoot in GetDefaultFolders. [r1847] Outlook 2007 tries to create a To-Do search folder under user mailbox. Creates the folder at provision time to be kind with it. Set PidTagParentFolderId to 0 for mailbox root [r1846] The wrong index in mapi_repl was causing the crash I've investigated over the past 10 hours. Please always use idx for mapi_response->mapi_repl[] index ;-) 2010-05-26 jkerihuel [r1845] In current architecture, we need to retrieve root mapistore folder properties from openchangedb, then use mapistore for operations such as GetHierarchyTable or GetContentsTable. This was not possible with the current design where we only switch between mapistore: true or false. I have introduced a mapistore_root boolean associated to folder object which we set to true if the folder initializes a mapistore context (otherwise false). This boolean is used in GetProps so we retrieve mapistore container properties from openchangedb and not mapistore. bradh [r1844] Add size calculations for public folder RopLogon response. 2010-05-25 jkerihuel [r1843] We'll change CreateFolder to generic code later. For the moment change from sqlite to fsopcf backend for system folders [r1842] Fix handling of flagged property row in GetProps (Mailbox case). [r1841] Missing break added, now makes Outlook 2003 launhes properly. [r1840] Ensure PidTagAttr is valid and prevent ldb layer from segfaulting [r1839] Send a flagged PropertyRow when GetProps is called with mapistore Add a nasty hack and call this fake MAPI_E_NOT_FOUND property value for GetProps if the object doesn't exist. In openchangeclient we are calling get_container_class using the parent object (Mailbox root folder) and the FID of the 2-level down folder. This causes openchange server to crash. The hack exposed above will help temporary workaround this problem while we figure out/remember the real problem: Why do we have to call the parent to retrieve the container class? [r1838] Remove last references to systemfolder in libmapiproxy API [r1837] release objects properly in the mailbox recursive function [r1836] After we release ocpf_context, strings are destroyed. Prevent from happening by stealing the overall context and talloc_strdup strings. We'll need to find a better/encapsulated way to do this on long term. [r1835] Add a small hack to handle StandardPropertyRow properly StandardPropertyRow have no errors and have a prefixing flag set to 0 [r1834] Get ride of the previous way to detect systemfolder/mailbox/mapistore folders. This was barely understandable and error prone. It is now replaced by a mapistore boolean set for every object + a convenient emsmdbp_object function to check mapistore value for given handle quickly. 2010-05-24 jkerihuel [r1833] Add mapistore implementation for QueryRows ROPs relying on GetHierarchyTable objects (folders properties listing). Add fsocpf backend implementation to fetch folders properties from a .properties OCPF file stored within the folder (identified by its PR_FID). Customized emsmdbp table object to have: - a context_id and whether the table is within mapistore or not. - to know if the table comes from GetHierarchyTabke or GetContentsTable Add a path element to the folder_list structure in fsocpf backend to quickly use the full path and open the .properties file. Note: current code is for developers only. It is known to have bugs (e.g. memory allocation), furthermore there is some manual openchangedb and filesystem operation to perform in order to have the commit intended results. [r1832] Add a convenient function for openchange server that lets build the SPropValue array with known properties. [r1830] Replace the hardcoded fsocpf_ctx->fid with a basic code searching for last elements in mapistore_uri path. [r1829] Fix typo in PidTag name [r1828] Add PidTagFolderChildCount [r1827] Add libocpf as a dependency to mapistore_fsocpf backend [r1826] Add a ulType to emsmdbp table object. We need to make the difference between folders table (hierarchy) and messages ones (contents). [r1825] This is a large work in progress commit: - Do not add mapistore_uri for Mailbox and IPM Subtree. These are only openchange.ldb containers. - Fix a memory issue with emsmdbp object destruction: use a different context for folder object. This was preventing from having a valid DIR * when releasing the object at mapistore layer. - Add preliminary implementation for OpenFolder (GenericFolder) in emsmdbp server code and mapistore. It can't yet be tested properly with openchangeclient --mailbox because we need to extend QueryRows implementation first. This will be achieved in further commits We are now using mapistore_uri attribute value (valid or NULL) to detect whether it is a systemfolder (blank container) or if we need to initialize a mapistore backend context. - Add mapistore implementation of GetHierarchyTable and backend implementation for fsocpf. Since we don't have a working Createfolder/mkdir implementation yet, you need to add PidTagFolderChildCount = 1 to the folder record in openchange.ldb + manually create the directory on the filesytem. [r1824] Missing mapi_object_release call added 2010-05-23 jkerihuel [r1823] - Add libmapi as a dependency to libmapistore. We need libmapi to benefit from operations on MAPI properties. - Add a MAPISTORE_RETVAL_IF macro and a MAPISTORE_SANITY_CHECKS one for common checks. - Refactor the search of the backend context given its context id in a function and propagate the change to related functions. - Add skeletons for opendir, closedir, mkdir and rmdir. Prototypes of these function may change in the future. [r1822] Implement create_context and delete_context for fsocpf backend. Patch initially from Brad Hards. Add a double linked list with fid/DIR couples for folders operations to be developed. [r1821] Fix a bug in NSPI server which was preventing NspiGetMatches from retrieving the correct DN from the in-memory tdb database. Should fix the profile creation error users were experiencing. [r1819] Add a reference to the libocpf documentation for ospf backend bradh [r1820] Add forgotten part of r1818. [r1818] Support provisioning mailboxes with either fsocpf or sqlite backends. fsocpf is the default at this stage. OK'd by Julien. 2010-05-22 jkerihuel [r1817] Fix paths to related pages [r1816] Patch from Brad, fix doc typo, grammar - makes it sound more English. 2010-05-21 jkerihuel [r1815] Add API documentation for init, backend connection contexts Add programming samples [r1814] Install libmapistore pc file [r1813] 0.2 version of mapistore documentation. Merge some of the initial mapistore wiki page content. Add a section on FSOCPF backend bradh [r1812] Various API documentation fixes. All trivial. [r1811] Fix some hard-coded formatting in mapitest common code. [r1810] Add a simple create / delete folder test to mapitest. I've been using this to test the basic operations. [r1809] Enable DeleteFolder rop, now we have a partial implementation. [r1808] Implement RopDeleteFolder, and handle the case where a folder already exists in RopCreateFolder This still only works for a top level folder. [r1807] Add convenience API to obtain the FID for a given folder (by name). This is useful to tell if a folder exists, which we need to do before we create it. Also fixes a nuisance warning about printf specifiers. [r1806] Extend CreateFolder size calculations to handle some of the optional elements We still don't properly handle the variable length server element. 2010-05-20 jkerihuel [r1805] Add general overview of what mapistore is and how it can be used from a user perspective [r1804] Fix doxygen warnings [r1803] Refactor mapiproxy documentation into a global mapiproxy / openchange server doc. - Add a mapistore documentation skeleton - Add related pictures 2010-05-19 jkerihuel [r1801] Add folder atomic operation to mapistore and skeleton to backends: mkdir,rmdir,opendir,closedir,readdir bradh [r1802] API documentation typo fix. 2010-05-18 jkerihuel [r1799] - Push Brad's CreateFolder implementation after turning hardcoded fields to generic one. Note: current implementation is incorrect as it states that any folder is referenced within openchange.ldb while only system/top folders are. We have a mapistore URI for system/top folders, not for subfolders which are stored directly within specified mapistore backend. However the implementation is almost correct when it comes to create folders directly under / in the user mailbox. [r1798] - Add a 'fsocpf' mapistore backend skeleton (FileSystem + OCPF) - Fix some doxygen in mapistore sqlite3 backend - Add an op_mkdir skeleton to mapistore - Add fsocpf:// namespace test to mapistore_test - Compile fsocpf only if libocpf gets compiled [r1797] Add defs_private.h so we can use PRIx64 where appropriate [r1796] It makes more sense to directly return the next available and formated FID rather than the GlobalCount raw value. [r1795] Add exchange username to emsmdbp_ctx structure for convenient purposes [r1794] After openchange_ldb is opened, map attributes of the @ROOTDSE record with ldb_set_opaque so ldb_get_default_basedn and ldb_get_root_basedn work. 2010-05-17 jkerihuel [r1793] Implement a convenient function to retrieve the GlobalCount value from the objectClass=server record in openchangedb - which is the next FID to be available. Note: the function currently lacks locking mechanisms. We should introduce some to prevent from race conditions. This code was originally designed by Brad. I've just refactored it. [r1792] Add a rootDSE entry to openchangedb. This change makes possible to call: - ldb_get_root_basedn() to retrieve CN=server,DC=domain,DC=ext - ldb_get_default_basedn() to retrieve CN=firstou,CN=firstorg,CN=server,DC=comain,DC=ext [r1790] Add server-side skeleton for ROPs: - ModifyRecipients - DeleteMessage - SubmitMessage - GetTransportFolder NOTE: GetTransportFolder is using hardcoded data that will be removed in futher commits. [r1789] Add libmapiserver size calculation for ROPs: - RopDeleteMessage - RopModifyRecipients - RopSubmitMessage - RopGetTransportFolder 2010-05-16 jkerihuel [r1787] Fix provisioning script and push a master-git samba4 version known to compile and work properly with openchange. There is probably a small typo left in installsamba.sh post_install script to fix bradh [r1788] Update docs for new samba version. Looks like we now have real complexity requirements for passwords... 2010-05-14 bradh [r1786] Fix the container class for the Drafts folder. This is per MS-OXCSFLD [r1785] Add PT_I8 for cast_SPropValue(). 2010-05-13 jkerihuel [r1784] Fix openchange vs latest samba4 git-master branch - Fix OpenChange schema: Had to split our 1-file schema into multiple files in order to be compliant with Samba4 LDB schema validation policy/rules. - Fix openchange provision script - Fix calls to smb_iconv_convenience_init - Fix the copied libmapi/socket code to work with latest samba4 code - Fix openchange server SIGSEGV when EcDoConnectEx is called I have tested the following to ensure nothing is broken: - mapitest with Exchange 2003. All tests are OK - openchangepfadmin (user creation/deletion OK) - openchange server provisioning - openchange server vs Outlook 2003: - profile creation OK - Outlook can open the user mailbox and display it properly 2010-05-10 jkerihuel [r1783] Skeleton server code for DeleteFolder ROP [r1782] Just add more skeleton code to select between available folder types [r1781] Server side skeleton for CreateFolder operation 2010-05-08 bradh [r1779] Implement some more properties for cast_mapi_SPropValue(). Patch mostly by Milan Crha, some changes by me. [r1778] Use retval instead of GetLastError() in a couple of places. [r1777] Add missing failure path handling. [r1776] Avoid assigning a boolean result to an enum MAPISTATUS. Fixes problem noted with mapitest on OXCFOLD-MOVECOPY-MESSAGES. 2010-05-06 bradh [r1774] Add comment about the number for each ROP in the server. 2010-05-03 bradh [r1772] Make sure we can load a server module when it is built with coverage testing enabled. 2010-05-02 bradh [r1770] Fix some mapitest issues reported by valgrind. These only occur when running against the openchange server - mostly problems with failure paths. [r1769] Fix up a few segfaults found when running against openchange server. 2010-05-01 bradh [r1767] Add support for EcDoRpc GetAddressTypes (0x49) and OptionsData (0x6f) to server. This is completely driven by the server provisioning - no hard coding. This makes a binary incompatible change, so if you get crashes, please try a clean rebuild. 2010-04-29 bradh [r1765] Add PT_DOUBLE support for set_SPropValue(). 2010-04-28 bradh [r1763] Add support for PT_ERROR in mapi_SPropValue casting function. [r1762] Add support for a couple more types in the casting code. Also adds a development-version "OPENCHANGE_ASSERT()" that flags incomplete code. 2010-04-23 jkerihuel [r1760] Add a convenient function to retrieve the total number of records in the Global Address List. Modify openchangeclient to expose this change in the --userlist option. 2010-04-20 jkerihuel [r1758] Fix OpenChange notification subsystem to handle multiple session properly Patch OpenChange trunk to reflect this API change Add quick and dirty doc/examples/multiple_notif.c to show how to setup multiple sessions + notifications with threads. [r1757] Add PidTag for transport message headers 2010-03-04 bradh [r1755] One more server API documentation fix. [r1754] More server side api documentation work. 2010-03-03 bradh [r1752] Mix of api documentation fixes for server side. [r1751] Add MAPI_E_NOT_IMPLEMENTED. This is based on information at http://social.msdn.microsoft.com/Forums/en-US/os_exchangeprotocols/thread/d3c860a8-f131-4c7a-aa11-b9ec328d06c4 2010-03-02 bradh [r1749] Implement RopOptionsData (0x6F). Updates IDL, adds implementation and mapitest coverage. This has no practical use, but might be useful for testing the server. 2010-02-28 bradh [r1747] Add talloc leak checking options to mapitest. 2010-02-27 bradh [r1745] Update man page for mapiprofile to reflect new --language option format. 2010-02-26 bradh [r1743] Add special handling for PS_MAPI property name mapping. This fixes a long-standing mapitest failure. The logic is based on MS-OXCPRPT, section 2.2.12.2.2 PropertyIds. [r1742] Minor API documentation fix. 2010-02-24 bradh [r1740] Build fix for example code 2010-02-23 jkerihuel [r1738] Fix format string problem #184 ticket bradh [r1737] Add status reporter classes to allow redirecting the progress messages. [r1736] Update man page to reflect mapitest --subunit option. [r1735] Implement basic subunit output protocol format for mapitest. There are a couple of documentation bits to follow. 2010-02-20 bradh [r1733] Trivial API dox addition. 2010-02-17 bradh [r1731] Update the IDL and implementation for RopGetPermissionsTable (0x3e) and RopModifyPermissions (0x40) to match MS-OXCPERM. The function signature for GetTable() and ModifyTable() has changed. They are now called GetPermissionsTable() and ModifyPermissions() respectively, and there is an additional "flags" argument, which you almost certainly want to pass as 0x00 if you are porting from some older implementation. Updates all users, and adds mapitest unit tests. 2010-02-11 jkerihuel [r1729] Add country codes to codepage-lcid description file bradh [r1727] Remove copied code from samba (ldb) and just use the ldb version. Resolves ticket #167 [r1726] Allow building if popt isn't available. The changes are to: - remove unnecessary include in libmapiadmin - only build mapistore test tool if popt is available - only build torture tests if popt is available. The last change could be finer (e.g. only leaving out the part of the torture test that actually requires popt) but that seemed more fragile and generally unnecessary. Resolves ticket #233. jelmer [r1728] Update bzrignore. 2010-02-10 bradh [r1724] Ensure we always initialise before trying to cleanup (e.g. in a failure scenario). Issue identified and patch provided by Erik Hovland, minor changes by me. Resolves ticket #236. [r1723] prop is declared within the switch statement. Fix by Erik Hovland - thanks very much. Resolves ticket #239. [r1722] Use strncpy instead of strcpy. Patch by Erik Hovland, plus a minor change by me to ensure the string is null terminated. Resolves ticket #237. [r1721] Add missing break statements Patch by Erik Hovland Resolves ticket #238. [r1720] Mark appropriate constructors as explicit. Patch by Erik Hovland - thanks very much. Resolves ticket #240. [r1719] Add newline. Patch from Erik Hovland - thanks again. Resolves ticket #242. [r1718] Fix spelling errors. Patch by Erik Hovland - thanks very much. Resolves ticket #241. [r1717] Make sure we actually can compile when using --enable-openchange-qt4 This patch ensures that $(MOC) gets set in the Makefile. 2010-02-09 jkerihuel [r1715] Add canonical names for codepage related properties (involved in PT_STRING8 encoding/decoding) 2010-02-08 jkerihuel [r1711] - Add parser for codepage-lcid - Add entire set of conversion functions for lcid, codepage, language and locale - mapiprofile now uses codepage/lcid matching LC_CTYPE environment variable for language detection, otherwise codepage/lcid matching language list. Language list is now dumped from codepage-lcid auto-generaed code. - Remove deprecated util and tests directory from libmapi and from build system. We now only rely on codepage_lcid.c - Update openchange code (utils, mapiprofile, mapitest and exchange2ical libs) to use this new API. - I have not looked into icalparameter_get_language, but assuming it is relying on previous API, I may have introduced a bug here. Looks like the function outputs for example "en-US" while we now checks for "en_US" to match setlocale output. bradh [r1710] Minor API documentation adds. [r1709] Add unit test coverage for the GetGALTable() function. This is mostly lifted from utils/openchangeclient.c [r1708] Switch to only building Qt4 bindings if specifically asked for. This is a bit experimental for now, so lets go safer... 2010-02-05 jkerihuel [r1706] In this particular case (error returned, mapi_response shouldn't be free'd) [r1705] Fix bug 605827 - SRowSet was free'd while still needed 2010-02-04 jkerihuel [r1703] Template file which associates Language, LCID, Locale and Codepage. Furthermore commits will implement the mparse parser which will auto-generate the associated C files. This should give us a reliable way to use it in mapiprofile, MAPI profiles database and for PT_STRING8 proper conversion purposes. If anything is missing or is incorrect, updating the file will be trivial. 2010-02-03 bradh [r1701] Fix bug where you couldn't select another messages in the default folder without changing folder first. Looks like this is just a bit I forgot to update when changing from an initial cut to the "more working" implementation. 2010-02-02 jkerihuel [r1699] - Fix trac ticket #183: PT_UNICODE properties are now turned to UTF-8 directly. - Remove deprecated utf8_convert lexer and windows_to_utf8 routine - Change openchange tools to use _UNICODE tag version instead - octool_get_propval now prefer UNICODE properties over PT_STRING8 ones (default behavior). - Change mapidump_message API to take an optional mapi_object_t message parameter. If the message object is specified, we can have access to the subject, and recipients (to, cc, bcc) without having to query them within a GetProps call. bradh [r1698] Fix an ugly cut-n-paste error. [r1697] Add pkg-config support for libmapi++. 2010-02-01 jkerihuel [r1695] Fix ticket #123 (known as 562948 on gnome bugzilla): "Unable to send mails containing UTF8 strings" OpenChange was using strlen(str) * 2 + 2 to calculate the expected size for utf16 string. This patch fixes this and replaces it with a function that make proper utf8 to utf16 conversion. This commit also replaces PT_STRING8 properties in openchangeclient.c with PT_UNICODE ones to ensure utf8 strings get converted properly. 2010-01-26 jkerihuel [r1693] - Add NormalizedSubject and SubjectPrefix strings to object_message_t structure. - Add a function to retrieve TypedString value - Add a mapidump function for obj_message (only retrieve subject and recipients) - Add --fetchsummary option to openchangeclient: Dumps properties from OpenMessage response only (subject and recipients) rather than going through GetProps and dumping a more complete version. bradh [r1692] Move make distclean to the end again. 2010-01-23 bradh [r1690] Remove a copy of the dlinklist.h header, and just use the samba version instead. 2010-01-20 bradh [r1688] Install missing file. 2010-01-13 bradh [r1686] Allow us to find samba python code on 64-bit machines. 2010-01-10 jkerihuel [r1684] Update EcDoConnectEx IDL to match latest specifications bradh [r1683] Minor additions to "make clean" / "make distclean" to remove generated python bits, and also the config.h file. 2010-01-08 bradh [r1681] Implement IsMailboxFolder for public folder types. Involves some refactoring of the way we handled the mapi_object_store_t, such that we now talloc_zero the structure. Adds mapitest coverage for these. Resolves Ticket #134. 2010-01-06 bradh [r1679] Add unit tests for IsMailboxFolder Also use 0xFFFFFFFFF instead of -1 for no-such-mailbox, consistent with the unsigned data type. 2010-01-04 jkerihuel [r1677] Change location of .cpp.o and .ccp.po to the correct location and inhibit compilation line output for moc and cpp compilation. bradh [r1676] Try harder to clean up libmapi++ bits. 2010-01-03 jkerihuel [r1673] Ignore moc files and generated binary [r1672] Update OpenChange version to 0.10 NOMAD Nomad is a mechanical explorer sent from Earth in 2002. It was melded with an alien device named Tan Ru and the resulting robotic hybrid began destroying anything that was imperfect including, in 2267, itself. bradh [r1674] Add documentation for qt/ subdirectory. [r1671] Try harder to find moc. [r1670] Initial commit of some Qt-style bindings. This is mostly for testing, although hopefully the library will emerge with a set of mostly-useful widgets for implementing real clients. 2009-12-31 bradh [r1668] Quiet the build here. Inadvertent removal in a previous patch. [r1667] Some support for ReviewBoard. 2009-12-29 bradh [r1665] Update OpenMessage flags to match specification values. [r1664] Cleanup libmapi++ code when we "make clean". [r1663] Add svn ignore entries. [r1662] Remove inline from shared library class. Fixes build on Intel C++ compiler. 2009-12-27 clsk [r1660] libmapi++ is no longer a header-only library 2009-12-26 bradh [r1658] Add first part of Restrictions support. [r1657] A little more documentation fixes. 2009-12-25 jkerihuel [r1654] Fix MAPIUninitialize() crash when leaving after an unsuccessful call. In such situation, mapi_response is not allocated but has a destructor associated. This fix removes the destructor whenever the error code is different from MAPI_E_SUCCESS. Also add a minor (probably useless) check on mapi_response pointer validity before attempting any other child's free. bradh [r1656] A couple of minor API documentation fixes. 2009-12-24 jkerihuel [r1651] Rename libmapi into openchange in our release script. Makes more sense given the scope of our releases. [r1650] Fix format string warnings. [r1649] New ModifyRecipients IDL and implementation. This patch improves the logic within the RecipientFlags bitmask calculation function and make use of different MAPI properties for ModifyRecipients. Fix trac ticket #125 and https://bugzilla.gnome.org/show_bug.cgi?id=568763 bradh [r1648] Minor API documentation fix. 2009-12-23 bradh [r1647] Fix some exchange2ical memory leaks / "still reachable" memory. [r1645] Fix property tag array count, so we get the language in Summary lines in the ical output. [r1644] Add protection against null CN values. Resolves ticket #232. Thanks to Arnout Engelen for the bug report and the patch to fix the problem. [r1643] Handle all day events for UTC+ timezones. This resolves ticket #217. Thanks to Arnout Engelen for both reporting the problem, and providing a patch. In the end I heavily modified the patch, and implemented a much simpler version while we sort out the timezone identifier problems. 2009-12-22 bradh [r1641] Minor documentation update to reflect GSoC exchange2ical merge. [r1640] temporary fix for building on FreeBSD 7.2. [r1639] Remove this file - converted it to trac tasks. 2009-12-21 jkerihuel [r1635] Patch from Johnny Jacob : Changed MonitorNotification to be non-blocking. Also checks whether to process notifications using a callback. [r1634] Open Profile Store using global_mapi_ctx for the memory context. This fix removes 20 context errors when running valgrind on mapitest. [r1633] - Fix important memory leaks in OpenChange NSPI stack. The memory context modifications applied to the EMSMDB stack have been propagated to the NSPI one. NSPI dcerpc_* functions now rely on a temporary context passed in parameter to the nspi_* functions from libmapi/nspi.c. - Changes propagated to torture, mapitest, IProfAdmin interface and ResolveNames function to match the internal API. - Add missing MAPIFreeBuffer call in mapitest modules [r1632] Minor cosmetic change [r1631] Minor changes to match our coding convention more closely [r1630] Return (const void *) instead of (void *) where missing [r1629] - Fix important memory leaks within the OpenChange stack. Most of the leaks came from the pipe memory context used in emsmdb_transaction which was only released on MAPIUninitialize and sometimes leaded in lost blocks. This fix makes extensive usage of the temporary memory context used in top MAPI calls implementation. This context is passed in argument to emsmdb_transaction and used for dcerpc_* operations. When we return from any libmapi call implementation, this context is destroyed. This guarantee no extra memory within NDR layer is kept. The only requirement for this patch to work is to make sure the data we return from MAPI calls is either reparent to another memory context or copied properly. bradh [r1638] Add support for skipping tests that don't apply to some server versions. [r1637] Change the format of the server version, so it matches the Microsoft way of doing versions. 2009-12-20 jkerihuel [r1627] Fix store version info assignment - Exchange version now works again in mapitest. [r1626] Clarify the developer's task when using GetPropList. We were allocating the SPropTag proptag array with the session context pointer, which was not released with a MAPIFreeBuffer(SPropTagArray). We are now using SPropTagArray pointer as parent context and clarify that the developer must pass an allocated SPropTagArray pointer to the function. [r1625] Missing mapi_object_release leading in small leaks. [r1624] Sanitize RfrGetNewDSA function and memory usage. The function was returning either a const char * passed in parameter or the string returned by RfrGetNewDSA call. Furthermore we were using the session pointer for the memory context. Finally the function description was not matching its behavior. What this patch does: - use a named memory context for RfrGetNewDSA call - return an allocated string on success otherwise NULL - release RFR memory context properly valgrind before patch (mapitest): ==28876== LEAK SUMMARY: ==28876== definitely lost: 0 bytes in 0 blocks ==28876== indirectly lost: 0 bytes in 0 blocks ==28876== possibly lost: 3,193,529 bytes in 23,296 blocks ==28876== still reachable: 345 bytes in 2 blocks ==28876== suppressed: 0 bytes in 0 blocks ==28876== ==28876== For counts of detected and suppressed errors, rerun with: -v ==28876== ERROR SUMMARY: 2351 errors from 2351 contexts (suppressed: 45 from 10) valgrind after patch (mapitest): ==29083== LEAK SUMMARY: ==29083== definitely lost: 0 bytes in 0 blocks ==29083== indirectly lost: 0 bytes in 0 blocks ==29083== possibly lost: 3,190,285 bytes in 23,256 blocks ==29083== still reachable: 345 bytes in 2 blocks ==29083== suppressed: 0 bytes in 0 blocks ==29083== ==29083== For counts of detected and suppressed errors, rerun with: -v ==29083== ERROR SUMMARY: 2338 errors from 2338 contexts (suppressed: 45 from 10) [r1623] This patch fixes most of the leaks coming from pull_emsmdb_property() function. pull_emsmdb_property is using pointers and allocate memory to prevent from returning a local variable address. Such pointers include PT_I2, PT_I8, PT_LONG, PT_ERROR or PT_BOOLEAN. Pointer's values are assigned in set_SPropValue but were never released/free'd. This patch implements free_emsmdb_property to fix this problem. valgrind before patch (mapitest): ==26674== LEAK SUMMARY: ==26674== definitely lost: 0 bytes in 0 blocks ==26674== indirectly lost: 0 bytes in 0 blocks ==26674== possibly lost: 3,264,485 bytes in 23,387 blocks ==26674== still reachable: 345 bytes in 2 blocks ==26674== suppressed: 0 bytes in 0 blocks ==26674== ==26674== For counts of detected and suppressed errors, rerun with: -v ==26674== ERROR SUMMARY: 2370 errors from 2370 contexts (suppressed: 45 from 10) valgrind after patch (mapitest): ==27270== LEAK SUMMARY: ==27270== definitely lost: 0 bytes in 0 blocks ==27270== indirectly lost: 0 bytes in 0 blocks ==27270== possibly lost: 3,127,733 bytes in 23,293 blocks ==27270== still reachable: 345 bytes in 2 blocks ==27270== suppressed: 0 bytes in 0 blocks ==27270== ==27270== For counts of detected and suppressed errors, rerun with: -v ==27270== ERROR SUMMARY: 2348 errors from 2348 contexts (suppressed: 45 from 10) bradh [r1622] Minor API documentation fixes. 2009-12-19 jkerihuel [r1620] - Add a macro to mparse.pl to free both mapi_response and mem_ctx within OpenChange calls implementation. For the moment it is only implemented in OpenUserMailbox call. - Fix a memory leak in OpenUserMailbox: When the call failed (ecUnknownUser or ecUseEnryption) mapi_response was not free'd properly. [r1619] Minor indentation fix bradh [r1618] Add some missing newlines to reduce compilation noise. [r1617] Merge in Ryan Lepinski's Google Summer of Code work on exchange2ical. See the gsoc_exchange2ical branch history for commits. I also made a change to address ticket #216, and fixed a couple of typos. 2009-12-18 bradh [r1615] Minor updates to provisioning instructions. Thanks to Girish Venkatachalam for some suggestions. 2009-12-17 jkerihuel [r1611] Fix 'unused variable' warning on FreeBSD for exchange2mbox bradh [r1613] Add documentation for the --freebusy option. [r1612] Warning fix. 2009-12-16 jkerihuel [r1607] Fix segfaults in mapitest launched with exchange2010 [r1606] Fix compilation warnings bradh [r1609] Add missing -L directory specifier. Looks like this was tolerated by gnu ld, but not by opensolaris ld. Patch by Brian Lu (Sun). Thanks again. [r1608] Add documentation for new mapiprofile --encrypt option, introduced in r1602. [r1605] Fix a couple of typos that trash CFLAGS during build. 2009-12-15 jkerihuel [r1603] Automatically switch from connect to seal on the emsmdb pipe if ecNotEncrypted is returned by EcDoConnect. [r1602] - Make OpenChange natively working with Exchange 2010 - Factorize binding string construction code within a single function - the seal flag is mandatory to connect to Exchange 2010 - add seal boolean value to MAPI profile creation and mapi_profile structure - add --encrypt option to mapiprofile to set the seal value 2009-12-14 bradh [r1600] Add documentation for set_SPropTagArray(). Thanks to Brian Lu (Sun) for reporting. 2009-12-13 jkerihuel [r1598] This doesn't really fix ticket #149, but this should at least prevent from triggering segmentation fault when PR_EMAIL_ADDRESS_UNICODE doesn't have any cn=Recipients,cn= substring bradh [r1597] Trivial fix (newline) for warning on FreeBSD compiler. [r1596] Add support for manually creating the library symlinks for FreeBSD This is a somewhat speculative commit. Also fixes a couple of cosmetic whitespace issues. 2009-12-12 jkerihuel [r1594] Patch from Bryan Lu : Create symbol link only on Solaris This closes ticket #221 and makes it possible to compile openchange on Solaris. [r1593] Temporary bug fix in emsabp.c - If restrictions are NULL in emsabp_search, return MAPI_E_INVALID_OBJECT. This prevents from using invalid res pointer leading in segmentation fault. Initial fix proposed by Erik Hovland [r1592] Patch from Erik Hovland : fid might be null. Check it before dereferencing in the ocpf_folder_lookup() call. Similar behavior fixed in openchangeclient folder_lookup() function. [r1591] Patch from Erik Hovland : NotificationData 'could' be null. Check it before handing it to notification-callback(). This is important because eventually NotificationData will be dereferenced in the code path. [r1590] Patch from Kamen Mazdrashki : Fix MAPI Warning error codes [r1589] Patch from Kamen Mazdrashki : bugfix: Bugs in abp_tdb layer fixed. emsabp_tdb_traverse_MId() returns 'false' (i.e. not found) in most of the cases. [r1588] Patch from Kamen Mazdrashki : Implement NspiQueryRows() address list enumeration We can now run openchangeclient --userlist on OpenChange NSPI server and Outlook 2003 is able to query GAL. Note: the initial patch was proposing: "(&%s(showInAddressBook=*))", purportedSearch I replaced it with "%s", purportedSearch only since we don't have yet any showInAddressBook attribute in AD. [r1587] Patch from Kamen Mazdrashki : - Add server side implementation for NspiResolveNamesW - Refactor and split emsabp_verify_user in two functions A new function emsabp_get_account_info() implemented to fetch info about given user name. emsabp_verify_user() uses the above function check if authenticated account_name is valid mail account and if so, account_name is cached in emsabp context for future use [r1586] Patch from Kamen Mazdrashki : NspiGetProps() reimplemented to match [MS-NSPI] specification more closely. As a side-effect, emsabp_fetch_attrs() was altered to return MAPI_E_INVALID_BOOKMARK in case requested MId is not found. This way the function returns more meaningful error codes - if requested MId is not found this surely means InvalidBookmark rather than CorruptStore 2009-12-11 jkerihuel [r1584] Path from Kamen Mazdrashki : Propagate dwFlags for incoming call to get EntryIDs correctly. Actually we need to propagate dwFlags so that emsabp_query() function to be able to determine whether EphemeralEntryID or PermanentEntryID is requested to be built. [r1583] Patch from Kamen Mazdrashki : Implement PR_SEARCH_KEY attribute getter [r1582] Patch from Kamen Mazdrashki Add PR_ADDRTYPE_UNICODE and PR_EMS_AB_PROXY_ADDRESSES_UNICODE getters. [r1581] Patch from Kamen Mazdrashki : - Extend NspiDNToMId() to search in Configuration and Domain partitions. - NspiDNToMId() has been extended to cache returned data properly, i.e. DNs from Configuration partition are cached in ttb_ctx db, DNs from Domain partition are cached in in-memory db ttdb_ctx. [r1580] Patch from Kamen Mazdrashki : emsabp_set_PermanentEntryID() implements MS specification more closely. For reference: [MS-NSPI] and [MS-OXOABK] [r1579] - Replace emsabp_get_server_GUID with samdb_ntds_objectGUID Samba4 function. - Change the way we initially fetched server GUID Credits to Kamen Mazdrashki for initial patch and associated research: It turns out MS implementation for NSPI reads the guid from: "CN=NTDS Settings,CN=,CN=Servers,CN=Default-First-Site-Name,CN=Sites," entry. [r1578] Fix samdb_connect warning. Add function prototype to nsp,emsmdb header files. Change samdb_ctx from void * to ldb_context * bradh [r1577] Update docs to match those in mapiproxy doxygen docs. [r1576] Roll to the latest Samba4 version. This should have no noticeable difference over the Samba4 alpha9 release, but its nice to use the latest version, and it might make a difference on the server side. 2009-12-10 jkerihuel [r1575] Fix OpenChange server code and access to Samba4 databases. Starting with samba4-alpha9, there is no more configuration.ldb or users.ldb. All information can be accessed through a single access to SamDB and configuration records accessed through ldb_get_config_basedn. The following implementation has been tested and is working with: - mapiprofile profile creation - openchangeclient --mailbox - Outlook 2003 account creation - Outlook 2003 mailbox opening 2009-12-09 jkerihuel [r1573] Fix openchange user provisioning scripts [r1572] Forgot to commit this LDIF modifications for openchange provisioning 2009-12-08 jkerihuel [r1570] - Fix OpenChange server provisioning (exchange classes and attribute only) - Remove deprecated provisioning steps - OpenChange user provisioning is still broken at this point, but will be fixed in further revisions. 2009-12-02 jkerihuel [r1568] Fix a cast warning at compilation time for libmapi++ [r1567] - Update openchange libraries to 0.9: close trac ticket #165 - Propagate pkgconfig solution in trac ticket #94 to other libs [r1566] - Update openchange code to work with samba4-alpha9 release - Apply minor fix to ldb_wrap_connect (number of parameters) - Update mapiproxy code to handle new Samba4 assoc_group implementation properly - Update samba4 version script to match alpha9 and related git commit 2009-11-27 bradh [r1564] Ensure we get output if sqlite3 isn't found at configure time. Now outputs "no" instead of a blank. 2009-11-26 bradh [r1562] Fix attribution, per IRC discussion. 2009-11-25 bradh [r1560] Ensure API documentation gets generated for utilities functions. Some undocumented stuff in here to look at later. [r1559] Add additional mapidump functions for notifications This is a patch from Johnny Jacob (Novell), with unit tests and some extra checks by me. Maintains good test coverage for this file. 2009-11-23 bradh [r1557] Avoid use-after-free for the number of rows in the SRowSet. Resolves issue #212, which has the valgrind error. 2009-11-22 bradh [r1555] Add test for get_proptag_value(). [r1554] Minor cleanups for mapidump functions. - Add support for dumping property tags using PT_SHORT. - Modify the tag for PR_whatever_ERROR results to include the _ERROR bit - Minor format change for PT_BINARY (training colon) - Ensure PT_SYSTIME respects the seperator value (API change) - Add a conditional assert() using infrastructure introduced in r1553. Implement mapitest support for all of libmapi/mapidump.c Update openchangeclient for the API change. [r1553] Introduce a compile time definition that is set for SVN snapshot releases. The intent is to use this to protect assert() calls that indicate incomplete code. 2009-11-19 bradh [r1551] Improved Sun Studio compiler support. Patch by Brian Lu (Sun) - thanks again. [r1550] Revert inadvertent part from previous commit (r1549) [r1549] Add coverage testing support. ./configure now supports --enable-coverage, which builds with the right options to support gcov. Also adds a new makefile target ("coverage") that runs the required post-processing steps. Also added a test script that does a range of openchange related (client side) operations. This is useful for generating the test load for coverage checks. So the basic recipe here is 1. Add the --enable-coverage option at configure time. 2. Do a clean build 3. Install it, or otherwise ensure that coverage-enabled libs are used 4. generate the test load (e.g. run ./script/smoketest.sh) 5. "make coverage" 6. Inspect the results in ./covresults 2009-11-13 bradh [r1547] Add support for the SunStudio compiler. I previously special-cased the Intel C compiler, and relied on some ugly ordering requirements to ensure it all worked. This approach is cleaner, allowing options to be build up separately for each compiler, and for the C and C++ versions. Tested on Linux with all three compilers. 2009-11-09 bradh [r1545] Adding missing include. Ticket #220. Patch from Brian Lu (Sun). Thanks very much. 2009-11-07 bradh [r1543] Additional portability fixes for SunOS. Based on a patch (ticket #220) by Brian Lu (Sun). Thanks very much. I modified the patch to try to use autoconf where possible. Resolves ticket #220. [r1542] Remove MAP_FILE flag from mmap(). Looks like this is only required on really old unix systems (e.g. NetBSD prior to 1.0), which we probably won't ever support. Patch by Brian Lu (Sun) - thanks very much. Partly resolves ticket #220 - still need to handle the first patch. 2009-11-02 bradh [r1540] Fix build problem using Sun Studio compiler. Reported by Brian Lu (Sun), including a patch (Ticket #219) I slightly modified the patch, but nothing substantial. 2009-10-21 jkerihuel [r1538] Patches provided by raboof: - Ticket #213 deprecated include directive removal - Ticket #214 missing sanity check - Ticket #215 fix some DEBUG macro level for sain ouput 2009-10-19 bradh [r1536] spello fixes. 2009-10-18 clsk [r1534] Use mapi_profile_get_ldif_path to find ldif path when one is not given 2009-10-09 clsk [r1531] Added libmapi++ wrapper function for CreateProfileStore 2009-10-08 bradh [r1529] Update buildsystem to avoid using bash-specific (well, not sh-supported) += mechanism. Should allow FreeBSD to be supported. 2009-10-06 bradh [r1527] Alternative solution to ticket #179, provided by Alan Alvarez. This alternative avoids the need for the user to clean up the string returned by what(). Also includes a test case, which I've used to validate that the original (prior to r1524) code is faulty, and that both fixes (From Erik Hovland and from Alan Alvarez) deal with it. Resolves Ticket #179 (again). 2009-09-26 bradh [r1524] Make sure that the string given by what() can be used. Patch by Erik Hovland - thanks very much. Resolves ticket #179. [r1523] Ensure that the libmapi++ messages example works even if there is no PR_CONVERSATION_TOPIC (subject). jelmer [r1525] Add 'make dist'. 2009-09-20 bradh [r1521] Modify mapi_object_set_logon_id() to be able to report errors. Original patch by Erik Hovland, I made some changes. 2009-09-19 bradh [r1519] Implement RopReloadCachedInformation (0x10). Minor change to IDL (previously implemented), and adds implementaiton and mapitest code. Also editorial comment fix in some related mapitest stuff. Resolves ticket #186 [r1518] Implement GetValidAttachments ROP (0x52). Includes IDL, implementation and mapitest. mapitest also checks DeleteAttach behaviour, which I don't think we previously covered anywhere. Also includes a comment fix in the mapitest code. 2009-09-16 bradh [r1516] Whitespace cleanup. Patch by Erik Hovland 2009-09-14 bradh [r1514] Update the properties list. Patch from Girish Venkatachalam 2009-09-12 bradh [r1512] Update API to use MAPITAGS enum. [r1511] Update to match API change. [r1510] Use appropriate enum here. [r1509] Use enum for OpenEmbeddedMessage call. [r1508] Use enums where appropriate. [r1507] Update users of FindRow to use enums. [r1506] We are supposed to be returning a MAPISTATUS, so switch to using the OPENCHANGE_RETVAL_ERR macro here. [r1505] Use appropriate enums instead of int types. [r1504] Use enums instead of ints / hardcoded values. [r1503] Use enum types where appropriate. Fixes warnings from Intel C compiler. [r1502] Return a suitable MAPISTATUS if we can't talloc sufficient memory here. Fixes warning from Intel compiler. 2009-09-11 bradh [r1500] Only pass "-Wmissing-prototypes -Wstrict-prototypes" to CFLAGS, not to CXXFLAGS as well. Avoids g++ warnings. [r1499] Use enumerated type instead of integer. [r1498] Remove unreachable code. [r1497] Add "static" to avoid the need for additional declarations. Avoids noise from the intel c compiler. [r1496] Namespace variable in macro, so we don't get noise about shadowing a declaration of "i" [r1495] Help icc find comparison_fn_t. [r1494] Match up data types in argument and format string. [r1493] Remove unused variable, and change a name to avoid a "shadowed declaration" warning. 2009-09-10 bradh [r1491] Portability fixes for Intel C Compiler. Set CFLAGS early, otherwise AC_PROG_CC will set CFLAGS to "-O2 -g", which later has -O3 appended, which icc complains about. Check if we're really icc, and if so, turn off some warnings. Also turn off the "FORTIFY_SOURCE" define which causes problems with missing builtins. The warnings can (and should) be turned back on later, after we fix the current issues. 2009-09-02 bradh [r1489] Correct diagnostics messages. 2009-08-29 bradh [r1487] Remove explicit -Wstrict-aliasing=3 from command line. This is implied by gcc -Wall option, and icc produces nuisance warnings with it enabled (related to the -W option, not the code being compiled). [r1486] Fix some memory leaks and a bug in mapiprofile. I introduced the bug in r1467, there could be others that are similar. 2009-08-24 bradh [r1484] Minor rewording of description [r1483] Minor cleanups. 2009-08-18 bradh [r1477] Move initialisation up, to make sure everything is valid in the failure paths Patch by Erik Hovland. Thanks once again. This closes out ticket #178. [r1476] Remove unreachable code. Patch by Erik Hovland. Thanks again. This is the second part of ticket #177. This completes the checkin of that ticket. [r1475] Remove unreachable code. Patch by Erik Hovland. Thanks very much. This is the first part of ticket #177. 2009-08-17 bradh [r1473] Ensure that we check the result of the operation we just performed. Patch by Erik Hovland. Thanks very much for continuing to provide these. This is the third part of the patch in ticket #177. The first two parts are yet to be addressed. [r1472] Make sure that return values are checked and report that given status if there is an error. Patch from Erik Hovland, with minor additional changes. Thanks again for the patch. Resolves #176. [r1471] More cleanups of memory leaks for setting up database and an associated failure case. [r1468] fix leak in openchangeclient (as seen with valgrind of "openchangeclient -m") [r1467] Fix memory leak in mapiprofile utility 2009-08-14 bradh [r1465] Ensure that when we pass --profile to mapitest, that profile gets used instead of the default. Also fix a small memory leak when using --profile, and add some extra comments. [r1464] Fix error handling case. Patch from Erik Hovland - thanks very much. Resolves ticket #175. 2009-08-13 bradh [r1461] Remove unused enum values. [r1460] Remove unused code - no simple tests. 2009-08-09 bradh [r1454] Update the script version of samba4 to alpha8. 2009-08-05 jelmer [r1450] Add tevent to dependencies. 2009-08-03 bradh [r1448] Remove unused headers. Patch by Erik Hovland - thanks very much, Resolves ticket #164. [r1447] Apply patch from Erik Hovland, from ticket #162. From the original patch: "The problem is that when you do stat first w/ a file string anyone can exploit the time in between to do whatever they want with the file that the string is a name for. Instead, try to open straight away. Then fstat w/ the file descriptor." I think the patch is fine, although I didn't run the torture test. 2009-08-02 bradh [r1444] Avoid duplicate call to mapi_object_get_logon_id Based on a patch proposed by Erik Hovland, but adapted to follow the pattern used in OpenStream(). Resolves issue #163. [r1443] Applied modified version of patch from Erik Hovland to address unused variables. See http://trac.openchange.org/attachment/ticket/160/unused-values for the rationale. This resolves #160. My version removes variables (rather than commenting them out) since we don't need them now. I also updated the documentation for options that are no longer available The origin of the unused PR_FOLDER_CHILD_COUNT is a bit strange. It was introduced in r808 (to resolve #103), and looks like it might have been used for debugging - no impact on the code. I pulled out the whole lot. Tested with openchangeclient --fetchmail --folder="Sent Mail" and mapitest. [r1442] Use array form of delete (error identified with libmapixx-attach test, using valgrind). [r1441] Fix potentially unused variable. Tested with mapitest (even though nothing should have been affected) and with libmapixx-test and libmapixx-attach under valgrind. Patch is remaining part of http://trac.openchange.org/ticket/153 Thanks to Erik Hovland for the patch. 2009-07-29 bradh [r1433] Remove dead / unused code. See http://trac.openchange.org/ticket/152#comment:1 for rationale. Original patch by Erik Hovland - thanks again. [r1432] Update test case to reflect new behaviour 2009-07-18 jelmer [r1423] Link libmapistore against tdb. [r1422] Update copies of config.guess and config.sub. [r1421] Link libmapiproxy against tdb. [r1420] Declare a SOVERSION for libmapistore. [r1419] Use LDFLAGS when linking exchange2ical. [r1418] Create symlink for libmapistore. [r1417] Link libmapi against tevent since it uses tevent_context_init, link ndr_exchange.po into libmapiserver since it uses some ndr_push_* symbols. [r1416] Fix typo in variable name. 2009-06-21 jelmer [r1365] Fix typo in Python variable name. [r1364] Keep separate flags for libraries around in config.mk. [r1362] Link libmapiserver against all libraries. 2009-06-18 jkerihuel [r1357] Add some PidTag* mapping involved with Recipients and RecipientRow 2009-05-28 jkerihuel [r1350] Patch from Erik Hovland : Initializes variables to make sure they aren't used uninitialized. Ref ticket #153 [r1349] - Add sanity check on mapitest_common creation routines within mapitest modules - Apply patch from Erik Hovland : check return types. [r1348] Patch From Erik Hovland In torture_rpc_mapi_sendattach a call is made to the system function read at line 199. The return value of read is assigned to read_size, which happens to be of unsigned type. So if read returns -1 (which it can) it will not be noticed. The patch changes the type to ssize_t (signed) and checks for -1 as well as zero to break out of the loop. Ref ticket #156 [r1347] Patch from Erik Hovland 1. In mapiproxy, the directory handle dir will be leaked after it is done being used. 2. exchange2mbox main() should use exit at line 785 just like all of the other error paths so that we don't leak anything ref. ticket #157 [r1346] Patch from Erik Hovland Adds a #include config.h to suppress compiler warnings for vasprintf [r1345] Patch from Erik Hovland : Make sure pointers are valid before dereferencing 1. lpProps 'might' be null 2. Add folder to variables checked before moving on. 4. Check nprop->guid before giving to strcmp, two times 6. Check definition before handing to strlen (which will dereference it) Reworked this one to include talloc_free 7. Check MessageClass? before handing to strncasecmp 8. Check backend, return if null. 10. Don't print out anything if lpProp is null 11. Check attach_size before dereferencing 2009-05-25 jkerihuel [r1343] Fix pull structure for QueryRows reply when no RowData is available 2009-05-07 jkerihuel [r1341] - Add preliminary IDL support for Exchange 2003/2007 EMSMDB RPC calls: * EcDoConnectEx * EcDoRpcExt2 - Add LZxpress and XorMagic support to EcDoRpcExt2 request/reply blob. However it doesn't yet support Chained calls. - Add AuxInfo/AUX_HEADER structures and IDL - Refactor mapi_request and mapi_response: move obfuscate_data calls up to the EcDoRpc layer 2009-04-27 jkerihuel [r1339] Patch from Paolo Abeni : call ProcessNotification() after each successful emsmdb_transaction() in all the libmapi calls. [r1338] Patch from Paolo Abeni : Mapi notifications can occurs inside any emsmdb_transaction; currently only the notification send by the server inside the emsmdb_transaction_null() in MonitorNotification() are parsed/processed/delivered to the appropriate callback. To be able to process all the received notifications, the notification structure must comprise the private data to be passed to the notification callback, since in the average mapi call this data is not available. This patch modifies the Subscribe() call and the mapi_notification structure, adding the private_data parameter (also the related Subscribe() calls are update) and add a libmapi call (DispatchNotifications) to force the notification dispatching in a [quite] non blocking way 2009-04-26 jkerihuel [r1336] Patch from Paolo Abeni : ProcessNotification() is ignoring the handle value contained into the processed notifications. This means that if many Subscribe() calls are performed on different folders but with the same flags, all the registered callback are [incorrectly] signaled with each received notification. The attached patch match the handler contained into the notification message against the notification object handle to avoid such replication. 2009-04-23 jkerihuel [r1331] Make sure delayed authenication is not called when server mode is enabled bradh [r1333] Update property list to reflect current OAB props. This deletes a few incompatible properties. Cannot determine the history of the PR_MAILBEAT_ props. [r1332] Fix display of Folder ID values (one is filled with ., the other is prefixed with .16 instead of being filled. Also remove duplicate close() of file descriptor. [r1330] Typo fix. 2009-04-22 bradh [r1328] Warning fix. 2009-04-21 bradh [r1326] Implement RopTransportNewMail (0x51). Includes IDL, libmapi implementation, and basic mapitest coverage. Also fix a few doxygen / formatting things. 2009-04-19 jkerihuel [r1324] - Add Redirect buffer support for OpenMsgStore and OpenPublicFolder. This commit fixes the ecWrongServer (0x478) error users encounter while running openchange based software in a clustered Exchange environment. 2009-04-18 bradh [r1322] Implement RopCloneStream (0x3b) and RopWriteAndCommitStream (0x90). Includes IDL, implementation and mapitest tests. 2009-04-17 bradh [r1320] Fix Search notifications. MS concurred that the docs are wrong. Patch by Paolo Abeni - thanks very much for the investigation and the patch. [r1319] Update GetStoreState documentation. [r1318] Implement RopSetPropertiesNoReplicate (0x79). IDL was already done. mapitest for DeletePropertiesNoReplicate was reused / updated. 2009-04-16 bradh [r1316] Implement (IDL, libmapi, mapitest) RopHardDeleteMessagesAndSubfolders (0x92) Also fix some bugs in mapitest common code, and an incorrect sanity check in CreateFolder(). 2009-04-15 bradh [r1314] Implement RopHardDeleteMessages (0x91). Includes IDL, implementation and mapitest. jelmer [r1313] Ignore generated property file. 2009-04-13 bradh [r1311] Add PT_ACTIONS to list of data types. Not fully/correctly handled yet. 2009-04-12 jkerihuel [r1309] - Add dcerpc_mapiproxy:delegated_auth option This option delays mapiproxy-remote server authentication when the client sends the first request on a given pipe. This is mandatory in order to have delegated credentials to work. - Factor remote connection into mapiproxy_op_connect 2009-04-11 bradh [r1307] Add session state to the notification. Patch by Paolo Abeni - thanks for the investigation and fix. Also remove a stray debug message. [r1306] Add a new mapitest suite for OXCNOTIF (Core Notifications). Add a test to the OXCNOTIF suite based on test case provided by Paolo Abeni. 2009-04-10 bradh [r1304] Update IDL for ModifyRules (0x41) and add IDL for UpdateDeferredActionMessages (0x57). This is a checkpoint commit, pending further investigation into how we handle PtypRestriction and PtypRuleAction. 2009-04-08 bradh [r1302] Mapitest cleanups - remove GetLastError(), and other minor edits. [r1301] Implement LockRegionStream and UnlockRegionStream ROPs. These appear to be a relatively recent addition to the documentation, possibly only used in Exchange 2007 / Outlook 2007. This is complete except for testing of whether the locking actually works. 2009-04-06 jkerihuel [r1299] Use parent folder full replica ID: 2 bytes instead of 1 byte [r1297] - Add Implementation for Logon redirect response buffer in OpenChange IDL - Update libmapiserver size calculation routine for Logon call to handle this case 2009-03-30 jkerihuel [r1293] Add session and logon_id to the list of parameters to copy between objects. This patch fixes a problem in openchangeclient when using the --folder parameter. bradh [r1294] Remove code relating to free'ing the bookmark returned by SetCollapseState. Initial investigations with MS lead me to believe that you can't free that resource. May be more work in this area as investigation continues. 2009-03-25 jkerihuel [r1291] Fix memory leaks for functions relying on pull_emsmdb_property 2009-03-16 jkerihuel [r1289] Fix emsabp valgrind errors 2009-03-12 jkerihuel [r1287] Make it possible to specify a version number for release different from major/minor from configure.ac 2009-03-11 jkerihuel [r1285] Make it possible to open and control up to 255 mailboxes within a single MAPI session. It implements an internal management of a logon_id array at session level + enable transparent transport/copy of current logon_id value among MAPI calls + finally transparently free the logon_id value when the store object (PF or mailbox) is being released. [r1284] - Retrieve recipients from OpenEmbeddedMessage reply - Test the implementation in mapitest - Avoid potential memory leak: steal context for returned ulPropTags. 2009-03-08 jkerihuel [r1282] Be more tolerant with Logon request flags [r1281] Set retval to MAPI_E_INVALID_BOOKMARK rather than returning. This case still needs to be fixed though. [r1280] Delete debug message [r1279] Create a default GetProps reply on error 2009-03-06 jkerihuel [r1277] Fix retval problem in libmapi/nspi.c for GetIDsFromNames. Function returns MAPI_E_SUCCESS, but errno is set to 0x0000000b. Set errno to retval to work around this problem. NSPI-GETIDSFROMNAMES [r1276] OXCPRPT-NAME-ID mapitest now passes: The QueryNamedProperties ecMemory retval has been worked-around by setting QueryFlags to NoStrings to limite the results scope. This means the MNID_STRING case is not fully checked anymore. We should maybe add additional tests to do full coverage. [r1275] Fix GetNamesFromIDs IDL and implementation. Note: We should probably update the function prototype so it takes a mapi_SPropTagArray rather than a single property. bradh [r1274] Protect against bad results from GetGALTable(). Resolves ticket #142 2009-03-04 jkerihuel [r1272] Patch from Paolo Abeni: Add sanity check to Subscribe and prevent applications from crashing if notify context is uninitialized. 2009-03-03 jkerihuel [r1270] Ensure NSPI server functions have a valid dcesrv_handle [r1269] Add quick/additional configuration information on how to setup openchange server [r1268] This commit adds a retval check on private data retrieval function and prevents QueryPosition from causing a segfault when parent object is meant to come from GetContentsTable. [r1267] - Fix NspiGetMatches server reply when specified username is invalid and search fails. - Make use of talloc hierarchy for NspiGetProps properties fetch + fix a talloc_free bug leading to segfault on failure. [r1265] Prevent from registering same mapistore backend multiple times bradh [r1266] Howto updates. 2009-03-02 jkerihuel [r1261] Add skeleton for GetRulesTable [r1258] - return MAPI_E_SUCCESS when QueryRows reply count is 0 - Move Reminders from IPM Subtree to Mailbox root [r1257] - Add QueryPosition implementation - Move from offset to numerator/denominator couple for table objects Outlook now opens properly using openchange server and display the mailbox folder list with icons ;-) [r1256] - Add skeletons for Restrict, SortTable, FindRow calls - Introduce emsmdb provider table object - Add preliminary table implementation for system/special folders - Add preliminary implementation of GetHierarchyTable, SetColumns and QueryRows - Improve creation of GetProps reply blob for Mailbox folder - Fix bug in EcRRegisterPushNotification when associated handle is invalid - Remove some usage of ldb_filter and use format string instead - Update libmapiserver sanity checks and look for error_code != MAPI_E_SUCCESS so openchange server is able to return failed replies to MAPI clients - Introduce flaggedPropertyRows in libmapiserver_push_property (needed by QueryRows) This commit makes openchange server work with "openchangeclient --mailbox" ;-) Still preliminary but anyway worthwhile enough to be mentioned ... [r1255] - Add a function to count subfolders of a container - Add a function to wrap MAPI tables over openchangedb - Factorize code used to fetch property values from LDB records [r1254] - Add default properties to folder records while provisioning mailbox - Add few more mapping for PR_* to PidTag - Add a new MAPI property to the list [r1253] Avoid openchangeclient --mailbox to segfault when run vs openchange server bradh [r1263] Remove some ldb_filters, and just use varargs into ldb_search [r1262] warning fix for 64-bit arch. [r1260] Revert previous commit. [r1259] Experimental commit to fix build problems resulting from property changes. 2009-03-01 jkerihuel [r1251] - Add PidTagDisplayName property to Mailbox object - Add PidTagParentFolderId to all system/special folders [r1250] - handles array depends if a valid mapi_repl exists. This commit fixes the destructor semantics. - Fix a mapitest segfault encountered while run vs openchange server - Return 1 in SRowSet_propcpy if an error was encountered. [r1249] Fix libmapi stack segfault when MAPI calls returns with error_code different from MAPI_E_SUCCESS. [r1248] Do not process NSPI request if we can't find the handle [r1247] Remove unnecessary ldb_filter parameter and replace it with ldb_search format string. 2009-02-28 jkerihuel [r1245] - GetPropertyIdsFromNames skeleton added [r1244] - Fix how Release replies are handled in mapi_repl[] array - Remove Release size calculation - Fix QueryRows size in libmapiserver - Add a dummy/skeleton GetPropertiesSpecific function for mapistore objects. - GetHierarchyTable skeleton added - SetProperties skeleton added - CreateMessage skeleton added - SaveChangesMessage skeleton added 2009-02-27 jkerihuel [r1241] Set mapi_response to NULL upon init ... just to get sure [r1240] Fix MAPIUninitialize segfault bradh [r1242] Warning fix. 2009-02-26 jkerihuel [r1238] - Add skeleton for GetContentsTable Rop - Add skeleton for some [MS-OXCTABL] Rops: SetColumns, SortTable, QueryRows, SeekRows - Add libmapiserver size calculation functions for all the above - Ensure we only set objects parameter if it exists - Return when dcesrv handle is not available [r1236] Merge s4-alpha7 branch back into trunk 2009-02-25 jkerihuel [r1227] - Add several PidTag to openchange.ldb folders - Add provisioning convenient function which adds attribute/value pair to a given folder record - Replace existing special folders reference within Inbox with PidTagIpm* tags - Add new PidTag values to mapi-properties - Add a function to libmapiproxy to build a folder EntryID as described in MS-OXODATA - Add a function which builds special properties for openchangedb folders - Add PT_BOOLEAN case to openchangedb folder get property function - Keep a reference to the mailbox username within emsmdb provider context - Create and return a handle in RegisterNotification [r1226] Improve PT_I8 dump [r1225] Wrong MessageClass size calculation fixed jelmer [r1229] Remove duplicate _GNU_SOURCE definition (already specified by Makefile) [r1228] Ignore new binary and trial output. 2009-02-24 jkerihuel [r1223] - Fix systemfolder value for System/Special folders - Add GetProps support to System/Special folders [r1222] Add auto-generated parser to the ignore list [r1221] - Add auto-generated parser for MAPI property to PidTag mapping - Add some PidTag values - Add a lookup and get property functions on system folders [r1220] - tuple SystemIdx in the dictionnary to workaround the ordering problem - Add ParentFolderId attribute to System Folders [r1217] - Add creation of "Special folders" to mailbox provisioning - Rename fid attribute to PidTagFolderId - Rename name attribute to PidTagDisplayName - Rename ExplicitContainerClass to PidTagContainerClass [r1216] Fix GlobalCount increment [r1215] Fix mailbox provisioning bradh [r1219] Add test for FILETIME structure. [r1218] Update docs for mapiproxy entry. jelmer [r1214] Fix handling of fids. 2009-02-23 jkerihuel [r1208] - Fix openchangedb mailbox hierarchy and introduces subfolders as described in [MS-OXOFOLDS] specifications. - Update openchangedb API to reflect this change. [r1207] Rename private mailbox folder "non_ipm_subtree" to "mailbox_root" to fit with MS-OXOFOLDS specifications. [r1206] - Add provisioning code for GetReceiveFolder defaults - Check if mapistore content repository already exists for the user - Make mailbox creation verbose jelmer [r1213] Fix parentfolder reference. [r1212] Fix syntax error. [r1211] Use recursive call to create folders. [r1210] Simplify list iteration, PEP8, avoid using string exceptions. 2009-02-22 jkerihuel [r1204] Fix 'dereferencing type-punned pointer' warnings [r1203] - Add strict-aliasing compiler flags - Fix format string warnings on ubuntu buildbot [r1202] - Add _FORTIFY_SOURCE=2 to the compiler CFLAGS - Fix warnings introduced by -D_FORTIFY_SOURCE bradh [r1201] I might have been a bit hasty with that last commit... Need sqlite3. [r1200] Try harder to find sqlite3. Seems to be in sqlite.pc on Ubuntu. [r1198] Fix warning on 64-bit arch. 2009-02-21 jkerihuel [r1197] - Add RopGetReceiveFolder (0x27) implementation The function respects should respect the semantics and behavior as described in MS-OXCSTOR specifications. However the python's code modification required: add ExplicitMessageClass attributes to folder records is not yet effective. - Add GetReceiveFolder size calculation function to libmapiserver - Add a function to openchangedb API to retrieve the FID/ExplicitMessageClass couple for a given SystemFolder within user's mailbox. [r1196] - Provision scripts: create a mapistore default storage space within ${private}/mapistore/${username} - Provision scripts: add default sqlite:// mapistore URI for system folders - Add mapistore context initialization when calling OpenFolder on SystemFolder - Add mapistore context release for folders in emsmdbp object destructor [r1195] Factorize emsmdbp objects Add emsmdbp_object generic talloc destructor bradh [r1194] Add test for PT_MV_LONG. [r1193] Add tests for PT_I8 and PT_BINARY [r1192] Fix warning about no newline at end of file. Remove most recently added tests from "to be done" list. [r1191] Add a couple more mapi_SPropValue tests. 2009-02-19 jkerihuel [r1189] - Initialize mapistore within emsmdb provider context - Add destructors for MAPI handles and mapistore contexts - Remove emsmdbp_ctx memory context structure member and allocate directly with emsmdbp_ctx [r1188] I don't see any good reason why we would pad MAPI replies with some bytes. I guess it comes from some prehistoric openchange code. [r1187] Fix systemfolder assignment depending on IsSystemFolder value [r1186] - Initialize OpenFolder server reply [r1185] - Wrap TDB connections to mapistore (code from samba4) so multiple instances can open read/write to the same TDB database - Remove static id_mapping_context (replaced with tdb_wrap calls) - Update mapistore linkage rules so mapistore can be used with exchange_emsmdb server - Link mapistore with exchange_emsmdb [r1183] Fix aclocal warning for AC_DEFINE comparison_fn_t [r1182] Remove useless GetProfilePtr from IProfAdmin interface Closes trac ticket #131 [r1181] Add missing script - prevent configure from generating warning vs missing file. [r1180] Remove stamp-h1 file during distclean and add it to the ignore list. [r1179] - Add server-side GetReceiveFolder (0x27) skeleton [r1178] Work around the comparison_fn_t redefinition problem between libocpf and ndr.h [r1177] FreeBSD doesn't have time.h daylight global variable bradh [r1184] start testing mapi_SPropValue_array. This also tests some underlying functions. 2009-02-18 jkerihuel [r1175] Add comparison_fn_t support to ndr.h This was the latest change require to make openchange compiles under FreeBSD = samba4/openchange FreeBSD support completed = 2009-02-17 jkerihuel [r1173] Remove duplicated post_install call [r1172] Add a post_install operation on FreeBSD Make sure pidl is installed properly. [r1171] Patch samba4 tarball so it compiles properly on FreeBSD 7.0 Note: this is a dirty hack which needs to be removed in the future [r1170] Install Samba4 correctly although user's PKG_CONFIG_PATH env variable may not be adjusted properly. [r1169] Avoid download samba4 release tarball if already available in current directory. [r1168] - Add test for comparison_fn_t in configure.ac - libocpf auto-generated files include stdlib.h and prevent from having the proper comparison_fn_t typedef. This commit works around this problem and define comparison_fn_t within a private header. [r1165] getline is a stdio GNU_SOURCE extension not available under FreeBSD. Use fgetln instead when it is compiled on this OS. [r1164] FreeBSD doesn't define sighandler_t but sig_t [r1163] Replace open() call with O_DIRECTORY flag (Linux specific) with opendir [r1162] - Add non-default search path /usr/local/{include,lib} to CFLAGS and LDFLAGS when compiling OpenChange under FreeBSD - Make use of LDFLAGS while compiling openchange tools bradh [r1167] A few improvements for property handling. Also add unit tests to verify behaviour is correct. The implementation for the FlatUID (GUID) structure appears broken. Perhaps I'm not using it correctly. [r1166] Microsoft confirmed the LCID is wrong in the spec, and will be updated in the next rev. 2009-02-16 jkerihuel [r1160] Check for Flex version < 2.5.35 Make sure users can define the FLEX environment variable [r1159] Add automake scripts for AC_CANONICAL_HOST support Needed for FreeBSD OS detection in configure.ac 2009-02-14 bradh [r1153] Fix warnings from lexer output. [r1152] Fixes for warnings on 64-bit architectures. [r1151] Fix warning on 64-bit architecture. jelmer [r1157] Add some more tests for openchange.mailbox. [r1156] Fix creation of new mailbox after provision. [r1155] Always use the same URL when connecting to openchangedb. [r1154] Fix arguments to openchangedb_provision. 2009-02-13 jkerihuel [r1149] Fix libmapi 64-bit machine cast warnings mentioned in Brad's devel email bradh [r1148] Warning fix for 64-bit arch. 2009-02-12 jkerihuel [r1146] Add doxygen definition for RopRelease [r1145] - Add server-side skeleton implementation for RopOpenFolder and RopRegisterNotification - Add preliminary size calculation functions in libmapiserver for the 2 calls above - Fix size bug for serialized requests - Add skeleton case for RopGetPropertiesSpecific on SystemFolders - Make sure the GetProps reply blob is initialized whatever happen - Add a skeleton emsmdbp folder object init function 2009-02-11 jkerihuel [r1143] Remove debug strings for GetPropertiesSpecific Rop [r1142] Enable verbose output in server mode - useful during development [r1141] Implement preliminary server-side RopGetPropertiesSpecific call for mailbox object. [r1140] - Fix GetProps blob for PT_BINARY: use SBinary_short instead of Binary_r - Fix GetProps size: subcontext is not added to the fixed size calculation [r1133] - GetPropsSpecific size calculation function added to libmapiserver - Function to create a GetProps reply property blob added to libmapiserver jelmer [r1139] Add tests for provisioning. [r1138] Several cleanups in python code, add tests for schema use. [r1137] Don't clear PYTHONPATH override. [r1136] Remove unused imports, add extra tests. [r1135] Use member variable for Ldb, rather than subclassing. [r1134] Remove print statements to avoid cluttering test output. [r1130] Add simple and incomplete testcase for OpenChangeDB. [r1129] Move wipe of data to mailbox.py, simplify arguments to add_root_mailbox. [r1128] Move adding a server to mailbox.py. [r1127] Move ldif from oc_provision_openchange.ldif into Python. [r1126] Stop providing setup_path to OpenChangeDB, as it's no longer used. [r1125] Avoid using separate LDIF file when creating folder mailboxes. [r1124] Avoid using separate LDIF file when creating mailboxes. [r1123] Avoid passing full names object. [r1122] Add check-python target. 2009-02-10 jelmer [r1120] fix openchange_newuser. [r1119] Use SamDB for actual SAM databases, Ldb otherwise. [r1118] Remove unused parameters, don't make parameters optional if they are mandatory. [r1117] remove unused parameters. [r1116] make mailbox object-oriented, remove creds/lp parameters. [r1115] Fix OpenChangeDB syntax. 2009-02-09 jkerihuel [r1113] - Add a systemfolder member to the MAPI handle structure to make a difference between objects managed by mapistore and those stored within openchange.ldb (root mailbox folders). - Add opaque functions to set/get private_data and systemfolder to the MAPI handles API. [r1112] Minor doxygen fix/improvement [r1109] Add libmapistore object files to the ignore list [r1108] - Add a very preliminary and light libmapistore implementation. mapistore only supplies init/release and add/del backend contexts. This commit also includes a sqlite3 backend skeleton (open/close sqlite db) - A temporary mapistore testing tool has been added locally for implementation checks. jelmer [r1111] Use convenience function for connecting to openchange.ldb. [r1110] Use standard LDB functions - openchange.ldb is not a SAM database. 2009-02-08 bradh [r1106] Implement support the SUMMARY language tag. [r1105] Initial checking of libical based exchange2ical code. This has a long way to go, so think of this as more of a checkpoint than a release. See http://sourceforge.net/projects/freeassociation/ for the library, or see if your distro has a package. [r1104] Reduce warnings. [r1103] Add missing parameter to API documentation. Resolves ticket #130. [r1102] API documentation fixes for OpenEmbeddedMessage() [r1101] Implement OpenEmbeddedMessage ROP (0x46). Resolves Ticket #93 [r1100] Factor out message creation and message fill actions. Also remove GetLastError() where appropriate. [r1099] Add some API documentation. 2009-02-07 jkerihuel [r1097] Update openchangepfadmin description Fix tool relying on libmapiadmin bradh [r1096] Minor code tweak. Fix ticket #132. [r1095] Add more explanation for README [r1094] Reimplement RTF decompression. Add unit tests from MS-OXRTFCP. [r1093] Fix warnings in example code [r1092] Add description for libmapiadmin [r1091] Add description for libmapi / libmapi++ [r1090] Start on the directory descriptions. [r1089] doc/ pointers 2009-02-06 bradh [r1088] Add overview. Extracted from API docs. [r1087] Additional docs. [r1084] Outline of README file. (also using this to test buildbot without changing real code) 2009-02-05 jkerihuel [r1081] Add Version field - avoid breaking pkg-config --list-all [r1080] Fix warnings (gcc 4.2.4) jelmer [r1083] Use variable for package version rather than hardcoding it. 2009-02-04 jkerihuel [r1078] Fix pc file libs 2009-02-03 jkerihuel [r1070] - Add an implementation of the MAPI handles management API. The API internally uses an in-memory TDB database to keep object hierarchy and a doubled chained list to associate private data to handles. The API currently provides add, search and delete facilities. Note that while untested, the delete operation is designed to recursively delete children of the 'meant to be deleted' handle. Finally the API doesn't remove TDB records but mark them as free so they can be reused across MAPI session and prevent from handle counter growing indefinitely. - Add a preliminary implementation of the Release call - Add Release size calculation to libmapiserver - Update EMSMDB provider to use MAPI handles API bradh [r1075] Minor api documentation fix. [r1074] Minor API docs fix. [r1073] Minor API docs fix. [r1072] Minor API docs tweak. [r1071] Token commit of tiny API docs fix. jelmer [r1076] Look for GNU make harder (gmake on BSDs). 2009-02-02 jkerihuel [r1068] - Add preliminary EMSMDB provider implementation for RopLogon (0xFE) - Add common routines for OpenChange LDB context init and search within libmapiproxy - Add libmapiserver skeleton with size calculation routine for RopLogon - Change DSO linking dependencies for mapiproxy shared libraries - Propagate _GNU_SOURCE change from libmapi.h to mapiproxy 2009-02-01 jkerihuel [r1067] Remove .po and .o objects within libmapiproxy subdirectory [r1066] Move libmapiproxy into its own directory and rebase mapiproxy headers accordingly Fix make uninstall for AD and profiles directories [r1064] doxygen typo fix [r1063] Add python code and ldif files needed to create and populate the experimental openchange dispatcher database. [r1062] Add 5-Minute configuration documentation for OpenChange server mode [r1061] - Rebase ldif files into sub directories: * AD for OpenChange AD modifications * profiles for OpenChange IProfAdmin interface - Makes it easier figuring out LDIF files scope - Prepare setup folder for LDIF openchangedb files integration - Update install/uninstall Makefile rules for ldif files and make sure everything got removed bradh [r1060] Add forgotten file. [r1059] Add support for short language names (e.g. en-AU) for lcid. 2009-01-31 jkerihuel [r1057] Delete deprecated libmapi setup Perl script bradh [r1056] Add summary report for tests. [r1055] Make mapitest return the number of failed tests. 2009-01-29 jkerihuel [r1052] - Add pkg-config pc file for libmapiproxy - Improve mapiproxy rules so libmapiproxy gets installed and cleaned properly [r1051] Free memory allocated by the fake subcontext in ndr_pull_mapi_response. This fix saves 300kb of memory and removes 700 loss records while valgrinding mapitest. [r1050] Fix segfault - Add sanity check - when SPropTagArray is NULL in NspiQueryRows request [r1048] Fix openchange_newuser name typo [r1047] Fix server provisioning command line examples [r1045] Fix several libmapi leaks. mapi_response was allocated using emsmdb_ctx->mem_ctx memory context and was not free'd when libmapi function released their context. Furthermore we need to release mapi_response->mapi_repl and mapi_response->handles which are now automatically free'd when mapi_response destructor is called. However note that this fix is not perfect: mapi_response memory is not free'd properly when calls exit with an error. This commit also make use of talloc_steal where necessary to keep returned fields allocated. 2009-01-28 jkerihuel [r1040] Use named context rather than autofree [r1039] Fix memory leak in emsmdb.c: Use a temporary memory context for request and length allocation in emsmdb_transaction. - This removes 827 loss records and approximatively saves 41kb of memory while valgrinding mapitest [r1038] - Fix memory leak in GetDefaultProfile and GetProfileTable. - Save from 10 loss records while valgrinding mapitest - Developers are now responsible from freeing the GetDefaultProfile string the function allocates. - Apply changes to all openchange tools. [r1037] Add blackbox subunit tests for mapiprofile tool bradh [r1043] One more trivial fix. [r1042] Typo fixes. (Yep, more trivial changes) [r1041] Fix incorrect LCID for en-CA. (OK, its token, I admit). jelmer [r1044] Don't define _GNU_SOURCE unconditionally. 2009-01-27 jkerihuel [r1036] Prevent mapiproxy from multiple init and modules/server register when an smb client connect to the server (e.g. windows browser or smbclient) 2009-01-26 bradh [r1033] According to [MS-OXOCAL] Section 2.2.1.44.1 "RecurrencePattern Structure", a monthly recurrence also has a Day specific parameter. Add that here. jelmer [r1035] Simply run autogen.sh rather than replicating it inside the Makefile. [r1034] need to run aclocal before autoconf for the pkg-config macros. 2009-01-25 jkerihuel [r1032] Use a autofree context rather than a named one - makes sure memory is free'd when we exit the test. Saves from 4 loss records while valgrind'ing mapitest. [r1031] Use temporary memory context for EcDoConnect. Saves from 20 loss records when valgrind'ing mapitest. [r1030] Free PropertyProblem structures returned by CopyTo. [r1029] Replace deprecated talloc_init calls with talloc_named This commit removes some valgrind loss records talloc_init was responsible for [r1028] Free everything Free everything when running mapitest --list-all. Valgrind however shows a loss record related to talloc_init ... bradh [r1027] Minor Intel C compiler warning fixes. [r1026] Minor apidocs cleanups. 2009-01-24 jkerihuel [r1024] Use double pointer for lp_ctx in GetLoadparmContext assessor [r1023] Fix memory leak in utf8 lexer. [r1022] - Remove custom iconv_convenience from pull_emsmdb_property and use lp_iconv_convenience on loadparm_context argument instead. - Change OpenChange libmapi API to reflect this change - Introduce a lp_ctx assessor in libmapi/cdo_mapi.c (mostly for mapitest modules). libmapi/mapiproxy developers should never have to make use of it. - Remove pointless duplicated call to lp_load_default in MAPIInitialize. [r1021] Free lpProps returned by GetProps, Fix context error in valgrind [r1020] - Fix memory leak bug: release ndr context in pull_emsmdb_property before returning - Terminate SPropValue and SPropTagArray using an element with ulPropTag = 0. This prevent from "invalid read size of 4" messages from valgrind and remove context errors. jelmer [r1025] Don't install mapiproxy if python wasn't found, since we wouldn't know where to install the provisioning scripts or be able to use them. 2009-01-20 jkerihuel [r1018] Merge libmapi-0.8 branch r1015 to 1017 into trunk [r1015] ** Start libmapi-0.9 COCHRANE development ** [r1014] Merge libmapi-0.8 branch changes into trunk 2009-01-18 jkerihuel [r1007] Add python install/uninstall rules to provision rather than mapiproxy-servers [r1006] - Remove server Makefile rules - Remove dead code Note: server and providers have been merged within mapiproxy, so there is no reason keeping this deprecated code. 2009-01-17 jkerihuel [r1005] Undoing change committed in r1004. [r1004] Use .po files instead of .o files for openchange tools [r1003] Add --version to openchange tools [r1002] Add COPYING file with GPLv3 license 2009-01-16 jkerihuel [r1001] - Add RenameProfile function to IProfAdmin API - Remove pointless CopyProfile from IProfAdmin API - Add --rename option to mapiprofile tool - Update man page to reflect this addition (close trac ticket #124) [r1000] Fix libmapi from crashing when mapi_repl is NULL. [r999] Update Samba4 git rev to fix the charcnv segfault met in openchange tools jelmer [r998] Try to find the Samba python modules if they're not installed in the system python directory. 2009-01-15 jkerihuel [r997] - Fix Subscribe semantic bug and add WholeStore boolean parameter - propagate API change to tools/torture callers [r996] - Add assessor functions to set dumpdata and debug level in libmapi (SetMAPIDumpData and SetMAPIDebugLevel) - OpenChange tools modified to use these function rather than set these parameters on their own [r995] - Fix --debuglevel segfault in openchange tools - Enable logging to stdout in MAPIInitialize 2009-01-14 jkerihuel [r994] * OpenChange libmapi function now returns MAPI error instead of -1 - use OPENCHANGE_RETVAL_IF instead of MAPI_RETVAL_IF - add doxygen documentation for some missing functions/files [r993] - Missed this event->tevent change in previous commit [r992] - Update openchange to use latest Samba4 master git rev (990491d) - Fix references to tevent_context structures - Fix iconv_convenience init in MAPIInitialize - Remove errorchecks mapitest module warning jelmer [r991] Use tevent_context_init. [r990] Ignore binaries. 2009-01-13 jkerihuel [r989] Some Exchange server (stand-alone) return MAPI_E_LOGON_FAILED when setting EssDN with username rather than using profile's mailbox string directly. This commit fixes the bug. [r988] - Add EcDoConnect and EcDoDisconnect preliminary support to dcesrv_exchange_emsmdb.c - Add internal session management mechanism to EMSMDB server - Add init and unbind modules function to EMSMDB server - Add emsmdbp_context and session to dcesrv_exchange_emsmdb.h bradh [r987] Fix valgrind errors caused by using free'd memory. 2009-01-12 jkerihuel [r986] Implement 'mapiproxy downgrade' behavior in EMSMDB server and force Outlook to use EcDoConnect (0x0) and EcDoRpc (0x2) rather than 0xA and 0xB (opnums using LZ based compression). [r985] - Add Preliminary implementation for RfrGetFQDNFromLegacyDN DS RFR server 2009-01-11 jkerihuel [r984] - Preliminary implementation of NspiGetProps NSPI server function - Makes sure emsabp_tdb_traverse_MId uses the correct dbuf size - Use correct ldb context (users or conf) depending on where MId is located (on-memory or on-disk) - Add PR_EMS_AB_NETWORK_ADDRESS mapping to emsabp_property *** Outlook is now able to create MAPI profile using OpenChange Server ONLY! *** [r983] - Preliminary implementation of NspiDNToMId NSPI server function - Add emsabp_search_legacyExchangeDN to search for a record given its legacyExchangeDN attribute. [r982] - Preliminary implementation of NspiQueryRows NSPI server function added - fix a bug in the MID TDB traversal routine: cut dptr to dsize length rather assuming it is NULL terminated - Add support for "referenced" property tags - Add support for PR_MV_STRING8 - Add emsabp_search_dn which search for a DN within AD and return the associated LDB message - Add PR_EMS_AB_HOME_MDB and PR_EMS_AB_PROXY_ADDRESSES to emsabp_property array [r981] Prevent from trying to add a NULL element to profile database and segfault on strlen [r980] Prevent x500_get_dn_element from segfaulting when an incorrect DN string parameter is supplied [r979] - Preliminary implementation of NspiGetMatches NSPI server function - Make use of a on-memory TDB database for Ephemeral Entry IDs - Add TDB traversal routines to retrieve DN associated to MId - Move lp_ctx within emsabp_ctx for convenience - Add EphemeralEntryID to Binary_r routine - add emsabp_query (Find attribute matching given property tag and return associated data) - add emsabp_fetch_attrs which builds a SRow array given a MId and requested property tags. - add emsabp_search which searches AD given input search criteria - add a preliminary Property Tag to AD attribute mapping + associated functions in emsabp_property.c Note: This NspiGetMatches is limited to MAILUSER which means we only look for users (located within users.ldb). This limitation will be removed when we have a preliminary working emsmdb server, so we can do more extensive NSPI server tests. [r978] Add sanity check to get_SPropValue_SRowSet, prevents the function from segfault when RowSet is NULL (e.g. crafted NspiQueryRows replies) [r977] Prevent IProfAdmin based code from crashing when a crafted NspiGetMatches reply with NULL ppOutMIds is returned. 2009-01-10 jkerihuel [r976] - Preliminary NspiGetSpecialTable implementation added to NSPI server/EMSABP provider: Hierarchy Table supported (required during profile creation) - add PT_BINARY support for mapidump_SPropValue - fix a bug when PT_STRING8 or PT_UNICODE pointer is set to MAPI_E_NOT_FOUND 2009-01-06 jkerihuel [r974] Add new Display Type values (used by EMSABP provider) [r973] Change DEBUGLEVEL for RfrGetNewDSA [r972] - preliminary implementation of RFR server (RfrGetNewDSA): makes Outlook happy - mapiproxy-servers-install now installs openchange python scripts and ldif file 2009-01-05 jkerihuel [r971] Move auth_serversupplied_info structure from dcesrv_exchange_nsp.h to libmapiproxy.h This structure is required for NTLM_AUTH_IS_OK macro [r969] - Add doxygen comments for all OpenChange server modules - Fix doxygen return value for exchange_nsp [r968] - Add mapiproxy server unbind function and hook in dcesrv_mapiproxy.c - Add exchange handle enum to dcesrv_mapiproxy.h - Add authentication verifier macro to libmapiproxy.h - Add preliminary EMSABP Address Book Provider implementation: * supports initialization, destructor (talloc) * implements user and codepage check routines * retrieve NSPI server GUID - Add NspiBind and NspiUnbind support to dcesrv_exchange_nsp.c - Add internal session mechanism management to NSPI server - Add init and unbind modules function to NSPI server - Add doxygen comments to all dcesrv_exchange_nsp.c functions - Add emsabp_context, session and non-exported Samba structure to dcesrv_exchange_nsp.h [r967] OpenChange configuration schema updated with Addressing schema (Address-Templates, Address-Types and Display-Templates - Exchange 2003 based) [r966] Execute server modules init function when loaded bradh [r965] A few API documentation fixes. 2009-01-04 jkerihuel [r963] Add documentation for MAPIProxy 'server mode' 2009-01-02 jkerihuel [r961] - Implement mapiproxy server mode architecture - Add server modules management API - Add skeletons for default OpenChange servers (nspi, emsmdb, ds_rfr) - Add temporary provision Makefile rule 2008-12-30 jkerihuel [r959] Initial text was correct - rollback [r958] Fix path typo bradh [r957] Ensure that GetLastError() also returns the correct value. [r956] Start changing the MAPI_RETVAL_IF() usage to two new macros: OPENCHANGE_RETVAL_IF() and OPENCHANGE_RETVAL_ERR(). simple_mapi.c is the only one converted at this stage. Also added a set of unit tests that verify at least some initial sanity checks. [r955] Remove unreachable code. Partly resolves ticket #124 2008-12-29 jkerihuel [r953] Remove references to ldap.h header file - not installed anymore with samba4 git rev openchange uses [r952] mapiproxy documentation update: 3 questions added to FAQ section [r951] Patch from Corentin Chary: - Add PR_CONTENT_FILTER_SCL property to libmapi [r950] - Update openchange to work with samba4 master git rev f308c2f - Replace reference to events.h with tevent.h - Update installsamba4.sh script to reflect latest samba4 compilation changes/requirements 2008-12-27 jkerihuel [r948] Fix mapidump date/month when freebusy period covers end of one year - beginning of next year Update openchangeclient to reflect these changes. 2008-12-24 jelmer [r946] Export PKG_CONFIG_PATH if it wasn't exported yet. Patch by Metze [r945] Fix PIC object flags for SWIG build. Patch by metze. 2008-12-21 bradh [r943] User %u format specifier for unsigned integer. [r942] Make return value match signature. [r941] Miscellaneous minor cleanups. Mainly making return types match signatues, format conversion (%u for unsigned values) and matching up result variable types (bool instead of enum MAPISTATUS). [r940] Return an enum MAPISTATUS, instead of a bool, to match function signature. [r939] Use %u instead of %d for unsigned values. 2008-12-20 bradh [r937] Another minor APIdox edit. [r936] API documentation tweak. [r935] API dox fix. [r934] API dox fix. [r933] Minor apidox fixes. [r932] More apidox triviality. [r931] Trivial APIdox edits. [r930] Supplement the user's PKG_CONFIG_PATH rather than overriding it. jelmer [r929] Add bindings for GetBestBody(), GetDefaultFolder(), GetDefaultPublicFolder(), AddUserPermission(), ModifyUserPermission(). [r928] Add bindings for create_message, delete_messages, get_message_status, set_read_flags. [r927] Add Python bindings for Unsubscribe(), get_task_status(), get_importance(), get_proptag_name(), get_proptag_value(), DeleteFolder(), CreateFolder(), EmptyFolder(), RemoveUserPermissions(), IsMailboxFolder(). 2008-12-19 jelmer [r925] Actually use pymapi variables in Makefile. [r924] Add configure flags for building and installing Python MAPI bindings (disabled by default). 2008-12-18 bradh [r922] Add namespace prefix to scanner. 2008-12-16 jkerihuel [r920] - spnego / gssapi_krb5 authentication now available for mapiprofile - add the --realm | -R option - update mapiprofile man page 2008-12-14 bradh [r912] Remove entries for --properties and --priority, which have been removed from the openchangeclient utility. Partly fixes #113. [r911] Don't generate / install man3 pages for libmapi++ or mapitest. Resolves ticket #121. Also don't install man3 pages that are just copies of the C implementation files, or just document bugs / todo items. jelmer [r918] Allow retrieving id and session of MAPI objects. [r917] Add MessageStore and Object Python classes, add bindings for OpenMsgStore, OpenUserMailbox, OpenPublicFolder. [r916] Add stubs for Session class. [r915] Add infrastructure for MAPI python module. [r914] Look for python and python-config binaries. [r913] Remove empty directory. 2008-12-13 jkerihuel [r910] Remove obsolete --properties option and related code 2008-12-10 jkerihuel [r908] Fix RecipientRow member's order 2008-12-09 jkerihuel [r906] - Update to latest samba4 git master revision (3508a66) - Fix references to samr info24 struct - Add support for assoc_group_id proxy - Add support in mapiproxy for bind/alter connections using assoc_group_id - Update mapiproxy documentation 2008-12-07 bradh [r904] Improve building. Partially addresses #94. More work required on this as we work on the portability in the future. [r903] Expose the underlying session. 2008-11-30 bradh [r901] Remove unused --priority option. [r900] These offsets / values can be negative, so we shouldn't use unsigned int type to represent them. 2008-11-29 jkerihuel [r898] Fix Logon problem for users running Exchange 2k7 in a clustered Exchange environment. This patch first tries to forge EssDN Logon string from "o" and "ou" attributes stored in the profile. If Logon fails with ecUnknownUser, then try to open the mailbox using the mailbox attribute stored in the profile. 2008-11-28 bradh [r896] Document the --label option. 2008-11-26 jkerihuel [r893] Make openchange compile and work against latest samba4 master git rev (58db2be) jelmer [r894] Remove check for unused type 'uint_t'. 2008-11-22 bradh [r888] More tweaks on the openchangeclient man1 page. [r887] More updates for man1 page for openchangeclient. Still doesn't fully address #113. [r886] Update the openchangeclient man1 page. Partly addresses ticket #113. There is still some work to do on this. [r885] Fix a typo, and try to make the descriptions more consistent. 2008-11-21 bradh [r883] Initial version of man1 page for mapitest [r882] Initial man1 page for exchange2ical utility. 2008-11-14 bradh [r879] Update man1 page for openchangepfadmin [r878] Minor updates for the man pages. 2008-11-13 jkerihuel [r875] Fix build errors: wrong number of arguments for ocpf_propvalue [r874] Fix warnings when compiling with -Wextra [r873] Fix warnings when compiling with -Wextra [r872] Fix warnings when compiling with -Wextra bradh [r876] Complete initializers here. 2008-11-10 bradh [r870] Update to reflect latest state of mapiprofile. 2008-11-09 bradh [r868] Prevent segfault when running mapitest. Looks like the we can return MAPI_E_SUCCESS even if one of the property values is MAPI_E_NOTFOUND. That error then get turned into a char*, and strncmp faults. Also fix a possible bug relating to operator precedence, and a couple of warnings (one for signed / unsigned comparison, and the other for an unsigned value never being less than zero). 2008-11-08 bradh [r866] Enable output to stdout. Resolves ticket #106. Thanks to raboof for the report and fix. 2008-11-07 bradh [r864] Fix missing initialisers (issue #110). Also fix some signed/unsigned warnings. [r863] Fix problems with incorrect initialisers (#110) and operator precedence. Also fix a couple of places with signed/unsigned confusion. [r862] Partial fix for issue #110, and a couple of very minor cleanups. 2008-11-06 bradh [r860] Minor cleanups. [r859] We probably want to return here, not do nothing. 2008-11-05 jkerihuel [r855] Fix empty patch function problem: add a retval bradh [r857] Typo fix. [r856] Explain the boost-thread trick. [r854] Minor documentation tweaks. 2008-11-04 jkerihuel [r852] - remove usage of global_loadparm in libmapiadmin - make use of session context rather than global_mapi_ctx in libmapiadmin - use local context rather than mapiadmin context in libmapiadmin - libmapiadmin now uses ldb helper rather than raw implementation (ldb async code) - libmapiadmin and openchangepfadmin now works again (user creation/deletion) !! ;-) - remove global_loadparm in torture test and replace it with torture context - fix dcerpc_init to match latest samba4 API - update samba4 version required to build openchange bradh [r850] More API documentation tweaks. [r849] More API documentation tweaks. [r848] Some API dox fixes for libmapi++. jelmer [r851] Remove unnecessary patching of lib/events/events.h. 2008-11-03 bradh [r846] Update to a more recent Samba4. jelmer [r845] Remove some usages of deprecated global_loadparm. [r844] Cope with new argument to dcerpc_log_packet(). 2008-11-01 jelmer [r842] Fix includes for DEBUG(), fix some more warnings. [r841] Use same_net_v4 rather than deprecated same_net(). [r840] Fix Samba 4 git revision. [r839] Fix includes - debug.h can only be included once. [r838] Include debug header. [r837] Cope with API changes in Samba functions. [r836] Use new function is_zero_ip_v4 rather than removed is_zero_ip. 2008-10-31 jkerihuel [r833] Fix OpenMsgStore binding in swig perl and fetchmail script 2008-10-21 jkerihuel [r824] Fix pointless const definition for GetFreeBusyYear return type 2008-10-20 jkerihuel [r823] - Add the IsFreeBusyConflict convenient function which checks if a given date conflicts with existing FreeBusy Busy/OOF events - Modify openchangeclient --sendappointment behavior to check whether start or end date conflicts with FreeBusy published data for the user. - Add the --force option to openchangeclient to override this behavior - Fix a counter bug in mapidump_freebusy_events [r821] Fix doxygen typo error [r820] - Add GetUserFreeBusyData convenient function which retrieves FreeBusy data in public folders for a given user. Note: Ambiguous name is not supported at the moment. - Add convenient FreeBusy mapidump routines - Add FreeBusy read support to openchangelient - Add PT_MV_LONG and PT_MV_BINARY support to pull_emsmdb_property and property.c functions - Add OpenUserMailbox which let developers open other mailboxes instead of the default profile one. - Add GetABRecipientInfo: convenient function which retrieves Address Book information for a given recipient 2008-10-17 jkerihuel [r818] - Add libmapi implementation for DeletePropertiesNoReplicate - Add mapitest test units for DeleteProps and DeletePropertiesNoReplicate [r817] Fix doxygen documentation 2008-10-16 jkerihuel [r815] - Implement multisession into libmapi - Update openchange tools and suite to reflect these changes - Fix SRow_addprop behavior NOTE: OpenMsgStore, ResolveNames, GetGALTable and RFR functions now take a mapi_session parameter. jelmer [r814] Use my openchange.org email address. 2008-10-09 jkerihuel [r812] - Add a session management API for mapiproxy modules. Similar code already existed for mpm_cache module. Common functions are now available to all mapiproxy modules through libmapiproxy - replace smbd with samba in mapiproxy documentation [r811] - Cache calendar, contact, journal, note, task and drafts folders IDs when GetDefaultFolder call is performed on one of these folders and keep them until obj_store is released. - Add a reverse lookup routine which says whether a given FID belongs to a default folder and which olFolderType it is. [r810] - Remove pointless memory context in GetDefaultFolder - Move entryID to FID code into a separated routine (GetFIDFromEntryID) [r809] Restore install rule for mapi profiles ldif files in libmapi-installscript. Fix the MAPI_E_NO_ACCESS bug when mapiprofile tries to create a new mapi profile store. 2008-10-08 jkerihuel [r808] - Ticket #103 resolved. openchangeclient can now perform custom folder lookup, fetch, mkdir and rmdir. - mapi_object_copy routine added to mapi_object.c 2008-10-06 jkerihuel [r806] Fix missing Month field in LogonTime structure 2008-10-05 jkerihuel [r805] propagate IDL warning fix to property.idl jelmer [r804] Add target for building python API documentation. 2008-10-01 jkerihuel [r802] Fix samba4 release and git revision [r801] Fix installsamba4.sh script paths jelmer [r803] Avoid warning. [r800] Install OpenChange python modules. [r799] Check for python dir during configure. [r798] ignore generated files. [r797] Stop installing js files. [r796] Use autoconf cache prefix. [r795] Use newer version of Samba 4. 2008-09-30 jkerihuel [r791] Remove dcesrv_exchange.so from server Makefile rule and move mapiproxy from TOOLS to SERVER. dcesrv_exchange and providers Makefile rules are orphan, planned to be removed (with their associated code) when emsabp merge process into mapiproxy is over. 2008-09-23 bradh [r790] Export the Binary_r structure. 2008-09-22 bradh [r789] Use more descriptive variable names in messages example code. [r788] Add a description of messages to libmapi++ API documentation. [r787] Add messages binary to the ignore list. [r786] Add new example showing libmapi++ message handling, and associated API documentation and build system changes. 2008-09-21 bradh [r785] Update the API documentation main page for libmapi++ 2008-09-19 jkerihuel [r784] Add foldertree binary to the ignore list [r783] - Add missing Input parameter - Add sanity check on ppNames - Fix ticket #102 [r781] - Fix a bug in NspiUpdateStat: make plDelta mandatory and use it for in,out - Add a NspiGetSpecialTable test for Address Creation Template bradh [r780] Fix valgrind-reported error, per ticket #101. [r779] Make sure we clean up after mapitest runs. Resolves ticket #84 2008-09-17 jkerihuel [r778] - Add msExchUserAccountControl attribute to extended user record - openchange_newuser can now create/enable/disable an OpenChange account [r776] Exit the test if the WriteStream operation fails [r773] Fix ncacn_ip_tcp binding string for OpenChange server object [r772] With new NSPI IDL, using cValues - 1 is incorrect and lead to errors. Use cValues directly instead [r771] Fix pipe function check and use ndr autogenerated defines rather than static strings Fix calls to NspiDNToMId bradh [r774] Make sure we set the body and body format properties, to ensure that the message is shown correctly with openchangeclient -F. 2008-09-16 jkerihuel [r770] - Fix provisioning - Rename oc_* python scripts to openchange_* - Add Full Exchange 2003 schema (classes and attributes) - Full Exchange 2003 modified classes and attributes support - Add prefixmap OID for some Exchange classes and attributes - Add missing ADSC classes and attributes - Improve configuration LDIF file with new objects NOTE: provision.py should find a way to handle firstorg properly NOTE: oc_provision_configuration.ldif is still incomplete bradh [r768] API documentation improvements. 2008-09-15 bradh [r767] Add an example to the libmapi++ documentation, and the right build magic and doxygen linkage. [r766] Minor API documentation fix 2008-09-14 bradh [r765] Add forgotten part of API documentation fixes for mapitest. [r764] Improve mapitest API documentation. 2008-09-13 bradh [r763] Use new DeleteFolder flags to clean up folders on deletion. This doesn't completely resolve ticket #84, but it does help. [r762] Ignore API documentation. [r761] Add Doxyfile to ignore list. [r760] Add initial support for Doxygen API documentation for libmapiadmin. 2008-09-12 bradh [r759] Implement the remainder of the standard public folders. 2008-09-10 bradh [r758] Only do header line removal at the start of the file (lines 20 through 40 seems like a good compromise). [r757] libmapi++ is C++, not C, so we should not optimise Doxygen output for C. 2008-09-09 jkerihuel [r755] - Update the Logon_repl IDL (0xFE) and implementation - Add new folders to the mapi_obj_store for PF folders - rename pf_finder to pf_search bradh [r756] Suppress some more unwanted headers. 2008-09-08 jkerihuel [r754] - Add GetStoreState (0x7b) IDL, implementation and mapitest unit [r753] Fix typo error [r752] - Update the EmptyFolder IDL [r751] - Update the SearchFlags enum, GetSearchCriteria and SetSearchCriteria IDL - Add mapitest units for GetSearchCriteria and SetSearchCriteria [r750] Link libmapi++ documentation to main apidocs page [r749] Update GetAttachmentTable IDL and remove the unknown field [r748] - Update DeleteFolder IDL and implementation - It now supports DeleteFolderFlags as input parameter and can return the ParticalCompletion state - Sanity checks added at the beginning of the function [r747] - Rename GetRowCount to QueryPosition - IDL, implementation, documentation and openchange code updated - ActionType enum fields prefixed with 'ActionType_'. Original values were causing conflicts while building Perl bindings with 'i386-linux-thread-multi/CORE/opnames.h where OP_DELETE was already defined' [r746] Change enum SaveFlags to uint8_t for doxygen documentation to be generated properly [r743] - Update SaveChangesMessage IDL and implementation - Add a SaveFlags parameter to SaveChangesMessage function - update openchange code to reflect this change bradh [r745] Build fix / fix for ticket #99. [r744] Filter out some new #include lines. This needs to be applied to other modules too. 2008-09-07 jkerihuel [r742] Update SRow and SRowSet IDL [r741] Delete obsolete input_locale and instance_key structures [r740] Fix WStringArray_r IDL [r739] - Move from MV_UNICODE_STRUCT and LPWSTR to WStringArray - LPWSTR structure removed [r738] Rename SDateTimeArray to DateTimeArray_r [r737] Rename SGuidArray to FlatUIDArray_r and fix the IDL [r736] Rename MV_LONG_STRUCT to LongArray_r [r735] Rename SBinary to Binary_r [r734] - Add removal of libmapi++ Doxyfile in make distclean rule - Add Doxyfile to svn:ignore [r733] Rename SShortArray to ShortArray_r [r732] - Move from SLPSTRArray to StringArray_r - LPSTR structure removed [r731] Rename MAPIUID to FlatUID_r [r730] Fix lexer warnings during compilation (ticket #100) [r729] - Update the EcDoConnect IDL (ref. ticket #99) - Add new fields to the emsmdb info structure - Add doxygen comments to libmapi/emsmdb.c bradh [r728] Reduce warnings when compiling with 64-bit arch. [r727] Initial checkin of infrastructure for libmapi++ API documentation. 2008-09-06 jkerihuel [r726] - MAJOR NSPI protocol and libmapi stack update - All NSPI protocol functions implemented - NSPI stack fully documented - NspiGetHierarchyInfo renamed to NspiGetSpecialTable - NspiDNToEph renamed to NspiDNToMId - instance_key removed from nspi_context and set as a parameter to NSPI functions - SPropertyRestriction renamed to PropertyRestriction_r - FlagList structure removed and replaced by a SPropTagArray - MAPI_SETTINGS removed and replaced by a STAT structure - new MAPI property tags added to libmapi/conf/mapi-properties - NSPI module added to mapitest bradh [r725] Clean up on failure. [r724] Clean up on failure. [r723] Minor improvements to ensure cleanup on failure. [r722] API documentation fix [r721] API documentation fix. [r720] API documentation fix. [r719] API documentation fix. [r718] API documentation fixes. 2008-09-05 bradh [r717] API documentation fixes. 2008-09-04 jkerihuel [r716] Fix EMSMDB 0xb function name [r715] - update EcRRegisterPushNotification IDL - update Notify IDL - implement complete MAPI notifications - update libmapi to reflect these changes - make openchangeclient prints a brief summary for each notification found - update ulEventMask used in openchangeclient 2008-09-03 jkerihuel [r714] - Rename Advise MAPI call to RegisterNotification - Update RegisterNotification IDL and implementation 2008-09-02 jkerihuel [r713] - Fix Restrict IDL and implementation - Add a new parameter to the Restrict function - close ticket #32 [r712] Add mapi_nameid.h to the ignore list [r711] - Replace libmapi/mapi_nameid.h with a generated mparse file - Add a mapi_nameid.h parser to mparse.pl - Add canonical names for named properties - GetProps and SetProps resolves named properties if they exist - named properties can now be set directly and make mapi_nameid API be optional. - replace named property tags hex value with their canonimal names - replace several use of the mapi_nameid API with smaller code [r710] - Add new IDL file (property.idl) to push/pull structures from binary blobs and not directly related to any MAPI calls. Include the generated property.h file into libmapi.h - Add PT_MV_STRING8 support in pull_emsmdb_property (GetProps reply parsing) and mapidump_SPropValue - Add functions to property.c to retrieve RecurrencePattern, TimeZoneStruct and GlobalObjectId structures (see property.idl). - add a preliminary version of exchange2ical tool. This version only dumps calendar folder appointments into ICS file on standard output. 2008-08-30 jkerihuel [r709] - Update mapi-nameid-properties with a more complete set of properties - Add a header to mapi-nameid-properties for sanity purposes - Move named properties with PT_STRING8 type to PT_UNICODE - update openchange code to reflect these changes - Add PSETID_Attachment to mapidefs.h 2008-08-28 jkerihuel [r707] Add missing check on password for the create command [r706] Fix incorrect usage of realm in mapiproxy 2008-08-27 jkerihuel [r705] Check for provider_rpc_connection retval for RFR functions. [r704] Update Doxyfile to parse mapiproxy/modules files and include documentation on static functions. [r703] - Add NSPI hook on NspiQueryRows and NspiDNToEph and replace the Exchange server name with mapiproxy one. - documentation updated to reflect these changes - new FAQ question added - developer documentation improved [r702] Add the RFR mapiproxy file. [r701] - Implement RfrGetNewDSA DN replacement in mapiproxy - use lp_realm rather than sockaddr in NspiGetProps (FQDN rather than IP address) - update mapiproxy documentation to reflect these changes 2008-08-26 jkerihuel [r698] - Add implementation of the NSPI Referral protocol (exchangeRFR) - update dcesrv_exchange and mapiproxy prototypes for RFR - add references to the RFR pipe in mapiproxy - prefix NSPI client connections with a RfrGetNewDSA call - add RFR functions implementation in libmapi/IMSProvider.c - add a --getfqdn option to mapiprofile - fix a minor mapiprofile option parsing bug 2008-08-25 jkerihuel [r697] Fix mapiproxy dummy module unbind prototype [r696] - Remove flags in EcDoRpc top function, fix compilation vs latest samba4-git version - EcDoRpc indent updated 2008-08-15 clsk [r694] Get rid of initialization order warning 2008-08-11 jkerihuel [r691] - add unbind hook for mapiproxy - add ahead mapiproxy mode - add read ahead in cache module - add synchronization mechanism in cache module - update mapiproxy documentation to reflect these changes 2008-08-08 bradh [r690] Temporarily comment out installation of files removed in r683. 2008-08-01 jelmer [r685] Fix arguments, paths in provision scripts. [r683] Merge python provision/newuser scripts. [r681] Simplify installation of manpages a bit. 2008-07-29 jkerihuel [r679] Add configure check for libboost-thread. Add libmapi++ to the build only if it is available. 2008-07-27 clsk [r678] - session constructor doesn't login to the server anymore, it calls MAPIInitialize(). - Created session::login() members. - test applications use default profile. 2008-07-26 jkerihuel [r676] - Import Alan Alvarez work from libmapi++ into trunk - Add a g++ check in configure.ac: don't call libmapi++ rules if g++ is missing - Add libmapi++ to the build system - Add a patch function to installsamba4.sh: rename private to private_data in samba4 events.h header file - Change #include directives so it uses SetMessageReadFlag renaming. This should have been part of r529 - missed it. 2008-05-30 jkerihuel [r535] merging from mapiproxy branch: - Fix MV_UNICODE_STRUCT and unicode strings - Keep LPWSTR for exchange_nsp and move from LPWSTR to mapi_LPWSTR for exchange_emsmdb - Add the NspiGetTemplateInfo IDL - Fix the NspiUpdateStat IDL [r534] Fix build: SetMessageReadFlag function name was not propagated in the module_oxcmsg.c bradh [r529] Initial merge of changes for rename of SetReadFlags to SetMessageReadFlags (op 0x11) and IDL for SetReadFlags (op 0x66). [r528] Use private_data instead of private, for C++ happiness. [r527] Minor cleanup. Using "try" confuses my c++ compiler... [r526] This is really part of r525. It moved to IMAPITable.c [r525] Update the table operations: - implement ExpandRow and CollapseRow - implement GetCollapseState and SetCollapseState - add mapitest coverage for the above, plus the Restrict call - implement ResetTable - implement FreeBookmark - add mapitest coverage for SRowSet parsing code - minor IDL fixes - various API documentation bits jelmer [r533] Use right directory for samba4_ver.sh script. [r532] Use common location for Samba 4 git revision. 2008-05-27 bradh [r522] Use PT_ERROR where appropriate. [r521] Update the SRowSet parser, fixing breakage I introduced. 2008-05-26 bradh [r518] Update examples to reflect recent API changes. jelmer [r520] Don't rely on absolute file paths since the distribution may be installing in other locations. [r519] make scripts executable. 2008-05-25 bradh [r515] Avoid segfaulting if you ask for a specific test or tests and forgot to start the server. Here is an example: [bradh@conferta trunk]$ ./bin/mapitest --mapi-calls=OXCTABLE-CATEGORY --mapi-calls=OXCTABLE-RESTRICT --mapi-calls=NOSERVER-LZFU Failed to connect host 192.168.11.77 on port 135 - NT_STATUS_HOST_UNREACHABLE Failed to connect host 192.168.11.77 (192.168.11.77) on port 135 - NT_STATUS_HOST_UNREACHABLE. MapiLogonEx : MAPI_E_RESERVED (0xFFFFFFFF) #############################[mapitest report]################################# [*] Date : Sun May 25 11:45:29 2008 [*] Confidential mode : [no] [*] Samba Information : 4.0.0alpha4-GIT-44d8b70 [*] OpenChange Information : 0.8-SVN-build-510 (Romulus) [*] System Information : Kernel name : Linux Kernel release : 2.6.23.17-88.fc7 Processor : x86_64 ############################################################################### [*] NOSERVER-LZFU [TEST] NOSERVER-LZFU ------------------------------------------------------------------------ * uncompress_rtf2 : 0x00000000 * uncompress_rtf2 : PASSED ------------------------------------------------------------------------ [RESULT] NOSERVER-LZFU: [SUCCESS] ======================================================================== [*] OXCTABLE-RESTRICT Server is offline, skipping test: "OXCTABLE-RESTRICT" [*] OXCTABLE-CATEGORY Server is offline, skipping test: "OXCTABLE-CATEGORY" 2008-05-24 bradh [r510] ignores objects that contain invalid handlers in mapi_object_release(). Patch by Alan Alvarez. Compile tested, passes mapitest on SBS2003. 2008-05-23 bradh [r507] Fix API documentation to match signature. 2008-05-20 bradh [r504] Update QueryRows IDL and implementation to match msdn documentation. The main work here is reworking the SRowSet parsing routine. 2008-05-18 bradh [r501] Typo fix - allow cleanup to work properly. 2008-05-17 bradh [r497] Make sure it has a return value. 2008-05-11 bradh [r495] Rename GetColumns remote operation to GetColumnsAll, and fix up IDL and implementation to match. Add some more unit test coverage, and pretty-up the output a little. [r494] Fix up breakage introduced in r493. jelmer [r496] Make sure nagios directory gets created if it didn't exist yet. 2008-05-10 bradh [r493] Refactor the unit tests. Extract out the setup and some of the cleanup code. 2008-05-08 jkerihuel [r490] - Update openchange code to work with Samba4 4.0.0alpha4-GIT-44d8b70 - Use event_context structure - update installsamba4.sh script to revert to this revision. - update torture modulesdir reference jelmer [r492] Look a little bit harder for the Samba installation. 2008-05-05 jkerihuel [r489] - Add GetLocalReplicaIds MAPI call (IDL + implementation + mapitest) - Add OXCFXICS mapitest module 2008-05-03 jkerihuel [r488] - Fix "the very secret" openchange coding style - Add Copyright for our humble new libmapi developer ;-) bradh [r487] Implement the CopyProperties operation, including a mapitest for this. 2008-05-02 jkerihuel [r485] - Add TransportSend MAPI call (IDL + implementation + mapitest). This code maybe needs some review regarding memory. [r484] - Add the GetTransportFolder MAPI call (IDL + implementation + mapitest) [r483] - Add SpoolerLockMessage MAPI call (IDL + implementation + mapitest) [r482] - Add SetSpooler MAPI call (IDL + implementation + mapitest) [r481] - Add GetRulesTable (IDL + implementation + mapitest) - Add the OXORULE mapitest suite bradh [r480] Typo fix. jelmer [r486] Make sure config.mk is the last file removed during distclean. 2008-05-01 jkerihuel [r479] - Add the Abort MAPI call (IDL + implementation) OpenChange doesn't support yet asynchronous operation which explains why no associated mapitest test has been implemented. This should be done in the future. [r478] - Add the MoveFolder MAPI call (IDL + implementation + mapitest) - Fix some typo in mapitest doxygen [r477] - Add MoveFolder MAPI call (IDL + implementation + mapitest) - Fix some doxygen stuff - add a common function within mapitest which looks for a folder name within a container and return the opened folder object on success. [r476] Add auto-generated Doxyfile to the svn ignore list [r475] - Add AbortSubmit MAPI call (IDL + implementation + mapitest) [r473] - Uninitialize MAPI and general memory context at the end of mapitest bradh [r474] Clean up / flush the stream after use. Saves a bit more "still reachable" in valgrind too. 2008-04-30 jkerihuel [r470] - Rename CopyMessages to MoveCopyMessages - Improve IDL + implementation and mapitest added bradh [r471] Make sure the version shown for mapitest documentation is automatically set to match the package version. [r468] complete the rest of the API documentation autonumbering. jelmer [r472] Remove duplicate use of $(SHLIBEXT). [r469] Avoid parallel builds for now. 2008-04-29 jkerihuel [r467] Fix GetContentsTable binding in perl swig [r466] - Improve the GetHierarchyTable and GetContentsTable IDL and public IDL implementation (new parameters in,out) bradh [r465] Initial part of automatic list numbering for doxygen comments. This doesn't work correctly with the current apidocs.css, which turns the list numbers into bullet points for reasons I don't understand. 2008-04-28 jkerihuel [r464] - Improve the DeleteMessages IDL request [r463] - Update libmapi version from 0.7 to 0.8 - Public API change for the GetReceiveFolder function; now takes a message class as 3rd parameter. [r458] - Improve GetSearchCriteria request IDL (unknown removed) - update libmapi copyright headers 2007 -> 2007-2008. [r457] - Improve the SubmitMessage IDL - minor indentation fixed in IMessage.c [r456] - Add CopyToStream MAPI call (IDL + implementation + mapitest) [r455] - Add SeekStream MAPI call (IDL + implementation + mapitest) - Add SetStreamSize MAPI call (IDL + implementation + mapitest) [r454] - Add CommitStream MAPI call (IDL + implementation + mapitest) - Add GetStreamSize MAPI call (IDL + implementation + mapitest) - refactor the stream test to include all stream related operations - add a common function which generates a random ASCII blob of data bradh [r453] Add doxygen support for the mapitest examples. jelmer [r459] Allow cleaning individual parts. 2008-04-27 jkerihuel [r452] - Add GetStatus call (IDL + implementation + mapitest) [r451] - Fix format string problem in mapitest headers [r450] Run offline suites by default. [r449] - Introduce the online/offline mode for suite - Fix Exchange headers print bug when server is offline - reset errno to 0 before running new test bradh [r447] Install the libmapiadmin.h header. [r446] Fix a compile-time warning on amd64, for the second argument to the getline() call - incompatible pointer type. I'm assuming that size_t is equivalent to uint32_t on a 32-bit architecture, but not on a 64-bit arch. A quick test showed no difference in actual output. jelmer [r448] Remove bashisms in installsamba4.sh 2008-04-26 jkerihuel [r445] - Add ReadRecipients MAPI call (IDL + implementation + mapitest) - Improve some ModifyRecipients and Recipients structure naming 2008-04-25 jkerihuel [r444] - Add RemoveAllRecipients call (IDL + implementation + mapitest) [r443] - Add OpenPublicFolderByName call added (IDL and implementation). - Note: the reply IDL doesn't handle Server and ServerCount yet. - Note: this call only refers to NNTP folders (e.g: folders located within "Internet Newsgroups". If developers use this call within "All Public Folders", then the call with return MAPI_E_NOT_FOUND. - Call not added to mapitest cause it require RightsAuthor permissions on Internet Newsgroups which is not the case by default. - dump-data and debug options added to mapitest - FOLDER suite renamed to OXCFOLD (naming convention) [r441] Rename module folder to oxcfold [r440] Replace the existing mapitest tool with a new implementation. It is less complete but more modular. jelmer [r442] Add proto headers to ignore file. 2008-04-20 jkerihuel [r438] OpenFolder request: replace unknown field with OpenModeFlags [r437] - Rename 0xFE opnum from OpenMsgStore to Logon - Update the Logon request IDL bradh [r439] Add BEGIN_DECLS for private_proto.h. [r436] Add forgotten part of rev435. [r435] Add unit test framework for compressed RTF decoding. Refactor lzfu.c to improve testability. 2008-04-19 jkerihuel [r434] Fix openchangeclient --mailbox --pf with wasn't launched anymore due to some incorrect sanity check tests. [r433] - Remove deprecated fuzzer_msgstore torture test - replace mapi_flags with logon_id in EcDoRpc_MAPI_REQ 2008-04-16 bradh [r432] A couple of minor fixes to make it read better. jelmer [r431] properly clean up sofiles [r430] Import exchange nagios check script by Bill Edmunds. [r429] Add support for creating libocpf soname symlink. [r428] Use standard include for uint64_t definition. [r427] Cleanup talloc and tdb before building samba4. 2008-04-14 jkerihuel [r426] Check for ocpf_set_Recipients retval (MAPI_E_NOT_FOUND) [r425] - Reset ocpf to NULL after release so the ocpf_init/release couple can be called more than once. - Sanity check on recipient, avoid parsing if no recipient is set. Return MAPI_E_NOT_FOUND instead. [r424] Add reference to the ocpf lib within the pc file. 2008-04-09 jelmer [r423] Remove duplicate SWIG instructions (already covered by stdint.i). [r422] Ignore files created by swig. [r421] Use config.mk in swig/perl/Makefile. [r420] Allow sambaprefix and prefix to be different. Allow building with unknown Samba git revisions (will still warn though). [r419] Add --with-samba argument to configure so samba and openchange can be installed in different directories. 2008-04-08 jkerihuel [r418] Add domain to the mapiprofile dump output. [r417] Fix OpenMessage IDL and GetRecipientTable fetched data -This line, and those below, will be ignored-- _M trunk M trunk/exchange.idl M trunk/libmapi/IStoreFolder.c M trunk/libmapi/emsmdb.c M trunk/libmapi/IMessage.c 2008-04-07 jelmer [r416] Fix typo, change samba-config -> samba-hostconfig. 2008-04-06 jkerihuel [r415] - Add openchangepfadmin to make install - Add openchangemapidump and locale_codepage to make clean 2008-04-05 jelmer [r413] Merge the samba4-latest branch. 2008-04-03 jkerihuel [r408] Revert so version number to 0.7 [r407] Fix Perl bindings: update mapidump_message [r405] ** Start libmapi-0.8 ROMULUS development ** [r402] Add ChangeLog and apidocs to the releases [r400] - Delete unmaintained regression suite - Fix typo error in torture-clean rule [r399] Add modified release script originally from abartlett/samba4 [r398] - Check for specific Samba4 git revision in configure.ac - Prefix locale functions with lcid and make them _PUBLIC_ bradh [r406] API documentation update. jelmer [r403] Fix some typos. 2008-04-02 jkerihuel [r397] Add installation script for samba4 [r396] - Apply the nspi pointer patch - make openchange works with samba4-alpha3 git 41309dc - update howto.txt bradh [r390] Move the top level API documentation to an "overview" section and add a redirect to that overview. This keeps the doxygen output more nicely separated for packaging. Also, generate the man pages where the install expects to find them. 2008-04-01 jkerihuel [r388] - Fix strsep bug in openchangeclient - Add RECIPIENT support to libocpf [r383] - escape/unescape strings support added - PT_MV_STRING8 type added to OCPF write API 2008-03-31 jkerihuel [r382] - return MAPI_E_NOT_FOUND if NspiGetMatches doesn't return any results (based upon patch from lofi@mountproc.org) - makes the workstation parameter of mapiprofile optional (use gethostname if not defined by the user on command line) [r381] - Fix an allocation memory problem in cast_SPropValue - update svn:ignore proplist 2008-03-30 jkerihuel [r380] Update the documentation build so it keeps generating an embedded website in with apidocs/html as root directory. [r378] - Add support for PT_UNICODE and PT_SHORT to libocpf - Initial implementation of the libocpf write API - Update libocpf documentation - add --ocpf-dump option in openchangeclient - Fix realdistclean rules for server - add cast_SPropValue function to libmapi/property.c which cast mapi_SPropValue to SPropValue bradh [r379] Split API documentation into two separate sections - one for libmapi and one for libocpf. Also add in a top level intro page. 2008-03-27 jkerihuel [r376] New build system which gathers a list of things that can be built with the libraries/utilities the user has installed and build that when "make all" is run. 2008-03-26 jkerihuel [r375] Add missing allocation for OLEGUID [r373] --ocpf-syntax doesn't require MAPI to be initialized. Furthermore makes ocpf-syntax "exclusive" (quit after performing the operation). bradh [r372] r371 was bad. What was I thinking with that nonsense! Revert to something sane. [r371] Make the ./bin/ directory if it doesn't exist. This should resolve ticket #33. 2008-03-23 bradh [r370] Improve language handling when creating profiles. You can now get a list of valid languages and use either the language code ID or the language name to specify what language later versions of Exchange should reply with. [r369] Typo fix - duplicate ; at the end of the structure. [r368] Match format to unsigned int argument. [r367] Make the format specifier match the unsigned argument. 2008-03-22 jkerihuel [r366] propset svn:ignore update [r365] Update propset svn:ignore on doc/examples and libocpf targets [r364] - Fix ticket #29: http://trac.openchange.org/ticket/29 - use access(2) to see if the database already exists - test if the profile already exists prior trying to add it - add descriptive error messages - catch CTRL-C signal and run a profile deletion routine bradh [r363] Update API documentation for ocpf_nproperty_add(). [r362] Typo fix. 2008-03-16 jkerihuel [r361] Fix mapidump_message call parameters 2008-03-13 jkerihuel [r360] Add fid/mid parameters to mapidump_message and changed openchangeclient_fetchitems to reflect these changes. [r359] Patch from Brad Hards : updates the OCPF doxygen file. [r358] Patch from Brad Hards : adds the doc/examples into the build system and enables make examples. [r357] Patch From Brad Hards, : API documentation update and minor fix for the error value change. 2008-03-09 jelmer [r355] Update bzr ignores. 2008-03-06 jkerihuel [r354] - Add PT_BINARY property support to OCP - Add stream support to OCPF for large PT_BINARY blobs. - Fix a bug which prevented from having no/empty PROPERTY or NPROPERTY sections. 2008-03-05 jkerihuel [r353] - Prevent from assigning a value which type doesn't match with the property one. - Add missing substitution variable support for some named properties declaration - Improve sample_appointment.ocpf example - Add PT_MV_STRING8 keyword to the list of supported property type identifiers. 2008-03-04 jkerihuel [r352] Improve OCPF PT_MV_STRING8 support. [r351] - Initial revision for libocpf and its documentation - YACC support added to the build system - custom lid and string support in mapi_nameid - lookup functions added for OOM, lid and string - OCPF commands added to openchangeclient (ocpf-file, ocpf-syntax, ocpf-sender) - PR_FID displayed in openchangeclient --mailbox - PT_MV_STRING8 support added to cast_mapi_SPropValue 2008-03-02 jkerihuel [r350] Patch from Brad Hards : updates code to build with current API [r349] Patch from Brad Hards : little update for some API dox 2008-02-21 jkerihuel [r348] - Add --update option to openchangeclient and allow users to modify existing messages (calendar, task, contact, note) - Add --delete option to openchangeclient and allow users to delete existing messages (calendar, task, contact, note) - Add some folder/message unique ID to mapidump outputs and send* openchangeclient functions. - Fix a bug in set_SPropValue: add sanity check on unicode string. Thanks to Suman Manjunath for this patch. - Fix mapidump_task function and identifiers of named properties used. 2008-02-19 jkerihuel [r347] Fix missing sanity check on priority [r346] Fix a bug in openchangeclient when tasks are created without body [r345] private flag added to openchangeclient appointments [r344] Fix folder IDs problem for Exchange 2007 SP1 2008-02-09 jkerihuel [r343] Fix names IDL against Samba4 4.0.0alpha3-GIT-41309dc 2008-01-24 jkerihuel [r342] - Fix a bug in IStoreFolder.c:OpenMessage which was also affecting GetRecipientTable. We were extending SPropTagArray prior calling emsmdb_get_SRow. This was causing ndr_pull_error in OpenMessage_repl and erroneous data to be inserted in the SRow. - Fix libmapi/socket/interface.c: - Use the latest version from Samba4 which removes reference to global_loadparm. - Moves struct interface declaration to netif.h - Report changes to emsmdb.c notification functions. - Change GetGALTable prototype to match general libmapi policy. Remove the usage of bool and replace it with uint8_t. Possible values added to mapidefs.h 2008-01-22 jkerihuel [r341] - Improve NspiQueryRows IDL and implementation - Add GetGALTable implementation: fetch all the Global Address List recipients - Add --userlist option to openchangeclient - Add a convenient and basic dumping function for Global Address List recipients. [r340] - Improve OpenMessage reply IDL - Fetch mapi recipients from OpenMessage reply - Add GetRecipientTable convenient function - Add OPENCHANGE-MAPI-RECIPIENT torture test to test GetRecipientTable implementation. - Add convenient SPropTagArray_add function - Add internal emsmdb_get_SRow routine 2008-01-21 jkerihuel [r339] Patch from Suman Manjunath : - Adds named-properties which define recurrence patterns for appointment and task. - Adds named properties for appointment timezone [r338] - Fix the SNotRestriction IDL and write custom push,pull,print functions - Add 2 new MAPI calls to the IDL: * GetSearchCriteria, * SetSearchCriteria - add sample {Get,Set}SearchCriteria torture test - add convenient mapi_id_array implementation - add GetDefaultFolder support for CommonView and Finder folders 2008-01-20 jelmer [r337] Make sure directory exists. 2008-01-18 jkerihuel [r336] - Fix tiny 'nail down samba4 version' bug - update the minimal Samba4 required version [r335] - Add FindRow call to the IDL - Improve mapi_Restriction support - Remove deprecated ndr_print_QueryRows function - Add a print function for fuzzyLevel - Add preliminary FindRow implementation test to MAPI-RESTRICTIONS torture test - Add couple of new MAPI tags to mapi-properties - change initial bookmark index to 3 2008-01-16 jkerihuel [r334] - Add 2 new MAPI calls to the IDL and mapitest: * SetReceiveFolder * GetReceiveFolderTable - Fix a bug in the SortTable test when no messages are returned by QueryRows [r333] - Add SeekRowApprox to the IDL and mapitest - Fix some doxygen typo [r332] - New calls added to the IDL, torture suite and mapitest: * CreateBookmark * SeekRowBookmark - Internal mapi_object_bookmark_t implementation added to mapi_object_table_t - SBinary_short default ndr_print function changed to custom 2008-01-14 jkerihuel [r331] Temporary fixes unexpected segfault in SortTable test. Emails sent during the Submit test have sometimes not yet been dispatched when the SortTable test begins. This fix adds a sleep(1) and an arbitrary number of attempts (5). [r330] Add 2 new MAPI calls to the IDL and libmapi: * AddressTypes * SortTable Tests for SortTable added to mapitest and the torture suite Test for AddressTypes added to mapitest. 2008-01-13 jkerihuel [r329] Fix perl bindings and fetchmail test [r328] 2 new MAPI call added to the IDL and mapitest: * GetMessageStatus * SetMessageStatus 2008-01-11 jkerihuel [r327] - Add DeleteAttach MAPI call - Add new mapi unit tests: * QueryColumns * CreateAttach * SaveChanges * GetAttachmentTable * DeleteAttach - Update mapitest README - Add some convenient functions to mapitest_common.c 2008-01-10 jkerihuel [r326] Add a preliminary draft of the mapitest standalone MAPI test suite. 2008-01-05 jkerihuel [r324] Add missing files [r323] - Fix the build with the latest Samba4 version. - Add a basic libmapi/version.h auto-generated file (based on Samba4 one) - Remove some warnings when compiling the utf8 lexer - Add a emsmdb_info structure to fetch some information from the Exchange server WARNING: Please note that EMSABP is definitely broken and requires a review and update. jelmer [r325] DESTDIR should never get into any source files, that would defeat its purpose. 2008-01-04 jkerihuel [r322] Fix the torture suite. 2007-12-28 jelmer [r321] provide extra required argument. [r320] Store a loadparm context in the global mapi context. [r319] Deal with samba version.h's that don't contain the Subversion revision. 2007-12-15 jelmer [r318] Use SWIG-provided typemaps for stdint. 2007-11-29 ali [r317] Fix Content-Type field in exchange2mbox Reported by Yuriy Filatov 2007-11-28 jkerihuel [r316] - Improve the CreateMessage IDL - Add new parameters to IMAPIFolder CreateMessage libmapi function - Add --mkdir --rmdir options to openchangeclient - Update the CreateFolder API and openchangeclient documentation - Fix CreateFolder calls in openchange tools and torture suite - Fix gendb_search warning 2007-11-25 jkerihuel [r315] Add new PSETID_Address named properties [r314] Fix a few code convention typos Patch from Suman Manjunath applied: converts a 'struct timeval' to 'NTTIME'. minor extension of 'set_SPropValue_proptag', used while setting PT_SYSTIME properties. 2007-11-21 jkerihuel [r313] update Samba4 first revision to 26100 jelmer [r312] Cope with ndr updates. 2007-11-12 jkerihuel [r311] Patch from Brad Hards: Fix possible Heap overflow in lzfu code 2007-11-07 jkerihuel [r310] Fix profile creation in a clustered Exchange 2007 environment. 2007-11-02 jkerihuel [r309] Fix QueryColumns req size. 2007-11-01 jkerihuel [r308] ** Start libmapi-0.7 PHASER development ** add --dump-data option to mapiprofile for debugging purpose 2007-10-31 jkerihuel [r306] openchangepfadmin (1) man page added [r305] Store messageID in the object when SaveChangesMessage is called [r304] Nail down Samba4 version for libmapi-0.6 2007-10-30 jkerihuel [r303] - Add PR_MSG_EDITOR_FORMAT property to the sendmail operation - Fix body dump bug when PR_MSG_EDITOR_FORMAT property is missing (default set to PLAINTEXT) - Continue to process the mailbox when a problem is encountered with mesage contents (not attachment) - Fix a typo bug in openchangeclient body help string [r302] Update doxygen section 2007-10-29 jkerihuel [r301] - Add doxygen man (3) pages to installman and uninstallman rules - do not run doxygen if apidocs already exists 2007-10-28 jkerihuel [r300] Move documentation to doxygen 2007-10-25 jkerihuel [r299] Add convenient date related functions for implementors: returns a timeval struct matching a PT_SYSTIME property for improved date manipulation in 3rd party softwares 2007-10-24 jkerihuel [r298] Fix build to work with latest Samba4 revision (4.0.0alpha2-SVN-build-25722) [r297] Fix make realdistclean when swig perl is enabled [r296] Fix swig perl bindins compilation: move *.o to *.po [r295] use talloc_memdup to copy const data in the body DATA_BLOB Should only provide valid pointer to talloc_free 2007-10-23 jkerihuel [r294] Fix the DeleteMessages [out] IDL. The remaining bytes were not part of DeleteMessages but MAPI notification (0x2a) 2007-10-22 jkerihuel [r293] - Add RTF support in exchange2mbox - Use openchange-tools public functions - Replace GetPropsAll calls with GetProps [r292] - fetchmail: * Use GetProps rather than GetPropsAll for message dump * Rely on PR_MSG_EDITOR_FORMAT to select the type of body * Open a stream for PR_BODY and PR_HTML if the size exceeds max property size -This line, and those below, will be ignored-- M trunk/Makefile.in A trunk/utils/openchange-tools.c M trunk/utils/openchangeclient.c M trunk/utils/openchange-tools.h M trunk/utils/openchangeclient.h M trunk/libmapi/mapidefs.h 2007-10-20 jelmer [r291] Fix ignores. 2007-10-19 ali [r290] Remove useless svn:ignore jkerihuel [r289] Add WrapCompressedRTFStream function for PR_RTF_COMPRESSED content. Original lzfu decompress routine fetched from libpst-0.5.2 [r288] make enum MAPISTATUS variables naming uniform in libmapi 2007-10-16 jkerihuel [r287] Add PT_CLSID case to get_SPropValue_data [r286] Add/Fix pull property support for PT_UNICODE and PT_CLSID (used by GetProps) [r285] Patch from Brad Hards : Fix compilation for x86_64 platforms. 2007-10-14 ali [r284] More svn:ignore updates [r283] Update of svn:ignore 2007-10-10 jkerihuel [r282] added the IDL license [r281] Convert OpenChange to GPLv3 [r280] - Add .po files to make clean - Fix a couple of warnings in the utf8 conversion lexer - Prefer long filenames to truncated one for attachments in openchangeclient 2007-10-09 jkerihuel [r279] Prevent exchange2mbox from segfault when PR_MESSAGE_DELIVERY_DATE is unset [r278] Add PT_CLSID and PT_MV_CLSID support to the IDL [r274] - Add new named properties - Convenient function for MNID_STRING props lookup added jelmer [r277] Make .po a recognized suffix. [r276] Fix compile error. [r275] Use -fPIC for library objects. 2007-10-08 jkerihuel [r273] - Rename GetAllNamesFromIDs to QueryNamesFromIDs (better naming) - fix SPropValue_CTR boolean to uint8_t in the IDL and emsmdb.c - add mapi_nameid convenient interface and headers - mapi-named-properties populated, parser added to mparse.pl, file added to the build system - remove any incorrect reference to named properties in openchange tree - remove deprecated libmapi/mapi.h file - remove unused ulFlag parameter from IProfAdmin functions - remove unused memory context from libmapi/x500.c - support sendnote operation in openchangeclient - optimize check/list oc_element functions in openchangeclient - update swig interface 2007-10-05 jkerihuel [r272] - New MAPI calls: Named properties support * GetNamesFromIDs * GetIDsFromNames * GetAllNamesFromIDs - Modified MAPI calls: * OpenMessage * SaveChanges These calls now have more granularity in libmapi with flags support - sample mapi-named-properties file introduced in libmapi/conf - Torture test suite: * suite temporary fixed (import torture_rpc_* functions from Samba4) * torture_namedprops test added - SWIG Perl bindings fixed according to changes described above - minor improvements in libmapi/mapidump.c 2007-10-02 jkerihuel [r271] - Decrease MAX_READ_SIZE to 0x1000 - Clean-up Read/WritreStream related code - add dump-data option to openchangepfadmin (debugging purpose) 2007-10-01 jkerihuel [r270] Fix build: - remove reference to core/nterr.h - add global_loadparm reference where missing - add reference to core/error.h where needed jelmer [r269] Improve output during build. [r268] Fix lp_load(). [r267] Pass loadparm contexts, should fix the build with newer Samba revisions. 2007-09-28 jkerihuel [r266] - WriteStream API changed: now returns the number of bytes written - WriteStream man page updated - 16 bytes extra-data bug fixed when sending attachments in openchangeclient - Set open mode to 0600 when attachments are stored on the filesystem 2007-09-19 jkerihuel [r265] Fix preliminary Perl bindings so it works with Samba4 alpha2 and latest libmapi revision. [r264] Patch from Andrew Gaylard : - When calling openchangeclient with the --dump-data switch, it will dump core, since the global_mapi_ctx pointer isn't initialised yet. The fix is to wait until it's set before accessing it. [r263] Patch from Andrew Gaylard : - Leaving any blank lines before .TH directives appears to cause a blank page to be output when converting man pages to DVI files (which is a step to converting them to PDF). The following patch remove the blank line above the .TH in each man page file. - mapiprofile doesn't understand the -A switch, as mentioned in it's man page. It should be -I. 2007-09-13 jkerihuel [r262] - Add objectClass to the object: container, message or attachment - Rename content to message in openchangebackup functions - add objectClass parameter to ocb_record_init 2007-09-12 jkerihuel [r261] - Move debug options to their correct location (after MAPIInitialize) - Improve code related to LDB transactions - Add convenient error checking macros 2007-09-11 jkerihuel [r260] - Add preliminary openchangemapidump draft - Fix lp_parm_* 1st parameter in the torture suite - New functions in property.c for MAPI data retrieval 2007-09-09 jelmer [r259] Use configure definition for mandir. 2007-09-08 dan [r258] Activate debugs this time [r257] Replaced remaining gotos with MAPI_RETVAL_IF so errno is set correctly [r256] MAPI_RETVAL_IF missing ";" could cause surprises ;-) [r255] Add error check for samr call. set errno with MAPI_RETVAL_IF. 2007-09-06 dan [r254] Make required packaged more clear (LinuxMagazin input) 2007-09-05 jelmer [r253] Remove invalid comment. 2007-09-04 jkerihuel [r252] - Clean-up function prototypes - Dump email when NEWMAIL notification is received 2007-08-31 jelmer [r251] Proper dependencies. [r250] Don't regenerate proto headers unless necessary. [r249] Add 'make check'. [r248] Use install for installing files/directories. [r247] Actually use replacement variable for libmagic. 2007-08-30 jkerihuel [r246] Remove forgotten BOOL [r245] Remove mapi_session pointer in mapi_objects Add public function to IProfAdmin: retrieve default ldif path location outside the OC tree 2007-08-28 jkerihuel [r244] Prevent users from creation of *undeletable* folders in Outlook and perform sanity check on dirclass + display possible values. [r243] Provides a way to modify Default and Anonymous permissions for a given folder. [r242] Fix errno in getdir function + add sanity check on opt_rmdir [r241] - Fix a memory related bug in mapiadmin_add_user - Add latest howto.txt modifications from Dan [r240] - Fix bug in *UserPermission function: return when user is not found - Add sanity checks to mapi_object API functions - mapi_object_release reset errno to 0: need to release object after displaying the potential error message. [r239] Fix a mapidump_appointment bug Add PF folder support to fetch-items operation 2007-08-27 jkerihuel [r238] openchangeclient now support send/read/delete operation on custom PF directories. [r233] - Add libmapiadmin library draft: Add/Remove Exchange user - openchangepfadmin tool added: Public Folders management - Add Sanity check to CreateFolder jelmer [r237] Update ignore list. [r236] Fix last references to BOOL, True and False. [r235] Fix more references to BOOL, False and True. [r234] Use standard type and values for booleans since Samba no longer exports BOOL, True and False. 2007-08-21 jkerihuel [r232] - Add OpenPublicFolder function to libmapi, Open Public Folder store - change torture suite API to match latest Samba4 pidl changes - utf8_convert regexp improved - minor changes: printf to DEBUG - howto.txt patch from Dan included - Samba4 torture code related to user account creation included in the torture suite. 2007-08-06 jkerihuel [r231] Fix segmentation fault when running update prior populating the database. 2007-07-31 jkerihuel [r230] Remove obsolete file from the torture suite [r229] - Add Exchange Administration test to the torture suite: Create Exchange user [r228] Dan update on howto.txt 2007-07-10 jkerihuel [r227] - Add Exchange ACLs support to MAPI library - Add 2 new MAPI opnum: GetTable and ModifyTable - Improve mapidump functions 2007-07-04 jkerihuel [r226] - Improve aclocal check in autogen.sh - Fix flex binary detection in configure.ac 2007-06-22 jkerihuel [r225] Same player ... [r224] Fix libmapi symlink [r223] Create libmapi.so symlink 2007-06-21 jkerihuel [r222] Fix mandir installation path Add ldconfig intructions to openchange installation documentation [r221] Fix build. 2007-06-20 jkerihuel [r220] RES_AND and RES_OR preliminary implementation. 2007-06-19 jkerihuel [r218] - doc patch from Brad Hards - rename PROFILE_NOPASSWORD to OC_PROFILE_NOPASSWORD - fix a warning in property.c 2007-06-16 jelmer [r210] Add some 'const' (fixes compile warnings). [r209] Use sonames (required for the Debian packages). [r208] Add .bzrignore file. [r207] Update version number and use globally defined version number in libmapi.pc. 2007-06-15 jkerihuel [r205] - Add IDL implementation for restrictions Content, Property, CompareProps, Bitmask, Size, Exist. - Add Restrict MAPI call handling the restrictions above - OPENCHANGE-MAPI-RESTRICTIONS torture test added to the suite. - convenient sendmail function added to mapi_common.c - get property size function for mapi_SPropValue added to property.c test --This line, and those below, will be ignored-- M Makefile.in M exchange.idl M torture/openchange.c A torture/mapi_restrictions.c M torture/mapi_common.c M libmapi/property.c M libmapi/IMAPITable.c 2007-06-11 jkerihuel [r204] Documentation update: Perl bindings installation 2007-06-10 jkerihuel [r203] - Add mapitags and mapicode support to Perl SWIG bindings - SPropTagArray support - SRowSet preliminary support - new constructor/destructor for mapi objects 2007-06-09 jkerihuel [r202] - IProfAdmin patch applied: having password outside of the profile - Perl bindings draft added to the trunk and to the build system: --enable-swig-perl=yes - datarootdir fixed in libmapi.pc.in 2007-06-06 jkerihuel [r201] - Add CopyMessages IDL and COPYMAIL torture implementation - Fix man page install dir according to latest Samba4 changes - Add datarootdir var to libmapi.pc.in and fix configure warning 2007-06-01 jkerihuel [r199] convenient function which retrieve a value from a SPropValue array given its property tag name, otherwise NULL 2007-05-31 jkerihuel [r198] Patch from Brad Hards : openchangeclient man page updated [r197] - Add Windows UTF8 to classic UTF8 conversion through a lexer - openchangeclient --mailbox option changed to use it - flex and bison support added to configure.ac - windows_to_utf8 function added: wrapper over yyparse_utf8 routine 2007-05-29 jkerihuel [r196] - features added to openchangeclient: * --send-appointment * --send-contact * --send-task * custom parameters - openchangeclient man page updated - new properties added to mapi-properties [r195] - Add man pages for simple_mapi.c functions: * GetDefaultFolder * GetFolderItemsCount [r194] - Remove deprecated functions from IMsgStore.c - Update man pages documentation [r193] Fix install rule in Makefile: add missing headers Move callback retval from uint32_t to int [r192] Fix notification callback retval [r191] - Advise opnum added to the IDL - Parts of the Notify response IDL implementation - Add Notification support to libmapi - Add --notifications option to openchangeclient 2007-05-28 jkerihuel [r190] Patch from Brad Hards : - PR_BUSINESS_FAX_NUMBER - improves the information provided on a contact by mapidump_contact() 2007-05-25 jkerihuel [r189] - Fix the release call in,out - Call Release from mapi_release_object - Add sanity check to OpenMsgStore - clean up parts of the mapi_newmail test [r188] EcDoDisconnect code now sounds to work properly Tested against Exchange 2000 / Exchange 2003 [r187] - Fix SpropValue property pull problem when GetProps layout is set - Add a dumpdata boolean to mapi_ctx_t so tools can dump hex data - Add PR_CONTAINER_CLASS fetch to openchangeclient --mailbox - Add debuglevel and dumpdata options support to openchangeclient 2007-05-24 jkerihuel [r186] - Remove useless memory allocation in mapidump.c - Improve mapidump_appointment - Add sample mapidump_note - Add --fetchitems option to openchangeclient: This command offers an easy way to fetch calendar, contacts, tasks, notes and mails from the Exchange server. - Add IPF container class defines to mapidefs.h - Add and Fix property tags 2007-05-22 jkerihuel [r185] - Commit the EcDoRpc max_data patch proposed on the devel list - Clean up folders related functions from the torture suite (GetDefaultFolder makes this code obsolete) 2007-05-21 jkerihuel [r184] Add the --mailbox option to openchangeclient which recursively lists the full mailbox folder hierarchy [r183] - Add PT_SYSTTIME support to get_SPropValue_data - Add mapidump_SPropValue_date dumping function - Add PT_SYSTIME support to mapidump_SPropValue [r182] - Add multi-valued SBinary_short support to mapi_SPropValue_CTR in the IDL - Add GetDefaultFolder implementation to simple_mapi.c. This function provides a convenient way to retrieve default folders ID. const olFolder values are stored in libmapi/mapidefs.h - Modify the torture test suite to reflect these changes. - OpenMsgStore now decodes all the fid returned in the response - fix a bug size in libmapi/property.c 2007-05-18 jkerihuel [r181] - Fix SMTP recipient in libmapi - Add SMTP recipient support to openchangeclient and the torture test suite - Fix a bug in SRow_addprop 2007-05-17 jkerihuel [r180] - OpenMessage IDL changed: we have a permission field. It is now set by default to 0x3 (read/write) until we change OpenMessage prototype. - Add a sanity check to MAPIInitialize when no profdb is specified 2007-05-15 jkerihuel [r179] Remove remaining MAPISTATUS and replace them with enum MAPISTATUS [r178] - SetReadFlags IDL and implementation added to libmapi - Warning fixed in emsabp.h [r177] Fix a bug in openchangeclient when attachments are using PR_ATTACH_LONG_FILENAME rather than PR_ATTACH_FILENAME to store attachment filename. [r176] Patch supplied by Brad Hards which renames private structure member to private_data for C++ compatibility. [r175] Add libmapi/simple_mapi.c designed to hold convenient functions for application development. - GetFolderItemsCount added which returns the number of total and unread messages for a given folder. 2007-05-14 jkerihuel [r174] - Fix a body openchangeclient bug which now prevent openchangeclient from segfault when no body is specified. - Add GetDefaultProfile call to exchange2mbox for the default operation. - Improve fuzzer_msgtore output 2007-05-13 jkerihuel [r173] Add a fuzzer torture test on OpenMsgStore which test all the possible max_data value. Should help to understand if libmapi fails because of max_data or not. 2007-05-12 jkerihuel [r171] exchange2mbox improved: - tdb dependency removed - message-id are now stored in the profile database - it now mirrors deletion operation from the mbox file back to the Exchange server. - man page updated to reflect these changes [r170] - GetProfileAttr function prototype modified. It now returns the results count for the given attribute and store values in a string array. - GetProfileAttr man page updated to reflect these changes - Fix mapiprofile attribute search command - migrate from open/write calls to stream ones in exchange2mbox texane [r172] newmail torture + notifications implementation -- texane 2007-05-11 jkerihuel [r169] Fix the SambaXP live demo segfault: When an ambiguous recipient is specified, it now skips the name properly and maintain a correct SRowSet. [r168] - Fix a bug when storing attachments into mbox - Add default path support to exchange2mbox 2007-05-10 jkerihuel [r167] - Update libmapi version according to the roadmap - Fix nspi_resolvenames to use default profile database and profile 2007-05-09 jkerihuel [r166] - Add default profile database and profile support in the torture suite. - Fix a bug in mapidump_task 2007-05-08 jkerihuel [r165] - Change MAPILogonEx to MAPILogonProvider and avoid potential emsmdb endpoint related problem - add sanity check on global session pointer 2007-05-06 ali [r164] Merged MAILOOK-branch changes r64:163 into the trunk. 2007-03-04 jkerihuel [r79] Remove ChangeLog, use svn log instead ;p 2007-02-13 jkerihuel [r63] - libmapi includes moved from libmapi/include to libmapi - Remove arguments from prototype definitions generation in mkproto.pl - __BEGIN_DECLS __END_DECLS support in header files - united libmapi/libmapi.h header file - openchange.h header removed - PIDL generated files moved to gen_ndr - compilation rule for libmapi header installation added - useless torture tests removed jkerihuel. 2007-02-12 jkerihuel [r62] Replace OpenProperty and ReadAttach calls with OpenStream and ReadStream call Add GetAttachmentTable call jkerihuel. 2007-02-09 jkerihuel [r58] Remove -Werror CFLAGS until I figure out how to fix our problem definitively. Remove static from dcesrv_exchange.c functions definition jkerihuel. texane [r61] . reimplement GetProps . retrieve attachment size . modify fetchmail and fetchattach torture -- texane [r60] . add GetPropList to exchange.idl . add GetPropList implementation to IMAPIProp.c -- texane [r59] - Add fetchattach torture; Attachment size is not yet defined and 42 is used. - add 3 new EcDoRpc opnums: - OpenAttach - ReadAttach - OpenProperty -- texane 2007-02-08 jkerihuel [r57] Forgot to add IMAPISession.c jkerihuel. 2007-02-07 jkerihuel [r56] Remove spurious warnings at compile time and add -Werror -Wstrict-prototypes to CC. jkerihuel. [r55] Dispatch libmapi functions into filenames matching the MAPI interface they belong to. jkerihuel. [r54] Fix the attach issue by value and add torture test to the openchange torture suite. jkerihuel. texane [r53] attachment torture test implementation -- texane 2007-02-06 jkerihuel [r52] Add a null element at the end of MAPI_REQ array so we can exit from the loop in ndr_print_mapi_request jkerihuel. [r49] - Add the DeleteMessages IDL - New torture tests added: * OPENCHANGE-MAPI-SENDMAIL * OPENCHANGE-MAPI-DELETEMAIL These are experimental implementation jkerihuel. texane [r51] subject option for delete message torture test -- texane [r50] added (recipients == null) check added default body added default subject -- texane 2007-02-03 jkerihuel [r48] Add NspiResolveNames and the associated torture test. jkerihuel. 2007-02-01 jkerihuel [r47] Fix nspi decoding problem due to the usage of a hyper instead of a dlong. jkerihuel. [r46] - Add a preliminary NspiUpdateStat IDL - Fix the new server code convention naming (function prefixed with dcesrv_) - Fix a security bug in emsabp provider code jkerihuel. [r45] Fix the allocation memory for the EcDoRpc_{MAPI_REQ,MAPI_REPL} pointer. jkerihuel. [r44] Add SetProps [out] support. Temporary allocation pb fixed in ndr_pull_mapi_response. Final fix in next commit. jkerihuel. 2007-01-31 jkerihuel [r43] Fix the SetProps [in] IDL New mapi call support added: - ModifyRecipients [in,out] - SubmitMessage [in,out] jkerihuel. [r42] Add IDL support for the following mapi calls: [in] CreateMessage [in] SetProps The SetProps IDL is still experimental and the content blob should be decoded more than the current IDL does. jkerihuel. 2007-01-30 jkerihuel [r41] Fix the align problem in QueryRows reply blob Add some printing output and clean useless DEBUG. jkerihuel. 2007-01-29 jkerihuel [r40] Fix the OpenMessage IDL and add ndr_print support to the MAPI-FETCHMAIL torture test so we can read information. jkerihuel. [r39] Commit of the first experimental but working implementation of the MAPI-FETCHMAIL torture test able to retrieve mails from an Exchange Server. jkerihuel. [r38] - Add a preview implementation of cached data system for multi MAPI calls requests - Add SetColumns and QueryRows calls to mapi.c + mapi_fetchmail torture test - Enhance some MAPI calls IDL - Fix some pull/print functions according to error_code and row_count values jkerihuel. 2007-01-28 jkerihuel [r37] Manual handling of EcDoRpc_MAPI_REPL pull and print function. When a mapi call returns an error_code different from MAPI_E_SUCCESS, we have to stop processing the function IDL since no parameters follow. jkerihuel. [r36] add MAPISTATUS to EcDoRpc_MAPI_REPL add mapi library code for: - OpenFolder - Release - GetContentsTable - GetReceiveFolder add mapi calls described above to MAPI-FETCHMAIL torture test jkerihuel. [r35] add mapi_response to emsmdb_transaction so we can get the results check the mapi call error core in OpenMsgStore jkerihuel. [r34] Add MAPISTATUS field in each mapi calls Add new MAPICODE (MAPI_E_CALL_FAILED) jkerihuel. [r33] Fix the mapi_request push function Add a first approach to the MAPI client side library Add a first approach of the MAPI-FETCHMAIL torture test Fix the smb.conf.example with new fields and remove Samba4 unused ones jkerihuel. 2007-01-27 jkerihuel [r32] Initial mapidump commit OpenMessage IDL fixed jkerihuel. 2007-01-24 jkerihuel [r31] Unused and dummy code removed jkerihuel [r30] - Remove the MAPI decoding TDR layer and associated functions - Add MAPI decoding in exchange.idl at NDR layer - mapi_request / mapi_response pull/print ok - implement subcontext for async response decoding in some EcDoRpc IDLs. - new MAPITAGS added related to Message envelope properties - clean up the code and remove unused files - Add new MAPI opnums and associated IDL: * [in] Release (opnum=0x1) * [in,out] OpenFolder (opnum=0x2) * [in,out] OpenMessage (opnum=0x3) * [in,out] GetContentsTable (opnum=0x5) * [in,out] GetProps (opnum=0x7) * [in,out] Secolumns (opnum=0x12) * [in,out] QueryRows (opnum=0x15) * [in,out] GetReceiveFolder (opnum=0x27) * [in,out] OpenMsgStore (opnum=0xFE) ** WARNING ** 1. Assumption ============== For IDL with unknown fields followed the IDL may change and the mapping of these unknown bytes incorrect. It's just based on assumptions and results of the different wireshark captures. 2. Broken Code ============== - The mapi_request / mapi_response pull function - emsmdb torture tests and libmapi/emsmdb.c All this code is currently broken and will be fixed when we start writing the new emsmdb torture suite using the new API. jkerihuel 2007-01-22 jkerihuel [r29] Fix ndr_pull_MAPI_DATA function jkerihuel. [r28] - Add new mapi opnums - Add a first IDL implementation for OpenMsgStore out jkerihuel. [r27] - Enhance the handles id support in MAPI_DATA - Remove unused code EMSMDB encoding/decoding is currently broken. It will be fixed when we start the client side mapi library implementation. jkerihuel. 2007-01-21 jkerihuel [r26] - Change IMAPISession.idl to mapi.idl - enhance mapi content payload decoding (multiple calls supported) - add sub EcDoRpc opnums and IDL for setcolumns (in) jkerihuel pkhun [r25] - memory leak fixed - new function on emsabp provider for entry id generation pkhun 2006-12-27 jkerihuel [r24] Old mapitables code deleted and merge of the samdb code used in openchange (emsabp_result_guid function). The following revision compiles and work fine with Samba4 revision 20341 jkerihuel. 2006-12-17 pkhun [r23] Instance keys management changed (we now use struct instance_key and uint32_t instead of an array of 4 uint8_t) pkhun 2006-12-15 jkerihuel [r22] - Fix compilation warnings based on patches provided by Stefan Huehner - Fix the DSO issue for x64 platforms - Add the evolution plugin in the compilation process - remove the mapidump code (obsolete and replaced with ndrdump usage) jkerihuel. 2006-12-13 jkerihuel [r21] evolution plugin moved into client/evolution for a correct and extensible naming convention. EcDoRpc IDL modified: - opnum are now 8 bits - action enum added - EcDoRpc ndrdump output enhanced IMAPISession IDL modified: - Change OpenMsgStore function name to MAPI_RPC_LOGON for the 0xFE opnum operation. Fix warnings in the code. jkerihuel. 2006-12-09 loic [r20] Openchange-Evolution plugin commit I reorganized openchange evolution plugin source tree. Now we have one directory for the camel-openchange provider, and one for the openchange eplugin. Everything can be found in the oc-evolution directory. This is code a minimalist implementation of the camel provider for evolution. It will make appears an openchange server type in the server list handled by evolution. Still have to fix the ./configure to create a Makefile though. 2006-12-05 jkerihuel [r19] Fix the memory allocation problems in the emsmdb torture test 2006-12-03 jkerihuel [r17] Removed ascstr and directly add it to the IDL [r16] Fix the NspiQueryRows response where strings containing the user email address have to be NULL terminated. The EMSABP provider is working ;-) pkhun [r18] The emsabp provider is now able to return multiple users when searching for part of a username. pkhun 2006-11-30 jkerihuel [r15] Fix the networkAddress binding strings for the Exchange object in the configuration db. The SERVER variable based on exchange:server had been added while we needed the NETBIOSNAME one Fix a segmentation fault in emsabp.c due to an unchecked pointer res->msgs. This was causing smbd to segfault when the supplied legacyExchangeDN sent by the user wasn't present in the database. jkerihuel 2006-11-27 jkerihuel [r14] Remove unused files and directory. Update Makefile.in and remove storedb compilation rules. pkhun [r13] Fixed : - NspiQueryRows - NspiDNToEph - NspiGetProps - provisioning (for the legacyExchangeDN of the server entry) 2006-11-26 jkerihuel [r11] Fix the build and remove dynconfig samba lib dependency. jkerihuel pkhun [r12] Unused ldif files removed + Schemas definitions updated pkhun [r10] Provisionning fixed (old ldif files cleaned) pkhun 2006-11-22 jkerihuel [r9] add tags rules to the Makefile jkerihuel. [r8] add the \\pipe\\protected_storage named pipe to exchange_nsp bindings jkerihuel. 2006-11-21 jkerihuel [r7] Add a dcerpc_server module in charge of the exchange interfaces registration. When this module is loaded prior the remote endpoint, it let us proxify the exchange_nsp and exchange_emsmdb ones. Change the exchange_nsp ncacn_np binding string to reflect how Exchange server is currently using it. Conform the IDL with latest pidl requirements and move the MAPI_DATA structure from exchange_nsp to exchange_emsmdb. jkerihuel 2006-11-14 jkerihuel [r6] Create the $prefix/modules/{dcerpc_server,torture} directories. This fix openchange make install rule. jkerihuel. [r5] This commit conforms openchange with the Samba4 trunk and fix the autotools checks. I've modified the openchange torture file to match the current smbtorture API and the OPENCHANGE-NSPI-PROFILE test was successful. The NSPI ndrdump suite has fully been tested and works correctly. jkerihuel. 2006-11-05 jkerihuel [r3] This commit fix the build system: - add the -ldynconfig dependency to LDFLAGS - add header checks in configure.ac. We need them for the moment cause Samba4 doesn't install some headers required by openchange core - fix the make install - remove autotools generated files and definitively ignore them with the .svnignore file - keepref keyword removed from exchange_nsp interface jkerihuel. pkhun [r4] + aclocal.m4 removed from repository + provisionning fixed pkhun. openchange-2.0/Doxyfile.in000066400000000000000000001466141223057412600156130ustar00rootroot00000000000000# Doxyfile 1.5.2 # This file describes the settings to be used by the documentation system # doxygen (www.doxygen.org) for a project # # All text after a hash (#) is considered a comment and will be ignored # The format is: # TAG = value [value, ...] # For lists items can also be appended using: # TAG += value [value, ...] # Values that contain spaces should be placed between quotes (" ") #--------------------------------------------------------------------------- # Project related configuration options #--------------------------------------------------------------------------- # This tag specifies the encoding used for all characters in the config file that # follow. The default is UTF-8 which is also the encoding used for all text before # the first occurrence of this tag. Doxygen uses libiconv (or the iconv built into # libc) for the transcoding. See http://www.gnu.org/software/libiconv for the list of # possible encodings. DOXYFILE_ENCODING = UTF-8 # The PROJECT_NAME tag is a single word (or a sequence of words surrounded # by quotes) that should identify the project. PROJECT_NAME = OpenChange # The PROJECT_NUMBER tag can be used to enter a project or revision number. # This could be handy for archiving the generated documentation or # if some version control system is used. PROJECT_NUMBER = @PACKAGE_VERSION@ # The OUTPUT_DIRECTORY tag is used to specify the (relative or absolute) # base path where the generated documentation will be put. # If a relative path is entered, it will be relative to the location # where doxygen was started. If left blank the current directory will be used. OUTPUT_DIRECTORY = apidocs # If the CREATE_SUBDIRS tag is set to YES, then doxygen will create # 4096 sub-directories (in 2 levels) under the output directory of each output # format and will distribute the generated files over these directories. # Enabling this option can be useful when feeding doxygen a huge amount of # source files, where putting all generated files in the same directory would # otherwise cause performance problems for the file system. CREATE_SUBDIRS = NO # The OUTPUT_LANGUAGE tag is used to specify the language in which all # documentation generated by doxygen is written. Doxygen will use this # information to generate all constant output in the proper language. # The default language is English, other supported languages are: # Afrikaans, Arabic, Brazilian, Catalan, Chinese, Chinese-Traditional, # Croatian, Czech, Danish, Dutch, Finnish, French, German, Greek, Hungarian, # Italian, Japanese, Japanese-en (Japanese with English messages), Korean, # Korean-en, Lithuanian, Norwegian, Polish, Portuguese, Romanian, Russian, # Serbian, Slovak, Slovene, Spanish, Swedish, and Ukrainian. OUTPUT_LANGUAGE = English # If the BRIEF_MEMBER_DESC tag is set to YES (the default) Doxygen will # include brief member descriptions after the members that are listed in # the file and class documentation (similar to JavaDoc). # Set to NO to disable this. BRIEF_MEMBER_DESC = YES # If the REPEAT_BRIEF tag is set to YES (the default) Doxygen will prepend # the brief description of a member or function before the detailed description. # Note: if both HIDE_UNDOC_MEMBERS and BRIEF_MEMBER_DESC are set to NO, the # brief descriptions will be completely suppressed. REPEAT_BRIEF = YES # This tag implements a quasi-intelligent brief description abbreviator # that is used to form the text in various listings. Each string # in this list, if found as the leading text of the brief description, will be # stripped from the text and the result after processing the whole list, is # used as the annotated text. Otherwise, the brief description is used as-is. # If left blank, the following values are used ("$name" is automatically # replaced with the name of the entity): "The $name class" "The $name widget" # "The $name file" "is" "provides" "specifies" "contains" # "represents" "a" "an" "the" ABBREVIATE_BRIEF = # If the ALWAYS_DETAILED_SEC and REPEAT_BRIEF tags are both set to YES then # Doxygen will generate a detailed section even if there is only a brief # description. ALWAYS_DETAILED_SEC = NO # If the INLINE_INHERITED_MEMB tag is set to YES, doxygen will show all # inherited members of a class in the documentation of that class as if those # members were ordinary class members. Constructors, destructors and assignment # operators of the base classes will not be shown. INLINE_INHERITED_MEMB = NO # If the FULL_PATH_NAMES tag is set to YES then Doxygen will prepend the full # path before files name in the file list and in the header files. If set # to NO the shortest path that makes the file name unique will be used. FULL_PATH_NAMES = YES # If the FULL_PATH_NAMES tag is set to YES then the STRIP_FROM_PATH tag # can be used to strip a user-defined part of the path. Stripping is # only done if one of the specified strings matches the left-hand part of # the path. The tag can be used to show relative paths in the file list. # If left blank the directory from which doxygen is run is used as the # path to strip. STRIP_FROM_PATH = # The STRIP_FROM_INC_PATH tag can be used to strip a user-defined part of # the path mentioned in the documentation of a class, which tells # the reader which header file to include in order to use a class. # If left blank only the name of the header file containing the class # definition is used. Otherwise one should specify the include paths that # are normally passed to the compiler using the -I flag. STRIP_FROM_INC_PATH = # If the SHORT_NAMES tag is set to YES, doxygen will generate much shorter # (but less readable) file names. This can be useful is your file systems # doesn't support long names like on DOS, Mac, or CD-ROM. SHORT_NAMES = NO # If the JAVADOC_AUTOBRIEF tag is set to YES then Doxygen # will interpret the first line (until the first dot) of a JavaDoc-style # comment as the brief description. If set to NO, the JavaDoc # comments will behave just like the Qt-style comments (thus requiring an # explicit @brief command for a brief description. JAVADOC_AUTOBRIEF = YES # The MULTILINE_CPP_IS_BRIEF tag can be set to YES to make Doxygen # treat a multi-line C++ special comment block (i.e. a block of //! or /// # comments) as a brief description. This used to be the default behaviour. # The new default is to treat a multi-line C++ comment block as a detailed # description. Set this tag to YES if you prefer the old behaviour instead. MULTILINE_CPP_IS_BRIEF = NO # If the INHERIT_DOCS tag is set to YES (the default) then an undocumented # member inherits the documentation from any documented member that it # re-implements. INHERIT_DOCS = YES # If the SEPARATE_MEMBER_PAGES tag is set to YES, then doxygen will produce # a new page for each member. If set to NO, the documentation of a member will # be part of the file/class/namespace that contains it. SEPARATE_MEMBER_PAGES = NO # The TAB_SIZE tag can be used to set the number of spaces in a tab. # Doxygen uses this value to replace tabs by spaces in code fragments. TAB_SIZE = 8 # This tag can be used to specify a number of aliases that acts # as commands in the documentation. An alias has the form "name=value". # For example adding "sideeffect=\par Side Effects:\n" will allow you to # put the command \sideeffect (or @sideeffect) in the documentation, which # will result in a user-defined paragraph with heading "Side Effects:". # You can put \n's in the value part of an alias to insert newlines. ALIASES = # Set the OPTIMIZE_OUTPUT_FOR_C tag to YES if your project consists of C # sources only. Doxygen will then generate output that is more tailored for C. # For instance, some of the names that are used will be different. The list # of all members will be omitted, etc. OPTIMIZE_OUTPUT_FOR_C = YES # Set the OPTIMIZE_OUTPUT_JAVA tag to YES if your project consists of Java # sources only. Doxygen will then generate output that is more tailored for Java. # For instance, namespaces will be presented as packages, qualified scopes # will look different, etc. OPTIMIZE_OUTPUT_JAVA = NO # If you use STL classes (i.e. std::string, std::vector, etc.) but do not want to # include (a tag file for) the STL sources as input, then you should # set this tag to YES in order to let doxygen match functions declarations and # definitions whose arguments contain STL classes (e.g. func(std::string); v.s. # func(std::string) {}). This also make the inheritance and collaboration # diagrams that involve STL classes more complete and accurate. BUILTIN_STL_SUPPORT = NO # If you use Microsoft's C++/CLI language, you should set this option to YES to # enable parsing support. CPP_CLI_SUPPORT = NO # If member grouping is used in the documentation and the DISTRIBUTE_GROUP_DOC # tag is set to YES, then doxygen will reuse the documentation of the first # member in the group (if any) for the other members of the group. By default # all members of a group must be documented explicitly. DISTRIBUTE_GROUP_DOC = NO # Set the SUBGROUPING tag to YES (the default) to allow class member groups of # the same type (for instance a group of public functions) to be put as a # subgroup of that type (e.g. under the Public Functions section). Set it to # NO to prevent subgrouping. Alternatively, this can be done per class using # the \nosubgrouping command. SUBGROUPING = YES #--------------------------------------------------------------------------- # Build related configuration options #--------------------------------------------------------------------------- # If the EXTRACT_ALL tag is set to YES doxygen will assume all entities in # documentation are documented, even if no documentation was available. # Private class members and static file members will be hidden unless # the EXTRACT_PRIVATE and EXTRACT_STATIC tags are set to YES EXTRACT_ALL = NO # If the EXTRACT_PRIVATE tag is set to YES all private members of a class # will be included in the documentation. EXTRACT_PRIVATE = NO # If the EXTRACT_STATIC tag is set to YES all static members of a file # will be included in the documentation. EXTRACT_STATIC = NO # If the EXTRACT_LOCAL_CLASSES tag is set to YES classes (and structs) # defined locally in source files will be included in the documentation. # If set to NO only classes defined in header files are included. EXTRACT_LOCAL_CLASSES = NO # This flag is only useful for Objective-C code. When set to YES local # methods, which are defined in the implementation section but not in # the interface are included in the documentation. # If set to NO (the default) only methods in the interface are included. EXTRACT_LOCAL_METHODS = NO # If the HIDE_UNDOC_MEMBERS tag is set to YES, Doxygen will hide all # undocumented members of documented classes, files or namespaces. # If set to NO (the default) these members will be included in the # various overviews, but no documentation section is generated. # This option has no effect if EXTRACT_ALL is enabled. HIDE_UNDOC_MEMBERS = YES # If the HIDE_UNDOC_CLASSES tag is set to YES, Doxygen will hide all # undocumented classes that are normally visible in the class hierarchy. # If set to NO (the default) these classes will be included in the various # overviews. This option has no effect if EXTRACT_ALL is enabled. HIDE_UNDOC_CLASSES = YES # If the HIDE_FRIEND_COMPOUNDS tag is set to YES, Doxygen will hide all # friend (class|struct|union) declarations. # If set to NO (the default) these declarations will be included in the # documentation. HIDE_FRIEND_COMPOUNDS = YES # If the HIDE_IN_BODY_DOCS tag is set to YES, Doxygen will hide any # documentation blocks found inside the body of a function. # If set to NO (the default) these blocks will be appended to the # function's detailed documentation block. HIDE_IN_BODY_DOCS = NO # The INTERNAL_DOCS tag determines if documentation # that is typed after a \internal command is included. If the tag is set # to NO (the default) then the documentation will be excluded. # Set it to YES to include the internal documentation. INTERNAL_DOCS = NO # If the CASE_SENSE_NAMES tag is set to NO then Doxygen will only generate # file names in lower-case letters. If set to YES upper-case letters are also # allowed. This is useful if you have classes or files whose names only differ # in case and if your file system supports case sensitive file names. Windows # and Mac users are advised to set this option to NO. CASE_SENSE_NAMES = YES # If the HIDE_SCOPE_NAMES tag is set to NO (the default) then Doxygen # will show members with their full class and namespace scopes in the # documentation. If set to YES the scope will be hidden. HIDE_SCOPE_NAMES = NO # If the SHOW_INCLUDE_FILES tag is set to YES (the default) then Doxygen # will put a list of the files that are included by a file in the documentation # of that file. SHOW_INCLUDE_FILES = YES # If the INLINE_INFO tag is set to YES (the default) then a tag [inline] # is inserted in the documentation for inline members. INLINE_INFO = YES # If the SORT_MEMBER_DOCS tag is set to YES (the default) then doxygen # will sort the (detailed) documentation of file and class members # alphabetically by member name. If set to NO the members will appear in # declaration order. SORT_MEMBER_DOCS = YES # If the SORT_BRIEF_DOCS tag is set to YES then doxygen will sort the # brief documentation of file, namespace and class members alphabetically # by member name. If set to NO (the default) the members will appear in # declaration order. SORT_BRIEF_DOCS = YES # If the SORT_BY_SCOPE_NAME tag is set to YES, the class list will be # sorted by fully-qualified names, including namespaces. If set to # NO (the default), the class list will be sorted only by class name, # not including the namespace part. # Note: This option is not very useful if HIDE_SCOPE_NAMES is set to YES. # Note: This option applies only to the class list, not to the # alphabetical list. SORT_BY_SCOPE_NAME = NO # The GENERATE_TODOLIST tag can be used to enable (YES) or # disable (NO) the todo list. This list is created by putting \todo # commands in the documentation. GENERATE_TODOLIST = YES # The GENERATE_TESTLIST tag can be used to enable (YES) or # disable (NO) the test list. This list is created by putting \test # commands in the documentation. GENERATE_TESTLIST = YES # The GENERATE_BUGLIST tag can be used to enable (YES) or # disable (NO) the bug list. This list is created by putting \bug # commands in the documentation. GENERATE_BUGLIST = YES # The GENERATE_DEPRECATEDLIST tag can be used to enable (YES) or # disable (NO) the deprecated list. This list is created by putting # \deprecated commands in the documentation. GENERATE_DEPRECATEDLIST= YES # The ENABLED_SECTIONS tag can be used to enable conditional # documentation sections, marked by \if sectionname ... \endif. ENABLED_SECTIONS = # The MAX_INITIALIZER_LINES tag determines the maximum number of lines # the initial value of a variable or define consists of for it to appear in # the documentation. If the initializer consists of more lines than specified # here it will be hidden. Use a value of 0 to hide initializers completely. # The appearance of the initializer of individual variables and defines in the # documentation can be controlled using \showinitializer or \hideinitializer # command in the documentation regardless of this setting. MAX_INITIALIZER_LINES = 30 # Set the SHOW_USED_FILES tag to NO to disable the list of files generated # at the bottom of the documentation of classes and structs. If set to YES the # list will mention the files that were used to generate the documentation. SHOW_USED_FILES = YES # If the sources in your project are distributed over multiple directories # then setting the SHOW_DIRECTORIES tag to YES will show the directory hierarchy # in the documentation. The default is NO. SHOW_DIRECTORIES = NO # The FILE_VERSION_FILTER tag can be used to specify a program or script that # doxygen should invoke to get the current version for each file (typically from the # version control system). Doxygen will invoke the program by executing (via # popen()) the command , where is the value of # the FILE_VERSION_FILTER tag, and is the name of an input file # provided by doxygen. Whatever the program writes to standard output # is used as the file version. See the manual for examples. FILE_VERSION_FILTER = #--------------------------------------------------------------------------- # configuration options related to warning and progress messages #--------------------------------------------------------------------------- # The QUIET tag can be used to turn on/off the messages that are generated # by doxygen. Possible values are YES and NO. If left blank NO is used. QUIET = NO # The WARNINGS tag can be used to turn on/off the warning messages that are # generated by doxygen. Possible values are YES and NO. If left blank # NO is used. WARNINGS = YES # If WARN_IF_UNDOCUMENTED is set to YES, then doxygen will generate warnings # for undocumented members. If EXTRACT_ALL is set to YES then this flag will # automatically be disabled. WARN_IF_UNDOCUMENTED = YES # If WARN_IF_DOC_ERROR is set to YES, doxygen will generate warnings for # potential errors in the documentation, such as not documenting some # parameters in a documented function, or documenting parameters that # don't exist or using markup commands wrongly. WARN_IF_DOC_ERROR = YES # This WARN_NO_PARAMDOC option can be abled to get warnings for # functions that are documented, but have no documentation for their parameters # or return value. If set to NO (the default) doxygen will only warn about # wrong or incomplete parameter documentation, but not about the absence of # documentation. WARN_NO_PARAMDOC = NO # The WARN_FORMAT tag determines the format of the warning messages that # doxygen can produce. The string should contain the $file, $line, and $text # tags, which will be replaced by the file and line number from which the # warning originated and the warning text. Optionally the format may contain # $version, which will be replaced by the version of the file (if it could # be obtained via FILE_VERSION_FILTER) WARN_FORMAT = "$file:$line: $text" # The WARN_LOGFILE tag can be used to specify a file to which warning # and error messages should be written. If left blank the output is written # to stderr. WARN_LOGFILE = #--------------------------------------------------------------------------- # configuration options related to the input files #--------------------------------------------------------------------------- # The INPUT tag can be used to specify the files and/or directories that contain # documented source files. You may enter file names like "myfile.cpp" or # directories like "/usr/src/myproject". Separate the files or directories # with spaces. INPUT = . # This tag can be used to specify the character encoding of the source files that # doxygen parses. Internally doxygen uses the UTF-8 encoding, which is also the default # input encoding. Doxygen uses libiconv (or the iconv built into libc) for the transcoding. # See http://www.gnu.org/software/libiconv for the list of possible encodings. INPUT_ENCODING = UTF-8 # If the value of the INPUT tag contains directories, you can use the # FILE_PATTERNS tag to specify one or more wildcard pattern (like *.cpp # and *.h) to filter out the source-files in the directories. If left # blank the following patterns are tested: # *.c *.cc *.cxx *.cpp *.c++ *.java *.ii *.ixx *.ipp *.i++ *.inl *.h *.hh *.hxx # *.hpp *.h++ *.idl *.odl *.cs *.php *.php3 *.inc *.m *.mm *.py FILE_PATTERNS = *.doxy # The RECURSIVE tag can be used to turn specify whether or not subdirectories # should be searched for input files as well. Possible values are YES and NO. # If left blank NO is used. RECURSIVE = NO # The EXCLUDE tag can be used to specify files and/or directories that should # excluded from the INPUT source files. This way you can easily exclude a # subdirectory from a directory tree whose root is specified with the INPUT tag. EXCLUDE = *_private.h # The EXCLUDE_SYMLINKS tag can be used select whether or not files or # directories that are symbolic links (a Unix filesystem feature) are excluded # from the input. EXCLUDE_SYMLINKS = NO # If the value of the INPUT tag contains directories, you can use the # EXCLUDE_PATTERNS tag to specify one or more wildcard patterns to exclude # certain files from those directories. Note that the wildcards are matched # against the file with absolute path, so to exclude all test directories # for example use the pattern */test/* EXCLUDE_PATTERNS = *.yy.c *_private.h # The EXCLUDE_SYMBOLS tag can be used to specify one or more symbol names # (namespaces, classes, functions, etc.) that should be excluded from the output. # The symbol name can be a fully qualified name, a word, or if the wildcard * is used, # a substring. Examples: ANamespace, AClass, AClass::ANamespace, ANamespace::*Test EXCLUDE_SYMBOLS = # The EXAMPLE_PATH tag can be used to specify one or more files or # directories that contain example code fragments that are included (see # the \include command). EXAMPLE_PATH = # If the value of the EXAMPLE_PATH tag contains directories, you can use the # EXAMPLE_PATTERNS tag to specify one or more wildcard pattern (like *.cpp # and *.h) to filter out the source-files in the directories. If left # blank all files are included. EXAMPLE_PATTERNS = # If the EXAMPLE_RECURSIVE tag is set to YES then subdirectories will be # searched for input files to be used with the \include or \dontinclude # commands irrespective of the value of the RECURSIVE tag. # Possible values are YES and NO. If left blank NO is used. EXAMPLE_RECURSIVE = NO # The IMAGE_PATH tag can be used to specify one or more files or # directories that contain image that are included in the documentation (see # the \image command). IMAGE_PATH = doc/doxygen/pictures/ # The INPUT_FILTER tag can be used to specify a program that doxygen should # invoke to filter for each input file. Doxygen will invoke the filter program # by executing (via popen()) the command , where # is the value of the INPUT_FILTER tag, and is the name of an # input file. Doxygen will then use the output that the filter program writes # to standard output. If FILTER_PATTERNS is specified, this tag will be # ignored. INPUT_FILTER = "sed \ -e 's/.*\//' \ -e 's/.*\//' \ -e 's/.*\//' \ -e 's/.*\//' \ -e 's/.*\//' \ -e 's/.*\//' \ -e 's/.*\//' \ -e 's/.*\//' \ -e 's/.*\//' \ -e 's/.*\//' \ -e 's/.*\//' \ -e 's/.*\//' \ -e 's/.*\//' \ -e 's/.*\//' \ -e 's/.*\//' \ -e 's/.*\//' \ -e 's/_PUBLIC_//'" # The FILTER_PATTERNS tag can be used to specify filters on a per file pattern # basis. Doxygen will compare the file name with each pattern and apply the # filter if there is a match. The filters are a list of the form: # pattern=filter (like *.cpp=my_cpp_filter). See INPUT_FILTER for further # info on how filters are used. If FILTER_PATTERNS is empty, INPUT_FILTER # is applied to all files. FILTER_PATTERNS = # If the FILTER_SOURCE_FILES tag is set to YES, the input filter (if set using # INPUT_FILTER) will be used to filter the input files when producing source # files to browse (i.e. when SOURCE_BROWSER is set to YES). FILTER_SOURCE_FILES = NO #--------------------------------------------------------------------------- # configuration options related to source browsing #--------------------------------------------------------------------------- # If the SOURCE_BROWSER tag is set to YES then a list of source files will # be generated. Documented entities will be cross-referenced with these sources. # Note: To get rid of all source code in the generated output, make sure also # VERBATIM_HEADERS is set to NO. SOURCE_BROWSER = NO # Setting the INLINE_SOURCES tag to YES will include the body # of functions and classes directly in the documentation. INLINE_SOURCES = NO # Setting the STRIP_CODE_COMMENTS tag to YES (the default) will instruct # doxygen to hide any special comment blocks from generated source code # fragments. Normal C and C++ comments will always remain visible. STRIP_CODE_COMMENTS = YES # If the REFERENCED_BY_RELATION tag is set to YES (the default) # then for each documented function all documented # functions referencing it will be listed. REFERENCED_BY_RELATION = YES # If the REFERENCES_RELATION tag is set to YES (the default) # then for each documented function all documented entities # called/used by that function will be listed. REFERENCES_RELATION = YES # If the REFERENCES_LINK_SOURCE tag is set to YES (the default) # and SOURCE_BROWSER tag is set to YES, then the hyperlinks from # functions in REFERENCES_RELATION and REFERENCED_BY_RELATION lists will # link to the source code. Otherwise they will link to the documentstion. REFERENCES_LINK_SOURCE = YES # If the USE_HTAGS tag is set to YES then the references to source code # will point to the HTML generated by the htags(1) tool instead of doxygen # built-in source browser. The htags tool is part of GNU's global source # tagging system (see http://www.gnu.org/software/global/global.html). You # will need version 4.8.6 or higher. USE_HTAGS = NO # If the VERBATIM_HEADERS tag is set to YES (the default) then Doxygen # will generate a verbatim copy of the header file for each class for # which an include is specified. Set to NO to disable this. VERBATIM_HEADERS = NO #--------------------------------------------------------------------------- # configuration options related to the alphabetical class index #--------------------------------------------------------------------------- # If the ALPHABETICAL_INDEX tag is set to YES, an alphabetical index # of all compounds will be generated. Enable this if the project # contains a lot of classes, structs, unions or interfaces. ALPHABETICAL_INDEX = NO # If the alphabetical index is enabled (see ALPHABETICAL_INDEX) then # the COLS_IN_ALPHA_INDEX tag can be used to specify the number of columns # in which this list will be split (can be a number in the range [1..20]) COLS_IN_ALPHA_INDEX = 5 # In case all classes in a project start with a common prefix, all # classes will be put under the same header in the alphabetical index. # The IGNORE_PREFIX tag can be used to specify one or more prefixes that # should be ignored while generating the index headers. IGNORE_PREFIX = #--------------------------------------------------------------------------- # configuration options related to the HTML output #--------------------------------------------------------------------------- # If the GENERATE_HTML tag is set to YES (the default) Doxygen will # generate HTML output. GENERATE_HTML = YES # The HTML_OUTPUT tag is used to specify where the HTML docs will be put. # If a relative path is entered the value of OUTPUT_DIRECTORY will be # put in front of it. If left blank `html' will be used as the default path. HTML_OUTPUT = html/overview # The HTML_FILE_EXTENSION tag can be used to specify the file extension for # each generated HTML page (for example: .htm,.php,.asp). If it is left blank # doxygen will generate files with .html extension. HTML_FILE_EXTENSION = .html # The HTML_HEADER tag can be used to specify a personal HTML header for # each generated HTML page. If it is left blank doxygen will generate a # standard header. HTML_HEADER = doc/doxygen/header.html # The HTML_FOOTER tag can be used to specify a personal HTML footer for # each generated HTML page. If it is left blank doxygen will generate a # standard footer. HTML_FOOTER = doc/doxygen/footer.html # The HTML_STYLESHEET tag can be used to specify a user-defined cascading # style sheet that is used by each HTML page. It can be used to # fine-tune the look of the HTML output. If the tag is left blank doxygen # will generate a default style sheet. Note that doxygen will try to copy # the style sheet file to the HTML output directory, so don't put your own # stylesheet in the HTML output directory as well, or it will be erased! HTML_STYLESHEET = doc/doxygen/apidocs.css # If the HTML_ALIGN_MEMBERS tag is set to YES, the members of classes, # files or namespaces will be aligned in HTML using tables. If set to # NO a bullet list will be used. HTML_ALIGN_MEMBERS = YES # If the GENERATE_HTMLHELP tag is set to YES, additional index files # will be generated that can be used as input for tools like the # Microsoft HTML help workshop to generate a compressed HTML help file (.chm) # of the generated HTML documentation. GENERATE_HTMLHELP = NO # If the GENERATE_HTMLHELP tag is set to YES, the CHM_FILE tag can # be used to specify the file name of the resulting .chm file. You # can add a path in front of the file if the result should not be # written to the html output directory. CHM_FILE = # If the GENERATE_HTMLHELP tag is set to YES, the HHC_LOCATION tag can # be used to specify the location (absolute path including file name) of # the HTML help compiler (hhc.exe). If non-empty doxygen will try to run # the HTML help compiler on the generated index.hhp. HHC_LOCATION = # If the GENERATE_HTMLHELP tag is set to YES, the GENERATE_CHI flag # controls if a separate .chi index file is generated (YES) or that # it should be included in the master .chm file (NO). GENERATE_CHI = NO # If the GENERATE_HTMLHELP tag is set to YES, the BINARY_TOC flag # controls whether a binary table of contents is generated (YES) or a # normal table of contents (NO) in the .chm file. BINARY_TOC = NO # The TOC_EXPAND flag can be set to YES to add extra items for group members # to the contents of the HTML help documentation and to the tree view. TOC_EXPAND = NO # The DISABLE_INDEX tag can be used to turn on/off the condensed index at # top of each HTML page. The value NO (the default) enables the index and # the value YES disables it. DISABLE_INDEX = NO # This tag can be used to set the number of enum values (range [1..20]) # that doxygen will group on one line in the generated HTML documentation. ENUM_VALUES_PER_LINE = 4 # If the GENERATE_TREEVIEW tag is set to YES, a side panel will be # generated containing a tree-like index structure (just like the one that # is generated for HTML Help). For this to work a browser that supports # JavaScript, DHTML, CSS and frames is required (for instance Mozilla 1.0+, # Netscape 6.0+, Internet explorer 5.0+, or Konqueror). Windows users are # probably better off using the HTML help feature. GENERATE_TREEVIEW = NO # If the treeview is enabled (see GENERATE_TREEVIEW) then this tag can be # used to set the initial width (in pixels) of the frame in which the tree # is shown. TREEVIEW_WIDTH = 250 #--------------------------------------------------------------------------- # configuration options related to the LaTeX output #--------------------------------------------------------------------------- # If the GENERATE_LATEX tag is set to YES (the default) Doxygen will # generate Latex output. GENERATE_LATEX = NO # The LATEX_OUTPUT tag is used to specify where the LaTeX docs will be put. # If a relative path is entered the value of OUTPUT_DIRECTORY will be # put in front of it. If left blank `latex' will be used as the default path. LATEX_OUTPUT = latex # The LATEX_CMD_NAME tag can be used to specify the LaTeX command name to be # invoked. If left blank `latex' will be used as the default command name. LATEX_CMD_NAME = latex # The MAKEINDEX_CMD_NAME tag can be used to specify the command name to # generate index for LaTeX. If left blank `makeindex' will be used as the # default command name. MAKEINDEX_CMD_NAME = makeindex # If the COMPACT_LATEX tag is set to YES Doxygen generates more compact # LaTeX documents. This may be useful for small projects and may help to # save some trees in general. COMPACT_LATEX = NO # The PAPER_TYPE tag can be used to set the paper type that is used # by the printer. Possible values are: a4, a4wide, letter, legal and # executive. If left blank a4wide will be used. PAPER_TYPE = letter # The EXTRA_PACKAGES tag can be to specify one or more names of LaTeX # packages that should be included in the LaTeX output. EXTRA_PACKAGES = # The LATEX_HEADER tag can be used to specify a personal LaTeX header for # the generated latex document. The header should contain everything until # the first chapter. If it is left blank doxygen will generate a # standard header. Notice: only use this tag if you know what you are doing! LATEX_HEADER = # If the PDF_HYPERLINKS tag is set to YES, the LaTeX that is generated # is prepared for conversion to pdf (using ps2pdf). The pdf file will # contain links (just like the HTML output) instead of page references # This makes the output suitable for online browsing using a pdf viewer. PDF_HYPERLINKS = YES # If the USE_PDFLATEX tag is set to YES, pdflatex will be used instead of # plain latex in the generated Makefile. Set this option to YES to get a # higher quality PDF documentation. USE_PDFLATEX = YES # If the LATEX_BATCHMODE tag is set to YES, doxygen will add the \\batchmode. # command to the generated LaTeX files. This will instruct LaTeX to keep # running if errors occur, instead of asking the user for help. # This option is also used when generating formulas in HTML. LATEX_BATCHMODE = NO # If LATEX_HIDE_INDICES is set to YES then doxygen will not # include the index chapters (such as File Index, Compound Index, etc.) # in the output. LATEX_HIDE_INDICES = NO #--------------------------------------------------------------------------- # configuration options related to the RTF output #--------------------------------------------------------------------------- # If the GENERATE_RTF tag is set to YES Doxygen will generate RTF output # The RTF output is optimized for Word 97 and may not look very pretty with # other RTF readers or editors. GENERATE_RTF = NO # The RTF_OUTPUT tag is used to specify where the RTF docs will be put. # If a relative path is entered the value of OUTPUT_DIRECTORY will be # put in front of it. If left blank `rtf' will be used as the default path. RTF_OUTPUT = rtf # If the COMPACT_RTF tag is set to YES Doxygen generates more compact # RTF documents. This may be useful for small projects and may help to # save some trees in general. COMPACT_RTF = NO # If the RTF_HYPERLINKS tag is set to YES, the RTF that is generated # will contain hyperlink fields. The RTF file will # contain links (just like the HTML output) instead of page references. # This makes the output suitable for online browsing using WORD or other # programs which support those fields. # Note: wordpad (write) and others do not support links. RTF_HYPERLINKS = NO # Load stylesheet definitions from file. Syntax is similar to doxygen's # config file, i.e. a series of assignments. You only have to provide # replacements, missing definitions are set to their default value. RTF_STYLESHEET_FILE = # Set optional variables used in the generation of an rtf document. # Syntax is similar to doxygen's config file. RTF_EXTENSIONS_FILE = #--------------------------------------------------------------------------- # configuration options related to the man page output #--------------------------------------------------------------------------- # If the GENERATE_MAN tag is set to YES (the default) Doxygen will # generate man pages GENERATE_MAN = NO # The MAN_OUTPUT tag is used to specify where the man pages will be put. # If a relative path is entered the value of OUTPUT_DIRECTORY will be # put in front of it. If left blank `man' will be used as the default path. MAN_OUTPUT = man # The MAN_EXTENSION tag determines the extension that is added to # the generated man pages (default is the subroutine's section .3) MAN_EXTENSION = .3 # If the MAN_LINKS tag is set to YES and Doxygen generates man output, # then it will generate one additional man file for each entity # documented in the real man page(s). These additional files # only source the real man page, but without them the man command # would be unable to find the correct page. The default is NO. MAN_LINKS = YES #--------------------------------------------------------------------------- # configuration options related to the XML output #--------------------------------------------------------------------------- # If the GENERATE_XML tag is set to YES Doxygen will # generate an XML file that captures the structure of # the code including all documentation. GENERATE_XML = NO # The XML_OUTPUT tag is used to specify where the XML pages will be put. # If a relative path is entered the value of OUTPUT_DIRECTORY will be # put in front of it. If left blank `xml' will be used as the default path. XML_OUTPUT = xml # The XML_SCHEMA tag can be used to specify an XML schema, # which can be used by a validating XML parser to check the # syntax of the XML files. XML_SCHEMA = # The XML_DTD tag can be used to specify an XML DTD, # which can be used by a validating XML parser to check the # syntax of the XML files. XML_DTD = # If the XML_PROGRAMLISTING tag is set to YES Doxygen will # dump the program listings (including syntax highlighting # and cross-referencing information) to the XML output. Note that # enabling this will significantly increase the size of the XML output. XML_PROGRAMLISTING = YES #--------------------------------------------------------------------------- # configuration options for the AutoGen Definitions output #--------------------------------------------------------------------------- # If the GENERATE_AUTOGEN_DEF tag is set to YES Doxygen will # generate an AutoGen Definitions (see autogen.sf.net) file # that captures the structure of the code including all # documentation. Note that this feature is still experimental # and incomplete at the moment. GENERATE_AUTOGEN_DEF = NO #--------------------------------------------------------------------------- # configuration options related to the Perl module output #--------------------------------------------------------------------------- # If the GENERATE_PERLMOD tag is set to YES Doxygen will # generate a Perl module file that captures the structure of # the code including all documentation. Note that this # feature is still experimental and incomplete at the # moment. GENERATE_PERLMOD = NO # If the PERLMOD_LATEX tag is set to YES Doxygen will generate # the necessary Makefile rules, Perl scripts and LaTeX code to be able # to generate PDF and DVI output from the Perl module output. PERLMOD_LATEX = NO # If the PERLMOD_PRETTY tag is set to YES the Perl module output will be # nicely formatted so it can be parsed by a human reader. This is useful # if you want to understand what is going on. On the other hand, if this # tag is set to NO the size of the Perl module output will be much smaller # and Perl will parse it just the same. PERLMOD_PRETTY = YES # The names of the make variables in the generated doxyrules.make file # are prefixed with the string contained in PERLMOD_MAKEVAR_PREFIX. # This is useful so different doxyrules.make files included by the same # Makefile don't overwrite each other's variables. PERLMOD_MAKEVAR_PREFIX = #--------------------------------------------------------------------------- # Configuration options related to the preprocessor #--------------------------------------------------------------------------- # If the ENABLE_PREPROCESSING tag is set to YES (the default) Doxygen will # evaluate all C-preprocessor directives found in the sources and include # files. ENABLE_PREPROCESSING = YES # If the MACRO_EXPANSION tag is set to YES Doxygen will expand all macro # names in the source code. If set to NO (the default) only conditional # compilation will be performed. Macro expansion can be done in a controlled # way by setting EXPAND_ONLY_PREDEF to YES. MACRO_EXPANSION = NO # If the EXPAND_ONLY_PREDEF and MACRO_EXPANSION tags are both set to YES # then the macro expansion is limited to the macros specified with the # PREDEFINED and EXPAND_AS_DEFINED tags. EXPAND_ONLY_PREDEF = NO # If the SEARCH_INCLUDES tag is set to YES (the default) the includes files # in the INCLUDE_PATH (see below) will be search if a #include is found. SEARCH_INCLUDES = YES # The INCLUDE_PATH tag can be used to specify one or more directories that # contain include files that are not input files but should be processed by # the preprocessor. INCLUDE_PATH = # You can use the INCLUDE_FILE_PATTERNS tag to specify one or more wildcard # patterns (like *.h and *.hpp) to filter out the header-files in the # directories. If left blank, the patterns specified with FILE_PATTERNS will # be used. INCLUDE_FILE_PATTERNS = # The PREDEFINED tag can be used to specify one or more macro names that # are defined before the preprocessor is started (similar to the -D option of # gcc). The argument of the tag is a list of macros of the form: name # or name=definition (no spaces). If the definition and the = are # omitted =1 is assumed. To prevent a macro definition from being # undefined via #undef or recursively expanded use the := operator # instead of the = operator. PREDEFINED = _PUBLIC_ # If the MACRO_EXPANSION and EXPAND_ONLY_PREDEF tags are set to YES then # this tag can be used to specify a list of macro names that should be expanded. # The macro definition that is found in the sources will be used. # Use the PREDEFINED tag if you want to use a different macro definition. EXPAND_AS_DEFINED = # If the SKIP_FUNCTION_MACROS tag is set to YES (the default) then # doxygen's preprocessor will remove all function-like macros that are alone # on a line, have an all uppercase name, and do not end with a semicolon. Such # function macros are typically used for boiler-plate code, and will confuse # the parser if not removed. SKIP_FUNCTION_MACROS = YES #--------------------------------------------------------------------------- # Configuration::additions related to external references #--------------------------------------------------------------------------- # The TAGFILES option can be used to specify one or more tagfiles. # Optionally an initial location of the external documentation # can be added for each tagfile. The format of a tag file without # this location is as follows: # TAGFILES = file1 file2 ... # Adding location for the tag files is done as follows: # TAGFILES = file1=loc1 "file2 = loc2" ... # where "loc1" and "loc2" can be relative or absolute paths or # URLs. If a location is present for each tag, the installdox tool # does not have to be run to correct the links. # Note that each tag file must have a unique name # (where the name does NOT include the path) # If a tag file is not located in the directory in which doxygen # is run, you must also specify the path to the tagfile here. TAGFILES = # When a file name is specified after GENERATE_TAGFILE, doxygen will create # a tag file that is based on the input files it reads. GENERATE_TAGFILE = # If the ALLEXTERNALS tag is set to YES all external classes will be listed # in the class index. If set to NO only the inherited external classes # will be listed. ALLEXTERNALS = NO # If the EXTERNAL_GROUPS tag is set to YES all external groups will be listed # in the modules index. If set to NO, only the current project's groups will # be listed. EXTERNAL_GROUPS = YES # The PERL_PATH should be the absolute path and name of the perl script # interpreter (i.e. the result of `which perl'). PERL_PATH = /usr/bin/perl #--------------------------------------------------------------------------- # Configuration options related to the dot tool #--------------------------------------------------------------------------- # If the CLASS_DIAGRAMS tag is set to YES (the default) Doxygen will # generate a inheritance diagram (in HTML, RTF and LaTeX) for classes with base # or super classes. Setting the tag to NO turns the diagrams off. Note that # this option is superseded by the HAVE_DOT option below. This is only a # fallback. It is recommended to install and use dot, since it yields more # powerful graphs. CLASS_DIAGRAMS = YES # You can define message sequence charts within doxygen comments using the \msc # command. Doxygen will then run the mscgen tool (see http://www.mcternan.me.uk/mscgen/) to # produce the chart and insert it in the documentation. The MSCGEN_PATH tag allows you to # specify the directory where the mscgen tool resides. If left empty the tool is assumed to # be found in the default search path. MSCGEN_PATH = # If set to YES, the inheritance and collaboration graphs will hide # inheritance and usage relations if the target is undocumented # or is not a class. HIDE_UNDOC_RELATIONS = YES # If you set the HAVE_DOT tag to YES then doxygen will assume the dot tool is # available from the path. This tool is part of Graphviz, a graph visualization # toolkit from AT&T and Lucent Bell Labs. The other options in this section # have no effect if this option is set to NO (the default) HAVE_DOT = NO # If the CLASS_GRAPH and HAVE_DOT tags are set to YES then doxygen # will generate a graph for each documented class showing the direct and # indirect inheritance relations. Setting this tag to YES will force the # the CLASS_DIAGRAMS tag to NO. CLASS_GRAPH = YES # If the COLLABORATION_GRAPH and HAVE_DOT tags are set to YES then doxygen # will generate a graph for each documented class showing the direct and # indirect implementation dependencies (inheritance, containment, and # class references variables) of the class with other documented classes. COLLABORATION_GRAPH = YES # If the GROUP_GRAPHS and HAVE_DOT tags are set to YES then doxygen # will generate a graph for groups, showing the direct groups dependencies GROUP_GRAPHS = YES # If the UML_LOOK tag is set to YES doxygen will generate inheritance and # collaboration diagrams in a style similar to the OMG's Unified Modeling # Language. UML_LOOK = NO # If set to YES, the inheritance and collaboration graphs will show the # relations between templates and their instances. TEMPLATE_RELATIONS = NO # If the ENABLE_PREPROCESSING, SEARCH_INCLUDES, INCLUDE_GRAPH, and HAVE_DOT # tags are set to YES then doxygen will generate a graph for each documented # file showing the direct and indirect include dependencies of the file with # other documented files. INCLUDE_GRAPH = YES # If the ENABLE_PREPROCESSING, SEARCH_INCLUDES, INCLUDED_BY_GRAPH, and # HAVE_DOT tags are set to YES then doxygen will generate a graph for each # documented header file showing the documented files that directly or # indirectly include this file. INCLUDED_BY_GRAPH = YES # If the CALL_GRAPH and HAVE_DOT tags are set to YES then doxygen will # generate a call dependency graph for every global function or class method. # Note that enabling this option will significantly increase the time of a run. # So in most cases it will be better to enable call graphs for selected # functions only using the \callgraph command. CALL_GRAPH = NO # If the CALLER_GRAPH and HAVE_DOT tags are set to YES then doxygen will # generate a caller dependency graph for every global function or class method. # Note that enabling this option will significantly increase the time of a run. # So in most cases it will be better to enable caller graphs for selected # functions only using the \callergraph command. CALLER_GRAPH = NO # If the GRAPHICAL_HIERARCHY and HAVE_DOT tags are set to YES then doxygen # will graphical hierarchy of all classes instead of a textual one. GRAPHICAL_HIERARCHY = YES # If the DIRECTORY_GRAPH, SHOW_DIRECTORIES and HAVE_DOT tags are set to YES # then doxygen will show the dependencies a directory has on other directories # in a graphical way. The dependency relations are determined by the #include # relations between the files in the directories. DIRECTORY_GRAPH = YES # The DOT_IMAGE_FORMAT tag can be used to set the image format of the images # generated by dot. Possible values are png, jpg, or gif # If left blank png will be used. DOT_IMAGE_FORMAT = png # The tag DOT_PATH can be used to specify the path where the dot tool can be # found. If left blank, it is assumed the dot tool can be found in the path. DOT_PATH = # The DOTFILE_DIRS tag can be used to specify one or more directories that # contain dot files that are included in the documentation (see the # \dotfile command). DOTFILE_DIRS = # The MAX_DOT_GRAPH_MAX_NODES tag can be used to set the maximum number of # nodes that will be shown in the graph. If the number of nodes in a graph # becomes larger than this value, doxygen will truncate the graph, which is # visualized by representing a node as a red box. Note that doxygen will always # show the root nodes and its direct children regardless of this setting. DOT_GRAPH_MAX_NODES = 50 # Set the DOT_TRANSPARENT tag to YES to generate images with a transparent # background. This is disabled by default, which results in a white background. # Warning: Depending on the platform used, enabling this option may lead to # badly anti-aliased labels on the edges of a graph (i.e. they become hard to # read). DOT_TRANSPARENT = NO # Set the DOT_MULTI_TARGETS tag to YES allow dot to generate multiple output # files in one run (i.e. multiple -o and -T options on the command line). This # makes dot run faster, but since only newer versions of dot (>1.8.10) # support this, this feature is disabled by default. DOT_MULTI_TARGETS = NO # If the GENERATE_LEGEND tag is set to YES (the default) Doxygen will # generate a legend page explaining the meaning of the various boxes and # arrows in the dot generated graphs. GENERATE_LEGEND = YES # If the DOT_CLEANUP tag is set to YES (the default) Doxygen will # remove the intermediate dot files that are used to generate # the various graphs. DOT_CLEANUP = YES #--------------------------------------------------------------------------- # Configuration::additions related to the search engine #--------------------------------------------------------------------------- # The SEARCHENGINE tag specifies whether or not a search engine should be # used. If set to NO the values of all tags below this one will be ignored. SEARCHENGINE = NO openchange-2.0/IDL_LICENSE.txt000066400000000000000000000006371223057412600160050ustar00rootroot00000000000000The IDL files in this directory are made available by the OpenChange Team under the following license: Permission to use, copy, modify, and distribute these interface definitions for any purpose is hereby granted without fee. This work is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. openchange-2.0/Mainpage.doxy000066400000000000000000000034041223057412600161130ustar00rootroot00000000000000/** @mainpage The OpenChange Library API Reference This is the online reference for developing with the OpenChange client libraries. Among other things, the OpenChange client libraries provide: - MAPI client library (libmapi) - MAPI administration libraries (libmapiadmin) - OpenChange Property Files (libocpf) - A regression test framework (mapitest) - MAPIProxy project (mapiproxy) - C++ bindings for libmapi (libmapi++)

OpenChange Project Goals

The OpenChange Project aims to provide a portable Open Source implementation of Microsoft Exchange Server and Exchange protocols. Exchange is a groupware server designed to work with Microsoft Outlook, and providing features such as a messaging server, shared calendars, contact databases, public folders, notes and tasks. The OpenChange project has three goals: - To provide a library for interoperability with Exchange protocols, and to assist implementors to use this to create groupware that interoperates with both Exchange and other OpenChange-based software. - To provide an alternative to Microsoft Exchange Server which uses native Exchange protocols and provides exactly equivalent functionality when viewed from Microsoft Outlook clients. - To develop a body of knowledge about the most popular groupware protocols in use commercially today in order to promote development of a documented and unencumbered standard, with all the benefits that standards bring.

More information

Visit the OpenChange web site for other useful information. */ openchange-2.0/Makefile000066400000000000000000001613751223057412600151410ustar00rootroot00000000000000# # Makefile for OpenChange # Written by Jelmer Vernooij , 2005. ifneq ($(MAKECMDGOALS), samba) ifneq ($(MAKECMDGOALS), samba-git) include config.mk endif endif default: all # Until we add proper dependencies for all the C files: .NOTPARALLEL: config.mk: config.status config.mk.in ./config.status config.status: configure @if test x"$(prefix)" != x""; \ then \ echo "Running configure with prefix '$(prefix)'..."; \ ./configure --prefix=$(prefix); \ else \ echo "Running configure without prefix"; \ ./configure; \ fi configure: configure.ac PREFIX=$(prefix) ./autogen.sh samba: ./script/installsamba4.sh all samba-git: ./script/installsamba4.sh git-all samba-git-update: ./script/installsamba4.sh git-update ################################################################# # top level compilation rules ################################################################# all: $(OC_IDL) \ $(OC_LIBS) \ $(OC_TOOLS) \ $(OC_SERVER) \ $(PYMAPIALL) \ $(COVERAGE_INIT) \ $(OPENCHANGE_QT4) install: all \ installlib \ installpc \ installheader \ $(OC_TOOLS_INSTALL) \ $(OC_SERVER_INSTALL) \ $(PYMAPIINSTALL) \ installnagios installlib: $(OC_LIBS_INSTALL) installpc: $(OC_LIBS_INSTALLPC) installheader: $(OC_LIBS_INSTALLHEADERS) uninstall:: $(OC_LIBS_UNINSTALL) \ $(OC_TOOLS_UNINSTALL) \ $(OC_SERVER_UNINSTALL) \ $(PYMAPIUNINSTALL) dist:: distclean ./autogen.sh distclean:: clean rm -f aclocal.m4 rm -rf autom4te.cache rm -f Doxyfile rm -f libmapi/Doxyfile rm -f libmapiadmin/Doxyfile rm -f libocpf/Doxyfile rm -f libmapi++/Doxyfile rm -f mapiproxy/Doxyfile rm -f mapiproxy/libmapistore/Doxyfile rm -f config.status config.log rm -f config.h rm -f stamp-h1 rm -f utils/mapitest/Doxyfile rm -f intltool-extract intltool-merge intltool-update rm -rf apidocs rm -rf gen_ndr rm -f tags clean:: rm -f *~ rm -f */*~ rm -f */*/*~ rm -f doc/examples/mapi_sample1 rm -f doc/examples/fetchappointment rm -f doc/examples/fetchmail re:: clean install ################################################################# # Suffixes compilation rules ################################################################# .SUFFIXES: .c .o .h .po .idl .cpp .idl.h: @echo "Generating $@" @$(PIDL) --outputdir=gen_ndr --header -- $< .c.o: @echo "Compiling $<" @$(CC) $(CFLAGS) -c $< -o $@ .c.po: @echo "Compiling $< with -fPIC" @$(CC) $(CFLAGS) -fPIC -c $< -o $@ .cpp.o: @echo "Compiling $< with -fPIC" @$(CXX) $(CXXFLAGS) $(QT4_CXXFLAGS) -fPIC -c $< -o $@ .cpp.po: @echo "Compiling $< with -fPIC" @$(CXX) $(CXXFLAGS) -fPIC -c $< -o $@ ################################################################# # IDL compilation rules ################################################################# idl: gen_ndr gen_ndr/ndr_exchange.h gen_ndr/ndr_property.h exchange.idl: properties_enum.h mapicodes_enum.h gen_ndr: @echo "Creating the gen_ndr directory" mkdir -p gen_ndr gen_ndr/ndr_%.h gen_ndr/ndr_%.c: %.idl %.h @echo "Generating $@" @$(PIDL) --outputdir=gen_ndr --ndr-parser -- $< gen_ndr/ndr_%_c.h gen_ndr/ndr_%_c.c: %.idl %.h @echo "Generating $@" @$(PIDL) --outputdir=gen_ndr --client -- $< gen_ndr/ndr_%_s.c: %.idl @echo "Generating $@" @$(PIDL) --outputdir=gen_ndr --server -- $< ################################################################# # libmapi compilation rules ################################################################# LIBMAPI_SO_VERSION = 0 libmapi: idl \ libmapi/version.h \ libmapi.$(SHLIBEXT).$(PACKAGE_VERSION) libmapi-install: libmapi \ libmapi-installpc \ libmapi-installlib \ libmapi-installheader \ libmapi-installscript libmapi-uninstall: libmapi-uninstallpc \ libmapi-uninstalllib \ libmapi-uninstallheader \ libmapi-uninstallscript libmapi-clean:: rm -f libmapi/*.o libmapi/*.po rm -f libmapi/*.gcno libmapi/*.gcda libmapi/*.gcov rm -f libmapi/socket/*.o libmapi/socket/*.po rm -f libmapi/socket/*.gcno libmapi/socket/*.gcda rm -f libmapi/version.h ifneq ($(SNAPSHOT), no) rm -f libmapi/mapicode.c rm -f libmapi/codepage_lcid.c rm -f mapicodes_enum.h endif rm -f gen_ndr/ndr_exchange* rm -f gen_ndr/exchange.h rm -f gen_ndr/ndr_property* rm -f gen_ndr/property.h rm -f ndr_mapi.o ndr_mapi.po rm -f ndr_mapi.gcno ndr_mapi.gcda rm -f *~ rm -f */*~ rm -f */*/*~ rm -f libmapi.$(SHLIBEXT).$(PACKAGE_VERSION) libmapi.$(SHLIBEXT).* \ libmapi.$(SHLIBEXT) clean:: libmapi-clean libmapi-distclean:: rm -f libmapi.pc distclean:: libmapi-distclean libmapi-installpc: @echo "[*] install: libmapi pc files" $(INSTALL) -d $(DESTDIR)$(libdir)/pkgconfig $(INSTALL) -m 0644 libmapi.pc $(DESTDIR)$(libdir)/pkgconfig libmapi-installlib: @echo "[*] install: libmapi library" $(INSTALL) -d $(DESTDIR)$(libdir) $(INSTALL) -m 0755 libmapi.$(SHLIBEXT).$(PACKAGE_VERSION) $(DESTDIR)$(libdir) ln -sf libmapi.$(SHLIBEXT).$(PACKAGE_VERSION) $(DESTDIR)$(libdir)/libmapi.$(SHLIBEXT) ifeq ($(MANUALLY_CREATE_SYMLINKS), yes) ln -sf libmapi.$(SHLIBEXT).$(PACKAGE_VERSION) $(DESTDIR)$(libdir)/libmapi.$(SHLIBEXT).$(LIBMAPI_SO_VERSION) endif libmapi-installheader: @echo "[*] install: libmapi headers" $(INSTALL) -d $(DESTDIR)$(includedir)/libmapi $(INSTALL) -d $(DESTDIR)$(includedir)/libmapi/socket $(INSTALL) -d $(DESTDIR)$(includedir)/gen_ndr $(INSTALL) -m 0644 libmapi/libmapi.h $(DESTDIR)$(includedir)/libmapi/ $(INSTALL) -m 0644 libmapi/nspi.h $(DESTDIR)$(includedir)/libmapi/ $(INSTALL) -m 0644 libmapi/emsmdb.h $(DESTDIR)$(includedir)/libmapi/ $(INSTALL) -m 0644 libmapi/mapi_context.h $(DESTDIR)$(includedir)/libmapi/ $(INSTALL) -m 0644 libmapi/mapi_provider.h $(DESTDIR)$(includedir)/libmapi/ $(INSTALL) -m 0644 libmapi/mapi_id_array.h $(DESTDIR)$(includedir)/libmapi/ $(INSTALL) -m 0644 libmapi/mapi_notification.h $(DESTDIR)$(includedir)/libmapi/ $(INSTALL) -m 0644 libmapi/mapi_object.h $(DESTDIR)$(includedir)/libmapi/ $(INSTALL) -m 0644 libmapi/mapi_profile.h $(DESTDIR)$(includedir)/libmapi/ $(INSTALL) -m 0644 libmapi/mapi_nameid.h $(DESTDIR)$(includedir)/libmapi/ $(INSTALL) -m 0644 libmapi/mapidefs.h $(DESTDIR)$(includedir)/libmapi/ $(INSTALL) -m 0644 libmapi/version.h $(DESTDIR)$(includedir)/libmapi/ $(INSTALL) -m 0644 libmapi/mapicode.h $(DESTDIR)$(includedir)/libmapi/ $(INSTALL) -m 0644 libmapi/idset.h $(DESTDIR)$(includedir)/libmapi/ $(INSTALL) -m 0644 libmapi/property_tags.h $(DESTDIR)$(includedir)/libmapi/ $(INSTALL) -m 0644 libmapi/property_altnames.h $(DESTDIR)$(includedir)/libmapi/ $(INSTALL) -m 0644 libmapi/socket/netif.h $(DESTDIR)$(includedir)/libmapi/socket/ $(INSTALL) -m 0644 gen_ndr/exchange.h $(DESTDIR)$(includedir)/gen_ndr/ $(INSTALL) -m 0644 gen_ndr/property.h $(DESTDIR)$(includedir)/gen_ndr/ $(INSTALL) -m 0644 gen_ndr/ndr_exchange.h $(DESTDIR)$(includedir)/gen_ndr/ $(INSTALL) -m 0644 gen_ndr/ndr_property.h $(DESTDIR)$(includedir)/gen_ndr/ @$(SED) $(DESTDIR)$(includedir)/libmapi/*.h @$(SED) $(DESTDIR)$(includedir)/libmapi/socket/*.h @$(SED) $(DESTDIR)$(includedir)/gen_ndr/*.h libmapi-installscript: $(INSTALL) -d $(DESTDIR)$(datadir)/setup/profiles $(INSTALL) -m 0644 setup/profiles/oc_profiles* $(DESTDIR)$(datadir)/setup/profiles/ libmapi-uninstallpc: rm -f $(DESTDIR)$(libdir)/pkgconfig/libmapi.pc libmapi-uninstalllib: rm -f $(DESTDIR)$(libdir)/libmapi.* libmapi-uninstallheader: rm -rf $(DESTDIR)$(includedir)/libmapi rm -f $(DESTDIR)$(includedir)/gen_ndr/exchange.h rm -f $(DESTDIR)$(includedir)/gen_ndr/property.h libmapi-uninstallscript: rm -f $(DESTDIR)$(datadir)/setup/profiles/oc_profiles* rm -rf $(DESTDIR)$(datadir)/setup/profiles libmapi.$(SHLIBEXT).$(PACKAGE_VERSION): \ libmapi/emsmdb.po \ libmapi/async_emsmdb.po \ libmapi/IABContainer.po \ libmapi/IProfAdmin.po \ libmapi/IMAPIContainer.po \ libmapi/IMAPIFolder.po \ libmapi/IMAPIProp.po \ libmapi/IMAPISession.po \ libmapi/IMAPISupport.po \ libmapi/IStream.po \ libmapi/IMAPITable.po \ libmapi/IMessage.po \ libmapi/IMsgStore.po \ libmapi/IStoreFolder.po \ libmapi/IUnknown.po \ libmapi/IMSProvider.po \ libmapi/IXPLogon.po \ libmapi/FXICS.po \ libmapi/utils.po \ libmapi/property.po \ libmapi/cdo_mapi.po \ libmapi/lzfu.po \ libmapi/mapi_object.po \ libmapi/mapi_id_array.po \ libmapi/property_tags.po \ libmapi/mapidump.po \ libmapi/mapicode.po \ libmapi/codepage_lcid.po \ libmapi/mapi_nameid.po \ libmapi/nspi.po \ libmapi/simple_mapi.po \ libmapi/freebusy.po \ libmapi/x500.po \ libmapi/fxparser.po \ libmapi/notif.po \ libmapi/idset.po \ ndr_mapi.po \ gen_ndr/ndr_exchange.po \ gen_ndr/ndr_exchange_c.po \ gen_ndr/ndr_property.po \ libmapi/socket/interface.po \ libmapi/socket/netif.po @echo "Linking $@" @$(CC) $(DSOOPT) $(CFLAGS) $(LDFLAGS) -Wl,-soname,libmapi.$(SHLIBEXT).$(LIBMAPI_SO_VERSION) -o $@ $^ $(LIBS) libmapi.$(SHLIBEXT).$(LIBMAPI_SO_VERSION): libmapi.$(SHLIBEXT).$(PACKAGE_VERSION) ln -fs $< $@ libmapi/version.h: VERSION @./script/mkversion.sh VERSION libmapi/version.h $(PACKAGE_VERSION) $(top_builddir)/ libmapi/emsmdb.c: libmapi/emsmdb.h gen_ndr/ndr_exchange_c.h libmapi/async_emsmdb.c: libmapi/emsmdb.h gen_ndr/ndr_exchange_c.h libmapi/mapicode.c mapicodes_enum.h: libmapi/conf/mparse.pl libmapi/conf/mapi-codes libmapi/conf/mparse.pl --parser=mapicodes --outputdir=libmapi/ libmapi/conf/mapi-codes libmapi/codepage_lcid.c: libmapi/conf/mparse.pl libmapi/conf/codepage-lcid libmapi/conf/mparse.pl --parser=codepage_lcid --outputdir=libmapi/ libmapi/conf/codepage-lcid ################################################################# # libmapi++ compilation rules ################################################################# LIBMAPIPP_SO_VERSION = 0 libmapixx: libmapi \ libmapipp.$(SHLIBEXT).$(PACKAGE_VERSION) \ libmapixx-tests \ libmapixx-examples libmapipp.$(SHLIBEXT).$(PACKAGE_VERSION): \ libmapi++/src/attachment.po \ libmapi++/src/folder.po \ libmapi++/src/mapi_exception.po \ libmapi++/src/message.po \ libmapi++/src/object.po \ libmapi++/src/profile.po \ libmapi++/src/session.po \ libmapi.$(SHLIBEXT).$(LIBMAPI_SO_VERSION) @echo "Linking $@" @$(CXX) $(DSOOPT) $(CXXFLAGS) $(LDFLAGS) -Wl,-soname,libmapipp.$(SHLIBEXT).$(LIBMAPIPP_SO_VERSION) -o $@ $^ $(LIBS) libmapixx-installpc: @echo "[*] install: libmapi++ pc files" $(INSTALL) -d $(DESTDIR)$(libdir)/pkgconfig $(INSTALL) -m 0644 libmapi++.pc $(DESTDIR)$(libdir)/pkgconfig libmapixx-distclean: rm -f libmapi++.pc libmapixx-uninstallpc: rm -f $(DESTDIR)$(libdir)/pkgconfig/libmapi++.pc distclean::libmapixx-distclean clean:: libmapixx-clean libmapixx-install: libmapixx-installheader libmapixx-installlib libmapixx-installpc libmapixx-uninstall: libmapixx-uninstallheader libmapixx-uninstalllib libmapixx-uninstallpc libmapixx-installheader: @echo "[*] install: libmapi++ headers" $(INSTALL) -d $(DESTDIR)$(includedir)/libmapi++ $(INSTALL) -m 0644 libmapi++/attachment.h $(DESTDIR)$(includedir)/libmapi++/ $(INSTALL) -m 0644 libmapi++/clibmapi.h $(DESTDIR)$(includedir)/libmapi++/ $(INSTALL) -m 0644 libmapi++/folder.h $(DESTDIR)$(includedir)/libmapi++/ $(INSTALL) -m 0644 libmapi++/libmapi++.h $(DESTDIR)$(includedir)/libmapi++/ $(INSTALL) -m 0644 libmapi++/mapi_exception.h $(DESTDIR)$(includedir)/libmapi++/ $(INSTALL) -m 0644 libmapi++/message.h $(DESTDIR)$(includedir)/libmapi++/ $(INSTALL) -m 0644 libmapi++/message_store.h $(DESTDIR)$(includedir)/libmapi++/ $(INSTALL) -m 0644 libmapi++/object.h $(DESTDIR)$(includedir)/libmapi++/ $(INSTALL) -m 0644 libmapi++/profile.h $(DESTDIR)$(includedir)/libmapi++/ $(INSTALL) -m 0644 libmapi++/property_container.h $(DESTDIR)$(includedir)/libmapi++/ $(INSTALL) -m 0644 libmapi++/session.h $(DESTDIR)$(includedir)/libmapi++/ @$(SED) $(DESTDIR)$(includedir)/libmapi++/*.h libmapixx-libs-clean: rm -f libmapi++/src/*.po rm -f libmapipp.$(SHLIBEXT)* rm -f libmapi++/src/*.gcno libmapi++/src/*.gcda libmapixx-clean: libmapixx-tests-clean libmapixx-libs-clean libmapixx-installlib: @echo "[*] install: libmapi++ library" $(INSTALL) -d $(DESTDIR)$(libdir) $(INSTALL) -m 0755 libmapipp.$(SHLIBEXT).$(PACKAGE_VERSION) $(DESTDIR)$(libdir) ln -sf libmapipp.$(SHLIBEXT).$(PACKAGE_VERSION) $(DESTDIR)$(libdir)/libmapipp.$(SHLIBEXT) ifeq ($(MANUALLY_CREATE_SYMLINKS), yes) ln -sf libmapipp.$(SHLIBEXT).$(PACKAGE_VERSION) $(DESTDIR)$(libdir)/libmapipp.$(SHLIBEXT).$(LIBMAPIPP_SO_VERSION) endif libmapixx-uninstallheader: rm -rf $(DESTDIR)$(includedir)/libmapi++ libmapixx-uninstalllib: rm -f $(DESTDIR)$(libdir)/libmapipp.* libmapixx-tests: libmapixx-test \ libmapixx-attach \ libmapixx-exception \ libmapixx-profiletest libmapixx-tests-clean: libmapixx-test-clean \ libmapixx-attach-clean \ libmapixx-exception-clean \ libmapixx-profiletest-clean libmapixx-test: bin/libmapixx-test libmapixx-test-clean: rm -f bin/libmapixx-test rm -f libmapi++/tests/*.o clean:: libmapixx-tests-clean bin/libmapixx-test: libmapi++/tests/test.cpp \ libmapipp.$(SHLIBEXT).$(PACKAGE_VERSION) \ libmapi.$(SHLIBEXT).$(PACKAGE_VERSION) @echo "Linking sample application $@" @$(CXX) $(CXXFLAGS) $(LDFLAGS) -o $@ $^ $(LIBS) clean:: libmapixx-test-clean libmapixx-attach: bin/libmapixx-attach libmapixx-attach-clean: rm -f bin/libmapixx-attach rm -f libmapi++/tests/*.po rm -f libmapi++/tests/*.gcno libmapi++/tests/*.gcda bin/libmapixx-attach: libmapi++/tests/attach_test.po \ libmapipp.$(SHLIBEXT).$(PACKAGE_VERSION) \ libmapi.$(SHLIBEXT).$(PACKAGE_VERSION) @echo "Linking sample application $@" @$(CXX) $(CXXFLAGS) -o $@ $^ $(LIBS) clean:: libmapixx-attach-clean libmapixx-exception: bin/libmapixx-exception bin/libmapixx-exception: libmapi++/tests/exception_test.cpp \ libmapipp.$(SHLIBEXT).$(PACKAGE_VERSION) \ libmapi.$(SHLIBEXT).$(PACKAGE_VERSION) @echo "Linking exception test application $@" @$(CXX) $(CXXFLAGS) -o $@ $^ $(LIBS) libmapixx-exception-clean: rm -f bin/libmapixx-exception rm -f libmapi++/tests/*.o rm -f libmapi++/tests/*.gcno libmapi++/tests/*.gcda clean:: libmapixx-exception-clean libmapixx-profiletest: bin/libmapixx-profiletest libmapixx-profiletest-clean: rm -f bin/libmapixx-profiletest rm -f libmapi++/tests/*.po rm -f libmapi++/tests/*.gcno libmapi++/tests/*.gcda bin/libmapixx-profiletest: libmapi++/tests/profile_test.po \ libmapipp.$(SHLIBEXT).$(PACKAGE_VERSION) \ libmapi.$(SHLIBEXT).$(PACKAGE_VERSION) @echo "Linking profile test application $@" @$(CXX) $(CXXFLAGS) -o $@ $^ $(LIBS) clean:: libmapixx-profiletest-clean libmapixx-examples: libmapi++/examples/foldertree \ libmapi++/examples/messages libmapixx-foldertree-clean: rm -f libmapi++/examples/foldertree rm -f libmapi++/examples/*.o rm -f libmapi++/examples/*.gcno libmapi++/examples/*.gcda libmapixx-messages-clean: rm -f libmapi++/examples/messages rm -f libmapi++/examples/*.o rm -f libmapi++/examples/*.gcno libmapi++/examples/*.gcda libmapi++/examples/foldertree: libmapi++/examples/foldertree.cpp \ libmapipp.$(SHLIBEXT).$(PACKAGE_VERSION) \ libmapi.$(SHLIBEXT).$(PACKAGE_VERSION) @echo "Linking foldertree example application $@" @$(CXX) $(CXXFLAGS) -o $@ $^ $(LIBS) clean:: libmapixx-foldertree-clean libmapi++/examples/messages: libmapi++/examples/messages.cpp \ libmapipp.$(SHLIBEXT).$(PACKAGE_VERSION) \ libmapi.$(SHLIBEXT).$(PACKAGE_VERSION) @echo "Linking messages example application $@" @$(CXX) $(CXXFLAGS) -o $@ $^ $(LIBS) clean:: libmapixx-messages-clean ################################################################# # libmapiadmin compilation rules ################################################################# LIBMAPIADMIN_SO_VERSION = 0 libmapiadmin: libmapiadmin.$(SHLIBEXT).$(PACKAGE_VERSION) libmapiadmin-install: libmapiadmin-installpc \ libmapiadmin-installlib \ libmapiadmin-installheader libmapiadmin-uninstall: libmapiadmin-uninstallpc \ libmapiadmin-uninstalllib \ libmapiadmin-uninstallheader libmapiadmin-clean:: rm -f libmapiadmin/*.o libmapiadmin/*.po rm -f libmapiadmin/*.gcno libmapiadmin/*.gcda rm -f libmapiadmin.$(SHLIBEXT).$(PACKAGE_VERSION) libmapiadmin.$(SHLIBEXT).* \ libmapiadmin.$(SHLIBEXT) clean:: libmapiadmin-clean libmapiadmin-distclean:: rm -f libmapiadmin.pc distclean:: libmapiadmin-distclean libmapiadmin-installpc: @echo "[*] install: libmapiadmin pc files" $(INSTALL) -d $(DESTDIR)$(libdir)/pkgconfig $(INSTALL) -m 0644 libmapiadmin.pc $(DESTDIR)$(libdir)/pkgconfig libmapiadmin-installlib: @echo "[*] install: libmapiadmin library" $(INSTALL) -d $(DESTDIR)$(libdir) $(INSTALL) -m 0755 libmapiadmin.$(SHLIBEXT).$(PACKAGE_VERSION) $(DESTDIR)$(libdir) ln -sf libmapiadmin.$(SHLIBEXT).$(PACKAGE_VERSION) $(DESTDIR)$(libdir)/libmapiadmin.$(SHLIBEXT) ifeq ($(MANUALLY_CREATE_SYMLINKS), yes) ln -sf libmapiadmin.$(SHLIBEXT).$(PACKAGE_VERSION) $(DESTDIR)$(libdir)/libmapiadmin.$(SHLIBEXT).$(LIBMAPIADMIN_SO_VERSION) endif libmapiadmin-installheader: @echo "[*] install: libmapiadmin headers" $(INSTALL) -d $(DESTDIR)$(includedir)/libmapiadmin $(INSTALL) -m 0644 libmapiadmin/libmapiadmin.h $(DESTDIR)$(includedir)/libmapiadmin/ @$(SED) $(DESTDIR)$(includedir)/libmapiadmin/*.h libmapiadmin-uninstallpc: rm -f $(DESTDIR)$(libdir)/pkgconfig/libmapiadmin.pc libmapiadmin-uninstalllib: rm -f $(DESTDIR)$(libdir)/libmapiadmin.* libmapiadmin-uninstallheader: rm -rf $(DESTDIR)$(includedir)/libmapiadmin libmapiadmin.$(SHLIBEXT).$(PACKAGE_VERSION): \ libmapiadmin/mapiadmin_user.po \ libmapiadmin/mapiadmin.po \ libmapi.$(SHLIBEXT).$(PACKAGE_VERSION) @echo "Linking $@" @$(CC) $(DSOOPT) $(LDFLAGS) -Wl,-soname,libmapiadmin.$(SHLIBEXT).$(LIBMAPIADMIN_SO_VERSION) -o $@ $^ $(LIBS) $(LIBMAPIADMIN_LIBS) ################################################################# # libocpf compilation rules ################################################################# LIBOCPF_SO_VERSION = 0 libocpf: libocpf.$(SHLIBEXT).$(PACKAGE_VERSION) libocpf-install: libocpf-installpc \ libocpf-installlib \ libocpf-installheader libocpf-uninstall: libocpf-uninstallpc \ libocpf-uninstalllib \ libocpf-uninstallheader libocpf-clean:: rm -f libocpf/*.o libocpf/*.po rm -f libocpf/*.gcno libocpf/*.gcda ifneq ($(SNAPSHOT), no) rm -f libocpf/lex.yy.c rm -f libocpf/ocpf.tab.c libocpf/ocpf.tab.h endif rm -f libocpf.$(SHLIBEXT).$(PACKAGE_VERSION) libocpf.$(SHLIBEXT).* \ libocpf.$(SHLIBEXT) clean:: libocpf-clean libocpf-distclean:: rm -f libocpf.pc distclean:: libocpf-distclean libocpf-installpc: @echo "[*] install: libocpf pc files" $(INSTALL) -d $(DESTDIR)$(libdir)/pkgconfig $(INSTALL) -m 0644 libocpf.pc $(DESTDIR)$(libdir)/pkgconfig libocpf-installlib: @echo "[*] install: libocpf library" $(INSTALL) -d $(DESTDIR)$(libdir) $(INSTALL) -m 0755 libocpf.$(SHLIBEXT).$(PACKAGE_VERSION) $(DESTDIR)$(libdir) ln -sf libocpf.$(SHLIBEXT).$(PACKAGE_VERSION) $(DESTDIR)$(libdir)/libocpf.$(SHLIBEXT) ifeq ($(MANUALLY_CREATE_SYMLINKS), yes) ln -sf libocpf.$(SHLIBEXT).$(PACKAGE_VERSION) $(DESTDIR)$(libdir)/libocpf.$(SHLIBEXT).$(LIBOCPF_SO_VERSION) endif libocpf-installheader: @echo "[*] install: libocpf headers" $(INSTALL) -d $(DESTDIR)$(includedir)/libocpf $(INSTALL) -m 0644 libocpf/ocpf.h $(DESTDIR)$(includedir)/libocpf/ @$(SED) $(DESTDIR)$(includedir)/libocpf/*.h libocpf-uninstallpc: rm -f $(DESTDIR)$(libdir)/pkgconfig/libocpf.pc libocpf-uninstalllib: rm -f $(DESTDIR)$(libdir)/libocpf.* libocpf-uninstallheader: rm -rf $(DESTDIR)$(includedir)/libocpf libocpf.$(SHLIBEXT).$(PACKAGE_VERSION): \ libocpf/ocpf.tab.po \ libocpf/lex.yy.po \ libocpf/ocpf_context.po \ libocpf/ocpf_public.po \ libocpf/ocpf_server.po \ libocpf/ocpf_dump.po \ libocpf/ocpf_api.po \ libocpf/ocpf_write.po \ libmapi.$(SHLIBEXT).$(PACKAGE_VERSION) @echo "Linking $@" @$(CC) $(DSOOPT) $(LDFLAGS) -Wl,-soname,libocpf.$(SHLIBEXT).$(LIBOCPF_SO_VERSION) -o $@ $^ $(LIBS) libocpf.$(SHLIBEXT).$(LIBOCPF_SO_VERSION): libocpf.$(SHLIBEXT).$(PACKAGE_VERSION) ln -fs $< $@ libocpf/lex.yy.c: libocpf/lex.l @echo "Generating $@" @$(FLEX) -t $< > $@ libocpf/ocpf.tab.c: libocpf/ocpf.y @echo "Generating $@" @$(BISON) -d $< -o $@ # Avoid warnings libocpf/lex.yy.o: CFLAGS= libocpf/ocpf.tab.o: CFLAGS= ################################################################# # mapiproxy compilation rules ################################################################# LIBMAPIPROXY_SO_VERSION = 0 LIBMAPISERVER_SO_VERSION = 0 .PHONY: mapiproxy mapiproxy: idl \ libmapiproxy \ libmapiserver \ libmapistore \ mapiproxy/dcesrv_mapiproxy.$(SHLIBEXT) \ mapiproxy-modules \ mapiproxy-servers mapiproxy-install: mapiproxy \ mapiproxy-modules-install \ mapiproxy-servers-install \ libmapiproxy-install \ libmapiserver-install \ libmapistore-installpc \ libmapistore-install $(INSTALL) -d $(DESTDIR)$(DCERPC_SERVER_MODULESDIR) $(INSTALL) -m 0755 mapiproxy/dcesrv_mapiproxy.$(SHLIBEXT) $(DESTDIR)$(DCERPC_SERVER_MODULESDIR) mapiproxy-uninstall: mapiproxy-modules-uninstall \ mapiproxy-servers-uninstall \ libmapiproxy-uninstall \ libmapiserver-uninstall \ libmapistore-uninstall rm -f $(DESTDIR)$(DCERPC_SERVER_MODULESDIR)/dcesrv_mapiproxy.* rm -f $(DESTDIR)$(libdir)/libmapiproxy.* rm -f $(DESTDIR)$(includedir)/libmapiproxy.h mapiproxy-clean:: mapiproxy-modules-clean \ mapiproxy-servers-clean \ libmapiproxy-clean \ libmapiserver-clean \ libmapistore-clean rm -f mapiproxy/*.o mapiproxy/*.po rm -f mapiproxy/*.gcno mapiproxy/*.gcda rm -f mapiproxy/dcesrv_mapiproxy.$(SHLIBEXT) clean:: mapiproxy-clean mapiproxy/dcesrv_mapiproxy.$(SHLIBEXT): mapiproxy/dcesrv_mapiproxy.po \ mapiproxy/dcesrv_mapiproxy_nspi.po \ mapiproxy/dcesrv_mapiproxy_rfr.po \ mapiproxy/dcesrv_mapiproxy_unused.po \ ndr_mapi.po \ gen_ndr/ndr_exchange.po @echo "Linking $@" @$(CC) -o $@ $(DSOOPT) $^ -L. $(LDFLAGS) $(LIBS) $(SAMBASERVER_LIBS) $(SAMDB_LIBS) -Lmapiproxy mapiproxy/libmapiproxy.$(SHLIBEXT).$(PACKAGE_VERSION) libmapi.$(SHLIBEXT).$(PACKAGE_VERSION) mapiproxy/dcesrv_mapiproxy.c: gen_ndr/ndr_exchange_s.c gen_ndr/ndr_exchange.c ############### # libmapiproxy ############### libmapiproxy: mapiproxy/libmapiproxy.$(SHLIBEXT).$(PACKAGE_VERSION) libmapiproxy-install: $(INSTALL) -m 0755 mapiproxy/libmapiproxy.$(SHLIBEXT).$(PACKAGE_VERSION) $(DESTDIR)$(libdir) ln -sf libmapiproxy.$(SHLIBEXT).$(PACKAGE_VERSION) $(DESTDIR)$(libdir)/libmapiproxy.$(SHLIBEXT) ifeq ($(MANUALLY_CREATE_SYMLINKS), yes) ln -sf libmapiproxy.$(SHLIBEXT).$(PACKAGE_VERSION) $(DESTDIR)$(libdir)/libmapiproxy.$(SHLIBEXT).$(LIBMAPIPROXY_SO_VERSION) endif $(INSTALL) -m 0644 mapiproxy/libmapiproxy/libmapiproxy.h $(DESTDIR)$(includedir)/ $(INSTALL) -m 0644 mapiproxy/libmapiproxy.pc $(DESTDIR)$(libdir)/pkgconfig libmapiproxy-clean: rm -f mapiproxy/libmapiproxy/*.po mapiproxy/libmapiproxy/*.o rm -f mapiproxy/libmapiproxy/*.gcno mapiproxy/libmapiproxy/*.gcda rm -f mapiproxy/libmapiproxy.$(SHLIBEXT).* libmapiproxy-uninstall: rm -f $(DESTDIR)$(libdir)/libmapiproxy.* rm -f $(DESTDIR)$(includedir)/libmapiproxy.h rm -f $(DESTDIR)$(libdir)/pkgconfig/libmapiproxy.pc libmapiproxy-distclean: rm -f mapiproxy/libmapiproxy.pc distclean::libmapiproxy-distclean mapiproxy/libmapiproxy/modules.o mapiproxy/libmapiproxy/modules.po: CFLAGS+=-DMODULESDIR=\"${modulesdir}\" mapiproxy/libmapiproxy.$(SHLIBEXT).$(PACKAGE_VERSION): mapiproxy/libmapiproxy/dcesrv_mapiproxy_module.po \ mapiproxy/libmapiproxy/dcesrv_mapiproxy_server.po \ mapiproxy/libmapiproxy/dcesrv_mapiproxy_session.po \ mapiproxy/libmapiproxy/openchangedb.po \ mapiproxy/libmapiproxy/openchangedb_table.po \ mapiproxy/libmapiproxy/openchangedb_message.po \ mapiproxy/libmapiproxy/openchangedb_property.po \ mapiproxy/libmapiproxy/mapi_handles.po \ mapiproxy/libmapiproxy/entryid.po \ mapiproxy/libmapiproxy/modules.po \ libmapi.$(SHLIBEXT).$(PACKAGE_VERSION) @echo "Linking $@" @$(CC) -o $@ $(DSOOPT) $(LDFLAGS) -Wl,-soname,libmapiproxy.$(SHLIBEXT).$(LIBMAPIPROXY_SO_VERSION) $^ -L. $(LIBS) $(TDB_LIBS) $(DL_LIBS) mapiproxy/libmapiproxy.$(SHLIBEXT).$(LIBMAPIPROXY_SO_VERSION): libmapiproxy.$(SHLIBEXT).$(PACKAGE_VERSION) ln -fs $< $@ ################# # libmapiserver ################# libmapiserver: mapiproxy/libmapiserver.$(SHLIBEXT).$(PACKAGE_VERSION) libmapiserver-install: $(INSTALL) -m 0755 mapiproxy/libmapiserver.$(SHLIBEXT).$(PACKAGE_VERSION) $(DESTDIR)$(libdir) ln -sf libmapiserver.$(SHLIBEXT).$(PACKAGE_VERSION) $(DESTDIR)$(libdir)/libmapiserver.$(SHLIBEXT) ifeq ($(MANUALLY_CREATE_SYMLINKS), yes) ln -sf libmapiserver.$(SHLIBEXT).$(PACKAGE_VERSION) $(DESTDIR)$(libdir)/libmapiserver.$(SHLIBEXT).$(LIBMAPISERVER_SO_VERSION) endif $(INSTALL) -m 0644 mapiproxy/libmapiserver/libmapiserver.h $(DESTDIR)$(includedir)/ $(INSTALL) -m 0644 mapiproxy/libmapiserver.pc $(DESTDIR)$(libdir)/pkgconfig @$(SED) $(DESTDIR)$(includedir)/*.h libmapiserver-clean: rm -f mapiproxy/libmapiserver/*.po mapiproxy/libmapiserver/*.o rm -f mapiproxy/libmapiserver/*.gcno mapiproxy/libmapiserver/*.gcda rm -f mapiproxy/libmapiserver.$(SHLIBEXT).* libmapiserver-uninstall: rm -f $(DESTDIR)$(libdir)/libmapiserver.* rm -f $(DESTDIR)$(includedir)/libmapiserver.h rm -f $(DESTDIR)$(libdir)/pkgconfig/libmapiserver.pc libmapiserver-distclean: rm -f mapiproxy/libmapiserver.pc distclean:: libmapiserver-distclean mapiproxy/libmapiserver.$(SHLIBEXT).$(PACKAGE_VERSION): mapiproxy/libmapiserver/libmapiserver_oxcstor.po \ mapiproxy/libmapiserver/libmapiserver_oxcprpt.po \ mapiproxy/libmapiserver/libmapiserver_oxcfold.po \ mapiproxy/libmapiserver/libmapiserver_oxcfxics.po \ mapiproxy/libmapiserver/libmapiserver_oxctabl.po \ mapiproxy/libmapiserver/libmapiserver_oxcmsg.po \ mapiproxy/libmapiserver/libmapiserver_oxcnotif.po \ mapiproxy/libmapiserver/libmapiserver_oxomsg.po \ mapiproxy/libmapiserver/libmapiserver_oxorule.po \ mapiproxy/libmapiserver/libmapiserver_oxcperm.po \ mapiproxy/libmapiserver/libmapiserver_oxcdata.po \ ndr_mapi.po \ gen_ndr/ndr_exchange.po @echo "Linking $@" @$(CC) -o $@ $(DSOOPT) $(LDFLAGS) -Wl,-soname,libmapiserver.$(SHLIBEXT).$(LIBMAPIPROXY_SO_VERSION) $^ $(LIBS) mapiproxy/libmapiserver.$(SHLIBEXT).$(LIBMAPISERVER_SO_VERSION): libmapiserver.$(SHLIBEXT).$(PACKAGE_VERSION) ln -fs $< $@ ################ # libmapistore ################ LIBMAPISTORE_SO_VERSION = 0 mapiproxy/libmapistore/mgmt/mapistore_mgmt.idl: mapiproxy/libmapistore/mgmt/gen_ndr mapiproxy/libmapistore/mgmt/gen_ndr/%.h: mapiproxy/libmapistore/mgmt/mapistore_mgmt.idl @echo "Generating $@" @$(PIDL) --outputdir=mapiproxy/libmapistore/mgmt/gen_ndr --header -- $< mapiproxy/libmapistore/mgmt/gen_ndr: @echo "Creating gen_ndr directory for libmapistore mgmt IDL" @mkdir -p mapiproxy/libmapistore/mgmt/gen_ndr mapiproxy/libmapistore/mgmt/gen_ndr/ndr_%.h mapiproxy/libmapistore/mgmt/gen_ndr/ndr_%.c: mapiproxy/libmapistore/mgmt/%.idl mapiproxy/libmapistore/mgmt/gen_ndr/%.h @echo "Generating $@" @$(PIDL) --outputdir=mapiproxy/libmapistore/mgmt/gen_ndr --ndr-parser -- $< libmapistore: mapiproxy/libmapistore/mapistore_nameid.h \ mapiproxy/libmapistore.$(SHLIBEXT).$(PACKAGE_VERSION) \ setup/mapistore/mapistore_namedprops.ldif \ $(OC_MAPISTORE) \ $(MAPISTORE_TEST) mapiproxy/libmapistore/mapistore_nameid.h: libmapi/conf/mparse.pl libmapi/conf/mapi-named-properties libmapi/conf/mparse.pl --parser=mapistore_nameid --outputdir=mapiproxy/libmapistore/ libmapi/conf/mapi-named-properties setup/mapistore/mapistore_namedprops.ldif: libmapi/conf/mparse.pl libmapi/conf/mapi-named-properties -mkdir --parent "setup/mapistore" libmapi/conf/mparse.pl --parser=mapistore_namedprops --outputdir=setup/mapistore/ libmapi/conf/mapi-named-properties libmapistore-installpc: @echo "[*] install: libmapistore pc files" $(INSTALL) -d $(DESTDIR)$(libdir)/pkgconfig $(INSTALL) -m 0644 mapiproxy/libmapistore.pc $(DESTDIR)$(libdir)/pkgconfig libmapistore-install: $(OC_MAPISTORE_INSTALL) $(INSTALL) -m 0755 mapiproxy/libmapistore.$(SHLIBEXT).$(PACKAGE_VERSION) $(DESTDIR)$(libdir) ln -sf libmapistore.$(SHLIBEXT).$(PACKAGE_VERSION) $(DESTDIR)$(libdir)/libmapistore.$(SHLIBEXT) ifeq ($(MANUALLY_CREATE_SYMLINKS), yes) ln -sf libmapistore.$(SHLIBEXT).$(PACKAGE_VERSION) $(DESTDIR)$(libdir)/libmapistore.$(SHLIBEXT).$(LIBMAPISTORE_SO_VERSION) endif $(INSTALL) -d $(DESTDIR)$(includedir)/mapistore $(INSTALL) -m 0644 mapiproxy/libmapistore/mapistore.h $(DESTDIR)$(includedir)/mapistore/ $(INSTALL) -m 0644 mapiproxy/libmapistore/mapistore_errors.h $(DESTDIR)$(includedir)/mapistore/ $(INSTALL) -m 0644 mapiproxy/libmapistore/mapistore_nameid.h $(DESTDIR)$(includedir)/mapistore/ $(INSTALL) -m 0644 mapiproxy/libmapiserver.pc $(DESTDIR)$(libdir)/pkgconfig $(INSTALL) -d $(DESTDIR)$(datadir)/setup/mapistore $(INSTALL) -m 0644 setup/mapistore/*.ldif $(DESTDIR)$(datadir)/setup/mapistore/ @$(SED) $(DESTDIR)$(includedir)/mapistore/*.h libmapistore-clean: $(OC_MAPISTORE_CLEAN) rm -f mapiproxy/libmapistore/*.po mapiproxy/libmapistore/*.o rm -f mapiproxy/libmapistore/mgmt/*.po mapiproxy/libmapistore/mgmt/*.o rm -f mapiproxy/libmapistore/*.gcno mapiproxy/libmapistore/*.gcda rm -f mapiproxy/libmapistore.$(SHLIBEXT).* rm -f setup/mapistore/mapistore_namedprops.ldif rm -f mapiproxy/libmapistore/mapistore_nameid.h rm -rf mapiproxy/libmapistore/mgmt/gen_ndr libmapistore-uninstall: $(OC_MAPISTORE_UNINSTALL) rm -f $(DESTDIR)$(libdir)/libmapistore.* rm -rf $(DESTDIR)$(includedir)/mapistore rm -f $(DESTDIR)$(libdir)/pkgconfig/libmapistore.pc rm -rf $(DESTDIR)$(datadir)/setup/mapistore libmapistore-distclean: libmapistore-clean rm -f mapiproxy/libmapistore.pc distclean:: libmapistore-distclean mapiproxy/libmapistore.$(SHLIBEXT).$(PACKAGE_VERSION): mapiproxy/libmapistore/mgmt/gen_ndr/ndr_mapistore_mgmt.po \ mapiproxy/libmapistore/mapistore_interface.po \ mapiproxy/libmapistore/mgmt/mapistore_mgmt.po \ mapiproxy/libmapistore/mgmt/mapistore_mgmt_messages.po \ mapiproxy/libmapistore/mgmt/mapistore_mgmt_send.po \ mapiproxy/libmapistore/mapistore_processing.po \ mapiproxy/libmapistore/mapistore_backend.po \ mapiproxy/libmapistore/mapistore_backend_defaults.po \ mapiproxy/libmapistore/mapistore_tdb_wrap.po \ mapiproxy/libmapistore/mapistore_ldb_wrap.po \ mapiproxy/libmapistore/mapistore_indexing.po \ mapiproxy/libmapistore/mapistore_replica_mapping.po \ mapiproxy/libmapistore/mapistore_namedprops.po \ mapiproxy/libmapistore/mapistore_notification.po \ libmapi.$(SHLIBEXT).$(PACKAGE_VERSION) @echo "Linking $@" @$(CC) -o $@ $(DSOOPT) $^ -L. $(LDFLAGS) $(LIBS) $(TDB_LIBS) $(DL_LIBS) -Wl,-soname,libmapistore.$(SHLIBEXT).$(LIBMAPISTORE_SO_VERSION) mapiproxy/libmapistore/mapistore_interface.po: mapiproxy/libmapistore/mapistore_nameid.h mapiproxy/libmapistore.$(SHLIBEXT).$(LIBMAPISTORE_SO_VERSION): libmapistore.$(SHLIBEXT).$(PACKAGE_VERSION) ln -fs $< $@ ##################### # mapistore backends ##################### ####################### # mapistore test tools ####################### mapistore_test: bin/mapistore_test bin/mapistore_test: mapiproxy/libmapistore/tests/mapistore_test.o \ mapiproxy/libmapistore.$(SHLIBEXT).$(PACKAGE_VERSION) @echo "Linking $@" @$(CC) -o $@ $^ $(LDFLAGS) $(LIBS) -lpopt -L. libmapi.$(SHLIBEXT).$(PACKAGE_VERSION) mapistore_clean: rm -f mapiproxy/libmapistore/tests/*.o rm -f mapiproxy/libmapistore/tests/*.gcno rm -f mapiproxy/libmapistore/tests/*.gcda rm -f bin/mapistore_test clean:: mapistore_clean #################### # mapiproxy modules #################### mapiproxy-modules: mapiproxy/modules/mpm_downgrade.$(SHLIBEXT) \ mapiproxy/modules/mpm_pack.$(SHLIBEXT) \ mapiproxy/modules/mpm_cache.$(SHLIBEXT) \ mapiproxy/modules/mpm_dummy.$(SHLIBEXT) mapiproxy-modules-install: mapiproxy-modules $(INSTALL) -d $(DESTDIR)$(modulesdir)/dcerpc_mapiproxy/ $(INSTALL) -m 0755 mapiproxy/modules/mpm_downgrade.$(SHLIBEXT) $(DESTDIR)$(modulesdir)/dcerpc_mapiproxy/ $(INSTALL) -m 0755 mapiproxy/modules/mpm_pack.$(SHLIBEXT) $(DESTDIR)$(modulesdir)/dcerpc_mapiproxy/ $(INSTALL) -m 0755 mapiproxy/modules/mpm_cache.$(SHLIBEXT) $(DESTDIR)$(modulesdir)/dcerpc_mapiproxy/ $(INSTALL) -m 0755 mapiproxy/modules/mpm_dummy.$(SHLIBEXT) $(DESTDIR)$(modulesdir)/dcerpc_mapiproxy/ mapiproxy-modules-uninstall: rm -rf $(DESTDIR)$(modulesdir)/dcerpc_mapiproxy mapiproxy-modules-clean:: rm -f mapiproxy/modules/*.o mapiproxy/modules/*.po rm -f mapiproxy/modules/*.gcno mapiproxy/modules/*.gcda rm -f mapiproxy/modules/*.so clean:: mapiproxy-modules-clean mapiproxy/modules/mpm_downgrade.$(SHLIBEXT): mapiproxy/modules/mpm_downgrade.po @echo "Linking $@" @$(CC) -o $@ $(DSOOPT) $(LDFLAGS) $^ -L. $(LIBS) -Lmapiproxy mapiproxy/libmapiproxy.$(SHLIBEXT).$(PACKAGE_VERSION) mapiproxy/modules/mpm_pack.$(SHLIBEXT): mapiproxy/modules/mpm_pack.po \ ndr_mapi.po \ gen_ndr/ndr_exchange.po @echo "Linking $@" @$(CC) -o $@ $(DSOOPT) $(LDFLAGS) $^ -L. $(LIBS) -Lmapiproxy mapiproxy/libmapiproxy.$(SHLIBEXT).$(PACKAGE_VERSION) mapiproxy/modules/mpm_cache.$(SHLIBEXT): mapiproxy/modules/mpm_cache.po \ mapiproxy/modules/mpm_cache_ldb.po \ mapiproxy/modules/mpm_cache_stream.po \ ndr_mapi.po \ gen_ndr/ndr_exchange.po @echo "Linking $@" @$(CC) -o $@ $(DSOOPT) $(LDFLAGS) $^ -L. $(LIBS) -Lmapiproxy mapiproxy/libmapiproxy.$(SHLIBEXT).$(PACKAGE_VERSION) mapiproxy/modules/mpm_dummy.$(SHLIBEXT): mapiproxy/modules/mpm_dummy.po @echo "Linking $@" @$(CC) -o $@ $(DSOOPT) $(LDFLAGS) $^ -L. $(LIBS) -Lmapiproxy mapiproxy/libmapiproxy.$(SHLIBEXT).$(PACKAGE_VERSION) samba_setupdir = $(shell $(PYTHON) -c 'import samba; print samba.param.setup_dir();') #################### # mapiproxy servers #################### provision-install: python-install $(INSTALL) -d $(DESTDIR)$(sbindir) $(INSTALL) -m 0755 setup/openchange_provision $(DESTDIR)$(sbindir)/ $(INSTALL) -m 0755 setup/openchange_newuser $(DESTDIR)$(sbindir)/ $(INSTALL) -d $(DESTDIR)$(samba_setupdir)/AD $(INSTALL) -m 0644 setup/AD/oc_provision* $(DESTDIR)$(samba_setupdir)/AD/ $(INSTALL) -m 0644 setup/AD/prefixMap.txt $(DESTDIR)$(samba_setupdir)/AD/ $(INSTALL) -m 0644 setup/AD/provision_schema_basedn_modify.ldif $(DESTDIR)$(samba_setupdir)/AD/ $(INSTALL) -d $(DESTDIR)$(datadir)/setup $(INSTALL) -d $(DESTDIR)$(datadir)/setup/openchangedb $(INSTALL) -m 0644 setup/openchangedb/oc_provision* $(DESTDIR)$(datadir)/setup/openchangedb/ provision-uninstall: python-uninstall rm -f $(DESTDIR)$(samba_setupdir)/AD/oc_provision_configuration.ldif rm -f $(DESTDIR)$(samba_setupdir)/AD/oc_provision_schema.ldif rm -f $(DESTDIR)$(samba_setupdir)/AD/oc_provision_schema_modify.ldif rm -f $(DESTDIR)$(samba_setupdir)/AD/oc_provision_schema_ADSC.ldif rm -f $(DESTDIR)$(samba_setupdir)/AD/prefixMap.txt rm -rf $(DESTDIR)$(datadir)/setup/AD rm -rf $(DESTDIR)$(datadir)/setup/openchangedb mapiproxy-servers: mapiproxy/servers/exchange_nsp.$(SHLIBEXT) \ mapiproxy/servers/exchange_emsmdb.$(SHLIBEXT) \ mapiproxy/servers/exchange_ds_rfr.$(SHLIBEXT) mapiproxy-servers-install: mapiproxy-servers provision-install $(INSTALL) -d $(DESTDIR)$(modulesdir)/dcerpc_mapiproxy_server/ $(INSTALL) -m 0755 mapiproxy/servers/exchange_nsp.$(SHLIBEXT) $(DESTDIR)$(modulesdir)/dcerpc_mapiproxy_server/ $(INSTALL) -m 0755 mapiproxy/servers/exchange_emsmdb.$(SHLIBEXT) $(DESTDIR)$(modulesdir)/dcerpc_mapiproxy_server/ $(INSTALL) -m 0755 mapiproxy/servers/exchange_ds_rfr.$(SHLIBEXT) $(DESTDIR)$(modulesdir)/dcerpc_mapiproxy_server/ mapiproxy-servers-uninstall: provision-uninstall rm -rf $(DESTDIR)$(modulesdir)/dcerpc_mapiproxy_server mapiproxy-servers-clean:: rm -f mapiproxy/servers/default/nspi/*.o mapiproxy/servers/default/nspi/*.po rm -f mapiproxy/servers/default/nspi/*.gcno mapiproxy/servers/default/nspi/*.gcda rm -f mapiproxy/servers/default/emsmdb/*.o mapiproxy/servers/default/emsmdb/*.po rm -f mapiproxy/servers/default/emsmdb/*.gcno mapiproxy/servers/default/emsmdb/*.gcda rm -f mapiproxy/servers/default/rfr/*.o mapiproxy/servers/default/rfr/*.po rm -f mapiproxy/servers/default/rfr/*.gcno mapiproxy/servers/default/rfr/*.gcda rm -f mapiproxy/servers/*.so clean:: mapiproxy-servers-clean mapiproxy/servers/exchange_nsp.$(SHLIBEXT): mapiproxy/servers/default/nspi/dcesrv_exchange_nsp.po \ mapiproxy/servers/default/nspi/emsabp.po \ mapiproxy/servers/default/nspi/emsabp_tdb.po \ mapiproxy/servers/default/nspi/emsabp_property.po @echo "Linking $@" @$(CC) -o $@ $(DSOOPT) $(LDFLAGS) $^ -L. $(LIBS) $(TDB_LIBS) $(SAMBASERVER_LIBS) $(SAMDB_LIBS) -Lmapiproxy mapiproxy/libmapiproxy.$(SHLIBEXT).$(PACKAGE_VERSION) mapiproxy/servers/exchange_emsmdb.$(SHLIBEXT): mapiproxy/servers/default/emsmdb/dcesrv_exchange_emsmdb.po \ mapiproxy/servers/default/emsmdb/emsmdbp.po \ mapiproxy/servers/default/emsmdb/emsmdbp_object.po \ mapiproxy/servers/default/emsmdb/emsmdbp_provisioning.po \ mapiproxy/servers/default/emsmdb/oxcstor.po \ mapiproxy/servers/default/emsmdb/oxcprpt.po \ mapiproxy/servers/default/emsmdb/oxcfold.po \ mapiproxy/servers/default/emsmdb/oxcfxics.po \ mapiproxy/servers/default/emsmdb/oxctabl.po \ mapiproxy/servers/default/emsmdb/oxcmsg.po \ mapiproxy/servers/default/emsmdb/oxcnotif.po \ mapiproxy/servers/default/emsmdb/oxomsg.po \ mapiproxy/servers/default/emsmdb/oxorule.po \ mapiproxy/servers/default/emsmdb/oxcperm.po @echo "Linking $@" @$(CC) -o $@ $(DSOOPT) $(LDFLAGS) $^ -L. $(LIBS) $(SAMBASERVER_LIBS) $(SAMDB_LIBS) -Lmapiproxy mapiproxy/libmapiproxy.$(SHLIBEXT).$(PACKAGE_VERSION) \ mapiproxy/libmapiserver.$(SHLIBEXT).$(PACKAGE_VERSION) \ mapiproxy/libmapistore.$(SHLIBEXT).$(PACKAGE_VERSION) mapiproxy/servers/exchange_ds_rfr.$(SHLIBEXT): mapiproxy/servers/default/rfr/dcesrv_exchange_ds_rfr.po @echo "Linking $@" @$(CC) -o $@ $(DSOOPT) $(LDFLAGS) $^ -L. $(LIBS) $(SAMBASERVER_LIBS) $(SAMDB_LIBS) -Lmapiproxy mapiproxy/libmapiproxy.$(SHLIBEXT).$(PACKAGE_VERSION) ################################################################# # Tools compilation rules ################################################################# ################### # openchangeclient ################### openchangeclient: bin/openchangeclient openchangeclient-install: openchangeclient $(INSTALL) -d $(DESTDIR)$(bindir) $(INSTALL) -m 0755 bin/openchangeclient $(DESTDIR)$(bindir) openchangeclient-uninstall: rm -f $(DESTDIR)$(bindir)/openchangeclient openchangeclient-clean:: rm -f bin/openchangeclient rm -f utils/openchangeclient.o rm -f utils/openchangeclient.gcno rm -f utils/openchangeclient.gcda rm -f utils/openchange-tools.o rm -f utils/openchange-tools.gcno rm -f utils/openchange-tools.gcda clean:: openchangeclient-clean bin/openchangeclient: utils/openchangeclient.o \ utils/openchange-tools.o \ libmapi.$(SHLIBEXT).$(PACKAGE_VERSION) \ libocpf.$(SHLIBEXT).$(PACKAGE_VERSION) @echo "Linking $@" @$(CC) $(CFLAGS) -o $@ $^ $(LDFLAGS) $(LIBS) -lpopt ############## # mapiprofile ############## mapiprofile: bin/mapiprofile mapiprofile-install: mapiprofile $(INSTALL) -d $(DESTDIR)$(bindir) $(INSTALL) -m 0755 bin/mapiprofile $(DESTDIR)$(bindir) mapiprofile-uninstall: rm -f $(DESTDIR)$(bindir)/mapiprofile mapiprofile-clean:: rm -f bin/mapiprofile rm -f utils/mapiprofile.o rm -f utils/mapiprofile.gcno rm -f utils/mapiprofile.gcda clean:: mapiprofile-clean bin/mapiprofile: utils/mapiprofile.o \ utils/openchange-tools.o \ libmapi.$(SHLIBEXT).$(PACKAGE_VERSION) @echo "Linking $@" @$(CC) $(CFLAGS) -o $@ $^ $(LDFLAGS) $(LIBS) -lpopt ################### #openchangepfadmin ################### openchangepfadmin: bin/openchangepfadmin openchangepfadmin-install: openchangepfadmin $(INSTALL) -d $(DESTDIR)$(bindir) $(INSTALL) -m 0755 bin/openchangepfadmin $(DESTDIR)$(bindir) openchangepfadmin-uninstall: rm -f $(DESTDIR)$(bindir)/openchangepfadmin openchangepfadmin-clean:: rm -f bin/openchangepfadmin rm -f utils/openchangepfadmin.o rm -f utils/openchangepfadmin.gcno rm -f utils/openchangepfadmin.gcda clean:: openchangepfadmin-clean bin/openchangepfadmin: utils/openchangepfadmin.o \ utils/openchange-tools.o \ libmapi.$(SHLIBEXT).$(PACKAGE_VERSION) \ libmapiadmin.$(SHLIBEXT).$(PACKAGE_VERSION) @echo "Linking $@" @$(CC) -o $@ $^ $(LDFLAGS) $(LIBS) $(LIBMAPIADMIN_LIBS) -lpopt ################### # exchange2mbox ################### exchange2mbox: bin/exchange2mbox exchange2mbox-install: exchange2mbox $(INSTALL) -d $(DESTDIR)$(bindir) $(INSTALL) -m 0755 bin/exchange2mbox $(DESTDIR)$(bindir) exchange2mbox-uninstall: rm -f $(DESTDIR)$(bindir)/exchange2mbox exchange2mbox-clean:: rm -f bin/exchange2mbox rm -f utils/exchange2mbox.o rm -f utils/exchange2mbox.gcno rm -f utils/exchange2mbox.gcda rm -f utils/openchange-tools.o rm -f utils/openchange-tools.gcno rm -f utils/openchange-tools.gcda clean:: exchange2mbox-clean bin/exchange2mbox: utils/exchange2mbox.o \ utils/openchange-tools.o \ libmapi.$(SHLIBEXT).$(PACKAGE_VERSION) @echo "Linking $@" @$(CC) -o $@ $^ $(LIBS) $(LDFLAGS) -lpopt $(MAGIC_LIBS) ################### # exchange2ical ################### exchange2ical: bin/exchange2ical exchange2ical-install: exchange2ical $(INSTALL) -d $(DESTDIR)$(bindir) $(INSTALL) -m 0755 bin/exchange2ical $(DESTDIR)$(bindir) exchange2ical-uninstall: rm -f $(DESTDIR)$(bindir)/exchange2ical exchange2ical-clean:: rm -f bin/exchange2ical rm -f utils/exchange2ical_tool.o rm -f utils/exchange2ical_tool.gcno rm -f utils/exchange2ical_tool.gcda rm -f libexchange2ical/libexchange2ical.o rm -f libexchange2ical/libexchange2ical.gcno rm -f libexchange2ical/libexchange2ical.gcda rm -f libexchange2ical/exchange2ical.o rm -f libexchange2ical/exchange2ical.gcno rm -f libexchange2ical/exchange2ical.gcda rm -f libexchange2ical/exchange2ical_utils.o rm -f libexchange2ical/exchange2ical_utils.gcno rm -f libexchange2ical/exchange2ical_utils.gcda rm -f libexchange2ical/exchange2ical_component.o rm -f libexchange2ical/exchange2ical_component.gcno rm -f libexchange2ical/exchange2ical_component.gcda rm -f libexchange2ical/exchange2ical_property.o rm -f libexchange2ical/exchange2ical_property.gcno rm -f libexchange2ical/exchange2ical_property.gcda rm -f libexchange2ical/libical2exchange.o rm -f libexchange2ical/libical2exchange.gcno rm -f libexchange2ical/libical2exchange.gcda rm -f libexchange2ical/ical2exchange.o rm -f libexchange2ical/ical2exchange.gcno rm -f libexchange2ical/ical2exchange.gcda rm -f libexchange2ical/ical2exchange_property.o rm -f libexchange2ical/ical2exchange_property.gcno rm -f libexchange2ical/ical2exchange_property.gcda rm -f libexchange2ical/openchange-tools.o rm -f libexchange2ical/openchange-tools.gcno rm -f libexchange2ical/openchange-tools.gcda clean:: exchange2ical-clean bin/exchange2ical: utils/exchange2ical_tool.o \ libexchange2ical/libexchange2ical.o \ libexchange2ical/exchange2ical.o \ libexchange2ical/exchange2ical_component.o \ libexchange2ical/exchange2ical_property.o \ libexchange2ical/exchange2ical_utils.o \ libexchange2ical/libical2exchange.o \ libexchange2ical/ical2exchange.o \ libexchange2ical/ical2exchange_property.o \ utils/openchange-tools.o \ libmapi.$(SHLIBEXT).$(PACKAGE_VERSION) @echo "Linking $@" @$(CC) $(LDFLAGS) -o $@ $^ $(LIBS) $(ICAL_LIBS) -lpopt ################### # mapitest ################### mapitest: libmapi \ utils/mapitest/proto.h \ bin/mapitest mapitest-install: mapitest $(INSTALL) -d $(DESTDIR)$(bindir) $(INSTALL) -m 0755 bin/mapitest $(DESTDIR)$(bindir) $(INSTALL) -d $(DESTDIR)$(datadir)/mapitest/lzxpress $(INSTALL) -d $(DESTDIR)$(datadir)/mapitest/lzfu $(INSTALL) -m 0644 utils/mapitest/data/lzxpress/* $(DESTDIR)$(datadir)/mapitest/lzxpress/ $(INSTALL) -m 0644 utils/mapitest/data/lzfu/* $(DESTDIR)$(datadir)/mapitest/lzfu/ mapitest-uninstall: rm -f $(DESTDIR)$(bindir)/mapitest rm -rf $(DESTDIR)$(datadir)/mapitest mapitest-clean: rm -f bin/mapitest rm -f utils/mapitest/*.o rm -f utils/mapitest/*.gcno rm -f utils/mapitest/*.gcda rm -f utils/mapitest/modules/*.o rm -f utils/mapitest/modules/*.gcno rm -f utils/mapitest/modules/*.gcda ifneq ($(SNAPSHOT), no) rm -f utils/mapitest/proto.h rm -f utils/mapitest/mapitest_proto.h endif clean:: mapitest-clean bin/mapitest: utils/mapitest/mapitest.o \ utils/openchange-tools.o \ utils/mapitest/mapitest_suite.o \ utils/mapitest/mapitest_print.o \ utils/mapitest/mapitest_stat.o \ utils/mapitest/mapitest_common.o \ utils/mapitest/module.o \ utils/mapitest/modules/module_oxcstor.o \ utils/mapitest/modules/module_oxcfold.o \ utils/mapitest/modules/module_oxcfxics.o \ utils/mapitest/modules/module_oxomsg.o \ utils/mapitest/modules/module_oxcmsg.o \ utils/mapitest/modules/module_oxcprpt.o \ utils/mapitest/modules/module_oxctable.o \ utils/mapitest/modules/module_oxorule.o \ utils/mapitest/modules/module_oxcnotif.o \ utils/mapitest/modules/module_oxcfxics.o \ utils/mapitest/modules/module_oxcperm.o \ utils/mapitest/modules/module_nspi.o \ utils/mapitest/modules/module_noserver.o \ utils/mapitest/modules/module_errorchecks.o \ utils/mapitest/modules/module_lcid.o \ utils/mapitest/modules/module_mapidump.o \ utils/mapitest/modules/module_lzxpress.o \ libmapi.$(SHLIBEXT).$(PACKAGE_VERSION) @echo "Linking $@" @$(CC) -o $@ $^ $(LDFLAGS) $(LIBS) -lpopt $(SUBUNIT_LIBS) utils/mapitest/proto.h: \ utils/mapitest/mapitest_suite.c \ utils/mapitest/mapitest_print.c \ utils/mapitest/mapitest_stat.c \ utils/mapitest/mapitest_common.c \ utils/mapitest/module.c \ utils/mapitest/modules/module_oxcstor.c \ utils/mapitest/modules/module_oxcfold.c \ utils/mapitest/modules/module_oxcfxics.c \ utils/mapitest/modules/module_oxomsg.c \ utils/mapitest/modules/module_oxcmsg.c \ utils/mapitest/modules/module_oxcprpt.c \ utils/mapitest/modules/module_oxcfxics.c \ utils/mapitest/modules/module_oxctable.c \ utils/mapitest/modules/module_oxorule.c \ utils/mapitest/modules/module_oxcnotif.c \ utils/mapitest/modules/module_oxcperm.c \ utils/mapitest/modules/module_nspi.c \ utils/mapitest/modules/module_noserver.c \ utils/mapitest/modules/module_errorchecks.c \ utils/mapitest/modules/module_lcid.c \ utils/mapitest/modules/module_mapidump.c \ utils/mapitest/modules/module_lzxpress.c @echo "Generating $@" @./script/mkproto.pl --private=utils/mapitest/mapitest_proto.h --public=utils/mapitest/proto.h $^ ##################### # openchangemapidump ##################### openchangemapidump: bin/openchangemapidump openchangemapidump-install: openchangemapidump $(INSTALL) -d $(DESTDIR)$(bindir) $(INSTALL) -m 0755 bin/openchangemapidump $(DESTDIR)$(bindir) openchangemapidump-uninstall: rm -f bin/openchangemapidump rm -f $(DESTDIR)$(bindir)/openchangemapidump openchangemapidump-clean:: rm -f bin/openchangemapidump rm -f utils/backup/openchangemapidump.o rm -f utils/backup/openchangemapidump.gcno rm -f utils/backup/openchangemapidump.gcda rm -f utils/backup/openchangebackup.o rm -f utils/backup/openchangebackup.gcno rm -f utils/backup/openchangebackup.gcda clean:: openchangemapidump-clean bin/openchangemapidump: utils/backup/openchangemapidump.o \ utils/backup/openchangebackup.o \ utils/openchange-tools.o \ libmapi.$(SHLIBEXT).$(PACKAGE_VERSION) @echo "Linking $@" @$(CC) -o $@ $^ $(LDFLAGS) $(LIBS) -lpopt ############### # schemaIDGUID ############### schemaIDGUID: bin/schemaIDGUID schemaIDGUID-install: schemaIDGUID $(INSTALL) -m 0755 bin/schemaIDGUID $(DESTDIR)$(bindir) schemaIDGUID-uninstall: rm -f $(DESTDIR)$(bindir)/schemaIDGUID schemaIDGUID-clean:: rm -f bin/schemaIDGUID rm -f utils/schemaIDGUID.o rm -f utils/schemaIDGUID.gcno rm -f utils/schemaIDGUID.gcda clean:: schemaIDGUID-clean bin/schemaIDGUID: utils/schemaIDGUID.o @echo "Linking $@" @$(CC) $(CFLAGS) -o $@ $^ $(LIBS) ################### # check_fasttransfer test app. ################### check_fasttransfer: bin/check_fasttransfer check_fasttransfer-install: check_fasttransfer $(INSTALL) -d $(DESTDIR)$(bindir) $(INSTALL) -m 0755 bin/check_fasttransfer $(DESTDIR)$(bindir) check_fasttransfer-uninstall: rm -f $(DESTDIR)$(bindir)/check_fasttransfer check_fasttransfer-clean:: rm -f bin/check_fasttransfer rm -f testprogs/check_fasttransfer.o rm -f testprogs/check_fasttransfer.gcno rm -f testprogs/check_fasttransfer.gcda clean:: check_fasttransfer-clean bin/check_fasttransfer: testprogs/check_fasttransfer.o \ libmapi.$(SHLIBEXT).$(PACKAGE_VERSION) \ mapiproxy/libmapistore.$(SHLIBEXT).$(PACKAGE_VERSION) @echo "Linking $@" @$(CC) -o $@ $^ $(LIBS) $(LDFLAGS) -lpopt ################### # test_asyncnotif test app. ################### test_asyncnotif: bin/test_asyncnotif test_asyncnotif-install: test_asyncnotif $(INSTALL) -d $(DESTDIR)$(bindir) $(INSTALL) -m 0755 bin/test_asyncnotif $(DESTDIR)$(bindir) test_asyncnotif-uninstall: rm -f $(DESTDIR)$(bindir)/test_asyncnotif test_asyncnotif-clean:: rm -f bin/test_asyncnotif rm -f testprogs/test_asyncnotif.o rm -f testprogs/test_asyncnotif.gcno rm -f testprogs/test_asyncnotif.gcda clean:: test_asyncnotif-clean bin/test_asyncnotif: testprogs/test_asyncnotif.o \ libmapi.$(SHLIBEXT).$(PACKAGE_VERSION) @echo "Linking $@" @$(CC) -o $@ $^ $(LIBS) $(LDFLAGS) -lpopt ################### # python code ################### pythonscriptdir = python PYTHON_MODULES = $(patsubst $(pythonscriptdir)/%,%,$(shell find $(pythonscriptdir) -name "*.py")) python-install:: @echo "Installing Python modules" @$(foreach MODULE, $(PYTHON_MODULES), \ $(INSTALL) -d $(DESTDIR)$(pythondir)/$(dir $(MODULE)); \ $(INSTALL) -m 0644 $(pythonscriptdir)/$(MODULE) $(DESTDIR)$(pythondir)/$(dir $(MODULE)); \ ) python-uninstall:: rm -rf $(DESTDIR)$(pythondir)/openchange EPYDOC_OPTIONS = --no-private --url http://www.openchange.org/ --no-sourcecode epydoc:: PYTHONPATH=$(pythonscriptdir):$(PYTHONPATH) epydoc $(EPYDOC_OPTIONS) openchange check-python: PYTHONPATH=$(pythonscriptdir):$(PYTHONPATH) trial openchange check:: check-python clean-python: rm -f pymapi/*.o rm -f $(pythonscriptdir)/mapi.$(SHLIBEXT) rm -f $(pythonscriptdir)/openchange/*.pyc clean:: clean-python pyopenchange: $(pythonscriptdir)/openchange/mapi.$(SHLIBEXT) \ $(pythonscriptdir)/openchange/mapistore.$(SHLIBEXT) # $(pythonscriptdir)/openchange/ocpf.$(SHLIBEXT) \ $(pythonscriptdir)/openchange/mapi.$(SHLIBEXT): pyopenchange/pymapi.c \ pyopenchange/pymapi_properties.c \ libmapi.$(SHLIBEXT).$(PACKAGE_VERSION) @echo "Linking $@" @$(CC) $(CFLAGS) -fno-strict-aliasing $(DSOOPT) $(LDFLAGS) -o $@ $^ $(PYTHON_CFLAGS) $(PYTHON_LIBS) $(LIBS) # $(pythonscriptdir)/openchange/ocpf.$(SHLIBEXT): pyopenchange/pyocpf.c \ # libocpf.$(SHLIBEXT).$(PACKAGE_VERSION) \ # libmapi.$(SHLIBEXT).$(PACKAGE_VERSION) # @echo "Linking $@" # @$(CC) $(CFLAGS) $(DSOOPT) $(LDFLAGS) -o $@ $^ $(PYTHON_CFLAGS) $(PYTHON_LIBS) $(LIBS) $(pythonscriptdir)/openchange/mapistore.$(SHLIBEXT): pyopenchange/mapistore/pymapistore.c \ pyopenchange/mapistore/mgmt.c \ pyopenchange/mapistore/context.c \ pyopenchange/mapistore/folder.c \ pyopenchange/mapistore/freebusy_properties.c \ pyopenchange/mapistore/table.c \ pyopenchange/mapistore/errors.c \ mapiproxy/libmapistore.$(SHLIBEXT).$(PACKAGE_VERSION) \ mapiproxy/libmapiproxy.$(SHLIBEXT).$(PACKAGE_VERSION) @echo "Compiling and linking $@" @$(CC) $(PYTHON_CFLAGS) $(CFLAGS) -fno-strict-aliasing $(DSOOPT) $(LDFLAGS) -o $@ $^ $(PYTHON_LIBS) $(LIBS) pyopenchange/mapistore/errors.c: pyopenchange/mapistore/gen_errors.py mapiproxy/libmapistore/mapistore_errors.h pyopenchange/mapistore/gen_errors.py mapiproxy/libmapistore/mapistore_errors.h $@ pyopenchange-clean: rm -f pyopenchange/*.o rm -f pyopenchange/*.pyc # rm -f $(pythonscriptdir)/openchange/mapi.$(SHLIBEXT) # rm -f $(pythonscriptdir)/openchange/ocpf.$(SHLIBEXT) rm -f $(pythonscriptdir)/openchange/mapistore.$(SHLIBEXT) clean:: pyopenchange-clean pyopenchange-install: $(INSTALL) -d $(DESTDIR)$(PYCDIR)/openchange $(INSTALL) -m 0755 $(pythonscriptdir)/openchange/mapi.$(SHLIBEXT) $(DESTDIR)$(PYCDIR)/openchange # $(INSTALL) -m 0755 $(pythonscriptdir)/openchange/ocpf.$(SHLIBEXT) $(DESTDIR)$(PYCDIR)/openchange $(INSTALL) -m 0755 $(pythonscriptdir)/openchange/mapistore.$(SHLIBEXT) $(DESTDIR)$(PYCDIR)/openchange pyopenchange-uninstall: rm -f $(DESTDIR)$(PYCDIR)/openchange/mapi.$(SHLIBEXT) rm -f $(DESTDIR)$(PYCDIR)/openchange/ocpf.$(SHLIBEXT) rm -f $(DESTDIR)$(PYCDIR)/openchange/mapistore.$(SHLIBEXT) ################### # nagios plugin ################### nagiosdir = $(libdir)/nagios installnagios: $(INSTALL) -d $(DESTDIR)$(nagiosdir) $(INSTALL) -m 0755 script/check_exchange $(DESTDIR)$(nagiosdir) ################### # libmapi examples ################### examples: cd doc/examples && make && cd ${OLD_PWD} examples-clean:: rm -f doc/examples/mapi_sample1 rm -f doc/examples/fetchappointment rm -f doc/examples/fetchmail clean:: examples-clean examples-install examples-uninstall: manpages = \ doc/man/man1/exchange2mbox.1 \ doc/man/man1/mapiprofile.1 \ doc/man/man1/openchangeclient.1 \ doc/man/man1/openchangepfadmin.1 \ $(wildcard apidocs/man/man3/*) installman: doxygen @./script/installman.sh $(DESTDIR)$(mandir) $(manpages) uninstallman: @./script/uninstallman.sh $(DESTDIR)$(mandir) $(manpages) doxygen: @if test ! -d apidocs ; then \ echo "Doxify API documentation: HTML and man pages"; \ mkdir -p apidocs/html; \ mkdir -p apidocs/man; \ $(DOXYGEN) Doxyfile; \ $(DOXYGEN) libmapi/Doxyfile; \ $(DOXYGEN) libmapiadmin/Doxyfile; \ $(DOXYGEN) libocpf/Doxyfile; \ $(DOXYGEN) libmapi++/Doxyfile; \ $(DOXYGEN) mapiproxy/Doxyfile; \ $(DOXYGEN) utils/mapitest/Doxyfile; \ $(DOXYGEN) mapiproxy/libmapistore/Doxyfile; \ cp -f doc/doxygen/index.html apidocs/html; \ cp -f doc/doxygen/pictures/* apidocs/html/overview; \ cp -f doc/doxygen/pictures/* apidocs/html/libmapi; \ cp -f doc/doxygen/pictures/* apidocs/html/libmapiadmin; \ cp -f doc/doxygen/pictures/* apidocs/html/libmapi++; \ cp -f doc/doxygen/pictures/* apidocs/html/libocpf; \ cp -f doc/doxygen/pictures/* apidocs/html/mapitest; \ cp -f doc/doxygen/pictures/* apidocs/html/mapiproxy; \ cp -f doc/doxygen/pictures/* apidocs/html/libmapistore; \ cp -f mapiproxy/documentation/pictures/* apidocs/html/mapiproxy;\ rm -f apidocs/man/man3/todo.3; \ rm -f apidocs/man/man3/bug.3; \ rm -f apidocs/man/man3/*.c.3; \ fi etags: etags `find $(srcdir) -name "*.[ch]"` ctags: ctags `find $(srcdir) -name "*.[ch]"` .PRECIOUS: exchange.h gen_ndr/ndr_exchange.h gen_ndr/ndr_exchange.c gen_ndr/ndr_exchange_c.c gen_ndr/ndr_exchange_c.h mapiproxy/libmapistore/mgmt/gen_ndr/ndr_mapistore_mgmt.c mapiproxy/libmapistore/mgmt/gen_ndr/mapistore_mgmt.h test:: check check:: libmapi.$(SHLIBEXT).$(LIBMAPI_SO_VERSION) # FIXME: Set up server ./bin/mapitest --mapi-calls #################################### # coverage tests # # this could be better integrated... #################################### coverage-init: lcov --base-directory . --directory . --capture --initial --output-file oc_cov.info coverage:: rm -f libmapi/\.gcov rm -f ./libocpf/lex.yy.gcda rm -f libocpf/\.gcov rm -f ./\.gcov lcov --base-directory . --directory . --output-file oc_cov.info --capture genhtml -o covresults oc_cov.info coverage-clean:: rm -rf oc_cov.info rm -rf covresults rm -f test.gcno clean:: coverage-clean #################################### # Qt4 widgets #################################### openchange_qt4: qt-lib qt-demoapp qt-lib: libqtmapi qt-demoapp: qt/demo/demoapp.moc qt/demo/demoapp # No install yet - we need to finish this first qt-clean:: rm -f qt/demo/demoapp rm -f qt/demo/*.o rm -f qt/lib/*.o rm -f qt/demo/*.moc rm -f qt/lib/*.moc rm -f libqtmapi* clean:: qt-clean qt/demo/demoapp.moc: qt/demo/demoapp.h @$(MOC) -i qt/demo/demoapp.h -o qt/demo/demoapp.moc qt/lib/foldermodel.moc: qt/lib/foldermodel.h @$(MOC) -i qt/lib/foldermodel.h -o qt/lib/foldermodel.moc qt/lib/messagesmodel.moc: qt/lib/messagesmodel.h @$(MOC) -i qt/lib/messagesmodel.h -o qt/lib/messagesmodel.moc libqtmapi: libmapi \ qt/lib/foldermodel.moc \ qt/lib/messagesmodel.moc \ libqtmapi.$(SHLIBEXT).$(PACKAGE_VERSION) LIBQTMAPI_SO_VERSION = 0 libqtmapi.$(SHLIBEXT).$(PACKAGE_VERSION): \ qt/lib/foldermodel.o \ qt/lib/messagesmodel.o @echo "Linking $@" @$(CXX) $(DSOOPT) $(CXXFLAGS) $(LDFLAGS) -Wl,-soname,libqtmapi.$(SHLIBEXT).$(LIBQTMAPI_SO_VERSION) -o $@ $^ $(LIBS) qt/demo/demoapp: qt/demo/demoapp.o \ qt/demo/main.o \ libmapi.$(SHLIBEXT).$(PACKAGE_VERSION) \ libmapipp.$(SHLIBEXT).$(PACKAGE_VERSION) \ libqtmapi.$(SHLIBEXT).$(PACKAGE_VERSION) @echo "Linking $@" @$(CXX) $(CXXFLAGS) -o $@ $^ $(QT4_LIBS) $(LDFLAGS) $(LIBS) # we don't yet install this... ln -sf libqtmapi.$(SHLIBEXT).$(PACKAGE_VERSION) libqtmapi.$(SHLIBEXT) ln -sf libqtmapi.$(SHLIBEXT).$(PACKAGE_VERSION) libqtmapi.$(SHLIBEXT).$(LIBQTMAPI_SO_VERSION) # This should be the last line in the makefile since other distclean rules may # need config.mk distclean:: rm -f config.mk openchange-2.0/README000066400000000000000000000141251223057412600143470ustar00rootroot00000000000000This is the README file for OpenChange ABOUT OPENCHANGE The OpenChange Project aims to provide a portable Open Source implementation of Microsoft Exchange Server and Exchange protocols. Exchange is a groupware server designed to work with Microsoft Outlook, and providing features such as a messaging server, shared calendars, contact databases, public folders, notes and tasks. The OpenChange project has three goals: * To provide a library for interoperability with Exchange protocols, and to assist implementers to use this to create groupware that interoperates with both Exchange and other OpenChange-based software. * To provide an alternative to Microsoft Exchange Server which uses native Exchange protocols and provides exactly equivalent functionality when viewed from Microsoft Outlook clients. * To develop a body of knowledge about the most popular groupware protocols in use commercially today in order to promote development of a documented and unencumbered standard, with all the benefits that standards bring. DOCUMENTATION There are two sources of documentation - text files in the doc/ directory, and API documentation generated from the source files using doxygen. You can create the API documentation yourself (using "make doxygen" at the top level) or you can refer to the copy on the OpenChange web site at http://apidocs.openchange.org/overview/index.html doc/howto.txt contains instructions on how to install and set up client libraries, client utilities and the server / proxy parts of OpenChange. doc/man/ contains man(1) pages for several OpenChange utilities. Note that man pages for programming (i.e. the parts that would appear in man3) are generated by doxygen, and will be found in apidocs/ if you generate the documentation yourself. doc/doxygen/ provides static content used as part of the doxygen API documentation generation process. doc/examples/ provides programming examples for libmapi. STRUCTURE - bin/ This directory is created during the build process. It contains the binaries (executable programs) that are compiled during the "make" step. The source for most of these is in the utils/ directory, described below. - doc/ This directory contains documentation - see description above (in DOCUMENTATION) for the various contents of this directory. - gen_ndr/ This directory contains routines for handling the Network Data Representation (NDR) for various Exchange RPC calls. The contents of this directory are generated (using Samba's pidl IDL compiler) at build time. The main input file is exchange.idl (see top level directory). - libexchange2ical This directory provides functionality for converting between Exchange calendar appointments and ICalendar (RFC2445 / RFC5545) format. Exchange -> ICalendar is fairly mature, ICalendar to Exchange is in work. - libmapi/ This directory contains the main client-side library, called libmapi. libmapi closely reflects the underlying protocol operations (Exchange RPC) being performed between the client and the server. For more information, consult the API documentation (either build yourself, or online at http://apidocs.openchange.org/libmapi/index.html) - libmapi++/ This directory contains C++ bindings for libmapi. It is not a replacement for libmapi, but is intended to provide easier access to many libmapi functions for C++ programmers. For more information, consult the API documentation (either build yourself, or online at http://apidocs.openchange.org/libmapi++/index.html) - libmapiadmin/ This directory contains client-side library functions for administering OpenChange or Exchange servers. For more information, consult the API documentation (either build yourself, or online at http://apidocs.openchange.org/libmapiadmin/index.html). If you are looking for a program you can run, instead of library functions to write your own program, "openchangepfadmin" might be of interest. - libocpf/ This directory contains library functions for the OpenChange Property Files (OCPF). This allows building of mail messages, address book entries, appointments and similar objects from text files. For more information, consult the API documentation (either build yourself, or online at http://apidocs.openchange.org/libocpf/index.html) - mapiproxy/ This directory provides an Exchange RPC proxy. You can use this to provide transparent proxying, or to change / monitor connections between the client and server. For more information, consult the API documentation (either build yourself, or online at http://apidocs.openchange.org/mapiproxy/index.html) - python/ This directory contains python scripts used to set up ("provision") the server side. They are not required for the client side. - qt/ This directory contains Qt4 bindings (lib/ subdirectory) and a sample application (demo/ subdirectory). The sample application is intended for research and development use, not as a complete end-user application. - samba4/ This directory will be created during the build process if you call "make samba" or execute the ./script/installsamba4.sh script. It is used to build samba4, if required. - script/ This directory contains a range of scripts useful for development or use of OpenChange. [TODO: document the scripts - perhaps write script/README?] - setup/ This directory contains data for setting up ("provisioning") the server. - testprogs/ This directory contains developer test tools - utils/ This directory contains the source code for a range of applications / utilities that can be used to interact with an exchange server. They include: - utils/backup/ backup and restore tools - utils/exchange2ical converts Exchange calendar into an ICal file - utils/exchange2mbox two way conversion between Exchange mail and mbox - utils/mapiprofile set up client side profiles (login information) - utils/mapitest/ test tools for libmapi functionality - utils/mapitrace/ test tool for tracing MAPI calls - utils/openchangeclient command line client for Exchange RPC - utils/openchangepfadmin Public Folders admin tools and administration of Exchange users (add/del) - utils/schemaIDGUID For more information on these tools, refer to the man(1) pages in doc/man/man1 openchange-2.0/VERSION000066400000000000000000000035501223057412600145370ustar00rootroot00000000000000######################################################## # OPENCHANGE Version # # # # script/mkversion.sh # # will use this file to create # # libmapi/version.h # # # ######################################################## ######################################################## # To mark SVN snapshots this should be set to 'yes' # # in the development BRANCH, and set to 'no' only in # # the release BRANCH # # # # .[...]-SVN-build-xxx # # # # e.g. OPENCHANGE_VERSION_IS_SVN_SNAPSHOT=yes # # -> "0.7-SVN-build-199" # ######################################################## OPENCHANGE_VERSION_IS_SVN_SNAPSHOT=no ############################################################# # This is for specifying a release nickname # # # # e.g. OPENCHANGE_VERSION_RELEASE_NICKNAME=Nicky Nickname # # -> "0.7 (Nicky Nickname)" # ############################################################# OPENCHANGE_VERSION_RELEASE_NICKNAME=Quadrant ############################################################# # This is for specifying a release number # # # # e.g. OPENCHANGE_VERSION_RELEASE_VERSION=0.8.2 # # -> "0.8.2 (Nicky Nickname)" # ############################################################# OPENCHANGE_VERSION_RELEASE_NUMBER=2.0 openchange-2.0/apidocs/000077500000000000000000000000001223057412600151065ustar00rootroot00000000000000openchange-2.0/apidocs/html/000077500000000000000000000000001223057412600160525ustar00rootroot00000000000000openchange-2.0/apidocs/html/index.html000066400000000000000000000005411223057412600200470ustar00rootroot00000000000000 OpenChange API Documentation

Redirecting you to the OpenChange API documentation overview.

openchange-2.0/apidocs/html/libmapi++/000077500000000000000000000000001223057412600176155ustar00rootroot00000000000000openchange-2.0/apidocs/html/libmapi++/24px-Cc-by_white.svg.png000066400000000000000000000053061223057412600240550ustar00rootroot00000000000000‰PNG  IHDR°çá»bKGDÿÿÿÿÿÿ X÷Ü pHYsHHFÉk> IDATXýXmP”U¾vˆeY pW$gQH–%ãËc*$åÃIkFmiØ‘ttrê‡C öa3 Œc†D$ e¬±X, «@³ Â.Èîõþy›uÓ÷·÷úóÌœçÜϹîëºçÜç<þxHØNÛNÛN½+zWô®.–_,¿X|»æÛ5ß® Q†(C`4F#p×ý®û]w@qRqRqðÿÎÿ;ÿcaÇÂŽIÅIÅIÅ@˜$L&Ämâ6qÛòÀ‡Ä-í-í--ùVë[­oµ’ <. … ¡B¨øSRT(*’’IŽ$‡”æHs¤9¤S’S’S‰ð>°Ï÷ˆôˆôˆ$Óôiú4=Ù2Ú2Ú2JZ•V¥Uù`^‚û9À3<Ã3À7ýßôÓl?Ø~°¸ªºªºªœ‡œ‡œ‡€ 6Øpx&õ™ÔgR0—0—0ÀMá¦pSB©P*”–õ–õ–õ@²GÙ£šª›ª›ª¦mMÛš¶#êõˆðj÷j÷jöeïËÞ— äÎäÎäÎÒ^i¯´÷að£ýȳégÓϦ“K{–ö,í±+¦êRu©ºÈŠÎŠÎŠNòöÔí©ÛSë£sñsñsñd{^{^{™u%ëJÖÒÅÛÅÛÅ›IER‘”ÔìÕìÕì%ÇSÇSÇS~gAuuu¤|µ|µ|5)øJð•à+rGËŽ–-äÀ±cÇþs‚å)ËS–§ÈÒ-¥[J·ž»=w{î&µ‚ZA-™÷BÞ y/³£³£³£‹$psäæÈÍR•¨JT%ÚßñýŽïw|OšÌ&³Éü¿'þWX­ÖFòÔ“§ž<õ$é6â6â6Bºæ»æ»æ“ÕÕÕ÷&°Ÿû¹Ÿ<”p(áP‚xxQxQxyëÀ­·üóÄÿŠùçœÿ‘Ô®Ô®Ô®´óŠx.⹈çÈÁÎÁÎÁN7ŽÜ8rã¹æÙ5Ï®y–tŠwŠwŠ'+++ÿÿÄÿŠã€qÀH¿üzðë¤(H$ "‹4Eš" ) ø0àÀ:³ñÌÆ3··7à é é  pNwNwN¦º¦º¦º€ZS­©Ö\K¹–r-èÎíÎíΆg†g†gOgOgOgÀ˜bL1¦õâzq½XÒ·¤oI SÊ”2%033TÿQýGõ€h§h§h'àëëkßdÜÜÝÜÝ܉sç&Î õ õ õÀ¸iÜ4n°uÕÖU[WÙ-*4š ©õ^^^r¹Ãr‡å¤S•S•SéêêJºMºMºM’»rwåîÊ%ûûûIE¤"RIîÙ¼góžÍäÜÆ¹sÉý'öŸØ‚”'Êå‰dÛ–¶-m[îï„N£Óè4¤ÇÛo{¼MŠä"¹HN {]z]z]Ñ:Ñ:Ñ:@¥T)UÊE¶Û!q¸k¾k¾k2e™²LÐÛÛ ¤½Ÿö~ÚûÀ¥ÉK“—&ÿVÿVÿV c.c.c¨­­Ê®•]+»œK>—|.ˆÔDj"5@[t[t[4 _ª_ª_ºpýÕΫW;>Y>Y>Y€õwëïÖ߈§ÄSâ)R'‰“Ä‘Í7›o6ß\¨€Ál0̤¼SÞ)ï$ƒR‚R‚RÈ—3_Î|9“ô³øYü,dÒ¤I7H‹ŸÅÏâGöÕôÕôÕAùAùAù¤Ä 1H dÈùó!çɲÀ²À²@R\".—Å?ÿTüÓÂõïîîÈ(×(×(W{Åç:æ:æ:¡£ÐQèˆÒDi¢´E:žAª U L©§ÔSj`$a$a$pLvLvL†¶mÚ VVV~‰~‰~‰À®_wýºëWÀrÄrÄrÈPf(3”ÀóåÏ—?_|ôÉGŸ|ô ·!nC܆E–o4 šQ¨(Tj*ŠÅŠb`V2+™•o‹·Å{±– ‚€5Ôj Ò­éÖt+P¡þBý ðzáõÂë@÷+ݯt¿èôú{x`c`c`#à~Úý´ûi À` °K>_òù’ϵ«ÚUí È5r\³È!2Ï–g˦ççÃïy}9úrôe»%%×K®—\_¤„ú }†>R!UHRò1ŸÇ|ó!ãZãZãZIe´2ZM.»³ìβ;d{{{¿=¾á†7Þ =.x\ð¸@Ö)ë”uJ²¥­¥­¥\öȲG–=B~œúqêÇ‹z²{²{²Iß}¾û|÷ÝSBª¯U_«¾¶'ÔTßTßTÌý6÷ÛÜoöqéyéyéyàÅÒK_,ÔoªßT¿ xj=µžZ F#‘'kOÖž¬B2B2B2ìñò+ò+ò+ÀK›^ÚôÒ&@Þ!ïw2³Ì,3¿Düñ  ($ ÉBt't't'€Á̓›7+›V6­lÐÜÜL>ŠGñ(Hï×¼_ó~¼úóÕŸ¯þ|5¬a iK±¥ØRH[€-À@Ú²mÙ¶l’{¸‡{þ¦#íænî&mkmkmkIÆ1Žq$ýéOÒ*° ¬Òö¥íKÛ—ö°™’™’™2ùpòáäÃvås r r H˜½Ì^f/r[Ö¶¬mYö Y]Y]Y]¤ùóæþávû7¨\W¹®r)žψgHŸ­>[}¶’º]‰®äžÃ\K]K]KéuÉë’×%Rü©øSñ§di|i|i#FQ`$c¼b¼b¼ÈŽ‹;.Þ_€^êg3f3f3Èʵ•k+×’êUêUêU¤Ãr‡åËIÇq'=4 ¹~lýØú12*+*+*‹ŒÍÍÍ'Ueª2Uéû®ï»¾ï’!!!v¥W„­[FjõZ½VO' ' '<ØÁ‡þ+ñ'†††È¢²¢²¢22\® ב2™ƒÌNèAOßbßbßb2Ç%Ç%Ç…ÔéuzžœŸŸx>ÿ^5¡–ü+^:tEXtComment Created with Inkscape (http://www.inkscape.org/) ã+ldIEND®B`‚openchange-2.0/apidocs/html/libmapi++/24px-Cc-sa_white.svg.png000066400000000000000000000053061223057412600240460ustar00rootroot00000000000000‰PNG  IHDR°çá»bKGDÿÿÿÿÿÿ X÷Ü pHYsHHFÉk> IDATXÕX}LÓW>¿ ´–.Ôb±‚" Cèê(lS„9ÉuN&n ʹŒ,+&+™“à&3[a`Ë$™ãs‰3Ö¨L(ŠX¸Åñá¬EÄ4ElK¡åyÿy÷–¼µ/¾çŸ›ÜsŸsžûœÓ{· þmô”¶ðà?¬Y3²†èBý…ú õD—7\ÞpyÑpâpâp"‘Ñh4DóÏÌ?3ÿ QPmPmP-QØoa¿…ýFw"îDÜ ¢ŒÊŒÊŒJ¢8n7ŽKäwÃï†ß§eCDxJ3›ŠMÅÀgW?»úÙU ‚‰`"€Ä bý#À>Ê>Ê> p ¸Ü€WÀ+àË3–g,Ïèú†¾q¯Ø°%` ===è&tº ÀéŠtE.Í‹ñVœÁœ!ºxçâ‹wˆ>5|jøÔ@Ô#ë‘õȈ|Ç|Ç|Lj^,z±èÅ"¢m»·íÞ¶›(Žljãùùù±x,‹G4;;K499IÔÞÚÞÚÞJÔ¾§}Oû"s‚9Áœ@$4 BQa~a~a>Ñ!Û!Û!o„7Âyš ¬Çz¬ßi|§ñ`ÕЪ¡UCnÅdý²~Y?ÐÔ×Ô×ÔLÍLÍLÍÂGø8¶ãØŽc;ÜÄãËãËãËS‘©ÈTäxÏ®ž]=»€Wv^Ùy´ Z­SÏÔ3õ‹~Ü&¶‰mÄ_‰¿ ;v( 05›šMÍžqÝÎng7P¼¶xmñZwœ—^éõ—^îõÝë»×Ð`é`é`)°áµ ¯mx Xž²äeò2y™'ñA„ B”ØJl%6 nUݪºU€*Z­ŠÄÄÄ“Ïä3€å[Ë·–o½ãq·qØkÝkÝkõl¥ÏÕŸ«?W{Â?~< $®H\‘¸Â½Þg®w®w®—ˆ³Œ³Œ³ŒˆÍÎfgQuQ—§¯È_‘¿"'Ò˜5f™Hë¯õ×úûëØ_Çþ"âïçïçïÿß.ëi=­'ò©õ©õ©õtϧϧϧ{Î3LÓAÄ–²¥l)éHG:"VPePeP%‘ƒëà:¸D³³³ÞóOØ'ìv¢Õ©«SW§åìËÙ—³È,7ËÍr"G…£ÂQá?—7—7—G4ùóäÏ“?{ú\WÀõœ_P-¨TDÖxk¼5~‘ckçÖέî’TýQõGÕÞ;à|Öù¬óY@ÀÉ€“'Þ:Þ:Þ:@œ&N§cccÞñÝ‚nA·ý$úIô“;/š?ÍŸtƒºAÝN¡¡ü¡ü¡| ¤0¤0¤pQë}RôIÑ'¯³¾ÎúpŒ9ÆO 2Z3Z3ZÄŒ9s㇓w%ïJ޴ŶŶÅwDwDwDÀÅ÷/¾ñ}`Ëw[¾Ûò'îÍóožó<`}×ú®õ]ϼgfÏÌž™XZ––¥Ö¶¯m_ÛP‡¤CÒ!$ ~ø!ÐógÏŸ=zW²V]«®Uœ:N§n¡(Š¢(À?Ê?Ê? Í Í Íxž…gñ$ê u…º€®³]g»Îzæ±UÙªlU€¼D^"/Yto¨ Ôj€ìB»Ð.ö(ö(ö(Ü ýŠ~E?`ï²wÙ»<;„¡ChÞм¡y±D,ë 7ò¬V +Ø”»)wS.pI}I}Ií]¨æèæèæhÀÏægó³Á™Á™Á™€¾J_¥¯Zô1§Óê´:- ¼"¼"¼ø}ï÷½ß÷@uJuJu àZp-¸<8wþîü0ì7ì7ìJ5¥šR ùwæß™ÛÓ·§oOÞî|»óíNà”ñ”ñ”ý–ý€~@Äì‹Ù³Ï-@qqq?° ].HmÀ5åšrMǧOŸXm¬6V°²deÉÊàtÆéŒÓ€óWç¯Î_½'F ZÐ8ßs¾ç|˜+Ÿ+Ÿ+\®W€ILbÒ;ü¦ô¦ô¦ØÜ°¹asƒ›xÒñ¤ãIÇñeãËÆ—¹×{¼   ¥F©QjV:+•ð[ø-ü@=®W÷ÎÝ;wïÜÒ„–2[Ž-Ç–4O7O7O76nlt—<”<”<zózózó<ñ^ßÄ–dK²%PVVx¾<_ž/À\b.1—I¶$[’ |Éÿ’ÿ%Ðwê;õÀdÅdÅd` ³†YÃk‹µÅÚÌlÙ:³>0|`øP¯®W׫ù«òWå¯Ü:n·`ŒŒ‘1IÂ$a’è½Ð{¡÷‚w–|Ô;ö:ö:öÍÏ7?ßü<šš øˆ}Ä>b€4¤!   P(ØÉØÉØI Q‘¨HTÉG’$d5²Y r2ädÈIÀçŸ|^p+½&nMÜš8 x x xß1¾c|ÇÒ|ê%þ±±gÇž{(¯)¯)¯âõñúx=àÃ÷áûð—>…þC*C*C*N§€èôúÀ™âLq¦<=ŸYΧюéÈ:tEXtComment Created with Inkscape (http://www.inkscape.org/) ã+ldIEND®B`‚openchange-2.0/apidocs/html/libmapi++/CC_SomeRightsReserved.png000066400000000000000000000064521223057412600244630ustar00rootroot00000000000000‰PNG  IHDRZ¬a x pHYs  šœtIMEÕ ÌIðbKGDÿÿÿ ½§“ ·IDATx^í™iŒUEÇû¾{ßÚÝ6ë"²Š‚@!`˜DÇ¡Ä "Œ2 ×%Æ(ê—D£ñƒ1¨â’Œ@Pƒ¢HezXš¦é†¶~¯ßrç÷ïÜêyV¼ 1í„VòçÔz«þuêÔ¹÷9%¿Nr@$Bd\ºP¤Ç¤KˆÒ•HD€’È|² È h‘,Ò›= lœ)Ò›Íøí´2$Ù"ír«,n¤…˜Õ?À+B¸4d¤à `d‘ž—Þ†vL‘_‰h×&By#Äl ,‹OHIÚyû¤Ø°N‡¤g¡èäÒùnÑ‹0 g­Kë!í i6IÁ¶dËŠ…‚bÉFÝ?Ÿ-ÚŠ°áÙ–eÈO&“‰gŸ}vä–-[¦œ8qâŽ\.7çÌ™3Ó÷ìÙ3áý÷ß¿büøñÝdÉňÅb©Ç{lÐ÷ßÿ‡ãÇÏ ÏÜæææ¿8p`ÎòåË+§L™ÒËz– {®ƒö½´Ú?Å­cݦ[e‰â²áÇw]¶lÙ´¾}ûBfxrçfÞ_|±»bÅŠ!ƒ *ÿ}]xÍÒ’V™OŸï ¤­{–.¸Xrì“O>ù“!yûöí 7ß|óêT*õwÊÖ<óÌ3ûNž<™S]±%Óg˜!yóæÍM7ÞxãÚÒÒÒ¥lÀâW^yeÝéÓ§3ª3Ï q5nHÞÎW‹ŽXVœ ½ÄŒ/¾øâè|p¢Ø·o_ãСC¿J§Ó­‘ˆÁ€Ê>ûì³—^ziµÚÍŸ?¿âÕW_í!}çΧG޹9“ÉüÄZ9%.}*{öì¹ð,–kK»¬p>Z´‰s£[å6\ÉÊÊÊ¡f€—_~ù_±#“½{÷:|ÈlÒ­·ÞÚÁôyþùç Ù³ýð¶mÛÒ¼È ýG2$ïXh—äµ?Ñá °7£OŸ>ÝÍøéc¶»Q+êp±ú˜é³råÊûb³78¶ 1Ë@Îï8ڱɷõb²ñÑqÓøÈ‘#9Ûê‹`ÜI²¢¢¢mîÇŽioŠÉ ß\#C²†óÐu„è>ˆ„µÃU´˜L÷îÝcöÆXäy Ååè›>;wöl²Î‘<'l íî:|ßïÐ^ƒmܸÑûâ‹/R555‰£G&!#ÉÍŸjiiI€$~4‘ÍfS<3U(ù|>!YWW÷Ã%—\ÒScÜvÛm=Þyçã´ñ€ "À´a¤<²y×®]±Ñ£G»êsÓM7¥/^|š0γD"qd©)D£Ñ‚ëº>(ñ<Ï!ïÁD€KÄâ^pÁ^×®]½þýûGG»æšk²í壎hÿ—ì&t¯ºêªDÇŽSç/‰ü1Á DB„Cr²“È/ñï¾û®Ú=oÞ¼Á«V­Ú€•»l‚ ’ýnݺ9o½õVçIˆË}ùå—ˆ.UŸ‡z¨ÓºuëWsvIž€ï/ýõ×õÒò7òˆ|P"‚ãñx+ɉDB$ srª¢½{÷Ž:êtåI¿”§VKqöÆç>8dF°4Y³‡èä©S§â”'xÃK@r\0dƒ¸ÈfÑ©×^{m . \ãa_¸pa͆ 2eee¥×]w]§Ù³gwÁÚ´‘GÔF$}øá‡{õêå)_UUuúÍ7߬ٺuë:uÊOœ8±ãÔ©SB^ ‹ÿ+äf »b3œ¡:@†x= Ùiü~¦C‡é.]º¤ÙØ QN3ýE´c‘z.ût Ñã• 'ôÜwÒœC‡űæ8¯Ã²è˜ˆ†ä¸¬ZRD$Çò²êaX—ûî»od—…ÎÜ÷Kn¸á†ƒÈV]ÀêܧŸ~ºë…^;[Ÿ»îºk‘!¤A‹ò\ÂÑ­`#Óll Va61­S`Nz8ܧžzêrë±Ñ%amŠÛâE`)$¤°ž$H±¨V“ÿMqEJÒYd î¯]»¶™§Øƒÿ›P¨¯¯ÏàN¾ñÆGñë9Ú°´zvÍš5M¸™,㔀ˆéÓØØxŠ7ÌÚ?þx#d·@bIyy¹ƒŒX¯ "Pç"=ê$]¤GY4„#Ût›3ÆG;ç°3þ9„>>ĉ´$DuAZ ×!b£" –%G%!$J[å¥{HwQ © ô­KQÒEF°´¶èEV òëׯo¤_=$çØì2+ g±È,® Ɔ—°yÅ £ e¾Ñ6/ÊI?%&)’€hî£ëtt´^~ä}‘Œlõ딹ä[A>á’Q ’uZZ@–òlȧÒPÂmiÝ1”àp_ä‡í¤Êb<‘*²Ñ•$[‰ HÑ’Ê»"2% Éå!URd;"8€X³’¤A„ä—ä{$‘/QˆDIr³Áüäzb¤2«r…ƒg#ÖÒC91á]…UîôIaÖl„N^£+ŽÕÊÛˆ’Fò’&/˜ÐN1´¤±nG©Øª€acÝH§ØºE0R¹²æ"Œ/=t?´¡`.ÄšM:«±àDæÎ;ž[ÎsÏ=7’ ©O¿~ýoûh#Øåy›6mêÅGšÞ¯{T¦~Lêµ½þúë')o±^N})Ÿ9ï Þüî»ï*ÔJ¦HcÇŽ­ä¢Ià³Ëˆ›¯ tÅÇû¡„V1.¢èôéÓ/G÷„Ûo¿}0Ò%Vî?cÆŒA?üpß%K–t&Bé‡/¯Ï&JP[éJÖ¼ûþùç=xNœ‹-~íµ×þž—¡±<çwšÃK/½4Œ²Ê÷Þ{oëÓúèÞξ¥s eKu¤¦M›¶öJW;AþLõÒ L×°Œpn¹üŸ1WCBšèá«Ã‡¯¡,W]]ý-ñmý#zTܨêŠ]ª)ã›ù)Þ./“.‹Þüõ×_ïâm*Ë—³²œÊ£ó Ü|°wÑ¢E²¦¶zŽHžÎ°ÓÊÛàRÛ*ÿ©yŽì¼*^`ªd‘¼Ììfü<ñî>\×q^:²lÈA¬þ ãØ"H¯­­=Ì‹Pý ’K—.=¦·?Œ¢^yÕ ¤Z¾›R‘Ìiiâ µ«Ý¯2æšÁ5œàÌ.>­V3FÒªpaÛ5Oꛃµl1ëÓéxüñÇkUÆÿ’UãÆ;‰;Ép¯l ã@ÙŠèý úÉ'Ÿlš5kÖIÞós¼Å€”ê=zäT/BL;£•W Ê[¨D*ǹŽ;@ãÖæRúa&œƒ˜zȯg¬ßEØ€£ÒqeÇ8ÒÒ% I—ظ33gÎLKW½ú©þ»‰gæÉ7˜ñ±ò:=bk™GíO%ƒŽñ}CãÙQQ mEõLŽzÏÌ«LÏ4m!ÚçBup›)½ä´­Å¬¿ÃÊÇá.è7±ÏÅáCŒÏDýÝ»wûJøÈVië,ºµíœ9s|;Ùí¹©}.Ÿ”aŒ>dû,ÆçHZ}Btk¾çöL{®öv}ø8Òq¡¡˜²!C†ø&Lðq]¾DÿÊé7üFôÿÿj|w‚%&IEND®B`‚openchange-2.0/apidocs/html/libmapi++/annotated.html000066400000000000000000000144561223057412600224720ustar00rootroot00000000000000 MAPIC++ClientLibraryBindings 2.0 API Documentation
Class List
Here are the classes, structs, unions and interfaces with brief descriptions:
[detail level 12]
\NlibmapippThe libmapi++ classes and other definitions are all enclosed in the libmapipp namespace
 oCattachmentThis class represents a message attachment
 oCfolderThis class represents a folder or container within Exchange
 oCmessageThis class represents a message in Exchange
 oCmessage_storeThis class represents the Message Store in Exchange
 oCobjectBase Object class
 oCprofile_databaseThis class represents a user profile database
 oCproperty_containerA container of properties to be used with classes derived from object
 oCproperty_container_iteratorIterator to use with Property Container
 \CsessionThis class represents a MAPI session with the Exchange Server

Creative Commons License
Creative Commons Attribution icon Creative Commons Share Alike icon
This content is licensed under the Creative Commons
Attribution ShareAlike License v. 3.0:
http://creativecommons.org/licenses/by-sa/3.0/

openchange-2.0/apidocs/html/libmapi++/apidocs.css000066400000000000000000000362151223057412600217600ustar00rootroot00000000000000/* ** WEBSITE ** */ BODY,H1,H2,H3,H4,H5,H6,P,CENTER,TD,TH,UL,DL,DIV { font-family: Geneva, Arial, Helvetica, sans-serif; } BODY,TD { font-size: 90%; } H1 { text-align: center; font-size: 160%; } H2 { font-size: 19px; font-weight: bold; color: #3E93D5; } H3 { font-size: 100%; } P { text-align: justify; } LI { li-style-type: square; li-style-position: outside; display: list-item; } CAPTION { font-weight: bold } DIV.qindex { width: 100%; background-color: #e8eef2; border: 1px solid #84b0c7; text-align: center; margin: 2px; padding: 2px; line-height: 140%; } DIV.nav { width: 100%; background-color: #e8eef2; border: 1px solid #84b0c7; text-align: center; margin: 2px; padding: 2px; line-height: 140%; } DIV.navtab { background-color: #e8eef2; border: 1px solid #84b0c7; text-align: center; margin: 2px; margin-right: 15px; padding: 2px; } TD.navtab { font-size: 70%; } A.qindex { text-decoration: none; font-weight: bold; color: #1A419D; } A.qindex:visited { text-decoration: none; font-weight: bold; color: #1A419D } A.qindex:hover { text-decoration: none; background-color: #ddddff; } A.qindexHL { text-decoration: none; font-weight: bold; background-color: #6666cc; color: #ffffff; border: 1px double #9295C2; } A.qindexHL:hover { text-decoration: none; background-color: #6666cc; color: #ffffff; } A.qindexHL:visited { text-decoration: none; background-color: #6666cc; color: #ffffff } A.el { text-decoration: none; font-weight: bold } A.elRef { font-weight: bold } A.code:link { text-decoration: none; font-weight: normal; color: #0000FF} A.code:visited { text-decoration: none; font-weight: normal; color: #0000FF} A.codeRef:link { font-weight: normal; color: #0000FF} A.codeRef:visited { font-weight: normal; color: #0000FF} A:hover { text-decoration: none; background-color: #f2f2ff } DL.el { margin-left: -1cm } .fragment { font-family: monospace, fixed; font-size: 95%; } PRE.fragment { border: 1px solid #CCCCCC; background-color: #f5f5f5; font-size: 11px; margin-top: 4px; margin-bottom: 4px; margin-left: 2px; margin-right: 8px; padding-left: 6px; padding-right: 6px; padding-top: 4px; padding-bottom: 4px; } DIV.ah { background-color: black; font-weight: bold; color: #ffffff; margin-bottom: 3px; margin-top: 3px } DIV.groupHeader { margin-left: 16px; margin-top: 12px; margin-bottom: 6px; font-weight: bold; } DIV.groupText { margin-left: 16px; font-style: italic; font-size: 90% } BODY { background: white; color: black; margin-right: 20px; margin-left: 20px; } TD.indexkey { background-color: #e8eef2; font-weight: bold; padding-right : 10px; padding-top : 2px; padding-left : 10px; padding-bottom : 2px; margin-left : 0px; margin-right : 0px; margin-top : 2px; margin-bottom : 2px; border: 1px solid #CCCCCC; } TD.indexvalue { background-color: #e8eef2; font-style: italic; padding-right : 10px; padding-top : 2px; padding-left : 10px; padding-bottom : 2px; margin-left : 0px; margin-right : 0px; margin-top : 2px; margin-bottom : 2px; border: 1px solid #CCCCCC; } TR.memlist { background-color: #f0f0f0; } P.formulaDsp { text-align: center; } IMG.formulaDsp { } IMG.formulaInl { vertical-align: middle; } SPAN.keyword { color: #008000 } SPAN.keywordtype { color: #604020 } SPAN.keywordflow { color: #e08000 } SPAN.comment { color: #800000 } SPAN.preprocessor { color: #806020 } SPAN.stringliteral { color: #002080 } SPAN.charliteral { color: #008080 } .mdescLeft { padding: 0px 8px 4px 8px; font-size: 80%; font-style: italic; background-color: #FAFAFA; border-top: 1px none #E0E0E0; border-right: 1px none #E0E0E0; border-bottom: 1px none #E0E0E0; border-left: 1px none #E0E0E0; margin: 0px; } .mdescRight { padding: 0px 8px 4px 8px; font-size: 80%; font-style: italic; background-color: #FAFAFA; border-top: 1px none #E0E0E0; border-right: 1px none #E0E0E0; border-bottom: 1px none #E0E0E0; border-left: 1px none #E0E0E0; margin: 0px; } .memItemLeft { padding: 1px 0px 0px 8px; margin: 4px; border-top-width: 1px; border-right-width: 1px; border-bottom-width: 1px; border-left-width: 1px; border-top-color: #E0E0E0; border-right-color: #E0E0E0; border-bottom-color: #E0E0E0; border-left-color: #E0E0E0; border-top-style: solid; border-right-style: none; border-bottom-style: none; border-left-style: none; background-color: #FAFAFA; font-size: 80%; } .memItemRight { padding: 1px 8px 0px 8px; margin: 4px; border-top-width: 1px; border-right-width: 1px; border-bottom-width: 1px; border-left-width: 1px; border-top-color: #E0E0E0; border-right-color: #E0E0E0; border-bottom-color: #E0E0E0; border-left-color: #E0E0E0; border-top-style: solid; border-right-style: none; border-bottom-style: none; border-left-style: none; background-color: #FAFAFA; font-size: 80%; } .memTemplItemLeft { padding: 1px 0px 0px 8px; margin: 4px; border-top-width: 1px; border-right-width: 1px; border-bottom-width: 1px; border-left-width: 1px; border-top-color: #E0E0E0; border-right-color: #E0E0E0; border-bottom-color: #E0E0E0; border-left-color: #E0E0E0; border-top-style: none; border-right-style: none; border-bottom-style: none; border-left-style: none; background-color: #FAFAFA; font-size: 80%; } .memTemplItemRight { padding: 1px 8px 0px 8px; margin: 4px; border-top-width: 1px; border-right-width: 1px; border-bottom-width: 1px; border-left-width: 1px; border-top-color: #E0E0E0; border-right-color: #E0E0E0; border-bottom-color: #E0E0E0; border-left-color: #E0E0E0; border-top-style: none; border-right-style: none; border-bottom-style: none; border-left-style: none; background-color: #FAFAFA; font-size: 80%; } .memTemplParams { padding: 1px 0px 0px 8px; margin: 4px; border-top-width: 1px; border-right-width: 1px; border-bottom-width: 1px; border-left-width: 1px; border-top-color: #E0E0E0; border-right-color: #E0E0E0; border-bottom-color: #E0E0E0; border-left-color: #E0E0E0; border-top-style: solid; border-right-style: none; border-bottom-style: none; border-left-style: none; color: #606060; background-color: #FAFAFA; font-size: 80%; } .search { color: #003399; font-weight: bold; } FORM.search { margin-bottom: 0px; margin-top: 0px; } INPUT.search { font-size: 75%; color: #000080; font-weight: normal; background-color: #e8eef2; } TD.tiny { font-size: 75%; } a { color: #1A41A8; } a:visited { color: #2A3798; } .dirtab { padding: 4px; border-collapse: collapse; border: 1px solid #84b0c7; } TH.dirtab { background: #e8eef2; font-weight: bold; } HR { height: 1px; border: none; border-top: 1px solid black; margin-bottom: 50px; } /* Style for detailed member documentation */ .memtemplate { font-size: 80%; color: #606060; font-weight: normal; } .memnav { background-color: #e8eef2; border: 1px solid #84b0c7; text-align: center; margin: 2px; margin-right: 15px; padding: 2px; } .memitem { padding: 4px; background-color: white; border-width: 1px; border-style: solid; border-color: #ccc; -moz-border-radius: 8px 8px 8px 8px; margin-bottom: 30px; } .memname { white-space: nowrap; font-weight: bold; font-size: 12px; margin: 10px 10px 10px 10px; } .memname EM { color: #45417e; } .memdoc{ padding-left: 10px; padding-right: 10px; } .memdoc EM, TD { font-size: 12px; } .memproto { background-color: #e9e9f4; width: 100%; border-width: 1px; border-style: solid; border-color: #ccc; font-weight: bold; -moz-border-radius: 8px 8px 8px 8px; } .paramkey { text-align: right; } .paramtype { white-space: nowrap; } .paramname { color: #602020; font-style: italic; white-space: nowrap; } /* End Styling for detailed member documentation */ /* for the tree view */ .ftvtree { font-family: sans-serif; margin:0.5em; } .directory { font-size: 9pt; font-weight: bold; } .directory h3 { margin: 0px; margin-top: 1em; font-size: 11pt; } .directory > h3 { margin-top: 0; } .directory p { margin: 0px; white-space: nowrap; } .directory div { display: none; margin: 0px; } .directory img { vertical-align: -30%; } #website { width: 820px; height: 100%; margin-left: auto; margin-right: auto; text-align: left; /* IE hack */ * position: absolute; * left: 50%; * margin-left: -410px; } /* ** HEADER ** */ .header { height: 200px; background: url(header.jpg) no-repeat top center; } body { background: #fff url(body_top_bg2.jpg) top left repeat-x; font-family: Arial, Trebuchet MS, Tahoma, Verdana, Helvetica, sans-serif; font-size: 11px; line-height: 17px; color: #444; color: #3a3a3a; fdpadding-top: 15px; text-align: center; background-color: #fbfbfb; } h1 { font: 24px bold Trebuchet MS, Arial; color: #FFF; padding: 0; margin: 0; } /* ** MIDDLE SIDE ** */ #middle_side { display: block; height: 100%; width: 800px; margin-top: 7px; backsground: url(middle_bg.jpg) top left repeat-x; background-color: #fbfbfb; } /* left and right side */ #left_side { background-color: #fff; clear: both; margin-bottom: 10px; border-bottom: 1px solid #eee; border-left: 1px solid #eee; border-right: 1px solid #eee; -moz-border-radius: 0 0 8px 8px; height: 29px; } /* ** MENU HORIZONTAL ** */ /************ Global Navigation *************/ DIV.tabs { float : left; width : 100%; background : url("tab_b.gif") repeat-x bottom; margin-top : 10px; margin-bottom : 4px; } DIV.tabs ul { margin : 0px; padding-left : 10px; list-style : none; } DIV.tabs li { display : inline; margin : 0px; padding : 0px; } DIV.tabs A { float : left; background : url("tab_r.gif") no-repeat right top; border-bottom : 1px solid #84B0C7; font-size : x-small; font-weight : bold; text-decoration : none; } DIV.tabs A:link, .tabs A:visited, DIV.tabs A:active, .tabs A:hover { color: #1A419D; } DIV.tabs SPAN { float : left; display : block; background : url("tab_l.gif") no-repeat left top; padding : 5px 10px; white-space : nowrap; } DIV.tabs TD { font-size : x-small; font-weight : bold; text-decoration : none; } /* Commented Backslash Hack hides rule from IE5-Mac \*/ DIV.tabs SPAN {float : none;} /* End IE5-Mac hack */ DIV.tabs A:hover SPAN { background-position: 0% -150px; } DIV.tabs LI.current A { background-position: 100% -150px; border-width : 0px; } DIV.tabs LI.current SPAN { background-position: 0% -150px; padding-bottom : 6px; } DIV.nav { background : none; border : none; border-bottom : 1px solid #84B0C7; } #right_side_home { font-family: "Lucida Grande", Arial, Verdana, sans-serif; background-color: white; padding: 0px 20px; border: 1px solid #ebebeb; border: 1px solid #ddd; -moz-border-radius: 10px 10px; width: 750px; * width: 800px; * margin-left: 0px; padding-bottom: 10px; } #right_side_home td { line-height: 17px; margin: 0 0 5px 0; padding: 10px 0 15px 7px display: table-cell; border-spacing: 2px 2px; vertical-align: middle; text-align: left; border-bottom: 1px solid #EEEEEE; } #right_side_home td h2, a.anchor { font-size: 19px; font-weight: bold; color: #3E93D5; } #right_side_home td.indexkey { border-bottom: none; } #right_side_home li { list-style-position: inside; valign: middle; } TD.indexkey { background-color: #e8eef2; font-size : 12px; font-weight : bold; padding-right : 10px; padding-top : 2px; padding-left : 10px; padding-bottom : 2px; margin-left : 0px; margin-right : 0px; margin-top : 2px; margin-bottom : 2px; border : 1px solid #CCCCCC; } TD.indexvalue { background-color: #e8eef2; font-style : italic; font-size : 12px; padding-right : 10px; padding-top : 2px; padding-left : 10px; padding-bottom : 2px; margin-left : 0px; margin-right : 0px; margin-top : 2px; margin-bottom : 2px; border : 1px solid #CCCCCC; } TR.memlist { background-color: #f0f0f0; } .mdescLeft { padding: 0px 8px 4px 8px; font-size: 80%; font-style: italic; background-color: #FAFAFA; border-top: 1px none #E0E0E0; border-right: 1px none #E0E0E0; border-bottom: 1px none #E0E0E0; border-left: 1px none #E0E0E0; margin: 0px; } .mdescRight { padding: 0px 8px 4px 8px; font-size: 80%; font-style: italic; background-color: #FAFAFA; border-top: 1px none #E0E0E0; border-right: 1px none #E0E0E0; border-bottom: 1px none #E0E0E0; border-left: 1px none #E0E0E0; margin: 0px; } .memItemLeft { padding: 1px 0px 0px 8px; margin: 4px; border-top-width: 1px; border-right-width: 1px; border-bottom-width: 1px; border-left-width: 1px; border-top-color: #E0E0E0; border-right-color: #E0E0E0; border-bottom-color: #E0E0E0; border-left-color: #E0E0E0; border-top-style: solid; border-right-style: none; border-bottom-style: none; border-left-style: none; background-color: #FAFAFA; font-size: 80%; } .memItemRight { padding: 1px 8px 0px 8px; margin: 4px; border-top-width: 1px; border-right-width: 1px; border-bottom-width: 1px; border-left-width: 1px; border-top-color: #E0E0E0; border-right-color: #E0E0E0; border-bottom-color: #E0E0E0; border-left-color: #E0E0E0; border-top-style: solid; border-right-style: none; border-bottom-style: none; border-left-style: none; background-color: #FAFAFA; font-size: 80%; } .memTemplItemLeft { padding: 1px 0px 0px 8px; margin: 4px; border-top-width: 1px; border-right-width: 1px; border-bottom-width: 1px; border-left-width: 1px; border-top-color: #E0E0E0; border-right-color: #E0E0E0; border-bottom-color: #E0E0E0; border-left-color: #E0E0E0; border-top-style: none; border-right-style: none; border-bottom-style: none; border-left-style: none; background-color: #FAFAFA; font-size: 80%; } .memTemplItemRight { padding: 1px 8px 0px 8px; margin: 4px; border-top-width: 1px; border-right-width: 1px; border-bottom-width: 1px; border-left-width: 1px; border-top-color: #E0E0E0; border-right-color: #E0E0E0; border-bottom-color: #E0E0E0; border-left-color: #E0E0E0; border-top-style: none; border-right-style: none; border-bottom-style: none; border-left-style: none; background-color: #FAFAFA; font-size: 80%; } .memTemplParams { padding: 1px 0px 0px 8px; margin: 4px; border-top-width: 1px; border-right-width: 1px; border-bottom-width: 1px; border-left-width: 1px; border-top-color: #E0E0E0; border-right-color: #E0E0E0; border-bottom-color: #E0E0E0; border-left-color: #E0E0E0; border-top-style: solid; border-right-style: none; border-bottom-style: none; border-left-style: none; color: #606060; background-color: #FAFAFA; font-size: 80%; } code { display: block; width: 100%; border: 1px solid #ccc; background-color: #e8edf3; padding-top: 10px; padding-bottom: 10px; padding-left: 5px; padding-right: 5px; margin-bottom: 10px; margin-top: 10px; } openchange-2.0/apidocs/html/libmapi++/attach_test_8cpp-example.html000066400000000000000000000315541223057412600254010ustar00rootroot00000000000000 MAPIC++ClientLibraryBindings 2.0 API Documentation
attach_test.cpp

An example that shows reading of attachments.

/*
libmapi C++ Wrapper
Sample attachment test application
Copyright (C) Alan Alvarez 2008.
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#include <iostream>
#include <libmapi++/libmapi++.h>
using namespace std;
using namespace libmapipp;
static uint32_t get_attachment_count(message& mapi_message)
{
message::attachment_container_type attachment_container = mapi_message.fetch_attachments();
return attachment_container.size();
}
static void print_messages_with_attachments(folder& up_folder)
{
folder::message_container_type messages = up_folder.fetch_messages();
for (folder::message_container_type::iterator Iter = messages.begin(); Iter != messages.end(); ++Iter) {
uint32_t attachment_count = get_attachment_count(*(*Iter));
// cout << "Attachment Count: " << attachment_count << endl;
if (attachment_count) {
cout << "Message (" << (*Iter)->get_id() << ") has " << attachment_count << " attachments." << endl;
}
}
}
static void print_folder_tree(folder& up_folder, session& mapi_session, unsigned int deep = 0)
{
property_container up_folder_property_container = up_folder.get_property_container();
up_folder_property_container << PR_DISPLAY_NAME << PR_CONTENT_COUNT;
up_folder_property_container.fetch();
string display_name = static_cast<const char*>(up_folder_property_container[PR_DISPLAY_NAME]);
const uint32_t message_count = *(static_cast<const uint32_t*>(up_folder_property_container[PR_CONTENT_COUNT]));
for (unsigned int i = 0; i < deep; ++i) {
cout << "|----> ";
}
cout << display_name << " (id: " << up_folder.get_id() << ") (messages: " << message_count << ")" << endl;
print_messages_with_attachments(up_folder);
// Fetch Top Information Folder Hierarchy (child folders)
for (unsigned int i = 0; i < hierarchy.size(); ++i) {
print_folder_tree(*hierarchy[i], mapi_session, deep+1);
}
}
int main()
{
try {
session mapi_session;
mapi_session.login();
// Get Default Top Information Store folder ID
mapi_id_t top_folder_id = mapi_session.get_message_store().get_default_folder(olFolderTopInformationStore);
// Open Top Information Folder
folder top_folder(mapi_session.get_message_store(), top_folder_id);
print_folder_tree(top_folder, mapi_session);
}
catch (mapi_exception e) // Catch any mapi exceptions
{
cout << "MAPI Exception @ main: " << e.what() << endl;
}
catch (std::runtime_error e) // Catch runtime exceptions
{
cout << "std::runtime_error exception @ main: " << e.what() << endl;
}
return 0;
}

Creative Commons License
Creative Commons Attribution icon Creative Commons Share Alike icon
This content is licensed under the Creative Commons
Attribution ShareAlike License v. 3.0:
http://creativecommons.org/licenses/by-sa/3.0/

openchange-2.0/apidocs/html/libmapi++/bc_s.png000066400000000000000000000012501223057412600212270ustar00rootroot00000000000000‰PNG  IHDR /ð9ÐoIDATxíMLAÇßìN»»¥ívKùPJik±R5^ŒChÂŃ!Dzƒ *U4VƒbÄD1~`8xà@ˆ^¿?ð𤡸Ý@јÝná`JLLÝØ¦ƒÜXi v«9ê)·}aV±&Ò0)›¼ð(‰zÛküNcFPÛù'@é¨KZK%!13§5£}Ý€ÒdÀã°’>´Åç´çhï¹G…ÉZ ïz×Ú—Éi£“ì–º=…@O¹«È‚1Ó¯¦3ãF«[ºä’d²¾JÒã`|^3˜Ý\›¿¡]²ó•'fçÓùyˆÄîçâÙ@¥Cos˧d:?$lhûnÝ× nm\†$cÔL6Ñý »Ì´x@N¦oPÀ®Î‘òÕ”€GÔ÷>9¹¨Q@ã±á“.‡qŠÜ´¼°Ø ”PCt(á«yŒQ$±°hÔNý8¤¥Ë MNjÿ$þßþŲo_ƒsLIEND®B`‚openchange-2.0/apidocs/html/libmapi++/bdwn.png000066400000000000000000000002231223057412600212520ustar00rootroot00000000000000‰PNG  IHDR5åZIDATxíË € DŸP–1ñlžmÀ r±j².e è†D[ØÉ¾ÙÏÔ¼µ¦ã´Þ|陣6€Všë3´Å?Ls'(}¬>+ žKó÷¥¿ch`‚ ^׃ÞnIEND®B`‚openchange-2.0/apidocs/html/libmapi++/body_top_bg2.jpg000066400000000000000000000006541223057412600226750ustar00rootroot00000000000000ÿØÿàJFIFddÿìDuckydÿîAdobedÀÿÛ„ÿÀ–ÿÄh að¡q‘QáR’¢ð!‘1aQÿÚ ?Ô¢±Õœ|W¼ í|ua³Dbe­‚hŒ*ø VÁ&ÅrV¹´,¸^Â-~TbÁÐéÊ—=©xj䮤*ÿRb²r %7L‘ñÜŠ¶5ø¦ èªÞV¶ ÿÙopenchange-2.0/apidocs/html/libmapi++/classes.html000066400000000000000000000133621223057412600221450ustar00rootroot00000000000000 MAPIC++ClientLibraryBindings 2.0 API Documentation
Class Index
A | F | M | O | P | S
  A  
  M  
  P  
  S  
attachment (libmapipp)   message (libmapipp)   profile_database (libmapipp)   session (libmapipp)   
  F  
message_store (libmapipp)   property_container (libmapipp)   
  O  
property_container_iterator (libmapipp)   
folder (libmapipp)   
object (libmapipp)   
A | F | M | O | P | S

Creative Commons License
Creative Commons Attribution icon Creative Commons Share Alike icon
This content is licensed under the Creative Commons
Attribution ShareAlike License v. 3.0:
http://creativecommons.org/licenses/by-sa/3.0/

openchange-2.0/apidocs/html/libmapi++/classlibmapipp_1_1attachment-members.html000066400000000000000000000142251223057412600276530ustar00rootroot00000000000000 MAPIC++ClientLibraryBindings 2.0 API Documentation
libmapipp::attachment Member List

This is the complete list of members for libmapipp::attachment, including all inherited members.

attachment(message &mapi_message, const uint32_t attach_num)libmapipp::attachment
data()libmapipp::objectinlinevirtual
get_data() const libmapipp::attachmentinline
get_data_size() const libmapipp::attachmentinline
get_filename() const libmapipp::attachmentinline
get_num() const libmapipp::attachmentinline
get_property_container()libmapipp::objectvirtual
get_session()libmapipp::objectinlinevirtual
object(session &mapi_session, const std::string &object_type="")libmapipp::objectinlineexplicit
~attachment()libmapipp::attachmentinlinevirtual
~object()libmapipp::objectinlinevirtual

Creative Commons License
Creative Commons Attribution icon Creative Commons Share Alike icon
This content is licensed under the Creative Commons
Attribution ShareAlike License v. 3.0:
http://creativecommons.org/licenses/by-sa/3.0/

openchange-2.0/apidocs/html/libmapi++/classlibmapipp_1_1attachment.html000066400000000000000000000342551223057412600262300ustar00rootroot00000000000000 MAPIC++ClientLibraryBindings 2.0 API Documentation
libmapipp::attachment Class Reference

This class represents a message attachment. More...

#include <attachment.h>

Inheritance diagram for libmapipp::attachment:
libmapipp::object

Public Member Functions

 attachment (message &mapi_message, const uint32_t attach_num) throw (mapi_exception)
 Constructor.
const uint8_t * get_data () const
 the contents of the attachment
uint32_t get_data_size () const
 the size of the attachment
std::string get_filename () const
 the filename of the attachment
uint32_t get_num () const
 The attachment number.
virtual ~attachment () throw ()
 Destructor.
- Public Member Functions inherited from libmapipp::object
virtual mapi_object_t & data () throw ()
 Obtain a reference to the mapi_object_t associated with this object.
virtual property_container get_property_container ()
 Obtain a property_container to be used with this object.
virtual sessionget_session ()
 Obtain the session associated with this object.
 object (session &mapi_session, const std::string &object_type="") throw ()
 Object Constructor.
virtual ~object () throw ()
 Destructor.

Detailed Description

This class represents a message attachment.

A message can contain both text content, and also have attached (embedded) files and messages. This class represents the attachments for one messaage.

You may not need to create the attachments yourself, since you can create a container with all the attachments using message::fetch_attachments().

Constructor & Destructor Documentation

libmapipp::attachment::attachment ( message mapi_message,
const uint32_t  attach_num 
) throw (mapi_exception)

Constructor.

Parameters
mapi_messagethe message that this attachment belongs to.
attach_numAttachment Number.

Member Function Documentation

const uint8_t* libmapipp::attachment::get_data ( ) const
inline

the contents of the attachment

Note
the length of the array is given by get_data_size()
uint32_t libmapipp::attachment::get_data_size ( ) const
inline

the size of the attachment

Returns
the size of the attachment in bytes
std::string libmapipp::attachment::get_filename ( ) const
inline

the filename of the attachment

Note
not all attachments have file names
Returns
string containing the file name of the attachment, if any

The documentation for this class was generated from the following file:
  • libmapi++/attachment.h

Creative Commons License
Creative Commons Attribution icon Creative Commons Share Alike icon
This content is licensed under the Creative Commons
Attribution ShareAlike License v. 3.0:
http://creativecommons.org/licenses/by-sa/3.0/

openchange-2.0/apidocs/html/libmapi++/classlibmapipp_1_1attachment.png000066400000000000000000000010351223057412600260360ustar00rootroot00000000000000‰PNG  IHDRƒP é6ÕPLTEÿÿÿèìõuÂÀÀÀ‰ÜtRNSÿÿÿÿÿÿÿÕÊT2¬IDATxíánë FÔ÷䛦4ØÝ*ÝYõ'oÄvNÀNþ’RJ‹ERU]ª`†ky›ªjGSWOA­¬.Ãå]TUûêå~İ›¨tûÑô­³5ËÕ\teŽ~fî>P0Äw3¼n "²VÿK>C¸AäIEND®B`‚openchange-2.0/apidocs/html/libmapi++/classlibmapipp_1_1folder-members.html000066400000000000000000000155151223057412600270010ustar00rootroot00000000000000 MAPIC++ClientLibraryBindings 2.0 API Documentation
libmapipp::folder Member List

This is the complete list of members for libmapipp::folder, including all inherited members.

data()libmapipp::objectinlinevirtual
delete_message(mapi_id_t message_id)libmapipp::folderinline
fetch_hierarchy()libmapipp::folder
fetch_messages()libmapipp::folder
folder(object &parent_folder, const mapi_id_t folder_id)libmapipp::folderinline
folder_shared_ptr typedeflibmapipp::folder
get_id() const libmapipp::folderinline
get_property_container()libmapipp::objectvirtual
get_session()libmapipp::objectinlinevirtual
hierarchy_container_type typedeflibmapipp::folder
message_shared_ptr typedeflibmapipp::folder
object(session &mapi_session, const std::string &object_type="")libmapipp::objectinlineexplicit
~folder()libmapipp::folderinlinevirtual
~object()libmapipp::objectinlinevirtual

Creative Commons License
Creative Commons Attribution icon Creative Commons Share Alike icon
This content is licensed under the Creative Commons
Attribution ShareAlike License v. 3.0:
http://creativecommons.org/licenses/by-sa/3.0/

openchange-2.0/apidocs/html/libmapi++/classlibmapipp_1_1folder.html000066400000000000000000000440401223057412600253440ustar00rootroot00000000000000 MAPIC++ClientLibraryBindings 2.0 API Documentation
libmapipp::folder Class Reference

This class represents a folder or container within Exchange. More...

#include <folder.h>

Inheritance diagram for libmapipp::folder:
libmapipp::object

Public Types

typedef boost::shared_ptr< folderfolder_shared_ptr
 Pointer to a folder.
typedef std::vector
< folder_shared_ptr
hierarchy_container_type
 Hierarchy folders.
typedef boost::shared_ptr
< message
message_shared_ptr
 Pointer to a message.

Public Member Functions

void delete_message (mapi_id_t message_id) throw (mapi_exception)
 Delete a message that belongs to this folder.
hierarchy_container_type fetch_hierarchy () throw (mapi_exception)
 Fetch all subfolders within this folder.
message_container_type fetch_messages () throw (mapi_exception)
 Fetch all messages in this folder.
 folder (object &parent_folder, const mapi_id_t folder_id) throw (mapi_exception)
 Constructor.
mapi_id_t get_id () const
 Obtain folder id.
virtual ~folder () throw ()
 Destructor.
- Public Member Functions inherited from libmapipp::object
virtual mapi_object_t & data () throw ()
 Obtain a reference to the mapi_object_t associated with this object.
virtual property_container get_property_container ()
 Obtain a property_container to be used with this object.
virtual sessionget_session ()
 Obtain the session associated with this object.
 object (session &mapi_session, const std::string &object_type="") throw ()
 Object Constructor.
virtual ~object () throw ()
 Destructor.

Detailed Description

This class represents a folder or container within Exchange.

Examples:
attach_test.cpp, foldertree.cpp, messages.cpp, and test.cpp.

Member Typedef Documentation

Hierarchy folders.

This is a vector (list) of child folders for a given folder

Constructor & Destructor Documentation

libmapipp::folder::folder ( object parent_folder,
const mapi_id_t  folder_id 
) throw (mapi_exception)
inline

Constructor.

Parameters
parent_folderThe parent of this folder.
folder_idThis folder's id.

Member Function Documentation

void libmapipp::folder::delete_message ( mapi_id_t  message_id) throw (mapi_exception)
inline

Delete a message that belongs to this folder.

Parameters
message_idThe id of the message to delete.
hierarchy_container_type libmapipp::folder::fetch_hierarchy ( ) throw (mapi_exception)

Fetch all subfolders within this folder.

Returns
A container of folder shared pointers.
Examples:
attach_test.cpp, foldertree.cpp, and test.cpp.
message_container_type libmapipp::folder::fetch_messages ( ) throw (mapi_exception)

Fetch all messages in this folder.

Returns
A container of message shared pointers.
Examples:
attach_test.cpp, messages.cpp, and test.cpp.
mapi_id_t libmapipp::folder::get_id ( ) const
inline

Obtain folder id.

Returns
This folder's id.
Examples:
attach_test.cpp, and test.cpp.

The documentation for this class was generated from the following file:
  • libmapi++/folder.h

Creative Commons License
Creative Commons Attribution icon Creative Commons Share Alike icon
This content is licensed under the Creative Commons
Attribution ShareAlike License v. 3.0:
http://creativecommons.org/licenses/by-sa/3.0/

openchange-2.0/apidocs/html/libmapi++/classlibmapipp_1_1folder.png000066400000000000000000000010011223057412600251520ustar00rootroot00000000000000‰PNG  IHDRiP-)«mPLTEÿÿÿèìõuÂÀÀÀ‰ÜtRNSÿÿÿÿÿÿÿÕÊT2IDATxíí’ƒ EOÂLßÿ‘Wñƒ Æjv†Îvi¹C Ž’`ÿ’RJ]DRUí ARUê$Ùšªª£[£i XÒÛµTU}ysOH¹É<0u«C¶ë¥3³ðÑ´–nýÝönnë´¶-­‰ºó MAPIC++ClientLibraryBindings 2.0 API Documentation
libmapipp::message Member List

This is the complete list of members for libmapipp::message, including all inherited members.

data()libmapipp::objectinlinevirtual
fetch_attachments()libmapipp::message
get_folder_id() const libmapipp::messageinline
get_id() const libmapipp::messageinline
get_property_container()libmapipp::objectvirtual
get_session()libmapipp::objectinlinevirtual
message(session &mapi_session, const mapi_id_t folder_id, const mapi_id_t message_id)libmapipp::messageinline
object(session &mapi_session, const std::string &object_type="")libmapipp::objectinlineexplicit
~message()libmapipp::messageinlinevirtual
~object()libmapipp::objectinlinevirtual

Creative Commons License
Creative Commons Attribution icon Creative Commons Share Alike icon
This content is licensed under the Creative Commons
Attribution ShareAlike License v. 3.0:
http://creativecommons.org/licenses/by-sa/3.0/

openchange-2.0/apidocs/html/libmapi++/classlibmapipp_1_1message.html000066400000000000000000000305061223057412600255170ustar00rootroot00000000000000 MAPIC++ClientLibraryBindings 2.0 API Documentation
libmapipp::message Class Reference

This class represents a message in Exchange. More...

#include <message.h>

Inheritance diagram for libmapipp::message:
libmapipp::object

Public Member Functions

attachment_container_type fetch_attachments ()
 Fetches all attachments in this message.
mapi_id_t get_folder_id () const
 Get this message's parent folder ID.
mapi_id_t get_id () const
 Get this message's ID.
 message (session &mapi_session, const mapi_id_t folder_id, const mapi_id_t message_id) throw (mapi_exception)
 Constructor.
virtual ~message () throw ()
 Destructor.
- Public Member Functions inherited from libmapipp::object
virtual mapi_object_t & data () throw ()
 Obtain a reference to the mapi_object_t associated with this object.
virtual property_container get_property_container ()
 Obtain a property_container to be used with this object.
virtual sessionget_session ()
 Obtain the session associated with this object.
 object (session &mapi_session, const std::string &object_type="") throw ()
 Object Constructor.
virtual ~object () throw ()
 Destructor.

Detailed Description

This class represents a message in Exchange.

It is important to note that a message is not necessarily an email message. It could be a contact, journal or anything else that is not a folder.

Examples:
attach_test.cpp.

Constructor & Destructor Documentation

libmapipp::message::message ( session mapi_session,
const mapi_id_t  folder_id,
const mapi_id_t  message_id 
) throw (mapi_exception)
inline

Constructor.

Parameters
mapi_sessionThe session to use to retrieve this message.
folder_idThe id of the folder this message belongs to.
message_idThe message id.

Member Function Documentation

attachment_container_type libmapipp::message::fetch_attachments ( )

Fetches all attachments in this message.

Returns
A container of attachment shared pointers.
Examples:
attach_test.cpp.

The documentation for this class was generated from the following file:
  • libmapi++/message.h

Creative Commons License
Creative Commons Attribution icon Creative Commons Share Alike icon
This content is licensed under the Creative Commons
Attribution ShareAlike License v. 3.0:
http://creativecommons.org/licenses/by-sa/3.0/

openchange-2.0/apidocs/html/libmapi++/classlibmapipp_1_1message.png000066400000000000000000000010301223057412600253250ustar00rootroot00000000000000‰PNG  IHDRxPåEA»PLTEÿÿÿèìõuÂÀÀÀ‰ÜtRNSÿÿÿÿÿÿÿÕÊT2§IDATxíí’³ FOÂLïÿ’×*ò¥QÖ·vÞ2ÍS*&I"ýK!ŒAUÕ_¬ªê¢?–ÝTU uÝ=85'àÛ¥UUmY±÷àÕäí· 1@öëm(ŠõZ§8± ñ÷8 o‹«äéÒAE³æš¡«ÆU|»D½fÎ¥åÔŸjU)ì¨àõ|µ™ë›m~]c»|ÕPƒÿ­Æ¹}S®ŸÓ®.œÌ®®úÿ·'WµN‰ÞSæ?ßž}óßIUÕE_ !„x¬À¿^ƒÈ£À w yø »z‚|4Á.š`M0€‹&ÀE ࢠpÑtKDd„M0€‹Æƒ—a3CŸ|Æüá¥lv¼¼`qv½ñ~áŠéÂ!?cëïíßûÅ—ÂZp6Ï— ‘rqÞ …Õ‘™w¨q”®¹,'”ªj§awàõpëoÞmªËÌ¥\߀kNÏŽ›V=,`5—@cW56Sý Æ¹}S®ŸÓ®(ÍêêØ€ç] `ªÍá£÷½ŽqW=áºãœãùï੯‹ˆ ДäúoeyIEND®B`‚openchange-2.0/apidocs/html/libmapi++/classlibmapipp_1_1message__store-members.html000066400000000000000000000111741223057412600305220ustar00rootroot00000000000000 MAPIC++ClientLibraryBindings 2.0 API Documentation
libmapipp::message_store Member List

This is the complete list of members for libmapipp::message_store, including all inherited members.

data()libmapipp::objectinlinevirtual
get_default_folder(const uint32_t id) const libmapipp::message_storeinline
get_property_container()libmapipp::objectvirtual
get_session()libmapipp::objectinlinevirtual
object(session &mapi_session, const std::string &object_type="")libmapipp::objectinlineexplicit
~object()libmapipp::objectinlinevirtual

Creative Commons License
Creative Commons Attribution icon Creative Commons Share Alike icon
This content is licensed under the Creative Commons
Attribution ShareAlike License v. 3.0:
http://creativecommons.org/licenses/by-sa/3.0/

openchange-2.0/apidocs/html/libmapi++/classlibmapipp_1_1message__store.html000066400000000000000000000255241223057412600270760ustar00rootroot00000000000000 MAPIC++ClientLibraryBindings 2.0 API Documentation
libmapipp::message_store Class Reference

This class represents the Message Store in Exchange. More...

#include <message_store.h>

Inheritance diagram for libmapipp::message_store:
libmapipp::object

Public Member Functions

mapi_id_t get_default_folder (const uint32_t id) const throw (mapi_exception)
 Retrieves the folder id for the specified default folder in the Message Store.
- Public Member Functions inherited from libmapipp::object
virtual mapi_object_t & data () throw ()
 Obtain a reference to the mapi_object_t associated with this object.
virtual property_container get_property_container ()
 Obtain a property_container to be used with this object.
virtual sessionget_session ()
 Obtain the session associated with this object.
 object (session &mapi_session, const std::string &object_type="") throw ()
 Object Constructor.
virtual ~object () throw ()
 Destructor.

Detailed Description

This class represents the Message Store in Exchange.

The message_store is the grouping of message folders (which could be the users private store including mail, calendar, todo list, journal, contacts and so on) or could be the public store (e.g. shared public folders).

It is not possible for you, the user, to create a message_store object. Instead, you should retrieve the message_store associated with a session using session::get_message_store()

Examples:
foldertree.cpp, and messages.cpp.

Member Function Documentation

mapi_id_t libmapipp::message_store::get_default_folder ( const uint32_t  id) const throw (mapi_exception)
inline

Retrieves the folder id for the specified default folder in the Message Store.

Parameters
idThe type of folder to search for.

The following types of folders are supported:

  • olFolderTopInformationStore
  • olFolderDeletedItems
  • olFolderOutbox
  • olFolderSentMail
  • olFolderInbox
  • olFolderCalendar
  • olFolderContacts
  • olFolderJournal
  • olFolderNotes
  • olFolderTasks
  • olFolderDrafts

If you are trying to enumerate all folders, you should open the olFolderTopInformationStore, and then get the hierarchy container for that top level folder.

Returns
The resulting folder id.
Examples:
attach_test.cpp, foldertree.cpp, messages.cpp, and test.cpp.

The documentation for this class was generated from the following file:
  • libmapi++/message_store.h

Creative Commons License
Creative Commons Attribution icon Creative Commons Share Alike icon
This content is licensed under the Creative Commons
Attribution ShareAlike License v. 3.0:
http://creativecommons.org/licenses/by-sa/3.0/

openchange-2.0/apidocs/html/libmapi++/classlibmapipp_1_1message__store.png000066400000000000000000000011731223057412600267100ustar00rootroot00000000000000‰PNG  IHDR›P9÷ÉPLTEÿÿÿèìõuÂÀÀÀ‰ÜtRNSÿÿÿÿÿÿÿÕÊT2 IDATxíÙrã E—*ÿÿ' ™ÖØRÓqßáNz¯Äã¤"JÒ”r6I²ËÙ$É®÷la3IêhèÛƒÓõªA¶}$©§ÞÚ°% ¯­žÃºgØž—¡p(ŽlÖ‰eXÿ–¤s ³íÃËÖƒòté  l‡¹f¤ž,õVÑžR›“ÖsúhN¥PØ+#7Øòª/²]…ä:n+©4k½õK©j¶¯×[nȽãÒç´O §nŸV-I­þò^È»¿Ï“ùél÷n–ß}×KÒ¿‘³I’]“³Åãœøœ“jb¶Çc^¸‰ÙžhÓÂÍÌæ} pGÎ`—³Øålv9€]Î`—³Øålv9€]Î`—³ØålvýGl!„0©SÊÙìr6»v¶ç°@G_ù7ú›–lß: ¯1¶dÏ·Ê:›¾x½eŠéÂ!ïÙz¯ßm¿·‡´®X¶x¤™Í)m´»´lû°l¶íϹ Þ «WqjZ—“z«–ìχ|È È ÃaYö @«¶tu ³-ÞmNËøWIÍ…RÆnwyÃV/‰ÛyHªˆÖp·ëzkQ:õÖÍéÍz{“Ó"Î[c¥ÏiŸ(­×§k¿œöinׇֺï…6Y·Þƒæ5?ÄV×çòp©ŸŠÛ PÙ¯¸ë&“³Ø59[!Ì©?g!JŠP—4IEND®B`‚openchange-2.0/apidocs/html/libmapi++/classlibmapipp_1_1object-members.html000066400000000000000000000104001223057412600267600ustar00rootroot00000000000000 MAPIC++ClientLibraryBindings 2.0 API Documentation
libmapipp::object Member List

This is the complete list of members for libmapipp::object, including all inherited members.

data()libmapipp::objectinlinevirtual
get_property_container()libmapipp::objectvirtual
get_session()libmapipp::objectinlinevirtual
object(session &mapi_session, const std::string &object_type="")libmapipp::objectinlineexplicit
~object()libmapipp::objectinlinevirtual

Creative Commons License
Creative Commons Attribution icon Creative Commons Share Alike icon
This content is licensed under the Creative Commons
Attribution ShareAlike License v. 3.0:
http://creativecommons.org/licenses/by-sa/3.0/

openchange-2.0/apidocs/html/libmapi++/classlibmapipp_1_1object.html000066400000000000000000000307351223057412600253450ustar00rootroot00000000000000 MAPIC++ClientLibraryBindings 2.0 API Documentation
libmapipp::object Class Reference

Base Object class. More...

#include <object.h>

Inheritance diagram for libmapipp::object:
libmapipp::attachment libmapipp::folder libmapipp::message libmapipp::message_store

Public Member Functions

virtual mapi_object_t & data () throw ()
 Obtain a reference to the mapi_object_t associated with this object.
virtual property_container get_property_container ()
 Obtain a property_container to be used with this object.
virtual sessionget_session ()
 Obtain the session associated with this object.
 object (session &mapi_session, const std::string &object_type="") throw ()
 Object Constructor.
virtual ~object () throw ()
 Destructor.

Detailed Description

Base Object class.

Most classes such as folder, message and message_store derive from this class. It is important that objects be passed around as references and that no unnecessary copies are made as this will call the class destructor which will call mapi_object_release() and release the handle associated with this object.

Constructor & Destructor Documentation

libmapipp::object::object ( session mapi_session,
const std::string &  object_type = "" 
) throw ()
inlineexplicit

Object Constructor.

Parameters
mapi_sessionSession this object is to be associated with.
object_typeThe name of the type of object (to be set in a subclass)
virtual libmapipp::object::~object ( ) throw ()
inlinevirtual

Destructor.

Calls mapi_object_release() which releases the handle associated with this object.

Member Function Documentation

virtual mapi_object_t& libmapipp::object::data ( ) throw ()
inlinevirtual

Obtain a reference to the mapi_object_t associated with this object.

Returns
A reference to the C struct mapi_object_t associated with this object
virtual property_container libmapipp::object::get_property_container ( )
virtual

Obtain a property_container to be used with this object.

Returns
A property_container to be used with this object.
Examples:
attach_test.cpp, foldertree.cpp, and test.cpp.
virtual session& libmapipp::object::get_session ( )
inlinevirtual

Obtain the session associated with this object.

Returns
The session associated with this object

The documentation for this class was generated from the following file:
  • libmapi++/object.h

Creative Commons License
Creative Commons Attribution icon Creative Commons Share Alike icon
This content is licensed under the Creative Commons
Attribution ShareAlike License v. 3.0:
http://creativecommons.org/licenses/by-sa/3.0/

openchange-2.0/apidocs/html/libmapi++/classlibmapipp_1_1object.png000066400000000000000000000025071223057412600251610ustar00rootroot00000000000000‰PNG  IHDRŠP©¤ÞPLTEÿÿÿèìõuÂÀÀÀ‰ÜtRNSÿÿÿÿÿÿÿÕÊT2ÖIDATxím“ª8›¦Êÿÿ“W¯Œ„7LÜòÙJo4ð¹¡çä+À7Òu]÷¡€ïàs_xTø"¢"@8™¨N&*€“‰Šàd~{á×ë÷°Á®«‹¢¿ ¾}BÔh±uoT‡»bw+¼NÃÝÏ÷ûTœ ÷iø °NTø"vªø˜ncðj\. èÇbm6l¾ˆ½]ºbŒWV-½U” 4Pñz¼¾ âxWTõ*>kxÏ»âXÂQ;˜Ùòdšª¸-0À&Qà‹ØÛoBMèÛb±<|*êþ•kÃÂÏú/?¾ˆª>Þüû¡{ø‡¢"ÀÀÉü•ŠÇ'*|Ÿû£"ÀÀÉDE€p2Q œLT'Óu]÷¡€pˆ @çÀ¹\.q œJTçr51.€3‰Šàt""@8™¨N&*€“‰Šàd¢"@8™¨N&*€“‰Šàd¢"@8™¨ðY\.—K¸\.—ïàCù_´‡„hAT¨ !Z*HH€DE€  Q ‚„hAT¨ !Z*HH€DE€  Q ‚„hAT¨ !Z*HH€DE€  Q ‚„hAT¨ !Z*HH€4Ù÷}ߌKß÷}3²ïû¾ÿ½êGRn êG’ª-ˆŠª$¤j ¢¢j ©Ú‚¨¨ZABª¶ *ªVª-XU±ûªüzuQpøy6°&q÷¸0|xþµ;BÖo§j ˧eÚ~è–Š•INPñÕÄÅMïSñí²©n³ªâ9™Ž«øoüë×ix@÷óý>åë¼}¹þïg^¹qíyC¥:ŽºâñÄCÉOÅíʸp”ê&ºâ Û9¯®•Û:K¬º`»+þe¦Ç{.7w,y¦âcº?ø'Ý£·vŽÃÎq¬Ü¸ùЦw¬©8ž:õ*îI¼®âýηª¸3Üd³æ‡á2±ê‚Ý*¾5Óxê—ñQr@ÅE{òbWþlVŸ7YV'£ZÅ#‰W#¿SŽá&›µÒ\¶÷︊ïÎ4; §üLÅNgc¶<™ž«¸çß­NÆq;݉Ë?ö÷ÐÎÆ®p›ÒK/ÐÎÆû2Í‹ÐEGšém±X>M:ï½è¾xÿòoZ? Šåå>¾Ð_Hüs®IÅI¦kß»ý§ú”¨¨ZÁù]qÇkþó®¸G=u2Ž«¨ú7´RQõm$¤j ¢¢j ©Ú‚¨¨ZABª¶ *ªVª-ˆŠª$¤j ®*ö}ß&Åö}ß& Ù÷}ß‚ÿ½u…>Ùõ‰ÖIEND®B`‚openchange-2.0/apidocs/html/libmapi++/classlibmapipp_1_1profile__database-members.html000066400000000000000000000113761223057412600311520ustar00rootroot00000000000000 MAPIC++ClientLibraryBindings 2.0 API Documentation
libmapipp::profile_database Member List

This is the complete list of members for libmapipp::profile_database, including all inherited members.

create_profile_store(const std::string &profiledb, const std::string &ldif_path="")libmapipp::profile_databasestatic
get_default_profile_name()libmapipp::profile_database
get_default_profile_path()libmapipp::profile_databasestatic
profile_database(const std::string &profiledb_path="")libmapipp::profile_databaseexplicit
set_default(const char *profname)libmapipp::profile_databaseinline
set_default(const std::string &profname)libmapipp::profile_databaseinline

Creative Commons License
Creative Commons Attribution icon Creative Commons Share Alike icon
This content is licensed under the Creative Commons
Attribution ShareAlike License v. 3.0:
http://creativecommons.org/licenses/by-sa/3.0/

openchange-2.0/apidocs/html/libmapi++/classlibmapipp_1_1profile__database.html000066400000000000000000000313261223057412600275170ustar00rootroot00000000000000 MAPIC++ClientLibraryBindings 2.0 API Documentation
libmapipp::profile_database Class Reference

This class represents a user profile database. More...

#include <profile.h>

Public Member Functions

std::string get_default_profile_name () throw (mapi_exception)
 Get the default profile name.
 profile_database (const std::string &profiledb_path="") throw (std::runtime_error, mapi_exception)
 Constructor.
bool set_default (const char *profname)
 Make the specified profile the default profile.
bool set_default (const std::string &profname)
 Make the specified profile the default profile.

Static Public Member Functions

static bool create_profile_store (const std::string &profiledb, const std::string &ldif_path="")
 Create an new profile database.
static std::string get_default_profile_path ()
 The path to the default profile database.

Detailed Description

This class represents a user profile database.

Todo:

possibly rename profile class to profile_database?

we should be able to create a profile using libmapi++ classes

we should be able to delete a profile using libmapi++ classes

maybe move some of the session.h documentation on profiles to profile.h?

Constructor & Destructor Documentation

libmapipp::profile_database::profile_database ( const std::string &  profiledb_path = "") throw (std::runtime_error, mapi_exception)
explicit

Constructor.

Parameters
profiledb_pathAn absolute path specifying the location of the profile database. If not specified (or "" is specified) the default location will be used (~/.openchange.profiles.ldb).

Member Function Documentation

static bool libmapipp::profile_database::create_profile_store ( const std::string &  profiledb,
const std::string &  ldif_path = "" 
)
static

Create an new profile database.

Parameters
profiledbthe absolute path to the profile database intended to be created
ldif_paththe absolute path to the LDIF information to use for initial setup
std::string libmapipp::profile_database::get_default_profile_name ( ) throw (mapi_exception)

Get the default profile name.

Returns
the name of the default profile
static std::string libmapipp::profile_database::get_default_profile_path ( )
static

The path to the default profile database.

This method is not normally required to be called by user applications but might be useful under some circumstances.

bool libmapipp::profile_database::set_default ( const char *  profname)
inline

Make the specified profile the default profile.

Parameters
profnamethe name of the profile to make default
bool libmapipp::profile_database::set_default ( const std::string &  profname)
inline

Make the specified profile the default profile.

Parameters
profnamethe name of the profile to make default

The documentation for this class was generated from the following file:
  • libmapi++/profile.h

Creative Commons License
Creative Commons Attribution icon Creative Commons Share Alike icon
This content is licensed under the Creative Commons
Attribution ShareAlike License v. 3.0:
http://creativecommons.org/licenses/by-sa/3.0/

openchange-2.0/apidocs/html/libmapi++/classlibmapipp_1_1property__container-members.html000066400000000000000000000120571223057412600316110ustar00rootroot00000000000000 MAPIC++ClientLibraryBindings 2.0 API Documentation
libmapipp::property_container Member List

This is the complete list of members for libmapipp::property_container, including all inherited members.

fetch()libmapipp::property_containerinline
fetch_all()libmapipp::property_containerinline
operator<<(uint32_t property_tag)libmapipp::property_containerinline
operator[](uint32_t property_tag)libmapipp::property_containerinline
property_container(TALLOC_CTX *memory_ctx, mapi_object_t &mapi_object)libmapipp::property_containerinline
size() const libmapipp::property_containerinline
~property_container()libmapipp::property_containerinline

Creative Commons License
Creative Commons Attribution icon Creative Commons Share Alike icon
This content is licensed under the Creative Commons
Attribution ShareAlike License v. 3.0:
http://creativecommons.org/licenses/by-sa/3.0/

openchange-2.0/apidocs/html/libmapi++/classlibmapipp_1_1property__container.html000066400000000000000000000230751223057412600301630ustar00rootroot00000000000000 MAPIC++ClientLibraryBindings 2.0 API Documentation
libmapipp::property_container Class Reference

A container of properties to be used with classes derived from object. More...

#include <property_container.h>

Public Member Functions

uint32_t fetch ()
 Fetches properties with the tags supplied using operator<<.
void fetch_all ()
 Fetches ALL properties of the object associated with this container.
property_containeroperator<< (uint32_t property_tag)
 Adds a Property Tag to be fetched by fetch().
const void * operator[] (uint32_t property_tag)
 Finds the property value associated with a property tag.
 property_container (TALLOC_CTX *memory_ctx, mapi_object_t &mapi_object)
 Constructor.
size_t size () const
 Get number of properties in container.
 ~property_container ()
 Destructor.

Detailed Description

A container of properties to be used with classes derived from object.

Examples:
attach_test.cpp, foldertree.cpp, messages.cpp, and test.cpp.

Member Function Documentation

uint32_t libmapipp::property_container::fetch ( )
inline

Fetches properties with the tags supplied using operator<<.

Returns
The number of objects that were fetched.
Examples:
attach_test.cpp, foldertree.cpp, messages.cpp, and test.cpp.
const void* libmapipp::property_container::operator[] ( uint32_t  property_tag)
inline

Finds the property value associated with a property tag.

Parameters
property_tagThe Property Tag to be searched for
Returns
Property Value as a const void pointer

The documentation for this class was generated from the following file:
  • libmapi++/property_container.h

Creative Commons License
Creative Commons Attribution icon Creative Commons Share Alike icon
This content is licensed under the Creative Commons
Attribution ShareAlike License v. 3.0:
http://creativecommons.org/licenses/by-sa/3.0/

openchange-2.0/apidocs/html/libmapi++/classlibmapipp_1_1property__container__iterator-members.html000066400000000000000000000132221223057412600336540ustar00rootroot00000000000000 MAPIC++ClientLibraryBindings 2.0 API Documentation openchange-2.0/apidocs/html/libmapi++/classlibmapipp_1_1property__container__iterator.html000066400000000000000000000247521223057412600322360ustar00rootroot00000000000000 MAPIC++ClientLibraryBindings 2.0 API Documentation
libmapipp::property_container_iterator Class Reference

Iterator to use with Property Container. More...

#include <property_container.h>

Public Member Functions

int get_tag ()
 Get Property Tag of the Property Value this operator points to.
int get_type ()
 Get Property Tag Type.
bool operator!= (const property_container_iterator &rhs) const
 operator!=
const void * operator* ()
 operator*
property_container_iteratoroperator++ ()
 operator++
property_container_iterator operator++ (int postfix)
 operator++ postfix
bool operator== (const property_container_iterator &rhs) const
 operator==
 property_container_iterator ()
 Default Constructor. Creates an invalid iterator.

Detailed Description

Iterator to use with Property Container.

Examples:
test.cpp.

Member Function Documentation

int libmapipp::property_container_iterator::get_tag ( )
inline

Get Property Tag of the Property Value this operator points to.

Returns
Property Tag of Property this iterator points to or MAPI_PROP_RESERVED if this is an invalid iterator.
int libmapipp::property_container_iterator::get_type ( )
inline

Get Property Tag Type.

Returns
Type of property this iterator points to or MAPI_PROP_RESERVED if this is an invalid iterator. Valid Types are:
  • PT_BOOLEAN
  • PT_I2
  • PT_LONG
  • PT_DOUBLE
  • PT_I8
  • PT_SYSTIME
  • PT_ERROR
  • PT_STRING8
  • PT_UNICODE
  • PT_BINARY
  • PT_CLSID
  • PT_ERROR
  • PT_MV_SHORT
  • PT_MV_LONG
  • PT_MV_STRING8
  • PT_MV_BINARY
  • PT_MV_CLSID
  • PT_MV_UNICODE
  • PT_MV_SYSTIME
  • PT_NULL
  • PT_OBJECT
const void* libmapipp::property_container_iterator::operator* ( )
inline

operator*

Returns
The property value as a void pointer.

The documentation for this class was generated from the following file:
  • libmapi++/property_container.h

Creative Commons License
Creative Commons Attribution icon Creative Commons Share Alike icon
This content is licensed under the Creative Commons
Attribution ShareAlike License v. 3.0:
http://creativecommons.org/licenses/by-sa/3.0/

openchange-2.0/apidocs/html/libmapi++/classlibmapipp_1_1session-members.html000066400000000000000000000114461223057412600272100ustar00rootroot00000000000000 MAPIC++ClientLibraryBindings 2.0 API Documentation
libmapipp::session Member List

This is the complete list of members for libmapipp::session, including all inherited members.

get_mapi_session()libmapipp::sessioninline
get_memory_ctx()libmapipp::sessioninline
get_message_store()libmapipp::sessioninline
get_profile_name() const libmapipp::sessioninline
login(const std::string &profile_name="", const std::string &password="")libmapipp::session
session(const std::string &profiledb="", const bool debug=false)libmapipp::sessionexplicit
~session()libmapipp::sessioninline

Creative Commons License
Creative Commons Attribution icon Creative Commons Share Alike icon
This content is licensed under the Creative Commons
Attribution ShareAlike License v. 3.0:
http://creativecommons.org/licenses/by-sa/3.0/

openchange-2.0/apidocs/html/libmapi++/classlibmapipp_1_1session.html000066400000000000000000000366211223057412600255620ustar00rootroot00000000000000 MAPIC++ClientLibraryBindings 2.0 API Documentation
libmapipp::session Class Reference

This class represents a MAPI session with the Exchange Server. More...

#include <session.h>

Public Member Functions

mapi_session * get_mapi_session () throw ()
 The underlying mapi_session.
TALLOC_CTX * get_memory_ctx () throw ()
 Obtain a talloc memory context for this session.
message_storeget_message_store () throw ()
 Obtain a reference to the message_store associated with this session.
std::string get_profile_name () const
 The name of the profile that is in use.
void login (const std::string &profile_name="", const std::string &password="") throw (mapi_exception)
 Log-in to the Exchange Server.
 session (const std::string &profiledb="", const bool debug=false) throw (std::runtime_error, mapi_exception)
 Constructor.
 ~session ()
 Uninitialize and clean up the MAPI session.

Detailed Description

This class represents a MAPI session with the Exchange Server.

The session is best thought of as the connection by a single user to a single server. It is possible to have multiple sessions open at the same time.

A key concept in the session is that of a profile, and the profile database. The profile is a pre-established data set that specifies the server information (e.g. server name / IP address, and Exchange domain) and client information (e.g. the user name, preferred language, and optionally the users password). The profiles are stored in a local store (Samba LDB database) known as the profile store or profile database. One of the profiles in the profile database can be designated as the default profile (which is particularly useful given that most users may only have one). See the profile class documentation for more information.

The general concept is that you create a session object, log in to the session using a selected profile name, and then work with the message_store associated with that session. The message_store is only valid so long as the session is valid.

Examples:
attach_test.cpp, foldertree.cpp, messages.cpp, and test.cpp.

Constructor & Destructor Documentation

libmapipp::session::session ( const std::string &  profiledb = "",
const bool  debug = false 
) throw (std::runtime_error, mapi_exception)
explicit

Constructor.

Parameters
profiledbAn absolute path specifying the location of the profile database. If not specified (or "" is specified) the default location will be used (~/.openchange.profiles.ldb).
debugWhether to output debug information to stdout

Member Function Documentation

mapi_session* libmapipp::session::get_mapi_session ( ) throw ()
inline

The underlying mapi_session.

Exposing this is temporary. Maybe be removed when we sort it out

TALLOC_CTX* libmapipp::session::get_memory_ctx ( ) throw ()
inline

Obtain a talloc memory context for this session.

This pointer can be used for subsequent memory allocations, and these will be cleaned up when the session is terminated.

message_store& libmapipp::session::get_message_store ( ) throw ()
inline

Obtain a reference to the message_store associated with this session.

Returns
The message_store associated with this session.
Examples:
attach_test.cpp, foldertree.cpp, messages.cpp, and test.cpp.
std::string libmapipp::session::get_profile_name ( ) const
inline

The name of the profile that is in use.

Calling this method only makes sense if login() has been called with this session object.

void libmapipp::session::login ( const std::string &  profile_name = "",
const std::string &  password = "" 
) throw (mapi_exception)

Log-in to the Exchange Server.

Parameters
profile_nameThe name of the profile to use to login with. If not specified (or "" is specified), then the default profile will be used.
passwordThe password to use to login with. It is possible to omit this if the password is stored in the profile database.
Examples:
attach_test.cpp, foldertree.cpp, messages.cpp, and test.cpp.

The documentation for this class was generated from the following file:
  • libmapi++/session.h

Creative Commons License
Creative Commons Attribution icon Creative Commons Share Alike icon
This content is licensed under the Creative Commons
Attribution ShareAlike License v. 3.0:
http://creativecommons.org/licenses/by-sa/3.0/

openchange-2.0/apidocs/html/libmapi++/closed.png000066400000000000000000000002041223057412600215700ustar00rootroot00000000000000‰PNG  IHDR à‘KIDATxíÝm @!†ÑGk™É7À-`&séts¦Àñþòð@åk}ª2€… P%Á_Ëþ¿N² .:0Dk¥‹Â›x" Ö›)¡xÒ5õIEND®B`‚openchange-2.0/apidocs/html/libmapi++/dir_d3109a7ed4c314538f27e0b8aec22e81.html000066400000000000000000000105771223057412600257240ustar00rootroot00000000000000 MAPIC++ClientLibraryBindings 2.0 API Documentation
libmapi++ Directory Reference

Files

file  attachment.h
file  clibmapi.h
file  folder.h
file  libmapi++-example.doxy
file  libmapi++-mainpage.doxy
file  libmapi++.h
file  mapi_exception.h
file  message.h
file  message_store.h
file  object.h
file  profile.h
file  property_container.h
file  session.h

Creative Commons License
Creative Commons Attribution icon Creative Commons Share Alike icon
This content is licensed under the Creative Commons
Attribution ShareAlike License v. 3.0:
http://creativecommons.org/licenses/by-sa/3.0/

openchange-2.0/apidocs/html/libmapi++/doxygen.png000066400000000000000000000073031223057412600220030ustar00rootroot00000000000000‰PNG  IHDRh ;ˆØŠIDATxí]y\•Õº~45%TL Q”PE"q–Û11±]8a„w*©¨(*â" ˆzÀè`8 ¨‰¢mÅ,’òà„p$%”œBó(8k†Ü÷ýÜû6lòö»§k÷Ç÷[ÏÞß·Ö;?k½ëßÕÕÕPxÑêÏ't´ÏùÈ€zÀÇÅ3_€Q4€g@œmÿ ¾ò‰âci‰ôçÿ{ ðÇð¬ù~½Á€4:õHcÂü ðŸÁ³„ª'ÕPÆæ P7^h،♠zb„cóP¨„ 3‚† Ò}çÿO²qÁºNkÝTÛ(É?d Ç~z<’«4Óǡ؞Þv­zµÙ¦õ¬ZâdÛ,Ë6Ók±]Fz< ¾ZçƒsÕ?ìƒsUø2SÉåwê1”c`[ì—}%ѽ.Ô¼6‚BLZ˜û!F8[ ¹…×TéÛ— »Þ#gó]å:vžu?‡vèbÙR˜?wùŽŸ¾ÊÐgbÑÉÌÕ$kF~Ê;عÆ•¢ïX®?ÉèlÆÙôõà»Nʪ¼­,ìHC§gAz•ÆlÓº­gÑú ]œjÎñåM…3ÓÚæoÒ³'=‘$Ò÷f}G•ŸS_‡öèco.Êȹ :ó£ Ãds®Ù:1=¼{ƒå9?÷ý…zqÛvîÓi‰D’p¿Ë šmÙíoÛâýaÖüEqÒµwÌ}¿~{òj€ç{ôºŸFNëí[ëOq·ÇOSúXO]°>‚‚muæÄ¾e¤“5Ë{¨JÕ¯£(›´«bÂçû’ÍlÓÅ}žïú`éUÞy„ac§Á†ÔCºŠóAkl‘±y¥†ô¢ùôs÷Aø¬7ÄõôoJ±äÄ ù.¥Be. Z¬Ð×ÇÈöå¹­ù'Ù-PëìŠyF.ž‚žÝÚ€lp&.êˆð•jò7’re’z19»ã§HGíø%œüq°ïüz׈c¬_k_")ŸHJnÐÑ~ˆÐÖ˜á´äÕ5 µÁq€ÿ5#¸·îà¶+9T‘‚ ðŽ÷Rܸrz“Ï´Ì =Ï…{ðáO£Èf ¡Íwg|Ž’Ü/¢Þ$÷¯¢ëðúÀ;¿à¨Ö™âÒÆ­]¯ÜW"Þ/< ‡÷DÏà°½üB}çyIEc^—ƒ=[V“Ýh²ëMä$l];Kû®¸ýr¦È*Åò ÿtÒõ$]•MŸ÷´;×I€1èó!‚œõ¸M õ¨(fÌæ<ÁÎÎò5~z¿ù¶ž mÌêÕ >–âÚ©âëˆIÎÞçz;ãu[i·eç^ÆÜÙÓ³NÞëF6B\}7†»+üŽÓ,Ã'a ½˜-yHY¿,‘^—ñfú~ß?Hcø¸…¸ñó{Z+4\såƒû·¯Ù·nߣð«íFÆ¡sغëû§D¾?ò<–Ævkx0ÅM±ælذÁIÓxÿd”žÜÉ÷EE»AªM«g*È£YEí7Û™^[uíý®v[wGå†=Ed¼n×¶ÆæÖÅl¡'¨pGÚk+‹æ¢À¬¨C8ªâš2 dz3H£ß ¡¨BÒûSÃÅù[wŘ ~xpçútÁæmö¤Å£¥iQæ­‰AB1ÉfÙ‰›4u¹ïìIÒ]Ë6äò%ÿ†† 1t.’NJph¬zÌ ÎR1Ž"3-"¸‡‹&ìó°1âüžìó[:‡ï„¼‘……N m–“W0®_èÜœ ×õ6ùò&»)Æìꦬýæ}¬ñ~»{múù]z½£M•ºP~^Îá:eQTÙ_*7ÕÄ9É8—·Ëï 3°¶47E•î¿u÷“SÉ»U¯ _ NíºôW¬e¸ÄNÓ|»;™¿;ŒæÅd"ȉôøòÞµõï¾®½"èÄ´ÖMM+bYµ‘_ÉæEÝüÎ]P»¹XKÐI½Þ¥oE<_¹(„EP±Œ|mÇÁ¡‘Ý,ŠÓ©ººZ±Îߺ§×kÝ,kÍMš`Äø…jzeU»æ ™Át3ÓÀ½˜6—ÒöùË·r¨¹Ñ}““wö:Χùë¼ ¿|‚TܵÉQˆKßç_ÁâÀ™œ”pÑÐóໃ¼Ydâ0!®àa –øöçW$ÃÁ‘Á$/\¬$ð 2ÞímÞLH‹Ÿ èd£HVÜ,:ò½»RÍZšJ­a„z*>‹_…NT(ù‚^SVF­U¹8ñEþôñ܈óùnd;«®8™\C]ø=Èêm¬Æ:‚´ÆbãDd=Áãßžˆ‹UU5O‹|]þð®Pèêv‰á\]2ßìÿ"yÈ[ïyʧz£g{Y«{„Ùø5©ÿ;w{N3é­nâĨw§Á¢ÍK¢Ý­ûÏ29Id¿’ì y)ìPÞò8ŒÅ©¯‰±@mPÔñwjl,6 áhWÕ˜d öà uõmÁp®.™á£Ç…twöR x­BδYcŒxg*vo  yò‘•“[¬?ÜVœ˜0ÒN¡O난~Žó’¯·h#´Hkýœ±8kÓß^Àq@]àÓ“ø,56´¯÷Í-κU»n…[>]@nîøÏœp›[œ6# €4tën¯:ŽÒþ}…—8äT9_žY$/´G’K™©ù†•(óÑ’Mø©`ŸÉdѺ;ùO‹B Ó&P{qöhJÉ+Úé–§¦l2«MïöÝ_1ÑÓ«’t¸½±l€ëØya ¦ô©«®½ÆL^¬žêñš¸ùy.¾Û½Š[ u/]½‹iS}øN>²e1™q‡jfÚ&¢©iT\=kÏ›ÀXô-.84V5ðu!TE˜ þ.ŒOH´¶4—zwTr.ï‰¦Ë xõµ·œÖ„HÆù£žÈHùg Ñhñ’T$ßyq¸zþ¨p¿´ë< q•ró÷š‰wÿÍÑð–I]´–æI²é²˜sÂ"×:Õ–bÕ¦“ÈÙL6¢9VÊÓWž§<æ;”3?ý©Mê3AV#µ±ËÞ¯‘ž K£UrÝ9!›qát¦H£Ù+6ÇV…/TS^pÃùqgLP'Ú5E ‚–ÀÞºîÄ Ën"2|Ÿ;®W»Îý"Ö¬TwÖâµtúŽO'› á+W Ã+¦âZÌ–<ÕÆ&nOÝ,IŠ£06.ÁZ.Çñúøh*INÚ’Oe½ÉgBXÐÔZóäøä9èü“hÒíDSš¥¡Ê µA¯/Ôc¸ö“`A§¯"zå|‘ €ÅŸ¨ú;HÍ#‚Î|%ÄOˆƒ«OàÌÉÐÜD ž mÜðâc–ƤÉÂqm¶uË&~÷núÒË £ÇÏ€ZÕj =«_n[‡‡÷nN§ÏÝ$_¾bE˜‚€Õ)ù8¾?6‘lú“ÍÙæÖ}#bW( œ³d-®•p&¡ý’œÖa”"9öõņÐ$’Ú›AÜ!ä;ÐÑõè{~á¹8‘ÛÞ£1ÛÓÉ0ž`²#´kÒuäNÅÖ Q¹bhæ ”8ûÓMáŽa›•¿”w±h²¢®qŠæ°(bK ‚’Z¾Ò%ÐÆémáãÖË(Éý‚ÛJ)@> þ›7% ï{y Á“¾ÆÒîohfòô>{pÿ.­_Î%±ÉèägëlZØ\B2B #™¸ÚüÒºp‚hÝšü®[¥Ü<‹#SpñÌA7’ãØHƒt4:Ÿ|g¨tÓL¶*($Æ©»ì…®ù’ó÷$;b›ÔÙ`=¶£¦M„MÌÄ5ò«·Ç¾“H·ÌH.¼žHeAîº5}r­dõ¨±)ÀT};€Q5iÖ2…O0ü…0óñÃ;óæ,Š´²µ냔}g‘£]‹7å9ˆà©_{üèîêžC>úhê{Ž .ÈìðIIð€?[Kswz6Òuíý¬;µ€ç§OåâJÉa˶zv°éd† ¤µâ‚l´é舊«Åüy¾c÷ÁèÖÍ'ràúÅ™TWÕôÓ°¡L €|ʽŒ¼ì­høBã ÝTëî'ò]Kø£ìâÏ(=¹Kx €¿ LÌ,Pý¤Êµu‡¹…׈ §Å¾÷à1Ý«Äý;¿pGDäxZYÛ kfæ6¸ùóæ7®œ®þ6·ÕoÚ¾ÔH~ò®Þ¸â 8Uø“p<ºw3¡a£ÏÑ’‘3èÏ"€bˆ-ÎܺÏ_ªÅ]+ËM©zü°s“f-êçhÇãÑýÊãôÿ5}ZQNb{Ó?å%ÿ\SUõعIÓæ}~}p[œoÔÄ„êÐMMZáNÅå@>Œ„²á6(?¡Åé âK½+ü?À%ÝÝ·/Ç1‚9áUø?B)”ÕèâÞlÈÒêÏ @=àùÄÞžk­®ÅIEND®B`‚openchange-2.0/apidocs/html/libmapi++/dynsections.js000066400000000000000000000041341223057412600225170ustar00rootroot00000000000000function toggleVisibility(linkObj) { var base = $(linkObj).attr('id'); var summary = $('#'+base+'-summary'); var content = $('#'+base+'-content'); var trigger = $('#'+base+'-trigger'); var src=$(trigger).attr('src'); if (content.is(':visible')===true) { content.hide(); summary.show(); $(linkObj).addClass('closed').removeClass('opened'); $(trigger).attr('src',src.substring(0,src.length-8)+'closed.png'); } else { content.show(); summary.hide(); $(linkObj).removeClass('closed').addClass('opened'); $(trigger).attr('src',src.substring(0,src.length-10)+'open.png'); } return false; } function updateStripes() { $('table.directory tr'). removeClass('even').filter(':visible:even').addClass('even'); } function toggleLevel(level) { $('table.directory tr').each(function(){ var l = this.id.split('_').length-1; var i = $('#img'+this.id.substring(3)); var a = $('#arr'+this.id.substring(3)); if (l MAPIC++ClientLibraryBindings 2.0 API Documentation

Creative Commons License
Creative Commons Attribution icon Creative Commons Share Alike icon
This content is licensed under the Creative Commons
Attribution ShareAlike License v. 3.0:
http://creativecommons.org/licenses/by-sa/3.0/

openchange-2.0/apidocs/html/libmapi++/foldertree_8cpp-example.html000066400000000000000000000306241223057412600252260ustar00rootroot00000000000000 MAPIC++ClientLibraryBindings 2.0 API Documentation
foldertree.cpp
This example lists the top level folders in the message store,

with output like:

Message store display name: Mailbox - Test User1
|-----> Calendar (0 items, 0 unread)
|-----> Contacts (0 items, 0 unread)
|-----> Deleted Items (0 items, 0 unread)
|-----> Drafts (0 items, 0 unread)
|-----> Inbox (26 items, 24 unread)
|-----> Journal (0 items, 0 unread)
|-----> Notes (0 items, 0 unread)
|-----> Outbox (9 items, 0 unread)
|-----> Sent Items (0 items, 0 unread)
|-----> Tasks (0 items, 0 unread)

The example shows how to create a session, get the message_store, get properties of the message store, and then gets the list of child folders and some associated folder properties.

/*
libmapi C++ Wrapper
Sample folder tree list application
Copyright (C) Brad Hards <bradh@frogmouth.net> 2008.
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#include <exception>
#include <string>
#include <libmapi++/libmapi++.h>
int main ()
{
try {
// Initialize MAPI Session
libmapipp::session mapi_session;
// You could log in with a non-default profile here
mapi_session.login();
// Get the private (user) folders message store
libmapipp::message_store &msg_store = mapi_session.get_message_store();
// Get a property of the top level message store
msg_store_props << PR_DISPLAY_NAME; // you could use other properties here
msg_store_props.fetch();
// Display the property. You can also use a property_container_iterator
// to work through the properties, but in this case there is only one.
std::cout << "Message store display name: "
<< (const char*)msg_store_props[PR_DISPLAY_NAME]
<< std::endl;
// Fetch the folder list.
// We start off by fetching the top level folder
mapi_id_t top_folder_id = msg_store.get_default_folder(olFolderTopInformationStore);
libmapipp::folder top_folder(msg_store, top_folder_id);
// Now get the child folders of the top level folder. These are returned as
// a std::vector of pointers to folders
// Display the name, total item count and unread item count for each folder
for (unsigned int i = 0; i < child_folders.size(); ++i) {
libmapipp::property_container child_props = child_folders[i]->get_property_container();
child_props << PR_DISPLAY_NAME << PR_CONTENT_COUNT << PR_CONTENT_UNREAD;
child_props.fetch();
std::cout << "|-----> " << (const char*)child_props[PR_DISPLAY_NAME]
<< " (" << (*(int*)child_props[PR_CONTENT_COUNT]) << " items, "
<< (*(int*)child_props[PR_CONTENT_UNREAD]) << " unread)"
<< std::endl;
}
}
catch (libmapipp::mapi_exception e) // Catch any MAPI exceptions
{
std::cout << "MAPI Exception in main: " << e.what()
<< std::endl;
}
catch (std::runtime_error e) // Catch any other runtime exceptions
{
std::cout << "std::runtime_error exception in main: "
<< e.what() << std::endl;
}
return 0;
}

Creative Commons License
Creative Commons Attribution icon Creative Commons Share Alike icon
This content is licensed under the Creative Commons
Attribution ShareAlike License v. 3.0:
http://creativecommons.org/licenses/by-sa/3.0/

openchange-2.0/apidocs/html/libmapi++/ftv2blank.png000066400000000000000000000001261223057412600222130ustar00rootroot00000000000000‰PNG  IHDRɪ|IDATxíݱðøScOx@ –¨y}IEND®B`‚openchange-2.0/apidocs/html/libmapi++/ftv2cl.png000066400000000000000000000007051223057412600215250ustar00rootroot00000000000000‰PNG  IHDRÚ}\ˆŒIDATxíÝ;H#AÇño4Љႇ œ„K‰‡‚á ’ê,m„ØØ vÚžJ°²¹ÚÎþî‚§ XY ÅB|dr³cvo—˜Ä°Ý ù0Ã’™3ÿͤõ”Ëe×´¸Éõ¯1XÞ8Œ‰nQˆ88ööÖ§3*rbñ¯¢û-$¨‚þ´˜“P1Žè@Z…-# Ïú01ÑÏÎêÄ1HkKŸ w¶O@¥ªÈóñ!f§ñu˜åác÷;’sá×Bý[E´Añ±—Í\ß>°ùý¿ÏËÊÂ]–P€zØf| Íñ¯“+Ù´gð5…b  i5ümM³œ_æÍq,ÒcŽõèoÓd´ !¶äò©ô•,ôðÀ{¹¨µYß,€zTÍ8H]𤕘ï7¼»/òó8ËQæ !F€~6ãá?Y ÀA@ŨÁ.@ƒ¶TäÄYïŠËë±r‘µ8Ð*·é>€Šçÿ?€×þŸe[6«xÂIEND®B`‚openchange-2.0/apidocs/html/libmapi++/ftv2doc.png000066400000000000000000000013521223057412600216730ustar00rootroot00000000000000‰PNG  IHDRÚ}\ˆ±IDATxíMOS[…Ÿžsúa?-XZ(PD4‚ AWbu`b 77wäHFÆCËÔÂÿà/`vo„ˆAPòq‹P @ ­ûÝè980 îà¤+»§Ýy×^ïZï9SW¹\83g‰3'°Nâçl¹¸_b¯p ïåûÆVÜÖ¡€Ÿ×"¬Ö†X€d]Ðà3“ÉÃÄÌ™xŸ ßMàœ[<çSPkvc—hÈ'…™˜^Åm™hØ7 `Û™¦ èÀåráq›‘œ¾!daeKŸþÆÕ˜:Ì*³_דâèi?I–eP*B7Ÿ¿åô!¹Ýgr6Ër6oKbëþãðôrI”ËTˆüªŒ¨xóö=›ù¢&‰(e+ßóÄkýÇ`ëÁÜb.“¸ÐW×w0¥°jÑzN™¬|©WEãµ¢a¯6[öX†AkÓù*/œ¨‰€ÉY­ ÿV’§–u²jÂ>1W *½·°PGŽzÿ¨/Eg{ ŸÇâaoŠÁVú:è¿™¤1$ôR§W,–ªà¨@ŠË56¾ÀÔÜ-¾,mê¸Î/æè¹– òr5¥T*S(Vf8ö9u’ Õ£w›ùóa=Í<{Ò¡UŒ÷r¯+ÉådDÏF$è°…£é¿`zþ»ÎúöN‘µÜ®0Q3£~_^Ëóâ¯N=ˆvpTà±LžT}ˆîkq†Òm<¼ÎÓ?Zh¿X£ï_þÝ¥[)ƒ `gêÃa_Ô*äÔ2`'=õ´Fÿ2EâÁPú ÷»›l=8‹Wv°%THqÉ¿<"¤ïG¾ÆxH{#ÆÖ«aÔJÕÞ‡—m‹„ çñKsÿàñVŠØ¡°·MâÒ^ TÁ– Ý›r¥ß½ømüÿ_™?ªWİ÷#uIEND®B`‚openchange-2.0/apidocs/html/libmapi++/ftv2folderclosed.png000066400000000000000000000011501223057412600235670ustar00rootroot00000000000000‰PNG  IHDRÚ}\ˆ/IDATxí]MOÔ@~ÚúuØlp]ö¿#›Å]PYECˆ\9ù¼yÑß`ÖÄÿàÿÀÉxóâ¢C &=qÐÄ£—vZçv¶3m؃‡vžLûNç}Þ÷}Þ½ZA@n° OäNp ’xóþK°ññ€xÜj”°8sÑ€“ “€œ_¼[Âíæ§ïD'‚•yye+ø¼û 7#rNŸlïük* ¾0Ь_d«_(àñÖ±àôz=ñxõv§÷h©‰z¹€šØP-äóä’̪uý¼$»\DãJc—B4¯ãÝÖ.:£Ï-ÑÏß}µŠLEíºþ #—ûáºÀÏgN;BŠ€6ïýñ䬜…ö@’Ðåñp&™h>p9¤™EEά¨ÎÊ‘" u¥n€$R"?{¹<˜…ë…%PNtâ$‰ß¶±úá+^<é"§2 ªDq”q´\¬«Ò™a–Œ‘©Aÿ€"Ôµ ™êŸèP£}#Eàz{û.8i îp³ê(ADwD¦E<ê¬cE¦$ HdÊÄ ”.:Ù GŽ-`ŒL‚ý¾'¢‰Ä<¤CIª½;ÙÇTZd±i};>èôß‚z×;K×§8t ¤Ž q”:uvÿv•Ý›¬²ÙvEân{„M·FXg¼ÌfZÖ¨°¹‰*›ßÌß©±ù©:›j–YqèÜë#3çÏSøWøÿÿÑr'ø Ôùù‚ ©¡IEND®B`‚openchange-2.0/apidocs/html/libmapi++/ftv2folderopen.png000066400000000000000000000011251223057412600232610ustar00rootroot00000000000000‰PNG  IHDRÚ}\ˆIDATxí]?oÓPÿ9iš4i°;ii“¶‰ZЉ‘‰ÀÀ7`bèÔÙ¬Øù,HìU'ô$*Tµ]‚T¡DPÚÄ6wÏ}‰;¡C; a¿ÓߟûÝïîž¼jAÀ­InSþ}€9H“ÓŽ|?íÁ÷ =_ÊÆŠ­†¥Àue*;¯YEäsYäæB¢Ÿ¿þÄ—£sÙ½½ÙŒ† É«›©ÀYÇq !GÇ¿v̇¹ÑØ®š °Œ‚ÔF¹}q¥b]÷7í·0)Úd›¾ÿð-èº}Pfä£ÖY{4™ÑÂ@}úæôñ2ÛüÔ—ñúåNŒI‚ÁǃcçÁº%£¬UаI³mc±ô˜å¼ÔÆüÈ>é¸xþt9Æ$µý OæVE*õU´Ì‚ç#ž×ˆ•ïûr@l$øPÿrHaaÇ¥ ²›dZ®rè‘ãqI„o¼øT\Ž,tªj2FAxv-LŸp׌p TÄI/ \¥sfí½; jViTƒèú¤o^cpÅü¼ûû»Ïb]”€¢¤<†aþÕœ²“ßÓ˜y“£§9:Œîù+À³€ñà,E žf³6éNˆÄE£KU}Ü^;¶ØnZ¢uß­US4— ѬëbížN¶.Úk¦ØjTÄöº%µªâ i¯VÄÊÝò§™ Èù¸)ùÿG€™òºJ@T x”IEND®B`‚openchange-2.0/apidocs/html/libmapi++/ftv2lastnode.png000066400000000000000000000001261223057412600227350ustar00rootroot00000000000000‰PNG  IHDRɪ|IDATxíݱðøScOx@ –¨y}IEND®B`‚openchange-2.0/apidocs/html/libmapi++/ftv2link.png000066400000000000000000000013521223057412600220630ustar00rootroot00000000000000‰PNG  IHDRÚ}\ˆ±IDATxíMOS[…Ÿžsúa?-XZ(PD4‚ AWbu`b 77wäHFÆCËÔÂÿà/`vo„ˆAPòq‹P @ ­ûÝè980 îà¤+»§Ýy×^ïZï9SW¹\83g‰3'°Nâçl¹¸_b¯p ïåûÆVÜÖ¡€Ÿ×"¬Ö†X€d]Ðà3“ÉÃÄÌ™xŸ ßMàœ[<çSPkvc—hÈ'…™˜^Åm™hØ7 `Û™¦ èÀåráq›‘œ¾!daeKŸþÆÕ˜:Ì*³_דâèi?I–eP*B7Ÿ¿åô!¹Ýgr6Ër6oKbëþãðôrI”ËTˆüªŒ¨xóö=›ù¢&‰(e+ßóÄkýÇ`ëÁÜb.“¸ÐW×w0¥°jÑzN™¬|©WEãµ¢a¯6[öX†AkÓù*/œ¨‰€ÉY­ ÿV’§–u²jÂ>1W *½·°PGŽzÿ¨/Eg{ ŸÇâaoŠÁVú:è¿™¤1$ôR§W,–ªà¨@ŠË56¾ÀÔÜ-¾,mê¸Î/æè¹– òr5¥T*S(Vf8ö9u’ Õ£w›ùóa=Í<{Ò¡UŒ÷r¯+ÉådDÏF$è°…£é¿`zþ»ÎúöN‘µÜ®0Q3£~_^Ëóâ¯N=ˆvpTà±LžT}ˆîkq†Òm<¼ÎÓ?Zh¿X£ï_þÝ¥[)ƒ `gêÃa_Ô*äÔ2`'=õ´Fÿ2EâÁPú ÷»›l=8‹Wv°%THqÉ¿<"¤ïG¾ÆxH{#ÆÖ«aÔJÕÞ‡—m‹„ çñKsÿàñVŠØ¡°·MâÒ^ TÁ– Ý›r¥ß½ømüÿ_™?ªWİ÷#uIEND®B`‚openchange-2.0/apidocs/html/libmapi++/ftv2mlastnode.png000066400000000000000000000003661223057412600231200ustar00rootroot00000000000000‰PNG  IHDRɪ|½IDATxíÝ!NAÅñ¤‡à\ ÷à Um@`Ô5iÒ`ëh ‚ÅW7] b§ÝˆŠ&oföÍd¾YÔ4 üšcø ‡€´‹Åòù3v=¼]†§µ\B… I¿‹=B·™B¡®;¸k´µ W°ÍN@vyÍÑÖ4ãß÷]ÈâYìã§|M}]ÔÚx6a }ôdׇØYüú¨>¤||5?Ó>|žB"¡î'¡IEND®B`‚openchange-2.0/apidocs/html/libmapi++/ftv2mnode.png000066400000000000000000000003661223057412600222340ustar00rootroot00000000000000‰PNG  IHDRɪ|½IDATxíÝ!NAÅñ¤‡à\ ÷à Um@`Ô5iÒ`ëh ‚ÅW7] b§ÝˆŠ&oföÍd¾YÔ4 üšcø ‡€´‹Åòù3v=¼]†§µ\B… I¿‹=B·™B¡®;¸k´µ W°ÍN@vyÍÑÖ4ãß÷]ÈâYìã§|M}]ÔÚx6a }ôdׇØYüú¨>¤||5?Ó>|žB"¡î'¡IEND®B`‚openchange-2.0/apidocs/html/libmapi++/ftv2mo.png000066400000000000000000000006231223057412600215410ustar00rootroot00000000000000‰PNG  IHDRÚ}\ˆZIDATxí1Kû@ÆiƒØB…Ò¡(h¬"EÄI'ÁoàªèÚ©ßÀáâä 8ùçR-‚â B«TPˆï]z¥B’3 _Þã’»ç}ŸË]VÇ÷}€ÌÈdIæ®i쟯JØ–b¸šÍÃõ+º™|KÂ…°,[Pï\ʘMÆ¢#€ä…F`JݤìÛk³úA±àþè?ØY4ck6"¹Z)ê¸0SHM¨@ï㋺WÖmo¼4èHJ¨Àÿö+…QobŒút ¤ú’*Ð~êè8_+3Y-ñðÜå½÷ ˜PwA¶+^ý}ºì£+xìhÏ•MAE]€TD~EÞߴ^R)`ÖAùŸÏ9©pÔq-Û¾õÛ3tÝÊÆ›ˆÃTÐHÈ)€ ½Š’ICªxëd#1ôú§é€ m@Vüý?Zæßgo_½3-³\IEND®B`‚openchange-2.0/apidocs/html/libmapi++/ftv2node.png000066400000000000000000000001261223057412600220510ustar00rootroot00000000000000‰PNG  IHDRɪ|IDATxíݱðøScOx@ –¨y}IEND®B`‚openchange-2.0/apidocs/html/libmapi++/ftv2ns.png000066400000000000000000000006041223057412600215450ustar00rootroot00000000000000‰PNG  IHDRÚ}\ˆKIDATxíÝ1K1Àñ­ž ØG•â‚n‚Šà ‚âælÁE¿€‹“ (nºêââêäࢋƒÐMAá@°‹ µât¾ÄK¡à%Ü•Û ý]BIïå%áuÍ…a™€,e × v¯ç¥«ˆi‹º¨Õö–î\tòòuénÄ0ã æÜÉoV\Ì$G.&@Y=ÆË%$um·¢ûÛ6–'Úß«9Qó\bÙ)²º0Ðë-Zœ¥TèHÍ`pÀcsm µö5:>Áë‡Þ¦I µØ ‚F‹Çà]» ›jg—ìoÏáõ©[ œõ š­onë €Ô¬¨vqõ„?\Ðç”  6»øüÒTe ÃÉéŸeç ÀÅlQ ¡c”€ª¬ü3*d€ÅWTMÏ\rÿÿh6™ø1±F ‹°fžIEND®B`‚openchange-2.0/apidocs/html/libmapi++/ftv2plastnode.png000066400000000000000000000003451223057412600231200ustar00rootroot00000000000000‰PNG  IHDRɪ|¬IDATxí=QF‘Ø¥D«ÔkÄ:‰F©PK؃=V@§Õ³ Õ8SHxñÌ0bnrróŠ{ò½¿¾’$ ÀÏTŠP  ö¼X¬OÛd6êìòð"°²S´±O¥B€(¡àQé)š+YĈ ÒªËRÉÐ>VtÉsˆm9(ê„䜥k‚-@ȧ-Ü$ó b Ò[he ¿Kp-ôl|CùÿApRG'rÍ­aIEND®B`‚openchange-2.0/apidocs/html/libmapi++/ftv2pnode.png000066400000000000000000000003451223057412600222340ustar00rootroot00000000000000‰PNG  IHDRɪ|¬IDATxí=QF‘Ø¥D«ÔkÄ:‰F©PK؃=V@§Õ³ Õ8SHxñÌ0bnrróŠ{ò½¿¾’$ ÀÏTŠP  ö¼X¬OÛd6êìòð"°²S´±O¥B€(¡àQé)š+YĈ ÒªËRÉÐ>VtÉsˆm9(ê„䜥k‚-@ȧ-Ü$ó b Ò[he ¿Kp-ôl|CùÿApRG'rÍ­aIEND®B`‚openchange-2.0/apidocs/html/libmapi++/ftv2splitbar.png000066400000000000000000000004721223057412600227500ustar00rootroot00000000000000‰PNG  IHDRM¸¿IDATxíÝ¡JCa‡ñç(˜ ëƒ%±Ø4 b±È˜Í¶3˜v^Á±˜…ãó–ŽELƒõ…¥•³ ,ÿb;íç{Ã/¼ðÞÀaYÕ¯åóøq:¼º¹›\òIIIIIIIIIIIIIIIIII-Òçl¹›«õ抢è_t/Ï»ã£ÑíYQVõðêäíã÷´×ùY¬Úÿµ§¦ivók¾_íåýÛ£I@$I@$I@$I@$I@$I@$I@$I@$I@$I@$I@$I@$I@$I@$I@$I@$I@$I@$ýC[Vì=ü[„fÆIEND®B`‚openchange-2.0/apidocs/html/libmapi++/ftv2vertline.png000066400000000000000000000001261223057412600227540ustar00rootroot00000000000000‰PNG  IHDRɪ|IDATxíݱðøScOx@ –¨y}IEND®B`‚openchange-2.0/apidocs/html/libmapi++/functions.html000066400000000000000000000266051223057412600225240ustar00rootroot00000000000000 MAPIC++ClientLibraryBindings 2.0 API Documentation
Here is a list of all documented class members with links to the class documentation for each member:

- a -

- c -

- d -

- f -

- g -

- h -

- l -

- m -

- o -

- p -

- s -

- ~ -


Creative Commons License
Creative Commons Attribution icon Creative Commons Share Alike icon
This content is licensed under the Creative Commons
Attribution ShareAlike License v. 3.0:
http://creativecommons.org/licenses/by-sa/3.0/

openchange-2.0/apidocs/html/libmapi++/functions_func.html000066400000000000000000000253631223057412600235370ustar00rootroot00000000000000 MAPIC++ClientLibraryBindings 2.0 API Documentation
 

- a -

- c -

- d -

- f -

- g -

- l -

- m -

- o -

- p -

- s -

- ~ -


Creative Commons License
Creative Commons Attribution icon Creative Commons Share Alike icon
This content is licensed under the Creative Commons
Attribution ShareAlike License v. 3.0:
http://creativecommons.org/licenses/by-sa/3.0/

openchange-2.0/apidocs/html/libmapi++/functions_type.html000066400000000000000000000054531223057412600235630ustar00rootroot00000000000000 MAPIC++ClientLibraryBindings 2.0 API Documentation

Creative Commons License
Creative Commons Attribution icon Creative Commons Share Alike icon
This content is licensed under the Creative Commons
Attribution ShareAlike License v. 3.0:
http://creativecommons.org/licenses/by-sa/3.0/

openchange-2.0/apidocs/html/libmapi++/header.jpg000066400000000000000000002264161223057412600215620ustar00rootroot00000000000000ÿØÿàJFIFddÿìDuckydÿîAdobedÀÿÛ„ÿÀÍ4ÿÄû     a!Qqð1A‘¡¢d ±"Ô%U•ÕV–Ö”WÑñ#EÁá2DT·BR3C$uµ&g(8x’S£³4…6¦hbc¤´Å†G§)   !1AQq"“ÓT”ÔUa2‘¡Ò#³´u6±BRVÁÑb²3$v'7ðár&ñ‚’¢CS%Âsƒ£4Dct¤5ef(ÿÚ ?ýAîÊåSñMÁÙB8v)¸;(GÅ7eáØ¦àì¡;Ü”#‡b›ƒ²„pìSpvPŽŠnÊñMÁÙB8v)¸;(GÅ7eáØ¦àì¡;Ü”#‡b›ƒ²„pìSpvPŽŠnÊñMÁÙB8v)¸;(GÅ7eáØ¦àì¡;Ü”#‡b›ƒ²„pìSpvPŽŠnÊñMÁÙB8v)¸;(GÅ7eáØ¦àì¡;Ü”#‡b›ƒ²„pìSpvPŽŠnÊñMÁÙB8v)¸;(GÅ7eáØ¦àì¡;Ü”#‡b›ƒ²„pìSpvPŽŠnÊñMÁÙB8v)¸;(GÅ7eáØ¦àì¡;Ü”#‡b›ƒ²„pìSpvPŽŠnÊñMÁÙB8v)¸;(GÅ7eáØ¦àì¡;Ü”#‡b›ƒ²„pìSpvPŽŠnÊñMÁÙB8v)¸;(GÅ7eáØ¦àì¡;Ü”#‡b›ƒ²„pìSpvPŽŠnÊñMÁÙB8v)¸;(GÅ7eáØ¦àì¡;Ü”#‡b›ƒ²„pìSpvPŽŠnÊñMÁÙB8v)¸;(GÅ7eáØ¦àì¡;Ü”#‡b›ƒ²„pìSpvPŽŠnÊñMÁÙB8v)¸;(GÅ7eáØ¦àì¡;Ü”#‡b›ƒ²„pìSpvPŽŠnÊñMÁÙB8v)¸;(GÅ7eáØ¦àì¡;Ü”#‡b›ƒ²„pìSpvPŽŠnÊñMÁÙB8v)¸;(GÅ7eáØ¦àì¡;Ü”#‡b›ƒ²„pì__gÓâ£êE~•²O\VݪÏãžà…·#÷Á?Nž•cÏ´Ôô™Û£¾!àÞÖ²x¬.c;s÷<%Íåå+ÝÁ’¾ºckO¦‹£Êcq0}ç)sµµi®W¶6׳SÈpo× 'ü߯Wí¬?þ«[7ð¿™áÜï¨]ù¥‚øócûëëvþqkúß„ÿ›øÇñå­õ¥?á2ÿùßP»óHøócûçëpyůëvþoc/Ç–¿Ö”¿†Ëÿç=BëÍ#ãÍïœW­Áçýn¿ÍÜeøî×úÒá‡2¿Ã¹ÏPºóIüy²=óŠõ¸<â×õ· 7qŸã»_ëJ?†Êÿç=BëÍ#㽑ïœW­ÁçýlÂÿÍÌiøê×úÒ—ðÇ™?áÜç¨]y¤|w²=óŠõ¸<â×õ¯ ÿ6ñ§ã«cë:?†<Êÿç=BëÍ#㽑ïœW­Áç¿­XcùµÛYÑü1æOø{9ê^iì|â½n8§ëNþlãoÇ6ÏÖt ¹“þÎzךGÇ{#ß8¯[ƒÎ-Z0×óg~8¶~³£øeÌðösÔn¼Ò>:Ù>ùÅzÜqkúφÿ›ßñųõ/áŸ2?ÃÙ¿QºóHøëdûçëpyÅ?Y°à÷²¾8üom}gGðË™áìߨÝy¤þ:Ù>ùÅzÔqkú͇šøãñ½µõ•Ã>d‡³~£uæ‘ñÖÉ÷Î+Ö óŠ~²áßæ¶9ümm}eGðϘÿáìߨÝy¤|u²}óŠõ¨<â×õ“5q×ãkoë*_ÃNcÿ‡ó~£uæ‘ñÎÊ÷Æ+Ö ó‹_ÖiìÏ{âýj8µýVÅÌ›ñtÃéy…îÏ©\ù´|o³=ï‹õ¨<⟪¸°{Ù&Äü]ðú?‡<Â÷gÔ®|Ú>6Ù¾÷ÆzÔqkú©‹™/âØ‡Ñü9æ¸s>¥sæÑñ¶Í÷¾3Ö ó‹_ÕL[üDZÀü>á×0}Ùõ+Ÿ6ŸÆÛ7ÞøÏZƒÎ)ú§‹¿˜ö7âȇÑü:æ¸s>¥sæÑñ¶Í÷¾3Ö ó‹_Õ,_üƱ¿A|:—ðï˜âÌz•Ï›GÆÛ7ÞøÏZƒÎ-Tq€÷²-Ž?þë‚øuþ`{‹1êW>mìß{ã=j8§ê†1þbYŠà¾Gðï˜âÌz•Ï›GÆ»;ÞøÏZƒÎ-Sñ—óÈüUðê?‡{ÿÜYR¹óhø×g{ßëPyÅ?Sñ—óÉüUðê_ÃÍÿî,Ç©\ù´þ5ÙÞöÆzÌqkúŒÿ˜VWâ˜?‡Qü<ßþâÌzÏ›GÆ»;ÞØÏYƒÎ-Sq ÷²•ø¦á´w÷¸³§sæÑñ®Î÷¶3Ö`óŠ~¦c_æ —ø¢á´w÷¸³§sæÑñ¦Î÷¶3Öaó‹_Ô¼müÀ²ÿB|6áîþ÷cÔî|Ú>4ÙþöÆzÌ>qOÔ¬müÀ³?Â|6—ð÷{/êw>mlÿ{c=fËZþ¤ã¿öoâx_†Ñü>ß¾ãËúÏ›GÆ›?ÞØÏY‡òÔýIǬßÄп £ø}¿}Ç—õ;Ÿ66½±¾³å­R1ÏßÛ;ñ4/Ã(þoßqåýNçÍ£ãMŸïlo¬Ãùk_Ô|s÷öÎüK ðÊ_Ãýûî<¿©Üù´þ3ÙþöÆúÌ?–§ê6:ûùgþ%†øeÃýùî<¿©Üy´|g´=íõ˜-kúŽþýÙÿ‰a¾Gðÿ~{“/êwmí{c}fËSõýû´?Cü2€7ß¹2þ§qæÑñžÐ÷¶7Öaüµ¯ê&<ûõh~$‡øe/€7ß¹2Þ§qæÑñžÐ÷®7Öaüµ?Pñïß«Gñ?Ã)ü¾ýÉ—õ;6Œö‡½q¾³å­Pñ÷ß›GñGÂé|¾ýÉ–õ;6Œ¶‡½q¾³å©ú…¾üZ_ˆâ>GÀ;ïÜ™oS¸óiüe´}ëõ˜-kúƒþüZ_ˆ¢>GÀ;ëÜ™oS¸ói|e´}ëõ˜-OÔ÷ÞÓüEðº_ï¯re½Rãͧñ–Ñ÷®7Öaüµ¯ê÷ÚÓüCðº>ß>åËz¥Ç›GÆ[GÞ¸ßY‡òÔû`ýöµ?Äü.€·×¹2Þ©qæÑñ–Ñ÷®7Öaüµ¯Ûëï­©ø‚'át|¾}Ë–õK6Œv½q¾³å©öúÂûëjþ ‰øUoŸrå½RãÍ£ã£ï\o¬Ãùk_·¶ßKWñW¨ø |û—-ê—mízã}fËSíå‡÷ÒÖú~+áT¾ßåÊú¥Ç›GÆ;KÞ¸ïY‡òÖ¿o,?¾–·Óñ_ £à=ñî\¯ª\y´|c´½ëŽõ˜-O·v'ß;_éø¯…Qð&ø÷.WÕ.<Ú>1Ú^õÇzÌ?–µûwbýòµþŸ‹øUïrå}RãͧñŽÒ÷®;Öaüµ>ÝX¿|­§¢þGÀ{ãܹ_T¸óhøÇi{×ë0þZŸn¬o¾6ÇÓÑ £àMñî\¯ª\y´|a´½ëŽõ˜-köæÆûãl}=ðª>ÞþåÊú¥Ç›GÆOÞ˜ïY‡òÔûqcýð¶~ŒøM/7¿¹²¾©qæÑñ†Ò÷¦;Öaüµ¯Û‹ï…³ôìgÂhø{û›+ê—mm?zc½fËSíÅ‘÷ÂÙúv3á4| ½ýÍ•õK6Œ6Ÿ½1Þ³å©öÞÈûßm}9ðš>ÞÞæÊú¥Ç›GÆOÞ˜ïY‡òÔûodýï¶¾œŒøMïose}Rãͣ㠧ïLw¬Ãùk_¶ÖOÞëkéÈÏ„Ñð.÷÷6WÕ.<Ú>/Ú~ôÇzÄ?–§Ûk+ïu·ôÜoÂhø{{›+ê—mm?zc½fËZýµ²¾÷[MÆü&w·¹²¾©qæÑñ~Ó÷¦;Ö!üµ>ÚÙ_{m¿¦ã~Kàmíîl¯ª\y´þ/Ú~ôÇzÄ?–§Û[/ïm¹ôÜoÂhø{{›)ê—m/Œ6Ÿ½1Þ±å©öÒËûÛn}7ðš>ÞÞæÊz¥Ç›GÆOÞ˜ïY‡òÔûieýí·>›øMoose=Rãͣ㠧ïLw¬Ãùj}´²þöÛŸMÆü&··¹²ž©qæÑñ†Ó÷¦;Öaüµ>ÚY{mϦã~GÀÛÛÜÙOT¸óhøÃiûÓë0þZŸm,¿½¶çÓq¿ £àmíîl§ª\y´|a´ýéŽõ˜-O¶–_ÞÛsé¸ß„Ñð6ö÷6SÕ.<Ú>0Ú~ôÇzÌ?–§ÛK/ïm¹ôÜoÂhø{{›)ê—mm?zc½fËSí¥—÷¶Üún7á4| ½½Í”õK6Œ6Ÿ½1Þ³å©öÒËûÛn}7ðš>ÞÞæÊz¥Ç›GÆOÞ˜ïY‡òÔûieýí·>›øMoose=Rãͣ㠧ïLw¬Ãùj}´²þöÛŸMÆü&··¹²ž©qæÑñ†Ó÷¦;Öaüµ>ÚY{mϦã~GÀÛÛÜÙOT¸óhøÃiûÓë0þZŸm,¿½¶çÓq¿ £àmíîl§ª\y´|a´ýéŽõ˜-O¶–_ÞÛsé¸ß„Ñð6ö÷6SÕ.<Ú>0Ú~ôÇzÌ?–§ÛK/ïm¹ôÜoÂhø{{›)ê—mm?zc½fËSí¥—÷¶Üún7á4| ½½Í”õK6Œ6Ÿ½1Þ³å©öÒËûÛn}7ðš>ÞÞæÊz¥Ç›GÆOÞ˜ïY‡òÔûieýí·>›øMoose=Rãͣ㠧ïLw¬Ãùj}´²þöÛŸMÆü&··¹²ž©qæÑñ†Ó÷¦;ÖaüµÈ[.Õâ)8há'(,™Ed"©,’¥¦ªJLEP‚Sˆ¡ZÜðMk;í®ctw1¼µìp-s\ÓG5Í4-sH ‚P¬ô3Eqn-Þ×Àö‡5Í!ÍsH¨s\ AÄ/£³éñWÔ¹+ô©Ùôø¨ú‘_¥bï¼JÆàXññ‰¶•Èeƒ‹\D[G2NJ&CC6*ä1ORöêÜ 6¾ñÈîKÞsS,û«×> §hð'•¿jGÐ8A<‹H/u†–ð«‚ònió6Û`ãÛ«Y.á¸i10ý–7£½xtÖ¡£†§Æ€¯oL…xäi¥® Òᑸ$Ö1÷T|¹Ì‹DÎmïFhV±í?䤉˜sk_§[khmÍn'mYÃidÐ*Ðò8j‘ÿjGž·<—Õð¶sqf·-ó²9ˉn.[ƒýV7ì±£©­.( uV|µb*”ë©ÓDꔪmÓÜþŠ’;SªPS¸)P& PSn½=ú’ÔU()ÕRZª©ANº)Õ)UÛã¤GjuJ wM`¥*›u÷jKSªPSnÞ*’ÔꔨÓN…UL íñÒ¢uJU:½ÊšR‚}‹SªR©·ÇPZR‚•ORuLUzüƒJ©Õ)TÛ§Oz•N©ANà¨-L ¦Ýj UU)Tê÷*t”ÁL XRN½‰J¦Þ¡¥¤'T §UAjuJ uÔ§T¥So½SBª©AOëè¤{Mºûµ%¡:¥*›t©-N©AJ‚ÔꔪmñÒ¡N©ANò…MªR©×ÑH´& R©¶ µ:¥*KU”Û¯MMN©ANò…*'T §^ЩÒR‚›jKSªPS¸* S)TÛ®Á©¥ª@S¤<´“ª`S¯¢•uH m©-N©@üõ©‚ªsPÔ–§T §pRâR‚›u¥@RU%©Õ(yõ©-Nªà~ª’ÔꔚŠQ:¤ŸNš<)Õ()J€§T€}µ%©×ëH)Õ 9ô©-N©ãÓSDU 9ôé¥Ç­:¤ÒàSW…-)Ô¤=Iju€~z)ñWs I¨ª@?8x©S±5p?0ÿM.=iÔ¤ÑÀ£‚¸)Q:•p5M¨ëWÒÒŸ\ SBŠö«„<4¨ª¸<5:SVs .!UÀÂT'^Õp?pQNÄS±\ J‰ÔŽ•®´¨Š…`0ôÒ¢t À`è¥E4ZÒIkB¡ P…(B”!J¥R„)B¡ P…(B”!J¥R„,®Áw ¹f"Éc “8±K^ð$Óþ@è§_›ûç÷Û1ûVïôò/»¶‡îž/öu·èX²?³îÒµo¶/À§gÝ¥…~pxš»e®Üõ•K¹2ÇŒ½ni57fÞ*Ù”u‚D¦ÑL}4ÞPÆ0òˆ×ì?%0V.U` Ç°5³ãmî^zÝ-ÌMžGÒ|g+ÐÐ@ ó{š[¼¶ÿÊËxíF+é hêÀ÷DÀ;õ*ꔪXTÐ'TÅSn¾íIjuJ mÒ¤µ:¥* SªR©·]ƒJŠª”é(TÒ©Õ0)×ÑRZR•Mµ%©Õ()ÕÑQ¥:¥:È4¨R•M½CR@N½©ANà¤ZR•MºÔ§T¥SnžåAjª¦:ú)'T ¦ßMuJ uR-N©ANº‚ÔꔪsžçôT–§T §pT¦bR©·Çߥ@R‚U%©Õ()×PZª© §0éÝâ©-N©ANà¥Å:¥*›|u4ªPSª‘jª¥6ëPZRU%©Õ((=54¢uH mÓ¦—…:¥óÒ =ª@?0Ô–ªªP?=N”ê§æ¡¨-N©Nz\SªPSn½Þ:\:ÐKObuHÛRZ~¤€~z’ÔêÌ:ôÔ–§T€~~JT#¡4…?0ëKÂ{RéR½¯b@?0÷tT{UÀýu%©×±\ ú "ª@8ôÔiNªàpè飈OÀ4¸u¢½ªàz(Ÿ ¦‰×µ\4ˆ@§R¸<<•:S©Væ’;Sª¸|<´´¦®})P„+†•{Sª¸Žà¬ (Ž#¡_ZTOWjÔ˜iQ>[{ž•¢¶ 4’¢Ö’JP…(B”!J¥R„)BYðÒ–¨<;ï\ùU0ø«ó{|þûf?jÝþžE÷vÐýÒÅþζý `ö;<•«T-‹þÝ*v;<”T#þÝ+ò•ŸÍ»žshkÞ˹$4—”Í~Öò¨Êý·ûú¤+óü÷šý­yúÄ‹©€ýU¾­N©@ýu%©Õ )·J‚Ôêš'T ¦Ý;¼TxSJçÿMRuH mê’Ôê”çä©-N© ¦Ýj Sªû™6y éQí\½xàà›v¬ÐUË•Ô0èTÑAUNo×ÒÇfYÜÖBÑR礞[ùÀ\ãÐOàYKcðožïTÐr[IKyŠú®n5>/W³0”@bRªø ©Ã@2e 5¯7ÌókcaÜcuÛg¿Õ‹ÇãÙ«ƒz»|+mÆì}Ë“ðÛ=±ž5p§¯Â<+¸à2è†dçn„ƒEÛ ©XGª)¦.I¯½Qs ”1¬Tļ¢<•ªÅÎìMäÝÕ•»ŠHÔáS@]Ð:*ÐOJÊͰo,ÁûãÈ¡¡£M:iÓÆ´<;*¶ÙÚ±)ÿçƒÒ¡È.b„©ïhôÆn7Cx{ýí9DC½]«~k™Èÿtiû2Ÿý=«„íá;ª[H‚ºÆàá®àˆrá«Y¦.\ šJKº ²b²~Žå#%5KCrD `Ö¶+`cîãl¯ŠFÆâE{(iÄ#¾#¤®ÆÔž²F—Ž®Úñ ‘кVn͹mÓÆQª‘0HGEÐäå×}=t^PïVÝi—ÇÞÌH5£À¬Î6ö׌Œ%½£ˆ\dëò dhB©MºtÒ-N½©AJ‚Õ@¥*›u©-N©J§UM uL uÒ N©J¦ßIjuJ uT–§T §]AjuJU6éîTЧUÚ¸kßÛ!@ã\{Y†uSˆ(º‚Þ6&9¸’S÷TôH¸Ô5:§C‰¦E9mcwîÌ&ÈÀO¸óòì UïyàÈão Oyà8¹Å­pÎíͽ”Ý9x°¸vk¼”õš5iï=MhâOz ˆÖ»—†ogg1QŒø¯ÉÒWîF~Å'«Ú±on&†äû@ûfÃ2sñQ«†".å¤IÈ”D‚AÔ…ùœÝçŸ3ndŸ—0ã¶ûZٞ؜ziãKr oxà\Èb%WIú5ü¹åNÆ…‘o[¹/sh&6:FýXà!íiè–@Ò)Ð>7{,ø·]K/dIÜQ“Ý$¸Á@Ê>ºAÓåÐ)tôxlŒåó[°¦L¦TÌã%Sz ”ÇÌ„8î¹—üÃr茖òµ¶ÊàZGxö²?ÿÕ¬0ž€,.Ž´q* ØüšÞ€Ùm©æÇåÈ:]!$ô'.véŽPúTðy¡Ä>¿¸gÉ1ÖAj¨dFFÛ¸˜‚ƒ v@¨±ÑBZ)UCDÅ7 ”ÑfËJmJ$9þ¢å÷0°ÆÁ37„qkÓ,N§y ”©cÀémxñ^Þ"†­ ¼6n_ee‹Ê4MQÈß±++@æ“Äv9§‹OŠÒÅWn½5½P­N©J§W”)Pê˜ëè©-N© ¦ßAjuL TéUT¥W¯È54N©J¦Ý:{Ô¨ªPS¸*KSªb©·Z‚ÔêªuTé)Õ0+Éà%Mz=íá×pÛgá«´ÓW×ùçK4iy•¥Pc¢­Çˆz*j¦@o¢²Šk¦º€‡5|ÏÉ.iîmñ—ËÙn7Àè,û¾ëDa‡Æ|­5 šðcWºsO``¶¦7u…l¢[}æ·—±‘N8¸¯9ÐpUS*…C ×ÒbŽ ÃÏB¾S®‘j*”ªsžçôTé)Õ0)ýaI0{•Mºûµ:BuJ uT–§T §]AjuHU6øêtªª`S«hRER•Mºû´¨ª@Sn•%ªª”¨-N©AM¾:)Õ()Ïã ”ÁìJU6ëîÒ N©ANªE©Õ )×PZR‚›t÷?¢¤µ:¤9ùv…M uJU6õ / uJ sÒÓØRù†¤µ:¤÷AjuJ >½5:Sª@Sª—ÒúépER–”궤µ:ýJàpè©-N©@ãÏ­AjuWõyiP§T qç×ËK‚jàz4ö'^Ä€na©!íHç©-M\ Ì:TRÇÃËS¥5p8séÓKˆN©ãGpëWÒ¢~p7pR!:ö«Ç¦¤µp8R¡N¥\ >©#µ:«ù§Jjà`ðÒ⬢½©×µ\ÝÞ¢ÀÛ|tQB¶´¨ž¥`0ÔÑ>[{ž•¢×]hIkI%(B”!J¥Y‰Ã"Zµt:wݸý!¼5ù½¾}³µnÿX‘}Ý´?tñ³­¿BŘ½vµª­NÇ»Z¿%œB˜ Ÿów´Ì90QRxÔt.¸ÁÔ`9p¬rU¶ªö/»BRòŽ¥3 cx¥þ€¾ÁtW}ÔM‘À;…[Bþ׬ý+L=Áµïß##™Ä WéT•Ã%0z«uœ1lªNY±lGGP§Uºí[z:E1A¹;!U° aÐÄÝY[qq]ops^ò@¨TõšÐÖ¾õÃmËZHkšæ´H$)NÒà6tT»uÐ(£¤À@éiÛ4PL'2J”Šö§HU DtÝ0ˆw‚³Ö™››g‡>ˆõô8vŠŠOè\ca˜‹ êêðý…bÍׄ;~áó3e%¸²ÌôìÚÉ•2†Lœ€T]ƒ©Š:r›”¼¡èÍé÷hÃåÖûZÑÕâYôöÓéâ:ºV§}¶ÅËÜÖQ“õ§ÛðýKæ¡¥íÉâæY,Åësn¨ŠÀÈ S¦r “P‡(€Š"^‘ÈYå-ÅÍ“Ãã=#è#¤-òÊæÂcËK_øm¥Sª»ÄÕªPS¯¢¦:¥6øé¢©ANª‚ÕUJ uÔ§T¥Sn”¨Sª`Sú¦0R‚›u÷i§Uï²ù„!ᓉŽ*åcŠòJÜgv¤˜(,6Æ/²P¾d2T¥¦œì”ˆ&¨Q:ŒSäÔ¡¯Â¿Íýæâßø\A!m¤‚'štw×sºÝ®pë1±•o`‘Üx•õw!í-°ÛC/½ef«†wéîíâ8Ø÷:‡´°v/ÎmËv^yÊÿ¹ò ñ0îjáºæžMLÉ:Pç3‡o DŠcfÙ=Ô›¢MA2HR€}7€ÀÚYØÁˆÆF!Æ[FØã`àZ)õ“Òç.q.$’Jð¼¾Zâæê\óÌ—ó¼½î=$Ÿè €€.Ml-ò>bAìTÜCÖ’‘R±Î–g!'ºnØ¿bñ¹ÓpÕë7ID”!Šr bˆl·vÖæÙöÓµ¯†F¹®µÍp!Í ð ƒB ÁÙ¸‚fÏ ‹$cƒšA¡‚è Š‚:è ‰PâCÙ}‰¸ŸœI±¯Ë[BFj]š w/¤n„pýþÙºiãx雼È=ôtôìŲ`<„øƒ–lŸ–œþÈìkg8bî ¬k 'ÅýîÜšô¹ÕšN§µõ>ùt[ã”6[®pÓÅÔh¿îóØ×IGPti‹¯ø<à“ñ¹jôŸ“²îtç®I^ËM‘ ~ß¶­™F.eŸ:Žzvñ‰ŠVúnKÛ® "‰Ì œ¤Ž÷Ìþyo=“̶müD1]â´E¶ýÝd’YXàÆ‡¶¯§{ éhÔà AÔj[•;gtlgfr2Éo¼µÑŒŽ7´¸–š7ìjq $P(­f\ÞÇ®øŒÂѰy I)Gmm˜|Å55|FÛ“So\›йnÖÉǬñÚ…!Vun3Ž(˜ }ÒjjÆå2ßÍ?ýÕ5æ<@Àe}Œq[>HØÑW0àMtù:'‚ïXc¹ y|Üv׆gnß$ÍcÜMá(“®·k;h8¬Aã[†ü%eVV¹dœNØ×“S–Àñ""ùvlÜ‘´œ¿bšMTœ€U ²ˆ”©,ƒ„V$* )ûw'y­mÌý¾ë¹£m¾rÙâ;ˆÚIn¢*Ù#©'»P8’×5í«ƒCå|Êåôû0-£{¦ÅNÒø^áãP9 [ "€‡5ÔÒ3^ßá#†°Ì`ã®beåÃw‘3BbÈG²Ì×AUZðA½¾â2nRàbÐå3õÌõœk%Næ0¦ª¾9›ç/0÷þë¸Ûšd1c- ^ÊÖ8:ŽÓÞVPøÙœ‰¢9&ú©¬ô¼_,önÐÛðçy˜éd¾¸E«öÒ£VŠFZ÷HÑöÝ­‘°5&Žv㋱W³ƒŽÖ'¾pžX‡Šs0Ê"æy5"õÓDTI°É:‰œ»o(yèvΦUÒŽ”jõ 9Na)?ÊÄe¹Ï~U]Ñß²ÍmÉ$ s¢dlš-’(-ßÈK¥‰ñš=~Êå70-ä²ÚͺÆf˜Â懹ï$tUÌ’YšöEC$cÅA<:p7á"¯ÅͷÞ[báºÍò¶eÞÊ9éÛ*ªh$åB:Œ~RýE$á²ÀPíT¦ÓßWÐ;›µÜªºß»RF—ýÀO {A’ÞM$µÍ¯:—Žà¶{›Ì }£¸àß½÷R†šTMZîÇpsM8´ƒÖ½!Íü;{:øC¹Ô›Î7Ï4Òàd̶fŒ›”{qºi);–IHYy±håúG#uWxÁ‘{#¦Qp®¥OæýµÍŽyóÛ­¥½Ä/qžýñ±±Ôš²&6FICH. ŽI A:ÅÞÙœåç*6Uñ»Ï¾âhdhî­÷Òž4Ž,sBꆒö0Pôqۆá~÷⃲Ï[/±›IçÓvÔ¤ÂøšÔ‹Nภf#î‰Yçì¦Fß\ŽX®ÉâV0•1)Äæ2Y]½Í¾gìÎ`ZìÞh¾ »KçÆÖLÆDÂÞõÝÜr1в&º>ðÈÙ#®Pt3<ºØ{›gÜnm„Ù­®m÷:7:GjîÛ­ì{e|ŽÑã1Ìyi45%¸YÁw ’¼[_îa’V ǵڳ–¾nVȦáÓ6VU(Øh¤•Õ›3UÁªIYcN̨©îÙæ¥,öã2"6Üfnœæ[BI sš|#w¦êŽqs u·Ê¹yËû½óšuž³2Ý¡ÓÈHÖ0ßGi'ƒC\â ]™ÕËì…ÃWš˜¢ä¶/ËÞfAX’ø†œ½åb!ä[j“Óɺ‡½­ÖÏÔb࢚¿ź!V)ŠÑð¬~SùÜXѸ­o¬l­¦`’+gÅl×½§‹CCíåsC‡ßLÓJEW¬^cù…½8k‹[«©ãv‰'l“9­pàK‹&Œ:‡î¢p­EEñµÂ±áì\ň®U®ì” ȰRN¥ æ%üÌZ×!“lÙ²2ðif ‰{b‚'"¢aÜQOGäç8o·­ÅÖÖÝ6ÛwØêÖ [#XáÉa$²XÞ@‘ é:mZÝ'™|µµÚðÛç¶ô®ŸmÝÓIqsæ—´jjcÙRÃMB„:¦„ú›Ç$áî÷ǘG#ñ=’ÝØ8Ÿ·|ñìdYŒ”Íó;sCÛ‰CÛ‘«7Aü¢‚bB.u[±j£ÅRÔÄQ¹QbüË}É»0ùÌž/eZ6ç; s¾Ä,òHàK[ýqG=Á€ð!䆟£7¾näñV7û¦àÁ‰´a%­ûR¹íf–4€]ýSPÖ—ÐZ#0¾1öjñŽÎî°8ˆ½1ÎA‚<Ó7Ò·r²Å*현ëx»†íº æbI¼n“´w›¹pP(§¾U ë9®`së–2Úå·eÅžC,¡Žcc€2´'»/ŠdcËC‹ã¶­5¡ióÌ^ÏåûŽã·a¹²ËG ç>RêT a²K+Ð⇊î<¨#ÍÜ]‚®|ÄppÞ.›F\ñ÷½Éh\²eIWlⳓ žU$ñI7i ¹ÛÆH®ɾMð0}5œæ>'Ëçó5ÒX›H¦Š:†¹îœ0E6Dâ¢7Ë èZݿˡ´ð1fùŽé$½¸%³ Å*+¢‘–½Ïí¸½‘°5&ŽwÛŒñÏ³ëŒÆSvŸÊ^x(ÄŹ—gq:—~ñËDTI¸È8‹™º.Ø™¸–îI„“g‰Êcn—¿ŠÊs¼±ºŠÿy¾Ï/·ä1α°jtµñÃãyé2Dö=û ʽùo%žØmÎ72Æ4=Ïq#¢¥¯–V½ ‘PÉñÓÀ/0o[js_V<º›•Ëg̼„–nCï¢+µ>‰ºj ”¢»íÌEÐS@íP¦Ó–¾ªÛÙìvæÃÛæñŽÕes^Úð –¸u9¦­pêp#©|û™ÃÞà²Sb¯Û¦ê NŠŽ±Ú(ZzÁl`¦ÚÌ–¬]R‚œõ%©Õ()·ÇQ¥:ö¥:B’uJU:éP'T€¦Ú’Ôꔩ-N©J¦Þ¡¨-N½©N%*ÁìJU6ëJƒ­:¤ÒÒRÇŸü5©×êHŽŠ’Ôê”×SDêŠ\zÓª@S®•骯֔5¨¨W‡EIjª¤MN”U :)qN©ýt¸&iN¥ ˜ÃRZЏž§J¤€na©#µWóù*tö&¥Ät§Up?=Á )iOR¸•¨ëWMN”ü à`šUX !ÞD'Up?8xªt¦®÷tR⮢½©×µ\E;AÔ¬ÛJˆ© ÚÒ¢u Àaé¥Dè ¶ðtR¢TZÒIkBJP…š¼/¥«%ÇNû•‡Æq¯ÍÝóûí˜ý«wúyÝÛC÷Oû:Ûô,Y•Øì%jËbS±Ø>J¿"E›wˆLî^AÓ2äðñ^ó•ûmÊ^Ví¯ØÿÕ!_˜;üÿçÌßí{ÏÖ$]:}+}-Z•RǦ¤µ:«ÃŸü%©Ô¥¦ˆª@Sª—…4 §_»Jƒ©:¤íÓ`÷iRZV}p'ÁܧײÒÓÈ®ÏYÎP5Èü¦;aœúBË'E(™.Ñí^*MN‹}ºBxo;9³mËl3ml‹_¹®Ú{–ô÷lè38uÐðŒwO}?–{ãzd4˜{r †´ÖãÄF ¥^EHoG ýOÚöE³í˜èf­áã3lÕ„dB ƢѓtÀ­Ù7*'A"9@‚0ˆˆ˜F¿2²yœŽw%%õã-ËÞ\çÈKËœOð$ý<P_qãñVx‹&ZÛ€ÈÚÐX@ph Ãô®•ÉR™mÙ26oÌòÎÑ(n¬¼œ˜,Î(«€êº†kG*ûýGUÓ7€+rÛØ·ºÍ×Ré&~†ž ÆQϧPÔâÆðþˇjÕ³™Xb¼À†²&kpë/}ZÀGI£Cÿ¬Ò°Ç%ܳnÓ21Ò±=ªÄIwÒë‘è"©€‡8™ER€a0ê¥{ÙÆØDðû¸åš€ÈÅ\HãØkà^G¹2ykÚEc¦8I£žç^.  óÿ(Ý ­rN¾É¬u’¹&ÞÛwMQh“.™"£[î.ýu”Mªc¨¡¸Q(W¿m«ëo ¾)ú#·´p:µW¼Ô4P¸öñ5â¼Ö÷\×ËutÇÈ纮0=”#WWàà†œ´KÙ踟ï`3¦poܧïùDp»dÞ †ºŽœºÖjò×--Ö±i`ÁÒ5½ 9ÞÑoÜÚ>wÿ…ßåqY ¶Ü1•Ní’Id M !8©Í®ø€¬fG\ᨓRh™€6W}˜Ü–÷‹8ÍGK$‡€8¯ŠNšÐ[pxtU®ÿ%h¹ 2|ù ‹†Ï $S1;6ÇRHñŽVLM¡Š²R̘$s¦ è Bòë aß·¬ -’9¢ãSâêÿêýwºmÙïƒ8}`E£Ì„I¢Ý\q²úìÝ©K²ìǹ0ªŸ`C9ng ©ÄNQÓPä÷_û”[²FØÊÉcpã¸8pã@hïĹMûæ{ ÃÇ´ý¡Ðxý ò}|Çr LfØ”O(Bo71Duôg €ª¡˜,n›C å/½ÔµÖÁenðwBXxÛ»í0žŸiÄ~?É’³·ÊÀbž‚Aö\:ùâüKß³{õÄ|ƒu¼j ¦»u‹¸¡  Aï”ä1G¼bˆr {¥…í¾JÕ·VƱ»ñ°¼²öÎk ƒo8£‡AíD/œê®ÑjëU()×Q¥:¥*›¢•;SªPS¸)P'T ¦Ýz{õ%©Õ()ÕRZR‚u{ª÷¯ÙâÑ,ÙÀ/ü>D™²—‹är<\{E쀆É8ÑË>AÁÌ©@¡ö–Ðj;©P u÷ÚüüȶM³Î]¿¼gÔ1Õ¹.¥xÚܹÓ4pÿåHÃÛãpê_[òL³9Ë<ÆÚ‹I¾×0èž¶'?üÆ?èñWçfÄh´y2|ÕvR Ü.Ñë7h¨ÝÛGm”2.9n±Hª¬A)ÈpÀ !¨WÙûxÅ-³fˆ‡FáPAx‚àAA æ\À’9Ìr״Ђ(A ƒÐGEe‚~A­ˆµaj½Ã⥠`¯bõ¥.Â:äÈ XL££]ê›Ôeî\¨læá’ÈDÉ8a àªû¢‘ɸmÈ?Ÿ8‹¶oæƒ!ŸÆ%…£æ«ÛöK!µÀõ‡<´‚:A¨à¾ÃÉ[»mòÓ| .îzC¥œÝ–‘ÔZÀA Š+®1r˰Ë35š†”›O|†›q\‘f$¡@@wN™Ä¦ð€ˆ%wwHÕüÍãôxÿV™upœ‹¾#ÿœÿÓļ&³­”ݲ (mý7ŠmD SwÀ@C”š¾ÅÆâÙ45“Bù²úùÑËFp¢ý5ûDÈÒköÌZõ;ɼã¢îWoÑ2¾.¸S±~ÖíŒ$]B®ªd3„ùNB€è:WÁ¢ž|]Îõn ‘XÛ“iñkœECÑÀWIì%}qÌh¢¿‡kœˆ«ä½ƒYpãG÷]åGÓýaô.Sí0K€ÙKóEñ…‘rÝ©6ÖÒ‘weDج¥œA­þdèÊ?]V6eƈJ.ò94Õ(¬C(¤"@ÉË®hZbo?‡ö¶ZÉrÑ3¦-ÖÖx­ã4g@$p"®w¡‘æ]¾Ã¸È[|a=ÜS²Ûqn’ïðþ1-ñè à±ÝþÈ^²E©—1ÞdÎ-î«AÃLJ’†¹]±pœŒcØyrMÇmtÍät‚©œ€¡@Ú€€€ z~æÆÿ0[³>/Ä}ÃZ¥ñ‡.kÚæ“rêæ‚ ÑpwÜÛÙx²øë숼„’ÝLyiÔÒÒŠ‚ ¨\<3Î(ÏÞÖü;‘ð¼Ë‰ÛRåb¡&ýÔ ½¼à×$”#¤Ög2Ý£¥Ìœdk0*À˜ÄС¨F²X=Áµ?—ì¾ÞÜ1ˆî¢†rÖ‡¶A¡ò5â…„ã9ü+ZÔõ®•ÎW¸9ÃŽÌáž_o$‘T–¹‡[X暇OŠÆ”¥RèÏlC5$xî’ne cðï€Íé„<&0HÖoùq·3òþ޾Oþ°X¾uÊ"Þ»¯îÑAYí쮈J/„þ.Ûwˆ»YU Aå&ñ±¼± ;£ÉïŠPç­+ù‘´m¦ÿÛa.kOÿÔµm’¸7C6]ÐïÐ9|>ÉiGÐüqauÛÂb^Q.¯ã]62‚ûÒ qRrvà©(UP”t±’î˜Nch:€içémï16å…ÿ,ˆ8³GÝi“§‡µ ×…]ÞPƒk³3Wvœ/Cä Žš²Þ¬ü&ŸI_Ÿ»NK…Êï_ª¢¦UCœçPÂsÆ0˜Æ1¨˜Æ0ê"<µö>6Ä]÷ý•óMõ×p4·¥väܦF‘†´Þ_פ¥è£jI]í¨Ï@ID|_éò±l½ LD»4‹ÙÂÐB¸Û´qVye,­mã¿}uJØØÙ¨ÕÚžjEMOÒ©Û‹!sdÛ ©æ}›i¦7=ŧF’Z(:(8ìo¶ù¹Åœ!·ÝÞ`1m»DD»Ã§6£_.±w»ƒ<ÞºÅúI×Óé~Œ>%ÝT“ýH—KûíÔc8Ÿrô£ª‡Äwzb#Ìy›HÃå-zó-bÛ~YE(ûG%ÿòæZ#®Ý6ú’>¡c/úñ.«šÆ¹+4{I³¾5Æ2Î`®lÍ’VáIëèä-Ø6’O×™–xò8Åv›dQp²„D=òY »¹ð›K“69ÃgÇEŽ·¤E­y–G5¡Œk]âÔº†§ì€^x4®žk”Ü\Í»Æažb½’öjÈ šÀI{‰oƒíÒVReLìÔáÊèq Ä~XËÙ¿0¦Vn.¸¸‡ÎÌf«,͹Ð+ÂÆ‘bÌ«Q!ÊÙÜ뇤DH"A Ÿá÷G:wͰÈìü~7¶Ü\!t€P€ã]:«®†£S-ÚÂkÖ Ü2XWíIÍ–ä¼¾ÈfÀëXMA R´¦ž:]3œ:¨³G‡Ù~dø,â¹Ï öíßmY¨Z¹H—[Åg‹¾^ç.'2‚ᩞÎÏœ|TfåÐ o”Þ÷Â>[½­÷Õ·1°mß“ÚÏ’ïmŒfDzè4Ž?V£ÐxSŠß¶´ÛN}•–;F+ˆ¬»¹ÃĤ’_Ütнü4Ó¬q¯†žÃÇÊ<½3ha0’Æ€ÓQ×ûý@ÿzŸó9!~×ÄWÓ$ý^Ȇgò4ôf®¼\,¦/«½G*œà7,àŽñ„DDej"""""5ôvß²ûŬZº;¦ª‰æn»›‰4ô÷Žþ’½ÈâíG{$¸lTLvW.4d™À¤&˜Cß Z§¢e!Dl ®š›wQ—¶” ´þb³‘EÀ5·ë/…Çð’Oô/{Ürºã’¸©$âI„~Êâr^1ÞšÞöGpôÚÜt¢,nìI¢·Ð©»<­¨þè–nçt€BÝHAðŠ©ˆˆ÷ñ›I.ÿ˜,ÕÅà­Är_ÒelL#ÿÁáÿ„•ÞÝlm¿'1pÛBöZê êÒ8ÿ„/ð]¨Ý{ç=Xw• ÞÑT{ûÅŸ7ø+ëL¶9ŽÛ7Ò;í}Îcÿå¹|뎽ss¶‘·£ïQýö¯_½¥ ãd=¡Çͤƒ’m£æwÈeSø­Þe‘o 'H c(ODTú”DÁÉ_'rV[›~Xn›:ýé‚åÌ¡§ŽÛ0[Ç«8¯¡ù£oÜ,4û»ŒßøMÉüUYíOéçFqi2­¯4…ªýÍe4•^hÇ“ #$ùc²´n &³¶)¦¨v¤?bŠZ“MÑ+”—<ɵÅÝü mc-«î%tÅ¡úšÏ¼eaÒ‰«Ç¥mƃcÜd-þ-žî9Ù îÛqn’ïðãQ Ç 7‚Å,5uû(pFAµò­ƒ—s;{žÓ]Úñlj¸2pœ„kÈ—Í$£`5QËGlª™È Ž÷ €€W¤n,w=÷FlWŠ6€¥ñ‡.ii7ÐA¡ZN÷”˜ ¬Yl}î@]ÂM55妭- $OZÂÞ2óÖ6Î\UÜYH8•´ç-ËE³™'1p‹»šˆˆJ%ÙÖe,Ù«½äZ³A >àÄL4×JõžJás›[jEƒÎ´2ê9¥!¡Íx {Ë… IIq¥zJó®idñ[ƒpÉ–Ä»U»âŒ–’æ·I¨p€tu.´M]JQäå½Öœ*¼’©ÁMºt÷©Sµ:¥;‚–”êªm©-N©ANà¨-N©AMºô÷êhBuJU:½Ê^ê”î T¡:¤*›jKSªPSž µ:¥6øûµ©-N©N~J\SªR©·_v¦:¤…"Ôê”ë©-N©áÑRZRǦ¢”èN©MºtÑáN©@ô¨BuHz’Ôê5%©×± 9ô©-N©ãÓSNÄêútÒãÖŠ¤.4€p¤ZO… yêKS¨W‡†§J|UÀÜÃRB*Î*TìM\Ì4¸õ§T€z8pW…"©Wm©¢ujà~zZS⮩¡EUÀÂjhª¸<4´¦®Ì4¸„T…`8ÑÁ:޵p?pQDS±\ J‰ÔŽ•®´¨Š‚¬šTN[x)QM Ξ’ÞTy×T|f~noŸßlÇí[¿ÓȾîÚºx¿ÙÖß¡bÌþÃg+V[†Ï P…øòâDÛ¼EgÀïfœ¦+æt+öã•þVí¯øú¤+òû˜ÿ>fëï{ÏÖ$]2 sÖýÅj5ìHæ(ð§áH륧±:¤ó›¤µ:¤óù* Sª@>Þïr¤µ:ýk|·â\sQp1ÉŠ¯e^ É¹wL`®p&ù€ #¸™DLm<5׺¸ŽÒÝ÷SEK€ ®{x]q3`í8Óþÿ©~½¸c¶m<€l{R%©A`fÔæj‰H‹éiyUP;éG‚)˜ÅŽÕ/h±À@‰ ]wJZü§æmþSzoÛì•Ë¿4á¨ñk#`!¬oê´4t¸’zI_kòÎêô!‚6Öáò¸5ƒq$ç“@]C@Sä̾ò,î—q:„CxöÏdSh†úG~f(è"(]¦gæD†ß16ð€—NÿÚÚ1]†²(4’9¬.r²„A² Z‹xÖ¨¨‚@& •c2”yké¼&ÏÅ lÎ2Û‰mÚÐØèàÀI5{ˆ'ñEI¯Bð»ýÁw5ç} od‡\ƯBå¾ø»ØÙᑈ,¤&Š´ÖÊÖ£¨=‡Æað·ƒ\åéÍñ‚}Ÿ|vÎHæŒÄu·„rMÒ'•¾lëŒ!˜ªöy]Õ_ÊLcÙùËfU„Ë•Œb=‹xâ-ÒÚ®PYS(ªß+í~`s’¬nÙÜøI²¸H˜dŒ¿ÅgCZˈ㕎`Y¬l!-h o¾ç¶.yœóœÁe#Çå%ñ¤cÃx»¤—B÷ÆàãÐç±åŽ>7ŒI.ú¬n¸áMã<«Äo–J=ºdåáìÆ*¡õû1:ÈKBvﺯpEt@ÄA""Øç ÕÓQ1ŽSp󧛼ǵ~ÜØ›zëà²K‡¹ík¸Løà†Þ Ð¸—<,s]B±ønXòëeNÜÖìÌ[ß>È@hipâ+_,“PŠ€4´žp^RûB¸ã–ã{*C#n°‘€Ä6½ic@?:a ùËó ·dúmŽ«rJÊ¢I¤N©¶LSçXêz7(yW/±N‚W6|ýÑk®%h:@mtE4:RKˆî$hn—Ì]ÿ.ñÈ £k¢Ä[‚!cˆÔkö¤}8juÑ@I.'Øþ -Ì?5즻í|ù>½§‰¦nKª&î¹›8]¢öñdnË}¬4ÂnjøŒuÄ«EDë"«RupQC´ ðŽqKŸÆsþÞãkÄ'ÎÃi⌀CôÃ!{%µÕx !Ü|BEë¶}Ê ¡ÏHbÄÉq+^ðH,¬Œ u@4£ôž ·ûCMWGbÿfß6 ÊÊû¾8Î÷¦ ‚]ŒÉ´˜¶#]\°È,ÅÊK£xHÄ·Žv‰®»AYGd"u d÷‹¿æzÝàßÁmœ¾î™† òÙØžE ØÎå¯/oÖ¿KXhçíVß“›^ß*ܶ[;e.݉ÂBÐX×HÐjçw¥¡§€qmK…CCIa?´ßXÎ*3ÅšÏ?yúk…SxÚɸ‹ˆç—<“Èçs—s6Ë$Ýã&<+$b•`M¯l%LVɳrW•÷;3oÌÌës™";*#¡Á’ kG½ÒiWiÁ¡ÇÍ ùæËÆìSœ1V@ˆŸBÒ÷’ ¤€@ñZ7Uu£mãÂoµg XæXÊþâ{£Ú4}8´\r K=lÙ¥ÀŒ#i×ñ,¯.êYšO=³ä¥#WE=MÙ‘Auä'nïÞAn»›¬MŒÙ]“tî†8è–k,kŒ3D f·0Ç &‚¤hôoï£ÍÜù¸ñû¦Òí#Æ è-Dò´5Áì q :øîໃn fÍüFñ#‰2ª6ÜdÉmË »;rZ6QÛ¶.cÌämG2÷<å(FNŒ-š¢Ð‰´rb®e³)Ë—ÜÜÉæ2웵v> !tÏg{rçH×4Nô2&BÍCÆ{žKÛVDv dlítwéËYÞÚîîÖ88E{²é+¨|V†€×QÄð¨Á¼1±®BöÙyµ¬Ÿ…±²¹5høÓý´-›J؇V.%WjH¸÷o’hW/TÞìý-ÁÀ`Ý0úÎghe1|“¾Û }ÎW<,ð$šY¥|šÜ©Ik+¡¢ …ç˜ÍÇaÍ\뙆 Ý´†’ÈãŠ6³H.#KM58ôjqâQ{Q/Ë'!ñ¹%qãûÆÖ¾­ÓØV3"OY× MÏ wº#¶…”„vù‰œ¶1€Lß ˆoW_ùyÄåpÛ*,ŵť躘˜æñ<áBXð×Põqê\ÜäÈØd÷D—XÙḵ6ñøÞÙP F¦’*:ÅVsû^4,ÕR¶)7Ì™€5ŽšO 6îàÂçóRæ¬o,ã™Ñh3Ã$Aô’btÐê ¥hí[O83X|¦2îÚåñ‰5ˆ¥d…µd`j qÓRM:bàþË;öÈǹùiûþòµlhÆ7;›¼n‹f _8”¶TA˜IMÓü=bÛÙ;%ÀàÞ$l$Ϋ7s ưMIM[7ŸN!¼Ûئ7ms(Ñ7`ųääã–@‚cd8ºÕ€ÞüÝ78«)r{6åßÔÔ|@If²Æ¸Å4`–ks rh*@fÀ2ûWšø È]Ga¹àÖ ñ¨ô‡‰#}5iax]ÇpÿÜ"p…*¦fâˆ\Y“’·c¥ËoÙ5·å#¤Ý:dᜠ°æVã‘»¤ˆÍÑ…»dš\‰V2ƒÙ”ÅÊî>aï¾bÙ·llÌ%ýƒ¥{;Û‡:F¹ êw‘²ÔxÎ/%í«CF¢C ³6–˹9íÏ•´»µÚ! cƒ‰WAsÝ#¨|V†€×QÄðªò+äÛ[2çÛ!Ú6\=…mMH »iÂFEIJˆ„‹bÖ*8ª³‡nÞ<²O[²/0‹¥”ÐÆ.ƒ_Jl Ûwkˆ¼¸’òþ&ög¹Î/‘Î.u Év–“¥•㤠€W†ï Äy¬¼ù+hYmg#†ˆšÐÖ4¶¡  D N§õ‰¡_I¡J +Òx-¼S•M´‹Sª@S«¢ µ0R‚SBªPSn=ÚR¢uJ sÒÓØR‚›j SªPS«¢¤µ:¥:êhSªPSn4¼)Õ()S§±:¤*›jKSªP?pT–ª!TÛ¯MM(Š¥:B—UJ uôTÐU m"Ôëõ¤õÔ§T€}ºwxªKSªP??’¦‡©:¤9† uJ¥@zª@?0Ô–§^Ô€z‚ÔëØÌ:l©-N©üþJTìM ˜{¿ÃKÂRùéP„+Þ‘ju)ãRZGR¸<5:Sª@8óëRZUÀüü”¨GB¹†•{S¯j¸ŠŽ ÁJŠªUÀÚxjHEB¸ž§J|UÀÀ=á¥DUX !¶¦5p8tR¡M\n´ªBu*àq£‚8+‚Š"ŠÀ4¨Hé^€p¨–ôY‡Nú‡-~lï¯ß|Ïí[¿Ö$_víÝ<_ìëoбfŸa³ÍÕ–ÅE; žhЊ/Ưæâ?ˆ÷´Í¹X9Ê@ óßi¯jòÙºšàÖ88p=-5 ±c,bg5„jèýÔ¾»ûÓa¥ÎÉP;£2@ñŽÖ*B¡Šæu"V]Crœ„\ŒÊp×@=«¨î¬>ðâwSJöþ4¯"– ‚+¡ßˆ…ÆmÉå‘I2ª·ìÙ9;6.Ö§!¸Š.C³n¡{6ŽJEH"tôï×ýÕ£".–Hõ4ëP=‡á}*íY+ŸÝèêtp¡èãÕÒ»ÊÖ™›R5{_ Ã9go$±¤XJLöq-Ù–& #£ó¤ìL@Ý¢(”ÞQéËZ®FLtÒ6ç 7nÚM#¡Ôé¥WJÊÛÃsLw -ŒW¦€Ôq¨·BÜ®kË5«3p–½’íV(*ÝTõåÝ:'ÿ(w‡–·,LϹ°c¥¾+‡ao¢e mµóÚÏönñ‡€ÿßTeSmd V:©ANzšꔪm×§»Z\ª@S«Ê´Õ:¥:ú*KS)TÛPZUÄÀr‰L€†ƒPYQCШ8Ž ®/iµ~aU0ÜPyuAÖ°×xˆç:›Ò²vùÅâž…°Èpcn™c‰5ïj=êÆÿqÉÐOÜþôe*ªæp–ÓXÀ@Êœ£§~²v˜¸­øÓŠèÜ_¾nKÙhŒ­‹{³>1ÉV ~F–•”<^?{xÛ­oyÔÈV{ÔÔaj/"Iç„;6Ê*›s¤™Œô¢!òùÛ[‚oæZÇ9…ã°M‚0ë‘ ¦‘o3H3÷`‚@¡wI¤¯£¶¦o$.ñR]Û7*é^D&V H3FA—k5Ÿ³Ð ê^Û–¢®™B(bƒQ¯¦¬q/’M%xeÞA¬’…v,¨„z€²žýNþ¦åk5iŠd[ºV.ã éF‘з‰ˆ²‰èb†ø èÏwŽå´ë\V÷„Ô.2À;€±û=ÉäÒ°ÇúÒ§JÉz7¦œW5‡·[Æ¢bœÁ ˆÖNÛÈJq]ï_3«Ôí¤Q~/ü¡6õq·ÖÍÞõÕS¯œè»µ¿ÊGI° ~PÐÉ]‹›a‹¹9›¾wÎ&m­¶våõ´÷mÝãô±Üʘ¢da¬säuK†HpÛ0{iíLŒYüînÒx­Ý®6 ÔáÅ®á$Ž~“ã1µÔ©ÌŽ3øoŧY&«¶Öd$Te‹bñ;7ÊZ°¤^' ñóeff%Þ½Gß GLÂ& ˆû_(ö<»'nɸ-vAï3N[Å¢G†‚ÐzÃÖ2¿Ö-$p+Ëyº£Ý9™r0‚Û6°G<¡¤Hê.sœêuCкÆRÜm,Ô…P ƒ§.µí· ¸`í/,†íð¾ ð\8,ÀÛ€±û-{ÚòiX¿îgÖ•:Wûͧ«ŠçöõºÞºŸNQQÖ²V¶ ·+£qvé…ÌJ§Uw WV©ANòR¢uJ mêT Õ()RZR‚›u¨-N©J¦Ý*KSªPS¯¢¦…:¥*›z†•uJ uT–§T ¦ÝjKSªR©ÕPZª©AN¾ŠT(ªB©·¨iP'T §=NžÄê”ÛÝîÔ–§T€~®Š‚ÕUJ Á©¥T ¦Ý)xUU()J€ô"©û{½Ê’ÕUHç©-ERüÃÔ5%ªª”çòTТ©NaÖ—´ÒéiìN½‰@üÃRZ{UÀüõ%©Õ ˜zªKSª@??’•èM!OÌ4¼)Õ •èE{ù†‘ ×µ zjKS±\$ê=5%¡:«Ã¢•M yéxQ^Õp=¯B~p7w†¦‰Ôõ«‡ŸÇH„pêWóÔéOЏ0Ò¢*®-Nš¸:)P„Õ€iU:•èÏ ÉoC”t0¯Íõûï™ý«wúÄ‹îí¡û§‹ýmú,Úì6y+U[†Ï%_‹Ž' »Ä§¥æÎ9d•%¨ª@8ôÔéNªàpèé¤ZRƦ‰Ô,ºÀ²ní“°s’®î¹†êFYé²Px9 7mÓ‘¼£9)D·vÑ&{ÅÉu= ¢D5Ò÷;,ïíÍ•ûÚÌcf¸ÿã2&6ÿhx²½Òqš;£Q![Ö"9mìc’÷Ť´ÿd¸ŸÂ;Òõbâ¾,¢ZSØ®Š!bÏ02“nc·`÷ã çOdä]H¹xåc‚Š*(î Óå•,ðÙÙ3po9|Y¥¿ûόǚ½º"kXƱ­hZÝU¡è[ìw°Eg&66-ˆGÀôõ¹Î$’I4&€à±êÊOcI+fÁô)ËÊžJBkµŠX±æ`Ì¢éI4gÔC&]æL"";Îç¾›rn(ò¹ímŠ2ØéÝ3V³À¸¹ÏwŠ ñkAÂu1ï8ëSmdiª¤“ýcBßM+Ú±[+ÚºÅUäD¢AA“täRNc³ª›ÄXÇ•”I”jMÑÞÞß2¯x“—~Âgv´÷ÝÙŠéÒ-% 7‡M$þ%‡¼°»kìãÓÇ£²µXH³"Oª¢· ÈѲ+˪V+Ò©DD=ñ‰p£aŠ;½ü3Õ±ZÈ!¦¯u‰‰%•¥¢wzš½»v´”ÈÊ”aíkqÂÅ“¶žÄ¤Ôc6…AÊŽ»PÊw5Ð4Þ×½ÉZ”ù˜ÍÀö[#ƒZ$ÔÒãSð,£E§Ü¦kÞtpâ8žž¥Æ®; 2¶mEfßM̵E»øÒ¼·n¨¶äUÂnÜ<1 Ýx¥ÌàSéÈ`(ià¬Ø›q\Êö°C¨#[xPtb½œ+ÿ¦·ûnH\Y¸b ÙÂÛ±³íˆ`Ý%ÎÌW v…)ŠþN4‚`å×R‰uõsœniÃSîŸÓý ªeÍ›>Í»^>’» ƒf~›Þ"Ù´4pDníf—fRM3iƒ„‚8tÔG”G¾нÆI+÷‹«‡šIOÔ?Ì»L¿ Å ÞÊT­W:Ü-´½¸ª×1m§O"Z,»¸›RÊ¡'èm½<ȶ(ɦAtQT8{”+·q6RÙß’{~Ûº*hhMkÙõ®Åíëû÷ËÓV´ô V”!b¬­ÓsK¨ç³ÌkªíMÙ€öZÖháqђﺆÝ'€qúÇêXæß]HÆ»¾&¿WÔ¶ÛžàNï4¡4ÂnNÉùݱtäȱ"ï cvÀ€:Q@ß05åÛ]KhÙ÷'21¡Ìs™ÑNƒÃ¢Ÿ÷.Ôã/‰.i wOhãÓÚ»/¸{öpÌž÷¢ä´ASDª·UC¹HÔGû$Êp&¥8sVW÷eþ½ø¨íô,&ᎌ†N±©§ê5 °ANºÎÐ-f©M¾>í)§T ~%AjuìJ s IjuH TЧTÀ§]*êÛ§¹Hµ:¥÷AjuJU9†¤µ:¥*hSªÙeâ“•(úò t/,Ûr(WnÚäÀVáÌ‘È%ä »ka4Ž…3Ìev¢·Sú¹ËW R•Mµªª”ê©¡N©AN¿%*'T ¦ßN”ꔩ-N©J¦Ýj SªR©·Or¤‚SŸÖ¨R•M¾:E©Õ()ÕPZª©ANº‚ÔꔪmñÔЧTÀ§WE*ÁJU:Ý©-N©J¦Ý*KSªPS¸*4§UµËF!*€¤§. <¾}Úê\Ú¶áš\»\:T.¾=‚ A5L ˆ÷€G½­`Ý…p4i:VU¹0EHâ¹½k¶ˆþÓ@2Ÿí‡”u®ý¦5–ü¬º—7¯›‡Rç%S@Ъ²«¥T §UN’R‚äTN©A]¾:šê˜ç©-N©J¦Ýj UU)TÛ§¹S¤§T §^ÐþŠI‚”ªmñ÷êhªPSª‘juJ uÔ§T¥SnžçôT§T §pRLÄ¥Sn¾í*ê”ê©-N©ANº‚ÔêªmÓÜ©-UT §?“ú)qLÄ ¦ÝzjhT §U"ÕUJ mÖ µ:¤6éRZR‚u4!:¤*›téîÒ—…:¥)R½ Õ(˜jKQT€~z’ÕUH s»Z‚Ôêçä¥Å:¥6ëK‡Z*´§R·ü5%©×êH N”êÌ:ô÷kRZRùù)P¦·^ï%.iÕ •;^Ä€naîè©!:ö«úêKS¯b¸<¥I Õ zjt¦®Žš8„ê4¸"½©ôS±?¸¦‰×µ\=5$#À® -)Ô«€ó I©ÕzcÂ:[Ði9J>2kóW}þüfjÝþ±"ûÃgþébÿg[~…‹7ûÖ­Çé[GŒhãô¡~'8¢6œLñQöuËɲÿ¸¿p¹LßùU¶áüwêp¯Ë~`þþç?kÞ~±"èÐ0†·ò£R4¨B¸„øõ$s .íWóù)iM\ Ò¤„ê»âؾ$¬·ökæïå±R)á»n–nÖUË9-Y®DÀP6ìТUDÁ¾dÌÐy5›üU¶V) {é èK€:A”8}!•Óô¯B³•ñXC§ Æßõ?γ/[ ú䞺̻‚,Æß¥p+µœ3)E”„nvM¤ÛÆÌ‚ÅÜpÕœ„`.;¥WU›PPÇï‰Aþµ™Û¯{îd‰ä9Ѱ´‘Ð\ uôW‡Ô°»™´²ü@t•´ Óñ.. mÒ¶ÒÕ¥U()SNÄêªmÒ—…4 §pR êL…SoPÔ–§^Ô §UIjuJU6ëPZWzYü5ñ[äºìœ•®›id޳YÈ+䑌M08œb¶Ž:RÂQLCF¨ïh]5Ò²ÜÆØ8+ó‹Ìæ±vÙhèå¹…a4ûm/?×ÓÃBÙñû3wemþ7=‘d9®èÚ;£úµ]E%' ò&f=ôL¬s…ZHFI´pÂA‹´L$Y³Æn“IÃg 41R˜£È![e½Åµä º´‘’ÚÈÐæ½Žcšz×4Aê Э~hf¶™Ö÷ tw 4s\ \Ò:A„ÖªùM½C\¥«Ž©AJ’ÔÁJU9† µ:¥:©P§T §@ÔÐ'T ¦ß"Ôꔨ-UUÝ–gù÷!Áý¦±°ÎN»-ÑŠ36MÃ#ðSíRG¾nÀíä•HɈˆS b€é™Ž`lLï÷no1µÈuÇ-ÄL{kJkiuX x©l¸ÝŸºòö¿}Åão§³ê|pÈæÝ$6ާXmHúÂêéX¹{~Mì,ô\”Ìkƒµ’‰—dæ6J=Òc¢Ÿ0z’.š¸LGßBÁá Ùín­oí™yc,sÙÈÐæ=Žcšz \ÒZàzˆ$,ŽŤñܰÑÌsK\Ò:œ×Aú øÁN¾Šç \UJ mñÔ–§T §UAjuJ uÔ–§T¥SmM uLU;‚• R•Mºûµ%©Õ)TÛ¥AjuJ ]Iju]fáü¿‘#šÇø«$_PÍ_+æZϱ®{š1¼š-Ú»Z9wð±oZ¤ý¯QTȘà¡SX†ÐåÖòû¿iíû–Ù粘ë+Ç0<2{˜aya.hxli-.k€p%®¨+7ŽÛ›‹1¹ÄØ^Ý[5å¥ðÁ,­Òæ5À84‘ZЃÐBäR|;ñ #55‚3444Cr’ÒÒ˜Â÷aÝGoäd_»ƒE«&,š¤uYS4Ó(˜Â5жæÀ¾¹ŽÎÏ9‡šògµ‘ÆËËg=ïy kÖÈKœçÐ $€Wn}»í`}ÍÎ+%´l.{Ým3ZÖ´UÎs‹kZ$’¤®Ÿ:ú+n-Zà)J¦Ú‚ÕUJ utTéìLÉUµî¦ÖÛ+É͵>…¡%$´<}Ö¼4Š6ÛùvégL§Nرn¤I#èS*R”DJXæe1rd_‡Žæe£ŒHøŒ362@tUÖI8€ÒH¡]ÇX_²É¹'Á3qÏyce,pÏK%4— - u-Û§Mw¨ ê×µ0)Ü%©Õ()·Z‚ÔꔪmÓÜ©-*ª”ëÚ(¯bb©·Çߥ@SªPSª¤µUR‚u©Õ)TÛ§Oz¤´§UºEGÊMÈ3ˆ…/- ¹0ŒŠhâBAó•9nÍ“TÕråsøB˜Ãà ë]\ÛY[¾îöHáµµsÞàÖ4’ç8€í$Ío÷S6ÞÕ’áækAsœOPh“ô»>êÁY²Å‡ûCxâ|‡mAµ˜š´g#㚊›€™æûª8çÏu:t´:®œKAë ;Ú{£m÷Ì–>ò N·¾µ£ÿ-£~€ê~%ÕeSn•´­~©ANº‚Ôꔪmê’ÒR‚]•U)Të÷jhT ¦Ý)ªªPS® µ:¤*›z†§JuíJ wJu[¤T|œä‹xXçÓòncÑÃù)®T*MÙ±bÑ5];táSHše1Îa®½ÕÍ­•»ï/dd6‘4¹ï{ƒÆRç9Ä5­‰$€Jæ·‚{©ÙmjÇÉs#ƒZÖç9Ç€ h©$žR¾‰h©{zMì$üT”Ìjæk#0ÅÔd›$Ó}»ÖRAÓUɨjES½ê‹K«L…³/l%Ž{9©’F潎ok\ÒZáô‚B»›{›9Ýkyâ¹a£˜ö–=§±Íp Š¯¹Ý¹rÇBCܲüÛrâ;äíûäKö°“ªE¸3I4áåVnFgŽtQIpACŠ*”ú%uâÈãn/fÆÛÜ@ü¸i–&È×IxÔÃ$`—3[|fêPâ*$–7ÐZÅ}42²ÊbáŽc„rš;CÈÒí'ƒ´“CÀñ[@)·Jí–®µR‚ÁJ…0{M½CK‡ZuJ祧±:¤íî÷j Sª@?pT–§T }ºÔ–§U¿ÅÛ×Ó ™Hx ¹XËq²O. È§ÏØA4\çMS/ «x¶Ë(™ŠE2e0”@Dº79,}”ðÚÞ\AÍË‹bcÞÖ>WRØÚâ È  ·oc}u ·°Ë%¼ ‘ÍcœØÚz È0P´‚uÜ ]T€p¤Zª¿Z@8óÔ¢£À‹UU yõ¨-EUÀáÑKŠi@ý~Z\ð¤…Sª¸˜jHE{Rùêtªª¸˜jHíERÇÃËS§±5p8søèâRÆ—pW…*'Ç©\ ÍH„ëÚ½Já-ë}°éßI!ñ¦Aäñ׿ŽüýøÌþÖ»ýbE÷–ÏýÒÅþζý sv=ÚÖ©ÿn…±)Ø÷kGýº¿ ó—Ão&A¸k÷”£þUmŸø{úœ+òߘ5ø÷9û^óõ‰Dƒ¢½…jWxjH Õ\ÏKJÀÜÃRBu*àq¥Døx„ø¬ýáfÖ°²L;«{#½fÙx™f,.ÎÈPP¥e1©*Ø®ÖE·¤‹cœ ¢NÓ7¾˜µáüÁÍn-»vëœn– *ÙÚ5jh5{ÚŽ%ºÀà[N{Ô³Çå,!mì¢'†Q„Ò„´é-5 vÇ¡f]ÊâÚ‹;´Å™êˆç|G tìˆ)»bš´D…&ºróù~,dïešNíŽ"MÀPº¼ZâOk‰4Y›è ¶yŽ*<4‘¨Vœ:8Àº=ò-U6ôö†9Îc&át\{³X"tÛ  S€ººÖóo$ÌŒ‰t:ƒ¨Ö+ÒOWÒ°R†Ö­è[S(øÅc§"&£[º„¸Ìñ)ÖÆ(œ’MÙòÙN]ôÑ @£¼÷À 4ï"/s$µqmËÓJñ ð÷öp+‰²¸¾ÁXÃ/·¼œ^J䘈zví£!Ú,“uaH¡Ô¥ èê&w*¶ä1S\Û†ÿ-g¡Ý»Šä‹(àcdŒMzOgi§«é\BÂÑÕsÜü:ðùkaù †ç†œuq’êdÍ87Ί܆g¨Û–ªº§dºª»L¦*Å0ˆ<5ªîLÕæWL tN:À¯:EOObîE¬žéÇU>•”ïÛBL£gì“{ènÌ".›”ÄIôzåY£Ä¨Š6] ÝÐu.µ©1·1=¤º­ =GªŸŽ«•²ž£Ä-åÀ¢šn7Žeç÷¤Pºo Îrˆ‰Í®¿äë]i-ËYZŽŠPt ó®Q3öŠÐË‘EWQ¾è”Ü@ê€ t€Â:{ã”F˜Œµl½5¯ƒÂ¨=äTNÅMÅ`0‰È¡•ô(¨•0H»„1D…0‰‡Qðìä«€é#Å"”êÝ)§T ë ‚Ôê®ÛÝîT–§T §=M uJU6õRð§UœÏœUgåž#áÓÈlI/aã«^éË7\"‰tg#¬v$vÖ)Ëeqã'.Z‹†æ‘Ër#éÄCÆ9õº2Û[—³;!‹9¹†Æ ¡÷.-sÁZá~‡ 8µÀÔ霦ÁcóÛÂ1–h“g·R³¤=°¶¡¤u´¼·Sx‡6­"„® •øÄâ,߯¯—Ù*ñ¶ {[^سîy»rÛ²#˜¥Šˆ¶#"1lÁ(ÆÉ&Nܤ œ¢§2‚&¬Þ×å&ÄÚØ6a!ÇZ\šiáŽY®^~Ü“=íqqy$é'KAÒÐX¼÷0·f{*윷·xß›Ž_p´}–FÖ††Š ©ÄUÄž+(3$œNðAmñ+y&ƒœß‡rÂXZø¼Á² ¤r‘)„ͯ)q(܈¥!7åê “WtV2ETê‰Ê!æ»FѼ¶çEÇ.±ÍÙy|YÈ[[Ô–ZܲC̈Kc”5Ò×Hq`m(Ví¸®½¹gòÈ€íÍŽ¿sM@q ˜¤¥žÂàÀzHÔOH_~Vàç…®®è[S3q?v%!u[öôÜTU•‹BfJÙe8ܦ4ýò²³ Å¤Y•R¢ÍºYûa)ä)¸6·79›¿±Se6~Úµ0ZÏ,o}ÅïvÉÿelZœý:K¤“DMqÑWHäÏrïcm„v7p%ž(ÞÖÃm­Ñµãý¤Ä¿HmjªBѪ‚ ·W€‹õ§ {y[Œ­[VÊ[-Îfw/öEžA’oÍ’NUU@2jvhÙL^ß±)œÄÎz`ååí¾ö†Îáù;«Ác<ß» \[÷]D8]æŸödÈaʬ¬{Æm¯-Ä-±‚ØÝ>ðƒÝ 05wúA' éÑ«íÔjÒ Öû ÂÇÙ±­Ùnð½o Ó-Zì…ÊÆÊÈ8ä–ƒLŸ™Uš I¤Ì‚í%†ª·`ùHX ÂU“é^s?~lÙmrËÂZYí[»†Bë‹[¾ýÖoÒ?½1Ñ´9„ø¯’7im âKîÕ¶ÅÚ{–;‹M‘”¸¹ÏÛÂé öýйk_Ü8=Ä:œZÇG£€pÙ1_ ¸Âãá¥&2–p[Û-rÃüy) …ž­É1,›[sã†m,ä[I¶4¥Õ*ñBp Ú6d“‡j, ‡f~îçæ~åÇóܸÛ8Q‘É;Û¦HgÆÂé{·:à–1 MÔ÷Èèâk*ýC«ƒØ˜KÍ–7¦s&l¬›~ëw0Bd{€X€áªW ;KZÀùïIã÷‡kÈŘ×=áŒ7bl3;i˜.Ëu bîµ.û|uâeÙ³bñ)ÍÖYP0„OAÞæÈì^`fó[Ÿ#±w…„6;« sþbS4Á-(øÜæµÍ,%­s\*I¨¥×´1˜Ì–êÛ—rÝà/$|_ŒG,RÇÒÇ€ç4‡\<ë¨+Ч]zÉjóê­îÞuÚvÄóe^Á¡-´Ë$dÖy“ÄO"Õ”éЏfS¢(€Žº‡~ºwñÝÉc4vN ½tO¸ô5å¤1ÄPÔPžv-.¢}ÓKíD/¤°¨Ž$Tt¯o¸Žµ8¶Î× ån òãË󷇶‚ôpÎUoe<Æì"¡#›))`nØrÎi6Êt©.ôtÓ1S*eI?Œ9y”åNÈÃ|/ÍìS,wæ›ï3ä,ÃnÜùDŒºîæk£, T–ÇPçââç}5¼¬9º2_ßܺÈ:ëkãî"³º›vµ¸Èxp&”sè@ 0+‰kû0gÃãÜŸˆå­®!m¸¶XÞfb]›È»»+/+*Í•âZìTaRzŠÊ*šNˆ£„ß ¡9LRB½Ë—8-¥²±|þÚËEs°.%uÜqÆæ¾ Æ9×’5ï«H .a 1è ’Jò­é•Ü;Ÿ#ŽÄg1òC»¡`·{Þ eº.pl%ì-m5À¸?UA‹³¤øPáŽË¾Ú`ŒƒÅÌfnYÄ|,ÄŒ7ø×Ú7„¢hú=¯1p¸žc.÷°tá4W|š)7ncÿnŠj”šÕ·4¹“˜Á¿|`vÌ2l°×É%»Ñ}=» ¬ÑÄ"tm«Asc.sžˆ^ÒsSì-“Ê·jåó’3sÖ=Ì·×iÎ¥"|…í{¨Hx­¯¦Ž¯`ø8ŸBW‹býž=µtð¿b¿¼gl.Ã7)œÇwN\Ç.Ê&n-D·\Q2‚‚å&¨~÷›¶/µÚÙ<xÆn[æÀçètàú´‡>7‡1íÔ¦š8Ž+mË›¦OŸ±ÊÊ`¾ÁÚºRÝM–œ[BKHcÛG5Ô®— ¯°F i˜¬Î n·+˜0ž.y‘2B1'éÜ 6Qr[…”zÔc’?cþêR¬!¯ù5°o}ñ6ÑÌ`qqÛ6værm´./-1Žkµž?d–øV#kmX÷7-~ùÌGbn ﯊MFžŽšÈ{{„\…°¦vÍ\D«mœ«w({n>Ëyp]®& §RˆbÊ×i»Ó=ŠI¨,æIû„’M™½!Îè¦&æÆô»Þ9‘³vø¿Ébä€wϸlPåˆÈçLç†éyv–CLƒ¼y-vû>^í‹}µŒÝ;—0lì¯Ù/æÛ ’Rö<1¢ Òu0 ºG¸Ï´%àŽ'Ãf$³±¥–¸‰Ë%•“Ö˜qЬkÍFæ¾®;V)âmò—<œ¤LU»àU!ÐI]ãºI@:gÔ @ÊÞóuå÷%ÖÕåö*ÚòïØÅíÍÍÁ†Ú)žÒï»Ç¡’>WŠç6Ž®Xë]—·ñØ[}Á¼/æ¶·¾/6°A’y"i§|ýNc#i¨-‹¨=!n¡ÁQ.¼•aÁbLµmÞX²ý²&²Y²t“% ÏaÙÖš¨%y+~Û>–íäL¥¼«¶é1P©»UÊZ"‰Å>©ç!ÅíËëí׊¸³Üö7±ÙýÍŽ}æâpM¸µ›KZöJçBXÖ;ƒˆhw8å ¿ÍZZíü„8+»WÜýåÍ,0Cc(y4 , ¸—4}­Mn¹6mŽ;7·®s„ɽѱҴBøåcƒÙF¢Ð+S¨PÑGÉ?ü%AÞq¸š‰k®bþ~þ*ÕÓbc¸ù¼Y;4 HÝ™%¹BNu“'.Šš®›>ºˆ$%9K®·~óZ÷&ê°Û–°àcò6 ›·Gzø£©.Ð!ÑœHcÍGki9“´y}k’fß¼ÍÏ&Yïk °[µö­{éA«½Ôö´ ›Àÿ£BÑ85}ugŒÙ‚o;ê2Ì’ÃÖ%Ýw¸º Ðîm÷¿g¤-¦ì\?QuZ9‹€¹ñWŠ*Ýÿ¹k¹¹9Ã/cawÆÆKË|½ôui•½ë&. 8>V¾YP×8ý [ Ëio÷^Ojä®Ùm>6ÒYŒ´¬nîÝiq$ÆæÈ]BZÙ%}Iðá…o¬”æpng¹okÏ Z®/‹¢6ä°¾ÊÀ]V¤P˜'æm–w&ÍÔˆ+7É‚ÊJA!DÂbñžbo<&g½°öÖXlÍж…ðÝwòÁ;ÿÙGp45Ž/>)1 Ôê4¡±²öÆWsµ²SÜäñ–æy[$ÔrÄÏö„ë.£5‚µ¥€q¤(µrçy"ã±còS©„1­¥fZhÜ×Läd „™ÊÝRC!'Â.«‰&cv®ˆ`Q3h ÞËoÍɺ®¶žÀÇ[ß\c[¼žâs ¾P\È¡sä-¸FZá^ަ?há-0û‡x^Ík ëž-¢†!,¯lfŽ•ÚœÆµÄ:\ A¢Þr ¬`pÜç_ëå¥8u±¶¥²µ¤“sAËÛ‘Œ}!’ܵ9†xÞž è›3¶PJ¢©€(==³ÍY¯çÜqîËâ›·#ÓRa9=äs=Ô-kC‡æ‡u§Œí«Zïv3¼¾ŠÎ,+öíáÈÓålUˆÄ‡ÆÖÔ8öž=x0´Ð¹¼W+ÿ« /‚a'üJM/ ¨ZÎ&Zc£+‰™_\}–Vei¤f”I“zä{"6€¨bH¿â72eÂé܇á.뾺î—榮øF#1‚cüà‹Q}›7/Ä]çt^-ëhÙ맺// ˆd mx:ä "ãÆ7µÏîæ…eqÚRîá¥EAU¹—lxéšÆ"b»ÍÌESt½¢*ÚºW¯à3˜íË…¶Ïbœ_Ž»‰²0‘CCÒ8ÑÍ5k…Mê^m—Å^àò“â2 Ó{o!cÀâ*:Áëk…ÓN ‚¸™TÛ¯k-¤,}V{ð)w[2Ù†·•»²Åç×·0õýu,›(h[ñ3øñ–]' ¡ßÌ“ÑÁ ˜¢‰ŠMå T•ðŽxâr7ö˜‹Ãgq‘Ú¶y6BÖ]$‘ø®Ð263¯S¡Ô ¨Ð\ßYåNBÊÒç%l.a²Ü6F;;‰Hk!>3uCÿKˆê T×vÌ+~>¸l¸~_0/cµ™IÝòô[(X÷eºùƒ´žº—ô) ­H¶Å"¿¦8j‘ŠSTNrŸU½“üÆÇŒ{ NákÙÜHÛqes­sK[¦@xiîÚ÷_h#aµg76MáËe"¼Èá‹]ß1Ó¨%Í!Åú])hã«[šÅ$Wĸb'-þ¥d«Šámˆp¦?p”Å6£'—CƸ$VNÛ²í–;'óNJ€(c¦T‹º¢€"rþ£º÷•ÞÓþíÛxûwe÷ûK"Œ9°µÝÓšâgB(ÇP\jÖžÃ@ÛÛbßpýû7{3qÛḃHúK{Çî›â™x6¤Š 8ô€yeÀqµÏŒï£ÃÞHŸ½ZãQdã YW¥®µvÄÀH,£v÷LZ‘ò2QÓ1I¬‘ÅÁ ¸vÉNqïqXýý¸ñ›’Ïls”™-BÖâÞc4•€ ÃØÇÆòÐMCÜCZ:HÈ^m %þç=³¯fºŽÇI¸‚x„r²7¬Òç5ì¨:€¡h“Ð=_…Ì-ecÜ]’2Î{ql²ÉØý¥ÑjÅZ¥î‡NÛ‘ÁÙ¢F*?I­¼Äª¦S?p™{UOÙ”€%¬|ÏÞy­Á“Û›SÛ™±—î†IßpØá´Ð8ê .•Ô$DÂt´j$‚²¯Ø[c‡°Íî» ŠúÌJÈ™ |¥äVƒIp¶ wޤÐEÓÏ›^V¡4òú·ò•™hÞVÙ£SŒs6ÚìA»2MãÔP~‹òöb˜«¼P‚`.ðVå±÷ÈÜø{ûܼ,±Èbï'·ºYxŒÁÄ»QkIioé¥C€­³ºö™Àäí-qÒ:îÎþÚ­äÒ^%à§QÁÜ)^°M*»b_„èç[«Edfd·±u”ÖñÌ*b!Da¬´o)4“F,ݪ¬ÚÌÑ~‚h"URUuûB›³Ž%Õ-9¹#ö5®íºÇ<ä2—®·°³Ž@d¸%å‘—9Í0â×8µÍkt‘«SAØ.9pÆî˹ozß¹ØZ‰¯.^ x i:ËCšÚ‚çjN“AgÃæÊׂ|<勞ë¾ìˆ×BöUóe¥m«xÀÄn »Û9û)7Àg­ˆ¡L“ ƒ…·€=茒ówí‹Ë7smk‚½°‹‹kƒ0·–J÷m¸k˜ßЇHá´ë¨ #Ù»o=mr6vB{Œµ¬.”Ã<#4lûn…Ís¼aÒá¨×«‰_e‹Ã>0w„ì\픳_éí±rÎܯâR¶ÎN.æEÔ{–ËV ®âEg`Ðë9UDJ“4ÀÛûÁ\YÎeîx·¥öÆÛ_ï ´ÈÇ™„Q#÷:g8ÀÝA¬hqt‡¢”+“±°2m{MÙžÊ}ÎÂydc˜"2<–8µ¢ ÒK‰¡.% 0tÖ«'IÖreµ¾ùyHòÒ(BI9@Z¹ˆIâÉÆ¾rÔÅ)›.í‘H¡Ó!Œ! i^½bë¹la’ýŠýÑ0ÈÆA’‚ö‡u†º °*¼Þí¶ÑÝÊË7¹ö‘ÁŽ"…̆¸Ž¢[BGQà¶â©¶»«‚«1øJl¢9Sˆ™D’3,d:qmzBbtdÛØŽ-‹¨¦>ñb »•×8€Q1>È`ñîlHü·÷_/m‰ï³w­PжÊÚ“\º½D†µ££U\Úž úW.ØÜqÈo9À1b­IŠ£ºž±@>šç4é[¯¨—"Ú8o‰¦"Šd›e;;#=ÍæùFÁH°Ï¼)4ìrC´MväL(·›MâëÕå{ÎÝËf9i9!¸Û“qiZñ²º=ãZÞÞæG¼ôj}A\ûùƒ5Æo¨…]}†ç躷]ÙÞ°4témOH]“0ÎÙ’á‹7”«È;iÕßšÓ“’aY·H/é6!"Ìá©]‘˦‘ÀNR(&åÓA×,æÉÛs3}O‡‰“ä›gŽÐÇ?»i?uejú;MWH…j³—1XO±6”Y9‹®oµ9¬ÖGûéâÔV® Ã1ÌwávëÛÓÀuà B(-cd¸<9¦Ži.uÚ<†ñ.ªêȰVN”°pÆožŸÉíXH9€gvØå¶­\„ê)¢¯GÛrE—vö%Â[(¢^š˜Ê^þèåÚo÷þùÛ6±ç·ž }°ùÙ]Ï}=£^àÖ¾fwml€8€îìð'¶8 M›´³×ÄmŒ¬ÓgšÇÄÐwQ\âØ¬¹†€‘¬q§eHÛq_ –Ù‡¦³GÊdÆÖ®Pua\LßÛÎez3(‰S’£W!!s;–+b³wRI59„1³ºy‘—Åov~ÝÅœåÖ-·P¹²†6®–F~qÎ Yy“U\âÖW.¾ßØøÜ†Ú—ræòp¶·¿6ò5Ñ—:ñ:)sô†R€<š4…¼[|9bKžÇÉU,ØîX¹ ­¬Ê^^ÐtêJ~xÈÇ©¸cƒ†¯”¸^:ìh)¦EU! ažK˜»³œÆíga[q¹/±îÑÇpÖ²)ÞÒ!h‰­f§IRx†µ¥Ä.Í–ÉÛ—ø«íÀÜ£¡ÁÚ^ˆš÷ÂK¤ak\ Xwxâí-eá©ÎÃòn±£±D>nÄW¬åÛc¹¼W°'˜Ý0-àn+zåN3ã†à©>zÉã'qâSï³ L'0'™Û;×9qº¦Ù;ºÊ LÛlÅÔN‚S,RÂ_Ýš5®kšúŠš;€bó»[Þ‹um»©nq.¹6ò6XÄrG(n±].s\ÒÞ<:*:jiÉßáþ,3D@äŒí;!xHÅÇȈ0µ#n«JÒ^A P#ßOšt§]™NTY¤]À6šã ÞÆÏ ¯öÞ ðñÊæG÷Ùßó†kl]Õ"èox領]ù¶ÎÈÄ­3™iŸ“|msþë e†áö]'yùÂÞ“ }ªîž°%±ŽxÎaŒr«+ ÌIÊYml£)n_ÑòÖ<ìŠ%›É,ªP¦‰9œLGEÍ»2ÁºµiœÀß¹=ÇÉ™7>Þ‰ö¢IË“ßMjøîba–d×%PX{§ê ±m7gØa9žÌjF\1Ï€wAñÜ5ðHà^Hf–UÝüãt‚x9ut>>} ÅKìa•®¤,»*Ù‚‘’cñÄI^àöBDŽ fc“–PØC?IR íBŽöéuÒ¶{ÍÁsæÕƒsâ­]𽹕Œw{Þ›m,e%æ1WÈÒ ‡‹CÂ¥köØX%¶Üà27 ÅÚÁœÞï»ês«Û¯ƒXàtŸ½4 ©³!mãñ]ÅoÎ9¹í|«b²ºbd–+ÛLqo=mœ»œÁ,²:€!¾et†œ»fÎÝÒî;Œ®;!mr˜«çA#õ+Õ!´€âPoO®îm´Ì8ûÛ)]qÈZ6V8·I­$Š€š˜Éh'¬ž…Û’œ$¹m•c1[KѲàñ‹ ‘™.9˜ÿF†Æ-Å$fÙ¨VîÖVWâÆ‹ dͼoé$׳)T9u+^mG&Õ—uKdçE>Möxøc~©/N­¸U 3[ƒ6š‰h;Ç.ÍÃÞŽé¢H¬s{#ÛFZ:žÓBKô‚Ò8·V¡ö@$R/✅Á ‚rµÇsd+väÛ[^ï³ n7¾™EªI…¤õ¼“Å[¾"Z¨‹GIöÊ€€éJ¢„»­ý»¶Ä–÷›ïmm·®&lnžÞã¾6®wí,h-¯HÃ¥½ ìmé G¥"ªBG-›Ë‘E é9; y5QòždZg`æp>xuw‘‘S,tñšA#ÓÒà <`¦ìKŒ}Äc2d†T»û$õø*(OUGUVkHÆÈÛî“¶%ç+$@nv©¼rF6Фw"ä­âç á14A@[]wÒ †•æy»+æ ÎåÑV ð¨i„xÍ¡áÄ}kn½ÅÏm!Š'°tPôƒÐGQ¯Ð¶ÇÆU±»ŒLŠæHçHH¢ªÞNØ€:öb òVjôt/•þ©­ÄJÃô­˜ÆjìälOHjSHs&ºº@JÂsv…Ð4]à×@Ò÷isº¼+¦8tš…Ä%!¤Ñjç}Gj šŠŠIûS.rh`íìN˜ÉŽ‚!¯'‚³6—VÒHÑP$ T‚8£é¯RêÈÉ#ããið™sì9-!+f ¤³BF¹m3(Ù…ÒlœsS¦1äjˆ¥ì„‚n]Ð.ÊÔw,‹&ã ]£iÄ’H$ŸÁô®í±kâñxËÔ)OÆx.ÞMÙLCé¡Ä¿Û)¸c§ìÓÜÔ *x’µÇBC…xu ý&¾Ùèéÿx(I^ÇtÀ "øE1 ö€A|Dˆ`Ôû¾ÀÔhužº‚5Úð¯i?ç)‰h>Áü?÷-í“—àS¡¡Ûn½²¤M$„å8 j¨ªÇM4ÌTÇP.£ËÊ5Òš{~JÑ-iARiÖ'_à]¸m¯&«âˆèë&£ë4[ÜkB¬à)0YP"mdÑzä `)^>7f͸€j"'8ìïWNæg2>ùwQ‘þÒâ¬oþ«\~ ²Ö±Èá“5Òö £à/û#ð•Ü6ý¨ñ€œ‰Ã¶Pÿè‹ìËâî’jþ‰„ºî¢u÷Õ¦ä2ÐÈx<££PÓOQlc¤ý.'À¶;k e>ï飵Jÿ ¿ú£ÿ >µÄstls otÄôm%w4û(È[6ºzêX¾Š ‰S!—t©ö§7„5ËìÉnï³öóÞ=ò[Z“;µgM  ð.¦P[ÇlYnƳX é$ŸÆh¼QÈ­˜Â\jÆ»$ƒ[Q‡ZA!Éô¿¤.öqÂ"_xfä–vª(˜¼†A }gµÛ$ØßïšXû§™OKYÁ±ƒØK@q®+Å7<ÍvKîÌ5l ¨ëwK¿§€Á@ûkb-Zõ~´ q¥DêÏ¥/ uJë¥AÔŠ¤óPÔ–§T€~%Ij`¬»à‡;Û¼?ñn]×»uãÉø©Ü‘nš«.Ÿy1çÏŠÝ휧ð»U"ê*Š"e•åçÙ ÷°î1Xgçà–;«RHÏnímmO^ÝL$ç㤿òÓtZm=ÙC&ÒìD±¾ ŠTžêfés¨8'KÈHiT…Ú7³ˆ´¢|)m¡ñdûµÇÙBømy)è c–˜TòíKnË ÝbâN$’\§Ü9Ó.ýkxæ`ÿwiÞWÂnhÕÌS2X¥ÇŽíÝë Ææjqnš´8Ñfò<žÝß|®Ú„e0rº°\Á$ncØOŠ^uŽíÀ@ZW&âRÔáã…«Sƒ¨+ÂÞ½²tþIW2g¹K>E »jÖ’B8s¶žlc5•}‚ 8~Tµ+gÄ éXÝ…m“ßÜͺæåõ¥Å–Ûƒ,1Œ†9¦aË-ÙˆøÌkÉsb'‹ãxáV®îížÃhìx9ykq Îj[Ͻß:'ǃ4Gn89Í9ôû/oOŒ²‡Î¸…ÎA[×V'±>Û@IcleæF*~ÜL¶ä³H2Í®´K3un¦-WMÉr™¨Ý@10Ê_5äW6vËØw½Ó}÷;øò7’†>)zÇIÀÀZÇ6S¨°—‚ Gwnkr÷wnmÙö×ï6³¶asdóo â%p1ð!ÁÎ¥¦ ž w?XÕ·׎‡¼ñë·L¸2µ8a´òÖ”tÆ/¸3 €2sMØNKz.BÚ”“ž]‚Ç\ šÎ)ÅDÌmFï—ûŠNYZoK»;öDýá>b{X 㼊ÂëDeÑèñÙ3ehmKY&²F—°Ûîü37ÍÆÙ·¹´sÛ·"ÆÅq(kí¤»ƒSÃ_«ÅtnsÜÂMs4€j ãv;®6ñÌ•ÏåK†Žm u 9"ï-¾Âø´8~V.µ·,tí©–R÷$µÒ‰ÔA²[qrS9Ô"JdsQògpÛÛ`¶ÅöãÜùl„ѱ¶-È^Ð7P.–äÍ™! 9ÆFÕ¤P5®{zxÇó/4ùl害î7FÎÚ¥ÚHÃݽ®‘òе¡†Ž*I 8mq¼Qç²¢Üz©S*®øé~áR¢B¤‰T_] œL¾õ4ÀÆ÷¥@JõÜ|Bæ~âWKvK@¯A}âzÏÒ¼êòC'"¡‘Ôvèqú8ÚJ~ Žù?ÿåÆ þ¨/pÿå™ú¼ ÿþ˜ÍWü5oúh”åüÆ~Û›ôr/9N௡hBñÐW(³][MîÛYÅèÑôœ…ǵٿ¢Ê>¶R“jyæqÎGÿf~æ,ª‘?Ø(`c2ñddÅ]G‡{#˺ÞAž51³ž:Ú¤¸u€BîãŸdÌ„É5ÏÇ ˜ekMèÆ°ÓÔâÚ€zŠôG%ð3–˜ßÇ¿¸3BO*ákt$±Å÷ޝçSè¹nŠ® .¥+=/ èÆIEI 1»âEAT“ùÿns¯jÍ‚.oº<^ñ¥—v×p=±ÈA KX褎FÑÀ4šÐis½{5Ë üYc•åÈ}þÛ”‡[Ïo3KØcÈsdcØj p)R©£½óVaý![€hÜýq±¿ø†Á÷ó‹»1ÈGʰ».[FÄ5Ýú"ѹ®Ç.‘šºÑƒD«#¬ªÄQ®ùÌ à«8Ò6vÒø­›êãb[¾Ã`æ¬ {3Ü÷l“ÃÃLp ipkZCèîË#Ú7&âø}ÛR×3n÷v2ìËvæ¹²Éë\Ȥ‘¤‡Ê€$[R|pçõîcàw4ež%îÌ…`%qàü¹~Jå¬àÂç·ÆË‡³.é…îYI)%¤“Z9kQk¤fê& œ[fCï]ƒhó«gín\Zà3¦K}銱e›ñΆ_¼Iqb1¬ !ârÖ»P:F³¨Šb7,w&z\eñ!“mŒ…Óî[zÙcîY ¯29Îqp-1á¤GOjG5Ê–M{A-\i1!)–0ö'äY±igl˜(ØHBI8XŒ]+0ý58Ã"‚Ú•2œÅóÉ6ÆW—œ·ØYMDZÛb³¢êúŒskÄ•¦F¨Ú@—…[!ÑBâÐwgqûËzîÛ,‘¾{üI‚Ö®NøXÖǤ—¸9ƒW SßùO `N7$²´C+.VàáÒy´E™'1¥ê¼{A~w«yƒ—nã ='Fé.ë± kÙå)ŒO0¹¶7žúÙ–Û^gÞZÁ¸"2\27‹pçi¤BWµòÓÆsY«Ki¨‚@XŸ³ó»gjni³Ñ¶Úypï …Ïi˜´j¬†6’[|PçSQû €Jé)O§žÎ±ïkÄG’ö³ktå“kÎ>`ÿ÷ø¯Õî±¾¿é¶Ïÿ…v6VÆ·X#…ËÛÆ…ý-ˆq >Éö TŒbwU£-g‹vq“ÊÁÌ ã\™‘1û,—ž¸~½-IX)æñS®!¾&^Fº²mœ&rvôÂWcÖ+Ö‡Ò(Š)˜TIÁ6™9{Îmm&î=¹¿~ÜÁç­çd±Ç=ý´mx¸šÑš,f-m1È*ãã¸ite£+²qÖܼÜ' š¼´nk+ˆš'Fð×Åi3ËL1Ü;S£x“Kµ°Ð}–Mx'´¬bq£eÜ’÷VJ°øjá¦Ì°˜LIÉæ§øƒú+C"ÁÒlÚÙç·¥JÜoî-þÁ2T;DÕ1u2†"*ë9·rs1Ž‹·/·ãÌ_IŽmýæ§UÍ.uÇzÇ2&ÅöœdƒCžÜæ-¼ÉÆÞÉ™´Âáq¶Œ{xëKj 4ÐCݸ:GIöZx‚GC]áì̺ósÓ.E39–“&àQ@SߺUÒ¢›T΢mÓ€#¥}©ihË;H¬ã¯wm`©ÔhÖ†Š¸Ð“AÓA^•ó Åînd¹}5È÷8ÐPUēë§£©|%SnÞ*ç-\U^¬áLI‘³_³ví´1}®êî¹RâôÓ'Šfî5šÅŒeŠí$;í¥^°l$EW©@'þ@×O—7–ëÛÛ3ùˆ´Ën[–ÚcŽÓîÃÜ׸kuìä6Œk×uS‡J÷µ·ó;›“7츽‡^Z–ÚÄ «‹GG]x¬t‘àŒxçòÒXNq´t['R/ÜžrÎ9[²d‚Ž].b¥qS1„ Q0€rz¿=ùKwq­¾f\Jö± Gp*ç8ÅN$Ä€´é¹OÌ;x_q62VÃKœuÃÀ4TžW€ !8L|—Õ^1/äd•‘¿œ†<øÝâÖ½á†Mƒ«Þð•*{À0Q,X˜Œ;tÌ‘ž1@j¡´jÂîon1Ê,Œ[Ø7ïW÷eâÚMmµ»+ÿÅ{œ ºHpSA:ehÛ¶£—8SÌ\°yšìýÞÎÜ8´ÎÍM3ÌêQm#Ô(_BGÉì‹*Ñ០#.HÝO%8zâJï’±2Ô“¥–Y‚y =c¸Bå“zs¬Œåµ? ‚2›|Ü•Ä šîfï-ÌŽNÞíK{VE¿öìÐ2æÅ8Ú¸ac@9¢cX(\Ó*4fq¶Øý“Ì›]Á5äÚ¨¦tn$–‹†š‰î!ñÈæ¶G8Ô5ÚÝC¨ vŒözfö·t³\†hlsŠ-öÒòÓ9ÊRNFÄ%ºÁ³…㦢ým's˜ˆ•Ɉ9'n© ¸pA¹çöË—¸6CtÜ:6Gc$eÏzâã~¨Ëcî¼bçŸéñI¨Zt< Üñä$fcº²ÀB×½÷ÎsvÐK^Ú>¯×À5£Æ¼`(Vó~Š û7ðù[.w ‰Ä½îFº€ž–;~ÑnÀÊÂMóîˆé¨é­tðZÝüÄeÌ€6C¶íª¨½Š¢´§Eh+Ó@»m#“8á.g÷Üô4¥GvúTÒ½•ú×0zÒÖ”àÃèÛåú‘vT—7£ ÂM%c­gw{†÷ôÖœQœJЍÐwDºéX˜fÊ[s‹zÜá#æcÛöî·a¶àÄÒ:ä }+#,vò×kÔyüÄ͙աlFb$p=D2¦«-硸²²ók[{ Øx§ðËq@üQxÄÛX‹ìœ¶?+¶B[‚fõ¹ÍÍHÏK4Pæ1QP(áOxC{CyMç*³;-Ù ã}”Ës*Ky{ËwÍßÇu¥ßšŽÞG"Ô¸wAƒÆ x£Ðní¹ŒÜí³ÛV–íÉ™¢fÇiÝ> ·óš@÷ºGŠžYqà ñŽÈ‘¿íÓí nrXÿòî'®ã‡üØÿö›?Òß.«OüÓÞ°.Gh°ïƒëmq¥Ë®œåÁñ0J½w™-›ÿجWœr°ÿ¹noønïýP»ýÆ7ŸÜ:pµp`Ø¢_¸ºÏ‘ÅYψ}œí­,Ñò‡”}ñÓc„|ûVÊ..w LDuîkø-ˇå0·=†ö”ÙZäîÙ{i9Ãx®Ôk'”&.{Æ>Àqh´rU®. Åâ'”d™Ñlt¸¤¹È¹LMÎоgÌ­ïÊmñµn1øÎç1º. s,£†ÞGÝ ÜÚDà{±$aŽ!Ï-ÔÐXAÕ¤ï;ksjno/ûÜnÞPë§Ë3na²4e.h!¥¡ÔqR£Ÿa<¯{EñaðŒn< ºéÌ.²Ž³r,›zø^PÌÞ@DÄܽ”C)ƱMHå›S ˜¸&šj<ôÚ·Ø[«¸÷¤™î›\Cl²’J%¶”3Se’Hk#¢sÜY#ÅAÑ©Õsš—ÚùûLœƒ µÙgýãq’7VpÜ1†9ã.¡Œ’ŒkÃsš¨(Ö¸¾éšâRÇÂYn{-ÂaLq[/lHÛq®/²â¯Œ¤7KFÉÂÁ¡oI7‘dÞ5»€pwŠ‘DÑíHCf1{».\f÷®&ÇiÍšÏ\Ûܶåó:öáöÖ]Ñd’XXâò4ÚAwØ$jðßÜïl^×ÈÝî(±xˆ&Ð66ÚÂÉî»ÀZæ0Fàæ†ƒ¨¼‚Úé$tWÓðT<ü<Æþ™o£ù£yÿÄþ‡-S˜Çÿ mØíþ²…);#a«.øÈ/ü ]Mê«UE1u9`LAIÝV»ÖP†Qgì²,"dhA•4QÉï•(ŸóNÛ7·w…îÃÜo‹X-Ã…tÇu¬‚g8ºÒBd< s‹’· >/5¶­r¹—ûjO,Ô4«íߥ‰ õ¹· ƒˆºGÖ\f“Ì_ê,.fËîö÷,t%ýÅ·ŠŸ\z C®’Jàö‹>,-û¡Ìµçdðû„íM’rYÞ4Ç Ý&‹™‹ËyÜKæÏæU—8‘4JÔåSE½öé½àæòÓr«!‹m¦÷pf²×e¬f=·—}ãÉpÔÙ[#KcŠ—Šx¼*Õzh´©î_yÊ[Û¹såÜÎy iºÝŽ$6§HãÑSN…³Úÿ°Wú|µ“þ"‡®æ\ÏÌHáŸô².®7þäkÅú6/ªP7³æl¨t›‹&ep¢eßQ4@§L‚:åLD@<#\Wáãù€ƒ»Éð›¨A?{–•=•\–š&åï ñ©4û´u§ÓE•9ÞÏ6TôTO Ön<·pOÙÛ}ÜUk Œ¥žŽZ)¢Ów ùz^M¤Îš¤Á`PÊ5 ‹tÄ¥0ˆ|³Ø™« nù¯y‘¸ß_x•²ØºKÖžáV¶ö倂Í4÷E ^˜²ÝØ«¸íùwmeÒî#,» µx‘¥€É%Äóô:µ¨PõpÉ6aí6ÅN$äY³²ÛɤÕãù\cvÇ1âM=däž&š%(ñÕ)@9@+§¶’åŸ+´o¨¼s´ñ.kY{Ý^“â1¤¸ž€ +³yß.=iÕ ž•B@8R-N§Â<õ%©Ô+ÃÃS¥:¯^ø4OzÖ;í¢<íӯ̽ûûóšý­yúÄ‹ï]û£Šýmú,ðìvŒkS[ŽÀñ_…+ÄŠn%C½¦ÌâÈ·Wîg)þíø{úœ+òÓ˜_¿ÙÊ{âóõ™Aë^E¨T…`0…¨=*à~à¤;ÀÀ4"§­X !Þ(Ÿ¥p?=NžÄÒ­•:@å$×H‹¶rTÕ.ò`»7);js—A&G(N_öiï¼a¬fZÉ×Ö/¼%¥Z~‘þ~#ëY<>Cûºý—ÿeZv½¸{²¶¹´uµÄdøÂŽd”á¨8P‡MAÀÚ½§¹ ³A3dà°á^#‡FžÂg3Gâá2psr°ÉâÆŽ•…”Û÷ 2‘©‰œöb %ñ€4¬t–°ÎíE¿œm%ŽÿÚiñ” ‰#ûTw„>°j"JJP¢vë@Y%)SQWŒ$ Ü J&ûhùˆ ª˜5¤(&”¾é0£›wrÃZ!k‡¥Í¯¥qºâÕü%¶ŒŸôjßè4üK‹O½HƼÇì^·tA"Åe~ÜN@0  ñ#n”GT'(rdíáÊ襵è«Oõ¡ßåë\“ýx_à#ü…r¸'%dÕ˜îA»t Îo"¡HEJnª:Žð€ ®¼µÕ¹ŠÿYuÎF>ôŠP[šWüŠ»ûÍ[’ߦCÇësF®]ÃØXP §¡Dª->õa0‘C¦}¼…ÝÔ@L‡–(ÇûLÁ=‚&Ž‘Û_誦]BÑHì¢I{ŠÞûp³–¤hþÛ‚D¥T“8dÞ&/)^¼2¢U chœµÒ‘¸ØçÌË«‡pûRÔÿám8.Ôwwã„FGú,ñš­í½°ÑáÁ[Žz^qN]QUë‚¶ÔâQM‚GM±SÓ“Mšº’e¦„hÅÛÁnÎÐÖêáÚóWWëRèß3ëu#äãÖISzÔ»’ÒbÙªiÇ1'Úvi‰)L¢€A(ï)ºDÌaè<£ ~´¬ÅÍIJ—\ÉWR¦§ x8žµ²aÃc5kG`<;?Ëô.Ûe¶âe„L_ìôÝ( sŽš€Duæ­N[¦j$ž+`û¼’4 VBâ:z>’z8u¬Eâû Ââë=7ʼE{¶u³ÈË&8§Ij“¤Á;†ër™4›52mª%ÿvqÉïLcÔù_ˆ½Ü9?¹BÇ7LJ\?¨éã5ë5¬Žh?Õmx€«ºnáÂØÙÈ3DMí'†¡×N zÅHà¼7:çYE9„Ê*s(sˆ‰ŽqG^QÔF¾Ïclc@}|èù#Ì’q{‰$ý'ŠÔÏËOObš«ù‡¨i§T€~z)Õ ˜jKSªPSž• uH mÒ—…4€~१±:­É¬´‹4¶g"õ«g¤Þ7nítv˜éŠnRMBr jº40‡†ºòÚÛÌöÉ4ltŒ5i-´ôÔ8€xv.V\M\ÈÞæ±Ãˆ€|4à~µóùêËTUe÷|GÃñ˜G"Ù,n[b%l{gÙnãæjÝó£Ûñ~€ÿ·,Kçm–v~RÇ1Ê(w«ÉùKËÛ½´þÌ¾Þæè_Ïp×FZÞõú›Mmihé p=oüÂÞû»pÿ{ã[<Ha-yÇ»n—WCˆ-=@ŸX” WªñZ ~µ¸-&ýÚ-[º|íÓv$2lpåe‘f™€€b5MC˜È`H  PÐæ áe½¼Ot‘1¬‘æ® \{IIéí\¯šYÖHç´PIÁÙÑÔ€ê÷+µER‚}ªªÛPZR‚œô¨z“ªÜ˜ËHÇ †zÄ˳XYº]°¬Ÿ³PQ:b¡5ð¡]y­­î±àM¡í‹–9憦'9•hH¨ì4_8)ÕÑ\ºj¢«ïNIé*À•ŠêeÙ‘Â¥j²¤ÝÜUVÅ8"¢…Ü % š¸m ”Næ7¿h u ;éjäÈbpˆš‘SB{HèFšÆLå:g2jÅ9S LC”u)Š`˜¢€÷ÀjœÀàZáV”ƒˆ5#ð¯©Ã×/;—ŽváQUÕT]uD QULcœ@¥åðWp²áhlc 8*|‘Åò8¹ç¤“R~µR©·ÇUNÔª¾öR/#Ö :bà bìÜ*Ù`!ƒCDäP ok × ÖðÜ3»|}ŽÀx.Hæ–k‰ÎkûA þ$}©Œ"cxÆ1Œ#©„G”DDyDDj´(85©©é_z’oœ Ý«‡®ÖlÐ [,áelÓx¢s™4@Ú» é\ ¶†7ºXØÑ#þÑï OÖ¹]4¯cc{œæ7 h<«êB Ué§BŠ¥6øûµ©§juL t‡”)Rªª”ëè©-@)J¦Ú‚ÕUJ TЧU÷šIê­b£ÇJ1ns(Ý™Ü*f¨(q9Žt[˜âŠG9”0ˆ@DL<ã\"[)œ1¢w 5Ã=' uõÊfÆ"sÝ€I ðŽ´ESn5zAQT §pT–¦ ûÍ ñVÈ2QÛ•¶1ÌÝ¡×Tí›™Cê aI#(c˜J¨ˆë\Þ&ÈéšÆ‰]ÒàM:*zM>•Êe‘̹ÎîÛÐ+P+ÓAÐ>¤ESn•T*j˜ëè©N«1±þLá†W[vNb±²E¥uZN'K%àp´ž¾ ç¦ìÑ>é^9 ÅveIªä\û©¡¸* ¾GžÛ|˵ܗ9­¡}Ž»Åݶ2lòx1[IK{ËWBXRç´´UÄšý>‹‰ÍlkŒ$8½Çk{on^Ír;$5ÑpÙKC´Òpq൫qž-ü®\oeãëfJÑÄønØqkXQS¯Ñ‘¹übá“—Æá™Iœ¼ã–¨™T›’ §¨ÛÚ¿Ë͵ŽG3Ÿ¹Žïuf.D×O‰¥·@-Šƒ¼sAÎ s¨ã^N==纬óâˈöûŠHà騂ù$#Åy¡¼:Mxc™$ž‘¢ŒñÉXª ,«2¸T­X74UFà~Äê&_|%×Þ‡0W¡:Þ(œ±½ø Ô`=4âxW­i¢if 物4'¶ATÛã«¡QT §WE*& b©Ð>íIju_z²œ ƒW®Ù°6l»••A¸w@Hç2i4÷ •×m¬½ÒÆÆ6Gt'ÂGõ®gO3Ø#{œæ7 h< }HJ²Õ_s™ÕŸGÈKžzI5?„ª‚ŸÖËRªPSnµ¢*¾Åºpš¸tådš”HÙ%—UT›Û b C˜J‰L. Päjâd1Fç=Œh{\@ŸoIéí\®–G´5î%­è’ƒ³êT:êèU 9é§T ¥AjuHÛ§wФµURœþJšŠ¥*œÃÕKÂRè¥zª@?0÷tT–§^Ô€~z‚ÔÁìHæÔêÏä©¥:HSó êJ€ô"«Ù. ÓÞ´£‹1Ôv¶K½_˜Ûû†úÍ~Ö¼ýbE÷ÆÎýÑÅ~Ͷý zöA³ÅZVÇÅNÈ6x¨ª8¯Áç§(]ßn4ì•!• &Fè'|¢á}Ó€9ÒoÈ#Èÿeh¹)5´†š—;ñŒÿBØñO0ÈñâøúzÑ—³‘…ì—÷•âè ˆv¬á Z¨CK\Ó—jœ[‡A9D¦.§û“tµ9Ä“mmŒ®çʳ‹i×À¾B˜™Zj?I?e¿iÇ£…HÌÞä­m,ß!¶ÂºYZ8šŸìŽ©Àt4_Ì·–®ÌÍ{J^÷k;ÇÆ*,c[¨¡£`â1ý"13èlÑ5Sî–PÆPÚ ·K÷–ÏÚvG2É´-s¿¬ç´ç·8ñ>…óVéÜsî,ƒ®OpŠ?îêphêI+­@áÑ[QjÖkØ54N½©Nz\Sð$)ù‡ª—U œI¼m›Êøêí¼&˜[ÖäO¦ÇÇ|c1&¹1iéÒÎØF´í×P Ú.²I]L`ZÄæòøÝ»‰¹Îæ$îqvºY_¥ïÑ\í,kžêÐÖ¸ž W½Ìä!Åc™Þ_ÜHØãmZÝOq£F§´Tõ¸€:ÊܲF:¾1 ïpcŒ“n¼µo[YÙXÎA½Q¢ê´YVè»nt°pî=û7lÜ&²¬³uÑPª&sÀ#Á··uá Ü;zá—X{–jŽF‡à i«\æ¹®®kÚ×5ÀµÀBæÌaò{'.1 É@í/c¨H$(ZK\ µÍ%®H ­âàÄYÔÆØó/O[ÞŽò«‹¥…püoëãçlª°—"³“s9ñl¢&KW­›m7’“CWVÃvmì¦á¿Ú–7óø¶Â똴HÞè\0I Öæß­„;óo~ž‡i<=ÞßËØa­3÷pèÄ_kaÖaqdž q{t¸SÇkkÒÚŽ+®ýÁ[•‡ªû™¶xý^Á‹W/—Ü:‚‹Tp°&˜j¢š$9÷¢:h\I ×;šÆV•qTô žW$qÉ+´ÆÒçtÐM>¥Ø¶î#È·V7ÈYvÞôì{ŠÜ[-/Û‡ãx&¿¸¼eS„¶Óø©ä›iÉOŒdÖ*Z²là¨ë¼¨ššµì†êÛø½Ãaµ/®4gòm™ÖÑwrô[°É)ÖÖÙ¡€ŸÎ=…Ý Ôx,½ž1}†»ÏÚůbcÉ©ƒA™Ú#ñKƒÝ©Ä®§K¨8®¹6ÖÃ¥aêê¥áN©NºTª@Sn5%ªª”Ü%©ÕvÎ"Âyc;Ü*ÚØ’Ș½f7’­c¢ˆ˜¤y9;*å„5Q)UxåÌpÝä­Wuï-­²,Ou^Ãghçin­N|ŽþÌq°:I\ØØâ(³Ø µžÝ7fÇk%ÍÀvš°v½î-cÒ÷4ÁwBà‰BÃs1þH€û9/;kÃ^qLþ5„—ô«jà*戒íàd¥¡é…lìT9'»ïÈ]C\ÛÝ8 ßg-þÞŸï\Én÷h’=3ENñ”•ŒqÓQãZkÁÅeóx ¾Ý¹ŽÓ3sq, ™£[X䮇UŽp¡àHpëuè)ÏYú°õJU6ëÓJ©Õ()ÒP©ÓTê»/*bœƒ„oYw“íÿ³7ŒKxçRá+ 3èèJ±BE‚Ÿ[òRÑJöìœús uÐÀ×6ÆèÀï<4{ƒmO÷œD®{[&‰#©c‹4ÊÆ ât‘¶A œÞõ¡µ t:M d…†@Òc$Âz—j e[¸²ì cþoæ©ÙkHÕ½ÿ9fâ§‹l¿eèƒ-é°Ý„áÁÒA6¨Ÿ]ò˜S÷õ¬é¶FC)Š7?ïøh5ã{¹3âïší]Þ™+H‹Ü:à³£lgM†@Aþç“•ÑÛ;\œ{$îœÚkÔÊ?Ŭ€ô‚GÆo‹2èÆ×tõ‰zÆ|Mu[/9é±ò"ÉéMS£éÑ.ßG9Њw‘YBr÷ûõ“Âæ1›s '}‹¹f¸ß¥ìÔÒH®—µ¯oÐæƒô.†S}…ÈKŠÉÇÝ_Àý/n¦»Kºi©…Í?Q!oVV1¾òEó;gÁüm­µnëÑׯpÑÿÛȘåVC°”dâGtSìšuÇNBWK3¹px »+¼ýÕÖFàAnÝ;¼”ÒŒ«àΟ´òÖý+³ŒÁås÷WXè»È,¡2Ìu1º#.£œÒïô-è˜['šÝÅ×`[:Ûù¢vBÛÆ’[Áö–j*t¶Ëö^‹ñ·¦Ãöf;GéµHß唟¾®™Þ[hd2x¯¼ÿ¿á d׌îåüÌo‹¾kµhÓ%cñ©{‡AÜdmœá³°¿î?Ý2rº;gkódÛ›Mz™Gøµ4Hⶺ¼¬;ºâ±.˜7 .»MÂÍ®(”g.1Š·"J.*½…s!ª)ro*šÇH7ƒßWžÄg16ùÌdí“tÐbyX51àš ðè]<Ž#%ŠÈMŠ¿‰Ì¿·q0ý$Rµs ›AQÄ>•ÄNò…e¨>©AN¾ŠE¨)TÛã¨-UT ¥F”ê˜è Ò¡N©J¦Ý:{Ô¨ªPS¸*KS)TÛ­AjuJU:ªtªªR©×Ñß©N©Š®ß*ê”ê©-N©J§]AjuHU6éîT–§TÀ§?Œ*S±)TÛã¥@RU%©Õ()×RZR•Mº{•ªª”çåè¥B€R‚›z‡Ü¥@R‚•:UU )¶¤µ:¤:º* SªPS jiDê‚›téîÒ—…:¥)P"©üÃRZª©üõ%©‚”§æ¡¨-N©NR¡M ˜u¥Ã­J¥§±:¤ó IjuíHç©ÒRù‡¨jKSªö§‚’kgDc¸v$où<%bæ¯c@ ž²À:½`ïìšð^‡ƒÝÕ‰¶“­l‡¤v‘OíqÚkwO;×hš𤹠›¨ÙTõU3h ‚ÉåSAÐÉŸt€~M5 Ö!Æ_ž-ï¼Axx´ÉG6±qŒñ`ŽÐGá[#Û¾×–J¹\¤IdÊ£èõ‘?¢©Ê%MRoêˆ8ßÝy`0w´×?n'ŒªH¨¯ÀV:HK N’?Ê8JÞ-X%'n,xÙ‹’*œe®” H•DÔí&lALtÜ´ÿ wDj/¯73áû–:ÊÞJ´ñ‘Í¥< õ.{hqÅÚîe{hGÙþú}k'¡x¤ÆNx[^'$M'Ô}t©»ù2 ƒ6.•f`ÈÐÚ9 Љ€¤ÓQ8€V¥6ÖÎÆ6AöM–Ytµ  ¸‡×‡ p4ú|Íe+¤6½èdm©ï MOÑ¥eÊVÖBq7Òeš1’ŠE¸k,À[8,’(r²¾»WmÄŠDå0€è;£È:†âÁßcå6·Z ËkPê‚Úñ­ý¾š.Í´Í{u R½Bœ~µ‘ñ×)IÙ© •8‚d0©¼'ÝÔJ‚]©ÌpOÃÈ=þýh÷‚jâê0qLæo-µöåõ$|8» $±¥ÝÛg¸7-ñä âèZ[BkMZÞõ¾ –†ñ˜¬^?=™µ«%ü±šœ·E„ø¬'¢GPA.qÈ® 0̓Ã?´=àÛ€×U×pÚ64áì+™“è¸Ö²¦,bÝ“(\ñ¢ÕÁÞO¿·®´›ªÝDQAÊ ˜É‰NB@æþðÎóØ=éc÷[[ »Øþó š÷»ïÜ÷˜_¨ÄÙb˜¸<9Îc˜ªÒNÝ˹ŠÙœØÊ훳<÷vöÏî$k[ܾõâFÐÕîŽHÃKHÁäŠAâtÊБñ 40öY± ï_šöu•¾õçžæÜy¶‰ŽÞ6¶V ŒØ5±ïžV´ð9í:^<`׸p£W¶nK™¶Ï*ðx\[ŒC3ßÜݹ¼ ºÖňâXÖ‘VôÐxÔ¬`á0ÝXgˆþ+µ²: =S1#Œîå„Y8;…®D_¯.ò¥™¦bå_‘ÑãRl-Ôj’‰•S(%0‘röÛ{æv}æëæ0XÍ0È ‘:×ýÙ°Uç»{ Lçê!Å¡ Šz.ñŸkžOmþâ Àç±mYtH.?>eñ¶¹ÚŒaºKAÄЮkÄf#¸¿Ã6;éáµ-n±Í÷î·j[v=¯4¼¼Š ‡Þªåg.µKP1H£‚œÅ1J%?/·Øåï)³¨ ûÖZmÛwmkt‰®ftb6Ôyè$0´MFGxmOŒy…ŽÆK/qo[Ïq-+ÝÃ^^à:É%­4.‚CcŒYÁo÷T¦ÂÑyŸäçQ ¼Kx_·U¿r@d)kz)äÇÄפ(v#k++ª‰(És!)„ÂsÖÞ7çç-qqo=ã.%¶Û,M¾‚Úa–Õ’½±÷–ò:GwÁsA4T@LŒÕpø.[ï{÷í·JË6èä6²Ï,rGpøÚ_¢f7º.kI†ƒj@c¸0À˜žÈÁRÜHq8…òú!ÎA{Œ1Æ*²_Ç@L]·4+w ÜR7Âý¤ÃÛq*´]±…»I@Á¨ï&U3Û—|îœÖ÷‹—œ¶u“.Û`Û˻ۆ¾Xà†BLŠ&¹äÏkƧiÐáØâÜNjàq›^Mã½EÓ­ÍÙ¶·µ…Ícå‘€™$ŽÑsN‘«SOh²Ö÷/Íx áÈoX{j÷Kåàmû9 cƒH–âwЈÜ XÖ´‡<ÒºOŠAw[‚ÅáŸ0Y‘²|=žîÇy}[öÖ²R—ýÑu'yµ¼$P…Š˜²nñQoEãGiä“t©Æ&€@:Ö¾cí,Ä–ÛøZd6˜±šàäma|ÜÀÃ#㸈½íÒæ5ÝÛ˜j\5¯‹ÏwŠÙ[‡ÉöÞ,÷ »Šg<­”L&pc_ 5kˆÖפtqíkãð+ƒò)°CG5^W,2ñðy3Û7 -«rhe’I¡i!½õÀ‘š$”6¬ÐÐÚê-©¦{)‡ånÙÌ|'˜+›ØËYqy‘±‘H@.î¡,v¦GZ;Q.àêp[õ‘ÀÝ œ8£ÅY¦ë¸S Ü9NÞ¾ífèW0h!)t9<tÛA¾1ÜG"ºfQÒ'D‹é¡Ç£šçfn÷emѳ­mÝ‘Ìæ"²–Úbh$%ì’Ëâ÷dÈÐ+š@cƒË:—gÊü]¶çÎ`w-ÄͲÆcdºŽx€âÀæJYÇ]â]p«šZÖ¾kC ðm™ñRɶ™³^*áæJÒ{|«7#oßsõ™u-&Ê58¦-cá£-ëÒZFD9ãXB™nÙ3 ‘åËooìýÛŒÛyOîl¥ÆàŽvÛÙ-´v·†9åîs¤|¶ñ²@ãÀM 3C…ý·ËÉ·¯³vÞváß§/ts¾xe.kt´5Žg¹…£‰„ÕÚšjÞ¼É8—Ýü1/Äv ˆ¿,ulì¢Ó^vmïqÇÝhÈ5’†FN2牗g¢.̳´RY¸“³ã‰J@H¦_?·wVøÄó)¼¼ÞÒØÞ¶óëË{‹had…†HÜ÷‚Ú5ů­x6¤ê!˜|ÖßÚÙw–ÖŽêÔÛ_ i¡žFÊÀæÊdž´ƒR›Jq4H.í,µ‰x3áѦq{Cfl…rdì/`dö”5Ñ oD@–áM÷Æ—®aVzùY¨‰¤R VJwí’ë;Wusƒ˜2憛Çcs7V­žHd–I{¢ÝwB@Ö†´‡K1$¸ÈÑcC«œÏíþ[ìèñ¯ÉÇ’¼¼¾ÆÁ;¢d¬‘÷Ú¤ï %ÄÇn‡¼êm8%ÿÃ.°³¶2e=–%­Î²Ö?‹Ë–Ýû#é·r¤›NS´×kå˜Ýæ|Ý6Ý¿¢ú: ¹"ª&cèŽsÌåØù)¬qQ\s~û­Xý0Øæƒ8sÞÜi%úuëqcš×CÖ+-²6Ö+uXÅu$;'!hÛ¸çsuJ"sIÖ‘Þ꺴éhpq‚ÕÜØË‡ Ä\Œƒ°w¸±ûû~qþ?Ë÷Œ€MZR’‘ê?Fïdkb2=¬â)w™½íNR¦p­?rs}òúÞ<î7·2Gqn¬-ÙÝÎÆHàטß>Gº2ø‘ýK‡ - ³6žñ™øœF/5a+á{ »™Úâs˜Ò扛Ý5úé ¾¼)…öwgC]¶Ö@‘E¥ýe¥â†b¤´û‰òšÎumÜ[€‹Žb£2?I~ÙG &¨¦bŠãßvÛÍÿÌbnl#{ì. ¯yŽ ˆEþðÙ´¼k{Ü$1é ¡ÀÐדi϶YÉì¡ÈAvö¶î>‰Ýr?2b«N–µ¥áÕ.!Ô"¡u}©‰­»ZÂö|å¨÷÷ ×RÍ“-n/å æßfŸ˜™BÆ `5LÑÊ8jˆÀŠªvªêo{Þ­›)º²9<îþÚ· ·ìf7Dæ²’¸ÜX:G÷¯Ôu€ãFpG+a·ì¬q;G? æ7·ù7‰çV1ÜÞ5ÐÚx¤ãq5èÈÓpVõ¹ŽeçSbÙ’0¶ã˜É'7oIHd];T»Æ"‚‚&)JÒ9}/8!åM†so¿2ÊĺI#–Y®ãˆ¸¸É0{.“K»¦1§h‘à’FѼcå¼¼Á»Åf‘’þêì6[†=‘Çn÷é ŒµÆF²£¼sÈ⡤^—„á>:ÖžãjȽ&g•—áóH\¶ÓÈ'åŠe<'D$àN²;gFrÂFÓuŽØ]Ã(%ŽšÖå{ÍKŒ†ÌÍaá€ZgòL†fÊÝnЇD­‰À¶Žd{Cèj:GBÖmv6{Ÿ’’Sqˆ²t‘–;Cdá©…í¡«\ÂÒ[QJÒ«›OÂ3ºxSök[*»A…Ë–2´å˜, Ÿ$Î_4„s¥Y¸( ÝϺmÀƒ¦•†±¾—Í.cdíà öØ«Z*ÒèñÚÚ8U¤Ž"¢£‚Ê]ÚǰvUŒÅ²Q¸´ÑÀ>óI-`b±Ê ŠÝ™Ž èíöÛ§sâ9‰Ù›¡Ö’Zd±’)bc£Õ{nA¸¡Ïwæû¯Î4µ¥y\û’Ù—›ŸÛ†\YdZÉ#‘áôµ˜R-oÞx„ý“BhÏñŸŽømÂwÔš³–³ÍÏp¶3ÖáŒ`”P²ØìÞCÝŸù¯ì»‹èðŠ»6™b‰»u bÜ;(n&à‰‘ŠÆ@4IÊÉ7\®Ì:iª©ºhQÓZÔîöŽAŸþŽã¼‹û/¯ýãýU¸Zo (/!1¿¬¶„~êñ–øÑk¢Û îÁš©é h3‘ËöÊ ±3g­ÓQ1!ûBHMÒ”7@§(ã~á¹-ÜDðÐ ¯Ghý}=«/W0;†4v;SúW-€`AI¤ñ“õ¶>ógL1Èö­Ôm_ÊÀ¢# €d÷ˆb¢q áF ì‘i}¬†Vôè §ej¹¼qLq,»„ÓãµwÄW–µƒÚß¶;œ+u..”AFd]Ã¥Žªª9QÊ¥XÇLÂM0&á@F±_ç2—âñÙ=¤p€vqð©“qàí¡“ŽÆµÇ†”ükƒÎqS~ÉÊqÀ„88“}º® ¢i]äˆdTCB˜Cw„Á  ¹ûN\ØÓ~í`t€4è©p=€¼Þï.:-'ûN<~¦´ÿ”ø:ÈJ¿•r£·î”r²ªS˜Ú{EGyC!L¡¹L ˜yGQ­òÖÆÖÆ.æÕŒú:O„ôŸ­i·W×WÒw·O/ÓÐ< }Kã󇊻WU\ ¯xjHN¥ B•¨WП @70Ò (¨Wóù)iM ˜jHíEUÀãá©Òš@8søêKUT¬šàÒàƒµø®áê⹦¢­Ûz-YRS3³²,â!¢cšM6UÓù9I›²`ɲE(ª§!PÔD¼ã›¶¹.Wçñøèe¸¿›pÈ⎒G½ÑÖ±Îq<Z ' -Ë—wv¶[ëyy#!´Žþ=ïpcÐðKœçÖ€8’HveÉÄ\Æãç.g¼W78ÙŸ9rm’ñ’HÈ[Ý•;.%Güz˲•·.¨_Ù.‘”&Š&áo‘3†»Ø›Ç‘˜­¹á’·ìcp{ f¶¸ŽÖ ×éxd°ÈÞ- â…Àæ¯7uÎÛæþéÁÈÉXܽÓÁkƒ£žÏ!-ÔÒC£•‡CÚjYÁÇVGácð?ˆ'mùÌQ‘2ùxc+‚)ÍÝd[Y킾î{FfÝŽ;UTKȱf‚ ‘Dˆ¨r>3É=½Í[MѼçÝÏè—kmä‘tì qƒÇh<–xÛ'³o&§¢Ž‚†l&§¾zÕùͱ÷œ»íöû6ÞáØ=çime’–(ÜæÚºÚâ*ÝJæ´µ6n|#]‡yB]¤,ï-wNÚj6mË4MÊí«‰®¬£{ÚÓ8žÒÚH."ä6C¦¤ ©]CÀod´§8”³¯L°¾$¹ø—k! œÜŒÞÕËP·Ì+û•t\X@Ü.n§¤|ë³¥©@Û…8¨žÙÎþZ;+e·rØ|[r¸Ý¹;›&4tÏc+"ŽF ¥ˆC•«¸Ò¤»_ånöYœ~FüØ^æbeéèŠéŽ‘ìt„¥’^êpáZ\2öEâÙêâÚ% &ÑRaž4±°NT³ò=ß‘n÷I ÌåVûä!,Dƒ§Ž ’Ä)ƒ†*š ;aîÖ?°vÑLn£uÝÎJÊ{H- ó”.•¦K¦šh¥Í$t¸T·m—/ºðøËËíÛ»£|b‹xl®b¸–âRÕ» ¸ŽÞ2û—BøØÇÜ6!Ró©Ž{Øßë<}–js{›?sÛnk­Ñi™¹‚Ë#Ÿ·.…ó?L"F½Îl.ÓH£ƒZçu4ôº<ŸY¼3q«jÞ\A`éÌ¥±¥´Â"À²oÈ‹„åB2bQTQm>EЊ¸.7ª;8ž.4]8f‚eQq/lB†;sf³¼Àæ>ÎÉáð9¨v͆JgIuqlø¸¾6LT/Š&†ŠM6†ÈâZÊè%w0xÌVÐÙ{’Ç#–ÆKœ»²¬‚Ù'½Ä !²HêšÇ§1 SP „ÞMmŒ­ìÞáå{'c(ûŸ‡I¬Òâü°îK½Œ5îñ+Òüw3ż°(úmGLž $Ý)©Žbæ2J¹œD¹-¯üÃgÝÉIÜãŵÌ0:Kv›{fÇ'}(£c s]^’€Òq™ì³¼œÄ6ÒöÉ—¸y/ ðI+Y1N^Îê3Åä‚)Ð H–2Zèâg ZÜ^ÙNf¯X9¬U“¸!¶øx¿ï6Z>èFÉVçláGŽ ‡» å#‘ó}AËd2‚C @‡ó¬g.7ŽO”÷‘ÙÙÏçÆï9²¶¶÷ t&àB@hoxâÈǼÆï°÷46 á¹ßoM·cÌ gÜÜÅ& ÷lÇa<°½²ˆL€ÔÜXæ´=¿i­$БCÓÜé”°`1^G¼ï±pH[Ò° "-ؤ•ÏzPtáÞâM슰öQbm›ÿvg9³µ]Ëݱ€ÎZeòRBË©omooced’ºI^Cdw‰F5•tÔYㆰëÛGob¹{ŸÇ9–Å\c¬™+ ŽÖá³Mu#£s#k#h.`ñªç:ŽÒâ’áÆm[²ÒâÓ…ÀÁ²¹ÂÅ™«æ;»(ÙÄÈ·6••[¹i)ø7+Òü_s±œ”8 ‹U"$RAEŽß'“ÅåyWÌÏml/²{;!ˆ‚Êãî‘î-eµ dRºøÏ…Ñ0js>É.$U¬t¬o±ûûcü1=Ý¥Žä³ÈËsÞ$Cû´ñÙ-í¾ù‚{©ç.H!qÖØ[Ž—7²FµÞ+Ô£ÛG¶­p+æ¬Þ5¸|´øØî ºŠl°½²G#zZö¹…ÃÆiŠÕ¦­wW*›u¬ÑjÅÕz!ÕÑae.2—×]÷kbÛ²O%BælWvß’F…±¥®&ñÖÌí­qO‚*§¢ð±Ä35U)’QUM®†L¥SÀyƒÎížec9¯‹±ºÉââÇI½‚ÙåË"/|ÑMUP$yàÖŽâ[ëÛ>÷œÙÜ¿¿º‚Æý÷¬¼µ–wh…ò67Å#ètU àI=~$ñ…ƒÂ„u›–.ì³d_™âÙË6Ñbã IzA^m m…Å1)‘'#ؼo¤#-Ð\ªo,š‚ —µ"\îÜÙÞi\^mlV*öÇcÜ⮡¹¼¾·–ÞGK×—ûªÊêxb¼¸ŠÄDÇ=­|¥’Ê_Ý´çéi€‚iT–eçi5öwåû)ÍÓn6¼äø…´f£mæã¹ä!›@B¢æ]ŒŽK*î1ºÉ‡pšFH†(€˜–_–—ŸøœÌv×ÃÅ€ž7Î#y…²d"7J†¼‚ipqÇdqìåCùá'åâ{b/h•̰¶2u‚.€GJÊî.x{q™pÁ) –°¥¡(Ç„¬-)mdëù¥‡*Ös:ow´<«ak1eÝ8Ar´:®Û®¦DJªb>]ÊýЋrÛ^b³7vÏÝy²k;W\±Ò~e¦h:£–kš^LJðx-rß9ƒ´_¸äÁÏmÆ[ÎÍ¿f×Gs8ÁŸœ"Q¨QñÔ¹§I.ioÑÁ}–ötáÝ)ð-öíµæ,N°)1=™–îÀµ†¾hk ¡~ª›¢×i&_Gjá]ävR¹M@Hr7û'˜å†w5 ­Ì9¼þwï×1\Œ{ŸCj x÷ÎgŒö¶Žs Í/.rZn Í÷ŠÆKq˜¼F+î°ÝÈ+¼ ¨Ÿÿ;ÅkZÁÓG®ÔáªêɸÿˆHû»ŠÓKà v–µµ<0ë…¶ÖÞKá#‰L#XWåÁyc[¶™2ìcgCIÄ¿Ay3¶“z vÊ3F5NÐMNÌÊ%¿ºUÁëœÍ“#·9­·7·÷vFûogy†Î\HÇÈÒV6”/©új[Eç;;,×/ó[[ï–v™Y®m¥gÞel,sà]G;¦¦´„¶´«xG Ø¡€ýšÐãzÚA/bæ{îRøŠŽ$¬Ø·™­ V’7[yéVëQe)¬ì¨¦váÚDœµÔ~9ñß1¯>åw÷Kì=³-ŸÜÉ¢áíÇ9;N™\×ø…±—ïŠð]†å±_ ì»o¼Ûýâ×%;§oxÍP´Þ‡‡JÚÖ6–øÀ¼[Æ´â¹ÆcÁ66OâžïÌíx—áÌ0ãëýÑrÍ'”"qÃÅÇ(ÀeâÛ[)G³2ÎÌÉT£NÈ˵|c¦b*]á)pÛC|f¶×,-6t»spü^ËC fÍýÌxwvó1£ccuL$ |tp-4ä÷ÕÅç7ÝÆä7†øq÷bY÷–÷Œktëhˆq{Î’#,.kêÒǃ2â6ÃÊW¯´s!¹¸a-¦y79ÇŒ.9hØI[¡ÖöÄ X¸÷ë5púnJ&Ìͪ²fWtw„7†&åæwla¹y·ã·šæ\n\Kvèc|Œ„Êó4®{Ú#š$qkHmxt ‹xâ³¹=å˜|ÑAö4ÇnÙÖ>QDQ†µÄ=Ìc]¡µp&œzW G X¥À¾Í¸q½-0—±³5õ){Å ÇVtc¼Ô„«I©¦zM¼ÁÔX ”ÖvTS;pí "NZÌ¿›;瘷sºû¥îÙ–Ïî¤Ñpöã‹È¦’¹¯ñ c.!Þ)à±­ËbþÙvÿy·ûÅ®JwLÞñš¡i¼•µ¬m-ñ}oÊíë ã‰N:øÄILcFÀæO•¬ "örÅ’É;q…š´f·:NU‹ôE’‰qº¡?htÁ2”1J:–w¸­y!´\Üuì—ØŒ­ÕͳaÞ[?xüÉú{jS¨ÐHØ19|4üÔÜm7¶¬µÈãî­á™Ò7¹t’w%¿¶„5Ô š‘AR@]!ÁäCxl镸P».;~^ 7Ø·n*y?iJä¶¼#cœOÚwDDƒr¤Œ©¡ž´p“s @ á}  ÖëÍËÉ/6F+šx»yá¾ÂßA|اa†cÞ"žjYÞ5Í/®–ðêZ¿.­™mºoö üÑIk”´–ÔɻȄÍi’)XáÁÚpoV§q]OÆÞC‡½3Ü䦠}ÄQPøfÂA3&£tmüzÜÑ.‚¨ˆ¹AåÀ/WIR—C¢¡4­¯’ø ¼6Å‚÷*?úöZY2DÔ-ÑÖ* H-‹»ii<×U¯ó;/o“Ý’ÚãÿþÑ–pBvãA¡2k Ž–±,î õbÕçÕJU6ÔªªR©ÕÑS¤§TÀ§@ù¦‰Õ()·ÇJ€§T ¥IjuJU6ëPZR•Mº{•:JuL XTª)TÛãïÒÒT §UIjª¥:ê SªR©·ÇSBR•N­¡R˜)J¦Ý}ÚE¡:¥6éRZR‚•©Õ()·ÇS¥UR‚]êIÕ)Tëè© ER•MºT–ªªPSž¤µ:¥6õ Fš'T€§VФS›u¥@R›t©-N©ANº’ÔêÛ§wŠ µ:¥9ü”¨SªR©·]”¸u§T€¥-=‰Õ(mAjuHêÚ%©Õ (<úÔé¢u^ép>]lx!ç‰ÿÜGݯ˾`~þfÿkÞ~±"ûÿfþèb¿fÚþ‹Ð-ÀÛäþŠÔVȦàmòE_^.ï]Äïþ!sOúȹk÷?”ô§lÃØïÔá_–\ÂýþÎ~ؼýfEUèKOR„)B¡ P…(B”!J¥VR NªÀpðÒÒŽ à<ÃSDø…`6”QíWÒNƒ©\B*B°0éEPUÀãáå©Òš¸e" uWxjhª¸Ÿ’‘jÀÜÃRBªžµp8Ò⎀p¡>)ÜÃJ€¢¡\Î*)«ù‡«üTˆíN©üþJ’ÔÕÀüÃRZRƦˆ¨HŠ<)ñJšT¡0UÀáÏ¥IjuHš’ÔêúT–§T€q©¢*< @è¥áUT §]*U n4‹SªP??’ µ0RüÃRZRœõ4)Õ)TÛÕK‡ZuJ w-=‰Õ )·_v¤µ:¥:ª SªPR§JuHU6éîE/ iANà¥@˜=‰AMºôÔ–§T §UAjª¥:êt§T¥SnžçôT‘ÚR‚ÁJ0R‚›uéïÔ–¢«!¸ƒÏîóôž0’ym7¶ 0Õ•‡ÐI´š²…—mf¸šp”ê§U“!f»ñ™3p ŸfÚòh aű-²Vðܺädr÷ä–wfàF BŽv Þ_²(¶ýÝ»$Ý“XÍ$-ƒîXØm.Ö!/:Í@¡v¿³Æ”é+ ÁNºÞ‹V§T¥Wm*´ê”î šÁJU6ëîÔ–§T ¦Ý;¼U%©Õ()Q¦ ª˜ªíñÒ§juJ uyB•N«)pŸP2Ùœ{jb¦3£¶Ó‘vÎk}vJ¨{*"}ŠQÎÍ b DÆÝ©œ¼—¤‘Dʸ”S17ʧ˜ï>^ßïl”å2’7d1Ѿls``ûÄ‘8½½åήóº.Ò]‚š‡BÝëlï M­e,¶ ;¥Í{c½t¯=Ë$hiÑàƒdÔÕJPq˜W2‡1Îsç0œç9„Ç9Œ:˜Æ1„DÆ0Ž¢=ñ¯HîÃF(Ò5jx’® wN“ÔŠ¥zÈ4¨S›té¥@UU()ܨ)TÛ­Ijª¥*›tîæ¨ÒSª`S¯¢’uJU6øéi Õ()ÕPZR‚u©Õ)TÛãïTUU()ýaý“¯bb©·_v‘hN©J¦Ý* SªPR µ:¥*›z†• uíJ t‡”*hR•N¾ŠE¡0R•Mµ©Õ()RZª©J¦Ýz{õ4!:¥:CʨR‚{B§H= Õ()¶¤µ:¥;‚ µ0R•MºìšQ:¤:CËKÂS}¨ )¶¤µ:¥óÔ¦ B©Ì=CRZR‚ÁKŠuJU6ëÝã¥@RU%©Õ{¿ÀçÿÀÄñŸþAµ~[s÷÷9û^óõ‰èÌýÏÄþ͵ý •¨-•J¿\\ÿÞ»‰ßüBæŸõ‘r×î(ÿéNØÿ‡±ß©Â¿,¹…ûýœý±yúÌ‹«Ð–ž¥R„)B¡ P…(B”!J¥R„)B€ÃÓJ:«€vR¡B¾µ4N¤-@Â" ô«ûƒú)'NÅp0 ©*àna¢‰Ôp?8xªt¦¬ï *U CmMuV‡EN”ü ÜÃSDWµ\4qO‡R¸(OZ@8óøéPÀááä©Òš@0øZ’ª¸ŸÉS¥:¤ó I ×µ ž• +ØúQáOÂ×KObuH};¼U%©Õ |5Sª@>ßðT–§_­ (>TN©MºRð¦”×Jƒ©Hæ¡©-N©üþJ’Ôê”Ì5©Õ )J…:¥6øûµ¥@R‚]‹Sª@S¯¢ µ:¥6éRZª©JšS¡:¥*›ixQT §pTÐê”Û¯»RZR‚U%ªª”¨§buJU6øéSµ:¥:º)Pê”Û¯»RZR‚›tîñT§T€¥Nšt'TÅSoަ©Õ()Ò¨ uJ uôT–§T¥SmAjª¥;‚§IêN©Š¦Ýi'T¥SnžåMN©ANà©-L¥SmAjuJU:ªhUU)Tëò $Wð¦*›z†§H)Õ()ÕRZª©ANº‚ÔꔪmþŠ’ uJ w*&bb©·_ Ô–§T §UIjuJ sÔªªPSo»Zšꔪt‡”)Q:¦:ú*KSªR©¶¤µ:¥?¬* SªPSn½=úšR•MºyB‘:¥<[*KUU)TÛRZR‚]©Õ()Ð>í*R•MºtÔR‚”´ö'T¥SmAjuH wIjuL t»SBªB©·Nžõ/ uJ RÒ:“ªR©·»š µ:¤*KSªPSn½=ÚÔé¢u^õp5ËaÛÃÏ ÿ'µ¯Ë.a~ÿg?l^~³"ýÙŸ¹øŸÙ¶¿ bôµ²©BàK‹Ÿû×q;ÿˆ\Óþ².ZýÏåý)Ûðö;õ8Wå—0¿³Ÿ¶/?Y‘cÕzÓÔ¡ P…(B”!J¥R„)B¡ P…(B”!JµÔB„UX>ZZSVÔУÀ¯­*'R€Â‘PUÀô'CÔ®¡íVw†‘ ðêWó…-)ñWs I¨ª¸zii «Ã¢¤µ?¸jh{RèâW…$ëÚ=4i¯b¸:*t”ê<úÔ–§Up?UIjuìHæ’¯j@Sž—ëØÌ:QÀô¢½©üþJ)¤óPÔ–§T€~%IjuWó IjuíJ sÒ¡N© ~aÓgø©pëN©@üþJZ{ ˜uØ5%©Õ )ÕPZR‚›{½Ú’Ôê¥Å:¥6ëÝÏJH m÷*KUU()×ÑRZФ*›j UU()ÏJ…:¥6øûµ©§juJ utRÓTê”芒Ôê”ÛÝîT§T€¥MèN©Š¦ßv´©ÚR‚!ÑJ•N©AN¾Š‚ÔÁHU6Ô–§T ¥MRuL íצ¦©Õ)TÛ§”)iUR‚ÁRZ˜)J¦Ú‚ÔꔪuTЦ PS¯ÉSDꘪmêZjR‚ÁRZR•MºÔªªR©·Or¤‚R‚ŸÖ4ESM¾>ý"ÕUJ uT§T §]IjuJUvøêhSªPS«¢•ª¦:¤µJU6ÔªªPR§JuJU6ëÓß©¡N©J¦Ñ(R N©Nà©-L¥SmAjuH utT–ª1Tëò M *”ªmñÒ UT ¥IjuJU6ëPZR‚]%©Õ()×¶¦…:¥6øéP'T §=-=‰Õ()·Z‚Ôêêè¨-UT §_»J…J mñ÷iJ‰Õ()ÏS§±0W¾Ü ð »ÿDÿÉÍkò·˜_¿ùÏÛ¿¬È¿Aö_îv'öe¯è½­=lªP…øâçþõÜNÿâ4ÿ¬‹–¿sùGÿJvÇü=ŽýNùeÌ/ßìçí‹ÏÖdXõ^„´õ(B”!J¥R„)B¡ P…(B”!J¥R„)B¡ P…¨‡xh¢uVóÒÒŽ à` M < ÚÒ¢u*ÀqþºÀ«û»ô“ãÔ®¡íW=*ü àpðòRÒš¸˜jHíEUÀãáå©Òš¸9ütˆ)‚z•ÀÃSDTu«èL} Áà\¯j@8ôÒ-MX‹J*=5BuW‡E"ÔÁJzš'^Õp?=.)øù†—U ŸÉHµ:¤ó»¤µ:¤óÔéN©üÃRZRœô¸§^Ä¥So»Z\ª@?õ…-)Õ(nµ©Õ )ÕRZRÇž¦‰Ôx‚T¸õ¦”è%*U )·Nš’ÕUJçòT¦ B©¶¤µ:¥*hSªPSn½4¨ªPSnžå"Ôê”þ°¨-L…SmIjuJ TЧTÀ¦ÝziSµ:¥6éîTéªuH wIj`¥*›j UU()Ü4)‚˜ë¥DU()·Nš5U^Ô §pT–§T¥Snµ©Õ)Tê¥BR‚}4LÅSoŽ‘juH uTªª`S® µ:¥*»|t¨SªPS¸*hªb©·_v‘juJ mÒ µ:¥* SªR©·]ƒJŠª”é(TÐ'TÀ§_EIjuJU6øêKSªR©ÕÑPZ˜)ANò *'T¥SoPÔ¯jPS¸)§T¥Snµ©Õ)TÛ§¹PZª©N¾ŠTN©J¦Þ¡© 'T §U"Ôê”ë¨-N©J¦Ý=Ïè©-N©ANà©LÄ¥So¿J:¥:ªKSªPS® µUWÖÑ%]¹nÕ¹ ¢îVMS/(¨¢§ ßt®ŽFòÛa6Jõá–DéãÐÖ°|.Õ•¥ÅýäV6­/¹šF± t—8Ь•ú#àêXk>1±Š;­XµnSi  [·M ^PܯɌÖEÙŒÍÞ]⺺–b; ¯sÈÿÞ_¢Ø«&ã1–ØÖš¶Þãè¿äYÃXÅßR„/À—?÷®âwÿ¹§ýd\µûŸÊ?úS¶?áìwêp¯Ë.a~ÿg?l^~³"Ǫô%§©B¡ P…(B”!J¥R„)B¡ P…(B”!J¥R„)B¡ P…¨‡†Šê®ç©ÒŽ À`ð *#ˆVÖ•¯j¸—øp8PŽ!\„Tu«„6Ò 'àV‡EN’š¸˜iÚUÀüáS¥ÀÀ>I Ô«Ä)Q:„€zÇ©\ Ì4¸ëÚÏËHµ5p8xJ’T€qðòÔéM\útÔ–§R54N£ëH ñHÛ¯M*Ф‡E-)Õ yõ¨-N©üüžåIjª¤=MT€¥.)¥6ëÓJ:¤õR-N©@ýu%©Õ\Û¥AjuJ MªPSnÞ*<)¥óòûµ4I×± )·¨jKSª@SŸ’¤µ:¥*›u¨-N©ANª\SªPS iP'T ¦Ý:i§T §=Aj`¤*œÃ­AjuJ uR¡N©NºšêÛ§M"ÔëÚ”¨-UT¥Snµ%©Õ)Tê©¡LÀ§]*ꔪmñÔ–§T §UIjuJ uÔ§T¥SnžåI:¥;‚•uìJU6ëîÔ–§T §UIjª¦* SªR«·ÇSDê”êò…*ê˜ëè©-N© ¦ßAjuL wNžÅUJ ôjhŠ¥6éÓJUR‚ÁRZSMµ©Õ!Tê©ÒSª`S¯¢¦‰‚”ªíñÒ N©ANª’ÕUJ uÔ§T¥SnžçôTé)Õ()Ü“±1TÛ¯»S¤'T §UIjuJ uÔ§T…SoާJª§!Œs¥)Œs¥ „Æ0è DDDkŽI#Š7K+ƒbh$’@$’x:ÉàÆÇÈñ@¹î4 ’O@t•˜¼:`雎àa-$ÅRn*C3l¢c¼–ð€zBÅ÷ªGÞ”yKßJøŸæ´ÎBý™´åï1¥Ãï3´ø²i5î£=l¨«Ü8:šEZM~©å,.12·sî(ô_Só¸qeGûGŽ§ÓƒZx·í:”ýâëE;RÞhÐ8"@0né˺óxkåô:ìê¥_ŸÎ"ý’ØâïÉwæEޏr¡¥² åsß-‹1iŒci[²qôô‹xÄ~ÄúRè»~r¢EVYR¦(qÔÃõvÝþp¹™¶vý†Û°±Á>Çg ´n’£#£‚6ÄÂòÛÖ4¼µ€¸µ­Ö€ð,Ïòç²s™{¬ÕÝÖU·W—2ÎðÉmÃå{¤ph6Î! ¸†‚ç)ROŽÿ´%·óÎJúVØü£Yîk{¿oy ÏoXß– ƒé™+mìŠ~ЖßÏ9+é[cò;ÜÖ÷~ÞòžÞ– ƒé™+mìŠ~ЖßÏ9+é[cò;ÜÖ÷~ÞòžÞ– ƒé™+mìŠ~ЖßÏ9+é[cò;ÜÖ÷~ÞòžÞ– ƒé™+mìŠ~ЖßÏ9+é[cò;ÜÖ÷~ÞòžÞ– ƒé™+mìŠ~ЖßÏ9+é[cò;ÜÖ÷~ÞòžÞ– ƒé™+mìŠ~ЖßÏ9+é[cò;ÜÖ÷~ÞòžÞ– ƒé™+mìŠ~ЖßÏ9+é[cò;ÜÖ÷~ÞòžÞ– ƒé™+mìŠ~ЖßÏ9+é[cò;ÜÖ÷~ÞòžÞ– ƒé™+mìŠ~ЖßÏ9+é[cò;ÜÖ÷~ÞòžÞ– ƒé™+mìŠ~ЖßÏ9+é[cò;ÜÖ÷~ÞòžÞ– ƒé™+mìŠ~ЖßÏ9+é[cò;ÜÖ÷~ÞòžÞ– ƒé™+mìŠ~ЖßÏ9+é[cò;ÜÖ÷~ÞòžÞ– ƒé™+mìŠ~ЖßÏ9+é[cò;ÜÖ÷~ÞòžÞ– ƒé™+mìŠ~ЖßÏ9+é[cò;ÜÖ÷~ÞòžÞ– ƒé™+mìŠ~ЖßÏ9+é[cò;ÜÖ÷~ÞòžÞ– ƒé™+mìŠ~ЖßÏ9+é[cò;ÜÖ÷~ÞòžÞ– ƒé™+mìŠ~ЖßÏ9+é[cò;ÜÖ÷~ÞòžÞ– ƒé™+mìŠ~ЖßÏ9+é[cò;ÜÖ÷~ÞòžÞ– ƒé™+mìŠ~ЖßÏ9+é[cò;ÜÖ÷~ÞòžÞ– ƒé™+mìŠ~ЖßÏ9+é[cò;ÜÖ÷~ÞòžÞ– ƒé™+mìŠ~ЖßÏ9+é[cò;ÜÖ÷~ÞòžÞ– ƒé™+mìŠ~ЖßÏ9+é[cò;¼Ö÷~ÞòžÞ– ƒé™+mìŠÁ솷ûç%})l~Q£çwšÞïÛÞBóÛÓù`Ø>™˜ò¶Þȵý¡íÏž2OÒ–Çå*_;œÖ÷~ÞòžÞ—ËÁôÌÇ•¶öE?h{s眓ô¥±ùJÎk{¿oy ÏoOåƒ`ÿy˜ò¶Þȵý¢-ÐþùÉ?J[”©|íó[Ýû{È^{z,;ÒòþVßÙU¿h«{猓ô¥±ùJŸÎç5½ß·¼…ç·¥òÁ°}31åm½•kûEÛßXv¥åü­¿²«~ÑÖÿÏ#éKgò/®jû¿oy ÏnGËÂôÌÇ•¶öU¯íoüï‘þ”¶)ÑóµÍ_wíï!yíÈùbØ^—˜ò¶þʵd„|d¥-ŸÊt¾vy©îý½ä/=¹?–-…éy+oì«_ÚFç|ôµùR—ÎÇ5=ß·ü…ç·%òŰ½//åmý•kûI@ü“¶¿*Qó¯ÍOwíÿ!yíÉü±ì/KËù[eVd¤{äo¤í¯Ê”|ëóSÝûÈ^{r>Xö¥åü­¿²­iX/ò/Òv×åJ>uù©îý¿ä/=¹?–=…éy+oì«PöKÁ‡z_"ý'm~U¥ó¯ÍOwíÿ!yíÈùcØ^——ò¶þÊ­ûLAüí‘>“¶ÿ*Ñó­Í?wíÿ!yíÈùdØ~——ò¶þÊ {&¡½-‘>“¶ÿ*ÒùÕæŸ»öÿ¼öäþY6¥åü­¿²«~ÓpŸ;d?¤­¿ÊÔ¾u9§èÈ]ûr>Y6¥åü­¿²­iØ_²ÒVßåj_:|Òô ¿ä.ý¹,ÛÒòþVßÙUƒÙ? ÞÙé+sòµ:|Óô »öä|²ì?KËù[eZþÔß:ä/¤­ÏÊô|éóKÐ6ÿ»öäþY¶¥åü­¿²«²Š?½rôÉ[Ÿ•é|ésKÐ6ÿ»öä|³l?KËù[eZþÔpÿ:䤭ßÊô|ésKÐ0BïÛ‘òϱ=//åmý•[ö¥ˆù× þñ·+ÒùÐæ `<…ß·#åŸaú^_ÊÛû*×ö§‰ùÓ }#nþX¥ó¡Í@Ày ¿nOåŸbz^_ÊÛû*°{*bƒûÓ }#nþX£ç?š>€ò~Ü–}‰éy+oìªßµTWΗÿÒ6÷åš>sù£è!wíÉü´lOKËù[eVý«bþt¿‡ÿxÛß–i|çsCÐ0BïÛ‘òѱ=//åmý•jÊèÀïIßßHÛß–i|æóCÐ0BïÛ‘òÓ±}//åmý•[ö°ŒùÎýúBßüµKç3š€ò~ÜŸËNÅô¼·•·öU¨{,£CûÎýúBßüµKç/™þ€ò~Ü–­‹éyo+oìªßµ¤wÎWçÒÿåª>rùŸè!wí¨ùjؾ—–ò¶þʬËhðïI_ŸH[ÿ–èùËæyÿö!wí©üµl_KËy[eZþÖñÿ9_H@~[¥ó•Ìÿ@Àù ¿mGË^Åô¼·•·öU`ö]0ï+ìz_À~[¥ó“Ìï@Àù ¿mOå¯bú^[ÊÛû*·ívÄ?¼o¯ãà?.RùÈæw `|…ß¶£å³cz^[ÊÛû*°{/™÷óü|åÊ_8üÎô‘»öÔ|¶loKËy[eVf0ïHß?ÇÀþ]£ç™Þò~ÚŸËnÆô¼·•·öU¯í„Ïç ãøøË´¾q¹›è8#wí¨ùmØÞ—–ò¶þʬÌFýá|u¿‚ü»GÎ/3}änýµ?–Ýéyo+oìªß¶3_œ/ã ¿/RùÄæg à¼ß¶£å»cú^[ÊÛû*°{2÷…ïütåê_8|Ìô‘»öÔ|·lKËy[eVfSpïH^ßÇAþ_£ç™žƒ‚ò7^ÚŸË~Çô¬·•·öUoÛ1¿ú}ëütåú_8\Ìô‘ºöÔ|·ìKËy[eVfrþzõ½ƒü¿Kç™~ƒ‚ò7^ڟˆÇô¬¯•·öU¯í úuéül'Ô¾p9—è8/#uí¨ùpÙ—•ò¶þʬÍ$ƒüúóþ6ê _7üÊô‘ºöÔ|¸ìJÊù[fVf¢aÞ}yÿ õ 7üÊô‘ºöÔþ\vG¥e|­¿³+~ÚÉÿ¦Þ_ÆÂýCKæû™^ƒƒò7^Ú—‘éY_+oìÊÁìÙ žÞ?ÆBýEKæ÷™>ƒƒò7^ÚŸË–Èô¬¯•·öe`öm”?Ïoã!~¢¥óyÌŸAÁù¯lGËžÈô¬¯•·öeoÛt?Ó/ã!¾¢¥ówÌŸAÁù¯lOåÏdúVWÊÛû2°{7ôÿ<¼:ÞC}GGÍß2}än½±.{'Ò²¾VßÙ•¿nóË¿øÈ¨èùºæG àü×¶#åÓdúVWÊÛû2·íÈoôË»ø¸©*~ny‘è8?#uí‰üºlŸJÊùX=™jÎSùåÝü\?Ô”|ÜsÐp~FëÛòë²}++å öeoÛ ÿéwoñqRÒù·æ?¡a<×¶'òí²}++å öepöu(çw`ô»ˆú–›~cúÈÝ{b>]¶O¥e|¤̵gb¡Þwvõ-/›ncúÈÝ{b.Û+Ò²žRfVý»–ÿJºÿЉúš—ͯ1½ än½±.û+Ò²žRfVgŠáþuuõ5/›>czÈÝ{b>]öW¥e<¤̬Ï5üêêþ*'êz_6|Æô,'‘ºöÄþ^6W¥e<¤Ì­ûz¸ÿIºŠŠúž›>czÈÝ{b>^6W¥e<¤̬Ïw!þstõE/›búÈÝ{b/;/Ò²žRfVý¾]¤]ÄÅ}QKæÃ˜¾……ò7^Ø——éYO)³+~ßnÿÒ.âbþ¨¥ó_ÌOBÂùŸlGËÖËô¬§”ƒÙ•ƒÙúð;Î.âbþ©¥ó_ÌOBÂùŸlOåëeúVSÊAìÊßõyÿŸ¹¿‰ŒúªšîbzÈÜûb>^ö_¥e<¤̬=÷û—ø˜Ïª©|Öóа¾FçÛù{Ùž•”ò{2°pø?ßîOâ#>ª¥óYÌ?BÂùŸkGËæÌô¬§”ƒÙ•¿ê ÿÿ=rõ]/š¾aúÈÜûZ/›3Ò²žRfV$ýþãëqõ]5|Ãô<7‘¹ö´|¾lÏIÉùH=™[þ¡R!ÞZãþ"7êÊ>j¹…èX_#síhù}Ùž•”ò{2dx ß.ò—Ã^Rv;¢ÃÙÇÚu…qKüÓsF6×Çë6Š«§ äùÙlxs§É8£,4>0ø]÷øB9Ê ž0©¨Q.ó‡w<ÂUŠ[Þ&è5yVëæ†ùÞŒ0g²¾Èš÷, Š/¢¬Œ4>FMdv¯AÛÛ iíw qq²è w®¬’}4{Ë‹kÖ¤} Ѽk†!,–艧۔¥ÔÛ…×PþºsÖ€·Þ…)HP)C@Є+P…(Bø|]¯ü'Ñ÷¿ûÍ5¡ æùÔüÚ§Èž§æÐ…>Dõ?6„)ò'©ù´!O‘=OÍ¡ |‰ê~mSäOSóhBŸ"zŸ›BùÔüÚ§Èž§æÐ…>Dõ?6„)ò'©ù´!O‘=OÍ¡ |‰ê~mSäOSóhBŸ"zŸ›BùÔüÚ§Èž§æÐ…>Dõ?6„)ò'©ù´!O‘=OÍ¡ |‰ê~mSäOSóhBŸ"zŸ›BùÔüÚ§Èž§æÐ…>Dõ?6„)ò'©ù´!O‘=OÍ¡ |‰ê~mSäOSóhBŸ"zŸ›BùÔüÚ§Èž§æÐ…>Dõ?6„)ò'©ù´!O‘=OÍ¡ |‰ê~mSäOSóhBŸ"zŸ›BùÔüÚ§Èž§æÐ…>Dõ?6„)ò'©ù´!O‘=OÍ¡ |‰ê~mSäOSóhBŸ"zŸ›BùÔüÚ§Èž§æÐ…>Dõ?6„)ò'©ù´!O‘=OÍ¡ |‰ê~mSäOSóhBŸ"zŸ›BùÔüÚ§Èž§æÐ…>Dõ?6„)ò'©ù´!O‘=OÍ¡ |‰ê~mSäOSóhBŸ"zŸ›BùÔüÚ§Èž§æÐ…>Dõ?6„)ò'©ù´!O‘=OÍ¡ |‰ê~mSäOSóhBŸ"zŸ›BùÔüÚ§Èž§æÐ…>Dõ?6„)ò'©ù´!O‘=OÍ¡ |‰ê~mSäOSóhBŸ"zŸ›BùÔüÚ§Èž§æÐ…>Dõ?6„)ò'©ù´!O‘=OÍ¡ |‰ê~mSäOSóhBŸ"zŸ›BùÔüÚ§Èž§æÐ…>Dõ?6„)ò'©ù´!O‘=OÍ¡ |‰ê~mSäOSóhBŸ"zŸ›BùÔüÚ¾ô=Oì; ?û¿à¡ é¡ P…(B”!ÿÙopenchange-2.0/apidocs/html/libmapi++/hierarchy.html000066400000000000000000000133651223057412600224710ustar00rootroot00000000000000 MAPIC++ClientLibraryBindings 2.0 API Documentation
Class Hierarchy
This inheritance list is sorted roughly, but not completely, alphabetically:
[detail level 12]
oClibmapipp::objectBase Object class
|oClibmapipp::attachmentThis class represents a message attachment
|oClibmapipp::folderThis class represents a folder or container within Exchange
|oClibmapipp::messageThis class represents a message in Exchange
|\Clibmapipp::message_storeThis class represents the Message Store in Exchange
oClibmapipp::profile_databaseThis class represents a user profile database
oClibmapipp::property_containerA container of properties to be used with classes derived from object
oClibmapipp::property_container_iteratorIterator to use with Property Container
\Clibmapipp::sessionThis class represents a MAPI session with the Exchange Server

Creative Commons License
Creative Commons Attribution icon Creative Commons Share Alike icon
This content is licensed under the Creative Commons
Attribution ShareAlike License v. 3.0:
http://creativecommons.org/licenses/by-sa/3.0/

openchange-2.0/apidocs/html/libmapi++/index.html000066400000000000000000000306211223057412600216140ustar00rootroot00000000000000 MAPIC++ClientLibraryBindings 2.0 API Documentation
libmapi++

libmapi++ - C++ Bindings for OpenChange Clients

libmapi++ provides C++ bindings for OpenChange client libraries (libmapi). It is intended to provide a higher level abstraction of the OpenChange client libraries for C++ users who would prefer to work with an object-oriented API.

Using libmapi++

Note
libmapi++ classes live in the libmapipp namespace.

When using libmapi++, you start by creating a session, and logging in to the server.

// Initialize MAPI Session
libmapipp::session mapi_session;
// login() can use an optional profile_name, and an optional password
mapi_session.login();

The session can then access the message store, which is the tree of private folders associated with a single user (containing various folders, such as the Inbox, Sent Mail, Calendar, Journal and so on).

The message store is associated with the session, so you don't create it yourself. Instead, you obtain it using the session object's get_message_store() method.

// Take a reference to the message store
libmapipp::message_store &msg_store = mapi_session.get_message_store();
Note
It has to be a reference, not a copy / assignment.

Most objects in libmapi++ (and any kind of MAPI library) can be considered to have properties that belong to them, and subordinate (child) objects. For example, the name of the message store is a property of the message store, but the various folders in the message store (or equally, the messages in a folder, or the attachments to a message) are part of a hierachy.

To get access to the properties of an object, you obtain the property_container associated with the object, set the properties you want to access, call fetch(), and then read off the various properties.

// Get a property of the top level message store
msg_store_props << PR_DISPLAY_NAME; // you could use other properties here
msg_store_props.fetch();
std::cout << "Message store display name: "
<< (const char*)msg_store_props[PR_DISPLAY_NAME]
<< std::endl;

Note that the operator[] is essentially a lookup operator. If you'd prefer to use an iterator, look at libmapipp::property_container_iterator.

As noted above, the objects in libmapi++ can be considered as a hierachy. To get the child elements for an object, you use the hierachy table for that element. For example, to get the various folders in the private information store, you could use code like this:

// We start off by fetching the top level folder
mapi_id_t top_folder_id = msg_store.get_default_folder(olFolderTopInformationStore);
libmapipp::folder top_folder(msg_store, top_folder_id);
// Now get the child folders of the top level folder. These are returned as
// a std::vector of pointers to folders
libmapipp::folder::hierarchy_container_type child_folders = top_folder.fetch_hierarchy();
// Display the name, total item count and unread item count for each folder
for (unsigned int i = 0; i < child_folders.size(); ++i) {
libmapipp::property_container child_props = child_folders[i]->get_property_container();
child_props << PR_DISPLAY_NAME << PR_CONTENT_COUNT << PR_CONTENT_UNREAD;
child_props.fetch();
std::cout << "|-----> " << (const char*)child_props[PR_DISPLAY_NAME]
<< " (" << (*(int*)child_props[PR_CONTENT_COUNT]) << " items, "
<< (*(int*)child_props[PR_CONTENT_UNREAD]) << " unread)"
<< std::endl;
}

As an alternative to working through the folder tree hierachy, you can also open folders directly. In the example below, we open the Inbox. The API documentation for message_store::get_default_folder() provides a list of other folder IDs that you may find useful.

mapi_id_t inbox_id = msg_store.get_default_folder(olFolderInbox);
libmapipp::folder inbox_folder(msg_store, inbox_id);

You can then get each message in the folder:

// These are returned as a std::vector of pointers to messages
libmapipp::folder::message_container_type messages = inbox_folder.fetch_messages();
std::cout << "Inbox contains " << messages.size() << " messages" << std::endl;

You can then get the various properties of each message in the same way as was used for the folder properties - you get the associated property_container, set the required properties, and call fetch() before reading off the required properties:

// Work through each message
for (unsigned int i = 0; i < messages.size(); ++i) {
// Get the properties we are interested in
libmapipp::property_container msg_props = messages[i]->get_property_container();
// We get the "to" addressee, and the subject
msg_props << PR_DISPLAY_TO << PR_CONVERSATION_TOPIC;
msg_props.fetch();
// Display those properties
std::cout << "|-----> " << (const char*)msg_props[PR_DISPLAY_TO]
<< "\t\t| " << (const char*)msg_props[PR_CONVERSATION_TOPIC]
<< std::endl;
}
Todo:
Explain attachments.

Creative Commons License
Creative Commons Attribution icon Creative Commons Share Alike icon
This content is licensed under the Creative Commons
Attribution ShareAlike License v. 3.0:
http://creativecommons.org/licenses/by-sa/3.0/

openchange-2.0/apidocs/html/libmapi++/messages_8cpp-example.html000066400000000000000000000256531223057412600247100ustar00rootroot00000000000000 MAPIC++ClientLibraryBindings 2.0 API Documentation
messages.cpp
This example displays information about the messages in the inbox, with

output like:

Inbox contains 2 messages
|-----> Test User1 | Working Remotely with Windows Small Business Server
|-----> Test User1 | Welcome to Windows Small Business Server 2003

The example shows how to create a session, get the message_store, and open the inbox folder. It then determines how many messages are in the inbox folder, and retrieves and prints the intended addressee and the message subject.

/*
libmapi C++ Wrapper
Sample folder message application
Copyright (C) Brad Hards <bradh@frogmouth.net> 2008.
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#include <exception>
#include <string>
#include <libmapi++/libmapi++.h>
int main ()
{
try {
// Initialize MAPI Session
libmapipp::session mapi_session;
// You could log in with a non-default profile here
mapi_session.login();
// Get the private (user) folders message store
libmapipp::message_store &msg_store = mapi_session.get_message_store();
// We start off by fetching the inbox
mapi_id_t inbox_id = msg_store.get_default_folder(olFolderInbox);
libmapipp::folder inbox_folder(msg_store, inbox_id);
// Now get the messages in this folder These are returned as
// a std::vector of pointers to messages
libmapipp::folder::message_container_type messages = inbox_folder.fetch_messages();
std::cout << "Inbox contains " << messages.size() << " messages" << std::endl;
// Work through each message
for (unsigned int i = 0; i < messages.size(); ++i) {
// Get the properties we are interested in
libmapipp::property_container msg_props = messages[i]->get_property_container();
// We get the "to" addressee, and the subject
// You can get a lot of other properties here (e.g. sender, body, etc).
msg_props << PR_DISPLAY_TO << PR_CONVERSATION_TOPIC;
msg_props.fetch();
// Display those properties
if (msg_props[PR_DISPLAY_TO] != 0) {
std::cout << "|-----> " << (const char*)msg_props[PR_DISPLAY_TO];
if(msg_props[PR_CONVERSATION_TOPIC] != 0) {
std::cout << "\t\t| " << (const char*)msg_props[PR_CONVERSATION_TOPIC];
}
std::cout << std::endl;
}
}
}
catch (libmapipp::mapi_exception e) // Catch any MAPI exceptions
{
std::cout << "MAPI Exception in main: " << e.what()
<< std::endl;
}
catch (std::runtime_error e) // Catch any other runtime exceptions
{
std::cout << "std::runtime_error exception in main: "
<< e.what() << std::endl;
}
return 0;
}

Creative Commons License
Creative Commons Attribution icon Creative Commons Share Alike icon
This content is licensed under the Creative Commons
Attribution ShareAlike License v. 3.0:
http://creativecommons.org/licenses/by-sa/3.0/

openchange-2.0/apidocs/html/libmapi++/middle_bg.jpg000066400000000000000000000005251223057412600222270ustar00rootroot00000000000000ÿØÿàJFIFddÿìDuckydÿîAdobedÀÿÛ„ÿÀdÿÄU Q¡Ña‘ÿÚ ?ßÀ#¿ªÚ0 ïæ¶œ ‡3Yû žñݲ ?ÿÙopenchange-2.0/apidocs/html/libmapi++/namespacelibmapipp.html000066400000000000000000000144351223057412600243440ustar00rootroot00000000000000 MAPIC++ClientLibraryBindings 2.0 API Documentation
libmapipp Namespace Reference

The libmapi++ classes and other definitions are all enclosed in the libmapipp namespace. More...

Classes

class  attachment
 This class represents a message attachment. More...
class  folder
 This class represents a folder or container within Exchange. More...
class  message
 This class represents a message in Exchange. More...
class  message_store
 This class represents the Message Store in Exchange. More...
class  object
 Base Object class. More...
class  profile_database
 This class represents a user profile database. More...
class  property_container
 A container of properties to be used with classes derived from object. More...
class  property_container_iterator
 Iterator to use with Property Container. More...
class  session
 This class represents a MAPI session with the Exchange Server. More...

Detailed Description

The libmapi++ classes and other definitions are all enclosed in the libmapipp namespace.


Creative Commons License
Creative Commons Attribution icon Creative Commons Share Alike icon
This content is licensed under the Creative Commons
Attribution ShareAlike License v. 3.0:
http://creativecommons.org/licenses/by-sa/3.0/

openchange-2.0/apidocs/html/libmapi++/namespaces.html000066400000000000000000000051051223057412600226230ustar00rootroot00000000000000 MAPIC++ClientLibraryBindings 2.0 API Documentation
Namespace List
Here is a list of all documented namespaces with brief descriptions:
\NlibmapippThe libmapi++ classes and other definitions are all enclosed in the libmapipp namespace

Creative Commons License
Creative Commons Attribution icon Creative Commons Share Alike icon
This content is licensed under the Creative Commons
Attribution ShareAlike License v. 3.0:
http://creativecommons.org/licenses/by-sa/3.0/

openchange-2.0/apidocs/html/libmapi++/nav_f.png000066400000000000000000000002311223057412600214100ustar00rootroot00000000000000‰PNG  IHDR8³»`IDATxíÝK€ EÑ–·[†øBÑmkâÄÂH—prÓ¼.‚Žó‚ꎤR6Z VI±E‚5j³„lóš›iI˜¬ÞêçJ0ŒÑÑ/Žû›™uøñóÞ¿6sH ÝõyIEND®B`‚openchange-2.0/apidocs/html/libmapi++/nav_g.png000066400000000000000000000001371223057412600214160ustar00rootroot00000000000000‰PNG  IHDRô1&IDATxíÝ1 ÁOHf„á_ ->~¸åM iËMèÀƒS½ü‚<IEND®B`‚openchange-2.0/apidocs/html/libmapi++/nav_h.png000066400000000000000000000001421223057412600214130ustar00rootroot00000000000000‰PNG  IHDR ,é@)IDATxíÝA @BQ­³šÛ›Ð¢Žáà) )ëý éaÅèÜ¿Æo‡RlÐßIEND®B`‚openchange-2.0/apidocs/html/libmapi++/nav_tab.gif000066400000000000000000000014541223057412600217220ustar00rootroot00000000000000GIF89aPæïïïþþþýþýûüúõ÷óñôïøú÷ýýüúûù÷ùöôöòöøõïóíðôîóöñùúøüýûòõðïòìîòëíñëòõïõõõÿÿÿúúúîòìðóîêëéðððôôôñññýýýñôðÆÉÅìîëÇÊÆÈÊÆÏÏÎÇÊÅËÍÊêìéïóîçèæÎÏÍÐÐÐõ÷ôÊÍÉïñíÆÈÄÊÌÊêêéïóìüýüÊËÉÏÏÏèêçÕ×ÓüüûÍÎÌëíêÌÍËíñêÏÐÏùûøêëêòöðóõñÉÊÇñôîîñì!ù,Pÿ€ˆ‰Š‹ŒŽ‘ˆ‚@;/Ÿ ¡¢£¤¥¦§¨E(ƒ )·¸¹º»¼½¾¿À¸ 7„23ËÌÍÎÏÐÑÒÓÔÐ=*"DÝÞßàáâãäåæä8 îïðñòóôõö÷õ.A þÿ H° ÁƒM R ¡Ã‡#JœH±¢ÅŠ0)ˆÀ±£Ç CŠI²$Ɉ8Xɲ¥Ë—0cÊœIsæD-èÜɳ§ÏŸ@ƒ *”¢’*]Ê´©Ó§P£J:Q‚X³jÝʵ«×¯`­È@‚³hÓª]˶­Û·p‰ßÆ@ôÀݻxóêÝË·¯ß¿~O Bð °áÈ+^̸±ãÆ< @@¹²å˘3kÞ̹3gˆr Mº´éÓ¨S«^Ízõ D4 ÈžM»¶íÛ¸sëÞ­»¢Àƒ N¼¸ñãÈ“'·H€óçУKŸN½ºõë×} À½»÷ïàËO¾|y;openchange-2.0/apidocs/html/libmapi++/open.png000066400000000000000000000001731223057412600212650ustar00rootroot00000000000000‰PNG  IHDR à‘BIDATxíÝÁ €0 Ð׬ՙ\Àº€39—b!©9{|ðI>$#Àß´ý8/¨ÄØzƒ/Ï>2À[ÎgiU,/¬~¼Ï\ Ä9Ù¸IEND®B`‚openchange-2.0/apidocs/html/libmapi++/pages.html000066400000000000000000000043511223057412600216050ustar00rootroot00000000000000 MAPIC++ClientLibraryBindings 2.0 API Documentation
Related Pages
Here is a list of all related documentation pages:

Creative Commons License
Creative Commons Attribution icon Creative Commons Share Alike icon
This content is licensed under the Creative Commons
Attribution ShareAlike License v. 3.0:
http://creativecommons.org/licenses/by-sa/3.0/

openchange-2.0/apidocs/html/libmapi++/pixel_grey.gif000066400000000000000000000000531223057412600224510ustar00rootroot00000000000000GIF89a€îîî!ù,D;openchange-2.0/apidocs/html/libmapi++/sync_off.png000066400000000000000000000015251223057412600221340ustar00rootroot00000000000000‰PNG  IHDRàw=øIDATxíÝKhTWÀñÿä1I&3™8M¦Iš™†I3Ú©b$cÌ I1V1±-(Tö±±Ð.* t!‚K[¥Ä¥ˆ„¨´f£`l(øl©"Y”¤6ÆgÌTú}·sgîܹ ±d{8?æÌ¹÷;çÜuíÚ`:!±F¬¢BäŠ?ŰÄm'yÊÅ>ÑlU¯½üý‰è_‹?€Œê ]€Y(ŠNñ±8fý1°Öqún-eâ¨øtºmâÈ Ó0}b›ù%·©µ×Œ®=Ÿ0´³?Š1sŸ‹0€¯8À‘;_ ‹W|%\ Zð— >舽ln¨p©.aÇ{ )t;Ú b nŸš¯›65°¢¡2çÅÔ?Žž>Oдàuönm¤¢Ì`×­Z¬WjC~>‘Ö¾0+á {{©fÝ×Mæ·æÅ•ìÙ¼˜` Ý›%uA6´½ÅÆö¨Á,]k¢ÄW¼™u±›]‹ˆ7§¯iòh€ ¶¶¬ÏÖu1 ló —Ҷ̺–:ÞÍ\ÄcãÏxøhR²Êè‡Qt$¿ß§¨ ª fdºü<4BÿÙ[•f¸d7=.Mé9/—éªÃëù/ÿO Üaàò}€,‘j?Ÿõ.5Úšm?œÿŸ®ŽXÿ2¬#¸d píæ(£?cÛú¼!½›a1¥Þ—ŽòØ©ܾ7dÔK:‚ùÒ‰ì)Ê3‚Ü™àÌà]€,±H€µ+køöäu<|`·LhC7¹ÔeÍ Ÿ×Ÿ˜tÜ‹ óH$^2%l.êaeÐäýE”ÌÉ|ÅÜìî‰Ýsä }¸ýDû^hzé~ðR›¦Ã¡¿]|#ü¯@×—Ö‡[k¹–<|š(Ç*€Ý¹dÇtMé:Ýñø«Ø,êÅû¢]”' øXÓ_nò¡Æ|Øý /c§fžâOIEND®B`‚openchange-2.0/apidocs/html/libmapi++/sync_on.png000066400000000000000000000015151223057412600217750ustar00rootroot00000000000000‰PNG  IHDRàw=øIDATxíÝ_HTYÀñï8ã¤ó§i§4-g6ÆËÕ&kQ)¨Ô!Š0ÒURKÚ…„ê¡/»PEÁ>ìK-+KÁ²Ñ.Y”¾dEPaA‰ø°¥¶›ZSÓïÜ;3wºŠ–¯—߯gfîïœsçœWKÇñ.€ÉøD­¨a‘'¬âq_ôˆk¢ÀŒ ÀDŽøQ´ÄïC¨¶åñÏÿgÅ ñ 0„Y‚:qZ¦Á)~õâ€èLý0HVñ× žz-¿‰C“%¨g¦˜6€é8%Úõ¬ëwêÙUÏ¿˜ª³Ä }? ?€·3ÀÀž©Š À”K• @hà a±ðaÇæUe‹ sù~ë2²ì“&Ú&B*AÄljæºììi*˨,Ëçí»÷oÆ£T”,d[˜¼3-*ÁÀ…>å‡Ë çLÉŸçfk˜Ò éw#*AEjKUy>ûšËÉõ&{µ¢8—m5Ki¬ jjƒD*¿NŽÖigwÃ7Dª’mz骹úKÛ¾±ˆ¶M!æ¤ÍkÐ?šoý¬_åÓlXí#Ò~–¸¬ê×ÒÑXŠÓ‘ùRÙ*Eû‚ՂדðEÜ;6«e"Q(²Ù=–¿Ezæ5Kؼָ_ 1òzBªJë ±XŒì96åªjL^7{ùãJÑ÷1½i@%8'7M©_\Qœ#ÓUŒËñýÿyõ Wo Éx8¼s¥v¯ªì|×SnÜ q_m Ýé î>bèÕí[JX,½4[Tú{R£ë¼ôˆ¾þa€tÝjjzzÅ'ÅìȶiIžŽòwÏs ¡€—ÕKøõâC^ŽŒ˜Y­¨µÉ%6¨´êˆº]vÛðhâ½iWv–hôëê°Ò¨¾'æÌ‚·ñ|[ßìúÅ^€YrD=<ýDû]äÇ÷s€Ïõ‹8™ºCì? À ¨—t4õᩎ¡Jã‡W‹É± îr¼cjMɘìx| šE©øNÔ‰œøA¢þ«–€Z¼ñ‡jó î#™§¢¢4gIEND®B`‚openchange-2.0/apidocs/html/libmapi++/tab_a.png000066400000000000000000000002161223057412600213700ustar00rootroot00000000000000‰PNG  IHDR$ÇÇ[UIDATxíK €0C'o¤(Šˆ[Žà%Üxÿ#Ù©­ç ùÁöó¦W¦e# 3t I 3+¼øEã~\D½9¯Ûàè’wM·¿öÿ}Yõ_êA4Yžã}IEND®B`‚openchange-2.0/apidocs/html/libmapi++/tab_b.png000066400000000000000000000002471223057412600213750ustar00rootroot00000000000000‰PNG  IHDR$ÇÇ[nIDATxíÝQ Â0„áàœR¥Xc±I7IÓ¨g|òÕÙœäãgY˜3˜Ï÷‡u{£ÔW—ÊSíŒ1Ü ¼CjˆiC†G¬ýççJ+| ÖÝs7ùŒ+Ù›`t‚3Ü‚a¢K¤Gq°ûQÍZÝT=@*éC݇LIEND®B`‚openchange-2.0/apidocs/html/libmapi++/tab_h.png000066400000000000000000000003001223057412600213710ustar00rootroot00000000000000‰PNG  IHDR$ÇÇ[‡IDATxíÝË ‚@EÑ 7êÂX’Ñø AADùjGü€ Z€e؈£ ë8¹›—Wƒx¾ÞìUK.µ%„0mɤ&+4iÑ$džÈt“׿ÍzWf5AZá'w¼øÆ"2¶Wœðòg%öªdæ)æþ™ÉR15F®dìž ÉБßO«×Áô»C"à@¯g=IEND®B`‚openchange-2.0/apidocs/html/libmapi++/tab_s.png000066400000000000000000000002701223057412600214120ustar00rootroot00000000000000‰PNG  IHDR$ÇÇ[IDATxíÝ ‚@@Ñ£?Q…¤"š¢%¦I‘—Šf–6[´HÃäQƒ<Þâõþ]ždr Í’s?ˆO=Ñññw'ÌF‡Ž íðö-~rÃ[œèŠ­ì¬mƒÖ¬ƒݯнŠÕF)Yº% §`nÌ,9B ™’©!ÑŒ\ý<Å#üîî•IEND®B`‚openchange-2.0/apidocs/html/libmapi++/tabs.css000066400000000000000000000022131223057412600212560ustar00rootroot00000000000000.tabs, .tabs2, .tabs3 { background-image: url('tab_b.png'); width: 100%; z-index: 101; font-size: 13px; font-family: 'Lucida Grande',Geneva,Helvetica,Arial,sans-serif; } .tabs2 { font-size: 10px; } .tabs3 { font-size: 9px; } .tablist { margin: 0; padding: 0; display: table; } .tablist li { float: left; display: table-cell; background-image: url('tab_b.png'); line-height: 36px; list-style: none; } .tablist a { display: block; padding: 0 20px; font-weight: bold; background-image:url('tab_s.png'); background-repeat:no-repeat; background-position:right; color: #283A5D; text-shadow: 0px 1px 1px rgba(255, 255, 255, 0.9); text-decoration: none; outline: none; } .tabs3 .tablist a { padding: 0 10px; } .tablist a:hover { background-image: url('tab_h.png'); background-repeat:repeat-x; color: #fff; text-shadow: 0px 1px 1px rgba(0, 0, 0, 1.0); text-decoration: none; } .tablist li.current a { background-image: url('tab_a.png'); background-repeat:repeat-x; color: #fff; text-shadow: 0px 1px 1px rgba(0, 0, 0, 1.0); } openchange-2.0/apidocs/html/libmapi++/test_8cpp-example.html000066400000000000000000000464471223057412600240640ustar00rootroot00000000000000 MAPIC++ClientLibraryBindings 2.0 API Documentation
test.cpp

An example that shows reading mail.

/*
libmapi C++ Wrapper
Sample test application
Copyright (C) Alan Alvarez 2008.
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#include <exception>
#include <vector>
#include <string>
#include <libmapi++/libmapi++.h>
using namespace libmapipp;
using std::string;
// The best way to get a folder message count is to get property PR_FOLDER_CHILD_COUNT.
// This is only used to test opening all messages.
static unsigned int get_message_count(folder& the_folder, session& mapi_session)
{
folder::message_container_type messages = the_folder.fetch_messages();
return messages.size();
}
static void print_folder_tree(folder& up_folder, session& mapi_session, unsigned int deep = 0)
{
property_container up_folder_property_container = up_folder.get_property_container();
up_folder_property_container << PR_DISPLAY_NAME << PR_CONTAINER_CLASS;
up_folder_property_container.fetch();
string display_name = static_cast<const char*>(up_folder_property_container[PR_DISPLAY_NAME]);
string container_class;
if (up_folder_property_container[PR_CONTAINER_CLASS])
container_class = static_cast<const char*>(up_folder_property_container[PR_CONTAINER_CLASS]);
for (unsigned int i = 0; i < deep; ++i) {
cout << "|----> ";
}
cout << display_name << " (id: " << up_folder.get_id() << ") (messages: " << get_message_count(up_folder, mapi_session) << ")"
<< " container class: " << container_class << endl;
// Fetch Top Information Folder Hierarchy (child folders)
for (unsigned int i = 0; i < hierarchy.size(); ++i) {
print_folder_tree(*hierarchy[i], mapi_session, deep+1);
}
}
int main ()
{
try {
// Initialize MAPI Session
session mapi_session;
mapi_session.login();
property_container store_properties = mapi_session.get_message_store().get_property_container();
store_properties << PR_DISPLAY_NAME;
store_properties.fetch();
cout << "Mailbox Name: " << static_cast<const char*>(*store_properties.begin()) << endl;
// Get Default Inbox folder ID.
mapi_id_t inbox_id = mapi_session.get_message_store().get_default_folder(olFolderInbox);
cout << "inbox_id: " << inbox_id << endl;
// Open Inbox Folder
folder inbox_folder(mapi_session.get_message_store(), inbox_id);
// Fetch messages in Inbox Folder
folder::message_container_type messages = inbox_folder.fetch_messages();
cout << "Inbox size: " << messages.size() << endl;
// Get and Print some information about the first message in the Inbox Folder
if (messages.size() > 0) {
// Get a property container associated to the first message
property_container message_property_container = messages[0]->get_property_container();
// Add Property Tags to be fetched and then fetch the properties.
message_property_container << PR_DISPLAY_TO << PR_CONVERSATION_TOPIC;
message_property_container.fetch_all();
string to;
string subject;
// Get some property values using property_container::operator[]
// to = static_cast<const char*>(message_property_container[PR_DISPLAY_TO]);
// subject = static_cast<const char*>(message_property_container[PR_CONVERSATION_TOPIC]);
// Print property values
// cout << "To: " << to << endl;
// cout << "Subject: " << subject << endl;
for (property_container::iterator Iter = message_property_container.begin(); Iter != message_property_container.end(); Iter++)
{
if (Iter.get_tag() == PR_DISPLAY_TO)
to = (const char*) *Iter;
else if (Iter.get_tag() == PR_CONVERSATION_TOPIC)
subject = (const char*) *Iter;
}
// Print property values
cout << "To: " << to << endl;
cout << "Subject: " << subject << endl;
}
// Get Default Top Information Store folder ID
mapi_id_t top_folder_id = mapi_session.get_message_store().get_default_folder(olFolderTopInformationStore);
// Open Top Information Folder
folder top_folder(mapi_session.get_message_store(), top_folder_id);
print_folder_tree(top_folder, mapi_session);
cout << "finished session" << endl;
}
catch (mapi_exception e) // Catch any mapi exceptions
{
cout << "MAPI Exception @ main: " << e.what() << endl;
}
catch (std::runtime_error e) // Catch runtime exceptions
{
cout << "std::runtime_error exception @ main: " << e.what() << endl;
}
return 0;
}

Creative Commons License
Creative Commons Attribution icon Creative Commons Share Alike icon
This content is licensed under the Creative Commons
Attribution ShareAlike License v. 3.0:
http://creativecommons.org/licenses/by-sa/3.0/

openchange-2.0/apidocs/html/libmapi++/todo.html000066400000000000000000000050151223057412600214510ustar00rootroot00000000000000 MAPIC++ClientLibraryBindings 2.0 API Documentation
Todo List
page libmapi++
Explain attachments.
Class libmapipp::profile_database

possibly rename profile class to profile_database?

we should be able to create a profile using libmapi++ classes

we should be able to delete a profile using libmapi++ classes

maybe move some of the session.h documentation on profiles to profile.h?


Creative Commons License
Creative Commons Attribution icon Creative Commons Share Alike icon
This content is licensed under the Creative Commons
Attribution ShareAlike License v. 3.0:
http://creativecommons.org/licenses/by-sa/3.0/

openchange-2.0/apidocs/html/libmapi/000077500000000000000000000000001223057412600174675ustar00rootroot00000000000000openchange-2.0/apidocs/html/libmapi/24px-Cc-by_white.svg.png000066400000000000000000000053061223057412600237270ustar00rootroot00000000000000‰PNG  IHDR°çá»bKGDÿÿÿÿÿÿ X÷Ü pHYsHHFÉk> IDATXýXmP”U¾vˆeY pW$gQH–%ãËc*$åÃIkFmiØ‘ttrê‡C öa3 Œc†D$ e¬±X, «@³ Â.Èîõþy›uÓ÷·÷úóÌœçÜϹîëºçÜç<þxHØNÛNÛN½+zWô®.–_,¿X|»æÛ5ß® Q†(C`4F#p×ý®û]w@qRqRqðÿÎÿ;ÿcaÇÂŽIÅIÅIÅ@˜$L&Ämâ6qÛòÀ‡Ä-í-í--ùVë[­oµ’ <. … ¡B¨øSRT(*’’IŽ$‡”æHs¤9¤S’S’S‰ð>°Ï÷ˆôˆôˆ$Óôiú4=Ù2Ú2Ú2JZ•V¥Uù`^‚û9À3<Ã3À7ýßôÓl?Ø~°¸ªºªºªœ‡œ‡œ‡€ 6Øpx&õ™ÔgR0—0—0ÀMá¦pSB©P*”–õ–õ–õ@²GÙ£šª›ª›ª¦mMÛš¶#êõˆðj÷j÷jöeïËÞ— äÎäÎäÎÒ^i¯´÷að£ýȳégÓϦ“K{–ö,í±+¦êRu©ºÈŠÎŠÎŠNòöÔí©ÛSë£sñsñsñd{^{^{™u%ëJÖÒÅÛÅÛÅ›IER‘”ÔìÕìÕì%ÇSÇSÇS~gAuuu¤|µ|µ|5)øJð•à+rGËŽ–-äÀ±cÇþs‚å)ËS–§ÈÒ-¥[J·ž»=w{î&µ‚ZA-™÷BÞ y/³£³£³£‹$psäæÈÍR•¨JT%ÚßñýŽïw|OšÌ&³Éü¿'þWX­ÖFòÔ“§ž<õ$é6â6â6Bºæ»æ»æ“ÕÕÕ÷&°Ÿû¹Ÿ<”p(áP‚xxQxQxyëÀ­·üóÄÿŠùçœÿ‘Ô®Ô®Ô®´óŠx.⹈çÈÁÎÁÎÁN7ŽÜ8rã¹æÙ5Ï®y–tŠwŠwŠ'+++ÿÿÄÿŠã€qÀH¿üzðë¤(H$ "‹4Eš" ) ø0àÀ:³ñÌÆ3··7à é é  pNwNwN¦º¦º¦º€ZS­©Ö\K¹–r-èÎíÎíΆg†g†gOgOgOgÀ˜bL1¦õâzq½XÒ·¤oI SÊ”2%033TÿQýGõ€h§h§h'àëëkßdÜÜÝÜÝ܉sç&Î õ õ õÀ¸iÜ4n°uÕÖU[WÙ-*4š ©õ^^^r¹Ãr‡å¤S•S•SéêêJºMºMºM’»rwåîÊ%ûûûIE¤"RIîÙ¼góžÍäÜÆ¹sÉý'öŸØ‚”'Êå‰dÛ–¶-m[îï„N£Óè4¤ÇÛo{¼MŠä"¹HN {]z]z]Ñ:Ñ:Ñ:@¥T)UÊE¶Û!q¸k¾k¾k2e™²LÐÛÛ ¤½Ÿö~ÚûÀ¥ÉK“—&ÿVÿVÿV c.c.c¨­­Ê®•]+»œK>—|.ˆÔDj"5@[t[t[4 _ª_ª_ºpýÕΫW;>Y>Y>Y€õwëïÖ߈§ÄSâ)R'‰“Ä‘Í7›o6ß\¨€Ál0̤¼SÞ)ï$ƒR‚R‚RÈ—3_Î|9“ô³øYü,dÒ¤I7H‹ŸÅÏâGöÕôÕôÕAùAùAù¤Ä 1H dÈùó!çɲÀ²À²@R\".—Å?ÿTüÓÂõïîîÈ(×(×(W{Åç:æ:æ:¡£ÐQèˆÒDi¢´E:žAª U L©§ÔSj`$a$a$pLvLvL†¶mÚ VVV~‰~‰~‰À®_wýºëWÀrÄrÄrÈPf(3”ÀóåÏ—?_|ôÉGŸ|ô ·!nC܆E–o4 šQ¨(Tj*ŠÅŠb`V2+™•o‹·Å{±– ‚€5Ôj Ò­éÖt+P¡þBý ðzáõÂë@÷+ݯt¿èôú{x`c`c`#à~Úý´ûi À` °K>_òù’ϵ«ÚUí È5r\³È!2Ï–g˦ççÃïy}9úrôe»%%×K®—\_¤„ú }†>R!UHRò1ŸÇ|ó!ãZãZãZIe´2ZM.»³ìβ;d{{{¿=¾á†7Þ =.x\ð¸@Ö)ë”uJ²¥­¥­¥\öȲG–=B~œúqêÇ‹z²{²{²Iß}¾û|÷ÝSBª¯U_«¾¶'ÔTßTßTÌý6÷ÛÜoöqéyéyéyàÅÒK_,ÔoªßT¿ xj=µžZ F#‘'kOÖž¬B2B2B2ìñò+ò+ò+ÀK›^ÚôÒ&@Þ!ïw2³Ì,3¿Düñ  ($ ÉBt't't'€Á̓›7+›V6­lÐÜÜL>ŠGñ(Hï×¼_ó~¼úóÕŸ¯þ|5¬a iK±¥ØRH[€-À@Ú²mÙ¶l’{¸‡{þ¦#íænî&mkmkmkIÆ1Žq$ýéOÒ*° ¬Òö¥íKÛ—ö°™’™’™2ùpòáäÃvås r r H˜½Ì^f/r[Ö¶¬mYö Y]Y]Y]¤ùóæþávû7¨\W¹®r)žψgHŸ­>[}¶’º]‰®äžÃ\K]K]KéuÉë’×%Rü©øSñ§di|i|i#FQ`$c¼b¼b¼ÈŽ‹;.Þ_€^êg3f3f3Èʵ•k+×’êUêUêU¤Ãr‡åËIÇq'=4 ¹~lýØú12*+*+*‹ŒÍÍÍ'Ueª2Uéû®ï»¾ï’!!!v¥W„­[FjõZ½VO' ' '<ØÁ‡þ+ñ'†††È¢²¢²¢22\® ב2™ƒÌNèAOßbßbßb2Ç%Ç%Ç…ÔéuzžœŸŸx>ÿ^5¡–ü+^:tEXtComment Created with Inkscape (http://www.inkscape.org/) ã+ldIEND®B`‚openchange-2.0/apidocs/html/libmapi/24px-Cc-sa_white.svg.png000066400000000000000000000053061223057412600237200ustar00rootroot00000000000000‰PNG  IHDR°çá»bKGDÿÿÿÿÿÿ X÷Ü pHYsHHFÉk> IDATXÕX}LÓW>¿ ´–.Ôb±‚" Cèê(lS„9ÉuN&n ʹŒ,+&+™“à&3[a`Ë$™ãs‰3Ö¨L(ŠX¸Åñá¬EÄ4ElK¡åyÿy÷–¼µ/¾çŸ›ÜsŸsžûœÓ{· þmô”¶ðà?¬Y3²†èBý…ú õD—7\ÞpyÑpâpâp"‘Ñh4DóÏÌ?3ÿ QPmPmP-QØoa¿…ýFw"îDÜ ¢ŒÊŒÊŒJ¢8n7ŽKäwÃï†ß§eCDxJ3›ŠMÅÀgW?»úÙU ‚‰`"€Ä bý#À>Ê>Ê> p ¸Ü€WÀ+àË3–g,Ïèú†¾q¯Ø°%` ===è&tº ÀéŠtE.Í‹ñVœÁœ!ºxçâ‹wˆ>5|jøÔ@Ô#ë‘õȈ|Ç|Ç|Lj^,z±èÅ"¢m»·íÞ¶›(Žljãùùù±x,‹G4;;K499IÔÞÚÞÚÞJÔ¾§}Oû"s‚9Áœ@$4 BQa~a~a>Ñ!Û!Û!o„7Âyš ¬Çz¬ßi|§ñ`ÕЪ¡UCnÅdý²~Y?ÐÔ×Ô×ÔLÍLÍLÍÂGø8¶ãØŽc;ÜÄãËãËãËS‘©ÈTäxÏ®ž]=»€Wv^Ùy´ Z­SÏÔ3õ‹~Ü&¶‰mÄ_‰¿ ;v( 05›šMÍžqÝÎng7P¼¶xmñZwœ—^éõ—^îõÝë»×Ð`é`é`)°áµ ¯mx Xž²äeò2y™'ñA„ B”ØJl%6 nUݪºU€*Z­ŠÄÄÄ“Ïä3€å[Ë·–o½ãq·qØkÝkÝkõl¥ÏÕŸ«?W{Â?~< $®H\‘¸Â½Þg®w®w®—ˆ³Œ³Œ³ŒˆÍÎfgQuQ—§¯È_‘¿"'Ò˜5f™Hë¯õ×úûëØ_Çþ"âïçïçïÿß.ëi=­'ò©õ©õ©õtϧϧϧ{Î3LÓAÄ–²¥l)éHG:"VPePeP%‘ƒëà:¸D³³³ÞóOØ'ìv¢Õ©«SW§åìËÙ—³È,7ËÍr"G…£ÂQá?—7—7—G4ùóäÏ“?{ú\WÀõœ_P-¨TDÖxk¼5~‘ckçÖέî’TýQõGÕÞ;à|Öù¬óY@ÀÉ€“'Þ:Þ:Þ:@œ&N§cccÞñÝ‚nA·ý$úIô“;/š?ÍŸtƒºAÝN¡¡ü¡ü¡| ¤0¤0¤pQë}RôIÑ'¯³¾ÎúpŒ9ÆO 2Z3Z3ZÄŒ9s㇓w%ïJ޴ŶŶÅwDwDwDÀÅ÷/¾ñ}`Ëw[¾Ûò'îÍóožó<`}×ú®õ]ϼgfÏÌž™XZ––¥Ö¶¯m_ÛP‡¤CÒ!$ ~ø!ÐógÏŸ=zW²V]«®Uœ:N§n¡(Š¢(À?Ê?Ê? Í Í Íxž…gñ$ê u…º€®³]g»Îzæ±UÙªlU€¼D^"/Yto¨ Ôj€ìB»Ð.ö(ö(ö(Ü ýŠ~E?`ï²wÙ»<;„¡ChÞм¡y±D,ë 7ò¬V +Ø”»)wS.pI}I}Ií]¨æèæèæhÀÏægó³Á™Á™Á™€¾J_¥¯Zô1§Óê´:- ¼"¼"¼ø}ï÷½ß÷@uJuJu àZp-¸<8wþîü0ì7ì7ìJ5¥šR ùwæß™ÛÓ·§oOÞî|»óíNà”ñ”ñ”ý–ý€~@Äì‹Ù³Ï-@qqq?° ].HmÀ5åšrMǧOŸXm¬6V°²deÉÊàtÆéŒÓ€óWç¯Î_½'F ZÐ8ßs¾ç|˜+Ÿ+Ÿ+\®W€ILbÒ;ü¦ô¦ô¦ØÜ°¹asƒ›xÒñ¤ãIÇñeãËÆ—¹×{¼   ¥F©QjV:+•ð[ø-ü@=®W÷ÎÝ;wïÜÒ„–2[Ž-Ç–4O7O7O76nlt—<”<”<zózózó<ñ^ßÄ–dK²%PVVx¾<_ž/À\b.1—I¶$[’ |Éÿ’ÿ%Ðwê;õÀdÅdÅd` ³†YÃk‹µÅÚÌlÙ:³>0|`øP¯®W׫ù«òWå¯Ü:n·`ŒŒ‘1IÂ$a’è½Ð{¡÷‚w–|Ô;ö:ö:öÍÏ7?ßü<šš øˆ}Ä>b€4¤!   P(ØÉØÉØI Q‘¨HTÉG’$d5²Y r2ädÈIÀçŸ|^p+½&nMÜš8 x x xß1¾c|ÇÒ|ê%þ±±gÇž{(¯)¯)¯âõñúx=àÃ÷áûð—>…þC*C*C*N§€èôúÀ™âLq¦<=ŸYΧюéÈ:tEXtComment Created with Inkscape (http://www.inkscape.org/) ã+ldIEND®B`‚openchange-2.0/apidocs/html/libmapi/CC_SomeRightsReserved.png000066400000000000000000000064521223057412600243350ustar00rootroot00000000000000‰PNG  IHDRZ¬a x pHYs  šœtIMEÕ ÌIðbKGDÿÿÿ ½§“ ·IDATx^í™iŒUEÇû¾{ßÚÝ6ë"²Š‚@!`˜DÇ¡Ä "Œ2 ×%Æ(ê—D£ñƒ1¨â’Œ@Pƒ¢HezXš¦é†¶~¯ßrç÷ïÜêyV¼ 1í„VòçÔz«þuêÔ¹÷9%¿Nr@$Bd\ºP¤Ç¤KˆÒ•HD€’È|² È h‘,Ò›= lœ)Ò›Íøí´2$Ù"ír«,n¤…˜Õ?À+B¸4d¤à `d‘ž—Þ†vL‘_‰h×&By#Äl ,‹OHIÚyû¤Ø°N‡¤g¡èäÒùnÑ‹0 g­Kë!í i6IÁ¶dËŠ…‚bÉFÝ?Ÿ-ÚŠ°áÙ–eÈO&“‰gŸ}vä–-[¦œ8qâŽ\.7çÌ™3Ó÷ìÙ3áý÷ß¿büøñÝdÉňÅb©Ç{lÐ÷ßÿ‡ãÇÏ ÏÜæææ¿8p`ÎòåË+§L™ÒËz– {®ƒö½´Ú?Å­cݦ[e‰â²áÇw]¶lÙ´¾}ûBfxrçfÞ_|±»bÅŠ!ƒ *ÿ}]xÍÒ’V™OŸï ¤­{–.¸Xrì“O>ù“!yûöí 7ß|óêT*õwÊÖ<óÌ3ûNž<™S]±%Óg˜!yóæÍM7ÞxãÚÒÒÒ¥lÀâW^yeÝéÓ§3ª3Ï q5nHÞÎW‹ŽXVœ ½ÄŒ/¾øâè|p¢Ø·o_ãСC¿J§Ó­‘ˆÁ€Ê>ûì³—^ziµÚÍŸ?¿âÕW_í!}çΧG޹9“ÉüÄZ9%.}*{öì¹ð,–kK»¬p>Z´‰s£[å6\ÉÊÊÊ¡f€—_~ù_±#“½{÷:|ÈlÒ­·ÞÚÁôyþùç Ù³ýð¶mÛÒ¼È ýG2$ïXh—äµ?Ñá °7£OŸ>ÝÍøéc¶»Q+êp±ú˜é³råÊûb³78¶ 1Ë@Îï8ڱɷõb²ñÑqÓøÈ‘#9Ûê‹`ÜI²¢¢¢mîÇŽioŠÉ ß\#C²†óÐu„è>ˆ„µÃU´˜L÷îÝcöÆXäy Ååè›>;wöl²Î‘<'l íî:|ßïÐ^ƒmܸÑûâ‹/R555‰£G&!#ÉÍŸjiiI€$~4‘ÍfS<3U(ù|>!YWW÷Ã%—\ÒScÜvÛm=Þyçã´ñ€ "À´a¤<²y×®]±Ñ£G»êsÓM7¥/^|š0γD"qd©)D£Ñ‚ëº>(ñ<Ï!ïÁD€KÄâ^pÁ^×®]½þýûGG»æšk²í壎hÿ—ì&t¯ºêªDÇŽSç/‰ü1Á DB„Cr²“È/ñï¾û®Ú=oÞ¼Á«V­Ú€•»l‚ ’ýnݺ9o½õVçIˆË}ùå—ˆ.UŸ‡z¨ÓºuëWsvIž€ï/ýõ×õÒò7òˆ|P"‚ãñx+ɉDB$ srª¢½{÷Ž:êtåI¿”§VKqöÆç>8dF°4Y³‡èä©S§â”'xÃK@r\0dƒ¸ÈfÑ©×^{m . \ãa_¸pa͆ 2eee¥×]w]§Ù³gwÁÚ´‘GÔF$}øá‡{õêå)_UUuúÍ7߬ٺuë:uÊOœ8±ãÔ©SB^ ‹ÿ+äf »b3œ¡:@†x= Ùiü~¦C‡é.]º¤ÙØ QN3ýE´c‘z.ût Ñã• 'ôÜwÒœC‡űæ8¯Ã²è˜ˆ†ä¸¬ZRD$Çò²êaX—ûî»od—…ÎÜ÷Kn¸á†ƒÈV]ÀêܧŸ~ºë…^;[Ÿ»îºk‘!¤A‹ò\ÂÑ­`#Óll Va61­S`Nz8ܧžzêrë±Ñ%amŠÛâE`)$¤°ž$H±¨V“ÿMqEJÒYd î¯]»¶™§Øƒÿ›P¨¯¯ÏàN¾ñÆGñë9Ú°´zvÍš5M¸™,㔀ˆéÓØØxŠ7ÌÚ?þx#d·@bIyy¹ƒŒX¯ "Pç"=ê$]¤GY4„#Ût›3ÆG;ç°3þ9„>>ĉ´$DuAZ ×!b£" –%G%!$J[å¥{HwQ © ô­KQÒEF°´¶èEV òëׯo¤_=$çØì2+ g±È,® Ɔ—°yÅ £ e¾Ñ6/ÊI?%&)’€hî£ëtt´^~ä}‘Œlõ딹ä[A>á’Q ’uZZ@–òlȧÒPÂmiÝ1”àp_ä‡í¤Êb<‘*²Ñ•$[‰ HÑ’Ê»"2% Éå!URd;"8€X³’¤A„ä—ä{$‘/QˆDIr³Áüäzb¤2«r…ƒg#ÖÒC91á]…UîôIaÖl„N^£+ŽÕÊÛˆ’Fò’&/˜ÐN1´¤±nG©Øª€acÝH§ØºE0R¹²æ"Œ/=t?´¡`.ÄšM:«±àDæÎ;ž[ÎsÏ=7’ ©O¿~ýoûh#Øåy›6mêÅGšÞ¯{T¦~Lêµ½þúë')o±^N})Ÿ9ï Þüî»ï*ÔJ¦HcÇŽ­ä¢Ià³Ëˆ›¯ tÅÇû¡„V1.¢èôéÓ/G÷„Ûo¿}0Ò%Vî?cÆŒA?üpß%K–t&Bé‡/¯Ï&JP[éJÖ¼ûþùç=xNœ‹-~íµ×þž—¡±<çwšÃK/½4Œ²Ê÷Þ{oëÓúèÞξ¥s eKu¤¦M›¶öJW;AþLõÒ L×°Œpn¹üŸ1WCBšèá«Ã‡¯¡,W]]ý-ñmý#zTܨêŠ]ª)ã›ù)Þ./“.‹Þüõ×_ïâm*Ë—³²œÊ£ó Ü|°wÑ¢E²¦¶zŽHžÎ°ÓÊÛàRÛ*ÿ©yŽì¼*^`ªd‘¼Ììfü<ñî>\×q^:²lÈA¬þ ãØ"H¯­­=Ì‹Pý ’K—.=¦·?Œ¢^yÕ ¤Z¾›R‘Ìiiâ µ«Ý¯2æšÁ5œàÌ.>­V3FÒªpaÛ5Oꛃµl1ëÓéxüñÇkUÆÿ’UãÆ;‰;Ép¯l ã@ÙŠèý úÉ'Ÿlš5kÖIÞós¼Å€”ê=zäT/BL;£•W Ê[¨D*ǹŽ;@ãÖæRúa&œƒ˜zȯg¬ßEØ€£ÒqeÇ8ÒÒ% I—ظ33gÎLKW½ú©þ»‰gæÉ7˜ñ±ò:=bk™GíO%ƒŽñ}CãÙQQ mEõLŽzÏÌ«LÏ4m!ÚçBup›)½ä´­Å¬¿ÃÊÇá.è7±ÏÅáCŒÏDýÝ»wûJøÈVië,ºµíœ9s|;Ùí¹©}.Ÿ”aŒ>dû,ÆçHZ}Btk¾çöL{®öv}ø8Òq¡¡˜²!C†ø&Lðq]¾DÿÊé7üFôÿÿj|w‚%&IEND®B`‚openchange-2.0/apidocs/html/libmapi/FXICS_8c.html000066400000000000000000001731441223057412600216350ustar00rootroot00000000000000 MAPIClientLibraries 2.0 API Documentation
FXICS.c File Reference

Fast Transfer and Incremental Change Synchronization operations. More...

#include "libmapi/libmapi.h"
#include "libmapi/libmapi_private.h"

Functions

_PUBLIC_ enum MAPISTATUS FXCopyFolder (mapi_object_t *obj, uint8_t copyFlags, uint8_t sendOptions, mapi_object_t *obj_source_context)
_PUBLIC_ enum MAPISTATUS FXCopyMessages (mapi_object_t *obj, mapi_id_array_t *message_ids, uint8_t copyFlags, uint8_t sendOptions, mapi_object_t *obj_source_context)
_PUBLIC_ enum MAPISTATUS FXCopyProperties (mapi_object_t *obj, uint8_t level, uint32_t copyFlags, uint8_t sendOptions, struct SPropTagArray *properties, mapi_object_t *obj_source_context)
_PUBLIC_ enum MAPISTATUS FXCopyTo (mapi_object_t *obj, uint8_t level, uint32_t copyFlags, uint8_t sendOptions, struct SPropTagArray *excludes, mapi_object_t *obj_source_context)
_PUBLIC_ enum MAPISTATUS FXDestConfigure (mapi_object_t *obj, enum FastTransferDestConfig_SourceOperation sourceOperation, mapi_object_t *obj_destination_context)
_PUBLIC_ enum MAPISTATUS FXGetBuffer (mapi_object_t *obj_source_context, uint16_t maxSize, enum TransferStatus *transferStatus, uint16_t *progressStepCount, uint16_t *totalStepCount, DATA_BLOB *blob)
 Get data from source fast transfer object.
_PUBLIC_ enum MAPISTATUS FXPutBuffer (mapi_object_t *obj_dest_context, DATA_BLOB *blob, uint16_t *usedSize)
 Send data to a destination fast transfer object.
_PUBLIC_ enum MAPISTATUS GetLocalReplicaIds (mapi_object_t *obj_store, uint32_t IdCount, struct GUID *ReplGuid, uint8_t GlobalCount[6])
_PUBLIC_ enum MAPISTATUS ICSSyncConfigure (mapi_object_t *obj, enum SynchronizationType sync_type, uint8_t send_options, uint16_t sync_flags, uint32_t sync_extraflags, DATA_BLOB restriction, struct SPropTagArray *property_tags, mapi_object_t *obj_sync_context)
_PUBLIC_ enum MAPISTATUS ICSSyncGetTransferState (mapi_object_t *obj, mapi_object_t *obj_sync_context)
_PUBLIC_ enum MAPISTATUS ICSSyncOpenCollector (mapi_object_t *folder, bool isContentsCollector, mapi_object_t *obj_collector)
_PUBLIC_ enum MAPISTATUS ICSSyncUploadStateBegin (mapi_object_t *obj_sync_context, enum StateProperty state_property, uint32_t length)
 Initialize an ICS Initial State upload.
_PUBLIC_ enum MAPISTATUS ICSSyncUploadStateContinue (mapi_object_t *obj_sync_context, DATA_BLOB state)
 Send data for an ICS Initial State upload.
_PUBLIC_ enum MAPISTATUS ICSSyncUploadStateEnd (mapi_object_t *obj_sync_context)
 Signal completion of an ICS Initial State upload.
_PUBLIC_ enum MAPISTATUS SetLocalReplicaMidsetDeleted (mapi_object_t *obj_folder, const struct GUID ReplGuid, const uint8_t GlobalCountLow[6], const uint8_t GlobalCountHigh[6])
_PUBLIC_ enum MAPISTATUS TellVersion (mapi_object_t *obj_store, uint16_t version[3])

Detailed Description

Fast Transfer and Incremental Change Synchronization operations.

Function Documentation

_PUBLIC_ enum MAPISTATUS FXCopyFolder ( mapi_object_t *  obj,
uint8_t  copyFlags,
uint8_t  sendOptions,
mapi_object_t *  obj_source_context 
)

Prepare a server for Fast Transfer transmission of a folder hierachy

This function is used to configure a server for a fast-transfer folder hierachy send operation. This could be the origin server in a server->client->server copy, or for a server to client download.

This operation copies the folder object, and any sub-objects (including folder properties and messages). It can optionally copy sub-folders, depending on copyFlags.

Parameters
objthe source object for the operation (folder)
copyFlagsflags that change the copy behaviour (see below)
sendOptionsflags that change the format of the transfer (see FXCopyMessages)
obj_source_contextthe fast transfer source context for future ROPs

copyflags can be zero or more of the following:

  • FastTransferCopyFolder_CopySubfolders to recursively copy any sub-folders and contained messages
  • FastTransferCopyFolder_NoGhostedContent to omit any ghosted content when copying public folders
Returns
MAPI_E_SUCCESS on success, otherwise MAPI error.
Note
Developers may also call GetLastError() to retrieve the last MAPI error code. Possible MAPI error codes are:
  • MAPI_E_NOT_INITIALIZED: MAPI subsystem has not been initialized
  • MAPI_E_INVALID_PARAMETER: one of the function parameters is invalid
  • MAPI_E_CALL_FAILED: A network problem was encountered during the transaction

References mapi_object_get_handle(), mapi_object_get_logon_id(), mapi_object_get_session(), mapi_object_set_handle(), mapi_object_set_logon_id(), and mapi_object_set_session().

_PUBLIC_ enum MAPISTATUS FXCopyMessages ( mapi_object_t *  obj,
mapi_id_array_t *  message_ids,
uint8_t  copyFlags,
uint8_t  sendOptions,
mapi_object_t *  obj_source_context 
)

Prepare a server for Fast Transfer transmission of a list of messages

This function is used to configure a server for a fast-transfer message send operation. This could be the origin server in a server->client->server copy, or for a server to client download.

This operation copies the message objects, and any sub-objects (including attachments and embedded messages).

Parameters
objthe source object for the operation (folder)
message_idsthe message IDs for the messages to copy.
copyFlagsflags that change the copy behaviour (see below)
sendOptionsflags that change the format of the transfer (see below)
obj_source_contextthe fast transfer source context for future ROPs

copyflags can be zero or more of the following:

  • FastTransferCopyMessage_Move - configure output for move
  • FastTransferCopyMessage_BestBody - output message bodies in original format (if not set, output in RTF)
  • FastTransferCopyMessage_SendEntryId - include message and change identification in the output stream

sendOptions can be zero or more of the following:

  • FastTransfer_Unicode - enable Unicode output
  • FastTransfer_UseCpid (not normally used directly - implied by ForUpload)
  • FastTransfer_ForUpload - (enable Unicode, and advise the server that transfer is server->client->server)
  • FastTransfer_RecoverMode - advise the server that the client supports recovery mode
  • FastTransfer_ForceUnicode - force Unicode output
  • FastTransfer_PartialItem - used for synchronisation download

If the FastTransfer_ForUpload is set, the next call must be TellVersion()

Returns
MAPI_E_SUCCESS on success, otherwise MAPI error.
Note
Developers may also call GetLastError() to retrieve the last MAPI error code. Possible MAPI error codes are:
  • MAPI_E_NOT_INITIALIZED: MAPI subsystem has not been initialized
  • MAPI_E_INVALID_PARAMETER: one of the function parameters is invalid
  • MAPI_E_CALL_FAILED: A network problem was encountered during the transaction

References mapi_id_array_get(), mapi_object_get_handle(), mapi_object_get_logon_id(), mapi_object_get_session(), mapi_object_set_handle(), mapi_object_set_logon_id(), and mapi_object_set_session().

_PUBLIC_ enum MAPISTATUS FXCopyProperties ( mapi_object_t *  obj,
uint8_t  level,
uint32_t  copyFlags,
uint8_t  sendOptions,
struct SPropTagArray *  properties,
mapi_object_t *  obj_source_context 
)

Prepare a server for Fast Transfer transmission of the properties of a folder, message or attachment

This function is used to configure a server for a fast-transfer download of properties. This could be the origin server in a server->client->server copy, or for a server to client download.

This operation copies the specified properties of the source object. It can optionally copy properties of sub-objects, depending on Level.

Parameters
objthe source object for the operation (folder, message or attachment)
levelwhether to copy properties of sub-objects of folders or messages (set to 0) or not (set to any other value)
copyFlagsflags that change the copy behaviour (see below)
sendOptionsflags that change the format of the transfer (see FXCopyMessages)
propertiesthe list of properties to transfer
obj_source_contextthe fast transfer source context for future ROPs

copyflags may be the following:

  • FastTransferCopyProperties_Move to configure as part of a move operation

Be careful in setting level to something other than zero. In particular, if level is non-zero for a message, then the list of recipients, and any attachments or embedded messages, will not be transferred.

Returns
MAPI_E_SUCCESS on success, otherwise MAPI error.
Note
Developers may also call GetLastError() to retrieve the last MAPI error code. Possible MAPI error codes are:
  • MAPI_E_NOT_INITIALIZED: MAPI subsystem has not been initialized
  • MAPI_E_INVALID_PARAMETER: one of the function parameters is invalid
  • MAPI_E_CALL_FAILED: A network problem was encountered during the transaction

References mapi_object_get_handle(), mapi_object_get_logon_id(), mapi_object_get_session(), mapi_object_set_handle(), mapi_object_set_logon_id(), and mapi_object_set_session().

_PUBLIC_ enum MAPISTATUS FXCopyTo ( mapi_object_t *  obj,
uint8_t  level,
uint32_t  copyFlags,
uint8_t  sendOptions,
struct SPropTagArray *  excludes,
mapi_object_t *  obj_source_context 
)

Prepare a server for Fast Transfer transmission of a folder, message or attachment

This function is used to configure a server for a fast-transfer download of a folder, message or attachment. This could be the origin server in a server->client->server copy, or for a server to client download.

This operation copies the source object, potentially omitting some properties. It can optionally copy sub-objects, depending on Level.

Parameters
objthe source object for the operation (folder, message or attachment)
levelwhether to copy sub-objects of folders or messages (set to 0) or not (set to any other value)
copyFlagsflags that change the copy behaviour (see below)
sendOptionsflags that change the format of the transfer (see FXCopyMessages)
excludesthe list of properties to exclude from the transfer
obj_source_contextthe fast transfer source context for future ROPs

copyflags can be zero or more of the following:

  • FastTransferCopyTo_Move to configure as part of a move operation
  • FastTransferCopyTo_BestBody to use original format for message bodies (if not set, use RTF instead)

Be careful in setting level to something other than zero. In particular, if level is non-zero for a message, then the list of recipients, and any attachments or embedded messages, will not be transferred.

Returns
MAPI_E_SUCCESS on success, otherwise MAPI error.
Note
Developers may also call GetLastError() to retrieve the last MAPI error code. Possible MAPI error codes are:
  • MAPI_E_NOT_INITIALIZED: MAPI subsystem has not been initialized
  • MAPI_E_INVALID_PARAMETER: one of the function parameters is invalid
  • MAPI_E_CALL_FAILED: A network problem was encountered during the transaction

References mapi_object_get_handle(), mapi_object_get_logon_id(), mapi_object_get_session(), mapi_object_set_handle(), mapi_object_set_logon_id(), and mapi_object_set_session().

_PUBLIC_ enum MAPISTATUS FXDestConfigure ( mapi_object_t *  obj,
enum FastTransferDestConfig_SourceOperation  sourceOperation,
mapi_object_t *  obj_destination_context 
)

Prepare a server for Fast Transfer receive

This function is used to configure a server for fast-transfer receive operation. This could be the target server in a server->client->server copy, or for a client->server upload.

Parameters
objthe target object for the upload (folder, message or attachment)
sourceOperationthe type of transfer (one of FastTransferDest_CopyTo, FastTransferDest_CopyProperties,FastTransferDest_CopyMessages or FastTransferDest_CopyFolder)
obj_destination_contextthe fast transfer context for future ROPs.
Returns
MAPI_E_SUCCESS on success, otherwise MAPI error.
Note
Developers may also call GetLastError() to retrieve the last MAPI error code. Possible MAPI error codes are:
  • MAPI_E_NOT_INITIALIZED: MAPI subsystem has not been initialized
  • MAPI_E_INVALID_PARAMETER: one of the function parameters is invalid
  • MAPI_E_CALL_FAILED: A network problem was encountered during the transaction

References mapi_object_get_handle(), mapi_object_get_logon_id(), mapi_object_get_session(), mapi_object_set_handle(), mapi_object_set_logon_id(), and mapi_object_set_session().

_PUBLIC_ enum MAPISTATUS FXGetBuffer ( mapi_object_t *  obj_source_context,
uint16_t  maxSize,
enum TransferStatus *  transferStatus,
uint16_t *  progressStepCount,
uint16_t *  totalStepCount,
DATA_BLOB *  blob 
)

Get data from source fast transfer object.

Fast transfers are done in blocks, each block transfered over a call to FXGetBuffer. If the block is small, it will fit into a single call, and the transferStatus will indicate completion. However larger transfers will require multiple calls.

Parameters
obj_source_contextthe source object (from FXCopyTo, FXCopyProperties, FXCopyFolder or FXCopyMessages)
maxSizethe maximum size (pass 0 to indicate maximum available size)
transferStatusresult of the transfer
progressStepCountthe approximate number of steps (of totalStepCount) completed
totalStepCountthe approximate number of steps (total)
blobthis part of the transfer
Returns
MAPI_E_SUCCESS on success, otherwise MAPI error.
Note
Developers may also call GetLastError() to retrieve the last MAPI error code. Possible MAPI error codes are:
  • MAPI_E_NOT_INITIALIZED: MAPI subsystem has not been initialized
  • MAPI_E_INVALID_PARAMETER: one of the function parameters is invalid
  • MAPI_E_CALL_FAILED: A network problem was encountered during the transaction

References mapi_object_get_handle(), mapi_object_get_logon_id(), and mapi_object_get_session().

_PUBLIC_ enum MAPISTATUS FXPutBuffer ( mapi_object_t *  obj_dest_context,
DATA_BLOB *  blob,
uint16_t *  usedSize 
)

Send data to a destination fast transfer object.

Fast transfers are done in blocks, each block transfered over a call to FXGetBuffer. If the block is small, it will fit into a single call, and the transferStatus will indicate completion. However larger transfers will require multiple calls.

Parameters
obj_dest_contextthe destination object (from FXDestConfigure)
blobthis part of the transfer
usedSizehow many bytes of this part of the transfer that were used (only less than the total if an error occurred)
Returns
MAPI_E_SUCCESS on success, otherwise MAPI error.
Note
Developers may also call GetLastError() to retrieve the last MAPI error code. Possible MAPI error codes are:
  • MAPI_E_NOT_INITIALIZED: MAPI subsystem has not been initialized
  • MAPI_E_INVALID_PARAMETER: one of the function parameters is invalid
  • MAPI_E_CALL_FAILED: A network problem was encountered during the transaction

References mapi_object_get_handle(), mapi_object_get_logon_id(), and mapi_object_get_session().

_PUBLIC_ enum MAPISTATUS GetLocalReplicaIds ( mapi_object_t *  obj_store,
uint32_t  IdCount,
struct GUID *  ReplGuid,
uint8_t  GlobalCount[6] 
)

Reserves a range of IDs to be used by a local replica

Parameters
obj_storepointer on the store MAPI object
IdCountID range length to reserve
ReplGuidpointer to the GUID structure returned by the server
GlobalCountbyte array that specifies the first allocated field
Returns
MAPI_E_SUCCESS on success, otherwise MAPI error.
Note
Developers may also call GetLastError() to retrieve the last MAPI error code. Possible MAPI error codes are:
  • MAPI_E_NOT_INITIALIZED: MAPI subsystem has not been initialized
  • MAPI_E_INVALID_PARAMETER: one of the function parameters is invalid
  • MAPI_E_CALL_FAILED: A network problem was encountered during the transaction

References mapi_object_get_handle(), mapi_object_get_logon_id(), and mapi_object_get_session().

_PUBLIC_ enum MAPISTATUS ICSSyncConfigure ( mapi_object_t *  obj,
enum SynchronizationType  sync_type,
uint8_t  send_options,
uint16_t  sync_flags,
uint32_t  sync_extraflags,
DATA_BLOB  restriction,
struct SPropTagArray *  property_tags,
mapi_object_t *  obj_sync_context 
)

Prepare a server for ICS download

This function is used to configure a server for ICS (Incremental Change Synchronization) download. You use the synchronization context handle for other ICS and Fast Transfer operations.

Parameters
objthe target object for the upload (folder)
sync_typethe type of synchronization that will be performed (just folder contents, or whole folder hierachy)
send_optionsflags that change the format of the transfer (see FXCopyMessages)
sync_flagsflags that change the behavior of the transfer (see below)
sync_extraflagsadditional flags that change the behavior of the transfer (see below)
restrictiona Restriction structure to limit downloads (only for sync_type == SynchronizationType_Content)
property_tagsthe properties to exclude (or include, if SynchronizationFlag_OnlySpecifiedProperties flag is set) in the download
obj_sync_contextthe resulting synchronization context handle

sync_flags can be zero or more of the following:

  • SynchronizationFlag_Unicode to use Unicode format (must match in send_options)
  • SynchronizationFlag_NoDeletions - whether to download changes about message deletion
  • SynchronizationFlag_IgnoreNoLongerInScope - whether to download changes for messages that have gone out of scope.
  • SynchronizationFlag_ReadState - server to download changes to read state
  • SynchronizationFlag_FAI server to download changes to FAI messages
  • SynchronizationFlag_Normal - server to download changes to normal messages
  • SynchronizationFlag_OnlySpecifiedProperties - set means to include only properties that are listed in property_tags, not-set means to exclude properties that are listed in property_tags
  • SynchronizationFlag_NoForeignIdentifiers - ignore persisted values (usually want this set)
  • SynchronizationFlag_BestBody - format for outputting message bodies (set means original format, not-set means output in RTF)
  • SynchronizationFlag_IgnoreSpecifiedOnFAI - ignore property_tags restrictions for FAI messages
  • SynchronizationFlag_Progress - whether to output progress information.
Note
SynchronizationFlag_IgnoreNoLongerInScope, SynchronizationFlag_ReadState, SynchronizationFlag_FAI, SynchronizationFlag_Normal, SynchronizationFlag_OnlySpecifiedProperties, SynchronizationFlag_BestBody and SynchronizationFlag_IgnoreSpecifiedOnFAI are only valid if the synchronization type is SynchronizationType_Content.

sync_extraflags can be zero or more of the following:

  • SynchronizationExtraFlag_Eid - whether the server includes the PR_FID / PR_MID in the download
  • SynchronizationExtraFlag_MessageSize - whether the server includes the PR_MESSAGE_SIZE property in the download (only for sync_type == SynchronizationType_Content)
  • SynchronizationExtraFlag_Cn - whether the server includes the PR_CHANGE_NUM property in the download.
  • SynchronizationExtraFlag_OrderByDeliveryTime - whether the server sends messages sorted by delivery time (only for sync_type == SynchronizationType_Content)
Returns
MAPI_E_SUCCESS on success, otherwise MAPI error.
Note
Developers may also call GetLastError() to retrieve the last MAPI error code. Possible MAPI error codes are:
  • MAPI_E_NOT_INITIALIZED: MAPI subsystem has not been initialized
  • MAPI_E_INVALID_PARAMETER: one of the function parameters is invalid
  • MAPI_E_CALL_FAILED: A network problem was encountered during the transaction

References mapi_object_get_handle(), mapi_object_get_logon_id(), mapi_object_get_session(), mapi_object_set_handle(), mapi_object_set_logon_id(), and mapi_object_set_session().

_PUBLIC_ enum MAPISTATUS ICSSyncGetTransferState ( mapi_object_t *  obj,
mapi_object_t *  obj_sync_context 
)

obtain an object to get the sync transfer state

Parameters
objthe source object
obj_sync_contextthe synchronization transfer state object
Returns
MAPI_E_SUCCESS on success, otherwise MAPI error.
Note
Developers may also call GetLastError() to retrieve the last MAPI error code. Possible MAPI error codes are:
  • MAPI_E_NOT_INITIALIZED: MAPI subsystem has not been initialized
  • MAPI_E_INVALID_PARAMETER: one of the function parameters is invalid
  • MAPI_E_CALL_FAILED: A network problem was encountered during the transaction

References mapi_object_get_handle(), mapi_object_get_logon_id(), mapi_object_get_session(), mapi_object_set_handle(), mapi_object_set_logon_id(), and mapi_object_set_session().

_PUBLIC_ enum MAPISTATUS ICSSyncOpenCollector ( mapi_object_t *  folder,
bool  isContentsCollector,
mapi_object_t *  obj_collector 
)

Prepare a folder for ICS upload

Parameters
folderthe folder for the collector creation
isContentsCollectortrue for contents collector, false for hierachy collector
obj_collectorpointer to the resulting ICS collector
Returns
MAPI_E_SUCCESS on success, otherwise MAPI error.
Note
Developers may also call GetLastError() to retrieve the last MAPI error code. Possible MAPI error codes are:
  • MAPI_E_NOT_INITIALIZED: MAPI subsystem has not been initialized
  • MAPI_E_INVALID_PARAMETER: one of the function parameters is invalid
  • MAPI_E_CALL_FAILED: A network problem was encountered during the transaction

References mapi_object_get_handle(), mapi_object_get_logon_id(), mapi_object_get_session(), mapi_object_set_handle(), mapi_object_set_logon_id(), and mapi_object_set_session().

_PUBLIC_ enum MAPISTATUS ICSSyncUploadStateBegin ( mapi_object_t *  obj_sync_context,
enum StateProperty  state_property,
uint32_t  length 
)

Initialize an ICS Initial State upload.

This is one of three operations (along with ICSSyncUploadStateContinue and ICSSyncUploadStateEnd) used to send the initial state for an ICS download to the server.

Parameters
obj_sync_contextthe synchronization context (from ICSSyncConfigure)
state_propertythe type of ICS state that will be uploaded (see below)
lengththe length (in bytes) of the ICS state that will be uploaded

state_property can be one of the following:

  • PidTagIdsetGiven
  • PidTagCnsetSeen
  • PidTagCnsetSeenFAI
  • PidTagCnsetRead
Returns
MAPI_E_SUCCESS on success, otherwise MAPI error.
Note
Developers may also call GetLastError() to retrieve the last MAPI error code. Possible MAPI error codes are:
  • MAPI_E_NOT_INITIALIZED: MAPI subsystem has not been initialized
  • MAPI_E_INVALID_PARAMETER: one of the function parameters is invalid
  • MAPI_E_CALL_FAILED: A network problem was encountered during the transaction

References mapi_object_get_handle(), mapi_object_get_logon_id(), and mapi_object_get_session().

_PUBLIC_ enum MAPISTATUS ICSSyncUploadStateContinue ( mapi_object_t *  obj_sync_context,
DATA_BLOB  state 
)

Send data for an ICS Initial State upload.

This is one of three operations (along with ICSSyncUploadStateBegin and ICSSyncUploadStateEnd) used to send the initial state for an ICS download to the server.

Parameters
obj_sync_contextthe synchronization context (from ICSSyncConfigure)
statethe state data for this part of the upload
Returns
MAPI_E_SUCCESS on success, otherwise MAPI error.
Note
Developers may also call GetLastError() to retrieve the last MAPI error code. Possible MAPI error codes are:
  • MAPI_E_NOT_INITIALIZED: MAPI subsystem has not been initialized
  • MAPI_E_INVALID_PARAMETER: one of the function parameters is invalid
  • MAPI_E_CALL_FAILED: A network problem was encountered during the transaction

References mapi_object_get_handle(), mapi_object_get_logon_id(), and mapi_object_get_session().

_PUBLIC_ enum MAPISTATUS ICSSyncUploadStateEnd ( mapi_object_t *  obj_sync_context)

Signal completion of an ICS Initial State upload.

This is one of three operations (along with ICSSyncUploadStateBegin and ICSSyncUploadStateContinue) used to send the initial state for an ICS download to the server.

Parameters
obj_sync_contextthe synchronization context (from ICSSyncConfigure)
Returns
MAPI_E_SUCCESS on success, otherwise MAPI error.
Note
Developers may also call GetLastError() to retrieve the last MAPI error code. Possible MAPI error codes are:
  • MAPI_E_NOT_INITIALIZED: MAPI subsystem has not been initialized
  • MAPI_E_INVALID_PARAMETER: one of the function parameters is invalid
  • MAPI_E_CALL_FAILED: A network problem was encountered during the transaction

References mapi_object_get_handle(), mapi_object_get_logon_id(), and mapi_object_get_session().

_PUBLIC_ enum MAPISTATUS SetLocalReplicaMidsetDeleted ( mapi_object_t *  obj_folder,
const struct GUID  ReplGuid,
const uint8_t  GlobalCountLow[6],
const uint8_t  GlobalCountHigh[6] 
)

Mark a range of Message Ids as deleted / unused

This function allows the client to specify that a specific range of message identifiers will never be used on a particular folder. This allows the server to make optimisations for message identifier sets during incremental change synchronisation operations.

Parameters
obj_folderpointer to the folder MAPI object
ReplGuidthe GUID for the MIDSET
GlobalCountLowlower end of the range to be marked as deleted
GlobalCountHighupper end of the range to be marked as deleted
Returns
MAPI_E_SUCCESS on success, otherwise MAPI error.
Note
Developers may also call GetLastError() to retrieve the last MAPI error code. Possible MAPI error codes are:
  • MAPI_E_NOT_INITIALIZED: MAPI subsystem has not been initialized
  • MAPI_E_INVALID_PARAMETER: one of the function parameters is invalid
  • MAPI_E_CALL_FAILED: A network problem was encountered during the transaction

References mapi_object_get_handle(), mapi_object_get_logon_id(), and mapi_object_get_session().

_PUBLIC_ enum MAPISTATUS TellVersion ( mapi_object_t *  obj_store,
uint16_t  version[3] 
)

Advise a server of the "other server" version

This function is used to set up a fast server-client-server transfer.

Parameters
obj_storepointer to the store MAPI object
versionthe server version
Returns
MAPI_E_SUCCESS on success, otherwise MAPI error.
Note
Developers may also call GetLastError() to retrieve the last MAPI error code. Possible MAPI error codes are:
  • MAPI_E_NOT_INITIALIZED: MAPI subsystem has not been initialized
  • MAPI_E_INVALID_PARAMETER: one of the function parameter is invalid
  • MAPI_E_CALL_FAILED: A network problem was encountered during the transaction

References mapi_object_get_handle(), mapi_object_get_logon_id(), and mapi_object_get_session().


Creative Commons License
Creative Commons Attribution icon Creative Commons Share Alike icon
This content is licensed under the Creative Commons
Attribution ShareAlike License v. 3.0:
http://creativecommons.org/licenses/by-sa/3.0/

openchange-2.0/apidocs/html/libmapi/IABContainer_8c.html000066400000000000000000000451031223057412600232100ustar00rootroot00000000000000 MAPIClientLibraries 2.0 API Documentation
IABContainer.c File Reference

Provides access to address book containers – Used to perform name resolution. More...

#include "libmapi/libmapi.h"
#include "libmapi/libmapi_private.h"

Functions

_PUBLIC_ enum MAPISTATUS GetABRecipientInfo (struct mapi_session *session, const char *username, struct SPropTagArray *pPropTags, struct PropertyRowSet_r **ppRowSet)
_PUBLIC_ enum MAPISTATUS GetGALTable (struct mapi_session *session, struct SPropTagArray *SPropTagArray, struct PropertyRowSet_r **rowsetp, uint32_t count, uint8_t ulFlags)
_PUBLIC_ enum MAPISTATUS GetGALTableCount (struct mapi_session *session, uint32_t *totalRecs)
_PUBLIC_ enum MAPISTATUS ResolveNames (struct mapi_session *session, const char **usernames, struct SPropTagArray *props, struct PropertyRowSet_r **rowset, struct PropertyTagArray_r **flaglist, uint32_t flags)

Detailed Description

Provides access to address book containers – Used to perform name resolution.

Function Documentation

_PUBLIC_ enum MAPISTATUS GetABRecipientInfo ( struct mapi_session *  session,
const char *  username,
struct SPropTagArray *  pPropTags,
struct PropertyRowSet_r **  ppRowSet 
)

Retrieve Address Book information for a given recipient

Parameters
sessionpointer to the MAPI session context
usernamepointer to the username to retrieve information from
pPropTagspointer to the property tags array to lookup
ppRowSetpointer on pointer to the results

Note that if pPropTags is NULL, then GetABNameInfo will fetch the following default property tags:

  1. PR_ADDRTYPE_UNICODE
  2. PR_EMAIL_ADDRESS_UNICODE
  3. PR_DISPLAY_NAME_UNICODE
  4. PR_OBJECT_TYPE
Returns
MAPI_E_SUCCESS on success, otherwise MAPI error.
Note
Developers may also call GetLastError() to retrieve the last MAPI error code. Possible MAPI error codes are:
  1. MAPI_E_NOT_INITIALIZED if MAPI subsystem is not initialized
  2. MAPI_E_SESSION_LIMIT if the NSPI session is unavailable
  3. MAPI_E_INVALID_PARAMETER if a function parameter is invalid
  4. MAPI_E_NOT_FOUND if the username to lookup doesn't match any records
See Also
nspi_DNToMId, nspi_GetProps

References MAPIFreeBuffer(), nspi_DNToMId(), nspi_GetProps(), ResolveNames(), and set_SPropTagArray().

Referenced by GetUserFreeBusyData().

_PUBLIC_ enum MAPISTATUS GetGALTable ( struct mapi_session *  session,
struct SPropTagArray *  SPropTagArray,
struct PropertyRowSet_r **  rowsetp,
uint32_t  count,
uint8_t  ulFlags 
)

Retrieve the global address list

The Global Address List is the full list of email addresses (and other account-type things, such as "rooms" and distribution lists) accessible on the server. A user will usually have access to both a personal address book, and to the Global Address List. Public Address Book is another name for Global Address List.

You access the Global Address List by setting the list of things that you want to retrieve from the Global Address List as property names in the SPropTagArray argument, and then calling this function. The results are returned in SRowSet.

You can get a convenient output of the results using mapidump_PAB_entry() for each row returned.

Parameters
sessionpointer to the MAPI session context
SPropTagArraypointer to an array of MAPI properties we want to fetch
SRowSetpointer to the rows of the table returned
countthe number of rows we want to fetch
ulFlagsspecify the table cursor location

Possible value for ulFlags:

  1. TABLE_START: Fetch rows from the beginning of the table
  2. TABLE_CUR: Fetch rows from current table location

The Global Address List may be quite large (tens of thousands of entries in a large deployment), so you usually call this function with ulFlags set to TABLE_START the first time, and then subsequent calls will be made with TABLE_CUR to progress through the table.

Returns
MAPI_E_SUCCESS on success, otherwise MAPI error.
Note
Developers may also call GetLastError() to retrieve the last MAPI error code. Possible MAPI error codes are:
  1. MAPI_E_NOT_INITIALIZED: MAPI subsystem has not been initialized
  2. MAPI_E_SESSION_LIMIT: No session has been opened on the provider
  3. MAPI_E_INVALID_PARAMETER: if a function parameter is invalid
  4. MAPI_E_CALL_FAILED: A network problem was encountered during the transaction
See Also
MapiLogonEx, MapiLogonProvider, mapidump_PAB_entry

References nspi_QueryRows().

_PUBLIC_ enum MAPISTATUS GetGALTableCount ( struct mapi_session *  session,
uint32_t *  totalRecs 
)

Retrieve the total number of records in the global address list

The Global Address List is the full list of email addresses (and other account-type things, such as "rooms" and distribution lists) accessible on the server. A user will usually have access to both a personal address book, and to the Global Address List. Public Address Book is another name for Global Address List.

Parameters
sessionpointer to the MAPI session context
totalRecspointers to the total number of records in the global address list returned
Returns
MAPI_E_SUCCESS on success, otherwise MAPI error.
Note
Developers may also call GetLastError() to retrieve the last MAPI error code. Possible MAPI error codes are:
  1. MAPI_E_NOT_INITIALIZED: MAPI subsystem has not been initialized
  2. MAPI_E_SESSION_LIMIT: No session has been opened on the provider
  3. MAPI_E_INVALID_PARAMETER: if a function parameter is invalid
  4. MAPI_E_CALL_FAILED: A network problem was encountered during the transaction

References nspi_QueryRows().

_PUBLIC_ enum MAPISTATUS ResolveNames ( struct mapi_session *  session,
const char **  usernames,
struct SPropTagArray *  props,
struct PropertyRowSet_r **  rowset,
struct PropertyTagArray_r **  flaglist,
uint32_t  flags 
)

Resolve user names against the Windows Address Book Provider

Parameters
sessionpointer to the MAPI session context
usernameslist of user names to resolve
rowsetresulting list of user details
propsresulting list of resolved names
flaglistresulting list of resolution status (see below)
flagsif set to MAPI_UNICODE then UNICODE MAPITAGS can be used, otherwise only UTF8 encoded fields may be returned.

Possible flaglist values are:

  1. MAPI_UNRESOLVED: could not be resolved
  2. MAPI_AMBIGUOUS: resolution match more than one entry
  3. MAPI_RESOLVED: resolution matched a single entry
Returns
MAPI_E_SUCCESS on success, otherwise MAPI error.
Note
Developers may also call GetLastError() to retrieve the last MAPI error code. Possible MAPI error codes are:
  1. MAPI_E_NOT_INITIALIZED: MAPI subsystem has not been initialized
  2. MAPI_E_SESSION_LIMIT: No session has been opened on the provider
  3. MAPI_E_NOT_ENOUGH_RESOURCES: MAPI subsystem failed to allocate the necessary resources to operate properly
  4. MAPI_E_NOT_FOUND: No suitable profile database was found in the path pointed by profiledb
  5. MAPI_E_CALL_FAILED: A network problem was encountered during the transaction

    It is the developer responsibility to call MAPIFreeBuffer on rowset and flaglist once they have finished to use them.

See Also
MAPILogonProvider, GetLastError

References nspi_ResolveNames(), and nspi_ResolveNamesW().

Referenced by AddUserPermission(), GetABRecipientInfo(), ModifyUserPermission(), and RemoveUserPermission().


Creative Commons License
Creative Commons Attribution icon Creative Commons Share Alike icon
This content is licensed under the Creative Commons
Attribution ShareAlike License v. 3.0:
http://creativecommons.org/licenses/by-sa/3.0/

openchange-2.0/apidocs/html/libmapi/IMAPIContainer_8c.html000066400000000000000000000772071223057412600234660ustar00rootroot00000000000000 MAPIClientLibraries 2.0 API Documentation
IMAPIContainer.c File Reference

Containers and tables related operations. More...

#include "libmapi/libmapi.h"
#include "libmapi/libmapi_private.h"

Functions

_PUBLIC_ enum MAPISTATUS GetContentsTable (mapi_object_t *obj_container, mapi_object_t *obj_table, uint8_t TableFlags, uint32_t *RowCount)
_PUBLIC_ enum MAPISTATUS GetHierarchyTable (mapi_object_t *obj_container, mapi_object_t *obj_table, uint8_t TableFlags, uint32_t *RowCount)
_PUBLIC_ enum MAPISTATUS GetPermissionsTable (mapi_object_t *obj_container, uint8_t flags, mapi_object_t *obj_table)
_PUBLIC_ enum MAPISTATUS GetRulesTable (mapi_object_t *obj_folder, mapi_object_t *obj_table, uint8_t TableFlags)
_PUBLIC_ enum MAPISTATUS GetSearchCriteria (mapi_object_t *obj_container, struct mapi_SRestriction *res, uint32_t *SearchFlags, uint16_t *FolderIdCount, uint64_t **FolderIds)
_PUBLIC_ enum MAPISTATUS ModifyPermissions (mapi_object_t *obj_table, uint8_t flags, struct mapi_PermissionsData *permsdata)
_PUBLIC_ enum MAPISTATUS SetSearchCriteria (mapi_object_t *obj_container, struct mapi_SRestriction *res, uint32_t SearchFlags, mapi_id_array_t *lpContainerList)

Detailed Description

Containers and tables related operations.

Function Documentation

_PUBLIC_ enum MAPISTATUS GetContentsTable ( mapi_object_t *  obj_container,
mapi_object_t *  obj_table,
uint8_t  TableFlags,
uint32_t *  RowCount 
)

Returns a pointer to a container's table object

This function takes a pointer to a container object and returns a pointer to its associated contents

Parameters
obj_containerthe object to get the contents of
obj_tablethe resulting table containing the container's contents.
TableFlagsflags controlling the type of table
RowCountthe number of rows in the hierarchy table

TableFlags possible values:

  • TableFlags_Associated (0x2): Get the contents table for "Folder Associated Information" messages, rather than normal messages.
  • TableFlags_DeferredErrors (0x8): The call response can return immediately, possibly before the call execution is complete and in this case the ReturnValue as well the RowCount fields in the return buffer might not be accurate. Only retval reporting failure can be considered valid in this case.
  • TableFlags_NoNotifications (0x10): Disables all notifications on .this Table object.
  • TableFlags_SoftDeletes (0x20): Enables the client to get a list of the soft deleted folders.
  • TableFlags_UseUnicode (0x40): Requests that the columns that contain string data be returned in Unicode format.
  • TableFlags_SuppressNotifications (0x80): Suppresses notifications generated by this client’s actions on this Table object.

Developers can either set RowCount to a valid pointer on uint32_t or set it to NULL. In this last case, GetHierarchyTable won't return any value to the calling function.

Returns
MAPI_E_SUCCESS on success, otherwise MAPI error.
Note
Developers may also call GetLastError() to retrieve the last MAPI error code. Possible MAPI error codes are:
  • MAPI_E_NOT_INITIALIZED: MAPI subsystem has not been initialized
  • MAPI_E_CALL_FAILED: A network problem was encountered during the transaction
See Also
OpenFolder, GetHierarchyTable, GetLastError
Examples:
fetchappointment.c, and fetchmail.c.

References mapi_object_get_handle(), mapi_object_get_logon_id(), mapi_object_get_session(), mapi_object_set_handle(), mapi_object_set_logon_id(), mapi_object_set_session(), and mapi_object_table_init().

Referenced by GetUserFreeBusyData().

_PUBLIC_ enum MAPISTATUS GetHierarchyTable ( mapi_object_t *  obj_container,
mapi_object_t *  obj_table,
uint8_t  TableFlags,
uint32_t *  RowCount 
)

Returns a pointer to a container's table object

This function takes a pointer to a container object and returns a pointer to its associated hierarchy table

Parameters
obj_containerthe object to get the contents of
obj_tablethe resulting table containing the container's hierarchy
TableFlagsflags controlling the type of table
RowCountthe number of rows in the hierarchy table

TableFlags possible values:

  • TableFlags_Depth (0x4): Fills the hierarchy table with containers from all levels. If this flag is not set, the hierarchy table contains only the container's immediate child containers.
  • TableFlags_DeferredErrors (0x8): The call response can return immediately, possibly before the call execution is complete and in this case the ReturnValue as well the RowCount fields in the return buffer might not be accurate. Only retval reporting failure can be considered valid in this case.
  • TableFlags_NoNotifications (0x10): Disables all notifications on .this Table object.
  • TableFlags_SoftDeletes (0x20): Enables the client to get a list of the soft deleted folders.
  • TableFlags_UseUnicode (0x40): Requests that the columns that contain string data be returned in Unicode format.
  • TableFlags_SuppressNotifications (0x80): Suppresses notifications generated by this client’s actions on this Table object.

Developers can either set RowCount to a valid pointer on uint32_t or set it to NULL. In this last case, GetHierarchyTable won't return any value to the calling function.

Returns
MAPI_E_SUCCESS on success, otherwise MAPI error.
Note
Developers may also call GetLastError() to retrieve the last MAPI error code. Possible MAPI error codes are:
  • MAPI_E_NOT_INITIALIZED: MAPI subsystem has not been initialized
  • MAPI_E_CALL_FAILED: A network problem was encountered during the transaction
See Also
OpenFolder, GetContentsTable, GetLastError

References mapi_object_get_handle(), mapi_object_get_logon_id(), mapi_object_get_session(), mapi_object_set_handle(), mapi_object_set_logon_id(), mapi_object_set_session(), and mapi_object_table_init().

Referenced by GetUserFreeBusyData().

_PUBLIC_ enum MAPISTATUS GetPermissionsTable ( mapi_object_t *  obj_container,
uint8_t  flags,
mapi_object_t *  obj_table 
)

Returns a pointer to the permission's table object.

This function takes a pointer to a container object and returns a pointer to its associated permission table

Parameters
obj_containerthe object to get the contents of
flagsany special flags to pass
obj_tablethe resulting table containing the container's permissions
Returns
MAPI_E_SUCCESS on success, otherwise MAPI error.

The only meaningful value for flags is IncludeFreeBusy (0x02). This should be set when getting permissions on the Calendar folder when using Exchange 2007 and later. It should not be set in other situations.

Note
Developers may also call GetLastError() to retrieve the last MAPI error code. Possible MAPI error codes are:
  • MAPI_E_NOT_INITIALIZED: MAPI subsystem has not been initialized
  • MAPI_E_CALL_FAILED: A network problem was encountered during the transaction
See Also
ModifyPermissions

References mapi_object_get_handle(), mapi_object_get_logon_id(), mapi_object_get_session(), mapi_object_set_handle(), mapi_object_set_logon_id(), mapi_object_set_session(), and mapi_object_table_init().

Referenced by ModifyUserPermission(), and RemoveUserPermission().

_PUBLIC_ enum MAPISTATUS GetRulesTable ( mapi_object_t *  obj_folder,
mapi_object_t *  obj_table,
uint8_t  TableFlags 
)

Gets the rules table of a folder

Parameters
obj_folderthe folder we want to retrieve the rules table from
obj_tablethe rules table
TableFlagsbitmask associated to the rules table

Possible values for TableFlags:

  • RulesTableFlags_Unicode (0x40): Set if the client is requesting that string values in the table to be returned as Unicode strings.
Returns
MAPI_E_SUCCESS on success, otherwise MAPI error.
Note
Developers may also call GetLastError() to retrieve the last MAPI error code. Possible MAPI error codes are:
  • MAPI_E_NOT_INITIALIZED: MAPI subsystem has not been initialized
  • MAPI_E_CALL_FAILED: A network problem was encountered during the transaction

References mapi_object_get_handle(), mapi_object_get_logon_id(), mapi_object_get_session(), mapi_object_set_handle(), mapi_object_set_logon_id(), mapi_object_set_session(), and mapi_object_table_init().

_PUBLIC_ enum MAPISTATUS GetSearchCriteria ( mapi_object_t *  obj_container,
struct mapi_SRestriction *  res,
uint32_t *  SearchFlags,
uint16_t *  FolderIdCount,
uint64_t **  FolderIds 
)

Obtains the search criteria for a container

Parameters
obj_containerthe object we retrieve search criteria from
respointer to a mapi_SRestriction structure defining the search criteria
SearchFlagsbitmask of flags that controls how the search is performed
FolderIdCountnumber of FolderIds entries
FolderIdspointer to a list of identifiers representing containers included in the search
Returns
MAPI_E_SUCCESS on success, otherwise MAPI error.
Note
Developers may also call GetLastError() to retrieve the last MAPI error code. Possible MAPI error codes are:
  • MAPI_E_NOT_INITIALIZED: MAPI subsystem has not been initialized
  • MAPI_E_CALL_FAILED: A network problem was encountered during the transaction
See Also
SetSearchCriteria

References mapi_object_get_handle(), mapi_object_get_logon_id(), and mapi_object_get_session().

_PUBLIC_ enum MAPISTATUS ModifyPermissions ( mapi_object_t *  obj_table,
uint8_t  flags,
struct mapi_PermissionsData *  permsdata 
)

Modify the entries of a permission table

This function takes a pointer to a table object, a list of entries to modify and alter the permission table of its associated container. This function can be used to add, modify or remove permissions.

Parameters
obj_tablethe table containing the container's permissions
flagsany special flags to use
permsdatathe list of permissions table entries to modify

Possible values for flags:

  • 0x02 for IncludeFreeBusy. This should be set when modifying permissions on the Calendar folder when using Exchange 2007 and later. It should not be set in other situations.
  • 0x01 for ReplaceRows. This means "remove all current permissions and use this set instead", so the permsdata must consist of ROW_ADD operations.
Returns
MAPI_E_SUCCESS on success, otherwise MAPI error.
Note
Developers may also call GetLastError() to retrieve the last MAPI error code. Possible MAPI error codes are:
  • MAPI_E_NOT_INITIALIZED: MAPI subsystem has not been initialized
  • MAPI_E_CALL_FAILED: A network problem was encountered during the transaction
See Also
GetPermissionsTable, AddUserPermission, ModifyUserPermission, RemoveUserPermission

References mapi_object_get_handle(), mapi_object_get_logon_id(), and mapi_object_get_session().

Referenced by AddUserPermission(), ModifyUserPermission(), and RemoveUserPermission().

_PUBLIC_ enum MAPISTATUS SetSearchCriteria ( mapi_object_t *  obj_container,
struct mapi_SRestriction *  res,
uint32_t  SearchFlags,
mapi_id_array_t *  lpContainerList 
)

Establishes search criteria for the container

Parameters
obj_containerthe object we apply search criteria to
respointer to a mapi_SRestriction structure defining the search criteria
SearchFlagsbitmask of flags that controls how the search is performed
lpContainerListpointer to a list of identifiers representing containers to be included in the search

SearchFlags can take the following values:

  • BACKGROUND_SEARCH: Search run at normal priority relative to other searches. This flag is mutually exclusive with the FOREGROUND_SEARCH one.
  • FOREGROUND_SEARCH: Search run at high priority relative to other searches. This flag is mutually exclusive with the BACKGROUND_SEARCH one.
  • RECURSIVE_SEARCH: The search should include the containers specified in the lpContainerList parameter and all of their child container. This flag is mutually exclusive with the SHALLOW_SEARCH one.
  • RESTART_SEARCH: The search should be initiated, if this is the first call to SetSearchCriteria, or restarted, if the search is inactive. This flag is mutually exclusive with the STOP_SEARCH flag.
  • SHALLOW_SEARCH: The search should only look in the containers specified in the lpContainerList parameter for matching entries. This flag is mutually exclusive with the RECURSIVE_SEARCH one.
  • STOP_SEARCH: The search should be aborted. This flag is mutually exclusive with the RESTART_SEARCH one.
Returns
MAPI_E_SUCCESS on success, otherwise MAPI error.
Note
Developers may also call GetLastError() to retrieve the last MAPI error code. Possible MAPI error codes are:
  • MAPI_E_NOT_INITIALIZED: MAPI subsystem has not been initialized
  • MAPI_E_INVALID_PARAMETER: One or more parameters were invalid (usually null pointer)
  • MAPI_E_CALL_FAILED: A network problem was encountered during the transaction
See Also
GetSearchCriteria

References get_mapi_SRestriction_size(), mapi_id_array_get(), mapi_object_get_handle(), mapi_object_get_logon_id(), and mapi_object_get_session().


Creative Commons License
Creative Commons Attribution icon Creative Commons Share Alike icon
This content is licensed under the Creative Commons
Attribution ShareAlike License v. 3.0:
http://creativecommons.org/licenses/by-sa/3.0/

openchange-2.0/apidocs/html/libmapi/IMAPIFolder_8c.html000066400000000000000000001321321223057412600227440ustar00rootroot00000000000000 MAPIClientLibraries 2.0 API Documentation
IMAPIFolder.c File Reference

Folder related functions. More...

#include "libmapi/libmapi.h"
#include "libmapi/libmapi_private.h"

Functions

_PUBLIC_ enum MAPISTATUS CopyFolder (mapi_object_t *obj_folder, mapi_object_t *obj_src, mapi_object_t *obj_dst, char *NewFolderName, bool UseUnicode, bool WantRecursive)
_PUBLIC_ enum MAPISTATUS CreateFolder (mapi_object_t *obj_parent, enum FOLDER_TYPE ulFolderType, const char *name, const char *comment, uint32_t ulFlags, mapi_object_t *obj_child)
_PUBLIC_ enum MAPISTATUS CreateMessage (mapi_object_t *obj_folder, mapi_object_t *obj_message)
_PUBLIC_ enum MAPISTATUS DeleteFolder (mapi_object_t *obj_parent, mapi_id_t FolderId, uint8_t DeleteFolderFlags, bool *PartialCompletion)
_PUBLIC_ enum MAPISTATUS DeleteMessage (mapi_object_t *obj_folder, mapi_id_t *id_messages, uint32_t cn_messages)
_PUBLIC_ enum MAPISTATUS EmptyFolder (mapi_object_t *obj_folder)
_PUBLIC_ enum MAPISTATUS GetMessageStatus (mapi_object_t *obj_folder, mapi_id_t msgid, uint32_t *ulStatus)
_PUBLIC_ enum MAPISTATUS HardDeleteMessage (mapi_object_t *obj_folder, mapi_id_t *id_messages, uint16_t cn_messages)
_PUBLIC_ enum MAPISTATUS HardDeleteMessagesAndSubfolders (mapi_object_t *obj_folder)
_PUBLIC_ enum MAPISTATUS MoveCopyMessages (mapi_object_t *obj_src, mapi_object_t *obj_dst, mapi_id_array_t *message_id, bool WantCopy)
_PUBLIC_ enum MAPISTATUS MoveFolder (mapi_object_t *obj_folder, mapi_object_t *obj_src, mapi_object_t *obj_dst, char *NewFolderName, bool UseUnicode)
_PUBLIC_ enum MAPISTATUS SetMessageStatus (mapi_object_t *obj_folder, mapi_id_t msgid, uint32_t ulNewStatus, uint32_t ulNewStatusMask, uint32_t *ulOldStatus)
_PUBLIC_ enum MAPISTATUS SetReadFlags (mapi_object_t *obj_folder, uint8_t ReadFlags, uint16_t MessageIdCount, uint64_t *MessageIds)

Detailed Description

Folder related functions.

Function Documentation

_PUBLIC_ enum MAPISTATUS CopyFolder ( mapi_object_t *  obj_folder,
mapi_object_t *  obj_src,
mapi_object_t *  obj_dst,
char *  NewFolderName,
bool  UseUnicode,
bool  WantRecursive 
)

Copy a folder

Parameters
obj_folderthe folder to copy
obj_srcsource object where the folder to copy is stored
obj_dstdestination object where the folder will be copied
NewFolderNamethe new folder name in the destination folder
UseUnicodewhether the folder name is unicode encoded or not
WantRecursivewhether we should copy folder's subdirectories or not
Returns
MAPI_E_SUCCESS on success, otherwise MAPI error.
Note
Developer may also call GetLastError() to retrieve the last MAPI error code. Possible MAPI error codes are:
  • MAPI_E_NOT_INITIALIZED: MAPI subsystem has not been initialized
  • MAPI_E_CALL_FAILED: A network problem was encountered during the transaction
See Also
OpenFolder, MoveFolder

References get_utf8_utf16_conv_length(), mapi_object_get_handle(), mapi_object_get_id(), mapi_object_get_logon_id(), and mapi_object_get_session().

_PUBLIC_ enum MAPISTATUS CreateFolder ( mapi_object_t *  obj_parent,
enum FOLDER_TYPE  ulFolderType,
const char *  name,
const char *  comment,
uint32_t  ulFlags,
mapi_object_t *  obj_child 
)

Create a folder

The function creates a folder (defined with its name, comment and type) within a specified folder.

Parameters
obj_parentthe folder to create the new folder in
ulFolderTypethe type of the folder
namethe name of the new folder
commentthe comment associated with the new folder
ulFlagsflags associated with folder creation
obj_childpointer to the newly created folder

ulFlags possible values:

  • MAPI_UNICODE: use UNICODE folder name and comment
  • OPEN_IF_EXISTS: open the folder if it already exists

ulFolderType possible values:

  • FOLDER_GENERIC
  • FOLDER_SEARCH
Returns
MAPI_E_SUCCESS on success, otherwise MAPI error.
Note
Developers may also call GetLastError() to retrieve the last MAPI error code. Possible MAPI error codes are:
  • MAPI_E_NOT_INITIALIZED: MAPI subsystem has not been initialized
  • MAPI_E_CALL_FAILED: A network problem was encountered during the transaction
See Also
OpenFolder, DeleteFolder, EmptyFolder, GetLastError

References get_utf8_utf16_conv_length(), mapi_object_get_handle(), mapi_object_get_logon_id(), mapi_object_get_session(), mapi_object_init(), mapi_object_set_handle(), mapi_object_set_id(), mapi_object_set_logon_id(), and mapi_object_set_session().

_PUBLIC_ enum MAPISTATUS CreateMessage ( mapi_object_t *  obj_folder,
mapi_object_t *  obj_message 
)

The function creates a message in the specified folder, and returns a pointer on this message.

Parameters
obj_folderthe folder to create the message in.
obj_messagepointer to the newly created message.
Returns
MAPI_E_SUCCESS on success, otherwise MAPI error.
Note
Developers may also call GetLastError() to retrieve the last MAPI error code. Possible MAPI error codes are:
  • MAPI_E_NOT_INITIALIZED: MAPI subsystem has not been initialized
  • MAPI_E_CALL_FAILED: A network problem was encountered during the transaction
See Also
OpenFolder, DeleteMessage, GetLastError

References mapi_object_get_handle(), mapi_object_get_id(), mapi_object_get_logon_id(), mapi_object_get_session(), mapi_object_set_handle(), mapi_object_set_logon_id(), and mapi_object_set_session().

_PUBLIC_ enum MAPISTATUS DeleteFolder ( mapi_object_t *  obj_parent,
mapi_id_t  FolderId,
uint8_t  DeleteFolderFlags,
bool *  PartialCompletion 
)

Delete a folder

The function deletes a specified folder.

Parameters
obj_parentthe folder containing the folder to be deleted
FolderIdthe ID of the folder to delete
DeleteFolderFlagscontrol DeleteFolder operation behavior
PartialCompletionpointer on a boolean value which specify whether the operation was partially completed or not

Possible values for DeleteFolderFlags are:

  1. DEL_MESSAGES Delete all the messages in the folder
  2. DEL_FOLDERS Delete the subfolder and all of its subfolders
  3. DELETE_HARD_DELETE Hard delete the folder
Returns
MAPI_E_SUCCESS on success, otherwise MAPI error.
Note
Developers may also call GetLastError() to retrieve the last MAPI error code. Possible MAPI error codes are:
  • MAPI_E_NOT_INITIALIZED: MAPI subsystem has not been initialized
  • MAPI_E_CALL_FAILED: A network problem was encountered during the transaction
See Also
OpenFolder, CreateFolder, EmptyFolder, GetLastError

References mapi_object_get_handle(), mapi_object_get_logon_id(), and mapi_object_get_session().

_PUBLIC_ enum MAPISTATUS DeleteMessage ( mapi_object_t *  obj_folder,
mapi_id_t *  id_messages,
uint32_t  cn_messages 
)

Delete one or more messages

This function deletes one or more messages based on their ids from a specified folder.

Parameters
obj_folderthe folder to delete messages from
id_messagesthe list of ids
cn_messagesthe number of messages in the id list.
Returns
MAPI_E_SUCCESS on success, otherwise MAPI error.
Note
Developers may also call GetLastError() to retrieve the last MAPI error code. Possible MAPI error codes are:
  • MAPI_E_NOT_INITIALIZED: MAPI subsystem has not been initialized
  • MAPI_E_CALL_FAILED: A network problem was encountered during the transaction
See Also
OpenFolder, CreateMessage, GetLastError

References mapi_object_get_handle(), mapi_object_get_logon_id(), and mapi_object_get_session().

_PUBLIC_ enum MAPISTATUS EmptyFolder ( mapi_object_t *  obj_folder)

Empty the contents of a folder

This function empties (clears) the contents of a specified folder.

Parameters
obj_folderthe folder to empty
Returns
MAPI_E_SUCCESS on success, otherwise MAPI error.
Note
Developers may also call GetLastError() to retrieve the last MAPI error code. Possible MAPI error codes are:
  • MAPI_E_NOT_INITIALIZED: MAPI subsystem has not been initialized
  • MAPI_E_CALL_FAILED: A network problem was encountered during the transaction
See Also
OpenFolder, CreateFolder, DeleteFolder, GetLastError

References mapi_object_get_handle(), mapi_object_get_logon_id(), and mapi_object_get_session().

_PUBLIC_ enum MAPISTATUS GetMessageStatus ( mapi_object_t *  obj_folder,
mapi_id_t  msgid,
uint32_t *  ulStatus 
)

Obtain the status associated with a message

This function obtains the status associated with a message in the given folder.

Parameters
obj_folderthe folder where the message is located
msgidthe message ID
ulStatusthe message status
Returns
MAPI_E_SUCCESS on success, otherwise MAPI error.
Note
Developers may also call GetLastError() to retrieve the last MAPI error code. Possible MAPI error codes are:
  • MAPI_E_NOT_INITIALIZED: MAPI subsystem has not been initialized
  • MAPI_E_CALL_FAILED: A network problem was encountered during the transaction

References mapi_object_get_handle(), mapi_object_get_logon_id(), and mapi_object_get_session().

_PUBLIC_ enum MAPISTATUS HardDeleteMessage ( mapi_object_t *  obj_folder,
mapi_id_t *  id_messages,
uint16_t  cn_messages 
)

Hard delete one or more messages

This function hard deletes one or more messages based on their ids from a specified folder.

Parameters
obj_folderthe folder to hard delete messages from
id_messagesthe list of ids
cn_messagesthe number of messages in the id list.
Returns
MAPI_E_SUCCESS on success, otherwise MAPI error.
Note
Developers may also call GetLastError() to retrieve the last MAPI error code. Possible MAPI error codes are:
  • MAPI_E_NOT_INITIALIZED: MAPI subsystem has not been initialized
  • MAPI_E_INVALID_PARAMETER: the parent folder was not valid
  • MAPI_E_CALL_FAILED: A network problem was encountered during the transaction
See Also
OpenFolder, CreateMessage, GetLastError

References mapi_object_get_handle(), mapi_object_get_logon_id(), and mapi_object_get_session().

_PUBLIC_ enum MAPISTATUS HardDeleteMessagesAndSubfolders ( mapi_object_t *  obj_folder)

Hard delete the contents of a folder, including subfolders

This function empties (clears) the contents of a specified folder.

Parameters
obj_folderthe folder to empty
Returns
MAPI_E_SUCCESS on success, otherwise MAPI error.
Note
Developers may also call GetLastError() to retrieve the last MAPI error code. Possible MAPI error codes are:
  • MAPI_E_NOT_INITIALIZED: MAPI subsystem has not been initialized
  • MAPI_E_INVALID_PARAMETER: obj_folder is not valid
  • MAPI_E_CALL_FAILED: A network problem was encountered during the transaction
See Also
DeleteFolder, EmptyFolder

References mapi_object_get_handle(), mapi_object_get_logon_id(), and mapi_object_get_session().

_PUBLIC_ enum MAPISTATUS MoveCopyMessages ( mapi_object_t *  obj_src,
mapi_object_t *  obj_dst,
mapi_id_array_t *  message_id,
bool  WantCopy 
)

Copy or Move a message from a folder to another

Parameters
obj_srcThe source folder
obj_dstThe destination folder
message_idpointer to container object for message ids.
WantCopyboolean value, defines whether the operation is a copy or a move

Possible values for WantCopy:

  1. 0: Move
  2. 1: Copy
Returns
MAPI_E_SUCCESS on success, otherwise MAPI error.
Note
Developers may also call GetLastError() to retrieve the last MAPI error code. Possible MAPI error codes are:
  • MAPI_E_NOT_INITIALIZED: MAPI subsystem has not been initialized
  • MAPI_E_CALL_FAILED: A network problem was encountered during the transaction
See Also
OpenFolder, GetLastError

References mapi_id_array_get(), mapi_object_get_handle(), mapi_object_get_logon_id(), and mapi_object_get_session().

_PUBLIC_ enum MAPISTATUS MoveFolder ( mapi_object_t *  obj_folder,
mapi_object_t *  obj_src,
mapi_object_t *  obj_dst,
char *  NewFolderName,
bool  UseUnicode 
)

Moves a folder

Parameters
obj_folderthe folder to move
obj_srcsource object where the folder to move is stored
obj_dstdestination object where the folder will be moved
NewFolderNamethe new folder name in the destination folder
UseUnicodewhether the folder name is unicode encoded or not
Returns
MAPI_E_SUCCESS on success, otherwise MAPI error.
Note
Developers may also call GetLastError() to retrieve the last MAPI error code. Possible MAPI error codes are:
  • MAPI_E_NOT_INITIALIZED: MAPI subsystem has not been initialized
  • MAPI_E_CALL_FAILED: A network problem was encountered during the transaction
See Also
OpenFolder, CopyFolder

References get_utf8_utf16_conv_length(), mapi_object_get_handle(), mapi_object_get_id(), mapi_object_get_logon_id(), and mapi_object_get_session().

_PUBLIC_ enum MAPISTATUS SetMessageStatus ( mapi_object_t *  obj_folder,
mapi_id_t  msgid,
uint32_t  ulNewStatus,
uint32_t  ulNewStatusMask,
uint32_t *  ulOldStatus 
)

Set the status associated with a message

This function sets the status associated with a message in the given folder.

Parameters
obj_folderthe folder where the message is located
msgidthe message ID
ulNewStatusthe new status to be assigned
ulNewStatusMaskbitmask of flags hat is applied to the new status indicating the flags to be set
ulOldStatuspointer on the previous status of the message

ulNewStatusMask possible values:

  • MSGSTATUS_DELMARKED: the message is marked for deletion
  • MSGSTATUS_HIDDEN: the message is not to be displayed
  • MSGSTATUS_HIGHLIGHTED: the message is to be displayed highlighted
  • MSGSTATUS_REMOTE_DELETE: the message has been marked for deletion on the remote message store without downloading to the local client.
  • MSGSTATUS_REMOTE_DOWNLOAD: the message has been marked for downloading from the remote message store to the local client.
  • MSGSTATUS_TAGGED: The message has been tagged for a client-defined purpose.
Returns
MAPI_E_SUCCESS on success, otherwise MAPI error.
Note
Developers may also call GetLastError() to retrieve the last MAPI error code. Possible MAPI error codes are:
  • MAPI_E_NOT_INITIALIZED: MAPI subsystem has not been initialized
  • MAPI_E_CALL_FAILED: A network problem was encountered during the transaction

References mapi_object_get_handle(), mapi_object_get_logon_id(), and mapi_object_get_session().

_PUBLIC_ enum MAPISTATUS SetReadFlags ( mapi_object_t *  obj_folder,
uint8_t  ReadFlags,
uint16_t  MessageIdCount,
uint64_t *  MessageIds 
)

Set the Read Flags on one or more messages

Parameters
obj_folderthe folder containing the messages to change
ReadFlagsa bitmap of flags controlling the changes to PR_PROPERTY_FLAGS
MessageIdCountthe number of messages in the MessageIds array
MessageIdsan array of message ids to set Read flags for

Note that the obj_folder argument is the object corresponding to the folder containing the messages (e.g. the result of CreateFolder() or OpenFolder(). It is not the content table of that folder (unlike SetMessageReadFlag().)

Returns
MAPI_E_SUCCESS on success, otherwise MAPI error.
Note
Developers may also call GetLastError() to retrieve the last MAPI error code. Possible MAPI error codes are:
  • MAPI_E_NOT_INITIALIZED: MAPI subsystem has not been initialized
  • MAPI_E_CALL_FAILED: A network problem was encountered during the transaction
See Also
SetMessageReadFlags for a slightly different version, working on a single message

References mapi_object_get_handle(), mapi_object_get_logon_id(), and mapi_object_get_session().


Creative Commons License
Creative Commons Attribution icon Creative Commons Share Alike icon
This content is licensed under the Creative Commons
Attribution ShareAlike License v. 3.0:
http://creativecommons.org/licenses/by-sa/3.0/

openchange-2.0/apidocs/html/libmapi/IMAPIProp_8c.html000066400000000000000000001427201223057412600224550ustar00rootroot00000000000000 MAPIClientLibraries 2.0 API Documentation
IMAPIProp.c File Reference

Properties and named properties operations. More...

#include "libmapi/libmapi.h"

Functions

_PUBLIC_ enum MAPISTATUS CopyProps (mapi_object_t *obj_src, mapi_object_t *obj_dst, struct SPropTagArray *tags, uint8_t copyFlags, uint16_t *problemCount, struct PropertyProblem **problems)
_PUBLIC_ enum MAPISTATUS CopyTo (mapi_object_t *obj_src, mapi_object_t *obj_dst, struct SPropTagArray *excludeTags, uint8_t copyFlags, uint16_t *problemCount, struct PropertyProblem **problems)
_PUBLIC_ enum MAPISTATUS DeletePropertiesNoReplicate (mapi_object_t *obj, struct SPropTagArray *proptags)
_PUBLIC_ enum MAPISTATUS DeleteProps (mapi_object_t *obj, struct SPropTagArray *proptags)
_PUBLIC_ enum MAPISTATUS GetIDsFromNames (mapi_object_t *obj, uint16_t count, struct MAPINAMEID *nameid, uint32_t ulFlags, struct SPropTagArray **proptags)
_PUBLIC_ enum MAPISTATUS GetNamesFromIDs (mapi_object_t *obj, enum MAPITAGS ulPropTag, uint16_t *count, struct MAPINAMEID **nameid)
_PUBLIC_ enum MAPISTATUS GetPropList (mapi_object_t *obj, struct SPropTagArray *proptags)
_PUBLIC_ enum MAPISTATUS GetProps (mapi_object_t *obj, uint32_t flags, struct SPropTagArray *SPropTagArray, struct SPropValue **lpProps, uint32_t *PropCount)
_PUBLIC_ enum MAPISTATUS GetPropsAll (mapi_object_t *obj, uint32_t flags, struct mapi_SPropValue_array *properties)
_PUBLIC_ enum MAPISTATUS QueryNamedProperties (mapi_object_t *obj, uint8_t queryFlags, struct GUID *guid, uint16_t *count, uint16_t **propID, struct MAPINAMEID **nameid)
_PUBLIC_ enum MAPISTATUS SaveChangesAttachment (mapi_object_t *obj_parent, mapi_object_t *obj_child, enum SaveFlags flags)
_PUBLIC_ enum MAPISTATUS SetPropertiesNoReplicate (mapi_object_t *obj, uint32_t flags, struct SPropValue *lpProps, unsigned long PropCount)
_PUBLIC_ enum MAPISTATUS SetProps (mapi_object_t *obj, uint32_t flags, struct SPropValue *lpProps, unsigned long PropCount)

Detailed Description

Properties and named properties operations.

Function Documentation

_PUBLIC_ enum MAPISTATUS CopyProps ( mapi_object_t *  obj_src,
mapi_object_t *  obj_dst,
struct SPropTagArray *  tags,
uint8_t  copyFlags,
uint16_t *  problemCount,
struct PropertyProblem **  problems 
)

Copy properties from one object to another

This function copies (or moves) specified properties from one object to another.

Parameters
obj_srcthe object to copy properties from
obj_dstthe object to set properties on
copyFlagsflags to determine whether to copy or move, and whether to overwrite existing properties.
tagsthe list of properties to copy
problemCount(return value) number of entries in the problems array
problems(return value) array of problemCount entries.

The caller is responsible for freeing the problems array using MAPIFreeBuffer(). If the problemCount pointer is NULL, then the problems array will not be returned.

Returns
MAPI_E_SUCCESS on success, otherwise MAPI error.
Note
Developers may also call GetLastError() to retrieve the last MAPI error code. Possible MAPI error codes are:
  • MAPI_E_NOT_INITIALIZED: MAPI subsystem has not been initialized
  • MAPI_E_CALL_FAILED: A network problem was encountered during the transaction
See Also
GetProps, SetProps, DeleteProps, CopyTo, GetLastError

References mapi_object_get_handle(), mapi_object_get_logon_id(), and mapi_object_get_session().

_PUBLIC_ enum MAPISTATUS CopyTo ( mapi_object_t *  obj_src,
mapi_object_t *  obj_dst,
struct SPropTagArray *  excludeTags,
uint8_t  copyFlags,
uint16_t *  problemCount,
struct PropertyProblem **  problems 
)

Copy multiple properties from one object to another

This function copies (or moves) properties from one object to another. Unlike CopyProperties, this function copies all properties except those identified.

Parameters
obj_srcthe object to copy properties from
obj_dstthe object to set properties on
excludeTagsthe list of properties to not copy
copyFlagsflags to determine whether to copy or move, and whether to overwrite existing properties.
problemCount(return value) number of entries in the problems array
problems(return value) array of problemCount entries.

The caller is responsible for freeing the problems array using MAPIFreeBuffer(). If the problemCount pointer is NULL, then the problems array will not be returned.

Returns
MAPI_E_SUCCESS on success, otherwise MAPI error.
Note
Developers may also call GetLastError() to retrieve the last MAPI error code. Possible MAPI error codes are:
  • MAPI_E_NOT_INITIALIZED: MAPI subsystem has not been initialized
  • MAPI_E_CALL_FAILED: A network problem was encountered during the transaction
See Also
GetProps, SetProps, DeleteProps, CopyProps

References mapi_object_get_handle(), mapi_object_get_logon_id(), and mapi_object_get_session().

_PUBLIC_ enum MAPISTATUS DeletePropertiesNoReplicate ( mapi_object_t *  obj,
struct SPropTagArray *  proptags 
)

Deletes property values from an object without invoking replication.

Parameters
objthe object to remove properties from
proptagsthe properties to remove from the given object
Returns
MAPI_E_SUCCESS on success, otherwise MAPI error.
Note
Developers may also call GetLastError() to retrieve the last MAPI error code. Possible MAPI error codes are:
  • MAPI_E_NOT_INITIALIZED: MAPI subsystem has not been initialized
  • MAPI_E_CALL_FAILED: A network problem was encountered during the transaction
See Also
DeleteProps

References mapi_object_get_handle(), mapi_object_get_logon_id(), and mapi_object_get_session().

_PUBLIC_ enum MAPISTATUS DeleteProps ( mapi_object_t *  obj,
struct SPropTagArray *  proptags 
)

Delete one or more properties from an object

Parameters
objthe object to remove properties from
proptagsthe properties to remove from the given object
Returns
MAPI_E_SUCCESS on success, otherwise MAPI error.
Note
Developers may also call GetLastError() to retrieve the last MAPI error code. Possible MAPI error codes are:
  • MAPI_E_NOT_INITIALIZED: MAPI subsystem has not been initialized
  • MAPI_E_CALL_FAILED: A network problem was encountered during the transaction
See Also
SetProps, GetLastError

References mapi_object_get_handle(), mapi_object_get_logon_id(), and mapi_object_get_session().

_PUBLIC_ enum MAPISTATUS GetIDsFromNames ( mapi_object_t *  obj,
uint16_t  count,
struct MAPINAMEID *  nameid,
uint32_t  ulFlags,
struct SPropTagArray **  proptags 
)

Provides the property identifiers that correspond to one or more property names.

Parameters
objthe object we are retrieving the identifiers from
countcount of property names pointed to by the nameid parameter.
nameidpointer to an array of property names
ulFlagsindicates how the property identifiers should be returned
proptagspointer to a pointer to an array of property tags containing existing or newly assigned property identifiers. Property types in this array are set to PT_NULL.

ulFlags can be set to:

  • 0 retrieves named properties from the server
  • MAPI_CREATE create the named properties if they don't exist on the server
Note
count and nameid parameter can automatically be built using the mapi_nameid API.
Returns
MAPI_E_SUCCESS on success, otherwise MAPI error.
Note
Developers may also call GetLastError() to retrieve the last MAPI error code. Possible MAPI error codes are:
  • MAPI_E_NOT_INITIALIZED: MAPI subsystem has not been initialized
  • MAPI_E_CALL_FAILED: A network problem was encountered during the transaction
See Also
GetNamesFromIds, QueryNamesFromIDs, mapi_nameid_new

References get_utf8_utf16_conv_length(), mapi_object_get_handle(), mapi_object_get_logon_id(), and mapi_object_get_session().

Referenced by GetProps(), mapi_nameid_GetIDsFromNames(), SetPropertiesNoReplicate(), and SetProps().

_PUBLIC_ enum MAPISTATUS GetNamesFromIDs ( mapi_object_t *  obj,
enum MAPITAGS  ulPropTag,
uint16_t *  count,
struct MAPINAMEID **  nameid 
)

Provides the property names that correspond to one or more property identifiers.

Parameters
objthe object we are retrieving the names from
ulPropTagthe mapped property tag
countcount of property names pointed to by the nameid parameter returned by the server
nameidpointer to a pointer to property names returned by the server

ulPropTag must be a property with type set to PT_NULL

Returns
MAPI_E_SUCCESS on success, otherwise MAPI error.
Note
Developers may also call GetLastError() to retrieve the last MAPI error code. Possible MAPI error codes are:
  • MAPI_E_NOT_INITIALIZED: MAPI subsystem has not been initialized
  • MAPI_E_CALL_FAILED: A network problem was encountered during the transaction
See Also
GetIDsFromNames, QueryNamesFromIDs

References mapi_object_get_handle(), mapi_object_get_logon_id(), and mapi_object_get_session().

_PUBLIC_ enum MAPISTATUS GetPropList ( mapi_object_t *  obj,
struct SPropTagArray *  proptags 
)

Retrieve all the properties associated with a given object

Parameters
objthe object to retrieve properties for
proptagsthe resulting list of properties associated with the object
Returns
MAPI_E_SUCCESS on success, otherwise MAPI error.
Note
Developers may also call GetLastError() to retrieve the last MAPI error code. Possible MAPI error codes are:
  • MAPI_E_NOT_INITIALIZED: MAPI subsystem has not been initialized
  • MAPI_E_CALL_FAILED: A network problem was encountered during the transaction

    The developer MUST provide an allocated SPropTagArray structure to the function.

See Also
GetProps, GetPropsAll, GetLastError

References mapi_object_get_handle(), mapi_object_get_logon_id(), and mapi_object_get_session().

_PUBLIC_ enum MAPISTATUS GetProps ( mapi_object_t *  obj,
uint32_t  flags,
struct SPropTagArray *  SPropTagArray,
struct SPropValue **  lpProps,
uint32_t *  PropCount 
)

Returns values of one or more properties for an object

The function takes a pointer on the object obj, a MAPITAGS array specified in mapitags, and the count of properties. The function returns associated values within the SPropValue values pointer.

The array of MAPI property tags can be filled with both known and named properties.

Parameters
objthe object to get properties on
flagsFlags for behaviour; can be bit-OR of MAPI_UNICODE and MAPI_PROPS_SKIP_NAMEDID_CHECK constants
SPropTagArrayan array of MAPI property tags
lpPropsthe result of the query
PropCountthe count of property tags
Returns
MAPI_E_SUCCESS on success, otherwise MAPI error.
Note
Developers may also call GetLastError() to retrieve the last MAPI error code. Possible MAPI error codes are:
  • MAPI_E_NOT_INITIALIZED: MAPI subsystem has not been initialized
  • MAPI_E_INVALID_PARAMETER: obj or SPropTagArray are null, or the session context could not be obtained
  • MAPI_E_CALL_FAILED: A network problem was encountered during the transaction
See Also
SetProps, GetPropList, GetPropsAll, DeleteProps, GetLastError

References emsmdb_get_SPropValue(), GetIDsFromNames(), mapi_nameid_lookup_SPropTagArray(), mapi_nameid_map_SPropTagArray(), mapi_nameid_new(), mapi_nameid_unmap_SPropTagArray(), mapi_object_get_handle(), mapi_object_get_logon_id(), mapi_object_get_session(), and MAPIFreeBuffer().

Referenced by EntryIDFromSourceIDForMessage(), GetBestBody(), GetFolderItemsCount(), and GetUserFreeBusyData().

_PUBLIC_ enum MAPISTATUS GetPropsAll ( mapi_object_t *  obj,
uint32_t  flags,
struct mapi_SPropValue_array *  properties 
)

Retrieve all properties and values associated with an object

This function returns all the properties and and associated values for a given object.

Parameters
objthe object to get the properties for
flagsFlags for behaviour; can be a MAPI_UNICODE constant
propertiesthe properties / values for the object
Returns
MAPI_E_SUCCESS on success, otherwise MAPI error.
Note
Developers may also call GetLastError() to retrieve the last MAPI error code. Possible MAPI error codes are:
  • MAPI_E_NOT_INITIALIZED: MAPI subsystem has not been initialized
  • MAPI_E_CALL_FAILED: A network problem was encountered during the transaction
See Also
GetProps, GetPropList, GetLastError
Examples:
fetchappointment.c, and fetchmail.c.

References mapi_object_get_handle(), mapi_object_get_logon_id(), and mapi_object_get_session().

_PUBLIC_ enum MAPISTATUS QueryNamedProperties ( mapi_object_t *  obj,
uint8_t  queryFlags,
struct GUID *  guid,
uint16_t *  count,
uint16_t **  propID,
struct MAPINAMEID **  nameid 
)

Provides the property names that correspond to one or more property identifiers.

Parameters
objthe object to obtain the properties for
queryFlagsA set of flags that can restrict the type of properties
guida pointer to the GUID for the property set to fetch (null for all property sets.
countcount of property names pointed to by the nameid and propID parameters returned by the server
propIDpointer to an array of property IDs returned by the server
nameidpointer to an array of property names returned by the server
Note
queryFlags can be NoStrings (0x1) or NoIds (0x2), neither or both. NoStrings will produce only ID properties, NoIds will produce only named properties, and both will result in no output.
Returns
MAPI_E_SUCCESS on success, otherwise MAPI error.
See Also
GetNamesFromIDs

References mapi_object_get_handle(), mapi_object_get_logon_id(), and mapi_object_get_session().

_PUBLIC_ enum MAPISTATUS SaveChangesAttachment ( mapi_object_t *  obj_parent,
mapi_object_t *  obj_child,
enum SaveFlags  flags 
)

Makes permanent any changes made to an attachment since the last save operation.

Parameters
obj_parentthe parent of the object to save changes for
obj_childthe object to save changes for
flagsthe access flags to set on the saved object

Possible flags:

  • KeepOpenReadOnly
  • KeepOpenReadWrite
  • ForceSave
Returns
MAPI_E_SUCCESS on success, otherwise MAPI error.
Note
Developers may also call GetLastError() to retrieve the last MAPI error code. Possible MAPI error codes are:
  • MAPI_E_NOT_INITIALIZED: MAPI subsystem has not been initialized
  • MAPI_E_CALL_FAILED: A network problem was encountered during the transaction
See Also
SetProps, ModifyRecipients, GetLastError

References mapi_object_get_handle(), mapi_object_get_logon_id(), and mapi_object_get_session().

_PUBLIC_ enum MAPISTATUS SetPropertiesNoReplicate ( mapi_object_t *  obj,
uint32_t  flags,
struct SPropValue *  lpProps,
unsigned long  PropCount 
)

Set one or more properties on a given object without invoking replication.

This function sets one or more properties on a specified object. It is the same as SetProps, except if the object is a folder, where this function does not result in folder properties being replicated.

Parameters
objthe object to set properties on
flagsFlags for behaviour; can be MAPI_PROPS_SKIP_NAMEDID_CHECK
lpPropsthe list of properties to set
PropCountthe number of properties
Returns
MAPI_E_SUCCESS on success, otherwise MAPI error.
Note
Developers may also call GetLastError() to retrieve the last MAPI error code. Possible MAPI error codes are:
  • MAPI_E_NOT_INITIALIZED: MAPI subsystem has not been initialized
  • MAPI_E_INVALID_PARAMETER: obj is not valid
  • MAPI_E_CALL_FAILED: A network problem was encountered during the transaction
See Also
SetProps, DeletePropertiesNoReplicate

References cast_mapi_SPropValue(), GetIDsFromNames(), mapi_nameid_lookup_SPropValue(), mapi_nameid_map_SPropValue(), mapi_nameid_new(), mapi_nameid_unmap_SPropValue(), mapi_object_get_handle(), mapi_object_get_logon_id(), mapi_object_get_session(), and MAPIFreeBuffer().

_PUBLIC_ enum MAPISTATUS SetProps ( mapi_object_t *  obj,
uint32_t  flags,
struct SPropValue *  lpProps,
unsigned long  PropCount 
)

Set one or more properties on a given object

This function sets one or more properties on a specified object.

Parameters
objthe object to set properties on
flagsFlags for behaviour; can be MAPI_PROPS_SKIP_NAMEDID_CHECK
lpPropsthe list of properties to set
PropCountthe number of properties
Returns
MAPI_E_SUCCESS on success, otherwise MAPI error.
Note
Developers may also call GetLastError() to retrieve the last MAPI error code. Possible MAPI error codes are:
  • MAPI_E_NOT_INITIALIZED: MAPI subsystem has not been initialized
  • MAPI_E_CALL_FAILED: A network problem was encountered during the transaction
See Also
GetProps, GetPropList, GetPropsAll, DeleteProps, GetLastError

References cast_mapi_SPropValue(), GetIDsFromNames(), mapi_nameid_lookup_SPropValue(), mapi_nameid_map_SPropValue(), mapi_nameid_new(), mapi_nameid_unmap_SPropValue(), mapi_object_get_handle(), mapi_object_get_logon_id(), mapi_object_get_session(), and MAPIFreeBuffer().


Creative Commons License
Creative Commons Attribution icon Creative Commons Share Alike icon
This content is licensed under the Creative Commons
Attribution ShareAlike License v. 3.0:
http://creativecommons.org/licenses/by-sa/3.0/

openchange-2.0/apidocs/html/libmapi/IMAPISession_8c.html000066400000000000000000000300311223057412600231470ustar00rootroot00000000000000 MAPIClientLibraries 2.0 API Documentation
IMAPISession.c File Reference

Session initialization options. More...

#include "libmapi/libmapi.h"
#include "libmapi/libmapi_private.h"

Functions

_PUBLIC_ enum MAPISTATUS OpenMsgStore (struct mapi_session *session, mapi_object_t *obj_store)
_PUBLIC_ enum MAPISTATUS OpenPublicFolder (struct mapi_session *session, mapi_object_t *obj_store)
_PUBLIC_ enum MAPISTATUS OpenUserMailbox (struct mapi_session *session, const char *username, mapi_object_t *obj_store)

Detailed Description

Session initialization options.

Function Documentation

_PUBLIC_ enum MAPISTATUS OpenMsgStore ( struct mapi_session *  session,
mapi_object_t *  obj_store 
)

Open the Message Store

This function opens the main message store. This allows access to the normal user folders.

Parameters
sessionpointer to the MAPI session context
obj_storethe result of opening the store
Returns
MAPI_E_SUCCESS on success, otherwise MAPI error.
Note
Developers may also call GetLastError() to retrieve the last MAPI error code. Possible MAPI error codes are:
  • MAPI_E_NOT_INITIALIZED: MAPI subsystem has not been initialized
  • MAPI_E_CALL_FAILED: A network problem was encountered during the transaction
See Also
MAPIInitialize which is required before opening the store
GetLastError to check the result of a failed call, if necessary
OpenPublicFolder if you need access to the public folders
Examples:
fetchappointment.c, and fetchmail.c.

References GetLastError(), and OpenUserMailbox().

_PUBLIC_ enum MAPISTATUS OpenPublicFolder ( struct mapi_session *  session,
mapi_object_t *  obj_store 
)

Open the Public Folder store

This function opens the public folder store. This allows access to the public folders.

Parameters
obj_storethe result of opening the store
sessionpointer to the MAPI session context
Returns
MAPI_E_SUCCESS on success, otherwise MAPI error.
Note
Developers may also call GetLastError() to retrieve the last MAPI error code. Possible MAPI error codes are:
  • MAPI_E_NOT_INITIALIZED: MAPI subsystem has not been initialized
  • MAPI_E_CALL_FAILED: A network problem was encountered during the transaction
See Also
MAPIInitialize which is required before opening the store
GetLastError to check the result of a failed call, if necessary
OpenMsgStore if you need access to the message store folders

References GetNewLogonId(), mapi_object_set_handle(), mapi_object_set_logon_id(), mapi_object_set_logon_store(), and mapi_object_set_session().

_PUBLIC_ enum MAPISTATUS OpenUserMailbox ( struct mapi_session *  session,
const char *  username,
mapi_object_t *  obj_store 
)

Open another user mailbox

This function opens the main message store. This allows access to the normal user folders.

Parameters
sessionpointer to the MAPI session context
usernamename of the user's mailbox to open
obj_storethe result of opening the store
Returns
MAPI_E_SUCCESS on success, otherwise MAPI error.
Note
Developers may also call GetLastError() to retrieve the last MAPI error code. Possible MAPI error codes are:
  • MAPI_E_NOT_INITIALIZED: MAPI subsystem has not been initialized
  • MAPI_E_CALL_FAILED: A network problem was encountered during the transaction
See Also
MAPIInitialize which is required before opening the store
GetLastError to check the result of a failed call, if necessary
OpenPublicFolder if you need access to the public folders

References GetNewLogonId(), mapi_object_set_handle(), mapi_object_set_logon_id(), mapi_object_set_logon_store(), and mapi_object_set_session().

Referenced by OpenMsgStore().


Creative Commons License
Creative Commons Attribution icon Creative Commons Share Alike icon
This content is licensed under the Creative Commons
Attribution ShareAlike License v. 3.0:
http://creativecommons.org/licenses/by-sa/3.0/

openchange-2.0/apidocs/html/libmapi/IMAPISupport_8c.html000066400000000000000000000371561223057412600232170ustar00rootroot00000000000000 MAPIClientLibraries 2.0 API Documentation
IMAPISupport.c File Reference

MAPI notifications functions. More...

#include "libmapi/libmapi.h"
#include "libmapi/libmapi_private.h"

Functions

_PUBLIC_ enum MAPISTATUS DispatchNotifications (struct mapi_session *session)
_PUBLIC_ enum MAPISTATUS MonitorNotification (struct mapi_session *session, void *private_data, struct mapi_notify_continue_callback_data *cb_data)
_PUBLIC_ enum MAPISTATUS Subscribe (mapi_object_t *obj, uint32_t *connection, uint16_t NotificationFlags, bool WholeStore, mapi_notify_callback_t notify_callback, void *private_data)
_PUBLIC_ enum MAPISTATUS Unsubscribe (struct mapi_session *session, uint32_t ulConnection)

Detailed Description

MAPI notifications functions.

Function Documentation

_PUBLIC_ enum MAPISTATUS DispatchNotifications ( struct mapi_session *  session)

Force notification of pending events

This function force the server to send any pending notificaion and process them. These MAPI notifications are next compared to the registered ones and the callback specified in Subscribe() called if it matches.

Returns
MAPI_E_SUCCESS on success, otherwise MAPI error.
Note
Developers may also call GetLastError() to retrieve the last MAPI error code. Possible MAPI error codes are:
  • MAPI_E_NOT_INITIALIZED: MAPI subsystem has not been initialized
  • MAPI_E_CALL_FAILED: A network problem was encountered during the transaction
See Also
RegisterNotification, Subscribe, Unsubscribe, GetLastError

References emsmdb_transaction_null().

_PUBLIC_ enum MAPISTATUS MonitorNotification ( struct mapi_session *  session,
void *  private_data,
struct mapi_notify_continue_callback_data *  cb_data 
)

Wait for notifications and process them

This function waits for notifications on the UDP port and generates the traffic needed to receive MAPI notifications. These MAPI notifications are next compared to the registered ones and the callback specified in Subscribe() called if it matches.

The function takes a callback in cb_data to check if it should continue to process notifications. Timeval in cb_data can be used to control the behavior of select.

Returns
MAPI_E_SUCCESS on success, otherwise MAPI error.
Note
Developers may also call GetLastError() to retrieve the last MAPI error code. Possible MAPI error codes are:
  • MAPI_E_NOT_INITIALIZED: MAPI subsystem has not been initialized
  • MAPI_E_CALL_FAILED: A network problem was encountered during the transaction
See Also
RegisterNotification, Subscribe, Unsubscribe, GetLastError
Note
This code is experimental. The current implementation is non-threaded, only supports fnevNewmail and fnevCreatedObject notifications and will block your process until you send a signal.

References emsmdb_transaction_null().

_PUBLIC_ enum MAPISTATUS Subscribe ( mapi_object_t *  obj,
uint32_t *  connection,
uint16_t  NotificationFlags,
bool  WholeStore,
mapi_notify_callback_t  notify_callback,
void *  private_data 
)

Register an object to receive notifications

This function registers notifications on the Exchange server for an object. The function holds the notifications intended to be monitored in as a bitmask.

Parameters
objthe object to get notifications for
connectionconnection identifier for callback function
NotificationFlagsmask for events to provide notifications for (see below)
WholeStorewhether the scope for this notification is whole database
notify_callbacknotification callback function.
private_datathe data to be passed at the callback function when invoked

The Notification Flags can take the following values:

  • fnevCriticalError
  • fnevNewMail
  • fnevObjectCreated
  • fnevObjectDeleted
  • fnevObjectModified
  • fnevObjectMoved
  • fnevObjectCopied
  • fnevSearchComplete
  • fnevTableModified
  • fnevStatusObjectModified
  • fnevReservedForMapi
  • fnevExtended
Returns
MAPI_E_SUCCESS on success, otherwise MAPI error.
Note
Developers may also call GetLastError() to retrieve the last MAPI error code. Possible MAPI error codes are:
  • MAPI_E_NOT_INITIALIZED: MAPI subsystem has not been initialized
  • MAPI_E_CALL_FAILED: A network problem was encountered during the transaction
See Also
RegisterNotification, Unsubscribe, MonitorNotification, GetLastError

References mapi_object_get_handle(), mapi_object_get_id(), mapi_object_get_logon_id(), mapi_object_get_session(), mapi_object_init(), mapi_object_set_handle(), and mapi_object_set_session().

_PUBLIC_ enum MAPISTATUS Unsubscribe ( struct mapi_session *  session,
uint32_t  ulConnection 
)

Unregister notifications on a given object.

Cancel any notification registrations associated with the notify object. This function unregisters notifications on the Exchange server for the object specified with its connection number ulConnection. The function will releases the notification on the Exchange server and remove the entry from the internal notifications list.

The function takes a callback to execute when such notification occurs and returns the ulConnection identifier we can use in further management.

Returns
MAPI_E_SUCCESS on success, otherwise MAPI error.
Note
Developers may also call GetLastError() to retrieve the last MAPI error code. Possible MAPI error codes are:
  • MAPI_E_NOT_INITIALIZED: MAPI subsystem has not been initialized
  • MAPI_E_CALL_FAILED: A network problem was encountered during the transaction
See Also
RegisterNotification, Subscribe, MonitorNotification, GetLastError

References Release().


Creative Commons License
Creative Commons Attribution icon Creative Commons Share Alike icon
This content is licensed under the Creative Commons
Attribution ShareAlike License v. 3.0:
http://creativecommons.org/licenses/by-sa/3.0/

openchange-2.0/apidocs/html/libmapi/IMAPITable_8c.html000066400000000000000000001775161223057412600225770ustar00rootroot00000000000000 MAPIClientLibraries 2.0 API Documentation
IMAPITable.c File Reference

Operations on tables. More...

#include "libmapi/libmapi.h"
#include "libmapi/libmapi_private.h"

Functions

_PUBLIC_ enum MAPISTATUS Abort (mapi_object_t *obj_table, uint8_t *TableStatus)
_PUBLIC_ enum MAPISTATUS CollapseRow (mapi_object_t *obj_table, uint64_t categoryId, uint32_t *rowCount)
_PUBLIC_ enum MAPISTATUS CreateBookmark (mapi_object_t *obj_table, uint32_t *lpbkPosition)
_PUBLIC_ enum MAPISTATUS ExpandRow (mapi_object_t *obj_table, uint64_t categoryId, uint16_t maxRows, struct SRowSet *rowData, uint32_t *expandedRowCount)
_PUBLIC_ enum MAPISTATUS FindRow (mapi_object_t *obj_table, struct mapi_SRestriction *res, enum BOOKMARK bkOrigin, enum FindRow_ulFlags ulFlags, struct SRowSet *SRowSet)
_PUBLIC_ enum MAPISTATUS FreeBookmark (mapi_object_t *obj_table, uint32_t bkPosition)
uint32_t get_mapi_SRestriction_size (struct mapi_SRestriction *res)
_PUBLIC_ enum MAPISTATUS GetCollapseState (mapi_object_t *obj_table, uint64_t rowId, uint32_t rowInstanceNumber, struct SBinary_short *CollapseState)
_PUBLIC_ enum MAPISTATUS GetStatus (mapi_object_t *obj_table, uint8_t *TableStatus)
_PUBLIC_ enum MAPISTATUS QueryColumns (mapi_object_t *obj_table, struct SPropTagArray *cols)
_PUBLIC_ enum MAPISTATUS QueryPosition (mapi_object_t *obj_table, uint32_t *Numerator, uint32_t *Denominator)
_PUBLIC_ enum MAPISTATUS QueryRows (mapi_object_t *obj_table, uint16_t row_count, enum QueryRowsFlags flags, struct SRowSet *rowSet)
_PUBLIC_ enum MAPISTATUS Reset (mapi_object_t *obj_table)
_PUBLIC_ enum MAPISTATUS Restrict (mapi_object_t *obj_table, struct mapi_SRestriction *res, uint8_t *TableStatus)
_PUBLIC_ enum MAPISTATUS SeekRow (mapi_object_t *obj_table, enum BOOKMARK origin, int32_t offset, uint32_t *row)
_PUBLIC_ enum MAPISTATUS SeekRowApprox (mapi_object_t *obj_table, uint32_t ulNumerator, uint32_t ulDenominator)
_PUBLIC_ enum MAPISTATUS SeekRowBookmark (mapi_object_t *obj_table, uint32_t lpbkPosition, uint32_t RowCount, uint32_t *row)
_PUBLIC_ enum MAPISTATUS SetCollapseState (mapi_object_t *obj_table, struct SBinary_short *CollapseState)
_PUBLIC_ enum MAPISTATUS SetColumns (mapi_object_t *obj_table, struct SPropTagArray *properties)
_PUBLIC_ enum MAPISTATUS SortTable (mapi_object_t *obj_table, struct SSortOrderSet *lpSortCriteria)

Detailed Description

Operations on tables.

Function Documentation

_PUBLIC_ enum MAPISTATUS Abort ( mapi_object_t *  obj_table,
uint8_t *  TableStatus 
)

Aborts an asynchronous table operation in progress

Parameters
obj_tablethe table object where we want to abort an asynchronous operation
TableStatuspointer on the table status returned by the operation
Returns
MAPI_E_SUCCESS on success, otherwise MAPI error.
Note
Developers may also call GetLastError() to retrieve the last MAPI error code. Possible MAPI error codes are:
  • MAPI_E_NOT_INITIALIZED: MAPI subsystem has not been initialized
  • MAPI_E_INVALID_PARAMETER: obj_table or TableStatus are null
  • MAPI_E_CALL_FAILED: A network problem was encountered during the transaction

References mapi_object_get_handle(), mapi_object_get_logon_id(), and mapi_object_get_session().

_PUBLIC_ enum MAPISTATUS CollapseRow ( mapi_object_t *  obj_table,
uint64_t  categoryId,
uint32_t *  rowCount 
)

Collapse an expanded row in a table

After a contents table has been sorted and categorized using SortTable, rows can be expanded and collapsed (using ExpandRow and CollapseRow repectively).

Parameters
obj_tablethe table we are collapsing the category in.
categoryIdthe row identification for the heading row for the category being collapsed.
rowCount(result) the number of rows that were removed from the table when the row was collapsed.

You obtain the categoryId argument from the PR_INST_ID property of the heading row for the category that is being collapsed.

If you pass rowCount as null, the number of rows will not be returned.

Returns
MAPI_E_SUCCESS on success, otherwise MAPI error.
Note
Developers may also call GetLastError() to retrieve the last MAPI error code. Possible MAPI error codes are:
  • MAPI_E_NOT_INITIALIZED: MAPI subsystem has not been initialized
  • MAPI_E_INVALID_PARAMETER: obj_table is NULL
  • MAPI_E_CALL_FAILED: A network problem was encountered during the transaction
See Also
ExpandRow

References mapi_object_get_handle(), mapi_object_get_logon_id(), and mapi_object_get_session().

_PUBLIC_ enum MAPISTATUS CreateBookmark ( mapi_object_t *  obj_table,
uint32_t *  lpbkPosition 
)

Marks the table current position

Parameters
obj_tablethe table we are creating a bookmark in
lpbkPositionpointer to the bookmark value. This bookmark can be passed in a call to the SeekRowBookmark method
Returns
MAPI_E_SUCCESS on success, otherwise MAPI error.
Note
Developers may also call GetLastError() to retrieve the last MAPI error code. Possible MAPI error codes are:
  • MAPI_E_NOT_INITIALIZED: MAPI subsystem has not been initialized
  • MAPI_E_INVALID_PARAMETER: obj_table is NULL
  • MAPI_E_CALL_FAILED: A network problem was encountered during the transaction
See Also
SeekRowBookmark, FreeBookmark

References mapi_object_get_handle(), mapi_object_get_logon_id(), and mapi_object_get_session().

_PUBLIC_ enum MAPISTATUS ExpandRow ( mapi_object_t *  obj_table,
uint64_t  categoryId,
uint16_t  maxRows,
struct SRowSet *  rowData,
uint32_t *  expandedRowCount 
)

Expand a collapsed row in a table

After a contents table has been sorted and categorized using SortTable, rows can be expanded and collapsed (using ExpandRow and CollapseRow repectively).

Parameters
obj_tablethe table we are collapsing the category in.
categoryIdthe row identification for the heading row for the category being expanded.
maxRowsthe maximum number of rows to retrieve (can be zero)
rowData(result) the data rows under this category heading
expandedRowCount(result) the number of rows that were added to the table when the row was expanded

You obtain the categoryId argument from the PR_INST_ID property of the heading row for the category that is being collapsed.

The maxRows argument specifies the upper limit on how many rows to return (as rowData) when the category is expanded. The expandedRowCount argument returns the number of rows that were added to the table. As an example, consider a collapsed category with 8 entries. If you set maxRows to 3, then rowData will contain the data for the first three rows, and expandedRowCount will be set to 8. If you now use QueryRows(), you can read the 5 additional rows. If you'd specified maxRows as 8 (or more), rowData would have contained all 8 rows and expandedRowCount still would have been 8.

Returns
MAPI_E_SUCCESS on success, otherwise MAPI error.
Note
Developers may also call GetLastError() to retrieve the last MAPI error code. Possible MAPI error codes are:
  • MAPI_E_NOT_INITIALIZED: MAPI subsystem has not been initialized
  • MAPI_E_INVALID_PARAMETER: obj_table, rowData or rowCount are NULL
  • MAPI_E_CALL_FAILED: A network problem was encountered during the transaction
See Also
CollapseRow

References emsmdb_get_SRowSet(), mapi_object_get_handle(), mapi_object_get_logon_id(), and mapi_object_get_session().

_PUBLIC_ enum MAPISTATUS FindRow ( mapi_object_t *  obj_table,
struct mapi_SRestriction *  res,
enum BOOKMARK  bkOrigin,
enum FindRow_ulFlags  ulFlags,
struct SRowSet *  SRowSet 
)

Find the next row in a table that matches specific search criteria

Parameters
obj_tablethe table we are searching in
respointer on search criterias
bkOriginbookmark identifying the row where FindRow should begin
ulFlagscontrols the direction of the search
SRowSetthe resulting row

bkOrigin can either take the value of a bookmark created with CreateBookmark or any of the default values:

  • BOOKMARK_BEGINNING
  • BOOKMARK_CURRENT
  • BOOKMARK_END

ulFlags can be set either to DIR_FORWARD (0x0) or DIR_BACKWARD (0x1).

Returns
MAPI_E_SUCCESS on success, otherwise MAPI error.
Note
Developers may also call GetLastError() to retrieve the last MAPI error code. Possible MAPI error codes are:
  • MAPI_E_NOT_INITIALIZED: MAPI subsystem has not been initialized
  • MAPI_E_INVALID_PARAMETER: obj_table is NULL
  • MAPI_E_INVALID_BOOKMARK: the bookmark specified is invalid or beyond the last row requested.
  • MAPI_E_CALL_FAILED: A network problem was encountered during the transaction
See Also
CreateBookmark

References emsmdb_get_SRowSet(), get_mapi_SRestriction_size(), mapi_object_bookmark_find(), mapi_object_get_handle(), mapi_object_get_logon_id(), and mapi_object_get_session().

Referenced by GetUserFreeBusyData().

_PUBLIC_ enum MAPISTATUS FreeBookmark ( mapi_object_t *  obj_table,
uint32_t  bkPosition 
)

Release the resources associated with a bookmark

Parameters
obj_tablethe table the bookmark is associated to
bkPositionthe bookmark to be freed
Returns
MAPI_E_SUCCESS on success, otherwise MAPI error.
Note
Developers may also call GetLastError() to retrieve the last MAPI error code. Possible MAPI error codes are:
  • MAPI_E_NOT_INITIALIZED: MAPI subsystem has not been initialized
  • MAPI_E_INVALID_PARAMETER: obj_table is NULL
  • MAPI_E_INVALID_BOOKMARK: The bookmark specified is invalid or beyond the last row requested
  • MAPI_E_CALL_FAILED: A network problem was encountered during the transaction
See Also
CreateBookmark

References mapi_object_get_handle(), mapi_object_get_logon_id(), mapi_object_get_session(), and MAPIFreeBuffer().

uint32_t get_mapi_SRestriction_size ( struct mapi_SRestriction *  res)

Get the size associated to a mapi SRestriction

Parameters
respointer on the mapi_SRestriction
Returns
mapi_SRestriction size

Referenced by FindRow(), Restrict(), and SetSearchCriteria().

_PUBLIC_ enum MAPISTATUS GetCollapseState ( mapi_object_t *  obj_table,
uint64_t  rowId,
uint32_t  rowInstanceNumber,
struct SBinary_short *  CollapseState 
)

Get the Collapse State of a Table

After a contents table has been sorted and categorized using SortTable, rows can be expanded and collapsed (using ExpandRow() and CollapseRow() repectively). You can save the state of the table using this function, and restore it using SetCollapseState.

Parameters
obj_tablethe table we are retrieving the state from
rowIdthe row number for the cursor
rowInstanceNumberthe instance number for the cursor
CollapseState(result) the returned table Collapse State

You obtain the row number and row instance number arguments from the PR_INST_ID and PR_INST_NUM properties of the row you want to use as the cursor.

Returns
MAPI_E_SUCCESS on success, otherwise MAPI error.
Note
Developers may also call GetLastError() to retrieve the last MAPI error code. Possible MAPI error codes are:
  • MAPI_E_NOT_INITIALIZED: MAPI subsystem has not been initialized
  • MAPI_E_INVALID_PARAMETER: obj_table or CollapseState are null
  • MAPI_E_CALL_FAILED: A network problem was encountered during the transaction
See Also
SetCollapseState

References mapi_object_get_handle(), mapi_object_get_logon_id(), and mapi_object_get_session().

_PUBLIC_ enum MAPISTATUS GetStatus ( mapi_object_t *  obj_table,
uint8_t *  TableStatus 
)

Get the status of a table

Parameters
obj_tablethe table we are retrieving the status from
TableStatusthe table status result

TableStatus can either hold:

  • TBLSTAT_COMPLETE (0x0)
  • TBLSTAT_SORTING (0x9)
  • TBLSTAT_SORT_ERROR (0xA)
  • TBLSTAT_SETTING_COLS (0xB)
  • TBLSTAT_SETCOL_ERROR (0xD)
  • TBLSTAT_RESTRICTING (0xE)
  • TBLSTAT_RESTRICT_ERROR (0xF)
Returns
MAPI_E_SUCCESS on success, otherwise MAPI error.
Note
Developers may also call GetLastError() to retrieve the last MAPI error code. Possible MAPI error codes are:
  • MAPI_E_NOT_INITIALIZED: MAPI subsystem has not been initialized
  • MAPI_E_INVALID_PARAMETER: obj_table is NULL
  • MAPI_E_INVALID_BOOKMARK: the bookmark specified is invalid or beyond the last row requested.
  • MAPI_E_CALL_FAILED: A network problem was encountered during the transaction
See Also
SetColumns, Restrict, FindRow, GetHierarchyTable, GetContentsTable

References mapi_object_get_handle(), mapi_object_get_logon_id(), and mapi_object_get_session().

_PUBLIC_ enum MAPISTATUS QueryColumns ( mapi_object_t *  obj_table,
struct SPropTagArray *  cols 
)

Retrieves the set of columns defined in the current table view

Parameters
obj_tablethe table we are retrieving columns from
colspointer to an array of property tags
Returns
MAPI_E_SUCCESS on success, otherwise MAPI error.
Note
Developers may also call GetLastError() to retrieve the last MAPI error code. Possible MAPI error codes are:
  • MAPI_E_NOT_INITIALIZED: MAPI subsystem has not been initialized
  • MAPI_E_INVALID_PARAMETER: obj_table is NULL
  • MAPI_E_CALL_FAILED: A network problem was encountered during the transaction
See Also
SetColumns, QueryRows

References mapi_object_get_handle(), mapi_object_get_logon_id(), and mapi_object_get_session().

_PUBLIC_ enum MAPISTATUS QueryPosition ( mapi_object_t *  obj_table,
uint32_t *  Numerator,
uint32_t *  Denominator 
)

Returns the approximate cursor position

Parameters
obj_tablepointer to the table's object
Numeratorpointer to the numerator of the fraction identifying the table position
Denominatorpointer to the denominator of the fraction identifying the table position
Returns
MAPI_E_SUCCESS on success, otherwise MAPI error.
Note
Developers may also call GetLastError() to retrieve the last MAPI error code. Possible MAPI error codes are:
  • MAPI_E_NOT_INITIALIZED: MAPI subsystem has not been initialized
  • MAPI_E_INVALID_PARAMETER: obj_table is NULL
  • MAPI_E_CALL_FAILED: A network problem was encountered during the transaction
See Also
QueryRows
Examples:
fetchappointment.c, and fetchmail.c.

References mapi_object_get_handle(), mapi_object_get_logon_id(), and mapi_object_get_session().

Referenced by ModifyUserPermission(), and RemoveUserPermission().

_PUBLIC_ enum MAPISTATUS QueryRows ( mapi_object_t *  obj_table,
uint16_t  row_count,
enum QueryRowsFlags  flags,
struct SRowSet *  rowSet 
)

Returns a RowSet with the properties returned by the server

Parameters
obj_tablethe table we are requesting properties from
row_countthe maximum number of rows to retrieve
flagsflags to use for the query
rowSetthe results

flags possible values:

  • TBL_ADVANCE: index automatically increased from last rowcount
  • TBL_NOADVANCE: should be used for a single QueryRows call
  • TBL_ENABLEPACKEDBUFFERS: (not yet implemented)
Returns
MAPI_E_SUCCESS on success, otherwise MAPI error.
Note
Developers may also call GetLastError() to retrieve the last MAPI error code. Possible MAPI error codes are:
  • MAPI_E_NOT_INITIALIZED: MAPI subsystem has not been initialized
  • MAPI_E_INVALID_PARAMETER: obj_table is NULL
  • MAPI_E_CALL_FAILED: A network problem was encountered during the transaction
See Also
SetColumns, QueryPosition, QueryColumns, SeekRow
Examples:
fetchappointment.c, and fetchmail.c.

References emsmdb_get_SRowSet(), mapi_object_get_handle(), mapi_object_get_logon_id(), and mapi_object_get_session().

Referenced by ModifyUserPermission(), and RemoveUserPermission().

_PUBLIC_ enum MAPISTATUS Reset ( mapi_object_t *  obj_table)

Removes all filters that are currently on a table

Parameters
obj_tablethe table object to reset
Returns
MAPI_E_SUCCESS on success, otherwise MAPI error.
Note
Developers may also call GetLastError() to retrieve the last MAPI error code. Possible MAPI error codes are:
  • MAPI_E_NOT_INITIALIZED: MAPI subsystem has not been initialized
  • MAPI_E_INVALID_PARAMETER: obj_table is NULL
  • MAPI_E_CALL_FAILED: A network problem was encountered during the transaction
See Also
Restrict

References mapi_object_get_handle(), mapi_object_get_logon_id(), and mapi_object_get_session().

_PUBLIC_ enum MAPISTATUS Restrict ( mapi_object_t *  obj_table,
struct mapi_SRestriction *  res,
uint8_t *  TableStatus 
)

Applies a filter to a table, reducing the row set to only those rows matching the specified criteria.

Parameters
obj_tablethe object we are filtering
resthe filters we want to apply
TableStatusthe table status result

TableStatus can either hold:

  • TBLSTAT_COMPLETE (0x0)
  • TBLSTAT_SORTING (0x9)
  • TBLSTAT_SORT_ERROR (0xA)
  • TBLSTAT_SETTING_COLS (0xB)
  • TBLSTAT_SETCOL_ERROR (0xD)
  • TBLSTAT_RESTRICTING (0xE)
  • TBLSTAT_RESTRICT_ERROR (0xF)

Unlike MAPI, you don't pass a null restriction argument to remove the current restrictions. Use Reset() instead.

TableStatus should be set to NULL if you don't want to retrieve the status of the table.

Returns
MAPI_E_SUCCESS on success, otherwise MAPI error.
Note
Developers may also call GetLastError() to retrieve the last MAPI error code. Possible MAPI error codes are:
  • MAPI_E_NOT_INITIALIZED: MAPI subsystem has not been initialized
  • MAPI_E_INVALID_PARAMETER: obj_table is NULL
  • MAPI_E_CALL_FAILED: A network problem was encountered during the transaction
See Also
QueryRows, Reset

References get_mapi_SRestriction_size(), mapi_object_get_handle(), mapi_object_get_logon_id(), and mapi_object_get_session().

_PUBLIC_ enum MAPISTATUS SeekRow ( mapi_object_t *  obj_table,
enum BOOKMARK  origin,
int32_t  offset,
uint32_t *  row 
)

Move the table cursor at a specific location

Parameters
obj_tablethe table we are moving cursor on
originthe table position where we start to seek
offseta particular offset in the table
rowthe position of the seeked row is returned in rows

origin possible values:

  • BOOKMARK_BEGINNING: Beginning of the table
  • BOOKMARK_CURRENT: Current position in the table
  • BOKMARK_END: End of the table
Returns
MAPI_E_SUCCESS on success, otherwise MAPI error.
Note
Developers may also call GetLastError() to retrieve the last MAPI error code. Possible MAPI error codes are:
  • MAPI_E_NOT_INITIALIZED: MAPI subsystem has not been initialized
  • MAPI_E_INVALID_PARAMETER: obj_table is NULL
  • MAPI_E_CALL_FAILED: A network problem was encountered during the transaction
See Also
SetColumns, QueryRows

References mapi_object_get_handle(), mapi_object_get_logon_id(), and mapi_object_get_session().

_PUBLIC_ enum MAPISTATUS SeekRowApprox ( mapi_object_t *  obj_table,
uint32_t  ulNumerator,
uint32_t  ulDenominator 
)

Moves the cursor to an approximate fractional position in the table

Parameters
obj_tablethe table we are moving cursor on
ulNumeratornumerator of the fraction representing the table position.
ulDenominatordenominator of the fraction representing the table position
  • If ulDenominator is NULL, then SeekRowApprox returns MAPI_E_INVALID_PARAMETER.
  • If ulNumerator is NULL, then SeekRowApprox moves the cursor to the beginning of the table. In such situation, SeekRowApprox call is similar to SeekRow with BOOKMARK_BEGINNING
  • If ulNumerator and ulDenominator have the same value, then SeekRowApprox moves the cursor to the end of the table. In such situation, SeekRowApprox call is similar to SeekRow with BOOKMARK_END
Returns
MAPI_E_SUCCESS on success, otherwise MAPI error.
Note
Developers may also call GetLastError() to retrieve the last MAPI error code. Possible MAPI error codes are:
  • MAPI_E_NOT_INITIALIZED: MAPI subsystem has not been initialized
  • MAPI_E_INVALID_PARAMETER: obj_table is NULL
  • MAPI_E_CALL_FAILED: A network problem was encountered during the transaction
See Also
SeekRow, SeekRowBookmark

References mapi_object_get_handle(), mapi_object_get_logon_id(), and mapi_object_get_session().

_PUBLIC_ enum MAPISTATUS SeekRowBookmark ( mapi_object_t *  obj_table,
uint32_t  lpbkPosition,
uint32_t  RowCount,
uint32_t *  row 
)

Move the table cursor at a specific location given a bookmark

Parameters
obj_tablethe table we are moving cursor on
lpbkPositionthe bookmarked position
RowCounta relative number of rows to the bookmark
rowthe position of the seeked row is returned in rows
Returns
MAPI_E_SUCCESS on success, otherwise MAPI error.
Note
Developers may also call GetLastError() to retrieve the last MAPI error code. Possible MAPI error codes are:
  • MAPI_E_NOT_INITIALIZED: MAPI subsystem has not been initialized
  • MAPI_E_INVALID_PARAMETER: obj_table is NULL
  • MAPI_E_INVALID_BOOKMARK: The bookmark specified is invalid or beyond the last row requested
  • MAPI_E_CALL_FAILED: A network problem was encountered during the transaction
See Also
CreateBookmark, FreeBookmark

References mapi_object_bookmark_find(), mapi_object_get_handle(), mapi_object_get_logon_id(), and mapi_object_get_session().

_PUBLIC_ enum MAPISTATUS SetCollapseState ( mapi_object_t *  obj_table,
struct SBinary_short *  CollapseState 
)

Set the Collapse State of a Table

After a contents table has been sorted and categorized using SortTable, rows can be expanded and collapsed (using ExpandRow() and CollapseRow() repectively). You can save the state of the table using GetCollapseState, and restore it using this function.

Parameters
obj_tablethe table we are restoring the state for
CollapseStatethe Collapse State to restore
Returns
MAPI_E_SUCCESS on success, otherwise MAPI error.
Note
Developers may also call GetLastError() to retrieve the last MAPI error code. Possible MAPI error codes are:
  • MAPI_E_NOT_INITIALIZED: MAPI subsystem has not been initialized
  • MAPI_E_INVALID_PARAMETER: obj_table or CollapseState are null
  • MAPI_E_CALL_FAILED: A network problem was encountered during the transaction
See Also
GetCollapseState

References mapi_object_get_handle(), mapi_object_get_logon_id(), and mapi_object_get_session().

_PUBLIC_ enum MAPISTATUS SetColumns ( mapi_object_t *  obj_table,
struct SPropTagArray *  properties 
)

Defines the particular properties and order of properties to appear as columns in the table.

Parameters
obj_tablethe table the function is setting columns for
propertiesthe properties intended to be set
Returns
MAPI_E_SUCCESS on success, otherwise MAPI error.
Note
Developers may also call GetLastError() to retrieve the last MAPI error code. Possible MAPI error codes are:
  • MAPI_E_NOT_INITIALIZED: MAPI subsystem has not been initialized
  • MAPI_E_INVALID_PARAMETER: obj_table is NULL
  • MAPI_W_ERROR_RETURNED: Problem encountered while trying to set one or more properties
  • MAPI_E_CALL_FAILED: A network problem was encountered during the transaction
See Also
QueryRows, QueryColumns, SeekRow, GetLastError
Examples:
fetchappointment.c, and fetchmail.c.

References mapi_object_get_handle(), mapi_object_get_logon_id(), and mapi_object_get_session().

Referenced by GetUserFreeBusyData(), ModifyUserPermission(), and RemoveUserPermission().

_PUBLIC_ enum MAPISTATUS SortTable ( mapi_object_t *  obj_table,
struct SSortOrderSet *  lpSortCriteria 
)

Order the rows of the table based on a criteria

Parameters
obj_tablethe table we are ordering rows on
lpSortCriteriapointer on sort criterias to apply
Returns
MAPI_E_SUCCESS on success, otherwise MAPI error.
Note
Developers may also call GetLastError() to retrieve the last MAPI error code. Possible MAPI error codes are:
  • MAPI_E_NOT_INITIALIZED: MAPI subsystem has not been initialized
  • MAPI_E_INVALID_PARAMETER: obj_table or lpSortCriteria is NULL
  • MAPI_E_CALL_FAILED: A network problem was encountered during the transaction

References mapi_object_get_handle(), mapi_object_get_logon_id(), and mapi_object_get_session().

Referenced by GetUserFreeBusyData().


Creative Commons License
Creative Commons Attribution icon Creative Commons Share Alike icon
This content is licensed under the Creative Commons
Attribution ShareAlike License v. 3.0:
http://creativecommons.org/licenses/by-sa/3.0/

openchange-2.0/apidocs/html/libmapi/IMSProvider_8c.html000066400000000000000000000367731223057412600231320ustar00rootroot00000000000000 MAPIClientLibraries 2.0 API Documentation
IMSProvider.c File Reference

Provider operations. More...

#include "libmapi/libmapi.h"

Functions

enum MAPISTATUS GetNewLogonId (struct mapi_session *session, uint8_t *logon_id)
_PUBLIC_ enum MAPISTATUS Logoff (mapi_object_t *obj_store)
_PUBLIC_ enum MAPISTATUS RegisterAsyncNotification (struct mapi_session *session, uint32_t *resultFlag)
_PUBLIC_ enum MAPISTATUS RegisterNotification (struct mapi_session *session)
_PUBLIC_ enum MAPISTATUS RfrGetFQDNFromLegacyDN (struct mapi_context *mapi_ctx, struct mapi_session *session, const char **serverFQDN)
_PUBLIC_ enum MAPISTATUS RfrGetNewDSA (struct mapi_context *mapi_ctx, struct mapi_session *session, const char *server, const char *userDN, char **dsa)

Detailed Description

Provider operations.

Function Documentation

enum MAPISTATUS GetNewLogonId ( struct mapi_session *  session,
uint8_t *  logon_id 
)

Retrieve a free logon identifier within the session

Parameters
sessionpointer to the MAPI session context
logon_idpointer to the logon identifier the function returns
Returns
MAPI_E_SUCCESS on success, otherwise MAPI eorr

Referenced by OpenPublicFolder(), and OpenUserMailbox().

_PUBLIC_ enum MAPISTATUS Logoff ( mapi_object_t *  obj_store)

Logoff an Exchange store

This function uninitializes the MAPI session associated to the object.

Parameters
obj_storepointer to the store object
Returns
MAPI_E_SUCCESS on success, otherwise MAPI_E_NOT_FOUND
Examples:
fetchappointment.c, and fetchmail.c.

References mapi_object_get_session(), mapi_object_release(), and MAPIFreeBuffer().

_PUBLIC_ enum MAPISTATUS RegisterAsyncNotification ( struct mapi_session *  session,
uint32_t *  resultFlag 
)

Create an asynchronous notification

This function initializes the notification subsystem and configures the server to send notifications. Note that this call will block.

Parameters
sessionthe session context to register for notifications on.
resultFlagthe result of the operation (true if there was anything returned)
Returns
MAPI_E_SUCCESS on success, otherwise MAPI error.
Note
Developers may also call GetLastError() to retrieve the last MAPI error code. Possible MAPI error codes are:
  • MAPI_E_NOT_INITIALIZED: MAPI subsystem has not been initialized
  • MAPI_E_CALL_FAILED: A network problem was encountered during the transaction
See Also
RegisterNotification

References emsmdb_async_waitex().

_PUBLIC_ enum MAPISTATUS RegisterNotification ( struct mapi_session *  session)

Initialize the notification subsystem

This function initializes the notification subsystem, binds a local UDP port to receive Exchange (server side) notifications and configures the server to send notifications on this port.

Parameters
sessionthe session context to register for notifications on.
Returns
MAPI_E_SUCCESS on success, otherwise MAPI error.
Note
Developers may also call GetLastError() to retrieve the last MAPI error code. Possible MAPI error codes are:
  • MAPI_E_NOT_INITIALIZED: MAPI subsystem has not been initialized
  • MAPI_E_CALL_FAILED: A network problem was encountered during the transaction
See Also
RegisterAsyncNotification, Subscribe, Unsubscribe, MonitorNotification, GetLastError

References emsmdb_bind_notification(), and emsmdb_register_notification().

_PUBLIC_ enum MAPISTATUS RfrGetFQDNFromLegacyDN ( struct mapi_context *  mapi_ctx,
struct mapi_session *  session,
const char **  serverFQDN 
)

Returns the FQDN of the NSPI server corresponding to a DN

Parameters
mapi_ctxpointer to the MAPI context
sessionpointer to the MAPI session context
serverFQDNpointer to the server FQDN string (return value)
Returns
MAPI_E_SUCCESS on success, otherwise a MAPI error and serverFQDN content set to NULL.
_PUBLIC_ enum MAPISTATUS RfrGetNewDSA ( struct mapi_context *  mapi_ctx,
struct mapi_session *  session,
const char *  server,
const char *  userDN,
char **  dsa 
)

Returns the name of an NSPI server

Parameters
mapi_ctxpointer to the MAPI context
sessionpointer to the MAPI session context
serverthe Exchange server address (IP or FQDN)
userDNoptional user mailbox DN
dsapointer to a new dsa (return value), containing a valid allocated string on success, otherwise NULL
Returns
MAPI_E_SUCCESS on success, otherwise a MAPI error and serverFQDN content set to NULL.
Note
The string returned can either be RfrGetNewDSA one on success, or a copy of the server's argument one on failure. If no server string is provided, NULL is returned.

It is up to the developer to free the returned string when not needed anymore.


Creative Commons License
Creative Commons Attribution icon Creative Commons Share Alike icon
This content is licensed under the Creative Commons
Attribution ShareAlike License v. 3.0:
http://creativecommons.org/licenses/by-sa/3.0/

openchange-2.0/apidocs/html/libmapi/IMessage_8c.html000066400000000000000000001571221223057412600224540ustar00rootroot00000000000000 MAPIClientLibraries 2.0 API Documentation
IMessage.c File Reference

Operations on messages. More...

#include "libmapi/libmapi.h"
#include "libmapi/libmapi_private.h"

Functions

_PUBLIC_ enum MAPISTATUS AbortSubmit (mapi_object_t *obj_store, mapi_object_t *obj_folder, mapi_object_t *obj_message)
_PUBLIC_ enum MAPISTATUS CreateAttach (mapi_object_t *obj_message, mapi_object_t *obj_attach)
_PUBLIC_ enum MAPISTATUS DeleteAttach (mapi_object_t *obj_message, uint32_t AttachmentID)
_PUBLIC_ enum MAPISTATUS GetAttachmentTable (mapi_object_t *obj_message, mapi_object_t *obj_table)
_PUBLIC_ enum MAPISTATUS GetRecipientTable (mapi_object_t *obj_message, struct SRowSet *SRowSet, struct SPropTagArray *SPropTagArray)
_PUBLIC_ enum MAPISTATUS GetValidAttach (mapi_object_t *obj_message, uint16_t *NumAttachments, uint32_t **AttachmentIds)
uint16_t mapi_recipients_RecipientFlags (struct SRow *aRow)
_PUBLIC_ enum MAPISTATUS ModifyRecipients (mapi_object_t *obj_message, struct SRowSet *SRowSet)
_PUBLIC_ enum MAPISTATUS OpenAttach (mapi_object_t *obj_message, uint32_t AttachmentID, mapi_object_t *obj_attach)
_PUBLIC_ enum MAPISTATUS OpenEmbeddedMessage (mapi_object_t *obj_attach, mapi_object_t *obj_embeddedmsg, enum OpenEmbeddedMessage_OpenModeFlags ulFlags)
_PUBLIC_ enum MAPISTATUS ReadRecipients (mapi_object_t *obj_message, uint32_t RowId, uint8_t *RowCount, struct ReadRecipientRow **RecipientRows)
_PUBLIC_ enum MAPISTATUS RemoveAllRecipients (mapi_object_t *obj_message)
_PUBLIC_ enum MAPISTATUS SaveChangesMessage (mapi_object_t *parent, mapi_object_t *obj_message, uint8_t SaveFlags)
_PUBLIC_ enum MAPISTATUS SetMessageReadFlag (mapi_object_t *obj_folder, mapi_object_t *obj_child, uint8_t flags)
_PUBLIC_ enum MAPISTATUS SetRecipientType (struct SRow *aRow, enum ulRecipClass RecipClass)
_PUBLIC_ enum MAPISTATUS SubmitMessage (mapi_object_t *obj_message)
_PUBLIC_ enum MAPISTATUS TransportSend (mapi_object_t *obj_message, struct mapi_SPropValue_array *lpProps)

Detailed Description

Operations on messages.

Function Documentation

_PUBLIC_ enum MAPISTATUS AbortSubmit ( mapi_object_t *  obj_store,
mapi_object_t *  obj_folder,
mapi_object_t *  obj_message 
)

Aborts a previous message submission.

Parameters
obj_storethe store object
obj_folderthe folder object where the message has been submitted
obj_messagethe submitted message object
Returns
MAPI_E_SUCCESS on success, otherwise MAPI error.
Note
Developers may also call GetLastError() to retrieve the last MAPI error code. Possible MAPI error codes are:
  • MAPI_E_NOT_INITIALIZED: MAPI subsystem has not been initialized
  • MAPI_E_CALL_FAILED: A network problem was encountered during the transaction
  • MAPI_E_UNABLE_TO_ABORT: The operation can not be aborted
  • MAPI_E_NOT_IN_QUEUE: The message is no longer in the message store's spooler queue
  • MAPI_E_NO_SUPPORT: the server object associated with the input handle index in the server object table is not of type Logon or the current logon session is a public logon.
See Also
SubmitMessage

References mapi_object_get_handle(), mapi_object_get_id(), mapi_object_get_logon_id(), and mapi_object_get_session().

_PUBLIC_ enum MAPISTATUS CreateAttach ( mapi_object_t *  obj_message,
mapi_object_t *  obj_attach 
)

Create a new attachment

This function creates a new attachment to an existing message.

Parameters
obj_messagethe message to attach to
obj_attachthe attachment

Both objects need to exist before you call this message. obj_message should be a valid message on the server. obj_attach needs to be initialised.

enum MAPISTATUS retval;
mapi_object_t obj_message;
mapi_object_t obj_attach;
... open or create the obj_message ...
mapi_object_init(&obj_attach);
retval = CreateAttach(&obj_message, &obj_attach);
... check the return value ...
... use SetProps() to set the attachment up ...
... perhaps OpenStream() / WriteStream() / CommitStream() on obj_attach ...
// Save the changes to the attachment and then the message
retval = SaveChangesAttachment(&obj_message, &obj_attach, KeepOpenReadOnly);
... check the return value ...
retval = SaveChangesMessage(&obj_folder, &obj_message, KeepOpenReadOnly);
... check the return value ...
Returns
MAPI_E_SUCCESS on success, otherwise MAPI error.
Note
Developers may also call GetLastError() to retrieve the last MAPI error code. Possible MAPI error codes are:
  • MAPI_E_NOT_INITIALIZED: MAPI subsystem has not been initialized
  • MAPI_E_CALL_FAILED: A network problem was encountered during the transaction
See Also
CreateMessage, GetAttachmentTable, OpenAttach, GetLastError

References mapi_object_get_handle(), mapi_object_get_logon_id(), mapi_object_get_session(), mapi_object_set_handle(), mapi_object_set_logon_id(), and mapi_object_set_session().

_PUBLIC_ enum MAPISTATUS DeleteAttach ( mapi_object_t *  obj_message,
uint32_t  AttachmentID 
)

Delete an attachment from a message

This function deletes one attachment from a message. The attachment to be deleted is specified by its PR_ATTACH_NUM

Parameters
obj_messagethe message to operate on
AttachmentIDthe attachment number
Returns
MAPI_E_SUCCESS on success, otherwise MAPI error.
Note
Developers may also call GetLastError() to retrieve the last MAPI error code. Possible MAPI error codes are:
  • MAPI_E_NOT_INITIALIZED: MAPI subsystem has not been initialized
  • MAPI_E_CALL_FAILED: A network problem was encountered during the transaction
See Also
CreateMessage, GetAttachmentTable, GetLastError

References mapi_object_get_handle(), mapi_object_get_logon_id(), and mapi_object_get_session().

_PUBLIC_ enum MAPISTATUS GetAttachmentTable ( mapi_object_t *  obj_message,
mapi_object_t *  obj_table 
)

Retrieve the attachment table for a message

Parameters
obj_messagethe message
obj_tablethe attachment table for the message
Returns
MAPI_E_SUCCESS on success, otherwise MAPI error.
Note
Developers may also call GetLastError() to retrieve the last MAPI error code. Possible MAPI error codes are:
  • MAPI_E_NOT_INITIALIZED: MAPI subsystem has not been initialized
  • MAPI_E_CALL_FAILED: A network problem was encountered during the transaction
See Also
CreateMessage, OpenMessage, CreateAttach, OpenAttach, GetLastError

References mapi_object_get_handle(), mapi_object_get_logon_id(), mapi_object_get_session(), mapi_object_set_handle(), mapi_object_set_logon_id(), and mapi_object_set_session().

_PUBLIC_ enum MAPISTATUS GetRecipientTable ( mapi_object_t *  obj_message,
struct SRowSet *  SRowSet,
struct SPropTagArray *  SPropTagArray 
)

Returns the message recipient table

Parameters
obj_messagethe message to receive recipients from
SRowSetpointer to the recipient table
SPropTagArraypointer to the array of properties listed in the recipient table
Returns
MAPI_E_SUCCESS on success, otherwise MAPI error.
Note
Developers may also call GetLastError() to retrieve the last MAPI error code. Possible MAPI error codes are:
  • MAPI_E_NOT_INITIALIZED: MAPI subsystem has not been initialized
See Also
OpenMessage
_PUBLIC_ enum MAPISTATUS GetValidAttach ( mapi_object_t *  obj_message,
uint16_t *  NumAttachments,
uint32_t **  AttachmentIds 
)

Get the valid attachment IDs for a message

This function returns the list of valid attachment IDs for a message. You can then use these IDs with the OpenAttach and DeleteAttach functions.

Parameters
obj_messagethe message to operate on
NumAttachmentsthe number of attachments for the message
AttachmentIdsarray of attachment Ids

The AttachmentIds array has NumAttachments elements.

Returns
MAPI_E_SUCCESS on success, otherwise MAPI error.
Note
Developers may also call GetLastError() to retrieve the last MAPI error code. Possible MAPI error codes are:
  • MAPI_E_NOT_INITIALIZED: MAPI subsystem has not been initialized
  • MAPI_E_INVALID_PARAMETER: a parameter is incorrect (e.g. null pointer)
  • MAPI_E_CALL_FAILED: A network problem was encountered during the transaction
See Also
OpenAttach, DeleteAttach

References mapi_object_get_handle(), mapi_object_get_logon_id(), and mapi_object_get_session().

uint16_t mapi_recipients_RecipientFlags ( struct SRow *  aRow)

RecipientFlags bitmask calculation for RecipientRows structure.

Parameters
aRowpointer to the SRow structures with the properties to pass to ModifyRecipients.

According to MS-OXCDATA 2.9.3.1 RecipientFlags structure, the bitmask can be represented as the following:

0 3 4 5 6 7 8 9 10 11 15 16 +---—+—+—+—+—+—+—+—+—+-------—+—+ | Type | E | D | T | S | R | N | U | I | Reserved | O | +---—+—+—+—+—+—+—+—+—+-------—+—+

Type: (0x7 mask) 3-bit enumeration describing the Address Type (PR_ADDRTYPE) E: (0x8) Email address included (PR_SMTP_ADDRESS) D: (0x10) Display Name included (PR_DISPLAY_NAME) T: (0x20) Transmittable Display Name included (PR_TRANSMITTABLE_DISPLAY_NAME) S: (0x40) If Transmittable Display Name is the same than Display Name (D == T) R: (0x80) Different transport is responsible for delivery N: (0x100) Recipient does not support receiving Rich Text messages U: (0x200) If we are using Unicode properties I: (0x400) If Simple Display Name is included (PR_7BIT_DISPLAY_NAME) Reserved: Must be zero O: (0x8000) Non-standard address type is used

The PidTag property to bitmask mapping was unclear for some fields. mapiproxy between Outlook 2003 and Exchange 2010 has been used for this purpose.

For further information about PidTagAddressType, refer to [MS-OXCMAIL] section 2.1.1.9

Returns
uint16_t holding the RecipientFlags value. 0 is returned when an inconsistency or a failure occurs

Referenced by ModifyRecipients().

_PUBLIC_ enum MAPISTATUS ModifyRecipients ( mapi_object_t *  obj_message,
struct SRowSet *  SRowSet 
)

Adds, deletes or modifies message recipients

Parameters
obj_messagethe message to change the recipients for
SRowSetthe recipients to add
Returns
MAPI_E_SUCCESS on success, otherwise MAPI error.

When using this function, take care to ensure that the properties that are present on the first row in the rowset are also present in all the following rows. If any are missing, this function will suffer NDR errors. This includes making sure that any string properties are present in the same encoding (e.g. if you use PR_SMTP_ADDRESS_UNICODE on the first row, don't provide PR_SMTP_ADDRESS on subsequent rows).

Note
Developers may also call GetLastError() to retrieve the last MAPI error code. Possible MAPI error codes are:
  • MAPI_E_NOT_INITIALIZED: MAPI subsystem has not been initialized
  • MAPI_E_CALL_FAILED: A network problem was encountered during the transaction
Bug:
ModifyRecipients can only add recipients.
See Also
CreateMessage, ResolveNames, SetRecipientType, GetLastError

References cast_mapi_SPropValue(), get_utf8_utf16_conv_length(), mapi_object_get_handle(), mapi_object_get_logon_id(), mapi_object_get_session(), and mapi_recipients_RecipientFlags().

_PUBLIC_ enum MAPISTATUS OpenAttach ( mapi_object_t *  obj_message,
uint32_t  AttachmentID,
mapi_object_t *  obj_attach 
)

Open an attachment to a message

This function opens one attachment from a message. The attachment to be opened is specified by its PR_ATTACH_NUM.

Parameters
obj_messagethe message to operate on
AttachmentIDthe attachment number
obj_attachthe resulting attachment object
Returns
MAPI_E_SUCCESS on success, otherwise MAPI error.
Note
Developers may also call GetLastError() to retrieve the last MAPI error code. Possible MAPI error codes are:
  • MAPI_E_NOT_INITIALIZED: MAPI subsystem has not been initialized
  • MAPI_E_CALL_FAILED: A network problem was encountered during the transaction
See Also
CreateMessage, CreateAttach, GetAttachmentTable, GetLastError

References mapi_object_get_handle(), mapi_object_get_logon_id(), mapi_object_get_session(), mapi_object_set_handle(), mapi_object_set_logon_id(), and mapi_object_set_session().

_PUBLIC_ enum MAPISTATUS OpenEmbeddedMessage ( mapi_object_t *  obj_attach,
mapi_object_t *  obj_embeddedmsg,
enum OpenEmbeddedMessage_OpenModeFlags  ulFlags 
)

Opens an embedded message object and retrieves a MAPI object that can be used to get or set properties on the embedded message.

This function essentially takes an attachment and gives you back a message.

Parameters
obj_attachthe attachment object
obj_embeddedmsgthe embedded message
ulFlagsaccess rights on the embedded message

Possible ulFlags values:

  • 0x0: read only access
  • 0x1: Read / Write access
  • 0x2: Create
... assume we have a message - obj_message ...
// Initialise the attachment object
mapi_object_init(&obj_attach);
// Create an attachment to the message
retval = CreateAttach(&obj_message, &obj_attach);
... check the return value ...
// use SetProps() to set the attachment up, noting the special PR_ATTACHM_METHOD property
attach[0].ulPropTag = PR_ATTACH_METHOD;
attach[0].value.l = ATTACH_EMBEDDED_MSG;
attach[1].ulPropTag = PR_RENDERING_POSITION;
attach[1].value.l = 0;
retval = SetProps(&obj_attach, 0, attach, 2);
... check the return value ...
// Initialise the embedded message object
mapi_object_init(&obj_embeddedmsg);
retval = OpenEmbeddedMessage(&obj_attach, &obj_embeddedmsg, MAPI_CREATE);
... check the return value ...
// Fill in the embedded message properties, just like any other message (e.g. resulting from CreateMessage())
// Save the changes to the embedded message
retval = SaveChangesMessage(&obj_message, &obj_embeddedmsg, KeepOpenReadOnly);
... check the return value ...
// Save the changes to the attachment
retval = SaveChangesAttachment(&obj_message, &obj_attach, KeepOpenReadOnly);
... check the return value ...
// Save the changes to the original message
retval = SaveChangesMessage(&obj_folder, &obj_message, KeepOpenReadOnly);
... check the return value ...
Returns
MAPI_E_SUCCESS on success, otherwise MAPI error. Possible MAPI error codes are:
  • MAPI_E_NOT_INITIALIZED: MAPI subsystem has not been initialized
  • MAPI_E_INVALID_PARAMETER: obj_store is undefined
  • MAPI_E_CALL_FAILED: A network problem was encountered during the transaction
Note
Developers may also call GetLastError() to retrieve the last MAPI error code.
See Also
CreateAttach, OpenMessage, GetLastError

References emsmdb_get_SRow(), mapi_object_get_handle(), mapi_object_get_logon_id(), mapi_object_get_session(), mapi_object_set_handle(), mapi_object_set_logon_id(), mapi_object_set_session(), SPropTagArray_add(), and SRow_addprop().

_PUBLIC_ enum MAPISTATUS ReadRecipients ( mapi_object_t *  obj_message,
uint32_t  RowId,
uint8_t *  RowCount,
struct ReadRecipientRow **  RecipientRows 
)

Read Recipients from a message

Parameters
obj_messagethe message we want to read recipients from
RowIdthe row index we start reading recipients from
RowCountpointer on the number of recipients
RecipientRowspointer on the recipients array
Returns
MAPI_E_SUCCESS on success, otherwise MAPI error.
Note
Developers may also call GetLastError() to retrieve the last MAPI error code. Possible MAPI error codes are:
  • MAPI_E_NOT_INITIALIZED: MAPI subsystem has not been initialized
  • MAPI_E_CALL_FAILED: A network problem was encountered during the transaction
See Also
ModifyRecipients, RemoveAllRecipients, GetRecipientTable, OpenMessage

References mapi_object_get_handle(), mapi_object_get_logon_id(), and mapi_object_get_session().

_PUBLIC_ enum MAPISTATUS RemoveAllRecipients ( mapi_object_t *  obj_message)

Deletes all recipients from a message

Parameters
obj_messagethe message we want to remove all recipients from
Returns
MAPI_E_SUCCESS on success, otherwise MAPI error.
Note
Developers may also call GetLastError() to retrieve the last MAPI error code. Possible MAPI error codes are:
  • MAPI_E_NOT_INITIALIZED: MAPI subsystem has not been initialized
  • MAPI_E_CALL_FAILED: A network problem was encountered during the transaction
See Also
ModifyRecipients, ReadRecipients

References mapi_object_get_handle(), mapi_object_get_logon_id(), and mapi_object_get_session().

_PUBLIC_ enum MAPISTATUS SaveChangesMessage ( mapi_object_t *  parent,
mapi_object_t *  obj_message,
uint8_t  SaveFlags 
)

Saves all changes to the message

Parameters
parentthe parent object for the message
obj_messagethe message to save
SaveFlagsspecify how the save operation behaves

Possible value for SaveFlags:

  1. KeepReadOnly Keep the Message object open with read-only access
  2. KeepOpenReadWrite Keep the Message object open with read-write access
  3. ForceSave Commit the changes and keep the message object open with read-write access
Returns
MAPI_E_SUCCESS on success, otherwise MAPI error.
Note
Developers may also call GetLastError() to retrieve the last MAPI error code. Possible MAPI error codes are:
  • MAPI_E_NOT_INITIALIZED: MAPI subsystem has not been initialized
  • MAPI_E_CALL_FAILED: A network problem was encountered during the transaction
See Also
SetProps, ModifyRecipients, GetLastError

References mapi_object_get_handle(), mapi_object_get_logon_id(), mapi_object_get_session(), and mapi_object_set_id().

_PUBLIC_ enum MAPISTATUS SetMessageReadFlag ( mapi_object_t *  obj_folder,
mapi_object_t *  obj_child,
uint8_t  flags 
)

Clear or set the MSGFLAG_READ flag for a given message

This function clears or sets the MSGFLAG_READ flag in the PR_MESSAGE_FLAGS property of a given message.

Parameters
obj_folderthe folder to operate in
obj_childthe message to set flags on
flagsthe new flags (MSGFLAG_READ) value
Returns
MAPI_E_SUCCESS on success, otherwise MAPI error.
Note
Developers may also call GetLastError() to retrieve the last MAPI error code. Possible MAPI error codes are:
  • MAPI_E_NOT_INITIALIZED: MAPI subsystem has not been initialized
  • MAPI_E_CALL_FAILED: A network problem was encountered during the transaction
See Also
OpenMessage, GetLastError

References mapi_object_get_handle(), mapi_object_get_logon_id(), and mapi_object_get_session().

_PUBLIC_ enum MAPISTATUS SetRecipientType ( struct SRow *  aRow,
enum ulRecipClass  RecipClass 
)

Set the type of a recipient

The function sets the recipient type (RecipClass) in the aRow parameter. ResolveNames should be used to fill the SRow structure.

Parameters
aRowthe row to set
RecipClassthe type of recipient to set on the specified row
Returns
MAPI_E_SUCCESS on success, otherwise MAPI error.
Note
Developers may also call GetLastError() to retrieve the last MAPI error code. Possible MAPI error codes are:
  • MAPI_E_INVALID_PARAMETER: The aRow parameter was not set properly.
See Also
ResolveNames, ModifyRecipients, GetLastError

References SRow_addprop().

_PUBLIC_ enum MAPISTATUS SubmitMessage ( mapi_object_t *  obj_message)

Saves all changes to the message and marks it as ready for sending.

This function saves all changes made to a message and marks it ready to be sent.

Parameters
obj_messagethe message to mark complete
Returns
MAPI_E_SUCCESS on success, otherwise MAPI error.
Note
Developers may also call GetLastError() to retrieve the last MAPI error code. Possible MAPI error codes are:
  • MAPI_E_NOT_INITIALIZED: MAPI subsystem has not been initialized
  • MAPI_E_CALL_FAILED: A network problem was encountered during the transaction
See Also
CreateMessage, SetProps, ModifyRecipients, SetRecipientType, GetLastError

References mapi_object_get_handle(), mapi_object_get_logon_id(), and mapi_object_get_session().

_PUBLIC_ enum MAPISTATUS TransportSend ( mapi_object_t *  obj_message,
struct mapi_SPropValue_array *  lpProps 
)

Sends the specified Message object out for message delivery.

References mapi_object_get_handle(), mapi_object_get_logon_id(), and mapi_object_get_session().


Creative Commons License
Creative Commons Attribution icon Creative Commons Share Alike icon
This content is licensed under the Creative Commons
Attribution ShareAlike License v. 3.0:
http://creativecommons.org/licenses/by-sa/3.0/

openchange-2.0/apidocs/html/libmapi/IMsgStore_8c.html000066400000000000000000001060701223057412600226270ustar00rootroot00000000000000 MAPIClientLibraries 2.0 API Documentation
IMsgStore.c File Reference

Folders related operations. More...

#include "libmapi/libmapi.h"
#include "libmapi/libmapi_private.h"

Functions

_PUBLIC_ enum MAPISTATUS GetOutboxFolder (mapi_object_t *obj_store, mapi_id_t *outbox_id)
_PUBLIC_ enum MAPISTATUS GetOwningServers (mapi_object_t *obj_store, mapi_object_t *obj_folder, uint16_t *OwningServersCount, uint16_t *CheapServersCount, char **OwningServers)
_PUBLIC_ enum MAPISTATUS GetReceiveFolder (mapi_object_t *obj_store, mapi_id_t *id_folder, const char *MessageClass)
_PUBLIC_ enum MAPISTATUS GetReceiveFolderTable (mapi_object_t *obj_store, struct SRowSet *SRowSet)
_PUBLIC_ enum MAPISTATUS GetStoreState (mapi_object_t *obj_store, uint32_t *StoreState)
_PUBLIC_ enum MAPISTATUS GetTransportFolder (mapi_object_t *obj_store, mapi_id_t *FolderId)
_PUBLIC_ enum MAPISTATUS OpenFolder (mapi_object_t *obj_store, mapi_id_t id_folder, mapi_object_t *obj_folder)
_PUBLIC_ enum MAPISTATUS OpenPublicFolderByName (mapi_object_t *obj_folder, mapi_object_t *obj_child, const char *name)
_PUBLIC_ enum MAPISTATUS PublicFolderIsGhosted (mapi_object_t *obj_store, mapi_object_t *obj_folder, bool *IsGhosted)
_PUBLIC_ enum MAPISTATUS SetReceiveFolder (mapi_object_t *obj_store, mapi_object_t *obj_folder, const char *lpszMessageClass)
_PUBLIC_ enum MAPISTATUS TransportNewMail (mapi_object_t *obj_store, mapi_object_t *obj_folder, mapi_object_t *obj_msg, const char *MessageClass, uint32_t MessageFlags)

Detailed Description

Folders related operations.

Function Documentation

_PUBLIC_ enum MAPISTATUS GetOutboxFolder ( mapi_object_t *  obj_store,
mapi_id_t *  outbox_id 
)

Retrieves the sending folder (OUTBOX) for a given store

This function obtains the folder that was established as the destination for outgoing messages of a specified message class.

This function does not result in any network traffic.

Parameters
obj_storethe store to get the outbox folder for
outbox_idthe resulting folder identification
Returns
MAPI_E_SUCCESS on success, otherwise MAPI error.
Note
Developers may also call GetLastError() to retrieve the last MAPI error code. Possible MAPI error codes are:
  • MAPI_E_NOT_INITIALIZED: MAPI subsystem has not been initialized
  • MAPI_E_CALL_FAILED: A network problem was encountered during the transaction
See Also
MAPIInitialize, OpenMsgStore, GetLastError, GetDefaultFolder
_PUBLIC_ enum MAPISTATUS GetOwningServers ( mapi_object_t *  obj_store,
mapi_object_t *  obj_folder,
uint16_t *  OwningServersCount,
uint16_t *  CheapServersCount,
char **  OwningServers 
)

Get the list of servers that host replicas of a given public folder.

Parameters
obj_storethe public folder store object
obj_folderthe folder object we search replica for
OwningServersCountnumber of OwningServers
CheapServersCountnumber of low-cost servers
OwningServerspointer on the list of NULL terminated ASCII string representing replica servers
Returns
MAPI_E_SUCCESS on success, otherwise MAPI error.
Note
ecNoReplicaAvailable (0x469) can be returned if no replica is available for the folder.

Developers may also call GetLastError() to retrieve the last MAPI error code. Possible MAPI error codes are:

  • MAPI_E_NOT_INITIALIZED: MAPI subsystem has not been initialized
  • MAPI_E_CALL_FAILED: A network problem was encountered during the transaction

References mapi_object_get_handle(), mapi_object_get_id(), mapi_object_get_logon_id(), and mapi_object_get_session().

_PUBLIC_ enum MAPISTATUS GetReceiveFolder ( mapi_object_t *  obj_store,
mapi_id_t *  id_folder,
const char *  MessageClass 
)

Gets the receive folder for incoming messages of a particular message class.

This function obtains the folder that was established as the destination for incoming messages of a specified message class, or the default receive folder for the message store.

Parameters
obj_storethe store to get the receiver folder for
id_folderthe resulting folder identification
MessageClasswhich message class to find the receivefolder for
Returns
MAPI_E_SUCCESS on success, otherwise MAPI error.
Note
Developers may also call GetLastError() to retrieve the last MAPI error code. Possible MAPI error codes are:
  • MAPI_E_NOT_INITIALIZED: MAPI subsystem has not been initialized
  • MAPI_E_CALL_FAILED: A network problem was encountered during the transaction
See Also
MAPIInitialize, OpenMsgStore, GetLastError, SetReceiveFolder, GetReceiveFolderTable

References mapi_object_get_handle(), mapi_object_get_logon_id(), and mapi_object_get_session().

_PUBLIC_ enum MAPISTATUS GetReceiveFolderTable ( mapi_object_t *  obj_store,
struct SRowSet *  SRowSet 
)

Retrieve the receive folder table which includes all the information about the receive folders for the message store

Parameters
obj_storethe message store object
SRowSetpointer on a SRowSet structure with GetReceiveFolderTable results.

Developers are required to call MAPIFreeBuffer(SRowSet.aRow) when they don't need the folder table data anymore.

Returns
MAPI_E_SUCCESS on success, otherwise MAPI error.
Note
Developers may also call GetLastError() to retrieve the last MAPI error code. Possible MAPI error codes are:
  • MAPI_E_NOT_INITIALIZED: MAPI subsystem has not been initialized
  • MAPI_E_CALL_FAILED: A network problem was encountered during the transaction
See Also
GetReceiveFolder, SetReceiveFolder

References mapi_object_get_handle(), mapi_object_get_logon_id(), and mapi_object_get_session().

_PUBLIC_ enum MAPISTATUS GetStoreState ( mapi_object_t *  obj_store,
uint32_t *  StoreState 
)

Gets the current store state for the logged in user

This operation must be performed against a user store (not against a Public Folder store). The StoreState will have the STORE_HAS_SEARCHES flag set if there are any active search folders. There are (currently) no other flags in the StoreState.

Parameters
obj_storethe store object
StoreStatepointer to the store state returned by the server
Returns
MAPI_E_SUCCESS on success, otherwise MAPI error.
Note
Developers may also call GetLastError() to retrieve the last MAPI error code. Possible MAPI error codes are:
  • MAPI_E_NOT_INITIALIZED: MAPI subsystem has not been initialized
  • MAPI_E_INVALID_PARAMETER: obj_store or StoreState are not valid
  • MAPI_E_CALL_FAILED: A network problem was encountered during the transaction

References mapi_object_get_handle(), mapi_object_get_logon_id(), and mapi_object_get_session().

_PUBLIC_ enum MAPISTATUS GetTransportFolder ( mapi_object_t *  obj_store,
mapi_id_t *  FolderId 
)

Retrieves the folder ID of the temporary transport folder.

Parameters
obj_storethe server object
FolderIdpointer on the returning Folder identifier
Returns
MAPI_E_SUCCESS on success, otherwise MAPI error.
Note
Developers may also call GetLastError() to retrieve the last MAPI error code. Possible MAPI error codes are:
  • MAPI_E_NOT_INITIALIZED: MAPI subsystem has not been initialized
  • MAPI_E_CALL_FAILED: A network problem was encountered during the transaction

References mapi_object_get_handle(), mapi_object_get_logon_id(), and mapi_object_get_session().

_PUBLIC_ enum MAPISTATUS OpenFolder ( mapi_object_t *  obj_store,
mapi_id_t  id_folder,
mapi_object_t *  obj_folder 
)

Open a folder from the store

Parameters
obj_storethe store to open a folder in (i.e. the parent)
id_folderthe folder identifier
obj_folderthe resulting open folder
Returns
MAPI_E_SUCCESS on success, otherwise MAPI error.
Note
Developers may also call GetLastError() to retrieve the last MAPI error code. Possible MAPI error codes are:
  • MAPI_E_NOT_INITIALIZED: MAPI subsystem has not been initialized
  • MAPI_E_CALL_FAILED: A network problem was encountered during the transaction
See Also
MAPIInitialize, OpenMsgStore, GetLastError
Examples:
fetchappointment.c, and fetchmail.c.

References mapi_object_get_handle(), mapi_object_get_logon_id(), mapi_object_get_session(), mapi_object_set_handle(), mapi_object_set_id(), mapi_object_set_logon_id(), and mapi_object_set_session().

Referenced by GetUserFreeBusyData().

_PUBLIC_ enum MAPISTATUS OpenPublicFolderByName ( mapi_object_t *  obj_folder,
mapi_object_t *  obj_child,
const char *  name 
)

Open a NNTP Public Folder given its name

Parameters
obj_folderthe parent folder
obj_childthe resulting open folder
namethe folder name
Returns
MAPI_E_SUCCESS on success, otherwise MAPI error.
Note
Developers may also call GetLastError() to retrieve the last MAPI error code. Possible MAPI error codes are:
  • MAPI_E_NOT_INITIALIZED: MAPI subsystem has not been initialized
  • MAPI_E_CALL_FAILED: A network problem was encountered during the transaction
See Also
OpenPublicFolder

References mapi_object_get_handle(), mapi_object_get_logon_id(), mapi_object_get_session(), mapi_object_set_handle(), mapi_object_set_logon_id(), and mapi_object_set_session().

_PUBLIC_ enum MAPISTATUS PublicFolderIsGhosted ( mapi_object_t *  obj_store,
mapi_object_t *  obj_folder,
bool *  IsGhosted 
)

Determine if a public folder is ghosted.

This function returns whether a public folder is ghosted or not.

Parameters
obj_storethe store of the public folder
obj_folderthe folder we are querying for ghost
IsGhostedpointer on the boolean value returned
Returns
MAPI_E_SUCCESS on success, otherwise MAPI error.
Note
Developers may also call GetLastError() to retrieve the last MAPI error code. Possible MAPI error codes are:
  • MAPI_E_NOT_INITIALIZED: MAPI subsystem has not been initialized
  • MAPI_E_CALL_FAILED: A network problem was encountered during the transaction

References mapi_object_get_handle(), mapi_object_get_id(), mapi_object_get_logon_id(), and mapi_object_get_session().

_PUBLIC_ enum MAPISTATUS SetReceiveFolder ( mapi_object_t *  obj_store,
mapi_object_t *  obj_folder,
const char *  lpszMessageClass 
)

Sets a folder as the destination for incoming messages of a particular message class.

Parameters
obj_storethe store to set the receive folder for
obj_folderthe destination folder
lpszMessageClassthe message class the folder will receive
Returns
MAPI_E_SUCCESS on success, otherwise MAPI error.
Note
Developers may also call GetLastError() to retrieve the last MAPI error code. Possible MAPI error codes are:
  • MAPI_E_NOT_INITIALIZED: MAPI subsystem has not been initialized
  • MAPI_E_CALL_FAILED: A network problem was encountered during the transaction
See Also
GetReceiveFolder, GetReceiveFolderTable

References mapi_object_get_handle(), mapi_object_get_id(), mapi_object_get_logon_id(), and mapi_object_get_session().

_PUBLIC_ enum MAPISTATUS TransportNewMail ( mapi_object_t *  obj_store,
mapi_object_t *  obj_folder,
mapi_object_t *  obj_msg,
const char *  MessageClass,
uint32_t  MessageFlags 
)

Notify the store of a new message to be processed

Parameters
obj_storethe store that the message is in (logon object)
obj_folderthe folder that the message is in
obj_msgthe message to be processed
MessageClassthe message class of the message to be processed
MessageFlagsthe message flags on the message
Returns
MAPI_E_SUCCESS on success, otherwise MAPI error.
Note
Developers may also call GetLastError() to retrieve the last MAPI error code. Possible MAPI error codes are:
  • MAPI_E_NOT_INITIALIZED: MAPI subsystem has not been initialized
  • MAPI_E_INVALID_PARAMETER: one the parameters is invalid
  • MAPI_E_CALL_FAILED: A network problem was encountered during the transaction
See Also
GetReceiveFolder, GetReceiveFolderTable

References mapi_object_get_handle(), mapi_object_get_id(), mapi_object_get_logon_id(), and mapi_object_get_session().


Creative Commons License
Creative Commons Attribution icon Creative Commons Share Alike icon
This content is licensed under the Creative Commons
Attribution ShareAlike License v. 3.0:
http://creativecommons.org/licenses/by-sa/3.0/

openchange-2.0/apidocs/html/libmapi/IProfAdmin_8c.html000066400000000000000000001540501223057412600227440ustar00rootroot00000000000000 MAPIClientLibraries 2.0 API Documentation
IProfAdmin.c File Reference

MAPI Profiles interface. More...

#include "libmapi/libmapi.h"
#include "libmapi/libmapi_private.h"

Functions

_PUBLIC_ enum MAPISTATUS ChangeProfilePassword (struct mapi_context *mapi_ctx, const char *profile, const char *old_password, const char *password)
_PUBLIC_ enum MAPISTATUS CopyProfile (struct mapi_context *mapi_ctx, const char *profile_src, const char *profile_dst)
_PUBLIC_ enum MAPISTATUS CreateProfile (struct mapi_context *mapi_ctx, const char *profile, const char *username, const char *password, uint32_t flag)
_PUBLIC_ enum MAPISTATUS CreateProfileStore (const char *profiledb, const char *ldif_path)
_PUBLIC_ enum MAPISTATUS DeleteProfile (struct mapi_context *mapi_ctx, const char *profile)
_PUBLIC_ enum MAPISTATUS DuplicateProfile (struct mapi_context *mapi_ctx, const char *profile_src, const char *profile_dst, const char *username)
_PUBLIC_ enum MAPISTATUS FindProfileAttr (struct mapi_profile *profile, const char *attribute, const char *value)
_PUBLIC_ enum MAPISTATUS GetDefaultProfile (struct mapi_context *mapi_ctx, char **profname)
_PUBLIC_ enum MAPISTATUS GetProfileAttr (struct mapi_profile *profile, const char *attribute, unsigned int *count, char ***value)
_PUBLIC_ enum MAPISTATUS GetProfileTable (struct mapi_context *mapi_ctx, struct SRowSet *proftable)
_PUBLIC_ enum MAPISTATUS LoadProfile (struct mapi_context *mapi_ctx, struct mapi_profile *profile)
_PUBLIC_ enum MAPISTATUS mapi_profile_add_string_attr (struct mapi_context *mapi_ctx, const char *profile, const char *attr, const char *value)
_PUBLIC_ enum MAPISTATUS mapi_profile_delete_string_attr (struct mapi_context *mapi_ctx, const char *profname, const char *attr, const char *value)
_PUBLIC_ const char * mapi_profile_get_ldif_path (void)
_PUBLIC_ enum MAPISTATUS mapi_profile_modify_string_attr (struct mapi_context *mapi_ctx, const char *profname, const char *attr, const char *value)
_PUBLIC_ enum MAPISTATUS OpenProfile (struct mapi_context *mapi_ctx, struct mapi_profile *profile, const char *profname, const char *password)
_PUBLIC_ enum MAPISTATUS ProcessNetworkProfile (struct mapi_session *session, const char *username, mapi_profile_callback_t callback, const void *private_data)
_PUBLIC_ enum MAPISTATUS RenameProfile (struct mapi_context *mapi_ctx, const char *old_profile, const char *profile)
_PUBLIC_ enum MAPISTATUS SetDefaultProfile (struct mapi_context *mapi_ctx, const char *profname)
_PUBLIC_ enum MAPISTATUS ShutDown (struct mapi_profile *profile)

Detailed Description

MAPI Profiles interface.

Function Documentation

_PUBLIC_ enum MAPISTATUS ChangeProfilePassword ( struct mapi_context *  mapi_ctx,
const char *  profile,
const char *  old_password,
const char *  password 
)

Change the profile password of an existing MAPI profile

Parameters
mapi_ctxpointer to the MAPI context
profilethe name of the profile to have its password changed
old_passwordthe old password
passwordthe new password
Returns
MAPI_E_SUCCESS on success, otherwise MAPI error.
Note
Developers may also call GetLastError() to retrieve the last MAPI error code. Possible MAPI error codes are:
  • MAPI_E_INVALID_PARAMETER: One of the following argument was not set: profile, old_password, password
  • MAPI_E_NOT_FOUND: The profile was not found in the database
See Also
CreateProfile, GetProfileTable, GetProfileAttr, ProcessNetworkProfile, GetLastError

References mapi_profile_modify_string_attr().

_PUBLIC_ enum MAPISTATUS CopyProfile ( struct mapi_context *  mapi_ctx,
const char *  profile_src,
const char *  profile_dst 
)

Copy a profile

Parameters
mapi_ctxpointer to the MAPI context
profile_srcthe source profile to copy from
profile_dstthe destination profile to copy to
Returns
MAPI_E_SUCCESS on success, otherwise MAPI error.

Referenced by DuplicateProfile().

_PUBLIC_ enum MAPISTATUS CreateProfile ( struct mapi_context *  mapi_ctx,
const char *  profile,
const char *  username,
const char *  password,
uint32_t  flag 
)

Create a profile in the MAPI profile database

This function creates a profile named profile in the MAPI profile database and sets the specified username in that profile.

This function may also set the password. If the flags include OC_PROFILE_NOPASSWORD then the password will not be set. Otherwise, the specified password argument will also be saved to the profile.

Parameters
mapi_ctxpointer to the MAPI context
profilethe name of the profile
usernamethe username of the profile
passwordthe password for the profile (if used)
flagthe union of the flags.
Returns
MAPI_E_SUCCESS on success, otherwise MAPI error.
Note
Developers may also call GetLastError() to retrieve the last MAPI error code. Possible MAPI error codes are:
  • MAPI_E_NOT_INITIALIZED: MAPI subsystem has not been initialized. The MAPI subsystem must be initialized (using MAPIInitialize) prior to creating a profile.
  • MAPI_E_NOT_ENOUGH_RESOURCES: MAPI subsystem failed to allocate the necessary resources to operate properly
  • MAPI_E_NO_SUPPORT: An error was encountered while setting the MAPI profile attributes in the database.
profile information (including the password, if saved to the profile) is stored unencrypted.
See Also
DeleteProfile, SetDefaultProfile, GetDefaultProfile, ChangeProfilePassword, GetProfileTable, ProcessNetworkProfile, GetLastError

References mapi_profile_add_string_attr().

_PUBLIC_ enum MAPISTATUS CreateProfileStore ( const char *  profiledb,
const char *  ldif_path 
)

Create a profile database

This function creates a new profile database, including doing an initial setup.

Parameters
profiledbthe absolute path to the profile database intended to be created
ldif_paththe absolute path to the LDIF information to use for initial setup.
Returns
MAPI_E_SUCCESS on success, otherwise MAPI error.
Note
Developers may also call GetLastError() to retrieve the last MAPI error code. Possible MAPI error codes are:
  • MAPI_E_CALL_FAILED: profiledb or ldif_path is not set
  • MAPI_E_NOT_ENOUGH_RESOURCES: ldb subsystem initialization failed
  • MAPI_E_NO_ACCESS: connection or ldif add failed
See Also
GetLastError, mapi_profile_get_ldif_path
_PUBLIC_ enum MAPISTATUS DeleteProfile ( struct mapi_context *  mapi_ctx,
const char *  profile 
)

Delete a profile from the MAPI profile database

Parameters
mapi_ctxpointer to the MAPI context
profilethe name of the profile to delete
Returns
MAPI_E_SUCCESS on success, otherwise MAPI error.
Note
Developers may also call GetLastError() to retrieve the last MAPI error code. Possible MAPI error codes are:
  • MAPI_E_NOT_INITIALIZED: MAPI subsystem has not been initialized. The MAPI subsystem must be initialized (using MAPIInitialize) prior to creating a profile.
  • MAPI_E_NOT_FOUND: The profile was not found in the database.
See Also
CreateProfile, ChangeProfilePassword, GetProfileTable, GetProfileAttr, ProcessNetworkProfile, GetLastError
_PUBLIC_ enum MAPISTATUS DuplicateProfile ( struct mapi_context *  mapi_ctx,
const char *  profile_src,
const char *  profile_dst,
const char *  username 
)

Duplicate an existing profile.

The username specified in parameter is used to customize the new profile. This function should only be used in environments where users are within the same administrative group, storage group, server etc. Otherwise this will create an invalid profile and may cause unpredictable results.

Parameters
mapi_ctxpointer to the MAPI context
profile_srcthe source profile to duplicate from
profile_dstthe destination profile to duplicate to
usernamethe username to replace within the destination profile
Returns
MAPI_E_SUCCESS on success, otherwise MAPI error

References CopyProfile(), GetLastError(), GetProfileAttr(), mapi_profile_delete_string_attr(), mapi_profile_modify_string_attr(), MAPIFreeBuffer(), MapiLogonProvider(), nspi_GetMatches(), nspi_GetSpecialTable(), OpenProfile(), and set_SPropTagArray().

_PUBLIC_ enum MAPISTATUS FindProfileAttr ( struct mapi_profile *  profile,
const char *  attribute,
const char *  value 
)

Search the value of an attribute within a given profile

Parameters
profilepointer to the MAPI profile
attributepointer to the attribute name
valuepointer to the attribute value
Returns
MAPI_E_SUCCESS on success, otherwise MAPI error
_PUBLIC_ enum MAPISTATUS GetDefaultProfile ( struct mapi_context *  mapi_ctx,
char **  profname 
)

Get the default profile from the database

Parameters
mapi_ctxpointer to the MAPI context
profnamethe result of the function (name of the default profile)
Returns
MAPI_E_SUCCESS on success, otherwise MAPI error.
Note
Developers may also call GetLastError() to retrieve the last MAPI error code. Possible MAPI error codes are:
  • MAPI_E_NOT_INITIALIZED: MAPI subsystem has not been initialized
  • MAPI_E_NOT_FOUND: The profile was not found in the database
On success GetDefaultProfile profname string is allocated. It is up to the developer to free it when not needed anymore.
See Also
SetDefaultProfile, GetProfileTable, GetLastError
Examples:
fetchappointment.c, fetchmail.c, and mapi_sample1.c.

References GetProfileTable().

_PUBLIC_ enum MAPISTATUS GetProfileAttr ( struct mapi_profile *  profile,
const char *  attribute,
unsigned int *  count,
char ***  value 
)

Retrieve attribute values from a profile

This function retrieves all the attribute values from the given profile. The number of results is stored in count and values are stored in an allocated string array in the value parameter that needs to be free'd using MAPIFreeBuffer().

Parameters
profilethe name of the profile to retrieve attributes from
attributethe attribute(s) to search for
countthe number of results
valuethe resulting values
Returns
MAPI_E_SUCCESS on success, otherwise MAPI error.
Note
Developers may also call GetLastError() to retrieve the last MAPI error code. Possible MAPI error codes are:
  • MAPI_E_NOT_INITIALIZED: MAPI subsystem has not been initialized
  • MAPI_E_INVALID_PARAMETER: Either profile or attribute was not set properly
  • MAPI_E_NOT_FOUND: The profile was not found in the database
See Also
SetDefaultProfile, GetDefaultProfile, MAPIFreeBuffer, GetProfileTable, GetLastError

Referenced by DuplicateProfile().

_PUBLIC_ enum MAPISTATUS GetProfileTable ( struct mapi_context *  mapi_ctx,
struct SRowSet *  proftable 
)

Retrieve the profile table

This function retrieves the profile table. Two fields are returned:

  • PR_DISPLAY_NAME: The profile name stored as a UTF8 string
  • PR_DEFAULT_PROFILE: Whether the profile is the default one(1) or not(0), stored as an integer
Parameters
mapi_ctxpointer to the MAPI context
proftablethe result of the call
Returns
MAPI_E_SUCCESS on success, otherwise MAPI error.
Note
Developers may also call GetLastError() to retrieve the last MAPI error code. Possible MAPI error codes are:
  • MAPI_E_NOT_INITIALIZED: MAPI subsystem has not been initialized
  • MAPI_E_NOT_FOUND: The profile was not found in the database
See Also
SetDefaultProfile, GetLastError

Referenced by GetDefaultProfile(), and RenameProfile().

_PUBLIC_ enum MAPISTATUS LoadProfile ( struct mapi_context *  mapi_ctx,
struct mapi_profile *  profile 
)

Load a MAPI Profile and sets its credentials

This function loads a named MAPI profile and sets the MAPI session credentials.

Parameters
mapi_ctxpointer to the MAPI context
profilepointer to the MAPI profile
Returns
MAPI_E_SUCCESS on success, otherwise MAPI error.
Note
Developers may also call GetLastError() to retrieve the last MAPI error code. Possible MAPI error codes are:
  • MAPI_E_NOT_INITIALIZED: MAPI subsystem has not been initialized
  • MAPI_E_INVALID_PARAMETER: The profile parameter is not initialized
  • MAPI_E_NOT_ENOUGH_RESOURCES: MAPI subsystem failed to allocate the necessary resources to perform the operation
See Also
OpenProfile, GetLastError

Referenced by MapiLogonProvider().

_PUBLIC_ enum MAPISTATUS mapi_profile_add_string_attr ( struct mapi_context *  mapi_ctx,
const char *  profile,
const char *  attr,
const char *  value 
)

Add an attribute to the profile

Parameters
mapi_ctxpointer to the MAPI context
profilepointer to the profile name
attrthe name of the atribute
valuethe value of the attribute

Referenced by CreateProfile(), and ProcessNetworkProfile().

_PUBLIC_ enum MAPISTATUS mapi_profile_delete_string_attr ( struct mapi_context *  mapi_ctx,
const char *  profname,
const char *  attr,
const char *  value 
)

Delete an attribute

Parameters
mapi_ctxpointer to the MAPI context
profnamethe name of the profile
attrthe name of the attribute
valuethe value of the attribute

Referenced by DuplicateProfile().

_PUBLIC_ const char* mapi_profile_get_ldif_path ( void  )

Get default ldif_path

This function returns the path for the default LDIF files.

See Also
CreateProfileStore
_PUBLIC_ enum MAPISTATUS mapi_profile_modify_string_attr ( struct mapi_context *  mapi_ctx,
const char *  profname,
const char *  attr,
const char *  value 
)

Modify an attribute

Parameters
mapi_ctxpointer to the MAPI context
profnamethe name of the profile
attrthe name of the attribute
valuethe value of the attribute

Referenced by ChangeProfilePassword(), DuplicateProfile(), and SetDefaultProfile().

_PUBLIC_ enum MAPISTATUS OpenProfile ( struct mapi_context *  mapi_ctx,
struct mapi_profile *  profile,
const char *  profname,
const char *  password 
)

Load a profile from the database

This function opens a named profile from the database, and fills the mapi_profile structure with common profile information.

Parameters
mapi_ctxpointer to the MAPI context
profilethe resulting profile
profnamethe name of the profile to open
passwordthe password to use with the profile
Returns
MAPI_E_SUCCESS on success, otherwise MAPI error.
Note
profile must be talloced because it used as talloc subcontext for data members. Developers may also call GetLastError() to retrieve the last MAPI error code. Possible MAPI error codes are:
  • MAPI_E_NOT_ENOUGH_RESOURCES: ldb subsystem initialization failed
  • MAPI_E_NOT_FOUND: the profile was not found in the profile database
  • MAPI_E_COLLISION: profname matched more than one entry
See Also
MAPIInitialize, GetLastError

Referenced by DuplicateProfile(), and MapiLogonProvider().

_PUBLIC_ enum MAPISTATUS ProcessNetworkProfile ( struct mapi_session *  session,
const char *  username,
mapi_profile_callback_t  callback,
const void *  private_data 
)

Process a full and automated MAPI profile creation

This function process a full and automated MAPI profile creation using the username pattern passed as a parameter. The functions takes a callback parameter which will be called when the username checked matches several usernames. Private data needed by the callback can be supplied using the private_data pointer.

typedef int (*mapi_callback_t) callback(struct SRowSet *, void *private_data);

The callback returns the SRow element index within the SRowSet structure. If the user cancels the operation the callback return value should be SRowSet->cRows or more.

Parameters
sessionthe session context
usernamethe username for the network profile
callbackfunction pointer callback function
private_datacontext data that will be provided to the callback
Returns
MAPI_E_SUCCESS on success, otherwise MAPI error.
Note
Developers may also call GetLastError() to retrieve the last MAPI error code. Possible MAPI error codes are:
  • MAPI_E_NOT_INITIALIZED: MAPI subsystem has not been initialized. The MAPI subsystem must be initialized (using MAPIInitialize) prior to creating a profile.
  • MAPI_E_END_OF_SESSION: The NSPI session has not been initialized
  • MAPI_E_CANCEL_USER: The user has aborted the operation
  • MAPI_E_INVALID_PARAMETER: The profile parameter was not set properly.
  • MAPI_E_NOT_FOUND: One of the mandatory field was not found during the profile creation process.
See Also
OpenProfileStore, MAPILogonProvider, GetLastError

References mapi_profile_add_string_attr(), MAPIFreeBuffer(), nspi_DNToMId(), nspi_GetMatches(), nspi_GetProps(), nspi_GetSpecialTable(), nspi_QueryRows(), and set_SPropTagArray().

_PUBLIC_ enum MAPISTATUS RenameProfile ( struct mapi_context *  mapi_ctx,
const char *  old_profile,
const char *  profile 
)

Rename a profile

Parameters
mapi_ctxpointer to the MAPI context
old_profileold profile name
profilenew profile name
Returns
MAPI_E_SUCCESS on success, otherwise MAPI error.

References GetProfileTable().

_PUBLIC_ enum MAPISTATUS SetDefaultProfile ( struct mapi_context *  mapi_ctx,
const char *  profname 
)

Set a default profile for the database

Parameters
mapi_ctxpointer to the MAPI context
profnamethe name of the profile to make the default profile
Returns
MAPI_E_SUCCESS on success, otherwise MAPI error.
Note
Developers may also call GetLastError() to retrieve the last MAPI error code. Possible MAPI error codes are:
  • MAPI_E_NOT_INITIALIZED: MAPI subsystem has not been initialized
  • MAPI_E_INVALID_PARAMETER: The profile parameter was not set properly.
  • MAPI_E_NOT_FOUND: The profile was not found in the database
See Also
GetDefaultProfile, GetProfileTable, GetLastError

References mapi_profile_modify_string_attr().

_PUBLIC_ enum MAPISTATUS ShutDown ( struct mapi_profile *  profile)

Release a profile

This function releases the credentials associated with the profile.

Parameters
profilethe profile to release.
Returns
MAPI_E_SUCCESS on success, otherwise MAPI error.
Note
Developers may also call GetLastError() to retrieve the last MAPI error code. Possible MAPI error codes are:
  • MAPI_E_INVALID_PARAMETER: The profile parameter was not set or not valid

Creative Commons License
Creative Commons Attribution icon Creative Commons Share Alike icon
This content is licensed under the Creative Commons
Attribution ShareAlike License v. 3.0:
http://creativecommons.org/licenses/by-sa/3.0/

openchange-2.0/apidocs/html/libmapi/IStoreFolder_8c.html000066400000000000000000000236311223057412600233150ustar00rootroot00000000000000 MAPIClientLibraries 2.0 API Documentation
IStoreFolder.c File Reference

Open messages. More...

#include "libmapi/libmapi.h"
#include "libmapi/libmapi_private.h"

Functions

_PUBLIC_ enum MAPISTATUS OpenMessage (mapi_object_t *obj_store, mapi_id_t id_folder, mapi_id_t id_message, mapi_object_t *obj_message, uint8_t ulFlags)
_PUBLIC_ enum MAPISTATUS ReloadCachedInformation (mapi_object_t *obj_message)

Detailed Description

Open messages.

Function Documentation

_PUBLIC_ enum MAPISTATUS OpenMessage ( mapi_object_t *  obj_store,
mapi_id_t  id_folder,
mapi_id_t  id_message,
mapi_object_t *  obj_message,
uint8_t  ulFlags 
)

Opens a specific message and retrieves a MAPI object that can be used to get or set message properties.

This function opens a specific message defined by a combination of object store, folder ID, and message ID and which read/write access is defined by ulFlags.

Parameters
obj_storethe store to read from
id_folderthe folder ID
id_messagethe message ID
obj_messagethe resulting message object
ulFlagsPossible ulFlags values:
  • 0x0: read only access
  • 0x1: ReadWrite
  • 0x3: Create
  • 0x4: OpenSoftDeleted
Returns
MAPI_E_SUCCESS on success, otherwise MAPI error.
Note
Developers may also call GetLastError() to retrieve the last MAPI error code. Possible MAPI error codes are:
  • MAPI_E_NOT_INITIALIZED: MAPI subsystem has not been initialized
  • MAPI_E_INVALID_PARAMETER: obj_store is undefined
  • MAPI_E_CALL_FAILED: A network problem was encountered during the transaction
See Also
MAPIInitialize, GetLastError
Examples:
fetchappointment.c, and fetchmail.c.

References emsmdb_get_SRow(), get_TypedString(), mapi_object_get_handle(), mapi_object_get_logon_id(), mapi_object_get_session(), mapi_object_set_handle(), mapi_object_set_logon_id(), mapi_object_set_session(), SPropTagArray_add(), and SRow_addprop().

Referenced by GetUserFreeBusyData().

_PUBLIC_ enum MAPISTATUS ReloadCachedInformation ( mapi_object_t *  obj_message)

Retrieve the message properties for an already open message.

This function is very similar to OpenMessage, but works on an already open message object.

Parameters
obj_messagethe message object to retrieve the properties for.
Returns
MAPI_E_SUCCESS on success, otherwise MAPI error.
Note
Developers may also call GetLastError() to retrieve the last MAPI error code. Possible MAPI error codes are:
  • MAPI_E_NOT_INITIALIZED: MAPI subsystem has not been initialized
  • MAPI_E_INVALID_PARAMETER: obj_store is undefined
  • MAPI_E_CALL_FAILED: A network problem was encountered during the transaction
See Also
OpenMessage

References emsmdb_get_SRow(), mapi_object_get_handle(), mapi_object_get_logon_id(), mapi_object_get_session(), SPropTagArray_add(), and SRow_addprop().


Creative Commons License
Creative Commons Attribution icon Creative Commons Share Alike icon
This content is licensed under the Creative Commons
Attribution ShareAlike License v. 3.0:
http://creativecommons.org/licenses/by-sa/3.0/

openchange-2.0/apidocs/html/libmapi/IStream_8c.html000066400000000000000000001174671223057412600223330ustar00rootroot00000000000000 MAPIClientLibraries 2.0 API Documentation
IStream.c File Reference

Functions for operating on Streams on MAPI objects. More...

#include "libmapi/libmapi.h"
#include "libmapi/libmapi_private.h"

Functions

_PUBLIC_ enum MAPISTATUS CloneStream (mapi_object_t *obj_src, mapi_object_t *obj_dst)
_PUBLIC_ enum MAPISTATUS CommitStream (mapi_object_t *obj_stream)
_PUBLIC_ enum MAPISTATUS CopyToStream (mapi_object_t *obj_src, mapi_object_t *obj_dst, uint64_t ByteCount, uint64_t *ReadByteCount, uint64_t *WrittenByteCount)
_PUBLIC_ enum MAPISTATUS GetStreamSize (mapi_object_t *obj_stream, uint32_t *StreamSize)
_PUBLIC_ enum MAPISTATUS LockRegionStream (mapi_object_t *obj_stream, uint64_t RegionOffset, uint64_t RegionSize, uint32_t LockFlags)
_PUBLIC_ enum MAPISTATUS OpenStream (mapi_object_t *obj_related, enum MAPITAGS PropertyTag, enum OpenStream_OpenModeFlags OpenModeFlags, mapi_object_t *obj_stream)
_PUBLIC_ enum MAPISTATUS ReadStream (mapi_object_t *obj_stream, unsigned char *buf_data, uint16_t ByteCount, uint16_t *ByteRead)
_PUBLIC_ enum MAPISTATUS SeekStream (mapi_object_t *obj_stream, uint8_t Origin, uint64_t Offset, uint64_t *NewPosition)
_PUBLIC_ enum MAPISTATUS SetStreamSize (mapi_object_t *obj_stream, uint64_t SizeStream)
_PUBLIC_ enum MAPISTATUS UnlockRegionStream (mapi_object_t *obj_stream, uint64_t RegionOffset, uint64_t RegionSize, uint32_t LockFlags)
_PUBLIC_ enum MAPISTATUS WriteAndCommitStream (mapi_object_t *obj_stream, DATA_BLOB *blob, uint16_t *WrittenSize)
_PUBLIC_ enum MAPISTATUS WriteStream (mapi_object_t *obj_stream, DATA_BLOB *blob, uint16_t *WrittenSize)

Detailed Description

Functions for operating on Streams on MAPI objects.

Function Documentation

_PUBLIC_ enum MAPISTATUS CloneStream ( mapi_object_t *  obj_src,
mapi_object_t *  obj_dst 
)

Clone a source stream to another stream

Parameters
obj_srcthe source stream object
obj_dstthe destination stream object
Returns
MAPI_E_SUCCESS on success, otherwise MAPI error.
Note
Developers may also call GetLastError() to retrieve the last MAPI error code. Possible MAPI error codes are:
  • MAPI_E_NOT_INITIALIZED: MAPI subsystem has not been initialized
  • MAPI_E_INVALID_PARAMETER: source or destination streams are not valid.
  • MAPI_E_CALL_FAILED: A network problem was encountered during the transaction
See Also
OpenStream

References mapi_object_get_handle(), mapi_object_get_logon_id(), mapi_object_get_session(), mapi_object_set_handle(), mapi_object_set_logon_id(), and mapi_object_set_session().

_PUBLIC_ enum MAPISTATUS CommitStream ( mapi_object_t *  obj_stream)

Commits stream operations

Parameters
obj_streamthe stream object to commit
Returns
MAPI_E_SUCCESS on success, otherwise MAPI error.
Note
Developers may also call GetLastError() to retrieve the last MAPI error code. Possible MAPI error codes are:
  • MAPI_E_NOT_INITIALIZED: MAPI subsystem has not been initialized
  • MAPI_E_INVALID_PARAMETER: Either the network stream or session context are not valid.
  • MAPI_E_CALL_FAILED: A network problem was encountered during the transaction
See Also
OpenStream, ReadStream, WriteStream

References mapi_object_get_handle(), mapi_object_get_logon_id(), and mapi_object_get_session().

_PUBLIC_ enum MAPISTATUS CopyToStream ( mapi_object_t *  obj_src,
mapi_object_t *  obj_dst,
uint64_t  ByteCount,
uint64_t *  ReadByteCount,
uint64_t *  WrittenByteCount 
)

Copy a number of bytes from a source stream to another stream

Parameters
obj_srcthe source stream object
obj_dstthe destination stream object
ByteCountthe number of bytes to copy
ReadByteCountpointer on the number of bytes read from the source object
WrittenByteCountpointer on the number of bytes written to the destination object
Returns
MAPI_E_SUCCESS on success, otherwise MAPI error.
Note
Developers may also call GetLastError() to retrieve the last MAPI error code. Possible MAPI error codes are:
  • MAPI_E_NOT_INITIALIZED: MAPI subsystem has not been initialized
  • MAPI_E_INVALID_BOOKMARK: the bookmark specified is invalid or beyond the last row requested.
  • MAPI_E_CALL_FAILED: A network problem was encountered during the transaction
See Also
OpenStream

References mapi_object_get_handle(), mapi_object_get_logon_id(), and mapi_object_get_session().

_PUBLIC_ enum MAPISTATUS GetStreamSize ( mapi_object_t *  obj_stream,
uint32_t *  StreamSize 
)

Gets the size of a stream

Parameters
obj_streamthe stream object we retrieve size from
StreamSizepointer on the stream size
Returns
MAPI_E_SUCCESS on success, otherwise MAPI error.
Note
Developers may also call GetLastError() to retrieve the last MAPI error code. Possible MAPI error codes are:
  • MAPI_E_NOT_INITIALIZED: MAPI subsystem has not been initialized
  • MAPI_E_INVALID_PARAMETER: obj_stream is not initialized, or there was a problem obtaining the session context
  • MAPI_E_CALL_FAILED: A network problem was encountered during the transaction
See Also
OpenStream, ReadStream

References mapi_object_get_handle(), mapi_object_get_logon_id(), and mapi_object_get_session().

_PUBLIC_ enum MAPISTATUS LockRegionStream ( mapi_object_t *  obj_stream,
uint64_t  RegionOffset,
uint64_t  RegionSize,
uint32_t  LockFlags 
)

Lock a range of bytes within the stream

Parameters
obj_streamthe stream object
RegionOffsetstarting point for the range
RegionSizelength of the range
LockFlagstype of locking to apply

Setting LockFlags to 0x00000001 will provide a write lock (i.e. one writer, any number of readers). Setting LockFlags to any other value will provide a read-write lock (one reader/writer, no other readers or writers).

Returns
MAPI_E_SUCCESS on success, otherwise MAPI error
Note
Developers may also call GetLastError() to retrieve the last MAPI error code. Possible MAPI error codes are:
  • MAPI_E_NOT_INITIALIZED: MAPI subsystem has not been initialized
  • MAPI_E_INVALID_PARAMETER: obj_stream is not valid
  • MAPI_E_CALL_FAILED: A network problem was encountered during the transaction
See Also
UnlockRegionStream

References mapi_object_get_handle(), mapi_object_get_logon_id(), and mapi_object_get_session().

_PUBLIC_ enum MAPISTATUS OpenStream ( mapi_object_t *  obj_related,
enum MAPITAGS  PropertyTag,
enum OpenStream_OpenModeFlags  OpenModeFlags,
mapi_object_t *  obj_stream 
)

Open a stream

This function opens a stream on the property prop set in obj_related with access flags set to access_flags and returns an object obj_stream.

Parameters
obj_relatedthe object to open.
PropertyTagthe property name for the object to create a stream for.
OpenModeFlagssets the access mode for the stream and is one of the following values: 0x0: ReadOnly 0x1: ReadWrite 0x2: Create 0x3: BestAccess
obj_streamthe resulting stream object.
Returns
MAPI_E_SUCCESS on success, otherwise MAPI error. Possible MAPI error codes are:
  • MAPI_E_NOT_INITIALIZED: MAPI subsystem has not been initialized
  • MAPI_E_INVALID_PARAMETER: A problem occurred obtaining the session context
  • MAPI_E_CALL_FAILED: A network problem was encountered during the transaction
Note
Developers may also call GetLastError() to retrieve the last MAPI error code.
See Also
ReadStream, WriteStream, GetLastError

References mapi_object_get_handle(), mapi_object_get_logon_id(), mapi_object_get_session(), mapi_object_set_handle(), mapi_object_set_logon_id(), and mapi_object_set_session().

_PUBLIC_ enum MAPISTATUS ReadStream ( mapi_object_t *  obj_stream,
unsigned char *  buf_data,
uint16_t  ByteCount,
uint16_t *  ByteRead 
)

Read buffer from a stream

This function reads from an open data stream. It will read up to ByteCount bytes from the stream, and return the data in data_buf. ByteRead is set to the number of bytes actually read.

Parameters
obj_streamthe opened stream object
buf_datathe buffer where data read from the stream will be stored
ByteCountthe number of bytes requested to be read from the stream
ByteReadthe number of bytes read from the stream
Returns
MAPI_E_SUCCESS on success, otherwise MAPI error. Possible MAPI error codes are:
  • MAPI_E_NOT_INITIALIZED: MAPI subsystem has not been initialized
  • MAPI_E_INVALID_PARAMETER: A problem occurred obtaining the session context
  • MAPI_E_CALL_FAILED: A network problem was encountered during the transaction
Note
Developers may also call GetLastError() to retrieve the last MAPI error code.
The data size intended to be read from the stream shouldn't extend a maximum size each time you call ReadStream. This size depends on Exchange server version. However 0x1000 is known to be a reliable read size value.
See Also
OpenStream, WriteStream, GetLastError

References mapi_object_get_handle(), mapi_object_get_logon_id(), and mapi_object_get_session().

Referenced by WrapCompressedRTFStream().

_PUBLIC_ enum MAPISTATUS SeekStream ( mapi_object_t *  obj_stream,
uint8_t  Origin,
uint64_t  Offset,
uint64_t *  NewPosition 
)

Seek a specific position within the stream

Parameters
obj_streamthe stream object
Originorigin location for the seek operation
Offsetthe seek offset
NewPositionpointer on the new position after the operation

Origin can either take one of the following values:

0x0 The new seek pointer is an offset relative to the beginning of the stream. 0x1 The new seek pointer is an offset relative to the current seek pointer location. 0x2 The new seek pointer is an offset relative to the end of the stream.

Returns
MAPI_E_SUCCESS on success, otherwise MAPI error
Note
Developers may also call GetLastError() to retrieve the last MAPI error code. Possible MAPI error codes are:
  • MAPI_E_NOT_INITIALIZED: MAPI subsystem has not been initialized
  • MAPI_E_INVALID_PARAMETER: obj_stream is not valid, Origin is out of limits, or NewPosition is null.
  • MAPI_E_CALL_FAILED: A network problem was encountered during the transaction
See Also
OpenStream, ReadStream

References mapi_object_get_handle(), mapi_object_get_logon_id(), and mapi_object_get_session().

_PUBLIC_ enum MAPISTATUS SetStreamSize ( mapi_object_t *  obj_stream,
uint64_t  SizeStream 
)

Set the stream size

Parameters
obj_streamthe stream object
SizeStreamthe size of the stream
Returns
MAPI_E_SUCCESS on success, otherwise MAPI error
Note
Developers may also call GetLastError() to retrieve the last MAPI error code. Possible MAPI error codes are:
  • MAPI_E_NOT_INITIALIZED: MAPI subsystem has not been initialized
  • MAPI_E_INVALID_PARAMETER: obj_stream is not valid
  • MAPI_E_CALL_FAILED: A network problem was encountered during the transaction
See Also
OpenStream, GetStreamSize

References mapi_object_get_handle(), mapi_object_get_logon_id(), and mapi_object_get_session().

_PUBLIC_ enum MAPISTATUS UnlockRegionStream ( mapi_object_t *  obj_stream,
uint64_t  RegionOffset,
uint64_t  RegionSize,
uint32_t  LockFlags 
)

Unlock a range of bytes within the stream

Parameters
obj_streamthe stream object
RegionOffsetstarting point for the range
RegionSizelength of the range
LockFlagstype of locking

LockFlags used in unlocking must match the LockFlags used in locking.

Returns
MAPI_E_SUCCESS on success, otherwise MAPI error
Note
Developers may also call GetLastError() to retrieve the last MAPI error code. Possible MAPI error codes are:
  • MAPI_E_NOT_INITIALIZED: MAPI subsystem has not been initialized
  • MAPI_E_INVALID_PARAMETER: obj_stream is not valid
  • MAPI_E_CALL_FAILED: A network problem was encountered during the transaction
See Also
UnlockRegionStream

References mapi_object_get_handle(), mapi_object_get_logon_id(), and mapi_object_get_session().

_PUBLIC_ enum MAPISTATUS WriteAndCommitStream ( mapi_object_t *  obj_stream,
DATA_BLOB *  blob,
uint16_t *  WrittenSize 
)

Write and commit a buffer to the stream

This function writes and commits the contents of a DATA_BLOB to the stream obj_stream.

Parameters
obj_streamthe opened stream object
blobthe DATA_BLOB to write to the stream
WrittenSizethe actual number of bytes written to the stream
Returns
MAPI_E_SUCCESS on success, otherwise MAPI error.
Note
Developers may also call GetLastError() to retrieve the last MAPI error code. Possible MAPI error codes are:
  • MAPI_E_NOT_INITIALIZED: MAPI subsystem has not been initialized
  • MAPI_E_INVALID_PARAMETER: A problem occurred obtaining the session context, or the stream or blob were null.
  • MAPI_E_CALL_FAILED: A network problem was encountered during the transaction
  • MAPI_E_TOO_BIG: the data blob was too large to process
The data size intended to be written to the stream should not exceed a maximum size each time you call WriteStream. This size depends on Exchange server version. However 0x1000 is known to be a reliable write size value.
See Also
WriteStream, CommitStream

References mapi_object_get_handle(), mapi_object_get_logon_id(), and mapi_object_get_session().

_PUBLIC_ enum MAPISTATUS WriteStream ( mapi_object_t *  obj_stream,
DATA_BLOB *  blob,
uint16_t *  WrittenSize 
)

Write buffer to the stream

This function writes the stream specified as a DATA_BLOB in data to the stream obj_stream.

Parameters
obj_streamthe opened stream object
blobthe DATA_BLOB to write to the stream
WrittenSizethe actual number of bytes written to the stream
Returns
MAPI_E_SUCCESS on success, otherwise MAPI error.
Note
Developers may also call GetLastError() to retrieve the last MAPI error code. Possible MAPI error codes are:
  • MAPI_E_NOT_INITIALIZED: MAPI subsystem has not been initialized
  • MAPI_E_INVALID_PARAMETER: A problem occurred obtaining the session context, or blob was null.
  • MAPI_E_CALL_FAILED: A network problem was encountered during the transaction
  • MAPI_E_TOO_BIG: the data blob was too large to process
The data size intended to be written to the stream should not exceed a maximum size each time you call WriteStream. This size depends on Exchange server version. However 0x1000 is known to be a reliable write size value.
See Also
OpenStream, ReadStream, GetLastError

References mapi_object_get_handle(), mapi_object_get_logon_id(), and mapi_object_get_session().


Creative Commons License
Creative Commons Attribution icon Creative Commons Share Alike icon
This content is licensed under the Creative Commons
Attribution ShareAlike License v. 3.0:
http://creativecommons.org/licenses/by-sa/3.0/

openchange-2.0/apidocs/html/libmapi/IUnknown_8c.html000066400000000000000000000435701223057412600225300ustar00rootroot00000000000000 MAPIClientLibraries 2.0 API Documentation
IUnknown.c File Reference

Various miscellaneous (ungrouped) functions. More...

#include "libmapi/libmapi.h"
#include "libmapi/libmapi_private.h"

Functions

_PUBLIC_ enum MAPISTATUS GetIdFromLongTermId (mapi_object_t *obj, struct LongTermId long_term_id, mapi_id_t *id)
_PUBLIC_ enum MAPISTATUS GetLastError (void)
_PUBLIC_ enum MAPISTATUS GetLongTermIdFromId (mapi_object_t *obj, mapi_id_t id, struct LongTermId *long_term_id)
_PUBLIC_ enum MAPISTATUS MAPIAllocateBuffer (struct mapi_context *mapi_ctx, uint32_t size, void **ptr)
_PUBLIC_ enum MAPISTATUS MAPIFreeBuffer (void *ptr)
_PUBLIC_ enum MAPISTATUS Release (mapi_object_t *obj)

Detailed Description

Various miscellaneous (ungrouped) functions.

Function Documentation

_PUBLIC_ enum MAPISTATUS GetIdFromLongTermId ( mapi_object_t *  obj,
struct LongTermId  long_term_id,
mapi_id_t *  id 
)

Convert an Long Term Id into an Id

The function looks up the Id for a specified Long Term Id value.

Parameters
objthe object to look up on
long_term_idthe id to look up
idthe id returned by the server
Returns
MAPI_E_SUCCESS on success, otherwise MAPI error.
Note
Developers may also call GetLastError() to retrieve the last MAPI error code. Possible MAPI error codes are:
  • MAPI_E_NOT_INITIALIZED: MAPI subsystem has not been initialized
  • MAPI_E_INVALID_PARAMETER: obj is null
  • MAPI_E_CALL_FAILED: A network problem was encountered during the transaction
See Also
GetLongTermIdFromId

References mapi_object_get_handle(), mapi_object_get_logon_id(), and mapi_object_get_session().

_PUBLIC_ enum MAPISTATUS GetLastError ( void  )

Returns the latest error code.

This function returns the error code set by a previous function call.

Note
Calls to this function may not work reliably in multi-threaded or multisession code. We suggest you capture the return value of the call, and check that instead.
Examples:
mapi_sample1.c.

Referenced by DuplicateProfile(), mapi_nameid_GetIDsFromNames(), OpenMsgStore(), and WrapCompressedRTFStream().

_PUBLIC_ enum MAPISTATUS GetLongTermIdFromId ( mapi_object_t *  obj,
mapi_id_t  id,
struct LongTermId *  long_term_id 
)

Convert an ID to a Long Term Id

The function looks up the Long Term Id for a specified ID value.

Parameters
objthe object to look up on
idthe id to look up
long_term_idthe long term ID returned from the server
Returns
MAPI_E_SUCCESS on success, otherwise MAPI error.
Note
Developers may also call GetLastError() to retrieve the last MAPI error code. Possible MAPI error codes are:
  • MAPI_E_NOT_INITIALIZED: MAPI subsystem has not been initialized
  • MAPI_E_INVALID_PARAMETER: obj is null
  • MAPI_E_CALL_FAILED: A network problem was encountered during the transaction
See Also
GetIdFromLongTermId

References mapi_object_get_handle(), mapi_object_get_logon_id(), and mapi_object_get_session().

_PUBLIC_ enum MAPISTATUS MAPIAllocateBuffer ( struct mapi_context *  mapi_ctx,
uint32_t  size,
void **  ptr 
)

Allocate memory using the MAPI memory context

Parameters
mapi_ctxpointer to the MAPI context
sizethe number of bytes to allocate
ptrpointer to the allocated byte region
Returns
MAPI_E_SUCCESS on success, otherwise MAPI error.
Note
Developers may also call GetLastError() to retrieve the last MAPI error code. Possible MAPI error codes are:
  • MAPI_E_NOT_INITIALIZED: MAPI subsystem has not been initialized
  • MAPI_E_SESSION_LIMIT: No session has been opened on the provider
  • MAPI_E_NOT_ENOUGH_RESOURCES: MAPI subsystem failed to allocate the necessary resources to operate properly
  • MAPI_E_INVALID_PARAMER: size is not set properly.
See Also
MAPIFreeBuffer, GetLastError
_PUBLIC_ enum MAPISTATUS MAPIFreeBuffer ( void *  ptr)

Free allocated memory

This function frees memory previously allocated with MAPIAllocateBuffer.

Parameters
ptrmemory region to free
Returns
MAPI_E_SUCCESS on success, otherwise MAPI error.
Note
Developers may also call GetLastError() to retrieve the last MAPI error code. Possible MAPI error codes are:
  • MAPI_E_INVALID_PARAMER: ptr is not set properly.
See Also
MAPIAllocateBuffer, GetLastError
Examples:
fetchappointment.c, and fetchmail.c.

Referenced by AddUserPermission(), DuplicateProfile(), EntryIDFromSourceIDForMessage(), FreeBookmark(), GetABRecipientInfo(), GetBestBody(), GetFolderItemsCount(), GetProps(), GetUserFreeBusyData(), Logoff(), ModifyUserPermission(), ProcessNetworkProfile(), RemoveUserPermission(), SetPropertiesNoReplicate(), and SetProps().

_PUBLIC_ enum MAPISTATUS Release ( mapi_object_t *  obj)

Release an object on the server

The function releases the object obj on the server.

Parameters
objthe object to release
Returns
MAPI_E_SUCCESS on success, otherwise MAPI error.
Note
Developers may also call GetLastError() to retrieve the last MAPI error code. Possible MAPI error codes are:
  • MAPI_E_NOT_INITIALIZED: MAPI subsystem has not been initialized
  • MAPI_E_CALL_FAILED: A network problem was encountered during the transaction
See Also
GetLastError

References mapi_object_get_handle(), mapi_object_get_logon_id(), and mapi_object_get_session().

Referenced by mapi_object_release(), and Unsubscribe().


Creative Commons License
Creative Commons Attribution icon Creative Commons Share Alike icon
This content is licensed under the Creative Commons
Attribution ShareAlike License v. 3.0:
http://creativecommons.org/licenses/by-sa/3.0/

openchange-2.0/apidocs/html/libmapi/IXPLogon_8c.html000066400000000000000000000353231223057412600224140ustar00rootroot00000000000000 MAPIClientLibraries 2.0 API Documentation
IXPLogon.c File Reference

Transport provider status information. More...

#include "libmapi/libmapi.h"
#include "libmapi/libmapi_private.h"

Functions

_PUBLIC_ enum MAPISTATUS AddressTypes (mapi_object_t *obj_store, uint16_t *lpcAdrType, struct mapi_LPSTR **lpAdrTypeArray)
_PUBLIC_ enum MAPISTATUS OptionsData (mapi_object_t *obj_store, const char *addrtype, uint8_t **OptionsData, uint16_t *OptionsLength, uint8_t **HelpFile, uint16_t *HelpFileLength, const char **HelpFileName)
_PUBLIC_ enum MAPISTATUS SetSpooler (mapi_object_t *obj_store)
_PUBLIC_ enum MAPISTATUS SpoolerLockMessage (mapi_object_t *obj_store, mapi_object_t *obj_message, enum LockState lockstate)

Detailed Description

Transport provider status information.

Function Documentation

_PUBLIC_ enum MAPISTATUS AddressTypes ( mapi_object_t *  obj_store,
uint16_t *  lpcAdrType,
struct mapi_LPSTR **  lpAdrTypeArray 
)

Returns the types of recipients that the transport provider handles.

Parameters
obj_storethe object to get recipients types from
lpcAdrTypethe count of recipients types returned
lpAdrTypeArraypointer on pointer of returned transport provider types
Returns
MAPI_E_SUCCESS on success, otherwise MAPI error.
Note
Developers may also call GetLastError() to retrieve the last MAPI error code. Possible MAPI error codes are:
  • MAPI_E_NOT_INITIALIZED: MAPI subsystem has not been initialized
  • MAPI_E_INVALID_PARAMETER: obj_store is not initialized
  • MAPI_E_CALL_FAILED: A network problem was encountered during the transaction

References mapi_object_get_handle(), mapi_object_get_logon_id(), and mapi_object_get_session().

_PUBLIC_ enum MAPISTATUS OptionsData ( mapi_object_t *  obj_store,
const char *  addrtype,
uint8_t **  OptionsData,
uint16_t *  OptionsLength,
uint8_t **  HelpFile,
uint16_t *  HelpFileLength,
const char **  HelpFileName 
)

Returns options information for the types of recipients that the transport provider handles.

Parameters
[in]obj_storethe object to get recipients types from
[in]addrtypestring name of the address type to get options for
[out]OptionsDatathe options data for this addrtype
[out]OptionsLengthlength of the OptionsData array
[out]HelpFilethe help file data for this addrtype (often empty)
[out]HelpFileLengthlength of the HelpFile array
[out]HelpFileNamethe name of the help file (often null)

The caller is responsible for talloc_free()ing the OptionsData array.

Returns
MAPI_E_SUCCESS on success, otherwise MAPI error.
Note
Developers may also call GetLastError() to retrieve the last MAPI error code. Possible MAPI error codes are:
  • MAPI_E_NOT_INITIALIZED: MAPI subsystem has not been initialized
  • MAPI_E_INVALID_PARAMETER: obj_store is not initialized
  • MAPI_E_CALL_FAILED: A network problem was encountered during the transaction

References mapi_object_get_handle(), mapi_object_get_logon_id(), and mapi_object_get_session().

_PUBLIC_ enum MAPISTATUS SetSpooler ( mapi_object_t *  obj_store)

Informs the server that the client intends to act as a mail spooler.

Parameters
obj_store,:the object server store object
Returns
MAPI_E_SUCCESS on success, otherwise MAPI error.
Note
Developers may also call GetLastError() to retrieve the last MAPI error code. Possible MAPI error codes are:
  • MAPI_E_NOT_INITIALIZED: MAPI subsystem has not been initialized
  • MAPI_E_INVALID_PARAMETER: obj_store is not initialized
  • MAPI_E_CALL_FAILED: A network problem was encountered during the transaction
See Also
SpoolerLockMessage

References mapi_object_get_handle(), mapi_object_get_logon_id(), and mapi_object_get_session().

_PUBLIC_ enum MAPISTATUS SpoolerLockMessage ( mapi_object_t *  obj_store,
mapi_object_t *  obj_message,
enum LockState  lockstate 
)

Locks the specified message for spooling.

Parameters
obj_storethe store object
obj_messagethe message object we want to lock
lockstatethe lock state

Possible values for the lock state:

  1. LockState_1stLock (0x0): Mark the message as locked
  2. LockState_1stUnlock (0x1): Mark the message as unlocked
  3. LockState_1stFinished (0x2): Mark the message as ready for processing by the server
Returns
MAPI_E_SUCCESS on success, otherwise MAPI error.
Note
Developers may also call GetLastError() to retrieve the last MAPI error code. Possible MAPI error codes are:
  • MAPI_E_NOT_INITIALIZED: MAPI subsystem has not been initialized
  • MAPI_E_INVALID_PARAMETER: obj_store is not initialized
  • MAPI_E_CALL_FAILED: A network problem was encountered during the transaction
See Also
SetSPooler

References mapi_object_get_handle(), mapi_object_get_id(), mapi_object_get_logon_id(), and mapi_object_get_session().


Creative Commons License
Creative Commons Attribution icon Creative Commons Share Alike icon
This content is licensed under the Creative Commons
Attribution ShareAlike License v. 3.0:
http://creativecommons.org/licenses/by-sa/3.0/

openchange-2.0/apidocs/html/libmapi/annotated.html000066400000000000000000000054171223057412600223410ustar00rootroot00000000000000 MAPIClientLibraries 2.0 API Documentation
Data Structures
Here are the data structures with brief descriptions:
oCmapi_obj_bookmarkIMAPITable object
\Cmapi_obj_storeIMsgStore object

Creative Commons License
Creative Commons Attribution icon Creative Commons Share Alike icon
This content is licensed under the Creative Commons
Attribution ShareAlike License v. 3.0:
http://creativecommons.org/licenses/by-sa/3.0/

openchange-2.0/apidocs/html/libmapi/apidocs.css000066400000000000000000000362151223057412600216320ustar00rootroot00000000000000/* ** WEBSITE ** */ BODY,H1,H2,H3,H4,H5,H6,P,CENTER,TD,TH,UL,DL,DIV { font-family: Geneva, Arial, Helvetica, sans-serif; } BODY,TD { font-size: 90%; } H1 { text-align: center; font-size: 160%; } H2 { font-size: 19px; font-weight: bold; color: #3E93D5; } H3 { font-size: 100%; } P { text-align: justify; } LI { li-style-type: square; li-style-position: outside; display: list-item; } CAPTION { font-weight: bold } DIV.qindex { width: 100%; background-color: #e8eef2; border: 1px solid #84b0c7; text-align: center; margin: 2px; padding: 2px; line-height: 140%; } DIV.nav { width: 100%; background-color: #e8eef2; border: 1px solid #84b0c7; text-align: center; margin: 2px; padding: 2px; line-height: 140%; } DIV.navtab { background-color: #e8eef2; border: 1px solid #84b0c7; text-align: center; margin: 2px; margin-right: 15px; padding: 2px; } TD.navtab { font-size: 70%; } A.qindex { text-decoration: none; font-weight: bold; color: #1A419D; } A.qindex:visited { text-decoration: none; font-weight: bold; color: #1A419D } A.qindex:hover { text-decoration: none; background-color: #ddddff; } A.qindexHL { text-decoration: none; font-weight: bold; background-color: #6666cc; color: #ffffff; border: 1px double #9295C2; } A.qindexHL:hover { text-decoration: none; background-color: #6666cc; color: #ffffff; } A.qindexHL:visited { text-decoration: none; background-color: #6666cc; color: #ffffff } A.el { text-decoration: none; font-weight: bold } A.elRef { font-weight: bold } A.code:link { text-decoration: none; font-weight: normal; color: #0000FF} A.code:visited { text-decoration: none; font-weight: normal; color: #0000FF} A.codeRef:link { font-weight: normal; color: #0000FF} A.codeRef:visited { font-weight: normal; color: #0000FF} A:hover { text-decoration: none; background-color: #f2f2ff } DL.el { margin-left: -1cm } .fragment { font-family: monospace, fixed; font-size: 95%; } PRE.fragment { border: 1px solid #CCCCCC; background-color: #f5f5f5; font-size: 11px; margin-top: 4px; margin-bottom: 4px; margin-left: 2px; margin-right: 8px; padding-left: 6px; padding-right: 6px; padding-top: 4px; padding-bottom: 4px; } DIV.ah { background-color: black; font-weight: bold; color: #ffffff; margin-bottom: 3px; margin-top: 3px } DIV.groupHeader { margin-left: 16px; margin-top: 12px; margin-bottom: 6px; font-weight: bold; } DIV.groupText { margin-left: 16px; font-style: italic; font-size: 90% } BODY { background: white; color: black; margin-right: 20px; margin-left: 20px; } TD.indexkey { background-color: #e8eef2; font-weight: bold; padding-right : 10px; padding-top : 2px; padding-left : 10px; padding-bottom : 2px; margin-left : 0px; margin-right : 0px; margin-top : 2px; margin-bottom : 2px; border: 1px solid #CCCCCC; } TD.indexvalue { background-color: #e8eef2; font-style: italic; padding-right : 10px; padding-top : 2px; padding-left : 10px; padding-bottom : 2px; margin-left : 0px; margin-right : 0px; margin-top : 2px; margin-bottom : 2px; border: 1px solid #CCCCCC; } TR.memlist { background-color: #f0f0f0; } P.formulaDsp { text-align: center; } IMG.formulaDsp { } IMG.formulaInl { vertical-align: middle; } SPAN.keyword { color: #008000 } SPAN.keywordtype { color: #604020 } SPAN.keywordflow { color: #e08000 } SPAN.comment { color: #800000 } SPAN.preprocessor { color: #806020 } SPAN.stringliteral { color: #002080 } SPAN.charliteral { color: #008080 } .mdescLeft { padding: 0px 8px 4px 8px; font-size: 80%; font-style: italic; background-color: #FAFAFA; border-top: 1px none #E0E0E0; border-right: 1px none #E0E0E0; border-bottom: 1px none #E0E0E0; border-left: 1px none #E0E0E0; margin: 0px; } .mdescRight { padding: 0px 8px 4px 8px; font-size: 80%; font-style: italic; background-color: #FAFAFA; border-top: 1px none #E0E0E0; border-right: 1px none #E0E0E0; border-bottom: 1px none #E0E0E0; border-left: 1px none #E0E0E0; margin: 0px; } .memItemLeft { padding: 1px 0px 0px 8px; margin: 4px; border-top-width: 1px; border-right-width: 1px; border-bottom-width: 1px; border-left-width: 1px; border-top-color: #E0E0E0; border-right-color: #E0E0E0; border-bottom-color: #E0E0E0; border-left-color: #E0E0E0; border-top-style: solid; border-right-style: none; border-bottom-style: none; border-left-style: none; background-color: #FAFAFA; font-size: 80%; } .memItemRight { padding: 1px 8px 0px 8px; margin: 4px; border-top-width: 1px; border-right-width: 1px; border-bottom-width: 1px; border-left-width: 1px; border-top-color: #E0E0E0; border-right-color: #E0E0E0; border-bottom-color: #E0E0E0; border-left-color: #E0E0E0; border-top-style: solid; border-right-style: none; border-bottom-style: none; border-left-style: none; background-color: #FAFAFA; font-size: 80%; } .memTemplItemLeft { padding: 1px 0px 0px 8px; margin: 4px; border-top-width: 1px; border-right-width: 1px; border-bottom-width: 1px; border-left-width: 1px; border-top-color: #E0E0E0; border-right-color: #E0E0E0; border-bottom-color: #E0E0E0; border-left-color: #E0E0E0; border-top-style: none; border-right-style: none; border-bottom-style: none; border-left-style: none; background-color: #FAFAFA; font-size: 80%; } .memTemplItemRight { padding: 1px 8px 0px 8px; margin: 4px; border-top-width: 1px; border-right-width: 1px; border-bottom-width: 1px; border-left-width: 1px; border-top-color: #E0E0E0; border-right-color: #E0E0E0; border-bottom-color: #E0E0E0; border-left-color: #E0E0E0; border-top-style: none; border-right-style: none; border-bottom-style: none; border-left-style: none; background-color: #FAFAFA; font-size: 80%; } .memTemplParams { padding: 1px 0px 0px 8px; margin: 4px; border-top-width: 1px; border-right-width: 1px; border-bottom-width: 1px; border-left-width: 1px; border-top-color: #E0E0E0; border-right-color: #E0E0E0; border-bottom-color: #E0E0E0; border-left-color: #E0E0E0; border-top-style: solid; border-right-style: none; border-bottom-style: none; border-left-style: none; color: #606060; background-color: #FAFAFA; font-size: 80%; } .search { color: #003399; font-weight: bold; } FORM.search { margin-bottom: 0px; margin-top: 0px; } INPUT.search { font-size: 75%; color: #000080; font-weight: normal; background-color: #e8eef2; } TD.tiny { font-size: 75%; } a { color: #1A41A8; } a:visited { color: #2A3798; } .dirtab { padding: 4px; border-collapse: collapse; border: 1px solid #84b0c7; } TH.dirtab { background: #e8eef2; font-weight: bold; } HR { height: 1px; border: none; border-top: 1px solid black; margin-bottom: 50px; } /* Style for detailed member documentation */ .memtemplate { font-size: 80%; color: #606060; font-weight: normal; } .memnav { background-color: #e8eef2; border: 1px solid #84b0c7; text-align: center; margin: 2px; margin-right: 15px; padding: 2px; } .memitem { padding: 4px; background-color: white; border-width: 1px; border-style: solid; border-color: #ccc; -moz-border-radius: 8px 8px 8px 8px; margin-bottom: 30px; } .memname { white-space: nowrap; font-weight: bold; font-size: 12px; margin: 10px 10px 10px 10px; } .memname EM { color: #45417e; } .memdoc{ padding-left: 10px; padding-right: 10px; } .memdoc EM, TD { font-size: 12px; } .memproto { background-color: #e9e9f4; width: 100%; border-width: 1px; border-style: solid; border-color: #ccc; font-weight: bold; -moz-border-radius: 8px 8px 8px 8px; } .paramkey { text-align: right; } .paramtype { white-space: nowrap; } .paramname { color: #602020; font-style: italic; white-space: nowrap; } /* End Styling for detailed member documentation */ /* for the tree view */ .ftvtree { font-family: sans-serif; margin:0.5em; } .directory { font-size: 9pt; font-weight: bold; } .directory h3 { margin: 0px; margin-top: 1em; font-size: 11pt; } .directory > h3 { margin-top: 0; } .directory p { margin: 0px; white-space: nowrap; } .directory div { display: none; margin: 0px; } .directory img { vertical-align: -30%; } #website { width: 820px; height: 100%; margin-left: auto; margin-right: auto; text-align: left; /* IE hack */ * position: absolute; * left: 50%; * margin-left: -410px; } /* ** HEADER ** */ .header { height: 200px; background: url(header.jpg) no-repeat top center; } body { background: #fff url(body_top_bg2.jpg) top left repeat-x; font-family: Arial, Trebuchet MS, Tahoma, Verdana, Helvetica, sans-serif; font-size: 11px; line-height: 17px; color: #444; color: #3a3a3a; fdpadding-top: 15px; text-align: center; background-color: #fbfbfb; } h1 { font: 24px bold Trebuchet MS, Arial; color: #FFF; padding: 0; margin: 0; } /* ** MIDDLE SIDE ** */ #middle_side { display: block; height: 100%; width: 800px; margin-top: 7px; backsground: url(middle_bg.jpg) top left repeat-x; background-color: #fbfbfb; } /* left and right side */ #left_side { background-color: #fff; clear: both; margin-bottom: 10px; border-bottom: 1px solid #eee; border-left: 1px solid #eee; border-right: 1px solid #eee; -moz-border-radius: 0 0 8px 8px; height: 29px; } /* ** MENU HORIZONTAL ** */ /************ Global Navigation *************/ DIV.tabs { float : left; width : 100%; background : url("tab_b.gif") repeat-x bottom; margin-top : 10px; margin-bottom : 4px; } DIV.tabs ul { margin : 0px; padding-left : 10px; list-style : none; } DIV.tabs li { display : inline; margin : 0px; padding : 0px; } DIV.tabs A { float : left; background : url("tab_r.gif") no-repeat right top; border-bottom : 1px solid #84B0C7; font-size : x-small; font-weight : bold; text-decoration : none; } DIV.tabs A:link, .tabs A:visited, DIV.tabs A:active, .tabs A:hover { color: #1A419D; } DIV.tabs SPAN { float : left; display : block; background : url("tab_l.gif") no-repeat left top; padding : 5px 10px; white-space : nowrap; } DIV.tabs TD { font-size : x-small; font-weight : bold; text-decoration : none; } /* Commented Backslash Hack hides rule from IE5-Mac \*/ DIV.tabs SPAN {float : none;} /* End IE5-Mac hack */ DIV.tabs A:hover SPAN { background-position: 0% -150px; } DIV.tabs LI.current A { background-position: 100% -150px; border-width : 0px; } DIV.tabs LI.current SPAN { background-position: 0% -150px; padding-bottom : 6px; } DIV.nav { background : none; border : none; border-bottom : 1px solid #84B0C7; } #right_side_home { font-family: "Lucida Grande", Arial, Verdana, sans-serif; background-color: white; padding: 0px 20px; border: 1px solid #ebebeb; border: 1px solid #ddd; -moz-border-radius: 10px 10px; width: 750px; * width: 800px; * margin-left: 0px; padding-bottom: 10px; } #right_side_home td { line-height: 17px; margin: 0 0 5px 0; padding: 10px 0 15px 7px display: table-cell; border-spacing: 2px 2px; vertical-align: middle; text-align: left; border-bottom: 1px solid #EEEEEE; } #right_side_home td h2, a.anchor { font-size: 19px; font-weight: bold; color: #3E93D5; } #right_side_home td.indexkey { border-bottom: none; } #right_side_home li { list-style-position: inside; valign: middle; } TD.indexkey { background-color: #e8eef2; font-size : 12px; font-weight : bold; padding-right : 10px; padding-top : 2px; padding-left : 10px; padding-bottom : 2px; margin-left : 0px; margin-right : 0px; margin-top : 2px; margin-bottom : 2px; border : 1px solid #CCCCCC; } TD.indexvalue { background-color: #e8eef2; font-style : italic; font-size : 12px; padding-right : 10px; padding-top : 2px; padding-left : 10px; padding-bottom : 2px; margin-left : 0px; margin-right : 0px; margin-top : 2px; margin-bottom : 2px; border : 1px solid #CCCCCC; } TR.memlist { background-color: #f0f0f0; } .mdescLeft { padding: 0px 8px 4px 8px; font-size: 80%; font-style: italic; background-color: #FAFAFA; border-top: 1px none #E0E0E0; border-right: 1px none #E0E0E0; border-bottom: 1px none #E0E0E0; border-left: 1px none #E0E0E0; margin: 0px; } .mdescRight { padding: 0px 8px 4px 8px; font-size: 80%; font-style: italic; background-color: #FAFAFA; border-top: 1px none #E0E0E0; border-right: 1px none #E0E0E0; border-bottom: 1px none #E0E0E0; border-left: 1px none #E0E0E0; margin: 0px; } .memItemLeft { padding: 1px 0px 0px 8px; margin: 4px; border-top-width: 1px; border-right-width: 1px; border-bottom-width: 1px; border-left-width: 1px; border-top-color: #E0E0E0; border-right-color: #E0E0E0; border-bottom-color: #E0E0E0; border-left-color: #E0E0E0; border-top-style: solid; border-right-style: none; border-bottom-style: none; border-left-style: none; background-color: #FAFAFA; font-size: 80%; } .memItemRight { padding: 1px 8px 0px 8px; margin: 4px; border-top-width: 1px; border-right-width: 1px; border-bottom-width: 1px; border-left-width: 1px; border-top-color: #E0E0E0; border-right-color: #E0E0E0; border-bottom-color: #E0E0E0; border-left-color: #E0E0E0; border-top-style: solid; border-right-style: none; border-bottom-style: none; border-left-style: none; background-color: #FAFAFA; font-size: 80%; } .memTemplItemLeft { padding: 1px 0px 0px 8px; margin: 4px; border-top-width: 1px; border-right-width: 1px; border-bottom-width: 1px; border-left-width: 1px; border-top-color: #E0E0E0; border-right-color: #E0E0E0; border-bottom-color: #E0E0E0; border-left-color: #E0E0E0; border-top-style: none; border-right-style: none; border-bottom-style: none; border-left-style: none; background-color: #FAFAFA; font-size: 80%; } .memTemplItemRight { padding: 1px 8px 0px 8px; margin: 4px; border-top-width: 1px; border-right-width: 1px; border-bottom-width: 1px; border-left-width: 1px; border-top-color: #E0E0E0; border-right-color: #E0E0E0; border-bottom-color: #E0E0E0; border-left-color: #E0E0E0; border-top-style: none; border-right-style: none; border-bottom-style: none; border-left-style: none; background-color: #FAFAFA; font-size: 80%; } .memTemplParams { padding: 1px 0px 0px 8px; margin: 4px; border-top-width: 1px; border-right-width: 1px; border-bottom-width: 1px; border-left-width: 1px; border-top-color: #E0E0E0; border-right-color: #E0E0E0; border-bottom-color: #E0E0E0; border-left-color: #E0E0E0; border-top-style: solid; border-right-style: none; border-bottom-style: none; border-left-style: none; color: #606060; background-color: #FAFAFA; font-size: 80%; } code { display: block; width: 100%; border: 1px solid #ccc; background-color: #e8edf3; padding-top: 10px; padding-bottom: 10px; padding-left: 5px; padding-right: 5px; margin-bottom: 10px; margin-top: 10px; } openchange-2.0/apidocs/html/libmapi/async__emsmdb_8c.html000066400000000000000000000121541223057412600235550ustar00rootroot00000000000000 MAPIClientLibraries 2.0 API Documentation
async_emsmdb.c File Reference

Async_EMSMDB stack functions. More...

#include "libmapi/libmapi.h"
#include "libmapi/libmapi_private.h"

Functions

enum MAPISTATUS emsmdb_async_waitex (struct emsmdb_context *emsmdb_ctx, uint32_t flagsIn, uint32_t *flagsOut)

Detailed Description

Async_EMSMDB stack functions.

Function Documentation

enum MAPISTATUS emsmdb_async_waitex ( struct emsmdb_context *  emsmdb_ctx,
uint32_t  flagsIn,
uint32_t *  flagsOut 
)

Create an asynchronous wait call

This basically "parks" a call on the AsyncEMSMDB interface to allow asynchronous notification to the client of changes on the server. This call (probably) won't return immediately, but will return when the server makes a change, or 300 seconds (5 minutes) elapses. This call will then need to be re-queued if further change notifications are wanted.

Parameters
emsmdb_ctxpointer to the EMSMDB context
flagsIninput flags (currently must be 0x00000000)
flagsOutoutput flags (zero for a call completion with no changes, non-zero if there are changes)
Returns
MAPI_E_SUCCESS on success, otherwise MAPI error

Referenced by RegisterAsyncNotification().


Creative Commons License
Creative Commons Attribution icon Creative Commons Share Alike icon
This content is licensed under the Creative Commons
Attribution ShareAlike License v. 3.0:
http://creativecommons.org/licenses/by-sa/3.0/

openchange-2.0/apidocs/html/libmapi/bc_s.png000066400000000000000000000012501223057412600211010ustar00rootroot00000000000000‰PNG  IHDR /ð9ÐoIDATxíMLAÇßìN»»¥ívKùPJik±R5^ŒChÂŃ!Dzƒ *U4VƒbÄD1~`8xà@ˆ^¿?ð𤡸Ý@јÝná`JLLÝØ¦ƒÜXi v«9ê)·}aV±&Ò0)›¼ð(‰zÛküNcFPÛù'@é¨KZK%!13§5£}Ý€ÒdÀã°’>´Åç´çhï¹G…ÉZ ïz×Ú—Éi£“ì–º=…@O¹«È‚1Ó¯¦3ãF«[ºä’d²¾JÒã`|^3˜Ý\›¿¡]²ó•'fçÓùyˆÄîçâÙ@¥Cos˧d:?$lhûnÝ× nm\†$cÔL6Ñý »Ì´x@N¦oPÀ®Î‘òÕ”€GÔ÷>9¹¨Q@ã±á“.‡qŠÜ´¼°Ø ”PCt(á«yŒQ$±°hÔNý8¤¥Ë MNjÿ$þßþŲo_ƒsLIEND®B`‚openchange-2.0/apidocs/html/libmapi/bdwn.png000066400000000000000000000002231223057412600211240ustar00rootroot00000000000000‰PNG  IHDR5åZIDATxíË € DŸP–1ñlžmÀ r±j².e è†D[ØÉ¾ÙÏÔ¼µ¦ã´Þ|陣6€Všë3´Å?Ls'(}¬>+ žKó÷¥¿ch`‚ ^׃ÞnIEND®B`‚openchange-2.0/apidocs/html/libmapi/body_top_bg2.jpg000066400000000000000000000006541223057412600225470ustar00rootroot00000000000000ÿØÿàJFIFddÿìDuckydÿîAdobedÀÿÛ„ÿÀ–ÿÄh að¡q‘QáR’¢ð!‘1aQÿÚ ?Ô¢±Õœ|W¼ í|ua³Dbe­‚hŒ*ø VÁ&ÅrV¹´,¸^Â-~TbÁÐéÊ—=©xj䮤*ÿRb²r %7L‘ñÜŠ¶5ø¦ èªÞV¶ ÿÙopenchange-2.0/apidocs/html/libmapi/bug.html000066400000000000000000000042511223057412600211340ustar00rootroot00000000000000 MAPIClientLibraries 2.0 API Documentation
Bug List
Global ModifyRecipients (mapi_object_t *obj_message, struct SRowSet *SRowSet)
ModifyRecipients can only add recipients.

Creative Commons License
Creative Commons Attribution icon Creative Commons Share Alike icon
This content is licensed under the Creative Commons
Attribution ShareAlike License v. 3.0:
http://creativecommons.org/licenses/by-sa/3.0/

openchange-2.0/apidocs/html/libmapi/cdo__mapi_8c.html000066400000000000000000000467431223057412600226770ustar00rootroot00000000000000 MAPIClientLibraries 2.0 API Documentation
cdo_mapi.c File Reference

MAPI subsystem related operations. More...

#include "libmapi/libmapi.h"
#include "libmapi/libmapi_private.h"

Functions

_PUBLIC_ enum MAPISTATUS GetLoadparmContext (struct mapi_context *mapi_ctx, struct loadparm_context **lp_ctx)
_PUBLIC_ enum MAPISTATUS MAPIInitialize (struct mapi_context **_mapi_ctx, const char *profiledb)
_PUBLIC_ enum MAPISTATUS MapiLogonEx (struct mapi_context *mapi_ctx, struct mapi_session **session, const char *profname, const char *password)
_PUBLIC_ enum MAPISTATUS MapiLogonProvider (struct mapi_context *mapi_ctx, struct mapi_session **session, const char *profname, const char *password, enum PROVIDER_ID provider)
_PUBLIC_ void MAPIUninitialize (struct mapi_context *mapi_ctx)
_PUBLIC_ enum MAPISTATUS SetMAPIDebugLevel (struct mapi_context *mapi_ctx, uint32_t level)
_PUBLIC_ enum MAPISTATUS SetMAPIDumpData (struct mapi_context *mapi_ctx, bool status)

Detailed Description

MAPI subsystem related operations.

Function Documentation

_PUBLIC_ enum MAPISTATUS GetLoadparmContext ( struct mapi_context *  mapi_ctx,
struct loadparm_context **  lp_ctx 
)

Retrieve the MAPI loadparm context for specified MAPI context

Parameters
mapi_ctxpointer to the MAPI context
lp_ctxpointer to a pointer to the loadparm context that the function returns
Returns
MAPI_E_SUCCESS on success, otherwise MAPI_E_NOT_INITIALIZED or MAPI_E_INVALID_PARAMETER
_PUBLIC_ enum MAPISTATUS MAPIInitialize ( struct mapi_context **  _mapi_ctx,
const char *  profiledb 
)

Initialize mapi context structure

This function inititalizes the MAPI subsystem and open the profile database pointed by profiledb .

Parameters
_mapi_ctxpointer to the MAPI context
profiledbprofile database path
Returns
MAPI_E_SUCCESS on success, otherwise MAPI error.
Note
Developers may also call GetLastError() to retrieve the last MAPI error code. Possible MAPI error codes are:
  • MAPI_E_NOT_INITIALIZED: MAPI subsystem has not been initialized
  • MAPI_E_NOT_ENOUGH_RESOURCES: MAPI subsystem failed to allocate the necessary resources to operate properly
  • MAPI_E_NOT_FOUND: No suitable profile database was found in the path pointed by profiledb
  • MAPI_E_CALL_FAILED: A network problem was encountered during the transaction
See Also
MAPIUninitialize
Examples:
fetchappointment.c, fetchmail.c, and mapi_sample1.c.
_PUBLIC_ enum MAPISTATUS MapiLogonEx ( struct mapi_context *  mapi_ctx,
struct mapi_session **  session,
const char *  profname,
const char *  password 
)

Create a full MAPI session

Open providers stored in the profile and return a pointer on a IMAPISession object.

Parameters
mapi_ctxpointer to the MAPI context
sessionpointer to a pointer to a MAPI session object
profnameprofile name to use
passwordpassword to use for the profile

password should be set to NULL if the password has been stored in the profile.

Returns
MAPI_E_SUCCESS on success otherwise MAPI error.
Note
Developers may also call GetLastError() to retrieve the last MAPI error code. Possible MAPI error codes are:
  • MAPI_E_NOT_INITIALIZED: MAPI subsystem has not been initialized
  • MAPI_E_NOT_ENOUGH_RESOURCES: MAPI subsystem failed to allocate the necessary resources to operate properly
  • MAPI_E_CALL_FAILED: A network problem was encountered during the transaction
See Also
MAPIInitialize, OpenProfile, MapiLogonProvider
Examples:
fetchappointment.c, fetchmail.c, and mapi_sample1.c.

References MapiLogonProvider().

_PUBLIC_ enum MAPISTATUS MapiLogonProvider ( struct mapi_context *  mapi_ctx,
struct mapi_session **  session,
const char *  profname,
const char *  password,
enum PROVIDER_ID  provider 
)

Initialize a session on the specified provider

Parameters
mapi_ctxpointer to the MAPI context
sessionpointer to a pointer to a MAPI session object
profnameprofile name
passwordprofile password
providerprovider we want to establish a connection on

password should be set to NULL if the password has been stored in the profile.

Supported providers are:

  • PROVIDER_ID_NSPI: Address Book provider
  • PROVIDER_ID_EMSMDB: MAPI Store provider
Returns
MAPI_E_SUCCESS on success, otherwise MAPI error.
Note
Developers may also call GetLastError() to retrieve the last MAPI error code. Possible MAPI error codes are:
  • MAPI_E_NOT_INITIALIZED: MAPI subsystem has not been initialized
  • MAPI_E_NOT_ENOUGH_RESOURCES: MAPI subsystem failed to allocate the necessary resources to operate properly
  • MAPI_E_CALL_FAILED: A network problem was encountered during the transaction
See Also
MapiLogonEx, OpenProfile, LoadProfile

References emsmdb_disconnect_dtor(), LoadProfile(), nspi_disconnect_dtor(), and OpenProfile().

Referenced by DuplicateProfile(), and MapiLogonEx().

_PUBLIC_ void MAPIUninitialize ( struct mapi_context *  mapi_ctx)

Uninitialize MAPI subsystem

Parameters
mapi_ctxpointer to the MAPI context

This function uninitializes the MAPI context and destroy recursively the whole mapi session and associated objects hierarchy

See Also
MAPIInitialize, GetLastError
Examples:
fetchappointment.c, fetchmail.c, and mapi_sample1.c.
_PUBLIC_ enum MAPISTATUS SetMAPIDebugLevel ( struct mapi_context *  mapi_ctx,
uint32_t  level 
)

Set MAPI debug level

Parameters
mapi_ctxpointer to the MAPI context
levelthe debug level to set
Returns
MAPI_E_SUCCESS on success, otherwise MAPI error.
Note
Developers may also call GetLastError() to retrieve the last MAPI error code. Possible MAPI error codes are:
  • MAPI_E_NOT_INITIALIZED: MAPI subsystem has not been initialized
  • MAPI_E_INVALID_PARAMETER: the function parameter is invalid
_PUBLIC_ enum MAPISTATUS SetMAPIDumpData ( struct mapi_context *  mapi_ctx,
bool  status 
)

Enable MAPI network trace output

Parameters
mapi_ctxpointer to the MAPI context
statusthe status

possible status values/behavior:

  1. true: Network traces are displayed on stdout
  2. false: Network traces are not displayed on stdout
Returns
MAPI_E_SUCCESS on success, otherwise MAPI_E_NOT_INITIALIZED

Creative Commons License
Creative Commons Attribution icon Creative Commons Share Alike icon
This content is licensed under the Creative Commons
Attribution ShareAlike License v. 3.0:
http://creativecommons.org/licenses/by-sa/3.0/

openchange-2.0/apidocs/html/libmapi/classes.html000066400000000000000000000054501223057412600220160ustar00rootroot00000000000000 MAPIClientLibraries 2.0 API Documentation

Creative Commons License
Creative Commons Attribution icon Creative Commons Share Alike icon
This content is licensed under the Creative Commons
Attribution ShareAlike License v. 3.0:
http://creativecommons.org/licenses/by-sa/3.0/

openchange-2.0/apidocs/html/libmapi/closed.png000066400000000000000000000002041223057412600214420ustar00rootroot00000000000000‰PNG  IHDR à‘KIDATxíÝm @!†ÑGk™É7À-`&séts¦Àñþòð@åk}ª2€… P%Á_Ëþ¿N² .:0Dk¥‹Â›x" Ö›)¡xÒ5õIEND®B`‚openchange-2.0/apidocs/html/libmapi/codepage__lcid_8c.html000066400000000000000000000377431223057412600236660ustar00rootroot00000000000000 MAPIClientLibraries 2.0 API Documentation
codepage_lcid.c File Reference

Codepage and Locale ID operations. More...

#include "libmapi/libmapi.h"
#include "libmapi/libmapi_private.h"
#include <locale.h>
#include <langinfo.h>

Functions

_PUBLIC_ uint32_t mapi_get_cpid_from_language (const char *language)
_PUBLIC_ uint32_t mapi_get_cpid_from_lcid (uint32_t lcid)
_PUBLIC_ uint32_t mapi_get_cpid_from_locale (const char *locale)
_PUBLIC_ char ** mapi_get_language_from_group (TALLOC_CTX *mem_ctx, uint32_t group)
_PUBLIC_ const char * mapi_get_language_from_lcid (uint32_t lcid)
_PUBLIC_ const char * mapi_get_language_from_locale (const char *locale)
_PUBLIC_ uint32_t mapi_get_lcid_from_language (const char *language)
_PUBLIC_ uint32_t mapi_get_lcid_from_locale (const char *locale)
_PUBLIC_ const char * mapi_get_locale_from_language (const char *language)
_PUBLIC_ const char * mapi_get_locale_from_lcid (uint32_t lcid)
_PUBLIC_ char * mapi_get_system_locale (void)
_PUBLIC_ bool mapi_verify_cpid (uint32_t cpid)

Detailed Description

Codepage and Locale ID operations.

Function Documentation

_PUBLIC_ uint32_t mapi_get_cpid_from_language ( const char *  language)

Return codepage associated to specified language

Parameters
languageThe language string to lookup
Returns
non-zero codepage on success, otherwise 0
_PUBLIC_ uint32_t mapi_get_cpid_from_lcid ( uint32_t  lcid)

Returns codepage for a given LCID (Locale ID)

Parameters
lcidthe locale ID to lookup
Returns
non-zero codepage on success, otherwise 0 if only unicode is supported for this language
_PUBLIC_ uint32_t mapi_get_cpid_from_locale ( const char *  locale)

Return codepage associated to specified locale

Parameters
localeThe locale string to lookup
Returns
non-zero codepage on success, otherwise 0
_PUBLIC_ char** mapi_get_language_from_group ( TALLOC_CTX *  mem_ctx,
uint32_t  group 
)

Returns List of languages for a given Language Group

Parameters
mem_ctxpointer to the memory context
groupthe locale group to lookup
Returns
Array of languages string on success, otherwise NULL
_PUBLIC_ const char* mapi_get_language_from_lcid ( uint32_t  lcid)

Returns Language for a given Locale ID

Parameters
lcidthe locale ID to lookup
Returns
language string on success, otherwise NULL
_PUBLIC_ const char* mapi_get_language_from_locale ( const char *  locale)

Returns Language for a given Locale

Parameters
localethe language string to lookup
Returns
Language string on success, otherwise NULL
_PUBLIC_ uint32_t mapi_get_lcid_from_language ( const char *  language)

Returns LCID (Locale ID) for a given language

Parameters
languagethe language string to lookup
Returns
non-zero LCID on success, otherwise 0
_PUBLIC_ uint32_t mapi_get_lcid_from_locale ( const char *  locale)

Returns LCID (Locale ID) for a given locale

Parameters
localethe locale string to lookup
Returns
non-zero LCID on success, otherwise 0
_PUBLIC_ const char* mapi_get_locale_from_language ( const char *  language)

Returns Locale for a given language

Parameters
languagethe language string to lookup
Returns
Locale string on success, otherwise NULL
_PUBLIC_ const char* mapi_get_locale_from_lcid ( uint32_t  lcid)

Returns Locale for a given Locale ID

Parameters
lcidthe locale ID to lookup
Returns
locale string on success, otherwise NULL
_PUBLIC_ char* mapi_get_system_locale ( void  )

Returns current locale used by the system

Returns
pointer to locale string on success, otherwise NULL
_PUBLIC_ bool mapi_verify_cpid ( uint32_t  cpid)

Verify if the specified codepage is valid

Parameters
cpidthe codepage to lookup
Returns
0 on success, otherwise 1

Creative Commons License
Creative Commons Attribution icon Creative Commons Share Alike icon
This content is licensed under the Creative Commons
Attribution ShareAlike License v. 3.0:
http://creativecommons.org/licenses/by-sa/3.0/

openchange-2.0/apidocs/html/libmapi/dir_04f2ecc425faf0d475a3caf484e551f3.html000066400000000000000000000054431223057412600257320ustar00rootroot00000000000000 MAPIClientLibraries 2.0 API Documentation
doxygen Directory Reference

Files

file  libmapi-concepts.doxy
file  libmapi-examples.doxy
file  libmapi-mainpage.doxy

Creative Commons License
Creative Commons Attribution icon Creative Commons Share Alike icon
This content is licensed under the Creative Commons
Attribution ShareAlike License v. 3.0:
http://creativecommons.org/licenses/by-sa/3.0/

openchange-2.0/apidocs/html/libmapi/dir_e68e8157741866f444e17edd764ebbae.html000066400000000000000000000046111223057412600256250ustar00rootroot00000000000000 MAPIClientLibraries 2.0 API Documentation
doc Directory Reference

Directories

directory  doxygen

Creative Commons License
Creative Commons Attribution icon Creative Commons Share Alike icon
This content is licensed under the Creative Commons
Attribution ShareAlike License v. 3.0:
http://creativecommons.org/licenses/by-sa/3.0/

openchange-2.0/apidocs/html/libmapi/dir_f632a44caec7a90b6d38c87e3df284e5.html000066400000000000000000000413321223057412600257470ustar00rootroot00000000000000 MAPIClientLibraries 2.0 API Documentation
libmapi Directory Reference

Files

file  async_emsmdb.c
 Async_EMSMDB stack functions.
file  cdo_mapi.c
 MAPI subsystem related operations.
file  codepage_lcid.c
 Codepage and Locale ID operations.
file  emsmdb.c
 EMSMDB stack functions.
file  emsmdb.h
file  freebusy.c
 Convenient API to access FreeBusy.
file  FXICS.c
 Fast Transfer and Incremental Change Synchronization operations.
file  fxparser.c
 Fast Transfer stream parser.
file  fxparser.h
file  IABContainer.c
 Provides access to address book containers – Used to perform name resolution.
file  idset.c
 Parsing of GLOBSET structures.
file  idset.h
file  IMAPIContainer.c
 Containers and tables related operations.
file  IMAPIFolder.c
 Folder related functions.
file  IMAPIProp.c
 Properties and named properties operations.
file  IMAPISession.c
 Session initialization options.
file  IMAPISupport.c
 MAPI notifications functions.
file  IMAPITable.c
 Operations on tables.
file  IMessage.c
 Operations on messages.
file  IMsgStore.c
 Folders related operations.
file  IMSProvider.c
 Provider operations.
file  IProfAdmin.c
 MAPI Profiles interface.
file  IStoreFolder.c
 Open messages.
file  IStream.c
 Functions for operating on Streams on MAPI objects.
file  IUnknown.c
 Various miscellaneous (ungrouped) functions.
file  IXPLogon.c
 Transport provider status information.
file  libmapi.h
file  lzfu.c
 Compressed RTF related functions.
file  mapi_context.h
file  mapi_id_array.c
 mapi_id_array support functions
file  mapi_id_array.h
file  mapi_nameid.c
 mapi_nameid convenience API
file  mapi_nameid.h
file  mapi_notification.h
file  mapi_object.c
 mapi_object_t support functions
file  mapi_object.h
file  mapi_profile.h
file  mapi_provider.h
file  mapicode.c
file  mapicode.h
file  mapidefs.h
file  mapidump.c
 Functions for displaying various data structures, mainly for debugging.
file  mapidump.h
file  notif.c
 Notification (MS-OXCNOTIF) operations.
file  nspi.c
 Name Service Provider (NSPI) stack functions.
file  nspi.h
file  property.c
 Functions for manipulating MAPI properties.
file  property_altnames.h
file  property_tags.c
file  property_tags.h
file  simple_mapi.c
 Convenience functions.
file  utils.c
 General utility functions.
file  x500.c

Creative Commons License
Creative Commons Attribution icon Creative Commons Share Alike icon
This content is licensed under the Creative Commons
Attribution ShareAlike License v. 3.0:
http://creativecommons.org/licenses/by-sa/3.0/

openchange-2.0/apidocs/html/libmapi/doxygen.png000066400000000000000000000073031223057412600216550ustar00rootroot00000000000000‰PNG  IHDRh ;ˆØŠIDATxí]y\•Õº~45%TL Q”PE"q–Û11±]8a„w*©¨(*â" ˆzÀè`8 ¨‰¢mÅ,’òà„p$%”œBó(8k†Ü÷ýÜû6lòö»§k÷Ç÷[ÏÞß·Ö;?k½ëßÕÕÕPxÑêÏ't´ÏùÈ€zÀÇÅ3_€Q4€g@œmÿ ¾ò‰âci‰ôçÿ{ ðÇð¬ù~½Á€4:õHcÂü ðŸÁ³„ª'ÕPÆæ P7^h،♠zb„cóP¨„ 3‚† Ò}çÿO²qÁºNkÝTÛ(É?d Ç~z<’«4Óǡ؞Þv­zµÙ¦õ¬ZâdÛ,Ë6Ók±]Fz< ¾ZçƒsÕ?ìƒsUø2SÉåwê1”c`[ì—}%ѽ.Ô¼6‚BLZ˜û!F8[ ¹…×TéÛ— »Þ#gó]å:vžu?‡vèbÙR˜?wùŽŸ¾ÊÐgbÑÉÌÕ$kF~Ê;عÆ•¢ïX®?ÉèlÆÙôõà»Nʪ¼­,ìHC§gAz•ÆlÓº­gÑú ]œjÎñåM…3ÓÚæoÒ³'=‘$Ò÷f}G•ŸS_‡öèco.Êȹ :ó£ Ãds®Ù:1=¼{ƒå9?÷ý…zqÛvîÓi‰D’p¿Ë šmÙíoÛâýaÖüEqÒµwÌ}¿~{òj€ç{ôºŸFNëí[ëOq·ÇOSúXO]°>‚‚muæÄ¾e¤“5Ë{¨JÕ¯£(›´«bÂçû’ÍlÓÅ}žïú`éUÞy„ac§Á†ÔCºŠóAkl‘±y¥†ô¢ùôs÷Aø¬7ÄõôoJ±äÄ ù.¥Be. Z¬Ð×ÇÈöå¹­ù'Ù-PëìŠyF.ž‚žÝÚ€lp&.êˆð•jò7’re’z19»ã§HGíø%œüq°ïüz׈c¬_k_")ŸHJnÐÑ~ˆÐÖ˜á´äÕ5 µÁq€ÿ5#¸·îà¶+9T‘‚ ðŽ÷Rܸrz“Ï´Ì =Ï…{ðáO£Èf ¡Íwg|Ž’Ü/¢Þ$÷¯¢ëðúÀ;¿à¨Ö™âÒÆ­]¯ÜW"Þ/< ‡÷DÏà°½üB}çyIEc^—ƒ=[V“Ýh²ëMä$l];Kû®¸ýr¦È*Åò ÿtÒõ$]•MŸ÷´;×I€1èó!‚œõ¸M õ¨(fÌæ<ÁÎÎò5~z¿ù¶ž mÌêÕ >–âÚ©âëˆIÎÞçz;ãu[i·eç^ÆÜÙÓ³NÞëF6B\}7†»+üŽÓ,Ã'a ½˜-yHY¿,‘^—ñfú~ß?Hcø¸…¸ñó{Z+4\såƒû·¯Ù·nߣð«íFÆ¡sغëû§D¾?ò<–Ævkx0ÅM±ælذÁIÓxÿd”žÜÉ÷EE»AªM«g*È£YEí7Û™^[uíý®v[wGå†=Ed¼n×¶ÆæÖÅl¡'¨pGÚk+‹æ¢À¬¨C8ªâš2 dz3H£ß ¡¨BÒûSÃÅù[wŘ ~xpçútÁæmö¤Å£¥iQæ­‰AB1ÉfÙ‰›4u¹ïìIÒ]Ë6äò%ÿ†† 1t.’NJph¬zÌ ÎR1Ž"3-"¸‡‹&ìó°1âüžìó[:‡ï„¼‘……N m–“W0®_èÜœ ×õ6ùò&»)Æìꦬýæ}¬ñ~»{múù]z½£M•ºP~^Îá:eQTÙ_*7ÕÄ9É8—·Ëï 3°¶47E•î¿u÷“SÉ»U¯ _ NíºôW¬e¸ÄNÓ|»;™¿;ŒæÅd"ȉôøòÞµõï¾®½"èÄ´ÖMM+bYµ‘_ÉæEÝüÎ]P»¹XKÐI½Þ¥oE<_¹(„EP±Œ|mÇÁ¡‘Ý,ŠÓ©ººZ±Îߺ§×kÝ,kÍMš`Äø…jzeU»æ ™Át3ÓÀ½˜6—ÒöùË·r¨¹Ñ}““wö:Χùë¼ ¿|‚TܵÉQˆKßç_ÁâÀ™œ”pÑÐóໃ¼Ydâ0!®àa –øöçW$ÃÁ‘Á$/\¬$ð 2ÞímÞLH‹Ÿ èd£HVÜ,:ò½»RÍZšJ­a„z*>‹_…NT(ù‚^SVF­U¹8ñEþôñ܈óùnd;«®8™\C]ø=Èêm¬Æ:‚´ÆbãDd=Áãßžˆ‹UU5O‹|]þð®Pèêv‰á\]2ßìÿ"yÈ[ïyʧz£g{Y«{„Ùø5©ÿ;w{N3é­nâĨw§Á¢ÍK¢Ý­ûÏ29Id¿’ì y)ìPÞò8ŒÅ©¯‰±@mPÔñwjl,6 áhWÕ˜d öà uõmÁp®.™á£Ç…twöR x­BδYcŒxg*vo  yò‘•“[¬?ÜVœ˜0ÒN¡O난~Žó’¯·h#´Hkýœ±8kÓß^Àq@]àÓ“ø,56´¯÷Í-κU»n…[>]@nîøÏœp›[œ6# €4tën¯:ŽÒþ}…—8äT9_žY$/´G’K™©ù†•(óÑ’Mø©`ŸÉdѺ;ùO‹B Ó&P{qöhJÉ+Úé–§¦l2«MïöÝ_1ÑÓ«’t¸½±l€ëØya ¦ô©«®½ÆL^¬žêñš¸ùy.¾Û½Š[ u/]½‹iS}øN>²e1™q‡jfÚ&¢©iT\=kÏ›ÀXô-.84V5ðu!TE˜ þ.ŒOH´¶4—zwTr.ï‰¦Ë xõµ·œÖ„HÆù£žÈHùg Ñhñ’T$ßyq¸zþ¨p¿´ë< q•ró÷š‰wÿÍÑð–I]´–æI²é²˜sÂ"×:Õ–bÕ¦“ÈÙL6¢9VÊÓWž§<æ;”3?ý©Mê3AV#µ±ËÞ¯‘ž K£UrÝ9!›qát¦H£Ù+6ÇV…/TS^pÃùqgLP'Ú5E ‚–ÀÞºîÄ Ën"2|Ÿ;®W»Îý"Ö¬TwÖâµtúŽO'› á+W Ã+¦âZÌ–<ÕÆ&nOÝ,IŠ£06.ÁZ.Çñúøh*INÚ’Oe½ÉgBXÐÔZóäøä9èü“hÒíDSš¥¡Ê µA¯/Ôc¸ö“`A§¯"zå|‘ €ÅŸ¨ú;HÍ#‚Î|%ÄOˆƒ«OàÌÉÐÜD ž mÜðâc–ƤÉÂqm¶uË&~÷núÒË £ÇÏ€ZÕj =«_n[‡‡÷nN§ÏÝ$_¾bE˜‚€Õ)ù8¾?6‘lú“ÍÙæÖ}#bW( œ³d-®•p&¡ý’œÖa”"9öõņÐ$’Ú›AÜ!ä;ÐÑõè{~á¹8‘ÛÞ£1ÛÓÉ0ž`²#´kÒuäNÅÖ Q¹bhæ ”8ûÓMáŽa›•¿”w±h²¢®qŠæ°(bK ‚’Z¾Ò%ÐÆémáãÖË(Éý‚ÛJ)@> þ›7% ï{y Á“¾ÆÒîohfòô>{pÿ.­_Î%±ÉèägëlZØ\B2B #™¸ÚüÒºp‚hÝšü®[¥Ü<‹#SpñÌA7’ãØHƒt4:Ÿ|g¨tÓL¶*($Æ©»ì…®ù’ó÷$;b›ÔÙ`=¶£¦M„MÌÄ5ò«·Ç¾“H·ÌH.¼žHeAîº5}r­dõ¨±)ÀT};€Q5iÖ2…O0ü…0óñÃ;óæ,Š´²µ냔}g‘£]‹7å9ˆà©_{üèîêžC>úhê{Ž .ÈìðIIð€?[Kswz6Òuíý¬;µ€ç§OåâJÉa˶zv°éd† ¤µâ‚l´é舊«Åüy¾c÷ÁèÖÍ'ràúÅ™TWÕôÓ°¡L €|ʽŒ¼ì­høBã ÝTëî'ò]Kø£ìâÏ(=¹Kx €¿ LÌ,Pý¤Êµu‡¹…׈ §Å¾÷à1Ý«Äý;¿pGDäxZYÛ kfæ6¸ùóæ7®œ®þ6·ÕoÚ¾ÔH~ò®Þ¸â 8Uø“p<ºw3¡a£ÏÑ’‘3èÏ"€bˆ-ÎܺÏ_ªÅ]+ËM©zü°s“f-êçhÇãÑýÊãôÿ5}ZQNb{Ó?å%ÿ\SUõعIÓæ}~}p[œoÔÄ„êÐMMZáNÅå@>Œ„²á6(?¡Åé âK½+ü?À%ÝÝ·/Ç1‚9áUø?B)”ÕèâÞlÈÒêÏ @=àùÄÞžk­®ÅIEND®B`‚openchange-2.0/apidocs/html/libmapi/dynsections.js000066400000000000000000000041341223057412600223710ustar00rootroot00000000000000function toggleVisibility(linkObj) { var base = $(linkObj).attr('id'); var summary = $('#'+base+'-summary'); var content = $('#'+base+'-content'); var trigger = $('#'+base+'-trigger'); var src=$(trigger).attr('src'); if (content.is(':visible')===true) { content.hide(); summary.show(); $(linkObj).addClass('closed').removeClass('opened'); $(trigger).attr('src',src.substring(0,src.length-8)+'closed.png'); } else { content.show(); summary.hide(); $(linkObj).removeClass('closed').addClass('opened'); $(trigger).attr('src',src.substring(0,src.length-10)+'open.png'); } return false; } function updateStripes() { $('table.directory tr'). removeClass('even').filter(':visible:even').addClass('even'); } function toggleLevel(level) { $('table.directory tr').each(function(){ var l = this.id.split('_').length-1; var i = $('#img'+this.id.substring(3)); var a = $('#arr'+this.id.substring(3)); if (l MAPIClientLibraries 2.0 API Documentation
emsmdb.c File Reference

EMSMDB stack functions. More...

#include <unistd.h>
#include <fcntl.h>
#include "libmapi/libmapi.h"
#include "libmapi/libmapi_private.h"

Functions

enum MAPISTATUS emsmdb_async_connect (struct emsmdb_context *emsmdb_ctx)
struct mapi_notify_ctx * emsmdb_bind_notification (struct mapi_context *mapi_ctx, TALLOC_CTX *mem_ctx)
struct emsmdb_context * emsmdb_connect (TALLOC_CTX *parent_mem_ctx, struct mapi_session *session, struct dcerpc_pipe *p, struct cli_credentials *cred, int *return_value)
struct emsmdb_context * emsmdb_connect_ex (TALLOC_CTX *mem_ctx, struct mapi_session *session, struct dcerpc_pipe *p, struct cli_credentials *cred, int *return_value)
enum MAPISTATUS emsmdb_disconnect (struct emsmdb_context *emsmdb_ctx)
int emsmdb_disconnect_dtor (void *data)
_PUBLIC_ struct emsmdb_info * emsmdb_get_info (struct mapi_session *session)
enum MAPISTATUS emsmdb_get_SPropValue (TALLOC_CTX *mem_ctx, DATA_BLOB *content, struct SPropTagArray *tags, struct SPropValue **propvals, uint32_t *cn_propvals, uint8_t flag)
void emsmdb_get_SRow (TALLOC_CTX *mem_ctx, struct SRow *aRow, struct SPropTagArray *proptags, uint16_t propcount, DATA_BLOB *content, uint8_t flag, uint8_t align)
_PUBLIC_ void emsmdb_get_SRowSet (TALLOC_CTX *mem_ctx, struct SRowSet *rowset, struct SPropTagArray *proptags, DATA_BLOB *content)
NTSTATUS emsmdb_register_notification (struct mapi_session *session, struct NOTIFKEY *notifkey)
_PUBLIC_ NTSTATUS emsmdb_transaction (struct emsmdb_context *emsmdb_ctx, TALLOC_CTX *mem_ctx, struct mapi_request *req, struct mapi_response **repl)
_PUBLIC_ NTSTATUS emsmdb_transaction_ext2 (struct emsmdb_context *emsmdb_ctx, TALLOC_CTX *mem_ctx, struct mapi_request *req, struct mapi_response **repl)
_PUBLIC_ NTSTATUS emsmdb_transaction_null (struct emsmdb_context *emsmdb_ctx, struct mapi_response **res)
void free_emsmdb_property (struct SPropValue *lpProp, void *data)
const void * pull_emsmdb_property (TALLOC_CTX *mem_ctx, uint32_t *offset, enum MAPITAGS tag, DATA_BLOB *data)

Detailed Description

EMSMDB stack functions.

Function Documentation

enum MAPISTATUS emsmdb_async_connect ( struct emsmdb_context *  emsmdb_ctx)

Get an async notification context handle

Parameters
emsmdb_ctxpointer to the EMSMDB context
Returns
MAPI_E_SUCCESS on success, otherwise MAPI error
struct mapi_notify_ctx* emsmdb_bind_notification ( struct mapi_context *  mapi_ctx,
TALLOC_CTX *  mem_ctx 
)
read

Initialize the notify context structure and bind a local UDP port to receive notifications from the server

Parameters
mapi_ctxpointer to the MAPI context
mem_ctxpointer to the memory context
Returns
an allocated mapi_notify_ctx structure on success, otherwise NULL

Referenced by RegisterNotification().

struct emsmdb_context* emsmdb_connect ( TALLOC_CTX *  parent_mem_ctx,
struct mapi_session *  session,
struct dcerpc_pipe *  p,
struct cli_credentials *  cred,
int *  return_value 
)
read

Establishes a new Session Context with the server on the exchange_emsmdb pipe

Parameters
parent_mem_ctxpointer to the memory context
sessionpointer to the MAPI session context
ppointer to the DCERPC pipe
credpointer to the user credentials
return_valuepointer on EcDoConnect MAPI return value
Returns
an allocated emsmdb_context on success, otherwise NULL
struct emsmdb_context* emsmdb_connect_ex ( TALLOC_CTX *  mem_ctx,
struct mapi_session *  session,
struct dcerpc_pipe *  p,
struct cli_credentials *  cred,
int *  return_value 
)
read

Establishes a new Session Context with the server on the exchange_emsmdb pipe using 0xA EcDoConnectEx opnum

Parameters
mem_ctxpointer to the memory context
sessionpointer to the MAPI session context
ppointer to the DCERPC pipe
credpointer to the user credentials
return_valuepointer on EcDoConnectEx MAPI return value
Returns
an allocated emsmdb_context structure on success, otherwise NULL
enum MAPISTATUS emsmdb_disconnect ( struct emsmdb_context *  emsmdb_ctx)

Destroy the EMSMDB context handle

Parameters
emsmdb_ctxpointer to the EMSMDB context
Returns
MAPI_E_SUCCESS on success, otherwise MAPI error

Referenced by emsmdb_disconnect_dtor().

int emsmdb_disconnect_dtor ( void *  data)

Destructor for the EMSMDB context. Call the EcDoDisconnect function.

Parameters
datageneric pointer to data with mapi_provider information
Returns
MAPI_E_SUCCESS on success, otherwise -1

References emsmdb_disconnect().

Referenced by MapiLogonProvider().

_PUBLIC_ struct emsmdb_info* emsmdb_get_info ( struct mapi_session *  session)
read

Retrieves the EMSMDB context server information structure

Parameters
sessionpointer to the MAPI session context
Returns
the server info structure on success, otherwise NULL
enum MAPISTATUS emsmdb_get_SPropValue ( TALLOC_CTX *  mem_ctx,
DATA_BLOB *  content,
struct SPropTagArray *  tags,
struct SPropValue **  propvals,
uint32_t *  cn_propvals,
uint8_t  flag 
)

Get a SPropValue array from a DATA blob

Parameters
mem_ctxpointer to the memory context
contentpointer to the DATA blob content
tagspointer to a list of property tags to lookup
propvalspointer on pointer to the returned SPropValues
cn_propvalspointer to the number of propvals
flagdescribes the type data
Returns
MAPI_E_SUCCESS on success

References free_emsmdb_property(), and pull_emsmdb_property().

Referenced by GetProps().

void emsmdb_get_SRow ( TALLOC_CTX *  mem_ctx,
struct SRow *  aRow,
struct SPropTagArray *  proptags,
uint16_t  propcount,
DATA_BLOB *  content,
uint8_t  flag,
uint8_t  align 
)

Get a SRow from a DATA blob

Parameters
mem_ctxpointer on the memory context
aRowpointer on the returned SRow
proptagspointer on a list of property tags to lookup
propcountnumber of SPropValue entries in aRow
contentpointer on the DATA blob content
flagthe type data
alignalignment pad
Returns
MAPI_E_SUCCESS on success
Note
TODO: We shouldn't have any alignment pad here

References free_emsmdb_property(), and pull_emsmdb_property().

Referenced by OpenEmbeddedMessage(), OpenMessage(), and ReloadCachedInformation().

_PUBLIC_ void emsmdb_get_SRowSet ( TALLOC_CTX *  mem_ctx,
struct SRowSet *  rowset,
struct SPropTagArray *  proptags,
DATA_BLOB *  content 
)

Get a SRowSet from a DATA blob

Parameters
mem_ctxpointer on the memory context
rowsetpointer on the returned SRowSe
proptagspointer on a list of property tags to lookup
contentpointer on the DATA blob content
Returns
MAPI_E_SUCCESS on success
Note
TODO: this doesn't yet handle the TypedPropertyValue and FlaggedPropertyValueWithTypeSpecified variants

References free_emsmdb_property(), and pull_emsmdb_property().

Referenced by ExpandRow(), FindRow(), and QueryRows().

NTSTATUS emsmdb_register_notification ( struct mapi_session *  session,
struct NOTIFKEY *  notifkey 
)

Register for notifications on the server

Parameters
sessionPointer to the current MAPI session
notifkeyThe opaque client-generated context data
Returns
NTSTATUS_OK on success, otherwise NT status error

Referenced by RegisterNotification().

_PUBLIC_ NTSTATUS emsmdb_transaction ( struct emsmdb_context *  emsmdb_ctx,
TALLOC_CTX *  mem_ctx,
struct mapi_request *  req,
struct mapi_response **  repl 
)

Make a EMSMDB transaction.

Parameters
emsmdb_ctxpointer to the EMSMDB connection context
mem_ctxpointer to the memory context
reqpointer to the MAPI request to send
replpointer on pointer to the MAPI reply returned by the server
Returns
NT_STATUS_OK on success, otherwise NT status error
_PUBLIC_ NTSTATUS emsmdb_transaction_ext2 ( struct emsmdb_context *  emsmdb_ctx,
TALLOC_CTX *  mem_ctx,
struct mapi_request *  req,
struct mapi_response **  repl 
)

Make a EMSMDB EXT2 transaction.

Parameters
emsmdb_ctxpointer to the EMSMDB connection context
mem_ctxpointer to the memory context
reqpointer to the MAPI request to send
replpointer on pointer to the MAPI reply returned by the server
Returns
NT_STATUS_OK on success, otherwise NT status error
_PUBLIC_ NTSTATUS emsmdb_transaction_null ( struct emsmdb_context *  emsmdb_ctx,
struct mapi_response **  res 
)

Send an empty MAPI packet - useful to keep connection up or force notifications.

Parameters
emsmdb_ctxpointer to the EMSMDB connection context
respointer on pointer to a MAPI response structure
Returns
NT_STATUS_OK on success, otherwise NT status error

Referenced by DispatchNotifications(), and MonitorNotification().

void free_emsmdb_property ( struct SPropValue *  lpProp,
void *  data 
)

Free property values retrieved with pull_emsmdb_property

Parameters
lpProppointer to SPropValue structure
datageneric pointer to associated lpProp data

Referenced by emsmdb_get_SPropValue(), emsmdb_get_SRow(), and emsmdb_get_SRowSet().

const void* pull_emsmdb_property ( TALLOC_CTX *  mem_ctx,
uint32_t *  offset,
enum MAPITAGS  tag,
DATA_BLOB *  data 
)

Retrieves a property value from a DATA blob

Parameters
mem_ctxpointer to the memory context
offsetpointer on pointer to the current offset
tagthe property tag which value is to be retrieved
datapointer to the data
Returns
pointer on constant generic data on success, otherwise NULL

Referenced by emsmdb_get_SPropValue(), emsmdb_get_SRow(), and emsmdb_get_SRowSet().


Creative Commons License
Creative Commons Attribution icon Creative Commons Share Alike icon
This content is licensed under the Creative Commons
Attribution ShareAlike License v. 3.0:
http://creativecommons.org/licenses/by-sa/3.0/

openchange-2.0/apidocs/html/libmapi/examples.html000066400000000000000000000042511223057412600221750ustar00rootroot00000000000000 MAPIClientLibraries 2.0 API Documentation

Creative Commons License
Creative Commons Attribution icon Creative Commons Share Alike icon
This content is licensed under the Creative Commons
Attribution ShareAlike License v. 3.0:
http://creativecommons.org/licenses/by-sa/3.0/

openchange-2.0/apidocs/html/libmapi/fetchappointment_8c-example.html000066400000000000000000000276151223057412600257630ustar00rootroot00000000000000 MAPIClientLibraries 2.0 API Documentation
fetchappointment.c

This example shows how to fetch an appointment from the server.This is very similar to the fetchmail.c example, except two minor changes:

  • We change the default folder constant from olFolderInbox to olFolderContact so any further operations are performed on a child of the calendar folder.
  • We use mapidump_appointment() rather than mapidump_message() to dump appointments on standard output.
#include <libmapi/libmapi.h>
#define DEFAULT_PROFDB "%s/.openchange/profiles.ldb"
int main(int argc, char *argv[])
{
enum MAPISTATUS retval;
struct mapi_context *mapi_ctx;
TALLOC_CTX *mem_ctx;
struct mapi_session *session = NULL;
mapi_object_t obj_store;
mapi_object_t obj_folder;
mapi_object_t obj_table;
mapi_object_t obj_message;
struct mapi_SPropValue_array props_all;
struct SRowSet rowset;
struct SPropTagArray *SPropTagArray;
mapi_id_t id_inbox;
mapi_id_t *fid, *mid;
char *profname;
char *profdb;
uint32_t Numerator;
uint32_t Denominator;
uint32_t i;
mem_ctx = talloc_named(NULL, 0, "fetchappointment");
/* Initialize MAPI */
profdb = talloc_asprintf(mem_ctx, DEFAULT_PROFDB, getenv("HOME"));
retval = MAPIInitialize(&mapi_ctx, profdb);
MAPI_RETVAL_IF(retval, retval, NULL);
/* Find Default Profile */
retval = GetDefaultProfile(mapi_ctx, &profname);
MAPI_RETVAL_IF(retval, retval, NULL);
/* Log on EMSMDB and NSPI */
retval = MapiLogonEx(mapi_ctx, &session, profname, NULL);
MAPI_RETVAL_IF(retval, retval, NULL);
/* Open Message Store */
mapi_object_init(&obj_store);
retval = OpenMsgStore(session, &obj_store);
MAPI_RETVAL_IF(retval, retval, NULL);
/* Find Inbox default folder */
retval = GetDefaultFolder(&obj_store, &id_inbox, olFolderCalendar);
MAPI_RETVAL_IF(retval, retval, NULL);
/* Open Inbox folder */
mapi_object_init(&obj_folder);
retval = OpenFolder(&obj_store, id_inbox, &obj_folder);
MAPI_RETVAL_IF(retval, retval, NULL);
/* Retrieve Inbox content table */
mapi_object_init(&obj_table);
retval = GetContentsTable(&obj_folder, &obj_table, 0x0, NULL);
MAPI_RETVAL_IF(retval, retval, NULL);
/* Create the MAPI table view */
SPropTagArray = set_SPropTagArray(mem_ctx, 0x2, PR_FID, PR_MID);
retval = SetColumns(&obj_table, SPropTagArray);
MAPIFreeBuffer(SPropTagArray);
MAPI_RETVAL_IF(retval, retval, mem_ctx);
/* Get current cursor position */
retval = QueryPosition(&obj_table, &Numerator, &Denominator);
MAPI_RETVAL_IF(retval, retval, NULL);
/* Iterate through rows */
while ((retval = QueryRows(&obj_table, Denominator, TBL_ADVANCE, &rowset)) != -1 && rowset.cRows) {
for (i = 0; i < rowset.cRows; i++) {
fid = (mapi_id_t *)find_SPropValue_data(&(rowset.aRow[i]), PR_FID);
mid = (mapi_id_t *)find_SPropValue_data(&(rowset.aRow[i]), PR_MID);
mapi_object_init(&obj_message);
retval = OpenMessage(&obj_store, *fid, *mid, &obj_message, 0x0);
if (retval != MAPI_E_NOT_FOUND) {
retval = GetPropsAll(&obj_message, MAPI_UNICODE, &props_all);
mapidump_appointment(&props_all, NULL);
mapi_object_release(&obj_message);
}
}
}
/* Release MAPI objects */
mapi_object_release(&obj_table);
mapi_object_release(&obj_folder);
Logoff(&obj_store);
/* Uninitialize MAPI */
MAPIUninitialize(mapi_ctx);
talloc_free(mem_ctx);
return (0);
}

Creative Commons License
Creative Commons Attribution icon Creative Commons Share Alike icon
This content is licensed under the Creative Commons
Attribution ShareAlike License v. 3.0:
http://creativecommons.org/licenses/by-sa/3.0/

openchange-2.0/apidocs/html/libmapi/fetchmail_8c-example.html000066400000000000000000000364151223057412600243450ustar00rootroot00000000000000 MAPIClientLibraries 2.0 API Documentation
fetchmail.c

This example shows how to fetch mail from the server.We initialize MAPI library with the profiles database path, retrieve the default profile name and open connections to both the Exchange message store provider (EMSMDB) and Exchange Address Book provider (EMSABP).

Open the message store

Now we have opened a connection to the Exchange message store provider, we can open the user mailbox store with OpenMsgStore() This function will return a set of pre-defined folder unique IDs (stored on double values) and a pointer to the upper object we can access in MAPI hierarchy.

Opening the Inbox folder

We now open the Inbox folder. Since OpenMsgStore() returns a set of common folders identifiers we store in the message store object (obj_store), we can retrieve them using the convenient GetDefaultFolder() function. This function doesn't generate any network traffic, but returns the folder identifier associated with the constant passed as argument (here olFolderInbox).

We could have used MAPI tables and GetHierarchyTable() function to find Inbox folder identifier. We would have had to retrieve the Top Information Store hierarchy table, customize the view with PR_FID (Folder ID MAPI property) and PR_DISPLAY_NAME, find the IPM_SUBTREE folder identifier, open it, retrieve the Hierarchy Table, call SetColumns() with PR_FID and finally browse table rows until we found the Inbox folder.folders to store emails within IPM_SUBTREE folder hierarchy.

Retrieve contents table

Once the Inbox folder is opened, we can call GetContentsTable() to create the view needed to list all the children objects. In the current example we suppose we will only retrieve IPM.Post objects (emails).

Customizing the MAPI view

We now customize the MAPI view and set the columns with the property tags we want to access: PR_FID (Folder Identifier) and PR_MID (Message identifier). MAPI uses unique and permanent identifiers to classify objects. These identifiers are double values (8 bytes) and never change until you move the object to another location.

We now enter the last step of the fetching process:

  • Call QueryPosition() to retrieve the current cursor position in the contents table. The function returns the approximate fractional position with a Numerator and Denominator. Denominator is the total number of rows in the table.
  • Recursively call QueryRows() with the TBL_ADVANCE flag to fetch table rows.
  • Iterate through QueryRows results
  • Retrieve columns values for each row with the convenient find_SPropValue_data()
  • Open the message given its folder and message ids.
  • Call GetPropsAll() rather than GetProps() to retrieve all properties associated with a given object
  • Call one of OpenChange mapidump API function to display nice messages dump on standard output.

We finally release mapi objects and clean up the MAPI library before returning

#include <libmapi/libmapi.h>
#define DEFAULT_PROFDB "%s/.openchange/profiles.ldb"
int main(int argc, char *argv[])
{
enum MAPISTATUS retval;
struct mapi_context *mapi_ctx;
TALLOC_CTX *mem_ctx;
struct mapi_session *session = NULL;
mapi_object_t obj_store;
mapi_object_t obj_folder;
mapi_object_t obj_table;
mapi_object_t obj_message;
struct mapi_SPropValue_array props_all;
struct SRowSet rowset;
struct SPropTagArray *SPropTagArray;
mapi_id_t id_inbox;
mapi_id_t *fid, *mid;
char *profname;
char *profdb;
uint32_t Numerator;
uint32_t Denominator;
uint32_t i;
mem_ctx = talloc_named(NULL, 0, "fetchmail");
/* Initialize MAPI */
profdb = talloc_asprintf(mem_ctx, DEFAULT_PROFDB, getenv("HOME"));
retval = MAPIInitialize(&mapi_ctx, profdb);
MAPI_RETVAL_IF(retval, retval, mem_ctx);
/* Find Default Profile */
retval = GetDefaultProfile(mapi_ctx, &profname);
MAPI_RETVAL_IF(retval, retval, mem_ctx);
/* Log on EMSMDB and NSPI */
retval = MapiLogonEx(mapi_ctx, &session, profname, NULL);
MAPI_RETVAL_IF(retval, retval, mem_ctx);
/* Open Message Store */
mapi_object_init(&obj_store);
retval = OpenMsgStore(session, &obj_store);
MAPI_RETVAL_IF(retval, retval, mem_ctx);
/* Find Inbox default folder */
retval = GetDefaultFolder(&obj_store, &id_inbox, olFolderInbox);
MAPI_RETVAL_IF(retval, retval, mem_ctx);
/* Open Inbox folder */
mapi_object_init(&obj_folder);
retval = OpenFolder(&obj_store, id_inbox, &obj_folder);
MAPI_RETVAL_IF(retval, retval, mem_ctx);
/* Retrieve Inbox content table */
mapi_object_init(&obj_table);
retval = GetContentsTable(&obj_folder, &obj_table, 0x0, NULL);
MAPI_RETVAL_IF(retval, retval, mem_ctx);
/* Create the MAPI table view */
SPropTagArray = set_SPropTagArray(mem_ctx, 0x2, PR_FID, PR_MID);
retval = SetColumns(&obj_table, SPropTagArray);
MAPIFreeBuffer(SPropTagArray);
MAPI_RETVAL_IF(retval, retval, mem_ctx);
talloc_free(mem_ctx);
/* Get current cursor position */
retval = QueryPosition(&obj_table, &Numerator, &Denominator);
MAPI_RETVAL_IF(retval, retval, mem_ctx);
/* Iterate through rows */
while ((retval = QueryRows(&obj_table, Denominator, TBL_ADVANCE, &rowset))
!= -1 && rowset.cRows) {
for (i = 0; i < rowset.cRows; i++) {
fid = (mapi_id_t *)find_SPropValue_data(&(rowset.aRow[i]), PR_FID);
mid = (mapi_id_t *)find_SPropValue_data(&(rowset.aRow[i]), PR_MID);
mapi_object_init(&obj_message);
retval = OpenMessage(&obj_store, *fid, *mid, &obj_message, 0x0);
if (retval != MAPI_E_NOT_FOUND) {
retval = GetPropsAll(&obj_message, MAPI_UNICODE, &props_all);
mapidump_message(&props_all, NULL, &obj_message);
mapi_object_release(&obj_message);
}
}
}
/* Release MAPI objects */
mapi_object_release(&obj_table);
mapi_object_release(&obj_folder);
Logoff(&obj_store);
/* Uninitialize MAPI */
MAPIUninitialize(mapi_ctx);
return (0);
}

Creative Commons License
Creative Commons Attribution icon Creative Commons Share Alike icon
This content is licensed under the Creative Commons
Attribution ShareAlike License v. 3.0:
http://creativecommons.org/licenses/by-sa/3.0/

openchange-2.0/apidocs/html/libmapi/files.html000066400000000000000000000343411223057412600214640ustar00rootroot00000000000000 MAPIClientLibraries 2.0 API Documentation
File List
Here is a list of all documented files with brief descriptions:
[detail level 12]
\-libmapi
 o*async_emsmdb.cAsync_EMSMDB stack functions
 o*cdo_mapi.cMAPI subsystem related operations
 o*codepage_lcid.cCodepage and Locale ID operations
 o*emsmdb.cEMSMDB stack functions
 o*freebusy.cConvenient API to access FreeBusy
 o*FXICS.cFast Transfer and Incremental Change Synchronization operations
 o*fxparser.cFast Transfer stream parser
 o*IABContainer.cProvides access to address book containers – Used to perform name resolution
 o*idset.cParsing of GLOBSET structures
 o*IMAPIContainer.cContainers and tables related operations
 o*IMAPIFolder.cFolder related functions
 o*IMAPIProp.cProperties and named properties operations
 o*IMAPISession.cSession initialization options
 o*IMAPISupport.cMAPI notifications functions
 o*IMAPITable.cOperations on tables
 o*IMessage.cOperations on messages
 o*IMsgStore.cFolders related operations
 o*IMSProvider.cProvider operations
 o*IProfAdmin.cMAPI Profiles interface
 o*IStoreFolder.cOpen messages
 o*IStream.cFunctions for operating on Streams on MAPI objects
 o*IUnknown.cVarious miscellaneous (ungrouped) functions
 o*IXPLogon.cTransport provider status information
 o*lzfu.cCompressed RTF related functions
 o*mapi_id_array.cMapi_id_array support functions
 o*mapi_nameid.cMapi_nameid convenience API
 o*mapi_object.cMapi_object_t support functions
 o*mapidump.cFunctions for displaying various data structures, mainly for debugging
 o*notif.cNotification (MS-OXCNOTIF) operations
 o*nspi.cName Service Provider (NSPI) stack functions
 o*property.cFunctions for manipulating MAPI properties
 o*simple_mapi.cConvenience functions
 \*utils.cGeneral utility functions

Creative Commons License
Creative Commons Attribution icon Creative Commons Share Alike icon
This content is licensed under the Creative Commons
Attribution ShareAlike License v. 3.0:
http://creativecommons.org/licenses/by-sa/3.0/

openchange-2.0/apidocs/html/libmapi/freebusy_8c.html000066400000000000000000000241521223057412600225770ustar00rootroot00000000000000 MAPIClientLibraries 2.0 API Documentation
freebusy.c File Reference

Convenient API to access FreeBusy. More...

#include "libmapi/libmapi.h"
#include "libmapi/libmapi_private.h"
#include <ctype.h>

Functions

_PUBLIC_ int GetFreeBusyYear (const uint32_t *publish_start)
_PUBLIC_ enum MAPISTATUS GetUserFreeBusyData (mapi_object_t *obj_store, const char *recipient, struct SRow *pSRow)
_PUBLIC_ enum MAPISTATUS IsFreeBusyConflict (mapi_object_t *obj_store, struct FILETIME *date, bool *conflict)

Detailed Description

Convenient API to access FreeBusy.

Function Documentation

_PUBLIC_ int GetFreeBusyYear ( const uint32_t *  publish_start)

Return the year associated with the FreeBusy start range

Parameters
publish_startpointer to the publish start integer
Returns
a valid year on success, otherwise 0

Referenced by IsFreeBusyConflict().

_PUBLIC_ enum MAPISTATUS GetUserFreeBusyData ( mapi_object_t *  obj_store,
const char *  recipient,
struct SRow *  pSRow 
)

Retrieve FreeBusy data associated with the specified recipient

Parameters
obj_storepointer to the public folder MAPI object
recipientname of the recipient to fetch freebusy data
pSRowpointer to the returned properties
Note
The function returns a SRow structure with the following property tags:
  1. PR_NORMALIZED_SUBJECT
  2. PR_FREEBUSY_RANGE_TIMESTAMP
  3. PR_FREEBUSY_PUBLISH_START
  4. PR_FREEBUSY_PUBLISH_END
  5. PR_SCHDINFO_MONTHS_MERGED
  6. PR_SCHDINFO_FREEBUSY_MERGED
  7. PR_SCHDINFO_MONTHS_TENTATIVE
  8. PR_SCHDINFO_FREEBUSY_TENTATIVE
  9. PR_SCHDINFO_MONTHS_BUSY
  10. PR_SCHDINFO_FREEBUSY_BUSY
  11. PR_SCHDINFO_MONTHS_OOF
  12. PR_SCHDINFO_FREEBUSY_OOF
Returns
MAPI_E_SUCCESS on success, otherwise MAPI error

References FindRow(), GetABRecipientInfo(), GetContentsTable(), GetDefaultPublicFolder(), GetHierarchyTable(), GetProps(), mapi_object_get_session(), mapi_object_init(), mapi_object_release(), MAPIFreeBuffer(), OpenFolder(), OpenMessage(), set_SPropTagArray(), SetColumns(), and SortTable().

Referenced by IsFreeBusyConflict().

_PUBLIC_ enum MAPISTATUS IsFreeBusyConflict ( mapi_object_t *  obj_store,
struct FILETIME *  date,
bool *  conflict 
)

Check if a date conflicts with existing FreeBusy Busy/Out Of Office events

Parameters
obj_storepointer to the public folder MAPI object
datepointer to the date to check
conflictpointer to the returned boolean value
Returns
MAPI_E_SUCCESS on success, otherwise MAPI error

References GetFreeBusyYear(), GetUserFreeBusyData(), and mapi_object_get_session().


Creative Commons License
Creative Commons Attribution icon Creative Commons Share Alike icon
This content is licensed under the Creative Commons
Attribution ShareAlike License v. 3.0:
http://creativecommons.org/licenses/by-sa/3.0/

openchange-2.0/apidocs/html/libmapi/ftv2blank.png000066400000000000000000000001261223057412600220650ustar00rootroot00000000000000‰PNG  IHDRɪ|IDATxíݱðøScOx@ –¨y}IEND®B`‚openchange-2.0/apidocs/html/libmapi/ftv2cl.png000066400000000000000000000007051223057412600213770ustar00rootroot00000000000000‰PNG  IHDRÚ}\ˆŒIDATxíÝ;H#AÇño4Љႇ œ„K‰‡‚á ’ê,m„ØØ vÚžJ°²¹ÚÎþî‚§ XY ÅB|dr³cvo—˜Ä°Ý ù0Ã’™3ÿͤõ”Ëe×´¸Éõ¯1XÞ8Œ‰nQˆ88ööÖ§3*rbñ¯¢û-$¨‚þ´˜“P1Žè@Z…-# Ïú01ÑÏÎêÄ1HkKŸ w¶O@¥ªÈóñ!f§ñu˜åác÷;’sá×Bý[E´Añ±—Í\ß>°ùý¿ÏËÊÂ]–P€zØf| Íñ¯“+Ù´gð5…b  i5ümM³œ_æÍq,ÒcŽõèoÓd´ !¶äò©ô•,ôðÀ{¹¨µYß,€zTÍ8H]𤕘ï7¼»/òó8ËQæ !F€~6ãá?Y ÀA@ŨÁ.@ƒ¶TäÄYïŠËë±r‘µ8Ð*·é>€Šçÿ?€×þŸe[6«xÂIEND®B`‚openchange-2.0/apidocs/html/libmapi/ftv2doc.png000066400000000000000000000013521223057412600215450ustar00rootroot00000000000000‰PNG  IHDRÚ}\ˆ±IDATxíMOS[…Ÿžsúa?-XZ(PD4‚ AWbu`b 77wäHFÆCËÔÂÿà/`vo„ˆAPòq‹P @ ­ûÝè980 îà¤+»§Ýy×^ïZï9SW¹\83g‰3'°Nâçl¹¸_b¯p ïåûÆVÜÖ¡€Ÿ×"¬Ö†X€d]Ðà3“ÉÃÄÌ™xŸ ßMàœ[<çSPkvc—hÈ'…™˜^Åm™hØ7 `Û™¦ èÀåráq›‘œ¾!daeKŸþÆÕ˜:Ì*³_דâèi?I–eP*B7Ÿ¿åô!¹Ýgr6Ër6oKbëþãðôrI”ËTˆüªŒ¨xóö=›ù¢&‰(e+ßóÄkýÇ`ëÁÜb.“¸ÐW×w0¥°jÑzN™¬|©WEãµ¢a¯6[öX†AkÓù*/œ¨‰€ÉY­ ÿV’§–u²jÂ>1W *½·°PGŽzÿ¨/Eg{ ŸÇâaoŠÁVú:è¿™¤1$ôR§W,–ªà¨@ŠË56¾ÀÔÜ-¾,mê¸Î/æè¹– òr5¥T*S(Vf8ö9u’ Õ£w›ùóa=Í<{Ò¡UŒ÷r¯+ÉådDÏF$è°…£é¿`zþ»ÎúöN‘µÜ®0Q3£~_^Ëóâ¯N=ˆvpTà±LžT}ˆîkq†Òm<¼ÎÓ?Zh¿X£ï_þÝ¥[)ƒ `gêÃa_Ô*äÔ2`'=õ´Fÿ2EâÁPú ÷»›l=8‹Wv°%THqÉ¿<"¤ïG¾ÆxH{#ÆÖ«aÔJÕÞ‡—m‹„ çñKsÿàñVŠØ¡°·MâÒ^ TÁ– Ý›r¥ß½ømüÿ_™?ªWİ÷#uIEND®B`‚openchange-2.0/apidocs/html/libmapi/ftv2folderclosed.png000066400000000000000000000011501223057412600234410ustar00rootroot00000000000000‰PNG  IHDRÚ}\ˆ/IDATxí]MOÔ@~ÚúuØlp]ö¿#›Å]PYECˆ\9ù¼yÑß`ÖÄÿàÿÀÉxóâ¢C &=qÐÄ£—vZçv¶3m؃‡vžLûNç}Þ÷}Þ½ZA@n° OäNp ’xóþK°ññ€xÜj”°8sÑ€“ “€œ_¼[Âíæ§ïD'‚•yye+ø¼û 7#rNŸlïük* ¾0Ь_d«_(àñÖ±àôz=ñxõv§÷h©‰z¹€šØP-äóä’̪uý¼$»\DãJc—B4¯ãÝÖ.:£Ï-ÑÏß}µŠLEíºþ #—ûáºÀÏgN;BŠ€6ïýñ䬜…ö@’Ðåñp&™h>p9¤™EEά¨ÎÊ‘" u¥n€$R"?{¹<˜…ë…%PNtâ$‰ß¶±úá+^<é"§2 ªDq”q´\¬«Ò™a–Œ‘©Aÿ€"Ôµ ™êŸèP£}#Eàz{û.8i îp³ê(ADwD¦E<ê¬cE¦$ HdÊÄ ”.:Ù GŽ-`ŒL‚ý¾'¢‰Ä<¤CIª½;ÙÇTZd±i};>èôß‚z×;K×§8t ¤Ž q”:uvÿv•Ý›¬²ÙvEân{„M·FXg¼ÌfZÖ¨°¹‰*›ßÌß©±ù©:›j–YqèÜë#3çÏSøWøÿÿÑr'ø Ôùù‚ ©¡IEND®B`‚openchange-2.0/apidocs/html/libmapi/ftv2folderopen.png000066400000000000000000000011251223057412600231330ustar00rootroot00000000000000‰PNG  IHDRÚ}\ˆIDATxí]?oÓPÿ9iš4i°;ii“¶‰ZЉ‘‰ÀÀ7`bèÔÙ¬Øù,HìU'ô$*Tµ]‚T¡DPÚÄ6wÏ}‰;¡C; a¿ÓߟûÝïîž¼jAÀ­InSþ}€9H“ÓŽ|?íÁ÷ =_ÊÆŠ­†¥Àue*;¯YEäsYäæB¢Ÿ¿þÄ—£sÙ½½ÙŒ† É«›©ÀYÇq !GÇ¿v̇¹ÑØ®š °Œ‚ÔF¹}q¥b]÷7í·0)Úd›¾ÿð-èº}Pfä£ÖY{4™ÑÂ@}úæôñ2ÛüÔ—ñúåNŒI‚ÁǃcçÁº%£¬UаI³mc±ô˜å¼ÔÆüÈ>é¸xþt9Æ$µý OæVE*õU´Ì‚ç#ž×ˆ•ïûr@l$øPÿrHaaÇ¥ ²›dZ®rè‘ãqI„o¼øT\Ž,tªj2FAxv-LŸp׌p TÄI/ \¥sfí½; jViTƒèú¤o^cpÅü¼ûû»Ïb]”€¢¤<†aþÕœ²“ßÓ˜y“£§9:Œîù+À³€ñà,E žf³6éNˆÄE£KU}Ü^;¶ØnZ¢uß­US4— ѬëbížN¶.Úk¦ØjTÄöº%µªâ i¯VÄÊÝò§™ Èù¸)ùÿG€™òºJ@T x”IEND®B`‚openchange-2.0/apidocs/html/libmapi/ftv2lastnode.png000066400000000000000000000001261223057412600226070ustar00rootroot00000000000000‰PNG  IHDRɪ|IDATxíݱðøScOx@ –¨y}IEND®B`‚openchange-2.0/apidocs/html/libmapi/ftv2link.png000066400000000000000000000013521223057412600217350ustar00rootroot00000000000000‰PNG  IHDRÚ}\ˆ±IDATxíMOS[…Ÿžsúa?-XZ(PD4‚ AWbu`b 77wäHFÆCËÔÂÿà/`vo„ˆAPòq‹P @ ­ûÝè980 îà¤+»§Ýy×^ïZï9SW¹\83g‰3'°Nâçl¹¸_b¯p ïåûÆVÜÖ¡€Ÿ×"¬Ö†X€d]Ðà3“ÉÃÄÌ™xŸ ßMàœ[<çSPkvc—hÈ'…™˜^Åm™hØ7 `Û™¦ èÀåráq›‘œ¾!daeKŸþÆÕ˜:Ì*³_דâèi?I–eP*B7Ÿ¿åô!¹Ýgr6Ër6oKbëþãðôrI”ËTˆüªŒ¨xóö=›ù¢&‰(e+ßóÄkýÇ`ëÁÜb.“¸ÐW×w0¥°jÑzN™¬|©WEãµ¢a¯6[öX†AkÓù*/œ¨‰€ÉY­ ÿV’§–u²jÂ>1W *½·°PGŽzÿ¨/Eg{ ŸÇâaoŠÁVú:è¿™¤1$ôR§W,–ªà¨@ŠË56¾ÀÔÜ-¾,mê¸Î/æè¹– òr5¥T*S(Vf8ö9u’ Õ£w›ùóa=Í<{Ò¡UŒ÷r¯+ÉådDÏF$è°…£é¿`zþ»ÎúöN‘µÜ®0Q3£~_^Ëóâ¯N=ˆvpTà±LžT}ˆîkq†Òm<¼ÎÓ?Zh¿X£ï_þÝ¥[)ƒ `gêÃa_Ô*äÔ2`'=õ´Fÿ2EâÁPú ÷»›l=8‹Wv°%THqÉ¿<"¤ïG¾ÆxH{#ÆÖ«aÔJÕÞ‡—m‹„ çñKsÿàñVŠØ¡°·MâÒ^ TÁ– Ý›r¥ß½ømüÿ_™?ªWİ÷#uIEND®B`‚openchange-2.0/apidocs/html/libmapi/ftv2mlastnode.png000066400000000000000000000003661223057412600227720ustar00rootroot00000000000000‰PNG  IHDRɪ|½IDATxíÝ!NAÅñ¤‡à\ ÷à Um@`Ô5iÒ`ëh ‚ÅW7] b§ÝˆŠ&oföÍd¾YÔ4 üšcø ‡€´‹Åòù3v=¼]†§µ\B… I¿‹=B·™B¡®;¸k´µ W°ÍN@vyÍÑÖ4ãß÷]ÈâYìã§|M}]ÔÚx6a }ôdׇØYüú¨>¤||5?Ó>|žB"¡î'¡IEND®B`‚openchange-2.0/apidocs/html/libmapi/ftv2mnode.png000066400000000000000000000003661223057412600221060ustar00rootroot00000000000000‰PNG  IHDRɪ|½IDATxíÝ!NAÅñ¤‡à\ ÷à Um@`Ô5iÒ`ëh ‚ÅW7] b§ÝˆŠ&oföÍd¾YÔ4 üšcø ‡€´‹Åòù3v=¼]†§µ\B… I¿‹=B·™B¡®;¸k´µ W°ÍN@vyÍÑÖ4ãß÷]ÈâYìã§|M}]ÔÚx6a }ôdׇØYüú¨>¤||5?Ó>|žB"¡î'¡IEND®B`‚openchange-2.0/apidocs/html/libmapi/ftv2mo.png000066400000000000000000000006231223057412600214130ustar00rootroot00000000000000‰PNG  IHDRÚ}\ˆZIDATxí1Kû@ÆiƒØB…Ò¡(h¬"EÄI'ÁoàªèÚ©ßÀáâä 8ùçR-‚â B«TPˆï]z¥B’3 _Þã’»ç}ŸË]VÇ÷}€ÌÈdIæ®i쟯JØ–b¸šÍÃõ+º™|KÂ…°,[Pï\ʘMÆ¢#€ä…F`JݤìÛk³úA±àþè?ØY4ck6"¹Z)ê¸0SHM¨@ï㋺WÖmo¼4èHJ¨Àÿö+…QobŒút ¤ú’*Ð~êè8_+3Y-ñðÜå½÷ ˜PwA¶+^ý}ºì£+xìhÏ•MAE]€TD~EÞߴ^R)`ÖAùŸÏ9©pÔq-Û¾õÛ3tÝÊÆ›ˆÃTÐHÈ)€ ½Š’ICªxëd#1ôú§é€ m@Vüý?Zæßgo_½3-³\IEND®B`‚openchange-2.0/apidocs/html/libmapi/ftv2node.png000066400000000000000000000001261223057412600217230ustar00rootroot00000000000000‰PNG  IHDRɪ|IDATxíݱðøScOx@ –¨y}IEND®B`‚openchange-2.0/apidocs/html/libmapi/ftv2ns.png000066400000000000000000000006041223057412600214170ustar00rootroot00000000000000‰PNG  IHDRÚ}\ˆKIDATxíÝ1K1Àñ­ž ØG•â‚n‚Šà ‚âælÁE¿€‹“ (nºêââêäࢋƒÐMAá@°‹ µât¾ÄK¡à%Ü•Û ý]BIïå%áuÍ…a™€,e × v¯ç¥«ˆi‹º¨Õö–î\tòòuénÄ0ã æÜÉoV\Ì$G.&@Y=ÆË%$um·¢ûÛ6–'Úß«9Qó\bÙ)²º0Ðë-Zœ¥TèHÍ`pÀcsm µö5:>Áë‡Þ¦I µØ ‚F‹Çà]» ›jg—ìoÏáõ©[ œõ š­onë €Ô¬¨vqõ„?\Ðç”  6»øüÒTe ÃÉéŸeç ÀÅlQ ¡c”€ª¬ü3*d€ÅWTMÏ\rÿÿh6™ø1±F ‹°fžIEND®B`‚openchange-2.0/apidocs/html/libmapi/ftv2plastnode.png000066400000000000000000000003451223057412600227720ustar00rootroot00000000000000‰PNG  IHDRɪ|¬IDATxí=QF‘Ø¥D«ÔkÄ:‰F©PK؃=V@§Õ³ Õ8SHxñÌ0bnrróŠ{ò½¿¾’$ ÀÏTŠP  ö¼X¬OÛd6êìòð"°²S´±O¥B€(¡àQé)š+YĈ ÒªËRÉÐ>VtÉsˆm9(ê„䜥k‚-@ȧ-Ü$ó b Ò[he ¿Kp-ôl|CùÿApRG'rÍ­aIEND®B`‚openchange-2.0/apidocs/html/libmapi/ftv2pnode.png000066400000000000000000000003451223057412600221060ustar00rootroot00000000000000‰PNG  IHDRɪ|¬IDATxí=QF‘Ø¥D«ÔkÄ:‰F©PK؃=V@§Õ³ Õ8SHxñÌ0bnrróŠ{ò½¿¾’$ ÀÏTŠP  ö¼X¬OÛd6êìòð"°²S´±O¥B€(¡àQé)š+YĈ ÒªËRÉÐ>VtÉsˆm9(ê„䜥k‚-@ȧ-Ü$ó b Ò[he ¿Kp-ôl|CùÿApRG'rÍ­aIEND®B`‚openchange-2.0/apidocs/html/libmapi/ftv2splitbar.png000066400000000000000000000004721223057412600226220ustar00rootroot00000000000000‰PNG  IHDRM¸¿IDATxíÝ¡JCa‡ñç(˜ ëƒ%±Ø4 b±È˜Í¶3˜v^Á±˜…ãó–ŽELƒõ…¥•³ ,ÿb;íç{Ã/¼ðÞÀaYÕ¯åóøq:¼º¹›\òIIIIIIIIIIIIIIIIII-Òçl¹›«õ抢è_t/Ï»ã£ÑíYQVõðêäíã÷´×ùY¬Úÿµ§¦ivók¾_íåýÛ£I@$I@$I@$I@$I@$I@$I@$I@$I@$I@$I@$I@$I@$I@$I@$I@$I@$I@$ýC[Vì=ü[„fÆIEND®B`‚openchange-2.0/apidocs/html/libmapi/ftv2vertline.png000066400000000000000000000001261223057412600226260ustar00rootroot00000000000000‰PNG  IHDRɪ|IDATxíݱðøScOx@ –¨y}IEND®B`‚openchange-2.0/apidocs/html/libmapi/fxparser_8c.html000066400000000000000000000235561223057412600226140ustar00rootroot00000000000000 MAPIClientLibraries 2.0 API Documentation
fxparser.c File Reference

Fast Transfer stream parser. More...

#include "libmapi/libmapi.h"
#include "libmapi/libmapi_private.h"
#include "libmapi/fxparser.h"

Functions

_PUBLIC_ struct fx_parser_context * fxparser_init (TALLOC_CTX *mem_ctx, void *priv)
_PUBLIC_ enum MAPISTATUS fxparser_parse (struct fx_parser_context *parser, DATA_BLOB *fxbuf)
_PUBLIC_ void fxparser_set_delprop_callback (struct fx_parser_context *parser, fxparser_delprop_callback_t delprop_callback)
_PUBLIC_ void fxparser_set_marker_callback (struct fx_parser_context *parser, fxparser_marker_callback_t marker_callback)
_PUBLIC_ void fxparser_set_namedprop_callback (struct fx_parser_context *parser, fxparser_namedprop_callback_t namedprop_callback)
_PUBLIC_ void fxparser_set_property_callback (struct fx_parser_context *parser, fxparser_property_callback_t property_callback)

Detailed Description

Fast Transfer stream parser.

Function Documentation

_PUBLIC_ struct fx_parser_context* fxparser_init ( TALLOC_CTX *  mem_ctx,
void *  priv 
)
read

initialise a fast transfer parser

_PUBLIC_ enum MAPISTATUS fxparser_parse ( struct fx_parser_context *  parser,
DATA_BLOB *  fxbuf 
)

parse a fast transfer buffer

_PUBLIC_ void fxparser_set_delprop_callback ( struct fx_parser_context *  parser,
fxparser_delprop_callback_t  delprop_callback 
)

set a callback function for delete properties output

_PUBLIC_ void fxparser_set_marker_callback ( struct fx_parser_context *  parser,
fxparser_marker_callback_t  marker_callback 
)

set a callback function for marker output

_PUBLIC_ void fxparser_set_namedprop_callback ( struct fx_parser_context *  parser,
fxparser_namedprop_callback_t  namedprop_callback 
)

set a callback function for named properties output

_PUBLIC_ void fxparser_set_property_callback ( struct fx_parser_context *  parser,
fxparser_property_callback_t  property_callback 
)

set a callback function for property output


Creative Commons License
Creative Commons Attribution icon Creative Commons Share Alike icon
This content is licensed under the Creative Commons
Attribution ShareAlike License v. 3.0:
http://creativecommons.org/licenses/by-sa/3.0/

openchange-2.0/apidocs/html/libmapi/globals.html000066400000000000000000000104641223057412600220050ustar00rootroot00000000000000 MAPIClientLibraries 2.0 API Documentation
Here is a list of all documented functions, variables, defines, enums, and typedefs with links to the documentation:

- a -


Creative Commons License
Creative Commons Attribution icon Creative Commons Share Alike icon
This content is licensed under the Creative Commons
Attribution ShareAlike License v. 3.0:
http://creativecommons.org/licenses/by-sa/3.0/

openchange-2.0/apidocs/html/libmapi/globals_0x63.html000066400000000000000000000142661223057412600225710ustar00rootroot00000000000000 MAPIClientLibraries 2.0 API Documentation
Here is a list of all documented functions, variables, defines, enums, and typedefs with links to the documentation:

- c -


Creative Commons License
Creative Commons Attribution icon Creative Commons Share Alike icon
This content is licensed under the Creative Commons
Attribution ShareAlike License v. 3.0:
http://creativecommons.org/licenses/by-sa/3.0/

openchange-2.0/apidocs/html/libmapi/globals_0x64.html000066400000000000000000000114611223057412600225640ustar00rootroot00000000000000 MAPIClientLibraries 2.0 API Documentation
Here is a list of all documented functions, variables, defines, enums, and typedefs with links to the documentation:

- d -


Creative Commons License
Creative Commons Attribution icon Creative Commons Share Alike icon
This content is licensed under the Creative Commons
Attribution ShareAlike License v. 3.0:
http://creativecommons.org/licenses/by-sa/3.0/

openchange-2.0/apidocs/html/libmapi/globals_0x65.html000066400000000000000000000140541223057412600225660ustar00rootroot00000000000000 MAPIClientLibraries 2.0 API Documentation
Here is a list of all documented functions, variables, defines, enums, and typedefs with links to the documentation:

- e -


Creative Commons License
Creative Commons Attribution icon Creative Commons Share Alike icon
This content is licensed under the Creative Commons
Attribution ShareAlike License v. 3.0:
http://creativecommons.org/licenses/by-sa/3.0/

openchange-2.0/apidocs/html/libmapi/globals_0x66.html000066400000000000000000000134461223057412600225730ustar00rootroot00000000000000 MAPIClientLibraries 2.0 API Documentation
Here is a list of all documented functions, variables, defines, enums, and typedefs with links to the documentation:

- f -


Creative Commons License
Creative Commons Attribution icon Creative Commons Share Alike icon
This content is licensed under the Creative Commons
Attribution ShareAlike License v. 3.0:
http://creativecommons.org/licenses/by-sa/3.0/

openchange-2.0/apidocs/html/libmapi/globals_0x67.html000066400000000000000000000241701223057412600225700ustar00rootroot00000000000000 MAPIClientLibraries 2.0 API Documentation
Here is a list of all documented functions, variables, defines, enums, and typedefs with links to the documentation:

- g -


Creative Commons License
Creative Commons Attribution icon Creative Commons Share Alike icon
This content is licensed under the Creative Commons
Attribution ShareAlike License v. 3.0:
http://creativecommons.org/licenses/by-sa/3.0/

openchange-2.0/apidocs/html/libmapi/globals_0x68.html000066400000000000000000000101541223057412600225660ustar00rootroot00000000000000 MAPIClientLibraries 2.0 API Documentation
Here is a list of all documented functions, variables, defines, enums, and typedefs with links to the documentation:

- h -


Creative Commons License
Creative Commons Attribution icon Creative Commons Share Alike icon
This content is licensed under the Creative Commons
Attribution ShareAlike License v. 3.0:
http://creativecommons.org/licenses/by-sa/3.0/

openchange-2.0/apidocs/html/libmapi/globals_0x69.html000066400000000000000000000130701223057412600225670ustar00rootroot00000000000000 MAPIClientLibraries 2.0 API Documentation
Here is a list of all documented functions, variables, defines, enums, and typedefs with links to the documentation:

- i -


Creative Commons License
Creative Commons Attribution icon Creative Commons Share Alike icon
This content is licensed under the Creative Commons
Attribution ShareAlike License v. 3.0:
http://creativecommons.org/licenses/by-sa/3.0/

openchange-2.0/apidocs/html/libmapi/globals_0x6c.html000066400000000000000000000102771223057412600226470ustar00rootroot00000000000000 MAPIClientLibraries 2.0 API Documentation
Here is a list of all documented functions, variables, defines, enums, and typedefs with links to the documentation:

- l -


Creative Commons License
Creative Commons Attribution icon Creative Commons Share Alike icon
This content is licensed under the Creative Commons
Attribution ShareAlike License v. 3.0:
http://creativecommons.org/licenses/by-sa/3.0/

openchange-2.0/apidocs/html/libmapi/globals_0x6d.html000066400000000000000000000355151223057412600226520ustar00rootroot00000000000000 MAPIClientLibraries 2.0 API Documentation
Here is a list of all documented functions, variables, defines, enums, and typedefs with links to the documentation:

- m -


Creative Commons License
Creative Commons Attribution icon Creative Commons Share Alike icon
This content is licensed under the Creative Commons
Attribution ShareAlike License v. 3.0:
http://creativecommons.org/licenses/by-sa/3.0/

openchange-2.0/apidocs/html/libmapi/globals_0x6e.html000066400000000000000000000143331223057412600226460ustar00rootroot00000000000000 MAPIClientLibraries 2.0 API Documentation
Here is a list of all documented functions, variables, defines, enums, and typedefs with links to the documentation:

- n -


Creative Commons License
Creative Commons Attribution icon Creative Commons Share Alike icon
This content is licensed under the Creative Commons
Attribution ShareAlike License v. 3.0:
http://creativecommons.org/licenses/by-sa/3.0/

openchange-2.0/apidocs/html/libmapi/globals_0x6f.html000066400000000000000000000121771223057412600226530ustar00rootroot00000000000000 MAPIClientLibraries 2.0 API Documentation
Here is a list of all documented functions, variables, defines, enums, and typedefs with links to the documentation:

- o -


Creative Commons License
Creative Commons Attribution icon Creative Commons Share Alike icon
This content is licensed under the Creative Commons
Attribution ShareAlike License v. 3.0:
http://creativecommons.org/licenses/by-sa/3.0/

openchange-2.0/apidocs/html/libmapi/globals_0x70.html000066400000000000000000000107131223057412600225600ustar00rootroot00000000000000 MAPIClientLibraries 2.0 API Documentation
Here is a list of all documented functions, variables, defines, enums, and typedefs with links to the documentation:

- p -


Creative Commons License
Creative Commons Attribution icon Creative Commons Share Alike icon
This content is licensed under the Creative Commons
Attribution ShareAlike License v. 3.0:
http://creativecommons.org/licenses/by-sa/3.0/

openchange-2.0/apidocs/html/libmapi/globals_0x71.html000066400000000000000000000105001223057412600225530ustar00rootroot00000000000000 MAPIClientLibraries 2.0 API Documentation
Here is a list of all documented functions, variables, defines, enums, and typedefs with links to the documentation:

- q -


Creative Commons License
Creative Commons Attribution icon Creative Commons Share Alike icon
This content is licensed under the Creative Commons
Attribution ShareAlike License v. 3.0:
http://creativecommons.org/licenses/by-sa/3.0/

openchange-2.0/apidocs/html/libmapi/globals_0x72.html000066400000000000000000000130031223057412600225550ustar00rootroot00000000000000 MAPIClientLibraries 2.0 API Documentation
Here is a list of all documented functions, variables, defines, enums, and typedefs with links to the documentation:

- r -


Creative Commons License
Creative Commons Attribution icon Creative Commons Share Alike icon
This content is licensed under the Creative Commons
Attribution ShareAlike License v. 3.0:
http://creativecommons.org/licenses/by-sa/3.0/

openchange-2.0/apidocs/html/libmapi/globals_0x73.html000066400000000000000000000176351223057412600225750ustar00rootroot00000000000000 MAPIClientLibraries 2.0 API Documentation
Here is a list of all documented functions, variables, defines, enums, and typedefs with links to the documentation:

- s -


Creative Commons License
Creative Commons Attribution icon Creative Commons Share Alike icon
This content is licensed under the Creative Commons
Attribution ShareAlike License v. 3.0:
http://creativecommons.org/licenses/by-sa/3.0/

openchange-2.0/apidocs/html/libmapi/globals_0x74.html000066400000000000000000000102721223057412600225640ustar00rootroot00000000000000 MAPIClientLibraries 2.0 API Documentation
Here is a list of all documented functions, variables, defines, enums, and typedefs with links to the documentation:

- t -


Creative Commons License
Creative Commons Attribution icon Creative Commons Share Alike icon
This content is licensed under the Creative Commons
Attribution ShareAlike License v. 3.0:
http://creativecommons.org/licenses/by-sa/3.0/

openchange-2.0/apidocs/html/libmapi/globals_0x75.html000066400000000000000000000101231223057412600225600ustar00rootroot00000000000000 MAPIClientLibraries 2.0 API Documentation
Here is a list of all documented functions, variables, defines, enums, and typedefs with links to the documentation:

- u -


Creative Commons License
Creative Commons Attribution icon Creative Commons Share Alike icon
This content is licensed under the Creative Commons
Attribution ShareAlike License v. 3.0:
http://creativecommons.org/licenses/by-sa/3.0/

openchange-2.0/apidocs/html/libmapi/globals_0x77.html000066400000000000000000000103001223057412600225570ustar00rootroot00000000000000 MAPIClientLibraries 2.0 API Documentation
Here is a list of all documented functions, variables, defines, enums, and typedefs with links to the documentation:

- w -


Creative Commons License
Creative Commons Attribution icon Creative Commons Share Alike icon
This content is licensed under the Creative Commons
Attribution ShareAlike License v. 3.0:
http://creativecommons.org/licenses/by-sa/3.0/

openchange-2.0/apidocs/html/libmapi/globals_defs.html000066400000000000000000000046311223057412600230050ustar00rootroot00000000000000 MAPIClientLibraries 2.0 API Documentation

Creative Commons License
Creative Commons Attribution icon Creative Commons Share Alike icon
This content is licensed under the Creative Commons
Attribution ShareAlike License v. 3.0:
http://creativecommons.org/licenses/by-sa/3.0/

openchange-2.0/apidocs/html/libmapi/globals_func.html000066400000000000000000000104101223057412600230070ustar00rootroot00000000000000 MAPIClientLibraries 2.0 API Documentation
 

- a -


Creative Commons License
Creative Commons Attribution icon Creative Commons Share Alike icon
This content is licensed under the Creative Commons
Attribution ShareAlike License v. 3.0:
http://creativecommons.org/licenses/by-sa/3.0/

openchange-2.0/apidocs/html/libmapi/globals_func_0x63.html000066400000000000000000000142121223057412600235730ustar00rootroot00000000000000 MAPIClientLibraries 2.0 API Documentation
 

- c -


Creative Commons License
Creative Commons Attribution icon Creative Commons Share Alike icon
This content is licensed under the Creative Commons
Attribution ShareAlike License v. 3.0:
http://creativecommons.org/licenses/by-sa/3.0/

openchange-2.0/apidocs/html/libmapi/globals_func_0x64.html000066400000000000000000000114051223057412600235750ustar00rootroot00000000000000 MAPIClientLibraries 2.0 API Documentation
 

- d -


Creative Commons License
Creative Commons Attribution icon Creative Commons Share Alike icon
This content is licensed under the Creative Commons
Attribution ShareAlike License v. 3.0:
http://creativecommons.org/licenses/by-sa/3.0/

openchange-2.0/apidocs/html/libmapi/globals_func_0x65.html000066400000000000000000000140001223057412600235700ustar00rootroot00000000000000 MAPIClientLibraries 2.0 API Documentation
 

- e -


Creative Commons License
Creative Commons Attribution icon Creative Commons Share Alike icon
This content is licensed under the Creative Commons
Attribution ShareAlike License v. 3.0:
http://creativecommons.org/licenses/by-sa/3.0/

openchange-2.0/apidocs/html/libmapi/globals_func_0x66.html000066400000000000000000000133721223057412600236040ustar00rootroot00000000000000 MAPIClientLibraries 2.0 API Documentation
 

- f -


Creative Commons License
Creative Commons Attribution icon Creative Commons Share Alike icon
This content is licensed under the Creative Commons
Attribution ShareAlike License v. 3.0:
http://creativecommons.org/licenses/by-sa/3.0/

openchange-2.0/apidocs/html/libmapi/globals_func_0x67.html000066400000000000000000000241141223057412600236010ustar00rootroot00000000000000 MAPIClientLibraries 2.0 API Documentation
 

- g -


Creative Commons License
Creative Commons Attribution icon Creative Commons Share Alike icon
This content is licensed under the Creative Commons
Attribution ShareAlike License v. 3.0:
http://creativecommons.org/licenses/by-sa/3.0/

openchange-2.0/apidocs/html/libmapi/globals_func_0x68.html000066400000000000000000000101001223057412600235700ustar00rootroot00000000000000 MAPIClientLibraries 2.0 API Documentation
 

- h -


Creative Commons License
Creative Commons Attribution icon Creative Commons Share Alike icon
This content is licensed under the Creative Commons
Attribution ShareAlike License v. 3.0:
http://creativecommons.org/licenses/by-sa/3.0/

openchange-2.0/apidocs/html/libmapi/globals_func_0x69.html000066400000000000000000000126151223057412600236060ustar00rootroot00000000000000 MAPIClientLibraries 2.0 API Documentation
 

- i -


Creative Commons License
Creative Commons Attribution icon Creative Commons Share Alike icon
This content is licensed under the Creative Commons
Attribution ShareAlike License v. 3.0:
http://creativecommons.org/licenses/by-sa/3.0/

openchange-2.0/apidocs/html/libmapi/globals_func_0x6c.html000066400000000000000000000102231223057412600236510ustar00rootroot00000000000000 MAPIClientLibraries 2.0 API Documentation

Creative Commons License
Creative Commons Attribution icon Creative Commons Share Alike icon
This content is licensed under the Creative Commons
Attribution ShareAlike License v. 3.0:
http://creativecommons.org/licenses/by-sa/3.0/

openchange-2.0/apidocs/html/libmapi/globals_func_0x6d.html000066400000000000000000000354411223057412600236630ustar00rootroot00000000000000 MAPIClientLibraries 2.0 API Documentation
 

- m -


Creative Commons License
Creative Commons Attribution icon Creative Commons Share Alike icon
This content is licensed under the Creative Commons
Attribution ShareAlike License v. 3.0:
http://creativecommons.org/licenses/by-sa/3.0/

openchange-2.0/apidocs/html/libmapi/globals_func_0x6e.html000066400000000000000000000142571223057412600236660ustar00rootroot00000000000000 MAPIClientLibraries 2.0 API Documentation
 

- n -


Creative Commons License
Creative Commons Attribution icon Creative Commons Share Alike icon
This content is licensed under the Creative Commons
Attribution ShareAlike License v. 3.0:
http://creativecommons.org/licenses/by-sa/3.0/

openchange-2.0/apidocs/html/libmapi/globals_func_0x6f.html000066400000000000000000000121231223057412600236550ustar00rootroot00000000000000 MAPIClientLibraries 2.0 API Documentation
 

- o -


Creative Commons License
Creative Commons Attribution icon Creative Commons Share Alike icon
This content is licensed under the Creative Commons
Attribution ShareAlike License v. 3.0:
http://creativecommons.org/licenses/by-sa/3.0/

openchange-2.0/apidocs/html/libmapi/globals_func_0x70.html000066400000000000000000000106371223057412600236000ustar00rootroot00000000000000 MAPIClientLibraries 2.0 API Documentation
 

- p -


Creative Commons License
Creative Commons Attribution icon Creative Commons Share Alike icon
This content is licensed under the Creative Commons
Attribution ShareAlike License v. 3.0:
http://creativecommons.org/licenses/by-sa/3.0/

openchange-2.0/apidocs/html/libmapi/globals_func_0x71.html000066400000000000000000000104241223057412600235730ustar00rootroot00000000000000 MAPIClientLibraries 2.0 API Documentation
 

- q -


Creative Commons License
Creative Commons Attribution icon Creative Commons Share Alike icon
This content is licensed under the Creative Commons
Attribution ShareAlike License v. 3.0:
http://creativecommons.org/licenses/by-sa/3.0/

openchange-2.0/apidocs/html/libmapi/globals_func_0x72.html000066400000000000000000000127271223057412600236040ustar00rootroot00000000000000 MAPIClientLibraries 2.0 API Documentation
 

- r -


Creative Commons License
Creative Commons Attribution icon Creative Commons Share Alike icon
This content is licensed under the Creative Commons
Attribution ShareAlike License v. 3.0:
http://creativecommons.org/licenses/by-sa/3.0/

openchange-2.0/apidocs/html/libmapi/globals_func_0x73.html000066400000000000000000000175611223057412600236060ustar00rootroot00000000000000 MAPIClientLibraries 2.0 API Documentation
 

- s -


Creative Commons License
Creative Commons Attribution icon Creative Commons Share Alike icon
This content is licensed under the Creative Commons
Attribution ShareAlike License v. 3.0:
http://creativecommons.org/licenses/by-sa/3.0/

openchange-2.0/apidocs/html/libmapi/globals_func_0x74.html000066400000000000000000000102161223057412600235750ustar00rootroot00000000000000 MAPIClientLibraries 2.0 API Documentation
 

- t -


Creative Commons License
Creative Commons Attribution icon Creative Commons Share Alike icon
This content is licensed under the Creative Commons
Attribution ShareAlike License v. 3.0:
http://creativecommons.org/licenses/by-sa/3.0/

openchange-2.0/apidocs/html/libmapi/globals_func_0x75.html000066400000000000000000000100471223057412600236000ustar00rootroot00000000000000 MAPIClientLibraries 2.0 API Documentation

Creative Commons License
Creative Commons Attribution icon Creative Commons Share Alike icon
This content is licensed under the Creative Commons
Attribution ShareAlike License v. 3.0:
http://creativecommons.org/licenses/by-sa/3.0/

openchange-2.0/apidocs/html/libmapi/globals_func_0x77.html000066400000000000000000000102241223057412600235770ustar00rootroot00000000000000 MAPIClientLibraries 2.0 API Documentation
 

- w -


Creative Commons License
Creative Commons Attribution icon Creative Commons Share Alike icon
This content is licensed under the Creative Commons
Attribution ShareAlike License v. 3.0:
http://creativecommons.org/licenses/by-sa/3.0/

openchange-2.0/apidocs/html/libmapi/header.jpg000066400000000000000000002264161223057412600214340ustar00rootroot00000000000000ÿØÿàJFIFddÿìDuckydÿîAdobedÀÿÛ„ÿÀÍ4ÿÄû     a!Qqð1A‘¡¢d ±"Ô%U•ÕV–Ö”WÑñ#EÁá2DT·BR3C$uµ&g(8x’S£³4…6¦hbc¤´Å†G§)   !1AQq"“ÓT”ÔUa2‘¡Ò#³´u6±BRVÁÑb²3$v'7ðár&ñ‚’¢CS%Âsƒ£4Dct¤5ef(ÿÚ ?ýAîÊåSñMÁÙB8v)¸;(GÅ7eáØ¦àì¡;Ü”#‡b›ƒ²„pìSpvPŽŠnÊñMÁÙB8v)¸;(GÅ7eáØ¦àì¡;Ü”#‡b›ƒ²„pìSpvPŽŠnÊñMÁÙB8v)¸;(GÅ7eáØ¦àì¡;Ü”#‡b›ƒ²„pìSpvPŽŠnÊñMÁÙB8v)¸;(GÅ7eáØ¦àì¡;Ü”#‡b›ƒ²„pìSpvPŽŠnÊñMÁÙB8v)¸;(GÅ7eáØ¦àì¡;Ü”#‡b›ƒ²„pìSpvPŽŠnÊñMÁÙB8v)¸;(GÅ7eáØ¦àì¡;Ü”#‡b›ƒ²„pìSpvPŽŠnÊñMÁÙB8v)¸;(GÅ7eáØ¦àì¡;Ü”#‡b›ƒ²„pìSpvPŽŠnÊñMÁÙB8v)¸;(GÅ7eáØ¦àì¡;Ü”#‡b›ƒ²„pìSpvPŽŠnÊñMÁÙB8v)¸;(GÅ7eáØ¦àì¡;Ü”#‡b›ƒ²„pìSpvPŽŠnÊñMÁÙB8v)¸;(GÅ7eáØ¦àì¡;Ü”#‡b›ƒ²„pìSpvPŽŠnÊñMÁÙB8v)¸;(GÅ7eáØ¦àì¡;Ü”#‡b›ƒ²„pìSpvPŽŠnÊñMÁÙB8v)¸;(GÅ7eáØ¦àì¡;Ü”#‡b›ƒ²„pìSpvPŽŠnÊñMÁÙB8v)¸;(GÅ7eáØ¦àì¡;Ü”#‡b›ƒ²„pì__gÓâ£êE~•²O\VݪÏãžà…·#÷Á?Nž•cÏ´Ôô™Û£¾!àÞÖ²x¬.c;s÷<%Íåå+ÝÁ’¾ºckO¦‹£Êcq0}ç)sµµi®W¶6׳SÈpo× 'ü߯Wí¬?þ«[7ð¿™áÜï¨]ù¥‚øócûëëvþqkúß„ÿ›øÇñå­õ¥?á2ÿùßP»óHøócûçëpyůëvþoc/Ç–¿Ö”¿†Ëÿç=BëÍ#ãÍïœW­Áçýn¿ÍÜeøî×úÒá‡2¿Ã¹ÏPºóIüy²=óŠõ¸<â×õ· 7qŸã»_ëJ?†Êÿç=BëÍ#㽑ïœW­ÁçýlÂÿÍÌiøê×úÒ—ðÇ™?áÜç¨]y¤|w²=óŠõ¸<â×õ¯ ÿ6ñ§ã«cë:?†<Êÿç=BëÍ#㽑ïœW­Áç¿­XcùµÛYÑü1æOø{9ê^iì|â½n8§ëNþlãoÇ6ÏÖt ¹“þÎzךGÇ{#ß8¯[ƒÎ-Z0×óg~8¶~³£øeÌðösÔn¼Ò>:Ù>ùÅzÜqkúφÿ›ßñųõ/áŸ2?ÃÙ¿QºóHøëdûçëpyÅ?Y°à÷²¾8üom}gGðË™áìߨÝy¤þ:Ù>ùÅzÔqkú͇šøãñ½µõ•Ã>d‡³~£uæ‘ñÖÉ÷Î+Ö óŠ~²áßæ¶9ümm}eGðϘÿáìߨÝy¤|u²}óŠõ¨<â×õ“5q×ãkoë*_ÃNcÿ‡ó~£uæ‘ñÎÊ÷Æ+Ö ó‹_ÖiìÏ{âýj8µýVÅÌ›ñtÃéy…îÏ©\ù´|o³=ï‹õ¨<⟪¸°{Ù&Äü]ðú?‡<Â÷gÔ®|Ú>6Ù¾÷ÆzÔqkú©‹™/âØ‡Ñü9æ¸s>¥sæÑñ¶Í÷¾3Ö ó‹_ÕL[üDZÀü>á×0}Ùõ+Ÿ6ŸÆÛ7ÞøÏZƒÎ)ú§‹¿˜ö7âȇÑü:æ¸s>¥sæÑñ¶Í÷¾3Ö ó‹_Õ,_üƱ¿A|:—ðï˜âÌz•Ï›GÆÛ7ÞøÏZƒÎ-Tq€÷²-Ž?þë‚øuþ`{‹1êW>mìß{ã=j8§ê†1þbYŠà¾Gðï˜âÌz•Ï›GÆ»;ÞøÏZƒÎ-Sñ—óÈüUðê?‡{ÿÜYR¹óhø×g{ßëPyÅ?Sñ—óÉüUðê_ÃÍÿî,Ç©\ù´þ5ÙÞöÆzÌqkúŒÿ˜VWâ˜?‡Qü<ßþâÌzÏ›GÆ»;ÞØÏYƒÎ-Sq ÷²•ø¦á´w÷¸³§sæÑñ®Î÷¶3Ö`óŠ~¦c_æ —ø¢á´w÷¸³§sæÑñ¦Î÷¶3Öaó‹_Ô¼müÀ²ÿB|6áîþ÷cÔî|Ú>4ÙþöÆzÌ>qOÔ¬müÀ³?Â|6—ð÷{/êw>mlÿ{c=fËZþ¤ã¿öoâx_†Ñü>ß¾ãËúÏ›GÆ›?ÞØÏY‡òÔýIǬßÄп £ø}¿}Ç—õ;Ÿ66½±¾³å­R1ÏßÛ;ñ4/Ã(þoßqåýNçÍ£ãMŸïlo¬Ãùk_Ô|s÷öÎüK ðÊ_Ãýûî<¿©Üù´þ3ÙþöÆúÌ?–§ê6:ûùgþ%†øeÃýùî<¿©Üy´|g´=íõ˜-kúŽþýÙÿ‰a¾Gðÿ~{“/êwmí{c}fËSõýû´?Cü2€7ß¹2þ§qæÑñžÐ÷¶7Öaüµ¯ê&<ûõh~$‡øe/€7ß¹2Þ§qæÑñžÐ÷®7Öaüµ?Pñïß«Gñ?Ã)ü¾ýÉ—õ;6Œö‡½q¾³å­Pñ÷ß›GñGÂé|¾ýÉ–õ;6Œ¶‡½q¾³å©ú…¾üZ_ˆâ>GÀ;ïÜ™oS¸óiüe´}ëõ˜-kúƒþüZ_ˆ¢>GÀ;ëÜ™oS¸ói|e´}ëõ˜-OÔ÷ÞÓüEðº_ï¯re½Rãͧñ–Ñ÷®7Öaüµ¯ê÷ÚÓüCðº>ß>åËz¥Ç›GÆ[GÞ¸ßY‡òÔû`ýöµ?Äü.€·×¹2Þ©qæÑñ–Ñ÷®7Öaüµ¯Ûëï­©ø‚'át|¾}Ë–õK6Œv½q¾³å©öúÂûëjþ ‰øUoŸrå½RãÍ£ã£ï\o¬Ãùk_·¶ßKWñW¨ø |û—-ê—mízã}fËSíå‡÷ÒÖú~+áT¾ßåÊú¥Ç›GÆ;KÞ¸ïY‡òÖ¿o,?¾–·Óñ_ £à=ñî\¯ª\y´|c´½ëŽõ˜-O·v'ß;_éø¯…Qð&ø÷.WÕ.<Ú>1Ú^õÇzÌ?–µûwbýòµþŸ‹øUïrå}RãͧñŽÒ÷®;Öaüµ>ÝX¿|­§¢þGÀ{ãܹ_T¸óhøÇi{×ë0þZŸn¬o¾6ÇÓÑ £àMñî\¯ª\y´|a´½ëŽõ˜-köæÆûãl}=ðª>ÞþåÊú¥Ç›GÆOÞ˜ïY‡òÔûqcýð¶~ŒøM/7¿¹²¾©qæÑñ†Ò÷¦;Öaüµ¯Û‹ï…³ôìgÂhø{û›+ê—mm?zc½fËSíÅ‘÷ÂÙúv3á4| ½ýÍ•õK6Œ6Ÿ½1Þ³å©öÞÈûßm}9ðš>ÞÞæÊú¥Ç›GÆOÞ˜ïY‡òÔûodýï¶¾œŒøMïose}Rãͣ㠧ïLw¬Ãùk_¶ÖOÞëkéÈÏ„Ñð.÷÷6WÕ.<Ú>/Ú~ôÇzÄ?–§Ûk+ïu·ôÜoÂhø{{›+ê—mm?zc½fËZýµ²¾÷[MÆü&w·¹²¾©qæÑñ~Ó÷¦;Ö!üµ>ÚÙ_{m¿¦ã~Kàmíîl¯ª\y´þ/Ú~ôÇzÄ?–§Û[/ïm¹ôÜoÂhø{{›)ê—m/Œ6Ÿ½1Þ±å©öÒËûÛn}7ðš>ÞÞæÊz¥Ç›GÆOÞ˜ïY‡òÔûieýí·>›øMoose=Rãͣ㠧ïLw¬Ãùj}´²þöÛŸMÆü&··¹²ž©qæÑñ†Ó÷¦;Öaüµ>ÚY{mϦã~GÀÛÛÜÙOT¸óhøÃiûÓë0þZŸm,¿½¶çÓq¿ £àmíîl§ª\y´|a´ýéŽõ˜-O¶–_ÞÛsé¸ß„Ñð6ö÷6SÕ.<Ú>0Ú~ôÇzÌ?–§ÛK/ïm¹ôÜoÂhø{{›)ê—mm?zc½fËSí¥—÷¶Üún7á4| ½½Í”õK6Œ6Ÿ½1Þ³å©öÒËûÛn}7ðš>ÞÞæÊz¥Ç›GÆOÞ˜ïY‡òÔûieýí·>›øMoose=Rãͣ㠧ïLw¬Ãùj}´²þöÛŸMÆü&··¹²ž©qæÑñ†Ó÷¦;Öaüµ>ÚY{mϦã~GÀÛÛÜÙOT¸óhøÃiûÓë0þZŸm,¿½¶çÓq¿ £àmíîl§ª\y´|a´ýéŽõ˜-O¶–_ÞÛsé¸ß„Ñð6ö÷6SÕ.<Ú>0Ú~ôÇzÌ?–§ÛK/ïm¹ôÜoÂhø{{›)ê—mm?zc½fËSí¥—÷¶Üún7á4| ½½Í”õK6Œ6Ÿ½1Þ³å©öÒËûÛn}7ðš>ÞÞæÊz¥Ç›GÆOÞ˜ïY‡òÔûieýí·>›øMoose=Rãͣ㠧ïLw¬Ãùj}´²þöÛŸMÆü&··¹²ž©qæÑñ†Ó÷¦;ÖaüµÈ[.Õâ)8há'(,™Ed"©,’¥¦ªJLEP‚Sˆ¡ZÜðMk;í®ctw1¼µìp-s\ÓG5Í4-sH ‚P¬ô3Eqn-Þ×Àö‡5Í!ÍsH¨s\ AÄ/£³éñWÔ¹+ô©Ùôø¨ú‘_¥bï¼JÆàXññ‰¶•Èeƒ‹\D[G2NJ&CC6*ä1ORöêÜ 6¾ñÈîKÞsS,û«×> §hð'•¿jGÐ8A<‹H/u†–ð«‚ònió6Û`ãÛ«Y.á¸i10ý–7£½xtÖ¡£†§Æ€¯oL…xäi¥® Òᑸ$Ö1÷T|¹Ì‹DÎmïFhV±í?䤉˜sk_§[khmÍn'mYÃidÐ*Ðò8j‘ÿjGž·<—Õð¶sqf·-ó²9ˉn.[ƒýV7ì±£©­.( uV|µb*”ë©ÓDꔪmÓÜþŠ’;SªPS¸)P& PSn½=ú’ÔU()ÕRZª©ANº)Õ)UÛã¤GjuJ wM`¥*›u÷jKSªPSnÞ*’ÔꔨÓN…UL íñÒ¢uJU:½ÊšR‚}‹SªR©·ÇPZR‚•ORuLUzüƒJ©Õ)TÛ§Oz•N©ANà¨-L ¦Ýj UU)Tê÷*t”ÁL XRN½‰J¦Þ¡¥¤'T §UAjuJ uÔ§T¥So½SBª©AOëè¤{Mºûµ%¡:¥*›t©-N©AJ‚ÔꔪmñÒ¡N©ANò…MªR©×ÑH´& R©¶ µ:¥*KU”Û¯MMN©ANò…*'T §^ЩÒR‚›jKSªPS¸* S)TÛ®Á©¥ª@S¤<´“ª`S¯¢•uH m©-N©@üõ©‚ªsPÔ–§T §pRâR‚›u¥@RU%©Õ(yõ©-Nªà~ª’ÔꔚŠQ:¤ŸNš<)Õ()J€§T€}µ%©×ëH)Õ 9ô©-N©ãÓSDU 9ôé¥Ç­:¤ÒàSW…-)Ô¤=Iju€~z)ñWs I¨ª@?8x©S±5p?0ÿM.=iÔ¤ÑÀ£‚¸)Q:•p5M¨ëWÒÒŸ\ SBŠö«„<4¨ª¸<5:SVs .!UÀÂT'^Õp?pQNÄS±\ J‰ÔŽ•®´¨Š…`0ôÒ¢t À`è¥E4ZÒIkB¡ P…(B”!J¥R„)B¡ P…(B”!J¥R„,®Áw ¹f"Éc “8±K^ð$Óþ@è§_›ûç÷Û1ûVïôò/»¶‡îž/öu·èX²?³îÒµo¶/À§gÝ¥…~pxš»e®Üõ•K¹2ÇŒ½ni57fÞ*Ù”u‚D¦ÑL}4ÞPÆ0òˆ×ì?%0V.U` Ç°5³ãmî^zÝ-ÌMžGÒ|g+ÐÐ@ ó{š[¼¶ÿÊËxíF+é hêÀ÷DÀ;õ*ꔪXTÐ'TÅSn¾íIjuJ mÒ¤µ:¥* SªR©·]ƒJŠª”é(TÒ©Õ0)×ÑRZR•Mµ%©Õ()ÕÑQ¥:¥:È4¨R•M½CR@N½©ANà¤ZR•MºÔ§T¥SnžåAjª¦:ú)'T ¦ßMuJ uR-N©ANº‚ÔꔪsžçôT–§T §pT¦bR©·Çߥ@R‚U%©Õ()×PZª© §0éÝâ©-N©ANà¥Å:¥*›|u4ªPSª‘jª¥6ëPZRU%©Õ((=54¢uH mÓ¦—…:¥óÒ =ª@?0Ô–ªªP?=N”ê§æ¡¨-N©Nz\SªPSn½Þ:\:ÐKObuHÛRZ~¤€~z’ÔêÌ:ôÔ–§T€~~JT#¡4…?0ëKÂ{RéR½¯b@?0÷tT{UÀýu%©×±\ ú "ª@8ôÔiNªàpè飈OÀ4¸u¢½ªàz(Ÿ ¦‰×µ\4ˆ@§R¸<<•:S©Væ’;Sª¸|<´´¦®})P„+†•{Sª¸Žà¬ (Ž#¡_ZTOWjÔ˜iQ>[{ž•¢¶ 4’¢Ö’JP…(B”!J¥R„)BYðÒ–¨<;ï\ùU0ø«ó{|þûf?jÝþžE÷vÐýÒÅþζý `ö;<•«T-‹þÝ*v;<”T#þÝ+ò•ŸÍ»žshkÞ˹$4—”Í~Öò¨Êý·ûú¤+óü÷šý­yúÄ‹©€ýU¾­N©@ýu%©Õ )·J‚Ôêš'T ¦Ý;¼TxSJçÿMRuH mê’Ôê”çä©-N© ¦Ýj Sªû™6y éQí\½xàà›v¬ÐUË•Ô0èTÑAUNo×ÒÇfYÜÖBÑR礞[ùÀ\ãÐOàYKcðožïTÐr[IKyŠú®n5>/W³0”@bRªø ©Ã@2e 5¯7ÌókcaÜcuÛg¿Õ‹ÇãÙ«ƒz»|+mÆì}Ë“ðÛ=±ž5p§¯Â<+¸à2è†dçn„ƒEÛ ©XGª)¦.I¯½Qs ”1¬Tļ¢<•ªÅÎìMäÝÕ•»ŠHÔáS@]Ð:*ÐOJÊͰo,ÁûãÈ¡¡£M:iÓÆ´<;*¶ÙÚ±)ÿçƒÒ¡È.b„©ïhôÆn7Cx{ýí9DC½]«~k™Èÿtiû2Ÿý=«„íá;ª[H‚ºÆàá®àˆrá«Y¦.\ šJKº ²b²~Žå#%5KCrD `Ö¶+`cîãl¯ŠFÆâE{(iÄ#¾#¤®ÆÔž²F—Ž®Úñ ‘кVn͹mÓÆQª‘0HGEÐäå×}=t^PïVÝi—ÇÞÌH5£À¬Î6ö׌Œ%½£ˆ\dëò dhB©MºtÒ-N½©AJ‚Õ@¥*›u©-N©J§UM uL uÒ N©J¦ßIjuJ uT–§T §]AjuJU6éîTЧUÚ¸kßÛ!@ã\{Y†uSˆ(º‚Þ6&9¸’S÷TôH¸Ô5:§C‰¦E9mcwîÌ&ÈÀO¸óòì UïyàÈão Oyà8¹Å­pÎíͽ”Ý9x°¸vk¼”õš5iï=MhâOz ˆÖ»—†ogg1QŒø¯ÉÒWîF~Å'«Ú±on&†äû@ûfÃ2sñQ«†".å¤IÈ”D‚AÔ…ùœÝçŸ3ndŸ—0ã¶ûZٞ؜ziãKr oxà\Èb%WIú5ü¹åNÆ…‘o[¹/sh&6:FýXà!íiè–@Ò)Ð>7{,ø·]K/dIÜQ“Ý$¸Á@Ê>ºAÓåÐ)tôxlŒåó[°¦L¦TÌã%Sz ”ÇÌ„8î¹—üÃr茖òµ¶ÊàZGxö²?ÿÕ¬0ž€,.Ž´q* ØüšÞ€Ùm©æÇåÈ:]!$ô'.véŽPúTðy¡Ä>¿¸gÉ1ÖAj¨dFFÛ¸˜‚ƒ v@¨±ÑBZ)UCDÅ7 ”ÑfËJmJ$9þ¢å÷0°ÆÁ37„qkÓ,N§y ”©cÀémxñ^Þ"†­ ¼6n_ee‹Ê4MQÈß±++@æ“Äv9§‹OŠÒÅWn½5½P­N©J§W”)Pê˜ëè©-N© ¦ßAjuL TéUT¥W¯È54N©J¦Ý:{Ô¨ªPS¸*KSªb©·Z‚ÔêªuTé)Õ0+Éà%Mz=íá×pÛgá«´ÓW×ùçK4iy•¥Pc¢­Çˆz*j¦@o¢²Šk¦º€‡5|ÏÉ.iîmñ—ËÙn7Àè,û¾ëDa‡Æ|­5 šðcWºsO``¶¦7u…l¢[}æ·—±‘N8¸¯9ÐpUS*…C ×ÒbŽ ÃÏB¾S®‘j*”ªsžçôTé)Õ0)ýaI0{•Mºûµ:BuJ uT–§T §]AjuHU6øêtªª`S«hRER•Mºû´¨ª@Sn•%ªª”¨-N©AM¾:)Õ()Ïã ”ÁìJU6ëîÒ N©ANªE©Õ )×PZR‚›t÷?¢¤µ:¤9ùv…M uJU6õ / uJ sÒÓØRù†¤µ:¤÷AjuJ >½5:Sª@Sª—ÒúépER–”궤µ:ýJàpè©-N©@ãÏ­AjuWõyiP§T qç×ËK‚jàz4ö'^Ä€na©!íHç©-M\ Ì:TRÇÃËS¥5p8séÓKˆN©ãGpëWÒ¢~p7pR!:ö«Ç¦¤µp8R¡N¥\ >©#µ:«ù§Jjà`ðÒ⬢½©×µ\ÝÞ¢ÀÛ|tQB¶´¨ž¥`0ÔÑ>[{ž•¢×]hIkI%(B”!J¥Y‰Ã"Zµt:wݸý!¼5ù½¾}³µnÿX‘}Ý´?tñ³­¿BŘ½vµª­NÇ»Z¿%œB˜ Ÿów´Ì90QRxÔt.¸ÁÔ`9p¬rU¶ªö/»BRòŽ¥3 cx¥þ€¾ÁtW}ÔM‘À;…[Bþ׬ý+L=Áµïß##™Ä WéT•Ã%0z«uœ1lªNY±lGGP§Uºí[z:E1A¹;!U° aÐÄÝY[qq]ops^ò@¨TõšÐÖ¾õÃmËZHkšæ´H$)NÒà6tT»uÐ(£¤À@éiÛ4PL'2J”Šö§HU DtÝ0ˆw‚³Ö™››g‡>ˆõô8vŠŠOè\ca˜‹ êêðý…bÍׄ;~áó3e%¸²ÌôìÚÉ•2†Lœ€T]ƒ©Š:r›”¼¡èÍé÷hÃåÖûZÑÕâYôöÓéâ:ºV§}¶ÅËÜÖQ“õ§ÛðýKæ¡¥íÉâæY,Åësn¨ŠÀÈ S¦r “P‡(€Š"^‘ÈYå-ÅÍ“Ãã=#è#¤-òÊæÂcËK_øm¥Sª»ÄÕªPS¯¢¦:¥6øé¢©ANª‚ÕUJ uÔ§T¥Sn”¨Sª`Sú¦0R‚›u÷i§Uï²ù„!ᓉŽ*åcŠòJÜgv¤˜(,6Æ/²P¾d2T¥¦œì”ˆ&¨Q:ŒSäÔ¡¯Â¿Íýæâßø\A!m¤‚'štw×sºÝ®pë1±•o`‘Üx•õw!í-°ÛC/½ef«†wéîíâ8Ø÷:‡´°v/ÎmËv^yÊÿ¹ò ñ0îjáºæžMLÉ:Pç3‡o DŠcfÙ=Ô›¢MA2HR€}7€ÀÚYØÁˆÆF!Æ[FØã`àZ)õ“Òç.q.$’Jð¼¾Zâæê\óÌ—ó¼½î=$Ÿè €€.Ml-ò>bAìTÜCÖ’‘R±Î–g!'ºnØ¿bñ¹ÓpÕë7ID”!Šr bˆl·vÖæÙöÓµ¯†F¹®µÍp!Í ð ƒB ÁÙ¸‚fÏ ‹$cƒšA¡‚è Š‚:è ‰PâCÙ}‰¸ŸœI±¯Ë[BFj]š w/¤n„pýþÙºiãx雼È=ôtôìŲ`<„øƒ–lŸ–œþÈìkg8bî ¬k 'ÅýîÜšô¹ÕšN§µõ>ùt[ã”6[®pÓÅÔh¿îóØ×IGPti‹¯ø<à“ñ¹jôŸ“²îtç®I^ËM‘ ~ß¶­™F.eŸ:Žzvñ‰ŠVúnKÛ® "‰Ì œ¤Ž÷Ìþyo=“̶müD1]â´E¶ýÝd’YXàÆ‡¶¯§{ éhÔà AÔj[•;gtlgfr2Éo¼µÑŒŽ7´¸–š7ìjq $P(­f\ÞÇ®øŒÂѰy I)Gmm˜|Å55|FÛ“So\›йnÖÉǬñÚ…!Vun3Ž(˜ }ÒjjÆå2ßÍ?ýÕ5æ<@Àe}Œq[>HØÑW0àMtù:'‚ïXc¹ y|Üv׆gnß$ÍcÜMá(“®·k;h8¬Aã[†ü%eVV¹dœNØ×“S–Àñ""ùvlÜ‘´œ¿bšMTœ€U ²ˆ”©,ƒ„V$* )ûw'y­mÌý¾ë¹£m¾rÙâ;ˆÚIn¢*Ù#©'»P8’×5í«ƒCå|Êåôû0-£{¦ÅNÒø^áãP9 [ "€‡5ÔÒ3^ßá#†°Ì`ã®beåÃw‘3BbÈG²Ì×AUZðA½¾â2nRàbÐå3õÌõœk%Næ0¦ª¾9›ç/0÷þë¸Ûšd1c- ^ÊÖ8:ŽÓÞVPøÙœ‰¢9&ú©¬ô¼_,önÐÛðçy˜éd¾¸E«öÒ£VŠFZ÷HÑöÝ­‘°5&Žv㋱W³ƒŽÖ'¾pžX‡Šs0Ê"æy5"õÓDTI°É:‰œ»o(yèvΦUÒŽ”jõ 9Na)?ÊÄe¹Ï~U]Ñß²ÍmÉ$ s¢dlš-’(-ßÈK¥‰ñš=~Êå70-ä²ÚͺÆf˜Â懹ï$tUÌ’YšöEC$cÅA<:p7á"¯ÅͷÞ[báºÍò¶eÞÊ9éÛ*ªh$åB:Œ~RýE$á²ÀPíT¦ÓßWÐ;›µÜªºß»RF—ýÀO {A’ÞM$µÍ¯:—Žà¶{›Ì }£¸àß½÷R†šTMZîÇpsM8´ƒÖ½!Íü;{:øC¹Ô›Î7Ï4Òàd̶fŒ›”{qºi);–IHYy±håúG#uWxÁ‘{#¦Qp®¥OæýµÍŽyóÛ­¥½Ä/qžýñ±±Ôš²&6FICH. ŽI A:ÅÞÙœåç*6Uñ»Ï¾âhdhî­÷Òž4Ž,sBꆒö0Pôqۆá~÷⃲Ï[/±›IçÓvÔ¤ÂøšÔ‹Nภf#î‰Yçì¦Fß\ŽX®ÉâV0•1)Äæ2Y]½Í¾gìÎ`ZìÞh¾ »KçÆÖLÆDÂÞõÝÜr1в&º>ðÈÙ#®Pt3<ºØ{›gÜnm„Ù­®m÷:7:GjîÛ­ì{e|ŽÑã1Ìyi45%¸YÁw ’¼[_îa’V ǵڳ–¾nVȦáÓ6VU(Øh¤•Õ›3UÁªIYcN̨©îÙæ¥,öã2"6Üfnœæ[BI sš|#w¦êŽqs u·Ê¹yËû½óšuž³2Ý¡ÓÈHÖ0ßGi'ƒC\â ]™ÕËì…ÃWš˜¢ä¶/ËÞfAX’ø†œ½åb!ä[j“Óɺ‡½­ÖÏÔb࢚¿ź!V)ŠÑð¬~SùÜXѸ­o¬l­¦`’+gÅl×½§‹CCíåsC‡ßLÓJEW¬^cù…½8k‹[«©ãv‰'l“9­pàK‹&Œ:‡î¢p­EEñµÂ±áì\ň®U®ì” ȰRN¥ æ%üÌZ×!“lÙ²2ðif ‰{b‚'"¢aÜQOGäç8o·­ÅÖÖÝ6ÛwØêÖ [#XáÉa$²XÞ@‘ é:mZÝ'™|µµÚðÛç¶ô®ŸmÝÓIqsæ—´jjcÙRÃMB„:¦„ú›Ç$áî÷ǘG#ñ=’ÝØ8Ÿ·|ñìdYŒ”Íó;sCÛ‰CÛ‘«7Aü¢‚bB.u[±j£ÅRÔÄQ¹QbüË}É»0ùÌž/eZ6ç; s¾Ä,òHàK[ýqG=Á€ð!䆟£7¾näñV7û¦àÁ‰´a%­ûR¹íf–4€]ýSPÖ—ÐZ#0¾1öjñŽÎî°8ˆ½1ÎA‚<Ó7Ò·r²Å*현ëx»†íº æbI¼n“´w›¹pP(§¾U ë9®`së–2Úå·eÅžC,¡Žcc€2´'»/ŠdcËC‹ã¶­5¡ióÌ^ÏåûŽã·a¹²ËG ç>RêT a²K+Ð⇊î<¨#ÍÜ]‚®|ÄppÞ.›F\ñ÷½Éh\²eIWlⳓ žU$ñI7i ¹ÛÆH®ɾMð0}5œæ>'Ëçó5ÒX›H¦Š:†¹îœ0E6Dâ¢7Ë èZݿˡ´ð1fùŽé$½¸%³ Å*+¢‘–½Ïí¸½‘°5&ŽwÛŒñÏ³ëŒÆSvŸÊ^x(ÄŹ—gq:—~ñËDTI¸È8‹™º.Ø™¸–îI„“g‰Êcn—¿ŠÊs¼±ºŠÿy¾Ï/·ä1α°jtµñÃãyé2Dö=û ʽùo%žØmÎ72Æ4=Ïq#¢¥¯–V½ ‘PÉñÓÀ/0o[js_V<º›•Ëg̼„–nCï¢+µ>‰ºj ”¢»íÌEÐS@íP¦Ó–¾ªÛÙìvæÃÛæñŽÕes^Úð –¸u9¦­pêp#©|û™ÃÞà²Sb¯Û¦ê NŠŽ±Ú(ZzÁl`¦ÚÌ–¬]R‚œõ%©Õ()·ÇQ¥:ö¥:B’uJU:éP'T€¦Ú’Ôꔩ-N©J¦Þ¡¨-N½©N%*ÁìJU6ëJƒ­:¤ÒÒRÇŸü5©×êHŽŠ’Ôê”×SDêŠ\zÓª@S®•骯֔5¨¨W‡EIjª¤MN”U :)qN©ýt¸&iN¥ ˜ÃRZЏž§J¤€na©#µWóù*tö&¥Ät§Up?=Á )iOR¸•¨ëWMN”ü à`šUX !ÞD'Up?8xªt¦®÷tR⮢½©×µ\E;AÔ¬ÛJˆ© ÚÒ¢u Àaé¥Dè ¶ðtR¢TZÒIkBJP…š¼/¥«%ÇNû•‡Æq¯ÍÝóûí˜ý«wúyÝÛC÷Oû:Ûô,Y•Øì%jËbS±Ø>J¿"E›wˆLî^AÓ2äðñ^ó•ûmÊ^Ví¯ØÿÕ!_˜;üÿçÌßí{ÏÖ$]:}+}-Z•RǦ¤µ:«ÃŸü%©Ô¥¦ˆª@Sª—…4 §_»Jƒ©:¤íÓ`÷iRZV}p'ÁܧײÒÓÈ®ÏYÎP5Èü¦;aœúBË'E(™.Ñí^*MN‹}ºBxo;9³mËl3ml‹_¹®Ú{–ô÷lè38uÐðŒwO}?–{ãzd4˜{r †´ÖãÄF ¥^EHoG ýOÚöE³í˜èf­áã3lÕ„dB ƢѓtÀ­Ù7*'A"9@‚0ˆˆ˜F¿2²yœŽw%%õã-ËÞ\çÈKËœOð$ý<P_qãñVx‹&ZÛ€ÈÚÐX@ph Ãô®•ÉR™mÙ26oÌòÎÑ(n¬¼œ˜,Î(«€êº†kG*ûýGUÓ7€+rÛØ·ºÍ×Ré&~†ž ÆQϧPÔâÆðþˇjÕ³™Xb¼À†²&kpë/}ZÀGI£Cÿ¬Ò°Ç%ܳnÓ21Ò±=ªÄIwÒë‘è"©€‡8™ER€a0ê¥{ÙÆØDðû¸åš€ÈÅ\HãØkà^G¹2ykÚEc¦8I£žç^.  óÿ(Ý ­rN¾É¬u’¹&ÞÛwMQh“.™"£[î.ýu”Mªc¨¡¸Q(W¿m«ëo ¾)ú#·´p:µW¼Ô4P¸öñ5â¼Ö÷\×ËutÇÈ纮0=”#WWàà†œ´KÙ踟ï`3¦poܧïùDp»dÞ †ºŽœºÖjò×--Ö±i`ÁÒ5½ 9ÞÑoÜÚ>wÿ…ßåqY ¶Ü1•Ní’Id M !8©Í®ø€¬fG\ᨓRh™€6W}˜Ü–÷‹8ÍGK$‡€8¯ŠNšÐ[pxtU®ÿ%h¹ 2|ù ‹†Ï $S1;6ÇRHñŽVLM¡Š²R̘$s¦ è Bòë aß·¬ -’9¢ãSâêÿêýwºmÙïƒ8}`E£Ì„I¢Ý\q²úìÝ©K²ìǹ0ªŸ`C9ng ©ÄNQÓPä÷_û”[²FØÊÉcpã¸8pã@hïĹMûæ{ ÃÇ´ý¡Ðxý ò}|Çr LfØ”O(Bo71Duôg €ª¡˜,n›C å/½ÔµÖÁenðwBXxÛ»í0žŸiÄ~?É’³·ÊÀbž‚Aö\:ùâüKß³{õÄ|ƒu¼j ¦»u‹¸¡  Aï”ä1G¼bˆr {¥…í¾JÕ·VƱ»ñ°¼²öÎk ƒo8£‡AíD/œê®ÑjëU()×Q¥:¥*›¢•;SªPS¸)P'T ¦Ýz{õ%©Õ()ÕRZR‚u{ª÷¯ÙâÑ,ÙÀ/ü>D™²—‹är<\{E쀆É8ÑË>AÁÌ©@¡ö–Ðj;©P u÷ÚüüȶM³Î]¿¼gÔ1Õ¹.¥xÚܹÓ4pÿåHÃÛãpê_[òL³9Ë<ÆÚ‹I¾×0èž¶'?üÆ?èñWçfÄh´y2|ÕvR Ü.Ñë7h¨ÝÛGm”2.9n±Hª¬A)ÈpÀ !¨WÙûxÅ-³fˆ‡FáPAx‚àAA æ\À’9Ìr״Ђ(A ƒÐGEe‚~A­ˆµaj½Ã⥠`¯bõ¥.Â:äÈ XL££]ê›Ôeî\¨læá’ÈDÉ8a àªû¢‘ɸmÈ?Ÿ8‹¶oæƒ!ŸÆ%…£æ«ÛöK!µÀõ‡<´‚:A¨à¾ÃÉ[»mòÓ| .îzC¥œÝ–‘ÔZÀA Š+®1r˰Ë35š†”›O|†›q\‘f$¡@@wN™Ä¦ð€ˆ%wwHÕüÍãôxÿV™upœ‹¾#ÿœÿÓļ&³­”ݲ (mý7ŠmD SwÀ@C”š¾ÅÆâÙ45“Bù²úùÑËFp¢ý5ûDÈÒköÌZõ;ɼã¢îWoÑ2¾.¸S±~ÖíŒ$]B®ªd3„ùNB€è:WÁ¢ž|]Îõn ‘XÛ“iñkœECÑÀWIì%}qÌh¢¿‡kœˆ«ä½ƒYpãG÷]åGÓýaô.Sí0K€ÙKóEñ…‘rÝ©6ÖÒ‘weDج¥œA­þdèÊ?]V6eƈJ.ò94Õ(¬C(¤"@ÉË®hZbo?‡ö¶ZÉrÑ3¦-ÖÖx­ã4g@$p"®w¡‘æ]¾Ã¸È[|a=ÜS²Ûqn’ïðþ1-ñè à±ÝþÈ^²E©—1ÞdÎ-î«AÃLJ’†¹]±pœŒcØyrMÇmtÍät‚©œ€¡@Ú€€€ z~æÆÿ0[³>/Ä}ÃZ¥ñ‡.kÚæ“rêæ‚ ÑpwÜÛÙx²øë숼„’ÝLyiÔÒÒŠ‚ ¨\<3Î(ÏÞÖü;‘ð¼Ë‰ÛRåb¡&ýÔ ½¼à×$”#¤Ög2Ý£¥Ìœdk0*À˜ÄС¨F²X=Áµ?—ì¾ÞÜ1ˆî¢†rÖ‡¶A¡ò5â…„ã9ü+ZÔõ®•ÎW¸9ÃŽÌáž_o$‘T–¹‡[X暇OŠÆ”¥RèÏlC5$xî’ne cðï€Íé„<&0HÖoùq·3òþ޾Oþ°X¾uÊ"Þ»¯îÑAYí쮈J/„þ.Ûwˆ»YU Aå&ñ±¼± ;£ÉïŠPç­+ù‘´m¦ÿÛa.kOÿÔµm’¸7C6]ÐïÐ9|>ÉiGÐüqauÛÂb^Q.¯ã]62‚ûÒ qRrvà©(UP”t±’î˜Nch:€içémï16å…ÿ,ˆ8³GÝi“§‡µ ×…]ÞPƒk³3Wvœ/Cä Žš²Þ¬ü&ŸI_Ÿ»NK…Êï_ª¢¦UCœçPÂsÆ0˜Æ1¨˜Æ0ê"<µö>6Ä]÷ý•óMõ×p4·¥väܦF‘†´Þ_פ¥è£jI]í¨Ï@ID|_éò±l½ LD»4‹ÙÂÐB¸Û´qVye,­mã¿}uJØØÙ¨ÕÚžjEMOÒ©Û‹!sdÛ ©æ}›i¦7=ŧF’Z(:(8ìo¶ù¹Åœ!·ÝÞ`1m»DD»Ã§6£_.±w»ƒ<ÞºÅúI×Óé~Œ>%ÝT“ýH—KûíÔc8Ÿrô£ª‡Äwzb#Ìy›HÃå-zó-bÛ~YE(ûG%ÿòæZ#®Ý6ú’>¡c/úñ.«šÆ¹+4{I³¾5Æ2Î`®lÍ’VáIëèä-Ø6’O×™–xò8Åv›dQp²„D=òY »¹ð›K“69ÃgÇEŽ·¤E­y–G5¡Œk]âÔº†§ì€^x4®žk”Ü\Í»Æažb½’öjÈ šÀI{‰oƒíÒVReLìÔáÊèq Ä~XËÙ¿0¦Vn.¸¸‡ÎÌf«,͹Ð+ÂÆ‘bÌ«Q!ÊÙÜ뇤DH"A Ÿá÷G:wͰÈìü~7¶Ü\!t€P€ã]:«®†£S-ÚÂkÖ Ü2XWíIÍ–ä¼¾ÈfÀëXMA R´¦ž:]3œ:¨³G‡Ù~dø,â¹Ï öíßmY¨Z¹H—[Åg‹¾^ç.'2‚ᩞÎÏœ|TfåÐ o”Þ÷Â>[½­÷Õ·1°mß“ÚÏ’ïmŒfDzè4Ž?V£ÐxSŠß¶´ÛN}•–;F+ˆ¬»¹ÃĤ’_Ütнü4Ó¬q¯†žÃÇÊ<½3ha0’Æ€ÓQ×ûý@ÿzŸó9!~×ÄWÓ$ý^Ȇgò4ôf®¼\,¦/«½G*œà7,àŽñ„DDej"""""5ôvß²ûŬZº;¦ª‰æn»›‰4ô÷Žþ’½ÈâíG{$¸lTLvW.4d™À¤&˜Cß Z§¢e!Dl ®š›wQ—¶” ´þb³‘EÀ5·ë/…Çð’Oô/{Ürºã’¸©$âI„~Êâr^1ÞšÞöGpôÚÜt¢,nìI¢·Ð©»<­¨þè–nçt€BÝHAðŠ©ˆˆ÷ñ›I.ÿ˜,ÕÅà­Är_ÒelL#ÿÁáÿ„•ÞÝlm¿'1pÛBöZê êÒ8ÿ„/ð]¨Ý{ç=Xw• ÞÑT{ûÅŸ7ø+ëL¶9ŽÛ7Ò;í}Îcÿå¹|뎽ss¶‘·£ïQýö¯_½¥ ãd=¡Çͤƒ’m£æwÈeSø­Þe‘o 'H c(ODTú”DÁÉ_'rV[›~Xn›:ýé‚åÌ¡§ŽÛ0[Ç«8¯¡ù£oÜ,4û»ŒßøMÉüUYíOéçFqi2­¯4…ªýÍe4•^hÇ“ #$ùc²´n &³¶)¦¨v¤?bŠZ“MÑ+”—<ɵÅÝü mc-«î%tÅ¡úšÏ¼eaÒ‰«Ç¥mƃcÜd-þ-žî9Ù îÛqn’ïðãQ Ç 7‚Å,5uû(pFAµò­ƒ—s;{žÓ]Úñlj¸2pœ„kÈ—Í$£`5QËGlª™È Ž÷ €€W¤n,w=÷FlWŠ6€¥ñ‡.ii7ÐA¡ZN÷”˜ ¬Yl}î@]ÂM55妭- $OZÂÞ2óÖ6Î\UÜYH8•´ç-ËE³™'1p‹»šˆˆJ%ÙÖe,Ù«½äZ³A >àÄL4×JõžJás›[jEƒÎ´2ê9¥!¡Íx {Ë… IIq¥zJó®idñ[ƒpÉ–Ä»U»âŒ–’æ·I¨p€tu.´M]JQäå½Öœ*¼’©ÁMºt÷©Sµ:¥;‚–”êªm©-N©ANà¨-N©AMºô÷êhBuJU:½Ê^ê”î T¡:¤*›jKSªPSž µ:¥6øûµ©-N©N~J\SªR©·_v¦:¤…"Ôê”ë©-N©áÑRZRǦ¢”èN©MºtÑáN©@ô¨BuHz’Ôê5%©×± 9ô©-N©ãÓSNÄêútÒãÖŠ¤.4€p¤ZO… yêKS¨W‡†§J|UÀÜÃRB*Î*TìM\Ì4¸õ§T€z8pW…"©Wm©¢ujà~zZS⮩¡EUÀÂjhª¸<4´¦®Ì4¸„T…`8ÑÁ:޵p?pQDS±\ J‰ÔŽ•®´¨Š‚¬šTN[x)QM Ξ’ÞTy×T|f~noŸßlÇí[¿ÓȾîÚºx¿ÙÖß¡bÌþÃg+V[†Ï P…øòâDÛ¼EgÀïfœ¦+æt+öã•þVí¯øú¤+òû˜ÿ>fëï{ÏÖ$]2 sÖýÅj5ìHæ(ð§áH륧±:¤ó›¤µ:¤óù* Sª@>Þïr¤µ:ýk|·â\sQp1ÉŠ¯e^ É¹wL`®p&ù€ #¸™DLm<5׺¸ŽÒÝ÷SEK€ ®{x]q3`í8Óþÿ©~½¸c¶m<€l{R%©A`fÔæj‰H‹éiyUP;éG‚)˜ÅŽÕ/h±À@‰ ]wJZü§æmþSzoÛì•Ë¿4á¨ñk#`!¬oê´4t¸’zI_kòÎêô!‚6Öáò¸5ƒq$ç“@]C@Sä̾ò,î—q:„CxöÏdSh†úG~f(è"(]¦gæD†ß16ð€—NÿÚÚ1]†²(4’9¬.r²„A² Z‹xÖ¨¨‚@& •c2”yké¼&ÏÅ lÎ2Û‰mÚÐØèàÀI5{ˆ'ñEI¯Bð»ýÁw5ç} od‡\ƯBå¾ø»ØÙᑈ,¤&Š´ÖÊÖ£¨=‡Æað·ƒ\åéÍñ‚}Ÿ|vÎHæŒÄu·„rMÒ'•¾lëŒ!˜ªöy]Õ_ÊLcÙùËfU„Ë•Œb=‹xâ-ÒÚ®PYS(ªß+í~`s’¬nÙÜøI²¸H˜dŒ¿ÅgCZˈ㕎`Y¬l!-h o¾ç¶.yœóœÁe#Çå%ñ¤cÃx»¤—B÷ÆàãÐç±åŽ>7ŒI.ú¬n¸áMã<«Äo–J=ºdåáìÆ*¡õû1:ÈKBvﺯpEt@ÄA""Øç ÕÓQ1ŽSp󧛼ǵ~ÜØ›zëà²K‡¹ík¸Løà†Þ Ð¸—<,s]B±ønXòëeNÜÖìÌ[ß>È@hipâ+_,“PŠ€4´žp^RûB¸ã–ã{*C#n°‘€Ä6½ic@?:a ùËó ·dúmŽ«rJÊ¢I¤N©¶LSçXêz7(yW/±N‚W6|ýÑk®%h:@mtE4:RKˆî$hn—Ì]ÿ.ñÈ £k¢Ä[‚!cˆÔkö¤}8juÑ@I.'Øþ -Ì?5즻í|ù>½§‰¦nKª&î¹›8]¢öñdnË}¬4ÂnjøŒuÄ«EDë"«RupQC´ ðŽqKŸÆsþÞãkÄ'ÎÃi⌀CôÃ!{%µÕx !Ü|BEë¶}Ê ¡ÏHbÄÉq+^ðH,¬Œ u@4£ôž ·ûCMWGbÿfß6 ÊÊû¾8Î÷¦ ‚]ŒÉ´˜¶#]\°È,ÅÊK£xHÄ·Žv‰®»AYGd"u d÷‹¿æzÝàßÁmœ¾î™† òÙØžE ØÎå¯/oÖ¿KXhçíVß“›^ß*ܶ[;e.݉ÂBÐX×HÐjçw¥¡§€qmK…CCIa?´ßXÎ*3ÅšÏ?yúk…SxÚɸ‹ˆç—<“Èçs—s6Ë$Ýã&<+$b•`M¯l%LVɳrW•÷;3oÌÌës™";*#¡Á’ kG½ÒiWiÁ¡ÇÍ ùæËÆìSœ1V@ˆŸBÒ÷’ ¤€@ñZ7Uu£mãÂoµg XæXÊþâ{£Ú4}8´\r K=lÙ¥ÀŒ#i×ñ,¯.êYšO=³ä¥#WE=MÙ‘Auä'nïÞAn»›¬MŒÙ]“tî†8è–k,kŒ3D f·0Ç &‚¤hôoï£ÍÜù¸ñû¦Òí#Æ è-Dò´5Áì q :øîໃn fÍüFñ#‰2ª6ÜdÉmË »;rZ6QÛ¶.cÌämG2÷<å(FNŒ-š¢Ð‰´rb®e³)Ë—ÜÜÉæ2웵v> !tÏg{rçH×4Nô2&BÍCÆ{žKÛVDv dlítwéËYÞÚîîÖ88E{²é+¨|V†€×QÄð¨Á¼1±®BöÙyµ¬Ÿ…±²¹5høÓý´-›J؇V.%WjH¸÷o’hW/TÞìý-ÁÀ`Ý0úÎghe1|“¾Û }ÎW<,ð$šY¥|šÜ©Ik+¡¢ …ç˜ÍÇaÍ\뙆 Ý´†’ÈãŠ6³H.#KM58ôjqâQ{Q/Ë'!ñ¹%qãûÆÖ¾­ÓØV3"OY× MÏ wº#¶…”„vù‰œ¶1€Lß ˆoW_ùyÄåpÛ*,ŵť躘˜æñ<áBXð×Põqê\ÜäÈØd÷D—XÙḵ6ñøÞÙP F¦’*:ÅVsû^4,ÕR¶)7Ì™€5ŽšO 6îàÂçóRæ¬o,ã™Ñh3Ã$Aô’btÐê ¥hí[O83X|¦2îÚåñ‰5ˆ¥d…µd`j qÓRM:bàþË;öÈǹùiûþòµlhÆ7;›¼n‹f _8”¶TA˜IMÓü=bÛÙ;%ÀàÞ$l$Ϋ7s ưMIM[7ŸN!¼Ûئ7ms(Ñ7`ųääã–@‚cd8ºÕ€ÞüÝ78«)r{6åßÔÔ|@If²Æ¸Å4`–ks rh*@fÀ2ûWšø È]Ga¹àÖ ñ¨ô‡‰#}5iax]ÇpÿÜ"p…*¦fâˆ\Y“’·c¥ËoÙ5·å#¤Ý:dᜠ°æVã‘»¤ˆÍÑ…»dš\‰V2ƒÙ”ÅÊî>aï¾bÙ·llÌ%ýƒ¥{;Û‡:F¹ êw‘²ÔxÎ/%í«CF¢C ³6–˹9íÏ•´»µÚ! cƒ‰WAsÝ#¨|V†€×QÄðªò+äÛ[2çÛ!Ú6\=…mMH »iÂFEIJˆ„‹bÖ*8ª³‡nÞ<²O[²/0‹¥”ÐÆ.ƒ_Jl Ûwkˆ¼¸’òþ&ög¹Î/‘Î.u Év–“¥•㤠€W†ï Äy¬¼ù+hYmg#†ˆšÐÖ4¶¡  D N§õ‰¡_I¡J +Òx-¼S•M´‹Sª@S«¢ µ0R‚SBªPSn=ÚR¢uJ sÒÓØR‚›j SªPS«¢¤µ:¥:êhSªPSn4¼)Õ()S§±:¤*›jKSªP?pT–ª!TÛ¯MM(Š¥:B—UJ uôTÐU m"Ôëõ¤õÔ§T€}ºwxªKSªP??’¦‡©:¤9† uJ¥@zª@?0Ô–§^Ô€z‚ÔëØÌ:l©-N©üþJTìM ˜{¿ÃKÂRùéP„+Þ‘ju)ãRZGR¸<5:Sª@8óëRZUÀüü”¨GB¹†•{S¯j¸ŠŽ ÁJŠªUÀÚxjHEB¸ž§J|UÀÀ=á¥DUX !¶¦5p8tR¡M\n´ªBu*àq£‚8+‚Š"ŠÀ4¨Hé^€p¨–ôY‡Nú‡-~lï¯ß|Ïí[¿Ö$_víÝ<_ìëoбfŸa³ÍÕ–ÅE; žhЊ/Ưæâ?ˆ÷´Í¹X9Ê@ óßi¯jòÙºšàÖ88p=-5 ±c,bg5„jèýÔ¾»ûÓa¥ÎÉP;£2@ñŽÖ*B¡Šæu"V]Crœ„\ŒÊp×@=«¨î¬>ðâwSJöþ4¯"– ‚+¡ßˆ…ÆmÉå‘I2ª·ìÙ9;6.Ö§!¸Š.C³n¡{6ŽJEH"tôï×ýÕ£".–Hõ4ëP=‡á}*íY+ŸÝèêtp¡èãÕÒ»ÊÖ™›R5{_ Ã9go$±¤XJLöq-Ù–& #£ó¤ìL@Ý¢(”ÞQéËZ®FLtÒ6ç 7nÚM#¡Ôé¥WJÊÛÃsLw -ŒW¦€Ôq¨·BÜ®kË5«3p–½’íV(*ÝTõåÝ:'ÿ(w‡–·,LϹ°c¥¾+‡ao¢e mµóÚÏönñ‡€ÿßTeSmd V:©ANzšꔪm×§»Z\ª@S«Ê´Õ:¥:ú*KS)TÛPZUÄÀr‰L€†ƒPYQCШ8Ž ®/iµ~aU0ÜPyuAÖ°×xˆç:›Ò²vùÅâž…°Èpcn™c‰5ïj=êÆÿqÉÐOÜþôe*ªæp–ÓXÀ@Êœ£§~²v˜¸­øÓŠèÜ_¾nKÙhŒ­‹{³>1ÉV ~F–•”<^?{xÛ­oyÔÈV{ÔÔaj/"Iç„;6Ê*›s¤™Œô¢!òùÛ[‚oæZÇ9…ã°M‚0ë‘ ¦‘o3H3÷`‚@¡wI¤¯£¶¦o$.ñR]Û7*é^D&V H3FA—k5Ÿ³Ð ê^Û–¢®™B(bƒQ¯¦¬q/’M%xeÞA¬’…v,¨„z€²žýNþ¦åk5iŠd[ºV.ã éF‘з‰ˆ²‰èb†ø èÏwŽå´ë\V÷„Ô.2À;€±û=ÉäÒ°ÇúÒ§JÉz7¦œW5‡·[Æ¢bœÁ ˆÖNÛÈJq]ï_3«Ôí¤Q~/ü¡6õq·ÖÍÞõÕS¯œè»µ¿ÊGI° ~PÐÉ]‹›a‹¹9›¾wÎ&m­¶våõ´÷mÝãô±Üʘ¢da¬säuK†HpÛ0{iíLŒYüînÒx­Ý®6 ÔáÅ®á$Ž~“ã1µÔ©ÌŽ3øoŧY&«¶Öd$Te‹bñ;7ÊZ°¤^' ñóeff%Þ½Gß GLÂ& ˆû_(ö<»'nɸ-vAï3N[Å¢G†‚ÐzÃÖ2¿Ö-$p+Ëyº£Ý9™r0‚Û6°G<¡¤Hê.sœêuCкÆRÜm,Ô…P ƒ§.µí· ¸`í/,†íð¾ ð\8,ÀÛ€±û-{ÚòiX¿îgÖ•:Wûͧ«ŠçöõºÞºŸNQQÖ²V¶ ·+£qvé…ÌJ§Uw WV©ANòR¢uJ mêT Õ()RZR‚›u¨-N©J¦Ý*KSªPS¯¢¦…:¥*›z†•uJ uT–§T ¦ÝjKSªR©ÕPZª©AN¾ŠT(ªB©·¨iP'T §=NžÄê”ÛÝîÔ–§T€~®Š‚ÕUJ Á©¥T ¦Ý)xUU()J€ô"©û{½Ê’ÕUHç©-ERüÃÔ5%ªª”çòTТ©NaÖ—´ÒéiìN½‰@üÃRZ{UÀüõ%©Õ ˜zªKSª@??’•èM!OÌ4¼)Õ •èE{ù†‘ ×µ zjKS±\$ê=5%¡:«Ã¢•M yéxQ^Õp=¯B~p7w†¦‰Ôõ«‡ŸÇH„pêWóÔéOЏ0Ò¢*®-Nš¸:)P„Õ€iU:•èÏ ÉoC”t0¯Íõûï™ý«wúÄ‹îí¡û§‹ýmú,Úì6y+U[†Ï%_‹Ž' »Ä§¥æÎ9d•%¨ª@8ôÔéNªàpèé¤ZRƦ‰Ô,ºÀ²ní“°s’®î¹†êFYé²Px9 7mÓ‘¼£9)D·vÑ&{ÅÉu= ¢D5Ò÷;,ïíÍ•ûÚÌcf¸ÿã2&6ÿhx²½Òqš;£Q![Ö"9mìc’÷Ť´ÿd¸ŸÂ;Òõbâ¾,¢ZSØ®Š!bÏ02“nc·`÷ã çOdä]H¹xåc‚Š*(î Óå•,ðÙÙ3po9|Y¥¿ûόǚ½º"kXƱ­hZÝU¡è[ìw°Eg&66-ˆGÀôõ¹Î$’I4&€à±êÊOcI+fÁô)ËÊžJBkµŠX±æ`Ì¢éI4gÔC&]æL"";Îç¾›rn(ò¹ímŠ2ØéÝ3V³À¸¹ÏwŠ ñkAÂu1ï8ëSmdiª¤“ýcBßM+Ú±[+ÚºÅUäD¢AA“täRNc³ª›ÄXÇ•”I”jMÑÞÞß2¯x“—~Âgv´÷ÝÙŠéÒ-% 7‡M$þ%‡¼°»kìãÓÇ£²µXH³"Oª¢· ÈѲ+˪V+Ò©DD=ñ‰p£aŠ;½ü3Õ±ZÈ!¦¯u‰‰%•¥¢wzš½»v´”ÈÊ”aíkqÂÅ“¶žÄ¤Ôc6…AÊŽ»PÊw5Ð4Þ×½ÉZ”ù˜ÍÀö[#ƒZ$ÔÒãSð,£E§Ü¦kÞtpâ8žž¥Æ®; 2¶mEfßM̵E»øÒ¼·n¨¶äUÂnÜ<1 Ýx¥ÌàSéÈ`(ià¬Ø›q\Êö°C¨#[xPtb½œ+ÿ¦·ûnH\Y¸b ÙÂÛ±³íˆ`Ý%ÎÌW v…)ŠþN4‚`å×R‰uõsœniÃSîŸÓý ªeÍ›>Í»^>’» ƒf~›Þ"Ù´4pDníf—fRM3iƒ„‚8tÔG”G¾нÆI+÷‹«‡šIOÔ?Ì»L¿ Å ÞÊT­W:Ü-´½¸ª×1m§O"Z,»¸›RÊ¡'èm½<ȶ(ɦAtQT8{”+·q6RÙß’{~Ûº*hhMkÙõ®Åíëû÷ËÓV´ô V”!b¬­ÓsK¨ç³ÌkªíMÙ€öZÖháqђﺆÝ'€qúÇêXæß]HÆ»¾&¿WÔ¶ÛžàNï4¡4ÂnNÉùݱtäȱ"ï cvÀ€:Q@ß05åÛ]KhÙ÷'21¡Ìs™ÑNƒÃ¢Ÿ÷.Ôã/‰.i wOhãÓÚ»/¸{öpÌž÷¢ä´ASDª·UC¹HÔGû$Êp&¥8sVW÷eþ½ø¨íô,&ᎌ†N±©§ê5 °ANºÎÐ-f©M¾>í)§T ~%AjuìJ s IjuH TЧTÀ§]*êÛ§¹Hµ:¥÷AjuJU9†¤µ:¥*hSªÙeâ“•(úò t/,Ûr(WnÚäÀVáÌ‘È%ä »ka4Ž…3Ìev¢·Sú¹ËW R•Mµªª”ê©¡N©AN¿%*'T ¦ßN”ꔩ-N©J¦Ýj SªR©·Or¤‚SŸÖ¨R•M¾:E©Õ()ÕPZª©ANº‚ÔꔪmñÔЧTÀ§WE*ÁJU:Ý©-N©J¦Ý*KSªPS¸*4§UµËF!*€¤§. <¾}Úê\Ú¶áš\»\:T.¾=‚ A5L ˆ÷€G½­`Ý…p4i:VU¹0EHâ¹½k¶ˆþÓ@2Ÿí‡”u®ý¦5–ü¬º—7¯›‡Rç%S@Ъ²«¥T §UN’R‚äTN©A]¾:šê˜ç©-N©J¦Ýj UU)TÛ§¹S¤§T §^ÐþŠI‚”ªmñ÷êhªPSª‘juJ uÔ§T¥SnžçôT§T §pRLÄ¥Sn¾í*ê”ê©-N©ANº‚ÔêªmÓÜ©-UT §?“ú)qLÄ ¦ÝzjhT §U"ÕUJ mÖ µ:¤6éRZR‚u4!:¤*›téîÒ—…:¥)R½ Õ(˜jKQT€~z’ÕUH s»Z‚Ôêçä¥Å:¥6ëK‡Z*´§R·ü5%©×êH N”êÌ:ô÷kRZRùù)P¦·^ï%.iÕ •;^Ä€naîè©!:ö«úêKS¯b¸<¥I Õ zjt¦®Žš8„ê4¸"½©ôS±?¸¦‰×µ\=5$#À® -)Ô«€ó I©ÕzcÂ:[Ði9J>2kóW}þüfjÝþ±"ûÃgþébÿg[~…‹7ûÖ­Çé[GŒhãô¡~'8¢6œLñQöuËɲÿ¸¿p¹LßùU¶áüwêp¯Ë~`þþç?kÞ~±"èÐ0†·ò£R4¨B¸„øõ$s .íWóù)iM\ Ò¤„ê»âؾ$¬·ökæïå±R)á»n–nÖUË9-Y®DÀP6ìТUDÁ¾dÌÐy5›üU¶V) {é èK€:A”8}!•Óô¯B³•ñXC§ Æßõ?γ/[ ú䞺̻‚,Æß¥p+µœ3)E”„nvM¤ÛÆÌ‚ÅÜpÕœ„`.;¥WU›PPÇï‰Aþµ™Û¯{îd‰ä9Ѱ´‘Ð\ uôW‡Ô°»™´²ü@t•´ Óñ.. mÒ¶ÒÕ¥U()SNÄêªmÒ—…4 §pR êL…SoPÔ–§^Ô §UIjuJU6ëPZWzYü5ñ[äºìœ•®›id޳YÈ+䑌M08œb¶Ž:RÂQLCF¨ïh]5Ò²ÜÆØ8+ó‹Ìæ±vÙhèå¹…a4ûm/?×ÓÃBÙñû3wemþ7=‘d9®èÚ;£úµ]E%' ò&f=ôL¬s…ZHFI´pÂA‹´L$Y³Æn“IÃg 41R˜£È![e½Åµä º´‘’ÚÈÐæ½Žcšz×4Aê Э~hf¶™Ö÷ tw 4s\ \Ò:A„ÖªùM½C\¥«Ž©AJ’ÔÁJU9† µ:¥:©P§T §@ÔÐ'T ¦ß"Ôꔨ-UUÝ–gù÷!Áý¦±°ÎN»-ÑŠ36MÃ#ðSíRG¾nÀíä•HɈˆS b€é™Ž`lLï÷no1µÈuÇ-ÄL{kJkiuX x©l¸ÝŸºòö¿}Åão§³ê|pÈæÝ$6ާXmHúÂêéX¹{~Mì,ô\”Ìkƒµ’‰—dæ6J=Òc¢Ÿ0z’.š¸LGßBÁá Ùín­oí™yc,sÙÈÐæ=Žcšz \ÒZàzˆ$,ŽŤñܰÑÌsK\Ò:œ×Aú øÁN¾Šç \UJ mñÔ–§T §UAjuJ uÔ–§T¥SmM uLU;‚• R•Mºûµ%©Õ)TÛ¥AjuJ ]Iju]fáü¿‘#šÇø«$_PÍ_+æZϱ®{š1¼š-Ú»Z9wð±oZ¤ý¯QTȘà¡SX†ÐåÖòû¿iíû–Ù粘ë+Ç0<2{˜aya.hxli-.k€p%®¨+7ŽÛ›‹1¹ÄØ^Ý[5å¥ðÁ,­Òæ5À84‘ZЃÐBäR|;ñ #55‚3444Cr’ÒÒ˜Â÷aÝGoäd_»ƒE«&,š¤uYS4Ó(˜Â5жæÀ¾¹ŽÎÏ9‡šògµ‘ÆËËg=ïy kÖÈKœçÐ $€Wn}»í`}ÍÎ+%´l.{Ým3ZÖ´UÎs‹kZ$’¤®Ÿ:ú+n-Zà)J¦Ú‚ÕUJ utTéìLÉUµî¦ÖÛ+É͵>…¡%$´<}Ö¼4Š6ÛùvégL§Nرn¤I#èS*R”DJXæe1rd_‡Žæe£ŒHøŒ362@tUÖI8€ÒH¡]ÇX_²É¹'Á3qÏyce,pÏK%4— - u-Û§Mw¨ ê×µ0)Ü%©Õ()·Z‚ÔꔪmÓÜ©-*ª”ëÚ(¯bb©·Çߥ@SªPSª¤µUR‚u©Õ)TÛ§Oz¤´§UºEGÊMÈ3ˆ…/- ¹0ŒŠhâBAó•9nÍ“TÕråsøB˜Ãà ë]\ÛY[¾îöHáµµsÞàÖ4’ç8€í$Ío÷S6ÞÕ’áækAsœOPh“ô»>êÁY²Å‡ûCxâ|‡mAµ˜š´g#㚊›€™æûª8çÏu:t´:®œKAë ;Ú{£m÷Ì–>ò N·¾µ£ÿ-£~€ê~%ÕeSn•´­~©ANº‚Ôꔪmê’ÒR‚]•U)Të÷jhT ¦Ý)ªªPS® µ:¤*›z†§JuíJ wJu[¤T|œä‹xXçÓòncÑÃù)®T*MÙ±bÑ5];táSHše1Îa®½ÕÍ­•»ï/dd6‘4¹ï{ƒÆRç9Ä5­‰$€Jæ·‚{©ÙmjÇÉs#ƒZÖç9Ç€ h©$žR¾‰h©{zMì$üT”Ìjæk#0ÅÔd›$Ó}»ÖRAÓUɨjES½ê‹K«L…³/l%Ž{9©’F潎ok\ÒZáô‚B»›{›9Ýkyâ¹a£˜ö–=§±Íp Š¯¹Ý¹rÇBCܲüÛrâ;äíûäKö°“ªE¸3I4áåVnFgŽtQIpACŠ*”ú%uâÈãn/fÆÛÜ@ü¸i–&È×IxÔÃ$`—3[|fêPâ*$–7ÐZÅ}42²ÊbáŽc„rš;CÈÒí'ƒ´“CÀñ[@)·Jí–®µR‚ÁJ…0{M½CK‡ZuJ祧±:¤íî÷j Sª@?pT–§T }ºÔ–§U¿ÅÛ×Ó ™Hx ¹XËq²O. È§ÏØA4\çMS/ «x¶Ë(™ŠE2e0”@Dº79,}”ðÚÞ\AÍË‹bcÞÖ>WRØÚâ È  ·oc}u ·°Ë%¼ ‘ÍcœØÚz È0P´‚uÜ ]T€p¤Zª¿Z@8óÔ¢£À‹UU yõ¨-EUÀáÑKŠi@ý~Z\ð¤…Sª¸˜jHE{Rùêtªª¸˜jHíERÇÃËS§±5p8søèâRÆ—pW…*'Ç©\ ÍH„ëÚ½Já-ë}°éßI!ñ¦Aäñ׿ŽüýøÌþÖ»ýbE÷–ÏýÒÅþζý sv=ÚÖ©ÿn…±)Ø÷kGýº¿ ó—Ão&A¸k÷”£þUmŸø{úœ+òߘ5ø÷9û^óõ‰Dƒ¢½…jWxjH Õ\ÏKJÀÜÃRBu*àq¥Døx„ø¬ýáfÖ°²L;«{#½fÙx™f,.ÎÈPP¥e1©*Ø®ÖE·¤‹cœ ¢NÓ7¾˜µáüÁÍn-»vëœn– *ÙÚ5jh5{ÚŽ%ºÀà[N{Ô³Çå,!mì¢'†Q„Ò„´é-5 vÇ¡f]ÊâÚ‹;´Å™êˆç|G tìˆ)»bš´D…&ºróù~,dïešNíŽ"MÀPº¼ZâOk‰4Y›è ¶yŽ*<4‘¨Vœ:8Àº=ò-U6ôö†9Îc&át\{³X"tÛ  S€ººÖóo$ÌŒ‰t:ƒ¨Ö+ÒOWÒ°R†Ö­è[S(øÅc§"&£[º„¸Ìñ)ÖÆ(œ’MÙòÙN]ôÑ @£¼÷À 4ï"/s$µqmËÓJñ ð÷öp+‰²¸¾ÁXÃ/·¼œ^J䘈zví£!Ú,“uaH¡Ô¥ èê&w*¶ä1S\Û†ÿ-g¡Ý»Šä‹(àcdŒMzOgi§«é\BÂÑÕsÜü:ðùkaù †ç†œuq’êdÍ87Ί܆g¨Û–ªº§dºª»L¦*Å0ˆ<5ªîLÕæWL tN:À¯:EOObîE¬žéÇU>•”ïÛBL£gì“{ènÌ".›”ÄIôzåY£Ä¨Š6] ÝÐu.µ©1·1=¤º­ =GªŸŽ«•²ž£Ä-åÀ¢šn7Žeç÷¤Pºo Îrˆ‰Í®¿äë]i-ËYZŽŠPt ó®Q3öŠÐË‘EWQ¾è”Ü@ê€ t€Â:{ã”F˜Œµl½5¯ƒÂ¨=äTNÅMÅ`0‰È¡•ô(¨•0H»„1D…0‰‡Qðìä«€é#Å"”êÝ)§T ë ‚Ôê®ÛÝîT–§T §=M uJU6õRð§UœÏœUgåž#áÓÈlI/aã«^éË7\"‰tg#¬v$vÖ)Ëeqã'.Z‹†æ‘Ër#éÄCÆ9õº2Û[—³;!‹9¹†Æ ¡÷.-sÁZá~‡ 8µÀÔ霦ÁcóÛÂ1–h“g·R³¤=°¶¡¤u´¼·Sx‡6­"„® •øÄâ,߯¯—Ù*ñ¶ {[^سîy»rÛ²#˜¥Šˆ¶#"1lÁ(ÆÉ&Nܤ œ¢§2‚&¬Þ×å&ÄÚØ6a!ÇZ\šiáŽY®^~Ü“=íqqy$é'KAÒÐX¼÷0·f{*윷·xß›Ž_p´}–FÖ††Š ©ÄUÄž+(3$œNðAmñ+y&ƒœß‡rÂXZø¼Á² ¤r‘)„ͯ)q(܈¥!7åê “WtV2ETê‰Ê!æ»FѼ¶çEÇ.±ÍÙy|YÈ[[Ô–ZܲC̈Kc”5Ò×Hq`m(Ví¸®½¹gòÈ€íÍŽ¿sM@q ˜¤¥žÂàÀzHÔOH_~Vàç…®®è[S3q?v%!u[öôÜTU•‹BfJÙe8ܦ4ýò²³ Å¤Y•R¢ÍºYûa)ä)¸6·79›¿±Se6~Úµ0ZÏ,o}ÅïvÉÿelZœý:K¤“DMqÑWHäÏrïcm„v7p%ž(ÞÖÃm­Ñµãý¤Ä¿HmjªBѪ‚ ·W€‹õ§ {y[Œ­[VÊ[-Îfw/öEžA’oÍ’NUU@2jvhÙL^ß±)œÄÎz`ååí¾ö†Îáù;«Ác<ß» \[÷]D8]æŸödÈaʬ¬{Æm¯-Ä-±‚ØÝ>ðƒÝ 05wúA' éÑ«íÔjÒ Öû ÂÇÙ±­Ùnð½o Ó-Zì…ÊÆÊÈ8ä–ƒLŸ™Uš I¤Ì‚í%†ª·`ùHX ÂU“é^s?~lÙmrËÂZYí[»†Bë‹[¾ýÖoÒ?½1Ñ´9„ø¯’7im âKîÕ¶ÅÚ{–;‹M‘”¸¹ÏÛÂé öýйk_Ü8=Ä:œZÇG£€pÙ1_ ¸Âãá¥&2–p[Û-rÃüy) …ž­É1,›[sã†m,ä[I¶4¥Õ*ñBp Ú6d“‡j, ‡f~îçæ~åÇóܸÛ8Q‘É;Û¦HgÆÂé{·:à–1 MÔ÷Èèâk*ýC«ƒØ˜KÍ–7¦s&l¬›~ëw0Bd{€X€áªW ;KZÀùïIã÷‡kÈŘ×=áŒ7bl3;i˜.Ëu bîµ.û|uâeÙ³bñ)ÍÖYP0„OAÞæÈì^`fó[Ÿ#±w…„6;« sþbS4Á-(øÜæµÍ,%­s\*I¨¥×´1˜Ì–êÛ—rÝà/$|_ŒG,RÇÒÇ€ç4‡\<ë¨+Ч]zÉjóê­îÞuÚvÄóe^Á¡-´Ë$dÖy“ÄO"Õ”éЏfS¢(€Žº‡~ºwñÝÉc4vN ½tO¸ô5å¤1ÄPÔPžv-.¢}ÓKíD/¤°¨Ž$Tt¯o¸Žµ8¶Î× ån òãË󷇶‚ôpÎUoe<Æì"¡#›))`nØrÎi6Êt©.ôtÓ1S*eI?Œ9y”åNÈÃ|/ÍìS,wæ›ï3ä,ÃnÜùDŒºîæk£, T–ÇPçââç}5¼¬9º2_ßܺÈ:ëkãî"³º›vµ¸Èxp&”sè@ 0+‰kû0gÃãÜŸˆå­®!m¸¶XÞfb]›È»»+/+*Í•âZìTaRzŠÊ*šNˆ£„ß ¡9LRB½Ë—8-¥²±|þÚËEs°.%uÜqÆæ¾ Æ9×’5ï«H .a 1è ’Jò­é•Ü;Ÿ#ŽÄg1òC»¡`·{Þ eº.pl%ì-m5À¸?UA‹³¤øPáŽË¾Ú`ŒƒÅÌfnYÄ|,ÄŒ7ø×Ú7„¢hú=¯1p¸žc.÷°tá4W|š)7ncÿnŠj”šÕ·4¹“˜Á¿|`vÌ2l°×É%»Ñ}=» ¬ÑÄ"tm«Asc.sžˆ^ÒsSì-“Ê·jåó’3sÖ=Ì·×iÎ¥"|…í{¨Hx­¯¦Ž¯`ø8ŸBW‹býž=µtð¿b¿¼gl.Ã7)œÇwN\Ç.Ê&n-D·\Q2‚‚å&¨~÷›¶/µÚÙ<xÆn[æÀçètàú´‡>7‡1íÔ¦š8Ž+mË›¦OŸ±ÊÊ`¾ÁÚºRÝM–œ[BKHcÛG5Ô®— ¯°F i˜¬Î n·+˜0ž.y‘2B1'éÜ 6Qr[…”zÔc’?cþêR¬!¯ù5°o}ñ6ÑÌ`qqÛ6værm´./-1Žkµž?d–øV#kmX÷7-~ùÌGbn ﯊MFžŽšÈ{{„\…°¦vÍ\D«mœ«w({n>Ëyp]®& §RˆbÊ×i»Ó=ŠI¨,æIû„’M™½!Îè¦&æÆô»Þ9‘³vø¿Ébä€wϸlPåˆÈçLç†éyv–CLƒ¼y-vû>^í‹}µŒÝ;—0lì¯Ù/æÛ ’Rö<1¢ Òu0 ºG¸Ï´%àŽ'Ãf$³±¥–¸‰Ë%•“Ö˜qЬkÍFæ¾®;V)âmò—<œ¤LU»àU!ÐI]ãºI@:gÔ @ÊÞóuå÷%ÖÕåö*ÚòïØÅíÍÍÁ†Ú)žÒï»Ç¡’>WŠç6Ž®Xë]—·ñØ[}Á¼/æ¶·¾/6°A’y"i§|ýNc#i¨-‹¨=!n¡ÁQ.¼•aÁbLµmÞX²ý²&²Y²t“% ÏaÙÖš¨%y+~Û>–íäL¥¼«¶é1P©»UÊZ"‰Å>©ç!ÅíËëí׊¸³Üö7±ÙýÍŽ}æâpM¸µ›KZöJçBXÖ;ƒˆhw8å ¿ÍZZíü„8+»WÜýåÍ,0Cc(y4 , ¸—4}­Mn¹6mŽ;7·®s„ɽѱҴBøåcƒÙF¢Ð+S¨PÑGÉ?ü%AÞq¸š‰k®bþ~þ*ÕÓbc¸ù¼Y;4 HÝ™%¹BNu“'.Šš®›>ºˆ$%9K®·~óZ÷&ê°Û–°àcò6 ›·Gzø£©.Ð!ÑœHcÍGki9“´y}k’fß¼ÍÏ&Yïk °[µö­{éA«½Ôö´ ›Àÿ£BÑ85}ugŒÙ‚o;ê2Ì’ÃÖ%Ýw¸º Ðîm÷¿g¤-¦ì\?QuZ9‹€¹ñWŠ*Ýÿ¹k¹¹9Ã/cawÆÆKË|½ôui•½ë&. 8>V¾YP×8ý [ Ëio÷^Ojä®Ùm>6ÒYŒ´¬nîÝiq$ÆæÈ]BZÙ%}Iðá…o¬”æpng¹okÏ Z®/‹¢6ä°¾ÊÀ]V¤P˜'æm–w&ÍÔˆ+7É‚ÊJA!DÂbñžbo<&g½°öÖXlÍж…ðÝwòÁ;ÿÙGp45Ž/>)1 Ôê4¡±²öÆWsµ²SÜäñ–æy[$ÔrÄÏö„ë.£5‚µ¥€q¤(µrçy"ã±còS©„1­¥fZhÜ×Läd „™ÊÝRC!'Â.«‰&cv®ˆ`Q3h ÞËoÍɺ®¶žÀÇ[ß\c[¼žâs ¾P\È¡sä-¸FZá^ަ?há-0û‡x^Ík ëž-¢†!,¯lfŽ•ÚœÆµÄ:\ A¢Þr ¬`pÜç_ëå¥8u±¶¥²µ¤“sAËÛ‘Œ}!’ܵ9†xÞž è›3¶PJ¢©€(==³ÍY¯çÜqîËâ›·#ÓRa9=äs=Ô-kC‡æ‡u§Œí«Zïv3¼¾ŠÎ,+öíáÈÓålUˆÄ‡ÆÖÔ8öž=x0´Ð¹¼W+ÿ« /‚a'üJM/ ¨ZÎ&Zc£+‰™_\}–Vei¤f”I“zä{"6€¨bH¿â72eÂé܇á.뾺î—榮øF#1‚cüà‹Q}›7/Ä]çt^-ëhÙ맺// ˆd mx:ä "ãÆ7µÏîæ…eqÚRîá¥EAU¹—lxéšÆ"b»ÍÌESt½¢*ÚºW¯à3˜íË…¶Ïbœ_Ž»‰²0‘CCÒ8ÑÍ5k…Mê^m—Å^àò“â2 Ó{o!cÀâ*:Áëk…ÓN ‚¸™TÛ¯k-¤,}V{ð)w[2Ù†·•»²Åç×·0õýu,›(h[ñ3øñ–]' ¡ßÌ“ÑÁ ˜¢‰ŠMå T•ðŽxâr7ö˜‹Ãgq‘Ú¶y6BÖ]$‘ø®Ð263¯S¡Ô ¨Ð\ßYåNBÊÒç%l.a²Ü6F;;‰Hk!>3uCÿKˆê T×vÌ+~>¸l¸~_0/cµ™IÝòô[(X÷eºùƒ´žº—ô) ­H¶Å"¿¦8j‘ŠSTNrŸU½“üÆÇŒ{ NákÙÜHÛqes­sK[¦@xiîÚ÷_h#aµg76MáËe"¼Èá‹]ß1Ó¨%Í!Åú])hã«[šÅ$Wĸb'-þ¥d«Šámˆp¦?p”Å6£'—CƸ$VNÛ²í–;'óNJ€(c¦T‹º¢€"rþ£º÷•ÞÓþíÛxûwe÷ûK"Œ9°µÝÓšâgB(ÇP\jÖžÃ@ÛÛbßpýû7{3qÛḃHúK{Çî›â™x6¤Š 8ô€yeÀqµÏŒï£ÃÞHŸ½ZãQdã YW¥®µvÄÀH,£v÷LZ‘ò2QÓ1I¬‘ÅÁ ¸vÉNqïqXýý¸ñ›’Ïls”™-BÖâÞc4•€ ÃØÇÆòÐMCÜCZ:HÈ^m %þç=³¯fºŽÇI¸‚x„r²7¬Òç5ì¨:€¡h“Ð=_…Ì-ecÜ]’2Î{ql²ÉØý¥ÑjÅZ¥î‡NÛ‘ÁÙ¢F*?I­¼Äª¦S?p™{UOÙ”€%¬|ÏÞy­Á“Û›SÛ™±—î†IßpØá´Ð8ê .•Ô$DÂt´j$‚²¯Ø[c‡°Íî» ŠúÌJÈ™ |¥äVƒIp¶ wޤÐEÓÏ›^V¡4òú·ò•™hÞVÙ£SŒs6ÚìA»2MãÔP~‹òöb˜«¼P‚`.ðVå±÷ÈÜø{ûܼ,±Èbï'·ºYxŒÁÄ»QkIioé¥C€­³ºö™Àäí-qÒ:îÎþÚ­äÒ^%à§QÁÜ)^°M*»b_„èç[«Edfd·±u”ÖñÌ*b!Da¬´o)4“F,ݪ¬ÚÌÑ~‚h"URUuûB›³Ž%Õ-9¹#ö5®íºÇ<ä2—®·°³Ž@d¸%å‘—9Í0â×8µÍkt‘«SAØ.9pÆî˹ozß¹ØZ‰¯.^ x i:ËCšÚ‚çjN“AgÃæÊׂ|<勞ë¾ìˆ×BöUóe¥m«xÀÄn »Û9û)7Àg­ˆ¡L“ ƒ…·€=茒ówí‹Ë7smk‚½°‹‹kƒ0·–J÷m¸k˜ßЇHá´ë¨ #Ù»o=mr6vB{Œµ¬.”Ã<#4lûn…Ís¼aÒá¨×«‰_e‹Ã>0w„ì\픳_éí±rÎܯâR¶ÎN.æEÔ{–ËV ®âEg`Ðë9UDJ“4ÀÛûÁ\YÎeîx·¥öÆÛ_ï ´ÈÇ™„Q#÷:g8ÀÝA¬hqt‡¢”+“±°2m{MÙžÊ}ÎÂydc˜"2<–8µ¢ ÒK‰¡.% 0tÖ«'IÖreµ¾ùyHòÒ(BI9@Z¹ˆIâÉÆ¾rÔÅ)›.í‘H¡Ó!Œ! i^½bë¹la’ýŠýÑ0ÈÆA’‚ö‡u†º °*¼Þí¶ÑÝÊË7¹ö‘ÁŽ"…̆¸Ž¢[BGQà¶â©¶»«‚«1øJl¢9Sˆ™D’3,d:qmzBbtdÛØŽ-‹¨¦>ñb »•×8€Q1>È`ñîlHü·÷_/m‰ï³w­PжÊÚ“\º½D†µ££U\Úž úW.ØÜqÈo9À1b­IŠ£ºž±@>šç4é[¯¨—"Ú8o‰¦"Šd›e;;#=ÍæùFÁH°Ï¼)4ìrC´MväL(·›MâëÕå{ÎÝËf9i9!¸Û“qiZñ²º=ãZÞÞæG¼ôj}A\ûùƒ5Æo¨…]}†ç躷]ÙÞ°4témOH]“0ÎÙ’á‹7”«È;iÕßšÓ“’aY·H/é6!"Ìá©]‘˦‘ÀNR(&åÓA×,æÉÛs3}O‡‰“ä›gŽÐÇ?»i?uejú;MWH…j³—1XO±6”Y9‹®oµ9¬ÖGûéâÔV® Ã1ÌwávëÛÓÀuà B(-cd¸<9¦Ži.uÚ<†ñ.ªêȰVN”°pÆožŸÉíXH9€gvØå¶­\„ê)¢¯GÛrE—vö%Â[(¢^š˜Ê^þèåÚo÷þùÛ6±ç·ž }°ùÙ]Ï}=£^àÖ¾fwml€8€îìð'¶8 M›´³×ÄmŒ¬ÓgšÇÄÐwQ\âØ¬¹†€‘¬q§eHÛq_ –Ù‡¦³GÊdÆÖ®Pua\LßÛÎez3(‰S’£W!!s;–+b³wRI59„1³ºy‘—Åov~ÝÅœåÖ-·P¹²†6®–F~qÎ Yy“U\âÖW.¾ßØøÜ†Ú—ræòp¶·¿6ò5Ñ—:ñ:)sô†R€<š4…¼[|9bKžÇÉU,ØîX¹ ­¬Ê^^ÐtêJ~xÈÇ©¸cƒ†¯”¸^:ìh)¦EU! ažK˜»³œÆíga[q¹/±îÑÇpÖ²)ÞÒ!h‰­f§IRx†µ¥Ä.Í–ÉÛ—ø«íÀÜ£¡ÁÚ^ˆš÷ÂK¤ak\ Xwxâí-eá©ÎÃòn±£±D>nÄW¬åÛc¹¼W°'˜Ý0-àn+zåN3ã†à©>zÉã'qâSï³ L'0'™Û;×9qº¦Ù;ºÊ LÛlÅÔN‚S,RÂ_Ýš5®kšúŠš;€bó»[Þ‹um»©nq.¹6ò6XÄrG(n±].s\ÒÞ<:*:jiÉßáþ,3D@äŒí;!xHÅÇȈ0µ#n«JÒ^A P#ßOšt§]™NTY¤]À6šã ÞÆÏ ¯öÞ ðñÊæG÷Ùßó†kl]Õ"èox領]ù¶ÎÈÄ­3™iŸ“|msþë e†áö]'yùÂÞ“ }ªîž°%±ŽxÎaŒr«+ ÌIÊYml£)n_ÑòÖ<ìŠ%›É,ªP¦‰9œLGEÍ»2ÁºµiœÀß¹=ÇÉ™7>Þ‰ö¢IË“ßMjøîba–d×%PX{§ê ±m7gØa9žÌjF\1Ï€wAñÜ5ðHà^Hf–UÝüãt‚x9ut>>} ÅKìa•®¤,»*Ù‚‘’cñÄI^àöBDŽ fc“–PØC?IR íBŽöéuÒ¶{ÍÁsæÕƒsâ­]𽹕Œw{Þ›m,e%æ1WÈÒ ‡‹CÂ¥köØX%¶Üà27 ÅÚÁœÞï»ês«Û¯ƒXàtŸ½4 ©³!mãñ]ÅoÎ9¹í|«b²ºbd–+ÛLqo=mœ»œÁ,²:€!¾et†œ»fÎÝÒî;Œ®;!mr˜«çA#õ+Õ!´€âPoO®îm´Ì8ûÛ)]qÈZ6V8·I­$Š€š˜Éh'¬ž…Û’œ$¹m•c1[KѲàñ‹ ‘™.9˜ÿF†Æ-Å$fÙ¨VîÖVWâÆ‹ dͼoé$׳)T9u+^mG&Õ—uKdçE>Möxøc~©/N­¸U 3[ƒ6š‰h;Ç.ÍÃÞŽé¢H¬s{#ÛFZ:žÓBKô‚Ò8·V¡ö@$R/✅Á ‚rµÇsd+väÛ[^ï³ n7¾™EªI…¤õ¼“Å[¾"Z¨‹GIöÊ€€éJ¢„»­ý»¶Ä–÷›ïmm·®&lnžÞã¾6®wí,h-¯HÃ¥½ ìmé G¥"ªBG-›Ë‘E é9; y5QòždZg`æp>xuw‘‘S,tñšA#ÓÒà <`¦ìKŒ}Äc2d†T»û$õø*(OUGUVkHÆÈÛî“¶%ç+$@nv©¼rF6Фw"ä­âç á14A@[]wÒ †•æy»+æ ÎåÑV ð¨i„xÍ¡áÄ}kn½ÅÏm!Š'°tPôƒÐGQ¯Ð¶ÇÆU±»ŒLŠæHçHH¢ªÞNØ€:öb òVjôt/•þ©­ÄJÃô­˜ÆjìälOHjSHs&ºº@JÂsv…Ð4]à×@Ò÷isº¼+¦8tš…Ä%!¤Ñjç}Gj šŠŠIûS.rh`íìN˜ÉŽ‚!¯'‚³6—VÒHÑP$ T‚8£é¯RêÈÉ#ããið™sì9-!+f ¤³BF¹m3(Ù…ÒlœsS¦1äjˆ¥ì„‚n]Ð.ÊÔw,‹&ã ]£iÄ’H$ŸÁô®í±kâñxËÔ)OÆx.ÞMÙLCé¡Ä¿Û)¸c§ìÓÜÔ *x’µÇBC…xu ý&¾Ùèéÿx(I^ÇtÀ "øE1 ö€A|Dˆ`Ôû¾ÀÔhužº‚5Úð¯i?ç)‰h>Áü?÷-í“—àS¡¡Ûn½²¤M$„å8 j¨ªÇM4ÌTÇP.£ËÊ5Òš{~JÑ-iARiÖ'_à]¸m¯&«âˆèë&£ë4[ÜkB¬à)0YP"mdÑzä `)^>7f͸€j"'8ìïWNæg2>ùwQ‘þÒâ¬oþ«\~ ²Ö±Èá“5Òö £à/û#ð•Ü6ý¨ñ€œ‰Ã¶Pÿè‹ìËâî’jþ‰„ºî¢u÷Õ¦ä2ÐÈx<££PÓOQlc¤ý.'À¶;k e>ï飵Jÿ ¿ú£ÿ >µÄstls otÄôm%w4û(È[6ºzêX¾Š ‰S!—t©ö§7„5ËìÉnï³öóÞ=ò[Z“;µgM  ð.¦P[ÇlYnƳX é$ŸÆh¼QÈ­˜Â\jÆ»$ƒ[Q‡ZA!Éô¿¤.öqÂ"_xfä–vª(˜¼†A }gµÛ$ØßïšXû§™OKYÁ±ƒØK@q®+Å7<ÍvKîÌ5l ¨ëwK¿§€Á@ûkb-Zõ~´ q¥DêÏ¥/ uJë¥AÔŠ¤óPÔ–§T€~%Ij`¬»à‡;Û¼?ñn]×»uãÉø©Ü‘nš«.Ÿy1çÏŠÝ휧ð»U"ê*Š"e•åçÙ ÷°î1Xgçà–;«RHÏnímmO^ÝL$ç㤿òÓtZm=ÙC&ÒìD±¾ ŠTžêfés¨8'KÈHiT…Ú7³ˆ´¢|)m¡ñdûµÇÙBømy)è c–˜TòíKnË ÝbâN$’\§Ü9Ó.ýkxæ`ÿwiÞWÂnhÕÌS2X¥ÇŽíÝë Ææjqnš´8Ñfò<žÝß|®Ú„e0rº°\Á$ncØOŠ^uŽíÀ@ZW&âRÔáã…«Sƒ¨+ÂÞ½²tþIW2g¹K>E »jÖ’B8s¶žlc5•}‚ 8~Tµ+gÄ éXÝ…m“ßÜͺæåõ¥Å–Ûƒ,1Œ†9¦aË-ÙˆøÌkÉsb'‹ãxáV®îížÃhìx9ykq Îj[Ͻß:'ǃ4Gn89Í9ôû/oOŒ²‡Î¸…ÎA[×V'±>Û@IcleæF*~ÜL¶ä³H2Í®´K3un¦-WMÉr™¨Ý@10Ê_5äW6vËØw½Ó}÷;øò7’†>)zÇIÀÀZÇ6S¨°—‚ Gwnkr÷wnmÙö×ï6³¶asdóo â%p1ð!ÁÎ¥¦ ž w?XÕ·׎‡¼ñë·L¸2µ8a´òÖ”tÆ/¸3 €2sMØNKz.BÚ”“ž]‚Ç\ šÎ)ÅDÌmFï—ûŠNYZoK»;öDýá>b{X 㼊ÂëDeÑèñÙ3ehmKY&²F—°Ûîü37ÍÆÙ·¹´sÛ·"ÆÅq(kí¤»ƒSÃ_«ÅtnsÜÂMs4€j ãv;®6ñÌ•ÏåK†Žm u 9"ï-¾Âø´8~V.µ·,tí©–R÷$µÒ‰ÔA²[qrS9Ô"JdsQògpÛÛ`¶ÅöãÜùl„ѱ¶-È^Ð7P.–äÍ™! 9ÆFÕ¤P5®{zxÇó/4ùl害î7FÎÚ¥ÚHÃݽ®‘òе¡†Ž*I 8mq¼Qç²¢Üz©S*®øé~áR¢B¤‰T_] œL¾õ4ÀÆ÷¥@JõÜ|Bæ~âWKvK@¯A}âzÏÒ¼êòC'"¡‘Ôvèqú8ÚJ~ Žù?ÿåÆ þ¨/pÿå™ú¼ ÿþ˜ÍWü5oúh”åüÆ~Û›ôr/9N௡hBñÐW(³][MîÛYÅèÑôœ…ǵٿ¢Ê>¶R“jyæqÎGÿf~æ,ª‘?Ø(`c2ñddÅ]G‡{#˺ÞAž51³ž:Ú¤¸u€BîãŸdÌ„É5ÏÇ ˜ekMèÆ°ÓÔâÚ€zŠôG%ð3–˜ßÇ¿¸3BO*ákt$±Å÷ޝçSè¹nŠ® .¥+=/ èÆIEI 1»âEAT“ùÿns¯jÍ‚.oº<^ñ¥—v×p=±ÈA KX褎FÑÀ4šÐis½{5Ë üYc•åÈ}þÛ”‡[Ïo3KØcÈsdcØj p)R©£½óVaý![€hÜýq±¿ø†Á÷ó‹»1ÈGʰ».[FÄ5Ýú"ѹ®Ç.‘šºÑƒD«#¬ªÄQ®ùÌ à«8Ò6vÒø­›êãb[¾Ã`æ¬ {3Ü÷l“ÃÃLp ipkZCèîË#Ú7&âø}ÛR×3n÷v2ìËvæ¹²Éë\Ȥ‘¤‡Ê€$[R|pçõîcàw4ež%îÌ…`%qàü¹~Jå¬àÂç·ÆË‡³.é…îYI)%¤“Z9kQk¤fê& œ[fCï]ƒhó«gín\Zà3¦K}銱e›ñΆ_¼Iqb1¬ !ârÖ»P:F³¨Šb7,w&z\eñ!“mŒ…Óî[zÙcîY ¯29Îqp-1á¤GOjG5Ê–M{A-\i1!)–0ö'äY±igl˜(ØHBI8XŒ]+0ý58Ã"‚Ú•2œÅóÉ6ÆW—œ·ØYMDZÛb³¢êúŒskÄ•¦F¨Ú@—…[!ÑBâÐwgqûËzîÛ,‘¾{üI‚Ö®NøXÖǤ—¸9ƒW SßùO `N7$²´C+.VàáÒy´E™'1¥ê¼{A~w«yƒ—nã ='Fé.ë± kÙå)ŒO0¹¶7žúÙ–Û^gÞZÁ¸"2\27‹pçi¤BWµòÓÆsY«Ki¨‚@XŸ³ó»gjni³Ñ¶Úypï …Ïi˜´j¬†6’[|PçSQû €Jé)O§žÎ±ïkÄG’ö³ktå“kÎ>`ÿ÷ø¯Õî±¾¿é¶Ïÿ…v6VÆ·X#…ËÛÆ…ý-ˆq >Éö TŒbwU£-g‹vq“ÊÁÌ ã\™‘1û,—ž¸~½-IX)æñS®!¾&^Fº²mœ&rvôÂWcÖ+Ö‡Ò(Š)˜TIÁ6™9{Îmm&î=¹¿~ÜÁç­çd±Ç=ý´mx¸šÑš,f-m1È*ãã¸ite£+²qÖܼÜ' š¼´nk+ˆš'Fð×Åi3ËL1Ü;S£x“Kµ°Ð}–Mx'´¬bq£eÜ’÷VJ°øjá¦Ì°˜LIÉæ§øƒú+C"ÁÒlÚÙç·¥JÜoî-þÁ2T;DÕ1u2†"*ë9·rs1Ž‹·/·ãÌ_IŽmýæ§UÍ.uÇzÇ2&ÅöœdƒCžÜæ-¼ÉÆÞÉ™´Âáq¶Œ{xëKj 4ÐCݸ:GIöZx‚GC]áì̺ósÓ.E39–“&àQ@SߺUÒ¢›T΢mÓ€#¥}©ihË;H¬ã¯wm`©ÔhÖ†Š¸Ð“AÓA^•ó Åînd¹}5È÷8ÐPUēë§£©|%SnÞ*ç-\U^¬áLI‘³_³ví´1}®êî¹RâôÓ'Šfî5šÅŒeŠí$;í¥^°l$EW©@'þ@×O—7–ëÛÛ3ùˆ´Ën[–ÚcŽÓîÃÜ׸kuìä6Œk×uS‡J÷µ·ó;›“7츽‡^Z–ÚÄ «‹GG]x¬t‘àŒxçòÒXNq´t['R/ÜžrÎ9[²d‚Ž].b¥qS1„ Q0€rz¿=ùKwq­¾f\Jö± Gp*ç8ÅN$Ä€´é¹OÌ;x_q62VÃKœuÃÀ4TžW€ !8L|—Õ^1/äd•‘¿œ†<øÝâÖ½á†Mƒ«Þð•*{À0Q,X˜Œ;tÌ‘ž1@j¡´jÂîon1Ê,Œ[Ø7ïW÷eâÚMmµ»+ÿÅ{œ ºHpSA:ehÛ¶£—8SÌ\°yšìýÞÎÜ8´ÎÍM3ÌêQm#Ô(_BGÉì‹*Ñ០#.HÝO%8zâJï’±2Ô“¥–Y‚y =c¸Bå“zs¬Œåµ? ‚2›|Ü•Ä šîfï-ÌŽNÞíK{VE¿öìÐ2æÅ8Ú¸ac@9¢cX(\Ó*4fq¶Øý“Ì›]Á5äÚ¨¦tn$–‹†š‰î!ñÈæ¶G8Ô5ÚÝC¨ vŒözfö·t³\†hlsŠ-öÒòÓ9ÊRNFÄ%ºÁ³…㦢ým's˜ˆ•Ɉ9'n© ¸pA¹çöË—¸6CtÜ:6Gc$eÏzâã~¨Ëcî¼bçŸéñI¨Zt< Üñä$fcº²ÀB×½÷ÎsvÐK^Ú>¯×À5£Æ¼`(Vó~Š û7ðù[.w ‰Ä½îFº€ž–;~ÑnÀÊÂMóîˆé¨é­tðZÝüÄeÌ€6C¶íª¨½Š¢´§Eh+Ó@»m#“8á.g÷Üô4¥GvúTÒ½•ú×0zÒÖ”àÃèÛåú‘vT—7£ ÂM%c­gw{†÷ôÖœQœJЍÐwDºéX˜fÊ[s‹zÜá#æcÛöî·a¶àÄÒ:ä }+#,vò×kÔyüÄ͙աlFb$p=D2¦«-硸²²ók[{ Øx§ðËq@üQxÄÛX‹ìœ¶?+¶B[‚fõ¹ÍÍHÏK4Pæ1QP(áOxC{CyMç*³;-Ù ã}”Ës*Ky{ËwÍßÇu¥ßšŽÞG"Ô¸wAƒÆ x£Ðní¹ŒÜí³ÛV–íÉ™¢fÇiÝ> ·óš@÷ºGŠžYqà ñŽÈ‘¿íÓí nrXÿòî'®ã‡üØÿö›?Òß.«OüÓÞ°.Gh°ïƒëmq¥Ë®œåÁñ0J½w™-›ÿجWœr°ÿ¹noønïýP»ýÆ7ŸÜ:pµp`Ø¢_¸ºÏ‘ÅYψ}œí­,Ñò‡”}ñÓc„|ûVÊ..w LDuîkø-ˇå0·=†ö”ÙZäîÙ{i9Ãx®Ôk'”&.{Æ>Àqh´rU®. Åâ'”d™Ñlt¸¤¹È¹LMÎоgÌ­ïÊmñµn1øÎç1º. s,£†ÞGÝ ÜÚDà{±$aŽ!Ï-ÔÐXAÕ¤ï;ksjno/ûÜnÞPë§Ë3na²4e.h!¥¡ÔqR£Ÿa<¯{EñaðŒn< ºéÌ.²Ž³r,›zø^PÌÞ@DÄܽ”C)ƱMHå›S ˜¸&šj<ôÚ·Ø[«¸÷¤™î›\Cl²’J%¶”3Se’Hk#¢sÜY#ÅAÑ©Õsš—ÚùûLœƒ µÙgýãq’7VpÜ1†9ã.¡Œ’ŒkÃsš¨(Ö¸¾éšâRÇÂYn{-ÂaLq[/lHÛq®/²â¯Œ¤7KFÉÂÁ¡oI7‘dÞ5»€pwŠ‘DÑíHCf1{».\f÷®&ÇiÍšÏ\Ûܶåó:öáöÖ]Ñd’XXâò4ÚAwØ$jðßÜïl^×ÈÝî(±xˆ&Ð66ÚÂÉî»ÀZæ0Fàæ†ƒ¨¼‚Úé$tWÓðT<ü<Æþ™o£ù£yÿÄþ‡-S˜Çÿ mØíþ²…);#a«.øÈ/ü ]Mê«UE1u9`LAIÝV»ÖP†Qgì²,"dhA•4QÉï•(ŸóNÛ7·w…îÃÜo‹X-Ã…tÇu¬‚g8ºÒBd< s‹’· >/5¶­r¹—ûjO,Ô4«íߥ‰ õ¹· ƒˆºGÖ\f“Ì_ê,.fËîö÷,t%ýÅ·ŠŸ\z C®’Jàö‹>,-û¡Ìµçdðû„íM’rYÞ4Ç Ý&‹™‹ËyÜKæÏæU—8‘4JÔåSE½öé½àæòÓr«!‹m¦÷pf²×e¬f=·—}ãÉpÔÙ[#KcŠ—Šx¼*Õzh´©î_yÊ[Û¹såÜÎy iºÝŽ$6§HãÑSN…³Úÿ°Wú|µ“þ"‡®æ\ÏÌHáŸô².®7þäkÅú6/ªP7³æl¨t›‹&ep¢eßQ4@§L‚:åLD@<#\Wáãù€ƒ»Éð›¨A?{–•=•\–š&åï ñ©4û´u§ÓE•9ÞÏ6TôTO Ön<·pOÙÛ}ÜUk Œ¥žŽZ)¢Ów ùz^M¤Îš¤Á`PÊ5 ‹tÄ¥0ˆ|³Ø™« nù¯y‘¸ß_x•²ØºKÖžáV¶ö倂Í4÷E ^˜²ÝØ«¸íùwmeÒî#,» µx‘¥€É%Äóô:µ¨PõpÉ6aí6ÅN$äY³²ÛɤÕãù\cvÇ1âM=däž&š%(ñÕ)@9@+§¶’åŸ+´o¨¼s´ñ.kY{Ý^“â1¤¸ž€ +³yß.=iÕ ž•B@8R-N§Â<õ%©Ô+ÃÃS¥:¯^ø4OzÖ;í¢<íӯ̽ûûóšý­yúÄ‹ï]û£Šýmú,ðìvŒkS[ŽÀñ_…+ÄŠn%C½¦ÌâÈ·Wîg)þíø{úœ+òÓ˜_¿ÙÊ{âóõ™Aë^E¨T…`0…¨=*à~à¤;ÀÀ4"§­X !Þ(Ÿ¥p?=NžÄÒ­•:@å$×H‹¶rTÕ.ò`»7);js—A&G(N_öiï¼a¬fZÉ×Ö/¼%¥Z~‘þ~#ëY<>Cûºý—ÿeZv½¸{²¶¹´uµÄdøÂŽd”á¨8P‡MAÀÚ½§¹ ³A3dà°á^#‡FžÂg3Gâá2psr°ÉâÆŽ•…”Û÷ 2‘©‰œöb %ñ€4¬t–°ÎíE¿œm%ŽÿÚiñ” ‰#ûTw„>°j"JJP¢vë@Y%)SQWŒ$ Ü J&ûhùˆ ª˜5¤(&”¾é0£›wrÃZ!k‡¥Í¯¥qºâÕü%¶ŒŸôjßè4üK‹O½HƼÇì^·tA"Åe~ÜN@0  ñ#n”GT'(rdíáÊ襵è«Oõ¡ßåë\“ýx_à#ü…r¸'%dÕ˜îA»t Îo"¡HEJnª:Žð€ ®¼µÕ¹ŠÿYuÎF>ôŠP[šWüŠ»ûÍ[’ߦCÇësF®]ÃØXP §¡Dª->õa0‘C¦}¼…ÝÔ@L‡–(ÇûLÁ=‚&Ž‘Û_誦]BÑHì¢I{ŠÞûp³–¤hþÛ‚D¥T“8dÞ&/)^¼2¢U chœµÒ‘¸ØçÌË«‡pûRÔÿám8.Ôwwã„FGú,ñš­í½°ÑáÁ[Žz^qN]QUë‚¶ÔâQM‚GM±SÓ“Mšº’e¦„hÅÛÁnÎÐÖêáÚóWWëRèß3ëu#äãÖISzÔ»’ÒbÙªiÇ1'Úvi‰)L¢€A(ï)ºDÌaè<£ ~´¬ÅÍIJ—\ÉWR¦§ x8žµ²aÃc5kG`<;?Ëô.Ûe¶âe„L_ìôÝ( sŽš€Duæ­N[¦j$ž+`û¼’4 VBâ:z>’z8u¬Eâû Ââë=7ʼE{¶u³ÈË&8§Ij“¤Á;†ër™4›52mª%ÿvqÉïLcÔù_ˆ½Ü9?¹BÇ7LJ\?¨éã5ë5¬Žh?Õmx€«ºnáÂØÙÈ3DMí'†¡×N zÅHà¼7:çYE9„Ê*s(sˆ‰ŽqG^QÔF¾Ïclc@}|èù#Ì’q{‰$ý'ŠÔÏËOObš«ù‡¨i§T€~z)Õ ˜jKSªPSž• uH mÒ—…4€~१±:­É¬´‹4¶g"õ«g¤Þ7nítv˜éŠnRMBr jº40‡†ºòÚÛÌöÉ4ltŒ5i-´ôÔ8€xv.V\M\ÈÞæ±Ãˆ€|4à~µóùêËTUe÷|GÃñ˜G"Ù,n[b%l{gÙnãæjÝó£Ûñ~€ÿ·,Kçm–v~RÇ1Ê(w«ÉùKËÛ½´þÌ¾Þæè_Ïp×FZÞõú›Mmihé p=oüÂÞû»pÿ{ã[<Ha-yÇ»n—WCˆ-=@ŸX” WªñZ ~µ¸-&ýÚ-[º|íÓv$2lpåe‘f™€€b5MC˜È`H  PÐæ áe½¼Ot‘1¬‘æ® \{IIéí\¯šYÖHç´PIÁÙÑÔ€ê÷+µER‚}ªªÛPZR‚œô¨z“ªÜ˜ËHÇ †zÄ˳XYº]°¬Ÿ³PQ:b¡5ð¡]y­­î±àM¡í‹–9憦'9•hH¨ì4_8)ÕÑ\ºj¢«ïNIé*À•ŠêeÙ‘Â¥j²¤ÝÜUVÅ8"¢…Ü % š¸m ”Næ7¿h u ;éjäÈbpˆš‘SB{HèFšÆLå:g2jÅ9S LC”u)Š`˜¢€÷ÀjœÀàZáV”ƒˆ5#ð¯©Ã×/;—ŽváQUÕT]uD QULcœ@¥åðWp²áhlc 8*|‘Åò8¹ç¤“R~µR©·ÇUNÔª¾öR/#Ö :bà bìÜ*Ù`!ƒCDäP ok × ÖðÜ3»|}ŽÀx.Hæ–k‰ÎkûA þ$}©Œ"cxÆ1Œ#©„G”DDyDDj´(85©©é_z’oœ Ý«‡®ÖlÐ [,áelÓx¢s™4@Ú» é\ ¶†7ºXØÑ#þÑï OÖ¹]4¯cc{œæ7 h<«êB Ué§BŠ¥6øûµ©§juL t‡”)Rªª”ëè©-@)J¦Ú‚ÕUJ TЧU÷šIê­b£ÇJ1ns(Ý™Ü*f¨(q9Žt[˜âŠG9”0ˆ@DL<ã\"[)œ1¢w 5Ã=' uõÊfÆ"sÝ€I ðŽ´ESn5zAQT §pT–¦ ûÍ ñVÈ2QÛ•¶1ÌÝ¡×Tí›™Cê aI#(c˜J¨ˆë\Þ&ÈéšÆ‰]ÒàM:*zM>•Êe‘̹ÎîÛÐ+P+ÓAÐ>¤ESn•T*j˜ëè©N«1±þLá†W[vNb±²E¥uZN'K%àp´ž¾ ç¦ìÑ>é^9 ÅveIªä\û©¡¸* ¾GžÛ|˵ܗ9­¡}Ž»Åݶ2lòx1[IK{ËWBXRç´´UÄšý>‹‰ÍlkŒ$8½Çk{on^Ír;$5ÑpÙKC´Òpq൫qž-ü®\oeãëfJÑÄønØqkXQS¯Ñ‘¹übá“—Æá™Iœ¼ã–¨™T›’ §¨ÛÚ¿Ë͵ŽG3Ÿ¹Žïuf.D×O‰¥·@-Šƒ¼sAÎ s¨ã^N==纬óâˈöûŠHà騂ù$#Åy¡¼:Mxc™$ž‘¢ŒñÉXª ,«2¸T­X74UFà~Äê&_|%×Þ‡0W¡:Þ(œ±½ø Ô`=4âxW­i¢if 物4'¶ATÛã«¡QT §WE*& b©Ð>íIju_z²œ ƒW®Ù°6l»••A¸w@Hç2i4÷ •×m¬½ÒÆÆ6Gt'ÂGõ®gO3Ø#{œæ7 h< }HJ²Õ_s™ÕŸGÈKžzI5?„ª‚ŸÖËRªPSnµ¢*¾Åºpš¸tådš”HÙ%—UT›Û b C˜J‰L. Päjâd1Fç=Œh{\@ŸoIéí\®–G´5î%­è’ƒ³êT:êèU 9é§T ¥AjuHÛ§wФµURœþJšŠ¥*œÃÕKÂRè¥zª@?0÷tT–§^Ô€~z‚ÔÁìHæÔêÏä©¥:HSó êJ€ô"«Ù. ÓÞ´£‹1Ôv¶K½_˜Ûû†úÍ~Ö¼ýbE÷ÆÎýÑÅ~Ͷý zöA³ÅZVÇÅNÈ6x¨ª8¯Áç§(]ßn4ì•!• &Fè'|¢á}Ó€9ÒoÈ#Èÿeh¹)5´†š—;ñŒÿBØñO0ÈñâøúzÑ—³‘…ì—÷•âè ˆv¬á Z¨CK\Ó—jœ[‡A9D¦.§û“tµ9Ä“mmŒ®çʳ‹i×À¾B˜™Zj?I?e¿iÇ£…HÌÞä­m,ß!¶ÂºYZ8šŸìŽ©Àt4_Ì·–®ÌÍ{J^÷k;ÇÆ*,c[¨¡£`â1ý"13èlÑ5Sî–PÆPÚ ·K÷–ÏÚvG2É´-s¿¬ç´ç·8ñ>…óVéÜsî,ƒ®OpŠ?îêphêI+­@áÑ[QjÖkØ54N½©Nz\Sð$)ù‡ª—U œI¼m›Êøêí¼&˜[ÖäO¦ÇÇ|c1&¹1iéÒÎØF´í×P Ú.²I]L`ZÄæòøÝ»‰¹Îæ$îqvºY_¥ïÑ\í,kžêÐÖ¸ž W½Ìä!Åc™Þ_ÜHØãmZÝOq£F§´Tõ¸€:ÊܲF:¾1 ïpcŒ“n¼µo[YÙXÎA½Q¢ê´YVè»nt°pî=û7lÜ&²¬³uÑPª&sÀ#Á··uá Ü;zá—X{–jŽF‡à i«\æ¹®®kÚ×5ÀµÀBæÌaò{'.1 É@í/c¨H$(ZK\ µÍ%®H ­âàÄYÔÆØó/O[ÞŽò«‹¥…püoëãçlª°—"³“s9ñl¢&KW­›m7’“CWVÃvmì¦á¿Ú–7óø¶Â똴HÞè\0I Öæß­„;óo~ž‡i<=ÞßËØa­3÷pèÄ_kaÖaqdž q{t¸SÇkkÒÚŽ+®ýÁ[•‡ªû™¶xý^Á‹W/—Ü:‚‹Tp°&˜j¢š$9÷¢:h\I ×;šÆV•qTô žW$qÉ+´ÆÒçtÐM>¥Ø¶î#È·V7ÈYvÞôì{ŠÜ[-/Û‡ãx&¿¸¼eS„¶Óø©ä›iÉOŒdÖ*Z²là¨ë¼¨ššµì†êÛø½Ãaµ/®4gòm™ÖÑwrô[°É)ÖÖÙ¡€ŸÎ=…Ý Ôx,½ž1}†»ÏÚůbcÉ©ƒA™Ú#ñKƒÝ©Ä®§K¨8®¹6ÖÃ¥aêê¥áN©NºTª@Sn5%ªª”Ü%©ÕvÎ"Âyc;Ü*ÚØ’Ș½f7’­c¢ˆ˜¤y9;*å„5Q)UxåÌpÝä­Wuï-­²,Ou^Ãghçin­N|ŽþÌq°:I\ØØâ(³Ø µžÝ7fÇk%ÍÀvš°v½î-cÒ÷4ÁwBà‰BÃs1þH€û9/;kÃ^qLþ5„—ô«jà*戒íàd¥¡é…lìT9'»ïÈ]C\ÛÝ8 ßg-þÞŸï\Én÷h’=3ENñ”•ŒqÓQãZkÁÅeóx ¾Ý¹ŽÓ3sq, ™£[X䮇UŽp¡àHpëuè)ÏYú°õJU6ëÓJ©Õ()ÒP©ÓTê»/*bœƒ„oYw“íÿ³7ŒKxçRá+ 3èèJ±BE‚Ÿ[òRÑJöìœús uÐÀ×6ÆèÀï<4{ƒmO÷œD®{[&‰#©c‹4ÊÆ ât‘¶A œÞõ¡µ t:M d…†@Òc$Âz—j e[¸²ì cþoæ©ÙkHÕ½ÿ9fâ§‹l¿eèƒ-é°Ý„áÁÒA6¨Ÿ]ò˜S÷õ¬é¶FC)Š7?ïøh5ã{¹3âïší]Þ™+H‹Ü:à³£lgM†@Aþç“•ÑÛ;\œ{$îœÚkÔÊ?Ŭ€ô‚GÆo‹2èÆ×tõ‰zÆ|Mu[/9é±ò"ÉéMS£éÑ.ßG9Њw‘YBr÷ûõ“Âæ1›s '}‹¹f¸ß¥ìÔÒH®—µ¯oÐæƒô.†S}…ÈKŠÉÇÝ_Àý/n¦»Kºi©…Í?Q!oVV1¾òEó;gÁüm­µnëÑׯpÑÿÛȘåVC°”dâGtSìšuÇNBWK3¹px »+¼ýÕÖFàAnÝ;¼”ÒŒ«àΟ´òÖý+³ŒÁås÷WXè»È,¡2Ìu1º#.£œÒïô-è˜['šÝÅ×`[:Ûù¢vBÛÆ’[Áö–j*t¶Ëö^‹ñ·¦Ãöf;GéµHß唟¾®™Þ[hd2x¯¼ÿ¿á d׌îåüÌo‹¾kµhÓ%cñ©{‡AÜdmœá³°¿î?Ý2rº;gkódÛ›Mz™Gøµ4Hⶺ¼¬;ºâ±.˜7 .»MÂÍ®(”g.1Š·"J.*½…s!ª)ro*šÇH7ƒßWžÄg16ùÌdí“tÐbyX51àš ðè]<Ž#%ŠÈMŠ¿‰Ì¿·q0ý$Rµs ›AQÄ>•ÄNò…e¨>©AN¾ŠE¨)TÛã¨-UT ¥F”ê˜è Ò¡N©J¦Ý:{Ô¨ªPS¸*KS)TÛ­AjuJU:ªtªªR©×Ñß©N©Š®ß*ê”ê©-N©J§]AjuHU6éîT–§TÀ§?Œ*S±)TÛã¥@RU%©Õ()×RZR•Mº{•ªª”çåè¥B€R‚›z‡Ü¥@R‚•:UU )¶¤µ:¤:º* SªPS jiDê‚›téîÒ—…:¥)P"©üÃRZª©üõ%©‚”§æ¡¨-N©NR¡M ˜u¥Ã­J¥§±:¤ó IjuíHç©ÒRù‡¨jKSªö§‚’kgDc¸v$où<%bæ¯c@ ž²À:½`ïìšð^‡ƒÝÕ‰¶“­l‡¤v‘OíqÚkwO;×hš𤹠›¨ÙTõU3h ‚ÉåSAÐÉŸt€~M5 Ö!Æ_ž-ï¼Axx´ÉG6±qŒñ`ŽÐGá[#Û¾×–J¹\¤IdÊ£èõ‘?¢©Ê%MRoêˆ8ßÝy`0w´×?n'ŒªH¨¯ÀV:HK N’?Ê8JÞ-X%'n,xÙ‹’*œe®” H•DÔí&lALtÜ´ÿ wDj/¯73áû–:ÊÞJ´ñ‘Í¥< õ.{hqÅÚîe{hGÙþú}k'¡x¤ÆNx[^'$M'Ô}t©»ù2 ƒ6.•f`ÈÐÚ9 Љ€¤ÓQ8€V¥6ÖÎÆ6AöM–Ytµ  ¸‡×‡ p4ú|Íe+¤6½èdm©ï MOÑ¥eÊVÖBq7Òeš1’ŠE¸k,À[8,’(r²¾»WmÄŠDå0€è;£È:†âÁßcå6·Z ËkPê‚Úñ­ý¾š.Í´Í{u R½Bœ~µ‘ñ×)IÙ© •8‚d0©¼'ÝÔJ‚]©ÌpOÃÈ=þýh÷‚jâê0qLæo-µöåõ$|8» $±¥ÝÛg¸7-ñä âèZ[BkMZÞõ¾ –†ñ˜¬^?=™µ«%ü±šœ·E„ø¬'¢GPA.qÈ® 0̓Ã?´=àÛ€×U×pÚ64áì+™“è¸Ö²¦,bÝ“(\ñ¢ÕÁÞO¿·®´›ªÝDQAÊ ˜É‰NB@æþðÎóØ=éc÷[[ »Øþó š÷»ïÜ÷˜_¨ÄÙb˜¸<9Îc˜ªÒNÝ˹ŠÙœØÊ훳<÷vöÏî$k[ܾõâFÐÕîŽHÃKHÁäŠAâtÊБñ 40öY± ï_šöu•¾õçžæÜy¶‰ŽÞ6¶V ŒØ5±ïžV´ð9í:^<`׸p£W¶nK™¶Ï*ðx\[ŒC3ßÜݹ¼ ºÖňâXÖ‘VôÐxÔ¬`á0ÝXgˆþ+µ²: =S1#Œîå„Y8;…®D_¯.ò¥™¦bå_‘ÑãRl-Ôj’‰•S(%0‘röÛ{æv}æëæ0XÍ0È ‘:×ýÙ°Uç»{ Lçê!Å¡ Šz.ñŸkžOmþâ Àç±mYtH.?>eñ¶¹ÚŒaºKAÄЮkÄf#¸¿Ã6;éáµ-n±Í÷î·j[v=¯4¼¼Š ‡Þªåg.µKP1H£‚œÅ1J%?/·Øåï)³¨ ûÖZmÛwmkt‰®ftb6Ôyè$0´MFGxmOŒy…ŽÆK/qo[Ïq-+ÝÃ^^à:É%­4.‚CcŒYÁo÷T¦ÂÑyŸäçQ ¼Kx_·U¿r@d)kz)äÇÄפ(v#k++ª‰(És!)„ÂsÖÞ7çç-qqo=ã.%¶Û,M¾‚Úa–Õ’½±÷–ò:GwÁsA4T@LŒÕpø.[ï{÷í·JË6èä6²Ï,rGpøÚ_¢f7º.kI†ƒj@c¸0À˜žÈÁRÜHq8…òú!ÎA{Œ1Æ*²_Ç@L]·4+w ÜR7Âý¤ÃÛq*´]±…»I@Á¨ï&U3Û—|îœÖ÷‹—œ¶u“.Û`Û˻ۆ¾Xà†BLŠ&¹äÏkƧiÐáØâÜNjàq›^Mã½EÓ­ÍÙ¶·µ…Ícå‘€™$ŽÑsN‘«SOh²Ö÷/Íx áÈoX{j÷Kåàmû9 cƒH–âwЈÜ XÖ´‡<ÒºOŠAw[‚ÅáŸ0Y‘²|=žîÇy}[öÖ²R—ýÑu'yµ¼$P…Š˜²nñQoEãGiä“t©Æ&€@:Ö¾cí,Ä–ÛøZd6˜±šàäma|ÜÀÃ#㸈½íÒæ5ÝÛ˜j\5¯‹ÏwŠÙ[‡ÉöÞ,÷ »Šg<­”L&pc_ 5kˆÖפtqíkãð+ƒò)°CG5^W,2ñðy3Û7 -«rhe’I¡i!½õÀ‘š$”6¬ÐÐÚê-©¦{)‡ånÙÌ|'˜+›ØËYqy‘±‘H@.î¡,v¦GZ;Q.àêp[õ‘ÀÝ œ8£ÅY¦ë¸S Ü9NÞ¾ífèW0h!)t9<tÛA¾1ÜG"ºfQÒ'D‹é¡Ç£šçfn÷emѳ­mÝ‘Ìæ"²–Úbh$%ì’Ëâ÷dÈÐ+š@cƒË:—gÊü]¶çÎ`w-ÄͲÆcdºŽx€âÀæJYÇ]â]p«šZÖ¾kC ðm™ñRɶ™³^*áæJÒ{|«7#oßsõ™u-&Ê58¦-cá£-ëÒZFD9ãXB™nÙ3 ‘åËooìýÛŒÛyOîl¥ÆàŽvÛÙ-´v·†9åîs¤|¶ñ²@ãÀM 3C…ý·ËÉ·¯³vÞváß§/ts¾xe.kt´5Žg¹…£‰„ÕÚšjÞ¼É8—Ýü1/Äv ˆ¿,ulì¢Ó^vmïqÇÝhÈ5’†FN2牗g¢.̳´RY¸“³ã‰J@H¦_?·wVøÄó)¼¼ÞÒØÞ¶óëË{‹had…†HÜ÷‚Ú5ů­x6¤ê!˜|ÖßÚÙw–ÖŽêÔÛ_ i¡žFÊÀæÊdž´ƒR›Jq4H.í,µ‰x3áѦq{Cfl…rdì/`dö”5Ñ oD@–áM÷Æ—®aVzùY¨‰¤R VJwí’ë;Wusƒ˜2憛Çcs7V­žHd–I{¢ÝwB@Ö†´‡K1$¸ÈÑcC«œÏíþ[ìèñ¯ÉÇ’¼¼¾ÆÁ;¢d¬‘÷Ú¤ï %ÄÇn‡¼êm8%ÿÃ.°³¶2e=–%­Î²Ö?‹Ë–Ýû#é·r¤›NS´×kå˜Ýæ|Ý6Ý¿¢ú: ¹"ª&cèŽsÌåØù)¬qQ\s~û­Xý0Øæƒ8sÞÜi%úuëqcš×CÖ+-²6Ö+uXÅu$;'!hÛ¸çsuJ"sIÖ‘Þ꺴éhpq‚ÕÜØË‡ Ä\Œƒ°w¸±ûû~qþ?Ë÷Œ€MZR’‘ê?Fïdkb2=¬â)w™½íNR¦p­?rs}òúÞ<î7·2Gqn¬-ÙÝÎÆHàטß>Gº2ø‘ýK‡ - ³6žñ™øœF/5a+á{ »™Úâs˜Ò扛Ý5úé ¾¼)…öwgC]¶Ö@‘E¥ýe¥â†b¤´û‰òšÎumÜ[€‹Žb£2?I~ÙG &¨¦bŠãßvÛÍÿÌbnl#{ì. ¯yŽ ˆEþðÙ´¼k{Ü$1é ¡ÀÐדi϶YÉì¡ÈAvö¶î>‰Ýr?2b«N–µ¥áÕ.!Ô"¡u}©‰­»ZÂö|å¨÷÷ ×RÍ“-n/å æßfŸ˜™BÆ `5LÑÊ8jˆÀŠªvªêo{Þ­›)º²9<îþÚ· ·ìf7Dæ²’¸ÜX:G÷¯Ôu€ãFpG+a·ì¬q;G? æ7·ù7‰çV1ÜÞ5ÐÚx¤ãq5èÈÓpVõ¹ŽeçSbÙ’0¶ã˜É'7oIHd];T»Æ"‚‚&)JÒ9}/8!åM†so¿2ÊĺI#–Y®ãˆ¸¸É0{.“K»¦1§h‘à’FѼcå¼¼Á»Åf‘’þêì6[†=‘Çn÷é ŒµÆF²£¼sÈ⡤^—„á>:ÖžãjȽ&g•—áóH\¶ÓÈ'åŠe<'D$àN²;gFrÂFÓuŽØ]Ã(%ŽšÖå{ÍKŒ†ÌÍaá€ZgòL†fÊÝnЇD­‰À¶Žd{Cèj:GBÖmv6{Ÿ’’Sqˆ²t‘–;Cdá©…í¡«\ÂÒ[QJÒ«›OÂ3ºxSök[*»A…Ë–2´å˜, Ÿ$Î_4„s¥Y¸( ÝϺmÀƒ¦•†±¾—Í.cdíà öØ«Z*ÒèñÚÚ8U¤Ž"¢£‚Ê]ÚǰvUŒÅ²Q¸´ÑÀ>óI-`b±Ê ŠÝ™Ž èíöÛ§sâ9‰Ù›¡Ö’Zd±’)bc£Õ{nA¸¡Ïwæû¯Î4µ¥y\û’Ù—›ŸÛ†\YdZÉ#‘áôµ˜R-oÞx„ý“BhÏñŸŽømÂwÔš³–³ÍÏp¶3ÖáŒ`”P²ØìÞCÝŸù¯ì»‹èðŠ»6™b‰»u bÜ;(n&à‰‘ŠÆ@4IÊÉ7\®Ì:iª©ºhQÓZÔîöŽAŸþŽã¼‹û/¯ýãýU¸Zo (/!1¿¬¶„~êñ–øÑk¢Û îÁš©é h3‘ËöÊ ±3g­ÓQ1!ûBHMÒ”7@§(ã~á¹-ÜDðÐ ¯Ghý}=«/W0;†4v;SúW-€`AI¤ñ“õ¶>ógL1Èö­Ôm_ÊÀ¢# €d÷ˆb¢q áF ì‘i}¬†Vôè §ej¹¼qLq,»„ÓãµwÄW–µƒÚß¶;œ+u..”AFd]Ã¥Žªª9QÊ¥XÇLÂM0&á@F±_ç2—âñÙ=¤p€vqð©“qàí¡“ŽÆµÇ†”ükƒÎqS~ÉÊqÀ„88“}º® ¢i]äˆdTCB˜Cw„Á  ¹ûN\ØÓ~í`t€4è©p=€¼Þï.:-'ûN<~¦´ÿ”ø:ÈJ¿•r£·î”r²ªS˜Ú{EGyC!L¡¹L ˜yGQ­òÖÆÖÆ.æÕŒú:O„ôŸ­i·W×WÒw·O/ÓÐ< }Kã󇊻WU\ ¯xjHN¥ B•¨WП @70Ò (¨Wóù)iM ˜jHíEUÀãá©Òš@8søêKUT¬šàÒàƒµø®áê⹦¢­Ûz-YRS3³²,â!¢cšM6UÓù9I›²`ɲE(ª§!PÔD¼ã›¶¹.Wçñøèe¸¿›pÈ⎒G½ÑÖ±Îq<Z ' -Ë—wv¶[ëyy#!´Žþ=ïpcÐðKœçÖ€8’HveÉÄ\Æãç.g¼W78ÙŸ9rm’ñ’HÈ[Ý•;.%Güz˲•·.¨_Ù.‘”&Š&áo‘3†»Ø›Ç‘˜­¹á’·ìcp{ f¶¸ŽÖ ×éxd°ÈÞ- â…Àæ¯7uÎÛæþéÁÈÉXܽÓÁkƒ£žÏ!-ÔÒC£•‡CÚjYÁÇVGácð?ˆ'mùÌQ‘2ùxc+‚)ÍÝd[Y킾î{FfÝŽ;UTKȱf‚ ‘Dˆ¨r>3É=½Í[MѼçÝÏè—kmä‘tì qƒÇh<–xÛ'³o&§¢Ž‚†l&§¾zÕùͱ÷œ»íöû6ÞáØ=çime’–(ÜæÚºÚâ*ÝJæ´µ6n|#]‡yB]¤,ï-wNÚj6mË4MÊí«‰®¬£{ÚÓ8žÒÚH."ä6C¦¤ ©]CÀod´§8”³¯L°¾$¹ø—k! œÜŒÞÕËP·Ì+û•t\X@Ü.n§¤|ë³¥©@Û…8¨žÙÎþZ;+e·rØ|[r¸Ý¹;›&4tÏc+"ŽF ¥ˆC•«¸Ò¤»_ånöYœ~FüØ^æbeéèŠéŽ‘ìt„¥’^êpáZ\2öEâÙêâÚ% &ÑRaž4±°NT³ò=ß‘n÷I ÌåVûä!,Dƒ§Ž ’Ä)ƒ†*š ;aîÖ?°vÑLn£uÝÎJÊ{H- ó”.•¦K¦šh¥Í$t¸T·m—/ºðøËËíÛ»£|b‹xl®b¸–âRÕ» ¸ŽÞ2û—BøØÇÜ6!Ró©Ž{Øßë<}–js{›?sÛnk­Ñi™¹‚Ë#Ÿ·.…ó?L"F½Îl.ÓH£ƒZçu4ôº<ŸY¼3q«jÞ\A`éÌ¥±¥´Â"À²oÈ‹„åB2bQTQm>EЊ¸.7ª;8ž.4]8f‚eQq/lB†;sf³¼Àæ>ÎÉáð9¨v͆JgIuqlø¸¾6LT/Š&†ŠM6†ÈâZÊè%w0xÌVÐÙ{’Ç#–ÆKœ»²¬‚Ù'½Ä !²HêšÇ§1 SP „ÞMmŒ­ìÞáå{'c(ûŸ‡I¬Òâü°îK½Œ5îñ+Òüw3ż°(úmGLž $Ý)©Žbæ2J¹œD¹-¯üÃgÝÉIÜãŵÌ0:Kv›{fÇ'}(£c s]^’€Òq™ì³¼œÄ6ÒöÉ—¸y/ ðI+Y1N^Îê3Åä‚)Ð H–2Zèâg ZÜ^ÙNf¯X9¬U“¸!¶øx¿ï6Z>èFÉVçláGŽ ‡» å#‘ó}AËd2‚C @‡ó¬g.7ŽO”÷‘ÙÙÏçÆï9²¶¶÷ t&àB@hoxâÈǼÆï°÷46 á¹ßoM·cÌ gÜÜÅ& ÷lÇa<°½²ˆL€ÔÜXæ´=¿i­$БCÓÜé”°`1^G¼ï±pH[Ò° "-ؤ•ÏzPtáÞâM슰öQbm›ÿvg9³µ]Ëݱ€ÎZeòRBË©omooced’ºI^Cdw‰F5•tÔYㆰëÛGob¹{ŸÇ9–Å\c¬™+ ŽÖá³Mu#£s#k#h.`ñªç:ŽÒâ’áÆm[²ÒâÓ…ÀÁ²¹ÂÅ™«æ;»(ÙÄÈ·6••[¹i)ø7+Òü_s±œ”8 ‹U"$RAEŽß'“ÅåyWÌÏml/²{;!ˆ‚Êãî‘î-eµ dRºøÏ…Ñ0js>É.$U¬t¬o±ûûcü1=Ý¥Žä³ÈËsÞ$Cû´ñÙ-í¾ù‚{©ç.H!qÖØ[Ž—7²FµÞ+Ô£ÛG¶­p+æ¬Þ5¸|´øØî ºŠl°½²G#zZö¹…ÃÆiŠÕ¦­wW*›u¬ÑjÅÕz!ÕÑae.2—×]÷kbÛ²O%BælWvß’F…±¥®&ñÖÌí­qO‚*§¢ð±Ä35U)’QUM®†L¥SÀyƒÎížec9¯‹±ºÉââÇI½‚ÙåË"/|ÑMUP$yàÖŽâ[ëÛ>÷œÙÜ¿¿º‚Æý÷¬¼µ–wh…ò67Å#ètU àI=~$ñ…ƒÂ„u›–.ì³d_™âÙË6Ñbã IzA^m m…Å1)‘'#ؼo¤#-Ð\ªo,š‚ —µ"\îÜÙÞi\^mlV*öÇcÜ⮡¹¼¾·–ÞGK×—ûªÊêxb¼¸ŠÄDÇ=­|¥’Ê_Ý´çéi€‚iT–eçi5öwåû)ÍÓn6¼äø…´f£mæã¹ä!›@B¢æ]ŒŽK*î1ºÉ‡pšFH†(€˜–_–—ŸøœÌv×ÃÅ€ž7Î#y…²d"7J†¼‚ipqÇdqìåCùá'åâ{b/h•̰¶2u‚.€GJÊî.x{q™pÁ) –°¥¡(Ç„¬-)mdëù¥‡*Ös:ow´<«ak1eÝ8Ar´:®Û®¦DJªb>]ÊýЋrÛ^b³7vÏÝy²k;W\±Ò~e¦h:£–kš^LJðx-rß9ƒ´_¸äÁÏmÆ[ÎÍ¿f×Gs8ÁŸœ"Q¨QñÔ¹§I.ioÑÁ}–ötáÝ)ð-öíµæ,N°)1=™–îÀµ†¾hk ¡~ª›¢×i&_Gjá]ävR¹M@Hr7û'˜å†w5 ­Ì9¼þwï×1\Œ{ŸCj x÷ÎgŒö¶Žs Í/.rZn Í÷ŠÆKq˜¼F+î°ÝÈ+¼ ¨Ÿÿ;ÅkZÁÓG®ÔáªêɸÿˆHû»ŠÓKà v–µµ<0ë…¶ÖÞKá#‰L#XWåÁyc[¶™2ìcgCIÄ¿Ay3¶“z vÊ3F5NÐMNÌÊ%¿ºUÁëœÍ“#·9­·7·÷vFûogy†Î\HÇÈÒV6”/©új[Eç;;,×/ó[[ï–v™Y®m¥gÞel,sà]G;¦¦´„¶´«xG Ø¡€ýšÐãzÚA/bæ{îRøŠŽ$¬Ø·™­ V’7[yéVëQe)¬ì¨¦váÚDœµÔ~9ñß1¯>åw÷Kì=³-ŸÜÉ¢áíÇ9;N™\×ø…±—ïŠð]†å±_ ì»o¼Ûýâ×%;§oxÍP´Þ‡‡JÚÖ6–øÀ¼[Æ´â¹ÆcÁ66OâžïÌíx—áÌ0ãëýÑrÍ'”"qÃÅÇ(ÀeâÛ[)G³2ÎÌÉT£NÈ˵|c¦b*]á)pÛC|f¶×,-6t»spü^ËC fÍýÌxwvó1£ccuL$ |tp-4ä÷ÕÅç7ÝÆä7†øq÷bY÷–÷Œktëhˆq{Î’#,.kêÒǃ2â6ÃÊW¯´s!¹¸a-¦y79ÇŒ.9hØI[¡ÖöÄ X¸÷ë5púnJ&Ìͪ²fWtw„7†&åæwla¹y·ã·šæ\n\Kvèc|Œ„Êó4®{Ú#š$qkHmxt ‹xâ³¹=å˜|ÑAö4ÇnÙÖ>QDQ†µÄ=Ìc]¡µp&œzW G X¥À¾Í¸q½-0—±³5õ){Å ÇVtc¼Ô„«I©¦zM¼ÁÔX ”ÖvTS;pí "NZÌ¿›;瘷sºû¥îÙ–Ïî¤Ñpöã‹È¦’¹¯ñ c.!Þ)à±­ËbþÙvÿy·ûÅ®JwLÞñš¡i¼•µ¬m-ñ}oÊíë ã‰N:øÄILcFÀæO•¬ "örÅ’É;q…š´f·:NU‹ôE’‰qº¡?htÁ2”1J:–w¸­y!´\Üuì—ØŒ­ÕͳaÞ[?xüÉú{jS¨ÐHØ19|4üÔÜm7¶¬µÈãî­á™Ò7¹t’w%¿¶„5Ô š‘AR@]!ÁäCxl镸P».;~^ 7Ø·n*y?iJä¶¼#cœOÚwDDƒr¤Œ©¡ž´p“s @ á}  ÖëÍËÉ/6F+šx»yá¾ÂßA|اa†cÞ"žjYÞ5Í/®–ðêZ¿.­™mºoö üÑIk”´–ÔɻȄÍi’)XáÁÚpoV§q]OÆÞC‡½3Ü䦠}ÄQPøfÂA3&£tmüzÜÑ.‚¨ˆ¹AåÀ/WIR—C¢¡4­¯’ø ¼6Å‚÷*?úöZY2DÔ-ÑÖ* H-‹»ii<×U¯ó;/o“Ý’ÚãÿþÑ–pBvãA¡2k Ž–±,î õbÕçÕJU6ÔªªR©ÕÑS¤§TÀ§@ù¦‰Õ()·ÇJ€§T ¥IjuJU6ëPZR•Mº{•:JuL XTª)TÛãïÒÒT §UIjª¥:ê SªR©·ÇSBR•N­¡R˜)J¦Ý}ÚE¡:¥6éRZR‚•©Õ()·ÇS¥UR‚]êIÕ)Tëè© ER•MºT–ªªPSž¤µ:¥6õ Fš'T€§VФS›u¥@R›t©-N©ANº’ÔêÛ§wŠ µ:¥9ü”¨SªR©·]”¸u§T€¥-=‰Õ(mAjuHêÚ%©Õ (<úÔé¢u^ép>]lx!ç‰ÿÜGݯ˾`~þfÿkÞ~±"ûÿfþèb¿fÚþ‹Ð-ÀÛäþŠÔVȦàmòE_^.ï]Äïþ!sOúȹk÷?”ô§lÃØïÔá_–\ÂýþÎ~ؼýfEUèKOR„)B¡ P…(B”!J¥VR NªÀpðÒÒŽ à<ÃSDø…`6”QíWÒNƒ©\B*B°0éEPUÀãáå©Òš¸e" uWxjhª¸Ÿ’‘jÀÜÃRBªžµp8Ò⎀p¡>)ÜÃJ€¢¡\Î*)«ù‡«üTˆíN©üþJ’ÔÕÀüÃRZRƦˆ¨HŠ<)ñJšT¡0UÀáÏ¥IjuHš’ÔêúT–§T€q©¢*< @è¥áUT §]*U n4‹SªP??’ µ0RüÃRZRœõ4)Õ)TÛÕK‡ZuJ w-=‰Õ )·_v¤µ:¥:ª SªPR§JuHU6éîE/ iANà¥@˜=‰AMºôÔ–§T §UAjª¥:êt§T¥SnžçôT‘ÚR‚ÁJ0R‚›uéïÔ–¢«!¸ƒÏîóôž0’ym7¶ 0Õ•‡ÐI´š²…—mf¸šp”ê§U“!f»ñ™3p ŸfÚòh aű-²Vðܺädr÷ä–wfàF BŽv Þ_²(¶ýÝ»$Ý“XÍ$-ƒîXØm.Ö!/:Í@¡v¿³Æ”é+ ÁNºÞ‹V§T¥Wm*´ê”î šÁJU6ëîÔ–§T ¦Ý;¼U%©Õ()Q¦ ª˜ªíñÒ§juJ uyB•N«)pŸP2Ùœ{jb¦3£¶Ó‘vÎk}vJ¨{*"}ŠQÎÍ b DÆÝ©œ¼—¤‘Dʸ”S17ʧ˜ï>^ßïl”å2’7d1Ѿls``ûÄ‘8½½åήóº.Ò]‚š‡BÝëlï M­e,¶ ;¥Í{c½t¯=Ë$hiÑàƒdÔÕJPq˜W2‡1Îsç0œç9„Ç9Œ:˜Æ1„DÆ0Ž¢=ñ¯HîÃF(Ò5jx’® wN“ÔŠ¥zÈ4¨S›té¥@UU()ܨ)TÛ­Ijª¥*›tîæ¨ÒSª`S¯¢’uJU6øéi Õ()ÕPZR‚u©Õ)TÛãïTUU()ýaý“¯bb©·_v‘hN©J¦Ý* SªPR µ:¥*›z†• uíJ t‡”*hR•N¾ŠE¡0R•Mµ©Õ()RZª©J¦Ýz{õ4!:¥:CʨR‚{B§H= Õ()¶¤µ:¥;‚ µ0R•MºìšQ:¤:CËKÂS}¨ )¶¤µ:¥óÔ¦ B©Ì=CRZR‚ÁKŠuJU6ëÝã¥@RU%©Õ{¿ÀçÿÀÄñŸþAµ~[s÷÷9û^óõ‰èÌýÏÄþ͵ý •¨-•J¿\\ÿÞ»‰ßüBæŸõ‘r×î(ÿéNØÿ‡±ß©Â¿,¹…ûýœý±yúÌ‹«Ð–ž¥R„)B¡ P…(B”!J¥R„)B€ÃÓJ:«€vR¡B¾µ4N¤-@Â" ô«ûƒú)'NÅp0 ©*àna¢‰Ôp?8xªt¦¬ï *U CmMuV‡EN”ü ÜÃSDWµ\4qO‡R¸(OZ@8óøéPÀááä©Òš@0øZ’ª¸ŸÉS¥:¤ó I ×µ ž• +ØúQáOÂ×KObuH};¼U%©Õ |5Sª@>ßðT–§_­ (>TN©MºRð¦”×Jƒ©Hæ¡©-N©üþJ’Ôê”Ì5©Õ )J…:¥6øûµ¥@R‚]‹Sª@S¯¢ µ:¥6éRZª©JšS¡:¥*›ixQT §pTÐê”Û¯»RZR‚U%ªª”¨§buJU6øéSµ:¥:º)Pê”Û¯»RZR‚›tîñT§T€¥Nšt'TÅSoަ©Õ()Ò¨ uJ uôT–§T¥SmAjª¥;‚§IêN©Š¦Ýi'T¥SnžåMN©ANà©-L¥SmAjuJU:ªhUU)Tëò $Wð¦*›z†§H)Õ()ÕRZª©ANº‚ÔꔪmþŠ’ uJ w*&bb©·_ Ô–§T §UIjuJ sÔªªPSo»Zšꔪt‡”)Q:¦:ú*KSªR©¶¤µ:¥?¬* SªPSn½=úšR•MºyB‘:¥<[*KUU)TÛRZR‚]©Õ()Ð>í*R•MºtÔR‚”´ö'T¥SmAjuH wIjuL t»SBªB©·Nžõ/ uJ RÒ:“ªR©·»š µ:¤*KSªPSn½=ÚÔé¢u^õp5ËaÛÃÏ ÿ'µ¯Ë.a~ÿg?l^~³"ýÙŸ¹øŸÙ¶¿ bôµ²©BàK‹Ÿû×q;ÿˆ\Óþ².ZýÏåý)Ûðö;õ8Wå—0¿³Ÿ¶/?Y‘cÕzÓÔ¡ P…(B”!J¥R„)B¡ P…(B”!JµÔB„UX>ZZSVÔУÀ¯­*'R€Â‘PUÀô'CÔ®¡íVw†‘ ðêWó…-)ñWs I¨ª¸zii «Ã¢¤µ?¸jh{RèâW…$ëÚ=4i¯b¸:*t”ê<úÔ–§Up?UIjuìHæ’¯j@Sž—ëØÌ:QÀô¢½©üþJ)¤óPÔ–§T€~%IjuWó IjuíJ sÒ¡N© ~aÓgø©pëN©@üþJZ{ ˜uØ5%©Õ )ÕPZR‚›{½Ú’Ôê¥Å:¥6ëÝÏJH m÷*KUU()×ÑRZФ*›j UU()ÏJ…:¥6øûµ©§juJ utRÓTê”芒Ôê”ÛÝîT§T€¥MèN©Š¦ßv´©ÚR‚!ÑJ•N©AN¾Š‚ÔÁHU6Ô–§T ¥MRuL íצ¦©Õ)TÛ§”)iUR‚ÁRZ˜)J¦Ú‚ÔꔪuTЦ PS¯ÉSDꘪmêZjR‚ÁRZR•MºÔªªR©·Or¤‚R‚ŸÖ4ESM¾>ý"ÕUJ uT§T §]IjuJUvøêhSªPS«¢•ª¦:¤µJU6ÔªªPR§JuJU6ëÓß©¡N©J¦Ñ(R N©Nà©-L¥SmAjuH utT–ª1Tëò M *”ªmñÒ UT ¥IjuJU6ëPZR‚]%©Õ()×¶¦…:¥6øéP'T §=-=‰Õ()·Z‚Ôêêè¨-UT §_»J…J mñ÷iJ‰Õ()ÏS§±0W¾Ü ð »ÿDÿÉÍkò·˜_¿ùÏÛ¿¬È¿Aö_îv'öe¯è½­=lªP…øâçþõÜNÿâ4ÿ¬‹–¿sùGÿJvÇü=ŽýNùeÌ/ßìçí‹ÏÖdXõ^„´õ(B”!J¥R„)B¡ P…(B”!J¥R„)B¡ P…¨‡xh¢uVóÒÒŽ à` M < ÚÒ¢u*ÀqþºÀ«û»ô“ãÔ®¡íW=*ü àpðòRÒš¸˜jHíEUÀãáå©Òš¸9ütˆ)‚z•ÀÃSDTu«èL} Áà\¯j@8ôÒ-MX‹J*=5BuW‡E"ÔÁJzš'^Õp?=.)øù†—U ŸÉHµ:¤ó»¤µ:¤óÔéN©üÃRZRœô¸§^Ä¥So»Z\ª@?õ…-)Õ(nµ©Õ )ÕRZRÇž¦‰Ôx‚T¸õ¦”è%*U )·Nš’ÕUJçòT¦ B©¶¤µ:¥*hSªPSn½4¨ªPSnžå"Ôê”þ°¨-L…SmIjuJ TЧTÀ¦ÝziSµ:¥6éîTéªuH wIj`¥*›j UU()Ü4)‚˜ë¥DU()·Nš5U^Ô §pT–§T¥Snµ©Õ)Tê¥BR‚}4LÅSoŽ‘juH uTªª`S® µ:¥*»|t¨SªPS¸*hªb©·_v‘juJ mÒ µ:¥* SªR©·]ƒJŠª”é(TÐ'TÀ§_EIjuJU6øêKSªR©ÕÑPZ˜)ANò *'T¥SoPÔ¯jPS¸)§T¥Snµ©Õ)TÛ§¹PZª©N¾ŠTN©J¦Þ¡© 'T §U"Ôê”ë¨-N©J¦Ý=Ïè©-N©ANà©LÄ¥So¿J:¥:ªKSªPS® µUWÖÑ%]¹nÕ¹ ¢îVMS/(¨¢§ ßt®ŽFòÛa6Jõá–DéãÐÖ°|.Õ•¥ÅýäV6­/¹šF± t—8Ь•ú#àêXk>1±Š;­XµnSi  [·M ^PܯɌÖEÙŒÍÞ]⺺–b; ¯sÈÿÞ_¢Ø«&ã1–ØÖš¶Þãè¿äYÃXÅßR„/À—?÷®âwÿ¹§ýd\µûŸÊ?úS¶?áìwêp¯Ë.a~ÿg?l^~³"Ǫô%§©B¡ P…(B”!J¥R„)B¡ P…(B”!J¥R„)B¡ P…¨‡†Šê®ç©ÒŽ À`ð *#ˆVÖ•¯j¸—øp8PŽ!\„Tu«„6Ò 'àV‡EN’š¸˜iÚUÀüáS¥ÀÀ>I Ô«Ä)Q:„€zÇ©\ Ì4¸ëÚÏËHµ5p8xJ’T€qðòÔéM\útÔ–§R54N£ëH ñHÛ¯M*Ф‡E-)Õ yõ¨-N©üüžåIjª¤=MT€¥.)¥6ëÓJ:¤õR-N©@ýu%©Õ\Û¥AjuJ MªPSnÞ*<)¥óòûµ4I×± )·¨jKSª@SŸ’¤µ:¥*›u¨-N©ANª\SªPS iP'T ¦Ý:i§T §=Aj`¤*œÃ­AjuJ uR¡N©NºšêÛ§M"ÔëÚ”¨-UT¥Snµ%©Õ)Tê©¡LÀ§]*ꔪmñÔ–§T §UIjuJ uÔ§T¥SnžåI:¥;‚•uìJU6ëîÔ–§T §UIjª¦* SªR«·ÇSDê”êò…*ê˜ëè©-N© ¦ßAjuL wNžÅUJ ôjhŠ¥6éÓJUR‚ÁRZSMµ©Õ!Tê©ÒSª`S¯¢¦‰‚”ªíñÒ N©ANª’ÕUJ uÔ§T¥SnžçôTé)Õ()Ü“±1TÛ¯»S¤'T §UIjuJ uÔ§T…SoާJª§!Œs¥)Œs¥ „Æ0è DDDkŽI#Š7K+ƒbh$’@$’x:ÉàÆÇÈñ@¹î4 ’O@t•˜¼:`雎àa-$ÅRn*C3l¢c¼–ð€zBÅ÷ªGÞ”yKßJøŸæ´ÎBý™´åï1¥Ãï3´ø²i5î£=l¨«Ü8:šEZM~©å,.12·sî(ô_Só¸qeGûGŽ§ÓƒZx·í:”ýâëE;RÞhÐ8"@0né˺óxkåô:ìê¥_ŸÎ"ý’ØâïÉwæEޏr¡¥² åsß-‹1iŒci[²qôô‹xÄ~ÄúRè»~r¢EVYR¦(qÔÃõvÝþp¹™¶vý†Û°±Á>Çg ´n’£#£‚6ÄÂòÛÖ4¼µ€¸µ­Ö€ð,Ïòç²s™{¬ÕÝÖU·W—2ÎðÉmÃå{¤ph6Î! ¸†‚ç)ROŽÿ´%·óÎJúVØü£Yîk{¿oy ÏoXß– ƒé™+mìŠ~ЖßÏ9+é[cò;ÜÖ÷~ÞòžÞ– ƒé™+mìŠ~ЖßÏ9+é[cò;ÜÖ÷~ÞòžÞ– ƒé™+mìŠ~ЖßÏ9+é[cò;ÜÖ÷~ÞòžÞ– ƒé™+mìŠ~ЖßÏ9+é[cò;ÜÖ÷~ÞòžÞ– ƒé™+mìŠ~ЖßÏ9+é[cò;ÜÖ÷~ÞòžÞ– ƒé™+mìŠ~ЖßÏ9+é[cò;ÜÖ÷~ÞòžÞ– ƒé™+mìŠ~ЖßÏ9+é[cò;ÜÖ÷~ÞòžÞ– ƒé™+mìŠ~ЖßÏ9+é[cò;ÜÖ÷~ÞòžÞ– ƒé™+mìŠ~ЖßÏ9+é[cò;ÜÖ÷~ÞòžÞ– ƒé™+mìŠ~ЖßÏ9+é[cò;ÜÖ÷~ÞòžÞ– ƒé™+mìŠ~ЖßÏ9+é[cò;ÜÖ÷~ÞòžÞ– ƒé™+mìŠ~ЖßÏ9+é[cò;ÜÖ÷~ÞòžÞ– ƒé™+mìŠ~ЖßÏ9+é[cò;ÜÖ÷~ÞòžÞ– ƒé™+mìŠ~ЖßÏ9+é[cò;ÜÖ÷~ÞòžÞ– ƒé™+mìŠ~ЖßÏ9+é[cò;ÜÖ÷~ÞòžÞ– ƒé™+mìŠ~ЖßÏ9+é[cò;ÜÖ÷~ÞòžÞ– ƒé™+mìŠ~ЖßÏ9+é[cò;ÜÖ÷~ÞòžÞ– ƒé™+mìŠ~ЖßÏ9+é[cò;ÜÖ÷~ÞòžÞ– ƒé™+mìŠ~ЖßÏ9+é[cò;ÜÖ÷~ÞòžÞ– ƒé™+mìŠ~ЖßÏ9+é[cò;ÜÖ÷~ÞòžÞ– ƒé™+mìŠ~ЖßÏ9+é[cò;ÜÖ÷~ÞòžÞ– ƒé™+mìŠ~ЖßÏ9+é[cò;¼Ö÷~ÞòžÞ– ƒé™+mìŠÁ솷ûç%})l~Q£çwšÞïÛÞBóÛÓù`Ø>™˜ò¶Þȵý¡íÏž2OÒ–Çå*_;œÖ÷~ÞòžÞ—ËÁôÌÇ•¶öE?h{s眓ô¥±ùJÎk{¿oy ÏoOåƒ`ÿy˜ò¶Þȵý¢-ÐþùÉ?J[”©|íó[Ýû{È^{z,;ÒòþVßÙU¿h«{猓ô¥±ùJŸÎç5½ß·¼…ç·¥òÁ°}31åm½•kûEÛßXv¥åü­¿²«~ÑÖÿÏ#éKgò/®jû¿oy ÏnGËÂôÌÇ•¶öU¯íoüï‘þ”¶)ÑóµÍ_wíï!yíÈùbØ^—˜ò¶þʵd„|d¥-ŸÊt¾vy©îý½ä/=¹?–-…éy+oì«_ÚFç|ôµùR—ÎÇ5=ß·ü…ç·%òŰ½//åmý•kûI@ü“¶¿*Qó¯ÍOwíÿ!yíÉü±ì/KËù[eVd¤{äo¤í¯Ê”|ëóSÝûÈ^{r>Xö¥åü­¿²­iX/ò/Òv×åJ>uù©îý¿ä/=¹?–=…éy+oì«PöKÁ‡z_"ý'm~U¥ó¯ÍOwíÿ!yíÈùcØ^——ò¶þÊ­ûLAüí‘>“¶ÿ*Ñó­Í?wíÿ!yíÈùdØ~——ò¶þÊ {&¡½-‘>“¶ÿ*ÒùÕæŸ»öÿ¼öäþY6¥åü­¿²«~ÓpŸ;d?¤­¿ÊÔ¾u9§èÈ]ûr>Y6¥åü­¿²­iØ_²ÒVßåj_:|Òô ¿ä.ý¹,ÛÒòþVßÙUƒÙ? ÞÙé+sòµ:|Óô »öä|²ì?KËù[eZþÔß:ä/¤­ÏÊô|éóKÐ6ÿ»öäþY¶¥åü­¿²«²Š?½rôÉ[Ÿ•é|ésKÐ6ÿ»öä|³l?KËù[eZþÔpÿ:䤭ßÊô|ésKÐ0BïÛ‘òϱ=//åmý•[ö¥ˆù× þñ·+ÒùÐæ `<…ß·#åŸaú^_ÊÛû*×ö§‰ùÓ }#nþX¥ó¡Í@Ày ¿nOåŸbz^_ÊÛû*°{*bƒûÓ }#nþX£ç?š>€ò~Ü–}‰éy+oìªßµTWΗÿÒ6÷åš>sù£è!wíÉü´lOKËù[eVý«bþt¿‡ÿxÛß–i|çsCÐ0BïÛ‘òѱ=//åmý•jÊèÀïIßßHÛß–i|æóCÐ0BïÛ‘òÓ±}//åmý•[ö°ŒùÎýúBßüµKç3š€ò~ÜŸËNÅô¼·•·öU¨{,£CûÎýúBßüµKç/™þ€ò~Ü–­‹éyo+oìªßµ¤wÎWçÒÿåª>rùŸè!wí¨ùjؾ—–ò¶þʬËhðïI_ŸH[ÿ–èùËæyÿö!wí©üµl_KËy[eZþÖñÿ9_H@~[¥ó•Ìÿ@Àù ¿mGË^Åô¼·•·öU`ö]0ï+ìz_À~[¥ó“Ìï@Àù ¿mOå¯bú^[ÊÛû*·ívÄ?¼o¯ãà?.RùÈæw `|…ß¶£å³cz^[ÊÛû*°{/™÷óü|åÊ_8üÎô‘»öÔ|¶loKËy[eVf0ïHß?ÇÀþ]£ç™Þò~ÚŸËnÆô¼·•·öU¯í„Ïç ãøøË´¾q¹›è8#wí¨ùmØÞ—–ò¶þʬÌFýá|u¿‚ü»GÎ/3}änýµ?–Ýéyo+oìªß¶3_œ/ã ¿/RùÄæg à¼ß¶£å»cú^[ÊÛû*°{2÷…ïütåê_8|Ìô‘»öÔ|·lKËy[eVfSpïH^ßÇAþ_£ç™žƒ‚ò7^ÚŸË~Çô¬·•·öUoÛ1¿ú}ëütåú_8\Ìô‘ºöÔ|·ìKËy[eVfrþzõ½ƒü¿Kç™~ƒ‚ò7^ڟˆÇô¬¯•·öU¯í úuéül'Ô¾p9—è8/#uí¨ùpÙ—•ò¶þʬÍ$ƒüúóþ6ê _7üÊô‘ºöÔ|¸ìJÊù[fVf¢aÞ}yÿ õ 7üÊô‘ºöÔþ\vG¥e|­¿³+~ÚÉÿ¦Þ_ÆÂýCKæû™^ƒƒò7^Ú—‘éY_+oìÊÁìÙ žÞ?ÆBýEKæ÷™>ƒƒò7^ÚŸË–Èô¬¯•·öe`öm”?Ïoã!~¢¥óyÌŸAÁù¯lGËžÈô¬¯•·öeoÛt?Ó/ã!¾¢¥ówÌŸAÁù¯lOåÏdúVWÊÛû2°{7ôÿ<¼:ÞC}GGÍß2}än½±.{'Ò²¾VßÙ•¿nóË¿øÈ¨èùºæG àü×¶#åÓdúVWÊÛû2·íÈoôË»ø¸©*~ny‘è8?#uí‰üºlŸJÊùX=™jÎSùåÝü\?Ô”|ÜsÐp~FëÛòë²}++å öeoÛ ÿéwoñqRÒù·æ?¡a<×¶'òí²}++å öepöu(çw`ô»ˆú–›~cúÈÝ{b>]¶O¥e|¤̵gb¡Þwvõ-/›ncúÈÝ{b.Û+Ò²žRfVý»–ÿJºÿЉúš—ͯ1½ än½±.û+Ò²žRfVgŠáþuuõ5/›>czÈÝ{b>]öW¥e<¤̬Ï5üêêþ*'êz_6|Æô,'‘ºöÄþ^6W¥e<¤Ì­ûz¸ÿIºŠŠúž›>czÈÝ{b>^6W¥e<¤̬Ïw!þstõE/›búÈÝ{b/;/Ò²žRfVý¾]¤]ÄÅ}QKæÃ˜¾……ò7^Ø——éYO)³+~ßnÿÒ.âbþ¨¥ó_ÌOBÂùŸlGËÖËô¬§”ƒÙ•ƒÙúð;Î.âbþ©¥ó_ÌOBÂùŸlOåëeúVSÊAìÊßõyÿŸ¹¿‰ŒúªšîbzÈÜûb>^ö_¥e<¤̬=÷û—ø˜Ïª©|Öóа¾FçÛù{Ùž•”ò{2°pø?ßîOâ#>ª¥óYÌ?BÂùŸkGËæÌô¬§”ƒÙ•¿ê ÿÿ=rõ]/š¾aúÈÜûZ/›3Ò²žRfV$ýþãëqõ]5|Ãô<7‘¹ö´|¾lÏIÉùH=™[þ¡R!ÞZãþ"7êÊ>j¹…èX_#síhù}Ùž•”ò{2dx ß.ò—Ã^Rv;¢ÃÙÇÚu…qKüÓsF6×Çë6Š«§ äùÙlxs§É8£,4>0ø]÷øB9Ê ž0©¨Q.ó‡w<ÂUŠ[Þ&è5yVëæ†ùÞŒ0g²¾Èš÷, Š/¢¬Œ4>FMdv¯AÛÛ iíw qq²è w®¬’}4{Ë‹kÖ¤} Ѽk†!,–艧۔¥ÔÛ…×PþºsÖ€·Þ…)HP)C@Є+P…(Bø|]¯ü'Ñ÷¿ûÍ5¡ æùÔüÚ§Èž§æÐ…>Dõ?6„)ò'©ù´!O‘=OÍ¡ |‰ê~mSäOSóhBŸ"zŸ›BùÔüÚ§Èž§æÐ…>Dõ?6„)ò'©ù´!O‘=OÍ¡ |‰ê~mSäOSóhBŸ"zŸ›BùÔüÚ§Èž§æÐ…>Dõ?6„)ò'©ù´!O‘=OÍ¡ |‰ê~mSäOSóhBŸ"zŸ›BùÔüÚ§Èž§æÐ…>Dõ?6„)ò'©ù´!O‘=OÍ¡ |‰ê~mSäOSóhBŸ"zŸ›BùÔüÚ§Èž§æÐ…>Dõ?6„)ò'©ù´!O‘=OÍ¡ |‰ê~mSäOSóhBŸ"zŸ›BùÔüÚ§Èž§æÐ…>Dõ?6„)ò'©ù´!O‘=OÍ¡ |‰ê~mSäOSóhBŸ"zŸ›BùÔüÚ§Èž§æÐ…>Dõ?6„)ò'©ù´!O‘=OÍ¡ |‰ê~mSäOSóhBŸ"zŸ›BùÔüÚ§Èž§æÐ…>Dõ?6„)ò'©ù´!O‘=OÍ¡ |‰ê~mSäOSóhBŸ"zŸ›BùÔüÚ§Èž§æÐ…>Dõ?6„)ò'©ù´!O‘=OÍ¡ |‰ê~mSäOSóhBŸ"zŸ›BùÔüÚ§Èž§æÐ…>Dõ?6„)ò'©ù´!O‘=OÍ¡ |‰ê~mSäOSóhBŸ"zŸ›BùÔüÚ§Èž§æÐ…>Dõ?6„)ò'©ù´!O‘=OÍ¡ |‰ê~mSäOSóhBŸ"zŸ›BùÔüÚ§Èž§æÐ…>Dõ?6„)ò'©ù´!O‘=OÍ¡ |‰ê~mSäOSóhBŸ"zŸ›BùÔüÚ¾ô=Oì; ?û¿à¡ é¡ P…(B”!ÿÙopenchange-2.0/apidocs/html/libmapi/idset_8c.html000066400000000000000000000365141223057412600220700ustar00rootroot00000000000000 MAPIClientLibraries 2.0 API Documentation
idset.c File Reference

Parsing of GLOBSET structures. More...

#include "libmapi/libmapi.h"
#include "libmapi/libmapi_private.h"

Functions

_PUBLIC_ uint64_t exchange_globcnt (uint64_t globcnt)
_PUBLIC_ struct globset_range * GLOBSET_parse (TALLOC_CTX *mem_ctx, DATA_BLOB buffer, uint32_t *countP, uint32_t *byte_countP)
_PUBLIC_ void IDSET_dump (const struct idset *idset, const char *label)
_PUBLIC_ bool IDSET_includes_eid (const struct idset *idset, uint64_t eid)
_PUBLIC_ bool IDSET_includes_guid_glob (const struct idset *idset, struct GUID *replica_guid, uint64_t id)
_PUBLIC_ struct idset * IDSET_merge_idsets (TALLOC_CTX *mem_ctx, const struct idset *left, const struct idset *right)
_PUBLIC_ struct idset * IDSET_parse (TALLOC_CTX *mem_ctx, DATA_BLOB buffer, bool idbased)
_PUBLIC_ struct Binary_r * IDSET_serialize (TALLOC_CTX *mem_ctx, const struct idset *idset)
_PUBLIC_ void ndr_push_idset (struct ndr_push *ndr, struct idset *idset)

Detailed Description

Parsing of GLOBSET structures.

Function Documentation

_PUBLIC_ uint64_t exchange_globcnt ( uint64_t  globcnt)

Inverts the bytes of a globcnt, such as for the ids returned by Exchange

Referenced by IDSET_dump(), IDSET_includes_eid(), and IDSET_includes_guid_glob().

_PUBLIC_ struct globset_range* GLOBSET_parse ( TALLOC_CTX *  mem_ctx,
DATA_BLOB  buffer,
uint32_t *  countP,
uint32_t *  byte_countP 
)
read

deserialize a GLOBSET following the format described in [OXCFXICS - 2.2.2.5]

Referenced by IDSET_parse().

_PUBLIC_ void IDSET_dump ( const struct idset *  idset,
const char *  label 
)

dump an idset structure

References exchange_globcnt().

Referenced by IDSET_parse().

_PUBLIC_ bool IDSET_includes_eid ( const struct idset *  idset,
uint64_t  eid 
)

tests the presence of a specific id in the ranges of a ReplID-based idset structure

References exchange_globcnt().

_PUBLIC_ bool IDSET_includes_guid_glob ( const struct idset *  idset,
struct GUID *  replica_guid,
uint64_t  id 
)

tests the presence of a specific id in the ranges of a ReplGUID-based idset structure

References exchange_globcnt().

_PUBLIC_ struct idset* IDSET_merge_idsets ( TALLOC_CTX *  mem_ctx,
const struct idset *  left,
const struct idset *  right 
)
read

merge two idsets structures into a third one

_PUBLIC_ struct idset* IDSET_parse ( TALLOC_CTX *  mem_ctx,
DATA_BLOB  buffer,
bool  idbased 
)
read

deserialize an IDSET following the format described in [OXCFXICS - 2.2.2.4]

References GLOBSET_parse(), and IDSET_dump().

_PUBLIC_ struct Binary_r* IDSET_serialize ( TALLOC_CTX *  mem_ctx,
const struct idset *  idset 
)
read

serialize an idset structure in a struct SBinary_r

Referenced by ndr_push_idset().

_PUBLIC_ void ndr_push_idset ( struct ndr_push *  ndr,
struct idset *  idset 
)

push an idset on an ndr stream

References IDSET_serialize().


Creative Commons License
Creative Commons Attribution icon Creative Commons Share Alike icon
This content is licensed under the Creative Commons
Attribution ShareAlike License v. 3.0:
http://creativecommons.org/licenses/by-sa/3.0/

openchange-2.0/apidocs/html/libmapi/index.html000066400000000000000000000131751223057412600214730ustar00rootroot00000000000000 MAPIClientLibraries 2.0 API Documentation
Opening Exchange to a wider world

OpenChange Project Goals

The OpenChange Project aims to provide a portable Open Source implementation of Microsoft Exchange Server and Exchange protocols. Exchange is a groupware server designed to work with Microsoft Outlook, and providing features such as a messaging server, shared calendars, contact databases, public folders, notes and tasks.

The OpenChange project has three goals:

  • To provide a library for interoperability with Exchange protocols, and to assist implementors to use this to create groupware that interoperates with both Exchange and other OpenChange-based software.
  • To provide an alternative to Microsoft Exchange Server which uses native Exchange protocols and provides exactly equivalent functionality when viewed from Microsoft Outlook clients.
  • To develop a body of knowledge about the most popular groupware protocols in use commercially today in order to promote development of a documented and unencumbered standard, with all the benefits that standards bring.

MAPI Overview

MAPI is the glue between Exchange and Outlook, but a common misconception is to consider it as a network protocol. MAPI, an acronym for Messaging Application Programming Interface, refers to a proprietary set of function call interfaces developed by Microsoft before Microsoft Exchange existed. By purchasing licenses to Microsoft's proprietary and Windows-only MAPI libraries, anyone can create message services that communicate using these functions. A mail server implemented in this way is what Microsoft calls a MAPI Service Provider. Any protocol could be used as a transport for these MAPI communications.

When Microsoft Exchange 5.5 was developed in 1997, the decision was taken to create a proprietary transport protocol for MAPI which closely matches the MAPI calling interface. This protocol is called ExchangeRPC and used in Outlook-Exchange communications. ExchangeRPC is the only transport OpenChange supports, and in practice is the only transport of interest today. Most of the world is being forced to use Microsoft Exchange servers, so that defines the transport that matters.

When OpenChange team members first looked at the network network traffic these generated by calling MAPI functions on Windows operating systems, we noticed blobs of data first either compressed or obfuscated, then encapsulated by an RPC transport protocol function (EMSMDB) and finally pushed on the wire. Transporting memory-image blobs on the wire is not good protocol design, however for a number of reasons the result now works quite reliably.

Looking at a MAPI Conversation

A high-level view of a MAPI conversation follows. We also introduce important terminology:

  • MAPI applications call MAPI providers, using the API to pass data (eg a mail message body) or MAPI conversation requests and responses (eg 'search for this address').
  • MAPI providers pack the client or server MAPI information in a blob. There are only two really important providers, one for data destined for what is somewhat strangely termed the Message Store (although it handles more than just messages), and the other for data to be sent to the Address Book. These are called the EMSMDB and EMSABP providers, respectively.
  • ExchangeRPC protocol is used to transport the MAPI information over the wire, encapsulating inside it one of two MAPI-specific protocols: the EMSMDB Message Store Protocol, or the NSPI Addressbook Protocol.
  • The store provider on the server side associated with the protocol used (either EMSMDB or EMSABP) extracts the MAPI blob from RPC protocol functions, analyzes its content and performs operations embedded within it.

Creative Commons License
Creative Commons Attribution icon Creative Commons Share Alike icon
This content is licensed under the Creative Commons
Attribution ShareAlike License v. 3.0:
http://creativecommons.org/licenses/by-sa/3.0/

openchange-2.0/apidocs/html/libmapi/lzfu_8c.html000066400000000000000000000127731223057412600217410ustar00rootroot00000000000000 MAPIClientLibraries 2.0 API Documentation
lzfu.c File Reference

Compressed RTF related functions. More...

#include "libmapi/libmapi.h"
#include "libmapi/libmapi_private.h"
#include <ctype.h>

Functions

_PUBLIC_ enum MAPISTATUS WrapCompressedRTFStream (mapi_object_t *obj_stream, DATA_BLOB *rtf)

Detailed Description

Compressed RTF related functions.

Function Documentation

_PUBLIC_ enum MAPISTATUS WrapCompressedRTFStream ( mapi_object_t *  obj_stream,
DATA_BLOB *  rtf 
)

creates a DATA_BLOB in uncompressed Rich Text Format (RTF) from the compressed format used in the PR_RTF_COMPRESSED property opened in the stream.

Parameters
obj_streamstream object with RTF stream content
rtfthe output blob with uncompressed content
Returns
MAPI_E_SUCCESS on success, otherwise MAPI error. Possible MAPI error codes are:
  • MAPI_E_NOT_INITIALIZED: MAPI subsystem has not been initialized
  • MAPI_E_INVALID_PARAMETER: obj_stream is not a valid pointer
  • MAPI_E_CORRUPT_DATA: a problem was encountered while decompressing the RTF compressed data
  • MAPI_E_CALL_FAILED: A network problem was encountered during the transaction
Note
Developers may also call GetLastError() to retrieve the last MAPI error code.
rtf->data needs to be freed with MAPIFreeBuffer
See Also
OpenStream

References GetLastError(), mapi_object_get_session(), and ReadStream().


Creative Commons License
Creative Commons Attribution icon Creative Commons Share Alike icon
This content is licensed under the Creative Commons
Attribution ShareAlike License v. 3.0:
http://creativecommons.org/licenses/by-sa/3.0/

openchange-2.0/apidocs/html/libmapi/mapi__id__array_8c.html000066400000000000000000000437211223057412600240540ustar00rootroot00000000000000 MAPIClientLibraries 2.0 API Documentation
mapi_id_array.c File Reference

mapi_id_array support functions More...

#include "libmapi/libmapi.h"
#include "libmapi/libmapi_private.h"

Functions

_PUBLIC_ enum MAPISTATUS mapi_id_array_add_id (mapi_id_array_t *id, mapi_id_t fid)
_PUBLIC_ enum MAPISTATUS mapi_id_array_add_obj (mapi_id_array_t *id, mapi_object_t *obj)
_PUBLIC_ enum MAPISTATUS mapi_id_array_del_id (mapi_id_array_t *id, mapi_id_t fid)
_PUBLIC_ enum MAPISTATUS mapi_id_array_del_obj (mapi_id_array_t *id, mapi_object_t *obj)
_PUBLIC_ enum MAPISTATUS mapi_id_array_get (TALLOC_CTX *mem_ctx, mapi_id_array_t *id, mapi_id_t **ContainerList)
_PUBLIC_ enum MAPISTATUS mapi_id_array_init (TALLOC_CTX *mem_ctx, mapi_id_array_t *id)
_PUBLIC_ enum MAPISTATUS mapi_id_array_release (mapi_id_array_t *id)

Detailed Description

mapi_id_array support functions

Function Documentation

_PUBLIC_ enum MAPISTATUS mapi_id_array_add_id ( mapi_id_array_t *  id,
mapi_id_t  fid 
)

Add a container ID to the list given its container ID

Parameters
idpointer to a mapi_id_array structure
fidthe container ID
Returns
MAPI_E_SUCCESS on success, otherwise MAPI error.
Note
Developers may also call GetLastError() to retrieve the last MAPI error code. Possible MAPI error codes are:
  • MAPI_E_NOT_INITIALIZED: MAPI subsystem has not been initialized
  • MAPI_E_INVALID_PARAMETER: The mapi_id_array_t is uninitialized
  • MAPI_E_CALL_FAILED: A network problem was encountered during the transaction
See Also
mapi_id_array_add_obj
_PUBLIC_ enum MAPISTATUS mapi_id_array_add_obj ( mapi_id_array_t *  id,
mapi_object_t *  obj 
)

Add a container ID to the list given its mapi_object_t

Parameters
idpointer to a mapi_id_array structure
objpointer on the mapi object we retrieve the container ID from
Returns
MAPI_E_SUCCESS on success, otherwise MAPI error.
Note
Developers may also call GetLastError() to retrieve the last MAPI error code. Possible MAPI error codes are:
  • MAPI_E_NOT_INITIALIZED: MAPI subsystem has not been initialized
  • MAPI_E_INVALID_PARAMETER: The mapi_id_array_t is uninitialized
  • MAPI_E_CALL_FAILED: A network problem was encountered during the transaction
See Also
mapi_id_array_add_id

References mapi_object_get_id().

_PUBLIC_ enum MAPISTATUS mapi_id_array_del_id ( mapi_id_array_t *  id,
mapi_id_t  fid 
)

Delete a container ID from the list given its container ID

Parameters
idpointer to a mapi_id_array structure
fidthe container ID
Returns
MAPI_E_SUCCESS on success, otherwise MAPI error.
Note
Developers may also call GetLastError() to retrieve the last MAPI error code. Possible MAPI error codes are:
  • MAPI_E_NOT_INITIALIZED: MAPI subsystem has not been initialized
  • MAPI_E_INVALID_PARAMETER: The mapi_id_array_t is uninitialized
  • MAPI_E_CALL_FAILED: A network problem was encountered during the transaction
See Also
mapi_id_array_add_id
_PUBLIC_ enum MAPISTATUS mapi_id_array_del_obj ( mapi_id_array_t *  id,
mapi_object_t *  obj 
)

Delete a container ID from the list given its mapi_object_t

Parameters
idpointer to a mapi_id_array structure
objpointer on the mapi object we retrieve the container ID from
Returns
MAPI_E_SUCCESS on success, otherwise MAPI error.
Note
Developers may also call GetLastError() to retrieve the last MAPI error code. Possible MAPI error codes are:
  • MAPI_E_NOT_INITIALIZED: MAPI subsystem has not been initialized
  • MAPI_E_INVALID_PARAMETER: The mapi_id_array_t is uninitialized
  • MAPI_E_CALL_FAILED: A network problem was encountered during the transaction
See Also
mapi_id_array_add_id

References mapi_object_get_id().

_PUBLIC_ enum MAPISTATUS mapi_id_array_get ( TALLOC_CTX *  mem_ctx,
mapi_id_array_t *  id,
mapi_id_t **  ContainerList 
)

Retrieve the ContainerList and store it within a uint64_t array.

Parameters
mem_ctxallocated talloc pointer
idpointer to a mapi_id_array structure
ContainerListpointer on a pointer of uint64_t values
Returns
MAPI_E_SUCCESS on success, otherwise MAPI error.
Note
Developers may also call GetLastError() to retrieve the last MAPI error code. Possible MAPI error codes are:
  • MAPI_E_NOT_INITIALIZED: MAPI subsystem has not been initialized
  • MAPI_E_INVALID_PARAMETER: The mapi_id_array_t is uninitialized
  • MAPI_E_CALL_FAILED: A network problem was encountered during the transaction
See Also
GetSearchCriteria

Referenced by FXCopyMessages(), MoveCopyMessages(), and SetSearchCriteria().

_PUBLIC_ enum MAPISTATUS mapi_id_array_init ( TALLOC_CTX *  mem_ctx,
mapi_id_array_t *  id 
)

Initialize a mapi_id_array structure

Parameters
mem_ctxpointer to the talloc context
idpointer to a mapi_id_array structure
Returns
MAPI_E_SUCCESS on success, otherwise MAPI error.
Note
Developers may also call GetLastError() to retrieve the last MAPI error code. Possible MAPI error codes are:
  • MAPI_E_NOT_INITIALIZED: MAPI subsystem has not been initialized
  • MAPI_E_INVALID_PARAMETER: The mapi_id_array_t is uninitialized
  • MAPI_E_CALL_FAILED: A network problem was encountered during the transaction
See Also
mapi_id_array_release
_PUBLIC_ enum MAPISTATUS mapi_id_array_release ( mapi_id_array_t *  id)

Uninitialize a mapi_id_array structure

Parameters
idpointer to a mapi_id_array structure
Returns
MAPI_E_SUCCESS on success, otherwise MAPI error.
Note
Developers may also call GetLastError() to retrieve the last MAPI error code. Possible MAPI error codes are:
  • MAPI_E_NOT_INITIALIZED: MAPI subsystem has not been initialized
  • MAPI_E_INVALID_PARAMETER: The mapi_id_array_t is uninitialized
  • MAPI_E_CALL_FAILED: A network problem was encountered during the transaction
See Also
mapi_id_array_init

Creative Commons License
Creative Commons Attribution icon Creative Commons Share Alike icon
This content is licensed under the Creative Commons
Attribution ShareAlike License v. 3.0:
http://creativecommons.org/licenses/by-sa/3.0/

openchange-2.0/apidocs/html/libmapi/mapi__nameid_8c.html000066400000000000000000001517201223057412600233570ustar00rootroot00000000000000 MAPIClientLibraries 2.0 API Documentation
mapi_nameid.c File Reference

mapi_nameid convenience API More...

#include "libmapi/libmapi.h"
#include "libmapi/libmapi_private.h"

Functions

_PUBLIC_ enum MAPISTATUS mapi_nameid_canonical_add (struct mapi_nameid *mapi_nameid, uint32_t proptag)
_PUBLIC_ enum MAPISTATUS mapi_nameid_custom_lid_add (struct mapi_nameid *mapi_nameid, uint16_t lid, uint16_t propType, const char *OLEGUID)
_PUBLIC_ enum MAPISTATUS mapi_nameid_custom_string_add (struct mapi_nameid *mapi_nameid, const char *Name, uint16_t propType, const char *OLEGUID)
_PUBLIC_ enum MAPISTATUS mapi_nameid_GetIDsFromNames (struct mapi_nameid *mapi_nameid, mapi_object_t *obj, struct SPropTagArray *SPropTagArray)
_PUBLIC_ enum MAPISTATUS mapi_nameid_lid_add (struct mapi_nameid *mapi_nameid, uint16_t lid, const char *OLEGUID)
_PUBLIC_ enum MAPISTATUS mapi_nameid_lid_lookup (uint16_t lid, const char *OLEGUID, uint16_t *propType)
_PUBLIC_ enum MAPISTATUS mapi_nameid_lid_lookup_canonical (uint16_t lid, const char *OLEGUID, uint32_t *propTag)
_PUBLIC_ enum MAPISTATUS mapi_nameid_lookup_SPropTagArray (struct mapi_nameid *nameid, struct SPropTagArray *SPropTagArray)
_PUBLIC_ enum MAPISTATUS mapi_nameid_lookup_SPropValue (struct mapi_nameid *mapi_nameid, struct SPropValue *lpProps, unsigned long PropCount)
_PUBLIC_ enum MAPISTATUS mapi_nameid_map_SPropTagArray (struct mapi_nameid *mapi_nameid, struct SPropTagArray *SPropTagArray, struct SPropTagArray *SPropTagArray2)
_PUBLIC_ enum MAPISTATUS mapi_nameid_map_SPropValue (struct mapi_nameid *mapi_nameid, struct SPropValue *lpProps, uint32_t PropCount, struct SPropTagArray *SPropTagArray)
_PUBLIC_ struct mapi_nameid * mapi_nameid_new (TALLOC_CTX *mem_ctx)
_PUBLIC_ enum MAPISTATUS mapi_nameid_OOM_add (struct mapi_nameid *mapi_nameid, const char *OOM, const char *OLEGUID)
_PUBLIC_ enum MAPISTATUS mapi_nameid_OOM_lookup (const char *OOM, const char *OLEGUID, uint16_t *propType)
_PUBLIC_ enum MAPISTATUS mapi_nameid_property_lookup (uint32_t proptag)
_PUBLIC_ enum MAPISTATUS mapi_nameid_SPropTagArray (struct mapi_nameid *mapi_nameid, struct SPropTagArray *SPropTagArray)
_PUBLIC_ enum MAPISTATUS mapi_nameid_string_add (struct mapi_nameid *mapi_nameid, const char *Name, const char *OLEGUID)
_PUBLIC_ enum MAPISTATUS mapi_nameid_string_lookup (const char *Name, const char *OLEGUID, uint16_t *propType)
_PUBLIC_ enum MAPISTATUS mapi_nameid_string_lookup_canonical (const char *Name, const char *OLEGUID, uint32_t *propTag)
_PUBLIC_ enum MAPISTATUS mapi_nameid_unmap_SPropTagArray (struct mapi_nameid *mapi_nameid, struct SPropTagArray *SPropTagArray)
_PUBLIC_ enum MAPISTATUS mapi_nameid_unmap_SPropValue (struct mapi_nameid *mapi_nameid, struct SPropValue *lpProps, uint32_t PropCount)

Detailed Description

mapi_nameid convenience API

Function Documentation

_PUBLIC_ enum MAPISTATUS mapi_nameid_canonical_add ( struct mapi_nameid *  mapi_nameid,
uint32_t  proptag 
)

Add a mapi_nameid entry given its canonical property tag

Parameters
mapi_nameidthe structure where results are stored
proptagthe canonical property tag we are searching
Returns
MAPI_E_SUCCESS on success, otherwise MAPI error.
Note
Developers may also call GetLastError() to retrieve the last MAPI error code. Possible MAPI error codes are:
  • MAPI_E_NOT_INITIALIZE: MAPI subsystem has not been initialized
  • MAPI_E_INVALID_PARAMETER: one of the parameters was not set properly
  • MAPI_E_NOT_FOUND: the entry intended to be added was not found
See Also
mapi_nameid_new

References get_utf8_utf16_conv_length().

Referenced by mapi_nameid_lookup_SPropTagArray(), and mapi_nameid_lookup_SPropValue().

_PUBLIC_ enum MAPISTATUS mapi_nameid_custom_lid_add ( struct mapi_nameid *  mapi_nameid,
uint16_t  lid,
uint16_t  propType,
const char *  OLEGUID 
)

Register and add a custom MNID_ID named property given its lid, proptype and OLEGUID.

Parameters
mapi_nameidthe structure where results are stored
lidthe light ID of the name property (used by MNID_ID named props only)
propTypethe named property type
OLEGUIDthe property set this entry belongs to
Returns
MAPI_E_SUCCESS on success, otherwise MAPI error.
Note
Developers may also call GetLastError() to retrieve the last MAPI error code. Possible MAPI error codes are:
  • MAPI_E_NOT_INITIALIZED: MAPI subsystem has not been initialized
  • MAPI_E_INVALID_PARAMETER: one of the parameter was no set properly
See Also
mapi_nameid_new, mapi_nameid_lid_add
_PUBLIC_ enum MAPISTATUS mapi_nameid_custom_string_add ( struct mapi_nameid *  mapi_nameid,
const char *  Name,
uint16_t  propType,
const char *  OLEGUID 
)

Register and add a custom MNID_STRING named property given its string, proptype and OLEGUID.

Parameters
mapi_nameidthe structure where results are stored
Namethe property name (used by MNID_STRING named props only)
propTypethe named property type
OLEGUIDthe property set this entry belongs to
Returns
MAPI_E_SUCCESS on success, otherwise MAPI error.
Note
Developers may also call GetLastError() to retrieve the last MAPI error code. Possible MAPI error codes are:
  • MAPI_E_NOT_INITIALIZED: MAPI subsystem has not been initialized
  • MAPI_E_INVALID_PARAMETER: one of the parameter was not set properly.
See Also
mapi_nameid_new, mapi_nameid_string_add

References get_utf8_utf16_conv_length().

_PUBLIC_ enum MAPISTATUS mapi_nameid_GetIDsFromNames ( struct mapi_nameid *  mapi_nameid,
mapi_object_t *  obj,
struct SPropTagArray *  SPropTagArray 
)

Lookup named properties (MNID_STRING) and return their mapped proptags

This convenient function calls GetIDsFromNames() and returns property tags with their real property type.

Returns
MAPI_E_SUCCESS on success, otherwise MAPI error.
Note
Developers may also call GetLastError() to retrieve the last MAPI error code. Possible MAPI error codes are:
  • MAPI_E_INVALID_PARAMETER: one of the parameters was not set properly
See Also
GetIDsFromNames, mapi_nameid_SPropTagArray

References GetIDsFromNames(), and GetLastError().

_PUBLIC_ enum MAPISTATUS mapi_nameid_lid_add ( struct mapi_nameid *  mapi_nameid,
uint16_t  lid,
const char *  OLEGUID 
)

Add a mapi_nameid entry given its lid and OLEGUID (MNID_ID)

Parameters
mapi_nameidthe structure where results are stored
lidthe light ID of the name property (used by MNID_ID named props only)
OLEGUIDthe property set this entry belongs to
Returns
MAPI_E_SUCCESS on success, otherwise MAPI error.
Note
Developers may also call GetLastError() to retrieve the last MAPI error code. Possible MAPI error codes are:
  • MAPI_E_NOT_INITIALIZED: MAPI subsystem has not been initialized
  • MAPI_E_INVALID_PARAMETER: one of the parameters was not set properly
  • MAPI_E_NOT_FOUND: the entry intended to be added was not found
See Also
mapi_nameid_new

References get_utf8_utf16_conv_length().

_PUBLIC_ enum MAPISTATUS mapi_nameid_lid_lookup ( uint16_t  lid,
const char *  OLEGUID,
uint16_t *  propType 
)

Search for a given lid,OLEGUID couple and return the associated propType.

Parameters
lidthe named property light ID
OLEGUIDthe named property GUID for this entry
propTypepointer on returned named property type
Returns
MAPI_E_SUCCESS on success, otherwise MAPI_E_NOT_FOUND.
Note
Developers may also call GetLastError() to retrieve the last MAPI error code. Possible MAPI error codes are:
  • MAPI_E_INVALID_PARAMETER: one of the parameter was not set properly.
  • MAPI_E_NOT_FOUND: no named property found
_PUBLIC_ enum MAPISTATUS mapi_nameid_lid_lookup_canonical ( uint16_t  lid,
const char *  OLEGUID,
uint32_t *  propTag 
)

Search for a given lid,OLEGUID couple and return the associated canonical propTag.

Parameters
lidthe named property light ID
OLEGUIDthe named property GUID for this entry
propTagpointer on returned named canonical property tag
Returns
MAPI_E_SUCCESS on success, otherwise MAPI_E_NOT_FOUND.
Note
Developers may also call GetLastError() to retrieve the last MAPI error code. Possible MAPI error codes are:
  • MAPI_E_INVALID_PARAMETER: one of the parameter was not set properly.
  • MAPI_E_NOT_FOUND: no named property found
_PUBLIC_ enum MAPISTATUS mapi_nameid_lookup_SPropTagArray ( struct mapi_nameid *  nameid,
struct SPropTagArray *  SPropTagArray 
)

Loop over SPropTagArray and look for canonical named property tags we can add to the nameid structure.

Parameters
nameidthe structure where results are stored
SPropTagArraythe array of property tags where to look for canonical named property tags.
Returns
MAPI_E_SUCCESS on success, otherwise MAPI error.
Note
Developers may also call GetLastError() to retrieve the last MAPI error code. Possible MAPI error codes are:
  • MAPI_E_INVALID_PARAMETER: one of the parameters was not set properly
  • MAPI_E_NOT_FOUND: no named property found
See Also
GetIDsFromNames

References mapi_nameid_canonical_add(), and mapi_nameid_property_lookup().

Referenced by GetProps().

_PUBLIC_ enum MAPISTATUS mapi_nameid_lookup_SPropValue ( struct mapi_nameid *  mapi_nameid,
struct SPropValue *  lpProps,
unsigned long  PropCount 
)

Loop over lpProps and look for canonical named property tags we can add to the nameid structure.

Parameters
mapi_nameidthe structure where results are stored
lpPropspointer on a SPropValue structure with the property tags where to look for canonical named property tags
PropCountcount of lpProps elemense
Returns
MAPI_E_SUCCESS on success, otherwise MAPI error.
Note
Developers may also call GetLastError() to retrieve the last MAPI error code. Possible MAPI error codes are:
  • MAPI_E_INVALID_PARAMETER: one of the parameters was not set properly
  • MAPI_E_NOT_FOUND: no named property found
See Also
GetIDsFromNames

References mapi_nameid_canonical_add().

Referenced by SetPropertiesNoReplicate(), and SetProps().

_PUBLIC_ enum MAPISTATUS mapi_nameid_map_SPropTagArray ( struct mapi_nameid *  mapi_nameid,
struct SPropTagArray *  SPropTagArray,
struct SPropTagArray *  SPropTagArray2 
)

Replace named property tags in SPropTagArray with the property ID Exchange expects and stored in SPropTagArray2.

Parameters
mapi_nameidthe structure where results are stored
SPropTagArraythe array of property tags with original property tags
SPropTagArray2the array of named property tags resolved with GetIDsFromNames
Returns
MAPI_E_SUCCESS on success, otherwise MAPI error.
Note
Developers may also call GetLastError() to retrieve the last MAPI error code. Possible MAPI error codes are:
  • MAPI_E_INVALID_PARAMETER: one of the parameters was not set properly
See Also
GetIDsFromNames

Referenced by GetProps().

_PUBLIC_ enum MAPISTATUS mapi_nameid_map_SPropValue ( struct mapi_nameid *  mapi_nameid,
struct SPropValue *  lpProps,
uint32_t  PropCount,
struct SPropTagArray *  SPropTagArray 
)

Replace named property tags in the SPropValue array with the property ID Exchange expects and stored in SPropTagArray.

Parameters
mapi_nameidthe structure where results are stored
lpPropspointer on a SPropValue structure with property tags and values
PropCountcount of lpProps elements
SPropTagArraythe array of named property tags resolved with GetIDsFromNames
Returns
MAPI_E_SUCCESS on success, otherwise MAPI error.
Note
Developers may also call GetLastError() to retrieve the last MAPI error code. Possible MAPI error codes are:
  • MAPI_E_INVALID_PARAMETER: one of the parameters was not set properly
See Also
GetIDsFromNames

Referenced by SetPropertiesNoReplicate(), and SetProps().

_PUBLIC_ struct mapi_nameid* mapi_nameid_new ( TALLOC_CTX *  mem_ctx)
read

Create a new mapi_nameid structure

Parameters
mem_ctxmemory context to use for allocation
Returns
a pointer to an allocated mapi_nameid structure on success, otherwise NULL
See Also
GetIDsFromNames

Referenced by GetProps(), SetPropertiesNoReplicate(), and SetProps().

_PUBLIC_ enum MAPISTATUS mapi_nameid_OOM_add ( struct mapi_nameid *  mapi_nameid,
const char *  OOM,
const char *  OLEGUID 
)

Add a mapi_nameid entry given its OOM and OLEGUID (MNID_ID|MNID_STRING)

Parameters
mapi_nameidthe structure where results are stored
OOMthe Outlook Object Model matching string
OLEGUIDthe property set this entry belongs to
Returns
MAPI_E_SUCCESS on success, otherwise MAPI error.
Note
Developers may also call GetLastError() to retrieve the last MAPI error code. Possible MAPI error codes are:
  • MAPI_E_NOT_INITIALIZED: MAPI subsystem has not been initialized
  • MAPI_E_INVALID_PARAMETER: one of the parameters was not set properly
  • MAPI_E_NOT_FOUND: the entry intended to be added was not found
See Also
mapi_nameid_new

References get_utf8_utf16_conv_length().

_PUBLIC_ enum MAPISTATUS mapi_nameid_OOM_lookup ( const char *  OOM,
const char *  OLEGUID,
uint16_t *  propType 
)

Search for a given OOM,OLEGUID couple and return the associated propType.

Parameters
OOMThe Outlook Object Model
OLEGUIDthe named property GUID for this entry
propTypepointer on returned named property type
Returns
MAPI_E_SUCCESS on success, otherwise MAPI_E_NOT_FOUND.
Note
Developers may also call GetLastError() to retrieve the last MAPI error code. Possible MAPI error codes are:
  • MAPI_E_INVALID_PARAMETER: one of the parameter was not set properly.
  • MAPI_E_NOT_FOUND: no named property found
_PUBLIC_ enum MAPISTATUS mapi_nameid_property_lookup ( uint32_t  proptag)

Search for a given referenced unmapped named property and return whether it was found or not.

Parameters
proptagthe unmapped property tag to lookup
Returns
MAPI_E_SUCCESS on success otherwise MAPI_E_NOT_FOUND

Referenced by mapi_nameid_lookup_SPropTagArray().

_PUBLIC_ enum MAPISTATUS mapi_nameid_SPropTagArray ( struct mapi_nameid *  mapi_nameid,
struct SPropTagArray *  SPropTagArray 
)

set SPropTagArray ulPropTag property types from mapi_nameid returned by GetIDsFromNames()

Parameters
mapi_nameidthe structure where results are stored
SPropTagArraythe array of property tags returned by previous call to GetIDsFromNames()
Returns
MAPI_E_SUCCESS on success, otherwise MAPI error.
Note
Developers may also call GetLastError() to retrieve the last MAPI error code. Possible MAPI error codes are:
  • MAPI_E_INVALID_PARAMETER: one of the parameters was not set properly
See Also
GetIDsFromNames
_PUBLIC_ enum MAPISTATUS mapi_nameid_string_add ( struct mapi_nameid *  mapi_nameid,
const char *  Name,
const char *  OLEGUID 
)

Add a mapi_nameid entry given its Name and OLEGUID (MNID_STRING)

Parameters
mapi_nameidthe structure where results are stored
Namethe property name (used by MNID_STRING named props only)
OLEGUIDthe property set this entry belongs to
Returns
MAPI_E_SUCCESS on success, otherwise MAPI error.
Note
Developers may also call GetLastError() to retrieve the last MAPI error code. Possible MAPI error codes are:
  • MAPI_E_NOT_INITIALIZED: MAPI subsystem has not been initialized
  • MAPI_E_INVALID_PARAMETER: one of the parameters was not set properly
  • MAPI_E_NOT_FOUND: the entry intended to be added was not found
See Also
mapi_nameid_new

References get_utf8_utf16_conv_length().

_PUBLIC_ enum MAPISTATUS mapi_nameid_string_lookup ( const char *  Name,
const char *  OLEGUID,
uint16_t *  propType 
)

Search for a given Name,OLEGUID couple and return the associated propType.

Parameters
Namethe named property name
OLEGUIDthe named property GUID for this entry
propTypepointer on returned named property type
Returns
MAPI_E_SUCCESS on success, otherwise MAPI_E_NOT_FOUND.
Note
Developers may also call GetLastError() to retrieve the last MAPI error code. Possible MAPI error codes are:
  • MAPI_E_INVALID_PARAMETER: one of the parameter was not set properly.
  • MAPI_E_NOT_FOUND: no named property found
_PUBLIC_ enum MAPISTATUS mapi_nameid_string_lookup_canonical ( const char *  Name,
const char *  OLEGUID,
uint32_t *  propTag 
)

Search for a given Name,OLEGUID couple and return the associated canonical propTag.

Parameters
Namethe named property name
OLEGUIDthe named property GUID for this entry
propTagpointer on returned named canonical property tag
Returns
MAPI_E_SUCCESS on success, otherwise MAPI_E_NOT_FOUND.
Note
Developers may also call GetLastError() to retrieve the last MAPI error code. Possible MAPI error codes are:
  • MAPI_E_INVALID_PARAMETER: one of the parameter was not set properly.
  • MAPI_E_NOT_FOUND: no named property found
_PUBLIC_ enum MAPISTATUS mapi_nameid_unmap_SPropTagArray ( struct mapi_nameid *  mapi_nameid,
struct SPropTagArray *  SPropTagArray 
)

Restore the original SPropTagArray array with the property tags saved in the mapi_nameid structure.

Parameters
mapi_nameidthe structure where results are stored
SPropTagArraythe array of property tags with original property tags
Returns
MAPI_E_SUCCESS on success, otherwise MAPI error.
Note
Developers may also call GetLastError() to retrieve the last MAPI error code. Possible MAPI error codes are:
  • MAPI_E_INVALID_PARAMETER: one of the parameters was not set properly
See Also
GetIDsFromNames

Referenced by GetProps().

_PUBLIC_ enum MAPISTATUS mapi_nameid_unmap_SPropValue ( struct mapi_nameid *  mapi_nameid,
struct SPropValue *  lpProps,
uint32_t  PropCount 
)

Restore the original SPropValue array with the property tags saved in the mapi_nameid structure.

Parameters
mapi_nameidthe structure where results are stored
lpPropsthe array of SPropValue structures with original property tags
PropCountcount of lpProps elements
Returns
MAPI_E_SUCCESS on success, otherwise MAPI error.
Note
Developers may also call GetLastError() to retrieve the last MAPI error code. Possible MAPI error codes are:
  • MAPI_E_INVALID_PARAMETER: one of the parameters was not set properly
See Also
GetIDsFromNames

Referenced by SetPropertiesNoReplicate(), and SetProps().


Creative Commons License
Creative Commons Attribution icon Creative Commons Share Alike icon
This content is licensed under the Creative Commons
Attribution ShareAlike License v. 3.0:
http://creativecommons.org/licenses/by-sa/3.0/

openchange-2.0/apidocs/html/libmapi/mapi__object_8c.html000066400000000000000000002176001223057412600233700ustar00rootroot00000000000000 MAPIClientLibraries 2.0 API Documentation
mapi_object.c File Reference

mapi_object_t support functions More...

#include "libmapi/libmapi.h"
#include "libmapi/libmapi_private.h"

Macros

#define INVALID_HANDLE_VALUE   0xffffffff
 keep intern to this file

Functions

_PUBLIC_ enum MAPISTATUS mapi_object_bookmark_debug (mapi_object_t *obj_table)
enum MAPISTATUS mapi_object_bookmark_find (mapi_object_t *obj_table, uint32_t bkPosition, struct SBinary_short *bin)
_PUBLIC_ enum MAPISTATUS mapi_object_bookmark_get_count (mapi_object_t *obj_table, uint32_t *count)
_PUBLIC_ enum MAPISTATUS mapi_object_copy (mapi_object_t *dst, mapi_object_t *src)
_PUBLIC_ void mapi_object_debug (mapi_object_t *obj)
mapi_handle_t mapi_object_get_handle (mapi_object_t *obj)
_PUBLIC_ mapi_id_t mapi_object_get_id (mapi_object_t *obj)
_PUBLIC_ enum MAPISTATUS mapi_object_get_logon_id (mapi_object_t *obj, uint8_t *logon_id)
_PUBLIC_ struct mapi_session * mapi_object_get_session (mapi_object_t *obj)
_PUBLIC_ enum MAPISTATUS mapi_object_init (mapi_object_t *obj)
int mapi_object_is_invalid (mapi_object_t *obj)
_PUBLIC_ void mapi_object_release (mapi_object_t *obj)
void mapi_object_set_handle (mapi_object_t *obj, mapi_handle_t handle)
void mapi_object_set_id (mapi_object_t *obj, mapi_id_t id)
_PUBLIC_ void mapi_object_set_logon_id (mapi_object_t *obj, uint8_t logon_id)
_PUBLIC_ void mapi_object_set_logon_store (mapi_object_t *obj)
_PUBLIC_ void mapi_object_set_session (mapi_object_t *obj, struct mapi_session *session)
void mapi_object_table_init (TALLOC_CTX *mem_ctx, mapi_object_t *obj_table)

Detailed Description

mapi_object_t support functions

Function Documentation

_PUBLIC_ enum MAPISTATUS mapi_object_bookmark_debug ( mapi_object_t *  obj_table)

Dump bookmarks associated to a MAPI object table

Parameters
obj_tablepointer on the MAPI object table
Returns
MAPI_E_SUCCESS on success, otherwise MAPI error.
enum MAPISTATUS mapi_object_bookmark_find ( mapi_object_t *  obj_table,
uint32_t  bkPosition,
struct SBinary_short *  bin 
)

Fetch a bookmark within a MAPI object table

Parameters
obj_tablepointer on the MAPI object table
bkPositionthe bookmark position to find
binpointer on the Sbinary_short the function fills
Returns
MAPI_E_SUCCESS on success, otherwise MAPI error.

Referenced by FindRow(), and SeekRowBookmark().

_PUBLIC_ enum MAPISTATUS mapi_object_bookmark_get_count ( mapi_object_t *  obj_table,
uint32_t *  count 
)

Retrieve the number of bookmarks stored in a MAPI object table

Parameters
obj_tablepointer to the MAPI object table
countpointer to the number of bookmarks to return
Returns
MAPI_E_SUCCESS on success, otherwise MAPI error.
_PUBLIC_ enum MAPISTATUS mapi_object_copy ( mapi_object_t *  dst,
mapi_object_t *  src 
)

Copy MAPI object

This function copies mapi_object data from source to destination.

Parameters
dstpointer on the destination MAPI object
srcpointer on the source MAPI object
Returns
MAPI_E_SUCCESS on success, otherwise MAPI_E_NOT_INITIALIZED
_PUBLIC_ void mapi_object_debug ( mapi_object_t *  obj)

Dump a MAPI object (for debugging)

Parameters
objpointer on the MAPI object to dump out
mapi_handle_t mapi_object_get_handle ( mapi_object_t *  obj)

Retrieve the handle associated to a MAPI object

Parameters
objpointer on the MAPI object to retrieve the handle from
Returns
a valid MAPI object handle on success, otherwise 0xFFFFFFFF.

Referenced by Abort(), AbortSubmit(), AddressTypes(), CloneStream(), CollapseRow(), CommitStream(), CopyFolder(), CopyProps(), CopyTo(), CopyToStream(), CreateAttach(), CreateBookmark(), CreateFolder(), CreateMessage(), DeleteAttach(), DeleteFolder(), DeleteMessage(), DeletePropertiesNoReplicate(), DeleteProps(), EmptyFolder(), ExpandRow(), FindRow(), FreeBookmark(), FXCopyFolder(), FXCopyMessages(), FXCopyProperties(), FXCopyTo(), FXDestConfigure(), FXGetBuffer(), FXPutBuffer(), GetAttachmentTable(), GetCollapseState(), GetContentsTable(), GetHierarchyTable(), GetIdFromLongTermId(), GetIDsFromNames(), GetLocalReplicaIds(), GetLongTermIdFromId(), GetMessageStatus(), GetNamesFromIDs(), GetOwningServers(), GetPermissionsTable(), GetPropList(), GetProps(), GetPropsAll(), GetReceiveFolder(), GetReceiveFolderTable(), GetRulesTable(), GetSearchCriteria(), GetStatus(), GetStoreState(), GetStreamSize(), GetTransportFolder(), GetValidAttach(), HardDeleteMessage(), HardDeleteMessagesAndSubfolders(), ICSSyncConfigure(), ICSSyncGetTransferState(), ICSSyncOpenCollector(), ICSSyncUploadStateBegin(), ICSSyncUploadStateContinue(), ICSSyncUploadStateEnd(), LockRegionStream(), mapi_object_is_invalid(), ModifyPermissions(), ModifyRecipients(), MoveCopyMessages(), MoveFolder(), OpenAttach(), OpenEmbeddedMessage(), OpenFolder(), OpenMessage(), OpenPublicFolderByName(), OpenStream(), OptionsData(), PublicFolderIsGhosted(), QueryColumns(), QueryNamedProperties(), QueryPosition(), QueryRows(), ReadRecipients(), ReadStream(), Release(), ReloadCachedInformation(), RemoveAllRecipients(), Reset(), Restrict(), SaveChangesAttachment(), SaveChangesMessage(), SeekRow(), SeekRowApprox(), SeekRowBookmark(), SeekStream(), SetCollapseState(), SetColumns(), SetLocalReplicaMidsetDeleted(), SetMessageReadFlag(), SetMessageStatus(), SetPropertiesNoReplicate(), SetProps(), SetReadFlags(), SetReceiveFolder(), SetSearchCriteria(), SetSpooler(), SetStreamSize(), SetSyncNotificationGuid(), SortTable(), SpoolerLockMessage(), SubmitMessage(), Subscribe(), SyncOpenAdvisor(), TellVersion(), TransportNewMail(), TransportSend(), UnlockRegionStream(), WriteAndCommitStream(), and WriteStream().

_PUBLIC_ mapi_id_t mapi_object_get_id ( mapi_object_t *  obj)

Retrieve an object ID for a given MAPI object

Parameters
objpointer on the MAPI object to get the ID for
Returns
the object ID, or 0xFFFFFFFFFFFFFFFF if the object does not exist

Referenced by AbortSubmit(), CopyFolder(), CreateMessage(), GetOwningServers(), mapi_id_array_add_obj(), mapi_id_array_del_obj(), MoveFolder(), PublicFolderIsGhosted(), SetReceiveFolder(), SpoolerLockMessage(), Subscribe(), and TransportNewMail().

_PUBLIC_ enum MAPISTATUS mapi_object_get_logon_id ( mapi_object_t *  obj,
uint8_t *  logon_id 
)

Retrieve the logon id for a given MAPI object

Parameters
objpointer to the object to retrieve the logon id from
logon_idpointer to a variable to store the logon id
Returns
MAPI_E_SUCCESS on success, otherwise MAPI error.

Referenced by Abort(), AbortSubmit(), AddressTypes(), CloneStream(), CollapseRow(), CommitStream(), CopyFolder(), CopyProps(), CopyTo(), CopyToStream(), CreateAttach(), CreateBookmark(), CreateFolder(), CreateMessage(), DeleteAttach(), DeleteFolder(), DeleteMessage(), DeletePropertiesNoReplicate(), DeleteProps(), EmptyFolder(), ExpandRow(), FindRow(), FreeBookmark(), FXCopyFolder(), FXCopyMessages(), FXCopyProperties(), FXCopyTo(), FXDestConfigure(), FXGetBuffer(), FXPutBuffer(), GetAttachmentTable(), GetCollapseState(), GetContentsTable(), GetHierarchyTable(), GetIdFromLongTermId(), GetIDsFromNames(), GetLocalReplicaIds(), GetLongTermIdFromId(), GetMessageStatus(), GetNamesFromIDs(), GetOwningServers(), GetPermissionsTable(), GetPropList(), GetProps(), GetPropsAll(), GetReceiveFolder(), GetReceiveFolderTable(), GetRulesTable(), GetSearchCriteria(), GetStatus(), GetStoreState(), GetStreamSize(), GetTransportFolder(), GetValidAttach(), HardDeleteMessage(), HardDeleteMessagesAndSubfolders(), ICSSyncConfigure(), ICSSyncGetTransferState(), ICSSyncOpenCollector(), ICSSyncUploadStateBegin(), ICSSyncUploadStateContinue(), ICSSyncUploadStateEnd(), LockRegionStream(), ModifyPermissions(), ModifyRecipients(), MoveCopyMessages(), MoveFolder(), OpenAttach(), OpenEmbeddedMessage(), OpenFolder(), OpenMessage(), OpenPublicFolderByName(), OpenStream(), OptionsData(), PublicFolderIsGhosted(), QueryColumns(), QueryNamedProperties(), QueryPosition(), QueryRows(), ReadRecipients(), ReadStream(), Release(), ReloadCachedInformation(), RemoveAllRecipients(), Reset(), Restrict(), SaveChangesAttachment(), SaveChangesMessage(), SeekRow(), SeekRowApprox(), SeekRowBookmark(), SeekStream(), SetCollapseState(), SetColumns(), SetLocalReplicaMidsetDeleted(), SetMessageReadFlag(), SetMessageStatus(), SetPropertiesNoReplicate(), SetProps(), SetReadFlags(), SetReceiveFolder(), SetSearchCriteria(), SetSpooler(), SetStreamSize(), SetSyncNotificationGuid(), SortTable(), SpoolerLockMessage(), SubmitMessage(), Subscribe(), SyncOpenAdvisor(), TellVersion(), TransportNewMail(), TransportSend(), UnlockRegionStream(), WriteAndCommitStream(), and WriteStream().

_PUBLIC_ struct mapi_session* mapi_object_get_session ( mapi_object_t *  obj)
read

Retrieve the session associated to the MAPI object

Parameters
objthe object to get the session for
Returns
pointer on a MAPI session on success, otherwise NULL

Referenced by Abort(), AbortSubmit(), AddressTypes(), AddUserPermission(), CloneStream(), CollapseRow(), CommitStream(), CopyFolder(), CopyProps(), CopyTo(), CopyToStream(), CreateAttach(), CreateBookmark(), CreateFolder(), CreateMessage(), DeleteAttach(), DeleteFolder(), DeleteMessage(), DeletePropertiesNoReplicate(), DeleteProps(), EmptyFolder(), ExpandRow(), FindRow(), FreeBookmark(), FXCopyFolder(), FXCopyMessages(), FXCopyProperties(), FXCopyTo(), FXDestConfigure(), FXGetBuffer(), FXPutBuffer(), GetAttachmentTable(), GetBestBody(), GetCollapseState(), GetContentsTable(), GetFolderItemsCount(), GetHierarchyTable(), GetIdFromLongTermId(), GetIDsFromNames(), GetLocalReplicaIds(), GetLongTermIdFromId(), GetMessageStatus(), GetNamesFromIDs(), GetOwningServers(), GetPermissionsTable(), GetPropList(), GetProps(), GetPropsAll(), GetReceiveFolder(), GetReceiveFolderTable(), GetRulesTable(), GetSearchCriteria(), GetStatus(), GetStoreState(), GetStreamSize(), GetTransportFolder(), GetUserFreeBusyData(), GetValidAttach(), HardDeleteMessage(), HardDeleteMessagesAndSubfolders(), ICSSyncConfigure(), ICSSyncGetTransferState(), ICSSyncOpenCollector(), ICSSyncUploadStateBegin(), ICSSyncUploadStateContinue(), ICSSyncUploadStateEnd(), IsFreeBusyConflict(), LockRegionStream(), Logoff(), ModifyPermissions(), ModifyRecipients(), ModifyUserPermission(), MoveCopyMessages(), MoveFolder(), OpenAttach(), OpenEmbeddedMessage(), OpenFolder(), OpenMessage(), OpenPublicFolderByName(), OpenStream(), OptionsData(), PublicFolderIsGhosted(), QueryColumns(), QueryNamedProperties(), QueryPosition(), QueryRows(), ReadRecipients(), ReadStream(), Release(), ReloadCachedInformation(), RemoveAllRecipients(), RemoveUserPermission(), Reset(), Restrict(), SaveChangesAttachment(), SaveChangesMessage(), SeekRow(), SeekRowApprox(), SeekRowBookmark(), SeekStream(), SetCollapseState(), SetColumns(), SetLocalReplicaMidsetDeleted(), SetMessageReadFlag(), SetMessageStatus(), SetPropertiesNoReplicate(), SetProps(), SetReadFlags(), SetReceiveFolder(), SetSearchCriteria(), SetSpooler(), SetStreamSize(), SetSyncNotificationGuid(), SortTable(), SpoolerLockMessage(), SubmitMessage(), Subscribe(), SyncOpenAdvisor(), TellVersion(), TransportNewMail(), TransportSend(), UnlockRegionStream(), WrapCompressedRTFStream(), WriteAndCommitStream(), and WriteStream().

_PUBLIC_ enum MAPISTATUS mapi_object_init ( mapi_object_t *  obj)

Initialize MAPI object

This function is required to be called before any manipulation of this MAPI object.

Parameters
objthe object to initialize
Returns
MAPI_E_SUCCESS on success, otherwise MAPI error.
Note
Developers may also call GetLastError() to retrieve the last MAPI error code. Possible MAPI error codes are:
  • MAPI_E_NOT_INITIALIZED: MAPI subsystem has not been initialized.
See Also
mapi_object_release
Examples:
fetchappointment.c, and fetchmail.c.

Referenced by CreateFolder(), GetUserFreeBusyData(), ModifyUserPermission(), RemoveUserPermission(), and Subscribe().

int mapi_object_is_invalid ( mapi_object_t *  obj)

Check if the supplied object has a valid handle

Parameters
objpointer on the MAPI object to test
Returns
0 on success, otherwise 1

References INVALID_HANDLE_VALUE, and mapi_object_get_handle().

_PUBLIC_ void mapi_object_release ( mapi_object_t *  obj)

Release MAPI object

This function is required to be called when this MAPI object is no longer required.

Parameters
objpointer on the MAPI object to release
See Also
mapi_object_initialize, Release
Examples:
fetchappointment.c, and fetchmail.c.

References INVALID_HANDLE_VALUE, and Release().

Referenced by GetUserFreeBusyData(), Logoff(), ModifyUserPermission(), and RemoveUserPermission().

void mapi_object_set_id ( mapi_object_t *  obj,
mapi_id_t  id 
)

Set the id for a given MAPI object

Parameters
objpointer on the MAPI object to set the session for
idIdentifier to set to the object obj

Referenced by CreateFolder(), OpenFolder(), and SaveChangesMessage().

_PUBLIC_ void mapi_object_set_logon_id ( mapi_object_t *  obj,
uint8_t  logon_id 
)
_PUBLIC_ void mapi_object_set_logon_store ( mapi_object_t *  obj)

Mark a MAPI object as a store object

Parameters
objpointer to the object to set the store boolean for

Referenced by OpenPublicFolder(), and OpenUserMailbox().

_PUBLIC_ void mapi_object_set_session ( mapi_object_t *  obj,
struct mapi_session *  session 
)
void mapi_object_table_init ( TALLOC_CTX *  mem_ctx,
mapi_object_t *  obj_table 
)

Initialize MAPI object private data to store a MAPI object table

Parameters
mem_ctxpointer on the memory context
obj_tablepointer on the MAPI object

Referenced by GetContentsTable(), GetHierarchyTable(), GetPermissionsTable(), and GetRulesTable().


Creative Commons License
Creative Commons Attribution icon Creative Commons Share Alike icon
This content is licensed under the Creative Commons
Attribution ShareAlike License v. 3.0:
http://creativecommons.org/licenses/by-sa/3.0/

openchange-2.0/apidocs/html/libmapi/mapi_sample1_8c-example.html000066400000000000000000000157071223057412600247620ustar00rootroot00000000000000 MAPIClientLibraries 2.0 API Documentation
mapi_sample1.c
This example shows a very basic MAPI program, including setup, login,

and teardown.The first MAPI library function called is MAPIInitialize(). As its name suggests, this function initializes MAPI library: It creates the MAPI global context, opens the profile database store (database path passed as function parameter) and initialize Samba4 transport layer. This function must be called prior any other MAPI library operations.

Once MAPI is initialized, we need to create a connection to Exchange and open MAPI sessions with the user credentials. This is the purpose of MapiLogonEx() which needs to be executed prior doing any effective code. This function takes a pointer on a mapi_session structure, the profile username and an optional password in case you decided to store it outside the profile. In the example above, we retrieve the default profile name from the database using GetDefaultProfile() Note that MapiLogonEx() opens connections to both the EMSMDB and EMSABP store providers. If you intend to interact with a single provider, use MapiLogonProvider() instead.

Finally we call MAPIUninitialize() prior to leaving the function. This opaque function will clean up the memory allocated during the session and stored within the global MAPI context.

#include <libmapi/libmapi.h>
#define DEFAULT_PROFDB_PATH "%s/.openchange/profiles.ldb"
int main(int argc, char *argv[])
{
TALLOC_CTX *mem_ctx;
struct mapi_context *mapi_ctx;
enum MAPISTATUS retval;
struct mapi_session *session = NULL;
char *profdb;
char *profname;
mem_ctx = talloc_named(NULL, 0, "mapi_sample1");
profdb = talloc_asprintf(mem_ctx, DEFAULT_PROFDB_PATH, getenv("HOME"));
retval = MAPIInitialize(&mapi_ctx, profdb);
mapi_errstr("MAPIInitialize", GetLastError());
if (retval != MAPI_E_SUCCESS) return -1;
retval = GetDefaultProfile(mapi_ctx, &profname);
mapi_errstr("GetDefaultProfile", GetLastError());
if (retval != MAPI_E_SUCCESS) return -1;
retval = MapiLogonEx(mapi_ctx, &session, profname, NULL);
mapi_errstr("MapiLogonEx", GetLastError());
if (retval != MAPI_E_SUCCESS) return -1;
MAPIUninitialize(mapi_ctx);
talloc_free(mem_ctx);
return 0;
}

Creative Commons License
Creative Commons Attribution icon Creative Commons Share Alike icon
This content is licensed under the Creative Commons
Attribution ShareAlike License v. 3.0:
http://creativecommons.org/licenses/by-sa/3.0/

openchange-2.0/apidocs/html/libmapi/mapiconcepts.html000066400000000000000000000112371223057412600230460ustar00rootroot00000000000000 MAPIClientLibraries 2.0 API Documentation
MAPI Concepts

MAPI objects

Almost any MAPI data you access, read or edit is associated with an object. No matter whether you intend to browse mailbox hierarchy, open folders, create tables or access items (messages, appointments, contacts, tasks, notes), you will have to initialize and use MAPI objects: object understanding and manipulation is fundamental.

  • When developing MAPI clients with Microsoft framework, instantiated objects inherit from parent classes. As a matter of fact, developers know which methods they can apply to objects and we suppose it makes their life easier.
  • In OpenChange, objects are opaque. They are generic data structures which content is set and accessed through MAPI public functions. Therefore, Linux MAPI developers must know what they are doing.

An example of MAPI object manipulation is shown below:

mapi_object obj_store;
[...]
mapi_object_init(&obj_store);
retval = OpenMsgStore(&obj_store);
if (retval != MAPI_E_SUCCESS) {
mapi_errstr("OpenMsgStore", GetLastError());
exit (1);
}
mapi_object_release(&obj_store);

MAPI Handles

Beyond memory management considerations, understanding MAPI handles role in object manipulation provides a better understanding why mapi_object_release() matters.

Handles are temporary identifiers returned by Exchange when you access or create objects on the server. They are used to make reference to a particular object all along its session lifetime. They are stored in unsigned integers, are unique for each object but temporary along MAPI session. Handles are the only links between objects accessed on the client side and efficiently stored on the server side.

Although OpenChange MAPI makes handles manipulation transparent for developers, mapi_object_release() frees both the allocated memory for the object on client side, but also releases the object on the server.


Creative Commons License
Creative Commons Attribution icon Creative Commons Share Alike icon
This content is licensed under the Creative Commons
Attribution ShareAlike License v. 3.0:
http://creativecommons.org/licenses/by-sa/3.0/

openchange-2.0/apidocs/html/libmapi/mapidump_8c.html000066400000000000000000000530241223057412600225670ustar00rootroot00000000000000 MAPIClientLibraries 2.0 API Documentation
mapidump.c File Reference

Functions for displaying various data structures, mainly for debugging. More...

#include "libmapi/libmapi.h"
#include "libmapi/libmapi_private.h"

Functions

_PUBLIC_ void mapidump_appointment (struct mapi_SPropValue_array *properties, const char *id)
_PUBLIC_ void mapidump_contact (struct mapi_SPropValue_array *properties, const char *id)
_PUBLIC_ void mapidump_date_SPropValue (struct SPropValue lpProp, const char *label, const char *sep)
_PUBLIC_ void mapidump_languages_list (void)
_PUBLIC_ void mapidump_message (struct mapi_SPropValue_array *properties, const char *id, mapi_object_t *obj_msg)
_PUBLIC_ void mapidump_message_summary (mapi_object_t *obj_message)
_PUBLIC_ void mapidump_note (struct mapi_SPropValue_array *properties, const char *id)
_PUBLIC_ void mapidump_PAB_entry (struct PropertyRow_r *aRow)
 Output a row of the public address book.
_PUBLIC_ void mapidump_SPropValue (struct SPropValue lpProp, const char *sep)
 Output one property tag and value.
_PUBLIC_ void mapidump_task (struct mapi_SPropValue_array *properties, const char *id)

Detailed Description

Functions for displaying various data structures, mainly for debugging.

Function Documentation

_PUBLIC_ void mapidump_appointment ( struct mapi_SPropValue_array *  properties,
const char *  id 
)

This function dumps the properties relating to an appointment to standard output

The expected way to obtain the properties array is to use OpenMessage() to obtain the appointment object, then to use GetPropsAll() to obtain all the properties.

Parameters
propertiesarray of appointment properties
ididentification to display for the appointment (can be NULL)
See Also
mapidump_message, mapidump_contact, mapidump_task, mapidump_note
Examples:
fetchappointment.c.
_PUBLIC_ void mapidump_contact ( struct mapi_SPropValue_array *  properties,
const char *  id 
)

This function dumps the properties relating to a contact (address book entry) to standard output

The expected way to obtain the properties array is to use OpenMessage() to obtain the contact object, then to use GetPropsAll() to obtain all the properties.

Parameters
propertiesarray of contact properties
ididentification to display for the contact (can be NULL)
See Also
mapidump_message, mapidump_appointment, mapidump_task, mapidump_note
_PUBLIC_ void mapidump_date_SPropValue ( struct SPropValue  lpProp,
const char *  label,
const char *  sep 
)

This function dumps a property containing a date / time to standard output

If the property does not contain a PT_SYSTIME type value, then no output will occur.

Parameters
lpPropthe property to dump
labelthe label to display prior to the time (e.g. the property tag)
sepa separator / spacer to insert in front of the label
Note
Prior to OpenChange 0.9, this function took 2 arguments, assuming a default separator of a tab. You can get the old behaviour by using "\t" for sep.

Referenced by mapidump_SPropValue().

_PUBLIC_ void mapidump_languages_list ( void  )

print the list of languages OpenChange supports

_PUBLIC_ void mapidump_message ( struct mapi_SPropValue_array *  properties,
const char *  id,
mapi_object_t *  obj_msg 
)

This function dumps the properties relating to an email message to standard output

The expected way to obtain the properties array is to use OpenMessage() to obtain the message object, then to use GetPropsAll() to obtain all the properties.

Parameters
propertiesarray of message properties
ididentification to display for the message (can be NULL)
obj_msgpointer to the message MAPI object (can be NULL)
See Also
mapidump_appointment, mapidump_contact, mapidump_task, mapidump_note
Examples:
fetchmail.c.

References mapidump_message_summary().

_PUBLIC_ void mapidump_message_summary ( mapi_object_t *  obj_message)

This function dumps message information retrieved from OpenMessage call. It provides a quick method to print message summaries with information such as subject and recipients.

Parameters
obj_messagepointer to the MAPI message object to use

Referenced by mapidump_message().

_PUBLIC_ void mapidump_note ( struct mapi_SPropValue_array *  properties,
const char *  id 
)

This function dumps the properties relating to a note to standard output

The expected way to obtain the properties array is to use OpenMessage() to obtain the note object, then to use GetPropsAll() to obtain all the properties.

Parameters
propertiesarray of note properties
ididentification to display for the note (can be NULL)
See Also
mapidump_message, mapidump_appointment, mapidump_contact, mapidump_task
_PUBLIC_ void mapidump_PAB_entry ( struct PropertyRow_r *  aRow)

Output a row of the public address book.

Parameters
aRowone row of the public address book (Global Address List)

This function is usually used with GetGALTable, which can obtain several rows at once - you'll need to iterate over the rows.

The SRow is assumed to contain entries for PR_ADDRTYPE_UNICODE, PR_DISPLAY_NAME_UNICODE, PR_EMAIL_ADDRESS_UNICODE and PR_ACCOUNT_UNICODE.

_PUBLIC_ void mapidump_SPropValue ( struct SPropValue  lpProp,
const char *  sep 
)

Output one property tag and value.

Parameters
lpPropthe property to print
sepa separator / spacer to insert in front of the label

References mapidump_date_SPropValue().

_PUBLIC_ void mapidump_task ( struct mapi_SPropValue_array *  properties,
const char *  id 
)

This function dumps the properties relating to a task (to-do list entry) to standard output

The expected way to obtain the properties array is to use OpenMessage() to obtain the task object, then to use GetPropsAll() to obtain all the properties.

Parameters
propertiesarray of task properties
ididentification to display for the task (can be NULL)
See Also
mapidump_message, mapidump_appointment, mapidump_contact, mapidump_note

Creative Commons License
Creative Commons Attribution icon Creative Commons Share Alike icon
This content is licensed under the Creative Commons
Attribution ShareAlike License v. 3.0:
http://creativecommons.org/licenses/by-sa/3.0/

openchange-2.0/apidocs/html/libmapi/middle_bg.jpg000066400000000000000000000005251223057412600221010ustar00rootroot00000000000000ÿØÿàJFIFddÿìDuckydÿîAdobedÀÿÛ„ÿÀdÿÄU Q¡Ña‘ÿÚ ?ßÀ#¿ªÚ0 ïæ¶œ ‡3Yû žñݲ ?ÿÙopenchange-2.0/apidocs/html/libmapi/nav_f.png000066400000000000000000000002311223057412600212620ustar00rootroot00000000000000‰PNG  IHDR8³»`IDATxíÝK€ EÑ–·[†øBÑmkâÄÂH—prÓ¼.‚Žó‚ꎤR6Z VI±E‚5j³„lóš›iI˜¬ÞêçJ0ŒÑÑ/Žû›™uøñóÞ¿6sH ÝõyIEND®B`‚openchange-2.0/apidocs/html/libmapi/nav_g.png000066400000000000000000000001371223057412600212700ustar00rootroot00000000000000‰PNG  IHDRô1&IDATxíÝ1 ÁOHf„á_ ->~¸åM iËMèÀƒS½ü‚<IEND®B`‚openchange-2.0/apidocs/html/libmapi/nav_h.png000066400000000000000000000001421223057412600212650ustar00rootroot00000000000000‰PNG  IHDR ,é@)IDATxíÝA @BQ­³šÛ›Ð¢Žáà) )ëý éaÅèÜ¿Æo‡RlÐßIEND®B`‚openchange-2.0/apidocs/html/libmapi/nav_tab.gif000066400000000000000000000014541223057412600215740ustar00rootroot00000000000000GIF89aPæïïïþþþýþýûüúõ÷óñôïøú÷ýýüúûù÷ùöôöòöøõïóíðôîóöñùúøüýûòõðïòìîòëíñëòõïõõõÿÿÿúúúîòìðóîêëéðððôôôñññýýýñôðÆÉÅìîëÇÊÆÈÊÆÏÏÎÇÊÅËÍÊêìéïóîçèæÎÏÍÐÐÐõ÷ôÊÍÉïñíÆÈÄÊÌÊêêéïóìüýüÊËÉÏÏÏèêçÕ×ÓüüûÍÎÌëíêÌÍËíñêÏÐÏùûøêëêòöðóõñÉÊÇñôîîñì!ù,Pÿ€ˆ‰Š‹ŒŽ‘ˆ‚@;/Ÿ ¡¢£¤¥¦§¨E(ƒ )·¸¹º»¼½¾¿À¸ 7„23ËÌÍÎÏÐÑÒÓÔÐ=*"DÝÞßàáâãäåæä8 îïðñòóôõö÷õ.A þÿ H° ÁƒM R ¡Ã‡#JœH±¢ÅŠ0)ˆÀ±£Ç CŠI²$Ɉ8Xɲ¥Ë—0cÊœIsæD-èÜɳ§ÏŸ@ƒ *”¢’*]Ê´©Ó§P£J:Q‚X³jÝʵ«×¯`­È@‚³hÓª]˶­Û·p‰ßÆ@ôÀݻxóêÝË·¯ß¿~O Bð °áÈ+^̸±ãÆ< @@¹²å˘3kÞ̹3gˆr Mº´éÓ¨S«^Ízõ D4 ÈžM»¶íÛ¸sëÞ­»¢Àƒ N¼¸ñãÈ“'·H€óçУKŸN½ºõë×} À½»÷ïàËO¾|y;openchange-2.0/apidocs/html/libmapi/notif_8c.html000066400000000000000000000203331223057412600220670ustar00rootroot00000000000000 MAPIClientLibraries 2.0 API Documentation
notif.c File Reference

Notification (MS-OXCNOTIF) operations. More...

#include "libmapi/libmapi.h"
#include "libmapi/libmapi_private.h"

Functions

_PUBLIC_ enum MAPISTATUS SetSyncNotificationGuid (mapi_object_t *obj_advisor, const struct GUID Guid)
_PUBLIC_ enum MAPISTATUS SyncOpenAdvisor (mapi_object_t *obj, mapi_object_t *obj_notifier)

Detailed Description

Notification (MS-OXCNOTIF) operations.

Function Documentation

_PUBLIC_ enum MAPISTATUS SetSyncNotificationGuid ( mapi_object_t *  obj_advisor,
const struct GUID  Guid 
)

Assign a notification GUID to an ICS Advisor object

This function allows the client to set a specific GUID to an ICS advistor object (as returned from SyncOpenAdvisor). This operation is not supported on Exchange 2010.

Parameters
obj_advisorpointer to the ICS Advisor object
Guidthe GUID for the notification
Returns
MAPI_E_SUCCESS on success, otherwise MAPI error.
Note
Developers may also call GetLastError() to retrieve the last MAPI error code. Possible MAPI error codes are:
  • MAPI_E_NOT_INITIALIZED: MAPI subsystem has not been initialized
  • MAPI_E_INVALID_PARAMETER: one of the function parameters is invalid
  • MAPI_E_CALL_FAILED: A network problem was encountered during the transaction

References mapi_object_get_handle(), mapi_object_get_logon_id(), and mapi_object_get_session().

_PUBLIC_ enum MAPISTATUS SyncOpenAdvisor ( mapi_object_t *  obj,
mapi_object_t *  obj_notifier 
)

Obtain an ICS notification object

This function is used to obtain a server object handle for an ICS notification operation (RegisterSyncNotifications or SetSyncNotificationGuid). This operation is not supported on Exchange 2010.

Parameters
objthe logon object for which notifications are desired
obj_notifierthe notifier object for future ROPs.
Returns
MAPI_E_SUCCESS on success, otherwise MAPI error.

The caller should release the returned notifier object when it is no longer required, using the mapi_object_release function.

Note
Developers may also call GetLastError() to retrieve the last MAPI error code. Possible MAPI error codes are:
  • MAPI_E_NOT_INITIALIZED: MAPI subsystem has not been initialized
  • MAPI_E_INVALID_PARAMETER: one of the function parameters is invalid
  • MAPI_E_CALL_FAILED: A network problem was encountered during the transaction

References mapi_object_get_handle(), mapi_object_get_logon_id(), mapi_object_get_session(), mapi_object_set_handle(), mapi_object_set_logon_id(), and mapi_object_set_session().


Creative Commons License
Creative Commons Attribution icon Creative Commons Share Alike icon
This content is licensed under the Creative Commons
Attribution ShareAlike License v. 3.0:
http://creativecommons.org/licenses/by-sa/3.0/

openchange-2.0/apidocs/html/libmapi/nspi_8c.html000066400000000000000000001653141223057412600217320ustar00rootroot00000000000000 MAPIClientLibraries 2.0 API Documentation
nspi.c File Reference

Name Service Provider (NSPI) stack functions. More...

#include "libmapi/libmapi.h"
#include "libmapi/libmapi_private.h"

Functions

_PUBLIC_ struct nspi_context * nspi_bind (TALLOC_CTX *parent_ctx, struct dcerpc_pipe *p, struct cli_credentials *cred, uint32_t codepage, uint32_t language, uint32_t method)
_PUBLIC_ enum MAPISTATUS nspi_CompareMIds (struct nspi_context *nspi_ctx, TALLOC_CTX *mem_ctx, uint32_t MId1, uint32_t MId2, uint32_t *plResult)
int nspi_disconnect_dtor (void *data)
_PUBLIC_ enum MAPISTATUS nspi_DNToMId (struct nspi_context *nspi_ctx, TALLOC_CTX *mem_ctx, struct StringsArray_r *pNames, struct PropertyTagArray_r **ppMIds)
_PUBLIC_ enum MAPISTATUS nspi_GetIDsFromNames (struct nspi_context *nspi_ctx, TALLOC_CTX *mem_ctx, bool VerifyNames, uint32_t cNames, struct PropertyName_r *ppNames, struct SPropTagArray **ppPropTags)
_PUBLIC_ enum MAPISTATUS nspi_GetMatches (struct nspi_context *nspi_ctx, TALLOC_CTX *mem_ctx, struct SPropTagArray *pPropTags, struct Restriction_r *Filter, uint32_t ulRequested, struct PropertyRowSet_r **ppRows, struct PropertyTagArray_r **ppOutMIds)
_PUBLIC_ enum MAPISTATUS nspi_GetNamesFromIDs (struct nspi_context *nspi_ctx, TALLOC_CTX *mem_ctx, struct FlatUID_r *lpGuid, struct SPropTagArray *pPropTags, struct SPropTagArray **ppReturnedPropTags, struct PropertyNameSet_r **ppNames)
_PUBLIC_ enum MAPISTATUS nspi_GetPropList (struct nspi_context *nspi_ctx, TALLOC_CTX *mem_ctx, bool WantObject, uint32_t dwMId, struct SPropTagArray **ppPropTags)
_PUBLIC_ enum MAPISTATUS nspi_GetProps (struct nspi_context *nspi_ctx, TALLOC_CTX *mem_ctx, struct SPropTagArray *pPropTags, struct PropertyTagArray_r *MId, struct PropertyRowSet_r **SRowSet)
_PUBLIC_ enum MAPISTATUS nspi_GetSpecialTable (struct nspi_context *nspi_ctx, TALLOC_CTX *mem_ctx, uint32_t Type, struct PropertyRowSet_r **ppRows)
_PUBLIC_ enum MAPISTATUS nspi_GetTemplateInfo (struct nspi_context *nspi_ctx, TALLOC_CTX *mem_ctx, uint32_t dwFlags, uint32_t ulType, char *pDN, struct PropertyRow_r **ppData)
_PUBLIC_ enum MAPISTATUS nspi_ModLinkAtt (struct nspi_context *nspi_ctx, bool Delete, uint32_t ulPropTag, uint32_t MId, struct BinaryArray_r *lpEntryIds)
_PUBLIC_ enum MAPISTATUS nspi_ModProps (struct nspi_context *nspi_ctx, TALLOC_CTX *mem_ctx, uint32_t MId, struct SPropTagArray *pPropTags, struct PropertyRow_r *pRow)
_PUBLIC_ enum MAPISTATUS nspi_QueryColumns (struct nspi_context *nspi_ctx, TALLOC_CTX *mem_ctx, bool WantUnicode, struct SPropTagArray **ppColumns)
_PUBLIC_ enum MAPISTATUS nspi_QueryRows (struct nspi_context *nspi_ctx, TALLOC_CTX *mem_ctx, struct SPropTagArray *pPropTags, struct PropertyTagArray_r *MIds, uint32_t count, struct PropertyRowSet_r **ppRows)
_PUBLIC_ enum MAPISTATUS nspi_ResolveNames (struct nspi_context *nspi_ctx, TALLOC_CTX *mem_ctx, const char **usernames, struct SPropTagArray *pPropTags, struct PropertyRowSet_r ***pppRows, struct PropertyTagArray_r ***pppMIds)
_PUBLIC_ enum MAPISTATUS nspi_ResolveNamesW (struct nspi_context *nspi_ctx, TALLOC_CTX *mem_ctx, const char **usernames, struct SPropTagArray *pPropTags, struct PropertyRowSet_r ***pppRows, struct PropertyTagArray_r ***pppMIds)
_PUBLIC_ enum MAPISTATUS nspi_ResortRestriction (struct nspi_context *nspi_ctx, TALLOC_CTX *mem_ctx, enum TableSortOrders SortType, struct PropertyTagArray_r *pInMIds, struct PropertyTagArray_r **ppMIds)
_PUBLIC_ enum MAPISTATUS nspi_SeekEntries (struct nspi_context *nspi_ctx, TALLOC_CTX *mem_ctx, enum TableSortOrders SortType, struct PropertyValue_r *pTarget, struct SPropTagArray *pPropTags, struct PropertyTagArray_r *pMIds, struct PropertyRowSet_r **pRows)
_PUBLIC_ enum MAPISTATUS nspi_unbind (struct nspi_context *nspi_ctx)
_PUBLIC_ enum MAPISTATUS nspi_UpdateStat (struct nspi_context *nspi_ctx, TALLOC_CTX *mem_ctx, uint32_t *plDelta)

Detailed Description

Name Service Provider (NSPI) stack functions.

Function Documentation

_PUBLIC_ struct nspi_context* nspi_bind ( TALLOC_CTX *  parent_ctx,
struct dcerpc_pipe *  p,
struct cli_credentials *  cred,
uint32_t  codepage,
uint32_t  language,
uint32_t  method 
)
read

Initiates a session between a client and the NSPI server.

Parameters
parent_ctxpointer to the memory context
ppointer to the DCERPC pipe
credpointer to the user credentials
codepagethe code to set in the STAT structure
languagethe language to set in the STAT structure
methodthe method to set in the STAT structure
Returns
Allocated pointer to a nspi_context structure on success, otherwise NULL
_PUBLIC_ enum MAPISTATUS nspi_CompareMIds ( struct nspi_context *  nspi_ctx,
TALLOC_CTX *  mem_ctx,
uint32_t  MId1,
uint32_t  MId2,
uint32_t *  plResult 
)

Compares the position in an address book container of two objects identified by MId and returns the value of the comparison

Parameters
nspi_ctxpointer to the NSPI connection context
mem_ctxpointer to the memory context
MId1the first MId to compare
MId2the second MId to compare
plResultpointer to the value of the comparison
Returns
MAPI_E_SUCCESS on success, otherwise MAPI error.
int nspi_disconnect_dtor ( void *  data)

Destructor for the NSPI context. Call the NspiUnbind function.

Parameters
datageneric pointer to data with mapi_provider information
Returns
MAPI_E_SUCCESS on success, otherwise MAPI error.

References nspi_unbind().

Referenced by MapiLogonProvider().

_PUBLIC_ enum MAPISTATUS nspi_DNToMId ( struct nspi_context *  nspi_ctx,
TALLOC_CTX *  mem_ctx,
struct StringsArray_r *  pNames,
struct PropertyTagArray_r **  ppMIds 
)

Maps a set of DN to a set of MId

Parameters
nspi_ctxpointer to the NSPI connection context
mem_ctxpointer to the memory context
pNamespointer to a StringsArray_r structure with the DN to map
ppMIdspointer on pointer to the returned list of MIds
Returns
MAPI_E_SUCCESS on success, otherwise MAPI error

Referenced by GetABRecipientInfo(), and ProcessNetworkProfile().

_PUBLIC_ enum MAPISTATUS nspi_GetIDsFromNames ( struct nspi_context *  nspi_ctx,
TALLOC_CTX *  mem_ctx,
bool  VerifyNames,
uint32_t  cNames,
struct PropertyName_r *  ppNames,
struct SPropTagArray **  ppPropTags 
)

Retrieve the Property IDs associated with property names from the NSPI server.

Parameters
nspi_ctxpointer on the NSPI connection context
mem_ctxpointer to the memoty context
VerifyNamesboolean value defining whether the NSPI server must verify that all client specified names are recognized by the server
cNamescount of PropertyName_r entries
ppNamespointer to a PropertyName_r structure with the list of property tags supplied by the client
ppPropTagspointer on pointer to the list of proptags returned by the server
Returns
MAPI_E_SUCCESS on success, otherwise MAPI error
_PUBLIC_ enum MAPISTATUS nspi_GetMatches ( struct nspi_context *  nspi_ctx,
TALLOC_CTX *  mem_ctx,
struct SPropTagArray *  pPropTags,
struct Restriction_r *  Filter,
uint32_t  ulRequested,
struct PropertyRowSet_r **  ppRows,
struct PropertyTagArray_r **  ppOutMIds 
)

Returns an explicit table.

Parameters
nspi_ctxpointer to the NSPI connection context
mem_ctxpointer to the memory context
pPropTagspointer to an array of property tags of columns
Filterpointer to the Restriction to apply to the table
ulRequestedThe upper limit for returned rows
ppRowspointer to pointer to a SRowSet structure holding the rows returned by the server
ppOutMIdspointer to pointer to a list of MId that comprise a restricted address book container
Returns
MAPI_E_SUCCESS on success, otherwise MAPI error. If the resulting table rows count will be greater than ulRequested, then an error MAPI_E_TABLE_TOO_BIG is returned. Note, this error can be also returned when server limits for table size are exceeded.

Referenced by DuplicateProfile(), and ProcessNetworkProfile().

_PUBLIC_ enum MAPISTATUS nspi_GetNamesFromIDs ( struct nspi_context *  nspi_ctx,
TALLOC_CTX *  mem_ctx,
struct FlatUID_r *  lpGuid,
struct SPropTagArray *  pPropTags,
struct SPropTagArray **  ppReturnedPropTags,
struct PropertyNameSet_r **  ppNames 
)

Returns a list of property names for a set of proptags

Parameters
nspi_ctxpointer on the NSPI connection text
mem_ctxpointer to the memory context
lpGuidthe property set about which the client is requesting information
pPropTagspointer to the proptags list
ppReturnedPropTagspointer on pointer to the list of all the proptags in the property set specified in lpGuid
ppNamespointer on pointer to the list of property names returned by the server
Returns
MAPI_E_SUCCESS on success, otherwise MAPI error
_PUBLIC_ enum MAPISTATUS nspi_GetPropList ( struct nspi_context *  nspi_ctx,
TALLOC_CTX *  mem_ctx,
bool  WantObject,
uint32_t  dwMId,
struct SPropTagArray **  ppPropTags 
)

Returns a list of all the properties that have values on the specified object

Parameters
nspi_ctxpointer to the NSPI connection context
mem_ctxpointer to the memory context
WantObjectboolean value defining whether we want the server to include properties with the type set to PT_OBJECT
dwMIdthe MId of the specified object
ppPropTagspointer on pointer to the list of property tags associated to the object.
Returns
MAPI_E_SUCCESS on success, otherwise MAPI error.
_PUBLIC_ enum MAPISTATUS nspi_GetProps ( struct nspi_context *  nspi_ctx,
TALLOC_CTX *  mem_ctx,
struct SPropTagArray *  pPropTags,
struct PropertyTagArray_r *  MId,
struct PropertyRowSet_r **  SRowSet 
)

Returns an address book row containing a set of the properties and values that exists on an object

Parameters
nspi_ctxpointer to the NSPI connection context
mem_ctxpointer to the memory context
pPropTagspointer to the list of property tags that the client wants to be returned
MIdpointer to the MId of the record
SRowSetpointer on pointer to the row returned by the server
Returns
MAPI_E_SUCCESS on success, otherwise MAPI error

Referenced by GetABRecipientInfo(), and ProcessNetworkProfile().

_PUBLIC_ enum MAPISTATUS nspi_GetSpecialTable ( struct nspi_context *  nspi_ctx,
TALLOC_CTX *  mem_ctx,
uint32_t  Type,
struct PropertyRowSet_r **  ppRows 
)

Returns the rows of a special table to the client. The special table can be a Hierarchy Table or an Address Creation Table

Parameters
nspi_ctxpointer to the NSPI connection context
mem_ctxpointer to the memory context
Typebitmap of flags defining the type of the special table
ppRowspointer on pointer to the rows returned by the server

Possible values for Type:

  1. NspiAddressCreationTemplates to access an Address Creation Table
  2. NspiUnicodeStrings for strings to be returned in Unicode

If NspiAddressCreationTemplates is not set, then NspiGetSpecialTable will automatically fetch the Hierarchy Table.

If NspiAddressCreationTemplates is set, then NspiUnicodeStrings is ignored.

Returns
MAPI_E_SUCCESS on success, otherwise MAPI error.

Referenced by DuplicateProfile(), and ProcessNetworkProfile().

_PUBLIC_ enum MAPISTATUS nspi_GetTemplateInfo ( struct nspi_context *  nspi_ctx,
TALLOC_CTX *  mem_ctx,
uint32_t  dwFlags,
uint32_t  ulType,
char *  pDN,
struct PropertyRow_r **  ppData 
)

Returns information about template objects in the address book.

Parameters
nspi_ctxpointer to the NSPI memory context
mem_ctxpointer to the memory context
dwFlagsset of bit flags
ulTypespecifies the display type of the template
pDNthe DN of the template requested
ppDatapointer on pointer to the data requested

Possible values for dwFlags:

  1. TI_TEMPLATE to return the template
  2. TI_SCRIPT to return the script associated to the template
  3. TI_EMT to return the e-mail type associated to the template
  4. TI_HELPFILE_NAME to return the help file associated to the template
  5. TI_HELPFILE_CONTENTS to return the contents of the help file associated to the template
    Returns
    MAPI_E_SUCCESS on success, otherwise MAPI error.
_PUBLIC_ enum MAPISTATUS nspi_ModLinkAtt ( struct nspi_context *  nspi_ctx,
bool  Delete,
uint32_t  ulPropTag,
uint32_t  MId,
struct BinaryArray_r *  lpEntryIds 
)

Modifies the values of a specific property of a specific row in the address book. This function only applies only to rows that support the PT_OBJECT Property Type.

Parameters
nspi_ctxpointer to the NSPI connection context
Deleteboolean value defining whether the server must remove all values specified by the input parameter lpEntryIDs from the property specified by ulPropTag
ulPropTagproperty tag of the property the client wishes to modify
MIdthe MId of the address book object
lpEntryIdsarray of BinaryArray_r structures intended to be modified or deleted
Returns
MAPI_E_SUCCESS on success, otherwise MAPI error
_PUBLIC_ enum MAPISTATUS nspi_ModProps ( struct nspi_context *  nspi_ctx,
TALLOC_CTX *  mem_ctx,
uint32_t  MId,
struct SPropTagArray *  pPropTags,
struct PropertyRow_r *  pRow 
)

Modify the properties of an object in the address book

Parameters
nspi_ctxpointer to the NSPI connection context
mem_ctxpointer to the memory context
MIdthe MId of the address book object
pPropTagspointer to the list of properties to be modified on the object
pRowContains an address book row
Returns
MAPI_E_SUCCESS on success, otherwise MAPI error
_PUBLIC_ enum MAPISTATUS nspi_QueryColumns ( struct nspi_context *  nspi_ctx,
TALLOC_CTX *  mem_ctx,
bool  WantUnicode,
struct SPropTagArray **  ppColumns 
)

Returns a list of all the properties the NSPI server is aware off.

Parameters
nspi_ctxpointer to the NSPI connection context
mem_ctxpointer to the memory context
WantUnicodewhether we want UNICODE properties or not
ppColumnspointer on pointer to a property tag array
Returns
MAPI_E_SUCCESS on success, otherwise MAPI error.
_PUBLIC_ enum MAPISTATUS nspi_QueryRows ( struct nspi_context *  nspi_ctx,
TALLOC_CTX *  mem_ctx,
struct SPropTagArray *  pPropTags,
struct PropertyTagArray_r *  MIds,
uint32_t  count,
struct PropertyRowSet_r **  ppRows 
)

Returns a number of Rows from a specified table.

Parameters
nspi_ctxpointer to the NSPI connection context
mem_ctxpointer to the memory context
pPropTagspointer to the list of proptags that the client requires to be returned for each row.
MIdspointer to a list of values representing an Explicit table
countthe number of rows requested
ppRowspointer on pointer to the the rows returned by the server
Returns
MAPI_E_SUCCESS on success, otherwise MAPI error

Referenced by GetGALTable(), GetGALTableCount(), and ProcessNetworkProfile().

_PUBLIC_ enum MAPISTATUS nspi_ResolveNames ( struct nspi_context *  nspi_ctx,
TALLOC_CTX *  mem_ctx,
const char **  usernames,
struct SPropTagArray *  pPropTags,
struct PropertyRowSet_r ***  pppRows,
struct PropertyTagArray_r ***  pppMIds 
)

Takes a set of string values in an 8-bit character set and performs ANR on those strings

Parameters
nspi_ctxpointer on the NSPI connection context
mem_ctxpointer to the memory context
usernamespointer on pointer to the list of values we want to perform ANR on
pPropTagspointer on the property tags list we want for each row returned
pppRowspointer on pointer on pointer to the rows returned by the server
pppMIdspointer on pointer on pointer to the MIds matching the array of strings
Returns
MAPI_E_SUCCESS on success, otherwise MAPI error

Referenced by ResolveNames().

_PUBLIC_ enum MAPISTATUS nspi_ResolveNamesW ( struct nspi_context *  nspi_ctx,
TALLOC_CTX *  mem_ctx,
const char **  usernames,
struct SPropTagArray *  pPropTags,
struct PropertyRowSet_r ***  pppRows,
struct PropertyTagArray_r ***  pppMIds 
)

Takes a set of string values in the Unicode character set and performs ambiguous name resolution (ANR) on those strings

Parameters
nspi_ctxpointer on the NSPI connection context
mem_ctxpointer to the memory context
usernamespointer on pointer to the list of values we want to perform ANR on
pPropTagspointer on the property tags list we want for each row returned
pppRowspointer on pointer on pointer to the rows returned by the server
pppMIdspointer on pointer on pointer to the MIds matching the array of strings
Returns
MAPI_E_SUCCESS on success, otherwise MAPI error

Referenced by ResolveNames().

_PUBLIC_ enum MAPISTATUS nspi_ResortRestriction ( struct nspi_context *  nspi_ctx,
TALLOC_CTX *  mem_ctx,
enum TableSortOrders  SortType,
struct PropertyTagArray_r *  pInMIds,
struct PropertyTagArray_r **  ppMIds 
)

Applies a sort order to the objects in a restricted address book container

Parameters
nspi_ctxpointer to the NSPI connection context
mem_ctxpointer to the memory context
SortTypethe table sort order to use
pInMIdspointer on a list of MIds that comprise a restricted address book container
ppMIdspointer on pointer to the returned list of MIds that comprise a restricted address book container.

SortType can take the following values:

  1. SortTypeDisplayName
  2. SortTypePhoneticDisplayName
Returns
MAPI_E_SUCCESS on success, otherwise MAPI error
_PUBLIC_ enum MAPISTATUS nspi_SeekEntries ( struct nspi_context *  nspi_ctx,
TALLOC_CTX *  mem_ctx,
enum TableSortOrders  SortType,
struct PropertyValue_r *  pTarget,
struct SPropTagArray *  pPropTags,
struct PropertyTagArray_r *  pMIds,
struct PropertyRowSet_r **  pRows 
)

Searches for and sets the logical position in a specific table to the first entry greater than or equal to a specified value. Optionally, it might also return information about rows in the table.

Parameters
nspi_ctxpointer to the NSPI connection context
mem_ctxpointer to the memory context
SortTypethe table sort order to use
pTargetPropertyValue_r struct holding the value being sought
pPropTagspointer to an array of property tags of columns that the client wants to be returned for each row returned.
pMIdspointer to a list of Mid that comprise a restricted address book container
pRowspointer to pointer to a SRowSet structure holding the rows returned by the server

SortType can take the following values:

  1. SortTypeDisplayName
  2. SortTypePhoneticDisplayName

If pTarget property tag is not set accordingly to SortType, the function returns MAPI_E_INVALID_PARAMETER. Possible values are:

  1. SortType set to SortTypeDisplayName and pTarget property tag set to PR_DISPLAY_NAME or PR_DISPLAY_UNICODE
  2. SortType set to SortTypePhoneticDisplayName and pTarget property tag set to PR_EMS_AB_PHONETIC_DISPLAY_NAME or PR_EMS_AB_PHONETIC_DISPLAY_NAME_UNICODE
Returns
MAPI_E_SUCCESS on success, otherwise MAPI error
_PUBLIC_ enum MAPISTATUS nspi_unbind ( struct nspi_context *  nspi_ctx)

Destroys the context handle

Parameters
nspi_ctxpointer to the NSPI connection context
Returns
return 1 on success or 2 if the input context is NULL

Referenced by nspi_disconnect_dtor().

_PUBLIC_ enum MAPISTATUS nspi_UpdateStat ( struct nspi_context *  nspi_ctx,
TALLOC_CTX *  mem_ctx,
uint32_t *  plDelta 
)

Updates the STAT block representing position in a table to reflect positioning changes requested by the client.

Parameters
nspi_ctxpointer to the NSPI connection context
mem_ctxpointer to the memory context
plDeltapointer to an unsigned long indicating movement within the address book container specified by the input parameter pStat.
Returns
MAPI_E_SUCCESS on success, otherwise MAPI error

Creative Commons License
Creative Commons Attribution icon Creative Commons Share Alike icon
This content is licensed under the Creative Commons
Attribution ShareAlike License v. 3.0:
http://creativecommons.org/licenses/by-sa/3.0/

openchange-2.0/apidocs/html/libmapi/open.png000066400000000000000000000001731223057412600211370ustar00rootroot00000000000000‰PNG  IHDR à‘BIDATxíÝÁ €0 Ð׬ՙ\Àº€39—b!©9{|ðI>$#Àß´ý8/¨ÄØzƒ/Ï>2À[ÎgiU,/¬~¼Ï\ Ä9Ù¸IEND®B`‚openchange-2.0/apidocs/html/libmapi/pages.html000066400000000000000000000046441223057412600214640ustar00rootroot00000000000000 MAPIClientLibraries 2.0 API Documentation
Related Pages
Here is a list of all related documentation pages:

Creative Commons License
Creative Commons Attribution icon Creative Commons Share Alike icon
This content is licensed under the Creative Commons
Attribution ShareAlike License v. 3.0:
http://creativecommons.org/licenses/by-sa/3.0/

openchange-2.0/apidocs/html/libmapi/pixel_grey.gif000066400000000000000000000000531223057412600223230ustar00rootroot00000000000000GIF89a€îîî!ù,D;openchange-2.0/apidocs/html/libmapi/property_8c.html000066400000000000000000001374551223057412600226520ustar00rootroot00000000000000 MAPIClientLibraries 2.0 API Documentation
property.c File Reference

Functions for manipulating MAPI properties. More...

#include "libmapi/libmapi.h"
#include "libmapi/libmapi_private.h"

Functions

_PUBLIC_ uint32_t cast_mapi_SPropValue (TALLOC_CTX *mem_ctx, struct mapi_SPropValue *mapi_sprop, struct SPropValue *sprop)
_PUBLIC_ void cast_PropertyRow_to_SRow (TALLOC_CTX *mem_ctx, struct PropertyRow_r *proprow, struct SRow *srow)
_PUBLIC_ void cast_PropertyRowSet_to_SRowSet (TALLOC_CTX *mem_ctx, struct PropertyRowSet_r *prowset, struct SRowSet *srowset)
_PUBLIC_ void cast_PropertyValue_to_SPropValue (struct PropertyValue_r *propvalue, struct SPropValue *spropvalue)
_PUBLIC_ uint32_t cast_SPropValue (TALLOC_CTX *mem_ctx, struct mapi_SPropValue *mapi_sprop, struct SPropValue *sprop)
_PUBLIC_ struct
AddressBookEntryId * 
get_AddressBookEntryId (TALLOC_CTX *mem_ctx, struct Binary_r *bin)
_PUBLIC_ struct FolderEntryId * get_FolderEntryId (TALLOC_CTX *mem_ctx, struct Binary_r *bin)
_PUBLIC_ struct GlobalObjectId * get_GlobalObjectId (TALLOC_CTX *mem_ctx, struct Binary_r *bin)
_PUBLIC_ struct MessageEntryId * get_MessageEntryId (TALLOC_CTX *mem_ctx, struct Binary_r *bin)
_PUBLIC_ struct PtypServerId * get_PtypServerId (TALLOC_CTX *mem_ctx, struct Binary_r *bin)
_PUBLIC_ struct RecurrencePattern * get_RecurrencePattern (TALLOC_CTX *mem_ctx, struct Binary_r *bin)
_PUBLIC_ struct TimeZoneStruct * get_TimeZoneStruct (TALLOC_CTX *mem_ctx, struct Binary_r *bin)
_PUBLIC_ const char * get_TypedString (struct TypedString *tstring)
size_t get_utf8_utf16_conv_length (const char *inbuf)
_PUBLIC_ void mapi_copy_spropvalues (TALLOC_CTX *mem_ctx, struct SPropValue *source_values, struct SPropValue *dest_values, uint32_t count)
_PUBLIC_ enum MAPISTATUS PropertyRow_addprop (struct PropertyRow_r *aRow, struct PropertyValue_r propValue)
_PUBLIC_ uint32_t PropertyRowSet_propcpy (TALLOC_CTX *mem_ctx, struct PropertyRowSet_r *RowSet, struct PropertyValue_r value)
_PUBLIC_ struct SPropTagArray * set_SPropTagArray (TALLOC_CTX *mem_ctx, uint32_t PropCount,...)
_PUBLIC_ enum MAPISTATUS SPropTagArray_add (TALLOC_CTX *mem_ctx, struct SPropTagArray *SPropTagArray, enum MAPITAGS aulPropTag)
_PUBLIC_ enum MAPISTATUS SPropTagArray_delete (TALLOC_CTX *mem_ctx, struct SPropTagArray *SPropTagArray, uint32_t aulPropTag)
_PUBLIC_ enum MAPISTATUS SPropTagArray_find (struct SPropTagArray SPropTagArray, enum MAPITAGS aulPropTag, uint32_t *propIdx)
_PUBLIC_ enum MAPISTATUS SRow_addprop (struct SRow *aRow, struct SPropValue spropvalue)
_PUBLIC_ uint32_t SRowSet_propcpy (TALLOC_CTX *mem_ctx, struct SRowSet *SRowSet, struct SPropValue spropvalue)

Detailed Description

Functions for manipulating MAPI properties.

Function Documentation

_PUBLIC_ uint32_t cast_mapi_SPropValue ( TALLOC_CTX *  mem_ctx,
struct mapi_SPropValue *  mapi_sprop,
struct SPropValue *  sprop 
)

Convenience function to convert a SPropValue structure into a mapi_SPropValue structure and return the associated size.

Parameters
mem_ctxpointer to the memory context to use for allocation
mapi_sproppointer to the MAPI SPropValue structure to copy data to
sproppointer to the SPropValue structure to copy data from
Returns
size of the converted data on success, otherwise 0

References get_utf8_utf16_conv_length().

Referenced by ModifyRecipients(), SetPropertiesNoReplicate(), and SetProps().

_PUBLIC_ void cast_PropertyRow_to_SRow ( TALLOC_CTX *  mem_ctx,
struct PropertyRow_r *  proprow,
struct SRow *  srow 
)

Convenience function to convert a PropertyRow_r structure into a SRow structure.

Parameters
mem_ctxpointer to the allocation context for structure members
proprowpointer to the PropertyRow_r structure to copy data to
srowpointer to the SRow structure to copy data from

References cast_PropertyValue_to_SPropValue().

Referenced by cast_PropertyRowSet_to_SRowSet().

_PUBLIC_ void cast_PropertyRowSet_to_SRowSet ( TALLOC_CTX *  mem_ctx,
struct PropertyRowSet_r *  prowset,
struct SRowSet *  srowset 
)

Convenience function to convert a PropertyRowSet_r structure into a SRowSet structure.

Parameters
mem_ctxpointer to the allocation context for structure members
prowsetpointer to the PropertyRowSet_r structure to copy data to
setrowsetpointer to the SRowSet structure to copy data from

References cast_PropertyRow_to_SRow().

_PUBLIC_ void cast_PropertyValue_to_SPropValue ( struct PropertyValue_r *  propvalue,
struct SPropValue *  spropvalue 
)

Convenience function to convert a PropertyValue_r structure into a SPropValue structure.

Parameters
propvaluepointer to the PropertyValue_r structure to copy data to
spropvaluepointer to the SPropValue structure to copy data from

Referenced by cast_PropertyRow_to_SRow().

_PUBLIC_ uint32_t cast_SPropValue ( TALLOC_CTX *  mem_ctx,
struct mapi_SPropValue *  mapi_sprop,
struct SPropValue *  sprop 
)

Convenience function to convert a mapi_SPropValue structure into a SPropValue structure and return the associated size

Parameters
mem_ctxpointer to the memory context to use for allocation
mapi_sproppointer to the MAPI SPropValue structure to copy data from
sproppointer to the SPropValue structure to copy data to
Returns
size of the converted data on success, otherwise 0

References get_utf8_utf16_conv_length().

_PUBLIC_ struct AddressBookEntryId* get_AddressBookEntryId ( TALLOC_CTX *  mem_ctx,
struct Binary_r *  bin 
)
read

Retrieve a AddressBookEntryId structure from a binary blob

Parameters
mem_ctxpointer to the memory context
binpointer to the Binary_r structure with raw AddressBookEntryId data
Returns
Allocated AddressBookEntryId structure on success, otherwise NULL
Note
Developers must free the allocated AddressBookEntryId when finished.
_PUBLIC_ struct FolderEntryId* get_FolderEntryId ( TALLOC_CTX *  mem_ctx,
struct Binary_r *  bin 
)
read

Retrieve a FolderEntryId structure from a binary blob

Parameters
mem_ctxpointer to the memory context
binpointer to the Binary_r structure with raw FolderEntryId data
Returns
Allocated FolderEntryId structure on success, otherwise NULL
Note
Developers must free the allocated FolderEntryId when finished.
_PUBLIC_ struct GlobalObjectId* get_GlobalObjectId ( TALLOC_CTX *  mem_ctx,
struct Binary_r *  bin 
)
read

Retrieve a GlobalObjectId structure from a binary blob

Parameters
mem_ctxpointer to the memory context
binpointer to the Binary_r structure with raw GlobalObjectId data
Returns
Allocated GlobalObjectId structure on success, otherwise NULL
Note
Developers must free the allocated GlobalObjectId when finished.
_PUBLIC_ struct MessageEntryId* get_MessageEntryId ( TALLOC_CTX *  mem_ctx,
struct Binary_r *  bin 
)
read

Retrieve a MessageEntryId structure from a binary blob

Parameters
mem_ctxpointer to the memory context
binpointer to the Binary_r structure with raw MessageEntryId data
Returns
Allocated MessageEntryId structure on success, otherwise NULL
Note
Developers must free the allocated MessageEntryId when finished.
_PUBLIC_ struct PtypServerId* get_PtypServerId ( TALLOC_CTX *  mem_ctx,
struct Binary_r *  bin 
)
read

Retrieve a PtypServerId structure from a binary blob

Parameters
mem_ctxpointer to the memory context
binpointer to the Binary_r structure with raw PtypServerId data
Returns
Allocated PtypServerId structure on success, otherwise NULL
Note
Developers must free the allocated PtypServerId when finished.
_PUBLIC_ struct RecurrencePattern* get_RecurrencePattern ( TALLOC_CTX *  mem_ctx,
struct Binary_r *  bin 
)
read

Retrieve a RecurrencePattern structure from a binary blob

Parameters
mem_ctxpointer to the memory context
binpointer to the Binary_r structure with non-mapped reccurrence data
Returns
Allocated RecurrencePattern structure on success, otherwise NULL
Note
Developers must free the allocated RecurrencePattern when finished.
_PUBLIC_ struct TimeZoneStruct* get_TimeZoneStruct ( TALLOC_CTX *  mem_ctx,
struct Binary_r *  bin 
)
read

Retrieve a TimeZoneStruct structure from a binary blob

Parameters
mem_ctxpointer to the memory context
binpointer to the Binary_r structure with raw TimeZoneStruct data
Returns
Allocated TimeZoneStruct structure on success, otherwise NULL
Note
Developers must free the allocated TimeZoneStruct when finished.
_PUBLIC_ const char* get_TypedString ( struct TypedString *  tstring)

Return the effective value used in a TypedString structure.

Parameters
tstringpointer to TypedString structure
Returns
pointer to a valid string on success, otherwise NULL

Referenced by OpenMessage().

size_t get_utf8_utf16_conv_length ( const char *  inbuf)

Return the expected size of the utf8 string after conversion to utf16 by iconv() function.

Parameters
inbufpointer to the input string
Returns
expected length of the converted string
Note
This routine is based upon utf8_pull() function from samba4/lib/util/charset/iconv.c

Referenced by cast_mapi_SPropValue(), cast_SPropValue(), CopyFolder(), CreateFolder(), GetIDsFromNames(), mapi_nameid_canonical_add(), mapi_nameid_custom_string_add(), mapi_nameid_lid_add(), mapi_nameid_OOM_add(), mapi_nameid_string_add(), ModifyRecipients(), and MoveFolder().

_PUBLIC_ void mapi_copy_spropvalues ( TALLOC_CTX *  mem_ctx,
struct SPropValue *  source_values,
struct SPropValue *  dest_values,
uint32_t  count 
)

Convenience function to copy an array of struct SPropValue or a part thereof into another array, by duplicating and properly parenting pointer data. The destination array is considered to be preallocated.

_PUBLIC_ enum MAPISTATUS PropertyRow_addprop ( struct PropertyRow_r *  aRow,
struct PropertyValue_r  propValue 
)

add a PropertyValue_r structure to a PropertyRow_r array

Parameters
aRowpointer to the PropertyRow_r array where propValue should be appended
propValuethe PropertyValue_r structure to add to aRow
Returns
MAPI_E_SUCCESS on success, otherwise MAPI_E_INVALID_PARAMETER.
_PUBLIC_ uint32_t PropertyRowSet_propcpy ( TALLOC_CTX *  mem_ctx,
struct PropertyRowSet_r *  RowSet,
struct PropertyValue_r  value 
)

Append a PropertyValue_r structure to given PropertyRowSet_r

Parameters
mem_ctxpointer to the memory context
RowSetpointer to the PropertyRowSet_r array to update
valuethe PropertyValue_r to append within SRowSet
Returns
0 on success, otherwise 1
_PUBLIC_ struct SPropTagArray* set_SPropTagArray ( TALLOC_CTX *  mem_ctx,
uint32_t  PropCount,
  ... 
)
read

Create a property tag array

Parameters
mem_ctxtalloc memory context to use for allocation
PropCountthe number of properties in the array

The varargs (the third and subsequent arguments) are the property tags to make up the array. So the normal way to use this to create an array of two tags is like:

struct SPropTagArray *array
array = set_SPropTagArray(mem_ctx, 2, PR_ENTRYID, PR_DISPLAY_NAME);
Examples:
fetchappointment.c, and fetchmail.c.

Referenced by AddUserPermission(), DuplicateProfile(), EntryIDFromSourceIDForMessage(), GetABRecipientInfo(), GetBestBody(), GetFolderItemsCount(), GetUserFreeBusyData(), ModifyUserPermission(), ProcessNetworkProfile(), and RemoveUserPermission().

_PUBLIC_ enum MAPISTATUS SPropTagArray_add ( TALLOC_CTX *  mem_ctx,
struct SPropTagArray *  SPropTagArray,
enum MAPITAGS  aulPropTag 
)

Add a property tag to an existing properties array

Parameters
mem_ctxtalloc memory context to use for allocation
SPropTagArrayexisting properties array to add to
aulPropTagthe property tag to add
Returns
MAPI_E_SUCCESS on success, otherwise MAPI error.
Note
Possible MAPI error codes are:
  • MAPI_E_NOT_INITIALIZED: MAPI subsystem has not been initialized
  • MAPI_E_INVALID_PARAMETER: SPropTagArray parameter is not correctly set

Referenced by OpenEmbeddedMessage(), OpenMessage(), and ReloadCachedInformation().

_PUBLIC_ enum MAPISTATUS SPropTagArray_delete ( TALLOC_CTX *  mem_ctx,
struct SPropTagArray *  SPropTagArray,
uint32_t  aulPropTag 
)

Delete a property tag from an existing properties array

Parameters
mem_ctxtalloc memory context to use for allocation
SPropTagArrayexisting properties array to remove from
aulPropTagthe property tag to remove
Returns
MAPI_E_SUCCESS on success, otherwise MAPI error.
Note
Possible MAPI error codes are:
  • MAPI_E_NOT_INITIALIZED: MAPI subsystem has not been initialized
  • MAPI_E_INVALID_PARAMETER: SPropTagArray parameter is not correctly set
_PUBLIC_ enum MAPISTATUS SPropTagArray_find ( struct SPropTagArray SPropTagArray  ,
enum MAPITAGS  aulPropTag,
uint32_t *  propIdx 
)

Return the index of a property tag in an existing properties array

Parameters
SPropTagArrayexisting properties array to remove from
aulPropTagthe property tag to find
propIdxthe index of the found property (undefined when MAPI_E_NOT_FOUND is returned)
Returns
MAPI_E_SUCCESS on success, otherwise MAPI error.
Note
Possible MAPI error codes are:
  • MAPI_E_NOT_INITIALIZED: MAPI subsystem has not been initialized
  • MAPI_E_INVALID_PARAMETER: SPropTagArray parameter is not correctly set
_PUBLIC_ enum MAPISTATUS SRow_addprop ( struct SRow *  aRow,
struct SPropValue  spropvalue 
)

add a SPropValue structure to a SRow array

Parameters
aRowpointer to the SRow array where spropvalue should be appended
spropvaluereference to the SPropValue structure to add to aRow
Returns
MAPI_E_SUCCESS on success, otherwise MAPI_E_INVALID_PARAMETER.

Referenced by OpenEmbeddedMessage(), OpenMessage(), ReloadCachedInformation(), and SetRecipientType().

_PUBLIC_ uint32_t SRowSet_propcpy ( TALLOC_CTX *  mem_ctx,
struct SRowSet *  SRowSet,
struct SPropValue  spropvalue 
)

Append a SPropValue structure to given SRowSet

Parameters
mem_ctxpointer to the memory context
SRowSetpointer to the SRowSet array to update
spropvaluethe SPropValue to append within SRowSet
Returns
0 on success, otherwise 1

Creative Commons License
Creative Commons Attribution icon Creative Commons Share Alike icon
This content is licensed under the Creative Commons
Attribution ShareAlike License v. 3.0:
http://creativecommons.org/licenses/by-sa/3.0/

openchange-2.0/apidocs/html/libmapi/simple__mapi_8c.html000066400000000000000000000665651223057412600234270ustar00rootroot00000000000000 MAPIClientLibraries 2.0 API Documentation
simple_mapi.c File Reference

Convenience functions. More...

#include "libmapi/libmapi.h"
#include "libmapi/libmapi_private.h"

Functions

_PUBLIC_ enum MAPISTATUS AddUserPermission (mapi_object_t *obj_folder, const char *username, enum ACLRIGHTS role)
_PUBLIC_ enum MAPISTATUS GetBestBody (mapi_object_t *obj_message, uint8_t *format)
_PUBLIC_ enum MAPISTATUS GetDefaultFolder (mapi_object_t *obj_store, uint64_t *folder, const uint32_t id)
_PUBLIC_ enum MAPISTATUS GetDefaultPublicFolder (mapi_object_t *obj_store, uint64_t *folder, const uint32_t id)
_PUBLIC_ enum MAPISTATUS GetFolderItemsCount (mapi_object_t *obj_folder, uint32_t *unread, uint32_t *total)
_PUBLIC_ bool IsMailboxFolder (mapi_object_t *obj_store, uint64_t fid, uint32_t *olFolder)
_PUBLIC_ enum MAPISTATUS ModifyUserPermission (mapi_object_t *obj_folder, const char *username, enum ACLRIGHTS role)
_PUBLIC_ enum MAPISTATUS RemoveUserPermission (mapi_object_t *obj_folder, const char *username)

Detailed Description

Convenience functions.

Function Documentation

_PUBLIC_ enum MAPISTATUS AddUserPermission ( mapi_object_t *  obj_folder,
const char *  username,
enum ACLRIGHTS  role 
)

Adds permissions for a user on a given folder

Parameters
obj_folderthe folder we add permission for
usernamethe Exchange username we add permissions for
rolethe permission mask value

The following permissions and rights are supported:

  • RightsNone
  • RightsReadItems
  • RightsCreateItems
  • RightsEditOwn
  • RightsDeleteOwn
  • RightsEditAll
  • RightsDeleteAll
  • RightsCreateSubfolders
  • RightsFolderOwner
  • RightsFolderContact
  • RoleNone
  • RoleReviewer
  • RoleContributor
  • RoleNoneditingAuthor
  • RoleAuthor
  • RoleEditor
  • RolePublishAuthor
  • RolePublishEditor
  • RightsAll
  • RoleOwner
Returns
MAPI_E_SUCCESS on success, otherwise a failure code (MAPISTATUS) indicating the error.
Note
Developers may also call GetLastError() to retrieve the last MAPI error code. Possible MAPI error codes are:
  • MAPI_E_NOT_INITIALIZED: MAPI subsystem has not been initialized.
  • MAPI_E_INVALID_PARAMETER: username is NULL
See Also
ResolveNames, ModifyPermissions

References mapi_object_get_session(), MAPIFreeBuffer(), ModifyPermissions(), ResolveNames(), and set_SPropTagArray().

_PUBLIC_ enum MAPISTATUS GetBestBody ( mapi_object_t *  obj_message,
uint8_t *  format 
)

Implement the BestBody algorithm and return the best body content type for a given message.

Parameters
obj_messagethe message we find the best body for
formatthe format - see below.
Returns
MAPI_E_SUCCESS on success, otherwise MAPI_E_NOT_FOUND. If MAPI_E_NOT_FOUND is returned then format is set to 0x0 (undefined). If MAPI_E_SUCCESS is returned, then format can have one of the following values:
  • olEditorText: format is plain text
  • olEditorHTML: format is HTML
  • olEditorRTF: format is RTF

References GetProps(), mapi_object_get_session(), MAPIFreeBuffer(), and set_SPropTagArray().

_PUBLIC_ enum MAPISTATUS GetDefaultFolder ( mapi_object_t *  obj_store,
uint64_t *  folder,
const uint32_t  id 
)

Retrieves the folder id for the specified default folder in a mailbox store

Parameters
obj_storethe store to search
idthe type of folder to search for
folderthe resulting folder reference

The following types of folders are supported:

  • olFolderTopInformationStore
  • olFolderDeletedItems
  • olFolderOutbox
  • olFolderSentMail
  • olFolderInbox
  • olFolderCommonView
  • olFolderCalendar
  • olFolderContacts
  • olFolderJournal
  • olFolderNotes
  • olFolderTasks
  • olFolderDrafts
  • olFolderReminders
  • olFolderFinder

Note that this function will cache FID values for common accessed folders such as calendar, contact, journal, note, task and drafts until the store object got released.

Returns
MAPI_E_SUCCESS on success, otherwise a failure code (MAPISTATUS) indicating the error.
Note
Developers may also call GetLastError() to retrieve the last MAPI error code. Possible MAPI error codes are:
  • MAPI_E_NOT_INITIALIZED: MAPI subsystem has not been initialized.
  • MAPI_E_INVALID_PARAMETER: obj_store is undefined
  • MAPI_E_NOT_FOUND: The specified folder could not be found or is not yet supported.
See Also
MAPIInitialize, OpenMsgStore, GetLastError
Examples:
fetchappointment.c, and fetchmail.c.
_PUBLIC_ enum MAPISTATUS GetDefaultPublicFolder ( mapi_object_t *  obj_store,
uint64_t *  folder,
const uint32_t  id 
)

Retrieve the folder id for the specified default folder in a public folder store

Parameters
obj_storethe store to search
idthe type of folder to search for
folderthe resulting folder reference

The following types of folders are supported:

  • olFolderPublicRoot - the parent (directly or indirectly) for the folders below
  • olFolderPublicIPMSubtree - Interpersonal Messages (IPM) folders
  • olFolderPublicNonIPMSubtree - Non-interpersonal message folders
  • olFolderPublicEFormsRoot - EForms Registry Root Folder
  • olFolderPublicFreeBusyRoot - Free/busy root folder
  • olFolderPublicOfflineAB - Offline address book root folder
  • olFolderPublicEFormsRegistry - EForms Registry for the users locale
  • olFolderPublicLocalFreeBusy - Site local free/busy folders
  • olFolderPublicLocalOfflineAB - Site local Offline address book
  • olFolderPublicNNTPArticle - NNTP article index folder
Returns
MAPI_E_SUCCESS on success, otherwise a failure code (MAPISTATUS) indicating the error.
Note
Developers may also call GetLastError() to retrieve the last MAPI error code. Possible MAPI error codes are:
  • MAPI_E_NOT_INITIALIZED: MAPI subsystem has not been initialized.
  • MAPI_E_INVALID_PARAMETER: obj_store is undefined
  • MAPI_E_NOT_FOUND: The specified folder could not be found or is not yet supported.
See Also
MAPIInitialize, OpenPublicFolder, GetLastError

Referenced by GetUserFreeBusyData().

_PUBLIC_ enum MAPISTATUS GetFolderItemsCount ( mapi_object_t *  obj_folder,
uint32_t *  unread,
uint32_t *  total 
)

Retrieves the total and unread number of items for a specified folder.

Parameters
obj_folderthe folder to get item counts for
unreadthe number of items in the folder (result)
totalthe number of items in the folder, including unread items (result)
Returns
MAPI_E_SUCCESS on success, otherwise a failure code (MAPISTATUS) indicating the error.
Note
Developers may also call GetLastError() to retrieve the last MAPI error code. Possible MAPI error codes are:
  • MAPI_E_NOT_INITIALIZED: MAPI subsystem has not been initialized.
  • MAPI_E_INVALID_PARAMETER: obj_folder is undefined
  • MAPI_E_NOT_FOUND: The specified folder could not be found or is not yet supported.
See Also
MAPIInitialize, OpenFolder, GetLastError

References GetProps(), mapi_object_get_session(), MAPIFreeBuffer(), and set_SPropTagArray().

_PUBLIC_ bool IsMailboxFolder ( mapi_object_t *  obj_store,
uint64_t  fid,
uint32_t *  olFolder 
)

Check if a given folder identifier matches with a system/default one and optionally returns the olFolder type

Parameters
obj_storepointer to the store object
fidreference to the folder identifier to check
olFolderpointer to the returned olFolder
Returns
true on success, otherwise false
_PUBLIC_ enum MAPISTATUS ModifyUserPermission ( mapi_object_t *  obj_folder,
const char *  username,
enum ACLRIGHTS  role 
)

Modify permissions for a user on a given folder

Parameters
obj_folderthe folder to modify permissions for
usernamethe Exchange username to modify permissions for
rolethe permission mask value (see AddUserPermission)
Returns
MAPI_E_SUCCESS on success, otherwise a failure code (MAPISTATUS) indicating the error.
Note
Developers may also call GetLastError() to retrieve the last MAPI error code. Possible MAPI error codes are:
  • MAPI_E_NOT_INITIALIZED: MAPI subsystem has not been initialized.
  • MAPI_E_INVALID_PARAMETER: username is NULL
  • MAPI_E_NOT_FOUND: couldn't find or change permissions for the given user
See Also
AddUserPermission, ResolveNames, GetPermissionsTable, ModifyPermissions

References GetPermissionsTable(), mapi_object_get_session(), mapi_object_init(), mapi_object_release(), MAPIFreeBuffer(), ModifyPermissions(), QueryPosition(), QueryRows(), ResolveNames(), set_SPropTagArray(), and SetColumns().

_PUBLIC_ enum MAPISTATUS RemoveUserPermission ( mapi_object_t *  obj_folder,
const char *  username 
)

Remove permissions for a user on a given folder

Parameters
obj_folderthe folder to remove permission from
usernamethe Exchange username to remove permissions for
Returns
MAPI_E_SUCCESS on success, otherwise a failure code (MAPISTATUS) indicating the error.
Note
Developers may also call GetLastError() to retrieve the last MAPI error code. Possible MAPI error codes are:
  • MAPI_E_NOT_INITIALIZED: MAPI subsystem has not been initialized.
  • MAPI_E_INVALID_PARAMETER: username or obj_folder are NULL
  • MAPI_E_NOT_FOUND: couldn't find or remove permissions for the given user
See Also
ResolveNames, GetPermissionsTable, ModifyPermissions

References GetPermissionsTable(), mapi_object_get_session(), mapi_object_init(), mapi_object_release(), MAPIFreeBuffer(), ModifyPermissions(), QueryPosition(), QueryRows(), ResolveNames(), set_SPropTagArray(), and SetColumns().


Creative Commons License
Creative Commons Attribution icon Creative Commons Share Alike icon
This content is licensed under the Creative Commons
Attribution ShareAlike License v. 3.0:
http://creativecommons.org/licenses/by-sa/3.0/

openchange-2.0/apidocs/html/libmapi/structmapi__obj__bookmark.html000066400000000000000000000046511223057412600255730ustar00rootroot00000000000000 MAPIClientLibraries 2.0 API Documentation
mapi_obj_bookmark Struct Reference

IMAPITable object. More...

#include <mapi_object.h>

Detailed Description

IMAPITable object.


The documentation for this struct was generated from the following file:
  • libmapi/mapi_object.h

Creative Commons License
Creative Commons Attribution icon Creative Commons Share Alike icon
This content is licensed under the Creative Commons
Attribution ShareAlike License v. 3.0:
http://creativecommons.org/licenses/by-sa/3.0/

openchange-2.0/apidocs/html/libmapi/structmapi__obj__store.html000066400000000000000000000046411223057412600251210ustar00rootroot00000000000000 MAPIClientLibraries 2.0 API Documentation
mapi_obj_store Struct Reference

IMsgStore object. More...

#include <mapi_object.h>

Detailed Description

IMsgStore object.


The documentation for this struct was generated from the following file:
  • libmapi/mapi_object.h

Creative Commons License
Creative Commons Attribution icon Creative Commons Share Alike icon
This content is licensed under the Creative Commons
Attribution ShareAlike License v. 3.0:
http://creativecommons.org/licenses/by-sa/3.0/

openchange-2.0/apidocs/html/libmapi/sync_off.png000066400000000000000000000015251223057412600220060ustar00rootroot00000000000000‰PNG  IHDRàw=øIDATxíÝKhTWÀñÿä1I&3™8M¦Iš™†I3Ú©b$cÌ I1V1±-(Tö±±Ð.* t!‚K[¥Ä¥ˆ„¨´f£`l(øl©"Y”¤6ÆgÌTú}·sgîܹ ±d{8?æÌ¹÷;çÜuíÚ`:!±F¬¢BäŠ?ŰÄm'yÊÅ>ÑlU¯½üý‰è_‹?€Œê ]€Y(ŠNñ±8fý1°Öqún-eâ¨øtºmâÈ Ó0}b›ù%·©µ×Œ®=Ÿ0´³?Š1sŸ‹0€¯8À‘;_ ‹W|%\ Zð— >舽ln¨p©.aÇ{ )t;Ú b nŸš¯›65°¢¡2çÅÔ?Žž>Oдàuönm¤¢Ì`×­Z¬WjC~>‘Ö¾0+á {{©fÝ×Mæ·æÅ•ìÙ¼˜` Ý›%uA6´½ÅÆö¨Á,]k¢ÄW¼™u±›]‹ˆ7§¯iòh€ ¶¶¬ÏÖu1 ló —Ҷ̺–:ÞÍ\ÄcãÏxøhR²Êè‡Qt$¿ß§¨ ª fdºü<4BÿÙ[•f¸d7=.Mé9/—éªÃëù/ÿO Üaàò}€,‘j?Ÿõ.5Úšm?œÿŸ®ŽXÿ2¬#¸d píæ(£?cÛú¼!½›a1¥Þ—ŽòØ©ܾ7dÔK:‚ùÒ‰ì)Ê3‚Ü™àÌà]€,±H€µ+køöäu<|`·LhC7¹ÔeÍ Ÿ×Ÿ˜tÜ‹ óH$^2%l.êaeÐäýE”ÌÉ|ÅÜìî‰Ýsä }¸ýDû^hzé~ðR›¦Ã¡¿]|#ü¯@×—Ö‡[k¹–<|š(Ç*€Ý¹dÇtMé:Ýñø«Ø,êÅû¢]”' øXÓ_nò¡Æ|Øý /c§fžâOIEND®B`‚openchange-2.0/apidocs/html/libmapi/sync_on.png000066400000000000000000000015151223057412600216470ustar00rootroot00000000000000‰PNG  IHDRàw=øIDATxíÝ_HTYÀñï8ã¤ó§i§4-g6ÆËÕ&kQ)¨Ô!Š0ÒURKÚ…„ê¡/»PEÁ>ìK-+KÁ²Ñ.Y”¾dEPaA‰ø°¥¶›ZSÓïÜ;3wºŠ–¯—߯gfîïœsçœWKÇñ.€ÉøD­¨a‘'¬âq_ôˆk¢ÀŒ ÀDŽøQ´ÄïC¨¶åñÏÿgÅ ñ 0„Y‚:qZ¦Á)~õâ€èLý0HVñ× žz-¿‰C“%¨g¦˜6€é8%Úõ¬ëwêÙUÏ¿˜ª³Ä }? ?€·3ÀÀž©Š À”K• @hà a±ðaÇæUe‹ sù~ë2²ì“&Ú&B*AÄljæºììi*˨,Ëçí»÷oÆ£T”,d[˜¼3-*ÁÀ…>å‡Ë çLÉŸçfk˜Ò éw#*AEjKUy>ûšËÉõ&{µ¢8—m5Ki¬ jjƒD*¿NŽÖigwÃ7Dª’mz骹úKÛ¾±ˆ¶M!æ¤ÍkÐ?šoý¬_åÓlXí#Ò~–¸¬ê×ÒÑXŠÓ‘ùRÙ*Eû‚ՂדðEÜ;6«e"Q(²Ù=–¿Ezæ5Kؼָ_ 1òzBªJë ±XŒì96åªjL^7{ùãJÑ÷1½i@%8'7M©_\Qœ#ÓUŒËñýÿyõ Wo Éx8¼s¥v¯ªì|×SnÜ q_m Ýé î>bèÕí[JX,½4[Tú{R£ë¼ôˆ¾þa€tÝjjzzÅ'ÅìȶiIžŽòwÏs ¡€—ÕKøõâC^ŽŒ˜Y­¨µÉ%6¨´êˆº]vÛðhâ½iWv–hôëê°Ò¨¾'æÌ‚·ñ|[ßìúÅ^€YrD=<ýDû]äÇ÷s€Ïõ‹8™ºCì? À ¨—t4õᩎ¡Jã‡W‹É± îr¼cjMɘìx| šE©øNÔ‰œøA¢þ«–€Z¼ñ‡jó î#™§¢¢4gIEND®B`‚openchange-2.0/apidocs/html/libmapi/tab_a.png000066400000000000000000000002161223057412600212420ustar00rootroot00000000000000‰PNG  IHDR$ÇÇ[UIDATxíK €0C'o¤(Šˆ[Žà%Üxÿ#Ù©­ç ùÁöó¦W¦e# 3t I 3+¼øEã~\D½9¯Ûàè’wM·¿öÿ}Yõ_êA4Yžã}IEND®B`‚openchange-2.0/apidocs/html/libmapi/tab_b.png000066400000000000000000000002471223057412600212470ustar00rootroot00000000000000‰PNG  IHDR$ÇÇ[nIDATxíÝQ Â0„áàœR¥Xc±I7IÓ¨g|òÕÙœäãgY˜3˜Ï÷‡u{£ÔW—ÊSíŒ1Ü ¼CjˆiC†G¬ýççJ+| ÖÝs7ùŒ+Ù›`t‚3Ü‚a¢K¤Gq°ûQÍZÝT=@*éC݇LIEND®B`‚openchange-2.0/apidocs/html/libmapi/tab_h.png000066400000000000000000000003001223057412600212430ustar00rootroot00000000000000‰PNG  IHDR$ÇÇ[‡IDATxíÝË ‚@EÑ 7êÂX’Ñø AADùjGü€ Z€e؈£ ë8¹›—Wƒx¾ÞìUK.µ%„0mɤ&+4iÑ$džÈt“׿ÍzWf5AZá'w¼øÆ"2¶Wœðòg%öªdæ)æþ™ÉR15F®dìž ÉБßO«×Áô»C"à@¯g=IEND®B`‚openchange-2.0/apidocs/html/libmapi/tab_s.png000066400000000000000000000002701223057412600212640ustar00rootroot00000000000000‰PNG  IHDR$ÇÇ[IDATxíÝ ‚@@Ñ£?Q…¤"š¢%¦I‘—Šf–6[´HÃäQƒ<Þâõþ]ždr Í’s?ˆO=Ñññw'ÌF‡Ž íðö-~rÃ[œèŠ­ì¬mƒÖ¬ƒݯнŠÕF)Yº% §`nÌ,9B ™’©!ÑŒ\ý<Å#üîî•IEND®B`‚openchange-2.0/apidocs/html/libmapi/tabs.css000066400000000000000000000022131223057412600211300ustar00rootroot00000000000000.tabs, .tabs2, .tabs3 { background-image: url('tab_b.png'); width: 100%; z-index: 101; font-size: 13px; font-family: 'Lucida Grande',Geneva,Helvetica,Arial,sans-serif; } .tabs2 { font-size: 10px; } .tabs3 { font-size: 9px; } .tablist { margin: 0; padding: 0; display: table; } .tablist li { float: left; display: table-cell; background-image: url('tab_b.png'); line-height: 36px; list-style: none; } .tablist a { display: block; padding: 0 20px; font-weight: bold; background-image:url('tab_s.png'); background-repeat:no-repeat; background-position:right; color: #283A5D; text-shadow: 0px 1px 1px rgba(255, 255, 255, 0.9); text-decoration: none; outline: none; } .tabs3 .tablist a { padding: 0 10px; } .tablist a:hover { background-image: url('tab_h.png'); background-repeat:repeat-x; color: #fff; text-shadow: 0px 1px 1px rgba(0, 0, 0, 1.0); text-decoration: none; } .tablist li.current a { background-image: url('tab_a.png'); background-repeat:repeat-x; color: #fff; text-shadow: 0px 1px 1px rgba(0, 0, 0, 1.0); } openchange-2.0/apidocs/html/libmapi/utils_8c.html000066400000000000000000000156041223057412600221150ustar00rootroot00000000000000 MAPIClientLibraries 2.0 API Documentation
utils.c File Reference

General utility functions. More...

#include "libmapi/libmapi.h"
#include "libmapi/libmapi_private.h"

Functions

_PUBLIC_ enum MAPISTATUS EntryIDFromSourceIDForMessage (TALLOC_CTX *mem_ctx, mapi_object_t *obj_store, mapi_object_t *obj_folder, mapi_object_t *obj_message, struct SBinary_short *entryID)
_PUBLIC_ enum MAPISTATUS GetFIDFromEntryID (uint16_t cb, uint8_t *lpb, uint64_t parent_fid, uint64_t *fid)

Detailed Description

General utility functions.

Function Documentation

_PUBLIC_ enum MAPISTATUS EntryIDFromSourceIDForMessage ( TALLOC_CTX *  mem_ctx,
mapi_object_t *  obj_store,
mapi_object_t *  obj_folder,
mapi_object_t *  obj_message,
struct SBinary_short *  entryID 
)

Build an EntryID for message from folder and message source ID

References GetProps(), MAPIFreeBuffer(), and set_SPropTagArray().

_PUBLIC_ enum MAPISTATUS GetFIDFromEntryID ( uint16_t  cb,
uint8_t *  lpb,
uint64_t  parent_fid,
uint64_t *  fid 
)

Create a FID from an EntryID

Parameters
cbcount of lpb bytes
lpbpointer on an array of bytes
parent_fidthe parent folder identifier
fidpointer to the returned fid
Returns
MAPI_E_SUCCESS on success, otherwise MAPI_E_INVALID_PARAMETER

Creative Commons License
Creative Commons Attribution icon Creative Commons Share Alike icon
This content is licensed under the Creative Commons
Attribution ShareAlike License v. 3.0:
http://creativecommons.org/licenses/by-sa/3.0/

openchange-2.0/apidocs/html/libmapiadmin/000077500000000000000000000000001223057412600205005ustar00rootroot00000000000000openchange-2.0/apidocs/html/libmapiadmin/24px-Cc-by_white.svg.png000066400000000000000000000053061223057412600247400ustar00rootroot00000000000000‰PNG  IHDR°çá»bKGDÿÿÿÿÿÿ X÷Ü pHYsHHFÉk> IDATXýXmP”U¾vˆeY pW$gQH–%ãËc*$åÃIkFmiØ‘ttrê‡C öa3 Œc†D$ e¬±X, «@³ Â.Èîõþy›uÓ÷·÷úóÌœçÜϹîëºçÜç<þxHØNÛNÛN½+zWô®.–_,¿X|»æÛ5ß® Q†(C`4F#p×ý®û]w@qRqRqðÿÎÿ;ÿcaÇÂŽIÅIÅIÅ@˜$L&Ämâ6qÛòÀ‡Ä-í-í--ùVë[­oµ’ <. … ¡B¨øSRT(*’’IŽ$‡”æHs¤9¤S’S’S‰ð>°Ï÷ˆôˆôˆ$Óôiú4=Ù2Ú2Ú2JZ•V¥Uù`^‚û9À3<Ã3À7ýßôÓl?Ø~°¸ªºªºªœ‡œ‡œ‡€ 6Øpx&õ™ÔgR0—0—0ÀMá¦pSB©P*”–õ–õ–õ@²GÙ£šª›ª›ª¦mMÛš¶#êõˆðj÷j÷jöeïËÞ— äÎäÎäÎÒ^i¯´÷að£ýȳégÓϦ“K{–ö,í±+¦êRu©ºÈŠÎŠÎŠNòöÔí©ÛSë£sñsñsñd{^{^{™u%ëJÖÒÅÛÅÛÅ›IER‘”ÔìÕìÕì%ÇSÇSÇS~gAuuu¤|µ|µ|5)øJð•à+rGËŽ–-äÀ±cÇþs‚å)ËS–§ÈÒ-¥[J·ž»=w{î&µ‚ZA-™÷BÞ y/³£³£³£‹$psäæÈÍR•¨JT%ÚßñýŽïw|OšÌ&³Éü¿'þWX­ÖFòÔ“§ž<õ$é6â6â6Bºæ»æ»æ“ÕÕÕ÷&°Ÿû¹Ÿ<”p(áP‚xxQxQxyëÀ­·üóÄÿŠùçœÿ‘Ô®Ô®Ô®´óŠx.⹈çÈÁÎÁÎÁN7ŽÜ8rã¹æÙ5Ï®y–tŠwŠwŠ'+++ÿÿÄÿŠã€qÀH¿üzðë¤(H$ "‹4Eš" ) ø0àÀ:³ñÌÆ3··7à é é  pNwNwN¦º¦º¦º€ZS­©Ö\K¹–r-èÎíÎíΆg†g†gOgOgOgÀ˜bL1¦õâzq½XÒ·¤oI SÊ”2%033TÿQýGõ€h§h§h'àëëkßdÜÜÝÜÝ܉sç&Î õ õ õÀ¸iÜ4n°uÕÖU[WÙ-*4š ©õ^^^r¹Ãr‡å¤S•S•SéêêJºMºMºM’»rwåîÊ%ûûûIE¤"RIîÙ¼góžÍäÜÆ¹sÉý'öŸØ‚”'Êå‰dÛ–¶-m[îï„N£Óè4¤ÇÛo{¼MŠä"¹HN {]z]z]Ñ:Ñ:Ñ:@¥T)UÊE¶Û!q¸k¾k¾k2e™²LÐÛÛ ¤½Ÿö~ÚûÀ¥ÉK“—&ÿVÿVÿV c.c.c¨­­Ê®•]+»œK>—|.ˆÔDj"5@[t[t[4 _ª_ª_ºpýÕΫW;>Y>Y>Y€õwëïÖ߈§ÄSâ)R'‰“Ä‘Í7›o6ß\¨€Ál0̤¼SÞ)ï$ƒR‚R‚RÈ—3_Î|9“ô³øYü,dÒ¤I7H‹ŸÅÏâGöÕôÕôÕAùAùAù¤Ä 1H dÈùó!çɲÀ²À²@R\".—Å?ÿTüÓÂõïîîÈ(×(×(W{Åç:æ:æ:¡£ÐQèˆÒDi¢´E:žAª U L©§ÔSj`$a$a$pLvLvL†¶mÚ VVV~‰~‰~‰À®_wýºëWÀrÄrÄrÈPf(3”ÀóåÏ—?_|ôÉGŸ|ô ·!nC܆E–o4 šQ¨(Tj*ŠÅŠb`V2+™•o‹·Å{±– ‚€5Ôj Ò­éÖt+P¡þBý ðzáõÂë@÷+ݯt¿èôú{x`c`c`#à~Úý´ûi À` °K>_òù’ϵ«ÚUí È5r\³È!2Ï–g˦ççÃïy}9úrôe»%%×K®—\_¤„ú }†>R!UHRò1ŸÇ|ó!ãZãZãZIe´2ZM.»³ìβ;d{{{¿=¾á†7Þ =.x\ð¸@Ö)ë”uJ²¥­¥­¥\öȲG–=B~œúqêÇ‹z²{²{²Iß}¾û|÷ÝSBª¯U_«¾¶'ÔTßTßTÌý6÷ÛÜoöqéyéyéyàÅÒK_,ÔoªßT¿ xj=µžZ F#‘'kOÖž¬B2B2B2ìñò+ò+ò+ÀK›^ÚôÒ&@Þ!ïw2³Ì,3¿Düñ  ($ ÉBt't't'€Á̓›7+›V6­lÐÜÜL>ŠGñ(Hï×¼_ó~¼úóÕŸ¯þ|5¬a iK±¥ØRH[€-À@Ú²mÙ¶l’{¸‡{þ¦#íænî&mkmkmkIÆ1Žq$ýéOÒ*° ¬Òö¥íKÛ—ö°™’™’™2ùpòáäÃvås r r H˜½Ì^f/r[Ö¶¬mYö Y]Y]Y]¤ùóæþávû7¨\W¹®r)žψgHŸ­>[}¶’º]‰®äžÃ\K]K]KéuÉë’×%Rü©øSñ§di|i|i#FQ`$c¼b¼b¼ÈŽ‹;.Þ_€^êg3f3f3Èʵ•k+×’êUêUêU¤Ãr‡åËIÇq'=4 ¹~lýØú12*+*+*‹ŒÍÍÍ'Ueª2Uéû®ï»¾ï’!!!v¥W„­[FjõZ½VO' ' '<ØÁ‡þ+ñ'†††È¢²¢²¢22\® ב2™ƒÌNèAOßbßbßb2Ç%Ç%Ç…ÔéuzžœŸŸx>ÿ^5¡–ü+^:tEXtComment Created with Inkscape (http://www.inkscape.org/) ã+ldIEND®B`‚openchange-2.0/apidocs/html/libmapiadmin/24px-Cc-sa_white.svg.png000066400000000000000000000053061223057412600247310ustar00rootroot00000000000000‰PNG  IHDR°çá»bKGDÿÿÿÿÿÿ X÷Ü pHYsHHFÉk> IDATXÕX}LÓW>¿ ´–.Ôb±‚" Cèê(lS„9ÉuN&n ʹŒ,+&+™“à&3[a`Ë$™ãs‰3Ö¨L(ŠX¸Åñá¬EÄ4ElK¡åyÿy÷–¼µ/¾çŸ›ÜsŸsžûœÓ{· þmô”¶ðà?¬Y3²†èBý…ú õD—7\ÞpyÑpâpâp"‘Ñh4DóÏÌ?3ÿ QPmPmP-QØoa¿…ýFw"îDÜ ¢ŒÊŒÊŒJ¢8n7ŽKäwÃï†ß§eCDxJ3›ŠMÅÀgW?»úÙU ‚‰`"€Ä bý#À>Ê>Ê> p ¸Ü€WÀ+àË3–g,Ïèú†¾q¯Ø°%` ===è&tº ÀéŠtE.Í‹ñVœÁœ!ºxçâ‹wˆ>5|jøÔ@Ô#ë‘õȈ|Ç|Ç|Lj^,z±èÅ"¢m»·íÞ¶›(Žljãùùù±x,‹G4;;K499IÔÞÚÞÚÞJÔ¾§}Oû"s‚9Áœ@$4 BQa~a~a>Ñ!Û!Û!o„7Âyš ¬Çz¬ßi|§ñ`ÕЪ¡UCnÅdý²~Y?ÐÔ×Ô×ÔLÍLÍLÍÂGø8¶ãØŽc;ÜÄãËãËãËS‘©ÈTäxÏ®ž]=»€Wv^Ùy´ Z­SÏÔ3õ‹~Ü&¶‰mÄ_‰¿ ;v( 05›šMÍžqÝÎng7P¼¶xmñZwœ—^éõ—^îõÝë»×Ð`é`é`)°áµ ¯mx Xž²äeò2y™'ñA„ B”ØJl%6 nUݪºU€*Z­ŠÄÄÄ“Ïä3€å[Ë·–o½ãq·qØkÝkÝkõl¥ÏÕŸ«?W{Â?~< $®H\‘¸Â½Þg®w®w®—ˆ³Œ³Œ³ŒˆÍÎfgQuQ—§¯È_‘¿"'Ò˜5f™Hë¯õ×úûëØ_Çþ"âïçïçïÿß.ëi=­'ò©õ©õ©õtϧϧϧ{Î3LÓAÄ–²¥l)éHG:"VPePeP%‘ƒëà:¸D³³³ÞóOØ'ìv¢Õ©«SW§åìËÙ—³È,7ËÍr"G…£ÂQá?—7—7—G4ùóäÏ“?{ú\WÀõœ_P-¨TDÖxk¼5~‘ckçÖέî’TýQõGÕÞ;à|Öù¬óY@ÀÉ€“'Þ:Þ:Þ:@œ&N§cccÞñÝ‚nA·ý$úIô“;/š?ÍŸtƒºAÝN¡¡ü¡ü¡| ¤0¤0¤pQë}RôIÑ'¯³¾ÎúpŒ9ÆO 2Z3Z3ZÄŒ9s㇓w%ïJ޴ŶŶÅwDwDwDÀÅ÷/¾ñ}`Ëw[¾Ûò'îÍóožó<`}×ú®õ]ϼgfÏÌž™XZ––¥Ö¶¯m_ÛP‡¤CÒ!$ ~ø!ÐógÏŸ=zW²V]«®Uœ:N§n¡(Š¢(À?Ê?Ê? Í Í Íxž…gñ$ê u…º€®³]g»Îzæ±UÙªlU€¼D^"/Yto¨ Ôj€ìB»Ð.ö(ö(ö(Ü ýŠ~E?`ï²wÙ»<;„¡ChÞм¡y±D,ë 7ò¬V +Ø”»)wS.pI}I}Ií]¨æèæèæhÀÏægó³Á™Á™Á™€¾J_¥¯Zô1§Óê´:- ¼"¼"¼ø}ï÷½ß÷@uJuJu àZp-¸<8wþîü0ì7ì7ìJ5¥šR ùwæß™ÛÓ·§oOÞî|»óíNà”ñ”ñ”ý–ý€~@Äì‹Ù³Ï-@qqq?° ].HmÀ5åšrMǧOŸXm¬6V°²deÉÊàtÆéŒÓ€óWç¯Î_½'F ZÐ8ßs¾ç|˜+Ÿ+Ÿ+\®W€ILbÒ;ü¦ô¦ô¦ØÜ°¹asƒ›xÒñ¤ãIÇñeãËÆ—¹×{¼   ¥F©QjV:+•ð[ø-ü@=®W÷ÎÝ;wïÜÒ„–2[Ž-Ç–4O7O7O76nlt—<”<”<zózózó<ñ^ßÄ–dK²%PVVx¾<_ž/À\b.1—I¶$[’ |Éÿ’ÿ%Ðwê;õÀdÅdÅd` ³†YÃk‹µÅÚÌlÙ:³>0|`øP¯®W׫ù«òWå¯Ü:n·`ŒŒ‘1IÂ$a’è½Ð{¡÷‚w–|Ô;ö:ö:öÍÏ7?ßü<šš øˆ}Ä>b€4¤!   P(ØÉØÉØI Q‘¨HTÉG’$d5²Y r2ädÈIÀçŸ|^p+½&nMÜš8 x x xß1¾c|ÇÒ|ê%þ±±gÇž{(¯)¯)¯âõñúx=àÃ÷áûð—>…þC*C*C*N§€èôúÀ™âLq¦<=ŸYΧюéÈ:tEXtComment Created with Inkscape (http://www.inkscape.org/) ã+ldIEND®B`‚openchange-2.0/apidocs/html/libmapiadmin/CC_SomeRightsReserved.png000066400000000000000000000064521223057412600253460ustar00rootroot00000000000000‰PNG  IHDRZ¬a x pHYs  šœtIMEÕ ÌIðbKGDÿÿÿ ½§“ ·IDATx^í™iŒUEÇû¾{ßÚÝ6ë"²Š‚@!`˜DÇ¡Ä "Œ2 ×%Æ(ê—D£ñƒ1¨â’Œ@Pƒ¢HezXš¦é†¶~¯ßrç÷ïÜêyV¼ 1í„VòçÔz«þuêÔ¹÷9%¿Nr@$Bd\ºP¤Ç¤KˆÒ•HD€’È|² È h‘,Ò›= lœ)Ò›Íøí´2$Ù"ír«,n¤…˜Õ?À+B¸4d¤à `d‘ž—Þ†vL‘_‰h×&By#Äl ,‹OHIÚyû¤Ø°N‡¤g¡èäÒùnÑ‹0 g­Kë!í i6IÁ¶dËŠ…‚bÉFÝ?Ÿ-ÚŠ°áÙ–eÈO&“‰gŸ}vä–-[¦œ8qâŽ\.7çÌ™3Ó÷ìÙ3áý÷ß¿büøñÝdÉňÅb©Ç{lÐ÷ßÿ‡ãÇÏ ÏÜæææ¿8p`ÎòåË+§L™ÒËz– {®ƒö½´Ú?Å­cݦ[e‰â²áÇw]¶lÙ´¾}ûBfxrçfÞ_|±»bÅŠ!ƒ *ÿ}]xÍÒ’V™OŸï ¤­{–.¸Xrì“O>ù“!yûöí 7ß|óêT*õwÊÖ<óÌ3ûNž<™S]±%Óg˜!yóæÍM7ÞxãÚÒÒÒ¥lÀâW^yeÝéÓ§3ª3Ï q5nHÞÎW‹ŽXVœ ½ÄŒ/¾øâè|p¢Ø·o_ãСC¿J§Ó­‘ˆÁ€Ê>ûì³—^ziµÚÍŸ?¿âÕW_í!}çΧG޹9“ÉüÄZ9%.}*{öì¹ð,–kK»¬p>Z´‰s£[å6\ÉÊÊÊ¡f€—_~ù_±#“½{÷:|ÈlÒ­·ÞÚÁôyþùç Ù³ýð¶mÛÒ¼È ýG2$ïXh—äµ?Ñá °7£OŸ>ÝÍøéc¶»Q+êp±ú˜é³råÊûb³78¶ 1Ë@Îï8ڱɷõb²ñÑqÓøÈ‘#9Ûê‹`ÜI²¢¢¢mîÇŽioŠÉ ß\#C²†óÐu„è>ˆ„µÃU´˜L÷îÝcöÆXäy Ååè›>;wöl²Î‘<'l íî:|ßïÐ^ƒmܸÑûâ‹/R555‰£G&!#ÉÍŸjiiI€$~4‘ÍfS<3U(ù|>!YWW÷Ã%—\ÒScÜvÛm=Þyçã´ñ€ "À´a¤<²y×®]±Ñ£G»êsÓM7¥/^|š0γD"qd©)D£Ñ‚ëº>(ñ<Ï!ïÁD€KÄâ^pÁ^×®]½þýûGG»æšk²í壎hÿ—ì&t¯ºêªDÇŽSç/‰ü1Á DB„Cr²“È/ñï¾û®Ú=oÞ¼Á«V­Ú€•»l‚ ’ýnݺ9o½õVçIˆË}ùå—ˆ.UŸ‡z¨ÓºuëWsvIž€ï/ýõ×õÒò7òˆ|P"‚ãñx+ɉDB$ srª¢½{÷Ž:êtåI¿”§VKqöÆç>8dF°4Y³‡èä©S§â”'xÃK@r\0dƒ¸ÈfÑ©×^{m . \ãa_¸pa͆ 2eee¥×]w]§Ù³gwÁÚ´‘GÔF$}øá‡{õêå)_UUuúÍ7߬ٺuë:uÊOœ8±ãÔ©SB^ ‹ÿ+äf »b3œ¡:@†x= Ùiü~¦C‡é.]º¤ÙØ QN3ýE´c‘z.ût Ñã• 'ôÜwÒœC‡űæ8¯Ã²è˜ˆ†ä¸¬ZRD$Çò²êaX—ûî»od—…ÎÜ÷Kn¸á†ƒÈV]ÀêܧŸ~ºë…^;[Ÿ»îºk‘!¤A‹ò\ÂÑ­`#Óll Va61­S`Nz8ܧžzêrë±Ñ%amŠÛâE`)$¤°ž$H±¨V“ÿMqEJÒYd î¯]»¶™§Øƒÿ›P¨¯¯ÏàN¾ñÆGñë9Ú°´zvÍš5M¸™,㔀ˆéÓØØxŠ7ÌÚ?þx#d·@bIyy¹ƒŒX¯ "Pç"=ê$]¤GY4„#Ût›3ÆG;ç°3þ9„>>ĉ´$DuAZ ×!b£" –%G%!$J[å¥{HwQ © ô­KQÒEF°´¶èEV òëׯo¤_=$çØì2+ g±È,® Ɔ—°yÅ £ e¾Ñ6/ÊI?%&)’€hî£ëtt´^~ä}‘Œlõ딹ä[A>á’Q ’uZZ@–òlȧÒPÂmiÝ1”àp_ä‡í¤Êb<‘*²Ñ•$[‰ HÑ’Ê»"2% Éå!URd;"8€X³’¤A„ä—ä{$‘/QˆDIr³Áüäzb¤2«r…ƒg#ÖÒC91á]…UîôIaÖl„N^£+ŽÕÊÛˆ’Fò’&/˜ÐN1´¤±nG©Øª€acÝH§ØºE0R¹²æ"Œ/=t?´¡`.ÄšM:«±àDæÎ;ž[ÎsÏ=7’ ©O¿~ýoûh#Øåy›6mêÅGšÞ¯{T¦~Lêµ½þúë')o±^N})Ÿ9ï Þüî»ï*ÔJ¦HcÇŽ­ä¢Ià³Ëˆ›¯ tÅÇû¡„V1.¢èôéÓ/G÷„Ûo¿}0Ò%Vî?cÆŒA?üpß%K–t&Bé‡/¯Ï&JP[éJÖ¼ûþùç=xNœ‹-~íµ×þž—¡±<çwšÃK/½4Œ²Ê÷Þ{oëÓúèÞξ¥s eKu¤¦M›¶öJW;AþLõÒ L×°Œpn¹üŸ1WCBšèá«Ã‡¯¡,W]]ý-ñmý#zTܨêŠ]ª)ã›ù)Þ./“.‹Þüõ×_ïâm*Ë—³²œÊ£ó Ü|°wÑ¢E²¦¶zŽHžÎ°ÓÊÛàRÛ*ÿ©yŽì¼*^`ªd‘¼Ììfü<ñî>\×q^:²lÈA¬þ ãØ"H¯­­=Ì‹Pý ’K—.=¦·?Œ¢^yÕ ¤Z¾›R‘Ìiiâ µ«Ý¯2æšÁ5œàÌ.>­V3FÒªpaÛ5Oꛃµl1ëÓéxüñÇkUÆÿ’UãÆ;‰;Ép¯l ã@ÙŠèý úÉ'Ÿlš5kÖIÞós¼Å€”ê=zäT/BL;£•W Ê[¨D*ǹŽ;@ãÖæRúa&œƒ˜zȯg¬ßEØ€£ÒqeÇ8ÒÒ% I—ظ33gÎLKW½ú©þ»‰gæÉ7˜ñ±ò:=bk™GíO%ƒŽñ}CãÙQQ mEõLŽzÏÌ«LÏ4m!ÚçBup›)½ä´­Å¬¿ÃÊÇá.è7±ÏÅáCŒÏDýÝ»wûJøÈVië,ºµíœ9s|;Ùí¹©}.Ÿ”aŒ>dû,ÆçHZ}Btk¾çöL{®öv}ø8Òq¡¡˜²!C†ø&Lðq]¾DÿÊé7üFôÿÿj|w‚%&IEND®B`‚openchange-2.0/apidocs/html/libmapiadmin/annotated.html000066400000000000000000000045531223057412600233520ustar00rootroot00000000000000 libmapiadmin 2.0 API Documentation
Data Structures
Here are the data structures with brief descriptions:
\Cmapiadmin_ctxMAPI admin function context

Creative Commons License
Creative Commons Attribution icon Creative Commons Share Alike icon
This content is licensed under the Creative Commons
Attribution ShareAlike License v. 3.0:
http://creativecommons.org/licenses/by-sa/3.0/

openchange-2.0/apidocs/html/libmapiadmin/apidocs.css000066400000000000000000000362151223057412600226430ustar00rootroot00000000000000/* ** WEBSITE ** */ BODY,H1,H2,H3,H4,H5,H6,P,CENTER,TD,TH,UL,DL,DIV { font-family: Geneva, Arial, Helvetica, sans-serif; } BODY,TD { font-size: 90%; } H1 { text-align: center; font-size: 160%; } H2 { font-size: 19px; font-weight: bold; color: #3E93D5; } H3 { font-size: 100%; } P { text-align: justify; } LI { li-style-type: square; li-style-position: outside; display: list-item; } CAPTION { font-weight: bold } DIV.qindex { width: 100%; background-color: #e8eef2; border: 1px solid #84b0c7; text-align: center; margin: 2px; padding: 2px; line-height: 140%; } DIV.nav { width: 100%; background-color: #e8eef2; border: 1px solid #84b0c7; text-align: center; margin: 2px; padding: 2px; line-height: 140%; } DIV.navtab { background-color: #e8eef2; border: 1px solid #84b0c7; text-align: center; margin: 2px; margin-right: 15px; padding: 2px; } TD.navtab { font-size: 70%; } A.qindex { text-decoration: none; font-weight: bold; color: #1A419D; } A.qindex:visited { text-decoration: none; font-weight: bold; color: #1A419D } A.qindex:hover { text-decoration: none; background-color: #ddddff; } A.qindexHL { text-decoration: none; font-weight: bold; background-color: #6666cc; color: #ffffff; border: 1px double #9295C2; } A.qindexHL:hover { text-decoration: none; background-color: #6666cc; color: #ffffff; } A.qindexHL:visited { text-decoration: none; background-color: #6666cc; color: #ffffff } A.el { text-decoration: none; font-weight: bold } A.elRef { font-weight: bold } A.code:link { text-decoration: none; font-weight: normal; color: #0000FF} A.code:visited { text-decoration: none; font-weight: normal; color: #0000FF} A.codeRef:link { font-weight: normal; color: #0000FF} A.codeRef:visited { font-weight: normal; color: #0000FF} A:hover { text-decoration: none; background-color: #f2f2ff } DL.el { margin-left: -1cm } .fragment { font-family: monospace, fixed; font-size: 95%; } PRE.fragment { border: 1px solid #CCCCCC; background-color: #f5f5f5; font-size: 11px; margin-top: 4px; margin-bottom: 4px; margin-left: 2px; margin-right: 8px; padding-left: 6px; padding-right: 6px; padding-top: 4px; padding-bottom: 4px; } DIV.ah { background-color: black; font-weight: bold; color: #ffffff; margin-bottom: 3px; margin-top: 3px } DIV.groupHeader { margin-left: 16px; margin-top: 12px; margin-bottom: 6px; font-weight: bold; } DIV.groupText { margin-left: 16px; font-style: italic; font-size: 90% } BODY { background: white; color: black; margin-right: 20px; margin-left: 20px; } TD.indexkey { background-color: #e8eef2; font-weight: bold; padding-right : 10px; padding-top : 2px; padding-left : 10px; padding-bottom : 2px; margin-left : 0px; margin-right : 0px; margin-top : 2px; margin-bottom : 2px; border: 1px solid #CCCCCC; } TD.indexvalue { background-color: #e8eef2; font-style: italic; padding-right : 10px; padding-top : 2px; padding-left : 10px; padding-bottom : 2px; margin-left : 0px; margin-right : 0px; margin-top : 2px; margin-bottom : 2px; border: 1px solid #CCCCCC; } TR.memlist { background-color: #f0f0f0; } P.formulaDsp { text-align: center; } IMG.formulaDsp { } IMG.formulaInl { vertical-align: middle; } SPAN.keyword { color: #008000 } SPAN.keywordtype { color: #604020 } SPAN.keywordflow { color: #e08000 } SPAN.comment { color: #800000 } SPAN.preprocessor { color: #806020 } SPAN.stringliteral { color: #002080 } SPAN.charliteral { color: #008080 } .mdescLeft { padding: 0px 8px 4px 8px; font-size: 80%; font-style: italic; background-color: #FAFAFA; border-top: 1px none #E0E0E0; border-right: 1px none #E0E0E0; border-bottom: 1px none #E0E0E0; border-left: 1px none #E0E0E0; margin: 0px; } .mdescRight { padding: 0px 8px 4px 8px; font-size: 80%; font-style: italic; background-color: #FAFAFA; border-top: 1px none #E0E0E0; border-right: 1px none #E0E0E0; border-bottom: 1px none #E0E0E0; border-left: 1px none #E0E0E0; margin: 0px; } .memItemLeft { padding: 1px 0px 0px 8px; margin: 4px; border-top-width: 1px; border-right-width: 1px; border-bottom-width: 1px; border-left-width: 1px; border-top-color: #E0E0E0; border-right-color: #E0E0E0; border-bottom-color: #E0E0E0; border-left-color: #E0E0E0; border-top-style: solid; border-right-style: none; border-bottom-style: none; border-left-style: none; background-color: #FAFAFA; font-size: 80%; } .memItemRight { padding: 1px 8px 0px 8px; margin: 4px; border-top-width: 1px; border-right-width: 1px; border-bottom-width: 1px; border-left-width: 1px; border-top-color: #E0E0E0; border-right-color: #E0E0E0; border-bottom-color: #E0E0E0; border-left-color: #E0E0E0; border-top-style: solid; border-right-style: none; border-bottom-style: none; border-left-style: none; background-color: #FAFAFA; font-size: 80%; } .memTemplItemLeft { padding: 1px 0px 0px 8px; margin: 4px; border-top-width: 1px; border-right-width: 1px; border-bottom-width: 1px; border-left-width: 1px; border-top-color: #E0E0E0; border-right-color: #E0E0E0; border-bottom-color: #E0E0E0; border-left-color: #E0E0E0; border-top-style: none; border-right-style: none; border-bottom-style: none; border-left-style: none; background-color: #FAFAFA; font-size: 80%; } .memTemplItemRight { padding: 1px 8px 0px 8px; margin: 4px; border-top-width: 1px; border-right-width: 1px; border-bottom-width: 1px; border-left-width: 1px; border-top-color: #E0E0E0; border-right-color: #E0E0E0; border-bottom-color: #E0E0E0; border-left-color: #E0E0E0; border-top-style: none; border-right-style: none; border-bottom-style: none; border-left-style: none; background-color: #FAFAFA; font-size: 80%; } .memTemplParams { padding: 1px 0px 0px 8px; margin: 4px; border-top-width: 1px; border-right-width: 1px; border-bottom-width: 1px; border-left-width: 1px; border-top-color: #E0E0E0; border-right-color: #E0E0E0; border-bottom-color: #E0E0E0; border-left-color: #E0E0E0; border-top-style: solid; border-right-style: none; border-bottom-style: none; border-left-style: none; color: #606060; background-color: #FAFAFA; font-size: 80%; } .search { color: #003399; font-weight: bold; } FORM.search { margin-bottom: 0px; margin-top: 0px; } INPUT.search { font-size: 75%; color: #000080; font-weight: normal; background-color: #e8eef2; } TD.tiny { font-size: 75%; } a { color: #1A41A8; } a:visited { color: #2A3798; } .dirtab { padding: 4px; border-collapse: collapse; border: 1px solid #84b0c7; } TH.dirtab { background: #e8eef2; font-weight: bold; } HR { height: 1px; border: none; border-top: 1px solid black; margin-bottom: 50px; } /* Style for detailed member documentation */ .memtemplate { font-size: 80%; color: #606060; font-weight: normal; } .memnav { background-color: #e8eef2; border: 1px solid #84b0c7; text-align: center; margin: 2px; margin-right: 15px; padding: 2px; } .memitem { padding: 4px; background-color: white; border-width: 1px; border-style: solid; border-color: #ccc; -moz-border-radius: 8px 8px 8px 8px; margin-bottom: 30px; } .memname { white-space: nowrap; font-weight: bold; font-size: 12px; margin: 10px 10px 10px 10px; } .memname EM { color: #45417e; } .memdoc{ padding-left: 10px; padding-right: 10px; } .memdoc EM, TD { font-size: 12px; } .memproto { background-color: #e9e9f4; width: 100%; border-width: 1px; border-style: solid; border-color: #ccc; font-weight: bold; -moz-border-radius: 8px 8px 8px 8px; } .paramkey { text-align: right; } .paramtype { white-space: nowrap; } .paramname { color: #602020; font-style: italic; white-space: nowrap; } /* End Styling for detailed member documentation */ /* for the tree view */ .ftvtree { font-family: sans-serif; margin:0.5em; } .directory { font-size: 9pt; font-weight: bold; } .directory h3 { margin: 0px; margin-top: 1em; font-size: 11pt; } .directory > h3 { margin-top: 0; } .directory p { margin: 0px; white-space: nowrap; } .directory div { display: none; margin: 0px; } .directory img { vertical-align: -30%; } #website { width: 820px; height: 100%; margin-left: auto; margin-right: auto; text-align: left; /* IE hack */ * position: absolute; * left: 50%; * margin-left: -410px; } /* ** HEADER ** */ .header { height: 200px; background: url(header.jpg) no-repeat top center; } body { background: #fff url(body_top_bg2.jpg) top left repeat-x; font-family: Arial, Trebuchet MS, Tahoma, Verdana, Helvetica, sans-serif; font-size: 11px; line-height: 17px; color: #444; color: #3a3a3a; fdpadding-top: 15px; text-align: center; background-color: #fbfbfb; } h1 { font: 24px bold Trebuchet MS, Arial; color: #FFF; padding: 0; margin: 0; } /* ** MIDDLE SIDE ** */ #middle_side { display: block; height: 100%; width: 800px; margin-top: 7px; backsground: url(middle_bg.jpg) top left repeat-x; background-color: #fbfbfb; } /* left and right side */ #left_side { background-color: #fff; clear: both; margin-bottom: 10px; border-bottom: 1px solid #eee; border-left: 1px solid #eee; border-right: 1px solid #eee; -moz-border-radius: 0 0 8px 8px; height: 29px; } /* ** MENU HORIZONTAL ** */ /************ Global Navigation *************/ DIV.tabs { float : left; width : 100%; background : url("tab_b.gif") repeat-x bottom; margin-top : 10px; margin-bottom : 4px; } DIV.tabs ul { margin : 0px; padding-left : 10px; list-style : none; } DIV.tabs li { display : inline; margin : 0px; padding : 0px; } DIV.tabs A { float : left; background : url("tab_r.gif") no-repeat right top; border-bottom : 1px solid #84B0C7; font-size : x-small; font-weight : bold; text-decoration : none; } DIV.tabs A:link, .tabs A:visited, DIV.tabs A:active, .tabs A:hover { color: #1A419D; } DIV.tabs SPAN { float : left; display : block; background : url("tab_l.gif") no-repeat left top; padding : 5px 10px; white-space : nowrap; } DIV.tabs TD { font-size : x-small; font-weight : bold; text-decoration : none; } /* Commented Backslash Hack hides rule from IE5-Mac \*/ DIV.tabs SPAN {float : none;} /* End IE5-Mac hack */ DIV.tabs A:hover SPAN { background-position: 0% -150px; } DIV.tabs LI.current A { background-position: 100% -150px; border-width : 0px; } DIV.tabs LI.current SPAN { background-position: 0% -150px; padding-bottom : 6px; } DIV.nav { background : none; border : none; border-bottom : 1px solid #84B0C7; } #right_side_home { font-family: "Lucida Grande", Arial, Verdana, sans-serif; background-color: white; padding: 0px 20px; border: 1px solid #ebebeb; border: 1px solid #ddd; -moz-border-radius: 10px 10px; width: 750px; * width: 800px; * margin-left: 0px; padding-bottom: 10px; } #right_side_home td { line-height: 17px; margin: 0 0 5px 0; padding: 10px 0 15px 7px display: table-cell; border-spacing: 2px 2px; vertical-align: middle; text-align: left; border-bottom: 1px solid #EEEEEE; } #right_side_home td h2, a.anchor { font-size: 19px; font-weight: bold; color: #3E93D5; } #right_side_home td.indexkey { border-bottom: none; } #right_side_home li { list-style-position: inside; valign: middle; } TD.indexkey { background-color: #e8eef2; font-size : 12px; font-weight : bold; padding-right : 10px; padding-top : 2px; padding-left : 10px; padding-bottom : 2px; margin-left : 0px; margin-right : 0px; margin-top : 2px; margin-bottom : 2px; border : 1px solid #CCCCCC; } TD.indexvalue { background-color: #e8eef2; font-style : italic; font-size : 12px; padding-right : 10px; padding-top : 2px; padding-left : 10px; padding-bottom : 2px; margin-left : 0px; margin-right : 0px; margin-top : 2px; margin-bottom : 2px; border : 1px solid #CCCCCC; } TR.memlist { background-color: #f0f0f0; } .mdescLeft { padding: 0px 8px 4px 8px; font-size: 80%; font-style: italic; background-color: #FAFAFA; border-top: 1px none #E0E0E0; border-right: 1px none #E0E0E0; border-bottom: 1px none #E0E0E0; border-left: 1px none #E0E0E0; margin: 0px; } .mdescRight { padding: 0px 8px 4px 8px; font-size: 80%; font-style: italic; background-color: #FAFAFA; border-top: 1px none #E0E0E0; border-right: 1px none #E0E0E0; border-bottom: 1px none #E0E0E0; border-left: 1px none #E0E0E0; margin: 0px; } .memItemLeft { padding: 1px 0px 0px 8px; margin: 4px; border-top-width: 1px; border-right-width: 1px; border-bottom-width: 1px; border-left-width: 1px; border-top-color: #E0E0E0; border-right-color: #E0E0E0; border-bottom-color: #E0E0E0; border-left-color: #E0E0E0; border-top-style: solid; border-right-style: none; border-bottom-style: none; border-left-style: none; background-color: #FAFAFA; font-size: 80%; } .memItemRight { padding: 1px 8px 0px 8px; margin: 4px; border-top-width: 1px; border-right-width: 1px; border-bottom-width: 1px; border-left-width: 1px; border-top-color: #E0E0E0; border-right-color: #E0E0E0; border-bottom-color: #E0E0E0; border-left-color: #E0E0E0; border-top-style: solid; border-right-style: none; border-bottom-style: none; border-left-style: none; background-color: #FAFAFA; font-size: 80%; } .memTemplItemLeft { padding: 1px 0px 0px 8px; margin: 4px; border-top-width: 1px; border-right-width: 1px; border-bottom-width: 1px; border-left-width: 1px; border-top-color: #E0E0E0; border-right-color: #E0E0E0; border-bottom-color: #E0E0E0; border-left-color: #E0E0E0; border-top-style: none; border-right-style: none; border-bottom-style: none; border-left-style: none; background-color: #FAFAFA; font-size: 80%; } .memTemplItemRight { padding: 1px 8px 0px 8px; margin: 4px; border-top-width: 1px; border-right-width: 1px; border-bottom-width: 1px; border-left-width: 1px; border-top-color: #E0E0E0; border-right-color: #E0E0E0; border-bottom-color: #E0E0E0; border-left-color: #E0E0E0; border-top-style: none; border-right-style: none; border-bottom-style: none; border-left-style: none; background-color: #FAFAFA; font-size: 80%; } .memTemplParams { padding: 1px 0px 0px 8px; margin: 4px; border-top-width: 1px; border-right-width: 1px; border-bottom-width: 1px; border-left-width: 1px; border-top-color: #E0E0E0; border-right-color: #E0E0E0; border-bottom-color: #E0E0E0; border-left-color: #E0E0E0; border-top-style: solid; border-right-style: none; border-bottom-style: none; border-left-style: none; color: #606060; background-color: #FAFAFA; font-size: 80%; } code { display: block; width: 100%; border: 1px solid #ccc; background-color: #e8edf3; padding-top: 10px; padding-bottom: 10px; padding-left: 5px; padding-right: 5px; margin-bottom: 10px; margin-top: 10px; } openchange-2.0/apidocs/html/libmapiadmin/bc_s.png000066400000000000000000000012501223057412600221120ustar00rootroot00000000000000‰PNG  IHDR /ð9ÐoIDATxíMLAÇßìN»»¥ívKùPJik±R5^ŒChÂŃ!Dzƒ *U4VƒbÄD1~`8xà@ˆ^¿?ð𤡸Ý@јÝná`JLLÝØ¦ƒÜXi v«9ê)·}aV±&Ò0)›¼ð(‰zÛküNcFPÛù'@é¨KZK%!13§5£}Ý€ÒdÀã°’>´Åç´çhï¹G…ÉZ ïz×Ú—Éi£“ì–º=…@O¹«È‚1Ó¯¦3ãF«[ºä’d²¾JÒã`|^3˜Ý\›¿¡]²ó•'fçÓùyˆÄîçâÙ@¥Cos˧d:?$lhûnÝ× nm\†$cÔL6Ñý »Ì´x@N¦oPÀ®Î‘òÕ”€GÔ÷>9¹¨Q@ã±á“.‡qŠÜ´¼°Ø ”PCt(á«yŒQ$±°hÔNý8¤¥Ë MNjÿ$þßþŲo_ƒsLIEND®B`‚openchange-2.0/apidocs/html/libmapiadmin/bdwn.png000066400000000000000000000002231223057412600221350ustar00rootroot00000000000000‰PNG  IHDR5åZIDATxíË € DŸP–1ñlžmÀ r±j².e è†D[ØÉ¾ÙÏÔ¼µ¦ã´Þ|陣6€Všë3´Å?Ls'(}¬>+ žKó÷¥¿ch`‚ ^׃ÞnIEND®B`‚openchange-2.0/apidocs/html/libmapiadmin/body_top_bg2.jpg000066400000000000000000000006541223057412600235600ustar00rootroot00000000000000ÿØÿàJFIFddÿìDuckydÿîAdobedÀÿÛ„ÿÀ–ÿÄh að¡q‘QáR’¢ð!‘1aQÿÚ ?Ô¢±Õœ|W¼ í|ua³Dbe­‚hŒ*ø VÁ&ÅrV¹´,¸^Â-~TbÁÐéÊ—=©xj䮤*ÿRb²r %7L‘ñÜŠ¶5ø¦ èªÞV¶ ÿÙopenchange-2.0/apidocs/html/libmapiadmin/classes.html000066400000000000000000000050111223057412600230200ustar00rootroot00000000000000 libmapiadmin 2.0 API Documentation
Data Structure Index
  M  
mapiadmin_ctx   

Creative Commons License
Creative Commons Attribution icon Creative Commons Share Alike icon
This content is licensed under the Creative Commons
Attribution ShareAlike License v. 3.0:
http://creativecommons.org/licenses/by-sa/3.0/

openchange-2.0/apidocs/html/libmapiadmin/closed.png000066400000000000000000000002041223057412600224530ustar00rootroot00000000000000‰PNG  IHDR à‘KIDATxíÝm @!†ÑGk™É7À-`&séts¦Àñþòð@åk}ª2€… P%Á_Ëþ¿N² .:0Dk¥‹Â›x" Ö›)¡xÒ5õIEND®B`‚openchange-2.0/apidocs/html/libmapiadmin/dir_d980c21a0c021abaf50ffd6242df67be.html000066400000000000000000000064101223057412600270010ustar00rootroot00000000000000 libmapiadmin 2.0 API Documentation
libmapiadmin Directory Reference

Files

file  libmapiadmin-mainpage.doxy
file  libmapiadmin.h
 Structures for MAPI admin functions.
file  mapiadmin.c
 Housekeeping functions for mapiadmin.
file  mapiadmin_user.c
 User management functions for mapiadmin.

Creative Commons License
Creative Commons Attribution icon Creative Commons Share Alike icon
This content is licensed under the Creative Commons
Attribution ShareAlike License v. 3.0:
http://creativecommons.org/licenses/by-sa/3.0/

openchange-2.0/apidocs/html/libmapiadmin/doxygen.png000066400000000000000000000073031223057412600226660ustar00rootroot00000000000000‰PNG  IHDRh ;ˆØŠIDATxí]y\•Õº~45%TL Q”PE"q–Û11±]8a„w*©¨(*â" ˆzÀè`8 ¨‰¢mÅ,’òà„p$%”œBó(8k†Ü÷ýÜû6lòö»§k÷Ç÷[ÏÞß·Ö;?k½ëßÕÕÕPxÑêÏ't´ÏùÈ€zÀÇÅ3_€Q4€g@œmÿ ¾ò‰âci‰ôçÿ{ ðÇð¬ù~½Á€4:õHcÂü ðŸÁ³„ª'ÕPÆæ P7^h،♠zb„cóP¨„ 3‚† Ò}çÿO²qÁºNkÝTÛ(É?d Ç~z<’«4Óǡ؞Þv­zµÙ¦õ¬ZâdÛ,Ë6Ók±]Fz< ¾ZçƒsÕ?ìƒsUø2SÉåwê1”c`[ì—}%ѽ.Ô¼6‚BLZ˜û!F8[ ¹…×TéÛ— »Þ#gó]å:vžu?‡vèbÙR˜?wùŽŸ¾ÊÐgbÑÉÌÕ$kF~Ê;عÆ•¢ïX®?ÉèlÆÙôõà»Nʪ¼­,ìHC§gAz•ÆlÓº­gÑú ]œjÎñåM…3ÓÚæoÒ³'=‘$Ò÷f}G•ŸS_‡öèco.Êȹ :ó£ Ãds®Ù:1=¼{ƒå9?÷ý…zqÛvîÓi‰D’p¿Ë šmÙíoÛâýaÖüEqÒµwÌ}¿~{òj€ç{ôºŸFNëí[ëOq·ÇOSúXO]°>‚‚muæÄ¾e¤“5Ë{¨JÕ¯£(›´«bÂçû’ÍlÓÅ}žïú`éUÞy„ac§Á†ÔCºŠóAkl‘±y¥†ô¢ùôs÷Aø¬7ÄõôoJ±äÄ ù.¥Be. Z¬Ð×ÇÈöå¹­ù'Ù-PëìŠyF.ž‚žÝÚ€lp&.êˆð•jò7’re’z19»ã§HGíø%œüq°ïüz׈c¬_k_")ŸHJnÐÑ~ˆÐÖ˜á´äÕ5 µÁq€ÿ5#¸·îà¶+9T‘‚ ðŽ÷Rܸrz“Ï´Ì =Ï…{ðáO£Èf ¡Íwg|Ž’Ü/¢Þ$÷¯¢ëðúÀ;¿à¨Ö™âÒÆ­]¯ÜW"Þ/< ‡÷DÏà°½üB}çyIEc^—ƒ=[V“Ýh²ëMä$l];Kû®¸ýr¦È*Åò ÿtÒõ$]•MŸ÷´;×I€1èó!‚œõ¸M õ¨(fÌæ<ÁÎÎò5~z¿ù¶ž mÌêÕ >–âÚ©âëˆIÎÞçz;ãu[i·eç^ÆÜÙÓ³NÞëF6B\}7†»+üŽÓ,Ã'a ½˜-yHY¿,‘^—ñfú~ß?Hcø¸…¸ñó{Z+4\såƒû·¯Ù·nߣð«íFÆ¡sغëû§D¾?ò<–Ævkx0ÅM±ælذÁIÓxÿd”žÜÉ÷EE»AªM«g*È£YEí7Û™^[uíý®v[wGå†=Ed¼n×¶ÆæÖÅl¡'¨pGÚk+‹æ¢À¬¨C8ªâš2 dz3H£ß ¡¨BÒûSÃÅù[wŘ ~xpçútÁæmö¤Å£¥iQæ­‰AB1ÉfÙ‰›4u¹ïìIÒ]Ë6äò%ÿ†† 1t.’NJph¬zÌ ÎR1Ž"3-"¸‡‹&ìó°1âüžìó[:‡ï„¼‘……N m–“W0®_èÜœ ×õ6ùò&»)Æìꦬýæ}¬ñ~»{múù]z½£M•ºP~^Îá:eQTÙ_*7ÕÄ9É8—·Ëï 3°¶47E•î¿u÷“SÉ»U¯ _ NíºôW¬e¸ÄNÓ|»;™¿;ŒæÅd"ȉôøòÞµõï¾®½"èÄ´ÖMM+bYµ‘_ÉæEÝüÎ]P»¹XKÐI½Þ¥oE<_¹(„EP±Œ|mÇÁ¡‘Ý,ŠÓ©ººZ±Îߺ§×kÝ,kÍMš`Äø…jzeU»æ ™Át3ÓÀ½˜6—ÒöùË·r¨¹Ñ}““wö:Χùë¼ ¿|‚TܵÉQˆKßç_ÁâÀ™œ”pÑÐóໃ¼Ydâ0!®àa –øöçW$ÃÁ‘Á$/\¬$ð 2ÞímÞLH‹Ÿ èd£HVÜ,:ò½»RÍZšJ­a„z*>‹_…NT(ù‚^SVF­U¹8ñEþôñ܈óùnd;«®8™\C]ø=Èêm¬Æ:‚´ÆbãDd=Áãßžˆ‹UU5O‹|]þð®Pèêv‰á\]2ßìÿ"yÈ[ïyʧz£g{Y«{„Ùø5©ÿ;w{N3é­nâĨw§Á¢ÍK¢Ý­ûÏ29Id¿’ì y)ìPÞò8ŒÅ©¯‰±@mPÔñwjl,6 áhWÕ˜d öà uõmÁp®.™á£Ç…twöR x­BδYcŒxg*vo  yò‘•“[¬?ÜVœ˜0ÒN¡O난~Žó’¯·h#´Hkýœ±8kÓß^Àq@]àÓ“ø,56´¯÷Í-κU»n…[>]@nîøÏœp›[œ6# €4tën¯:ŽÒþ}…—8äT9_žY$/´G’K™©ù†•(óÑ’Mø©`ŸÉdѺ;ùO‹B Ó&P{qöhJÉ+Úé–§¦l2«MïöÝ_1ÑÓ«’t¸½±l€ëØya ¦ô©«®½ÆL^¬žêñš¸ùy.¾Û½Š[ u/]½‹iS}øN>²e1™q‡jfÚ&¢©iT\=kÏ›ÀXô-.84V5ðu!TE˜ þ.ŒOH´¶4—zwTr.ï‰¦Ë xõµ·œÖ„HÆù£žÈHùg Ñhñ’T$ßyq¸zþ¨p¿´ë< q•ró÷š‰wÿÍÑð–I]´–æI²é²˜sÂ"×:Õ–bÕ¦“ÈÙL6¢9VÊÓWž§<æ;”3?ý©Mê3AV#µ±ËÞ¯‘ž K£UrÝ9!›qát¦H£Ù+6ÇV…/TS^pÃùqgLP'Ú5E ‚–ÀÞºîÄ Ën"2|Ÿ;®W»Îý"Ö¬TwÖâµtúŽO'› á+W Ã+¦âZÌ–<ÕÆ&nOÝ,IŠ£06.ÁZ.Çñúøh*INÚ’Oe½ÉgBXÐÔZóäøä9èü“hÒíDSš¥¡Ê µA¯/Ôc¸ö“`A§¯"zå|‘ €ÅŸ¨ú;HÍ#‚Î|%ÄOˆƒ«OàÌÉÐÜD ž mÜðâc–ƤÉÂqm¶uË&~÷núÒË £ÇÏ€ZÕj =«_n[‡‡÷nN§ÏÝ$_¾bE˜‚€Õ)ù8¾?6‘lú“ÍÙæÖ}#bW( œ³d-®•p&¡ý’œÖa”"9öõņÐ$’Ú›AÜ!ä;ÐÑõè{~á¹8‘ÛÞ£1ÛÓÉ0ž`²#´kÒuäNÅÖ Q¹bhæ ”8ûÓMáŽa›•¿”w±h²¢®qŠæ°(bK ‚’Z¾Ò%ÐÆémáãÖË(Éý‚ÛJ)@> þ›7% ï{y Á“¾ÆÒîohfòô>{pÿ.­_Î%±ÉèägëlZØ\B2B #™¸ÚüÒºp‚hÝšü®[¥Ü<‹#SpñÌA7’ãØHƒt4:Ÿ|g¨tÓL¶*($Æ©»ì…®ù’ó÷$;b›ÔÙ`=¶£¦M„MÌÄ5ò«·Ç¾“H·ÌH.¼žHeAîº5}r­dõ¨±)ÀT};€Q5iÖ2…O0ü…0óñÃ;óæ,Š´²µ냔}g‘£]‹7å9ˆà©_{üèîêžC>úhê{Ž .ÈìðIIð€?[Kswz6Òuíý¬;µ€ç§OåâJÉa˶zv°éd† ¤µâ‚l´é舊«Åüy¾c÷ÁèÖÍ'ràúÅ™TWÕôÓ°¡L €|ʽŒ¼ì­høBã ÝTëî'ò]Kø£ìâÏ(=¹Kx €¿ LÌ,Pý¤Êµu‡¹…׈ §Å¾÷à1Ý«Äý;¿pGDäxZYÛ kfæ6¸ùóæ7®œ®þ6·ÕoÚ¾ÔH~ò®Þ¸â 8Uø“p<ºw3¡a£ÏÑ’‘3èÏ"€bˆ-ÎܺÏ_ªÅ]+ËM©zü°s“f-êçhÇãÑýÊãôÿ5}ZQNb{Ó?å%ÿ\SUõعIÓæ}~}p[œoÔÄ„êÐMMZáNÅå@>Œ„²á6(?¡Åé âK½+ü?À%ÝÝ·/Ç1‚9áUø?B)”ÕèâÞlÈÒêÏ @=àùÄÞžk­®ÅIEND®B`‚openchange-2.0/apidocs/html/libmapiadmin/dynsections.js000066400000000000000000000041341223057412600234020ustar00rootroot00000000000000function toggleVisibility(linkObj) { var base = $(linkObj).attr('id'); var summary = $('#'+base+'-summary'); var content = $('#'+base+'-content'); var trigger = $('#'+base+'-trigger'); var src=$(trigger).attr('src'); if (content.is(':visible')===true) { content.hide(); summary.show(); $(linkObj).addClass('closed').removeClass('opened'); $(trigger).attr('src',src.substring(0,src.length-8)+'closed.png'); } else { content.show(); summary.hide(); $(linkObj).removeClass('closed').addClass('opened'); $(trigger).attr('src',src.substring(0,src.length-10)+'open.png'); } return false; } function updateStripes() { $('table.directory tr'). removeClass('even').filter(':visible:even').addClass('even'); } function toggleLevel(level) { $('table.directory tr').each(function(){ var l = this.id.split('_').length-1; var i = $('#img'+this.id.substring(3)); var a = $('#arr'+this.id.substring(3)); if (l libmapiadmin 2.0 API Documentation
File List
Here is a list of all documented files with brief descriptions:
[detail level 12]
\-libmapiadmin
 o*libmapiadmin.hStructures for MAPI admin functions
 o*mapiadmin.cHousekeeping functions for mapiadmin
 \*mapiadmin_user.cUser management functions for mapiadmin

Creative Commons License
Creative Commons Attribution icon Creative Commons Share Alike icon
This content is licensed under the Creative Commons
Attribution ShareAlike License v. 3.0:
http://creativecommons.org/licenses/by-sa/3.0/

openchange-2.0/apidocs/html/libmapiadmin/ftv2blank.png000066400000000000000000000001261223057412600230760ustar00rootroot00000000000000‰PNG  IHDRɪ|IDATxíݱðøScOx@ –¨y}IEND®B`‚openchange-2.0/apidocs/html/libmapiadmin/ftv2cl.png000066400000000000000000000007051223057412600224100ustar00rootroot00000000000000‰PNG  IHDRÚ}\ˆŒIDATxíÝ;H#AÇño4Љႇ œ„K‰‡‚á ’ê,m„ØØ vÚžJ°²¹ÚÎþî‚§ XY ÅB|dr³cvo—˜Ä°Ý ù0Ã’™3ÿͤõ”Ëe×´¸Éõ¯1XÞ8Œ‰nQˆ88ööÖ§3*rbñ¯¢û-$¨‚þ´˜“P1Žè@Z…-# Ïú01ÑÏÎêÄ1HkKŸ w¶O@¥ªÈóñ!f§ñu˜åác÷;’sá×Bý[E´Añ±—Í\ß>°ùý¿ÏËÊÂ]–P€zØf| Íñ¯“+Ù´gð5…b  i5ümM³œ_æÍq,ÒcŽõèoÓd´ !¶äò©ô•,ôðÀ{¹¨µYß,€zTÍ8H]𤕘ï7¼»/òó8ËQæ !F€~6ãá?Y ÀA@ŨÁ.@ƒ¶TäÄYïŠËë±r‘µ8Ð*·é>€Šçÿ?€×þŸe[6«xÂIEND®B`‚openchange-2.0/apidocs/html/libmapiadmin/ftv2doc.png000066400000000000000000000013521223057412600225560ustar00rootroot00000000000000‰PNG  IHDRÚ}\ˆ±IDATxíMOS[…Ÿžsúa?-XZ(PD4‚ AWbu`b 77wäHFÆCËÔÂÿà/`vo„ˆAPòq‹P @ ­ûÝè980 îà¤+»§Ýy×^ïZï9SW¹\83g‰3'°Nâçl¹¸_b¯p ïåûÆVÜÖ¡€Ÿ×"¬Ö†X€d]Ðà3“ÉÃÄÌ™xŸ ßMàœ[<çSPkvc—hÈ'…™˜^Åm™hØ7 `Û™¦ èÀåráq›‘œ¾!daeKŸþÆÕ˜:Ì*³_דâèi?I–eP*B7Ÿ¿åô!¹Ýgr6Ër6oKbëþãðôrI”ËTˆüªŒ¨xóö=›ù¢&‰(e+ßóÄkýÇ`ëÁÜb.“¸ÐW×w0¥°jÑzN™¬|©WEãµ¢a¯6[öX†AkÓù*/œ¨‰€ÉY­ ÿV’§–u²jÂ>1W *½·°PGŽzÿ¨/Eg{ ŸÇâaoŠÁVú:è¿™¤1$ôR§W,–ªà¨@ŠË56¾ÀÔÜ-¾,mê¸Î/æè¹– òr5¥T*S(Vf8ö9u’ Õ£w›ùóa=Í<{Ò¡UŒ÷r¯+ÉådDÏF$è°…£é¿`zþ»ÎúöN‘µÜ®0Q3£~_^Ëóâ¯N=ˆvpTà±LžT}ˆîkq†Òm<¼ÎÓ?Zh¿X£ï_þÝ¥[)ƒ `gêÃa_Ô*äÔ2`'=õ´Fÿ2EâÁPú ÷»›l=8‹Wv°%THqÉ¿<"¤ïG¾ÆxH{#ÆÖ«aÔJÕÞ‡—m‹„ çñKsÿàñVŠØ¡°·MâÒ^ TÁ– Ý›r¥ß½ømüÿ_™?ªWİ÷#uIEND®B`‚openchange-2.0/apidocs/html/libmapiadmin/ftv2folderclosed.png000066400000000000000000000011501223057412600244520ustar00rootroot00000000000000‰PNG  IHDRÚ}\ˆ/IDATxí]MOÔ@~ÚúuØlp]ö¿#›Å]PYECˆ\9ù¼yÑß`ÖÄÿàÿÀÉxóâ¢C &=qÐÄ£—vZçv¶3m؃‡vžLûNç}Þ÷}Þ½ZA@n° OäNp ’xóþK°ññ€xÜj”°8sÑ€“ “€œ_¼[Âíæ§ïD'‚•yye+ø¼û 7#rNŸlïük* ¾0Ь_d«_(àñÖ±àôz=ñxõv§÷h©‰z¹€šØP-äóä’̪uý¼$»\DãJc—B4¯ãÝÖ.:£Ï-ÑÏß}µŠLEíºþ #—ûáºÀÏgN;BŠ€6ïýñ䬜…ö@’Ðåñp&™h>p9¤™EEά¨ÎÊ‘" u¥n€$R"?{¹<˜…ë…%PNtâ$‰ß¶±úá+^<é"§2 ªDq”q´\¬«Ò™a–Œ‘©Aÿ€"Ôµ ™êŸèP£}#Eàz{û.8i îp³ê(ADwD¦E<ê¬cE¦$ HdÊÄ ”.:Ù GŽ-`ŒL‚ý¾'¢‰Ä<¤CIª½;ÙÇTZd±i};>èôß‚z×;K×§8t ¤Ž q”:uvÿv•Ý›¬²ÙvEân{„M·FXg¼ÌfZÖ¨°¹‰*›ßÌß©±ù©:›j–YqèÜë#3çÏSøWøÿÿÑr'ø Ôùù‚ ©¡IEND®B`‚openchange-2.0/apidocs/html/libmapiadmin/ftv2folderopen.png000066400000000000000000000011251223057412600241440ustar00rootroot00000000000000‰PNG  IHDRÚ}\ˆIDATxí]?oÓPÿ9iš4i°;ii“¶‰ZЉ‘‰ÀÀ7`bèÔÙ¬Øù,HìU'ô$*Tµ]‚T¡DPÚÄ6wÏ}‰;¡C; a¿ÓߟûÝïîž¼jAÀ­InSþ}€9H“ÓŽ|?íÁ÷ =_ÊÆŠ­†¥Àue*;¯YEäsYäæB¢Ÿ¿þÄ—£sÙ½½ÙŒ† É«›©ÀYÇq !GÇ¿v̇¹ÑØ®š °Œ‚ÔF¹}q¥b]÷7í·0)Úd›¾ÿð-èº}Pfä£ÖY{4™ÑÂ@}úæôñ2ÛüÔ—ñúåNŒI‚ÁǃcçÁº%£¬UаI³mc±ô˜å¼ÔÆüÈ>é¸xþt9Æ$µý OæVE*õU´Ì‚ç#ž×ˆ•ïûr@l$øPÿrHaaÇ¥ ²›dZ®rè‘ãqI„o¼øT\Ž,tªj2FAxv-LŸp׌p TÄI/ \¥sfí½; jViTƒèú¤o^cpÅü¼ûû»Ïb]”€¢¤<†aþÕœ²“ßÓ˜y“£§9:Œîù+À³€ñà,E žf³6éNˆÄE£KU}Ü^;¶ØnZ¢uß­US4— ѬëbížN¶.Úk¦ØjTÄöº%µªâ i¯VÄÊÝò§™ Èù¸)ùÿG€™òºJ@T x”IEND®B`‚openchange-2.0/apidocs/html/libmapiadmin/ftv2lastnode.png000066400000000000000000000001261223057412600236200ustar00rootroot00000000000000‰PNG  IHDRɪ|IDATxíݱðøScOx@ –¨y}IEND®B`‚openchange-2.0/apidocs/html/libmapiadmin/ftv2link.png000066400000000000000000000013521223057412600227460ustar00rootroot00000000000000‰PNG  IHDRÚ}\ˆ±IDATxíMOS[…Ÿžsúa?-XZ(PD4‚ AWbu`b 77wäHFÆCËÔÂÿà/`vo„ˆAPòq‹P @ ­ûÝè980 îà¤+»§Ýy×^ïZï9SW¹\83g‰3'°Nâçl¹¸_b¯p ïåûÆVÜÖ¡€Ÿ×"¬Ö†X€d]Ðà3“ÉÃÄÌ™xŸ ßMàœ[<çSPkvc—hÈ'…™˜^Åm™hØ7 `Û™¦ èÀåráq›‘œ¾!daeKŸþÆÕ˜:Ì*³_דâèi?I–eP*B7Ÿ¿åô!¹Ýgr6Ër6oKbëþãðôrI”ËTˆüªŒ¨xóö=›ù¢&‰(e+ßóÄkýÇ`ëÁÜb.“¸ÐW×w0¥°jÑzN™¬|©WEãµ¢a¯6[öX†AkÓù*/œ¨‰€ÉY­ ÿV’§–u²jÂ>1W *½·°PGŽzÿ¨/Eg{ ŸÇâaoŠÁVú:è¿™¤1$ôR§W,–ªà¨@ŠË56¾ÀÔÜ-¾,mê¸Î/æè¹– òr5¥T*S(Vf8ö9u’ Õ£w›ùóa=Í<{Ò¡UŒ÷r¯+ÉådDÏF$è°…£é¿`zþ»ÎúöN‘µÜ®0Q3£~_^Ëóâ¯N=ˆvpTà±LžT}ˆîkq†Òm<¼ÎÓ?Zh¿X£ï_þÝ¥[)ƒ `gêÃa_Ô*äÔ2`'=õ´Fÿ2EâÁPú ÷»›l=8‹Wv°%THqÉ¿<"¤ïG¾ÆxH{#ÆÖ«aÔJÕÞ‡—m‹„ çñKsÿàñVŠØ¡°·MâÒ^ TÁ– Ý›r¥ß½ømüÿ_™?ªWİ÷#uIEND®B`‚openchange-2.0/apidocs/html/libmapiadmin/ftv2mlastnode.png000066400000000000000000000003661223057412600240030ustar00rootroot00000000000000‰PNG  IHDRɪ|½IDATxíÝ!NAÅñ¤‡à\ ÷à Um@`Ô5iÒ`ëh ‚ÅW7] b§ÝˆŠ&oföÍd¾YÔ4 üšcø ‡€´‹Åòù3v=¼]†§µ\B… I¿‹=B·™B¡®;¸k´µ W°ÍN@vyÍÑÖ4ãß÷]ÈâYìã§|M}]ÔÚx6a }ôdׇØYüú¨>¤||5?Ó>|žB"¡î'¡IEND®B`‚openchange-2.0/apidocs/html/libmapiadmin/ftv2mnode.png000066400000000000000000000003661223057412600231170ustar00rootroot00000000000000‰PNG  IHDRɪ|½IDATxíÝ!NAÅñ¤‡à\ ÷à Um@`Ô5iÒ`ëh ‚ÅW7] b§ÝˆŠ&oföÍd¾YÔ4 üšcø ‡€´‹Åòù3v=¼]†§µ\B… I¿‹=B·™B¡®;¸k´µ W°ÍN@vyÍÑÖ4ãß÷]ÈâYìã§|M}]ÔÚx6a }ôdׇØYüú¨>¤||5?Ó>|žB"¡î'¡IEND®B`‚openchange-2.0/apidocs/html/libmapiadmin/ftv2mo.png000066400000000000000000000006231223057412600224240ustar00rootroot00000000000000‰PNG  IHDRÚ}\ˆZIDATxí1Kû@ÆiƒØB…Ò¡(h¬"EÄI'ÁoàªèÚ©ßÀáâä 8ùçR-‚â B«TPˆï]z¥B’3 _Þã’»ç}ŸË]VÇ÷}€ÌÈdIæ®i쟯JØ–b¸šÍÃõ+º™|KÂ…°,[Pï\ʘMÆ¢#€ä…F`JݤìÛk³úA±àþè?ØY4ck6"¹Z)ê¸0SHM¨@ï㋺WÖmo¼4èHJ¨Àÿö+…QobŒút ¤ú’*Ð~êè8_+3Y-ñðÜå½÷ ˜PwA¶+^ý}ºì£+xìhÏ•MAE]€TD~EÞߴ^R)`ÖAùŸÏ9©pÔq-Û¾õÛ3tÝÊÆ›ˆÃTÐHÈ)€ ½Š’ICªxëd#1ôú§é€ m@Vüý?Zæßgo_½3-³\IEND®B`‚openchange-2.0/apidocs/html/libmapiadmin/ftv2node.png000066400000000000000000000001261223057412600227340ustar00rootroot00000000000000‰PNG  IHDRɪ|IDATxíݱðøScOx@ –¨y}IEND®B`‚openchange-2.0/apidocs/html/libmapiadmin/ftv2ns.png000066400000000000000000000006041223057412600224300ustar00rootroot00000000000000‰PNG  IHDRÚ}\ˆKIDATxíÝ1K1Àñ­ž ØG•â‚n‚Šà ‚âælÁE¿€‹“ (nºêââêäࢋƒÐMAá@°‹ µât¾ÄK¡à%Ü•Û ý]BIïå%áuÍ…a™€,e × v¯ç¥«ˆi‹º¨Õö–î\tòòuénÄ0ã æÜÉoV\Ì$G.&@Y=ÆË%$um·¢ûÛ6–'Úß«9Qó\bÙ)²º0Ðë-Zœ¥TèHÍ`pÀcsm µö5:>Áë‡Þ¦I µØ ‚F‹Çà]» ›jg—ìoÏáõ©[ œõ š­onë €Ô¬¨vqõ„?\Ðç”  6»øüÒTe ÃÉéŸeç ÀÅlQ ¡c”€ª¬ü3*d€ÅWTMÏ\rÿÿh6™ø1±F ‹°fžIEND®B`‚openchange-2.0/apidocs/html/libmapiadmin/ftv2plastnode.png000066400000000000000000000003451223057412600240030ustar00rootroot00000000000000‰PNG  IHDRɪ|¬IDATxí=QF‘Ø¥D«ÔkÄ:‰F©PK؃=V@§Õ³ Õ8SHxñÌ0bnrróŠ{ò½¿¾’$ ÀÏTŠP  ö¼X¬OÛd6êìòð"°²S´±O¥B€(¡àQé)š+YĈ ÒªËRÉÐ>VtÉsˆm9(ê„䜥k‚-@ȧ-Ü$ó b Ò[he ¿Kp-ôl|CùÿApRG'rÍ­aIEND®B`‚openchange-2.0/apidocs/html/libmapiadmin/ftv2pnode.png000066400000000000000000000003451223057412600231170ustar00rootroot00000000000000‰PNG  IHDRɪ|¬IDATxí=QF‘Ø¥D«ÔkÄ:‰F©PK؃=V@§Õ³ Õ8SHxñÌ0bnrróŠ{ò½¿¾’$ ÀÏTŠP  ö¼X¬OÛd6êìòð"°²S´±O¥B€(¡àQé)š+YĈ ÒªËRÉÐ>VtÉsˆm9(ê„䜥k‚-@ȧ-Ü$ó b Ò[he ¿Kp-ôl|CùÿApRG'rÍ­aIEND®B`‚openchange-2.0/apidocs/html/libmapiadmin/ftv2splitbar.png000066400000000000000000000004721223057412600236330ustar00rootroot00000000000000‰PNG  IHDRM¸¿IDATxíÝ¡JCa‡ñç(˜ ëƒ%±Ø4 b±È˜Í¶3˜v^Á±˜…ãó–ŽELƒõ…¥•³ ,ÿb;íç{Ã/¼ðÞÀaYÕ¯åóøq:¼º¹›\òIIIIIIIIIIIIIIIIII-Òçl¹›«õ抢è_t/Ï»ã£ÑíYQVõðêäíã÷´×ùY¬Úÿµ§¦ivók¾_íåýÛ£I@$I@$I@$I@$I@$I@$I@$I@$I@$I@$I@$I@$I@$I@$I@$I@$I@$I@$ýC[Vì=ü[„fÆIEND®B`‚openchange-2.0/apidocs/html/libmapiadmin/ftv2vertline.png000066400000000000000000000001261223057412600236370ustar00rootroot00000000000000‰PNG  IHDRɪ|IDATxíݱðøScOx@ –¨y}IEND®B`‚openchange-2.0/apidocs/html/libmapiadmin/globals.html000066400000000000000000000064701223057412600230200ustar00rootroot00000000000000 libmapiadmin 2.0 API Documentation
Here is a list of all documented functions, variables, defines, enums, and typedefs with links to the documentation:

Creative Commons License
Creative Commons Attribution icon Creative Commons Share Alike icon
This content is licensed under the Creative Commons
Attribution ShareAlike License v. 3.0:
http://creativecommons.org/licenses/by-sa/3.0/

openchange-2.0/apidocs/html/libmapiadmin/globals_func.html000066400000000000000000000062551223057412600240340ustar00rootroot00000000000000 libmapiadmin 2.0 API Documentation
 

Creative Commons License
Creative Commons Attribution icon Creative Commons Share Alike icon
This content is licensed under the Creative Commons
Attribution ShareAlike License v. 3.0:
http://creativecommons.org/licenses/by-sa/3.0/

openchange-2.0/apidocs/html/libmapiadmin/header.jpg000066400000000000000000002264161223057412600224450ustar00rootroot00000000000000ÿØÿàJFIFddÿìDuckydÿîAdobedÀÿÛ„ÿÀÍ4ÿÄû     a!Qqð1A‘¡¢d ±"Ô%U•ÕV–Ö”WÑñ#EÁá2DT·BR3C$uµ&g(8x’S£³4…6¦hbc¤´Å†G§)   !1AQq"“ÓT”ÔUa2‘¡Ò#³´u6±BRVÁÑb²3$v'7ðár&ñ‚’¢CS%Âsƒ£4Dct¤5ef(ÿÚ ?ýAîÊåSñMÁÙB8v)¸;(GÅ7eáØ¦àì¡;Ü”#‡b›ƒ²„pìSpvPŽŠnÊñMÁÙB8v)¸;(GÅ7eáØ¦àì¡;Ü”#‡b›ƒ²„pìSpvPŽŠnÊñMÁÙB8v)¸;(GÅ7eáØ¦àì¡;Ü”#‡b›ƒ²„pìSpvPŽŠnÊñMÁÙB8v)¸;(GÅ7eáØ¦àì¡;Ü”#‡b›ƒ²„pìSpvPŽŠnÊñMÁÙB8v)¸;(GÅ7eáØ¦àì¡;Ü”#‡b›ƒ²„pìSpvPŽŠnÊñMÁÙB8v)¸;(GÅ7eáØ¦àì¡;Ü”#‡b›ƒ²„pìSpvPŽŠnÊñMÁÙB8v)¸;(GÅ7eáØ¦àì¡;Ü”#‡b›ƒ²„pìSpvPŽŠnÊñMÁÙB8v)¸;(GÅ7eáØ¦àì¡;Ü”#‡b›ƒ²„pìSpvPŽŠnÊñMÁÙB8v)¸;(GÅ7eáØ¦àì¡;Ü”#‡b›ƒ²„pìSpvPŽŠnÊñMÁÙB8v)¸;(GÅ7eáØ¦àì¡;Ü”#‡b›ƒ²„pìSpvPŽŠnÊñMÁÙB8v)¸;(GÅ7eáØ¦àì¡;Ü”#‡b›ƒ²„pìSpvPŽŠnÊñMÁÙB8v)¸;(GÅ7eáØ¦àì¡;Ü”#‡b›ƒ²„pìSpvPŽŠnÊñMÁÙB8v)¸;(GÅ7eáØ¦àì¡;Ü”#‡b›ƒ²„pì__gÓâ£êE~•²O\VݪÏãžà…·#÷Á?Nž•cÏ´Ôô™Û£¾!àÞÖ²x¬.c;s÷<%Íåå+ÝÁ’¾ºckO¦‹£Êcq0}ç)sµµi®W¶6׳SÈpo× 'ü߯Wí¬?þ«[7ð¿™áÜï¨]ù¥‚øócûëëvþqkúß„ÿ›øÇñå­õ¥?á2ÿùßP»óHøócûçëpyůëvþoc/Ç–¿Ö”¿†Ëÿç=BëÍ#ãÍïœW­Áçýn¿ÍÜeøî×úÒá‡2¿Ã¹ÏPºóIüy²=óŠõ¸<â×õ· 7qŸã»_ëJ?†Êÿç=BëÍ#㽑ïœW­ÁçýlÂÿÍÌiøê×úÒ—ðÇ™?áÜç¨]y¤|w²=óŠõ¸<â×õ¯ ÿ6ñ§ã«cë:?†<Êÿç=BëÍ#㽑ïœW­Áç¿­XcùµÛYÑü1æOø{9ê^iì|â½n8§ëNþlãoÇ6ÏÖt ¹“þÎzךGÇ{#ß8¯[ƒÎ-Z0×óg~8¶~³£øeÌðösÔn¼Ò>:Ù>ùÅzÜqkúφÿ›ßñųõ/áŸ2?ÃÙ¿QºóHøëdûçëpyÅ?Y°à÷²¾8üom}gGðË™áìߨÝy¤þ:Ù>ùÅzÔqkú͇šøãñ½µõ•Ã>d‡³~£uæ‘ñÖÉ÷Î+Ö óŠ~²áßæ¶9ümm}eGðϘÿáìߨÝy¤|u²}óŠõ¨<â×õ“5q×ãkoë*_ÃNcÿ‡ó~£uæ‘ñÎÊ÷Æ+Ö ó‹_ÖiìÏ{âýj8µýVÅÌ›ñtÃéy…îÏ©\ù´|o³=ï‹õ¨<⟪¸°{Ù&Äü]ðú?‡<Â÷gÔ®|Ú>6Ù¾÷ÆzÔqkú©‹™/âØ‡Ñü9æ¸s>¥sæÑñ¶Í÷¾3Ö ó‹_ÕL[üDZÀü>á×0}Ùõ+Ÿ6ŸÆÛ7ÞøÏZƒÎ)ú§‹¿˜ö7âȇÑü:æ¸s>¥sæÑñ¶Í÷¾3Ö ó‹_Õ,_üƱ¿A|:—ðï˜âÌz•Ï›GÆÛ7ÞøÏZƒÎ-Tq€÷²-Ž?þë‚øuþ`{‹1êW>mìß{ã=j8§ê†1þbYŠà¾Gðï˜âÌz•Ï›GÆ»;ÞøÏZƒÎ-Sñ—óÈüUðê?‡{ÿÜYR¹óhø×g{ßëPyÅ?Sñ—óÉüUðê_ÃÍÿî,Ç©\ù´þ5ÙÞöÆzÌqkúŒÿ˜VWâ˜?‡Qü<ßþâÌzÏ›GÆ»;ÞØÏYƒÎ-Sq ÷²•ø¦á´w÷¸³§sæÑñ®Î÷¶3Ö`óŠ~¦c_æ —ø¢á´w÷¸³§sæÑñ¦Î÷¶3Öaó‹_Ô¼müÀ²ÿB|6áîþ÷cÔî|Ú>4ÙþöÆzÌ>qOÔ¬müÀ³?Â|6—ð÷{/êw>mlÿ{c=fËZþ¤ã¿öoâx_†Ñü>ß¾ãËúÏ›GÆ›?ÞØÏY‡òÔýIǬßÄп £ø}¿}Ç—õ;Ÿ66½±¾³å­R1ÏßÛ;ñ4/Ã(þoßqåýNçÍ£ãMŸïlo¬Ãùk_Ô|s÷öÎüK ðÊ_Ãýûî<¿©Üù´þ3ÙþöÆúÌ?–§ê6:ûùgþ%†øeÃýùî<¿©Üy´|g´=íõ˜-kúŽþýÙÿ‰a¾Gðÿ~{“/êwmí{c}fËSõýû´?Cü2€7ß¹2þ§qæÑñžÐ÷¶7Öaüµ¯ê&<ûõh~$‡øe/€7ß¹2Þ§qæÑñžÐ÷®7Öaüµ?Pñïß«Gñ?Ã)ü¾ýÉ—õ;6Œö‡½q¾³å­Pñ÷ß›GñGÂé|¾ýÉ–õ;6Œ¶‡½q¾³å©ú…¾üZ_ˆâ>GÀ;ïÜ™oS¸óiüe´}ëõ˜-kúƒþüZ_ˆ¢>GÀ;ëÜ™oS¸ói|e´}ëõ˜-OÔ÷ÞÓüEðº_ï¯re½Rãͧñ–Ñ÷®7Öaüµ¯ê÷ÚÓüCðº>ß>åËz¥Ç›GÆ[GÞ¸ßY‡òÔû`ýöµ?Äü.€·×¹2Þ©qæÑñ–Ñ÷®7Öaüµ¯Ûëï­©ø‚'át|¾}Ë–õK6Œv½q¾³å©öúÂûëjþ ‰øUoŸrå½RãÍ£ã£ï\o¬Ãùk_·¶ßKWñW¨ø |û—-ê—mízã}fËSíå‡÷ÒÖú~+áT¾ßåÊú¥Ç›GÆ;KÞ¸ïY‡òÖ¿o,?¾–·Óñ_ £à=ñî\¯ª\y´|c´½ëŽõ˜-O·v'ß;_éø¯…Qð&ø÷.WÕ.<Ú>1Ú^õÇzÌ?–µûwbýòµþŸ‹øUïrå}RãͧñŽÒ÷®;Öaüµ>ÝX¿|­§¢þGÀ{ãܹ_T¸óhøÇi{×ë0þZŸn¬o¾6ÇÓÑ £àMñî\¯ª\y´|a´½ëŽõ˜-köæÆûãl}=ðª>ÞþåÊú¥Ç›GÆOÞ˜ïY‡òÔûqcýð¶~ŒøM/7¿¹²¾©qæÑñ†Ò÷¦;Öaüµ¯Û‹ï…³ôìgÂhø{û›+ê—mm?zc½fËSíÅ‘÷ÂÙúv3á4| ½ýÍ•õK6Œ6Ÿ½1Þ³å©öÞÈûßm}9ðš>ÞÞæÊú¥Ç›GÆOÞ˜ïY‡òÔûodýï¶¾œŒøMïose}Rãͣ㠧ïLw¬Ãùk_¶ÖOÞëkéÈÏ„Ñð.÷÷6WÕ.<Ú>/Ú~ôÇzÄ?–§Ûk+ïu·ôÜoÂhø{{›+ê—mm?zc½fËZýµ²¾÷[MÆü&w·¹²¾©qæÑñ~Ó÷¦;Ö!üµ>ÚÙ_{m¿¦ã~Kàmíîl¯ª\y´þ/Ú~ôÇzÄ?–§Û[/ïm¹ôÜoÂhø{{›)ê—m/Œ6Ÿ½1Þ±å©öÒËûÛn}7ðš>ÞÞæÊz¥Ç›GÆOÞ˜ïY‡òÔûieýí·>›øMoose=Rãͣ㠧ïLw¬Ãùj}´²þöÛŸMÆü&··¹²ž©qæÑñ†Ó÷¦;Öaüµ>ÚY{mϦã~GÀÛÛÜÙOT¸óhøÃiûÓë0þZŸm,¿½¶çÓq¿ £àmíîl§ª\y´|a´ýéŽõ˜-O¶–_ÞÛsé¸ß„Ñð6ö÷6SÕ.<Ú>0Ú~ôÇzÌ?–§ÛK/ïm¹ôÜoÂhø{{›)ê—mm?zc½fËSí¥—÷¶Üún7á4| ½½Í”õK6Œ6Ÿ½1Þ³å©öÒËûÛn}7ðš>ÞÞæÊz¥Ç›GÆOÞ˜ïY‡òÔûieýí·>›øMoose=Rãͣ㠧ïLw¬Ãùj}´²þöÛŸMÆü&··¹²ž©qæÑñ†Ó÷¦;Öaüµ>ÚY{mϦã~GÀÛÛÜÙOT¸óhøÃiûÓë0þZŸm,¿½¶çÓq¿ £àmíîl§ª\y´|a´ýéŽõ˜-O¶–_ÞÛsé¸ß„Ñð6ö÷6SÕ.<Ú>0Ú~ôÇzÌ?–§ÛK/ïm¹ôÜoÂhø{{›)ê—mm?zc½fËSí¥—÷¶Üún7á4| ½½Í”õK6Œ6Ÿ½1Þ³å©öÒËûÛn}7ðš>ÞÞæÊz¥Ç›GÆOÞ˜ïY‡òÔûieýí·>›øMoose=Rãͣ㠧ïLw¬Ãùj}´²þöÛŸMÆü&··¹²ž©qæÑñ†Ó÷¦;ÖaüµÈ[.Õâ)8há'(,™Ed"©,’¥¦ªJLEP‚Sˆ¡ZÜðMk;í®ctw1¼µìp-s\ÓG5Í4-sH ‚P¬ô3Eqn-Þ×Àö‡5Í!ÍsH¨s\ AÄ/£³éñWÔ¹+ô©Ùôø¨ú‘_¥bï¼JÆàXññ‰¶•Èeƒ‹\D[G2NJ&CC6*ä1ORöêÜ 6¾ñÈîKÞsS,û«×> §hð'•¿jGÐ8A<‹H/u†–ð«‚ònió6Û`ãÛ«Y.á¸i10ý–7£½xtÖ¡£†§Æ€¯oL…xäi¥® Òᑸ$Ö1÷T|¹Ì‹DÎmïFhV±í?䤉˜sk_§[khmÍn'mYÃidÐ*Ðò8j‘ÿjGž·<—Õð¶sqf·-ó²9ˉn.[ƒýV7ì±£©­.( uV|µb*”ë©ÓDꔪmÓÜþŠ’;SªPS¸)P& PSn½=ú’ÔU()ÕRZª©ANº)Õ)UÛã¤GjuJ wM`¥*›u÷jKSªPSnÞ*’ÔꔨÓN…UL íñÒ¢uJU:½ÊšR‚}‹SªR©·ÇPZR‚•ORuLUzüƒJ©Õ)TÛ§Oz•N©ANà¨-L ¦Ýj UU)Tê÷*t”ÁL XRN½‰J¦Þ¡¥¤'T §UAjuJ uÔ§T¥So½SBª©AOëè¤{Mºûµ%¡:¥*›t©-N©AJ‚ÔꔪmñÒ¡N©ANò…MªR©×ÑH´& R©¶ µ:¥*KU”Û¯MMN©ANò…*'T §^ЩÒR‚›jKSªPS¸* S)TÛ®Á©¥ª@S¤<´“ª`S¯¢•uH m©-N©@üõ©‚ªsPÔ–§T §pRâR‚›u¥@RU%©Õ(yõ©-Nªà~ª’ÔꔚŠQ:¤ŸNš<)Õ()J€§T€}µ%©×ëH)Õ 9ô©-N©ãÓSDU 9ôé¥Ç­:¤ÒàSW…-)Ô¤=Iju€~z)ñWs I¨ª@?8x©S±5p?0ÿM.=iÔ¤ÑÀ£‚¸)Q:•p5M¨ëWÒÒŸ\ SBŠö«„<4¨ª¸<5:SVs .!UÀÂT'^Õp?pQNÄS±\ J‰ÔŽ•®´¨Š…`0ôÒ¢t À`è¥E4ZÒIkB¡ P…(B”!J¥R„)B¡ P…(B”!J¥R„,®Áw ¹f"Éc “8±K^ð$Óþ@è§_›ûç÷Û1ûVïôò/»¶‡îž/öu·èX²?³îÒµo¶/À§gÝ¥…~pxš»e®Üõ•K¹2ÇŒ½ni57fÞ*Ù”u‚D¦ÑL}4ÞPÆ0òˆ×ì?%0V.U` Ç°5³ãmî^zÝ-ÌMžGÒ|g+ÐÐ@ ó{š[¼¶ÿÊËxíF+é hêÀ÷DÀ;õ*ꔪXTÐ'TÅSn¾íIjuJ mÒ¤µ:¥* SªR©·]ƒJŠª”é(TÒ©Õ0)×ÑRZR•Mµ%©Õ()ÕÑQ¥:¥:È4¨R•M½CR@N½©ANà¤ZR•MºÔ§T¥SnžåAjª¦:ú)'T ¦ßMuJ uR-N©ANº‚ÔꔪsžçôT–§T §pT¦bR©·Çߥ@R‚U%©Õ()×PZª© §0éÝâ©-N©ANà¥Å:¥*›|u4ªPSª‘jª¥6ëPZRU%©Õ((=54¢uH mÓ¦—…:¥óÒ =ª@?0Ô–ªªP?=N”ê§æ¡¨-N©Nz\SªPSn½Þ:\:ÐKObuHÛRZ~¤€~z’ÔêÌ:ôÔ–§T€~~JT#¡4…?0ëKÂ{RéR½¯b@?0÷tT{UÀýu%©×±\ ú "ª@8ôÔiNªàpè飈OÀ4¸u¢½ªàz(Ÿ ¦‰×µ\4ˆ@§R¸<<•:S©Væ’;Sª¸|<´´¦®})P„+†•{Sª¸Žà¬ (Ž#¡_ZTOWjÔ˜iQ>[{ž•¢¶ 4’¢Ö’JP…(B”!J¥R„)BYðÒ–¨<;ï\ùU0ø«ó{|þûf?jÝþžE÷vÐýÒÅþζý `ö;<•«T-‹þÝ*v;<”T#þÝ+ò•ŸÍ»žshkÞ˹$4—”Í~Öò¨Êý·ûú¤+óü÷šý­yúÄ‹©€ýU¾­N©@ýu%©Õ )·J‚Ôêš'T ¦Ý;¼TxSJçÿMRuH mê’Ôê”çä©-N© ¦Ýj Sªû™6y éQí\½xàà›v¬ÐUË•Ô0èTÑAUNo×ÒÇfYÜÖBÑR礞[ùÀ\ãÐOàYKcðožïTÐr[IKyŠú®n5>/W³0”@bRªø ©Ã@2e 5¯7ÌókcaÜcuÛg¿Õ‹ÇãÙ«ƒz»|+mÆì}Ë“ðÛ=±ž5p§¯Â<+¸à2è†dçn„ƒEÛ ©XGª)¦.I¯½Qs ”1¬Tļ¢<•ªÅÎìMäÝÕ•»ŠHÔáS@]Ð:*ÐOJÊͰo,ÁûãÈ¡¡£M:iÓÆ´<;*¶ÙÚ±)ÿçƒÒ¡È.b„©ïhôÆn7Cx{ýí9DC½]«~k™Èÿtiû2Ÿý=«„íá;ª[H‚ºÆàá®àˆrá«Y¦.\ šJKº ²b²~Žå#%5KCrD `Ö¶+`cîãl¯ŠFÆâE{(iÄ#¾#¤®ÆÔž²F—Ž®Úñ ‘кVn͹mÓÆQª‘0HGEÐäå×}=t^PïVÝi—ÇÞÌH5£À¬Î6ö׌Œ%½£ˆ\dëò dhB©MºtÒ-N½©AJ‚Õ@¥*›u©-N©J§UM uL uÒ N©J¦ßIjuJ uT–§T §]AjuJU6éîTЧUÚ¸kßÛ!@ã\{Y†uSˆ(º‚Þ6&9¸’S÷TôH¸Ô5:§C‰¦E9mcwîÌ&ÈÀO¸óòì UïyàÈão Oyà8¹Å­pÎíͽ”Ý9x°¸vk¼”õš5iï=MhâOz ˆÖ»—†ogg1QŒø¯ÉÒWîF~Å'«Ú±on&†äû@ûfÃ2sñQ«†".å¤IÈ”D‚AÔ…ùœÝçŸ3ndŸ—0ã¶ûZٞ؜ziãKr oxà\Èb%WIú5ü¹åNÆ…‘o[¹/sh&6:FýXà!íiè–@Ò)Ð>7{,ø·]K/dIÜQ“Ý$¸Á@Ê>ºAÓåÐ)tôxlŒåó[°¦L¦TÌã%Sz ”ÇÌ„8î¹—üÃr茖òµ¶ÊàZGxö²?ÿÕ¬0ž€,.Ž´q* ØüšÞ€Ùm©æÇåÈ:]!$ô'.véŽPúTðy¡Ä>¿¸gÉ1ÖAj¨dFFÛ¸˜‚ƒ v@¨±ÑBZ)UCDÅ7 ”ÑfËJmJ$9þ¢å÷0°ÆÁ37„qkÓ,N§y ”©cÀémxñ^Þ"†­ ¼6n_ee‹Ê4MQÈß±++@æ“Äv9§‹OŠÒÅWn½5½P­N©J§W”)Pê˜ëè©-N© ¦ßAjuL TéUT¥W¯È54N©J¦Ý:{Ô¨ªPS¸*KSªb©·Z‚ÔêªuTé)Õ0+Éà%Mz=íá×pÛgá«´ÓW×ùçK4iy•¥Pc¢­Çˆz*j¦@o¢²Šk¦º€‡5|ÏÉ.iîmñ—ËÙn7Àè,û¾ëDa‡Æ|­5 šðcWºsO``¶¦7u…l¢[}æ·—±‘N8¸¯9ÐpUS*…C ×ÒbŽ ÃÏB¾S®‘j*”ªsžçôTé)Õ0)ýaI0{•Mºûµ:BuJ uT–§T §]AjuHU6øêtªª`S«hRER•Mºû´¨ª@Sn•%ªª”¨-N©AM¾:)Õ()Ïã ”ÁìJU6ëîÒ N©ANªE©Õ )×PZR‚›t÷?¢¤µ:¤9ùv…M uJU6õ / uJ sÒÓØRù†¤µ:¤÷AjuJ >½5:Sª@Sª—ÒúépER–”궤µ:ýJàpè©-N©@ãÏ­AjuWõyiP§T qç×ËK‚jàz4ö'^Ä€na©!íHç©-M\ Ì:TRÇÃËS¥5p8séÓKˆN©ãGpëWÒ¢~p7pR!:ö«Ç¦¤µp8R¡N¥\ >©#µ:«ù§Jjà`ðÒ⬢½©×µ\ÝÞ¢ÀÛ|tQB¶´¨ž¥`0ÔÑ>[{ž•¢×]hIkI%(B”!J¥Y‰Ã"Zµt:wݸý!¼5ù½¾}³µnÿX‘}Ý´?tñ³­¿BŘ½vµª­NÇ»Z¿%œB˜ Ÿów´Ì90QRxÔt.¸ÁÔ`9p¬rU¶ªö/»BRòŽ¥3 cx¥þ€¾ÁtW}ÔM‘À;…[Bþ׬ý+L=Áµïß##™Ä WéT•Ã%0z«uœ1lªNY±lGGP§Uºí[z:E1A¹;!U° aÐÄÝY[qq]ops^ò@¨TõšÐÖ¾õÃmËZHkšæ´H$)NÒà6tT»uÐ(£¤À@éiÛ4PL'2J”Šö§HU DtÝ0ˆw‚³Ö™››g‡>ˆõô8vŠŠOè\ca˜‹ êêðý…bÍׄ;~áó3e%¸²ÌôìÚÉ•2†Lœ€T]ƒ©Š:r›”¼¡èÍé÷hÃåÖûZÑÕâYôöÓéâ:ºV§}¶ÅËÜÖQ“õ§ÛðýKæ¡¥íÉâæY,Åësn¨ŠÀÈ S¦r “P‡(€Š"^‘ÈYå-ÅÍ“Ãã=#è#¤-òÊæÂcËK_øm¥Sª»ÄÕªPS¯¢¦:¥6øé¢©ANª‚ÕUJ uÔ§T¥Sn”¨Sª`Sú¦0R‚›u÷i§Uï²ù„!ᓉŽ*åcŠòJÜgv¤˜(,6Æ/²P¾d2T¥¦œì”ˆ&¨Q:ŒSäÔ¡¯Â¿Íýæâßø\A!m¤‚'štw×sºÝ®pë1±•o`‘Üx•õw!í-°ÛC/½ef«†wéîíâ8Ø÷:‡´°v/ÎmËv^yÊÿ¹ò ñ0îjáºæžMLÉ:Pç3‡o DŠcfÙ=Ô›¢MA2HR€}7€ÀÚYØÁˆÆF!Æ[FØã`àZ)õ“Òç.q.$’Jð¼¾Zâæê\óÌ—ó¼½î=$Ÿè €€.Ml-ò>bAìTÜCÖ’‘R±Î–g!'ºnØ¿bñ¹ÓpÕë7ID”!Šr bˆl·vÖæÙöÓµ¯†F¹®µÍp!Í ð ƒB ÁÙ¸‚fÏ ‹$cƒšA¡‚è Š‚:è ‰PâCÙ}‰¸ŸœI±¯Ë[BFj]š w/¤n„pýþÙºiãx雼È=ôtôìŲ`<„øƒ–lŸ–œþÈìkg8bî ¬k 'ÅýîÜšô¹ÕšN§µõ>ùt[ã”6[®pÓÅÔh¿îóØ×IGPti‹¯ø<à“ñ¹jôŸ“²îtç®I^ËM‘ ~ß¶­™F.eŸ:Žzvñ‰ŠVúnKÛ® "‰Ì œ¤Ž÷Ìþyo=“̶müD1]â´E¶ýÝd’YXàÆ‡¶¯§{ éhÔà AÔj[•;gtlgfr2Éo¼µÑŒŽ7´¸–š7ìjq $P(­f\ÞÇ®øŒÂѰy I)Gmm˜|Å55|FÛ“So\›йnÖÉǬñÚ…!Vun3Ž(˜ }ÒjjÆå2ßÍ?ýÕ5æ<@Àe}Œq[>HØÑW0àMtù:'‚ïXc¹ y|Üv׆gnß$ÍcÜMá(“®·k;h8¬Aã[†ü%eVV¹dœNØ×“S–Àñ""ùvlÜ‘´œ¿bšMTœ€U ²ˆ”©,ƒ„V$* )ûw'y­mÌý¾ë¹£m¾rÙâ;ˆÚIn¢*Ù#©'»P8’×5í«ƒCå|Êåôû0-£{¦ÅNÒø^áãP9 [ "€‡5ÔÒ3^ßá#†°Ì`ã®beåÃw‘3BbÈG²Ì×AUZðA½¾â2nRàbÐå3õÌõœk%Næ0¦ª¾9›ç/0÷þë¸Ûšd1c- ^ÊÖ8:ŽÓÞVPøÙœ‰¢9&ú©¬ô¼_,önÐÛðçy˜éd¾¸E«öÒ£VŠFZ÷HÑöÝ­‘°5&Žv㋱W³ƒŽÖ'¾pžX‡Šs0Ê"æy5"õÓDTI°É:‰œ»o(yèvΦUÒŽ”jõ 9Na)?ÊÄe¹Ï~U]Ñß²ÍmÉ$ s¢dlš-’(-ßÈK¥‰ñš=~Êå70-ä²ÚͺÆf˜Â懹ï$tUÌ’YšöEC$cÅA<:p7á"¯ÅͷÞ[báºÍò¶eÞÊ9éÛ*ªh$åB:Œ~RýE$á²ÀPíT¦ÓßWÐ;›µÜªºß»RF—ýÀO {A’ÞM$µÍ¯:—Žà¶{›Ì }£¸àß½÷R†šTMZîÇpsM8´ƒÖ½!Íü;{:øC¹Ô›Î7Ï4Òàd̶fŒ›”{qºi);–IHYy±håúG#uWxÁ‘{#¦Qp®¥OæýµÍŽyóÛ­¥½Ä/qžýñ±±Ôš²&6FICH. ŽI A:ÅÞÙœåç*6Uñ»Ï¾âhdhî­÷Òž4Ž,sBꆒö0Pôqۆá~÷⃲Ï[/±›IçÓvÔ¤ÂøšÔ‹Nภf#î‰Yçì¦Fß\ŽX®ÉâV0•1)Äæ2Y]½Í¾gìÎ`ZìÞh¾ »KçÆÖLÆDÂÞõÝÜr1в&º>ðÈÙ#®Pt3<ºØ{›gÜnm„Ù­®m÷:7:GjîÛ­ì{e|ŽÑã1Ìyi45%¸YÁw ’¼[_îa’V ǵڳ–¾nVȦáÓ6VU(Øh¤•Õ›3UÁªIYcN̨©îÙæ¥,öã2"6Üfnœæ[BI sš|#w¦êŽqs u·Ê¹yËû½óšuž³2Ý¡ÓÈHÖ0ßGi'ƒC\â ]™ÕËì…ÃWš˜¢ä¶/ËÞfAX’ø†œ½åb!ä[j“Óɺ‡½­ÖÏÔb࢚¿ź!V)ŠÑð¬~SùÜXѸ­o¬l­¦`’+gÅl×½§‹CCíåsC‡ßLÓJEW¬^cù…½8k‹[«©ãv‰'l“9­pàK‹&Œ:‡î¢p­EEñµÂ±áì\ň®U®ì” ȰRN¥ æ%üÌZ×!“lÙ²2ðif ‰{b‚'"¢aÜQOGäç8o·­ÅÖÖÝ6ÛwØêÖ [#XáÉa$²XÞ@‘ é:mZÝ'™|µµÚðÛç¶ô®ŸmÝÓIqsæ—´jjcÙRÃMB„:¦„ú›Ç$áî÷ǘG#ñ=’ÝØ8Ÿ·|ñìdYŒ”Íó;sCÛ‰CÛ‘«7Aü¢‚bB.u[±j£ÅRÔÄQ¹QbüË}É»0ùÌž/eZ6ç; s¾Ä,òHàK[ýqG=Á€ð!䆟£7¾näñV7û¦àÁ‰´a%­ûR¹íf–4€]ýSPÖ—ÐZ#0¾1öjñŽÎî°8ˆ½1ÎA‚<Ó7Ò·r²Å*현ëx»†íº æbI¼n“´w›¹pP(§¾U ë9®`së–2Úå·eÅžC,¡Žcc€2´'»/ŠdcËC‹ã¶­5¡ióÌ^ÏåûŽã·a¹²ËG ç>RêT a²K+Ð⇊î<¨#ÍÜ]‚®|ÄppÞ.›F\ñ÷½Éh\²eIWlⳓ žU$ñI7i ¹ÛÆH®ɾMð0}5œæ>'Ëçó5ÒX›H¦Š:†¹îœ0E6Dâ¢7Ë èZݿˡ´ð1fùŽé$½¸%³ Å*+¢‘–½Ïí¸½‘°5&ŽwÛŒñÏ³ëŒÆSvŸÊ^x(ÄŹ—gq:—~ñËDTI¸È8‹™º.Ø™¸–îI„“g‰Êcn—¿ŠÊs¼±ºŠÿy¾Ï/·ä1α°jtµñÃãyé2Dö=û ʽùo%žØmÎ72Æ4=Ïq#¢¥¯–V½ ‘PÉñÓÀ/0o[js_V<º›•Ëg̼„–nCï¢+µ>‰ºj ”¢»íÌEÐS@íP¦Ó–¾ªÛÙìvæÃÛæñŽÕes^Úð –¸u9¦­pêp#©|û™ÃÞà²Sb¯Û¦ê NŠŽ±Ú(ZzÁl`¦ÚÌ–¬]R‚œõ%©Õ()·ÇQ¥:ö¥:B’uJU:éP'T€¦Ú’Ôꔩ-N©J¦Þ¡¨-N½©N%*ÁìJU6ëJƒ­:¤ÒÒRÇŸü5©×êHŽŠ’Ôê”×SDêŠ\zÓª@S®•骯֔5¨¨W‡EIjª¤MN”U :)qN©ýt¸&iN¥ ˜ÃRZЏž§J¤€na©#µWóù*tö&¥Ät§Up?=Á )iOR¸•¨ëWMN”ü à`šUX !ÞD'Up?8xªt¦®÷tR⮢½©×µ\E;AÔ¬ÛJˆ© ÚÒ¢u Àaé¥Dè ¶ðtR¢TZÒIkBJP…š¼/¥«%ÇNû•‡Æq¯ÍÝóûí˜ý«wúyÝÛC÷Oû:Ûô,Y•Øì%jËbS±Ø>J¿"E›wˆLî^AÓ2äðñ^ó•ûmÊ^Ví¯ØÿÕ!_˜;üÿçÌßí{ÏÖ$]:}+}-Z•RǦ¤µ:«ÃŸü%©Ô¥¦ˆª@Sª—…4 §_»Jƒ©:¤íÓ`÷iRZV}p'ÁܧײÒÓÈ®ÏYÎP5Èü¦;aœúBË'E(™.Ñí^*MN‹}ºBxo;9³mËl3ml‹_¹®Ú{–ô÷lè38uÐðŒwO}?–{ãzd4˜{r †´ÖãÄF ¥^EHoG ýOÚöE³í˜èf­áã3lÕ„dB ƢѓtÀ­Ù7*'A"9@‚0ˆˆ˜F¿2²yœŽw%%õã-ËÞ\çÈKËœOð$ý<P_qãñVx‹&ZÛ€ÈÚÐX@ph Ãô®•ÉR™mÙ26oÌòÎÑ(n¬¼œ˜,Î(«€êº†kG*ûýGUÓ7€+rÛØ·ºÍ×Ré&~†ž ÆQϧPÔâÆðþˇjÕ³™Xb¼À†²&kpë/}ZÀGI£Cÿ¬Ò°Ç%ܳnÓ21Ò±=ªÄIwÒë‘è"©€‡8™ER€a0ê¥{ÙÆØDðû¸åš€ÈÅ\HãØkà^G¹2ykÚEc¦8I£žç^.  óÿ(Ý ­rN¾É¬u’¹&ÞÛwMQh“.™"£[î.ýu”Mªc¨¡¸Q(W¿m«ëo ¾)ú#·´p:µW¼Ô4P¸öñ5â¼Ö÷\×ËutÇÈ纮0=”#WWàà†œ´KÙ踟ï`3¦poܧïùDp»dÞ †ºŽœºÖjò×--Ö±i`ÁÒ5½ 9ÞÑoÜÚ>wÿ…ßåqY ¶Ü1•Ní’Id M !8©Í®ø€¬fG\ᨓRh™€6W}˜Ü–÷‹8ÍGK$‡€8¯ŠNšÐ[pxtU®ÿ%h¹ 2|ù ‹†Ï $S1;6ÇRHñŽVLM¡Š²R̘$s¦ è Bòë aß·¬ -’9¢ãSâêÿêýwºmÙïƒ8}`E£Ì„I¢Ý\q²úìÝ©K²ìǹ0ªŸ`C9ng ©ÄNQÓPä÷_û”[²FØÊÉcpã¸8pã@hïĹMûæ{ ÃÇ´ý¡Ðxý ò}|Çr LfØ”O(Bo71Duôg €ª¡˜,n›C å/½ÔµÖÁenðwBXxÛ»í0žŸiÄ~?É’³·ÊÀbž‚Aö\:ùâüKß³{õÄ|ƒu¼j ¦»u‹¸¡  Aï”ä1G¼bˆr {¥…í¾JÕ·VƱ»ñ°¼²öÎk ƒo8£‡AíD/œê®ÑjëU()×Q¥:¥*›¢•;SªPS¸)P'T ¦Ýz{õ%©Õ()ÕRZR‚u{ª÷¯ÙâÑ,ÙÀ/ü>D™²—‹är<\{E쀆É8ÑË>AÁÌ©@¡ö–Ðj;©P u÷ÚüüȶM³Î]¿¼gÔ1Õ¹.¥xÚܹÓ4pÿåHÃÛãpê_[òL³9Ë<ÆÚ‹I¾×0èž¶'?üÆ?èñWçfÄh´y2|ÕvR Ü.Ñë7h¨ÝÛGm”2.9n±Hª¬A)ÈpÀ !¨WÙûxÅ-³fˆ‡FáPAx‚àAA æ\À’9Ìr״Ђ(A ƒÐGEe‚~A­ˆµaj½Ã⥠`¯bõ¥.Â:äÈ XL££]ê›Ôeî\¨læá’ÈDÉ8a àªû¢‘ɸmÈ?Ÿ8‹¶oæƒ!ŸÆ%…£æ«ÛöK!µÀõ‡<´‚:A¨à¾ÃÉ[»mòÓ| .îzC¥œÝ–‘ÔZÀA Š+®1r˰Ë35š†”›O|†›q\‘f$¡@@wN™Ä¦ð€ˆ%wwHÕüÍãôxÿV™upœ‹¾#ÿœÿÓļ&³­”ݲ (mý7ŠmD SwÀ@C”š¾ÅÆâÙ45“Bù²úùÑËFp¢ý5ûDÈÒköÌZõ;ɼã¢îWoÑ2¾.¸S±~ÖíŒ$]B®ªd3„ùNB€è:WÁ¢ž|]Îõn ‘XÛ“iñkœECÑÀWIì%}qÌh¢¿‡kœˆ«ä½ƒYpãG÷]åGÓýaô.Sí0K€ÙKóEñ…‘rÝ©6ÖÒ‘weDج¥œA­þdèÊ?]V6eƈJ.ò94Õ(¬C(¤"@ÉË®hZbo?‡ö¶ZÉrÑ3¦-ÖÖx­ã4g@$p"®w¡‘æ]¾Ã¸È[|a=ÜS²Ûqn’ïðþ1-ñè à±ÝþÈ^²E©—1ÞdÎ-î«AÃLJ’†¹]±pœŒcØyrMÇmtÍät‚©œ€¡@Ú€€€ z~æÆÿ0[³>/Ä}ÃZ¥ñ‡.kÚæ“rêæ‚ ÑpwÜÛÙx²øë숼„’ÝLyiÔÒÒŠ‚ ¨\<3Î(ÏÞÖü;‘ð¼Ë‰ÛRåb¡&ýÔ ½¼à×$”#¤Ög2Ý£¥Ìœdk0*À˜ÄС¨F²X=Áµ?—ì¾ÞÜ1ˆî¢†rÖ‡¶A¡ò5â…„ã9ü+ZÔõ®•ÎW¸9ÃŽÌáž_o$‘T–¹‡[X暇OŠÆ”¥RèÏlC5$xî’ne cðï€Íé„<&0HÖoùq·3òþ޾Oþ°X¾uÊ"Þ»¯îÑAYí쮈J/„þ.Ûwˆ»YU Aå&ñ±¼± ;£ÉïŠPç­+ù‘´m¦ÿÛa.kOÿÔµm’¸7C6]ÐïÐ9|>ÉiGÐüqauÛÂb^Q.¯ã]62‚ûÒ qRrvà©(UP”t±’î˜Nch:€içémï16å…ÿ,ˆ8³GÝi“§‡µ ×…]ÞPƒk³3Wvœ/Cä Žš²Þ¬ü&ŸI_Ÿ»NK…Êï_ª¢¦UCœçPÂsÆ0˜Æ1¨˜Æ0ê"<µö>6Ä]÷ý•óMõ×p4·¥väܦF‘†´Þ_פ¥è£jI]í¨Ï@ID|_éò±l½ LD»4‹ÙÂÐB¸Û´qVye,­mã¿}uJØØÙ¨ÕÚžjEMOÒ©Û‹!sdÛ ©æ}›i¦7=ŧF’Z(:(8ìo¶ù¹Åœ!·ÝÞ`1m»DD»Ã§6£_.±w»ƒ<ÞºÅúI×Óé~Œ>%ÝT“ýH—KûíÔc8Ÿrô£ª‡Äwzb#Ìy›HÃå-zó-bÛ~YE(ûG%ÿòæZ#®Ý6ú’>¡c/úñ.«šÆ¹+4{I³¾5Æ2Î`®lÍ’VáIëèä-Ø6’O×™–xò8Åv›dQp²„D=òY »¹ð›K“69ÃgÇEŽ·¤E­y–G5¡Œk]âÔº†§ì€^x4®žk”Ü\Í»Æažb½’öjÈ šÀI{‰oƒíÒVReLìÔáÊèq Ä~XËÙ¿0¦Vn.¸¸‡ÎÌf«,͹Ð+ÂÆ‘bÌ«Q!ÊÙÜ뇤DH"A Ÿá÷G:wͰÈìü~7¶Ü\!t€P€ã]:«®†£S-ÚÂkÖ Ü2XWíIÍ–ä¼¾ÈfÀëXMA R´¦ž:]3œ:¨³G‡Ù~dø,â¹Ï öíßmY¨Z¹H—[Åg‹¾^ç.'2‚ᩞÎÏœ|TfåÐ o”Þ÷Â>[½­÷Õ·1°mß“ÚÏ’ïmŒfDzè4Ž?V£ÐxSŠß¶´ÛN}•–;F+ˆ¬»¹ÃĤ’_Ütнü4Ó¬q¯†žÃÇÊ<½3ha0’Æ€ÓQ×ûý@ÿzŸó9!~×ÄWÓ$ý^Ȇgò4ôf®¼\,¦/«½G*œà7,àŽñ„DDej"""""5ôvß²ûŬZº;¦ª‰æn»›‰4ô÷Žþ’½ÈâíG{$¸lTLvW.4d™À¤&˜Cß Z§¢e!Dl ®š›wQ—¶” ´þb³‘EÀ5·ë/…Çð’Oô/{Ürºã’¸©$âI„~Êâr^1ÞšÞöGpôÚÜt¢,nìI¢·Ð©»<­¨þè–nçt€BÝHAðŠ©ˆˆ÷ñ›I.ÿ˜,ÕÅà­Är_ÒelL#ÿÁáÿ„•ÞÝlm¿'1pÛBöZê êÒ8ÿ„/ð]¨Ý{ç=Xw• ÞÑT{ûÅŸ7ø+ëL¶9ŽÛ7Ò;í}Îcÿå¹|뎽ss¶‘·£ïQýö¯_½¥ ãd=¡Çͤƒ’m£æwÈeSø­Þe‘o 'H c(ODTú”DÁÉ_'rV[›~Xn›:ýé‚åÌ¡§ŽÛ0[Ç«8¯¡ù£oÜ,4û»ŒßøMÉüUYíOéçFqi2­¯4…ªýÍe4•^hÇ“ #$ùc²´n &³¶)¦¨v¤?bŠZ“MÑ+”—<ɵÅÝü mc-«î%tÅ¡úšÏ¼eaÒ‰«Ç¥mƃcÜd-þ-žî9Ù îÛqn’ïðãQ Ç 7‚Å,5uû(pFAµò­ƒ—s;{žÓ]Úñlj¸2pœ„kÈ—Í$£`5QËGlª™È Ž÷ €€W¤n,w=÷FlWŠ6€¥ñ‡.ii7ÐA¡ZN÷”˜ ¬Yl}î@]ÂM55妭- $OZÂÞ2óÖ6Î\UÜYH8•´ç-ËE³™'1p‹»šˆˆJ%ÙÖe,Ù«½äZ³A >àÄL4×JõžJás›[jEƒÎ´2ê9¥!¡Íx {Ë… IIq¥zJó®idñ[ƒpÉ–Ä»U»âŒ–’æ·I¨p€tu.´M]JQäå½Öœ*¼’©ÁMºt÷©Sµ:¥;‚–”êªm©-N©ANà¨-N©AMºô÷êhBuJU:½Ê^ê”î T¡:¤*›jKSªPSž µ:¥6øûµ©-N©N~J\SªR©·_v¦:¤…"Ôê”ë©-N©áÑRZRǦ¢”èN©MºtÑáN©@ô¨BuHz’Ôê5%©×± 9ô©-N©ãÓSNÄêútÒãÖŠ¤.4€p¤ZO… yêKS¨W‡†§J|UÀÜÃRB*Î*TìM\Ì4¸õ§T€z8pW…"©Wm©¢ujà~zZS⮩¡EUÀÂjhª¸<4´¦®Ì4¸„T…`8ÑÁ:޵p?pQDS±\ J‰ÔŽ•®´¨Š‚¬šTN[x)QM Ξ’ÞTy×T|f~noŸßlÇí[¿ÓȾîÚºx¿ÙÖß¡bÌþÃg+V[†Ï P…øòâDÛ¼EgÀïfœ¦+æt+öã•þVí¯øú¤+òû˜ÿ>fëï{ÏÖ$]2 sÖýÅj5ìHæ(ð§áH륧±:¤ó›¤µ:¤óù* Sª@>Þïr¤µ:ýk|·â\sQp1ÉŠ¯e^ É¹wL`®p&ù€ #¸™DLm<5׺¸ŽÒÝ÷SEK€ ®{x]q3`í8Óþÿ©~½¸c¶m<€l{R%©A`fÔæj‰H‹éiyUP;éG‚)˜ÅŽÕ/h±À@‰ ]wJZü§æmþSzoÛì•Ë¿4á¨ñk#`!¬oê´4t¸’zI_kòÎêô!‚6Öáò¸5ƒq$ç“@]C@Sä̾ò,î—q:„CxöÏdSh†úG~f(è"(]¦gæD†ß16ð€—NÿÚÚ1]†²(4’9¬.r²„A² Z‹xÖ¨¨‚@& •c2”yké¼&ÏÅ lÎ2Û‰mÚÐØèàÀI5{ˆ'ñEI¯Bð»ýÁw5ç} od‡\ƯBå¾ø»ØÙᑈ,¤&Š´ÖÊÖ£¨=‡Æað·ƒ\åéÍñ‚}Ÿ|vÎHæŒÄu·„rMÒ'•¾lëŒ!˜ªöy]Õ_ÊLcÙùËfU„Ë•Œb=‹xâ-ÒÚ®PYS(ªß+í~`s’¬nÙÜøI²¸H˜dŒ¿ÅgCZˈ㕎`Y¬l!-h o¾ç¶.yœóœÁe#Çå%ñ¤cÃx»¤—B÷ÆàãÐç±åŽ>7ŒI.ú¬n¸áMã<«Äo–J=ºdåáìÆ*¡õû1:ÈKBvﺯpEt@ÄA""Øç ÕÓQ1ŽSp󧛼ǵ~ÜØ›zëà²K‡¹ík¸Løà†Þ Ð¸—<,s]B±ønXòëeNÜÖìÌ[ß>È@hipâ+_,“PŠ€4´žp^RûB¸ã–ã{*C#n°‘€Ä6½ic@?:a ùËó ·dúmŽ«rJÊ¢I¤N©¶LSçXêz7(yW/±N‚W6|ýÑk®%h:@mtE4:RKˆî$hn—Ì]ÿ.ñÈ £k¢Ä[‚!cˆÔkö¤}8juÑ@I.'Øþ -Ì?5즻í|ù>½§‰¦nKª&î¹›8]¢öñdnË}¬4ÂnjøŒuÄ«EDë"«RupQC´ ðŽqKŸÆsþÞãkÄ'ÎÃi⌀CôÃ!{%µÕx !Ü|BEë¶}Ê ¡ÏHbÄÉq+^ðH,¬Œ u@4£ôž ·ûCMWGbÿfß6 ÊÊû¾8Î÷¦ ‚]ŒÉ´˜¶#]\°È,ÅÊK£xHÄ·Žv‰®»AYGd"u d÷‹¿æzÝàßÁmœ¾î™† òÙØžE ØÎå¯/oÖ¿KXhçíVß“›^ß*ܶ[;e.݉ÂBÐX×HÐjçw¥¡§€qmK…CCIa?´ßXÎ*3ÅšÏ?yúk…SxÚɸ‹ˆç—<“Èçs—s6Ë$Ýã&<+$b•`M¯l%LVɳrW•÷;3oÌÌës™";*#¡Á’ kG½ÒiWiÁ¡ÇÍ ùæËÆìSœ1V@ˆŸBÒ÷’ ¤€@ñZ7Uu£mãÂoµg XæXÊþâ{£Ú4}8´\r K=lÙ¥ÀŒ#i×ñ,¯.êYšO=³ä¥#WE=MÙ‘Auä'nïÞAn»›¬MŒÙ]“tî†8è–k,kŒ3D f·0Ç &‚¤hôoï£ÍÜù¸ñû¦Òí#Æ è-Dò´5Áì q :øîໃn fÍüFñ#‰2ª6ÜdÉmË »;rZ6QÛ¶.cÌämG2÷<å(FNŒ-š¢Ð‰´rb®e³)Ë—ÜÜÉæ2웵v> !tÏg{rçH×4Nô2&BÍCÆ{žKÛVDv dlítwéËYÞÚîîÖ88E{²é+¨|V†€×QÄð¨Á¼1±®BöÙyµ¬Ÿ…±²¹5høÓý´-›J؇V.%WjH¸÷o’hW/TÞìý-ÁÀ`Ý0úÎghe1|“¾Û }ÎW<,ð$šY¥|šÜ©Ik+¡¢ …ç˜ÍÇaÍ\뙆 Ý´†’ÈãŠ6³H.#KM58ôjqâQ{Q/Ë'!ñ¹%qãûÆÖ¾­ÓØV3"OY× MÏ wº#¶…”„vù‰œ¶1€Lß ˆoW_ùyÄåpÛ*,ŵť躘˜æñ<áBXð×Põqê\ÜäÈØd÷D—XÙḵ6ñøÞÙP F¦’*:ÅVsû^4,ÕR¶)7Ì™€5ŽšO 6îàÂçóRæ¬o,ã™Ñh3Ã$Aô’btÐê ¥hí[O83X|¦2îÚåñ‰5ˆ¥d…µd`j qÓRM:bàþË;öÈǹùiûþòµlhÆ7;›¼n‹f _8”¶TA˜IMÓü=bÛÙ;%ÀàÞ$l$Ϋ7s ưMIM[7ŸN!¼Ûئ7ms(Ñ7`ųääã–@‚cd8ºÕ€ÞüÝ78«)r{6åßÔÔ|@If²Æ¸Å4`–ks rh*@fÀ2ûWšø È]Ga¹àÖ ñ¨ô‡‰#}5iax]ÇpÿÜ"p…*¦fâˆ\Y“’·c¥ËoÙ5·å#¤Ý:dᜠ°æVã‘»¤ˆÍÑ…»dš\‰V2ƒÙ”ÅÊî>aï¾bÙ·llÌ%ýƒ¥{;Û‡:F¹ êw‘²ÔxÎ/%í«CF¢C ³6–˹9íÏ•´»µÚ! cƒ‰WAsÝ#¨|V†€×QÄðªò+äÛ[2çÛ!Ú6\=…mMH »iÂFEIJˆ„‹bÖ*8ª³‡nÞ<²O[²/0‹¥”ÐÆ.ƒ_Jl Ûwkˆ¼¸’òþ&ög¹Î/‘Î.u Év–“¥•㤠€W†ï Äy¬¼ù+hYmg#†ˆšÐÖ4¶¡  D N§õ‰¡_I¡J +Òx-¼S•M´‹Sª@S«¢ µ0R‚SBªPSn=ÚR¢uJ sÒÓØR‚›j SªPS«¢¤µ:¥:êhSªPSn4¼)Õ()S§±:¤*›jKSªP?pT–ª!TÛ¯MM(Š¥:B—UJ uôTÐU m"Ôëõ¤õÔ§T€}ºwxªKSªP??’¦‡©:¤9† uJ¥@zª@?0Ô–§^Ô€z‚ÔëØÌ:l©-N©üþJTìM ˜{¿ÃKÂRùéP„+Þ‘ju)ãRZGR¸<5:Sª@8óëRZUÀüü”¨GB¹†•{S¯j¸ŠŽ ÁJŠªUÀÚxjHEB¸ž§J|UÀÀ=á¥DUX !¶¦5p8tR¡M\n´ªBu*àq£‚8+‚Š"ŠÀ4¨Hé^€p¨–ôY‡Nú‡-~lï¯ß|Ïí[¿Ö$_víÝ<_ìëoбfŸa³ÍÕ–ÅE; žhЊ/Ưæâ?ˆ÷´Í¹X9Ê@ óßi¯jòÙºšàÖ88p=-5 ±c,bg5„jèýÔ¾»ûÓa¥ÎÉP;£2@ñŽÖ*B¡Šæu"V]Crœ„\ŒÊp×@=«¨î¬>ðâwSJöþ4¯"– ‚+¡ßˆ…ÆmÉå‘I2ª·ìÙ9;6.Ö§!¸Š.C³n¡{6ŽJEH"tôï×ýÕ£".–Hõ4ëP=‡á}*íY+ŸÝèêtp¡èãÕÒ»ÊÖ™›R5{_ Ã9go$±¤XJLöq-Ù–& #£ó¤ìL@Ý¢(”ÞQéËZ®FLtÒ6ç 7nÚM#¡Ôé¥WJÊÛÃsLw -ŒW¦€Ôq¨·BÜ®kË5«3p–½’íV(*ÝTõåÝ:'ÿ(w‡–·,LϹ°c¥¾+‡ao¢e mµóÚÏönñ‡€ÿßTeSmd V:©ANzšꔪm×§»Z\ª@S«Ê´Õ:¥:ú*KS)TÛPZUÄÀr‰L€†ƒPYQCШ8Ž ®/iµ~aU0ÜPyuAÖ°×xˆç:›Ò²vùÅâž…°Èpcn™c‰5ïj=êÆÿqÉÐOÜþôe*ªæp–ÓXÀ@Êœ£§~²v˜¸­øÓŠèÜ_¾nKÙhŒ­‹{³>1ÉV ~F–•”<^?{xÛ­oyÔÈV{ÔÔaj/"Iç„;6Ê*›s¤™Œô¢!òùÛ[‚oæZÇ9…ã°M‚0ë‘ ¦‘o3H3÷`‚@¡wI¤¯£¶¦o$.ñR]Û7*é^D&V H3FA—k5Ÿ³Ð ê^Û–¢®™B(bƒQ¯¦¬q/’M%xeÞA¬’…v,¨„z€²žýNþ¦åk5iŠd[ºV.ã éF‘з‰ˆ²‰èb†ø èÏwŽå´ë\V÷„Ô.2À;€±û=ÉäÒ°ÇúÒ§JÉz7¦œW5‡·[Æ¢bœÁ ˆÖNÛÈJq]ï_3«Ôí¤Q~/ü¡6õq·ÖÍÞõÕS¯œè»µ¿ÊGI° ~PÐÉ]‹›a‹¹9›¾wÎ&m­¶våõ´÷mÝãô±Üʘ¢da¬säuK†HpÛ0{iíLŒYüînÒx­Ý®6 ÔáÅ®á$Ž~“ã1µÔ©ÌŽ3øoŧY&«¶Öd$Te‹bñ;7ÊZ°¤^' ñóeff%Þ½Gß GLÂ& ˆû_(ö<»'nɸ-vAï3N[Å¢G†‚ÐzÃÖ2¿Ö-$p+Ëyº£Ý9™r0‚Û6°G<¡¤Hê.sœêuCкÆRÜm,Ô…P ƒ§.µí· ¸`í/,†íð¾ ð\8,ÀÛ€±û-{ÚòiX¿îgÖ•:Wûͧ«ŠçöõºÞºŸNQQÖ²V¶ ·+£qvé…ÌJ§Uw WV©ANòR¢uJ mêT Õ()RZR‚›u¨-N©J¦Ý*KSªPS¯¢¦…:¥*›z†•uJ uT–§T ¦ÝjKSªR©ÕPZª©AN¾ŠT(ªB©·¨iP'T §=NžÄê”ÛÝîÔ–§T€~®Š‚ÕUJ Á©¥T ¦Ý)xUU()J€ô"©û{½Ê’ÕUHç©-ERüÃÔ5%ªª”çòTТ©NaÖ—´ÒéiìN½‰@üÃRZ{UÀüõ%©Õ ˜zªKSª@??’•èM!OÌ4¼)Õ •èE{ù†‘ ×µ zjKS±\$ê=5%¡:«Ã¢•M yéxQ^Õp=¯B~p7w†¦‰Ôõ«‡ŸÇH„pêWóÔéOЏ0Ò¢*®-Nš¸:)P„Õ€iU:•èÏ ÉoC”t0¯Íõûï™ý«wúÄ‹îí¡û§‹ýmú,Úì6y+U[†Ï%_‹Ž' »Ä§¥æÎ9d•%¨ª@8ôÔéNªàpèé¤ZRƦ‰Ô,ºÀ²ní“°s’®î¹†êFYé²Px9 7mÓ‘¼£9)D·vÑ&{ÅÉu= ¢D5Ò÷;,ïíÍ•ûÚÌcf¸ÿã2&6ÿhx²½Òqš;£Q![Ö"9mìc’÷Ť´ÿd¸ŸÂ;Òõbâ¾,¢ZSØ®Š!bÏ02“nc·`÷ã çOdä]H¹xåc‚Š*(î Óå•,ðÙÙ3po9|Y¥¿ûόǚ½º"kXƱ­hZÝU¡è[ìw°Eg&66-ˆGÀôõ¹Î$’I4&€à±êÊOcI+fÁô)ËÊžJBkµŠX±æ`Ì¢éI4gÔC&]æL"";Îç¾›rn(ò¹ímŠ2ØéÝ3V³À¸¹ÏwŠ ñkAÂu1ï8ëSmdiª¤“ýcBßM+Ú±[+ÚºÅUäD¢AA“täRNc³ª›ÄXÇ•”I”jMÑÞÞß2¯x“—~Âgv´÷ÝÙŠéÒ-% 7‡M$þ%‡¼°»kìãÓÇ£²µXH³"Oª¢· ÈѲ+˪V+Ò©DD=ñ‰p£aŠ;½ü3Õ±ZÈ!¦¯u‰‰%•¥¢wzš½»v´”ÈÊ”aíkqÂÅ“¶žÄ¤Ôc6…AÊŽ»PÊw5Ð4Þ×½ÉZ”ù˜ÍÀö[#ƒZ$ÔÒãSð,£E§Ü¦kÞtpâ8žž¥Æ®; 2¶mEfßM̵E»øÒ¼·n¨¶äUÂnÜ<1 Ýx¥ÌàSéÈ`(ià¬Ø›q\Êö°C¨#[xPtb½œ+ÿ¦·ûnH\Y¸b ÙÂÛ±³íˆ`Ý%ÎÌW v…)ŠþN4‚`å×R‰uõsœniÃSîŸÓý ªeÍ›>Í»^>’» ƒf~›Þ"Ù´4pDníf—fRM3iƒ„‚8tÔG”G¾нÆI+÷‹«‡šIOÔ?Ì»L¿ Å ÞÊT­W:Ü-´½¸ª×1m§O"Z,»¸›RÊ¡'èm½<ȶ(ɦAtQT8{”+·q6RÙß’{~Ûº*hhMkÙõ®Åíëû÷ËÓV´ô V”!b¬­ÓsK¨ç³ÌkªíMÙ€öZÖháqђﺆÝ'€qúÇêXæß]HÆ»¾&¿WÔ¶ÛžàNï4¡4ÂnNÉùݱtäȱ"ï cvÀ€:Q@ß05åÛ]KhÙ÷'21¡Ìs™ÑNƒÃ¢Ÿ÷.Ôã/‰.i wOhãÓÚ»/¸{öpÌž÷¢ä´ASDª·UC¹HÔGû$Êp&¥8sVW÷eþ½ø¨íô,&ᎌ†N±©§ê5 °ANºÎÐ-f©M¾>í)§T ~%AjuìJ s IjuH TЧTÀ§]*êÛ§¹Hµ:¥÷AjuJU9†¤µ:¥*hSªÙeâ“•(úò t/,Ûr(WnÚäÀVáÌ‘È%ä »ka4Ž…3Ìev¢·Sú¹ËW R•Mµªª”ê©¡N©AN¿%*'T ¦ßN”ꔩ-N©J¦Ýj SªR©·Or¤‚SŸÖ¨R•M¾:E©Õ()ÕPZª©ANº‚ÔꔪmñÔЧTÀ§WE*ÁJU:Ý©-N©J¦Ý*KSªPS¸*4§UµËF!*€¤§. <¾}Úê\Ú¶áš\»\:T.¾=‚ A5L ˆ÷€G½­`Ý…p4i:VU¹0EHâ¹½k¶ˆþÓ@2Ÿí‡”u®ý¦5–ü¬º—7¯›‡Rç%S@Ъ²«¥T §UN’R‚äTN©A]¾:šê˜ç©-N©J¦Ýj UU)TÛ§¹S¤§T §^ÐþŠI‚”ªmñ÷êhªPSª‘juJ uÔ§T¥SnžçôT§T §pRLÄ¥Sn¾í*ê”ê©-N©ANº‚ÔêªmÓÜ©-UT §?“ú)qLÄ ¦ÝzjhT §U"ÕUJ mÖ µ:¤6éRZR‚u4!:¤*›téîÒ—…:¥)R½ Õ(˜jKQT€~z’ÕUH s»Z‚Ôêçä¥Å:¥6ëK‡Z*´§R·ü5%©×êH N”êÌ:ô÷kRZRùù)P¦·^ï%.iÕ •;^Ä€naîè©!:ö«úêKS¯b¸<¥I Õ zjt¦®Žš8„ê4¸"½©ôS±?¸¦‰×µ\=5$#À® -)Ô«€ó I©ÕzcÂ:[Ði9J>2kóW}þüfjÝþ±"ûÃgþébÿg[~…‹7ûÖ­Çé[GŒhãô¡~'8¢6œLñQöuËɲÿ¸¿p¹LßùU¶áüwêp¯Ë~`þþç?kÞ~±"èÐ0†·ò£R4¨B¸„øõ$s .íWóù)iM\ Ò¤„ê»âؾ$¬·ökæïå±R)á»n–nÖUË9-Y®DÀP6ìТUDÁ¾dÌÐy5›üU¶V) {é èK€:A”8}!•Óô¯B³•ñXC§ Æßõ?γ/[ ú䞺̻‚,Æß¥p+µœ3)E”„nvM¤ÛÆÌ‚ÅÜpÕœ„`.;¥WU›PPÇï‰Aþµ™Û¯{îd‰ä9Ѱ´‘Ð\ uôW‡Ô°»™´²ü@t•´ Óñ.. mÒ¶ÒÕ¥U()SNÄêªmÒ—…4 §pR êL…SoPÔ–§^Ô §UIjuJU6ëPZWzYü5ñ[äºìœ•®›id޳YÈ+䑌M08œb¶Ž:RÂQLCF¨ïh]5Ò²ÜÆØ8+ó‹Ìæ±vÙhèå¹…a4ûm/?×ÓÃBÙñû3wemþ7=‘d9®èÚ;£úµ]E%' ò&f=ôL¬s…ZHFI´pÂA‹´L$Y³Æn“IÃg 41R˜£È![e½Åµä º´‘’ÚÈÐæ½Žcšz×4Aê Э~hf¶™Ö÷ tw 4s\ \Ò:A„ÖªùM½C\¥«Ž©AJ’ÔÁJU9† µ:¥:©P§T §@ÔÐ'T ¦ß"Ôꔨ-UUÝ–gù÷!Áý¦±°ÎN»-ÑŠ36MÃ#ðSíRG¾nÀíä•HɈˆS b€é™Ž`lLï÷no1µÈuÇ-ÄL{kJkiuX x©l¸ÝŸºòö¿}Åão§³ê|pÈæÝ$6ާXmHúÂêéX¹{~Mì,ô\”Ìkƒµ’‰—dæ6J=Òc¢Ÿ0z’.š¸LGßBÁá Ùín­oí™yc,sÙÈÐæ=Žcšz \ÒZàzˆ$,ŽŤñܰÑÌsK\Ò:œ×Aú øÁN¾Šç \UJ mñÔ–§T §UAjuJ uÔ–§T¥SmM uLU;‚• R•Mºûµ%©Õ)TÛ¥AjuJ ]Iju]fáü¿‘#šÇø«$_PÍ_+æZϱ®{š1¼š-Ú»Z9wð±oZ¤ý¯QTȘà¡SX†ÐåÖòû¿iíû–Ù粘ë+Ç0<2{˜aya.hxli-.k€p%®¨+7ŽÛ›‹1¹ÄØ^Ý[5å¥ðÁ,­Òæ5À84‘ZЃÐBäR|;ñ #55‚3444Cr’ÒÒ˜Â÷aÝGoäd_»ƒE«&,š¤uYS4Ó(˜Â5жæÀ¾¹ŽÎÏ9‡šògµ‘ÆËËg=ïy kÖÈKœçÐ $€Wn}»í`}ÍÎ+%´l.{Ým3ZÖ´UÎs‹kZ$’¤®Ÿ:ú+n-Zà)J¦Ú‚ÕUJ utTéìLÉUµî¦ÖÛ+É͵>…¡%$´<}Ö¼4Š6ÛùvégL§Nرn¤I#èS*R”DJXæe1rd_‡Žæe£ŒHøŒ362@tUÖI8€ÒH¡]ÇX_²É¹'Á3qÏyce,pÏK%4— - u-Û§Mw¨ ê×µ0)Ü%©Õ()·Z‚ÔꔪmÓÜ©-*ª”ëÚ(¯bb©·Çߥ@SªPSª¤µUR‚u©Õ)TÛ§Oz¤´§UºEGÊMÈ3ˆ…/- ¹0ŒŠhâBAó•9nÍ“TÕråsøB˜Ãà ë]\ÛY[¾îöHáµµsÞàÖ4’ç8€í$Ío÷S6ÞÕ’áækAsœOPh“ô»>êÁY²Å‡ûCxâ|‡mAµ˜š´g#㚊›€™æûª8çÏu:t´:®œKAë ;Ú{£m÷Ì–>ò N·¾µ£ÿ-£~€ê~%ÕeSn•´­~©ANº‚Ôꔪmê’ÒR‚]•U)Të÷jhT ¦Ý)ªªPS® µ:¤*›z†§JuíJ wJu[¤T|œä‹xXçÓòncÑÃù)®T*MÙ±bÑ5];táSHše1Îa®½ÕÍ­•»ï/dd6‘4¹ï{ƒÆRç9Ä5­‰$€Jæ·‚{©ÙmjÇÉs#ƒZÖç9Ç€ h©$žR¾‰h©{zMì$üT”Ìjæk#0ÅÔd›$Ó}»ÖRAÓUɨjES½ê‹K«L…³/l%Ž{9©’F潎ok\ÒZáô‚B»›{›9Ýkyâ¹a£˜ö–=§±Íp Š¯¹Ý¹rÇBCܲüÛrâ;äíûäKö°“ªE¸3I4áåVnFgŽtQIpACŠ*”ú%uâÈãn/fÆÛÜ@ü¸i–&È×IxÔÃ$`—3[|fêPâ*$–7ÐZÅ}42²ÊbáŽc„rš;CÈÒí'ƒ´“CÀñ[@)·Jí–®µR‚ÁJ…0{M½CK‡ZuJ祧±:¤íî÷j Sª@?pT–§T }ºÔ–§U¿ÅÛ×Ó ™Hx ¹XËq²O. È§ÏØA4\çMS/ «x¶Ë(™ŠE2e0”@Dº79,}”ðÚÞ\AÍË‹bcÞÖ>WRØÚâ È  ·oc}u ·°Ë%¼ ‘ÍcœØÚz È0P´‚uÜ ]T€p¤Zª¿Z@8óÔ¢£À‹UU yõ¨-EUÀáÑKŠi@ý~Z\ð¤…Sª¸˜jHE{Rùêtªª¸˜jHíERÇÃËS§±5p8søèâRÆ—pW…*'Ç©\ ÍH„ëÚ½Já-ë}°éßI!ñ¦Aäñ׿ŽüýøÌþÖ»ýbE÷–ÏýÒÅþζý sv=ÚÖ©ÿn…±)Ø÷kGýº¿ ó—Ão&A¸k÷”£þUmŸø{úœ+òߘ5ø÷9û^óõ‰Dƒ¢½…jWxjH Õ\ÏKJÀÜÃRBu*àq¥Døx„ø¬ýáfÖ°²L;«{#½fÙx™f,.ÎÈPP¥e1©*Ø®ÖE·¤‹cœ ¢NÓ7¾˜µáüÁÍn-»vëœn– *ÙÚ5jh5{ÚŽ%ºÀà[N{Ô³Çå,!mì¢'†Q„Ò„´é-5 vÇ¡f]ÊâÚ‹;´Å™êˆç|G tìˆ)»bš´D…&ºróù~,dïešNíŽ"MÀPº¼ZâOk‰4Y›è ¶yŽ*<4‘¨Vœ:8Àº=ò-U6ôö†9Îc&át\{³X"tÛ  S€ººÖóo$ÌŒ‰t:ƒ¨Ö+ÒOWÒ°R†Ö­è[S(øÅc§"&£[º„¸Ìñ)ÖÆ(œ’MÙòÙN]ôÑ @£¼÷À 4ï"/s$µqmËÓJñ ð÷öp+‰²¸¾ÁXÃ/·¼œ^J䘈zví£!Ú,“uaH¡Ô¥ èê&w*¶ä1S\Û†ÿ-g¡Ý»Šä‹(àcdŒMzOgi§«é\BÂÑÕsÜü:ðùkaù †ç†œuq’êdÍ87Ί܆g¨Û–ªº§dºª»L¦*Å0ˆ<5ªîLÕæWL tN:À¯:EOObîE¬žéÇU>•”ïÛBL£gì“{ènÌ".›”ÄIôzåY£Ä¨Š6] ÝÐu.µ©1·1=¤º­ =GªŸŽ«•²ž£Ä-åÀ¢šn7Žeç÷¤Pºo Îrˆ‰Í®¿äë]i-ËYZŽŠPt ó®Q3öŠÐË‘EWQ¾è”Ü@ê€ t€Â:{ã”F˜Œµl½5¯ƒÂ¨=äTNÅMÅ`0‰È¡•ô(¨•0H»„1D…0‰‡Qðìä«€é#Å"”êÝ)§T ë ‚Ôê®ÛÝîT–§T §=M uJU6õRð§UœÏœUgåž#áÓÈlI/aã«^éË7\"‰tg#¬v$vÖ)Ëeqã'.Z‹†æ‘Ër#éÄCÆ9õº2Û[—³;!‹9¹†Æ ¡÷.-sÁZá~‡ 8µÀÔ霦ÁcóÛÂ1–h“g·R³¤=°¶¡¤u´¼·Sx‡6­"„® •øÄâ,߯¯—Ù*ñ¶ {[^سîy»rÛ²#˜¥Šˆ¶#"1lÁ(ÆÉ&Nܤ œ¢§2‚&¬Þ×å&ÄÚØ6a!ÇZ\šiáŽY®^~Ü“=íqqy$é'KAÒÐX¼÷0·f{*윷·xß›Ž_p´}–FÖ††Š ©ÄUÄž+(3$œNðAmñ+y&ƒœß‡rÂXZø¼Á² ¤r‘)„ͯ)q(܈¥!7åê “WtV2ETê‰Ê!æ»FѼ¶çEÇ.±ÍÙy|YÈ[[Ô–ZܲC̈Kc”5Ò×Hq`m(Ví¸®½¹gòÈ€íÍŽ¿sM@q ˜¤¥žÂàÀzHÔOH_~Vàç…®®è[S3q?v%!u[öôÜTU•‹BfJÙe8ܦ4ýò²³ Å¤Y•R¢ÍºYûa)ä)¸6·79›¿±Se6~Úµ0ZÏ,o}ÅïvÉÿelZœý:K¤“DMqÑWHäÏrïcm„v7p%ž(ÞÖÃm­Ñµãý¤Ä¿HmjªBѪ‚ ·W€‹õ§ {y[Œ­[VÊ[-Îfw/öEžA’oÍ’NUU@2jvhÙL^ß±)œÄÎz`ååí¾ö†Îáù;«Ác<ß» \[÷]D8]æŸödÈaʬ¬{Æm¯-Ä-±‚ØÝ>ðƒÝ 05wúA' éÑ«íÔjÒ Öû ÂÇÙ±­Ùnð½o Ó-Zì…ÊÆÊÈ8ä–ƒLŸ™Uš I¤Ì‚í%†ª·`ùHX ÂU“é^s?~lÙmrËÂZYí[»†Bë‹[¾ýÖoÒ?½1Ñ´9„ø¯’7im âKîÕ¶ÅÚ{–;‹M‘”¸¹ÏÛÂé öýйk_Ü8=Ä:œZÇG£€pÙ1_ ¸Âãá¥&2–p[Û-rÃüy) …ž­É1,›[sã†m,ä[I¶4¥Õ*ñBp Ú6d“‡j, ‡f~îçæ~åÇóܸÛ8Q‘É;Û¦HgÆÂé{·:à–1 MÔ÷Èèâk*ýC«ƒØ˜KÍ–7¦s&l¬›~ëw0Bd{€X€áªW ;KZÀùïIã÷‡kÈŘ×=áŒ7bl3;i˜.Ëu bîµ.û|uâeÙ³bñ)ÍÖYP0„OAÞæÈì^`fó[Ÿ#±w…„6;« sþbS4Á-(øÜæµÍ,%­s\*I¨¥×´1˜Ì–êÛ—rÝà/$|_ŒG,RÇÒÇ€ç4‡\<ë¨+Ч]zÉjóê­îÞuÚvÄóe^Á¡-´Ë$dÖy“ÄO"Õ”éЏfS¢(€Žº‡~ºwñÝÉc4vN ½tO¸ô5å¤1ÄPÔPžv-.¢}ÓKíD/¤°¨Ž$Tt¯o¸Žµ8¶Î× ån òãË󷇶‚ôpÎUoe<Æì"¡#›))`nØrÎi6Êt©.ôtÓ1S*eI?Œ9y”åNÈÃ|/ÍìS,wæ›ï3ä,ÃnÜùDŒºîæk£, T–ÇPçââç}5¼¬9º2_ßܺÈ:ëkãî"³º›vµ¸Èxp&”sè@ 0+‰kû0gÃãÜŸˆå­®!m¸¶XÞfb]›È»»+/+*Í•âZìTaRzŠÊ*šNˆ£„ß ¡9LRB½Ë—8-¥²±|þÚËEs°.%uÜqÆæ¾ Æ9×’5ï«H .a 1è ’Jò­é•Ü;Ÿ#ŽÄg1òC»¡`·{Þ eº.pl%ì-m5À¸?UA‹³¤øPáŽË¾Ú`ŒƒÅÌfnYÄ|,ÄŒ7ø×Ú7„¢hú=¯1p¸žc.÷°tá4W|š)7ncÿnŠj”šÕ·4¹“˜Á¿|`vÌ2l°×É%»Ñ}=» ¬ÑÄ"tm«Asc.sžˆ^ÒsSì-“Ê·jåó’3sÖ=Ì·×iÎ¥"|…í{¨Hx­¯¦Ž¯`ø8ŸBW‹býž=µtð¿b¿¼gl.Ã7)œÇwN\Ç.Ê&n-D·\Q2‚‚å&¨~÷›¶/µÚÙ<xÆn[æÀçètàú´‡>7‡1íÔ¦š8Ž+mË›¦OŸ±ÊÊ`¾ÁÚºRÝM–œ[BKHcÛG5Ô®— ¯°F i˜¬Î n·+˜0ž.y‘2B1'éÜ 6Qr[…”zÔc’?cþêR¬!¯ù5°o}ñ6ÑÌ`qqÛ6værm´./-1Žkµž?d–øV#kmX÷7-~ùÌGbn ﯊MFžŽšÈ{{„\…°¦vÍ\D«mœ«w({n>Ëyp]®& §RˆbÊ×i»Ó=ŠI¨,æIû„’M™½!Îè¦&æÆô»Þ9‘³vø¿Ébä€wϸlPåˆÈçLç†éyv–CLƒ¼y-vû>^í‹}µŒÝ;—0lì¯Ù/æÛ ’Rö<1¢ Òu0 ºG¸Ï´%àŽ'Ãf$³±¥–¸‰Ë%•“Ö˜qЬkÍFæ¾®;V)âmò—<œ¤LU»àU!ÐI]ãºI@:gÔ @ÊÞóuå÷%ÖÕåö*ÚòïØÅíÍÍÁ†Ú)žÒï»Ç¡’>WŠç6Ž®Xë]—·ñØ[}Á¼/æ¶·¾/6°A’y"i§|ýNc#i¨-‹¨=!n¡ÁQ.¼•aÁbLµmÞX²ý²&²Y²t“% ÏaÙÖš¨%y+~Û>–íäL¥¼«¶é1P©»UÊZ"‰Å>©ç!ÅíËëí׊¸³Üö7±ÙýÍŽ}æâpM¸µ›KZöJçBXÖ;ƒˆhw8å ¿ÍZZíü„8+»WÜýåÍ,0Cc(y4 , ¸—4}­Mn¹6mŽ;7·®s„ɽѱҴBøåcƒÙF¢Ð+S¨PÑGÉ?ü%AÞq¸š‰k®bþ~þ*ÕÓbc¸ù¼Y;4 HÝ™%¹BNu“'.Šš®›>ºˆ$%9K®·~óZ÷&ê°Û–°àcò6 ›·Gzø£©.Ð!ÑœHcÍGki9“´y}k’fß¼ÍÏ&Yïk °[µö­{éA«½Ôö´ ›Àÿ£BÑ85}ugŒÙ‚o;ê2Ì’ÃÖ%Ýw¸º Ðîm÷¿g¤-¦ì\?QuZ9‹€¹ñWŠ*Ýÿ¹k¹¹9Ã/cawÆÆKË|½ôui•½ë&. 8>V¾YP×8ý [ Ëio÷^Ojä®Ùm>6ÒYŒ´¬nîÝiq$ÆæÈ]BZÙ%}Iðá…o¬”æpng¹okÏ Z®/‹¢6ä°¾ÊÀ]V¤P˜'æm–w&ÍÔˆ+7É‚ÊJA!DÂbñžbo<&g½°öÖXlÍж…ðÝwòÁ;ÿÙGp45Ž/>)1 Ôê4¡±²öÆWsµ²SÜäñ–æy[$ÔrÄÏö„ë.£5‚µ¥€q¤(µrçy"ã±còS©„1­¥fZhÜ×Läd „™ÊÝRC!'Â.«‰&cv®ˆ`Q3h ÞËoÍɺ®¶žÀÇ[ß\c[¼žâs ¾P\È¡sä-¸FZá^ަ?há-0û‡x^Ík ëž-¢†!,¯lfŽ•ÚœÆµÄ:\ A¢Þr ¬`pÜç_ëå¥8u±¶¥²µ¤“sAËÛ‘Œ}!’ܵ9†xÞž è›3¶PJ¢©€(==³ÍY¯çÜqîËâ›·#ÓRa9=äs=Ô-kC‡æ‡u§Œí«Zïv3¼¾ŠÎ,+öíáÈÓålUˆÄ‡ÆÖÔ8öž=x0´Ð¹¼W+ÿ« /‚a'üJM/ ¨ZÎ&Zc£+‰™_\}–Vei¤f”I“zä{"6€¨bH¿â72eÂé܇á.뾺î—榮øF#1‚cüà‹Q}›7/Ä]çt^-ëhÙ맺// ˆd mx:ä "ãÆ7µÏîæ…eqÚRîá¥EAU¹—lxéšÆ"b»ÍÌESt½¢*ÚºW¯à3˜íË…¶Ïbœ_Ž»‰²0‘CCÒ8ÑÍ5k…Mê^m—Å^àò“â2 Ó{o!cÀâ*:Áëk…ÓN ‚¸™TÛ¯k-¤,}V{ð)w[2Ù†·•»²Åç×·0õýu,›(h[ñ3øñ–]' ¡ßÌ“ÑÁ ˜¢‰ŠMå T•ðŽxâr7ö˜‹Ãgq‘Ú¶y6BÖ]$‘ø®Ð263¯S¡Ô ¨Ð\ßYåNBÊÒç%l.a²Ü6F;;‰Hk!>3uCÿKˆê T×vÌ+~>¸l¸~_0/cµ™IÝòô[(X÷eºùƒ´žº—ô) ­H¶Å"¿¦8j‘ŠSTNrŸU½“üÆÇŒ{ NákÙÜHÛqes­sK[¦@xiîÚ÷_h#aµg76MáËe"¼Èá‹]ß1Ó¨%Í!Åú])hã«[šÅ$Wĸb'-þ¥d«Šámˆp¦?p”Å6£'—CƸ$VNÛ²í–;'óNJ€(c¦T‹º¢€"rþ£º÷•ÞÓþíÛxûwe÷ûK"Œ9°µÝÓšâgB(ÇP\jÖžÃ@ÛÛbßpýû7{3qÛḃHúK{Çî›â™x6¤Š 8ô€yeÀqµÏŒï£ÃÞHŸ½ZãQdã YW¥®µvÄÀH,£v÷LZ‘ò2QÓ1I¬‘ÅÁ ¸vÉNqïqXýý¸ñ›’Ïls”™-BÖâÞc4•€ ÃØÇÆòÐMCÜCZ:HÈ^m %þç=³¯fºŽÇI¸‚x„r²7¬Òç5ì¨:€¡h“Ð=_…Ì-ecÜ]’2Î{ql²ÉØý¥ÑjÅZ¥î‡NÛ‘ÁÙ¢F*?I­¼Äª¦S?p™{UOÙ”€%¬|ÏÞy­Á“Û›SÛ™±—î†IßpØá´Ð8ê .•Ô$DÂt´j$‚²¯Ø[c‡°Íî» ŠúÌJÈ™ |¥äVƒIp¶ wޤÐEÓÏ›^V¡4òú·ò•™hÞVÙ£SŒs6ÚìA»2MãÔP~‹òöb˜«¼P‚`.ðVå±÷ÈÜø{ûܼ,±Èbï'·ºYxŒÁÄ»QkIioé¥C€­³ºö™Àäí-qÒ:îÎþÚ­äÒ^%à§QÁÜ)^°M*»b_„èç[«Edfd·±u”ÖñÌ*b!Da¬´o)4“F,ݪ¬ÚÌÑ~‚h"URUuûB›³Ž%Õ-9¹#ö5®íºÇ<ä2—®·°³Ž@d¸%å‘—9Í0â×8µÍkt‘«SAØ.9pÆî˹ozß¹ØZ‰¯.^ x i:ËCšÚ‚çjN“AgÃæÊׂ|<勞ë¾ìˆ×BöUóe¥m«xÀÄn »Û9û)7Àg­ˆ¡L“ ƒ…·€=茒ówí‹Ë7smk‚½°‹‹kƒ0·–J÷m¸k˜ßЇHá´ë¨ #Ù»o=mr6vB{Œµ¬.”Ã<#4lûn…Ís¼aÒá¨×«‰_e‹Ã>0w„ì\픳_éí±rÎܯâR¶ÎN.æEÔ{–ËV ®âEg`Ðë9UDJ“4ÀÛûÁ\YÎeîx·¥öÆÛ_ï ´ÈÇ™„Q#÷:g8ÀÝA¬hqt‡¢”+“±°2m{MÙžÊ}ÎÂydc˜"2<–8µ¢ ÒK‰¡.% 0tÖ«'IÖreµ¾ùyHòÒ(BI9@Z¹ˆIâÉÆ¾rÔÅ)›.í‘H¡Ó!Œ! i^½bë¹la’ýŠýÑ0ÈÆA’‚ö‡u†º °*¼Þí¶ÑÝÊË7¹ö‘ÁŽ"…̆¸Ž¢[BGQà¶â©¶»«‚«1øJl¢9Sˆ™D’3,d:qmzBbtdÛØŽ-‹¨¦>ñb »•×8€Q1>È`ñîlHü·÷_/m‰ï³w­PжÊÚ“\º½D†µ££U\Úž úW.ØÜqÈo9À1b­IŠ£ºž±@>šç4é[¯¨—"Ú8o‰¦"Šd›e;;#=ÍæùFÁH°Ï¼)4ìrC´MväL(·›MâëÕå{ÎÝËf9i9!¸Û“qiZñ²º=ãZÞÞæG¼ôj}A\ûùƒ5Æo¨…]}†ç躷]ÙÞ°4témOH]“0ÎÙ’á‹7”«È;iÕßšÓ“’aY·H/é6!"Ìá©]‘˦‘ÀNR(&åÓA×,æÉÛs3}O‡‰“ä›gŽÐÇ?»i?uejú;MWH…j³—1XO±6”Y9‹®oµ9¬ÖGûéâÔV® Ã1ÌwávëÛÓÀuà B(-cd¸<9¦Ži.uÚ<†ñ.ªêȰVN”°pÆožŸÉíXH9€gvØå¶­\„ê)¢¯GÛrE—vö%Â[(¢^š˜Ê^þèåÚo÷þùÛ6±ç·ž }°ùÙ]Ï}=£^àÖ¾fwml€8€îìð'¶8 M›´³×ÄmŒ¬ÓgšÇÄÐwQ\âØ¬¹†€‘¬q§eHÛq_ –Ù‡¦³GÊdÆÖ®Pua\LßÛÎez3(‰S’£W!!s;–+b³wRI59„1³ºy‘—Åov~ÝÅœåÖ-·P¹²†6®–F~qÎ Yy“U\âÖW.¾ßØøÜ†Ú—ræòp¶·¿6ò5Ñ—:ñ:)sô†R€<š4…¼[|9bKžÇÉU,ØîX¹ ­¬Ê^^ÐtêJ~xÈÇ©¸cƒ†¯”¸^:ìh)¦EU! ažK˜»³œÆíga[q¹/±îÑÇpÖ²)ÞÒ!h‰­f§IRx†µ¥Ä.Í–ÉÛ—ø«íÀÜ£¡ÁÚ^ˆš÷ÂK¤ak\ Xwxâí-eá©ÎÃòn±£±D>nÄW¬åÛc¹¼W°'˜Ý0-àn+zåN3ã†à©>zÉã'qâSï³ L'0'™Û;×9qº¦Ù;ºÊ LÛlÅÔN‚S,RÂ_Ýš5®kšúŠš;€bó»[Þ‹um»©nq.¹6ò6XÄrG(n±].s\ÒÞ<:*:jiÉßáþ,3D@äŒí;!xHÅÇȈ0µ#n«JÒ^A P#ßOšt§]™NTY¤]À6šã ÞÆÏ ¯öÞ ðñÊæG÷Ùßó†kl]Õ"èox領]ù¶ÎÈÄ­3™iŸ“|msþë e†áö]'yùÂÞ“ }ªîž°%±ŽxÎaŒr«+ ÌIÊYml£)n_ÑòÖ<ìŠ%›É,ªP¦‰9œLGEÍ»2ÁºµiœÀß¹=ÇÉ™7>Þ‰ö¢IË“ßMjøîba–d×%PX{§ê ±m7gØa9žÌjF\1Ï€wAñÜ5ðHà^Hf–UÝüãt‚x9ut>>} ÅKìa•®¤,»*Ù‚‘’cñÄI^àöBDŽ fc“–PØC?IR íBŽöéuÒ¶{ÍÁsæÕƒsâ­]𽹕Œw{Þ›m,e%æ1WÈÒ ‡‹CÂ¥köØX%¶Üà27 ÅÚÁœÞï»ês«Û¯ƒXàtŸ½4 ©³!mãñ]ÅoÎ9¹í|«b²ºbd–+ÛLqo=mœ»œÁ,²:€!¾et†œ»fÎÝÒî;Œ®;!mr˜«çA#õ+Õ!´€âPoO®îm´Ì8ûÛ)]qÈZ6V8·I­$Š€š˜Éh'¬ž…Û’œ$¹m•c1[KѲàñ‹ ‘™.9˜ÿF†Æ-Å$fÙ¨VîÖVWâÆ‹ dͼoé$׳)T9u+^mG&Õ—uKdçE>Möxøc~©/N­¸U 3[ƒ6š‰h;Ç.ÍÃÞŽé¢H¬s{#ÛFZ:žÓBKô‚Ò8·V¡ö@$R/✅Á ‚rµÇsd+väÛ[^ï³ n7¾™EªI…¤õ¼“Å[¾"Z¨‹GIöÊ€€éJ¢„»­ý»¶Ä–÷›ïmm·®&lnžÞã¾6®wí,h-¯HÃ¥½ ìmé G¥"ªBG-›Ë‘E é9; y5QòždZg`æp>xuw‘‘S,tñšA#ÓÒà <`¦ìKŒ}Äc2d†T»û$õø*(OUGUVkHÆÈÛî“¶%ç+$@nv©¼rF6Фw"ä­âç á14A@[]wÒ †•æy»+æ ÎåÑV ð¨i„xÍ¡áÄ}kn½ÅÏm!Š'°tPôƒÐGQ¯Ð¶ÇÆU±»ŒLŠæHçHH¢ªÞNØ€:öb òVjôt/•þ©­ÄJÃô­˜ÆjìälOHjSHs&ºº@JÂsv…Ð4]à×@Ò÷isº¼+¦8tš…Ä%!¤Ñjç}Gj šŠŠIûS.rh`íìN˜ÉŽ‚!¯'‚³6—VÒHÑP$ T‚8£é¯RêÈÉ#ããið™sì9-!+f ¤³BF¹m3(Ù…ÒlœsS¦1äjˆ¥ì„‚n]Ð.ÊÔw,‹&ã ]£iÄ’H$ŸÁô®í±kâñxËÔ)OÆx.ÞMÙLCé¡Ä¿Û)¸c§ìÓÜÔ *x’µÇBC…xu ý&¾Ùèéÿx(I^ÇtÀ "øE1 ö€A|Dˆ`Ôû¾ÀÔhužº‚5Úð¯i?ç)‰h>Áü?÷-í“—àS¡¡Ûn½²¤M$„å8 j¨ªÇM4ÌTÇP.£ËÊ5Òš{~JÑ-iARiÖ'_à]¸m¯&«âˆèë&£ë4[ÜkB¬à)0YP"mdÑzä `)^>7f͸€j"'8ìïWNæg2>ùwQ‘þÒâ¬oþ«\~ ²Ö±Èá“5Òö £à/û#ð•Ü6ý¨ñ€œ‰Ã¶Pÿè‹ìËâî’jþ‰„ºî¢u÷Õ¦ä2ÐÈx<££PÓOQlc¤ý.'À¶;k e>ï飵Jÿ ¿ú£ÿ >µÄstls otÄôm%w4û(È[6ºzêX¾Š ‰S!—t©ö§7„5ËìÉnï³öóÞ=ò[Z“;µgM  ð.¦P[ÇlYnƳX é$ŸÆh¼QÈ­˜Â\jÆ»$ƒ[Q‡ZA!Éô¿¤.öqÂ"_xfä–vª(˜¼†A }gµÛ$ØßïšXû§™OKYÁ±ƒØK@q®+Å7<ÍvKîÌ5l ¨ëwK¿§€Á@ûkb-Zõ~´ q¥DêÏ¥/ uJë¥AÔŠ¤óPÔ–§T€~%Ij`¬»à‡;Û¼?ñn]×»uãÉø©Ü‘nš«.Ÿy1çÏŠÝ휧ð»U"ê*Š"e•åçÙ ÷°î1Xgçà–;«RHÏnímmO^ÝL$ç㤿òÓtZm=ÙC&ÒìD±¾ ŠTžêfés¨8'KÈHiT…Ú7³ˆ´¢|)m¡ñdûµÇÙBømy)è c–˜TòíKnË ÝbâN$’\§Ü9Ó.ýkxæ`ÿwiÞWÂnhÕÌS2X¥ÇŽíÝë Ææjqnš´8Ñfò<žÝß|®Ú„e0rº°\Á$ncØOŠ^uŽíÀ@ZW&âRÔáã…«Sƒ¨+ÂÞ½²tþIW2g¹K>E »jÖ’B8s¶žlc5•}‚ 8~Tµ+gÄ éXÝ…m“ßÜͺæåõ¥Å–Ûƒ,1Œ†9¦aË-ÙˆøÌkÉsb'‹ãxáV®îížÃhìx9ykq Îj[Ͻß:'ǃ4Gn89Í9ôû/oOŒ²‡Î¸…ÎA[×V'±>Û@IcleæF*~ÜL¶ä³H2Í®´K3un¦-WMÉr™¨Ý@10Ê_5äW6vËØw½Ó}÷;øò7’†>)zÇIÀÀZÇ6S¨°—‚ Gwnkr÷wnmÙö×ï6³¶asdóo â%p1ð!ÁÎ¥¦ ž w?XÕ·׎‡¼ñë·L¸2µ8a´òÖ”tÆ/¸3 €2sMØNKz.BÚ”“ž]‚Ç\ šÎ)ÅDÌmFï—ûŠNYZoK»;öDýá>b{X 㼊ÂëDeÑèñÙ3ehmKY&²F—°Ûîü37ÍÆÙ·¹´sÛ·"ÆÅq(kí¤»ƒSÃ_«ÅtnsÜÂMs4€j ãv;®6ñÌ•ÏåK†Žm u 9"ï-¾Âø´8~V.µ·,tí©–R÷$µÒ‰ÔA²[qrS9Ô"JdsQògpÛÛ`¶ÅöãÜùl„ѱ¶-È^Ð7P.–äÍ™! 9ÆFÕ¤P5®{zxÇó/4ùl害î7FÎÚ¥ÚHÃݽ®‘òе¡†Ž*I 8mq¼Qç²¢Üz©S*®øé~áR¢B¤‰T_] œL¾õ4ÀÆ÷¥@JõÜ|Bæ~âWKvK@¯A}âzÏÒ¼êòC'"¡‘Ôvèqú8ÚJ~ Žù?ÿåÆ þ¨/pÿå™ú¼ ÿþ˜ÍWü5oúh”åüÆ~Û›ôr/9N௡hBñÐW(³][MîÛYÅèÑôœ…ǵٿ¢Ê>¶R“jyæqÎGÿf~æ,ª‘?Ø(`c2ñddÅ]G‡{#˺ÞAž51³ž:Ú¤¸u€BîãŸdÌ„É5ÏÇ ˜ekMèÆ°ÓÔâÚ€zŠôG%ð3–˜ßÇ¿¸3BO*ákt$±Å÷ޝçSè¹nŠ® .¥+=/ èÆIEI 1»âEAT“ùÿns¯jÍ‚.oº<^ñ¥—v×p=±ÈA KX褎FÑÀ4šÐis½{5Ë üYc•åÈ}þÛ”‡[Ïo3KØcÈsdcØj p)R©£½óVaý![€hÜýq±¿ø†Á÷ó‹»1ÈGʰ».[FÄ5Ýú"ѹ®Ç.‘šºÑƒD«#¬ªÄQ®ùÌ à«8Ò6vÒø­›êãb[¾Ã`æ¬ {3Ü÷l“ÃÃLp ipkZCèîË#Ú7&âø}ÛR×3n÷v2ìËvæ¹²Éë\Ȥ‘¤‡Ê€$[R|pçõîcàw4ež%îÌ…`%qàü¹~Jå¬àÂç·ÆË‡³.é…îYI)%¤“Z9kQk¤fê& œ[fCï]ƒhó«gín\Zà3¦K}銱e›ñΆ_¼Iqb1¬ !ârÖ»P:F³¨Šb7,w&z\eñ!“mŒ…Óî[zÙcîY ¯29Îqp-1á¤GOjG5Ê–M{A-\i1!)–0ö'äY±igl˜(ØHBI8XŒ]+0ý58Ã"‚Ú•2œÅóÉ6ÆW—œ·ØYMDZÛb³¢êúŒskÄ•¦F¨Ú@—…[!ÑBâÐwgqûËzîÛ,‘¾{üI‚Ö®NøXÖǤ—¸9ƒW SßùO `N7$²´C+.VàáÒy´E™'1¥ê¼{A~w«yƒ—nã ='Fé.ë± kÙå)ŒO0¹¶7žúÙ–Û^gÞZÁ¸"2\27‹pçi¤BWµòÓÆsY«Ki¨‚@XŸ³ó»gjni³Ñ¶Úypï …Ïi˜´j¬†6’[|PçSQû €Jé)O§žÎ±ïkÄG’ö³ktå“kÎ>`ÿ÷ø¯Õî±¾¿é¶Ïÿ…v6VÆ·X#…ËÛÆ…ý-ˆq >Éö TŒbwU£-g‹vq“ÊÁÌ ã\™‘1û,—ž¸~½-IX)æñS®!¾&^Fº²mœ&rvôÂWcÖ+Ö‡Ò(Š)˜TIÁ6™9{Îmm&î=¹¿~ÜÁç­çd±Ç=ý´mx¸šÑš,f-m1È*ãã¸ite£+²qÖܼÜ' š¼´nk+ˆš'Fð×Åi3ËL1Ü;S£x“Kµ°Ð}–Mx'´¬bq£eÜ’÷VJ°øjá¦Ì°˜LIÉæ§øƒú+C"ÁÒlÚÙç·¥JÜoî-þÁ2T;DÕ1u2†"*ë9·rs1Ž‹·/·ãÌ_IŽmýæ§UÍ.uÇzÇ2&ÅöœdƒCžÜæ-¼ÉÆÞÉ™´Âáq¶Œ{xëKj 4ÐCݸ:GIöZx‚GC]áì̺ósÓ.E39–“&àQ@SߺUÒ¢›T΢mÓ€#¥}©ihË;H¬ã¯wm`©ÔhÖ†Š¸Ð“AÓA^•ó Åînd¹}5È÷8ÐPUēë§£©|%SnÞ*ç-\U^¬áLI‘³_³ví´1}®êî¹RâôÓ'Šfî5šÅŒeŠí$;í¥^°l$EW©@'þ@×O—7–ëÛÛ3ùˆ´Ën[–ÚcŽÓîÃÜ׸kuìä6Œk×uS‡J÷µ·ó;›“7츽‡^Z–ÚÄ «‹GG]x¬t‘àŒxçòÒXNq´t['R/ÜžrÎ9[²d‚Ž].b¥qS1„ Q0€rz¿=ùKwq­¾f\Jö± Gp*ç8ÅN$Ä€´é¹OÌ;x_q62VÃKœuÃÀ4TžW€ !8L|—Õ^1/äd•‘¿œ†<øÝâÖ½á†Mƒ«Þð•*{À0Q,X˜Œ;tÌ‘ž1@j¡´jÂîon1Ê,Œ[Ø7ïW÷eâÚMmµ»+ÿÅ{œ ºHpSA:ehÛ¶£—8SÌ\°yšìýÞÎÜ8´ÎÍM3ÌêQm#Ô(_BGÉì‹*Ñ០#.HÝO%8zâJï’±2Ô“¥–Y‚y =c¸Bå“zs¬Œåµ? ‚2›|Ü•Ä šîfï-ÌŽNÞíK{VE¿öìÐ2æÅ8Ú¸ac@9¢cX(\Ó*4fq¶Øý“Ì›]Á5äÚ¨¦tn$–‹†š‰î!ñÈæ¶G8Ô5ÚÝC¨ vŒözfö·t³\†hlsŠ-öÒòÓ9ÊRNFÄ%ºÁ³…㦢ým's˜ˆ•Ɉ9'n© ¸pA¹çöË—¸6CtÜ:6Gc$eÏzâã~¨Ëcî¼bçŸéñI¨Zt< Üñä$fcº²ÀB×½÷ÎsvÐK^Ú>¯×À5£Æ¼`(Vó~Š û7ðù[.w ‰Ä½îFº€ž–;~ÑnÀÊÂMóîˆé¨é­tðZÝüÄeÌ€6C¶íª¨½Š¢´§Eh+Ó@»m#“8á.g÷Üô4¥GvúTÒ½•ú×0zÒÖ”àÃèÛåú‘vT—7£ ÂM%c­gw{†÷ôÖœQœJЍÐwDºéX˜fÊ[s‹zÜá#æcÛöî·a¶àÄÒ:ä }+#,vò×kÔyüÄ͙աlFb$p=D2¦«-硸²²ók[{ Øx§ðËq@üQxÄÛX‹ìœ¶?+¶B[‚fõ¹ÍÍHÏK4Pæ1QP(áOxC{CyMç*³;-Ù ã}”Ës*Ky{ËwÍßÇu¥ßšŽÞG"Ô¸wAƒÆ x£Ðní¹ŒÜí³ÛV–íÉ™¢fÇiÝ> ·óš@÷ºGŠžYqà ñŽÈ‘¿íÓí nrXÿòî'®ã‡üØÿö›?Òß.«OüÓÞ°.Gh°ïƒëmq¥Ë®œåÁñ0J½w™-›ÿجWœr°ÿ¹noønïýP»ýÆ7ŸÜ:pµp`Ø¢_¸ºÏ‘ÅYψ}œí­,Ñò‡”}ñÓc„|ûVÊ..w LDuîkø-ˇå0·=†ö”ÙZäîÙ{i9Ãx®Ôk'”&.{Æ>Àqh´rU®. Åâ'”d™Ñlt¸¤¹È¹LMÎоgÌ­ïÊmñµn1øÎç1º. s,£†ÞGÝ ÜÚDà{±$aŽ!Ï-ÔÐXAÕ¤ï;ksjno/ûÜnÞPë§Ë3na²4e.h!¥¡ÔqR£Ÿa<¯{EñaðŒn< ºéÌ.²Ž³r,›zø^PÌÞ@DÄܽ”C)ƱMHå›S ˜¸&šj<ôÚ·Ø[«¸÷¤™î›\Cl²’J%¶”3Se’Hk#¢sÜY#ÅAÑ©Õsš—ÚùûLœƒ µÙgýãq’7VpÜ1†9ã.¡Œ’ŒkÃsš¨(Ö¸¾éšâRÇÂYn{-ÂaLq[/lHÛq®/²â¯Œ¤7KFÉÂÁ¡oI7‘dÞ5»€pwŠ‘DÑíHCf1{».\f÷®&ÇiÍšÏ\Ûܶåó:öáöÖ]Ñd’XXâò4ÚAwØ$jðßÜïl^×ÈÝî(±xˆ&Ð66ÚÂÉî»ÀZæ0Fàæ†ƒ¨¼‚Úé$tWÓðT<ü<Æþ™o£ù£yÿÄþ‡-S˜Çÿ mØíþ²…);#a«.øÈ/ü ]Mê«UE1u9`LAIÝV»ÖP†Qgì²,"dhA•4QÉï•(ŸóNÛ7·w…îÃÜo‹X-Ã…tÇu¬‚g8ºÒBd< s‹’· >/5¶­r¹—ûjO,Ô4«íߥ‰ õ¹· ƒˆºGÖ\f“Ì_ê,.fËîö÷,t%ýÅ·ŠŸ\z C®’Jàö‹>,-û¡Ìµçdðû„íM’rYÞ4Ç Ý&‹™‹ËyÜKæÏæU—8‘4JÔåSE½öé½àæòÓr«!‹m¦÷pf²×e¬f=·—}ãÉpÔÙ[#KcŠ—Šx¼*Õzh´©î_yÊ[Û¹såÜÎy iºÝŽ$6§HãÑSN…³Úÿ°Wú|µ“þ"‡®æ\ÏÌHáŸô².®7þäkÅú6/ªP7³æl¨t›‹&ep¢eßQ4@§L‚:åLD@<#\Wáãù€ƒ»Éð›¨A?{–•=•\–š&åï ñ©4û´u§ÓE•9ÞÏ6TôTO Ön<·pOÙÛ}ÜUk Œ¥žŽZ)¢Ów ùz^M¤Îš¤Á`PÊ5 ‹tÄ¥0ˆ|³Ø™« nù¯y‘¸ß_x•²ØºKÖžáV¶ö倂Í4÷E ^˜²ÝØ«¸íùwmeÒî#,» µx‘¥€É%Äóô:µ¨PõpÉ6aí6ÅN$äY³²ÛɤÕãù\cvÇ1âM=däž&š%(ñÕ)@9@+§¶’åŸ+´o¨¼s´ñ.kY{Ý^“â1¤¸ž€ +³yß.=iÕ ž•B@8R-N§Â<õ%©Ô+ÃÃS¥:¯^ø4OzÖ;í¢<íӯ̽ûûóšý­yúÄ‹ï]û£Šýmú,ðìvŒkS[ŽÀñ_…+ÄŠn%C½¦ÌâÈ·Wîg)þíø{úœ+òÓ˜_¿ÙÊ{âóõ™Aë^E¨T…`0…¨=*à~à¤;ÀÀ4"§­X !Þ(Ÿ¥p?=NžÄÒ­•:@å$×H‹¶rTÕ.ò`»7);js—A&G(N_öiï¼a¬fZÉ×Ö/¼%¥Z~‘þ~#ëY<>Cûºý—ÿeZv½¸{²¶¹´uµÄdøÂŽd”á¨8P‡MAÀÚ½§¹ ³A3dà°á^#‡FžÂg3Gâá2psr°ÉâÆŽ•…”Û÷ 2‘©‰œöb %ñ€4¬t–°ÎíE¿œm%ŽÿÚiñ” ‰#ûTw„>°j"JJP¢vë@Y%)SQWŒ$ Ü J&ûhùˆ ª˜5¤(&”¾é0£›wrÃZ!k‡¥Í¯¥qºâÕü%¶ŒŸôjßè4üK‹O½HƼÇì^·tA"Åe~ÜN@0  ñ#n”GT'(rdíáÊ襵è«Oõ¡ßåë\“ýx_à#ü…r¸'%dÕ˜îA»t Îo"¡HEJnª:Žð€ ®¼µÕ¹ŠÿYuÎF>ôŠP[šWüŠ»ûÍ[’ߦCÇësF®]ÃØXP §¡Dª->õa0‘C¦}¼…ÝÔ@L‡–(ÇûLÁ=‚&Ž‘Û_誦]BÑHì¢I{ŠÞûp³–¤hþÛ‚D¥T“8dÞ&/)^¼2¢U chœµÒ‘¸ØçÌË«‡pûRÔÿám8.Ôwwã„FGú,ñš­í½°ÑáÁ[Žz^qN]QUë‚¶ÔâQM‚GM±SÓ“Mšº’e¦„hÅÛÁnÎÐÖêáÚóWWëRèß3ëu#äãÖISzÔ»’ÒbÙªiÇ1'Úvi‰)L¢€A(ï)ºDÌaè<£ ~´¬ÅÍIJ—\ÉWR¦§ x8žµ²aÃc5kG`<;?Ëô.Ûe¶âe„L_ìôÝ( sŽš€Duæ­N[¦j$ž+`û¼’4 VBâ:z>’z8u¬Eâû Ââë=7ʼE{¶u³ÈË&8§Ij“¤Á;†ër™4›52mª%ÿvqÉïLcÔù_ˆ½Ü9?¹BÇ7LJ\?¨éã5ë5¬Žh?Õmx€«ºnáÂØÙÈ3DMí'†¡×N zÅHà¼7:çYE9„Ê*s(sˆ‰ŽqG^QÔF¾Ïclc@}|èù#Ì’q{‰$ý'ŠÔÏËOObš«ù‡¨i§T€~z)Õ ˜jKSªPSž• uH mÒ—…4€~१±:­É¬´‹4¶g"õ«g¤Þ7nítv˜éŠnRMBr jº40‡†ºòÚÛÌöÉ4ltŒ5i-´ôÔ8€xv.V\M\ÈÞæ±Ãˆ€|4à~µóùêËTUe÷|GÃñ˜G"Ù,n[b%l{gÙnãæjÝó£Ûñ~€ÿ·,Kçm–v~RÇ1Ê(w«ÉùKËÛ½´þÌ¾Þæè_Ïp×FZÞõú›Mmihé p=oüÂÞû»pÿ{ã[<Ha-yÇ»n—WCˆ-=@ŸX” WªñZ ~µ¸-&ýÚ-[º|íÓv$2lpåe‘f™€€b5MC˜È`H  PÐæ áe½¼Ot‘1¬‘æ® \{IIéí\¯šYÖHç´PIÁÙÑÔ€ê÷+µER‚}ªªÛPZR‚œô¨z“ªÜ˜ËHÇ †zÄ˳XYº]°¬Ÿ³PQ:b¡5ð¡]y­­î±àM¡í‹–9憦'9•hH¨ì4_8)ÕÑ\ºj¢«ïNIé*À•ŠêeÙ‘Â¥j²¤ÝÜUVÅ8"¢…Ü % š¸m ”Næ7¿h u ;éjäÈbpˆš‘SB{HèFšÆLå:g2jÅ9S LC”u)Š`˜¢€÷ÀjœÀàZáV”ƒˆ5#ð¯©Ã×/;—ŽváQUÕT]uD QULcœ@¥åðWp²áhlc 8*|‘Åò8¹ç¤“R~µR©·ÇUNÔª¾öR/#Ö :bà bìÜ*Ù`!ƒCDäP ok × ÖðÜ3»|}ŽÀx.Hæ–k‰ÎkûA þ$}©Œ"cxÆ1Œ#©„G”DDyDDj´(85©©é_z’oœ Ý«‡®ÖlÐ [,áelÓx¢s™4@Ú» é\ ¶†7ºXØÑ#þÑï OÖ¹]4¯cc{œæ7 h<«êB Ué§BŠ¥6øûµ©§juL t‡”)Rªª”ëè©-@)J¦Ú‚ÕUJ TЧU÷šIê­b£ÇJ1ns(Ý™Ü*f¨(q9Žt[˜âŠG9”0ˆ@DL<ã\"[)œ1¢w 5Ã=' uõÊfÆ"sÝ€I ðŽ´ESn5zAQT §pT–¦ ûÍ ñVÈ2QÛ•¶1ÌÝ¡×Tí›™Cê aI#(c˜J¨ˆë\Þ&ÈéšÆ‰]ÒàM:*zM>•Êe‘̹ÎîÛÐ+P+ÓAÐ>¤ESn•T*j˜ëè©N«1±þLá†W[vNb±²E¥uZN'K%àp´ž¾ ç¦ìÑ>é^9 ÅveIªä\û©¡¸* ¾GžÛ|˵ܗ9­¡}Ž»Åݶ2lòx1[IK{ËWBXRç´´UÄšý>‹‰ÍlkŒ$8½Çk{on^Ír;$5ÑpÙKC´Òpq൫qž-ü®\oeãëfJÑÄønØqkXQS¯Ñ‘¹übá“—Æá™Iœ¼ã–¨™T›’ §¨ÛÚ¿Ë͵ŽG3Ÿ¹Žïuf.D×O‰¥·@-Šƒ¼sAÎ s¨ã^N==纬óâˈöûŠHà騂ù$#Åy¡¼:Mxc™$ž‘¢ŒñÉXª ,«2¸T­X74UFà~Äê&_|%×Þ‡0W¡:Þ(œ±½ø Ô`=4âxW­i¢if 物4'¶ATÛã«¡QT §WE*& b©Ð>íIju_z²œ ƒW®Ù°6l»••A¸w@Hç2i4÷ •×m¬½ÒÆÆ6Gt'ÂGõ®gO3Ø#{œæ7 h< }HJ²Õ_s™ÕŸGÈKžzI5?„ª‚ŸÖËRªPSnµ¢*¾Åºpš¸tådš”HÙ%—UT›Û b C˜J‰L. Päjâd1Fç=Œh{\@ŸoIéí\®–G´5î%­è’ƒ³êT:êèU 9é§T ¥AjuHÛ§wФµURœþJšŠ¥*œÃÕKÂRè¥zª@?0÷tT–§^Ô€~z‚ÔÁìHæÔêÏä©¥:HSó êJ€ô"«Ù. ÓÞ´£‹1Ôv¶K½_˜Ûû†úÍ~Ö¼ýbE÷ÆÎýÑÅ~Ͷý zöA³ÅZVÇÅNÈ6x¨ª8¯Áç§(]ßn4ì•!• &Fè'|¢á}Ó€9ÒoÈ#Èÿeh¹)5´†š—;ñŒÿBØñO0ÈñâøúzÑ—³‘…ì—÷•âè ˆv¬á Z¨CK\Ó—jœ[‡A9D¦.§û“tµ9Ä“mmŒ®çʳ‹i×À¾B˜™Zj?I?e¿iÇ£…HÌÞä­m,ß!¶ÂºYZ8šŸìŽ©Àt4_Ì·–®ÌÍ{J^÷k;ÇÆ*,c[¨¡£`â1ý"13èlÑ5Sî–PÆPÚ ·K÷–ÏÚvG2É´-s¿¬ç´ç·8ñ>…óVéÜsî,ƒ®OpŠ?îêphêI+­@áÑ[QjÖkØ54N½©Nz\Sð$)ù‡ª—U œI¼m›Êøêí¼&˜[ÖäO¦ÇÇ|c1&¹1iéÒÎØF´í×P Ú.²I]L`ZÄæòøÝ»‰¹Îæ$îqvºY_¥ïÑ\í,kžêÐÖ¸ž W½Ìä!Åc™Þ_ÜHØãmZÝOq£F§´Tõ¸€:ÊܲF:¾1 ïpcŒ“n¼µo[YÙXÎA½Q¢ê´YVè»nt°pî=û7lÜ&²¬³uÑPª&sÀ#Á··uá Ü;zá—X{–jŽF‡à i«\æ¹®®kÚ×5ÀµÀBæÌaò{'.1 É@í/c¨H$(ZK\ µÍ%®H ­âàÄYÔÆØó/O[ÞŽò«‹¥…püoëãçlª°—"³“s9ñl¢&KW­›m7’“CWVÃvmì¦á¿Ú–7óø¶Â똴HÞè\0I Öæß­„;óo~ž‡i<=ÞßËØa­3÷pèÄ_kaÖaqdž q{t¸SÇkkÒÚŽ+®ýÁ[•‡ªû™¶xý^Á‹W/—Ü:‚‹Tp°&˜j¢š$9÷¢:h\I ×;šÆV•qTô žW$qÉ+´ÆÒçtÐM>¥Ø¶î#È·V7ÈYvÞôì{ŠÜ[-/Û‡ãx&¿¸¼eS„¶Óø©ä›iÉOŒdÖ*Z²là¨ë¼¨ššµì†êÛø½Ãaµ/®4gòm™ÖÑwrô[°É)ÖÖÙ¡€ŸÎ=…Ý Ôx,½ž1}†»ÏÚůbcÉ©ƒA™Ú#ñKƒÝ©Ä®§K¨8®¹6ÖÃ¥aêê¥áN©NºTª@Sn5%ªª”Ü%©ÕvÎ"Âyc;Ü*ÚØ’Ș½f7’­c¢ˆ˜¤y9;*å„5Q)UxåÌpÝä­Wuï-­²,Ou^Ãghçin­N|ŽþÌq°:I\ØØâ(³Ø µžÝ7fÇk%ÍÀvš°v½î-cÒ÷4ÁwBà‰BÃs1þH€û9/;kÃ^qLþ5„—ô«jà*戒íàd¥¡é…lìT9'»ïÈ]C\ÛÝ8 ßg-þÞŸï\Én÷h’=3ENñ”•ŒqÓQãZkÁÅeóx ¾Ý¹ŽÓ3sq, ™£[X䮇UŽp¡àHpëuè)ÏYú°õJU6ëÓJ©Õ()ÒP©ÓTê»/*bœƒ„oYw“íÿ³7ŒKxçRá+ 3èèJ±BE‚Ÿ[òRÑJöìœús uÐÀ×6ÆèÀï<4{ƒmO÷œD®{[&‰#©c‹4ÊÆ ât‘¶A œÞõ¡µ t:M d…†@Òc$Âz—j e[¸²ì cþoæ©ÙkHÕ½ÿ9fâ§‹l¿eèƒ-é°Ý„áÁÒA6¨Ÿ]ò˜S÷õ¬é¶FC)Š7?ïøh5ã{¹3âïší]Þ™+H‹Ü:à³£lgM†@Aþç“•ÑÛ;\œ{$îœÚkÔÊ?Ŭ€ô‚GÆo‹2èÆ×tõ‰zÆ|Mu[/9é±ò"ÉéMS£éÑ.ßG9Њw‘YBr÷ûõ“Âæ1›s '}‹¹f¸ß¥ìÔÒH®—µ¯oÐæƒô.†S}…ÈKŠÉÇÝ_Àý/n¦»Kºi©…Í?Q!oVV1¾òEó;gÁüm­µnëÑׯpÑÿÛȘåVC°”dâGtSìšuÇNBWK3¹px »+¼ýÕÖFàAnÝ;¼”ÒŒ«àΟ´òÖý+³ŒÁås÷WXè»È,¡2Ìu1º#.£œÒïô-è˜['šÝÅ×`[:Ûù¢vBÛÆ’[Áö–j*t¶Ëö^‹ñ·¦Ãöf;GéµHß唟¾®™Þ[hd2x¯¼ÿ¿á d׌îåüÌo‹¾kµhÓ%cñ©{‡AÜdmœá³°¿î?Ý2rº;gkódÛ›Mz™Gøµ4Hⶺ¼¬;ºâ±.˜7 .»MÂÍ®(”g.1Š·"J.*½…s!ª)ro*šÇH7ƒßWžÄg16ùÌdí“tÐbyX51àš ðè]<Ž#%ŠÈMŠ¿‰Ì¿·q0ý$Rµs ›AQÄ>•ÄNò…e¨>©AN¾ŠE¨)TÛã¨-UT ¥F”ê˜è Ò¡N©J¦Ý:{Ô¨ªPS¸*KS)TÛ­AjuJU:ªtªªR©×Ñß©N©Š®ß*ê”ê©-N©J§]AjuHU6éîT–§TÀ§?Œ*S±)TÛã¥@RU%©Õ()×RZR•Mº{•ªª”çåè¥B€R‚›z‡Ü¥@R‚•:UU )¶¤µ:¤:º* SªPS jiDê‚›téîÒ—…:¥)P"©üÃRZª©üõ%©‚”§æ¡¨-N©NR¡M ˜u¥Ã­J¥§±:¤ó IjuíHç©ÒRù‡¨jKSªö§‚’kgDc¸v$où<%bæ¯c@ ž²À:½`ïìšð^‡ƒÝÕ‰¶“­l‡¤v‘OíqÚkwO;×hš𤹠›¨ÙTõU3h ‚ÉåSAÐÉŸt€~M5 Ö!Æ_ž-ï¼Axx´ÉG6±qŒñ`ŽÐGá[#Û¾×–J¹\¤IdÊ£èõ‘?¢©Ê%MRoêˆ8ßÝy`0w´×?n'ŒªH¨¯ÀV:HK N’?Ê8JÞ-X%'n,xÙ‹’*œe®” H•DÔí&lALtÜ´ÿ wDj/¯73áû–:ÊÞJ´ñ‘Í¥< õ.{hqÅÚîe{hGÙþú}k'¡x¤ÆNx[^'$M'Ô}t©»ù2 ƒ6.•f`ÈÐÚ9 Љ€¤ÓQ8€V¥6ÖÎÆ6AöM–Ytµ  ¸‡×‡ p4ú|Íe+¤6½èdm©ï MOÑ¥eÊVÖBq7Òeš1’ŠE¸k,À[8,’(r²¾»WmÄŠDå0€è;£È:†âÁßcå6·Z ËkPê‚Úñ­ý¾š.Í´Í{u R½Bœ~µ‘ñ×)IÙ© •8‚d0©¼'ÝÔJ‚]©ÌpOÃÈ=þýh÷‚jâê0qLæo-µöåõ$|8» $±¥ÝÛg¸7-ñä âèZ[BkMZÞõ¾ –†ñ˜¬^?=™µ«%ü±šœ·E„ø¬'¢GPA.qÈ® 0̓Ã?´=àÛ€×U×pÚ64áì+™“è¸Ö²¦,bÝ“(\ñ¢ÕÁÞO¿·®´›ªÝDQAÊ ˜É‰NB@æþðÎóØ=éc÷[[ »Øþó š÷»ïÜ÷˜_¨ÄÙb˜¸<9Îc˜ªÒNÝ˹ŠÙœØÊ훳<÷vöÏî$k[ܾõâFÐÕîŽHÃKHÁäŠAâtÊБñ 40öY± ï_šöu•¾õçžæÜy¶‰ŽÞ6¶V ŒØ5±ïžV´ð9í:^<`׸p£W¶nK™¶Ï*ðx\[ŒC3ßÜݹ¼ ºÖňâXÖ‘VôÐxÔ¬`á0ÝXgˆþ+µ²: =S1#Œîå„Y8;…®D_¯.ò¥™¦bå_‘ÑãRl-Ôj’‰•S(%0‘röÛ{æv}æëæ0XÍ0È ‘:×ýÙ°Uç»{ Lçê!Å¡ Šz.ñŸkžOmþâ Àç±mYtH.?>eñ¶¹ÚŒaºKAÄЮkÄf#¸¿Ã6;éáµ-n±Í÷î·j[v=¯4¼¼Š ‡Þªåg.µKP1H£‚œÅ1J%?/·Øåï)³¨ ûÖZmÛwmkt‰®ftb6Ôyè$0´MFGxmOŒy…ŽÆK/qo[Ïq-+ÝÃ^^à:É%­4.‚CcŒYÁo÷T¦ÂÑyŸäçQ ¼Kx_·U¿r@d)kz)äÇÄפ(v#k++ª‰(És!)„ÂsÖÞ7çç-qqo=ã.%¶Û,M¾‚Úa–Õ’½±÷–ò:GwÁsA4T@LŒÕpø.[ï{÷í·JË6èä6²Ï,rGpøÚ_¢f7º.kI†ƒj@c¸0À˜žÈÁRÜHq8…òú!ÎA{Œ1Æ*²_Ç@L]·4+w ÜR7Âý¤ÃÛq*´]±…»I@Á¨ï&U3Û—|îœÖ÷‹—œ¶u“.Û`Û˻ۆ¾Xà†BLŠ&¹äÏkƧiÐáØâÜNjàq›^Mã½EÓ­ÍÙ¶·µ…Ícå‘€™$ŽÑsN‘«SOh²Ö÷/Íx áÈoX{j÷Kåàmû9 cƒH–âwЈÜ XÖ´‡<ÒºOŠAw[‚ÅáŸ0Y‘²|=žîÇy}[öÖ²R—ýÑu'yµ¼$P…Š˜²nñQoEãGiä“t©Æ&€@:Ö¾cí,Ä–ÛøZd6˜±šàäma|ÜÀÃ#㸈½íÒæ5ÝÛ˜j\5¯‹ÏwŠÙ[‡ÉöÞ,÷ »Šg<­”L&pc_ 5kˆÖפtqíkãð+ƒò)°CG5^W,2ñðy3Û7 -«rhe’I¡i!½õÀ‘š$”6¬ÐÐÚê-©¦{)‡ånÙÌ|'˜+›ØËYqy‘±‘H@.î¡,v¦GZ;Q.àêp[õ‘ÀÝ œ8£ÅY¦ë¸S Ü9NÞ¾ífèW0h!)t9<tÛA¾1ÜG"ºfQÒ'D‹é¡Ç£šçfn÷emѳ­mÝ‘Ìæ"²–Úbh$%ì’Ëâ÷dÈÐ+š@cƒË:—gÊü]¶çÎ`w-ÄͲÆcdºŽx€âÀæJYÇ]â]p«šZÖ¾kC ðm™ñRɶ™³^*áæJÒ{|«7#oßsõ™u-&Ê58¦-cá£-ëÒZFD9ãXB™nÙ3 ‘åËooìýÛŒÛyOîl¥ÆàŽvÛÙ-´v·†9åîs¤|¶ñ²@ãÀM 3C…ý·ËÉ·¯³vÞváß§/ts¾xe.kt´5Žg¹…£‰„ÕÚšjÞ¼É8—Ýü1/Äv ˆ¿,ulì¢Ó^vmïqÇÝhÈ5’†FN2牗g¢.̳´RY¸“³ã‰J@H¦_?·wVøÄó)¼¼ÞÒØÞ¶óëË{‹had…†HÜ÷‚Ú5ů­x6¤ê!˜|ÖßÚÙw–ÖŽêÔÛ_ i¡žFÊÀæÊdž´ƒR›Jq4H.í,µ‰x3áѦq{Cfl…rdì/`dö”5Ñ oD@–áM÷Æ—®aVzùY¨‰¤R VJwí’ë;Wusƒ˜2憛Çcs7V­žHd–I{¢ÝwB@Ö†´‡K1$¸ÈÑcC«œÏíþ[ìèñ¯ÉÇ’¼¼¾ÆÁ;¢d¬‘÷Ú¤ï %ÄÇn‡¼êm8%ÿÃ.°³¶2e=–%­Î²Ö?‹Ë–Ýû#é·r¤›NS´×kå˜Ýæ|Ý6Ý¿¢ú: ¹"ª&cèŽsÌåØù)¬qQ\s~û­Xý0Øæƒ8sÞÜi%úuëqcš×CÖ+-²6Ö+uXÅu$;'!hÛ¸çsuJ"sIÖ‘Þ꺴éhpq‚ÕÜØË‡ Ä\Œƒ°w¸±ûû~qþ?Ë÷Œ€MZR’‘ê?Fïdkb2=¬â)w™½íNR¦p­?rs}òúÞ<î7·2Gqn¬-ÙÝÎÆHàטß>Gº2ø‘ýK‡ - ³6žñ™øœF/5a+á{ »™Úâs˜Ò扛Ý5úé ¾¼)…öwgC]¶Ö@‘E¥ýe¥â†b¤´û‰òšÎumÜ[€‹Žb£2?I~ÙG &¨¦bŠãßvÛÍÿÌbnl#{ì. ¯yŽ ˆEþðÙ´¼k{Ü$1é ¡ÀÐדi϶YÉì¡ÈAvö¶î>‰Ýr?2b«N–µ¥áÕ.!Ô"¡u}©‰­»ZÂö|å¨÷÷ ×RÍ“-n/å æßfŸ˜™BÆ `5LÑÊ8jˆÀŠªvªêo{Þ­›)º²9<îþÚ· ·ìf7Dæ²’¸ÜX:G÷¯Ôu€ãFpG+a·ì¬q;G? æ7·ù7‰çV1ÜÞ5ÐÚx¤ãq5èÈÓpVõ¹ŽeçSbÙ’0¶ã˜É'7oIHd];T»Æ"‚‚&)JÒ9}/8!åM†so¿2ÊĺI#–Y®ãˆ¸¸É0{.“K»¦1§h‘à’FѼcå¼¼Á»Åf‘’þêì6[†=‘Çn÷é ŒµÆF²£¼sÈ⡤^—„á>:ÖžãjȽ&g•—áóH\¶ÓÈ'åŠe<'D$àN²;gFrÂFÓuŽØ]Ã(%ŽšÖå{ÍKŒ†ÌÍaá€ZgòL†fÊÝnЇD­‰À¶Žd{Cèj:GBÖmv6{Ÿ’’Sqˆ²t‘–;Cdá©…í¡«\ÂÒ[QJÒ«›OÂ3ºxSök[*»A…Ë–2´å˜, Ÿ$Î_4„s¥Y¸( ÝϺmÀƒ¦•†±¾—Í.cdíà öØ«Z*ÒèñÚÚ8U¤Ž"¢£‚Ê]ÚǰvUŒÅ²Q¸´ÑÀ>óI-`b±Ê ŠÝ™Ž èíöÛ§sâ9‰Ù›¡Ö’Zd±’)bc£Õ{nA¸¡Ïwæû¯Î4µ¥y\û’Ù—›ŸÛ†\YdZÉ#‘áôµ˜R-oÞx„ý“BhÏñŸŽømÂwÔš³–³ÍÏp¶3ÖáŒ`”P²ØìÞCÝŸù¯ì»‹èðŠ»6™b‰»u bÜ;(n&à‰‘ŠÆ@4IÊÉ7\®Ì:iª©ºhQÓZÔîöŽAŸþŽã¼‹û/¯ýãýU¸Zo (/!1¿¬¶„~êñ–øÑk¢Û îÁš©é h3‘ËöÊ ±3g­ÓQ1!ûBHMÒ”7@§(ã~á¹-ÜDðÐ ¯Ghý}=«/W0;†4v;SúW-€`AI¤ñ“õ¶>ógL1Èö­Ôm_ÊÀ¢# €d÷ˆb¢q áF ì‘i}¬†Vôè §ej¹¼qLq,»„ÓãµwÄW–µƒÚß¶;œ+u..”AFd]Ã¥Žªª9QÊ¥XÇLÂM0&á@F±_ç2—âñÙ=¤p€vqð©“qàí¡“ŽÆµÇ†”ükƒÎqS~ÉÊqÀ„88“}º® ¢i]äˆdTCB˜Cw„Á  ¹ûN\ØÓ~í`t€4è©p=€¼Þï.:-'ûN<~¦´ÿ”ø:ÈJ¿•r£·î”r²ªS˜Ú{EGyC!L¡¹L ˜yGQ­òÖÆÖÆ.æÕŒú:O„ôŸ­i·W×WÒw·O/ÓÐ< }Kã󇊻WU\ ¯xjHN¥ B•¨WП @70Ò (¨Wóù)iM ˜jHíEUÀãá©Òš@8søêKUT¬šàÒàƒµø®áê⹦¢­Ûz-YRS3³²,â!¢cšM6UÓù9I›²`ɲE(ª§!PÔD¼ã›¶¹.Wçñøèe¸¿›pÈ⎒G½ÑÖ±Îq<Z ' -Ë—wv¶[ëyy#!´Žþ=ïpcÐðKœçÖ€8’HveÉÄ\Æãç.g¼W78ÙŸ9rm’ñ’HÈ[Ý•;.%Güz˲•·.¨_Ù.‘”&Š&áo‘3†»Ø›Ç‘˜­¹á’·ìcp{ f¶¸ŽÖ ×éxd°ÈÞ- â…Àæ¯7uÎÛæþéÁÈÉXܽÓÁkƒ£žÏ!-ÔÒC£•‡CÚjYÁÇVGácð?ˆ'mùÌQ‘2ùxc+‚)ÍÝd[Y킾î{FfÝŽ;UTKȱf‚ ‘Dˆ¨r>3É=½Í[MѼçÝÏè—kmä‘tì qƒÇh<–xÛ'³o&§¢Ž‚†l&§¾zÕùͱ÷œ»íöû6ÞáØ=çime’–(ÜæÚºÚâ*ÝJæ´µ6n|#]‡yB]¤,ï-wNÚj6mË4MÊí«‰®¬£{ÚÓ8žÒÚH."ä6C¦¤ ©]CÀod´§8”³¯L°¾$¹ø—k! œÜŒÞÕËP·Ì+û•t\X@Ü.n§¤|ë³¥©@Û…8¨žÙÎþZ;+e·rØ|[r¸Ý¹;›&4tÏc+"ŽF ¥ˆC•«¸Ò¤»_ånöYœ~FüØ^æbeéèŠéŽ‘ìt„¥’^êpáZ\2öEâÙêâÚ% &ÑRaž4±°NT³ò=ß‘n÷I ÌåVûä!,Dƒ§Ž ’Ä)ƒ†*š ;aîÖ?°vÑLn£uÝÎJÊ{H- ó”.•¦K¦šh¥Í$t¸T·m—/ºðøËËíÛ»£|b‹xl®b¸–âRÕ» ¸ŽÞ2û—BøØÇÜ6!Ró©Ž{Øßë<}–js{›?sÛnk­Ñi™¹‚Ë#Ÿ·.…ó?L"F½Îl.ÓH£ƒZçu4ôº<ŸY¼3q«jÞ\A`éÌ¥±¥´Â"À²oÈ‹„åB2bQTQm>EЊ¸.7ª;8ž.4]8f‚eQq/lB†;sf³¼Àæ>ÎÉáð9¨v͆JgIuqlø¸¾6LT/Š&†ŠM6†ÈâZÊè%w0xÌVÐÙ{’Ç#–ÆKœ»²¬‚Ù'½Ä !²HêšÇ§1 SP „ÞMmŒ­ìÞáå{'c(ûŸ‡I¬Òâü°îK½Œ5îñ+Òüw3ż°(úmGLž $Ý)©Žbæ2J¹œD¹-¯üÃgÝÉIÜãŵÌ0:Kv›{fÇ'}(£c s]^’€Òq™ì³¼œÄ6ÒöÉ—¸y/ ðI+Y1N^Îê3Åä‚)Ð H–2Zèâg ZÜ^ÙNf¯X9¬U“¸!¶øx¿ï6Z>èFÉVçláGŽ ‡» å#‘ó}AËd2‚C @‡ó¬g.7ŽO”÷‘ÙÙÏçÆï9²¶¶÷ t&àB@hoxâÈǼÆï°÷46 á¹ßoM·cÌ gÜÜÅ& ÷lÇa<°½²ˆL€ÔÜXæ´=¿i­$БCÓÜé”°`1^G¼ï±pH[Ò° "-ؤ•ÏzPtáÞâM슰öQbm›ÿvg9³µ]Ëݱ€ÎZeòRBË©omooced’ºI^Cdw‰F5•tÔYㆰëÛGob¹{ŸÇ9–Å\c¬™+ ŽÖá³Mu#£s#k#h.`ñªç:ŽÒâ’áÆm[²ÒâÓ…ÀÁ²¹ÂÅ™«æ;»(ÙÄÈ·6••[¹i)ø7+Òü_s±œ”8 ‹U"$RAEŽß'“ÅåyWÌÏml/²{;!ˆ‚Êãî‘î-eµ dRºøÏ…Ñ0js>É.$U¬t¬o±ûûcü1=Ý¥Žä³ÈËsÞ$Cû´ñÙ-í¾ù‚{©ç.H!qÖØ[Ž—7²FµÞ+Ô£ÛG¶­p+æ¬Þ5¸|´øØî ºŠl°½²G#zZö¹…ÃÆiŠÕ¦­wW*›u¬ÑjÅÕz!ÕÑae.2—×]÷kbÛ²O%BælWvß’F…±¥®&ñÖÌí­qO‚*§¢ð±Ä35U)’QUM®†L¥SÀyƒÎížec9¯‹±ºÉââÇI½‚ÙåË"/|ÑMUP$yàÖŽâ[ëÛ>÷œÙÜ¿¿º‚Æý÷¬¼µ–wh…ò67Å#ètU àI=~$ñ…ƒÂ„u›–.ì³d_™âÙË6Ñbã IzA^m m…Å1)‘'#ؼo¤#-Ð\ªo,š‚ —µ"\îÜÙÞi\^mlV*öÇcÜ⮡¹¼¾·–ÞGK×—ûªÊêxb¼¸ŠÄDÇ=­|¥’Ê_Ý´çéi€‚iT–eçi5öwåû)ÍÓn6¼äø…´f£mæã¹ä!›@B¢æ]ŒŽK*î1ºÉ‡pšFH†(€˜–_–—ŸøœÌv×ÃÅ€ž7Î#y…²d"7J†¼‚ipqÇdqìåCùá'åâ{b/h•̰¶2u‚.€GJÊî.x{q™pÁ) –°¥¡(Ç„¬-)mdëù¥‡*Ös:ow´<«ak1eÝ8Ar´:®Û®¦DJªb>]ÊýЋrÛ^b³7vÏÝy²k;W\±Ò~e¦h:£–kš^LJðx-rß9ƒ´_¸äÁÏmÆ[ÎÍ¿f×Gs8ÁŸœ"Q¨QñÔ¹§I.ioÑÁ}–ötáÝ)ð-öíµæ,N°)1=™–îÀµ†¾hk ¡~ª›¢×i&_Gjá]ävR¹M@Hr7û'˜å†w5 ­Ì9¼þwï×1\Œ{ŸCj x÷ÎgŒö¶Žs Í/.rZn Í÷ŠÆKq˜¼F+î°ÝÈ+¼ ¨Ÿÿ;ÅkZÁÓG®ÔáªêɸÿˆHû»ŠÓKà v–µµ<0ë…¶ÖÞKá#‰L#XWåÁyc[¶™2ìcgCIÄ¿Ay3¶“z vÊ3F5NÐMNÌÊ%¿ºUÁëœÍ“#·9­·7·÷vFûogy†Î\HÇÈÒV6”/©új[Eç;;,×/ó[[ï–v™Y®m¥gÞel,sà]G;¦¦´„¶´«xG Ø¡€ýšÐãzÚA/bæ{îRøŠŽ$¬Ø·™­ V’7[yéVëQe)¬ì¨¦váÚDœµÔ~9ñß1¯>åw÷Kì=³-ŸÜÉ¢áíÇ9;N™\×ø…±—ïŠð]†å±_ ì»o¼Ûýâ×%;§oxÍP´Þ‡‡JÚÖ6–øÀ¼[Æ´â¹ÆcÁ66OâžïÌíx—áÌ0ãëýÑrÍ'”"qÃÅÇ(ÀeâÛ[)G³2ÎÌÉT£NÈ˵|c¦b*]á)pÛC|f¶×,-6t»spü^ËC fÍýÌxwvó1£ccuL$ |tp-4ä÷ÕÅç7ÝÆä7†øq÷bY÷–÷Œktëhˆq{Î’#,.kêÒǃ2â6ÃÊW¯´s!¹¸a-¦y79ÇŒ.9hØI[¡ÖöÄ X¸÷ë5púnJ&Ìͪ²fWtw„7†&åæwla¹y·ã·šæ\n\Kvèc|Œ„Êó4®{Ú#š$qkHmxt ‹xâ³¹=å˜|ÑAö4ÇnÙÖ>QDQ†µÄ=Ìc]¡µp&œzW G X¥À¾Í¸q½-0—±³5õ){Å ÇVtc¼Ô„«I©¦zM¼ÁÔX ”ÖvTS;pí "NZÌ¿›;瘷sºû¥îÙ–Ïî¤Ñpöã‹È¦’¹¯ñ c.!Þ)à±­ËbþÙvÿy·ûÅ®JwLÞñš¡i¼•µ¬m-ñ}oÊíë ã‰N:øÄILcFÀæO•¬ "örÅ’É;q…š´f·:NU‹ôE’‰qº¡?htÁ2”1J:–w¸­y!´\Üuì—ØŒ­ÕͳaÞ[?xüÉú{jS¨ÐHØ19|4üÔÜm7¶¬µÈãî­á™Ò7¹t’w%¿¶„5Ô š‘AR@]!ÁäCxl镸P».;~^ 7Ø·n*y?iJä¶¼#cœOÚwDDƒr¤Œ©¡ž´p“s @ á}  ÖëÍËÉ/6F+šx»yá¾ÂßA|اa†cÞ"žjYÞ5Í/®–ðêZ¿.­™mºoö üÑIk”´–ÔɻȄÍi’)XáÁÚpoV§q]OÆÞC‡½3Ü䦠}ÄQPøfÂA3&£tmüzÜÑ.‚¨ˆ¹AåÀ/WIR—C¢¡4­¯’ø ¼6Å‚÷*?úöZY2DÔ-ÑÖ* H-‹»ii<×U¯ó;/o“Ý’ÚãÿþÑ–pBvãA¡2k Ž–±,î õbÕçÕJU6ÔªªR©ÕÑS¤§TÀ§@ù¦‰Õ()·ÇJ€§T ¥IjuJU6ëPZR•Mº{•:JuL XTª)TÛãïÒÒT §UIjª¥:ê SªR©·ÇSBR•N­¡R˜)J¦Ý}ÚE¡:¥6éRZR‚•©Õ()·ÇS¥UR‚]êIÕ)Tëè© ER•MºT–ªªPSž¤µ:¥6õ Fš'T€§VФS›u¥@R›t©-N©ANº’ÔêÛ§wŠ µ:¥9ü”¨SªR©·]”¸u§T€¥-=‰Õ(mAjuHêÚ%©Õ (<úÔé¢u^ép>]lx!ç‰ÿÜGݯ˾`~þfÿkÞ~±"ûÿfþèb¿fÚþ‹Ð-ÀÛäþŠÔVȦàmòE_^.ï]Äïþ!sOúȹk÷?”ô§lÃØïÔá_–\ÂýþÎ~ؼýfEUèKOR„)B¡ P…(B”!J¥VR NªÀpðÒÒŽ à<ÃSDø…`6”QíWÒNƒ©\B*B°0éEPUÀãáå©Òš¸e" uWxjhª¸Ÿ’‘jÀÜÃRBªžµp8Ò⎀p¡>)ÜÃJ€¢¡\Î*)«ù‡«üTˆíN©üþJ’ÔÕÀüÃRZRƦˆ¨HŠ<)ñJšT¡0UÀáÏ¥IjuHš’ÔêúT–§T€q©¢*< @è¥áUT §]*U n4‹SªP??’ µ0RüÃRZRœõ4)Õ)TÛÕK‡ZuJ w-=‰Õ )·_v¤µ:¥:ª SªPR§JuHU6éîE/ iANà¥@˜=‰AMºôÔ–§T §UAjª¥:êt§T¥SnžçôT‘ÚR‚ÁJ0R‚›uéïÔ–¢«!¸ƒÏîóôž0’ym7¶ 0Õ•‡ÐI´š²…—mf¸šp”ê§U“!f»ñ™3p ŸfÚòh aű-²Vðܺädr÷ä–wfàF BŽv Þ_²(¶ýÝ»$Ý“XÍ$-ƒîXØm.Ö!/:Í@¡v¿³Æ”é+ ÁNºÞ‹V§T¥Wm*´ê”î šÁJU6ëîÔ–§T ¦Ý;¼U%©Õ()Q¦ ª˜ªíñÒ§juJ uyB•N«)pŸP2Ùœ{jb¦3£¶Ó‘vÎk}vJ¨{*"}ŠQÎÍ b DÆÝ©œ¼—¤‘Dʸ”S17ʧ˜ï>^ßïl”å2’7d1Ѿls``ûÄ‘8½½åήóº.Ò]‚š‡BÝëlï M­e,¶ ;¥Í{c½t¯=Ë$hiÑàƒdÔÕJPq˜W2‡1Îsç0œç9„Ç9Œ:˜Æ1„DÆ0Ž¢=ñ¯HîÃF(Ò5jx’® wN“ÔŠ¥zÈ4¨S›té¥@UU()ܨ)TÛ­Ijª¥*›tîæ¨ÒSª`S¯¢’uJU6øéi Õ()ÕPZR‚u©Õ)TÛãïTUU()ýaý“¯bb©·_v‘hN©J¦Ý* SªPR µ:¥*›z†• uíJ t‡”*hR•N¾ŠE¡0R•Mµ©Õ()RZª©J¦Ýz{õ4!:¥:CʨR‚{B§H= Õ()¶¤µ:¥;‚ µ0R•MºìšQ:¤:CËKÂS}¨ )¶¤µ:¥óÔ¦ B©Ì=CRZR‚ÁKŠuJU6ëÝã¥@RU%©Õ{¿ÀçÿÀÄñŸþAµ~[s÷÷9û^óõ‰èÌýÏÄþ͵ý •¨-•J¿\\ÿÞ»‰ßüBæŸõ‘r×î(ÿéNØÿ‡±ß©Â¿,¹…ûýœý±yúÌ‹«Ð–ž¥R„)B¡ P…(B”!J¥R„)B€ÃÓJ:«€vR¡B¾µ4N¤-@Â" ô«ûƒú)'NÅp0 ©*àna¢‰Ôp?8xªt¦¬ï *U CmMuV‡EN”ü ÜÃSDWµ\4qO‡R¸(OZ@8óøéPÀááä©Òš@0øZ’ª¸ŸÉS¥:¤ó I ×µ ž• +ØúQáOÂ×KObuH};¼U%©Õ |5Sª@>ßðT–§_­ (>TN©MºRð¦”×Jƒ©Hæ¡©-N©üþJ’Ôê”Ì5©Õ )J…:¥6øûµ¥@R‚]‹Sª@S¯¢ µ:¥6éRZª©JšS¡:¥*›ixQT §pTÐê”Û¯»RZR‚U%ªª”¨§buJU6øéSµ:¥:º)Pê”Û¯»RZR‚›tîñT§T€¥Nšt'TÅSoަ©Õ()Ò¨ uJ uôT–§T¥SmAjª¥;‚§IêN©Š¦Ýi'T¥SnžåMN©ANà©-L¥SmAjuJU:ªhUU)Tëò $Wð¦*›z†§H)Õ()ÕRZª©ANº‚ÔꔪmþŠ’ uJ w*&bb©·_ Ô–§T §UIjuJ sÔªªPSo»Zšꔪt‡”)Q:¦:ú*KSªR©¶¤µ:¥?¬* SªPSn½=úšR•MºyB‘:¥<[*KUU)TÛRZR‚]©Õ()Ð>í*R•MºtÔR‚”´ö'T¥SmAjuH wIjuL t»SBªB©·Nžõ/ uJ RÒ:“ªR©·»š µ:¤*KSªPSn½=ÚÔé¢u^õp5ËaÛÃÏ ÿ'µ¯Ë.a~ÿg?l^~³"ýÙŸ¹øŸÙ¶¿ bôµ²©BàK‹Ÿû×q;ÿˆ\Óþ².ZýÏåý)Ûðö;õ8Wå—0¿³Ÿ¶/?Y‘cÕzÓÔ¡ P…(B”!J¥R„)B¡ P…(B”!JµÔB„UX>ZZSVÔУÀ¯­*'R€Â‘PUÀô'CÔ®¡íVw†‘ ðêWó…-)ñWs I¨ª¸zii «Ã¢¤µ?¸jh{RèâW…$ëÚ=4i¯b¸:*t”ê<úÔ–§Up?UIjuìHæ’¯j@Sž—ëØÌ:QÀô¢½©üþJ)¤óPÔ–§T€~%IjuWó IjuíJ sÒ¡N© ~aÓgø©pëN©@üþJZ{ ˜uØ5%©Õ )ÕPZR‚›{½Ú’Ôê¥Å:¥6ëÝÏJH m÷*KUU()×ÑRZФ*›j UU()ÏJ…:¥6øûµ©§juJ utRÓTê”芒Ôê”ÛÝîT§T€¥MèN©Š¦ßv´©ÚR‚!ÑJ•N©AN¾Š‚ÔÁHU6Ô–§T ¥MRuL íצ¦©Õ)TÛ§”)iUR‚ÁRZ˜)J¦Ú‚ÔꔪuTЦ PS¯ÉSDꘪmêZjR‚ÁRZR•MºÔªªR©·Or¤‚R‚ŸÖ4ESM¾>ý"ÕUJ uT§T §]IjuJUvøêhSªPS«¢•ª¦:¤µJU6ÔªªPR§JuJU6ëÓß©¡N©J¦Ñ(R N©Nà©-L¥SmAjuH utT–ª1Tëò M *”ªmñÒ UT ¥IjuJU6ëPZR‚]%©Õ()×¶¦…:¥6øéP'T §=-=‰Õ()·Z‚Ôêêè¨-UT §_»J…J mñ÷iJ‰Õ()ÏS§±0W¾Ü ð »ÿDÿÉÍkò·˜_¿ùÏÛ¿¬È¿Aö_îv'öe¯è½­=lªP…øâçþõÜNÿâ4ÿ¬‹–¿sùGÿJvÇü=ŽýNùeÌ/ßìçí‹ÏÖdXõ^„´õ(B”!J¥R„)B¡ P…(B”!J¥R„)B¡ P…¨‡xh¢uVóÒÒŽ à` M < ÚÒ¢u*ÀqþºÀ«û»ô“ãÔ®¡íW=*ü àpðòRÒš¸˜jHíEUÀãáå©Òš¸9ütˆ)‚z•ÀÃSDTu«èL} Áà\¯j@8ôÒ-MX‹J*=5BuW‡E"ÔÁJzš'^Õp?=.)øù†—U ŸÉHµ:¤ó»¤µ:¤óÔéN©üÃRZRœô¸§^Ä¥So»Z\ª@?õ…-)Õ(nµ©Õ )ÕRZRÇž¦‰Ôx‚T¸õ¦”è%*U )·Nš’ÕUJçòT¦ B©¶¤µ:¥*hSªPSn½4¨ªPSnžå"Ôê”þ°¨-L…SmIjuJ TЧTÀ¦ÝziSµ:¥6éîTéªuH wIj`¥*›j UU()Ü4)‚˜ë¥DU()·Nš5U^Ô §pT–§T¥Snµ©Õ)Tê¥BR‚}4LÅSoŽ‘juH uTªª`S® µ:¥*»|t¨SªPS¸*hªb©·_v‘juJ mÒ µ:¥* SªR©·]ƒJŠª”é(TÐ'TÀ§_EIjuJU6øêKSªR©ÕÑPZ˜)ANò *'T¥SoPÔ¯jPS¸)§T¥Snµ©Õ)TÛ§¹PZª©N¾ŠTN©J¦Þ¡© 'T §U"Ôê”ë¨-N©J¦Ý=Ïè©-N©ANà©LÄ¥So¿J:¥:ªKSªPS® µUWÖÑ%]¹nÕ¹ ¢îVMS/(¨¢§ ßt®ŽFòÛa6Jõá–DéãÐÖ°|.Õ•¥ÅýäV6­/¹šF± t—8Ь•ú#àêXk>1±Š;­XµnSi  [·M ^PܯɌÖEÙŒÍÞ]⺺–b; ¯sÈÿÞ_¢Ø«&ã1–ØÖš¶Þãè¿äYÃXÅßR„/À—?÷®âwÿ¹§ýd\µûŸÊ?úS¶?áìwêp¯Ë.a~ÿg?l^~³"Ǫô%§©B¡ P…(B”!J¥R„)B¡ P…(B”!J¥R„)B¡ P…¨‡†Šê®ç©ÒŽ À`ð *#ˆVÖ•¯j¸—øp8PŽ!\„Tu«„6Ò 'àV‡EN’š¸˜iÚUÀüáS¥ÀÀ>I Ô«Ä)Q:„€zÇ©\ Ì4¸ëÚÏËHµ5p8xJ’T€qðòÔéM\útÔ–§R54N£ëH ñHÛ¯M*Ф‡E-)Õ yõ¨-N©üüžåIjª¤=MT€¥.)¥6ëÓJ:¤õR-N©@ýu%©Õ\Û¥AjuJ MªPSnÞ*<)¥óòûµ4I×± )·¨jKSª@SŸ’¤µ:¥*›u¨-N©ANª\SªPS iP'T ¦Ý:i§T §=Aj`¤*œÃ­AjuJ uR¡N©NºšêÛ§M"ÔëÚ”¨-UT¥Snµ%©Õ)Tê©¡LÀ§]*ꔪmñÔ–§T §UIjuJ uÔ§T¥SnžåI:¥;‚•uìJU6ëîÔ–§T §UIjª¦* SªR«·ÇSDê”êò…*ê˜ëè©-N© ¦ßAjuL wNžÅUJ ôjhŠ¥6éÓJUR‚ÁRZSMµ©Õ!Tê©ÒSª`S¯¢¦‰‚”ªíñÒ N©ANª’ÕUJ uÔ§T¥SnžçôTé)Õ()Ü“±1TÛ¯»S¤'T §UIjuJ uÔ§T…SoާJª§!Œs¥)Œs¥ „Æ0è DDDkŽI#Š7K+ƒbh$’@$’x:ÉàÆÇÈñ@¹î4 ’O@t•˜¼:`雎àa-$ÅRn*C3l¢c¼–ð€zBÅ÷ªGÞ”yKßJøŸæ´ÎBý™´åï1¥Ãï3´ø²i5î£=l¨«Ü8:šEZM~©å,.12·sî(ô_Só¸qeGûGŽ§ÓƒZx·í:”ýâëE;RÞhÐ8"@0né˺óxkåô:ìê¥_ŸÎ"ý’ØâïÉwæEޏr¡¥² åsß-‹1iŒci[²qôô‹xÄ~ÄúRè»~r¢EVYR¦(qÔÃõvÝþp¹™¶vý†Û°±Á>Çg ´n’£#£‚6ÄÂòÛÖ4¼µ€¸µ­Ö€ð,Ïòç²s™{¬ÕÝÖU·W—2ÎðÉmÃå{¤ph6Î! ¸†‚ç)ROŽÿ´%·óÎJúVØü£Yîk{¿oy ÏoXß– ƒé™+mìŠ~ЖßÏ9+é[cò;ÜÖ÷~ÞòžÞ– ƒé™+mìŠ~ЖßÏ9+é[cò;ÜÖ÷~ÞòžÞ– ƒé™+mìŠ~ЖßÏ9+é[cò;ÜÖ÷~ÞòžÞ– ƒé™+mìŠ~ЖßÏ9+é[cò;ÜÖ÷~ÞòžÞ– ƒé™+mìŠ~ЖßÏ9+é[cò;ÜÖ÷~ÞòžÞ– ƒé™+mìŠ~ЖßÏ9+é[cò;ÜÖ÷~ÞòžÞ– ƒé™+mìŠ~ЖßÏ9+é[cò;ÜÖ÷~ÞòžÞ– ƒé™+mìŠ~ЖßÏ9+é[cò;ÜÖ÷~ÞòžÞ– ƒé™+mìŠ~ЖßÏ9+é[cò;ÜÖ÷~ÞòžÞ– ƒé™+mìŠ~ЖßÏ9+é[cò;ÜÖ÷~ÞòžÞ– ƒé™+mìŠ~ЖßÏ9+é[cò;ÜÖ÷~ÞòžÞ– ƒé™+mìŠ~ЖßÏ9+é[cò;ÜÖ÷~ÞòžÞ– ƒé™+mìŠ~ЖßÏ9+é[cò;ÜÖ÷~ÞòžÞ– ƒé™+mìŠ~ЖßÏ9+é[cò;ÜÖ÷~ÞòžÞ– ƒé™+mìŠ~ЖßÏ9+é[cò;ÜÖ÷~ÞòžÞ– ƒé™+mìŠ~ЖßÏ9+é[cò;ÜÖ÷~ÞòžÞ– ƒé™+mìŠ~ЖßÏ9+é[cò;ÜÖ÷~ÞòžÞ– ƒé™+mìŠ~ЖßÏ9+é[cò;ÜÖ÷~ÞòžÞ– ƒé™+mìŠ~ЖßÏ9+é[cò;ÜÖ÷~ÞòžÞ– ƒé™+mìŠ~ЖßÏ9+é[cò;ÜÖ÷~ÞòžÞ– ƒé™+mìŠ~ЖßÏ9+é[cò;ÜÖ÷~ÞòžÞ– ƒé™+mìŠ~ЖßÏ9+é[cò;¼Ö÷~ÞòžÞ– ƒé™+mìŠÁ솷ûç%})l~Q£çwšÞïÛÞBóÛÓù`Ø>™˜ò¶Þȵý¡íÏž2OÒ–Çå*_;œÖ÷~ÞòžÞ—ËÁôÌÇ•¶öE?h{s眓ô¥±ùJÎk{¿oy ÏoOåƒ`ÿy˜ò¶Þȵý¢-ÐþùÉ?J[”©|íó[Ýû{È^{z,;ÒòþVßÙU¿h«{猓ô¥±ùJŸÎç5½ß·¼…ç·¥òÁ°}31åm½•kûEÛßXv¥åü­¿²«~ÑÖÿÏ#éKgò/®jû¿oy ÏnGËÂôÌÇ•¶öU¯íoüï‘þ”¶)ÑóµÍ_wíï!yíÈùbØ^—˜ò¶þʵd„|d¥-ŸÊt¾vy©îý½ä/=¹?–-…éy+oì«_ÚFç|ôµùR—ÎÇ5=ß·ü…ç·%òŰ½//åmý•kûI@ü“¶¿*Qó¯ÍOwíÿ!yíÉü±ì/KËù[eVd¤{äo¤í¯Ê”|ëóSÝûÈ^{r>Xö¥åü­¿²­iX/ò/Òv×åJ>uù©îý¿ä/=¹?–=…éy+oì«PöKÁ‡z_"ý'm~U¥ó¯ÍOwíÿ!yíÈùcØ^——ò¶þÊ­ûLAüí‘>“¶ÿ*Ñó­Í?wíÿ!yíÈùdØ~——ò¶þÊ {&¡½-‘>“¶ÿ*ÒùÕæŸ»öÿ¼öäþY6¥åü­¿²«~ÓpŸ;d?¤­¿ÊÔ¾u9§èÈ]ûr>Y6¥åü­¿²­iØ_²ÒVßåj_:|Òô ¿ä.ý¹,ÛÒòþVßÙUƒÙ? ÞÙé+sòµ:|Óô »öä|²ì?KËù[eZþÔß:ä/¤­ÏÊô|éóKÐ6ÿ»öäþY¶¥åü­¿²«²Š?½rôÉ[Ÿ•é|ésKÐ6ÿ»öä|³l?KËù[eZþÔpÿ:䤭ßÊô|ésKÐ0BïÛ‘òϱ=//åmý•[ö¥ˆù× þñ·+ÒùÐæ `<…ß·#åŸaú^_ÊÛû*×ö§‰ùÓ }#nþX¥ó¡Í@Ày ¿nOåŸbz^_ÊÛû*°{*bƒûÓ }#nþX£ç?š>€ò~Ü–}‰éy+oìªßµTWΗÿÒ6÷åš>sù£è!wíÉü´lOKËù[eVý«bþt¿‡ÿxÛß–i|çsCÐ0BïÛ‘òѱ=//åmý•jÊèÀïIßßHÛß–i|æóCÐ0BïÛ‘òÓ±}//åmý•[ö°ŒùÎýúBßüµKç3š€ò~ÜŸËNÅô¼·•·öU¨{,£CûÎýúBßüµKç/™þ€ò~Ü–­‹éyo+oìªßµ¤wÎWçÒÿåª>rùŸè!wí¨ùjؾ—–ò¶þʬËhðïI_ŸH[ÿ–èùËæyÿö!wí©üµl_KËy[eZþÖñÿ9_H@~[¥ó•Ìÿ@Àù ¿mGË^Åô¼·•·öU`ö]0ï+ìz_À~[¥ó“Ìï@Àù ¿mOå¯bú^[ÊÛû*·ívÄ?¼o¯ãà?.RùÈæw `|…ß¶£å³cz^[ÊÛû*°{/™÷óü|åÊ_8üÎô‘»öÔ|¶loKËy[eVf0ïHß?ÇÀþ]£ç™Þò~ÚŸËnÆô¼·•·öU¯í„Ïç ãøøË´¾q¹›è8#wí¨ùmØÞ—–ò¶þʬÌFýá|u¿‚ü»GÎ/3}änýµ?–Ýéyo+oìªß¶3_œ/ã ¿/RùÄæg à¼ß¶£å»cú^[ÊÛû*°{2÷…ïütåê_8|Ìô‘»öÔ|·lKËy[eVfSpïH^ßÇAþ_£ç™žƒ‚ò7^ÚŸË~Çô¬·•·öUoÛ1¿ú}ëütåú_8\Ìô‘ºöÔ|·ìKËy[eVfrþzõ½ƒü¿Kç™~ƒ‚ò7^ڟˆÇô¬¯•·öU¯í úuéül'Ô¾p9—è8/#uí¨ùpÙ—•ò¶þʬÍ$ƒüúóþ6ê _7üÊô‘ºöÔ|¸ìJÊù[fVf¢aÞ}yÿ õ 7üÊô‘ºöÔþ\vG¥e|­¿³+~ÚÉÿ¦Þ_ÆÂýCKæû™^ƒƒò7^Ú—‘éY_+oìÊÁìÙ žÞ?ÆBýEKæ÷™>ƒƒò7^ÚŸË–Èô¬¯•·öe`öm”?Ïoã!~¢¥óyÌŸAÁù¯lGËžÈô¬¯•·öeoÛt?Ó/ã!¾¢¥ówÌŸAÁù¯lOåÏdúVWÊÛû2°{7ôÿ<¼:ÞC}GGÍß2}än½±.{'Ò²¾VßÙ•¿nóË¿øÈ¨èùºæG àü×¶#åÓdúVWÊÛû2·íÈoôË»ø¸©*~ny‘è8?#uí‰üºlŸJÊùX=™jÎSùåÝü\?Ô”|ÜsÐp~FëÛòë²}++å öeoÛ ÿéwoñqRÒù·æ?¡a<×¶'òí²}++å öepöu(çw`ô»ˆú–›~cúÈÝ{b>]¶O¥e|¤̵gb¡Þwvõ-/›ncúÈÝ{b.Û+Ò²žRfVý»–ÿJºÿЉúš—ͯ1½ än½±.û+Ò²žRfVgŠáþuuõ5/›>czÈÝ{b>]öW¥e<¤̬Ï5üêêþ*'êz_6|Æô,'‘ºöÄþ^6W¥e<¤Ì­ûz¸ÿIºŠŠúž›>czÈÝ{b>^6W¥e<¤̬Ïw!þstõE/›búÈÝ{b/;/Ò²žRfVý¾]¤]ÄÅ}QKæÃ˜¾……ò7^Ø——éYO)³+~ßnÿÒ.âbþ¨¥ó_ÌOBÂùŸlGËÖËô¬§”ƒÙ•ƒÙúð;Î.âbþ©¥ó_ÌOBÂùŸlOåëeúVSÊAìÊßõyÿŸ¹¿‰ŒúªšîbzÈÜûb>^ö_¥e<¤̬=÷û—ø˜Ïª©|Öóа¾FçÛù{Ùž•”ò{2°pø?ßîOâ#>ª¥óYÌ?BÂùŸkGËæÌô¬§”ƒÙ•¿ê ÿÿ=rõ]/š¾aúÈÜûZ/›3Ò²žRfV$ýþãëqõ]5|Ãô<7‘¹ö´|¾lÏIÉùH=™[þ¡R!ÞZãþ"7êÊ>j¹…èX_#síhù}Ùž•”ò{2dx ß.ò—Ã^Rv;¢ÃÙÇÚu…qKüÓsF6×Çë6Š«§ äùÙlxs§É8£,4>0ø]÷øB9Ê ž0©¨Q.ó‡w<ÂUŠ[Þ&è5yVëæ†ùÞŒ0g²¾Èš÷, Š/¢¬Œ4>FMdv¯AÛÛ iíw qq²è w®¬’}4{Ë‹kÖ¤} Ѽk†!,–艧۔¥ÔÛ…×PþºsÖ€·Þ…)HP)C@Є+P…(Bø|]¯ü'Ñ÷¿ûÍ5¡ æùÔüÚ§Èž§æÐ…>Dõ?6„)ò'©ù´!O‘=OÍ¡ |‰ê~mSäOSóhBŸ"zŸ›BùÔüÚ§Èž§æÐ…>Dõ?6„)ò'©ù´!O‘=OÍ¡ |‰ê~mSäOSóhBŸ"zŸ›BùÔüÚ§Èž§æÐ…>Dõ?6„)ò'©ù´!O‘=OÍ¡ |‰ê~mSäOSóhBŸ"zŸ›BùÔüÚ§Èž§æÐ…>Dõ?6„)ò'©ù´!O‘=OÍ¡ |‰ê~mSäOSóhBŸ"zŸ›BùÔüÚ§Èž§æÐ…>Dõ?6„)ò'©ù´!O‘=OÍ¡ |‰ê~mSäOSóhBŸ"zŸ›BùÔüÚ§Èž§æÐ…>Dõ?6„)ò'©ù´!O‘=OÍ¡ |‰ê~mSäOSóhBŸ"zŸ›BùÔüÚ§Èž§æÐ…>Dõ?6„)ò'©ù´!O‘=OÍ¡ |‰ê~mSäOSóhBŸ"zŸ›BùÔüÚ§Èž§æÐ…>Dõ?6„)ò'©ù´!O‘=OÍ¡ |‰ê~mSäOSóhBŸ"zŸ›BùÔüÚ§Èž§æÐ…>Dõ?6„)ò'©ù´!O‘=OÍ¡ |‰ê~mSäOSóhBŸ"zŸ›BùÔüÚ§Èž§æÐ…>Dõ?6„)ò'©ù´!O‘=OÍ¡ |‰ê~mSäOSóhBŸ"zŸ›BùÔüÚ§Èž§æÐ…>Dõ?6„)ò'©ù´!O‘=OÍ¡ |‰ê~mSäOSóhBŸ"zŸ›BùÔüÚ§Èž§æÐ…>Dõ?6„)ò'©ù´!O‘=OÍ¡ |‰ê~mSäOSóhBŸ"zŸ›BùÔüÚ¾ô=Oì; ?û¿à¡ é¡ P…(B”!ÿÙopenchange-2.0/apidocs/html/libmapiadmin/index.html000066400000000000000000000040221223057412600224730ustar00rootroot00000000000000 libmapiadmin 2.0 API Documentation
libmapiadmin

Client library for OpenChange Administration

libmapiadmin provides administration client capabilities for OpenChange and Exchange servers.

Note
As of version 0.8, libmapiadmin is considered alpha quality.

Creative Commons License
Creative Commons Attribution icon Creative Commons Share Alike icon
This content is licensed under the Creative Commons
Attribution ShareAlike License v. 3.0:
http://creativecommons.org/licenses/by-sa/3.0/

openchange-2.0/apidocs/html/libmapiadmin/libmapiadmin_8h.html000066400000000000000000000210421223057412600244120ustar00rootroot00000000000000 libmapiadmin 2.0 API Documentation
libmapiadmin.h File Reference

Structures for MAPI admin functions. More...

#include <sys/types.h>
#include <stdio.h>
#include <stdlib.h>
#include <stdbool.h>
#include <unistd.h>
#include <errno.h>
#include <string.h>
#include <stdint.h>
#include <talloc.h>
#include <ldb.h>
#include <tevent.h>
#include "libmapi/libmapi.h"

Data Structures

struct  mapiadmin_ctx
 MAPI admin function context. More...

Functions

struct mapiadmin_ctxmapiadmin_init (struct mapi_session *)
 Create and initialise a mapiadmin_ctx structure.
enum MAPISTATUS mapiadmin_release (struct mapiadmin_ctx *)
 Clean up a mapiadmin_ctx structure.
enum MAPISTATUS mapiadmin_user_add (struct mapiadmin_ctx *)
 Add a user to Active Directory.
enum MAPISTATUS mapiadmin_user_del (struct mapiadmin_ctx *)
 Delete a user from Active Directory.
enum MAPISTATUS mapiadmin_user_extend (struct mapiadmin_ctx *)
 Extend user attributes to be Exchange user.

Detailed Description

Structures for MAPI admin functions.

Function Documentation

struct mapiadmin_ctx* mapiadmin_init ( struct mapi_session *  session)
read

Create and initialise a mapiadmin_ctx structure.

You should use mapiadmin_release to clean up the mapiadmin_ctx structure when done.

enum MAPISTATUS mapiadmin_release ( struct mapiadmin_ctx mapiadmin_ctx)

Clean up a mapiadmin_ctx structure.

The structure is assumed to have been allocated using mapiadmin_init() or equivalent code.


Creative Commons License
Creative Commons Attribution icon Creative Commons Share Alike icon
This content is licensed under the Creative Commons
Attribution ShareAlike License v. 3.0:
http://creativecommons.org/licenses/by-sa/3.0/

openchange-2.0/apidocs/html/libmapiadmin/mapiadmin_8c.html000066400000000000000000000136421223057412600237250ustar00rootroot00000000000000 libmapiadmin 2.0 API Documentation
mapiadmin.c File Reference

Housekeeping functions for mapiadmin. More...

Functions

struct mapiadmin_ctxmapiadmin_init (struct mapi_session *session)
 Create and initialise a mapiadmin_ctx structure.
enum MAPISTATUS mapiadmin_release (struct mapiadmin_ctx *mapiadmin_ctx)
 Clean up a mapiadmin_ctx structure.

Detailed Description

Housekeeping functions for mapiadmin.

Function Documentation

struct mapiadmin_ctx* mapiadmin_init ( struct mapi_session *  session)
read

Create and initialise a mapiadmin_ctx structure.

You should use mapiadmin_release to clean up the mapiadmin_ctx structure when done.

enum MAPISTATUS mapiadmin_release ( struct mapiadmin_ctx mapiadmin_ctx)

Clean up a mapiadmin_ctx structure.

The structure is assumed to have been allocated using mapiadmin_init() or equivalent code.


Creative Commons License
Creative Commons Attribution icon Creative Commons Share Alike icon
This content is licensed under the Creative Commons
Attribution ShareAlike License v. 3.0:
http://creativecommons.org/licenses/by-sa/3.0/

openchange-2.0/apidocs/html/libmapiadmin/mapiadmin__user_8c.html000066400000000000000000000111051223057412600251120ustar00rootroot00000000000000 libmapiadmin 2.0 API Documentation
mapiadmin_user.c File Reference

User management functions for mapiadmin. More...

Functions

enum MAPISTATUS mapiadmin_user_add (struct mapiadmin_ctx *mapiadmin_ctx)
 Add a user to Active Directory.
enum MAPISTATUS mapiadmin_user_del (struct mapiadmin_ctx *mapiadmin_ctx)
 Delete a user from Active Directory.
enum MAPISTATUS mapiadmin_user_extend (struct mapiadmin_ctx *mapiadmin_ctx)
 Extend user attributes to be Exchange user.

Detailed Description

User management functions for mapiadmin.


Creative Commons License
Creative Commons Attribution icon Creative Commons Share Alike icon
This content is licensed under the Creative Commons
Attribution ShareAlike License v. 3.0:
http://creativecommons.org/licenses/by-sa/3.0/

openchange-2.0/apidocs/html/libmapiadmin/middle_bg.jpg000066400000000000000000000005251223057412600231120ustar00rootroot00000000000000ÿØÿàJFIFddÿìDuckydÿîAdobedÀÿÛ„ÿÀdÿÄU Q¡Ña‘ÿÚ ?ßÀ#¿ªÚ0 ïæ¶œ ‡3Yû žñݲ ?ÿÙopenchange-2.0/apidocs/html/libmapiadmin/nav_f.png000066400000000000000000000002311223057412600222730ustar00rootroot00000000000000‰PNG  IHDR8³»`IDATxíÝK€ EÑ–·[†øBÑmkâÄÂH—prÓ¼.‚Žó‚ꎤR6Z VI±E‚5j³„lóš›iI˜¬ÞêçJ0ŒÑÑ/Žû›™uøñóÞ¿6sH ÝõyIEND®B`‚openchange-2.0/apidocs/html/libmapiadmin/nav_g.png000066400000000000000000000001371223057412600223010ustar00rootroot00000000000000‰PNG  IHDRô1&IDATxíÝ1 ÁOHf„á_ ->~¸åM iËMèÀƒS½ü‚<IEND®B`‚openchange-2.0/apidocs/html/libmapiadmin/nav_h.png000066400000000000000000000001421223057412600222760ustar00rootroot00000000000000‰PNG  IHDR ,é@)IDATxíÝA @BQ­³šÛ›Ð¢Žáà) )ëý éaÅèÜ¿Æo‡RlÐßIEND®B`‚openchange-2.0/apidocs/html/libmapiadmin/nav_tab.gif000066400000000000000000000014541223057412600226050ustar00rootroot00000000000000GIF89aPæïïïþþþýþýûüúõ÷óñôïøú÷ýýüúûù÷ùöôöòöøõïóíðôîóöñùúøüýûòõðïòìîòëíñëòõïõõõÿÿÿúúúîòìðóîêëéðððôôôñññýýýñôðÆÉÅìîëÇÊÆÈÊÆÏÏÎÇÊÅËÍÊêìéïóîçèæÎÏÍÐÐÐõ÷ôÊÍÉïñíÆÈÄÊÌÊêêéïóìüýüÊËÉÏÏÏèêçÕ×ÓüüûÍÎÌëíêÌÍËíñêÏÐÏùûøêëêòöðóõñÉÊÇñôîîñì!ù,Pÿ€ˆ‰Š‹ŒŽ‘ˆ‚@;/Ÿ ¡¢£¤¥¦§¨E(ƒ )·¸¹º»¼½¾¿À¸ 7„23ËÌÍÎÏÐÑÒÓÔÐ=*"DÝÞßàáâãäåæä8 îïðñòóôõö÷õ.A þÿ H° ÁƒM R ¡Ã‡#JœH±¢ÅŠ0)ˆÀ±£Ç CŠI²$Ɉ8Xɲ¥Ë—0cÊœIsæD-èÜɳ§ÏŸ@ƒ *”¢’*]Ê´©Ó§P£J:Q‚X³jÝʵ«×¯`­È@‚³hÓª]˶­Û·p‰ßÆ@ôÀݻxóêÝË·¯ß¿~O Bð °áÈ+^̸±ãÆ< @@¹²å˘3kÞ̹3gˆr Mº´éÓ¨S«^Ízõ D4 ÈžM»¶íÛ¸sëÞ­»¢Àƒ N¼¸ñãÈ“'·H€óçУKŸN½ºõë×} À½»÷ïàËO¾|y;openchange-2.0/apidocs/html/libmapiadmin/open.png000066400000000000000000000001731223057412600221500ustar00rootroot00000000000000‰PNG  IHDR à‘BIDATxíÝÁ €0 Ð׬ՙ\Àº€39—b!©9{|ðI>$#Àß´ý8/¨ÄØzƒ/Ï>2À[ÎgiU,/¬~¼Ï\ Ä9Ù¸IEND®B`‚openchange-2.0/apidocs/html/libmapiadmin/pixel_grey.gif000066400000000000000000000000531223057412600233340ustar00rootroot00000000000000GIF89a€îîî!ù,D;openchange-2.0/apidocs/html/libmapiadmin/structmapiadmin__ctx.html000066400000000000000000000045311223057412600256120ustar00rootroot00000000000000 libmapiadmin 2.0 API Documentation
mapiadmin_ctx Struct Reference

MAPI admin function context. More...

#include <libmapiadmin.h>

Detailed Description

MAPI admin function context.


The documentation for this struct was generated from the following file:

Creative Commons License
Creative Commons Attribution icon Creative Commons Share Alike icon
This content is licensed under the Creative Commons
Attribution ShareAlike License v. 3.0:
http://creativecommons.org/licenses/by-sa/3.0/

openchange-2.0/apidocs/html/libmapiadmin/sync_off.png000066400000000000000000000015251223057412600230170ustar00rootroot00000000000000‰PNG  IHDRàw=øIDATxíÝKhTWÀñÿä1I&3™8M¦Iš™†I3Ú©b$cÌ I1V1±-(Tö±±Ð.* t!‚K[¥Ä¥ˆ„¨´f£`l(øl©"Y”¤6ÆgÌTú}·sgîܹ ±d{8?æÌ¹÷;çÜuíÚ`:!±F¬¢BäŠ?ŰÄm'yÊÅ>ÑlU¯½üý‰è_‹?€Œê ]€Y(ŠNñ±8fý1°Öqún-eâ¨øtºmâÈ Ó0}b›ù%·©µ×Œ®=Ÿ0´³?Š1sŸ‹0€¯8À‘;_ ‹W|%\ Zð— >舽ln¨p©.aÇ{ )t;Ú b nŸš¯›65°¢¡2çÅÔ?Žž>Oдàuönm¤¢Ì`×­Z¬WjC~>‘Ö¾0+á {{©fÝ×Mæ·æÅ•ìÙ¼˜` Ý›%uA6´½ÅÆö¨Á,]k¢ÄW¼™u±›]‹ˆ7§¯iòh€ ¶¶¬ÏÖu1 ló —Ҷ̺–:ÞÍ\ÄcãÏxøhR²Êè‡Qt$¿ß§¨ ª fdºü<4BÿÙ[•f¸d7=.Mé9/—éªÃëù/ÿO Üaàò}€,‘j?Ÿõ.5Úšm?œÿŸ®ŽXÿ2¬#¸d píæ(£?cÛú¼!½›a1¥Þ—ŽòØ©ܾ7dÔK:‚ùÒ‰ì)Ê3‚Ü™àÌà]€,±H€µ+køöäu<|`·LhC7¹ÔeÍ Ÿ×Ÿ˜tÜ‹ óH$^2%l.êaeÐäýE”ÌÉ|ÅÜìî‰Ýsä }¸ýDû^hzé~ðR›¦Ã¡¿]|#ü¯@×—Ö‡[k¹–<|š(Ç*€Ý¹dÇtMé:Ýñø«Ø,êÅû¢]”' øXÓ_nò¡Æ|Øý /c§fžâOIEND®B`‚openchange-2.0/apidocs/html/libmapiadmin/sync_on.png000066400000000000000000000015151223057412600226600ustar00rootroot00000000000000‰PNG  IHDRàw=øIDATxíÝ_HTYÀñï8ã¤ó§i§4-g6ÆËÕ&kQ)¨Ô!Š0ÒURKÚ…„ê¡/»PEÁ>ìK-+KÁ²Ñ.Y”¾dEPaA‰ø°¥¶›ZSÓïÜ;3wºŠ–¯—߯gfîïœsçœWKÇñ.€ÉøD­¨a‘'¬âq_ôˆk¢ÀŒ ÀDŽøQ´ÄïC¨¶åñÏÿgÅ ñ 0„Y‚:qZ¦Á)~õâ€èLý0HVñ× žz-¿‰C“%¨g¦˜6€é8%Úõ¬ëwêÙUÏ¿˜ª³Ä }? ?€·3ÀÀž©Š À”K• @hà a±ðaÇæUe‹ sù~ë2²ì“&Ú&B*AÄljæºììi*˨,Ëçí»÷oÆ£T”,d[˜¼3-*ÁÀ…>å‡Ë çLÉŸçfk˜Ò éw#*AEjKUy>ûšËÉõ&{µ¢8—m5Ki¬ jjƒD*¿NŽÖigwÃ7Dª’mz骹úKÛ¾±ˆ¶M!æ¤ÍkÐ?šoý¬_åÓlXí#Ò~–¸¬ê×ÒÑXŠÓ‘ùRÙ*Eû‚ՂדðEÜ;6«e"Q(²Ù=–¿Ezæ5Kؼָ_ 1òzBªJë ±XŒì96åªjL^7{ùãJÑ÷1½i@%8'7M©_\Qœ#ÓUŒËñýÿyõ Wo Éx8¼s¥v¯ªì|×SnÜ q_m Ýé î>bèÕí[JX,½4[Tú{R£ë¼ôˆ¾þa€tÝjjzzÅ'ÅìȶiIžŽòwÏs ¡€—ÕKøõâC^ŽŒ˜Y­¨µÉ%6¨´êˆº]vÛðhâ½iWv–hôëê°Ò¨¾'æÌ‚·ñ|[ßìúÅ^€YrD=<ýDû]äÇ÷s€Ïõ‹8™ºCì? À ¨—t4õᩎ¡Jã‡W‹É± îr¼cjMɘìx| šE©øNÔ‰œøA¢þ«–€Z¼ñ‡jó î#™§¢¢4gIEND®B`‚openchange-2.0/apidocs/html/libmapiadmin/tab_a.png000066400000000000000000000002161223057412600222530ustar00rootroot00000000000000‰PNG  IHDR$ÇÇ[UIDATxíK €0C'o¤(Šˆ[Žà%Üxÿ#Ù©­ç ùÁöó¦W¦e# 3t I 3+¼øEã~\D½9¯Ûàè’wM·¿öÿ}Yõ_êA4Yžã}IEND®B`‚openchange-2.0/apidocs/html/libmapiadmin/tab_b.png000066400000000000000000000002471223057412600222600ustar00rootroot00000000000000‰PNG  IHDR$ÇÇ[nIDATxíÝQ Â0„áàœR¥Xc±I7IÓ¨g|òÕÙœäãgY˜3˜Ï÷‡u{£ÔW—ÊSíŒ1Ü ¼CjˆiC†G¬ýççJ+| ÖÝs7ùŒ+Ù›`t‚3Ü‚a¢K¤Gq°ûQÍZÝT=@*éC݇LIEND®B`‚openchange-2.0/apidocs/html/libmapiadmin/tab_h.png000066400000000000000000000003001223057412600222540ustar00rootroot00000000000000‰PNG  IHDR$ÇÇ[‡IDATxíÝË ‚@EÑ 7êÂX’Ñø AADùjGü€ Z€e؈£ ë8¹›—Wƒx¾ÞìUK.µ%„0mɤ&+4iÑ$džÈt“׿ÍzWf5AZá'w¼øÆ"2¶Wœðòg%öªdæ)æþ™ÉR15F®dìž ÉБßO«×Áô»C"à@¯g=IEND®B`‚openchange-2.0/apidocs/html/libmapiadmin/tab_s.png000066400000000000000000000002701223057412600222750ustar00rootroot00000000000000‰PNG  IHDR$ÇÇ[IDATxíÝ ‚@@Ñ£?Q…¤"š¢%¦I‘—Šf–6[´HÃäQƒ<Þâõþ]ždr Í’s?ˆO=Ñññw'ÌF‡Ž íðö-~rÃ[œèŠ­ì¬mƒÖ¬ƒݯнŠÕF)Yº% §`nÌ,9B ™’©!ÑŒ\ý<Å#üîî•IEND®B`‚openchange-2.0/apidocs/html/libmapiadmin/tabs.css000066400000000000000000000022131223057412600221410ustar00rootroot00000000000000.tabs, .tabs2, .tabs3 { background-image: url('tab_b.png'); width: 100%; z-index: 101; font-size: 13px; font-family: 'Lucida Grande',Geneva,Helvetica,Arial,sans-serif; } .tabs2 { font-size: 10px; } .tabs3 { font-size: 9px; } .tablist { margin: 0; padding: 0; display: table; } .tablist li { float: left; display: table-cell; background-image: url('tab_b.png'); line-height: 36px; list-style: none; } .tablist a { display: block; padding: 0 20px; font-weight: bold; background-image:url('tab_s.png'); background-repeat:no-repeat; background-position:right; color: #283A5D; text-shadow: 0px 1px 1px rgba(255, 255, 255, 0.9); text-decoration: none; outline: none; } .tabs3 .tablist a { padding: 0 10px; } .tablist a:hover { background-image: url('tab_h.png'); background-repeat:repeat-x; color: #fff; text-shadow: 0px 1px 1px rgba(0, 0, 0, 1.0); text-decoration: none; } .tablist li.current a { background-image: url('tab_a.png'); background-repeat:repeat-x; color: #fff; text-shadow: 0px 1px 1px rgba(0, 0, 0, 1.0); } openchange-2.0/apidocs/html/libmapistore/000077500000000000000000000000001223057412600205445ustar00rootroot00000000000000openchange-2.0/apidocs/html/libmapistore/24px-Cc-by_white.svg.png000066400000000000000000000053061223057412600250040ustar00rootroot00000000000000‰PNG  IHDR°çá»bKGDÿÿÿÿÿÿ X÷Ü pHYsHHFÉk> IDATXýXmP”U¾vˆeY pW$gQH–%ãËc*$åÃIkFmiØ‘ttrê‡C öa3 Œc†D$ e¬±X, «@³ Â.Èîõþy›uÓ÷·÷úóÌœçÜϹîëºçÜç<þxHØNÛNÛN½+zWô®.–_,¿X|»æÛ5ß® Q†(C`4F#p×ý®û]w@qRqRqðÿÎÿ;ÿcaÇÂŽIÅIÅIÅ@˜$L&Ämâ6qÛòÀ‡Ä-í-í--ùVë[­oµ’ <. … ¡B¨øSRT(*’’IŽ$‡”æHs¤9¤S’S’S‰ð>°Ï÷ˆôˆôˆ$Óôiú4=Ù2Ú2Ú2JZ•V¥Uù`^‚û9À3<Ã3À7ýßôÓl?Ø~°¸ªºªºªœ‡œ‡œ‡€ 6Øpx&õ™ÔgR0—0—0ÀMá¦pSB©P*”–õ–õ–õ@²GÙ£šª›ª›ª¦mMÛš¶#êõˆðj÷j÷jöeïËÞ— äÎäÎäÎÒ^i¯´÷að£ýȳégÓϦ“K{–ö,í±+¦êRu©ºÈŠÎŠÎŠNòöÔí©ÛSë£sñsñsñd{^{^{™u%ëJÖÒÅÛÅÛÅ›IER‘”ÔìÕìÕì%ÇSÇSÇS~gAuuu¤|µ|µ|5)øJð•à+rGËŽ–-äÀ±cÇþs‚å)ËS–§ÈÒ-¥[J·ž»=w{î&µ‚ZA-™÷BÞ y/³£³£³£‹$psäæÈÍR•¨JT%ÚßñýŽïw|OšÌ&³Éü¿'þWX­ÖFòÔ“§ž<õ$é6â6â6Bºæ»æ»æ“ÕÕÕ÷&°Ÿû¹Ÿ<”p(áP‚xxQxQxyëÀ­·üóÄÿŠùçœÿ‘Ô®Ô®Ô®´óŠx.⹈çÈÁÎÁÎÁN7ŽÜ8rã¹æÙ5Ï®y–tŠwŠwŠ'+++ÿÿÄÿŠã€qÀH¿üzðë¤(H$ "‹4Eš" ) ø0àÀ:³ñÌÆ3··7à é é  pNwNwN¦º¦º¦º€ZS­©Ö\K¹–r-èÎíÎíΆg†g†gOgOgOgÀ˜bL1¦õâzq½XÒ·¤oI SÊ”2%033TÿQýGõ€h§h§h'àëëkßdÜÜÝÜÝ܉sç&Î õ õ õÀ¸iÜ4n°uÕÖU[WÙ-*4š ©õ^^^r¹Ãr‡å¤S•S•SéêêJºMºMºM’»rwåîÊ%ûûûIE¤"RIîÙ¼góžÍäÜÆ¹sÉý'öŸØ‚”'Êå‰dÛ–¶-m[îï„N£Óè4¤ÇÛo{¼MŠä"¹HN {]z]z]Ñ:Ñ:Ñ:@¥T)UÊE¶Û!q¸k¾k¾k2e™²LÐÛÛ ¤½Ÿö~ÚûÀ¥ÉK“—&ÿVÿVÿV c.c.c¨­­Ê®•]+»œK>—|.ˆÔDj"5@[t[t[4 _ª_ª_ºpýÕΫW;>Y>Y>Y€õwëïÖ߈§ÄSâ)R'‰“Ä‘Í7›o6ß\¨€Ál0̤¼SÞ)ï$ƒR‚R‚RÈ—3_Î|9“ô³øYü,dÒ¤I7H‹ŸÅÏâGöÕôÕôÕAùAùAù¤Ä 1H dÈùó!çɲÀ²À²@R\".—Å?ÿTüÓÂõïîîÈ(×(×(W{Åç:æ:æ:¡£ÐQèˆÒDi¢´E:žAª U L©§ÔSj`$a$a$pLvLvL†¶mÚ VVV~‰~‰~‰À®_wýºëWÀrÄrÄrÈPf(3”ÀóåÏ—?_|ôÉGŸ|ô ·!nC܆E–o4 šQ¨(Tj*ŠÅŠb`V2+™•o‹·Å{±– ‚€5Ôj Ò­éÖt+P¡þBý ðzáõÂë@÷+ݯt¿èôú{x`c`c`#à~Úý´ûi À` °K>_òù’ϵ«ÚUí È5r\³È!2Ï–g˦ççÃïy}9úrôe»%%×K®—\_¤„ú }†>R!UHRò1ŸÇ|ó!ãZãZãZIe´2ZM.»³ìβ;d{{{¿=¾á†7Þ =.x\ð¸@Ö)ë”uJ²¥­¥­¥\öȲG–=B~œúqêÇ‹z²{²{²Iß}¾û|÷ÝSBª¯U_«¾¶'ÔTßTßTÌý6÷ÛÜoöqéyéyéyàÅÒK_,ÔoªßT¿ xj=µžZ F#‘'kOÖž¬B2B2B2ìñò+ò+ò+ÀK›^ÚôÒ&@Þ!ïw2³Ì,3¿Düñ  ($ ÉBt't't'€Á̓›7+›V6­lÐÜÜL>ŠGñ(Hï×¼_ó~¼úóÕŸ¯þ|5¬a iK±¥ØRH[€-À@Ú²mÙ¶l’{¸‡{þ¦#íænî&mkmkmkIÆ1Žq$ýéOÒ*° ¬Òö¥íKÛ—ö°™’™’™2ùpòáäÃvås r r H˜½Ì^f/r[Ö¶¬mYö Y]Y]Y]¤ùóæþávû7¨\W¹®r)žψgHŸ­>[}¶’º]‰®äžÃ\K]K]KéuÉë’×%Rü©øSñ§di|i|i#FQ`$c¼b¼b¼ÈŽ‹;.Þ_€^êg3f3f3Èʵ•k+×’êUêUêU¤Ãr‡åËIÇq'=4 ¹~lýØú12*+*+*‹ŒÍÍÍ'Ueª2Uéû®ï»¾ï’!!!v¥W„­[FjõZ½VO' ' '<ØÁ‡þ+ñ'†††È¢²¢²¢22\® ב2™ƒÌNèAOßbßbßb2Ç%Ç%Ç…ÔéuzžœŸŸx>ÿ^5¡–ü+^:tEXtComment Created with Inkscape (http://www.inkscape.org/) ã+ldIEND®B`‚openchange-2.0/apidocs/html/libmapistore/24px-Cc-sa_white.svg.png000066400000000000000000000053061223057412600247750ustar00rootroot00000000000000‰PNG  IHDR°çá»bKGDÿÿÿÿÿÿ X÷Ü pHYsHHFÉk> IDATXÕX}LÓW>¿ ´–.Ôb±‚" Cèê(lS„9ÉuN&n ʹŒ,+&+™“à&3[a`Ë$™ãs‰3Ö¨L(ŠX¸Åñá¬EÄ4ElK¡åyÿy÷–¼µ/¾çŸ›ÜsŸsžûœÓ{· þmô”¶ðà?¬Y3²†èBý…ú õD—7\ÞpyÑpâpâp"‘Ñh4DóÏÌ?3ÿ QPmPmP-QØoa¿…ýFw"îDÜ ¢ŒÊŒÊŒJ¢8n7ŽKäwÃï†ß§eCDxJ3›ŠMÅÀgW?»úÙU ‚‰`"€Ä bý#À>Ê>Ê> p ¸Ü€WÀ+àË3–g,Ïèú†¾q¯Ø°%` ===è&tº ÀéŠtE.Í‹ñVœÁœ!ºxçâ‹wˆ>5|jøÔ@Ô#ë‘õȈ|Ç|Ç|Lj^,z±èÅ"¢m»·íÞ¶›(Žljãùùù±x,‹G4;;K499IÔÞÚÞÚÞJÔ¾§}Oû"s‚9Áœ@$4 BQa~a~a>Ñ!Û!Û!o„7Âyš ¬Çz¬ßi|§ñ`ÕЪ¡UCnÅdý²~Y?ÐÔ×Ô×ÔLÍLÍLÍÂGø8¶ãØŽc;ÜÄãËãËãËS‘©ÈTäxÏ®ž]=»€Wv^Ùy´ Z­SÏÔ3õ‹~Ü&¶‰mÄ_‰¿ ;v( 05›šMÍžqÝÎng7P¼¶xmñZwœ—^éõ—^îõÝë»×Ð`é`é`)°áµ ¯mx Xž²äeò2y™'ñA„ B”ØJl%6 nUݪºU€*Z­ŠÄÄÄ“Ïä3€å[Ë·–o½ãq·qØkÝkÝkõl¥ÏÕŸ«?W{Â?~< $®H\‘¸Â½Þg®w®w®—ˆ³Œ³Œ³ŒˆÍÎfgQuQ—§¯È_‘¿"'Ò˜5f™Hë¯õ×úûëØ_Çþ"âïçïçïÿß.ëi=­'ò©õ©õ©õtϧϧϧ{Î3LÓAÄ–²¥l)éHG:"VPePeP%‘ƒëà:¸D³³³ÞóOØ'ìv¢Õ©«SW§åìËÙ—³È,7ËÍr"G…£ÂQá?—7—7—G4ùóäÏ“?{ú\WÀõœ_P-¨TDÖxk¼5~‘ckçÖέî’TýQõGÕÞ;à|Öù¬óY@ÀÉ€“'Þ:Þ:Þ:@œ&N§cccÞñÝ‚nA·ý$úIô“;/š?ÍŸtƒºAÝN¡¡ü¡ü¡| ¤0¤0¤pQë}RôIÑ'¯³¾ÎúpŒ9ÆO 2Z3Z3ZÄŒ9s㇓w%ïJ޴ŶŶÅwDwDwDÀÅ÷/¾ñ}`Ëw[¾Ûò'îÍóožó<`}×ú®õ]ϼgfÏÌž™XZ––¥Ö¶¯m_ÛP‡¤CÒ!$ ~ø!ÐógÏŸ=zW²V]«®Uœ:N§n¡(Š¢(À?Ê?Ê? Í Í Íxž…gñ$ê u…º€®³]g»Îzæ±UÙªlU€¼D^"/Yto¨ Ôj€ìB»Ð.ö(ö(ö(Ü ýŠ~E?`ï²wÙ»<;„¡ChÞм¡y±D,ë 7ò¬V +Ø”»)wS.pI}I}Ií]¨æèæèæhÀÏægó³Á™Á™Á™€¾J_¥¯Zô1§Óê´:- ¼"¼"¼ø}ï÷½ß÷@uJuJu àZp-¸<8wþîü0ì7ì7ìJ5¥šR ùwæß™ÛÓ·§oOÞî|»óíNà”ñ”ñ”ý–ý€~@Äì‹Ù³Ï-@qqq?° ].HmÀ5åšrMǧOŸXm¬6V°²deÉÊàtÆéŒÓ€óWç¯Î_½'F ZÐ8ßs¾ç|˜+Ÿ+Ÿ+\®W€ILbÒ;ü¦ô¦ô¦ØÜ°¹asƒ›xÒñ¤ãIÇñeãËÆ—¹×{¼   ¥F©QjV:+•ð[ø-ü@=®W÷ÎÝ;wïÜÒ„–2[Ž-Ç–4O7O7O76nlt—<”<”<zózózó<ñ^ßÄ–dK²%PVVx¾<_ž/À\b.1—I¶$[’ |Éÿ’ÿ%Ðwê;õÀdÅdÅd` ³†YÃk‹µÅÚÌlÙ:³>0|`øP¯®W׫ù«òWå¯Ü:n·`ŒŒ‘1IÂ$a’è½Ð{¡÷‚w–|Ô;ö:ö:öÍÏ7?ßü<šš øˆ}Ä>b€4¤!   P(ØÉØÉØI Q‘¨HTÉG’$d5²Y r2ädÈIÀçŸ|^p+½&nMÜš8 x x xß1¾c|ÇÒ|ê%þ±±gÇž{(¯)¯)¯âõñúx=àÃ÷áûð—>…þC*C*C*N§€èôúÀ™âLq¦<=ŸYΧюéÈ:tEXtComment Created with Inkscape (http://www.inkscape.org/) ã+ldIEND®B`‚openchange-2.0/apidocs/html/libmapistore/CC_SomeRightsReserved.png000066400000000000000000000064521223057412600254120ustar00rootroot00000000000000‰PNG  IHDRZ¬a x pHYs  šœtIMEÕ ÌIðbKGDÿÿÿ ½§“ ·IDATx^í™iŒUEÇû¾{ßÚÝ6ë"²Š‚@!`˜DÇ¡Ä "Œ2 ×%Æ(ê—D£ñƒ1¨â’Œ@Pƒ¢HezXš¦é†¶~¯ßrç÷ïÜêyV¼ 1í„VòçÔz«þuêÔ¹÷9%¿Nr@$Bd\ºP¤Ç¤KˆÒ•HD€’È|² È h‘,Ò›= lœ)Ò›Íøí´2$Ù"ír«,n¤…˜Õ?À+B¸4d¤à `d‘ž—Þ†vL‘_‰h×&By#Äl ,‹OHIÚyû¤Ø°N‡¤g¡èäÒùnÑ‹0 g­Kë!í i6IÁ¶dËŠ…‚bÉFÝ?Ÿ-ÚŠ°áÙ–eÈO&“‰gŸ}vä–-[¦œ8qâŽ\.7çÌ™3Ó÷ìÙ3áý÷ß¿büøñÝdÉňÅb©Ç{lÐ÷ßÿ‡ãÇÏ ÏÜæææ¿8p`ÎòåË+§L™ÒËz– {®ƒö½´Ú?Å­cݦ[e‰â²áÇw]¶lÙ´¾}ûBfxrçfÞ_|±»bÅŠ!ƒ *ÿ}]xÍÒ’V™OŸï ¤­{–.¸Xrì“O>ù“!yûöí 7ß|óêT*õwÊÖ<óÌ3ûNž<™S]±%Óg˜!yóæÍM7ÞxãÚÒÒÒ¥lÀâW^yeÝéÓ§3ª3Ï q5nHÞÎW‹ŽXVœ ½ÄŒ/¾øâè|p¢Ø·o_ãСC¿J§Ó­‘ˆÁ€Ê>ûì³—^ziµÚÍŸ?¿âÕW_í!}çΧG޹9“ÉüÄZ9%.}*{öì¹ð,–kK»¬p>Z´‰s£[å6\ÉÊÊÊ¡f€—_~ù_±#“½{÷:|ÈlÒ­·ÞÚÁôyþùç Ù³ýð¶mÛÒ¼È ýG2$ïXh—äµ?Ñá °7£OŸ>ÝÍøéc¶»Q+êp±ú˜é³råÊûb³78¶ 1Ë@Îï8ڱɷõb²ñÑqÓøÈ‘#9Ûê‹`ÜI²¢¢¢mîÇŽioŠÉ ß\#C²†óÐu„è>ˆ„µÃU´˜L÷îÝcöÆXäy Ååè›>;wöl²Î‘<'l íî:|ßïÐ^ƒmܸÑûâ‹/R555‰£G&!#ÉÍŸjiiI€$~4‘ÍfS<3U(ù|>!YWW÷Ã%—\ÒScÜvÛm=Þyçã´ñ€ "À´a¤<²y×®]±Ñ£G»êsÓM7¥/^|š0γD"qd©)D£Ñ‚ëº>(ñ<Ï!ïÁD€KÄâ^pÁ^×®]½þýûGG»æšk²í壎hÿ—ì&t¯ºêªDÇŽSç/‰ü1Á DB„Cr²“È/ñï¾û®Ú=oÞ¼Á«V­Ú€•»l‚ ’ýnݺ9o½õVçIˆË}ùå—ˆ.UŸ‡z¨ÓºuëWsvIž€ï/ýõ×õÒò7òˆ|P"‚ãñx+ɉDB$ srª¢½{÷Ž:êtåI¿”§VKqöÆç>8dF°4Y³‡èä©S§â”'xÃK@r\0dƒ¸ÈfÑ©×^{m . \ãa_¸pa͆ 2eee¥×]w]§Ù³gwÁÚ´‘GÔF$}øá‡{õêå)_UUuúÍ7߬ٺuë:uÊOœ8±ãÔ©SB^ ‹ÿ+äf »b3œ¡:@†x= Ùiü~¦C‡é.]º¤ÙØ QN3ýE´c‘z.ût Ñã• 'ôÜwÒœC‡űæ8¯Ã²è˜ˆ†ä¸¬ZRD$Çò²êaX—ûî»od—…ÎÜ÷Kn¸á†ƒÈV]ÀêܧŸ~ºë…^;[Ÿ»îºk‘!¤A‹ò\ÂÑ­`#Óll Va61­S`Nz8ܧžzêrë±Ñ%amŠÛâE`)$¤°ž$H±¨V“ÿMqEJÒYd î¯]»¶™§Øƒÿ›P¨¯¯ÏàN¾ñÆGñë9Ú°´zvÍš5M¸™,㔀ˆéÓØØxŠ7ÌÚ?þx#d·@bIyy¹ƒŒX¯ "Pç"=ê$]¤GY4„#Ût›3ÆG;ç°3þ9„>>ĉ´$DuAZ ×!b£" –%G%!$J[å¥{HwQ © ô­KQÒEF°´¶èEV òëׯo¤_=$çØì2+ g±È,® Ɔ—°yÅ £ e¾Ñ6/ÊI?%&)’€hî£ëtt´^~ä}‘Œlõ딹ä[A>á’Q ’uZZ@–òlȧÒPÂmiÝ1”àp_ä‡í¤Êb<‘*²Ñ•$[‰ HÑ’Ê»"2% Éå!URd;"8€X³’¤A„ä—ä{$‘/QˆDIr³Áüäzb¤2«r…ƒg#ÖÒC91á]…UîôIaÖl„N^£+ŽÕÊÛˆ’Fò’&/˜ÐN1´¤±nG©Øª€acÝH§ØºE0R¹²æ"Œ/=t?´¡`.ÄšM:«±àDæÎ;ž[ÎsÏ=7’ ©O¿~ýoûh#Øåy›6mêÅGšÞ¯{T¦~Lêµ½þúë')o±^N})Ÿ9ï Þüî»ï*ÔJ¦HcÇŽ­ä¢Ià³Ëˆ›¯ tÅÇû¡„V1.¢èôéÓ/G÷„Ûo¿}0Ò%Vî?cÆŒA?üpß%K–t&Bé‡/¯Ï&JP[éJÖ¼ûþùç=xNœ‹-~íµ×þž—¡±<çwšÃK/½4Œ²Ê÷Þ{oëÓúèÞξ¥s eKu¤¦M›¶öJW;AþLõÒ L×°Œpn¹üŸ1WCBšèá«Ã‡¯¡,W]]ý-ñmý#zTܨêŠ]ª)ã›ù)Þ./“.‹Þüõ×_ïâm*Ë—³²œÊ£ó Ü|°wÑ¢E²¦¶zŽHžÎ°ÓÊÛàRÛ*ÿ©yŽì¼*^`ªd‘¼Ììfü<ñî>\×q^:²lÈA¬þ ãØ"H¯­­=Ì‹Pý ’K—.=¦·?Œ¢^yÕ ¤Z¾›R‘Ìiiâ µ«Ý¯2æšÁ5œàÌ.>­V3FÒªpaÛ5Oꛃµl1ëÓéxüñÇkUÆÿ’UãÆ;‰;Ép¯l ã@ÙŠèý úÉ'Ÿlš5kÖIÞós¼Å€”ê=zäT/BL;£•W Ê[¨D*ǹŽ;@ãÖæRúa&œƒ˜zȯg¬ßEØ€£ÒqeÇ8ÒÒ% I—ظ33gÎLKW½ú©þ»‰gæÉ7˜ñ±ò:=bk™GíO%ƒŽñ}CãÙQQ mEõLŽzÏÌ«LÏ4m!ÚçBup›)½ä´­Å¬¿ÃÊÇá.è7±ÏÅáCŒÏDýÝ»wûJøÈVië,ºµíœ9s|;Ùí¹©}.Ÿ”aŒ>dû,ÆçHZ}Btk¾çöL{®öv}ø8Òq¡¡˜²!C†ø&Lðq]¾DÿÊé7üFôÿÿj|w‚%&IEND®B`‚openchange-2.0/apidocs/html/libmapistore/apidocs.css000066400000000000000000000362151223057412600227070ustar00rootroot00000000000000/* ** WEBSITE ** */ BODY,H1,H2,H3,H4,H5,H6,P,CENTER,TD,TH,UL,DL,DIV { font-family: Geneva, Arial, Helvetica, sans-serif; } BODY,TD { font-size: 90%; } H1 { text-align: center; font-size: 160%; } H2 { font-size: 19px; font-weight: bold; color: #3E93D5; } H3 { font-size: 100%; } P { text-align: justify; } LI { li-style-type: square; li-style-position: outside; display: list-item; } CAPTION { font-weight: bold } DIV.qindex { width: 100%; background-color: #e8eef2; border: 1px solid #84b0c7; text-align: center; margin: 2px; padding: 2px; line-height: 140%; } DIV.nav { width: 100%; background-color: #e8eef2; border: 1px solid #84b0c7; text-align: center; margin: 2px; padding: 2px; line-height: 140%; } DIV.navtab { background-color: #e8eef2; border: 1px solid #84b0c7; text-align: center; margin: 2px; margin-right: 15px; padding: 2px; } TD.navtab { font-size: 70%; } A.qindex { text-decoration: none; font-weight: bold; color: #1A419D; } A.qindex:visited { text-decoration: none; font-weight: bold; color: #1A419D } A.qindex:hover { text-decoration: none; background-color: #ddddff; } A.qindexHL { text-decoration: none; font-weight: bold; background-color: #6666cc; color: #ffffff; border: 1px double #9295C2; } A.qindexHL:hover { text-decoration: none; background-color: #6666cc; color: #ffffff; } A.qindexHL:visited { text-decoration: none; background-color: #6666cc; color: #ffffff } A.el { text-decoration: none; font-weight: bold } A.elRef { font-weight: bold } A.code:link { text-decoration: none; font-weight: normal; color: #0000FF} A.code:visited { text-decoration: none; font-weight: normal; color: #0000FF} A.codeRef:link { font-weight: normal; color: #0000FF} A.codeRef:visited { font-weight: normal; color: #0000FF} A:hover { text-decoration: none; background-color: #f2f2ff } DL.el { margin-left: -1cm } .fragment { font-family: monospace, fixed; font-size: 95%; } PRE.fragment { border: 1px solid #CCCCCC; background-color: #f5f5f5; font-size: 11px; margin-top: 4px; margin-bottom: 4px; margin-left: 2px; margin-right: 8px; padding-left: 6px; padding-right: 6px; padding-top: 4px; padding-bottom: 4px; } DIV.ah { background-color: black; font-weight: bold; color: #ffffff; margin-bottom: 3px; margin-top: 3px } DIV.groupHeader { margin-left: 16px; margin-top: 12px; margin-bottom: 6px; font-weight: bold; } DIV.groupText { margin-left: 16px; font-style: italic; font-size: 90% } BODY { background: white; color: black; margin-right: 20px; margin-left: 20px; } TD.indexkey { background-color: #e8eef2; font-weight: bold; padding-right : 10px; padding-top : 2px; padding-left : 10px; padding-bottom : 2px; margin-left : 0px; margin-right : 0px; margin-top : 2px; margin-bottom : 2px; border: 1px solid #CCCCCC; } TD.indexvalue { background-color: #e8eef2; font-style: italic; padding-right : 10px; padding-top : 2px; padding-left : 10px; padding-bottom : 2px; margin-left : 0px; margin-right : 0px; margin-top : 2px; margin-bottom : 2px; border: 1px solid #CCCCCC; } TR.memlist { background-color: #f0f0f0; } P.formulaDsp { text-align: center; } IMG.formulaDsp { } IMG.formulaInl { vertical-align: middle; } SPAN.keyword { color: #008000 } SPAN.keywordtype { color: #604020 } SPAN.keywordflow { color: #e08000 } SPAN.comment { color: #800000 } SPAN.preprocessor { color: #806020 } SPAN.stringliteral { color: #002080 } SPAN.charliteral { color: #008080 } .mdescLeft { padding: 0px 8px 4px 8px; font-size: 80%; font-style: italic; background-color: #FAFAFA; border-top: 1px none #E0E0E0; border-right: 1px none #E0E0E0; border-bottom: 1px none #E0E0E0; border-left: 1px none #E0E0E0; margin: 0px; } .mdescRight { padding: 0px 8px 4px 8px; font-size: 80%; font-style: italic; background-color: #FAFAFA; border-top: 1px none #E0E0E0; border-right: 1px none #E0E0E0; border-bottom: 1px none #E0E0E0; border-left: 1px none #E0E0E0; margin: 0px; } .memItemLeft { padding: 1px 0px 0px 8px; margin: 4px; border-top-width: 1px; border-right-width: 1px; border-bottom-width: 1px; border-left-width: 1px; border-top-color: #E0E0E0; border-right-color: #E0E0E0; border-bottom-color: #E0E0E0; border-left-color: #E0E0E0; border-top-style: solid; border-right-style: none; border-bottom-style: none; border-left-style: none; background-color: #FAFAFA; font-size: 80%; } .memItemRight { padding: 1px 8px 0px 8px; margin: 4px; border-top-width: 1px; border-right-width: 1px; border-bottom-width: 1px; border-left-width: 1px; border-top-color: #E0E0E0; border-right-color: #E0E0E0; border-bottom-color: #E0E0E0; border-left-color: #E0E0E0; border-top-style: solid; border-right-style: none; border-bottom-style: none; border-left-style: none; background-color: #FAFAFA; font-size: 80%; } .memTemplItemLeft { padding: 1px 0px 0px 8px; margin: 4px; border-top-width: 1px; border-right-width: 1px; border-bottom-width: 1px; border-left-width: 1px; border-top-color: #E0E0E0; border-right-color: #E0E0E0; border-bottom-color: #E0E0E0; border-left-color: #E0E0E0; border-top-style: none; border-right-style: none; border-bottom-style: none; border-left-style: none; background-color: #FAFAFA; font-size: 80%; } .memTemplItemRight { padding: 1px 8px 0px 8px; margin: 4px; border-top-width: 1px; border-right-width: 1px; border-bottom-width: 1px; border-left-width: 1px; border-top-color: #E0E0E0; border-right-color: #E0E0E0; border-bottom-color: #E0E0E0; border-left-color: #E0E0E0; border-top-style: none; border-right-style: none; border-bottom-style: none; border-left-style: none; background-color: #FAFAFA; font-size: 80%; } .memTemplParams { padding: 1px 0px 0px 8px; margin: 4px; border-top-width: 1px; border-right-width: 1px; border-bottom-width: 1px; border-left-width: 1px; border-top-color: #E0E0E0; border-right-color: #E0E0E0; border-bottom-color: #E0E0E0; border-left-color: #E0E0E0; border-top-style: solid; border-right-style: none; border-bottom-style: none; border-left-style: none; color: #606060; background-color: #FAFAFA; font-size: 80%; } .search { color: #003399; font-weight: bold; } FORM.search { margin-bottom: 0px; margin-top: 0px; } INPUT.search { font-size: 75%; color: #000080; font-weight: normal; background-color: #e8eef2; } TD.tiny { font-size: 75%; } a { color: #1A41A8; } a:visited { color: #2A3798; } .dirtab { padding: 4px; border-collapse: collapse; border: 1px solid #84b0c7; } TH.dirtab { background: #e8eef2; font-weight: bold; } HR { height: 1px; border: none; border-top: 1px solid black; margin-bottom: 50px; } /* Style for detailed member documentation */ .memtemplate { font-size: 80%; color: #606060; font-weight: normal; } .memnav { background-color: #e8eef2; border: 1px solid #84b0c7; text-align: center; margin: 2px; margin-right: 15px; padding: 2px; } .memitem { padding: 4px; background-color: white; border-width: 1px; border-style: solid; border-color: #ccc; -moz-border-radius: 8px 8px 8px 8px; margin-bottom: 30px; } .memname { white-space: nowrap; font-weight: bold; font-size: 12px; margin: 10px 10px 10px 10px; } .memname EM { color: #45417e; } .memdoc{ padding-left: 10px; padding-right: 10px; } .memdoc EM, TD { font-size: 12px; } .memproto { background-color: #e9e9f4; width: 100%; border-width: 1px; border-style: solid; border-color: #ccc; font-weight: bold; -moz-border-radius: 8px 8px 8px 8px; } .paramkey { text-align: right; } .paramtype { white-space: nowrap; } .paramname { color: #602020; font-style: italic; white-space: nowrap; } /* End Styling for detailed member documentation */ /* for the tree view */ .ftvtree { font-family: sans-serif; margin:0.5em; } .directory { font-size: 9pt; font-weight: bold; } .directory h3 { margin: 0px; margin-top: 1em; font-size: 11pt; } .directory > h3 { margin-top: 0; } .directory p { margin: 0px; white-space: nowrap; } .directory div { display: none; margin: 0px; } .directory img { vertical-align: -30%; } #website { width: 820px; height: 100%; margin-left: auto; margin-right: auto; text-align: left; /* IE hack */ * position: absolute; * left: 50%; * margin-left: -410px; } /* ** HEADER ** */ .header { height: 200px; background: url(header.jpg) no-repeat top center; } body { background: #fff url(body_top_bg2.jpg) top left repeat-x; font-family: Arial, Trebuchet MS, Tahoma, Verdana, Helvetica, sans-serif; font-size: 11px; line-height: 17px; color: #444; color: #3a3a3a; fdpadding-top: 15px; text-align: center; background-color: #fbfbfb; } h1 { font: 24px bold Trebuchet MS, Arial; color: #FFF; padding: 0; margin: 0; } /* ** MIDDLE SIDE ** */ #middle_side { display: block; height: 100%; width: 800px; margin-top: 7px; backsground: url(middle_bg.jpg) top left repeat-x; background-color: #fbfbfb; } /* left and right side */ #left_side { background-color: #fff; clear: both; margin-bottom: 10px; border-bottom: 1px solid #eee; border-left: 1px solid #eee; border-right: 1px solid #eee; -moz-border-radius: 0 0 8px 8px; height: 29px; } /* ** MENU HORIZONTAL ** */ /************ Global Navigation *************/ DIV.tabs { float : left; width : 100%; background : url("tab_b.gif") repeat-x bottom; margin-top : 10px; margin-bottom : 4px; } DIV.tabs ul { margin : 0px; padding-left : 10px; list-style : none; } DIV.tabs li { display : inline; margin : 0px; padding : 0px; } DIV.tabs A { float : left; background : url("tab_r.gif") no-repeat right top; border-bottom : 1px solid #84B0C7; font-size : x-small; font-weight : bold; text-decoration : none; } DIV.tabs A:link, .tabs A:visited, DIV.tabs A:active, .tabs A:hover { color: #1A419D; } DIV.tabs SPAN { float : left; display : block; background : url("tab_l.gif") no-repeat left top; padding : 5px 10px; white-space : nowrap; } DIV.tabs TD { font-size : x-small; font-weight : bold; text-decoration : none; } /* Commented Backslash Hack hides rule from IE5-Mac \*/ DIV.tabs SPAN {float : none;} /* End IE5-Mac hack */ DIV.tabs A:hover SPAN { background-position: 0% -150px; } DIV.tabs LI.current A { background-position: 100% -150px; border-width : 0px; } DIV.tabs LI.current SPAN { background-position: 0% -150px; padding-bottom : 6px; } DIV.nav { background : none; border : none; border-bottom : 1px solid #84B0C7; } #right_side_home { font-family: "Lucida Grande", Arial, Verdana, sans-serif; background-color: white; padding: 0px 20px; border: 1px solid #ebebeb; border: 1px solid #ddd; -moz-border-radius: 10px 10px; width: 750px; * width: 800px; * margin-left: 0px; padding-bottom: 10px; } #right_side_home td { line-height: 17px; margin: 0 0 5px 0; padding: 10px 0 15px 7px display: table-cell; border-spacing: 2px 2px; vertical-align: middle; text-align: left; border-bottom: 1px solid #EEEEEE; } #right_side_home td h2, a.anchor { font-size: 19px; font-weight: bold; color: #3E93D5; } #right_side_home td.indexkey { border-bottom: none; } #right_side_home li { list-style-position: inside; valign: middle; } TD.indexkey { background-color: #e8eef2; font-size : 12px; font-weight : bold; padding-right : 10px; padding-top : 2px; padding-left : 10px; padding-bottom : 2px; margin-left : 0px; margin-right : 0px; margin-top : 2px; margin-bottom : 2px; border : 1px solid #CCCCCC; } TD.indexvalue { background-color: #e8eef2; font-style : italic; font-size : 12px; padding-right : 10px; padding-top : 2px; padding-left : 10px; padding-bottom : 2px; margin-left : 0px; margin-right : 0px; margin-top : 2px; margin-bottom : 2px; border : 1px solid #CCCCCC; } TR.memlist { background-color: #f0f0f0; } .mdescLeft { padding: 0px 8px 4px 8px; font-size: 80%; font-style: italic; background-color: #FAFAFA; border-top: 1px none #E0E0E0; border-right: 1px none #E0E0E0; border-bottom: 1px none #E0E0E0; border-left: 1px none #E0E0E0; margin: 0px; } .mdescRight { padding: 0px 8px 4px 8px; font-size: 80%; font-style: italic; background-color: #FAFAFA; border-top: 1px none #E0E0E0; border-right: 1px none #E0E0E0; border-bottom: 1px none #E0E0E0; border-left: 1px none #E0E0E0; margin: 0px; } .memItemLeft { padding: 1px 0px 0px 8px; margin: 4px; border-top-width: 1px; border-right-width: 1px; border-bottom-width: 1px; border-left-width: 1px; border-top-color: #E0E0E0; border-right-color: #E0E0E0; border-bottom-color: #E0E0E0; border-left-color: #E0E0E0; border-top-style: solid; border-right-style: none; border-bottom-style: none; border-left-style: none; background-color: #FAFAFA; font-size: 80%; } .memItemRight { padding: 1px 8px 0px 8px; margin: 4px; border-top-width: 1px; border-right-width: 1px; border-bottom-width: 1px; border-left-width: 1px; border-top-color: #E0E0E0; border-right-color: #E0E0E0; border-bottom-color: #E0E0E0; border-left-color: #E0E0E0; border-top-style: solid; border-right-style: none; border-bottom-style: none; border-left-style: none; background-color: #FAFAFA; font-size: 80%; } .memTemplItemLeft { padding: 1px 0px 0px 8px; margin: 4px; border-top-width: 1px; border-right-width: 1px; border-bottom-width: 1px; border-left-width: 1px; border-top-color: #E0E0E0; border-right-color: #E0E0E0; border-bottom-color: #E0E0E0; border-left-color: #E0E0E0; border-top-style: none; border-right-style: none; border-bottom-style: none; border-left-style: none; background-color: #FAFAFA; font-size: 80%; } .memTemplItemRight { padding: 1px 8px 0px 8px; margin: 4px; border-top-width: 1px; border-right-width: 1px; border-bottom-width: 1px; border-left-width: 1px; border-top-color: #E0E0E0; border-right-color: #E0E0E0; border-bottom-color: #E0E0E0; border-left-color: #E0E0E0; border-top-style: none; border-right-style: none; border-bottom-style: none; border-left-style: none; background-color: #FAFAFA; font-size: 80%; } .memTemplParams { padding: 1px 0px 0px 8px; margin: 4px; border-top-width: 1px; border-right-width: 1px; border-bottom-width: 1px; border-left-width: 1px; border-top-color: #E0E0E0; border-right-color: #E0E0E0; border-bottom-color: #E0E0E0; border-left-color: #E0E0E0; border-top-style: solid; border-right-style: none; border-bottom-style: none; border-left-style: none; color: #606060; background-color: #FAFAFA; font-size: 80%; } code { display: block; width: 100%; border: 1px solid #ccc; background-color: #e8edf3; padding-top: 10px; padding-bottom: 10px; padding-left: 5px; padding-right: 5px; margin-bottom: 10px; margin-top: 10px; } openchange-2.0/apidocs/html/libmapistore/bc_s.png000066400000000000000000000012501223057412600221560ustar00rootroot00000000000000‰PNG  IHDR /ð9ÐoIDATxíMLAÇßìN»»¥ívKùPJik±R5^ŒChÂŃ!Dzƒ *U4VƒbÄD1~`8xà@ˆ^¿?ð𤡸Ý@јÝná`JLLÝØ¦ƒÜXi v«9ê)·}aV±&Ò0)›¼ð(‰zÛküNcFPÛù'@é¨KZK%!13§5£}Ý€ÒdÀã°’>´Åç´çhï¹G…ÉZ ïz×Ú—Éi£“ì–º=…@O¹«È‚1Ó¯¦3ãF«[ºä’d²¾JÒã`|^3˜Ý\›¿¡]²ó•'fçÓùyˆÄîçâÙ@¥Cos˧d:?$lhûnÝ× nm\†$cÔL6Ñý »Ì´x@N¦oPÀ®Î‘òÕ”€GÔ÷>9¹¨Q@ã±á“.‡qŠÜ´¼°Ø ”PCt(á«yŒQ$±°hÔNý8¤¥Ë MNjÿ$þßþŲo_ƒsLIEND®B`‚openchange-2.0/apidocs/html/libmapistore/bdwn.png000066400000000000000000000002231223057412600222010ustar00rootroot00000000000000‰PNG  IHDR5åZIDATxíË € DŸP–1ñlžmÀ r±j².e è†D[ØÉ¾ÙÏÔ¼µ¦ã´Þ|陣6€Všë3´Å?Ls'(}¬>+ žKó÷¥¿ch`‚ ^׃ÞnIEND®B`‚openchange-2.0/apidocs/html/libmapistore/body_top_bg2.jpg000066400000000000000000000006541223057412600236240ustar00rootroot00000000000000ÿØÿàJFIFddÿìDuckydÿîAdobedÀÿÛ„ÿÀ–ÿÄh að¡q‘QáR’¢ð!‘1aQÿÚ ?Ô¢±Õœ|W¼ í|ua³Dbe­‚hŒ*ø VÁ&ÅrV¹´,¸^Â-~TbÁÐéÊ—=©xj䮤*ÿRb²r %7L‘ñÜŠ¶5ø¦ èªÞV¶ ÿÙopenchange-2.0/apidocs/html/libmapistore/closed.png000066400000000000000000000002041223057412600225170ustar00rootroot00000000000000‰PNG  IHDR à‘KIDATxíÝm @!†ÑGk™É7À-`&séts¦Àñþòð@åk}ª2€… P%Á_Ëþ¿N² .:0Dk¥‹Â›x" Ö›)¡xÒ5õIEND®B`‚openchange-2.0/apidocs/html/libmapistore/dir_0b045e385ae4c7fe40978fa57669068a.html000066400000000000000000000071641223057412600265410ustar00rootroot00000000000000 OpenChange mapistore library 2.0 API Documentation
mgmt Directory Reference

Files

file  mapistore_mgmt.c
 Provides mapistore management routine for administrative/services tools.
file  mapistore_mgmt.h
file  mapistore_mgmt_messages.c
 Process IPC messages received on command message queue.
file  mapistore_mgmt_send.c
 Provides mapistore management routine for sending messages/notifications from administrative/services tools to OpenChange Server/listener process.

Creative Commons License
Creative Commons Attribution icon Creative Commons Share Alike icon
This content is licensed under the Creative Commons
Attribution ShareAlike License v. 3.0:
http://creativecommons.org/licenses/by-sa/3.0/

openchange-2.0/apidocs/html/libmapistore/dir_38e8bc4c27696e2cf53047c7c774bf34.html000066400000000000000000000047621223057412600266230ustar00rootroot00000000000000 OpenChange mapistore library 2.0 API Documentation
tests Directory Reference

Files

file  mapistore_test.c
 Test mapistore implementation.

Creative Commons License
Creative Commons Attribution icon Creative Commons Share Alike icon
This content is licensed under the Creative Commons
Attribution ShareAlike License v. 3.0:
http://creativecommons.org/licenses/by-sa/3.0/

openchange-2.0/apidocs/html/libmapistore/dir_4f343f6bd7925b18a2c3c13737f093b9.html000066400000000000000000000043141223057412600265170ustar00rootroot00000000000000 OpenChange mapistore library 2.0 API Documentation
mapiproxy Directory Reference

Directories

directory  libmapistore

Creative Commons License
Creative Commons Attribution icon Creative Commons Share Alike icon
This content is licensed under the Creative Commons
Attribution ShareAlike License v. 3.0:
http://creativecommons.org/licenses/by-sa/3.0/

openchange-2.0/apidocs/html/libmapistore/dir_b0e0b4699a05b0625ab8fbc609e36268.html000066400000000000000000000136231223057412600265710ustar00rootroot00000000000000 OpenChange mapistore library 2.0 API Documentation
libmapistore Directory Reference

Directories

directory  mgmt
directory  tests

Files

file  mapistore.h
 MAPISTORE general API.
file  mapistore_backend.c
 mapistore backends management API
file  mapistore_backend_defaults.c
 Initialize default behavior for mapistore backends.
file  mapistore_errors.h
 This header provides a set of result codes for MAPISTORE function calls.
file  mapistore_indexing.c
 MAPISTORE internal indexing functions.
file  mapistore_interface.c
file  mapistore_ldb_wrap.c
file  mapistore_namedprops.c
file  mapistore_notification.c
file  mapistore_processing.c
file  mapistore_replica_mapping.c
file  mapistore_tdb_wrap.c

Creative Commons License
Creative Commons Attribution icon Creative Commons Share Alike icon
This content is licensed under the Creative Commons
Attribution ShareAlike License v. 3.0:
http://creativecommons.org/licenses/by-sa/3.0/

openchange-2.0/apidocs/html/libmapistore/doxygen.png000066400000000000000000000073031223057412600227320ustar00rootroot00000000000000‰PNG  IHDRh ;ˆØŠIDATxí]y\•Õº~45%TL Q”PE"q–Û11±]8a„w*©¨(*â" ˆzÀè`8 ¨‰¢mÅ,’òà„p$%”œBó(8k†Ü÷ýÜû6lòö»§k÷Ç÷[ÏÞß·Ö;?k½ëßÕÕÕPxÑêÏ't´ÏùÈ€zÀÇÅ3_€Q4€g@œmÿ ¾ò‰âci‰ôçÿ{ ðÇð¬ù~½Á€4:õHcÂü ðŸÁ³„ª'ÕPÆæ P7^h،♠zb„cóP¨„ 3‚† Ò}çÿO²qÁºNkÝTÛ(É?d Ç~z<’«4Óǡ؞Þv­zµÙ¦õ¬ZâdÛ,Ë6Ók±]Fz< ¾ZçƒsÕ?ìƒsUø2SÉåwê1”c`[ì—}%ѽ.Ô¼6‚BLZ˜û!F8[ ¹…×TéÛ— »Þ#gó]å:vžu?‡vèbÙR˜?wùŽŸ¾ÊÐgbÑÉÌÕ$kF~Ê;عÆ•¢ïX®?ÉèlÆÙôõà»Nʪ¼­,ìHC§gAz•ÆlÓº­gÑú ]œjÎñåM…3ÓÚæoÒ³'=‘$Ò÷f}G•ŸS_‡öèco.Êȹ :ó£ Ãds®Ù:1=¼{ƒå9?÷ý…zqÛvîÓi‰D’p¿Ë šmÙíoÛâýaÖüEqÒµwÌ}¿~{òj€ç{ôºŸFNëí[ëOq·ÇOSúXO]°>‚‚muæÄ¾e¤“5Ë{¨JÕ¯£(›´«bÂçû’ÍlÓÅ}žïú`éUÞy„ac§Á†ÔCºŠóAkl‘±y¥†ô¢ùôs÷Aø¬7ÄõôoJ±äÄ ù.¥Be. Z¬Ð×ÇÈöå¹­ù'Ù-PëìŠyF.ž‚žÝÚ€lp&.êˆð•jò7’re’z19»ã§HGíø%œüq°ïüz׈c¬_k_")ŸHJnÐÑ~ˆÐÖ˜á´äÕ5 µÁq€ÿ5#¸·îà¶+9T‘‚ ðŽ÷Rܸrz“Ï´Ì =Ï…{ðáO£Èf ¡Íwg|Ž’Ü/¢Þ$÷¯¢ëðúÀ;¿à¨Ö™âÒÆ­]¯ÜW"Þ/< ‡÷DÏà°½üB}çyIEc^—ƒ=[V“Ýh²ëMä$l];Kû®¸ýr¦È*Åò ÿtÒõ$]•MŸ÷´;×I€1èó!‚œõ¸M õ¨(fÌæ<ÁÎÎò5~z¿ù¶ž mÌêÕ >–âÚ©âëˆIÎÞçz;ãu[i·eç^ÆÜÙÓ³NÞëF6B\}7†»+üŽÓ,Ã'a ½˜-yHY¿,‘^—ñfú~ß?Hcø¸…¸ñó{Z+4\såƒû·¯Ù·nߣð«íFÆ¡sغëû§D¾?ò<–Ævkx0ÅM±ælذÁIÓxÿd”žÜÉ÷EE»AªM«g*È£YEí7Û™^[uíý®v[wGå†=Ed¼n×¶ÆæÖÅl¡'¨pGÚk+‹æ¢À¬¨C8ªâš2 dz3H£ß ¡¨BÒûSÃÅù[wŘ ~xpçútÁæmö¤Å£¥iQæ­‰AB1ÉfÙ‰›4u¹ïìIÒ]Ë6äò%ÿ†† 1t.’NJph¬zÌ ÎR1Ž"3-"¸‡‹&ìó°1âüžìó[:‡ï„¼‘……N m–“W0®_èÜœ ×õ6ùò&»)Æìꦬýæ}¬ñ~»{múù]z½£M•ºP~^Îá:eQTÙ_*7ÕÄ9É8—·Ëï 3°¶47E•î¿u÷“SÉ»U¯ _ NíºôW¬e¸ÄNÓ|»;™¿;ŒæÅd"ȉôøòÞµõï¾®½"èÄ´ÖMM+bYµ‘_ÉæEÝüÎ]P»¹XKÐI½Þ¥oE<_¹(„EP±Œ|mÇÁ¡‘Ý,ŠÓ©ººZ±Îߺ§×kÝ,kÍMš`Äø…jzeU»æ ™Át3ÓÀ½˜6—ÒöùË·r¨¹Ñ}““wö:Χùë¼ ¿|‚TܵÉQˆKßç_ÁâÀ™œ”pÑÐóໃ¼Ydâ0!®àa –øöçW$ÃÁ‘Á$/\¬$ð 2ÞímÞLH‹Ÿ èd£HVÜ,:ò½»RÍZšJ­a„z*>‹_…NT(ù‚^SVF­U¹8ñEþôñ܈óùnd;«®8™\C]ø=Èêm¬Æ:‚´ÆbãDd=Áãßžˆ‹UU5O‹|]þð®Pèêv‰á\]2ßìÿ"yÈ[ïyʧz£g{Y«{„Ùø5©ÿ;w{N3é­nâĨw§Á¢ÍK¢Ý­ûÏ29Id¿’ì y)ìPÞò8ŒÅ©¯‰±@mPÔñwjl,6 áhWÕ˜d öà uõmÁp®.™á£Ç…twöR x­BδYcŒxg*vo  yò‘•“[¬?ÜVœ˜0ÒN¡O난~Žó’¯·h#´Hkýœ±8kÓß^Àq@]àÓ“ø,56´¯÷Í-κU»n…[>]@nîøÏœp›[œ6# €4tën¯:ŽÒþ}…—8äT9_žY$/´G’K™©ù†•(óÑ’Mø©`ŸÉdѺ;ùO‹B Ó&P{qöhJÉ+Úé–§¦l2«MïöÝ_1ÑÓ«’t¸½±l€ëØya ¦ô©«®½ÆL^¬žêñš¸ùy.¾Û½Š[ u/]½‹iS}øN>²e1™q‡jfÚ&¢©iT\=kÏ›ÀXô-.84V5ðu!TE˜ þ.ŒOH´¶4—zwTr.ï‰¦Ë xõµ·œÖ„HÆù£žÈHùg Ñhñ’T$ßyq¸zþ¨p¿´ë< q•ró÷š‰wÿÍÑð–I]´–æI²é²˜sÂ"×:Õ–bÕ¦“ÈÙL6¢9VÊÓWž§<æ;”3?ý©Mê3AV#µ±ËÞ¯‘ž K£UrÝ9!›qát¦H£Ù+6ÇV…/TS^pÃùqgLP'Ú5E ‚–ÀÞºîÄ Ën"2|Ÿ;®W»Îý"Ö¬TwÖâµtúŽO'› á+W Ã+¦âZÌ–<ÕÆ&nOÝ,IŠ£06.ÁZ.Çñúøh*INÚ’Oe½ÉgBXÐÔZóäøä9èü“hÒíDSš¥¡Ê µA¯/Ôc¸ö“`A§¯"zå|‘ €ÅŸ¨ú;HÍ#‚Î|%ÄOˆƒ«OàÌÉÐÜD ž mÜðâc–ƤÉÂqm¶uË&~÷núÒË £ÇÏ€ZÕj =«_n[‡‡÷nN§ÏÝ$_¾bE˜‚€Õ)ù8¾?6‘lú“ÍÙæÖ}#bW( œ³d-®•p&¡ý’œÖa”"9öõņÐ$’Ú›AÜ!ä;ÐÑõè{~á¹8‘ÛÞ£1ÛÓÉ0ž`²#´kÒuäNÅÖ Q¹bhæ ”8ûÓMáŽa›•¿”w±h²¢®qŠæ°(bK ‚’Z¾Ò%ÐÆémáãÖË(Éý‚ÛJ)@> þ›7% ï{y Á“¾ÆÒîohfòô>{pÿ.­_Î%±ÉèägëlZØ\B2B #™¸ÚüÒºp‚hÝšü®[¥Ü<‹#SpñÌA7’ãØHƒt4:Ÿ|g¨tÓL¶*($Æ©»ì…®ù’ó÷$;b›ÔÙ`=¶£¦M„MÌÄ5ò«·Ç¾“H·ÌH.¼žHeAîº5}r­dõ¨±)ÀT};€Q5iÖ2…O0ü…0óñÃ;óæ,Š´²µ냔}g‘£]‹7å9ˆà©_{üèîêžC>úhê{Ž .ÈìðIIð€?[Kswz6Òuíý¬;µ€ç§OåâJÉa˶zv°éd† ¤µâ‚l´é舊«Åüy¾c÷ÁèÖÍ'ràúÅ™TWÕôÓ°¡L €|ʽŒ¼ì­høBã ÝTëî'ò]Kø£ìâÏ(=¹Kx €¿ LÌ,Pý¤Êµu‡¹…׈ §Å¾÷à1Ý«Äý;¿pGDäxZYÛ kfæ6¸ùóæ7®œ®þ6·ÕoÚ¾ÔH~ò®Þ¸â 8Uø“p<ºw3¡a£ÏÑ’‘3èÏ"€bˆ-ÎܺÏ_ªÅ]+ËM©zü°s“f-êçhÇãÑýÊãôÿ5}ZQNb{Ó?å%ÿ\SUõعIÓæ}~}p[œoÔÄ„êÐMMZáNÅå@>Œ„²á6(?¡Åé âK½+ü?À%ÝÝ·/Ç1‚9áUø?B)”ÕèâÞlÈÒêÏ @=àùÄÞžk­®ÅIEND®B`‚openchange-2.0/apidocs/html/libmapistore/dynsections.js000066400000000000000000000041341223057412600234460ustar00rootroot00000000000000function toggleVisibility(linkObj) { var base = $(linkObj).attr('id'); var summary = $('#'+base+'-summary'); var content = $('#'+base+'-content'); var trigger = $('#'+base+'-trigger'); var src=$(trigger).attr('src'); if (content.is(':visible')===true) { content.hide(); summary.show(); $(linkObj).addClass('closed').removeClass('opened'); $(trigger).attr('src',src.substring(0,src.length-8)+'closed.png'); } else { content.show(); summary.hide(); $(linkObj).removeClass('closed').addClass('opened'); $(trigger).attr('src',src.substring(0,src.length-10)+'open.png'); } return false; } function updateStripes() { $('table.directory tr'). removeClass('even').filter(':visible:even').addClass('even'); } function toggleLevel(level) { $('table.directory tr').each(function(){ var l = this.id.split('_').length-1; var i = $('#img'+this.id.substring(3)); var a = $('#arr'+this.id.substring(3)); if (l OpenChange mapistore library 2.0 API Documentation
File List
Here is a list of all documented files with brief descriptions:
[detail level 1234]
\-mapiproxy
 \-libmapistore
  o-mgmt
  |o*mapistore_mgmt.cProvides mapistore management routine for administrative/services tools
  |o*mapistore_mgmt_messages.cProcess IPC messages received on command message queue
  |\*mapistore_mgmt_send.cProvides mapistore management routine for sending messages/notifications from administrative/services tools to OpenChange Server/listener process
  o-tests
  |\*mapistore_test.cTest mapistore implementation
  o*mapistore.hMAPISTORE general API
  o*mapistore_backend.cMapistore backends management API
  o*mapistore_backend_defaults.cInitialize default behavior for mapistore backends
  o*mapistore_errors.hThis header provides a set of result codes for MAPISTORE function calls
  \*mapistore_indexing.cMAPISTORE internal indexing functions

Creative Commons License
Creative Commons Attribution icon Creative Commons Share Alike icon
This content is licensed under the Creative Commons
Attribution ShareAlike License v. 3.0:
http://creativecommons.org/licenses/by-sa/3.0/

openchange-2.0/apidocs/html/libmapistore/ftv2blank.png000066400000000000000000000001261223057412600231420ustar00rootroot00000000000000‰PNG  IHDRɪ|IDATxíݱðøScOx@ –¨y}IEND®B`‚openchange-2.0/apidocs/html/libmapistore/ftv2cl.png000066400000000000000000000007051223057412600224540ustar00rootroot00000000000000‰PNG  IHDRÚ}\ˆŒIDATxíÝ;H#AÇño4Љႇ œ„K‰‡‚á ’ê,m„ØØ vÚžJ°²¹ÚÎþî‚§ XY ÅB|dr³cvo—˜Ä°Ý ù0Ã’™3ÿͤõ”Ëe×´¸Éõ¯1XÞ8Œ‰nQˆ88ööÖ§3*rbñ¯¢û-$¨‚þ´˜“P1Žè@Z…-# Ïú01ÑÏÎêÄ1HkKŸ w¶O@¥ªÈóñ!f§ñu˜åác÷;’sá×Bý[E´Añ±—Í\ß>°ùý¿ÏËÊÂ]–P€zØf| Íñ¯“+Ù´gð5…b  i5ümM³œ_æÍq,ÒcŽõèoÓd´ !¶äò©ô•,ôðÀ{¹¨µYß,€zTÍ8H]𤕘ï7¼»/òó8ËQæ !F€~6ãá?Y ÀA@ŨÁ.@ƒ¶TäÄYïŠËë±r‘µ8Ð*·é>€Šçÿ?€×þŸe[6«xÂIEND®B`‚openchange-2.0/apidocs/html/libmapistore/ftv2doc.png000066400000000000000000000013521223057412600226220ustar00rootroot00000000000000‰PNG  IHDRÚ}\ˆ±IDATxíMOS[…Ÿžsúa?-XZ(PD4‚ AWbu`b 77wäHFÆCËÔÂÿà/`vo„ˆAPòq‹P @ ­ûÝè980 îà¤+»§Ýy×^ïZï9SW¹\83g‰3'°Nâçl¹¸_b¯p ïåûÆVÜÖ¡€Ÿ×"¬Ö†X€d]Ðà3“ÉÃÄÌ™xŸ ßMàœ[<çSPkvc—hÈ'…™˜^Åm™hØ7 `Û™¦ èÀåráq›‘œ¾!daeKŸþÆÕ˜:Ì*³_דâèi?I–eP*B7Ÿ¿åô!¹Ýgr6Ër6oKbëþãðôrI”ËTˆüªŒ¨xóö=›ù¢&‰(e+ßóÄkýÇ`ëÁÜb.“¸ÐW×w0¥°jÑzN™¬|©WEãµ¢a¯6[öX†AkÓù*/œ¨‰€ÉY­ ÿV’§–u²jÂ>1W *½·°PGŽzÿ¨/Eg{ ŸÇâaoŠÁVú:è¿™¤1$ôR§W,–ªà¨@ŠË56¾ÀÔÜ-¾,mê¸Î/æè¹– òr5¥T*S(Vf8ö9u’ Õ£w›ùóa=Í<{Ò¡UŒ÷r¯+ÉådDÏF$è°…£é¿`zþ»ÎúöN‘µÜ®0Q3£~_^Ëóâ¯N=ˆvpTà±LžT}ˆîkq†Òm<¼ÎÓ?Zh¿X£ï_þÝ¥[)ƒ `gêÃa_Ô*äÔ2`'=õ´Fÿ2EâÁPú ÷»›l=8‹Wv°%THqÉ¿<"¤ïG¾ÆxH{#ÆÖ«aÔJÕÞ‡—m‹„ çñKsÿàñVŠØ¡°·MâÒ^ TÁ– Ý›r¥ß½ømüÿ_™?ªWİ÷#uIEND®B`‚openchange-2.0/apidocs/html/libmapistore/ftv2folderclosed.png000066400000000000000000000011501223057412600245160ustar00rootroot00000000000000‰PNG  IHDRÚ}\ˆ/IDATxí]MOÔ@~ÚúuØlp]ö¿#›Å]PYECˆ\9ù¼yÑß`ÖÄÿàÿÀÉxóâ¢C &=qÐÄ£—vZçv¶3m؃‡vžLûNç}Þ÷}Þ½ZA@n° OäNp ’xóþK°ññ€xÜj”°8sÑ€“ “€œ_¼[Âíæ§ïD'‚•yye+ø¼û 7#rNŸlïük* ¾0Ь_d«_(àñÖ±àôz=ñxõv§÷h©‰z¹€šØP-äóä’̪uý¼$»\DãJc—B4¯ãÝÖ.:£Ï-ÑÏß}µŠLEíºþ #—ûáºÀÏgN;BŠ€6ïýñ䬜…ö@’Ðåñp&™h>p9¤™EEά¨ÎÊ‘" u¥n€$R"?{¹<˜…ë…%PNtâ$‰ß¶±úá+^<é"§2 ªDq”q´\¬«Ò™a–Œ‘©Aÿ€"Ôµ ™êŸèP£}#Eàz{û.8i îp³ê(ADwD¦E<ê¬cE¦$ HdÊÄ ”.:Ù GŽ-`ŒL‚ý¾'¢‰Ä<¤CIª½;ÙÇTZd±i};>èôß‚z×;K×§8t ¤Ž q”:uvÿv•Ý›¬²ÙvEân{„M·FXg¼ÌfZÖ¨°¹‰*›ßÌß©±ù©:›j–YqèÜë#3çÏSøWøÿÿÑr'ø Ôùù‚ ©¡IEND®B`‚openchange-2.0/apidocs/html/libmapistore/ftv2folderopen.png000066400000000000000000000011251223057412600242100ustar00rootroot00000000000000‰PNG  IHDRÚ}\ˆIDATxí]?oÓPÿ9iš4i°;ii“¶‰ZЉ‘‰ÀÀ7`bèÔÙ¬Øù,HìU'ô$*Tµ]‚T¡DPÚÄ6wÏ}‰;¡C; a¿ÓߟûÝïîž¼jAÀ­InSþ}€9H“ÓŽ|?íÁ÷ =_ÊÆŠ­†¥Àue*;¯YEäsYäæB¢Ÿ¿þÄ—£sÙ½½ÙŒ† É«›©ÀYÇq !GÇ¿v̇¹ÑØ®š °Œ‚ÔF¹}q¥b]÷7í·0)Úd›¾ÿð-èº}Pfä£ÖY{4™ÑÂ@}úæôñ2ÛüÔ—ñúåNŒI‚ÁǃcçÁº%£¬UаI³mc±ô˜å¼ÔÆüÈ>é¸xþt9Æ$µý OæVE*õU´Ì‚ç#ž×ˆ•ïûr@l$øPÿrHaaÇ¥ ²›dZ®rè‘ãqI„o¼øT\Ž,tªj2FAxv-LŸp׌p TÄI/ \¥sfí½; jViTƒèú¤o^cpÅü¼ûû»Ïb]”€¢¤<†aþÕœ²“ßÓ˜y“£§9:Œîù+À³€ñà,E žf³6éNˆÄE£KU}Ü^;¶ØnZ¢uß­US4— ѬëbížN¶.Úk¦ØjTÄöº%µªâ i¯VÄÊÝò§™ Èù¸)ùÿG€™òºJ@T x”IEND®B`‚openchange-2.0/apidocs/html/libmapistore/ftv2lastnode.png000066400000000000000000000001261223057412600236640ustar00rootroot00000000000000‰PNG  IHDRɪ|IDATxíݱðøScOx@ –¨y}IEND®B`‚openchange-2.0/apidocs/html/libmapistore/ftv2link.png000066400000000000000000000013521223057412600230120ustar00rootroot00000000000000‰PNG  IHDRÚ}\ˆ±IDATxíMOS[…Ÿžsúa?-XZ(PD4‚ AWbu`b 77wäHFÆCËÔÂÿà/`vo„ˆAPòq‹P @ ­ûÝè980 îà¤+»§Ýy×^ïZï9SW¹\83g‰3'°Nâçl¹¸_b¯p ïåûÆVÜÖ¡€Ÿ×"¬Ö†X€d]Ðà3“ÉÃÄÌ™xŸ ßMàœ[<çSPkvc—hÈ'…™˜^Åm™hØ7 `Û™¦ èÀåráq›‘œ¾!daeKŸþÆÕ˜:Ì*³_דâèi?I–eP*B7Ÿ¿åô!¹Ýgr6Ër6oKbëþãðôrI”ËTˆüªŒ¨xóö=›ù¢&‰(e+ßóÄkýÇ`ëÁÜb.“¸ÐW×w0¥°jÑzN™¬|©WEãµ¢a¯6[öX†AkÓù*/œ¨‰€ÉY­ ÿV’§–u²jÂ>1W *½·°PGŽzÿ¨/Eg{ ŸÇâaoŠÁVú:è¿™¤1$ôR§W,–ªà¨@ŠË56¾ÀÔÜ-¾,mê¸Î/æè¹– òr5¥T*S(Vf8ö9u’ Õ£w›ùóa=Í<{Ò¡UŒ÷r¯+ÉådDÏF$è°…£é¿`zþ»ÎúöN‘µÜ®0Q3£~_^Ëóâ¯N=ˆvpTà±LžT}ˆîkq†Òm<¼ÎÓ?Zh¿X£ï_þÝ¥[)ƒ `gêÃa_Ô*äÔ2`'=õ´Fÿ2EâÁPú ÷»›l=8‹Wv°%THqÉ¿<"¤ïG¾ÆxH{#ÆÖ«aÔJÕÞ‡—m‹„ çñKsÿàñVŠØ¡°·MâÒ^ TÁ– Ý›r¥ß½ømüÿ_™?ªWİ÷#uIEND®B`‚openchange-2.0/apidocs/html/libmapistore/ftv2mlastnode.png000066400000000000000000000003661223057412600240470ustar00rootroot00000000000000‰PNG  IHDRɪ|½IDATxíÝ!NAÅñ¤‡à\ ÷à Um@`Ô5iÒ`ëh ‚ÅW7] b§ÝˆŠ&oföÍd¾YÔ4 üšcø ‡€´‹Åòù3v=¼]†§µ\B… I¿‹=B·™B¡®;¸k´µ W°ÍN@vyÍÑÖ4ãß÷]ÈâYìã§|M}]ÔÚx6a }ôdׇØYüú¨>¤||5?Ó>|žB"¡î'¡IEND®B`‚openchange-2.0/apidocs/html/libmapistore/ftv2mnode.png000066400000000000000000000003661223057412600231630ustar00rootroot00000000000000‰PNG  IHDRɪ|½IDATxíÝ!NAÅñ¤‡à\ ÷à Um@`Ô5iÒ`ëh ‚ÅW7] b§ÝˆŠ&oföÍd¾YÔ4 üšcø ‡€´‹Åòù3v=¼]†§µ\B… I¿‹=B·™B¡®;¸k´µ W°ÍN@vyÍÑÖ4ãß÷]ÈâYìã§|M}]ÔÚx6a }ôdׇØYüú¨>¤||5?Ó>|žB"¡î'¡IEND®B`‚openchange-2.0/apidocs/html/libmapistore/ftv2mo.png000066400000000000000000000006231223057412600224700ustar00rootroot00000000000000‰PNG  IHDRÚ}\ˆZIDATxí1Kû@ÆiƒØB…Ò¡(h¬"EÄI'ÁoàªèÚ©ßÀáâä 8ùçR-‚â B«TPˆï]z¥B’3 _Þã’»ç}ŸË]VÇ÷}€ÌÈdIæ®i쟯JØ–b¸šÍÃõ+º™|KÂ…°,[Pï\ʘMÆ¢#€ä…F`JݤìÛk³úA±àþè?ØY4ck6"¹Z)ê¸0SHM¨@ï㋺WÖmo¼4èHJ¨Àÿö+…QobŒút ¤ú’*Ð~êè8_+3Y-ñðÜå½÷ ˜PwA¶+^ý}ºì£+xìhÏ•MAE]€TD~EÞߴ^R)`ÖAùŸÏ9©pÔq-Û¾õÛ3tÝÊÆ›ˆÃTÐHÈ)€ ½Š’ICªxëd#1ôú§é€ m@Vüý?Zæßgo_½3-³\IEND®B`‚openchange-2.0/apidocs/html/libmapistore/ftv2node.png000066400000000000000000000001261223057412600230000ustar00rootroot00000000000000‰PNG  IHDRɪ|IDATxíݱðøScOx@ –¨y}IEND®B`‚openchange-2.0/apidocs/html/libmapistore/ftv2ns.png000066400000000000000000000006041223057412600224740ustar00rootroot00000000000000‰PNG  IHDRÚ}\ˆKIDATxíÝ1K1Àñ­ž ØG•â‚n‚Šà ‚âælÁE¿€‹“ (nºêââêäࢋƒÐMAá@°‹ µât¾ÄK¡à%Ü•Û ý]BIïå%áuÍ…a™€,e × v¯ç¥«ˆi‹º¨Õö–î\tòòuénÄ0ã æÜÉoV\Ì$G.&@Y=ÆË%$um·¢ûÛ6–'Úß«9Qó\bÙ)²º0Ðë-Zœ¥TèHÍ`pÀcsm µö5:>Áë‡Þ¦I µØ ‚F‹Çà]» ›jg—ìoÏáõ©[ œõ š­onë €Ô¬¨vqõ„?\Ðç”  6»øüÒTe ÃÉéŸeç ÀÅlQ ¡c”€ª¬ü3*d€ÅWTMÏ\rÿÿh6™ø1±F ‹°fžIEND®B`‚openchange-2.0/apidocs/html/libmapistore/ftv2plastnode.png000066400000000000000000000003451223057412600240470ustar00rootroot00000000000000‰PNG  IHDRɪ|¬IDATxí=QF‘Ø¥D«ÔkÄ:‰F©PK؃=V@§Õ³ Õ8SHxñÌ0bnrróŠ{ò½¿¾’$ ÀÏTŠP  ö¼X¬OÛd6êìòð"°²S´±O¥B€(¡àQé)š+YĈ ÒªËRÉÐ>VtÉsˆm9(ê„䜥k‚-@ȧ-Ü$ó b Ò[he ¿Kp-ôl|CùÿApRG'rÍ­aIEND®B`‚openchange-2.0/apidocs/html/libmapistore/ftv2pnode.png000066400000000000000000000003451223057412600231630ustar00rootroot00000000000000‰PNG  IHDRɪ|¬IDATxí=QF‘Ø¥D«ÔkÄ:‰F©PK؃=V@§Õ³ Õ8SHxñÌ0bnrróŠ{ò½¿¾’$ ÀÏTŠP  ö¼X¬OÛd6êìòð"°²S´±O¥B€(¡àQé)š+YĈ ÒªËRÉÐ>VtÉsˆm9(ê„䜥k‚-@ȧ-Ü$ó b Ò[he ¿Kp-ôl|CùÿApRG'rÍ­aIEND®B`‚openchange-2.0/apidocs/html/libmapistore/ftv2splitbar.png000066400000000000000000000004721223057412600236770ustar00rootroot00000000000000‰PNG  IHDRM¸¿IDATxíÝ¡JCa‡ñç(˜ ëƒ%±Ø4 b±È˜Í¶3˜v^Á±˜…ãó–ŽELƒõ…¥•³ ,ÿb;íç{Ã/¼ðÞÀaYÕ¯åóøq:¼º¹›\òIIIIIIIIIIIIIIIIII-Òçl¹›«õ抢è_t/Ï»ã£ÑíYQVõðêäíã÷´×ùY¬Úÿµ§¦ivók¾_íåýÛ£I@$I@$I@$I@$I@$I@$I@$I@$I@$I@$I@$I@$I@$I@$I@$I@$I@$I@$ýC[Vì=ü[„fÆIEND®B`‚openchange-2.0/apidocs/html/libmapistore/ftv2vertline.png000066400000000000000000000001261223057412600237030ustar00rootroot00000000000000‰PNG  IHDRɪ|IDATxíݱðøScOx@ –¨y}IEND®B`‚openchange-2.0/apidocs/html/libmapistore/globals.html000066400000000000000000000404621223057412600230630ustar00rootroot00000000000000 OpenChange mapistore library 2.0 API Documentation
Here is a list of all documented functions, variables, defines, enums, and typedefs with links to the documentation:

- m -


Creative Commons License
Creative Commons Attribution icon Creative Commons Share Alike icon
This content is licensed under the Creative Commons
Attribution ShareAlike License v. 3.0:
http://creativecommons.org/licenses/by-sa/3.0/

openchange-2.0/apidocs/html/libmapistore/globals_enum.html000066400000000000000000000044351223057412600241070ustar00rootroot00000000000000 OpenChange mapistore library 2.0 API Documentation

Creative Commons License
Creative Commons Attribution icon Creative Commons Share Alike icon
This content is licensed under the Creative Commons
Attribution ShareAlike License v. 3.0:
http://creativecommons.org/licenses/by-sa/3.0/

openchange-2.0/apidocs/html/libmapistore/globals_eval.html000066400000000000000000000136411223057412600240710ustar00rootroot00000000000000 OpenChange mapistore library 2.0 API Documentation
 

Creative Commons License
Creative Commons Attribution icon Creative Commons Share Alike icon
This content is licensed under the Creative Commons
Attribution ShareAlike License v. 3.0:
http://creativecommons.org/licenses/by-sa/3.0/

openchange-2.0/apidocs/html/libmapistore/globals_func.html000066400000000000000000000304331223057412600240730ustar00rootroot00000000000000 OpenChange mapistore library 2.0 API Documentation
 

- m -


Creative Commons License
Creative Commons Attribution icon Creative Commons Share Alike icon
This content is licensed under the Creative Commons
Attribution ShareAlike License v. 3.0:
http://creativecommons.org/licenses/by-sa/3.0/

openchange-2.0/apidocs/html/libmapistore/header.jpg000066400000000000000000002264161223057412600225110ustar00rootroot00000000000000ÿØÿàJFIFddÿìDuckydÿîAdobedÀÿÛ„ÿÀÍ4ÿÄû     a!Qqð1A‘¡¢d ±"Ô%U•ÕV–Ö”WÑñ#EÁá2DT·BR3C$uµ&g(8x’S£³4…6¦hbc¤´Å†G§)   !1AQq"“ÓT”ÔUa2‘¡Ò#³´u6±BRVÁÑb²3$v'7ðár&ñ‚’¢CS%Âsƒ£4Dct¤5ef(ÿÚ ?ýAîÊåSñMÁÙB8v)¸;(GÅ7eáØ¦àì¡;Ü”#‡b›ƒ²„pìSpvPŽŠnÊñMÁÙB8v)¸;(GÅ7eáØ¦àì¡;Ü”#‡b›ƒ²„pìSpvPŽŠnÊñMÁÙB8v)¸;(GÅ7eáØ¦àì¡;Ü”#‡b›ƒ²„pìSpvPŽŠnÊñMÁÙB8v)¸;(GÅ7eáØ¦àì¡;Ü”#‡b›ƒ²„pìSpvPŽŠnÊñMÁÙB8v)¸;(GÅ7eáØ¦àì¡;Ü”#‡b›ƒ²„pìSpvPŽŠnÊñMÁÙB8v)¸;(GÅ7eáØ¦àì¡;Ü”#‡b›ƒ²„pìSpvPŽŠnÊñMÁÙB8v)¸;(GÅ7eáØ¦àì¡;Ü”#‡b›ƒ²„pìSpvPŽŠnÊñMÁÙB8v)¸;(GÅ7eáØ¦àì¡;Ü”#‡b›ƒ²„pìSpvPŽŠnÊñMÁÙB8v)¸;(GÅ7eáØ¦àì¡;Ü”#‡b›ƒ²„pìSpvPŽŠnÊñMÁÙB8v)¸;(GÅ7eáØ¦àì¡;Ü”#‡b›ƒ²„pìSpvPŽŠnÊñMÁÙB8v)¸;(GÅ7eáØ¦àì¡;Ü”#‡b›ƒ²„pìSpvPŽŠnÊñMÁÙB8v)¸;(GÅ7eáØ¦àì¡;Ü”#‡b›ƒ²„pìSpvPŽŠnÊñMÁÙB8v)¸;(GÅ7eáØ¦àì¡;Ü”#‡b›ƒ²„pì__gÓâ£êE~•²O\VݪÏãžà…·#÷Á?Nž•cÏ´Ôô™Û£¾!àÞÖ²x¬.c;s÷<%Íåå+ÝÁ’¾ºckO¦‹£Êcq0}ç)sµµi®W¶6׳SÈpo× 'ü߯Wí¬?þ«[7ð¿™áÜï¨]ù¥‚øócûëëvþqkúß„ÿ›øÇñå­õ¥?á2ÿùßP»óHøócûçëpyůëvþoc/Ç–¿Ö”¿†Ëÿç=BëÍ#ãÍïœW­Áçýn¿ÍÜeøî×úÒá‡2¿Ã¹ÏPºóIüy²=óŠõ¸<â×õ· 7qŸã»_ëJ?†Êÿç=BëÍ#㽑ïœW­ÁçýlÂÿÍÌiøê×úÒ—ðÇ™?áÜç¨]y¤|w²=óŠõ¸<â×õ¯ ÿ6ñ§ã«cë:?†<Êÿç=BëÍ#㽑ïœW­Áç¿­XcùµÛYÑü1æOø{9ê^iì|â½n8§ëNþlãoÇ6ÏÖt ¹“þÎzךGÇ{#ß8¯[ƒÎ-Z0×óg~8¶~³£øeÌðösÔn¼Ò>:Ù>ùÅzÜqkúφÿ›ßñųõ/áŸ2?ÃÙ¿QºóHøëdûçëpyÅ?Y°à÷²¾8üom}gGðË™áìߨÝy¤þ:Ù>ùÅzÔqkú͇šøãñ½µõ•Ã>d‡³~£uæ‘ñÖÉ÷Î+Ö óŠ~²áßæ¶9ümm}eGðϘÿáìߨÝy¤|u²}óŠõ¨<â×õ“5q×ãkoë*_ÃNcÿ‡ó~£uæ‘ñÎÊ÷Æ+Ö ó‹_ÖiìÏ{âýj8µýVÅÌ›ñtÃéy…îÏ©\ù´|o³=ï‹õ¨<⟪¸°{Ù&Äü]ðú?‡<Â÷gÔ®|Ú>6Ù¾÷ÆzÔqkú©‹™/âØ‡Ñü9æ¸s>¥sæÑñ¶Í÷¾3Ö ó‹_ÕL[üDZÀü>á×0}Ùõ+Ÿ6ŸÆÛ7ÞøÏZƒÎ)ú§‹¿˜ö7âȇÑü:æ¸s>¥sæÑñ¶Í÷¾3Ö ó‹_Õ,_üƱ¿A|:—ðï˜âÌz•Ï›GÆÛ7ÞøÏZƒÎ-Tq€÷²-Ž?þë‚øuþ`{‹1êW>mìß{ã=j8§ê†1þbYŠà¾Gðï˜âÌz•Ï›GÆ»;ÞøÏZƒÎ-Sñ—óÈüUðê?‡{ÿÜYR¹óhø×g{ßëPyÅ?Sñ—óÉüUðê_ÃÍÿî,Ç©\ù´þ5ÙÞöÆzÌqkúŒÿ˜VWâ˜?‡Qü<ßþâÌzÏ›GÆ»;ÞØÏYƒÎ-Sq ÷²•ø¦á´w÷¸³§sæÑñ®Î÷¶3Ö`óŠ~¦c_æ —ø¢á´w÷¸³§sæÑñ¦Î÷¶3Öaó‹_Ô¼müÀ²ÿB|6áîþ÷cÔî|Ú>4ÙþöÆzÌ>qOÔ¬müÀ³?Â|6—ð÷{/êw>mlÿ{c=fËZþ¤ã¿öoâx_†Ñü>ß¾ãËúÏ›GÆ›?ÞØÏY‡òÔýIǬßÄп £ø}¿}Ç—õ;Ÿ66½±¾³å­R1ÏßÛ;ñ4/Ã(þoßqåýNçÍ£ãMŸïlo¬Ãùk_Ô|s÷öÎüK ðÊ_Ãýûî<¿©Üù´þ3ÙþöÆúÌ?–§ê6:ûùgþ%†øeÃýùî<¿©Üy´|g´=íõ˜-kúŽþýÙÿ‰a¾Gðÿ~{“/êwmí{c}fËSõýû´?Cü2€7ß¹2þ§qæÑñžÐ÷¶7Öaüµ¯ê&<ûõh~$‡øe/€7ß¹2Þ§qæÑñžÐ÷®7Öaüµ?Pñïß«Gñ?Ã)ü¾ýÉ—õ;6Œö‡½q¾³å­Pñ÷ß›GñGÂé|¾ýÉ–õ;6Œ¶‡½q¾³å©ú…¾üZ_ˆâ>GÀ;ïÜ™oS¸óiüe´}ëõ˜-kúƒþüZ_ˆ¢>GÀ;ëÜ™oS¸ói|e´}ëõ˜-OÔ÷ÞÓüEðº_ï¯re½Rãͧñ–Ñ÷®7Öaüµ¯ê÷ÚÓüCðº>ß>åËz¥Ç›GÆ[GÞ¸ßY‡òÔû`ýöµ?Äü.€·×¹2Þ©qæÑñ–Ñ÷®7Öaüµ¯Ûëï­©ø‚'át|¾}Ë–õK6Œv½q¾³å©öúÂûëjþ ‰øUoŸrå½RãÍ£ã£ï\o¬Ãùk_·¶ßKWñW¨ø |û—-ê—mízã}fËSíå‡÷ÒÖú~+áT¾ßåÊú¥Ç›GÆ;KÞ¸ïY‡òÖ¿o,?¾–·Óñ_ £à=ñî\¯ª\y´|c´½ëŽõ˜-O·v'ß;_éø¯…Qð&ø÷.WÕ.<Ú>1Ú^õÇzÌ?–µûwbýòµþŸ‹øUïrå}RãͧñŽÒ÷®;Öaüµ>ÝX¿|­§¢þGÀ{ãܹ_T¸óhøÇi{×ë0þZŸn¬o¾6ÇÓÑ £àMñî\¯ª\y´|a´½ëŽõ˜-köæÆûãl}=ðª>ÞþåÊú¥Ç›GÆOÞ˜ïY‡òÔûqcýð¶~ŒøM/7¿¹²¾©qæÑñ†Ò÷¦;Öaüµ¯Û‹ï…³ôìgÂhø{û›+ê—mm?zc½fËSíÅ‘÷ÂÙúv3á4| ½ýÍ•õK6Œ6Ÿ½1Þ³å©öÞÈûßm}9ðš>ÞÞæÊú¥Ç›GÆOÞ˜ïY‡òÔûodýï¶¾œŒøMïose}Rãͣ㠧ïLw¬Ãùk_¶ÖOÞëkéÈÏ„Ñð.÷÷6WÕ.<Ú>/Ú~ôÇzÄ?–§Ûk+ïu·ôÜoÂhø{{›+ê—mm?zc½fËZýµ²¾÷[MÆü&w·¹²¾©qæÑñ~Ó÷¦;Ö!üµ>ÚÙ_{m¿¦ã~Kàmíîl¯ª\y´þ/Ú~ôÇzÄ?–§Û[/ïm¹ôÜoÂhø{{›)ê—m/Œ6Ÿ½1Þ±å©öÒËûÛn}7ðš>ÞÞæÊz¥Ç›GÆOÞ˜ïY‡òÔûieýí·>›øMoose=Rãͣ㠧ïLw¬Ãùj}´²þöÛŸMÆü&··¹²ž©qæÑñ†Ó÷¦;Öaüµ>ÚY{mϦã~GÀÛÛÜÙOT¸óhøÃiûÓë0þZŸm,¿½¶çÓq¿ £àmíîl§ª\y´|a´ýéŽõ˜-O¶–_ÞÛsé¸ß„Ñð6ö÷6SÕ.<Ú>0Ú~ôÇzÌ?–§ÛK/ïm¹ôÜoÂhø{{›)ê—mm?zc½fËSí¥—÷¶Üún7á4| ½½Í”õK6Œ6Ÿ½1Þ³å©öÒËûÛn}7ðš>ÞÞæÊz¥Ç›GÆOÞ˜ïY‡òÔûieýí·>›øMoose=Rãͣ㠧ïLw¬Ãùj}´²þöÛŸMÆü&··¹²ž©qæÑñ†Ó÷¦;Öaüµ>ÚY{mϦã~GÀÛÛÜÙOT¸óhøÃiûÓë0þZŸm,¿½¶çÓq¿ £àmíîl§ª\y´|a´ýéŽõ˜-O¶–_ÞÛsé¸ß„Ñð6ö÷6SÕ.<Ú>0Ú~ôÇzÌ?–§ÛK/ïm¹ôÜoÂhø{{›)ê—mm?zc½fËSí¥—÷¶Üún7á4| ½½Í”õK6Œ6Ÿ½1Þ³å©öÒËûÛn}7ðš>ÞÞæÊz¥Ç›GÆOÞ˜ïY‡òÔûieýí·>›øMoose=Rãͣ㠧ïLw¬Ãùj}´²þöÛŸMÆü&··¹²ž©qæÑñ†Ó÷¦;ÖaüµÈ[.Õâ)8há'(,™Ed"©,’¥¦ªJLEP‚Sˆ¡ZÜðMk;í®ctw1¼µìp-s\ÓG5Í4-sH ‚P¬ô3Eqn-Þ×Àö‡5Í!ÍsH¨s\ AÄ/£³éñWÔ¹+ô©Ùôø¨ú‘_¥bï¼JÆàXññ‰¶•Èeƒ‹\D[G2NJ&CC6*ä1ORöêÜ 6¾ñÈîKÞsS,û«×> §hð'•¿jGÐ8A<‹H/u†–ð«‚ònió6Û`ãÛ«Y.á¸i10ý–7£½xtÖ¡£†§Æ€¯oL…xäi¥® Òᑸ$Ö1÷T|¹Ì‹DÎmïFhV±í?䤉˜sk_§[khmÍn'mYÃidÐ*Ðò8j‘ÿjGž·<—Õð¶sqf·-ó²9ˉn.[ƒýV7ì±£©­.( uV|µb*”ë©ÓDꔪmÓÜþŠ’;SªPS¸)P& PSn½=ú’ÔU()ÕRZª©ANº)Õ)UÛã¤GjuJ wM`¥*›u÷jKSªPSnÞ*’ÔꔨÓN…UL íñÒ¢uJU:½ÊšR‚}‹SªR©·ÇPZR‚•ORuLUzüƒJ©Õ)TÛ§Oz•N©ANà¨-L ¦Ýj UU)Tê÷*t”ÁL XRN½‰J¦Þ¡¥¤'T §UAjuJ uÔ§T¥So½SBª©AOëè¤{Mºûµ%¡:¥*›t©-N©AJ‚ÔꔪmñÒ¡N©ANò…MªR©×ÑH´& R©¶ µ:¥*KU”Û¯MMN©ANò…*'T §^ЩÒR‚›jKSªPS¸* S)TÛ®Á©¥ª@S¤<´“ª`S¯¢•uH m©-N©@üõ©‚ªsPÔ–§T §pRâR‚›u¥@RU%©Õ(yõ©-Nªà~ª’ÔꔚŠQ:¤ŸNš<)Õ()J€§T€}µ%©×ëH)Õ 9ô©-N©ãÓSDU 9ôé¥Ç­:¤ÒàSW…-)Ô¤=Iju€~z)ñWs I¨ª@?8x©S±5p?0ÿM.=iÔ¤ÑÀ£‚¸)Q:•p5M¨ëWÒÒŸ\ SBŠö«„<4¨ª¸<5:SVs .!UÀÂT'^Õp?pQNÄS±\ J‰ÔŽ•®´¨Š…`0ôÒ¢t À`è¥E4ZÒIkB¡ P…(B”!J¥R„)B¡ P…(B”!J¥R„,®Áw ¹f"Éc “8±K^ð$Óþ@è§_›ûç÷Û1ûVïôò/»¶‡îž/öu·èX²?³îÒµo¶/À§gÝ¥…~pxš»e®Üõ•K¹2ÇŒ½ni57fÞ*Ù”u‚D¦ÑL}4ÞPÆ0òˆ×ì?%0V.U` Ç°5³ãmî^zÝ-ÌMžGÒ|g+ÐÐ@ ó{š[¼¶ÿÊËxíF+é hêÀ÷DÀ;õ*ꔪXTÐ'TÅSn¾íIjuJ mÒ¤µ:¥* SªR©·]ƒJŠª”é(TÒ©Õ0)×ÑRZR•Mµ%©Õ()ÕÑQ¥:¥:È4¨R•M½CR@N½©ANà¤ZR•MºÔ§T¥SnžåAjª¦:ú)'T ¦ßMuJ uR-N©ANº‚ÔꔪsžçôT–§T §pT¦bR©·Çߥ@R‚U%©Õ()×PZª© §0éÝâ©-N©ANà¥Å:¥*›|u4ªPSª‘jª¥6ëPZRU%©Õ((=54¢uH mÓ¦—…:¥óÒ =ª@?0Ô–ªªP?=N”ê§æ¡¨-N©Nz\SªPSn½Þ:\:ÐKObuHÛRZ~¤€~z’ÔêÌ:ôÔ–§T€~~JT#¡4…?0ëKÂ{RéR½¯b@?0÷tT{UÀýu%©×±\ ú "ª@8ôÔiNªàpè飈OÀ4¸u¢½ªàz(Ÿ ¦‰×µ\4ˆ@§R¸<<•:S©Væ’;Sª¸|<´´¦®})P„+†•{Sª¸Žà¬ (Ž#¡_ZTOWjÔ˜iQ>[{ž•¢¶ 4’¢Ö’JP…(B”!J¥R„)BYðÒ–¨<;ï\ùU0ø«ó{|þûf?jÝþžE÷vÐýÒÅþζý `ö;<•«T-‹þÝ*v;<”T#þÝ+ò•ŸÍ»žshkÞ˹$4—”Í~Öò¨Êý·ûú¤+óü÷šý­yúÄ‹©€ýU¾­N©@ýu%©Õ )·J‚Ôêš'T ¦Ý;¼TxSJçÿMRuH mê’Ôê”çä©-N© ¦Ýj Sªû™6y éQí\½xàà›v¬ÐUË•Ô0èTÑAUNo×ÒÇfYÜÖBÑR礞[ùÀ\ãÐOàYKcðožïTÐr[IKyŠú®n5>/W³0”@bRªø ©Ã@2e 5¯7ÌókcaÜcuÛg¿Õ‹ÇãÙ«ƒz»|+mÆì}Ë“ðÛ=±ž5p§¯Â<+¸à2è†dçn„ƒEÛ ©XGª)¦.I¯½Qs ”1¬Tļ¢<•ªÅÎìMäÝÕ•»ŠHÔáS@]Ð:*ÐOJÊͰo,ÁûãÈ¡¡£M:iÓÆ´<;*¶ÙÚ±)ÿçƒÒ¡È.b„©ïhôÆn7Cx{ýí9DC½]«~k™Èÿtiû2Ÿý=«„íá;ª[H‚ºÆàá®àˆrá«Y¦.\ šJKº ²b²~Žå#%5KCrD `Ö¶+`cîãl¯ŠFÆâE{(iÄ#¾#¤®ÆÔž²F—Ž®Úñ ‘кVn͹mÓÆQª‘0HGEÐäå×}=t^PïVÝi—ÇÞÌH5£À¬Î6ö׌Œ%½£ˆ\dëò dhB©MºtÒ-N½©AJ‚Õ@¥*›u©-N©J§UM uL uÒ N©J¦ßIjuJ uT–§T §]AjuJU6éîTЧUÚ¸kßÛ!@ã\{Y†uSˆ(º‚Þ6&9¸’S÷TôH¸Ô5:§C‰¦E9mcwîÌ&ÈÀO¸óòì UïyàÈão Oyà8¹Å­pÎíͽ”Ý9x°¸vk¼”õš5iï=MhâOz ˆÖ»—†ogg1QŒø¯ÉÒWîF~Å'«Ú±on&†äû@ûfÃ2sñQ«†".å¤IÈ”D‚AÔ…ùœÝçŸ3ndŸ—0ã¶ûZٞ؜ziãKr oxà\Èb%WIú5ü¹åNÆ…‘o[¹/sh&6:FýXà!íiè–@Ò)Ð>7{,ø·]K/dIÜQ“Ý$¸Á@Ê>ºAÓåÐ)tôxlŒåó[°¦L¦TÌã%Sz ”ÇÌ„8î¹—üÃr茖òµ¶ÊàZGxö²?ÿÕ¬0ž€,.Ž´q* ØüšÞ€Ùm©æÇåÈ:]!$ô'.véŽPúTðy¡Ä>¿¸gÉ1ÖAj¨dFFÛ¸˜‚ƒ v@¨±ÑBZ)UCDÅ7 ”ÑfËJmJ$9þ¢å÷0°ÆÁ37„qkÓ,N§y ”©cÀémxñ^Þ"†­ ¼6n_ee‹Ê4MQÈß±++@æ“Äv9§‹OŠÒÅWn½5½P­N©J§W”)Pê˜ëè©-N© ¦ßAjuL TéUT¥W¯È54N©J¦Ý:{Ô¨ªPS¸*KSªb©·Z‚ÔêªuTé)Õ0+Éà%Mz=íá×pÛgá«´ÓW×ùçK4iy•¥Pc¢­Çˆz*j¦@o¢²Šk¦º€‡5|ÏÉ.iîmñ—ËÙn7Àè,û¾ëDa‡Æ|­5 šðcWºsO``¶¦7u…l¢[}æ·—±‘N8¸¯9ÐpUS*…C ×ÒbŽ ÃÏB¾S®‘j*”ªsžçôTé)Õ0)ýaI0{•Mºûµ:BuJ uT–§T §]AjuHU6øêtªª`S«hRER•Mºû´¨ª@Sn•%ªª”¨-N©AM¾:)Õ()Ïã ”ÁìJU6ëîÒ N©ANªE©Õ )×PZR‚›t÷?¢¤µ:¤9ùv…M uJU6õ / uJ sÒÓØRù†¤µ:¤÷AjuJ >½5:Sª@Sª—ÒúépER–”궤µ:ýJàpè©-N©@ãÏ­AjuWõyiP§T qç×ËK‚jàz4ö'^Ä€na©!íHç©-M\ Ì:TRÇÃËS¥5p8séÓKˆN©ãGpëWÒ¢~p7pR!:ö«Ç¦¤µp8R¡N¥\ >©#µ:«ù§Jjà`ðÒ⬢½©×µ\ÝÞ¢ÀÛ|tQB¶´¨ž¥`0ÔÑ>[{ž•¢×]hIkI%(B”!J¥Y‰Ã"Zµt:wݸý!¼5ù½¾}³µnÿX‘}Ý´?tñ³­¿BŘ½vµª­NÇ»Z¿%œB˜ Ÿów´Ì90QRxÔt.¸ÁÔ`9p¬rU¶ªö/»BRòŽ¥3 cx¥þ€¾ÁtW}ÔM‘À;…[Bþ׬ý+L=Áµïß##™Ä WéT•Ã%0z«uœ1lªNY±lGGP§Uºí[z:E1A¹;!U° aÐÄÝY[qq]ops^ò@¨TõšÐÖ¾õÃmËZHkšæ´H$)NÒà6tT»uÐ(£¤À@éiÛ4PL'2J”Šö§HU DtÝ0ˆw‚³Ö™››g‡>ˆõô8vŠŠOè\ca˜‹ êêðý…bÍׄ;~áó3e%¸²ÌôìÚÉ•2†Lœ€T]ƒ©Š:r›”¼¡èÍé÷hÃåÖûZÑÕâYôöÓéâ:ºV§}¶ÅËÜÖQ“õ§ÛðýKæ¡¥íÉâæY,Åësn¨ŠÀÈ S¦r “P‡(€Š"^‘ÈYå-ÅÍ“Ãã=#è#¤-òÊæÂcËK_øm¥Sª»ÄÕªPS¯¢¦:¥6øé¢©ANª‚ÕUJ uÔ§T¥Sn”¨Sª`Sú¦0R‚›u÷i§Uï²ù„!ᓉŽ*åcŠòJÜgv¤˜(,6Æ/²P¾d2T¥¦œì”ˆ&¨Q:ŒSäÔ¡¯Â¿Íýæâßø\A!m¤‚'štw×sºÝ®pë1±•o`‘Üx•õw!í-°ÛC/½ef«†wéîíâ8Ø÷:‡´°v/ÎmËv^yÊÿ¹ò ñ0îjáºæžMLÉ:Pç3‡o DŠcfÙ=Ô›¢MA2HR€}7€ÀÚYØÁˆÆF!Æ[FØã`àZ)õ“Òç.q.$’Jð¼¾Zâæê\óÌ—ó¼½î=$Ÿè €€.Ml-ò>bAìTÜCÖ’‘R±Î–g!'ºnØ¿bñ¹ÓpÕë7ID”!Šr bˆl·vÖæÙöÓµ¯†F¹®µÍp!Í ð ƒB ÁÙ¸‚fÏ ‹$cƒšA¡‚è Š‚:è ‰PâCÙ}‰¸ŸœI±¯Ë[BFj]š w/¤n„pýþÙºiãx雼È=ôtôìŲ`<„øƒ–lŸ–œþÈìkg8bî ¬k 'ÅýîÜšô¹ÕšN§µõ>ùt[ã”6[®pÓÅÔh¿îóØ×IGPti‹¯ø<à“ñ¹jôŸ“²îtç®I^ËM‘ ~ß¶­™F.eŸ:Žzvñ‰ŠVúnKÛ® "‰Ì œ¤Ž÷Ìþyo=“̶müD1]â´E¶ýÝd’YXàÆ‡¶¯§{ éhÔà AÔj[•;gtlgfr2Éo¼µÑŒŽ7´¸–š7ìjq $P(­f\ÞÇ®øŒÂѰy I)Gmm˜|Å55|FÛ“So\›йnÖÉǬñÚ…!Vun3Ž(˜ }ÒjjÆå2ßÍ?ýÕ5æ<@Àe}Œq[>HØÑW0àMtù:'‚ïXc¹ y|Üv׆gnß$ÍcÜMá(“®·k;h8¬Aã[†ü%eVV¹dœNØ×“S–Àñ""ùvlÜ‘´œ¿bšMTœ€U ²ˆ”©,ƒ„V$* )ûw'y­mÌý¾ë¹£m¾rÙâ;ˆÚIn¢*Ù#©'»P8’×5í«ƒCå|Êåôû0-£{¦ÅNÒø^áãP9 [ "€‡5ÔÒ3^ßá#†°Ì`ã®beåÃw‘3BbÈG²Ì×AUZðA½¾â2nRàbÐå3õÌõœk%Næ0¦ª¾9›ç/0÷þë¸Ûšd1c- ^ÊÖ8:ŽÓÞVPøÙœ‰¢9&ú©¬ô¼_,önÐÛðçy˜éd¾¸E«öÒ£VŠFZ÷HÑöÝ­‘°5&Žv㋱W³ƒŽÖ'¾pžX‡Šs0Ê"æy5"õÓDTI°É:‰œ»o(yèvΦUÒŽ”jõ 9Na)?ÊÄe¹Ï~U]Ñß²ÍmÉ$ s¢dlš-’(-ßÈK¥‰ñš=~Êå70-ä²ÚͺÆf˜Â懹ï$tUÌ’YšöEC$cÅA<:p7á"¯ÅͷÞ[báºÍò¶eÞÊ9éÛ*ªh$åB:Œ~RýE$á²ÀPíT¦ÓßWÐ;›µÜªºß»RF—ýÀO {A’ÞM$µÍ¯:—Žà¶{›Ì }£¸àß½÷R†šTMZîÇpsM8´ƒÖ½!Íü;{:øC¹Ô›Î7Ï4Òàd̶fŒ›”{qºi);–IHYy±håúG#uWxÁ‘{#¦Qp®¥OæýµÍŽyóÛ­¥½Ä/qžýñ±±Ôš²&6FICH. ŽI A:ÅÞÙœåç*6Uñ»Ï¾âhdhî­÷Òž4Ž,sBꆒö0Pôqۆá~÷⃲Ï[/±›IçÓvÔ¤ÂøšÔ‹Nภf#î‰Yçì¦Fß\ŽX®ÉâV0•1)Äæ2Y]½Í¾gìÎ`ZìÞh¾ »KçÆÖLÆDÂÞõÝÜr1в&º>ðÈÙ#®Pt3<ºØ{›gÜnm„Ù­®m÷:7:GjîÛ­ì{e|ŽÑã1Ìyi45%¸YÁw ’¼[_îa’V ǵڳ–¾nVȦáÓ6VU(Øh¤•Õ›3UÁªIYcN̨©îÙæ¥,öã2"6Üfnœæ[BI sš|#w¦êŽqs u·Ê¹yËû½óšuž³2Ý¡ÓÈHÖ0ßGi'ƒC\â ]™ÕËì…ÃWš˜¢ä¶/ËÞfAX’ø†œ½åb!ä[j“Óɺ‡½­ÖÏÔb࢚¿ź!V)ŠÑð¬~SùÜXѸ­o¬l­¦`’+gÅl×½§‹CCíåsC‡ßLÓJEW¬^cù…½8k‹[«©ãv‰'l“9­pàK‹&Œ:‡î¢p­EEñµÂ±áì\ň®U®ì” ȰRN¥ æ%üÌZ×!“lÙ²2ðif ‰{b‚'"¢aÜQOGäç8o·­ÅÖÖÝ6ÛwØêÖ [#XáÉa$²XÞ@‘ é:mZÝ'™|µµÚðÛç¶ô®ŸmÝÓIqsæ—´jjcÙRÃMB„:¦„ú›Ç$áî÷ǘG#ñ=’ÝØ8Ÿ·|ñìdYŒ”Íó;sCÛ‰CÛ‘«7Aü¢‚bB.u[±j£ÅRÔÄQ¹QbüË}É»0ùÌž/eZ6ç; s¾Ä,òHàK[ýqG=Á€ð!䆟£7¾näñV7û¦àÁ‰´a%­ûR¹íf–4€]ýSPÖ—ÐZ#0¾1öjñŽÎî°8ˆ½1ÎA‚<Ó7Ò·r²Å*현ëx»†íº æbI¼n“´w›¹pP(§¾U ë9®`së–2Úå·eÅžC,¡Žcc€2´'»/ŠdcËC‹ã¶­5¡ióÌ^ÏåûŽã·a¹²ËG ç>RêT a²K+Ð⇊î<¨#ÍÜ]‚®|ÄppÞ.›F\ñ÷½Éh\²eIWlⳓ žU$ñI7i ¹ÛÆH®ɾMð0}5œæ>'Ëçó5ÒX›H¦Š:†¹îœ0E6Dâ¢7Ë èZݿˡ´ð1fùŽé$½¸%³ Å*+¢‘–½Ïí¸½‘°5&ŽwÛŒñÏ³ëŒÆSvŸÊ^x(ÄŹ—gq:—~ñËDTI¸È8‹™º.Ø™¸–îI„“g‰Êcn—¿ŠÊs¼±ºŠÿy¾Ï/·ä1α°jtµñÃãyé2Dö=û ʽùo%žØmÎ72Æ4=Ïq#¢¥¯–V½ ‘PÉñÓÀ/0o[js_V<º›•Ëg̼„–nCï¢+µ>‰ºj ”¢»íÌEÐS@íP¦Ó–¾ªÛÙìvæÃÛæñŽÕes^Úð –¸u9¦­pêp#©|û™ÃÞà²Sb¯Û¦ê NŠŽ±Ú(ZzÁl`¦ÚÌ–¬]R‚œõ%©Õ()·ÇQ¥:ö¥:B’uJU:éP'T€¦Ú’Ôꔩ-N©J¦Þ¡¨-N½©N%*ÁìJU6ëJƒ­:¤ÒÒRÇŸü5©×êHŽŠ’Ôê”×SDêŠ\zÓª@S®•骯֔5¨¨W‡EIjª¤MN”U :)qN©ýt¸&iN¥ ˜ÃRZЏž§J¤€na©#µWóù*tö&¥Ät§Up?=Á )iOR¸•¨ëWMN”ü à`šUX !ÞD'Up?8xªt¦®÷tR⮢½©×µ\E;AÔ¬ÛJˆ© ÚÒ¢u Àaé¥Dè ¶ðtR¢TZÒIkBJP…š¼/¥«%ÇNû•‡Æq¯ÍÝóûí˜ý«wúyÝÛC÷Oû:Ûô,Y•Øì%jËbS±Ø>J¿"E›wˆLî^AÓ2äðñ^ó•ûmÊ^Ví¯ØÿÕ!_˜;üÿçÌßí{ÏÖ$]:}+}-Z•RǦ¤µ:«ÃŸü%©Ô¥¦ˆª@Sª—…4 §_»Jƒ©:¤íÓ`÷iRZV}p'ÁܧײÒÓÈ®ÏYÎP5Èü¦;aœúBË'E(™.Ñí^*MN‹}ºBxo;9³mËl3ml‹_¹®Ú{–ô÷lè38uÐðŒwO}?–{ãzd4˜{r †´ÖãÄF ¥^EHoG ýOÚöE³í˜èf­áã3lÕ„dB ƢѓtÀ­Ù7*'A"9@‚0ˆˆ˜F¿2²yœŽw%%õã-ËÞ\çÈKËœOð$ý<P_qãñVx‹&ZÛ€ÈÚÐX@ph Ãô®•ÉR™mÙ26oÌòÎÑ(n¬¼œ˜,Î(«€êº†kG*ûýGUÓ7€+rÛØ·ºÍ×Ré&~†ž ÆQϧPÔâÆðþˇjÕ³™Xb¼À†²&kpë/}ZÀGI£Cÿ¬Ò°Ç%ܳnÓ21Ò±=ªÄIwÒë‘è"©€‡8™ER€a0ê¥{ÙÆØDðû¸åš€ÈÅ\HãØkà^G¹2ykÚEc¦8I£žç^.  óÿ(Ý ­rN¾É¬u’¹&ÞÛwMQh“.™"£[î.ýu”Mªc¨¡¸Q(W¿m«ëo ¾)ú#·´p:µW¼Ô4P¸öñ5â¼Ö÷\×ËutÇÈ纮0=”#WWàà†œ´KÙ踟ï`3¦poܧïùDp»dÞ †ºŽœºÖjò×--Ö±i`ÁÒ5½ 9ÞÑoÜÚ>wÿ…ßåqY ¶Ü1•Ní’Id M !8©Í®ø€¬fG\ᨓRh™€6W}˜Ü–÷‹8ÍGK$‡€8¯ŠNšÐ[pxtU®ÿ%h¹ 2|ù ‹†Ï $S1;6ÇRHñŽVLM¡Š²R̘$s¦ è Bòë aß·¬ -’9¢ãSâêÿêýwºmÙïƒ8}`E£Ì„I¢Ý\q²úìÝ©K²ìǹ0ªŸ`C9ng ©ÄNQÓPä÷_û”[²FØÊÉcpã¸8pã@hïĹMûæ{ ÃÇ´ý¡Ðxý ò}|Çr LfØ”O(Bo71Duôg €ª¡˜,n›C å/½ÔµÖÁenðwBXxÛ»í0žŸiÄ~?É’³·ÊÀbž‚Aö\:ùâüKß³{õÄ|ƒu¼j ¦»u‹¸¡  Aï”ä1G¼bˆr {¥…í¾JÕ·VƱ»ñ°¼²öÎk ƒo8£‡AíD/œê®ÑjëU()×Q¥:¥*›¢•;SªPS¸)P'T ¦Ýz{õ%©Õ()ÕRZR‚u{ª÷¯ÙâÑ,ÙÀ/ü>D™²—‹är<\{E쀆É8ÑË>AÁÌ©@¡ö–Ðj;©P u÷ÚüüȶM³Î]¿¼gÔ1Õ¹.¥xÚܹÓ4pÿåHÃÛãpê_[òL³9Ë<ÆÚ‹I¾×0èž¶'?üÆ?èñWçfÄh´y2|ÕvR Ü.Ñë7h¨ÝÛGm”2.9n±Hª¬A)ÈpÀ !¨WÙûxÅ-³fˆ‡FáPAx‚àAA æ\À’9Ìr״Ђ(A ƒÐGEe‚~A­ˆµaj½Ã⥠`¯bõ¥.Â:äÈ XL££]ê›Ôeî\¨læá’ÈDÉ8a àªû¢‘ɸmÈ?Ÿ8‹¶oæƒ!ŸÆ%…£æ«ÛöK!µÀõ‡<´‚:A¨à¾ÃÉ[»mòÓ| .îzC¥œÝ–‘ÔZÀA Š+®1r˰Ë35š†”›O|†›q\‘f$¡@@wN™Ä¦ð€ˆ%wwHÕüÍãôxÿV™upœ‹¾#ÿœÿÓļ&³­”ݲ (mý7ŠmD SwÀ@C”š¾ÅÆâÙ45“Bù²úùÑËFp¢ý5ûDÈÒköÌZõ;ɼã¢îWoÑ2¾.¸S±~ÖíŒ$]B®ªd3„ùNB€è:WÁ¢ž|]Îõn ‘XÛ“iñkœECÑÀWIì%}qÌh¢¿‡kœˆ«ä½ƒYpãG÷]åGÓýaô.Sí0K€ÙKóEñ…‘rÝ©6ÖÒ‘weDج¥œA­þdèÊ?]V6eƈJ.ò94Õ(¬C(¤"@ÉË®hZbo?‡ö¶ZÉrÑ3¦-ÖÖx­ã4g@$p"®w¡‘æ]¾Ã¸È[|a=ÜS²Ûqn’ïðþ1-ñè à±ÝþÈ^²E©—1ÞdÎ-î«AÃLJ’†¹]±pœŒcØyrMÇmtÍät‚©œ€¡@Ú€€€ z~æÆÿ0[³>/Ä}ÃZ¥ñ‡.kÚæ“rêæ‚ ÑpwÜÛÙx²øë숼„’ÝLyiÔÒÒŠ‚ ¨\<3Î(ÏÞÖü;‘ð¼Ë‰ÛRåb¡&ýÔ ½¼à×$”#¤Ög2Ý£¥Ìœdk0*À˜ÄС¨F²X=Áµ?—ì¾ÞÜ1ˆî¢†rÖ‡¶A¡ò5â…„ã9ü+ZÔõ®•ÎW¸9ÃŽÌáž_o$‘T–¹‡[X暇OŠÆ”¥RèÏlC5$xî’ne cðï€Íé„<&0HÖoùq·3òþ޾Oþ°X¾uÊ"Þ»¯îÑAYí쮈J/„þ.Ûwˆ»YU Aå&ñ±¼± ;£ÉïŠPç­+ù‘´m¦ÿÛa.kOÿÔµm’¸7C6]ÐïÐ9|>ÉiGÐüqauÛÂb^Q.¯ã]62‚ûÒ qRrvà©(UP”t±’î˜Nch:€içémï16å…ÿ,ˆ8³GÝi“§‡µ ×…]ÞPƒk³3Wvœ/Cä Žš²Þ¬ü&ŸI_Ÿ»NK…Êï_ª¢¦UCœçPÂsÆ0˜Æ1¨˜Æ0ê"<µö>6Ä]÷ý•óMõ×p4·¥väܦF‘†´Þ_פ¥è£jI]í¨Ï@ID|_éò±l½ LD»4‹ÙÂÐB¸Û´qVye,­mã¿}uJØØÙ¨ÕÚžjEMOÒ©Û‹!sdÛ ©æ}›i¦7=ŧF’Z(:(8ìo¶ù¹Åœ!·ÝÞ`1m»DD»Ã§6£_.±w»ƒ<ÞºÅúI×Óé~Œ>%ÝT“ýH—KûíÔc8Ÿrô£ª‡Äwzb#Ìy›HÃå-zó-bÛ~YE(ûG%ÿòæZ#®Ý6ú’>¡c/úñ.«šÆ¹+4{I³¾5Æ2Î`®lÍ’VáIëèä-Ø6’O×™–xò8Åv›dQp²„D=òY »¹ð›K“69ÃgÇEŽ·¤E­y–G5¡Œk]âÔº†§ì€^x4®žk”Ü\Í»Æažb½’öjÈ šÀI{‰oƒíÒVReLìÔáÊèq Ä~XËÙ¿0¦Vn.¸¸‡ÎÌf«,͹Ð+ÂÆ‘bÌ«Q!ÊÙÜ뇤DH"A Ÿá÷G:wͰÈìü~7¶Ü\!t€P€ã]:«®†£S-ÚÂkÖ Ü2XWíIÍ–ä¼¾ÈfÀëXMA R´¦ž:]3œ:¨³G‡Ù~dø,â¹Ï öíßmY¨Z¹H—[Åg‹¾^ç.'2‚ᩞÎÏœ|TfåÐ o”Þ÷Â>[½­÷Õ·1°mß“ÚÏ’ïmŒfDzè4Ž?V£ÐxSŠß¶´ÛN}•–;F+ˆ¬»¹ÃĤ’_Ütнü4Ó¬q¯†žÃÇÊ<½3ha0’Æ€ÓQ×ûý@ÿzŸó9!~×ÄWÓ$ý^Ȇgò4ôf®¼\,¦/«½G*œà7,àŽñ„DDej"""""5ôvß²ûŬZº;¦ª‰æn»›‰4ô÷Žþ’½ÈâíG{$¸lTLvW.4d™À¤&˜Cß Z§¢e!Dl ®š›wQ—¶” ´þb³‘EÀ5·ë/…Çð’Oô/{Ürºã’¸©$âI„~Êâr^1ÞšÞöGpôÚÜt¢,nìI¢·Ð©»<­¨þè–nçt€BÝHAðŠ©ˆˆ÷ñ›I.ÿ˜,ÕÅà­Är_ÒelL#ÿÁáÿ„•ÞÝlm¿'1pÛBöZê êÒ8ÿ„/ð]¨Ý{ç=Xw• ÞÑT{ûÅŸ7ø+ëL¶9ŽÛ7Ò;í}Îcÿå¹|뎽ss¶‘·£ïQýö¯_½¥ ãd=¡Çͤƒ’m£æwÈeSø­Þe‘o 'H c(ODTú”DÁÉ_'rV[›~Xn›:ýé‚åÌ¡§ŽÛ0[Ç«8¯¡ù£oÜ,4û»ŒßøMÉüUYíOéçFqi2­¯4…ªýÍe4•^hÇ“ #$ùc²´n &³¶)¦¨v¤?bŠZ“MÑ+”—<ɵÅÝü mc-«î%tÅ¡úšÏ¼eaÒ‰«Ç¥mƃcÜd-þ-žî9Ù îÛqn’ïðãQ Ç 7‚Å,5uû(pFAµò­ƒ—s;{žÓ]Úñlj¸2pœ„kÈ—Í$£`5QËGlª™È Ž÷ €€W¤n,w=÷FlWŠ6€¥ñ‡.ii7ÐA¡ZN÷”˜ ¬Yl}î@]ÂM55妭- $OZÂÞ2óÖ6Î\UÜYH8•´ç-ËE³™'1p‹»šˆˆJ%ÙÖe,Ù«½äZ³A >àÄL4×JõžJás›[jEƒÎ´2ê9¥!¡Íx {Ë… IIq¥zJó®idñ[ƒpÉ–Ä»U»âŒ–’æ·I¨p€tu.´M]JQäå½Öœ*¼’©ÁMºt÷©Sµ:¥;‚–”êªm©-N©ANà¨-N©AMºô÷êhBuJU:½Ê^ê”î T¡:¤*›jKSªPSž µ:¥6øûµ©-N©N~J\SªR©·_v¦:¤…"Ôê”ë©-N©áÑRZRǦ¢”èN©MºtÑáN©@ô¨BuHz’Ôê5%©×± 9ô©-N©ãÓSNÄêútÒãÖŠ¤.4€p¤ZO… yêKS¨W‡†§J|UÀÜÃRB*Î*TìM\Ì4¸õ§T€z8pW…"©Wm©¢ujà~zZS⮩¡EUÀÂjhª¸<4´¦®Ì4¸„T…`8ÑÁ:޵p?pQDS±\ J‰ÔŽ•®´¨Š‚¬šTN[x)QM Ξ’ÞTy×T|f~noŸßlÇí[¿ÓȾîÚºx¿ÙÖß¡bÌþÃg+V[†Ï P…øòâDÛ¼EgÀïfœ¦+æt+öã•þVí¯øú¤+òû˜ÿ>fëï{ÏÖ$]2 sÖýÅj5ìHæ(ð§áH륧±:¤ó›¤µ:¤óù* Sª@>Þïr¤µ:ýk|·â\sQp1ÉŠ¯e^ É¹wL`®p&ù€ #¸™DLm<5׺¸ŽÒÝ÷SEK€ ®{x]q3`í8Óþÿ©~½¸c¶m<€l{R%©A`fÔæj‰H‹éiyUP;éG‚)˜ÅŽÕ/h±À@‰ ]wJZü§æmþSzoÛì•Ë¿4á¨ñk#`!¬oê´4t¸’zI_kòÎêô!‚6Öáò¸5ƒq$ç“@]C@Sä̾ò,î—q:„CxöÏdSh†úG~f(è"(]¦gæD†ß16ð€—NÿÚÚ1]†²(4’9¬.r²„A² Z‹xÖ¨¨‚@& •c2”yké¼&ÏÅ lÎ2Û‰mÚÐØèàÀI5{ˆ'ñEI¯Bð»ýÁw5ç} od‡\ƯBå¾ø»ØÙᑈ,¤&Š´ÖÊÖ£¨=‡Æað·ƒ\åéÍñ‚}Ÿ|vÎHæŒÄu·„rMÒ'•¾lëŒ!˜ªöy]Õ_ÊLcÙùËfU„Ë•Œb=‹xâ-ÒÚ®PYS(ªß+í~`s’¬nÙÜøI²¸H˜dŒ¿ÅgCZˈ㕎`Y¬l!-h o¾ç¶.yœóœÁe#Çå%ñ¤cÃx»¤—B÷ÆàãÐç±åŽ>7ŒI.ú¬n¸áMã<«Äo–J=ºdåáìÆ*¡õû1:ÈKBvﺯpEt@ÄA""Øç ÕÓQ1ŽSp󧛼ǵ~ÜØ›zëà²K‡¹ík¸Løà†Þ Ð¸—<,s]B±ønXòëeNÜÖìÌ[ß>È@hipâ+_,“PŠ€4´žp^RûB¸ã–ã{*C#n°‘€Ä6½ic@?:a ùËó ·dúmŽ«rJÊ¢I¤N©¶LSçXêz7(yW/±N‚W6|ýÑk®%h:@mtE4:RKˆî$hn—Ì]ÿ.ñÈ £k¢Ä[‚!cˆÔkö¤}8juÑ@I.'Øþ -Ì?5즻í|ù>½§‰¦nKª&î¹›8]¢öñdnË}¬4ÂnjøŒuÄ«EDë"«RupQC´ ðŽqKŸÆsþÞãkÄ'ÎÃi⌀CôÃ!{%µÕx !Ü|BEë¶}Ê ¡ÏHbÄÉq+^ðH,¬Œ u@4£ôž ·ûCMWGbÿfß6 ÊÊû¾8Î÷¦ ‚]ŒÉ´˜¶#]\°È,ÅÊK£xHÄ·Žv‰®»AYGd"u d÷‹¿æzÝàßÁmœ¾î™† òÙØžE ØÎå¯/oÖ¿KXhçíVß“›^ß*ܶ[;e.݉ÂBÐX×HÐjçw¥¡§€qmK…CCIa?´ßXÎ*3ÅšÏ?yúk…SxÚɸ‹ˆç—<“Èçs—s6Ë$Ýã&<+$b•`M¯l%LVɳrW•÷;3oÌÌës™";*#¡Á’ kG½ÒiWiÁ¡ÇÍ ùæËÆìSœ1V@ˆŸBÒ÷’ ¤€@ñZ7Uu£mãÂoµg XæXÊþâ{£Ú4}8´\r K=lÙ¥ÀŒ#i×ñ,¯.êYšO=³ä¥#WE=MÙ‘Auä'nïÞAn»›¬MŒÙ]“tî†8è–k,kŒ3D f·0Ç &‚¤hôoï£ÍÜù¸ñû¦Òí#Æ è-Dò´5Áì q :øîໃn fÍüFñ#‰2ª6ÜdÉmË »;rZ6QÛ¶.cÌämG2÷<å(FNŒ-š¢Ð‰´rb®e³)Ë—ÜÜÉæ2웵v> !tÏg{rçH×4Nô2&BÍCÆ{žKÛVDv dlítwéËYÞÚîîÖ88E{²é+¨|V†€×QÄð¨Á¼1±®BöÙyµ¬Ÿ…±²¹5høÓý´-›J؇V.%WjH¸÷o’hW/TÞìý-ÁÀ`Ý0úÎghe1|“¾Û }ÎW<,ð$šY¥|šÜ©Ik+¡¢ …ç˜ÍÇaÍ\뙆 Ý´†’ÈãŠ6³H.#KM58ôjqâQ{Q/Ë'!ñ¹%qãûÆÖ¾­ÓØV3"OY× MÏ wº#¶…”„vù‰œ¶1€Lß ˆoW_ùyÄåpÛ*,ŵť躘˜æñ<áBXð×Põqê\ÜäÈØd÷D—XÙḵ6ñøÞÙP F¦’*:ÅVsû^4,ÕR¶)7Ì™€5ŽšO 6îàÂçóRæ¬o,ã™Ñh3Ã$Aô’btÐê ¥hí[O83X|¦2îÚåñ‰5ˆ¥d…µd`j qÓRM:bàþË;öÈǹùiûþòµlhÆ7;›¼n‹f _8”¶TA˜IMÓü=bÛÙ;%ÀàÞ$l$Ϋ7s ưMIM[7ŸN!¼Ûئ7ms(Ñ7`ųääã–@‚cd8ºÕ€ÞüÝ78«)r{6åßÔÔ|@If²Æ¸Å4`–ks rh*@fÀ2ûWšø È]Ga¹àÖ ñ¨ô‡‰#}5iax]ÇpÿÜ"p…*¦fâˆ\Y“’·c¥ËoÙ5·å#¤Ý:dᜠ°æVã‘»¤ˆÍÑ…»dš\‰V2ƒÙ”ÅÊî>aï¾bÙ·llÌ%ýƒ¥{;Û‡:F¹ êw‘²ÔxÎ/%í«CF¢C ³6–˹9íÏ•´»µÚ! cƒ‰WAsÝ#¨|V†€×QÄðªò+äÛ[2çÛ!Ú6\=…mMH »iÂFEIJˆ„‹bÖ*8ª³‡nÞ<²O[²/0‹¥”ÐÆ.ƒ_Jl Ûwkˆ¼¸’òþ&ög¹Î/‘Î.u Év–“¥•㤠€W†ï Äy¬¼ù+hYmg#†ˆšÐÖ4¶¡  D N§õ‰¡_I¡J +Òx-¼S•M´‹Sª@S«¢ µ0R‚SBªPSn=ÚR¢uJ sÒÓØR‚›j SªPS«¢¤µ:¥:êhSªPSn4¼)Õ()S§±:¤*›jKSªP?pT–ª!TÛ¯MM(Š¥:B—UJ uôTÐU m"Ôëõ¤õÔ§T€}ºwxªKSªP??’¦‡©:¤9† uJ¥@zª@?0Ô–§^Ô€z‚ÔëØÌ:l©-N©üþJTìM ˜{¿ÃKÂRùéP„+Þ‘ju)ãRZGR¸<5:Sª@8óëRZUÀüü”¨GB¹†•{S¯j¸ŠŽ ÁJŠªUÀÚxjHEB¸ž§J|UÀÀ=á¥DUX !¶¦5p8tR¡M\n´ªBu*àq£‚8+‚Š"ŠÀ4¨Hé^€p¨–ôY‡Nú‡-~lï¯ß|Ïí[¿Ö$_víÝ<_ìëoбfŸa³ÍÕ–ÅE; žhЊ/Ưæâ?ˆ÷´Í¹X9Ê@ óßi¯jòÙºšàÖ88p=-5 ±c,bg5„jèýÔ¾»ûÓa¥ÎÉP;£2@ñŽÖ*B¡Šæu"V]Crœ„\ŒÊp×@=«¨î¬>ðâwSJöþ4¯"– ‚+¡ßˆ…ÆmÉå‘I2ª·ìÙ9;6.Ö§!¸Š.C³n¡{6ŽJEH"tôï×ýÕ£".–Hõ4ëP=‡á}*íY+ŸÝèêtp¡èãÕÒ»ÊÖ™›R5{_ Ã9go$±¤XJLöq-Ù–& #£ó¤ìL@Ý¢(”ÞQéËZ®FLtÒ6ç 7nÚM#¡Ôé¥WJÊÛÃsLw -ŒW¦€Ôq¨·BÜ®kË5«3p–½’íV(*ÝTõåÝ:'ÿ(w‡–·,LϹ°c¥¾+‡ao¢e mµóÚÏönñ‡€ÿßTeSmd V:©ANzšꔪm×§»Z\ª@S«Ê´Õ:¥:ú*KS)TÛPZUÄÀr‰L€†ƒPYQCШ8Ž ®/iµ~aU0ÜPyuAÖ°×xˆç:›Ò²vùÅâž…°Èpcn™c‰5ïj=êÆÿqÉÐOÜþôe*ªæp–ÓXÀ@Êœ£§~²v˜¸­øÓŠèÜ_¾nKÙhŒ­‹{³>1ÉV ~F–•”<^?{xÛ­oyÔÈV{ÔÔaj/"Iç„;6Ê*›s¤™Œô¢!òùÛ[‚oæZÇ9…ã°M‚0ë‘ ¦‘o3H3÷`‚@¡wI¤¯£¶¦o$.ñR]Û7*é^D&V H3FA—k5Ÿ³Ð ê^Û–¢®™B(bƒQ¯¦¬q/’M%xeÞA¬’…v,¨„z€²žýNþ¦åk5iŠd[ºV.ã éF‘з‰ˆ²‰èb†ø èÏwŽå´ë\V÷„Ô.2À;€±û=ÉäÒ°ÇúÒ§JÉz7¦œW5‡·[Æ¢bœÁ ˆÖNÛÈJq]ï_3«Ôí¤Q~/ü¡6õq·ÖÍÞõÕS¯œè»µ¿ÊGI° ~PÐÉ]‹›a‹¹9›¾wÎ&m­¶våõ´÷mÝãô±Üʘ¢da¬säuK†HpÛ0{iíLŒYüînÒx­Ý®6 ÔáÅ®á$Ž~“ã1µÔ©ÌŽ3øoŧY&«¶Öd$Te‹bñ;7ÊZ°¤^' ñóeff%Þ½Gß GLÂ& ˆû_(ö<»'nɸ-vAï3N[Å¢G†‚ÐzÃÖ2¿Ö-$p+Ëyº£Ý9™r0‚Û6°G<¡¤Hê.sœêuCкÆRÜm,Ô…P ƒ§.µí· ¸`í/,†íð¾ ð\8,ÀÛ€±û-{ÚòiX¿îgÖ•:Wûͧ«ŠçöõºÞºŸNQQÖ²V¶ ·+£qvé…ÌJ§Uw WV©ANòR¢uJ mêT Õ()RZR‚›u¨-N©J¦Ý*KSªPS¯¢¦…:¥*›z†•uJ uT–§T ¦ÝjKSªR©ÕPZª©AN¾ŠT(ªB©·¨iP'T §=NžÄê”ÛÝîÔ–§T€~®Š‚ÕUJ Á©¥T ¦Ý)xUU()J€ô"©û{½Ê’ÕUHç©-ERüÃÔ5%ªª”çòTТ©NaÖ—´ÒéiìN½‰@üÃRZ{UÀüõ%©Õ ˜zªKSª@??’•èM!OÌ4¼)Õ •èE{ù†‘ ×µ zjKS±\$ê=5%¡:«Ã¢•M yéxQ^Õp=¯B~p7w†¦‰Ôõ«‡ŸÇH„pêWóÔéOЏ0Ò¢*®-Nš¸:)P„Õ€iU:•èÏ ÉoC”t0¯Íõûï™ý«wúÄ‹îí¡û§‹ýmú,Úì6y+U[†Ï%_‹Ž' »Ä§¥æÎ9d•%¨ª@8ôÔéNªàpèé¤ZRƦ‰Ô,ºÀ²ní“°s’®î¹†êFYé²Px9 7mÓ‘¼£9)D·vÑ&{ÅÉu= ¢D5Ò÷;,ïíÍ•ûÚÌcf¸ÿã2&6ÿhx²½Òqš;£Q![Ö"9mìc’÷Ť´ÿd¸ŸÂ;Òõbâ¾,¢ZSØ®Š!bÏ02“nc·`÷ã çOdä]H¹xåc‚Š*(î Óå•,ðÙÙ3po9|Y¥¿ûόǚ½º"kXƱ­hZÝU¡è[ìw°Eg&66-ˆGÀôõ¹Î$’I4&€à±êÊOcI+fÁô)ËÊžJBkµŠX±æ`Ì¢éI4gÔC&]æL"";Îç¾›rn(ò¹ímŠ2ØéÝ3V³À¸¹ÏwŠ ñkAÂu1ï8ëSmdiª¤“ýcBßM+Ú±[+ÚºÅUäD¢AA“täRNc³ª›ÄXÇ•”I”jMÑÞÞß2¯x“—~Âgv´÷ÝÙŠéÒ-% 7‡M$þ%‡¼°»kìãÓÇ£²µXH³"Oª¢· ÈѲ+˪V+Ò©DD=ñ‰p£aŠ;½ü3Õ±ZÈ!¦¯u‰‰%•¥¢wzš½»v´”ÈÊ”aíkqÂÅ“¶žÄ¤Ôc6…AÊŽ»PÊw5Ð4Þ×½ÉZ”ù˜ÍÀö[#ƒZ$ÔÒãSð,£E§Ü¦kÞtpâ8žž¥Æ®; 2¶mEfßM̵E»øÒ¼·n¨¶äUÂnÜ<1 Ýx¥ÌàSéÈ`(ià¬Ø›q\Êö°C¨#[xPtb½œ+ÿ¦·ûnH\Y¸b ÙÂÛ±³íˆ`Ý%ÎÌW v…)ŠþN4‚`å×R‰uõsœniÃSîŸÓý ªeÍ›>Í»^>’» ƒf~›Þ"Ù´4pDníf—fRM3iƒ„‚8tÔG”G¾нÆI+÷‹«‡šIOÔ?Ì»L¿ Å ÞÊT­W:Ü-´½¸ª×1m§O"Z,»¸›RÊ¡'èm½<ȶ(ɦAtQT8{”+·q6RÙß’{~Ûº*hhMkÙõ®Åíëû÷ËÓV´ô V”!b¬­ÓsK¨ç³ÌkªíMÙ€öZÖháqђﺆÝ'€qúÇêXæß]HÆ»¾&¿WÔ¶ÛžàNï4¡4ÂnNÉùݱtäȱ"ï cvÀ€:Q@ß05åÛ]KhÙ÷'21¡Ìs™ÑNƒÃ¢Ÿ÷.Ôã/‰.i wOhãÓÚ»/¸{öpÌž÷¢ä´ASDª·UC¹HÔGû$Êp&¥8sVW÷eþ½ø¨íô,&ᎌ†N±©§ê5 °ANºÎÐ-f©M¾>í)§T ~%AjuìJ s IjuH TЧTÀ§]*êÛ§¹Hµ:¥÷AjuJU9†¤µ:¥*hSªÙeâ“•(úò t/,Ûr(WnÚäÀVáÌ‘È%ä »ka4Ž…3Ìev¢·Sú¹ËW R•Mµªª”ê©¡N©AN¿%*'T ¦ßN”ꔩ-N©J¦Ýj SªR©·Or¤‚SŸÖ¨R•M¾:E©Õ()ÕPZª©ANº‚ÔꔪmñÔЧTÀ§WE*ÁJU:Ý©-N©J¦Ý*KSªPS¸*4§UµËF!*€¤§. <¾}Úê\Ú¶áš\»\:T.¾=‚ A5L ˆ÷€G½­`Ý…p4i:VU¹0EHâ¹½k¶ˆþÓ@2Ÿí‡”u®ý¦5–ü¬º—7¯›‡Rç%S@Ъ²«¥T §UN’R‚äTN©A]¾:šê˜ç©-N©J¦Ýj UU)TÛ§¹S¤§T §^ÐþŠI‚”ªmñ÷êhªPSª‘juJ uÔ§T¥SnžçôT§T §pRLÄ¥Sn¾í*ê”ê©-N©ANº‚ÔêªmÓÜ©-UT §?“ú)qLÄ ¦ÝzjhT §U"ÕUJ mÖ µ:¤6éRZR‚u4!:¤*›téîÒ—…:¥)R½ Õ(˜jKQT€~z’ÕUH s»Z‚Ôêçä¥Å:¥6ëK‡Z*´§R·ü5%©×êH N”êÌ:ô÷kRZRùù)P¦·^ï%.iÕ •;^Ä€naîè©!:ö«úêKS¯b¸<¥I Õ zjt¦®Žš8„ê4¸"½©ôS±?¸¦‰×µ\=5$#À® -)Ô«€ó I©ÕzcÂ:[Ði9J>2kóW}þüfjÝþ±"ûÃgþébÿg[~…‹7ûÖ­Çé[GŒhãô¡~'8¢6œLñQöuËɲÿ¸¿p¹LßùU¶áüwêp¯Ë~`þþç?kÞ~±"èÐ0†·ò£R4¨B¸„øõ$s .íWóù)iM\ Ò¤„ê»âؾ$¬·ökæïå±R)á»n–nÖUË9-Y®DÀP6ìТUDÁ¾dÌÐy5›üU¶V) {é èK€:A”8}!•Óô¯B³•ñXC§ Æßõ?γ/[ ú䞺̻‚,Æß¥p+µœ3)E”„nvM¤ÛÆÌ‚ÅÜpÕœ„`.;¥WU›PPÇï‰Aþµ™Û¯{îd‰ä9Ѱ´‘Ð\ uôW‡Ô°»™´²ü@t•´ Óñ.. mÒ¶ÒÕ¥U()SNÄêªmÒ—…4 §pR êL…SoPÔ–§^Ô §UIjuJU6ëPZWzYü5ñ[äºìœ•®›id޳YÈ+䑌M08œb¶Ž:RÂQLCF¨ïh]5Ò²ÜÆØ8+ó‹Ìæ±vÙhèå¹…a4ûm/?×ÓÃBÙñû3wemþ7=‘d9®èÚ;£úµ]E%' ò&f=ôL¬s…ZHFI´pÂA‹´L$Y³Æn“IÃg 41R˜£È![e½Åµä º´‘’ÚÈÐæ½Žcšz×4Aê Э~hf¶™Ö÷ tw 4s\ \Ò:A„ÖªùM½C\¥«Ž©AJ’ÔÁJU9† µ:¥:©P§T §@ÔÐ'T ¦ß"Ôꔨ-UUÝ–gù÷!Áý¦±°ÎN»-ÑŠ36MÃ#ðSíRG¾nÀíä•HɈˆS b€é™Ž`lLï÷no1µÈuÇ-ÄL{kJkiuX x©l¸ÝŸºòö¿}Åão§³ê|pÈæÝ$6ާXmHúÂêéX¹{~Mì,ô\”Ìkƒµ’‰—dæ6J=Òc¢Ÿ0z’.š¸LGßBÁá Ùín­oí™yc,sÙÈÐæ=Žcšz \ÒZàzˆ$,ŽŤñܰÑÌsK\Ò:œ×Aú øÁN¾Šç \UJ mñÔ–§T §UAjuJ uÔ–§T¥SmM uLU;‚• R•Mºûµ%©Õ)TÛ¥AjuJ ]Iju]fáü¿‘#šÇø«$_PÍ_+æZϱ®{š1¼š-Ú»Z9wð±oZ¤ý¯QTȘà¡SX†ÐåÖòû¿iíû–Ù粘ë+Ç0<2{˜aya.hxli-.k€p%®¨+7ŽÛ›‹1¹ÄØ^Ý[5å¥ðÁ,­Òæ5À84‘ZЃÐBäR|;ñ #55‚3444Cr’ÒÒ˜Â÷aÝGoäd_»ƒE«&,š¤uYS4Ó(˜Â5жæÀ¾¹ŽÎÏ9‡šògµ‘ÆËËg=ïy kÖÈKœçÐ $€Wn}»í`}ÍÎ+%´l.{Ým3ZÖ´UÎs‹kZ$’¤®Ÿ:ú+n-Zà)J¦Ú‚ÕUJ utTéìLÉUµî¦ÖÛ+É͵>…¡%$´<}Ö¼4Š6ÛùvégL§Nرn¤I#èS*R”DJXæe1rd_‡Žæe£ŒHøŒ362@tUÖI8€ÒH¡]ÇX_²É¹'Á3qÏyce,pÏK%4— - u-Û§Mw¨ ê×µ0)Ü%©Õ()·Z‚ÔꔪmÓÜ©-*ª”ëÚ(¯bb©·Çߥ@SªPSª¤µUR‚u©Õ)TÛ§Oz¤´§UºEGÊMÈ3ˆ…/- ¹0ŒŠhâBAó•9nÍ“TÕråsøB˜Ãà ë]\ÛY[¾îöHáµµsÞàÖ4’ç8€í$Ío÷S6ÞÕ’áækAsœOPh“ô»>êÁY²Å‡ûCxâ|‡mAµ˜š´g#㚊›€™æûª8çÏu:t´:®œKAë ;Ú{£m÷Ì–>ò N·¾µ£ÿ-£~€ê~%ÕeSn•´­~©ANº‚Ôꔪmê’ÒR‚]•U)Të÷jhT ¦Ý)ªªPS® µ:¤*›z†§JuíJ wJu[¤T|œä‹xXçÓòncÑÃù)®T*MÙ±bÑ5];táSHše1Îa®½ÕÍ­•»ï/dd6‘4¹ï{ƒÆRç9Ä5­‰$€Jæ·‚{©ÙmjÇÉs#ƒZÖç9Ç€ h©$žR¾‰h©{zMì$üT”Ìjæk#0ÅÔd›$Ó}»ÖRAÓUɨjES½ê‹K«L…³/l%Ž{9©’F潎ok\ÒZáô‚B»›{›9Ýkyâ¹a£˜ö–=§±Íp Š¯¹Ý¹rÇBCܲüÛrâ;äíûäKö°“ªE¸3I4áåVnFgŽtQIpACŠ*”ú%uâÈãn/fÆÛÜ@ü¸i–&È×IxÔÃ$`—3[|fêPâ*$–7ÐZÅ}42²ÊbáŽc„rš;CÈÒí'ƒ´“CÀñ[@)·Jí–®µR‚ÁJ…0{M½CK‡ZuJ祧±:¤íî÷j Sª@?pT–§T }ºÔ–§U¿ÅÛ×Ó ™Hx ¹XËq²O. È§ÏØA4\çMS/ «x¶Ë(™ŠE2e0”@Dº79,}”ðÚÞ\AÍË‹bcÞÖ>WRØÚâ È  ·oc}u ·°Ë%¼ ‘ÍcœØÚz È0P´‚uÜ ]T€p¤Zª¿Z@8óÔ¢£À‹UU yõ¨-EUÀáÑKŠi@ý~Z\ð¤…Sª¸˜jHE{Rùêtªª¸˜jHíERÇÃËS§±5p8søèâRÆ—pW…*'Ç©\ ÍH„ëÚ½Já-ë}°éßI!ñ¦Aäñ׿ŽüýøÌþÖ»ýbE÷–ÏýÒÅþζý sv=ÚÖ©ÿn…±)Ø÷kGýº¿ ó—Ão&A¸k÷”£þUmŸø{úœ+òߘ5ø÷9û^óõ‰Dƒ¢½…jWxjH Õ\ÏKJÀÜÃRBu*àq¥Døx„ø¬ýáfÖ°²L;«{#½fÙx™f,.ÎÈPP¥e1©*Ø®ÖE·¤‹cœ ¢NÓ7¾˜µáüÁÍn-»vëœn– *ÙÚ5jh5{ÚŽ%ºÀà[N{Ô³Çå,!mì¢'†Q„Ò„´é-5 vÇ¡f]ÊâÚ‹;´Å™êˆç|G tìˆ)»bš´D…&ºróù~,dïešNíŽ"MÀPº¼ZâOk‰4Y›è ¶yŽ*<4‘¨Vœ:8Àº=ò-U6ôö†9Îc&át\{³X"tÛ  S€ººÖóo$ÌŒ‰t:ƒ¨Ö+ÒOWÒ°R†Ö­è[S(øÅc§"&£[º„¸Ìñ)ÖÆ(œ’MÙòÙN]ôÑ @£¼÷À 4ï"/s$µqmËÓJñ ð÷öp+‰²¸¾ÁXÃ/·¼œ^J䘈zví£!Ú,“uaH¡Ô¥ èê&w*¶ä1S\Û†ÿ-g¡Ý»Šä‹(àcdŒMzOgi§«é\BÂÑÕsÜü:ðùkaù †ç†œuq’êdÍ87Ί܆g¨Û–ªº§dºª»L¦*Å0ˆ<5ªîLÕæWL tN:À¯:EOObîE¬žéÇU>•”ïÛBL£gì“{ènÌ".›”ÄIôzåY£Ä¨Š6] ÝÐu.µ©1·1=¤º­ =GªŸŽ«•²ž£Ä-åÀ¢šn7Žeç÷¤Pºo Îrˆ‰Í®¿äë]i-ËYZŽŠPt ó®Q3öŠÐË‘EWQ¾è”Ü@ê€ t€Â:{ã”F˜Œµl½5¯ƒÂ¨=äTNÅMÅ`0‰È¡•ô(¨•0H»„1D…0‰‡Qðìä«€é#Å"”êÝ)§T ë ‚Ôê®ÛÝîT–§T §=M uJU6õRð§UœÏœUgåž#áÓÈlI/aã«^éË7\"‰tg#¬v$vÖ)Ëeqã'.Z‹†æ‘Ër#éÄCÆ9õº2Û[—³;!‹9¹†Æ ¡÷.-sÁZá~‡ 8µÀÔ霦ÁcóÛÂ1–h“g·R³¤=°¶¡¤u´¼·Sx‡6­"„® •øÄâ,߯¯—Ù*ñ¶ {[^سîy»rÛ²#˜¥Šˆ¶#"1lÁ(ÆÉ&Nܤ œ¢§2‚&¬Þ×å&ÄÚØ6a!ÇZ\šiáŽY®^~Ü“=íqqy$é'KAÒÐX¼÷0·f{*윷·xß›Ž_p´}–FÖ††Š ©ÄUÄž+(3$œNðAmñ+y&ƒœß‡rÂXZø¼Á² ¤r‘)„ͯ)q(܈¥!7åê “WtV2ETê‰Ê!æ»FѼ¶çEÇ.±ÍÙy|YÈ[[Ô–ZܲC̈Kc”5Ò×Hq`m(Ví¸®½¹gòÈ€íÍŽ¿sM@q ˜¤¥žÂàÀzHÔOH_~Vàç…®®è[S3q?v%!u[öôÜTU•‹BfJÙe8ܦ4ýò²³ Å¤Y•R¢ÍºYûa)ä)¸6·79›¿±Se6~Úµ0ZÏ,o}ÅïvÉÿelZœý:K¤“DMqÑWHäÏrïcm„v7p%ž(ÞÖÃm­Ñµãý¤Ä¿HmjªBѪ‚ ·W€‹õ§ {y[Œ­[VÊ[-Îfw/öEžA’oÍ’NUU@2jvhÙL^ß±)œÄÎz`ååí¾ö†Îáù;«Ác<ß» \[÷]D8]æŸödÈaʬ¬{Æm¯-Ä-±‚ØÝ>ðƒÝ 05wúA' éÑ«íÔjÒ Öû ÂÇÙ±­Ùnð½o Ó-Zì…ÊÆÊÈ8ä–ƒLŸ™Uš I¤Ì‚í%†ª·`ùHX ÂU“é^s?~lÙmrËÂZYí[»†Bë‹[¾ýÖoÒ?½1Ñ´9„ø¯’7im âKîÕ¶ÅÚ{–;‹M‘”¸¹ÏÛÂé öýйk_Ü8=Ä:œZÇG£€pÙ1_ ¸Âãá¥&2–p[Û-rÃüy) …ž­É1,›[sã†m,ä[I¶4¥Õ*ñBp Ú6d“‡j, ‡f~îçæ~åÇóܸÛ8Q‘É;Û¦HgÆÂé{·:à–1 MÔ÷Èèâk*ýC«ƒØ˜KÍ–7¦s&l¬›~ëw0Bd{€X€áªW ;KZÀùïIã÷‡kÈŘ×=áŒ7bl3;i˜.Ëu bîµ.û|uâeÙ³bñ)ÍÖYP0„OAÞæÈì^`fó[Ÿ#±w…„6;« sþbS4Á-(øÜæµÍ,%­s\*I¨¥×´1˜Ì–êÛ—rÝà/$|_ŒG,RÇÒÇ€ç4‡\<ë¨+Ч]zÉjóê­îÞuÚvÄóe^Á¡-´Ë$dÖy“ÄO"Õ”éЏfS¢(€Žº‡~ºwñÝÉc4vN ½tO¸ô5å¤1ÄPÔPžv-.¢}ÓKíD/¤°¨Ž$Tt¯o¸Žµ8¶Î× ån òãË󷇶‚ôpÎUoe<Æì"¡#›))`nØrÎi6Êt©.ôtÓ1S*eI?Œ9y”åNÈÃ|/ÍìS,wæ›ï3ä,ÃnÜùDŒºîæk£, T–ÇPçââç}5¼¬9º2_ßܺÈ:ëkãî"³º›vµ¸Èxp&”sè@ 0+‰kû0gÃãÜŸˆå­®!m¸¶XÞfb]›È»»+/+*Í•âZìTaRzŠÊ*šNˆ£„ß ¡9LRB½Ë—8-¥²±|þÚËEs°.%uÜqÆæ¾ Æ9×’5ï«H .a 1è ’Jò­é•Ü;Ÿ#ŽÄg1òC»¡`·{Þ eº.pl%ì-m5À¸?UA‹³¤øPáŽË¾Ú`ŒƒÅÌfnYÄ|,ÄŒ7ø×Ú7„¢hú=¯1p¸žc.÷°tá4W|š)7ncÿnŠj”šÕ·4¹“˜Á¿|`vÌ2l°×É%»Ñ}=» ¬ÑÄ"tm«Asc.sžˆ^ÒsSì-“Ê·jåó’3sÖ=Ì·×iÎ¥"|…í{¨Hx­¯¦Ž¯`ø8ŸBW‹býž=µtð¿b¿¼gl.Ã7)œÇwN\Ç.Ê&n-D·\Q2‚‚å&¨~÷›¶/µÚÙ<xÆn[æÀçètàú´‡>7‡1íÔ¦š8Ž+mË›¦OŸ±ÊÊ`¾ÁÚºRÝM–œ[BKHcÛG5Ô®— ¯°F i˜¬Î n·+˜0ž.y‘2B1'éÜ 6Qr[…”zÔc’?cþêR¬!¯ù5°o}ñ6ÑÌ`qqÛ6værm´./-1Žkµž?d–øV#kmX÷7-~ùÌGbn ﯊MFžŽšÈ{{„\…°¦vÍ\D«mœ«w({n>Ëyp]®& §RˆbÊ×i»Ó=ŠI¨,æIû„’M™½!Îè¦&æÆô»Þ9‘³vø¿Ébä€wϸlPåˆÈçLç†éyv–CLƒ¼y-vû>^í‹}µŒÝ;—0lì¯Ù/æÛ ’Rö<1¢ Òu0 ºG¸Ï´%àŽ'Ãf$³±¥–¸‰Ë%•“Ö˜qЬkÍFæ¾®;V)âmò—<œ¤LU»àU!ÐI]ãºI@:gÔ @ÊÞóuå÷%ÖÕåö*ÚòïØÅíÍÍÁ†Ú)žÒï»Ç¡’>WŠç6Ž®Xë]—·ñØ[}Á¼/æ¶·¾/6°A’y"i§|ýNc#i¨-‹¨=!n¡ÁQ.¼•aÁbLµmÞX²ý²&²Y²t“% ÏaÙÖš¨%y+~Û>–íäL¥¼«¶é1P©»UÊZ"‰Å>©ç!ÅíËëí׊¸³Üö7±ÙýÍŽ}æâpM¸µ›KZöJçBXÖ;ƒˆhw8å ¿ÍZZíü„8+»WÜýåÍ,0Cc(y4 , ¸—4}­Mn¹6mŽ;7·®s„ɽѱҴBøåcƒÙF¢Ð+S¨PÑGÉ?ü%AÞq¸š‰k®bþ~þ*ÕÓbc¸ù¼Y;4 HÝ™%¹BNu“'.Šš®›>ºˆ$%9K®·~óZ÷&ê°Û–°àcò6 ›·Gzø£©.Ð!ÑœHcÍGki9“´y}k’fß¼ÍÏ&Yïk °[µö­{éA«½Ôö´ ›Àÿ£BÑ85}ugŒÙ‚o;ê2Ì’ÃÖ%Ýw¸º Ðîm÷¿g¤-¦ì\?QuZ9‹€¹ñWŠ*Ýÿ¹k¹¹9Ã/cawÆÆKË|½ôui•½ë&. 8>V¾YP×8ý [ Ëio÷^Ojä®Ùm>6ÒYŒ´¬nîÝiq$ÆæÈ]BZÙ%}Iðá…o¬”æpng¹okÏ Z®/‹¢6ä°¾ÊÀ]V¤P˜'æm–w&ÍÔˆ+7É‚ÊJA!DÂbñžbo<&g½°öÖXlÍж…ðÝwòÁ;ÿÙGp45Ž/>)1 Ôê4¡±²öÆWsµ²SÜäñ–æy[$ÔrÄÏö„ë.£5‚µ¥€q¤(µrçy"ã±còS©„1­¥fZhÜ×Läd „™ÊÝRC!'Â.«‰&cv®ˆ`Q3h ÞËoÍɺ®¶žÀÇ[ß\c[¼žâs ¾P\È¡sä-¸FZá^ަ?há-0û‡x^Ík ëž-¢†!,¯lfŽ•ÚœÆµÄ:\ A¢Þr ¬`pÜç_ëå¥8u±¶¥²µ¤“sAËÛ‘Œ}!’ܵ9†xÞž è›3¶PJ¢©€(==³ÍY¯çÜqîËâ›·#ÓRa9=äs=Ô-kC‡æ‡u§Œí«Zïv3¼¾ŠÎ,+öíáÈÓålUˆÄ‡ÆÖÔ8öž=x0´Ð¹¼W+ÿ« /‚a'üJM/ ¨ZÎ&Zc£+‰™_\}–Vei¤f”I“zä{"6€¨bH¿â72eÂé܇á.뾺î—榮øF#1‚cüà‹Q}›7/Ä]çt^-ëhÙ맺// ˆd mx:ä "ãÆ7µÏîæ…eqÚRîá¥EAU¹—lxéšÆ"b»ÍÌESt½¢*ÚºW¯à3˜íË…¶Ïbœ_Ž»‰²0‘CCÒ8ÑÍ5k…Mê^m—Å^àò“â2 Ó{o!cÀâ*:Áëk…ÓN ‚¸™TÛ¯k-¤,}V{ð)w[2Ù†·•»²Åç×·0õýu,›(h[ñ3øñ–]' ¡ßÌ“ÑÁ ˜¢‰ŠMå T•ðŽxâr7ö˜‹Ãgq‘Ú¶y6BÖ]$‘ø®Ð263¯S¡Ô ¨Ð\ßYåNBÊÒç%l.a²Ü6F;;‰Hk!>3uCÿKˆê T×vÌ+~>¸l¸~_0/cµ™IÝòô[(X÷eºùƒ´žº—ô) ­H¶Å"¿¦8j‘ŠSTNrŸU½“üÆÇŒ{ NákÙÜHÛqes­sK[¦@xiîÚ÷_h#aµg76MáËe"¼Èá‹]ß1Ó¨%Í!Åú])hã«[šÅ$Wĸb'-þ¥d«Šámˆp¦?p”Å6£'—CƸ$VNÛ²í–;'óNJ€(c¦T‹º¢€"rþ£º÷•ÞÓþíÛxûwe÷ûK"Œ9°µÝÓšâgB(ÇP\jÖžÃ@ÛÛbßpýû7{3qÛḃHúK{Çî›â™x6¤Š 8ô€yeÀqµÏŒï£ÃÞHŸ½ZãQdã YW¥®µvÄÀH,£v÷LZ‘ò2QÓ1I¬‘ÅÁ ¸vÉNqïqXýý¸ñ›’Ïls”™-BÖâÞc4•€ ÃØÇÆòÐMCÜCZ:HÈ^m %þç=³¯fºŽÇI¸‚x„r²7¬Òç5ì¨:€¡h“Ð=_…Ì-ecÜ]’2Î{ql²ÉØý¥ÑjÅZ¥î‡NÛ‘ÁÙ¢F*?I­¼Äª¦S?p™{UOÙ”€%¬|ÏÞy­Á“Û›SÛ™±—î†IßpØá´Ð8ê .•Ô$DÂt´j$‚²¯Ø[c‡°Íî» ŠúÌJÈ™ |¥äVƒIp¶ wޤÐEÓÏ›^V¡4òú·ò•™hÞVÙ£SŒs6ÚìA»2MãÔP~‹òöb˜«¼P‚`.ðVå±÷ÈÜø{ûܼ,±Èbï'·ºYxŒÁÄ»QkIioé¥C€­³ºö™Àäí-qÒ:îÎþÚ­äÒ^%à§QÁÜ)^°M*»b_„èç[«Edfd·±u”ÖñÌ*b!Da¬´o)4“F,ݪ¬ÚÌÑ~‚h"URUuûB›³Ž%Õ-9¹#ö5®íºÇ<ä2—®·°³Ž@d¸%å‘—9Í0â×8µÍkt‘«SAØ.9pÆî˹ozß¹ØZ‰¯.^ x i:ËCšÚ‚çjN“AgÃæÊׂ|<勞ë¾ìˆ×BöUóe¥m«xÀÄn »Û9û)7Àg­ˆ¡L“ ƒ…·€=茒ówí‹Ë7smk‚½°‹‹kƒ0·–J÷m¸k˜ßЇHá´ë¨ #Ù»o=mr6vB{Œµ¬.”Ã<#4lûn…Ís¼aÒá¨×«‰_e‹Ã>0w„ì\픳_éí±rÎܯâR¶ÎN.æEÔ{–ËV ®âEg`Ðë9UDJ“4ÀÛûÁ\YÎeîx·¥öÆÛ_ï ´ÈÇ™„Q#÷:g8ÀÝA¬hqt‡¢”+“±°2m{MÙžÊ}ÎÂydc˜"2<–8µ¢ ÒK‰¡.% 0tÖ«'IÖreµ¾ùyHòÒ(BI9@Z¹ˆIâÉÆ¾rÔÅ)›.í‘H¡Ó!Œ! i^½bë¹la’ýŠýÑ0ÈÆA’‚ö‡u†º °*¼Þí¶ÑÝÊË7¹ö‘ÁŽ"…̆¸Ž¢[BGQà¶â©¶»«‚«1øJl¢9Sˆ™D’3,d:qmzBbtdÛØŽ-‹¨¦>ñb »•×8€Q1>È`ñîlHü·÷_/m‰ï³w­PжÊÚ“\º½D†µ££U\Úž úW.ØÜqÈo9À1b­IŠ£ºž±@>šç4é[¯¨—"Ú8o‰¦"Šd›e;;#=ÍæùFÁH°Ï¼)4ìrC´MväL(·›MâëÕå{ÎÝËf9i9!¸Û“qiZñ²º=ãZÞÞæG¼ôj}A\ûùƒ5Æo¨…]}†ç躷]ÙÞ°4témOH]“0ÎÙ’á‹7”«È;iÕßšÓ“’aY·H/é6!"Ìá©]‘˦‘ÀNR(&åÓA×,æÉÛs3}O‡‰“ä›gŽÐÇ?»i?uejú;MWH…j³—1XO±6”Y9‹®oµ9¬ÖGûéâÔV® Ã1ÌwávëÛÓÀuà B(-cd¸<9¦Ži.uÚ<†ñ.ªêȰVN”°pÆožŸÉíXH9€gvØå¶­\„ê)¢¯GÛrE—vö%Â[(¢^š˜Ê^þèåÚo÷þùÛ6±ç·ž }°ùÙ]Ï}=£^àÖ¾fwml€8€îìð'¶8 M›´³×ÄmŒ¬ÓgšÇÄÐwQ\âØ¬¹†€‘¬q§eHÛq_ –Ù‡¦³GÊdÆÖ®Pua\LßÛÎez3(‰S’£W!!s;–+b³wRI59„1³ºy‘—Åov~ÝÅœåÖ-·P¹²†6®–F~qÎ Yy“U\âÖW.¾ßØøÜ†Ú—ræòp¶·¿6ò5Ñ—:ñ:)sô†R€<š4…¼[|9bKžÇÉU,ØîX¹ ­¬Ê^^ÐtêJ~xÈÇ©¸cƒ†¯”¸^:ìh)¦EU! ažK˜»³œÆíga[q¹/±îÑÇpÖ²)ÞÒ!h‰­f§IRx†µ¥Ä.Í–ÉÛ—ø«íÀÜ£¡ÁÚ^ˆš÷ÂK¤ak\ Xwxâí-eá©ÎÃòn±£±D>nÄW¬åÛc¹¼W°'˜Ý0-àn+zåN3ã†à©>zÉã'qâSï³ L'0'™Û;×9qº¦Ù;ºÊ LÛlÅÔN‚S,RÂ_Ýš5®kšúŠš;€bó»[Þ‹um»©nq.¹6ò6XÄrG(n±].s\ÒÞ<:*:jiÉßáþ,3D@äŒí;!xHÅÇȈ0µ#n«JÒ^A P#ßOšt§]™NTY¤]À6šã ÞÆÏ ¯öÞ ðñÊæG÷Ùßó†kl]Õ"èox領]ù¶ÎÈÄ­3™iŸ“|msþë e†áö]'yùÂÞ“ }ªîž°%±ŽxÎaŒr«+ ÌIÊYml£)n_ÑòÖ<ìŠ%›É,ªP¦‰9œLGEÍ»2ÁºµiœÀß¹=ÇÉ™7>Þ‰ö¢IË“ßMjøîba–d×%PX{§ê ±m7gØa9žÌjF\1Ï€wAñÜ5ðHà^Hf–UÝüãt‚x9ut>>} ÅKìa•®¤,»*Ù‚‘’cñÄI^àöBDŽ fc“–PØC?IR íBŽöéuÒ¶{ÍÁsæÕƒsâ­]𽹕Œw{Þ›m,e%æ1WÈÒ ‡‹CÂ¥köØX%¶Üà27 ÅÚÁœÞï»ês«Û¯ƒXàtŸ½4 ©³!mãñ]ÅoÎ9¹í|«b²ºbd–+ÛLqo=mœ»œÁ,²:€!¾et†œ»fÎÝÒî;Œ®;!mr˜«çA#õ+Õ!´€âPoO®îm´Ì8ûÛ)]qÈZ6V8·I­$Š€š˜Éh'¬ž…Û’œ$¹m•c1[KѲàñ‹ ‘™.9˜ÿF†Æ-Å$fÙ¨VîÖVWâÆ‹ dͼoé$׳)T9u+^mG&Õ—uKdçE>Möxøc~©/N­¸U 3[ƒ6š‰h;Ç.ÍÃÞŽé¢H¬s{#ÛFZ:žÓBKô‚Ò8·V¡ö@$R/✅Á ‚rµÇsd+väÛ[^ï³ n7¾™EªI…¤õ¼“Å[¾"Z¨‹GIöÊ€€éJ¢„»­ý»¶Ä–÷›ïmm·®&lnžÞã¾6®wí,h-¯HÃ¥½ ìmé G¥"ªBG-›Ë‘E é9; y5QòždZg`æp>xuw‘‘S,tñšA#ÓÒà <`¦ìKŒ}Äc2d†T»û$õø*(OUGUVkHÆÈÛî“¶%ç+$@nv©¼rF6Фw"ä­âç á14A@[]wÒ †•æy»+æ ÎåÑV ð¨i„xÍ¡áÄ}kn½ÅÏm!Š'°tPôƒÐGQ¯Ð¶ÇÆU±»ŒLŠæHçHH¢ªÞNØ€:öb òVjôt/•þ©­ÄJÃô­˜ÆjìälOHjSHs&ºº@JÂsv…Ð4]à×@Ò÷isº¼+¦8tš…Ä%!¤Ñjç}Gj šŠŠIûS.rh`íìN˜ÉŽ‚!¯'‚³6—VÒHÑP$ T‚8£é¯RêÈÉ#ããið™sì9-!+f ¤³BF¹m3(Ù…ÒlœsS¦1äjˆ¥ì„‚n]Ð.ÊÔw,‹&ã ]£iÄ’H$ŸÁô®í±kâñxËÔ)OÆx.ÞMÙLCé¡Ä¿Û)¸c§ìÓÜÔ *x’µÇBC…xu ý&¾Ùèéÿx(I^ÇtÀ "øE1 ö€A|Dˆ`Ôû¾ÀÔhužº‚5Úð¯i?ç)‰h>Áü?÷-í“—àS¡¡Ûn½²¤M$„å8 j¨ªÇM4ÌTÇP.£ËÊ5Òš{~JÑ-iARiÖ'_à]¸m¯&«âˆèë&£ë4[ÜkB¬à)0YP"mdÑzä `)^>7f͸€j"'8ìïWNæg2>ùwQ‘þÒâ¬oþ«\~ ²Ö±Èá“5Òö £à/û#ð•Ü6ý¨ñ€œ‰Ã¶Pÿè‹ìËâî’jþ‰„ºî¢u÷Õ¦ä2ÐÈx<££PÓOQlc¤ý.'À¶;k e>ï飵Jÿ ¿ú£ÿ >µÄstls otÄôm%w4û(È[6ºzêX¾Š ‰S!—t©ö§7„5ËìÉnï³öóÞ=ò[Z“;µgM  ð.¦P[ÇlYnƳX é$ŸÆh¼QÈ­˜Â\jÆ»$ƒ[Q‡ZA!Éô¿¤.öqÂ"_xfä–vª(˜¼†A }gµÛ$ØßïšXû§™OKYÁ±ƒØK@q®+Å7<ÍvKîÌ5l ¨ëwK¿§€Á@ûkb-Zõ~´ q¥DêÏ¥/ uJë¥AÔŠ¤óPÔ–§T€~%Ij`¬»à‡;Û¼?ñn]×»uãÉø©Ü‘nš«.Ÿy1çÏŠÝ휧ð»U"ê*Š"e•åçÙ ÷°î1Xgçà–;«RHÏnímmO^ÝL$ç㤿òÓtZm=ÙC&ÒìD±¾ ŠTžêfés¨8'KÈHiT…Ú7³ˆ´¢|)m¡ñdûµÇÙBømy)è c–˜TòíKnË ÝbâN$’\§Ü9Ó.ýkxæ`ÿwiÞWÂnhÕÌS2X¥ÇŽíÝë Ææjqnš´8Ñfò<žÝß|®Ú„e0rº°\Á$ncØOŠ^uŽíÀ@ZW&âRÔáã…«Sƒ¨+ÂÞ½²tþIW2g¹K>E »jÖ’B8s¶žlc5•}‚ 8~Tµ+gÄ éXÝ…m“ßÜͺæåõ¥Å–Ûƒ,1Œ†9¦aË-ÙˆøÌkÉsb'‹ãxáV®îížÃhìx9ykq Îj[Ͻß:'ǃ4Gn89Í9ôû/oOŒ²‡Î¸…ÎA[×V'±>Û@IcleæF*~ÜL¶ä³H2Í®´K3un¦-WMÉr™¨Ý@10Ê_5äW6vËØw½Ó}÷;øò7’†>)zÇIÀÀZÇ6S¨°—‚ Gwnkr÷wnmÙö×ï6³¶asdóo â%p1ð!ÁÎ¥¦ ž w?XÕ·׎‡¼ñë·L¸2µ8a´òÖ”tÆ/¸3 €2sMØNKz.BÚ”“ž]‚Ç\ šÎ)ÅDÌmFï—ûŠNYZoK»;öDýá>b{X 㼊ÂëDeÑèñÙ3ehmKY&²F—°Ûîü37ÍÆÙ·¹´sÛ·"ÆÅq(kí¤»ƒSÃ_«ÅtnsÜÂMs4€j ãv;®6ñÌ•ÏåK†Žm u 9"ï-¾Âø´8~V.µ·,tí©–R÷$µÒ‰ÔA²[qrS9Ô"JdsQògpÛÛ`¶ÅöãÜùl„ѱ¶-È^Ð7P.–äÍ™! 9ÆFÕ¤P5®{zxÇó/4ùl害î7FÎÚ¥ÚHÃݽ®‘òе¡†Ž*I 8mq¼Qç²¢Üz©S*®øé~áR¢B¤‰T_] œL¾õ4ÀÆ÷¥@JõÜ|Bæ~âWKvK@¯A}âzÏÒ¼êòC'"¡‘Ôvèqú8ÚJ~ Žù?ÿåÆ þ¨/pÿå™ú¼ ÿþ˜ÍWü5oúh”åüÆ~Û›ôr/9N௡hBñÐW(³][MîÛYÅèÑôœ…ǵٿ¢Ê>¶R“jyæqÎGÿf~æ,ª‘?Ø(`c2ñddÅ]G‡{#˺ÞAž51³ž:Ú¤¸u€BîãŸdÌ„É5ÏÇ ˜ekMèÆ°ÓÔâÚ€zŠôG%ð3–˜ßÇ¿¸3BO*ákt$±Å÷ޝçSè¹nŠ® .¥+=/ èÆIEI 1»âEAT“ùÿns¯jÍ‚.oº<^ñ¥—v×p=±ÈA KX褎FÑÀ4šÐis½{5Ë üYc•åÈ}þÛ”‡[Ïo3KØcÈsdcØj p)R©£½óVaý![€hÜýq±¿ø†Á÷ó‹»1ÈGʰ».[FÄ5Ýú"ѹ®Ç.‘šºÑƒD«#¬ªÄQ®ùÌ à«8Ò6vÒø­›êãb[¾Ã`æ¬ {3Ü÷l“ÃÃLp ipkZCèîË#Ú7&âø}ÛR×3n÷v2ìËvæ¹²Éë\Ȥ‘¤‡Ê€$[R|pçõîcàw4ež%îÌ…`%qàü¹~Jå¬àÂç·ÆË‡³.é…îYI)%¤“Z9kQk¤fê& œ[fCï]ƒhó«gín\Zà3¦K}銱e›ñΆ_¼Iqb1¬ !ârÖ»P:F³¨Šb7,w&z\eñ!“mŒ…Óî[zÙcîY ¯29Îqp-1á¤GOjG5Ê–M{A-\i1!)–0ö'äY±igl˜(ØHBI8XŒ]+0ý58Ã"‚Ú•2œÅóÉ6ÆW—œ·ØYMDZÛb³¢êúŒskÄ•¦F¨Ú@—…[!ÑBâÐwgqûËzîÛ,‘¾{üI‚Ö®NøXÖǤ—¸9ƒW SßùO `N7$²´C+.VàáÒy´E™'1¥ê¼{A~w«yƒ—nã ='Fé.ë± kÙå)ŒO0¹¶7žúÙ–Û^gÞZÁ¸"2\27‹pçi¤BWµòÓÆsY«Ki¨‚@XŸ³ó»gjni³Ñ¶Úypï …Ïi˜´j¬†6’[|PçSQû €Jé)O§žÎ±ïkÄG’ö³ktå“kÎ>`ÿ÷ø¯Õî±¾¿é¶Ïÿ…v6VÆ·X#…ËÛÆ…ý-ˆq >Éö TŒbwU£-g‹vq“ÊÁÌ ã\™‘1û,—ž¸~½-IX)æñS®!¾&^Fº²mœ&rvôÂWcÖ+Ö‡Ò(Š)˜TIÁ6™9{Îmm&î=¹¿~ÜÁç­çd±Ç=ý´mx¸šÑš,f-m1È*ãã¸ite£+²qÖܼÜ' š¼´nk+ˆš'Fð×Åi3ËL1Ü;S£x“Kµ°Ð}–Mx'´¬bq£eÜ’÷VJ°øjá¦Ì°˜LIÉæ§øƒú+C"ÁÒlÚÙç·¥JÜoî-þÁ2T;DÕ1u2†"*ë9·rs1Ž‹·/·ãÌ_IŽmýæ§UÍ.uÇzÇ2&ÅöœdƒCžÜæ-¼ÉÆÞÉ™´Âáq¶Œ{xëKj 4ÐCݸ:GIöZx‚GC]áì̺ósÓ.E39–“&àQ@SߺUÒ¢›T΢mÓ€#¥}©ihË;H¬ã¯wm`©ÔhÖ†Š¸Ð“AÓA^•ó Åînd¹}5È÷8ÐPUēë§£©|%SnÞ*ç-\U^¬áLI‘³_³ví´1}®êî¹RâôÓ'Šfî5šÅŒeŠí$;í¥^°l$EW©@'þ@×O—7–ëÛÛ3ùˆ´Ën[–ÚcŽÓîÃÜ׸kuìä6Œk×uS‡J÷µ·ó;›“7츽‡^Z–ÚÄ «‹GG]x¬t‘àŒxçòÒXNq´t['R/ÜžrÎ9[²d‚Ž].b¥qS1„ Q0€rz¿=ùKwq­¾f\Jö± Gp*ç8ÅN$Ä€´é¹OÌ;x_q62VÃKœuÃÀ4TžW€ !8L|—Õ^1/äd•‘¿œ†<øÝâÖ½á†Mƒ«Þð•*{À0Q,X˜Œ;tÌ‘ž1@j¡´jÂîon1Ê,Œ[Ø7ïW÷eâÚMmµ»+ÿÅ{œ ºHpSA:ehÛ¶£—8SÌ\°yšìýÞÎÜ8´ÎÍM3ÌêQm#Ô(_BGÉì‹*Ñ០#.HÝO%8zâJï’±2Ô“¥–Y‚y =c¸Bå“zs¬Œåµ? ‚2›|Ü•Ä šîfï-ÌŽNÞíK{VE¿öìÐ2æÅ8Ú¸ac@9¢cX(\Ó*4fq¶Øý“Ì›]Á5äÚ¨¦tn$–‹†š‰î!ñÈæ¶G8Ô5ÚÝC¨ vŒözfö·t³\†hlsŠ-öÒòÓ9ÊRNFÄ%ºÁ³…㦢ým's˜ˆ•Ɉ9'n© ¸pA¹çöË—¸6CtÜ:6Gc$eÏzâã~¨Ëcî¼bçŸéñI¨Zt< Üñä$fcº²ÀB×½÷ÎsvÐK^Ú>¯×À5£Æ¼`(Vó~Š û7ðù[.w ‰Ä½îFº€ž–;~ÑnÀÊÂMóîˆé¨é­tðZÝüÄeÌ€6C¶íª¨½Š¢´§Eh+Ó@»m#“8á.g÷Üô4¥GvúTÒ½•ú×0zÒÖ”àÃèÛåú‘vT—7£ ÂM%c­gw{†÷ôÖœQœJЍÐwDºéX˜fÊ[s‹zÜá#æcÛöî·a¶àÄÒ:ä }+#,vò×kÔyüÄ͙աlFb$p=D2¦«-硸²²ók[{ Øx§ðËq@üQxÄÛX‹ìœ¶?+¶B[‚fõ¹ÍÍHÏK4Pæ1QP(áOxC{CyMç*³;-Ù ã}”Ës*Ky{ËwÍßÇu¥ßšŽÞG"Ô¸wAƒÆ x£Ðní¹ŒÜí³ÛV–íÉ™¢fÇiÝ> ·óš@÷ºGŠžYqà ñŽÈ‘¿íÓí nrXÿòî'®ã‡üØÿö›?Òß.«OüÓÞ°.Gh°ïƒëmq¥Ë®œåÁñ0J½w™-›ÿجWœr°ÿ¹noønïýP»ýÆ7ŸÜ:pµp`Ø¢_¸ºÏ‘ÅYψ}œí­,Ñò‡”}ñÓc„|ûVÊ..w LDuîkø-ˇå0·=†ö”ÙZäîÙ{i9Ãx®Ôk'”&.{Æ>Àqh´rU®. Åâ'”d™Ñlt¸¤¹È¹LMÎоgÌ­ïÊmñµn1øÎç1º. s,£†ÞGÝ ÜÚDà{±$aŽ!Ï-ÔÐXAÕ¤ï;ksjno/ûÜnÞPë§Ë3na²4e.h!¥¡ÔqR£Ÿa<¯{EñaðŒn< ºéÌ.²Ž³r,›zø^PÌÞ@DÄܽ”C)ƱMHå›S ˜¸&šj<ôÚ·Ø[«¸÷¤™î›\Cl²’J%¶”3Se’Hk#¢sÜY#ÅAÑ©Õsš—ÚùûLœƒ µÙgýãq’7VpÜ1†9ã.¡Œ’ŒkÃsš¨(Ö¸¾éšâRÇÂYn{-ÂaLq[/lHÛq®/²â¯Œ¤7KFÉÂÁ¡oI7‘dÞ5»€pwŠ‘DÑíHCf1{».\f÷®&ÇiÍšÏ\Ûܶåó:öáöÖ]Ñd’XXâò4ÚAwØ$jðßÜïl^×ÈÝî(±xˆ&Ð66ÚÂÉî»ÀZæ0Fàæ†ƒ¨¼‚Úé$tWÓðT<ü<Æþ™o£ù£yÿÄþ‡-S˜Çÿ mØíþ²…);#a«.øÈ/ü ]Mê«UE1u9`LAIÝV»ÖP†Qgì²,"dhA•4QÉï•(ŸóNÛ7·w…îÃÜo‹X-Ã…tÇu¬‚g8ºÒBd< s‹’· >/5¶­r¹—ûjO,Ô4«íߥ‰ õ¹· ƒˆºGÖ\f“Ì_ê,.fËîö÷,t%ýÅ·ŠŸ\z C®’Jàö‹>,-û¡Ìµçdðû„íM’rYÞ4Ç Ý&‹™‹ËyÜKæÏæU—8‘4JÔåSE½öé½àæòÓr«!‹m¦÷pf²×e¬f=·—}ãÉpÔÙ[#KcŠ—Šx¼*Õzh´©î_yÊ[Û¹såÜÎy iºÝŽ$6§HãÑSN…³Úÿ°Wú|µ“þ"‡®æ\ÏÌHáŸô².®7þäkÅú6/ªP7³æl¨t›‹&ep¢eßQ4@§L‚:åLD@<#\Wáãù€ƒ»Éð›¨A?{–•=•\–š&åï ñ©4û´u§ÓE•9ÞÏ6TôTO Ön<·pOÙÛ}ÜUk Œ¥žŽZ)¢Ów ùz^M¤Îš¤Á`PÊ5 ‹tÄ¥0ˆ|³Ø™« nù¯y‘¸ß_x•²ØºKÖžáV¶ö倂Í4÷E ^˜²ÝØ«¸íùwmeÒî#,» µx‘¥€É%Äóô:µ¨PõpÉ6aí6ÅN$äY³²ÛɤÕãù\cvÇ1âM=däž&š%(ñÕ)@9@+§¶’åŸ+´o¨¼s´ñ.kY{Ý^“â1¤¸ž€ +³yß.=iÕ ž•B@8R-N§Â<õ%©Ô+ÃÃS¥:¯^ø4OzÖ;í¢<íӯ̽ûûóšý­yúÄ‹ï]û£Šýmú,ðìvŒkS[ŽÀñ_…+ÄŠn%C½¦ÌâÈ·Wîg)þíø{úœ+òÓ˜_¿ÙÊ{âóõ™Aë^E¨T…`0…¨=*à~à¤;ÀÀ4"§­X !Þ(Ÿ¥p?=NžÄÒ­•:@å$×H‹¶rTÕ.ò`»7);js—A&G(N_öiï¼a¬fZÉ×Ö/¼%¥Z~‘þ~#ëY<>Cûºý—ÿeZv½¸{²¶¹´uµÄdøÂŽd”á¨8P‡MAÀÚ½§¹ ³A3dà°á^#‡FžÂg3Gâá2psr°ÉâÆŽ•…”Û÷ 2‘©‰œöb %ñ€4¬t–°ÎíE¿œm%ŽÿÚiñ” ‰#ûTw„>°j"JJP¢vë@Y%)SQWŒ$ Ü J&ûhùˆ ª˜5¤(&”¾é0£›wrÃZ!k‡¥Í¯¥qºâÕü%¶ŒŸôjßè4üK‹O½HƼÇì^·tA"Åe~ÜN@0  ñ#n”GT'(rdíáÊ襵è«Oõ¡ßåë\“ýx_à#ü…r¸'%dÕ˜îA»t Îo"¡HEJnª:Žð€ ®¼µÕ¹ŠÿYuÎF>ôŠP[šWüŠ»ûÍ[’ߦCÇësF®]ÃØXP §¡Dª->õa0‘C¦}¼…ÝÔ@L‡–(ÇûLÁ=‚&Ž‘Û_誦]BÑHì¢I{ŠÞûp³–¤hþÛ‚D¥T“8dÞ&/)^¼2¢U chœµÒ‘¸ØçÌË«‡pûRÔÿám8.Ôwwã„FGú,ñš­í½°ÑáÁ[Žz^qN]QUë‚¶ÔâQM‚GM±SÓ“Mšº’e¦„hÅÛÁnÎÐÖêáÚóWWëRèß3ëu#äãÖISzÔ»’ÒbÙªiÇ1'Úvi‰)L¢€A(ï)ºDÌaè<£ ~´¬ÅÍIJ—\ÉWR¦§ x8žµ²aÃc5kG`<;?Ëô.Ûe¶âe„L_ìôÝ( sŽš€Duæ­N[¦j$ž+`û¼’4 VBâ:z>’z8u¬Eâû Ââë=7ʼE{¶u³ÈË&8§Ij“¤Á;†ër™4›52mª%ÿvqÉïLcÔù_ˆ½Ü9?¹BÇ7LJ\?¨éã5ë5¬Žh?Õmx€«ºnáÂØÙÈ3DMí'†¡×N zÅHà¼7:çYE9„Ê*s(sˆ‰ŽqG^QÔF¾Ïclc@}|èù#Ì’q{‰$ý'ŠÔÏËOObš«ù‡¨i§T€~z)Õ ˜jKSªPSž• uH mÒ—…4€~१±:­É¬´‹4¶g"õ«g¤Þ7nítv˜éŠnRMBr jº40‡†ºòÚÛÌöÉ4ltŒ5i-´ôÔ8€xv.V\M\ÈÞæ±Ãˆ€|4à~µóùêËTUe÷|GÃñ˜G"Ù,n[b%l{gÙnãæjÝó£Ûñ~€ÿ·,Kçm–v~RÇ1Ê(w«ÉùKËÛ½´þÌ¾Þæè_Ïp×FZÞõú›Mmihé p=oüÂÞû»pÿ{ã[<Ha-yÇ»n—WCˆ-=@ŸX” WªñZ ~µ¸-&ýÚ-[º|íÓv$2lpåe‘f™€€b5MC˜È`H  PÐæ áe½¼Ot‘1¬‘æ® \{IIéí\¯šYÖHç´PIÁÙÑÔ€ê÷+µER‚}ªªÛPZR‚œô¨z“ªÜ˜ËHÇ †zÄ˳XYº]°¬Ÿ³PQ:b¡5ð¡]y­­î±àM¡í‹–9憦'9•hH¨ì4_8)ÕÑ\ºj¢«ïNIé*À•ŠêeÙ‘Â¥j²¤ÝÜUVÅ8"¢…Ü % š¸m ”Næ7¿h u ;éjäÈbpˆš‘SB{HèFšÆLå:g2jÅ9S LC”u)Š`˜¢€÷ÀjœÀàZáV”ƒˆ5#ð¯©Ã×/;—ŽváQUÕT]uD QULcœ@¥åðWp²áhlc 8*|‘Åò8¹ç¤“R~µR©·ÇUNÔª¾öR/#Ö :bà bìÜ*Ù`!ƒCDäP ok × ÖðÜ3»|}ŽÀx.Hæ–k‰ÎkûA þ$}©Œ"cxÆ1Œ#©„G”DDyDDj´(85©©é_z’oœ Ý«‡®ÖlÐ [,áelÓx¢s™4@Ú» é\ ¶†7ºXØÑ#þÑï OÖ¹]4¯cc{œæ7 h<«êB Ué§BŠ¥6øûµ©§juL t‡”)Rªª”ëè©-@)J¦Ú‚ÕUJ TЧU÷šIê­b£ÇJ1ns(Ý™Ü*f¨(q9Žt[˜âŠG9”0ˆ@DL<ã\"[)œ1¢w 5Ã=' uõÊfÆ"sÝ€I ðŽ´ESn5zAQT §pT–¦ ûÍ ñVÈ2QÛ•¶1ÌÝ¡×Tí›™Cê aI#(c˜J¨ˆë\Þ&ÈéšÆ‰]ÒàM:*zM>•Êe‘̹ÎîÛÐ+P+ÓAÐ>¤ESn•T*j˜ëè©N«1±þLá†W[vNb±²E¥uZN'K%àp´ž¾ ç¦ìÑ>é^9 ÅveIªä\û©¡¸* ¾GžÛ|˵ܗ9­¡}Ž»Åݶ2lòx1[IK{ËWBXRç´´UÄšý>‹‰ÍlkŒ$8½Çk{on^Ír;$5ÑpÙKC´Òpq൫qž-ü®\oeãëfJÑÄønØqkXQS¯Ñ‘¹übá“—Æá™Iœ¼ã–¨™T›’ §¨ÛÚ¿Ë͵ŽG3Ÿ¹Žïuf.D×O‰¥·@-Šƒ¼sAÎ s¨ã^N==纬óâˈöûŠHà騂ù$#Åy¡¼:Mxc™$ž‘¢ŒñÉXª ,«2¸T­X74UFà~Äê&_|%×Þ‡0W¡:Þ(œ±½ø Ô`=4âxW­i¢if 物4'¶ATÛã«¡QT §WE*& b©Ð>íIju_z²œ ƒW®Ù°6l»••A¸w@Hç2i4÷ •×m¬½ÒÆÆ6Gt'ÂGõ®gO3Ø#{œæ7 h< }HJ²Õ_s™ÕŸGÈKžzI5?„ª‚ŸÖËRªPSnµ¢*¾Åºpš¸tådš”HÙ%—UT›Û b C˜J‰L. Päjâd1Fç=Œh{\@ŸoIéí\®–G´5î%­è’ƒ³êT:êèU 9é§T ¥AjuHÛ§wФµURœþJšŠ¥*œÃÕKÂRè¥zª@?0÷tT–§^Ô€~z‚ÔÁìHæÔêÏä©¥:HSó êJ€ô"«Ù. ÓÞ´£‹1Ôv¶K½_˜Ûû†úÍ~Ö¼ýbE÷ÆÎýÑÅ~Ͷý zöA³ÅZVÇÅNÈ6x¨ª8¯Áç§(]ßn4ì•!• &Fè'|¢á}Ó€9ÒoÈ#Èÿeh¹)5´†š—;ñŒÿBØñO0ÈñâøúzÑ—³‘…ì—÷•âè ˆv¬á Z¨CK\Ó—jœ[‡A9D¦.§û“tµ9Ä“mmŒ®çʳ‹i×À¾B˜™Zj?I?e¿iÇ£…HÌÞä­m,ß!¶ÂºYZ8šŸìŽ©Àt4_Ì·–®ÌÍ{J^÷k;ÇÆ*,c[¨¡£`â1ý"13èlÑ5Sî–PÆPÚ ·K÷–ÏÚvG2É´-s¿¬ç´ç·8ñ>…óVéÜsî,ƒ®OpŠ?îêphêI+­@áÑ[QjÖkØ54N½©Nz\Sð$)ù‡ª—U œI¼m›Êøêí¼&˜[ÖäO¦ÇÇ|c1&¹1iéÒÎØF´í×P Ú.²I]L`ZÄæòøÝ»‰¹Îæ$îqvºY_¥ïÑ\í,kžêÐÖ¸ž W½Ìä!Åc™Þ_ÜHØãmZÝOq£F§´Tõ¸€:ÊܲF:¾1 ïpcŒ“n¼µo[YÙXÎA½Q¢ê´YVè»nt°pî=û7lÜ&²¬³uÑPª&sÀ#Á··uá Ü;zá—X{–jŽF‡à i«\æ¹®®kÚ×5ÀµÀBæÌaò{'.1 É@í/c¨H$(ZK\ µÍ%®H ­âàÄYÔÆØó/O[ÞŽò«‹¥…püoëãçlª°—"³“s9ñl¢&KW­›m7’“CWVÃvmì¦á¿Ú–7óø¶Â똴HÞè\0I Öæß­„;óo~ž‡i<=ÞßËØa­3÷pèÄ_kaÖaqdž q{t¸SÇkkÒÚŽ+®ýÁ[•‡ªû™¶xý^Á‹W/—Ü:‚‹Tp°&˜j¢š$9÷¢:h\I ×;šÆV•qTô žW$qÉ+´ÆÒçtÐM>¥Ø¶î#È·V7ÈYvÞôì{ŠÜ[-/Û‡ãx&¿¸¼eS„¶Óø©ä›iÉOŒdÖ*Z²là¨ë¼¨ššµì†êÛø½Ãaµ/®4gòm™ÖÑwrô[°É)ÖÖÙ¡€ŸÎ=…Ý Ôx,½ž1}†»ÏÚůbcÉ©ƒA™Ú#ñKƒÝ©Ä®§K¨8®¹6ÖÃ¥aêê¥áN©NºTª@Sn5%ªª”Ü%©ÕvÎ"Âyc;Ü*ÚØ’Ș½f7’­c¢ˆ˜¤y9;*å„5Q)UxåÌpÝä­Wuï-­²,Ou^Ãghçin­N|ŽþÌq°:I\ØØâ(³Ø µžÝ7fÇk%ÍÀvš°v½î-cÒ÷4ÁwBà‰BÃs1þH€û9/;kÃ^qLþ5„—ô«jà*戒íàd¥¡é…lìT9'»ïÈ]C\ÛÝ8 ßg-þÞŸï\Én÷h’=3ENñ”•ŒqÓQãZkÁÅeóx ¾Ý¹ŽÓ3sq, ™£[X䮇UŽp¡àHpëuè)ÏYú°õJU6ëÓJ©Õ()ÒP©ÓTê»/*bœƒ„oYw“íÿ³7ŒKxçRá+ 3èèJ±BE‚Ÿ[òRÑJöìœús uÐÀ×6ÆèÀï<4{ƒmO÷œD®{[&‰#©c‹4ÊÆ ât‘¶A œÞõ¡µ t:M d…†@Òc$Âz—j e[¸²ì cþoæ©ÙkHÕ½ÿ9fâ§‹l¿eèƒ-é°Ý„áÁÒA6¨Ÿ]ò˜S÷õ¬é¶FC)Š7?ïøh5ã{¹3âïší]Þ™+H‹Ü:à³£lgM†@Aþç“•ÑÛ;\œ{$îœÚkÔÊ?Ŭ€ô‚GÆo‹2èÆ×tõ‰zÆ|Mu[/9é±ò"ÉéMS£éÑ.ßG9Њw‘YBr÷ûõ“Âæ1›s '}‹¹f¸ß¥ìÔÒH®—µ¯oÐæƒô.†S}…ÈKŠÉÇÝ_Àý/n¦»Kºi©…Í?Q!oVV1¾òEó;gÁüm­µnëÑׯpÑÿÛȘåVC°”dâGtSìšuÇNBWK3¹px »+¼ýÕÖFàAnÝ;¼”ÒŒ«àΟ´òÖý+³ŒÁås÷WXè»È,¡2Ìu1º#.£œÒïô-è˜['šÝÅ×`[:Ûù¢vBÛÆ’[Áö–j*t¶Ëö^‹ñ·¦Ãöf;GéµHß唟¾®™Þ[hd2x¯¼ÿ¿á d׌îåüÌo‹¾kµhÓ%cñ©{‡AÜdmœá³°¿î?Ý2rº;gkódÛ›Mz™Gøµ4Hⶺ¼¬;ºâ±.˜7 .»MÂÍ®(”g.1Š·"J.*½…s!ª)ro*šÇH7ƒßWžÄg16ùÌdí“tÐbyX51àš ðè]<Ž#%ŠÈMŠ¿‰Ì¿·q0ý$Rµs ›AQÄ>•ÄNò…e¨>©AN¾ŠE¨)TÛã¨-UT ¥F”ê˜è Ò¡N©J¦Ý:{Ô¨ªPS¸*KS)TÛ­AjuJU:ªtªªR©×Ñß©N©Š®ß*ê”ê©-N©J§]AjuHU6éîT–§TÀ§?Œ*S±)TÛã¥@RU%©Õ()×RZR•Mº{•ªª”çåè¥B€R‚›z‡Ü¥@R‚•:UU )¶¤µ:¤:º* SªPS jiDê‚›téîÒ—…:¥)P"©üÃRZª©üõ%©‚”§æ¡¨-N©NR¡M ˜u¥Ã­J¥§±:¤ó IjuíHç©ÒRù‡¨jKSªö§‚’kgDc¸v$où<%bæ¯c@ ž²À:½`ïìšð^‡ƒÝÕ‰¶“­l‡¤v‘OíqÚkwO;×hš𤹠›¨ÙTõU3h ‚ÉåSAÐÉŸt€~M5 Ö!Æ_ž-ï¼Axx´ÉG6±qŒñ`ŽÐGá[#Û¾×–J¹\¤IdÊ£èõ‘?¢©Ê%MRoêˆ8ßÝy`0w´×?n'ŒªH¨¯ÀV:HK N’?Ê8JÞ-X%'n,xÙ‹’*œe®” H•DÔí&lALtÜ´ÿ wDj/¯73áû–:ÊÞJ´ñ‘Í¥< õ.{hqÅÚîe{hGÙþú}k'¡x¤ÆNx[^'$M'Ô}t©»ù2 ƒ6.•f`ÈÐÚ9 Љ€¤ÓQ8€V¥6ÖÎÆ6AöM–Ytµ  ¸‡×‡ p4ú|Íe+¤6½èdm©ï MOÑ¥eÊVÖBq7Òeš1’ŠE¸k,À[8,’(r²¾»WmÄŠDå0€è;£È:†âÁßcå6·Z ËkPê‚Úñ­ý¾š.Í´Í{u R½Bœ~µ‘ñ×)IÙ© •8‚d0©¼'ÝÔJ‚]©ÌpOÃÈ=þýh÷‚jâê0qLæo-µöåõ$|8» $±¥ÝÛg¸7-ñä âèZ[BkMZÞõ¾ –†ñ˜¬^?=™µ«%ü±šœ·E„ø¬'¢GPA.qÈ® 0̓Ã?´=àÛ€×U×pÚ64áì+™“è¸Ö²¦,bÝ“(\ñ¢ÕÁÞO¿·®´›ªÝDQAÊ ˜É‰NB@æþðÎóØ=éc÷[[ »Øþó š÷»ïÜ÷˜_¨ÄÙb˜¸<9Îc˜ªÒNÝ˹ŠÙœØÊ훳<÷vöÏî$k[ܾõâFÐÕîŽHÃKHÁäŠAâtÊБñ 40öY± ï_šöu•¾õçžæÜy¶‰ŽÞ6¶V ŒØ5±ïžV´ð9í:^<`׸p£W¶nK™¶Ï*ðx\[ŒC3ßÜݹ¼ ºÖňâXÖ‘VôÐxÔ¬`á0ÝXgˆþ+µ²: =S1#Œîå„Y8;…®D_¯.ò¥™¦bå_‘ÑãRl-Ôj’‰•S(%0‘röÛ{æv}æëæ0XÍ0È ‘:×ýÙ°Uç»{ Lçê!Å¡ Šz.ñŸkžOmþâ Àç±mYtH.?>eñ¶¹ÚŒaºKAÄЮkÄf#¸¿Ã6;éáµ-n±Í÷î·j[v=¯4¼¼Š ‡Þªåg.µKP1H£‚œÅ1J%?/·Øåï)³¨ ûÖZmÛwmkt‰®ftb6Ôyè$0´MFGxmOŒy…ŽÆK/qo[Ïq-+ÝÃ^^à:É%­4.‚CcŒYÁo÷T¦ÂÑyŸäçQ ¼Kx_·U¿r@d)kz)äÇÄפ(v#k++ª‰(És!)„ÂsÖÞ7çç-qqo=ã.%¶Û,M¾‚Úa–Õ’½±÷–ò:GwÁsA4T@LŒÕpø.[ï{÷í·JË6èä6²Ï,rGpøÚ_¢f7º.kI†ƒj@c¸0À˜žÈÁRÜHq8…òú!ÎA{Œ1Æ*²_Ç@L]·4+w ÜR7Âý¤ÃÛq*´]±…»I@Á¨ï&U3Û—|îœÖ÷‹—œ¶u“.Û`Û˻ۆ¾Xà†BLŠ&¹äÏkƧiÐáØâÜNjàq›^Mã½EÓ­ÍÙ¶·µ…Ícå‘€™$ŽÑsN‘«SOh²Ö÷/Íx áÈoX{j÷Kåàmû9 cƒH–âwЈÜ XÖ´‡<ÒºOŠAw[‚ÅáŸ0Y‘²|=žîÇy}[öÖ²R—ýÑu'yµ¼$P…Š˜²nñQoEãGiä“t©Æ&€@:Ö¾cí,Ä–ÛøZd6˜±šàäma|ÜÀÃ#㸈½íÒæ5ÝÛ˜j\5¯‹ÏwŠÙ[‡ÉöÞ,÷ »Šg<­”L&pc_ 5kˆÖפtqíkãð+ƒò)°CG5^W,2ñðy3Û7 -«rhe’I¡i!½õÀ‘š$”6¬ÐÐÚê-©¦{)‡ånÙÌ|'˜+›ØËYqy‘±‘H@.î¡,v¦GZ;Q.àêp[õ‘ÀÝ œ8£ÅY¦ë¸S Ü9NÞ¾ífèW0h!)t9<tÛA¾1ÜG"ºfQÒ'D‹é¡Ç£šçfn÷emѳ­mÝ‘Ìæ"²–Úbh$%ì’Ëâ÷dÈÐ+š@cƒË:—gÊü]¶çÎ`w-ÄͲÆcdºŽx€âÀæJYÇ]â]p«šZÖ¾kC ðm™ñRɶ™³^*áæJÒ{|«7#oßsõ™u-&Ê58¦-cá£-ëÒZFD9ãXB™nÙ3 ‘åËooìýÛŒÛyOîl¥ÆàŽvÛÙ-´v·†9åîs¤|¶ñ²@ãÀM 3C…ý·ËÉ·¯³vÞváß§/ts¾xe.kt´5Žg¹…£‰„ÕÚšjÞ¼É8—Ýü1/Äv ˆ¿,ulì¢Ó^vmïqÇÝhÈ5’†FN2牗g¢.̳´RY¸“³ã‰J@H¦_?·wVøÄó)¼¼ÞÒØÞ¶óëË{‹had…†HÜ÷‚Ú5ů­x6¤ê!˜|ÖßÚÙw–ÖŽêÔÛ_ i¡žFÊÀæÊdž´ƒR›Jq4H.í,µ‰x3áѦq{Cfl…rdì/`dö”5Ñ oD@–áM÷Æ—®aVzùY¨‰¤R VJwí’ë;Wusƒ˜2憛Çcs7V­žHd–I{¢ÝwB@Ö†´‡K1$¸ÈÑcC«œÏíþ[ìèñ¯ÉÇ’¼¼¾ÆÁ;¢d¬‘÷Ú¤ï %ÄÇn‡¼êm8%ÿÃ.°³¶2e=–%­Î²Ö?‹Ë–Ýû#é·r¤›NS´×kå˜Ýæ|Ý6Ý¿¢ú: ¹"ª&cèŽsÌåØù)¬qQ\s~û­Xý0Øæƒ8sÞÜi%úuëqcš×CÖ+-²6Ö+uXÅu$;'!hÛ¸çsuJ"sIÖ‘Þ꺴éhpq‚ÕÜØË‡ Ä\Œƒ°w¸±ûû~qþ?Ë÷Œ€MZR’‘ê?Fïdkb2=¬â)w™½íNR¦p­?rs}òúÞ<î7·2Gqn¬-ÙÝÎÆHàטß>Gº2ø‘ýK‡ - ³6žñ™øœF/5a+á{ »™Úâs˜Ò扛Ý5úé ¾¼)…öwgC]¶Ö@‘E¥ýe¥â†b¤´û‰òšÎumÜ[€‹Žb£2?I~ÙG &¨¦bŠãßvÛÍÿÌbnl#{ì. ¯yŽ ˆEþðÙ´¼k{Ü$1é ¡ÀÐדi϶YÉì¡ÈAvö¶î>‰Ýr?2b«N–µ¥áÕ.!Ô"¡u}©‰­»ZÂö|å¨÷÷ ×RÍ“-n/å æßfŸ˜™BÆ `5LÑÊ8jˆÀŠªvªêo{Þ­›)º²9<îþÚ· ·ìf7Dæ²’¸ÜX:G÷¯Ôu€ãFpG+a·ì¬q;G? æ7·ù7‰çV1ÜÞ5ÐÚx¤ãq5èÈÓpVõ¹ŽeçSbÙ’0¶ã˜É'7oIHd];T»Æ"‚‚&)JÒ9}/8!åM†so¿2ÊĺI#–Y®ãˆ¸¸É0{.“K»¦1§h‘à’FѼcå¼¼Á»Åf‘’þêì6[†=‘Çn÷é ŒµÆF²£¼sÈ⡤^—„á>:ÖžãjȽ&g•—áóH\¶ÓÈ'åŠe<'D$àN²;gFrÂFÓuŽØ]Ã(%ŽšÖå{ÍKŒ†ÌÍaá€ZgòL†fÊÝnЇD­‰À¶Žd{Cèj:GBÖmv6{Ÿ’’Sqˆ²t‘–;Cdá©…í¡«\ÂÒ[QJÒ«›OÂ3ºxSök[*»A…Ë–2´å˜, Ÿ$Î_4„s¥Y¸( ÝϺmÀƒ¦•†±¾—Í.cdíà öØ«Z*ÒèñÚÚ8U¤Ž"¢£‚Ê]ÚǰvUŒÅ²Q¸´ÑÀ>óI-`b±Ê ŠÝ™Ž èíöÛ§sâ9‰Ù›¡Ö’Zd±’)bc£Õ{nA¸¡Ïwæû¯Î4µ¥y\û’Ù—›ŸÛ†\YdZÉ#‘áôµ˜R-oÞx„ý“BhÏñŸŽømÂwÔš³–³ÍÏp¶3ÖáŒ`”P²ØìÞCÝŸù¯ì»‹èðŠ»6™b‰»u bÜ;(n&à‰‘ŠÆ@4IÊÉ7\®Ì:iª©ºhQÓZÔîöŽAŸþŽã¼‹û/¯ýãýU¸Zo (/!1¿¬¶„~êñ–øÑk¢Û îÁš©é h3‘ËöÊ ±3g­ÓQ1!ûBHMÒ”7@§(ã~á¹-ÜDðÐ ¯Ghý}=«/W0;†4v;SúW-€`AI¤ñ“õ¶>ógL1Èö­Ôm_ÊÀ¢# €d÷ˆb¢q áF ì‘i}¬†Vôè §ej¹¼qLq,»„ÓãµwÄW–µƒÚß¶;œ+u..”AFd]Ã¥Žªª9QÊ¥XÇLÂM0&á@F±_ç2—âñÙ=¤p€vqð©“qàí¡“ŽÆµÇ†”ükƒÎqS~ÉÊqÀ„88“}º® ¢i]äˆdTCB˜Cw„Á  ¹ûN\ØÓ~í`t€4è©p=€¼Þï.:-'ûN<~¦´ÿ”ø:ÈJ¿•r£·î”r²ªS˜Ú{EGyC!L¡¹L ˜yGQ­òÖÆÖÆ.æÕŒú:O„ôŸ­i·W×WÒw·O/ÓÐ< }Kã󇊻WU\ ¯xjHN¥ B•¨WП @70Ò (¨Wóù)iM ˜jHíEUÀãá©Òš@8søêKUT¬šàÒàƒµø®áê⹦¢­Ûz-YRS3³²,â!¢cšM6UÓù9I›²`ɲE(ª§!PÔD¼ã›¶¹.Wçñøèe¸¿›pÈ⎒G½ÑÖ±Îq<Z ' -Ë—wv¶[ëyy#!´Žþ=ïpcÐðKœçÖ€8’HveÉÄ\Æãç.g¼W78ÙŸ9rm’ñ’HÈ[Ý•;.%Güz˲•·.¨_Ù.‘”&Š&áo‘3†»Ø›Ç‘˜­¹á’·ìcp{ f¶¸ŽÖ ×éxd°ÈÞ- â…Àæ¯7uÎÛæþéÁÈÉXܽÓÁkƒ£žÏ!-ÔÒC£•‡CÚjYÁÇVGácð?ˆ'mùÌQ‘2ùxc+‚)ÍÝd[Y킾î{FfÝŽ;UTKȱf‚ ‘Dˆ¨r>3É=½Í[MѼçÝÏè—kmä‘tì qƒÇh<–xÛ'³o&§¢Ž‚†l&§¾zÕùͱ÷œ»íöû6ÞáØ=çime’–(ÜæÚºÚâ*ÝJæ´µ6n|#]‡yB]¤,ï-wNÚj6mË4MÊí«‰®¬£{ÚÓ8žÒÚH."ä6C¦¤ ©]CÀod´§8”³¯L°¾$¹ø—k! œÜŒÞÕËP·Ì+û•t\X@Ü.n§¤|ë³¥©@Û…8¨žÙÎþZ;+e·rØ|[r¸Ý¹;›&4tÏc+"ŽF ¥ˆC•«¸Ò¤»_ånöYœ~FüØ^æbeéèŠéŽ‘ìt„¥’^êpáZ\2öEâÙêâÚ% &ÑRaž4±°NT³ò=ß‘n÷I ÌåVûä!,Dƒ§Ž ’Ä)ƒ†*š ;aîÖ?°vÑLn£uÝÎJÊ{H- ó”.•¦K¦šh¥Í$t¸T·m—/ºðøËËíÛ»£|b‹xl®b¸–âRÕ» ¸ŽÞ2û—BøØÇÜ6!Ró©Ž{Øßë<}–js{›?sÛnk­Ñi™¹‚Ë#Ÿ·.…ó?L"F½Îl.ÓH£ƒZçu4ôº<ŸY¼3q«jÞ\A`éÌ¥±¥´Â"À²oÈ‹„åB2bQTQm>EЊ¸.7ª;8ž.4]8f‚eQq/lB†;sf³¼Àæ>ÎÉáð9¨v͆JgIuqlø¸¾6LT/Š&†ŠM6†ÈâZÊè%w0xÌVÐÙ{’Ç#–ÆKœ»²¬‚Ù'½Ä !²HêšÇ§1 SP „ÞMmŒ­ìÞáå{'c(ûŸ‡I¬Òâü°îK½Œ5îñ+Òüw3ż°(úmGLž $Ý)©Žbæ2J¹œD¹-¯üÃgÝÉIÜãŵÌ0:Kv›{fÇ'}(£c s]^’€Òq™ì³¼œÄ6ÒöÉ—¸y/ ðI+Y1N^Îê3Åä‚)Ð H–2Zèâg ZÜ^ÙNf¯X9¬U“¸!¶øx¿ï6Z>èFÉVçláGŽ ‡» å#‘ó}AËd2‚C @‡ó¬g.7ŽO”÷‘ÙÙÏçÆï9²¶¶÷ t&àB@hoxâÈǼÆï°÷46 á¹ßoM·cÌ gÜÜÅ& ÷lÇa<°½²ˆL€ÔÜXæ´=¿i­$БCÓÜé”°`1^G¼ï±pH[Ò° "-ؤ•ÏzPtáÞâM슰öQbm›ÿvg9³µ]Ëݱ€ÎZeòRBË©omooced’ºI^Cdw‰F5•tÔYㆰëÛGob¹{ŸÇ9–Å\c¬™+ ŽÖá³Mu#£s#k#h.`ñªç:ŽÒâ’áÆm[²ÒâÓ…ÀÁ²¹ÂÅ™«æ;»(ÙÄÈ·6••[¹i)ø7+Òü_s±œ”8 ‹U"$RAEŽß'“ÅåyWÌÏml/²{;!ˆ‚Êãî‘î-eµ dRºøÏ…Ñ0js>É.$U¬t¬o±ûûcü1=Ý¥Žä³ÈËsÞ$Cû´ñÙ-í¾ù‚{©ç.H!qÖØ[Ž—7²FµÞ+Ô£ÛG¶­p+æ¬Þ5¸|´øØî ºŠl°½²G#zZö¹…ÃÆiŠÕ¦­wW*›u¬ÑjÅÕz!ÕÑae.2—×]÷kbÛ²O%BælWvß’F…±¥®&ñÖÌí­qO‚*§¢ð±Ä35U)’QUM®†L¥SÀyƒÎížec9¯‹±ºÉââÇI½‚ÙåË"/|ÑMUP$yàÖŽâ[ëÛ>÷œÙÜ¿¿º‚Æý÷¬¼µ–wh…ò67Å#ètU àI=~$ñ…ƒÂ„u›–.ì³d_™âÙË6Ñbã IzA^m m…Å1)‘'#ؼo¤#-Ð\ªo,š‚ —µ"\îÜÙÞi\^mlV*öÇcÜ⮡¹¼¾·–ÞGK×—ûªÊêxb¼¸ŠÄDÇ=­|¥’Ê_Ý´çéi€‚iT–eçi5öwåû)ÍÓn6¼äø…´f£mæã¹ä!›@B¢æ]ŒŽK*î1ºÉ‡pšFH†(€˜–_–—ŸøœÌv×ÃÅ€ž7Î#y…²d"7J†¼‚ipqÇdqìåCùá'åâ{b/h•̰¶2u‚.€GJÊî.x{q™pÁ) –°¥¡(Ç„¬-)mdëù¥‡*Ös:ow´<«ak1eÝ8Ar´:®Û®¦DJªb>]ÊýЋrÛ^b³7vÏÝy²k;W\±Ò~e¦h:£–kš^LJðx-rß9ƒ´_¸äÁÏmÆ[ÎÍ¿f×Gs8ÁŸœ"Q¨QñÔ¹§I.ioÑÁ}–ötáÝ)ð-öíµæ,N°)1=™–îÀµ†¾hk ¡~ª›¢×i&_Gjá]ävR¹M@Hr7û'˜å†w5 ­Ì9¼þwï×1\Œ{ŸCj x÷ÎgŒö¶Žs Í/.rZn Í÷ŠÆKq˜¼F+î°ÝÈ+¼ ¨Ÿÿ;ÅkZÁÓG®ÔáªêɸÿˆHû»ŠÓKà v–µµ<0ë…¶ÖÞKá#‰L#XWåÁyc[¶™2ìcgCIÄ¿Ay3¶“z vÊ3F5NÐMNÌÊ%¿ºUÁëœÍ“#·9­·7·÷vFûogy†Î\HÇÈÒV6”/©új[Eç;;,×/ó[[ï–v™Y®m¥gÞel,sà]G;¦¦´„¶´«xG Ø¡€ýšÐãzÚA/bæ{îRøŠŽ$¬Ø·™­ V’7[yéVëQe)¬ì¨¦váÚDœµÔ~9ñß1¯>åw÷Kì=³-ŸÜÉ¢áíÇ9;N™\×ø…±—ïŠð]†å±_ ì»o¼Ûýâ×%;§oxÍP´Þ‡‡JÚÖ6–øÀ¼[Æ´â¹ÆcÁ66OâžïÌíx—áÌ0ãëýÑrÍ'”"qÃÅÇ(ÀeâÛ[)G³2ÎÌÉT£NÈ˵|c¦b*]á)pÛC|f¶×,-6t»spü^ËC fÍýÌxwvó1£ccuL$ |tp-4ä÷ÕÅç7ÝÆä7†øq÷bY÷–÷Œktëhˆq{Î’#,.kêÒǃ2â6ÃÊW¯´s!¹¸a-¦y79ÇŒ.9hØI[¡ÖöÄ X¸÷ë5púnJ&Ìͪ²fWtw„7†&åæwla¹y·ã·šæ\n\Kvèc|Œ„Êó4®{Ú#š$qkHmxt ‹xâ³¹=å˜|ÑAö4ÇnÙÖ>QDQ†µÄ=Ìc]¡µp&œzW G X¥À¾Í¸q½-0—±³5õ){Å ÇVtc¼Ô„«I©¦zM¼ÁÔX ”ÖvTS;pí "NZÌ¿›;瘷sºû¥îÙ–Ïî¤Ñpöã‹È¦’¹¯ñ c.!Þ)à±­ËbþÙvÿy·ûÅ®JwLÞñš¡i¼•µ¬m-ñ}oÊíë ã‰N:øÄILcFÀæO•¬ "örÅ’É;q…š´f·:NU‹ôE’‰qº¡?htÁ2”1J:–w¸­y!´\Üuì—ØŒ­ÕͳaÞ[?xüÉú{jS¨ÐHØ19|4üÔÜm7¶¬µÈãî­á™Ò7¹t’w%¿¶„5Ô š‘AR@]!ÁäCxl镸P».;~^ 7Ø·n*y?iJä¶¼#cœOÚwDDƒr¤Œ©¡ž´p“s @ á}  ÖëÍËÉ/6F+šx»yá¾ÂßA|اa†cÞ"žjYÞ5Í/®–ðêZ¿.­™mºoö üÑIk”´–ÔɻȄÍi’)XáÁÚpoV§q]OÆÞC‡½3Ü䦠}ÄQPøfÂA3&£tmüzÜÑ.‚¨ˆ¹AåÀ/WIR—C¢¡4­¯’ø ¼6Å‚÷*?úöZY2DÔ-ÑÖ* H-‹»ii<×U¯ó;/o“Ý’ÚãÿþÑ–pBvãA¡2k Ž–±,î õbÕçÕJU6ÔªªR©ÕÑS¤§TÀ§@ù¦‰Õ()·ÇJ€§T ¥IjuJU6ëPZR•Mº{•:JuL XTª)TÛãïÒÒT §UIjª¥:ê SªR©·ÇSBR•N­¡R˜)J¦Ý}ÚE¡:¥6éRZR‚•©Õ()·ÇS¥UR‚]êIÕ)Tëè© ER•MºT–ªªPSž¤µ:¥6õ Fš'T€§VФS›u¥@R›t©-N©ANº’ÔêÛ§wŠ µ:¥9ü”¨SªR©·]”¸u§T€¥-=‰Õ(mAjuHêÚ%©Õ (<úÔé¢u^ép>]lx!ç‰ÿÜGݯ˾`~þfÿkÞ~±"ûÿfþèb¿fÚþ‹Ð-ÀÛäþŠÔVȦàmòE_^.ï]Äïþ!sOúȹk÷?”ô§lÃØïÔá_–\ÂýþÎ~ؼýfEUèKOR„)B¡ P…(B”!J¥VR NªÀpðÒÒŽ à<ÃSDø…`6”QíWÒNƒ©\B*B°0éEPUÀãáå©Òš¸e" uWxjhª¸Ÿ’‘jÀÜÃRBªžµp8Ò⎀p¡>)ÜÃJ€¢¡\Î*)«ù‡«üTˆíN©üþJ’ÔÕÀüÃRZRƦˆ¨HŠ<)ñJšT¡0UÀáÏ¥IjuHš’ÔêúT–§T€q©¢*< @è¥áUT §]*U n4‹SªP??’ µ0RüÃRZRœõ4)Õ)TÛÕK‡ZuJ w-=‰Õ )·_v¤µ:¥:ª SªPR§JuHU6éîE/ iANà¥@˜=‰AMºôÔ–§T §UAjª¥:êt§T¥SnžçôT‘ÚR‚ÁJ0R‚›uéïÔ–¢«!¸ƒÏîóôž0’ym7¶ 0Õ•‡ÐI´š²…—mf¸šp”ê§U“!f»ñ™3p ŸfÚòh aű-²Vðܺädr÷ä–wfàF BŽv Þ_²(¶ýÝ»$Ý“XÍ$-ƒîXØm.Ö!/:Í@¡v¿³Æ”é+ ÁNºÞ‹V§T¥Wm*´ê”î šÁJU6ëîÔ–§T ¦Ý;¼U%©Õ()Q¦ ª˜ªíñÒ§juJ uyB•N«)pŸP2Ùœ{jb¦3£¶Ó‘vÎk}vJ¨{*"}ŠQÎÍ b DÆÝ©œ¼—¤‘Dʸ”S17ʧ˜ï>^ßïl”å2’7d1Ѿls``ûÄ‘8½½åήóº.Ò]‚š‡BÝëlï M­e,¶ ;¥Í{c½t¯=Ë$hiÑàƒdÔÕJPq˜W2‡1Îsç0œç9„Ç9Œ:˜Æ1„DÆ0Ž¢=ñ¯HîÃF(Ò5jx’® wN“ÔŠ¥zÈ4¨S›té¥@UU()ܨ)TÛ­Ijª¥*›tîæ¨ÒSª`S¯¢’uJU6øéi Õ()ÕPZR‚u©Õ)TÛãïTUU()ýaý“¯bb©·_v‘hN©J¦Ý* SªPR µ:¥*›z†• uíJ t‡”*hR•N¾ŠE¡0R•Mµ©Õ()RZª©J¦Ýz{õ4!:¥:CʨR‚{B§H= Õ()¶¤µ:¥;‚ µ0R•MºìšQ:¤:CËKÂS}¨ )¶¤µ:¥óÔ¦ B©Ì=CRZR‚ÁKŠuJU6ëÝã¥@RU%©Õ{¿ÀçÿÀÄñŸþAµ~[s÷÷9û^óõ‰èÌýÏÄþ͵ý •¨-•J¿\\ÿÞ»‰ßüBæŸõ‘r×î(ÿéNØÿ‡±ß©Â¿,¹…ûýœý±yúÌ‹«Ð–ž¥R„)B¡ P…(B”!J¥R„)B€ÃÓJ:«€vR¡B¾µ4N¤-@Â" ô«ûƒú)'NÅp0 ©*àna¢‰Ôp?8xªt¦¬ï *U CmMuV‡EN”ü ÜÃSDWµ\4qO‡R¸(OZ@8óøéPÀááä©Òš@0øZ’ª¸ŸÉS¥:¤ó I ×µ ž• +ØúQáOÂ×KObuH};¼U%©Õ |5Sª@>ßðT–§_­ (>TN©MºRð¦”×Jƒ©Hæ¡©-N©üþJ’Ôê”Ì5©Õ )J…:¥6øûµ¥@R‚]‹Sª@S¯¢ µ:¥6éRZª©JšS¡:¥*›ixQT §pTÐê”Û¯»RZR‚U%ªª”¨§buJU6øéSµ:¥:º)Pê”Û¯»RZR‚›tîñT§T€¥Nšt'TÅSoަ©Õ()Ò¨ uJ uôT–§T¥SmAjª¥;‚§IêN©Š¦Ýi'T¥SnžåMN©ANà©-L¥SmAjuJU:ªhUU)Tëò $Wð¦*›z†§H)Õ()ÕRZª©ANº‚ÔꔪmþŠ’ uJ w*&bb©·_ Ô–§T §UIjuJ sÔªªPSo»Zšꔪt‡”)Q:¦:ú*KSªR©¶¤µ:¥?¬* SªPSn½=úšR•MºyB‘:¥<[*KUU)TÛRZR‚]©Õ()Ð>í*R•MºtÔR‚”´ö'T¥SmAjuH wIjuL t»SBªB©·Nžõ/ uJ RÒ:“ªR©·»š µ:¤*KSªPSn½=ÚÔé¢u^õp5ËaÛÃÏ ÿ'µ¯Ë.a~ÿg?l^~³"ýÙŸ¹øŸÙ¶¿ bôµ²©BàK‹Ÿû×q;ÿˆ\Óþ².ZýÏåý)Ûðö;õ8Wå—0¿³Ÿ¶/?Y‘cÕzÓÔ¡ P…(B”!J¥R„)B¡ P…(B”!JµÔB„UX>ZZSVÔУÀ¯­*'R€Â‘PUÀô'CÔ®¡íVw†‘ ðêWó…-)ñWs I¨ª¸zii «Ã¢¤µ?¸jh{RèâW…$ëÚ=4i¯b¸:*t”ê<úÔ–§Up?UIjuìHæ’¯j@Sž—ëØÌ:QÀô¢½©üþJ)¤óPÔ–§T€~%IjuWó IjuíJ sÒ¡N© ~aÓgø©pëN©@üþJZ{ ˜uØ5%©Õ )ÕPZR‚›{½Ú’Ôê¥Å:¥6ëÝÏJH m÷*KUU()×ÑRZФ*›j UU()ÏJ…:¥6øûµ©§juJ utRÓTê”芒Ôê”ÛÝîT§T€¥MèN©Š¦ßv´©ÚR‚!ÑJ•N©AN¾Š‚ÔÁHU6Ô–§T ¥MRuL íצ¦©Õ)TÛ§”)iUR‚ÁRZ˜)J¦Ú‚ÔꔪuTЦ PS¯ÉSDꘪmêZjR‚ÁRZR•MºÔªªR©·Or¤‚R‚ŸÖ4ESM¾>ý"ÕUJ uT§T §]IjuJUvøêhSªPS«¢•ª¦:¤µJU6ÔªªPR§JuJU6ëÓß©¡N©J¦Ñ(R N©Nà©-L¥SmAjuH utT–ª1Tëò M *”ªmñÒ UT ¥IjuJU6ëPZR‚]%©Õ()×¶¦…:¥6øéP'T §=-=‰Õ()·Z‚Ôêêè¨-UT §_»J…J mñ÷iJ‰Õ()ÏS§±0W¾Ü ð »ÿDÿÉÍkò·˜_¿ùÏÛ¿¬È¿Aö_îv'öe¯è½­=lªP…øâçþõÜNÿâ4ÿ¬‹–¿sùGÿJvÇü=ŽýNùeÌ/ßìçí‹ÏÖdXõ^„´õ(B”!J¥R„)B¡ P…(B”!J¥R„)B¡ P…¨‡xh¢uVóÒÒŽ à` M < ÚÒ¢u*ÀqþºÀ«û»ô“ãÔ®¡íW=*ü àpðòRÒš¸˜jHíEUÀãáå©Òš¸9ütˆ)‚z•ÀÃSDTu«èL} Áà\¯j@8ôÒ-MX‹J*=5BuW‡E"ÔÁJzš'^Õp?=.)øù†—U ŸÉHµ:¤ó»¤µ:¤óÔéN©üÃRZRœô¸§^Ä¥So»Z\ª@?õ…-)Õ(nµ©Õ )ÕRZRÇž¦‰Ôx‚T¸õ¦”è%*U )·Nš’ÕUJçòT¦ B©¶¤µ:¥*hSªPSn½4¨ªPSnžå"Ôê”þ°¨-L…SmIjuJ TЧTÀ¦ÝziSµ:¥6éîTéªuH wIj`¥*›j UU()Ü4)‚˜ë¥DU()·Nš5U^Ô §pT–§T¥Snµ©Õ)Tê¥BR‚}4LÅSoŽ‘juH uTªª`S® µ:¥*»|t¨SªPS¸*hªb©·_v‘juJ mÒ µ:¥* SªR©·]ƒJŠª”é(TÐ'TÀ§_EIjuJU6øêKSªR©ÕÑPZ˜)ANò *'T¥SoPÔ¯jPS¸)§T¥Snµ©Õ)TÛ§¹PZª©N¾ŠTN©J¦Þ¡© 'T §U"Ôê”ë¨-N©J¦Ý=Ïè©-N©ANà©LÄ¥So¿J:¥:ªKSªPS® µUWÖÑ%]¹nÕ¹ ¢îVMS/(¨¢§ ßt®ŽFòÛa6Jõá–DéãÐÖ°|.Õ•¥ÅýäV6­/¹šF± t—8Ь•ú#àêXk>1±Š;­XµnSi  [·M ^PܯɌÖEÙŒÍÞ]⺺–b; ¯sÈÿÞ_¢Ø«&ã1–ØÖš¶Þãè¿äYÃXÅßR„/À—?÷®âwÿ¹§ýd\µûŸÊ?úS¶?áìwêp¯Ë.a~ÿg?l^~³"Ǫô%§©B¡ P…(B”!J¥R„)B¡ P…(B”!J¥R„)B¡ P…¨‡†Šê®ç©ÒŽ À`ð *#ˆVÖ•¯j¸—øp8PŽ!\„Tu«„6Ò 'àV‡EN’š¸˜iÚUÀüáS¥ÀÀ>I Ô«Ä)Q:„€zÇ©\ Ì4¸ëÚÏËHµ5p8xJ’T€qðòÔéM\útÔ–§R54N£ëH ñHÛ¯M*Ф‡E-)Õ yõ¨-N©üüžåIjª¤=MT€¥.)¥6ëÓJ:¤õR-N©@ýu%©Õ\Û¥AjuJ MªPSnÞ*<)¥óòûµ4I×± )·¨jKSª@SŸ’¤µ:¥*›u¨-N©ANª\SªPS iP'T ¦Ý:i§T §=Aj`¤*œÃ­AjuJ uR¡N©NºšêÛ§M"ÔëÚ”¨-UT¥Snµ%©Õ)Tê©¡LÀ§]*ꔪmñÔ–§T §UIjuJ uÔ§T¥SnžåI:¥;‚•uìJU6ëîÔ–§T §UIjª¦* SªR«·ÇSDê”êò…*ê˜ëè©-N© ¦ßAjuL wNžÅUJ ôjhŠ¥6éÓJUR‚ÁRZSMµ©Õ!Tê©ÒSª`S¯¢¦‰‚”ªíñÒ N©ANª’ÕUJ uÔ§T¥SnžçôTé)Õ()Ü“±1TÛ¯»S¤'T §UIjuJ uÔ§T…SoާJª§!Œs¥)Œs¥ „Æ0è DDDkŽI#Š7K+ƒbh$’@$’x:ÉàÆÇÈñ@¹î4 ’O@t•˜¼:`雎àa-$ÅRn*C3l¢c¼–ð€zBÅ÷ªGÞ”yKßJøŸæ´ÎBý™´åï1¥Ãï3´ø²i5î£=l¨«Ü8:šEZM~©å,.12·sî(ô_Só¸qeGûGŽ§ÓƒZx·í:”ýâëE;RÞhÐ8"@0né˺óxkåô:ìê¥_ŸÎ"ý’ØâïÉwæEޏr¡¥² åsß-‹1iŒci[²qôô‹xÄ~ÄúRè»~r¢EVYR¦(qÔÃõvÝþp¹™¶vý†Û°±Á>Çg ´n’£#£‚6ÄÂòÛÖ4¼µ€¸µ­Ö€ð,Ïòç²s™{¬ÕÝÖU·W—2ÎðÉmÃå{¤ph6Î! ¸†‚ç)ROŽÿ´%·óÎJúVØü£Yîk{¿oy ÏoXß– ƒé™+mìŠ~ЖßÏ9+é[cò;ÜÖ÷~ÞòžÞ– ƒé™+mìŠ~ЖßÏ9+é[cò;ÜÖ÷~ÞòžÞ– ƒé™+mìŠ~ЖßÏ9+é[cò;ÜÖ÷~ÞòžÞ– ƒé™+mìŠ~ЖßÏ9+é[cò;ÜÖ÷~ÞòžÞ– ƒé™+mìŠ~ЖßÏ9+é[cò;ÜÖ÷~ÞòžÞ– ƒé™+mìŠ~ЖßÏ9+é[cò;ÜÖ÷~ÞòžÞ– ƒé™+mìŠ~ЖßÏ9+é[cò;ÜÖ÷~ÞòžÞ– ƒé™+mìŠ~ЖßÏ9+é[cò;ÜÖ÷~ÞòžÞ– ƒé™+mìŠ~ЖßÏ9+é[cò;ÜÖ÷~ÞòžÞ– ƒé™+mìŠ~ЖßÏ9+é[cò;ÜÖ÷~ÞòžÞ– ƒé™+mìŠ~ЖßÏ9+é[cò;ÜÖ÷~ÞòžÞ– ƒé™+mìŠ~ЖßÏ9+é[cò;ÜÖ÷~ÞòžÞ– ƒé™+mìŠ~ЖßÏ9+é[cò;ÜÖ÷~ÞòžÞ– ƒé™+mìŠ~ЖßÏ9+é[cò;ÜÖ÷~ÞòžÞ– ƒé™+mìŠ~ЖßÏ9+é[cò;ÜÖ÷~ÞòžÞ– ƒé™+mìŠ~ЖßÏ9+é[cò;ÜÖ÷~ÞòžÞ– ƒé™+mìŠ~ЖßÏ9+é[cò;ÜÖ÷~ÞòžÞ– ƒé™+mìŠ~ЖßÏ9+é[cò;ÜÖ÷~ÞòžÞ– ƒé™+mìŠ~ЖßÏ9+é[cò;ÜÖ÷~ÞòžÞ– ƒé™+mìŠ~ЖßÏ9+é[cò;ÜÖ÷~ÞòžÞ– ƒé™+mìŠ~ЖßÏ9+é[cò;ÜÖ÷~ÞòžÞ– ƒé™+mìŠ~ЖßÏ9+é[cò;¼Ö÷~ÞòžÞ– ƒé™+mìŠÁ솷ûç%})l~Q£çwšÞïÛÞBóÛÓù`Ø>™˜ò¶Þȵý¡íÏž2OÒ–Çå*_;œÖ÷~ÞòžÞ—ËÁôÌÇ•¶öE?h{s眓ô¥±ùJÎk{¿oy ÏoOåƒ`ÿy˜ò¶Þȵý¢-ÐþùÉ?J[”©|íó[Ýû{È^{z,;ÒòþVßÙU¿h«{猓ô¥±ùJŸÎç5½ß·¼…ç·¥òÁ°}31åm½•kûEÛßXv¥åü­¿²«~ÑÖÿÏ#éKgò/®jû¿oy ÏnGËÂôÌÇ•¶öU¯íoüï‘þ”¶)ÑóµÍ_wíï!yíÈùbØ^—˜ò¶þʵd„|d¥-ŸÊt¾vy©îý½ä/=¹?–-…éy+oì«_ÚFç|ôµùR—ÎÇ5=ß·ü…ç·%òŰ½//åmý•kûI@ü“¶¿*Qó¯ÍOwíÿ!yíÉü±ì/KËù[eVd¤{äo¤í¯Ê”|ëóSÝûÈ^{r>Xö¥åü­¿²­iX/ò/Òv×åJ>uù©îý¿ä/=¹?–=…éy+oì«PöKÁ‡z_"ý'm~U¥ó¯ÍOwíÿ!yíÈùcØ^——ò¶þÊ­ûLAüí‘>“¶ÿ*Ñó­Í?wíÿ!yíÈùdØ~——ò¶þÊ {&¡½-‘>“¶ÿ*ÒùÕæŸ»öÿ¼öäþY6¥åü­¿²«~ÓpŸ;d?¤­¿ÊÔ¾u9§èÈ]ûr>Y6¥åü­¿²­iØ_²ÒVßåj_:|Òô ¿ä.ý¹,ÛÒòþVßÙUƒÙ? ÞÙé+sòµ:|Óô »öä|²ì?KËù[eZþÔß:ä/¤­ÏÊô|éóKÐ6ÿ»öäþY¶¥åü­¿²«²Š?½rôÉ[Ÿ•é|ésKÐ6ÿ»öä|³l?KËù[eZþÔpÿ:䤭ßÊô|ésKÐ0BïÛ‘òϱ=//åmý•[ö¥ˆù× þñ·+ÒùÐæ `<…ß·#åŸaú^_ÊÛû*×ö§‰ùÓ }#nþX¥ó¡Í@Ày ¿nOåŸbz^_ÊÛû*°{*bƒûÓ }#nþX£ç?š>€ò~Ü–}‰éy+oìªßµTWΗÿÒ6÷åš>sù£è!wíÉü´lOKËù[eVý«bþt¿‡ÿxÛß–i|çsCÐ0BïÛ‘òѱ=//åmý•jÊèÀïIßßHÛß–i|æóCÐ0BïÛ‘òÓ±}//åmý•[ö°ŒùÎýúBßüµKç3š€ò~ÜŸËNÅô¼·•·öU¨{,£CûÎýúBßüµKç/™þ€ò~Ü–­‹éyo+oìªßµ¤wÎWçÒÿåª>rùŸè!wí¨ùjؾ—–ò¶þʬËhðïI_ŸH[ÿ–èùËæyÿö!wí©üµl_KËy[eZþÖñÿ9_H@~[¥ó•Ìÿ@Àù ¿mGË^Åô¼·•·öU`ö]0ï+ìz_À~[¥ó“Ìï@Àù ¿mOå¯bú^[ÊÛû*·ívÄ?¼o¯ãà?.RùÈæw `|…ß¶£å³cz^[ÊÛû*°{/™÷óü|åÊ_8üÎô‘»öÔ|¶loKËy[eVf0ïHß?ÇÀþ]£ç™Þò~ÚŸËnÆô¼·•·öU¯í„Ïç ãøøË´¾q¹›è8#wí¨ùmØÞ—–ò¶þʬÌFýá|u¿‚ü»GÎ/3}änýµ?–Ýéyo+oìªß¶3_œ/ã ¿/RùÄæg à¼ß¶£å»cú^[ÊÛû*°{2÷…ïütåê_8|Ìô‘»öÔ|·lKËy[eVfSpïH^ßÇAþ_£ç™žƒ‚ò7^ÚŸË~Çô¬·•·öUoÛ1¿ú}ëütåú_8\Ìô‘ºöÔ|·ìKËy[eVfrþzõ½ƒü¿Kç™~ƒ‚ò7^ڟˆÇô¬¯•·öU¯í úuéül'Ô¾p9—è8/#uí¨ùpÙ—•ò¶þʬÍ$ƒüúóþ6ê _7üÊô‘ºöÔ|¸ìJÊù[fVf¢aÞ}yÿ õ 7üÊô‘ºöÔþ\vG¥e|­¿³+~ÚÉÿ¦Þ_ÆÂýCKæû™^ƒƒò7^Ú—‘éY_+oìÊÁìÙ žÞ?ÆBýEKæ÷™>ƒƒò7^ÚŸË–Èô¬¯•·öe`öm”?Ïoã!~¢¥óyÌŸAÁù¯lGËžÈô¬¯•·öeoÛt?Ó/ã!¾¢¥ówÌŸAÁù¯lOåÏdúVWÊÛû2°{7ôÿ<¼:ÞC}GGÍß2}än½±.{'Ò²¾VßÙ•¿nóË¿øÈ¨èùºæG àü×¶#åÓdúVWÊÛû2·íÈoôË»ø¸©*~ny‘è8?#uí‰üºlŸJÊùX=™jÎSùåÝü\?Ô”|ÜsÐp~FëÛòë²}++å öeoÛ ÿéwoñqRÒù·æ?¡a<×¶'òí²}++å öepöu(çw`ô»ˆú–›~cúÈÝ{b>]¶O¥e|¤̵gb¡Þwvõ-/›ncúÈÝ{b.Û+Ò²žRfVý»–ÿJºÿЉúš—ͯ1½ än½±.û+Ò²žRfVgŠáþuuõ5/›>czÈÝ{b>]öW¥e<¤̬Ï5üêêþ*'êz_6|Æô,'‘ºöÄþ^6W¥e<¤Ì­ûz¸ÿIºŠŠúž›>czÈÝ{b>^6W¥e<¤̬Ïw!þstõE/›búÈÝ{b/;/Ò²žRfVý¾]¤]ÄÅ}QKæÃ˜¾……ò7^Ø——éYO)³+~ßnÿÒ.âbþ¨¥ó_ÌOBÂùŸlGËÖËô¬§”ƒÙ•ƒÙúð;Î.âbþ©¥ó_ÌOBÂùŸlOåëeúVSÊAìÊßõyÿŸ¹¿‰ŒúªšîbzÈÜûb>^ö_¥e<¤̬=÷û—ø˜Ïª©|Öóа¾FçÛù{Ùž•”ò{2°pø?ßîOâ#>ª¥óYÌ?BÂùŸkGËæÌô¬§”ƒÙ•¿ê ÿÿ=rõ]/š¾aúÈÜûZ/›3Ò²žRfV$ýþãëqõ]5|Ãô<7‘¹ö´|¾lÏIÉùH=™[þ¡R!ÞZãþ"7êÊ>j¹…èX_#síhù}Ùž•”ò{2dx ß.ò—Ã^Rv;¢ÃÙÇÚu…qKüÓsF6×Çë6Š«§ äùÙlxs§É8£,4>0ø]÷øB9Ê ž0©¨Q.ó‡w<ÂUŠ[Þ&è5yVëæ†ùÞŒ0g²¾Èš÷, Š/¢¬Œ4>FMdv¯AÛÛ iíw qq²è w®¬’}4{Ë‹kÖ¤} Ѽk†!,–艧۔¥ÔÛ…×PþºsÖ€·Þ…)HP)C@Є+P…(Bø|]¯ü'Ñ÷¿ûÍ5¡ æùÔüÚ§Èž§æÐ…>Dõ?6„)ò'©ù´!O‘=OÍ¡ |‰ê~mSäOSóhBŸ"zŸ›BùÔüÚ§Èž§æÐ…>Dõ?6„)ò'©ù´!O‘=OÍ¡ |‰ê~mSäOSóhBŸ"zŸ›BùÔüÚ§Èž§æÐ…>Dõ?6„)ò'©ù´!O‘=OÍ¡ |‰ê~mSäOSóhBŸ"zŸ›BùÔüÚ§Èž§æÐ…>Dõ?6„)ò'©ù´!O‘=OÍ¡ |‰ê~mSäOSóhBŸ"zŸ›BùÔüÚ§Èž§æÐ…>Dõ?6„)ò'©ù´!O‘=OÍ¡ |‰ê~mSäOSóhBŸ"zŸ›BùÔüÚ§Èž§æÐ…>Dõ?6„)ò'©ù´!O‘=OÍ¡ |‰ê~mSäOSóhBŸ"zŸ›BùÔüÚ§Èž§æÐ…>Dõ?6„)ò'©ù´!O‘=OÍ¡ |‰ê~mSäOSóhBŸ"zŸ›BùÔüÚ§Èž§æÐ…>Dõ?6„)ò'©ù´!O‘=OÍ¡ |‰ê~mSäOSóhBŸ"zŸ›BùÔüÚ§Èž§æÐ…>Dõ?6„)ò'©ù´!O‘=OÍ¡ |‰ê~mSäOSóhBŸ"zŸ›BùÔüÚ§Èž§æÐ…>Dõ?6„)ò'©ù´!O‘=OÍ¡ |‰ê~mSäOSóhBŸ"zŸ›BùÔüÚ§Èž§æÐ…>Dõ?6„)ò'©ù´!O‘=OÍ¡ |‰ê~mSäOSóhBŸ"zŸ›BùÔüÚ§Èž§æÐ…>Dõ?6„)ò'©ù´!O‘=OÍ¡ |‰ê~mSäOSóhBŸ"zŸ›BùÔüÚ¾ô=Oì; ?û¿à¡ é¡ P…(B”!ÿÙopenchange-2.0/apidocs/html/libmapistore/index.html000066400000000000000000000033071223057412600225440ustar00rootroot00000000000000 OpenChange mapistore library 2.0 API Documentation
OpenChange mapistore library Documentation

Creative Commons License
Creative Commons Attribution icon Creative Commons Share Alike icon
This content is licensed under the Creative Commons
Attribution ShareAlike License v. 3.0:
http://creativecommons.org/licenses/by-sa/3.0/

openchange-2.0/apidocs/html/libmapistore/mapistore_8h.html000066400000000000000000003560261223057412600240500ustar00rootroot00000000000000 OpenChange mapistore library 2.0 API Documentation
mapistore.h File Reference

MAPISTORE general API. More...

#include <sys/types.h>
#include <sys/stat.h>
#include <stdio.h>
#include <time.h>
#include <unistd.h>
#include <stdint.h>
#include <stdbool.h>
#include <tdb.h>
#include <ldb.h>
#include <talloc.h>
#include <util/debug.h>
#include "libmapi/libmapi.h"

Functions

enum mapistore_error mapistore_add_context (struct mapistore_context *, const char *, const char *, uint64_t, uint32_t *, void **)
enum mapistore_error mapistore_add_context_ref_count (struct mapistore_context *, uint32_t)
const char * mapistore_backend_get_installdir (void)
init_backend_fn * mapistore_backend_load (TALLOC_CTX *, const char *)
struct backend_context * mapistore_backend_lookup (struct backend_context_list *, uint32_t)
struct backend_context * mapistore_backend_lookup_by_name (TALLOC_CTX *, const char *)
struct backend_context * mapistore_backend_lookup_by_uri (struct backend_context_list *, const char *)
enum mapistore_error mapistore_backend_register (const void *)
bool mapistore_backend_run_init (init_backend_fn *)
enum mapistore_error mapistore_del_context (struct mapistore_context *, uint32_t)
const char * mapistore_errstr (enum mapistore_error)
enum mapistore_error mapistore_folder_create_folder (struct mapistore_context *, uint32_t, void *, TALLOC_CTX *, uint64_t, struct SRow *, void **)
enum mapistore_error mapistore_folder_create_message (struct mapistore_context *, uint32_t, void *, TALLOC_CTX *, uint64_t, uint8_t, void **)
enum mapistore_error mapistore_folder_delete (struct mapistore_context *, uint32_t, void *, uint8_t)
enum mapistore_error mapistore_folder_delete_message (struct mapistore_context *, uint32_t, void *, uint64_t, uint8_t)
enum mapistore_error mapistore_folder_get_child_count (struct mapistore_context *, uint32_t, void *, enum mapistore_table_type, uint32_t *)
enum mapistore_error mapistore_folder_get_deleted_fmids (struct mapistore_context *, uint32_t, void *, TALLOC_CTX *, enum mapistore_table_type, uint64_t, struct UI8Array_r **, uint64_t *)
enum mapistore_error mapistore_folder_open_folder (struct mapistore_context *, uint32_t, void *, TALLOC_CTX *, uint64_t, void **)
enum mapistore_error mapistore_folder_open_message (struct mapistore_context *, uint32_t, void *, TALLOC_CTX *, uint64_t, bool, void **)
enum MAPISTATUS mapistore_get_queued_notifications (struct mapistore_context *, struct mapistore_subscription *, struct mapistore_notification_list **)
enum MAPISTATUS mapistore_get_queued_notifications_named (struct mapistore_context *, const char *, struct mapistore_notification_list **)
enum mapistore_error mapistore_indexing_record_add_fid (struct mapistore_context *, uint32_t, const char *, uint64_t)
enum mapistore_error mapistore_indexing_record_add_mid (struct mapistore_context *, uint32_t, const char *, uint64_t)
enum mapistore_error mapistore_indexing_record_del_fid (struct mapistore_context *, uint32_t, const char *, uint64_t, uint8_t)
enum mapistore_error mapistore_indexing_record_del_mid (struct mapistore_context *, uint32_t, const char *, uint64_t, uint8_t)
enum mapistore_error mapistore_indexing_record_get_uri (struct mapistore_context *, const char *, TALLOC_CTX *, uint64_t, char **, bool *)
struct mapistore_context * mapistore_init (TALLOC_CTX *, struct loadparm_context *, const char *)
enum mapistore_error mapistore_message_get_message_data (struct mapistore_context *, uint32_t, void *, TALLOC_CTX *, struct mapistore_message **)
enum mapistore_error mapistore_message_modify_recipients (struct mapistore_context *, uint32_t, void *, struct SPropTagArray *, uint16_t, struct mapistore_message_recipient *)
enum mapistore_error mapistore_message_save (struct mapistore_context *, uint32_t, void *)
enum mapistore_error mapistore_message_set_read_flag (struct mapistore_context *, uint32_t, void *, uint8_t)
enum mapistore_error mapistore_message_submit (struct mapistore_context *, uint32_t, void *, enum SubmitFlags)
enum mapistore_error mapistore_namedprops_create_id (struct ldb_context *, struct MAPINAMEID, uint16_t)
enum mapistore_error mapistore_namedprops_get_mapped_id (struct ldb_context *ldb_ctx, struct MAPINAMEID, uint16_t *)
enum mapistore_error mapistore_namedprops_get_nameid (struct ldb_context *, uint16_t, TALLOC_CTX *mem_ctx, struct MAPINAMEID **)
enum mapistore_error mapistore_namedprops_get_nameid_type (struct ldb_context *, uint16_t, uint16_t *)
uint16_t mapistore_namedprops_next_unused_id (struct ldb_context *)
enum mapistore_error mapistore_release (struct mapistore_context *)
enum mapistore_error mapistore_replica_mapping_guid_to_replid (struct mapistore_context *, const char *username, const struct GUID *, uint16_t *)
enum mapistore_error mapistore_replica_mapping_replid_to_guid (struct mapistore_context *, const char *username, uint16_t, struct GUID *)
enum mapistore_error mapistore_search_context_by_uri (struct mapistore_context *, const char *, uint32_t *, void **)
enum mapistore_error mapistore_set_connection_info (struct mapistore_context *, struct ldb_context *, struct ldb_context *, const char *)
enum mapistore_error mapistore_set_mapping_path (const char *)

Detailed Description

MAPISTORE general API.

This header contains general functions, primarily for users of the store (rather than storage providers).

Function Documentation

enum mapistore_error mapistore_add_context ( struct mapistore_context *  mstore_ctx,
const char *  owner,
const char *  uri,
uint64_t  fid,
uint32_t *  context_id,
void **  backend_object 
)

Add a new connection context to mapistore

Parameters
mstore_ctxpointer to the mapistore context
urithe connection context URI
context_idpointer to the context identifier the function returns
Returns
MAPISTORE_SUCCESS on success, otherwise MAPISTORE error

References mapistore_add_context(), mapistore_backend_create_context(), MAPISTORE_ERR_CONTEXT_FAILED, MAPISTORE_ERR_INVALID_NAMESPACE, mapistore_indexing_add(), and MAPISTORE_SUCCESS.

Referenced by mapistore_add_context().

enum mapistore_error mapistore_add_context_ref_count ( struct mapistore_context *  mstore_ctx,
uint32_t  context_id 
)

Increase the reference counter of an existing context

Parameters
mstore_ctxpointer to the mapistore context
contex_idthe context identifier referencing the context to update
Returns
MAPISTORE_SUCCESS on success, otherwise MAPISTORE error

References mapistore_add_context_ref_count(), mapistore_backend_add_ref_count(), mapistore_backend_lookup(), MAPISTORE_ERR_INVALID_PARAMETER, and MAPISTORE_ERROR.

Referenced by mapistore_add_context_ref_count().

const char* mapistore_backend_get_installdir ( void  )

Return the full path where mapistore backends are installed.

Returns
Pointer to the full path where backends are installed.

Referenced by mapistore_backend_load().

init_backend_fn* mapistore_backend_load ( TALLOC_CTX *  mem_ctx,
const char *  path 
)

Load the initialization functions from backends DSO

Parameters
mem_ctxpointer to the memory context
pathpointer to the backend's DSO folder
Returns
allocated array of functions pointers to initialization functions on success, otherwise NULL.

References mapistore_backend_get_installdir().

Referenced by mapistore_backend_init().

struct backend_context* mapistore_backend_lookup ( struct backend_context_list *  backend_list_ctx,
uint32_t  context_id 
)
read
struct backend_context* mapistore_backend_lookup_by_name ( TALLOC_CTX *  mem_ctx,
const char *  name 
)
read

Return a pointer on backend functions given its name

Parameters
mem_ctxpointer to the memory context
namethe backend name to lookup
Returns
Allocated pointer to the mapistore_backend context on success, otherwise NULL

Referenced by mapistore_mgmt_generate_uri().

struct backend_context* mapistore_backend_lookup_by_uri ( struct backend_context_list *  backend_list_ctx,
const char *  uri 
)
read

find the context matching given uri string

Parameters
backend_list_ctxpointer to the backend context list
urithe uri string to search
Returns
Pointer to the mapistore_backend context on success, otherwise NULL

Referenced by mapistore_search_context_by_uri().

enum mapistore_error mapistore_backend_register ( const void *  _backend)

Register mapistore backends

Parameters
backendpointer to the mapistore backend to register
Returns
MAPISTORE_SUCCESS on success

References MAPISTORE_ERR_INVALID_PARAMETER, and MAPISTORE_SUCCESS.

bool mapistore_backend_run_init ( init_backend_fn *  fns)

Run specified initialization functions.

Parameters
fnspointer to an array of mapistore backends initialization functions
Returns
true on success, otherwise false

Referenced by mapistore_backend_init().

enum mapistore_error mapistore_del_context ( struct mapistore_context *  mstore_ctx,
uint32_t  context_id 
)

Delete an existing connection context from mapistore

Parameters
mstore_ctxpointer to the mapistore context
context_idthe context identifier referencing the context to delete
Returns
MAPISTORE_SUCCESS on success, otherwise MAPISTORE error

References mapistore_backend_delete_context(), mapistore_backend_lookup(), mapistore_del_context(), MAPISTORE_ERR_INVALID_PARAMETER, MAPISTORE_ERR_REF_COUNT, MAPISTORE_ERROR, and MAPISTORE_SUCCESS.

Referenced by mapistore_del_context().

enum mapistore_error mapistore_folder_create_folder ( struct mapistore_context *  mstore_ctx,
uint32_t  context_id,
void *  folder,
TALLOC_CTX *  mem_ctx,
uint64_t  fid,
struct SRow *  aRow,
void **  child_folder 
)

Create a directory in mapistore

Parameters
mstore_ctxpointer to the mapistore context
context_idthe context identifier referencing the backend where the directory will be created
parent_fidthe parent folder identifier
new_fidthe folder identifier for the new folder
aRowpointer to MAPI data structures with properties to be added to the new folder
Returns
MAPISTORE_SUCCESS on success, otherwise MAPISTORE errors

References mapistore_backend_lookup(), MAPISTORE_ERR_INVALID_PARAMETER, and mapistore_folder_create_folder().

Referenced by mapistore_folder_create_folder().

enum mapistore_error mapistore_folder_create_message ( struct mapistore_context *  mstore_ctx,
uint32_t  context_id,
void *  folder,
TALLOC_CTX *  mem_ctx,
uint64_t  mid,
uint8_t  associated,
void **  messagep 
)

Create a message in mapistore

Parameters
mstore_ctxpointer to the mapistore context
context_idthe context identifier referencing the backend where the messagewill be created
parent_fidthe parent folder identifier
midthe message identifier to create
Returns
MAPISTORE_SUCCESS on success, otherwise MAPISTORE errors

References mapistore_backend_lookup(), MAPISTORE_ERR_INVALID_PARAMETER, and mapistore_folder_create_message().

Referenced by mapistore_folder_create_message().

enum mapistore_error mapistore_folder_delete ( struct mapistore_context *  mstore_ctx,
uint32_t  context_id,
void *  folder,
uint8_t  flags 
)

Remove a directory in mapistore

Parameters
mstore_ctxpointer to the mapistore context
context_idthe context identifier referencing the backend
parent_fidthe parent folder identifier
fidthe folder identifier representing the folder to delete
flagsflags that control the behaviour of the operation
Returns
MAPISTORE_SUCCESS on success, otherwise MAPISTORE errors

References mapistore_backend_lookup(), MAPISTORE_ERR_EXIST, MAPISTORE_ERR_INVALID_PARAMETER, mapistore_folder_delete(), and MAPISTORE_SUCCESS.

Referenced by mapistore_folder_delete().

enum mapistore_error mapistore_folder_delete_message ( struct mapistore_context *  mstore_ctx,
uint32_t  context_id,
void *  folder,
uint64_t  mid,
uint8_t  flags 
)

Delete a message from mapistore

Parameters
mstore_ctxpointer to the mapistore context
context_idthe context identifier referencing the backend where the message's to be located is stored
midthe message identifier of the folder to delete
flagsflags that control the behaviour of the operation (MAPISTORE_SOFT_DELETE or MAPISTORE_PERMANENT_DELETE)
Returns
MAPISTORE_SUCCESS on success, otherwise MAPISTORE errors

References mapistore_backend_lookup(), MAPISTORE_ERR_INVALID_PARAMETER, and mapistore_folder_delete_message().

Referenced by mapistore_folder_delete_message().

enum mapistore_error mapistore_folder_get_child_count ( struct mapistore_context *  mstore_ctx,
uint32_t  context_id,
void *  folder,
enum mapistore_table_type  table_type,
uint32_t *  RowCount 
)

Retrieve the number of child messages within a mapistore folder

Parameters
mstore_ctxpointer to the mapistore context
context_idthe context identifier referencing the backend
fidthe folder identifier
RowCountpointer to the count result to return
Returns
MAPISTORE_SUCCESS on success, otherwise MAPISTORE errors

References mapistore_backend_lookup(), MAPISTORE_ERR_INVALID_PARAMETER, and mapistore_folder_get_child_count().

Referenced by mapistore_folder_get_child_count().

enum mapistore_error mapistore_folder_get_deleted_fmids ( struct mapistore_context *  mstore_ctx,
uint32_t  context_id,
void *  folder,
TALLOC_CTX *  mem_ctx,
enum mapistore_table_type  table_type,
uint64_t  change_num,
struct UI8Array_r **  fmidsp,
uint64_t *  cnp 
)

Get the array of deleted items following a specific change number

Parameters
mstore_ctxpointer to the mapistore context
context_idthe context identifier referencing the backend where the message's to be located is stored
folderthe folder backend object
mem_ctxthe TALLOC_CTX that should be used as parent for the returned array
table_typethe type of object that we want to take into account
change_numthe reference change number
fmidspa pointer to the returned array
Returns
MAPISTORE_SUCCESS on success, otherwise MAPISTORE errors

References mapistore_backend_lookup(), MAPISTORE_ERR_INVALID_PARAMETER, and mapistore_folder_get_deleted_fmids().

Referenced by mapistore_folder_get_deleted_fmids().

enum mapistore_error mapistore_folder_open_folder ( struct mapistore_context *  mstore_ctx,
uint32_t  context_id,
void *  folder,
TALLOC_CTX *  mem_ctx,
uint64_t  fid,
void **  child_folder 
)

Open a directory in mapistore

Parameters
mstore_ctxpointer to the mapistore context
context_idthe context identifier referencing the backend where the directory will be opened
parent_fidthe parent folder identifier
fidfolder identifier to open
Returns
MAPISTORE_SUCCESS on success, otherwise MAPISTORE errors

References mapistore_backend_lookup(), MAPISTORE_ERR_INVALID_PARAMETER, and mapistore_folder_open_folder().

Referenced by mapistore_folder_open_folder().

enum mapistore_error mapistore_folder_open_message ( struct mapistore_context *  mstore_ctx,
uint32_t  context_id,
void *  folder,
TALLOC_CTX *  mem_ctx,
uint64_t  mid,
bool  read_write,
void **  messagep 
)

Open a message in mapistore

Parameters
mstore_ctxpointer to the mapistore context
context_idthe context identifier referencing the backend where the directory will be opened
parent_fidthe parent folder identifier
midthe message identifier to open
pointerto the mapistore_message structure
Returns
MAPISTORE SUCCESS on success, otherwise MAPISTORE errors

References mapistore_backend_lookup(), MAPISTORE_ERR_INVALID_PARAMETER, and mapistore_folder_open_message().

Referenced by mapistore_folder_open_message().

enum MAPISTATUS mapistore_get_queued_notifications ( struct mapistore_context *  mstore_ctx,
struct mapistore_subscription *  s,
struct mapistore_notification_list **  nl 
)

Return the list of pending mapistore notifications within the queue pointed by the mapistore subscription structure.

Parameters
mstore_ctxpointer to the mapistore context
spointer to the mapistore subscription where the mqueue file descriptor is stored
nlpointer on pointer to the list of mapistore noficiations to return
Returns
MAPISTORE_SUCCESS on success, otherwise MAPISTORE error

References MAPISTORE_ERR_INVALID_PARAMETER, MAPISTORE_ERR_NOT_FOUND, MAPISTORE_ERR_NOT_INITIALIZED, mapistore_get_queued_notifications(), and MAPISTORE_SUCCESS.

Referenced by mapistore_get_queued_notifications().

enum MAPISTATUS mapistore_get_queued_notifications_named ( struct mapistore_context *  mstore_ctx,
const char *  mqueue_name,
struct mapistore_notification_list **  nl 
)

Return the list of pending mapistore notifications available on the queue name specified in argument.

Parameters
mstore_ctxpointer to the mapistore context
mqueue_namethe name of the queue to open
nlpointer on pointer to the list of mapistore notifications to return
Returns
MAPISTORE_SUCCESS on success, otherwise MAPISTORE error.

References MAPISTORE_ERR_INVALID_PARAMETER, MAPISTORE_ERR_NOT_FOUND, MAPISTORE_ERR_NOT_INITIALIZED, mapistore_get_queued_notifications_named(), and MAPISTORE_SUCCESS.

Referenced by mapistore_get_queued_notifications_named().

enum mapistore_error mapistore_indexing_record_add_fid ( struct mapistore_context *  mstore_ctx,
uint32_t  context_id,
const char *  username,
uint64_t  fid 
)

Add a fid record to the indexing database

Parameters
mstore_ctxpointer to the mapistore context
context_idthe context identifier referencing the indexing database to update
fidthe fid to add
Note
This is a wrapper to the internal common mapistore_indexing_record_add_fmid function.
Returns
MAPISTORE_SUCCESS on success, otherwise MAPISTORE error

References mapistore_indexing_record_add_fmid().

enum mapistore_error mapistore_indexing_record_add_mid ( struct mapistore_context *  mstore_ctx,
uint32_t  context_id,
const char *  username,
uint64_t  mid 
)

Add a mid record to the indexing database

Parameters
mstore_ctxpointer to the mapistore context
context_idthe context identifier referencing the indexing database to update
midthe mid to add
Note
This is a wrapper to the internal common mapistore_indexing_record_add_fmid function.
Returns
MAPISTORE_SUCCESS on success, otherwise MAPISTORE error

References mapistore_indexing_record_add_fmid().

enum mapistore_error mapistore_indexing_record_del_fid ( struct mapistore_context *  mstore_ctx,
uint32_t  context_id,
const char *  username,
uint64_t  fid,
uint8_t  flags 
)

Delete a fid record from the indexing database

Parameters
mstore_ctxpointer to the mapistore context
context_idthe context identifier referencing the indexing database to update
fidthe fid to remove
flagsthe type of deletion MAPISTORE_SOFT_DELETE or MAPISTORE_PERMANENT_DELETE
Returns
MAPISTORE_SUCCESS on success, otherwise MAPISTORE error

References mapistore_indexing_record_del_fmid().

enum mapistore_error mapistore_indexing_record_del_mid ( struct mapistore_context *  mstore_ctx,
uint32_t  context_id,
const char *  username,
uint64_t  mid,
uint8_t  flags 
)

Delete a mid record from the indexing database

Parameters
mstore_ctxpointer to the mapistore context
context_idthe context identifier referencing the indexing database to update
midthe mid to remove
flagsthe type of deletion MAPISTORE_SOFT_DELETE or MAPISTORE_PERMANENT_DELETE
Returns
MAPISTORE_SUCCESS on success, otherwise MAPISTORE error

References mapistore_indexing_record_del_fmid().

enum mapistore_error mapistore_indexing_record_get_uri ( struct mapistore_context *  mstore_ctx,
const char *  username,
TALLOC_CTX *  mem_ctx,
uint64_t  fmid,
char **  urip,
bool *  soft_deletedp 
)

Returns record data

Parameters
mstore_ctxpointer to the mapistore context
usernamethe name of the account where to look for the indexing database
mem_ctxpointer to the memory context
fmidthe fmid/key to the record
urippointer to the uri pointer
soft_deletedppointer to the soft deleted pointer
Returns
MAPISTORE_SUCCESS on success, otherwise MAPISTORE error

References MAPISTORE_ERR_NOT_FOUND, MAPISTORE_ERR_NOT_INITIALIZED, MAPISTORE_ERROR, mapistore_indexing_add(), and MAPISTORE_SUCCESS.

struct mapistore_context* mapistore_init ( TALLOC_CTX *  mem_ctx,
struct loadparm_context *  lp_ctx,
const char *  path 
)
read

Initialize the mapistore context

Parameters
mem_ctxpointer to the memory context
paththe path to the location to load the backend providers from (NULL for default)
Returns
allocate mapistore context on success, otherwise NULL

References mapistore_backend_init(), mapistore_errstr(), mapistore_init(), mapistore_set_mapping_path(), and MAPISTORE_SUCCESS.

Referenced by mapistore_init().

enum mapistore_error mapistore_message_get_message_data ( struct mapistore_context *  mstore_ctx,
uint32_t  context_id,
void *  message,
TALLOC_CTX *  mem_ctx,
struct mapistore_message **  msg 
)

Modify recipients of a message in mapistore

Parameters
mstore_ctxpointer to the mapistore context
context_idthe context identifier referencing the backend where properties will be stored
midthe identifier referencing the message the array of recipient rows the number of elements in the array
Returns
MAPISTORE_SUCCESS on success, otherwise MAPISTORE errors

References mapistore_backend_lookup(), MAPISTORE_ERR_INVALID_PARAMETER, and mapistore_message_get_message_data().

Referenced by mapistore_message_get_message_data().

enum mapistore_error mapistore_message_modify_recipients ( struct mapistore_context *  mstore_ctx,
uint32_t  context_id,
void *  message,
struct SPropTagArray *  columns,
uint16_t  count,
struct mapistore_message_recipient *  recipients 
)

Modify recipients of a message in mapistore

Parameters
mstore_ctxpointer to the mapistore context
context_idthe context identifier referencing the backend where properties will be stored
midthe identifier referencing the message the array of recipient rows the number of elements in the array
Returns
MAPISTORE_SUCCESS on success, otherwise MAPISTORE errors

References mapistore_backend_lookup(), MAPISTORE_ERR_INVALID_PARAMETER, and mapistore_message_modify_recipients().

Referenced by mapistore_message_modify_recipients().

enum mapistore_error mapistore_message_save ( struct mapistore_context *  mstore_ctx,
uint32_t  context_id,
void *  message 
)

Commit the changes made to a message in mapistore

Parameters
mstore_ctxpointer to the mapistore context
context_idthe context identifier referencing the backend where the message's changes will be saved
midthe message identifier to save
flagsflags associated to the commit operation
Returns
MAPISTORE_SUCCESS on success, otherwise MAPISTORE errors

References mapistore_backend_lookup(), MAPISTORE_ERR_INVALID_PARAMETER, and mapistore_message_save().

Referenced by mapistore_message_save().

enum mapistore_error mapistore_message_set_read_flag ( struct mapistore_context *  mstore_ctx,
uint32_t  context_id,
void *  message,
uint8_t  flag 
)

Commit the changes made to a message in mapistore

Parameters
mstore_ctxpointer to the mapistore context
context_idthe context identifier referencing the backend where the message's changes will be saved
midthe message identifier to save
flagsflags associated to the commit operation
Returns
MAPISTORE_SUCCESS on success, otherwise MAPISTORE errors

References mapistore_backend_lookup(), MAPISTORE_ERR_INVALID_PARAMETER, and mapistore_message_set_read_flag().

Referenced by mapistore_message_set_read_flag().

enum mapistore_error mapistore_message_submit ( struct mapistore_context *  mstore_ctx,
uint32_t  context_id,
void *  message,
enum SubmitFlags  flags 
)

Submits a message for sending.

Parameters
mstore_ctxpointer to the mapistore context
context_idthe context identifier referencing the backend where the message will be submitted
midthe message identifier representing the message to submit
flagsflags associated to the submit operation
Returns
MAPISTORE_SUCCESS on success, otherwise MAPISTORE errors

References mapistore_backend_lookup(), MAPISTORE_ERR_INVALID_PARAMETER, and mapistore_message_submit().

Referenced by mapistore_message_submit().

enum mapistore_error mapistore_namedprops_create_id ( struct ldb_context *  ldb_ctx,
struct MAPINAMEID  nameid,
uint16_t  mapped_id 
)

return the mapped property ID matching the nameid structure passed in parameter.

Parameters
ldb_ctxpointer to the namedprops ldb context
nameidthe MAPINAMEID structure to lookup
propIDpointer to the property ID the function returns
Returns
MAPISTORE_SUCCESS on success, otherwise MAPISTORE_ERROR

References MAPISTORE_ERR_DATABASE_INIT, and mapistore_namedprops_create_id().

Referenced by mapistore_namedprops_create_id().

enum mapistore_error mapistore_namedprops_get_mapped_id ( struct ldb_context *  ldb_ctx,
struct MAPINAMEID  nameid,
uint16_t *  propID 
)

return the mapped property ID matching the nameid structure passed in parameter.

Parameters
ldb_ctxpointer to the namedprops ldb context
nameidthe MAPINAMEID structure to lookup
propIDpointer to the property ID the function returns
Returns
MAPISTORE_SUCCESS on success, otherwise MAPISTORE_ERROR

References MAPISTORE_ERROR, mapistore_namedprops_get_mapped_id(), and MAPISTORE_SUCCESS.

Referenced by mapistore_namedprops_get_mapped_id().

enum mapistore_error mapistore_namedprops_get_nameid ( struct ldb_context *  ldb_ctx,
uint16_t  propID,
TALLOC_CTX *  mem_ctx,
struct MAPINAMEID **  nameidp 
)

return the nameid structture matching the mapped property ID passed in parameter.

Parameters
ldb_ctxpointer to the namedprops ldb context
propIDthe property ID to lookup
nameidpointer to the MAPINAMEID structure the function returns
Returns
MAPISTORE_SUCCESS on success, otherwise MAPISTORE_ERROR

References MAPISTORE_ERROR, mapistore_namedprops_get_nameid(), and MAPISTORE_SUCCESS.

Referenced by mapistore_namedprops_get_nameid().

enum mapistore_error mapistore_namedprops_get_nameid_type ( struct ldb_context *  ldb_ctx,
uint16_t  propID,
uint16_t *  propTypeP 
)

return the type matching the mapped property ID passed in parameter.

Parameters
ldb_ctxpointer to the namedprops ldb context
propIDthe property ID to lookup
propTypePpointer to the uint16_t that will receive the property type
Returns
MAPISTORE_SUCCESS on success, otherwise MAPISTORE_ERROR

References MAPISTORE_ERROR, mapistore_namedprops_get_nameid_type(), and MAPISTORE_SUCCESS.

Referenced by mapistore_namedprops_get_nameid_type().

uint16_t mapistore_namedprops_next_unused_id ( struct ldb_context *  ldb_ctx)

return the next unmapped property ID

Parameters
ldb_ctxpointer to the namedprops ldb context
Returns
0 on error, the next mapped id otherwise

References mapistore_namedprops_next_unused_id().

Referenced by mapistore_namedprops_next_unused_id().

enum mapistore_error mapistore_release ( struct mapistore_context *  mstore_ctx)

Release the mapistore context and destroy any data associated

Parameters
mstore_ctxpointer to the mapistore context
Note
The function needs to rely on talloc destructors which is not implemented in code yet.
Returns
MAPISTORE_SUCCESS on success, otherwise MAPISTORE error

References MAPISTORE_ERR_NOT_INITIALIZED, mapistore_release(), and MAPISTORE_SUCCESS.

Referenced by mapistore_release().

enum mapistore_error mapistore_replica_mapping_guid_to_replid ( struct mapistore_context *  mstore_ctx,
const char *  username,
const struct GUID *  guidP,
uint16_t *  replidP 
)

Search a replica guid in the database, creates it if it does not exist

Parameters
mstore_ctxpointer to the mapistore context
guidPthe replica guid
replidPpointer to the returned replica id
Returns
MAPISTORE_SUCCESS on success, otherwise MAPISTORE error

References MAPISTORE_ERROR, mapistore_replica_mapping_guid_to_replid(), and MAPISTORE_SUCCESS.

Referenced by mapistore_replica_mapping_guid_to_replid().

enum mapistore_error mapistore_replica_mapping_replid_to_guid ( struct mapistore_context *  mstore_ctx,
const char *  username,
uint16_t  replid,
struct GUID *  guidP 
)

Search a replica id in the database

Parameters
mstore_ctxpointer to the mapistore context
replidthe replica id
guidPpointer to the returned replica guid
Returns
MAPISTORE_SUCCESS on success, otherwise MAPISTORE error

References MAPISTORE_ERROR, mapistore_replica_mapping_replid_to_guid(), and MAPISTORE_SUCCESS.

Referenced by mapistore_replica_mapping_replid_to_guid().

enum mapistore_error mapistore_search_context_by_uri ( struct mapistore_context *  mstore_ctx,
const char *  uri,
uint32_t *  context_id,
void **  backend_object 
)

Search for an existing context given its uri

Parameters
mstore_ctxpointer to the mapistore context
urithe URI to lookup
context_idpointer to the context identifier to return
Returns
MAPISTORE_SUCCESS on success, otherwise MAPISTORE error

References mapistore_backend_lookup_by_uri(), MAPISTORE_ERR_NOT_FOUND, MAPISTORE_ERROR, mapistore_search_context_by_uri(), and MAPISTORE_SUCCESS.

Referenced by mapistore_search_context_by_uri().

enum mapistore_error mapistore_set_connection_info ( struct mapistore_context *  mstore_ctx,
struct ldb_context *  sam_ctx,
struct ldb_context *  oc_ctx,
const char *  username 
)

Set connection info for current mapistore context

Parameters
mstore_ctxpointer to the mapistore context
oc_ctxpointer to the openchange ldb database
usernamepointer to the current username
Returns
MAPISTORE_SUCCESS on success, otherwise MAPISTORE error

References MAPISTORE_ERR_INVALID_PARAMETER, MAPISTORE_ERR_NOT_INITIALIZED, mapistore_set_connection_info(), and MAPISTORE_SUCCESS.

Referenced by mapistore_set_connection_info().

enum mapistore_error mapistore_set_mapping_path ( const char *  path)

Set the mapping path

Parameters
pathpointer to the mapping path
Note
The mapping path can be set unless id_mapping_context is initialized. If path is NULL and mapping path is not yet initialized, then mapping_path will be reset to its default value when the initialization routine is called.
Returns
MAPISTORE_SUCCESS on success, otherwise MAPISTORE error

References MAPISTORE_ERR_NO_DIRECTORY, mapistore_set_mapping_path(), and MAPISTORE_SUCCESS.

Referenced by mapistore_init(), and mapistore_set_mapping_path().


Creative Commons License
Creative Commons Attribution icon Creative Commons Share Alike icon
This content is licensed under the Creative Commons
Attribution ShareAlike License v. 3.0:
http://creativecommons.org/licenses/by-sa/3.0/

openchange-2.0/apidocs/html/libmapistore/mapistore__backend_8c.html000066400000000000000000000732421223057412600256450ustar00rootroot00000000000000 OpenChange mapistore library 2.0 API Documentation
mapistore_backend.c File Reference

mapistore backends management API More...

#include <string.h>
#include <dlfcn.h>
#include <dirent.h>
#include "mapistore.h"
#include "mapistore_errors.h"
#include "mapistore_private.h"
#include <dlinklist.h>
#include <samba_util.h>
#include <util/debug.h>

Functions

_PUBLIC_ enum mapistore_error mapistore_backend_add_ref_count (struct backend_context *bctx)
enum mapistore_error mapistore_backend_create_context (TALLOC_CTX *mem_ctx, struct mapistore_connection_info *conn_info, struct tdb_wrap *tdbwrap, const char *namespace, const char *uri, uint64_t fid, struct backend_context **context_p)
_PUBLIC_ enum mapistore_error mapistore_backend_delete_context (struct backend_context *bctx)
_PUBLIC_ const char * mapistore_backend_get_installdir (void)
enum mapistore_error mapistore_backend_init (TALLOC_CTX *mem_ctx, const char *path)
enum mapistore_error mapistore_backend_list_contexts (const char *username, struct tdb_wrap *tdbwrap, TALLOC_CTX *mem_ctx, struct mapistore_contexts_list **contexts_listP)
_PUBLIC_ init_backend_fn * mapistore_backend_load (TALLOC_CTX *mem_ctx, const char *path)
_PUBLIC_ struct backend_context * mapistore_backend_lookup (struct backend_context_list *backend_list_ctx, uint32_t context_id)
_PUBLIC_ struct backend_context * mapistore_backend_lookup_by_name (TALLOC_CTX *mem_ctx, const char *name)
_PUBLIC_ struct backend_context * mapistore_backend_lookup_by_uri (struct backend_context_list *backend_list_ctx, const char *uri)
_PUBLIC_ enum mapistore_error mapistore_backend_register (const void *_backend)
_PUBLIC_ enum mapistore_error mapistore_backend_registered (const char *name)
_PUBLIC_ bool mapistore_backend_run_init (init_backend_fn *fns)

Detailed Description

mapistore backends management API

Function Documentation

_PUBLIC_ enum mapistore_error mapistore_backend_add_ref_count ( struct backend_context *  bctx)

Increase the ref count associated to a given backend

Parameters
bctxpointer to the backend context
Returns
MAPISTORE_SUCCESS on success, otherwise MAPISTORE_ERROR

References MAPISTORE_ERROR, and MAPISTORE_SUCCESS.

Referenced by mapistore_add_context_ref_count().

enum mapistore_error mapistore_backend_create_context ( TALLOC_CTX *  mem_ctx,
struct mapistore_connection_info *  conn_info,
struct tdb_wrap *  tdbwrap,
const char *  namespace,
const char *  uri,
uint64_t  fid,
struct backend_context **  context_p 
)

Create backend context

Parameters
mem_ctxpointer to the memory context
namespacethe backend namespace
urithe backend parameters which can be passes inline
Returns
a valid backend_context pointer on success, otherwise NULL

References MAPISTORE_ERR_NOT_FOUND, and MAPISTORE_SUCCESS.

Referenced by mapistore_add_context().

_PUBLIC_ enum mapistore_error mapistore_backend_delete_context ( struct backend_context *  bctx)

Delete a context from the specified backend

Parameters
bctxpointer to the backend context
Returns
MAPISTORE_SUCCESS on success, otherwise MAPISTORE error

References MAPISTORE_ERR_REF_COUNT, and MAPISTORE_SUCCESS.

Referenced by mapistore_del_context(), and mapistore_mgmt_generate_uri().

_PUBLIC_ const char* mapistore_backend_get_installdir ( void  )

Return the full path where mapistore backends are installed.

Returns
Pointer to the full path where backends are installed.

Referenced by mapistore_backend_load().

enum mapistore_error mapistore_backend_init ( TALLOC_CTX *  mem_ctx,
const char *  path 
)

Initialize mapistore backends

Parameters
mem_ctxpointer to the memory context
pathpointer to folder where mapistore backends are installed
Returns
MAPISTORE_SUCCESS on success, otherwise MAPISTORE_ERR_BACKEND_INIT

References mapistore_backend_load(), mapistore_backend_run_init(), MAPISTORE_ERR_BACKEND_INIT, and MAPISTORE_SUCCESS.

Referenced by mapistore_init().

enum mapistore_error mapistore_backend_list_contexts ( const char *  username,
struct tdb_wrap *  tdbwrap,
TALLOC_CTX *  mem_ctx,
struct mapistore_contexts_list **  contexts_listP 
)

List backend contexts for given user

Parameters
mem_ctxpointer to the memory context
namespacethe backend namespace
urithe backend parameters which can be passes inline
Returns
a valid backend_context pointer on success, otherwise NULL

References MAPISTORE_ERR_INVALID_PARAMETER, and MAPISTORE_SUCCESS.

_PUBLIC_ init_backend_fn* mapistore_backend_load ( TALLOC_CTX *  mem_ctx,
const char *  path 
)

Load the initialization functions from backends DSO

Parameters
mem_ctxpointer to the memory context
pathpointer to the backend's DSO folder
Returns
allocated array of functions pointers to initialization functions on success, otherwise NULL.

References mapistore_backend_get_installdir().

Referenced by mapistore_backend_init().

_PUBLIC_ struct backend_context* mapistore_backend_lookup ( struct backend_context_list *  backend_list_ctx,
uint32_t  context_id 
)
read
_PUBLIC_ struct backend_context* mapistore_backend_lookup_by_name ( TALLOC_CTX *  mem_ctx,
const char *  name 
)
read

Return a pointer on backend functions given its name

Parameters
mem_ctxpointer to the memory context
namethe backend name to lookup
Returns
Allocated pointer to the mapistore_backend context on success, otherwise NULL

Referenced by mapistore_mgmt_generate_uri().

_PUBLIC_ struct backend_context* mapistore_backend_lookup_by_uri ( struct backend_context_list *  backend_list_ctx,
const char *  uri 
)
read

find the context matching given uri string

Parameters
backend_list_ctxpointer to the backend context list
urithe uri string to search
Returns
Pointer to the mapistore_backend context on success, otherwise NULL

Referenced by mapistore_search_context_by_uri().

_PUBLIC_ enum mapistore_error mapistore_backend_register ( const void *  _backend)

Register mapistore backends

Parameters
backendpointer to the mapistore backend to register
Returns
MAPISTORE_SUCCESS on success

References MAPISTORE_ERR_INVALID_PARAMETER, and MAPISTORE_SUCCESS.

_PUBLIC_ enum mapistore_error mapistore_backend_registered ( const char *  name)

Check if the specified backend is registered given its name.

Parameters
namebackend's name to lookup
Returns
MAPISTORE_SUCCESS on success, otherwise MAPISTORE error

References MAPISTORE_ERR_INVALID_PARAMETER, MAPISTORE_ERR_NOT_FOUND, and MAPISTORE_SUCCESS.

Referenced by mapistore_mgmt_registered_backend().

_PUBLIC_ bool mapistore_backend_run_init ( init_backend_fn *  fns)

Run specified initialization functions.

Parameters
fnspointer to an array of mapistore backends initialization functions
Returns
true on success, otherwise false

Referenced by mapistore_backend_init().


Creative Commons License
Creative Commons Attribution icon Creative Commons Share Alike icon
This content is licensed under the Creative Commons
Attribution ShareAlike License v. 3.0:
http://creativecommons.org/licenses/by-sa/3.0/

openchange-2.0/apidocs/html/libmapistore/mapistore__backend__defaults_8c.html000066400000000000000000000052731223057412600276720ustar00rootroot00000000000000 OpenChange mapistore library 2.0 API Documentation
mapistore_backend_defaults.c File Reference

Initialize default behavior for mapistore backends. More...

#include "mapistore_errors.h"
#include "mapistore.h"
#include "mapistore_private.h"

Detailed Description

Initialize default behavior for mapistore backends.


Creative Commons License
Creative Commons Attribution icon Creative Commons Share Alike icon
This content is licensed under the Creative Commons
Attribution ShareAlike License v. 3.0:
http://creativecommons.org/licenses/by-sa/3.0/

openchange-2.0/apidocs/html/libmapistore/mapistore__errors_8h.html000066400000000000000000000301251223057412600255700ustar00rootroot00000000000000 OpenChange mapistore library 2.0 API Documentation
mapistore_errors.h File Reference

This header provides a set of result codes for MAPISTORE function calls. More...

Enumerations

enum  mapistore_error {
  MAPISTORE_SUCCESS = 0, MAPISTORE_ERROR = 1, MAPISTORE_ERR_NO_MEMORY = 2, MAPISTORE_ERR_ALREADY_INITIALIZED = 3,
  MAPISTORE_ERR_NOT_INITIALIZED = 4, MAPISTORE_ERR_CORRUPTED = 5, MAPISTORE_ERR_INVALID_PARAMETER = 6, MAPISTORE_ERR_NO_DIRECTORY = 7,
  MAPISTORE_ERR_DATABASE_INIT = 8, MAPISTORE_ERR_DATABASE_OPS = 9, MAPISTORE_ERR_BACKEND_REGISTER = 10, MAPISTORE_ERR_BACKEND_INIT = 11,
  MAPISTORE_ERR_CONTEXT_FAILED = 12, MAPISTORE_ERR_INVALID_NAMESPACE = 13, MAPISTORE_ERR_NOT_FOUND = 14, MAPISTORE_ERR_REF_COUNT = 15,
  MAPISTORE_ERR_EXIST = 16, MAPISTORE_ERR_INVALID_DATA = 17, MAPISTORE_ERR_MSG_SEND = 18, MAPISTORE_ERR_MSG_RCV = 19,
  MAPISTORE_ERR_DENIED = 20, MAPISTORE_ERR_NOT_IMPLEMENTED
}

Detailed Description

This header provides a set of result codes for MAPISTORE function calls.

Enumeration Type Documentation

Enumerator:
MAPISTORE_SUCCESS 

The function call succeeded.

MAPISTORE_ERROR 

The function call failed for some non-specific reason.

MAPISTORE_ERR_NO_MEMORY 

The function call failed because it was unable to allocate the memory required by underlying operations.

MAPISTORE_ERR_ALREADY_INITIALIZED 

The function call failed because underlying context has already been initialized.

MAPISTORE_ERR_NOT_INITIALIZED 

The function call failed because context has not been initialized.

MAPISTORE_ERR_CORRUPTED 

The function call failed because an internal mapistore storage component has corrupted data.

MAPISTORE_ERR_INVALID_PARAMETER 

The function call failed because one of the function parameters is invalid.

MAPISTORE_ERR_NO_DIRECTORY 

The function call failed because the directory doesn't exist.

MAPISTORE_ERR_DATABASE_INIT 

The function call failed because the underlying function couldn't open a database.

MAPISTORE_ERR_DATABASE_OPS 

The function call failed because the underlying function didn't run a database operation successfully.

MAPISTORE_ERR_BACKEND_REGISTER 

The function failed to register a storage backend.

MAPISTORE_ERR_BACKEND_INIT 

One of more storage backend initialization functions failed to complete successfully.

MAPISTORE_ERR_CONTEXT_FAILED 

The function failed because mapistore failed to create a context.

MAPISTORE_ERR_INVALID_NAMESPACE 

The function failed because the provided namespace is invalid.

MAPISTORE_ERR_NOT_FOUND 

The function failed to find requested record/data.

MAPISTORE_ERR_REF_COUNT 

The function still has a reference count.

MAPISTORE_ERR_EXIST 

The function already have record/data for the searched element.

MAPISTORE_ERR_INVALID_DATA 

The function failed to generate requested data/payload.

MAPISTORE_ERR_MSG_SEND 

The function failed to send message.

MAPISTORE_ERR_MSG_RCV 

The function failed to receive message.

MAPISTORE_ERR_DENIED 

The operation required privileges that the user does not have.

MAPISTORE_ERR_NOT_IMPLEMENTED 

The function is not implemented.


Creative Commons License
Creative Commons Attribution icon Creative Commons Share Alike icon
This content is licensed under the Creative Commons
Attribution ShareAlike License v. 3.0:
http://creativecommons.org/licenses/by-sa/3.0/

openchange-2.0/apidocs/html/libmapistore/mapistore__indexing_8c.html000066400000000000000000001003751223057412600260610ustar00rootroot00000000000000 OpenChange mapistore library 2.0 API Documentation
mapistore_indexing.c File Reference

MAPISTORE internal indexing functions. More...

#include <string.h>
#include "mapistore.h"
#include "mapistore_errors.h"
#include "mapistore_private.h"
#include <dlinklist.h>
#include "libmapi/libmapi_private.h"
#include <tdb.h>

Functions

_PUBLIC_ enum mapistore_error mapistore_indexing_add (struct mapistore_context *mstore_ctx, const char *username, struct indexing_context_list **ictxp)
_PUBLIC_ enum mapistore_error mapistore_indexing_record_add_fid (struct mapistore_context *mstore_ctx, uint32_t context_id, const char *username, uint64_t fid)
enum mapistore_error mapistore_indexing_record_add_fmid (struct mapistore_context *mstore_ctx, uint32_t context_id, const char *username, uint64_t fmid)
_PUBLIC_ enum mapistore_error mapistore_indexing_record_add_mid (struct mapistore_context *mstore_ctx, uint32_t context_id, const char *username, uint64_t mid)
_PUBLIC_ enum mapistore_error mapistore_indexing_record_del_fid (struct mapistore_context *mstore_ctx, uint32_t context_id, const char *username, uint64_t fid, uint8_t flags)
enum mapistore_error mapistore_indexing_record_del_fmid (struct mapistore_context *mstore_ctx, uint32_t context_id, const char *username, uint64_t fmid, uint8_t flags)
_PUBLIC_ enum mapistore_error mapistore_indexing_record_del_mid (struct mapistore_context *mstore_ctx, uint32_t context_id, const char *username, uint64_t mid, uint8_t flags)
_PUBLIC_ enum mapistore_error mapistore_indexing_record_get_uri (struct mapistore_context *mstore_ctx, const char *username, TALLOC_CTX *mem_ctx, uint64_t fmid, char **urip, bool *soft_deletedp)
struct indexing_context_list * mapistore_indexing_search (struct mapistore_context *mstore_ctx, const char *username)
enum mapistore_error mapistore_indexing_search_existing_fmid (struct indexing_context_list *ictx, uint64_t fmid, bool *IsSoftDeleted)

Detailed Description

MAPISTORE internal indexing functions.

This file contains functionality to map between folder / message identifiers and backend URI strings.

Function Documentation

_PUBLIC_ enum mapistore_error mapistore_indexing_add ( struct mapistore_context *  mstore_ctx,
const char *  username,
struct indexing_context_list **  ictxp 
)

Open connection to indexing database for a given user

Parameters
mstore_ctxpointer to the mapistore context
usernamename for which the indexing database has to be created
Returns
MAPISTORE_SUCCESS on success, otherwise MAPISTORE error

References MAPISTORE_ERR_DATABASE_INIT, MAPISTORE_ERR_NOT_INITIALIZED, MAPISTORE_ERROR, mapistore_indexing_search(), and MAPISTORE_SUCCESS.

Referenced by mapistore_add_context(), mapistore_indexing_record_add_fmid(), mapistore_indexing_record_del_fmid(), mapistore_indexing_record_get_uri(), mapistore_mgmt_register_message(), and mapistore_mgmt_registered_message().

_PUBLIC_ enum mapistore_error mapistore_indexing_record_add_fid ( struct mapistore_context *  mstore_ctx,
uint32_t  context_id,
const char *  username,
uint64_t  fid 
)

Add a fid record to the indexing database

Parameters
mstore_ctxpointer to the mapistore context
context_idthe context identifier referencing the indexing database to update
fidthe fid to add
Note
This is a wrapper to the internal common mapistore_indexing_record_add_fmid function.
Returns
MAPISTORE_SUCCESS on success, otherwise MAPISTORE error

References mapistore_indexing_record_add_fmid().

enum mapistore_error mapistore_indexing_record_add_fmid ( struct mapistore_context *  mstore_ctx,
uint32_t  context_id,
const char *  username,
uint64_t  fmid 
)

Add a folder or message record to the indexing database

Parameters
mstore_ctxpointer to the mapistore context
context_idthe context identifier referencing the indexing database to update
fmidthe folder or message ID to add
typeMAPISTORE_FOLDER or MAPISTORE_MESSAGE
Returns
MAPISTORE_SUCCESS on success, otherwise MAPISTORE error

References mapistore_backend_lookup(), MAPISTORE_ERR_INVALID_PARAMETER, MAPISTORE_ERROR, mapistore_indexing_add(), and mapistore_indexing_search_existing_fmid().

Referenced by mapistore_indexing_record_add_fid(), and mapistore_indexing_record_add_mid().

_PUBLIC_ enum mapistore_error mapistore_indexing_record_add_mid ( struct mapistore_context *  mstore_ctx,
uint32_t  context_id,
const char *  username,
uint64_t  mid 
)

Add a mid record to the indexing database

Parameters
mstore_ctxpointer to the mapistore context
context_idthe context identifier referencing the indexing database to update
midthe mid to add
Note
This is a wrapper to the internal common mapistore_indexing_record_add_fmid function.
Returns
MAPISTORE_SUCCESS on success, otherwise MAPISTORE error

References mapistore_indexing_record_add_fmid().

_PUBLIC_ enum mapistore_error mapistore_indexing_record_del_fid ( struct mapistore_context *  mstore_ctx,
uint32_t  context_id,
const char *  username,
uint64_t  fid,
uint8_t  flags 
)

Delete a fid record from the indexing database

Parameters
mstore_ctxpointer to the mapistore context
context_idthe context identifier referencing the indexing database to update
fidthe fid to remove
flagsthe type of deletion MAPISTORE_SOFT_DELETE or MAPISTORE_PERMANENT_DELETE
Returns
MAPISTORE_SUCCESS on success, otherwise MAPISTORE error

References mapistore_indexing_record_del_fmid().

enum mapistore_error mapistore_indexing_record_del_fmid ( struct mapistore_context *  mstore_ctx,
uint32_t  context_id,
const char *  username,
uint64_t  fmid,
uint8_t  flags 
)

Remove a folder or message record from the indexing database

Parameters
mstore_ctxpointer to the mapistore context
context_idthe context identifier referencing the indexing database to update
fmidthe folder or message ID to delete
flagsthe type of deletion MAPISTORE_SOFT_DELETE or MAPISTORE_PERMANENT_DELETE
Returns
MAPISTORE_SUCCESS on success, otherwise MAPISTORE error

References mapistore_backend_lookup(), MAPISTORE_ERR_DATABASE_OPS, MAPISTORE_ERR_INVALID_PARAMETER, MAPISTORE_ERROR, mapistore_indexing_add(), mapistore_indexing_search_existing_fmid(), and MAPISTORE_SUCCESS.

Referenced by mapistore_indexing_record_del_fid(), and mapistore_indexing_record_del_mid().

_PUBLIC_ enum mapistore_error mapistore_indexing_record_del_mid ( struct mapistore_context *  mstore_ctx,
uint32_t  context_id,
const char *  username,
uint64_t  mid,
uint8_t  flags 
)

Delete a mid record from the indexing database

Parameters
mstore_ctxpointer to the mapistore context
context_idthe context identifier referencing the indexing database to update
midthe mid to remove
flagsthe type of deletion MAPISTORE_SOFT_DELETE or MAPISTORE_PERMANENT_DELETE
Returns
MAPISTORE_SUCCESS on success, otherwise MAPISTORE error

References mapistore_indexing_record_del_fmid().

_PUBLIC_ enum mapistore_error mapistore_indexing_record_get_uri ( struct mapistore_context *  mstore_ctx,
const char *  username,
TALLOC_CTX *  mem_ctx,
uint64_t  fmid,
char **  urip,
bool *  soft_deletedp 
)

Returns record data

Parameters
mstore_ctxpointer to the mapistore context
usernamethe name of the account where to look for the indexing database
mem_ctxpointer to the memory context
fmidthe fmid/key to the record
urippointer to the uri pointer
soft_deletedppointer to the soft deleted pointer
Returns
MAPISTORE_SUCCESS on success, otherwise MAPISTORE error

References MAPISTORE_ERR_NOT_FOUND, MAPISTORE_ERR_NOT_INITIALIZED, MAPISTORE_ERROR, mapistore_indexing_add(), and MAPISTORE_SUCCESS.

struct indexing_context_list* mapistore_indexing_search ( struct mapistore_context *  mstore_ctx,
const char *  username 
)
read

Search the indexing record matching the username

Parameters
mstore_ctxpointer to the mapistore context
usernamethe username to lookup
Returns
pointer to the tdb_wrap structure on success, otherwise NULL

Referenced by mapistore_indexing_add().

enum mapistore_error mapistore_indexing_search_existing_fmid ( struct indexing_context_list *  ictx,
uint64_t  fmid,
bool *  IsSoftDeleted 
)

Convenient function to check if the folder/message ID passed in parameter already exists in the database or not and whether it is soft deleted or not

Parameters
ictxpointer to the indexing context
fmidfolder/message ID to lookup
IsSoftDeletedpointer to boolean returned by the function which indicates whether the record is soft_deleted or not
Returns
MAPISTORE_SUCCESS if the folder/message ID doesn't exist, otherwise MAPISTORE_ERR_EXIST.

References MAPISTORE_ERR_EXIST, MAPISTORE_ERROR, and MAPISTORE_SUCCESS.

Referenced by mapistore_indexing_record_add_fmid(), and mapistore_indexing_record_del_fmid().


Creative Commons License
Creative Commons Attribution icon Creative Commons Share Alike icon
This content is licensed under the Creative Commons
Attribution ShareAlike License v. 3.0:
http://creativecommons.org/licenses/by-sa/3.0/

openchange-2.0/apidocs/html/libmapistore/mapistore__mgmt_8c.html000066400000000000000000000717711223057412600252270ustar00rootroot00000000000000 OpenChange mapistore library 2.0 API Documentation
mapistore_mgmt.c File Reference

Provides mapistore management routine for administrative/services tools. More...

#include "mapiproxy/libmapistore/mapistore.h"
#include "mapiproxy/libmapistore/mapistore_errors.h"
#include "mapiproxy/libmapistore/mapistore_private.h"
#include "mapiproxy/libmapistore/mgmt/mapistore_mgmt.h"
#include "mapiproxy/libmapistore/mgmt/gen_ndr/ndr_mapistore_mgmt.h"

Functions

_PUBLIC_ enum mapistore_error mapistore_mgmt_generate_uri (struct mapistore_mgmt_context *mgmt_ctx, const char *backend, const char *username, const char *folder, const char *message, const char *rootURI, char **uri)
_PUBLIC_ struct
mapistore_mgmt_context * 
mapistore_mgmt_init (struct mapistore_context *mstore_ctx)
_PUBLIC_ enum mapistore_error mapistore_mgmt_register_message (struct mapistore_mgmt_context *mgmt_ctx, const char *backend, const char *sysuser, uint64_t mid, const char *rootURI, const char *messageID, char **registered_uri)
_PUBLIC_ enum mapistore_error mapistore_mgmt_registered_backend (struct mapistore_mgmt_context *mgmt_ctx, const char *backend)
_PUBLIC_ enum mapistore_error mapistore_mgmt_registered_folder_subscription (struct mapistore_mgmt_context *mgmt_ctx, const char *username, const char *folderURI, uint16_t NotificationFlags)
_PUBLIC_ enum mapistore_error mapistore_mgmt_registered_message (struct mapistore_mgmt_context *mgmt_ctx, const char *backend, const char *sysuser, const char *username, const char *folder, const char *rootURI, const char *message)
_PUBLIC_ struct
mapistore_mgmt_users_list * 
mapistore_mgmt_registered_users (struct mapistore_mgmt_context *mgmt_ctx, const char *backend, const char *vuser)
_PUBLIC_ enum mapistore_error mapistore_mgmt_release (struct mapistore_mgmt_context *mgmt_ctx)
_PUBLIC_ enum mapistore_error mapistore_mgmt_set_verbosity (struct mapistore_mgmt_context *mgmt_ctx, bool verbose)

Detailed Description

Provides mapistore management routine for administrative/services tools.

Using this interface virtually restrict mapistore features to the specific management functions subset.

Function Documentation

_PUBLIC_ enum mapistore_error mapistore_mgmt_generate_uri ( struct mapistore_mgmt_context *  mgmt_ctx,
const char *  backend,
const char *  username,
const char *  folder,
const char *  message,
const char *  rootURI,
char **  uri 
)

Register the mapping between a system user and a backend user for a specific backend.

Parameters
conn_infopointer to the connection information
backendthe name of the backend
vuserthe name of the matching user in the backend
Returns
MAPISTORE_SUCCESS on success, otherwise MAPISTORE error

Unregister the mapping between a system user and a backend user for a specific backend.

Parameters
conn_infopointer to the connection information
backendthe name of the backend
vuserthe name of the matching user in the backend
Returns
MAPISTORE_SUCCESS on success, otherwise MAPISTORE error

Retrieves a partial or complete URI from the backend depending on the specified parameters. This function is used by the mapistore management interface to get from backend either the expected URI for further registration or a partial (backend compliant) URI for partial search.

Parameters
mgmt_ctxPointer to the mapistore management context
backendthe name of the backend
usernamethe name of the user in the backend
folderthe name of the folder in the backend
messagethe name of the message in the backend
uripointer on pointer to the URI to return
Note
The returned uri is allocated and needs to be free'd using talloc_free() upon end of use.
Returns
MAPISTORE_SUCCESS on success, otherwise MAPISTORE error

References mapistore_backend_delete_context(), mapistore_backend_lookup_by_name(), MAPISTORE_ERR_INVALID_PARAMETER, MAPISTORE_ERR_NOT_INITIALIZED, and MAPISTORE_SUCCESS.

Referenced by mapistore_mgmt_register_message(), and mapistore_mgmt_registered_message().

_PUBLIC_ struct mapistore_mgmt_context* mapistore_mgmt_init ( struct mapistore_context *  mstore_ctx)
read

Initialize a mapistore manager context.

Parameters
mstore_ctxPointer to an existing mapistore_context
Returns
allocated mapistore_mgmt context on success, otherwise NULL
TODO: fix signal handler before restoring this code

sa.sa_sigaction = mgmt_ipc_notif_handler; sigemptyset(&sa.sa_mask); sa.sa_flags = SA_SIGINFO; if (sigaction(SIGIO, &sa, NULL) == -1) { perror("sigaction"); talloc_free(mgmt_ctx); return NULL; } se.sigev_notify = SIGEV_SIGNAL; se.sigev_signo = SIGIO; se.sigev_value.sival_ptr = (void *) mgmt_ctx; if (mq_notify(mgmt_ctx->mq_ipc, &se) == -1) { perror("mq_notify"); talloc_free(mgmt_ctx); return NULL; }

_PUBLIC_ enum mapistore_error mapistore_mgmt_register_message ( struct mapistore_mgmt_context *  mgmt_ctx,
const char *  backend,
const char *  sysuser,
uint64_t  mid,
const char *  rootURI,
const char *  messageID,
char **  registered_uri 
)

Register a message in the indexing database of the user

Parameters
mgmt_ctxPointer to the mapistore management context
backendthe backend for which we register the message
sysuserthe name of the openchage user
midthe message ID to register
uripartial URI without message extension
messageIDthe message identifier in the backend
registered_uripointer on pointer to the registered MAPIStore URI
Returns
MAPISTORE_SUCCESS on success, otherwise MAPISTORE error

References mapistore_indexing_add(), mapistore_mgmt_generate_uri(), and MAPISTORE_SUCCESS.

_PUBLIC_ enum mapistore_error mapistore_mgmt_registered_backend ( struct mapistore_mgmt_context *  mgmt_ctx,
const char *  backend 
)

Check if the specified backend is registered in mapistore

Parameters
mgmt_ctxpointer to the mapistore management context
backendpointer to the backend name
Returns
MAPISTORE_SUCCESS on success, otherwise MAPISTORE error

References mapistore_backend_registered(), and MAPISTORE_ERR_INVALID_PARAMETER.

_PUBLIC_ enum mapistore_error mapistore_mgmt_registered_folder_subscription ( struct mapistore_mgmt_context *  mgmt_ctx,
const char *  username,
const char *  folderURI,
uint16_t  NotificationFlags 
)

Check if the subscription described by NotificationFlags has been registered for specified folder.

Parameters
mgmt_ctxpointer to the mapistore management context
usernamethe username to lookup
folderURIthe mapistore URI to lookup
NotificationFlagsthe subscription type
Returns
MAPISTORE_SUCCESS on success, otherwise MAPISTORE error

References MAPISTORE_ERR_INVALID_PARAMETER, MAPISTORE_ERR_NOT_FOUND, MAPISTORE_ERR_NOT_INITIALIZED, and MAPISTORE_SUCCESS.

Referenced by mapistore_mgmt_send_newmail_notification().

_PUBLIC_ enum mapistore_error mapistore_mgmt_registered_message ( struct mapistore_mgmt_context *  mgmt_ctx,
const char *  backend,
const char *  sysuser,
const char *  username,
const char *  folder,
const char *  rootURI,
const char *  message 
)

Check if a message is already registered within indexing database for the user.

Parameters
mgmt_ctxPointer to the mapistore management context
backendthe name of the backend
sysuserthe name of the mapistore user (openchange)
usernamethe name of the user on the remote system the backend manages
folderthe name of the folder on the remote system the backend manages
messagethe name of the message on the remote system the backend manages
Returns
true if the message is registered, otherwise false

References mapistore_indexing_add(), mapistore_mgmt_generate_uri(), and MAPISTORE_SUCCESS.

_PUBLIC_ struct mapistore_mgmt_users_list* mapistore_mgmt_registered_users ( struct mapistore_mgmt_context *  mgmt_ctx,
const char *  backend,
const char *  vuser 
)
read

Retrieve the list of registered usernames

Parameters
mgmt_ctxpointer to the mapistore management context
backendthe name of the backend to lookup
vuserthe name of the virtual user to lookup
Returns
Allocated mapistore management user list on success, otherwise NULL
_PUBLIC_ enum mapistore_error mapistore_mgmt_release ( struct mapistore_mgmt_context *  mgmt_ctx)

Release the mapistore management context and destory any data associated.

Parameters
mgmt_ctxpointer to the mapistore management context
Returns
MAPISTORE_SUCCESS on success, otherwise MAPISTORE error

References MAPISTORE_ERR_NOT_INITIALIZED, and MAPISTORE_SUCCESS.

_PUBLIC_ enum mapistore_error mapistore_mgmt_set_verbosity ( struct mapistore_mgmt_context *  mgmt_ctx,
bool  verbose 
)

Set mapistore management verbosity

Parameters
mgmt_ctxpointer to the mapistore management context
verboseboolean value that sets or unset verbosity
Returns
MAPISTORE_SUCCESS on success, otherwise MAPISTORE error

References MAPISTORE_ERR_NOT_INITIALIZED, and MAPISTORE_SUCCESS.


Creative Commons License
Creative Commons Attribution icon Creative Commons Share Alike icon
This content is licensed under the Creative Commons
Attribution ShareAlike License v. 3.0:
http://creativecommons.org/licenses/by-sa/3.0/

openchange-2.0/apidocs/html/libmapistore/mapistore__mgmt__messages_8c.html000066400000000000000000000060311223057412600272400ustar00rootroot00000000000000 OpenChange mapistore library 2.0 API Documentation
mapistore_mgmt_messages.c File Reference

Process IPC messages received on command message queue. More...

#include "mapiproxy/libmapistore/mapistore.h"
#include "mapiproxy/libmapistore/mapistore_errors.h"
#include "mapiproxy/libmapistore/mapistore_private.h"
#include "mapiproxy/libmapistore/mgmt/mapistore_mgmt.h"
#include "mapiproxy/libmapistore/mgmt/gen_ndr/ndr_mapistore_mgmt.h"

Detailed Description

Process IPC messages received on command message queue.


Creative Commons License
Creative Commons Attribution icon Creative Commons Share Alike icon
This content is licensed under the Creative Commons
Attribution ShareAlike License v. 3.0:
http://creativecommons.org/licenses/by-sa/3.0/

openchange-2.0/apidocs/html/libmapistore/mapistore__mgmt__send_8c.html000066400000000000000000000143231223057412600263650ustar00rootroot00000000000000 OpenChange mapistore library 2.0 API Documentation
mapistore_mgmt_send.c File Reference

Provides mapistore management routine for sending messages/notifications from administrative/services tools to OpenChange Server/listener process. More...

#include "mapiproxy/libmapistore/mapistore.h"
#include "mapiproxy/libmapistore/mapistore_errors.h"
#include "mapiproxy/libmapistore/mapistore_private.h"
#include "mapiproxy/libmapistore/mgmt/mapistore_mgmt.h"
#include "mapiproxy/libmapistore/mgmt/gen_ndr/ndr_mapistore_mgmt.h"

Functions

enum mapistore_error mapistore_mgmt_send_newmail_notification (struct mapistore_mgmt_context *mgmt_ctx, const char *username, uint64_t FolderID, uint64_t MessageID, const char *MAPIStoreURI)

Detailed Description

Provides mapistore management routine for sending messages/notifications from administrative/services tools to OpenChange Server/listener process.

Using this interface virtually restrict mapistore features to the specific management functions subset.

Function Documentation

enum mapistore_error mapistore_mgmt_send_newmail_notification ( struct mapistore_mgmt_context *  mgmt_ctx,
const char *  username,
uint64_t  FolderID,
uint64_t  MessageID,
const char *  MAPIStoreURI 
)

Creative Commons License
Creative Commons Attribution icon Creative Commons Share Alike icon
This content is licensed under the Creative Commons
Attribution ShareAlike License v. 3.0:
http://creativecommons.org/licenses/by-sa/3.0/

openchange-2.0/apidocs/html/libmapistore/mapistore__test_8c.html000066400000000000000000000056221223057412600252320ustar00rootroot00000000000000 OpenChange mapistore library 2.0 API Documentation
mapistore_test.c File Reference

Test mapistore implementation. More...

#include "mapiproxy/libmapistore/mapistore.h"
#include "mapiproxy/libmapistore/mapistore_errors.h"
#include <talloc.h>
#include <core/ntstatus.h>
#include <popt.h>
#include <util/debug.h>

Detailed Description

Test mapistore implementation.


Creative Commons License
Creative Commons Attribution icon Creative Commons Share Alike icon
This content is licensed under the Creative Commons
Attribution ShareAlike License v. 3.0:
http://creativecommons.org/licenses/by-sa/3.0/

openchange-2.0/apidocs/html/libmapistore/middle_bg.jpg000066400000000000000000000005251223057412600231560ustar00rootroot00000000000000ÿØÿàJFIFddÿìDuckydÿîAdobedÀÿÛ„ÿÀdÿÄU Q¡Ña‘ÿÚ ?ßÀ#¿ªÚ0 ïæ¶œ ‡3Yû žñݲ ?ÿÙopenchange-2.0/apidocs/html/libmapistore/nav_f.png000066400000000000000000000002311223057412600223370ustar00rootroot00000000000000‰PNG  IHDR8³»`IDATxíÝK€ EÑ–·[†øBÑmkâÄÂH—prÓ¼.‚Žó‚ꎤR6Z VI±E‚5j³„lóš›iI˜¬ÞêçJ0ŒÑÑ/Žû›™uøñóÞ¿6sH ÝõyIEND®B`‚openchange-2.0/apidocs/html/libmapistore/nav_g.png000066400000000000000000000001371223057412600223450ustar00rootroot00000000000000‰PNG  IHDRô1&IDATxíÝ1 ÁOHf„á_ ->~¸åM iËMèÀƒS½ü‚<IEND®B`‚openchange-2.0/apidocs/html/libmapistore/nav_h.png000066400000000000000000000001421223057412600223420ustar00rootroot00000000000000‰PNG  IHDR ,é@)IDATxíÝA @BQ­³šÛ›Ð¢Žáà) )ëý éaÅèÜ¿Æo‡RlÐßIEND®B`‚openchange-2.0/apidocs/html/libmapistore/nav_tab.gif000066400000000000000000000014541223057412600226510ustar00rootroot00000000000000GIF89aPæïïïþþþýþýûüúõ÷óñôïøú÷ýýüúûù÷ùöôöòöøõïóíðôîóöñùúøüýûòõðïòìîòëíñëòõïõõõÿÿÿúúúîòìðóîêëéðððôôôñññýýýñôðÆÉÅìîëÇÊÆÈÊÆÏÏÎÇÊÅËÍÊêìéïóîçèæÎÏÍÐÐÐõ÷ôÊÍÉïñíÆÈÄÊÌÊêêéïóìüýüÊËÉÏÏÏèêçÕ×ÓüüûÍÎÌëíêÌÍËíñêÏÐÏùûøêëêòöðóõñÉÊÇñôîîñì!ù,Pÿ€ˆ‰Š‹ŒŽ‘ˆ‚@;/Ÿ ¡¢£¤¥¦§¨E(ƒ )·¸¹º»¼½¾¿À¸ 7„23ËÌÍÎÏÐÑÒÓÔÐ=*"DÝÞßàáâãäåæä8 îïðñòóôõö÷õ.A þÿ H° ÁƒM R ¡Ã‡#JœH±¢ÅŠ0)ˆÀ±£Ç CŠI²$Ɉ8Xɲ¥Ë—0cÊœIsæD-èÜɳ§ÏŸ@ƒ *”¢’*]Ê´©Ó§P£J:Q‚X³jÝʵ«×¯`­È@‚³hÓª]˶­Û·p‰ßÆ@ôÀݻxóêÝË·¯ß¿~O Bð °áÈ+^̸±ãÆ< @@¹²å˘3kÞ̹3gˆr Mº´éÓ¨S«^Ízõ D4 ÈžM»¶íÛ¸sëÞ­»¢Àƒ N¼¸ñãÈ“'·H€óçУKŸN½ºõë×} À½»÷ïàËO¾|y;openchange-2.0/apidocs/html/libmapistore/open.png000066400000000000000000000001731223057412600222140ustar00rootroot00000000000000‰PNG  IHDR à‘BIDATxíÝÁ €0 Ð׬ՙ\Àº€39—b!©9{|ðI>$#Àß´ý8/¨ÄØzƒ/Ï>2À[ÎgiU,/¬~¼Ï\ Ä9Ù¸IEND®B`‚openchange-2.0/apidocs/html/libmapistore/pixel_grey.gif000066400000000000000000000000531223057412600234000ustar00rootroot00000000000000GIF89a€îîî!ù,D;openchange-2.0/apidocs/html/libmapistore/sync_off.png000066400000000000000000000015251223057412600230630ustar00rootroot00000000000000‰PNG  IHDRàw=øIDATxíÝKhTWÀñÿä1I&3™8M¦Iš™†I3Ú©b$cÌ I1V1±-(Tö±±Ð.* t!‚K[¥Ä¥ˆ„¨´f£`l(øl©"Y”¤6ÆgÌTú}·sgîܹ ±d{8?æÌ¹÷;çÜuíÚ`:!±F¬¢BäŠ?ŰÄm'yÊÅ>ÑlU¯½üý‰è_‹?€Œê ]€Y(ŠNñ±8fý1°Öqún-eâ¨øtºmâÈ Ó0}b›ù%·©µ×Œ®=Ÿ0´³?Š1sŸ‹0€¯8À‘;_ ‹W|%\ Zð— >舽ln¨p©.aÇ{ )t;Ú b nŸš¯›65°¢¡2çÅÔ?Žž>Oдàuönm¤¢Ì`×­Z¬WjC~>‘Ö¾0+á {{©fÝ×Mæ·æÅ•ìÙ¼˜` Ý›%uA6´½ÅÆö¨Á,]k¢ÄW¼™u±›]‹ˆ7§¯iòh€ ¶¶¬ÏÖu1 ló —Ҷ̺–:ÞÍ\ÄcãÏxøhR²Êè‡Qt$¿ß§¨ ª fdºü<4BÿÙ[•f¸d7=.Mé9/—éªÃëù/ÿO Üaàò}€,‘j?Ÿõ.5Úšm?œÿŸ®ŽXÿ2¬#¸d píæ(£?cÛú¼!½›a1¥Þ—ŽòØ©ܾ7dÔK:‚ùÒ‰ì)Ê3‚Ü™àÌà]€,±H€µ+køöäu<|`·LhC7¹ÔeÍ Ÿ×Ÿ˜tÜ‹ óH$^2%l.êaeÐäýE”ÌÉ|ÅÜìî‰Ýsä }¸ýDû^hzé~ðR›¦Ã¡¿]|#ü¯@×—Ö‡[k¹–<|š(Ç*€Ý¹dÇtMé:Ýñø«Ø,êÅû¢]”' øXÓ_nò¡Æ|Øý /c§fžâOIEND®B`‚openchange-2.0/apidocs/html/libmapistore/sync_on.png000066400000000000000000000015151223057412600227240ustar00rootroot00000000000000‰PNG  IHDRàw=øIDATxíÝ_HTYÀñï8ã¤ó§i§4-g6ÆËÕ&kQ)¨Ô!Š0ÒURKÚ…„ê¡/»PEÁ>ìK-+KÁ²Ñ.Y”¾dEPaA‰ø°¥¶›ZSÓïÜ;3wºŠ–¯—߯gfîïœsçœWKÇñ.€ÉøD­¨a‘'¬âq_ôˆk¢ÀŒ ÀDŽøQ´ÄïC¨¶åñÏÿgÅ ñ 0„Y‚:qZ¦Á)~õâ€èLý0HVñ× žz-¿‰C“%¨g¦˜6€é8%Úõ¬ëwêÙUÏ¿˜ª³Ä }? ?€·3ÀÀž©Š À”K• @hà a±ðaÇæUe‹ sù~ë2²ì“&Ú&B*AÄljæºììi*˨,Ëçí»÷oÆ£T”,d[˜¼3-*ÁÀ…>å‡Ë çLÉŸçfk˜Ò éw#*AEjKUy>ûšËÉõ&{µ¢8—m5Ki¬ jjƒD*¿NŽÖigwÃ7Dª’mz骹úKÛ¾±ˆ¶M!æ¤ÍkÐ?šoý¬_åÓlXí#Ò~–¸¬ê×ÒÑXŠÓ‘ùRÙ*Eû‚ՂדðEÜ;6«e"Q(²Ù=–¿Ezæ5Kؼָ_ 1òzBªJë ±XŒì96åªjL^7{ùãJÑ÷1½i@%8'7M©_\Qœ#ÓUŒËñýÿyõ Wo Éx8¼s¥v¯ªì|×SnÜ q_m Ýé î>bèÕí[JX,½4[Tú{R£ë¼ôˆ¾þa€tÝjjzzÅ'ÅìȶiIžŽòwÏs ¡€—ÕKøõâC^ŽŒ˜Y­¨µÉ%6¨´êˆº]vÛðhâ½iWv–hôëê°Ò¨¾'æÌ‚·ñ|[ßìúÅ^€YrD=<ýDû]äÇ÷s€Ïõ‹8™ºCì? À ¨—t4õᩎ¡Jã‡W‹É± îr¼cjMɘìx| šE©øNÔ‰œøA¢þ«–€Z¼ñ‡jó î#™§¢¢4gIEND®B`‚openchange-2.0/apidocs/html/libmapistore/tab_a.png000066400000000000000000000002161223057412600223170ustar00rootroot00000000000000‰PNG  IHDR$ÇÇ[UIDATxíK €0C'o¤(Šˆ[Žà%Üxÿ#Ù©­ç ùÁöó¦W¦e# 3t I 3+¼øEã~\D½9¯Ûàè’wM·¿öÿ}Yõ_êA4Yžã}IEND®B`‚openchange-2.0/apidocs/html/libmapistore/tab_b.png000066400000000000000000000002471223057412600223240ustar00rootroot00000000000000‰PNG  IHDR$ÇÇ[nIDATxíÝQ Â0„áàœR¥Xc±I7IÓ¨g|òÕÙœäãgY˜3˜Ï÷‡u{£ÔW—ÊSíŒ1Ü ¼CjˆiC†G¬ýççJ+| ÖÝs7ùŒ+Ù›`t‚3Ü‚a¢K¤Gq°ûQÍZÝT=@*éC݇LIEND®B`‚openchange-2.0/apidocs/html/libmapistore/tab_h.png000066400000000000000000000003001223057412600223200ustar00rootroot00000000000000‰PNG  IHDR$ÇÇ[‡IDATxíÝË ‚@EÑ 7êÂX’Ñø AADùjGü€ Z€e؈£ ë8¹›—Wƒx¾ÞìUK.µ%„0mɤ&+4iÑ$džÈt“׿ÍzWf5AZá'w¼øÆ"2¶Wœðòg%öªdæ)æþ™ÉR15F®dìž ÉБßO«×Áô»C"à@¯g=IEND®B`‚openchange-2.0/apidocs/html/libmapistore/tab_s.png000066400000000000000000000002701223057412600223410ustar00rootroot00000000000000‰PNG  IHDR$ÇÇ[IDATxíÝ ‚@@Ñ£?Q…¤"š¢%¦I‘—Šf–6[´HÃäQƒ<Þâõþ]ždr Í’s?ˆO=Ñññw'ÌF‡Ž íðö-~rÃ[œèŠ­ì¬mƒÖ¬ƒݯнŠÕF)Yº% §`nÌ,9B ™’©!ÑŒ\ý<Å#üîî•IEND®B`‚openchange-2.0/apidocs/html/libmapistore/tabs.css000066400000000000000000000022131223057412600222050ustar00rootroot00000000000000.tabs, .tabs2, .tabs3 { background-image: url('tab_b.png'); width: 100%; z-index: 101; font-size: 13px; font-family: 'Lucida Grande',Geneva,Helvetica,Arial,sans-serif; } .tabs2 { font-size: 10px; } .tabs3 { font-size: 9px; } .tablist { margin: 0; padding: 0; display: table; } .tablist li { float: left; display: table-cell; background-image: url('tab_b.png'); line-height: 36px; list-style: none; } .tablist a { display: block; padding: 0 20px; font-weight: bold; background-image:url('tab_s.png'); background-repeat:no-repeat; background-position:right; color: #283A5D; text-shadow: 0px 1px 1px rgba(255, 255, 255, 0.9); text-decoration: none; outline: none; } .tabs3 .tablist a { padding: 0 10px; } .tablist a:hover { background-image: url('tab_h.png'); background-repeat:repeat-x; color: #fff; text-shadow: 0px 1px 1px rgba(0, 0, 0, 1.0); text-decoration: none; } .tablist li.current a { background-image: url('tab_a.png'); background-repeat:repeat-x; color: #fff; text-shadow: 0px 1px 1px rgba(0, 0, 0, 1.0); } openchange-2.0/apidocs/html/libocpf/000077500000000000000000000000001223057412600174705ustar00rootroot00000000000000openchange-2.0/apidocs/html/libocpf/24px-Cc-by_white.svg.png000066400000000000000000000053061223057412600237300ustar00rootroot00000000000000‰PNG  IHDR°çá»bKGDÿÿÿÿÿÿ X÷Ü pHYsHHFÉk> IDATXýXmP”U¾vˆeY pW$gQH–%ãËc*$åÃIkFmiØ‘ttrê‡C öa3 Œc†D$ e¬±X, «@³ Â.Èîõþy›uÓ÷·÷úóÌœçÜϹîëºçÜç<þxHØNÛNÛN½+zWô®.–_,¿X|»æÛ5ß® Q†(C`4F#p×ý®û]w@qRqRqðÿÎÿ;ÿcaÇÂŽIÅIÅIÅ@˜$L&Ämâ6qÛòÀ‡Ä-í-í--ùVë[­oµ’ <. … ¡B¨øSRT(*’’IŽ$‡”æHs¤9¤S’S’S‰ð>°Ï÷ˆôˆôˆ$Óôiú4=Ù2Ú2Ú2JZ•V¥Uù`^‚û9À3<Ã3À7ýßôÓl?Ø~°¸ªºªºªœ‡œ‡œ‡€ 6Øpx&õ™ÔgR0—0—0ÀMá¦pSB©P*”–õ–õ–õ@²GÙ£šª›ª›ª¦mMÛš¶#êõˆðj÷j÷jöeïËÞ— äÎäÎäÎÒ^i¯´÷að£ýȳégÓϦ“K{–ö,í±+¦êRu©ºÈŠÎŠÎŠNòöÔí©ÛSë£sñsñsñd{^{^{™u%ëJÖÒÅÛÅÛÅ›IER‘”ÔìÕìÕì%ÇSÇSÇS~gAuuu¤|µ|µ|5)øJð•à+rGËŽ–-äÀ±cÇþs‚å)ËS–§ÈÒ-¥[J·ž»=w{î&µ‚ZA-™÷BÞ y/³£³£³£‹$psäæÈÍR•¨JT%ÚßñýŽïw|OšÌ&³Éü¿'þWX­ÖFòÔ“§ž<õ$é6â6â6Bºæ»æ»æ“ÕÕÕ÷&°Ÿû¹Ÿ<”p(áP‚xxQxQxyëÀ­·üóÄÿŠùçœÿ‘Ô®Ô®Ô®´óŠx.⹈çÈÁÎÁÎÁN7ŽÜ8rã¹æÙ5Ï®y–tŠwŠwŠ'+++ÿÿÄÿŠã€qÀH¿üzðë¤(H$ "‹4Eš" ) ø0àÀ:³ñÌÆ3··7à é é  pNwNwN¦º¦º¦º€ZS­©Ö\K¹–r-èÎíÎíΆg†g†gOgOgOgÀ˜bL1¦õâzq½XÒ·¤oI SÊ”2%033TÿQýGõ€h§h§h'àëëkßdÜÜÝÜÝ܉sç&Î õ õ õÀ¸iÜ4n°uÕÖU[WÙ-*4š ©õ^^^r¹Ãr‡å¤S•S•SéêêJºMºMºM’»rwåîÊ%ûûûIE¤"RIîÙ¼góžÍäÜÆ¹sÉý'öŸØ‚”'Êå‰dÛ–¶-m[îï„N£Óè4¤ÇÛo{¼MŠä"¹HN {]z]z]Ñ:Ñ:Ñ:@¥T)UÊE¶Û!q¸k¾k¾k2e™²LÐÛÛ ¤½Ÿö~ÚûÀ¥ÉK“—&ÿVÿVÿV c.c.c¨­­Ê®•]+»œK>—|.ˆÔDj"5@[t[t[4 _ª_ª_ºpýÕΫW;>Y>Y>Y€õwëïÖ߈§ÄSâ)R'‰“Ä‘Í7›o6ß\¨€Ál0̤¼SÞ)ï$ƒR‚R‚RÈ—3_Î|9“ô³øYü,dÒ¤I7H‹ŸÅÏâGöÕôÕôÕAùAùAù¤Ä 1H dÈùó!çɲÀ²À²@R\".—Å?ÿTüÓÂõïîîÈ(×(×(W{Åç:æ:æ:¡£ÐQèˆÒDi¢´E:žAª U L©§ÔSj`$a$a$pLvLvL†¶mÚ VVV~‰~‰~‰À®_wýºëWÀrÄrÄrÈPf(3”ÀóåÏ—?_|ôÉGŸ|ô ·!nC܆E–o4 šQ¨(Tj*ŠÅŠb`V2+™•o‹·Å{±– ‚€5Ôj Ò­éÖt+P¡þBý ðzáõÂë@÷+ݯt¿èôú{x`c`c`#à~Úý´ûi À` °K>_òù’ϵ«ÚUí È5r\³È!2Ï–g˦ççÃïy}9úrôe»%%×K®—\_¤„ú }†>R!UHRò1ŸÇ|ó!ãZãZãZIe´2ZM.»³ìβ;d{{{¿=¾á†7Þ =.x\ð¸@Ö)ë”uJ²¥­¥­¥\öȲG–=B~œúqêÇ‹z²{²{²Iß}¾û|÷ÝSBª¯U_«¾¶'ÔTßTßTÌý6÷ÛÜoöqéyéyéyàÅÒK_,ÔoªßT¿ xj=µžZ F#‘'kOÖž¬B2B2B2ìñò+ò+ò+ÀK›^ÚôÒ&@Þ!ïw2³Ì,3¿Düñ  ($ ÉBt't't'€Á̓›7+›V6­lÐÜÜL>ŠGñ(Hï×¼_ó~¼úóÕŸ¯þ|5¬a iK±¥ØRH[€-À@Ú²mÙ¶l’{¸‡{þ¦#íænî&mkmkmkIÆ1Žq$ýéOÒ*° ¬Òö¥íKÛ—ö°™’™’™2ùpòáäÃvås r r H˜½Ì^f/r[Ö¶¬mYö Y]Y]Y]¤ùóæþávû7¨\W¹®r)žψgHŸ­>[}¶’º]‰®äžÃ\K]K]KéuÉë’×%Rü©øSñ§di|i|i#FQ`$c¼b¼b¼ÈŽ‹;.Þ_€^êg3f3f3Èʵ•k+×’êUêUêU¤Ãr‡åËIÇq'=4 ¹~lýØú12*+*+*‹ŒÍÍÍ'Ueª2Uéû®ï»¾ï’!!!v¥W„­[FjõZ½VO' ' '<ØÁ‡þ+ñ'†††È¢²¢²¢22\® ב2™ƒÌNèAOßbßbßb2Ç%Ç%Ç…ÔéuzžœŸŸx>ÿ^5¡–ü+^:tEXtComment Created with Inkscape (http://www.inkscape.org/) ã+ldIEND®B`‚openchange-2.0/apidocs/html/libocpf/24px-Cc-sa_white.svg.png000066400000000000000000000053061223057412600237210ustar00rootroot00000000000000‰PNG  IHDR°çá»bKGDÿÿÿÿÿÿ X÷Ü pHYsHHFÉk> IDATXÕX}LÓW>¿ ´–.Ôb±‚" Cèê(lS„9ÉuN&n ʹŒ,+&+™“à&3[a`Ë$™ãs‰3Ö¨L(ŠX¸Åñá¬EÄ4ElK¡åyÿy÷–¼µ/¾çŸ›ÜsŸsžûœÓ{· þmô”¶ðà?¬Y3²†èBý…ú õD—7\ÞpyÑpâpâp"‘Ñh4DóÏÌ?3ÿ QPmPmP-QØoa¿…ýFw"îDÜ ¢ŒÊŒÊŒJ¢8n7ŽKäwÃï†ß§eCDxJ3›ŠMÅÀgW?»úÙU ‚‰`"€Ä bý#À>Ê>Ê> p ¸Ü€WÀ+àË3–g,Ïèú†¾q¯Ø°%` ===è&tº ÀéŠtE.Í‹ñVœÁœ!ºxçâ‹wˆ>5|jøÔ@Ô#ë‘õȈ|Ç|Ç|Lj^,z±èÅ"¢m»·íÞ¶›(Žljãùùù±x,‹G4;;K499IÔÞÚÞÚÞJÔ¾§}Oû"s‚9Áœ@$4 BQa~a~a>Ñ!Û!Û!o„7Âyš ¬Çz¬ßi|§ñ`ÕЪ¡UCnÅdý²~Y?ÐÔ×Ô×ÔLÍLÍLÍÂGø8¶ãØŽc;ÜÄãËãËãËS‘©ÈTäxÏ®ž]=»€Wv^Ùy´ Z­SÏÔ3õ‹~Ü&¶‰mÄ_‰¿ ;v( 05›šMÍžqÝÎng7P¼¶xmñZwœ—^éõ—^îõÝë»×Ð`é`é`)°áµ ¯mx Xž²äeò2y™'ñA„ B”ØJl%6 nUݪºU€*Z­ŠÄÄÄ“Ïä3€å[Ë·–o½ãq·qØkÝkÝkõl¥ÏÕŸ«?W{Â?~< $®H\‘¸Â½Þg®w®w®—ˆ³Œ³Œ³ŒˆÍÎfgQuQ—§¯È_‘¿"'Ò˜5f™Hë¯õ×úûëØ_Çþ"âïçïçïÿß.ëi=­'ò©õ©õ©õtϧϧϧ{Î3LÓAÄ–²¥l)éHG:"VPePeP%‘ƒëà:¸D³³³ÞóOØ'ìv¢Õ©«SW§åìËÙ—³È,7ËÍr"G…£ÂQá?—7—7—G4ùóäÏ“?{ú\WÀõœ_P-¨TDÖxk¼5~‘ckçÖέî’TýQõGÕÞ;à|Öù¬óY@ÀÉ€“'Þ:Þ:Þ:@œ&N§cccÞñÝ‚nA·ý$úIô“;/š?ÍŸtƒºAÝN¡¡ü¡ü¡| ¤0¤0¤pQë}RôIÑ'¯³¾ÎúpŒ9ÆO 2Z3Z3ZÄŒ9s㇓w%ïJ޴ŶŶÅwDwDwDÀÅ÷/¾ñ}`Ëw[¾Ûò'îÍóožó<`}×ú®õ]ϼgfÏÌž™XZ––¥Ö¶¯m_ÛP‡¤CÒ!$ ~ø!ÐógÏŸ=zW²V]«®Uœ:N§n¡(Š¢(À?Ê?Ê? Í Í Íxž…gñ$ê u…º€®³]g»Îzæ±UÙªlU€¼D^"/Yto¨ Ôj€ìB»Ð.ö(ö(ö(Ü ýŠ~E?`ï²wÙ»<;„¡ChÞм¡y±D,ë 7ò¬V +Ø”»)wS.pI}I}Ií]¨æèæèæhÀÏægó³Á™Á™Á™€¾J_¥¯Zô1§Óê´:- ¼"¼"¼ø}ï÷½ß÷@uJuJu àZp-¸<8wþîü0ì7ì7ìJ5¥šR ùwæß™ÛÓ·§oOÞî|»óíNà”ñ”ñ”ý–ý€~@Äì‹Ù³Ï-@qqq?° ].HmÀ5åšrMǧOŸXm¬6V°²deÉÊàtÆéŒÓ€óWç¯Î_½'F ZÐ8ßs¾ç|˜+Ÿ+Ÿ+\®W€ILbÒ;ü¦ô¦ô¦ØÜ°¹asƒ›xÒñ¤ãIÇñeãËÆ—¹×{¼   ¥F©QjV:+•ð[ø-ü@=®W÷ÎÝ;wïÜÒ„–2[Ž-Ç–4O7O7O76nlt—<”<”<zózózó<ñ^ßÄ–dK²%PVVx¾<_ž/À\b.1—I¶$[’ |Éÿ’ÿ%Ðwê;õÀdÅdÅd` ³†YÃk‹µÅÚÌlÙ:³>0|`øP¯®W׫ù«òWå¯Ü:n·`ŒŒ‘1IÂ$a’è½Ð{¡÷‚w–|Ô;ö:ö:öÍÏ7?ßü<šš øˆ}Ä>b€4¤!   P(ØÉØÉØI Q‘¨HTÉG’$d5²Y r2ädÈIÀçŸ|^p+½&nMÜš8 x x xß1¾c|ÇÒ|ê%þ±±gÇž{(¯)¯)¯âõñúx=àÃ÷áûð—>…þC*C*C*N§€èôúÀ™âLq¦<=ŸYΧюéÈ:tEXtComment Created with Inkscape (http://www.inkscape.org/) ã+ldIEND®B`‚openchange-2.0/apidocs/html/libocpf/CC_SomeRightsReserved.png000066400000000000000000000064521223057412600243360ustar00rootroot00000000000000‰PNG  IHDRZ¬a x pHYs  šœtIMEÕ ÌIðbKGDÿÿÿ ½§“ ·IDATx^í™iŒUEÇû¾{ßÚÝ6ë"²Š‚@!`˜DÇ¡Ä "Œ2 ×%Æ(ê—D£ñƒ1¨â’Œ@Pƒ¢HezXš¦é†¶~¯ßrç÷ïÜêyV¼ 1í„VòçÔz«þuêÔ¹÷9%¿Nr@$Bd\ºP¤Ç¤KˆÒ•HD€’È|² È h‘,Ò›= lœ)Ò›Íøí´2$Ù"ír«,n¤…˜Õ?À+B¸4d¤à `d‘ž—Þ†vL‘_‰h×&By#Äl ,‹OHIÚyû¤Ø°N‡¤g¡èäÒùnÑ‹0 g­Kë!í i6IÁ¶dËŠ…‚bÉFÝ?Ÿ-ÚŠ°áÙ–eÈO&“‰gŸ}vä–-[¦œ8qâŽ\.7çÌ™3Ó÷ìÙ3áý÷ß¿büøñÝdÉňÅb©Ç{lÐ÷ßÿ‡ãÇÏ ÏÜæææ¿8p`ÎòåË+§L™ÒËz– {®ƒö½´Ú?Å­cݦ[e‰â²áÇw]¶lÙ´¾}ûBfxrçfÞ_|±»bÅŠ!ƒ *ÿ}]xÍÒ’V™OŸï ¤­{–.¸Xrì“O>ù“!yûöí 7ß|óêT*õwÊÖ<óÌ3ûNž<™S]±%Óg˜!yóæÍM7ÞxãÚÒÒÒ¥lÀâW^yeÝéÓ§3ª3Ï q5nHÞÎW‹ŽXVœ ½ÄŒ/¾øâè|p¢Ø·o_ãСC¿J§Ó­‘ˆÁ€Ê>ûì³—^ziµÚÍŸ?¿âÕW_í!}çΧG޹9“ÉüÄZ9%.}*{öì¹ð,–kK»¬p>Z´‰s£[å6\ÉÊÊÊ¡f€—_~ù_±#“½{÷:|ÈlÒ­·ÞÚÁôyþùç Ù³ýð¶mÛÒ¼È ýG2$ïXh—äµ?Ñá °7£OŸ>ÝÍøéc¶»Q+êp±ú˜é³råÊûb³78¶ 1Ë@Îï8ڱɷõb²ñÑqÓøÈ‘#9Ûê‹`ÜI²¢¢¢mîÇŽioŠÉ ß\#C²†óÐu„è>ˆ„µÃU´˜L÷îÝcöÆXäy Ååè›>;wöl²Î‘<'l íî:|ßïÐ^ƒmܸÑûâ‹/R555‰£G&!#ÉÍŸjiiI€$~4‘ÍfS<3U(ù|>!YWW÷Ã%—\ÒScÜvÛm=Þyçã´ñ€ "À´a¤<²y×®]±Ñ£G»êsÓM7¥/^|š0γD"qd©)D£Ñ‚ëº>(ñ<Ï!ïÁD€KÄâ^pÁ^×®]½þýûGG»æšk²í壎hÿ—ì&t¯ºêªDÇŽSç/‰ü1Á DB„Cr²“È/ñï¾û®Ú=oÞ¼Á«V­Ú€•»l‚ ’ýnݺ9o½õVçIˆË}ùå—ˆ.UŸ‡z¨ÓºuëWsvIž€ï/ýõ×õÒò7òˆ|P"‚ãñx+ɉDB$ srª¢½{÷Ž:êtåI¿”§VKqöÆç>8dF°4Y³‡èä©S§â”'xÃK@r\0dƒ¸ÈfÑ©×^{m . \ãa_¸pa͆ 2eee¥×]w]§Ù³gwÁÚ´‘GÔF$}øá‡{õêå)_UUuúÍ7߬ٺuë:uÊOœ8±ãÔ©SB^ ‹ÿ+äf »b3œ¡:@†x= Ùiü~¦C‡é.]º¤ÙØ QN3ýE´c‘z.ût Ñã• 'ôÜwÒœC‡űæ8¯Ã²è˜ˆ†ä¸¬ZRD$Çò²êaX—ûî»od—…ÎÜ÷Kn¸á†ƒÈV]ÀêܧŸ~ºë…^;[Ÿ»îºk‘!¤A‹ò\ÂÑ­`#Óll Va61­S`Nz8ܧžzêrë±Ñ%amŠÛâE`)$¤°ž$H±¨V“ÿMqEJÒYd î¯]»¶™§Øƒÿ›P¨¯¯ÏàN¾ñÆGñë9Ú°´zvÍš5M¸™,㔀ˆéÓØØxŠ7ÌÚ?þx#d·@bIyy¹ƒŒX¯ "Pç"=ê$]¤GY4„#Ût›3ÆG;ç°3þ9„>>ĉ´$DuAZ ×!b£" –%G%!$J[å¥{HwQ © ô­KQÒEF°´¶èEV òëׯo¤_=$çØì2+ g±È,® Ɔ—°yÅ £ e¾Ñ6/ÊI?%&)’€hî£ëtt´^~ä}‘Œlõ딹ä[A>á’Q ’uZZ@–òlȧÒPÂmiÝ1”àp_ä‡í¤Êb<‘*²Ñ•$[‰ HÑ’Ê»"2% Éå!URd;"8€X³’¤A„ä—ä{$‘/QˆDIr³Áüäzb¤2«r…ƒg#ÖÒC91á]…UîôIaÖl„N^£+ŽÕÊÛˆ’Fò’&/˜ÐN1´¤±nG©Øª€acÝH§ØºE0R¹²æ"Œ/=t?´¡`.ÄšM:«±àDæÎ;ž[ÎsÏ=7’ ©O¿~ýoûh#Øåy›6mêÅGšÞ¯{T¦~Lêµ½þúë')o±^N})Ÿ9ï Þüî»ï*ÔJ¦HcÇŽ­ä¢Ià³Ëˆ›¯ tÅÇû¡„V1.¢èôéÓ/G÷„Ûo¿}0Ò%Vî?cÆŒA?üpß%K–t&Bé‡/¯Ï&JP[éJÖ¼ûþùç=xNœ‹-~íµ×þž—¡±<çwšÃK/½4Œ²Ê÷Þ{oëÓúèÞξ¥s eKu¤¦M›¶öJW;AþLõÒ L×°Œpn¹üŸ1WCBšèá«Ã‡¯¡,W]]ý-ñmý#zTܨêŠ]ª)ã›ù)Þ./“.‹Þüõ×_ïâm*Ë—³²œÊ£ó Ü|°wÑ¢E²¦¶zŽHžÎ°ÓÊÛàRÛ*ÿ©yŽì¼*^`ªd‘¼Ììfü<ñî>\×q^:²lÈA¬þ ãØ"H¯­­=Ì‹Pý ’K—.=¦·?Œ¢^yÕ ¤Z¾›R‘Ìiiâ µ«Ý¯2æšÁ5œàÌ.>­V3FÒªpaÛ5Oꛃµl1ëÓéxüñÇkUÆÿ’UãÆ;‰;Ép¯l ã@ÙŠèý úÉ'Ÿlš5kÖIÞós¼Å€”ê=zäT/BL;£•W Ê[¨D*ǹŽ;@ãÖæRúa&œƒ˜zȯg¬ßEØ€£ÒqeÇ8ÒÒ% I—ظ33gÎLKW½ú©þ»‰gæÉ7˜ñ±ò:=bk™GíO%ƒŽñ}CãÙQQ mEõLŽzÏÌ«LÏ4m!ÚçBup›)½ä´­Å¬¿ÃÊÇá.è7±ÏÅáCŒÏDýÝ»wûJøÈVië,ºµíœ9s|;Ùí¹©}.Ÿ”aŒ>dû,ÆçHZ}Btk¾çöL{®öv}ø8Òq¡¡˜²!C†ø&Lðq]¾DÿÊé7üFôÿÿj|w‚%&IEND®B`‚openchange-2.0/apidocs/html/libocpf/apidocs.css000066400000000000000000000362151223057412600216330ustar00rootroot00000000000000/* ** WEBSITE ** */ BODY,H1,H2,H3,H4,H5,H6,P,CENTER,TD,TH,UL,DL,DIV { font-family: Geneva, Arial, Helvetica, sans-serif; } BODY,TD { font-size: 90%; } H1 { text-align: center; font-size: 160%; } H2 { font-size: 19px; font-weight: bold; color: #3E93D5; } H3 { font-size: 100%; } P { text-align: justify; } LI { li-style-type: square; li-style-position: outside; display: list-item; } CAPTION { font-weight: bold } DIV.qindex { width: 100%; background-color: #e8eef2; border: 1px solid #84b0c7; text-align: center; margin: 2px; padding: 2px; line-height: 140%; } DIV.nav { width: 100%; background-color: #e8eef2; border: 1px solid #84b0c7; text-align: center; margin: 2px; padding: 2px; line-height: 140%; } DIV.navtab { background-color: #e8eef2; border: 1px solid #84b0c7; text-align: center; margin: 2px; margin-right: 15px; padding: 2px; } TD.navtab { font-size: 70%; } A.qindex { text-decoration: none; font-weight: bold; color: #1A419D; } A.qindex:visited { text-decoration: none; font-weight: bold; color: #1A419D } A.qindex:hover { text-decoration: none; background-color: #ddddff; } A.qindexHL { text-decoration: none; font-weight: bold; background-color: #6666cc; color: #ffffff; border: 1px double #9295C2; } A.qindexHL:hover { text-decoration: none; background-color: #6666cc; color: #ffffff; } A.qindexHL:visited { text-decoration: none; background-color: #6666cc; color: #ffffff } A.el { text-decoration: none; font-weight: bold } A.elRef { font-weight: bold } A.code:link { text-decoration: none; font-weight: normal; color: #0000FF} A.code:visited { text-decoration: none; font-weight: normal; color: #0000FF} A.codeRef:link { font-weight: normal; color: #0000FF} A.codeRef:visited { font-weight: normal; color: #0000FF} A:hover { text-decoration: none; background-color: #f2f2ff } DL.el { margin-left: -1cm } .fragment { font-family: monospace, fixed; font-size: 95%; } PRE.fragment { border: 1px solid #CCCCCC; background-color: #f5f5f5; font-size: 11px; margin-top: 4px; margin-bottom: 4px; margin-left: 2px; margin-right: 8px; padding-left: 6px; padding-right: 6px; padding-top: 4px; padding-bottom: 4px; } DIV.ah { background-color: black; font-weight: bold; color: #ffffff; margin-bottom: 3px; margin-top: 3px } DIV.groupHeader { margin-left: 16px; margin-top: 12px; margin-bottom: 6px; font-weight: bold; } DIV.groupText { margin-left: 16px; font-style: italic; font-size: 90% } BODY { background: white; color: black; margin-right: 20px; margin-left: 20px; } TD.indexkey { background-color: #e8eef2; font-weight: bold; padding-right : 10px; padding-top : 2px; padding-left : 10px; padding-bottom : 2px; margin-left : 0px; margin-right : 0px; margin-top : 2px; margin-bottom : 2px; border: 1px solid #CCCCCC; } TD.indexvalue { background-color: #e8eef2; font-style: italic; padding-right : 10px; padding-top : 2px; padding-left : 10px; padding-bottom : 2px; margin-left : 0px; margin-right : 0px; margin-top : 2px; margin-bottom : 2px; border: 1px solid #CCCCCC; } TR.memlist { background-color: #f0f0f0; } P.formulaDsp { text-align: center; } IMG.formulaDsp { } IMG.formulaInl { vertical-align: middle; } SPAN.keyword { color: #008000 } SPAN.keywordtype { color: #604020 } SPAN.keywordflow { color: #e08000 } SPAN.comment { color: #800000 } SPAN.preprocessor { color: #806020 } SPAN.stringliteral { color: #002080 } SPAN.charliteral { color: #008080 } .mdescLeft { padding: 0px 8px 4px 8px; font-size: 80%; font-style: italic; background-color: #FAFAFA; border-top: 1px none #E0E0E0; border-right: 1px none #E0E0E0; border-bottom: 1px none #E0E0E0; border-left: 1px none #E0E0E0; margin: 0px; } .mdescRight { padding: 0px 8px 4px 8px; font-size: 80%; font-style: italic; background-color: #FAFAFA; border-top: 1px none #E0E0E0; border-right: 1px none #E0E0E0; border-bottom: 1px none #E0E0E0; border-left: 1px none #E0E0E0; margin: 0px; } .memItemLeft { padding: 1px 0px 0px 8px; margin: 4px; border-top-width: 1px; border-right-width: 1px; border-bottom-width: 1px; border-left-width: 1px; border-top-color: #E0E0E0; border-right-color: #E0E0E0; border-bottom-color: #E0E0E0; border-left-color: #E0E0E0; border-top-style: solid; border-right-style: none; border-bottom-style: none; border-left-style: none; background-color: #FAFAFA; font-size: 80%; } .memItemRight { padding: 1px 8px 0px 8px; margin: 4px; border-top-width: 1px; border-right-width: 1px; border-bottom-width: 1px; border-left-width: 1px; border-top-color: #E0E0E0; border-right-color: #E0E0E0; border-bottom-color: #E0E0E0; border-left-color: #E0E0E0; border-top-style: solid; border-right-style: none; border-bottom-style: none; border-left-style: none; background-color: #FAFAFA; font-size: 80%; } .memTemplItemLeft { padding: 1px 0px 0px 8px; margin: 4px; border-top-width: 1px; border-right-width: 1px; border-bottom-width: 1px; border-left-width: 1px; border-top-color: #E0E0E0; border-right-color: #E0E0E0; border-bottom-color: #E0E0E0; border-left-color: #E0E0E0; border-top-style: none; border-right-style: none; border-bottom-style: none; border-left-style: none; background-color: #FAFAFA; font-size: 80%; } .memTemplItemRight { padding: 1px 8px 0px 8px; margin: 4px; border-top-width: 1px; border-right-width: 1px; border-bottom-width: 1px; border-left-width: 1px; border-top-color: #E0E0E0; border-right-color: #E0E0E0; border-bottom-color: #E0E0E0; border-left-color: #E0E0E0; border-top-style: none; border-right-style: none; border-bottom-style: none; border-left-style: none; background-color: #FAFAFA; font-size: 80%; } .memTemplParams { padding: 1px 0px 0px 8px; margin: 4px; border-top-width: 1px; border-right-width: 1px; border-bottom-width: 1px; border-left-width: 1px; border-top-color: #E0E0E0; border-right-color: #E0E0E0; border-bottom-color: #E0E0E0; border-left-color: #E0E0E0; border-top-style: solid; border-right-style: none; border-bottom-style: none; border-left-style: none; color: #606060; background-color: #FAFAFA; font-size: 80%; } .search { color: #003399; font-weight: bold; } FORM.search { margin-bottom: 0px; margin-top: 0px; } INPUT.search { font-size: 75%; color: #000080; font-weight: normal; background-color: #e8eef2; } TD.tiny { font-size: 75%; } a { color: #1A41A8; } a:visited { color: #2A3798; } .dirtab { padding: 4px; border-collapse: collapse; border: 1px solid #84b0c7; } TH.dirtab { background: #e8eef2; font-weight: bold; } HR { height: 1px; border: none; border-top: 1px solid black; margin-bottom: 50px; } /* Style for detailed member documentation */ .memtemplate { font-size: 80%; color: #606060; font-weight: normal; } .memnav { background-color: #e8eef2; border: 1px solid #84b0c7; text-align: center; margin: 2px; margin-right: 15px; padding: 2px; } .memitem { padding: 4px; background-color: white; border-width: 1px; border-style: solid; border-color: #ccc; -moz-border-radius: 8px 8px 8px 8px; margin-bottom: 30px; } .memname { white-space: nowrap; font-weight: bold; font-size: 12px; margin: 10px 10px 10px 10px; } .memname EM { color: #45417e; } .memdoc{ padding-left: 10px; padding-right: 10px; } .memdoc EM, TD { font-size: 12px; } .memproto { background-color: #e9e9f4; width: 100%; border-width: 1px; border-style: solid; border-color: #ccc; font-weight: bold; -moz-border-radius: 8px 8px 8px 8px; } .paramkey { text-align: right; } .paramtype { white-space: nowrap; } .paramname { color: #602020; font-style: italic; white-space: nowrap; } /* End Styling for detailed member documentation */ /* for the tree view */ .ftvtree { font-family: sans-serif; margin:0.5em; } .directory { font-size: 9pt; font-weight: bold; } .directory h3 { margin: 0px; margin-top: 1em; font-size: 11pt; } .directory > h3 { margin-top: 0; } .directory p { margin: 0px; white-space: nowrap; } .directory div { display: none; margin: 0px; } .directory img { vertical-align: -30%; } #website { width: 820px; height: 100%; margin-left: auto; margin-right: auto; text-align: left; /* IE hack */ * position: absolute; * left: 50%; * margin-left: -410px; } /* ** HEADER ** */ .header { height: 200px; background: url(header.jpg) no-repeat top center; } body { background: #fff url(body_top_bg2.jpg) top left repeat-x; font-family: Arial, Trebuchet MS, Tahoma, Verdana, Helvetica, sans-serif; font-size: 11px; line-height: 17px; color: #444; color: #3a3a3a; fdpadding-top: 15px; text-align: center; background-color: #fbfbfb; } h1 { font: 24px bold Trebuchet MS, Arial; color: #FFF; padding: 0; margin: 0; } /* ** MIDDLE SIDE ** */ #middle_side { display: block; height: 100%; width: 800px; margin-top: 7px; backsground: url(middle_bg.jpg) top left repeat-x; background-color: #fbfbfb; } /* left and right side */ #left_side { background-color: #fff; clear: both; margin-bottom: 10px; border-bottom: 1px solid #eee; border-left: 1px solid #eee; border-right: 1px solid #eee; -moz-border-radius: 0 0 8px 8px; height: 29px; } /* ** MENU HORIZONTAL ** */ /************ Global Navigation *************/ DIV.tabs { float : left; width : 100%; background : url("tab_b.gif") repeat-x bottom; margin-top : 10px; margin-bottom : 4px; } DIV.tabs ul { margin : 0px; padding-left : 10px; list-style : none; } DIV.tabs li { display : inline; margin : 0px; padding : 0px; } DIV.tabs A { float : left; background : url("tab_r.gif") no-repeat right top; border-bottom : 1px solid #84B0C7; font-size : x-small; font-weight : bold; text-decoration : none; } DIV.tabs A:link, .tabs A:visited, DIV.tabs A:active, .tabs A:hover { color: #1A419D; } DIV.tabs SPAN { float : left; display : block; background : url("tab_l.gif") no-repeat left top; padding : 5px 10px; white-space : nowrap; } DIV.tabs TD { font-size : x-small; font-weight : bold; text-decoration : none; } /* Commented Backslash Hack hides rule from IE5-Mac \*/ DIV.tabs SPAN {float : none;} /* End IE5-Mac hack */ DIV.tabs A:hover SPAN { background-position: 0% -150px; } DIV.tabs LI.current A { background-position: 100% -150px; border-width : 0px; } DIV.tabs LI.current SPAN { background-position: 0% -150px; padding-bottom : 6px; } DIV.nav { background : none; border : none; border-bottom : 1px solid #84B0C7; } #right_side_home { font-family: "Lucida Grande", Arial, Verdana, sans-serif; background-color: white; padding: 0px 20px; border: 1px solid #ebebeb; border: 1px solid #ddd; -moz-border-radius: 10px 10px; width: 750px; * width: 800px; * margin-left: 0px; padding-bottom: 10px; } #right_side_home td { line-height: 17px; margin: 0 0 5px 0; padding: 10px 0 15px 7px display: table-cell; border-spacing: 2px 2px; vertical-align: middle; text-align: left; border-bottom: 1px solid #EEEEEE; } #right_side_home td h2, a.anchor { font-size: 19px; font-weight: bold; color: #3E93D5; } #right_side_home td.indexkey { border-bottom: none; } #right_side_home li { list-style-position: inside; valign: middle; } TD.indexkey { background-color: #e8eef2; font-size : 12px; font-weight : bold; padding-right : 10px; padding-top : 2px; padding-left : 10px; padding-bottom : 2px; margin-left : 0px; margin-right : 0px; margin-top : 2px; margin-bottom : 2px; border : 1px solid #CCCCCC; } TD.indexvalue { background-color: #e8eef2; font-style : italic; font-size : 12px; padding-right : 10px; padding-top : 2px; padding-left : 10px; padding-bottom : 2px; margin-left : 0px; margin-right : 0px; margin-top : 2px; margin-bottom : 2px; border : 1px solid #CCCCCC; } TR.memlist { background-color: #f0f0f0; } .mdescLeft { padding: 0px 8px 4px 8px; font-size: 80%; font-style: italic; background-color: #FAFAFA; border-top: 1px none #E0E0E0; border-right: 1px none #E0E0E0; border-bottom: 1px none #E0E0E0; border-left: 1px none #E0E0E0; margin: 0px; } .mdescRight { padding: 0px 8px 4px 8px; font-size: 80%; font-style: italic; background-color: #FAFAFA; border-top: 1px none #E0E0E0; border-right: 1px none #E0E0E0; border-bottom: 1px none #E0E0E0; border-left: 1px none #E0E0E0; margin: 0px; } .memItemLeft { padding: 1px 0px 0px 8px; margin: 4px; border-top-width: 1px; border-right-width: 1px; border-bottom-width: 1px; border-left-width: 1px; border-top-color: #E0E0E0; border-right-color: #E0E0E0; border-bottom-color: #E0E0E0; border-left-color: #E0E0E0; border-top-style: solid; border-right-style: none; border-bottom-style: none; border-left-style: none; background-color: #FAFAFA; font-size: 80%; } .memItemRight { padding: 1px 8px 0px 8px; margin: 4px; border-top-width: 1px; border-right-width: 1px; border-bottom-width: 1px; border-left-width: 1px; border-top-color: #E0E0E0; border-right-color: #E0E0E0; border-bottom-color: #E0E0E0; border-left-color: #E0E0E0; border-top-style: solid; border-right-style: none; border-bottom-style: none; border-left-style: none; background-color: #FAFAFA; font-size: 80%; } .memTemplItemLeft { padding: 1px 0px 0px 8px; margin: 4px; border-top-width: 1px; border-right-width: 1px; border-bottom-width: 1px; border-left-width: 1px; border-top-color: #E0E0E0; border-right-color: #E0E0E0; border-bottom-color: #E0E0E0; border-left-color: #E0E0E0; border-top-style: none; border-right-style: none; border-bottom-style: none; border-left-style: none; background-color: #FAFAFA; font-size: 80%; } .memTemplItemRight { padding: 1px 8px 0px 8px; margin: 4px; border-top-width: 1px; border-right-width: 1px; border-bottom-width: 1px; border-left-width: 1px; border-top-color: #E0E0E0; border-right-color: #E0E0E0; border-bottom-color: #E0E0E0; border-left-color: #E0E0E0; border-top-style: none; border-right-style: none; border-bottom-style: none; border-left-style: none; background-color: #FAFAFA; font-size: 80%; } .memTemplParams { padding: 1px 0px 0px 8px; margin: 4px; border-top-width: 1px; border-right-width: 1px; border-bottom-width: 1px; border-left-width: 1px; border-top-color: #E0E0E0; border-right-color: #E0E0E0; border-bottom-color: #E0E0E0; border-left-color: #E0E0E0; border-top-style: solid; border-right-style: none; border-bottom-style: none; border-left-style: none; color: #606060; background-color: #FAFAFA; font-size: 80%; } code { display: block; width: 100%; border: 1px solid #ccc; background-color: #e8edf3; padding-top: 10px; padding-bottom: 10px; padding-left: 5px; padding-right: 5px; margin-bottom: 10px; margin-top: 10px; } openchange-2.0/apidocs/html/libocpf/bc_s.png000066400000000000000000000012501223057412600211020ustar00rootroot00000000000000‰PNG  IHDR /ð9ÐoIDATxíMLAÇßìN»»¥ívKùPJik±R5^ŒChÂŃ!Dzƒ *U4VƒbÄD1~`8xà@ˆ^¿?ð𤡸Ý@јÝná`JLLÝØ¦ƒÜXi v«9ê)·}aV±&Ò0)›¼ð(‰zÛküNcFPÛù'@é¨KZK%!13§5£}Ý€ÒdÀã°’>´Åç´çhï¹G…ÉZ ïz×Ú—Éi£“ì–º=…@O¹«È‚1Ó¯¦3ãF«[ºä’d²¾JÒã`|^3˜Ý\›¿¡]²ó•'fçÓùyˆÄîçâÙ@¥Cos˧d:?$lhûnÝ× nm\†$cÔL6Ñý »Ì´x@N¦oPÀ®Î‘òÕ”€GÔ÷>9¹¨Q@ã±á“.‡qŠÜ´¼°Ø ”PCt(á«yŒQ$±°hÔNý8¤¥Ë MNjÿ$þßþŲo_ƒsLIEND®B`‚openchange-2.0/apidocs/html/libocpf/bdwn.png000066400000000000000000000002231223057412600211250ustar00rootroot00000000000000‰PNG  IHDR5åZIDATxíË € DŸP–1ñlžmÀ r±j².e è†D[ØÉ¾ÙÏÔ¼µ¦ã´Þ|陣6€Všë3´Å?Ls'(}¬>+ žKó÷¥¿ch`‚ ^׃ÞnIEND®B`‚openchange-2.0/apidocs/html/libocpf/body_top_bg2.jpg000066400000000000000000000006541223057412600225500ustar00rootroot00000000000000ÿØÿàJFIFddÿìDuckydÿîAdobedÀÿÛ„ÿÀ–ÿÄh að¡q‘QáR’¢ð!‘1aQÿÚ ?Ô¢±Õœ|W¼ í|ua³Dbe­‚hŒ*ø VÁ&ÅrV¹´,¸^Â-~TbÁÐéÊ—=©xj䮤*ÿRb²r %7L‘ñÜŠ¶5ø¦ èªÞV¶ ÿÙopenchange-2.0/apidocs/html/libocpf/closed.png000066400000000000000000000002041223057412600214430ustar00rootroot00000000000000‰PNG  IHDR à‘KIDATxíÝm @!†ÑGk™É7À-`&séts¦Àñþòð@åk}ª2€… P%Á_Ëþ¿N² .:0Dk¥‹Â›x" Ö›)¡xÒ5õIEND®B`‚openchange-2.0/apidocs/html/libocpf/dir_54b976a5bf00dfec3627acb49f7b4f96.html000066400000000000000000000112401223057412600257470ustar00rootroot00000000000000 OpenChange Property Files 2.0 API Documentation
libocpf Directory Reference

Files

file  lex.h
file  ocpf-documentation.doxy
file  ocpf.h
file  ocpf.tab.c
file  ocpf.tab.h
file  ocpf_context.c
 OCPF context API.
file  ocpf_dump.c
 ocpf Dump API
file  ocpf_dump.h
file  ocpf_public.c
 public OCPF API
file  ocpf_server.c
 ocpf public API for server side.
file  ocpf_write.c
 public OCPF write API

Creative Commons License
Creative Commons Attribution icon Creative Commons Share Alike icon
This content is licensed under the Creative Commons
Attribution ShareAlike License v. 3.0:
http://creativecommons.org/licenses/by-sa/3.0/

openchange-2.0/apidocs/html/libocpf/doxygen.png000066400000000000000000000073031223057412600216560ustar00rootroot00000000000000‰PNG  IHDRh ;ˆØŠIDATxí]y\•Õº~45%TL Q”PE"q–Û11±]8a„w*©¨(*â" ˆzÀè`8 ¨‰¢mÅ,’òà„p$%”œBó(8k†Ü÷ýÜû6lòö»§k÷Ç÷[ÏÞß·Ö;?k½ëßÕÕÕPxÑêÏ't´ÏùÈ€zÀÇÅ3_€Q4€g@œmÿ ¾ò‰âci‰ôçÿ{ ðÇð¬ù~½Á€4:õHcÂü ðŸÁ³„ª'ÕPÆæ P7^h،♠zb„cóP¨„ 3‚† Ò}çÿO²qÁºNkÝTÛ(É?d Ç~z<’«4Óǡ؞Þv­zµÙ¦õ¬ZâdÛ,Ë6Ók±]Fz< ¾ZçƒsÕ?ìƒsUø2SÉåwê1”c`[ì—}%ѽ.Ô¼6‚BLZ˜û!F8[ ¹…×TéÛ— »Þ#gó]å:vžu?‡vèbÙR˜?wùŽŸ¾ÊÐgbÑÉÌÕ$kF~Ê;عÆ•¢ïX®?ÉèlÆÙôõà»Nʪ¼­,ìHC§gAz•ÆlÓº­gÑú ]œjÎñåM…3ÓÚæoÒ³'=‘$Ò÷f}G•ŸS_‡öèco.Êȹ :ó£ Ãds®Ù:1=¼{ƒå9?÷ý…zqÛvîÓi‰D’p¿Ë šmÙíoÛâýaÖüEqÒµwÌ}¿~{òj€ç{ôºŸFNëí[ëOq·ÇOSúXO]°>‚‚muæÄ¾e¤“5Ë{¨JÕ¯£(›´«bÂçû’ÍlÓÅ}žïú`éUÞy„ac§Á†ÔCºŠóAkl‘±y¥†ô¢ùôs÷Aø¬7ÄõôoJ±äÄ ù.¥Be. Z¬Ð×ÇÈöå¹­ù'Ù-PëìŠyF.ž‚žÝÚ€lp&.êˆð•jò7’re’z19»ã§HGíø%œüq°ïüz׈c¬_k_")ŸHJnÐÑ~ˆÐÖ˜á´äÕ5 µÁq€ÿ5#¸·îà¶+9T‘‚ ðŽ÷Rܸrz“Ï´Ì =Ï…{ðáO£Èf ¡Íwg|Ž’Ü/¢Þ$÷¯¢ëðúÀ;¿à¨Ö™âÒÆ­]¯ÜW"Þ/< ‡÷DÏà°½üB}çyIEc^—ƒ=[V“Ýh²ëMä$l];Kû®¸ýr¦È*Åò ÿtÒõ$]•MŸ÷´;×I€1èó!‚œõ¸M õ¨(fÌæ<ÁÎÎò5~z¿ù¶ž mÌêÕ >–âÚ©âëˆIÎÞçz;ãu[i·eç^ÆÜÙÓ³NÞëF6B\}7†»+üŽÓ,Ã'a ½˜-yHY¿,‘^—ñfú~ß?Hcø¸…¸ñó{Z+4\såƒû·¯Ù·nߣð«íFÆ¡sغëû§D¾?ò<–Ævkx0ÅM±ælذÁIÓxÿd”žÜÉ÷EE»AªM«g*È£YEí7Û™^[uíý®v[wGå†=Ed¼n×¶ÆæÖÅl¡'¨pGÚk+‹æ¢À¬¨C8ªâš2 dz3H£ß ¡¨BÒûSÃÅù[wŘ ~xpçútÁæmö¤Å£¥iQæ­‰AB1ÉfÙ‰›4u¹ïìIÒ]Ë6äò%ÿ†† 1t.’NJph¬zÌ ÎR1Ž"3-"¸‡‹&ìó°1âüžìó[:‡ï„¼‘……N m–“W0®_èÜœ ×õ6ùò&»)Æìꦬýæ}¬ñ~»{múù]z½£M•ºP~^Îá:eQTÙ_*7ÕÄ9É8—·Ëï 3°¶47E•î¿u÷“SÉ»U¯ _ NíºôW¬e¸ÄNÓ|»;™¿;ŒæÅd"ȉôøòÞµõï¾®½"èÄ´ÖMM+bYµ‘_ÉæEÝüÎ]P»¹XKÐI½Þ¥oE<_¹(„EP±Œ|mÇÁ¡‘Ý,ŠÓ©ººZ±Îߺ§×kÝ,kÍMš`Äø…jzeU»æ ™Át3ÓÀ½˜6—ÒöùË·r¨¹Ñ}““wö:Χùë¼ ¿|‚TܵÉQˆKßç_ÁâÀ™œ”pÑÐóໃ¼Ydâ0!®àa –øöçW$ÃÁ‘Á$/\¬$ð 2ÞímÞLH‹Ÿ èd£HVÜ,:ò½»RÍZšJ­a„z*>‹_…NT(ù‚^SVF­U¹8ñEþôñ܈óùnd;«®8™\C]ø=Èêm¬Æ:‚´ÆbãDd=Áãßžˆ‹UU5O‹|]þð®Pèêv‰á\]2ßìÿ"yÈ[ïyʧz£g{Y«{„Ùø5©ÿ;w{N3é­nâĨw§Á¢ÍK¢Ý­ûÏ29Id¿’ì y)ìPÞò8ŒÅ©¯‰±@mPÔñwjl,6 áhWÕ˜d öà uõmÁp®.™á£Ç…twöR x­BδYcŒxg*vo  yò‘•“[¬?ÜVœ˜0ÒN¡O난~Žó’¯·h#´Hkýœ±8kÓß^Àq@]àÓ“ø,56´¯÷Í-κU»n…[>]@nîøÏœp›[œ6# €4tën¯:ŽÒþ}…—8äT9_žY$/´G’K™©ù†•(óÑ’Mø©`ŸÉdѺ;ùO‹B Ó&P{qöhJÉ+Úé–§¦l2«MïöÝ_1ÑÓ«’t¸½±l€ëØya ¦ô©«®½ÆL^¬žêñš¸ùy.¾Û½Š[ u/]½‹iS}øN>²e1™q‡jfÚ&¢©iT\=kÏ›ÀXô-.84V5ðu!TE˜ þ.ŒOH´¶4—zwTr.ï‰¦Ë xõµ·œÖ„HÆù£žÈHùg Ñhñ’T$ßyq¸zþ¨p¿´ë< q•ró÷š‰wÿÍÑð–I]´–æI²é²˜sÂ"×:Õ–bÕ¦“ÈÙL6¢9VÊÓWž§<æ;”3?ý©Mê3AV#µ±ËÞ¯‘ž K£UrÝ9!›qát¦H£Ù+6ÇV…/TS^pÃùqgLP'Ú5E ‚–ÀÞºîÄ Ën"2|Ÿ;®W»Îý"Ö¬TwÖâµtúŽO'› á+W Ã+¦âZÌ–<ÕÆ&nOÝ,IŠ£06.ÁZ.Çñúøh*INÚ’Oe½ÉgBXÐÔZóäøä9èü“hÒíDSš¥¡Ê µA¯/Ôc¸ö“`A§¯"zå|‘ €ÅŸ¨ú;HÍ#‚Î|%ÄOˆƒ«OàÌÉÐÜD ž mÜðâc–ƤÉÂqm¶uË&~÷núÒË £ÇÏ€ZÕj =«_n[‡‡÷nN§ÏÝ$_¾bE˜‚€Õ)ù8¾?6‘lú“ÍÙæÖ}#bW( œ³d-®•p&¡ý’œÖa”"9öõņÐ$’Ú›AÜ!ä;ÐÑõè{~á¹8‘ÛÞ£1ÛÓÉ0ž`²#´kÒuäNÅÖ Q¹bhæ ”8ûÓMáŽa›•¿”w±h²¢®qŠæ°(bK ‚’Z¾Ò%ÐÆémáãÖË(Éý‚ÛJ)@> þ›7% ï{y Á“¾ÆÒîohfòô>{pÿ.­_Î%±ÉèägëlZØ\B2B #™¸ÚüÒºp‚hÝšü®[¥Ü<‹#SpñÌA7’ãØHƒt4:Ÿ|g¨tÓL¶*($Æ©»ì…®ù’ó÷$;b›ÔÙ`=¶£¦M„MÌÄ5ò«·Ç¾“H·ÌH.¼žHeAîº5}r­dõ¨±)ÀT};€Q5iÖ2…O0ü…0óñÃ;óæ,Š´²µ냔}g‘£]‹7å9ˆà©_{üèîêžC>úhê{Ž .ÈìðIIð€?[Kswz6Òuíý¬;µ€ç§OåâJÉa˶zv°éd† ¤µâ‚l´é舊«Åüy¾c÷ÁèÖÍ'ràúÅ™TWÕôÓ°¡L €|ʽŒ¼ì­høBã ÝTëî'ò]Kø£ìâÏ(=¹Kx €¿ LÌ,Pý¤Êµu‡¹…׈ §Å¾÷à1Ý«Äý;¿pGDäxZYÛ kfæ6¸ùóæ7®œ®þ6·ÕoÚ¾ÔH~ò®Þ¸â 8Uø“p<ºw3¡a£ÏÑ’‘3èÏ"€bˆ-ÎܺÏ_ªÅ]+ËM©zü°s“f-êçhÇãÑýÊãôÿ5}ZQNb{Ó?å%ÿ\SUõعIÓæ}~}p[œoÔÄ„êÐMMZáNÅå@>Œ„²á6(?¡Åé âK½+ü?À%ÝÝ·/Ç1‚9áUø?B)”ÕèâÞlÈÒêÏ @=àùÄÞžk­®ÅIEND®B`‚openchange-2.0/apidocs/html/libocpf/dynsections.js000066400000000000000000000041341223057412600223720ustar00rootroot00000000000000function toggleVisibility(linkObj) { var base = $(linkObj).attr('id'); var summary = $('#'+base+'-summary'); var content = $('#'+base+'-content'); var trigger = $('#'+base+'-trigger'); var src=$(trigger).attr('src'); if (content.is(':visible')===true) { content.hide(); summary.show(); $(linkObj).addClass('closed').removeClass('opened'); $(trigger).attr('src',src.substring(0,src.length-8)+'closed.png'); } else { content.show(); summary.hide(); $(linkObj).removeClass('closed').addClass('opened'); $(trigger).attr('src',src.substring(0,src.length-10)+'open.png'); } return false; } function updateStripes() { $('table.directory tr'). removeClass('even').filter(':visible:even').addClass('even'); } function toggleLevel(level) { $('table.directory tr').each(function(){ var l = this.id.split('_').length-1; var i = $('#img'+this.id.substring(3)); var a = $('#arr'+this.id.substring(3)); if (l OpenChange Property Files 2.0 API Documentation
Examples
Here is a list of all examples:

Creative Commons License
Creative Commons Attribution icon Creative Commons Share Alike icon
This content is licensed under the Creative Commons
Attribution ShareAlike License v. 3.0:
http://creativecommons.org/licenses/by-sa/3.0/

openchange-2.0/apidocs/html/libocpf/files.html000066400000000000000000000104601223057412600214610ustar00rootroot00000000000000 OpenChange Property Files 2.0 API Documentation
File List
Here is a list of all documented files with brief descriptions:
[detail level 12]
\-libocpf
 o*ocpf_context.cOCPF context API
 o*ocpf_dump.cOcpf Dump API
 o*ocpf_public.cPublic OCPF API
 o*ocpf_server.cOcpf public API for server side
 \*ocpf_write.cPublic OCPF write API

Creative Commons License
Creative Commons Attribution icon Creative Commons Share Alike icon
This content is licensed under the Creative Commons
Attribution ShareAlike License v. 3.0:
http://creativecommons.org/licenses/by-sa/3.0/

openchange-2.0/apidocs/html/libocpf/ftv2blank.png000066400000000000000000000001261223057412600220660ustar00rootroot00000000000000‰PNG  IHDRɪ|IDATxíݱðøScOx@ –¨y}IEND®B`‚openchange-2.0/apidocs/html/libocpf/ftv2cl.png000066400000000000000000000007051223057412600214000ustar00rootroot00000000000000‰PNG  IHDRÚ}\ˆŒIDATxíÝ;H#AÇño4Љႇ œ„K‰‡‚á ’ê,m„ØØ vÚžJ°²¹ÚÎþî‚§ XY ÅB|dr³cvo—˜Ä°Ý ù0Ã’™3ÿͤõ”Ëe×´¸Éõ¯1XÞ8Œ‰nQˆ88ööÖ§3*rbñ¯¢û-$¨‚þ´˜“P1Žè@Z…-# Ïú01ÑÏÎêÄ1HkKŸ w¶O@¥ªÈóñ!f§ñu˜åác÷;’sá×Bý[E´Añ±—Í\ß>°ùý¿ÏËÊÂ]–P€zØf| Íñ¯“+Ù´gð5…b  i5ümM³œ_æÍq,ÒcŽõèoÓd´ !¶äò©ô•,ôðÀ{¹¨µYß,€zTÍ8H]𤕘ï7¼»/òó8ËQæ !F€~6ãá?Y ÀA@ŨÁ.@ƒ¶TäÄYïŠËë±r‘µ8Ð*·é>€Šçÿ?€×þŸe[6«xÂIEND®B`‚openchange-2.0/apidocs/html/libocpf/ftv2doc.png000066400000000000000000000013521223057412600215460ustar00rootroot00000000000000‰PNG  IHDRÚ}\ˆ±IDATxíMOS[…Ÿžsúa?-XZ(PD4‚ AWbu`b 77wäHFÆCËÔÂÿà/`vo„ˆAPòq‹P @ ­ûÝè980 îà¤+»§Ýy×^ïZï9SW¹\83g‰3'°Nâçl¹¸_b¯p ïåûÆVÜÖ¡€Ÿ×"¬Ö†X€d]Ðà3“ÉÃÄÌ™xŸ ßMàœ[<çSPkvc—hÈ'…™˜^Åm™hØ7 `Û™¦ èÀåráq›‘œ¾!daeKŸþÆÕ˜:Ì*³_דâèi?I–eP*B7Ÿ¿åô!¹Ýgr6Ër6oKbëþãðôrI”ËTˆüªŒ¨xóö=›ù¢&‰(e+ßóÄkýÇ`ëÁÜb.“¸ÐW×w0¥°jÑzN™¬|©WEãµ¢a¯6[öX†AkÓù*/œ¨‰€ÉY­ ÿV’§–u²jÂ>1W *½·°PGŽzÿ¨/Eg{ ŸÇâaoŠÁVú:è¿™¤1$ôR§W,–ªà¨@ŠË56¾ÀÔÜ-¾,mê¸Î/æè¹– òr5¥T*S(Vf8ö9u’ Õ£w›ùóa=Í<{Ò¡UŒ÷r¯+ÉådDÏF$è°…£é¿`zþ»ÎúöN‘µÜ®0Q3£~_^Ëóâ¯N=ˆvpTà±LžT}ˆîkq†Òm<¼ÎÓ?Zh¿X£ï_þÝ¥[)ƒ `gêÃa_Ô*äÔ2`'=õ´Fÿ2EâÁPú ÷»›l=8‹Wv°%THqÉ¿<"¤ïG¾ÆxH{#ÆÖ«aÔJÕÞ‡—m‹„ çñKsÿàñVŠØ¡°·MâÒ^ TÁ– Ý›r¥ß½ømüÿ_™?ªWİ÷#uIEND®B`‚openchange-2.0/apidocs/html/libocpf/ftv2folderclosed.png000066400000000000000000000011501223057412600234420ustar00rootroot00000000000000‰PNG  IHDRÚ}\ˆ/IDATxí]MOÔ@~ÚúuØlp]ö¿#›Å]PYECˆ\9ù¼yÑß`ÖÄÿàÿÀÉxóâ¢C &=qÐÄ£—vZçv¶3m؃‡vžLûNç}Þ÷}Þ½ZA@n° OäNp ’xóþK°ññ€xÜj”°8sÑ€“ “€œ_¼[Âíæ§ïD'‚•yye+ø¼û 7#rNŸlïük* ¾0Ь_d«_(àñÖ±àôz=ñxõv§÷h©‰z¹€šØP-äóä’̪uý¼$»\DãJc—B4¯ãÝÖ.:£Ï-ÑÏß}µŠLEíºþ #—ûáºÀÏgN;BŠ€6ïýñ䬜…ö@’Ðåñp&™h>p9¤™EEά¨ÎÊ‘" u¥n€$R"?{¹<˜…ë…%PNtâ$‰ß¶±úá+^<é"§2 ªDq”q´\¬«Ò™a–Œ‘©Aÿ€"Ôµ ™êŸèP£}#Eàz{û.8i îp³ê(ADwD¦E<ê¬cE¦$ HdÊÄ ”.:Ù GŽ-`ŒL‚ý¾'¢‰Ä<¤CIª½;ÙÇTZd±i};>èôß‚z×;K×§8t ¤Ž q”:uvÿv•Ý›¬²ÙvEân{„M·FXg¼ÌfZÖ¨°¹‰*›ßÌß©±ù©:›j–YqèÜë#3çÏSøWøÿÿÑr'ø Ôùù‚ ©¡IEND®B`‚openchange-2.0/apidocs/html/libocpf/ftv2folderopen.png000066400000000000000000000011251223057412600231340ustar00rootroot00000000000000‰PNG  IHDRÚ}\ˆIDATxí]?oÓPÿ9iš4i°;ii“¶‰ZЉ‘‰ÀÀ7`bèÔÙ¬Øù,HìU'ô$*Tµ]‚T¡DPÚÄ6wÏ}‰;¡C; a¿ÓߟûÝïîž¼jAÀ­InSþ}€9H“ÓŽ|?íÁ÷ =_ÊÆŠ­†¥Àue*;¯YEäsYäæB¢Ÿ¿þÄ—£sÙ½½ÙŒ† É«›©ÀYÇq !GÇ¿v̇¹ÑØ®š °Œ‚ÔF¹}q¥b]÷7í·0)Úd›¾ÿð-èº}Pfä£ÖY{4™ÑÂ@}úæôñ2ÛüÔ—ñúåNŒI‚ÁǃcçÁº%£¬UаI³mc±ô˜å¼ÔÆüÈ>é¸xþt9Æ$µý OæVE*õU´Ì‚ç#ž×ˆ•ïûr@l$øPÿrHaaÇ¥ ²›dZ®rè‘ãqI„o¼øT\Ž,tªj2FAxv-LŸp׌p TÄI/ \¥sfí½; jViTƒèú¤o^cpÅü¼ûû»Ïb]”€¢¤<†aþÕœ²“ßÓ˜y“£§9:Œîù+À³€ñà,E žf³6éNˆÄE£KU}Ü^;¶ØnZ¢uß­US4— ѬëbížN¶.Úk¦ØjTÄöº%µªâ i¯VÄÊÝò§™ Èù¸)ùÿG€™òºJ@T x”IEND®B`‚openchange-2.0/apidocs/html/libocpf/ftv2lastnode.png000066400000000000000000000001261223057412600226100ustar00rootroot00000000000000‰PNG  IHDRɪ|IDATxíݱðøScOx@ –¨y}IEND®B`‚openchange-2.0/apidocs/html/libocpf/ftv2link.png000066400000000000000000000013521223057412600217360ustar00rootroot00000000000000‰PNG  IHDRÚ}\ˆ±IDATxíMOS[…Ÿžsúa?-XZ(PD4‚ AWbu`b 77wäHFÆCËÔÂÿà/`vo„ˆAPòq‹P @ ­ûÝè980 îà¤+»§Ýy×^ïZï9SW¹\83g‰3'°Nâçl¹¸_b¯p ïåûÆVÜÖ¡€Ÿ×"¬Ö†X€d]Ðà3“ÉÃÄÌ™xŸ ßMàœ[<çSPkvc—hÈ'…™˜^Åm™hØ7 `Û™¦ èÀåráq›‘œ¾!daeKŸþÆÕ˜:Ì*³_דâèi?I–eP*B7Ÿ¿åô!¹Ýgr6Ër6oKbëþãðôrI”ËTˆüªŒ¨xóö=›ù¢&‰(e+ßóÄkýÇ`ëÁÜb.“¸ÐW×w0¥°jÑzN™¬|©WEãµ¢a¯6[öX†AkÓù*/œ¨‰€ÉY­ ÿV’§–u²jÂ>1W *½·°PGŽzÿ¨/Eg{ ŸÇâaoŠÁVú:è¿™¤1$ôR§W,–ªà¨@ŠË56¾ÀÔÜ-¾,mê¸Î/æè¹– òr5¥T*S(Vf8ö9u’ Õ£w›ùóa=Í<{Ò¡UŒ÷r¯+ÉådDÏF$è°…£é¿`zþ»ÎúöN‘µÜ®0Q3£~_^Ëóâ¯N=ˆvpTà±LžT}ˆîkq†Òm<¼ÎÓ?Zh¿X£ï_þÝ¥[)ƒ `gêÃa_Ô*äÔ2`'=õ´Fÿ2EâÁPú ÷»›l=8‹Wv°%THqÉ¿<"¤ïG¾ÆxH{#ÆÖ«aÔJÕÞ‡—m‹„ çñKsÿàñVŠØ¡°·MâÒ^ TÁ– Ý›r¥ß½ømüÿ_™?ªWİ÷#uIEND®B`‚openchange-2.0/apidocs/html/libocpf/ftv2mlastnode.png000066400000000000000000000003661223057412600227730ustar00rootroot00000000000000‰PNG  IHDRɪ|½IDATxíÝ!NAÅñ¤‡à\ ÷à Um@`Ô5iÒ`ëh ‚ÅW7] b§ÝˆŠ&oföÍd¾YÔ4 üšcø ‡€´‹Åòù3v=¼]†§µ\B… I¿‹=B·™B¡®;¸k´µ W°ÍN@vyÍÑÖ4ãß÷]ÈâYìã§|M}]ÔÚx6a }ôdׇØYüú¨>¤||5?Ó>|žB"¡î'¡IEND®B`‚openchange-2.0/apidocs/html/libocpf/ftv2mnode.png000066400000000000000000000003661223057412600221070ustar00rootroot00000000000000‰PNG  IHDRɪ|½IDATxíÝ!NAÅñ¤‡à\ ÷à Um@`Ô5iÒ`ëh ‚ÅW7] b§ÝˆŠ&oföÍd¾YÔ4 üšcø ‡€´‹Åòù3v=¼]†§µ\B… I¿‹=B·™B¡®;¸k´µ W°ÍN@vyÍÑÖ4ãß÷]ÈâYìã§|M}]ÔÚx6a }ôdׇØYüú¨>¤||5?Ó>|žB"¡î'¡IEND®B`‚openchange-2.0/apidocs/html/libocpf/ftv2mo.png000066400000000000000000000006231223057412600214140ustar00rootroot00000000000000‰PNG  IHDRÚ}\ˆZIDATxí1Kû@ÆiƒØB…Ò¡(h¬"EÄI'ÁoàªèÚ©ßÀáâä 8ùçR-‚â B«TPˆï]z¥B’3 _Þã’»ç}ŸË]VÇ÷}€ÌÈdIæ®i쟯JØ–b¸šÍÃõ+º™|KÂ…°,[Pï\ʘMÆ¢#€ä…F`JݤìÛk³úA±àþè?ØY4ck6"¹Z)ê¸0SHM¨@ï㋺WÖmo¼4èHJ¨Àÿö+…QobŒút ¤ú’*Ð~êè8_+3Y-ñðÜå½÷ ˜PwA¶+^ý}ºì£+xìhÏ•MAE]€TD~EÞߴ^R)`ÖAùŸÏ9©pÔq-Û¾õÛ3tÝÊÆ›ˆÃTÐHÈ)€ ½Š’ICªxëd#1ôú§é€ m@Vüý?Zæßgo_½3-³\IEND®B`‚openchange-2.0/apidocs/html/libocpf/ftv2node.png000066400000000000000000000001261223057412600217240ustar00rootroot00000000000000‰PNG  IHDRɪ|IDATxíݱðøScOx@ –¨y}IEND®B`‚openchange-2.0/apidocs/html/libocpf/ftv2ns.png000066400000000000000000000006041223057412600214200ustar00rootroot00000000000000‰PNG  IHDRÚ}\ˆKIDATxíÝ1K1Àñ­ž ØG•â‚n‚Šà ‚âælÁE¿€‹“ (nºêââêäࢋƒÐMAá@°‹ µât¾ÄK¡à%Ü•Û ý]BIïå%áuÍ…a™€,e × v¯ç¥«ˆi‹º¨Õö–î\tòòuénÄ0ã æÜÉoV\Ì$G.&@Y=ÆË%$um·¢ûÛ6–'Úß«9Qó\bÙ)²º0Ðë-Zœ¥TèHÍ`pÀcsm µö5:>Áë‡Þ¦I µØ ‚F‹Çà]» ›jg—ìoÏáõ©[ œõ š­onë €Ô¬¨vqõ„?\Ðç”  6»øüÒTe ÃÉéŸeç ÀÅlQ ¡c”€ª¬ü3*d€ÅWTMÏ\rÿÿh6™ø1±F ‹°fžIEND®B`‚openchange-2.0/apidocs/html/libocpf/ftv2plastnode.png000066400000000000000000000003451223057412600227730ustar00rootroot00000000000000‰PNG  IHDRɪ|¬IDATxí=QF‘Ø¥D«ÔkÄ:‰F©PK؃=V@§Õ³ Õ8SHxñÌ0bnrróŠ{ò½¿¾’$ ÀÏTŠP  ö¼X¬OÛd6êìòð"°²S´±O¥B€(¡àQé)š+YĈ ÒªËRÉÐ>VtÉsˆm9(ê„䜥k‚-@ȧ-Ü$ó b Ò[he ¿Kp-ôl|CùÿApRG'rÍ­aIEND®B`‚openchange-2.0/apidocs/html/libocpf/ftv2pnode.png000066400000000000000000000003451223057412600221070ustar00rootroot00000000000000‰PNG  IHDRɪ|¬IDATxí=QF‘Ø¥D«ÔkÄ:‰F©PK؃=V@§Õ³ Õ8SHxñÌ0bnrróŠ{ò½¿¾’$ ÀÏTŠP  ö¼X¬OÛd6êìòð"°²S´±O¥B€(¡àQé)š+YĈ ÒªËRÉÐ>VtÉsˆm9(ê„䜥k‚-@ȧ-Ü$ó b Ò[he ¿Kp-ôl|CùÿApRG'rÍ­aIEND®B`‚openchange-2.0/apidocs/html/libocpf/ftv2splitbar.png000066400000000000000000000004721223057412600226230ustar00rootroot00000000000000‰PNG  IHDRM¸¿IDATxíÝ¡JCa‡ñç(˜ ëƒ%±Ø4 b±È˜Í¶3˜v^Á±˜…ãó–ŽELƒõ…¥•³ ,ÿb;íç{Ã/¼ðÞÀaYÕ¯åóøq:¼º¹›\òIIIIIIIIIIIIIIIIII-Òçl¹›«õ抢è_t/Ï»ã£ÑíYQVõðêäíã÷´×ùY¬Úÿµ§¦ivók¾_íåýÛ£I@$I@$I@$I@$I@$I@$I@$I@$I@$I@$I@$I@$I@$I@$I@$I@$I@$I@$ýC[Vì=ü[„fÆIEND®B`‚openchange-2.0/apidocs/html/libocpf/ftv2vertline.png000066400000000000000000000001261223057412600226270ustar00rootroot00000000000000‰PNG  IHDRɪ|IDATxíݱðøScOx@ –¨y}IEND®B`‚openchange-2.0/apidocs/html/libocpf/globals.html000066400000000000000000000130551223057412600220050ustar00rootroot00000000000000 OpenChange Property Files 2.0 API Documentation
Here is a list of all documented functions, variables, defines, enums, and typedefs with links to the documentation:

Creative Commons License
Creative Commons Attribution icon Creative Commons Share Alike icon
This content is licensed under the Creative Commons
Attribution ShareAlike License v. 3.0:
http://creativecommons.org/licenses/by-sa/3.0/

openchange-2.0/apidocs/html/libocpf/globals_func.html000066400000000000000000000126421223057412600230210ustar00rootroot00000000000000 OpenChange Property Files 2.0 API Documentation
 

Creative Commons License
Creative Commons Attribution icon Creative Commons Share Alike icon
This content is licensed under the Creative Commons
Attribution ShareAlike License v. 3.0:
http://creativecommons.org/licenses/by-sa/3.0/

openchange-2.0/apidocs/html/libocpf/header.jpg000066400000000000000000002264161223057412600214350ustar00rootroot00000000000000ÿØÿàJFIFddÿìDuckydÿîAdobedÀÿÛ„ÿÀÍ4ÿÄû     a!Qqð1A‘¡¢d ±"Ô%U•ÕV–Ö”WÑñ#EÁá2DT·BR3C$uµ&g(8x’S£³4…6¦hbc¤´Å†G§)   !1AQq"“ÓT”ÔUa2‘¡Ò#³´u6±BRVÁÑb²3$v'7ðár&ñ‚’¢CS%Âsƒ£4Dct¤5ef(ÿÚ ?ýAîÊåSñMÁÙB8v)¸;(GÅ7eáØ¦àì¡;Ü”#‡b›ƒ²„pìSpvPŽŠnÊñMÁÙB8v)¸;(GÅ7eáØ¦àì¡;Ü”#‡b›ƒ²„pìSpvPŽŠnÊñMÁÙB8v)¸;(GÅ7eáØ¦àì¡;Ü”#‡b›ƒ²„pìSpvPŽŠnÊñMÁÙB8v)¸;(GÅ7eáØ¦àì¡;Ü”#‡b›ƒ²„pìSpvPŽŠnÊñMÁÙB8v)¸;(GÅ7eáØ¦àì¡;Ü”#‡b›ƒ²„pìSpvPŽŠnÊñMÁÙB8v)¸;(GÅ7eáØ¦àì¡;Ü”#‡b›ƒ²„pìSpvPŽŠnÊñMÁÙB8v)¸;(GÅ7eáØ¦àì¡;Ü”#‡b›ƒ²„pìSpvPŽŠnÊñMÁÙB8v)¸;(GÅ7eáØ¦àì¡;Ü”#‡b›ƒ²„pìSpvPŽŠnÊñMÁÙB8v)¸;(GÅ7eáØ¦àì¡;Ü”#‡b›ƒ²„pìSpvPŽŠnÊñMÁÙB8v)¸;(GÅ7eáØ¦àì¡;Ü”#‡b›ƒ²„pìSpvPŽŠnÊñMÁÙB8v)¸;(GÅ7eáØ¦àì¡;Ü”#‡b›ƒ²„pìSpvPŽŠnÊñMÁÙB8v)¸;(GÅ7eáØ¦àì¡;Ü”#‡b›ƒ²„pìSpvPŽŠnÊñMÁÙB8v)¸;(GÅ7eáØ¦àì¡;Ü”#‡b›ƒ²„pì__gÓâ£êE~•²O\VݪÏãžà…·#÷Á?Nž•cÏ´Ôô™Û£¾!àÞÖ²x¬.c;s÷<%Íåå+ÝÁ’¾ºckO¦‹£Êcq0}ç)sµµi®W¶6׳SÈpo× 'ü߯Wí¬?þ«[7ð¿™áÜï¨]ù¥‚øócûëëvþqkúß„ÿ›øÇñå­õ¥?á2ÿùßP»óHøócûçëpyůëvþoc/Ç–¿Ö”¿†Ëÿç=BëÍ#ãÍïœW­Áçýn¿ÍÜeøî×úÒá‡2¿Ã¹ÏPºóIüy²=óŠõ¸<â×õ· 7qŸã»_ëJ?†Êÿç=BëÍ#㽑ïœW­ÁçýlÂÿÍÌiøê×úÒ—ðÇ™?áÜç¨]y¤|w²=óŠõ¸<â×õ¯ ÿ6ñ§ã«cë:?†<Êÿç=BëÍ#㽑ïœW­Áç¿­XcùµÛYÑü1æOø{9ê^iì|â½n8§ëNþlãoÇ6ÏÖt ¹“þÎzךGÇ{#ß8¯[ƒÎ-Z0×óg~8¶~³£øeÌðösÔn¼Ò>:Ù>ùÅzÜqkúφÿ›ßñųõ/áŸ2?ÃÙ¿QºóHøëdûçëpyÅ?Y°à÷²¾8üom}gGðË™áìߨÝy¤þ:Ù>ùÅzÔqkú͇šøãñ½µõ•Ã>d‡³~£uæ‘ñÖÉ÷Î+Ö óŠ~²áßæ¶9ümm}eGðϘÿáìߨÝy¤|u²}óŠõ¨<â×õ“5q×ãkoë*_ÃNcÿ‡ó~£uæ‘ñÎÊ÷Æ+Ö ó‹_ÖiìÏ{âýj8µýVÅÌ›ñtÃéy…îÏ©\ù´|o³=ï‹õ¨<⟪¸°{Ù&Äü]ðú?‡<Â÷gÔ®|Ú>6Ù¾÷ÆzÔqkú©‹™/âØ‡Ñü9æ¸s>¥sæÑñ¶Í÷¾3Ö ó‹_ÕL[üDZÀü>á×0}Ùõ+Ÿ6ŸÆÛ7ÞøÏZƒÎ)ú§‹¿˜ö7âȇÑü:æ¸s>¥sæÑñ¶Í÷¾3Ö ó‹_Õ,_üƱ¿A|:—ðï˜âÌz•Ï›GÆÛ7ÞøÏZƒÎ-Tq€÷²-Ž?þë‚øuþ`{‹1êW>mìß{ã=j8§ê†1þbYŠà¾Gðï˜âÌz•Ï›GÆ»;ÞøÏZƒÎ-Sñ—óÈüUðê?‡{ÿÜYR¹óhø×g{ßëPyÅ?Sñ—óÉüUðê_ÃÍÿî,Ç©\ù´þ5ÙÞöÆzÌqkúŒÿ˜VWâ˜?‡Qü<ßþâÌzÏ›GÆ»;ÞØÏYƒÎ-Sq ÷²•ø¦á´w÷¸³§sæÑñ®Î÷¶3Ö`óŠ~¦c_æ —ø¢á´w÷¸³§sæÑñ¦Î÷¶3Öaó‹_Ô¼müÀ²ÿB|6áîþ÷cÔî|Ú>4ÙþöÆzÌ>qOÔ¬müÀ³?Â|6—ð÷{/êw>mlÿ{c=fËZþ¤ã¿öoâx_†Ñü>ß¾ãËúÏ›GÆ›?ÞØÏY‡òÔýIǬßÄп £ø}¿}Ç—õ;Ÿ66½±¾³å­R1ÏßÛ;ñ4/Ã(þoßqåýNçÍ£ãMŸïlo¬Ãùk_Ô|s÷öÎüK ðÊ_Ãýûî<¿©Üù´þ3ÙþöÆúÌ?–§ê6:ûùgþ%†øeÃýùî<¿©Üy´|g´=íõ˜-kúŽþýÙÿ‰a¾Gðÿ~{“/êwmí{c}fËSõýû´?Cü2€7ß¹2þ§qæÑñžÐ÷¶7Öaüµ¯ê&<ûõh~$‡øe/€7ß¹2Þ§qæÑñžÐ÷®7Öaüµ?Pñïß«Gñ?Ã)ü¾ýÉ—õ;6Œö‡½q¾³å­Pñ÷ß›GñGÂé|¾ýÉ–õ;6Œ¶‡½q¾³å©ú…¾üZ_ˆâ>GÀ;ïÜ™oS¸óiüe´}ëõ˜-kúƒþüZ_ˆ¢>GÀ;ëÜ™oS¸ói|e´}ëõ˜-OÔ÷ÞÓüEðº_ï¯re½Rãͧñ–Ñ÷®7Öaüµ¯ê÷ÚÓüCðº>ß>åËz¥Ç›GÆ[GÞ¸ßY‡òÔû`ýöµ?Äü.€·×¹2Þ©qæÑñ–Ñ÷®7Öaüµ¯Ûëï­©ø‚'át|¾}Ë–õK6Œv½q¾³å©öúÂûëjþ ‰øUoŸrå½RãÍ£ã£ï\o¬Ãùk_·¶ßKWñW¨ø |û—-ê—mízã}fËSíå‡÷ÒÖú~+áT¾ßåÊú¥Ç›GÆ;KÞ¸ïY‡òÖ¿o,?¾–·Óñ_ £à=ñî\¯ª\y´|c´½ëŽõ˜-O·v'ß;_éø¯…Qð&ø÷.WÕ.<Ú>1Ú^õÇzÌ?–µûwbýòµþŸ‹øUïrå}RãͧñŽÒ÷®;Öaüµ>ÝX¿|­§¢þGÀ{ãܹ_T¸óhøÇi{×ë0þZŸn¬o¾6ÇÓÑ £àMñî\¯ª\y´|a´½ëŽõ˜-köæÆûãl}=ðª>ÞþåÊú¥Ç›GÆOÞ˜ïY‡òÔûqcýð¶~ŒøM/7¿¹²¾©qæÑñ†Ò÷¦;Öaüµ¯Û‹ï…³ôìgÂhø{û›+ê—mm?zc½fËSíÅ‘÷ÂÙúv3á4| ½ýÍ•õK6Œ6Ÿ½1Þ³å©öÞÈûßm}9ðš>ÞÞæÊú¥Ç›GÆOÞ˜ïY‡òÔûodýï¶¾œŒøMïose}Rãͣ㠧ïLw¬Ãùk_¶ÖOÞëkéÈÏ„Ñð.÷÷6WÕ.<Ú>/Ú~ôÇzÄ?–§Ûk+ïu·ôÜoÂhø{{›+ê—mm?zc½fËZýµ²¾÷[MÆü&w·¹²¾©qæÑñ~Ó÷¦;Ö!üµ>ÚÙ_{m¿¦ã~Kàmíîl¯ª\y´þ/Ú~ôÇzÄ?–§Û[/ïm¹ôÜoÂhø{{›)ê—m/Œ6Ÿ½1Þ±å©öÒËûÛn}7ðš>ÞÞæÊz¥Ç›GÆOÞ˜ïY‡òÔûieýí·>›øMoose=Rãͣ㠧ïLw¬Ãùj}´²þöÛŸMÆü&··¹²ž©qæÑñ†Ó÷¦;Öaüµ>ÚY{mϦã~GÀÛÛÜÙOT¸óhøÃiûÓë0þZŸm,¿½¶çÓq¿ £àmíîl§ª\y´|a´ýéŽõ˜-O¶–_ÞÛsé¸ß„Ñð6ö÷6SÕ.<Ú>0Ú~ôÇzÌ?–§ÛK/ïm¹ôÜoÂhø{{›)ê—mm?zc½fËSí¥—÷¶Üún7á4| ½½Í”õK6Œ6Ÿ½1Þ³å©öÒËûÛn}7ðš>ÞÞæÊz¥Ç›GÆOÞ˜ïY‡òÔûieýí·>›øMoose=Rãͣ㠧ïLw¬Ãùj}´²þöÛŸMÆü&··¹²ž©qæÑñ†Ó÷¦;Öaüµ>ÚY{mϦã~GÀÛÛÜÙOT¸óhøÃiûÓë0þZŸm,¿½¶çÓq¿ £àmíîl§ª\y´|a´ýéŽõ˜-O¶–_ÞÛsé¸ß„Ñð6ö÷6SÕ.<Ú>0Ú~ôÇzÌ?–§ÛK/ïm¹ôÜoÂhø{{›)ê—mm?zc½fËSí¥—÷¶Üún7á4| ½½Í”õK6Œ6Ÿ½1Þ³å©öÒËûÛn}7ðš>ÞÞæÊz¥Ç›GÆOÞ˜ïY‡òÔûieýí·>›øMoose=Rãͣ㠧ïLw¬Ãùj}´²þöÛŸMÆü&··¹²ž©qæÑñ†Ó÷¦;ÖaüµÈ[.Õâ)8há'(,™Ed"©,’¥¦ªJLEP‚Sˆ¡ZÜðMk;í®ctw1¼µìp-s\ÓG5Í4-sH ‚P¬ô3Eqn-Þ×Àö‡5Í!ÍsH¨s\ AÄ/£³éñWÔ¹+ô©Ùôø¨ú‘_¥bï¼JÆàXññ‰¶•Èeƒ‹\D[G2NJ&CC6*ä1ORöêÜ 6¾ñÈîKÞsS,û«×> §hð'•¿jGÐ8A<‹H/u†–ð«‚ònió6Û`ãÛ«Y.á¸i10ý–7£½xtÖ¡£†§Æ€¯oL…xäi¥® Òᑸ$Ö1÷T|¹Ì‹DÎmïFhV±í?䤉˜sk_§[khmÍn'mYÃidÐ*Ðò8j‘ÿjGž·<—Õð¶sqf·-ó²9ˉn.[ƒýV7ì±£©­.( uV|µb*”ë©ÓDꔪmÓÜþŠ’;SªPS¸)P& PSn½=ú’ÔU()ÕRZª©ANº)Õ)UÛã¤GjuJ wM`¥*›u÷jKSªPSnÞ*’ÔꔨÓN…UL íñÒ¢uJU:½ÊšR‚}‹SªR©·ÇPZR‚•ORuLUzüƒJ©Õ)TÛ§Oz•N©ANà¨-L ¦Ýj UU)Tê÷*t”ÁL XRN½‰J¦Þ¡¥¤'T §UAjuJ uÔ§T¥So½SBª©AOëè¤{Mºûµ%¡:¥*›t©-N©AJ‚ÔꔪmñÒ¡N©ANò…MªR©×ÑH´& R©¶ µ:¥*KU”Û¯MMN©ANò…*'T §^ЩÒR‚›jKSªPS¸* S)TÛ®Á©¥ª@S¤<´“ª`S¯¢•uH m©-N©@üõ©‚ªsPÔ–§T §pRâR‚›u¥@RU%©Õ(yõ©-Nªà~ª’ÔꔚŠQ:¤ŸNš<)Õ()J€§T€}µ%©×ëH)Õ 9ô©-N©ãÓSDU 9ôé¥Ç­:¤ÒàSW…-)Ô¤=Iju€~z)ñWs I¨ª@?8x©S±5p?0ÿM.=iÔ¤ÑÀ£‚¸)Q:•p5M¨ëWÒÒŸ\ SBŠö«„<4¨ª¸<5:SVs .!UÀÂT'^Õp?pQNÄS±\ J‰ÔŽ•®´¨Š…`0ôÒ¢t À`è¥E4ZÒIkB¡ P…(B”!J¥R„)B¡ P…(B”!J¥R„,®Áw ¹f"Éc “8±K^ð$Óþ@è§_›ûç÷Û1ûVïôò/»¶‡îž/öu·èX²?³îÒµo¶/À§gÝ¥…~pxš»e®Üõ•K¹2ÇŒ½ni57fÞ*Ù”u‚D¦ÑL}4ÞPÆ0òˆ×ì?%0V.U` Ç°5³ãmî^zÝ-ÌMžGÒ|g+ÐÐ@ ó{š[¼¶ÿÊËxíF+é hêÀ÷DÀ;õ*ꔪXTÐ'TÅSn¾íIjuJ mÒ¤µ:¥* SªR©·]ƒJŠª”é(TÒ©Õ0)×ÑRZR•Mµ%©Õ()ÕÑQ¥:¥:È4¨R•M½CR@N½©ANà¤ZR•MºÔ§T¥SnžåAjª¦:ú)'T ¦ßMuJ uR-N©ANº‚ÔꔪsžçôT–§T §pT¦bR©·Çߥ@R‚U%©Õ()×PZª© §0éÝâ©-N©ANà¥Å:¥*›|u4ªPSª‘jª¥6ëPZRU%©Õ((=54¢uH mÓ¦—…:¥óÒ =ª@?0Ô–ªªP?=N”ê§æ¡¨-N©Nz\SªPSn½Þ:\:ÐKObuHÛRZ~¤€~z’ÔêÌ:ôÔ–§T€~~JT#¡4…?0ëKÂ{RéR½¯b@?0÷tT{UÀýu%©×±\ ú "ª@8ôÔiNªàpè飈OÀ4¸u¢½ªàz(Ÿ ¦‰×µ\4ˆ@§R¸<<•:S©Væ’;Sª¸|<´´¦®})P„+†•{Sª¸Žà¬ (Ž#¡_ZTOWjÔ˜iQ>[{ž•¢¶ 4’¢Ö’JP…(B”!J¥R„)BYðÒ–¨<;ï\ùU0ø«ó{|þûf?jÝþžE÷vÐýÒÅþζý `ö;<•«T-‹þÝ*v;<”T#þÝ+ò•ŸÍ»žshkÞ˹$4—”Í~Öò¨Êý·ûú¤+óü÷šý­yúÄ‹©€ýU¾­N©@ýu%©Õ )·J‚Ôêš'T ¦Ý;¼TxSJçÿMRuH mê’Ôê”çä©-N© ¦Ýj Sªû™6y éQí\½xàà›v¬ÐUË•Ô0èTÑAUNo×ÒÇfYÜÖBÑR礞[ùÀ\ãÐOàYKcðožïTÐr[IKyŠú®n5>/W³0”@bRªø ©Ã@2e 5¯7ÌókcaÜcuÛg¿Õ‹ÇãÙ«ƒz»|+mÆì}Ë“ðÛ=±ž5p§¯Â<+¸à2è†dçn„ƒEÛ ©XGª)¦.I¯½Qs ”1¬Tļ¢<•ªÅÎìMäÝÕ•»ŠHÔáS@]Ð:*ÐOJÊͰo,ÁûãÈ¡¡£M:iÓÆ´<;*¶ÙÚ±)ÿçƒÒ¡È.b„©ïhôÆn7Cx{ýí9DC½]«~k™Èÿtiû2Ÿý=«„íá;ª[H‚ºÆàá®àˆrá«Y¦.\ šJKº ²b²~Žå#%5KCrD `Ö¶+`cîãl¯ŠFÆâE{(iÄ#¾#¤®ÆÔž²F—Ž®Úñ ‘кVn͹mÓÆQª‘0HGEÐäå×}=t^PïVÝi—ÇÞÌH5£À¬Î6ö׌Œ%½£ˆ\dëò dhB©MºtÒ-N½©AJ‚Õ@¥*›u©-N©J§UM uL uÒ N©J¦ßIjuJ uT–§T §]AjuJU6éîTЧUÚ¸kßÛ!@ã\{Y†uSˆ(º‚Þ6&9¸’S÷TôH¸Ô5:§C‰¦E9mcwîÌ&ÈÀO¸óòì UïyàÈão Oyà8¹Å­pÎíͽ”Ý9x°¸vk¼”õš5iï=MhâOz ˆÖ»—†ogg1QŒø¯ÉÒWîF~Å'«Ú±on&†äû@ûfÃ2sñQ«†".å¤IÈ”D‚AÔ…ùœÝçŸ3ndŸ—0ã¶ûZٞ؜ziãKr oxà\Èb%WIú5ü¹åNÆ…‘o[¹/sh&6:FýXà!íiè–@Ò)Ð>7{,ø·]K/dIÜQ“Ý$¸Á@Ê>ºAÓåÐ)tôxlŒåó[°¦L¦TÌã%Sz ”ÇÌ„8î¹—üÃr茖òµ¶ÊàZGxö²?ÿÕ¬0ž€,.Ž´q* ØüšÞ€Ùm©æÇåÈ:]!$ô'.véŽPúTðy¡Ä>¿¸gÉ1ÖAj¨dFFÛ¸˜‚ƒ v@¨±ÑBZ)UCDÅ7 ”ÑfËJmJ$9þ¢å÷0°ÆÁ37„qkÓ,N§y ”©cÀémxñ^Þ"†­ ¼6n_ee‹Ê4MQÈß±++@æ“Äv9§‹OŠÒÅWn½5½P­N©J§W”)Pê˜ëè©-N© ¦ßAjuL TéUT¥W¯È54N©J¦Ý:{Ô¨ªPS¸*KSªb©·Z‚ÔêªuTé)Õ0+Éà%Mz=íá×pÛgá«´ÓW×ùçK4iy•¥Pc¢­Çˆz*j¦@o¢²Šk¦º€‡5|ÏÉ.iîmñ—ËÙn7Àè,û¾ëDa‡Æ|­5 šðcWºsO``¶¦7u…l¢[}æ·—±‘N8¸¯9ÐpUS*…C ×ÒbŽ ÃÏB¾S®‘j*”ªsžçôTé)Õ0)ýaI0{•Mºûµ:BuJ uT–§T §]AjuHU6øêtªª`S«hRER•Mºû´¨ª@Sn•%ªª”¨-N©AM¾:)Õ()Ïã ”ÁìJU6ëîÒ N©ANªE©Õ )×PZR‚›t÷?¢¤µ:¤9ùv…M uJU6õ / uJ sÒÓØRù†¤µ:¤÷AjuJ >½5:Sª@Sª—ÒúépER–”궤µ:ýJàpè©-N©@ãÏ­AjuWõyiP§T qç×ËK‚jàz4ö'^Ä€na©!íHç©-M\ Ì:TRÇÃËS¥5p8séÓKˆN©ãGpëWÒ¢~p7pR!:ö«Ç¦¤µp8R¡N¥\ >©#µ:«ù§Jjà`ðÒ⬢½©×µ\ÝÞ¢ÀÛ|tQB¶´¨ž¥`0ÔÑ>[{ž•¢×]hIkI%(B”!J¥Y‰Ã"Zµt:wݸý!¼5ù½¾}³µnÿX‘}Ý´?tñ³­¿BŘ½vµª­NÇ»Z¿%œB˜ Ÿów´Ì90QRxÔt.¸ÁÔ`9p¬rU¶ªö/»BRòŽ¥3 cx¥þ€¾ÁtW}ÔM‘À;…[Bþ׬ý+L=Áµïß##™Ä WéT•Ã%0z«uœ1lªNY±lGGP§Uºí[z:E1A¹;!U° aÐÄÝY[qq]ops^ò@¨TõšÐÖ¾õÃmËZHkšæ´H$)NÒà6tT»uÐ(£¤À@éiÛ4PL'2J”Šö§HU DtÝ0ˆw‚³Ö™››g‡>ˆõô8vŠŠOè\ca˜‹ êêðý…bÍׄ;~áó3e%¸²ÌôìÚÉ•2†Lœ€T]ƒ©Š:r›”¼¡èÍé÷hÃåÖûZÑÕâYôöÓéâ:ºV§}¶ÅËÜÖQ“õ§ÛðýKæ¡¥íÉâæY,Åësn¨ŠÀÈ S¦r “P‡(€Š"^‘ÈYå-ÅÍ“Ãã=#è#¤-òÊæÂcËK_øm¥Sª»ÄÕªPS¯¢¦:¥6øé¢©ANª‚ÕUJ uÔ§T¥Sn”¨Sª`Sú¦0R‚›u÷i§Uï²ù„!ᓉŽ*åcŠòJÜgv¤˜(,6Æ/²P¾d2T¥¦œì”ˆ&¨Q:ŒSäÔ¡¯Â¿Íýæâßø\A!m¤‚'štw×sºÝ®pë1±•o`‘Üx•õw!í-°ÛC/½ef«†wéîíâ8Ø÷:‡´°v/ÎmËv^yÊÿ¹ò ñ0îjáºæžMLÉ:Pç3‡o DŠcfÙ=Ô›¢MA2HR€}7€ÀÚYØÁˆÆF!Æ[FØã`àZ)õ“Òç.q.$’Jð¼¾Zâæê\óÌ—ó¼½î=$Ÿè €€.Ml-ò>bAìTÜCÖ’‘R±Î–g!'ºnØ¿bñ¹ÓpÕë7ID”!Šr bˆl·vÖæÙöÓµ¯†F¹®µÍp!Í ð ƒB ÁÙ¸‚fÏ ‹$cƒšA¡‚è Š‚:è ‰PâCÙ}‰¸ŸœI±¯Ë[BFj]š w/¤n„pýþÙºiãx雼È=ôtôìŲ`<„øƒ–lŸ–œþÈìkg8bî ¬k 'ÅýîÜšô¹ÕšN§µõ>ùt[ã”6[®pÓÅÔh¿îóØ×IGPti‹¯ø<à“ñ¹jôŸ“²îtç®I^ËM‘ ~ß¶­™F.eŸ:Žzvñ‰ŠVúnKÛ® "‰Ì œ¤Ž÷Ìþyo=“̶müD1]â´E¶ýÝd’YXàÆ‡¶¯§{ éhÔà AÔj[•;gtlgfr2Éo¼µÑŒŽ7´¸–š7ìjq $P(­f\ÞÇ®øŒÂѰy I)Gmm˜|Å55|FÛ“So\›йnÖÉǬñÚ…!Vun3Ž(˜ }ÒjjÆå2ßÍ?ýÕ5æ<@Àe}Œq[>HØÑW0àMtù:'‚ïXc¹ y|Üv׆gnß$ÍcÜMá(“®·k;h8¬Aã[†ü%eVV¹dœNØ×“S–Àñ""ùvlÜ‘´œ¿bšMTœ€U ²ˆ”©,ƒ„V$* )ûw'y­mÌý¾ë¹£m¾rÙâ;ˆÚIn¢*Ù#©'»P8’×5í«ƒCå|Êåôû0-£{¦ÅNÒø^áãP9 [ "€‡5ÔÒ3^ßá#†°Ì`ã®beåÃw‘3BbÈG²Ì×AUZðA½¾â2nRàbÐå3õÌõœk%Næ0¦ª¾9›ç/0÷þë¸Ûšd1c- ^ÊÖ8:ŽÓÞVPøÙœ‰¢9&ú©¬ô¼_,önÐÛðçy˜éd¾¸E«öÒ£VŠFZ÷HÑöÝ­‘°5&Žv㋱W³ƒŽÖ'¾pžX‡Šs0Ê"æy5"õÓDTI°É:‰œ»o(yèvΦUÒŽ”jõ 9Na)?ÊÄe¹Ï~U]Ñß²ÍmÉ$ s¢dlš-’(-ßÈK¥‰ñš=~Êå70-ä²ÚͺÆf˜Â懹ï$tUÌ’YšöEC$cÅA<:p7á"¯ÅͷÞ[báºÍò¶eÞÊ9éÛ*ªh$åB:Œ~RýE$á²ÀPíT¦ÓßWÐ;›µÜªºß»RF—ýÀO {A’ÞM$µÍ¯:—Žà¶{›Ì }£¸àß½÷R†šTMZîÇpsM8´ƒÖ½!Íü;{:øC¹Ô›Î7Ï4Òàd̶fŒ›”{qºi);–IHYy±håúG#uWxÁ‘{#¦Qp®¥OæýµÍŽyóÛ­¥½Ä/qžýñ±±Ôš²&6FICH. ŽI A:ÅÞÙœåç*6Uñ»Ï¾âhdhî­÷Òž4Ž,sBꆒö0Pôqۆá~÷⃲Ï[/±›IçÓvÔ¤ÂøšÔ‹Nภf#î‰Yçì¦Fß\ŽX®ÉâV0•1)Äæ2Y]½Í¾gìÎ`ZìÞh¾ »KçÆÖLÆDÂÞõÝÜr1в&º>ðÈÙ#®Pt3<ºØ{›gÜnm„Ù­®m÷:7:GjîÛ­ì{e|ŽÑã1Ìyi45%¸YÁw ’¼[_îa’V ǵڳ–¾nVȦáÓ6VU(Øh¤•Õ›3UÁªIYcN̨©îÙæ¥,öã2"6Üfnœæ[BI sš|#w¦êŽqs u·Ê¹yËû½óšuž³2Ý¡ÓÈHÖ0ßGi'ƒC\â ]™ÕËì…ÃWš˜¢ä¶/ËÞfAX’ø†œ½åb!ä[j“Óɺ‡½­ÖÏÔb࢚¿ź!V)ŠÑð¬~SùÜXѸ­o¬l­¦`’+gÅl×½§‹CCíåsC‡ßLÓJEW¬^cù…½8k‹[«©ãv‰'l“9­pàK‹&Œ:‡î¢p­EEñµÂ±áì\ň®U®ì” ȰRN¥ æ%üÌZ×!“lÙ²2ðif ‰{b‚'"¢aÜQOGäç8o·­ÅÖÖÝ6ÛwØêÖ [#XáÉa$²XÞ@‘ é:mZÝ'™|µµÚðÛç¶ô®ŸmÝÓIqsæ—´jjcÙRÃMB„:¦„ú›Ç$áî÷ǘG#ñ=’ÝØ8Ÿ·|ñìdYŒ”Íó;sCÛ‰CÛ‘«7Aü¢‚bB.u[±j£ÅRÔÄQ¹QbüË}É»0ùÌž/eZ6ç; s¾Ä,òHàK[ýqG=Á€ð!䆟£7¾näñV7û¦àÁ‰´a%­ûR¹íf–4€]ýSPÖ—ÐZ#0¾1öjñŽÎî°8ˆ½1ÎA‚<Ó7Ò·r²Å*현ëx»†íº æbI¼n“´w›¹pP(§¾U ë9®`së–2Úå·eÅžC,¡Žcc€2´'»/ŠdcËC‹ã¶­5¡ióÌ^ÏåûŽã·a¹²ËG ç>RêT a²K+Ð⇊î<¨#ÍÜ]‚®|ÄppÞ.›F\ñ÷½Éh\²eIWlⳓ žU$ñI7i ¹ÛÆH®ɾMð0}5œæ>'Ëçó5ÒX›H¦Š:†¹îœ0E6Dâ¢7Ë èZݿˡ´ð1fùŽé$½¸%³ Å*+¢‘–½Ïí¸½‘°5&ŽwÛŒñÏ³ëŒÆSvŸÊ^x(ÄŹ—gq:—~ñËDTI¸È8‹™º.Ø™¸–îI„“g‰Êcn—¿ŠÊs¼±ºŠÿy¾Ï/·ä1α°jtµñÃãyé2Dö=û ʽùo%žØmÎ72Æ4=Ïq#¢¥¯–V½ ‘PÉñÓÀ/0o[js_V<º›•Ëg̼„–nCï¢+µ>‰ºj ”¢»íÌEÐS@íP¦Ó–¾ªÛÙìvæÃÛæñŽÕes^Úð –¸u9¦­pêp#©|û™ÃÞà²Sb¯Û¦ê NŠŽ±Ú(ZzÁl`¦ÚÌ–¬]R‚œõ%©Õ()·ÇQ¥:ö¥:B’uJU:éP'T€¦Ú’Ôꔩ-N©J¦Þ¡¨-N½©N%*ÁìJU6ëJƒ­:¤ÒÒRÇŸü5©×êHŽŠ’Ôê”×SDêŠ\zÓª@S®•骯֔5¨¨W‡EIjª¤MN”U :)qN©ýt¸&iN¥ ˜ÃRZЏž§J¤€na©#µWóù*tö&¥Ät§Up?=Á )iOR¸•¨ëWMN”ü à`šUX !ÞD'Up?8xªt¦®÷tR⮢½©×µ\E;AÔ¬ÛJˆ© ÚÒ¢u Àaé¥Dè ¶ðtR¢TZÒIkBJP…š¼/¥«%ÇNû•‡Æq¯ÍÝóûí˜ý«wúyÝÛC÷Oû:Ûô,Y•Øì%jËbS±Ø>J¿"E›wˆLî^AÓ2äðñ^ó•ûmÊ^Ví¯ØÿÕ!_˜;üÿçÌßí{ÏÖ$]:}+}-Z•RǦ¤µ:«ÃŸü%©Ô¥¦ˆª@Sª—…4 §_»Jƒ©:¤íÓ`÷iRZV}p'ÁܧײÒÓÈ®ÏYÎP5Èü¦;aœúBË'E(™.Ñí^*MN‹}ºBxo;9³mËl3ml‹_¹®Ú{–ô÷lè38uÐðŒwO}?–{ãzd4˜{r †´ÖãÄF ¥^EHoG ýOÚöE³í˜èf­áã3lÕ„dB ƢѓtÀ­Ù7*'A"9@‚0ˆˆ˜F¿2²yœŽw%%õã-ËÞ\çÈKËœOð$ý<P_qãñVx‹&ZÛ€ÈÚÐX@ph Ãô®•ÉR™mÙ26oÌòÎÑ(n¬¼œ˜,Î(«€êº†kG*ûýGUÓ7€+rÛØ·ºÍ×Ré&~†ž ÆQϧPÔâÆðþˇjÕ³™Xb¼À†²&kpë/}ZÀGI£Cÿ¬Ò°Ç%ܳnÓ21Ò±=ªÄIwÒë‘è"©€‡8™ER€a0ê¥{ÙÆØDðû¸åš€ÈÅ\HãØkà^G¹2ykÚEc¦8I£žç^.  óÿ(Ý ­rN¾É¬u’¹&ÞÛwMQh“.™"£[î.ýu”Mªc¨¡¸Q(W¿m«ëo ¾)ú#·´p:µW¼Ô4P¸öñ5â¼Ö÷\×ËutÇÈ纮0=”#WWàà†œ´KÙ踟ï`3¦poܧïùDp»dÞ †ºŽœºÖjò×--Ö±i`ÁÒ5½ 9ÞÑoÜÚ>wÿ…ßåqY ¶Ü1•Ní’Id M !8©Í®ø€¬fG\ᨓRh™€6W}˜Ü–÷‹8ÍGK$‡€8¯ŠNšÐ[pxtU®ÿ%h¹ 2|ù ‹†Ï $S1;6ÇRHñŽVLM¡Š²R̘$s¦ è Bòë aß·¬ -’9¢ãSâêÿêýwºmÙïƒ8}`E£Ì„I¢Ý\q²úìÝ©K²ìǹ0ªŸ`C9ng ©ÄNQÓPä÷_û”[²FØÊÉcpã¸8pã@hïĹMûæ{ ÃÇ´ý¡Ðxý ò}|Çr LfØ”O(Bo71Duôg €ª¡˜,n›C å/½ÔµÖÁenðwBXxÛ»í0žŸiÄ~?É’³·ÊÀbž‚Aö\:ùâüKß³{õÄ|ƒu¼j ¦»u‹¸¡  Aï”ä1G¼bˆr {¥…í¾JÕ·VƱ»ñ°¼²öÎk ƒo8£‡AíD/œê®ÑjëU()×Q¥:¥*›¢•;SªPS¸)P'T ¦Ýz{õ%©Õ()ÕRZR‚u{ª÷¯ÙâÑ,ÙÀ/ü>D™²—‹är<\{E쀆É8ÑË>AÁÌ©@¡ö–Ðj;©P u÷ÚüüȶM³Î]¿¼gÔ1Õ¹.¥xÚܹÓ4pÿåHÃÛãpê_[òL³9Ë<ÆÚ‹I¾×0èž¶'?üÆ?èñWçfÄh´y2|ÕvR Ü.Ñë7h¨ÝÛGm”2.9n±Hª¬A)ÈpÀ !¨WÙûxÅ-³fˆ‡FáPAx‚àAA æ\À’9Ìr״Ђ(A ƒÐGEe‚~A­ˆµaj½Ã⥠`¯bõ¥.Â:äÈ XL££]ê›Ôeî\¨læá’ÈDÉ8a àªû¢‘ɸmÈ?Ÿ8‹¶oæƒ!ŸÆ%…£æ«ÛöK!µÀõ‡<´‚:A¨à¾ÃÉ[»mòÓ| .îzC¥œÝ–‘ÔZÀA Š+®1r˰Ë35š†”›O|†›q\‘f$¡@@wN™Ä¦ð€ˆ%wwHÕüÍãôxÿV™upœ‹¾#ÿœÿÓļ&³­”ݲ (mý7ŠmD SwÀ@C”š¾ÅÆâÙ45“Bù²úùÑËFp¢ý5ûDÈÒköÌZõ;ɼã¢îWoÑ2¾.¸S±~ÖíŒ$]B®ªd3„ùNB€è:WÁ¢ž|]Îõn ‘XÛ“iñkœECÑÀWIì%}qÌh¢¿‡kœˆ«ä½ƒYpãG÷]åGÓýaô.Sí0K€ÙKóEñ…‘rÝ©6ÖÒ‘weDج¥œA­þdèÊ?]V6eƈJ.ò94Õ(¬C(¤"@ÉË®hZbo?‡ö¶ZÉrÑ3¦-ÖÖx­ã4g@$p"®w¡‘æ]¾Ã¸È[|a=ÜS²Ûqn’ïðþ1-ñè à±ÝþÈ^²E©—1ÞdÎ-î«AÃLJ’†¹]±pœŒcØyrMÇmtÍät‚©œ€¡@Ú€€€ z~æÆÿ0[³>/Ä}ÃZ¥ñ‡.kÚæ“rêæ‚ ÑpwÜÛÙx²øë숼„’ÝLyiÔÒÒŠ‚ ¨\<3Î(ÏÞÖü;‘ð¼Ë‰ÛRåb¡&ýÔ ½¼à×$”#¤Ög2Ý£¥Ìœdk0*À˜ÄС¨F²X=Áµ?—ì¾ÞÜ1ˆî¢†rÖ‡¶A¡ò5â…„ã9ü+ZÔõ®•ÎW¸9ÃŽÌáž_o$‘T–¹‡[X暇OŠÆ”¥RèÏlC5$xî’ne cðï€Íé„<&0HÖoùq·3òþ޾Oþ°X¾uÊ"Þ»¯îÑAYí쮈J/„þ.Ûwˆ»YU Aå&ñ±¼± ;£ÉïŠPç­+ù‘´m¦ÿÛa.kOÿÔµm’¸7C6]ÐïÐ9|>ÉiGÐüqauÛÂb^Q.¯ã]62‚ûÒ qRrvà©(UP”t±’î˜Nch:€içémï16å…ÿ,ˆ8³GÝi“§‡µ ×…]ÞPƒk³3Wvœ/Cä Žš²Þ¬ü&ŸI_Ÿ»NK…Êï_ª¢¦UCœçPÂsÆ0˜Æ1¨˜Æ0ê"<µö>6Ä]÷ý•óMõ×p4·¥väܦF‘†´Þ_פ¥è£jI]í¨Ï@ID|_éò±l½ LD»4‹ÙÂÐB¸Û´qVye,­mã¿}uJØØÙ¨ÕÚžjEMOÒ©Û‹!sdÛ ©æ}›i¦7=ŧF’Z(:(8ìo¶ù¹Åœ!·ÝÞ`1m»DD»Ã§6£_.±w»ƒ<ÞºÅúI×Óé~Œ>%ÝT“ýH—KûíÔc8Ÿrô£ª‡Äwzb#Ìy›HÃå-zó-bÛ~YE(ûG%ÿòæZ#®Ý6ú’>¡c/úñ.«šÆ¹+4{I³¾5Æ2Î`®lÍ’VáIëèä-Ø6’O×™–xò8Åv›dQp²„D=òY »¹ð›K“69ÃgÇEŽ·¤E­y–G5¡Œk]âÔº†§ì€^x4®žk”Ü\Í»Æažb½’öjÈ šÀI{‰oƒíÒVReLìÔáÊèq Ä~XËÙ¿0¦Vn.¸¸‡ÎÌf«,͹Ð+ÂÆ‘bÌ«Q!ÊÙÜ뇤DH"A Ÿá÷G:wͰÈìü~7¶Ü\!t€P€ã]:«®†£S-ÚÂkÖ Ü2XWíIÍ–ä¼¾ÈfÀëXMA R´¦ž:]3œ:¨³G‡Ù~dø,â¹Ï öíßmY¨Z¹H—[Åg‹¾^ç.'2‚ᩞÎÏœ|TfåÐ o”Þ÷Â>[½­÷Õ·1°mß“ÚÏ’ïmŒfDzè4Ž?V£ÐxSŠß¶´ÛN}•–;F+ˆ¬»¹ÃĤ’_Ütнü4Ó¬q¯†žÃÇÊ<½3ha0’Æ€ÓQ×ûý@ÿzŸó9!~×ÄWÓ$ý^Ȇgò4ôf®¼\,¦/«½G*œà7,àŽñ„DDej"""""5ôvß²ûŬZº;¦ª‰æn»›‰4ô÷Žþ’½ÈâíG{$¸lTLvW.4d™À¤&˜Cß Z§¢e!Dl ®š›wQ—¶” ´þb³‘EÀ5·ë/…Çð’Oô/{Ürºã’¸©$âI„~Êâr^1ÞšÞöGpôÚÜt¢,nìI¢·Ð©»<­¨þè–nçt€BÝHAðŠ©ˆˆ÷ñ›I.ÿ˜,ÕÅà­Är_ÒelL#ÿÁáÿ„•ÞÝlm¿'1pÛBöZê êÒ8ÿ„/ð]¨Ý{ç=Xw• ÞÑT{ûÅŸ7ø+ëL¶9ŽÛ7Ò;í}Îcÿå¹|뎽ss¶‘·£ïQýö¯_½¥ ãd=¡Çͤƒ’m£æwÈeSø­Þe‘o 'H c(ODTú”DÁÉ_'rV[›~Xn›:ýé‚åÌ¡§ŽÛ0[Ç«8¯¡ù£oÜ,4û»ŒßøMÉüUYíOéçFqi2­¯4…ªýÍe4•^hÇ“ #$ùc²´n &³¶)¦¨v¤?bŠZ“MÑ+”—<ɵÅÝü mc-«î%tÅ¡úšÏ¼eaÒ‰«Ç¥mƃcÜd-þ-žî9Ù îÛqn’ïðãQ Ç 7‚Å,5uû(pFAµò­ƒ—s;{žÓ]Úñlj¸2pœ„kÈ—Í$£`5QËGlª™È Ž÷ €€W¤n,w=÷FlWŠ6€¥ñ‡.ii7ÐA¡ZN÷”˜ ¬Yl}î@]ÂM55妭- $OZÂÞ2óÖ6Î\UÜYH8•´ç-ËE³™'1p‹»šˆˆJ%ÙÖe,Ù«½äZ³A >àÄL4×JõžJás›[jEƒÎ´2ê9¥!¡Íx {Ë… IIq¥zJó®idñ[ƒpÉ–Ä»U»âŒ–’æ·I¨p€tu.´M]JQäå½Öœ*¼’©ÁMºt÷©Sµ:¥;‚–”êªm©-N©ANà¨-N©AMºô÷êhBuJU:½Ê^ê”î T¡:¤*›jKSªPSž µ:¥6øûµ©-N©N~J\SªR©·_v¦:¤…"Ôê”ë©-N©áÑRZRǦ¢”èN©MºtÑáN©@ô¨BuHz’Ôê5%©×± 9ô©-N©ãÓSNÄêútÒãÖŠ¤.4€p¤ZO… yêKS¨W‡†§J|UÀÜÃRB*Î*TìM\Ì4¸õ§T€z8pW…"©Wm©¢ujà~zZS⮩¡EUÀÂjhª¸<4´¦®Ì4¸„T…`8ÑÁ:޵p?pQDS±\ J‰ÔŽ•®´¨Š‚¬šTN[x)QM Ξ’ÞTy×T|f~noŸßlÇí[¿ÓȾîÚºx¿ÙÖß¡bÌþÃg+V[†Ï P…øòâDÛ¼EgÀïfœ¦+æt+öã•þVí¯øú¤+òû˜ÿ>fëï{ÏÖ$]2 sÖýÅj5ìHæ(ð§áH륧±:¤ó›¤µ:¤óù* Sª@>Þïr¤µ:ýk|·â\sQp1ÉŠ¯e^ É¹wL`®p&ù€ #¸™DLm<5׺¸ŽÒÝ÷SEK€ ®{x]q3`í8Óþÿ©~½¸c¶m<€l{R%©A`fÔæj‰H‹éiyUP;éG‚)˜ÅŽÕ/h±À@‰ ]wJZü§æmþSzoÛì•Ë¿4á¨ñk#`!¬oê´4t¸’zI_kòÎêô!‚6Öáò¸5ƒq$ç“@]C@Sä̾ò,î—q:„CxöÏdSh†úG~f(è"(]¦gæD†ß16ð€—NÿÚÚ1]†²(4’9¬.r²„A² Z‹xÖ¨¨‚@& •c2”yké¼&ÏÅ lÎ2Û‰mÚÐØèàÀI5{ˆ'ñEI¯Bð»ýÁw5ç} od‡\ƯBå¾ø»ØÙᑈ,¤&Š´ÖÊÖ£¨=‡Æað·ƒ\åéÍñ‚}Ÿ|vÎHæŒÄu·„rMÒ'•¾lëŒ!˜ªöy]Õ_ÊLcÙùËfU„Ë•Œb=‹xâ-ÒÚ®PYS(ªß+í~`s’¬nÙÜøI²¸H˜dŒ¿ÅgCZˈ㕎`Y¬l!-h o¾ç¶.yœóœÁe#Çå%ñ¤cÃx»¤—B÷ÆàãÐç±åŽ>7ŒI.ú¬n¸áMã<«Äo–J=ºdåáìÆ*¡õû1:ÈKBvﺯpEt@ÄA""Øç ÕÓQ1ŽSp󧛼ǵ~ÜØ›zëà²K‡¹ík¸Løà†Þ Ð¸—<,s]B±ønXòëeNÜÖìÌ[ß>È@hipâ+_,“PŠ€4´žp^RûB¸ã–ã{*C#n°‘€Ä6½ic@?:a ùËó ·dúmŽ«rJÊ¢I¤N©¶LSçXêz7(yW/±N‚W6|ýÑk®%h:@mtE4:RKˆî$hn—Ì]ÿ.ñÈ £k¢Ä[‚!cˆÔkö¤}8juÑ@I.'Øþ -Ì?5즻í|ù>½§‰¦nKª&î¹›8]¢öñdnË}¬4ÂnjøŒuÄ«EDë"«RupQC´ ðŽqKŸÆsþÞãkÄ'ÎÃi⌀CôÃ!{%µÕx !Ü|BEë¶}Ê ¡ÏHbÄÉq+^ðH,¬Œ u@4£ôž ·ûCMWGbÿfß6 ÊÊû¾8Î÷¦ ‚]ŒÉ´˜¶#]\°È,ÅÊK£xHÄ·Žv‰®»AYGd"u d÷‹¿æzÝàßÁmœ¾î™† òÙØžE ØÎå¯/oÖ¿KXhçíVß“›^ß*ܶ[;e.݉ÂBÐX×HÐjçw¥¡§€qmK…CCIa?´ßXÎ*3ÅšÏ?yúk…SxÚɸ‹ˆç—<“Èçs—s6Ë$Ýã&<+$b•`M¯l%LVɳrW•÷;3oÌÌës™";*#¡Á’ kG½ÒiWiÁ¡ÇÍ ùæËÆìSœ1V@ˆŸBÒ÷’ ¤€@ñZ7Uu£mãÂoµg XæXÊþâ{£Ú4}8´\r K=lÙ¥ÀŒ#i×ñ,¯.êYšO=³ä¥#WE=MÙ‘Auä'nïÞAn»›¬MŒÙ]“tî†8è–k,kŒ3D f·0Ç &‚¤hôoï£ÍÜù¸ñû¦Òí#Æ è-Dò´5Áì q :øîໃn fÍüFñ#‰2ª6ÜdÉmË »;rZ6QÛ¶.cÌämG2÷<å(FNŒ-š¢Ð‰´rb®e³)Ë—ÜÜÉæ2웵v> !tÏg{rçH×4Nô2&BÍCÆ{žKÛVDv dlítwéËYÞÚîîÖ88E{²é+¨|V†€×QÄð¨Á¼1±®BöÙyµ¬Ÿ…±²¹5høÓý´-›J؇V.%WjH¸÷o’hW/TÞìý-ÁÀ`Ý0úÎghe1|“¾Û }ÎW<,ð$šY¥|šÜ©Ik+¡¢ …ç˜ÍÇaÍ\뙆 Ý´†’ÈãŠ6³H.#KM58ôjqâQ{Q/Ë'!ñ¹%qãûÆÖ¾­ÓØV3"OY× MÏ wº#¶…”„vù‰œ¶1€Lß ˆoW_ùyÄåpÛ*,ŵť躘˜æñ<áBXð×Põqê\ÜäÈØd÷D—XÙḵ6ñøÞÙP F¦’*:ÅVsû^4,ÕR¶)7Ì™€5ŽšO 6îàÂçóRæ¬o,ã™Ñh3Ã$Aô’btÐê ¥hí[O83X|¦2îÚåñ‰5ˆ¥d…µd`j qÓRM:bàþË;öÈǹùiûþòµlhÆ7;›¼n‹f _8”¶TA˜IMÓü=bÛÙ;%ÀàÞ$l$Ϋ7s ưMIM[7ŸN!¼Ûئ7ms(Ñ7`ųääã–@‚cd8ºÕ€ÞüÝ78«)r{6åßÔÔ|@If²Æ¸Å4`–ks rh*@fÀ2ûWšø È]Ga¹àÖ ñ¨ô‡‰#}5iax]ÇpÿÜ"p…*¦fâˆ\Y“’·c¥ËoÙ5·å#¤Ý:dᜠ°æVã‘»¤ˆÍÑ…»dš\‰V2ƒÙ”ÅÊî>aï¾bÙ·llÌ%ýƒ¥{;Û‡:F¹ êw‘²ÔxÎ/%í«CF¢C ³6–˹9íÏ•´»µÚ! cƒ‰WAsÝ#¨|V†€×QÄðªò+äÛ[2çÛ!Ú6\=…mMH »iÂFEIJˆ„‹bÖ*8ª³‡nÞ<²O[²/0‹¥”ÐÆ.ƒ_Jl Ûwkˆ¼¸’òþ&ög¹Î/‘Î.u Év–“¥•㤠€W†ï Äy¬¼ù+hYmg#†ˆšÐÖ4¶¡  D N§õ‰¡_I¡J +Òx-¼S•M´‹Sª@S«¢ µ0R‚SBªPSn=ÚR¢uJ sÒÓØR‚›j SªPS«¢¤µ:¥:êhSªPSn4¼)Õ()S§±:¤*›jKSªP?pT–ª!TÛ¯MM(Š¥:B—UJ uôTÐU m"Ôëõ¤õÔ§T€}ºwxªKSªP??’¦‡©:¤9† uJ¥@zª@?0Ô–§^Ô€z‚ÔëØÌ:l©-N©üþJTìM ˜{¿ÃKÂRùéP„+Þ‘ju)ãRZGR¸<5:Sª@8óëRZUÀüü”¨GB¹†•{S¯j¸ŠŽ ÁJŠªUÀÚxjHEB¸ž§J|UÀÀ=á¥DUX !¶¦5p8tR¡M\n´ªBu*àq£‚8+‚Š"ŠÀ4¨Hé^€p¨–ôY‡Nú‡-~lï¯ß|Ïí[¿Ö$_víÝ<_ìëoбfŸa³ÍÕ–ÅE; žhЊ/Ưæâ?ˆ÷´Í¹X9Ê@ óßi¯jòÙºšàÖ88p=-5 ±c,bg5„jèýÔ¾»ûÓa¥ÎÉP;£2@ñŽÖ*B¡Šæu"V]Crœ„\ŒÊp×@=«¨î¬>ðâwSJöþ4¯"– ‚+¡ßˆ…ÆmÉå‘I2ª·ìÙ9;6.Ö§!¸Š.C³n¡{6ŽJEH"tôï×ýÕ£".–Hõ4ëP=‡á}*íY+ŸÝèêtp¡èãÕÒ»ÊÖ™›R5{_ Ã9go$±¤XJLöq-Ù–& #£ó¤ìL@Ý¢(”ÞQéËZ®FLtÒ6ç 7nÚM#¡Ôé¥WJÊÛÃsLw -ŒW¦€Ôq¨·BÜ®kË5«3p–½’íV(*ÝTõåÝ:'ÿ(w‡–·,LϹ°c¥¾+‡ao¢e mµóÚÏönñ‡€ÿßTeSmd V:©ANzšꔪm×§»Z\ª@S«Ê´Õ:¥:ú*KS)TÛPZUÄÀr‰L€†ƒPYQCШ8Ž ®/iµ~aU0ÜPyuAÖ°×xˆç:›Ò²vùÅâž…°Èpcn™c‰5ïj=êÆÿqÉÐOÜþôe*ªæp–ÓXÀ@Êœ£§~²v˜¸­øÓŠèÜ_¾nKÙhŒ­‹{³>1ÉV ~F–•”<^?{xÛ­oyÔÈV{ÔÔaj/"Iç„;6Ê*›s¤™Œô¢!òùÛ[‚oæZÇ9…ã°M‚0ë‘ ¦‘o3H3÷`‚@¡wI¤¯£¶¦o$.ñR]Û7*é^D&V H3FA—k5Ÿ³Ð ê^Û–¢®™B(bƒQ¯¦¬q/’M%xeÞA¬’…v,¨„z€²žýNþ¦åk5iŠd[ºV.ã éF‘з‰ˆ²‰èb†ø èÏwŽå´ë\V÷„Ô.2À;€±û=ÉäÒ°ÇúÒ§JÉz7¦œW5‡·[Æ¢bœÁ ˆÖNÛÈJq]ï_3«Ôí¤Q~/ü¡6õq·ÖÍÞõÕS¯œè»µ¿ÊGI° ~PÐÉ]‹›a‹¹9›¾wÎ&m­¶våõ´÷mÝãô±Üʘ¢da¬säuK†HpÛ0{iíLŒYüînÒx­Ý®6 ÔáÅ®á$Ž~“ã1µÔ©ÌŽ3øoŧY&«¶Öd$Te‹bñ;7ÊZ°¤^' ñóeff%Þ½Gß GLÂ& ˆû_(ö<»'nɸ-vAï3N[Å¢G†‚ÐzÃÖ2¿Ö-$p+Ëyº£Ý9™r0‚Û6°G<¡¤Hê.sœêuCкÆRÜm,Ô…P ƒ§.µí· ¸`í/,†íð¾ ð\8,ÀÛ€±û-{ÚòiX¿îgÖ•:Wûͧ«ŠçöõºÞºŸNQQÖ²V¶ ·+£qvé…ÌJ§Uw WV©ANòR¢uJ mêT Õ()RZR‚›u¨-N©J¦Ý*KSªPS¯¢¦…:¥*›z†•uJ uT–§T ¦ÝjKSªR©ÕPZª©AN¾ŠT(ªB©·¨iP'T §=NžÄê”ÛÝîÔ–§T€~®Š‚ÕUJ Á©¥T ¦Ý)xUU()J€ô"©û{½Ê’ÕUHç©-ERüÃÔ5%ªª”çòTТ©NaÖ—´ÒéiìN½‰@üÃRZ{UÀüõ%©Õ ˜zªKSª@??’•èM!OÌ4¼)Õ •èE{ù†‘ ×µ zjKS±\$ê=5%¡:«Ã¢•M yéxQ^Õp=¯B~p7w†¦‰Ôõ«‡ŸÇH„pêWóÔéOЏ0Ò¢*®-Nš¸:)P„Õ€iU:•èÏ ÉoC”t0¯Íõûï™ý«wúÄ‹îí¡û§‹ýmú,Úì6y+U[†Ï%_‹Ž' »Ä§¥æÎ9d•%¨ª@8ôÔéNªàpèé¤ZRƦ‰Ô,ºÀ²ní“°s’®î¹†êFYé²Px9 7mÓ‘¼£9)D·vÑ&{ÅÉu= ¢D5Ò÷;,ïíÍ•ûÚÌcf¸ÿã2&6ÿhx²½Òqš;£Q![Ö"9mìc’÷Ť´ÿd¸ŸÂ;Òõbâ¾,¢ZSØ®Š!bÏ02“nc·`÷ã çOdä]H¹xåc‚Š*(î Óå•,ðÙÙ3po9|Y¥¿ûόǚ½º"kXƱ­hZÝU¡è[ìw°Eg&66-ˆGÀôõ¹Î$’I4&€à±êÊOcI+fÁô)ËÊžJBkµŠX±æ`Ì¢éI4gÔC&]æL"";Îç¾›rn(ò¹ímŠ2ØéÝ3V³À¸¹ÏwŠ ñkAÂu1ï8ëSmdiª¤“ýcBßM+Ú±[+ÚºÅUäD¢AA“täRNc³ª›ÄXÇ•”I”jMÑÞÞß2¯x“—~Âgv´÷ÝÙŠéÒ-% 7‡M$þ%‡¼°»kìãÓÇ£²µXH³"Oª¢· ÈѲ+˪V+Ò©DD=ñ‰p£aŠ;½ü3Õ±ZÈ!¦¯u‰‰%•¥¢wzš½»v´”ÈÊ”aíkqÂÅ“¶žÄ¤Ôc6…AÊŽ»PÊw5Ð4Þ×½ÉZ”ù˜ÍÀö[#ƒZ$ÔÒãSð,£E§Ü¦kÞtpâ8žž¥Æ®; 2¶mEfßM̵E»øÒ¼·n¨¶äUÂnÜ<1 Ýx¥ÌàSéÈ`(ià¬Ø›q\Êö°C¨#[xPtb½œ+ÿ¦·ûnH\Y¸b ÙÂÛ±³íˆ`Ý%ÎÌW v…)ŠþN4‚`å×R‰uõsœniÃSîŸÓý ªeÍ›>Í»^>’» ƒf~›Þ"Ù´4pDníf—fRM3iƒ„‚8tÔG”G¾нÆI+÷‹«‡šIOÔ?Ì»L¿ Å ÞÊT­W:Ü-´½¸ª×1m§O"Z,»¸›RÊ¡'èm½<ȶ(ɦAtQT8{”+·q6RÙß’{~Ûº*hhMkÙõ®Åíëû÷ËÓV´ô V”!b¬­ÓsK¨ç³ÌkªíMÙ€öZÖháqђﺆÝ'€qúÇêXæß]HÆ»¾&¿WÔ¶ÛžàNï4¡4ÂnNÉùݱtäȱ"ï cvÀ€:Q@ß05åÛ]KhÙ÷'21¡Ìs™ÑNƒÃ¢Ÿ÷.Ôã/‰.i wOhãÓÚ»/¸{öpÌž÷¢ä´ASDª·UC¹HÔGû$Êp&¥8sVW÷eþ½ø¨íô,&ᎌ†N±©§ê5 °ANºÎÐ-f©M¾>í)§T ~%AjuìJ s IjuH TЧTÀ§]*êÛ§¹Hµ:¥÷AjuJU9†¤µ:¥*hSªÙeâ“•(úò t/,Ûr(WnÚäÀVáÌ‘È%ä »ka4Ž…3Ìev¢·Sú¹ËW R•Mµªª”ê©¡N©AN¿%*'T ¦ßN”ꔩ-N©J¦Ýj SªR©·Or¤‚SŸÖ¨R•M¾:E©Õ()ÕPZª©ANº‚ÔꔪmñÔЧTÀ§WE*ÁJU:Ý©-N©J¦Ý*KSªPS¸*4§UµËF!*€¤§. <¾}Úê\Ú¶áš\»\:T.¾=‚ A5L ˆ÷€G½­`Ý…p4i:VU¹0EHâ¹½k¶ˆþÓ@2Ÿí‡”u®ý¦5–ü¬º—7¯›‡Rç%S@Ъ²«¥T §UN’R‚äTN©A]¾:šê˜ç©-N©J¦Ýj UU)TÛ§¹S¤§T §^ÐþŠI‚”ªmñ÷êhªPSª‘juJ uÔ§T¥SnžçôT§T §pRLÄ¥Sn¾í*ê”ê©-N©ANº‚ÔêªmÓÜ©-UT §?“ú)qLÄ ¦ÝzjhT §U"ÕUJ mÖ µ:¤6éRZR‚u4!:¤*›téîÒ—…:¥)R½ Õ(˜jKQT€~z’ÕUH s»Z‚Ôêçä¥Å:¥6ëK‡Z*´§R·ü5%©×êH N”êÌ:ô÷kRZRùù)P¦·^ï%.iÕ •;^Ä€naîè©!:ö«úêKS¯b¸<¥I Õ zjt¦®Žš8„ê4¸"½©ôS±?¸¦‰×µ\=5$#À® -)Ô«€ó I©ÕzcÂ:[Ði9J>2kóW}þüfjÝþ±"ûÃgþébÿg[~…‹7ûÖ­Çé[GŒhãô¡~'8¢6œLñQöuËɲÿ¸¿p¹LßùU¶áüwêp¯Ë~`þþç?kÞ~±"èÐ0†·ò£R4¨B¸„øõ$s .íWóù)iM\ Ò¤„ê»âؾ$¬·ökæïå±R)á»n–nÖUË9-Y®DÀP6ìТUDÁ¾dÌÐy5›üU¶V) {é èK€:A”8}!•Óô¯B³•ñXC§ Æßõ?γ/[ ú䞺̻‚,Æß¥p+µœ3)E”„nvM¤ÛÆÌ‚ÅÜpÕœ„`.;¥WU›PPÇï‰Aþµ™Û¯{îd‰ä9Ѱ´‘Ð\ uôW‡Ô°»™´²ü@t•´ Óñ.. mÒ¶ÒÕ¥U()SNÄêªmÒ—…4 §pR êL…SoPÔ–§^Ô §UIjuJU6ëPZWzYü5ñ[äºìœ•®›id޳YÈ+䑌M08œb¶Ž:RÂQLCF¨ïh]5Ò²ÜÆØ8+ó‹Ìæ±vÙhèå¹…a4ûm/?×ÓÃBÙñû3wemþ7=‘d9®èÚ;£úµ]E%' ò&f=ôL¬s…ZHFI´pÂA‹´L$Y³Æn“IÃg 41R˜£È![e½Åµä º´‘’ÚÈÐæ½Žcšz×4Aê Э~hf¶™Ö÷ tw 4s\ \Ò:A„ÖªùM½C\¥«Ž©AJ’ÔÁJU9† µ:¥:©P§T §@ÔÐ'T ¦ß"Ôꔨ-UUÝ–gù÷!Áý¦±°ÎN»-ÑŠ36MÃ#ðSíRG¾nÀíä•HɈˆS b€é™Ž`lLï÷no1µÈuÇ-ÄL{kJkiuX x©l¸ÝŸºòö¿}Åão§³ê|pÈæÝ$6ާXmHúÂêéX¹{~Mì,ô\”Ìkƒµ’‰—dæ6J=Òc¢Ÿ0z’.š¸LGßBÁá Ùín­oí™yc,sÙÈÐæ=Žcšz \ÒZàzˆ$,ŽŤñܰÑÌsK\Ò:œ×Aú øÁN¾Šç \UJ mñÔ–§T §UAjuJ uÔ–§T¥SmM uLU;‚• R•Mºûµ%©Õ)TÛ¥AjuJ ]Iju]fáü¿‘#šÇø«$_PÍ_+æZϱ®{š1¼š-Ú»Z9wð±oZ¤ý¯QTȘà¡SX†ÐåÖòû¿iíû–Ù粘ë+Ç0<2{˜aya.hxli-.k€p%®¨+7ŽÛ›‹1¹ÄØ^Ý[5å¥ðÁ,­Òæ5À84‘ZЃÐBäR|;ñ #55‚3444Cr’ÒÒ˜Â÷aÝGoäd_»ƒE«&,š¤uYS4Ó(˜Â5жæÀ¾¹ŽÎÏ9‡šògµ‘ÆËËg=ïy kÖÈKœçÐ $€Wn}»í`}ÍÎ+%´l.{Ým3ZÖ´UÎs‹kZ$’¤®Ÿ:ú+n-Zà)J¦Ú‚ÕUJ utTéìLÉUµî¦ÖÛ+É͵>…¡%$´<}Ö¼4Š6ÛùvégL§Nرn¤I#èS*R”DJXæe1rd_‡Žæe£ŒHøŒ362@tUÖI8€ÒH¡]ÇX_²É¹'Á3qÏyce,pÏK%4— - u-Û§Mw¨ ê×µ0)Ü%©Õ()·Z‚ÔꔪmÓÜ©-*ª”ëÚ(¯bb©·Çߥ@SªPSª¤µUR‚u©Õ)TÛ§Oz¤´§UºEGÊMÈ3ˆ…/- ¹0ŒŠhâBAó•9nÍ“TÕråsøB˜Ãà ë]\ÛY[¾îöHáµµsÞàÖ4’ç8€í$Ío÷S6ÞÕ’áækAsœOPh“ô»>êÁY²Å‡ûCxâ|‡mAµ˜š´g#㚊›€™æûª8çÏu:t´:®œKAë ;Ú{£m÷Ì–>ò N·¾µ£ÿ-£~€ê~%ÕeSn•´­~©ANº‚Ôꔪmê’ÒR‚]•U)Të÷jhT ¦Ý)ªªPS® µ:¤*›z†§JuíJ wJu[¤T|œä‹xXçÓòncÑÃù)®T*MÙ±bÑ5];táSHše1Îa®½ÕÍ­•»ï/dd6‘4¹ï{ƒÆRç9Ä5­‰$€Jæ·‚{©ÙmjÇÉs#ƒZÖç9Ç€ h©$žR¾‰h©{zMì$üT”Ìjæk#0ÅÔd›$Ó}»ÖRAÓUɨjES½ê‹K«L…³/l%Ž{9©’F潎ok\ÒZáô‚B»›{›9Ýkyâ¹a£˜ö–=§±Íp Š¯¹Ý¹rÇBCܲüÛrâ;äíûäKö°“ªE¸3I4áåVnFgŽtQIpACŠ*”ú%uâÈãn/fÆÛÜ@ü¸i–&È×IxÔÃ$`—3[|fêPâ*$–7ÐZÅ}42²ÊbáŽc„rš;CÈÒí'ƒ´“CÀñ[@)·Jí–®µR‚ÁJ…0{M½CK‡ZuJ祧±:¤íî÷j Sª@?pT–§T }ºÔ–§U¿ÅÛ×Ó ™Hx ¹XËq²O. È§ÏØA4\çMS/ «x¶Ë(™ŠE2e0”@Dº79,}”ðÚÞ\AÍË‹bcÞÖ>WRØÚâ È  ·oc}u ·°Ë%¼ ‘ÍcœØÚz È0P´‚uÜ ]T€p¤Zª¿Z@8óÔ¢£À‹UU yõ¨-EUÀáÑKŠi@ý~Z\ð¤…Sª¸˜jHE{Rùêtªª¸˜jHíERÇÃËS§±5p8søèâRÆ—pW…*'Ç©\ ÍH„ëÚ½Já-ë}°éßI!ñ¦Aäñ׿ŽüýøÌþÖ»ýbE÷–ÏýÒÅþζý sv=ÚÖ©ÿn…±)Ø÷kGýº¿ ó—Ão&A¸k÷”£þUmŸø{úœ+òߘ5ø÷9û^óõ‰Dƒ¢½…jWxjH Õ\ÏKJÀÜÃRBu*àq¥Døx„ø¬ýáfÖ°²L;«{#½fÙx™f,.ÎÈPP¥e1©*Ø®ÖE·¤‹cœ ¢NÓ7¾˜µáüÁÍn-»vëœn– *ÙÚ5jh5{ÚŽ%ºÀà[N{Ô³Çå,!mì¢'†Q„Ò„´é-5 vÇ¡f]ÊâÚ‹;´Å™êˆç|G tìˆ)»bš´D…&ºróù~,dïešNíŽ"MÀPº¼ZâOk‰4Y›è ¶yŽ*<4‘¨Vœ:8Àº=ò-U6ôö†9Îc&át\{³X"tÛ  S€ººÖóo$ÌŒ‰t:ƒ¨Ö+ÒOWÒ°R†Ö­è[S(øÅc§"&£[º„¸Ìñ)ÖÆ(œ’MÙòÙN]ôÑ @£¼÷À 4ï"/s$µqmËÓJñ ð÷öp+‰²¸¾ÁXÃ/·¼œ^J䘈zví£!Ú,“uaH¡Ô¥ èê&w*¶ä1S\Û†ÿ-g¡Ý»Šä‹(àcdŒMzOgi§«é\BÂÑÕsÜü:ðùkaù †ç†œuq’êdÍ87Ί܆g¨Û–ªº§dºª»L¦*Å0ˆ<5ªîLÕæWL tN:À¯:EOObîE¬žéÇU>•”ïÛBL£gì“{ènÌ".›”ÄIôzåY£Ä¨Š6] ÝÐu.µ©1·1=¤º­ =GªŸŽ«•²ž£Ä-åÀ¢šn7Žeç÷¤Pºo Îrˆ‰Í®¿äë]i-ËYZŽŠPt ó®Q3öŠÐË‘EWQ¾è”Ü@ê€ t€Â:{ã”F˜Œµl½5¯ƒÂ¨=äTNÅMÅ`0‰È¡•ô(¨•0H»„1D…0‰‡Qðìä«€é#Å"”êÝ)§T ë ‚Ôê®ÛÝîT–§T §=M uJU6õRð§UœÏœUgåž#áÓÈlI/aã«^éË7\"‰tg#¬v$vÖ)Ëeqã'.Z‹†æ‘Ër#éÄCÆ9õº2Û[—³;!‹9¹†Æ ¡÷.-sÁZá~‡ 8µÀÔ霦ÁcóÛÂ1–h“g·R³¤=°¶¡¤u´¼·Sx‡6­"„® •øÄâ,߯¯—Ù*ñ¶ {[^سîy»rÛ²#˜¥Šˆ¶#"1lÁ(ÆÉ&Nܤ œ¢§2‚&¬Þ×å&ÄÚØ6a!ÇZ\šiáŽY®^~Ü“=íqqy$é'KAÒÐX¼÷0·f{*윷·xß›Ž_p´}–FÖ††Š ©ÄUÄž+(3$œNðAmñ+y&ƒœß‡rÂXZø¼Á² ¤r‘)„ͯ)q(܈¥!7åê “WtV2ETê‰Ê!æ»FѼ¶çEÇ.±ÍÙy|YÈ[[Ô–ZܲC̈Kc”5Ò×Hq`m(Ví¸®½¹gòÈ€íÍŽ¿sM@q ˜¤¥žÂàÀzHÔOH_~Vàç…®®è[S3q?v%!u[öôÜTU•‹BfJÙe8ܦ4ýò²³ Å¤Y•R¢ÍºYûa)ä)¸6·79›¿±Se6~Úµ0ZÏ,o}ÅïvÉÿelZœý:K¤“DMqÑWHäÏrïcm„v7p%ž(ÞÖÃm­Ñµãý¤Ä¿HmjªBѪ‚ ·W€‹õ§ {y[Œ­[VÊ[-Îfw/öEžA’oÍ’NUU@2jvhÙL^ß±)œÄÎz`ååí¾ö†Îáù;«Ác<ß» \[÷]D8]æŸödÈaʬ¬{Æm¯-Ä-±‚ØÝ>ðƒÝ 05wúA' éÑ«íÔjÒ Öû ÂÇÙ±­Ùnð½o Ó-Zì…ÊÆÊÈ8ä–ƒLŸ™Uš I¤Ì‚í%†ª·`ùHX ÂU“é^s?~lÙmrËÂZYí[»†Bë‹[¾ýÖoÒ?½1Ñ´9„ø¯’7im âKîÕ¶ÅÚ{–;‹M‘”¸¹ÏÛÂé öýйk_Ü8=Ä:œZÇG£€pÙ1_ ¸Âãá¥&2–p[Û-rÃüy) …ž­É1,›[sã†m,ä[I¶4¥Õ*ñBp Ú6d“‡j, ‡f~îçæ~åÇóܸÛ8Q‘É;Û¦HgÆÂé{·:à–1 MÔ÷Èèâk*ýC«ƒØ˜KÍ–7¦s&l¬›~ëw0Bd{€X€áªW ;KZÀùïIã÷‡kÈŘ×=áŒ7bl3;i˜.Ëu bîµ.û|uâeÙ³bñ)ÍÖYP0„OAÞæÈì^`fó[Ÿ#±w…„6;« sþbS4Á-(øÜæµÍ,%­s\*I¨¥×´1˜Ì–êÛ—rÝà/$|_ŒG,RÇÒÇ€ç4‡\<ë¨+Ч]zÉjóê­îÞuÚvÄóe^Á¡-´Ë$dÖy“ÄO"Õ”éЏfS¢(€Žº‡~ºwñÝÉc4vN ½tO¸ô5å¤1ÄPÔPžv-.¢}ÓKíD/¤°¨Ž$Tt¯o¸Žµ8¶Î× ån òãË󷇶‚ôpÎUoe<Æì"¡#›))`nØrÎi6Êt©.ôtÓ1S*eI?Œ9y”åNÈÃ|/ÍìS,wæ›ï3ä,ÃnÜùDŒºîæk£, T–ÇPçââç}5¼¬9º2_ßܺÈ:ëkãî"³º›vµ¸Èxp&”sè@ 0+‰kû0gÃãÜŸˆå­®!m¸¶XÞfb]›È»»+/+*Í•âZìTaRzŠÊ*šNˆ£„ß ¡9LRB½Ë—8-¥²±|þÚËEs°.%uÜqÆæ¾ Æ9×’5ï«H .a 1è ’Jò­é•Ü;Ÿ#ŽÄg1òC»¡`·{Þ eº.pl%ì-m5À¸?UA‹³¤øPáŽË¾Ú`ŒƒÅÌfnYÄ|,ÄŒ7ø×Ú7„¢hú=¯1p¸žc.÷°tá4W|š)7ncÿnŠj”šÕ·4¹“˜Á¿|`vÌ2l°×É%»Ñ}=» ¬ÑÄ"tm«Asc.sžˆ^ÒsSì-“Ê·jåó’3sÖ=Ì·×iÎ¥"|…í{¨Hx­¯¦Ž¯`ø8ŸBW‹býž=µtð¿b¿¼gl.Ã7)œÇwN\Ç.Ê&n-D·\Q2‚‚å&¨~÷›¶/µÚÙ<xÆn[æÀçètàú´‡>7‡1íÔ¦š8Ž+mË›¦OŸ±ÊÊ`¾ÁÚºRÝM–œ[BKHcÛG5Ô®— ¯°F i˜¬Î n·+˜0ž.y‘2B1'éÜ 6Qr[…”zÔc’?cþêR¬!¯ù5°o}ñ6ÑÌ`qqÛ6værm´./-1Žkµž?d–øV#kmX÷7-~ùÌGbn ﯊MFžŽšÈ{{„\…°¦vÍ\D«mœ«w({n>Ëyp]®& §RˆbÊ×i»Ó=ŠI¨,æIû„’M™½!Îè¦&æÆô»Þ9‘³vø¿Ébä€wϸlPåˆÈçLç†éyv–CLƒ¼y-vû>^í‹}µŒÝ;—0lì¯Ù/æÛ ’Rö<1¢ Òu0 ºG¸Ï´%àŽ'Ãf$³±¥–¸‰Ë%•“Ö˜qЬkÍFæ¾®;V)âmò—<œ¤LU»àU!ÐI]ãºI@:gÔ @ÊÞóuå÷%ÖÕåö*ÚòïØÅíÍÍÁ†Ú)žÒï»Ç¡’>WŠç6Ž®Xë]—·ñØ[}Á¼/æ¶·¾/6°A’y"i§|ýNc#i¨-‹¨=!n¡ÁQ.¼•aÁbLµmÞX²ý²&²Y²t“% ÏaÙÖš¨%y+~Û>–íäL¥¼«¶é1P©»UÊZ"‰Å>©ç!ÅíËëí׊¸³Üö7±ÙýÍŽ}æâpM¸µ›KZöJçBXÖ;ƒˆhw8å ¿ÍZZíü„8+»WÜýåÍ,0Cc(y4 , ¸—4}­Mn¹6mŽ;7·®s„ɽѱҴBøåcƒÙF¢Ð+S¨PÑGÉ?ü%AÞq¸š‰k®bþ~þ*ÕÓbc¸ù¼Y;4 HÝ™%¹BNu“'.Šš®›>ºˆ$%9K®·~óZ÷&ê°Û–°àcò6 ›·Gzø£©.Ð!ÑœHcÍGki9“´y}k’fß¼ÍÏ&Yïk °[µö­{éA«½Ôö´ ›Àÿ£BÑ85}ugŒÙ‚o;ê2Ì’ÃÖ%Ýw¸º Ðîm÷¿g¤-¦ì\?QuZ9‹€¹ñWŠ*Ýÿ¹k¹¹9Ã/cawÆÆKË|½ôui•½ë&. 8>V¾YP×8ý [ Ëio÷^Ojä®Ùm>6ÒYŒ´¬nîÝiq$ÆæÈ]BZÙ%}Iðá…o¬”æpng¹okÏ Z®/‹¢6ä°¾ÊÀ]V¤P˜'æm–w&ÍÔˆ+7É‚ÊJA!DÂbñžbo<&g½°öÖXlÍж…ðÝwòÁ;ÿÙGp45Ž/>)1 Ôê4¡±²öÆWsµ²SÜäñ–æy[$ÔrÄÏö„ë.£5‚µ¥€q¤(µrçy"ã±còS©„1­¥fZhÜ×Läd „™ÊÝRC!'Â.«‰&cv®ˆ`Q3h ÞËoÍɺ®¶žÀÇ[ß\c[¼žâs ¾P\È¡sä-¸FZá^ަ?há-0û‡x^Ík ëž-¢†!,¯lfŽ•ÚœÆµÄ:\ A¢Þr ¬`pÜç_ëå¥8u±¶¥²µ¤“sAËÛ‘Œ}!’ܵ9†xÞž è›3¶PJ¢©€(==³ÍY¯çÜqîËâ›·#ÓRa9=äs=Ô-kC‡æ‡u§Œí«Zïv3¼¾ŠÎ,+öíáÈÓålUˆÄ‡ÆÖÔ8öž=x0´Ð¹¼W+ÿ« /‚a'üJM/ ¨ZÎ&Zc£+‰™_\}–Vei¤f”I“zä{"6€¨bH¿â72eÂé܇á.뾺î—榮øF#1‚cüà‹Q}›7/Ä]çt^-ëhÙ맺// ˆd mx:ä "ãÆ7µÏîæ…eqÚRîá¥EAU¹—lxéšÆ"b»ÍÌESt½¢*ÚºW¯à3˜íË…¶Ïbœ_Ž»‰²0‘CCÒ8ÑÍ5k…Mê^m—Å^àò“â2 Ó{o!cÀâ*:Áëk…ÓN ‚¸™TÛ¯k-¤,}V{ð)w[2Ù†·•»²Åç×·0õýu,›(h[ñ3øñ–]' ¡ßÌ“ÑÁ ˜¢‰ŠMå T•ðŽxâr7ö˜‹Ãgq‘Ú¶y6BÖ]$‘ø®Ð263¯S¡Ô ¨Ð\ßYåNBÊÒç%l.a²Ü6F;;‰Hk!>3uCÿKˆê T×vÌ+~>¸l¸~_0/cµ™IÝòô[(X÷eºùƒ´žº—ô) ­H¶Å"¿¦8j‘ŠSTNrŸU½“üÆÇŒ{ NákÙÜHÛqes­sK[¦@xiîÚ÷_h#aµg76MáËe"¼Èá‹]ß1Ó¨%Í!Åú])hã«[šÅ$Wĸb'-þ¥d«Šámˆp¦?p”Å6£'—CƸ$VNÛ²í–;'óNJ€(c¦T‹º¢€"rþ£º÷•ÞÓþíÛxûwe÷ûK"Œ9°µÝÓšâgB(ÇP\jÖžÃ@ÛÛbßpýû7{3qÛḃHúK{Çî›â™x6¤Š 8ô€yeÀqµÏŒï£ÃÞHŸ½ZãQdã YW¥®µvÄÀH,£v÷LZ‘ò2QÓ1I¬‘ÅÁ ¸vÉNqïqXýý¸ñ›’Ïls”™-BÖâÞc4•€ ÃØÇÆòÐMCÜCZ:HÈ^m %þç=³¯fºŽÇI¸‚x„r²7¬Òç5ì¨:€¡h“Ð=_…Ì-ecÜ]’2Î{ql²ÉØý¥ÑjÅZ¥î‡NÛ‘ÁÙ¢F*?I­¼Äª¦S?p™{UOÙ”€%¬|ÏÞy­Á“Û›SÛ™±—î†IßpØá´Ð8ê .•Ô$DÂt´j$‚²¯Ø[c‡°Íî» ŠúÌJÈ™ |¥äVƒIp¶ wޤÐEÓÏ›^V¡4òú·ò•™hÞVÙ£SŒs6ÚìA»2MãÔP~‹òöb˜«¼P‚`.ðVå±÷ÈÜø{ûܼ,±Èbï'·ºYxŒÁÄ»QkIioé¥C€­³ºö™Àäí-qÒ:îÎþÚ­äÒ^%à§QÁÜ)^°M*»b_„èç[«Edfd·±u”ÖñÌ*b!Da¬´o)4“F,ݪ¬ÚÌÑ~‚h"URUuûB›³Ž%Õ-9¹#ö5®íºÇ<ä2—®·°³Ž@d¸%å‘—9Í0â×8µÍkt‘«SAØ.9pÆî˹ozß¹ØZ‰¯.^ x i:ËCšÚ‚çjN“AgÃæÊׂ|<勞ë¾ìˆ×BöUóe¥m«xÀÄn »Û9û)7Àg­ˆ¡L“ ƒ…·€=茒ówí‹Ë7smk‚½°‹‹kƒ0·–J÷m¸k˜ßЇHá´ë¨ #Ù»o=mr6vB{Œµ¬.”Ã<#4lûn…Ís¼aÒá¨×«‰_e‹Ã>0w„ì\픳_éí±rÎܯâR¶ÎN.æEÔ{–ËV ®âEg`Ðë9UDJ“4ÀÛûÁ\YÎeîx·¥öÆÛ_ï ´ÈÇ™„Q#÷:g8ÀÝA¬hqt‡¢”+“±°2m{MÙžÊ}ÎÂydc˜"2<–8µ¢ ÒK‰¡.% 0tÖ«'IÖreµ¾ùyHòÒ(BI9@Z¹ˆIâÉÆ¾rÔÅ)›.í‘H¡Ó!Œ! i^½bë¹la’ýŠýÑ0ÈÆA’‚ö‡u†º °*¼Þí¶ÑÝÊË7¹ö‘ÁŽ"…̆¸Ž¢[BGQà¶â©¶»«‚«1øJl¢9Sˆ™D’3,d:qmzBbtdÛØŽ-‹¨¦>ñb »•×8€Q1>È`ñîlHü·÷_/m‰ï³w­PжÊÚ“\º½D†µ££U\Úž úW.ØÜqÈo9À1b­IŠ£ºž±@>šç4é[¯¨—"Ú8o‰¦"Šd›e;;#=ÍæùFÁH°Ï¼)4ìrC´MväL(·›MâëÕå{ÎÝËf9i9!¸Û“qiZñ²º=ãZÞÞæG¼ôj}A\ûùƒ5Æo¨…]}†ç躷]ÙÞ°4témOH]“0ÎÙ’á‹7”«È;iÕßšÓ“’aY·H/é6!"Ìá©]‘˦‘ÀNR(&åÓA×,æÉÛs3}O‡‰“ä›gŽÐÇ?»i?uejú;MWH…j³—1XO±6”Y9‹®oµ9¬ÖGûéâÔV® Ã1ÌwávëÛÓÀuà B(-cd¸<9¦Ži.uÚ<†ñ.ªêȰVN”°pÆožŸÉíXH9€gvØå¶­\„ê)¢¯GÛrE—vö%Â[(¢^š˜Ê^þèåÚo÷þùÛ6±ç·ž }°ùÙ]Ï}=£^àÖ¾fwml€8€îìð'¶8 M›´³×ÄmŒ¬ÓgšÇÄÐwQ\âØ¬¹†€‘¬q§eHÛq_ –Ù‡¦³GÊdÆÖ®Pua\LßÛÎez3(‰S’£W!!s;–+b³wRI59„1³ºy‘—Åov~ÝÅœåÖ-·P¹²†6®–F~qÎ Yy“U\âÖW.¾ßØøÜ†Ú—ræòp¶·¿6ò5Ñ—:ñ:)sô†R€<š4…¼[|9bKžÇÉU,ØîX¹ ­¬Ê^^ÐtêJ~xÈÇ©¸cƒ†¯”¸^:ìh)¦EU! ažK˜»³œÆíga[q¹/±îÑÇpÖ²)ÞÒ!h‰­f§IRx†µ¥Ä.Í–ÉÛ—ø«íÀÜ£¡ÁÚ^ˆš÷ÂK¤ak\ Xwxâí-eá©ÎÃòn±£±D>nÄW¬åÛc¹¼W°'˜Ý0-àn+zåN3ã†à©>zÉã'qâSï³ L'0'™Û;×9qº¦Ù;ºÊ LÛlÅÔN‚S,RÂ_Ýš5®kšúŠš;€bó»[Þ‹um»©nq.¹6ò6XÄrG(n±].s\ÒÞ<:*:jiÉßáþ,3D@äŒí;!xHÅÇȈ0µ#n«JÒ^A P#ßOšt§]™NTY¤]À6šã ÞÆÏ ¯öÞ ðñÊæG÷Ùßó†kl]Õ"èox領]ù¶ÎÈÄ­3™iŸ“|msþë e†áö]'yùÂÞ“ }ªîž°%±ŽxÎaŒr«+ ÌIÊYml£)n_ÑòÖ<ìŠ%›É,ªP¦‰9œLGEÍ»2ÁºµiœÀß¹=ÇÉ™7>Þ‰ö¢IË“ßMjøîba–d×%PX{§ê ±m7gØa9žÌjF\1Ï€wAñÜ5ðHà^Hf–UÝüãt‚x9ut>>} ÅKìa•®¤,»*Ù‚‘’cñÄI^àöBDŽ fc“–PØC?IR íBŽöéuÒ¶{ÍÁsæÕƒsâ­]𽹕Œw{Þ›m,e%æ1WÈÒ ‡‹CÂ¥köØX%¶Üà27 ÅÚÁœÞï»ês«Û¯ƒXàtŸ½4 ©³!mãñ]ÅoÎ9¹í|«b²ºbd–+ÛLqo=mœ»œÁ,²:€!¾et†œ»fÎÝÒî;Œ®;!mr˜«çA#õ+Õ!´€âPoO®îm´Ì8ûÛ)]qÈZ6V8·I­$Š€š˜Éh'¬ž…Û’œ$¹m•c1[KѲàñ‹ ‘™.9˜ÿF†Æ-Å$fÙ¨VîÖVWâÆ‹ dͼoé$׳)T9u+^mG&Õ—uKdçE>Möxøc~©/N­¸U 3[ƒ6š‰h;Ç.ÍÃÞŽé¢H¬s{#ÛFZ:žÓBKô‚Ò8·V¡ö@$R/✅Á ‚rµÇsd+väÛ[^ï³ n7¾™EªI…¤õ¼“Å[¾"Z¨‹GIöÊ€€éJ¢„»­ý»¶Ä–÷›ïmm·®&lnžÞã¾6®wí,h-¯HÃ¥½ ìmé G¥"ªBG-›Ë‘E é9; y5QòždZg`æp>xuw‘‘S,tñšA#ÓÒà <`¦ìKŒ}Äc2d†T»û$õø*(OUGUVkHÆÈÛî“¶%ç+$@nv©¼rF6Фw"ä­âç á14A@[]wÒ †•æy»+æ ÎåÑV ð¨i„xÍ¡áÄ}kn½ÅÏm!Š'°tPôƒÐGQ¯Ð¶ÇÆU±»ŒLŠæHçHH¢ªÞNØ€:öb òVjôt/•þ©­ÄJÃô­˜ÆjìälOHjSHs&ºº@JÂsv…Ð4]à×@Ò÷isº¼+¦8tš…Ä%!¤Ñjç}Gj šŠŠIûS.rh`íìN˜ÉŽ‚!¯'‚³6—VÒHÑP$ T‚8£é¯RêÈÉ#ããið™sì9-!+f ¤³BF¹m3(Ù…ÒlœsS¦1äjˆ¥ì„‚n]Ð.ÊÔw,‹&ã ]£iÄ’H$ŸÁô®í±kâñxËÔ)OÆx.ÞMÙLCé¡Ä¿Û)¸c§ìÓÜÔ *x’µÇBC…xu ý&¾Ùèéÿx(I^ÇtÀ "øE1 ö€A|Dˆ`Ôû¾ÀÔhužº‚5Úð¯i?ç)‰h>Áü?÷-í“—àS¡¡Ûn½²¤M$„å8 j¨ªÇM4ÌTÇP.£ËÊ5Òš{~JÑ-iARiÖ'_à]¸m¯&«âˆèë&£ë4[ÜkB¬à)0YP"mdÑzä `)^>7f͸€j"'8ìïWNæg2>ùwQ‘þÒâ¬oþ«\~ ²Ö±Èá“5Òö £à/û#ð•Ü6ý¨ñ€œ‰Ã¶Pÿè‹ìËâî’jþ‰„ºî¢u÷Õ¦ä2ÐÈx<££PÓOQlc¤ý.'À¶;k e>ï飵Jÿ ¿ú£ÿ >µÄstls otÄôm%w4û(È[6ºzêX¾Š ‰S!—t©ö§7„5ËìÉnï³öóÞ=ò[Z“;µgM  ð.¦P[ÇlYnƳX é$ŸÆh¼QÈ­˜Â\jÆ»$ƒ[Q‡ZA!Éô¿¤.öqÂ"_xfä–vª(˜¼†A }gµÛ$ØßïšXû§™OKYÁ±ƒØK@q®+Å7<ÍvKîÌ5l ¨ëwK¿§€Á@ûkb-Zõ~´ q¥DêÏ¥/ uJë¥AÔŠ¤óPÔ–§T€~%Ij`¬»à‡;Û¼?ñn]×»uãÉø©Ü‘nš«.Ÿy1çÏŠÝ휧ð»U"ê*Š"e•åçÙ ÷°î1Xgçà–;«RHÏnímmO^ÝL$ç㤿òÓtZm=ÙC&ÒìD±¾ ŠTžêfés¨8'KÈHiT…Ú7³ˆ´¢|)m¡ñdûµÇÙBømy)è c–˜TòíKnË ÝbâN$’\§Ü9Ó.ýkxæ`ÿwiÞWÂnhÕÌS2X¥ÇŽíÝë Ææjqnš´8Ñfò<žÝß|®Ú„e0rº°\Á$ncØOŠ^uŽíÀ@ZW&âRÔáã…«Sƒ¨+ÂÞ½²tþIW2g¹K>E »jÖ’B8s¶žlc5•}‚ 8~Tµ+gÄ éXÝ…m“ßÜͺæåõ¥Å–Ûƒ,1Œ†9¦aË-ÙˆøÌkÉsb'‹ãxáV®îížÃhìx9ykq Îj[Ͻß:'ǃ4Gn89Í9ôû/oOŒ²‡Î¸…ÎA[×V'±>Û@IcleæF*~ÜL¶ä³H2Í®´K3un¦-WMÉr™¨Ý@10Ê_5äW6vËØw½Ó}÷;øò7’†>)zÇIÀÀZÇ6S¨°—‚ Gwnkr÷wnmÙö×ï6³¶asdóo â%p1ð!ÁÎ¥¦ ž w?XÕ·׎‡¼ñë·L¸2µ8a´òÖ”tÆ/¸3 €2sMØNKz.BÚ”“ž]‚Ç\ šÎ)ÅDÌmFï—ûŠNYZoK»;öDýá>b{X 㼊ÂëDeÑèñÙ3ehmKY&²F—°Ûîü37ÍÆÙ·¹´sÛ·"ÆÅq(kí¤»ƒSÃ_«ÅtnsÜÂMs4€j ãv;®6ñÌ•ÏåK†Žm u 9"ï-¾Âø´8~V.µ·,tí©–R÷$µÒ‰ÔA²[qrS9Ô"JdsQògpÛÛ`¶ÅöãÜùl„ѱ¶-È^Ð7P.–äÍ™! 9ÆFÕ¤P5®{zxÇó/4ùl害î7FÎÚ¥ÚHÃݽ®‘òе¡†Ž*I 8mq¼Qç²¢Üz©S*®øé~áR¢B¤‰T_] œL¾õ4ÀÆ÷¥@JõÜ|Bæ~âWKvK@¯A}âzÏÒ¼êòC'"¡‘Ôvèqú8ÚJ~ Žù?ÿåÆ þ¨/pÿå™ú¼ ÿþ˜ÍWü5oúh”åüÆ~Û›ôr/9N௡hBñÐW(³][MîÛYÅèÑôœ…ǵٿ¢Ê>¶R“jyæqÎGÿf~æ,ª‘?Ø(`c2ñddÅ]G‡{#˺ÞAž51³ž:Ú¤¸u€BîãŸdÌ„É5ÏÇ ˜ekMèÆ°ÓÔâÚ€zŠôG%ð3–˜ßÇ¿¸3BO*ákt$±Å÷ޝçSè¹nŠ® .¥+=/ èÆIEI 1»âEAT“ùÿns¯jÍ‚.oº<^ñ¥—v×p=±ÈA KX褎FÑÀ4šÐis½{5Ë üYc•åÈ}þÛ”‡[Ïo3KØcÈsdcØj p)R©£½óVaý![€hÜýq±¿ø†Á÷ó‹»1ÈGʰ».[FÄ5Ýú"ѹ®Ç.‘šºÑƒD«#¬ªÄQ®ùÌ à«8Ò6vÒø­›êãb[¾Ã`æ¬ {3Ü÷l“ÃÃLp ipkZCèîË#Ú7&âø}ÛR×3n÷v2ìËvæ¹²Éë\Ȥ‘¤‡Ê€$[R|pçõîcàw4ež%îÌ…`%qàü¹~Jå¬àÂç·ÆË‡³.é…îYI)%¤“Z9kQk¤fê& œ[fCï]ƒhó«gín\Zà3¦K}銱e›ñΆ_¼Iqb1¬ !ârÖ»P:F³¨Šb7,w&z\eñ!“mŒ…Óî[zÙcîY ¯29Îqp-1á¤GOjG5Ê–M{A-\i1!)–0ö'äY±igl˜(ØHBI8XŒ]+0ý58Ã"‚Ú•2œÅóÉ6ÆW—œ·ØYMDZÛb³¢êúŒskÄ•¦F¨Ú@—…[!ÑBâÐwgqûËzîÛ,‘¾{üI‚Ö®NøXÖǤ—¸9ƒW SßùO `N7$²´C+.VàáÒy´E™'1¥ê¼{A~w«yƒ—nã ='Fé.ë± kÙå)ŒO0¹¶7žúÙ–Û^gÞZÁ¸"2\27‹pçi¤BWµòÓÆsY«Ki¨‚@XŸ³ó»gjni³Ñ¶Úypï …Ïi˜´j¬†6’[|PçSQû €Jé)O§žÎ±ïkÄG’ö³ktå“kÎ>`ÿ÷ø¯Õî±¾¿é¶Ïÿ…v6VÆ·X#…ËÛÆ…ý-ˆq >Éö TŒbwU£-g‹vq“ÊÁÌ ã\™‘1û,—ž¸~½-IX)æñS®!¾&^Fº²mœ&rvôÂWcÖ+Ö‡Ò(Š)˜TIÁ6™9{Îmm&î=¹¿~ÜÁç­çd±Ç=ý´mx¸šÑš,f-m1È*ãã¸ite£+²qÖܼÜ' š¼´nk+ˆš'Fð×Åi3ËL1Ü;S£x“Kµ°Ð}–Mx'´¬bq£eÜ’÷VJ°øjá¦Ì°˜LIÉæ§øƒú+C"ÁÒlÚÙç·¥JÜoî-þÁ2T;DÕ1u2†"*ë9·rs1Ž‹·/·ãÌ_IŽmýæ§UÍ.uÇzÇ2&ÅöœdƒCžÜæ-¼ÉÆÞÉ™´Âáq¶Œ{xëKj 4ÐCݸ:GIöZx‚GC]áì̺ósÓ.E39–“&àQ@SߺUÒ¢›T΢mÓ€#¥}©ihË;H¬ã¯wm`©ÔhÖ†Š¸Ð“AÓA^•ó Åînd¹}5È÷8ÐPUēë§£©|%SnÞ*ç-\U^¬áLI‘³_³ví´1}®êî¹RâôÓ'Šfî5šÅŒeŠí$;í¥^°l$EW©@'þ@×O—7–ëÛÛ3ùˆ´Ën[–ÚcŽÓîÃÜ׸kuìä6Œk×uS‡J÷µ·ó;›“7츽‡^Z–ÚÄ «‹GG]x¬t‘àŒxçòÒXNq´t['R/ÜžrÎ9[²d‚Ž].b¥qS1„ Q0€rz¿=ùKwq­¾f\Jö± Gp*ç8ÅN$Ä€´é¹OÌ;x_q62VÃKœuÃÀ4TžW€ !8L|—Õ^1/äd•‘¿œ†<øÝâÖ½á†Mƒ«Þð•*{À0Q,X˜Œ;tÌ‘ž1@j¡´jÂîon1Ê,Œ[Ø7ïW÷eâÚMmµ»+ÿÅ{œ ºHpSA:ehÛ¶£—8SÌ\°yšìýÞÎÜ8´ÎÍM3ÌêQm#Ô(_BGÉì‹*Ñ០#.HÝO%8zâJï’±2Ô“¥–Y‚y =c¸Bå“zs¬Œåµ? ‚2›|Ü•Ä šîfï-ÌŽNÞíK{VE¿öìÐ2æÅ8Ú¸ac@9¢cX(\Ó*4fq¶Øý“Ì›]Á5äÚ¨¦tn$–‹†š‰î!ñÈæ¶G8Ô5ÚÝC¨ vŒözfö·t³\†hlsŠ-öÒòÓ9ÊRNFÄ%ºÁ³…㦢ým's˜ˆ•Ɉ9'n© ¸pA¹çöË—¸6CtÜ:6Gc$eÏzâã~¨Ëcî¼bçŸéñI¨Zt< Üñä$fcº²ÀB×½÷ÎsvÐK^Ú>¯×À5£Æ¼`(Vó~Š û7ðù[.w ‰Ä½îFº€ž–;~ÑnÀÊÂMóîˆé¨é­tðZÝüÄeÌ€6C¶íª¨½Š¢´§Eh+Ó@»m#“8á.g÷Üô4¥GvúTÒ½•ú×0zÒÖ”àÃèÛåú‘vT—7£ ÂM%c­gw{†÷ôÖœQœJЍÐwDºéX˜fÊ[s‹zÜá#æcÛöî·a¶àÄÒ:ä }+#,vò×kÔyüÄ͙աlFb$p=D2¦«-硸²²ók[{ Øx§ðËq@üQxÄÛX‹ìœ¶?+¶B[‚fõ¹ÍÍHÏK4Pæ1QP(áOxC{CyMç*³;-Ù ã}”Ës*Ky{ËwÍßÇu¥ßšŽÞG"Ô¸wAƒÆ x£Ðní¹ŒÜí³ÛV–íÉ™¢fÇiÝ> ·óš@÷ºGŠžYqà ñŽÈ‘¿íÓí nrXÿòî'®ã‡üØÿö›?Òß.«OüÓÞ°.Gh°ïƒëmq¥Ë®œåÁñ0J½w™-›ÿجWœr°ÿ¹noønïýP»ýÆ7ŸÜ:pµp`Ø¢_¸ºÏ‘ÅYψ}œí­,Ñò‡”}ñÓc„|ûVÊ..w LDuîkø-ˇå0·=†ö”ÙZäîÙ{i9Ãx®Ôk'”&.{Æ>Àqh´rU®. Åâ'”d™Ñlt¸¤¹È¹LMÎоgÌ­ïÊmñµn1øÎç1º. s,£†ÞGÝ ÜÚDà{±$aŽ!Ï-ÔÐXAÕ¤ï;ksjno/ûÜnÞPë§Ë3na²4e.h!¥¡ÔqR£Ÿa<¯{EñaðŒn< ºéÌ.²Ž³r,›zø^PÌÞ@DÄܽ”C)ƱMHå›S ˜¸&šj<ôÚ·Ø[«¸÷¤™î›\Cl²’J%¶”3Se’Hk#¢sÜY#ÅAÑ©Õsš—ÚùûLœƒ µÙgýãq’7VpÜ1†9ã.¡Œ’ŒkÃsš¨(Ö¸¾éšâRÇÂYn{-ÂaLq[/lHÛq®/²â¯Œ¤7KFÉÂÁ¡oI7‘dÞ5»€pwŠ‘DÑíHCf1{».\f÷®&ÇiÍšÏ\Ûܶåó:öáöÖ]Ñd’XXâò4ÚAwØ$jðßÜïl^×ÈÝî(±xˆ&Ð66ÚÂÉî»ÀZæ0Fàæ†ƒ¨¼‚Úé$tWÓðT<ü<Æþ™o£ù£yÿÄþ‡-S˜Çÿ mØíþ²…);#a«.øÈ/ü ]Mê«UE1u9`LAIÝV»ÖP†Qgì²,"dhA•4QÉï•(ŸóNÛ7·w…îÃÜo‹X-Ã…tÇu¬‚g8ºÒBd< s‹’· >/5¶­r¹—ûjO,Ô4«íߥ‰ õ¹· ƒˆºGÖ\f“Ì_ê,.fËîö÷,t%ýÅ·ŠŸ\z C®’Jàö‹>,-û¡Ìµçdðû„íM’rYÞ4Ç Ý&‹™‹ËyÜKæÏæU—8‘4JÔåSE½öé½àæòÓr«!‹m¦÷pf²×e¬f=·—}ãÉpÔÙ[#KcŠ—Šx¼*Õzh´©î_yÊ[Û¹såÜÎy iºÝŽ$6§HãÑSN…³Úÿ°Wú|µ“þ"‡®æ\ÏÌHáŸô².®7þäkÅú6/ªP7³æl¨t›‹&ep¢eßQ4@§L‚:åLD@<#\Wáãù€ƒ»Éð›¨A?{–•=•\–š&åï ñ©4û´u§ÓE•9ÞÏ6TôTO Ön<·pOÙÛ}ÜUk Œ¥žŽZ)¢Ów ùz^M¤Îš¤Á`PÊ5 ‹tÄ¥0ˆ|³Ø™« nù¯y‘¸ß_x•²ØºKÖžáV¶ö倂Í4÷E ^˜²ÝØ«¸íùwmeÒî#,» µx‘¥€É%Äóô:µ¨PõpÉ6aí6ÅN$äY³²ÛɤÕãù\cvÇ1âM=däž&š%(ñÕ)@9@+§¶’åŸ+´o¨¼s´ñ.kY{Ý^“â1¤¸ž€ +³yß.=iÕ ž•B@8R-N§Â<õ%©Ô+ÃÃS¥:¯^ø4OzÖ;í¢<íӯ̽ûûóšý­yúÄ‹ï]û£Šýmú,ðìvŒkS[ŽÀñ_…+ÄŠn%C½¦ÌâÈ·Wîg)þíø{úœ+òÓ˜_¿ÙÊ{âóõ™Aë^E¨T…`0…¨=*à~à¤;ÀÀ4"§­X !Þ(Ÿ¥p?=NžÄÒ­•:@å$×H‹¶rTÕ.ò`»7);js—A&G(N_öiï¼a¬fZÉ×Ö/¼%¥Z~‘þ~#ëY<>Cûºý—ÿeZv½¸{²¶¹´uµÄdøÂŽd”á¨8P‡MAÀÚ½§¹ ³A3dà°á^#‡FžÂg3Gâá2psr°ÉâÆŽ•…”Û÷ 2‘©‰œöb %ñ€4¬t–°ÎíE¿œm%ŽÿÚiñ” ‰#ûTw„>°j"JJP¢vë@Y%)SQWŒ$ Ü J&ûhùˆ ª˜5¤(&”¾é0£›wrÃZ!k‡¥Í¯¥qºâÕü%¶ŒŸôjßè4üK‹O½HƼÇì^·tA"Åe~ÜN@0  ñ#n”GT'(rdíáÊ襵è«Oõ¡ßåë\“ýx_à#ü…r¸'%dÕ˜îA»t Îo"¡HEJnª:Žð€ ®¼µÕ¹ŠÿYuÎF>ôŠP[šWüŠ»ûÍ[’ߦCÇësF®]ÃØXP §¡Dª->õa0‘C¦}¼…ÝÔ@L‡–(ÇûLÁ=‚&Ž‘Û_誦]BÑHì¢I{ŠÞûp³–¤hþÛ‚D¥T“8dÞ&/)^¼2¢U chœµÒ‘¸ØçÌË«‡pûRÔÿám8.Ôwwã„FGú,ñš­í½°ÑáÁ[Žz^qN]QUë‚¶ÔâQM‚GM±SÓ“Mšº’e¦„hÅÛÁnÎÐÖêáÚóWWëRèß3ëu#äãÖISzÔ»’ÒbÙªiÇ1'Úvi‰)L¢€A(ï)ºDÌaè<£ ~´¬ÅÍIJ—\ÉWR¦§ x8žµ²aÃc5kG`<;?Ëô.Ûe¶âe„L_ìôÝ( sŽš€Duæ­N[¦j$ž+`û¼’4 VBâ:z>’z8u¬Eâû Ââë=7ʼE{¶u³ÈË&8§Ij“¤Á;†ër™4›52mª%ÿvqÉïLcÔù_ˆ½Ü9?¹BÇ7LJ\?¨éã5ë5¬Žh?Õmx€«ºnáÂØÙÈ3DMí'†¡×N zÅHà¼7:çYE9„Ê*s(sˆ‰ŽqG^QÔF¾Ïclc@}|èù#Ì’q{‰$ý'ŠÔÏËOObš«ù‡¨i§T€~z)Õ ˜jKSªPSž• uH mÒ—…4€~१±:­É¬´‹4¶g"õ«g¤Þ7nítv˜éŠnRMBr jº40‡†ºòÚÛÌöÉ4ltŒ5i-´ôÔ8€xv.V\M\ÈÞæ±Ãˆ€|4à~µóùêËTUe÷|GÃñ˜G"Ù,n[b%l{gÙnãæjÝó£Ûñ~€ÿ·,Kçm–v~RÇ1Ê(w«ÉùKËÛ½´þÌ¾Þæè_Ïp×FZÞõú›Mmihé p=oüÂÞû»pÿ{ã[<Ha-yÇ»n—WCˆ-=@ŸX” WªñZ ~µ¸-&ýÚ-[º|íÓv$2lpåe‘f™€€b5MC˜È`H  PÐæ áe½¼Ot‘1¬‘æ® \{IIéí\¯šYÖHç´PIÁÙÑÔ€ê÷+µER‚}ªªÛPZR‚œô¨z“ªÜ˜ËHÇ †zÄ˳XYº]°¬Ÿ³PQ:b¡5ð¡]y­­î±àM¡í‹–9憦'9•hH¨ì4_8)ÕÑ\ºj¢«ïNIé*À•ŠêeÙ‘Â¥j²¤ÝÜUVÅ8"¢…Ü % š¸m ”Næ7¿h u ;éjäÈbpˆš‘SB{HèFšÆLå:g2jÅ9S LC”u)Š`˜¢€÷ÀjœÀàZáV”ƒˆ5#ð¯©Ã×/;—ŽváQUÕT]uD QULcœ@¥åðWp²áhlc 8*|‘Åò8¹ç¤“R~µR©·ÇUNÔª¾öR/#Ö :bà bìÜ*Ù`!ƒCDäP ok × ÖðÜ3»|}ŽÀx.Hæ–k‰ÎkûA þ$}©Œ"cxÆ1Œ#©„G”DDyDDj´(85©©é_z’oœ Ý«‡®ÖlÐ [,áelÓx¢s™4@Ú» é\ ¶†7ºXØÑ#þÑï OÖ¹]4¯cc{œæ7 h<«êB Ué§BŠ¥6øûµ©§juL t‡”)Rªª”ëè©-@)J¦Ú‚ÕUJ TЧU÷šIê­b£ÇJ1ns(Ý™Ü*f¨(q9Žt[˜âŠG9”0ˆ@DL<ã\"[)œ1¢w 5Ã=' uõÊfÆ"sÝ€I ðŽ´ESn5zAQT §pT–¦ ûÍ ñVÈ2QÛ•¶1ÌÝ¡×Tí›™Cê aI#(c˜J¨ˆë\Þ&ÈéšÆ‰]ÒàM:*zM>•Êe‘̹ÎîÛÐ+P+ÓAÐ>¤ESn•T*j˜ëè©N«1±þLá†W[vNb±²E¥uZN'K%àp´ž¾ ç¦ìÑ>é^9 ÅveIªä\û©¡¸* ¾GžÛ|˵ܗ9­¡}Ž»Åݶ2lòx1[IK{ËWBXRç´´UÄšý>‹‰ÍlkŒ$8½Çk{on^Ír;$5ÑpÙKC´Òpq൫qž-ü®\oeãëfJÑÄønØqkXQS¯Ñ‘¹übá“—Æá™Iœ¼ã–¨™T›’ §¨ÛÚ¿Ë͵ŽG3Ÿ¹Žïuf.D×O‰¥·@-Šƒ¼sAÎ s¨ã^N==纬óâˈöûŠHà騂ù$#Åy¡¼:Mxc™$ž‘¢ŒñÉXª ,«2¸T­X74UFà~Äê&_|%×Þ‡0W¡:Þ(œ±½ø Ô`=4âxW­i¢if 物4'¶ATÛã«¡QT §WE*& b©Ð>íIju_z²œ ƒW®Ù°6l»••A¸w@Hç2i4÷ •×m¬½ÒÆÆ6Gt'ÂGõ®gO3Ø#{œæ7 h< }HJ²Õ_s™ÕŸGÈKžzI5?„ª‚ŸÖËRªPSnµ¢*¾Åºpš¸tådš”HÙ%—UT›Û b C˜J‰L. Päjâd1Fç=Œh{\@ŸoIéí\®–G´5î%­è’ƒ³êT:êèU 9é§T ¥AjuHÛ§wФµURœþJšŠ¥*œÃÕKÂRè¥zª@?0÷tT–§^Ô€~z‚ÔÁìHæÔêÏä©¥:HSó êJ€ô"«Ù. ÓÞ´£‹1Ôv¶K½_˜Ûû†úÍ~Ö¼ýbE÷ÆÎýÑÅ~Ͷý zöA³ÅZVÇÅNÈ6x¨ª8¯Áç§(]ßn4ì•!• &Fè'|¢á}Ó€9ÒoÈ#Èÿeh¹)5´†š—;ñŒÿBØñO0ÈñâøúzÑ—³‘…ì—÷•âè ˆv¬á Z¨CK\Ó—jœ[‡A9D¦.§û“tµ9Ä“mmŒ®çʳ‹i×À¾B˜™Zj?I?e¿iÇ£…HÌÞä­m,ß!¶ÂºYZ8šŸìŽ©Àt4_Ì·–®ÌÍ{J^÷k;ÇÆ*,c[¨¡£`â1ý"13èlÑ5Sî–PÆPÚ ·K÷–ÏÚvG2É´-s¿¬ç´ç·8ñ>…óVéÜsî,ƒ®OpŠ?îêphêI+­@áÑ[QjÖkØ54N½©Nz\Sð$)ù‡ª—U œI¼m›Êøêí¼&˜[ÖäO¦ÇÇ|c1&¹1iéÒÎØF´í×P Ú.²I]L`ZÄæòøÝ»‰¹Îæ$îqvºY_¥ïÑ\í,kžêÐÖ¸ž W½Ìä!Åc™Þ_ÜHØãmZÝOq£F§´Tõ¸€:ÊܲF:¾1 ïpcŒ“n¼µo[YÙXÎA½Q¢ê´YVè»nt°pî=û7lÜ&²¬³uÑPª&sÀ#Á··uá Ü;zá—X{–jŽF‡à i«\æ¹®®kÚ×5ÀµÀBæÌaò{'.1 É@í/c¨H$(ZK\ µÍ%®H ­âàÄYÔÆØó/O[ÞŽò«‹¥…püoëãçlª°—"³“s9ñl¢&KW­›m7’“CWVÃvmì¦á¿Ú–7óø¶Â똴HÞè\0I Öæß­„;óo~ž‡i<=ÞßËØa­3÷pèÄ_kaÖaqdž q{t¸SÇkkÒÚŽ+®ýÁ[•‡ªû™¶xý^Á‹W/—Ü:‚‹Tp°&˜j¢š$9÷¢:h\I ×;šÆV•qTô žW$qÉ+´ÆÒçtÐM>¥Ø¶î#È·V7ÈYvÞôì{ŠÜ[-/Û‡ãx&¿¸¼eS„¶Óø©ä›iÉOŒdÖ*Z²là¨ë¼¨ššµì†êÛø½Ãaµ/®4gòm™ÖÑwrô[°É)ÖÖÙ¡€ŸÎ=…Ý Ôx,½ž1}†»ÏÚůbcÉ©ƒA™Ú#ñKƒÝ©Ä®§K¨8®¹6ÖÃ¥aêê¥áN©NºTª@Sn5%ªª”Ü%©ÕvÎ"Âyc;Ü*ÚØ’Ș½f7’­c¢ˆ˜¤y9;*å„5Q)UxåÌpÝä­Wuï-­²,Ou^Ãghçin­N|ŽþÌq°:I\ØØâ(³Ø µžÝ7fÇk%ÍÀvš°v½î-cÒ÷4ÁwBà‰BÃs1þH€û9/;kÃ^qLþ5„—ô«jà*戒íàd¥¡é…lìT9'»ïÈ]C\ÛÝ8 ßg-þÞŸï\Én÷h’=3ENñ”•ŒqÓQãZkÁÅeóx ¾Ý¹ŽÓ3sq, ™£[X䮇UŽp¡àHpëuè)ÏYú°õJU6ëÓJ©Õ()ÒP©ÓTê»/*bœƒ„oYw“íÿ³7ŒKxçRá+ 3èèJ±BE‚Ÿ[òRÑJöìœús uÐÀ×6ÆèÀï<4{ƒmO÷œD®{[&‰#©c‹4ÊÆ ât‘¶A œÞõ¡µ t:M d…†@Òc$Âz—j e[¸²ì cþoæ©ÙkHÕ½ÿ9fâ§‹l¿eèƒ-é°Ý„áÁÒA6¨Ÿ]ò˜S÷õ¬é¶FC)Š7?ïøh5ã{¹3âïší]Þ™+H‹Ü:à³£lgM†@Aþç“•ÑÛ;\œ{$îœÚkÔÊ?Ŭ€ô‚GÆo‹2èÆ×tõ‰zÆ|Mu[/9é±ò"ÉéMS£éÑ.ßG9Њw‘YBr÷ûõ“Âæ1›s '}‹¹f¸ß¥ìÔÒH®—µ¯oÐæƒô.†S}…ÈKŠÉÇÝ_Àý/n¦»Kºi©…Í?Q!oVV1¾òEó;gÁüm­µnëÑׯpÑÿÛȘåVC°”dâGtSìšuÇNBWK3¹px »+¼ýÕÖFàAnÝ;¼”ÒŒ«àΟ´òÖý+³ŒÁås÷WXè»È,¡2Ìu1º#.£œÒïô-è˜['šÝÅ×`[:Ûù¢vBÛÆ’[Áö–j*t¶Ëö^‹ñ·¦Ãöf;GéµHß唟¾®™Þ[hd2x¯¼ÿ¿á d׌îåüÌo‹¾kµhÓ%cñ©{‡AÜdmœá³°¿î?Ý2rº;gkódÛ›Mz™Gøµ4Hⶺ¼¬;ºâ±.˜7 .»MÂÍ®(”g.1Š·"J.*½…s!ª)ro*šÇH7ƒßWžÄg16ùÌdí“tÐbyX51àš ðè]<Ž#%ŠÈMŠ¿‰Ì¿·q0ý$Rµs ›AQÄ>•ÄNò…e¨>©AN¾ŠE¨)TÛã¨-UT ¥F”ê˜è Ò¡N©J¦Ý:{Ô¨ªPS¸*KS)TÛ­AjuJU:ªtªªR©×Ñß©N©Š®ß*ê”ê©-N©J§]AjuHU6éîT–§TÀ§?Œ*S±)TÛã¥@RU%©Õ()×RZR•Mº{•ªª”çåè¥B€R‚›z‡Ü¥@R‚•:UU )¶¤µ:¤:º* SªPS jiDê‚›téîÒ—…:¥)P"©üÃRZª©üõ%©‚”§æ¡¨-N©NR¡M ˜u¥Ã­J¥§±:¤ó IjuíHç©ÒRù‡¨jKSªö§‚’kgDc¸v$où<%bæ¯c@ ž²À:½`ïìšð^‡ƒÝÕ‰¶“­l‡¤v‘OíqÚkwO;×hš𤹠›¨ÙTõU3h ‚ÉåSAÐÉŸt€~M5 Ö!Æ_ž-ï¼Axx´ÉG6±qŒñ`ŽÐGá[#Û¾×–J¹\¤IdÊ£èõ‘?¢©Ê%MRoêˆ8ßÝy`0w´×?n'ŒªH¨¯ÀV:HK N’?Ê8JÞ-X%'n,xÙ‹’*œe®” H•DÔí&lALtÜ´ÿ wDj/¯73áû–:ÊÞJ´ñ‘Í¥< õ.{hqÅÚîe{hGÙþú}k'¡x¤ÆNx[^'$M'Ô}t©»ù2 ƒ6.•f`ÈÐÚ9 Љ€¤ÓQ8€V¥6ÖÎÆ6AöM–Ytµ  ¸‡×‡ p4ú|Íe+¤6½èdm©ï MOÑ¥eÊVÖBq7Òeš1’ŠE¸k,À[8,’(r²¾»WmÄŠDå0€è;£È:†âÁßcå6·Z ËkPê‚Úñ­ý¾š.Í´Í{u R½Bœ~µ‘ñ×)IÙ© •8‚d0©¼'ÝÔJ‚]©ÌpOÃÈ=þýh÷‚jâê0qLæo-µöåõ$|8» $±¥ÝÛg¸7-ñä âèZ[BkMZÞõ¾ –†ñ˜¬^?=™µ«%ü±šœ·E„ø¬'¢GPA.qÈ® 0̓Ã?´=àÛ€×U×pÚ64áì+™“è¸Ö²¦,bÝ“(\ñ¢ÕÁÞO¿·®´›ªÝDQAÊ ˜É‰NB@æþðÎóØ=éc÷[[ »Øþó š÷»ïÜ÷˜_¨ÄÙb˜¸<9Îc˜ªÒNÝ˹ŠÙœØÊ훳<÷vöÏî$k[ܾõâFÐÕîŽHÃKHÁäŠAâtÊБñ 40öY± ï_šöu•¾õçžæÜy¶‰ŽÞ6¶V ŒØ5±ïžV´ð9í:^<`׸p£W¶nK™¶Ï*ðx\[ŒC3ßÜݹ¼ ºÖňâXÖ‘VôÐxÔ¬`á0ÝXgˆþ+µ²: =S1#Œîå„Y8;…®D_¯.ò¥™¦bå_‘ÑãRl-Ôj’‰•S(%0‘röÛ{æv}æëæ0XÍ0È ‘:×ýÙ°Uç»{ Lçê!Å¡ Šz.ñŸkžOmþâ Àç±mYtH.?>eñ¶¹ÚŒaºKAÄЮkÄf#¸¿Ã6;éáµ-n±Í÷î·j[v=¯4¼¼Š ‡Þªåg.µKP1H£‚œÅ1J%?/·Øåï)³¨ ûÖZmÛwmkt‰®ftb6Ôyè$0´MFGxmOŒy…ŽÆK/qo[Ïq-+ÝÃ^^à:É%­4.‚CcŒYÁo÷T¦ÂÑyŸäçQ ¼Kx_·U¿r@d)kz)äÇÄפ(v#k++ª‰(És!)„ÂsÖÞ7çç-qqo=ã.%¶Û,M¾‚Úa–Õ’½±÷–ò:GwÁsA4T@LŒÕpø.[ï{÷í·JË6èä6²Ï,rGpøÚ_¢f7º.kI†ƒj@c¸0À˜žÈÁRÜHq8…òú!ÎA{Œ1Æ*²_Ç@L]·4+w ÜR7Âý¤ÃÛq*´]±…»I@Á¨ï&U3Û—|îœÖ÷‹—œ¶u“.Û`Û˻ۆ¾Xà†BLŠ&¹äÏkƧiÐáØâÜNjàq›^Mã½EÓ­ÍÙ¶·µ…Ícå‘€™$ŽÑsN‘«SOh²Ö÷/Íx áÈoX{j÷Kåàmû9 cƒH–âwЈÜ XÖ´‡<ÒºOŠAw[‚ÅáŸ0Y‘²|=žîÇy}[öÖ²R—ýÑu'yµ¼$P…Š˜²nñQoEãGiä“t©Æ&€@:Ö¾cí,Ä–ÛøZd6˜±šàäma|ÜÀÃ#㸈½íÒæ5ÝÛ˜j\5¯‹ÏwŠÙ[‡ÉöÞ,÷ »Šg<­”L&pc_ 5kˆÖפtqíkãð+ƒò)°CG5^W,2ñðy3Û7 -«rhe’I¡i!½õÀ‘š$”6¬ÐÐÚê-©¦{)‡ånÙÌ|'˜+›ØËYqy‘±‘H@.î¡,v¦GZ;Q.àêp[õ‘ÀÝ œ8£ÅY¦ë¸S Ü9NÞ¾ífèW0h!)t9<tÛA¾1ÜG"ºfQÒ'D‹é¡Ç£šçfn÷emѳ­mÝ‘Ìæ"²–Úbh$%ì’Ëâ÷dÈÐ+š@cƒË:—gÊü]¶çÎ`w-ÄͲÆcdºŽx€âÀæJYÇ]â]p«šZÖ¾kC ðm™ñRɶ™³^*áæJÒ{|«7#oßsõ™u-&Ê58¦-cá£-ëÒZFD9ãXB™nÙ3 ‘åËooìýÛŒÛyOîl¥ÆàŽvÛÙ-´v·†9åîs¤|¶ñ²@ãÀM 3C…ý·ËÉ·¯³vÞváß§/ts¾xe.kt´5Žg¹…£‰„ÕÚšjÞ¼É8—Ýü1/Äv ˆ¿,ulì¢Ó^vmïqÇÝhÈ5’†FN2牗g¢.̳´RY¸“³ã‰J@H¦_?·wVøÄó)¼¼ÞÒØÞ¶óëË{‹had…†HÜ÷‚Ú5ů­x6¤ê!˜|ÖßÚÙw–ÖŽêÔÛ_ i¡žFÊÀæÊdž´ƒR›Jq4H.í,µ‰x3áѦq{Cfl…rdì/`dö”5Ñ oD@–áM÷Æ—®aVzùY¨‰¤R VJwí’ë;Wusƒ˜2憛Çcs7V­žHd–I{¢ÝwB@Ö†´‡K1$¸ÈÑcC«œÏíþ[ìèñ¯ÉÇ’¼¼¾ÆÁ;¢d¬‘÷Ú¤ï %ÄÇn‡¼êm8%ÿÃ.°³¶2e=–%­Î²Ö?‹Ë–Ýû#é·r¤›NS´×kå˜Ýæ|Ý6Ý¿¢ú: ¹"ª&cèŽsÌåØù)¬qQ\s~û­Xý0Øæƒ8sÞÜi%úuëqcš×CÖ+-²6Ö+uXÅu$;'!hÛ¸çsuJ"sIÖ‘Þ꺴éhpq‚ÕÜØË‡ Ä\Œƒ°w¸±ûû~qþ?Ë÷Œ€MZR’‘ê?Fïdkb2=¬â)w™½íNR¦p­?rs}òúÞ<î7·2Gqn¬-ÙÝÎÆHàטß>Gº2ø‘ýK‡ - ³6žñ™øœF/5a+á{ »™Úâs˜Ò扛Ý5úé ¾¼)…öwgC]¶Ö@‘E¥ýe¥â†b¤´û‰òšÎumÜ[€‹Žb£2?I~ÙG &¨¦bŠãßvÛÍÿÌbnl#{ì. ¯yŽ ˆEþðÙ´¼k{Ü$1é ¡ÀÐדi϶YÉì¡ÈAvö¶î>‰Ýr?2b«N–µ¥áÕ.!Ô"¡u}©‰­»ZÂö|å¨÷÷ ×RÍ“-n/å æßfŸ˜™BÆ `5LÑÊ8jˆÀŠªvªêo{Þ­›)º²9<îþÚ· ·ìf7Dæ²’¸ÜX:G÷¯Ôu€ãFpG+a·ì¬q;G? æ7·ù7‰çV1ÜÞ5ÐÚx¤ãq5èÈÓpVõ¹ŽeçSbÙ’0¶ã˜É'7oIHd];T»Æ"‚‚&)JÒ9}/8!åM†so¿2ÊĺI#–Y®ãˆ¸¸É0{.“K»¦1§h‘à’FѼcå¼¼Á»Åf‘’þêì6[†=‘Çn÷é ŒµÆF²£¼sÈ⡤^—„á>:ÖžãjȽ&g•—áóH\¶ÓÈ'åŠe<'D$àN²;gFrÂFÓuŽØ]Ã(%ŽšÖå{ÍKŒ†ÌÍaá€ZgòL†fÊÝnЇD­‰À¶Žd{Cèj:GBÖmv6{Ÿ’’Sqˆ²t‘–;Cdá©…í¡«\ÂÒ[QJÒ«›OÂ3ºxSök[*»A…Ë–2´å˜, Ÿ$Î_4„s¥Y¸( ÝϺmÀƒ¦•†±¾—Í.cdíà öØ«Z*ÒèñÚÚ8U¤Ž"¢£‚Ê]ÚǰvUŒÅ²Q¸´ÑÀ>óI-`b±Ê ŠÝ™Ž èíöÛ§sâ9‰Ù›¡Ö’Zd±’)bc£Õ{nA¸¡Ïwæû¯Î4µ¥y\û’Ù—›ŸÛ†\YdZÉ#‘áôµ˜R-oÞx„ý“BhÏñŸŽømÂwÔš³–³ÍÏp¶3ÖáŒ`”P²ØìÞCÝŸù¯ì»‹èðŠ»6™b‰»u bÜ;(n&à‰‘ŠÆ@4IÊÉ7\®Ì:iª©ºhQÓZÔîöŽAŸþŽã¼‹û/¯ýãýU¸Zo (/!1¿¬¶„~êñ–øÑk¢Û îÁš©é h3‘ËöÊ ±3g­ÓQ1!ûBHMÒ”7@§(ã~á¹-ÜDðÐ ¯Ghý}=«/W0;†4v;SúW-€`AI¤ñ“õ¶>ógL1Èö­Ôm_ÊÀ¢# €d÷ˆb¢q áF ì‘i}¬†Vôè §ej¹¼qLq,»„ÓãµwÄW–µƒÚß¶;œ+u..”AFd]Ã¥Žªª9QÊ¥XÇLÂM0&á@F±_ç2—âñÙ=¤p€vqð©“qàí¡“ŽÆµÇ†”ükƒÎqS~ÉÊqÀ„88“}º® ¢i]äˆdTCB˜Cw„Á  ¹ûN\ØÓ~í`t€4è©p=€¼Þï.:-'ûN<~¦´ÿ”ø:ÈJ¿•r£·î”r²ªS˜Ú{EGyC!L¡¹L ˜yGQ­òÖÆÖÆ.æÕŒú:O„ôŸ­i·W×WÒw·O/ÓÐ< }Kã󇊻WU\ ¯xjHN¥ B•¨WП @70Ò (¨Wóù)iM ˜jHíEUÀãá©Òš@8søêKUT¬šàÒàƒµø®áê⹦¢­Ûz-YRS3³²,â!¢cšM6UÓù9I›²`ɲE(ª§!PÔD¼ã›¶¹.Wçñøèe¸¿›pÈ⎒G½ÑÖ±Îq<Z ' -Ë—wv¶[ëyy#!´Žþ=ïpcÐðKœçÖ€8’HveÉÄ\Æãç.g¼W78ÙŸ9rm’ñ’HÈ[Ý•;.%Güz˲•·.¨_Ù.‘”&Š&áo‘3†»Ø›Ç‘˜­¹á’·ìcp{ f¶¸ŽÖ ×éxd°ÈÞ- â…Àæ¯7uÎÛæþéÁÈÉXܽÓÁkƒ£žÏ!-ÔÒC£•‡CÚjYÁÇVGácð?ˆ'mùÌQ‘2ùxc+‚)ÍÝd[Y킾î{FfÝŽ;UTKȱf‚ ‘Dˆ¨r>3É=½Í[MѼçÝÏè—kmä‘tì qƒÇh<–xÛ'³o&§¢Ž‚†l&§¾zÕùͱ÷œ»íöû6ÞáØ=çime’–(ÜæÚºÚâ*ÝJæ´µ6n|#]‡yB]¤,ï-wNÚj6mË4MÊí«‰®¬£{ÚÓ8žÒÚH."ä6C¦¤ ©]CÀod´§8”³¯L°¾$¹ø—k! œÜŒÞÕËP·Ì+û•t\X@Ü.n§¤|ë³¥©@Û…8¨žÙÎþZ;+e·rØ|[r¸Ý¹;›&4tÏc+"ŽF ¥ˆC•«¸Ò¤»_ånöYœ~FüØ^æbeéèŠéŽ‘ìt„¥’^êpáZ\2öEâÙêâÚ% &ÑRaž4±°NT³ò=ß‘n÷I ÌåVûä!,Dƒ§Ž ’Ä)ƒ†*š ;aîÖ?°vÑLn£uÝÎJÊ{H- ó”.•¦K¦šh¥Í$t¸T·m—/ºðøËËíÛ»£|b‹xl®b¸–âRÕ» ¸ŽÞ2û—BøØÇÜ6!Ró©Ž{Øßë<}–js{›?sÛnk­Ñi™¹‚Ë#Ÿ·.…ó?L"F½Îl.ÓH£ƒZçu4ôº<ŸY¼3q«jÞ\A`éÌ¥±¥´Â"À²oÈ‹„åB2bQTQm>EЊ¸.7ª;8ž.4]8f‚eQq/lB†;sf³¼Àæ>ÎÉáð9¨v͆JgIuqlø¸¾6LT/Š&†ŠM6†ÈâZÊè%w0xÌVÐÙ{’Ç#–ÆKœ»²¬‚Ù'½Ä !²HêšÇ§1 SP „ÞMmŒ­ìÞáå{'c(ûŸ‡I¬Òâü°îK½Œ5îñ+Òüw3ż°(úmGLž $Ý)©Žbæ2J¹œD¹-¯üÃgÝÉIÜãŵÌ0:Kv›{fÇ'}(£c s]^’€Òq™ì³¼œÄ6ÒöÉ—¸y/ ðI+Y1N^Îê3Åä‚)Ð H–2Zèâg ZÜ^ÙNf¯X9¬U“¸!¶øx¿ï6Z>èFÉVçláGŽ ‡» å#‘ó}AËd2‚C @‡ó¬g.7ŽO”÷‘ÙÙÏçÆï9²¶¶÷ t&àB@hoxâÈǼÆï°÷46 á¹ßoM·cÌ gÜÜÅ& ÷lÇa<°½²ˆL€ÔÜXæ´=¿i­$БCÓÜé”°`1^G¼ï±pH[Ò° "-ؤ•ÏzPtáÞâM슰öQbm›ÿvg9³µ]Ëݱ€ÎZeòRBË©omooced’ºI^Cdw‰F5•tÔYㆰëÛGob¹{ŸÇ9–Å\c¬™+ ŽÖá³Mu#£s#k#h.`ñªç:ŽÒâ’áÆm[²ÒâÓ…ÀÁ²¹ÂÅ™«æ;»(ÙÄÈ·6••[¹i)ø7+Òü_s±œ”8 ‹U"$RAEŽß'“ÅåyWÌÏml/²{;!ˆ‚Êãî‘î-eµ dRºøÏ…Ñ0js>É.$U¬t¬o±ûûcü1=Ý¥Žä³ÈËsÞ$Cû´ñÙ-í¾ù‚{©ç.H!qÖØ[Ž—7²FµÞ+Ô£ÛG¶­p+æ¬Þ5¸|´øØî ºŠl°½²G#zZö¹…ÃÆiŠÕ¦­wW*›u¬ÑjÅÕz!ÕÑae.2—×]÷kbÛ²O%BælWvß’F…±¥®&ñÖÌí­qO‚*§¢ð±Ä35U)’QUM®†L¥SÀyƒÎížec9¯‹±ºÉââÇI½‚ÙåË"/|ÑMUP$yàÖŽâ[ëÛ>÷œÙÜ¿¿º‚Æý÷¬¼µ–wh…ò67Å#ètU àI=~$ñ…ƒÂ„u›–.ì³d_™âÙË6Ñbã IzA^m m…Å1)‘'#ؼo¤#-Ð\ªo,š‚ —µ"\îÜÙÞi\^mlV*öÇcÜ⮡¹¼¾·–ÞGK×—ûªÊêxb¼¸ŠÄDÇ=­|¥’Ê_Ý´çéi€‚iT–eçi5öwåû)ÍÓn6¼äø…´f£mæã¹ä!›@B¢æ]ŒŽK*î1ºÉ‡pšFH†(€˜–_–—ŸøœÌv×ÃÅ€ž7Î#y…²d"7J†¼‚ipqÇdqìåCùá'åâ{b/h•̰¶2u‚.€GJÊî.x{q™pÁ) –°¥¡(Ç„¬-)mdëù¥‡*Ös:ow´<«ak1eÝ8Ar´:®Û®¦DJªb>]ÊýЋrÛ^b³7vÏÝy²k;W\±Ò~e¦h:£–kš^LJðx-rß9ƒ´_¸äÁÏmÆ[ÎÍ¿f×Gs8ÁŸœ"Q¨QñÔ¹§I.ioÑÁ}–ötáÝ)ð-öíµæ,N°)1=™–îÀµ†¾hk ¡~ª›¢×i&_Gjá]ävR¹M@Hr7û'˜å†w5 ­Ì9¼þwï×1\Œ{ŸCj x÷ÎgŒö¶Žs Í/.rZn Í÷ŠÆKq˜¼F+î°ÝÈ+¼ ¨Ÿÿ;ÅkZÁÓG®ÔáªêɸÿˆHû»ŠÓKà v–µµ<0ë…¶ÖÞKá#‰L#XWåÁyc[¶™2ìcgCIÄ¿Ay3¶“z vÊ3F5NÐMNÌÊ%¿ºUÁëœÍ“#·9­·7·÷vFûogy†Î\HÇÈÒV6”/©új[Eç;;,×/ó[[ï–v™Y®m¥gÞel,sà]G;¦¦´„¶´«xG Ø¡€ýšÐãzÚA/bæ{îRøŠŽ$¬Ø·™­ V’7[yéVëQe)¬ì¨¦váÚDœµÔ~9ñß1¯>åw÷Kì=³-ŸÜÉ¢áíÇ9;N™\×ø…±—ïŠð]†å±_ ì»o¼Ûýâ×%;§oxÍP´Þ‡‡JÚÖ6–øÀ¼[Æ´â¹ÆcÁ66OâžïÌíx—áÌ0ãëýÑrÍ'”"qÃÅÇ(ÀeâÛ[)G³2ÎÌÉT£NÈ˵|c¦b*]á)pÛC|f¶×,-6t»spü^ËC fÍýÌxwvó1£ccuL$ |tp-4ä÷ÕÅç7ÝÆä7†øq÷bY÷–÷Œktëhˆq{Î’#,.kêÒǃ2â6ÃÊW¯´s!¹¸a-¦y79ÇŒ.9hØI[¡ÖöÄ X¸÷ë5púnJ&Ìͪ²fWtw„7†&åæwla¹y·ã·šæ\n\Kvèc|Œ„Êó4®{Ú#š$qkHmxt ‹xâ³¹=å˜|ÑAö4ÇnÙÖ>QDQ†µÄ=Ìc]¡µp&œzW G X¥À¾Í¸q½-0—±³5õ){Å ÇVtc¼Ô„«I©¦zM¼ÁÔX ”ÖvTS;pí "NZÌ¿›;瘷sºû¥îÙ–Ïî¤Ñpöã‹È¦’¹¯ñ c.!Þ)à±­ËbþÙvÿy·ûÅ®JwLÞñš¡i¼•µ¬m-ñ}oÊíë ã‰N:øÄILcFÀæO•¬ "örÅ’É;q…š´f·:NU‹ôE’‰qº¡?htÁ2”1J:–w¸­y!´\Üuì—ØŒ­ÕͳaÞ[?xüÉú{jS¨ÐHØ19|4üÔÜm7¶¬µÈãî­á™Ò7¹t’w%¿¶„5Ô š‘AR@]!ÁäCxl镸P».;~^ 7Ø·n*y?iJä¶¼#cœOÚwDDƒr¤Œ©¡ž´p“s @ á}  ÖëÍËÉ/6F+šx»yá¾ÂßA|اa†cÞ"žjYÞ5Í/®–ðêZ¿.­™mºoö üÑIk”´–ÔɻȄÍi’)XáÁÚpoV§q]OÆÞC‡½3Ü䦠}ÄQPøfÂA3&£tmüzÜÑ.‚¨ˆ¹AåÀ/WIR—C¢¡4­¯’ø ¼6Å‚÷*?úöZY2DÔ-ÑÖ* H-‹»ii<×U¯ó;/o“Ý’ÚãÿþÑ–pBvãA¡2k Ž–±,î õbÕçÕJU6ÔªªR©ÕÑS¤§TÀ§@ù¦‰Õ()·ÇJ€§T ¥IjuJU6ëPZR•Mº{•:JuL XTª)TÛãïÒÒT §UIjª¥:ê SªR©·ÇSBR•N­¡R˜)J¦Ý}ÚE¡:¥6éRZR‚•©Õ()·ÇS¥UR‚]êIÕ)Tëè© ER•MºT–ªªPSž¤µ:¥6õ Fš'T€§VФS›u¥@R›t©-N©ANº’ÔêÛ§wŠ µ:¥9ü”¨SªR©·]”¸u§T€¥-=‰Õ(mAjuHêÚ%©Õ (<úÔé¢u^ép>]lx!ç‰ÿÜGݯ˾`~þfÿkÞ~±"ûÿfþèb¿fÚþ‹Ð-ÀÛäþŠÔVȦàmòE_^.ï]Äïþ!sOúȹk÷?”ô§lÃØïÔá_–\ÂýþÎ~ؼýfEUèKOR„)B¡ P…(B”!J¥VR NªÀpðÒÒŽ à<ÃSDø…`6”QíWÒNƒ©\B*B°0éEPUÀãáå©Òš¸e" uWxjhª¸Ÿ’‘jÀÜÃRBªžµp8Ò⎀p¡>)ÜÃJ€¢¡\Î*)«ù‡«üTˆíN©üþJ’ÔÕÀüÃRZRƦˆ¨HŠ<)ñJšT¡0UÀáÏ¥IjuHš’ÔêúT–§T€q©¢*< @è¥áUT §]*U n4‹SªP??’ µ0RüÃRZRœõ4)Õ)TÛÕK‡ZuJ w-=‰Õ )·_v¤µ:¥:ª SªPR§JuHU6éîE/ iANà¥@˜=‰AMºôÔ–§T §UAjª¥:êt§T¥SnžçôT‘ÚR‚ÁJ0R‚›uéïÔ–¢«!¸ƒÏîóôž0’ym7¶ 0Õ•‡ÐI´š²…—mf¸šp”ê§U“!f»ñ™3p ŸfÚòh aű-²Vðܺädr÷ä–wfàF BŽv Þ_²(¶ýÝ»$Ý“XÍ$-ƒîXØm.Ö!/:Í@¡v¿³Æ”é+ ÁNºÞ‹V§T¥Wm*´ê”î šÁJU6ëîÔ–§T ¦Ý;¼U%©Õ()Q¦ ª˜ªíñÒ§juJ uyB•N«)pŸP2Ùœ{jb¦3£¶Ó‘vÎk}vJ¨{*"}ŠQÎÍ b DÆÝ©œ¼—¤‘Dʸ”S17ʧ˜ï>^ßïl”å2’7d1Ѿls``ûÄ‘8½½åήóº.Ò]‚š‡BÝëlï M­e,¶ ;¥Í{c½t¯=Ë$hiÑàƒdÔÕJPq˜W2‡1Îsç0œç9„Ç9Œ:˜Æ1„DÆ0Ž¢=ñ¯HîÃF(Ò5jx’® wN“ÔŠ¥zÈ4¨S›té¥@UU()ܨ)TÛ­Ijª¥*›tîæ¨ÒSª`S¯¢’uJU6øéi Õ()ÕPZR‚u©Õ)TÛãïTUU()ýaý“¯bb©·_v‘hN©J¦Ý* SªPR µ:¥*›z†• uíJ t‡”*hR•N¾ŠE¡0R•Mµ©Õ()RZª©J¦Ýz{õ4!:¥:CʨR‚{B§H= Õ()¶¤µ:¥;‚ µ0R•MºìšQ:¤:CËKÂS}¨ )¶¤µ:¥óÔ¦ B©Ì=CRZR‚ÁKŠuJU6ëÝã¥@RU%©Õ{¿ÀçÿÀÄñŸþAµ~[s÷÷9û^óõ‰èÌýÏÄþ͵ý •¨-•J¿\\ÿÞ»‰ßüBæŸõ‘r×î(ÿéNØÿ‡±ß©Â¿,¹…ûýœý±yúÌ‹«Ð–ž¥R„)B¡ P…(B”!J¥R„)B€ÃÓJ:«€vR¡B¾µ4N¤-@Â" ô«ûƒú)'NÅp0 ©*àna¢‰Ôp?8xªt¦¬ï *U CmMuV‡EN”ü ÜÃSDWµ\4qO‡R¸(OZ@8óøéPÀááä©Òš@0øZ’ª¸ŸÉS¥:¤ó I ×µ ž• +ØúQáOÂ×KObuH};¼U%©Õ |5Sª@>ßðT–§_­ (>TN©MºRð¦”×Jƒ©Hæ¡©-N©üþJ’Ôê”Ì5©Õ )J…:¥6øûµ¥@R‚]‹Sª@S¯¢ µ:¥6éRZª©JšS¡:¥*›ixQT §pTÐê”Û¯»RZR‚U%ªª”¨§buJU6øéSµ:¥:º)Pê”Û¯»RZR‚›tîñT§T€¥Nšt'TÅSoަ©Õ()Ò¨ uJ uôT–§T¥SmAjª¥;‚§IêN©Š¦Ýi'T¥SnžåMN©ANà©-L¥SmAjuJU:ªhUU)Tëò $Wð¦*›z†§H)Õ()ÕRZª©ANº‚ÔꔪmþŠ’ uJ w*&bb©·_ Ô–§T §UIjuJ sÔªªPSo»Zšꔪt‡”)Q:¦:ú*KSªR©¶¤µ:¥?¬* SªPSn½=úšR•MºyB‘:¥<[*KUU)TÛRZR‚]©Õ()Ð>í*R•MºtÔR‚”´ö'T¥SmAjuH wIjuL t»SBªB©·Nžõ/ uJ RÒ:“ªR©·»š µ:¤*KSªPSn½=ÚÔé¢u^õp5ËaÛÃÏ ÿ'µ¯Ë.a~ÿg?l^~³"ýÙŸ¹øŸÙ¶¿ bôµ²©BàK‹Ÿû×q;ÿˆ\Óþ².ZýÏåý)Ûðö;õ8Wå—0¿³Ÿ¶/?Y‘cÕzÓÔ¡ P…(B”!J¥R„)B¡ P…(B”!JµÔB„UX>ZZSVÔУÀ¯­*'R€Â‘PUÀô'CÔ®¡íVw†‘ ðêWó…-)ñWs I¨ª¸zii «Ã¢¤µ?¸jh{RèâW…$ëÚ=4i¯b¸:*t”ê<úÔ–§Up?UIjuìHæ’¯j@Sž—ëØÌ:QÀô¢½©üþJ)¤óPÔ–§T€~%IjuWó IjuíJ sÒ¡N© ~aÓgø©pëN©@üþJZ{ ˜uØ5%©Õ )ÕPZR‚›{½Ú’Ôê¥Å:¥6ëÝÏJH m÷*KUU()×ÑRZФ*›j UU()ÏJ…:¥6øûµ©§juJ utRÓTê”芒Ôê”ÛÝîT§T€¥MèN©Š¦ßv´©ÚR‚!ÑJ•N©AN¾Š‚ÔÁHU6Ô–§T ¥MRuL íצ¦©Õ)TÛ§”)iUR‚ÁRZ˜)J¦Ú‚ÔꔪuTЦ PS¯ÉSDꘪmêZjR‚ÁRZR•MºÔªªR©·Or¤‚R‚ŸÖ4ESM¾>ý"ÕUJ uT§T §]IjuJUvøêhSªPS«¢•ª¦:¤µJU6ÔªªPR§JuJU6ëÓß©¡N©J¦Ñ(R N©Nà©-L¥SmAjuH utT–ª1Tëò M *”ªmñÒ UT ¥IjuJU6ëPZR‚]%©Õ()×¶¦…:¥6øéP'T §=-=‰Õ()·Z‚Ôêêè¨-UT §_»J…J mñ÷iJ‰Õ()ÏS§±0W¾Ü ð »ÿDÿÉÍkò·˜_¿ùÏÛ¿¬È¿Aö_îv'öe¯è½­=lªP…øâçþõÜNÿâ4ÿ¬‹–¿sùGÿJvÇü=ŽýNùeÌ/ßìçí‹ÏÖdXõ^„´õ(B”!J¥R„)B¡ P…(B”!J¥R„)B¡ P…¨‡xh¢uVóÒÒŽ à` M < ÚÒ¢u*ÀqþºÀ«û»ô“ãÔ®¡íW=*ü àpðòRÒš¸˜jHíEUÀãáå©Òš¸9ütˆ)‚z•ÀÃSDTu«èL} Áà\¯j@8ôÒ-MX‹J*=5BuW‡E"ÔÁJzš'^Õp?=.)øù†—U ŸÉHµ:¤ó»¤µ:¤óÔéN©üÃRZRœô¸§^Ä¥So»Z\ª@?õ…-)Õ(nµ©Õ )ÕRZRÇž¦‰Ôx‚T¸õ¦”è%*U )·Nš’ÕUJçòT¦ B©¶¤µ:¥*hSªPSn½4¨ªPSnžå"Ôê”þ°¨-L…SmIjuJ TЧTÀ¦ÝziSµ:¥6éîTéªuH wIj`¥*›j UU()Ü4)‚˜ë¥DU()·Nš5U^Ô §pT–§T¥Snµ©Õ)Tê¥BR‚}4LÅSoŽ‘juH uTªª`S® µ:¥*»|t¨SªPS¸*hªb©·_v‘juJ mÒ µ:¥* SªR©·]ƒJŠª”é(TÐ'TÀ§_EIjuJU6øêKSªR©ÕÑPZ˜)ANò *'T¥SoPÔ¯jPS¸)§T¥Snµ©Õ)TÛ§¹PZª©N¾ŠTN©J¦Þ¡© 'T §U"Ôê”ë¨-N©J¦Ý=Ïè©-N©ANà©LÄ¥So¿J:¥:ªKSªPS® µUWÖÑ%]¹nÕ¹ ¢îVMS/(¨¢§ ßt®ŽFòÛa6Jõá–DéãÐÖ°|.Õ•¥ÅýäV6­/¹šF± t—8Ь•ú#àêXk>1±Š;­XµnSi  [·M ^PܯɌÖEÙŒÍÞ]⺺–b; ¯sÈÿÞ_¢Ø«&ã1–ØÖš¶Þãè¿äYÃXÅßR„/À—?÷®âwÿ¹§ýd\µûŸÊ?úS¶?áìwêp¯Ë.a~ÿg?l^~³"Ǫô%§©B¡ P…(B”!J¥R„)B¡ P…(B”!J¥R„)B¡ P…¨‡†Šê®ç©ÒŽ À`ð *#ˆVÖ•¯j¸—øp8PŽ!\„Tu«„6Ò 'àV‡EN’š¸˜iÚUÀüáS¥ÀÀ>I Ô«Ä)Q:„€zÇ©\ Ì4¸ëÚÏËHµ5p8xJ’T€qðòÔéM\útÔ–§R54N£ëH ñHÛ¯M*Ф‡E-)Õ yõ¨-N©üüžåIjª¤=MT€¥.)¥6ëÓJ:¤õR-N©@ýu%©Õ\Û¥AjuJ MªPSnÞ*<)¥óòûµ4I×± )·¨jKSª@SŸ’¤µ:¥*›u¨-N©ANª\SªPS iP'T ¦Ý:i§T §=Aj`¤*œÃ­AjuJ uR¡N©NºšêÛ§M"ÔëÚ”¨-UT¥Snµ%©Õ)Tê©¡LÀ§]*ꔪmñÔ–§T §UIjuJ uÔ§T¥SnžåI:¥;‚•uìJU6ëîÔ–§T §UIjª¦* SªR«·ÇSDê”êò…*ê˜ëè©-N© ¦ßAjuL wNžÅUJ ôjhŠ¥6éÓJUR‚ÁRZSMµ©Õ!Tê©ÒSª`S¯¢¦‰‚”ªíñÒ N©ANª’ÕUJ uÔ§T¥SnžçôTé)Õ()Ü“±1TÛ¯»S¤'T §UIjuJ uÔ§T…SoާJª§!Œs¥)Œs¥ „Æ0è DDDkŽI#Š7K+ƒbh$’@$’x:ÉàÆÇÈñ@¹î4 ’O@t•˜¼:`雎àa-$ÅRn*C3l¢c¼–ð€zBÅ÷ªGÞ”yKßJøŸæ´ÎBý™´åï1¥Ãï3´ø²i5î£=l¨«Ü8:šEZM~©å,.12·sî(ô_Só¸qeGûGŽ§ÓƒZx·í:”ýâëE;RÞhÐ8"@0né˺óxkåô:ìê¥_ŸÎ"ý’ØâïÉwæEޏr¡¥² åsß-‹1iŒci[²qôô‹xÄ~ÄúRè»~r¢EVYR¦(qÔÃõvÝþp¹™¶vý†Û°±Á>Çg ´n’£#£‚6ÄÂòÛÖ4¼µ€¸µ­Ö€ð,Ïòç²s™{¬ÕÝÖU·W—2ÎðÉmÃå{¤ph6Î! ¸†‚ç)ROŽÿ´%·óÎJúVØü£Yîk{¿oy ÏoXß– ƒé™+mìŠ~ЖßÏ9+é[cò;ÜÖ÷~ÞòžÞ– ƒé™+mìŠ~ЖßÏ9+é[cò;ÜÖ÷~ÞòžÞ– ƒé™+mìŠ~ЖßÏ9+é[cò;ÜÖ÷~ÞòžÞ– ƒé™+mìŠ~ЖßÏ9+é[cò;ÜÖ÷~ÞòžÞ– ƒé™+mìŠ~ЖßÏ9+é[cò;ÜÖ÷~ÞòžÞ– ƒé™+mìŠ~ЖßÏ9+é[cò;ÜÖ÷~ÞòžÞ– ƒé™+mìŠ~ЖßÏ9+é[cò;ÜÖ÷~ÞòžÞ– ƒé™+mìŠ~ЖßÏ9+é[cò;ÜÖ÷~ÞòžÞ– ƒé™+mìŠ~ЖßÏ9+é[cò;ÜÖ÷~ÞòžÞ– ƒé™+mìŠ~ЖßÏ9+é[cò;ÜÖ÷~ÞòžÞ– ƒé™+mìŠ~ЖßÏ9+é[cò;ÜÖ÷~ÞòžÞ– ƒé™+mìŠ~ЖßÏ9+é[cò;ÜÖ÷~ÞòžÞ– ƒé™+mìŠ~ЖßÏ9+é[cò;ÜÖ÷~ÞòžÞ– ƒé™+mìŠ~ЖßÏ9+é[cò;ÜÖ÷~ÞòžÞ– ƒé™+mìŠ~ЖßÏ9+é[cò;ÜÖ÷~ÞòžÞ– ƒé™+mìŠ~ЖßÏ9+é[cò;ÜÖ÷~ÞòžÞ– ƒé™+mìŠ~ЖßÏ9+é[cò;ÜÖ÷~ÞòžÞ– ƒé™+mìŠ~ЖßÏ9+é[cò;ÜÖ÷~ÞòžÞ– ƒé™+mìŠ~ЖßÏ9+é[cò;ÜÖ÷~ÞòžÞ– ƒé™+mìŠ~ЖßÏ9+é[cò;ÜÖ÷~ÞòžÞ– ƒé™+mìŠ~ЖßÏ9+é[cò;ÜÖ÷~ÞòžÞ– ƒé™+mìŠ~ЖßÏ9+é[cò;¼Ö÷~ÞòžÞ– ƒé™+mìŠÁ솷ûç%})l~Q£çwšÞïÛÞBóÛÓù`Ø>™˜ò¶Þȵý¡íÏž2OÒ–Çå*_;œÖ÷~ÞòžÞ—ËÁôÌÇ•¶öE?h{s眓ô¥±ùJÎk{¿oy ÏoOåƒ`ÿy˜ò¶Þȵý¢-ÐþùÉ?J[”©|íó[Ýû{È^{z,;ÒòþVßÙU¿h«{猓ô¥±ùJŸÎç5½ß·¼…ç·¥òÁ°}31åm½•kûEÛßXv¥åü­¿²«~ÑÖÿÏ#éKgò/®jû¿oy ÏnGËÂôÌÇ•¶öU¯íoüï‘þ”¶)ÑóµÍ_wíï!yíÈùbØ^—˜ò¶þʵd„|d¥-ŸÊt¾vy©îý½ä/=¹?–-…éy+oì«_ÚFç|ôµùR—ÎÇ5=ß·ü…ç·%òŰ½//åmý•kûI@ü“¶¿*Qó¯ÍOwíÿ!yíÉü±ì/KËù[eVd¤{äo¤í¯Ê”|ëóSÝûÈ^{r>Xö¥åü­¿²­iX/ò/Òv×åJ>uù©îý¿ä/=¹?–=…éy+oì«PöKÁ‡z_"ý'm~U¥ó¯ÍOwíÿ!yíÈùcØ^——ò¶þÊ­ûLAüí‘>“¶ÿ*Ñó­Í?wíÿ!yíÈùdØ~——ò¶þÊ {&¡½-‘>“¶ÿ*ÒùÕæŸ»öÿ¼öäþY6¥åü­¿²«~ÓpŸ;d?¤­¿ÊÔ¾u9§èÈ]ûr>Y6¥åü­¿²­iØ_²ÒVßåj_:|Òô ¿ä.ý¹,ÛÒòþVßÙUƒÙ? ÞÙé+sòµ:|Óô »öä|²ì?KËù[eZþÔß:ä/¤­ÏÊô|éóKÐ6ÿ»öäþY¶¥åü­¿²«²Š?½rôÉ[Ÿ•é|ésKÐ6ÿ»öä|³l?KËù[eZþÔpÿ:䤭ßÊô|ésKÐ0BïÛ‘òϱ=//åmý•[ö¥ˆù× þñ·+ÒùÐæ `<…ß·#åŸaú^_ÊÛû*×ö§‰ùÓ }#nþX¥ó¡Í@Ày ¿nOåŸbz^_ÊÛû*°{*bƒûÓ }#nþX£ç?š>€ò~Ü–}‰éy+oìªßµTWΗÿÒ6÷åš>sù£è!wíÉü´lOKËù[eVý«bþt¿‡ÿxÛß–i|çsCÐ0BïÛ‘òѱ=//åmý•jÊèÀïIßßHÛß–i|æóCÐ0BïÛ‘òÓ±}//åmý•[ö°ŒùÎýúBßüµKç3š€ò~ÜŸËNÅô¼·•·öU¨{,£CûÎýúBßüµKç/™þ€ò~Ü–­‹éyo+oìªßµ¤wÎWçÒÿåª>rùŸè!wí¨ùjؾ—–ò¶þʬËhðïI_ŸH[ÿ–èùËæyÿö!wí©üµl_KËy[eZþÖñÿ9_H@~[¥ó•Ìÿ@Àù ¿mGË^Åô¼·•·öU`ö]0ï+ìz_À~[¥ó“Ìï@Àù ¿mOå¯bú^[ÊÛû*·ívÄ?¼o¯ãà?.RùÈæw `|…ß¶£å³cz^[ÊÛû*°{/™÷óü|åÊ_8üÎô‘»öÔ|¶loKËy[eVf0ïHß?ÇÀþ]£ç™Þò~ÚŸËnÆô¼·•·öU¯í„Ïç ãøøË´¾q¹›è8#wí¨ùmØÞ—–ò¶þʬÌFýá|u¿‚ü»GÎ/3}änýµ?–Ýéyo+oìªß¶3_œ/ã ¿/RùÄæg à¼ß¶£å»cú^[ÊÛû*°{2÷…ïütåê_8|Ìô‘»öÔ|·lKËy[eVfSpïH^ßÇAþ_£ç™žƒ‚ò7^ÚŸË~Çô¬·•·öUoÛ1¿ú}ëütåú_8\Ìô‘ºöÔ|·ìKËy[eVfrþzõ½ƒü¿Kç™~ƒ‚ò7^ڟˆÇô¬¯•·öU¯í úuéül'Ô¾p9—è8/#uí¨ùpÙ—•ò¶þʬÍ$ƒüúóþ6ê _7üÊô‘ºöÔ|¸ìJÊù[fVf¢aÞ}yÿ õ 7üÊô‘ºöÔþ\vG¥e|­¿³+~ÚÉÿ¦Þ_ÆÂýCKæû™^ƒƒò7^Ú—‘éY_+oìÊÁìÙ žÞ?ÆBýEKæ÷™>ƒƒò7^ÚŸË–Èô¬¯•·öe`öm”?Ïoã!~¢¥óyÌŸAÁù¯lGËžÈô¬¯•·öeoÛt?Ó/ã!¾¢¥ówÌŸAÁù¯lOåÏdúVWÊÛû2°{7ôÿ<¼:ÞC}GGÍß2}än½±.{'Ò²¾VßÙ•¿nóË¿øÈ¨èùºæG àü×¶#åÓdúVWÊÛû2·íÈoôË»ø¸©*~ny‘è8?#uí‰üºlŸJÊùX=™jÎSùåÝü\?Ô”|ÜsÐp~FëÛòë²}++å öeoÛ ÿéwoñqRÒù·æ?¡a<×¶'òí²}++å öepöu(çw`ô»ˆú–›~cúÈÝ{b>]¶O¥e|¤̵gb¡Þwvõ-/›ncúÈÝ{b.Û+Ò²žRfVý»–ÿJºÿЉúš—ͯ1½ än½±.û+Ò²žRfVgŠáþuuõ5/›>czÈÝ{b>]öW¥e<¤̬Ï5üêêþ*'êz_6|Æô,'‘ºöÄþ^6W¥e<¤Ì­ûz¸ÿIºŠŠúž›>czÈÝ{b>^6W¥e<¤̬Ïw!þstõE/›búÈÝ{b/;/Ò²žRfVý¾]¤]ÄÅ}QKæÃ˜¾……ò7^Ø——éYO)³+~ßnÿÒ.âbþ¨¥ó_ÌOBÂùŸlGËÖËô¬§”ƒÙ•ƒÙúð;Î.âbþ©¥ó_ÌOBÂùŸlOåëeúVSÊAìÊßõyÿŸ¹¿‰ŒúªšîbzÈÜûb>^ö_¥e<¤̬=÷û—ø˜Ïª©|Öóа¾FçÛù{Ùž•”ò{2°pø?ßîOâ#>ª¥óYÌ?BÂùŸkGËæÌô¬§”ƒÙ•¿ê ÿÿ=rõ]/š¾aúÈÜûZ/›3Ò²žRfV$ýþãëqõ]5|Ãô<7‘¹ö´|¾lÏIÉùH=™[þ¡R!ÞZãþ"7êÊ>j¹…èX_#síhù}Ùž•”ò{2dx ß.ò—Ã^Rv;¢ÃÙÇÚu…qKüÓsF6×Çë6Š«§ äùÙlxs§É8£,4>0ø]÷øB9Ê ž0©¨Q.ó‡w<ÂUŠ[Þ&è5yVëæ†ùÞŒ0g²¾Èš÷, Š/¢¬Œ4>FMdv¯AÛÛ iíw qq²è w®¬’}4{Ë‹kÖ¤} Ѽk†!,–艧۔¥ÔÛ…×PþºsÖ€·Þ…)HP)C@Є+P…(Bø|]¯ü'Ñ÷¿ûÍ5¡ æùÔüÚ§Èž§æÐ…>Dõ?6„)ò'©ù´!O‘=OÍ¡ |‰ê~mSäOSóhBŸ"zŸ›BùÔüÚ§Èž§æÐ…>Dõ?6„)ò'©ù´!O‘=OÍ¡ |‰ê~mSäOSóhBŸ"zŸ›BùÔüÚ§Èž§æÐ…>Dõ?6„)ò'©ù´!O‘=OÍ¡ |‰ê~mSäOSóhBŸ"zŸ›BùÔüÚ§Èž§æÐ…>Dõ?6„)ò'©ù´!O‘=OÍ¡ |‰ê~mSäOSóhBŸ"zŸ›BùÔüÚ§Èž§æÐ…>Dõ?6„)ò'©ù´!O‘=OÍ¡ |‰ê~mSäOSóhBŸ"zŸ›BùÔüÚ§Èž§æÐ…>Dõ?6„)ò'©ù´!O‘=OÍ¡ |‰ê~mSäOSóhBŸ"zŸ›BùÔüÚ§Èž§æÐ…>Dõ?6„)ò'©ù´!O‘=OÍ¡ |‰ê~mSäOSóhBŸ"zŸ›BùÔüÚ§Èž§æÐ…>Dõ?6„)ò'©ù´!O‘=OÍ¡ |‰ê~mSäOSóhBŸ"zŸ›BùÔüÚ§Èž§æÐ…>Dõ?6„)ò'©ù´!O‘=OÍ¡ |‰ê~mSäOSóhBŸ"zŸ›BùÔüÚ§Èž§æÐ…>Dõ?6„)ò'©ù´!O‘=OÍ¡ |‰ê~mSäOSóhBŸ"zŸ›BùÔüÚ§Èž§æÐ…>Dõ?6„)ò'©ù´!O‘=OÍ¡ |‰ê~mSäOSóhBŸ"zŸ›BùÔüÚ§Èž§æÐ…>Dõ?6„)ò'©ù´!O‘=OÍ¡ |‰ê~mSäOSóhBŸ"zŸ›BùÔüÚ¾ô=Oì; ?û¿à¡ é¡ P…(B”!ÿÙopenchange-2.0/apidocs/html/libocpf/index.html000066400000000000000000001104651223057412600214740ustar00rootroot00000000000000 OpenChange Property Files 2.0 API Documentation
OpenChange Property File (OCPF)

OpenChange Property File (OCPF)

Contents


Revision History

Date Revision Number Author Revision Content
27/11/10 0.7 Brad Hards Add PT_DOUBLE support. Update PT_I8 description.
27/11/10 0.6.1 Brad Hards Update bug tracker link, minor rewording
25/06/10 0.6 Julien Kerihuel Add PT_MV_BINARY, PT_MV_LONG and PT_MV_UNICODE support. Update PT_BINARY description.
01/04/08 0.5 Julien Kerihuel Add RECIPIENT support
29/03/08 0.4 Julien Kerihuel Add PT_UNICODE support and ocpf_dump option
06/03/08 0.3 Julien Kerihuel Add PT_BINARY and Streams support
05/03/08 0.2 Julien Kerihuel Improve PT_MV_STRING8 support
03/03/08 0.1 Julien Kerihuel Initial Revision


1. Introduction

OCPF stands for OpenChange Property Files. This is a tiny file format designed for scripting and which facilitates third-party applications interaction and developers work using OpenChange. The main objective of OCPF is to offer the possibility to go beyond OpenChange tools default properties and create a custom message with user-defined fields.

2. Purpose and Scope

OCPF is designed to be used in various kind of applications and for different purposes:

  • Research on properties: OpenChange developers have often requested for an easy way to test properties and properties values. Prior to OCPF, developers had to write an application linked with libmapi and compile it so that they could test properties. Moreover, adding new named properties in trunk required commit permission to OpenChange source repository. OCPF solves this issue and allow developers to write OCPF files with custom properties that they can send using OpenChange tools. Furthermore OCPF will provide the community a convenient way to agree on a particular property.

  • Web Applications: OCPF offers a scripted language with substitution variables which makes it possible to use OCPF templates and use OCPF in conjunction with Web Forms. Since OCPF API supports the parsing of multiple files, developers can plan to have a file with variable declarations and a separate OCPF template that just specifies variables.

  • Backup/Restore: OCPF format may offer an easy way for a restore/backup application to dump to the local filesystem and restore messages on Exchange server. Furthermore, substitution of variables can possibly be used to maintain the new hierarchy, such as changing folders ID across Exchange servers and help migrating database from a server to another.


3. Limitations and Bugs

OCPF is a pretty new library and it currently has a some limitations:

  • It only supports a very limited set of property types
  • It doesn't support attachment yet

These limitations will be removed in later versions of OCPF.

If you find bugs, limitations or encounter issues while using the OCPF library, please consider reporting them on http://tracker.openchange.org. (Note: registration is required to create new tickets).

For questions about its usage or about libocpf development, please post on the OpenChange devel mailing-list.

4. Syntax

The general OCPF syntax is pretty basic. It mostly consists of top-level keywords, sections and properties types.

5. Top Level Keywords

5.1 TYPE

  • Format:

    TYPE STRING

  • Description:

    This keyword specifies the message class of the message. Users can either specify their custom type or use on of the following standard values:

    • "IPM.Appointment"
    • "IPM.Contact"
    • "IPM.Journal"
    • "IPM.Note"
    • "IPM.StickyNote"
    • "IPM.Task"
    • "IPM.Post"
  • Note:

    TYPE can only be defined once and takes a string value as parameter. String values must be quoted otherwise a syntax error will be displayed on output.

  • Example:
    TYPE "IPM.Appointment"


5.2 FOLDER

  • Format:
    FOLDER STRING
    FOLDER PT_I8
    FOLDER VAR
  • Description:

    This keyword defines the destination folder of the message. Users can either specify a default folder using the string value or a custom folder ID using its PR_FID value. It is also possible to substitute the value with a variable, but it is limited to PT_I8 values.

    When FOLDER is set with a PT_I8 custom value and the ocpf_OpenFolder public function used, it can be set to any folder identifier within the message store. The function will loop over mailbox folders until it finds the folder with the given folder ID and opens it.

    Possible STRING values:

    • olFolderTopInformationStore
    • olFolderDeletedItems
    • olFolderOutbox
    • olFolderSentMail
    • olFolderInbox
    • olFolderCommonView
    • olFolderCalendar
    • olFolderContacts
    • olFolderJournal
    • olFolderNotes
    • olFolderTasks
  • Note:

    FOLDER can only be defined once.

  • Examples:

    FOLDER "olFolderCalendar"

    or

    FOLDER D0x9504000000000001

    or

    SET $folder_id = D0x9504000000000001
    FOLDER $folder_id


5.3. SET

  • Format:
    SET VAR = PROPVALUE
  • Description:

    This keyword registers a variable named VAR and sets its value to PROPVALUE. Variables must be prefixed with a dollar sign ($) and their value can be set to any supported property type. See section on property values for further information.

  • Note:

    SET can be used as many times as needed by the user, however VAR name must remain unique. When a variable name is registered for the second time, the OCPF parser displays a warning on the standard output and skips the assignment.

  • Example:
    SET $var1 = 0xdeadbeef
    SET $var2 = "Hello World"
    SET $var3 = T2008-03-06 23:30:00


5.4. OLEGUID

  • Format:
    OLEGUID IDENTIFIER STRING
  • Description:

    This keyword registers an OLEGUID couple (IDENTIFIER and STRING value) that can then be used when declaring named properties (see NPROPERTY). OLEGUID keyword takes two parameters: first the name, used with named properties (PSETID_Appointment, PS_PUBLIC_STRINGS etc.) and secondly a string representing a GUID value.

  • Note:

    OLEGUID are identified by their IDENTIFIER and STRING. Users can't register the same OLEGUID IDENTIFIER or STRING twice. If such case occurs, a warning message will be displayed on stdout.

  • Example:
    OLEGUID PSETID_Appointment "00062002-0000-0000-c000-000000000046"
    [...]
    NPROPERTY {
    OOM:Label:PSETID_Appointment = T2008-03-06 23:30:00
    [...]


5.5. RECIPIENT

  • Format:
    RECIPIENT TO STRING;STRING;STRING
    RECIPIENT CC STRING;STRING
    RECIPIENT BCC STRING
  • Description:

    This keyword declares recipients. RECIPIENT is followed by a recipient type (TO, CC or BCC) and a set of STRING (recipients) separated with semicolon.

  • Example:
    RECIPIENT TO "recipient1";"recipient2";"recipient3"
    RECIPIENT CC "recipient4"
    RECIPIENT BCC "recipient5@remote.corp";"recipient6"


5.6. PROPERTY section

  • Format:
    PROPERTY {
    [...]
    };
  • Description:

    This keyword declares a known property section. PROPERTY is followed by an opening brace, a set of property declarations and is ended with a closing brace and semicolon. This section only recognizes properties as described in 6. Known properties.

  • Note:

    While we suggest keeping a single PROPERTY section, nothing prevents the user from declaring as many PROPERTY sections as needed.

  • Example:
    PROPERTY {
    PR_SUBJECT = "Hello World"
    0x1000001e = "Sample body content"
    };


5.7. NPROPERTY section

  • Format:
    NPROPERTY {
    [...]
    };
  • Description:

    This keyword declares a named property section. NPROPERTY is followed by an opening brace, a set of named properties declarations and is ended with a closing brace and semicolon. This section only recognizes named properties as described in 7. Named Properties.

  • Note:

    While we suggest keeping a single NPROPERTY section, nothing prevents the user from declaring as many NPROPERTY sections as needed.

  • Example:
    NPROPERTY {
    OOM:Start:PSETID_Appointment = T2008-03-06 22:00:00
    OOM:Location:PSETID_Appointment = "Home Sweet Home"
    /* Meeting Status */
    MNID_ID:0x8217:PSETID_Appointment = 0;
    };



6. Known Properties

A known properties is any property where the value doesn't change across Exchange servers and versions. Known properties can only be registered within a PROPERTY section (See 5.6 PROPERTY section). Known properties have the same general syntax:

IDENTIFIER = [PROPVALUE | VAR]
INTEGER = [PROPVALUE | VAR]

OCPF lets the user define known properties using two different methods: property names or property tags.

Please note that OCPF doesn't check whether the value associated with the property matches the property type. For the moment it is the developer's responsibility to ensure that the property type matches its value.

6.1. Property Names

    Property Names are defined with an IDENTIFIER which must match
    one already registered in libmapi/conf/mapi-properties. For
    example:
PR_SUBJECT = "Hello World"
PR_START_DATE = T2008-03-06 22:00:00
PR_PRIORITY = 2


6.2. Property Tags

    Property Tags are the other way to set a property. This is an
    integer value represented using hexadecimal notation and
    which has two parts: the upper 16 bits are the property ID and
    the lower 16 bits are the property type.

    While users may prefer to use the property name notation for
    declaration, libmapi/conf/mapi-properties remains incomplete
    and there may be cases where you need to use the property tag
    notation. The example below sets properties described in
    previous example using their property tag notation.
0x0037001e = "Hello World"
0x00600040 = T2008-03-06 22:00:00
0x00260003 = 2

.

7. Named Properties

The OCPF syntax for different kind of named properties is quite generic. It supports each of the three kinds of property (OOM, MNID_ID, MNID_STRING) and can set known named properties (those listed in libmapi/conf/mapi-named-properties) or register new named properties (except OOM properties).

The types of properties, and how they can be used, are described below.

7.1. OOM

OOM stands for Outlook Object Model and is a friendly name associated to a named property. It has no meaning to Exchange, but it can be useful for OpenChange or MAPI developers.

OOM are human readable shortcuts for most named properties and OOM values are are considered reliable. This is the reason why OOM can only be used if it exists in libmapi/conf/mapi-named-properties. This method - in our opinion - is the best method to guarantee developers a common and validated mapi-named-properties file.

Theorically, property names can have the same OOM, property ID (MNID_ID) or name (MNID_STRING). The only way to guarantee named property uniqueness is to associate its value with a OLEGUID.

OLEGUID needs to be registered before they can be used with named properties. See 5.4 OLEGUID for more information on how to register a OLEGUID.

OOM named properties have the following syntax:

OOM:IDENTIFIER:IDENTIFIER = [PROPVALUE | VAR]

The first IDENTIFIER represents the OOM value while the second one represents the OLEGUID. Note that identifiers are not enclosed with quotes. Below are some OOM assignments examples:

OOM:Label:PSETID_Appointment = 9
OOM:End:PSETID_Appointment = $end_date
OOM:Private:PSETID_Common = B"true"


7.2. MNID_ID

Named properties that Exchange converts using their property ID (16 bits) are known as MNID_ID named property kind. OCPF provides two different ways to define MNID_ID. It can either be a new named property or an existing one which wouldn't have any associated OOM.

MNID_ID named property kind has the following syntax:

MNID_ID:INTEGER:PROPTYPE:IDENTIFIER = [PROPVALUE | VAR]
MNID_ID:INTEGER:IDENTIFIER = [PROPVALUE | VAR]

If the MNID_ID named property doesn't exist within libmapi/conf/mapi-named-property then you must specify its property type.

As described in the example below, the main difference between known and custom MNID_ID named properties is whether or not we specify its property type. If your MNID_ID property has not been referenced within libmapi/conf/mapi-named-property, then you must supply its property type, otherwise you can skip it.

Note: PROPTYPE can be any of the values described in 8. Supported Property Types .

MNID_ID:0x8501:PT_LONG:PSETID_Common = $reminder /* Reminder */
MNID_ID:0x8217:PSETID_Appointment = 0 /* MeetingStatus */


7.3. MNID_STRING

Exchange also supports named properties which do not have a property ID but are described using property names. These named properties are known as MNID_STRING named property kind and Exchange maps these names to a temporary property type.

MNID_STRING named property kind has the following syntax:

MNID_STRING:STRING:IDENTIFIER = [PROPVALUE | VAR]
MNID_STRING:STRING:PROPTYPE:IDENTIFIER = [PROPVALUE | VAR]

MNID_STRING difference between known and custom is the same as MNID_ID one. If the MNID_STRING property doesn't exist in libmapi/conf/mapi-named-properties, then users have to supply its PROPTYPE.

NOTE: PROPTYPE can be any of the value described in 8. Supported Property Types .

Considering the behavior described above, we could set the "Keywords" MNID_STRING named property using any of the following example:

MNID_STRING:"Keywords":PS_PUBLIC_STRINGS = {"one", "two" , "three" }
MNID_STRING:"Keywords":PT_MV_STRING8:PS_PUBLIC_STRINGS = {"one", "two" , "three" }


8. Supported Property Types

8.1. PT_BOOLEAN

OCPF uses the following format for BOOLEAN values:

B"true"
B"false"


8.2. PT_SHORT

OCPF can use any of the following formats for SHORT values:

S0x1234
S32

The short integer can either be in hexadecimal of decimal notation but must be prefixed with a "S" to specify this is a short integer value. If you omit to specify the "S", mismatch property type/value errors will occur while sending the message.

8.3. PT_LONG

OCPF can use any of the following formats for PT_LONG values:

0xdeadbeef
L0xdeadbeef
32

The integer can either be in hexadecimal or decimal notation or prefixed with a "L" to specify this is long value. If you use the hexadecimal notation consider using the 'L' prefixed form since other form may disappear in further versions.

8.4. PT_I8

OCPF uses the following format for PT_I8 (uint64_t) values:

D0x9504000000000001


8.5. PT_DOUBLE

OCPF uses an exponent format for floating point (double) number, as shown in this example:

F3.1415e+03


8.6. PT_STRING8

OCPF defines a string as a set of characters (A-Za-z0-9_) enclosed with double quotes:

"I am a STRING"


8.7. PT_UNICODE

OCPF defines a unicode string as a set of characters enclosed with double quotes and prefixed with W:

W"I am a UNICODE string"


8.8. PT_SYSTIME

OCPF defines date using the following format string:

TYYYY-MM-DD HH:MM:SS

Dates are prefixed with a 'T' character and its content is represented with the syntax below:

  • YYYY: year
  • MM: month
  • DD: day
  • HH: hours
  • MM: minutes
  • SS: seconds
T2008-03-06 22:30:00 /* 2008, 6th of March 10:30:00PM */


8.9. PT_MV_STRING8

PT_MV_STRING8 are arrays ("multiple values") of strings. OCPF defines PT_MV_STRING8 property values as STRING property values separated by commas and enclosed within braces.

{ STRING, STRING, ..., STRING }

At least one STRING property value is required to create a valid PT_MV_STRING8 property. If two or more STRING property values are set, then they must be separated with comma.

{ "single multi-string value" }
{ "one" , "two", "three", "owned" }


8.10. PT_MV_UNICODE

PT_MV_UNICODE are arrays ("multiple values") of unicode strings. OCPF defines PT_MV_UNICODE property values as UNICODE property values separated by commas and enclosed within braces.

{ UNICODE, UNICODE, ..., UNICODE }

At least one UNICODE property value is required to create a valid PT_MV_UNICODE property. If two or more UNICODE property values are set, then they must be separated with comma.

{ W"single multi-unicode value" }
{ W"four", W"five", W"six" }


8.11. PT_BINARY

PT_BINARY are blobs of data. OCPF defines PT_BINARY property values using two different methods. This can either be raw/inline blob of data or filename/external.

If users wish to add raw data blob for a given property, they need to enclose UINT8 (from 0x00 to 0xFF) values within braces. However many cases occur where the data blob is large (such as HTML content; PR_HTML has PT_BINARY property type). In such cases, users may rather prefer to write an external file and specify a filename.

{ UINT8 UINT8 [...] UINT8 }
< STRING >

Note that if the blob of data (raw or pointed by filename) is too large to fit in the property values array, then OCPF will automatically open a stream for the property and write its data in the stream.

PR_HTML = { 0x48 0x65 0x6c 0x6c 0x6f } /* Hello */
PR_HTML = <"/tmp/sample.html">


8.12. PT_MV_BINARY

PT_MV_BINARY are arrays ("multiple values") of PT_BINARY blobs. OCPF defines PT_MV_BINARY propery values as PT_BINARY property values separated by commas and encloses within braces.

{ PT_BINARY, PT_BINARY, PT_BINARY }

At least one PT_BINARY property value is required to create a valid PT_MV_BINARY property. If two or more PT_BINARY are set, then they must be separated with comma.

{ {0x48 0x65 0x6c 0x6c 0x6f}, {0x77 0x6f 0x72 0x6c 0x64}, { 0x21 } } /* Hello world ! */

Note that current implementation does not support the following PT_BINARY format:

< STRING >


8.13. PT_MV_LONG

PT_MV_LONG are arrays ("multiple values") of integers. OCPF defines PT_MV_LONG property values as INTEGER property values separated by commas and enclosed within braces.

{ INTEGER, INTEGER, INTEGER }

At least one INTEGER property value is required to create a valid PT_MV_LONG property. If two or more INTEGER property values are set, then they must be separated with comma.

Also note that PT_MV_LONG are very similar to PT_BINARY in their syntax. The main difference lies in the representation of UINT8 and INTEGER values.

{ 1, 2, 3 }
{ L0x1, 0x123456, 42 }


9. Comments

OCPF files can contain comments embedded in normal C-style comment markers. That is, a comment starts with a combination of / followed by *, and ends with combination of * followed by /.

Anything contained with in comment markers is ignored by the OCPF tools, and is only for the convenience of human readers.

/* This is a comment */

10. OCPF and openchangeclient

OCPF support has been added to the openchangeclient utility. It now has the ability to parse and process OCPF files. Two different options are supported; you can either check an OCPF files' syntax (–ocpf_syntax) or process the files (–ocpf_sender).

Users can set OCPF files using –ocpf-file=filename. Note that you can specify –ocpf-file multiple times if you have split the OCPF contents into different files. However the whole OCPF files you specify must only represent a single message.

Sample OCPF files are provided in the distribution (libocpf/examples), and can also be browsed from the Examples section of this documentation:

10.1 ocpf_syntax

Process specified OCPF files, display syntax errors if detected and dump OCPF context content on standard output.

openchangeclient --ocpf-syntax \
--ocpf-file=libocpf/examples/sample_appointment.ocpf

10.2. ocpf_sender

Process specified OCPF files and create/send a message using OCPF context contents.

openchangeclient --ocpf_sender \
--ocpf-file=libocpf/examples/sample_appointment.ocpf

10.3 ocpf_dump

Process specified MAPI message and generates the corresponding OCPF file on the filesystem.

openchangeclient --fetch-items=Appointment
MAILBOX (1 messages)
|== test ==| : AA13000000000001/20C140000000003
Location: paris
Start time : Sat Mar 29 09:00:00 2008 CET
End time : Sat Mar 29 09:30:00 2008 CET
Timezone: (GMT+01:00) Brussels, Copenhagen, Madrid, Paris
Private: False
Status: Completed
fetchitems : MAPI_E_SUCCESS (0x0)
openchangeclient --ocpf-dump=AA13000000000001/20C140000000003
OCPF output file: 20c140000000003.ocpf
OCPF Dump : MAPI_E_SUCCESS (0x0)

Creative Commons License
Creative Commons Attribution icon Creative Commons Share Alike icon
This content is licensed under the Creative Commons
Attribution ShareAlike License v. 3.0:
http://creativecommons.org/licenses/by-sa/3.0/

openchange-2.0/apidocs/html/libocpf/middle_bg.jpg000066400000000000000000000005251223057412600221020ustar00rootroot00000000000000ÿØÿàJFIFddÿìDuckydÿîAdobedÀÿÛ„ÿÀdÿÄU Q¡Ña‘ÿÚ ?ßÀ#¿ªÚ0 ïæ¶œ ‡3Yû žñݲ ?ÿÙopenchange-2.0/apidocs/html/libocpf/nav_f.png000066400000000000000000000002311223057412600212630ustar00rootroot00000000000000‰PNG  IHDR8³»`IDATxíÝK€ EÑ–·[†øBÑmkâÄÂH—prÓ¼.‚Žó‚ꎤR6Z VI±E‚5j³„lóš›iI˜¬ÞêçJ0ŒÑÑ/Žû›™uøñóÞ¿6sH ÝõyIEND®B`‚openchange-2.0/apidocs/html/libocpf/nav_g.png000066400000000000000000000001371223057412600212710ustar00rootroot00000000000000‰PNG  IHDRô1&IDATxíÝ1 ÁOHf„á_ ->~¸åM iËMèÀƒS½ü‚<IEND®B`‚openchange-2.0/apidocs/html/libocpf/nav_h.png000066400000000000000000000001421223057412600212660ustar00rootroot00000000000000‰PNG  IHDR ,é@)IDATxíÝA @BQ­³šÛ›Ð¢Žáà) )ëý éaÅèÜ¿Æo‡RlÐßIEND®B`‚openchange-2.0/apidocs/html/libocpf/nav_tab.gif000066400000000000000000000014541223057412600215750ustar00rootroot00000000000000GIF89aPæïïïþþþýþýûüúõ÷óñôïøú÷ýýüúûù÷ùöôöòöøõïóíðôîóöñùúøüýûòõðïòìîòëíñëòõïõõõÿÿÿúúúîòìðóîêëéðððôôôñññýýýñôðÆÉÅìîëÇÊÆÈÊÆÏÏÎÇÊÅËÍÊêìéïóîçèæÎÏÍÐÐÐõ÷ôÊÍÉïñíÆÈÄÊÌÊêêéïóìüýüÊËÉÏÏÏèêçÕ×ÓüüûÍÎÌëíêÌÍËíñêÏÐÏùûøêëêòöðóõñÉÊÇñôîîñì!ù,Pÿ€ˆ‰Š‹ŒŽ‘ˆ‚@;/Ÿ ¡¢£¤¥¦§¨E(ƒ )·¸¹º»¼½¾¿À¸ 7„23ËÌÍÎÏÐÑÒÓÔÐ=*"DÝÞßàáâãäåæä8 îïðñòóôõö÷õ.A þÿ H° ÁƒM R ¡Ã‡#JœH±¢ÅŠ0)ˆÀ±£Ç CŠI²$Ɉ8Xɲ¥Ë—0cÊœIsæD-èÜɳ§ÏŸ@ƒ *”¢’*]Ê´©Ó§P£J:Q‚X³jÝʵ«×¯`­È@‚³hÓª]˶­Û·p‰ßÆ@ôÀݻxóêÝË·¯ß¿~O Bð °áÈ+^̸±ãÆ< @@¹²å˘3kÞ̹3gˆr Mº´éÓ¨S«^Ízõ D4 ÈžM»¶íÛ¸sëÞ­»¢Àƒ N¼¸ñãÈ“'·H€óçУKŸN½ºõë×} À½»÷ïàËO¾|y;openchange-2.0/apidocs/html/libocpf/ocpf__context_8c.html000066400000000000000000000353041223057412600236070ustar00rootroot00000000000000 OpenChange Property Files 2.0 API Documentation
ocpf_context.c File Reference

OCPF context API. More...

#include "libocpf/ocpf.h"

Functions

struct ocpf_context * ocpf_context_add (struct ocpf *ocpf_ctx, const char *filename, uint32_t *context_id, uint8_t flags, bool *existing)
int ocpf_context_delete (struct ocpf *ocpf_ctx, struct ocpf_context *ctx)
stat h stat h struct ocpf_context * ocpf_context_init (TALLOC_CTX *mem_ctx, const char *filename, uint8_t flags, uint32_t context_id)
struct ocpf_context * ocpf_context_search_by_context_id (struct ocpf_context *ctx, uint32_t context_id)
struct ocpf_context * ocpf_context_search_by_filename (struct ocpf_context *ctx, const char *filename)

Detailed Description

OCPF context API.

Function Documentation

struct ocpf_context* ocpf_context_add ( struct ocpf *  ocpf_ctx,
const char *  filename,
uint32_t *  context_id,
uint8_t  flags,
bool *  existing 
)
read

Add an OCPF context to the list

Parameters
ocpf_ctxpointer to the global ocpf context
filenamepointer to the
context_idpointer to the context_id the function returns
flagsFlags controlling how the OCPF should be opened
existingboolean returned by the function to specify if the context was already existing or not
Returns
valid ocpf context pointer on success, otherwise NULL

References ocpf_context_init().

Referenced by ocpf_new_context().

int ocpf_context_delete ( struct ocpf *  ocpf_ctx,
struct ocpf_context *  ctx 
)

Delete an OCPF context

Parameters
ocpf_ctxpointer to the global ocpf context
ctxpointer to the OCPF context to delete
Returns
0 on success, 1 if there were still a ref_count, otherwise -1 on errors.

Referenced by ocpf_del_context().

stat h stat h struct ocpf_context* ocpf_context_init ( TALLOC_CTX *  mem_ctx,
const char *  filename,
uint8_t  flags,
uint32_t  context_id 
)
read

Initialize a new OCPF context

Parameters
mem_ctxpointer to the memory context
filenamethe OCPF filename used for this context
flagsFlags controlling how the OCPF should be opened
context_idthe identifier representing the context
context_idthe context identifier to use for this context
Returns
new allocated OCPF context on success, otherwise NULL

Referenced by ocpf_context_add().

struct ocpf_context* ocpf_context_search_by_context_id ( struct ocpf_context *  ctx,
uint32_t  context_id 
)
read

Search a context given its context identifier

Parameters
ctxpointer to the ocpf context list
context_idthe context identifier to use for search
Returns
pointer to valid ocpf context on success, otherwise NULL

Referenced by ocpf_clear_props(), ocpf_del_context(), ocpf_dump_folder(), ocpf_dump_oleguid(), ocpf_dump_recipients(), ocpf_dump_type(), ocpf_get_recipients(), ocpf_get_SPropValue(), ocpf_OpenFolder(), ocpf_parse(), ocpf_server_add_SPropValue(), ocpf_server_set_SPropValue(), ocpf_server_set_type(), ocpf_server_sync(), ocpf_set_Recipients(), ocpf_set_SPropValue(), ocpf_write_auto(), ocpf_write_commit(), and ocpf_write_init().

struct ocpf_context* ocpf_context_search_by_filename ( struct ocpf_context *  ctx,
const char *  filename 
)
read

Search a context given its filename

Parameters
ctxpointer to the ocpf context list
filenamethe filename to use for search
Returns
pointer to valid ocpf context on success, otherwise NULL

Creative Commons License
Creative Commons Attribution icon Creative Commons Share Alike icon
This content is licensed under the Creative Commons
Attribution ShareAlike License v. 3.0:
http://creativecommons.org/licenses/by-sa/3.0/

openchange-2.0/apidocs/html/libocpf/ocpf__dump_8c.html000066400000000000000000000144331223057412600230700ustar00rootroot00000000000000 OpenChange Property Files 2.0 API Documentation
ocpf_dump.c File Reference

ocpf Dump API More...

#include "libocpf/ocpf.h"

Functions

_PUBLIC_ void ocpf_dump_folder (uint32_t context_id)
_PUBLIC_ void ocpf_dump_oleguid (uint32_t context_id)
_PUBLIC_ void ocpf_dump_recipients (uint32_t context_id)
_PUBLIC_ void ocpf_dump_type (uint32_t context_id)

Detailed Description

ocpf Dump API

Function Documentation

_PUBLIC_ void ocpf_dump_folder ( uint32_t  context_id)

Dump OCPF Destination Folder

Dump OCPF Registered Destination Folder

References ocpf_context_search_by_context_id().

_PUBLIC_ void ocpf_dump_oleguid ( uint32_t  context_id)

Dump OCPF OLEGUID

Dump OCPF Registered OLEGUID

References ocpf_context_search_by_context_id().

_PUBLIC_ void ocpf_dump_recipients ( uint32_t  context_id)

Dump OCPF Recipients

Dump OCPF Recipients

References ocpf_context_search_by_context_id().

_PUBLIC_ void ocpf_dump_type ( uint32_t  context_id)

Dump OCPF Type

Dump OCPF Registered Type

References ocpf_context_search_by_context_id().


Creative Commons License
Creative Commons Attribution icon Creative Commons Share Alike icon
This content is licensed under the Creative Commons
Attribution ShareAlike License v. 3.0:
http://creativecommons.org/licenses/by-sa/3.0/

openchange-2.0/apidocs/html/libocpf/ocpf__public_8c.html000066400000000000000000000542271223057412600234060ustar00rootroot00000000000000 OpenChange Property Files 2.0 API Documentation
ocpf_public.c File Reference

public OCPF API More...

#include "libocpf/ocpf.h"

Functions

enum MAPISTATUS ocpf_clear_props (uint32_t context_id)
_PUBLIC_ int ocpf_del_context (uint32_t context_id)
_PUBLIC_ enum MAPISTATUS ocpf_get_recipients (TALLOC_CTX *mem_ctx, uint32_t context_id, struct SRowSet **SRowSet)
_PUBLIC_ struct SPropValue * ocpf_get_SPropValue (uint32_t context_id, uint32_t *cValues)
_PUBLIC_ int ocpf_init (void)
_PUBLIC_ int ocpf_new_context (const char *filename, uint32_t *context_id, uint8_t flags)
_PUBLIC_ enum MAPISTATUS ocpf_OpenFolder (uint32_t context_id, mapi_object_t *obj_store, mapi_object_t *obj_folder)
_PUBLIC_ int ocpf_parse (uint32_t context_id)
_PUBLIC_ int ocpf_release (void)
_PUBLIC_ enum MAPISTATUS ocpf_set_Recipients (TALLOC_CTX *mem_ctx, uint32_t context_id, mapi_object_t *obj_message)
_PUBLIC_ enum MAPISTATUS ocpf_set_SPropValue (TALLOC_CTX *mem_ctx, uint32_t context_id, mapi_object_t *obj_folder, mapi_object_t *obj_message)

Detailed Description

public OCPF API

Function Documentation

enum MAPISTATUS ocpf_clear_props ( uint32_t  context_id)

Clear the known properties from the OCPF entity

Parameters
context_ididentifier of the context to clear properties from
Returns
MAPI_E_SUCCESS on success, otherwise a non-zero error code

References ocpf_context_search_by_context_id().

_PUBLIC_ int ocpf_del_context ( uint32_t  context_id)

Delete an OCPF context

Parameters
context_idcontext identifier referencing the context to delete
Returns
OCPF_SUCCESS on success, otherwise OCPF_ERROR

References ocpf_context_delete(), and ocpf_context_search_by_context_id().

_PUBLIC_ enum MAPISTATUS ocpf_get_recipients ( TALLOC_CTX *  mem_ctx,
uint32_t  context_id,
struct SRowSet **  SRowSet 
)

Get the message recipients from ocpf context

This function gets the recipient (To, Cc, Bcc) from the ocpf context and information stored.

Parameters
mem_ctxthe memory context to use for memory allocation
context_ididentifier to the context to set recipients for
SRowSetpointer on pointer to the set of recipients to return
Returns
MAPI_E_SUCCESS on success, otherwise NULL
See Also
ocpf

References ocpf_context_search_by_context_id().

_PUBLIC_ struct SPropValue* ocpf_get_SPropValue ( uint32_t  context_id,
uint32_t *  cValues 
)
read

Get the OCPF SPropValue array

This function is an accessor designed to return the SPropValue structure created with ocpf_set_SPropValue.

Parameters
context_ididentifier of the context to retrieve SPropValue from
cValuespointer on the number of SPropValue entries
Returns
NULL on error, otherwise returns an allocated lpProps pointer
See Also
ocpf_set_SPropValue

References ocpf_context_search_by_context_id().

_PUBLIC_ int ocpf_init ( void  )

Initialize OCPF context

Initialize ocpf context and allocate memory for internal structures

Returns
OCPF_SUCCESS on success, otherwise OCPF_ERROR
See Also
ocpf_release, ocpf_parse
_PUBLIC_ int ocpf_new_context ( const char *  filename,
uint32_t *  context_id,
uint8_t  flags 
)

Create a new OCPF context

Parameters
filenamethe filename to process
context_idpointer to the context identifier the function
flagsFlags controlling how the OCPF should be opened
Returns
OCPF_SUCCESS on success, otherwise OCPF_ERROR

References ocpf_context_add().

_PUBLIC_ enum MAPISTATUS ocpf_OpenFolder ( uint32_t  context_id,
mapi_object_t *  obj_store,
mapi_object_t *  obj_folder 
)

Open OCPF folder

This function opens the folder associated with the ocpf folder global context value.

Parameters
context_ididentifier of the context to open the folder for
obj_storethe store object
obj_folderthe folder to open
Returns
MAPI_E_SUCCESS on success, otherwise MAPI_E_NOT_FOUND.
Note
Developers should call GetLastError() to retrieve the last MAPI error code. Possible MAPI error codes are:
  • MAPI_E_NOT_INITIALIZED: MAPI subsystem has not been initialized.
  • MAPI_E_INVALID_PARAMETER: obj_store is undefined
  • MAPI_E_NOT_FOUND: The specified folder could not be found or is not yet supported.
See Also
ocpf_init, ocpf_parse

References ocpf_context_search_by_context_id().

_PUBLIC_ int ocpf_parse ( uint32_t  context_id)

Parse OCPF file

Parse and process the given ocpf file.

Parameters
context_idthe identifier of the context holding the file to be parsed
Returns
OCPF_SUCCESS on success, otherwise OCPF_ERROR
See Also
ocpf_init

References ocpf_context_search_by_context_id().

_PUBLIC_ int ocpf_release ( void  )

Uninitialize OCPF context

Uninitialize the global OCPF context and release memory.

Returns
OCPF_SUCCESS on success, otherwise OCPF_ERROR
See Also
ocpf_init
_PUBLIC_ enum MAPISTATUS ocpf_set_Recipients ( TALLOC_CTX *  mem_ctx,
uint32_t  context_id,
mapi_object_t *  obj_message 
)

Set the message recipients from ocpf context

This function sets the recipient (To, Cc, Bcc) from the ocpf context and information stored.

Parameters
mem_ctxthe memory context to use for memory allocation
context_ididentifier to the context to set recipients for
obj_messagepointer to the message object we use for internal MAPI operations
Returns
OCPF_SUCCESS on success, otherwise OCPF_ERROR.
See Also
ocpf

References ocpf_context_search_by_context_id().

_PUBLIC_ enum MAPISTATUS ocpf_set_SPropValue ( TALLOC_CTX *  mem_ctx,
uint32_t  context_id,
mapi_object_t *  obj_folder,
mapi_object_t *  obj_message 
)

Build a SPropValue array from ocpf context

This function builds a SPropValue array from the ocpf context and information stored.

Parameters
mem_ctxthe memory context to use for memory allocation
context_ididentifier of the context to build a SPropValue array for
obj_folderpointer the folder object we use for internal MAPI operations
obj_messagepointer to the message object we use for internal MAPI operations
Returns
MAPI_E_SUCCESS on success, otherwise -1.
Note
Developers should call GetLastError() to retrieve the last MAPI error code. Possible MAPI error codes are:
  • MAPI_E_NOT_INITIALIZED: MAPI subsystem has not been initialized
See Also
ocpf_get_SPropValue

References ocpf_context_search_by_context_id().


Creative Commons License
Creative Commons Attribution icon Creative Commons Share Alike icon
This content is licensed under the Creative Commons
Attribution ShareAlike License v. 3.0:
http://creativecommons.org/licenses/by-sa/3.0/

openchange-2.0/apidocs/html/libocpf/ocpf__server_8c.html000066400000000000000000000240031223057412600234230ustar00rootroot00000000000000 OpenChange Property Files 2.0 API Documentation
ocpf_server.c File Reference

ocpf public API for server side. More...

#include "libocpf/ocpf.h"

Functions

_PUBLIC_ enum MAPISTATUS ocpf_server_add_SPropValue (uint32_t context_id, struct SPropValue *lpProps)
_PUBLIC_ enum MAPISTATUS ocpf_server_set_SPropValue (TALLOC_CTX *mem_ctx, uint32_t context_id)
enum MAPISTATUS ocpf_server_set_type (uint32_t context_id, const char *type)
_PUBLIC_ enum MAPISTATUS ocpf_server_sync (uint32_t context_id)

Detailed Description

ocpf public API for server side.

Do not perform any libmapi calls and trust incoming data. Most of these functions have equivalent in ocpf_public.c or ocpf_api.c

Function Documentation

_PUBLIC_ enum MAPISTATUS ocpf_server_add_SPropValue ( uint32_t  context_id,
struct SPropValue *  lpProps 
)

Add a SPropValue structure to the context

This functions adds a SPropValue to the ocpf context. This property must be part of the known property namespace. If the property already exists in the list, it is automatically replaced with the new one.

Parameters
context_ididentifier of the ocpf context
lpPropspointer to the SPropValue structure to add to the context
Returns
MAPI_E_SUCCESS on success, otheriwse MAPI/OCPF error
See Also
ocpf_server_add_named_SPropValue

References ocpf_context_search_by_context_id().

_PUBLIC_ enum MAPISTATUS ocpf_server_set_SPropValue ( TALLOC_CTX *  mem_ctx,
uint32_t  context_id 
)

Build a SPropValue array from ocpf context

This function builds a SPropValue array from the ocpf context and information stored.

Parameters
mem_ctxpointer to the memory context to use for memory allocation
context_ididentifier of the context to build a SPropValue array for
Note
This function is a server-side convenient function only. It doesn't handle named properties and its scope is much more limited than ocpf_set_SpropValue. Developers working on a client-side software/library must use ocpf_set_SPropValue instead.
Returns
MAPI_E_SUCCESS on success, otherwise MAPI/OCPF error
See Also
ocpf_get_SPropValue

References ocpf_context_search_by_context_id(), and ocpf_server_set_type().

enum MAPISTATUS ocpf_server_set_type ( uint32_t  context_id,
const char *  type 
)

Set the message class (type) associated to an OCPF file.

Parameters
context_ididentifier of the context to set type for
typepointer to the type's string to set
Returns
MAPI_E_SUCCESS on success, otherwise MAPI/OCPF error

References ocpf_context_search_by_context_id().

Referenced by ocpf_server_set_SPropValue().

_PUBLIC_ enum MAPISTATUS ocpf_server_sync ( uint32_t  context_id)

Synchronize data on filesystem

Parameters
context_ididentifier of the ocpf context
Returns
MAPI_E_SUCCESS on success, otherwise otheriwse MAPI/OCPF error

References ocpf_context_search_by_context_id().


Creative Commons License
Creative Commons Attribution icon Creative Commons Share Alike icon
This content is licensed under the Creative Commons
Attribution ShareAlike License v. 3.0:
http://creativecommons.org/licenses/by-sa/3.0/

openchange-2.0/apidocs/html/libocpf/ocpf__write_8c.html000066400000000000000000000202531223057412600232520ustar00rootroot00000000000000 OpenChange Property Files 2.0 API Documentation
ocpf_write.c File Reference

public OCPF write API More...

#include "libocpf/ocpf.h"

Functions

_PUBLIC_ int ocpf_write_auto (uint32_t context_id, mapi_object_t *obj_message, struct mapi_SPropValue_array *mapi_lpProps)
_PUBLIC_ int ocpf_write_commit (uint32_t context_id)
_PUBLIC_ int ocpf_write_init (uint32_t context_id, mapi_id_t folder_id)

Detailed Description

public OCPF write API

Function Documentation

_PUBLIC_ int ocpf_write_auto ( uint32_t  context_id,
mapi_object_t *  obj_message,
struct mapi_SPropValue_array *  mapi_lpProps 
)

Create the OCPF structure required for the commit operation

This function process properties and named properties from the specified mapi_SPropValue_array and generates an OCPF structure with all the attributes required to create an OCPF file in the commit operation.

Parameters
context_idthe identifier representing the context
obj_messagethe message object
mapi_lpPropsthe array of mapi properties returned by GetPropsAll
Returns
OCPF_SUCCESS on success, otherwise OCPF_ERROR
See Also
GetPropsAll, ocpf_write_commit

References ocpf_context_search_by_context_id().

_PUBLIC_ int ocpf_write_commit ( uint32_t  context_id)

Write OCPF structure to OCPF file

This function dumps the OCPF structure content into the OCPF file defined in ocpf_write_init.

Parameters
context_idthe identifier representing the context
Returns
OCPF_SUCCESS on success, otherwise OCPF_ERROR
See Also
ocpf_write_init, ocpf_write_auto

References ocpf_context_search_by_context_id().

_PUBLIC_ int ocpf_write_init ( uint32_t  context_id,
mapi_id_t  folder_id 
)

Specify the OCPF file name to write

Specify the ocpf file to create

Parameters
context_idthe identifier representing the context
folder_idthe folder
Returns
OCPF_SUCCESS on success, otherwise OCPF_ERROR
See Also
ocpf_init

References ocpf_context_search_by_context_id().


Creative Commons License
Creative Commons Attribution icon Creative Commons Share Alike icon
This content is licensed under the Creative Commons
Attribution ShareAlike License v. 3.0:
http://creativecommons.org/licenses/by-sa/3.0/

openchange-2.0/apidocs/html/libocpf/open.png000066400000000000000000000001731223057412600211400ustar00rootroot00000000000000‰PNG  IHDR à‘BIDATxíÝÁ €0 Ð׬ՙ\Àº€39—b!©9{|ðI>$#Àß´ý8/¨ÄØzƒ/Ï>2À[ÎgiU,/¬~¼Ï\ Ä9Ù¸IEND®B`‚openchange-2.0/apidocs/html/libocpf/pixel_grey.gif000066400000000000000000000000531223057412600223240ustar00rootroot00000000000000GIF89a€îîî!ù,D;openchange-2.0/apidocs/html/libocpf/sample_appointment_8ocpf-example.html000066400000000000000000000161511223057412600270110ustar00rootroot00000000000000 OpenChange Property Files 2.0 API Documentation
sample_appointment.ocpf
This example shows a sample OCPF file designed to create a calendar

with the following details:

  • Event starting the 6th of March at 10:00PM and ending at 11:45PM
  • Reminder set 45 minutes before the beginning of event
  • Label set to Anniversary
  • Subject, Body, Location and Private flag set
/*
* OpenChange Property File
*
* Copyright (C) Julien Kerihuel 2008.
*
* Sample appointment
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>
*/
TYPE "IPM.Appointment"
FOLDER "olFolderCalendar"
OLEGUID PSETID_Appointment "00062002-0000-0000-c000-000000000046"
OLEGUID PSETID_Common "00062008-0000-0000-c000-000000000046"
OLEGUID PS_PUBLIC_STRINGS "00020329-0000-0000-c000-000000000046"
SET $subject = "[OCPF] Julien Kerihuel Birthday"
SET $start_date = T2008-03-06 22:00:00
SET $end_date = T2008-03-06 23:45:00
SET $reminder = 45
SET $keywords = { "candles", "friends", "family" }
SET $private = B"true"
SET $wrong = 0
PROPERTY {
PR_CONVERSATION_TOPIC = $subject
PR_NORMALIZED_SUBJECT = $subject
PR_BODY = "Another year, another pleasure"
PR_START_DATE = $start_date
PR_END_DATE = $end_date
PR_SENSITIVITY = 2
};
NPROPERTY {
OOM:BusyStatus:PSETID_Appointment = 9
OOM:ApptStartDate:PSETID_Appointment = $start_date
OOM:CommonStart:PSETID_Common = $start_date
OOM:ApptEndDate:PSETID_Appointment = $end_date
OOM:CommonEnd:PSETID_Common = $end_date
OOM:Location:PSETID_Appointment = W"Home Sweet Home"
/* MeetingStatus */
MNID_ID:0x8217:PSETID_Appointment = $wrong
OOM:Private:PSETID_Common = $private
/* Set a reminder */
MNID_ID:0x8501:PT_LONG:PSETID_Common = $reminder
/* Add categories */
MNID_STRING:"Keywords":PS_PUBLIC_STRINGS = $keywords
};

Creative Commons License
Creative Commons Attribution icon Creative Commons Share Alike icon
This content is licensed under the Creative Commons
Attribution ShareAlike License v. 3.0:
http://creativecommons.org/licenses/by-sa/3.0/

openchange-2.0/apidocs/html/libocpf/sample_task_8ocpf-example.html000066400000000000000000000146301223057412600254150ustar00rootroot00000000000000 OpenChange Property Files 2.0 API Documentation
sample_task.ocpf
This example shows a sample OCPF file designed to create a task with

the following details:

  • Task starting the 6th of March at 8:00PM and ending at 11:00PM
  • Importance set to High
  • Waiting for someone else
  • Subject, Body and Private flag set
/*
* OpenChange Property File
*
* Copyright (C) Julien Kerihuel 2008.
*
* Sample task
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>
*/
TYPE "IPM.Task"
FOLDER "olFolderTasks"
OLEGUID PSETID_Task "00062003-0000-0000-c000-000000000046"
OLEGUID PSETID_Common "00062008-0000-0000-c000-000000000046"
OLEGUID PS_PUBLIC_STRINGS "00020329-0000-0000-c000-000000000046"
SET $subject = "[OCPF] Sample Task"
SET $body = "This is the sample task body"
SET $start_date = T2008-03-06 20:00:00
SET $end_date = T2008-03-06 23:00:00
SET $importance = 2 /* IMPORTANCE_HIGH */
SET $task_status = 3 /* Waiting */
PROPERTY {
PR_CONVERSATION_TOPIC = $subject
PR_NORMALIZED_SUBJECT = $subject
PR_BODY = $body
PR_IMPORTANCE = $importance
PR_SENSITIVITY = 2 /* needed to have private box ticked */
};
NPROPERTY {
OOM:Companies:PSETID_Common = {"OpenChange Project", "Samba Project" }
OOM:StartDate:PSETID_Task = $start_date
OOM:DueDate:PSETID_Task = $end_date
OOM:Status:PSETID_Task = $task_status
OOM:Private:PSETID_Common = B"true"
MNID_STRING:"Keywords":PS_PUBLIC_STRINGS = { "Category1", "Category2" }
};

Creative Commons License
Creative Commons Attribution icon Creative Commons Share Alike icon
This content is licensed under the Creative Commons
Attribution ShareAlike License v. 3.0:
http://creativecommons.org/licenses/by-sa/3.0/

openchange-2.0/apidocs/html/libocpf/sync_off.png000066400000000000000000000015251223057412600220070ustar00rootroot00000000000000‰PNG  IHDRàw=øIDATxíÝKhTWÀñÿä1I&3™8M¦Iš™†I3Ú©b$cÌ I1V1±-(Tö±±Ð.* t!‚K[¥Ä¥ˆ„¨´f£`l(øl©"Y”¤6ÆgÌTú}·sgîܹ ±d{8?æÌ¹÷;çÜuíÚ`:!±F¬¢BäŠ?ŰÄm'yÊÅ>ÑlU¯½üý‰è_‹?€Œê ]€Y(ŠNñ±8fý1°Öqún-eâ¨øtºmâÈ Ó0}b›ù%·©µ×Œ®=Ÿ0´³?Š1sŸ‹0€¯8À‘;_ ‹W|%\ Zð— >舽ln¨p©.aÇ{ )t;Ú b nŸš¯›65°¢¡2çÅÔ?Žž>Oдàuönm¤¢Ì`×­Z¬WjC~>‘Ö¾0+á {{©fÝ×Mæ·æÅ•ìÙ¼˜` Ý›%uA6´½ÅÆö¨Á,]k¢ÄW¼™u±›]‹ˆ7§¯iòh€ ¶¶¬ÏÖu1 ló —Ҷ̺–:ÞÍ\ÄcãÏxøhR²Êè‡Qt$¿ß§¨ ª fdºü<4BÿÙ[•f¸d7=.Mé9/—éªÃëù/ÿO Üaàò}€,‘j?Ÿõ.5Úšm?œÿŸ®ŽXÿ2¬#¸d píæ(£?cÛú¼!½›a1¥Þ—ŽòØ©ܾ7dÔK:‚ùÒ‰ì)Ê3‚Ü™àÌà]€,±H€µ+køöäu<|`·LhC7¹ÔeÍ Ÿ×Ÿ˜tÜ‹ óH$^2%l.êaeÐäýE”ÌÉ|ÅÜìî‰Ýsä }¸ýDû^hzé~ðR›¦Ã¡¿]|#ü¯@×—Ö‡[k¹–<|š(Ç*€Ý¹dÇtMé:Ýñø«Ø,êÅû¢]”' øXÓ_nò¡Æ|Øý /c§fžâOIEND®B`‚openchange-2.0/apidocs/html/libocpf/sync_on.png000066400000000000000000000015151223057412600216500ustar00rootroot00000000000000‰PNG  IHDRàw=øIDATxíÝ_HTYÀñï8ã¤ó§i§4-g6ÆËÕ&kQ)¨Ô!Š0ÒURKÚ…„ê¡/»PEÁ>ìK-+KÁ²Ñ.Y”¾dEPaA‰ø°¥¶›ZSÓïÜ;3wºŠ–¯—߯gfîïœsçœWKÇñ.€ÉøD­¨a‘'¬âq_ôˆk¢ÀŒ ÀDŽøQ´ÄïC¨¶åñÏÿgÅ ñ 0„Y‚:qZ¦Á)~õâ€èLý0HVñ× žz-¿‰C“%¨g¦˜6€é8%Úõ¬ëwêÙUÏ¿˜ª³Ä }? ?€·3ÀÀž©Š À”K• @hà a±ðaÇæUe‹ sù~ë2²ì“&Ú&B*AÄljæºììi*˨,Ëçí»÷oÆ£T”,d[˜¼3-*ÁÀ…>å‡Ë çLÉŸçfk˜Ò éw#*AEjKUy>ûšËÉõ&{µ¢8—m5Ki¬ jjƒD*¿NŽÖigwÃ7Dª’mz骹úKÛ¾±ˆ¶M!æ¤ÍkÐ?šoý¬_åÓlXí#Ò~–¸¬ê×ÒÑXŠÓ‘ùRÙ*Eû‚ՂדðEÜ;6«e"Q(²Ù=–¿Ezæ5Kؼָ_ 1òzBªJë ±XŒì96åªjL^7{ùãJÑ÷1½i@%8'7M©_\Qœ#ÓUŒËñýÿyõ Wo Éx8¼s¥v¯ªì|×SnÜ q_m Ýé î>bèÕí[JX,½4[Tú{R£ë¼ôˆ¾þa€tÝjjzzÅ'ÅìȶiIžŽòwÏs ¡€—ÕKøõâC^ŽŒ˜Y­¨µÉ%6¨´êˆº]vÛðhâ½iWv–hôëê°Ò¨¾'æÌ‚·ñ|[ßìúÅ^€YrD=<ýDû]äÇ÷s€Ïõ‹8™ºCì? À ¨—t4õᩎ¡Jã‡W‹É± îr¼cjMɘìx| šE©øNÔ‰œøA¢þ«–€Z¼ñ‡jó î#™§¢¢4gIEND®B`‚openchange-2.0/apidocs/html/libocpf/tab_a.png000066400000000000000000000002161223057412600212430ustar00rootroot00000000000000‰PNG  IHDR$ÇÇ[UIDATxíK €0C'o¤(Šˆ[Žà%Üxÿ#Ù©­ç ùÁöó¦W¦e# 3t I 3+¼øEã~\D½9¯Ûàè’wM·¿öÿ}Yõ_êA4Yžã}IEND®B`‚openchange-2.0/apidocs/html/libocpf/tab_b.png000066400000000000000000000002471223057412600212500ustar00rootroot00000000000000‰PNG  IHDR$ÇÇ[nIDATxíÝQ Â0„áàœR¥Xc±I7IÓ¨g|òÕÙœäãgY˜3˜Ï÷‡u{£ÔW—ÊSíŒ1Ü ¼CjˆiC†G¬ýççJ+| ÖÝs7ùŒ+Ù›`t‚3Ü‚a¢K¤Gq°ûQÍZÝT=@*éC݇LIEND®B`‚openchange-2.0/apidocs/html/libocpf/tab_h.png000066400000000000000000000003001223057412600212440ustar00rootroot00000000000000‰PNG  IHDR$ÇÇ[‡IDATxíÝË ‚@EÑ 7êÂX’Ñø AADùjGü€ Z€e؈£ ë8¹›—Wƒx¾ÞìUK.µ%„0mɤ&+4iÑ$džÈt“׿ÍzWf5AZá'w¼øÆ"2¶Wœðòg%öªdæ)æþ™ÉR15F®dìž ÉБßO«×Áô»C"à@¯g=IEND®B`‚openchange-2.0/apidocs/html/libocpf/tab_s.png000066400000000000000000000002701223057412600212650ustar00rootroot00000000000000‰PNG  IHDR$ÇÇ[IDATxíÝ ‚@@Ñ£?Q…¤"š¢%¦I‘—Šf–6[´HÃäQƒ<Þâõþ]ždr Í’s?ˆO=Ñññw'ÌF‡Ž íðö-~rÃ[œèŠ­ì¬mƒÖ¬ƒݯнŠÕF)Yº% §`nÌ,9B ™’©!ÑŒ\ý<Å#üîî•IEND®B`‚openchange-2.0/apidocs/html/libocpf/tabs.css000066400000000000000000000022131223057412600211310ustar00rootroot00000000000000.tabs, .tabs2, .tabs3 { background-image: url('tab_b.png'); width: 100%; z-index: 101; font-size: 13px; font-family: 'Lucida Grande',Geneva,Helvetica,Arial,sans-serif; } .tabs2 { font-size: 10px; } .tabs3 { font-size: 9px; } .tablist { margin: 0; padding: 0; display: table; } .tablist li { float: left; display: table-cell; background-image: url('tab_b.png'); line-height: 36px; list-style: none; } .tablist a { display: block; padding: 0 20px; font-weight: bold; background-image:url('tab_s.png'); background-repeat:no-repeat; background-position:right; color: #283A5D; text-shadow: 0px 1px 1px rgba(255, 255, 255, 0.9); text-decoration: none; outline: none; } .tabs3 .tablist a { padding: 0 10px; } .tablist a:hover { background-image: url('tab_h.png'); background-repeat:repeat-x; color: #fff; text-shadow: 0px 1px 1px rgba(0, 0, 0, 1.0); text-decoration: none; } .tablist li.current a { background-image: url('tab_a.png'); background-repeat:repeat-x; color: #fff; text-shadow: 0px 1px 1px rgba(0, 0, 0, 1.0); } openchange-2.0/apidocs/html/mapiproxy/000077500000000000000000000000001223057412600201025ustar00rootroot00000000000000openchange-2.0/apidocs/html/mapiproxy/24px-Cc-by_white.svg.png000066400000000000000000000053061223057412600243420ustar00rootroot00000000000000‰PNG  IHDR°çá»bKGDÿÿÿÿÿÿ X÷Ü pHYsHHFÉk> IDATXýXmP”U¾vˆeY pW$gQH–%ãËc*$åÃIkFmiØ‘ttrê‡C öa3 Œc†D$ e¬±X, «@³ Â.Èîõþy›uÓ÷·÷úóÌœçÜϹîëºçÜç<þxHØNÛNÛN½+zWô®.–_,¿X|»æÛ5ß® Q†(C`4F#p×ý®û]w@qRqRqðÿÎÿ;ÿcaÇÂŽIÅIÅIÅ@˜$L&Ämâ6qÛòÀ‡Ä-í-í--ùVë[­oµ’ <. … ¡B¨øSRT(*’’IŽ$‡”æHs¤9¤S’S’S‰ð>°Ï÷ˆôˆôˆ$Óôiú4=Ù2Ú2Ú2JZ•V¥Uù`^‚û9À3<Ã3À7ýßôÓl?Ø~°¸ªºªºªœ‡œ‡œ‡€ 6Øpx&õ™ÔgR0—0—0ÀMá¦pSB©P*”–õ–õ–õ@²GÙ£šª›ª›ª¦mMÛš¶#êõˆðj÷j÷jöeïËÞ— äÎäÎäÎÒ^i¯´÷að£ýȳégÓϦ“K{–ö,í±+¦êRu©ºÈŠÎŠÎŠNòöÔí©ÛSë£sñsñsñd{^{^{™u%ëJÖÒÅÛÅÛÅ›IER‘”ÔìÕìÕì%ÇSÇSÇS~gAuuu¤|µ|µ|5)øJð•à+rGËŽ–-äÀ±cÇþs‚å)ËS–§ÈÒ-¥[J·ž»=w{î&µ‚ZA-™÷BÞ y/³£³£³£‹$psäæÈÍR•¨JT%ÚßñýŽïw|OšÌ&³Éü¿'þWX­ÖFòÔ“§ž<õ$é6â6â6Bºæ»æ»æ“ÕÕÕ÷&°Ÿû¹Ÿ<”p(áP‚xxQxQxyëÀ­·üóÄÿŠùçœÿ‘Ô®Ô®Ô®´óŠx.⹈çÈÁÎÁÎÁN7ŽÜ8rã¹æÙ5Ï®y–tŠwŠwŠ'+++ÿÿÄÿŠã€qÀH¿üzðë¤(H$ "‹4Eš" ) ø0àÀ:³ñÌÆ3··7à é é  pNwNwN¦º¦º¦º€ZS­©Ö\K¹–r-èÎíÎíΆg†g†gOgOgOgÀ˜bL1¦õâzq½XÒ·¤oI SÊ”2%033TÿQýGõ€h§h§h'àëëkßdÜÜÝÜÝ܉sç&Î õ õ õÀ¸iÜ4n°uÕÖU[WÙ-*4š ©õ^^^r¹Ãr‡å¤S•S•SéêêJºMºMºM’»rwåîÊ%ûûûIE¤"RIîÙ¼góžÍäÜÆ¹sÉý'öŸØ‚”'Êå‰dÛ–¶-m[îï„N£Óè4¤ÇÛo{¼MŠä"¹HN {]z]z]Ñ:Ñ:Ñ:@¥T)UÊE¶Û!q¸k¾k¾k2e™²LÐÛÛ ¤½Ÿö~ÚûÀ¥ÉK“—&ÿVÿVÿV c.c.c¨­­Ê®•]+»œK>—|.ˆÔDj"5@[t[t[4 _ª_ª_ºpýÕΫW;>Y>Y>Y€õwëïÖ߈§ÄSâ)R'‰“Ä‘Í7›o6ß\¨€Ál0̤¼SÞ)ï$ƒR‚R‚RÈ—3_Î|9“ô³øYü,dÒ¤I7H‹ŸÅÏâGöÕôÕôÕAùAùAù¤Ä 1H dÈùó!çɲÀ²À²@R\".—Å?ÿTüÓÂõïîîÈ(×(×(W{Åç:æ:æ:¡£ÐQèˆÒDi¢´E:žAª U L©§ÔSj`$a$a$pLvLvL†¶mÚ VVV~‰~‰~‰À®_wýºëWÀrÄrÄrÈPf(3”ÀóåÏ—?_|ôÉGŸ|ô ·!nC܆E–o4 šQ¨(Tj*ŠÅŠb`V2+™•o‹·Å{±– ‚€5Ôj Ò­éÖt+P¡þBý ðzáõÂë@÷+ݯt¿èôú{x`c`c`#à~Úý´ûi À` °K>_òù’ϵ«ÚUí È5r\³È!2Ï–g˦ççÃïy}9úrôe»%%×K®—\_¤„ú }†>R!UHRò1ŸÇ|ó!ãZãZãZIe´2ZM.»³ìβ;d{{{¿=¾á†7Þ =.x\ð¸@Ö)ë”uJ²¥­¥­¥\öȲG–=B~œúqêÇ‹z²{²{²Iß}¾û|÷ÝSBª¯U_«¾¶'ÔTßTßTÌý6÷ÛÜoöqéyéyéyàÅÒK_,ÔoªßT¿ xj=µžZ F#‘'kOÖž¬B2B2B2ìñò+ò+ò+ÀK›^ÚôÒ&@Þ!ïw2³Ì,3¿Düñ  ($ ÉBt't't'€Á̓›7+›V6­lÐÜÜL>ŠGñ(Hï×¼_ó~¼úóÕŸ¯þ|5¬a iK±¥ØRH[€-À@Ú²mÙ¶l’{¸‡{þ¦#íænî&mkmkmkIÆ1Žq$ýéOÒ*° ¬Òö¥íKÛ—ö°™’™’™2ùpòáäÃvås r r H˜½Ì^f/r[Ö¶¬mYö Y]Y]Y]¤ùóæþávû7¨\W¹®r)žψgHŸ­>[}¶’º]‰®äžÃ\K]K]KéuÉë’×%Rü©øSñ§di|i|i#FQ`$c¼b¼b¼ÈŽ‹;.Þ_€^êg3f3f3Èʵ•k+×’êUêUêU¤Ãr‡åËIÇq'=4 ¹~lýØú12*+*+*‹ŒÍÍÍ'Ueª2Uéû®ï»¾ï’!!!v¥W„­[FjõZ½VO' ' '<ØÁ‡þ+ñ'†††È¢²¢²¢22\® ב2™ƒÌNèAOßbßbßb2Ç%Ç%Ç…ÔéuzžœŸŸx>ÿ^5¡–ü+^:tEXtComment Created with Inkscape (http://www.inkscape.org/) ã+ldIEND®B`‚openchange-2.0/apidocs/html/mapiproxy/24px-Cc-sa_white.svg.png000066400000000000000000000053061223057412600243330ustar00rootroot00000000000000‰PNG  IHDR°çá»bKGDÿÿÿÿÿÿ X÷Ü pHYsHHFÉk> IDATXÕX}LÓW>¿ ´–.Ôb±‚" Cèê(lS„9ÉuN&n ʹŒ,+&+™“à&3[a`Ë$™ãs‰3Ö¨L(ŠX¸Åñá¬EÄ4ElK¡åyÿy÷–¼µ/¾çŸ›ÜsŸsžûœÓ{· þmô”¶ðà?¬Y3²†èBý…ú õD—7\ÞpyÑpâpâp"‘Ñh4DóÏÌ?3ÿ QPmPmP-QØoa¿…ýFw"îDÜ ¢ŒÊŒÊŒJ¢8n7ŽKäwÃï†ß§eCDxJ3›ŠMÅÀgW?»úÙU ‚‰`"€Ä bý#À>Ê>Ê> p ¸Ü€WÀ+àË3–g,Ïèú†¾q¯Ø°%` ===è&tº ÀéŠtE.Í‹ñVœÁœ!ºxçâ‹wˆ>5|jøÔ@Ô#ë‘õȈ|Ç|Ç|Lj^,z±èÅ"¢m»·íÞ¶›(Žljãùùù±x,‹G4;;K499IÔÞÚÞÚÞJÔ¾§}Oû"s‚9Áœ@$4 BQa~a~a>Ñ!Û!Û!o„7Âyš ¬Çz¬ßi|§ñ`ÕЪ¡UCnÅdý²~Y?ÐÔ×Ô×ÔLÍLÍLÍÂGø8¶ãØŽc;ÜÄãËãËãËS‘©ÈTäxÏ®ž]=»€Wv^Ùy´ Z­SÏÔ3õ‹~Ü&¶‰mÄ_‰¿ ;v( 05›šMÍžqÝÎng7P¼¶xmñZwœ—^éõ—^îõÝë»×Ð`é`é`)°áµ ¯mx Xž²äeò2y™'ñA„ B”ØJl%6 nUݪºU€*Z­ŠÄÄÄ“Ïä3€å[Ë·–o½ãq·qØkÝkÝkõl¥ÏÕŸ«?W{Â?~< $®H\‘¸Â½Þg®w®w®—ˆ³Œ³Œ³ŒˆÍÎfgQuQ—§¯È_‘¿"'Ò˜5f™Hë¯õ×úûëØ_Çþ"âïçïçïÿß.ëi=­'ò©õ©õ©õtϧϧϧ{Î3LÓAÄ–²¥l)éHG:"VPePeP%‘ƒëà:¸D³³³ÞóOØ'ìv¢Õ©«SW§åìËÙ—³È,7ËÍr"G…£ÂQá?—7—7—G4ùóäÏ“?{ú\WÀõœ_P-¨TDÖxk¼5~‘ckçÖέî’TýQõGÕÞ;à|Öù¬óY@ÀÉ€“'Þ:Þ:Þ:@œ&N§cccÞñÝ‚nA·ý$úIô“;/š?ÍŸtƒºAÝN¡¡ü¡ü¡| ¤0¤0¤pQë}RôIÑ'¯³¾ÎúpŒ9ÆO 2Z3Z3ZÄŒ9s㇓w%ïJ޴ŶŶÅwDwDwDÀÅ÷/¾ñ}`Ëw[¾Ûò'îÍóožó<`}×ú®õ]ϼgfÏÌž™XZ––¥Ö¶¯m_ÛP‡¤CÒ!$ ~ø!ÐógÏŸ=zW²V]«®Uœ:N§n¡(Š¢(À?Ê?Ê? Í Í Íxž…gñ$ê u…º€®³]g»Îzæ±UÙªlU€¼D^"/Yto¨ Ôj€ìB»Ð.ö(ö(ö(Ü ýŠ~E?`ï²wÙ»<;„¡ChÞм¡y±D,ë 7ò¬V +Ø”»)wS.pI}I}Ií]¨æèæèæhÀÏægó³Á™Á™Á™€¾J_¥¯Zô1§Óê´:- ¼"¼"¼ø}ï÷½ß÷@uJuJu àZp-¸<8wþîü0ì7ì7ìJ5¥šR ùwæß™ÛÓ·§oOÞî|»óíNà”ñ”ñ”ý–ý€~@Äì‹Ù³Ï-@qqq?° ].HmÀ5åšrMǧOŸXm¬6V°²deÉÊàtÆéŒÓ€óWç¯Î_½'F ZÐ8ßs¾ç|˜+Ÿ+Ÿ+\®W€ILbÒ;ü¦ô¦ô¦ØÜ°¹asƒ›xÒñ¤ãIÇñeãËÆ—¹×{¼   ¥F©QjV:+•ð[ø-ü@=®W÷ÎÝ;wïÜÒ„–2[Ž-Ç–4O7O7O76nlt—<”<”<zózózó<ñ^ßÄ–dK²%PVVx¾<_ž/À\b.1—I¶$[’ |Éÿ’ÿ%Ðwê;õÀdÅdÅd` ³†YÃk‹µÅÚÌlÙ:³>0|`øP¯®W׫ù«òWå¯Ü:n·`ŒŒ‘1IÂ$a’è½Ð{¡÷‚w–|Ô;ö:ö:öÍÏ7?ßü<šš øˆ}Ä>b€4¤!   P(ØÉØÉØI Q‘¨HTÉG’$d5²Y r2ädÈIÀçŸ|^p+½&nMÜš8 x x xß1¾c|ÇÒ|ê%þ±±gÇž{(¯)¯)¯âõñúx=àÃ÷áûð—>…þC*C*C*N§€èôúÀ™âLq¦<=ŸYΧюéÈ:tEXtComment Created with Inkscape (http://www.inkscape.org/) ã+ldIEND®B`‚openchange-2.0/apidocs/html/mapiproxy/CC_SomeRightsReserved.png000066400000000000000000000064521223057412600247500ustar00rootroot00000000000000‰PNG  IHDRZ¬a x pHYs  šœtIMEÕ ÌIðbKGDÿÿÿ ½§“ ·IDATx^í™iŒUEÇû¾{ßÚÝ6ë"²Š‚@!`˜DÇ¡Ä "Œ2 ×%Æ(ê—D£ñƒ1¨â’Œ@Pƒ¢HezXš¦é†¶~¯ßrç÷ïÜêyV¼ 1í„VòçÔz«þuêÔ¹÷9%¿Nr@$Bd\ºP¤Ç¤KˆÒ•HD€’È|² È h‘,Ò›= lœ)Ò›Íøí´2$Ù"ír«,n¤…˜Õ?À+B¸4d¤à `d‘ž—Þ†vL‘_‰h×&By#Äl ,‹OHIÚyû¤Ø°N‡¤g¡èäÒùnÑ‹0 g­Kë!í i6IÁ¶dËŠ…‚bÉFÝ?Ÿ-ÚŠ°áÙ–eÈO&“‰gŸ}vä–-[¦œ8qâŽ\.7çÌ™3Ó÷ìÙ3áý÷ß¿büøñÝdÉňÅb©Ç{lÐ÷ßÿ‡ãÇÏ ÏÜæææ¿8p`ÎòåË+§L™ÒËz– {®ƒö½´Ú?Å­cݦ[e‰â²áÇw]¶lÙ´¾}ûBfxrçfÞ_|±»bÅŠ!ƒ *ÿ}]xÍÒ’V™OŸï ¤­{–.¸Xrì“O>ù“!yûöí 7ß|óêT*õwÊÖ<óÌ3ûNž<™S]±%Óg˜!yóæÍM7ÞxãÚÒÒÒ¥lÀâW^yeÝéÓ§3ª3Ï q5nHÞÎW‹ŽXVœ ½ÄŒ/¾øâè|p¢Ø·o_ãСC¿J§Ó­‘ˆÁ€Ê>ûì³—^ziµÚÍŸ?¿âÕW_í!}çΧG޹9“ÉüÄZ9%.}*{öì¹ð,–kK»¬p>Z´‰s£[å6\ÉÊÊÊ¡f€—_~ù_±#“½{÷:|ÈlÒ­·ÞÚÁôyþùç Ù³ýð¶mÛÒ¼È ýG2$ïXh—äµ?Ñá °7£OŸ>ÝÍøéc¶»Q+êp±ú˜é³råÊûb³78¶ 1Ë@Îï8ڱɷõb²ñÑqÓøÈ‘#9Ûê‹`ÜI²¢¢¢mîÇŽioŠÉ ß\#C²†óÐu„è>ˆ„µÃU´˜L÷îÝcöÆXäy Ååè›>;wöl²Î‘<'l íî:|ßïÐ^ƒmܸÑûâ‹/R555‰£G&!#ÉÍŸjiiI€$~4‘ÍfS<3U(ù|>!YWW÷Ã%—\ÒScÜvÛm=Þyçã´ñ€ "À´a¤<²y×®]±Ñ£G»êsÓM7¥/^|š0γD"qd©)D£Ñ‚ëº>(ñ<Ï!ïÁD€KÄâ^pÁ^×®]½þýûGG»æšk²í壎hÿ—ì&t¯ºêªDÇŽSç/‰ü1Á DB„Cr²“È/ñï¾û®Ú=oÞ¼Á«V­Ú€•»l‚ ’ýnݺ9o½õVçIˆË}ùå—ˆ.UŸ‡z¨ÓºuëWsvIž€ï/ýõ×õÒò7òˆ|P"‚ãñx+ɉDB$ srª¢½{÷Ž:êtåI¿”§VKqöÆç>8dF°4Y³‡èä©S§â”'xÃK@r\0dƒ¸ÈfÑ©×^{m . \ãa_¸pa͆ 2eee¥×]w]§Ù³gwÁÚ´‘GÔF$}øá‡{õêå)_UUuúÍ7߬ٺuë:uÊOœ8±ãÔ©SB^ ‹ÿ+äf »b3œ¡:@†x= Ùiü~¦C‡é.]º¤ÙØ QN3ýE´c‘z.ût Ñã• 'ôÜwÒœC‡űæ8¯Ã²è˜ˆ†ä¸¬ZRD$Çò²êaX—ûî»od—…ÎÜ÷Kn¸á†ƒÈV]ÀêܧŸ~ºë…^;[Ÿ»îºk‘!¤A‹ò\ÂÑ­`#Óll Va61­S`Nz8ܧžzêrë±Ñ%amŠÛâE`)$¤°ž$H±¨V“ÿMqEJÒYd î¯]»¶™§Øƒÿ›P¨¯¯ÏàN¾ñÆGñë9Ú°´zvÍš5M¸™,㔀ˆéÓØØxŠ7ÌÚ?þx#d·@bIyy¹ƒŒX¯ "Pç"=ê$]¤GY4„#Ût›3ÆG;ç°3þ9„>>ĉ´$DuAZ ×!b£" –%G%!$J[å¥{HwQ © ô­KQÒEF°´¶èEV òëׯo¤_=$çØì2+ g±È,® Ɔ—°yÅ £ e¾Ñ6/ÊI?%&)’€hî£ëtt´^~ä}‘Œlõ딹ä[A>á’Q ’uZZ@–òlȧÒPÂmiÝ1”àp_ä‡í¤Êb<‘*²Ñ•$[‰ HÑ’Ê»"2% Éå!URd;"8€X³’¤A„ä—ä{$‘/QˆDIr³Áüäzb¤2«r…ƒg#ÖÒC91á]…UîôIaÖl„N^£+ŽÕÊÛˆ’Fò’&/˜ÐN1´¤±nG©Øª€acÝH§ØºE0R¹²æ"Œ/=t?´¡`.ÄšM:«±àDæÎ;ž[ÎsÏ=7’ ©O¿~ýoûh#Øåy›6mêÅGšÞ¯{T¦~Lêµ½þúë')o±^N})Ÿ9ï Þüî»ï*ÔJ¦HcÇŽ­ä¢Ià³Ëˆ›¯ tÅÇû¡„V1.¢èôéÓ/G÷„Ûo¿}0Ò%Vî?cÆŒA?üpß%K–t&Bé‡/¯Ï&JP[éJÖ¼ûþùç=xNœ‹-~íµ×þž—¡±<çwšÃK/½4Œ²Ê÷Þ{oëÓúèÞξ¥s eKu¤¦M›¶öJW;AþLõÒ L×°Œpn¹üŸ1WCBšèá«Ã‡¯¡,W]]ý-ñmý#zTܨêŠ]ª)ã›ù)Þ./“.‹Þüõ×_ïâm*Ë—³²œÊ£ó Ü|°wÑ¢E²¦¶zŽHžÎ°ÓÊÛàRÛ*ÿ©yŽì¼*^`ªd‘¼Ììfü<ñî>\×q^:²lÈA¬þ ãØ"H¯­­=Ì‹Pý ’K—.=¦·?Œ¢^yÕ ¤Z¾›R‘Ìiiâ µ«Ý¯2æšÁ5œàÌ.>­V3FÒªpaÛ5Oꛃµl1ëÓéxüñÇkUÆÿ’UãÆ;‰;Ép¯l ã@ÙŠèý úÉ'Ÿlš5kÖIÞós¼Å€”ê=zäT/BL;£•W Ê[¨D*ǹŽ;@ãÖæRúa&œƒ˜zȯg¬ßEØ€£ÒqeÇ8ÒÒ% I—ظ33gÎLKW½ú©þ»‰gæÉ7˜ñ±ò:=bk™GíO%ƒŽñ}CãÙQQ mEõLŽzÏÌ«LÏ4m!ÚçBup›)½ä´­Å¬¿ÃÊÇá.è7±ÏÅáCŒÏDýÝ»wûJøÈVië,ºµíœ9s|;Ùí¹©}.Ÿ”aŒ>dû,ÆçHZ}Btk¾çöL{®öv}ø8Òq¡¡˜²!C†ø&Lðq]¾DÿÊé7üFôÿÿj|w‚%&IEND®B`‚openchange-2.0/apidocs/html/mapiproxy/annotated.html000066400000000000000000000063021223057412600227460ustar00rootroot00000000000000 MAPIProxy 2.0 API Documentation
Data Structures
Here are the data structures with brief descriptions:
oCEphemeralEntryIDEphemeralEntryID structure
oCmpm_streamA stream can either be for a message or attachment
\CPermanentEntryIDPermanentEntryID structure

Creative Commons License
Creative Commons Attribution icon Creative Commons Share Alike icon
This content is licensed under the Creative Commons
Attribution ShareAlike License v. 3.0:
http://creativecommons.org/licenses/by-sa/3.0/

openchange-2.0/apidocs/html/mapiproxy/apidocs.css000066400000000000000000000362151223057412600222450ustar00rootroot00000000000000/* ** WEBSITE ** */ BODY,H1,H2,H3,H4,H5,H6,P,CENTER,TD,TH,UL,DL,DIV { font-family: Geneva, Arial, Helvetica, sans-serif; } BODY,TD { font-size: 90%; } H1 { text-align: center; font-size: 160%; } H2 { font-size: 19px; font-weight: bold; color: #3E93D5; } H3 { font-size: 100%; } P { text-align: justify; } LI { li-style-type: square; li-style-position: outside; display: list-item; } CAPTION { font-weight: bold } DIV.qindex { width: 100%; background-color: #e8eef2; border: 1px solid #84b0c7; text-align: center; margin: 2px; padding: 2px; line-height: 140%; } DIV.nav { width: 100%; background-color: #e8eef2; border: 1px solid #84b0c7; text-align: center; margin: 2px; padding: 2px; line-height: 140%; } DIV.navtab { background-color: #e8eef2; border: 1px solid #84b0c7; text-align: center; margin: 2px; margin-right: 15px; padding: 2px; } TD.navtab { font-size: 70%; } A.qindex { text-decoration: none; font-weight: bold; color: #1A419D; } A.qindex:visited { text-decoration: none; font-weight: bold; color: #1A419D } A.qindex:hover { text-decoration: none; background-color: #ddddff; } A.qindexHL { text-decoration: none; font-weight: bold; background-color: #6666cc; color: #ffffff; border: 1px double #9295C2; } A.qindexHL:hover { text-decoration: none; background-color: #6666cc; color: #ffffff; } A.qindexHL:visited { text-decoration: none; background-color: #6666cc; color: #ffffff } A.el { text-decoration: none; font-weight: bold } A.elRef { font-weight: bold } A.code:link { text-decoration: none; font-weight: normal; color: #0000FF} A.code:visited { text-decoration: none; font-weight: normal; color: #0000FF} A.codeRef:link { font-weight: normal; color: #0000FF} A.codeRef:visited { font-weight: normal; color: #0000FF} A:hover { text-decoration: none; background-color: #f2f2ff } DL.el { margin-left: -1cm } .fragment { font-family: monospace, fixed; font-size: 95%; } PRE.fragment { border: 1px solid #CCCCCC; background-color: #f5f5f5; font-size: 11px; margin-top: 4px; margin-bottom: 4px; margin-left: 2px; margin-right: 8px; padding-left: 6px; padding-right: 6px; padding-top: 4px; padding-bottom: 4px; } DIV.ah { background-color: black; font-weight: bold; color: #ffffff; margin-bottom: 3px; margin-top: 3px } DIV.groupHeader { margin-left: 16px; margin-top: 12px; margin-bottom: 6px; font-weight: bold; } DIV.groupText { margin-left: 16px; font-style: italic; font-size: 90% } BODY { background: white; color: black; margin-right: 20px; margin-left: 20px; } TD.indexkey { background-color: #e8eef2; font-weight: bold; padding-right : 10px; padding-top : 2px; padding-left : 10px; padding-bottom : 2px; margin-left : 0px; margin-right : 0px; margin-top : 2px; margin-bottom : 2px; border: 1px solid #CCCCCC; } TD.indexvalue { background-color: #e8eef2; font-style: italic; padding-right : 10px; padding-top : 2px; padding-left : 10px; padding-bottom : 2px; margin-left : 0px; margin-right : 0px; margin-top : 2px; margin-bottom : 2px; border: 1px solid #CCCCCC; } TR.memlist { background-color: #f0f0f0; } P.formulaDsp { text-align: center; } IMG.formulaDsp { } IMG.formulaInl { vertical-align: middle; } SPAN.keyword { color: #008000 } SPAN.keywordtype { color: #604020 } SPAN.keywordflow { color: #e08000 } SPAN.comment { color: #800000 } SPAN.preprocessor { color: #806020 } SPAN.stringliteral { color: #002080 } SPAN.charliteral { color: #008080 } .mdescLeft { padding: 0px 8px 4px 8px; font-size: 80%; font-style: italic; background-color: #FAFAFA; border-top: 1px none #E0E0E0; border-right: 1px none #E0E0E0; border-bottom: 1px none #E0E0E0; border-left: 1px none #E0E0E0; margin: 0px; } .mdescRight { padding: 0px 8px 4px 8px; font-size: 80%; font-style: italic; background-color: #FAFAFA; border-top: 1px none #E0E0E0; border-right: 1px none #E0E0E0; border-bottom: 1px none #E0E0E0; border-left: 1px none #E0E0E0; margin: 0px; } .memItemLeft { padding: 1px 0px 0px 8px; margin: 4px; border-top-width: 1px; border-right-width: 1px; border-bottom-width: 1px; border-left-width: 1px; border-top-color: #E0E0E0; border-right-color: #E0E0E0; border-bottom-color: #E0E0E0; border-left-color: #E0E0E0; border-top-style: solid; border-right-style: none; border-bottom-style: none; border-left-style: none; background-color: #FAFAFA; font-size: 80%; } .memItemRight { padding: 1px 8px 0px 8px; margin: 4px; border-top-width: 1px; border-right-width: 1px; border-bottom-width: 1px; border-left-width: 1px; border-top-color: #E0E0E0; border-right-color: #E0E0E0; border-bottom-color: #E0E0E0; border-left-color: #E0E0E0; border-top-style: solid; border-right-style: none; border-bottom-style: none; border-left-style: none; background-color: #FAFAFA; font-size: 80%; } .memTemplItemLeft { padding: 1px 0px 0px 8px; margin: 4px; border-top-width: 1px; border-right-width: 1px; border-bottom-width: 1px; border-left-width: 1px; border-top-color: #E0E0E0; border-right-color: #E0E0E0; border-bottom-color: #E0E0E0; border-left-color: #E0E0E0; border-top-style: none; border-right-style: none; border-bottom-style: none; border-left-style: none; background-color: #FAFAFA; font-size: 80%; } .memTemplItemRight { padding: 1px 8px 0px 8px; margin: 4px; border-top-width: 1px; border-right-width: 1px; border-bottom-width: 1px; border-left-width: 1px; border-top-color: #E0E0E0; border-right-color: #E0E0E0; border-bottom-color: #E0E0E0; border-left-color: #E0E0E0; border-top-style: none; border-right-style: none; border-bottom-style: none; border-left-style: none; background-color: #FAFAFA; font-size: 80%; } .memTemplParams { padding: 1px 0px 0px 8px; margin: 4px; border-top-width: 1px; border-right-width: 1px; border-bottom-width: 1px; border-left-width: 1px; border-top-color: #E0E0E0; border-right-color: #E0E0E0; border-bottom-color: #E0E0E0; border-left-color: #E0E0E0; border-top-style: solid; border-right-style: none; border-bottom-style: none; border-left-style: none; color: #606060; background-color: #FAFAFA; font-size: 80%; } .search { color: #003399; font-weight: bold; } FORM.search { margin-bottom: 0px; margin-top: 0px; } INPUT.search { font-size: 75%; color: #000080; font-weight: normal; background-color: #e8eef2; } TD.tiny { font-size: 75%; } a { color: #1A41A8; } a:visited { color: #2A3798; } .dirtab { padding: 4px; border-collapse: collapse; border: 1px solid #84b0c7; } TH.dirtab { background: #e8eef2; font-weight: bold; } HR { height: 1px; border: none; border-top: 1px solid black; margin-bottom: 50px; } /* Style for detailed member documentation */ .memtemplate { font-size: 80%; color: #606060; font-weight: normal; } .memnav { background-color: #e8eef2; border: 1px solid #84b0c7; text-align: center; margin: 2px; margin-right: 15px; padding: 2px; } .memitem { padding: 4px; background-color: white; border-width: 1px; border-style: solid; border-color: #ccc; -moz-border-radius: 8px 8px 8px 8px; margin-bottom: 30px; } .memname { white-space: nowrap; font-weight: bold; font-size: 12px; margin: 10px 10px 10px 10px; } .memname EM { color: #45417e; } .memdoc{ padding-left: 10px; padding-right: 10px; } .memdoc EM, TD { font-size: 12px; } .memproto { background-color: #e9e9f4; width: 100%; border-width: 1px; border-style: solid; border-color: #ccc; font-weight: bold; -moz-border-radius: 8px 8px 8px 8px; } .paramkey { text-align: right; } .paramtype { white-space: nowrap; } .paramname { color: #602020; font-style: italic; white-space: nowrap; } /* End Styling for detailed member documentation */ /* for the tree view */ .ftvtree { font-family: sans-serif; margin:0.5em; } .directory { font-size: 9pt; font-weight: bold; } .directory h3 { margin: 0px; margin-top: 1em; font-size: 11pt; } .directory > h3 { margin-top: 0; } .directory p { margin: 0px; white-space: nowrap; } .directory div { display: none; margin: 0px; } .directory img { vertical-align: -30%; } #website { width: 820px; height: 100%; margin-left: auto; margin-right: auto; text-align: left; /* IE hack */ * position: absolute; * left: 50%; * margin-left: -410px; } /* ** HEADER ** */ .header { height: 200px; background: url(header.jpg) no-repeat top center; } body { background: #fff url(body_top_bg2.jpg) top left repeat-x; font-family: Arial, Trebuchet MS, Tahoma, Verdana, Helvetica, sans-serif; font-size: 11px; line-height: 17px; color: #444; color: #3a3a3a; fdpadding-top: 15px; text-align: center; background-color: #fbfbfb; } h1 { font: 24px bold Trebuchet MS, Arial; color: #FFF; padding: 0; margin: 0; } /* ** MIDDLE SIDE ** */ #middle_side { display: block; height: 100%; width: 800px; margin-top: 7px; backsground: url(middle_bg.jpg) top left repeat-x; background-color: #fbfbfb; } /* left and right side */ #left_side { background-color: #fff; clear: both; margin-bottom: 10px; border-bottom: 1px solid #eee; border-left: 1px solid #eee; border-right: 1px solid #eee; -moz-border-radius: 0 0 8px 8px; height: 29px; } /* ** MENU HORIZONTAL ** */ /************ Global Navigation *************/ DIV.tabs { float : left; width : 100%; background : url("tab_b.gif") repeat-x bottom; margin-top : 10px; margin-bottom : 4px; } DIV.tabs ul { margin : 0px; padding-left : 10px; list-style : none; } DIV.tabs li { display : inline; margin : 0px; padding : 0px; } DIV.tabs A { float : left; background : url("tab_r.gif") no-repeat right top; border-bottom : 1px solid #84B0C7; font-size : x-small; font-weight : bold; text-decoration : none; } DIV.tabs A:link, .tabs A:visited, DIV.tabs A:active, .tabs A:hover { color: #1A419D; } DIV.tabs SPAN { float : left; display : block; background : url("tab_l.gif") no-repeat left top; padding : 5px 10px; white-space : nowrap; } DIV.tabs TD { font-size : x-small; font-weight : bold; text-decoration : none; } /* Commented Backslash Hack hides rule from IE5-Mac \*/ DIV.tabs SPAN {float : none;} /* End IE5-Mac hack */ DIV.tabs A:hover SPAN { background-position: 0% -150px; } DIV.tabs LI.current A { background-position: 100% -150px; border-width : 0px; } DIV.tabs LI.current SPAN { background-position: 0% -150px; padding-bottom : 6px; } DIV.nav { background : none; border : none; border-bottom : 1px solid #84B0C7; } #right_side_home { font-family: "Lucida Grande", Arial, Verdana, sans-serif; background-color: white; padding: 0px 20px; border: 1px solid #ebebeb; border: 1px solid #ddd; -moz-border-radius: 10px 10px; width: 750px; * width: 800px; * margin-left: 0px; padding-bottom: 10px; } #right_side_home td { line-height: 17px; margin: 0 0 5px 0; padding: 10px 0 15px 7px display: table-cell; border-spacing: 2px 2px; vertical-align: middle; text-align: left; border-bottom: 1px solid #EEEEEE; } #right_side_home td h2, a.anchor { font-size: 19px; font-weight: bold; color: #3E93D5; } #right_side_home td.indexkey { border-bottom: none; } #right_side_home li { list-style-position: inside; valign: middle; } TD.indexkey { background-color: #e8eef2; font-size : 12px; font-weight : bold; padding-right : 10px; padding-top : 2px; padding-left : 10px; padding-bottom : 2px; margin-left : 0px; margin-right : 0px; margin-top : 2px; margin-bottom : 2px; border : 1px solid #CCCCCC; } TD.indexvalue { background-color: #e8eef2; font-style : italic; font-size : 12px; padding-right : 10px; padding-top : 2px; padding-left : 10px; padding-bottom : 2px; margin-left : 0px; margin-right : 0px; margin-top : 2px; margin-bottom : 2px; border : 1px solid #CCCCCC; } TR.memlist { background-color: #f0f0f0; } .mdescLeft { padding: 0px 8px 4px 8px; font-size: 80%; font-style: italic; background-color: #FAFAFA; border-top: 1px none #E0E0E0; border-right: 1px none #E0E0E0; border-bottom: 1px none #E0E0E0; border-left: 1px none #E0E0E0; margin: 0px; } .mdescRight { padding: 0px 8px 4px 8px; font-size: 80%; font-style: italic; background-color: #FAFAFA; border-top: 1px none #E0E0E0; border-right: 1px none #E0E0E0; border-bottom: 1px none #E0E0E0; border-left: 1px none #E0E0E0; margin: 0px; } .memItemLeft { padding: 1px 0px 0px 8px; margin: 4px; border-top-width: 1px; border-right-width: 1px; border-bottom-width: 1px; border-left-width: 1px; border-top-color: #E0E0E0; border-right-color: #E0E0E0; border-bottom-color: #E0E0E0; border-left-color: #E0E0E0; border-top-style: solid; border-right-style: none; border-bottom-style: none; border-left-style: none; background-color: #FAFAFA; font-size: 80%; } .memItemRight { padding: 1px 8px 0px 8px; margin: 4px; border-top-width: 1px; border-right-width: 1px; border-bottom-width: 1px; border-left-width: 1px; border-top-color: #E0E0E0; border-right-color: #E0E0E0; border-bottom-color: #E0E0E0; border-left-color: #E0E0E0; border-top-style: solid; border-right-style: none; border-bottom-style: none; border-left-style: none; background-color: #FAFAFA; font-size: 80%; } .memTemplItemLeft { padding: 1px 0px 0px 8px; margin: 4px; border-top-width: 1px; border-right-width: 1px; border-bottom-width: 1px; border-left-width: 1px; border-top-color: #E0E0E0; border-right-color: #E0E0E0; border-bottom-color: #E0E0E0; border-left-color: #E0E0E0; border-top-style: none; border-right-style: none; border-bottom-style: none; border-left-style: none; background-color: #FAFAFA; font-size: 80%; } .memTemplItemRight { padding: 1px 8px 0px 8px; margin: 4px; border-top-width: 1px; border-right-width: 1px; border-bottom-width: 1px; border-left-width: 1px; border-top-color: #E0E0E0; border-right-color: #E0E0E0; border-bottom-color: #E0E0E0; border-left-color: #E0E0E0; border-top-style: none; border-right-style: none; border-bottom-style: none; border-left-style: none; background-color: #FAFAFA; font-size: 80%; } .memTemplParams { padding: 1px 0px 0px 8px; margin: 4px; border-top-width: 1px; border-right-width: 1px; border-bottom-width: 1px; border-left-width: 1px; border-top-color: #E0E0E0; border-right-color: #E0E0E0; border-bottom-color: #E0E0E0; border-left-color: #E0E0E0; border-top-style: solid; border-right-style: none; border-bottom-style: none; border-left-style: none; color: #606060; background-color: #FAFAFA; font-size: 80%; } code { display: block; width: 100%; border: 1px solid #ccc; background-color: #e8edf3; padding-top: 10px; padding-bottom: 10px; padding-left: 5px; padding-right: 5px; margin-bottom: 10px; margin-top: 10px; } openchange-2.0/apidocs/html/mapiproxy/bc_s.png000066400000000000000000000012501223057412600215140ustar00rootroot00000000000000‰PNG  IHDR /ð9ÐoIDATxíMLAÇßìN»»¥ívKùPJik±R5^ŒChÂŃ!Dzƒ *U4VƒbÄD1~`8xà@ˆ^¿?ð𤡸Ý@јÝná`JLLÝØ¦ƒÜXi v«9ê)·}aV±&Ò0)›¼ð(‰zÛküNcFPÛù'@é¨KZK%!13§5£}Ý€ÒdÀã°’>´Åç´çhï¹G…ÉZ ïz×Ú—Éi£“ì–º=…@O¹«È‚1Ó¯¦3ãF«[ºä’d²¾JÒã`|^3˜Ý\›¿¡]²ó•'fçÓùyˆÄîçâÙ@¥Cos˧d:?$lhûnÝ× nm\†$cÔL6Ñý »Ì´x@N¦oPÀ®Î‘òÕ”€GÔ÷>9¹¨Q@ã±á“.‡qŠÜ´¼°Ø ”PCt(á«yŒQ$±°hÔNý8¤¥Ë MNjÿ$þßþŲo_ƒsLIEND®B`‚openchange-2.0/apidocs/html/mapiproxy/bdwn.png000066400000000000000000000002231223057412600215370ustar00rootroot00000000000000‰PNG  IHDR5åZIDATxíË € DŸP–1ñlžmÀ r±j².e è†D[ØÉ¾ÙÏÔ¼µ¦ã´Þ|陣6€Všë3´Å?Ls'(}¬>+ žKó÷¥¿ch`‚ ^׃ÞnIEND®B`‚openchange-2.0/apidocs/html/mapiproxy/body_top_bg2.jpg000066400000000000000000000006541223057412600231620ustar00rootroot00000000000000ÿØÿàJFIFddÿìDuckydÿîAdobedÀÿÛ„ÿÀ–ÿÄh að¡q‘QáR’¢ð!‘1aQÿÚ ?Ô¢±Õœ|W¼ í|ua³Dbe­‚hŒ*ø VÁ&ÅrV¹´,¸^Â-~TbÁÐéÊ—=©xj䮤*ÿRb²r %7L‘ñÜŠ¶5ø¦ èªÞV¶ ÿÙopenchange-2.0/apidocs/html/mapiproxy/classes.html000066400000000000000000000065701223057412600224350ustar00rootroot00000000000000 MAPIProxy 2.0 API Documentation
Data Structure Index
E | M | P
  E  
  M  
  P  
EphemeralEntryID   mpm_stream   PermanentEntryID   
E | M | P

Creative Commons License
Creative Commons Attribution icon Creative Commons Share Alike icon
This content is licensed under the Creative Commons
Attribution ShareAlike License v. 3.0:
http://creativecommons.org/licenses/by-sa/3.0/

openchange-2.0/apidocs/html/mapiproxy/closed.png000066400000000000000000000002041223057412600220550ustar00rootroot00000000000000‰PNG  IHDR à‘KIDATxíÝm @!†ÑGk™É7À-`&séts¦Àñþòð@åk}ª2€… P%Á_Ëþ¿N² .:0Dk¥‹Â›x" Ö›)¡xÒ5õIEND®B`‚openchange-2.0/apidocs/html/mapiproxy/dcerpc_mapiproxy_server_false_nspi.png000066400000000000000000000436131223057412600277600ustar00rootroot00000000000000‰PNG  IHDRXÙíügsBITÛáOà pHYsêe¤ IDATxœíÝw\S×ûð'–!ˆ²Ä­àÖ¨¨¸q (â®ý"ŠÅªTk­£íÐV­«Ö…q!Š *â¸Ø(È’=d¯@BB ÷÷Çý~ó£€€zŸ÷¾âåäÜ— OÎIî¹,Š¢!„b*9ÒB!’°~™X,Ö‚ H§h‘Ï(ê'·yóf‹•žž^ïKL>,µ16騽¨­­•——oûýfee©¨¨4Û¬íã½ï? áFŽyæÌ}}ý÷L‡údpDøåïÕ«—ŠŠÊªU«d“’’Ư¤¤¤¥¥åëë›””dmm­¤¤¤§§·oß>`±XÆ ³°°°¶¶¦ÿ;|øðAƒ)**Î;·ªªª^õv*{ºššÚŽ;fÏž­¨¨hccSSSû÷ï×ÕÕe³Ù&&&ÞÞÞößµkW—F¿T/^bbâ¸qã”””´µµW¯^-‘HNœ8!''túôi999“:Š¢ŒçÍ›ÿZmÞ¼YSS“ÃátïÞ===½áѨ»G6›­¯¯/•JE"‘††ÆÊ•+éãÙôl9‹%‰‚‚‚ŒŒŒ:Tï@É´$3Bè£PèKaiiÙ¹sçððð#GŽÀüùó)Š2dˆ––Öƒ^½zõúõë!C†DFFîÚµ }úôÑ£G;vd±X–––¹¹¹ìСC||üرc·mÛÆápêöF÷Y¯‡¾}ûÖÛ/ý·›&{“Œ¢(ضm[ß¾}:´eË–˜˜˜Fûob×ôFYéJŒ>™ÐÐÐ=z())9::ÂÿÆqqqcÆŒQTTìСÕ+Wèw˜”••醬% FŒ1dȇcgg' ëõPo§²§Ó#BŠ¢èáÅ‹)ŠÚ´i“ŠŠJŸ>}Æÿ«Žõú‡:#Âz_ªÛ?ý½XYYq8MMMggg±X¼cÇ…ðððëׯÀÙ³gkjjŒ ))©^BŠ¢&Ož¬ªªÊf³‡šœœÜðhÔkŸ••%''§¨¨(›\möʼ׈°ÑE©%™BƒEáõ¨‹5þüK—.µ}ÿŸd×b±xæÌ™"‘èñãÇÓBˆ9ðS£èý(Õ±qãFÒqêSRRJHHÍd"„P³ð=Bô/ÍÎÄÆÆÊkjj~Âþ?ÉäÎp „ÞN"„b4œE!ÄhXB1Â/Óg´dsûÚþ~˜/õûBè}á‡eÐá¢ÛïÒ„Mkƒ%¼BG„_\t»ÙE·Y,ÖСC---UTTd+V×[Õº‰„õÔ{"4¹$wk/á]¯«zGæÖ­[ OHKK0`@Ý£Ñè¬áA“l...ônv5ð†ý4<€žµ:‚ó£O ÝnvÑmz‘‘‘ƒ ÒÖÖ¦7Ö[Õº‰„õÔ{"Õä’Ü­½„wîêY›º?ÊFÆ»~dõšYXXèéé………>|˜>>ͮްŸ†°Ñs¡Ö†…ðË‹nSÍ-º-Këàà {XoUë&ÖSï‰MÞÖ^»aWõŽLÓ¡Ñ£Ñè¬a³†'[³«7ì§álô@¨µá{„_\t»ÙE·eiY,–l§õVµn:a]õžøÃ?4qx[{ ïz]YYYÕ;2Ðàdhôh4ú#kجáÉÖ’ÕÀëõÓð¶üà#ô)‘®Äè“ÁE·›]t»aZªÁªÖM$¬§Þ©æ–änÕ%¼ëuµdÉ’zG¦áÉÐèÑhbùïºÍè“MYYyùòå°hÑ¢fWoØOÃØè9€PkÃBˆþå]ˆÛ ÿO²k‘H4iÒ$++«À—!66666¶¬¬Œ~3oÏž=Ÿ¤[<øˆüÔ(z?L^t»ïm)55uܸqÚÚÚ;wîtuu]»vm½x¬Ðg×E<¤ijjêèè ÓÆ˜ü½¿/>þÕ«W\.7((¨  €ËåzzzÀ¨Q£öíÛööö7n€o¿ývÉ’%ðÛo¿M˜0x<—Ëåóù·nÝâr¹IIIQQQ\.÷Ñ£G¹¹¹\.×ËË ¸\îÀÎÎnÓ¦Màââ²lÙ2عsçäÉ“àäÉ“\.W ܸqƒËå&''‡‡‡s¹Ü'Ožäääp¹\ooïÚÚZ.—{øða°µµÝ²e 8;;;::€››› ;vŒËåŠD¢ëׯs¹Ü´´´.—ûüùóÌÌL.—ëëë+‘H¸\î‘#G`ÆŒ?ýô899999ÀO?ý4cÆ 8rä—Ë•H$¾¾¾\.733óùóç\.7$$$--Ëå^¿~]$q¹ÜcÇŽ€››8:::;;À–-[lmmàðáÃ\.·¶¶ÖÛÛ›Ëåæää+3ƒ/F%$+)+óÂ×)érêÚ²®Ê+tªÂÒ²*‰482&;¿°¨´<82&ým^…@“˜žÅ_¼ŠOOMç „‘ñoØl6}VH•Ôÿ¿« Aú[º«ò–|pdLN~QaiypdLZN*)#›/¾x—”œFw|0&9M,¯È“2²é³"-'î ØŠÁ‘1o ‹Kÿ›*¿¼âÿO°ç/ãâ’Óù!ž«­w®~»~ã‘ý{³²² ÿmB¤±(Š"¡¹¬ûnìø‰‘΂",*<ìÉ£'ŽÖÔÔ$Æ BÁ‘1¤# „Ú«AýIG@ä1è=ÂŒŒŒy3¦Üñ÷#!DÞ«WæÍ˜’››K:"A…PQQ±G¯ÞšZZ¤ƒ „ÈÓÒÖîÑ«7‡Ã!‘‡S£!æÂ©QŒ¾}ûví ÇÇA¤ƒ „È ºwwí ÇÂÂBÒAy *„R©T ¨¬©©!!D^MD ¨”J¥¤ƒ òpj!Ä\85Š€Q#‚‚‚ß~Þú‚t„y!ÏžüöóÖ’’ÒAy *„B¡ðyðãÜœÒABä½ÍÎ~üX$‘‚ÈéQ„sáÔ(FKJJN=‹µ!1/£O=ÂçóIAä1¨–––žu?žK:Bˆ¼¸˜WgÝc!DÀ¨©Q©Tzïi(‡ÃQPP !D˜D"©®®ž2z8‹Å"Æ ¡@ xx?'+‹t„yÙ™ï …BÒAy *„»wüB:Bˆ¼ÐçÏvïø¹´´”tDƒ¦F«««/^ó×ÑÕí ·CˆéÊËÊŠ‹ ÙÍÄ÷JƒF„µµµ¥%%b±˜t„y"QUiI .±†€Q…ðíÛ·ß}³"øaé !òÜÿè66ém§K—.»÷63ïN:Bˆ¼Ñ㬻ëèè‚ÈcЈPAAÁØÌL½CÒABäihh›™±Ù   waP!ÌÌÌ\8kúÝ[7HA‘wóúÕ…³¦çåå‘‚È“wss#¡ÈËË‹(–åÀÁÚ;’΂"LQQÑÌÜ|ÚäI‡tDƒ.Ÿ (êQøK‹%'Ç q0B¨QR©”¢¨qC‚ÈcPIHMMµ6ðšé !ò¼==¬‡ ÌÎÎ&‘Ç B¨©©¹`é²î={“‚"¯gŸ> –.SWW'‘Ç ©QÀû"„þ ïGˆ€Q#ÂŒŒŒ¹6“nù]#!DžŸ¯Ï\›I¹¹¹¤ƒ òT•””úö·èˆ×Ï"„tttûö·ÀŒ"À©Q„“áÔ(Fœœ›é3–|5vüDÒYÚ£Ÿ6®/)."}iŒLL7ý¼ƒtŠFÞ½íëu1ðþ=]]]ÒYa Z^ˆ¢(‰D"­­%¤JOyÃçóÍÍÍIA_ŽøøxE…vúGF*•J$æŒP4"œmÒÒ93xõêUÒAЗcôèÑb±ø¯ã<ÒAÞ §F0êÃ2ùùù;·þöâ9é !ò^< Þ¹õÇ’’ÒAyítÖ¢5TUU…‡<„¢¢b·n݆ ³i¶%ƒ ¡‰‰‰_À#Ò)BíÂìyógÏ›¯¯¯O:H»væÌ¾ššš.]ºòÞ¤R©··×¢E [Ò˜A…°¤¤äÄ‘C£¬Æöµ°$!DXLtÔó§ÁíÕÐÐ ¥:{ö¯êêê>¿uÉ¥RéÉ“Çõô:ôì9´%íôaii©Ï=1!Žt„yq±1<÷ŠŠ ÒAÚ©³gÿ‹ÅŸoÔÖVæpZ:ÒcЈÐÌÌìÞÓPÒABäÍ]°h–½ƒé íÑÙ³‰D¢’òÞ>  £F„÷oùgf¤“‚"/#-õþ-¡PH:H»sîÜþÏ· º»ŸÐÒRz¯*Œ*„………{~ÛJ:E555¤S Ô^„‡¼ØóÛÎÒÒRÒAÚ—sçö …ÂÏ· jj***¾÷´ƒ¦F»vízÎûš¶NGÒAÈP×ÐpZ<Êô³íç+«¨Žƒa63m‡­§§G:H;rþü¡P8hÐ ÒAÞÛÇTA`Ôˆ°¦¦¦° ¿Š©3!ŠŠŠÓgÙ=¸ßaæÔ‹çNÀqÐÑÑÙ¾};ý¸W¯^ôƒÀÀÀ#FŒ3fèСÿüótîÜyܸq ¸ÿ>´ñšmÕÕÕ3f̨ý …ôÚÛòrR©ÔÖÖ¶ººšt/“P ,,Èÿ°Så‹tþü@ð9WA¥«‚À¨annî†Õή›6ÏqhÑ•%_Û¹óÎóÜËJKŽÜá oñ׎ï5:TWW÷÷÷ÿþûïëÞÔ{Íš5< _VÓ³Ljjj>LOOŸ7oÞ¤I“>,ªT*•“ké«´º/^¼8sæLyyùÛo»"''7cÆ GGGÒY¾@‚Žìßë`;ÍÐÐtòJJŠâââ´´´>|H:Ë{ËÌÌÐÐPTTüðrÆ BØ¥K—=‡ÿ11íF:1ŠŠŠKïû*øü÷-‡òòòNNNGýá‡d555ïÝ»7kÖ¬:hiiɶ›˜˜”••5ìä÷ß÷ññÑÐа²²úú믫ªª(Š:~üx¿~ýÀÌÌlòäɯ^½:tè˜1cæÎ+‘H àëëûí·ß¾«ñ£GèÏ_¾|ùøñãššZ·óŠŠŠŸþùîÝ»>>>7oÞ<{ölRR’“““T*åp8rrrE¹¸¸<~üxÅŠêêêçÏŸÏÏÏwssspp ÃwëÖmÊ”)tƒuëÖÅÄÄ8::*))õïß? ))©ÞNéuÕíA ÈÅÎ;é¯ÚØØ¼|ù²ººúÌ™3½{÷ž>}úòå˱¶†1ã'˜˜™éà J@"‘véÖ͘t‘‘‘ö1Uµè¶D"¹ìG[»£ZMÛ(/+ó<Û.Ö®­­õ»â-‹éŸ;‹Å¢(ªƒ†Æâ¯o^½2hР&Ý677ýúõˆ#ž?>`À€„„HOOßµkWpp°ššÚßÿ=lØ0ssóäääèèè5kÖÓÿ•ubffª££#•J§M›¶{÷¥-_¾<((tuuƒ‚‚ú÷ï»eË?????¿   „„„&ËúïÙ³gbb"L:µ^û?ÿü399ùåË—AAAªªª&Lpss³²²’ (uuu#""´µµ‡ ¥¬¬\TT4~üøW¯^Ñ×m`mm½{÷îáLJ††NŸ>½°°°áNëú=TWWË@GGÇßßĈ!!![¶l €=z$%%}’Ÿ~ÛkÏ‹nóùåe¥¥ógÚ°Ù ¼K~~®Ï±Ï´Þ¸qGCƒÍb±~ÉÉi›©iïf{`Й™¹dŽ-‘©Ñ >ÿâ¹3m¼Ó&ÈκòËË/œá)¶àVÝŠŠŠK–,qww—m111¡G`‘‘‘ŽŽŽÑÑÑ•••ãÆ“J¥û÷ïoØÃéÓ§7nÜ(‹—.]ëêêJo—}Š]MM.lýúõ+,,,((8wîܶmÛf̘ÑDã†vîââb``ð×_©ªª@JJŠ••ȦU;tè`ddD?¾råÊñãÇåå勊þÿu@ZZÚðáÃ`ذa***î´žº=Ô=666 ¤¤4bÄ>|xFFF£ßúTnû]?²ïج,œE *„ººº¶üd1€ØÇ‚×ý°yÖÜy¤öNKŒsùÏÒºÃAM-í¥ŽN¶sç9-´oI«V­²²²’]‰‘””Ô£GèÒ¥ ý¹ú=Âw=}ذacÇŽ½{÷>tèPïÞ½@"‘Ð ê¾½·xñâ#GŽdgg0 ÙÆ4ssóììlCCÆí×®]»{÷î£GÚÚÚêêêvëÖíéÓ§£F’ È꾢ܾ}ûË—/E"QÝB[ï%§±±qXXØÐ¡CÃÃÃé²×hȺêöP÷P¤¤¤€H$ 6lXxx8]/srrLMMßu0ÑÇmæ,yrÓ r,ñI˜sî'(Š¢K †¦][ÞƒªªªÝÁƒéÿþþûï G"‘8p Ù§Ï;W(ŠÅâÕ«WÏž=ÛÅÅE(ÊËË;ÖÍÍ­^ãE‹uíÚõ·ß~€ãÇ7ݘ6oÞ¼›7o:;;×konnÎáp¾ùæ›^½z}ýõ×þþþGŽqrrEEÅû÷ï×ûl޽½ý¸q㬦¦ö®ïåСCË—/WVVîÓ§½^e C6<ô 3gÎlذA,Ÿ>}nÞ¼){‡}ZfæÝMLUðR"Ĩ÷SRRÌÍ͉Lfgf.²›ñݦ-v Úx×u%ƽ^ùÕ¢º£Àº%ð˸1ouuõœ9süüüZþ¡Ó&‘HèOè„……mذáñãÇÙa½÷S¥RéìÙ³½½½ßë•J»Òžß#ôò8wdÿÞ,œ€¿G¨¢¢Íbq(Jú û¯ª¦¥%˜˜´Ê¡Æ÷߃¦¦æ¢eŽ=z5P¾T§OÕÒÖ^üõò÷~F8Ž¿¿Ûì+$$äǤ(J"‘=z´ÞWKJJæÌ™#ûï¤I“¶nÝú^ýËÉÉùùù}‚ ¨1½ûö[´ÌQ½Í?:×þÕÖR,–XEEéö©¤¤ž’ò)+ë§Å BرcÇUk]I§ ¦¨ `ð°;ÿÜÇá|™%°í=úÉ“'ïúª¶¶öû^’Uw8ˆZ›ÅÀAá=˜0je™ôôôÙ“Çßò»F:::Í[´« B´ëW¼gOŸ››K:"A…PYYyàà!:ºHA‘§ÛIoàà!_ê{è½0hjTOOoû®?I§@µ #­ÆŒ´£­­M:"A#œœœU_/ypt„ywn­úzIAAé ˆ<ÿ«±Ø"„jH^ž­¡¡ûaÏ•JkËÊ>× *„ÇÎxNj&N6qê´NðCM©­­))ùò?OÄ ©Ñüü|·ÍCŸ?#!DÞ³àÇn›7–””‚ÈcP!¬ªªzYTøy ÕB­ª° ÿed¤X,&‘Ç ©Q“«wI§h×rss?÷%ÖP»RRRBß룚5wÞ¬¹óºtéB:"A…°¸¸øèÁýVÖÖý,ÎÒN…„„Ô] ¡7dÈÒ÷22âYðc‹CûqqÄ BXVVvñÜi½.±6jóÎß««qš}b**ítD˜÷úâ¹Óþ¶ a=µµ >åZ£íƒ ¡™™Yàóp‚·ajçúôkü·}‘æ-Z2Çaé íŽX\õæM"§wê~/55Ü¡³`PU¨¨¨¸éwÍbÀ@3ó „KM~ûêå°~=›¸å$3ÉË×öêeN:E›bЧF ÿÚõktd8é !ò"BCþÚõkYYé ˆ<ŒŒ.\½¡¥…K "„`šíì‘cÆvîÜ™tDƒF„‰$'+SPYI:Bˆ¼ÊÊŠœ¬ÌššÒAy *„¹¹¹?¬]ý4ø!é !òþ°vuQQé ˆ<MvéÒeß‘ãF&&¤ƒ „È7a’™ywÒAy ²ÙlÝNzÊ**¤ƒ „ÈSVQÖí¤'//O:"A…0++ë«y³îÜ"!DÞí~_Í›ŸŸO:"AS£ººº·mïg‰ËÊ „`Èð·m×ÒÒ"‘Ǥ3|ÊÊÊrrM pÕÕÕ'MÆVPh³H¡vËØÔÌÀ°« ¾W‚Ø_̪ ‰‰‰=zôh¢AjjêäÑÃ]7mžã°°ÍR!„Ú§+—<ìß›••ehhH: "Œ Æ ›4ié$.""âÎ;Í6ÓÒÒZ긢Wï¾m !ÔÎõéשã uuuÒAyl9r䯿þJ:ɇ;zôhK ¡¶¶öŠÕkÚ B¨ýë?``ÿñÖõ©ÑôôtÛ‰cý¯ù’‚"ïš·—íıoß¾%‘Ç B¨¢¢2tÄH½ÎxCj„tÖ×:b¤’ƒîº‡Þ…A—OtêÔé§_w‘NjFŒ²1ÊJ[WáGL*„ÙÙÙ+–.\ôÕ×Ö“¦ÎҮ͞dmdjJ?výa³™y÷™ÆLž6c͆àøáþ×|o>€ˆÐ“G±ªÅbÛÙ¼cGmFwÈVMM͘ñ/e±XôFŠ¢„ÁV~3zœµ,€Ï¥ ö 7›óä‘CQá –.‹ñÄ›q IDATŽ[¸ì?Á‚¶îü­5Ž úòÜ»uÓû¢ÇãA:u"Æ BÈb±8Ž®¨Ôe•C'xu·¨©©§¥$SÅb±ãã444éíþÜuèÄ)-íŽPÁç_ö8×h3Y‡‰ä¯]¿^¾pnþ’e²e¥¥ß._V·^¹èY¯J¥Ò†‰>¸çyÕN9|Þ猱žðIú’ɳå9‹Å"‘Ç Bh``päÔYÒ)>Wý,ľЖcÉõé׿ /Þ¨¦®úüÙèqÖªªjê:¼«™Œ‚‚‚‹ë×UNó—,“m*Uë\ÌzóšoaAÁÚ•ŽÃGŽZüõòù¶6CGŒLy“d3Ã6ðî’’bGço¬'M9~ø`A^þÚ•Ž÷6‡~™ž~í^PVFÆ¿l§¤[AaÿÑM/³€kÂä©&OÕÕÕ%‘Ç B˜ŸŸÿÓÆõ3ìæ 9št–v­J(¤ë üºw‡0aÊÔë>Þ0sÎ܇÷é¯nÿíÓî§O)«¨|·iË»šÕ¥Þ¡ƒX$’íE"‘¤&¿qÛõ§¬ÁôÙsDYY騱}>¦Ââââ#û÷Ž?±?Þ€¢Iu§F\ÖX H?ž8Õ¦^Ë󼓙éil…ÚššµßoÚûÛÎF›Ñ²Xr5ɘñã/•m¤(JTUõ놺í‡õÃZîè1v dÇMœ´v¥cÏÞ}š½£äú·þ±Ó 8 ýƒï¢ÆEG†?}ôÐâïC¸¸ Ë(‘ÔNñ!ÂÂ"?²¸ººîß¿ÿãÓ°X¬ùóç_ºt©Þã–pssëׯŸ½½ýì÷èÑ£...Í.º’’bnnNdÑíìÌÌEv3¾Û´¥î_v„A^瘰èvxxxppðªU«”••›h–ŸŸëãs¬[7ã6 ö ݸqGCƒÝ耜¶™šön¶‡Öz±œ••õÏ?ÿ´¼ýŽ;|||Z) ­[·nâíæa)BÃâ¥â¿ì*C† ¹xñ¢©©éþýû…B!é8íÔG¤¤¤ñãÇ+))iiiùúþk Ï®]»º¸¸Ðm¬­­•””ôôôöíÛ,kèС–––***²-àååÕª×ô”——_õöJM~Óz»@}.’“¯z{UVV’Òê¶oßžŸŸ¿~ýz,‡ú¨B¸xñâèèè;wî<~ü¸W¯^ïjóæÍ›çÏŸ÷ÝwßÿýÇ ;;ûÌ™3½{÷þý÷ß ++ lmmé­¤¨¨èàŸ»^FE´Þ.BŸ‹È°Ðƒî*kîCÈ_€éÓ§<ŠŠŠ°6ê£>,mcc3nܸ¦ÛPeee%•JàéÓ§0jÔ¨š››GFF=;¡¬¬ÜªÓFFF¯ßÔÔÔj½]¼‹ìʹ²ÒÒ¶ß;B¨¡Ñc­-’——/,,$¥Õ­_¿~ñâÅô籋‹‹×¯_¿k׮͛7;;;«4÷é3&ø¨BhiiùôéÓGuìØñ]³š–––¹¹¹ìСC||üرc·mÛÆf³á3¢4…ÂÂÂÜÜÜþ4sÿþý›Y­­­e±XÐæ‹*ÕÖÔÀ±ÃŽ>ÐÆ»F5Á™t€¶Äb±(Š¢Ç$………ëׯÿå—_|}}›Ì0ÁGÂóçϯZµjÊ”)ŠŠŠ§OŸn´Í… ¾ù曥K—²X, ‹iÓ¦5Ú쫯¾:sæÌСC³³³?,ŒD"i¶Í/P#´º šºú¢¯þCdסz^EG½x¼iÓ¦:ÎÒêÊÊÊöíÛG—@“““J¥½{÷vss3¦ñµ,å£ aïÞ½=z$ûoÝë e{öìT÷Y²/]ºtIv}…»»»»»ûÇ„IHHhúò‰ªªªç<»ëvÒû˜}˜µ+‚Ê%ŽNm¿k„PCùy¹9YY«¾^¢¨¨H:K«[µj]éسgO777{{{¼Ê–Æ  êååå545™pÒ#„𥍍¤¡©É„J™™ÉãýwÑD,bбÈÊÊúÏû€»·IA‘w÷æÿ,°ÏÏÏ'¤ÕýþûOŸ>^^^±±±XëaЈ°S§N?nßÙ·¿é !ò†qGªwØ©¥Eàcäm)33344ÔËË GM`P!TUU;a‡Ã!!Dž¡‘q§Î]š^xì •J#""ðþÃMcÐ „´´4›1ÜW[w!7„ÐgÁ×ë¢ÍîÛ·oIi]&&&X›Å B¨¥¥µl…s¯>ýHA‘××ÂbÙ g&\;šÅ ©Qmmíå«V“NjúY èg1 !FÓÒÒ¦[¾qõ é !ò|/_œn=ú‹ŸE-Á B¨ªª:j̸.¤ƒ „È3045fœ’’é ˆ<MvêÔiËŽ_I§@µ ÃGŽ>r”¶¶6é ˆ<³³³—/r¼w‡t„y÷nù/_äÀ„ êQ³TåääTUÕ8 x!BØlUU5¼Æ£¦Fõõõä‘NjÆOž2~ò]]]ÒAy z5”——·uƒë‹§Á¤ƒ „È{òèÁÖ ®ÅÅŤƒ òTÅbñ›¤¼G¦è‹Ç€ÄÄDÙ}?G-ifll|ù~R!0ÓnîL»¹;w&‘Ç€Û·oß¾ýåßœ¨¨¨èÐÞ?ÆM˜d1pé,!¢ÂÂõÿçoMMMÒYaìçÏŸ“Îði5Ý ¼¼ÜçâC##,„¡¤„xŸ‹öÿ¹ !b1‚t†6Ò­[·Ç¯H§@µ ó—|5ÉW†††¤ƒ òôa™òòroOä¤DÒABä%ÆÇy{zTVV’‚ÈcP!,**:¼ïÏWÑ‘¤ƒ „È‹Ž?¼ïϲ²2ÒAy º ÞØØØÛÿ®ºÞu!3ìæŽ›0©K—.¤ƒ ò4"‹ÅI ñx!BÊJŠ“â«««IAä1¨æååmýW–A®²†Âû¢ÿÇ ©ÑN:mÝù[ï¾ýHA‘7|ähM--¼C=FBUUU®Õ%%%ÒABäéhëtÄ?55š––6ÃÚÊÿš/é !ò®^öšamõöí[ÒAy *„ÚÚÚË¿YݧŸé !òúYX.ÿfu‡¸ÂbÒÔ¨––Ö2'gÒ)BíB_ ˾–X0jD˜––f3†ëçëC:Bˆ¼+^mÆpqj£ ¡ššÚØ “ »’‚"¯«‘ñØ “”••IAä1hjTWW÷Çí;I§@µ ø#‡qGjii‘‚ÈcP!ÌÊÊúzþÜ¥ŽN¦ØÎÒ~ÍždmdjZYQ1oÑ›™³d[@¯s—­;k´ŒÏ¥ ö 7»—“GEE„/Xº,>66:"lá²ÿ?¢;G¨mÜñ÷»tþì³'Ázzz¤³ ÂTåååµ´µ9ŠŠ¤ƒ´kÊ**‡Nð„BÁÊ% é"GoiºÌ•‹žu ¡T*mt «÷<¯úÀÉ#‡Ïû\€1ÖZãÛAè]”””´´µq‰5Œ*„úúúûž$âó •š{ï¤a››×| Ö®t>r”Ÿ¯ÏÐ#SÞ$Ṵ̀ ¼{§¤¤ØÑùëISàøáƒyùkW:@ÞÛúAfzúµ{AYü²’Rl…ýGOà)ÔzÆMœ^:vŽÃ3óîb±Øvî¼ò²²uÎËéBè¼fÝÀ{t³%sle`ß®_V®^k1pл†’}*Á‚nú]½~ÅGGG‡tDƒ auuuFjjeŸtvMYEåðÉÓ1/£<Ïð†qGÂ;¦Fëµi´3óîð(ð¾ßo9yùò²²f÷þ6;Ûbà À*ˆZŸ_ž‘šZSSC:"A…ÐÈÈèâõ›¤S|ú[ «ÒSSL̺½WŠ¢èòròôÞ±N_ò©®®^æ0§ÙýêƼŒêo9G„¨µMŸe7}–]çÎIAä1èoMQQÑ?v½ŒŒ äó0Ónޝ×Å÷m3|ä¨Öº\½|I¶eÜÄIkW:ž}z½7ÕÒÒ2ŠŠ I%ü@CC£ÞFŠ¢D"¶‘Q÷–ôÀ B(‰^ǼêÞ£§Šé,!ÂŠŠ SÞ$ٌńPL™2eøðá¡¡¡EEGG7Z»w79r,Ùœ&$$45õ_—P%‘(nذ³…Wa1¨æççÿüÃ×M›çt%S‹ ŽìßÛ|;„PëKŒ‹ŽÏNNTWgÄ,‘¡¡aHHÐ&Õ+‡PS#ÉÉyC8削 ÑÐøÿZFWAW×-½éƒ ¡ÁÞ9}RJKJ¼<ΑÚ;B¨¡'NŽ@]###·mÛÖ»wo5µæ/óý,PTWs\]·¼Ç€‡A…Åb)((ÈýoÅ“6và¸;‘ý"„UR\TŸÿÕ<;‡C:K[ظqãþýûéÇrrrR©tôèÑnnn&L€üü\¢é> Š‚êj…uëÜ MÞë‰ *„ÙÙÙ+—.tÝ´yŽÃ¶ß;.†P»x÷Αý{§ÏbÂ¥„ùùùG‹EQÔÈ‘#e%ð‹AWÁµkݺv5yßç2¨êééýüÛîž}ú’‚"oĨÑut´µµIi {öì‰D0jÔ¨/¯EDÂ^»v»‘‘Éüƒ Zt»´´ôǟ܆Žàâì(B(.6&24dï®_rùjƒ !GÆŽ€jG¬õ'‘Ç 2¦¦¦N5ìúoÒABäù\¼0yÔ°œœÒAy *„êêꓦÍ026!!Dž‰™Ù¤i3TðÓs§FBL†S£5"ÌÊÊújÞìû·o’‚"ïöë_Í›ŸŸO:"A…ÍfëvÒSQU%!Dž²ŠŠn'=yy2k.¢v§FBÌ…S£5"ÌÍÍݸÆåÙãG¤ƒ „È{¸qKQQé ˆ<B‰D’›“]YYI:Bˆ¼Êʊܜ욚ÒAy85Šb.œEÀ¨aaaá¾ß‰Ž'!D^xè‹}¿ÿRVVF:"A…°¢¢âÖëéi©¤ƒ „ÈKKN¾uãº@ ‘‡S£!æÂ©QŒ–••yžå%ÆÇ‘‚"/þu¬çY^EEé ˆ<Ââââc‡¼ŽyI:Bˆ¼WQ‘Ç(//'‘Ç ©ÑÚÚZÿ Ç*ªjL¸'5B¨i¢ª*¡P0cü\\1hDXUU^TP@:Bˆ¼‚ü¼¨ˆp±XL:"A…0??ÇæB_<%!DÞó'Á;6ÿPRRB:"AS£"‘è¬×•ÎúúÚuHgAV\T˜Ÿ›ûŸ…ó8é,ˆ0B¡†TsrrV}½äaà}ÒABäܹ½êë%ø¡À& íèéé¹íÚÓ£WoÒABäq­ÆèvÒÓÖÖ&‘Ç B¨¬¬l9hªªé !ò:uÒSUUUTT$‘Ç ©Ñôôt»)nݸF:Bˆ¼ëW¼í¦LÈÍÍ%‘'ïææF:C‘““㋪ ÒQG—t„aòòò]ŒfØLÅA!bÐ個n#„þ ÝFÀ¨©ÑÔÔÔ Ü!×|.“‚"ÏÛÓcwHNNé ˆ<Buuõé¶³MLÍHA‘gjn>Ýv¶ªª*é ˆ<œE1N"`Ôˆ033s±ÝÌ{·n’‚"ï–ßµÅv3óòòHAä1¨*((t5RSÃëB ¦¦nÐÕˆÍfеÔè]pj!Ä\85Š€Q#ÂÜÜÜ «ŸßóÜiíŽ9Ι“Ç8Ž^ç.îÿü-ªªêjlâåqîmvV·î=nù]{Õ§_ÿÇAî<$2,ôƵ+ý,¤¥$_ñò465+//»xîLG]6›}Æý¸¢’b'½Î'Žª®w52¾xîLÞÛœnÝ{ø_ó}Ý»oÿ‡÷?´48"4Äÿš¯Å€ÉI‰¾—/švëVRR|éüYÝNXrrgÝO())éèv:ùÏᚉaW#ϳ¼‚ü<3óî7|}âcczõí÷àþݧZ òÜÿúUËAƒ“â}/_23ï^RTxÉãl§Î‚s§N(«¨hwÔq?úwmm­A×®Îð òͺ™_¿â׫OßÀ{wž?¶00ôù³›~W ’÷úª·—yž…ù^ç:wéR[[{žwRUMMSKÛýèß%Õ7ìêÁs/.*4íf~ÍÛëMbBÏÞ}ïÞ~ñ4¸ÿ€!ÏžÜò»6pÈи˜W×|.wïÕ+?7×ëÂùÎúú5ÉùÓîjêê§Ž}Ãs§N”––˜˜uó½|1åÍ›½zß¿}3ôù³þ–ž?y|ûÆõÁÃ†Ç¾Š¾æs¹gï>osr.{ž×74‹ÄgNuÐÐPSWçÿ‡Åbu108{ò8¿¼ÜØÔìŠ×ÅôÔ”î={Ý»åò¢Ÿ…å³ÇîÞô4tXLtÔõ+Þ½úôÍÉÊô¾èaØÕHTUåq攆¦¦ŠŠ*ïÄQyyùÎúú¼ãÿTVV›˜ú\¼ž–Ú½g¯;þ~‘á¡}û[>}üðþ훃† {áçëÓ»_¿ÌôtŸKº •Îò4µ´””•NŸ8Æf³;wÑ?uìH•PhdlrÙó|VF†yž·ü®½ŒŒèÓß"øaPàÝÛ‡ Ž÷»êÓ·¿EzZªÏ%O÷nù@Ðý»×¼½ ôù3ÓîãÁs éi<÷‚‚üâ¢Bž{ZJ²H$òà¹Ç¾Œ€Kçμx ~¾Þwo@àÝ;×½/@ÈÓ'žgOÀ똗}º¡¡!ǀݻw/Y²díÚµ“&Mzúô)¤¥¥ 2„Åb>}ºnK 4h££ãÚµkY,Öš5k **jöìÙk×®1cF\\\Ýb±¸¶¶633“þ¯ÝÖ­[éÇ Ÿ%Ûïßÿ=zôh‹¥££sìØ1عsg=‚ƒƒ›}â¸qãþ»o ¡¶EW&ccã‡Ò[ª««G]ïl …ôù_﹉„¢(×·o߆ÛßÕ¦U¿zw­Ñ¡CŸióçÏŸ2eŠì÷ë—_~5 ¶)IDAT±±±yóæÍwß}Go‘J¥=zô¸}û6EQb±ØÖÖVöt???Š¢.^¼¨§§GQÔùóçkkk)Šº{÷n÷îÝëîˆnyáºeMM¾¾~@@EQ‡¢÷.•J»uëFQÔ•+WFŽY/ó¦M›8ΤI“þúë¯äädY¼FŸEï÷æÍ›ô.455³²²(Šòóó;{öl ŸHÃBˆÚ}8p`Ú´iô–³gÏ|xìØ± ÈÈÈpppX³fͪU«V®\YQQ±eË6›½~ýúäää¾}ûšššš™™ ><222''gìØ±Ó¦M‰D~;‰D¶ 7mÚ4ƒS§NQµuëV{{{WW×™3gîÝ»×ÞÞV®\yéÒ%º‡]»v-^¼xÍš5'N|òäIÝ´õºŠµµµ]·nÝܹs·mÛFQTddä¬Y³Ö¬Y3}úôׯ_êŸúŒÕýEHII™2e ½½¦¦fôèÑC† ©¬¬¤·¼yódÿ­ûtzcDDýëy÷îÝyóæ999ÙÛÛ³X¬º-+**ê¶LJJ’==$$„ÞHïèÛo¿]·n“““••UÃØoß¾=yòäœ9s8ί¿þÚijê&¤(ÊÙÙyûöíE-]º´ªªªåO¤°¢¶GŸ…åå庺º±±±E999Ñë6›9s¦X,¾xñbÇŽeå§îïöÎ;ÇŽÛp{Ómè—<ÏÒÒòòåËô—~þùçeË–Q ^,{{{Ë^E.[¶¬Þ_ŠwíºîKcúW1??Ÿ¢¨œœœ½{÷6¶ðUv×í;¾FLÖÄ܃«««žžÞ«W¯èÿ6QëžØ'**J¶å]-©ÿB@@5(„åååôù|~Ý=òùüÛ·oÓ¿ Eyzzª¨¨4ñ¬zß`dd¤AZZÚúõëë~_Í>‘¢(|‘¡¢¢âââ²gÏžÛ·oO:µÞWcbbºwïÎápìììàÊ•+u¿ºzõêeË–¥¤¤xzz¾«ÿwµ;v,ýïË—/eû2eН¯/lÞ¼¹¢¢báÂ…¿üò ØÙÙegg‡……¥¥¥uêÔIUUµ%ßšµµ5ôêÕ+??ßÈÈhܸq#FŒøñÇ“““7lØÐ°}§N,X°bÅŠ“'O&''¿««”””¤¤$+++àp8ׯ_OIIIII9{ö¬««ëíÛ·ååå[1–¦¦&\¿~½ÿþû÷ï_´h}ânݺõèу~ÏO$Í›7¯Ñ§ ‚êêjmmmÈÈÈhz_fffúúú/^¼€ððpzc·nݺuëF¿{—••µxñâºOIII±±±¡Ç”Àf³õõõ›}–ÌÀõõõ,X°|ùò–ìî_Zúê¡ODör¬°°PCCÃÁÁ¡¶¶¶ÞˆðÛo¿upppvvvvvîß¿£#¿Fûla›””½B|ö왺º:ý¸Þ‹å?þøcñâÅßÿ}jjjÓßN£é6111»wï633³··¯¯å¯²¾loúõ5b²¤¤¤ùó瀋‹Ëêÿ€˜˜˜Ü¼y3 @KKkâĉqqqÔÿfÝ]]]—.]úäÉ“ÒÒRúéß}÷ìñæÍ›·mÛ6xðà5kÖÐEeóæÍïjIQT@@À Aƒœ·nÝ*''G‹ŠŠš>>ýû÷'§)XQ›’½P]»v­lcaa!½qõêÕÅÅųfÍ5jTBBýÕ'NhhhXYY]ºtIöR.//¯aŸ...QQQ¶iø20==]öa'''>Ÿÿ®ËK–, júÛqqqÉÎÎnøÒxÙ²e'Nttttuu6mš———X,:tèòåË·¢O/O§ÓCBBzX¾¡„õãºuë–ªªªŽŽNAA¶¤¤¤ÄÁÁAJJJSS“Á`ÙØØHIIÑh´²²2 Æ ÓÒÒÚ²e @pqqÑÒÒRSSKNNî¾¹p]؆úúúûöíëß¿¿¾¾þëׯ`Ë–-d2YJJjĈ Xá.{ÖÒÒÚºuë{W ‡”ŸŸO¡P$%%---óóó÷íÛ'''÷üùó¹sçêéé±X¬U«V©ªªr8œêêj"‘xòäIá¶ÛÊ•+åääÈdò²eË Ëá W4aÂ'''HKK#ÿ®>ñ7²gÏlCŒðW)øÐ½ºùQ™˜˜P©ÔP(ìL°²²200ÈÏÏOOOojj²²²²··/++suuuttäóù ¯¯_TTTYY ‚ÍMLLºo.\Ðh´¬¬,áÛ¶mãóùiii>ÌÌÌ$‘HXá.{€•+W~h• $ …‚­µ°°àñx®®®FFFD"1--Ïç?~ü®^½)++ÛÔÔTQQÑÐЀ)''óàÁƒ””ìp„_¸¢óçÏ„ׯ_/Z´HWW—Çã}ü»|òÿÖå7²`Á¨¨¨¨¨¨èòU ûнºJX?. ‰   >Ÿ¿xñb,a‘H¤E‹ H$IIIyyyIII‰Äçó`É’%ØZlŽ­í²¹0X¶lY—ÁÁÁ|>Ë–- °yóæ÷îYø/¶û*AH$©ËÚ¿ÿþœ‘¸¸¸L›6môèÑÓ§Oïä¶mÛ ¤¬¬¼víÚî‡/\Q[[›’’ÒîÝ»UUU7nÜøŸß•ÀÓë²våÊ•‚6D—¯zåÊ•Gð=t¯îAúÆ 8äûehh˜™™YZZš‘‘-177§Óé÷ïßoii¡P(fff[·níèè(//ÇÊHJJ ö ØÜÐаûæd2Y¸: ‰.ø|>lß¾}êÔ©îîîóæÍãÿÿ=ë.{Ö}• ¤Áƒ§§§ckMLL:::~ûí7[[Û;wî\ºtiÒ¤IàïïÏãñ.\¸oÞ¼!“ÉŠŠŠ`bb’œœ|ãÆàààmÛ¶u9üåË— *’––ž6mÚöíÛëëë}||à?¿+Á7,üc[[›ðRRRP\\¬ªª*¼¹¢¢byyyRR’ ä{«û kX?®ƒVVVŽ3FII [«¬¬lgg7mÚ´¶¶¶'N‰Ä &TWWw߃’’ÒØ±c«««8Ð}óO cþüùçÏŸOLL”““ûО?R©°cÇŽq¹\+++.—ûÇlܸ±¢¢âÊ•+Ë–-[°`Amm-LžlèçÏû P·¥RÞ56·ñ%†8ÚuH5Œ®Ãd•úå•Œí¡¦cp~s’×x#Šõ‰¸SÞÓ§Ù ±;,,pÑ"ë¡Ã׬^²%ÄÜÎ)páÂ#‘Q†–4Ÿ™3/$^Ö66?nlFvî€Az.ÎNO^¾’S`G³b6·6wr‡:9p$¤^¾©9ÜU¡¯jN~ç˜ÑõŒ®^OšÙ ,¨q§ãgLŸJâ¶7<ü—ùóm\F¬_·®ËÉ6gö¬ó/i›yyz¦ff©ê¸ òðé ÁÉÖÊ#q´ï$H¾®®áæ"«Ü/¿ðŸ“í¯ôI^Œ(Ö±'ã¼gL³u¹{÷nÁɶeës[§E¿üu4ÚÀ’6ÛÛûÒå?µŒL;&ãŽàd{-«ÜßÎÚª¾¥­¹ƒ;ÔÉK’~ù¦êŸ“-¯Àsìh }ã+]Ÿ<ÑË„f,&Fp²-[º„6ÄuÕ¯«vlßajãðËüù‹Ñïr²åå÷×Òâ`÷òMUK'¿¬´¢¢"žV||ü¾½{FyþdemÓÀdªkh›˜2ëÞ ÒÕÓ74b¼}k4ØD[G·¶¦ÚÜÒJ]}`Ý»w–Tš²ŠJSc#ÕÚVN^®•ͦÙÚIJJvvvÚ88ò¸<°stje·JIIÙ:8²XMd²•µMcC}ßþýÍ,(õõÌšÆ&¦uïÞéêëë¾}[k<ØTkÎÛš UU]YWG¡Z+*)³šš¨6¶²rrm­­ÖvöÇÖÞ‘Ãá{'g6»EJJÚÆÞÕÔÔG±…fÝØÐÐÀS Ëzf†–¶Ñ`“ºw ]}]}Fm±©™–ö ·µ5VV¨Õ3™V4E%¥f‹jc++#ÛÖÖfmç@$¸\®­ƒV‘£sKK‹ŒŒ´µ«©QQIÙ’Jk¨¯ ªfjnÁdÖiji®{ÇÐ70ÔÑÓ[[kbn®¡¥Íx[K¡ÒúöïßP_oemCîÓ§¥¹™fc+--ÓÞÞfcgO y\®­ƒSgG‘H´wÂb5ÉÊÊÑlíš””•-¬¨ ªªj&fæõÌ:­Aƒ ŒŒë }##]½·µ5&æ55Þ1–Tjß~ýê­h6drŸ––fš­´´tG{»ðx<[§ööv‘dçäÌjj’•—£ÙØ555*«ôµ X5Ô׫©ljƬ«¤««ohÄx[kh4x®îÛê3 EM}`Ý;…JSéÛ¯©±jm#¯ Àni¡ÙØIJJvvtØØ;ðù<>ŸoçèÔÚÚ*))iëàÄb5)`ç@cCß~ýÌ-)ÿ:Ùt°ŠÞŒlªªš:³î…flVÖ¶òòòÿ:Ùìø<Ø;9·²[$¥¤mYMMä>}¬hÂ'[½º††±‰i]Ý;]=}=CìÐÔÖ~[[ciE ¦V_WG¡Ò•UXMMTká“ôÿ'['@°wÒÒÜ,--8Ù)TëÆÆ†~ý±“©¡¥…lzú†ºúokjLÌÌ4µ´µµjÿªõL&…fý¿“MV¶­­fkO$¹\®­£cgG'v´°XÒ²2Övö¬¦Æ>JJ–TZCC}ÿ.'ƒ¡oh¤£§ÿ¶¶ÆÄÌâ`خܜ;3fÌÀóÉ ‰Wlœ°IåSŠ mÍMlllð| KRRRVhæ(AÄ”´´ŒŒŒ àû¢ûõë×—ø²[šE‚ =²o×ö 6¾gÍa0—o$L5Œ ˆ8zõò…½¥©¡¡!ž[XÍÍÍ5U•<OÔ Ò#̺:ƒøîÞ¾}{ãoÁ­ìQ‚ HüqøàîÝ»ß]Âæææ¿S³¨©‰xÎË‚{̺w޳àù/¹¢¢"'+ƒÃéu ‚ôȃ¢¢üü|Àw—ðÎ;{wnkkmu ‚ôÈÙS'Ž= øîr8œÛwïKKKQÇ‚ È—ëèhBµ––Æs «¤¤$þDLGG‡¨A¤Gnþ}=11ðÝ%,))9w¢½½MÔ Ò#·’®_¾|ðÝ%€Œ‚Q‡€ ÈW0”fønaeggïÝñ;ºèŽ âîì©“QQQ€ï„UYY™›ÅápD‚ =RZ\TPP¨Kˆ ˆXÀ—0%%e㪕­l¶¨A¤G¢#†††¾VKKKmM5zùAÄ]C=óÝ»w€º„‚ˆüw ¯_¿0¯¥Ö€ â-|×öuëÖ¾–¤¤¤¼¼ŽÑÈ·ð]ýáðx¼¡4 "‘ˆçÖñãÇýüü®¥¤÷QTu,"v&.öÈþpQGˆ CCÃcg.Š:Šÿ òŸ«¯«“˜˜ˆç„egg·xE°Œ¬¬¨ù.„°°0QGˆóçÏ×ÕÕ‰:Š™4c&ÕÄð} K__äè±$’¤¨ù^¬X±BÔ! bàÑ£G©©©¢Žâ_l­Ìßw ¼<†7³Ð]Bok–Í›7ðÝÂ6lØú­ÛeeåD‚ =òsÀ/ÖfÆ€ï–ŠŠŠ‘±zÒAÄœ†––®®.à;a]¾|yîôɨKˆ ânûÆuË–-|w Gv(RN^AÔ Ò#+~µ³0|·°‚„„„¨£@¤§$ˆDìoÏ +))iùÂvK³¨é -ÍÍhôz¯„íÚ´ià;aM˜0áÓgåÈ¢¤7ÈÊÉ-™ï{öÔɶ¶¶/Ø\MMmûöíØg++«””GGÇaÆ9889r[®­­íêêJ¥R“““±b_+økmmõööþÜ­z-¼ÿäííýe¿D`õæ­{öì|'¬ÆÆÆŠWå?H»ƒH$ŽŸ45"ŸO Æ¿sçNSSÓW¯^ÐéôfddÔÖÖÆÇÇ:thåÊ•žžžááá]ŠVR___F+((è¾ÏeË–q8œæææØØXww÷Ý»w[YYñx<ì×­©©™››«¨¨èää”››+++Ëd2=<<òòòº¬-..vss‹‹‹ãñxUUUÝëêòu o¾jÕ*ác×ÐÐÈÍÍåñxóæÍÃú΂CøŠ¿èojþüù©©©ßÕËÏõL¦3Õ¼oß¾x~¬áÕ«Wé)É?Mš,%%Ý;52ëÞý¶,¨wêú¾¤¤$‡ÃÁþjjlŒ‹‹‰6·¤üç–²²²³gÏŽŽŽ¬µUTTäçç‡ý‘3™LWWW>ŸÞuà//¯-[¶DDDÌš5ËÃã´´tÑ¢EØªŽŽèׯŸ¾¾¾¾¾þòåË;;;333wïÞíïïߥ˜ d÷ðºï3((ÈÀÀ ¬¬ ª««±‹V‚œúöí«¡¡-ILLŒŠŠ" £ûZhhhÐÔÔ%%¥÷ÖÕ…ðæ]Ž]QQÛ“ÉüÏïùDEyÄ6–§§'žVNNÎþÝ;ÝÇŒíµ„ÕÙÙùøa©™%e€ªZïÔØÇ{ùì™àG¬Õ¯ÿ€O`gáÂ…C† éìì|üø±±±1¨©© ÚàØ5¬÷nH"‘BCCÛÛÛíìì<<^LØ„ nÞ¼Ù¥°ººº­­­¿¿MMMTTTxxx@@€””FÛ·o_—=xyy¹¸¸XZZ’Éï¿e¼fÍš‘#GR©T¬…õ‰½÷ØUTTV­ZuÿþýƒbètºXß4øì?3„jø¾†•ŸŸ¿ÿp”_€ŒŒLïÔX[S=uܨ»E’°::Ú§ŽUÏd€ž!–ª°¶@ÂÉ㿆õ=c³Ù~~~ ß® .—+!!ñúõë3fdgg÷dW—ö0ÞÞÞ111²â3.Ûwx ëjâEÊ`ÃY³fá¹…UVVvé\ ŸŸ{-a‰ÖÕKë™L}C#ß_ RÈÉÉ}Ól›6mb0ØÃ>Â'L˜ ø1$$ÄÅÅå³vþ­ƒÿ¤Þ¢W¾xŠó„5{öìA¦ÿ}±::Ús³³¶íÙ‡§TÕk\]]ÓÒÒÞ»JQQñ³F³ëÒ¼B¾Š=QøŸæ+++k÷¶-m­­¢¤7ð¸¼ÐC]‡£l…àOÂÉãØsxnaUWWßÏ»ËápDHo@C×#8ö¸ì!t´¾Ö”)STõŒE‚ =µyÇnüw “““×­\Æþa^ÍA¼Š:¸oç΀ï„ÕÚÚZÏdâ÷± ùQ°šš°gzñÜ%ôôôT8HÔQ ÒSÁë6â¿KxíÚµ@ß9‚!SS{¶o]³f à;aÉÊÊ*)« »ü"îÈä>}ú¾»„#FŒR ê(¾#¢YYY¢¡«A˰.!žÖ… –¯\yôd‚Â^yýqÈ+ týúuQ‚ˆlÀïÇæ5¿ëë>|Ï K]]jmKB©ŒŸ4eü¤)¢ŽA¾±‰©¹‘à»…åììü«lQG HOyÏ™‡ÿ»„§NãâÄjB3?#ˆx ^üˬY³ß-,“IÓ¼{?A¾.—á#)&F€ï„E¥RçÎÿERRRÔ Ò#cÆ{á¿K;ÂÁº©±AÔ Ò#KçûN:ðݲ··_üwAÄÝÔ™³©¦Æ€ï„¥££ã2b$‰„º„"Þ¬¬m­Ìß]³gÏNãÞÌBw D¼­[¹ÔßßðÝÂruuÝ´}—¬œ¼¨A¤Gæ-Xhcn¤þýû‹:˜/4nÜ¸ØØØPTTÔÖÑýqæ©G¼RUˆMFKz÷î«««¨Cú<§OŸnú¯'BÿüóO??¿k)éŸ8ï1‚ ß§›7èëê$&&’`ìØ±¿þú«¨Cú<ÿYfôèÑ{•“Wè…x¾slvKa~¾¨£@ĉúÀºú¢ŽâK‚³³4|_Ãâóù<®XÎuüÕÕVW¯^¶XÔQ âÄkêô«×‰:Šðø|.— øNX7nÜ^ü ê DEE :TÔQ bÀÝÝ]Ô!üË¡=¡ÿëâ•——Q^QŒlø‡–––‰‰‰¨£@ÄÀ÷öBÛÚ-Û,MßÏa1™ÌçOŸrŒ‰TÇ*+*ÊËËß +==ý÷ kZ[Ù¢A9¹ÿ~À÷5,ooï¾Zº¨Kˆ ânGø'+sÀw ëùóç·’®s8¢A¹—›ƒ=É„ç„u÷îÝC{ÃÚZ[E‚ =réLüñãÇá+&,,üáSÐéôÍ›7­º˜7o^ê½BôL‚ˆ»ƒÄ^¼x¾E «¢¢bÆ ŸX˜N§‡„„|õ0ùùùÑÚÚÚ¾Ñþ¿7I×®ðxèAY‡®&^<}ú4ô$a•””888HIIijj2 Ár--­­[·@QQ‘””F+++0tèP---mmmì&åž={°å=;œ÷{üøñÕÄKßbçß¡–––™^ž×¯\æ '9|ÉL½M§Ó¡' kΜ9uuu999 222Ý Ì;—D"+**úùùa ›››***âãã`Á‚PQQñÅa|ĬY³®¥¤“ûü(w š8©­½mgÈFï ã>7mikk»ºººººŽ1ÔÕÕW¯^­Z½zµºº:¤¤¤8::6ÌÁÁáÈ‘#*¦­­íææ6lذŋ··· ï߯Æûw²´¶¶z{{îVVVVß"˜oG8à.Á{{{ã¦{±ûàḸ8èIÂzðà‡‡F:t(ù}S+?xð   ÀÆÆ&++ëÞ½{ØBWWWggg¨¯¯ÐÔÔüâ0>"33sgÈÆ碻””´o¼­­ùÜ´¥¢¢’ššššššœœ ªªªwïÞÅVݽ{WUU‚ƒƒ¯]»–žžž““3cÆŒSQQ¹}ûvzzºŽŽÎ¶mÛ„÷Ÿ‘‘ö¹Çõéý\á’qqq^^^Ÿ[žxzzbÍ8uüØ¡C‡ 'Ïa™››Óéôû÷ï·´´P(”îÌÌÌ$$$¶nÝÚÑÑu@BBëòù|’’€ââbKKË/ŽäCjkkõfÿ¨½­ Zš›ë™Ì^«TØ·ÑQ õÀx[»3dãñ¨#ó,4üÙoäØÛÛçääðù|lŽ{2™œ’’2zôh2™¬¬¬ü¡bAAAC† Ù²e‹` ›Í–—ÿ×xŠååå¾¾¾<oäÈ‘³gÏ^°`›Íæñx‘‘‘ÖÖÖ­­­ ˜>}ú!Còòò¢¢¢Ö­[÷¡’gÏžÅö|ùòåS§N•—— —d0Ç‹‹[¼x±›››‰‰I@@€„„FÛ·op¹\ÿœœœÀÀ@‰Ï`0BBB&OžŒíÖÂÂ;äÀÀ@}}ýeË–Y[[–””t©Ë¢ˑvÙÞÞþÞ½{YYYK—.9r¤à Y¿~½ Æ.Åôôô‚‚‚¨T*öJ0†Ëåúøø:tÈÍÍÍÃÃÃ×××××÷sõߡϞJòÿÿ944”ÿù mmmI$’ººúÛ·o`åÊ•XÂ>ÚØØH¤~ýú­ZµJx•àC^^ž––|níÖÖÖøùFãz®¢"\¿~ýCß§–––‹‹‹‹‹ËÌ™3ù|>…B),,\ºté’%KŠŠŠ( ŸÏùòå‚ LLLìììîÞ½û¡bØÿ1VVVÂû711Y·n]{{» @\\\nn.ŸÏçñx?ýôSii)ŸÏ///wwwçóùêêêÏž=ãóùYYY|>ÅŠ)))))@¥Rù|~÷’K—. üùçŸù|þÈ‘#ïß¿Ïçó¹\.¶•††Æ›7oX,–……›ÍæóùuuuÖÖÖ‚Ý puu­¨¨xõꕺºú{ëÖ}-¶«––ìFþB„?Ée IDATkìRÌÍÍíÕ«W‚ª1Äâ>|¸ð—ðttt¼¦NOÏ/þ~þÃûò…Btàÿ[LÂ(Š 'ø¡2ÖÖÖ¯_¿þ²ˆD¢´´ôG p¹ÜÎÎNII)èÅ4ÒÙÑ1PSkŽ_@ïUùoÇFÖVWa# 7lø1ãÖ/ÿÈVX—Mx …Byðà¿:::‘‘‘PTTäçç———÷Þbííí$©ËþŸ?îííÝ¢//¯-[¶DDDÌš5«´´tÑ¢EØòŽŽèׯŸ¾¾>899-_¾¼³³333s÷îÝþþþ*ÙE÷}`wª««±ë>Äÿ–¶oß¾ØÈ–D"1111**Š@ ßS.ÐÐЀ]ÍPRRzo]D°+===ì—ËþB<<<>T¬¾¾^[[[P5FQQ‹‡)¢þ·sdxº‘þºuëÄõÕ))©ñãÇ_ºté#e®_¿¾vÃÆûué†|SAóäååG{Žïµ…åfgUW¾"‘Èç󇸺͛¿PÏÀðåóg_°·¹sç ÿøøñccccPSSü“Ó½˜ÀáÇnjÓe¡²²òÓ§O?’H¤ÐÐÐööv;;;SSÓýû÷ëéé@gg'å>|xHHˆ³³3‘HüxIŒšš“Éì^rÅŠÑÑÑ«W¯¾|ù²ššv9‚Çãa{n#oÛ¶-//ÍfÓh4ÁBáJJJUUU<¯±±º×%¬ûZÁ®„÷)ü…` ë½Å”••±[UXÕ˜ÆÆÆÊÊJ‡uØ –àp µ•Íf³ßïŽ;–¬¦%ê(zÕ±ÈÀqŽ¥ªOÜÉdºººbŸ¯]»†}˜={¶p™ÐÐÐ’’‡#|í¼K1&“éææÆår-,,öîÝ+¼>ŸßÚÚºcÇAák×®|¸¤’¸NböfÏóu?WW×´´´­UTTìrùbAX—Ï£5œ?~úOcšY,Q‚ Hl\µ{+Ï-, {'gÁuAÄ”™%ÅÂØð°œœœVȼÿþ‚ bdúì9øïž}ú÷ÕËݧ´DD¼ÜÉLONN|'¬{÷îEØ×Žžl@1wùüÙ“'O¾»„¾¾¾†V¶¢Žâ{±~ù⪪*QGˆ!ÃGú.X$ê(þsÓÏ ëîÝ»‡öý%PF’ åååd2ÙÙÙYÔ b !!¡¡¾^ÔQüOâ¹3Ï‹óç΋ç„õüùó]õñ @ ãææ†ÝjA£Óé¢á_r³3™5•8OXÞÞÞšÆæ¢ŽAžÚ¹ïþ§ùJOOß¶q]+=‡… âíä±£û÷ï|_ê««{ò¨ŒÇã‰:Azäuy¹‰øNX'Nì7è?ùCäû·~ëvüw étú¯A‹ØìQ‚ HD„‡mݺð°¸\nggŸ/ê8éNg'öÊ ž»„cÆŒQPÕu½§³£CMsàÑÒUkðß%¼råJÀì-Í?Ê~Yi{¶o­­©u ò•í Ù øNXd2YCKëÇ™5g˜ÛˆûùyÞÆ¡´…àLUUlZ?<ÿ1»¹¹mÞ±[ö‡™œH$Î XÀápþ¼xþsÓ–¶¶¶««+•J‹‹^âêêºsçÎ÷€””GGÇaÆ9889rä«Qkk«··÷çneeeõÕ#éIëׯ2dHRR’ðBooï¶¶¶¯nùýˆµ°ð| ëìÙ³K—-?~æ‚™,êXzÉpÑ1‘‡+ßTp8œ«‰ÿú3qÜ„‰³}ýUÕÔ?¾¡ŠŠJjjjKK‹“““`ÉG @ppðÍ›7ûöí õ}õŒÇã}bSW¸d\\œ——×§lõÝâñxýõ×ýû÷…—‰DOOÏøøx___Æ&FÖÿºÜHO7::Ï kРAC\\I¤Þ>Æ'm]¿¦—+PVéû¦â5ðx<'H[œO*šÅb}ü½Ë.ÈdrJJÊèÑ£Éd²²²2”——/X°€Ífóx¼ÈÈH kkëÖÖÖLŸ>}È!yyyQQQëÖ­ûPɳgÏbû¿|ùò©S§ºì“Á`?~<..nñâÅnnn&&&4mß¾}ÀårýýýsrrI$R||<ƒÁ ™‘%•fil>®oûg”ôr;C6>yTÖË• c³[ªÞ¼üH$y<ž‰¹“ñvêÔ©zùY[[[WW·¨¨(!!a̘1Ø===X·n»»{÷P^^¾sçÎôôt2™|èÐ![[ÛñãÇïܹÓÔÔôÕ«Wt:}àÀúúúÙÙÙñññ‡Z¹r¥§§gxxø‡J ¢¢ÑhÝ÷¹lÙ2‡ÓÜÜëîî¾{÷n+++AÓLSS377WQQÑÉÉ)77WVV–ÉdzxxäååuY[\\ìææÇãñªªªº×%ü- ><66°Â§N222²³³ãóù¡ËW*8++«ÂÂBá%ÂG׃_õ7¤««kek¿bõ:Qò?ø^æÄ‰óç/¸tãVŸ>нVéêM[z­®÷Z8wvMUÇ“àr¹f–¿_i¶v³'z~d+•´´´¬¬¬={ö`ù¨{—°KÐÑщŒŒ€¢¢"??¿¼¼¼ÒÒÒE‹þD©££úõë‡ý‰:99-_¾¼³³333s÷îÝþþþ*ÙE÷}”••@uu5vEIБìÛ·¯††¶$111**Š@ 0Œîk ¡¡ASS”””Þ[—°úúzmmmAa//¯-[¶DDDÌš5ËÃãKáî‡ó¡DþÓÒ~º:çÎÃs¢P(>~þÒÒ?ÐØ2y¹wJKŠ±Ï¦–XªúôÍ7nÜøâÅ ¬mõŸ?~lll jjjXSÝÔÔtÿþýØZìI?áKWÇ qvv&‰/‰QSSc2™ÝK®X±"::zõêÕ—/_VSS+..¶´´´°„;Û¶mËËËc³Ù4 [Ò¥)¤¤¤TUUÅãñß¿0ee劊 À “H¤ÐÐÐööv;;»î «ûá/a0XÞD>ÅhÏñV&F€ï–™™ÙïÙR?Ò³”1QGÀÒŠêû™©JÀÏÏïèÑ£ØÁÿ,ZRR"##ÃápÂÂÂàÀÍÍÍD"ÑÅÅ%$$DxÛ™3gR©Ôœœœÿ,‰™0aÂÍ›7»”TWW·µµõ÷÷¯©©‰ŠŠ ’’\ÃæåååââbiiIþÀ—5kÖŒ9’J¥b¦GµvíÚQ£FYYY©¨¨Àµk×<ØÖÖ&¸ ñéètº¸ßOèMnPÍß×°bbbüüü®¥¤÷QTu,½!/÷Ή?ŽÎ›¿ð½©jöDÏñãÇ‹×~l6ÛÏÏ/!!áÛUÁår%$$^¿~=cÆŒìììoWQÞÞÞ111²²²½VãgùÞ®aúÎÑ×ÕILLÄs ËÉÉ)xÝF™ïõœøêTúö;}\ÔQ|Mrrrß4[@FFƦM› Æž={º¬jllœ0a‚àÇ—íç³ À·>.œñþyÍÔðÝ%8p µ=‰$)ê@z‰ž¡¨C?®®®iiiï]¥¨¨(|Ûáã>«0ò¹›˜Qp?Uý… ¼'Œkf5‰:AzdÓêà… ¾[X#FŒø}w¸¬œ¼¨A¤G/±57|·°deeûöë÷ã¼üŒ x¥¨¨„½Jç?æk×®-œçÓÒÌu ‚ôHض-«W¯|w Çq센Âòæ3‚àÕŠ5ëí-Mß-¬ööö¦¦F4k‚ˆ;vK ‹Å|·°nݺµfù’k)é’?ƃ£ÿ©¨¨èÀ¢ŽMMß×½õÈáøptòäÉÒÊýÈ}DÈ÷"#####CÔQ ÈgÛ¸}—#Å ðݪ­­-¾_ ®>ø#½Nø!ÇÏ%~_ÃB¾:¢„„¨CøŸçOž(J444ðœ°233C·næ6Í%’’?ÊÿþœŽ=–£«ãîîŽç—ŸÛÛÛ“ïä)ÉÝWCDŒ°Ù-ÎVæ x¾KøèÑ£?/žï> ‚ â%3õö7ß5Ü¿?&2¢½ÍM‚ âíjâEl| =Îm u DÌýºx¡H`¯â’¼¼¼¼JÿÁ&fßÓ”‚|.ee• žcõôôðÜÂRUUµ°¢Jð|A~úFF&&&€ï»„/^œ=i|3 =8Š âmËÚß/^ ø¾èþúõëøKÚ9:£YÚD¬•Þ·1lgg‡ç–´´tŸ>Šèågwròò €ï.á_ýè÷sK3KÔ Ò#{wü¾nÝ:Àw—ðíÛ·‰ß46Ew D¼½|ñÜÞÂÄØØÏ-,6›ýŽÁ@³æ ˆ¸kl¨¯¯¯|w SRRÖÿº¼•&¡@ñ}èÀ®]»ß]B‹õ×í õèº;‚ˆµwoß:Z™©©©áù/¹²²2ÿn.‡Ó)ê@鑲‡ŠŠŠß]Âììì°m[ÚZ[E‚ =rædldd$à»KØÙÙ™’›/++‡Fk@±ÖÖÖ6„j.++‹çViiéùøS¢A¹}óÆÕ«Wß]¢¢¢¸c´··‰:Az$éÚ• .¾»„€ÆtG¼Àÿ˜î999ûví@ÝDÜ‹‹ŽŽ|'¬W¯^e¥§r8Q‚ Hß/¸{÷. .!‚ bÿ]ÂÛ·oo^ók+›-ê@é‘c‘aaa€ïi¾X,VeEzùAÄ£¶¶¦ .!‚ bÿ]¿ÿþ{é¿–4Z‚ˆ·ý¡;6lØøNXRRÒèµw$II)))À÷¼„úúú¯ªk‹ï˜YR._8÷ôQ™±‰iÂÉØÚê*=Ãc‘­l¶ö C{ÃH$’²ŠJä}dEEIâØáˆjê--Í'£ÒÓ«©ªŠ=>ØÜüÉ£GçOÇQmíòïæ^M¼hcï–r+=å…ftíÊý¼{f–‰çÎ<úÄh°Iü‰˜·okõô þ8|¨­­MS[;bo˜”´t%Ũû•”BÌ‘Ãj²šX'ÿ8ªk`PõæM‰ã¦––ž?emïp/'ûúŸ‰Öv©·è™©·-©´ëW.ß/05·¸x6¡üÅsCãÁ§Ž«{ÇÐÕ78q ³³c ¦VÄÞ0i2¹Ïуû•TTø<~LäauMÍÆ††¸cÑz†F¯_9kF±zø øBüiÇœ¬Œ¤«W¬íìSè7²3Ò-­¨ý™ø ¸ÐÄÌâBÂéWå/ ÇÅD×3™:zú‘öq¹\5õ‡Ã÷ÈÊÉÉÉÉG: Ò¯‡Ã9uDCK«žYw*æcãWå/ÏœE³³¿—sçZâ%{‡Ô䛩)ªõßWÿ,*È7µ°¼t.áųgFƒMNÇÆ¼{ûVWß :â`GG»†¦VÄÞ0)irÅ£÷+*+@Läa5 ¦¦Æ¸?¢õ ßT¼N8kfI){P‚¹Ù™×¯þimgûæ¬ô´N¶Âû¦æÏÄÿs²ÅüÁ¬{§£§ôÐ~‡£>PãpøYYy…£‡(÷íËãqG¨©ÕPÏŒ;ö‡¾‘QEyù™“'Ì­¬J‹‹/$œ¶utº“™q㯫4[»dzRNfº…õÚåK¥ÅE&fæçãOU¼*702>yìhCC½Ž®^ä}<oâÔé>3¦¾[XPRxÿîl(¸w÷~~äfg––@fêíg@Êͤ×å/;:;’éIÕ••-Í-Éô¤wïÞ60™Éô$VSÓÛÚÚdzR[kë›×¯’éI<ïåógiÉ7àQéƒìô4¬¢{9w ÿ^nQA>ÜÉÌ(+)€ŒÛÉ/ž>áóùÉô¤×¯Ê;Ú;’éIÕÕUÍ,V2=‰YWWϬÃ*ª©®J¦'µ··UüE/ž=MOI€²ÒÙéP|¿ /7òrîß/€;ie¥ =ùÖ‹gOy<^2=©âõ«¶¶ÖdzRmM5‹Õ”LOª¯«c¾{—LOjifau´·W”—'Ó“àù“'©ÉððAINVæçåßÍ€{9wJ ï@VzÚ㇥–rëåóg\.7™žô¦â5VÑÛšš¦ÆÆdzR}=óƒ‘LOjii©®|“LOêììxõòEÊÍ$xúäQFj ”–çde@aA~Á½»XEŠ  3=õqÙCH½u³üÅs‡“LOªzó¦•ÝšLOb¼­mh¨O¦'564`±Ù-U•o’éI\çÕË—·oÒàÉ£²¬´T(-)º›…y÷ óîÀÝì¬Ò’"ÈJK}ò¨ nߤ¿zù’‹UTù†ÍnI¦'½c0’éI õŒ·µÉô¤VvkÕ›7Éô$‡Sþâyê­›ð¸ìafz*<(*Ä΂{w ò '럓-#5åé“GØÉöêå‹ÎN¶7--ÿTT_ÏL¦'556¾­©I¦'µµµ¾©xLOâr¹/Ÿ?KK¹–fu9Ùîææç@NVÆÃ%‘šüüÉH¦'U”—w´·'Ó“jª«ZšYÉô$æ»wõuuÉô$«©¶¦«è_'[ò-ìd»“‘öÏÉ–sòrs°“-;#ýŸ“-%YødkooÃ*b55%Ó“ê™u̺ºdzR3‹UýÏÉÖñúUy2=‰Ïç¿xú$ãv2”•”ÜÉÌ€¢‚üü{ÿ:Ù²ÓÓ•>€´ä›/Ÿ?üEãü¢;‚ x‚ó‚ x‚‚ b%,AÄJX‚ˆ ”°(a!"6PÂBDl „… ˆØ@ A±‚ b%,ä먬¬ôññ!C‡^)%%µtéRÁ*•ºÿ~ÁL&ÓÇLJD"-^¼8 ÀÕÕµ¨¨H°påÊ•ï-ðÕã®ñSÊ?{öLFF櫇ü>‚|%OŸ>•””ÔÐÐÈÎÎÆ–p8wwwyyyA™¢¢"SSS*•ÚeCiiiìó¹sçlmm»,|oo¿ –¯[ùZP ùšˆDâòåËwíÚ…ýxáÂ///áqqqgΜ)+++)yÿ`°&&&Ïž={ï*A’’{{{™ýû÷»¹¹@QQÑĉ—/_>cÆ ƒ«W¯–ˆ½~ýº±±qPP¡¡¡»»{mmmjjª±±ñ©S§ºï¿µµÛùž={ôôôvïÞ-XµtéÒ¹sçNŸ>ýÈ‘#Û·oçp8‹/ŽÇÖîܹóçŸ^ºté¸qã222>´“/^LŸ>}ùòåS¦L €L™2eÉ’%'N|òäÉ'|Í?0QgL?°FGSS“ŠŠJYYŸÏ÷õõ}úô© …ÕÙÙ9cÆ >Ÿ?}úô+VtÙû¼gÏž±cÇò?Ü <}ú”@ ܾ}›ÏçGGGóù|“{÷îñùüãÇÏš5 +¼páÂààุ¸¿ÿþ›ÏçÇÄÄ`455ýòË/ïû@ JKKSSSµ´´°µ•••¡­­­±±1,,¬{ +!!û™™I¥Rß»>ŸO£ÑÒÒÒ°oc̘1|>ßÜܼ´´”Ïçÿý÷ßîîî_òÕÿ0ð< "d2yáÂ…¡¡¡3fÌððð^uãÆ wwwðñññóóÛµk‰ôÏÈáp~ùå—¶¶6 ‰˜˜˜î»íR€Åb‰Dìz™¿¿MMÍ“'Oh4ØÚÚ®^½Ûj×®] ¥¥¥åðáÃ0}úôÕ«W3ŒK—.Íœ9ó#GA$MMMŸ>}Z__-0`…B6lX```PPÐëׯ»l¢ªªêííM&“›››±Fb÷ÔÖÖ:;;‰Dº~ýzMMÍÇ= mmmD"êô| JXÈ×·dÉ##£æææ„„„—/_ –'$$H¤»wïr¹Üæææ¤¤$OOOl‰DŠŒŒüÈ>»`±X$IBBû‘ÿaݬ­­SSSÛÛÛ¥¥¥åää¦OŸ[\\¼`Á‚WÂÿŒ#‘HyyyW®\Ù¾}ûùóçÃÃÅ˳X¬qãÆ={öìÊ•+ïÝ öÐmÜî°°0¬pssóG¢BP:G¾¾,Y²ÄÓÓSP ¡¡AVV6666222::záÂ…'NœøZ5ª««@^^Þˆ#°åGŽY¾|ùСC7mÚ„-Y°`ÁŽ;lmm?·Š7oÞlÛ¶mâĉÑÑÑ÷îÝ“””Äf;wî´µµµ··÷íÛ„stjjj %;;:::¦L™¢¦¦fbb’‘‘UUUO£º†…|uuu³gÏ–øí·ß ›ššfÏž-))¹xñâqãÆyxxÔ××óùüööv///iié°°0Á†Õb€(IDAT £ËÞV¬XñÞ‚%MMMØ’ÂÂB//¯eË–M›6­¶¶–ÏçïÝ»×ØØøþýûaaa6lÀJ:;;ca¼7þ+V`Μ9³iÓ&IIÉÐÐP>ŸÿîÝ;77·ÀÀÀI“&ÅÆÆr¹Ü¡C‡ÎŸ?ǎضoßîàà4wî\IIIè¾>ŸÿôéÓiÓ¦-_¾|Μ9Ø5¸’’’±cÇ.]ºtΜ9oÞ¼ùê¿·£Ooìââ"bw”‡ë;õèÑ#%%%uuõøøxb ›Í:t¨„„D¿~ýJKK“’’,!!annž––4mÔ¨Qªªª»ví¢Ñh£GVUUUVV~üøqÛ— ÷E¼PEEESSóèÑ£½zõÒÔÔÌËË€]»vÉÊÊJHHŒ7®²²’hÜjͪªª»wï~ïS‘âââLMMÅÅÅMLLâââŽ=*--ýêÕ«E‹ 0 ¦¦fÆ JJJ§¸¸˜N§_ºtI0v[¿~½´´´¬¬¬““‘¹Õæ wdkk;|øp ¥Ñhaaaíï«O|G:D¼ ¼«‰‚m»ûŽðÑwI__àÀ)))¦¦¦Ä¯™™™––V\\ܳgϪ««ÍÌÌ,--ÓÒÒ¬­­‡ Æçó@SS3))©°°/×××oûrá¾ÀÜÜ<""BøÁž={ø|~hhè‹/ÂÃà †››Ѹ՚`ýúõzJÉØØØÔÔ”xÖØØ˜ÇãY[[ëèèÐéôÐÐP>ŸŸžžwïÞ=uê”””Tuuu~~~ee%ŸÏ—––>wî\JJJHH‘¹Õæ wtãÆ –——·råJ ×þ¾ì‡îÿ¯Õ;²lÙ2ÈÏÏÏÏÏoµ«›O}:888ØÛÛóx<___(((•••““Ó××üøñƒœ÷ìÙ­6íÚµ‚Žºuë6kÖ¬¿þú«¢¢bÁ‚m·ÝW‚=,üccc£ðœœ¬¤¤$ür99¹œœœ   AË÷v÷ÀcXß©'NþøãòòòÄ’ .((( 2dÖ¬Y/^¤Óé¶¶¶ÅÅÅm× //?yòäâââãÇ·}ù'ÆXºté7nݺ%--ý¡5·Ó©°³gÏr¹\333.—ëéé¹}ûöüü|''§eË–½yóf̘!%%%++;iÒ$::vìØ1CCÃM›6 Žaµ¿ùL&³¢¢bذaZZZm,òÿZ=;cÆ UUUSSÓqãÆ /_³fM@@ÀÙ³gK>±;j"{ˆ‡º$øwzÒ‘k½Óúúzssó+Vˆ²D"a¡¯ORȳgÏÈŽó?ÒÒÒµµµ7n$;úB4>~Ó!ÔEà !Ôe`ÁBuX°¾wx.áë´Á:LÇïüúl\.WðuªŸŸßê[]mup$§kÇge&e?ª#÷GXß)<—Pø\B6räHUUU555ÁW1[`ØN0a­^ÕÎnd0ßâœÄíí¶›ßö…­vBÇïöÛà÷°¾Wx.¡ð¹„`ffFüÁÁømN0l'˜°V¯jg7;vì[œ“ø¡½ÝvóÛ¾°ÕNèø=Ð~{>žKøÝÂs Û&äñx‚`ü6'¶LX«Wµ³¿Ñ9‰íìímþ‡vBÇïî<†õÂs Aè\B"ñრFÛ Û &ÐêUíìÆotNb;{»Õæ·Õj'tüøèNÀcXß)<—>pF í †íôþ¡Wuü9‰íhµùÕñ{à£íqJˆ¾|ç~»Mî0"žJÙöްÐ×÷]KØi7¶­V›ÿµ’wäÀs B]ްB],„P— !Ôe`ÁBuX°B],„P— !Ôe`ÁBuX°B],„P— !Ôe`ÁBuX°B],„P— !Ôe`ÁBuX°B],„P— !ÔeP¼`íÛ·ïàÁƒ°eË–Ó§OÀªU«®]»Æçó™Lf```UU“ÉŒˆˆÈÏÏg2™l6;%%…ÉdæååEFF2™ÌÊÊÊ   &“Éãñ®_¿¾råJ8sæÌæÍ›àСC{÷î€;v¸¹¹ÀÚµk½¼¼`É’%þþþõõõL&óéÓ§%%%L&3>>>##ƒÉdfeeÅÄÄ0™ÌÒÒÒÇ3™Ì¦¦¦[·n988ÀÅ‹ׯ_Ç'îQþçŸ=z6lØpîÜ9X¾|¹¯¯/‡Ãa2™>,++c2™QQQ¯_¿f2™iiiIIIL&³°°0,,ŒÉdÖÖÖ,Z´¼½½ûí78uêÔÖ­[ÀÕÕÕÕÕþøãpttôññ€… Þ»w¯¦¦†Éd†……0™Ìäää/^0™Ìœœ‹Åd2ËË˃ƒƒ™L&‡Ã¹qãÆŠ+àìÙ³Ä-Ž9BÜØÎÅÅåĉ°nÝ:ânéööö·oßnlld2™!!!oß¾e2™±±±™™™L&3333..ŽÉd¾yóæÉ“'L&³¡¡áÎ;vvvàååµnÝ:8yòäÎ;௿þ:|ø0lÚ´ÉÓÓV®\yãÆ .—Ëd2d2™---~~~Ë–-€óçÏÿþûïpìØ1âÎc»ví"n¥åìì|áÂXºtéÍ›7›››™Læ£GÞ½{Çd2cbb^½zÅd2ÓÓÓ˜Lfqqqhh(“ɬ««»{÷î’%KàòåËÄM·þþûïíÛ·w¹? Á_4•o¤zâÄ —]“~žjÏgE¾-ÓÌŽdEÓ¥º÷ÑÒdE©iëq»ÉD²¢ Yª–VD²¢"â’h4Z$+*,.©0?/’—›ÉŠ ‹g‡GÇEFE‡Å³#¢ã²³2ÃâÙѱÍMMañìVtoee“aìVTÔ Í"£¢{ª¨uSìÉŠÒ1ø®®9’e—Ô]F&’—TQQNt”’”øÏúcâ‰1qÉ DG•eañ숨˜î22ƒâÙQÑå5õÚfÏ£¤äUD²¢4ô ëÉŠ2µ´ê¥¤D¬¿¹©)’Ÿœ•IlHDlBÄsVX<;"&žEôSXP@< „ų#£bòJÞX `EñÅ%ûéE²¢újhѺËG²¢ Ì- Ë«#YQ᱉ qq¢£’âb¢£XAþØ„ˆöXlæË—DþúúzâbfñìȨèºf®†ÑÀHV”‚²J÷Þ*‘¬(m#ÓŠ&n$+Ê|x¢œ¼<±þêª*bG¥¥¦D²¢ÂãÙÿv—C¼¥oßë—””²ˆgG°¢KÊ+uÍ-#XQ2r½5t"YQýu šÄ$#YQÆCûª”ëçr¹‘¬¨°Ø¤¼œ×‘¬¨°øäÈßñˆ˜¸HVtX<;<*6/ç5±~G<èÓWÅÈ’ÉŠn¡1ÔôM"ž³”Ô4ÄåzF²¢ôÌ•T×G²¢†Ä&JJJ½+-%vTb\Â?ïHL|Ä¿¥¥°‰7¢¦ºšX¿œ¼üÀxvdTLUC“¦É V”lÞr}Õ"YQš&5\z$+jà°Š=zF²¢Âbê#YQáqÉ/Ó¿QÄ;ó))"ÖÏïžW®mß°>(ð¾……•ïšâyÑkÅšudA}¹’¢"¿kÞûv»¨««S¹`@X<›ì¡¯`¤¹1PûÖþýûÇZš“!$’”äÄуM###@Œ8TIIâââ iY#S3²ƒ „¾FWìÑóçÉ?þðÃTžÖ××?~+¯ @v„Зãp8µ55“F §ò”ðøñã¿LKv „H^¾H™:~tLL Pûk ?ýôSm ì!‘¨ôSÛâò§––Pû »²²²Ž¾Ù)B"‘’–ÖÕ7‘‘j¬³gÏ.™ý+Ù)B"ÉÊx¹pÖôÄÄD ö”pÖ¬Y y²S „DÒ_}ÀëëëµGXbbbd§@‰„N§‹‹KÐét vÁòññY·r)Ù)B"yå´Ü>55¨ü=¬’’’{!ÏtôôÉ‚úr y¹9³mêÞ½;•GXåååyyd§@‰¤©©)?/·¡¡¨=%ô÷÷ß½uÙ)B"ÉÏËqÙ¼!##¨=%¬©©yݳwo²ƒ „¾\KKKeEù”±£$$$¨<ÂJOO}ò˜ì!‘TWU†>~TVVÔž>zôèä!W²S „DR\Txüàþׯ_µ§„\.÷Y\2ƒAå/Ç"Dy|>ŸËåZ[˜Ñh4*°ÂÃÃ/œ>Ev „HÞ¾)9çñw~~>P{J˜pÇï:Ù)B")/+»ã{½¤¤¨=%¼¦;BTAýkºøÓ…ì!‘æçíßµ#++ ¨]° ØI d§@‰¤¾¾ž˜PSS8%Du ÔŸúúúnY·†ì!‘ä¾ÎÞ´Ö1-- ¨]°šššêêjÉN Ç««­år¹€SB„P—@L ©ü-ðK—.¹:ì~Þ‹ì äóüûäKv"Ù)P—1ÉvúøI“ÉNñW™®»w^õ¾bbbBå‚õÃ?()+“¢S(,ÈÏÈÈ?~<ÙAPàëëka5Šìÿ#.!¡¤Ü§[·n@íÖ´iÓz¨i’¢³0`À7ÈN:;>ŸO\=½óP믾Ëõ®®.Pû »»»ûÛŸÈNIzÚ‹Y?OŠ‹‹j,MMÍ¡V#ÈN‰ì? 1JAA¨=%´±±‘êÙ‡ì!‘ôUé·vã–µGX‡š4rÙ)B"yÁN¶±Âb±€ÚkèСs-&;BH$={÷ž·ÈNEE¨=%´°°¨å‹‘!$’ž½zÏœ7¿oß¾@íÖáDzþ^ºóx<²# ôM¼HIž4rXTTP»`Mœ8qݦ?ÈNÑAŠ þܶ9÷uö7í…F£IKK÷/¡ÑhÎÎÎàïﯡ¡Á`0úôésäÈâ)F§Óõõõ‰C‚Ƭ¾¾^UUõܹsÜoGn/ŸÏ744Ü»woÇt×ñúªôsþc;õº«««›±$;E駦ÆçÃÂYÓ]¶lü¦e«¡¡ÁÍÍMxɲeËtuuÓÓÓ¯]»¦­­-XøòåK:¾téR{$Îzý²öžžžsæÌ1ÃçÊÏÏß¶mÛ¿ü³6™ÇãÙÙÙíß¿¿®®î‹{ìÌdde ±”——j,ùÓ§’¢ã,´_ .œ5ÝeˆoT¶´µµOž<ÙØØ(XR[[›––v÷î]yyù)S¦ eddtttÆŽK\ä½Ö¯_/---++ëääIIIƒ–077OKK£Ñh£FRUUݵk—­­íðáà 44”F£………µj Âí]x{{1BJJJÐ@EEESSóèÑ£½zõÒÔÔÌËËÛ°aƒ’’‡Ã)..¦Óé—.]j•“F£9RUUUMM-''§mr6zôhUUUeeåÇ€ªªêîÝ»?k{…7Á`´ÚÞö÷MUUUPPЗ¼£^ÆË´9¶?ÅÇǵ ÖôéÓw¹";EÇQS×k3‰F£ñx¼'ƒ¿QÙš2eм¼ü… Kœóóó×®]kjj*<âp8 jjjZÕ©S§ÜÜÜX,–­­-,Z´ˆÁ`$''ËÉÉÙÙÙ@QQѽ{÷–-[¶`Á‹•ŸŸýúu #F´m,Ü^ЛÍÖÒÒüXWWwãÆììl//¯;wîdgg_¾|ÙÞÞþíÛ·AAAþþþ’’’¿üòKÛ¨µµµ>>>ùùùÞÞÞm“@MMMPP²²²££ão¯`Ž;Öj{Ûß?Ä6&''¨ë.MM]cÏÁ£zzz@íO »wﮨأ#{,ÈË»~¥õÿçõïÅ‚ˆcðO=|ò0xÌ›¯8Y ÓéëÖ­;|ø°`ÉŽ;‚‚‚~ÿý÷S§Nº½‚MÐÕÕݱc‡ðö@;ûGxÀK= C¡‡¢¸¸8P»`yyymݺõItÇ]ÖýÝ»··}¯÷ìÝ[B\¢Ã:Æçÿßg…|ÏçÇEG))÷é.%ùµzY¸páöíÛ?®Y³†Éd6LQQ±©©‰XÈd2·lÙÒ·o_IÉö«¯¯ÿøñã8;;ïÙ³ÇÐÐPLLl÷îÝÍÍÍ999k×®%~G [·n³fÍú믿***,X­Í팉›ÄÄÄZ= þòìííy<ž¯¯ï{£Š‰‰Uƒhß*9„‡‡§¦¦†…… Žâ}îö oBÛím»ÉÂû‡ØÆö‹uו•¹r1ÓT'bøðáT.XóçÏ—SVéø~ÿ:tLÏÀ°ãû€³§Ü.yžÆçóØ-ýù—é{wn¯(}óµz‘’’Z½zõŽ;ˆÓÓÓmll*++544ÜÝ݉…òòòÄÇ:í &>Ä1‹/ÚÛÛÛÚÚÊËË/Y²¤Uc&“yúôéaÆÓŸö Ì;wË–- Äa¬™1c†££#NŸ4iÒǶþ=ɉí88X^^þÃw9´´ÝÎ]266j_q4##Ãï^ЈÑc:¬ÇÄøØß–œöò!¥`ÕTWÿú“MC}=(öèA”* ‰nà²ecEéâ|÷ïJCCƒ®®îÎ;Û)jD³#FXZZþý÷ß_Ð F[¿~=1îx|>ßÈÈhþüù›7oþ*k£Óé«Ö:ÿg>Sôµ}ÕÕUIñqË-PTT¤òëæÍ›Û:vJH®ëÞ^ õõŠ=z.°s”ªïœ””T^^ÞG›IKKëèèlܸ„ç°ÁÁÁ£F}ù¥ì¾âªÚA£ÑRSS¿Åš;‰¼œ×¬w²jAñ)á²eËÔõÉNÑAjª«C?\³a3–ª/ <Ïø‚Øš¦PûXx‡ÑÑÓ÷¹`nnÔ>èž››£¢úÁÕ©¤®¶öµ›íZ‘‰®®¶6.&zÌÐÁ’’’Tþý :¼÷O²Stå¾}±Z!J*,È?¸g׫W¯€Ú#¬uëÖ™YY“!$#“ÀgÏ---€Úßt‰‰¹yÍ›ì!‘”½+õõ¹\\\ Ô.XÏŸ?¿|þ,Ù)B")}óæò9Ï‚‚ ö”ÐÙÙÙrìD²S „Db`lò02f¨¹1P{„õðáÃcö‘!$’¢Â‚£û÷fggµ VVVÖó°gd§@‰¤¦º:"ì)qÚ9•§„+V¬0²ü^.‘üQïÞ½óôô$;êì:á¹zºú7 27j¬Û·oŸt÷رוì B^^žƒƒÙ)úly¹9žŸzÏËÎ&44ô£™]]];øÎÏ¡¯.•´r13"âß;?ÛÙÙµ?Té„ôôô>Úfܸq%åU¦óklh¨¬¨ ;êJzôê%..Nv å>*Žë7¨««µ?%ÔÓÓ=nÙ):…gOBþÜön Œ¾ç¯újjë@N^~Ìx›ž={µ –››N …>}Z^^žì¨³KJJÚ³gÙ)þ'=-õÿ¦„T5uêÔF#;E'2eÊ”>}úuv?üðÙþªšúŽ¿öëè赿ÖУGµþêd§@‰¤[·njêRRR@í‚uþüù¥ æ!$’¬Ìt»¹³’’’€ÚǰæÌ™#¥Ð‹ì!‘h Ð:â~ÆÐШ=Ââr¹‡ì!‘ðù|‡C܃Êëúõë׬";BH$9¯_ýî¸âÅ‹ð F#¾}*xð)‚ƒƒwîÜùµ2´bggwÎçÆ7Z9B¨chéè]¸ægffßb„•ŸŸ¿mÛ¶OlìââòÕ3Þ¼y“™þò­¼³áñx5ÕÕd§@èëklhÈLYWW¢,6›=tèP ‰~ýú•–– –«ªªîÞ½’’’,!!annž––4mäÈ‘ªªªjjj999pèÐ!b¹h[ô~{w~jéìêètú?]þܶ%?/—ì,}Mù¹{¶ÿ‘™™ ¢,&“YVVÆb±|||$ßw ©E‹1Œääd999;»î^S[[ëã㓟Ÿïíí Ë–-€üüü/ŽÑŽß~ûífÐão±æÎ‰i¿ôaà½3l¿ l©©©Y[[[[[7úôé³iÓ&â©M›6_7 6lبQ£†êîîþ¡fjjjcÆŒ5jÔêÕ«‰{É Ö?xðà+W®|¥Íýˆ†††9s>ûK-ļ£ n›|Μ9žèëÓ30ºóð©……ˆòµ†”””¥K—š›ðÆ)))4mðàÁÍÍÍ‚û_[[[[YY@EEÈÈÈ@¿~ý¾8F;Ølvðý€ÿÌg~‹•wBZ:ºV£­ÃŸ>yxïQÐýñ“&/tX¦ªÖÿS^«¨¨øôéSÁJJJÄõÒ ::š¸‘³³óÇ{ôèÿ¾}ïm¦¨¨øäÉ8xðàž={víÚ%XCCÃðáÃçÍ›÷YÛÅãñèôOúÏ*ÜÒËËkÚ´iŸÕÅL™2ÅÛÛ{É’%dUeyùàûƒôµTTT¾|„eddœ^SSÓ¶¡¡¡±±ñõëׯ_¿~àÀb¡˜˜1$J˜„„$''qŒvÔ,$$ÄÐÐpþüù\.W|Á‚†††Ä °±±¹uëÖ'¾ÝYII‘û±Ã¹¹¹ ÊëÂ… C† éÕ«ñ%ÔV.^¼hoookk+//ÿ¡2?cƌ˗/›šš †`Ÿ¨±±ñÒ¥K×®]k¿™D·nG¶þCúvZš›ÀÑ~1‰wúfˆ‰q¹\>ŸÏãr ø~À£ û½Gyy¹µµ5¨¨¨³¶Ù³gŸ?žÏçÛÙÙÝ¿.^¼¸oß¾;vÈÊÊž>>sçÎm§¥ ÷’’EEÅE‹H™­å IDATµjéïï¿zõêÚÚÚ3fL˜0ÁÍÍÍÌÌŒÇ㯪¨¨pqq‘““>|xTT”ƒƒCyy¹ÍŒ3Ú6èÑ£Gpp0Ç#ŠuÛTÂ{£í³Äª”””^¾|©  0räHIIIá}"è±U3999âŸàÿDyyùÞ½{y<Þâŋnj½zõ*,,üœßNÊÈÄìY\òpsc¥`™šš ¦ðïˆIø©©iLLŒðKÚ¶4hP^^ÞôÎãñ8Nçü^h«Qä\KžÇãùûùÖ××ð@LLŒËåš ll:ØÞU+ZM ÀÔÔ”¸×®‰‰ ±D]]ýÔ©S””dggûÞfMMM £Õú_½z5gÎbÌ2mÚ´]»v¹¹¹Í›7ÏÆÆ&55uåÊ•DûææfèÙ³'Qƒ†¾víÚ–––ðððØÛÛ¨e+m×éè訥¥E| T\\üχåÿN${ôè¡¢¢B,¹uë–‡‡FþLI¸Aee%q4ƒ¸FÛ¾ÚO"XÕ€ˆ\.·Õ>ùP³ŠŠ â œ‚ËoÈÉÉaÊËËÛî‡.­¤¨èæuÕ];ÕÕÕ»ê©9ÒÒÒK–,ñôôl§Í‰'víÞÝÁÇÝl3ÈbÈ2G§ŽìTà¾ÿíººZ Óé<ÏÔ|ÝòUÆfƒïßû‚µ-Z´HøÇôôt]]]PVV·j&ð÷ßÿøã­*((÷ƒÁpuumjj2dˆÁ±cLj ɶ´´€P€±cǺ¸¸XYYÑéôö[”••ËËËÛ¶\·nÝ™3g6mÚtûömeeåäädÁÁ/á¬÷ìÙ[__/| V¸¼¼|QQÇ«ªª€¶} kû¬`UÂëlµO>ÔLAAø¨ŠèšxPXXÈãñ³õÒÒR¢Àuu••î¬s\Õ… Ö§ptt4³²&;EÇáp8ç=܉Çfƒ¥ê_+˜@@@ñ`þüùÂm\]]Ùl¶¤¤$‡Ã9xð `y«fåååcÆŒár¹ÆÆÆ‡^?ŸÏohhØ»w¯ £'N466Ç•Ž?¾jÕªÚÚZ:>zôèV_Л;wîÀY,ÖG[lmm>|تeŸ>},,,ìííKJJ<<<Ž9âàà@|óæèÑ£­Ö0mÚ´Ñ£G›˜˜wÄkkóæÍãÇ8p 1Ìi?Õ§dn»O>dË–-'N433STT$–(**nذ!!!áĉÄ’àà`j|ì g`xçá sc Àºâ%’GŒÑþ+ àïÓž›wîî°Tðëd›‘ÖcÖl áòž÷ýoïsÙ>hˆå’e+[•ªàû÷þܶ¹¨¨èû¹V}}½Ï·ë‚Ë劉‰åååÍž=;22òÛuôeæÌ™sîÜ9âª,ŸåÁƒ“&Mꪢ6iiéoZ­ ,,lÇŽ¥¥¥Ä÷Ÿ[©ªª²µµüèââ2zt‡ÙüÖ›ßaÿ÷Mw*,;;;CÈNÑAÄÄÄ~ÿc;Ù)¾/ÖÖÖ¡¡¡zVNN®ÕçèËhéè^¸ægff ”¿ZÆ߾—«5|£Ó›"]Nv¶óêå_ùj Çãr;ã÷BŸŽ|â«…@í)áìÙ³Ut ÉN‰ÆÍï⊣çÏŸwÀkº#ÔÅeeüïšîT.X=zô诮Nv „HºIJö×@|?ƒÊS©S§*ôÓ ;BH$ªjý·ïÙGýûº¹¹Íüi"Ù)B"I‘:}Ò8âÜU*°ôôôF›@vŠNdöìÙÄejGYYÙþÏòòc&L$.ÄFå‚5nÜ8 …Þd§èzöêe1tXCsKCsë“rj…ÑMÒbè0i¡+—‘«O_Çõ444€ÚËÕÕuë¶mŸÇ’„|æCÌ-¾—/ý#ŠIMNZm¿(,,lذa ¸ÿ~g~Ô»wï>ÚfäÈ‘vËWv@„з£¤ÜÇ~¥#qý/†¢¢bRRÒ{/ÚÉ׃o‡™™Yy·c „¾…=~ž>ƒ¸c£Ë­>ݱcǶnÝú$º½+m"„:¹´TöÊÅ̈ˆˆáÇSùÖäÉ“«ñ3B]›J?µM;viiiµ¿‡¥¢¢bô±›/ „:9éîÝ ÿ¹î+• Ö™3gΚNv „H2ÓÓü:-!!¨ýµ†™3gŠuÿì!‘ôW°ÿØI}}} öK\\\JJšì!‘ÐÅĤ¤¥ÅÄÄ€ÚËÛÛÛi¹=Ù)B"yý*ó7‡%Äí/©<%\¸paÏ~êd§@‰DSKç´—q§^*°ªªªŠ‹¨p«n„¾gÍÍÍÅ…@í‚uûöm—-ÉNI~^ÎŽM¿gddµ§„+W®Ô21ÿx»ï@}}ÝA—md§@]‰Ãšõ}úvŠ;ÝëêÜx0hÐ  vÁÊÌÌŒ|úˬÙd!‡Ãyôè‘¡¡a¿~ýÈ΂:»wïÞÅÅÅͳ_NvTWWE„=µ27îÓ§• ÖÇÜK`íÚµvvvd§@q«z²SüOqQáÑý{gNBñ‚åììla=žì!‘™ŸO£ÑÈNÐW¦£§ï}+ÀœòS›7oný}-Ù):ÎU¯‹÷îÜâp8dAèkÊËyýÇz§—/_µ V}}}Ue%Ù):艓ïýsî´)X¶•p8œÊŠò–– vÁš?þ‰3çÉNÑqz+)ÿdûKIqÑþ];fÛNþ¬²¥¦¦fmm=pà@///á%ÖÖÖûöí{o 6lبQ£†êîîþÕ·¨¡¡aΜ9Ÿû*33³¯žD”.¶nÝ:bĈ   á…sæÌ!.?€>j€–¶Û¹KÆÆTŸzyy­²[HvŠ5‰=ƒÁ€woß~VÙRTT|úôixxøÁƒ…—<}útÓ¦MïmÎÎÎÏž=c±X³g·w ÇûÄMnéåå5mÚ´O|açÄãñîÝ».8Ù…ØÀ)S¦x{{“­ËÈÎÊ\±x›ÍjtïÞ½{=;¾_vR¢û±#ß/ACS++#ø« ÊÖùÓî³,ú”×ÖÔÔHJJ~zYYÙI“&ÉÊÊ*((@NNβeËêëëy<Þ©S§Œ tñâ۰°#FÄÆÆzxxœ9sæC-®]»F¬ÿöíÛ—/_nÕ²´´ôüùó^^^«W¯3fŒ¾¾¾ƒƒƒ˜˜˜¹¹ùÑ£G€ËåÚÛÛ³X¬U«V1 ooïÒÒR—3f€±±±¥¥%ñìŠ+‚ƒƒœœ ”˜˜Èf³Û¦ÞüGGÇr¹\bc—,YÂãñÆ¿uëÖVûJ°áÝ»w·¶¶>þüÔ©Shcc³dÉ’%K–|Êûòc0Š=zˆ‹‹Ïç“ç ‹gwpKæÌ|Wú¶ƒ;ÖÔÔÔP_/ø‘F£ñùüZÚÙY™žžž:ùYMMMCC#))ÉÇÇçÇ$– 0þøã &´m999ûöí{ö왬¬ìÉ“'-,,¦Nºoß>ƒÜÜ\‡ààà¾}û†……½yóÆÛÛûäÉ“ëׯŸ2eʘ1c>ÔRSSSÊÜÜ<>>¾mK'''‡S[[{áÂ… &8pÀÌÌŒÇãÑétèׯ_TT”œœÜðá㢢¤¤¤ÊËËmllbcc[=›œœ}šødð£ \]]Ùl¶¤¤$‡Ã!Æ?~|ÕªUµµµt:}ôèÑ...‚Î;wàÀ,‹ø±–¶¶¶>lÕ²OŸ>ööö%%%GŽqppÃ6mÚ´Ñ£G›˜üsßà¶6oÞ<~üøí§Ú²eËĉÍÌÌ àĉ ,ø„]û‚ƒƒ»úç ¦¯J¿õ[¶ÿE¨| ëðáÃ;vî¼ÿ4‚ì äî-¿ »w/[ѶTUWWM3²cXS}}½Ï·ë‚Ë劉‰åååÍž=;22òÛuÔÊœ9sÎ;'%%Õa=~ºÎv ëE {í ‡'!!–––Ta 2dÖÜÏþ××uõUéçvîÙ)¾&iiéoZ­ ,,lÇŽ¥¥¥‡jõTUU•­­­àG—Ñ£G¿w%ŸÞRà[o•ôìÕkÖ¼}ûöjO ---èÝÈNÑq ±$;B×cmmúÞ§äää„?vhǧ·D_ g¯ÞóÙýóQ Ùa¾¡C‡ý8êKŽã „:)É6VCˆ£ŸTaÙØØ”Vב!$’¾*ýÖmúƒ8èNå–¦¦æÐá#ÈN‰¬ìC­F§RP¹`¹»»Ï™öÙ)B"IùbÖÏ“âââ€ÚSÂ_~ù…ÃøŽº#DIjýÕw¹"¾¢Lå–¬¬lo%e²S „DÂï­¤,!!Ôa]ºtiëÖ­O¢ÈÒYÄÄÄÈÈÈuvIIIdGø?ÙY™+3µ"†Nå‚5oÞ<Ù^}ÈNщxxxxxx¡Ï£¡©}Òó‚‘‘P{„ÕÔÔT[[KvŠNAFFÖ÷~ðÇÛ!ô/E2®%÷^\.§¶¦†¸%• –¯¯/N t:ç¡.*/çõ¦µŽ#‡˜>œÊ'?———=‹TUëOv„ЗkjjzSR<}Òx)))*J˜ŸŸÏNÄáB][}]mrB|uu5Pûk þ|ÏU–B]HaA¾ëîÄ­ê©<%lll|/ó+·!„º.—[_Wg3Â’Á`Py„•pÇÌ+¬#„DW^öîŽïõ’’ ö”0<<üÂé¯wO„PGz[Rrþ´;q5}*O ŒÛ|!„¾â6_Ta=zôèÄ!W²S „DR\TxìÀ¾×¯_µ Vzzú³'ÉNIueå³Çeee€SB„P—@ý)¡¿¿ÿ®?6‘!$’ü¼\—Í222€Ú«¼¼¼ /—ì!‘456äç544N B]õ§„>>>ëV,%;BH$¯³_9-·OMMj,ƒ!ÑM‚ì!‘Ði4qq :8%Du ÔŸž={vñì_ÉNIVFú™¿$&&µ –²²²®¾Ù)B"‘’’Ò50$SB„P@ý)áñãǧٌ%;BH$/_¤N?:&&¨]°LLL~üy*Ù)B"QPPüñçi½{÷jO ù|þ³¸dâÓP„P×ÅãñF6j°öïß?nè ²S „D’’œhma b;wî$;Ï·"!!!!+ghlJv„З£ÓÅzöêýóäeee©<%¬««{Ýyn`‹ú§ºªr²õqqq*O Oœ81ãÇ d§@‰äå‹”i6c‰O ©|«úŸþ¹žKv„hú©öߺ{¯¶¶6Pû {¯^½hi“!$IIIMmmiii vÁ:wîœý¼ÿ!$’¬ÌôųMJJjO ÿóŸÿt“S$;BH$ꚇÜ< €Ú#,4Ù)B¢üS¹`]½zõ÷Õ+ÈNIÎëWëV.{ñâPûÔœ·oßÞ y¦¥£Kv„Зklh(ÈÏ›õóÝ»w§ò«´´4'ûÙ)B"ill|ý*«¾¾¨=%¼{÷îží!$’‚üÜÝ[7gffµ§„µµµ"£{ôìEv„Зkii!NÍ‘ ò+---$øÙ)B"©ª¬|ü ðÝ»w@í)áãÇÿ>zˆì!‘”ž<|0''¨=%Ä ø!D|>ŸÏçdB£Ñ¨üÇêù÷ ²S „Dò¶¤äôÉãyyy@í)arrò½;·ÉNIyyÙ½;7ß¼yÔžÞæ !ª þm¾îß¿¿×²S „DR˜Ÿ·w綬¬, vÁ***JKM!;BH$õõõi©ìššÀ)!B¨K þ”ðÆ›Ö:’!$’Ü×Ù~[•––Ô.X§©±‘ì!‘ðøü¦¦FÔ¾/¡±±qvAÑ«Ì m]=_Ÿ+oß¾Q éuîLcC£J?Õ3nÇ%$ºÉþðÃy÷ääi4ð:wFI¹oMuÕU¯ ê4‹ |}®è¿LM½ã{ÝÜÂ2†õüqp ©ù ÐG1Ï# M‚ü_¾HÕÑÓ¿uýjQaÁM-ï‹çjª«Uû«Ÿuw£Ñh=zö<ëîÖ]FV\\â’§GÏ^½¼/žSí¯þöí›W¼´õô_efÞº~Õdà Ä¸Ø ÿƒ-ÂCŸD†=325{x”¨g`x÷¦oîëlMmëW.•—•õ×иxƃÃiQêÓ×óï’’RÝ»Ë\8í.¯ Èãr/Ÿ÷ì£Ò¯¢¢üÚå‹´tòr^ß¼æmhb–’œèÓwÐKVDØÓÇLš?yø >6ÆÀÈø¾ÿíÌô—Úºz~W½ß–«м|γ¾¾®ŸZÿÓnÇ †¼¼Â9¿e£Óé^gÏôVîS[SsõÒ…þꊋ }}.ëe¼|qûƵƒ‡ÄF±Ý73ü,äqÔóCcÓ÷°uõ nû^/ÈË ¥íséBuU¥Zõ³§Ü€={õ:ë~Rº»L7ÉnÏx(öìÕÜÔä}á\?ÕþïJK¯_¹¤­«—ý*ëÖu3ó¤ø¸ûþ·Í-†D> }bl:ðñƒÀä„x=C£»·ür²_iéè^÷ö*+}×_cÀ¥³§›ššú¨¨œq;.ÑMRFVöÂiw9yù¼§r_•ªÊÊk^54µ òóü®^102IKaßñ»>hÈШÈð§ƒMš?}e`dx÷NÆË4=ý›×}Š ‹44µ®\8WW[£ªÖÿŒÛ 1†˜¼‚â¹Sn22² †ø¥³§{õVª¯¯÷¹x^M]ãMqñ ï˺ú†™é/o߸f6È">6:ø^€Ù ÁaOCXáaF&¦Á÷沈“uõ îøÝÈÏÍÑÔÖ¹êu±¢¢¼¿ºÆ…Ó§8\No%eÏ¿OHIIKJI]JŒ‹Ñ74¾wçVWùÓ=vüO¶¿ 65j° "ô)+"B‚ÄÇD@àÝ;©ì$ð÷óÍÊHojlò÷ó-ÈË­ªªò÷ó-}û¦ôí[?ßꪪ‚¼\?ß¦ÆÆW™þ~¾|>?-…x×bbB>VDXDèS yËzÁ÷ï%'&ÀÝ[~/ÓZZ8þ~¾¹¯³kkküý|KŠ‹ÊËÞùûùV”•øûù6ÔÕçd¿ò÷óår¹éi©÷n߀䄸‡÷ †õ<ìÉc{ú$*2&ÆÇÀ=ÿ[i©)<.×ßÏ7;+³¡¾ÞßÏ·¨  ²²ÂßÏ·¬´ômI±¿ŸoMMu~nŽ¿ŸossSVzúÝ›¾ÀNL|pï.ÄFG=} ‘a¡ÏÞÀ“GÁqÑQtïnjròÿvTS“¿Ÿo~nNMuµ¿Ÿï›’â²ÒR?ßÊÊŠÂü|?߆††ì¬,?_—–ʾç6$ÄÅ< VDxxèSxò8†õÞKNˆ€{wn¥§½àp8þ~¾9Ù¯êjkýý|‹ +ÊËýý|ËÊÞ•úûùÖÖÖæ¾Îö÷ómá´d¼L»wç&$%ÄßÿgG…†<€ˆÐ'¬ð0âOˆ€@ÿ;i©l>ŸOì¨Æ†z?ß‚üªÊŠÞñ7oüý|««ªóssýý|›šš²2Óýý| %9)(Àâc¢C‚ƒàyسÈg¡ðôáøhß»ËNJ€€Û~™/_¶47ûûùæåæÔÔ;ªä]i©¿ŸoEyyaA¾¿Ÿo}}ÝëÞqÎËÔÔ{þ· ).îу@ˆ~þÏ;þäñ¿ïøý¤øx¸}3ýÅ .—ëïçû:ûU}}¿ŸoQaÁ?;ê]iIq±¿ŸomMMnÎk?ß–ææŒô´»·ü %)áÁ½ˆ‹b…>~Ôåþ4Ñ?莢аBT‚ !Ôe`ÁBuX°B],„P— !Ôe`ÁBuX°B],„P— !Ôe`ÁB_AQQÑܹsi4ÚÈ‘#…—Ÿ:uJ\\|ÕªU‚%fffÇŽüXVV6wî\ƒ±|ùòÅ‹[[[³ÙlÁB''§÷6øêù…{ü”öYYY’’’_=ú8>B_Cff¦¸¸xß¾}###‰%gܸqÝ»w´ILLÔ××777oõÂnݺ¯_¿niiÙjá{|‹ü‚^¾ncôá }5t:ÝÉÉiÿþýľ¾¾Ó¦MnpéÒ%Ÿ/^¤¤¼ÿÒÕúúúít¡¯¯Ÿ””dii)))yìØ±1cÆhkk@RRÒ/¿ü²víÚÙ³g—––þþûït:ýܹs:::Ë—/×ÔÔ7nÜ›7o=z¤««{ñâÅ÷®¿¡¡XùáÇ5448 xjõêÕL&sÖ¬Yîîî»wïæp8Ë—/¿|ù2ñìÞ½{™Læš5k&Ožú¡•deeÍœ9ÓÉÉiÚ´iëÖ­€”””_ýõ·ß~›6mZûÛŽp„…¾bÐQ]]­¨¨˜––Æçó—,Y’™™)aµ´´Ìœ9“ÏçÏš5ËÙÙ¹Õ ‰ÇGýé§Ÿøa 233i4Ú“'Oø|¾§§'ŸÏ××׉‰áóùgÏž7oŸÏ_¾|ùƽ½½ïß¿O,Ÿ;w.ŸÏ¯©©YµjÕ‡òh4ZZZÚ“'OTUU‰g h4ZccceeåÁƒÛް®]»F< 333{ïJø|¾™™Yhh(±7&MšÄçó _¼xÁçó'L˜ð%»þ{ »`"J‘••]¾|¹««ëìÙ³'L˜ üT``àĉ`Á‚K—.Ý·oŸ˜˜ñ‡Ãqrrjll€óçÏ·]m«UUUt:8^fggWRR’‘‘ann–––[¶lWWW33³ººº'NÀìÙ³7oÞ\VVvóæÍ9sæ´¿t:]OOOLL¬¢¢‚X¢¤¤dff6bĈU«V9::7õÖ§OŸ… ÊÉÉÕÔÔ¼zõê½+)))INN¶²²ƒXRR’––æááx—ò‚…¾²5kÖhkk×ÖÖúøø¼~ýZ°üêÕ«222l6›ÃáTWWÿøãÄS ãèÑ£í¬³Uƒªª*ƒ!¨wü÷]ÓMFFÆÜÜ<44´¹¹YBBBZZzÖ¬YçÏŸg³ÙíoƒÁíW‹c0111ýõ—ŸŸß‘#G„Û×ÔÔLš4)11Q[[;++ëÆï] F£µêîàÁƒDãÚÚÚöƒ!¬èè+ëÝ»÷š5k¦L™"((P^^.##ãááqôèÑ“'O.[¶ìCG‘¾@Ÿ>}´µµ ::zܸqàîî¾víÚaƹ¸¸Í–/_¾wïÞAƒ}A{öì±µµõððˆ‰‰'.1NÔ¦ÆÆÆÆÆF®Ñ­(++›ššFFF@SSÓÌ™3•••õõõਨhéÒ¥_íûBò”QBYYÙüùóÅÄÄ6nÜ(XX]Ø0öÁ$IDAT]=þ|qqñÕ«WOž<ÙÆÆ¦¢¢‚Ïç755M:•8&-xáªU«JKK[­mݺuïm XR]]M,‰·µµurrš9sæ›7o>¬««›@ ^¶mÛF4³²²"2|(ÿºuëˆW¯^ݱc‡¸¸¸««+ŸÏ÷îݘ1cV­Z5}úô .p¹Ü‘#G.]ºtïÞ½ÄvïÞmiiI˜€¶+áóù3gÎ\»víüùóŸ>}ÊçóÙlöäɓ׬Y3þü¼¼¼¯ýÎP ^"}rrr·lÙròäI²³ /‡Ç°ÐwaÆŒ øóÏ?É‚D‚#,„P—ÝB],„P— !Ôe`ÁBuX°B]Æ‹ëNÔW$ÞÏIEND®B`‚openchange-2.0/apidocs/html/mapiproxy/dcesrv__exchange__ds__rfr_8c.html000066400000000000000000000351171223057412600265150ustar00rootroot00000000000000 MAPIProxy 2.0 API Documentation
dcesrv_exchange_ds_rfr.c File Reference

OpenChange RFR Server implementation. More...

#include "mapiproxy/dcesrv_mapiproxy.h"
#include "dcesrv_exchange_ds_rfr.h"

Functions

static NTSTATUS dcesrv_exchange_ds_rfr_dispatch (struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx, void *r, struct mapiproxy *mapiproxy)
static NTSTATUS dcesrv_exchange_ds_rfr_init (struct dcesrv_context *dce_ctx)
static NTSTATUS dcesrv_exchange_ds_rfr_unbind (struct server_id server_id, uint32_t context_id)
static enum MAPISTATUS dcesrv_RfrGetFQDNFromLegacyDN (struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx, struct RfrGetFQDNFromLegacyDN *r)
static enum MAPISTATUS dcesrv_RfrGetNewDSA (struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx, struct RfrGetNewDSA *r)
NTSTATUS samba_init_module (void)

Detailed Description

OpenChange RFR Server implementation.

Function Documentation

static NTSTATUS dcesrv_exchange_ds_rfr_dispatch ( struct dcesrv_call_state *  dce_call,
TALLOC_CTX *  mem_ctx,
void *  r,
struct mapiproxy *  mapiproxy 
)
static

Dispatch incoming RFR call to the correct OpenChange server function

Parameters
dce_callpointer to the session context
mem_ctxpointer to the memory context
rgeneric pointer on RFR data
mapiproxypointer to the mapiproxy structure controlling mapiproxy behavior
Returns
NT_STATUS_OK

References dcesrv_RfrGetFQDNFromLegacyDN(), and dcesrv_RfrGetNewDSA().

Referenced by samba_init_module().

static NTSTATUS dcesrv_exchange_ds_rfr_init ( struct dcesrv_context *  dce_ctx)
static

Initialize the RFR OpenChange server

Parameters
dce_ctxpointer to the server context
Returns
NT_STATUS_OK on success

Referenced by samba_init_module().

static NTSTATUS dcesrv_exchange_ds_rfr_unbind ( struct server_id  server_id,
uint32_t  context_id 
)
static

Terminate the RFR connection

Parameters
server_idreference to the server identifier structure
context_idthe connection context identifier
Returns
NT_STATUS_OK on success

Referenced by samba_init_module().

static enum MAPISTATUS dcesrv_RfrGetFQDNFromLegacyDN ( struct dcesrv_call_state *  dce_call,
TALLOC_CTX *  mem_ctx,
struct RfrGetFQDNFromLegacyDN *  r 
)
static

exchange_ds_rrf RfrGetFQDNFromLegacyDN (0x1) function

Parameters
dce_callpointer to the session context
mem_ctxpointer to the memory context
rpointer to the RfrGetFQDNFromLegacyDN request data
Returns
MAPI_E_SUCCESS on success

Referenced by dcesrv_exchange_ds_rfr_dispatch().

static enum MAPISTATUS dcesrv_RfrGetNewDSA ( struct dcesrv_call_state *  dce_call,
TALLOC_CTX *  mem_ctx,
struct RfrGetNewDSA *  r 
)
static

exchange_ds_rfr RfrGetNewDSA (0x0) function

Parameters
dce_callpointer to the session context
mem_ctxpointer to the memory context
rpointer to the RfrGetNewDSA request data
Note
We incorrectly assume input pUserDN is correct and available, but it is OK for now.
Returns
MAPI_E_SUCCESS on success

Referenced by dcesrv_exchange_ds_rfr_dispatch().

NTSTATUS samba_init_module ( void  )

Entry point for the default OpenChange RFR server

Returns
NT_STATUS_OK on success, otherwise NTSTATUS error

References dcesrv_exchange_ds_rfr_dispatch(), dcesrv_exchange_ds_rfr_init(), and dcesrv_exchange_ds_rfr_unbind().


Creative Commons License
Creative Commons Attribution icon Creative Commons Share Alike icon
This content is licensed under the Creative Commons
Attribution ShareAlike License v. 3.0:
http://creativecommons.org/licenses/by-sa/3.0/

openchange-2.0/apidocs/html/mapiproxy/dcesrv__exchange__emsmdb_8c.html000066400000000000000000001327061223057412600263500ustar00rootroot00000000000000 MAPIProxy 2.0 API Documentation
dcesrv_exchange_emsmdb.c File Reference

OpenChange EMSMDB Server implementation. More...

#include "mapiproxy/dcesrv_mapiproxy.h"
#include "mapiproxy/libmapiserver/libmapiserver.h"
#include "dcesrv_exchange_emsmdb.h"

Functions

static enum MAPISTATUS dcesrv_EcDoAsyncConnectEx (struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx, struct EcDoAsyncConnectEx *r)
static enum MAPISTATUS dcesrv_EcDoConnect (struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx, struct EcDoConnect *r)
static enum MAPISTATUS dcesrv_EcDoConnectEx (struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx, struct EcDoConnectEx *r)
static enum MAPISTATUS dcesrv_EcDoDisconnect (struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx, struct EcDoDisconnect *r)
static enum MAPISTATUS dcesrv_EcDoRpc (struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx, struct EcDoRpc *r)
static enum MAPISTATUS dcesrv_EcDoRpcExt (struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx, struct EcDoRpcExt *r)
static enum MAPISTATUS dcesrv_EcDoRpcExt2 (struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx, struct EcDoRpcExt2 *r)
static void dcesrv_EcDummyRpc (struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx, struct EcDummyRpc *r)
static void dcesrv_EcGetMoreRpc (struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx, struct EcGetMoreRpc *r)
static void dcesrv_EcRGetDCName (struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx, struct EcRGetDCName *r)
static void dcesrv_EcRNetGetDCName (struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx, struct EcRNetGetDCName *r)
static enum MAPISTATUS dcesrv_EcRRegisterPushNotification (struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx, struct EcRRegisterPushNotification *r)
static enum MAPISTATUS dcesrv_EcRUnregisterPushNotification (struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx, struct EcRUnregisterPushNotification *r)
static void dcesrv_EcUnknown0xC (struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx, struct EcUnknown0xC *r)
static void dcesrv_EcUnknown0xD (struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx, struct EcUnknown0xD *r)
static NTSTATUS dcesrv_exchange_emsmdb_dispatch (struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx, void *r, struct mapiproxy *mapiproxy)
static NTSTATUS dcesrv_exchange_emsmdb_init (struct dcesrv_context *dce_ctx)
static NTSTATUS dcesrv_exchange_emsmdb_unbind (struct server_id server_id, uint32_t context_id)
NTSTATUS samba_init_module (void)

Detailed Description

OpenChange EMSMDB Server implementation.

Function Documentation

static enum MAPISTATUS dcesrv_EcDoAsyncConnectEx ( struct dcesrv_call_state *  dce_call,
TALLOC_CTX *  mem_ctx,
struct EcDoAsyncConnectEx *  r 
)
static

exchange_emsmdb EcGetMoreRpc (0xe) function

Parameters
dce_callpointer to the session context
mem_ctxpointer to the memory context
rpointer to the EcDoAsyncConnectExt request data
Returns
MAPI_E_SUCCESS on success

Referenced by dcesrv_exchange_emsmdb_dispatch().

static enum MAPISTATUS dcesrv_EcDoConnect ( struct dcesrv_call_state *  dce_call,
TALLOC_CTX *  mem_ctx,
struct EcDoConnect *  r 
)
static

exchange_emsmdb EcDoConnect (0x0) function

Parameters
dce_callpointer to the session context
mem_ctxpointer to the memory context
rpointer to the EcDoConnect request data
Note
Session linking is not supported at the moment
Returns
MAPI_E_SUCCESS on success

References emsmdbp_init(), emsmdbp_verify_user(), emsmdbp_verify_userdn(), mpm_session_increment_ref_count(), mpm_session_init(), mpm_session_set_destructor(), and mpm_session_set_private_data().

Referenced by dcesrv_exchange_emsmdb_dispatch().

static enum MAPISTATUS dcesrv_EcDoConnectEx ( struct dcesrv_call_state *  dce_call,
TALLOC_CTX *  mem_ctx,
struct EcDoConnectEx *  r 
)
static

exchange_emsmdb EcDoConnectEx (0xA) function

Parameters
dce_callpointer to the session context
mem_ctxpointer to the memory context
rpointer to the EcDoConnectEx request data
Returns
MAPI_E_SUCCESS on success

References emsmdbp_init(), emsmdbp_verify_user(), emsmdbp_verify_userdn(), mpm_session_increment_ref_count(), mpm_session_init(), mpm_session_set_destructor(), and mpm_session_set_private_data().

Referenced by dcesrv_exchange_emsmdb_dispatch().

static enum MAPISTATUS dcesrv_EcDoDisconnect ( struct dcesrv_call_state *  dce_call,
TALLOC_CTX *  mem_ctx,
struct EcDoDisconnect *  r 
)
static

exchange_emsmdb EcDoDisconnect (0x1) function

Parameters
dce_callpointer to the session context
mem_ctxpointer to the memory context
rpointer to the EcDoDisconnect request data
Returns
MAPI_E_SUCCESS on success

References mpm_session_release().

Referenced by dcesrv_exchange_emsmdb_dispatch().

static enum MAPISTATUS dcesrv_EcDoRpc ( struct dcesrv_call_state *  dce_call,
TALLOC_CTX *  mem_ctx,
struct EcDoRpc *  r 
)
static

exchange_emsmdb EcDoRpc (0x2) function

Parameters
dce_callpointer to the session context
mem_ctxpointer to the memory context
rpointer to the EcDoRpc request data
Returns
MAPI_E_SUCCESS on success

Referenced by dcesrv_exchange_emsmdb_dispatch().

static enum MAPISTATUS dcesrv_EcDoRpcExt ( struct dcesrv_call_state *  dce_call,
TALLOC_CTX *  mem_ctx,
struct EcDoRpcExt *  r 
)
static

exchange_emsmdb EcDoRpcExt (0x9) function

Parameters
dce_callpointer to the session context
mem_ctxpointer to the memory context
rpointer to the EcDoRpcExt request data
Returns
MAPI_E_SUCCESS on success

Referenced by dcesrv_exchange_emsmdb_dispatch().

static enum MAPISTATUS dcesrv_EcDoRpcExt2 ( struct dcesrv_call_state *  dce_call,
TALLOC_CTX *  mem_ctx,
struct EcDoRpcExt2 *  r 
)
static

exchange_emsmdb EcDoRpcExt2 (0xB) function

Parameters
dce_callpointer to the session context
mem_ctxpointer to the memory context
rpointer to the EcDoRpcExt2 request data
Returns
MAPI_E_SUCCESS on success

Referenced by dcesrv_exchange_emsmdb_dispatch().

static void dcesrv_EcDummyRpc ( struct dcesrv_call_state *  dce_call,
TALLOC_CTX *  mem_ctx,
struct EcDummyRpc *  r 
)
static

exchange_emsmdb EcDummyRpc (0x6) function

Parameters
dce_callpointer to the session context
mem_ctxpointer to the memory context
rpointer to the EcDummyRpc request data
Returns
MAPI_E_SUCCESS on success

Referenced by dcesrv_exchange_emsmdb_dispatch().

static void dcesrv_EcGetMoreRpc ( struct dcesrv_call_state *  dce_call,
TALLOC_CTX *  mem_ctx,
struct EcGetMoreRpc *  r 
)
static

exchange_emsmdb EcGetMoreRpc (0x3) function

Parameters
dce_callpointer to the session context
mem_ctxpointer to the memory context
rpointer to the EcGetMoreRpc request data
Returns
MAPI_E_SUCCESS on success

Referenced by dcesrv_exchange_emsmdb_dispatch().

static void dcesrv_EcRGetDCName ( struct dcesrv_call_state *  dce_call,
TALLOC_CTX *  mem_ctx,
struct EcRGetDCName *  r 
)
static

exchange_emsmdb EcRGetDCName (0x7) function

Parameters
dce_callpointer to the session context
mem_ctxpointer to the memory context
rpointer to the EcRGetDCName request data
Returns
MAPI_E_SUCCESS on success

Referenced by dcesrv_exchange_emsmdb_dispatch().

static void dcesrv_EcRNetGetDCName ( struct dcesrv_call_state *  dce_call,
TALLOC_CTX *  mem_ctx,
struct EcRNetGetDCName *  r 
)
static

exchange_emsmdb EcRNetGetDCName (0x8) function

Parameters
dce_callpointer to the session context
mem_ctxpointer to the memory context
rpointer to the EcRNetGetDCName request data
Returns
MAPI_E_SUCCESS on success

Referenced by dcesrv_exchange_emsmdb_dispatch().

static enum MAPISTATUS dcesrv_EcRRegisterPushNotification ( struct dcesrv_call_state *  dce_call,
TALLOC_CTX *  mem_ctx,
struct EcRRegisterPushNotification *  r 
)
static

exchange_emsmdb EcRRegisterPushNotification (0x4) function

Parameters
dce_callpointer to the session context
mem_ctxpointer to the memory context
rpointer to the EcRRegisterPushNotification request data
Returns
MAPI_E_SUCCESS on success

Referenced by dcesrv_exchange_emsmdb_dispatch().

static enum MAPISTATUS dcesrv_EcRUnregisterPushNotification ( struct dcesrv_call_state *  dce_call,
TALLOC_CTX *  mem_ctx,
struct EcRUnregisterPushNotification *  r 
)
static

exchange_emsmdb EcRUnregisterPushNotification (0x5) function

Parameters
dce_callpointer to the session context
mem_ctxpointer to the memory context
rpointer to the EcRUnregisterPushNotification request data
Returns
MAPI_E_SUCCESS on success

Referenced by dcesrv_exchange_emsmdb_dispatch().

static void dcesrv_EcUnknown0xC ( struct dcesrv_call_state *  dce_call,
TALLOC_CTX *  mem_ctx,
struct EcUnknown0xC *  r 
)
static

exchange_emsmdb EcUnknown0xC (0xc) function

Parameters
dce_callpointer to the session context
mem_ctxpointer to the memory context
rpointer to the EcUnknown0xC request data
Returns
MAPI_E_SUCCESS on success

Referenced by dcesrv_exchange_emsmdb_dispatch().

static void dcesrv_EcUnknown0xD ( struct dcesrv_call_state *  dce_call,
TALLOC_CTX *  mem_ctx,
struct EcUnknown0xD *  r 
)
static

exchange_emsmdb EcUnknown0xD (0xc) function

Parameters
dce_callpointer to the session context
mem_ctxpointer to the memory context
rpointer to the EcUnknown0xD request data
Returns
MAPI_E_SUCCESS on success

Referenced by dcesrv_exchange_emsmdb_dispatch().

static NTSTATUS dcesrv_exchange_emsmdb_dispatch ( struct dcesrv_call_state *  dce_call,
TALLOC_CTX *  mem_ctx,
void *  r,
struct mapiproxy *  mapiproxy 
)
static

Dispatch incoming EMSMDB call to the correct OpenChange server function

Parameters
dce_callpointer to the session context
mem_ctxpointer to the memory context
rgeneric pointer on EMSMDB data
mapiproxypointer to the mapiproxy structure controlling mapiproxy behavior
Returns
NT_STATUS_OK;

References dcesrv_EcDoAsyncConnectEx(), dcesrv_EcDoConnect(), dcesrv_EcDoConnectEx(), dcesrv_EcDoDisconnect(), dcesrv_EcDoRpc(), dcesrv_EcDoRpcExt(), dcesrv_EcDoRpcExt2(), dcesrv_EcDummyRpc(), dcesrv_EcGetMoreRpc(), dcesrv_EcRGetDCName(), dcesrv_EcRNetGetDCName(), dcesrv_EcRRegisterPushNotification(), dcesrv_EcRUnregisterPushNotification(), dcesrv_EcUnknown0xC(), and dcesrv_EcUnknown0xD().

Referenced by samba_init_module().

static NTSTATUS dcesrv_exchange_emsmdb_init ( struct dcesrv_context *  dce_ctx)
static

Initialize the EMSMDB OpenChange server

Parameters
dce_ctxpointer to the server context
Returns
NT_STATUS_OK on success

References emsmdbp_openchange_ldb_init().

Referenced by samba_init_module().

static NTSTATUS dcesrv_exchange_emsmdb_unbind ( struct server_id  server_id,
uint32_t  context_id 
)
static

Terminate the EMSMDB connection and release the associated session and context if still available. This case occurs when the client doesn't call EcDoDisconnect but quit unexpectedly.

Parameters
server_idreference to the server identifier structure
context_idthe connection context identifier
Returns
NT_STATUS_OK on success

Referenced by samba_init_module().

NTSTATUS samba_init_module ( void  )

Entry point for the default OpenChange EMSMDB server

Returns
NT_STATUS_OK on success, otherwise NTSTATUS error

References dcesrv_exchange_emsmdb_dispatch(), dcesrv_exchange_emsmdb_init(), and dcesrv_exchange_emsmdb_unbind().


Creative Commons License
Creative Commons Attribution icon Creative Commons Share Alike icon
This content is licensed under the Creative Commons
Attribution ShareAlike License v. 3.0:
http://creativecommons.org/licenses/by-sa/3.0/

openchange-2.0/apidocs/html/mapiproxy/dcesrv__exchange__nsp_8c.html000066400000000000000000001704311223057412600256760ustar00rootroot00000000000000 MAPIProxy 2.0 API Documentation
dcesrv_exchange_nsp.c File Reference

OpenChange NSPI Server implementation. More...

#include "mapiproxy/dcesrv_mapiproxy.h"
#include "dcesrv_exchange_nsp.h"

Functions

static NTSTATUS dcesrv_exchange_nsp_dispatch (struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx, void *r, struct mapiproxy *mapiproxy)
static NTSTATUS dcesrv_exchange_nsp_init (struct dcesrv_context *dce_ctx)
static NTSTATUS dcesrv_exchange_nsp_unbind (struct server_id server_id, uint32_t context_id)
static void dcesrv_NspiBind (struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx, struct NspiBind *r)
static void dcesrv_NspiCompareMIds (struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx, struct NspiCompareMIds *r)
static void dcesrv_NspiDeleteEntries (struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx, struct NspiDeleteEntries *r)
static void dcesrv_NspiDNToMId (struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx, struct NspiDNToMId *r)
static void dcesrv_NspiGetIDsFromNames (struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx, struct NspiGetIDsFromNames *r)
static void dcesrv_NspiGetMatches (struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx, struct NspiGetMatches *r)
static void dcesrv_NspiGetNamesFromIDs (struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx, struct NspiGetNamesFromIDs *r)
static void dcesrv_NspiGetPropList (struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx, struct NspiGetPropList *r)
static void dcesrv_NspiGetProps (struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx, struct NspiGetProps *r)
static void dcesrv_NspiGetSpecialTable (struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx, struct NspiGetSpecialTable *r)
static void dcesrv_NspiGetTemplateInfo (struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx, struct NspiGetTemplateInfo *r)
static void dcesrv_NspiModLinkAtt (struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx, struct NspiModLinkAtt *r)
static void dcesrv_NspiModProps (struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx, struct NspiModProps *r)
static void dcesrv_NspiQueryColumns (struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx, struct NspiQueryColumns *r)
static void dcesrv_NspiQueryRows (struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx, struct NspiQueryRows *r)
static void dcesrv_NspiResolveNames (struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx, struct NspiResolveNames *r)
static void dcesrv_NspiResolveNamesW (struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx, struct NspiResolveNamesW *r)
static void dcesrv_NspiResortRestriction (struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx, struct NspiResortRestriction *r)
static void dcesrv_NspiSeekEntries (struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx, struct NspiSeekEntries *r)
static void dcesrv_NspiUnbind (struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx, struct NspiUnbind *r)
static void dcesrv_NspiUpdateStat (struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx, struct NspiUpdateStat *r)
NTSTATUS samba_init_module (void)

Detailed Description

OpenChange NSPI Server implementation.

Function Documentation

static NTSTATUS dcesrv_exchange_nsp_dispatch ( struct dcesrv_call_state *  dce_call,
TALLOC_CTX *  mem_ctx,
void *  r,
struct mapiproxy *  mapiproxy 
)
static

Dispatch incoming NSPI call to the correct OpenChange server function.

Parameters
dce_callpointer to the session context
mem_ctxpointer to the memory context
rgeneric pointer on NSPI data
mapiproxypointer to the mapiproxy structure controlling mapiproxy behavior
Returns
NT_STATUS_OK

References dcesrv_NspiBind(), dcesrv_NspiCompareMIds(), dcesrv_NspiDeleteEntries(), dcesrv_NspiDNToMId(), dcesrv_NspiGetIDsFromNames(), dcesrv_NspiGetMatches(), dcesrv_NspiGetNamesFromIDs(), dcesrv_NspiGetPropList(), dcesrv_NspiGetProps(), dcesrv_NspiGetSpecialTable(), dcesrv_NspiGetTemplateInfo(), dcesrv_NspiModLinkAtt(), dcesrv_NspiModProps(), dcesrv_NspiQueryColumns(), dcesrv_NspiQueryRows(), dcesrv_NspiResolveNames(), dcesrv_NspiResolveNamesW(), dcesrv_NspiResortRestriction(), dcesrv_NspiSeekEntries(), dcesrv_NspiUnbind(), and dcesrv_NspiUpdateStat().

Referenced by samba_init_module().

static NTSTATUS dcesrv_exchange_nsp_init ( struct dcesrv_context *  dce_ctx)
static

Initialize the NSPI OpenChange server

Parameters
dce_ctxpointer to the server context
Returns
NT_STATUS_OK on success, otherwise NT_STATUS_NO_MEMORY

References emsabp_tdb_init().

Referenced by samba_init_module().

static NTSTATUS dcesrv_exchange_nsp_unbind ( struct server_id  server_id,
uint32_t  context_id 
)
static

Terminates the NSPI connection and release the associated session and context if still available. This case occurs when the client doesn't call NspiUnbind but quit unexpectedly.

Parameters
server_idreference to the server identifier structure
context_idthe connection context identifier
Returns
NT_STATUS_OK on success

Referenced by samba_init_module().

static void dcesrv_NspiBind ( struct dcesrv_call_state *  dce_call,
TALLOC_CTX *  mem_ctx,
struct NspiBind *  r 
)
static

exchange_nsp NspiBind (0x0) function, Initiates a NSPI session with the client.

This function checks if the user is an Exchange user and input parameters like codepage are valid. If it passes the tests, the function initializes an emsabp context and returns to the client a valid policy_handle and expected reply parameters.

Parameters
dce_callpointer to the session context
mem_ctxpointer to the memory context
rpointer to the NspiBind call structure
Returns
MAPI_E_SUCCESS on success, otherwise a MAPI error

References emsabp_init(), emsabp_verify_codepage(), emsabp_verify_user(), mpm_session_increment_ref_count(), mpm_session_init(), mpm_session_set_destructor(), and mpm_session_set_private_data().

Referenced by dcesrv_exchange_nsp_dispatch().

static void dcesrv_NspiCompareMIds ( struct dcesrv_call_state *  dce_call,
TALLOC_CTX *  mem_ctx,
struct NspiCompareMIds *  r 
)
static

exchange_nsp NspiCompareMIds (0xA) function

Parameters
dce_callpointer to the session context
mem_ctxpointer to the memory context
rpointer to the NspiCompareMIds request data
Returns
MAPI_E_SUCCESS on success

Referenced by dcesrv_exchange_nsp_dispatch().

static void dcesrv_NspiDeleteEntries ( struct dcesrv_call_state *  dce_call,
TALLOC_CTX *  mem_ctx,
struct NspiDeleteEntries *  r 
)
static

exchange_nsp NspiDeleteEntries (0xF) function

Parameters
dce_callpointer to the session context
mem_ctxpointer to the memory context
rpointer to the NspiDeleteEntries request data
Returns
MAPI_E_SUCCESS on success

Referenced by dcesrv_exchange_nsp_dispatch().

static void dcesrv_NspiDNToMId ( struct dcesrv_call_state *  dce_call,
TALLOC_CTX *  mem_ctx,
struct NspiDNToMId *  r 
)
static

exchange_nsp NspiDNToMId (0x7) function

Parameters
dce_callpointer to the session context
mem_ctxpointer to the memory context
rpointer to the NspiDNToMId request data
Note
Only searches within configuration.ldb are supported at the moment.
Returns
MAPI_E_SUCCESS on success

References emsabp_search_legacyExchangeDN(), emsabp_tdb_fetch_MId(), and emsabp_tdb_insert().

Referenced by dcesrv_exchange_nsp_dispatch().

static void dcesrv_NspiGetIDsFromNames ( struct dcesrv_call_state *  dce_call,
TALLOC_CTX *  mem_ctx,
struct NspiGetIDsFromNames *  r 
)
static

exchange_nsp NspiGetIDsFromNames (0x12) function

Parameters
dce_callpointer to the session context
mem_ctxpointer to the memory context
rpointer to the NspiGetIDsFromNames request data
Returns
MAPI_E_SUCCESS on success

Referenced by dcesrv_exchange_nsp_dispatch().

static void dcesrv_NspiGetMatches ( struct dcesrv_call_state *  dce_call,
TALLOC_CTX *  mem_ctx,
struct NspiGetMatches *  r 
)
static

exchange_nsp NspiGetMatches (0x5) function

Parameters
dce_callpointer to the session context
mem_ctxpointer to the memory context
rpointer to the NspiGetMatches request data
Returns
MAPI_E_SUCCESS on success

References emsabp_fetch_attrs(), and emsabp_search().

Referenced by dcesrv_exchange_nsp_dispatch().

static void dcesrv_NspiGetNamesFromIDs ( struct dcesrv_call_state *  dce_call,
TALLOC_CTX *  mem_ctx,
struct NspiGetNamesFromIDs *  r 
)
static

exchange_nsp NspiGetNamesFromIDs (0x11) function

Parameters
dce_callpointer to the session context
mem_ctxpointer to the memory context
rpointer to the NspiGetNamesFromIDs request data
Returns
MAPI_E_SUCCESS on success

Referenced by dcesrv_exchange_nsp_dispatch().

static void dcesrv_NspiGetPropList ( struct dcesrv_call_state *  dce_call,
TALLOC_CTX *  mem_ctx,
struct NspiGetPropList *  r 
)
static

exchange_nsp NspiGetPropList (0x8) function

Parameters
dce_callpointer to the session context
mem_ctxpointer to the memory context
rpointer to the NspiGetPropList request data
Returns
MAPI_E_SUCCESS on success

Referenced by dcesrv_exchange_nsp_dispatch().

static void dcesrv_NspiGetProps ( struct dcesrv_call_state *  dce_call,
TALLOC_CTX *  mem_ctx,
struct NspiGetProps *  r 
)
static

exchange_nsp NspiGetProps (0x9) function

Parameters
dce_callpointer to the session context
mem_ctxpointer to the memory context
rpointer to the NspiGetProps request data
Returns
MAPI_E_SUCCESS on success

References emsabp_fetch_attrs(), and emsabp_tdb_lookup_MId().

Referenced by dcesrv_exchange_nsp_dispatch().

static void dcesrv_NspiGetSpecialTable ( struct dcesrv_call_state *  dce_call,
TALLOC_CTX *  mem_ctx,
struct NspiGetSpecialTable *  r 
)
static

exchange_nsp NspiGetSpecialTable (0xC) function

Parameters
dce_callpointer to the session context
mem_ctxpointer to the memory context
rpointer to the NspiGetSpecialTable request data
Note
MS-NSPI specifies lpVersion "holds the value of the version number of the hierarchy table that the client has." We will ignore this for the moment.
Returns
MAPI_E_SUCCESS on success

References emsabp_get_CreationTemplatesTable(), and emsabp_get_HierarchyTable().

Referenced by dcesrv_exchange_nsp_dispatch().

static void dcesrv_NspiGetTemplateInfo ( struct dcesrv_call_state *  dce_call,
TALLOC_CTX *  mem_ctx,
struct NspiGetTemplateInfo *  r 
)
static

exchange_nsp NspiGetTemplateInfo (0xD) function

Parameters
dce_callpointer to the session context
mem_ctxpointer to the memory context
rpointer to the NspiGetTemplateInfo request data
Returns
MAPI_E_SUCCESS on success

Referenced by dcesrv_exchange_nsp_dispatch().

static void dcesrv_NspiModLinkAtt ( struct dcesrv_call_state *  dce_call,
TALLOC_CTX *  mem_ctx,
struct NspiModLinkAtt *  r 
)
static

exchange_nsp NspiModLinkAtt (0xE) function

Parameters
dce_callpointer to the session context
mem_ctxpointer to the memory context
rpointer to the NspiModLinkAtt request data
Returns
MAPI_E_SUCCESS on success

Referenced by dcesrv_exchange_nsp_dispatch().

static void dcesrv_NspiModProps ( struct dcesrv_call_state *  dce_call,
TALLOC_CTX *  mem_ctx,
struct NspiModProps *  r 
)
static

exchange_nsp NspiModProps (0xB) function

Parameters
dce_callpointer to the session context
mem_ctxpointer to the memory context
rpointer to the NspiModProps request data
Returns
MAPI_E_SUCCESS on success

Referenced by dcesrv_exchange_nsp_dispatch().

static void dcesrv_NspiQueryColumns ( struct dcesrv_call_state *  dce_call,
TALLOC_CTX *  mem_ctx,
struct NspiQueryColumns *  r 
)
static

exchange_nsp NspiQueryColumns (0x10) function

Parameters
dce_callpointer to the session context
mem_ctxpointer to the memory context
rpointer to the NspiQueryColumns request data
Returns
MAPI_E_SUCCESS on success

Referenced by dcesrv_exchange_nsp_dispatch().

static void dcesrv_NspiQueryRows ( struct dcesrv_call_state *  dce_call,
TALLOC_CTX *  mem_ctx,
struct NspiQueryRows *  r 
)
static

exchange_nsp NspiQueryRows (0x3) function

Parameters
dce_callpointer to the session context
mem_ctxpointer to the memory context
rpointer to the NspiQueryRows request data
Returns
MAPI_E_SUCCESS on success

References emsabp_ab_container_enum(), emsabp_fetch_attrs(), emsabp_fetch_attrs_from_msg(), and emsabp_tdb_lookup_MId().

Referenced by dcesrv_exchange_nsp_dispatch().

static void dcesrv_NspiResolveNames ( struct dcesrv_call_state *  dce_call,
TALLOC_CTX *  mem_ctx,
struct NspiResolveNames *  r 
)
static

exchange_nsp NspiResolveNames (0x13) function

Parameters
dce_callpointer to the session context
mem_ctxpointer to the memory context
rpointer to the NspiResolveNames request data
Returns
MAPI_E_SUCCESS on success

References emsabp_ab_container_by_id(), and emsabp_fetch_attrs_from_msg().

Referenced by dcesrv_exchange_nsp_dispatch().

static void dcesrv_NspiResolveNamesW ( struct dcesrv_call_state *  dce_call,
TALLOC_CTX *  mem_ctx,
struct NspiResolveNamesW *  r 
)
static

exchange_nsp NspiResolveNamesW (0x14) function

Parameters
dce_callpointer to the session context
mem_ctxpointer to the memory context
rpointer to the NspiResolveNamesW request data
Returns
MAPI_E_SUCCESS on success

References emsabp_ab_container_by_id(), and emsabp_fetch_attrs_from_msg().

Referenced by dcesrv_exchange_nsp_dispatch().

static void dcesrv_NspiResortRestriction ( struct dcesrv_call_state *  dce_call,
TALLOC_CTX *  mem_ctx,
struct NspiResortRestriction *  r 
)
static

exchange_nsp NspiResortRestriction (0x6) function

Parameters
dce_callpointer to the session context
mem_ctxpointer to the memory context
rpointer to the NspiResortRestriction request data
Returns
MAPI_E_SUCCESS on success

Referenced by dcesrv_exchange_nsp_dispatch().

static void dcesrv_NspiSeekEntries ( struct dcesrv_call_state *  dce_call,
TALLOC_CTX *  mem_ctx,
struct NspiSeekEntries *  r 
)
static

exchange_nsp NspiSeekEntries (0x4) function

Parameters
dce_callpointer to the session context
mem_ctxpointer to the memory context
rpointer to the NspiSeekEntries request data
Returns
MAPI_E_SUCCESS on success

References emsabp_fetch_attrs(), emsabp_search(), and emsabp_tdb_lookup_MId().

Referenced by dcesrv_exchange_nsp_dispatch().

static void dcesrv_NspiUnbind ( struct dcesrv_call_state *  dce_call,
TALLOC_CTX *  mem_ctx,
struct NspiUnbind *  r 
)
static

exchange_nsp NspiUnbind (0x1) function, Terminates a NSPI session with the client

Parameters
dce_callpointer to the session context
mem_ctxpointer to the memory context
rpointer to the NspiUnbind call structure

References mpm_session_release().

Referenced by dcesrv_exchange_nsp_dispatch().

static void dcesrv_NspiUpdateStat ( struct dcesrv_call_state *  dce_call,
TALLOC_CTX *  mem_ctx,
struct NspiUpdateStat *  r 
)
static

exchange_nsp NspiUpdateStat (0x2) function

Parameters
dce_callpointer to the session context
mem_ctxpointer to the memory context
rpointer to the NspiUpdateStat request data
Returns
MAPI_E_SUCCESS on success

References emsabp_search(), and emsabp_tdb_lookup_MId().

Referenced by dcesrv_exchange_nsp_dispatch().

NTSTATUS samba_init_module ( void  )

Entry point for the default OpenChange NSPI server

Returns
NT_STATUS_OK on success, otherwise NTSTATUS error

References dcesrv_exchange_nsp_dispatch(), dcesrv_exchange_nsp_init(), and dcesrv_exchange_nsp_unbind().


Creative Commons License
Creative Commons Attribution icon Creative Commons Share Alike icon
This content is licensed under the Creative Commons
Attribution ShareAlike License v. 3.0:
http://creativecommons.org/licenses/by-sa/3.0/

openchange-2.0/apidocs/html/mapiproxy/dcesrv__mapiproxy_8c.html000066400000000000000000000503231223057412600251220ustar00rootroot00000000000000 MAPIProxy 2.0 API Documentation
dcesrv_mapiproxy.c File Reference

mapiproxy main file More...

#include "mapiproxy/dcesrv_mapiproxy.h"
#include "mapiproxy/dcesrv_mapiproxy_proto.h"
#include <dlinklist.h>
#include "libmapi/libmapi.h"
#include "libmapi/libmapi_private.h"
#include "gen_ndr/ndr_exchange_s.c"

Functions

NTSTATUS dcerpc_server_mapiproxy_init (void)
static NTSTATUS mapiproxy_op_bind (struct dcesrv_call_state *dce_call, const struct dcesrv_interface *iface, uint32_t if_version)
static NTSTATUS mapiproxy_op_dispatch (struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx, void *r)
static NTSTATUS mapiproxy_op_init_server (struct dcesrv_context *dce_ctx, const struct dcesrv_endpoint_server *ep_server)
static NTSTATUS mapiproxy_op_ndr_pull (struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx, struct ndr_pull *pull, void **r)
static NTSTATUS mapiproxy_op_ndr_push (struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx, struct ndr_push *push, const void *r)
static void mapiproxy_op_unbind (struct dcesrv_connection_context *context, const struct dcesrv_interface *iface)
static NTSTATUS mapiproxy_register_one_iface (struct dcesrv_context *dce_ctx, const struct dcesrv_interface *iface)
NTSTATUS samba_init_module (void)

Detailed Description

mapiproxy main file

Function Documentation

NTSTATUS dcerpc_server_mapiproxy_init ( void  )

register the mapiproxy endpoint server.

Returns
NT_STATUS_OK on success, otherwise NTSTATUS error

References mapiproxy_op_init_server().

Referenced by samba_init_module().

static NTSTATUS mapiproxy_op_bind ( struct dcesrv_call_state *  dce_call,
const struct dcesrv_interface *  iface,
uint32_t  if_version 
)
static

This function is called when the client binds to one of the interfaces mapiproxy handles.

Parameters
dce_callpointer to the session context
ifacepointer to the dcesrv interface structure with function hooks
if_versionthe version of the pipe
Returns
NT_STATUS_OK on success, otherwise NTSTATUS error
static NTSTATUS mapiproxy_op_dispatch ( struct dcesrv_call_state *  dce_call,
TALLOC_CTX *  mem_ctx,
void *  r 
)
static

This function is called after the pull but before the push. Moreover it is called before the request is forward to the remote endpoint.

Parameters
dce_callpointer to the session context
mem_ctxpointer to the memory context
rgeneric pointer to the call mapped data
Returns
NT_STATUS_OK on success, otherwise NTSTATUS error

References mapiproxy_NspiDNToMId().

static NTSTATUS mapiproxy_op_init_server ( struct dcesrv_context *  dce_ctx,
const struct dcesrv_endpoint_server *  ep_server 
)
static

Initializes the server and register emsmdb,nspi and rfr interfaces

Parameters
dce_ctxpointer to the dcesrv context
ep_serverpointer to the endpoint server list
Returns
NT_STATUS_OK on success, otherwise NTSTATUS error

References mapiproxy_register_one_iface(), and mapiproxy_server_init().

Referenced by dcerpc_server_mapiproxy_init().

static NTSTATUS mapiproxy_op_ndr_pull ( struct dcesrv_call_state *  dce_call,
TALLOC_CTX *  mem_ctx,
struct ndr_pull *  pull,
void **  r 
)
static

This is the function called when mapiproxy receives a request. The request has already been extracted and its information filled into structures

Parameters
dce_callpointer to the session context
mem_ctxpointer to the memory context
pullpointer on pointer to the ndr_pull structure
rgeneric pointer on pointer to the pulled ndr content
Returns
NT_STATUS_OK on success, other NTSTATUS error
static NTSTATUS mapiproxy_op_ndr_push ( struct dcesrv_call_state *  dce_call,
TALLOC_CTX *  mem_ctx,
struct ndr_push *  push,
const void *  r 
)
static

This is the function called when mapiproxy receive a response. The response has already been extracted and its information filled into structures

Parameters
dce_callpointer to the session context
mem_ctxpointer to the memory context
pushpointer to the ndr_push structure
rgeneric pointer to the data pushed
Returns
NT_STATUS_OK on success, otherwise a NTSTATUS error

References mapiproxy_NspiGetProps(), mapiproxy_NspiQueryRows(), and mapiproxy_RfrGetNewDSA().

static void mapiproxy_op_unbind ( struct dcesrv_connection_context *  context,
const struct dcesrv_interface *  iface 
)
static

Called when the client disconnects from one of the endpoints managed by mapiproxy.

Parameters
contextpointer to the connection context
ifacepointer to the dcesrv interface structure with function hooks
static NTSTATUS mapiproxy_register_one_iface ( struct dcesrv_context *  dce_ctx,
const struct dcesrv_interface *  iface 
)
static

Register an endpoint

Parameters
dce_ctxpointer to the dcerpc context
ifacepointer to the dcesrv interface with function hooks
Returns
NT_STATUS_OK on success, otherwise NTSTATUS error

Referenced by mapiproxy_op_init_server().

NTSTATUS samba_init_module ( void  )

Register mapiproxy dynamic shared object modules

This function registers mapiproxy modules located

Entry point of mapiproxy dynamic shared object.

This function first registers exchange endpoints and ndr tables, then attempts to register the mapiproxy interface.

Returns
NT_STATUS_OK on success, otherwise NT_STATUS_UNSUCCESSFUL;

Entry point for the pack mapiproxy module

Returns
NT_STATUS_OK on success, otherwise NTSTATUS error

Creative Commons License
Creative Commons Attribution icon Creative Commons Share Alike icon
This content is licensed under the Creative Commons
Attribution ShareAlike License v. 3.0:
http://creativecommons.org/licenses/by-sa/3.0/

openchange-2.0/apidocs/html/mapiproxy/dcesrv__mapiproxy__module_8c.html000066400000000000000000000052611223057412600266270ustar00rootroot00000000000000 MAPIProxy 2.0 API Documentation
dcesrv_mapiproxy_module.c File Reference

mapiproxy modules management More...

#include "mapiproxy/dcesrv_mapiproxy.h"
#include "libmapiproxy.h"
#include <util/debug.h>

Detailed Description

mapiproxy modules management


Creative Commons License
Creative Commons Attribution icon Creative Commons Share Alike icon
This content is licensed under the Creative Commons
Attribution ShareAlike License v. 3.0:
http://creativecommons.org/licenses/by-sa/3.0/

openchange-2.0/apidocs/html/mapiproxy/dcesrv__mapiproxy__nspi_8c.html000066400000000000000000000232421223057412600263120ustar00rootroot00000000000000 MAPIProxy 2.0 API Documentation
dcesrv_mapiproxy_nspi.c File Reference

NSPI hook functions. More...

#include "mapiproxy/dcesrv_mapiproxy.h"
#include "mapiproxy/dcesrv_mapiproxy_proto.h"
#include "libmapi/mapidefs.h"
#include "libmapi/property_altnames.h"

Functions

bool mapiproxy_NspiDNToMId (struct dcesrv_call_state *dce_call, struct NspiDNToMId *r)
bool mapiproxy_NspiGetProps (struct dcesrv_call_state *dce_call, struct NspiGetProps *r)
bool mapiproxy_NspiQueryRows (struct dcesrv_call_state *dce_call, struct NspiQueryRows *r)
static char * x500_get_servername (const char *dn)

Detailed Description

NSPI hook functions.

Function Documentation

bool mapiproxy_NspiDNToMId ( struct dcesrv_call_state *  dce_call,
struct NspiDNToMId *  r 
)

This function looks if the server DN string in the request holds the mapiproxy netbios name and replaces it with the original Exchange server one fetched from NspiQueryRows or NspiGetProps.

Parameters
dce_callpointer to the session context
rpointer to the NspiDNToMId structure
Returns
true on success or false if no occurrence of the mapiproxy netbios name was found.

Referenced by mapiproxy_op_dispatch().

bool mapiproxy_NspiGetProps ( struct dcesrv_call_state *  dce_call,
struct NspiGetProps *  r 
)

This function replaces network address from the binding strings returned by Exchange for the PR_EMS_AB_NETWORK_ADDRESS property and limit the binding strings scope to ncacn_ip_tcp.

Parameters
dce_callpointer to the session context
rpointer to the NspiGetProps structure
Returns
true on success, otherwise false

Referenced by mapiproxy_op_ndr_push().

bool mapiproxy_NspiQueryRows ( struct dcesrv_call_state *  dce_call,
struct NspiQueryRows *  r 
)

This function replaces the Exchange server name with mapiproxy netbios name for the PR_EMS_AB_HOME_MDB property and saves the original name in a global variable for further usage - such as mapiproxy_NspiDNToMId.

Parameters
dce_callpointer to the session context
rpointer to the NspiQueryRows structure
See Also
mapiproxy_NspiDNToMId

References x500_get_servername().

Referenced by mapiproxy_op_ndr_push().

static char* x500_get_servername ( const char *  dn)
static

Retrieve the servername from a DN string

Parameters
dnthe DN string
Returns
a talloc'd server name

Referenced by mapiproxy_NspiQueryRows().


Creative Commons License
Creative Commons Attribution icon Creative Commons Share Alike icon
This content is licensed under the Creative Commons
Attribution ShareAlike License v. 3.0:
http://creativecommons.org/licenses/by-sa/3.0/

openchange-2.0/apidocs/html/mapiproxy/dcesrv__mapiproxy__rfr_8c.html000066400000000000000000000101641223057412600261310ustar00rootroot00000000000000 MAPIProxy 2.0 API Documentation
dcesrv_mapiproxy_rfr.c File Reference

NSPI Referral hook functions. More...

#include "mapiproxy/dcesrv_mapiproxy.h"
#include "mapiproxy/dcesrv_mapiproxy_proto.h"

Functions

bool mapiproxy_RfrGetNewDSA (struct dcesrv_call_state *dce_call, struct RfrGetNewDSA *r)

Detailed Description

NSPI Referral hook functions.

Function Documentation

bool mapiproxy_RfrGetNewDSA ( struct dcesrv_call_state *  dce_call,
struct RfrGetNewDSA *  r 
)

This function replaces the Exchange server FQDN with mapiproxy one.

Returns
true on success, otherwise false

Referenced by mapiproxy_op_ndr_push().


Creative Commons License
Creative Commons Attribution icon Creative Commons Share Alike icon
This content is licensed under the Creative Commons
Attribution ShareAlike License v. 3.0:
http://creativecommons.org/licenses/by-sa/3.0/

openchange-2.0/apidocs/html/mapiproxy/dcesrv__mapiproxy__server_8c.html000066400000000000000000000162001223057412600266430ustar00rootroot00000000000000 MAPIProxy 2.0 API Documentation
dcesrv_mapiproxy_server.c File Reference

mapiproxy server modules management More...

#include "mapiproxy/dcesrv_mapiproxy.h"
#include "libmapiproxy.h"
#include <util/debug.h>

Functions

_PUBLIC_ TDB_CONTEXT * mapiproxy_server_emsabp_tdb_init (struct loadparm_context *lp_ctx)
_PUBLIC_ NTSTATUS mapiproxy_server_init (struct dcesrv_context *dce_ctx)
_PUBLIC_ void * mapiproxy_server_openchange_ldb_init (struct loadparm_context *lp_ctx)

Detailed Description

mapiproxy server modules management

Function Documentation

_PUBLIC_ TDB_CONTEXT* mapiproxy_server_emsabp_tdb_init ( struct loadparm_context *  lp_ctx)

Initialize an EMSABP TDB context available to all instances when Samba is not run in single mode.

Parameters
lp_ctxpointer to the loadparm context
Note
TDB database can't be opened twice with O_RDWR flags. We ensure here we have a general context initialized, which we'll reopen within forked instances

return Allocated TDB context on success, otherwise NULL

Referenced by emsabp_tdb_init().

_PUBLIC_ NTSTATUS mapiproxy_server_init ( struct dcesrv_context *  dce_ctx)

Initialize mapiproxy servers modules

Parameters
dce_ctxpointer to the connection context
Returns
NT_STATUS_OK on success otherwise NT error

Referenced by mapiproxy_op_init_server().

_PUBLIC_ void* mapiproxy_server_openchange_ldb_init ( struct loadparm_context *  lp_ctx)

Initialize an openchange LDB context available to all mapiproxy instances. This LDB context points on the OpenChange dispatcher database used within emsmdb default provider.

Parameters
lp_ctxpointer to the loadparm context
Note
The memory context is not free'd leading and causes a loss record.
Returns
Allocated LDB context on success, otherwise NULL

Referenced by emsmdbp_openchange_ldb_init().


Creative Commons License
Creative Commons Attribution icon Creative Commons Share Alike icon
This content is licensed under the Creative Commons
Attribution ShareAlike License v. 3.0:
http://creativecommons.org/licenses/by-sa/3.0/

openchange-2.0/apidocs/html/mapiproxy/dcesrv__mapiproxy__session_8c.html000066400000000000000000000450551223057412600270320ustar00rootroot00000000000000 MAPIProxy 2.0 API Documentation
dcesrv_mapiproxy_session.c File Reference

session API for mapiproxy modules More...

#include "mapiproxy/dcesrv_mapiproxy.h"
#include "libmapiproxy.h"

Functions

bool mpm_session_cmp (struct mpm_session *session, struct dcesrv_call_state *dce_call)
bool mpm_session_cmp_sub (struct mpm_session *session, struct server_id sid, uint32_t context_id)
bool mpm_session_increment_ref_count (struct mpm_session *session)
struct mpm_session * mpm_session_init (TALLOC_CTX *mem_ctx, struct dcesrv_call_state *dce_call)
struct mpm_session * mpm_session_new (TALLOC_CTX *mem_ctx, struct server_id serverid, uint32_t context_id)
bool mpm_session_release (struct mpm_session *session)
bool mpm_session_set_destructor (struct mpm_session *session, bool(*destructor)(void *))
bool mpm_session_set_private_data (struct mpm_session *session, void *private_data)

Detailed Description

session API for mapiproxy modules

Function Documentation

bool mpm_session_cmp ( struct mpm_session *  session,
struct dcesrv_call_state *  dce_call 
)

Compare the mpm session with the session context one

This function is a wrapper on mpm_session_cmp_sub

Parameters
sessionpointer to the mapiproxy module session
dce_callpointer to the session context
Returns
true on success, otherwise false
See Also
mpm_session_cmp_sub

References mpm_session_cmp_sub().

Referenced by cache_dispatch(), cache_pull_OpenAttach(), cache_pull_OpenMessage(), cache_pull_OpenStream(), cache_pull_Release(), cache_push_OpenAttach(), cache_push_OpenMessage(), cache_push_OpenStream(), and cache_push_ReadStream().

bool mpm_session_cmp_sub ( struct mpm_session *  session,
struct server_id  sid,
uint32_t  context_id 
)

Compare the mpm session with the session context one

Parameters
sessionpointer to the mapiproxy module session
sidreference to a server_id structure to compare
context_idthe connection context id to compare

Referenced by mpm_session_cmp().

bool mpm_session_increment_ref_count ( struct mpm_session *  session)

Increment the ref_count associated to a session

Parameters
sessionpointer to the session where to increment ref_count
Returns
true on success, otherwise false

Referenced by dcesrv_EcDoConnect(), dcesrv_EcDoConnectEx(), and dcesrv_NspiBind().

struct mpm_session* mpm_session_init ( TALLOC_CTX *  mem_ctx,
struct dcesrv_call_state *  dce_call 
)
read

Create and return an allocated pointer to a mpm session

Parameters
mem_ctxpointer to the memory context
dce_callpointer to the session context
Returns
Pointer to an allocated mpm_session structure on success, otherwise NULL

References mpm_session_new().

Referenced by cache_pull_OpenAttach(), cache_pull_OpenMessage(), cache_pull_OpenStream(), dcesrv_EcDoConnect(), dcesrv_EcDoConnectEx(), and dcesrv_NspiBind().

struct mpm_session* mpm_session_new ( TALLOC_CTX *  mem_ctx,
struct server_id  serverid,
uint32_t  context_id 
)
read

Create and return an allocated pointer to a mpm session

Parameters
mem_ctxpointer to the memory context
serveridreference to the session context server identifier structure
context_idreference to the context identifier
Returns
Pointer to an allocated mpm_session structure on success, otherwise NULL

Referenced by mpm_session_init().

bool mpm_session_release ( struct mpm_session *  session)

Release a mapiproxy session context

Parameters
sessionpointer to the mpm session context
Returns
true on success, otherwise false

Referenced by cache_pull_Release(), dcesrv_EcDoDisconnect(), and dcesrv_NspiUnbind().

bool mpm_session_set_destructor ( struct mpm_session *  session,
bool(*)(void *)  destructor 
)

Set the mpm session destructor

Parameters
sessionpointer to the mpm session context
destructorpointer to the destructor function
Returns
true on success, otherwise false

Referenced by dcesrv_EcDoConnect(), dcesrv_EcDoConnectEx(), and dcesrv_NspiBind().

bool mpm_session_set_private_data ( struct mpm_session *  session,
void *  private_data 
)

Set the mpm session pointer on private data

Parameters
sessionpointer to the mpm session context
private_datageneric pointer on private data
Returns
true on success, otherwise false

Referenced by dcesrv_EcDoConnect(), dcesrv_EcDoConnectEx(), and dcesrv_NspiBind().


Creative Commons License
Creative Commons Attribution icon Creative Commons Share Alike icon
This content is licensed under the Creative Commons
Attribution ShareAlike License v. 3.0:
http://creativecommons.org/licenses/by-sa/3.0/

openchange-2.0/apidocs/html/mapiproxy/devdoc.png000066400000000000000000000022571223057412600220620ustar00rootroot00000000000000‰PNG  IHDRàw=øvIDATH‰í•ÛoUE‡¿™};§íé…ÚÒSO¡§biCU"cÄG_LÓ‰ù#ôÍ¿Æ5F4ñA‰ÑŒ/n (¥Ð––ôôr.û왵|ا¶$†à“/®d’Ù“™ùÖoýffÃÿñ_‡y”Ic#}?\åðä(a`P`ayoÏßäÒõ%œ“(yñÙ*Ï?½ŸòP/1ÓÀÉBÌf^Ήè;"úýÆVKÏ\¼Åé_nrweãသbÌუ;4ÆÌ‚ Ø új’Ä'K]…£µõu³¸´ª•±aÓßßÃæFëZ£Ù~xÏ{¹;7ŸŸ¯Üæ§Kól5Û;€ñò/?ÈÓO–I’¸ÛÀ‰0 Oö÷õ½ä¼Fwî,3wã­´ IšB!fbb”òp?ˆdµÍôKçäUý¼ÙvísWïðá©_ F‡{92]9b-o ì9aÃBiõþ:g/Ü Ùl"âÀZ‹ªb ˆ(‹K5jm Å$(ÎöuG³Í–[VÌûÏÍì{û³ÓW¼…|²ó2»otèžîBiaþ6×çþ Ñhb­% #’$!Žc¢0$Žcâ$Ɔ!‚¡™:–×RÚ¶‡'&îíïï{óúÂj±ÑÊrªš7qmphr„gföSÛlqwé>Ë÷Öhµ-Q"â)$6£˜½Ãƒì«”ylO>kã²6.sæÓo.—2ç·`,A” @»Õ¢z¦&F˜™gm£Îââ*+«5ºº T*e*•2Q`piJ–¶16À1¢J£™YUrÛn“*„ظ€µ!âi½AÁz¦Txê©I’¤‹v« ÎAÐMÜÝ:‡÷mT<" (Гl`¬ÙQ„Æâb €,­“5·°béêÁ‹ø,ß…Î! ‚<Ù¿Å!Æt†TQT1†¸X¡ ㄨ ª" ä‰yQ‚À€ÙU"Uƒ±;›« ¨GÔ`Ä Æ`ŒÁZ‹Á Þ¡²Ýò$T$OL•íuLþûTPÑmSPÄÔ{T‡z‡xŸ÷;jt[ydž] rˆJG6Šú|\D‡A|J±Ø‹¸¬“µëëQñ Òì2YUɼ&½¤õ.s¹óÆí$àœÇ«cÀ;ðÛ€ˆª *ˆt ìRPÛlþpêë3¿M¨N öõ)Y³*y]½0 âwš×_¼gm}ƒ?o/¥g.Üøb}«•ªjþØMW‡806ÈO—o—öôv? MAPIProxy 2.0 API Documentation
nspi Directory Reference

Files

file  dcesrv_exchange_nsp.c
 OpenChange NSPI Server implementation.
file  dcesrv_exchange_nsp.h
file  emsabp.c
 Address Book Provider implementation.
file  emsabp_property.c
 Property Tag to AD attributes mapping.
file  emsabp_tdb.c
 EMSABP TDB database API.

Creative Commons License
Creative Commons Attribution icon Creative Commons Share Alike icon
This content is licensed under the Creative Commons
Attribution ShareAlike License v. 3.0:
http://creativecommons.org/licenses/by-sa/3.0/

openchange-2.0/apidocs/html/mapiproxy/dir_0cb97b4c0e849ee81c074db53a5211e5.html000066400000000000000000000147121223057412600262050ustar00rootroot00000000000000 MAPIProxy 2.0 API Documentation
libmapiserver Directory Reference

Files

file  libmapiserver.h
file  libmapiserver_oxcdata.c
 OXCDATA Data Structures.
file  libmapiserver_oxcfold.c
 OXCFOLD ROP Response size calculations.
file  libmapiserver_oxcfxics.c
 OXCFXICS ROP Response size calculations.
file  libmapiserver_oxcmsg.c
 OXCMSG ROP Response size calculations.
file  libmapiserver_oxcnotif.c
 OXCNOTIF ROP Response size calculations.
file  libmapiserver_oxcperm.c
file  libmapiserver_oxcprpt.c
 OXCPRPT ROP Response size calculations.
file  libmapiserver_oxcstor.c
 OXCSTOR ROP Response size calculations.
file  libmapiserver_oxctabl.c
 OXCTABL ROP Response size calculations.
file  libmapiserver_oxomsg.c
 OXOMSG ROP Response size calculations.
file  libmapiserver_oxorule.c
 OXORULE ROP Response size calculations.

Creative Commons License
Creative Commons Attribution icon Creative Commons Share Alike icon
This content is licensed under the Creative Commons
Attribution ShareAlike License v. 3.0:
http://creativecommons.org/licenses/by-sa/3.0/

openchange-2.0/apidocs/html/mapiproxy/dir_169eeca83f8b96a00b50043e4befc92d.html000066400000000000000000000133201223057412600263430ustar00rootroot00000000000000 MAPIProxy 2.0 API Documentation
libmapiproxy Directory Reference

Files

file  dcesrv_mapiproxy_module.c
 mapiproxy modules management
file  dcesrv_mapiproxy_server.c
 mapiproxy server modules management
file  dcesrv_mapiproxy_session.c
 session API for mapiproxy modules
file  entryid.c
 EntryID convenient routines.
file  libmapiproxy.h
file  mapi_handles.c
 API for MAPI handles management.
file  modules.c
file  openchangedb.c
 OpenChange Dispatcher database routines.
file  openchangedb_message.c
 OpenChange Dispatcher database message routines.
file  openchangedb_property.c
file  openchangedb_table.c
 OpenChange Dispatcher database table routines.

Creative Commons License
Creative Commons Attribution icon Creative Commons Share Alike icon
This content is licensed under the Creative Commons
Attribution ShareAlike License v. 3.0:
http://creativecommons.org/licenses/by-sa/3.0/

openchange-2.0/apidocs/html/mapiproxy/dir_176deadb32849cba3f91581aabf4bbdf.html000066400000000000000000000053661223057412600265720ustar00rootroot00000000000000 MAPIProxy 2.0 API Documentation
documentation Directory Reference

Files

file  Mainpage.doxy
file  mapiproxy-documentation.doxy
file  mapistore-documentation.doxy

Creative Commons License
Creative Commons Attribution icon Creative Commons Share Alike icon
This content is licensed under the Creative Commons
Attribution ShareAlike License v. 3.0:
http://creativecommons.org/licenses/by-sa/3.0/

openchange-2.0/apidocs/html/mapiproxy/dir_4c35cb2dde09236b6b5ef740a040f283.html000066400000000000000000000105271223057412600261760ustar00rootroot00000000000000 MAPIProxy 2.0 API Documentation
modules Directory Reference

Files

file  mpm_cache.c
 Cache messages and attachments so we can reduce WAN traffic.
file  mpm_cache.h
file  mpm_cache_ldb.c
 LDB routines for the cache module.
file  mpm_cache_stream.c
 Storage routines for the cache module.
file  mpm_downgrade.c
 Downgrade EMSMDB protocol version EcDoConnect/EcDoRpc.
file  mpm_dummy.c
file  mpm_pack.c
 Pack/Unpack specified MAPI calls into/from a custom MAPI call.

Creative Commons License
Creative Commons Attribution icon Creative Commons Share Alike icon
This content is licensed under the Creative Commons
Attribution ShareAlike License v. 3.0:
http://creativecommons.org/licenses/by-sa/3.0/

openchange-2.0/apidocs/html/mapiproxy/dir_4f343f6bd7925b18a2c3c13737f093b9.html000066400000000000000000000122071223057412600260550ustar00rootroot00000000000000 MAPIProxy 2.0 API Documentation
mapiproxy Directory Reference

Directories

directory  documentation
directory  libmapiproxy
directory  libmapiserver
directory  modules
directory  servers

Files

file  dcesrv_mapiproxy.c
 mapiproxy main file
file  dcesrv_mapiproxy.h
file  dcesrv_mapiproxy_nspi.c
 NSPI hook functions.
file  dcesrv_mapiproxy_proto.h
file  dcesrv_mapiproxy_rfr.c
 NSPI Referral hook functions.
file  dcesrv_mapiproxy_unused.c

Creative Commons License
Creative Commons Attribution icon Creative Commons Share Alike icon
This content is licensed under the Creative Commons
Attribution ShareAlike License v. 3.0:
http://creativecommons.org/licenses/by-sa/3.0/

openchange-2.0/apidocs/html/mapiproxy/dir_5f92d1cc3ef1ed494d20737c0a581a70.html000066400000000000000000000060041223057412600262000ustar00rootroot00000000000000 MAPIProxy 2.0 API Documentation
default Directory Reference

Directories

directory  emsmdb
directory  nspi
directory  rfr

Creative Commons License
Creative Commons Attribution icon Creative Commons Share Alike icon
This content is licensed under the Creative Commons
Attribution ShareAlike License v. 3.0:
http://creativecommons.org/licenses/by-sa/3.0/

openchange-2.0/apidocs/html/mapiproxy/dir_955147c4045647e840edafd0078966e5.html000066400000000000000000000046531223057412600257400ustar00rootroot00000000000000 MAPIProxy 2.0 API Documentation
servers Directory Reference

Directories

directory  default

Creative Commons License
Creative Commons Attribution icon Creative Commons Share Alike icon
This content is licensed under the Creative Commons
Attribution ShareAlike License v. 3.0:
http://creativecommons.org/licenses/by-sa/3.0/

openchange-2.0/apidocs/html/mapiproxy/dir_d26905b8daec86404da18b971c53f2aa.html000066400000000000000000000163221223057412600262660ustar00rootroot00000000000000 MAPIProxy 2.0 API Documentation
emsmdb Directory Reference

Files

file  dcesrv_exchange_emsmdb.c
 OpenChange EMSMDB Server implementation.
file  dcesrv_exchange_emsmdb.h
file  emsmdbp.c
 EMSMDB Provider implementation.
file  emsmdbp_object.c
 Server-side specific objects init/release routines.
file  emsmdbp_provisioning.c
 Account provisioning.
file  oxcfold.c
 Folder object routines and Rops.
file  oxcfxics.c
 FastTransfer and ICS object routines and Rops.
file  oxcmsg.c
 Message and Attachment object routines and Rops.
file  oxcnotif.c
 Core Notifications routines and Rops.
file  oxcperm.c
 Access and Operation Permissions Rops.
file  oxcprpt.c
 Property and Stream Object routines and Rops.
file  oxcstor.c
 Server-side store objects routines and Rops.
file  oxctabl.c
 Table object routines and Rops.
file  oxomsg.c
 Server-side message routines and Rops.
file  oxorule.c

Creative Commons License
Creative Commons Attribution icon Creative Commons Share Alike icon
This content is licensed under the Creative Commons
Attribution ShareAlike License v. 3.0:
http://creativecommons.org/licenses/by-sa/3.0/

openchange-2.0/apidocs/html/mapiproxy/dir_fd69325d438aa8719f06cb66ae8a0ac3.html000066400000000000000000000057031223057412600262760ustar00rootroot00000000000000 MAPIProxy 2.0 API Documentation
rfr Directory Reference

Files

file  dcesrv_exchange_ds_rfr.c
 OpenChange RFR Server implementation.
file  dcesrv_exchange_ds_rfr.h

Creative Commons License
Creative Commons Attribution icon Creative Commons Share Alike icon
This content is licensed under the Creative Commons
Attribution ShareAlike License v. 3.0:
http://creativecommons.org/licenses/by-sa/3.0/

openchange-2.0/apidocs/html/mapiproxy/doxygen.png000066400000000000000000000073031223057412600222700ustar00rootroot00000000000000‰PNG  IHDRh ;ˆØŠIDATxí]y\•Õº~45%TL Q”PE"q–Û11±]8a„w*©¨(*â" ˆzÀè`8 ¨‰¢mÅ,’òà„p$%”œBó(8k†Ü÷ýÜû6lòö»§k÷Ç÷[ÏÞß·Ö;?k½ëßÕÕÕPxÑêÏ't´ÏùÈ€zÀÇÅ3_€Q4€g@œmÿ ¾ò‰âci‰ôçÿ{ ðÇð¬ù~½Á€4:õHcÂü ðŸÁ³„ª'ÕPÆæ P7^h،♠zb„cóP¨„ 3‚† Ò}çÿO²qÁºNkÝTÛ(É?d Ç~z<’«4Óǡ؞Þv­zµÙ¦õ¬ZâdÛ,Ë6Ók±]Fz< ¾ZçƒsÕ?ìƒsUø2SÉåwê1”c`[ì—}%ѽ.Ô¼6‚BLZ˜û!F8[ ¹…×TéÛ— »Þ#gó]å:vžu?‡vèbÙR˜?wùŽŸ¾ÊÐgbÑÉÌÕ$kF~Ê;عÆ•¢ïX®?ÉèlÆÙôõà»Nʪ¼­,ìHC§gAz•ÆlÓº­gÑú ]œjÎñåM…3ÓÚæoÒ³'=‘$Ò÷f}G•ŸS_‡öèco.Êȹ :ó£ Ãds®Ù:1=¼{ƒå9?÷ý…zqÛvîÓi‰D’p¿Ë šmÙíoÛâýaÖüEqÒµwÌ}¿~{òj€ç{ôºŸFNëí[ëOq·ÇOSúXO]°>‚‚muæÄ¾e¤“5Ë{¨JÕ¯£(›´«bÂçû’ÍlÓÅ}žïú`éUÞy„ac§Á†ÔCºŠóAkl‘±y¥†ô¢ùôs÷Aø¬7ÄõôoJ±äÄ ù.¥Be. Z¬Ð×ÇÈöå¹­ù'Ù-PëìŠyF.ž‚žÝÚ€lp&.êˆð•jò7’re’z19»ã§HGíø%œüq°ïüz׈c¬_k_")ŸHJnÐÑ~ˆÐÖ˜á´äÕ5 µÁq€ÿ5#¸·îà¶+9T‘‚ ðŽ÷Rܸrz“Ï´Ì =Ï…{ðáO£Èf ¡Íwg|Ž’Ü/¢Þ$÷¯¢ëðúÀ;¿à¨Ö™âÒÆ­]¯ÜW"Þ/< ‡÷DÏà°½üB}çyIEc^—ƒ=[V“Ýh²ëMä$l];Kû®¸ýr¦È*Åò ÿtÒõ$]•MŸ÷´;×I€1èó!‚œõ¸M õ¨(fÌæ<ÁÎÎò5~z¿ù¶ž mÌêÕ >–âÚ©âëˆIÎÞçz;ãu[i·eç^ÆÜÙÓ³NÞëF6B\}7†»+üŽÓ,Ã'a ½˜-yHY¿,‘^—ñfú~ß?Hcø¸…¸ñó{Z+4\såƒû·¯Ù·nߣð«íFÆ¡sغëû§D¾?ò<–Ævkx0ÅM±ælذÁIÓxÿd”žÜÉ÷EE»AªM«g*È£YEí7Û™^[uíý®v[wGå†=Ed¼n×¶ÆæÖÅl¡'¨pGÚk+‹æ¢À¬¨C8ªâš2 dz3H£ß ¡¨BÒûSÃÅù[wŘ ~xpçútÁæmö¤Å£¥iQæ­‰AB1ÉfÙ‰›4u¹ïìIÒ]Ë6äò%ÿ†† 1t.’NJph¬zÌ ÎR1Ž"3-"¸‡‹&ìó°1âüžìó[:‡ï„¼‘……N m–“W0®_èÜœ ×õ6ùò&»)Æìꦬýæ}¬ñ~»{múù]z½£M•ºP~^Îá:eQTÙ_*7ÕÄ9É8—·Ëï 3°¶47E•î¿u÷“SÉ»U¯ _ NíºôW¬e¸ÄNÓ|»;™¿;ŒæÅd"ȉôøòÞµõï¾®½"èÄ´ÖMM+bYµ‘_ÉæEÝüÎ]P»¹XKÐI½Þ¥oE<_¹(„EP±Œ|mÇÁ¡‘Ý,ŠÓ©ººZ±Îߺ§×kÝ,kÍMš`Äø…jzeU»æ ™Át3ÓÀ½˜6—ÒöùË·r¨¹Ñ}““wö:Χùë¼ ¿|‚TܵÉQˆKßç_ÁâÀ™œ”pÑÐóໃ¼Ydâ0!®àa –øöçW$ÃÁ‘Á$/\¬$ð 2ÞímÞLH‹Ÿ èd£HVÜ,:ò½»RÍZšJ­a„z*>‹_…NT(ù‚^SVF­U¹8ñEþôñ܈óùnd;«®8™\C]ø=Èêm¬Æ:‚´ÆbãDd=Áãßžˆ‹UU5O‹|]þð®Pèêv‰á\]2ßìÿ"yÈ[ïyʧz£g{Y«{„Ùø5©ÿ;w{N3é­nâĨw§Á¢ÍK¢Ý­ûÏ29Id¿’ì y)ìPÞò8ŒÅ©¯‰±@mPÔñwjl,6 áhWÕ˜d öà uõmÁp®.™á£Ç…twöR x­BδYcŒxg*vo  yò‘•“[¬?ÜVœ˜0ÒN¡O난~Žó’¯·h#´Hkýœ±8kÓß^Àq@]àÓ“ø,56´¯÷Í-κU»n…[>]@nîøÏœp›[œ6# €4tën¯:ŽÒþ}…—8äT9_žY$/´G’K™©ù†•(óÑ’Mø©`ŸÉdѺ;ùO‹B Ó&P{qöhJÉ+Úé–§¦l2«MïöÝ_1ÑÓ«’t¸½±l€ëØya ¦ô©«®½ÆL^¬žêñš¸ùy.¾Û½Š[ u/]½‹iS}øN>²e1™q‡jfÚ&¢©iT\=kÏ›ÀXô-.84V5ðu!TE˜ þ.ŒOH´¶4—zwTr.ï‰¦Ë xõµ·œÖ„HÆù£žÈHùg Ñhñ’T$ßyq¸zþ¨p¿´ë< q•ró÷š‰wÿÍÑð–I]´–æI²é²˜sÂ"×:Õ–bÕ¦“ÈÙL6¢9VÊÓWž§<æ;”3?ý©Mê3AV#µ±ËÞ¯‘ž K£UrÝ9!›qát¦H£Ù+6ÇV…/TS^pÃùqgLP'Ú5E ‚–ÀÞºîÄ Ën"2|Ÿ;®W»Îý"Ö¬TwÖâµtúŽO'› á+W Ã+¦âZÌ–<ÕÆ&nOÝ,IŠ£06.ÁZ.Çñúøh*INÚ’Oe½ÉgBXÐÔZóäøä9èü“hÒíDSš¥¡Ê µA¯/Ôc¸ö“`A§¯"zå|‘ €ÅŸ¨ú;HÍ#‚Î|%ÄOˆƒ«OàÌÉÐÜD ž mÜðâc–ƤÉÂqm¶uË&~÷núÒË £ÇÏ€ZÕj =«_n[‡‡÷nN§ÏÝ$_¾bE˜‚€Õ)ù8¾?6‘lú“ÍÙæÖ}#bW( œ³d-®•p&¡ý’œÖa”"9öõņÐ$’Ú›AÜ!ä;ÐÑõè{~á¹8‘ÛÞ£1ÛÓÉ0ž`²#´kÒuäNÅÖ Q¹bhæ ”8ûÓMáŽa›•¿”w±h²¢®qŠæ°(bK ‚’Z¾Ò%ÐÆémáãÖË(Éý‚ÛJ)@> þ›7% ï{y Á“¾ÆÒîohfòô>{pÿ.­_Î%±ÉèägëlZØ\B2B #™¸ÚüÒºp‚hÝšü®[¥Ü<‹#SpñÌA7’ãØHƒt4:Ÿ|g¨tÓL¶*($Æ©»ì…®ù’ó÷$;b›ÔÙ`=¶£¦M„MÌÄ5ò«·Ç¾“H·ÌH.¼žHeAîº5}r­dõ¨±)ÀT};€Q5iÖ2…O0ü…0óñÃ;óæ,Š´²µ냔}g‘£]‹7å9ˆà©_{üèîêžC>úhê{Ž .ÈìðIIð€?[Kswz6Òuíý¬;µ€ç§OåâJÉa˶zv°éd† ¤µâ‚l´é舊«Åüy¾c÷ÁèÖÍ'ràúÅ™TWÕôÓ°¡L €|ʽŒ¼ì­høBã ÝTëî'ò]Kø£ìâÏ(=¹Kx €¿ LÌ,Pý¤Êµu‡¹…׈ §Å¾÷à1Ý«Äý;¿pGDäxZYÛ kfæ6¸ùóæ7®œ®þ6·ÕoÚ¾ÔH~ò®Þ¸â 8Uø“p<ºw3¡a£ÏÑ’‘3èÏ"€bˆ-ÎܺÏ_ªÅ]+ËM©zü°s“f-êçhÇãÑýÊãôÿ5}ZQNb{Ó?å%ÿ\SUõعIÓæ}~}p[œoÔÄ„êÐMMZáNÅå@>Œ„²á6(?¡Åé âK½+ü?À%ÝÝ·/Ç1‚9áUø?B)”ÕèâÞlÈÒêÏ @=àùÄÞžk­®ÅIEND®B`‚openchange-2.0/apidocs/html/mapiproxy/dynsections.js000066400000000000000000000041341223057412600230040ustar00rootroot00000000000000function toggleVisibility(linkObj) { var base = $(linkObj).attr('id'); var summary = $('#'+base+'-summary'); var content = $('#'+base+'-content'); var trigger = $('#'+base+'-trigger'); var src=$(trigger).attr('src'); if (content.is(':visible')===true) { content.hide(); summary.show(); $(linkObj).addClass('closed').removeClass('opened'); $(trigger).attr('src',src.substring(0,src.length-8)+'closed.png'); } else { content.show(); summary.hide(); $(linkObj).removeClass('closed').addClass('opened'); $(trigger).attr('src',src.substring(0,src.length-10)+'open.png'); } return false; } function updateStripes() { $('table.directory tr'). removeClass('even').filter(':visible:even').addClass('even'); } function toggleLevel(level) { $('table.directory tr').each(function(){ var l = this.id.split('_').length-1; var i = $('#img'+this.id.substring(3)); var a = $('#arr'+this.id.substring(3)); if (l MAPIProxy 2.0 API Documentation
emsabp.c File Reference

Address Book Provider implementation. More...

#include "mapiproxy/dcesrv_mapiproxy.h"
#include "dcesrv_exchange_nsp.h"

Functions

_PUBLIC_ enum MAPISTATUS emsabp_ab_container_by_id (TALLOC_CTX *mem_ctx, struct emsabp_context *emsabp_ctx, uint32_t ContainerID, struct ldb_message **ldb_msg)
_PUBLIC_ enum MAPISTATUS emsabp_ab_container_enum (TALLOC_CTX *mem_ctx, struct emsabp_context *emsabp_ctx, uint32_t ContainerID, struct ldb_result **ldb_resp)
_PUBLIC_ enum MAPISTATUS emsabp_EphemeralEntryID_to_Binary_r (TALLOC_CTX *mem_ctx, struct EphemeralEntryID *ephEntryID, struct Binary_r *bin)
_PUBLIC_ enum MAPISTATUS emsabp_fetch_attrs (TALLOC_CTX *mem_ctx, struct emsabp_context *emsabp_ctx, struct PropertyRow_r *aRow, uint32_t MId, uint32_t dwFlags, struct SPropTagArray *pPropTags)
_PUBLIC_ enum MAPISTATUS emsabp_fetch_attrs_from_msg (TALLOC_CTX *mem_ctx, struct emsabp_context *emsabp_ctx, struct PropertyRow_r *aRow, struct ldb_message *ldb_msg, uint32_t MId, uint32_t dwFlags, struct SPropTagArray *pPropTags)
_PUBLIC_ enum MAPISTATUS emsabp_get_account_info (TALLOC_CTX *mem_ctx, struct emsabp_context *emsabp_ctx, const char *username, struct ldb_message **ldb_msg)
_PUBLIC_ enum MAPISTATUS emsabp_get_CreationTemplatesTable (TALLOC_CTX *mem_ctx, struct emsabp_context *emsabp_ctx, uint32_t dwFlags, struct PropertyRowSet_r **SRowSet)
_PUBLIC_ enum MAPISTATUS emsabp_get_HierarchyTable (TALLOC_CTX *mem_ctx, struct emsabp_context *emsabp_ctx, uint32_t dwFlags, struct PropertyRowSet_r **SRowSet)
_PUBLIC_ struct emsabp_context * emsabp_init (struct loadparm_context *lp_ctx, TDB_CONTEXT *tdb_ctx)
_PUBLIC_ enum MAPISTATUS emsabp_PermanentEntryID_to_Binary_r (TALLOC_CTX *mem_ctx, struct PermanentEntryID *permEntryID, struct Binary_r *bin)
_PUBLIC_ void * emsabp_query (TALLOC_CTX *mem_ctx, struct emsabp_context *emsabp_ctx, struct ldb_message *msg, uint32_t ulPropTag, uint32_t MId, uint32_t dwFlags)
_PUBLIC_ enum MAPISTATUS emsabp_search (TALLOC_CTX *mem_ctx, struct emsabp_context *emsabp_ctx, struct PropertyTagArray_r *MIds, struct Restriction_r *restriction, struct STAT *pStat, uint32_t limit)
_PUBLIC_ enum MAPISTATUS emsabp_search_dn (struct emsabp_context *emsabp_ctx, const char *dn, struct ldb_message **ldb_res)
_PUBLIC_ enum MAPISTATUS emsabp_search_legacyExchangeDN (struct emsabp_context *emsabp_ctx, const char *legacyDN, struct ldb_message **ldb_res, bool *pbUseConfPartition)
_PUBLIC_ enum MAPISTATUS emsabp_set_EphemeralEntryID (struct emsabp_context *emsabp_ctx, uint32_t DisplayType, uint32_t MId, struct EphemeralEntryID *ephEntryID)
_PUBLIC_ enum MAPISTATUS emsabp_set_PermanentEntryID (struct emsabp_context *emsabp_ctx, uint32_t DisplayType, struct ldb_message *msg, struct PermanentEntryID *permEntryID)
_PUBLIC_ enum MAPISTATUS emsabp_table_fetch_attrs (TALLOC_CTX *mem_ctx, struct emsabp_context *emsabp_ctx, struct PropertyRow_r *aRow, uint32_t dwFlags, struct PermanentEntryID *permEntryID, struct PermanentEntryID *parentPermEntryID, struct ldb_message *msg, bool child)
_PUBLIC_ bool emsabp_verify_codepage (struct emsabp_context *emsabp_ctx, uint32_t CodePage)
_PUBLIC_ bool emsabp_verify_user (struct dcesrv_call_state *dce_call, struct emsabp_context *emsabp_ctx)

Detailed Description

Address Book Provider implementation.

Function Documentation

_PUBLIC_ enum MAPISTATUS emsabp_ab_container_by_id ( TALLOC_CTX *  mem_ctx,
struct emsabp_context *  emsabp_ctx,
uint32_t  ContainerID,
struct ldb_message **  ldb_msg 
)

Fetch Address Book container record for given ContainerID

Parameters
mem_ctxmemory context for allocation
emsabp_ctxpointer to the EMSABP context
ContainerIDid of the container to fetch
ldb_msgpointer on pointer to the LDB message returned by the function
Returns
MAPI_E_SUCCESS on success, otherwise MAPI_ERROR

References emsabp_search_dn(), and emsabp_tdb_fetch_dn_from_MId().

Referenced by dcesrv_NspiResolveNames(), dcesrv_NspiResolveNamesW(), and emsabp_ab_container_enum().

_PUBLIC_ enum MAPISTATUS emsabp_ab_container_enum ( TALLOC_CTX *  mem_ctx,
struct emsabp_context *  emsabp_ctx,
uint32_t  ContainerID,
struct ldb_result **  ldb_resp 
)

Enumerate AB container entries

Parameters
mem_ctxpointer to the memory context
emsabp_ctxpointer to the EMSABP context
ContainerIDid of the container to fetch
ldb_respointer on pointer to the LDB result returned by the function
Returns
MAPI_E_SUCCESS on success, otherwise MAPI error

References emsabp_ab_container_by_id().

Referenced by dcesrv_NspiQueryRows().

_PUBLIC_ enum MAPISTATUS emsabp_EphemeralEntryID_to_Binary_r ( TALLOC_CTX *  mem_ctx,
struct EphemeralEntryID ephEntryID,
struct Binary_r *  bin 
)

Map an EphemeralEntryID structure into a Binary_r structure

Parameters
mem_ctxpointer to the memory context
ephEntryIDpointer to the Ephemeral EntryID structure
binpointer to the Binary_r structure the server will return
Returns
MAPI_E_SUCCESS on success, otherwise MAPI_E_INVALID_PARAMETER

Referenced by emsabp_query().

_PUBLIC_ enum MAPISTATUS emsabp_fetch_attrs ( TALLOC_CTX *  mem_ctx,
struct emsabp_context *  emsabp_ctx,
struct PropertyRow_r *  aRow,
uint32_t  MId,
uint32_t  dwFlags,
struct SPropTagArray *  pPropTags 
)

Builds the SRow array entry for the specified MId.

The function retrieves the DN associated to the specified MId within its on-memory TDB database. It next fetches the LDB record matching the DN and finally retrieve the requested properties for this record.

Parameters
mem_ctxpointer to the memory context
emsabp_ctxpointer to the EMSABP context
aRowpointer to the SRow structure where results will be stored
MIdMId to fetch properties for
dwFlagsbit flags specifying whether or not the server must return the values of the property PidTagEntryId in the Ephemeral or Permanent Entry ID format
pPropTagspointer to the property tags array
Note
We currently assume records are users.ldb
Returns
MAPI_E_SUCCESS on success, otherwise MAPI error

References emsabp_query(), and emsabp_tdb_fetch_dn_from_MId().

Referenced by dcesrv_NspiGetMatches(), dcesrv_NspiGetProps(), dcesrv_NspiQueryRows(), and dcesrv_NspiSeekEntries().

_PUBLIC_ enum MAPISTATUS emsabp_fetch_attrs_from_msg ( TALLOC_CTX *  mem_ctx,
struct emsabp_context *  emsabp_ctx,
struct PropertyRow_r *  aRow,
struct ldb_message *  ldb_msg,
uint32_t  MId,
uint32_t  dwFlags,
struct SPropTagArray *  pPropTags 
)

Build the SRow array entry for the specified ldb_message.

Parameters
mem_ctxpointer to the memory context
emsabp_ctxpointer to the EMSABP context
aRowpointer to the SRow structure where results will be stored
ldb_msgldb_message record to fetch results from
MIdMId of the entry to fetch (may be 0)
dwFlagsinput call flags (default to 0)
pPropTagspointer to the property tags array
Returns
MAPI_E_SUCCESS on success, otherwise MAPI error

References emsabp_query(), emsabp_tdb_fetch_MId(), and emsabp_tdb_insert().

Referenced by dcesrv_NspiQueryRows(), dcesrv_NspiResolveNames(), and dcesrv_NspiResolveNamesW().

_PUBLIC_ enum MAPISTATUS emsabp_get_account_info ( TALLOC_CTX *  mem_ctx,
struct emsabp_context *  emsabp_ctx,
const char *  username,
struct ldb_message **  ldb_msg 
)

Get AD record for Mail-enabled account

Parameters
mem_ctxpointer to the session context
emsabp_ctxpointer to the EMSABP context
usernameUser common name
ldb_msgPointer on pointer to ldb_message to return result to
Returns
MAPI_E_SUCCESS on success, otherwise MAPI_E_NOT_ENOUGH_RESOURCES, MAPI_E_NOT_FOUND or MAPI_E_CORRUPT_STORE

Referenced by emsabp_verify_user().

_PUBLIC_ enum MAPISTATUS emsabp_get_CreationTemplatesTable ( TALLOC_CTX *  mem_ctx,
struct emsabp_context *  emsabp_ctx,
uint32_t  dwFlags,
struct PropertyRowSet_r **  SRowSet 
)

Retrieve and build the CreationTemplates Table requested by GetSpecialTable NSPI call

Parameters
mem_ctxpointer to the memory context
emsabp_ctxpointer to the EMSABP context
dwFlagsflags controlling whether strings should be UNICODE or not
SRowSetpointer on pointer to the output SRowSet array
Returns
MAPI_E_SUCCESS on success, otherwise MAPI_E_CORRUPT_STORE

Referenced by dcesrv_NspiGetSpecialTable().

_PUBLIC_ enum MAPISTATUS emsabp_get_HierarchyTable ( TALLOC_CTX *  mem_ctx,
struct emsabp_context *  emsabp_ctx,
uint32_t  dwFlags,
struct PropertyRowSet_r **  SRowSet 
)

Retrieve and build the HierarchyTable requested by GetSpecialTable NSPI call

Parameters
mem_ctxpointer to the memory context
emsabp_ctxpointer to the EMSABP context
dwFlagsflags controlling whether strings should be UNICODE or not
SRowSetpointer on pointer to the output SRowSet array
Returns
MAPI_E_SUCCESS on success, otherwise MAPI_E_CORRUPT_STORE

References emsabp_set_PermanentEntryID(), and emsabp_table_fetch_attrs().

Referenced by dcesrv_NspiGetSpecialTable().

_PUBLIC_ struct emsabp_context* emsabp_init ( struct loadparm_context *  lp_ctx,
TDB_CONTEXT *  tdb_ctx 
)
read

Initialize the EMSABP context and open connections to Samba databases.

Parameters
lp_ctxpointer to the loadparm context
tdb_ctxpointer to the EMSABP TDB context
Returns
Allocated emsabp_context on success, otherwise NULL

References emsabp_tdb_init_tmp().

Referenced by dcesrv_NspiBind().

_PUBLIC_ enum MAPISTATUS emsabp_PermanentEntryID_to_Binary_r ( TALLOC_CTX *  mem_ctx,
struct PermanentEntryID permEntryID,
struct Binary_r *  bin 
)

Map a PermanentEntryID structure into a Binary_r structure (for PR_ENTRYID and PR_EMS_AB_PARENT_ENTRYID properties)

Parameters
mem_ctxpointer to the memory context
permEntryIDpointer to the Permanent EntryID structure
binpointer to the Binary_r structure the server will return
Returns
MAPI_E_SUCCESS on success, otherwise MAPI_E_INVALID_PARAMETER

Referenced by emsabp_query(), and emsabp_table_fetch_attrs().

_PUBLIC_ void* emsabp_query ( TALLOC_CTX *  mem_ctx,
struct emsabp_context *  emsabp_ctx,
struct ldb_message *  msg,
uint32_t  ulPropTag,
uint32_t  MId,
uint32_t  dwFlags 
)

Find the attribute matching the specified property tag and return the associated data.

Parameters
mem_ctxpointer to the memory context
emsabp_ctxpointer to the EMSABP context
msgpointer to the LDB message
ulPropTagthe property tag to lookup
MIdMinimal Entry ID associated to the current message
dwFlagsbit flags specifying whether or not the server must return the values of the property PidTagEntryId in the Ephemeral or Permanent Entry ID format
Note
This implementation is at the moment limited to MAILUSER, which means we arbitrary set PR_OBJECT_TYPE and PR_DISPLAY_TYPE while we should have a generic method to fill these properties.
Returns
Valid generic pointer on success, otherwise NULL

References emsabp_EphemeralEntryID_to_Binary_r(), emsabp_PermanentEntryID_to_Binary_r(), emsabp_property_get_attribute(), emsabp_property_get_ref_attr(), emsabp_property_is_ref(), emsabp_search_dn(), emsabp_set_EphemeralEntryID(), and emsabp_set_PermanentEntryID().

Referenced by emsabp_fetch_attrs(), and emsabp_fetch_attrs_from_msg().

_PUBLIC_ enum MAPISTATUS emsabp_search ( TALLOC_CTX *  mem_ctx,
struct emsabp_context *  emsabp_ctx,
struct PropertyTagArray_r *  MIds,
struct Restriction_r *  restriction,
struct STAT *  pStat,
uint32_t  limit 
)

Search Active Directory given input search criterias. The function associates for each records returned by the search a unique session Minimal Entry ID and a LDB message.

Parameters
mem_ctxpointer to the memory context
emsabp_ctxpointer to the EMSABP context
MIdspointer to the list of MIds the function returns
restrictionpointer to restriction rules to apply to the search
pStatpointer the STAT structure associated to the search
limitthe limit number of results the function can return
Note
SortTypePhoneticDisplayName sort type is currently not supported.
Returns
MAPI_E_SUCCESS on success, otherwise MAPI error

References emsabp_property_get_attribute(), emsabp_tdb_fetch_MId(), emsabp_tdb_insert(), and emsabp_tdb_lookup_MId().

Referenced by dcesrv_NspiGetMatches(), dcesrv_NspiSeekEntries(), and dcesrv_NspiUpdateStat().

_PUBLIC_ enum MAPISTATUS emsabp_search_dn ( struct emsabp_context *  emsabp_ctx,
const char *  dn,
struct ldb_message **  ldb_res 
)

Search for a given DN within AD and return the associated LDB message.

Parameters
emsabp_ctxpointer to the EMSABP context
dnpointer to the DN string to search for
ldb_respointer on pointer to the LDB message returned by the function
Returns
MAPI_E_SUCCESS on success, otherwise MAPI error

Referenced by emsabp_ab_container_by_id(), and emsabp_query().

_PUBLIC_ enum MAPISTATUS emsabp_search_legacyExchangeDN ( struct emsabp_context *  emsabp_ctx,
const char *  legacyDN,
struct ldb_message **  ldb_res,
bool *  pbUseConfPartition 
)

Search for a given AD record given its legacyDN parameter and return the associated LDB message.

Parameters
emsabp_ctxpointer to the EMSABP context
legacyDNpointer to the legacyDN attribute value to lookup
ldb_respointer on pointer to the LDB message returned by the function
pbUseConfPartitionpointer on boolean specifying whether the legacyExchangeDN was retrieved from the Configuration parition or not
Returns
MAPI_E_SUCCESS on success, otherwise MAPI error

Referenced by dcesrv_NspiDNToMId().

_PUBLIC_ enum MAPISTATUS emsabp_set_EphemeralEntryID ( struct emsabp_context *  emsabp_ctx,
uint32_t  DisplayType,
uint32_t  MId,
struct EphemeralEntryID ephEntryID 
)

Build an EphemeralEntryID structure

Parameters
emsabp_ctxpointer to the EMSABP context
DisplayTypethe AB object display type
MIdthe MId value
ephEntryIDpointer to the EphemeralEntryID returned by the function
Returns
MAPI_E_SUCCESS on success, otherwise MAPI_E_NOT_ENOUGH_RESOURCES or MAPI_E_CORRUPT_STORE

Referenced by emsabp_query().

_PUBLIC_ enum MAPISTATUS emsabp_set_PermanentEntryID ( struct emsabp_context *  emsabp_ctx,
uint32_t  DisplayType,
struct ldb_message *  msg,
struct PermanentEntryID permEntryID 
)

Build a PermanentEntryID structure

Parameters
emsabp_ctxpointer to the EMSABP context
DisplayTypethe AB object display type
msgpointer to the LDB message
permEntryIDpointer to the PermanentEntryID returned by the function
Note
This function only covers DT_CONTAINER AddressBook objects. It should be extended in the future to support more containers.
Returns
MAPI_E_SUCCESS on success, otherwise MAPI_E_NOT_ENOUGH_RESOURCES or MAPI_E_CORRUPT_STORE

Referenced by emsabp_get_HierarchyTable(), and emsabp_query().

_PUBLIC_ enum MAPISTATUS emsabp_table_fetch_attrs ( TALLOC_CTX *  mem_ctx,
struct emsabp_context *  emsabp_ctx,
struct PropertyRow_r *  aRow,
uint32_t  dwFlags,
struct PermanentEntryID permEntryID,
struct PermanentEntryID parentPermEntryID,
struct ldb_message *  msg,
bool  child 
)

Builds the SRow array entry for the specified table record.

Parameters
mem_ctxpointer to the memory context
emsabp_ctxpointer to the EMSABP context
aRowpointer to the SRow structure where results will be stored
dwFlagsflags controlling whether strings should be unicode encoded or not
permEntryIDpointer to the current record Permanent EntryID
parentPermEntryIDpointer to the parent record Permanent EntryID
msgpointer to the LDB message for current record
childboolean value specifying whether current record is root or child within containers hierarchy
Returns
MAPI_E_SUCCESS on success, otherwise MAPI error

References emsabp_PermanentEntryID_to_Binary_r(), emsabp_tdb_fetch_MId(), and emsabp_tdb_insert().

Referenced by emsabp_get_HierarchyTable().

_PUBLIC_ bool emsabp_verify_codepage ( struct emsabp_context *  emsabp_ctx,
uint32_t  CodePage 
)

Check if the provided codepage is correct

Parameters
emsabp_ctxpointer to the EMSABP context
CodePagethe codepage identifier
Note
The prototype is currently incorrect, but we are looking for a better way to check codepage, maybe within AD. At the moment this function is just a wrapper over libmapi valid_codepage function.
Returns
true on success, otherwise false

Referenced by dcesrv_NspiBind().

_PUBLIC_ bool emsabp_verify_user ( struct dcesrv_call_state *  dce_call,
struct emsabp_context *  emsabp_ctx 
)

Check if the authenticated user belongs to the Exchange organization

Parameters
dce_callpointer to the session context
emsabp_ctxpointer to the EMSABP context
Returns
true on success, otherwise false

References emsabp_get_account_info().

Referenced by dcesrv_NspiBind().


Creative Commons License
Creative Commons Attribution icon Creative Commons Share Alike icon
This content is licensed under the Creative Commons
Attribution ShareAlike License v. 3.0:
http://creativecommons.org/licenses/by-sa/3.0/

openchange-2.0/apidocs/html/mapiproxy/emsabp__property_8c.html000066400000000000000000000176211223057412600247430ustar00rootroot00000000000000 MAPIProxy 2.0 API Documentation
emsabp_property.c File Reference

Property Tag to AD attributes mapping. More...

#include "dcesrv_exchange_nsp.h"

Functions

_PUBLIC_ const char * emsabp_property_get_attribute (uint32_t ulPropTag)
_PUBLIC_ const char * emsabp_property_get_ref_attr (uint32_t ulPropTag)
_PUBLIC_ uint32_t emsabp_property_get_ulPropTag (const char *attribute)
_PUBLIC_ int emsabp_property_is_ref (uint32_t ulPropTag)

Detailed Description

Property Tag to AD attributes mapping.

Function Documentation

_PUBLIC_ const char* emsabp_property_get_attribute ( uint32_t  ulPropTag)

Return the AD attribute name associated to a property tag

Parameters
ulPropTagthe property tag to lookup
Returns
valid pointer to the attribute name on success, otherwise NULL

Referenced by emsabp_query(), and emsabp_search().

_PUBLIC_ const char* emsabp_property_get_ref_attr ( uint32_t  ulPropTag)

Returns the reference attr for a given attribute

Parameters
ulPropTagproperty tag to lookup
Returns
pointer to a valid reference attribute on success, otherwise NULL

Referenced by emsabp_query().

_PUBLIC_ uint32_t emsabp_property_get_ulPropTag ( const char *  attribute)

Return the property tag associated to AD attribute name

Parameters
attributethe AD attribute name to lookup
Returns
property tag value on success, otherwise PT_ERROR
_PUBLIC_ int emsabp_property_is_ref ( uint32_t  ulPropTag)

Returns whether the given attribute's value references another AD record

Parameters
ulPropTagthe property tag to lookup
Returns
1 if the attribute is a reference, 0 if not and -1 if an error occurred.

Referenced by emsabp_query().


Creative Commons License
Creative Commons Attribution icon Creative Commons Share Alike icon
This content is licensed under the Creative Commons
Attribution ShareAlike License v. 3.0:
http://creativecommons.org/licenses/by-sa/3.0/

openchange-2.0/apidocs/html/mapiproxy/emsabp__tdb_8c.html000066400000000000000000000427201223057412600236260ustar00rootroot00000000000000 MAPIProxy 2.0 API Documentation
emsabp_tdb.c File Reference

EMSABP TDB database API. More...

#include "mapiproxy/dcesrv_mapiproxy.h"
#include "dcesrv_exchange_nsp.h"
#include <util/debug.h>

Functions

_PUBLIC_ enum MAPISTATUS emsabp_tdb_close (TDB_CONTEXT *tdb_ctx)
_PUBLIC_ enum MAPISTATUS emsabp_tdb_fetch (TDB_CONTEXT *tdb_ctx, const char *keyname, TDB_DATA *result)
_PUBLIC_ enum MAPISTATUS emsabp_tdb_fetch_dn_from_MId (TALLOC_CTX *mem_ctx, TDB_CONTEXT *tdb_ctx, uint32_t MId, char **dn)
_PUBLIC_ enum MAPISTATUS emsabp_tdb_fetch_MId (TDB_CONTEXT *tdb_ctx, const char *keyname, uint32_t *MId)
_PUBLIC_ TDB_CONTEXT * emsabp_tdb_init (TALLOC_CTX *mem_ctx, struct loadparm_context *lp_ctx)
_PUBLIC_ TDB_CONTEXT * emsabp_tdb_init_tmp (TALLOC_CTX *mem_ctx)
_PUBLIC_ enum MAPISTATUS emsabp_tdb_insert (TDB_CONTEXT *tdb_ctx, const char *keyname)
_PUBLIC_ bool emsabp_tdb_lookup_MId (TDB_CONTEXT *tdb_ctx, uint32_t MId)

Detailed Description

EMSABP TDB database API.

Function Documentation

_PUBLIC_ enum MAPISTATUS emsabp_tdb_close ( TDB_CONTEXT *  tdb_ctx)

Close EMSABP TDB database

Returns
MAPI_E_SUCCESS on success, otherwise MAPI_E_INVALID_PARAMETER
_PUBLIC_ enum MAPISTATUS emsabp_tdb_fetch ( TDB_CONTEXT *  tdb_ctx,
const char *  keyname,
TDB_DATA *  result 
)

Fetch an element within a TDB database given its key

Parameters
tdb_ctxpointer to the EMSABP TDB context
keynamepointer to the TDB key to fetch
resultpointer on TDB results
Returns
MAPI_E_SUCCESS on success, otherwise MAPI_E_NOT_FOUND

Referenced by emsabp_tdb_init(), and emsabp_tdb_insert().

_PUBLIC_ enum MAPISTATUS emsabp_tdb_fetch_dn_from_MId ( TALLOC_CTX *  mem_ctx,
TDB_CONTEXT *  tdb_ctx,
uint32_t  MId,
char **  dn 
)

Traverse the EMSABP TDB and fetch the DN associated with the MId

Parameters
mem_ctxpointer to the memory context
tdb_ctxpointer to the EMSABP TDB context
MIdMID to search
dnpointer on pointer to the dn to return
Returns
MAPI_E_SUCCESS on success, otherwise false

Referenced by emsabp_ab_container_by_id(), and emsabp_fetch_attrs().

_PUBLIC_ enum MAPISTATUS emsabp_tdb_fetch_MId ( TDB_CONTEXT *  tdb_ctx,
const char *  keyname,
uint32_t *  MId 
)

Retrieve the Minimal EntryID associated to a given DN

Parameters
tdb_ctxpointer to the EMSABP TDB context
keynamepointer to the TDB key to search for
MIdpointer on the integer the function returns
Returns
MAPI_E_SUCCESS on success, otherwise MAPI error

Referenced by dcesrv_NspiDNToMId(), emsabp_fetch_attrs_from_msg(), emsabp_search(), and emsabp_table_fetch_attrs().

_PUBLIC_ TDB_CONTEXT* emsabp_tdb_init ( TALLOC_CTX *  mem_ctx,
struct loadparm_context *  lp_ctx 
)

Open EMSABP TDB database

Parameters
mem_ctxpointer to the memory context
lp_ctxpointer to the loadparm context
Returns
MAPI_E_SUCCESS on success, otherwise MAPI error

References emsabp_tdb_fetch(), and mapiproxy_server_emsabp_tdb_init().

Referenced by dcesrv_exchange_nsp_init().

_PUBLIC_ TDB_CONTEXT* emsabp_tdb_init_tmp ( TALLOC_CTX *  mem_ctx)

Initialize a temporary (on-memory) TDB database. This database is used to store temporary MId used within a session lifetime.

Parameters
mem_ctxpointer to the memory context
Returns
Allocated TDB context on success, otherwise NULL

Referenced by emsabp_init().

_PUBLIC_ enum MAPISTATUS emsabp_tdb_insert ( TDB_CONTEXT *  tdb_ctx,
const char *  keyname 
)

Insert an element into TDB database

Parameters
tdb_ctxpointer to the EMSABP TDB context
keynamepointer to the TDB key name string
Returns
MAPI_E_SUCCESS on success, otherwise MAPI error

References emsabp_tdb_fetch().

Referenced by dcesrv_NspiDNToMId(), emsabp_fetch_attrs_from_msg(), emsabp_search(), and emsabp_table_fetch_attrs().

_PUBLIC_ bool emsabp_tdb_lookup_MId ( TDB_CONTEXT *  tdb_ctx,
uint32_t  MId 
)

Traverse the EMSABP TDB database and look for the input MId

Parameters
tdb_ctxpointer to the EMSABP TDB context
MIdMID to lookup
Returns
true on success, otherwise false

Referenced by dcesrv_NspiGetProps(), dcesrv_NspiQueryRows(), dcesrv_NspiSeekEntries(), dcesrv_NspiUpdateStat(), and emsabp_search().


Creative Commons License
Creative Commons Attribution icon Creative Commons Share Alike icon
This content is licensed under the Creative Commons
Attribution ShareAlike License v. 3.0:
http://creativecommons.org/licenses/by-sa/3.0/

openchange-2.0/apidocs/html/mapiproxy/emsmdbp_8c.html000066400000000000000000000425461223057412600230240ustar00rootroot00000000000000 MAPIProxy 2.0 API Documentation
emsmdbp.c File Reference

EMSMDB Provider implementation. More...

#include "mapiproxy/dcesrv_mapiproxy.h"
#include "dcesrv_exchange_emsmdb.h"
#include "mapiproxy/libmapiserver/libmapiserver.h"
#include <ldap_ndr.h>

Functions

_PUBLIC_ struct emsmdbp_context * emsmdbp_init (struct loadparm_context *lp_ctx, const char *username, void *ldb_ctx)
static int emsmdbp_mapi_handles_destructor (void *data)
static int emsmdbp_mapi_store_destructor (void *data)
_PUBLIC_ void * emsmdbp_openchange_ldb_init (struct loadparm_context *lp_ctx)
_PUBLIC_ enum MAPISTATUS emsmdbp_resolve_recipient (TALLOC_CTX *mem_ctx, struct emsmdbp_context *emsmdbp_ctx, char *recipient, struct mapi_SPropTagArray *properties, struct RecipientRow *row)
_PUBLIC_ bool emsmdbp_verify_user (struct dcesrv_call_state *dce_call, struct emsmdbp_context *emsmdbp_ctx)
_PUBLIC_ bool emsmdbp_verify_userdn (struct dcesrv_call_state *dce_call, struct emsmdbp_context *emsmdbp_ctx, const char *legacyExchangeDN, struct ldb_message **msg)

Detailed Description

EMSMDB Provider implementation.

Function Documentation

_PUBLIC_ struct emsmdbp_context* emsmdbp_init ( struct loadparm_context *  lp_ctx,
const char *  username,
void *  ldb_ctx 
)
read

Initialize the EMSMDBP context and open connections to Samba databases.

Parameters
lp_ctxpointer to the loadparm_context
usernameaccount name for current session
ldb_ctxpointer to the openchange dispatcher ldb database
Returns
Allocated emsmdbp_context pointer on success, otherwise NULL

References emsmdbp_mapi_handles_destructor(), emsmdbp_mapi_store_destructor(), and mapi_handles_init().

Referenced by dcesrv_EcDoConnect(), and dcesrv_EcDoConnectEx().

static int emsmdbp_mapi_handles_destructor ( void *  data)
static

Release the MAPI handles context used by EMSMDB provider context

Parameters
datapointer on data to destroy
Returns
0 on success, otherwise -1

References mapi_handles_release().

Referenced by emsmdbp_init().

static int emsmdbp_mapi_store_destructor ( void *  data)
static

Release the MAPISTORE context used by EMSMDB provider context

Parameters
datapointer on data to destroy
Returns
0 on success, otherwise -1

Referenced by emsmdbp_init().

_PUBLIC_ void* emsmdbp_openchange_ldb_init ( struct loadparm_context *  lp_ctx)

Open openchange.ldb database

Parameters
lp_ctxpointer on the loadparm_context
Note
This function is just a wrapper over mapiproxy_server_openchange_ldb_init
Returns
Allocated LDB context on success, otherwise NULL

References mapiproxy_server_openchange_ldb_init().

Referenced by dcesrv_exchange_emsmdb_init().

_PUBLIC_ enum MAPISTATUS emsmdbp_resolve_recipient ( TALLOC_CTX *  mem_ctx,
struct emsmdbp_context *  emsmdbp_ctx,
char *  recipient,
struct mapi_SPropTagArray *  properties,
struct RecipientRow *  row 
)

Resolve a recipient and build the associated RecipientRow structure

Parameters
mem_ctxpointer to the memory context
emsmdbp_ctxpointer to the EMSMDBP context
recipientpointer to the recipient string
propertiesarray of properties to lookup for a recipient
rowthe RecipientRow to fill in
Note
This is a very preliminary implementation with a lot of pseudo-hardcoded things. Lot of work is required to make this function generic and to cover all different cases
Returns
Allocated RecipientRow on success, otherwise NULL

References libmapiserver_push_property().

_PUBLIC_ bool emsmdbp_verify_user ( struct dcesrv_call_state *  dce_call,
struct emsmdbp_context *  emsmdbp_ctx 
)

Check if the authenticated user belongs to the Exchange organization and is enabled

Parameters
dce_callpointer to the session context
emsmdbp_ctxpointer to the EMSMDBP context
Returns
true on success, otherwise false

References openchangedb_get_MailboxReplica().

Referenced by dcesrv_EcDoConnect(), and dcesrv_EcDoConnectEx().

_PUBLIC_ bool emsmdbp_verify_userdn ( struct dcesrv_call_state *  dce_call,
struct emsmdbp_context *  emsmdbp_ctx,
const char *  legacyExchangeDN,
struct ldb_message **  msg 
)

Check if the user record which legacyExchangeDN points to belongs to the Exchange organization and is enabled

Parameters
dce_callpointer to the session context
emsmdbp_ctxpointer to the EMSMDBP context
legacyExchangeDNpointer to the userDN to lookup
msgpointer on pointer to the LDB message matching the record
Note
Users can set msg to NULL if they do not intend to retrieve the message
Returns
true on success, otherwise false

Referenced by dcesrv_EcDoConnect(), and dcesrv_EcDoConnectEx().


Creative Commons License
Creative Commons Attribution icon Creative Commons Share Alike icon
This content is licensed under the Creative Commons
Attribution ShareAlike License v. 3.0:
http://creativecommons.org/licenses/by-sa/3.0/

openchange-2.0/apidocs/html/mapiproxy/emsmdbp__object_8c.html000066400000000000000000001376741223057412600245200ustar00rootroot00000000000000 MAPIProxy 2.0 API Documentation
emsmdbp_object.c File Reference

Server-side specific objects init/release routines. More...

#include <ctype.h>
#include "mapiproxy/dcesrv_mapiproxy.h"
#include "mapiproxy/libmapiproxy/libmapiproxy.h"
#include "mapiproxy/libmapiserver/libmapiserver.h"
#include "mapiproxy/libmapistore/mapistore_nameid.h"
#include "libmapi/property_tags.h"
#include "libmapi/property_altnames.h"
#include "dcesrv_exchange_emsmdb.h"

Functions

_PUBLIC_ uint32_t emsmdbp_get_contextID (struct emsmdbp_object *object)
char * emsmdbp_get_owner (struct emsmdbp_object *object)
bool emsmdbp_is_mailboxstore (struct emsmdbp_object *object)
bool emsmdbp_is_mapistore (struct emsmdbp_object *object)
_PUBLIC_ struct emsmdbp_object * emsmdbp_object_attachment_init (TALLOC_CTX *mem_ctx, struct emsmdbp_context *emsmdbp_ctx, uint64_t messageID, struct emsmdbp_object *parent)
_PUBLIC_ int emsmdbp_object_copy_properties (struct emsmdbp_context *emsmdbp_ctx, struct emsmdbp_object *source_object, struct emsmdbp_object *target_object, struct SPropTagArray *excluded_properties, bool deep_copy)
static int emsmdbp_object_destructor (void *data)
_PUBLIC_ struct emsmdbp_object * emsmdbp_object_folder_init (TALLOC_CTX *mem_ctx, struct emsmdbp_context *emsmdbp_ctx, uint64_t folderID, struct emsmdbp_object *parent_object)
_PUBLIC_ struct emsmdbp_object * emsmdbp_object_ftcontext_init (TALLOC_CTX *mem_ctx, struct emsmdbp_context *emsmdbp_ctx, struct emsmdbp_object *parent)
_PUBLIC_ struct emsmdbp_object * emsmdbp_object_init (TALLOC_CTX *mem_ctx, struct emsmdbp_context *emsmdbp_ctx, struct emsmdbp_object *parent_object)
_PUBLIC_ struct emsmdbp_object * emsmdbp_object_mailbox_init (TALLOC_CTX *mem_ctx, struct emsmdbp_context *emsmdbp_ctx, const char *essDN, bool mailboxstore)
_PUBLIC_ struct emsmdbp_object * emsmdbp_object_message_init (TALLOC_CTX *mem_ctx, struct emsmdbp_context *emsmdbp_ctx, uint64_t messageID, struct emsmdbp_object *parent)
_PUBLIC_ enum mapistore_error emsmdbp_object_open_folder_by_fid (TALLOC_CTX *mem_ctx, struct emsmdbp_context *emsmdbp_ctx, struct emsmdbp_object *context_object, uint64_t fid, struct emsmdbp_object **folder_object_p)
_PUBLIC_ struct emsmdbp_object * emsmdbp_object_stream_init (TALLOC_CTX *mem_ctx, struct emsmdbp_context *emsmdbp_ctx, struct emsmdbp_object *parent)
_PUBLIC_ struct emsmdbp_object * emsmdbp_object_subscription_init (TALLOC_CTX *mem_ctx, struct emsmdbp_context *emsmdbp_ctx, struct emsmdbp_object *parent)
_PUBLIC_ struct emsmdbp_object * emsmdbp_object_synccontext_init (TALLOC_CTX *mem_ctx, struct emsmdbp_context *emsmdbp_ctx, struct emsmdbp_object *parent_object)
_PUBLIC_ struct emsmdbp_object * emsmdbp_object_table_init (TALLOC_CTX *mem_ctx, struct emsmdbp_context *emsmdbp_ctx, struct emsmdbp_object *parent)

Detailed Description

Server-side specific objects init/release routines.

Function Documentation

char* emsmdbp_get_owner ( struct emsmdbp_object *  object)

Convenience function to determine the owner of an object

Parameters
objectpointer to the emsmdp object
Returns
true if parent is within mailbox store, otherwise false

Referenced by EcDoRpc_RopDeleteMessages(), EcDoRpc_RopSaveChangesMessage(), EcDoRpc_RopSubmitMessage(), EcDoRpc_RopSyncGetTransferState(), EcDoRpc_RopSyncImportDeletes(), EcDoRpc_RopSyncImportHierarchyChange(), EcDoRpc_RopSyncImportMessageChange(), and EcDoRpc_RopSyncImportReadStateChanges().

bool emsmdbp_is_mailboxstore ( struct emsmdbp_object *  object)

Convenient function to determine whether specified mapi_handles refers to object within mailbox or public folders store.

Parameters
objectpointer to the emsmdp object
Returns
true if parent is within mailbox store, otherwise false
_PUBLIC_ struct emsmdbp_object* emsmdbp_object_attachment_init ( TALLOC_CTX *  mem_ctx,
struct emsmdbp_context *  emsmdbp_ctx,
uint64_t  messageID,
struct emsmdbp_object *  parent 
)
read

Initialize a attachment object

Parameters
mem_ctxpointer to the memory context
emsmdbp_ctxpointer to the emsmdb provider cotnext
folderIDthe folder identifier
messageIDthe message identifier
parentemsmdbp object of the parent

References emsmdbp_object_init().

Referenced by EcDoRpc_RopCreateAttach(), and EcDoRpc_RopOpenAttach().

_PUBLIC_ int emsmdbp_object_copy_properties ( struct emsmdbp_context *  emsmdbp_ctx,
struct emsmdbp_object *  source_object,
struct emsmdbp_object *  target_object,
struct SPropTagArray *  excluded_properties,
bool  deep_copy 
)

Copy properties from an object to another object

Parameters
emsmdbp_ctxpointer to the emsmdb provider context
source_objectpointer to the source object
target_objectpointer to the target object
excluded_propertiespointer to a SPropTagArray listing properties that must not be copied
deep_copyindicates whether subobjects must be copied
Returns
Allocated emsmdbp object on success, otherwise NULL

References emsmdbp_is_mapistore().

Referenced by EcDoRpc_RopCopyTo().

static int emsmdbp_object_destructor ( void *  data)
static

talloc destructor for emsmdbp_objects

Parameters
datageneric pointer on data
Returns
0 on success, otherwise -1

References emsmdbp_get_contextID(), and emsmdbp_is_mapistore().

Referenced by emsmdbp_object_init().

_PUBLIC_ struct emsmdbp_object* emsmdbp_object_folder_init ( TALLOC_CTX *  mem_ctx,
struct emsmdbp_context *  emsmdbp_ctx,
uint64_t  folderID,
struct emsmdbp_object *  parent_object 
)
read

Initialize a folder object

Parameters
mem_ctxpointer to the memory context
emsmdbp_ctxpointer to the emsmdb provider context
folderIDthe folder identifier
parentemsmdbp object of the parent folder for this folder
Returns
Allocated emsmdbp object on success, otherwise NULL

References emsmdbp_object_init().

Referenced by emsmdbp_object_open_folder_by_fid().

_PUBLIC_ struct emsmdbp_object* emsmdbp_object_ftcontext_init ( TALLOC_CTX *  mem_ctx,
struct emsmdbp_context *  emsmdbp_ctx,
struct emsmdbp_object *  parent 
)
read

Initialize a ftcontext object

Parameters
mem_ctxpointer to the memory context
emsmdbp_ctxpointer to the emsmdb provider cotnext
whole_storewhether the subscription applies to the specified change on the entire store or stricly on the specified folder/message
folderIDthe folder identifier
messageIDthe message identifier
parentemsmdbp object of the parent

References emsmdbp_object_init().

Referenced by EcDoRpc_RopFastTransferSourceCopyTo(), and EcDoRpc_RopSyncGetTransferState().

_PUBLIC_ struct emsmdbp_object* emsmdbp_object_init ( TALLOC_CTX *  mem_ctx,
struct emsmdbp_context *  emsmdbp_ctx,
struct emsmdbp_object *  parent_object 
)
read

Initialize an emsmdbp_object

Parameters
mem_ctxpointer to the memory context
emsmdbp_ctxpointer to the emsmdb provider context
Returns
Allocated emsmdbp object on success, otherwise NULL

References emsmdbp_object_destructor().

Referenced by emsmdbp_object_attachment_init(), emsmdbp_object_folder_init(), emsmdbp_object_ftcontext_init(), emsmdbp_object_mailbox_init(), emsmdbp_object_message_init(), emsmdbp_object_stream_init(), emsmdbp_object_subscription_init(), emsmdbp_object_synccontext_init(), and emsmdbp_object_table_init().

_PUBLIC_ struct emsmdbp_object* emsmdbp_object_mailbox_init ( TALLOC_CTX *  mem_ctx,
struct emsmdbp_context *  emsmdbp_ctx,
const char *  essDN,
bool  mailboxstore 
)
read

Initialize a mailbox object

Parameters
mem_ctxpointer to the memory context
emsmdbp_ctxpointer to the emsmdb provider context
requestpointer to the Logon MAPI request
mailboxstoreboolean which specifies whether the mailbox object is a PF store or a private mailbox store
Returns
Allocated emsmdbp object on success, otherwise NULL

References emsmdbp_object_init(), openchangedb_get_PublicFolderID(), and openchangedb_get_SystemFolderID().

Referenced by EcDoRpc_RopLogon().

_PUBLIC_ struct emsmdbp_object* emsmdbp_object_message_init ( TALLOC_CTX *  mem_ctx,
struct emsmdbp_context *  emsmdbp_ctx,
uint64_t  messageID,
struct emsmdbp_object *  parent 
)
read

Initialize a message object

Parameters
mem_ctxpointer to the memory context
emsmdbp_ctxpointer to the emsmdb provider context
messageIDthe message identifier
parentemsmdbp object of the parent
Returns
Allocated emsmdbp object on success, otherwise NULL

References emsmdbp_object_init().

Referenced by EcDoRpc_RopCreateMessage(), EcDoRpc_RopOpenEmbeddedMessage(), and EcDoRpc_RopSyncImportMessageChange().

_PUBLIC_ enum mapistore_error emsmdbp_object_open_folder_by_fid ( TALLOC_CTX *  mem_ctx,
struct emsmdbp_context *  emsmdbp_ctx,
struct emsmdbp_object *  context_object,
uint64_t  fid,
struct emsmdbp_object **  folder_object_p 
)

Return the folder object associated to specified folder identified

Parameters
mem_ctxpointer to the memory context
emsmdbp_ctxpointer to the emsmdbp context
context_objectpointer to current context object
fidpointer to the Folder Identifier to lookup
Returns
Valid emsmdbp object structure on success, otherwise NULL

References emsmdbp_object_folder_init().

Referenced by EcDoRpc_RopCreateFolder(), EcDoRpc_RopCreateMessage(), EcDoRpc_RopOpenFolder(), and EcDoRpc_RopSyncImportHierarchyChange().

_PUBLIC_ struct emsmdbp_object* emsmdbp_object_stream_init ( TALLOC_CTX *  mem_ctx,
struct emsmdbp_context *  emsmdbp_ctx,
struct emsmdbp_object *  parent 
)
read

Initialize a stream object

Parameters
mem_ctxpointer to the memory context
emsmdbp_ctxpointer to the emsmdb provider cotnext
propertythe stream property identifier
parentemsmdbp object of the parent

References emsmdbp_object_init().

Referenced by EcDoRpc_RopOpenStream().

_PUBLIC_ struct emsmdbp_object* emsmdbp_object_subscription_init ( TALLOC_CTX *  mem_ctx,
struct emsmdbp_context *  emsmdbp_ctx,
struct emsmdbp_object *  parent 
)
read

Initialize a notification subscription object

Parameters
mem_ctxpointer to the memory context
emsmdbp_ctxpointer to the emsmdb provider cotnext
whole_storewhether the subscription applies to the specified change on the entire store or stricly on the specified folder/message
folderIDthe folder identifier
messageIDthe message identifier
parentemsmdbp object of the parent

References emsmdbp_object_init().

Referenced by EcDoRpc_RopRegisterNotification().

_PUBLIC_ struct emsmdbp_object* emsmdbp_object_synccontext_init ( TALLOC_CTX *  mem_ctx,
struct emsmdbp_context *  emsmdbp_ctx,
struct emsmdbp_object *  parent_object 
)
read

Initialize a synccontext object

Parameters
mem_ctxpointer to the memory context
emsmdbp_ctxpointer to the emsmdb provider cotnext
whole_storewhether the subscription applies to the specified change on the entire store or stricly on the specified folder/message
folderIDthe folder identifier
messageIDthe message identifier
parentemsmdbp object of the parent

References emsmdbp_object_init(), and openchangedb_get_MailboxReplica().

Referenced by EcDoRpc_RopSyncConfigure(), and EcDoRpc_RopSyncOpenCollector().

_PUBLIC_ struct emsmdbp_object* emsmdbp_object_table_init ( TALLOC_CTX *  mem_ctx,
struct emsmdbp_context *  emsmdbp_ctx,
struct emsmdbp_object *  parent 
)
read

Initialize a table object

Parameters
mem_ctxpointer to the memory context
emsmdbp_ctxpointer to the emsmdb provider context
parentemsmdbp object of the parent
Returns
Allocated emsmdbp object on success, otherwise NULL

References emsmdbp_object_init().

Referenced by EcDoRpc_RopGetPermissionsTable().


Creative Commons License
Creative Commons Attribution icon Creative Commons Share Alike icon
This content is licensed under the Creative Commons
Attribution ShareAlike License v. 3.0:
http://creativecommons.org/licenses/by-sa/3.0/

openchange-2.0/apidocs/html/mapiproxy/emsmdbp__provisioning_8c.html000066400000000000000000000135431223057412600257640ustar00rootroot00000000000000 MAPIProxy 2.0 API Documentation
emsmdbp_provisioning.c File Reference

Account provisioning. More...

#include <ctype.h>
#include <string.h>
#include "dcesrv_exchange_emsmdb.h"
#include <gen_ndr/ndr_property.h>

Functions

_PUBLIC_ enum MAPISTATUS emsmdbp_mailbox_provision (struct emsmdbp_context *emsmdbp_ctx, const char *username)

Detailed Description

Account provisioning.

Function Documentation


Creative Commons License
Creative Commons Attribution icon Creative Commons Share Alike icon
This content is licensed under the Creative Commons
Attribution ShareAlike License v. 3.0:
http://creativecommons.org/licenses/by-sa/3.0/

openchange-2.0/apidocs/html/mapiproxy/entryid_8c.html000066400000000000000000000166751223057412600230570ustar00rootroot00000000000000 MAPIProxy 2.0 API Documentation
entryid.c File Reference

EntryID convenient routines. More...

#include "mapiproxy/dcesrv_mapiproxy.h"
#include "libmapiproxy.h"
#include "libmapi/libmapi.h"
#include "libmapi/libmapi_private.h"

Functions

enum MAPISTATUS entryid_set_AB_EntryID (TALLOC_CTX *mem_ctx, const char *legacyExchangeDN, struct SBinary_short *bin)
_PUBLIC_ enum MAPISTATUS entryid_set_folder_EntryID (TALLOC_CTX *mem_ctx, struct GUID *MailboxGuid, struct GUID *ReplGuid, uint16_t FolderType, uint64_t fid, struct Binary_r **rbin)

Detailed Description

EntryID convenient routines.

Function Documentation

enum MAPISTATUS entryid_set_AB_EntryID ( TALLOC_CTX *  mem_ctx,
const char *  legacyExchangeDN,
struct SBinary_short *  bin 
)

Build an Address Book EntryID from a legacyExchangeDN

Parameters
mem_ctxpointer to the memory context
legacyExchangeDNthe string to copy into the binary blob
binthe binary blob where the function stores results

Referenced by EcDoRpc_RopCreateMessage().

_PUBLIC_ enum MAPISTATUS entryid_set_folder_EntryID ( TALLOC_CTX *  mem_ctx,
struct GUID *  MailboxGuid,
struct GUID *  ReplGuid,
uint16_t  FolderType,
uint64_t  fid,
struct Binary_r **  rbin 
)

Build a folder EntryID

Parameters
mem_ctxpointer to the memory context
MailboxGuidpointer to the Mailbox Guid
ReplGuidpointer to the Replica Guid
FolderTypethe type of folder
fidthe folder identifier
rbinthe Binary_r structure where the function stores results
Returns
MAPI_E_SUCCESS on success, otherwise MAPI_E_INVALID_PARAMETER

Creative Commons License
Creative Commons Attribution icon Creative Commons Share Alike icon
This content is licensed under the Creative Commons
Attribution ShareAlike License v. 3.0:
http://creativecommons.org/licenses/by-sa/3.0/

openchange-2.0/apidocs/html/mapiproxy/files.html000066400000000000000000000667401223057412600221070ustar00rootroot00000000000000 MAPIProxy 2.0 API Documentation
File List
Here is a list of all documented files with brief descriptions:
[detail level 12345]
\-mapiproxy
 o-libmapiproxy
 |o*dcesrv_mapiproxy_module.cMapiproxy modules management
 |o*dcesrv_mapiproxy_server.cMapiproxy server modules management
 |o*dcesrv_mapiproxy_session.cSession API for mapiproxy modules
 |o*entryid.cEntryID convenient routines
 |o*mapi_handles.cAPI for MAPI handles management
 |o*openchangedb.cOpenChange Dispatcher database routines
 |o*openchangedb_message.cOpenChange Dispatcher database message routines
 |\*openchangedb_table.cOpenChange Dispatcher database table routines
 o-libmapiserver
 |o*libmapiserver_oxcdata.cOXCDATA Data Structures
 |o*libmapiserver_oxcfold.cOXCFOLD ROP Response size calculations
 |o*libmapiserver_oxcfxics.cOXCFXICS ROP Response size calculations
 |o*libmapiserver_oxcmsg.cOXCMSG ROP Response size calculations
 |o*libmapiserver_oxcnotif.cOXCNOTIF ROP Response size calculations
 |o*libmapiserver_oxcprpt.cOXCPRPT ROP Response size calculations
 |o*libmapiserver_oxcstor.cOXCSTOR ROP Response size calculations
 |o*libmapiserver_oxctabl.cOXCTABL ROP Response size calculations
 |o*libmapiserver_oxomsg.cOXOMSG ROP Response size calculations
 |\*libmapiserver_oxorule.cOXORULE ROP Response size calculations
 o-modules
 |o*mpm_cache.cCache messages and attachments so we can reduce WAN traffic
 |o*mpm_cache_ldb.cLDB routines for the cache module
 |o*mpm_cache_stream.cStorage routines for the cache module
 |o*mpm_downgrade.cDowngrade EMSMDB protocol version EcDoConnect/EcDoRpc
 |\*mpm_pack.cPack/Unpack specified MAPI calls into/from a custom MAPI call
 o-servers
 |\-default
 | o-emsmdb
 | |o*dcesrv_exchange_emsmdb.cOpenChange EMSMDB Server implementation
 | |o*emsmdbp.cEMSMDB Provider implementation
 | |o*emsmdbp_object.cServer-side specific objects init/release routines
 | |o*emsmdbp_provisioning.cAccount provisioning
 | |o*oxcfold.cFolder object routines and Rops
 | |o*oxcfxics.cFastTransfer and ICS object routines and Rops
 | |o*oxcmsg.cMessage and Attachment object routines and Rops
 | |o*oxcnotif.cCore Notifications routines and Rops
 | |o*oxcperm.cAccess and Operation Permissions Rops
 | |o*oxcprpt.cProperty and Stream Object routines and Rops
 | |o*oxcstor.cServer-side store objects routines and Rops
 | |o*oxctabl.cTable object routines and Rops
 | |\*oxomsg.cServer-side message routines and Rops
 | o-nspi
 | |o*dcesrv_exchange_nsp.cOpenChange NSPI Server implementation
 | |o*emsabp.cAddress Book Provider implementation
 | |o*emsabp_property.cProperty Tag to AD attributes mapping
 | |\*emsabp_tdb.cEMSABP TDB database API
 | \-rfr
 |  \*dcesrv_exchange_ds_rfr.cOpenChange RFR Server implementation
 o*dcesrv_mapiproxy.cMapiproxy main file
 o*dcesrv_mapiproxy_nspi.cNSPI hook functions
 \*dcesrv_mapiproxy_rfr.cNSPI Referral hook functions

Creative Commons License
Creative Commons Attribution icon Creative Commons Share Alike icon
This content is licensed under the Creative Commons
Attribution ShareAlike License v. 3.0:
http://creativecommons.org/licenses/by-sa/3.0/

openchange-2.0/apidocs/html/mapiproxy/ftv2blank.png000066400000000000000000000001261223057412600225000ustar00rootroot00000000000000‰PNG  IHDRɪ|IDATxíݱðøScOx@ –¨y}IEND®B`‚openchange-2.0/apidocs/html/mapiproxy/ftv2cl.png000066400000000000000000000007051223057412600220120ustar00rootroot00000000000000‰PNG  IHDRÚ}\ˆŒIDATxíÝ;H#AÇño4Љႇ œ„K‰‡‚á ’ê,m„ØØ vÚžJ°²¹ÚÎþî‚§ XY ÅB|dr³cvo—˜Ä°Ý ù0Ã’™3ÿͤõ”Ëe×´¸Éõ¯1XÞ8Œ‰nQˆ88ööÖ§3*rbñ¯¢û-$¨‚þ´˜“P1Žè@Z…-# Ïú01ÑÏÎêÄ1HkKŸ w¶O@¥ªÈóñ!f§ñu˜åác÷;’sá×Bý[E´Añ±—Í\ß>°ùý¿ÏËÊÂ]–P€zØf| Íñ¯“+Ù´gð5…b  i5ümM³œ_æÍq,ÒcŽõèoÓd´ !¶äò©ô•,ôðÀ{¹¨µYß,€zTÍ8H]𤕘ï7¼»/òó8ËQæ !F€~6ãá?Y ÀA@ŨÁ.@ƒ¶TäÄYïŠËë±r‘µ8Ð*·é>€Šçÿ?€×þŸe[6«xÂIEND®B`‚openchange-2.0/apidocs/html/mapiproxy/ftv2doc.png000066400000000000000000000013521223057412600221600ustar00rootroot00000000000000‰PNG  IHDRÚ}\ˆ±IDATxíMOS[…Ÿžsúa?-XZ(PD4‚ AWbu`b 77wäHFÆCËÔÂÿà/`vo„ˆAPòq‹P @ ­ûÝè980 îà¤+»§Ýy×^ïZï9SW¹\83g‰3'°Nâçl¹¸_b¯p ïåûÆVÜÖ¡€Ÿ×"¬Ö†X€d]Ðà3“ÉÃÄÌ™xŸ ßMàœ[<çSPkvc—hÈ'…™˜^Åm™hØ7 `Û™¦ èÀåráq›‘œ¾!daeKŸþÆÕ˜:Ì*³_דâèi?I–eP*B7Ÿ¿åô!¹Ýgr6Ër6oKbëþãðôrI”ËTˆüªŒ¨xóö=›ù¢&‰(e+ßóÄkýÇ`ëÁÜb.“¸ÐW×w0¥°jÑzN™¬|©WEãµ¢a¯6[öX†AkÓù*/œ¨‰€ÉY­ ÿV’§–u²jÂ>1W *½·°PGŽzÿ¨/Eg{ ŸÇâaoŠÁVú:è¿™¤1$ôR§W,–ªà¨@ŠË56¾ÀÔÜ-¾,mê¸Î/æè¹– òr5¥T*S(Vf8ö9u’ Õ£w›ùóa=Í<{Ò¡UŒ÷r¯+ÉådDÏF$è°…£é¿`zþ»ÎúöN‘µÜ®0Q3£~_^Ëóâ¯N=ˆvpTà±LžT}ˆîkq†Òm<¼ÎÓ?Zh¿X£ï_þÝ¥[)ƒ `gêÃa_Ô*äÔ2`'=õ´Fÿ2EâÁPú ÷»›l=8‹Wv°%THqÉ¿<"¤ïG¾ÆxH{#ÆÖ«aÔJÕÞ‡—m‹„ çñKsÿàñVŠØ¡°·MâÒ^ TÁ– Ý›r¥ß½ømüÿ_™?ªWİ÷#uIEND®B`‚openchange-2.0/apidocs/html/mapiproxy/ftv2folderclosed.png000066400000000000000000000011501223057412600240540ustar00rootroot00000000000000‰PNG  IHDRÚ}\ˆ/IDATxí]MOÔ@~ÚúuØlp]ö¿#›Å]PYECˆ\9ù¼yÑß`ÖÄÿàÿÀÉxóâ¢C &=qÐÄ£—vZçv¶3m؃‡vžLûNç}Þ÷}Þ½ZA@n° OäNp ’xóþK°ññ€xÜj”°8sÑ€“ “€œ_¼[Âíæ§ïD'‚•yye+ø¼û 7#rNŸlïük* ¾0Ь_d«_(àñÖ±àôz=ñxõv§÷h©‰z¹€šØP-äóä’̪uý¼$»\DãJc—B4¯ãÝÖ.:£Ï-ÑÏß}µŠLEíºþ #—ûáºÀÏgN;BŠ€6ïýñ䬜…ö@’Ðåñp&™h>p9¤™EEά¨ÎÊ‘" u¥n€$R"?{¹<˜…ë…%PNtâ$‰ß¶±úá+^<é"§2 ªDq”q´\¬«Ò™a–Œ‘©Aÿ€"Ôµ ™êŸèP£}#Eàz{û.8i îp³ê(ADwD¦E<ê¬cE¦$ HdÊÄ ”.:Ù GŽ-`ŒL‚ý¾'¢‰Ä<¤CIª½;ÙÇTZd±i};>èôß‚z×;K×§8t ¤Ž q”:uvÿv•Ý›¬²ÙvEân{„M·FXg¼ÌfZÖ¨°¹‰*›ßÌß©±ù©:›j–YqèÜë#3çÏSøWøÿÿÑr'ø Ôùù‚ ©¡IEND®B`‚openchange-2.0/apidocs/html/mapiproxy/ftv2folderopen.png000066400000000000000000000011251223057412600235460ustar00rootroot00000000000000‰PNG  IHDRÚ}\ˆIDATxí]?oÓPÿ9iš4i°;ii“¶‰ZЉ‘‰ÀÀ7`bèÔÙ¬Øù,HìU'ô$*Tµ]‚T¡DPÚÄ6wÏ}‰;¡C; a¿ÓߟûÝïîž¼jAÀ­InSþ}€9H“ÓŽ|?íÁ÷ =_ÊÆŠ­†¥Àue*;¯YEäsYäæB¢Ÿ¿þÄ—£sÙ½½ÙŒ† É«›©ÀYÇq !GÇ¿v̇¹ÑØ®š °Œ‚ÔF¹}q¥b]÷7í·0)Úd›¾ÿð-èº}Pfä£ÖY{4™ÑÂ@}úæôñ2ÛüÔ—ñúåNŒI‚ÁǃcçÁº%£¬UаI³mc±ô˜å¼ÔÆüÈ>é¸xþt9Æ$µý OæVE*õU´Ì‚ç#ž×ˆ•ïûr@l$øPÿrHaaÇ¥ ²›dZ®rè‘ãqI„o¼øT\Ž,tªj2FAxv-LŸp׌p TÄI/ \¥sfí½; jViTƒèú¤o^cpÅü¼ûû»Ïb]”€¢¤<†aþÕœ²“ßÓ˜y“£§9:Œîù+À³€ñà,E žf³6éNˆÄE£KU}Ü^;¶ØnZ¢uß­US4— ѬëbížN¶.Úk¦ØjTÄöº%µªâ i¯VÄÊÝò§™ Èù¸)ùÿG€™òºJ@T x”IEND®B`‚openchange-2.0/apidocs/html/mapiproxy/ftv2lastnode.png000066400000000000000000000001261223057412600232220ustar00rootroot00000000000000‰PNG  IHDRɪ|IDATxíݱðøScOx@ –¨y}IEND®B`‚openchange-2.0/apidocs/html/mapiproxy/ftv2link.png000066400000000000000000000013521223057412600223500ustar00rootroot00000000000000‰PNG  IHDRÚ}\ˆ±IDATxíMOS[…Ÿžsúa?-XZ(PD4‚ AWbu`b 77wäHFÆCËÔÂÿà/`vo„ˆAPòq‹P @ ­ûÝè980 îà¤+»§Ýy×^ïZï9SW¹\83g‰3'°Nâçl¹¸_b¯p ïåûÆVÜÖ¡€Ÿ×"¬Ö†X€d]Ðà3“ÉÃÄÌ™xŸ ßMàœ[<çSPkvc—hÈ'…™˜^Åm™hØ7 `Û™¦ èÀåráq›‘œ¾!daeKŸþÆÕ˜:Ì*³_דâèi?I–eP*B7Ÿ¿åô!¹Ýgr6Ër6oKbëþãðôrI”ËTˆüªŒ¨xóö=›ù¢&‰(e+ßóÄkýÇ`ëÁÜb.“¸ÐW×w0¥°jÑzN™¬|©WEãµ¢a¯6[öX†AkÓù*/œ¨‰€ÉY­ ÿV’§–u²jÂ>1W *½·°PGŽzÿ¨/Eg{ ŸÇâaoŠÁVú:è¿™¤1$ôR§W,–ªà¨@ŠË56¾ÀÔÜ-¾,mê¸Î/æè¹– òr5¥T*S(Vf8ö9u’ Õ£w›ùóa=Í<{Ò¡UŒ÷r¯+ÉådDÏF$è°…£é¿`zþ»ÎúöN‘µÜ®0Q3£~_^Ëóâ¯N=ˆvpTà±LžT}ˆîkq†Òm<¼ÎÓ?Zh¿X£ï_þÝ¥[)ƒ `gêÃa_Ô*äÔ2`'=õ´Fÿ2EâÁPú ÷»›l=8‹Wv°%THqÉ¿<"¤ïG¾ÆxH{#ÆÖ«aÔJÕÞ‡—m‹„ çñKsÿàñVŠØ¡°·MâÒ^ TÁ– Ý›r¥ß½ømüÿ_™?ªWİ÷#uIEND®B`‚openchange-2.0/apidocs/html/mapiproxy/ftv2mlastnode.png000066400000000000000000000003661223057412600234050ustar00rootroot00000000000000‰PNG  IHDRɪ|½IDATxíÝ!NAÅñ¤‡à\ ÷à Um@`Ô5iÒ`ëh ‚ÅW7] b§ÝˆŠ&oföÍd¾YÔ4 üšcø ‡€´‹Åòù3v=¼]†§µ\B… I¿‹=B·™B¡®;¸k´µ W°ÍN@vyÍÑÖ4ãß÷]ÈâYìã§|M}]ÔÚx6a }ôdׇØYüú¨>¤||5?Ó>|žB"¡î'¡IEND®B`‚openchange-2.0/apidocs/html/mapiproxy/ftv2mnode.png000066400000000000000000000003661223057412600225210ustar00rootroot00000000000000‰PNG  IHDRɪ|½IDATxíÝ!NAÅñ¤‡à\ ÷à Um@`Ô5iÒ`ëh ‚ÅW7] b§ÝˆŠ&oföÍd¾YÔ4 üšcø ‡€´‹Åòù3v=¼]†§µ\B… I¿‹=B·™B¡®;¸k´µ W°ÍN@vyÍÑÖ4ãß÷]ÈâYìã§|M}]ÔÚx6a }ôdׇØYüú¨>¤||5?Ó>|žB"¡î'¡IEND®B`‚openchange-2.0/apidocs/html/mapiproxy/ftv2mo.png000066400000000000000000000006231223057412600220260ustar00rootroot00000000000000‰PNG  IHDRÚ}\ˆZIDATxí1Kû@ÆiƒØB…Ò¡(h¬"EÄI'ÁoàªèÚ©ßÀáâä 8ùçR-‚â B«TPˆï]z¥B’3 _Þã’»ç}ŸË]VÇ÷}€ÌÈdIæ®i쟯JØ–b¸šÍÃõ+º™|KÂ…°,[Pï\ʘMÆ¢#€ä…F`JݤìÛk³úA±àþè?ØY4ck6"¹Z)ê¸0SHM¨@ï㋺WÖmo¼4èHJ¨Àÿö+…QobŒút ¤ú’*Ð~êè8_+3Y-ñðÜå½÷ ˜PwA¶+^ý}ºì£+xìhÏ•MAE]€TD~EÞߴ^R)`ÖAùŸÏ9©pÔq-Û¾õÛ3tÝÊÆ›ˆÃTÐHÈ)€ ½Š’ICªxëd#1ôú§é€ m@Vüý?Zæßgo_½3-³\IEND®B`‚openchange-2.0/apidocs/html/mapiproxy/ftv2node.png000066400000000000000000000001261223057412600223360ustar00rootroot00000000000000‰PNG  IHDRɪ|IDATxíݱðøScOx@ –¨y}IEND®B`‚openchange-2.0/apidocs/html/mapiproxy/ftv2ns.png000066400000000000000000000006041223057412600220320ustar00rootroot00000000000000‰PNG  IHDRÚ}\ˆKIDATxíÝ1K1Àñ­ž ØG•â‚n‚Šà ‚âælÁE¿€‹“ (nºêââêäࢋƒÐMAá@°‹ µât¾ÄK¡à%Ü•Û ý]BIïå%áuÍ…a™€,e × v¯ç¥«ˆi‹º¨Õö–î\tòòuénÄ0ã æÜÉoV\Ì$G.&@Y=ÆË%$um·¢ûÛ6–'Úß«9Qó\bÙ)²º0Ðë-Zœ¥TèHÍ`pÀcsm µö5:>Áë‡Þ¦I µØ ‚F‹Çà]» ›jg—ìoÏáõ©[ œõ š­onë €Ô¬¨vqõ„?\Ðç”  6»øüÒTe ÃÉéŸeç ÀÅlQ ¡c”€ª¬ü3*d€ÅWTMÏ\rÿÿh6™ø1±F ‹°fžIEND®B`‚openchange-2.0/apidocs/html/mapiproxy/ftv2plastnode.png000066400000000000000000000003451223057412600234050ustar00rootroot00000000000000‰PNG  IHDRɪ|¬IDATxí=QF‘Ø¥D«ÔkÄ:‰F©PK؃=V@§Õ³ Õ8SHxñÌ0bnrróŠ{ò½¿¾’$ ÀÏTŠP  ö¼X¬OÛd6êìòð"°²S´±O¥B€(¡àQé)š+YĈ ÒªËRÉÐ>VtÉsˆm9(ê„䜥k‚-@ȧ-Ü$ó b Ò[he ¿Kp-ôl|CùÿApRG'rÍ­aIEND®B`‚openchange-2.0/apidocs/html/mapiproxy/ftv2pnode.png000066400000000000000000000003451223057412600225210ustar00rootroot00000000000000‰PNG  IHDRɪ|¬IDATxí=QF‘Ø¥D«ÔkÄ:‰F©PK؃=V@§Õ³ Õ8SHxñÌ0bnrróŠ{ò½¿¾’$ ÀÏTŠP  ö¼X¬OÛd6êìòð"°²S´±O¥B€(¡àQé)š+YĈ ÒªËRÉÐ>VtÉsˆm9(ê„䜥k‚-@ȧ-Ü$ó b Ò[he ¿Kp-ôl|CùÿApRG'rÍ­aIEND®B`‚openchange-2.0/apidocs/html/mapiproxy/ftv2splitbar.png000066400000000000000000000004721223057412600232350ustar00rootroot00000000000000‰PNG  IHDRM¸¿IDATxíÝ¡JCa‡ñç(˜ ëƒ%±Ø4 b±È˜Í¶3˜v^Á±˜…ãó–ŽELƒõ…¥•³ ,ÿb;íç{Ã/¼ðÞÀaYÕ¯åóøq:¼º¹›\òIIIIIIIIIIIIIIIIII-Òçl¹›«õ抢è_t/Ï»ã£ÑíYQVõðêäíã÷´×ùY¬Úÿµ§¦ivók¾_íåýÛ£I@$I@$I@$I@$I@$I@$I@$I@$I@$I@$I@$I@$I@$I@$I@$I@$I@$I@$ýC[Vì=ü[„fÆIEND®B`‚openchange-2.0/apidocs/html/mapiproxy/ftv2vertline.png000066400000000000000000000001261223057412600232410ustar00rootroot00000000000000‰PNG  IHDRɪ|IDATxíݱðøScOx@ –¨y}IEND®B`‚openchange-2.0/apidocs/html/mapiproxy/globals.html000066400000000000000000000122411223057412600224130ustar00rootroot00000000000000 MAPIProxy 2.0 API Documentation
Here is a list of all documented functions, variables, defines, enums, and typedefs with links to the documentation:

- c -


Creative Commons License
Creative Commons Attribution icon Creative Commons Share Alike icon
This content is licensed under the Creative Commons
Attribution ShareAlike License v. 3.0:
http://creativecommons.org/licenses/by-sa/3.0/

openchange-2.0/apidocs/html/mapiproxy/globals_0x64.html000066400000000000000000000251621223057412600232020ustar00rootroot00000000000000 MAPIProxy 2.0 API Documentation
Here is a list of all documented functions, variables, defines, enums, and typedefs with links to the documentation:

- d -


Creative Commons License
Creative Commons Attribution icon Creative Commons Share Alike icon
This content is licensed under the Creative Commons
Attribution ShareAlike License v. 3.0:
http://creativecommons.org/licenses/by-sa/3.0/

openchange-2.0/apidocs/html/mapiproxy/globals_0x65.html000066400000000000000000000507661223057412600232130ustar00rootroot00000000000000 MAPIProxy 2.0 API Documentation
Here is a list of all documented functions, variables, defines, enums, and typedefs with links to the documentation:

- e -


Creative Commons License
Creative Commons Attribution icon Creative Commons Share Alike icon
This content is licensed under the Creative Commons
Attribution ShareAlike License v. 3.0:
http://creativecommons.org/licenses/by-sa/3.0/

openchange-2.0/apidocs/html/mapiproxy/globals_0x67.html000066400000000000000000000065461223057412600232120ustar00rootroot00000000000000 MAPIProxy 2.0 API Documentation
Here is a list of all documented functions, variables, defines, enums, and typedefs with links to the documentation:

- g -


Creative Commons License
Creative Commons Attribution icon Creative Commons Share Alike icon
This content is licensed under the Creative Commons
Attribution ShareAlike License v. 3.0:
http://creativecommons.org/licenses/by-sa/3.0/

openchange-2.0/apidocs/html/mapiproxy/globals_0x6c.html000066400000000000000000000435201223057412600232570ustar00rootroot00000000000000 MAPIProxy 2.0 API Documentation
Here is a list of all documented functions, variables, defines, enums, and typedefs with links to the documentation:

- l -


Creative Commons License
Creative Commons Attribution icon Creative Commons Share Alike icon
This content is licensed under the Creative Commons
Attribution ShareAlike License v. 3.0:
http://creativecommons.org/licenses/by-sa/3.0/

openchange-2.0/apidocs/html/mapiproxy/globals_0x6d.html000066400000000000000000000224531223057412600232620ustar00rootroot00000000000000 MAPIProxy 2.0 API Documentation
Here is a list of all documented functions, variables, defines, enums, and typedefs with links to the documentation:

- m -


Creative Commons License
Creative Commons Attribution icon Creative Commons Share Alike icon
This content is licensed under the Creative Commons
Attribution ShareAlike License v. 3.0:
http://creativecommons.org/licenses/by-sa/3.0/

openchange-2.0/apidocs/html/mapiproxy/globals_0x6f.html000066400000000000000000000225361223057412600232660ustar00rootroot00000000000000 MAPIProxy 2.0 API Documentation
Here is a list of all documented functions, variables, defines, enums, and typedefs with links to the documentation:

- o -


Creative Commons License
Creative Commons Attribution icon Creative Commons Share Alike icon
This content is licensed under the Creative Commons
Attribution ShareAlike License v. 3.0:
http://creativecommons.org/licenses/by-sa/3.0/

openchange-2.0/apidocs/html/mapiproxy/globals_0x70.html000066400000000000000000000070671223057412600232030ustar00rootroot00000000000000 MAPIProxy 2.0 API Documentation
Here is a list of all documented functions, variables, defines, enums, and typedefs with links to the documentation:

- p -


Creative Commons License
Creative Commons Attribution icon Creative Commons Share Alike icon
This content is licensed under the Creative Commons
Attribution ShareAlike License v. 3.0:
http://creativecommons.org/licenses/by-sa/3.0/

openchange-2.0/apidocs/html/mapiproxy/globals_0x72.html000066400000000000000000000073071223057412600232020ustar00rootroot00000000000000 MAPIProxy 2.0 API Documentation
Here is a list of all documented functions, variables, defines, enums, and typedefs with links to the documentation:

- r -


Creative Commons License
Creative Commons Attribution icon Creative Commons Share Alike icon
This content is licensed under the Creative Commons
Attribution ShareAlike License v. 3.0:
http://creativecommons.org/licenses/by-sa/3.0/

openchange-2.0/apidocs/html/mapiproxy/globals_0x73.html000066400000000000000000000077561223057412600232130ustar00rootroot00000000000000 MAPIProxy 2.0 API Documentation
Here is a list of all documented functions, variables, defines, enums, and typedefs with links to the documentation:

- s -


Creative Commons License
Creative Commons Attribution icon Creative Commons Share Alike icon
This content is licensed under the Creative Commons
Attribution ShareAlike License v. 3.0:
http://creativecommons.org/licenses/by-sa/3.0/

openchange-2.0/apidocs/html/mapiproxy/globals_0x75.html000066400000000000000000000065311223057412600232030ustar00rootroot00000000000000 MAPIProxy 2.0 API Documentation
Here is a list of all documented functions, variables, defines, enums, and typedefs with links to the documentation:

- u -


Creative Commons License
Creative Commons Attribution icon Creative Commons Share Alike icon
This content is licensed under the Creative Commons
Attribution ShareAlike License v. 3.0:
http://creativecommons.org/licenses/by-sa/3.0/

openchange-2.0/apidocs/html/mapiproxy/globals_0x78.html000066400000000000000000000066011223057412600232040ustar00rootroot00000000000000 MAPIProxy 2.0 API Documentation
Here is a list of all documented functions, variables, defines, enums, and typedefs with links to the documentation:

- x -


Creative Commons License
Creative Commons Attribution icon Creative Commons Share Alike icon
This content is licensed under the Creative Commons
Attribution ShareAlike License v. 3.0:
http://creativecommons.org/licenses/by-sa/3.0/

openchange-2.0/apidocs/html/mapiproxy/globals_func.html000066400000000000000000000121221223057412600234240ustar00rootroot00000000000000 MAPIProxy 2.0 API Documentation
 

- c -


Creative Commons License
Creative Commons Attribution icon Creative Commons Share Alike icon
This content is licensed under the Creative Commons
Attribution ShareAlike License v. 3.0:
http://creativecommons.org/licenses/by-sa/3.0/

openchange-2.0/apidocs/html/mapiproxy/globals_func_0x64.html000066400000000000000000000250431223057412600242130ustar00rootroot00000000000000 MAPIProxy 2.0 API Documentation
 

- d -


Creative Commons License
Creative Commons Attribution icon Creative Commons Share Alike icon
This content is licensed under the Creative Commons
Attribution ShareAlike License v. 3.0:
http://creativecommons.org/licenses/by-sa/3.0/

openchange-2.0/apidocs/html/mapiproxy/globals_func_0x65.html000066400000000000000000000506471223057412600242240ustar00rootroot00000000000000 MAPIProxy 2.0 API Documentation
 

- e -


Creative Commons License
Creative Commons Attribution icon Creative Commons Share Alike icon
This content is licensed under the Creative Commons
Attribution ShareAlike License v. 3.0:
http://creativecommons.org/licenses/by-sa/3.0/

openchange-2.0/apidocs/html/mapiproxy/globals_func_0x67.html000066400000000000000000000064271223057412600242230ustar00rootroot00000000000000 MAPIProxy 2.0 API Documentation

Creative Commons License
Creative Commons Attribution icon Creative Commons Share Alike icon
This content is licensed under the Creative Commons
Attribution ShareAlike License v. 3.0:
http://creativecommons.org/licenses/by-sa/3.0/

openchange-2.0/apidocs/html/mapiproxy/globals_func_0x6c.html000066400000000000000000000434011223057412600242700ustar00rootroot00000000000000 MAPIProxy 2.0 API Documentation
 

- l -


Creative Commons License
Creative Commons Attribution icon Creative Commons Share Alike icon
This content is licensed under the Creative Commons
Attribution ShareAlike License v. 3.0:
http://creativecommons.org/licenses/by-sa/3.0/

openchange-2.0/apidocs/html/mapiproxy/globals_func_0x6d.html000066400000000000000000000223341223057412600242730ustar00rootroot00000000000000 MAPIProxy 2.0 API Documentation
 

- m -


Creative Commons License
Creative Commons Attribution icon Creative Commons Share Alike icon
This content is licensed under the Creative Commons
Attribution ShareAlike License v. 3.0:
http://creativecommons.org/licenses/by-sa/3.0/

openchange-2.0/apidocs/html/mapiproxy/globals_func_0x6f.html000066400000000000000000000224171223057412600242770ustar00rootroot00000000000000 MAPIProxy 2.0 API Documentation
 

- o -


Creative Commons License
Creative Commons Attribution icon Creative Commons Share Alike icon
This content is licensed under the Creative Commons
Attribution ShareAlike License v. 3.0:
http://creativecommons.org/licenses/by-sa/3.0/

openchange-2.0/apidocs/html/mapiproxy/globals_func_0x70.html000066400000000000000000000067501223057412600242140ustar00rootroot00000000000000 MAPIProxy 2.0 API Documentation

Creative Commons License
Creative Commons Attribution icon Creative Commons Share Alike icon
This content is licensed under the Creative Commons
Attribution ShareAlike License v. 3.0:
http://creativecommons.org/licenses/by-sa/3.0/

openchange-2.0/apidocs/html/mapiproxy/globals_func_0x72.html000066400000000000000000000071701223057412600242130ustar00rootroot00000000000000 MAPIProxy 2.0 API Documentation
 

- r -


Creative Commons License
Creative Commons Attribution icon Creative Commons Share Alike icon
This content is licensed under the Creative Commons
Attribution ShareAlike License v. 3.0:
http://creativecommons.org/licenses/by-sa/3.0/

openchange-2.0/apidocs/html/mapiproxy/globals_func_0x73.html000066400000000000000000000076371223057412600242240ustar00rootroot00000000000000 MAPIProxy 2.0 API Documentation openchange-2.0/apidocs/html/mapiproxy/globals_func_0x75.html000066400000000000000000000064121223057412600242140ustar00rootroot00000000000000 MAPIProxy 2.0 API Documentation

Creative Commons License
Creative Commons Attribution icon Creative Commons Share Alike icon
This content is licensed under the Creative Commons
Attribution ShareAlike License v. 3.0:
http://creativecommons.org/licenses/by-sa/3.0/

openchange-2.0/apidocs/html/mapiproxy/globals_func_0x78.html000066400000000000000000000064621223057412600242240ustar00rootroot00000000000000 MAPIProxy 2.0 API Documentation

Creative Commons License
Creative Commons Attribution icon Creative Commons Share Alike icon
This content is licensed under the Creative Commons
Attribution ShareAlike License v. 3.0:
http://creativecommons.org/licenses/by-sa/3.0/

openchange-2.0/apidocs/html/mapiproxy/header.jpg000066400000000000000000002264161223057412600220470ustar00rootroot00000000000000ÿØÿàJFIFddÿìDuckydÿîAdobedÀÿÛ„ÿÀÍ4ÿÄû     a!Qqð1A‘¡¢d ±"Ô%U•ÕV–Ö”WÑñ#EÁá2DT·BR3C$uµ&g(8x’S£³4…6¦hbc¤´Å†G§)   !1AQq"“ÓT”ÔUa2‘¡Ò#³´u6±BRVÁÑb²3$v'7ðár&ñ‚’¢CS%Âsƒ£4Dct¤5ef(ÿÚ ?ýAîÊåSñMÁÙB8v)¸;(GÅ7eáØ¦àì¡;Ü”#‡b›ƒ²„pìSpvPŽŠnÊñMÁÙB8v)¸;(GÅ7eáØ¦àì¡;Ü”#‡b›ƒ²„pìSpvPŽŠnÊñMÁÙB8v)¸;(GÅ7eáØ¦àì¡;Ü”#‡b›ƒ²„pìSpvPŽŠnÊñMÁÙB8v)¸;(GÅ7eáØ¦àì¡;Ü”#‡b›ƒ²„pìSpvPŽŠnÊñMÁÙB8v)¸;(GÅ7eáØ¦àì¡;Ü”#‡b›ƒ²„pìSpvPŽŠnÊñMÁÙB8v)¸;(GÅ7eáØ¦àì¡;Ü”#‡b›ƒ²„pìSpvPŽŠnÊñMÁÙB8v)¸;(GÅ7eáØ¦àì¡;Ü”#‡b›ƒ²„pìSpvPŽŠnÊñMÁÙB8v)¸;(GÅ7eáØ¦àì¡;Ü”#‡b›ƒ²„pìSpvPŽŠnÊñMÁÙB8v)¸;(GÅ7eáØ¦àì¡;Ü”#‡b›ƒ²„pìSpvPŽŠnÊñMÁÙB8v)¸;(GÅ7eáØ¦àì¡;Ü”#‡b›ƒ²„pìSpvPŽŠnÊñMÁÙB8v)¸;(GÅ7eáØ¦àì¡;Ü”#‡b›ƒ²„pìSpvPŽŠnÊñMÁÙB8v)¸;(GÅ7eáØ¦àì¡;Ü”#‡b›ƒ²„pìSpvPŽŠnÊñMÁÙB8v)¸;(GÅ7eáØ¦àì¡;Ü”#‡b›ƒ²„pì__gÓâ£êE~•²O\VݪÏãžà…·#÷Á?Nž•cÏ´Ôô™Û£¾!àÞÖ²x¬.c;s÷<%Íåå+ÝÁ’¾ºckO¦‹£Êcq0}ç)sµµi®W¶6׳SÈpo× 'ü߯Wí¬?þ«[7ð¿™áÜï¨]ù¥‚øócûëëvþqkúß„ÿ›øÇñå­õ¥?á2ÿùßP»óHøócûçëpyůëvþoc/Ç–¿Ö”¿†Ëÿç=BëÍ#ãÍïœW­Áçýn¿ÍÜeøî×úÒá‡2¿Ã¹ÏPºóIüy²=óŠõ¸<â×õ· 7qŸã»_ëJ?†Êÿç=BëÍ#㽑ïœW­ÁçýlÂÿÍÌiøê×úÒ—ðÇ™?áÜç¨]y¤|w²=óŠõ¸<â×õ¯ ÿ6ñ§ã«cë:?†<Êÿç=BëÍ#㽑ïœW­Áç¿­XcùµÛYÑü1æOø{9ê^iì|â½n8§ëNþlãoÇ6ÏÖt ¹“þÎzךGÇ{#ß8¯[ƒÎ-Z0×óg~8¶~³£øeÌðösÔn¼Ò>:Ù>ùÅzÜqkúφÿ›ßñųõ/áŸ2?ÃÙ¿QºóHøëdûçëpyÅ?Y°à÷²¾8üom}gGðË™áìߨÝy¤þ:Ù>ùÅzÔqkú͇šøãñ½µõ•Ã>d‡³~£uæ‘ñÖÉ÷Î+Ö óŠ~²áßæ¶9ümm}eGðϘÿáìߨÝy¤|u²}óŠõ¨<â×õ“5q×ãkoë*_ÃNcÿ‡ó~£uæ‘ñÎÊ÷Æ+Ö ó‹_ÖiìÏ{âýj8µýVÅÌ›ñtÃéy…îÏ©\ù´|o³=ï‹õ¨<⟪¸°{Ù&Äü]ðú?‡<Â÷gÔ®|Ú>6Ù¾÷ÆzÔqkú©‹™/âØ‡Ñü9æ¸s>¥sæÑñ¶Í÷¾3Ö ó‹_ÕL[üDZÀü>á×0}Ùõ+Ÿ6ŸÆÛ7ÞøÏZƒÎ)ú§‹¿˜ö7âȇÑü:æ¸s>¥sæÑñ¶Í÷¾3Ö ó‹_Õ,_üƱ¿A|:—ðï˜âÌz•Ï›GÆÛ7ÞøÏZƒÎ-Tq€÷²-Ž?þë‚øuþ`{‹1êW>mìß{ã=j8§ê†1þbYŠà¾Gðï˜âÌz•Ï›GÆ»;ÞøÏZƒÎ-Sñ—óÈüUðê?‡{ÿÜYR¹óhø×g{ßëPyÅ?Sñ—óÉüUðê_ÃÍÿî,Ç©\ù´þ5ÙÞöÆzÌqkúŒÿ˜VWâ˜?‡Qü<ßþâÌzÏ›GÆ»;ÞØÏYƒÎ-Sq ÷²•ø¦á´w÷¸³§sæÑñ®Î÷¶3Ö`óŠ~¦c_æ —ø¢á´w÷¸³§sæÑñ¦Î÷¶3Öaó‹_Ô¼müÀ²ÿB|6áîþ÷cÔî|Ú>4ÙþöÆzÌ>qOÔ¬müÀ³?Â|6—ð÷{/êw>mlÿ{c=fËZþ¤ã¿öoâx_†Ñü>ß¾ãËúÏ›GÆ›?ÞØÏY‡òÔýIǬßÄп £ø}¿}Ç—õ;Ÿ66½±¾³å­R1ÏßÛ;ñ4/Ã(þoßqåýNçÍ£ãMŸïlo¬Ãùk_Ô|s÷öÎüK ðÊ_Ãýûî<¿©Üù´þ3ÙþöÆúÌ?–§ê6:ûùgþ%†øeÃýùî<¿©Üy´|g´=íõ˜-kúŽþýÙÿ‰a¾Gðÿ~{“/êwmí{c}fËSõýû´?Cü2€7ß¹2þ§qæÑñžÐ÷¶7Öaüµ¯ê&<ûõh~$‡øe/€7ß¹2Þ§qæÑñžÐ÷®7Öaüµ?Pñïß«Gñ?Ã)ü¾ýÉ—õ;6Œö‡½q¾³å­Pñ÷ß›GñGÂé|¾ýÉ–õ;6Œ¶‡½q¾³å©ú…¾üZ_ˆâ>GÀ;ïÜ™oS¸óiüe´}ëõ˜-kúƒþüZ_ˆ¢>GÀ;ëÜ™oS¸ói|e´}ëõ˜-OÔ÷ÞÓüEðº_ï¯re½Rãͧñ–Ñ÷®7Öaüµ¯ê÷ÚÓüCðº>ß>åËz¥Ç›GÆ[GÞ¸ßY‡òÔû`ýöµ?Äü.€·×¹2Þ©qæÑñ–Ñ÷®7Öaüµ¯Ûëï­©ø‚'át|¾}Ë–õK6Œv½q¾³å©öúÂûëjþ ‰øUoŸrå½RãÍ£ã£ï\o¬Ãùk_·¶ßKWñW¨ø |û—-ê—mízã}fËSíå‡÷ÒÖú~+áT¾ßåÊú¥Ç›GÆ;KÞ¸ïY‡òÖ¿o,?¾–·Óñ_ £à=ñî\¯ª\y´|c´½ëŽõ˜-O·v'ß;_éø¯…Qð&ø÷.WÕ.<Ú>1Ú^õÇzÌ?–µûwbýòµþŸ‹øUïrå}RãͧñŽÒ÷®;Öaüµ>ÝX¿|­§¢þGÀ{ãܹ_T¸óhøÇi{×ë0þZŸn¬o¾6ÇÓÑ £àMñî\¯ª\y´|a´½ëŽõ˜-köæÆûãl}=ðª>ÞþåÊú¥Ç›GÆOÞ˜ïY‡òÔûqcýð¶~ŒøM/7¿¹²¾©qæÑñ†Ò÷¦;Öaüµ¯Û‹ï…³ôìgÂhø{û›+ê—mm?zc½fËSíÅ‘÷ÂÙúv3á4| ½ýÍ•õK6Œ6Ÿ½1Þ³å©öÞÈûßm}9ðš>ÞÞæÊú¥Ç›GÆOÞ˜ïY‡òÔûodýï¶¾œŒøMïose}Rãͣ㠧ïLw¬Ãùk_¶ÖOÞëkéÈÏ„Ñð.÷÷6WÕ.<Ú>/Ú~ôÇzÄ?–§Ûk+ïu·ôÜoÂhø{{›+ê—mm?zc½fËZýµ²¾÷[MÆü&w·¹²¾©qæÑñ~Ó÷¦;Ö!üµ>ÚÙ_{m¿¦ã~Kàmíîl¯ª\y´þ/Ú~ôÇzÄ?–§Û[/ïm¹ôÜoÂhø{{›)ê—m/Œ6Ÿ½1Þ±å©öÒËûÛn}7ðš>ÞÞæÊz¥Ç›GÆOÞ˜ïY‡òÔûieýí·>›øMoose=Rãͣ㠧ïLw¬Ãùj}´²þöÛŸMÆü&··¹²ž©qæÑñ†Ó÷¦;Öaüµ>ÚY{mϦã~GÀÛÛÜÙOT¸óhøÃiûÓë0þZŸm,¿½¶çÓq¿ £àmíîl§ª\y´|a´ýéŽõ˜-O¶–_ÞÛsé¸ß„Ñð6ö÷6SÕ.<Ú>0Ú~ôÇzÌ?–§ÛK/ïm¹ôÜoÂhø{{›)ê—mm?zc½fËSí¥—÷¶Üún7á4| ½½Í”õK6Œ6Ÿ½1Þ³å©öÒËûÛn}7ðš>ÞÞæÊz¥Ç›GÆOÞ˜ïY‡òÔûieýí·>›øMoose=Rãͣ㠧ïLw¬Ãùj}´²þöÛŸMÆü&··¹²ž©qæÑñ†Ó÷¦;Öaüµ>ÚY{mϦã~GÀÛÛÜÙOT¸óhøÃiûÓë0þZŸm,¿½¶çÓq¿ £àmíîl§ª\y´|a´ýéŽõ˜-O¶–_ÞÛsé¸ß„Ñð6ö÷6SÕ.<Ú>0Ú~ôÇzÌ?–§ÛK/ïm¹ôÜoÂhø{{›)ê—mm?zc½fËSí¥—÷¶Üún7á4| ½½Í”õK6Œ6Ÿ½1Þ³å©öÒËûÛn}7ðš>ÞÞæÊz¥Ç›GÆOÞ˜ïY‡òÔûieýí·>›øMoose=Rãͣ㠧ïLw¬Ãùj}´²þöÛŸMÆü&··¹²ž©qæÑñ†Ó÷¦;ÖaüµÈ[.Õâ)8há'(,™Ed"©,’¥¦ªJLEP‚Sˆ¡ZÜðMk;í®ctw1¼µìp-s\ÓG5Í4-sH ‚P¬ô3Eqn-Þ×Àö‡5Í!ÍsH¨s\ AÄ/£³éñWÔ¹+ô©Ùôø¨ú‘_¥bï¼JÆàXññ‰¶•Èeƒ‹\D[G2NJ&CC6*ä1ORöêÜ 6¾ñÈîKÞsS,û«×> §hð'•¿jGÐ8A<‹H/u†–ð«‚ònió6Û`ãÛ«Y.á¸i10ý–7£½xtÖ¡£†§Æ€¯oL…xäi¥® Òᑸ$Ö1÷T|¹Ì‹DÎmïFhV±í?䤉˜sk_§[khmÍn'mYÃidÐ*Ðò8j‘ÿjGž·<—Õð¶sqf·-ó²9ˉn.[ƒýV7ì±£©­.( uV|µb*”ë©ÓDꔪmÓÜþŠ’;SªPS¸)P& PSn½=ú’ÔU()ÕRZª©ANº)Õ)UÛã¤GjuJ wM`¥*›u÷jKSªPSnÞ*’ÔꔨÓN…UL íñÒ¢uJU:½ÊšR‚}‹SªR©·ÇPZR‚•ORuLUzüƒJ©Õ)TÛ§Oz•N©ANà¨-L ¦Ýj UU)Tê÷*t”ÁL XRN½‰J¦Þ¡¥¤'T §UAjuJ uÔ§T¥So½SBª©AOëè¤{Mºûµ%¡:¥*›t©-N©AJ‚ÔꔪmñÒ¡N©ANò…MªR©×ÑH´& R©¶ µ:¥*KU”Û¯MMN©ANò…*'T §^ЩÒR‚›jKSªPS¸* S)TÛ®Á©¥ª@S¤<´“ª`S¯¢•uH m©-N©@üõ©‚ªsPÔ–§T §pRâR‚›u¥@RU%©Õ(yõ©-Nªà~ª’ÔꔚŠQ:¤ŸNš<)Õ()J€§T€}µ%©×ëH)Õ 9ô©-N©ãÓSDU 9ôé¥Ç­:¤ÒàSW…-)Ô¤=Iju€~z)ñWs I¨ª@?8x©S±5p?0ÿM.=iÔ¤ÑÀ£‚¸)Q:•p5M¨ëWÒÒŸ\ SBŠö«„<4¨ª¸<5:SVs .!UÀÂT'^Õp?pQNÄS±\ J‰ÔŽ•®´¨Š…`0ôÒ¢t À`è¥E4ZÒIkB¡ P…(B”!J¥R„)B¡ P…(B”!J¥R„,®Áw ¹f"Éc “8±K^ð$Óþ@è§_›ûç÷Û1ûVïôò/»¶‡îž/öu·èX²?³îÒµo¶/À§gÝ¥…~pxš»e®Üõ•K¹2ÇŒ½ni57fÞ*Ù”u‚D¦ÑL}4ÞPÆ0òˆ×ì?%0V.U` Ç°5³ãmî^zÝ-ÌMžGÒ|g+ÐÐ@ ó{š[¼¶ÿÊËxíF+é hêÀ÷DÀ;õ*ꔪXTÐ'TÅSn¾íIjuJ mÒ¤µ:¥* SªR©·]ƒJŠª”é(TÒ©Õ0)×ÑRZR•Mµ%©Õ()ÕÑQ¥:¥:È4¨R•M½CR@N½©ANà¤ZR•MºÔ§T¥SnžåAjª¦:ú)'T ¦ßMuJ uR-N©ANº‚ÔꔪsžçôT–§T §pT¦bR©·Çߥ@R‚U%©Õ()×PZª© §0éÝâ©-N©ANà¥Å:¥*›|u4ªPSª‘jª¥6ëPZRU%©Õ((=54¢uH mÓ¦—…:¥óÒ =ª@?0Ô–ªªP?=N”ê§æ¡¨-N©Nz\SªPSn½Þ:\:ÐKObuHÛRZ~¤€~z’ÔêÌ:ôÔ–§T€~~JT#¡4…?0ëKÂ{RéR½¯b@?0÷tT{UÀýu%©×±\ ú "ª@8ôÔiNªàpè飈OÀ4¸u¢½ªàz(Ÿ ¦‰×µ\4ˆ@§R¸<<•:S©Væ’;Sª¸|<´´¦®})P„+†•{Sª¸Žà¬ (Ž#¡_ZTOWjÔ˜iQ>[{ž•¢¶ 4’¢Ö’JP…(B”!J¥R„)BYðÒ–¨<;ï\ùU0ø«ó{|þûf?jÝþžE÷vÐýÒÅþζý `ö;<•«T-‹þÝ*v;<”T#þÝ+ò•ŸÍ»žshkÞ˹$4—”Í~Öò¨Êý·ûú¤+óü÷šý­yúÄ‹©€ýU¾­N©@ýu%©Õ )·J‚Ôêš'T ¦Ý;¼TxSJçÿMRuH mê’Ôê”çä©-N© ¦Ýj Sªû™6y éQí\½xàà›v¬ÐUË•Ô0èTÑAUNo×ÒÇfYÜÖBÑR礞[ùÀ\ãÐOàYKcðožïTÐr[IKyŠú®n5>/W³0”@bRªø ©Ã@2e 5¯7ÌókcaÜcuÛg¿Õ‹ÇãÙ«ƒz»|+mÆì}Ë“ðÛ=±ž5p§¯Â<+¸à2è†dçn„ƒEÛ ©XGª)¦.I¯½Qs ”1¬Tļ¢<•ªÅÎìMäÝÕ•»ŠHÔáS@]Ð:*ÐOJÊͰo,ÁûãÈ¡¡£M:iÓÆ´<;*¶ÙÚ±)ÿçƒÒ¡È.b„©ïhôÆn7Cx{ýí9DC½]«~k™Èÿtiû2Ÿý=«„íá;ª[H‚ºÆàá®àˆrá«Y¦.\ šJKº ²b²~Žå#%5KCrD `Ö¶+`cîãl¯ŠFÆâE{(iÄ#¾#¤®ÆÔž²F—Ž®Úñ ‘кVn͹mÓÆQª‘0HGEÐäå×}=t^PïVÝi—ÇÞÌH5£À¬Î6ö׌Œ%½£ˆ\dëò dhB©MºtÒ-N½©AJ‚Õ@¥*›u©-N©J§UM uL uÒ N©J¦ßIjuJ uT–§T §]AjuJU6éîTЧUÚ¸kßÛ!@ã\{Y†uSˆ(º‚Þ6&9¸’S÷TôH¸Ô5:§C‰¦E9mcwîÌ&ÈÀO¸óòì UïyàÈão Oyà8¹Å­pÎíͽ”Ý9x°¸vk¼”õš5iï=MhâOz ˆÖ»—†ogg1QŒø¯ÉÒWîF~Å'«Ú±on&†äû@ûfÃ2sñQ«†".å¤IÈ”D‚AÔ…ùœÝçŸ3ndŸ—0ã¶ûZٞ؜ziãKr oxà\Èb%WIú5ü¹åNÆ…‘o[¹/sh&6:FýXà!íiè–@Ò)Ð>7{,ø·]K/dIÜQ“Ý$¸Á@Ê>ºAÓåÐ)tôxlŒåó[°¦L¦TÌã%Sz ”ÇÌ„8î¹—üÃr茖òµ¶ÊàZGxö²?ÿÕ¬0ž€,.Ž´q* ØüšÞ€Ùm©æÇåÈ:]!$ô'.véŽPúTðy¡Ä>¿¸gÉ1ÖAj¨dFFÛ¸˜‚ƒ v@¨±ÑBZ)UCDÅ7 ”ÑfËJmJ$9þ¢å÷0°ÆÁ37„qkÓ,N§y ”©cÀémxñ^Þ"†­ ¼6n_ee‹Ê4MQÈß±++@æ“Äv9§‹OŠÒÅWn½5½P­N©J§W”)Pê˜ëè©-N© ¦ßAjuL TéUT¥W¯È54N©J¦Ý:{Ô¨ªPS¸*KSªb©·Z‚ÔêªuTé)Õ0+Éà%Mz=íá×pÛgá«´ÓW×ùçK4iy•¥Pc¢­Çˆz*j¦@o¢²Šk¦º€‡5|ÏÉ.iîmñ—ËÙn7Àè,û¾ëDa‡Æ|­5 šðcWºsO``¶¦7u…l¢[}æ·—±‘N8¸¯9ÐpUS*…C ×ÒbŽ ÃÏB¾S®‘j*”ªsžçôTé)Õ0)ýaI0{•Mºûµ:BuJ uT–§T §]AjuHU6øêtªª`S«hRER•Mºû´¨ª@Sn•%ªª”¨-N©AM¾:)Õ()Ïã ”ÁìJU6ëîÒ N©ANªE©Õ )×PZR‚›t÷?¢¤µ:¤9ùv…M uJU6õ / uJ sÒÓØRù†¤µ:¤÷AjuJ >½5:Sª@Sª—ÒúépER–”궤µ:ýJàpè©-N©@ãÏ­AjuWõyiP§T qç×ËK‚jàz4ö'^Ä€na©!íHç©-M\ Ì:TRÇÃËS¥5p8séÓKˆN©ãGpëWÒ¢~p7pR!:ö«Ç¦¤µp8R¡N¥\ >©#µ:«ù§Jjà`ðÒ⬢½©×µ\ÝÞ¢ÀÛ|tQB¶´¨ž¥`0ÔÑ>[{ž•¢×]hIkI%(B”!J¥Y‰Ã"Zµt:wݸý!¼5ù½¾}³µnÿX‘}Ý´?tñ³­¿BŘ½vµª­NÇ»Z¿%œB˜ Ÿów´Ì90QRxÔt.¸ÁÔ`9p¬rU¶ªö/»BRòŽ¥3 cx¥þ€¾ÁtW}ÔM‘À;…[Bþ׬ý+L=Áµïß##™Ä WéT•Ã%0z«uœ1lªNY±lGGP§Uºí[z:E1A¹;!U° aÐÄÝY[qq]ops^ò@¨TõšÐÖ¾õÃmËZHkšæ´H$)NÒà6tT»uÐ(£¤À@éiÛ4PL'2J”Šö§HU DtÝ0ˆw‚³Ö™››g‡>ˆõô8vŠŠOè\ca˜‹ êêðý…bÍׄ;~áó3e%¸²ÌôìÚÉ•2†Lœ€T]ƒ©Š:r›”¼¡èÍé÷hÃåÖûZÑÕâYôöÓéâ:ºV§}¶ÅËÜÖQ“õ§ÛðýKæ¡¥íÉâæY,Åësn¨ŠÀÈ S¦r “P‡(€Š"^‘ÈYå-ÅÍ“Ãã=#è#¤-òÊæÂcËK_øm¥Sª»ÄÕªPS¯¢¦:¥6øé¢©ANª‚ÕUJ uÔ§T¥Sn”¨Sª`Sú¦0R‚›u÷i§Uï²ù„!ᓉŽ*åcŠòJÜgv¤˜(,6Æ/²P¾d2T¥¦œì”ˆ&¨Q:ŒSäÔ¡¯Â¿Íýæâßø\A!m¤‚'štw×sºÝ®pë1±•o`‘Üx•õw!í-°ÛC/½ef«†wéîíâ8Ø÷:‡´°v/ÎmËv^yÊÿ¹ò ñ0îjáºæžMLÉ:Pç3‡o DŠcfÙ=Ô›¢MA2HR€}7€ÀÚYØÁˆÆF!Æ[FØã`àZ)õ“Òç.q.$’Jð¼¾Zâæê\óÌ—ó¼½î=$Ÿè €€.Ml-ò>bAìTÜCÖ’‘R±Î–g!'ºnØ¿bñ¹ÓpÕë7ID”!Šr bˆl·vÖæÙöÓµ¯†F¹®µÍp!Í ð ƒB ÁÙ¸‚fÏ ‹$cƒšA¡‚è Š‚:è ‰PâCÙ}‰¸ŸœI±¯Ë[BFj]š w/¤n„pýþÙºiãx雼È=ôtôìŲ`<„øƒ–lŸ–œþÈìkg8bî ¬k 'ÅýîÜšô¹ÕšN§µõ>ùt[ã”6[®pÓÅÔh¿îóØ×IGPti‹¯ø<à“ñ¹jôŸ“²îtç®I^ËM‘ ~ß¶­™F.eŸ:Žzvñ‰ŠVúnKÛ® "‰Ì œ¤Ž÷Ìþyo=“̶müD1]â´E¶ýÝd’YXàÆ‡¶¯§{ éhÔà AÔj[•;gtlgfr2Éo¼µÑŒŽ7´¸–š7ìjq $P(­f\ÞÇ®øŒÂѰy I)Gmm˜|Å55|FÛ“So\›йnÖÉǬñÚ…!Vun3Ž(˜ }ÒjjÆå2ßÍ?ýÕ5æ<@Àe}Œq[>HØÑW0àMtù:'‚ïXc¹ y|Üv׆gnß$ÍcÜMá(“®·k;h8¬Aã[†ü%eVV¹dœNØ×“S–Àñ""ùvlÜ‘´œ¿bšMTœ€U ²ˆ”©,ƒ„V$* )ûw'y­mÌý¾ë¹£m¾rÙâ;ˆÚIn¢*Ù#©'»P8’×5í«ƒCå|Êåôû0-£{¦ÅNÒø^áãP9 [ "€‡5ÔÒ3^ßá#†°Ì`ã®beåÃw‘3BbÈG²Ì×AUZðA½¾â2nRàbÐå3õÌõœk%Næ0¦ª¾9›ç/0÷þë¸Ûšd1c- ^ÊÖ8:ŽÓÞVPøÙœ‰¢9&ú©¬ô¼_,önÐÛðçy˜éd¾¸E«öÒ£VŠFZ÷HÑöÝ­‘°5&Žv㋱W³ƒŽÖ'¾pžX‡Šs0Ê"æy5"õÓDTI°É:‰œ»o(yèvΦUÒŽ”jõ 9Na)?ÊÄe¹Ï~U]Ñß²ÍmÉ$ s¢dlš-’(-ßÈK¥‰ñš=~Êå70-ä²ÚͺÆf˜Â懹ï$tUÌ’YšöEC$cÅA<:p7á"¯ÅͷÞ[báºÍò¶eÞÊ9éÛ*ªh$åB:Œ~RýE$á²ÀPíT¦ÓßWÐ;›µÜªºß»RF—ýÀO {A’ÞM$µÍ¯:—Žà¶{›Ì }£¸àß½÷R†šTMZîÇpsM8´ƒÖ½!Íü;{:øC¹Ô›Î7Ï4Òàd̶fŒ›”{qºi);–IHYy±håúG#uWxÁ‘{#¦Qp®¥OæýµÍŽyóÛ­¥½Ä/qžýñ±±Ôš²&6FICH. ŽI A:ÅÞÙœåç*6Uñ»Ï¾âhdhî­÷Òž4Ž,sBꆒö0Pôqۆá~÷⃲Ï[/±›IçÓvÔ¤ÂøšÔ‹Nภf#î‰Yçì¦Fß\ŽX®ÉâV0•1)Äæ2Y]½Í¾gìÎ`ZìÞh¾ »KçÆÖLÆDÂÞõÝÜr1в&º>ðÈÙ#®Pt3<ºØ{›gÜnm„Ù­®m÷:7:GjîÛ­ì{e|ŽÑã1Ìyi45%¸YÁw ’¼[_îa’V ǵڳ–¾nVȦáÓ6VU(Øh¤•Õ›3UÁªIYcN̨©îÙæ¥,öã2"6Üfnœæ[BI sš|#w¦êŽqs u·Ê¹yËû½óšuž³2Ý¡ÓÈHÖ0ßGi'ƒC\â ]™ÕËì…ÃWš˜¢ä¶/ËÞfAX’ø†œ½åb!ä[j“Óɺ‡½­ÖÏÔb࢚¿ź!V)ŠÑð¬~SùÜXѸ­o¬l­¦`’+gÅl×½§‹CCíåsC‡ßLÓJEW¬^cù…½8k‹[«©ãv‰'l“9­pàK‹&Œ:‡î¢p­EEñµÂ±áì\ň®U®ì” ȰRN¥ æ%üÌZ×!“lÙ²2ðif ‰{b‚'"¢aÜQOGäç8o·­ÅÖÖÝ6ÛwØêÖ [#XáÉa$²XÞ@‘ é:mZÝ'™|µµÚðÛç¶ô®ŸmÝÓIqsæ—´jjcÙRÃMB„:¦„ú›Ç$áî÷ǘG#ñ=’ÝØ8Ÿ·|ñìdYŒ”Íó;sCÛ‰CÛ‘«7Aü¢‚bB.u[±j£ÅRÔÄQ¹QbüË}É»0ùÌž/eZ6ç; s¾Ä,òHàK[ýqG=Á€ð!䆟£7¾näñV7û¦àÁ‰´a%­ûR¹íf–4€]ýSPÖ—ÐZ#0¾1öjñŽÎî°8ˆ½1ÎA‚<Ó7Ò·r²Å*현ëx»†íº æbI¼n“´w›¹pP(§¾U ë9®`së–2Úå·eÅžC,¡Žcc€2´'»/ŠdcËC‹ã¶­5¡ióÌ^ÏåûŽã·a¹²ËG ç>RêT a²K+Ð⇊î<¨#ÍÜ]‚®|ÄppÞ.›F\ñ÷½Éh\²eIWlⳓ žU$ñI7i ¹ÛÆH®ɾMð0}5œæ>'Ëçó5ÒX›H¦Š:†¹îœ0E6Dâ¢7Ë èZݿˡ´ð1fùŽé$½¸%³ Å*+¢‘–½Ïí¸½‘°5&ŽwÛŒñÏ³ëŒÆSvŸÊ^x(ÄŹ—gq:—~ñËDTI¸È8‹™º.Ø™¸–îI„“g‰Êcn—¿ŠÊs¼±ºŠÿy¾Ï/·ä1α°jtµñÃãyé2Dö=û ʽùo%žØmÎ72Æ4=Ïq#¢¥¯–V½ ‘PÉñÓÀ/0o[js_V<º›•Ëg̼„–nCï¢+µ>‰ºj ”¢»íÌEÐS@íP¦Ó–¾ªÛÙìvæÃÛæñŽÕes^Úð –¸u9¦­pêp#©|û™ÃÞà²Sb¯Û¦ê NŠŽ±Ú(ZzÁl`¦ÚÌ–¬]R‚œõ%©Õ()·ÇQ¥:ö¥:B’uJU:éP'T€¦Ú’Ôꔩ-N©J¦Þ¡¨-N½©N%*ÁìJU6ëJƒ­:¤ÒÒRÇŸü5©×êHŽŠ’Ôê”×SDêŠ\zÓª@S®•骯֔5¨¨W‡EIjª¤MN”U :)qN©ýt¸&iN¥ ˜ÃRZЏž§J¤€na©#µWóù*tö&¥Ät§Up?=Á )iOR¸•¨ëWMN”ü à`šUX !ÞD'Up?8xªt¦®÷tR⮢½©×µ\E;AÔ¬ÛJˆ© ÚÒ¢u Àaé¥Dè ¶ðtR¢TZÒIkBJP…š¼/¥«%ÇNû•‡Æq¯ÍÝóûí˜ý«wúyÝÛC÷Oû:Ûô,Y•Øì%jËbS±Ø>J¿"E›wˆLî^AÓ2äðñ^ó•ûmÊ^Ví¯ØÿÕ!_˜;üÿçÌßí{ÏÖ$]:}+}-Z•RǦ¤µ:«ÃŸü%©Ô¥¦ˆª@Sª—…4 §_»Jƒ©:¤íÓ`÷iRZV}p'ÁܧײÒÓÈ®ÏYÎP5Èü¦;aœúBË'E(™.Ñí^*MN‹}ºBxo;9³mËl3ml‹_¹®Ú{–ô÷lè38uÐðŒwO}?–{ãzd4˜{r †´ÖãÄF ¥^EHoG ýOÚöE³í˜èf­áã3lÕ„dB ƢѓtÀ­Ù7*'A"9@‚0ˆˆ˜F¿2²yœŽw%%õã-ËÞ\çÈKËœOð$ý<P_qãñVx‹&ZÛ€ÈÚÐX@ph Ãô®•ÉR™mÙ26oÌòÎÑ(n¬¼œ˜,Î(«€êº†kG*ûýGUÓ7€+rÛØ·ºÍ×Ré&~†ž ÆQϧPÔâÆðþˇjÕ³™Xb¼À†²&kpë/}ZÀGI£Cÿ¬Ò°Ç%ܳnÓ21Ò±=ªÄIwÒë‘è"©€‡8™ER€a0ê¥{ÙÆØDðû¸åš€ÈÅ\HãØkà^G¹2ykÚEc¦8I£žç^.  óÿ(Ý ­rN¾É¬u’¹&ÞÛwMQh“.™"£[î.ýu”Mªc¨¡¸Q(W¿m«ëo ¾)ú#·´p:µW¼Ô4P¸öñ5â¼Ö÷\×ËutÇÈ纮0=”#WWàà†œ´KÙ踟ï`3¦poܧïùDp»dÞ †ºŽœºÖjò×--Ö±i`ÁÒ5½ 9ÞÑoÜÚ>wÿ…ßåqY ¶Ü1•Ní’Id M !8©Í®ø€¬fG\ᨓRh™€6W}˜Ü–÷‹8ÍGK$‡€8¯ŠNšÐ[pxtU®ÿ%h¹ 2|ù ‹†Ï $S1;6ÇRHñŽVLM¡Š²R̘$s¦ è Bòë aß·¬ -’9¢ãSâêÿêýwºmÙïƒ8}`E£Ì„I¢Ý\q²úìÝ©K²ìǹ0ªŸ`C9ng ©ÄNQÓPä÷_û”[²FØÊÉcpã¸8pã@hïĹMûæ{ ÃÇ´ý¡Ðxý ò}|Çr LfØ”O(Bo71Duôg €ª¡˜,n›C å/½ÔµÖÁenðwBXxÛ»í0žŸiÄ~?É’³·ÊÀbž‚Aö\:ùâüKß³{õÄ|ƒu¼j ¦»u‹¸¡  Aï”ä1G¼bˆr {¥…í¾JÕ·VƱ»ñ°¼²öÎk ƒo8£‡AíD/œê®ÑjëU()×Q¥:¥*›¢•;SªPS¸)P'T ¦Ýz{õ%©Õ()ÕRZR‚u{ª÷¯ÙâÑ,ÙÀ/ü>D™²—‹är<\{E쀆É8ÑË>AÁÌ©@¡ö–Ðj;©P u÷ÚüüȶM³Î]¿¼gÔ1Õ¹.¥xÚܹÓ4pÿåHÃÛãpê_[òL³9Ë<ÆÚ‹I¾×0èž¶'?üÆ?èñWçfÄh´y2|ÕvR Ü.Ñë7h¨ÝÛGm”2.9n±Hª¬A)ÈpÀ !¨WÙûxÅ-³fˆ‡FáPAx‚àAA æ\À’9Ìr״Ђ(A ƒÐGEe‚~A­ˆµaj½Ã⥠`¯bõ¥.Â:äÈ XL££]ê›Ôeî\¨læá’ÈDÉ8a àªû¢‘ɸmÈ?Ÿ8‹¶oæƒ!ŸÆ%…£æ«ÛöK!µÀõ‡<´‚:A¨à¾ÃÉ[»mòÓ| .îzC¥œÝ–‘ÔZÀA Š+®1r˰Ë35š†”›O|†›q\‘f$¡@@wN™Ä¦ð€ˆ%wwHÕüÍãôxÿV™upœ‹¾#ÿœÿÓļ&³­”ݲ (mý7ŠmD SwÀ@C”š¾ÅÆâÙ45“Bù²úùÑËFp¢ý5ûDÈÒköÌZõ;ɼã¢îWoÑ2¾.¸S±~ÖíŒ$]B®ªd3„ùNB€è:WÁ¢ž|]Îõn ‘XÛ“iñkœECÑÀWIì%}qÌh¢¿‡kœˆ«ä½ƒYpãG÷]åGÓýaô.Sí0K€ÙKóEñ…‘rÝ©6ÖÒ‘weDج¥œA­þdèÊ?]V6eƈJ.ò94Õ(¬C(¤"@ÉË®hZbo?‡ö¶ZÉrÑ3¦-ÖÖx­ã4g@$p"®w¡‘æ]¾Ã¸È[|a=ÜS²Ûqn’ïðþ1-ñè à±ÝþÈ^²E©—1ÞdÎ-î«AÃLJ’†¹]±pœŒcØyrMÇmtÍät‚©œ€¡@Ú€€€ z~æÆÿ0[³>/Ä}ÃZ¥ñ‡.kÚæ“rêæ‚ ÑpwÜÛÙx²øë숼„’ÝLyiÔÒÒŠ‚ ¨\<3Î(ÏÞÖü;‘ð¼Ë‰ÛRåb¡&ýÔ ½¼à×$”#¤Ög2Ý£¥Ìœdk0*À˜ÄС¨F²X=Áµ?—ì¾ÞÜ1ˆî¢†rÖ‡¶A¡ò5â…„ã9ü+ZÔõ®•ÎW¸9ÃŽÌáž_o$‘T–¹‡[X暇OŠÆ”¥RèÏlC5$xî’ne cðï€Íé„<&0HÖoùq·3òþ޾Oþ°X¾uÊ"Þ»¯îÑAYí쮈J/„þ.Ûwˆ»YU Aå&ñ±¼± ;£ÉïŠPç­+ù‘´m¦ÿÛa.kOÿÔµm’¸7C6]ÐïÐ9|>ÉiGÐüqauÛÂb^Q.¯ã]62‚ûÒ qRrvà©(UP”t±’î˜Nch:€içémï16å…ÿ,ˆ8³GÝi“§‡µ ×…]ÞPƒk³3Wvœ/Cä Žš²Þ¬ü&ŸI_Ÿ»NK…Êï_ª¢¦UCœçPÂsÆ0˜Æ1¨˜Æ0ê"<µö>6Ä]÷ý•óMõ×p4·¥väܦF‘†´Þ_פ¥è£jI]í¨Ï@ID|_éò±l½ LD»4‹ÙÂÐB¸Û´qVye,­mã¿}uJØØÙ¨ÕÚžjEMOÒ©Û‹!sdÛ ©æ}›i¦7=ŧF’Z(:(8ìo¶ù¹Åœ!·ÝÞ`1m»DD»Ã§6£_.±w»ƒ<ÞºÅúI×Óé~Œ>%ÝT“ýH—KûíÔc8Ÿrô£ª‡Äwzb#Ìy›HÃå-zó-bÛ~YE(ûG%ÿòæZ#®Ý6ú’>¡c/úñ.«šÆ¹+4{I³¾5Æ2Î`®lÍ’VáIëèä-Ø6’O×™–xò8Åv›dQp²„D=òY »¹ð›K“69ÃgÇEŽ·¤E­y–G5¡Œk]âÔº†§ì€^x4®žk”Ü\Í»Æažb½’öjÈ šÀI{‰oƒíÒVReLìÔáÊèq Ä~XËÙ¿0¦Vn.¸¸‡ÎÌf«,͹Ð+ÂÆ‘bÌ«Q!ÊÙÜ뇤DH"A Ÿá÷G:wͰÈìü~7¶Ü\!t€P€ã]:«®†£S-ÚÂkÖ Ü2XWíIÍ–ä¼¾ÈfÀëXMA R´¦ž:]3œ:¨³G‡Ù~dø,â¹Ï öíßmY¨Z¹H—[Åg‹¾^ç.'2‚ᩞÎÏœ|TfåÐ o”Þ÷Â>[½­÷Õ·1°mß“ÚÏ’ïmŒfDzè4Ž?V£ÐxSŠß¶´ÛN}•–;F+ˆ¬»¹ÃĤ’_Ütнü4Ó¬q¯†žÃÇÊ<½3ha0’Æ€ÓQ×ûý@ÿzŸó9!~×ÄWÓ$ý^Ȇgò4ôf®¼\,¦/«½G*œà7,àŽñ„DDej"""""5ôvß²ûŬZº;¦ª‰æn»›‰4ô÷Žþ’½ÈâíG{$¸lTLvW.4d™À¤&˜Cß Z§¢e!Dl ®š›wQ—¶” ´þb³‘EÀ5·ë/…Çð’Oô/{Ürºã’¸©$âI„~Êâr^1ÞšÞöGpôÚÜt¢,nìI¢·Ð©»<­¨þè–nçt€BÝHAðŠ©ˆˆ÷ñ›I.ÿ˜,ÕÅà­Är_ÒelL#ÿÁáÿ„•ÞÝlm¿'1pÛBöZê êÒ8ÿ„/ð]¨Ý{ç=Xw• ÞÑT{ûÅŸ7ø+ëL¶9ŽÛ7Ò;í}Îcÿå¹|뎽ss¶‘·£ïQýö¯_½¥ ãd=¡Çͤƒ’m£æwÈeSø­Þe‘o 'H c(ODTú”DÁÉ_'rV[›~Xn›:ýé‚åÌ¡§ŽÛ0[Ç«8¯¡ù£oÜ,4û»ŒßøMÉüUYíOéçFqi2­¯4…ªýÍe4•^hÇ“ #$ùc²´n &³¶)¦¨v¤?bŠZ“MÑ+”—<ɵÅÝü mc-«î%tÅ¡úšÏ¼eaÒ‰«Ç¥mƃcÜd-þ-žî9Ù îÛqn’ïðãQ Ç 7‚Å,5uû(pFAµò­ƒ—s;{žÓ]Úñlj¸2pœ„kÈ—Í$£`5QËGlª™È Ž÷ €€W¤n,w=÷FlWŠ6€¥ñ‡.ii7ÐA¡ZN÷”˜ ¬Yl}î@]ÂM55妭- $OZÂÞ2óÖ6Î\UÜYH8•´ç-ËE³™'1p‹»šˆˆJ%ÙÖe,Ù«½äZ³A >àÄL4×JõžJás›[jEƒÎ´2ê9¥!¡Íx {Ë… IIq¥zJó®idñ[ƒpÉ–Ä»U»âŒ–’æ·I¨p€tu.´M]JQäå½Öœ*¼’©ÁMºt÷©Sµ:¥;‚–”êªm©-N©ANà¨-N©AMºô÷êhBuJU:½Ê^ê”î T¡:¤*›jKSªPSž µ:¥6øûµ©-N©N~J\SªR©·_v¦:¤…"Ôê”ë©-N©áÑRZRǦ¢”èN©MºtÑáN©@ô¨BuHz’Ôê5%©×± 9ô©-N©ãÓSNÄêútÒãÖŠ¤.4€p¤ZO… yêKS¨W‡†§J|UÀÜÃRB*Î*TìM\Ì4¸õ§T€z8pW…"©Wm©¢ujà~zZS⮩¡EUÀÂjhª¸<4´¦®Ì4¸„T…`8ÑÁ:޵p?pQDS±\ J‰ÔŽ•®´¨Š‚¬šTN[x)QM Ξ’ÞTy×T|f~noŸßlÇí[¿ÓȾîÚºx¿ÙÖß¡bÌþÃg+V[†Ï P…øòâDÛ¼EgÀïfœ¦+æt+öã•þVí¯øú¤+òû˜ÿ>fëï{ÏÖ$]2 sÖýÅj5ìHæ(ð§áH륧±:¤ó›¤µ:¤óù* Sª@>Þïr¤µ:ýk|·â\sQp1ÉŠ¯e^ É¹wL`®p&ù€ #¸™DLm<5׺¸ŽÒÝ÷SEK€ ®{x]q3`í8Óþÿ©~½¸c¶m<€l{R%©A`fÔæj‰H‹éiyUP;éG‚)˜ÅŽÕ/h±À@‰ ]wJZü§æmþSzoÛì•Ë¿4á¨ñk#`!¬oê´4t¸’zI_kòÎêô!‚6Öáò¸5ƒq$ç“@]C@Sä̾ò,î—q:„CxöÏdSh†úG~f(è"(]¦gæD†ß16ð€—NÿÚÚ1]†²(4’9¬.r²„A² Z‹xÖ¨¨‚@& •c2”yké¼&ÏÅ lÎ2Û‰mÚÐØèàÀI5{ˆ'ñEI¯Bð»ýÁw5ç} od‡\ƯBå¾ø»ØÙᑈ,¤&Š´ÖÊÖ£¨=‡Æað·ƒ\åéÍñ‚}Ÿ|vÎHæŒÄu·„rMÒ'•¾lëŒ!˜ªöy]Õ_ÊLcÙùËfU„Ë•Œb=‹xâ-ÒÚ®PYS(ªß+í~`s’¬nÙÜøI²¸H˜dŒ¿ÅgCZˈ㕎`Y¬l!-h o¾ç¶.yœóœÁe#Çå%ñ¤cÃx»¤—B÷ÆàãÐç±åŽ>7ŒI.ú¬n¸áMã<«Äo–J=ºdåáìÆ*¡õû1:ÈKBvﺯpEt@ÄA""Øç ÕÓQ1ŽSp󧛼ǵ~ÜØ›zëà²K‡¹ík¸Løà†Þ Ð¸—<,s]B±ønXòëeNÜÖìÌ[ß>È@hipâ+_,“PŠ€4´žp^RûB¸ã–ã{*C#n°‘€Ä6½ic@?:a ùËó ·dúmŽ«rJÊ¢I¤N©¶LSçXêz7(yW/±N‚W6|ýÑk®%h:@mtE4:RKˆî$hn—Ì]ÿ.ñÈ £k¢Ä[‚!cˆÔkö¤}8juÑ@I.'Øþ -Ì?5즻í|ù>½§‰¦nKª&î¹›8]¢öñdnË}¬4ÂnjøŒuÄ«EDë"«RupQC´ ðŽqKŸÆsþÞãkÄ'ÎÃi⌀CôÃ!{%µÕx !Ü|BEë¶}Ê ¡ÏHbÄÉq+^ðH,¬Œ u@4£ôž ·ûCMWGbÿfß6 ÊÊû¾8Î÷¦ ‚]ŒÉ´˜¶#]\°È,ÅÊK£xHÄ·Žv‰®»AYGd"u d÷‹¿æzÝàßÁmœ¾î™† òÙØžE ØÎå¯/oÖ¿KXhçíVß“›^ß*ܶ[;e.݉ÂBÐX×HÐjçw¥¡§€qmK…CCIa?´ßXÎ*3ÅšÏ?yúk…SxÚɸ‹ˆç—<“Èçs—s6Ë$Ýã&<+$b•`M¯l%LVɳrW•÷;3oÌÌës™";*#¡Á’ kG½ÒiWiÁ¡ÇÍ ùæËÆìSœ1V@ˆŸBÒ÷’ ¤€@ñZ7Uu£mãÂoµg XæXÊþâ{£Ú4}8´\r K=lÙ¥ÀŒ#i×ñ,¯.êYšO=³ä¥#WE=MÙ‘Auä'nïÞAn»›¬MŒÙ]“tî†8è–k,kŒ3D f·0Ç &‚¤hôoï£ÍÜù¸ñû¦Òí#Æ è-Dò´5Áì q :øîໃn fÍüFñ#‰2ª6ÜdÉmË »;rZ6QÛ¶.cÌämG2÷<å(FNŒ-š¢Ð‰´rb®e³)Ë—ÜÜÉæ2웵v> !tÏg{rçH×4Nô2&BÍCÆ{žKÛVDv dlítwéËYÞÚîîÖ88E{²é+¨|V†€×QÄð¨Á¼1±®BöÙyµ¬Ÿ…±²¹5høÓý´-›J؇V.%WjH¸÷o’hW/TÞìý-ÁÀ`Ý0úÎghe1|“¾Û }ÎW<,ð$šY¥|šÜ©Ik+¡¢ …ç˜ÍÇaÍ\뙆 Ý´†’ÈãŠ6³H.#KM58ôjqâQ{Q/Ë'!ñ¹%qãûÆÖ¾­ÓØV3"OY× MÏ wº#¶…”„vù‰œ¶1€Lß ˆoW_ùyÄåpÛ*,ŵť躘˜æñ<áBXð×Põqê\ÜäÈØd÷D—XÙḵ6ñøÞÙP F¦’*:ÅVsû^4,ÕR¶)7Ì™€5ŽšO 6îàÂçóRæ¬o,ã™Ñh3Ã$Aô’btÐê ¥hí[O83X|¦2îÚåñ‰5ˆ¥d…µd`j qÓRM:bàþË;öÈǹùiûþòµlhÆ7;›¼n‹f _8”¶TA˜IMÓü=bÛÙ;%ÀàÞ$l$Ϋ7s ưMIM[7ŸN!¼Ûئ7ms(Ñ7`ųääã–@‚cd8ºÕ€ÞüÝ78«)r{6åßÔÔ|@If²Æ¸Å4`–ks rh*@fÀ2ûWšø È]Ga¹àÖ ñ¨ô‡‰#}5iax]ÇpÿÜ"p…*¦fâˆ\Y“’·c¥ËoÙ5·å#¤Ý:dᜠ°æVã‘»¤ˆÍÑ…»dš\‰V2ƒÙ”ÅÊî>aï¾bÙ·llÌ%ýƒ¥{;Û‡:F¹ êw‘²ÔxÎ/%í«CF¢C ³6–˹9íÏ•´»µÚ! cƒ‰WAsÝ#¨|V†€×QÄðªò+äÛ[2çÛ!Ú6\=…mMH »iÂFEIJˆ„‹bÖ*8ª³‡nÞ<²O[²/0‹¥”ÐÆ.ƒ_Jl Ûwkˆ¼¸’òþ&ög¹Î/‘Î.u Év–“¥•㤠€W†ï Äy¬¼ù+hYmg#†ˆšÐÖ4¶¡  D N§õ‰¡_I¡J +Òx-¼S•M´‹Sª@S«¢ µ0R‚SBªPSn=ÚR¢uJ sÒÓØR‚›j SªPS«¢¤µ:¥:êhSªPSn4¼)Õ()S§±:¤*›jKSªP?pT–ª!TÛ¯MM(Š¥:B—UJ uôTÐU m"Ôëõ¤õÔ§T€}ºwxªKSªP??’¦‡©:¤9† uJ¥@zª@?0Ô–§^Ô€z‚ÔëØÌ:l©-N©üþJTìM ˜{¿ÃKÂRùéP„+Þ‘ju)ãRZGR¸<5:Sª@8óëRZUÀüü”¨GB¹†•{S¯j¸ŠŽ ÁJŠªUÀÚxjHEB¸ž§J|UÀÀ=á¥DUX !¶¦5p8tR¡M\n´ªBu*àq£‚8+‚Š"ŠÀ4¨Hé^€p¨–ôY‡Nú‡-~lï¯ß|Ïí[¿Ö$_víÝ<_ìëoбfŸa³ÍÕ–ÅE; žhЊ/Ưæâ?ˆ÷´Í¹X9Ê@ óßi¯jòÙºšàÖ88p=-5 ±c,bg5„jèýÔ¾»ûÓa¥ÎÉP;£2@ñŽÖ*B¡Šæu"V]Crœ„\ŒÊp×@=«¨î¬>ðâwSJöþ4¯"– ‚+¡ßˆ…ÆmÉå‘I2ª·ìÙ9;6.Ö§!¸Š.C³n¡{6ŽJEH"tôï×ýÕ£".–Hõ4ëP=‡á}*íY+ŸÝèêtp¡èãÕÒ»ÊÖ™›R5{_ Ã9go$±¤XJLöq-Ù–& #£ó¤ìL@Ý¢(”ÞQéËZ®FLtÒ6ç 7nÚM#¡Ôé¥WJÊÛÃsLw -ŒW¦€Ôq¨·BÜ®kË5«3p–½’íV(*ÝTõåÝ:'ÿ(w‡–·,LϹ°c¥¾+‡ao¢e mµóÚÏönñ‡€ÿßTeSmd V:©ANzšꔪm×§»Z\ª@S«Ê´Õ:¥:ú*KS)TÛPZUÄÀr‰L€†ƒPYQCШ8Ž ®/iµ~aU0ÜPyuAÖ°×xˆç:›Ò²vùÅâž…°Èpcn™c‰5ïj=êÆÿqÉÐOÜþôe*ªæp–ÓXÀ@Êœ£§~²v˜¸­øÓŠèÜ_¾nKÙhŒ­‹{³>1ÉV ~F–•”<^?{xÛ­oyÔÈV{ÔÔaj/"Iç„;6Ê*›s¤™Œô¢!òùÛ[‚oæZÇ9…ã°M‚0ë‘ ¦‘o3H3÷`‚@¡wI¤¯£¶¦o$.ñR]Û7*é^D&V H3FA—k5Ÿ³Ð ê^Û–¢®™B(bƒQ¯¦¬q/’M%xeÞA¬’…v,¨„z€²žýNþ¦åk5iŠd[ºV.ã éF‘з‰ˆ²‰èb†ø èÏwŽå´ë\V÷„Ô.2À;€±û=ÉäÒ°ÇúÒ§JÉz7¦œW5‡·[Æ¢bœÁ ˆÖNÛÈJq]ï_3«Ôí¤Q~/ü¡6õq·ÖÍÞõÕS¯œè»µ¿ÊGI° ~PÐÉ]‹›a‹¹9›¾wÎ&m­¶våõ´÷mÝãô±Üʘ¢da¬säuK†HpÛ0{iíLŒYüînÒx­Ý®6 ÔáÅ®á$Ž~“ã1µÔ©ÌŽ3øoŧY&«¶Öd$Te‹bñ;7ÊZ°¤^' ñóeff%Þ½Gß GLÂ& ˆû_(ö<»'nɸ-vAï3N[Å¢G†‚ÐzÃÖ2¿Ö-$p+Ëyº£Ý9™r0‚Û6°G<¡¤Hê.sœêuCкÆRÜm,Ô…P ƒ§.µí· ¸`í/,†íð¾ ð\8,ÀÛ€±û-{ÚòiX¿îgÖ•:Wûͧ«ŠçöõºÞºŸNQQÖ²V¶ ·+£qvé…ÌJ§Uw WV©ANòR¢uJ mêT Õ()RZR‚›u¨-N©J¦Ý*KSªPS¯¢¦…:¥*›z†•uJ uT–§T ¦ÝjKSªR©ÕPZª©AN¾ŠT(ªB©·¨iP'T §=NžÄê”ÛÝîÔ–§T€~®Š‚ÕUJ Á©¥T ¦Ý)xUU()J€ô"©û{½Ê’ÕUHç©-ERüÃÔ5%ªª”çòTТ©NaÖ—´ÒéiìN½‰@üÃRZ{UÀüõ%©Õ ˜zªKSª@??’•èM!OÌ4¼)Õ •èE{ù†‘ ×µ zjKS±\$ê=5%¡:«Ã¢•M yéxQ^Õp=¯B~p7w†¦‰Ôõ«‡ŸÇH„pêWóÔéOЏ0Ò¢*®-Nš¸:)P„Õ€iU:•èÏ ÉoC”t0¯Íõûï™ý«wúÄ‹îí¡û§‹ýmú,Úì6y+U[†Ï%_‹Ž' »Ä§¥æÎ9d•%¨ª@8ôÔéNªàpèé¤ZRƦ‰Ô,ºÀ²ní“°s’®î¹†êFYé²Px9 7mÓ‘¼£9)D·vÑ&{ÅÉu= ¢D5Ò÷;,ïíÍ•ûÚÌcf¸ÿã2&6ÿhx²½Òqš;£Q![Ö"9mìc’÷Ť´ÿd¸ŸÂ;Òõbâ¾,¢ZSØ®Š!bÏ02“nc·`÷ã çOdä]H¹xåc‚Š*(î Óå•,ðÙÙ3po9|Y¥¿ûόǚ½º"kXƱ­hZÝU¡è[ìw°Eg&66-ˆGÀôõ¹Î$’I4&€à±êÊOcI+fÁô)ËÊžJBkµŠX±æ`Ì¢éI4gÔC&]æL"";Îç¾›rn(ò¹ímŠ2ØéÝ3V³À¸¹ÏwŠ ñkAÂu1ï8ëSmdiª¤“ýcBßM+Ú±[+ÚºÅUäD¢AA“täRNc³ª›ÄXÇ•”I”jMÑÞÞß2¯x“—~Âgv´÷ÝÙŠéÒ-% 7‡M$þ%‡¼°»kìãÓÇ£²µXH³"Oª¢· ÈѲ+˪V+Ò©DD=ñ‰p£aŠ;½ü3Õ±ZÈ!¦¯u‰‰%•¥¢wzš½»v´”ÈÊ”aíkqÂÅ“¶žÄ¤Ôc6…AÊŽ»PÊw5Ð4Þ×½ÉZ”ù˜ÍÀö[#ƒZ$ÔÒãSð,£E§Ü¦kÞtpâ8žž¥Æ®; 2¶mEfßM̵E»øÒ¼·n¨¶äUÂnÜ<1 Ýx¥ÌàSéÈ`(ià¬Ø›q\Êö°C¨#[xPtb½œ+ÿ¦·ûnH\Y¸b ÙÂÛ±³íˆ`Ý%ÎÌW v…)ŠþN4‚`å×R‰uõsœniÃSîŸÓý ªeÍ›>Í»^>’» ƒf~›Þ"Ù´4pDníf—fRM3iƒ„‚8tÔG”G¾нÆI+÷‹«‡šIOÔ?Ì»L¿ Å ÞÊT­W:Ü-´½¸ª×1m§O"Z,»¸›RÊ¡'èm½<ȶ(ɦAtQT8{”+·q6RÙß’{~Ûº*hhMkÙõ®Åíëû÷ËÓV´ô V”!b¬­ÓsK¨ç³ÌkªíMÙ€öZÖháqђﺆÝ'€qúÇêXæß]HÆ»¾&¿WÔ¶ÛžàNï4¡4ÂnNÉùݱtäȱ"ï cvÀ€:Q@ß05åÛ]KhÙ÷'21¡Ìs™ÑNƒÃ¢Ÿ÷.Ôã/‰.i wOhãÓÚ»/¸{öpÌž÷¢ä´ASDª·UC¹HÔGû$Êp&¥8sVW÷eþ½ø¨íô,&ᎌ†N±©§ê5 °ANºÎÐ-f©M¾>í)§T ~%AjuìJ s IjuH TЧTÀ§]*êÛ§¹Hµ:¥÷AjuJU9†¤µ:¥*hSªÙeâ“•(úò t/,Ûr(WnÚäÀVáÌ‘È%ä »ka4Ž…3Ìev¢·Sú¹ËW R•Mµªª”ê©¡N©AN¿%*'T ¦ßN”ꔩ-N©J¦Ýj SªR©·Or¤‚SŸÖ¨R•M¾:E©Õ()ÕPZª©ANº‚ÔꔪmñÔЧTÀ§WE*ÁJU:Ý©-N©J¦Ý*KSªPS¸*4§UµËF!*€¤§. <¾}Úê\Ú¶áš\»\:T.¾=‚ A5L ˆ÷€G½­`Ý…p4i:VU¹0EHâ¹½k¶ˆþÓ@2Ÿí‡”u®ý¦5–ü¬º—7¯›‡Rç%S@Ъ²«¥T §UN’R‚äTN©A]¾:šê˜ç©-N©J¦Ýj UU)TÛ§¹S¤§T §^ÐþŠI‚”ªmñ÷êhªPSª‘juJ uÔ§T¥SnžçôT§T §pRLÄ¥Sn¾í*ê”ê©-N©ANº‚ÔêªmÓÜ©-UT §?“ú)qLÄ ¦ÝzjhT §U"ÕUJ mÖ µ:¤6éRZR‚u4!:¤*›téîÒ—…:¥)R½ Õ(˜jKQT€~z’ÕUH s»Z‚Ôêçä¥Å:¥6ëK‡Z*´§R·ü5%©×êH N”êÌ:ô÷kRZRùù)P¦·^ï%.iÕ •;^Ä€naîè©!:ö«úêKS¯b¸<¥I Õ zjt¦®Žš8„ê4¸"½©ôS±?¸¦‰×µ\=5$#À® -)Ô«€ó I©ÕzcÂ:[Ði9J>2kóW}þüfjÝþ±"ûÃgþébÿg[~…‹7ûÖ­Çé[GŒhãô¡~'8¢6œLñQöuËɲÿ¸¿p¹LßùU¶áüwêp¯Ë~`þþç?kÞ~±"èÐ0†·ò£R4¨B¸„øõ$s .íWóù)iM\ Ò¤„ê»âؾ$¬·ökæïå±R)á»n–nÖUË9-Y®DÀP6ìТUDÁ¾dÌÐy5›üU¶V) {é èK€:A”8}!•Óô¯B³•ñXC§ Æßõ?γ/[ ú䞺̻‚,Æß¥p+µœ3)E”„nvM¤ÛÆÌ‚ÅÜpÕœ„`.;¥WU›PPÇï‰Aþµ™Û¯{îd‰ä9Ѱ´‘Ð\ uôW‡Ô°»™´²ü@t•´ Óñ.. mÒ¶ÒÕ¥U()SNÄêªmÒ—…4 §pR êL…SoPÔ–§^Ô §UIjuJU6ëPZWzYü5ñ[äºìœ•®›id޳YÈ+䑌M08œb¶Ž:RÂQLCF¨ïh]5Ò²ÜÆØ8+ó‹Ìæ±vÙhèå¹…a4ûm/?×ÓÃBÙñû3wemþ7=‘d9®èÚ;£úµ]E%' ò&f=ôL¬s…ZHFI´pÂA‹´L$Y³Æn“IÃg 41R˜£È![e½Åµä º´‘’ÚÈÐæ½Žcšz×4Aê Э~hf¶™Ö÷ tw 4s\ \Ò:A„ÖªùM½C\¥«Ž©AJ’ÔÁJU9† µ:¥:©P§T §@ÔÐ'T ¦ß"Ôꔨ-UUÝ–gù÷!Áý¦±°ÎN»-ÑŠ36MÃ#ðSíRG¾nÀíä•HɈˆS b€é™Ž`lLï÷no1µÈuÇ-ÄL{kJkiuX x©l¸ÝŸºòö¿}Åão§³ê|pÈæÝ$6ާXmHúÂêéX¹{~Mì,ô\”Ìkƒµ’‰—dæ6J=Òc¢Ÿ0z’.š¸LGßBÁá Ùín­oí™yc,sÙÈÐæ=Žcšz \ÒZàzˆ$,ŽŤñܰÑÌsK\Ò:œ×Aú øÁN¾Šç \UJ mñÔ–§T §UAjuJ uÔ–§T¥SmM uLU;‚• R•Mºûµ%©Õ)TÛ¥AjuJ ]Iju]fáü¿‘#šÇø«$_PÍ_+æZϱ®{š1¼š-Ú»Z9wð±oZ¤ý¯QTȘà¡SX†ÐåÖòû¿iíû–Ù粘ë+Ç0<2{˜aya.hxli-.k€p%®¨+7ŽÛ›‹1¹ÄØ^Ý[5å¥ðÁ,­Òæ5À84‘ZЃÐBäR|;ñ #55‚3444Cr’ÒÒ˜Â÷aÝGoäd_»ƒE«&,š¤uYS4Ó(˜Â5жæÀ¾¹ŽÎÏ9‡šògµ‘ÆËËg=ïy kÖÈKœçÐ $€Wn}»í`}ÍÎ+%´l.{Ým3ZÖ´UÎs‹kZ$’¤®Ÿ:ú+n-Zà)J¦Ú‚ÕUJ utTéìLÉUµî¦ÖÛ+É͵>…¡%$´<}Ö¼4Š6ÛùvégL§Nرn¤I#èS*R”DJXæe1rd_‡Žæe£ŒHøŒ362@tUÖI8€ÒH¡]ÇX_²É¹'Á3qÏyce,pÏK%4— - u-Û§Mw¨ ê×µ0)Ü%©Õ()·Z‚ÔꔪmÓÜ©-*ª”ëÚ(¯bb©·Çߥ@SªPSª¤µUR‚u©Õ)TÛ§Oz¤´§UºEGÊMÈ3ˆ…/- ¹0ŒŠhâBAó•9nÍ“TÕråsøB˜Ãà ë]\ÛY[¾îöHáµµsÞàÖ4’ç8€í$Ío÷S6ÞÕ’áækAsœOPh“ô»>êÁY²Å‡ûCxâ|‡mAµ˜š´g#㚊›€™æûª8çÏu:t´:®œKAë ;Ú{£m÷Ì–>ò N·¾µ£ÿ-£~€ê~%ÕeSn•´­~©ANº‚Ôꔪmê’ÒR‚]•U)Të÷jhT ¦Ý)ªªPS® µ:¤*›z†§JuíJ wJu[¤T|œä‹xXçÓòncÑÃù)®T*MÙ±bÑ5];táSHše1Îa®½ÕÍ­•»ï/dd6‘4¹ï{ƒÆRç9Ä5­‰$€Jæ·‚{©ÙmjÇÉs#ƒZÖç9Ç€ h©$žR¾‰h©{zMì$üT”Ìjæk#0ÅÔd›$Ó}»ÖRAÓUɨjES½ê‹K«L…³/l%Ž{9©’F潎ok\ÒZáô‚B»›{›9Ýkyâ¹a£˜ö–=§±Íp Š¯¹Ý¹rÇBCܲüÛrâ;äíûäKö°“ªE¸3I4áåVnFgŽtQIpACŠ*”ú%uâÈãn/fÆÛÜ@ü¸i–&È×IxÔÃ$`—3[|fêPâ*$–7ÐZÅ}42²ÊbáŽc„rš;CÈÒí'ƒ´“CÀñ[@)·Jí–®µR‚ÁJ…0{M½CK‡ZuJ祧±:¤íî÷j Sª@?pT–§T }ºÔ–§U¿ÅÛ×Ó ™Hx ¹XËq²O. È§ÏØA4\çMS/ «x¶Ë(™ŠE2e0”@Dº79,}”ðÚÞ\AÍË‹bcÞÖ>WRØÚâ È  ·oc}u ·°Ë%¼ ‘ÍcœØÚz È0P´‚uÜ ]T€p¤Zª¿Z@8óÔ¢£À‹UU yõ¨-EUÀáÑKŠi@ý~Z\ð¤…Sª¸˜jHE{Rùêtªª¸˜jHíERÇÃËS§±5p8søèâRÆ—pW…*'Ç©\ ÍH„ëÚ½Já-ë}°éßI!ñ¦Aäñ׿ŽüýøÌþÖ»ýbE÷–ÏýÒÅþζý sv=ÚÖ©ÿn…±)Ø÷kGýº¿ ó—Ão&A¸k÷”£þUmŸø{úœ+òߘ5ø÷9û^óõ‰Dƒ¢½…jWxjH Õ\ÏKJÀÜÃRBu*àq¥Døx„ø¬ýáfÖ°²L;«{#½fÙx™f,.ÎÈPP¥e1©*Ø®ÖE·¤‹cœ ¢NÓ7¾˜µáüÁÍn-»vëœn– *ÙÚ5jh5{ÚŽ%ºÀà[N{Ô³Çå,!mì¢'†Q„Ò„´é-5 vÇ¡f]ÊâÚ‹;´Å™êˆç|G tìˆ)»bš´D…&ºróù~,dïešNíŽ"MÀPº¼ZâOk‰4Y›è ¶yŽ*<4‘¨Vœ:8Àº=ò-U6ôö†9Îc&át\{³X"tÛ  S€ººÖóo$ÌŒ‰t:ƒ¨Ö+ÒOWÒ°R†Ö­è[S(øÅc§"&£[º„¸Ìñ)ÖÆ(œ’MÙòÙN]ôÑ @£¼÷À 4ï"/s$µqmËÓJñ ð÷öp+‰²¸¾ÁXÃ/·¼œ^J䘈zví£!Ú,“uaH¡Ô¥ èê&w*¶ä1S\Û†ÿ-g¡Ý»Šä‹(àcdŒMzOgi§«é\BÂÑÕsÜü:ðùkaù †ç†œuq’êdÍ87Ί܆g¨Û–ªº§dºª»L¦*Å0ˆ<5ªîLÕæWL tN:À¯:EOObîE¬žéÇU>•”ïÛBL£gì“{ènÌ".›”ÄIôzåY£Ä¨Š6] ÝÐu.µ©1·1=¤º­ =GªŸŽ«•²ž£Ä-åÀ¢šn7Žeç÷¤Pºo Îrˆ‰Í®¿äë]i-ËYZŽŠPt ó®Q3öŠÐË‘EWQ¾è”Ü@ê€ t€Â:{ã”F˜Œµl½5¯ƒÂ¨=äTNÅMÅ`0‰È¡•ô(¨•0H»„1D…0‰‡Qðìä«€é#Å"”êÝ)§T ë ‚Ôê®ÛÝîT–§T §=M uJU6õRð§UœÏœUgåž#áÓÈlI/aã«^éË7\"‰tg#¬v$vÖ)Ëeqã'.Z‹†æ‘Ër#éÄCÆ9õº2Û[—³;!‹9¹†Æ ¡÷.-sÁZá~‡ 8µÀÔ霦ÁcóÛÂ1–h“g·R³¤=°¶¡¤u´¼·Sx‡6­"„® •øÄâ,߯¯—Ù*ñ¶ {[^سîy»rÛ²#˜¥Šˆ¶#"1lÁ(ÆÉ&Nܤ œ¢§2‚&¬Þ×å&ÄÚØ6a!ÇZ\šiáŽY®^~Ü“=íqqy$é'KAÒÐX¼÷0·f{*윷·xß›Ž_p´}–FÖ††Š ©ÄUÄž+(3$œNðAmñ+y&ƒœß‡rÂXZø¼Á² ¤r‘)„ͯ)q(܈¥!7åê “WtV2ETê‰Ê!æ»FѼ¶çEÇ.±ÍÙy|YÈ[[Ô–ZܲC̈Kc”5Ò×Hq`m(Ví¸®½¹gòÈ€íÍŽ¿sM@q ˜¤¥žÂàÀzHÔOH_~Vàç…®®è[S3q?v%!u[öôÜTU•‹BfJÙe8ܦ4ýò²³ Å¤Y•R¢ÍºYûa)ä)¸6·79›¿±Se6~Úµ0ZÏ,o}ÅïvÉÿelZœý:K¤“DMqÑWHäÏrïcm„v7p%ž(ÞÖÃm­Ñµãý¤Ä¿HmjªBѪ‚ ·W€‹õ§ {y[Œ­[VÊ[-Îfw/öEžA’oÍ’NUU@2jvhÙL^ß±)œÄÎz`ååí¾ö†Îáù;«Ác<ß» \[÷]D8]æŸödÈaʬ¬{Æm¯-Ä-±‚ØÝ>ðƒÝ 05wúA' éÑ«íÔjÒ Öû ÂÇÙ±­Ùnð½o Ó-Zì…ÊÆÊÈ8ä–ƒLŸ™Uš I¤Ì‚í%†ª·`ùHX ÂU“é^s?~lÙmrËÂZYí[»†Bë‹[¾ýÖoÒ?½1Ñ´9„ø¯’7im âKîÕ¶ÅÚ{–;‹M‘”¸¹ÏÛÂé öýйk_Ü8=Ä:œZÇG£€pÙ1_ ¸Âãá¥&2–p[Û-rÃüy) …ž­É1,›[sã†m,ä[I¶4¥Õ*ñBp Ú6d“‡j, ‡f~îçæ~åÇóܸÛ8Q‘É;Û¦HgÆÂé{·:à–1 MÔ÷Èèâk*ýC«ƒØ˜KÍ–7¦s&l¬›~ëw0Bd{€X€áªW ;KZÀùïIã÷‡kÈŘ×=áŒ7bl3;i˜.Ëu bîµ.û|uâeÙ³bñ)ÍÖYP0„OAÞæÈì^`fó[Ÿ#±w…„6;« sþbS4Á-(øÜæµÍ,%­s\*I¨¥×´1˜Ì–êÛ—rÝà/$|_ŒG,RÇÒÇ€ç4‡\<ë¨+Ч]zÉjóê­îÞuÚvÄóe^Á¡-´Ë$dÖy“ÄO"Õ”éЏfS¢(€Žº‡~ºwñÝÉc4vN ½tO¸ô5å¤1ÄPÔPžv-.¢}ÓKíD/¤°¨Ž$Tt¯o¸Žµ8¶Î× ån òãË󷇶‚ôpÎUoe<Æì"¡#›))`nØrÎi6Êt©.ôtÓ1S*eI?Œ9y”åNÈÃ|/ÍìS,wæ›ï3ä,ÃnÜùDŒºîæk£, T–ÇPçââç}5¼¬9º2_ßܺÈ:ëkãî"³º›vµ¸Èxp&”sè@ 0+‰kû0gÃãÜŸˆå­®!m¸¶XÞfb]›È»»+/+*Í•âZìTaRzŠÊ*šNˆ£„ß ¡9LRB½Ë—8-¥²±|þÚËEs°.%uÜqÆæ¾ Æ9×’5ï«H .a 1è ’Jò­é•Ü;Ÿ#ŽÄg1òC»¡`·{Þ eº.pl%ì-m5À¸?UA‹³¤øPáŽË¾Ú`ŒƒÅÌfnYÄ|,ÄŒ7ø×Ú7„¢hú=¯1p¸žc.÷°tá4W|š)7ncÿnŠj”šÕ·4¹“˜Á¿|`vÌ2l°×É%»Ñ}=» ¬ÑÄ"tm«Asc.sžˆ^ÒsSì-“Ê·jåó’3sÖ=Ì·×iÎ¥"|…í{¨Hx­¯¦Ž¯`ø8ŸBW‹býž=µtð¿b¿¼gl.Ã7)œÇwN\Ç.Ê&n-D·\Q2‚‚å&¨~÷›¶/µÚÙ<xÆn[æÀçètàú´‡>7‡1íÔ¦š8Ž+mË›¦OŸ±ÊÊ`¾ÁÚºRÝM–œ[BKHcÛG5Ô®— ¯°F i˜¬Î n·+˜0ž.y‘2B1'éÜ 6Qr[…”zÔc’?cþêR¬!¯ù5°o}ñ6ÑÌ`qqÛ6værm´./-1Žkµž?d–øV#kmX÷7-~ùÌGbn ﯊MFžŽšÈ{{„\…°¦vÍ\D«mœ«w({n>Ëyp]®& §RˆbÊ×i»Ó=ŠI¨,æIû„’M™½!Îè¦&æÆô»Þ9‘³vø¿Ébä€wϸlPåˆÈçLç†éyv–CLƒ¼y-vû>^í‹}µŒÝ;—0lì¯Ù/æÛ ’Rö<1¢ Òu0 ºG¸Ï´%àŽ'Ãf$³±¥–¸‰Ë%•“Ö˜qЬkÍFæ¾®;V)âmò—<œ¤LU»àU!ÐI]ãºI@:gÔ @ÊÞóuå÷%ÖÕåö*ÚòïØÅíÍÍÁ†Ú)žÒï»Ç¡’>WŠç6Ž®Xë]—·ñØ[}Á¼/æ¶·¾/6°A’y"i§|ýNc#i¨-‹¨=!n¡ÁQ.¼•aÁbLµmÞX²ý²&²Y²t“% ÏaÙÖš¨%y+~Û>–íäL¥¼«¶é1P©»UÊZ"‰Å>©ç!ÅíËëí׊¸³Üö7±ÙýÍŽ}æâpM¸µ›KZöJçBXÖ;ƒˆhw8å ¿ÍZZíü„8+»WÜýåÍ,0Cc(y4 , ¸—4}­Mn¹6mŽ;7·®s„ɽѱҴBøåcƒÙF¢Ð+S¨PÑGÉ?ü%AÞq¸š‰k®bþ~þ*ÕÓbc¸ù¼Y;4 HÝ™%¹BNu“'.Šš®›>ºˆ$%9K®·~óZ÷&ê°Û–°àcò6 ›·Gzø£©.Ð!ÑœHcÍGki9“´y}k’fß¼ÍÏ&Yïk °[µö­{éA«½Ôö´ ›Àÿ£BÑ85}ugŒÙ‚o;ê2Ì’ÃÖ%Ýw¸º Ðîm÷¿g¤-¦ì\?QuZ9‹€¹ñWŠ*Ýÿ¹k¹¹9Ã/cawÆÆKË|½ôui•½ë&. 8>V¾YP×8ý [ Ëio÷^Ojä®Ùm>6ÒYŒ´¬nîÝiq$ÆæÈ]BZÙ%}Iðá…o¬”æpng¹okÏ Z®/‹¢6ä°¾ÊÀ]V¤P˜'æm–w&ÍÔˆ+7É‚ÊJA!DÂbñžbo<&g½°öÖXlÍж…ðÝwòÁ;ÿÙGp45Ž/>)1 Ôê4¡±²öÆWsµ²SÜäñ–æy[$ÔrÄÏö„ë.£5‚µ¥€q¤(µrçy"ã±còS©„1­¥fZhÜ×Läd „™ÊÝRC!'Â.«‰&cv®ˆ`Q3h ÞËoÍɺ®¶žÀÇ[ß\c[¼žâs ¾P\È¡sä-¸FZá^ަ?há-0û‡x^Ík ëž-¢†!,¯lfŽ•ÚœÆµÄ:\ A¢Þr ¬`pÜç_ëå¥8u±¶¥²µ¤“sAËÛ‘Œ}!’ܵ9†xÞž è›3¶PJ¢©€(==³ÍY¯çÜqîËâ›·#ÓRa9=äs=Ô-kC‡æ‡u§Œí«Zïv3¼¾ŠÎ,+öíáÈÓålUˆÄ‡ÆÖÔ8öž=x0´Ð¹¼W+ÿ« /‚a'üJM/ ¨ZÎ&Zc£+‰™_\}–Vei¤f”I“zä{"6€¨bH¿â72eÂé܇á.뾺î—榮øF#1‚cüà‹Q}›7/Ä]çt^-ëhÙ맺// ˆd mx:ä "ãÆ7µÏîæ…eqÚRîá¥EAU¹—lxéšÆ"b»ÍÌESt½¢*ÚºW¯à3˜íË…¶Ïbœ_Ž»‰²0‘CCÒ8ÑÍ5k…Mê^m—Å^àò“â2 Ó{o!cÀâ*:Áëk…ÓN ‚¸™TÛ¯k-¤,}V{ð)w[2Ù†·•»²Åç×·0õýu,›(h[ñ3øñ–]' ¡ßÌ“ÑÁ ˜¢‰ŠMå T•ðŽxâr7ö˜‹Ãgq‘Ú¶y6BÖ]$‘ø®Ð263¯S¡Ô ¨Ð\ßYåNBÊÒç%l.a²Ü6F;;‰Hk!>3uCÿKˆê T×vÌ+~>¸l¸~_0/cµ™IÝòô[(X÷eºùƒ´žº—ô) ­H¶Å"¿¦8j‘ŠSTNrŸU½“üÆÇŒ{ NákÙÜHÛqes­sK[¦@xiîÚ÷_h#aµg76MáËe"¼Èá‹]ß1Ó¨%Í!Åú])hã«[šÅ$Wĸb'-þ¥d«Šámˆp¦?p”Å6£'—CƸ$VNÛ²í–;'óNJ€(c¦T‹º¢€"rþ£º÷•ÞÓþíÛxûwe÷ûK"Œ9°µÝÓšâgB(ÇP\jÖžÃ@ÛÛbßpýû7{3qÛḃHúK{Çî›â™x6¤Š 8ô€yeÀqµÏŒï£ÃÞHŸ½ZãQdã YW¥®µvÄÀH,£v÷LZ‘ò2QÓ1I¬‘ÅÁ ¸vÉNqïqXýý¸ñ›’Ïls”™-BÖâÞc4•€ ÃØÇÆòÐMCÜCZ:HÈ^m %þç=³¯fºŽÇI¸‚x„r²7¬Òç5ì¨:€¡h“Ð=_…Ì-ecÜ]’2Î{ql²ÉØý¥ÑjÅZ¥î‡NÛ‘ÁÙ¢F*?I­¼Äª¦S?p™{UOÙ”€%¬|ÏÞy­Á“Û›SÛ™±—î†IßpØá´Ð8ê .•Ô$DÂt´j$‚²¯Ø[c‡°Íî» ŠúÌJÈ™ |¥äVƒIp¶ wޤÐEÓÏ›^V¡4òú·ò•™hÞVÙ£SŒs6ÚìA»2MãÔP~‹òöb˜«¼P‚`.ðVå±÷ÈÜø{ûܼ,±Èbï'·ºYxŒÁÄ»QkIioé¥C€­³ºö™Àäí-qÒ:îÎþÚ­äÒ^%à§QÁÜ)^°M*»b_„èç[«Edfd·±u”ÖñÌ*b!Da¬´o)4“F,ݪ¬ÚÌÑ~‚h"URUuûB›³Ž%Õ-9¹#ö5®íºÇ<ä2—®·°³Ž@d¸%å‘—9Í0â×8µÍkt‘«SAØ.9pÆî˹ozß¹ØZ‰¯.^ x i:ËCšÚ‚çjN“AgÃæÊׂ|<勞ë¾ìˆ×BöUóe¥m«xÀÄn »Û9û)7Àg­ˆ¡L“ ƒ…·€=茒ówí‹Ë7smk‚½°‹‹kƒ0·–J÷m¸k˜ßЇHá´ë¨ #Ù»o=mr6vB{Œµ¬.”Ã<#4lûn…Ís¼aÒá¨×«‰_e‹Ã>0w„ì\픳_éí±rÎܯâR¶ÎN.æEÔ{–ËV ®âEg`Ðë9UDJ“4ÀÛûÁ\YÎeîx·¥öÆÛ_ï ´ÈÇ™„Q#÷:g8ÀÝA¬hqt‡¢”+“±°2m{MÙžÊ}ÎÂydc˜"2<–8µ¢ ÒK‰¡.% 0tÖ«'IÖreµ¾ùyHòÒ(BI9@Z¹ˆIâÉÆ¾rÔÅ)›.í‘H¡Ó!Œ! i^½bë¹la’ýŠýÑ0ÈÆA’‚ö‡u†º °*¼Þí¶ÑÝÊË7¹ö‘ÁŽ"…̆¸Ž¢[BGQà¶â©¶»«‚«1øJl¢9Sˆ™D’3,d:qmzBbtdÛØŽ-‹¨¦>ñb »•×8€Q1>È`ñîlHü·÷_/m‰ï³w­PжÊÚ“\º½D†µ££U\Úž úW.ØÜqÈo9À1b­IŠ£ºž±@>šç4é[¯¨—"Ú8o‰¦"Šd›e;;#=ÍæùFÁH°Ï¼)4ìrC´MväL(·›MâëÕå{ÎÝËf9i9!¸Û“qiZñ²º=ãZÞÞæG¼ôj}A\ûùƒ5Æo¨…]}†ç躷]ÙÞ°4témOH]“0ÎÙ’á‹7”«È;iÕßšÓ“’aY·H/é6!"Ìá©]‘˦‘ÀNR(&åÓA×,æÉÛs3}O‡‰“ä›gŽÐÇ?»i?uejú;MWH…j³—1XO±6”Y9‹®oµ9¬ÖGûéâÔV® Ã1ÌwávëÛÓÀuà B(-cd¸<9¦Ži.uÚ<†ñ.ªêȰVN”°pÆožŸÉíXH9€gvØå¶­\„ê)¢¯GÛrE—vö%Â[(¢^š˜Ê^þèåÚo÷þùÛ6±ç·ž }°ùÙ]Ï}=£^àÖ¾fwml€8€îìð'¶8 M›´³×ÄmŒ¬ÓgšÇÄÐwQ\âØ¬¹†€‘¬q§eHÛq_ –Ù‡¦³GÊdÆÖ®Pua\LßÛÎez3(‰S’£W!!s;–+b³wRI59„1³ºy‘—Åov~ÝÅœåÖ-·P¹²†6®–F~qÎ Yy“U\âÖW.¾ßØøÜ†Ú—ræòp¶·¿6ò5Ñ—:ñ:)sô†R€<š4…¼[|9bKžÇÉU,ØîX¹ ­¬Ê^^ÐtêJ~xÈÇ©¸cƒ†¯”¸^:ìh)¦EU! ažK˜»³œÆíga[q¹/±îÑÇpÖ²)ÞÒ!h‰­f§IRx†µ¥Ä.Í–ÉÛ—ø«íÀÜ£¡ÁÚ^ˆš÷ÂK¤ak\ Xwxâí-eá©ÎÃòn±£±D>nÄW¬åÛc¹¼W°'˜Ý0-àn+zåN3ã†à©>zÉã'qâSï³ L'0'™Û;×9qº¦Ù;ºÊ LÛlÅÔN‚S,RÂ_Ýš5®kšúŠš;€bó»[Þ‹um»©nq.¹6ò6XÄrG(n±].s\ÒÞ<:*:jiÉßáþ,3D@äŒí;!xHÅÇȈ0µ#n«JÒ^A P#ßOšt§]™NTY¤]À6šã ÞÆÏ ¯öÞ ðñÊæG÷Ùßó†kl]Õ"èox領]ù¶ÎÈÄ­3™iŸ“|msþë e†áö]'yùÂÞ“ }ªîž°%±ŽxÎaŒr«+ ÌIÊYml£)n_ÑòÖ<ìŠ%›É,ªP¦‰9œLGEÍ»2ÁºµiœÀß¹=ÇÉ™7>Þ‰ö¢IË“ßMjøîba–d×%PX{§ê ±m7gØa9žÌjF\1Ï€wAñÜ5ðHà^Hf–UÝüãt‚x9ut>>} ÅKìa•®¤,»*Ù‚‘’cñÄI^àöBDŽ fc“–PØC?IR íBŽöéuÒ¶{ÍÁsæÕƒsâ­]𽹕Œw{Þ›m,e%æ1WÈÒ ‡‹CÂ¥köØX%¶Üà27 ÅÚÁœÞï»ês«Û¯ƒXàtŸ½4 ©³!mãñ]ÅoÎ9¹í|«b²ºbd–+ÛLqo=mœ»œÁ,²:€!¾et†œ»fÎÝÒî;Œ®;!mr˜«çA#õ+Õ!´€âPoO®îm´Ì8ûÛ)]qÈZ6V8·I­$Š€š˜Éh'¬ž…Û’œ$¹m•c1[KѲàñ‹ ‘™.9˜ÿF†Æ-Å$fÙ¨VîÖVWâÆ‹ dͼoé$׳)T9u+^mG&Õ—uKdçE>Möxøc~©/N­¸U 3[ƒ6š‰h;Ç.ÍÃÞŽé¢H¬s{#ÛFZ:žÓBKô‚Ò8·V¡ö@$R/✅Á ‚rµÇsd+väÛ[^ï³ n7¾™EªI…¤õ¼“Å[¾"Z¨‹GIöÊ€€éJ¢„»­ý»¶Ä–÷›ïmm·®&lnžÞã¾6®wí,h-¯HÃ¥½ ìmé G¥"ªBG-›Ë‘E é9; y5QòždZg`æp>xuw‘‘S,tñšA#ÓÒà <`¦ìKŒ}Äc2d†T»û$õø*(OUGUVkHÆÈÛî“¶%ç+$@nv©¼rF6Фw"ä­âç á14A@[]wÒ †•æy»+æ ÎåÑV ð¨i„xÍ¡áÄ}kn½ÅÏm!Š'°tPôƒÐGQ¯Ð¶ÇÆU±»ŒLŠæHçHH¢ªÞNØ€:öb òVjôt/•þ©­ÄJÃô­˜ÆjìälOHjSHs&ºº@JÂsv…Ð4]à×@Ò÷isº¼+¦8tš…Ä%!¤Ñjç}Gj šŠŠIûS.rh`íìN˜ÉŽ‚!¯'‚³6—VÒHÑP$ T‚8£é¯RêÈÉ#ããið™sì9-!+f ¤³BF¹m3(Ù…ÒlœsS¦1äjˆ¥ì„‚n]Ð.ÊÔw,‹&ã ]£iÄ’H$ŸÁô®í±kâñxËÔ)OÆx.ÞMÙLCé¡Ä¿Û)¸c§ìÓÜÔ *x’µÇBC…xu ý&¾Ùèéÿx(I^ÇtÀ "øE1 ö€A|Dˆ`Ôû¾ÀÔhužº‚5Úð¯i?ç)‰h>Áü?÷-í“—àS¡¡Ûn½²¤M$„å8 j¨ªÇM4ÌTÇP.£ËÊ5Òš{~JÑ-iARiÖ'_à]¸m¯&«âˆèë&£ë4[ÜkB¬à)0YP"mdÑzä `)^>7f͸€j"'8ìïWNæg2>ùwQ‘þÒâ¬oþ«\~ ²Ö±Èá“5Òö £à/û#ð•Ü6ý¨ñ€œ‰Ã¶Pÿè‹ìËâî’jþ‰„ºî¢u÷Õ¦ä2ÐÈx<££PÓOQlc¤ý.'À¶;k e>ï飵Jÿ ¿ú£ÿ >µÄstls otÄôm%w4û(È[6ºzêX¾Š ‰S!—t©ö§7„5ËìÉnï³öóÞ=ò[Z“;µgM  ð.¦P[ÇlYnƳX é$ŸÆh¼QÈ­˜Â\jÆ»$ƒ[Q‡ZA!Éô¿¤.öqÂ"_xfä–vª(˜¼†A }gµÛ$ØßïšXû§™OKYÁ±ƒØK@q®+Å7<ÍvKîÌ5l ¨ëwK¿§€Á@ûkb-Zõ~´ q¥DêÏ¥/ uJë¥AÔŠ¤óPÔ–§T€~%Ij`¬»à‡;Û¼?ñn]×»uãÉø©Ü‘nš«.Ÿy1çÏŠÝ휧ð»U"ê*Š"e•åçÙ ÷°î1Xgçà–;«RHÏnímmO^ÝL$ç㤿òÓtZm=ÙC&ÒìD±¾ ŠTžêfés¨8'KÈHiT…Ú7³ˆ´¢|)m¡ñdûµÇÙBømy)è c–˜TòíKnË ÝbâN$’\§Ü9Ó.ýkxæ`ÿwiÞWÂnhÕÌS2X¥ÇŽíÝë Ææjqnš´8Ñfò<žÝß|®Ú„e0rº°\Á$ncØOŠ^uŽíÀ@ZW&âRÔáã…«Sƒ¨+ÂÞ½²tþIW2g¹K>E »jÖ’B8s¶žlc5•}‚ 8~Tµ+gÄ éXÝ…m“ßÜͺæåõ¥Å–Ûƒ,1Œ†9¦aË-ÙˆøÌkÉsb'‹ãxáV®îížÃhìx9ykq Îj[Ͻß:'ǃ4Gn89Í9ôû/oOŒ²‡Î¸…ÎA[×V'±>Û@IcleæF*~ÜL¶ä³H2Í®´K3un¦-WMÉr™¨Ý@10Ê_5äW6vËØw½Ó}÷;øò7’†>)zÇIÀÀZÇ6S¨°—‚ Gwnkr÷wnmÙö×ï6³¶asdóo â%p1ð!ÁÎ¥¦ ž w?XÕ·׎‡¼ñë·L¸2µ8a´òÖ”tÆ/¸3 €2sMØNKz.BÚ”“ž]‚Ç\ šÎ)ÅDÌmFï—ûŠNYZoK»;öDýá>b{X 㼊ÂëDeÑèñÙ3ehmKY&²F—°Ûîü37ÍÆÙ·¹´sÛ·"ÆÅq(kí¤»ƒSÃ_«ÅtnsÜÂMs4€j ãv;®6ñÌ•ÏåK†Žm u 9"ï-¾Âø´8~V.µ·,tí©–R÷$µÒ‰ÔA²[qrS9Ô"JdsQògpÛÛ`¶ÅöãÜùl„ѱ¶-È^Ð7P.–äÍ™! 9ÆFÕ¤P5®{zxÇó/4ùl害î7FÎÚ¥ÚHÃݽ®‘òе¡†Ž*I 8mq¼Qç²¢Üz©S*®øé~áR¢B¤‰T_] œL¾õ4ÀÆ÷¥@JõÜ|Bæ~âWKvK@¯A}âzÏÒ¼êòC'"¡‘Ôvèqú8ÚJ~ Žù?ÿåÆ þ¨/pÿå™ú¼ ÿþ˜ÍWü5oúh”åüÆ~Û›ôr/9N௡hBñÐW(³][MîÛYÅèÑôœ…ǵٿ¢Ê>¶R“jyæqÎGÿf~æ,ª‘?Ø(`c2ñddÅ]G‡{#˺ÞAž51³ž:Ú¤¸u€BîãŸdÌ„É5ÏÇ ˜ekMèÆ°ÓÔâÚ€zŠôG%ð3–˜ßÇ¿¸3BO*ákt$±Å÷ޝçSè¹nŠ® .¥+=/ èÆIEI 1»âEAT“ùÿns¯jÍ‚.oº<^ñ¥—v×p=±ÈA KX褎FÑÀ4šÐis½{5Ë üYc•åÈ}þÛ”‡[Ïo3KØcÈsdcØj p)R©£½óVaý![€hÜýq±¿ø†Á÷ó‹»1ÈGʰ».[FÄ5Ýú"ѹ®Ç.‘šºÑƒD«#¬ªÄQ®ùÌ à«8Ò6vÒø­›êãb[¾Ã`æ¬ {3Ü÷l“ÃÃLp ipkZCèîË#Ú7&âø}ÛR×3n÷v2ìËvæ¹²Éë\Ȥ‘¤‡Ê€$[R|pçõîcàw4ež%îÌ…`%qàü¹~Jå¬àÂç·ÆË‡³.é…îYI)%¤“Z9kQk¤fê& œ[fCï]ƒhó«gín\Zà3¦K}銱e›ñΆ_¼Iqb1¬ !ârÖ»P:F³¨Šb7,w&z\eñ!“mŒ…Óî[zÙcîY ¯29Îqp-1á¤GOjG5Ê–M{A-\i1!)–0ö'äY±igl˜(ØHBI8XŒ]+0ý58Ã"‚Ú•2œÅóÉ6ÆW—œ·ØYMDZÛb³¢êúŒskÄ•¦F¨Ú@—…[!ÑBâÐwgqûËzîÛ,‘¾{üI‚Ö®NøXÖǤ—¸9ƒW SßùO `N7$²´C+.VàáÒy´E™'1¥ê¼{A~w«yƒ—nã ='Fé.ë± kÙå)ŒO0¹¶7žúÙ–Û^gÞZÁ¸"2\27‹pçi¤BWµòÓÆsY«Ki¨‚@XŸ³ó»gjni³Ñ¶Úypï …Ïi˜´j¬†6’[|PçSQû €Jé)O§žÎ±ïkÄG’ö³ktå“kÎ>`ÿ÷ø¯Õî±¾¿é¶Ïÿ…v6VÆ·X#…ËÛÆ…ý-ˆq >Éö TŒbwU£-g‹vq“ÊÁÌ ã\™‘1û,—ž¸~½-IX)æñS®!¾&^Fº²mœ&rvôÂWcÖ+Ö‡Ò(Š)˜TIÁ6™9{Îmm&î=¹¿~ÜÁç­çd±Ç=ý´mx¸šÑš,f-m1È*ãã¸ite£+²qÖܼÜ' š¼´nk+ˆš'Fð×Åi3ËL1Ü;S£x“Kµ°Ð}–Mx'´¬bq£eÜ’÷VJ°øjá¦Ì°˜LIÉæ§øƒú+C"ÁÒlÚÙç·¥JÜoî-þÁ2T;DÕ1u2†"*ë9·rs1Ž‹·/·ãÌ_IŽmýæ§UÍ.uÇzÇ2&ÅöœdƒCžÜæ-¼ÉÆÞÉ™´Âáq¶Œ{xëKj 4ÐCݸ:GIöZx‚GC]áì̺ósÓ.E39–“&àQ@SߺUÒ¢›T΢mÓ€#¥}©ihË;H¬ã¯wm`©ÔhÖ†Š¸Ð“AÓA^•ó Åînd¹}5È÷8ÐPUēë§£©|%SnÞ*ç-\U^¬áLI‘³_³ví´1}®êî¹RâôÓ'Šfî5šÅŒeŠí$;í¥^°l$EW©@'þ@×O—7–ëÛÛ3ùˆ´Ën[–ÚcŽÓîÃÜ׸kuìä6Œk×uS‡J÷µ·ó;›“7츽‡^Z–ÚÄ «‹GG]x¬t‘àŒxçòÒXNq´t['R/ÜžrÎ9[²d‚Ž].b¥qS1„ Q0€rz¿=ùKwq­¾f\Jö± Gp*ç8ÅN$Ä€´é¹OÌ;x_q62VÃKœuÃÀ4TžW€ !8L|—Õ^1/äd•‘¿œ†<øÝâÖ½á†Mƒ«Þð•*{À0Q,X˜Œ;tÌ‘ž1@j¡´jÂîon1Ê,Œ[Ø7ïW÷eâÚMmµ»+ÿÅ{œ ºHpSA:ehÛ¶£—8SÌ\°yšìýÞÎÜ8´ÎÍM3ÌêQm#Ô(_BGÉì‹*Ñ០#.HÝO%8zâJï’±2Ô“¥–Y‚y =c¸Bå“zs¬Œåµ? ‚2›|Ü•Ä šîfï-ÌŽNÞíK{VE¿öìÐ2æÅ8Ú¸ac@9¢cX(\Ó*4fq¶Øý“Ì›]Á5äÚ¨¦tn$–‹†š‰î!ñÈæ¶G8Ô5ÚÝC¨ vŒözfö·t³\†hlsŠ-öÒòÓ9ÊRNFÄ%ºÁ³…㦢ým's˜ˆ•Ɉ9'n© ¸pA¹çöË—¸6CtÜ:6Gc$eÏzâã~¨Ëcî¼bçŸéñI¨Zt< Üñä$fcº²ÀB×½÷ÎsvÐK^Ú>¯×À5£Æ¼`(Vó~Š û7ðù[.w ‰Ä½îFº€ž–;~ÑnÀÊÂMóîˆé¨é­tðZÝüÄeÌ€6C¶íª¨½Š¢´§Eh+Ó@»m#“8á.g÷Üô4¥GvúTÒ½•ú×0zÒÖ”àÃèÛåú‘vT—7£ ÂM%c­gw{†÷ôÖœQœJЍÐwDºéX˜fÊ[s‹zÜá#æcÛöî·a¶àÄÒ:ä }+#,vò×kÔyüÄ͙աlFb$p=D2¦«-硸²²ók[{ Øx§ðËq@üQxÄÛX‹ìœ¶?+¶B[‚fõ¹ÍÍHÏK4Pæ1QP(áOxC{CyMç*³;-Ù ã}”Ës*Ky{ËwÍßÇu¥ßšŽÞG"Ô¸wAƒÆ x£Ðní¹ŒÜí³ÛV–íÉ™¢fÇiÝ> ·óš@÷ºGŠžYqà ñŽÈ‘¿íÓí nrXÿòî'®ã‡üØÿö›?Òß.«OüÓÞ°.Gh°ïƒëmq¥Ë®œåÁñ0J½w™-›ÿجWœr°ÿ¹noønïýP»ýÆ7ŸÜ:pµp`Ø¢_¸ºÏ‘ÅYψ}œí­,Ñò‡”}ñÓc„|ûVÊ..w LDuîkø-ˇå0·=†ö”ÙZäîÙ{i9Ãx®Ôk'”&.{Æ>Àqh´rU®. Åâ'”d™Ñlt¸¤¹È¹LMÎоgÌ­ïÊmñµn1øÎç1º. s,£†ÞGÝ ÜÚDà{±$aŽ!Ï-ÔÐXAÕ¤ï;ksjno/ûÜnÞPë§Ë3na²4e.h!¥¡ÔqR£Ÿa<¯{EñaðŒn< ºéÌ.²Ž³r,›zø^PÌÞ@DÄܽ”C)ƱMHå›S ˜¸&šj<ôÚ·Ø[«¸÷¤™î›\Cl²’J%¶”3Se’Hk#¢sÜY#ÅAÑ©Õsš—ÚùûLœƒ µÙgýãq’7VpÜ1†9ã.¡Œ’ŒkÃsš¨(Ö¸¾éšâRÇÂYn{-ÂaLq[/lHÛq®/²â¯Œ¤7KFÉÂÁ¡oI7‘dÞ5»€pwŠ‘DÑíHCf1{».\f÷®&ÇiÍšÏ\Ûܶåó:öáöÖ]Ñd’XXâò4ÚAwØ$jðßÜïl^×ÈÝî(±xˆ&Ð66ÚÂÉî»ÀZæ0Fàæ†ƒ¨¼‚Úé$tWÓðT<ü<Æþ™o£ù£yÿÄþ‡-S˜Çÿ mØíþ²…);#a«.øÈ/ü ]Mê«UE1u9`LAIÝV»ÖP†Qgì²,"dhA•4QÉï•(ŸóNÛ7·w…îÃÜo‹X-Ã…tÇu¬‚g8ºÒBd< s‹’· >/5¶­r¹—ûjO,Ô4«íߥ‰ õ¹· ƒˆºGÖ\f“Ì_ê,.fËîö÷,t%ýÅ·ŠŸ\z C®’Jàö‹>,-û¡Ìµçdðû„íM’rYÞ4Ç Ý&‹™‹ËyÜKæÏæU—8‘4JÔåSE½öé½àæòÓr«!‹m¦÷pf²×e¬f=·—}ãÉpÔÙ[#KcŠ—Šx¼*Õzh´©î_yÊ[Û¹såÜÎy iºÝŽ$6§HãÑSN…³Úÿ°Wú|µ“þ"‡®æ\ÏÌHáŸô².®7þäkÅú6/ªP7³æl¨t›‹&ep¢eßQ4@§L‚:åLD@<#\Wáãù€ƒ»Éð›¨A?{–•=•\–š&åï ñ©4û´u§ÓE•9ÞÏ6TôTO Ön<·pOÙÛ}ÜUk Œ¥žŽZ)¢Ów ùz^M¤Îš¤Á`PÊ5 ‹tÄ¥0ˆ|³Ø™« nù¯y‘¸ß_x•²ØºKÖžáV¶ö倂Í4÷E ^˜²ÝØ«¸íùwmeÒî#,» µx‘¥€É%Äóô:µ¨PõpÉ6aí6ÅN$äY³²ÛɤÕãù\cvÇ1âM=däž&š%(ñÕ)@9@+§¶’åŸ+´o¨¼s´ñ.kY{Ý^“â1¤¸ž€ +³yß.=iÕ ž•B@8R-N§Â<õ%©Ô+ÃÃS¥:¯^ø4OzÖ;í¢<íӯ̽ûûóšý­yúÄ‹ï]û£Šýmú,ðìvŒkS[ŽÀñ_…+ÄŠn%C½¦ÌâÈ·Wîg)þíø{úœ+òÓ˜_¿ÙÊ{âóõ™Aë^E¨T…`0…¨=*à~à¤;ÀÀ4"§­X !Þ(Ÿ¥p?=NžÄÒ­•:@å$×H‹¶rTÕ.ò`»7);js—A&G(N_öiï¼a¬fZÉ×Ö/¼%¥Z~‘þ~#ëY<>Cûºý—ÿeZv½¸{²¶¹´uµÄdøÂŽd”á¨8P‡MAÀÚ½§¹ ³A3dà°á^#‡FžÂg3Gâá2psr°ÉâÆŽ•…”Û÷ 2‘©‰œöb %ñ€4¬t–°ÎíE¿œm%ŽÿÚiñ” ‰#ûTw„>°j"JJP¢vë@Y%)SQWŒ$ Ü J&ûhùˆ ª˜5¤(&”¾é0£›wrÃZ!k‡¥Í¯¥qºâÕü%¶ŒŸôjßè4üK‹O½HƼÇì^·tA"Åe~ÜN@0  ñ#n”GT'(rdíáÊ襵è«Oõ¡ßåë\“ýx_à#ü…r¸'%dÕ˜îA»t Îo"¡HEJnª:Žð€ ®¼µÕ¹ŠÿYuÎF>ôŠP[šWüŠ»ûÍ[’ߦCÇësF®]ÃØXP §¡Dª->õa0‘C¦}¼…ÝÔ@L‡–(ÇûLÁ=‚&Ž‘Û_誦]BÑHì¢I{ŠÞûp³–¤hþÛ‚D¥T“8dÞ&/)^¼2¢U chœµÒ‘¸ØçÌË«‡pûRÔÿám8.Ôwwã„FGú,ñš­í½°ÑáÁ[Žz^qN]QUë‚¶ÔâQM‚GM±SÓ“Mšº’e¦„hÅÛÁnÎÐÖêáÚóWWëRèß3ëu#äãÖISzÔ»’ÒbÙªiÇ1'Úvi‰)L¢€A(ï)ºDÌaè<£ ~´¬ÅÍIJ—\ÉWR¦§ x8žµ²aÃc5kG`<;?Ëô.Ûe¶âe„L_ìôÝ( sŽš€Duæ­N[¦j$ž+`û¼’4 VBâ:z>’z8u¬Eâû Ââë=7ʼE{¶u³ÈË&8§Ij“¤Á;†ër™4›52mª%ÿvqÉïLcÔù_ˆ½Ü9?¹BÇ7LJ\?¨éã5ë5¬Žh?Õmx€«ºnáÂØÙÈ3DMí'†¡×N zÅHà¼7:çYE9„Ê*s(sˆ‰ŽqG^QÔF¾Ïclc@}|èù#Ì’q{‰$ý'ŠÔÏËOObš«ù‡¨i§T€~z)Õ ˜jKSªPSž• uH mÒ—…4€~१±:­É¬´‹4¶g"õ«g¤Þ7nítv˜éŠnRMBr jº40‡†ºòÚÛÌöÉ4ltŒ5i-´ôÔ8€xv.V\M\ÈÞæ±Ãˆ€|4à~µóùêËTUe÷|GÃñ˜G"Ù,n[b%l{gÙnãæjÝó£Ûñ~€ÿ·,Kçm–v~RÇ1Ê(w«ÉùKËÛ½´þÌ¾Þæè_Ïp×FZÞõú›Mmihé p=oüÂÞû»pÿ{ã[<Ha-yÇ»n—WCˆ-=@ŸX” WªñZ ~µ¸-&ýÚ-[º|íÓv$2lpåe‘f™€€b5MC˜È`H  PÐæ áe½¼Ot‘1¬‘æ® \{IIéí\¯šYÖHç´PIÁÙÑÔ€ê÷+µER‚}ªªÛPZR‚œô¨z“ªÜ˜ËHÇ †zÄ˳XYº]°¬Ÿ³PQ:b¡5ð¡]y­­î±àM¡í‹–9憦'9•hH¨ì4_8)ÕÑ\ºj¢«ïNIé*À•ŠêeÙ‘Â¥j²¤ÝÜUVÅ8"¢…Ü % š¸m ”Næ7¿h u ;éjäÈbpˆš‘SB{HèFšÆLå:g2jÅ9S LC”u)Š`˜¢€÷ÀjœÀàZáV”ƒˆ5#ð¯©Ã×/;—ŽváQUÕT]uD QULcœ@¥åðWp²áhlc 8*|‘Åò8¹ç¤“R~µR©·ÇUNÔª¾öR/#Ö :bà bìÜ*Ù`!ƒCDäP ok × ÖðÜ3»|}ŽÀx.Hæ–k‰ÎkûA þ$}©Œ"cxÆ1Œ#©„G”DDyDDj´(85©©é_z’oœ Ý«‡®ÖlÐ [,áelÓx¢s™4@Ú» é\ ¶†7ºXØÑ#þÑï OÖ¹]4¯cc{œæ7 h<«êB Ué§BŠ¥6øûµ©§juL t‡”)Rªª”ëè©-@)J¦Ú‚ÕUJ TЧU÷šIê­b£ÇJ1ns(Ý™Ü*f¨(q9Žt[˜âŠG9”0ˆ@DL<ã\"[)œ1¢w 5Ã=' uõÊfÆ"sÝ€I ðŽ´ESn5zAQT §pT–¦ ûÍ ñVÈ2QÛ•¶1ÌÝ¡×Tí›™Cê aI#(c˜J¨ˆë\Þ&ÈéšÆ‰]ÒàM:*zM>•Êe‘̹ÎîÛÐ+P+ÓAÐ>¤ESn•T*j˜ëè©N«1±þLá†W[vNb±²E¥uZN'K%àp´ž¾ ç¦ìÑ>é^9 ÅveIªä\û©¡¸* ¾GžÛ|˵ܗ9­¡}Ž»Åݶ2lòx1[IK{ËWBXRç´´UÄšý>‹‰ÍlkŒ$8½Çk{on^Ír;$5ÑpÙKC´Òpq൫qž-ü®\oeãëfJÑÄønØqkXQS¯Ñ‘¹übá“—Æá™Iœ¼ã–¨™T›’ §¨ÛÚ¿Ë͵ŽG3Ÿ¹Žïuf.D×O‰¥·@-Šƒ¼sAÎ s¨ã^N==纬óâˈöûŠHà騂ù$#Åy¡¼:Mxc™$ž‘¢ŒñÉXª ,«2¸T­X74UFà~Äê&_|%×Þ‡0W¡:Þ(œ±½ø Ô`=4âxW­i¢if 物4'¶ATÛã«¡QT §WE*& b©Ð>íIju_z²œ ƒW®Ù°6l»••A¸w@Hç2i4÷ •×m¬½ÒÆÆ6Gt'ÂGõ®gO3Ø#{œæ7 h< }HJ²Õ_s™ÕŸGÈKžzI5?„ª‚ŸÖËRªPSnµ¢*¾Åºpš¸tådš”HÙ%—UT›Û b C˜J‰L. Päjâd1Fç=Œh{\@ŸoIéí\®–G´5î%­è’ƒ³êT:êèU 9é§T ¥AjuHÛ§wФµURœþJšŠ¥*œÃÕKÂRè¥zª@?0÷tT–§^Ô€~z‚ÔÁìHæÔêÏä©¥:HSó êJ€ô"«Ù. ÓÞ´£‹1Ôv¶K½_˜Ûû†úÍ~Ö¼ýbE÷ÆÎýÑÅ~Ͷý zöA³ÅZVÇÅNÈ6x¨ª8¯Áç§(]ßn4ì•!• &Fè'|¢á}Ó€9ÒoÈ#Èÿeh¹)5´†š—;ñŒÿBØñO0ÈñâøúzÑ—³‘…ì—÷•âè ˆv¬á Z¨CK\Ó—jœ[‡A9D¦.§û“tµ9Ä“mmŒ®çʳ‹i×À¾B˜™Zj?I?e¿iÇ£…HÌÞä­m,ß!¶ÂºYZ8šŸìŽ©Àt4_Ì·–®ÌÍ{J^÷k;ÇÆ*,c[¨¡£`â1ý"13èlÑ5Sî–PÆPÚ ·K÷–ÏÚvG2É´-s¿¬ç´ç·8ñ>…óVéÜsî,ƒ®OpŠ?îêphêI+­@áÑ[QjÖkØ54N½©Nz\Sð$)ù‡ª—U œI¼m›Êøêí¼&˜[ÖäO¦ÇÇ|c1&¹1iéÒÎØF´í×P Ú.²I]L`ZÄæòøÝ»‰¹Îæ$îqvºY_¥ïÑ\í,kžêÐÖ¸ž W½Ìä!Åc™Þ_ÜHØãmZÝOq£F§´Tõ¸€:ÊܲF:¾1 ïpcŒ“n¼µo[YÙXÎA½Q¢ê´YVè»nt°pî=û7lÜ&²¬³uÑPª&sÀ#Á··uá Ü;zá—X{–jŽF‡à i«\æ¹®®kÚ×5ÀµÀBæÌaò{'.1 É@í/c¨H$(ZK\ µÍ%®H ­âàÄYÔÆØó/O[ÞŽò«‹¥…püoëãçlª°—"³“s9ñl¢&KW­›m7’“CWVÃvmì¦á¿Ú–7óø¶Â똴HÞè\0I Öæß­„;óo~ž‡i<=ÞßËØa­3÷pèÄ_kaÖaqdž q{t¸SÇkkÒÚŽ+®ýÁ[•‡ªû™¶xý^Á‹W/—Ü:‚‹Tp°&˜j¢š$9÷¢:h\I ×;šÆV•qTô žW$qÉ+´ÆÒçtÐM>¥Ø¶î#È·V7ÈYvÞôì{ŠÜ[-/Û‡ãx&¿¸¼eS„¶Óø©ä›iÉOŒdÖ*Z²là¨ë¼¨ššµì†êÛø½Ãaµ/®4gòm™ÖÑwrô[°É)ÖÖÙ¡€ŸÎ=…Ý Ôx,½ž1}†»ÏÚůbcÉ©ƒA™Ú#ñKƒÝ©Ä®§K¨8®¹6ÖÃ¥aêê¥áN©NºTª@Sn5%ªª”Ü%©ÕvÎ"Âyc;Ü*ÚØ’Ș½f7’­c¢ˆ˜¤y9;*å„5Q)UxåÌpÝä­Wuï-­²,Ou^Ãghçin­N|ŽþÌq°:I\ØØâ(³Ø µžÝ7fÇk%ÍÀvš°v½î-cÒ÷4ÁwBà‰BÃs1þH€û9/;kÃ^qLþ5„—ô«jà*戒íàd¥¡é…lìT9'»ïÈ]C\ÛÝ8 ßg-þÞŸï\Én÷h’=3ENñ”•ŒqÓQãZkÁÅeóx ¾Ý¹ŽÓ3sq, ™£[X䮇UŽp¡àHpëuè)ÏYú°õJU6ëÓJ©Õ()ÒP©ÓTê»/*bœƒ„oYw“íÿ³7ŒKxçRá+ 3èèJ±BE‚Ÿ[òRÑJöìœús uÐÀ×6ÆèÀï<4{ƒmO÷œD®{[&‰#©c‹4ÊÆ ât‘¶A œÞõ¡µ t:M d…†@Òc$Âz—j e[¸²ì cþoæ©ÙkHÕ½ÿ9fâ§‹l¿eèƒ-é°Ý„áÁÒA6¨Ÿ]ò˜S÷õ¬é¶FC)Š7?ïøh5ã{¹3âïší]Þ™+H‹Ü:à³£lgM†@Aþç“•ÑÛ;\œ{$îœÚkÔÊ?Ŭ€ô‚GÆo‹2èÆ×tõ‰zÆ|Mu[/9é±ò"ÉéMS£éÑ.ßG9Њw‘YBr÷ûõ“Âæ1›s '}‹¹f¸ß¥ìÔÒH®—µ¯oÐæƒô.†S}…ÈKŠÉÇÝ_Àý/n¦»Kºi©…Í?Q!oVV1¾òEó;gÁüm­µnëÑׯpÑÿÛȘåVC°”dâGtSìšuÇNBWK3¹px »+¼ýÕÖFàAnÝ;¼”ÒŒ«àΟ´òÖý+³ŒÁås÷WXè»È,¡2Ìu1º#.£œÒïô-è˜['šÝÅ×`[:Ûù¢vBÛÆ’[Áö–j*t¶Ëö^‹ñ·¦Ãöf;GéµHß唟¾®™Þ[hd2x¯¼ÿ¿á d׌îåüÌo‹¾kµhÓ%cñ©{‡AÜdmœá³°¿î?Ý2rº;gkódÛ›Mz™Gøµ4Hⶺ¼¬;ºâ±.˜7 .»MÂÍ®(”g.1Š·"J.*½…s!ª)ro*šÇH7ƒßWžÄg16ùÌdí“tÐbyX51àš ðè]<Ž#%ŠÈMŠ¿‰Ì¿·q0ý$Rµs ›AQÄ>•ÄNò…e¨>©AN¾ŠE¨)TÛã¨-UT ¥F”ê˜è Ò¡N©J¦Ý:{Ô¨ªPS¸*KS)TÛ­AjuJU:ªtªªR©×Ñß©N©Š®ß*ê”ê©-N©J§]AjuHU6éîT–§TÀ§?Œ*S±)TÛã¥@RU%©Õ()×RZR•Mº{•ªª”çåè¥B€R‚›z‡Ü¥@R‚•:UU )¶¤µ:¤:º* SªPS jiDê‚›téîÒ—…:¥)P"©üÃRZª©üõ%©‚”§æ¡¨-N©NR¡M ˜u¥Ã­J¥§±:¤ó IjuíHç©ÒRù‡¨jKSªö§‚’kgDc¸v$où<%bæ¯c@ ž²À:½`ïìšð^‡ƒÝÕ‰¶“­l‡¤v‘OíqÚkwO;×hš𤹠›¨ÙTõU3h ‚ÉåSAÐÉŸt€~M5 Ö!Æ_ž-ï¼Axx´ÉG6±qŒñ`ŽÐGá[#Û¾×–J¹\¤IdÊ£èõ‘?¢©Ê%MRoêˆ8ßÝy`0w´×?n'ŒªH¨¯ÀV:HK N’?Ê8JÞ-X%'n,xÙ‹’*œe®” H•DÔí&lALtÜ´ÿ wDj/¯73áû–:ÊÞJ´ñ‘Í¥< õ.{hqÅÚîe{hGÙþú}k'¡x¤ÆNx[^'$M'Ô}t©»ù2 ƒ6.•f`ÈÐÚ9 Љ€¤ÓQ8€V¥6ÖÎÆ6AöM–Ytµ  ¸‡×‡ p4ú|Íe+¤6½èdm©ï MOÑ¥eÊVÖBq7Òeš1’ŠE¸k,À[8,’(r²¾»WmÄŠDå0€è;£È:†âÁßcå6·Z ËkPê‚Úñ­ý¾š.Í´Í{u R½Bœ~µ‘ñ×)IÙ© •8‚d0©¼'ÝÔJ‚]©ÌpOÃÈ=þýh÷‚jâê0qLæo-µöåõ$|8» $±¥ÝÛg¸7-ñä âèZ[BkMZÞõ¾ –†ñ˜¬^?=™µ«%ü±šœ·E„ø¬'¢GPA.qÈ® 0̓Ã?´=àÛ€×U×pÚ64áì+™“è¸Ö²¦,bÝ“(\ñ¢ÕÁÞO¿·®´›ªÝDQAÊ ˜É‰NB@æþðÎóØ=éc÷[[ »Øþó š÷»ïÜ÷˜_¨ÄÙb˜¸<9Îc˜ªÒNÝ˹ŠÙœØÊ훳<÷vöÏî$k[ܾõâFÐÕîŽHÃKHÁäŠAâtÊБñ 40öY± ï_šöu•¾õçžæÜy¶‰ŽÞ6¶V ŒØ5±ïžV´ð9í:^<`׸p£W¶nK™¶Ï*ðx\[ŒC3ßÜݹ¼ ºÖňâXÖ‘VôÐxÔ¬`á0ÝXgˆþ+µ²: =S1#Œîå„Y8;…®D_¯.ò¥™¦bå_‘ÑãRl-Ôj’‰•S(%0‘röÛ{æv}æëæ0XÍ0È ‘:×ýÙ°Uç»{ Lçê!Å¡ Šz.ñŸkžOmþâ Àç±mYtH.?>eñ¶¹ÚŒaºKAÄЮkÄf#¸¿Ã6;éáµ-n±Í÷î·j[v=¯4¼¼Š ‡Þªåg.µKP1H£‚œÅ1J%?/·Øåï)³¨ ûÖZmÛwmkt‰®ftb6Ôyè$0´MFGxmOŒy…ŽÆK/qo[Ïq-+ÝÃ^^à:É%­4.‚CcŒYÁo÷T¦ÂÑyŸäçQ ¼Kx_·U¿r@d)kz)äÇÄפ(v#k++ª‰(És!)„ÂsÖÞ7çç-qqo=ã.%¶Û,M¾‚Úa–Õ’½±÷–ò:GwÁsA4T@LŒÕpø.[ï{÷í·JË6èä6²Ï,rGpøÚ_¢f7º.kI†ƒj@c¸0À˜žÈÁRÜHq8…òú!ÎA{Œ1Æ*²_Ç@L]·4+w ÜR7Âý¤ÃÛq*´]±…»I@Á¨ï&U3Û—|îœÖ÷‹—œ¶u“.Û`Û˻ۆ¾Xà†BLŠ&¹äÏkƧiÐáØâÜNjàq›^Mã½EÓ­ÍÙ¶·µ…Ícå‘€™$ŽÑsN‘«SOh²Ö÷/Íx áÈoX{j÷Kåàmû9 cƒH–âwЈÜ XÖ´‡<ÒºOŠAw[‚ÅáŸ0Y‘²|=žîÇy}[öÖ²R—ýÑu'yµ¼$P…Š˜²nñQoEãGiä“t©Æ&€@:Ö¾cí,Ä–ÛøZd6˜±šàäma|ÜÀÃ#㸈½íÒæ5ÝÛ˜j\5¯‹ÏwŠÙ[‡ÉöÞ,÷ »Šg<­”L&pc_ 5kˆÖפtqíkãð+ƒò)°CG5^W,2ñðy3Û7 -«rhe’I¡i!½õÀ‘š$”6¬ÐÐÚê-©¦{)‡ånÙÌ|'˜+›ØËYqy‘±‘H@.î¡,v¦GZ;Q.àêp[õ‘ÀÝ œ8£ÅY¦ë¸S Ü9NÞ¾ífèW0h!)t9<tÛA¾1ÜG"ºfQÒ'D‹é¡Ç£šçfn÷emѳ­mÝ‘Ìæ"²–Úbh$%ì’Ëâ÷dÈÐ+š@cƒË:—gÊü]¶çÎ`w-ÄͲÆcdºŽx€âÀæJYÇ]â]p«šZÖ¾kC ðm™ñRɶ™³^*áæJÒ{|«7#oßsõ™u-&Ê58¦-cá£-ëÒZFD9ãXB™nÙ3 ‘åËooìýÛŒÛyOîl¥ÆàŽvÛÙ-´v·†9åîs¤|¶ñ²@ãÀM 3C…ý·ËÉ·¯³vÞváß§/ts¾xe.kt´5Žg¹…£‰„ÕÚšjÞ¼É8—Ýü1/Äv ˆ¿,ulì¢Ó^vmïqÇÝhÈ5’†FN2牗g¢.̳´RY¸“³ã‰J@H¦_?·wVøÄó)¼¼ÞÒØÞ¶óëË{‹had…†HÜ÷‚Ú5ů­x6¤ê!˜|ÖßÚÙw–ÖŽêÔÛ_ i¡žFÊÀæÊdž´ƒR›Jq4H.í,µ‰x3áѦq{Cfl…rdì/`dö”5Ñ oD@–áM÷Æ—®aVzùY¨‰¤R VJwí’ë;Wusƒ˜2憛Çcs7V­žHd–I{¢ÝwB@Ö†´‡K1$¸ÈÑcC«œÏíþ[ìèñ¯ÉÇ’¼¼¾ÆÁ;¢d¬‘÷Ú¤ï %ÄÇn‡¼êm8%ÿÃ.°³¶2e=–%­Î²Ö?‹Ë–Ýû#é·r¤›NS´×kå˜Ýæ|Ý6Ý¿¢ú: ¹"ª&cèŽsÌåØù)¬qQ\s~û­Xý0Øæƒ8sÞÜi%úuëqcš×CÖ+-²6Ö+uXÅu$;'!hÛ¸çsuJ"sIÖ‘Þ꺴éhpq‚ÕÜØË‡ Ä\Œƒ°w¸±ûû~qþ?Ë÷Œ€MZR’‘ê?Fïdkb2=¬â)w™½íNR¦p­?rs}òúÞ<î7·2Gqn¬-ÙÝÎÆHàטß>Gº2ø‘ýK‡ - ³6žñ™øœF/5a+á{ »™Úâs˜Ò扛Ý5úé ¾¼)…öwgC]¶Ö@‘E¥ýe¥â†b¤´û‰òšÎumÜ[€‹Žb£2?I~ÙG &¨¦bŠãßvÛÍÿÌbnl#{ì. ¯yŽ ˆEþðÙ´¼k{Ü$1é ¡ÀÐדi϶YÉì¡ÈAvö¶î>‰Ýr?2b«N–µ¥áÕ.!Ô"¡u}©‰­»ZÂö|å¨÷÷ ×RÍ“-n/å æßfŸ˜™BÆ `5LÑÊ8jˆÀŠªvªêo{Þ­›)º²9<îþÚ· ·ìf7Dæ²’¸ÜX:G÷¯Ôu€ãFpG+a·ì¬q;G? æ7·ù7‰çV1ÜÞ5ÐÚx¤ãq5èÈÓpVõ¹ŽeçSbÙ’0¶ã˜É'7oIHd];T»Æ"‚‚&)JÒ9}/8!åM†so¿2ÊĺI#–Y®ãˆ¸¸É0{.“K»¦1§h‘à’FѼcå¼¼Á»Åf‘’þêì6[†=‘Çn÷é ŒµÆF²£¼sÈ⡤^—„á>:ÖžãjȽ&g•—áóH\¶ÓÈ'åŠe<'D$àN²;gFrÂFÓuŽØ]Ã(%ŽšÖå{ÍKŒ†ÌÍaá€ZgòL†fÊÝnЇD­‰À¶Žd{Cèj:GBÖmv6{Ÿ’’Sqˆ²t‘–;Cdá©…í¡«\ÂÒ[QJÒ«›OÂ3ºxSök[*»A…Ë–2´å˜, Ÿ$Î_4„s¥Y¸( ÝϺmÀƒ¦•†±¾—Í.cdíà öØ«Z*ÒèñÚÚ8U¤Ž"¢£‚Ê]ÚǰvUŒÅ²Q¸´ÑÀ>óI-`b±Ê ŠÝ™Ž èíöÛ§sâ9‰Ù›¡Ö’Zd±’)bc£Õ{nA¸¡Ïwæû¯Î4µ¥y\û’Ù—›ŸÛ†\YdZÉ#‘áôµ˜R-oÞx„ý“BhÏñŸŽømÂwÔš³–³ÍÏp¶3ÖáŒ`”P²ØìÞCÝŸù¯ì»‹èðŠ»6™b‰»u bÜ;(n&à‰‘ŠÆ@4IÊÉ7\®Ì:iª©ºhQÓZÔîöŽAŸþŽã¼‹û/¯ýãýU¸Zo (/!1¿¬¶„~êñ–øÑk¢Û îÁš©é h3‘ËöÊ ±3g­ÓQ1!ûBHMÒ”7@§(ã~á¹-ÜDðÐ ¯Ghý}=«/W0;†4v;SúW-€`AI¤ñ“õ¶>ógL1Èö­Ôm_ÊÀ¢# €d÷ˆb¢q áF ì‘i}¬†Vôè §ej¹¼qLq,»„ÓãµwÄW–µƒÚß¶;œ+u..”AFd]Ã¥Žªª9QÊ¥XÇLÂM0&á@F±_ç2—âñÙ=¤p€vqð©“qàí¡“ŽÆµÇ†”ükƒÎqS~ÉÊqÀ„88“}º® ¢i]äˆdTCB˜Cw„Á  ¹ûN\ØÓ~í`t€4è©p=€¼Þï.:-'ûN<~¦´ÿ”ø:ÈJ¿•r£·î”r²ªS˜Ú{EGyC!L¡¹L ˜yGQ­òÖÆÖÆ.æÕŒú:O„ôŸ­i·W×WÒw·O/ÓÐ< }Kã󇊻WU\ ¯xjHN¥ B•¨WП @70Ò (¨Wóù)iM ˜jHíEUÀãá©Òš@8søêKUT¬šàÒàƒµø®áê⹦¢­Ûz-YRS3³²,â!¢cšM6UÓù9I›²`ɲE(ª§!PÔD¼ã›¶¹.Wçñøèe¸¿›pÈ⎒G½ÑÖ±Îq<Z ' -Ë—wv¶[ëyy#!´Žþ=ïpcÐðKœçÖ€8’HveÉÄ\Æãç.g¼W78ÙŸ9rm’ñ’HÈ[Ý•;.%Güz˲•·.¨_Ù.‘”&Š&áo‘3†»Ø›Ç‘˜­¹á’·ìcp{ f¶¸ŽÖ ×éxd°ÈÞ- â…Àæ¯7uÎÛæþéÁÈÉXܽÓÁkƒ£žÏ!-ÔÒC£•‡CÚjYÁÇVGácð?ˆ'mùÌQ‘2ùxc+‚)ÍÝd[Y킾î{FfÝŽ;UTKȱf‚ ‘Dˆ¨r>3É=½Í[MѼçÝÏè—kmä‘tì qƒÇh<–xÛ'³o&§¢Ž‚†l&§¾zÕùͱ÷œ»íöû6ÞáØ=çime’–(ÜæÚºÚâ*ÝJæ´µ6n|#]‡yB]¤,ï-wNÚj6mË4MÊí«‰®¬£{ÚÓ8žÒÚH."ä6C¦¤ ©]CÀod´§8”³¯L°¾$¹ø—k! œÜŒÞÕËP·Ì+û•t\X@Ü.n§¤|ë³¥©@Û…8¨žÙÎþZ;+e·rØ|[r¸Ý¹;›&4tÏc+"ŽF ¥ˆC•«¸Ò¤»_ånöYœ~FüØ^æbeéèŠéŽ‘ìt„¥’^êpáZ\2öEâÙêâÚ% &ÑRaž4±°NT³ò=ß‘n÷I ÌåVûä!,Dƒ§Ž ’Ä)ƒ†*š ;aîÖ?°vÑLn£uÝÎJÊ{H- ó”.•¦K¦šh¥Í$t¸T·m—/ºðøËËíÛ»£|b‹xl®b¸–âRÕ» ¸ŽÞ2û—BøØÇÜ6!Ró©Ž{Øßë<}–js{›?sÛnk­Ñi™¹‚Ë#Ÿ·.…ó?L"F½Îl.ÓH£ƒZçu4ôº<ŸY¼3q«jÞ\A`éÌ¥±¥´Â"À²oÈ‹„åB2bQTQm>EЊ¸.7ª;8ž.4]8f‚eQq/lB†;sf³¼Àæ>ÎÉáð9¨v͆JgIuqlø¸¾6LT/Š&†ŠM6†ÈâZÊè%w0xÌVÐÙ{’Ç#–ÆKœ»²¬‚Ù'½Ä !²HêšÇ§1 SP „ÞMmŒ­ìÞáå{'c(ûŸ‡I¬Òâü°îK½Œ5îñ+Òüw3ż°(úmGLž $Ý)©Žbæ2J¹œD¹-¯üÃgÝÉIÜãŵÌ0:Kv›{fÇ'}(£c s]^’€Òq™ì³¼œÄ6ÒöÉ—¸y/ ðI+Y1N^Îê3Åä‚)Ð H–2Zèâg ZÜ^ÙNf¯X9¬U“¸!¶øx¿ï6Z>èFÉVçláGŽ ‡» å#‘ó}AËd2‚C @‡ó¬g.7ŽO”÷‘ÙÙÏçÆï9²¶¶÷ t&àB@hoxâÈǼÆï°÷46 á¹ßoM·cÌ gÜÜÅ& ÷lÇa<°½²ˆL€ÔÜXæ´=¿i­$БCÓÜé”°`1^G¼ï±pH[Ò° "-ؤ•ÏzPtáÞâM슰öQbm›ÿvg9³µ]Ëݱ€ÎZeòRBË©omooced’ºI^Cdw‰F5•tÔYㆰëÛGob¹{ŸÇ9–Å\c¬™+ ŽÖá³Mu#£s#k#h.`ñªç:ŽÒâ’áÆm[²ÒâÓ…ÀÁ²¹ÂÅ™«æ;»(ÙÄÈ·6••[¹i)ø7+Òü_s±œ”8 ‹U"$RAEŽß'“ÅåyWÌÏml/²{;!ˆ‚Êãî‘î-eµ dRºøÏ…Ñ0js>É.$U¬t¬o±ûûcü1=Ý¥Žä³ÈËsÞ$Cû´ñÙ-í¾ù‚{©ç.H!qÖØ[Ž—7²FµÞ+Ô£ÛG¶­p+æ¬Þ5¸|´øØî ºŠl°½²G#zZö¹…ÃÆiŠÕ¦­wW*›u¬ÑjÅÕz!ÕÑae.2—×]÷kbÛ²O%BælWvß’F…±¥®&ñÖÌí­qO‚*§¢ð±Ä35U)’QUM®†L¥SÀyƒÎížec9¯‹±ºÉââÇI½‚ÙåË"/|ÑMUP$yàÖŽâ[ëÛ>÷œÙÜ¿¿º‚Æý÷¬¼µ–wh…ò67Å#ètU àI=~$ñ…ƒÂ„u›–.ì³d_™âÙË6Ñbã IzA^m m…Å1)‘'#ؼo¤#-Ð\ªo,š‚ —µ"\îÜÙÞi\^mlV*öÇcÜ⮡¹¼¾·–ÞGK×—ûªÊêxb¼¸ŠÄDÇ=­|¥’Ê_Ý´çéi€‚iT–eçi5öwåû)ÍÓn6¼äø…´f£mæã¹ä!›@B¢æ]ŒŽK*î1ºÉ‡pšFH†(€˜–_–—ŸøœÌv×ÃÅ€ž7Î#y…²d"7J†¼‚ipqÇdqìåCùá'åâ{b/h•̰¶2u‚.€GJÊî.x{q™pÁ) –°¥¡(Ç„¬-)mdëù¥‡*Ös:ow´<«ak1eÝ8Ar´:®Û®¦DJªb>]ÊýЋrÛ^b³7vÏÝy²k;W\±Ò~e¦h:£–kš^LJðx-rß9ƒ´_¸äÁÏmÆ[ÎÍ¿f×Gs8ÁŸœ"Q¨QñÔ¹§I.ioÑÁ}–ötáÝ)ð-öíµæ,N°)1=™–îÀµ†¾hk ¡~ª›¢×i&_Gjá]ävR¹M@Hr7û'˜å†w5 ­Ì9¼þwï×1\Œ{ŸCj x÷ÎgŒö¶Žs Í/.rZn Í÷ŠÆKq˜¼F+î°ÝÈ+¼ ¨Ÿÿ;ÅkZÁÓG®ÔáªêɸÿˆHû»ŠÓKà v–µµ<0ë…¶ÖÞKá#‰L#XWåÁyc[¶™2ìcgCIÄ¿Ay3¶“z vÊ3F5NÐMNÌÊ%¿ºUÁëœÍ“#·9­·7·÷vFûogy†Î\HÇÈÒV6”/©új[Eç;;,×/ó[[ï–v™Y®m¥gÞel,sà]G;¦¦´„¶´«xG Ø¡€ýšÐãzÚA/bæ{îRøŠŽ$¬Ø·™­ V’7[yéVëQe)¬ì¨¦váÚDœµÔ~9ñß1¯>åw÷Kì=³-ŸÜÉ¢áíÇ9;N™\×ø…±—ïŠð]†å±_ ì»o¼Ûýâ×%;§oxÍP´Þ‡‡JÚÖ6–øÀ¼[Æ´â¹ÆcÁ66OâžïÌíx—áÌ0ãëýÑrÍ'”"qÃÅÇ(ÀeâÛ[)G³2ÎÌÉT£NÈ˵|c¦b*]á)pÛC|f¶×,-6t»spü^ËC fÍýÌxwvó1£ccuL$ |tp-4ä÷ÕÅç7ÝÆä7†øq÷bY÷–÷Œktëhˆq{Î’#,.kêÒǃ2â6ÃÊW¯´s!¹¸a-¦y79ÇŒ.9hØI[¡ÖöÄ X¸÷ë5púnJ&Ìͪ²fWtw„7†&åæwla¹y·ã·šæ\n\Kvèc|Œ„Êó4®{Ú#š$qkHmxt ‹xâ³¹=å˜|ÑAö4ÇnÙÖ>QDQ†µÄ=Ìc]¡µp&œzW G X¥À¾Í¸q½-0—±³5õ){Å ÇVtc¼Ô„«I©¦zM¼ÁÔX ”ÖvTS;pí "NZÌ¿›;瘷sºû¥îÙ–Ïî¤Ñpöã‹È¦’¹¯ñ c.!Þ)à±­ËbþÙvÿy·ûÅ®JwLÞñš¡i¼•µ¬m-ñ}oÊíë ã‰N:øÄILcFÀæO•¬ "örÅ’É;q…š´f·:NU‹ôE’‰qº¡?htÁ2”1J:–w¸­y!´\Üuì—ØŒ­ÕͳaÞ[?xüÉú{jS¨ÐHØ19|4üÔÜm7¶¬µÈãî­á™Ò7¹t’w%¿¶„5Ô š‘AR@]!ÁäCxl镸P».;~^ 7Ø·n*y?iJä¶¼#cœOÚwDDƒr¤Œ©¡ž´p“s @ á}  ÖëÍËÉ/6F+šx»yá¾ÂßA|اa†cÞ"žjYÞ5Í/®–ðêZ¿.­™mºoö üÑIk”´–ÔɻȄÍi’)XáÁÚpoV§q]OÆÞC‡½3Ü䦠}ÄQPøfÂA3&£tmüzÜÑ.‚¨ˆ¹AåÀ/WIR—C¢¡4­¯’ø ¼6Å‚÷*?úöZY2DÔ-ÑÖ* H-‹»ii<×U¯ó;/o“Ý’ÚãÿþÑ–pBvãA¡2k Ž–±,î õbÕçÕJU6ÔªªR©ÕÑS¤§TÀ§@ù¦‰Õ()·ÇJ€§T ¥IjuJU6ëPZR•Mº{•:JuL XTª)TÛãïÒÒT §UIjª¥:ê SªR©·ÇSBR•N­¡R˜)J¦Ý}ÚE¡:¥6éRZR‚•©Õ()·ÇS¥UR‚]êIÕ)Tëè© ER•MºT–ªªPSž¤µ:¥6õ Fš'T€§VФS›u¥@R›t©-N©ANº’ÔêÛ§wŠ µ:¥9ü”¨SªR©·]”¸u§T€¥-=‰Õ(mAjuHêÚ%©Õ (<úÔé¢u^ép>]lx!ç‰ÿÜGݯ˾`~þfÿkÞ~±"ûÿfþèb¿fÚþ‹Ð-ÀÛäþŠÔVȦàmòE_^.ï]Äïþ!sOúȹk÷?”ô§lÃØïÔá_–\ÂýþÎ~ؼýfEUèKOR„)B¡ P…(B”!J¥VR NªÀpðÒÒŽ à<ÃSDø…`6”QíWÒNƒ©\B*B°0éEPUÀãáå©Òš¸e" uWxjhª¸Ÿ’‘jÀÜÃRBªžµp8Ò⎀p¡>)ÜÃJ€¢¡\Î*)«ù‡«üTˆíN©üþJ’ÔÕÀüÃRZRƦˆ¨HŠ<)ñJšT¡0UÀáÏ¥IjuHš’ÔêúT–§T€q©¢*< @è¥áUT §]*U n4‹SªP??’ µ0RüÃRZRœõ4)Õ)TÛÕK‡ZuJ w-=‰Õ )·_v¤µ:¥:ª SªPR§JuHU6éîE/ iANà¥@˜=‰AMºôÔ–§T §UAjª¥:êt§T¥SnžçôT‘ÚR‚ÁJ0R‚›uéïÔ–¢«!¸ƒÏîóôž0’ym7¶ 0Õ•‡ÐI´š²…—mf¸šp”ê§U“!f»ñ™3p ŸfÚòh aű-²Vðܺädr÷ä–wfàF BŽv Þ_²(¶ýÝ»$Ý“XÍ$-ƒîXØm.Ö!/:Í@¡v¿³Æ”é+ ÁNºÞ‹V§T¥Wm*´ê”î šÁJU6ëîÔ–§T ¦Ý;¼U%©Õ()Q¦ ª˜ªíñÒ§juJ uyB•N«)pŸP2Ùœ{jb¦3£¶Ó‘vÎk}vJ¨{*"}ŠQÎÍ b DÆÝ©œ¼—¤‘Dʸ”S17ʧ˜ï>^ßïl”å2’7d1Ѿls``ûÄ‘8½½åήóº.Ò]‚š‡BÝëlï M­e,¶ ;¥Í{c½t¯=Ë$hiÑàƒdÔÕJPq˜W2‡1Îsç0œç9„Ç9Œ:˜Æ1„DÆ0Ž¢=ñ¯HîÃF(Ò5jx’® wN“ÔŠ¥zÈ4¨S›té¥@UU()ܨ)TÛ­Ijª¥*›tîæ¨ÒSª`S¯¢’uJU6øéi Õ()ÕPZR‚u©Õ)TÛãïTUU()ýaý“¯bb©·_v‘hN©J¦Ý* SªPR µ:¥*›z†• uíJ t‡”*hR•N¾ŠE¡0R•Mµ©Õ()RZª©J¦Ýz{õ4!:¥:CʨR‚{B§H= Õ()¶¤µ:¥;‚ µ0R•MºìšQ:¤:CËKÂS}¨ )¶¤µ:¥óÔ¦ B©Ì=CRZR‚ÁKŠuJU6ëÝã¥@RU%©Õ{¿ÀçÿÀÄñŸþAµ~[s÷÷9û^óõ‰èÌýÏÄþ͵ý •¨-•J¿\\ÿÞ»‰ßüBæŸõ‘r×î(ÿéNØÿ‡±ß©Â¿,¹…ûýœý±yúÌ‹«Ð–ž¥R„)B¡ P…(B”!J¥R„)B€ÃÓJ:«€vR¡B¾µ4N¤-@Â" ô«ûƒú)'NÅp0 ©*àna¢‰Ôp?8xªt¦¬ï *U CmMuV‡EN”ü ÜÃSDWµ\4qO‡R¸(OZ@8óøéPÀááä©Òš@0øZ’ª¸ŸÉS¥:¤ó I ×µ ž• +ØúQáOÂ×KObuH};¼U%©Õ |5Sª@>ßðT–§_­ (>TN©MºRð¦”×Jƒ©Hæ¡©-N©üþJ’Ôê”Ì5©Õ )J…:¥6øûµ¥@R‚]‹Sª@S¯¢ µ:¥6éRZª©JšS¡:¥*›ixQT §pTÐê”Û¯»RZR‚U%ªª”¨§buJU6øéSµ:¥:º)Pê”Û¯»RZR‚›tîñT§T€¥Nšt'TÅSoަ©Õ()Ò¨ uJ uôT–§T¥SmAjª¥;‚§IêN©Š¦Ýi'T¥SnžåMN©ANà©-L¥SmAjuJU:ªhUU)Tëò $Wð¦*›z†§H)Õ()ÕRZª©ANº‚ÔꔪmþŠ’ uJ w*&bb©·_ Ô–§T §UIjuJ sÔªªPSo»Zšꔪt‡”)Q:¦:ú*KSªR©¶¤µ:¥?¬* SªPSn½=úšR•MºyB‘:¥<[*KUU)TÛRZR‚]©Õ()Ð>í*R•MºtÔR‚”´ö'T¥SmAjuH wIjuL t»SBªB©·Nžõ/ uJ RÒ:“ªR©·»š µ:¤*KSªPSn½=ÚÔé¢u^õp5ËaÛÃÏ ÿ'µ¯Ë.a~ÿg?l^~³"ýÙŸ¹øŸÙ¶¿ bôµ²©BàK‹Ÿû×q;ÿˆ\Óþ².ZýÏåý)Ûðö;õ8Wå—0¿³Ÿ¶/?Y‘cÕzÓÔ¡ P…(B”!J¥R„)B¡ P…(B”!JµÔB„UX>ZZSVÔУÀ¯­*'R€Â‘PUÀô'CÔ®¡íVw†‘ ðêWó…-)ñWs I¨ª¸zii «Ã¢¤µ?¸jh{RèâW…$ëÚ=4i¯b¸:*t”ê<úÔ–§Up?UIjuìHæ’¯j@Sž—ëØÌ:QÀô¢½©üþJ)¤óPÔ–§T€~%IjuWó IjuíJ sÒ¡N© ~aÓgø©pëN©@üþJZ{ ˜uØ5%©Õ )ÕPZR‚›{½Ú’Ôê¥Å:¥6ëÝÏJH m÷*KUU()×ÑRZФ*›j UU()ÏJ…:¥6øûµ©§juJ utRÓTê”芒Ôê”ÛÝîT§T€¥MèN©Š¦ßv´©ÚR‚!ÑJ•N©AN¾Š‚ÔÁHU6Ô–§T ¥MRuL íצ¦©Õ)TÛ§”)iUR‚ÁRZ˜)J¦Ú‚ÔꔪuTЦ PS¯ÉSDꘪmêZjR‚ÁRZR•MºÔªªR©·Or¤‚R‚ŸÖ4ESM¾>ý"ÕUJ uT§T §]IjuJUvøêhSªPS«¢•ª¦:¤µJU6ÔªªPR§JuJU6ëÓß©¡N©J¦Ñ(R N©Nà©-L¥SmAjuH utT–ª1Tëò M *”ªmñÒ UT ¥IjuJU6ëPZR‚]%©Õ()×¶¦…:¥6øéP'T §=-=‰Õ()·Z‚Ôêêè¨-UT §_»J…J mñ÷iJ‰Õ()ÏS§±0W¾Ü ð »ÿDÿÉÍkò·˜_¿ùÏÛ¿¬È¿Aö_îv'öe¯è½­=lªP…øâçþõÜNÿâ4ÿ¬‹–¿sùGÿJvÇü=ŽýNùeÌ/ßìçí‹ÏÖdXõ^„´õ(B”!J¥R„)B¡ P…(B”!J¥R„)B¡ P…¨‡xh¢uVóÒÒŽ à` M < ÚÒ¢u*ÀqþºÀ«û»ô“ãÔ®¡íW=*ü àpðòRÒš¸˜jHíEUÀãáå©Òš¸9ütˆ)‚z•ÀÃSDTu«èL} Áà\¯j@8ôÒ-MX‹J*=5BuW‡E"ÔÁJzš'^Õp?=.)øù†—U ŸÉHµ:¤ó»¤µ:¤óÔéN©üÃRZRœô¸§^Ä¥So»Z\ª@?õ…-)Õ(nµ©Õ )ÕRZRÇž¦‰Ôx‚T¸õ¦”è%*U )·Nš’ÕUJçòT¦ B©¶¤µ:¥*hSªPSn½4¨ªPSnžå"Ôê”þ°¨-L…SmIjuJ TЧTÀ¦ÝziSµ:¥6éîTéªuH wIj`¥*›j UU()Ü4)‚˜ë¥DU()·Nš5U^Ô §pT–§T¥Snµ©Õ)Tê¥BR‚}4LÅSoŽ‘juH uTªª`S® µ:¥*»|t¨SªPS¸*hªb©·_v‘juJ mÒ µ:¥* SªR©·]ƒJŠª”é(TÐ'TÀ§_EIjuJU6øêKSªR©ÕÑPZ˜)ANò *'T¥SoPÔ¯jPS¸)§T¥Snµ©Õ)TÛ§¹PZª©N¾ŠTN©J¦Þ¡© 'T §U"Ôê”ë¨-N©J¦Ý=Ïè©-N©ANà©LÄ¥So¿J:¥:ªKSªPS® µUWÖÑ%]¹nÕ¹ ¢îVMS/(¨¢§ ßt®ŽFòÛa6Jõá–DéãÐÖ°|.Õ•¥ÅýäV6­/¹šF± t—8Ь•ú#àêXk>1±Š;­XµnSi  [·M ^PܯɌÖEÙŒÍÞ]⺺–b; ¯sÈÿÞ_¢Ø«&ã1–ØÖš¶Þãè¿äYÃXÅßR„/À—?÷®âwÿ¹§ýd\µûŸÊ?úS¶?áìwêp¯Ë.a~ÿg?l^~³"Ǫô%§©B¡ P…(B”!J¥R„)B¡ P…(B”!J¥R„)B¡ P…¨‡†Šê®ç©ÒŽ À`ð *#ˆVÖ•¯j¸—øp8PŽ!\„Tu«„6Ò 'àV‡EN’š¸˜iÚUÀüáS¥ÀÀ>I Ô«Ä)Q:„€zÇ©\ Ì4¸ëÚÏËHµ5p8xJ’T€qðòÔéM\útÔ–§R54N£ëH ñHÛ¯M*Ф‡E-)Õ yõ¨-N©üüžåIjª¤=MT€¥.)¥6ëÓJ:¤õR-N©@ýu%©Õ\Û¥AjuJ MªPSnÞ*<)¥óòûµ4I×± )·¨jKSª@SŸ’¤µ:¥*›u¨-N©ANª\SªPS iP'T ¦Ý:i§T §=Aj`¤*œÃ­AjuJ uR¡N©NºšêÛ§M"ÔëÚ”¨-UT¥Snµ%©Õ)Tê©¡LÀ§]*ꔪmñÔ–§T §UIjuJ uÔ§T¥SnžåI:¥;‚•uìJU6ëîÔ–§T §UIjª¦* SªR«·ÇSDê”êò…*ê˜ëè©-N© ¦ßAjuL wNžÅUJ ôjhŠ¥6éÓJUR‚ÁRZSMµ©Õ!Tê©ÒSª`S¯¢¦‰‚”ªíñÒ N©ANª’ÕUJ uÔ§T¥SnžçôTé)Õ()Ü“±1TÛ¯»S¤'T §UIjuJ uÔ§T…SoާJª§!Œs¥)Œs¥ „Æ0è DDDkŽI#Š7K+ƒbh$’@$’x:ÉàÆÇÈñ@¹î4 ’O@t•˜¼:`雎àa-$ÅRn*C3l¢c¼–ð€zBÅ÷ªGÞ”yKßJøŸæ´ÎBý™´åï1¥Ãï3´ø²i5î£=l¨«Ü8:šEZM~©å,.12·sî(ô_Só¸qeGûGŽ§ÓƒZx·í:”ýâëE;RÞhÐ8"@0né˺óxkåô:ìê¥_ŸÎ"ý’ØâïÉwæEޏr¡¥² åsß-‹1iŒci[²qôô‹xÄ~ÄúRè»~r¢EVYR¦(qÔÃõvÝþp¹™¶vý†Û°±Á>Çg ´n’£#£‚6ÄÂòÛÖ4¼µ€¸µ­Ö€ð,Ïòç²s™{¬ÕÝÖU·W—2ÎðÉmÃå{¤ph6Î! ¸†‚ç)ROŽÿ´%·óÎJúVØü£Yîk{¿oy ÏoXß– ƒé™+mìŠ~ЖßÏ9+é[cò;ÜÖ÷~ÞòžÞ– ƒé™+mìŠ~ЖßÏ9+é[cò;ÜÖ÷~ÞòžÞ– ƒé™+mìŠ~ЖßÏ9+é[cò;ÜÖ÷~ÞòžÞ– ƒé™+mìŠ~ЖßÏ9+é[cò;ÜÖ÷~ÞòžÞ– ƒé™+mìŠ~ЖßÏ9+é[cò;ÜÖ÷~ÞòžÞ– ƒé™+mìŠ~ЖßÏ9+é[cò;ÜÖ÷~ÞòžÞ– ƒé™+mìŠ~ЖßÏ9+é[cò;ÜÖ÷~ÞòžÞ– ƒé™+mìŠ~ЖßÏ9+é[cò;ÜÖ÷~ÞòžÞ– ƒé™+mìŠ~ЖßÏ9+é[cò;ÜÖ÷~ÞòžÞ– ƒé™+mìŠ~ЖßÏ9+é[cò;ÜÖ÷~ÞòžÞ– ƒé™+mìŠ~ЖßÏ9+é[cò;ÜÖ÷~ÞòžÞ– ƒé™+mìŠ~ЖßÏ9+é[cò;ÜÖ÷~ÞòžÞ– ƒé™+mìŠ~ЖßÏ9+é[cò;ÜÖ÷~ÞòžÞ– ƒé™+mìŠ~ЖßÏ9+é[cò;ÜÖ÷~ÞòžÞ– ƒé™+mìŠ~ЖßÏ9+é[cò;ÜÖ÷~ÞòžÞ– ƒé™+mìŠ~ЖßÏ9+é[cò;ÜÖ÷~ÞòžÞ– ƒé™+mìŠ~ЖßÏ9+é[cò;ÜÖ÷~ÞòžÞ– ƒé™+mìŠ~ЖßÏ9+é[cò;ÜÖ÷~ÞòžÞ– ƒé™+mìŠ~ЖßÏ9+é[cò;ÜÖ÷~ÞòžÞ– ƒé™+mìŠ~ЖßÏ9+é[cò;ÜÖ÷~ÞòžÞ– ƒé™+mìŠ~ЖßÏ9+é[cò;ÜÖ÷~ÞòžÞ– ƒé™+mìŠ~ЖßÏ9+é[cò;¼Ö÷~ÞòžÞ– ƒé™+mìŠÁ솷ûç%})l~Q£çwšÞïÛÞBóÛÓù`Ø>™˜ò¶Þȵý¡íÏž2OÒ–Çå*_;œÖ÷~ÞòžÞ—ËÁôÌÇ•¶öE?h{s眓ô¥±ùJÎk{¿oy ÏoOåƒ`ÿy˜ò¶Þȵý¢-ÐþùÉ?J[”©|íó[Ýû{È^{z,;ÒòþVßÙU¿h«{猓ô¥±ùJŸÎç5½ß·¼…ç·¥òÁ°}31åm½•kûEÛßXv¥åü­¿²«~ÑÖÿÏ#éKgò/®jû¿oy ÏnGËÂôÌÇ•¶öU¯íoüï‘þ”¶)ÑóµÍ_wíï!yíÈùbØ^—˜ò¶þʵd„|d¥-ŸÊt¾vy©îý½ä/=¹?–-…éy+oì«_ÚFç|ôµùR—ÎÇ5=ß·ü…ç·%òŰ½//åmý•kûI@ü“¶¿*Qó¯ÍOwíÿ!yíÉü±ì/KËù[eVd¤{äo¤í¯Ê”|ëóSÝûÈ^{r>Xö¥åü­¿²­iX/ò/Òv×åJ>uù©îý¿ä/=¹?–=…éy+oì«PöKÁ‡z_"ý'm~U¥ó¯ÍOwíÿ!yíÈùcØ^——ò¶þÊ­ûLAüí‘>“¶ÿ*Ñó­Í?wíÿ!yíÈùdØ~——ò¶þÊ {&¡½-‘>“¶ÿ*ÒùÕæŸ»öÿ¼öäþY6¥åü­¿²«~ÓpŸ;d?¤­¿ÊÔ¾u9§èÈ]ûr>Y6¥åü­¿²­iØ_²ÒVßåj_:|Òô ¿ä.ý¹,ÛÒòþVßÙUƒÙ? ÞÙé+sòµ:|Óô »öä|²ì?KËù[eZþÔß:ä/¤­ÏÊô|éóKÐ6ÿ»öäþY¶¥åü­¿²«²Š?½rôÉ[Ÿ•é|ésKÐ6ÿ»öä|³l?KËù[eZþÔpÿ:䤭ßÊô|ésKÐ0BïÛ‘òϱ=//åmý•[ö¥ˆù× þñ·+ÒùÐæ `<…ß·#åŸaú^_ÊÛû*×ö§‰ùÓ }#nþX¥ó¡Í@Ày ¿nOåŸbz^_ÊÛû*°{*bƒûÓ }#nþX£ç?š>€ò~Ü–}‰éy+oìªßµTWΗÿÒ6÷åš>sù£è!wíÉü´lOKËù[eVý«bþt¿‡ÿxÛß–i|çsCÐ0BïÛ‘òѱ=//åmý•jÊèÀïIßßHÛß–i|æóCÐ0BïÛ‘òÓ±}//åmý•[ö°ŒùÎýúBßüµKç3š€ò~ÜŸËNÅô¼·•·öU¨{,£CûÎýúBßüµKç/™þ€ò~Ü–­‹éyo+oìªßµ¤wÎWçÒÿåª>rùŸè!wí¨ùjؾ—–ò¶þʬËhðïI_ŸH[ÿ–èùËæyÿö!wí©üµl_KËy[eZþÖñÿ9_H@~[¥ó•Ìÿ@Àù ¿mGË^Åô¼·•·öU`ö]0ï+ìz_À~[¥ó“Ìï@Àù ¿mOå¯bú^[ÊÛû*·ívÄ?¼o¯ãà?.RùÈæw `|…ß¶£å³cz^[ÊÛû*°{/™÷óü|åÊ_8üÎô‘»öÔ|¶loKËy[eVf0ïHß?ÇÀþ]£ç™Þò~ÚŸËnÆô¼·•·öU¯í„Ïç ãøøË´¾q¹›è8#wí¨ùmØÞ—–ò¶þʬÌFýá|u¿‚ü»GÎ/3}änýµ?–Ýéyo+oìªß¶3_œ/ã ¿/RùÄæg à¼ß¶£å»cú^[ÊÛû*°{2÷…ïütåê_8|Ìô‘»öÔ|·lKËy[eVfSpïH^ßÇAþ_£ç™žƒ‚ò7^ÚŸË~Çô¬·•·öUoÛ1¿ú}ëütåú_8\Ìô‘ºöÔ|·ìKËy[eVfrþzõ½ƒü¿Kç™~ƒ‚ò7^ڟˆÇô¬¯•·öU¯í úuéül'Ô¾p9—è8/#uí¨ùpÙ—•ò¶þʬÍ$ƒüúóþ6ê _7üÊô‘ºöÔ|¸ìJÊù[fVf¢aÞ}yÿ õ 7üÊô‘ºöÔþ\vG¥e|­¿³+~ÚÉÿ¦Þ_ÆÂýCKæû™^ƒƒò7^Ú—‘éY_+oìÊÁìÙ žÞ?ÆBýEKæ÷™>ƒƒò7^ÚŸË–Èô¬¯•·öe`öm”?Ïoã!~¢¥óyÌŸAÁù¯lGËžÈô¬¯•·öeoÛt?Ó/ã!¾¢¥ówÌŸAÁù¯lOåÏdúVWÊÛû2°{7ôÿ<¼:ÞC}GGÍß2}än½±.{'Ò²¾VßÙ•¿nóË¿øÈ¨èùºæG àü×¶#åÓdúVWÊÛû2·íÈoôË»ø¸©*~ny‘è8?#uí‰üºlŸJÊùX=™jÎSùåÝü\?Ô”|ÜsÐp~FëÛòë²}++å öeoÛ ÿéwoñqRÒù·æ?¡a<×¶'òí²}++å öepöu(çw`ô»ˆú–›~cúÈÝ{b>]¶O¥e|¤̵gb¡Þwvõ-/›ncúÈÝ{b.Û+Ò²žRfVý»–ÿJºÿЉúš—ͯ1½ än½±.û+Ò²žRfVgŠáþuuõ5/›>czÈÝ{b>]öW¥e<¤̬Ï5üêêþ*'êz_6|Æô,'‘ºöÄþ^6W¥e<¤Ì­ûz¸ÿIºŠŠúž›>czÈÝ{b>^6W¥e<¤̬Ïw!þstõE/›búÈÝ{b/;/Ò²žRfVý¾]¤]ÄÅ}QKæÃ˜¾……ò7^Ø——éYO)³+~ßnÿÒ.âbþ¨¥ó_ÌOBÂùŸlGËÖËô¬§”ƒÙ•ƒÙúð;Î.âbþ©¥ó_ÌOBÂùŸlOåëeúVSÊAìÊßõyÿŸ¹¿‰ŒúªšîbzÈÜûb>^ö_¥e<¤̬=÷û—ø˜Ïª©|Öóа¾FçÛù{Ùž•”ò{2°pø?ßîOâ#>ª¥óYÌ?BÂùŸkGËæÌô¬§”ƒÙ•¿ê ÿÿ=rõ]/š¾aúÈÜûZ/›3Ò²žRfV$ýþãëqõ]5|Ãô<7‘¹ö´|¾lÏIÉùH=™[þ¡R!ÞZãþ"7êÊ>j¹…èX_#síhù}Ùž•”ò{2dx ß.ò—Ã^Rv;¢ÃÙÇÚu…qKüÓsF6×Çë6Š«§ äùÙlxs§É8£,4>0ø]÷øB9Ê ž0©¨Q.ó‡w<ÂUŠ[Þ&è5yVëæ†ùÞŒ0g²¾Èš÷, Š/¢¬Œ4>FMdv¯AÛÛ iíw qq²è w®¬’}4{Ë‹kÖ¤} Ѽk†!,–艧۔¥ÔÛ…×PþºsÖ€·Þ…)HP)C@Є+P…(Bø|]¯ü'Ñ÷¿ûÍ5¡ æùÔüÚ§Èž§æÐ…>Dõ?6„)ò'©ù´!O‘=OÍ¡ |‰ê~mSäOSóhBŸ"zŸ›BùÔüÚ§Èž§æÐ…>Dõ?6„)ò'©ù´!O‘=OÍ¡ |‰ê~mSäOSóhBŸ"zŸ›BùÔüÚ§Èž§æÐ…>Dõ?6„)ò'©ù´!O‘=OÍ¡ |‰ê~mSäOSóhBŸ"zŸ›BùÔüÚ§Èž§æÐ…>Dõ?6„)ò'©ù´!O‘=OÍ¡ |‰ê~mSäOSóhBŸ"zŸ›BùÔüÚ§Èž§æÐ…>Dõ?6„)ò'©ù´!O‘=OÍ¡ |‰ê~mSäOSóhBŸ"zŸ›BùÔüÚ§Èž§æÐ…>Dõ?6„)ò'©ù´!O‘=OÍ¡ |‰ê~mSäOSóhBŸ"zŸ›BùÔüÚ§Èž§æÐ…>Dõ?6„)ò'©ù´!O‘=OÍ¡ |‰ê~mSäOSóhBŸ"zŸ›BùÔüÚ§Èž§æÐ…>Dõ?6„)ò'©ù´!O‘=OÍ¡ |‰ê~mSäOSóhBŸ"zŸ›BùÔüÚ§Èž§æÐ…>Dõ?6„)ò'©ù´!O‘=OÍ¡ |‰ê~mSäOSóhBŸ"zŸ›BùÔüÚ§Èž§æÐ…>Dõ?6„)ò'©ù´!O‘=OÍ¡ |‰ê~mSäOSóhBŸ"zŸ›BùÔüÚ§Èž§æÐ…>Dõ?6„)ò'©ù´!O‘=OÍ¡ |‰ê~mSäOSóhBŸ"zŸ›BùÔüÚ§Èž§æÐ…>Dõ?6„)ò'©ù´!O‘=OÍ¡ |‰ê~mSäOSóhBŸ"zŸ›BùÔüÚ¾ô=Oì; ?û¿à¡ é¡ P…(B”!ÿÙopenchange-2.0/apidocs/html/mapiproxy/index.html000066400000000000000000000114571223057412600221070ustar00rootroot00000000000000 MAPIProxy 2.0 API Documentation
The OpenChange Server Reference

Introduction

This is the online reference for configuring mapiproxy and developing with the OpenChange server code:

  • Users will find documentation on how to setup mapiproxy, mapiproxy modules, openchange server, how to provision samba4 and openchange. User's documentation is tagged with the user icon.
  • Developers will find documentation on OpenChange server internals, design, architecture, implementation and API references. Developer's documentation is tagged with the box icon.

MAPIProxy documentation

MAPIProxy is an endpoint server for Samba4 which proxies ExchangeRPC traffic from MAPI clients (Outlook, openchangeclient, etc.) to Microsoft Exchange Server (and back). It can either act as a transparent proxy, for hacking, monitoring or debugging purposes or modify traffic on the fly and so provide new features. It is primarily developed for - but not limited to - third-party implementors looking for a development framework they can use for MAPI acceleration purposes.
Link to MAPIProxy documentation:

MAPIStore documentation

MAPIStore is the SAL component of OpenChange server. SAL stands for Storage Abstraction Layer. It is the component used by OpenChange Server to push/get information (messages, folders) to/from storage backends. The following document intends to describe the overall/theoretical SAL behavior and contraints we need to consider when dealing with MAPI/EMSMDB. It also describes the semantics and inner working of its storage backends.

Link to MAPIStore documentation:

Creative Commons License
Creative Commons Attribution icon Creative Commons Share Alike icon
This content is licensed under the Creative Commons
Attribution ShareAlike License v. 3.0:
http://creativecommons.org/licenses/by-sa/3.0/

openchange-2.0/apidocs/html/mapiproxy/libmapiserver__oxcdata_8c.html000066400000000000000000000226501223057412600260750ustar00rootroot00000000000000 MAPIProxy 2.0 API Documentation
libmapiserver_oxcdata.c File Reference

OXCDATA Data Structures. More...

#include "libmapiserver.h"
#include "libmapi/mapidefs.h"
#include <util/debug.h>

Functions

_PUBLIC_ uint16_t libmapiserver_LongTermId_size (void)
_PUBLIC_ uint16_t libmapiserver_mapi_SPropValue_size (uint16_t cValues, struct mapi_SPropValue *lpProps)
_PUBLIC_ uint16_t libmapiserver_PropertyName_size (struct MAPINAMEID *property_name)
_PUBLIC_ uint16_t libmapiserver_RecipientRow_size (struct RecipientRow recipientrow)
uint16_t libmapiserver_TypedString_size (struct TypedString typedstring)

Detailed Description

OXCDATA Data Structures.

Function Documentation

_PUBLIC_ uint16_t libmapiserver_LongTermId_size ( void  )

Calculate the size of a LongTermId structure

Returns
Size of LongTermId structure

Referenced by libmapiserver_RopGetPerUserLongTermIds_size().

_PUBLIC_ uint16_t libmapiserver_mapi_SPropValue_size ( uint16_t  cValues,
struct mapi_SPropValue *  lpProps 
)

Calculate the size of a mapi_SPropValue array structure

Returns
Size of mapi_SPropValue structure

Referenced by libmapiserver_RopGetPropertiesAll_size().

_PUBLIC_ uint16_t libmapiserver_PropertyName_size ( struct MAPINAMEID *  property_name)

Calculate the size of a PropertyName structure

Returns
Size of PropertyName structure

Referenced by libmapiserver_RopGetNamesFromIDs_size().

_PUBLIC_ uint16_t libmapiserver_RecipientRow_size ( struct RecipientRow  recipientrow)

Calculate the size of a RecipientRow structure

Parameters
recipientrowRecipientRow structure
Returns
Size of RecipientRow structure

Referenced by libmapiserver_RopOpenEmbeddedMessage_size(), libmapiserver_RopOpenMessage_size(), and libmapiserver_RopReloadCachedInformation_size().

uint16_t libmapiserver_TypedString_size ( struct TypedString  typedstring)

Calculate the size of a TypedString structure

Parameters
typedstringTypedString structure
Returns
Size of typedstring structure

Referenced by libmapiserver_RopOpenEmbeddedMessage_size(), libmapiserver_RopOpenMessage_size(), and libmapiserver_RopReloadCachedInformation_size().


Creative Commons License
Creative Commons Attribution icon Creative Commons Share Alike icon
This content is licensed under the Creative Commons
Attribution ShareAlike License v. 3.0:
http://creativecommons.org/licenses/by-sa/3.0/

openchange-2.0/apidocs/html/mapiproxy/libmapiserver__oxcfold_8c.html000066400000000000000000000435541223057412600261160ustar00rootroot00000000000000 MAPIProxy 2.0 API Documentation
libmapiserver_oxcfold.c File Reference

OXCFOLD ROP Response size calculations. More...

#include "libmapiserver.h"

Functions

uint16_t libmapiserver_RopCopyFolder_size (struct EcDoRpc_MAPI_REPL *response)
_PUBLIC_ uint16_t libmapiserver_RopCreateFolder_size (struct EcDoRpc_MAPI_REPL *response)
_PUBLIC_ uint16_t libmapiserver_RopDeleteFolder_size (struct EcDoRpc_MAPI_REPL *response)
_PUBLIC_ uint16_t libmapiserver_RopDeleteMessage_size (struct EcDoRpc_MAPI_REPL *response)
_PUBLIC_ uint16_t libmapiserver_RopEmptyFolder_size (struct EcDoRpc_MAPI_REPL *response)
_PUBLIC_ uint16_t libmapiserver_RopGetContentsTable_size (struct EcDoRpc_MAPI_REPL *response)
_PUBLIC_ uint16_t libmapiserver_RopGetHierarchyTable_size (struct EcDoRpc_MAPI_REPL *response)
_PUBLIC_ uint16_t libmapiserver_RopGetSearchCriteria_size (struct EcDoRpc_MAPI_REPL *response)
_PUBLIC_ uint16_t libmapiserver_RopMoveCopyMessages_size (struct EcDoRpc_MAPI_REPL *response)
uint16_t libmapiserver_RopMoveFolder_size (struct EcDoRpc_MAPI_REPL *response)
uint16_t libmapiserver_RopOpenFolder_size (struct EcDoRpc_MAPI_REPL *response)
_PUBLIC_ uint16_t libmapiserver_RopSetSearchCriteria_size (struct EcDoRpc_MAPI_REPL *response)

Detailed Description

OXCFOLD ROP Response size calculations.

Function Documentation

uint16_t libmapiserver_RopCopyFolder_size ( struct EcDoRpc_MAPI_REPL *  response)

Calculate CopyFolder rop size

Parameters
responsepointer to the CopyFolder EcDoRpc_MAPI_REPL structure
Returns
Size of CopyFolder response

Referenced by EcDoRpc_RopCopyFolder().

_PUBLIC_ uint16_t libmapiserver_RopCreateFolder_size ( struct EcDoRpc_MAPI_REPL *  response)

Calculate CreateFolder Rop size

Parameters
responsepointer to the CreateFolder EcDoRpc_MAPI_REPL structure
Returns
Size of CreateFolder response

Referenced by EcDoRpc_RopCreateFolder().

_PUBLIC_ uint16_t libmapiserver_RopDeleteFolder_size ( struct EcDoRpc_MAPI_REPL *  response)

Calculate DeleteFolder Rop size

Parameters
responsepointer to the DeleteFolder EcDoRpc_MAPI_REPL structure
Returns
Size of DeleteFolder response

Referenced by EcDoRpc_RopDeleteFolder().

_PUBLIC_ uint16_t libmapiserver_RopDeleteMessage_size ( struct EcDoRpc_MAPI_REPL *  response)

Calculate DeleteMessage (0x1e) Rop size

Parameters
responsepointer to the DeleteMessage EcDoRpc_MAPI_REPL structure
Returns
Size of DeleteMessage response

Referenced by EcDoRpc_RopDeleteMessages().

_PUBLIC_ uint16_t libmapiserver_RopEmptyFolder_size ( struct EcDoRpc_MAPI_REPL *  response)

Calculate EmptyFolder Rop size

Parameters
responsepointer to the EmptyFolder EcDoRpc_MAPI_REPL structure
Returns
Size of EmptyFolder response

Referenced by EcDoRpc_RopEmptyFolder().

_PUBLIC_ uint16_t libmapiserver_RopGetContentsTable_size ( struct EcDoRpc_MAPI_REPL *  response)

Calculate GetContentsTable Rop size

Parameters
responsepointer to the GetContentsTable EcDoRpc_MAPI_REPL structure
Returns
Size of GetContentsTable response

Referenced by EcDoRpc_RopGetContentsTable().

_PUBLIC_ uint16_t libmapiserver_RopGetHierarchyTable_size ( struct EcDoRpc_MAPI_REPL *  response)

Calculate GetHierarchyTable Rop size

Parameters
responsepointer to the GetHierarchyTable EcDoRpc_MAPI_REPL structure
Returns
Size of GetHierarchyTable response

Referenced by EcDoRpc_RopGetHierarchyTable().

_PUBLIC_ uint16_t libmapiserver_RopGetSearchCriteria_size ( struct EcDoRpc_MAPI_REPL *  response)

Calculate GetSearchCriteria (0x31) Rop size

Parameters
responsepointer to the GetSearchCriteria EcDoRpc_MAPI_REPL structure
Returns
Size of GetSearchCriteria response

Referenced by EcDoRpc_RopGetSearchCriteria().

_PUBLIC_ uint16_t libmapiserver_RopMoveCopyMessages_size ( struct EcDoRpc_MAPI_REPL *  response)

Calculate MoveCopyMessages rop size

Parameters
responsepointer to the MoveCopyMessags EcDoRpc_MAPI_REPL structure
Returns
Size of MoveCopyMessages response
uint16_t libmapiserver_RopMoveFolder_size ( struct EcDoRpc_MAPI_REPL *  response)

Calculate MoveFolder rop size

Parameters
responsepointer to the MoveFolder EcDoRpc_MAPI_REPL structure
Returns
Size of MoveFolder response

Referenced by EcDoRpc_RopMoveFolder().

uint16_t libmapiserver_RopOpenFolder_size ( struct EcDoRpc_MAPI_REPL *  response)

Calculate OpenFolder Rop size

Parameters
responsepointer to the OpenFolder EcDoRpc_MAPI_REPL structure
Returns
Size of OpenFolder response

Referenced by EcDoRpc_RopOpenFolder().

_PUBLIC_ uint16_t libmapiserver_RopSetSearchCriteria_size ( struct EcDoRpc_MAPI_REPL *  response)

Calculate SetSearchCriteria (0x30) Rop size

Parameters
responsepointer to the SetSearchCriteria EcDoRpc_MAPI_REPL structure
Returns
Size of SetSearchCriteria response

Referenced by EcDoRpc_RopSetSearchCriteria().


Creative Commons License
Creative Commons Attribution icon Creative Commons Share Alike icon
This content is licensed under the Creative Commons
Attribution ShareAlike License v. 3.0:
http://creativecommons.org/licenses/by-sa/3.0/

openchange-2.0/apidocs/html/mapiproxy/libmapiserver__oxcfxics_8c.html000066400000000000000000000551501223057412600263010ustar00rootroot00000000000000 MAPIProxy 2.0 API Documentation
libmapiserver_oxcfxics.c File Reference

OXCFXICS ROP Response size calculations. More...

#include "libmapiserver.h"

Functions

uint16_t libmapiserver_RopFastTransferSourceCopyTo_size (struct EcDoRpc_MAPI_REPL *response)
_PUBLIC_ uint16_t libmapiserver_RopFastTransferSourceGetBuffer_size (struct EcDoRpc_MAPI_REPL *response)
_PUBLIC_ uint16_t libmapiserver_RopGetLocalReplicaIds_size (struct EcDoRpc_MAPI_REPL *response)
_PUBLIC_ uint16_t libmapiserver_RopSetLocalReplicaMidsetDeleted_size (struct EcDoRpc_MAPI_REPL *response)
_PUBLIC_ uint16_t libmapiserver_RopSyncConfigure_size (struct EcDoRpc_MAPI_REPL *response)
_PUBLIC_ uint16_t libmapiserver_RopSyncGetTransferState_size (struct EcDoRpc_MAPI_REPL *response)
_PUBLIC_ uint16_t libmapiserver_RopSyncImportDeletes_size (struct EcDoRpc_MAPI_REPL *response)
_PUBLIC_ uint16_t libmapiserver_RopSyncImportHierarchyChange_size (struct EcDoRpc_MAPI_REPL *response)
_PUBLIC_ uint16_t libmapiserver_RopSyncImportMessageChange_size (struct EcDoRpc_MAPI_REPL *response)
_PUBLIC_ uint16_t libmapiserver_RopSyncImportMessageMove_size (struct EcDoRpc_MAPI_REPL *response)
_PUBLIC_ uint16_t libmapiserver_RopSyncImportReadStateChanges_size (struct EcDoRpc_MAPI_REPL *response)
_PUBLIC_ uint16_t libmapiserver_RopSyncOpenCollector_size (struct EcDoRpc_MAPI_REPL *response)
_PUBLIC_ uint16_t libmapiserver_RopSyncUploadStateStreamBegin_size (struct EcDoRpc_MAPI_REPL *response)
_PUBLIC_ uint16_t libmapiserver_RopSyncUploadStateStreamContinue_size (struct EcDoRpc_MAPI_REPL *response)
_PUBLIC_ uint16_t libmapiserver_RopSyncUploadStateStreamEnd_size (struct EcDoRpc_MAPI_REPL *response)

Detailed Description

OXCFXICS ROP Response size calculations.

Function Documentation

uint16_t libmapiserver_RopFastTransferSourceCopyTo_size ( struct EcDoRpc_MAPI_REPL *  response)

Calculate FastTransferSourceCopyTo (0x4d) Rop size

Parameters
responsepointer to the FastTransferSourceCopyTo EcDoRpc_MAPI_REPL structure
Returns
Size of FastTransferSourceCopyTo response

Referenced by EcDoRpc_RopFastTransferSourceCopyTo().

_PUBLIC_ uint16_t libmapiserver_RopFastTransferSourceGetBuffer_size ( struct EcDoRpc_MAPI_REPL *  response)

Calculate FastTransferSourceGetBuffer (0x4d) Rop size

Parameters
responsepointer to the FastTransferSourceGetBuffer EcDoRpc_MAPI_REPL structure
Returns
Size of FastTransferSourceGetBuffer response

Referenced by EcDoRpc_RopFastTransferSourceGetBuffer().

_PUBLIC_ uint16_t libmapiserver_RopGetLocalReplicaIds_size ( struct EcDoRpc_MAPI_REPL *  response)

Calculate GetLocalReplicaIds (0x7f) Rop size

Parameters
responsepointer to the GetLocalReplicaIds EcDoRpc_MAPI_REPL structure
Returns
Size of GetLocalReplicaIds response

Referenced by EcDoRpc_RopGetLocalReplicaIds().

_PUBLIC_ uint16_t libmapiserver_RopSetLocalReplicaMidsetDeleted_size ( struct EcDoRpc_MAPI_REPL *  response)

Calculate SetLocalReplicaMidsetDeleted (0x93) Rop size

Parameters
responsepointer to the SetLocalReplicaMidsetDeleted EcDoRpc_MAPI_REPL structure
Returns
Size of SetLocalReplicaMidsetDeleted response

Referenced by EcDoRpc_RopSetLocalReplicaMidsetDeleted().

_PUBLIC_ uint16_t libmapiserver_RopSyncConfigure_size ( struct EcDoRpc_MAPI_REPL *  response)

Calculate SyncConfigure (0x70) Rop size

Parameters
responsepointer to the SyncConfigure EcDoRpc_MAPI_REPL structure
Returns
Size of SyncConfigure response

Referenced by EcDoRpc_RopSyncConfigure().

_PUBLIC_ uint16_t libmapiserver_RopSyncGetTransferState_size ( struct EcDoRpc_MAPI_REPL *  response)

Calculate SyncGetTransferState (0x82) Rop size

Parameters
responsepointer to the SyncGetTransferState EcDoRpc_MAPI_REPL structure
Returns
Size of SyncGetTransferState response

Referenced by EcDoRpc_RopSyncGetTransferState().

_PUBLIC_ uint16_t libmapiserver_RopSyncImportDeletes_size ( struct EcDoRpc_MAPI_REPL *  response)

Calculate SyncImportDeletes (0x74) Rop size

Parameters
responsepointer to the SyncImportDeletes EcDoRpc_MAPI_REPL structure
Returns
Size of SyncImportDeletes response

Referenced by EcDoRpc_RopSyncImportDeletes().

_PUBLIC_ uint16_t libmapiserver_RopSyncImportHierarchyChange_size ( struct EcDoRpc_MAPI_REPL *  response)

Calculate SyncImportHierarchyChange (0x73) Rop size

Parameters
responsepointer to the SyncImportHierarchyChange EcDoRpc_MAPI_REPL structure
Returns
Size of SyncImportHierarchyChange response

Referenced by EcDoRpc_RopSyncImportHierarchyChange().

_PUBLIC_ uint16_t libmapiserver_RopSyncImportMessageChange_size ( struct EcDoRpc_MAPI_REPL *  response)

Calculate SyncImportMessageChange (0x73) Rop size

Parameters
responsepointer to the SyncImportMessageChange EcDoRpc_MAPI_REPL structure
Returns
Size of SyncImportMessageChange response

Referenced by EcDoRpc_RopSyncImportMessageChange().

_PUBLIC_ uint16_t libmapiserver_RopSyncImportMessageMove_size ( struct EcDoRpc_MAPI_REPL *  response)

Calculate SyncImportMessageMove (0x78) Rop size

Parameters
responsepointer to the SyncImportMessageMove EcDoRpc_MAPI_REPL structure
Returns
Size of SyncImportMessageMove response
_PUBLIC_ uint16_t libmapiserver_RopSyncImportReadStateChanges_size ( struct EcDoRpc_MAPI_REPL *  response)

Calculate SyncImportReadStateChanges (0x80) Rop size

Parameters
responsepointer to the SyncImportReadStateChanges EcDoRpc_MAPI_REPL structure
Returns
Size of SyncImportReadStateChanges response

Referenced by EcDoRpc_RopSyncImportReadStateChanges().

_PUBLIC_ uint16_t libmapiserver_RopSyncOpenCollector_size ( struct EcDoRpc_MAPI_REPL *  response)

Calculate SyncOpenCollector (0x7e) Rop size

Parameters
responsepointer to the SyncOpenCollector EcDoRpc_MAPI_REPL structure
Returns
Size of SyncOpenCollector response

Referenced by EcDoRpc_RopSyncOpenCollector().

_PUBLIC_ uint16_t libmapiserver_RopSyncUploadStateStreamBegin_size ( struct EcDoRpc_MAPI_REPL *  response)

Calculate SyncUploadStateStreamBegin (0x75) Rop size

Parameters
responsepointer to the SyncUploadStateStreamBegin EcDoRpc_MAPI_REPL structure
Returns
Size of SyncUploadStateStreamBegin response

Referenced by EcDoRpc_RopSyncUploadStateStreamBegin().

_PUBLIC_ uint16_t libmapiserver_RopSyncUploadStateStreamContinue_size ( struct EcDoRpc_MAPI_REPL *  response)

Calculate SyncUploadStateStreamContinue (0x76) Rop size

Parameters
responsepointer to the SyncUploadStateStreamContinue EcDoRpc_MAPI_REPL structure
Returns
Size of SyncUploadStateStreamContinue response

Referenced by EcDoRpc_RopSyncUploadStateStreamContinue().

_PUBLIC_ uint16_t libmapiserver_RopSyncUploadStateStreamEnd_size ( struct EcDoRpc_MAPI_REPL *  response)

Calculate SyncUploadStateStreamEnd (0x77) Rop size

Parameters
responsepointer to the SyncUploadStateStreamEnd EcDoRpc_MAPI_REPL structure
Returns
Size of SyncUploadStateStreamEnd response

Referenced by EcDoRpc_RopSyncUploadStateStreamEnd().


Creative Commons License
Creative Commons Attribution icon Creative Commons Share Alike icon
This content is licensed under the Creative Commons
Attribution ShareAlike License v. 3.0:
http://creativecommons.org/licenses/by-sa/3.0/

openchange-2.0/apidocs/html/mapiproxy/libmapiserver__oxcmsg_8c.html000066400000000000000000000460131223057412600257510ustar00rootroot00000000000000 MAPIProxy 2.0 API Documentation
libmapiserver_oxcmsg.c File Reference

OXCMSG ROP Response size calculations. More...

#include "libmapiserver.h"

Functions

_PUBLIC_ uint16_t libmapiserver_RopCreateAttach_size (struct EcDoRpc_MAPI_REPL *response)
_PUBLIC_ uint16_t libmapiserver_RopCreateMessage_size (struct EcDoRpc_MAPI_REPL *response)
_PUBLIC_ uint16_t libmapiserver_RopGetAttachmentTable_size (struct EcDoRpc_MAPI_REPL *response)
_PUBLIC_ uint16_t libmapiserver_RopModifyRecipients_size (struct EcDoRpc_MAPI_REPL *response)
_PUBLIC_ uint16_t libmapiserver_RopOpenAttach_size (struct EcDoRpc_MAPI_REPL *response)
_PUBLIC_ uint16_t libmapiserver_RopOpenEmbeddedMessage_size (struct EcDoRpc_MAPI_REPL *response)
uint16_t libmapiserver_RopOpenMessage_size (struct EcDoRpc_MAPI_REPL *response)
_PUBLIC_ uint16_t libmapiserver_RopReloadCachedInformation_size (struct EcDoRpc_MAPI_REPL *response)
_PUBLIC_ uint16_t libmapiserver_RopRemoveAllRecipients_size (struct EcDoRpc_MAPI_REPL *response)
_PUBLIC_ uint16_t libmapiserver_RopSaveChangesAttachment_size (struct EcDoRpc_MAPI_REPL *response)
_PUBLIC_ uint16_t libmapiserver_RopSaveChangesMessage_size (struct EcDoRpc_MAPI_REPL *response)
_PUBLIC_ uint16_t libmapiserver_RopSetMessageReadFlag_size (struct EcDoRpc_MAPI_REPL *response)

Detailed Description

OXCMSG ROP Response size calculations.

Function Documentation

_PUBLIC_ uint16_t libmapiserver_RopCreateAttach_size ( struct EcDoRpc_MAPI_REPL *  response)

Calculate CreateAttach (0x23) Rop size

Parameters
responsepointer to the CreateAttach EcDoRpc_MAPI_REPL
Returns
Size of CreateAttach response

Referenced by EcDoRpc_RopCreateAttach().

_PUBLIC_ uint16_t libmapiserver_RopCreateMessage_size ( struct EcDoRpc_MAPI_REPL *  response)

Calculate CreateMessage (0x6) Rop size

Parameters
responsepointer to the CreateMessage EcDoRpc_MAPI_REPL structure
Returns
Size of CreateMessage response

Referenced by EcDoRpc_RopCreateMessage().

_PUBLIC_ uint16_t libmapiserver_RopGetAttachmentTable_size ( struct EcDoRpc_MAPI_REPL *  response)

Calculate GetAttachmentTable (0x21) Rop size

Parameters
responsepointer to the GetAttachmentTable EcDoRpc_MAPI_REPL
Returns
Size of GetAttachmentTable response

Referenced by EcDoRpc_RopGetAttachmentTable().

_PUBLIC_ uint16_t libmapiserver_RopModifyRecipients_size ( struct EcDoRpc_MAPI_REPL *  response)

Calculate ModifyRecipients (0xe) Rop size

Parameters
responsepointer to the ModifyRecipients EcDoRpc_MAPI_REPL structure
Returns
Size of ModifyRecipients response

Referenced by EcDoRpc_RopModifyRecipients().

_PUBLIC_ uint16_t libmapiserver_RopOpenAttach_size ( struct EcDoRpc_MAPI_REPL *  response)

Calculate OpenAttach (0x22) Rop size

Parameters
responsepointer to the OpenAttach EcDoRpc_MAPI_REPL
Returns
Size of OpenAttach response

Referenced by EcDoRpc_RopOpenAttach().

_PUBLIC_ uint16_t libmapiserver_RopOpenEmbeddedMessage_size ( struct EcDoRpc_MAPI_REPL *  response)

Calculate OpenEmbeddedMessage (0x46) Rop size

Parameters
responsepointer to the OpenEmbeddedMessage EcDoRpc_MAPI_REPL
Returns
Size of OpenEmbeddedMessage response

References libmapiserver_RecipientRow_size(), and libmapiserver_TypedString_size().

Referenced by EcDoRpc_RopOpenEmbeddedMessage().

uint16_t libmapiserver_RopOpenMessage_size ( struct EcDoRpc_MAPI_REPL *  response)

Calculate OpenMessage (0x3) Rop size

Parameters
responsepointer to the OpenMessage EcDoRpc_MAPI_REPL structure
Returns
Size of OpenMessage response

References libmapiserver_RecipientRow_size(), and libmapiserver_TypedString_size().

Referenced by EcDoRpc_RopOpenMessage().

_PUBLIC_ uint16_t libmapiserver_RopReloadCachedInformation_size ( struct EcDoRpc_MAPI_REPL *  response)

Calculate ReloadCachedInformation (0x10) Rop size

Parameters
responsepointer to the ReloadCachedInformation EcDoRpc_MAPI_REPL structure
Returns
Size of ReloadCachedInformation response

References libmapiserver_RecipientRow_size(), and libmapiserver_TypedString_size().

Referenced by EcDoRpc_RopReloadCachedInformation().

_PUBLIC_ uint16_t libmapiserver_RopRemoveAllRecipients_size ( struct EcDoRpc_MAPI_REPL *  response)

Calculate RemoveAllRecipients (0xd) Rop size

Parameters
responsepointer to the RemoveAllRecipients EcDoRpc_MAPI_REPL structure
Returns
Size of RemoveAllRecipients response

Referenced by EcDoRpc_RopRemoveAllRecipients().

_PUBLIC_ uint16_t libmapiserver_RopSaveChangesAttachment_size ( struct EcDoRpc_MAPI_REPL *  response)

Calculate SaveChangesAttachment (0x25) Rop size

Parameters
responsepointer to the SaveChangesAttachment EcDoRpc_MAPI_REPL
Returns
Size of SaveChangesAttachment response

Referenced by EcDoRpc_RopSaveChangesAttachment().

_PUBLIC_ uint16_t libmapiserver_RopSaveChangesMessage_size ( struct EcDoRpc_MAPI_REPL *  response)

Calculate SaveChangesMessage (0xc) Rop size

Parameters
responsepointer to the SaveChangesMessage EcDoRpc_MAPI_REPL structure
Returns
Size of SaveChangesMessage response

Referenced by EcDoRpc_RopSaveChangesMessage().

_PUBLIC_ uint16_t libmapiserver_RopSetMessageReadFlag_size ( struct EcDoRpc_MAPI_REPL *  response)

Calculate SetMessageReadFlag (0x11) Rop size

Parameters
responsepointer to the SetMessageReadFlag EcDoRpc_MAPI_REPL structure
Returns
Size of SetMessageReadFlag response

Referenced by EcDoRpc_RopSetMessageReadFlag().


Creative Commons License
Creative Commons Attribution icon Creative Commons Share Alike icon
This content is licensed under the Creative Commons
Attribution ShareAlike License v. 3.0:
http://creativecommons.org/licenses/by-sa/3.0/

openchange-2.0/apidocs/html/mapiproxy/libmapiserver__oxcnotif_8c.html000066400000000000000000000114441223057412600263020ustar00rootroot00000000000000 MAPIProxy 2.0 API Documentation
libmapiserver_oxcnotif.c File Reference

OXCNOTIF ROP Response size calculations. More...

#include "libmapiserver.h"
#include <util/debug.h>

Functions

_PUBLIC_ uint16_t libmapiserver_RopNotify_size (struct EcDoRpc_MAPI_REPL *response)
uint16_t libmapiserver_RopRegisterNotification_size (void)

Detailed Description

OXCNOTIF ROP Response size calculations.

Function Documentation

_PUBLIC_ uint16_t libmapiserver_RopNotify_size ( struct EcDoRpc_MAPI_REPL *  response)

Calculate Notify Rop size

Returns
Size of Notify response
uint16_t libmapiserver_RopRegisterNotification_size ( void  )

Calculate RegisterNotification Rop size

Returns
Size of RegisterNotification response

Referenced by EcDoRpc_RopRegisterNotification().


Creative Commons License
Creative Commons Attribution icon Creative Commons Share Alike icon
This content is licensed under the Creative Commons
Attribution ShareAlike License v. 3.0:
http://creativecommons.org/licenses/by-sa/3.0/

openchange-2.0/apidocs/html/mapiproxy/libmapiserver__oxcprpt_8c.html000066400000000000000000000733271223057412600261600ustar00rootroot00000000000000 MAPIProxy 2.0 API Documentation
libmapiserver_oxcprpt.c File Reference

OXCPRPT ROP Response size calculations. More...

#include "libmapiserver.h"
#include "libmapi/libmapi.h"
#include "libmapi/mapidefs.h"

Functions

_PUBLIC_ int libmapiserver_push_property (TALLOC_CTX *mem_ctx, uint32_t property, const void *value, DATA_BLOB *blob, uint8_t layout, uint8_t flagged, uint8_t untyped)
_PUBLIC_ struct SRow * libmapiserver_ROP_request_to_properties (TALLOC_CTX *mem_ctx, void *request, uint8_t opnum)
_PUBLIC_ uint16_t libmapiserver_RopCommitStream_size (struct EcDoRpc_MAPI_REPL *response)
_PUBLIC_ uint16_t libmapiserver_RopCopyTo_size (struct EcDoRpc_MAPI_REPL *response)
_PUBLIC_ uint16_t libmapiserver_RopDeleteProperties_size (struct EcDoRpc_MAPI_REPL *response)
_PUBLIC_ uint16_t libmapiserver_RopDeletePropertiesNoReplicate_size (struct EcDoRpc_MAPI_REPL *response)
_PUBLIC_ uint16_t libmapiserver_RopGetNamesFromIDs_size (struct EcDoRpc_MAPI_REPL *response)
_PUBLIC_ uint16_t libmapiserver_RopGetPropertiesAll_size (struct EcDoRpc_MAPI_REPL *response)
_PUBLIC_ uint16_t libmapiserver_RopGetPropertiesList_size (struct EcDoRpc_MAPI_REPL *response)
_PUBLIC_ uint16_t libmapiserver_RopGetPropertiesSpecific_size (struct EcDoRpc_MAPI_REQ *request, struct EcDoRpc_MAPI_REPL *response)
_PUBLIC_ uint16_t libmapiserver_RopGetPropertyIdsFromNames_size (struct EcDoRpc_MAPI_REPL *response)
_PUBLIC_ uint16_t libmapiserver_RopGetStreamSize_size (struct EcDoRpc_MAPI_REPL *response)
_PUBLIC_ uint16_t libmapiserver_RopOpenStream_size (struct EcDoRpc_MAPI_REPL *response)
_PUBLIC_ uint16_t libmapiserver_RopReadStream_size (struct EcDoRpc_MAPI_REPL *response)
_PUBLIC_ uint16_t libmapiserver_RopSeekStream_size (struct EcDoRpc_MAPI_REPL *response)
_PUBLIC_ uint16_t libmapiserver_RopSetProperties_size (struct EcDoRpc_MAPI_REPL *response)
_PUBLIC_ uint16_t libmapiserver_RopSetStreamSize_size (struct EcDoRpc_MAPI_REPL *response)
_PUBLIC_ uint16_t libmapiserver_RopWriteStream_size (struct EcDoRpc_MAPI_REPL *response)

Detailed Description

OXCPRPT ROP Response size calculations.

Function Documentation

_PUBLIC_ int libmapiserver_push_property ( TALLOC_CTX *  mem_ctx,
uint32_t  property,
const void *  value,
DATA_BLOB *  blob,
uint8_t  layout,
uint8_t  flagged,
uint8_t  untyped 
)

Add a property value to a DATA blob. This convenient function should be used when creating a GetPropertiesSpecific reply response blob.

Parameters
mem_ctxpointer to the memory context
propertythe property tag which value is meant to be appended to the blob
valuegeneric pointer on the property value
blobthe data blob the function uses to return the blob
layoutwhether values should be prefixed by a layout
flaggeddefine if the properties are flagged or not
Note
blob.length must be set to 0 before this function is called the first time. Also the function only supports a limited set of property types at the moment.
Returns
0 on success;

Referenced by EcDoRpc_RopFindRow(), and emsmdbp_resolve_recipient().

_PUBLIC_ struct SRow* libmapiserver_ROP_request_to_properties ( TALLOC_CTX *  mem_ctx,
void *  request,
uint8_t  opnum 
)
read

Turn request parameters to SPropValue array. This convenient function should be used among MAPI ROPs that have parameters which can be turned to MAPI properties and are stored within backends.

Parameters
mem_ctxpointer to the memory context
requestgeneric pointer to the ROP request
opnumMAPI opnum identifying ROP contents
Note
Developers must talloc_free returned SRow after they finish using it.
Returns
Allocated SRow on success, otherwise NULL

Referenced by EcDoRpc_RopCreateFolder().

_PUBLIC_ uint16_t libmapiserver_RopCommitStream_size ( struct EcDoRpc_MAPI_REPL *  response)

Calculate CommitStream Rop size

Parameters
responsepointer to the CommitStream EcDoRpc_MAPI_REPL structure
Returns
Size of CommitStream response

Referenced by EcDoRpc_RopCommitStream().

_PUBLIC_ uint16_t libmapiserver_RopCopyTo_size ( struct EcDoRpc_MAPI_REPL *  response)

Calculate CopyTo Rop size

Parameters
responsepointer to the CopyTo EcDoRpc_MAPI_REPL structure
Returns
Size of SetProperties response

Referenced by EcDoRpc_RopCopyTo().

_PUBLIC_ uint16_t libmapiserver_RopDeleteProperties_size ( struct EcDoRpc_MAPI_REPL *  response)

Calculate SetProperties Rop size

Parameters
responsepointer to the SetProperties EcDoRpc_MAPI_REPL structure
Returns
Size of SetProperties response

Referenced by EcDoRpc_RopDeleteProperties().

_PUBLIC_ uint16_t libmapiserver_RopDeletePropertiesNoReplicate_size ( struct EcDoRpc_MAPI_REPL *  response)

Calculate DeletePropertiesNoReplicate Rop size

Parameters
responsepointer to the DeletePropertiesNoReplicate EcDoRpc_MAPI_REPL structure
Returns
Size of DeletePropertiesNoReplicate response

Referenced by EcDoRpc_RopDeletePropertiesNoReplicate().

_PUBLIC_ uint16_t libmapiserver_RopGetNamesFromIDs_size ( struct EcDoRpc_MAPI_REPL *  response)

Calculate GetNamesFromIDs Rop size

Parameters
responsepointer to the GetNamesFromIDs EcDoRpc_MAPI_REPL structure
Returns
Size of GetNamesFromIDs response

References libmapiserver_PropertyName_size().

Referenced by EcDoRpc_RopGetNamesFromIDs().

_PUBLIC_ uint16_t libmapiserver_RopGetPropertiesAll_size ( struct EcDoRpc_MAPI_REPL *  response)

Calculate GetPropertiesAll Rop size

Parameters
requestpointer to the GetPropertiesAll EcDoRpc_MAPI_REPL structure
Returns
Size of GetPropsAll response

References libmapiserver_mapi_SPropValue_size().

Referenced by EcDoRpc_RopGetPropertiesAll().

_PUBLIC_ uint16_t libmapiserver_RopGetPropertiesList_size ( struct EcDoRpc_MAPI_REPL *  response)

Calculate GetPropertiesList Rop size

Parameters
requestpointer to the GetPropertiesList EcDoRpc_MAPI_REPL structure
Returns
Size of GetPropertiesList response

Referenced by EcDoRpc_RopGetPropertiesList().

_PUBLIC_ uint16_t libmapiserver_RopGetPropertiesSpecific_size ( struct EcDoRpc_MAPI_REQ *  request,
struct EcDoRpc_MAPI_REPL *  response 
)

Calculate GetPropertiesSpecific Rop size

Parameters
requestpointer to the GetPropertiesSpecific EcDoRpc_MAPI_REQ structure
responsepointer to the GetPropertiesSpecific EcDoRpc_MAPI_REPL structure
Returns
Size of GetPropsSpecific response

Referenced by EcDoRpc_RopGetPropertiesSpecific().

_PUBLIC_ uint16_t libmapiserver_RopGetPropertyIdsFromNames_size ( struct EcDoRpc_MAPI_REPL *  response)

Calculate GetPropertyIdsFromNames Rop size

Parameters
responsepointer to the GetPropertyIdsFromNames EcDoRpc_MAPI_REPL structure
Returns
Size of GetPropertyIdsFromNames response

Referenced by EcDoRpc_RopGetPropertyIdsFromNames().

_PUBLIC_ uint16_t libmapiserver_RopGetStreamSize_size ( struct EcDoRpc_MAPI_REPL *  response)

Calculate GetStreamSize Rop size

Parameters
responsepointer to the GetStreamSize EcDoRpc_MAPI_REPL structure
Returns
Size of GetStreamSize response

Referenced by EcDoRpc_RopGetStreamSize().

_PUBLIC_ uint16_t libmapiserver_RopOpenStream_size ( struct EcDoRpc_MAPI_REPL *  response)

Calculate OpenStream Rop size

Parameters
responsepointer to the OpenStream EcDoRpc_MAPI_REPL structure
Returns
Size of OpenStream response

Referenced by EcDoRpc_RopOpenStream().

_PUBLIC_ uint16_t libmapiserver_RopReadStream_size ( struct EcDoRpc_MAPI_REPL *  response)

Calculate ReadStream Rop size

Parameters
responsepointer to the ReadStream EcDoRpc_MAPI_REPL structure
Returns
Size of ReadStream response

Referenced by EcDoRpc_RopReadStream().

_PUBLIC_ uint16_t libmapiserver_RopSeekStream_size ( struct EcDoRpc_MAPI_REPL *  response)

Calculate SeekStream Rop size

Parameters
responsepointer to the SeekStream EcDoRpc_MAPI_REPL structure
Returns
Size of SeekStream response

Referenced by EcDoRpc_RopSeekStream().

_PUBLIC_ uint16_t libmapiserver_RopSetProperties_size ( struct EcDoRpc_MAPI_REPL *  response)

Calculate SetProperties Rop size

Parameters
responsepointer to the SetProperties EcDoRpc_MAPI_REPL structure
Returns
Size of SetProperties response

Referenced by EcDoRpc_RopSetProperties().

_PUBLIC_ uint16_t libmapiserver_RopSetStreamSize_size ( struct EcDoRpc_MAPI_REPL *  response)

Calculate SetStreamSize Rop size

Parameters
responsepointer to the SetStreamSize EcDoRpc_MAPI_REPL structure
Returns
Size of SeekStream response

Referenced by EcDoRpc_RopSetStreamSize().

_PUBLIC_ uint16_t libmapiserver_RopWriteStream_size ( struct EcDoRpc_MAPI_REPL *  response)

Calculate WriteStream Rop size

Parameters
responsepointer to the WriteStream EcDoRpc_MAPI_REPL structure
Returns
Size of WriteStream response

Referenced by EcDoRpc_RopWriteStream().


Creative Commons License
Creative Commons Attribution icon Creative Commons Share Alike icon
This content is licensed under the Creative Commons
Attribution ShareAlike License v. 3.0:
http://creativecommons.org/licenses/by-sa/3.0/

openchange-2.0/apidocs/html/mapiproxy/libmapiserver__oxcstor_8c.html000066400000000000000000000401511223057412600261470ustar00rootroot00000000000000 MAPIProxy 2.0 API Documentation
libmapiserver_oxcstor.c File Reference

OXCSTOR ROP Response size calculations. More...

#include "libmapiserver.h"
#include <string.h>

Functions

_PUBLIC_ uint16_t libmapiserver_RopGetPerUserGuid_size (struct EcDoRpc_MAPI_REPL *response)
_PUBLIC_ uint16_t libmapiserver_RopGetPerUserLongTermIds_size (struct EcDoRpc_MAPI_REPL *response)
_PUBLIC_ uint16_t libmapiserver_RopGetReceiveFolder_size (struct EcDoRpc_MAPI_REPL *response)
_PUBLIC_ uint16_t libmapiserver_RopGetReceiveFolderTable_size (struct EcDoRpc_MAPI_REPL *response)
_PUBLIC_ uint16_t libmapiserver_RopGetStoreState_size (struct EcDoRpc_MAPI_REPL *response)
_PUBLIC_ uint16_t libmapiserver_RopIdFromLongTermId_size (struct EcDoRpc_MAPI_REPL *response)
uint16_t libmapiserver_RopLogon_size (struct EcDoRpc_MAPI_REQ *request, struct EcDoRpc_MAPI_REPL *response)
_PUBLIC_ uint16_t libmapiserver_RopLongTermIdFromId_size (struct EcDoRpc_MAPI_REPL *response)
_PUBLIC_ uint16_t libmapiserver_RopReadPerUserInformation_size (struct EcDoRpc_MAPI_REPL *response)
_PUBLIC_ uint16_t libmapiserver_RopSetReceiveFolder_size (struct EcDoRpc_MAPI_REPL *response)

Detailed Description

OXCSTOR ROP Response size calculations.

Function Documentation

_PUBLIC_ uint16_t libmapiserver_RopGetPerUserGuid_size ( struct EcDoRpc_MAPI_REPL *  response)

Calculate GetPerUserLongTermIds Rop size

Parameters
responsepointer to the GetPerUserLongTermIds EcDoRpc_MAPI_REPL structure
Returns
Size of GetPerUserLongTermIds response

Referenced by EcDoRpc_RopGetPerUserGuid().

_PUBLIC_ uint16_t libmapiserver_RopGetPerUserLongTermIds_size ( struct EcDoRpc_MAPI_REPL *  response)

Calculate GetPerUserLongTermIds Rop size

Parameters
responsepointer to the GetPerUserLongTermIds EcDoRpc_MAPI_REPL structure
Returns
Size of GetPerUserLongTermIds response

References libmapiserver_LongTermId_size().

Referenced by EcDoRpc_RopGetPerUserLongTermIds().

_PUBLIC_ uint16_t libmapiserver_RopGetReceiveFolder_size ( struct EcDoRpc_MAPI_REPL *  response)

Calculate GetReceiveFolder Rop size

Parameters
responsepointer to the GetReceiveFolder EcDoRpc_MAPI_REPL structure
Returns
Size of GetReceiveFolder response

Referenced by EcDoRpc_RopGetReceiveFolder().

_PUBLIC_ uint16_t libmapiserver_RopGetReceiveFolderTable_size ( struct EcDoRpc_MAPI_REPL *  response)

Calculate GetReceiveFolderTable ROP size

Parameters
responsepointer to the GetReceiveFolderTable EcDoRpc_MAPI_REPL structure
Returns
Size of GetPerUserLongTermIds response
_PUBLIC_ uint16_t libmapiserver_RopGetStoreState_size ( struct EcDoRpc_MAPI_REPL *  response)

Calculate GetStoreState Rop size

Parameters
responsepointer to the GetStoreState EcDoRpc_MAPI_REPL structure
Returns
Size of GetStoreState response

Referenced by EcDoRpc_RopGetStoreState().

_PUBLIC_ uint16_t libmapiserver_RopIdFromLongTermId_size ( struct EcDoRpc_MAPI_REPL *  response)

Calculate IdFromLongTermId Rop size

Parameters
responsepointer to the IdFromLongTermId EcDoRpc_MAPI_REPL structure
Returns
Size of IdFromLongTermId response

Referenced by EcDoRpc_RopIdFromLongTermId().

uint16_t libmapiserver_RopLogon_size ( struct EcDoRpc_MAPI_REQ *  request,
struct EcDoRpc_MAPI_REPL *  response 
)

Calculate Logon Rop size

Parameters
requestpointer to the Logon EcDoRpc_MAPI_REQ structure
responsepointer to the Logon EcDoRpc_MAPI_REPL structure
Returns
Size of Logon response

Referenced by EcDoRpc_RopLogon().

_PUBLIC_ uint16_t libmapiserver_RopLongTermIdFromId_size ( struct EcDoRpc_MAPI_REPL *  response)

Calculate LongTermIdFromId Rop size

Parameters
responsepointer to the LongTermIdFromId EcDoRpc_MAPI_REPL structure
Returns
Size of LongTermIdFromId response

Referenced by EcDoRpc_RopLongTermIdFromId().

_PUBLIC_ uint16_t libmapiserver_RopReadPerUserInformation_size ( struct EcDoRpc_MAPI_REPL *  response)

Calculate ReadPerUserInformation Rop size

Parameters
responsepointer to the ReadPerUserInformation EcDoRpc_MAPI_REPL structure
Returns
Size of ReadPerUserInformation response

Referenced by EcDoRpc_RopReadPerUserInformation().

_PUBLIC_ uint16_t libmapiserver_RopSetReceiveFolder_size ( struct EcDoRpc_MAPI_REPL *  response)

Calculate SetReceiveFolder (0x26) Rop size

Parameters
responsepointer to the SetReceiveFolder EcDoRpc_MAPI_REPL structure
Returns
Size of SetReceiveFolder response

Referenced by EcDoRpc_RopSetReceiveFolder().


Creative Commons License
Creative Commons Attribution icon Creative Commons Share Alike icon
This content is licensed under the Creative Commons
Attribution ShareAlike License v. 3.0:
http://creativecommons.org/licenses/by-sa/3.0/

openchange-2.0/apidocs/html/mapiproxy/libmapiserver__oxctabl_8c.html000066400000000000000000000313561223057412600261110ustar00rootroot00000000000000 MAPIProxy 2.0 API Documentation
libmapiserver_oxctabl.c File Reference

OXCTABL ROP Response size calculations. More...

#include "libmapiserver.h"

Functions

_PUBLIC_ uint16_t libmapiserver_RopFindRow_size (struct EcDoRpc_MAPI_REPL *response)
_PUBLIC_ uint16_t libmapiserver_RopQueryPosition_size (struct EcDoRpc_MAPI_REPL *response)
_PUBLIC_ uint16_t libmapiserver_RopQueryRows_size (struct EcDoRpc_MAPI_REPL *response)
_PUBLIC_ uint16_t libmapiserver_RopResetTable_size (struct EcDoRpc_MAPI_REPL *response)
_PUBLIC_ uint16_t libmapiserver_RopRestrict_size (struct EcDoRpc_MAPI_REPL *response)
_PUBLIC_ uint16_t libmapiserver_RopSeekRow_size (struct EcDoRpc_MAPI_REPL *response)
uint16_t libmapiserver_RopSetColumns_size (struct EcDoRpc_MAPI_REPL *response)
_PUBLIC_ uint16_t libmapiserver_RopSortTable_size (struct EcDoRpc_MAPI_REPL *response)

Detailed Description

OXCTABL ROP Response size calculations.

Function Documentation

_PUBLIC_ uint16_t libmapiserver_RopFindRow_size ( struct EcDoRpc_MAPI_REPL *  response)

Calculate FindRow Rop size

Parameters
responsepointer to the FindRow EcDoRpc_MAPI_REPL structure
Returns
Size of FindRow response

Referenced by EcDoRpc_RopFindRow().

_PUBLIC_ uint16_t libmapiserver_RopQueryPosition_size ( struct EcDoRpc_MAPI_REPL *  response)

Calculate QueryPosition Rop size

Parameters
responsepointer to the QueryPosition EcDoRpc_MAPI_REPL structure
Returns
Size of QueryPosition response

Referenced by EcDoRpc_RopQueryPosition().

_PUBLIC_ uint16_t libmapiserver_RopQueryRows_size ( struct EcDoRpc_MAPI_REPL *  response)

Calculate QueryRows Rop size

Parameters
responsepointer to the QueryRows EcDoRpc_MAPI_REPL structure
Returns
Size of QueryRows response

Referenced by EcDoRpc_RopQueryRows().

_PUBLIC_ uint16_t libmapiserver_RopResetTable_size ( struct EcDoRpc_MAPI_REPL *  response)

Calculate ResetTable (0x81) Rop size

Parameters
responsepointer to the ResetTable EcDoRpc_MAPI_REPL structure
Returns
Size of ResetTable response

Referenced by EcDoRpc_RopResetTable().

_PUBLIC_ uint16_t libmapiserver_RopRestrict_size ( struct EcDoRpc_MAPI_REPL *  response)

Calculate Restrict Rop size

Parameters
responsepointer to the Restrict EcDoRpc_MAPI_REPL structure
Returns
Size of Restrict response

Referenced by EcDoRpc_RopRestrict().

_PUBLIC_ uint16_t libmapiserver_RopSeekRow_size ( struct EcDoRpc_MAPI_REPL *  response)

Calculate SeekRow Rop size

Parameters
responsepointer to the SeekRow EcDoRpc_MAPI_REPL structure
Returns
Size of SeekRow response

Referenced by EcDoRpc_RopSeekRow().

uint16_t libmapiserver_RopSetColumns_size ( struct EcDoRpc_MAPI_REPL *  response)

Calculate SetColumns Rop size

Parameters
responsepointer to the SetColumns EcDoRpc_MAPI_REPL structure
Returns
Size of SetColumns response

Referenced by EcDoRpc_RopSetColumns().

_PUBLIC_ uint16_t libmapiserver_RopSortTable_size ( struct EcDoRpc_MAPI_REPL *  response)

Calculate SortTable Rop size

Parameters
responsepointer to the SortTable EcDoRpc_MAPI_REPL structure
Returns
Size of SortTable response

Referenced by EcDoRpc_RopSortTable().


Creative Commons License
Creative Commons Attribution icon Creative Commons Share Alike icon
This content is licensed under the Creative Commons
Attribution ShareAlike License v. 3.0:
http://creativecommons.org/licenses/by-sa/3.0/

openchange-2.0/apidocs/html/mapiproxy/libmapiserver__oxomsg_8c.html000066400000000000000000000247261223057412600257740ustar00rootroot00000000000000 MAPIProxy 2.0 API Documentation
libmapiserver_oxomsg.c File Reference

OXOMSG ROP Response size calculations. More...

#include "libmapiserver.h"
#include <string.h>

Functions

_PUBLIC_ uint16_t libmapiserver_RopGetAddressTypes_size (struct EcDoRpc_MAPI_REPL *response)
_PUBLIC_ uint16_t libmapiserver_RopGetTransportFolder_size (struct EcDoRpc_MAPI_REPL *response)
_PUBLIC_ uint16_t libmapiserver_RopOptionsData_size (struct EcDoRpc_MAPI_REPL *response)
_PUBLIC_ uint16_t libmapiserver_RopSetSpooler_size (struct EcDoRpc_MAPI_REPL *response)
uint16_t libmapiserver_RopSubmitMessage_size (struct EcDoRpc_MAPI_REPL *response)
_PUBLIC_ uint16_t libmapiserver_RopTransportSend_size (struct EcDoRpc_MAPI_REPL *response)

Detailed Description

OXOMSG ROP Response size calculations.

Function Documentation

_PUBLIC_ uint16_t libmapiserver_RopGetAddressTypes_size ( struct EcDoRpc_MAPI_REPL *  response)

Calculate GetAddressTypes (0x49) Rop size

Parameters
responsepointer to the GetAddressTypes EcDoRpc_MAPI_REPL structure
Returns
Size of GetAddressTypes response

Referenced by EcDoRpc_RopGetAddressTypes().

_PUBLIC_ uint16_t libmapiserver_RopGetTransportFolder_size ( struct EcDoRpc_MAPI_REPL *  response)

Calculate GetTransportFolder (0x6d) ROP size

Parameters
responsepointer to the GetTransportFolder EcDoRpc_MAPI_REPL structure
Returns
Size of GetTransportFolder response

Referenced by EcDoRpc_RopGetTransportFolder().

_PUBLIC_ uint16_t libmapiserver_RopOptionsData_size ( struct EcDoRpc_MAPI_REPL *  response)

Calculate OptionsData (0x6f) Rop size

Parameters
responsepointer to the OptionsData EcDoRpc_MAPI_REPL structure
Returns
Size of OptionsData response

Referenced by EcDoRpc_RopOptionsData().

_PUBLIC_ uint16_t libmapiserver_RopSetSpooler_size ( struct EcDoRpc_MAPI_REPL *  response)

Calculate SetSpooler (0x47) Rop size

Parameters
responsepointer to the SetSpooler EcDoRpc_MAPI_REPL structure
Returns
Size of SetSpooler response

Referenced by EcDoRpc_RopSetSpooler().

uint16_t libmapiserver_RopSubmitMessage_size ( struct EcDoRpc_MAPI_REPL *  response)

Calculate SubmitMessage (0x32) Rop size

Parameters
responsepointer to the SubmitMessage EcDoRpc_MAPI_REPL structure
Returns
Size of SubmitMessage response

Referenced by EcDoRpc_RopSubmitMessage().

_PUBLIC_ uint16_t libmapiserver_RopTransportSend_size ( struct EcDoRpc_MAPI_REPL *  response)

Calculate TransportSend (0x4a) Rop size

Parameters
responsepointer to the TransportSend EcDoRpc_MAPI_REPL structure
Returns
Size of TransportSend response

Referenced by EcDoRpc_RopTransportSend().


Creative Commons License
Creative Commons Attribution icon Creative Commons Share Alike icon
This content is licensed under the Creative Commons
Attribution ShareAlike License v. 3.0:
http://creativecommons.org/licenses/by-sa/3.0/

openchange-2.0/apidocs/html/mapiproxy/libmapiserver__oxorule_8c.html000066400000000000000000000110351223057412600261420ustar00rootroot00000000000000 MAPIProxy 2.0 API Documentation
libmapiserver_oxorule.c File Reference

OXORULE ROP Response size calculations. More...

#include "libmapiserver.h"

Functions

uint16_t libmapiserver_RopGetRulesTable_size (void)
_PUBLIC_ uint16_t libmapiserver_RopModifyRules_size (void)

Detailed Description

OXORULE ROP Response size calculations.

Function Documentation

uint16_t libmapiserver_RopGetRulesTable_size ( void  )

Calculate GetRulesTable Rop size

Returns
Size of GetRulesTable response
_PUBLIC_ uint16_t libmapiserver_RopModifyRules_size ( void  )

Calculate ModifyRules Rop size

Returns
Size of ModifyRules response

Creative Commons License
Creative Commons Attribution icon Creative Commons Share Alike icon
This content is licensed under the Creative Commons
Attribution ShareAlike License v. 3.0:
http://creativecommons.org/licenses/by-sa/3.0/

openchange-2.0/apidocs/html/mapiproxy/mapi__handles_8c.html000066400000000000000000001214061223057412600241510ustar00rootroot00000000000000 MAPIProxy 2.0 API Documentation
mapi_handles.c File Reference

API for MAPI handles management. More...

#include "mapiproxy/dcesrv_mapiproxy.h"
#include "libmapi/libmapi.h"
#include "libmapi/libmapi_private.h"
#include "libmapiproxy.h"

Functions

_PUBLIC_ enum MAPISTATUS mapi_handles_add (struct mapi_handles_context *handles_ctx, uint32_t container_handle, struct mapi_handles **rec)
_PUBLIC_ enum MAPISTATUS mapi_handles_delete (struct mapi_handles_context *handles_ctx, uint32_t handle)
_PUBLIC_ enum MAPISTATUS mapi_handles_get_private_data (struct mapi_handles *handle, void **private_data)
_PUBLIC_ struct
mapi_handles_context * 
mapi_handles_init (TALLOC_CTX *mem_ctx)
_PUBLIC_ enum MAPISTATUS mapi_handles_release (struct mapi_handles_context *handles_ctx)
_PUBLIC_ enum MAPISTATUS mapi_handles_search (struct mapi_handles_context *handles_ctx, uint32_t handle, struct mapi_handles **rec)
_PUBLIC_ enum MAPISTATUS mapi_handles_set_private_data (struct mapi_handles *handle, void *private_data)
static enum MAPISTATUS mapi_handles_tdb_free (struct mapi_handles_context *handles_ctx, uint32_t handle)
static enum MAPISTATUS mapi_handles_tdb_update (struct mapi_handles_context *handles_ctx, uint32_t handle, uint32_t container_handle)
static int mapi_handles_traverse_delete (TDB_CONTEXT *tdb_ctx, TDB_DATA key, TDB_DATA dbuf, void *state)
static int mapi_handles_traverse_null (TDB_CONTEXT *tdb_ctx, TDB_DATA key, TDB_DATA dbuf, void *state)

Detailed Description

API for MAPI handles management.

Function Documentation

_PUBLIC_ enum MAPISTATUS mapi_handles_add ( struct mapi_handles_context *  handles_ctx,
uint32_t  container_handle,
struct mapi_handles **  rec 
)
_PUBLIC_ enum MAPISTATUS mapi_handles_delete ( struct mapi_handles_context *  handles_ctx,
uint32_t  handle 
)

Remove the MAPI handle referenced by the handle parameter from the double chained list and mark its associated TDB record as null

Parameters
handles_ctxpointer to the MAPI handles context
handlethe handle to delete
Returns
MAPI_E_SUCCESS on success, otherwise MAPI error

References mapi_handles_tdb_free(), and mapi_handles_traverse_delete().

Referenced by EcDoRpc_RopCreateAttach(), EcDoRpc_RopCreateFolder(), EcDoRpc_RopGetAttachmentTable(), EcDoRpc_RopGetPermissionsTable(), EcDoRpc_RopOpenAttach(), EcDoRpc_RopOpenMessage(), EcDoRpc_RopRelease(), EcDoRpc_RopSyncImportMessageChange(), and mapi_handles_traverse_delete().

_PUBLIC_ enum MAPISTATUS mapi_handles_get_private_data ( struct mapi_handles *  handle,
void **  private_data 
)

Get the private data associated to a MAPI handle

Parameters
handlepointer to the MAPI handle structure
private_datapointer on pointer to the private data the function returns
Returns
MAPI_E_SUCCESS on success, otherwise MAPI_E_NOT_FOUND

Referenced by EcDoRpc_RopCommitStream(), EcDoRpc_RopCopyFolder(), EcDoRpc_RopCopyTo(), EcDoRpc_RopCreateAttach(), EcDoRpc_RopCreateFolder(), EcDoRpc_RopCreateMessage(), EcDoRpc_RopDeleteFolder(), EcDoRpc_RopDeleteMessages(), EcDoRpc_RopEmptyFolder(), EcDoRpc_RopFastTransferSourceCopyTo(), EcDoRpc_RopFastTransferSourceGetBuffer(), EcDoRpc_RopFindRow(), EcDoRpc_RopGetAttachmentTable(), EcDoRpc_RopGetContentsTable(), EcDoRpc_RopGetHierarchyTable(), EcDoRpc_RopGetLocalReplicaIds(), EcDoRpc_RopGetPermissionsTable(), EcDoRpc_RopGetPropertiesAll(), EcDoRpc_RopGetPropertiesList(), EcDoRpc_RopGetPropertiesSpecific(), EcDoRpc_RopGetStreamSize(), EcDoRpc_RopGetTransportFolder(), EcDoRpc_RopIdFromLongTermId(), EcDoRpc_RopLongTermIdFromId(), EcDoRpc_RopModifyPermissions(), EcDoRpc_RopModifyRecipients(), EcDoRpc_RopMoveFolder(), EcDoRpc_RopOpenAttach(), EcDoRpc_RopOpenEmbeddedMessage(), EcDoRpc_RopOpenFolder(), EcDoRpc_RopOpenMessage(), EcDoRpc_RopOpenStream(), EcDoRpc_RopQueryPosition(), EcDoRpc_RopQueryRows(), EcDoRpc_RopReadStream(), EcDoRpc_RopRegisterNotification(), EcDoRpc_RopReloadCachedInformation(), EcDoRpc_RopRemoveAllRecipients(), EcDoRpc_RopResetTable(), EcDoRpc_RopRestrict(), EcDoRpc_RopSaveChangesMessage(), EcDoRpc_RopSeekRow(), EcDoRpc_RopSeekStream(), EcDoRpc_RopSetColumns(), EcDoRpc_RopSetMessageReadFlag(), EcDoRpc_RopSetProperties(), EcDoRpc_RopSetStreamSize(), EcDoRpc_RopSortTable(), EcDoRpc_RopSubmitMessage(), EcDoRpc_RopSyncConfigure(), EcDoRpc_RopSyncGetTransferState(), EcDoRpc_RopSyncImportDeletes(), EcDoRpc_RopSyncImportHierarchyChange(), EcDoRpc_RopSyncImportMessageChange(), EcDoRpc_RopSyncImportReadStateChanges(), EcDoRpc_RopSyncOpenCollector(), EcDoRpc_RopSyncUploadStateStreamBegin(), EcDoRpc_RopSyncUploadStateStreamContinue(), EcDoRpc_RopSyncUploadStateStreamEnd(), EcDoRpc_RopTransportSend(), EcDoRpc_RopWriteStream(), RopGetReceiveFolder(), and RopSetReceiveFolder().

_PUBLIC_ struct mapi_handles_context* mapi_handles_init ( TALLOC_CTX *  mem_ctx)
read

Initialize MAPI handles context

Parameters
mem_ctxpointer to the memory context
Returns
Allocated MAPI handles context on success, otherwise NULL

Referenced by emsmdbp_init().

_PUBLIC_ enum MAPISTATUS mapi_handles_release ( struct mapi_handles_context *  handles_ctx)

Release MAPI handles context

Parameters
handles_ctxpointer to the MAPI handles context
Returns
MAPI_E_SUCCESS on success, otherwise MAPI error

Referenced by emsmdbp_mapi_handles_destructor().

_PUBLIC_ enum MAPISTATUS mapi_handles_search ( struct mapi_handles_context *  handles_ctx,
uint32_t  handle,
struct mapi_handles **  rec 
)

Search for a record in the TDB database

Parameters
handles_ctxpointer to the MAPI handles context
handleMAPI handle to lookup
recpointer to the MAPI handle structure the function returns
Returns
MAPI_E_SUCCESS on success, otherwise MAPI error

Referenced by EcDoRpc_RopCommitStream(), EcDoRpc_RopCopyFolder(), EcDoRpc_RopCopyTo(), EcDoRpc_RopCreateAttach(), EcDoRpc_RopCreateFolder(), EcDoRpc_RopCreateMessage(), EcDoRpc_RopDeleteFolder(), EcDoRpc_RopDeleteMessages(), EcDoRpc_RopEmptyFolder(), EcDoRpc_RopFastTransferSourceCopyTo(), EcDoRpc_RopFastTransferSourceGetBuffer(), EcDoRpc_RopFindRow(), EcDoRpc_RopGetAttachmentTable(), EcDoRpc_RopGetContentsTable(), EcDoRpc_RopGetHierarchyTable(), EcDoRpc_RopGetLocalReplicaIds(), EcDoRpc_RopGetPermissionsTable(), EcDoRpc_RopGetPropertiesAll(), EcDoRpc_RopGetPropertiesList(), EcDoRpc_RopGetPropertiesSpecific(), EcDoRpc_RopGetStreamSize(), EcDoRpc_RopGetTransportFolder(), EcDoRpc_RopIdFromLongTermId(), EcDoRpc_RopLongTermIdFromId(), EcDoRpc_RopModifyPermissions(), EcDoRpc_RopModifyRecipients(), EcDoRpc_RopMoveFolder(), EcDoRpc_RopOpenAttach(), EcDoRpc_RopOpenEmbeddedMessage(), EcDoRpc_RopOpenFolder(), EcDoRpc_RopOpenMessage(), EcDoRpc_RopOpenStream(), EcDoRpc_RopQueryPosition(), EcDoRpc_RopQueryRows(), EcDoRpc_RopReadStream(), EcDoRpc_RopRegisterNotification(), EcDoRpc_RopReloadCachedInformation(), EcDoRpc_RopRemoveAllRecipients(), EcDoRpc_RopResetTable(), EcDoRpc_RopRestrict(), EcDoRpc_RopSaveChangesMessage(), EcDoRpc_RopSeekRow(), EcDoRpc_RopSeekStream(), EcDoRpc_RopSetColumns(), EcDoRpc_RopSetMessageReadFlag(), EcDoRpc_RopSetProperties(), EcDoRpc_RopSetStreamSize(), EcDoRpc_RopSortTable(), EcDoRpc_RopSubmitMessage(), EcDoRpc_RopSyncConfigure(), EcDoRpc_RopSyncGetTransferState(), EcDoRpc_RopSyncImportDeletes(), EcDoRpc_RopSyncImportHierarchyChange(), EcDoRpc_RopSyncImportMessageChange(), EcDoRpc_RopSyncImportReadStateChanges(), EcDoRpc_RopSyncOpenCollector(), EcDoRpc_RopSyncUploadStateStreamBegin(), EcDoRpc_RopSyncUploadStateStreamContinue(), EcDoRpc_RopSyncUploadStateStreamEnd(), EcDoRpc_RopTransportSend(), EcDoRpc_RopWriteStream(), RopGetReceiveFolder(), and RopSetReceiveFolder().

_PUBLIC_ enum MAPISTATUS mapi_handles_set_private_data ( struct mapi_handles *  handle,
void *  private_data 
)
static enum MAPISTATUS mapi_handles_tdb_free ( struct mapi_handles_context *  handles_ctx,
uint32_t  handle 
)
static

Set a TDB record data as null meaning it can be reused in the future.

Parameters
handles_ctxpointer to the MAPI handles context
handlehandle key value to free
Returns
MAPI_E_SUCCESS on success, otherwise MAPI error

Referenced by mapi_handles_add(), and mapi_handles_delete().

static enum MAPISTATUS mapi_handles_tdb_update ( struct mapi_handles_context *  handles_ctx,
uint32_t  handle,
uint32_t  container_handle 
)
static

Update a TDB record

Referenced by mapi_handles_add().

static int mapi_handles_traverse_delete ( TDB_CONTEXT *  tdb_ctx,
TDB_DATA  key,
TDB_DATA  dbuf,
void *  state 
)
static

Traverse TDB database and search for records which dbuf value is set to state.

Parameters
tdb_ctxpointer to the TDB context
keythe current TDB key (potential child handle)
dbufthe current TDB value (parent handle)
statepointer on private data
Returns
1 when a free record is found, otherwise 0

References mapi_handles_delete().

Referenced by mapi_handles_delete().

static int mapi_handles_traverse_null ( TDB_CONTEXT *  tdb_ctx,
TDB_DATA  key,
TDB_DATA  dbuf,
void *  state 
)
static

Traverse TDB database and search for the first record which dbuf value is "null" string.

Parameters
tdb_ctxpointer to the TDB context
keythe current TDB key
dbufthe current TDB value
statepointer on private data
Returns
1 when a free record is found, otherwise 0

Referenced by mapi_handles_add().


Creative Commons License
Creative Commons Attribution icon Creative Commons Share Alike icon
This content is licensed under the Creative Commons
Attribution ShareAlike License v. 3.0:
http://creativecommons.org/licenses/by-sa/3.0/

openchange-2.0/apidocs/html/mapiproxy/mapiproxy-documentation.html000066400000000000000000002055621223057412600257010ustar00rootroot00000000000000 MAPIProxy 2.0 API Documentation

Contents


Revision History

Date Revision Number Author Revision Content
27/11/2010 0.6.3 Brad Hards Fix tracker link and a couple of typos.
03/03/09 0.6.2 Julien Kerihuel Add configuration info for server mode.
01/02/09 0.6.1 Julien Kerihuel Add configuration info for server mode.
04/01/09 0.6 Julien Kerihuel server mode documented, update mapiproxy naming to MAPIProxy.
29/12/08 0.5.5 Julien Kerihuel Add 3 new questions to FAQ section
09/12/08 0.5.4 Julien Kerihuel Add dcesrv:assoc group checking to smb.conf configuration requirements
10/07/08 0.5.3 Julien Kerihuel Rename smbd process to samba session API and update documentation
08/26/08 0.5.2 Julien Kerihuel documentation update on NSPI replacement and new FAQ question added
08/26/08 0.5.1 Julien Kerihuel documentation on NSPI referral added
08/11/08 0.5 Julien Kerihuel unbind hook added, cache module documentation and scenario added
07/23/08 0.4 Julien Kerihuel MAPIProxy API hooks, IDL update, mapiproxy structure description and documentation added for the cache module
06/25/08 0.3.2 Julien Kerihuel Minor installation update
06/04/08 0.3.1 Brad Hards Minor edits
05/27/08 0.3 Julien Kerihuel Available modules section added
05/24/08 0.2 Julien Kerihuel EMSMDB protocol version subsection updated, modules system section added, 5-minute configuration updated
05/15/08 0.1 Julien Kerihuel Initial Revision


1. Introduction

1.1. Purpose and Scope

MAPIProxy is an endpoint server for Samba4 which proxies ExchangeRPC traffic from MAPI clients (Outlook, openchangeclient, etc.) to Microsoft Exchange Server (and back). It can either act as a transparent proxy, for hacking, monitoring or debugging purposes or modify traffic on the fly and so provide new features. It is primarily developed for - but not limited to - third-party implementors looking for a development framework they can use for MAPI acceleration purposes.

This project is originally based on dcerpc_remote.c code from Stefan Metzemacher (Samba4 trunk) and is released under GPLv3 or later. It creates a dynamic shared object file which is loaded into samba and uses the Samba configuration file (smb.conf) to set common options.


1.2. General overview

Figure 1. General MAPIProxy network overview

The MAPIProxy traffic can be divided into 3 different parts as described in the figure above:

  • [1] clients to MAPIProxy:
    The origin of a client connect does not have much importance: it can either be an incoming connection from a real MAPI client, a connection relayed from another third-party proxy or another MAPIProxy instance. MAPIProxy runs as an endpoint server registered when samba starts. When the Samba4 endpoint mapper receives an incoming connection asking for one of the ExchangeRPC endpoints: NSPI (Name Service Provider Interface - Address Book) or EMSMDB (Exchange Message Store), the endpoint mapper redirects ExchangeRPC traffic to MAPIProxy which will pull, push and dispatch MAPI operations.

  • [2] MAPIProxy to MAPIProxy:
    The main objective of MAPIProxy is not to directly connect to the remote message server, but rather to relay some kind of modified MAPI traffic to the next MAPIProxy hop. This configuration can be used to add a compression layer between MAPIProxy instances, or to send specific third-party vendor information. However, a proxied connection directly from a MAPI client to an Exchange server (i.e. client-MAPIProxy-server is possible and such a configuration could be used for many other purposes.

  • [3] MAPIProxy to server:
    This last node is responsible for restoring MAPI contents and pushing it to the real Exchange server.


1.3. Bugs and Limitations

If you find bugs, limitations or have features you would like to see included in MAPIProxy, please register on the OpenChange Tracker System and create new tickets.

2. Installation

2.1. Download MAPIProxy

MAPIProxy is only available through SVN at the moment. A tarball release will only be made when we have a stabilized API with a preliminary set of useful features. You will need a SVN client to download openchange (including MAPIProxy).

$ svn co https://svn.openchange.org/openchange/trunk openchange

2.2. Samba4 installation

The MAPIProxy implementation requires a very recent Samba4 version in order to run properly. If Samba4 is planned to be installed from scratch for MAPIProxy only, please use the make samba-git compilation rule provided in the build system. This command will automate most part of the samba4 installation process. The only requirement for this step is to have an up to date GIT version installed on the system.

# make samba-git

When the installation process is finished, a running samba4 installation will be located in /usr/local/samba/. You will possibly be required to run ldconfig before you move to next steps. Please refer to doc/howto.txt for further information on openchange compilation.

2.3. MAPIProxy installation

If you have existing OpenChange DSO in the /usr/local/samba/modules/dcerpc_server/ folder, such as dcesrv_exchange.so, please remove them prior loading samba with MAPIProxy.

$ ./autogen.sh
$ ./configure --prefix=/usr/local/samba
$ make
# make install
# rm -rf /usr/local/samba/modules/dcerpc_server/dcesrv_exchange.so


3. Configuration

3.1. 5-Minute Configuration

This 5-Minute configuration will help you set up a minimal MAPIProxy using specified credentials and relaying traffic from Outlook clients to a remote Exchange server. This configuration will be performed in three steps:

  • [1] Provision Samba:
    From samba4/source4 directory, run under the root account:

    # ./setup/provision --realm=OPENCHANGE.LOCAL --domain=OPENCHANGE \
    --adminpass=openchange --server-role='domain controller'

    If you don't have DNS resolution and your realm can't be resolved, samba will be unable to authenticate the user in its user database. You must specify a realm which MAPI clients and MAPIProxy can resolve.

    If everything works fine, the provisioning script will have created all the databases, populated the AD (Active Directory) and generated a valid smb.conf file.

  • [2] Add a user account:

    In this configuration, we'll set the same credentials both for the user in the windows domain and on the Samba4 server. Let say there is already a user named testuser with its password set to openchange on the Exchange server:

    # ./setup/newuser testuser
    New Password: openchange

  • [3] Configure MAPIProxy options:

    In this final step, we only need to customize a small set of parameters:

    • dcerpc endpoint servers:
      MUST include epmapper and mapiproxy separated with comma.

    • dcerpc_mapiproxy:binding:
      This is the binding string used to connect to the remote Exchange server. The format of this string is: transport:address[flags]. In the example below, we'll be using the TCP over IP transport, connect on 192.168.1.1 and add the print flag so MAPI packets get dissected on samba stdout (or logfile).

    • dcerpc_mapiproxy:username and dcerpc_mapiproxy:password:
      The specified credentials we will be using to connect to the remote Exchange server.

    • dcerpc_mapiproxy:domain:
      The Windows domain the remote Exchange server belongs to.

    • dcerpc_mapiproxy:interfaces:
      In our case, we want to relay the whole ExchangeRPC traffic, so we need to load both the EMSMDB and NSP interface. In the meantime, people interested in NSPI proxy only would only have to load the exchange_nsp interface.

    • dcerpc_mapiproxy:modules:
      MAPIProxy provides a stackable modular system which primary objective is to provide developers an API for modules development. In our case we want to activate the downgrade module responsible for the EcDoConnect/EcDoRpc EMSMDB RPC functions negotiation.

    [globals]
    netbios name = MAPIPROXY
    workgroup = OPENCHANGE
    realm = OPENCHANGE.LOCAL
    server role = domain controller
    ### Configuration required by mapiproxy ###
    dcesrv:assoc group checking = false
    dcerpc endpoint servers = epmapper, mapiproxy
    dcerpc_mapiproxy:binding = ncacn_ip_tcp:192.168.1.1[print]
    dcerpc_mapiproxy:username = testuser
    dcerpc_mapiproxy:password = openchange
    dcerpc_mapiproxy:domain = EXCHANGE
    dcerpc_mapiproxy:interfaces = exchange_emsmdb, exchange_nsp, exchange_ds_rfr
    dcerpc_mapiproxy:modules = downgrade
    ### Configuration required by mapiproxy ###
    [netlogon]
    path = /usr/local/samba/var/locks/sysvol/openchange.local/scripts
    read only = no
    [sysvol]
    path = /usr/local/samba/var/locks/sysvol
    read only = no

We are now ready to run samba:

# samba -d5 -i -M single

If everything works properly, the following lines should be displayed in samba output:

DCERPC endpoint server 'exchange_emsmdb' registered
DCERPC endpoint server 'exchange_nsp' registered
DCERPC endpoint server 'exchange_ds_rfr' registered
DCERPC endpoint server 'mapiproxy' registered
dcesrv_interface_register: interface 'epmapper' registered on endpoint 'ncacn_np:[\pipe\epmapper]'
dcesrv_interface_register: interface 'epmapper' registered on endpoint 'ncacn_ip_tcp:[135]'
dcesrv_interface_register: interface 'epmapper' registered on endpoint 'ncalrpc:[EPMAPPER]'
MAPIPROXY module 'downgrade' registered
MAPIPROXY module 'downgrade' loaded
mapiproxy_module_load 'downgrade' (Downgrade EMSMDB protocol version EcDoConnect/EcDoRpc)
dcesrv_interface_register: interface 'exchange_emsmdb' registered on endpoint 'ncacn_np:[\pipe\lsass]'
dcesrv_interface_register: interface 'exchange_emsmdb' registered on endpoint 'ncacn_np:[\pipe\protected_storage]'
dcesrv_interface_register: interface 'exchange_emsmdb' registered on endpoint 'ncacn_ip_tcp:'
dcesrv_interface_register: interface 'exchange_nsp' registered on endpoint 'ncacn_np:[\pipe\lsass]'
dcesrv_interface_register: interface 'exchange_nsp' registered on endpoint 'ncacn_np:[\pipe\protected_storage]'
dcesrv_interface_register: interface 'exchange_nsp' registered on endpoint 'ncacn_ip_tcp:[]'
dcesrv_interface_register: interface 'exchange_ds_rfr' registered on endpoint 'ncacn_np:[\pipe\lsass]'
dcesrv_interface_register: interface 'exchange_ds_rfr' registered on endpoint 'ncacn_np:[\pipe\protected_storage]'
dcesrv_interface_register: interface 'exchange_ds_rfr' registered on endpoint 'ncacn_ip_tcp:[]'
You should now be able to configure Outlook to use an Exchange account with the proxy IP address and run Outlook seamlessly (both online or cached exchange mode).


4. Technical Concepts

4.1. NSPI Bindings Replacement

When Outlook sets up an Exchange account using either the mail applet from the configuration panel or the account editor within Outlook, it uses the NSPI protocol (Name Service Provider Interface, effectively the address book provider). In this case, NSPI is used to resolve the Exchange username and fetch from Exchange server all information needed by Outlook to initiate direct connection to the EMSMDB pipe (effectively the message store) the next time it connects to the server.

At some point of the profile's creation process, Outlook queries Exchange for some specific connection information using the NspiGetProps (0x9) RPC operation . More specifically, when Outlook requests for the PR_EMS_AB_NETWORK_ADDRESS MAPI property, Exchange returns a list binding strings. Outlook next stores these binding strings at some location - associated to the Outlook profile - in the windows registry and uses them for future connections.

Outlook can also rely on other information returned by NSPI functions and connect to the real Exchange server rather than MAPIProxy. Such case occurs when Outlook is able to resolve the exchange server using its hostname. This reference to the original Exchange server can be found when Outlook requests for the PR_EMS_AB_HOME_MDB MAPI property during the NspiQueryRows (0x3) RPC operation. MAPIProxy replaces the Exchange server name with its own netbios name and forward the reply to the client.

In the meantime, this information is next used by Outlook to query a minimal entry ID for a distinguished name using this server name. MAPIProxy needs to substitute the server name in the inbound request string with the original exchange one.

MAPIProxy needs to avoid Outlook clients being aware of this remote server address and trying to communicate directly with the remote server instead of using the proxy. In order to do this, MAPIProxy alters the Outlook-Exchange MAPI traffic and replaces these binding strings with the MAPIProxy FQDN and netbios name.


4.2. NSPI Referral Replacement

The Address Book Name Service Provider Interface (NSPI) Referral Service is a service used by Outlook to retrieve the name of an NSPI server. No NSPI connection should be initiated without first querying for the correct NSPI server. In this case, RFR returns the fully qualified domain name of the real Exchange server and starts using it if available.

MAPIProxy needs to avoid Outlook clients being aware of this server address and trying to communicate directly with the remote server instead of using the proxy. In order to do this, MAPIProxy alters the Outlook-Exchange MAPI traffic and replaces the server DN returned by RfrGetNewDSA (0x0) RPC operation with the MAPIProxy realm as specified in smb.conf.


4.3. Force EMSMDB Protocol Version

When Outlook starts and presumably calls MapiLogonEx, it first opens a connection to the Exchange server on the NSPI pipe, then on the EMSMDB pipe. Under Outlook 2003, the very first EMSMDB RPC call Outlook makes can be considered as a kind of protocol version negotiation. Depending on which version of Outlook is used, and how the Exchange server replies to the EMSMDB connect request, Outlook will either keep using the same pool of RPC calls or downgrade.

For example Outlook 2003 (default behavior) tests if the remote server supports the 2 new EMSMDB calls (EcDoConnectEx/EcDoRpcExt2) introduced in Exchange 2003. If Exchange replies to the EcDoConnectEx request with a dcerpc_fault, it means the server does not support the RPC operation, presumably has a version before 2003, and Outlook needs to downgrade its version in order to communicate with the server:

  • EcDoConnectEx (0xa) call
    • On success, Outlook will use EcDoRpcExt2 (0xb) to handle MAPI traffic
    • On failure (dcerpc_fault: nca_op_rng_error), Outlook calls EcDoConnect (0x0) and use EcDoRpc (0x2) to handle MAPI traffic

If MAPIProxy runs in an environment with Outlook clients and Exchange servers using a version above 2003, a last step is required to successfully use Outlook. The EcDoConnect RPC reply returns the Exchange server version (as an array of 3 short integers). When Outlook detects this particular server version, it automatically closes the connection and keep requesting indefinitely for EcDoConnectEx. To deal with this, MAPIProxy modifies the EcDoConnect reply sent by Exchange and replaces the server version with a one equal to that sent by Exchange 2000.

In the meantime, if we reproduce this test with Outlook 2000 which doesn't support these 2 new RPC calls, Outlook will directly call EcDoConnect.

The main difference between the EcDoConnectEx/EcDoRpcExt2 operations and the EcDoConnect/EcDoRpc operations is that the former use both XOR 0xA5 obfuscation and LZ77 compression/Direct2 encoding; while the latter only use the XOR obfuscation to handle MAPI content. If MAPIProxy wants to act as an intelligent proxy (for example, to be able to analyze MAPI content on the fly, compress MAPI data etc), receiving non compressed MAPI traffic would probably improve the overall process.

Below is a list of Exchange/Outlook pairs and the EMSMDB connect function they will use by default:

Exchange version Outlook version EMSMDB connect function
5.5/2000 any EcDoConnect (0x0)
2003 2000 EcDoConnect (0x0)
2007 2000 EcDoConnect (0x0)
Microsoft officially says it is unsupported
2003 2003-2007 EcDoConnectEx (0xa)
2007 2003 EcDoConnectEx (0xa)
2007 2007 EcDoConnectEx (0xa)

MAPIProxy reproduces the Exchange 2000 behavior and prevents Outlook from communicating with the Exchange server using the EcDoConnectEx/EcDoRpcExt2 as described in Figure 2 below. When Outlook sends an EcDoConnectEx request, MAPIProxy does not relay the request to the remote Exchange server and immediately returns a dcerpc_fault to Outlook. Outlook, assuming the server doesn't support this call uses EcDoConnect instead. From this call, MAPIProxy relay the information to Exchange.

Figure 2. MAPIProxy behavior on Outlook EMSMDB connection

From the Exchange side, the server will analyze this EcDoConnect request as a call sent by Outlook 2000 or below version. Exchange works fine using this protocol version unless Exchange 2007 SP1 which appears to introduce client version restrictions by default. In the meantime, existing tests demonstrate similar restrictions would apply to Outlook 2003 connection (without MAPIProxy) and prevent Outlook version before 2007 connecting to Exchange 2007. Further information and solution is available at the following addresses:


4.4. OpenChange IDL File

IDL stands for Interface Definition Language and OpenChange uses this format to describe ExchangeRPC communications. This file is processed by pidl (Perl IDL compiler provided by Samba4) which turns this protocol description into C-code dealing with the push, pull and print operations.

OpenChange development policy in trunk used to push a new MAPI call in the IDL only when the associated libmapi implementation and mapitest unit is developed, but this was preventing from distributing MAPIProxy with further openchange releases. Furthermore, the OpenChange IDL is now almost complete and merging back to the trunk helps improving libmapi reliability.


5. Stackable Modules

5.1. General Overview

The MAPIProxy stackable modules system provides implementers a development framework to add new features. This stackable mechanism allows developers to write modules with a very specific scope of which modifications will transparently be relayed to the next module until it is finally pushed by MAPIProxy to the next hop (Figure 3.).

Figure 3. MAPIProxy module stack and EcDoRpc interaction

With this system, developers can focus their effort on ExchangeRPC traffic - or any other protocol samba supports - interception, modification, analysis and avoid spending time on implementing a new endpoint server. Furthermore it provides an easier way for implementers to divide the work in smaller units and develop each of them in a separated module.

MAPIProxy modules are dynamic shared objects with an entry point and a limited set of hooks. These modules have to be installed in the dcerpc_mapiproxy folder within the samba4 modules directory (e.g. /usr/local/samba/modules). MAPIProxy modules specified in the Samba configuration file (smb.conf) will be loaded into MAPIProxy at runtime and interact with each other in the same order they were defined:

dcerpc_mapiproxy:modules = downgrade,dummy

All MAPIProxy modules will be registered but only those specified on the dcerpc_mapiproxy:modules parametric option line will be added to the chained list of effective modules.

5.2. Module entry point

MAPIProxy modules must have an entry point function named samba_init_module. This function needs to set general information about the module, specify the module's hooks and finally call the mapiproxy_module_register function to register itself in the MAPIProxy module subsystem.

NTSTATUS samba_init_module(void)
{
struct mapiproxy_module module;
NTSTATUS ret;
/* Fill in our name */
module.name = "sample";
module.description = "A sample module";
module.endpoint = "any";
/* Fill in all the operations */
module.init = sample_init;
module.push = sample_push;
module.ndr_pull = sample_ndr_pull;
module.pull = sample_pull;
module.dispatch = NULL;
module.unbind = NULL;
/* Register ourselves with the MAPIPROXY subsytem */
ret = mapiproxy_module_register(&module);
if (!NT_STATUS_IS_OK(ret)) {
DEBUG(0, ("Failed to register 'sample' mapiproxy module!\n"));
return ret;
}
return ret;
}
  • module.name:
    This is the module name. This name will be used by dcerpc_mapiproxy:modules in smb.conf to load the module

  • module.description:
    This field lets developers specify a brief module description for information purpose only.

  • module.endpoint:
    This field defines the interface which this module is designed to work with. The primary objective is to avoid calling the module hooks if the module doesn't have any impact on the requests or replies. For example, a module only interacting with the EcDoRpc function should define exchange_emsmdb.

    In the meantime, it can happen that a module requires to interact with more than a single interface. In such case, use the 'any' keyword which will call the modules functions with any endpoints proxied by MAPIProxy.

5.3. Module Hooks

MAPIProxy offers a set of hooks which modules can implement to modify/change/alter client to server MAPI traffic. The figure below shows how and when hooks are called during a request/response lifetime.

Figure 4. Usage of MAPIProxy Hooks during a request/response life time
  • init: This is the initialization function for the module which is only called once - when the module is loaded. It is generally used to retrieve smb.conf parametric options for the module and initialize some global structures

  • pull: This is the function called when MAPIProxy receives a MAPI request. The request has already been extracted and its information filled into MAPI structures

  • push: This is the function called when MAPIProxy receive a MAPI response. The response has already been extracted and its information filled into MAPI structures

  • dispatch: Similarly to the MAPIProxy top-level dispatch function, it is used to dispatch the information. This function is called after the pull but before the push. Moreover it is called before the request is forward to the remote endpoint.

  • ndr_pull: This is the function called before data from a request is extracted from the NDR blob.

  • ndr_push: This is the function called before data from a response is extracted from the NDR blob.

  • unbind: This is the function called when the connection closes. It can be used to free data associated to a given session and stored within a module global list.

Please note that the module API is still under development and is likely to change in further revisions.

5.4. mapiproxy structure

MAPIProxy uses a structure modules can modify in their dispatch routine and which impact on the general MAPIProxy behavior.

Figure 5. overview of mapiproxy structure variables scope
  • norelay: This boolean variable can be used by modules to tell MAPIProxy not to relay the incoming request to the remote server through dcerpc_ndr_request() but directly jump to the push (response) MAPIProxy code. This variable is for example in use within the cache module when we read stream from the local filesystem and play it back to MAPI clients.

  • ahead: This boolean variable can be used by modules to tell MAPIProxy not to relay the incoming response to the client through the push and dcerpc_ndr_request routine but loop over the dispatch routine. This variable is for example in use within the cache module when we want to read a stream ahead from Exchange server to the remote MAPIProxy instance.


6. Available Modules

6.1. Downgrade Module

The downgrade module implements the EcDoConnect/EcDoRpc negotiation as described in section 4.2. It ensures Outlook will not send compressed information or use functions other than EcDoRpc for EMSMDB transport. In order to use the downgrade module, edit smb.conf and add downgrade to dcerpc_mapiproxy:modules.

dcerpc_mapiproxy:modules = downgrade


6.2. Pack Module

Note that this module only works with an infrastructure using two or more instances of MAPIProxy as described in Figure 1

The pack module implements routines designed to manipulate and factorize MAPI content between different MAPIProxy instances. It also offers a developer overview on how to manipulate mapi requests. Last but not least, it provides data which can next be used by subsequent MAPIProxy modules for example to compress or encrypt this proxypack blob.

  • First, MAPIProxy extracts and removes specific MAPI calls from the request, pack them within the proxypack MAPI call data blob, prefix them with their real offset in the array of mapi requests and finally append this custom call at the end of the mapi requests array (Figure 4).

    Figure 6. Pack process

  • Final MAPIProxy hop will seek the mapi requests array looking for the proxypack call. If found, it unpacks MAPI data and restore these calls at their initial location within the mapi requests array (Figure 6).

    Figure 7. Unpack process

This module has two configuration options:

  • mpm_pack:opnums
    This option takes a list of MAPI calls to pack into the proxypack data blob. It can take one or more MAPI opnums, each of them separated with a comma.

  • mpm_pack:lasthop
    This options takes either true or false.the lasthop option defines whether this is a MAPIProxy directly connected to Outlook/Exchange or yet another proxy inserted within the MAPIProxy chain of hops. If this MAPIProxy instance is not a last hop, then it will skip the pack/unpack operations and forward the request to the next one.
mpm_pack:opnums = 0x70,0x75,0x76,0x77,0xa
mpm_pack:lasthop = true

In order to use the pack module, edit smb.conf and add pack to dcerpc_mapiproxy:modules.

dcerpc_mapiproxy:modules = downgrade,pack


6.3. Cache Module

The cache module implements a cache mechanism for streams related to messages or attachments. This module reduces communication latency between MAPI clients (using online mode) and Exchange. When configured with online mode, MAPI clients retrieve data from Exchange each time they access a message and don't have any offline storage mechanisms enabled - data are downloaded and stored within a temporary files folder. This module also offers a preliminary synchronization mechanism which can be used to transfer files between different MAPIProxy instances and use different protocols than MAPI for data transfer (such as rsync or wget).

The cache module is designed to cover different cases:

Scenario 1: Replay attachments

This scenario only requires a single MAPIProxy instance and requires a single configuration option:

mpm_cache:path = /tmp/cache
Figure 8. Replay stream scenario
  • 1. Outlook reads a stream for the first time:
    MAPIProxy monitors the Outlook-Exchange traffic and store the attachment on the local filesystem.

  • 2. Outlook requests this stream again:
    MAPIProxy looks over its cache, find the requested stream and directly communicate with Outlook without forwarding requests to the remote server.


Scenario 2: Read stream ahead

This scenario requires two MAPIProxy instances and requires different configuration options for local and remote MAPIProxy:

  • local MAPIProxy smb.conf sample:

    mpm_cache:path = /tmp/cache
    mpm_cache:ahead = false
    mpm_cache:sync = true
    mpm_cache:sync_cmd = /usr/bin/rsync -z mapiproxy@192.168.102.2:__FILE__ __FILE__

  • remote MAPIProxy smb.conf sample:

    mpm_cache:path = /tmp/cache
    mpm_cache:ahead = true
    mpm_cache:sync = false

Figure 9. Read ahead scenario with synchronization mechanism
  • This scenario uses 2 MAPIProxy instances. We call remote MAPIProxy, the MAPIProxy instance connected to the Exchange server network and local MAPIProxy the instance connected to the MAPI clients network.

  • 1. Outlook wants to read an attachment for the first time:
    The remote MAPIProxy monitors the first ReadStream request and read the full stream ahead on its own and stores it on its local filesystem.

  • 2. remote MAPIProxy replies to local MAPIProxy and local MAPIProxy runs the synchronization mechanism. The current implementation provides a fork/execve/waitpid process which allows to run any command with parameters. When local MAPIProxy finishes to store the file locally through the synchronization mechanism, it marks the stream as being cached.

  • 3. local MAPIProxy plays the attachment back to the client from cache.

The module monitors OpenMessage, OpenAttach, OpenStream, ReadStream and Release MAPI calls and stores streams on the local filesystem with indexation in a TDB database. Note that the module doesn't yet provide semantics needed to remove entries from the TDB database.

This module has different configuration options and modes:

  • mpm_cache:path
    This option takes the full path to an existing folder on the filesystem. This folder will be the storage root path for the cache module and will hold the TDB store, a folder hierarchy and stream files.

    mpm_cache:path = /tmp/cache

  • mpm_cache:ahead
    This option takes a boolean value (true or false) and defines whether the ahead mechanism should be enabled or not. This mode should only be enabled on the remote MAPIProxy instance. It can be enabled on local MAPIProxy instance, however there won't be any benefit but Outlook unexpectedly falling in some time out mode and close the connection.

    mpm_cache:ahead = true

  • mpm_cache:sync
    This option takes a boolean value (true or false) and defines whether the synchronization mechanism should be enabled or not. This mode only makes sense on the local MAPIProxy instance and mpm_cache:sync_cmd must also be configured.

    mpm_cache:sync = true

  • mpm_cache:sync_cmd
    This option takes the command line to execute for the synchronization process. A preliminary substitution variable mechanism is available but should be improved over time. For the moment, the cache module only provides __FILE__ which will be substituted by the full path to the cached file. The synchronization process currently assumes local and remote MAPIProxy instances have the same storage path (mpm_cache:path).

    mpm_cache:sync_cmd = /usr/bin/rsync -z mapiproxy@192.168.102.2:__FILE__ __FILE__

In order to use the cache module, edit smb.conf and add cache to dcerpc_mapiproxy:modules.

dcerpc_mapiproxy:modules = downgrade,cache


Notes

  • While the cache module implements a preliminary session mechanism (multiple clients support), this mode is currently only implemented up to 50%. Multiple clients will work for files already cached, but will cause unexpected behaviors while synchronizing a remote file at the same moment from different session. This bug should be fixed when the streaming and lock mechanism will be implemented.

  • The synchronization mechanism is yet experimental and we have deliberately changed the storage path permissions from 0700 to 0777 for trivial setup. File permissions will become parametric smb.conf options in the future.


7. Server Mode

7.1. 5-Minute Configuration

This 5-Minute configuration will help you set up a preliminary OpenChange server. This configuration will be performed in three steps. Before running these commands, make sure you have followed step 1 (Provision Samba) and step 2 (Add a user account) in MAPIProxy 5-Minute configuration section.

  • [1] Provision OpenChange:
    From openchange root directory, run under the root account:

    # ./setup/openchange_provision

    This script will extends Samba4 Active Directory with Exchange classes and attributes needed to run OpenChange server. Note that this operation may require several minutes to complete.

  • [2] Create the Exchange user account:
    OpenChange does not create the user account the way Samba does. It only extends existing users from the SAM database and add attributes required to access OpenChange server. The underlying concept is that system administrators may want to give access to Samba shares to a specific user but do not want him to access OpenChange server.The user must have been created using the Samba4 samba-tool newuser script before you run this command. Run under the root account:

    # ./setup/openchange_newuser --create <username>

    where username is the user account you want to give access to OpenChange server

  • [3] Create the OpenChange Dispatcher database:
    OpenChange uses a dispatcher database designed to store generic and top-level information about user mailbox. The following command will create a blank openchangedb ldb database:

    # ./setup/openchange_provision --openchangedb

  • [4] Create a mailbox for the user in the OpenChange Dispatcher database:
    Run under the root account:

    # ./setup/openchange_newuser --mailbox <username>

  • [5] Configure OpenChange server options:
    OpenChange server only requires a very limited set of options to be added to smb.conf in order to run. Note that the following configuration also works with existing MAPIProxy configuration. This configuration will turn MAPIProxy into OpenChange server only and no remote connection to Exchange server will be made:

    [globals]
    netbios name = MAPIPROXY
    workgroup = OPENCHANGE
    realm = OPENCHANGE.LOCAL
    server role = domain controller
    ### Configuration required by OpenChange server ###
    dcerpc endpoint servers = epmapper, mapiproxy
    dcerpc_mapiproxy:server = true
    dcerpc_mapiproxy:interfaces = exchange_emsmdb, exchange_nsp, exchange_ds_rfr
    ### Configuration required by OpenChange server ###
    [netlogon]
    path = /usr/local/samba/var/locks/sysvol/openchange.local/scripts
    read only = no
    [sysvol]
    path = /usr/local/samba/var/locks/sysvol
    read only = no



7.2. General Overview

Although section 1.1 only describes MAPIProxy as a proxy, recent work makes it possible to turn MAPIProxy either into a complete and real stand-alone server or server/proxy hybrid.

MAPIProxy behaviour is controlled through the dcerpc_mapiproxy:server parametric option. To use MAPIProxy as an independent server, set

dcerpc_mapiproxy:server = true
  • dcerpc_mapiproxy:server = true
    When this parametric option is set to true, MAPIProxy will not initiate connections to a remote server, but instead will direct client connections to its own default NSPI, RFR and EMSMDB servers and work as a stand-alone server.

  • dcerpc_mapiproxy:server = false
    If this option is unset or set to false (default behavior), MAPIProxy will work in proxy mode only and initiates a connection to a remote server using the binding/credentials configuration as specified in section 3.1 (5-Minute Configuration).


In addition to the server mode described above, MAPIProxy provides an additional set of configuration options which makes possible to override and customize MAPIProxy behavior. The server mode has been designed to supply a modular mechanism somewhat similar to the modules one described in section 5. While MAPIProxy modules are stackable and can be chained, server modules only support a single module for a given endpoint:

  • When dcerpc_mapiproxy:server is set to true, MAPIProxy registers dynamic shared object stored at a specific location (modules/dcerpc_mapiproxy_servers) and load server modules tagged with the MAPIPROXY_DEFAULT status. For each of the endpoints MAPIProxy can handle (exchange_nsp, exchange_emsmdb, exchange_ds_rfr), the associated default server will be loaded. These default servers are located within mapiproxy/servers/modules. (Figure 10.)

    Figure 10. Server mode enabled

  • When dcerpc_mapiproxy:server is set to false, MAPIProxy still registers server dynamic shared objects but does not load any of them, which means that ExchangeRPC traffic will be relayed to remote server.

However there may be some cases where developers would like to run a custom server they have developed, or handle a limited set of ExchangeRPC traffic on their own for a given endpoint. This configuration is made possible through 3 parametric options:

dcerpc_mapiproxy:nspi_server = nspi_server
dcerpc_mapiproxy:emsmdb_server = emsmdb_server
dcerpc_mapiproxy:rfr_server = exchange_ds_rfr

Each of these options specifies the server module name to be loaded for a given endpoint. Note that these options override the dcerpc_mapiproxy:server state:

  • If dcerpc_mapiproxy:server is set to true, specifying one or all of these options will override default servers with your own custom servers. For example Figure 11 shows a mapiproxy configuration where server mode is enabled but where the NSPI server has been replaced with a custom one.

    Figure 11. Server mode enabled but custom NSPI server loaded

  • If dcerpc_mapiproxy:server is set to false, specifying one or all of these options will force MAPIProxy to relay the associated traffic to default or custom server. For example, Figure 12 shows a mapiproxy configuration where NSPI traffic is handled by OpenChange NSPI server while EMSMDB and RFR traffic is relayed to the remote server.

    Figure 12. Server mode disabled but NSPI server loaded


8. Frequently Asked Questions

8.1. The action could not be completed

Figure 13. Outlook error: The action could not be completed

If you have followed the 5-Minute Configuration instructions and the above error message box (Figure 13) is displayed each time you click the Check Name button, then you need to:

  • Click on More Settings
  • Open the security Tab
  • Tick the Always prompt for username and password checkbox in the User Configuration section (Figure 14)
Figure 14. Resolution: Always prompt for username and password

Next time you click on Check Name, Outlook will prompt for username and password. A similar credentials dialog will be displayed each time Outlook is launched.


8.2. Profile creation goes fine, but Outlook can't open your default e-mail folders

The profile was properly created using the mail applet from the configuration panel (or using Outlook wizard). However when I launch Outlook, I keep having the following error message:

Figure 15. Outlook error: Unable to Open your default e-mail folders

This probably means Outlook is unable to lookup the resolved name of your MAPIProxy/samba4 server. You can either:

  • 1. Make your Windows workstation points to a domain name server able to resolve MAPIProxy fully qualified name.

  • 2. Open
    C:\WINDOWS\system32\etc\drivers\hosts
    file and add an entry for mapiproxy. For example if I have mapiproxy.openchange.local pointing at 192.168.102.2, then hosts file should hold the following line:
    192.168.102.2 mapiproxy.openchange.local mapiproxy


8.3. Does MAPIProxy need to be domain controller?

No it doesn't. MAPIProxy works fine as a member server of a Windows domain. However, since delegated credentials and forwarded kerberos credentials don't yet work, you'll need to force samba to rely on the local SAM database. To force this behavior, add to smb.conf within the global section:

server role = member server
aux_methods:member server = sam


8.4. Generating Samba's private keys takes infinite time

For some configuration, the private keys generation process at Samba startup can be very long. In case private keys are not generated within a couple of minutes, it is suggested to recompile Samba with gnutls disabled as in the example below:

$ ./configure.developer --enable-debug --disable-gnutls
$ gmake idl_full
$ gmake
$ sudo gmake install


8.5. On Ubuntu make samba-git exits with gmake: not found

On Ubuntu, I have the following output while trying to install samba4 from OpenChange sources:

To build Samba, run /usr/bin/make
Step2: Compile Samba4 (IDL)
./script/installsamba4.sh: 332: gmake: not found
Step3: Compile Samba4 (Source)
./script/installsamba4.sh: 332: gmake: not found
Error in Step3 (error code 127)

gmake is make on Ubuntu. Creating the following symbolic link will fix the issue:

$ sudo ln -s /usr/bin/make /usr/bin/gmake

Creative Commons License
Creative Commons Attribution icon Creative Commons Share Alike icon
This content is licensed under the Creative Commons
Attribution ShareAlike License v. 3.0:
http://creativecommons.org/licenses/by-sa/3.0/

openchange-2.0/apidocs/html/mapiproxy/mapiproxy.png000066400000000000000000001076041223057412600226500ustar00rootroot00000000000000‰PNG  IHDRÛæ‹¸¤tIMEØ ž·f( pHYs''”iQgAMA± üaIDATxÚì½i°e×u¶Ç3Üé=£C73   Ap”(R´äPJdÅr¥*U©üq¹’r)•R©Êq"§ì”[²bY¶HQQgP Š$H˜3Ðã›ßδÏÞYkíso¿nÎÅ~ÝØ_=6ï=÷Ü3½‡o{íµ¾Ås, `@œë h9 `» 0r@@@ÀvA`䀀€€í‚ÀÈÛ‘¶ #lFØ.Œ°]9 `» 0r@@@ÀvA`䀀€€í‚ÀÈÛ‘¶ #lFØ.Œ°]9 `» 0r@@@ÀvA`䀀€€í‚ÀÈÛ‘¶ #lFØ.Œ°]9 `» 0r@@@ÀvA`䀀€€í‚ÀÈÛ‘¶ #lFØ.Œ°]9 `» 0r@@@ÀvA`䀀€€í‚ÀÈÛ‘¶ #lFØ.Œ°]9 `» 0r@@@ÀvA`䀀€€í‚ÀÈÛê\_À+Öÿë˜cŒÃðÈñ ’ŽÞÃxÏù¹¾Ê€€€Ÿ¸Ãÿúþ®€§XÃøÆø>ȯž|ý[ǹDÖÅÿ9Úêð/l/é_㣹?x 耀 ‘x k,R'0)¼U¢™nŽ^p$h9‰ 9¢WÞè_àaÎ'ñ AŸ} ú·¢Ýà€9Ii8£íìáà2Äœ.,Fþ `‘€Ù¸B¶5ŒÕ¤XÉ´$ë˜&Š4D£µs%)âˆ5ì Ì«)R1¥éŸHïš ³ƒj®-Ü 5Ç’Å!øpA 0ò±àlX°Q†„XX&$s‚uR–J–pÔ°b°†¾"èED¯O‡)èÅôqÿÔáËš!©™¹¢äŠ®!$Õƒp8oùÂè(g¹aë#V’ÐEžÕL*Öj1!X*X2áYôY~OÄ×Ç+¶¾ÿAQá³÷üÁ—çÙ¹‚–¦ù@;ÖŽBL# àüC`äï`7`[Åã‚­ YVº¼æ ‹ûZ)“’E1‹PÊ.ÜÇ"4q¼EO Õþ\r -ªv>´,·¬¬˜©X'b1g­(,œ7Œ|6*ƒºxyÓ K _žÕ,‰ítÄJ åª9N¥,ÖHÁšdrº= ý3ÿ¢f•ÃH7¨zÍY[£dš¶7#ŸFQ±¼pëïYQ³š³¼tqÄ« iZk&4ëôðü€RæWÕ”Äxq÷û1²²?Oôg´$Ø-nÖŒ—8–ÀÈÑÑ8Š^ضŒŒÈ kj×/Åê/‡,+Jü´¦<3`4ÇqM/j!É&)&¢¡LŽp}OÐ:žšÄ‘ý3æT0 õªsS"鎻ŠYÉò/ ›àlC¼¢Ù/­ 3¶1r›#6*8–cH¦•ë8÷æ(pl,†/jÚy¶Çæ`»£,cKI‰Xÿú45>޶d%ÿ„×ö£÷~¬ãH¯èÚàjÇfïi‰qŒÖvˆ³lÁ+š‘³j}äÆ%_°šréGgÙÌ,››g²Õ\³Í1ËkäèùîÓJØE]¤Ý•šu$›“H|5kþÅüÊ™kùL5G|Í‘šÏ•<¥\j–;LÉªÏ Ôø-ÁZqˆcl¼Ù:f­fn±~ÎW6ë,¯-WI,AcBfJqп\:ñ4b =x±f!P5½­öqãLŒ²º¥1(Q‘4VÚÌåŽkÞUMììè_Ýìð“ÉçïÎß·ÌäékC2¹¢ñY¸dSŽÍvPæËÊ8×x%22ˆÄ̰¥5·¶Q¯@õrø±†ƒò­¬ˆ"ôšH#Ç•5N$ ¯k GÄž ÉËq¶Øc°[‰1Ùn‹ ªlö„[Mòá<ùÚIp™Oþu“Ÿ’þÕ?mdÃã'ªýkªþ.]ÂÐ2ËÙÉ1ÞÅL‹EœE*è倀s‰W#2·1`K›,«\åX`@R¶{{:nœ4~ªüe7Iÿ0žš+̶Fÿe‰—º9Äp9ˆåHsŒ€€Ÿ.XF¶0 ¯Ýư^ºQîÆ¥àRÖµ+òÂÕ¥’@»ÒúÙºuUe0!ŸlÍ¥P3³ªÝEÁ«5æZCùznuDÊð¾#E£…¹×û·œŸaHzv3cã D(|Ì>ŽðU‰gQ’xY¢jî(LáðŠØ«ãÒa‚³œHæœ5úšo‰‡ü¤†ËÓ_¼o.U‘§š>K\ÌÔ”ä7*XQàrˆå@Ê߸`ÙÔleÓ®öëþÈÖÎéH[Œlm]¯q.*c ¨¶Y*áB´Zq·'cÍ´躩Fíh4,$Q3èY¥±ÖO ÎH¬ut£D‚槃Ì%[ÖFlcÀò‚u;øǬ§°\pPàa;)Šî²FFƈ²E ­ÝŒä-7ei0@•Íh< œðæDv2ü j>½}‹¢v[¶ÃaËf8Z`¢ˆÁø <ÉÁ z.¥q( àï &#r{b9;µš2é¨ÓkëDÕTßak;ÊÊñ¸*Ê ¾è¨)ŽÛ˜z!€Œ@IWlã «ÒEZè˜{æÕ §ú l•rI‚,)¡(ÖQXwJsþá5[^býzÞÃ>À«‘æi-=gRü”Ñέ”"-9.$–…s]²™6ërÂN{¥ã:’É…c%gUΓ&1ƒMòê Lì–07›¼þÚ„šÉò \ȸ¦€µô•2HÐ-z ã£à³a¹/ àï#ÃÝ Ævy=?¶4çH4‰“^/ívpqV¡ý<ˆÖ<³uU;”Ìô8—ÂI)u$êÚ•e]׸)R¥±rRq`IëàqYk,Îè#Äh ð5Æ¡ggôÌ–öasRL±p"j'•kŸ\ªWWètŠ1cdI\"AÃ…µZ¸x˜j6b.ð~e±hx°°ÒbÄ$ùlÌÚêtö…!j^ÎYW¹®â_þÄÌ^mi¥*¦mv¶Šgäáéc p^l’¢uû pk4*‚§×Ö¬—œë_s@ÀŠ Š‘ueåÖúfe3;¹Üïë´ÕÞ¹ÐY\Œ»m¡%¦²U¼à'ƒR†¹;hኢ+pcÈ cÎu±æJ:T͌ז™Êš Y[J#7Û$­T ú¼ÒÚµÚºÓæ^&ÛŠ2.¢¦:¨öøI7èÃ÷éèš{?ϺÂS ª—ÕÜNÑ H¦1ˆc¤?E«‹5IWF%*ÖX²®Fvö¨[)˜Œ°§‰`g¸gð-jÝMRëÜŽžæGWô)¼¦ùPxU7­²á§£qhä8rÌ¥çú—p!â‚bäµÍj­_åÖ‹Á Óhv®=×Ó­»i(æ0*8ÈÏA†tƒùLö繎 (Ø$Æl¡˜ÅÀnmËduÉÈÈÜÖ!¶µJít$v¡i>£l9àqNügK”Í\ñ•A=Øtã1¶| Œ,0¢ä‹ŒY[!††cVKŒ`€Èžëa ZÍ™)@׳4ņÍЦš£cqJKbaA5xõ™5Óx…š0¯ÚR$Â'oˉ®vVx–)q[Ö„•­a=òÀ[¢ºR=ý~¶¸@èr”׫ýx×ñ”L"YTn’’³ù٨זsmÞÒg| î|3gý1jg´ß!1 , tì¨ßsQb똰ƒ˜Í3g0Ä!`;Ǥ’<ŽD ©8­²,s”}ú7"W{FUÔð´ ŒVlP¹±Ñ°ÊÆNèXc𣖒ƒLW†:]%@žÕk†ËÃkÀÛD*Œ5Šb«–R;P¼(±w¤d\ç\5 8OãvKɉEÊÆPÓOÅ$ûùæ­tï‘lï—ö†1þM‰ï7†HÓs­VøYâaäS«Åñ¥lm`„ÒíT“‘<—J ³z˜Y.t§wÛ˜PÜk±DRáÆ¸Iá\U;cxe±u“& “(f©ÿ^YYºSu9ðu’bx—ÂHnWÄ.ÝÚÓó}©pNÁ]¬â«1•„òêHf^U.‰¬%W#Aý­»)ñ#IxSãÀE(1™ˆÓç;—†Â¾Úù¼æ˜íûJk»%4Qû¸°jŸ·Ê䌼‡|mKm1¸ÃVTR7Y}…!O%Œ­³þ÷ìD.Ñ!-. àgƒóž‘áòGY½²Qm ðb«¥ãHÙÚ˜ªê¶EšFC·¶Y`ˆ EáS)LögÛ(÷¶ZY25Î rNáÒ¨'¾ñ6"Õ…¹‹ú¸?»òÉ–¬…j*¡Äd;É)+1s[•µR¢×“ð] XSa†ŒW¨|±(Cá8¡|â3‰ÖŠòÛà ŠûQ‹5Hûˆpe–±qîlÞu*EÊžm±žhDnîš{t“ò<¸Áª t=ߘJ`‘·Èý‚uâÓ}µaçÕ1›OQŒ{»gí0>@©®ØæÐÁ#m¡lÿÙøë¼Âq~32\û8skýêäÊ8+ÌÜ\k׎d&1¥oŽÊqn€‚W˦?BÝk [¢H&1¹È#{b µªjÊUp!$VBS´ùh,½ŠÕ½‡‹5Ò¨ .–½¤Úš\í•jVÍ`7 ÜÑØg¬ai Ö*m#{ _TR#)ƒdV“´âémò"!+†¼Œ‰qTP—¶”‘Ó%¾ 1² êî¨3ƒ‰Ö !F—–þà­š„ ü1Ç’2^¹¢E‰.ÉH»µpBÁh"†yðb³ÆI*NÎvðÌÞl¢ð±À©%ÏSH9 àïŠó; ˜åfy-[^+Vû•A×¶øS‡f/Ì´"Ë£á¦à‹Ýî|¯½14£ÌäyeJ`j^W’cÎ1÷kWJr±ðJ’妟»‰¯¦¯²S>Ç€3|ì¶gÚ_‡EiZDT1h‘"£z<áƒb4·;q«­ðyÁ9b®™É˜Ó”SÁš’?Åš‡}£( B2£X5F¶…ã'´"(µ×Á׃ »hƒÀŸŸCƒ¢Â°•œu#u˜mÂÞS?%íŸðÔpýºEzœ‚æÖ6õį.UÈËpI±¯Lá¬ߥ„e˜´à»†ƒHw•#üpkd`„—O O­ŒV7²¢²2Jâ8I½s>Þµ ZÌÊ›T€á¨X]ÔVè$­—Xí¬µ–^ó&R ,ESÝ4it.e,ÓöŠ4)ê ∼š ¾Ô¹‘¦öÕ"ø¹kŠ>67Ë|\eÅ8ŠôŽÅ^«%¼!cM„u6o1CƒSìBŸ9`Ž ®æe îÆ<8Ƈà/6æÔvš±¹–´¨ãµ”®©öÙʹŠTl¸‰›’×X>·üI4Ù`¿‹¢tBóˆc>† $MFQ“:|„+–X˜ê@Ê'œÇye-_ÝÈóÒZ.¡¸3‚U‘VUÍ–6ÜL[Ì÷χN;Žb½1•e«¤•F–Šø¦šúø° <^N/8Ñ´±xŠSåY̲à˜D\’¡DŒ‹i¦¤}®1èÁ$ ‡™¹q´7n‰"Öé견E©ªÒ ¹R-¹t@ïÄj IÍŒàÿÕéŠ;æÓ×dËð&spRÌRRá5-b÷?*æ.k¶9Âoár¢$ËfÞ˜è3Þ¸Í)ƒœ—sl0ÀxH%™(|ª.IÙkd©yY0ã–19xø€;æÛ¼Z â"籦¾$%Kj3º€€W<ÎK D6›—Ž–Vû WQÅ‘ÒZ(Ák=ÛKg{ª­›Lƒªtëýl0*@¥ÎÎu@ÆzÉYV–y‡ 4¢X(ò(ÅI2;Ò¹Œxг!RöÔT3b*Fi ¤<$PúlšÜ<_ªÐ-™g˜C§”LSL\ ØõÙ^\ûPP\V¹¼ªk¦`Ø)ðu,é†ñ@S†0¦©ð»>ií4) ÑIÐëî%K€ŠmÓ@ìíêFá§ê]ÇÒ¤¹†4Æ=wPÄńn8NFàeÔÈtÀ6QðpèÒ”çî–èŸü—p>2²µnœ×'WFƒQ%„†uiÌh\€œU¢™šGÀÎRs·­Ó–L"äU`äš›æy>ÄççÚq¬Jãò’ùV§È¹ÖÁ)üSÜó¯/Ó#áL¯ýGŒòá`øçBÒT¿.(4àá¼ ÖÔ+¤j24|°¸ {eM!ùÌ‘RÖ zÿeŒ–‘÷úYZ*67r¸rà寀©€ŽÈö“Œ…@Ø{úºgéW éWŠtLǸx©¼á=…†yã’1#§1ZdF˜6F,Øøµ*) OáµqjÈOʦõK…ýÓÃm‰ÐíæÎO5†c³Ø•J¥ðà|bäÚº¢¬_>Ñ?qjssXê(êv;³½´ÛÝTöº±&QªmsTÆuåɈ!ñùÌb¯¹T Ÿ¦S®EU™Ñ +²¢ÓiÍÏ·€ Ê=‡&;–$3§H•oP„¹ »‰LöEÆl‹ß0%g4Iruݔ͑­ëyšRßÈሂ’ùôf‘7¡’qfWWê"7^ d팤ôÌîd„Ú\”Èã(ÀUc®O+“MÚ²ðCAE±aäkŲ3."…¦EpF yǮΠ‡ÀõNSÀZR,ÛÕg8/gDÊ@Äp¢ˆ£½½ôg1(óÇ#³cV‰ÀÉ?6Î'FÝ»¼–­ ªþØP×M$âH+ÑNÕ Æ„%NÒ1{Ìå• v-eM`K=LnC(9! Gà”Øt6e›ëÃV ³ÓÒ–Ê2;.áÈ圲&à‹4­çhßr„–áš48Þ±³F¦´6G¦§#Ëc×ÈmŸgêºîv£nÙßçuøÝ[‰^¶±aÑÖH¹8æ~cMeÙÀÂ(•jÿ,e@û6Ø’â•9í9„Ñd‹ÎpI’h:+ÑG^Ϥ˜z\:Ô¼@Öãœm¬»;Ãb¨šiŒ>÷Ò-mýhP“ímtØ08˜U–|î +K'…›m;¢€€ç#oôócKã'ûãÜÎ#˜ÅǑж1Õ<Ò<VFéKêPÉ m5¶A¹(U¤lÃ3ØÎ)ј +¸Ž¸©ìÚÊf™—33­……|ZÔ®¨\Mb‹Iˆw-‘®@vl„'›:;/K_l¸ŸÖú(Âë¨{—²¡r©¦¤l76úv47—ú|g)¦qj.ExCÖï£Yб’» RÓN"eÄi…ÕwŒVá@Ôƒò5dd'é"†\…’¸)Ea”q‘çxýè}ÓÛ’•ÖrVfNcá WÔ€ªá[)ÖPÇ©’ªKà óš•Æ%hœÁ‹¾îºi 倀 ç #ç¥]ßÌ_8:è 40ü™¤*Ž‘–ˆé˜"GcId¤•TŠD-ú;…ÚÄ3öÄ­B6^ÁX9Ý,ÕÕµ©Gì*«ÞLÒ›iëH 7E…ûP{sdôòÄÊëÚ«dG4ÝD9|F³g[Ÿ¼áSã˜I;tÁ¤Ö}©l«*¥ƒÊ”;gÛm¸¿¦•ªM¨î”ìÔ)LzV‘„QD;“TG©¯(¥:gÞä­¦Ø4ÈXï:„YÉ>NbɵC¢XÆšoùp¢¶sQ‘M]f ©ãaßIé`ó‘^—ø¶RìÈ¢oúŽ­V¼0<а.O×sm¡U^ühœ7Œ<ÊÊ—O –׳h2—ÄqšD\r¿œF›™ÆZD”J¡”N^¤ ƒ¤–¦k`T `€ÔœÄhN)h¸ ØJ”¥9yb¹6fÏÞ…ÙÙVK£Õ½³“xwÜÇ“-ÿùX)rJ ®jò¾¤Ž–™€\5$ój›M21X³xˆDYè—Üí(¥˜duÈ kÊôèñ¼?0:Ž’³/š"å¬Öh„¥Ø#‚ºf9ŠeŒ;3,ëP”B‡‘k…{Š\˜K†9ÒØN ï)ÁõZP¿ã¾Òû{p¿vcïQSÁHÌ1‘®ÌUVh1»n‡FØ-°ªÜ|G„€r@ÀÄùÁÈ 1O,-ú™h}­¶¨ù$†$’"E$¢XµSE ¬ÆRÑ÷hÈÏ6"yCÃ@™BR@Ã%¨¡(>Ì–ƒý²¬ô‡ gççÚs3 PÏf¿fµÄ€6aVmÎ3Iu€×¦BñŒÚ’7åR7áfKöo5iUŸ\ÑðzÞ[clÚR­´éλ¡á²:]®­©Sõ‰5³´T€PO•&\+¡4oÊXR ûÂOD‰t‚ŒŠ Ï‹åZ$-j횬Žèva£ŽDr¸ÆÂ¶ÐØd2ïˆFìLýòšT ô ¢µ8øJNJNS½°Ð²–/¯³Ò&‰îÄÄfY¹qf)BŽõô: JAÏ¡x–Z_ ïHGÄäK6„lBÉ”ÅWb °¦í´ÑWሌ·¬6µËȰ}D|œ•µÅØ·1µÁjq&|ÏU‡AdCu(xZºƒ]\1òjtOfØ× _§ñ#ª‘Q|<¶¥åí–hK—;'N—jbUJwQ“#³’~åÐÁoÆQúv¬0—Ž&"hYWaF ä€€ˆó€‘Ãr”×@80én§Ñ\/%HÁ   ž’ÐwØç\ù¸Ese³†’¥±ðíôpÍ÷¢CæõéÃ0¿GCùšÖý¨ ˆkÈ\SßhKñÜ(ÖišŽÇåÚúdu'•í&%µ_¢ÐoŠûˆÞ½öŽET:(š¬ "YIÁ G‘VG%v†2ä(qn°FZí‘#{9—Š:ø9Ÿ}L9|E^ŽF#Î5V…PÜ3§QvSÔºØ%ÏgCóÆ2 `š ]=:Üû–°‚gYeÖ¢kð8á2My7BM]Ô®áê)×n²§'E4ZòÜ )3\QÄC…‹ð$aô’Ò…B¾€€„óÀSJYPÞ0 èµÍq­¥ÁD©…Òµõk˲ö6AU]+¦qÍòÞ¨–½ÖuñéÉŽt'mÀ%@l,M¶ OiþíM“‘úï0á[P®±3s½lœ/¯gƒQ¹s>íÆ2Õ|#Ã0+Fx)Š §®ˆ£á @ÉÒÂѸ*éÈB¨ _7 L1 ¹Š"Œ (ZÊ3”5…s¢‰Vc‚©Q"_V”(âwïì…Ùö…j[+°¨ÛšÅX‡ÇesZ¾“R8\XiÐO¹—°Ù„­ßþǼq6¶Ûh¡„Œ 7<Mëù.Û=ÃŽ¯ã`$ ¶“¾[á¥a”^.JÊî€',p”Á. àb»Ç‘‹²fÕ‰åñ樮¨/Òb¦«g» º U.+Ab±%.Þž i}‰†£XBršè¯0yå^–×ee±·ˆ©…_¥‡±` !»Æ¼{;yÖLØ«²^]Ù6ܳk¦“ ÝÄаþ|&ä9ߊzsP4üyV5Æ îKþ¸kÖ©S ÕŒHÚßw³6%ƦáJblîGm™¨4öàÖ­”º(*­e¯%ß\YßÔº‹‹ŽF‘VðÄpUN†}ýX¤¬PµÄ:r´Sê´Ñ•b\³•uŠÛNDžç*Ž“„¯o[©«`D‹[r®åZ±8±îÒ~·¢$ÉÿåT£™=&„àíéÃ<“^xAÄ]–0ðØkF‚ Q@À÷Áv×Èð3¶­­)Ï™€ùuU«¬°-Wá•3Ðq9C³Úp© ¶õb5‡O5å#5IYƒvÅ5.r°V¢÷Æbäf­*±YÀøèq³~TÙON9¿8W•åÑcÝn¼wW§­X2Ëe<¢x:“yãÄæ'øÀ‡¸phj̾£…AɯKÊ¿£1 d¾Ÿlt=æŸÁUTT <ÊÊÊk´ë ±‹€€ïÁyGçeT ²Â“ há,/22xóæÅÂ6‘ßúCú…;œ"c”²¸LG¯9úvbúÈ¡.®hI ”a„íPÑó¾©èÃj`SáB™›h]?£À°rqŸ(›5ˆÐ8ª+;UpìT‹½ß0ÜÁ)ÙI{Ë!ŒQ o…Aˆð.ƒ7¡àÆò¹Ón>>MwƒÃKYaw¨åµÁæ` ×=‚GSÁe8R·Û³A~ñÞÅå`°!¸â\Ñ9)™D*:8Œ@kóð¬k%Ô»¦zkÅ2x7eÖMðö(«ï ;Ph¼Ÿ×Xôà\0,eSàHcW~¿H —šh̸0Ô+ ÆB> Ë`²8ãp åsý—°í°½™ò€éÐi3CÛ ë€0¦ 4ÿÍgÆy⣠3[a¢V7ƒ’Ä”6Z¾ÃðÍàe“zÐpXL0ð¶Æøã‰ÙYŸÉ@îš^S  TD |ï¨Û¤’+èáš1Ë|‰õ°)´ÀýB"öV¦FAZcð¦BÖç:¬c’ÿä¸Va¦Ûí£³rÇ\81ËGp2S;FØUbs‡æ˜X"Œá3-«€TØÃx£ÙÞó$Q åÆã"Ib¥¸àà|D `ê…®ÒÝ0yŠR”Ÿ 9µ’☘ADŒÉ•ÅL8 ‚×8VÁÕÂU™p¶7#—å¥e ê]ã©F‰Y% L.OP(¢(E7³ušõ†a¥V çïÆàÚF¬ŸŠûÜdl‚⦔Z`á\…,! R©”ÖŒ©k¨wmcäs5µ/ªI+([ËNƒ™yM$rã#ÒùþO¢1Âg¬Ñ•ž”«²d$|É·OiJ´ip™~PÆ;Ùq¼qN«Ž8(à2Ÿ±ívTVV³Ý\' 4°+Ü Àx–c G–ä:†ýK å678íÀ²“HÁkQS ¾²uV˜™vJÆÿ¬¦ð­Uм°ÀæÈ¼5Õ¶X³lsÁ°¥25É‘§³ÊEd6Ô¬hžŸÆZÈP1°Û‘¹ä ÇåpTyMUÌ«[ ïÊšª*|q¥Áù”2ŠË6 ñ¼Æ¤?¤Ù¦!ˆwŬiy$¶OuÀpÎê‘U½[zQJJIöôÃkcïÚCÂ~QŽ1$8Îj˜æwRì/U–¨)ìÍóz1ñ§§lGúÒ”(hïRâ&޲Éôˆ"™eõ`8¬A¯Ò #èbWS@„B 8à›¦)Ðu^˜v¢±…㽃þÐæ>‚‚™$­®6L>X;%5Ïö§ƒ¦6F©ÍaÖiDZ–Y * •¦À!ãHaâ²u½{Mz†ºpáJ S4ÍVp£@wS¸æ8y2™™°Û‘‰@#•ÍK”µ˜ËIŒóR$B`Ì–û6΋FÌkpHL¶ö*˜"­UY6z™\ŠüJUéhŸãxm}½\cåCÕÙ΀„¬LI vÞR?r¼š2t…÷ŒÉ|O&TÖpxiëzœÁ8ÀÚ-‰sö¦~›ûæ ‚HŠb!ÜÇ[ɈûØ6ò¨mVùÐ\Tcð-{D”gf<.ðøNLRýšòDc(-$c‹Ñ —Ä^p£¿¿W¾¾É*Œ9ð­V¤º=ô…0¢ƒF8€Á[?áÈ«b8*çÓ ¢…&'|\ÏÄ0:Œ­BKeÌrÃᆞ ÒÉ 9R"/ëHã¯~G…ñaq̃†Çk*|àØ”6¨ä€€ ¶uöÛ¤>MÀ„7f±£ü ©(¸¢D%aˆ4xèÊFÚ;¸S2f$cHU’ÿ Ìñ q¹ ÿ–×c®‰û(Ÿc«^ý’¨Æ´3Î)§C#@ÍÑJS^1®Øù:fänæëú¸ï–$p¨ÀˆsÛª`Ü.Îi“ýœ:zLìí½è6T0"ÉGÎrÌCð6IÞ›L—ôÈÛûÌl¤ý(+€h·=”rb ŽW\æYÔØî¤µå ׬۸8i‡£cÐNá`aêO~îo‡£<Žùî½_|ËíÖ*©VP겨¥Ð­8Ú žìXlsÔåžÂBG¿­–:µVÆ»¢™]ß@*£«§ÁÐ˙찭9nØJÅòX²\p43ÒÂÚzœ›nk[ÿü<±­5² x6˜­÷GEFÈdW/‘£“D¶Z83/« QStÕ{>DØZ 8¡•ÆÀ¤Ô.Ìä1ì rÈ òŠ÷ ¾žoà°ÞÁˆØ pæ¾?)U'×uÓp ­ˆ1›‹­}}Ñ@93éˆJW®”˼âíX´INúÆ£t‡ë1ßÛÚã˜P»ÆÔ;Q>ƒó"˜†.HcqS£QЉ×UMÁ Q˜I&¸*á‘iÌíSãï ¶Öuõ‘O>øè“/<ûÂ)àå·Ý}¤,e6I¼“ Ü…‡Œõ2F»ªÀ$AÛëh_h(Uc[á×4ÇY ·–hV¸¦|Æûu nðé¦1Ø#ʱæ^0´ã°ùV;–!é" Àã<ˆâµÂÜ6f”Æä5®ú[^a S˜„²I#Ùk§i„öÀhÅ¿6/*US0tceHçÌU¦ÊË" ªíu¦^Ø×öŒwd#:¥LKéUMùÒ1?hèS9ø²¡P4|¡¢e=xh;y:Üì“í8kw[ÃQv|)++6ßBëaN^?µ7|ð6Èί¼aL]8ÑI£öQFùvbj‘¤,…±Hböˆäš3¿—0ðPž6ƒ!j<Êa~€¹:®+EºÛ‰}ò6–BOà‡¸ƒáЮmdKë¥ê¥ZmÒ4œx8Æç $>/G®Ê–ªZTÄ+ËWû8ùèø–¬Þ¶_ ´¯°‡l3ú>ÖXàHѲFy}®ÿĶ ΃ #(ÐHËVª;íˆZÜ£¤UI,ç4Å&à¿ì(®‘ƒ²hN‚B–‘©ª¢ÈqÁ óvõ ÑŒ)-Ö¡åÁ\aâö!Ó5ã}¤ðut‚<%0W©–®"c¶HkàPÙUsÛØ9Eç+‚AÁnMãÎLgcmóÅ—ËýÍv¤êE0•fø?j¥Ð‡ ¦÷è^Îp0àñHc(Ù›ZÀm´;:Ë¢µ.1€ zLa²·«¦™ –qÞ£BiAn>ÎÔds üŽO5 –ªª2eeÇ9Ý£¥’aü¬(²VmÓVû‡Ýž±(Ž L†F‘K†4U¯A Ñ•˜™ŸÙ\Û|þ…åƒw´ŒEôGÄ\h²á[hS Gcb¸ZÉ0©ObsÓs­ë%‹c>7ßKÛÜÌ…ÃÆÔŽ_¼2D0£¤¨* õ²víVŒ©&¥™›I8¦cg×_qÙ=‹ Ww/.84‡Ãˆ `ãÃA=‹ár¯xœF®|¢»t^¢32rjæË¸ØGA ð¬pã˜Í$ìTó‘)ÜÄáöå–i  êaˆD÷d hJÌ(+?˜œ'ŒÌH‡&‰n·¢¼,6û.ÓÇ ¤¶£F? ¼äincZy9V¡ }­È°¤›Áü ‹J­ 0Æ&‰tš(\6dµ/øÃFt è»6UŒL©¿¢öΜ˜zçó4€Ó ,ì¶ØSk¯-Q'¨cU˜’3Ö”ZÀɇø.Ò¢7ÛÝX>ýÌ©«¯ØÕŽ‘µW6°<ûöP“rm˜à—%P¹…Ñ”>#<Ì©»ÑHòvKîÙÝúŽJæ4%VS­!>­û᪠j Ïb_éÂÓ榨”]íÞ}÷«Ñ_4qíN&Ù›T ^ÇIŒáQ²d›‹ñ¸–àÆBD´?®Ñ^¯²”6BÖtpËý‘K4‡ûg0&qTáÓ,*ǨÌ[Fi*³¶¼ñëàè(‡™é¦çÍŸb@Àß¶õÊÞÙ×*…–Ò[!£‘Ö,‹Ùk1c¢F'"º¶ðžëd”ÜZ‘þŰEM± ‹Å× 5uUã‘1ÆÚŽÓTÃ$ÝY…fë ²5íðšQŠ—/D¯"*šÆä\¥#o¦FiЖ:`;ÌžX%ã4¿¶ —×d6®Ö7F;çZŽùÆF{jÊÌõÉX(É-É2¸g ¹R±ø4ÂMá‹8­VÂÈ* n³é"å;¸R{l,MôK‚äh‘¶`´Ù¨Œ'QžUðÜbt|Æ~Þ g‹²Œ4ë´“Ùd>ÖB(<¯öGÅ VS‰‡TØ‚£óÝMò½ÏÊF¦3,¼Æ»×rÊÈ>Sùçc©ä¯0a}/ ±ÝÝ8Ïüg¼´š¯ndƒjWR¨Va»OwäIàBÕH-‹¢´ÆbݦSøÒ2Á¤T‹•'H6 ¶h÷B¼0£4öˆs@.ÃZcúA[P.SÁ´{è‘§^:v ¸)Ž¢7ßy£µæùOŠleµ'ß·{~×ÎÙk®8Ði¥ÀË'VÖáÓ—-oôÇI¬/½xçÕ—_´saf°9è¶ôÁý=¸©AÅN,eÀûi ã+Ãï>wbiuó¥——¨¸¥óE»ço>rhÿ¾IL.ôÃÊqÄVÖûø'†p—fÿÞÅk¯ºô؉ՕÕÍã§Öà÷ì\€s]²WcK) ïÙÙv™•0wètÕú³/?µCË®3¿pÏ­Eኼì´ÔÂBú•û¿ôío>™åUš¦ï~ß;aà{æéN]>yâäž}»wïÛqùáK/¾h'(ä±qŠR§aô1…ûÒçîá™gà1å…»çÞ;/»âàñ£ÇN?¹¾¼|äúǯ>”è&Š1Æ€{yieyùر¥þêJ‘á÷íܳgÇî=‹gµI}ù¥“úà_WUÿ¾õ¶ëÞø¦[ýkøÕüé‡>õÒ‹'ýÛ+¯ºôÞ·½îÏÿì3Ó-oºûÖWßzÝYGƒ¯`Æ$cívú_çÜ\ï\ÿuœ?Q‹)ºm˜'èãë0`m=SJµ;iÚJ9QÀfãÌdp6NÖÂLEÀv#Rë$A½Ô“e@²¢• ÇFcû\V Gnל줂E<Š„©U‘ÛÍaIYd jÜs/žxèÛO1¬ŸÆõw¾ûò‰S«[Ç5`’#×\ú?p÷wž>öá=xrycëõ/Ìuï¾óºwßóªaV]Î.Ú‘v53‹É©å|e5ÿ«Ï~ý+}çÔÊf]Û³nü¯>÷õ÷¾ëu0`×*æªÒecsìXÿ³÷? ÏÁùË_{biµ_ùœgB¤ÕÕW\|ïoÙ¹87ÎrxVÝNT ŠÁ°|èѧŸ{q ö9°oÇ=w^ç°:QÀóÿöÃO~þ30r}ùÅcËK+ë›ÓÁ×ÎÝ;ÞóÞõÖ{o·•4º*’yâñï~é _ö»]rÙ/ßÿµ/}á+Cx¬Îý³ÿå7¯ºör;ÉïÆüãOÂYú›ƒÒ»åû Žôì\÷ž{îø•ø¶n·=ݾcçü`0þÂç¿êß~ëá'/¹dïe÷Ãë/Ýÿÿï?~4§‡_þM’h8ò¯î÷;ÃÜ|ËÕÞjÊã=þÑ|Á¿¾ñ¦«Ò49×׈ó)jÁˆ "-;mí[Lc@UG)~‰¢¤ /Vv8ªNΩ¢äUá4—í$êvâ4â¦Ìóñ¤G†ó.o”l+`¹þÈ GUmòT۪Ĕ»¹9Ñ‚1€J³«mæûÎó@Á »}þÅ“ƒaö½×yriã+ßxú¯=ÙÿžO=ŸzöøÎ³—_ºD(—²…‰}l\™ÿðÇŸûÔ}ß„¯Àű^˜ëÍδ±úÓžñ‹O>}ô²‹wïZœ«©¼Û»´´þÅ¿ýŽ1Íp1ÖžAå ²O.­?ûü‰Ý;çf»¶6Z `·û¿öÄÆæöéuÓÛn8¨Ñ?êuR©Üƒ÷íÅç2zF«+ky–Ÿu£á葇ÛÜ\䪜B7uiafòͯ~óÅç_òûœ8zò‘‡/ŠÂ¿}í7:| •ö±“'WþÅïþÁg?õåÑh|ÖØƒÅ/£ì±GŸyö™—¯;r¸ÓiùíJÉC‡<üð“ëë}x;ŒúýÑkn¿aiiõÿü—´¼¼îÿ<~é}o~×»_/z½ö}_øšçú²2w¿ù6áñ7õgþ̳Ͼìß¾ç=wßxÓ•çúO; qþidFÿEÍÏÆ ™.6Fõú¯Ñ˜ 8&ŸI+ :M^Ô΢²Ì†eYTT5!¹u’úÖ¡£¹Q8[s›÷G<«¢±]˜©óÒ€œŸQ3{¢Sëð5¾ÙÏ…<#‰;Žô‡öî\œ*yüÉ—–V7ýöµõ£Ô½Ë.ÞuÉþðú‘'^ZZÁO@?uß÷ÝtE¤":b31îÙ£÷õ;”âÌnºîà{ßuÇÜlW+½¾1|ü;/~èã÷gy1矾ï¡ë¯¹D0a,z Òq§ùÙΞ]óíV²¶1<¹´6!™žXZûÔºhï½v< gg» =1ìôyVUÙJTBÏe^sFŽpG¸hÏE{‹²8úÂÑS'NaÖFQ~ê÷]qåÁë^uc¹lŸÌ–PÃÒ©åï÷ËÃ(û‡?ôé¯~åÛÓƒ¸dßž}»adzñÅÏ?w4Ç’yû•¯|û?ÿ§¿üŸþçhÝü•î?°û×ÿÛwýîïü/‡A_ä0<·ç&ÜzÍ5ßÿþ·úììï½âÊKúúãt%k?öìwÝìw*ú»/ú× ©A>Ÿë¿è€€ç%#ûc©ó\‰\85¢j´ÊrWÚpJ­eœè¹Vf÷ãQ5dRq-•jÇuã€lulæûÕ9Œ+GTȌьÕ~9ÈënK 2S˜jÇl¼o^ÍtÔ‰¬œ^ \ïýòëßtç‘$Žáˆ_þÛÇÿïßÿË)ýÕ÷¼ö­o¼a¦Û&úâƒÿËÛ|züäÚòÚæ¥íγjc³sò»Ïùïý:î¾ó†Cï‚k¬,Û»{nq~æ>óèwž‡/;±6ænJNôV µ5sìʃûÞûöÛfgº\j8ѳ/øðÇ¿œ=÷Ò‰¯~ãÉ×ß~í¨*€É£$šF!(±Ïg:ã*hã·<Ìèã·ÞÿªÛ_£ã´?¯.­~꣟~à‹_&gógú«+®¾Ü(ôqsöûü¦öíßsåÕ‡¾øÚëûƒ>òí§þú“Md#m%ø÷¾þM· ¥ºÚšò3Ÿzàÿù7â9÷3Ÿ~àšk¾ííwNøº;oþÆCO|üc÷1 ÿþ¿ÿó¢(ýGIýƒ_½w~afúöî7¿v¦¶2õ׿þØ”‘[:E³À¡ËwŸë¿è€€ç%#{ø¾yó³I¤ÅòzÁW.Ëm¤1ãMÀÜÛ 2Z«`®\•ÜiÅŒI zbq­‘¹Z%£1¹®cDX:}\˜vK–VԌ:‘¸h§nm)gxõ‡ï}ãMi¢5¾{Õ /¾hdz/4 J·Þxù/Ü{kDy0ˆÜrãAËÏ<ŸfYyjyõÊÃ{óq¹Ñoyã‘7¾æŠŽo.­7\}‰à&ï/ŸZ}æùß}æØó/5Ç\Ûns³­ª°Y–×[Ø0¼çm·íÝ5Í'`šéÞ;^}õ_}æk¾þð›>}ÛM‡qér8nuZœ7C Lbê­‚žšuYäÕV–ë;ïzû»ß0ÄÃXãÒNëî·¿å™§ž9yü|úÒ GŸyòé+o8RQúß™z½æu·üÒ¯¾÷ðá=¦r³]¬b þô§ F~‡{ßq×›ßúºHëÍ©íL'yû;ïúÖ·žüüç0^ ¼üÑ|áõoxõ4àzù~àí=öŒ×ÅÃáxz®·ÜsÇíwܸõìGn¸baaveO<þ,œÔ¦Ÿzòùñ¸‰Ã€¬î>×Ë ΃*êvõ‚·[z¶—ìÛÕ^œfRÙ‰¥­pGQ€Ø³X;Ââ(Ju,tD~jÖRSQ,=Ʋ:ƒk_ó3­¹n¬¥e6®Ü(é$Ç.Ôý~Õï×//U/­Ú«“¥jØ ýê›.WZUè½NŒ<ýôæ#‡Ð/Ôb®.Q¯›\z`Çôâ±ÀÕIÊ¢VT.M{ûì¼ý†s=ý'ý›ÿý÷>ôÏÿÿò»ÿêÃô¡/üí7žŽšx4)SlcÕjaô|4>áݵػþê‹0­k-ù¼¹ë¯¾xn¶ãwXYë÷#4€¦XíÖÇØëµ%¦3SW`oþ0â$¾ëM·¢›ºEÍ¥fæænºõ–éõ<úè3­X#»3‚Ø ‹s¿ù›ïÞ½{èÞ7J\ß=ñØ3~‡$‰ßx÷­Ôj ûÒæÎ€sßþŽ»¢¨iX zÖLj§Ø»wç?ù~yë¢ಃû©§ñ ={o¸± ¿ôâñgžÆ·×Ë“ ˆÎÊÁ8·85òq,•âÀ ´ZÙ(‡Y=,ÊÚ‹¦À¹B‘'N¦e)ï—ŽÖmÎEJ-Ä šÛk¬3EVæ(ëVÚmu!Ù¸¨–ÖÐ@ÃNB¬I]´wS†ÜYãP1±˜ÀO\´ó‹Éê+ªíéO=8u;ò)k1ºo?ñü‡?þà#ß9Z™lõàÜ(ËŠ¼Œ’h~®½²Þš~²o÷üâ| dìh8ÆëQÁoó o|õ}_ø°0Èí¯}õÑoºjccðôÓÍÚã‹÷ºüÀ¹þû 8 ‘Í»qù.ÂÔ®µÍjch6FÈÅ@Ö\’õ¦o§‡…ͨ‹Ñ}\ݰˆåXëǰxL>£ñšåºÆÂëj}ÜçK«e1î´£;DÚÞºx…v?ª1B²µgT«‰cØvÄÕl«„ô½é¨BÙˆÝÿÀ“ÿî?éâ¦75Ókïß»pÅå{ûÎËO<…ót H¥´¥DEªÝVÓSÎôR8a·onoý¦—D¿¾9ÄA’ôäjàu+áðÇY5.²zbiD—îF£w Oô>ˆlªF9}#+Ëkýa®"é+§Û/½ü²i·uÙÇjr,B‰ØÑc'§ƒV;‰¢Ä Ÿ§Ò´®†ßhç4‰ý>0Š,-­õëÞX€æ=ý$­}êɪ·™³42àÚk8°ûùçÁëÇxùÅޝ®4ùˆ7ßrõYZ; àÜâadFSo&xG‰NKÇk¹sÙÆ°2’%Øv‰¸ ¹9'|wQlôTS©1º|–ŽBËÞ;3ã`:F)(i׿sŒÛ’©¬rΞ&)›z$#,L9àÁ÷þ`“¥Hï¦qúSÎ0níðzF£áŸÿõS:Þ¹Ð}Õ‘ƒ·9tèÒ]½nG§ê_ý¿Ÿ˜02[˜‹{³±3¾Rîô O­ôÑZÇ!‡(±òÏN¯)ŠÔŽ…N 6ìt~1š’Æ1ŒFØÏÉÛÏ{¡]5Î]·ÍãFµhœ§Ë«ƒ­bxÇs‚¹3îu÷òfu <éŠÂÆš5ïÝ»«ÕJ<)on ûýAonëK¨*°B§P¾²²±ºÚf’ÆûìÞú‹þýЇ>ôºuãç?÷·w½þ–ï AÌ/ÌÜvûÏÈÏ<ýðøO<çSâ’$zÍkŽœë?Û€€3pá0òVìšO"ÁºI±60ùÔ°ÐxJ56éÔÆ@¬7ãäV”fåè»ÆmUb‘ü›sM=R ³ê¹$R‚Ÿ6a§Xq+—!ç+[ä:‡¦‹=oa,¯Ž}3¨£'WŽhæò‹óÝßù§ï¹öò‹6‡ÔET£»PQœ®¡P’µZ ÙTÓ6&ˆ§66ãV”€6×XÞœ«66GÓtGóÝ9m0å7¾ ¯'ÌÓt OàØË'_q2–“Glq1³c/^ÏÂŽ…Q^w"_ksú`ÍzÍò¼.ŽJÕrמ»v-xŠì÷‡pð™ùExæq$Íò²N´xú»/ 'yÜvk~ît„ðÐ×ÿË}ñ¬ZÓÑ(ûÃ?øÈ¡C¦¹S¼öµ7}ü£÷ÁƒÁè‘G¾ûØ£Oûí!d° q~¯ìýÌôâý{:—ìiϦBÔÕpPÀ컬P Sj™„ሒYCýª§ÝIrv§JB œåÜÐôÙãüÔÊf9)´»ôÀíKë¶ðheÁN.m>ý܉é·ê’™‚Z\“½Üi¼¼ñÙû‹bÕ›i-,Ìt:IUå÷=øÈ´JeÏÎÙùÙV„9€ªÝNO×°q´…‡ã ôÅÄ>Ž‘ ½ïÓ_ü§Ÿ¾áÆ+¯½öÐÖ«ðщ‡¿ùF9p[7žë?Ò€€³qÁ2ò Ûi{~6:¹R,oTƒÜÔµÄ,e-“X¡Ó5d¢fD¨Xm=¡9’„‘D m09Að-ó ßCD І8jñ7夦];½ vfPƒ{ê§aààÅ;wí˜9~iwu}ð;¿÷ç—î_Ü¿{&+ª‡yempÆ-Q“냯geŒ³ò?~ð‹þÄWgºéêúÞN?ºåúËn»åJ)Ðà_ǃ瓋‘`u}¬uœJÌòN0Xr†Ò|òñ§þÅÿö{ó‹³@|›ëý©€mµZoº÷-IšRWçÓצ°¾¬ðg:b0.êÚIÅ.:°ïß÷æû¯ÿ„zƒÛ‡¾þèÃß||v®§µ^]ݨ&Bˆ÷¿ÿ­Óô5F*8׫`ß÷Ë÷\sÍÁC‡|í«ýÍ¿ÎHAð¿þõÿúÏë¬ãÛn?òÁþõÚ¤œ’abÜ­pÁF-¦ t¼ÛŽöïJî‰÷ÌŠNÌÑÊ͆Š#Ç”2!˜Ž0D+)à+È?èCQk;¿FDd,Û²°GɾgÍöí™3æF1úöN”•¼uò¦h–w,ÌüÚûîh¥ ll~ì…îÛŸýÒ@Çœ¬„ýG8¯Çкßrº0 0ýAöòñµ)Ãtᵯ¾òýÊ›v-η[-Rßšœzú¨34U2â€+ß:eòôZmœÚWUuêÄòÚÊú”ŽçæçÞõþ_ºôòƒ¬i*h ëÎx8®YK­Ð-škű?VÁŸ{Þ~ׯn1Â!aeãä‰å)ÃG°Ã/¼çMÓÉ`0úÃ?øÈ”U‹ßö¶×qtÍ>£TïÁþ̧8ëoàÀÝg çk®=Ôë…EÀ¶Ã…¯‘§H4~›M—ÖŠ«Å¸Ä©?¶75i^nÈ{|’YŒzÙÒJóo=Ýl‰kÒÎ@˰)©KéÖl Z»£d:ê*uæõðI¦…’Ùݯ»>Nâ~ò¡'Ÿ9>]Çk§Ñå—îzÝmW=òäÑ¿yð F¦9OLæÃú™[^uÍÖôdŸ˜üÀ—¿å‡xûšÛoàÁ9`ûáÄÈ‘ûv&–ZÚ¨6ÇØ¯žc¬µúÝKE ©}~1)eFò–Ê ý’»ûõG®½r?Ð(ðø®]=Üê°9“ŠðÅ=ðéUûiÙMÎÏ÷¦} € à€÷¼áÈuWî÷<ƒAÂjxhý®[¯¼ùºKŸzöä±@P­„_whñàE "‰¯¿îÒ¯»Ì‹ó]W:Gm9¶I½áŽknºþâ'Ÿ>±´´¹Ñ]uhï%vìÝ3‹=–j†½­ð+ØzJûŽ7ÝÜp©Vš&º*mÒÇN(uú¸‹»w¾ûÚ÷Ýzçk–Ž__]]\\¸ñ–C»÷î]^+à8M3mß³•‰[_{ûõG.‡wYi/;|še»ºve…¦}£¬® Î%*!b)€y/»êÐÒ‰Õ^8YŽ7©'atËwíšßêœÉhñ’K÷ýÓöþm§Ó¾ñ¦«¦Ÿ·¾ówíÜ9oÎÎÀUW„_‡/ÿÛ³gñškžë¿Ä€€ïƒW#ûŽs=ÝIÕÊf±¼YfØÌÝâ„ÃÌiÊ®Y¦óYƘن>k ú_¶ÿš+öûõ:N?¾ IY0 cøÔ tXL±€£ ŸÄ`ÙµWì¿úðþ©èÆÆ"»ç ÊÇ€÷Ýn|ãu_}øâŸí¾y™H\f±|j½ÜYS•¨ã”haÏga¨þBÐ:.åùŽ÷¶)•f¤ ·æ¹5‚š7òÜ$FŒÕq5²§ $”}ŒŸÂI|Ïfÿm$Pò‚ZGÎcl:ÛAΣªöX²—iýxû=ŸyG>úÑð/½Àkž¬ø Ò>aÆF› x`\D,†?ÊÂ¥Ib/ßR!b­¡ÓâÃsÊÆu„M˜ÐŠšÔÕþ1aJ,=áiŒ½hAG~V–®“âXˆ­·¬•Ø ‘“¨£4naêšÚŠÿŒËüGù‡/+³tjÍ×(¶Ûé=o½#„,¶'.ü•½ÐbÝ–ºxWº£DRÕØ~GÆUu;f¸\Oú´*0F\SLÙÇmáuYùPFs(GUÑÞQ#4ÒYʲð,C¤‡¯}'=OÇŽ ŠÈ\÷¬=‡Ò1AƒƒÆ,ªfí‰doR¢q ì,ÿK?øø°/#ôëŠM>×|”Ä<¦@tˆ¶XGSJÙË™§¥†þΈ¼ð=ò.u  ‹ª¤ª?*TôE7äïÁ'L§Ó•.ì'J(^¢½§k·€¦9Y}r”§¶UØa@Q˜K(­c?;`Ùô‹'N_ž.H¾éîÛ®9s•/ `ûà•«‘§ÐŠ_¼»•ÆåòFµÚ/° ˜)˜bÏwõHñqÁœlfýH‚Ô útΑQàÊ&ÄáóÒÚd Ö¢ç_ÆÉÅÂùÂeVÉrjÏÜ@|%²k¨²²Ø6Ta¿Q,Òct¢ÓIxgä6œfRNÄMµÛÍÒ"§K…K0Ôl4í*FJa)"®¿II[0Â`­ò>¬³íXãiì“m,ZYrú'yl±ó•kF&ŒD+Ç ,ÎŽx…#/í$"+°¢/¤T |FJ  µÀÚöï YüÌ~ÑZÝrË5øõw~¯ýE@À6AøÓl°s.ê¶µpý“«ùòXŽÇIåd§-"ÍA¨ZÏ­´‚ç¦òV`ð¡¡Z¢9 žºnòç`‹òμ #4äX“nµøué#Ô¤|½‡3‘A¥9KV”,7,¥Ž8·ȞžÇé ‹½ÿñ7ïµäG·o÷¼j{Zç“D;±ÿ!7¢NÁÒ4jµÓŽN ÓQk¸U.p¼©ÝwÝqýW¥Ýì3³3˜4AAÔÈ\ÃÇYQ™Jˆˆz^c6!Ö'rßH+!ËÒ`ŸY'm“¢g³\Ì´°5ÈàÊØX ʩх î×X‰$"ÛûŸÝÌííï¸óÈ ‡ýëÙÙÞ‘®h·Ósý·ðqžõ¢þû<‹Žg'W²²fi»½{1^œeñf\k§$Y?L‚¿ eþÛ0mñäë³)š¸rŠfzœî¨–¤‘̲‰<àRaíyw] ü ƒA±…6Ó°…±Í¬±Ñ€ñ5²¢ÚÂi±IÝdRO¥>ÙÙº&üÝ XJ‡ijeaÃjcsêµÝé)×ÖE ˆ^— Çós1ÝgŸ[E&<[˜Nà øÿÛûh;®ëºÛ¦¼ú+ðÑ  E‘¢HФz¨bY¢dɶâ(¶g%˱³R;Yò²Ó#kʼn‹r‰mQ–-«KT£H±ˆ;E€½ Ú¯¯L¹-çÜ;óðMI Ày·@èýWæÍ›‡¿gϹçìm#Á K `g ^Â4ËC ŽÈXiµn$I3…=¡ÒÈ|–÷1¸d²]&×­FÔmã©g0” §Û1êlàèÃsÃ鉿ó¦’V:‚Fþ;*Ø8“6R¾÷©lØÏZ+X²j˜…Ìö¨tknÄ-‘ÇŒ@‚Â/S·ôGLm<„íoU™øT¯¬uE‘£U8©+= ›Š\ë® 68ƒÖV(–.¬¯Zc¹6"<Â}0®Á\c²ñEd_aÕ<·ÖU‹´ nÅw÷nÖ‘r#bŒ%J[`gûš•¥u…¹f¬E© o`J\3'| FJµ:‰3T†=ÁHØwwb€Çq°”ª“¤IÄËBE‰Ÿ8¡¤ž·sÙ¸G ÌKiâˆçn`ņ·€7#? „WO`Ö®}ýÙÙÅ¢Hó¢±y&N27Àñ³H$uú؈‡sÃw5âº%Íu'TC%ÖT…câzæ8ŽÞᓯªÒž@©£Kß,ቕº™‹B‘§¾¹”•òõWöÊÓ®óÖð%lR.ª:2©÷ÐIõª·Ú·ßtàï& ‚÷‡…)Ñ Ù Ah]iáD’¦b8,}ºbUæ4˜évdžƒ<+Jê½ÑÄÔø Ål(ÆÌ9R3œAÏ™ëêÀcÏ„›R,”ks¼PÓØƒa6’^ÌŒü„8Ù/=½ûØ“ƒƒG ©ÑÙbÃéϙϑ ­ÍŽ]õ@¸‘ko[ÁF]ŽRëþªÅÂs®õåæz=кuÄêYÕM"ûÿ‚mÄd¬Ïof®ÑØo”º­£x¿`Hü9ÀÕ»}0t»‘:[ým\w©íÝ\ÕwÞhv^ö0¶Ž&ð~Z§q”ñÑùòð¡å ˽(6òBq ¤<½¾ÄAtC#|„9j†G3f©7h¤1ÅÉC²ÐWYa;¢_¨¼´iÇ\E¨ŸÊ’ˆ • ºÐ“Ù`x_YÀ‹§Ÿ¶êÇßÈ A`ä Îéx‹o^Ó Vï=Ø 7¥îN§d>CeJ]¯w\ìkÚ5 ûú€¯øU¾‘µu/š+JÇÂXÛÕN´²§9}VÕ Ÿ%]c%äïÆBÕºØ8ÁÎ|pÔ1jæ´Ú kMs' ÿ2× /-'qUÈ. Y–%o¤#ƸqÝx¦ïU cûðu®™ûäLGèVQ©; ¶Ënϙ𖞘ä|ަÜ7äYTÐ@ðF)c[²`´Ä˜ÚSýÅœRF~&LEÆ6›fÍû üÖN°„»A»ZábqÖu\Ä‘sup¼‰åZOCk7o×I«yãíR[1»ðf“nÐÙ¯øéÚÈ·ˆ·‚^NcWª®9ËÖäÎØ1o9ëGH8¶âÙÑÀž­Çû”3<‚݃·“%Ò¥›Ô€±¿˜QaŒeî±J.8¶¦Yç\ᙹîq†-&1w½z¶öÃC³il¡sîEB×Áì?/ºùãƒ%­A¾mb8¦ørtz$¬é¼ÈùG`ÕxⶆKCËÄ8oÄ/ÙLKCæÖÍ4PO‚q‚Äê¦Ô*á<§¾GíØ}˜cLFª ²¶•Üksb[uMÀFà%yÏl%d²‰~=½ eª§uãÎ 8hªÓ€ï;FYm«¶e.ŽQ¶ël#EÂT§M\Š2ÔÄZgy¹f•‘¦ƒ¦I"ŠcÚˆÄÔT ÄšF,—è¡lÑ,)LXL”*7¬í6š § ÝnâÒe1HгbAqÊ„m^ߪ„Ò„w˜ré&Ô, ,<¥Ó䱨v5B¥oæ$ìèš©ôTç§ /꙽g‰©±xËÚ´—V•s‹æ‘ý (xUvDŽò´o+&®¡a'2gÕPŠDJýŠœ¯Bø.wdUúÔ¯z9Í+F+zõ ÅÆÇGaÇç~D®.7׫‚þµ¶ÖÎ~¢Ñ¿cÊì|6LY”b'°¦Tªßë=rtavA+Åy[‹­ðb´56FÃÜ~§ý‹Ò8¼Wp®­‘a³ÌŸ*:­H•%ZQæÚB0+ HÛ%RÞÆhŽ‘ZÆÿœ—J5’=Fð…ÀÈÏ «'Ó «ÛFå³GææPã?¦;øo.vÊ$娔Ý5¾Ó´*;`A¸N亀€Ã&²bp_årä> Ú{(x¡‘È‘®Ý‚ך·î© ¦²Ë öX“pu>°U;‡Rdqa)ϳ$ÒË,@ÁE‘+%¤ÓisW¥v.@ŒQŽœXa ‡e‡jLÐÙS˜Þ ›]"¸2Ǽés#Ø+/dr\ÌÍp±Z·Ä)ìefØuáNÆû ÁÊõrÒ6âð2àEPµx¶Ø0òd÷áá#óQ4шâIA¦d>¯XÒ³0ñÁ"g: WÆégíZ2Ü܇àÕJ ­GŒ÷Z¯‰ÕÔ"W+« ˆq¥óÊ—S_‘@Zd®×ÂÏàyáì'°}S¥ÇN¸ÕÒœ!y†“BàR"ì@«™XÕŽãt||¼T¤˜]”¦šú6Ø2 4ªg‘ÑnÀÚÉ_Ê0ÊÚØÁ0'ØCÝUF¹^ŒO5®åxª›–Y)]ù«ÏÞ¼~ýÌùçn…Å‚¢×3>¥¶ ÎX)sfÊBœxFÖÚ\{ÓC_þÖ8±½ë-/{ÿ».8Õÿ”NòB~ì²oïÿûþÎõkÆü <ß’äÙ‚3ºe]{ºi©²~fJWðí$U 5 ÑJ,#|ÂV…c¯[ã¨먚ÏL5¾Aë„l²,¬UFrØlf]£!•«'q™Ï>ÍÚKf6z_RyÔYrÌÃ4d|¢=>ÞÆê­»³Ó““ññ±8Þ×¾I®VíHœZa\)–‘£­k“@±‹mÚ&qÇ _'ý¯[؈ÓNÊççûŠ0סL€›­ÿÎ(Yaw‰’‘`ŸŒÂZJ_ßpä?—îæ›ï|ì¹~q@Ç¿öÿf©—ŸêA§Réo^sßÜÂàTïHÀ³BÐÈÏ„mÙÐégja®ÿ¤àͨÑmrЮiŒkn„T>m£‰ ®¬ÁöKhgAiGÞl¤Já³8]m]Zkíy\Me¸BcQT3·­Úé܈#b„Zidr¬j Ï|lÏáÛïÚõÐ#¶nYýºWqæ¶µ«¦[.­ú—cØÏ»«™³{î{⊫î|ÙÙ[V¯ÛyÏcï}×…/ݶE­²ñ×ß™_ìÿÂϾ%ËŠk¿{÷ôTó½ï¼ØpœéX¯ºvç£=Å#þ¶·^ðæ×l“E™+³ã¡ýß¹n'ºsꎻ¹øužQH,]äòÿ}í¶÷ïe”žÎÆŸy÷…¥’i‚ÿ{ƒüÓ_¼õÞ÷¿ê‚-眵þö»ÿé‡ß§ ã}âªÕÓm[0ä—½èG¸Îß÷ðË>yÝC»Â)!q_êU±Ü°µ›î| 621Öüìw̬êþÒϾ֧j¦¾âª»¯¾[.yãÙï}ûyœ38|òs7¿ú§Ãó‹RýÌO]ðïÜ;?óS¯eqý@ÀÖþö«w|÷ÖGà#Œ¶÷û ¾î¢­ðÖ×lèCï»øÂsO½Äïˆú ^¶ñÃxu§…«û.üÞeWNO´_}áé ù7¬›ø•½^î_µ{ïÑË.¿^)óö7 ÿ»Ÿ4‰~㟿ãÆÛwõúù'>uýãOý¥Ÿ{íË^²Î¿d©ŸßxÛ£´ÿŠoß}÷ýOþü¥%±Æ¹î¦‡[Ídróñ€Ç7®›|æ/ ®ÙwÜ·ï©C‹RêÓ6LÁ=›ÖM áÆÝ÷ïûìWï¼ÿ‘×ßüðõÁ#K/Ùºfµ[€óÁwoyäÌ­33ÓÈ•ð-}æº}æ¿ðõïwä¥üÒ7îº}çž÷ïûÒ7w óò ¯<ãö(㎻÷œ±·ì³~í„ß¿ÁÇž8rèhoq)»ñÖG/yÓ9 þc"_ýöN؇4ŦÈ]îŠ _Žd ¬úõ«ïùü׿Wbð6¹ùŽÇ€¹~ú’— ÁYúW¿óYàÄV3†û?{Ågm]sžû¤ðä¿úü­pôö?µoúé/ÜòŽ7Ÿ3ÞmÂC{öýôo;2ׇSË—¿¹cnqà?‹?87ݱ a®þì¯o<û̵[ÝìØÇ?y]·.ö2xáç¿ö½N;}Û0Ïå?þÏ/Ï/RA•Ã>À zæ/hù¡¾þ–G¦'ÛË|º[¾÷8|´¹ùA£ŸãN$wìÜó›ÿýKpÉ5ÌÊAVÀé¡ÝÂèþ¨÷úIAÐÈÏ À_«&âù©ôÀ‘¬ßÏgbm—Ê Ý⋳šÔÓØˆŒü(k“ûQ±á‘¥Àvôº<„T‹~Ä=d&àùnb×ÁÆ¢j2Å7xŒ|3ˆ÷¨sñ8©Õé4à×~ÇÝ{_ºm­ï¾ð{‚ÝÒè½iµVœñ‹.8ã§Þ~ñç¾|ã¿ÿ—Üvúšßþ¯ŸÚ~ۃ眹¦)â¿ÿ×Þ¾c×ê鱟ß»fVi¼(0 w{ƒb÷Þÿñë—vÇZq]sí-ŸþüMÿæW/å1{ÓÎyë΋òLÿ‡ÿúßÑìÓF¶ßþçU'œg>÷µ;/¼ðÌÍ3]{Á/ó_ýß_ߨíG;tøèR»™À'¥ö­ëî{ýÅÛ~ñg_ó,¿¬Më'?öÛüÔçoÙ~Ç®?ý½¸ü!Š í}ô#8cËê‘ßp ü’ÿ·ßz?ˆSøúù?ßx×[ν ‚ú+Wîüøÿ…?ù«®úîsÙ?ùägo†ÓÆ3ì€ßì0üŒó7_¾ýõ¯ÜÙo>øúwï™oý³ßü4pÓ{.y9|êÏíNá~ Œ1 ×Ÿ}ÏE ÍA‚à}ðѧ~çß¼gÃÚ , A ?ÂW^wßôTûSøAäU™nÙ4½|OÞ÷Î .}ÇyGçúïÿÇ—4öw a—ž:¼ú7°öòƒ³~fü#ÿêÝøã¿üK8«ÁÁ°„ó{ùÀ^u|„í·ïúÄå×Ã.ÁŽÝpë#·~ïqï~ î>g/ØÎ<8Ë5|Òåç÷ÿôê_ûå7Ã{wUç~ì_üíM¿øÁWÿòÏ¿ööêÓ_¸ÍïÀÉùõ? uä猱ŸC_YÊCs¥4¤R7-\gG­Ä߈gÆîZY¼â'ø«WY[ d22¦¨9ÚÛÞ[gdá¤5_{*yÒû;¸ï‹WÜñŸ?úÅÝOà¯Þ<—'èMF_;ÅiÐAÖ õùap2³z˜ˆsë–5Oì=Gœ1ψcñ®K.šžî:qUfÂü^-. à9X¶ùÖS{÷σŠÇÄkgM¯•AfÜ1Ì3TØÍúƒ|¬ÛðŠ¾ÕˆÏܺ¦,°äjœ¯UáWˆìͯ}Éóç>æg¸ˆ,‡ðKžrDg ÍúCŒØö?ëÅ‘ë4ÖÎŒuZ)ÜxæíÃÖ@D.·7o˜zò©ùa&GO€‡¦&ÚðÖ°@IpœDç—†^à ™Ï}éú¬Ž'˜1˜â¡#èèÈ|ï޽眹Î×àïKÞxö¶ÍÇ‚_á»Øºy•Ë펢¸a^V_»ý!­ œàǧí<øRá샿ޏ|ñï»mó*8—T[;Úë´“Ñ2À¹/Ý ~TÌ÷jàñåç•lyã«Ïô_â…ïb÷¾£œ»ÉÿØn'qòBÓ”/´Ïsr0ÙM§'doLG–r;Õ¤‰[+cuùØ·9xêÓ#‹NŠz¹*×õbÁªLUüÏÕ¡YíIojR®C<£Ñ;3’Ôõ-Z;|z¾óÞ'.yËËë_¿·ÕŠwï>ôäþ9oñì»8ü»3‹“rYdmqe Ûª 0ìS‡æ›ðª'½þâ3Ae[ih-ÃÑQÈyØSŽº}ÍÌäx·õä¹3¶ÎhÙ¿uÇÞ—žuZ»™:7; Ÿ"޹+×`o²2jÕTã§/9oÓ†é‹^¾y|¼!(=ºû4'KõÈã‡Î;uhd¡ï{çùIÍ#œX;ppáËWî¸ø¼ÍðK{b¿YŠSã­ënzèÝo;.2xä)ŠÑñ†MÁÖVOuvÞ·÷õ¯:£,Õ5Û:ÿœ­æ±º3\¸Àå#à#¿÷í$¾÷íçmÙ8ýÊó·LŒ7ŸåÙ„$\æÿÂû_ üçÈk¶?ø’­kÎ=ký3¼´öìüàïÃgŸ±´óÇ>ñí…¥ì™ßŽÒ°åRªïÞúèáÙžèçnþÁŸ¾ä*Hïïí÷î}â[×Þ÷«¿ø&ØÃv¨áÛ\~p¾pµðš:ÿl ÞµûÈâÒ Í%Ô‘pŠ.J;ßË@€rl7jœ´*8°ºjá,+ˆõI{U×pM©Ü%wàd¶Ëôóôí¹Ø;ÌÁ3ÓˆÄn6dXV^ ¤N ¡u1šVŒYÍ´šÉ§þö†í·>|ý:¼xèÈâ]÷ìÙºefㆪüê-&{ªßÏ]Ê(aúðcOÎÍõ^øì—nêýùK_½vMg0,þàÏ®ºëžÝûÌÞq×£wܵëô-3ívKpÞŒEQÊ?¹üª[nàÊë<:7üGÿà’ɉv) miˆ3ÐÈW^³sýšIø½ÅÈì̪±?øÓ«/ûËkoºýÑ«¿{ÿ]÷í{åù›Æ;•úûèÇ¿ýÍkñ·/“{K½üO?}Ãm;vü“×l¼ôçûçÿ0™íýï?ûΗ¿µã¡]w>°ïkWß37?ðuäË?wóg¿z磻Ãå9Ü4á«Ò@ý ?úñ+¿~õ½Ÿú­wìÜ Wî§m˜ºùÎÇà"¶”, —ÛþÆÞsï¹ä¼¶°µ5«º¿ûû_ûÆÕ÷ÀÖv=qä·~ý«¦:þÑ»xØ Î1ÿçϾ_å¯ý£·øÏÌt÷ýñUðç×ÜxÛ£W^?<íl§÷\øÏ¿ÿõ»îÝ;ÌÊë'ÿÇ~Ëß~ÍE[Abï¼ïþùµ×ßüðe—_¿ïÀÜß}a»•ä…üè] BÎa µ?qùõþ6pßæÓ7ÜòÈ埻^róK©·ß¾ >ŸÑÁ9ãôxþè6èY88p®»ùáÏ]q'\qû¿ûï ;<1Ö|äñÃùè—¿råÎn{ôÛ×?à…ÿèPÀ÷¿þøê·¾î,xßÑÁY~¨ïº÷‰ûÏ.ñgt´Ÿö­Á6Ï<}擟»ùkWÝóÅoÞÕä{÷Ïù8Õ”pÂë‡f‹ÍQ&6l˜Ú<Ãb^õÿÖ9FŽëé OÍ^DuÍ@{{ 7¼gle)E•¸ö=J¡ Ï ™h‘É””šÌ±”\ÍFûê³wïU÷…gj*bw=~ðÞû÷ž¶iúÂóO»ëî'vï9üªWlÝrÚjRÜàž'ÃaAg,†M\ñ­ÛvÜûø¯þÊ»ïØùð眶nºsÖ¶ñóÙg¾r[?£îÓ(ÁØÅž9>ÖáÛ×ã;ï~ñÖÓ×­Ÿ™‚ëÜ~Ög€7ï{hÿ÷_àþ/¿q)ˆÇ·¾þ¬Më-TÓÁ' xÕ/ÛôÒ3ÖÀÁ;áÔ91Þzõ+¶|çÆýíw½õe P´Þòˆ?8¯å~¥KiŸ_DÛ^zë]»ýíw¾åeÀ¡p|¶ßþè`X¾ñUg»ù;9:8pXàŽnûCçkWÝ}ÖkAÿÖûâ§ÿèŸlÞ8µü‹#®¼3Ú NxáÛßtöÓ¾µï?ÔËöÓ¾µÑ¦€÷ÍÏÚ¶æ_|ä3òÑÃÁIýå>ù81ÈÌ=..ͪéöæµb¢U]Øæ5󊚈G«nšTN@ÒñµvþAÖÙcRgoo)ñ86mª éþ_8Œœ~Iú…k¡‹œ{œq–ž®8ÂjGPe2rþ¬œÛF…SM Û_X4‡Ì+eq`ƒ'wß¿ç²?ÿúì|ï—>ô÷>ðþ×e½A*è¶-Ýý{‡ç2Â@¿HØ5Ú÷•p ¦ÖäÝv2=5þÄ%ø$I$¤* £Ûoypû-D‚ë úÙúÍŸ{ŹëqüÏXƒ½Û,—*¤?…4V·NõWzR4ô‘~øî7~õíϼ¶¢tñ¥oíøöõ÷Ã5ÊÜÂðC—^üá¼ê$Ç ÜyÏñ™íE©öì›}ókÎüÍ_gü N|á|’“Œ8¢­?ZzÒŠÁ ©Œ=½«‘ñu;R<#ƒ!Ù`^*­4¥ØL‡Õ‡ª›ÙZ‘ÎiÑÏ';ñÄXrx¾—xš›47G“7PÙBpš$tr¬9·8è t·Û1J8ë‚ç‚4bÔ±ñö­Ìe»)œ1Ãñ¼+ÎêžhéßÛÅ©Jx#5ì§R4Nh‰ÁQ îE,ØÑùl²?ë#ð¢@`äãG)ᜦ‰ËvD«\Q¸Î!­*·#Nôðí¤–Æ®i ©™/++øö ‘´ÈÊiV`9Á+u¬t]vnpžmí¨ŽÌªˆwLö9~ð|‰äHâDÄIª8œN,ŒÀgÑJbsÅ‘D±*d«û D‘¥ÖäÙpÃÚé2,õ†­îÄp0( 7ˆaz–¹dŒÎãÌG W‹ëXÓp]"@Ъ?,;­$>^¿ˆ€€*#? ©³ÂD‚¶›è0©\a!r]À®¹‚æn@.ª-/FhuOı„¶¸G—‘}•ÃÕ†]#sD¢ˆÆiF¤•ZP±Ž ÅãÈF0yY`þS»aEºn¤bóÆUK s‹ƒ¤ÝÍ‹"Ï>™qȾ|¬‹A¨F»b±‘žº‘ˆ¼´ £mGs‹jÍT¨ <¡Ž|œÐÚr“&ü´u©ŸøÈ]>ˆŠSÎÝ‚:Þ4N;ûõ9ƒyÌtùhµYvVôU `d à8%“hWI2…C"h½ìÝ|c†ŸþðÚÛ'øÙQ¶­ì2|.!º.c]‡’ø¢ò/·ÞÜÞº)BmÂ4VÃá ìY¶8²¸˜VO­šhíÝw¸´N+4¡“ÀÈ UíRŸÈÒ—º\³j‚™Õt<ªW‘Ëš1ª^¿ìfH3!ciån‘a_DeLá+Ê­Ñù,O¾Þà· «>BªfäÊþMTOóš»Û±ÀÙ$ý[†ëÁiëÜŽ°§8‰ne’RYÊù¥‚§,:.”ÄÞeK½àWU^ óU²LSr»Õj”¥ÆENŠýª4q$£Zá,uš„½€€ŒÀÈǃRšBš±NìK¹´hFÝL›>6*MFmgËþZq´p>Od™å0²`d¬YõÉ ÜŸñ¡|~ÑÏ 5lŒc¼Ê«Öµ»vËñÊ:™±ê$ IÝ€a«ÞdâHÙ/º¾4\.d Y˜ã½¦Ì‡Ìä­”uÿ÷JADËXÛ_*Ê'[ÐgËÅ臵 쬀“è|¬;ívY*Ñ8Žòb` UÚ¤)[\,zY¹au0 ø¡U‹ãUÐÅÝv"*Þ,§Ãœ¬ž¦@ £ª±Ï¥6µ¶#׋eËz¾ê`œU›,QÉ6blg ½³è¬7|í[&ledQÏL“ÊÃG:Q±jGšÜq: âÊÇÌ/ŹõFEd”ʤx& Õ¼,‡ÜèUS“"Ž»Dýa®¤y+µ¡Nxã_næZðØR­1*Pr”É6‰ã,Ë8§i­à¹Àâ4d&ÍÆP¯xF|çq)µ2¾N¢™ذmM ¼6À¨ÅÜjÇ”ËáÐ4[Q§-õúenX$'ÆŽd­„MS¡€€ÀÈǃ¼4T`ß× ·Ã‚*%Ñ4˜såRJ¥;¨£êÄÈìÍå9»ò±Ÿ¢¶D¹¤; »©.éÄÕj^¡pØ9Ô`—1ñNó8ðF¹¯{ªMú$'[;<@íR__®£Füƒ°ŸXAÆ’·L ðþ\ôeY”Rš4à%‹óÃ(އ…sªÀ¦8ƒ&ÌnZN,.XV¨áínT–K¶h$ ïÆÆÚ……¼ÙNZÍdn!˜Ý8Ó<Õ_Z@ÀO#?g(mµ±iŒ®•‹ÉrÛmGq‚Gè±dS{oÒeEdïú¦\W²rä‹& ™=M•-4µµq=®àÕ¦žÕ}´*YÚI™²jlšø·ãÕø¶’hEœDØî ü þmq´ÏRm|Å“ÊÛ…á”bŒ-€‘K31žtÊETö–Uµi¼(p•íqviË–²gLCDl¬K©çæ†ÍV,8ÍŠRk³ymû$G±ü„"0òs Ð`ÌÑ¥¾(ÑóW+ Ùº•7Ìsb#‘z,god*t, ) ¶0ƒ2MiEX,Ž”èxdžiHÕ‰lm­vYU2™Ð»ä:á\ù]xC ÌìˆàÛ¥1¶F —¥umÇØPQù/›÷M)•ˆDÌh>ö—úR±N7ÕJFÆ¡ý³ÏÌ'lkªÑ¼BFâ"¤šmçV¡S8Íf\*5ä"†·ÓTô‡jãêV$ÂrE@À³B`äç ¥|3:QŽ‘t9‰£ÚxÞh=ý¡—Jg$(k|B§IZ¸dNÒMK»„'ålÌ+¦¦ušx»úÚÞ¨P–8½ŒÎóÌg'¡=`ÂèÈyN"¡c¿Zœpxœ ÊÒhC¥2%jX¬_(c†Ã¡¶œÇ(â­æ­ÉÖ‘Ù%YJ wQ´}Óp6†}ìU»c‹Œ3,O[ͤÑ`ƒA¡”2š®™n- ËuSͰšðìù9C¤¿8ây©}‰‚qG•’%Ž…#_ãk¾ä˜=q-hÆ…O'i¸¹>ié8ZÖgãú…]£…®Ãô˜ m*õ±‘âzŠYoŠóøÇÒÊéÍœUݾآØÐBZ4ª—¹¸T²,ö«%"æül¹&FØ’>9ÙÉòr°4<é¯á$¡ËÈ þ¤üDt·eKÌB°4aŰȲ¢,Ùª©d®—¯j¶šáX@Às@ø…9DJÓ6\Ô½ÕXD¦> ÄÔEdã;ZµWbxòc»M:>87wT‹¨é›ø°>RYÑe&ô¬.<-1Kª2M‘*ÑæX/ë“Ã4Ò‹ºh.šÙ ‘F’!' öó×)“ÆèÉ©1xËÁâ¢%¼ÀõD4M,âØVÕ‹4æ­V{i11jrÎx§X­–úyV°±n4ÌÕÌDc¼ìž#Aò\»RWX)À54Î*ÛM_8ƦãeqJÚ¹¸•›—£û޹»³§qIÐ[{§Má–æ¼õ„o_³®MñcsÆY[¸Ó€ODÅ (œøů,%fB»¾7äbìP.U 6A½åœ*â(Iàèa–++Ì™2ÓÓãÖò¥ù>å¢4 Ð`>VÆÜRJÇÛ-¥Š……ˆ|,µm·0fzaiDÜj¦ æW§“c!a: à9#0òñ ‘™[)mY€¨¤ó¹JãxjÂ%çq×êKÐY/›ÖS¶²­HbÒŽIìÔq/Gd!p®„»=^Þq«ò±5u‹…Ï ñÔﯕ®Ì‘%2²V ØØxß Ì©¦Hœï…UŽú1éŽG4m$–ÙA¿”®¡Û(Nq Úhl\Ûw`V*“¦ ¨fæ¬+àÍ';­,HÃxÌ#.Œ-»cífLææ³Ky»Ý`ÜL¶Ò©@ÇÇ…°~´‰±jèÛºaFŒšÚ—5Š’f9¶|ÀÉ@JƒA¬3¤á© ãí¬3ŸÀ 3è»E>z¶ÛN›ic8ÀìRt«°§’¥éÎÌÌÍ/ "þd…dc«ÚÃ^ovn`8XÌŒæ ‘ÍòƒGãc(ŠN[Ýh¤á_T@Àñ#üþ'bÁr©:MÒhÐy^,.#7HÝq!}»…¦XLpä›DÕ˜56ÀY¬ZR™Ð‹¨rqƒ‡+_c×D¬ÜŠŸÏþ€ûŽ]ßvà)I=Ì0/†ŸZgÿéÝ4Æ [?ÌG]0r‰ÊTðȲA¿f œÑÖFd%lb¼Ûïeífs¡7_j2Ñj%†ÊÞb_ëÈr è>RÔàí–hÄâБþüâpõtÎ[×µY–øñù8‘&¼T¤Ý$qT*mÓ4^\Rûæ§oH YÕ†™s£—X²HX#掩—†¸ÅÎ÷ÇYhú•@o¡é;+Œ©Æó0:Ïå0I7ýœFN€уè¶ñ¸u]vØE¡ ªdüçÅÒe³¦Ì*ÆtšÄfGj²8XÂÓ…Õ%·Ip D€Vžœ?<;zToÜL—úÒZ†Qz1ÎrjâF<Ñåi=uxinnizº zÚš@Ç'‘ÝgœõÆâC³ Š’O@Å›6$ÊÕ…•AÍÓ’ 1,bh3T”¶ÈÕpÈ’„sgŸÄN#›c¦ntÔ³Áª† oÔ»GV’"'ƒLç¥*•½l´o„s©I#ãæ´ÖÜY»ˆMâf«Ù„óGoÐgV»i@fqÀDh#Û‘˜oõû‹¦H˜9²¨æ3.âˆ1c$œ¢$Ic19†›Ü½ïˆRjfÍÄT; B' ‘,ÄÜ®N¥öKkrñó’óh¬ËüÄs^¢ñE#±Ígó2¡R1m)HinAAÛùÙhØN+ŽÚM€fý+]«\Õƒì½ß(vÎÁCEa‡…b‡›£c1‚‹s×[áKÎ$-ó#ÕJ›f#i6pfd™’Ò•8°ÏÓºŒ91j˜—ÑX§qôÈÒ|_eZ¥q×û´d N¼ t<³òБÅN«!ZÓ×¶1 * à!0ò@v3cñMeQ¦†ÝÍ-Œ7 T»E¡Ëܶò¶ívß\å³YQŽH²·˜ãT´´Iq š&QÌ#Å1:†?¾î,Ñ,ß9T¸å>kjÿeK…K-E‰¬ñ¸Jˆ¥¬2·i«U÷³2ËJŽõWA&JkŨ™šŸžìY¿§z¹Q”Æ áà!Æ¢4æãcIšòáPï?0;99ÖJÅÆ™V° 8±Œü㢙 ²~ß.”Üh§¸ö••ŠqáêZ*;’~ä M{åb[5vBà<µ VíÅ]\¾‹"Ak7REL;7"Y癕'¥.K×Ua*ã!üËÀöª»,Nß¹'ƒFÍ­fÚî¤ZÛÅŬ,K7È¢ U@§­V«Ûn•E~tn‘;1Ö–Z)e0” ÑH pq‹#G{<¢cV7;ÞZ? à„"0ò @»!6Ì$–³sRTÜL4´%*ÔYÚ`$i'$oòA¦¥–”pt&J1!%-e ¬×hD ‹Ñ„“U .Ž8¹ÍŽ_ç™URãTž2þHí#SVÅ©èj"Å;d`(KÓÔ1HïÅ…Q’3“Ä*7gÇ82¢#ž$,IAõRÁ0Ï)/,0к›ÓÃf ¥ÛØbàS9”«iàì5uîùŒÁkÑ÷;8ˆ4ÞS¿nãšêÆÇ; Ï­ÑÓãÉD7baÞ# àT#0òIƒ•Ê™/æ{r~I2fµ1͘u[ siàQ °³†p´f”¡?2ÇÅ>dam² ¨€±ËQÃße)ó"£nfÕµÆdw œ"عìà˜Kç¤Iƒ>تñtõdB¬F>Ù0¦¢æ…^1;ŸbšiÜHãV ‡¦ó\»H¬7ÀŸH`XFùá`4ð²¢®| I)ËBEé--.áQøÛÅŽ å±ÁlÓ$)Ýj5Az f'»Q§óàG°òù”Áù“aìœÏ-½òm5£F­ ·4‡&öuaƒø(Uÿ'¶ º£ë¦q©ªF!‰£·¶¸%ö:cj)¥–kFãÝ8ÔˆV8#¯ Í¶Kµ°T²}ˆ@™u¥aZ}S.÷ɺDS¼ß8à '¨ñÿ(ç,â´‘°±N B8Ìb"øÉ@`ä çRd±²ì¨Wâ¢zn¢=¦ÅÙ<΀|‘pǹ°.ð@`䀀€€•‚`°R9 `¥ 0r@@@ÀJA`䀀€€•‚ÀÈ+‘V #¬FX)Œ°R9 `¥ 0r@@@ÀJA`䀀€€•‚ÀÈ+‘V #¬FX)Œ°R9 `¥ 0r@@@ÀJA`䀀€€•‚ÀÈ+‘V #¬FX)Œ°R9 `¥ 0r@@@ÀJA`䀀€€•‚ÀÈ+‘V #¬FX)Œ°Rðÿãz߉Âʼn=IEND®B`‚openchange-2.0/apidocs/html/mapiproxy/mapiproxy_emsmdb_graph.png000066400000000000000000001170411223057412600253540ustar00rootroot00000000000000‰PNG  IHDRÏ6ù"òsBIT|dˆ pHYs × ×B(›xtEXtSoftwarewww.inkscape.org›î< IDATxœìw˜UõÇ?ß¡w²PzPŠ`AAP ÒDAP°ó£ XD@PD@ª(]:H—zMBhi$”ÐB(9¿?Ι¼³³ï»»Iv“Ýä|žgž÷{ïܹ3o¹gN»23$ílô.6³Oh'’––Þ0³—Kå‹[›Ùóíí¯•ól œ §ð< ¨¥ÔÿõÔÔò»E}1O~õ/Åù¬t Åïè‘øÁM[¶óÝÇÿ6öˆýJm.‹²Óq¿…âw[);Qšß¢là7ÀyqO‡?ÞÝê ä3qq½KþH©~º€ûmú ›R³ß÷ú}£l8.¾ûŸ+})¦OàÔ„ÂÞr3!9µqc¥öçó×RùàRÿ+DÙî±?6ö‹ýÃb¿Wéƒß²Ô×w€“ãæîH9Çx¹uÝš€pSìÿ0ö'ÇïaPì¿_:f]|âÿðßÒ÷wñ¨/„b¿ÐšMÅ'åFÂÇÀ¢QVü¡ÞûÅÛ¥q,Q:÷ÚQ¶[ì/µû"þ§Y\×Ê¥ºŸGùIñûþÿ#î1§?›Üfûo¡‘Âþ¥6Åsñ}Ú½TW<|~¯TÖ#^‹ïóˆø]-ûï½£p¡w_|>+þã—úB@øuìûçÆþ¿cÿìØ_¦t _¤ùd½'ð9jðKÛqŠk¸ÚüYÌ»•Ú^ô‰›ŠsÄBë0šÖaIj½†Ïïôž>EK>…?µ7 \X(¼!W­sL[QÂÿ¨ÀÕüE]1èryÙ?¡U1 ¿ Ï†‘´po´; øI©ú¥Ò9ÆëÊñúB嵨_¡4þ¢3;ßÌÂmDë…÷l’´ÅSñúz¼Ž4÷4.¢`æ´4!s"þ»|²ÔÇ•>ÇÄëøxí]§M™wñ§‡ò1‹VÚÜQz_ö [9n‘RÝ(\ðšPª;wžú°þç}žÕñ²Næ†âß÷b;»Tw!@âÿÝ—HZ’Úwõ΢qïÑ]Qöfì/ô §€gpÀWKÇ,^é£è¿ècéxí¯#âÜðä‚¥÷ÿÄKÄþ  ©·¤ ÃqÝföAT¿R97¸ÓbQ÷*>¯–Ûõã,"Íl’™õÅç¶Ë¿ôÀÿhö—´zi@M¸â÷Qô>9¯&é+Q^u¯HÚFR½ ~˜ˆÿQýFÒf¸´nS1j7ÿI›GÆþk¾1Ø ®nä)©?þ‡º&®Vz!®÷I‹Å¾,š.i;àÛ±aåuICpµ.øÓÔ«’6–tp¼nDÍIj_¢$ijHq£ r7üOó3û6î˜Ôˆo†ÃcáŒô¢™½ÓJûE€í%-leOVÚL)½«yöŒsíûOƒ;%âOV ÷㧘ÙëQ¿5sɹ­Œ1™û13û ´•¿Å'¸7ñ ÷Ø8`5ázÛ¢±¤^•¾‹ï¯UÊ¿Ž;ë?bfýqÿ†Ô§Q#ãõ ጻÍ…‹Ñ¥ã>ϡŶu´(îûð-ÜOi3{·Ôä¡x].…ûP x0æ·âácÝxÝ ¨s,Ytff¯àÀÚ…Jâpüæþ W%¾† *©-.§¹}}4ÍM âÚˆ¢ÍYQ^uRÜ––NV÷aÀŠÔì˜Åö ¶A%ÌWÕLÃ7«£–Ù¨ÒWy[+Ú ž¨Ô]FsÕÓß*õ£KǵNß¿šÓj»ÜºöFÍÄpBì*úb`ñŠýUpaâcÜité;7 Ú&†Whî¼Ô721¼›ŠcÞÖŒ6…‰á°Êø¿CMûW„O¶Šú¨©;{Q³ý~§ÔÇú¥1Þ1§?“ÜæØo¡01LõÃÅöߨß:êFM¸À4Â_÷º/Ž¿Ÿ³þuÍÂñ(´â;·þi¸íOøT|¯×‹c C1æñëc=jNÁããwTü „3bðGà/¸Öâw îIáWaø¼<>¶²¹¿˜›'Q›ƒ‡S3ìRº/Äû€OGýi¸cåx¸dÊnO3;AÒ¿p§„žÀ1f6Šf¶s¨ËઑÕðÐÀ§¢þ]`P„.GMåø5üá¥hw“¤Uq„%ãC~Àb¤fö¢¤õñ?­¸Ä½fV¨( SÁÛÑþ"IÃð§ŸBíRf$M££—B[ñi"Q’™=Rºv~ 鯸ö. ’Ü ¸T¶:®²šˆÛ„Æ“$­s>)š€§ñ'é"YÉ[Ô4V˜Ù(Iã¶ØpGÝB W˜ ¾Žû­€ÿÉ^åOFŸ/TÚ¿ÇìƒÿfÏ5³aQ÷ü÷roù3;_Ò“ÀÎøïþ%à3aïãÎO6³$}ZJR3›ffKŠÿþÎiã~%s//á*ô*ÃB°/î û 3#iO\›½¯¤;ÌìIãqgÙñ§÷BõBôý\ìO+ë#3&éûøwÿ3øÄü=üÁ·øŸ¿7'¿³qÑÇ“föDh²ýŸG1€OÞàæíáøï¥ˆè{ ¸¦Á=y¹Á=y­ô~Üx\»øàçV3\šï+áÑÇ›Y¡)¸מ¬? ?Œ;yþ¹ðÎL’d.AÒ{¸ ºŠ™U…€zí7Ç”Qf63¾E3M˜"7ߤÆëX;š$Ý I‡á“ý|À~¸Vc<0ÐÜŸ¯[ѳí&I’$Æ>¸‰ó9`¿’nÎqÔ|÷À5{wGájñI’$³0Côµù㓤;!_Ï`=\Õÿ2ð”™}ÜúQ]—’$I’$iA£0Ž$I’$IæaR@H’$I’¤) $I’$IÒ‚’$I’$iA I’$I’´ „$I’$IZB’$I’$-貂¤ë%1§Ç‘$I’$ó"]9ÕòøBI’$I’Ìfº¬!I’Ù‡¤…%}FÒÂsz,I27#i=IÏéq´‡’$_êýþxM’¤óXØmN¢=¤€$I’$³¤9=¶H!I’$I’¤€$I’$³b å.¯AèÊQ ³ I€c€Wc¼f¹v’$IÒñty!5ΚÀuïÿž¶kë@I};whI’$É\D·yèL ‚ÓVÅ5Ã?HºJR~©‘H’$Iº) 8MÀç%= é I–´WQ)é4`$p,ðoIçFÕ`¬™½mfO™ÙÀ§¨™*ÚDR/I¿’ô:ð"0VÒm’6é¸ËK’$IºÝFƒ&gpp1.,4ŸHÚø.°’™²åKÇ)wdfïI:ü5Úï ìÌ\œbfÓâ?_¶4³g$õvN¶è”«M’$I’6HÁi.7³GG+u_þUföJé¸z¦‰w€…$ NŽFú‡HZ ø °®™=}O.•tc¹Ã0Y|\,’$I’îG·Ñ ¤‰ÁiÍa`R+Ç©S¾"0.Þÿ8ÇÌÎ6³Û€C©™>¼`fOU;0³w$ –ô ð&0FÒEIËIúŠ¤Þ’Ö‘´`k™$I’tº¼€0ÏkB¥¿$p”¤oâþà!3{ w<ܲÁáMÀã•þúâᑎ¢u€ß”š<,$i~<'÷è6†x)pðE`uàJIÏ™ÙåÀ¦ÀIÀëÀ`eI?6³«c,?Žë[¸ I{Hú¡¤Q7è-iYIËÄÄy9ð>pN´yŸœ 6&šÙÜѯÑÀ$­ ¬gfï˜ÙCÀ-À×£I° °½™mŒk, vÃ}+vÖ†KZ¹Ôÿ§%]*éNI'JZ¤ÎTΫýÝô*5Ûø@ÒIHºFÒé’5º¶$I’yœÔ Ì*’v¾¼\Ù^ƘÙdzÒØô§¢ (ÕO”ôi`gà3ÀÛÀ䨊OÖûÅþàZ`?3{7Ê®ö‘t Ð÷9¸4ênN”´¢™½Xçô+àQãJec5â}àßf61öŸÆŠ‚&àl3;@ÒÒ¸ÖáIë·â¾?Œñlm·Ns½%é3ûi´Ÿ|ZÒ+xäÅ`ð¥8ç€Ø>¨sMI’$ó2ÝFƒÐå\%'>Y~Ø5Þ/L“4––ÂC!@¼lfoÍêÌl2ž]±Zþív~8þÿLŒùŠ(ÃÌFFå-’~‚ ‹ßÄ5€’ú™Ù{ÑßWÿÄû&à‰Ò¹Æó2+…-\Pª¬ïÂ#*þafS$=L–´:ðFœã÷ÀY¸@°¤ùpÍÁdà[¸fd·Ç+!ÈŒÃÍÄ8–z—<“$Iæaº“b—¯…_8ä­ Œ×bûL¼zJz‡ÂCl³¬…hcüïß–Ô ø¤…`fJz8Øxø/0ÞÌž—ô0p¡¤pmÅJÀyqxPÎÚØ×0,…‡U–(—ž÷ãÂÄýá71ÿâ.Šk&'•Æ{€¤ÇµÌì{E§±–E?IÛÄùƘٛQÝ xRÒæ!- œmfÃÛu“$Iæ>R@è,B…?,¶Hê?A× ÊZˆO$£±ÑQZˆZ©»¸°Aõ6À¯puÿxà föRÔUÃ,›¨ MÀ¸Â‘°Nýà 3;γ*°wÔŸ,ˆéÿ$IW&5]™ù{&¶„¢?-ˆMqÛû@\%_ÖBT…‡ÓBÔÿ³•ýkKïon¯r5Ëix2§k%MÆMwâù?#%ý8˜†'izŸ¤«Oð-FU–ÉN–Çó@4¢)Ú}7L3HЇgûÇǘv‘´ ð.½¯K{wK: øŸ™ý3Ž|ÚÌ®(ŸTRö& Š,š_6³>)I’$í 5s1i¼ÛŒj!6‹×&šk!ê t²/D\Ï¿Kï Ÿh膩ጉ™½!›Gâãá“/ã÷á/’–Šºûð|‹IjÂ}'¦ aº¸_Ëb,ŠùÛCln, ýñÓç$…k.ÞÖöGÿ5³=£ýhÜ™´VÖÀMÅuþ{àá­‹Jz8ÐÌnº>À`\YÆ>…G­´* DôÍ^föRÙbq#:û³N’¤Ë“„¹YÐBl†G+¬@M Ñ("£Ó´q ¯Õ){h±üµ™]#én`[<Œ±î(ù3àD`Iùò×Âד¸w€Ü× <,é‚’E™&\€*XÏSqA¼ï,NÍ1ssàç¥öÏàÒyaFi*½‡’‰EÒFx„ƶÀ½ñúIÍì àz\Sò"p´¤ópÌQÀÂ’ž5³+«BãÉÀö¥²}€¿áQ Jbf÷Ö¹I’Ìݤ!qfA 1–Zˆ·iE€`6h!`º_Ä¿KECJ×Ò×(|Bm2¿"Æ5ZÒïñ'ÿÂ~åIóe\¸˜VÖ~”è Ì_Ú_˜ëY€;]–ý%Êû{áÑ1‹ëᦊ-%=…k/Lñ}ˆ†ýqgΥ댉¸¾[ÌlX»p:°£™Ý(é—ÀExJîv¦Ÿài»G”ÊkšÙÍ N’¤+‘aŽIûi‡b>|r+ 3ª…(òBLnq‚޽–iîpQ¥þÄVx¬Ôv²¤C€ËŸ`(>9?hfCñO_’T$žÚ¯rîpÿ‰‚ñR€AøŸ>û㉬ ÷g •t žŒªX£/pŸ™CcvÆÃV öF™Y±×™Ào%­…çùØ ¸¤4Ø¿vǯ#JåogKZ9ÍIÒ­H!™u¦?#Zˆrhg{µ…oÄØ95Ñ+eGÅ!x¦Æ ÔÌ¿ÂÕþCqé5šk žv”ô7\Ý¿ µØãÌìàzc‘´>Ñ ,éó!\5·5ºy*ë•€»KÅ›à)² Š ™ÙÔ8ךÀA’–À3\žjfçEŸ+á‚àÏðŒ—Ó3{7’\mƒ›E’$éÚ¤‰!™½Ì ¢*@´G 1ݹ²³µU̬n*ìH$µ*nìIóu/ÄóGü ¸ŒHÏu'wH:÷EøXÕÌî’´¤™MŠc.“ôðYÜ\²,Íýª¬Šg•,kPÓ\€ÿA|Œ›OÀý(†Iº,Æ{G!¿ÎñüMÒb¥DTÿ¾A IÒH BÒ5˜-D5±T{´ÕȌ٦…0_Aò¾³å·Íì`‹b?¢"^º§$}×܈›"®ÇWÎÀ1þë*9$~‡j~ɧn¶¦¹€0w¶L’¤û„dî!´¯ÄV7D/ž¼ëå…Ø×Nô§¥¢^nˆ13šRÙÌ~<ãWU·ŸOð¤QwÖ©»XÒ%ÀʸC•gñE¯Ê+tž\)é|"ÿî˜X]ÿÆ‹¯gIºÁÌÞ—/œµ+n6z ¾¦â¾ešð¶’$éúdC2obfo3óZˆ=âý"Ô´KÍv_ˆ‚xÂÕ¨NÒE¸Så)Qv£¤½ïâû™Y‘ËáïxFËíÍìCIâNˆ¿Âs.\bfßé!¤ᑯ¡Èñ9<u’$]Ÿ41$I=fQ ±E¼–µ fB ÑAœ ìR.0³K€Kê´ý09|)À×Ýø¥¤ñü ;•úø%_áskà’æÇ}~ØÁ×$Iç’„$™QfR 1šQÖBŒ¡±ñRœ«£Çÿ<žÆº=m'Tö_öÝ5ö;j~ãyêj4’$ér¤!I:‹™ÔBÑ…ÑÌ U5 ðˆŒ.µ¼´™]Ó£2ö¶›³#J’d&H B’Ì fB Q Ú£…(²Sv¸¢|„GDü]Ò›À_€›+QI’t-ºÍï3„dždµÕÜíÑB”}#:E af‰’vÁ£¶^•t2png-î•$I‡„$é®Ì€¢žQȨj!š9WΊÂÌÆJÚOæ4÷Q8AÒ¿ð-²P&I2ÇÈ0Ç$™Û©h!êZˆzÙ)ÛÒBÔËNÙP af÷H:ø5Æ=€oKzø#py)Z"I’¤UR@H’N$4OÅÖ‚ÐB4ÑR€ø,5óÆÂÀÇ¥ì”uC;Íì/’6vÄÓ=÷ŽÓlü8]ÒiÀ-‘$Éì'5I’´MhŠI¾.’¡¥1"Šì”…â|á©iøzàD}c;8\ÒÀŸÌ¬áÊ”I’t 餘$IÇ#Û«…ØÏŸÐèé¤XHj;à+’ÞþIóÕ&“$é|Rƒ$IçbfŸHz Oδ35ÍAÃCðå¦çÑú¾bg’$Oš’$™=DZæëñ¤z—ª¦á+=öú“ñÕ.Á#3†ÃÌlœ¤ÏáË['I’) $I·FÒ—ð¥ŸÂ}^Ç—˜~Vlföúd’$eRƒ$Iç"iWà[À„6>3;&I2‘B’tSÌìRàÒ9=Ž$Ifˆn£AhË™)I’$I’Ž£Û„9¦€$I’$³ŸÔ $I’$I241$I2g4_d_L’$™iR@H’¹IËJ:HÒ<×Á‘szLI’Ô¥Ûh2Š!Iº8’,ffoHüXx8ÖÌÆà¿åã€{€/™Ù¨95Þ$IæRƒ$]IóK¯¿‘´ð p𤅀»ÀéÀRÀÍ’0³W€«S8H’.Mj’$i?’Nž~ ܇§=>ø2ð-3{TÒÙqÌøêÛ—ãÙ_›ÃO’¤ýd˜c’$Í‘ÔSÒÉ’^•ô±¤+%õ‹êÅ€“qóÀ.±‚ã³ÀP3{´ÔflÑŸ™½‹¯Á°q Vš-“$ɬÒå5) $Éìãx`°°¾€ÒIQ7kfÃJí‡Ó\#ð0XÒü¥²E¨ýÑ Ç—zN’¤ëÒmL ) $ÉL iuI“tž¤Ý%MgÂÖØø#î+°.>¡SRxÿ^¥}U#p¾ ÓÁ’zKú4ðiàÆRûUf庒$I R@H’:Hêùv”t¸¤-KuKÿß®v–Æ[cAàïÀðE–^öˆ~†ƒBX(h¦0³€ïâš…k€ã̬X¦ù3Û|&/9I’ÙC·Ñ ¤“b2Ï#i0wÜØxŸÈ—Ä—M¾LÒ3»ø:ðš™ÇÅÕÿkàNƒx¸ÉÌ~S:·ð?ŠãuEà…¨¬\îÀÌî‘´îð¶™}Xª›6ãWŸ$IRŸ’þøþT¾ð:>I0³m$} |èŒ+6³ ’îÁ„›[9ÏñÀE’^ÁCâ9 ö7³§%],Tjÿu´fö 0iæ.µ%’æúwTI’´Jj’dv#©°9>¹¬üO&ôQ+‡Ç5ó›ÙÔèk8Í'ák€#Jí”Ô§h;®ÑÚøÌìjI»àBÁw€‘ÀN²Ø, IDAT¯Ììé¨ÿv¥½Ñ!Q‘Ga0~_V/½_ w˜L’dö‘B’t4¡–ß Ø˜ü+&Ꞹ#ßýÀùÀÕx^¾ÀÏ[ér8n2˜Z)\Úè'iYàNÜ¡ðW’NvÀý Êíëbf7Rs*ìpâÞ  &”…¦hö nÒ PæNí¬q%I2n“!„¤;r°=p!°'ð}I[™ÙI/O›ÙY’Þ.—ôëŠPf8°˜¤žföq©lÇ¢™},éy` 3»#Ö<8 ø1nV8øIÇ_j}"ÔqÍ5«GY‘[á\K1¸=^GÏUï…¤ÏÍ–'I’&†$i/’âiƒ‡›Y5Ô¯Úv Ü‹3›(éhÜ1pà<|b_´7³ÿFdÀ`àÉz}šÙ«’¦«â“(ÑÏê’ª~€[pmfö$bXŒëXàåÒ¾€ð(„b»ÂÌnhó†4¿ÞeiiX=úîÿÙ¼ã¾8;Þ0³±õúL’$i) $³ IâÎpÏšÙ³±.ð1þ]\NÒ—ÍìñVºY˜hfÌì=IŸ§& ”'î¾À@[þ#ñI¼F'½ñÌìg•ë9xØØøb”ÿ÷…x)Æ3 ×6<Ýà¾ôŠëª'Ë6OÁ3+Ž.ˆqŽÀïe«BU’$]ŠÔ $ó&’æ /ûrÙ@àZ þ”;_Žx*°«™Œv‡ãžþ_iå¯}b¢÷£l5µúpà IÛáªÿCð‰ú™6†¾0¦Ø §Æß¶qÌ+xXâ?½"=2À«÷@Òâ±øRÕ7`ej¿ÅñøÄÿp15A॒&#I’¤ÓI!AÒnxšß»# Ч™®½ÇoƒOÒ»;IšifWE“³ñU,G˜Ù3E2"`ü ~yI½Z‰:Šg"Ü8=4Ssü¼ýý_»`§¶&W3{¢½×[:æâjY„ ®$©ê°:žSÿóøÄ5߀%!#I’¹“Ô $ÝŠÏàOówã¶í3å«$õhŒgc‘ô=<ŸÀ®ø¤û6ð×h2XøNIÃP½ŽEiîð‘™µåP¯…¨oX•ZÈàëÔœ¯¡¦ ]r†L’dÞ$„¤[0 øZ¼ ˆ¤=«?3³»$Ãc÷ë%Žç89&ðËñEˆ6Ç—.ž†OâÍ´°ðY33IëGÕš4ÌìªÈ~ø<¹Ñ=…†ÀÌÞ Æ  ™/ƒ¤íq¿‚7©ùÜLcßá‚RÕ$°:µÄBŸ£qAà&jBÀ3ë°dFI’Ì5tSa ÝI_ÂãûŸ/ÒþÎÀ±Ÿú™ÙíøDyXTõÅ'Ý«Ë#ÿ?x¬ü˜9Ã÷‹Ð¹˜ìÖŽÔÀwã†}Jç+‡â!éUàpàÚH8烫çëq1îïPå&3»¾Z(i~IëÑRŒ;8‚ 8ÕÁxÈà‡Õ>“$I&†¤s‘Ô_+àsøZmµ?8ÑÌ g½MqoÿB@XYR_3»XÒÞ@’p€™ßJ÷Ï}%õ/…Ö §6Ñܱûâ&‰gÍì¨ðØ×\ì…Ûæ§4¸†^¸ùaDkë˜Ùÿ5¨ZºoÀ øÕpÇø¹å,j¾2˜$É>‰n\'év3›@ó'zpap),q>?m·¯œsaà ¥È„*Õ•oÆ'aÌìE|}„ö2-ú{ ¸7£Lwì“´õ}Væ‹fãp À£À¿¨ /gÈ`’$s˜’ö!{_ÇUðï¿­OofïJZ N4³û¢üàȸ=ž8hJ¼?ŸÀ¿Xêf"îm¿rôSà÷ÇIÚÿŽ<Š«áÿ#iI3{½Îðw.5„’ 3u#˜žÚø`%|âÿª¤²0P„ ~H-dðrš; ¶pŒL’$™Ãt›‡“æ’ÖÆ½àï)TÚ’õþ‚/žÓ:Þÿf6-V\(OÇïÇÍëÅ!÷G‡ŸÁ¸-Ÿ8¾>}“ôsàøwäHüI|=à­ãi!È´—ÐNÔó XÏd2XLþWQs|aVÎ$I2‡H ¼JØÂì†GÜ ‹G|Xè-is3{8÷êÿü LxÃñ0Á‚= ÌìÔC‘|3{RÒ£Ày’îöÅÍkà ·Çù‰ögã ŽÊÔ]Ë =”Ö&¨ú¬,ÍŠÁÀ Ô‚‘2˜$É\Bjº+’¾,bf§µ³}_`#à=3{,Ê–Àй .ÀŸ¼w.6Š|'ã^üëÍàÓðp\)è¬#ià›¸câR¥ú}qÆ@`wÜc €™“ñ,!iÜÙ±ê0ˆæ!ƒEöÀ[© ÏgÈ`’$s9館™øÐL@ˆÄ<ƒð”ÄFÙܾÿ °¶¤ûÝÌìõXfxš™íZêãMà®’p2p—¤žÀd\«0#T5GáK ?‰G >UTšÙ«¸ b–‘´-Mƒi2ø2>ñß…gg,|ÆuÄ’$I’Î#„–< Zì„}üRÜþ~=~ÏöŽt½[˜Ùc‘—`$°+ÍÙ)3œæê¥‰øSu?Ü1ðJIÇ„Ç?’ µ2Ö?K›Ùx\¸)óR»¯¼B%d°*,ÍÞ§2x.5߀ L’$iIjº’¾Š¯ÐÑ_YRŸÈ x þ®xÅo…{é÷‘ô]ÜÖÿ!°. §e6¿áøªgÄþ*¸ð®™]'é4`˜¤‡ðP½q…º˜Ù;Àgöº $-I}߀•h28x_½°0dÈ`’$ÉŒ“BWGÒ2¸&à`\88Ÿãªú/m2ׄOøÃñÁ§/FÝpÜ7¡Ìpà›’®Á'Úƒ€£ “ƒ™ýŸ¤3ð‰y ×è‰ £Ûk³UW¦þCKD³ñˆ†‘¸Ö¤ì$˜!ƒI’$³N·y šç`k`\xí#éwÀ÷pïþ'i°ÐžŠWÀ•fvCQ(i%Ü8¾¸Q™á¸q2°!0ÄÌî,7“Ât³BxÿïB-£àjø ‰£€ŸPY!«š€Á4œDóÁò*ƒ2˜$IÒù¤¡ÐŸ00³%=H-iÐøBCÿ,ÚHêefoHúpV¬^X„/Îlƒ¯p^å\Ãñ þ®ª`ЈXøheñ_OÍ7`DƒDGI’$Iç“„nÄãÀÆ’– '?ðIö£xð€¤qaa °(°‡™$é^Üï ðÜÔPd<¹r®—ñ‰{ ®eh•ŒkÖÂÃ$‹Áù£Ùdj“ÿÍÔ|2d0I’¤ë’„®DD,‰‰0³'Â)ðTI'â õ£–`èÕXhè»ÀâÀCø“|qü}D&ömÀÔ4*ÆÕŸú¾ËS | ŸøïÄ mÀx’$I’îBF1t%$ À7«윂/ès7®X¥¨ •üI³8†>¸À*Àö±®@! ùÞ§¦ 8‡æ« Ö]9I’$éV¤‰¡+ †§ þØ žÚ=÷ìV)~¥Ú®ç\Šúë ¬H-dp,>ñ?D-dpðJ† &I’̤aN é³ÀÀ¶Ô>„™ÙsÔOîŒXe9ü~7$­,Ü|xÅÌî-5yX-Þ¯›-ê"iEà6àQà@`uà¿¥&ÿN”ô°¤±’Ž”Ô'Ží#iOI=$ ’´t£óÌ™/"I’¤©A˜‹yx¸-é}IÏIdfN‘4$žØ?Ç5þ’â“öef6ÿÂ,P9ßRÀ;ñþ=ZÿÌö†™Ù1f67Ul"iýÒ6v6ÂC.·Žº€³q?ˆs€'$ý¬Ü¹¤ $!éI«´qŸ ~$éœv¶M’$Iº]ÞAÒÅÀkø“÷ØÒëX3{{vÇÌ®®+¯>ñ¾õ‡Kzø î€x#0MÒ8`0?°4p)PLÄ‹JÚÐ̧ø¯;GýÃÀVÀ¿ o]JNfövø7,EM¸Äèû=¥cš€¾À1f6TÒÀÀ©Ñv/àDàßÀ4àIC m‡¤%qdI\ëq5nnÙhfI’$™‡é6„®. ¸Ÿ¼úãªûþ±5IšFEh ¥ 1Î̦vÖÍì=àÙJÙéÀ镲~a–XøxÓ̦”ÚŒ—tp¯¤ÛÏÿ ¡ÖNt ðjÔ¯mî3³¯I¢$= œmf—4ðGÜ%é,Üäq·™};|3¶ÇµW™Ù³uŽM’$énXÛMº]]@h3› L†5j#©nÇ/ˆâu£JÙ¢ñTܪ afouÖõ˜ÙDà¦uCÃü°®!y+ê.“´nÖXwhÜ-m¢eE¹¬ Ÿø úï™ÙäxÊŸ lýöÇ.‹ïÏVÀ•qÂÖôsD¤G•¦¸Ž ¸¹£‡¤]p!èb<óä½’v3³Û$í üx 8Tî ÌrÀd3{¿ÞýK’$™Ã¤‰¡«Õ„ØkÔNRo|Ò« k”Ë"×AUx¨'H|P=GGbf¯á¾Õòã"—Â|•5Æ¿¨4ÿ£¿Æ² Õ„_¸ ñ6°“™OKAC¸Ù¤õ“jý(àÔ0™ø3ð33»@Ò+1öÛ%mƒ›;Çý>þ€F_ÆãŽ–WgƱë;›Ù/§VZ7Å<ÂX«HÚØÏÌ~ÔF»ÞÀÚföh[}&I’tuæz¡½DÂK±5DÒB47iôÇ“mZ*[NÒ{Ôq¬¬”M0³Oªçè€k™†«æËe¯PвMK»ÑÜ™p2pQ´{?žÚ/‘ô=\ÐZ8ÅÌî$ü$]÷±Lo\¸hDp[I»°:îTy”¤ýq­F¯8xÖÉóÌìlI‹ãš†BûÑŸæÉš¸¹†hÿw`'ÜgbsIǛ٠Q·:° ®‘\&¡5Á­\CÁÏñ„WÓIÛáþw•’g%I2ï’„¹3{[]â)xIZ ë_)•-.imföFg]OAåýÇ(i\Ìì6IðôÒK〢ú0<b¤¤ëf6$êFGHº¸§ŽQ5môÄ87Ã( sÆQ¿¾ÈUÁ(\RhªÂôý0]|XÉÌÞ sÄ ’.ÅïõuxØé#ÀÆÀ®’þô–tð¨™Y½¡•ØX§Tö<å?ÀÉ’~lfgVM’$銤€Ð ÄÓðÄØ®Ò¶ý¬Q$ÊN–M©0–Æ–… Ñ©v÷0›ÜV§|Œ¤ ñÆ•€KÕ[{ßÇÃ4ë •öŸÅMß4³¿Q3s|HM›>‘ óÄ|¸ðR>¦,0 ÁD-iL”¿Šû>î q–™M¢J*éŸñötÜ£Gg„ÆI›ßÂ…¥‰’®.tŽ™}Ü éHú ®Õéœkf¿)Õýø‹™o«Ÿ$Iºñ_©AHZ#&Šªÿ*’ e´F|r,ÊúKšJë‘EØg›ÔL\Ë4üÉû‘Jù$ÜgàÔ‡žK);d¬M±p¹¤ïàÂCp¦™ÝÜ|'žæûáΑ…ä'¡‘Yx-49Û§D÷KwàY+ûã n݉ߓÑñÄÿ|D‘mf… Ñ„k?^¨wá»måwÄ#; ÍÆP) $³Nhž‹­!a¯ k_*•-%é Ú$&5ˆ:èPÌìª:e÷Ä„¹Æ9žš9ãHà<<$sR”÷)þ(®!8øž¦ºÐ Ö2³kŒåI§âI®ž‘´V m9ZnŒÿ–ÊÂÑFøÊ›Ehk3›"éE\ ØAÒÆxäÉn¸éæP<ÿÅ¥’NÁ+„«ðl—) $IÒi¤€0¾ oÐúz óáN€ÕhÍ*e FÖÇV‰ðÉèŒkùº¯–¿ì"I¡ªûž²`W<Âá àBÜìQhh~üOÒÿ€³pGÎ¥ÍìI[†/Æa’¾ŠkÆâއ-"FJ,ŠçÑ(;œ.ŽóÇùŠûõàiIã>û‡ŸG/\¸8¦tì›47«<¬'i©öDa$IÒ%I BÒµˆI¬˜ðnÔNR_Zš4šð¤Iå°Ï¢¿¶²YV}fõ: íF9Ùæé·ËN„—•ê&ÄÓúÎxÔÉ'Ô„m€‹Ã)qéw¡xØRÒ£ ÂW'SËHY¦ì¯°5žÓáùËTI¿Ç•̬pÂ\׈”ý2&ÓCVC0šŠ§ïN!IºÝ"YR I]b"|!¶†È—“® ƒð4ÑEÙ2’Þ¢mAbâLd³|˜RXa[„ÆãÜØÊå¿t,° ¾¢æäRõQ¸?À³‘°©ºœ÷xÜï¡Ì4üžjzL_¨ë(\`X¸Ô®w¼ÎOÍ,±>Í?ÁW-L’$Ý#5ÉÜNdq|‹¶³Y.MKAb“JÙ"’ÆÓvªé“·™ýµ¯e ¾ÐTµü1|¥ÌFǽ(i´¤õÍìñ(þ3p_D ,/å½)@dÁ¼8½_ÒEáï0 ÿóX˜Z4ÆWpâø¸ƒæ¨™¿Ú®I8Ÿ~ˆG—Q&e‰d.$„$‰§æñ±5|ÚL„ýi)H¬U. £­$Tã:;›e… ñÈ…ÇÌìiùRß;ãþþ!HôÀó8üËÌþ élÜ'a0ƒÜ-éûøú«;”εðPR9·þ1[ã¹0_ijt¶* HÚ,^´æë$IW$M I2#„ŸÂ‹´T§7#²YV£5VÄ“8eËIz—¶‰ªsáÌr>°Eåzžޝ”MÃC˃;^.+{âËjOÀw¯$²ú:µÄQsËóá3:ÉÿwVí1æ÷¿5³g:vˆIÒa¤!I:šð#[]JÙ,«‚Äúø*‘EÙâ’&Òv6ËVŸÖcB»z&¯ç=xXi‘0ë5<µuOà’n(çôÔ·j~ òÀ¾x"­€ó$݈G™”×)I’Ž 5IÒ•‰I¸=Ù,ûÑÒ7b5GËb‘®h[? Où_h”À*ÂÁíõG†/Àk»‰Va0Ô̶TmuÕ&3û@Òºx¯AfV8gÞ iÅØ¯&³ºÏ}± ðޤoáþ}"QÕÌìÞh{ž¨j]3{9úí…'£ZŒæ ™%ɬ’„$™[3@{²Y.AKAbmàË¥²%%½N‚D¤©®Ž£Õ?óE¨¾„ç†Ø ÷øDÒYÀßÌlt{¯y0}á.k¹ºêx4C½ÈÀ[u´7…oÉ’VÂâÜŒ¯ zƒ¤þñÙ Z1†€Ÿû!´lŠÿ¹ßß@Ó$í!Ód^#|^§íl–…Y£,HlAóhðÔËm ÍžnÍìyIß®Ä#Àó8üDÒ£øSñ5]P«0€æ+{–y_6»ÕA ÖÁÃF_~ÜkfE¸èŸ%|NÒóxvÑ; L¾òçÿp'ʉÀIÛšÙÓQÿ7à8< ã}àÒÙ‘ª<éÖ¤€$Is"j¢XM²!’Šå®«‚Ć4$>¢~„Æðõ(æ§–€i3|âœ&éLº–VaàÀX¬«¸?#Ì—×¾ w8 8ÅÌ>”Ô;4 ¨ÜË'=ONe‘˜ªÙBb¸ðÕÚZ­-«~ž#c§Ø?7W|)ÌOkâÚŽŸâQ5ÄõlŠ/}¾5îÌz~5)X‘>¼{Tn¿𤙠oï1I—¡[) $I%7¢„H‘Ͳ­1XæëTZ…ƒð ypk {¦1³KN£MøÄ?Ô½#ikàL|ÌïãËoŸí–’¯þùî3°'¾ôøÑý<:IƒUqMÏÛQ¼ ÐHXÚøN1GB§ïG]á\y˜™=õï”ÖÊX w~ü-ðW|iðñLšHú,p°R˜žŽ5³³Kcí‹Gßô-™Rþ×Z¤€Ð=I B’$K)›åô˜I?ö¡í?!Ã1­ûKtÆÛKkN£föð©xbïYʨy5®ößè…‡@þ¸¸d~¹¸GÒ¡ø:¿n)ž¾%ÝŠO¸Ó}¢¼G<é/„›Ž >¤öØŒ,„ƒ`.LŒúÌìøès "LUÒR¸¦çÐó:¸oÄ“fö ¤M¢ÞðÏw I_Ä µ"4ó¿ ü3’®Ij’$™½Äø™À.¸Ê<¯À»¸°Ðwü{ O&ôTlkâ6ø%mAÍ¿aêl½€vN…åý[iCbfÃ$}ך숛Ž.5ù1p½¤eñå´ 7ÇŒNÁS׆Fû=ðû.¼X9åRÔLMÀ奺wñ ð¤WSqo}ü¾ßlc¼¸ÀÌŽ´‚ùwà—øbc SÓ MGÒ—ãÜÃð%Éoû° ®aɼ’9Cj’$™=ÄÓèµøºÓð§Ø§ñ‰ìË„T IDATq<üqT½±$ê÷&àçÔ²Q¾CãŵŠ× 3±ÈÖlÇ̆⡌õêFFjìðµ/zàBÔ?£ÉQÀùR¹< ±uÔ5s’”´ Í×Ò¨:QöÇÓŽƒ/l6ÿÌv¤f&zRÒj¸™äÏ¥q¾çXbZø2”Ø Oõ‘ÔK;Ý×´&˜õÇW&ýbô·"¾HØföHø6Üì \$iK\À,-éb`3ÇŸbfoÄ~àý0qÍ~:Õ|¡²ÖÚÍg7 [\K I2'wpŸ3š²œ‰²?ð…ò~´kO6Ê)y…™=ç—¨–ÿºR4wJ,„¬;i®Ah¢uqpˆ¤3pSƸÂí¸Ãä4\ Js–£&d4¢ σQ°‚ùðc¼Œ›6.þ†;Hž~wÄù‹4×ûÐÜGã7¸`tB´ùð]Ü1ö¿ÀÉVZç$Â{ûTןÇ8~ÛÆµœ/éV3» ÔßòÑßómÛUI B’$s73˜²*D¬|¦T¶\D(´µÈÖë˜E¶:œx¾$ÞîRæ0Ü„™MÓÆ/€‹ñpÔgÌì6àuIG7K:_{Dfv1®yX¨'ë&àÙÒþ¸£ãõøý^\žŒÉv5bM3{/2q®ÇöÞ®äÜXŽZ6ËÝpçPÜã` ðãÐTÜ‚G‰ô–ôðµ8ßfÀ’ÖF—´.Ó‘ôy\ˆÙ'ö{â‚Ï.Àk’^ÆÓqO®Û…I B’$IA8>KóI«’–¤åÚëâŽ{EÙò5'Zõ(Ôá]‰ªJÞÌÆãf¡zmOtf¹9ž>\XŒ’t“™ý°ÎáU߇gp'ÍÛªI²"•µÑ<ćÔ4e­GAÿRÙÀ©À%fö‘¤ƒûpçÏýðUS?çZwÔ|I€;\ÞŠ;_V9 7má¾x.Á1Þ+qäguŽm¤½ñïÒà43{!Êû˘ÙK­Þ‘¤!I’dFˆÓ“p§ÊºÄSdÙ¬Q[•ÊšT[d«­l”¶ÈVGcf÷àN†å²)ÀΡú_²zLLvÓ|Rÿþ>LÒ©x†Éµñ\ ¯âÖêÀ3‘hê›xx(xôË;¥þ{á”cä)¨×ú=£n Ð7îÿóÀ/$í\dfE–ÑÃìpT‘‘²Îu¬…k™n)ï\Q$ø’t)¾–ÆÏ$­¬nfÿiÐß!Ñö„ÿgï<Ãí(«6|? ½HBH€Ð{"M¥(Ò» "¨ ¢¢¢"ˆ4é MéUŠ ½HM¡$@HBB’õýXk²çì³÷i95Y÷uí뜙ygæM8ï3«[áÖ‹ CHÎ’´ºU5óêÒ‚$IÒÄðÛÔ/Í ÌŠö¯éü&[B˜ä™åc[ºjŸIÚO­Üw¼©¬ŸJ:¸7Ä×ñX‚âû}¬J'Ìñ·ÿÑxÚå <~án¨Tkß%iw<ädI?4³kBäõ§éŠ¢_ÁKdYóãbäÇ¥1ïSIó| ¸[ÒûföŸpO\Ï3·Tlf7Ås>ƒg\Õ9ÅÝ×71§ö"-I’$]EXZÒd«ã#Š&[ÅvÑd«^\Ä`´y?ŽnIÄ+ÜŸj~ˆ÷›X _ÌO¥…ö›Q=rx¸vÞ¡“ érà‡’^1³‘f6UR‘ʉ™= |%ì%]‹[€>m&»eUJÀˆ8þ÷œ†×’(b'~œ)×û˜ÙëòŠ•Eðe!˜Æë—®uÞF¼£B¦9&I’ôÂÄü>-o²U_ a¶FÑd«nÊ'.$>®¾GWâá¦øß.?HÒ¸µà]\<‰÷¦xZÒ`qà Igàe±‡â©Ã✩T:nÖc ‹@kV¹ÎÄÖxjf1Ïë% ýͬpO¬×w(3¾_5‡÷ðÜ )’$IZ„5l²õT½qª4Ùª¶HlTú}Yy“­&EîÖèô¶Ò‘žYBÀ̆•6¯+íŸ .éHܵ1¹@’NÁëf쌨õ&H!é6àQ3;µÆT&ýJÛoãŽ}Jû¾Š§is_·‚|„§˜,L¤m–DI\à¢eñóhoÒ‚$I2·a-o²µ$ã#ÖÄ+4Û}#-°©”Ï1À{íYH(Ìï+㮄֜7J•Èbß]x7ÎZã×—´%Y‹{ñ`Ébü4IWW†Ù/k}.€¤åñ ?ÅëGü84No°øKZÏ ù}é~µDDGAŠI’$ImÂ÷>/‡]“pkô§qËï-ª¶ zsÕ,'Wߣ‰ùuJ©e3{wCÔ:ö¬¤ù$ 6³7b÷€ñÔÊ1ÀQO¢/pp¦™]"é_À0I›˜ÙSÀ}À©’>gÞøëÛ¸˜ùOé–[1 @Z’$I’¶nÂjP—Hk¬ñCe·Fq½¦\cÍlZGNÒ_ð/™Ù,ФÍðÔÍ›ÚcÞs)’$I梊ã4 Ìk@IêGã ËM«ö-©ŒÍU³lT§¡+‰K#Ëû"(óLàëœçiAH’$Iz‘a0.>ÏÔE‹–¥±kc]¦}Í· ÛI s=úI!I’$i5± 7z¯FÒâ4«àõ Šíe$M¢ùj–ïXÓ-®Ûú,ã [{^¤Tnü£•u-Ò‚$I’ÌÝDa¢Ix¡¤š„‰¿ã#6¦a*è’ÆÓ|5ËNéìhfC%„w•¼8ÛÌêö)ŸÚÁSkR $I’$]J;ŽÏÿê‹ÆPh±Vy_ÄQ4)"p·F{4e:·"ì#é àt¼³eSMÀÒ‚$I’$íA¤8¾ŸºD¤j1/ŒTì[FÒG4_Ír|Sn 3›M°^¢"VÎΑt5nU¨®u‘.†$I’$él¢ Ô0*}n¾4ŽØ/ ]l/)隯f¹ð$^±èq0Þûuܪp}TÚì¤@H’$Iæ:­ñN|ž«7NÒ¼¸[£:>â‹4Œ˜ïÿ° Ð+NŸ7>ë⠫ΓteO B’$I’ôT¢Ó[ñ©‹¤hºMôÂñóðøyš¤éÀuݬrå,z5?$I’$I’zHú>ðO¼ uy] LŽÏ4¼×mÀà_ÀýÝU@Z’$I’¤M„ûáBà \|ˆ»&áÕ*ų2^^ÞDªæfÖd®&B’$I’´Iý€¿Ë—OáBàÅ”—Î:I’$I2‡2ع «2Í1I’$IæDÌ죮žCG“AŠI’$IÒ¹ô B „$I’$I‘!I’$™#‘4¯¤ë$-ÕÕs©"-I’$IÒÑHšOÒ¡’.—ô+I ì"Gÿ.êÚÖ$B’$I’t0ç¿ÄS wîŽ^ ç¢-sw¡G¤9¦@H’$Iº’ô-IûKZ¼…ç,Œ·ZÞÁÌζ6¾ Þm GtдÛBº’$I’¤’V’ôçÒv_¼ûâ!’–¯sîIWJZXè7]ÂÌ>nv-r+°¡¤:äaæPR $I’$]Á7€JÛǯÛk§HÚQÒÛ’Ö‹±¿&F-‚¢ÁŒÒµn¶(6Ìì}¼Êáfíÿm"-I’$Éœ‹¤$ jãé»”¶7ž6³iQð `7I ™Ù]ÀO{%}Ø85΋‹ƒ²u` °DÕý¦Ò½Ö¼I’$ÉËπݚ ©Þ:³10ª´=ƒ†V€»ñH[˜Ù•À÷ë€kÍllìŸ <ìY:·7ðYÕýfÐ}‚»Ë<š$B’$IÒV†k‚ÇHZ²|PÒ]¸¥ ½ð…¼à`V`b´A~è_óFìû¦¤­Jû¯ö’Ô'ÉŽÀcU÷<ײÇj?$-"és’ö“ôkI×Ç\Öìì¹´–ìÅ$I’´I šÙÔÒ®!Àáñûp«ÀWcì¼ÀÖx+äZ0_iûàIG— õæ-ù p0ø§¤=ÌìAëŒÄc'º5)’$Iæ$Í,ffïµpüRf6!~?ØX¸ÄÌ®Ža{áßüãë%­†/„KIêcfïK:8_ÒÝxÆ@µ™¿Ìõx&Ãùfö–¤?wJº·D< ü/ƯZ,üföŸP`fOÖº‘™Ý†g6´Iý©m Xwn­†[>þ¿3³Ñ-½Ow'B’$ÉœÃ÷ðô¾½ê !0 8X_ÒÊÀOpýÏ€%³%M5³áV™Ùqþð`Á­Íì>I#p+ÂÍì.IOÅuVÆøz\üRÒjfö €™çoüF´8v~[¾&¾‡yc޵„@‘1xÿ¾®ˆŸÃáQo¡­ôˆ4ÇI’$scM$‹ÁýÄÌ&Vù:ž"øs3ÛQÒ‚¸…`k3{NÒüx,Á‘@!'›ÙTI/á‹ë}xÂZÀcÈ1T‚O¯7Q3{GÒ€‹$mS··´ù¨"' 7@Y¬Le ‡/üÏ×Rq ¼•;‚I’$Iû ûÎxý€S€½ñ¿+¨*3ØÈÌ.‰íÅE“%­„Ó½ Ü_ÿ«²; “â÷Y™ f6FÒ©x@á M=ƒ™ý#b ¾ˆ‹6™ ƒ©m èÃ>^ÃþQÃÌlKHsL$IÒM‘4÷Ó÷î0³§b* êÙÀBÀÂföMI“€»Ììµ:—J”%>ÀÆMÀf6£jü`A௒Îù,Š‚ÇlTuÎXà‘×j„™}¿¹1¥ÒÊÕB`UÃë \L7³™’†#Íì›-xÔ“€€45(bê¥ .Ãê¥ ¾V¤ ö`Ò‚$IÒ“ ÿö¸|ѺÔÌÎnæ¼ÞÀ/ñ΂%=ìņŠãû™ÙµñÖ3û‡x¾-îN“´€™}R>hfS"`Bìûø®¤Ã¥BECñÅû®&¿,¿V¹ä1’úQ;Hp0•”ÁQøÂÿ( SÇ4w¿Jf1$I’ôdB\Ž/h¿Â£óû_)Y¯"ø‹7ÂÏ_,ÔKPùã?·&s2IEâ<­°ÜTè±xÖòs”Ý­&:Ör ŠyÎÀ» )ƒçP lQO‡¤Õ¤!I’¤XxOï{¸_x_)„àhüͽ7p\ˆ‚¢ÊßíÅØ·»áaKàß%7ÂÀQár¸o+¼„™}Pž”¤~Q5ð!¼§Àÿá…]q¾Ð._•âx$.0³3Ê׌ ÁVó‰”ÁU©2¸h ûÆ)ƒÃqËÄ4’Î&-I’$³ÉàSàfÖ¨;`øÌÿ:xÊ[y¹q™—©øú?ÁËðŒÁßðúáÅž®’t™½½ñÂB›ã ßÅáë?˜Ù›!.f™ãÍìñV>ùYûR?e°7M§ vûöÂs™æ˜$I2»Dºà+¸%à±°¬ÌV‚íuñRÃÕ¦Û!À>5.;•?ЇH:-Έÿm÷þ^ð IãðÞÏá©‹Dšá¦ùIuÊ^k}õ‘2¸µ…@Ÿ6·  Ç-*ElÀ+saÊ`O$] I’$íÄÜŒ2nÆŽ›ÿÿ ,‹WÖ«õG·œE49ÚÏí/bô=àIw?þ^FµÁ=ãí}a`b­H}3{¿z_SHZœÚ"`*)ƒc©¤ ^GÃ.ƒ=b‘Iê’„$I’v`(nFßx»jq –Ô§Æ"=X,õ>‹ý.¼\HÚ8_ n¬ž@ÔøoUÿè³°µ…À21l» }>lÍý’Cw)’$é ¬Nó ÂîßHú%^wàÀCQp2þ>)8¸¦,2Ìl<^)±MHZˆú)ƒ ư"ep SGfÊà\IZ’$IÚ!¸•`è>Ø÷ÓÏcfC%í„×:xR|x8Îý"0*DÀl!iYj[–£’28·ÜKÔÁ µ®™Ì•db’$I;ñ*0ˆ×&÷,øMô Ø<Òý¦We ´ªŽ@d)¬Jc!°:•IR±ü§ôûk™2˜Ì)¤@H’¤Ã4_{,˜f6MÒqxÿ!xIßFí~[ÓXÒÒÔ¶¬H%eð-¦ ±™2˜ÌiAH’dîDÒ€ÃðÆDoµÇ5ÍìÏm˜Gከ%–ŠaEÊà0§ Öí`˜$³A)&I2÷û»âMŠ6ö0³v-¸÷bÔOœ/†Á-/Ð0epT¦ &]@Z’$©¤-G{úâ>ûpa°Rì¾ÐÌnhçûïÊXK ˆaÓðx…ax¦r—ÁLLº =âÿùIÒÁÄÂ6øÀÌ&–ýð9à쮘×ì…~~ŒWøþ‡ï5¼/B[¯»žX-VŠaïÑ0e°è1)ƒIO!-I27#im¼øÍ’À¢’Ž7³BüøŸ¤ûÍì¥.›d+‰T¿c€ïóã}Ÿ»·Äw/iµ­Ëã<§Sé2XNž)ƒI'ƒ“$áb¼Öÿ÷ð|üÛ$=dfÏEãŸ?§;uá[„¤5ãpw‚Q)\æ3{±tÎ|x@-!P¤ N¢R=°œ2øz¦ &Iב!Ij é ѨØÞ_—®N6³Ïꜻ^°g¬wX˜½ï•ô0n–?<†ßü¡N™àn¤-€ŸáݧSûïÆt¼%ó§’N£"V¢’2ø&¾ð?\B¥€Ð¸Ž~†$éf¤!Iz"’>œ|9¶7Çsà&¿>N —€óÌlzŒ½k^è… …‚kñÅ3%éàëÀåüh-&â&vÆ?»Dm«øß’- h˜2XÄdÊ`’ô0R $IcvÁkö|¸ÑÌ®€Y)uçHú#^Vw'`[I{¿N5³©’¦ão eýKxÉ`•²FKw赜y$}1ËáÕ ¡¾0(˜| ÜÞÙ I2Ò#,½ºzIÒHú©¤o·ñôpsyÁ <}®àf``Ëx+Þã–ƒ Âñ"a‰zã*íëQ÷Å|þ üÐò¿óÄ5®—ô×h©œ$ImR $I2°Y½ƒ’¶—´uÃ}p“zÁTÞ¤1³IÀsÀú±ý)Þ†xE`, -s÷{•¶Æ™ÙÇ¥}½ñ@½®¤WáE„nžÁÓ Ë9Û3q±4“Æð¾<+i­Ž™j’$Aº’9•¡ÀŽ’ö–4³óJÇ ü®‰óËnáÀ!UÇ X´´½Þ#`$p‡¤¯…88TÒ¹À­À¸o¾ÌÆÀ±-y¨Ù!ÕkBT<˵fö`ó–Çk9”?«ÅÏ¥¨ˆƒñûx ç‘fva‡1¬X؇ᩙE­áf6¹êzÛ¶v-óá1I’8iAH’I[›ÙŸš7/°pþV¾(p'î÷îô‘´™½‰gì,cfŸHºxCÒ¦fö¤¤WãZãñ·ö$튿ÝÖ³\/i!3›û¾‹¿iÄ[af¯Ä±›ñ4H";á¶|-˜Ù(`TßÇâÔ«PÉ,x_ü_n¤"FšY­XN%ŠeÁ£$éa¤@H:‹…ñ:’Ô˜T² éR*.ƒ³ñ.|ç·˜Ù/b̹À¸•`(0ÚÌ>0³1’n¶žÄÝ k˜Ù4IGà• Ÿîª7Q3&éj\ ûÞ¶‰7w+×û7³ñ³ñ½®’¨-–‰aÓqÊp<–¡¨68¬ª¿C’$ÝŸ´ $s7Ñtç³H÷ÛX5ÞêÇà‘î¯Uò:p ЧXô$}¸LÒ·ðÅ~U` I½qÐGÒ¼¥ª†½©¤ì ¥‡€™Ý/é`?à—ÍLÿXàiI×›ÙS¥kLoÕ—P"¾êàÀ¢ Q‘ø•Åÿn–®Y¹1I’G „dîDÒŽÀoñ·_‹ µ¿ãnƒ]ÌlhS‡ãk¼<Š/ø7ãUùfH÷ظ",ëà™àâ°ªký¯[Ðds$3›îˆæ 5"šÕ²,‡ÿQ˜I¥ìðýxÝá¸5`¶¬I’$íE „¤MHú)Þ®xY¼@Ð>aâ_ˆû!p©™™¤^f63ô5ñ…¾Ci¼ ß»N*Ý{I¼ |ÕÿVÄ#ÝCï©q¯-Û[â›7³šAw1‡ù¨¤ V "eðc*¥†/¢b xµp‹$I2W’„¤girñ¬ãðb9W˜Ù¿ãøáÀ7ðt¹3ðæ;_öž1³KŠë•ã&ÿ¼,.i™RŸŸ–\ +áõ ¶6³7% ÃË¿|jf³ÜÑühV¤h"´/°g+¾‹¥©-V¤’2ø6.žÄ‹Ø€vK]L’$élR ÌHZXOk{ÐÌ&´àœyp»#ž&ø„™i{Ûá±cñüý5K%­éóÖÃc ÿB¸ù¼/[Õ›SŽÀc ÆÅ¾ç¢"ßx ãƒÀñ¥œú¡ÀêfvssÏŒ[6~[â£^ÊàR1ì*)ƒÿ b nfµàÞI’$iAH:I«âµó{ãi{Kâ>öUJcæÁÀ§fVö»¿Š›ï—Ëû\*éP3» _øVÇÛ?„¿ÁCš¤Û IDAT„g\ç÷ÿ4†/Ò»á&õç€ßW¥\œ(é'qÓkÏ9•f6ï X‹!¸›£%¼¬!©Z¬‚gL€·i.§ .‚7ºCÊ`’$s )’ŽAÒ¢ÀCÀifvfißÒïÛà­‡ßÖ”ô°[Dÿ¬ef›ÇØwñ”¾»pSÿÌ8¯à!¼$ðÕxšàL3; jN½áâáo’®¦â4³ ø·.^­°\ã3»´5߃™5‘2¸<µ­bX‘28Œ†)ƒÃ3e0I’N Ñß¾îH „.DÒ2¸/{üÌ[¼¶/0±,Ììݸv/üýd3;/Rì^ŽÆû £aGÁ[s%ÍE‡Fâ¹ùoÄñ¡T|÷gÿ‘ôîw_›ÙÍ‘µpîžx¸¶4¿GñŒ„Ù"žg5j§ Ï5‘Š :e°ÍéŠI’$³Iº’ÚHZl›Š/XàézkK:ÆÌþ^»1žæ7_XOÓýZ¸9¿Ëã†7ì´½sñ¿ÓñVb3+i nn/Ükáî(šÙÓ’¾ˆˆKð€˜Ù[¸ûa¶‘4€Úր婤 ¾s~/¬T ¾ÓsH’$™IÐNDÚÕðEôÅ&rý1³$M/×IÚ¸QÒP3{LÒ†x½ÿÓñÅï|‘ÜoG¼Pã«Ï¢°D”KÜŽúÅïCqkB™¡øâ[Cp÷Bñ Oà™ ³M¤ ®Bm!°X ûˆ†)ƒÅï™2˜$IO#-s:’Ãú¬‰û½‰/¬¦”ý¶Ä«å=n€¢ ð,`f·Jº8:ü^fø×qW'$‡wá;¨¨1P=73'ix\£hk¼"•ºÿC•$Í_*y|?•:çQú÷af'´úK*!i)* Y¬„Z•.ƒå”Áá™2˜$IÒ¹¤@˜=&ÛG×D `$퀿y¿€›Â—Œíê7ô‚»ð®„ÄØY c4 ‰ Þ/ª‡ã•øŠûõ~bf¿NăûSp Ä.q­±’NÆ£÷?}?/Ý«^ªb“D âŠÔ¶,Ã>Áã!†Ó8eðã¶Ü7I’¤‘„9¨8 X Ž8Xï ø=3»ºêðjûé'Qiû°IÕñ%™ÙÇ’ön’´Ÿ°n}ó»^Ò8<=±7°Y9ÕÑÌ~Óšç­z¶Å¨ÝW`U*)ƒãñ…žŽY73e0I’¹œsC€í"¦`-¼`ÑgföM`3Ü­pmó†â9ùŠöÀë •ÅÿžÒï#2e0I’d® -]¤M€Ÿß òáЦ(µáý©Ÿ2Ø $oаËàp2e0I’dn'-¤ñ†B[áæzá õÍfvQ®7/°2µ…À1¬HFÔÁ×2e0I’$©A¦9v’æö~†—:.Lôóââ`<µ{”¯±$µEÀÊTRGá ÿS4LÓ¾O”$I’̤@è(¢Òwãx@høLö0³¢Ëá`j ~1~*Þe°H,,ÃÍlJG>O’$I2×.†Ž ZýõÂ…@瑱<+é¯xà`9e°Üe°oÎN)ã$I’$i!iAh/$­„g$|ÍÍ]x‰4Lž)ƒI’$IÒ#^D»½@´ð+àóø—Ú«…§^_à}à7é"H’$IºÝÞ‚ÐÒŶ+XØo-¼•/³¥Ê«ðœ¤uÛwzI’$IÒ&2‹a6™ <Œg' Æ­ƒã³*Þ”h*±3ñ †Þ4ŒG˜ÏFxZÒ1fv~ÇO=I’$Iê’.†vÀÌl0¢ÖÁÈL( ‡âS- zó‘ô%à»f6±c§ž$I’$uI BGMŠFÅçáêãMˆ3$lfouÒT“$I’¤ -]Ms"I’$IºˆnoAèÎAŠI’$I2'Ò#,)’$I’¤óI B’$I’$ èiŽ)’$I’$iD „$I’$é\Ò‚$I’$I#2H1I’$I’š¤!I’$I’¤‹!I’$I’žI „$I’$é\Ò‚$I’$IÏ$B’$I’t.iAH’$I’¤™æ˜$I’$IMÒ‚$I’$IÒÅ$I’$IÏ$B’$I’t.=‚0OWO '"©/p+ð60ºôó¿föVWÎ-I’$IÚƒ´ ´å k7€þÀ.ÀZÍ(iIëJZ´Cg˜$I’tWÒ‚03cf×·æ$Iów/}%Mþœdfï´ÿ4“$I’nHiAh÷$-\ë ¤å%'é~I7JÚµtž€-Ílðuà3à%I«¶äÆaø¥¤ïHZ¿ž%I’$I‘¡m VÞ–4QÒË’.´ð °8pð7àóqÞ@àC3› `f#Ìì1þäò äÌ_ãÞ_ÃÝWJzBÒ&íûxI’$I’„9˜ÀÅf¶dü¾pvÛXø¶™Ýnfw›Ù qlÌXÍ­ø‚€¤_S€qa…X¡4vp‡™}ÏÌÖ†ÿ׎ϖ$I’$)ÚÈ Α4 Oüpž™Í4ãã>Hºø>pRœ?[šÎGÀ̰>l»/¦–æ:³Î#ž0³ý`–P»Ø¸ ظ]Ò³föº¤=KÇ€5$]lbf_ŠïáLïò¢þw\PœŒ‹Žeh±7ðT ‹´púß•¶÷Fáÿ°7^ž¾,émà|à`3»NÒR¸ÕaXœ»°s!‚ qAq €¤Õñl·šÙË4ÏŸ«Ë›$éàn3{¤×L’$éhÒÅÐÞ˜Ù | 3³Q’¦IZ¿Ú"“$IRE)ÎM˜Ù§xëç7šo×Õ±«àže$M¢ùøˆwÊn 3{Ò‚ØÞ˜Ùê—uÞØ_dÀߦ ³ø|‡DÜÇèÒ±·ð€ÇýÍì¸{¶tÏqë©Ào€«p1Q¯*e™M€ûKÛ«ãîçJû&Å>ÌìII·¿–tÞyóø:Y1£€>xPè¨ØwnH$Is¤!iH,xR‰ðoDdô¥±Ø;/ö-õš£ãžJX<®Šù÷Â΢õGÀ×åÝ''âı’öþ%ioÜ*± žÝðpð73{OÒcTÞâ§Äušb ÿ'œ˜ÿw_¸O6 ¡¨;ïoñ <>ãÊê‹ÆóÜnf£J‡ÞÃ…^’$IS¤!iax'>ÏÕe“‹l‚²X«¼/ÒC› ²Vö``zu}‚*ÓûèÒþ§".bó˜÷»x=…yâù Ñ48¢™ KÜ­Q¯¸RÁ8ÜmÒÚgy¨Æ¡£êŒÿ8Š7}7õ×âJqf6DÒ+À©’޾‡gru6ú÷àµ%v—´GU¥ÈxüÅ«ÀvQ,«ÌÂô7ƒ$I’æH0•_‰O]"ˆ¯:Èràk¥}}$½KÓñ£#°C‰€Ç{›r-p‚¤^%Qó-Ü𞺻™M ËÀíÀ=fv²¤ÿàý6î1²^›â|3ûMûm…×iH’$iŠ´ $=‹p L^¨7&²úÓXHlKÃlùi>ÈrL·ðvÃÌÞ—ôžîøxì{ØPÒ¼UiœýñrÐ×Ǹ$Ý\þ/3=?°–¤?Æs<8û³l=Ñ¿ãMFÒx?m·"æ¢/0xHÒ8üïÚ²xÀæÎf65*vŽÄÀ…!²Á…¸@x«(ˆ%i p›¤«ÌlrŸ‰»m Þ¤Ò”lgà¸">!b=ÆV?C©újx|Ã$IËOãÂ^þ.ér3++7NÅ],—àA”ŸDÔÅyšs;%Ý’´ $IÒ¹Äâw>îbX°êð <‚¿7.FÏÓé–„º˜Ù(¼gFyßh`ñèZºþŒ™Ù¤Ò“tpc+®wåüC HIp™Ù#’^öþÇ{ƒ©Ôiø*•ºMÅG”é÷¿,²K$…Û7/J:o?~/žÅqpð‹˜ÓSø³mñ¬ âük€C‹"Qá¶Zwk´¨^‡¤Ûý›«N*iC`H;¶ŠŸ[È:I’t.ѲúvÜ0³^Yx¯ððB¹6€¤mñÅfŠ¤ë¨˜ìke^ŒíŽ B¸>nâø¿%-‹§ª~ <™àB©úÜ˃ñŸH£ÜírPìÿSÜûÜ2òcàÿ€ÿâÿ†î`Ñcª]a¥ºøq!$íßÙMxÜÈc’ö(‰°¤!iAH’¤ÓxÓÌ6ŸÝ‹„TScÂ÷]]Öz<+ ÜdkÍ 3û`vçÜ„˜¸ @Ò Ürr)pi±JÚ#ß–úE¸j „㮌ÛÍì%<¸ï4*ÙHZ‰†©›hhµ([¾Œ»Žö”´%•¸• âø–À±fv; ùžº/ÞÁtrçØwãÜóZwý`f×E¦Æ‹¸•åÑ:ßEñLÛàÂv0×q.pQ)@t?\ô4géIôÑ”!Iæ"˜®³î5 ˜DóÕ(ûÑPD ¾@Ã"R Q©FYOHtD“­Ö0/¾xÕÅÌ^ÃÖ¦xŒÆ};ŽÃk8Œt3^ca¤™ý ·\,icµÎÛ[Ò×ð¬‹5ðì‚qÿ’Fà—«ãYà_•Ô×¼Ýv£¹H*²cÊ,Vü1*›â.‘‚_oàî”ïך¯¤Ÿà›TšŠ —9…´ $I’t&±`M¶ž«7N•&[ÕñëÑЭa4Ÿ­1Î:¯ÓXàÆÖœAˆÕˆ·…{aU`rÄÜ€IºÒÌ~KcÆÓ0öáqà›’2ï\º#ðQX*¾ï p²xuvKdEœ ™-#P¶Ì4¼ÖÄœB)&I’tG¬íM¶âtÛP±R,#o²ÕœxovSþÌìAÚ©Òe,ÒÃkì`üy§ÿ7ùwÄøG¢ÏÇ!À÷ÍlJXu.à X­<é×Ã¬Ú ×ÅñÍÊ®J¬Eì‘NZ’$Iz*Ö‚&[±.Eãøˆ«ö-.i<ͧ}vZ6Êlpžmð{€(g½=°'n™ÙÑÌþcÿYØ=Æý¸4ª5.„dŽÆ,§Tß(Š[ ÆçÒ‚$I2§V¢ÉÖóõÆ…½Ú­±,þv\ŽèMóÙc"¸³K0³!’ΗԻȉ²ÌÔûW௥íû%‰JNÃ31â…¢úKz8ÄÌîŒSvî5³™³H B’$I2«ÉVKŠP-Lã ËÁx­b{€¤h^HtX5K3»l6ν¥´ù­â—R3«É±½^¥rǶޫ›’AŠI’$IëˆÌ‰WãS—è™P±^Ĩ}$½KóÙÝ¢šeˆ™rÀäËͬQ¬DÒñ¤@H’$éD-‡ 4Ñ3Üýi±%+E«ªXY-$ZÓÓc¶1³S"ÆcN#-I’$I×n¢Cd]$-Hc1¯PnÒ5•æ³5Æ·g5ËlöÔu¤@H’$™Ë‰R̯ŧ.‘’Xd¹.^ݱܤë=šÏÖx¿C¦g„$I’dÎ!õ÷)uœ¬&²0úÓ8>b«òvX-ÆÐ¼h”úØ]÷Ç`3Ùìà†¤@H’$Iæ.½P,ðO×'i‹ˆeÏZ”Ä´nIDATÑ0>bÍgkŒ wJ§e§·“t9ðàŸföigÏ££H$I’t:ð8">u‘´EÄšÀö¥}}[Ò¤‹v¨fYã9þ.i3àjàcI—g7“y‘„$I’$™"ó¼}uM¢~Bµ[cY`óª}‹HjI“®ÖV³<ïã±pp°¤áx÷Ê{ªU!B’$IÒ£‰ú cãóL½q’æ§±ˆˆ÷ˆ(7é*ê14%$ÆÕ,Ílº¤¯ã±ýðÒâ$/«Â¹fVt"M B’$I’tâM~d|êíª«ã#VÅT•›t}@CqÞSbþ¸Ô¢ñó0àI¯z·×3u$)’$I’¤Dt”œ ­7&Ü}i("6zÕ>o|6.Á‡’Ö6³º®“®¦Öƒ$I’$IÒf6ÓÌÆ›Ù³fv¾èï‰ ZÌÀ»U¾ö. +iÃN™pH B’$I’´Ióûóáàc\, ¼‹—Ã~ïöù"p8°±™}·+æÜRR $I’$IÔø'°%ð!.žžÅ…ÀËQ¥²ú¼™db’$I’ÌyDÅ­€“€Íì.žR»“!I’$IZI\º±­§Ó,¤˜$I’$O „$I’$IÐ#ZX§@H’$I’Î%] I’$I’ôLR $I’$Iç’„$I’$Iz&)’$I’NGRhXÔA¤!I’$Iª‘´2ð‚¤Eºz.]H „$I’dîCR?I¿“ô„¤Û%ý>: bf¯7gwí,»ŒLsL’$IæZ®ÆÛ!œ|8ºtüT`;I_삹uº½!K-'I’$ 4Ÿ™M+m_à?þhf£Zp™}ÌìÝÒ5NNÎ0³O%]Üßžóï®HZX XXº‹§Ó,)’$I’YHúÞ¦øw±}0p>¾¸o <+iM3{OÒŠÀL3{3Æ~ØÅÌv-‹ƒ``hÕ¾wIš×Ì>ë¨gêl$-¬QõYXŠå࣮™]ËI$I’”ùð³ÒöQÀQfvpº¤Gãø€-€?IÚ œìQ}Áh‹ü`§ªCÏKஈ1íüФyqÑSK,æ¯Ã€Ëâçp`/`ûNžr«I$I2‡æü3Ílb+Ï[Øxº´{m`|iû:àHàGfv•¤O»€Û€çÍìÑ—¾¸Ì̯Ú?£5óë $õ¡¶X‰Ê:_øŸÅc/†Åç­èúX}ÍotüÌgŸI’$s{ÿªuPÒzÀH3›\uhyàS3›^Ú÷ ò[3%õ7³ñfvCøÖ/­q¯ƒp¿û>ÕÇÌÌ$ХÉ0˜ÚB o ›¼†/ü7RÃÍlR[n;{³îxR $I’Ìy Áá’tp¯™´(n!èSçÜêFoã¾ó‚)ñsq*–…õû€ßIif÷ŽVÎv–“´6°¤™]Ç׆ՈWèâÙW§±X˜?†M ²øßŒ[†#̬½,="Í1B’$IFÒJøú“fö~쬿ø °lo 1³ZArÓ€…ª‚öÄ¡" ¦Çý߯]«×KÚßÌî~,<ˆ›á‡O–î·pK».’ ¢¶5`` ›ŒÄþ»€?BÀÌÞkÏù45ÕNºO›I$IÒôð/Üܾ°”´ƒ™=ƒ „ƒcøÏ¡’¶6³‡€ÍÇê\zðž­poì» 8RÒ:föh8ÞÌFÄñ_—˜ÙX`¬¤Ý€%Ýü _|_1³OkÜïcàÒ6|HZFÕB`5< àC*€û¨X^+§qviAH’$IZ‡¤þÀ:fvŸ¤U€óp+€€Íìl`n ØÈ̦Hú  ¸1þ¦¾&€™M’ô#à°+î¿ÞÌž*7÷åïë™ÙI_Àû Æç—}ñ7å¡44U¿ƒ/:}ÍlŒ¤7q+B‘Zxð0ÍÌ^«7W3{]Ò‰¸5âk¥ýÃñE¹ÍDe-°2 S‡Ñ0ep8uR{(=â9R $I’ÔAÒçðžkàQûïÿ5³Kczá¦î­ð`ÀWK‹ˆ÷0Gó¿,ZçvC f6!¶‰{>‡›Ð‡Q©Q08JÒ/ß^de‹L†ÇÌìUIãÅ}šÄÌ.–Ô_Ò€ÖšéãûLm!Ð/†5•2øakî׃I B’$If°°²™ˆŒg$íif…ÿA|_/|,^%o_IKãcs3{¶™{ ¥\ðþ7z3›åËœ}p°8p‡¤p Áù¥L†¿áV…2ý)Å 4…™ÚÔñhÕ\2¸ Sߣb¸…ŠÙŽ)ƒ=‘´ $I’t%‘‚·.¾-‰/À/·´°¸Íp`&°@ˆ„‡ðÃ…@xø:0(]¼.é4Ü àùÿoïÌ£íªŠ4þû!F‚@À Ì ¢ˆ È`K«8` Š´¨iµ‘F#vÛ-¢ ¤é…‚‚B+¨Œ¢ ÈŒ"‘QÆ÷’D†hˆ„ê?jŸÜ!çMäM7ù~kÝ•—s÷ÙgŸ›—»ëTÕWÕkuÓ"V׺8SÒ‰d=‚=wo-ã—G{Ÿ.o:™|°èÿ ë4wTìI=I7-C^î%7þ+HÕB•$øørš {Œ1f9Ž”ì]DƶÿLôÙ­©ÉÐx²WÀndᄈ¸3"IºŸ¬)p›¤=]€Ó›®Ñ ìXÉø"â/’®*×½ŽÜ@×! ðôF7Ú‡G–×"2\P…7æ9 DÄÉ}̽”4&vªÛ´‹dpKê%ƒ/-ò¼dp&#/ìD¬b0ƘÁ¦<Ñn Œ‹ˆ‹ûÞLŽˆiMçŸLƽ@£aίÈ/ìãÉ'ô$í”9Ž—t°ðgÒ QÑ L4¶Ém>¦¬ïIÓ( J¢Þj5Õg3š[-£ãåÕBD,‘4‹ÜÈ{mtÏ_—ô I{°¼!ÐÉà#½]à ‡Œ1f04¬æ· ù$ÝMö¸¸mÜ6dÞƒq[7­yLQ OJ'Iý¸"—»\ÒîduÀcÊãÉ.‡Ç×JÚµÄû»Wû–V¿Û‘I‰}.“t@»S9Öb ”ä¼vøû ¹¡7«Ñ³dpÝ2ìYòé&.ƒ•dpÑ×`^ö cÌ °)°Ø¬ù:da[2Jè64¡­„î-¤ëÿÕäÓÜÂ6-ýÀîåç.à=M“t éxެAðÒ-Ù,‰ˆøƒ¤Édøb1ðÇʈrÏãý‹aT½6V/ÃæÑ žGØ»I;‘Žøìm c:nà-½$½}ô,lÓÖ¡ð>ào¤ápcu°xž'¿gã%msÊuh<áuSÚúLîôéˆø®¤™À—I‰á¢¦yªë=\5Л.’ÁWQï Ø° {ކdð"¹3jº5šÑƒ=Æ3tÛHzé¾ß¾¼‰ˆ;H)âñíbD,-›÷v4’v%¿ÿù’nŽ–tÙÞ÷Ýd¡ È ÷²òœ2ïc¥øQ¥Ùï¶ŠˆÊ{1 $£gÉàKʰJ28ƒVÉàý«¸d°±Ác‰.`màsd¡ ë€ï’¥w!³ô{*°³¬³a©!ð6à€oFDÕ®ø#ÀOɼ€§Iwüw s$k߄ے »ht ì‘"»l7¶)çŠTÜKzª.ƒU’àusšŽÅcŒYQJéáG#â×5Cn eŠËš5…º©’¶^Kºãl*tDéLøzIë϶'êõõ„_kºîšÔK·¦U2Xy®kúyvSì¼XæhŒ1ƒHU:¸Î@8¸YÒeÀoÈD½µ€—‘ Žw·öVÊw …}$m@½7`2)\Êò’Á*7À’A3ê±`Œéº]$íMë†<µ'Ú,,´.ð{J—ÁRⸯ2ǵÉàæÔ{Ö+Þ¡µË`å ˜eÉ é{Œ1fé"ëlZ~î"½òœ€o¾˜‰‹d°.Ip ’Á‡HÀŸi• >hÉ  ñûbÁ3$HÚØ;"ÎŒù"âà”XÏR‰Ph– ΢¾Ë %ƒf0±Á³j!iK²záhÎë#‹ÕI×*Ã¥U2Xõ¸/"–÷šÍ*‡C ƘUI»ýö#¿ü>]Cx½‰Ô{6¥U28ƒVÉàLKéƘBÒ¾¤a°;YPHÀÏ#âŒA˜{M²·B]’àø2ìIÕ›%ƒs,4£{Œ1+'%»ÿ Ò0Ø–|Z‡üÒ›G–"È|èY28–” þ…ÜøœI£€Ðüš)1+ˆ cL¿‘ôR² ÒQdëã*»ù»äñd͹«›Qo4K«|€³›~¾'"þ6Ø÷cÌa‚1få@Ò+ÈJ…Ÿ!K!¿àš¿ä–Gw—|„:ÉàeìCäÆß,œ‰%ƒfÕ #~Çm ÓD)µ{PDœ:Òk Hš|ø8iôô±”ìað¯À±åØsd¡™,/\ávÇÆt8ö 3)®òÝÈšø³#â1XVóÿÝ’FÄGt‘#ˆ¤ÞO&öõ]!²ëàO_Ðè2hÉ 1Ëãƒ1£IŸNn'ŸŠß(é­1½ 9˜.éÆˆ¸„–9R¼AÒÙdA¡Šþ|Oˆ¬88•ìªxc:›1#½cVI›HÚh§°GDì{’qóï-{3â>àೃ»ÒQÍØòçAdÂ`sŒt)°˜ô$ôF•—ðYà%D«±Ðn@Œvn—ô᡾cÌÐàƒé$>F&ÂU|•,»¹Áÿ øð½²1í‹I/ÁØÜÞSsÛŽ]O>IoܵÜ‚¤ué¹ Qõÿÿ¯@Kûáò9Í-¯kælBÖ)h~mIv?܈T;üDÒ>ä¿Ã3ƒxkÆt2áA°`†IkK#bIŸƒ—ç=¤PñVàôˆX,ôà02\pp p±¤Ï¶«YÏ^ÀÛ€×4ˆç%=M&ÞjÊfý*êë ¼¢ [Ì!“/¦UQ° |×÷÷šý0 ÆiûJºÈFcÆÔr p$pí@N’ôràõÀM‡×¦ÕÕ}!p´¤#âaIû“ž[3"b^ۜ㇖VÁíôsVŠò¢§&D•!³€Fq¡Ëi-;übŒ²ED¼@/„1fôcÁ 73ÉÒ¼µ‚¤ï§FÄmoUvš­î4ýGÄÝ’‚¬Ö÷pñ|ø`gIãÛZö~¸>"~Q³‘á‹twƒ€¤Mè¹ ´–¾8•FÙá¿÷z1Æcj袸ú%ý¸5"N.9™wd/çª<öN+çW•ýÆ5?8‚Lš»RÒ;"â)Iï> œPd}Û¯Œˆ Ëy;³"¢%6?X”&D[Rß„è¥eXsÙáßÒðÌrÙacÌPcÁ *e“Þ“ÜȾ¼Žl®stIRë&“þ ¸^Òñ0° pWÉlO–׎Àÿ–cWç5yÖ.Ç电켚ô i_-émÀ†À¤vÿ:à;eÍ{—¾øO")%Šë’'ÓPUe‡o΢a<䘽1+%ö ˜•I;ï$ÙGDHº˜|ò½ø%Ùñﻤ ¡‹ 1·K: 88xðûºk•pÁ%Àûh—wHúYùozDÜ[ÞŸ ü{Q1&éeŘ8­¼z⇴*&zûV#3÷ëÂë–aϳÈÿ\\vØ3ʱ`úDқȧò#7EÄÞ’þ“|*ß ø³¤#âAÒKðHDœTΟüQÒçÉÚüëKZ?"'å‡Ý’ö „szYÊ9Ài’¾K"b©¤wÇ‘¡„[iô ">Þ>AD<ÕŸ{Žˆ…5ŸÃ:ô,\½ {”Üøï"••!à²ÃƘ {LgPž€×ìE§~&ù4=8´ä ì³ËþŽ" „窓#â6Is"âjIsÈ<„#âÿ$}–446!›ýÔRν™ô[ŽÍ'Û E28‰zo@•Ÿ°¸—Üø/¥aÌ(’KcŒé fh(In;’O´Éb7ÝqóæX8x;ð”¤K"âó5Cg›TïIz#iï'i;r³_T@µÍ±.™}_½¿-Eþ?—4Ø ”9îÃÈ2¾?‹ˆîþÞk;’ÆQ/ÜŠ†dðII‚¿¦U2ø|ûœÆÓO:"·ÈBç2…ŒÅŸKÆáßœ.éµÕÆY6ï§È‚Aûó€/EÄ=eŽ Ëû;DÄ#=•)&7ôf÷øÓ¤R` pi˜4»ä»€$}88„ü1½éýÍÛ®q Ðgf~D,”ô:àÙ¾ÆÂ2É`]X`SÒ‚_ <@nüב¹•7`~®aŒ1Ä!3¤Ì"7è“#âÈ~À _"å{÷_þ‘”úí@nðûÛWR¾^bäÝÀ[ª¿DD—¤™¤,ð[åÚcFÄyeüR­p<éYØ?"•)¾\ éPÎ]øpzn¼=R¼)S¨— Ž/Þ)ŸÃ 2dÒ,\„1Ƙl Œ’vÞAndë“ölଈ¸ªmìêd8aQDÜ ‹›bù·”¡«O4Ú |x]QÜ ¼‹TÜTÆü¥Ëífù2Å—IÚ¸¯¬ïjÒcp?i |­‡DÁfã`õ²†«I/BHÚ€ž%ƒU7ÂyäÆÿàG4 -4ÆŒìA0½²ùÔ<¬Ö·˜4.‘45"Îôwd(à>`{IW’Oã/®ú·—$ÃýHoÁnMרÔ¹1Kú%°3¹‘/>@jï{c&0AÒ„ˆx¬Ìu»¤ÍËõ^n«E]0“ÜÌïïmâ"_Ü´2š$ƒu†Àzå´çHcjp>­’Á~I1f„±°²#iCòéyÛ¦×:±c§v/‰ˆ‹›ŽÝ!éYàä¢ €”öý[DœQjñÏ&õ¾MŸ"7úÙdái4Z÷v%MŠˆʱõ€¿FÄIÿ SŠÝF6-º7"~ּЈxVÒ[h« Pê ôÔàçôÒË (!–’*#` ÉàcäÆßE¶_n– Žª> Æ3:›iaÅ™Fú¹‘]DnÌË´3¹©¿˜ï-c6)…{šµù?Nvæ“ÒºKŠ$ð;À{I¡ x2"+×9¸IÒýq*i4,%€#ÉÒ¾{•õÇJz¨ÂÓ×ÝdDÜTw¼'"â«J&Sï Ø¨ ]BzGfíš›%ƒO`Œ1+'ö ¬tó#âк7%í \FÊ ¿¬WžØg“å·#KìYÈ§Ô ˜D#?`qÓ”ÒháÛ l&é%ñ·ˆx@ÒÁÀå’n,a€9d££»H«õÛqMÓõúª(Ø'’Ö¦gÉàZeØB’Á«h³-4Ƭb؃°ŠÐl)il‰ñO"7ý;J{á#È2ÄG—ñ•«ÿyI³ÉD{í‚5• ÿ>²dðIå½ÍȺ¬È'ôÛ"â7’¾HæÜ^Ö÷ûˆ8˜DÒD꽯,ë’ÁHUBå ’¦GÆÓ8Iq¡X“,%¼9§ŸAÊ ç‘EŒnèáÜe +$íL |8EÒÆ¤Çáp`_X–ðŠ(ÇOm[ß6ý½™"9Ü’å ­—•aÏÒ þ€†7àK1fåÀ R ÷Ì~œQSë.ðúNïªÞ“´5p™ÓpxD¿ÙØœVÉàLàOÀ¹4 ,4ƘUŠŽøÎ_é „RÉðà_Èû«îñ˜ˆ˜¾óŽ%kÔ…&”a‹9䯭’ÁA7LŒ1Æt,ö ’^M†"U—¥Œ¿ÞÏy*‰b»!0…¬˜ð8$ÁKi÷Z2hŒ1¦ìAJâ/o'±4ÜúKg€EÄÒ¦sDö¨óL,Ã*ÉàLà×´JÚ»2Ƴ’cÂPP6øýÈ~;“= DÃkP18ØMR»dp\ó4 oÀu´JŸÃcŒ\ìAlŠ*à`Òc°ºí†AEß*Î% ßgÒðÌÊ5cŒ15؃0”RŸ¾@**ÆÖŸ4,´³€Ï9IÐcÌ(¡#ê ŒéôÁZ’N ËXüPûóÁVã>\'i³![¥1ÆÓ:"Ä0š ‘òÁ§€édH`>™ˆX¤´ðù^æ ¼¸SÒC³TcŒ1f@ŒzÂh107"ŽŽ«JC6'š ¼ªéÏ-Êk"†•1†LJ<_Ò߇»J¡1Ƙ¢#<£Ù@¨¥È*¯›Úß/ ‡ i5 &“U §uÞ,éÀˆ¸sXmŒ1Æ´bÂpSÊ?R^7ב´°±$¹Ì±1Ƙa¦#’W:¡?DDe@cŒ1¦†Ñœ¤hŒ1ƬŒt„Á‚1Æ3¼tDhÛ‚1Æ3ü؃`Œ1ƘìA0ÆcL-ö cŒ1¦')cŒ1¦3±`Œ1Æ /ö cŒ1f9œ¤hŒ1ƘZìA0ÆcL 1cŒ1¦3±`Œ1Æ /ö cŒ1¦3±`Œ1Æ /ö cŒ1¦3ÍÂãÀ“#½cVó˟Ƙ¡¥#<Šèˆz ÆcÌJ¤M€Ý#â‚‘^Koü?Ÿ x³d­IEND®B`‚openchange-2.0/apidocs/html/mapiproxy/mapiproxy_error_001.png000066400000000000000000000116051223057412600244340ustar00rootroot00000000000000‰PNG  IHDRówY©1sRGB®ÎébKGDÿÿÿ ½§“ pHYs  šœtIMEØ6ÆRŸtEXtCommentCreated with GIMPWàIDATxÚíÝy˜åÇñoõ1÷ÁƒJ¸ÅD0ȯU‰LŒ®Y}6n²OdñŽñ@£ÆÅh6›Ý51ƄĠ² ‰GÆ›ÁP9<ðæ¤gºkÿ¨é™î™îžêkººù}ž‡‡îž®îª·Þê_½o¯±~ÍJÉJóæ_çè‰Ç«$DDD²ÐÂ… ðlX[«ÉRžàƒ©ç=ÖõªFÈã®=†ÑóqçäF”ÇÖ{#?î|w×c#döBž„?îúâ®—È{,câËkëûâïHešÌ|G*ÓdÖSÒËØm¾ã© væ;Ê÷%<ßñÔ};ë)Ë6¯ÚfµÍj›uü6:Ÿ©0!ïÃÎÇ.íψˆˆäHË\DDDÒï‚)å O[]]ÍîY¦0É´DÎU[ºlEn·Ì?ëgzCÒŸ·íµÛ;úúÍl}uaçóÑ3oql9¬ù˵T;7áÏxë©+˜:w±¶6‘,Ñ#Ì›6ÿ€’±óz¼¹áÇ(;òröðsʺÜA>lÊõìXe=?ìøè¡þÉ›wôxmÄŒ›ØÞä#O¼ ØöêmV¨Ï¼ØòŠìcNº5%óÿÁó7öxíèÓïìuº÷ž»€‰gÝ£Z,"’Å*«¦°~ÍJ[¯Gõ¸ÆM‡ùƇž—uyƃ<Á >ýF¾6ý'|múO¬ýv[Óžy £SäãO»ƒñ§ÝÉøÓ¬ßð·«v‹ˆ$‚a ïxƒtÒ5Y½b6½tSÖÎ{gÏ] )¾ÑˆˆôÔ½›=é–yh w»áTZ…¶Î¾Z}og7{6 ¶Ì;Ûì E‰ä¡ÇÏã tÇÝnHÕÕÝì’IÁKÓ‚ÇÌED¤o‚¼{¨'Ý2·«|üÔ¿ÿ`ØIpý+#‡ÀÀ ¨{ï~v‡œ7xâU`a­rèèf7`è±×òÕ»÷„×ý¸ C§ÞÀŽUwE=nø 7òÉ›wðÉá—§/M‹Ç˜“n壗o ; îˆêÛ{òmlzéæÝìÝ™uê|ðü¼ÿ÷ðËÓŽ>ýN0 *ϸ‹õ+n`ý_¯ïñÝμ›÷ž».ê p“fßËêg®aõò®£cÏY„w®uÜüí“à¦Ìy GÌÔ¹‹Yõä|j—^¡ãæ""i­õO7»aš¦¹am­ZÑ  ´!Ö|k m³ÚfµÍ’šV.˜Ržðàjjj:oç:!ïÃÎ×t;W‘>ëÖ¬‰P˜‹ˆˆô¡êêꔦÂ\DD¤Eõ,YÏ\DD$Ëu¶ÌW-ý•†ˆHÂÌ(EÒO-s…¹ˆˆˆ(ÌEDDDa.""¢0…¹ˆˆˆ(ÌEDDDa.""¢0…¹ˆˆˆ(ÌEDDÄYaîr5SVþ†J\DD$ÅúdToþ§Œû}\®46T±éƒûÈÏ÷ªôEDD²¡ení ;ìÛ´ùö()­¥‹ùËsÛUú"""ÙæÝCK xÝn €©S·RûΖ<±Yk@DDÄÉaîr5âv-Ç0ÁpN³€k¼Áþ×û|¶c¿Ö‚ˆˆˆSü_ù#´ù ߆ËjÁD[3œ0}'LÛ̞بµ ""âÔ0w»–àqC~¾8|äãq[¿fþk,}úSvïnv\ÁTVM;¨+F´åOw¹8½ÜÓ5©ú܃½Þê7!¾åé«eR½Ìâ0P¾˜@;x ¯¸hZ€FŒü!гNù’“¦oåwK¶d¼B‡þËäÄÁPésyûòÇ1“õ6Û¶‰D>#•ei…¾–‰ßõkV²~ÍÊ^¿?—êšS–#ߦKÓüxÜO` ¬Ô x1[›xýe'ž¾¨Ï.0L.ûa-ÿð(.úîH.éóB ­ÌÁÇ™ä„yçsZ½Õ6‘Û˘ ëÀIÛJ:æ#-aÞ¯ôÚ[”•EÅüqI€ . &àÓOà°Ã௯㬳?å˜ñ›ùóÓ‡ó£Lpl !´ð£½žè´Á×Ö¯YVáb½7‘ïöZ÷ùëþ™½íEÆš§ÞÊ!Òü§ºÜí¼Ö}~씳Ýe³³ÀÍá-À`$;Á—^ô×Þvß™;ÂQ­óDVP:[]3§·³;?¹|œ.›×_®-[¢Ýå™Þ JÕoe2Ë›lY%:}*×YJÏf//XB›¯™B7xËŠÁôÎ<%@aA Ã\yL;¡ð>(Lû¸ðüM ¸g²ì6¯ j•{ª[é}±lj¥gnÙÒ²}âÝýçÂïC¬iíôD$òÝŽk™çµÿÓùEðzaÿ>(‡ ¿ÝÄ–¨¨N^ÞÌœ¹×ê}gTàqíæ_ú&?¾ssÏEAAžc÷À{;a!ZåŽ4m¤“¯ì~O<óíózÛ“ÙPí|§ÝË)÷XËïFm÷ø[÷eK´ÜPo“-¿xË«¯¶ »ËÕ[=MÅ|¥j=%³ÝÄ»MF µÐçñ”G¼ÛA<¿­v–!ë/]¿1ñ2LÓ47¬­MúÇ¢,o ®Ö)̇¥Pìo€Á°öPuÊ(Î5ŸÆúx¾v94íÀáÐÜuuøL8aÎ%|sö,Λãücç’Û-]&(¢íÔé–.[AMMMêZæÞ¶Ç0<ùnhl‚Ð+aÜP‡I[¿G­óáÚ±þoÚÅýhûªŽ¼þðýóßeÑ£#9óŒ1zT[ED$-­Ù\’’cæ¥Þgñ؋ۀ’|ðûÁ×f]VÞ …IÇøøåï_á´êϬóâüXo°nåê)*àÀnøÑ…ïá |Æ‹/mÑÚ‘ŒÑ„ˆs·Íл×I Ã¼È¿Ø òÞz‰¯ÍU:Î'Ù^¿T‡)©ÓÅ šîÅ€¢BFi45Y­r#dw¡Øz>ë;{¬.v7Ö™ìÁ–»4ù aT ÃØ·¼pí%¯sÇo†sêÉ#p¹Œ´†Z÷çñ‘èMø£íñÆ3ˆC¼gwƺo±ÝR9ï½}V¤!࡯u‰VN‰Ô/»ßë¦NDÅî´½µ<%žrÈÔ`<ñ.k<xdzàqH˜—²_kù_\í~hnéjmA^«^ÈãøïÍŒ«¨`à Ûq—`Ý8&´;~çNQ‚«¸ê›9ÿÔxàñYöÜF¾uvß_wžÌ v>'ß—ÊAÝ+g0‘xË"ƒôÅ .‰Ôt|·:’Y†T¢’ì@4ñÖ¯lŒ§·zœìï@¦¾‡„yaëoi7Àë£ ¯£UÞÌ®ÿðÏW{ 6~1€›~fpçCÛ¬VºÙñà€êöBy|uÍ †óO_Ç—Ž`öéGàõºQh±î@”̈XÙ~BY2="NûÜL–i¦îO©yÖ,é;ÖêÛŽJŽ…yëhkÚÇÅù€øººÌƒ­ó€Õúþè‹` “†A]}ïðoëj‘èõõ0äÜEyøë|\>wþ~¯¾¾“gv\Ù9ÝÎû“p ÷zS1ÚR¬Ö|²å’É2ÍÖõy0-oª—-Õe`ç°˜ƒÊ- WÔöwümà2Áíîè^ǰ.Ks…ü3 ȇÙÓ>ßåâÑ%‹™1c¿ÕÅnÐõÞà´íí°o/nÓà€JûÁ7¦lgÉS[²bÃÍt—RèF«k2Òª}=ßé:ñ.ÕË‘­­ôlœgµÒÓ7¶}¶× ICË<кšv?ø|°Ÿ¯ÛÄÄèÚ5X» . Zaùo¾ä§‹GÒØÚ@ÓŽ™œ=ãU|Ÿƒ?ÐÑ ïx?&˜ûñµCÀEí0ùÈ<õ«ÑlÙº—Ñ£úg4PÒõþXïKdÀx¿/Ö€‘^·3F<ƒF$3L¬rêËA]ÒQSõÝND%™h’<%åÎÁxìl{‰Ì—Ým<Ú:K÷6 ‰Ih •ò–‡Ùÿùãx=àqƒãFm.x¼0¸ŸîMÍPߘ¦3;ën”@¿r˜sý^^3œ«æù³+µÖDÄ­L˜dZR­ÔΣ´ÿF싺z.Ó´úÜ»ßߥã8À»ÌŽ÷˜FH+>ä½`½¿À >Ÿ‹Ÿÿy2/¼5ŠþeÍ”•h͉ˆˆt“ðÙì bÕÖøßÿyƒ–ÖfŒ˜—Gjº1ßíqùñµ{ØöyÊŠ[8®j3fŒÔGP«\r"̦NÃðáÃX·~gÇùoFxN›Ý2Ûìö7¢<7C&0ý{9nÒ¡Ž¹4MDD$gÂà!Erò•¤ˆˆH†¸T""" sQ˜‹ˆˆˆÂ\DDDa.""" sQ˜‹ˆˆˆÂ\DDDa.""" sQ˜‹ˆˆˆÂ\DDDa.""" sQ˜‹ˆˆˆÂ\DD$gyT"©QY5M…`Óú5+U" sg2MS…Cuu5555*…¹ˆ³mX[«Bˆ`é²*‘4Ñ1s…¹ˆˆˆ(ÌEDDDa.""¢0‘¬VY5­ó_÷×c=‘ì§³ÙEr$ÈC¯Ýîþ¼·×ED-sqPƒuS–H-r¹ˆÂ\Dr(ðEDa.""" sé+‘ºÝEDa."j»ÇÑE$7èlv‘ ôhÇǃïÓñs…¹ˆ84Ðí¼® É=êfQ˜‹ˆˆˆÂ\DDDæ"""+'’bK—­P!ˆˆÂ\$[UWW«DDa.’ÍjjjT"¢0ÉVº~[D2E'À‰ˆˆ(ÌEDDDa.""" s…¹ˆˆˆ(ÌEDDDa.""" s…¹ˆˆˆ(ÌEDDDa."""¶x.\¨RÉæ0×(O"""Ùíÿ¿ˆáÓ|ƒÅ IEND®B`‚openchange-2.0/apidocs/html/mapiproxy/mapiproxy_error_001_fix.png000066400000000000000000000125731223057412600253070ustar00rootroot00000000000000‰PNG  IHDRXíúm2sRGB®ÎébKGDÿÿÿ ½§“ pHYs  šœtIMEØ ,i+/YtEXtCommentCreated with GIMPWÖIDATxÚíÝ$e}ÇñïP[þÑDJ£b´Ät—Û9vÃíVŽ€p§+r€$¡!ÜÁÁarÀYÃ$¢î„å‡Å¯r‚ºÊF.pÖŒ§è ÜÉž©h󣢩P‰š¿'ÌÎ\OO?ýÏ}µ¿;eêCwÈ»Ïï¼3øÞ—6÷…ë{6Ü%ïÙpWßô{vuÂuÍÅ÷ÊšÜ+""­‡?®\ïÝn”Ýn”g¸¬÷ØÓ÷wÂõÌË’µ{HDD¾ùù?í{Þ÷\btð,ÞÑ ×õW?*ë·<*""_ÛqAß4 ·Ï™ŠB‡lÒp­`³R½ÞYÁ;ϸY~üôrð©ÃË;k.UH¸‚uåÛüYìßÿè£÷ ôÁ>óÀe}}°OÝ÷QåóϾâá^Ût«ØoÜuqïïçmÞÕ×5ôøç6(ç5»õ˽{E¬^ƒÝNºŽ:n³¾lãÝ›NÙÖ«bEDþuï§{]EóÂb'\W¯ß!Ryþk×8›÷š‹ïüÖJDÈv_XÛÍÝ7¹ÞtÊõrÌäõ™/7Ø;zf§‚^þæ6Ž2yÿ•_èý~îæ]4*®á uRÁšú±kä•åòß/ÝÞ{ìèñ­‘Ó¾þ¤OÈ/~xkß…®îE®`õz¸‹ &¿÷îåçß¿Yþå{Ÿêýí­§}2²ò:vÍMòÓoߤ½Èuh÷öÞïºiðÇsòÒ“ÛäGO¾Ð¼Èåäu·Ë ‹×ÊóÛU®§]0/Ï>¶I¾ûè•;ý¢{dÏ®+ºfBº¢>¢õ¾ËZMäŒÊÓ÷_:ÐEнÐecÝU_”Å;.è"øàÊ…. ¨TUªmA­Ýn·ØÇ`/9p£´O0Ø Çƒ½øìeÃêW'þ&W«Õê}UvÕ«õë Wˆ| Lë/¼›kD€gº¯½&AÀæÐi̼‚ðgffÆË| X•§ +-ƃOzìs —ÐÀеC?QdT°@À `€€@À€W|“«ÄFÇ'K³-IâXx ×2…Ò¦-Ûd~ç;åØ"VEá )SeW•ŠozzZ6mÙ&Íf³’'já2çV[Ôª(Xý”­²+{×]Õ<†ËòÎæ›“¶¨;µ[ýp`¢è<Çpt»>`, tïÙýÏçr‚?¶À¡Q†eø^—î­‡ƒÿùâsÞ¨VAPé€Íª"Ê¢ª£²l‡ðãQûn_Õó‹~ü¹Þ®ÒÍßä˜[¦¯ªSµ>Áõ6Ýn›ó1jŸ‡ßáè^ô+YÁšüÁ›TJq¡—Õ«µIØš†—iuhZIúxûT¦w"¶ÇŸíqiS©'Y—,Û!ê\KºÎI·¡Œøˆë©{…NÚ¿Byx›í+øòÐ÷äû O[½fÝEZǬÏÓùÇíó2^ÿq}¤}ûn2½ë@S]Irâ»Z7Ÿ¡£z[ªê›z<ü˜é‰UÔ*¹ëWÔø^ÿ´óÏâÝY!Ö¦ qu±$‹Ä´+ ‹ut½Œ¸yÅõŸ%yLÕ­ãj»†Qç½êÖµ‰ïõ×Í¿JÄG\îPÝ㺆5Þ¶zò±m¾¦ªU•$Ôm׎içoZÙ‡_\\_˜5 Ù¤Ë6ÙnWí\Öc»Ön·Û&ßm.òw —¤ÕjI³Ù¬Ä÷¸Ëø}õî>¬ê…U;†‹|\t×izzš¯Ê€õz€ØGÀ€/Ú>XFN/î«g™û a𙙉íó ö TñdEñÌ®[+³ëÖr,bè/ô6è"OX `€€°@À `€€@À€o#ÃXè0îµe¼‹%€Šì0µh뀀7ÚÌ캵V•­ê.“Q·ÌŽ»w½nžáç›Ü~<ȶ£ì0W¯× 9’Úˆ¯Æˆl ÕMÒT!©ººIå©ê 0™§júðtªmN£Ñ ‚ S_oÉ£îÚ9ŒÛ8›l/€êáS@ÀšU´|@ŒML ïSº‹FQÁi2­nYÁþÔàE.WË€nvŒ kÁ&«.~©æ¡ª^M–·,Óå@i»€€Í°2¦Ò@À@‰ŒML°àë5 ž°@À@± ås°¶#Ou$ìP´Z-£éæwα—°¶šÍ¦vš2U®>ÆI`ìwí(âæsÓáy¹œ7ØÌOŠ aßz&ïa™‡@Ž ÕàçÃØ‡&ËWW¡›/ˆl¡p°–OÞ÷išÐäx%`KóvOUaw}ë“*[WE½½Œ;9uó2­ã~7¿é(iª¶×-;j?%]?“v¯T˜ªÖ'êß6·&"Œ Ø\…ižn=£ªtlçeR)™l«ÉúÚTkIo­ã¢;CõB Û×6m’&Ü’ŽüFw[Ê·“øõŒª²M:]Úçê‚ÉõºEUt®÷y*m›‚€­¼¸Ê6Ét>_|toóóþÂ[´+øT¬åÂ7¹VVE¬ŒÂÛªÛv×Õ¬ï6v=ÿ¨þx_Ç Õ,lî‚#/·žQŒ¦/ïß«œÎv½L×צͲ¸µŽÉ2TÓ¤Yg]¹Øö¨yp»¢ò©µÛív܇ùGÇ'­>ì¿°¸¤ýjëÂâ’Ì®[kk{åµÈ¬Šü<ÓÁhâBªˆ¥$y‘L²IÛÚÅ€+ªu°=.ãž¶•^’MtÍ€(i¿køÃ(%î q£{%mSÛ¶6Ù·q_nˆ N“1fÓ<léè|_eŠ:PŠÉð…iö…«}j³ª T5½®š-k×  §Aç²"Fu_¤R\¶µË¡ ³~>ò¥ÐÓÊrà ÛõV7G‘æµßòö"äk¸H“ФQÁæ.d£ÞŠÅ='nz›AB¢NÛÀp0y(%êÂ’j4/›ÁO\µµÉ2UÇÒÖÂ`/å3”Á^€¼w1 ?Š:ØK)> ¸x O¸‚.À!B¾1°@ÀX `€€tnEÀ€£ã“,øª`½|Ñ Ñhк*ÏyÀÖëuZ|,ƒ¼@}°@À `€€@À lø¸×üØÄ÷°€ #×å{~Ýwo÷ܽ^’åªæ €€Í%ßw UÍßÅr¹Û)PÎÇ"XX\RþmvÝZëŠ.ª2 >¶¼oïgxºªR·œpØuÿ^¦îqÝv¤™GT Çí ˆêõz!Ç9ñÕQLH–QáWñE=W7O“Çu§j½lædãÚ(¢":âkÆi^mT!ëúíô0ú:³X&#š%ؤ¢Þv§ Rݲ² רj@9åö"—îm+KT°™„§êBMÔEðô6•gÔ²’Ì38½Éò£æo².Áy§Ùnî"°ý˜“î‚QÜßÒÌS5U×…n¹&ëb;‚ ‹X ,°X¨ ¡|Öv´§¢Ž¤€€ŠV«e4ÝüÎ9öÖV³ÙÔN“´rÕ cX56_óEuŽ1οrÛ[«Õ¬’ªÖ·ýáÛÚ¨pÀÚ„+ÐE¦ív;q¸êîn ú»ÉmYâ^UIÆÝÞÆä–2á·ö¦·´Ñu¤¹iûÙÎ_·]6í¤ÛO¦óŽ›§É; “õ1ݾ4DZÉ-”P€ †l0\ƒ¡ë[ÜíWâÝv~q/Q·ƒQMo{KÝ6Ú܂Ǥ=’Î?é-|¢æ·I—i:`zšy&Ù6mΠï Øpåê#\mª§pÕ`z²Úy^%YGß·øI&ÏË2`ân¾i²qÇq‘;Ö“4•kð†IÃÏö]uK›ªò}‹Ÿ4—n²¬æTËŠj?ޱòÈÅE®n¨&©\»¤ê*yøÕÞæÕ?nZzóöÈÃÛм¿ÖciŽcÐEiŸkTˆ&9Qm.œè–k[u‡ŸgsK›$ËVµ“ë[ü¤Ý?6Ûh;oÓéMÚ$nÚ$mgÚæIÛÉÔÚív;îÃü£ã“Vö_X\Ò~µuaqIf×­5ž§í:øz[çë9yš?Ø?yc’)Y®K«ÕŠý†ipš¡T°õz£]>eà–<~R€ê¨|Ç Ê‹á €€*olbŠ€*X(/Ÿ"h4´,Öõ ùŒ+x XnNÏDÓ ž°@À `€€-5à<`‹,e¨û– ‚…ŒO T `Ç&¦zÿ©ß6[ ›,+êñp¥÷{Ôº©*E“uµi§¨y†WmîùT»€;™ÜÑ ê–ÅQwÅ žüQÓ‡+2“;¾Æ-+É-¦ãæ“äþöIÚÉv©fl^ØÞ=Ö6ÜLÃU²Yt ·-¼1@Àz ×ËÓU“á[mn@yTö"—ªR ‡b’·èQóKú¾ûBUÛF,ã 6x‚.ïß;2áðÒ…’‹ªÎdlÞZ'};®j#ÓuTµ©ÍzS%Ù¨µÛív܃£ã“™ A˜¦Rí ø¶°¸$­VKæwÎM3’‡“Üe¥ ¥î"°}ëÚ(#¾É,,.°àC«Õ"`À‡f³é¾vaq‰–àL½^/ìÍT½\äjµZR‹û8Te¶[¨¶4•ç¦-Û ¿ý#|Ÿ´~N£Ñ(Ŷ°r]ÉŸ"€ªl­V«Ä2‹ÊW[±@À&8QŠtâÔj5åúwÿüOµ}ªùÄM«ú{ÑÂ×t² ê$Ë)ò1ŒáÉú„k·Û¥h¸îvøØ¦àüÊÔfyÚoÞGU%™ 6A¸FUjQ• ª¢óõüàz¶Ûm'Kp>ICÓv;T•uÜïiÚ3j‡Û/®Ômƒéöƽ[0Ù^—ó Ú5 Ѳ¶/é~×=·½.æa². Ó2ê6Ô‹\ªWy›PHû|ÛêÓE«[¿àv…» âú…M¶­;O›íÉÛ ÏêÊ3Û-û™™ôÁª‚%퉛æùÁŠ,o!µ.Qa«ÚŽao›ê­´«õðµ=ª6F¶ÝT°)B6m5éúù¦'«Ë*6«PŽêKî>fZM»èÎðð„ *_ÁFäQ}V&'Q8 tÏWM§zÌE˜n—‹(Óm³¿i{ºÚŽàãqëlsÜÄÍWÕgj³n¶ëÖ{e>@m¦·­ÚlK².I¦Iº^i·M·®®ÚΤšÖ=Ïåqcò{ÒuK{ £¼ØÇWeÀ‡ÑñI{¡Òü*ËÈXI*X€7eÓ5 /;¿s®²Ã“èÏÖ¡z½ÎQ>–Ê:ø°@ÀX `€€°@À `€€@À ,€€X ,°X `,°@ÀX `€€°@À Ðú›|­±ÞyJIEND®B`‚openchange-2.0/apidocs/html/mapiproxy/mapiproxy_error_002.png000066400000000000000000000122221223057412600244310ustar00rootroot00000000000000‰PNG  IHDRîr•Ä2ÚsRGB®ÎébKGDÿÿÿ ½§“ pHYs  šœtIMEØ 8¨­pIDATxÚíÝy”TåÆñï­êªê½Ù ˆ„Å€@ÜÅŒŠ'£‰G'“dÆd有q!FcŒ{ÔÄcrr23&Nrmµƒ!ÑxH¢pCÁA@(4ÐûRUóGUuWU×r×êºÝÏçœ>]˽·î}ß÷¾¿û¾wyÍ×Å_0âñ¸·ˆˆˆÜtÓMT¼öÊz¥„ˆˆˆOTÌ?ÿimp00Ò^÷¿ø0Œ¯ûf7ò¼NL›ûurêþ…¦½#íMæëþî{]l=snoÖ¶[Ïœ¯³¶·Øzö/:ÿ¶[OÓyä0_ræ‘Å|ªé[l=ͤu±õ´º½vË}ú6ÚÍ—Œ<²™/éÛë°n²—¾9ÒÚJ]˜/­ó–ÿ¦¯êþÂu“æ†ß  cŸµ¸EDDÄ×`{ÞÅ‹óïw4)p‹ˆˆ”’ëÉ›Ö Í÷ûÏ¿ïõ!ó¯q¼¼ÏÜÜ÷zÚÉ׳ý/7õ½Ÿ~êe›÷-ŽZv§íelxô 柷B{™ˆH™ÊÜm[ @íŒKLØòæýÔ~)ßø! G\ZA{âq߯0`÷†ÄûIÇçàï>wë€Ï¦,¼€ÏÜÀÔ“®vü5ħrðv2ˆæRý×øìÓKn/:ß««¯àÈ¥w¨‹ˆøÌìy ؼq©Ï³å¼8­õ­eí-÷g¼¯?âÒAÚv¤‚öä¿Ë'“;Ÿ½ÅÔüÓO½ÑµV÷O&‚ö¬3ocÖ™·ñé%·ðÚ®Q©ÂR9¨­í-îìà];óZ¶ühÀwÙ-îý¯ß—ñýÈÙ—Ó¼9ÑÝ:jÎìÛt/£ç,`ï«÷dL;öÈoö½Þ³ñ®ŒïÆèþýû‹™-Ë Ç^= å}Èüo÷½o}¢Õ:iÁwl%êŽgnfêÉ×÷½ßþ—›˜~Ê ¼ýç3ZÜÛÖÞ1ߌʼnú[O_Ÿñùá§ÏzÆ®Ið9ŸMô"lz"±}sÏþAß4¯¬¾ €yç ly¿¼êÊŒ÷Çœ{wßëš–g|wÜ?Ý›sÖ7^À‚óïÓž&"ârðž=oAFð6´sîš_§í­D—yk2h×ÍüÆ€VwÊdÐ1ë²÷òìÛÔRA{ÌÜå`|üÊÝ|ôÊÝŒw%%ƒö¸£®$ýþ½_J¥OsU_ÿà…dïTWyJ¢«ÜÈX+R]å)©®òtÛÖ&‚÷§Ý”q/_*hÏ<í0`ËŸ®ãͧ¾k+xsäÒ;rnæË'‚öÑÿHÓ—V]É‹ÿ÷MŽ9÷n^lJ(û¹D^¼ðØržôŠÁ{ý#—püù÷ahñ,x[ Úy[ܵ3.éë.¯›y 8¨ºGÍI\ðd˜\Æž—ïÊhmûÕ–§¯óíºoH Ú""âì®rÛ-îôàí ÑjYz«;ÑÒ¾Ó×Á;Õâ÷Ÿž#""C#h§Ÿï6¼ËêÉiãæ]™ì*—Á”º,uŽ[DD¼ ÚÙÜv‹Û¬†Y—qàõû2.P9ûòœÓŽž»œ½¯ÞÃÇi¨=ò›`­mèï*ôU|øÒ¨e_œ–rÈükؽáö¼§M>áZÞ}îVÞý[æùæÔí`V¶èF¶­½‘­i¨ÍX|33N»™·ž¾~@Wyö9î#θ•7ž¼–×ÿ˜¹ŽŸ^r;†³ÏºÍk®aÓï¿=à·ç.ý¯®¾:ïÅiG-»‹—¿’—Ò.PK]œvÌ?&Îs¿ðXÿj¹.N;þ¼¬ärÖ7^¦‹ÓDD\”¯Um¶«Üؼq]\ƒŒhÓù’34Ȉ)²½d$Ïþ‡uÿ…Ç5Ø~rÚÚµkûy:7ü&MkôÈS¯å{|© Ü"""Z¼x±«ËSàñPöè^Ni2¬ •J0µ¥¬àÊ=í†BÞªA1Œ[܆ÑËÄIŸ§§"•P[·ž^¾Ì“OÜÆ9gOñÕfúwf>7û}®†•yòÍgf=ÍQjmä[f®é³ÿ›i©˜Iw;ëR¬ug'ïÒ[ƒfÓ¾PÅhµLXI¿\yaf[ìOVö™ì–uúÿbeÐʶÛ'Ì”7³ieg?rc?Î÷“ü6S¦ìÖfê+éVh?2[WX©kÜ>à”À=jÌtt@õˆ p°™ùó·óý;VÒÒz>~áSe}´œž V?·ÒÅfužBÓ šV×ßnEdõ(>ײ¬l§“í0Û]]h™¹v~§iì¤\™I¿|¯½Þ—ì”'婨¤ýªX°ËU±:¨°R'8ÝïÍ–íô g%ÀY­ÌÌo7¯ÜÚÍî{^ìG%Ü@+ÁÀ*Œ8Á1ÀIŒ¾µüo,]6‹“ŽgÒ!õ¾é:*å|å²þfZË^v!š]o/Ò9×2í´T³ äûíÁ¼ÎÃlzØ-sv>½8`qc{¼(Kf–c¦Åœoúb­o·ê‡rÞ§|¸G4<@O7ÔÕ‚0€õ`Œ¡§½…Nüˆlå×Mäª+ŽóEF™)xå\ýz¾ÊÌz;É«¿m§[Ñ‹us3ýìvÿú¹,–z›»r3œ¦•ßÏ—rýK~;X0°’Š D"@ð&¡"˜øþ[—?Cãc»øøãv† ¿¶¾ãJ^¿´\‡RùËwþ¿œÖÉÏ•pö¹ú¡P/š×L½á÷ýÊëõ/i‹{Tà b½P]ášj èZ1"ã m‹Nÿ;§ž¸_®|›+¾1§¤GKVos(´³ê:Íwž(ß4›7®³9‹Öï3in Z€ÞV¨ì‚úѰw/-{ƒû¶ßý~çîð’dj¡ûñœ 8bå!ùNð0³.VÖÇ‹´µ;h‚™ÜZ¶“A]¬.Ëi¹2ó¼q«iZ¬\ÙÝf;eÐî -vòÊ­2•+øi€ëë\hz3Ë·Ú»RªRÊ6p‡z~AW BkÄ€V8r6Ì`Â!‡Ó3âÁĵj½$þ·í‡šô|¸—ðH¸ø‚—¸ûÁ©œ}ÖaTWyÛI`÷áòV"(¶,«¿me:7?±º:r·š–f·Ùé²ãÖ²ì–+«•¬•g”;Ýf»e°Ðï˜y×`”)·ê 2´H)ÛÀ]ZM´­™Pªj#BwOâ³`<5§›Ÿüê/…`0ày†[ÙÌ ®av§•©—ƒŸX-ô¹ºšŠ-Ûé€n,ÛÎ@nn“råvšš½ðÑìïyQ ÀSª2å$¿ÍL£Rü3@ŠS®?ò´>°ŠpÛm„‚0rl-FCš›!–¸“X!kŸÅ¢3÷õ_˜OöôÕa8t:ì~—èÁ6‚8✯òµ‹?Ã’Ó§""¥oÉèö>Qy…sþ•î÷!KÞ–œž8Ä1¶ÒÝ ±(T÷±‡ïæÑŸNçííÍLŸ6rØg¤Î=*]DDÛ’xÅ::·ÑÛ ]ÝqŒ8ôß”ÕÌ@E®þ׌´µÃ®÷ ƒxŽùâÉFx°j+^xæ•ÉÔTÆØôÚn×·Ù{#‹ xPl †ì–hú–§žŸÆÈúvêk+] ÚvП/°¹9xˆ•‡ÖÛl¡ØoZiÕZ`ÀÊö9Ms§ƒ^x1H‚Ó´nGZFÝφíÛøŸÿþío³ÎÕ7 N]ˆÒÝ[ÁŽ÷GR_ÓÁ1óƱpáÐ|‹“‡Ö{Qñ{9DÕí³šf^/g¨_£ "C8pÌ?ö0&OžÈ¦Í{’צ™19žŸãYß‘ç}Ȉ¨•$""ÞhlZãÍxÜ"""â n¨µ-"" Ü"""¢À-""¢À-""" Ü""" Ü"""¢À-""" Ü""" Ü"""¢À-""".Ó #"Îãlë ‚"jq‹øR<V‹-R¦‹¨Å-âo¯½²~XlgcÓe¶ˆZÜ"""¢À-""¢À-""" Ü"""¢À-2TÌž· ï/ûóBïEÄtU¹ÈÚé÷Lg¿/ö¹ˆ¨Å-"ƒ´!ñà“\-mmnñipnQà§ru‹ˆ·ˆ”IP6{Þ[DüIW•‹ ±àï|vj:ïQà‘2Þf>WÐñ?u•‹ˆˆ(p‹ˆˆˆ·ˆˆˆ·ˆˆˆø….N)Ʀ5JQàñƒÅ‹+DD[Ä/Ö®]«Dn?Ð}Ó"â6]œ&""¢À-""" Ü""" Ü"""⺿TDDÄG[·ªˆˆˆøÇÿBLú' íŽIEND®B`‚openchange-2.0/apidocs/html/mapiproxy/mapiproxy_hook_life.png000066400000000000000000000307771223057412600246750ustar00rootroot00000000000000‰PNG  IHDR¾¡û¬¯sBIT|dˆ pHYs × ×B(›xtEXtSoftwarewww.inkscape.org›î< IDATxœíÝwxUÅÖÇñïJ½#EŠ"‚("6^,Ø+*Þ+b¯\¯½]¯]ÀÞûµ쀈]»"Š‚‚(Eé%zM÷Ùñœ„@zö9Éïóá8ø ¸Ø9÷ð0Å9w¥QrPyÆwá{ œ´7³á@;àäàx&ðpŒsîým´9!ø¾Ð¸ØXìÿœ/øžïiH ¾ïÔ¹2Ø^ ¼do›Ù¹ez•""Rã)9¨<¯7;çÖFìçœ;ø?ü_훜s3sy%´™|?ôð 0ø?”Ñè”›`fm¢®5?ñ2ð¾—£=0 ¸ 8 Ø Ô1³vfV\ˆˆH-¥ä â~&8çÖ8çFÇž†žqÎmpέÃ')øùhø®ýhSIAÝåÀ€Àå@‚sî{`$p ÁP†sn%ðpððspý‹ð½ÿ ®_0Dqð矾5((£»ÊåÑ£azÝê½æÈaè~{fxô˜ê½¾ˆÔT¦§2Æ¿àŽ‡åιwÂŽ¥ª=sÓ+¡­Ð1­ro¹nì{,ücN%6Z‚»/„ÍáÖ«áýv0îS¸·Kõ]¿¶z ˜£§2J¦žƒšaðYØAT¥`¦›™-4³‘fÖß̇—HM`f—™Yߨý Ì줨ýÃÌį̀ýÿ3³GÌìV3ëû‡™µ«ÞÈ#Ìl'3kÖõkÝÊX8çÖ„Cupν¬1 ·FŽ™-FáçeüìœËßV¥wÓ0hùd „üfÐ`8\ù¤í?0V\l†æO®{ÛÍ6ÖíÙûÀÞ'ÁI!wBÝßaÍQ» ¤üýn„žká½ö0á¸ãÌHùÁ@«wáÂï*çuŠÐX| ‰^|¼œÿ/df#œsÙÀnø‰Ð£—Íì,à `0¿ Q3k ¬:8çþz[:çG•iä)ι 3k†¿Ý;ßÌZôÐÿ÷[;çFÕí€ÿ›¿e|™vÎ-­Ü·§öQÏÄçÜ›ø»>rñs'º×Ÿ+Íl´™üRª€¼Îñoèr+ôü¬9Ft÷çžß–ß­o‡C΂ÕG€KÔÍi +¯„¦ÀéÂ>‹¶~Üö°â*h=ö?òëûwús›Ò w§"å;BVý-Û©°If¶>QUpÐ̺à?ôßÁ¯·R`£sî/`:Ðv+m¾Œ‡9ÀÌúà'EÿËÌî Ú܉¿ÓëˠΣDæ> 5³3Û ¿¸Ü¹fö¿ î£A¬€ín@/à€r¿ò7õT#33ü_ Eö·õUÚ²a¶Y×~ø7†¿}³Ið6äšÙ&üºwß;çrJüG*¤Éëpæï~{Ú×°è `2,<R¿†Ë‚¡œŒ'`ʱ…릌ƒ+?*ÝuÒ¾†‹¿öÛKŸ€™Ã!ãê²Å*Ra¯âï`j‹_ƒåœàø¹ÀPàüDç‚ÄáB3;X|‡ÿ .Ê€ÛœssÍl~âõFàŠ`Xð$àè ìÌmÄvð°ØÏ̶Zá'n¿íœË4³ï€ÙιËúÂeKq™˜ÙnøäŠ~ø”鲕º+á+¿e*òU“ÚoÈÖÿM’ð= uÖ@süQeL¶›ÙN\9Íýv^ ¨3!rî¨?`J‘ጺ“Kô¨ëì7f&Âäfe‹U¤Âm€¹@€™%Y`ׂgÂO;ç†TöûlÁ9çæÛ ðk´ln²ñw^¹ þæ \>é‡HÒߟ¬îÁ¯{~xñ 3»ÿ{¡2~O qšàé/ÄßzWæ'§[4âZ~ƒ_9²À:ü‡ÿrü-žï¿TÍ¿uÒRØ´kdÿ£]Ørˆ®¤5,¢lŒjkìn¾îžËafLj‹R M6d$Cnç .R’‹ðÚw½¼ãœ» ü¤Cà,ü‡|Y=œˆï=è‚_Nþk3ŒÿÝ\p+ð7À f6¿€øõ]ÎÞ:¿ào㞉¿<ë÷¥f¶É9W0D!å¯É@nm™ˆ'Abð~¹èLüÂøUÇ8ç2«>Šv£`ÆËðH_Øa ̺”È‚Uåu ü ^9º} “ϤpB$RY.ÇÿN] <÷å|’ûCT¹ñÿ÷Š&Þá?¨£][°áœ{×̾Á?¬îóऻ‚ù9@ï ÜËf6#¸ö¡Á$ã/Ílp0Î9·Ö̾:㟛Ä=ßS(ÏÉÔ2fÖ ø ÿ h~‚Ô•w‡B´äŸ¡ÞÆÈ~úBÈYç·Ï †e—À²,hù,,OºA·hêLH/úKr>ËO„%;CÊÏpòàȹÎ7Â_ÿ‚ñ'@Ãaà†C௶´Åà‚-ëm†äŸÊÿz¥6sÎM.²¿žÈ²ìÑdzñÏe)®YÅ›Rdþ¯ÿècÌleÔ±‹ikþÿ|tÛEÛ_„Ÿ!—‹ ™Y/àzç\¿°c‘êÜÆt,0Ñ9·¤‚mUÁ"HåuókÐømøÏÛ%—•Ø E¤æSÏÄ… w èÓqâù½!¿˜gVtÿ£úc)™’‘R™Ÿ ¯7>YrÙ¢– ùÅÌh¸v¹Úè1Ù"S”ˆ”Jf*¬¹(GrpË=•ŽˆHÒ ‰"""Rˆ’)Dà ""! žepwØqH•™èœ»9ì ÊCɈHxZëÂD*]ü “qIɈHxeι¯ÃD*W𬉸M4ç@D$<‰”é9"ÕCɈHx’Pr 1HɈHxñ‰)JDD£a‰IJDj¬ñᆯ"ûƒ…'û„C=“”ˆÔXY‰·Cd?¯ äÔ /)†z$&éVF‘˜6¦,l À/Aê*ø¤çûóÏö‚]gBï•~ÿ£6°¬œ;)´¥,4!Qb’zDªÅ¢xäXø²EÙêMÝf=Ÿ½vEwÀ]OGÎϽ~ëÙŸv üuiåÄ,Õ@à “Ôs R-ÚdCÚjó|þ$Ï„6£àÔ P¿„¿ó:BŸÞpì"˜~?¼4É÷\0¾zb—*¤a‰IJDJÍ¥Á»*ÖFòDÈé¹=`Ö?àŽ° ‡#GAu[ÖIœë€® y¬è(9ˆJ$&)9)•6› ÙŠ·³¾q°áÀÖCÂJß‹Ðáûâ—Xd? Ì;¹—9—[¯â1J5Ò°‚Ä$%"¥Ò2®}­bmÜw&d÷€Ô¯¡Ñ'Ð÷3è¼±äzùÛû ß\˜\rö„fús©“aUà¿¿þpHØJ’!1H%&)9©ÉÐñ{¸öÕ²×Mü ~|&O€ÍGBÚhø“?×j4Ì~ í¹!ayåÆ-ULà “”ˆT‹–9Ðvùê&.c.… ûBê‡0ðûȹ ÆÃ”à«¡í#Ðx=, †.º­†?DÊv2Êÿ¤ hXAb’’‘¸Ð{%ô]ü¹îë¡ûÇQ–ùoÍr ßÑpÆ´* OÊK=“´ÎHL«“ )E>Ô¿k 7Œ '©dI¨ç@bzDbÚ…ßß>–“®Y(áHeK²ÂB¤(õˆˆ„Gà “”ˆˆ„G%&)9 z$&)9 A’˜¤ä@D$<V¨!ÌìX3kXB™þf7(9 †jŽLà³­%f68Õ9É ’‘ð¨ç æ˜t~0³FÑ'‚Äà9`+ ™Å%""áQÏA áœË¾v~êÃ߉Á#øg%"R<½?|¶ßÙ ^ên<Ñ^î#:‡E 4!±f lvžÚヺÀBçÜÂc+%"Ró¯é»ûí?„9§Wíõn½>i]º²sNYÇTm<¦a…še þß4ØèŒO òwBŒ«ÌâbÖ¤ˆÄƒŸ¨úkl: V½,®úkU +Ô Î¹f6èJáÏ×µÀ»áDU>JD¤ žÞæÝ ®.4QøÜ'Ãæ6póÙO ‚Íûƒk‰³áò3ü£«oÍ^‡Ìs ¯ Ôù.¿å˜V0önÈíæÛLýN=ÖÁ­C ¿Ly ~Ë‚–ÀŸÀÐ=`ö!§ $¬ÀUïùúùi0øÈÚÒ¿€ÞÿƒÃ—VãV%5ÏHà 9êX20.œpÊGà "µÎüT¸m ~^Ø 6•ò÷Àç-aÎóÐä%èw<ä6†ÜÝ"ç³›CNÐåÿò Óœƒ÷ÎwAªóçr;Ãò  ë-°Ë@ØÔžèÏ¥äÂÁU½¡WÈkï_éÏ]r$,‡®—Ã…'ÀyŸÁ‡maÆ0¨û-œpq24Ÿ‰iýÐä èÛòÂø³*ôÖU> +Ô<àçDû!^na, ž‘¸5?µüuz Þ} f¾·-‚ÄyPwôz^^|Ÿ†Ä9ðßá~¿Éƒðü9[¹€A~ø¹3ì< Îþµðé†oÂSýö½oÀêS€§ýµÈ„·:ân26ïãË5Ë$ç@»àI†¿þÿ‚žŽj<*þ”ïáŠ`†ø”·`áuÀ}¥xƒª‹&$Öß•-»$O‹ìwÞ蓊âœñ m³€[ë@ý×à¦Ç#ç›ÎˆÚþV¶ôÛ_5‡1ïBÊ$H™ã‡\ý­¿„œÖúËÖϧEÅÛ`¹–ˆ)V¨aœsÎÌ>þYpˆ8º…±@\&ιlñŒ{‘Ú¢O&ôÙ©bmÌJ‡ß‚¼°’æA£OáÐ1[&R–ÂÆC#ûSëB^ûâ˶Ìë_^„7ºÂ¯¯ÃÐïàÜIþüŠnÀO~;swH æŒ;ËÏ <Èïß}!dõŽj8ò#»É a}ß²½ö˜¢a…ši$p4PÈtÎ- 9ž2‹Ëä@D*b~* » R'B§kàô饫×ëcøøz¸÷lØów)þ¯¢bïïïVhù8ð+¤ÍäU‘ºõ6BòÏeÝU* õÔ8ιUf¶hGœÝÂXÀœÛJâ/RC™Y 蘅J-uÝ$Øã8å°#)Ÿ§€9›sË*Ú’™}Üàœû¾âqI,1³³€Tç\Üõ©ç@D$<V¨¹^ÚÅcbdfÉ%“J”¯?,"•£ó@è¹ øsãC—u~A¤ZAk®oðãRÔk Ý5¶°M®ÈWÁ1+î¸+\‡¨ïYÀ¢,`EUG,»Î߯¸ÿûÃ`ÖÕpÆ´­—©QÔsPC9?fÿqØq”W4uÐ/±ä¢µÝßI€+’,Ý·bŽåV '|‰EZIb’–O®8Ûr7Áüw‹:m[‘ÚNà “4!±Ô,zcÃ0®˜Ó†ïQPr "…hXAb’z*G1½ÇÔc "[¥ä@bRŒ&/ïÏD-™úl/ÿXÖ°ýýA_dØ èl™”Ðá "µ‘†$&Åè°Â¼ãýã^ Yp$-&UÞ5†uYÇÃ-åxB[±ôE %à ' ""Ó„ÄR0KIRÂŽ£6‰Ñä ¨=î…”œÊmsy{ÿ¬÷r?¾ÕÀJ˜{`QÛPx¸ADD=¥Ó°ô©õ¤–ø(?ääàéýaeÈO…úÓáø/¡ãæ-Ëe¶„ä, jmö1­à×ÃýcdëÌ‚³> ž÷Œm ?翯 kwƒ:³á¢÷ =ß?vUo ìïë´˜g–â¸ÑŸíeí=P^ "…hÎA©u‡D-ñµ iÎA®Á Çá¯×aßËÎ…O{_~Á90ÿÄÈþ³½àËOaÕÛ–Ý ½íŸ6ðÇñ<ô,½²w„¥À}·úó+ëCÎàaÝþkuër¼rÌ=ù›’‰I!õºö‹<ß|ÒP’Ì$˜sÔy'òÌ÷ŒÁðððú9pÃ3‘²Éóà¶Kýö}§Cæmqüó/Xô,Ú†ÜXöøËÝ{ ,AD¢iXAbRHÉÁšC iZáÄ ©Óù?ßòÚCÝ©¾áïºS`ãž…Ëvy'²ÝyœO,~hýæ–;ô-•aîÄì ""MH”˜Rr×R~)_Ý•­ü÷ÕÇÃê"ÿ©’çÞ?jNd»ÅZÿ=«’f¼–§÷@"5™­®@õ(9Rr´²z—\®8MÃ\`»àÒ/˃åSyÆ—±÷@DªÆ”zÐ}}5_t»ŠTvÎ3 [$\!õq7ûòv€ÇŽŒÌ3Ø”sÒJ®{Ìl?$±ô\˜\?r<3 >oYú:ÿ®>|Ù¢l±G+:ùp‹“[ß‘*ðÕþpÃr§_8mS•ÿŽsÎm®ÈWUÇ'R!õ\ö)Üö,|n™IÓ!§;t¼þýý¶ëÖσ—ägàIðÖ8›†Ãu/UàE•¢÷@DJ–ц¦–¯nƒ Xû¬?fô‡[—Cb¤M€ƒž…ô¸tنǀAö.°ކÿ/|~y??4žü'ìû½ØŸ¹#ü~t/|{)dï­‡eÇ ·Aϵ‘v†îóÀ•7C£\§Ý«Á¦=¨;.zÞŸxàdpIPo!,9 \Ü~AU¾!®s0è9æw÷/ºù“púoþÜî¯À¦¨^„]‚ÔìÈþÉÂ~GÁ{úö¸ ZÝ §Îðç÷šù|"Q óZè4ö\9vÇÙðKø¥ ´\R¾×QÖ¹"²uÉÓaÅYP¡Ïð \*¸¶ßr»Á˜.°äÿûC¤¨a]`áãÐäNhõ!¬ß6·œ¿ç†>€Þ+ý¹Ÿ;ƒ« ٭ᎨÖÖBvçÂítýªðþN#aÒ@ÙÉÿA<¦/Ø85˜P¿¾$dÀøÓ Ðٰ߯´3$É“«+1Ýt_¬ðfq«&ŠHÕ¸úÿ—Ÿ)«3¦Âѽ!}<¬>ÞwÝonà¿'l„„¬ÈW½O ñ{…Û9nAáýSg@Òï~ ø^„:ïD–ûÏk–U¸Ý„,hô04êYO*r«~ÕRÏA¥QïˆH|;x9ü0𰟸ü˜ø ´™ó€ôùðŸ‘eo·á›°ê5rö†]oŽœK™YG@ßWB¸ w«ÔsP5¶Ñ{ "â™iIõØñÄÁðQ¿½)òÒÁ–A‡ ~UÝÔ1ùox²¬þ°~mxy÷’Ûîó>ä7_ð½“çz½äÂÛƒüÉðè10³Ne¾Â²PÏA¥*±÷`+eD¤¶0³ÆÀáÀ±ÀDàñp#oe/˜÷,|»H€Ä¹ÐîæH÷ÿ‰×À{C`îKp÷F ÉÏhs]Ém÷Z›¦ƒ Ÿ;,œ 3ï… _ÂÄ•àBÒóM¥¾Ä20hÕ$†@ÍS0!ÚÎEmk€Ñ›œ[‘Jh€™µ€ŽipQØ¡H\z ˜³Ù9·¬4¥ƒÞ=€¾@  þ³‡sWWY˜5ˆYófð¯:UÿÈæE)0±´Y {­Ùz™ñm¡Þ&80£rï‚ù©Ìk íWTçäÃ-=‘—ë7«áÅP#mëg%K+¢‰ÔpQ½ýƒïé@ °xÔ9wMHáÉVµÉ†6óJ.óÏ¿ªæúû¬7)ˆHrníª°ƒ‰gÅôìäà¬mð?çÜõÕ¡HÙhΈÔpÏô†Ì½á¦G+»e3Û¸8(ž-˜X”^¤x ô0³O¢ŽOwÎUpñ'‘Ê¥ä@Dj¸Í k§ªhÙ97ÎÌrµÀAÀöøƒº[©RxŽÈúÐ;ÿ®ŠØD*BɈH8ç~~0³ÀaÀ?€£ñ½ ©@Z°ÝxØÇ9·ØÌ–‡·È¶Äer`fizÔ©ˆÄçÜZàíà 3놿eñd +´&šÙÞø¡Ý-&1'.“üß½a!"²-ι©ÀTà>3«‚ŸŸp,ð-pñû{¸åãÔÑJ³ÕbµÅÝ¥™Õî4³Çœs›ÂŽGD¤4œsë÷ƒ/̬ p ê9(…•«á«˜YZ¸6ˆ»äÏp"~òÏèpC)çÜ 3Ûh½ƒ8çrܰã¨MâñÙ gßO 5 ‘ŠËE=ƒâ19Ø/ø~h¨QˆˆTœ&$JLŠ«äÀ̺ù”dfÃŒGD¤‚òˆÏá]©áâ*9Àß;\ðä&Àñ!Æ"#Æ6õ›¯wõ²•RPÏĤxKú‰985ÄXDbÄô`á-aGñ׉ð×?ÂŽ"N(9˜7É™5Z9ÜÎÌꄈH%ЄD‰Iñ4Öu8~Rð+b$àã?ø0¬ D*ßðá÷¡ñûy $,‡6OÁÅ_ûóóSáÅÁ°ù0Hœ ?(\ÿÆ`»ÿÁÒ‹€¸ë˜â¯“‘ ~-ƒŒ‹!¿)4xn|ÒŸ`d7ƒŸðûSêÁð·àÚ¾Ð(>2O‡¼N`k Ý¸è[_Ö¥À;aó!6öz ú.¬ä7ª&PÏĤ¸é9NêáŸj¶ÿà’FhhAjœÍé½?¬ß?Z¼ ó€Üài/ÿrv†=OƒîƒU箟» dœ;‚~§mý:Y Û–Ÿû\ ÿkÏ‚‡Oðç³›CÎvQq%ùò¹ÀÔº1º {ö„#@ëy‘²O†?ÁñÇ~.çÃ…Fv‚;®§÷+¹l\Ò„D‰Iq‘ÏJ?X¬Æ/?º8*ÄÐDªŠÁáÁ!ËàŠ<ÞÕŸÚp"4 ýgÁù?C½÷·¬ÞüU8{ 쳺äKµ| úÍ…u>€'–\'ÙùÞ%»Àäúpðr8!*9Hþ®~z¯„öÃaÓA%· >éx¨Üò,Ü0&¾ 9-áÂq¥«wÔsPC™ÙqföJØq”W¼d¬»ãŸ‘~¸sîg3Ã9÷£™ |af]œs3BŽQ¤%døÖ¿÷WÀš°iä7ƒ¶Ó"çêO‡õEîÜé4¹ô×Ú!º­ßay)þJï¼: „yð;àíÏ`ïûá¸þ|JT›MW€k¾íöžÛæ ÜÎú½d!{/¸á«Ò¾š-¹ºòSùëWç\¾™ÅÅiRf‰@JØA”W¼$½€>ι_¢ ¡ø…‘”H-ž Ë`ÁnÀ_þØÚ]·,—”_ú6gï ,òÛëºCâR¿² 6u”û¥[ázÿ UüS#øð6øùb8î†Ò_·h[ãOƒ/΂½!¿ä7² ñ Ðñ‡òµ[ ±Öå)ƒxI^ Z²… A˜ZÝc& wpIDAT‰„§î(X~¼ö'lhúxZ]ƹ0bd¶ÇÁv·úã»…/Á³½ u#,¼ Rçö0· |h[$/. ½VA¯GGaS ßæõ‡Õ§Ãê?ƒd¤&rffÎ9=qPbF\$[K J{^$¾Ô])?>–òÔ æ\ð0<“SŸ€Äù°Ýý°ò°¨²ã¡nVé¯×r(L¹òC£gàÊüñ#—ÀïC`Þµ@6´}¦E~mdœ¯Ü¶Ò¿ƒ~/úã©ó(4Ž^o3$—±[?=ÎLòûóS·Y<¾Ì;Ѓ…$fX<&«f6Ã9×%ì8$>™Y 蘅JÈæ§ÂÿfÂi»BuaG?žælvÎ-«ŒÖÌl-ÐÜ9W†„Nb™õNqÎÅåCã¢ç@DÊë—0q+K5©zc‘­ÐBHs”ˆÔhó›À’#·Ða–á÷ßÜ æî – ;þÿ˜);¥|q(Ô_ª¾×$1@%æ¨ç@¤Ôæ\ cƒ™C`Ãî0ù=xôî÷60ÿ¾"寅©{úí»ÿ“ƒìæ°¹üvV¤œ« #†Âš}á¯Ap˳Õñj$fhÎÄý@Š”MÜu’ß|`,¹ø¸äj뎃6÷Â%_oy.¿t=Îþ¦×…—~ñ= Ý×—/Ä_ÀØÞpÀ÷ÐsmùÚj¤a‰9ê9)“:ßE¶{|ù­á»¦%×kô&,x? Oö\‹œKÈô‰@× °ÆïZú˜r ^Ù n7 ‡ß@NC%qCÉÄõˆ”‰‹ú?“üBOp˜ $.›_?²}íkðùg0áxXxÜz:Ü~?gŠ\$òKø¿™‘ ¯÷…gBîàêùë[$ý ëw‡!»—ãÄ®I’ÕGs$æ(9)“MûCî#äà·ƒ!aô^ ›VÄDø°-ô]è¿çu‰ª—à'&ö¼ý9üø!¬«ÀBËèú#üÔòB~>¸†à¨3­b¯³Î4è4¿bmH)©ç@bŽ’‘²ÉAAÒ,È:Ú^æ§çC÷á»á0aät‚Ä¿"ÕnûR'@â*Øt Ô õó*ÊÑ‹áè[üvF2¼µ,;²{¦`ðàŠµ/ÕD%æÄëdc3û p1òE Ä ×[ü×ïιrNì+N“‘Ðz*,Ù:<\øvÄÁ·ÀÈN°dG8ð{ø}{èÜÆxЙ0£ä§@¯Wàð¥þøÞ3 áŠÂ×èr t›W¶¸Zæ“¿öû£[û‰‰šwÔs 1'^“ƒÝˆüg²ðK¯#¡½n*19€`mƒÅŸë? ˜å·{Duí¹ÄÕ}=tŸTøØÙS*ãÑ‹+Þ†T%sâ29pÎ- ;©Rf@åaG!5Ž&$J̉Ëä@$ƒî ;©‘Ôs 1G눈„K%æ(9 —z$æ(9 —’‰9JDDÂ¥ ‰s”T3ÛÃÌîŽÚßÅ̉ÚO7³‡Ì,=êØƒÁ±Óͬ¾™µ0³Óª;v •z$æ(9¨<“Ìì€`ÿBà„¨óÿöþuì@ü}ø-€[€ÆÀÑIE}3ÛÁÌêÇÚ˜YBT™f¶{P6ÑÌššY«‚òQåþ®gfIfÖ$(×0ªLŠ™u7³ÆQÇšYƒò¾1"²Mš(1G?•k0ÀÌ&à?è—F;8xx-8–çœ[¬öxýVÚ<¸øôFÌö0³ÿ€³€‰ÀÀOÀøÇoofÏ9ç>5³Å@73»X¼Œv1³[€ÀР®O˜Ù5@ ‰™uΨØ[$"Eä÷˜Ùma"•*ø ì ÊKÉAåZ ´Æ'ïÿ0³ÀjçÜ3[efss€Žf6ÈîÝF»ß9çn6³ƒðÝÓðÞ§à?𳀱ι_ͬ °Â9wµ™53³Y@NÐÆ^ÀéÀÓÀlçÜͬÐÿ™øøÒÌ’ñ½â{™.ʈHå(1¨™*øü”ð(9¨|ï] ’à`» hìæ8çN)¨hf;o¥Í‚ø4Ö«qÀbçÜL3›œcfÙÀãÀÆ | ¤GÛÔ ¶ß× œs˜Ù@|Òqpþù«ƒr·–ú]‘RqÎåâ'%ŠÄ %•o4ÐÛ9—mf˜™ÇÿçœË Æü¿ ºöËê#à| þƒ¿ ¡HÂ÷&tÊu1³+€]ι©fÖÉÌÎŽÄ'[0³=]ðÏèåœ[kf?ûSÀåˆ[DDâˆ9çJ.%% ºðSs £ŽíAð¡íœû-êx7ü¼]œs¿DOÚ;çfDk´»8Ø7üDÆt`,Pø?`ð#Ð ÿþËÀRçÜŸQõúSœs+Í, ØÞ9÷§™Õ ê-öÃY|ëœÛÔÝ èŒwÎô6Ä-3kÓࢰC‘¸ô0g³žñ"5™’ƒÆÌ¶®uÎ]v,±JÉTŒ’©ù4¬PÃ8ç–J DD¤Ü´ÎˆH-¬ÒÏÌE;ÖÌZFíÿ_Ð3Y°¿OPg`Ø3;°z#—ª¢ä@DDÒ€€sáïùR¯{û©À³^å" ·}»¯šâ•*¦a˜„¿3 üÂjÑkšœ<gf)ιìàøhçÜÒ` ø”¢ wg}„_æS 8?¡úiàà üªkœs×™ÙøÛ«#so™Y༠١ι¯ƒ[ÃWÍ—œsšÙõÀö@}àßÀvÀ%ÁþxçÜÐ ¾Gµ†’)0ÙÌöÆ/é>-êøiøõYã€QÁñk̬ þî¦ì`t!š{mœsyfö¾w"¿ðÛ  ps®`=•.Àü-ÕŸo×'á×]yøÛõ!À`$¾÷âpàçÜ3» xX€N›"í>q04Yy 0ÿ HÈÝ>†cEÊd¶‡ôÍÀŠÂ±Lí+{BÊ28î]èºÁŸŸY>8Žú¾ÙÛ—é8NŸŸ·„_Ž„ìPgœõ!4Ë…u‰ðì Ðöw03*¾ƒ !Ný^èݾ‡£GÎg$Ãk'Àîcá°ŒJÛEd›4¬ š\ƒŒàó»`î}µ#,yž w^sî¬`ÙðàÝ‘zÃ÷…yƒ g;Èk™WÁ cü‡wÅ—ÃÔ[à·aÝVŸß~#;EÊD+ÄòÙý0ÿ~Èm +n†WGÁ¬t_fv#_fÄ0ÿnÈk ÂK=à³OaåÅÓ2ÞññÔσÍÛäWáû&¾'ûÀ¼ y4Ê…•'ÃE–«v$,» Ú]žWDªzDBçêÀMøÒ‡‡%Cê¸ý`Hrpÿi°üvȸ ZæÀ)?B£##õg¥Ãsãáݵ¯FŽçì Çì}2aQ <ñ&L¹ú_°õXò›ÀÅ@»,{?|øŒ<nx¶p¹ëðì7¾ IÓàò³||_Þ cÆÂÈóá¦ÇáêÇáÎ}áã‡aÝõ0ïahô œàë7–Ü ³îŠô~džéQ½"RÔs ºFïG† :ÿì¿7þÈ'~’`BË |.¼×î·Ý¯_ +aSçÂí&ÿäðÃu¿€ìý¶KÝ/|bpÀ ߯†"uš|I æ§Bnhð‰O YÉ?ÂÆ ^z>~9ävƒ¯>‚ä_áÚ§#í1, Þ=Îï¿×²{C§èëˆH5Rr º†ó"Û-ƒnô&QÇš®óß³Rü÷ÿ 㾄 {AÂfHŸ ¶òn7uFáý€«sÒ¶Kƒ"uRg@~óÂÇ:þÙžÖ0h6µH½©ß2²ß'R~‚ü¦ÐrX$ñ?7¡Þ0Xy†ßŸr*$M†3¦m=N©JJDâÎÒ³!í#¸ýB¸ùA¸öµ-?À6ï^xMw°ÕÐqóÖÛ^Ó½H= qIác ù‘í½–ù°¬g‘z=!qadÿ¡!ëH ‹nÌ?(°ç»«Ÿ¿°¡?4y ’‘¸“° °Èþ£GA~Û-ËåôŒL@ß6iŸo»í ‡G>¸GîèÛh°:Ír!e,¬;¾k꽺+äìõƒz£v€Œ;¡ù ¸þZHœ ?ä'A8z1¤~ < .Åß}!"aÑ„D‘¸ÓþU˜ù*Üøžßw åë-Ë¥}GÁ¯SüäÄ„ èýÀ¶ÛNýÞû>þ²÷‡”oà_#·]g!0ñ%ø`Œþ röÔÏàü×ýœ„ŸŸ„´Oàš7}ùƒ/‡ÏFÃýá†ç"í´zæ¾u_*|[¦ˆT7%"¡IrÐiì5¶ÞiCpìÏȱn«`Öè¬pþD˜¹'||0¤l€>`FKÈ/Ò˜6¼~Û’^…ÃÆžý¿óÐnqá:mFA£gaþPïI8ëG?¡ {&,»Y8éŸÁ.G×ûÀÆ–Ðä^#ÀøúÐaòk¤üa°áDÈlV¸FA»]^/ñ­‘*eι’K‰Ô fÖ:¦ÁE%Ž[7½u?‡Ÿ(]ù\ƒçÂN'ÿ~¬ÒЊµ.î{,n‹ñ˜§€9›sZ]Rj,õˆHÈˇøÉ’œv4"¢ä@¤†Úÿh\†qû${{-*¹le;èXò=· ú¯-"ÅQr R#½¸ä2EõŸ]ùq”Æ^k€5á\[DŠ£[EDD¤%"""Rˆ’)Ds¤–Z |v—V‡€H•Ó:RëøuØÆÃ‡DJ¤u¤Fû£‹«AáÇIEND®B`‚openchange-2.0/apidocs/html/mapiproxy/mapiproxy_logo.png000066400000000000000000000217631223057412600236710ustar00rootroot00000000000000‰PNG  IHDR``â˜w8 IDATxœí½y”eWußÿÙçÜá5O]Õ“º¥î–Z3XHÉ‚m°<È;D¶c2¬˜pˆÇ!+ùÅCŒ‰ƒ!q!rlX$6L°…Ah@“ÕB­n‰îVÏÝÕ5¿ª7¿;ýûãUA#Ô]%uµp׺«nUÝ{î¹{ŸóÝûì³Ï=¢ª\Æ¥ƒ¹Ôø›ŽË ¸Ä¸¬€KŒË ¸Ä¸¬€KŒË ¸Äð^ÎÅ"#Úr%èV~ å«”—wþJîy9ç³lhd8 z\u®ÃË€¬u 2Rî½$ª Ë5ºó ½µó‹Yö7+èÈ#À³ª³nMr]‹D†·? ôxïz×ÛƒŸþéwŽ^uÕ¶-ù|nÜS Kg²|¬éáß0t›¿Î9×l4š³û÷˜üØÇ>>ÿ§úçÕÅÅ¥8|Vu®µZ«*@d¸òn ÷Þ{¢ü+¿ò¯7]-"=|Cè¯""ú?WÀ¥iVá…#Çé—þó©O|âS3 O«Î}vµ›ÏkºœÏ@ß{Þó3úп¿: ƒ-€¿|ÉwkKÙð<[ºúê;?úÑ_í- ÁüÁÿr"#{UgOžï¾óö‘áànÞ¼±÷+_ùÜ•vy. Õ—Cæž={çî¹ç'÷œ>}f/ðIÕ¹s6ÔUÜP¹Ƚë]oÏmØ0ÚO·Çd@º‡ˆ¬[Yß&Gø;w^éß}÷÷‚l)O«¶Ü}÷÷嬵9º”“­ã‘®sy߇+ ö®»^_¦Ëcçð*ãíïé)y;vl÷UÕ ëH?ßùö÷%¡"b¯¼ò ÛÓS²µZ½ÿ|¯¢É ôûår qªš²Ž ‘ïF%(àz{Ë®¯¯×¯Õ¹ó]¼ÚHXÂ0X¡‹?ÿ2Î 2ß÷3cVô¬FAÔëÍèœÕú/SÐù¡@œeY§^o¤Ý_ÏÕ(ˆz½ž‰—v™‚Î’$Iãz½‘­&®Uƒqqœ8  Ä\¦ µ@8IÒ8Ž“U[ת´Œºªv¸ÀÐ÷”þeû¢²•®Û{öÏï(EQÔìêÎU)hù½Ëäs pŠuä­H^Q_ÁÊ7Æ$"݇–Ç®ëĪÄ@Ç‘t}îoG(w:Që›#¾/µÎԀ𠠊Ä)ùvJY…b„O»ús–¦—±ò»¬éÆžrN!Í”Ô)‘@Ëš"$/·Nh7›­PXíâµRPCUc^æ@Ì)¦SjFôeJÁxžQÄ‚³ª+Md…bV(nåÁ/nå"`<ÁG°ÂL)¥O¨y†6—>@耨Ýn7Aó«]¼V j-SК Št Õ¦%Nò*Û%IS\è‘9Ί¨vû€0rn;³b ]Jò ˆ|k1N ;mÛUDC."×ëh=)¨ Dt=¡óŽ.Ò ¯ÖÒÁ¥–ö9ëy8ßCÅ`|‹šî”†,ÏÚ¬xUñrÅ=Ër™î³Î~ÞJ‹h¹³ÿhQK)픜/,ù–¯¾ñv@ÔUÀêX+5U5¢KAçT@»ã ‹ F;)ycȬ¤Y’Îy&ÍÏG‚Q ¢Š*±j!p]E¬(@4µàÛn]ÅA[ “n/г<ºŠˆ=Â$¥?M CKżº6bYÍÎzzAíe zÉ ŠÔ[®±ÉH”¨5ĉ“$Í4Ÿó $ï¡ë-¿¢FTDÕ€—)zÖUÔȲƒUX\~»Ìƒœ,+k¥ +çâƒ`Á)a'eØ •У¶f^W*•ÎzRP‹.}KpŠ©TãÁ™J<ØÛW¤à›¬ÕÎ4NœcPFË©5BÛŠQg…Ô úX5di†ÌWTÑ0߇\€:!´B#géˆb¬Á%ˬãK×v,Wål%„V… “9úZ 6ï3ÿ*ØDss ëJA­—¢ çÔÌ-%ƒ­ˆëyYõæÑ¬liGVâTI3U1F<u™fI‚f™b=!M,% ‚îƒÊEL³í¤Ó:m´ã‹手X$Ë+´ðCŸüÌCoüÙT¶mD³T8xò0›FsŒl,É_wÙö!œÍ‰90kµ‘ V4íÁö—så?ºÿøys9_–#똖rvF6›Déñ §xeÏHhóA@àùêKZu­4PÕ¶6[‰lÚÐï‚\ A–šv&:»Ø¢™ŽM.²a4fb´Ÿ úú-â{:dòñSzë÷ŒË¾Ó¾oÔ¬tb§Õf*•ª¯[6†ÜýÖë便 ©&´;±<ùÕj¼]ܰ{GàÉ™ôÄÁgÇw,µçå¦Ý1;w°çk'eßS-òôA—^½ ïДjÎKõu›}¬¯Z.sf2.ÿu6ÂÿOoN~ü}µ¿ºPŠÓâPi"/{œ1VÍÔÚÄuâL+‹u͇\}Uà®Û>èîÈs§uêÌ´~Ü;sÊåf'jCý¦¯§·¼Ô?8RoÔ–†³Lõ/80ûŽ·]íî66A>G»^é[ªµzKAÃÈÄì¼e»,U>ÿ¥ca'q ßÒûôW¿V1ÁîÆ Wº´zã'ûGû™«¹¸%¥‡ŽÞ°{`þøÁã}×ì¨äF‡u#ܪo¦Ò*dÍÁ¹Þ¤nÛ:¾¸a0°{­Íÿä}¿å/-,N}â>P¸ãö{·Ò5¾/%`3]C; œxøÑûêwÜ~ï °8øð£÷­9Ø·f#¼‚OþæßªÜó³_xPwÛÒbkÃàpŸt¢Ìøžd=ù²ä{òT曜>ÝÒ™…Ľnw¯»õÚ¡ôΛwȧ<£O?ñ•ïk'Óo[œ´-p9#¢}ýG—*‹[œsᆿ<6:ô;·ì(Û|èv©R¹Òósv³61}ë÷þ÷kwßøÐüéÃ÷ Øc?¨†àeê-ìÛ—}°ÿö×sîÀ»<ßbÓ·þêâ©É[ûüŸ½ßóÚË2»7â[î~Çfâæ'|îÏÞ¹tbÿ­õ¢Çwmzæ×~ãçýO÷c?ùà—¿'KÓÕôw½û—øòïÿp+ðÛÀû€»«€þøMà?¿üp ÝÁ˜®«>Ÿú­·,}¨µØ84;[é³×í÷Â0°ívf¼0”Þ‚q‘yhÏ´ù¯Ÿ<â=¼gŠþÍÍ× XA½·ýð÷ÿÎ=?þö_MÓ4o­‘øÞŸú…Ý7ìüÒô™ÉïmKϳG:ùMÃa纛où;®ýÏÏÍ;ôÜ›çëÓhgÆ1šÿõÉdóÏ)ްsü<öÔWm¬êáb»±·%gNÍû†|ëïŽÜþSÿ¤íJ‡ö|þÏþéÔác…$ʼ4ކ†6n}êö·þÀŸ=øÈ3W?pÿ#ÿ¦;îüÝ›ÞúÎ óù?IãøCw¾á§wÿgYØÿeYÈÿæáGï; |øÁ;n¿7Ü<øð£÷5¿!¼ 6ÂçÆÇ~í͵0ôÕfý¡V-ªµ[‰Ý0Q¶›6–Ìæ‰A»c×fsÝÎ óÚÝ[ìæ‘œ77Óñ?ùW“„¡'¥žÒì•W_uðŠmO{¾×غ}ûžžþá¹ Ǩsþð¨øÍ,ç¢Øö>ùÈûN>÷ä{ÕEív+_.:))— ÓwÝ~íþ´Ÿé¤þ«ííÍjµP­ÖØ4>ȶ­£TêÆóZ·}ß-mÞ4<å7>ÒnÔ7ôÒN³ ±Áìÿ̽ÿ}èÊ=ú•g¾G„ìo»ë¯6oiaî€P]öÚ‡½/>L—1žþrY ®¥ÛCvŸ~¹r|Y^Ћñ¿>xGòÇz㡸Ýù\eræPw¤·ìÛñ1ÏlÙšñM%Ó?R0=ý=²Ð¶Þ¾ƒ ÞR#Åã‚ÀˆxXAB“¢â‰é6k`ú̾[ö=ì ?ùÎ7ýöûÞûþé–+6=ÓSò¹ñ¦²ôöDQÜ31Z(nèABë†EL£ì™Ø¼•þ¡Aª#YšÏ=?=ðŽwl—ž 9¢˜èØtÚÌûàAãôB?U#(Î:§ÁâìüЦÍc¹€EdöŽÛï5téÇ- üMË"x¨ïêÀƒß,¼uö‚Î…O|ðöúÏüòÞ/O›>27Þ:¶mcÿ¦‰¢ŒŒ„€¨Ø~}ãã®ÝQóÈï73S"ž‡ÑhYà"’÷Q—`Ò)KU@{òÀaîØÍ‡½sxdà ‹#ÐéÄýŸÿü_}pÓ†°27—\¿qÓŽÿ¶aüúäØÑ‡O59YFzsÌO»Üç÷÷>¸÷þ±Ãnþø-IáŠO¯ù• ÍUXjúlt\wë¾ü̃Ýó?ó·?:<6º¯67}£ˆüe¹¯ÿ‹µÅÊ÷ÿxùçGî¸ýÞ×.ßÿ üKà~ô¾³i¯¿t>üÁnPàä{?|p¦³X»aÒ%×¥IŸ×ÓW"_Ĉ)æÑñMãÇóy•KÖh^Ý 7íz`Ó#§ ydbbhòÚ¯þ|oo>ºjÇî½Æ¤ÜóÔ±ëvNôÎ ßþ;s³õÞȪQrOñÄmwÝø™©S3Ûßúïûô×íÞ³ï™YžÝŸ>¹Ô™jdŒ ˜7^£Yºæc'&g®¹æõoùðWNnz@SѦ}¦w$˜Mñ4Ìç¨6ãÖ¯|øßÿÇü…75+3^ü|ÿ`ßÿþ¯~o|Çí÷nþð à+À{€wÜ~ï3Àýt{ǪKR_ /Û Z ù¹ÑþàÔ_{VOÏÏ-Ýô ÷•$QÑÀ½ñ5×?×ÓË^+¨±ð“ïþ¡O§h‚ì¾vû‘]×n!ðÈ‚½ëÍ7=yÕõ7>98é÷ôÐ4š÷»±Ï÷âïÿÑ;ÿRõAo»eˆO}®tÿ™šåôl•+úJ¨âšÅVÌÕ_¸cûÌ骄õÜøàu·ök_ M2's‹‰+ß0T»íîþÔõ…O~ê‰g~þ½¹ðð£÷ýÆY¯xø9€;n¿÷ï¿Lwaö¿UxÉ Z ¿ü3›ôßÿÔæ3½åð³KssÇŽ™×ᲊ¨J.‡q)6`B‹É…PñÂ?‚×,!Í«È`Ù0Û²Œ–TÄC\7ÝvÝoyÛëÿH30¼ ;WV(¼õ-7±mc?cC°[÷mzÍ›>܈:±Í•ØóÔFëdœ(Yf h´|µÈihS4uLŒ®¥õ= üðc?z_ý[…·º´nôRøWïm}äÓæKSÓ[ž|"½îîÜ`¦"« ž3‚±Šs‚Ïzh¦dqJ–+ =&çD’L5çwÓU®¾nû‘ )H¡½eÈ"À ïø‘«Øºu3ñx•Z'?ý=o~ãôC¿÷ÖÏÈü+·óÜ‘âyLWê¼±gœù¥: ãäÌ|ÄPO óµ6£ãC«N¨<üè}‡€C"£ ò‚Ö‚÷þÈp:6RxìädeÏ'ïŸcSAÅW5ša<<k8Gæ‘4Åd efzB%ê.‘l9/.Ë ŠRYH9v&‘ÁeïSO35Ó|®L9gqFÅ„×ì¤IGà)z)ÎäÕZƒSÕRÞ0=ßqQzÁKwÖä] z1ÞwϨnÙ<ðtµ²øÜ§˜g¤¾Å„6Äbn®h>Dm¦Ö$—Ãzf«)}E!É”d%åI¡T²X‰9pà4â:|â~rèÓê¤4;°i´ß7ÔÛÙ÷ìaµÆàû>ÐŒ2:qÒÍ™·‚5Ðh¤1N/t²þâÄ^.þÅßw7žxæ«'*‡Ž4Î#¡1x˜\(& kº“õV+@†4#%·œÊø¨Îu{że×Î~®¼¢ÌO¼óo1:2*ª> •6›FˤIÂb¥¥3“×QreC«ZãÔ|‡z5¦ºT#ç'8稴:ÑÛnU²«/:ùw6Å;·÷=þçLf¾sˆŠ'HÎâ…Š!b,bm÷k*ÎVéó¥Ñë âºÂ·èrÊK¾à12ÜK„Ðl%¨ªÀR­ÅHÍ Y2׈Š»újœiX* Á†¾ô÷úôõäI’TRe懿M(èlô”‚3Õ¥ÖìÑÉÄõ¢(¡ ½/4´ˆ5àYÔxÝ”+à¡‘ ©C4ñÀXÔ9ĥ˱pÝÉܾ2E”‹Eš==ày>±‹¥§¯Ä¦þ”LIEH%(['J¸LäôL[J…`q^õÛ‹‚VðóïÜœõ–s§ö®j ‚ÁÓnºsà—ópš‰ ƒnjGÏC=ífO‡>â/ÿÏ÷ vÇøìNéÞCS´Ó /2¨7»Yº¡;ºëª*õv†ÑŒ‚çê ˆã˜3³æ`o®ýjÉãU¥  ”X˜[LHE Ú]û$ˆ®äk†ˆgÁ¥Ç0X(dËÙŒV Ân¦sà{ÊáI!+Œ¡8zzË:>4ˆdVkê`ÉrÅæ!ŽM9:qŒÍ”À:6…¸ÌÑjŲÔL§ä¶ñuÊz•bA/¾M?ðTT…L4 D³n†V Î R Ñ$ƒ¹9€8C[ÑrN1DQ7=ð»#aM`v!£ÒÎS*0àg˜ÐRo/’1Zrlë£Å4Ú†Åf›¼G¹(äCœ¤räd%ݼ¡gf^s%t^Z‚.Ê¢lñò¹­!±-‹jäIM—Ò¥("%Aqh=B· £'ó ÍD4M—﫺DI83/:±¥Ÿ›w—(\\'ôZDqë·ø >'æb*õâŽrBÁϨÖZÍHªõôÔ½~½½½\ JC×ï(PIp‹¦HšJw…[ö0tví+ Ö@3ƒÐÃV5ç«+äU]õdm$qÈà€åæÚD›Žj³m4ÇÆ¡ŒFª|õp›Å¦ƒ(RcÍVÚHž?Riõôä§Öñ5/],è|ø½ÿ7gúû©øZ­+N%µÒ%KETUm'hÁõ£ðÜ4ÚMÝ |ÉŒTÏÇ=Ѱ(Z*¢Wl€±A¡YÏì³LäÙ¾-¯ûNyºç@Æb+ÕÐ¥8ËFJÔ—ê,UZZ­'‡êû·¬gë¿0/Hdè¢ÐO«“&&zóÇΨ†92„Ì .SUPçƒ&ˆ;:^5ŒZ꺦¡§6—#1¦k”5CsöË(à õ* è®m–ë¯H°¥!}îtÄþç©Fm¼,"v1=9ôéÉGÒh'æù#‹'áï_ó- Yë„óÊñu’¶XúS#=ý–Ë;¯‘cÇOK9¨$©úõ÷\1^vM6àUwC£Ä5ê¨}ìt§xã®ùÀ—>KÚÉàøzån¡…Yj‰×›ÓÔó%Q§àD’õSåÔkš’<_÷¸(6àÿΆtfjé艳'pº¦<}J)xÐÉ`)Õs€ãbL‹­6 ¯­ÕT~¢Î#ÏÌsdªÉ Ç—äðÔ Z‹Œo*ÉÔä¬mTOÊÖ11SÓ)…>ÃyjTnͰ]\X “ɤïyÏþán}5n¯ÔÀj>ì+…—ËØy…™xøñé¾þ¾@Kå‚9~2q?ú½¾~ññX"ç38ÐLË9“eâI'óé-©ÖÔ|á‘EÝw ÂÂbM+‹sÚh×È’Œ›ÇIZ™œšœÌ 6Ó×ìÜÀ‰“ 4²@ŠÆãÎ׎133•tbyá¿r×ôÅx¯aeüŠÇ«ºP¯ïûXTÍcã¶ñøÓK:9›rìXÅ´Z){-éƒOM»ÏÜ¿ä¾üDbNLf’të)üâbMÁ¸µ|¸õ¢ö‚|ô箃?ûû_(ö µF2Ü[Œ{çg*¥Ù3ifH§•ˆ¦v”xÆ%c…¸xÕXl£ÝI*±ËâÏôû_íï­† é¯þ»üÖû¯utH|}‘Ä{?r@â85ž5â‚õlöÀï¿íÛMÐ/ÆÊ@ìBz€\%¼yﮕo0|'áÛs ö72XY¤=l׳FC`—¿!u^Osµù€å¡úùw¸Œ—D‰¯›ðÜX‚VrÐF׫Vƒ0BW†íóÍ­œO Zé^£;×»vßÍ.›—égAuþœžÌùà@ŽÈN‘‘Þu®çw1dÐÒæÎwåù€;ÔA{@oYÏ*~·Bd¸zà=ïnzçT€ê¼[Öàäu"#7‹ _Þõè _~d”î§Ëöð ;ú’Xm>  <²î–V?ìytRuîÛé«å— "#E`pÝÕòøhUuþ¼iŽkØKrhsp hÎ,ۈŮ¢d¹ ³Gßk9%÷¼œó‹V¶J £ [>P$ÝTVÛÞv- °ÀH˜^»ü38ïß]8—ÎnE5à0ð4h ¨©Î¯ú¹ä5ng;$ ½@™îG‰JÀÐòß¾uCç妷jkZþƒêYÿ“—Ñ›dõ{ÏYÆ‹¯]­Î/~G¥»¡sX »`»D K«QÏ Ö¼¡3€È—{CÀ7ï!üÝŽ¿£žu¤tßT_uáo*ô•n#%2¼"øuTÀÙu9W‘kaƒWúœµ<ÿ›.V@Uç^qÈø+à2Ö—}úKŒË ¸Ä¸¬€KŒË ¸ÄøÿY[ª¾iÖ8àIEND®B`‚openchange-2.0/apidocs/html/mapiproxy/mapiproxy_overview.png000066400000000000000000000672261223057412600246030ustar00rootroot00000000000000‰PNG  IHDRƒHÞÿÐsBIT|dˆ pHYs × ×B(›xtEXtSoftwarewww.inkscape.org›î< IDATxœìy¸%Uuèkï]Uçœ{îÜ#ƒÌ“ *2¨‰…8¡ó|qŠÓSã£/&ãDœ¢/Ά 8%È " €ŒJÝôxÇ3WÕÞ{½?νÐ4Í ^Îïûê»§ªvíZ§Nuïµ×^ƒ¨* 0`À€™˜¥`À€ 0`ÀÒ1P 0`À€Á ”Á 0`À€G0n©°ã!"ÏÞ¸Õ¡w«ê϶Ónتú«;éëãÀÁ »]U}æ-ßêÐZUýý}ìk`·­ýJU[÷G¾Dä(nO›ªzÉ}ìg8t«C7¨êÍ÷W¾îŽ28ྰ3p,ðY`0µõIù2p$°ç¡0z'}]Ì/äöõC·°U€Œ¾…=FE/B ôP¼ƒ­ûǾÀO·Ú?x+€ˆT€gÏVkŸÿ¨ª³Ûôõ*à[í üúÁ{À#ŒïqÛÿq¿f+…NDž œDÒ» h¿>œ¡·â<˜Û¿ïï>ôà‰=`@D¸·ˆÈ€SÕK·s~ p5ðKàEÀˆªÞ™2¸xÍÏTÕúƒ òý"*.˜]V©2a„1ÀEp b@ (ýý˜ ýÿôçCä#ÌZ˜1B¾´ßfÇBD.Þ¨ªŸØæÜñôá-À¯þ>X ܦª›·Óç_UÕ‡«2XYØú—¨U "”…*Å`²òÀ "sÀOUõyÛ9w&ð8àb`3ðhà ô›ªê»·sÍ>ÀuÀ»Tu  xÐX<¬TÕ "OF–Xž{Eˆ$­œe³],…=ku†Æ#©`@p²0ÀZ(U‹ˆTúJᤃDg(Šn¤"s~Ÿ kœ¥³”ßug#ð à+ªZHÿ7ø(ð×À߯^:ñ\T‘"0VÂrvÊ ûZa$‚ñ $€8ÀôßÅ̦)…ö'&ÝBi•ÊʦnÎìí-ýî7¯ÜvR""+€w‰È?©jciD0 1obaŒðp ¨jüØRJ°¨îh¨"ÓMöØÒâàŽ×U&•,ͨZÑZOÄ,˜X, Ë ¥@EÀ!°°ô—-}ÅÐ XÖ*Æseù\Écm`ýå·©eËR}ï•¿¬K¶9Dä£Àëé[cv,NVæ»ì• ®Õs ilÖ·:E¥BDÕŠÈbÀ  $U`$–¥Âª{‘Cž)QÖU,7$†¹%û¢¶gVÕM"rðçôÝc®øƒ 6`ÀV8ÐGe÷]öK-Ì€ûKÓåüàO—ZŠn®£f9hº#äj·‡IRqIÀ‹­yé = u…`Û_FúÊŸ,l‹þ„‹@¯ßœdá¯fB–¥x`¢TöhzyɆzÂoR˶¾nîmú¿ÅüR ò@#¶“ëD£'«§Ú<ºÙeKub9ÕRp-%Iqý‰ŠQð@pÙÂd¥ ÿþY §?qÉè+‡Æs†! õ;uJõ‘#l±Êº,avÁê=à~²`Á>š¾;ÕK,΀ýA«ÊÿYëxJo©…pÿðœ[ÉùÁR‹±Ã Šiõtå›õðs²—‚ORdl £‚S° HÈql hGð(a>1TÀ˜¾–Ò_’[Ä5úÊIüØuaßi"g©Eí’å­¿­rƒ5 þMÞ7^AÿÙþh©y tý¬´±!‡ya¨Õ‚$Å%ÛîA%¡(•¼—`êôýW±}ŸVkn›¬,NR"ý‰IBÿ\dÁßuq³† à{äg{l¨%\W±¬ÿC?ƒ‡"r$ý “ƒé>¯ÓÐq_DV,µ X>ƒq¨ª¥­›‡M7e—n0cbb( !"&¶IÁYrŸ#2„8‡)RŒö• /0¿`uQ=1‡9×_®(t IÀ ô­ˆžþ5þ,ôa# 5a¸L!8™+Ù=nÈ,kK{éžÖŽ…ˆ<ø ýe·S–Xœû…Ô¶ÌéžëgâÞs³ºðš¤Nü²å¤Ác‹€Id`cÀ¤  ú–kÍ•ùD¨%}¥C¶ÿ~V鿃‹,Z Û 3ã,¼—@ű–Ô\dzSŒ\ LW·˜~äü€{ƩܖF+/RÕÓ–PžûÃ;Á5XŠø‘28à…*f®wÚ0Ã!S-»ˆzåhU{1š$©ëôăԇHF†ÕŒVÅŠU"âUi‹Ò˜„®DÁ êÁ;èõúr»ÚOw‚ô} çµouQnS7±Z¥¡S*Þ“•žÝϵC)7‹°Cúbþ¡‘½€ïÒ_>IUwHEeq²²fc|â––ìÑ$«F;d$Ø”ª1b!ò1ó d¸Ž´ûÖik”¨ÊZgXi!UhEÐêû~„³ôßúô•ÀÅÉŠQèJ?àkñý\œ¬¸TM|È Ú­ûŒW¸p0Y¹ÇœDßr{}Ëà·D䫪ú²¥ë¾1ÆÙ_¬(îøxέÌñÔ×”ÁTInÞä›í°{;·Ã¢1€—ÜklÏœ¬˜‘ºè¸•Ò{ªPd™J!A¬*bèYp"ªèú9H24Ë ÙFÇj@@U‘ÜéDb¤©0m@K …q…Bn?Øn­¦lE0…¡,Î{nLV×%–æÒ=Á‡."² pý%ù§©ê5K,Ò}bëÉÊLÛ¬VC,Jg|žç6º2)º3ÆF#2:JR¯÷'+X¬¯Ê|TÚVX¡Š¡§ ¢ ‚Æ~$±–}?ÖNV,ú*Ìémï¢ç¶‰J ¯hÀ¤P‹ ©hyŽLVîªzíÂÇK€SEäûÀÉ"òaU½j E0àŽËÄ>¸¼àôÃRžõ›ܸx¼Áñ‡D6¬ãÒ³¶n?ÏÑGYöÞPç‹¿¿­÷¬,øÞ!†G­æëW Uí÷ó¬C-mâï±ßÉ4cÿ2Êyow\N3ùá:ÿú¡Œ“ïÓ ¨t%p½s¼CZ Ü7B ]³¾}ð‹ý—¯µ£#\³áóè£fijQ [¦£ V¨t+’&V»)¬Q†‡¤1R—DÒ+ñæµÕicÄyEª±„Ѽ'=ɸ%Q¨YL&ô‘ ¥2lûƒíÂ@¬ –C:£bbРD›’…’]š%Yè¼Kü8RˆÈ*úŠàpÜör_޴É?~ãœîÔ‰/ò‹ˆ¶:!T«ÎUq·UÊBɬôŒ•4Dr ”A(¬!u†Š@/*zÓ,¸jj”¡ï»0œê*D¦ eB’ƒÏ`¹é+Š*·MV\dûlYM0Þ1ÚSRÒ(Ù¿j¸(uŸ ?§Ò·>(ƒ–”;Ô&.øö¡ž_ÿ[—So-7¸ÑœõYÏeŸßºm‡÷¬,¹à‹9ßüðíûøÎã.j‰M_ÄN¯bÑÓØlF3× tÚ4Š‚9õ´*Õ@ðÞ%åæÍÖ¯ÕbýzÂÌ<.QfM¤ÝÍ ›º„[š¤™2W…›»Ú÷3 ·1ö•B4|¿‚g,6qT¢p@î[êgúPAD–ÓWwŽWÕŸ/±H÷‰H¿®}ðšuÝ«U+£#¢•z*yÐ2øPdIÊPÍ…¢ˆ~ãzõ³Ó¦æqs³±=½E;3314£'ø@/@(ߘ‰åÍ7QÜpåô,e·K™y¡dºÒš lîR£Ø!Ð^¤7 ‚_x'}„  ïç»iㄚ€Ç‘¨¡ÒòÑ.xÔR?ˈɅ¿ƒ´R–œí. •_)§”\˜%™7yáS„êåJkõÖíz|ñ†e_ŽÌ<»Åv­ó‰µ·õ‘Þ0Á–÷̰ê%?;xÇÝ 4ÏSŸY··0²yˆž—lã“`ØóËîÅâ~““ð\ñ˜”çž?ć7œ9ÔåŸMyÖ5=¾rL¿Y´\–üÏáësö Èzc\ô?guøðÊÔ.†U7Žrþêì¸çˆÈK}vW™ˆ¼oaJU?ù‡’ÅÍ~}]ói%©”‰¶Ú¬Ù¸rÔ±ßj Î8<Ð.5éæ"Y†Az¾nÕ—Š !Í$EË Í ÄµÊÍg …B2ߖ̈ÆJÆŠ‘*ëÊH£(I³ eÕ (2Ÿ#óMìP…ÆŠ:…1ÔJ%S!äDÑŠe6ƒenTQUjª$Æ¡ÁC Oèttz´"—Cq·áaÊBíës€=€¶W{G`¾Vݼ¹8<ª¬ UüĈ+GÆí57ßA Ï‹¨ÉˆScÅ8'¡ÛÍ2ÁPAÕÈÌ,¥µ”õ:=UŠÕ+%Y·Ñ×z9¡QÚØž#ª‘jm˜r|ˆµêy ñÓ)qÖЭZÑU_H¡¿Äl¦ïa“…ÄB‹ˆð˜é{ŽW9ßøte"R^ |MUÛ[?œ~™¹ýwxÀ€%å–Á>’ #ç¶xÍqk_`Ùç?·mÙô„?ú¦aâÌ‚ÿ:éÎo“οËrdÓŒŸRrÁ?*ÉȺÃ;¼÷°mÛx.þ—’ŸŒÌ°Û«rÎø”2·[t†Õo(øÎÊ’ ?ÙჟPföêñÕÏͲÏK”æÎ YdËÞÊæÝ”®48éŒÈG€Ï•Ïl°SdgÍqä1w'÷€;ðRའÛ*ú¹Ì÷ßð‡"Fuë6vìå~x§eI¾ï.•8ZñåÊQ¼÷1Þ2]Æu3‘õsʦ¹¨½nÌ+ŽNbhf ±R!«TŦ1I!­%$­¤ SSÝØéaUÑñ!ZãÆkÌZ! YÆÆ*ØPšóï µŒ0TÁ‡@hF\³$˜3€5ÄvAœí;`‹ˆOD²D˜Í …“9¬ ’f2ÙÈoL|¤ò\ú5‰«À9"¢Ûl­%–ïnñA³[¶ôŒ˜e•?>buÓtoØäu® µ„|×qz»-£Üy…0\;1BÊèÛ0^—°|Ì…ËlÁÔ Õ ¾( ÝŽÚà5›yÌÞ®³Ë*‰«W¡{îJ}ÏU´Çêôˆˆ±—àGªx+øó°n[–L;hG…¾ -Oðд0#.Í’µØ"b³”ê|W‰‘t©ŸïC€Œ~ ÷¹ND.‘5ôKuŽÿKU×,©„p©eŽ8­ä¼·ôøÜyJoÿ õó¯ºõü<Ç=¤7Ìׯmò‚ÿÊ9ó J÷”Eß@¥\5ËÞ/Sš»D¦^ä8üÍw%HƒãQæåüƒ޼Ûú­=>9Yûæï=¶Æ{7G6Øv;×ó«…êq²Âëß:Ä?®ŸçÉ?÷üæUÀWSN8£Ç—N˜`í§Ú¼eˆCÜþ±…ûþ¿Å{XöûdÂÑ¿»;YÜU}ÖRËàƒV¯úÝÌÖoiíœf¿vc'L7­ìµzHŒh¬ÎuÕ“¨Ñ^¡ˆ‘("¡ðÄÂßZ²«¨lT’(b FñB’@šéÈøx•ZU(B¡†€ÐIÀ[Ñá‰½Ž”µ!¨8$h5‘á*„Ai$Š_^¥>_ S$=‚¯âë †HÏB ukH¼'d)+=WϸüšâãRàýwqþ!m5íæaøÆu­ÇN5üªGí4Rì´Ì©÷1Ì5 i–LÍgÚÎÒÖhHŒ ‘ÂlR!-¼@­Å/ÔýQ©¤ÐBsÞSäÁŽŽ$:\£gd6:Aœ!²¤í‚ИӲRR‡ŒÔ¢€F¨!7BÛ IÅPm–2\Ãá)멤 Ìù~…ÌZŠV2YÞ,ô±UÇõ©“Gr“9à©ÀqÀÞôÓü\ |øœªnZBÙ–„ÇñN Qòœ*¼æAygf9ðù‘5/®ò–7l1à.”Á~xééNÞýjòï ÕÛEŠy~u’0ôëÏ\°Þ©kðô£n[bÕLé,Æn¨ñÚãj¼÷%y¶&pÝBíÂ{¢䜾/`º|øó]]ÃH›ÿs˜eÏÍàÖ.©8ž°¦ä—ûl¯Ÿ!NY—ó•ÎsÌÂÐ/G|i”³/çòïÞYÁ|OD àÕªzÖݶÞ"òŸÀáÀrÀœUë7·÷˽®\µjRº½"¶;=Ê27Y£Cµ¨¨÷…–e‘áJðâ¢÷*y©cDň €ÁûžzÀ+)QBŒ”"PÎD ƒæ&I”àEm‚›ž÷½ ô¾S«eÎ8²²¤—¦ÄP"uAìBÁº”àLAk,¥ZQÍgÛRé”1"C)&*¶f˜ïFêÆ£`A«­Ô+ò[#·Ë÷pã "Ò~«ª¨êeÀe÷´9Œ~ž·#ïrýs[¿¥µ³MRfæó²ç½$ªŠ;Ò Ý.¾Z£KZgéG´bD¢€*i´¬ÊÆ‘!¢W’Nï=>M‘Ìà*B¯ç#ÆZ± ãÍž>z´*Çú¦9ppÔÂöyàâûØ×¯]ø|Kd9TÅLÏõvíæa§=w_ŽC£åi¶b¼Y•Ñz¢J†^3B0!Ç¥‰“—ÑXÓ_WU1Fú“•êDDDPH¬ar²¦ŠR–8$x° Ò+ˆçK‰1†¬šŠs ã>¤^L?‡fă-=ÍŠÁÖ­væRÉz…†Ò‹ÔÁÖ,­R±A0*¤b¥Þ)801ñÆ,1g áÍôBÞü–~¾ËûÂn }@ÿ}˜Fg»›}`{gRNøõZšw£ Öùäs¾õ£:Ÿº9ç+ËÇ[¼ñx¡rù$ÍW,ëòáemÞuþÖíî UÞõ³&ö¡vÿßu>ý5ÏÅu¥gƒBî(Û¿]WpæºǽµÊ[>ŸrÒ\“—9Ì/¼«û ñ[zœ:Üä¤OØÙP ünb˜¯_Yeóy-^7«4€V½#áØ3‡ù晳ìÁBU¯æþ)€[÷õ€FvGÅݲ©½ÿæéVZ©¤az¾Ôv7hµæÄ!Il@5j¢Öh飩Ö*EÔ& ÝV‡á‘*¡ð IÙ¢bŒH„¾–§¢VP#hˆ˜4Š .! ÂÆ]¾¬&IŠŒ'8‹¶Ú0׌R2…Xò2Múuì¤ôˆF¢Q$qØ t5RÖ¶4a¨Û3½ÜK”*Œ¤H&´ƒRE©¯=çd¤“ëÊZ&«e'Uý-°ûÔ×G€<}Ýz¹¾ycóÀn^šJ¯ô;-«êÎËkÚìšÝ@»0&„4M‚ŠÑ¬V•¼›#Ñ3V¯j³«DEŒ”c$Þ:Ž¢bHbìç\ðÛ‘(h»âpÝÄØo#‰ÌÎFм­µ˜h¨;¡%Mú©hD 1*bÁäÍ ¹q²†¶£Œ6šÚ)r •*R±˜T(ƒP ïÃe )K©£W$V– ªUõñß]°zïþ@ôõPF°óÛ¦©{ éòÑI¥kª¼nZ¿Óü—‘ ¶Çg'ïnå²àµ’OTxãFËî÷(0ªÇ'Ç-ûõžÞ½;YžÞ¸§éîr¾2¬tM…W> …;¬Û ³Býj€”ç´‡ùêu ǃPý9€2»—e¿/m}]•¿™2L|«Ç¿"LL CÛU„¡k„ñ;<øŒ´2N|±2õäÏýï.ÿ÷³k'û×T)Œ‡…Ï¿ÆKa㣵—ª½Ü«1ÎתNH jUk­Š ÆˆŠ*bç\ !ŠjÄ«E¯«™S«1ÛõTuVƒ1Öô—xc¿ÊƒŸk°råÆ*‚¨4*Ü´¾CYŠÖ‡†jNÄ$–B¬"ÆA§ *”>šJbÂPF™G©æ¹R­ŠÏRH ’4÷š¥NòVŽ¢žé剕ÎRÿîÈæéΞ×ÜÔ<ÂZ›D±ÑYÑ‘z¨ibÕYƒ1&kоÙOuQLÿý"*ív›,µ&I+Ú)g-ÆHƒ.¶ÑßWãÀ{%ÁYUBP­Õ FPkéÿذ¹¤ÝS®;\f“e}¿B-Š~ac“€FÄGèåÊHE g³m[ Qýp]ÌDµï [F ¡[hÄHO¢®«WdíÝ?©eDä>ë S˜5Bzõ$½» 4œa·WGnþ;ÃnïŸàÆÏ̲×_nø a§žà–\ëæ8ø»Jñaì›–=~ ÖGn9Xiï1Éüúýíò†È-o²+ ÙhxÔw•ÙÝ#›O†°"åyÏáô+ï?Mõtaìç†UW€óžªÌâGø¯£Sžs«¥{ ¹’ßA6ìôaxSä¦ç+íc…áÿž¤qknƒg<®àG§A²Ö²×'„‘éÀu'(ƒ¡ØO˜ü“LýÝmrL~H™9Y=òç”ÆòÀÚ—C±¯åÀ×så™÷öwXdPŽnÀÃŽ¢ŒÕ^ÇŒq&uçH£vi|0š¦ID"‚`…¾QDˆò¢0‚Qg­&‰¨u5ŠÜË-›Z¬˜¨Ñ) ÝD„QQÄC ª"ˆ±¢¡ÄDQ­T3-Š Ib` :9š²fmCò¢Ô¢WÑ¡š- k“J•Âe²&h44[‘"ïi–Ôht`r”®Fª!¢eèg¶)X¡%J% ¡Ù{NÔí•wÿÄü¡™iä+“DÓ‘!Q¯½Ü‹±#D#*‰ŠëÔ1ãlCˆFU© kð¹Æ²w¯1ß-7º¸´[rþ[AÊ!>øü*oŸZhû“iÆOQŠý¶î±Á³VfN6¬øÌ›þa«S_ž"¹ pÍß®ý¾e¿û•×óNû ØÑ!fÝ^1ÜézmDÐ(•4u‚ª”ei|D¼"ª*ÖÆô]¯ÒÒ$Á:+eˆÒíéõ¼$©•J}˜©F_䬃zEEQ¢"€Uœƒ4²j&ÆZ¡d"Ív!k×w¸æw›L«X1‘bc—bL(Ù IDATF³Ë–é®¶Û¾˜™‰I^Ó h½Š&‰èØP%Ž IèAÖm*%/|¯šâ´_®$%&V\´k,.u$ÖÚ‘Òkm©·'Fµ^\ÕÚ¨¢£©ª³b}1 TMâD+¦’Š©V­("ívÏøàÅ:§Î‰&Y“ ɦÙBÚͦYVG¬EŒ1’—*e‰k¤ŸPÅØ¾¯CPÌP½&ø\í[ü¤ÓS&F3­%%›·4dýú6é¢7×P×ÍÕ£Ñt¼n•P¨10ׄ´7^'·BVxb§$†Ht†VŒªNç°®9áHÛØþ¶U+ªZãÞ fºà‡Ÿ.øÞ§Á4ª¼ã[û*[žvj”s¿tOîn9èË[ïñÏ—€äÐÛuÛû+]éðž• Ž?dž§D0F|j¥'*ã ±,ƒzß[œ¬%ª³†zÖZg±¶¥îƒïû3ˆjÚëOVªU§e©ûC‹f™‰>z!Šä¥Ž8Z…‘2‚ô˜DDÈ‹€5kú“gE\âbˆŒÅžÒw!®Õ˜HºlœîiŒk­ô¼$óMÍ+U‰##FZ-•^YR«8¢ˆ5Zä1¯f¦ÚîIhvÑá 1DU@³Dl£££½B–×2ï瀻dž§<)²áÂÈP® ÜðÞ&/ºxë”oBºFÉ÷Rº²ß}ÆsÉSAãÈŒò“_,ïòÑIˆ÷)…@w¯ïò±Riß¡Fɹ{n{L¨]¯tŽÍxñ÷ï,ÕÞÁ½öŒlzAdë[üå­ ¢ ¾ý²ÈÌ 7 pô/Oz@óÇÝ[ Îx‰aòâeäI(9÷½wÖV™5³ìýåȦ§:þ–eß®û«i&?tOîUò“¿-øÆV?lY…²~ÿ¾AXqÿ®ä‘8Ó[9Q½~(‘µ1✳Öµ£õªÉ\b²ÄÚ²,M»[ÚNÇ›v»g»y4}ç}5Ö1ÖH^xÓj—Òî¨ÌÍ2×èJ¯Péõ¢t{UEEÀ¥LÍdR’Dû©e@±FCTÊ "Z«bV¬#NAQ%hÔ¹¹&ÝB%ËjéÄh…D$…—¼Ð¸i:—éÙ\+Uk…v'`ŒŠˆ’f†¹2”¼D ¯j ¢¨w¡ÚÉà ÕÌCˆ‰ÑlýPÍ••,5Æ9S­fB4Na4F1"¦ÝÎM«]ºV§´yL HQº=/í¶—ùfi¶ÌôdãæŽtº¼T|„P1Öm"ÓóQ(‹~ùÈ„°¸4lÔ‡HéUŠ¢¿œ<99b†‡ªÄ "bÐ¥ÓîJ³UŠØ*£U ^Ón·°o~Ïþõœ‹®úãéÙhR«1MU ñT3«6Át<â íVRlPh¢Á ÁL–éæauˆš,õo2à¡K—(9ÿàÖÖùÂßTyË@Ú9ß>µäì[«ˆç@X=ÇáÏyàîî«ý¾ë·ËØå”{´¼}gãQ¨ÿHiýQ“?¿ÕïP™5ž‹_·m{ËþçôøÜk·=÷@rŸ–‰…±ïüà$àÑ 62wœ0|kÔN`Írenœ…¨œÏ>¸ä“ Æ.Ÿà¦Ï6xÎAßíÑD6SåÍèñ©W+ÅrÃò_ŽqùW…ª–œ]mñÚ#[)ûæ(?¾`–ý_Ùød!™ËxÙç‡8e]¿þàÌ BçêV/SòåJ¹ë Ëß•© Ö~rëï3Ç‘'*~r’¹?YœUä|åâ&qaƒgž6Â/áQ¯©òúÓ>gØýg<ÿ¿K.ÚK)ö(¹è3,ÿÓ„gÞÁ”;ÏÑGy~û $<á[‹J¥+strdêp!ÝRåͧVù›©m¯oðüÇx~ù´QÎùôýz8#‚ÖkÉÌ®«‡¯¾äê-;ÛÄYk+’fN'5ÆV'猫Úî&ø@âj25ÏÓŸ¸ê”vÞÝqȹùÀU(3L°y»ÕNî Ë^F6½¾äìÌñøOYöZ[rÞ ‘-/†û Ÿò§§ä|ýØœ¯ž^rö@6§l~:Èâø~«us”Ÿ?ÍØéÊô˧vtša¯‘5+k«l>~’Þ ÷G¸Ê ã ï–\ðO‘ iðÜc…Ú¯ÀÞª=GÖ¨´vþ»Á3+8ûó†?ã8ô›« øÝ>k>`?Ýqèׄjló®ïÆÎ²ìóÀožeïeÜò±&¯~z±OM8êÒÈ ›„‰Ÿ;ùyà÷{Ú‡:ÿaèy‘"Ž2,ÿÞÖæåŒ“›-^ŽçŠ£€K#›ž¸úl` @ÙøìÀ5—¤üѵ˦ «Î·ìuMÂS7{οµïyŽ=²ä¢[öú”•‚³¿Ðä¥/æ«×ͲÇ;”¹£,},²æ˜6ï=-åù¼µÂ7Ï“.ùÕ{*¼ä5Eðî!®\V»ñ1{M^xóæÎcQ†!†¨&ÆhŒŠÄèUkµ4Z)4btj¶g{…3“£Yœ±qr¬.Ív`j¦ÿýëg½yv¾µj—Õ“k¦fçw`ï=vºÎYSÞ¸nóž!F³÷î«~÷Œ£>óàý–ÏÌ4½üð§Wwé•kk·{õN·¨=öÑ»_vâ O:m¸–5ÏûÅå/<û¼«ž:>V_×n÷Æa]Wþö¸§>î[;­o]úÛßsÚ÷/zÉŸ>ýqß|ÒaûŸsýµ×=ö ŸþÚk—¯Z¾Ñ‡èZÍöðÁ‡ìÿë§<ý¨ÿž\¹òæßþúêþñ¥o¼aÙòåjCY{—&·ü¯WžøÙ믾á€ÿøâ£×Ý|Ëê²(d×]W^ô1ûöžxðYy^T?ùñ¯tíÚ û¾ñM'¿éÊ+®?òŒoÿä5Ï}Þ pÆ·Ïù«¿|ÅóÞôчyݵ7ö‘ÿûïŸ}ÕkNúÛ#žð˜-ñÏ»ÃSIm{Õ²Úïç[s“íN¡fpÖÅZÕHÔC´b¬DU¥[xQUu¶*C5B–8íåH¯SR–cDœ3êK¯ÞGF‡STÑD’$ADTœcýæ&»®®’Y+=oDDÔQï‘ ¼°ˆˆÖ멬ZQ‘õ›:â‚\Uæ[=WÊ W¯Žïýë—¼ª?Y)c%K)r%ÍRõªª)ý¬èNˆŠO,.JéE5YÈ„m$Xc$/â²z…2øˆ#¬ˆlxóöÏI~1Ëÿ[iÿ‘a×á{¿Y<;Æ/Ï™aùç#S¯œå1çså Oé ñÏÏîðîEÖ¿©`ý[úòÂÄWï‹„£\ð³v:%²ñ žKþÝs ܘñg–óoÞ—>éógœñžÈæ¿;e=7ã¥_èò¯ ÙíŒBã\ý–9žøÛȺ7•œ"·ê¦!Œ~;·¸×ÜGËàdC¨ý¦ÁóŽ \ýÇ¡_ñ\¹]Í´äÂW&ÿk‚›>³ph«ú©f~‚©÷ÌqÈñ ~‚-ï˜çØNÉùŸ>í]ÀvŽÙXáõ·†mGÖ¿Üqð{ǸäGÀYÓTŽmóÎgŽsõi9_7¬¼a„3¯hpbŒü¾}ç>ƒÅ*¡~þ¶G…l“Ò]uWÏ¢Æ7v9¥iÙãÚÅþ»üý­ç=—ý…aù×ǹöÓLì_rÖÉÀ{"›_žð´—-X9`ÿÝ.›žj.Ûû?ÿ™e#›ÿø˜C°aScÙÍ·lÙ+q¦óä#ÿ„¯6Zäk_øÚ[¯¸ôªÃÞöþ7¿±ÕêÖýMûüþú›öYµzÅ-»í¶ê‡ˆèûßóÉ÷mÙ<³ây/:þ‹ûì¹úÂo|õûo½ð‚_ÿ¹/¼ÿˆÉecöÛ÷KÎøö9õ¾wê­Öÿgï¼ãí(ÊÇý¼3»{êí7½B Ašô ¨t¤H+ŠŠò³±!öŠ +Ø¥HTz==!¹ýž¾;óþþØsC¡‰Ðó|>7wËìÌÜ9s²ï¼ó–jǤI½ V)W sænôÀY_8íc=¸hög>yî§—/[9Õ{5™lTyýë÷üÑûO?á}Þ«ù̧Îýåßo¼ýàoóÑ}úú†&âÿιð=ï;îôí¶›sÍ›O<ãÎÓ?x⩇¾ß¹·Þrï¾ïß—þzÒɇ|ömo?â“öÓmñ\èÅ?§0(Ý,ü!ðÃõß[}&ð$m_ŽÓrœvJÌM™*_ÛD°>âKRâØsKÏÎY·¾´_=žÚÎòoÔùõëüj£]WŒí ¶qÁ¶O}^×ãØ]Ü!páº×Û¸à!à„µ¯ ±ËB瓳&¹nýøA™LvÜ=Á0«/Çÿ[ñ\=¨Ÿ§Ø ö“»¸p~áü„[ž6”eîïw¿M©ÍmçO󟾉ÆTÔ[×wgí”qž¡IBî®±ó Çß ¾'á®0LJÎL½Äû¯î§ø³QÞ8'-•LŒ8ð®'jÌݧ”žQx[?ÑretòºW•Úd!¿|}OfoyÄ “ÖôÑÐ}¯Ò˜˜æpÖ|ž3ÖÇBö>e`ÒØ¹ã±÷fÿ %>DD;Ú¢•³§ç·çƒÕª³µ†³6lâÔ$±1adMYÉg“±"¨šR©<¶¬Ü·¨¢]¡‰"#"è!ìxÅî;lö¯7¼f»+EÐw|Ð÷÷ÛsÞ_=p‡?,YÑ7Ó‹•Ž®q‹÷SNñÎg/»rþÑß¿àŠ÷,]Ù7-°Æ%„íçm<›-f^¿ßî[ÿr«93o¸ùŽ÷+—«ùj5U\rYu4ê©wÀÞûí|õžûîôçwÛé&O\øÐƒÎY¹héf>ͪêm±- ººC[Ì…¶XÈš0H”hkk3ù|ÞD™0,Ö£Å+ª X›L›Ú»Ì ¶­˜+Ö&Ó§Ž[êœFù\¶išº|A¸å®G·=ò]ßûþ_w¢KâÂÞùRAÅX%—K§ÉFÓÇõ‡81êµ»#¿ºR­GF+Ýê½´3’+ähøæWTÄuv„ÒÙÑ;®w¹ªÊ£­œF32ÇÜ­çÞÒÑž‹ë1ºtYßD€Íçn|Š©'¾c“M§ßY(äF/Z±9@…µ™3'ßÐÖ–?¡g @6›©¼ãGý_¹\í¸ëÎw»÷žGvÚu·W='¯úÏŽ¶håÖ³»®š;£x-‰/•ÊÐy±jL bƒl.²ù¶¼éìÈÛžŽ¼i/fl>kìªÕÕÌÃË­4(2bqgœ~ô—wÛa³›=t× >ñÿŽýü>»Ï»ú¨ƒw¾`ÉòÕ3ÃŒ•öΉ|íŒc>³hÉã³Oýð¹|ð3ç}d´Ò¹héªiaæ÷xû›öþÉ~»nõ‡ýwŸ÷‹×îõªŸßøÏ{Þ008Ò;88,Ýmš‹¬Ôkéü;èà}.Û÷5;]µÓn;ýñÍï~Û§|à‘¹ÜyßΪéýžÞîÇtþ—;ò¸C~:4\î¸âò^÷ÆcüÍ[Þyôw8h·ß~óœî›ÍfÊ?ÿùe‡T¸;åÝGä±Ç–m±zõÀ”oœý‘ýÃ0h#~Ûíæ^sËÍ÷î÷àƒ‹¶¹òŠN*rÃûì»ã Ú¶kÑâ¥D25ν¡ŸüEýt¹Ÿöï—8õoJcKË&gf9eè¥îÓ¿gÐ0ÉõÒØóÙÊ…ìu^ƒ?œ?ÀäQËœlÝTÿ>‰"?¼zˆ]>ÖOÏç,ÓnJ¸ÿ}†Iç 0ã†Þ…B× gx3¡í>ËÔóîúØ ó²ÊŠmÀ·ùæS¼˜ œûh º™u’лdlvŒNn¾l€q‡²Éù–Í q&á÷z~ÙÎ¥w§ïøën;uˆm ŽG‰Çžºÿ‘pÛɃl9>ÃQOÒ’ì𓘿;ȬUJ’SFö‹8þ¨´Î ç%\æ¯ú¶cñ`GÛøÕšíê,ïZj˜tl…/ÿr-3]Üsɳ÷Ó!"U CjΣëü¬{íÙÎÿSe^Œgþ¤ªßXûo7F|> n>£ø·—’þÑx³l>²ah}6´&²ªªÇ^]’¸áDJµ„l5¶ˆhSlD›a›:\¦áÞ±½é–ûvwÞÛ ¾ùÖ÷yÍ–ëqdB«6J¬ê™0wÖ$®™ÇWÍh+d‡Æwû[”PÞ«xŸ¾œ‡«y7.+Ë—.ßXD|Gï¸ÇL\é‚À9—P­yé׳àŽÛîÛæð£øEâÉßqÇ‚-J¥JÇìÙ3n¸õ–{÷½âòëO.óCÃ#¥žýð¢3OÿàI§ì²ë«þØÑÑÖ÷«_^ñ!U5{ïóêß=Íœú1Ð¹Îø¿ãúüË­íeªú¯õÝcˆŸÐ›{¤½ö?²¬²}©áge3"Æ«ãxçñÄ!„’xp’˜ÁÁÑ(‰Ãšó;ÖU0bÒÉšÏGUU µùÿ”ÆÀ­w?´ãξècùáývßòš­¶˜y×Ï~s݉A "F‰2éz¸½+ç3F*UÕ0bçÕÖëqÖç£a€Ld¤­½ q3b­î|±ÒQ0&m³°Rèì(ŒL9í‘DÃ2±28Tj¯ÕêÙ|!_2ƈze³™þ °q¹T]ôwù²Uc+¤Z­¢(¬xàn?»õ–{÷ýÇü;\½zpÊn»osYggÛS´6"²5#ýÎŽýðž¿’ÚZ¤ªÿöû¥ÅóÃ0ÉY6ûgÕPŸ z. Øý¢v.ºwCôéy ƒ–i? ØfÕS¯ÏºZhIçÜî| Kî娣c®92á¶£ Ýw¦ oq¿#³Æ#'`ûF‘¯Ráóov,ÞòéwÇ„Ãä=ï­,Œ Sþ^äëèâ±±Í Çâ=„h ϧËih˜yIÀÖBšR&Ç©G6øãÞJß4ÖAÈi7«ß2Ä;í.˜8`Û3;™ÿ·±2í\sÁ(‡®v,Ú=`Þo<+çl» _ÿ¸Ìé»x–Ìó,¿3ýûûtpõ¿F8ð ·¸ ‡¾©Ÿ> ÐÍà)÷› IDATò¯ ²Å£ŽÅ{ ¹¾tø˜Ú×0ù[†).ÏY+!<¦ÆY;·áóEUsMÑeìËÿlÇªì ­kÑÓAšÆ³Ú¯uÎß°teu‹ÅýµÃ(2ímÆ¡‘\`¬iïÌx#Å‚MÅA+`Ц6]1Å»¤ùRHbÌ®;Ìþçßæß¿Û‘§|ïûãzŠƒ —ôMh$I˜4m w?»ðú“~ó‡ùG×êq¶XÈŽžñ¾#Îèíé¨ yX±ªJìŒf›/ç?þþÊc¯ºâ¯‡{¯F½òÆýÚ̦/xèž{wPï©Ö¡˜5ê¼q'½åÐÿâç8ñÐßùWcmR¯Õs¯{ýž?zã1|Ã9\pþ?šÉD•þø3;\ý—sÞ/úl±˜zÇ)Gý_[{að„“ÞðùoŸý˯O™:áá§ßÙçù™=Óñ }Þü›óèÅè‡ógDÐ|.œ3³xݪÁúâýy±7]&l¡º ÈX4’eq.0ožX¬ˆ1ñÍùiÒ´#XÒΈø×í vvÞÛãÙñ’ÃÜéâ;XºY©\-F¡¡­Í4÷F®¸æŽ×¾õè=è.ÞußÂݧMê~xò¸ŽUQ˜F‚ixE14¿Ü{ç‚íúú‡»ÕÅáü¿Ýxh¾P™8}úÝ£«gÖ:©×czz{Wl9o³;¯¿ö_{m´ÉÌ{g̘”ùË×½µTªtì±çv¿x|eÿô+.¿þä¹[ÌúG©TéüÂç~øãO|ê” …ÜÈ®»osÙ´i¼òŠÞ,"zÈaû~ïi†öCÀ,ž,ðó"ž¿˜u¿Øm?ű²Å‹K ~ üvC÷cŒç- vñÈÏÖw½“]=vÜη¯}¯_=|îÉ×~{?ð¤~YÞ3˜å=OÒê¤uÏ¿¸nýíÞ~%ðmàºZ´ß\Zà›ç¯[n !§]Üs)péúî[f&Üq90æ¹ó÷±{!»Ô;ùǵÀµë{¶éX²^ç•.îý=ðûu¯w³ôì±ã<ŸZ•çSg¯[æù¢c{6ÿãXk’S w†Q-^²º±]©D1— |X+Jú2WüVsf.˜<±kU.k½ ‘q=Å¡Wo»ém¹\éé. ï¼Ãìn6kòCa{í:çÆ|>Sùý•·ÐÝž)¿ýØ=~qñŸïܯËTœQ€Ã_·Ã%+š˜8õ†/Þfîô‡ªU¥³=óøVsfÜÔÓÕ¾<ñ*ÙÈ*Àö»¼ú*Aµ422îõG¼îç§m|§ª—l±}p»¶¾qúÆ3î÷ªÆ†«–N<ùðm¿ÃV7_yù ŽŒ” Ûo?ç’×°Ëù<²t«\.SzÏûŽûS§Nxx¿ýwúÕƒ.Üvåʾ™££å®¶¶Âàž{mñ·Ïþå×wÙeë˃ ˆ×7ŽªºAc‰þ·&ž<.÷À„îÌ#KWV·XÒ_ßÞ{Âb!Ò(²šÏYÖz#¨¦q*¢`ð© MáÔÅO,VÔ!;n»É­Wßxï^?ùÝßßø§¿Ý³÷Â%}Scç‚8qOmŠ wÜ·hÞμà{‰ówÞ|éãÇ¿·³£‹±@ß@Ѻ—L”®V­\5õ­Çþ¿_x¯&nÄÑÑ'÷• Æ-X½j&€ª"& $êTÜ~¯ÙõOßúÚO>|Ƈ¿úÍ( Fœ™n¿ßF΀*D›Ïžüè§>xÄ·¼’ˆ s7òà'N?ê«a@C±Vt§ígÝ:o‹oU¯:©Ý°ÕV³ç%Õ Î›;ýžSNÜï<1¨IOm+мzë™7O›4ÆÞ†Œ›8aÉ>ì÷ Q'½=yíl`Ä2}ã™ Þ}ú;?nƒ@£Ð✗ĩÆNeó-6½k³9›Üå½óÙÈÞlMš®iöì·þ‹ï?ll¦LðÈç¾pÚácç¿þÕŸNðǶëíí\~Èaû<֥ŋĨb¥³#Yµ²¿>g¤Ré|&“É.°`DP^»Ï¶+—+…¶BÔ0!ÁÌi=Ë?r …¨XD ú¦#vÿ팩½‹EöÞmιÑ;ï]¶™ô]ošðØc+Gzó™¨ê © ¼ç­¯=·^odkõFvÆÔq‹wØfúCq «Wû÷ÞöüSÆß_k8ò™@vÜ}ç?wtv¬D]0}Æ„ÁÙ[ïp¹*Ò;nü’CŽ<è'¦LY'J.o(—^sàî—Ϙ9yñ­·Ü·µsI8eRï?öÚkû‹úû†&ÍÝbÖ?9tïïO:áá©S'<ü–·öéL6ª4qÖ9oçÌÙèfñ½n÷Ÿ<Ýb¥E‹Ï–0ØâšlÆŽl4)wcÇH²âÅ¥]Éæ;»²¾ž€¦é̉ ñ!Ð4Ÿ‰BâÑÔ•Ã(à•(­Ô„†‡Ð‚ó`fL¿p×WÏžßÕQDÐæ»7Uã(äód#Q! C íí;ì¼íß{z»—y@­Uêˆ:T,VÄÇNÈå ™œÑj%‘\Æ‚ˆzçð vÙãscõª©Õj½pÖçßwÄŒ“<û-^ :ŠÁŠŽb°r´’L~xE}¯ZŒ !ª"ÍÅŠ°÷¶‹2ébéÓzúN:z÷KêÞaŒàßtÄF!u#ºÝ¼î˜7w£;*U¯Óº Û4ÐÄ¡cI¶z»‹»ì0{~šV;ͽ] ‘z{Ƹ׼óÅD¾\®4+6°µ}_À®Ë´)ºbuË„In|øë’É„ª>‘ļG‰ÊæsgÝ3}ã™÷dBÕ|üÓ4+ã'ô,9ù-‡>)lÈÉo=ì3cǧ¾ë¬ëx`ávªjkÆÆlѢŠ£% ¶hÚÝ<üªMÛ]^Ýi ¿:­·++jMÓ̯¨I­Â¼€ªÇZ›jhPcH¼‚$ ÑzŒ”ëh6B*ô¥zà~¯úó!¯yÕŸTï‘0DñéÛ¼³#‡j@µ^ “¦M[ð‘O½÷“‹— ÓHj#O걂±KÄ9Á;KGHºhqJd-‰z´ië*¤ A•4ϱ¡áS£Â†‚x˜6©{ÙØbE1ESç“ÄC!‘¬z¬d3Í·µ ì°ó¶Ÿ8yÒc^UÂ0ÔÒh‚h‚ŠÅ+&ñÆç­ mÄJ.cñ^U½¢¨>k6ß|ã[ÚÛ‹³6™vW[{aðÅö-þ·àë\{nÀ^-ÒW8 ×e‡ØûݪÚz™ÿ›$N³w?<ºÿp•i[Ínó5'ŠACCbmªÉ“Ô[Ô«â½Ç^1F¨*8+©–¥£.F{Û`¸ŠZƒ:¨ˆT‰¢ô®NÅQMœÊà G½ ,º³Ú?Ta¨T×Ðf´§ÓVû+¡7Viˆ:y|Ö–œä"Ô©h&T,B­ž¸žŽL+hô+UìÊÆKV7vÙlfžrèZ¼*„Þ¼|*¾áÔã%µopÍk BT­BhÑb¤”¢Eé5çÀÔy$ŠP^ ´\òZ®ªÔñqÜ`\W K—R&£F½d³ê+u#a`¼ˆ§³-Юμ–ÊuÉfŸ8/…¬ñªõ˜î¶ÌMxx[<DdƒÈ eÞ?µÆùï†ò«”d˜’¬:ÿqÄo‹œ³äÙki±6crÃSâ ¾dÖ‰L9mC÷ã™è#º. , ýd¯¨ðÉ ÿn]17e†Ù÷Õÿ±ÎµxZ+µ-fÿÚžcéÒÇci«ˆ*µ€àED1&5º7BâSí ^ ¼GC MM!"Š'Ý–T“HØÔË«G¼"I"Z­*¥RBµ’Ä1Î)I¢„UAÕ‘‰ŒA½s‚‚ HcĉàT‘ÀˆX+$NŸ6^h‹W"¸I=ÑÝ¡øe·/(™Bˆà1"¤€ÓbF "‚ƒQEE0*„b0bÀ{ðŠX qLÓF!5‡@Á»¦&Ð¥¦ 4/‚âr9Cg‡addDâÄᜆ©çUº§œËgQ’TåmÀ9!² ƪ%Õ ¦¶εÛZ<;#¾e•³¯SŽW4:ÿ(çƒÏzVœóçÝ6t_ɼ"·‰•8IqC÷ã™q㔸Ûa«o„ì>òïÖÔàÒž˜¾ <%]N‹ÿk?Wæc“˜ðñ~z>7ÂÁóÆ®±ËCì¸Ï3ßÖO÷—†ÙýIÒý0{îÒOÏúé8gÙÇ>qGeßÜO÷—‡Øyϱ«%Þ;m€ KËorB•¯õŒÝdÓãG8h›&~d€qŸåMk²ˆ(Ub‡ýÒ¾¿ê AfXæýSŸxvîýt}}MßÔàŠüØõ—˜rZ?ß`ÜgJ¼÷)q =˶t, ÓãvMNHëÚâ°±”5¾×9À”Ó†ÙgÇ~º¿<È&'Ô¹°˜ŽùOß ®g€qŸ`Ò‡žÇÇÕâ0u\ö¡Õ«FX56¿)&5¦¼1`,"1é;NÔ+FšÚBÀ{Œ¦öX¢Ö®‘Q¿Fó‚ `ü„¬‰ãÛè×µ&˜kSH÷üÔH¤ê=hÏY*7¨7P¥ÞHLSOCœ¨†¡T_Êqkñâ3±'³`Z¯¹û%5ò!„1`ƒ`ך›ˆ¤"ž˜¦Í«¦óÐ+&I<Þyl€ Íù¨OÌѱ é.þAò9“ËŠP(äÅ«à}ªŠ´’ªªŒŒÔƒ1p1±¼W@õ¨*ÞyÍD¦% ¶xF”A£ÔçA°¸ƒ¿_µîý"ß]Tä'¬{½Á¥…Aæ9À¸O0îÓƒÌ=bLfyr™MNáàyu.hKßõ½g ²ÙÑC¼zßAf§TŸbת šA6}Óº²NÂ-Ñ [2À„ÿkÖsLÌ_rk—“†Ù÷Õ1×e™÷†ôý>óíÿþ(½0ž·0Xâ„ó•ÊF–¹)»±Ó—÷ó,9ÝñÐAó.vÜwü>På[ÝU¾rdûæ^sõGÙâpÏ¢mný2øÀ2ë/1ÿøÊ('n0ÄöûÇÜôuCçý!{ýÂúX?<G(qÁ²éŸnù܇n•^¤×0ùŽ=¨ÔÛ*œñã'žYñÚWAè~X软Îo~£ €Af~Ü±àØ€­/r,Þ˱ð£ ÷M`âG<‹Ž°l~)$™û=¤“a”£«”glw¾a“k•m뎙gõ1ŽÅ´9_õ¬Ú5`«‹”¡éÃìùÓtü=+NM¸íM[\æYµs™Sß›~HÿL)`ûË^ý§çû™µø÷èéŒo³yÇõ<2DµæµÑXD 2Lh‘À ÆŽ…þMÿÏÛ2³Q#H=F­1G!}Ñúæ™™(%•6Ë•úšh°NSë慠‹©6b1ÆPˆêÕšØ0Câhî] Q&ï¡Tµ³µò¶þ²ñÔÂÍå‘ruኺƒT hÒ~V@¬Á™T0c4Jt:‡Ç+ª""‚ºt±bš«Ž¦\÷¤ÅÊ„ ˆ'´ÑÕÓAÚ$>5žUÒÆÓ_AºXñž¶H©8*Õt±'N‚f¬&¤Þpÿ±üª-þ;º3~¬\Ìߺ|>á¦#K¼í7ŽŸWFvõ¬zµgÅfއ¾4Â;=µþƒwq<üEÏÊMÆ®òæM†Øõrǽçx÷S†÷v<ø•a^wE‰wÎ+çYfÓ6o=n„ƒ~ê¸çžá=•¾]^àPýÛÛÆÏÎèàºùYÞ}†gàõU¾zŒP¸9ϧá-wìpŽgÑ!cõ ¹»ºYü½Nnþ«¡óʘë÷pÜ÷NÔóºxäçí\zw÷^üÄ3™ûºYòNþy¡ç²„[÷€4àu¿ÿ 8c÷ˆ’LXÛ^Ï0þ².‹û'„‹G9~€gàuYÞùÉ®ýGW¦}x ð¬zkÄÁŸÉòŽÛs|òBÁòÆ9#²³OëâþtpÍ?;™]Þ÷tãWá3ã•‘²œú™ 'ß笟(ñÄ*_îMKhTà¬Oupïù¶2´@ÈÔÛ¹ò¶±ôx-^Æuf¶åí@¥ê4gŸôBÕP”dL@Q/ÒLY—þNµ„¤ïW˜ðgÖJàÓôvÚôÚlÔ•R9±jÁ»Ô˜Ë4·Øá$Ç)Cªªó«oƒëŽ8øu½4öîad·€WŸn\ó¿¸nÊðáYÞÉ¿šmÞóòÑ ö“»¸p~áü±-Ì1<Ë& Ñ‚€í¾¾ÌhÌåMa+\qH9½÷¥åàÛ«|¹W)OWªs˼çÜ2ï97áæSÁ¬Ñò ŵ¨Üj¨ŽPâ©sÖ›¹cíg„üj¨Nf]Ùìʘ¼Ñ³zS@c®Y³l˜ºV[ÁjÏŠ 5~Ø®«ÀW—AšÂGj|w"6¸ìcýi8›ây|ª»Ã0é9…툹qFZçÙ_«K—Ç\;½ÙŸYÞ3`yÕjÅýÛN'-þ3„T'tg®!>õþ5‚ZÒ‘ÁYÁ·&Ü ©fʼnG]º%<¦8\³g AsX ®{V÷•¨5b@°Öé{Œ QPc„@¼fC/•†ÅêœÇ{ň’ͤ’¥÷ÞˆðoÛª¶xù3¾+óhW[°bÙªX³©0g°ÍÅŠÓœsbD½¤¡0×,Vñ ®éÄ4¶lh.Vd,Φ5¨Oç«V+Ž‘R§FcIœ#´²f±’¸D‚ÀbEÉD‘&>$qc#¨5"ÙŒEU¥\u¦=õoÁkñŠ¢È>+tŸ®Ç³ú1½x˜Ýîé§íÇÃì¿ÃÚeK,$S¶ÿÄXú×±,bBáZeäµMÈRÂG»xàscïsËÌ$Ï™ ù”áƒÖÞê­saQ9P(\—ãc}Ãìu4¶°Ìþü˜ÒFÈi'ÿ¼FèüƒRÝu”c7{r›¶¿ß|L¦KG»!xŠ0ØCõð^â{‰wëà…§/W›%Ü”8u:øbÄ¡+ÓñŒ1ÚÔvÎäøpŸPX,DõP>þ‰Ÿ‘wò«ïóã?a™ûWe¤]šÔÅ£?}¦ö,[/áæ¯ 0Ë&·{Ïîâá§Í/ äq<|ð;7÷½¤þLåŸhkê/ë\|nÌ´‹”þ}À®D-›%†‰ßipé×™óä%އvÈpÄ%í\þ¯ºb«ï[¶<_)·Y¦/nçw®¯^åÛVøìwêüú|¡sÀñà®ÎyÆ(ú9N(ó¡Ê3ßnè^¼®'U‹—(’Š5Ò@ɺ±`ÑòÄ»´)VÕ¤>#hÄ$h{­'Í+kló½wihUtM`_@%PæPZ£„™P÷ëiÄU‰«™À(ªÔcð¯‘(EÔVÐ4¦œTkÉ褞|߆¹/Åp•o”œS‚1Ý^s®Ñ´sM3Ñ4G7í }¥¹X MºX3S0ÍÝ\cÒÅ˘P(6 ;S‹gBDPÛ4F ™ÀhÕy¬ ù\¨Þ{i4bM¦ãT62"@âœ$Λ|6\¾áF®Å+‘,§ e9åBà„[>9‘'z}Êqÿg”ê¥BN¡>ÀñÀg×_‹U†ºÖ¾"dW­¯d‘oÿy˜}G=\àY|˜Á"?ÿËX9¥:-msáGž¾ÍJ瓯…ëmsCð¼]±Û¹âÄQN:ɱp_Ãä?tpÃ/Çî ᣖ-/p<øš€íÏîàú¿4·>_[á‹Ç'Üy”Y°ý•–Ùÿx" X6»ªY€Næ_7ÂoO¸åõ wi˜4?-³ù-PÎ=ñÌœÛ=ý  |ëì gæxpË¿V†®¶l½À0ãâ€y Çž3lt©eÞ#]<òó2₩Áeû…ôÉ:—üÂ0³ ›å_b‡»íáYµ¡ûžˆCû„œ¶så±£¼ùÇ‚7™Õ–×Ü–Ö=ù;–Íêéñ”ó¶IëZö‘!v8ıtXª† ·…ìZUFaêyO|0[U SÖä…Íóáãêün/OßFÏ÷3kñQÈD&‰– Qnÿ6_¸®)ŠiÚVyE 0 ¬®¤× bð~LÓüzÄ)Z®‚‘ä-*ª¸¤!Šj½îñ>Ñb†D Î'ê€À¥û×Q êD¬ljt·gÞpƒÖâ¥"›1%±ÁƵqMe_˜têU4u&QkÐz ènGo ‚@3ç±oiÆTŸÚ"–êåQ§jpDÙœZï©Å êqƒ(0ˆ¨º$»DŒµ*ªX! ˆ¨z/Õj<0©·ÐZ¬´ø· ؾÑÅý?ê§ýĮ́ðéI©‰Z´ ª®ƒ¶ Ùå9)„xÛê½jBÇ”Ác*|r‚g0Rª;z~0oM^l!³J<Û'ÏY+Ÿ[“ëßÝuDJ祤V'èÐh‚ØPòQj7ÇuQT‹Y«êrQ–l¦@=Qêõ$µŒu/"EãX%°J½á¤»#»hÃŽ\‹ÿ<‹-:¦tÚïW†+ó];ùç5/´€í.Œùëq5~z$9@vûÝÚe„žûa5u.Ü#ÏY¿}¡m¾ÔüÇ2íUÈ>úŸªï¥Æ³ºXç·gÔ8û»Jej–wžø\CZüwÓ?ܘÚQ ÌHŒ·mÞ ±§ù¢”t‡×‚:ðµ:ä³øöÑ Ýº ¤/Ù0ÀY›FãˆcÄ;$ñHA! żh'ª ‰¾úå ïIDATêœs–BÖh[.b¸æµ\IÔƒQ¯Šˆ¤ i$‰Ä±3I⥷3sÿ†·/ •šë*‚À¥Z<µàÅ iÔ{Ÿ™ > µ{m8´3•Ä IÅ$ jêÕ”,µC¡io‡h&¯ªÆZë5r9+½]‘f¬—j#a´\Ç©¤žS‚D’8@÷¦˜ ·+-žý:Ì®»¯}­Áùaö;’ÉBæž Ç” |þ°«n;k”7o²ö3 ·DClsàói;UR… =åY}$D Ú¹äI‘=ÚøÍ¥>ìxèã#²ÕÚ÷ ƒ!¶=à¹úlþckãW/ëqÏDÓÎï-º-^^¨bF+n£Éy_®¨ Û$óò„3‰Ž%mÐD¡£ã‹0\o¾h‹€‘5yŒE=jS'ŒmnÑz‹ŒŒªz…0’ZCÛòµFBM#ª•8UCzƒAɆ¡#¸ÄI˜±$‰¾lìPZ¼øŒV’žžŽ€J‚¨)‚ £Í½(ðµd,D­$©P•PÒ]eµ5¶™¡.,ˆ—T“(NE+åç!¡-jÒhàO]C­V$°õê1Íe#¢P4q΀ùê"Zü Tv‹¹iß>ì¨> ’(õ­A0ýǼo¬l†ãGküèÔ˜Ωóó«üæˆVB<^©oN:ù®|>íÆÿγìCéñô3×½0/Žxý{üñ» .ûc?¹; ZqRß |Ò7 f¾À‘xqxÙJ©-Z¼(W“î(—)ÖcÈDââ"“îþÒô"–ÔiDë)¡Ýt¨Ž&ІXK,’†csÍôu¦ãCSïÏÔYÒûżЧ¤YÕ(dh`˜ÑŠŠ±hà NTŒSrù@ÃÒ+"qì—NèÎ>%‹ÿN¼'­ùYÓ¦ä}¹‚Ø"Z0–nاë¼.N’mˠõԡ$Hm½1¸±X„êR/b1M§ÀŠE†U5D¨Zïh+„xQ-ÇASЈïq ¡µF+ı3ÙP+ä‚Á 8l-^ùѶ5¾±§gÅvJ}2øŒÐõkC÷½Eν(dÿ'eZêàÚÔùõÞe>zŒ2¼9Ä ZbwUÄAkœ0¶6Lú†eöügj?Ë[~Sã¼ Çû.^_™v.¾'æ¦ýJœp´gp.4¦@´ÒÐ}cÈ^‹Ðb˜â “¾a˜r× ™ÿ -a°E‹g ‘PÌf­)×¼/äÄ bšöXžf° £ª Ä–bâÞ"ªé6Ø`MîbL3°´j· À{4HsÀJÃ+õX40ÐpVFÄX¢@ÕyQkUSC‹h&c±Æ"•Z]2Q82y|¾%þQ©%Q&Ê' d"tÌ¡)õÿX£¹ö4ö0ZN+±G]ªR L𦮡ŠxŸn57M7Ù¡&]°ˆ—T@ÌFJÆzFÊ¡jÒÿø•ªcQ«‚1ˆ†d2ÔIœ¨„Ö,í(f–<Ûßբź4íêÿüáY 7iúœ÷ÌeŽÍpüן­®žçÌg-²K½‹G~þLe “\7ËŸµ®—’–0Ø¢Å3  ŒøJ"ˆ£é ÖÓ ÅfAk^\¹†täð±B%FÖâ $~Ìò´©Y;X¡µ¨÷P©z­Ô=µzB­î4 F†KtwD8ç´ÚHPDŒ(A›F¿•‘RMòÙ :¹7÷²Ye¶xiˆÅ\ÖJ߈êäqâPŒOB´9?´ì°ÎkKíëD mHb QRç#iªRÍ7h­áÅ‹Ñ8Aã8¬Þ7㜓\ÆøZì0VTðV+Ú "^ÊÕ„b>ni­[´xyÒ[´x¢@Fë>CÓÒôÔÔr‚¯ÔÑÎ\êa\©cŒ–JÓPKS/TÕTm£¥ªR*ÕI’D¼­7<Î9UM(òŒŒT@¼ò‘öŒ'ÎDÖj„jˆ±¢mÅŒ(iG{T›Ü›¿Ãi9<ýï!F ÑH3³Æ@Piš1ŒÆ¸JÛÛ†/'P‹‘Ðb£º6…?h¦Nl&LôªV°¤žñ±­ÔÒüÂÕj]c­ÐÛÑh4h4Þ Ôˆªj` ÆB”J5Ú‹Qm\Wöž 7L-Z´x&ZÂ`‹Ï@62C£U×74R뉢¬Žë¶‚¢¡¨U¨ÅЙ#øjÐ$Í`ÚüWM3èîð¨§ZS©Õm4¼S¼w$Þ©óŽb>¢\«K=nhG!0IÜð£Õ†ä2YÅ{+„‘•|Ö˜J¹¢“Æå–u·g‡y®±´Zü…2Z×4¶ ªª¦1¢!h¬h­ÝE|¢ØZŒ!°BÕ»f\AšêCß\¬x´^JåzCÔA­¡êœSïÚÚò”+uœÆ m¾`”†Çd B«Qh¶bÆTÊ5ÍçÃÚÄžÜÖÈKµÕ¢E‹g¦% ¶hñ X#I[Vîʆºçò•Ué(潆FJ±hµŽt¶Sm@¤¡gœÃ¢$N±‰C¬Ái _)yê §‰sÚh¨xŸà],ù¬Á%^jõªõ¡–« ÉFU1íÅU«G˜Ð[X=¡;÷І¡’BÖöUênùh©2q™†L›á<¦`©WSªÁ¸|êE\©c¬ ¥Ajeà!Oilú3ZV††©7MœÇ;Ñ$ŽÅùD=J[[¤#åšÄqC#«’Ä Sª6M¨¹Œ%vŠ÷*½=³jõ°Nì-.›ÔÛš£-Z¼Ü †yÝa8šh¹Øár­˜Àd2APÈ‹ŒQc TQ††cÊÕX“FStAU Åœ4ÎÔFF’lƨ±Vp ^­8«ÅHÅkįœ·ioËQ¤Å 9»ló…ënY0¼çý—d¸¢‚ØjU™5Uâþa•á’`Œ#ĉ5FÅ£XÍDÆg3ÈpI®Ûr%Q—xœwš$±ª* ÚÙž—Z#6•R)1¢dBÑ®¶Œ Õµ–±ªÒÛ•Ô1:Z·Ù|Ü c[Ð-Z´xù¨ê‚ ݉-^îX#µYSò×X[Ûe¤Ïç3Çu7RΊ$ ©–+L” °Jï%[P‰2¢ÃCžF#Á%¯爈FÆPÈEÖëë.1Fjç‘(@Ämíy$Ÿ Ê]máýùl0´¡Ç¢ÅËl(ËÇu„Ãýî½TŽÉd-Õi¸¬)Uâ¤Ö¬ú¸Q7Æd2ä²ø(0 H#V‰©ÖœºØã5µ ”¦ã|>—¡RmØ$®'¹ŒcMêåUlh¶C¼÷¦µ+gN*Üßÿû©ñûNáï Ý/ eU éÊïÿ·wo»mA€ÿ™].IQÛr›¦Ò6-r‘GÈô­ú¦Ú´IÜ ’B‘²xÚéEìÛ¢‡B¬ùž`÷f÷ÿAbÇóOµÇøÅÛíøª9Lù¡9¤ïŸ]!)éþxÿÕWU–U‹¥× ›í„»ã€˜’¦˜$¥çYE‰ýh‚‚™4ÏD„ÀjUÊõ*ÿíj~É<Û¡kþVLZl›øâíŸý!/òº¾KÕ r9øc;FŸåðÞ¡Èä¨*Ö<-¤®{íLj'¤•êÊα*hJqòÌèûŽr\_”{ĤX/Ûù,»µ²rˆøçûGÌ£ jaИÿ@îýnxqó{ó’ôÉõ‚ƒJß |´ÀjÄ;ÒF“vCï½ú¡CŠ ìX©Ï%jÒ—ëâÝÕ"¼.‚Ío5ÿNLRÞ¼ëjSÞ6<¶Ò¤¤»6Á«¨JUzY_ Zï#öMÿPV4¥¤Ä"Æ]?„ô¾¬„@’`>/ðäªøÕÊŠ1Ÿ? ƒÆüý˜»fú:&a"÷Õf?®D@eîÅ9@‰ÐQûnÔ8M v48GÊdY︽Xf·žV³Ð¯Wù›SïË|ÞDá6õø¼ëc~»9ü¸˜Ï\Ñ$N‰œ†Œ±\x%†Q›¶×iÁL‚CG UG Á{rY®O×åMQxÌKÿ¾Ì]{Òc> ƒÆ|Bªpc”ån?¬cÂ,‰¸iÒ€@¤žå˜y¼ç±*\S•YÍLrêu›ÇKD³ºžnêþÛ»^¯wúñw…$ÇQÇqÂ0LˆqR8VïœzÇœe®ÿî›Ë×eà]UºÙ¥aÌ#caÐcÎÄCY©Ûñ2&-ðq؈ÞÊ!UQÇ$Ì”ÊܵË*ÛZY1æñ³0hŒ1ÆsÆøÔ 0ÆcŒ1§caÐcŒ1æŒY4ÆcŒ9cUæB¯ÂIEND®B`‚openchange-2.0/apidocs/html/mapiproxy/mapiproxy_struct.png000066400000000000000000000354121223057412600242510ustar00rootroot00000000000000‰PNG  IHDR=a=B¤sBIT|dˆ pHYs × ×B(›xtEXtSoftwarewww.inkscape.org›î< IDATxœíg˜TUҀߚÈ0 9 *E0 FT &T]sÎw]]×5§5£~ºæ,Ä,( DA¤ Arž\ß:íô4=3Ý·{pÞçé§ûö=¡ºgîí:u*ˆªâñx<žm™ÔPÕÿV££NÀ»ªzUuÉáñ”GZu àñ„‘öØÿäJU]YÝòx<ÛÍ0¥§N5ËÑØÉR¯šåðxÊ$¥ºðxÂü\[Ý‚x<5I‘†"’GûZ´É)ç|š›3£‚qjÇ"“ÇSSðJÇãñÔ@Dd?™«€\ùCD—Ñ%SDžÖ›Dä}É ¯ˆ ‘•Àz`½ˆ¼'"­ÃÚ%" "æ\ "—Fȶ»ˆül‘e"rA?ºÇSiøí­éˆ)¾+°›à¾@0AU7D´MvvV3Uu]Øù`'w83qïü¤ª¸6Ý9À Uý=ë»c¦s–?ªj‘“©½kºDUׇõk¤«UõÏX¿§ÑûŸXì Ü/"KTõµˆö7¸ö퀓€+€‡D$ˆ)E¯=“î"ÒEU7ÍMÀKî¹;v?-" Tõs§H}IÉõ¾x(Jú7àñ$UõôlÄn’Ï?»× ÌZ„µëq^1%é²°6§…»[)*p†;1ÆÛ@ý°1V¸÷ïrÇ)íCÙÀ€³Ü{Ï„Ó(tïŸRÝß³øGéžk»9îÿúͰvë(QvZ©À\÷Þ{®M¿°ë§{¯!çÞ»64—{®-pºË\›'ܹsÂÆäÞ;8ì½Wªû»óÿ(ëá··<ùÀ+îxWà©|ˆÝüV?aÖš!"rd”ñ~>ÆÌìÿ2€‡Ë€…˜¢ôx²}†­VOÂ|}§TU'\»A"’í^Ànü+bù<žH+ùØ ,ÀüÝ:„ÎEiÿ¥ª.UÕ"ìúhàž»…µ{UD–3±ëìúè$"ßaVžùØb§YÄœÜs1ð‰{=³ y<5¯ôxÀ¶ öQÕs€Ý{»¹çã)1cŸ£ª7cæî\÷ÞeQÆ{è ªýUõ£°6ã1«Ò(à ÷ÞYe9Cªj1pœ“)ËÍ’¯»sÄ|[éæ§»sÝókªš_Ág÷xj*ϽåØ"ä$`º;—¥ýü°×…ç Â^‚-d>ts< Ltç^ö½~£d±Ú†ý^†‡œ«S±íd§Fã}z<#Ã^¯qÏ!E¤cع ªš'"“0“vøùo:+LˆÐʰ¶Z G0ÿƒéDžÙ ø†’Õm8µlUÝ("ÿ®.‘Oœ\/Déçñl+„üÕ>SÕÇÝõíz‹…Éa¯§¨êЈôþt~?mÝÛCUuˆˆìì1ÖOa¯/‘€A@6O Ç[z<«Ã^Gœ[öºMØëvQ·øµŒ1¾Έòø£ ¹®Ãž-@Ì™ù(ížtrïÜ…ý_OVÕ­)g"d ý›Ûršƒm;ŪŽÞu‡O‰ÈùFD–_eõ-׿7çÌ/œ)Y¤Üƒ-”ž*›ÇS•xK§"¾ÆÌÙiÀ­"ræÙÒÿ2†1F{c Ö(l»ê@àXU}«Œ~!þfluÙó*…ªÎ‘€1ÿ$€ÿÅ —ÇS“yÛÒ=s¾sà?óµ ñ-–˜0<ò'lë)Ü*sf9=³è´Å¶Ä^ÀYq1ß»•ضVv½ãæý@-ròà1Ìz»¸øæiÍõxj Rz³#!"1“ô­ªz·{op0BUû¸÷nîckËà7ÀѪZ "§aÑX-UuiØ<õ1Gdzd%ûÿ¿©j;×nf͹[Uo‘ΔÜ@‹±­°É@÷^ŽZ˜-"r˜“Ì2ÔBÃBê=Çãñ–ž›{°ˆª1ab)(mQ©êƒ.ŠädJòô|OißXX:@©?ªºVDöά=ͱÄg3°è¬`JØ×o–ó)8‹BùØõëçÚÿ夬ª£Dd&–Óç}¯ðx<'oéñlóˆH +ž^ 衪S«W*ÇãñÔ4¼¥Ç³=0¥ÒÄ+<Ç㉆Wz<ÛC°mº”8dz<ÇS ¿½åñx<g‡Àçéñx<dzCà•Çãñx<;^éñx<dzCà•Çãñx<;^éñx<dzCàCÖ=gGDš±Ìåe=ò±LëáßU5?Ú˜ÏöˆY÷$Éê—ó(~Ãn´¿…jfy<žø‘T 'p¬{ìŠU>_ƒõ ½®´Ú‡=ï,æ#wTõW<ží¯ôx!"iX…åc¾ÀnÀzì»Ö=Â_aU;`7Ü-8È=F«jq•~gADZ`ώĪ›æãUµ(À˜iÀ.ØuÙ«è¾+üŽª.LŠðO Á+=ž˜‘(¹é­C7ÝïãQXD¤)¶Òìà}€¡Ø wœúNÙ¸ 8Ë:þð¹ª.­„¹R€Ã€Ó±Ãs€·0hY²çóxª¯ôxÊEDÒ €Ë0Sø—ØM÷ Uý3Ésµb7ÜFÀ»ÀÛªú}2çñx¶D¤-p¶ ¸¢ªyU8:pv=öžîõ[Óžm¯ôx¢âV|§ÿÁ¶ îÆVÕö“ˆtróÄ¢ oVÕaU1·ÇS¸m¬[ӀDZ"ºÕªhˆHkà>Ì t ðŠ·Äz¶E¼ÒãÙ éÜ lnQÕoªYž#€G€?ëTuzuÊãñTÎ9ùvàràà>U]]½R•FDzb ‘kTõ»jÉ㉠¯ôxþÂÝÐr€[k’eÅý \üø¸MUWT«PO’‘F˜/[.p±ª.©f‘ÊDD8 ¸ ܤª‹«W*'6|rB"r5ð>¶o¿gMRxTµHUŸÁr‘lfŠÈ.TÞãÙf‘®ÀDà{àøš¬ð¨ñ*v-Î&º“ÇSãñ–žÉžöNRÕÕ+QlˆHGà¿@ ì‡âjÉ㉠®RÕwª[ž ˆÈ1ÀËÀµªúfuËãñ”‡·ôìÀ¸ô1XÒ²·…@Uç¨êqÀkÀxÙ»ºeòxbEŒÿGm« €ª~Ü-"·W·<Oyx¥gEDzaæô¡ªz†ªn®n™‚ ªWŸ‰ÈñÕ-Ç#/bywöSÕŸª[˜DQÕÀÀÑ"òš³ {<5¯ôì€8“úûÀùªú`uË“(ª:Kšø„ˆÜPÝòx<å!"·{}UueuË“,\ޮñߕ‘"Ò¸šEòx¶Âûôì`ˆH`8p¤ªþ\Ýò$i‰}¶ÉÀªZXÍ"y<¥p ŽG€jºÃr"ˆÈÀqضù6iEölŸx¥gBDZã±ØÏª[žÊ@D²×Ýáɾ–—§¦ "ûŸG«êÕ-Oe#"/µTuPuËâñ„ðJÏ‚SÆ/ªêãÕ-OeâŠ(ŽÀ2HßZÝòx<.h`°TU/«ä¹êb7Úð›nðV½y1°DU *YŽ&Ø6×õªú^eÎåñ”‡ˆda Ž×Uõ¿•0~7à÷Ȧb×Û’°G&Ðhåžwº£€€*ÿÈY—¿ÎVÕ‘Éß㉯ôìˆÈýÀ>À±Éösq ÕÁÀ¬*s6v“]öHÅn´¡›n3ìÆüðªÎN¦La²í |ôÞÞü—<Û"r+°ªžœÄ13« 4à=÷˜kM,iôNŽÀ$Þ©ª£“%§›ç`à ç¶”ó}╞í9 x ØKU×&qÜ®À•À‰Àrì†;Ô…®VÔ7 ×=8Ø€Y¢žRÕeÉ’ÑÍu6ð/ ‡ª®IæØOEˆHsàg,4ý·$yV.æGànUš„1kc —¿OæBAD®À4ïØì©V¼Ò³ã¬0“ûUõí$Ù¸SVžÞUÕ¹ ޹VQý\¬ ÆCªº!AQÃÇ è„…{ÇfO•!"Ï«UupÆj]M±bŸ£3ÊéÀ¥X%õϰ|I‰2sŽÍ[TõŠdŒçñÁçéÙ¾9»É$¬ðˆHšˆÜÌΝwVÕ{UxTõ÷£°æ4[D®p7àdp–uúßIÏã©çkÓ¸+ c|‹¥dا2U-PÕ'€ŽÀ2`’›;\ ‘¶IÏã‰oéÙNqÑZ³€ª:1Á±r€¡˜’|…ªÎI‚ˆåÍ·;–ž¿ V,áºZ"ÒÛfØÓW„öT"2Ûò}&ÁqNžÎRÕ¯’"\ìs‹mÿSUŸOÂxvSÕsËã ‚·ôl¿ÜŒN‚³¶ÂœSÙ €ªÎTÕ~˜óãÄd¬4Uu)ðp[¢cy<!"ÇaûÏ%8Î¥˜ÿΑU­ð¸|^׋È.D"<ôq¡õO•ã-=Û!NQùØ;«†³¸|<¡ª%K¾8eUp¾MUÿ/Á±³±l¸¿&C>'"2xRU?H`ŒÞX¢ÍTuaÒ„ &K¶Y¤ª'8Ö5˜CóiIÎ㉯ôl‡ˆÈ#˜/Ï- ŒÑs‚¾MU_¯¨}e""€WUõîǺ 訪KŠpO"Ò ó}k¡ªùÇh…ŸUSòÛ¸¯P¾¡ÀÉ]¸ý\àø!3µ§f‘""uE$5ô†ËÝz""õÂŽk¹D[¡ãœrúJDßLwÑ„Žë„›J£ô­vœÑ7[D2¢õ2VºˆÔ ;®Ñ·¾ˆH}Ó¢ôÍ ;®WNßT·: g‰H­°ã2¿÷Dpòœ ¼À©À[À[Õ­ð¸-µÞÀÅ"’èêð̼¾{â’UŒû ÿI{ñ?OÛˆyÂÛ¦VQÛðëH¢´MIRÛ´rÚ¦—Ó6-¼m2ž€Â“‰¥px´¦(<.Ô¼?p­ˆŸÀ8y˜s÷É’Íã‰úÁ‘9ºÏÌÆ¢{ °lå!gûÕXrÝ&îøwlÛºV”¾EÀ| ½;^‹eBo掀ÚQú¿Üñ:` ÐÜ/ÁæDéy¼ XƒåÄ HÈBúØ\ %îMá}7«°œz`éh2>6hƒåÞ‹ì›ëÚïâŽW¸v Ýñ,P)ò{/>^¬:îw –ìQUÝ7H7Æ}X$U ñ‹†ù 蟈¯’ˆ\¤ª’&\™sué'¦B÷=~š }óìõÂTX%°·K9&z@–nÝv^*ä tqmGdÀe´ã~ø;º¶_eÂáùªP$ðEFÙm?Í„£]Û-c3 k;# Ò#Ú†ÆÙ"0.Žt?ôSÓ G¡}ÑÖmפÀô48ĵ’MŠaç$´•=]Û‰ïÎSÕ-eþ* Ü´¾ØöÏ1ªzlr%K"Ò«!ÖGU 8F:–è U”Lù¶žk×Ð2Nt%7~J‡qõáò%­l 7……æ?×öÚ=ÜÿÒçµau: ZgÇ«^i ×./éóh38ûOhè®ÉWëC“|8Æå%ú.fdÃE«Kú<Ôn\Zr<¤ ô^»¹kìÃ:vÍp)<æ§Â' áÊrd¡!´Û ‡æÚñÈ,X’ syÚ¶O7‡ëÃr¢=ÞNY -Ý}êíº]Çm²ãIðC\²ªìyŸm¬‡=]¶ý³aS* \oÇKR`hc¸úÏÒŸÿŠ¥ö› ðRh G¸kvt-øµ6œ_Îwödè·Ú¸{Â{9vÿŠö÷Ö-vmЧ†PŒY úi ˆ%yX¬ª÷ìßxóªqÉüÄ¢Ižzõsp·9À‰ªúC2åÛz®ÛQ¢­{ªÍS<¹*g‘–ÀO@Ë ¥Vœey¦PT˜è³º‘s+°¤‹|$Dä& •ª^“LÙ¶žçÖVPk[°‚Ýc·uÂZ­£d! ¶XÎÄ’]ä»~¡gÅrªÖ ë³[ˆ‡Œµ[°…nha[ˆ-ü³Ë™w£›#´Îss… ÅØb¼<Ù7c‹“´ÀÍ]žìœ\¡Å®{웜œ!Ùó¼á²o¢ÄX£.%ßY4Ù (1ŽD›w£;.»PÆß{‰Þªq¤‡åééLù0‡Ã Üƒ…§Ö8…þŠ&yx%1rÇ€ó“%—Çã8–@m¹k/k²Âãxû5931†aYÙ+™_2J~Áî±u"ÚÔ‹8ΦDáûñÏ ;J+ PúÇ×>#ì8ÒJC´yëP¢4€É]+ì8%ÙkS¢4à^W${¥ƒ¹k=;BöŒ(²çPšz”þ΢É^›ÒDûÎ"e/ëï=¤A |þmx¶mÁ¬<óƒtvûôu€7“*Uòy¨'"‰Ü0?À²JW2#kUÜÆS9ü.á>xUÄi@ d bÁW·'U¢JÀYw®î–0?Ï8ǘl«‘W‰Ìõ× ÇqöºèT©Õ®=ñ’<×(`ç¿á æ\x[Mò㉆“ïFàHÇÛ8Æø X[ù7ÜE•;¾§lê‚Y#ªgiíŽE8áTàU äÏ!Ëá"r·ˆŒ‘Eä¹MDΑ¤¸3¨êwÀ,ÓrP†aO+‘³“Vsг­S§8Ú$µê¶'QÒ«+l#±¼:A褨ê‡ûÿ…‹rë-"ÿt7ÚsÝM¸}²¢i\TË\ಆ©óúî~QQm4PU­ÊûÛNÀª§ÃR3FD‘ñXÀ\à^Ì2:³ùüâ®ÍdXùoÆFî}ÄJ(=O ‰f×ô$¡Äû?Ž^JÜ { B,L60"R¸¸‹Ì‡yÀŽ…±µV‰È`Uý2‘¹7ßˆÈ ªº1@ÿaXh¿ÏÒìIm@•ÔÅRrŠÕË „Ûž~»þ†–å`,V¸ô¬ÆÝ?IK¡ª Dd"p¶e/€F"Ò^Uç•Ã㉲Sà•HÏ"϶I+`…Ë„þ˜µ2‹ÿ頻‡¨ê?Tõ6U=[UUÕÖÀÀ"ò… AŒªÎÄ"e‚†öNH¥@|Ã__ÕÆä”,A¬ôG? +{ñ4êþnyUª:ÏeC> ¸UDÎ $q Ð?ÎÉ9K‘QIÜï£'=ŽÆE)pö†êÃN>–«!nYe¶ê©ê”€ý›_¨ê¹å­Ø\Zþ.˜‚õ•ˆô 2g·¨Ü ÷à°e(‡Aþúª6º«ê¦*œ°-Á-­{ßé蜵ÿ+ÎsÞUôîr©*‚2螸2Nf•X‹ëæe·ñìôÊõ!ë5Ž J'ÍŠ™Dn¸£öxxNUŸŽ¥±ªªêì†û‚ˆtM`î€c%x!Ä_(ÙräåÞpËP¸÷ŸÕ-É6N"–žXÖÕ œ L ’°ÓEzÞ‘@×+æûv B%+=O i–ø§¼ß‹ éð?W§(5® Ûÿ°L8Ú^×_çŽ(9WCþš é›àŠˆ¨¢gN‚Ü°Ò ™ë¡Õlè?ÝŽóRàésíõŸA¥ÄŎÃìË!g üã^ÞÆß™‹àöD¢ ÂX^ ¦µ†Œ8tArÆ L"7Ü–@Ðdˆûb[ZÅÛWU§ˆÈÀG"r€ª.¯°ÓÖc,‘ù˜?D”ý¿çè#ËRk~nÂÔ"Hɇ”íÌéz "’R…ш‰*=#*l˱ðñ@¨êX¹KJÚ+à0¡-®ÑúÎÂòy<•Ìœô4x§ *§Ñ¦4X–Äíý™pòT{=êLXíj°¬ÿŽRí°½á‹JŽG_Z1øãDÈkWz®ùÀ´¯àŸw@njɼ‹¦Æ¯ôä×†ÂæPà+)¶»$ñÆþ]gÿ$¤-ƒCOIΘÅÀÏA°Û<ò£ÁoÖ×ce/Eɨê{"Ò³P†aØ 7ˆÒ3‹JµôLδ œXÑ–·€‡üt˜·´ }æÂ¸VðË^ÐíØ/Ì*0¼+,o yumÑn&fõ{ý @àèI0rOXÛºLƒÙùÝfƒ< õœ?ɯõ`B7ÈÚ ÝgÃ×@a1Ú¸”ò_v‚Ma×ù›³÷†CFÃ+a~]³/lj õ–Á±¡a¦ÀÛ½L–C~€Ö›`Z˜ÞÒs¡ÅrX¸ 4[ Gº-ÒÙõarW“åä8·_ ¥” ”ì3YXÊÙ $béiŽ)ï‰ð?`°ˆôXâk`HÀ¹gED‚fw.Ÿ'[òèêbMÌkµ  ëÊjÄÃĬ48s#hdÊòP˜qª)=ós`ÍQö^©”ŠŽ9ÎW#e#×)ÇÀ¡ÏlÝ®ù«Ðó˜|(,º Öõ?„Þ3c)/†u‡U­ ¥ÚÍ(¹a†Ói1¬}Únžá|Ñ~ïdŸ¡ãt8,,±ßëÛÇë÷=ŒØ66€¾c Y.Ìj ÷t_K-xí`{=pœÕýøv˜Ó 3¡þ2Øÿgh»¾âÏSüÄù²1Và+-0g tî Ø7ÄÀe"²WÀªËñ©A˜ì,"i•Þ|Üf¶NZSN‚U'Àì™×É,¥¿ÃŒaéY ™0GaêÃp‰K/0ö ÐHɃâ,˜§0ë)¸Â}'Óî¶qæþ›Ãèoy°âF8i*LÝæÜÙßÃq7À´6ðÓ½º~Øù;»>Kàœ‹¡ÓZ˜4Ös§À–=AÓ õ˜³3L¼ ŠÃ>óŒ¥Ðï:8p1,Û–Ÿ ¾„›ï‚¡wCîîÐñÈÞdóf,†#O·¾ŸK.„Fð°ë8èRì²oW«°‚‚AÈ$¸r–…åÙŒªªˆ<%G A¶”’ŠñνADÖcÁ‹‚ŒQ>'¬aëTÀŒj£nØúýô•ðÏ'6ÿÈn0ñQÈø ºŽÎ«Æî £/„ÍìO[ Ù³áòÇ g´ Ÿµ>NŸžì‰°á ø¡|ÒÏ~ìëDÙG^–ë:=lï­<ʶ¼"ÉØ=Éì=ÀÚyg5€»^„Éÿ…ù×ï7Áè2§µ‡i÷ÂÔ°­­ûn†‘/À¼›`ÞðéËðTXïŸî±>?“_þ|dŸZÇKVQ}k7í^ؘ_ Ÿ¼fc.¸ ¦>ŸÛgJÎ ’Lk-%•Pã¥>V•5XQ–À¸”ýOafú Ì£¤*l¹b•ckÍ¡û ó-K.€Ž@Ë祇—´Ýw0Üv8Ü×ö½ÉÎ/:wë1Ó×ÀÑç@½¦<ýpUù25„fŸÀaBæ¯PØ>Ž0 oé-^‚î×CÛ%0ùŸ¦ð4yŽ?rÆAa á®»‹Ÿ…Z3MaºûaSx|~ ýfÚ¹üVðÁÞÖ~•ûœ]?Ž÷¬Qzð+X´sÀ¾á¼‰ùÙáO ‘¤‡b ·J u *7dÛ‚`ó^Û>ì±kåÈ´-°*>}֚ˡ°>¬:ÑÜ^¶MÒ`nZI%ôŠèøLݾ>Öé‹¡ñظév÷6…(k:œ3n½ ›Á°}à”ˆ€kºÁ“ «¤:ΊMž÷¯´-²Ì9ÐýQh¿¦î[ß7‚Õý!íO8óBØ’C_……WÀ¸ñp`ØŠC  Ïy0î»(&ö‚ã¿€u÷ÁÜ¿Cê*8üFk[»Võ…Ôu0ø$¨W£ãüAÝ‘>_#ž£½^4ŽHþ÷W› ÌÆË îx"l]%ÿ‡)/ÇÛÑ­UDêÌ×Rzæè[#²,gd¼Ô§N†!»À†ƒ!í¸à ³ .¹¶ì^ÒvÍNðèI°¹ »mqXXvû>º½cÛ^¹ïÂè#!¯=¬/çæ•².x jÁœ¯aI;ذ[„œãáÚ—ìõ´&vûºmuýñ!L9Д#€œBè;¼÷ lêaV‹,¯íP˜ù/˜Ù­¼¶¦põ °}3'ED2Hã/‰(= ®ôÜYKªÊ®ªËDi¬ªqmèjžˆl‘úªdÑVDéJÕÈ• UÄ6å+½ay7h2Ã|WgÃ[ç xÙ¬øóêÁÇ'æ]ÍòZoViX€‘í`òI¾z ‡œ/å;ûƒ ¿¡×Z ¿û»-Ï—Ž„] Í8Xß–í§Âñ# ¹³òÍ­ ‚ܦÐj¬¹t,ï;M†AÎ’?±|{lÙ Ò×B§¯àÄ2¬ë“v…¦¶î8ÒoÜ×í AØ5õ}K{bɘ¿€¦•|ÞŽƒì%ÐjÌ8êÏ;ÙoýUOCf1 ÐCDòÊiÏxa¯O;ž@d¹0Û wCËø3¢ûÑ~½RW@»g ­fºÚM["" ]HqAXh±”£ kŠùáPDI%Áˆë½n˜2’¶¢Îsí‹B?daýµ„b§ÔÖ‡ù  ±óÙ;ù˜}%¬? ¾wÛÁ-Zyš(p¿ˆìú@<'z®Ð[Dúèßè#"‡G9W‘ÜôrIÃ÷Cñ”l›Å"S!ð²ˆ,+§MyýŸ‘µeœ+¯_+à¦æ-ç\Ç÷àBbgX?HË·×Á)S`Ÿiðú °òD9¾?ÖÍ^7…gjSxçE(ªg¿éÀ¦}€0¥§°|ù¬/αyö;Þ~#ë ÷€Ì? ¿¬?><‚ë`iXÓVÅ®²çÚ£à•v0øQó½}é(h ’3¶EKQCóee|Þ ¾yÚ~ó²¦ÃÆ}á»ãaÍ༯¶þº-‚oò °L?Ãõ™e–—²ÐZð¹°Ë$XéÌUu#ª§„)3»¯6ËM~+øò|X6 æžjç²]þ˜ÙõaÒ¿LÙjü¬8†ÿ:_f²Ô-€fÃ`Éy°b€ý@0{w^¢dÛW*xNô܉Ø5ø|€þ½°ÌåoF9‹ÜS1+i((a'`UÏgêŽ9Ï(§MYýÀ¢@çÅÙÌ'i ð{9mþ2 )]2¼~»®L=VÁžwÁˆGL™Èš—»Åéç™Â“5ο vÙhnágÃ>7B¿)pï[¦}¾ô gèeíS6¹gØg~îåÒóO¼È”ŽVÏÂÕ¯ÂÇ]`̳0ç* ŠÒÓr3´~Ÿk ÖÚ£`v>Ô? òJÆlý´Yµ>ê cŸ†9WRê~ZÔÀŒ$?‚õðUo˜·;Ì; ˜³œûGsŒ3ãR :Ý ç¯Ó®€S« ›ÂnwÀ)£`u Å…oX ·É)£aÅ[Pÿ·­M€ãŽÒ—@í°UàÆ½íå“Cá‚ÏKÞ¯½Üöòƒ3ɢǜo®Ö‹ang8/†›dËi° Ó;†ÃæÀOÍáûc¡ÃâØæï¼Æ+52G憫ìø“#a¿ñpÆ×0ô@sÎÜÜ®âñÀÔG”rJŒ²5µÕê\DVƒ8ãŠÈoÀ±>7‰ÈØË'˜Cô.ØÒê©xê¹U^F¬´"²Øõ´ˆÄÒw°^UƒFÏ”3öƒ1þ݃Òg$~ ëÜà¨{ ËY7C÷÷æ_™ò°OD ŽÔÕ6Ø–Qa3XÞ ˜ _óφ‚V¥ûlŠðsª?Þ¶~6Ô² ;™¯ìê]í|Ö,;=­DV€Ü]ìyñ%0ø’’÷‹ÚÖ\û(×Ù•o¢áðé°ü@Ø´?¬é Ã'š%'ÏÍ»è2V±°1ü^§ôg¿t¨ÛùɃãFÀcW›Eë÷GaÍánÇÄé¡à‰Y·Áà0?Ýü]KË—9¯ÄJ›cu|U+>ŸƒìB¸ñɲϯp–Ÿ¶/ÂaÅ/=ßBÐ |µkÜ |^Ú¶t3gá©Øþ?1(=§O€ÅoÚVÝèÿƒÑ. M  0ÆT»­†º£Ì?í^3Íõ¿]kNÕE¶C‡7}ÄØYMp‚ÑÀ+"’£ªqgVÕ/\‚ÁAØju)pr€Â‹ÙùÝBÉL¼Siþo䔟"’ß‚# µÛîé5]9îï²ÛrXyU‰•³Ý:¸åøx?¨µŽœ#ÝÖmËÿ¦þ÷ÂÂ(Ðmìógé9êFD¦n„k.†/÷±mßÃ'C ÷7=øX5v‰ÈïÔoì|Ý64‚†ËM¦œBXY º¾¼ýÝvôù„á€ÚVZZ1tYe&íÍ{B‡áq|yXŠ*Ìʼ˜Ø}J¡ªëœâsV.ÈŘ¥3PfuGCJ[gãaWJ[jâ!| µšé=9ú‚þ»V°áÀ’ãoÏ€°×inKo}9ÊUj˜¯S¸[Ⱥtøõ³†t¿Žø {¶"×·™nŒð­d€Ú«ì9/Ì/,7¹=uƒ4} ZG¤%hå^ý{ØiV®K†Ãà®;a}oøsO`„í”6…¦oBëוúa~?˜Â¢åf¨?ÒG¯ ¶í¾z_[d(@ÊSÆZ= Íæl-Û_ßGÜùåÒ`× , òàåÑ6ŠƒZ¯1Ðì7h°Î<º÷uáˇFXoNx¦N-1‡÷º¶dA›2„Î),™wß2LÛl€;.‡Ow79¥:;ëR¯ïìF^ßÝȻϹ ²Â¬7>“Þ‡Ù /rVÁ!ÓK¶ßz^eŽj»¸1ú þÃn ·Þ3Z¨n¦Û>ëTø¹#lj —³ì ÀË aðªØÚÿÅr‚G0­‘o0óü«ÇX‰UsN„º@Gd°è•…ûVâ wÐL™‹‘ƒQ*lw÷ÕöÑ8×ÂÌé[Pâ¨[ŸçÄ(e "ç§q. вr?d° ì>§EÉõMö[J¿÷öþðÛ‘°¹dOŽ>N¬t/V}§*ËPŒö‘Fªïõ –vá|*=‰â,UàÐï/a ž Ô"Á(в™™»UÜì/þwæÛ„mÃþëFûmûì?–¢Ã}°p€í2¼<Î ; 3{Áêcáþh0 Vía‰q+"?Õ¢)IuMáõÓLቇCǼ-f=ºý< T§É7°¸#¬íeÀÙkay'Xß~¿õ˜³ZÂ×ÿgÖãìùPX6¸ä• \°QãQðGXÛüêÆì :D3œ=†Ã·ý,:  SXž¹£`åɰò¨·Ä|—îá½+·<^¨— £ì–„‘Y\’Œ0{®°Gˆ²Ú¶ÙmÂÎ[A„VŠ–?o8}gJV—Õö±ËFØ%Êx=––øð¤Óx÷eöˆ$r®®+ƒ'¡Jú‰~˜´‘&ª$_Ï[Xfâ@JO¢¸¨³=)íK»<ÇG ¦mn§dý¤Bv~lís6Bí!3î Ù‰³rWØÔ ‡#^©úùƒ£ª¹"2 8†R¬13xFDvQÕ “D8ø6`ë?È~݆2•èD]7>¥gÓ¾aîÇñ™K!¯£¥{¸ècý3|ú?øe0L˜e[=CÀÂó,ÏÖª =F°I.ìò¼õûw¨ýdO‰£:¬ƒýn†©×@ÞÎPo,¤~gAB©N™¼äux*–Ÿ³oµ÷R6C£O¢Ùl­É²©»æ€í„4~Îu»8¿Cjß"ÆŒa‹·ÿÏðýÛ²J_R:ùè9Cà%ÕÇÁŒ;ܸë¡ÅÛÑFŠÞ›ìšH~OÒÑYªq[z‘°=õ¸©™ç;Æ®š Dd/àMUçîꛉ…ìgÉèê¢^.® ÿ‘+;Â.A Èzfu>Ü÷ƒªÆ§%98Ÿ˜CU5ž=Íðþz¨ê€äJÓÜï#TõÙ}ûWÕ¸³ª‹H°TUëTØ8ñûô$ÊŒ†PœbÛ´)qܶ¤Âu¢ûÖÄÂçàÐyæg4©¼÷’9Oïõw4¶¤]±ÀôÆZ Ö˜a£<òR`^}ÈK‡N«¢Å;f¬¤ÀÏ¡V!´_[6˜%iðJ”ðáÙ–øK.·Ò£ª›EäEà.,«ªéKÔ‚˜­2ãVxí¨´UæôLóëöT=+ËöYeJæÌˆ¤T¶þ L‘>ªôzˆWlô ‚סkOpž¶X ¢í„.}¢²Š‚+<`‘T£ºAÊ:óݨ;NpOÑÒ»3‘Y\ñgŠwÌXI/†½ãN)48{hV2õ$B>ð\“>=`JÏ} Üpÿ Ì‘îª:¹¢ÆÉBD²€+ñ+ýyD¤>0¡Z Ä[†Â“<:Vu Tu±ˆ,zc+j¥¾ˆ\ ‘ý‚FràvàqUÑ÷p+úïì›H¡VÏ_ìûÌëùõ!c-ìô³å´ñ”02+@Ⱥ§rÉ.¤1«ê.tûÔÒr™oÄü ªÂŒK±ªZŽ—~¹ôâ“u´¥Ò¬<ž”O€~Pzà¯hÈa"rTe_‡"ræOO¿ðþ9X"ijŠÐŽJUzîoƒ+oøC¿(¾­žÒI%…ézª‘OH ½ª¾ ü ¼QÒ¢R‘vÀ?0+SPïìÛŽJ5­ðVÔjcNŠˆÔª†‰?ŠH"õ‰cŽù¯Væu访Ç3°òôàƒnÍt!ñ*ñåps”àÏŽÉQ›ŞÇSsP`A"áÓ'EÉâgcá§%0F…ˆHððU ´B‘.@jNÈ0%¯’h·G…Õtš(Õ•§ª“€9ÀE Œ¡Ày@àCi$ñþBD:#¨ê´†@ð­-€>”ΆîñT)æÓã©9_öqÙPW§'0F–³ç0yÄ)'IÅ­‚_ÇËIvY!‰XyÀüˆ¾I ´‰;C¶'Y4ЪŒÜŠààV‰#GSiT58ø«o·_²„‘îÀ×ÀíªúbãdaÙm‡ìßÈUUïÓã©–¥úí­G:p~¢Î‹7w%b^w޽‡‘"´ ûV¸å0,)Q`åÌXéqrì‡Õ óx’†ªþŒ®Mpœ"U½¸ øHDž‘–AÇ‘,y z¸ZU_®¨O\|ž€ÃõÑÄ”A?žOº•̳­2<'æ{gæí W7g: †ž»¬²}1ød93Qÿ9øË tš[Í«'P[UË©7U.‡“ðeˆ7üöqµae(ªQ€Û€ëD$hy˜¿PÕO€nXÅôé"ò°³’Ä„ˆ´‘;€ÙXEó®ªc¹2ÇlÜü3aŽ!xªŠéQ•Y¹=5š‹Ö¦ÀtÁêmo J^¯Ë…iù%Çóò`inÉñÄ|Èݽï†\˜Öw~üžWr<%6åFï»)×·ŽçYÿÐñÔ|?Zß‚-0!¬ïÒ\“;t<-ß>WèxtXߢ-0.¬ïò\˜Ö÷ç|XSƼ‘Ç+rá—°¾³ól¼Ðñ¸|›/Zß5¹ðNí$üuoþ!" %üRã?À@¬ â 9]Dâò;‘Dä%lKë&U½8 [ÿnM ÿÑÀ ÊPƒÜöqx@^.¾«¼†¿²Þ'µíŠrÚnˆÒ6Da”¶¹å´]SÃÚ†¾£îÅUXwk+Tu.0sÔOÆxªê ˜ão1ð‰ˆü."ÏŠÈßDäéáœýDdˆÜ."c°hκ@U¤ªÉȶ}+–P4ÐÖ”³´öĶÙ*‘=/¬<ÛžÏMDj‡V½nEŸîü;‘  8TÅÛEEä…ÂEé› µ m³¨jAXßüPÊò ú¦99cé+@­P¡K×7%dMp™{ Êè Ö7s ï[ú¡ïe¬È¾@QXß,`Kè»Ò7#@±Î­‘€…ªúïDÇ ³ð/`wl…övC]*Vêþ†;a‘Q=±„g ¼ QÕõQ†ŽWŽÓ€€‚&%‘_€ :qV0ÇiÐ0l7¹ÜK/ׂMip¹«3ößpÔzØÃ)ám_È‚ÜÔ²Û>Я,i[—¸ú‡ÂÉk¡M1¬ø_Ã’qŸsŠõE›Kæ¼`54T˜Ÿïׇ\B²g³-IØù[¶žóçTø².\¿&zÛðÏÙvHËîzNîÖm'¥ÁØ:pÝÚ’¶õ à̼èm¿Ë†k\ôГ9Ð$úä©Þ^­?x"Ò³lž©ªIÿq‘Ý0klW 1Ð+º ÿ ˜ŒmA%Í¿LDÚãÝÖ ]ÃW¨ê¡É’+ú<ÿ͆ï›Âϵá¼0íøþæ¥#»žn}ÖA{÷= s Æܵ7/ >¯W®,{ŒÀ›¡‡û?“‹3`ûß\—byØn S:i ƒVB3—møíºÐ¸Žp×ÐO0).,GögÂÁ`wç¸ÿq¶eRàV6‹Ráý†pÍŠ²Çx¥>tÈ…žîz_ æÖ‚³×–Ýç±&pòjhíîGïåX2ÃãÜ=hf:|›—¬.{Œç˜5.¤œŽÌ‚•é0ÐýN,O7ÃuaI j­€zî;{£´Ê‡CÜw6)3úß{ð¯ð÷³ "­±Òó‡Ž*gì–˜iº/°v³MÇœ¨`Ëí_Ÿ€×T5"q[͉…¸ž«ªcŽÑ¥ªý#<žX‘ÞÀ›@¯íÅaו¬˜¤ª$0Æ·À“.M†ÇS%x¥g;GDÎÁÌЕžÝUJ*-¯®Ì„j.âÁªzBc<lVÕ¿'O2':"rpÐ3dÝV‘K1æý‚^çbµö†m’iòx*Â+=;"ò0fþ>¶Cx“‚ˆtâ= šÁYDêbY˜÷TÕ •Ù=ž¸‘瀦À‰ Ô‰«VDä0,·V/U]À8/sUõÞ$‰æñÄ„Yß1Œ9>>XÝ‚$‚ˆ4ÁBݯH dXÒ·‘^áñT1W`–лª[ 8?ž7€ÓTxcyÀþ/I¢y<1㕞gÝ9èç¶»¶9œ3øûÀ+ª8¡s²¾ K½ïñT.°aV¢â¾ª(ó’,\}­€õ£ ã"འÐO"øí­éŒ®UÕ·ª[žx‘籨”‰l ˆHàUÝ'iÂyW• ÆXæä³TxR€Û‡“%ŸÇ/ªº»Wã\”eDDºß_$ªð8^𠧺ðJφªþ ìe#ZÍkËÅå3z 8 8ZU7&8ä%X†»7•ÍãIUÍWÕó×€ "²uˉˆåâºÉ%(Mt¼Ã€C€;Ëã ŠWzv@Tup–ævœˆì\Í"m…ˆì| ‡ªêÒÇkÜ\¾­FÎx¶?Tõ!LÿX¬¸oµ×‰‘TùðÐWU‡&aÌt`pMå–}ñxÊÇ+=;(n¥y.fõøÞ¥±¯Û]bÕ¤'¸”ùÉÈùó–$±Ò²/{–¨êeÉ×ã© ÜÿoOà4à,Úk(ð®ªþpÌVÀq@à`L!y‹¨Jjéw/ù‹üº#™c{À§Àª:£2çòx<[ã"0—úúvžš†Wz MAPIProxy 2.0 API Documentation

Contents

Revision History

Date Revision Number Author Revision Content
21/05/10 0.3 Julien Kerihuel Add API documentation for initialization, backend connection contexts and add programming samples
21/05/10 0.2 Julien Kerihuel Merge initial Wiki document and add FSOCPF section
20/05/10 0.1 Julien Kerihuel Draft document.


1. Introduction

1.1. Purpose and Scope

MAPIStore is the SAL component of OpenChange server. SAL stands for Storage Abstraction Layer. It is the component used by OpenChange Server to push/get information (messages, folders) to/from storage backends. The following document intends to describe the overall/theoretical SAL behavior and constraints we need to consider when dealing with MAPI/EMSMDB. It also describes the semantics and inner working of its storage backends.


1.2. General overview

The main objective of mapistore is to provide an interface layer with a common set of atomic functions (operations) used to trigger and dispatch data and commands to the appropriate backend. MAPIStore relies on a backend mechanism specifically designed to transparently handle some of the MAPI semantics required by any Exchange compatible server.

The initial idea was to provide to OpenChange a highly customizable storage backend mechanism which would fit in any situation and any environments. One of the greatest limitation we have found with existing groupware is the storage layer which is generally limited to a single solution, service or format and is neither scalable nor modifiable when user requirements evolve upon time.

MAPIStore solves this problem and go beyond classical limitations. It is not a revolutionary concept, but the way openchange uses it makes the whole difference and offer administrators an innovative way to customize storage.

MAPIStore allows you to:

  • use a different backend for any top-folder
  • transparently move/copy data across backends
  • develop new backends quickly
  • access all the different backends through an unique API

For example (assuming all associated backends were developed) a user could have the following storage organization for his mailbox:

  • Mails stored using an IMAP backend (Cyrus-IMAP or dovecot)
  • Calendar items stored in CalDAV or pushed in Google calendar
  • Sent emails and archives/backup stored in a compression backend
  • Tasks stored in a MySQL database
  • Notes stored on the filesystem

If the user is not satisfied with one of the backend's performance, they would just have to use an administration tool, change the backend, wait for the replication, synchronization to finish and there data will be available from the new backend.

Information can be completely decentralized, stored on one of several servers and still be accessible transparently from OpenChange server.


2. Technical / MAPI Considerations

2.1. MAPI objects

An object is a physical (message, folder) or temporary (table) but generic entity which can be represented as a 2 columns fixed array with n rows, where each row contains a property of that entity. One column repesents the property tags (names), and the other represents the property value (or values).

From a MAPI perspective (network layer), opening an object means:

  • opening either a private mailbox or public folder store. These are referenced by EssDN and not IDs
  • opening a message given its PR_MID (Message identifier)
  • opening a folder/container given its PR_FID (Folder identifier)

2.2. MAPI tables

Another category of MAPI objects are tables (also known as views) created with MAPI ROPs such as GetContentsTable, GetHierarchyTable, GetAttachmentTable or GetRulesTable. Views are temporary representation of the elements that a container holds at a specific moment. It can be represented as a list of n rows (elements) with n columns (property values):

  • GetContentsTables creates a view listing all messages available within a container
  • GetHierarchyTable creates a view listing all containers within a container
  • GetAttachmentTable creates a view listing all the attachment of a message
  • GetRulesTable creates a view listing all permissions associated to a container

Tables are customized through the SetColumns MAPI ROP which will define the property identifiers to be retrieved. The QueryRows MAPI ROP can then be called to sequentially retrieve rows and associated property values. A table is similar to a MAPI object except it is virtual, created on demand to represent a list of objects rather than a unique object.

2.3. MAPI properties and mapping

There is a large set of fixed and known MAPI properties available. If appropriate backends are developed, there can be a 1-1 mapping between MAPI properties and backend properties for some of them. This mapping may even be enough for common purposes. However there will still be a set of MAPI properties which won't fit in this process.

There are different way to workaround this issue. For example, Kolab is using a Cyrus/IMAP backend and associate/store MAPI properties to the message using ANNOTATE-MORE within a XML file format.

OpenChange provides similar mechanism with its OCPF file format.

2.4. Named properties vs known properties

OpenChange server needs to support named properties. An initial set of named properties can be defined at provisioning time, but this list must not be static. Users must be able to add, delete, change new entries and create their own set of custom named properties as required.


3. MAPIStore Architecture

Given that objects representation are similar to SQL database records, an architecture like the sqlite one makes sense for our purpose:

Component Brief description
INTERFACE convenient top-level functions (Public API) accessed through EMSMDB providers
PROCESSING set of atomic operations (open, read, write, close, mkdir, rmdir etc.)
BACKENDS The code which does things in the specified storage system (mysql, fsocpf, imap etc.)

3.1. INTERFACE layer

The interface layer doesn't have any knowledge about mapistore internals, how or where objects are stored. The interface uses MAPI data structure, supplies PR_FID and PR_MID values and assumes the interface layer will return a pack of data it can directly use without further or significant modifications. The interface layer functions should also have (as a parameter) a pointer to a mapistore context with private/opaque set of information (void *) about the object.

3.2. PROCESSING layer

The processing layer is responsible for:

  • mapping OpenChange objects identifiers (PR_FID, PR_MID) to unique backends object identifiers (on purpose, depending on the kind of backend).
  • format input/output data: glue between INTERFACE and BACKENDS
  • relay input requests to the correct backend through atomic operations
  • maintain mapistore's integrity

3.3. BACKENDS layer

The backends layer has a list of modules identified at mapistore initialization and available across user sessions, which means unique initialization at server start-up. Each module is a backend (fsocpf, sqlite, imap, etc.) and similarly to many other openchange components is loaded as a DSO object (dynamic shared object)

3.4. Relationship to OpenChange Dispatcher database

MAPIStore and the openchange "dispatcher" database (openchange.ldb) are completely unrelated. MAPIStore is a standalone API and developers can use it independently from OpenChange server.

However, the mapistore API has initially been designed to be used by OpenChange server, and OpenChange server is using a tiny indexing database which describes user mailboxes top level containers. In openchange.ldb the mapistore_uri attribute is attached to top level containers and its value points to a valid mapistore URI (namespace + path). Note that a single user can have several different types of mapistore databases in use (one for each of the top level containers).

The is the only relationship between the database and the store: The database points to store locations.

3.5. Object mapping

MAPIStore needs to maintain a hash database linking unique OpenChange identifiers to unique backend identifiers. This hash table can be stored within a TDB database.

MAPIStore is responsible for managing IDs mapping between OpenChange objects and backend specific objects. It maintains a list of free identifiers which it reallocates on demand whenever a backend needs (mapistore_register_id()) one or where it wants to release one (mapistore_unregister_id()).


4. MAPIStore API

MAPIStore relies on the talloc library for memory allocation.

4.1. Initialization

If there was a "hello mapistore" program, it would only require to make 2 calls:

  • mapistore_init:
    The initialization routine initializes the mapistore general context used along all mapistore calls, the mapping context databases (described below) and finally load all the backends available (DSO). When this operation is successful, developers are ready to make mapistore calls.
  • mapistore_release:
    The release operation uninitializes the mapistore general context, closes connections to database and frees the remaining allocated memory.

mapistore_sample1.c

#include <mapistore/mapistore.h>
int main(int ac, const char *av[])
{
TALLOC_CTX *mem_ctx;
struct mapistore_context *mstore_ctx;
int retval;
/* Step 1. Create the talloc memory context */
mem_ctx = talloc_named(NULL, 0, "mapistore_sample1");
/* Step 2. Initialize mapistore system */
mstore_ctx = mapistore_init(mem_ctx, NULL);
if (!mstore_ctx) {
exit (1);
}
/* Step 3. Uninitialize mapistore system */
retval = mapistore_release(mstore_ctx);
if (retval != MAPISTORE_SUCCESS) {
exit (1);
}
return 0;
}
$ export PKG_CONFIG_PATH=/usr/local/samba/lib/pkgconfig
$ gcc mapistore_sample1.c -o mapistore_sample1 `pkg-config --cflags --libs libmapistore`
$ ./mapistore_sample1
$


4.2. Backend contexts

MAPIStore registers and loads its backends upon initialization. It means they are only instantiated/initialized one time during the whole server lifetime and the same code is used for all users and all mapistore folders.

These backend contexts (or connection contexts) are identified by a context id, which is an unsigned 32 bit integer which references the context during its lifetime. If OpenChange is used in a very large environment with many top folders (which implies the same number of mapistore contexts), or if OpenChange server has an incredibly long uptime, it would be possible to run out of available context identifiers.

In order to prevent this situation from happening, mapistore implements context databases where it stores available/free/used context identifiers:

  • mapistore_id_mapping_used.tdb: TDB database with used IDs
  • mapistore_id_mapping_free.tdb: TDB database with available pool of IDs

MAPIStore provides a convenient set of functions to manage backend contexts:

  • mapistore_set_mapping_path: Defines the path where context databases are stored. Call to this function is optional and default path would be used instead. However if a call to this function has to be made, it must be done before any call to mapistore (even mapistore_init).
  • mapistore_add_context: Add a new connection context to mapistore
  • mapistore_del_context: Delete a connection context from mapistore

mapistore_sample2.c:

#include <mapistore/mapistore.h>
int main(int ac, const char *av[])
{
TALLOC_CTX *mem_ctx;
struct mapistore_context *mstore_ctx;
int retval;
uint32_t context_id = 0;
uint32_t context_id2 = 0;
/* Step 1. Create the talloc memory context */
mem_ctx = talloc_named(NULL, 0, "mapistore_sample1");
/* Step 2. Set the mapping path to /tmp */
retval = mapistore_set_mapping_path("/tmp");
if (retval != MAPISTORE_SUCCESS) {
exit (1);
}
/* Step 3. Initialize mapistore system */
mstore_ctx = mapistore_init(mem_ctx, NULL);
if (!mstore_ctx) {
exit (1);
}
/* Step 4. Add connection contexts */
retval = mapistore_add_context(mstore_ctx, "fsocpf:///tmp/Inbox", &context_id);
if (retval != MAPISTORE_SUCCESS) {
exit (1);
}
retval = mapistore_add_context(mstore_ctx, "fsocpf:///tmp/Sent Items", &context_id2);
if (retval != MAPISTORE_SUCCESS) {
exit (1);
}
/* Step 5. Release connection contexts */
retval = mapistore_del_context(mstore_ctx, context_id);
retval = mapistore_del_context(mstore_ctx, context_id2);
/* Step 6. Uninitialize mapistore system */
retval = mapistore_release(mstore_ctx);
if (retval != MAPISTORE_SUCCESS) {
exit (1);
}
return 0;
}
$ ./mapistore_sample2
sqlite3 backend initialized
fsocpf backend initialized
namespace is fsocpf:// and backend_uri is '/tmp/Inbox'
[fsocpf_create_context:49]
namespace is fsocpf:// and backend_uri is '/tmp/Sent Items'
[fsocpf_create_context:49]
$


5. FSOCPF Backend

5.1. Definition

FSOCPF stands for FileSystem and OpenChange Property Files. It is a backend designed to help developers testing OpenChange server code easily. The main idea is to have a backend we can manipulate, analyze and modify from the Linux console without having to develop a specific tool. This backend uses the UNIX filesystem for folder semantics and the OCPF file format as a way to store MAPI objects easily.

5.2. Namespace and Attributes

The namespace for this backend is:

fsocpf://

The mapistore_uri attribute for the folder definition in openchange.ldb must be a valid path where the last part of the URI is the FSOCPF container folder to create on the filesystem.

5.3. Overview

[+] Private user storage space
|
+-[+] Top-MAPIStore folder (Inbox)
|
+-[+] 0xf1000001 (mapistore folder1)
| |
| +-[+] .properties (OCPF)
| |
| +-[+] 0xe10000001.ocpf (message - OCPF)
| |
| +-[+] 0xe10000001 (attachment folder)
| |
| +-[+] 1.ocpf (PR_ATTACH_NUM)
| |
| +-[+] 1.data (attachment / stream data)
|
+-[+] 0xf2000001 (mapistore folder2)
|
+-[+] .properties (OCPF)

The figure above exposes the storage architecture of the FSOCPF backend using a real-world example. In this use case, we have decided to associate the FSOCPF backend to the Inbox folder. It means that any folder created under Inbox or any message stored within Inbox at any level of depth is stored and retrieved from the path defined in openchange.ldb.

In openchange.ldb, the mapistore_uri attribute of the Inbox record points to:

fsocpf://Private user storage space/Inbox

where Private user storage space can for example be

/usr/local/samba/private/mapistore/$username

Under Inbox, we have created 2 folders:

  • 0xf1000001 folder1
  • 0xf2000001 folder2

These folders are identified/named using their FID. Since they are classical filesystem folders, we can't associate attributes to them such as a folder comment, or the container class. All these attributes with the displayable name are stored into the .properties file within the folder.

Inside 0xf1000001 folder, we have 1 message named 0xe10000001.ocpf stored in the OCPF file format (property/value pair). Any properties associated to the message (subject, recipient, body) are stored within this file.

This message also has attachments. Attachments are stored within a directory at the same level named 0xe10000001 (message name without OCPF extension). Within this directory, we find the attachments named using the PR_ATTACH_NUM property value and the OCPF file extension. The content of the attachment is stored in $PR_ATTACH_NUM.data - in this case 1.data.


5.4. Documentation and References


Creative Commons License
Creative Commons Attribution icon Creative Commons Share Alike icon
This content is licensed under the Creative Commons
Attribution ShareAlike License v. 3.0:
http://creativecommons.org/licenses/by-sa/3.0/

openchange-2.0/apidocs/html/mapiproxy/mapistore.png000066400000000000000000001474711223057412600226310ustar00rootroot00000000000000‰PNG  IHDRÛæeŒˆ2tEXtSoftwareAdobe ImageReadyqÉe<ÎÛIDATxÚÔ—IH]g†{â¬qž£qгQ‘X¥*E¬-JM‹Q[º© ¡tSpe¢ÄE¤]”Šf‘:€g-q@qˆâˆužqž½}âIŽrSb¼!ÿâòßsþsþ÷{¿÷{¿ÿH¤Ré'ÛP8ýçݾWyÉ»ƒ–H$ç «©©‘$b• _r- ÏJJJ©©©— òZ‡äœl>}úÔÊÊÊÅÅåèèhjjêæÍ›+++·nÝâ‘ÖÖV ·Õõ˜þóx°ýîî.KJJ˜ƒczzúÅ‹]]]«««)))¥¥¥‚<êëë®XWmcc³··Ç¤¯¯/,,,>>~nnÐÏž=«ªªC$¡¡¡FFF±±±kkkååå^^^uuuòT‹,h;;;0÷÷÷ÃY^^1<~üXWW×ÉÉéÎ;0ýïñ®‚«ÇÏóçÏå)t%1§Âfùùù¨6 `yyydd”èÜ‚Zôôôz{{цëYƒ¸===EÄâ«äTˆéééšššæææÐ¼½½­¥¥åããÓÖÖh QYYygg'$$qkkk›˜˜lnn¢r–Q¯öööŽŽŽò©E%q†joܸ”“““[ZZÜÜÜЮ¯¯oGGGxx8  55µ‰‰ UUÕÛ·oïïïwwwB|ee¥ƒƒƒ 9Ƀ±µµåííSPP€€…< ÕÔÔTGG²›ššÐ:kˆ3!H ²Ò‚`ˆdii‰äjyÔÓððpOO²1pa©XZZ⇇‡€swwçWEE=X[[ Ù@*,#¼ADüÕ÷™?ÿ–'³Ù9U¯ËÝ;þJ¨Å“¥vt<à ˆ\AÁ{ǃ‹Ož¨3®˜™™‘zJMph~!µ¡¡ç1RyðàñöÚÚZ 1!!P… ÞGî’Ã_žb…"&¥Ì9äääÈœ·>|˜™™)q&hÁ騳ÑÑÑÀÀ@öã'4EÌvñ Bâ.€ØVB[H¶___çndd¤ºº:w…¦x}Þ§ fí²ýüü€ÎÞ° 8LƒëØ à ûã.6G!ÎÏϳŒ®¯¯Ï_‘­Ó2×ëÓT!¥†ãÒMhìÊ\p=~…0;Á9opAâdœ$Ü¿ÿÞ½{èçõK®µÅœœ=¨}d„BÈ5çOÒM—±µµ¥Î ˜ùìì,|(ÄßßâYC÷&*('ñÜwÝǽ“6NŠiÂÔJHJJ*++C(™rȦF‘,ò…oØ¥@aš•„Š ÒØÓÒÒ _>’·¿Uù…3Ú®Ì;=Þ‡G{{; ˆÄ"1/|ß9ß~°oD„K»Á.è“““hA#žÄÄDäV¢ø¹}¹H.“M$ Á¨ÖÕÕÕÙÙ)‹¼ÊícöÐ"ŠLÞå&ƒ @¿GòþÜúXÆPkÿ užQÀ‹8ˆP*A¨DÌÐ…ŠR R´þI­¶CÅ ¥­ˆí$.Z©HŒK¥¥T]M°DÅEA‡” Jˆƒ‰‚bqpS¬[ú3§\ÿ`J›ö^Óoxyï÷½÷~Ï{Þçœóœ£ÿ?Ðiÿ Ä™Ç^ ÄpÈ2Òä¹NfìW¥ïº‡t–\Î!Öé ôëEÁàààÌÌŒä-F9ORÜØØðQsïÞ=ÉåÌW¢¬|–ä+í tPh‰8h˜H{s©DMAxܽ{×GÛåp뇆†FFFRé¾§$˜ê€B¢1|lnn®¯¯Ÿžž6ÏÈÈ`f<&š+++«¨¨˜ššò¨±±Q…k)Ë‚§xLìS›sssæ,G!qéÌÒÒRz:///Z{KKKj„bŽ£HÍ•~2?;÷è¨ö€£ú«««‡‡‡ÑƒbÎÎÎÎÉɹsç¥As†àTA–——«|/ ƒ8Y¢¾   jA¥ˆJšxmmÍ2¬ ’¶*pöVÛâ7!zåÊßU¤¦/z,óE€¨>ÈyE«àŸŸ.r™´”¡Üñè'ÒÓ¡_XX¨©©Iâc“”ì×ÒÒ‚šŠŽ¦¦&RÓÑ ”1»ªMø¥rŸVŽÐa?ê{›´=¤? =ÉoŠ¿ÀË ØÙÙ„(…`BÄ öÕ|̯ÜòÈJqPýÇ_£µwÜYüzÈXÛücr3Ht8¹¾ýýýè2F‡À莉½™Ë)ÖXiÞÕÕ•ø©ú¯~®kùéƒ/0ÿÓ“ñÿ½Úoc’÷Ή›o\þèõ7?üÇ2<–ŠÝ5),,Tœ²7ËñÅùùù••êÂ~P¶¡¡arrÒ¼¯¯b8Cß_ùÆXóù÷ñ±ôãïb²·¹ßz·µé“òËoö¯l¼»»,sÖ¿=¿¢g¡ •å9FUQc9‹Z¼½½mí±tww÷³”\i Ü9\q &¶¸¸øèÑ#VtŸu~‰Ñ#­«;jKÔ›››ëëë‘M¢ß¼y3Ñ&䬑‰²²²bÁƒâQgg§1bN´ê ¸²²Rõþ bd3‹‹‹QYfxyy¹ªª CtkPekkË \ºtɬaàè…F 4ŠÍ^ßßßï0‡)pµ¶¶BVWW¹rìÓâ¦m€nìäœ ˆ)µ§OŸzqüÙO”ÅÐ!¦4ŠŠŠ ±ŸÛ·o—””<~üøúõëÞ‡-Rt{{ûèèhooo"%/Ì¥½vâ_`ÎúÁÁ³EK˜Gx!»Ú˜Ø|xxh½-á±yB%'ÚIÇ"@ôMX• ÷Üø n¢¯ä2;;Ë/%ÉûEë3lN:by˜yž>n Ú„#R§bˆ ßÑшÿŒAIãñ9½C±¢­­-Ò/æ¹°hMaÄüŽ*ÊÌÌäpTÿ_´‘RÚ¯ØÛÛcH±l``€½™_ùœûT^¸àÉšôêò9§ÿðáC´Z1‚ÙØŒ{ùHtQ×÷p‰§s.lã¿iË”µÁÿ€œ{ ±ªŠÃ>]JI´s0/Œ ÞPG$ó’ÌØ¦Ù£ ‰ø ^ÈÑ"! „,1_$ ²œõÁql¼ ÞÇñY’C^R3à )^zÉé×üi·›S39æœöÃaµ×Þgö·¾õý¿ÿZkÏ_ÿÅS ‘¡±¹tÝØÒ‹Z÷{ìÝ·áDë#ÈDÀ¹ûG[;¬-8ëíVK—.ÍÏÏ{äR¹¹¹"xZÀ3‹Ëý™òx@gêÿa7Äœ,KÄ€ØWÎI~û—.]J/Ä?t瑞äýq9a™'_¾|yß¾}¥,2×I“&ååå9ņĿ9:ò@Þiûöí“'O–a±¨%%%hè}ûöñ…;wŽ{ºj÷îÝì Ö§½`6 H&”™béà"#åß<í¡C‡©•²”qãÆÈ}.\èSV(ûÄåùóçy¬Ô mÛ¶-·‘o1ñµ_±bE=dA\â”)S…IKvkGùÑ JRXXÐAƒ­]»Á[¢Â݃iÓ¦Mê%j:uê$“Uf©uÝ\I[€USSýÞ½{_»v­]»v••• ë&L˜Ð¾}û‚‚‰ã™3g’‰ôlèGÓ ¼¼\v'e&±EÊÇŽ &ª¤ RAT5äuIì)–×IÕ·iÓ¦¬¬LâK[”cèÊ•+ݺuƒ¾ºxñ¢þ6lp)‰BN6:¹;vd:t ª ƾ½{÷jÓ±cÇ.]ºè†ØÇж8‹à1 »ìœå1  |?~Ä1'¹dÔ#¯º3‰›HÖÓ¢‘ͺ¼lٲؑ ˆˆo±ó3§~µ/4רÇGˆ++Ðn—_"‹ætÍÕëƒÃ‡wŸZW¯^2dHhôåË—]¥½q Wb#ÞèÑ£“™Üìðv,Z´¨oݺ5VÉ<eðœð‚ˆÏÓ§O3j¤¤ {¼þ@[e…éÓ§ïÚµ‹4 w'Nœ ÍÁþýû)rQQQ,d‘ÔÐúmÛ¶i0~üøþýû+è6DÞ¸qcìkEüÿd[ÕýðË×àð¾ÒSc™tD}ø„˜ê‚T,•if¤ÃÝç† ÆŽ{áÂ,Ö+Ú‹„zE3·‚>ýÁÖ®]»Æžh…X’áF¨CÙu vçÜùæ[S#_Ÿ~ ƒªÂ+=Í¡{âƒ,èœ^H À¥¿ÔàK&øÚ€R7¤ÂÒR¹`Á"Óàç~_ð¬«ÛòiqÑkÖݮ۶æÍÂIïÿ¾7å×Û›?{óÉ'Ú ÿîíú_=TñþÀÂ7¾ªüðù—ܸqKMMõǽOWx}Æ+Ÿ|¶åúõ[¬\žÛõ™§Ÿ›¨üó›žzvÜ Cûì­úæÆÅŠÏýbªMô—AŒ9m ùØl«%B¢6|BĮ؃z¹K–,:>ž?^¡Œ¶„¼rÖÓ¦M;wáCŒ†©S§’ªM©¨¹J—46•â·—nýü¤fçoïZÿNéæƒñµºüŽw+|ùÁ·û?R¸q³Öç÷GWÏ|õæÍÚkÖþôÝC^œÍ@…òKî9ÄšÿtR fÂTŒe@ƒ›> Úž={¤Èë¬S¸Bmm-|9<§T²zè=za)ÌÉ“'ûõë‡×Ççä—è>š_ܹs']ÖÒïêDÎðºG†ãù—ß©{ ‡ï&2ÔŠkðš;wîÌ™31ŽŒË}úô G^ãm`©w‰¾qjñâÅ—äjƒŽÀ)CP7ˆ¥¥¥¾ºOø¿Øñ¼fÍ?øìy¬„§E)Ñ4QQ·e`LUÙ{Íf[²Èû·•ÿV1øªª*äÂ2A̘1Â]uu5–7P“Ÿ={ÁW¯^í+°@†ª„›Ç˜5kÜ×­[§½€æB‚#‘AäQ£FÅKyzbåÊ•h.m)))Y¿~½åÝN9þ0Æ#ýׯ+@Ñ&œR¼í“^®O—¹Ã‰'¦g¦£瓎´nv(¹\ËXJoð¢QÓ¢_RXµjåWóóó±ØÃG¶Æl9Bì …n‘æÉ 4(‡ý@yZ,3Ôž0F;!)§ ú‰@Çãµ ÷ô£èIŠö±¢7HM3ÌmA¹E!N~æ1<†ˆÏð²Æ»tF+2âù#ú4XŒ¹Fn:•mt•b£kñU¡Ü«W/*¬Ûâ…nD«Þ:uê‹ S-é‰Úèôoõ³Eñ FwøYÍ]ÅÀDåðÈ\¼tCEEµÂSÄ §ì*#±–•zGv.Äîxý¾ÄÝh€©þsŸ²²2 '­Ð…º!²Äœ?vù´öùÏ¿ÈJ<9ÏÓ•È‹‰@äÀ0èFòòòrê7zÁˆ1yó:I$”±Rʧ'hjÏž=;^&4ˆÅÕˆuލ12Ø9sæÐ“d½5:/Y¯jX7º†í™ j2 üý‘#G ybAzâ,q²bgèСCeÁÄîÝ»ÿZ°ÌDv˜Ëe£0Å'5î {ôÖŒ3è83£?€î¶Ú¤Ã] ·R:7augåðâ½ mHÅfb#±†#¤ mb¹$ý”«32š={öÌÍ͘“Ú›5³ÍD¹±¬<YkÌ¡?¦?VPí¢¢"‚‹X™'3³u ûïÊŒâ1>áo¡lÒ> lVŒd“Ê¿yþ»ß}mê|KVyŒ{>Õ tÒ2…³øÍÀ¢±šæñÿ¹.;dú7Ø;󘪲;Ž¿XMF­£èD‚»7Šâ^,¶NŒRPÜ ¦âbÿÁV«IkµmâXu&1h4"‹Šƒ¸@DqAÅ]7ܪ¶—ԥ߷srç¾Pnçþñrß}çÞûî÷|Ï÷ü~çþÎïTŽËNíÞ—˃¾š¢=+¦¨3î+¡Õ÷xž£€ÖAdgÀZÓ½_FK·v˜.Õ©ûÞZ¬¨¨(99¹¤¤Ä3Hÿ­ Úâ?ä²÷íèÑ£8ß:tÀ“ÆáoÖ¬Ù¬9gwªuª„Å*©÷&bV®ÓÊÒÙ¼w˜:WÍÜ6áräÈ‘/^77ךÈhåÊ•™™™ÖÞÒ:øéX{ÙPlöìÙà˜””tíÚ5ƒÂõë×=zôìÙ3ŽÜ¼yS RŒ .(¨ùòåË+--½sçŽÎRÌÆÃ‡©†Ç›Dp\oI222ø¬a˽ƶºüaá LLLœ:uj“&M®\¹ÛнÑÅALG"4g8''çðáÃ!!!°ÕÇÇdõúnÇŽS¦L¡˜æ›:t õŽUQ‡€Nu*c¨Ëý®Ïa½_E(óØÈú@·¦¼îjø|ê]*Xè¥_÷îÝÙ¿}û6ЦM0ñÈÈH—;üãõë×W8>CvyJ˃‚‚¬\6“¥œaä•‹2M888¸qãÆSôøÐ\ö}}}ÓÒÒ–.]š’’‚ò.\¸ÐÌÐß½{7þˆ¿¿?œ2¥æÂdFIBCC‘š²²2̤Y3y$ÜB­„êAåµïÝ«W/`å8§S RrŒ˜˜5s"æ9µkÆ ÿ¹È+¸ü¡û~pBÉ<ÐŒu ¾blARé5¸tëÖ çE¢A÷Õ¢E l^0R¢9p?::²ÓÅij&LÇ£á+ÒÏEØ}Žgggs: ¥< ýl…v~ý›/â“sÞ‚²ÇÜUÿ^S>C±„rI̬š…`=øò»MsW õ8"ßÂÔhš*ü·{ãÆXÇÊ2À)hˆ‡……yþ×?þeÛéó7‡t2àgçJ' 4aɛї¯$Í ‰œ÷êÍ _Ôsþ¬q=ý¡ sYà€8ÍfÕŸa§øÔ×­¢6üèñ£ݾ´µyû‘zçp`÷Š_‰{ýêu£F n\Jªv.ëiñ0^©•ØÌ`E°É4‘Ä3j 逪 Ò€'=žŒ6Ôƒãà(šò`}ìØ1îB1êR“‚*øÇ{™}ßO[:’¶èØ7KÒöž°üÓïÇœ?¶æRÞ:öøo«’·nøüüñõ¦Àý’í¿¾óW¡¿ûÎý¶ÚÉ!gÍ p4ÿ9sæhNŽÕuDLÀnÑ¢Eè,šŽËg5ß8>>žS†ˆfìŸKíÚµ {#88˜åçç«c¬@ŽÓ7Lÿú‹XíÇ' û´[ÖÖ9<Þ™C_µôkÖåç¿5G>†ª7ï{-üèÖ7ËÒÿq§êg{a øÂ8•Æ‹í X"R2_¼x«°ØÁ’ UIG‚qçÔg"2€‚ZstÚ´i Çã:”ÁXt¹'°ìÛ·šp¹×E¤¼fš)ð^7ßO>¾sïM|ÿ¤ÑPŒ [³ÍOý#>GŽgüÕ‘b4úé×/j#Ř>{•í²o¦5i1ôµûzÕm›1Ì3# ‹C‘šš:räHÍæEgddë–-[ÒÓÓ¥È9992- jii)$MHHÐÊMôiXÊû÷ïç+W8p FÝñÌ™3†c{h¤Ÿ›îÙ³‡K­Y³è=§2¿u]‹_Œ˜ûúCݼ(†RÑeÁÖ€€°z0Å’ÅÌÀ Ó‹;º5l ™qüħ@jñ……ÅXZ ô)bPÊËŸÙîÝ»´æ]áLr#3ˆa{ã÷V«î«ÅŸÕ&{Bir/òºxñb°Ö`Ï"`4aÂl4Aã>@@€H{Çîҥˊ+@™N NëÔáÔ¥¤¤¬_¿M—àPë:S866–šƒõJF`EÖJa[ZÛÖ3°½íˆæXWÕŒõªAÙúöèúiæxZX@†GŸ>}°j7nܘ——‡ ÔZïhSÔ|Ù²eãÇ5j”øŽ¡ šêÞ¿ÿÜÜ\???¾jš*§sM€ž;wnÇŽ=˜° ó?»7öMz>'Ož¬±osÄä03ÖMOÝ_i Ö™òÖs=õtŠmMÛÔûJŒ/ËŒKNN²sçÎaäru°v ¡Ò3h”«HLLä®ÈOy•³fÍ‚Ñh:ŽµÊœ®á=d_éèzt<++ \ЬìiÔ+&‡ ±2/ =#š¸7³§1‡–/_>cÆ D_ “»¾Ý¡¥J§OŸnk^×dÒ-(Oò˜tãóçϯ¸a•ËeóšÚˆÁ+º=!D:Ξ= …éùnΛ7Os‰5x¯¥þ8…@Mè• Wã:TFñÎ;áø’%Kð!±ÛšjÀLîÚµ+õ¤µ ¹‚Þ˜Ø"»àŸÜ—>±ÒÛYó: M|±^±Û4]Å+**ÊÊb}š¹´Ö–ÄV‹a“þT bû)íðð¨*äS›éׯ_š‡D|/€'µ ;˜7È‚8”YÔƒ‡¤’h 4ÊCðúîÍå^•]¦bd“DDDp¨ô›@$[ xÑ"æßše´,„­iZW†ÐánTŪ“žK·Y÷7¸7×;Eáx-‚"5ÌE1µÌª•¯ˆìÖ»g„(å¹i*6X‡„„ÐZù†ê­+¸CU.Ò®];U÷H :)‚ÉÇÇÇÛ–@5}`yORY~UvƒÎUccèa´ ‚ÃHèÝ»7ÇáF9Øä§Ðô”yO6‰NTÐö5ÚÂg`` Fà”÷…Ÿð÷`±Ìm8Ny¨I>qâDЧW4o²5¼`³èkýø²iž¨à*@KÁZÈ(Pjº^-c]€©†ž•/t€Œ-Š ±Þˆ¹§Ð&8—)¦uD4ù]«&s Då`u}ʉê^†¹Fñåb!¾W®\Û×××\i|2‡<%ᬼ¥“}IVüU À–@vh\І¢P.•À‘QÕ©A®` »Ú_[׳K…›à«¼¾ÊSö­{3ÃùX @ŒwÇAE#Ê:¦ë¬V­ZÁSî jãžéµ)~@Ÿ8qB=›òíP¥–3¢• ©žM›6±“‘‘¡X„ˆÞÊ£æh‘^¬(% ­„ª7nÜèÑ£)ã²ÌfµN{¯±^Ä52åý  Qa@As…2˜"ˆ€z*ÅÈÂ}¼j-IH%)k5”ç'dtdY%U¦SܼÆÎãÊ“&M 3[]ÞZ=ùÝ»ØÁAá+Ó˜F€ÀkÄD#5Ðs þ)d€–Ny*İ`~hµE ëE”"øA™ú eè˜1c; ¼|Zÿ_ò™_Á7>>‰Auwšàë‘W<¤<;;›ægUi }ûöMHHÀ©¡/EvñkøTL éÓ§+‹¤çzj•Y®õ([á.++ƒ¼%%%ÐP†ÔÓ*¸ÈH¶œI û@©|r4„­@jP|§2dZ«Óä˜tXŠˆJçÇ Ékàí#÷Êt•Zó”ƒ4»kLˆÑe ŽERLX µòµtþ<ìÊ’HkĦ¥¥)·»@D^¤*ÐÅ1b†‡×5±äYs¹< õšíÂ… J®Šà‚8."–2ÒaÃѺ^’ˆìŒ9ªÕˆ²;ÅÄX×ݬ ð§pm—éšv[ß/Ċש1pß¡gSg뀼$ôŒcì¹:5ÆâwS ‡çàz‡íÝfžzMa ~øÑƨ–nÊa¾ß`ï\€«*Ò<žu­E ðäýÍ€#_¨Qd¤V]uœq©±ÖU)‘­AÝ)—Ç*‹Š@Áð&QD@TDDñQ[[º?îoì½ÞÜ„ à$ážJÝ:÷œ>}ú¦ÿýïwý}wZýÆUÿTi?¤Êl”«ÇY'Z©å_°¯ÈK¥Y¶Äxà >ãþŠè€5 $U>V®t\wÅ¥$:Ë Þã—H8ò=£~Ç­þ@‡a&úd:ô’Þ.ˆrÜ.%×” ò¾þúë±cÇÖ¨Q#99ÙèæŸþùÁƒ³²²7n¬ùÂÉ1ˆ«+ª¤·Ü”Ë¥›OÓò"uÆ +V¬¨W¯^­Zµ.ºè"—¿ýöÛ={öÔ¬Y³K—._|qô^ª“ÑÊUÀ!qüt÷V§ÏÝØ*..»nsÓdÔ}+GÝ·o_ýúõX‰\ZácÄFÓá<øÅL ¾ê@¹üÕ ¡ØE‹éš«I“&ˆ-:5Ê(ù)8`øêÕ«JûË/¿äqàËÉW_}¥·´˜2<ýôÓû÷ï×'·:”™™Ùµk×jÕª}öÙåAvÉ[q]']eµr‘¼&Mš¤á8RÕûÍ7ßh%×4rp1¨^ 9rD»DýâjoàÔŸÈèuëÖ×öíÛóxð£A›7n\JJŠÑ;²dëÖ­dÕ©S§æÍ›‹è÷ò„F¨ÚæÄƒ&0]‰YyÉ’%nbg@dôèÑ2_´S«ä¹ÓÄ è„‚‚‚½{÷je«•WÀÍáÇõöûE‡'ÐÊ–ö ßÊvíÚé›”Zö;"¬4 °qãF  ¥otñxdúôé}ôQÆ Ñß´ŸmÛ¶Ýu×]𳆇¶Z’›óq•Ê%77·[·nÖ¤H(ÐiÓ¦1X¢&ôÖôÛo¿Ý¦M÷Jé¤H'«4øR 6‘@Û¤wg¦ q±ÉrW7R>;kÖ,Þ>lØ0Yt:xŽö©á‹o¯ëׯW©ëuʘO>ùDo_äLoàþfº dztÄóè–ƒÝWV(SsÙÙÙ€ þš¡7m%X 7¤RÈV†§I †j×®M'bHIp¹2Ñï#ª®Ð6[¯ôÏãcT¯” {ž Ny¯Þ.MŠBM{¹ŽÆ ú #U¨R(Û=÷ÜCó#.Âßä y£@3¥%q\Ò  äJ ejQŸ `q.½  ¼¼<øX Öóî¿“½dctxB—ÝËÿt˪güú‹9|æ¿õgX™“]ïN÷ú_~Ý>}TJý‹ömý¯¤HÌÍV]éw휬ZS8Î8¿ÖJ„?ÿp¡_Ûu~AÝ_žŽ’§ö8«ÿüó\à舣]œÄxByë­· X·lÙbÜ's†šÑîQ¸Ø¥KqðàÁ=ö1ÂÐ1Æ,–kîƼyó8™1cݯ»÷Þ{ŽÀXÓ…½qÛ¡FªhbKzz:×áu» ¤×Hd1Ÿå9úõn{ëµé †~å/wÇÜͼeü7?>hÄ„ÉÓ—î|ÿã2òéÒ¡YÜëÿ=õŸA-ãŸÚöº«Mú“ÿãõ¸É¦Î8†Â5Ëžö+=SÉ4·Ü˜s¥fƒÖ¿êÂzWíÝ÷IU‘aqkÇŽÀÉñÜsÏ3LŸ>½¨¨hõêÕTór£¶C÷ÍæëK¯¼ÅgÃFiǘûoå“#G޶ëöëJe+ `!4A02|ƒÆ6lèÛ·/˜CY †6rupíÚµHjM5&NœJÈ„G† ”A˜ +ÂÂôEqq±³ÔÀ:)²?…<Ñx’"!íñÐ}4ˆ÷ªÎµöÐrr2C=XÛ¶m—,Yb›ÌÏÏ'çàt>ñÄ´F²š5k š6mZ§N­[·¢UÀ:mí6ª”ßÜâÖkz4k‹•fM’u}¯^]Åæ>¤7¿{tÖ}ÌlÞ¤îKÿ~Ï´—VôîÞ*:ý”Ùoæì˜™ºþñáâ?ÿÿqdáʧÇ?5wÛŽcárî5øº=ÿ*Nò¦¾<Õ-#ÇŸþ¹=pkÃu>Ø2kßþƒ7 ôÈ_õLk{`ÇœÉ~›ÃÓ‡÷gó9û¥¥¯­Ü;£ã)µþ·YísÎíȈ*lÕt€±ÿ‹/¾8vì1açf$À… ¡dÒ\xá…7NMM… I‘€ØÎ¹ Zʃ`´víÚŽ#i<7Üpúuë¶oßÎW¡ æ$E8^KÑ>}ú¸‚ÍSÒllˆ ”ÉÂ… 59xð Í€Vgоò^å2ÃÁ¼¼¼«¯¾š¶ád/¢‰’3­qþüù¼®_¿~ü„²ÃqŸª9f†}ß÷}Ðʉã”Ay×®]®©2,XãöìÙ³nݺÀ˜à šd€}ŒZp6Íhh\ðÁgΜ µ»Háú‹9tè¶M2¸Kø•[ôû éD9di8Š!tH†ŠÙhw#G/_¾œæ¸¹%ÅÒ<ÁÈ­Lž3í0;;›Ekq‹T‡ÓÜñÛ¶m+,,,”cVOsÏkØg·n½ª2Q–À $­Y³-‹¢…’—.]Ê­`Œ*ëà’¾‚x…›¡7Æa¤Glh¡aGÜf¶nÝš ýÀ!Ch ;v|üñÇ'Mšý#Ž)†3Ð (ØÕVŽ ]=ÉÈÈ å³Ï>K©¼‚r:Eˆ.2ø1ùð[HÌ•îÝ»“˜‚@BZÐÚz8Ð{‹—e7z´Ê ‚ЯX±ââ‹/6¨î)Ç´¹CÄô²ýx”—Õ")^þô•€•Ãu8löìÙÚøJº†ß‚·4r9šs¨Îî;lýwìOb¯hÜtœ,C7ë^\cË`Lgô°n…ÔñãÇ#Hè(Lƒ Âä´V†ÍäИNS$Ò»¸hÑ"ÄÃ3Ï<ù‹;ä õ’Øè¢.¸¸iXŸ’ׯ_¡²lÙ2’QrXÙp¥q¡œôÃÆX+¸V­Z¨v𢡠ƒ‘`Œ³>IpÛm·Êûî»ü÷>+®sú¸wÉÊàôdÈ'­H捻 »h¥—îò"_MbÎ'D»--YÔy‘ÃpÔ1E"nÁ8ü>~øa¿‹zä+oáüºë®ƒ/Êß`NvؽE¸꧎8PPP '˜/%%…þjtm™!„ ܪ̓Vð*þ‰†Á9\¨PþßÈáò8ÐQv§§§»|Ý¿™Þè꯼òÊäÉ“m$ 0ŽäÀ¥ 4¢Ê™é¢¹¹B9a}@Rò={öðlíÈáhUiDÏ€v‚øI‰:ßgýp$E9 ˆNQ‹c¨Úr^¼l ¬W€Ô>ǥÒ{X’"á¢ÌqòÚk¯ýhr­fÍpN: fʤG_/íýÀ4î-[EÒ1ÞAv@ð5 (÷ätà8>+G¦—•µ1Óç"gÝgJ•§¥¥ÙËÃsn;5;h~U~~¾Aݹ‚,Ò6oÞLÿîzŸíÛ·@]ÔSü¡zvØ¢ò·‹)dHJFfÚåíÝ»˜R0Û}+Œ[›ì1x` 4'JK_zãÆ‰2ÐJ)¶ÓÉH·ˆósrrr¼Î{ae44“¢ìîKÆLú±ñç‰öÂð™²Äð|•T¶ò¯Çm“§•KzÕ¦"!`WÔ4ds75¸O|…‚Æ ¾«EøÛvâbyÊ ·´¦RŽÉÜ øÈñ™9h_Akö:öÉ" †ÊÆåEð¨ž?Gªp= ¾ÝK»víÜ@h´`¨„Lrs€ûa©ž¢¥E»· ë2ÑþŠâÆ"<Ñ9  #ð*ãA•ýÌ8.k^9šTÜ~l,†5ˆã"@0ôÖ²eK­¸ —ƒ5€›I­þ®]»j½ ªŠ‹‹[µjŒ”¹ ÔФ¬¯½?ƒ6‡’ùdffæ¦M›Üb4hÐ §–µm+`K[M¾Ý£ªƒ6²Ä0z莃!M0‚&[´hA2v äž»œó.Ô#-ÜœÂ2¡0Û·o?¶vuø0H5¨<,K9¬»À½yóæ:À¥0j rcð å“!?“+y½zõ‚½GëbŒ¯ù8Ü%V! –ô¨¢=ÀxŒ"Ž:Ï!C†(mîܹT!ˆ×e‘vñÁ<<éòŒ¾yÄ­²j÷nA»Ã?-¬Ã'bAT ([γº-a …$àHOOg„·fÍ'¸ ¶vïÞ]PP@u^zé¥Ô=à Ç¯[·.X¡= ‰5Ñ$g×íœ;³ú]ÄÛUÔ0´>y\7Y^èÉ~”pó"FrjeîÂß$Ðä__´zL„_;vìHS$½„íæ¨¤ˆ= Ÿ°>$î'Äe£üd7p‰r9îd…U xýœÇ߇!s€Ö°~rðÇØŽ*‡srrøÊ žC?¸TÁuðá0îÒ5C™€‰ÜB-ò3š;#00änmûeØÔ Nbšë6pé:Ⱦ}û€5’|ÓEð%ìëIšù$ è uç€5…¡Í™3‡âQ6ÆhtÈâ+W®¤½‘-8æ·ô=z¼ûî»drÉ%— Eô†íì9fˆ¦/âZl'Ž¿Íj_ô-QýÔ7Õï„\:ùÔ—kÓ¦MÁ5­‘;È“‰]¡ï:t(üÛåÙ³gÛ­#îJ>õ¨¦¡Oð|®\±gpÁ¤MÚ“!ƒ¨T—.€•¦EHO1hc´† ÂÇtÜ¥`º»¥468žg;…¤¡.øÔLHK#A‡Ð|ªgJ®óE³rXÇŽ™¹KÊîÜ k׮ݲe ˜NIIq¿«\î·4è ꞯëÖ­Ööò©©©ÙÙÙT-H½âŠ+A‚Tý hêIåÓBÀèÒ¥KÍŠ“Ÿð·^éu èÜEXܵk×Ì™3=m™¡óŒŒ ZâÞ™”ú¼yó@-Dš‹‹‹×¯_Ý:åj5HĪ^Ô AFçÎJíqç£ÏÃN™Ž+"”­-·ûÓ)Ã[NÜ‚f¤¡0ÐtH‚/»ì² 5wË9­Z‹<åô­Xtë¨ÎÃ5up€Ü38dËCàþFL".”Ëç;.¥U)XBDÆ2’ããë:N:¦µ—O)x4l.Ö¬V’[\|Tl>®¸ötBM1‰¤€øËMd#SIŒ'í+§öŠ~ÞV¬Q¯,Ƈ¬'Ž>>nÖ€tý"r|•Ç•dN'ìb½@ã£"ñq91Ž8p ''gïÞ½ßùÎw222êׯozà#cÇ …‹•Å1ïÆºâ˜¯½öZAAA•*UÜäüÏþÓíþ×_=ŸÆy9*B šcÇöŠ£©:vïÞ]§NÓN;­råÊF¢¨Q£F~~þš5kjÖ¬)¾Ø#ŠÝÒ}êãu»ÇÇî¬å+$òH$÷ù-\¸ÐdîÑpƒ‡7•¡Ù)aYb(Ÿ°ó¼c·šR„¸•°žtÒIÆàq7nܱc‡ÑȾÌ*›ãu»ß^qt_pØê>~SùšÇÉíÓÿøÇ?øSL—Î襻½§„-vΗb0‰m' ŽÑ*€©,MÔg¤‹3Î8-+ŸrÊ)áÓ{ÔçŸÎŒÐô¬ne=ä¯(ÝŸ8Å=:„ªÑsâÌóÊâÏ>ûlôèÑ«V­âÝÄÎ;wéÒEÁP¬™–ë“&M:묳Î>ûì“O>ùÔSOM$“‚Ë3Ï<³nݺf’4ü\ôö]»v½øâ‹•*Uëßþö·ÓuÇwsèÈìѤt‰´ìX7—“ã˜ÛÝ߀jÕªU¥J•Ê•+A`½nݺÛn»Í ÞéË¿€¾aƆ$ä[£ …80´¹›Œú͹ôæ›o8p jÕªð75ƒcÇCéÕªU£ Ëñáâ¯+{ åD—>ÈšZÁèäË+VìܹZMü{Px>ùVÈw³¨äåbõêÕ öîÝkËð,oFò}nnn^^2à /ÑÆGö=q& ŒŠ¤+ÊDµØT!Y¶³/lùòå†p5ƒÎ—½*ÂÞx+!<¦'ÑÛœäççgdd|ï{ß ±…ø4ßž‘dMj oÛ¶:Lwm9=aÔ¨QK÷îÝ3Ñì ÅÊ'ÏÆðØ0Wapœþ’þþ÷¿?òÈ#°©¸¹òÊ+[´h!þ¢¸7½ ù€¯ùRÍ#›þùÏæ$¨*àÕ!ÛtfF)ŽÂe÷îÝÔð·¿ý-H Ã’Vi˜‹æ¡U!€búXñðÃׯ_ß4·ãÇîmÛ¶5‹O)ÐŒ·LWÔy^Ê›1b¯ö7 dåÊ•0+ìˆä5œ}Ð 'N4C 1Á‚É ‡•bL°þõë×oß¾½f͚܈´…°š¶öíÛ"M!ÌI4+çôãÝKçÊ#ŽSÞ™ÂQåô¢"&65*ƒµ€[¹råüùó5€‰.]º0ßRoÀ”È Ó.Eëw#µ¡.(Æ'…hµ=‹H˜¸aÆLÈL=M1€ ÷S'€ ]tÑ‚ ¨œG0¥/mžÅísæÌ¡©ˆ *¡åªanžÈpÁ cBºxˆf†ŒTapœÎ4p!<ÂÁaAsxiÙÕ Áɸà›±Û?å`6akæ…@\-Á§sÊà²U•(Êà«E $¹kšz«FðÊ•ƒ)©"Å1Ÿ`B¥þ`H k´yêÔ©(cõH½á‡óP·yófôíä‡é/çÇaìÏC*À²pžÃ7ïbv ×ý’wÞ@:3ÊkU.ò%€ÜP/7‚®¬[·µº…´­]»V-î°®.ý‹®¢æXôgŠf™Ö©#<šwÇaŸDž²uëV€¨]Å-Óz?õÁY[´gƒxêëÚFÈwêIQÅÚ(b—kË4|ð/;x·9^K±ÌÒÜïäŒ2šätmãv¨ˆS Ù V¬X¶[B\”ðrƦza©k/Ó€ ››3HwàJK"¹ÛŠÊÝÍjîun¤Ûp×9眃†Ö©.gРUNUõèß²e …bÉ1‡” ¬,Í—²6À^Á4Ÿ7Ú Aÿä­«8õÅp`%++ @Åï~Ù²e®ƒ'—4Yˆoðѵk×`‹õÈ‚ÅൠøÀ=W\«S t#æ‰àA ´çÓO?UËV«VÍMP(iªè!Ùçð+J¦aÆLøh=Ç*<…jÇŽË9¿´F”ç×ñ uúmJŒ: ǼÎ÷ߟOÔ8X¹r%¸tL‡¥\œã1Ú³gO—”U¨‹2r'àîÜzdÊãÖ=é™2h÷ÚµkŒŒ «â¡t8Ù°jÕ*À]½zuÐÆs´ÐÛ 3à0Ÿà;ˆlÆ&…|åS9·SÀ¦Îu«§«ÐNÃ_P Å~“q…ÁñúõëÝ íÖ7Þ½Ò"d~–H®–ñîµvEwù&ñê$Œoýár æNæà8&°@pRàFò¶*¦Ò?}Cyà …!Ñœœ©—\Òs=v§ˆ\ÕѾ}{Ú\¥Jî¥B5:¿¤ºáz ÝïÔÉB GhnÔ9)To•>ÃãÓQ[ÀqEܬý‹×ÌpÜ8]iûÀƒ$]ê‘°8ÝÉRüÉ]Èk0=hÐ Æ Ô´màѺ+u%/L=õÆØ­v7]C‘âïø¯_— Rn“YeáŸÀ†ƒ>—.] ª€ ãFÈ2¬\p£ý˜+.ŽÀ£”ܲe‹ñŒÁ™F·XÃÁnÓׄB"7¦ã5mÚÖ§3 l³ýÄ]}v õ1‰{ |Èsù95¢ch§Ó³¾œ¼­Ï>ÿûºMÛ3ëÕøÏS¿c÷0p¬N@›âeS+3=‚Õ“ˆ÷”ŒÝ†öd|"ô¨=L¼Ü˜$ßkp–†¥<…¦1Îuµ$W€}íA02]g#CR wùÔM4‘ÜýX©Ÿ§Ó%¨ýÀ9'`ßæ\¤«Pžö0pŽØàϲ›|îƒUë¶SzÂÐûÂÅëûý~÷Þý\œòÖGü¶Þ=ûµa“n¿¾Ç7]TR™…K×]{Ûso¿ñ¿ÚµÎŠqüåኆû‹\:Võò'˜à+”¥c±û/Ç¥déÙ5d 3Ž£DuV0úhЦYCc$„Æ*IpãªFk`bøžÐ78oß¾=臀Á>ˆÛý\ós!ZFZ´lÙòÖ0'Ikg”@;q-Üt¿Cns*éxýOn¿æ|Ï÷ì;ðÕßÖç5áu=¯ILÀ‡‡cÝ2„Lw.¿ür£û¸ ëÆ.¸ãC…K/½Ôu kD'¨U›ép\*¦a;~uN"<ÈÕ]õÝ€ÍE”ŒÞ?ºeee™¿ŒþÖ¹sg°ënˇçêš­'-§Wôïß?»¨ìǘ)9âøgÞOùj×Þýýž|g×Þ¿8ÖýÏ‹[ßsóüªÿ3#f-XûÊÓ7ßùÐà/’‡i# BâõᓎwìúôÂ+û")Ü3ë×þj¿Jÿyòu·ÿН®¹í9kÎ_1Œ?·mßÛáŸYòª^]^zî®/kò§GŸúÃÞüŸ4â¹A#:¶Ë7ò—\ÿé}/¾óÞT7ëÌ™úßç6©W±qì”Ë}ó%íóñظq#˜vÛRéï;lܵk@1jw`•(.G€Z4šwO¯›î˜¦ÉEGÇx7¬ÏEWp\ð£¯Úô%JÙwX–cÀ=—ýâåqo™]¯«ò¶U=³ÒA]Qtp¾{ß¿þü`ü¢œÕ[†¼pûÁiÆ_îQ¸ëá?„o»]ùÄâIÏ©ÃgÞ†íWÝòl(“·aÛ°w§ÝsÛeé-9ðÙß:ö¸/¹buò}ÿÃO&~¼hݲaɯþzpÖ~N¯Dò??wÁj>O¯q‰ªS‡¦³ç­ìÔý®Âõ0Ç©À8îc+_&XÔ¶ oZÔN‚°æ9ÑìÄ.à)zHÁ‰YvOpªJ]ßOäº^rÔ¶¦RÆ€°aöýQ!¦·5k]qQÝ)&å­-¬ÔŽ;´<ÈaoYðù_:7ÿnà }nÿmø¶YãZÓÞíþ<ÿʧ6nÙ½ý¹G®íÒþàþÅ'_ù§— Œ¯éÓ9ZàùߎâsÁ¤_IÕ€5o}!'o½þúøß?ôqÓ?á3wá`Øš“¶]ï*ܶgÿ¿žVé p}óªw<?iŸçuh:~Ô—¤Rµ‹zö~`ÞôßU`ûqØ‚ï6¡¨«»šXGJT¬¾ÂÎöÒ{‚Ó8ІÚþË_þ¢=+I†’¸ ¥çð´8AºØùUŸ÷1C5Œ¨Ð«Ø¥DZX|Ý•¸8pàÀYfΜ9ÔÃoñ‰.RÚŽls¿[{$ÕŲSNþΩ'§†&5aq·«Ùµï3\õtú½‚˜ãñÿºŠÏ™órS dÖ?›Ïö=ððÀá‹–­‹m[e–ÒAÌñÒ³wòùû?Ž_ìoƒÇ$æù«N«~ñiÕ{V:ëà„rUîæŠ½’(ÊÖ–ëÚFŽùôÓO3 :th°§'.à–?þ8Jäü ÎÜ]zÀ¿×_ýÞ{ïíÝ»·ÎIƒÞ¹s§¨åO5kˆÚíwÝu×äÉ“GŒAŸyá…dn¼ô¯<¡ÜÖcÆŒá2¥{þùçW¯^½cÇz£^öþê0¼Á’Ç…{2ìÅ[S¾úIÿ¡¯Ÿ&1ßtUç#xsÞÛ'ã¬3ö“ n¼kPVû;Ö&ùø"˜ÏÕkò‹ýVi‘ÚŠ˜»ã8ÄZåJ·|Br}ûömܸñ€úõëg’„hNš€HXmÕªU(WàSnß¾}ñâÅÅ©^ èåi7ýïÛ·ïî»ï¦ð7ÞxõÕWßrË-‰¤Ë¨ jø?ÉCDª€™AÒ©î»ï¾Ý»wÓUzè!júú›O šëܵlÙ2P>kÖ,AÌÌuÊ”)LI…¬Â)}„)ûÿ—y^Ó¬³ÓÉxÓÖ=|Nï¡—ž¸î¦¾]J©açî?ó™Qíôô¯&|2wÎ+kæ½ÚëâöüÙ뺧ÊÒ¤ISóÙ¤qb¿=¯ýÁIäÊ…CöçÄ»&Ø=iû†ÑÇ!7ŸK–,¼ï>úèÑGÇ÷ß?˜+jL  Ÿk§M›V»víÍ›7Ïž=;33sÏž=[¶lY´hQaaaôC&AØ/~ñ‹3Î8cÆŒíÚµƒb'L˜S[~~þŠ+@9$­f 2: Ÿ .üá@¹H3¨“gq/-TškQ¦m\ädÍš5<ÖçzÕªU©°  €ÂP>²$%6óá.æõêÑòWõ-½ÌòÜ­ÅÀwÏŸ=¹â¦çùü¯Ÿ^žRàÜ.÷>÷ò(Ͼ?õCÞžÎkdtKùá,ÿ¼å΃Ÿß[|«^tÿÁÊÛÝ‚€öÊ/õú¸Â¯ç9mrbÄ‹¯[·.´ MÖªU+Q´pÍ$Ï„Ïr0Ð_»víé§Ÿæ²'MšÛ28ûÇ?þ±>“”w¿#>åF#„ãhƒK/½QžîÙ³'_U®\´ý=yÐÚ¶m«çƒhã–¬¬¬M›6“"y¡Š4׬Y“~¨ešGÔ¯_?‘Œd|éÆzÛ¿ÿÙgŸMk}Ö1Z‚nÖ¨æŠ5èã’2 õùñ ÉAðàW—^تؼ·FÎþþŒ/ŠR­ykŸí’*yêÌœºÍoÒî6oÊKµ²¯í÷Èk÷?ôª%ûö¹ ¤†ÕªYíâ´g¶W+ó*í=‰/çulZáqlJWÓA ˜hÑ¢ÅðáÃ/¹äÈd4jÔˆ¯Rìbàë)®J€~È¢(†Ð {ݸ¢³´°ÏOXëüÀWô÷„ºnçö*Y–ʹâÆGµçœsä 4éiÜ¢=[Ëšá,²³³?ùäÈ\pë­·R¾F! l“ ÷ÚëÂçf~ýúÞù¡ž¿øØ5“?YõÁøELûßuÙì…yšÛÂñßÏüøÝ±sϪRùG½Î«^$*2ëeÜ~Ã2ët(]9ëåé³Woÿl„ò/Üø/è²!<6xÛö}íZ9ó+È}û‰_Ÿ·0—ÙÞ gï¬Y£Š×{^Ø6½½=ddÜÀë…»øöÙ§î(ÿöãCï—{é@*@€*}k:uê1tÆnp|jòÐpñî»ïvïÞ ›2³¨^½zK†ï3ϽK—.ãÆãY¦OµH^¾¥NÓ:Ñ%øÔ÷Úk¯ïn¸aôèÑ>ø`4÷ž¹BرcG€ÎO.%‰S±SÕ#8î~dè²Uùó>úE¼Jw4ù8ìÆÓ`¬_aG#QæOú}²C?þ¸3N S†ö 7Œð¢Å7‘ • :é?ݺu;¸"õÓŸ&’;Oµ¢4iÒ„»ãÕÆCÜÎT•‹T‹7X¦Zµjf­L×Ç‡æ†Ø®\Íó¤jXÓy/ž—­ós¬?þ˜Ù^‡zôèaiUƒ¢ZõF਷§F´*Uª¸³ÚÍÒÚM9Š´…5ñBð ïÃ?d ‡t¯»î:#µ©¿Û´i¦ ALÈ€ÎÑÍ þ7¿ù¢ˆîáînn !ysÍÜÜ\Š‚ç®—^z‰Â¾ªw²º%¬b–”`!e@ûê!³ž}øG¯<}s Í£ÆÇ¾¹`vEPnݺõw¿ûÐüõ¯ýÇ?þÑ €Á‰Þu`HÚ­xú‘V­Z/”h^^ž.—ü‰Š ™b—n£ÑÚM£ €ÈŸh’‡~Øý¡ºpÀè®Å¡Ï©S§R9 @"¿ùæ›Ï>û,mЉ‚îG…tšý† Rù Aƒú÷¸‘f ëÝÞö2•BºéľânêSOù–MëÄÐüªú8EÞ1éáÝóvÝ}äà>~üx óꫯ‚‰1cÆÀ^”Acx£>ò½ˆ l«‚(cTµá ˜ð9—rÍŒ»Pæ$¥¶·ß~Û­%€é•W^Q@ÊÃ^q‹Î@:Í]sÍ5H¦žÈq°ÈSLµsçNÃ}»qLÇVïMæ—À÷©§žâ‡Øo5K3Õéùå—_.V§ì ‰^¡*®0%8F¯ÁÄYìA³ÝòåÍ›7?Z5—±¶hÊ©®HY]3~YîÂRmŸ>}.½ôR}ÔúRë¯& —Ù¸|Ÿòè£rþc²óióZ½zµq*ıtÙ²;vðç#<“'O¦'üö·¿¥ Jk1ÈVÞ(\ñ¦¶Ÿüä'ï¼óeÎ?ÿü9sæPŒ[Ð*t0ˆ\šÁD‡;sæqiÄoa( ' —¶mÛF÷«_¿>1¦ÑaÿO¿õ­-ÉÃÿäO<¡¬:ŠGäáù}÷ÝWR±²?šbæ„¶,åÿ˜<Ê»>ŽŠ<Õ§~Œ†ª`K+Èxæ™g6nÜhŠÉ\]㫆Ƀ9äzë­·Ö«WoøðánÜ ˜Î!¶6OlÑ¢õÌ›7÷íÛ—y£?è·#>‚322àr¹“‹ŽÍš5ƒŒçÎ "o¸áŠ™5Ò¥¹9O p.vn0ÍïºãŽ;Þxã Êð3ùܼys)º«¤)Ýý÷ß¼†J³Ÿ|òÉ®]»rñ¦›n2²‘ãO~‚K˜FœÃýÖì-ü™R?\ã„»øÂ:<ÅGƒQF+äz´ÂÊɃz(Faù˜O`1>­“Æ”Ââþ ¢—’‡¹%|ek!ûp~<ôq"]×¥÷¨*„Ñv_´q5{öìé 56ëZ¤‡ìhä{î¹e¶w÷Ýwƒc¾â}À¾Õ«WWatðñ’V¬X.¯¾új˜²qãÆ(ò¦M›¢Å³í$ϰ‚®ÔðÉu®¸Ÿ B}ì±ÇFMYYYt'’RÀï¢Á‰¢ð‡n¤å§¡&NœHÍh ïàÿñ_Sþ4íç?þ8(á(ð‚ah¾åóvÏITÎg¨(ß|óÍü ò·ÐþFÜxPR€šÁ„ã;õ¨)Ã×§ð•–n­ćNu”1cF`nÊP9_Ñj¦nŠ•ÄÁÔª -ᢽ4ú¯õXDc:´Ý àãñ`èJj™¬*]„¯Æãàl©ÃÍEN¹åª«®âõÀ—À·K—.ÔoòÝ}¼‘z²³³ÿòýïàÀK—.íׯ߈#Ô ÎðôÊG:ÓêQi€f¿2—ã[o½uã7B6ô®h×CQðæ\®;÷Üs¹wáÂ…†Þâ[~åGQŒþÀ£‰`••¯÷çŸÍ“G`,Wn ãb”ÔéóÂÂ[ø·û-׎Ç&hKüŠŸ ©9py(à9ÏryˆÞžòC¢ò°ú'åmI)Lêþ ë7…@ŠR5m××`w3!®ÉŽIy43¾ƒ]])É”aüÓ‹½—c…em—x%Y(ÂÓ^¦ÿq$.;PÙ+o1܃-jͼ=3ahúƒ›ºíÎËø¯ÁLÔóóŸÿÜ÷@sÑ¢EèJz;Åø ²G½tîܹwïÞ?úѸ’——§ ×w9Ýu3%§ØM$3èø¯‹Nƒ´£-,{ÅW„ëp (t”ôéí´Ÿ¯ ”_ñô€kßp†Ê'Åè±|ÅÔ%ª› 8í’ª‘CJ1xÃ÷VKƒË8ƒtašËȪ¤ðmÉ1ç㨱Â@¶xñb^³›ØLeg` cª¢‡ƒ;(ç.÷q…ë®5P‰ÑçÝÈiZsí\†>I…òÖ5"¸½‡iÊ ¶nÝ:xð`&s#GޤUT¥·»Q&–-[fjc¾P¹›dõ¢†àQêB³nݺZèÌyJyz š¯ÐÖç[.ê Z쾦hx¡èÿ ØÙxp&x£¨2Çz»VàfµÃ>ïž?ù¤$ç-Ð[7T¨–²XSÝïg?ûé$¡I<ˆNÅÈcùœœ¿¢ _™…ʹNŸAÉ„ƒ?é65]{<™<8¡~¸–[ 5Y<<”“ãgwFÑ‹«W¯LwZ¶l JÆç†Ó3Ï<“™>pAðŸumO6Œ;ÿpfÔa°ÕªU+€…œpdç‰l„8dÆ'ÐÃ-Ê¡@=Ô¬'†pçÑ.€óŸâõó¸ 6pnÚjÍŒÀš†™ú‰ú‘ k*á¿Éûã?>}út*§0â{ÕªUüðÂÂBžÕ£Gƒ¾ôiÓ¦Ñá6ôª©V­Z.‹Dw–´Drd!Z¬Ó) ü] ~Bèo_Ã:H ˆ•’@!33Ómîé0ÃܬY³ŒLA@nn.Ü#m»þ'sƒ*´õÎ;¹#¾ÍL°£™C5;Pr…’†P€Ýb¤yD#±-¤dÍš5)fèD=.¸Ñ>ÊØB×2ÜÑMŸA[¤Â2…TK¢íÚµ3ð ê­‰:XSX¥ìàJ¤E>G úØMÉ£$¬Åñq¢,ñ„tQj°š®¥nhÌtsÏ&ß®]»–i“›R•Ú’A°‘è¾A 75 ëáØÍ·†Öt=þ¦ÿ a¹Å$7аºjذ¡7¹‹Ú4hÀ W²²²¨Š˜6 îyŠÑ ·mÛÆs÷ìÙlR¾X7Ú ¤°Ž1L T]ìf”+QLûï*}[nIã@¹²Ë1ŽËѺ´uíÀÜbT³€` ãÝó€̧Ÿ§;>¨¸€6îâÐÀ7ÐäìÙ³²u¦Ó¨§¢|€l.Ö«WOÙ`GâŠ*Qò:¿ä@Ïnw†Ê½h®s‚N5„3Ÿ!cý aÄN'0½½(sŽn »µ%)LÏÓ¶ÅnCåÇÆ¨ü[òpÝÁoöâÝKÆú-(…Ý-G—‡1î½ Üh_£BDóüùó;vìèëyǵ 9q¤·@¨šÆ4ePI÷îÝižÊF-â¡Ìáh 5Þ¡® q£½¸XM= œÆ/]º”{i¾Qí`—Î&²CL‚¨…ØÖ¥q0YëÁ_'ŽS<]xÓð®þ ¾*å)Ã= &5¨…=ÆF] éÎû‡xônò£6àÎ'”É” ÂÜ",¬3ƒEîU;vìĺ_ƒÛfÕªUA!PfVn4 ŽÕÄàrëÖ­´“G»ÚÒÕ,[¶L'c~ 8PKK8§$­âÄ»c ʼn"j£sâð &—Áå‚£¯Œ®€ØÂž%õlˆ¸¦\µ¯óBGs#M™dI"a ÃX>¦ƒˆ¼uã²¹è¶{,áã©S§ÊÓZ Q䮘PŒzBaô3HÊ}Ý•˜t‚fÚ¹k×.õ48¦=¦áA`P³ùxÌ•¢€ºˆ®Ð,hËi®˜Ú•EvŠì¿ÈÌ1”Ë‘®àÅ@~³fÍjÙ²¥VÕ…)÷€¸ÓΨ„¼xpž|Óaö† O$ܸaüŠ0.«¹©Ç@šFìä@p»âm` SPC4§x:àŠE¨P‚gîoL·ŒŒ :Õ¢¤m#¹ñ“O>AÞ µQÉ<‹ù"½…z rÊÿбâNjÍ(G˜ýšqœ"ìtT3fÌe—]fS£[\ô(çM\°’••åÖ:Õ­‰]¥D`ÜÒð<Æ aŠÂ–>ÍÎØtžÁFÔ4D1nvT>Ãn·hÑ"ðm† ÓžŽ/rÝ…q³sçNÎ÷îÝkX:*q?hæOîâ'nÃlº‚Öó‚­#À:Ý”gs*/ú8ú>/^¬µÕ!^ˆ vÍà 8vïÞ-Gjp Ý\?S30q²~ýzãQ [¸ Rê ÓD‘>À@ï’!ß©ڤ;wîìãtAfr¶råJS«ëÎAySýQX@ó©ÎqòdÝg%ƒ\”ë†Ä?~<Õ­àÑønîwÒ®•È)ö¸˜‰Ë…®¤âo…‘uÁÛÕ© <™] N\ IpIÏfÇÑf'ÊhS!˜Q†[ŒÝ¦ÑÍxº†šs—!ZnÔ®çº ‡õ»L¨3†Yý(ωŸÚI¨ÐàWzú›Ú‚…$lôçvmÉ´M‹µ´É„Ô«ÑðŠǪ‹ÇåBWñǀ˭s ƒ,Üf20m°gú¼`¾‚³{÷î 1oòtI—Ƀõ¦M› p šUÙ(Š_è|N_ƒÑë§¡™ÚTφ§0°ÖŽay@ÌÅQ£FuèЕÌC]àP\{íµÁóÉìLnÛ¶mûöíß|óMúÛêÕ«iUÇŽ³³³é“”)L¥dK¡Þ8¯^yÔ‰¢ô3:ш7º0q2Ž»ÌûÑG’.]º)¨ë½÷Þ«]»6H‚ÛÀ ;묳 H Ìà?wŒB±AÛs‚;Ž{Ox S.•G3âÛ%Ü4ê”ÎÜxTîŠäM«(|jé-Zýx¢Êgݺuݺu[¸p!}ƒ¤‚/TÍoÄtŒ¥K—Ž=š[”!Ï_:^S”qŠSo|”¯u@ÉkvPi~~>4 tÇ‹/¾ÈkMš4s‚ÁÝY—iwQÕ G `¤nÃöPFs2pÉË˃¤C´í @ÃV~wRbAédËô© \³AŒ‚F2bh{V¼:ï4º&¥ðš5ktòd0aá¹ØÁͯJ04h¦…ü3°;\Dœ.‹Ã,D3Šãv”)¾oZ×r“qÀyfëp³§žeèHSP’‰?àvè×òà–8eƒÁ¹˜™™Y§NœœœàW¤Y^7Ã$x5õ¹vY†Füµk×Bí*æeË–Ñx4 >I´U±„„h<'nÞ¼Y×~‚†d-'ü隇êjg"áh€@½Ñèagu âòÈÇ™ƒ²Ú¤¢‘F¼äº‰z™q‚ž®W¯^HºÁõ+®¸bÚ´i”òFÛv‹Ñžä1nܸË/¿œb€ÒÉY"™Ž—&LhÚ´)CAAÃ*C÷îÝuº§Nš„¡­¿C‡ECÏš5 ,Ò¤ÆÓ¯àlE×®]éš´$vEºÐªU«tˆ30màŠsAÏ º´aßðŸu±HÅ\Œ¡|œC‹9£VŽ9¦ÔdÆdù"¹ÎŒ :D6èwaZiw¹X°W¯^S¦Lá„I˜q8¹ˆbÊhÄ òF™™Ü ªáx³8¢e­ÊõMÈ`1‚%èTt§}ûöõèуñ "Bšá¨äÃ?„ª( &†Ú°ar5ÛL%Žg(L#© YÕ1yp¢Ú‰ÚsRÖ;šHIÑ-âãkãcp w¶nÝzüøñœÃjŒìP”øsqAËoš×Ï\ 2¼{ÁE@6xð`ª‚Y™„¹aàµ>à ©Íàn( êÑŸÎ…7XV…@õH‚È6wî\:¸§Iºùs;­¦TE1Šq<þ|Ôõ÷̺6©×‡zÆÅ ð8„½ˆ±(ꇙÒ<Åî–œ<>Žõñ?›;’U tzd”XÞ®]³9ñ¾ùŠOÊïJ`ëK©»:ø@Κ~¸p#×K³fÍÀ¥ÂõDQfHpFg0ª^Î!5è¾àÐë*m0°xÉ%—û…ÃT’¹LL#Û´iCUHó‰¸jhš3¬MÚÞÅ€À—†ñ©¦JD\ÛR6™ÛsŠ#FsyáãDrsPcÐWQ˜g 2pKi.+,^¼¸S§N@= ¾!Qô(`ÜŒøR;£üIÍ ÅL Ìêt‡pq„’t d²3GåÊ *§¼ÓAhÛØ„´S‹¨Äà›¦b: 3|²V ­jbó\‹u Å>$Rc—G¾1œ”Þîú¯…¼¼  £;„½rQ_¸æ¨ú‹\Ôg’[Œð•‚T£Ë©7Ö¬Y: ³á`mÔ•"ä¦væFcp»ÁÛ7oŽPf¸°°œ‰¢m‚‰´¸ƒ)¸ŒF]‰~•¹0>Ê‘®Hy7ºû¸/ݸa´µÕ«WC‡³‰mŒ`Ö0 Yrídµ3téÒ…áÞeg Æ9âTY"ÍA9Üï.’ŒŒ jx÷ÝwÁ=*–ÐÐt“'èŽ]÷Vj›lÜYYY017ºs6Éå“âJ%à¨u¢¤™\ŒÝò…ã2ZòÓ_¬]»6oÊܲe |iÚ2îÝG¤¢ŒÑ¾ŸšrÁs5#ñšñŠž¦K 7Œã†Ò0pÀ…bµFW­éKü°þÝäaÇãqtš ƒfE)¿1ºƒ+Q\xš¸XW”Ex„ìwÐ0,èÖ7¬8)„S](Q9´nÝÚ€kP¯·™Báúl€9j@8Å”GÕë(is‚hë5êœf`“HƈHþ64rúŠO@m:vcG¶oŽ›LU”A›–æDÒíÝÀYºïMØ4??˜“XC˜¹ÉÜÍâ™Ì¹Œ·víZeÐ4kWÀeÆ é `:ÄÑrñO>v´q[JÉíFz0š¾'”>.ãáÒ´6WÖœêÔæ¤ÐÚ—/_sk’ãÊöíÛIï"oäSâ¶mþ47:X§Xnn.D‹ðEˆÃå®+ ‚#h”z³¦«áDÚFèÄßh>.v Ø¹<#Jš‰hvŽh¶2]ÿŠ7Éí'®¼ÀÐÜî´/;;»yóæõë×G3¤†Râ¡ö-¶ý±8¡øø–¦ŠÅM±•(—kÔ¨¡aaÆ Ú4ÐÖ \HZìr¢m8ì):-yâ @Æ01j8]õ–ôtÃ3G­.)Ø|âóqÔ ñÕ×`W´wï^…‹ @Ö%CUµSXÂРUÌêj&ø›¯Š¾Å6/€|SX9^Xþ¦èŠ£û¦5¨ðʨÃàØôMˆ ÷?#!Ón\5z,*Âh³n-½é Nÿí1v¿Ñ8>Z˜Ö{!˜;@³YJ]ŽÖ‹C>6®€µ²?:ÚÎ׈b+‰Yù=ÏKü»-öp¡šôÿŠŽˆ2DŽ;ÜÚŽã›'Ž¿ŠD9¦88v•‡šã}MÇÿøÖqÀhYìe©Åæs.åYÎŽR~±†¼ø¨ð8ÖgòhŽ %ƒ¾XŒ¦ç§9úƒZ²~WyâàßP]qÔíÇS¡¦ì ‰ñtÂòqâß#«’_¿.msÄL÷üâøè¾ø”¤ÇaˆOxŒ~]ìƒQ®q|ìÞJ)5rÆv´tĿ#ÆÍ7QWòkiãxêøôtc1†bt7y]là•¨[RÌÓ1ŽSÀs¥€ãèêCVRÒÖ¦ã٣⣂á¸,kÚ%E¦*©K1µ¡">b;–Ž›hö¤áWX] ‹8)[¦ã£¼ÿ_€öÞή¢Ü×Þ÷~Ü£€ !$t:ó<“€ ‚ ¨ýð(¨€pdÐ{'T>TTŽˆ (rGf „„’@æN§ÓIºCf ÊñÞë÷d?ö{нwwºC& Š°k¯]«¦Õõ¯½õ»êÝTT’܉çÙXãu"˜FŠœrÚˆÜ.g,~¥]m{zË/4§œv "·´-ÚuJ“y>¿ö7¥¥VTFJ2ÇÙfê)ll² ÿœrÚMR‹ •e¾¼Þrß%8Â¥–†·$|D»Œ!vÿIN9eDΦõ{^ÎÐ’ãƒ×ާ%{ùížß·åï$ÿ‘ä”9Ÿº¾¹ {ÇÀ·}UXsÊi‡Ò>yvѶ+uÝ 1·-:O%¼SxtN9å”yWE¬D­Ÿûi$ßBr¶Ç]µ”ø)‘iD×ZQOlåÄ/SãœrÊR‹=ÂãæÍ›çÌ™3mÚ´^xA?\dÿOsêСØ1c† ²ß~ûîÁ´"Wꊴ\m<ãlN9eDÞ{EuuuüãÁ©OÍç?ýÓ?í»ï¾…0¾Éßþö·¿þõ¯Ë—/ïÓ§Ð .¿µ˜"„ÔAºxÝ‘sÊé,µxý mùŠ+ Ëzˈd¹Ðy¾¸ì¯Æ¹œ9sfÇŽ=ôP>Áq°»]®õwbû+ZN¾µî‡¾sÊéu†È%!É_/sjÁb@6Ü¿ñ5"Q ÇFÃô¦~’_|ñÅ%K–tíÚµ{÷îÜ1f¥rŒ=5ømÔ nË«iI¸‘÷rÊéõÈ%ôêuÁ­@Øpñ¶~ýzñtŸ}ö17aÄ…¢£  øî¿ÿþ|þõ¯]·nÀÝÈ­{DXTr”WñÎ+Z™;ç”Óë‘Ëuö¶I[‚\’b yõêÕÛnŸ}Y•+¸A›™ CÄ«}ó¸’eÃf—åÙY-l.ïøV\«Z2¡NýòeDÎ)§½#ïôÐ7^oݺuóæÍ`ׯCõä-ÍÙu´ÔæØ;€éOúS™Ÿ”NlÚ´é­o}ë¾ûîKùߪªª5kÖP;8E¸ÏS7nŽ?~èСØÐH+´AÙ]¸p!hKÉ  qÛßò–·(»aEJ¥EU¨Êã ,¾kjjzöìÙ¥K—:Е.*ÖKzä‘G{ì±8¬'3•ò©xä•W^ùÏÿüO>5?a„C9ijD{WSpWÕ6þ!UbdtÎ)§=Ï‘wV˜î»ï¾—^z©W¯^ÀÖ~ûí·o1qó«r[pyÆŒ`% Ì p_…JgS /¼ðB·nÝ@d€Ü‹ý•ëô°ÎØï\P8%Ð µººš¯4€e#rRZùŸ•R•R—J~R/m¦S֮ΈÏjAåŽ;R—{‚€{%³»'RWêf³|UxŽ5rÊ)#r»E;\‚ò„¶Û(“è€Dœ°×(”9—çÎ ºUUUuíÚµS§Nx _ÅÄ–ÚÏ} 3$iŠ;%¡0Ó3;BÃ<å‘%óÉÚЊ&œú›“#ÃM—™}/^ @ú=zôP\ôßrÒqh‰–P¾v¬lÉ«rKÝŠ0:§œ2"ïrDÞ¸q#ÀÄ'Ûùý‹ ~ÇFž‹BrX´]r‚$úœ:ÂÂ|~û@«+V‡G¸£”Yš\ŽDèòky±˜(‡Æ[zßU! $•ê‡ýíokll[÷)¦°ñ+ÉO 7mÚDƒí‹ºtbzŒOØ¡lÙ²…RÈÅ$ý ¯(Oð&oáÖ[o]¶l™B5óhˆÏõÑG}ÔQG±b…§-x]‘—ˆ•KVÍŠärÊ)#òkJAÊZ™WþóŸï¸ãŽƒšÓ[Š ˆP  6€Gyäÿ(&1«\$Z+<~>"ÞÂ\»Á‡árM6Ê¡º_|Ûºu«ÆuÛ €FŸõcݺuÀ“(©HŸ>}¨‚f÷íÛ—é…÷ùìØ±ãK/½$œÉúI”Ã"DX~hCEM8sN›6mýúõ´–ò)‡.€’t³W¯^ ¦Ãh›:Ekà ¼Ð¬¦Ö†|e”`ôÊOÜ…¤g¡­ÿ ”Ä ßr­«[´Í™#ç”y§%\Ìmg8Rh>“9²ñ_½z5()ÌÁÈTù*Q“ÁAÉÀO"”p_hÖ.ˆ#µ íÎg „~ªö¬“r„ÚrPæ¢{÷î>ú(`jiZ„Ϊ¿AÉ .Œó1ûE—ɬîL€K…Ñå§‚*Õ…7¢ôOõ£ ¯6]ášqS]ºÐ¬ð@½. )35ÿÌ™3ÉO«x ;ãIN–@®ùUÁõ²nÑ…Í›7³z)iï’œÚÍ—;™+¼6ó–œrʈ¼#{UÒ 7ܱ…”A͘ހ (^»v-`'ˆ0ÿ-ªÀ 7ॢbÒ”xÆ›JŠÓy®µ\8΃ðô3Ï4R§¾Ž‡zˆÆë#T‘…ïÂëZpAãäÉ“)9Uvn (§ [áÕÎçbÉr‰œrÚMˆœÊa!\!ÖŒ-‰¢›ÒR¦=Ü Bºaà ðn”"?˜ ‘ÁB¿”êz¡åžºžtñàÉõô øà¸n÷ „{z@GRÃAŸÈ|Ò5S(ª¬ÉCŠ":¹†eϘ1º †jøg›S™,CÄ}ˆ6yÂ*DÖ .Ó)vX‘@Ã=šS[nÍš5å4JÔÑÜ1¤’îÔ¡¾Ùâ4*¢× r˜;õn;z†Ju&Â9å´k9=Ö/ ?!cÖà¡¡«L¶œÿˆÔ $0PC°H¥ °ãBñ(ìù矅b«V! ’Hž-[¶¸Ú’^}èß FÐþÛo¿" $â…f› 8)ÀGQên"Ê×Í L½ $ƒ-Ú ­úHc©xúé§Óa ܤGÇ_ºtéòåËÝ ¯ªªîYÆJ@¶ÄßEØv+¾°yŒ˜æ…ʈÜÄxòINJVŸÄuÂWÓ®­RÊŽÛ>*§œ2"·5¥,¯"Ö0™ÇPá{õêÅ6¼Gܲa…L{0¼ ð§ÐY’°xàY {Ö¬Y*·ñ+E|TÑ­[7 B ^³éVåvI°H«ê\Pì@|W‚ò®ÍŸ?ÿñÇ÷D À¢yacæ¢Bi¥v}…fu–“Ð ÷@v\ÓjZÁDšC”?ï¼ó¦L™¢Ï ~¢yž…8ŸvÚi€5Õ)ñ&EÕÖÖ’sòäÉà졇š2ߤ§½c@ ÔqÃÍ Ø¿“›Ç_(¦††ò° …ˆ_‰M{´¢?åe+˜SN‘K£HTÄe` T­©©Q»V£çþýûó“ûîTpÁ„‡ö‚D€)×!MNX ˆ”°lÙ2ðœ-ýH—d¾»ÝÖ{÷î ˆÃ.)jÒ¤IJÂ¥<Ò•þùÏfU³@.š$x…# EêX([PDÈãÂ;òe%'j¤½RL+W®¤k*{¶ò\Õy–ÆS¾vÕªUøÃ”‰³0ˆìt‡by\‰ª[x”„4UÅá…k‡ ò3> ݼyóÜŽè6ÆËý•_§vê;প<|Iº¹É)§ŒÈí›BmÜf–<°Nœ8QYz ªÝ»wW +”½À#-#”K´T…;h²•¢j¸×5€ †•@A‡¦"` ØJÛÆŒùUh ÜÄ![X0O:Õüîë¹ÏƒÑr óâ4R$Õg¡Y¯@‘ÅKw¤óJYKÈ ¥ídU"æ>ù¤Ñ15ß±?¸PO,ÑçÛ®`N9eDÞ¾\Q,ûŽw¼dijjb'Î܆î‘ó°Ã¦M›Ö¯_?¦=8œ 8´tîܹõõõlÀSçé¤UÞúðÃ\*]h-­4x¤Ÿx…%°Hf §ºº‚™ÒI¥ÃÓ§Oç¾ú¹b.°¥ÔµÐìÁÇ•@]]nÖ›6mÒÎ+{-‰Q-ôhÔ'ªò”?­X±B?FàÁTÚi>‘m˜]¦^†Å¶92¢›¬|ðàÁ¢|¼Žr‹DOåûô‹_)З¢™†©½yófŠuqÑ¢EädÙp…:ß.=â”P‡BzáÕ¶!Y”œSFä¶Ê%Z'Å­ü$‹q ù¢L8ÚwÜÁüç«¢Þ††)$Ûg`…›ê“…˜ú@ÈUWW§€‹ÙÔ|ò”ùj7hÏ⨔‹È‚u L–‡pB$á ¶+ðšíŒA+…¹<ÅB>AR—‘7lçâèRÁ‚ã ¶Jré&h¨¨¯©Ÿ å¿d¨ªª:äCXEt-[[2ý’áBðµ>·×©šù©ˆU‡Õ‘Ά»ýÞ½{ÃÁ]„rÃ:Âl)(MO§Êí‚ÎV7CpN9µ‘KØM+rŒ4gšxâ‰'Ø:ãy*Õ³˜Â§°²Kþkjj`dt ‡%Á(=j&„Åðú‚ð¬Še"ZdI´”¥òÙà×`ÂepÊc4…a‡íÀ5FBø p[‹tXù8hCCuʡö䆂„]æ m¹†h«³X;nÞÓU‚v1”CÏO _¹r%}QNÍ@)Äð°ñÉ'Ÿœ4i’Èë Ц}€CŠÕÜP›FŒÁºU"nïÉ^ÉcN9åTŠ¢m9œÙ®WÌVÓøÖ[o…;ÿChL0ùո⤎“±À! mPf>ù:{öl>)“_ÇB³rXPQÐ4÷|,d»it;Ûàœ>á@v0Q[’º Ò0OAjxÏ1Åb«ö+²›ª`Û)bWÇÒeÀ¼ S HªgQuõ”ÃÐ$F@÷I"¯ êÐ;¶Íž R;lAh ÅÞsÏ=⾫KÔËëPÓYE‹T&îW®µ«$/Ž21MÏÛ+Vn=RjæË9eDnÇDjWˆâÚÚÚ)S¦8É Í!3¸Ð%…Z\AZÍ–{Bž»ï:¨n¡Ð`cxÜü4¤V{pªÓ)þ½™•›JcåÅ. :¯?®=⋼ôHÊÓHÁ+Š’žƒª€‹„Vã¡€l=lIÄ}]¸ÁUé:s¦dݺuäÔOitvV “ê®_¿ž%ÊØì¿…Û£œHŠÃ¡~*lq”ø¤ÞËùyƒ, Û^ äkyÀÃŒÈ9eDÞù‰-óÃ?üâ‹/г±ºYL`‘¢¦¦FEò„GöBâ´Aš%3( ¨IT+ûÕ£B¤%ó (cÕ]‘(¬{6Û( âµa Ù«y#½\JQµÀ­¤ÒBçÿnN©ÉœÊ ª÷ê4™Fd ZʲCkXm¹ 6,_¾\i‰²Ù«5꣙›`"HÊ…0j›Ã Úd!4õÂA jÊôm¤J hW,.ü5|=Öë£Y}8šÑ­[·ÐiÉcêv÷[™#ç”Ó.DdÕ`yÌ^µ‰¥¢IB•i*s€s+ €ó<¶‰€pÉF›O1WŽé³*¤&dqÜäÆŸrXwÙI¤PT7ÖœOµb©BO¡x¨ŒuíÚµ7næ\©%Ùx–2¹þk1…(#ôºBQDù² qT¨ƒ nê‡ÈBh¨Ý«W¯‹)uÕ¡¡¹ˆžºlÖ¬#õæ­ ¯Ï#FŒÚΨæìr¥'¿*t6IH-,GWWÄ¡”=u ¥ì¶H“·{8œ½[ä”yçÀñâÅ‹xàP,d”òYmçÜԻݳ2í!ÀE¼(4ûÛŒ0q"c>)S¸‰-vœ…¨ÄrìvêÔ N§x§.WÀh B§‚òéŽØg3ÔS¾a\jMõB”aõ›0ÂOœ1ʬ…6ãIs_?dc(øºråJ† 㱓0–•dœOúa>¸cX<‡t=[±b…ZÞžC†ÁKÄ*å>½fˆèhëDÞnЊþžº“v.®=-©¨*gvœSN;‘ƒÁM:U‡gÎpÝG„_Ikª«+ x²ÇSLì=z¨LÒ­~ׄŸU’ -Ÿ®/½.4G9 aˆå‡Y°Âh£F’5o GEa!½zõ꺺ºX¼T ¦ìÖi0Í3>HH«G?©ehk€q,<ÊÐC£nÉ’%j}höݧOZøØc-]ºÔVIHÃß¿_™xà#US8û >¨Î@v%?Ü?ôÐCAm ?¤®=ynºŒ‘ÁX$l_xD+v·…æEu?¨eÆ tGm2[WŒ{-Å9åôÆN;ͯSôÑG5‚F($„(V<y=þÒA³WÇ»NòåË—/\¸¤4h†mB^ꊌë-[¶îS¬¼RÇr@ƒ‘â‚ôÔJ3Ev=À¥cc†dXí ç%‰êÄîÝ»×ÔÔ(™¡Í¬={öä~CCêU«ôïÉg%ª´“üJ$x\=Ýe@]©t=õM.C<)A@Œ!UC9B™„kyÏëÜ‚R¯]»–Ö9…–«°¡ß 3{d§Ü#ÄëÖâ» %?éÛ·/#LƒY6xd m`qcc£cEùîÊÅÊÃ}e,Î)§È7n|àôNIŠã~f2@B)|tÎ mÃb¥l"f¡¨ë&=Õg– Þñ ,MgTMã«ZÊÂŽ40<Í™3'%k¡b¡ðÁ;¢¼>Ò´¼ Áঠ¶ $­¯¯×/‡Â~5º«"o†Â.ëÕêÊ}=s®Y³FãiAÜ“L:âàTWWÙ[ŠI”TçÄ…­Ð¬£¦R i@)- çA”!6ldœœ¾£*ÝvgÖ%6&„ìŽ9…ÐxõÁyõ,Ü„ÎGl•0åÔv1O¼œrÚUˆÌ[°`Æ]…¢yX¸ôÕžM±i ó‚üêÞ~xË& _-¹;$ÂÄEù¸ªµ€evîܹPTÏe²8óô$ •çê|]õ c’ÐФµaQºÍƒ`4¿ò IH½>ƒøI޼zõjí*gpPCápÉQmC^¬ÿ{ À…Ã{Š^À:û÷ï/à‚³ µ°&þp^Õ?øUû¨÷;NTŠ  ZËSTAËCÒMêó^¨Ú)ôwõR=C™5U÷ë×v’™Bxé…¢OTVp_£¾Ø…È»Kìô2ç”Ó®Bätމ5%’AAM÷ðNQ÷ ~ kn2½ Em9 m¥‡å{Û¥êÀ×¶òe]Ý.ÔB¥*#Ã.¹SVCYªçiŠwƒÊ¥ÑíLPW€¯8ˆP®wïÞìÒ¥ ]ã‚A%ª "QIÕ‘B³Éµ”VÚ(Ñ.•=¹èHŒSÏUŠÖêid¬\u4,Ô’Å‹›jDÐ}5(@OR/^¬:Cª»}<÷%* * ïÓ§9AdîôíÛ—BæÍ›GE µ{^G“Xçžzê)J`—!ÅÊŽTvÖcßAŤ!¸2ôÖ¥íUrÏ)§ŒÈ•SŠ’Ìgii×NŽÉädn‡ÍwÀ° À IÅ[  @jq6Ì.Bp!Æ >\è!§¾ƒù ðÉWª£1„ÒL®õ\Au€ˆÎì©WÕ eÄ Òè|~‚;Æ- ½Nœ8±PT(Õïà¤"©Œh ó<£™ðHSS“b–h/Í k €È‚škᢛ^Å$?óÌ3pRŠª©©#ÓMV pPÅd†”òõ‰!3U³¢P4´#'X©°ž¢ßkLH6q [»v­ÂåB1æ JÞ]]tÎçЭ*&7L*ÅÂLÃtâbY¯¶âŸPN9å´3¥©îTÈU%bªÁ…£z¶½ƒf2Ãàüq~2d_ÁVP€í?×ú–ŒHÂe%~úôéÚž…7 ¨1¼•ÂU˜sS€Å JT4¦à¾{ùÐ-+ñ0¡¶†ÎÒdY°² ê¥Á žâš††çŠÒª-k¼:®.†åVÚKcèÐv a0ÐgŸ}´UüŠz@s¸Ur šáÙ© Ôj’ÀyyÅ€<ÔèÂÔR¸ÞJyî6¨Bv¤öè›üÄâÄMVAÊÑä’%Ð[3P©NéÒ€R­¯å9å”ÓÎGd‘Nfç^X¯@âŽrI&*ó°…‚¡8g2 ±P 1§<—l/‰s!ñC¯8X]]ÍS…W‹¦)\è/@(Hb®f‚p¦$º¾¾fJ-)£—Ô ô.JºEá0<‰à˯,à”^~轓 ¸qŠr„xË R8Ð`Ñ\h}!iè¨ûÐ5Åä¾A¯îôÀ 2*“€sS‡G$·*Hðɵ~–}kµµµuuu´¹GvKœ ÍF4” }Öå?à®ç~®ÁnúKE.Ú›¤ª‹sÊiÏpd·Ìi€áØæWUU…>¯¬S[¦4˜Èæ×xz*(h–-–×"¨ÅY_–ö'ÐÄ@÷ ‹ÂSpY; ¥úöÔãšÕ°ÇKõ: Í–ßÚOšéBáL ÕYÕ5êDÛÈæ9[ýžDD=Ú2\å!®ÅÜ´=„v}ríp·ç¢‘Rl yš'«¥mPcWMC2î˜p“‹£>šÌ>B9¡Q§P˜Dµ“²ãˆÀ]QÝmg¥oýäžéÏ4ËÝöÿMß?·êÐ+æ|hÊ‚k~ñàß 7çgwúI‡ï‘ÙuÃoúù-‰ >~âgŸ´cål~éå›o›d×Ïùè °_F®ŒÈ­ ”™Óš]+H6ù”úF:4É$nñºuë´éFž˜Ìa~gD–¬åˆ`ª½†dS¹p¡¨§œZ]4-÷(_«n¾Â:)A æ°°Hµh¹ÉÆüÄO ¶AìVúlÃèˆr ÏÍ<²îÃø%Œî¦M›f|¿BÑSË ‰§atªC‡ #DU-×ÔÎO‹iéÒ¥ŒóêÕ«5IÛL\meÅÄžæ¹H(®Q*цŒ‡gQ•ä๠lDE±‘a­%±ƒîfè %€õ<¨³Ž]Ǥ­/¿’~=ç‹¿®ÊÛàøÆÓ;[^þëë}–.ªkºîw;¦o?|à‘ceäʈ¼}¦'c +TîÖ­[8Æ åvÒ÷˜zá³Â31ÝM1º7 !€¢[l¥xAo0¯¢I„¹ —ob7è (Š*yTH†¯-N‰;öð–ڸÆ Kcú…a4iÀ€â£.AT±­ƒ­K–,ñ4’ÉÜÃC“ú|2åÇ{Œ_]q³òÙ šGÉ£FŠƒ>3V¦… R£9] tˆJ~ [X <d Q]SSC›) ˆ‘L•UvéßîÅ_ÿÝ-ל»ÿ~o‰;s5•ÀqëéÙ……Pémé°¡=Ûþìêµ/®^·qÖ܆Ç÷îZÕåy>õñù×z9/mùKí’•þÙ@~õ¯yí#§^°hyÓsë¹îÞ­ÓÐA=óËk/sX¿øé®f|í;·þ=ùùG#š¯.>ïÔÏœÿ>.û9/mÉGÏ¿:%ÿë‚Ó>{áZP»âŒ³¯Ü¼ykIQ~ð¶ýþãwW Ü+-íû?þÃ÷ô{3|ñ³ÿü½þ[ áx¡ésÞ÷à“~ö‡ÅÂÿñ»$‡ïÀöÿ·[.?æ¨R÷ $ÇA–wÅ_íÕ—~èì/ü.‚ò¯n¹æ“[^æâ—þúùóOêrè-!òþûoó Õ·gç÷¼sxß^Uýzv~[ñÎO-þÉM­Y¿që˯|ò ¿øÊÅ8ù¸‘-5`Ô°Þï7xôðÞ\ß;iÖïïœÊÅ’†ÕÇ}ðŠ»~siu%¾œ¦½éëozÀëœ|äÇÏ8VjüÔì:þÝòûG^zéåÈ|÷m—ϘY{å5¿÷ë×¾ð‘Á{įCš¯?Ù ¼óñæ›=ùÓK`Ç\ÔϹèû -‡8¿ûý_ü'¼óºï}ºb«¾÷£TqôÛ‡ù·Ñ¸rwŽ9á3ó68‘.ýü™žÚAEÒ½iÓÖ/ýç·Ý> ¤>e—.ý™_ýâÇ2ªîIDöXÉOe‹NãŠpzrá“,Å Å—ž•…Ça‘«-<.œ¢…_ÊqÅÓêlÄqV´PQ‰KB[ü㤊…f æ`ýñ+÷õ@ÄW}S¤•¢ES…³Tü’6ÉáRS®í€«AáÂxÆA¥ ©ä7ÖÓsÏ=׫W¯2…G õÄCS0†.|k8¤Þ G£»MdqóÎ… ¯{~(_ôõ[·lý‡°ø¬ ãNïÔ4óàÝ7' —Ë‘'>:ëßïšâõ'?vÒ_ùxü.?|×÷n¼ù¾oü·ðõöÿ˜|ô‘C?üÁcË[µtîïª$ÜøÊ忘¿p™×÷þûUã?tÐþ?¿îó|þë/îäëwpkFä½BŽ¬Ù˜çK­;)@sÿ·¿ýíñÇß©S'Çžé¿øâ‹ .<餓$ÈaD‡ƒ¸…ñ[œe¥:XúfSšAžýŠI \NåÈå|¹äë¹çž{饗jßìi¡âêÿMœ8qöìÙßùÎwTPs­Ú°a•’-010º8A¤¦œ)S¦€‰ ‹~Ž Í>Bõ¸6}úô|ä#”l¿¸Ð*:ÔÃáJ„c9L·¥\pÁé§Ÿ>oÞ¼ÚÚÚÎ;Ÿzê©'œpÂw¿û]Úyá…úv\Zºté¢@ß–„ô‰¯Ï?ÿ|*Dnãöå5¦ë¿}& ¼õ/]·a³{gà˜­?›þÙ-?ôؼŠR‹kIת£‡÷™5o©ráíæ¿ò«g}𜫷lÙ†³×ÿúþëu_*µøÀ)ã>sÞ© uÛ°°vE\Ÿ÷ñ“Ë3œö)"2iþ¢å®TÈA-Èšï›8=®OýÐ¥¥9íEˆ¬ŠU [lÃÃWd¨^ˆwÝu××¾öµÆÆF?øàƒô£ap±#Ž8býúõ˜®â=ÅÍtÎß~ûí‹-úú׿>iÒ¤U«VrÈ!#GŽìÓ§9¯ºê*2|õ«_ Ï7ÑOzš—±ÕÉ.SÐt‘˜9sæ‰'ž¸qãFéaˆ›¿ùÍoN˜0˜ã“ŸÈàù›š\¯X±BE!O(4;híY¾|ù—¾ô¥áÇÓ)sñ]tѧ?ýé3Î8cèС¨¬FÞÕq­ÎC©CÃ/¼¤êðhÓ¦M/¿ü2@ ò^y啬1 /ÃxÞyçqÿË_þ2ôYgÊ,$¾lÙ²¾}ûùÛ¦zf°MŒX û](³µÙ¥iÿýÞrË50å_©†qÂø!Û…ã¢ùßD?ûCÇ|ð½cÓ ïüзw¬1³ç5´=su—Cž|`§~dÊܧ‹’ŠÚ%+ã×;ï{òÎ{§Õÿ·?ÿ´¤é¹õ5EyEÉÍí"oK‰üî8<`ÿÆÚÛ3h¾8òÚµk=£/4ûJ˜Ã°(61±bÀ…mòÔ©SÉ(Àø.¿üò|«¯¯ŒÂÙ’]}ß@…f?ñz _½zõ‹iìØ±ppîÃazè¡÷¾÷½÷ßÿç>÷9*‚W*mˆÐp%pÂ9'I-4šj¿D1 +>øÁ^{íµ²NÖ¨"¸Ïª@~¾Ò}ý]PæÒ¥K# *×ki*UÍ ©©4|ôÑG׬YÃÖÕÕ©2ÌZrÇwp‡rjjj€lƒ¤¨š¢Çz†×a[š„ægŸ}vàÀÀèõ×_OG~úÓŸŽ?^U9ø8‹ë õJÿU:•c‹hÿânÊôwsUÿý_/j{þ9‹ãúËž:~ì€ÒŒo}8®ßwâ˜íætÊÜAýkÀåãÁ¿W‰¾}ËŸî{ò2åY‹8|`ɳ©#Ò{Ž;üG×ÿ‡××þìŽ?1¤$Ã5×ý’uäÐvõî£g¼û«—ßX¬zëGÏùöm7}½b¶M›¶lÚ¼5ë]ìˆÌÜK¶8×b» ieæ¯[·ŽMñ‘GÉô¾é¦›6oÞ JÊ¿ ¦yöÙg?òÈ#º9j#T9;¦–Y³fuëÖÍxHš'À=/^ÌF›k¶ù={öÔiÑi§C'·q„¦& ›Õ›ÚÀÄŽ;F-%bbîÏž=[iŒ¶Ådõ`©äæ)§œÂ@ïà­´‡Aàæu×]÷™Ï|fîܹ¥~âÕØ¥:¨75r‚wª²¥ÑEÓè‚ÈrróÍ7S)ˆI!Fwåâä“OæšU0”ct+u« ×(³EÉŠ¤aÜÌÈôîÝ[ykF¡9"­rZÈðúY…c-Dè›Fûðç îõ|¿]Yÿ·Ù;zÌ€[þ}ª×߸掾=:=v@ýòµÏ.X¾eë+m”ZŒ{ß×ú÷êÒ¥êàöÛwqê% «â¹óÏzw[ù³—ý2dÇÖPÿnjh̘µÊü_2åf8>2Áå .ù hþö±ƒ¡½ÓŸ^tîYïùì…† êù‹îüÿy-¸Ù}ÈG3è¨#†pÀ~ -¿ýOE×~|õÅíEä Ïû@cÓÚŸÿò.®ïŸ8ýàê÷Ötëjøú~FÕ=ÈÀœî‰ã؇  Šù vèÐIX@\ŠÎ‚¡Ì<6êÆ#ýúõ[W®\Á2Ò“"PcáÂ…Duu5(Ñ4hîån½õVÊ?âˆ#4k¦|PÆðϧŸ~ú3Ï<£6t×®] Ò!Ñ.$ª]éa`´dÉI}¡èžB—•:•§4ë¶3“â%6 a¡èì˜GX{@dŠÕC)-§ÍZ$ª¾s“òáòR×Í&S)CA™PiMD˜m#G6n)¿*ÅrÕ£GýyŠ×,¢s(YËëXºVqCÓúÝŸúöì|ׯ>{É·~·tù6-‚¥+ÖÕ¯X[h–Šžô®LžÓ–r–,[S·lu¡YÁìmû¿õ’Ozê mµ <óCïºóÊ‘Ÿ~vÉÓÏÔ¥’}¸óϾwáàÝ_%™ü“3Ï¿zaÝ6ùÁ¢º&þ•l"ßsüá ~wÅU¿ýÕo—§?µÐBÿ±Z|â½ßúÚÙ;6nßýæ¿ðïªk~wýwmÞ¼¥i度•kâ#w¯é|êÉGeHÝ+9|…½†DÉ̬¤€p`›MþÙÏ~fƒO~ØÜùçŸgY½zõtÈîâ)<ÕüQ#Ÿ  µ÷MÛüB|F}­ Æ6î ¦è HhF––o¢¼:sæL ''O鈒6S)ÅÒ PÎ¥å.K")…@Ãi<5ª:­H d@(Š%Ü4ðRhÑù©7»!C†Ÿ…ç®»î=z4 è\UUE×¾÷½ïŠö/lAh$ˆLiÚÔéTϳ¸×q­9õ(ò|€a9ï¼óØOrÈ!´„nÂñµkÔÎj*¡æÍò+µ§¾ŸT´Ø ^¯þò‡ÚžyÄàîý¶²ömû½åWÛÒƒ—~úýÛ-¼D×¢•4fdßg¹¦üþ—ÿçéükß6ô€ýîùý7·›íŠK?Æ¿¶ûÅÿõaþµ1ó¥Ÿ?“4_ˆ,s–*Xdò^Ìjç¿ÙÜ¡Oœ8qòäÉ¿üå/Áe0P¸óÎ;¡·ª [–àf9ô^å¹d"A4áfýúõÀÄûÞ÷¾[n¹öúï|çÚk¯…{º[ÿío{ýõ×Ës5×3fŒ&źÒCå9<–©LÆ O¨ 3$ä¾ýío?ðÀ]ºtáš]¼ (ÅW<þøã…fkJÑX3t;Çh€ƒzøÔRŽõ•á@©ß 2eÊI'tÙe—½óïdÝb­š1cÆUW]ùu«áˆõîÝ[²¯'RÃc³BDh׈udY=j¤ƒ=ôqK¢üàä6l˜ïBÕ7†‚ë[L®ÁŠb\2=ßÛE)ûPÎ)#r›æI¯ëÃ7ÂE»«Õ©|ç°þôOòÉ'Ÿ~úé²``Pª@)I9ÝïG€gy Œ6 Fèx¹‡HNš4éÊ+¯?~|4þ»ßýîÌ3ÏÂlOGïQ‹~]Q, O³~Ùep@7ï_|ñ)§œrÖYgÝTLt“~­]»–f|èCúüç?Í5×°`ÀôUT#–ƒæÔ ņëŠÞq §û…fg¡’Ÿe†ÌµµµK—.eÄŽ=öØo|ãtêœsÎq05ýðYLQR]]†Žg»J9:0ºñÆ¡ù¾2n²ñ)Nù¼š€M“@d–@_wt»ë¢'–;  hE¸œþíñy¢Iz‘SN{"§J»!_üìˆA €’™ÜµkWjìØ±ç’SAÐmáÂ… Ó›Ù­BX%+ÙÔ%‚F‹þdƒH¾ýíogk/1´m ÿ6)Û{Þcuü¤\%\ê„"m˜S8äWI·¶ˆ©% ×JKàÈ`–Þâ)™ÕBwnïÿ¶¯9¤½i”R[EÎþýû»†ÙÓYš1tª3È{¾)s„ Á,<6µ¡¾¾žþ’ÇÕW%B—³ ösÞr_"-Áz*Ùý}ÕW?’Á"§Ý^kÜ3árùòåŠJiix$eÊðÇE‹obæÌ™÷Üs_A%è»r]‡M3›zCP§±2Õ%óæÍ£(\¤ãæÄ‰/^¬¦—ˆž>õÔS†"ýùÏŸ>43Ú@dOÌRë¾°qPü2}útjÑg¼%[‚ÞîåÚ¶AÔkhhøÔ§>5mÚ4Æá‰'žPsNÃâgîlذþê"*•ŒëÀÊw¿ûÝå^I)mÈ!ì'>ö±Iù5˜tÌçU«VÁ”ÅbãHŠ>Eõg¿´ð†wÓ`7 kÖ¬yòÉ'yäùæ7¿yÜqÇéÞúËñîÝX-.W2ôùóç³îòÖŒPSSÓ©S'Æ-5àloJíeZëœrʈü_ ˆ>DpÐÈáÙ ÐìçWckòŠ+ŒóÄ”Fï¾ûn¶ÃgŸ}ö‡?üaÙ–Þ5#”j¸ŽÙH9”0{öl.ĵù—ü¦Ì×îÝ»gOn8®´¨¥K—ÒÔáÇ—Ó´à•>òøã³—‡ìƒ/ýÌg>sï½÷¶4’ÍsÏ=WvžwBÇ™v’‡ÕHMÚv»ŒS¼lÙ²Ç{Œñ1Æhß¾}¯ºêªñãÇË‚ciq$ÁbJ€wK`í©/W—¤á˜‰ªÅgO Têî}ã7òù‘|¤1bPË#úJv¡‰.â:vì8uêTª½ˆœ*8VÜôóœsιå–[ÒlŸøÄ'~ô£Iàü ±ix×»Þµ7Ï·Ã;lΜ9ü9Ñàô>Íæ]·w2>û쳟ýìgwn¯™” ™ Ø˜P“'OÞYåS,Kþå—_nù9µ[jQqG©+5·ÿn`=2Îq*–õHÙ%_ydèС’SÐ 4ÿ¾ {ôÑGçΫbÃi§¦m³:Œ¡SÒÍãcÇŽå¼dÉ’‹/¾Ø™ÉŸûC=ôÑ~TyDòˆ#އô:º,@.Ö h²ªÄa©‘z,3ÿQGEãY9€<#‡~ò“Ÿ„!BŸÅ\–„‹.ºj¬Š´ÜYµ“0iᓺ \2lذp3¡ªT‡PÚ뉙ѵAÃAƒi» ù½á†Î8ã ÚpÙe—½÷½ïUq›ŽºPµ¶ð$€Jº-ÙÓQ}íÛ*ý|pK>͵?úh82ØÁ’ù§?ý ÐÿÖ·¾µpáBÁ(ˆŒ[mmí¤I“yä%é-‰}·{ÑJP¾ ÃŠæyÑ!ü©ðˆp<¹˜ÄeaŽiIÉä³À>×-ÿ®¾“¸OJ€`ò@f@“œ|53Ÿf¾¢˜JlÄ­…O²ñ¸µØ¤òDá?þñéU€w ¿|4hŒÄŸkûÂW›G£yÔ¯i¯¹¶mtŠÌäôŽl×5Ãr¬ËaáWžõšO²Y)Á‘%àÔèrH9üê Eýض¿]Ém|:¤ªð§Mî_}Ê!Š—Cj!ô{‘Ô¢•lLf‚ùÞs44`óÉ$7â‘Þ-Ü,ë­F@TK¬ÐìÎ;…æ°{á;¸„Æ1ÂßHDˆU`È^ÆMÐ2~É%—€¡Z z\&×ò85K¡HÇT´ äµÇSÏì[´hŽìß!°W_}5$ Ã^¾ººÌJ—“€~£r„ œÙÃ:´4×?W‡…ll)”ËÄó›ß|å+_a…p­Ò^œœ)&Uå¼sÿý÷Ç©& ÉA›ÁÚ§á²#„ݬg %(­±±±©©‰ nrMß¹©+PÈZ‘Z(úoŇT*Pæ%ò—Æò Ùä§ØP»þóŸÿ 4xÍ*èc”¤9KH™å[…Ûjf²Ù@%6 ´Írh@”Cáà¬Úœå‘aœã'‚r¢‘åR‹¸®©WÃ2ó\/í dý.—0ÈiŸeðIšÁÚvÓM7ÑŒr¾O9!U©9é]:n”Ü¡Cµµ€€ü4ýi¤⬠f”¬ÔqðAÛïµU3ì¸é,±È}ãèZ¤,%nüõcfƾÆž2'V@¹ !éCaöj~‘„uJݼóàÈ‘#¬ŠUÉ¡|0ñ%ƒáª:r©P,ûY(¿S§NLã{ï½·®®Ž¿E('¤Oi™ùKŠˆPáp=eúÑ¢¼äàõ|åB/ø‡~ø™gž©7ÑùóçéK_’€Hh”ó¬³Î2ŽjÀª7Âè šzFVº+¶ÁJÃ…µ@º#”*# îó·q>þøã/»ì2MÀ ”i©ÝŠ+Šáõø‰–³l0ì:§öVÓ—šDiÆ"QC|ýúõ¼8Þ/ '¯8ÝQµîl(Ù—xÚ«xÁ ÇFvÉ[;­˜ü‰Q…ÂË^_ËîxÔ¨Qü)RSšOŠ QøÕç5ÉFãkK¬P“ú"S°Âª•Ý4µŸ]L HD )6‚i½%EÛØTU<Î}>!éÑk iÉ‚ô÷õQàv8“/”¹‚lZEgcÄМ¾0nÀ}úÞù5]€ÓDÎ7”¹”S8޳£§žzŠ?hÃbª xÕ××KÍ”“Ô»ÒøXaôСCõY£ÀT­6ÈÒI7›ºÐÔ C(¢•xjWíWôO#*(#FŒ …,³T äQþÊ•+A¢³¤aUE½(¤Ä¿eèHˆà)zú•~û´™*ÀÚ3kÖ¬‹.ºèŒ3θæšk´sÑÝQXa±ºªP:¡4Ùb=Ê /ÉÊÄ­ÚÆ°ç8å”Sø{å)è3cÅJ©«LÐó¹çžSt³fÍm ÷iN\ë$„*À&Gв†ÅH‰€5×SHxQúì‰kD O]–˜x¤o­¾CQ/õ%M®½öZ¶5p´à¤²'f¯ÓR~Ä”–Ë¡œÛLcLùi9ˆ(>’D±øK9´õ€’S¡-%ÓDÁÏÚ…ÑiÒárBJ],t'Nù¨H®GGs`—¢Ò¾(!¡´´ {]¦æá¾…¤øCÄxR,× ‘{ãX¥P 7¥át„kŠQÝÑD*IG)}4ÃSÐ4ÂÚ¾Mn’“¾¸ö…‡árÕyêZ„ãóÔKd‰®ÅìÙ³YêÙ³0QÇŒ£¾„ÊÏ<ó ¨${²/¸….]O0ó™ä6lhd”™ª\ÅM)(Y<¢¢ÚÚÚ0T˜à<Ä@ÆËŧ[mÏnݺÑÙqÇŽ%ŒiÜèÉèÁ§ðê0Û2#…„¯¥t 3Š•hóŒ3î¿ÿ~ðz~ÔQG Áê-€w€&“_ÁM&ÔΛNAÆi­¬ñ=õ=/ºi!íð2D¬‹†"ÔTšüìZô@Ï}ªcy0\€¼›œÃ† ã«’ — Þ_•<ð _6ž†é¬7t‡þ0€bŸ~úiH:CÚ·oß>}úpÁòfK¤lå¾UÛHi•‚eå§À&3·åÌ­¥3@f;w*îÓKšTÂO_ g¯Øf±R)Jù#ÂnKw¤–ÚÖJu-d¶kTw,µrÛ’Ði§¿ˆ½ZŽì=²%í·yóæA9™Ûn‡ÃÍ1ü“•/ÇL]@\—fnºÝ/SSš‘2dHpd©œh”°×뿚Av&jè.2t 4Q JºUÛ uDØˆŠ¢jš>‚C÷K óA¡DV¦}±–¨¦¦p<øµ‚ p“ké__,&0nÕªUÜ‘e8†Ê1TÖÉ¸ìØ½ˆW$Í'× øÎ'¿‚È .†¨6mš½xk1Q¸gz®¢¼Îõ5 wôÈÆ"§gf,¯ŒÅƒ2«««%nÈÜ‘SG©›½râ\.ÓH©@Ðç’-Ú®VL‚Ó;/ðb×QNÛU1(9!xÓi¿™Z‚cø(ÕÒ,ŽìC_-D±Æ9VÁK+j§“¹ÿþ €jT·hÑ"ùNˆÄ &˜*‚QÞMÔzô$'a¤Fµq¹)4…‡M¾Ã œ”Y4¸¯+ä0{ ŒPVÎŒ5™Án·óû5ô”üJcÉ®AW­öÊSúHâ'É¥IMMMúñ¡^š$ j¯¼¹9‰ËéòcG@Cʯ©©4Ã]½˜œ ÍUXT†£N Œô–zµöƒDjîûÒ}¤¡¡!”¸[rZ_.µ( ]Xxµ&r„X Uåg»ÚçëeFý!½I^D›¹b’ŸâðQ‹T^#D|èP0ЄAL×5P@ƒPO<ñ“_›àBsDŒB³3±&X°.á!ýº vÂU€­Ý»wg×0‘™O¨ýˆ#t.îȵS‘…jyAÀCð× šJå-ª åOŽW®"Š„ÔÕB÷C^Ðe½õëˆÃ#5(gÏž=ÙpGa®ÝQ`­ùqãÆÁÜaÙܤL˜2êMzôèÁ'ÙÂR¦P´ðÖ×/S¨Ê9v–_»té2|øððjÄã¼,e>¼}iåX/=–í–„š-¿ˆ?¡ô­Ü;þÞàv9§œv7G.¢”Nf/SZ‡ ÌL@dÔ¨Q1‚£¥|G”/$eZ¦I*ƒëñÐ)‚˜j\Sìà&˜KEúñQ¼à¾°Î(P𬡄¬ÐM÷†  Ÿl«&6pàÀÕ«WƒVúYVXl½A!AðB³Æ[‘c(è ŠÀRrŸU¶ i4u'§š@˜Æ„´G ¯‡cVÊH’‡ùÕ’i$šÞÉ‚I»¢e„ÑAõðD^5¯aJRûÍEÂÑ ­8‰<°K¨‹:ò¸ï1žÓ_š“næLKZªxzÇ¡ÈXΑKò—Ó¢p;µ{D9å´·sä–nª; ÷ë×Ï#2¦ ¸À4 Ö¯_/TyÌÅ'0ÄLV׿>ÝÕÏÊS_š‡…Æ1Ÿ<Î'O…ÔB 0¤`‚ úÈÄ=›ÒÚ¦jÝ«ü„ÌÀÜÔ©S)dìØ±b5j·U)'Gô—îtîÜ™>êèRá¯=U <,?lêùÊ}M±¹®¯¯§:5ÖZQnk(U;\Pˆ–8AÌ©RM-.HtÖ‘wÇ `¢à×dÖå±>ê"ì4ϲB°’QŸQ5°ˆ!V()q޵Jý×^–¯µÜi} µq,ìKI£n·Ä‘Ó“d¯µíÌÎ9sʹPâð¥„ÝHÜTÉ2³&6…Uˆè`<ˆªÛvPŒÊUzS¶ëñ`ʤÒ”h"‡¨ÚDbr­·‰¨¦±œ°(Ú’ÿ°ÃS—Éê[ÃsH€B³¡„‚WýyÒl~­««K5ô€,l±1,C‡¸;­6Ñ“ÉO6Ã\©üÎ9•Üpy]hƒçIg‰â”™µøC{öìIa"Ï%é©yáÂ……D‰›î°íàÅÑõ”õFD÷Õ˜ÖE²[ ÕWÜX»¾‡*bqªåVH”UB›°ä”/½(‘;{ ›8§ŒÈ…–€8î0“õ"BÉUƒT†šX&|xê¥cgµÊX`(`(.€¡ˆd1jÔ(¹-TðL…HUAÀ0$‚îñ»u²Q~„ƒ3Ü‘ðDäÔQ}(YK¥ÃÃg¬}VF¯2‰^á%¡L`μêÉ4ªK›ìÿ,&å-¬|ª ¦1<¨Š¿\Æb“®]"=‚Ëk¸¬ª†ç„…¢^‡âåvöƒ×q&°r‡Ö2†ácÄwij»jÕ*«ì¬:vqdêI&ã¶råÊ9sæ„u»º(åšm©C’” /7§åêñ—æ¯*´d©qN‘[”]ÄVTwbl™A–I“& «ÀФa€âaÏBÛ=OãYZ¢%Á:œ‹*iÜ}}z(|àS&R]ûÄA7PK€ON-àÒlOó"“ æp6[… ¥*&‡â‡î²§Þ4‚é4º¤ºt–_C(Á8èyŽbyAú„Ó~ǽˆ‹Dœs†K?éêADu«V­¢1t™Ñs@Rûš%îŒ(œš¿—ŸÝµÄy+*_fPÎéMÈ媣éúÈ‘#™ŸÚS@ý Îz(¤tBŽéÉŒhÅäj=ú ÷oLõ=ÌógŸ}VË‘B³©EÐ%uÎÒ d¹Ôôò€Ñ£³ €;zÊC-KÓaPjøøÎ*²bÅ …-qV" 2,Y²dÑ¢E*`pt6^”®Üe²4’è/8"“‡gõÈ2Æ.PS¹Xþø“¤a!Íf4xŠgÁYñ@[ž5à4­R/øÀbÒ—…†‘¸ñ¹×®]«MŠãærçío;OMžÁWÊJÌ"¡¹>ÚͯóOž:ú裩+ŽÒ˜{¾j}…SJ%82TšôËA±#FŒ0À­¸v`œGŽÊ4´I·êÚÂé…Ø¥®ªª*Ymcc£Æè@$™YœÈ N1èN…­ —TÊø«JAEå²eËÜ ðjÆŒÔzÒ¬Ófî7ŽgYWl¯ŒW æR/#OïXb‡ Â;bqå¶Çw\ïÞ½ù•Æ,]º´Ð|þ™þy„5¶±èwnÉ´¯%It‰¶\N9½!ÓNˆê¤LöÆo4L§¨“L} ÁgE4cÁùÉÒŒŽ,m„DºÓY#A6lÉ<³’$*·¥(*ÒQ™<Ñóz1‘_}ôQ8£bPË—3†$>id0ä[Ï@g÷îÝA(õÆl›vwfþÍIpßZ'ª°¬'b9¬:Ú¬%ÔbÂÞm ÊÊ &«Ý;Í)*ûD.jÑu#ÂR×èÑ£©ˆ;jq°È5440>rsÆêÔSOeu™5k–ÝT£KG†õƒ6ð6U¯VÞÂWZÎhж~ýú±áàZ£’òºþ—Dliý¤.%—€r¦Ì9½ÙåÈ%I_º½zõb’CN™“:j0ATeš")6}útpÇ]óÀÉ&'7Ãß…qâ‚Y}/²€8äj¦-²újàˆî2@FI(Õ…ËùPó'ÅÔ âÐ<ˆ$­ARq]“{ên_uް¢Ö2[wšª‹yS.›w‘Hƒ:©´äÌb¬È9ÕÐQü 7Ë(iáAÃé’’PððBáL •2Ý2Pݤ‘|’ ÏûZ²dÉœ9s@O®ÁwÇŠ;ð_Y°`k\8É)†}«”‹ã&ÄÈfÕå^êõ©\"EÒÔýtK´·D¹"˜už´9eDÞŽ@ƒxüñÇßvÛm†.5Ò„t*@xëêê|x˜™Ä16uàp ˆèÈé•“_ûÝ"ƒÚ€ˆÂèpþÓÞÚ…cÖ ²Î ìÓY-FŽÝÈ&ŸMq0h?QË9ךšòS&ŸñgUƒhTA é/ʈ©î„NPù6¬-&€¯o߾ޤbw¾ó º3  ,`b–uªXh³Gá1öúÄOÄ´ ¬gAÛàËE D6”)aŸ;w®FÛšAš U)‰Ãˆ6…Ó]rZÓøŽâp¯PéÈ.àµ%wõ%b±B«q©sÊ)K-*.)>üðÃŒiÀ€l~¹VªP*”p‡.ߘ½@•á3€@AeX‚ÔœSA!ܶ"Æó2pŸ@ïÞ½{*½ûî»)çïx‡Ó€9Ѩ%”æžbHƒÁUÄDy5Ààû,p@ž)Pâ¬8à£jåâ#™Ad·©´ÔF[ÄÐr[¿~½†…´‡G(œ¥Ë%„ÇûôéÃ>€MUƒn\sÌ1;w"¹Éø°lÐȉ'rGʼnBÑß4#ÌOäW­jPÎ'ÝTj¬š³Jùj¹Ñx [õmGÀæÁŽiëhDquySĤ…7Mâ&ÒòÓxJcxC­oZ"¿%ôRÛë–ìE³Ô"§ŒÈRì¯Á¾Gy¤P´âSæÈM­ÅÜÚ«<«&V¸D ùõúÐðÕC|Hª5\h_0ÿCs €Óð €ô©ì£´qS1)Iðqåì¸e‘Z"H2<TÅ6¾FuJxáW´¢ºpÖ+á³?¼VŠº½, ð_«ÖÖÖêèNO Œ‰C´ðæNÏž==dÓb[éC¤öžvzÊåyD¡Šï•ØÐ^ ­†è¿P<]Œ8ßÔkT'–@^–ÌWKqwö‘2)Å ¦m|²xÖ%‚‹B .„Z"È%äŠ02"甥- .Ô‘bÆ{ì±ZÙ m5ú”•êª$qt@¡ÿIUâ43cG¯aå«"¨¼±|ùr}kv1vìX 8[¶l™ûež‚0ÐS¦LÑy›ªÁ¶$¼Ôë5M‰°¨¤#ªÖÄ“=­?BãMC>­ò„o3‚c —üªþ_‰ÑB³QŸË˜+™± ÕcƒÏj 7fÌz´dÉÏùÉ8 ´ â”K½}>µ¾iøÎêX(:8v¥áÓ¦M£dÚ_SSÃè¹ ©dz:;V÷™E‹¥Bqõj€n3<â#?cE³!æŠø´Špœ’ßB .,B:ìã©ðISN‘Û*JV1@>Ète/ ’jĬ~.@©âª¤ÏMw8SmAµVÙhÃd ëâ)ܰaÃ(aÆŒ²QµÁ€ Y°``4~üxjT˜*( Ð9餓XÀ¦´¡Ä“£xî“Æ I±¬ÈNž ·RlW…¼Òm•‘cÈ”Š_4 )Ùª‡2?q}çwÄô ¤ƒh3n ø• H]zÿáMÕÉ‹5@'JŒç“O>éR§à•eq¢#¼ˆºº:†ÅJ5HÑ"QKî$BPàŠ*ØÆÓŠÀQZúÁªH«å¢ÖG+ì8…õ©kͰܳ„´%çLsÊR‹í§°i,„W§ïú‰×ŽYbh” ý-ˆ,‚TìëAH®fn)_]4•1¸p¯Ý·o_ fÑ¢E  ¸ ´:ü ƒ™‹PHÐdCeáFTUËX°£Ù”&:膘J=âã0âuyä‘ ÝäÉ“ÉÏúö544°Ei3mÐôƒöhgÁƒr[µ¡ö<¨"OUUUñ+¸)gèôĦ ‡B[®ÉÉMOêtÁÞ5,„¿iE€&\›*‚Û~ÏÕ°?Îá Hʼn¶„ŸNïlNžæ…{èB%Uâ’ã»r!r*þ UEÏpÙ£EN‘·Ä%>áÂ-§ž0ÃǹFžãñ˜µ¯•gHDV!LZêÉ`@ÕJúÙ}ë&ðÕ ±¯Î¯lŽgW¯^MNi—Ž5”œÊd5Þ(MÓg5u„¦Ë% ýû÷‡¶»ÒX ØmjjòÎ}™jS`÷îݹ¿páBWÝg á²_\Ÿ¯ÊT 6˜ˆÈHÃ(ojdÙãqÍý¾ò"a4fÍše¨']j0zãÈ|•À¤ˆžTSDŽw¤¬FyzèºUt?_þ§Òï€1^Fäœ2"·¦ ͪ¸ÿ§9‰\ÿÙœ´»gÝò‡o„@dÀ¨¾¾xRÖ©¬Y},cÓQ…>†ÔÁˆHÉ#/·ê.—QiMM @ ²ëMõn!9å°žP]WLJv˜.,RËo½sœp ZdØk»@ä×_eX`Šç‡zÆÐ/„Ô[y1@IíPZ ^©Î?LÅ‘1x’…ÃséUÔÕÕy¦G]HÅzLjá Õ¹0Øq€ˆã¾ðr•Ô4&6ð7å³­ðâ«mîw L+†€Ê)§ŒÈ;¦S[Œ˜l©Ï0¾ •Úû­\¹þ TÉõ<,,Poœ%ZË …{ÜT€‚©á?zõê›q‹ÒsqcccD=e…k×®7n7§Nb%½{÷†ð®[·®¶¶VDzJÝu«UzSPÉ.ކáÉî„§¨}¡ëzîT9LHÜš‚+7§FàXÝp•#@II Ñl%Äb à¦Ôµ<ŒizªYhCTšœrzs¦}vgeI³ð²K¨„@uÍ£s 0(Ħ:eÓ`Êv IµNÇáÄGŽ‘#Gz §®1õèÑãH®…BÀwþüùðMõó@ÀÁƒƒ˜ÚhDx$þxN-œ»äA©=ä7LÃ=ú#=šFµ¶Ù³g«S,µÐ|V©tÅõÌbµ¹Û‚ ¥Õ½Ð­~–V&^~WCˉªÞøÊÝ•Ðá”/gÇ9å´Ó8ònööžÎ%€O½J’TsNY¡®!üê<èX85N£MûI` ÎÖX ê€ ¢à¯ÑH=RÓM%×F_^µjÌ]Í  Í"ݺuS§Bßl`Ÿ1¢¢/º¼ÐWr¡ÙÕ²zÁerMúi¿ìZœg¦gn±hIÑFõ†å³òèyŽsÊé Ë‘w¦#€[ø* \R&)jY¹rec1…Ãe@ÖÃ@²AŸ#HJ°HqÏ•Y‡Âï²eË4µßá¼” búuë¨1L´=KMàÒó·V6%¾á+%—+W4¸h  Ã^¡Y \~:—±8§œ2"ï4@—oÞ¼ù…^X¿~½¦†ºýUZ-ï®®®+ëëë=× x‚Õªj­lA …èÏ^b®[Y¼ ƒ‚¾ê2ÇUUU1À­¯»Šçom\ŸRgiñ7NçRkºrŒ.÷òÓJ¦œrÊi/EärÎeÌÍr] íƒ÷¬0D4õ‹ôbsÚ´iÓ–-[@ÛP æBËCµªC“/ˆyÈIäÅ©EŠÅžÝ]¥C‡ú š=‚+y°]R…Šúg…J mÏîr »œrÊy¯ ËÊjKN å¶qЍ™ 0­9¢§ˆ!¶.eÄ¡ã¬ô#xn3‚¹û7' X»¾ôŒ®í€Ø’χŠBÿ’¨£åhžu$rÊéMÈ­ìywÀ”vÇi†ÖÆlqN(X‡²]0僷`Á¡"ñ:¼E©…w€œ*ŒnEƒ¸¥W°?ŽL“sÊ)sä½–AšƒX— u*µ($^“"¥<44"Zrø»Ã+M»žjé½·Wf½K5Ž÷¸nON9eDÞc€ÛJÌ‹ÖA¡âîN)wwYxŸÂmד}N9eD~ãSà]„\í…•×È [ 'ú:JoŒ^ä”S»Òá/>õX¶c(œ ÒýøN[÷ÚïgÒƒÄ;öÊC¹6fªH½È¤!§Ì‘ßÈRˆòl%òнJ|¹g³ˆj UrÊ)#òÞ‹¤{!x튖¨ ëènW Ýž„V^\>ÜË)#ò®ÅͽÍ_¿@öú¬Š,9å”Ó\jñZ’þÕÚèÇy÷Ë.vX1n÷ƒ`Aä”S»Ò>yÊÓÄâ–"$½jÝ!ŒÛÍÚx=i”´¤u«ÂœrÊ9§=C~ß [ø–|å”SNojŽÜ5Û=°XRÑžjÆ®&ø%F+%V‹yâå”SÅôfÔÀ¯èP­-^Ö Eó+¯¼R²±h×>£d#ßvEÝ×ÅÀš ÍSwwy–SNYjQ×vІrcåÖ ã›g·Ñvµ¶œrÊéÍΑSÿ>¯†”Stn©_+ßvÛœ†:­¸È,§œÚ•þ+æ­Ø®¯IEND®B`‚openchange-2.0/apidocs/html/mapiproxy/mapistore_logo.png000066400000000000000000000300111223057412600236260ustar00rootroot00000000000000‰PNG  IHDR``â˜w8 IDATxœí}i\×uÞwÞÖ¯÷žžÌ €€ ‚I“"Ë!mG"-F²¨ íRbÙ®ØR©²È;åT¶Š“Tì$NÊQ\±“XŽãRl—b*‘R‘íŠ"ÉVHš¢©Å4‚H˜ÁlÝ=½¾î~ëɾçâÍ`@ÈüÝ*zfÞzνgùÎwn3ã;ãÆ;ýÿ¿ï(àßQÀ;dƪºë¹7qíë}¦Ô €ºgÂÌvÇ›–eýÖç>÷ûÎ+¯œù—™Œƒ¿ûwÿÖÉ·­Ï,|ö³ÿkéÍ7/ñ±c÷¾øôÓï;ÉÌó>àI¹¹Ém²üßéáªÿGÛ~¿àÓÿñ?þæOÕëMþþïÿ ûäɇ¯»vU@E ÿý¿áò«¯žÃ{ßûøÿ|ä‘ïúaß àï3óÌmœY7{õûýãq Ã!ŸÏŸ&¢ðÛ¸nôsLD_ÿÝßýŸœ={þ¡~ðø¾ûŽ˜»)`×(èÌ™s—Ïž=cÇŽ|êÑGþ a3~À$€ðú×n·{ž‡ Ç1Â0Äh4B§Ó¹w4Ý z'Ÿ@àgžùÀr¹Ü‹_úÒsD4µk„·£ˆ¦è…þ„r¹Ü‹O?ýÔÇ€™”™«ÌÓÿ¿ÝÏ7sN†`f†Ó4õ ‚žça4Û~îízΛüüø‡?üô¯u:8¾›¬]~¿°¶¶Î'O>üÓJøU"zLiøv,í3{DË oô|ù—$‰~Ø$IE‚ €išŽmÛ'-Ëú£wÈi§=;;} R)ÀDS/0ׯ±÷»)à išôÞ÷~¯8‡Ô±á.Çßìhîòû2€În'%IRŽãI’h%ˆBÄEQ$aäízÖ·3¾ë®»À$@­í즀Z>Ÿãápô`6ë~Àaµ¼ôçvâ7ñ™Æ·Nfn`l“Îï÷ûF£-³š™EÑ¥¨Ïaú\fFOŠã–eÁu]d2™¯@E3·ø.×ûL&q È y8Ží«Ÿ+D¤ÀÌLD§ãâ·úœ%"ÄqŒ‹/þÅ$IÈ0 X–…R©„B¡À¶mÿofŽˆˆL0ó&Ìì†aˆB¡Û¶aš&LÓÔ³?Š"ŒF#­"²xœ+èç\ZZ‚a:yl·Û(•JOLLü˜Äž¿  u ïËÊàCöÝ@Žãiš§SÇ»{3#`æìåË—Ÿ2 ¹\†a Žct»]03åóù'Çù=Œã}‰,Ðï÷ß/ÂÇkš&ˆI’ “É “É`8Â÷}X–õ˲žMßœ™É¶m­f†çyà=•Jå DdîðÜëÛ~60ŽvÞr8Ž­bíTÌ»*€Ç£ 2×è-Lƒ±p¯ùûöÏ£Ñè/GQÃ0¶8Ô Ðn·%ºyŸiš¿ +çïdò¶?‡23ð}ŽãÀ²¬0ý÷8Ž·8ð$I0Ç1lÛ~ªP(|^]VΫEQôÝÃá0Ç1ˆ™L®ë~^ÉÈ0¸Þû¦eºÓ/wS€®Æ°€èz&(Žc{yyùÃDÛ¶‘Ïç½R©ô?0¶å[–d’$$J!‚K’ù|ù|r¿Ô½†¡¶û² ¶ Ô÷}ÄqŒB¡€l6Ès¶Ûí‡åÞr¼8n"B†à¨d.PïõžV«…ÍÍMÇAµZýÁB¡ð»†a€­"º]Ì‘dî;ke×°mÉD¸Ž :sæÌš¦‰L&ß÷1òqÿH¥Rù^úX™q–µõÖ†a ‚t³å~f€mÛZéHHü€ø(ó†á‰v»}Äqí?ÀqíÀ•RZ;ä+T®§&|ßG«ÕB’$Ï”Ëåß!¢׉¸˜qK&h{ˆr]†¡,y„aˆáp(ŽðÃårùWåØ$I A T*!“ÉÀ¶mˆS¶mƒÁQ!Š"ضÁxy'é0S-8¥0DQ¤‘P”™Ñívf³YýŒ¢€$IÍfáyž\'VÂÔ÷”£ÞQÁó<†×u?œÉd>«&k‹läÇÝd|=ð6}ED¤gä¶p&Š¢-+Ž0ŸÏ£\.’¤ôz½†|>¯£ù[’$p]F£ÑŽã|IJ¬Oʽ ÃÀ`0@†Za•Jý~Ì Ó4†Ã!\W°2"4™ý’AËê1 aÂóÿïåÏår™ ÃMºÌÜÚ.õyGÁ¿•RÆX;aA—.]úp¯×cf†mÛ,a%3£T*É’åF£ñ÷–––$Ã…eYòÚ‰êÊ÷}–—s¥ ý‚ ÃaIÌÇÑÇÉ3ÈŠÓ¥îÅâ7ä‚éDoss“‰èï5›M´Z-qìÚ_ˆrK¥§rõݰ à± m‡ï½þúëOHüŸÍfaY–N²lÛ3£×ëassNGÇðé¤KbzYp"Œ8ŽuB•Æ|ô¦Š1Ãá0m"6K‚ý $Hò&F ¦i¢ÛíÂ÷}Ôëu0³mt ïgY–vö“““7P}»Í&è•W^ù1…‰ˆ¡(ж8Dh·Ûäû>+gÌ «—,™,Ëb×uẮ—ð}_Ñþ,TŽF#ŠãXÏ^¥H’°°×ëÁ²,8ŽCù|ž³Ù¬†¹²É*1¤ ˜ˆÏçu ÃZ­w»]]µS š¬2É]w:Ôëõ¿:55õ_ä·EA·f‚¶-™-&èòåË_¼xñ/)t’€Æʉ9PÎR›¨t¼.‰ŽÊ`Y LÉdØ4M½ì=ÏC†E‘ÆäUè*IœvΦi²@#’`†Á¥RI"3IÂàyKR'×1M“%xP3UðG¹\fõ~Ì F___Êqœ¸R©üço» ÚØØøèÙ³gŸÞ^T˜Á²,LLLh\H"ÐAY3ây|ßG6›E6›ÕK^ÌØ`0ÐX|&“A¡P@.—ÓX¾Ü#Wˆ9á†^¯§£ÁªšÍ&\×ÕuªTëMÚ…ïûèõz(—ËZáÌŒápˆz½þÇqâl6ûkÛe©þ»=&huuõiÓ4©X,2.RY,%I‚÷KâbÛ6™¦ÉAP³Ùdå´Ä9ê8F#V§þ}Ç%mÛLD¨T*P+„ˆˆ‡Ã¡†±“$¡J¥ÂµZ ¥R ­V ­V‹ŠÅ"\×%œÍfaš&Ið QŽçy4Ø4M ‚@ç5b ­¬¬p¡P ÉÉIYÇ1g³Ù§çççå¶$b;™ Ë—/ÿõ –¥º¾¾.Õle®B¤cÏóÐétضm¸®K…BŌض-¥>ÞÜÜÔ)’$¤þ—hHÇ훦ÉÃá‚÷‡C4 ö<¶mÓÊÊ ÇqŒb±È˜˜˜@†,¦Ìu]¶,‹2™ ;Žƒv»­ÍeYlš&ŠÅ¢^UŽã ›ÍŠÒ¸Õja0 ßïs£Ñ@¥Rùh¡Pø@û‚ÛR‹„ƒÁà‡Êå2\×¥8ŽÑn·aY•J%T«U®V«d¦ È6I|D>ŸÇää$ )EFQD­VK°{¡33år9ø¾On&I‚n· Ïóȶmt»]´Z-‰rH|‰¬,µ ‘Íf111A²J=Ï£–E{÷îE>Ÿ'AmÛ(•Jسg®7(²P­Vƒëºð<<ÏÃúú:jµÚ …OꙬó€Û€‰PÅN*\žs¹ªÕª8K ‡CÝDl¾Äßjf¡X,Â÷}†N§#ÑŠ¾¾„’abccF®ë¢Z­" C}ñº¦ÏÛþYây5Ë1uxÙï÷qþüy8ŽÃõz¹\AÀu]  y÷z=‚ `y~¹žïûðG6›EÇ:' Ñ`ABkµâ8¦ápÈý~_;þL&C™L&ù"Žcò}Ÿ»Ý.år9Êd2<aÛ6EQÄ騬Z­’Êh4q¿ß×Å%•S†lY:ét:œ¢FF[e9VåÍ(`Ç ³Å0 –-I^]]Åää$çr9 u;5JôÁ®ë²,t:†R©¤³ 8eâtB'&, C#Ë= CVt ‡Ëì5MS³$z½+Å"›ÍrŠÜ¥‹4R§Îd2òÞ,…%åÄe"°ÊÒ¹T*Á²,½*äyoË Øvx JójÄ^‹³ËåršáJ´ôÏ*ÃÕÅ Çqຮ~héä:)e£\.o ÃÐ=YiHAr~¿¯}¡P€ïû:jJû Q„ä¢\©æ¥óQª@.)3$Q®ªaGdôíå13G’Ù¶Í“““ˆ¢ˆÇá(ŠÈ4M=£äåÄDåóyÚ³gÐ/†¡ä:ö¯V«p]÷ªýQ#mkEX–e‘aœf¼Åq,&B+¸V«Q·Ûe•Бa¬h1ªƒÓÐÉ^6›¥™™î÷û”ÉdXð Á„R¨,`ÅÀ Á`Àâ[Ò&h›oXÛMPLDaµZE­VÓñþÜÜKvkÛ¶.IŠPÙ0«ô š¨fž.°V“ÉdËå8…µË‹èçI…˜º9O®£î§¢2vÎçóº>‘FFåØTVÍ•J…%É’ %AdffIJ7664µ2m‚®N¤·o‚âL&ƒl6«Ã;(#PDúÅèU€¶/g9& Ix–žüiËïÓèhú~‚É5å\Ás¹ÜT5}œ\Cn›æ/É9âR(ª¦Lnƒ-tôê x{&(aæ(UW%™‘DDN‡³Ù,`¡J[½ ì ÂW/MÌ,&„¤> !̯M¡ïû¼¾¾Ž……ŒF# }¤ Uák·Û(—Ë•ã˜?€LÓä(Šˆ™y}}o¾ù&ŠÅ"ˆ…BÊå2g³Y.33©!E› ·‚%nÆi¡« ³JHðùÏž_}õUT«U¾÷Þ{±oß>ìÛ·OÏHf– ‡aˆ+W®P¿ßç\.×u¹Ùl¢V«Aðõ" ÅÒN?×… ðÕ¯~§OŸFµZÅþàò·¾õ-üøÿ¸NƼ •ÆcÀŒŸ}öYaÝñìì,&''qôèQv‡^H½|ßç—^z Ÿýìg‘ÏçÑï÷ñÁ~GŽáL&ƒÙÙYN­mÎèjŸÁ­›  ™1`fj·Ûp]­V‹^~ùe=z”<ÏÃg>ó<óÌ3˜œœ'HDß÷I°š/}éKøßø š™™!˲pøðaüÀüÍÏÏ ~¤M›º`Û6A€óçÏã¹çžÃüÈÀ0 ú…_øLMMáÉ'ŸßCårSSSRŸ&f¦~¿?üÃ?ă>Hù|¿ù›¿‰G}”ŠÅ¢ ¬´wï^d2Ra/µZ-4›M<üðÃ8qâ>ýéOc}}4 333P<¦ôlÛyÀö¡[†ÄVnllˆ}äf³‰ƒ¢Ñh`mmMSÄå¡‚ ÀÆÆ‹EÔëu,//ã™gžÁ{Þó|îsŸÃòò2Ö××ÑívqôèQ]ßefôû}ôû} ó›ßÄ»ßýnÜwß}€Ç{ /¿ü2<ÏC¯×0f`‹Eض­ÃÏF£N§ƒ÷¿ÿý ¸|ù².ÜKР`tº‰pF¥-Öu]”ËeضÑhÄËˢœœÔжȈÇ$ß»õ o7A %R Ã=ÏSÇmíúúºN”J¥RÚyq¯×ãN§ƒn·‹Ñh„F£l6‹ápȵZ …B®ë2©¯˜,‰é{™Ã0ŠŠ…kµLÓD¡Pª 7›MaDhxÂó<$I½^O#¡¹\Ž%±¡<€l6‹ÍÍM¬­­¡Ýn#›Íò¾}û V‹Da,Z™ „Æ´õDdôvMP‚«á àB¡À†aPÇtôèQ>}ú4åóy B¬gKÃáa±¹—––pìØ1êõzEJ¥¥z¾*ã”$*Š"²m›§¦¦ðæ›ob4¡R©ÐÊÊ 'I‚jµŠápÇq4¼Š’¨\.s>Ÿ§_|‘<È+++8|ø0MMMq±XÔ”sÃ0H|Ï=÷ ×ëáÌ™3RСééi䦭äÀ©Hꆣ ë픤Œ“1 /8Ž#&Ÿ8q³³³<Q*•tÄ ²fv¥RI× î»ï>Ôëu¼üòË|ùòe©@ñຮŽÏeªæ‚ï~÷»±¹¹‰¯|å+øÊW¾Â/^DEp]ûöíà]!S!#‹E|èCÂÊÊ Ÿ;wN2].‹˜EµZ…‚XÑ^¸×ë¡ÙlBÐÞ……LMM±ªØq¥Rْäü@ŒqàoO(·íÐCÌL.—C³ÙÄp8Äg?ûYd2T«UìÝ»Â4“)ò,˃>ˆB¡€~¿–”#œ«™ ™L£ÑH×xà \ºt £Ñ‡«¯¾ª•%þCL‹øÏó°°°€b±ˆV«…={ö`ffFÃ"…BAûÉkÚí6^zé%<÷ÜsØ»w/žxâ ìÙ³G7t …4,Ÿ™wœÒ7£€í&À8¡¡q5Œr¹œ8Uj6›¼ººJ<òqâ„F_£(¢\.—)‘$ :uŠŸ}öYT*:pà:tÇ'"b¡Ì LŲZ­òñãÇå=¤†LI’°ëº$` Óvä­&b;-TÖÇ*)á}ûöá'ò'±²²Â£Ñ—.]BE˜•L˜™ÇO¯×ÃÊÊ Îž=‹³gÏâÞ{ïå'žxÇŽ3s»ÝÖ÷–U  ]£Ñà^¯‡ßú­ßÂéÓ§qèÐ!ÌÏÏóñãÇñä“Oê½Á`À4ER%†\©TP.—±´´Ä¥R 'OžD.—ãN§£ÉWÂ⇜$ …Ž= ñN+++¼¾¾Ž£G² ¶Ó8ßRŽ7¢€M„g‚A@Žã`ß¾}X\\„ïûX]]Åêê*²ÙlÚ iššàúÔSOá®»îB½^Çùóç155`lB ͘–¨JšãðÆoàÌ™38xð ¾ïû¾¥RI·*‰ÂÒ-KaâðáÃø‰Ÿø ¬­­¡ÕjáüùóÃwÜq‡®ÎI”7I²uªÅÉ/--áôéÓX[[Ç>ô!©uèûoWWÀÍcAר ^¯#T«U* ¬­Â6¦B¡À (•Jš!Ñ@xä‘GðÐCih½^Ç«¯¾Jsss<;;‹(Š(IV ¢ºãŽ;Øu]>|ËËËxã7è·û·ùøæçç¡x©E‘dÂ"XÊd2¼¸¸ˆ»îº‹Â0äV«…••úÓ?ýSžŸŸÇÝwß Eæ¢ápÈžçQ»ÝfÈçóšL–$ íß¿Ÿƒ  ••¶, —.]¢f³)$ƒÝDzÓXÐ5¿S0Tõ—/_Æ`0@>ŸÇÔÔ’$ÁÆÆ|ßÇ]wÝ¥±s‰R­BRfD©T‚mÛxùå—ñ¹Ï}?öc?†»ï¾[ßOΤtqq‡0öI8uê®\¹‚……Üyçš*IX¼“`rrR×sŸ}öY<òÈ#xßûÞ¢1erii W®\çy˜ÅÄÄ666tuLVs§ÓÁp8Än¿e,h'Û5Y ê£ÑˆWVVtXÁ½ºÚT¯×EÊå2Êå2»®‹Á`ÀÌc®„§qs­VÃSO=…Çœ¥UÕ¶mKÊœqkÆœl7°gÏ>räN:…/~ñ‹xíµ×ðä“O²ÊXÉqn·Û‡:±R½ð}‹‹‹|÷ÝwSÜjµ@D¸p᫦–ÜDr åèyjj ý~Ÿ/\¸ 0aÔ]#KéÍ(€°3§‘†Ã! …Õ$El%YöB„UY,õz=†AçÎÓ½¹“““”ÍfI)†Ã!1³Ì,*•JÂ’#åL) %§“¦ééi]'¾pá:u ïz×»ÀÌh4tá€^¯‡……², ëëëèõzš*333C¹\žçÑ`0ÀÄÄ­¬¬hæµeYh·ÛhµZä8F£ -^5ŠléAÞ&KÜÒ^Û)œO©8 3`|yâN§#½Wzé v]¬xDÆ4Rx‘hIâþf³ÉÍfÙlÅbq£Õj±#—Ë¡P(@BHéK¶m÷Ýw+I’`uu£ÑHaº<55…B¡ÀªNŒZ­†Á`€+W®p¯×ÓõjRL a|‹EÞ³g¦¦¦8—Ë!Š"´Z-N—:ÓC î]ä|Ý.Ék~)Å¢@ÆRGÎÔ„±&ìiæ«[IÝXv8QtŒF£-<œÑh„z½Ž¥¥%––ËeÌÏσ™±±±ÏóÒ „‚? ¦ OUzƒE°aJ?›@ízEKŽ!¼'Õú„J¥Â¶m“Ð'åÚÛe)ª¸ì%ª§6Õ’JŠžÁ†ah;j¦¦¦„™@ª«…‚ ` U-<ÏÓµÚR©Äý~?G ÄIDAT£ÑˆªÕ* ·HtdY–ÀRì§Z­Æ™LF'‰ÒÓï÷Ñh44~†¡`YÔï÷YA499ÉÓÓÓ(—˹Q§ÓA&“щ¡`R ™¥z½Îžç‘ŽãmÛ¼ƒýß,3ލFo×{Æ¢¢HW¶Ät†Á‚½H:¯˜hR)ÒÉÝ÷åû>\×E6›åZ­Û¶!è©(J§ Q4¦¹)À®ßïKë†l6«7Ú6¨(Šàû>c’Íf9]bU«““$A¿ßg©ì),K`v]³³³,æ)ŽcM“ß¾®—¤í¨€ë Ó›&‰™˜˜@±XD¹\Ö LT± ¶PÈå…ÅÈòG&¡˜K±_:Û…–ÉdP©T099©[X}߇(Rðz9·ÝnÃ÷} eÏÍÍáðáÃ[Ú‘Äd–J%LMM!ŸÏëSDÃáP÷±]gÜŒ«p[§<Ȇ( ä8§ ;Ž£i!A@®ë²ïû:eO=,AÀª?€Úí6ÏÌÌ X,’ëº[–´Šx´I˜Yš/$§¨T*ú\I „e­ž$œefò}ŸmÛÖff4IM™â8fß÷Ñh4t›S³Ù$fæ|>O‹‹‹¬Z°ˆ™u—çοI°Óžçá7ÞÐ…‰ëÇÁùóçybb›››ð}_£œŠi¦é'€î €mÛ¬8žËÅ"Kçäö{†ÁÒÿ•Ú’†ƒ Ðû ¸R© X,êž0©9är9ž˜˜3£R©@„/80ÎuÂ0d¸éÖZQñ`0`[°‹·› ¾ÕNyÚÁ |8R§ÓaÏóH ¹\ŽÊå2×j5DQ„µµ5¨—&"ÒTæq‹’j  Ïó8ضMù|—/_F§Ó!ÏóxzzZC¾¬ˆ[)îz½mnn²l)£¸ütèÐ!–Ù¯ú¨ßï³eY411!¼VäóyÊårœö5ŠÎHÂzHwú¨•F¬ð'êv»h4š ¶{°óØALí¨/ 1÷ïß¹¹9œ={VŠØ,öU0õååeôz=!Û‚™)Š"é€Ñø¾8m`œ(‰ãç'«F§¸˜h4`f]ü\•7!›i¤9;¾ïKYajlK’¸ééit»]jµZBÞÕ@œÔ%„ZY*•H6ýHw‰nWÀÕXæ†Mðh®=Áu]N’ëëëèt:,±ïÔÔïÝ»kkküæ›o‚ˆÐl6ñæ›o¢×ëáÎ;ïäV«ß÷õvçÏŸçZ­"âååe´Ûmd2VµVé¢'1=êeØ0 H§‹mÛè÷û,ÁŽãH7%1³˜–hiffFSé•§V«ÅF/^„çyì8Z­–{[­–––Ðl61==Ísssèv»:T¨cûPrܱ¾²‹”v0A“““4==Á`@’¸t:ZZZÂp8$Çq°¹¹©÷ßñ}çΣV«¥;S$ú)—ËT©T¨R©@•"É4M¼ôÒKèõz$6Ù·Á Y ÌŒ|>yŽtÝ@Õ¢IÈ»žça0P6›%iœ¤‰‰ ”J%†A «‚mÛ´¹¹ ×uéÔ©SRtB«ÕÂóÏ?@1imm ËËË$þ(’<äZÀÿn7ï¢VyÀÖø5 ÃýSSSØ·oúý>/--Añùyssõzï¸ã)ùþxÏ×J¥ÂФÅNÅb1½Lõ6“;Žƒååe&²d­qk{Üï÷Ñl6aÛ6Ën’†ÁÂI’&qY9ŠÙÇ) «@3³e»©{û¾fÖø–çyœÉdP,yeeE:it‹®<£Œ……£? Ð?ºi´ýpÛ¶/IÄb*• ÇáÁ`@–ea4!ÝQ¨¸ö²‰=5òù<”ùàGªKÓC¤é¢T*é˜_¨îÍf£Ñsssh6›zÕICø¡ÃË&O333˜œœÔ×ït:¨T*˜ŸŸ‡ëº‚½^™L†£(Òýk*’]R>ŒG£ù¾b±ˆR©×uEÑ_¶ô¦±Â¡¥ ;™ RB$fþ7Dô3ò‡Z­†r¹ŒsçΑïû†!©æ;ffÚØØ“ãÕrÌår‡tñâE «Ü@²R Ã766Ç1‹EVŽ‘ºÝ.A€™™iU¥$IXV…Â’hzzškµšî¶,‹¢(âN§£¹l6K­V‹Õ6c²êõ:­¯¯óÊÊŠN‰ˆ”ó&ñsâ䕦N§Ã¦i’`U¶mÓ¡C‡xÏž=⌟ÝA®;ŽL„R¹ý/…Báä¡C‡þ[½^_èv»ØÜÜ„ µõ—Œjµ* 7 $I¢Ôõõu¬¯¯cÏž=œÏçe¿–FÁÖ … …‚ðYB^Yê®ër.—CǨT*ÒÀÍD„n·«!q©=¬¬¬`mm÷ï߯©ó2ë“$A³Ù„aEêõ:×ëuí³ Õùiš¦4ç±°®çççùðáØý¥r¹¬',Q––^ùW{÷ïß’ JÏ~p]÷Å™™™“wß}÷ ƒÁ`AöÌ;)•«t÷Éüü<Ä9K•ʲ,lnnjÈ@ ¡ƒ ¦T.—µIIoºZ.—5ZÌÂ-çª]W4ò*çA wÈè\L¨çy(—Ëz’ýFî#¸Ôœ³Ù,æææpÏ=÷àÈ‘#¿tàÀŸÙ.K˲>àn& Ú­˜œœ\>tèÐIÃ0^˜˜˜˜_]]%µô¦™LF³‰U¡=EÇö‚ψmU˜ÆõèrŸØ›4×s4aii ÅbÓÓÓØ»w¯6t»©ôz%ªÕTQ+Ñï÷ÅQ€ø¶m›8€ééiDQ´%GQÛ"£T*ñìì,íÝ»ü™k„…-%ÉU@Œëlø:33³ì8ÎÉéééZ­ÖÂææ&Z­–¦÷Ig‰P9ÔÖd:<0N¾d©]155%_GÙi“n;Î;‡0 51V¶L^^^† ‰õ.X²?]½^O7ü_>ꉙQ=ËtÇwàÀââ¢ÞKH BBs]—Ô¿´³¤XÉS¾pî† ÍÒ×O¡«ÕêrµZÝ·ÛßWVVN4›Í^yåzíµ×˜™uŸ–w-Ë¢$Iôþ¾ï³tÝ×j5–mÕ¤MÙl–‡Ã!¾ñoÀ²,?~œZ­ þÄÌP1?¯¯¯ëN,Ë"µ&LÓ¤(Šd+M®’€æææøÈ‘#tÏ=÷ð»~sƒpÞYœ»%bÉhä_¿œÿcÏž=ÈçóÅqüòp8ä3gÎh? ZS—&777¡šíØó<Ú·oOOOCjEe2n·Û( Úß„aÈ333zÆ+J:¯¬¬ ÝnóÜÜ%I‚3gÎðÆÆ†Ò˜YèŽlš&K]»P(`vv–ï½÷^>~ü8æççÿq¹\þgoC Ôï{"Ç÷”Û- êw:]´ÛS©Üšö-Ëz1ŸÏ;‹‹‹ûǹ455…K—.éݳ:Iô!õZÙ£Ñh€l¬AÒü–ÏçÇo¥2Îv»~¿¯ãrÙ“T:šÍ¦6?‚éHö @¶! ¹wµZÅþýû—÷ïßÿ=‹‹‹—nå½ÓãOþä‹Åõõ:06AÝåtí¯êÃáVVÖþö­*,Ë òù|¼ÿþý•JeéСC,ˆª*RÇì8ŠÅ" ­Ýó !Wáödš¦iÕžÐtß}÷ñwÞI®ëRBQ¡b±È®ëJ_ñr¹\>V­VÛ·úÎéñðÃïþú¯’D5v”Ñ¿co2ƒ¿þõWpäÈ]oë!LÓ\UŽŠææænèœ×_ýÄ©S§^xýõ׌#¤••í?Ô G,ÍbJ-A²×(ŠpèÐ!>vìŽ9òKû÷ï¿å u3ƒ¨F/¼ðû'ÿ÷¿Kv:n'h8°çÏ¿³gÏ?z÷Ýwþñí~À rŽãìøP³³³A˽^oáüùó:ldÕîŒÍPš¶.¸~N^\\ÄñãÇqøðáùýû÷¯Þî÷¸Î0/\¸ø/G£^Úé;Ä€4˜1@Ñ»Þõ ÀüÁ—·ß÷®=õíÝ„¹\î³³³?tüøq9rSSS(‹$t¡Á  »2A@ÌŒ™™?~>ú(î¿ÿþýüsþÙ³ç‹_ûÚÿ~áÏþìÌË‹ûðùÝŽÝñË<‰jΕ+§žûÖ·þì¡?ú£?Æ¡C®¼ÿýïýᙙ龾}t»Ý¤Ñh`uuÍfN­V õzý~_7u§÷øTsÏž=XXXÀÜÜܾ}ûö-ÿy=3QÍ~þùß{þþàË™¦‰|ä>xð!‹¹±sÿÀnäQ¢Zñµ×¾ö_OŸ>ûþçŸ ù|=vreqñŽ8ðàs»-©|õÛ™®wÌ ÅJx±Óé,(´u¡Ûí¾ ™w:Û$Rªv*,ݧ îo›ˆ¦€ ÀùÌg~í]ívç_¿öÚë‹<óÌP©”›ŸŸý¿»ž•þÚ_û+ ?üÃO¿òüó_C·;Þ1pqq?-,Ìr¡_ýæ7ÿìo|üãçëésõWñÁG}èWLÓœ%ÒÿTzÇñê—¿üÜOüôOÿ£Ó;ÝûßþÛ~ôñÇO~Ê4ÍYfƧ>õ_O|á _l¼þúÅ›úzÂO|⣳ýèG^ÜÜlÿúc}àŸÞ̹o1¿ç±cG~us³=wñâe^Zº‚0ŒpÇ{ñÄßK««w>þøw_¸Þ…®û…ÎJ»¹}ìG÷~â;sæÌk8}ú,Úí.ÝÇ%‚•TO:Ü1Bãõ˜%F ºzŒª é®xÒ[ 0 ƒôuÇJ¼Úì$›Ë>ã몯ƒ×÷¸zíñy©JŸ0Õgp•@vuâè3ÒÏ|Íóš¦Éss3xðÁc¸ë®ƒ/ÿ§ÿôéïû¹ŸûÙ~’$Ža»~¿ÀupU5€ Pþ—ù_{ä‘Ñó÷{Þ@ƒM©™Ž´¨Æ"b¾*º«û?% Ëw–é:ôU¥ ˜E[®Ÿ¾¶`,rÏŸƒ(Iâ-ûP\}èûhIk±o½ÎUÅ€•²0>óË¿ü©òÕ¯þqÀàsㆿuð†pÍI4e|ò“?oÿÔOýýî¿•ñÆ__€ÅÅïZÞÜ<¢Ýî./.~×Û²çÿá?ükçãÿ;·ãke0€äV}â-)à;ãö]µ¿3þ|Æwðï(àÿ 4À.<ˆÎ†IEND®B`‚openchange-2.0/apidocs/html/mapiproxy/middle_bg.jpg000066400000000000000000000005251223057412600225140ustar00rootroot00000000000000ÿØÿàJFIFddÿìDuckydÿîAdobedÀÿÛ„ÿÀdÿÄU Q¡Ña‘ÿÚ ?ßÀ#¿ªÚ0 ïæ¶œ ‡3Yû žñݲ ?ÿÙopenchange-2.0/apidocs/html/mapiproxy/mpm__cache_8c.html000066400000000000000000001260661223057412600234500ustar00rootroot00000000000000 MAPIProxy 2.0 API Documentation
mpm_cache.c File Reference

Cache messages and attachments so we can reduce WAN traffic. More...

#include "libmapi/libmapi.h"
#include "libmapi/libmapi_private.h"
#include "mapiproxy/dcesrv_mapiproxy.h"
#include "mapiproxy/libmapiproxy/libmapiproxy.h"
#include "mapiproxy/modules/mpm_cache.h"

Functions

static NTSTATUS cache_dispatch (struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx, void *r, struct mapiproxy *mapiproxy)
static void cache_dump_stream_stat (struct mpm_stream *stream)
static NTSTATUS cache_exec_sync_cmd (struct mpm_stream *stream)
static uint32_t cache_find_call_request_index (uint8_t opnum, struct EcDoRpc_MAPI_REQ *mapi_req)
static NTSTATUS cache_init (struct dcesrv_context *dce_ctx)
static NTSTATUS cache_pull (struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx, void *r)
static NTSTATUS cache_pull_OpenAttach (struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx, struct EcDoRpc_MAPI_REQ mapi_req, struct EcDoRpc *EcDoRpc)
static NTSTATUS cache_pull_OpenMessage (struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx, struct OpenMessage_req request)
static NTSTATUS cache_pull_OpenStream (struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx, struct EcDoRpc_MAPI_REQ mapi_req, struct EcDoRpc *EcDoRpc)
static NTSTATUS cache_pull_Release (struct dcesrv_call_state *dce_call, struct EcDoRpc *EcDoRpc, uint32_t handle_idx)
static NTSTATUS cache_push (struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx, void *r)
static NTSTATUS cache_push_OpenAttach (struct dcesrv_call_state *dce_call, struct EcDoRpc_MAPI_REQ mapi_req, struct EcDoRpc_MAPI_REPL mapi_repl, struct EcDoRpc *EcDoRpc)
static NTSTATUS cache_push_OpenMessage (struct dcesrv_call_state *dce_call, struct EcDoRpc_MAPI_REQ mapi_req, struct EcDoRpc_MAPI_REPL mapi_repl, struct EcDoRpc *EcDoRpc)
static NTSTATUS cache_push_OpenStream (struct dcesrv_call_state *dce_call, struct EcDoRpc_MAPI_REQ mapi_req, struct EcDoRpc_MAPI_REPL mapi_repl, struct EcDoRpc *EcDoRpc)
static NTSTATUS cache_push_ReadStream (struct dcesrv_call_state *dce_call, struct EcDoRpc_MAPI_REQ mapi_req, struct EcDoRpc_MAPI_REPL mapi_repl, struct EcDoRpc *EcDoRpc)
NTSTATUS samba_init_module (void)

Detailed Description

Cache messages and attachments so we can reduce WAN traffic.

Function Documentation

static NTSTATUS cache_dispatch ( struct dcesrv_call_state *  dce_call,
TALLOC_CTX *  mem_ctx,
void *  r,
struct mapiproxy *  mapiproxy 
)
static

Dispatch function.

This function avoids calling dcerpc_ndr_request - understand forwarding client request to remove server - when the client is reading a message/attachment stream available in the cache.

This function can also be used to loop over dcerpc_ndr_request and perform a read-ahead operation.

Parameters
dce_callthe session context
mem_ctxthe memory context
rpointer on EcDoRpc operation
mapiproxypointer to a mapiproxy structure controlling mapiproxy behavior.
Returns
NT_STATUS_OK

References cache_dump_stream_stat(), mpm_cache_stream_read(), mpm_cache_stream_reset(), mpm_cache_stream_write(), and mpm_session_cmp().

Referenced by samba_init_module().

static void cache_dump_stream_stat ( struct mpm_stream stream)
static

Dump time statistic between OpenStream and Release

This function monitors the effective time required to open, read and close a stream.

Parameters
streamthe mpm_stream entry

Referenced by cache_dispatch(), and cache_push_ReadStream().

static NTSTATUS cache_exec_sync_cmd ( struct mpm_stream stream)
static
  1. close the existing FILE *
  2. build complete file path
  3. replace FILE arguments with complete file path
  4. call execve
  5. stat the sync'd file
  6. open the stream again
  7. mark the file as cached
Parameters
streampointer on the mpm_stream entry

References mpm_cache_stream_close(), and mpm_cache_stream_open().

Referenced by cache_push_ReadStream().

static uint32_t cache_find_call_request_index ( uint8_t  opnum,
struct EcDoRpc_MAPI_REQ *  mapi_req 
)
static

Find the position of the given MAPI call in a serialized MAPI request.

If the request includes a Release call, then request and replies indexes for other calls will mismatch.

Parameters
opnumThe MAPI opnum to seek
mapi_reqPointer to the MAPI request calls array
Returns
On success, returns the call position, otherwise -1.

Referenced by cache_push().

static NTSTATUS cache_init ( struct dcesrv_context *  dce_ctx)
static

Initialize the cache module and retrieve configuration from smb.conf

Possible smb.conf parameters: mpm_cache:database

Parameters
dce_ctxthe session context
Returns
NT_STATUS_OK on success otherwise NT_STATUS_INVALID_PARAMETER, NT_STATUS_NO_MEMORY

References mpm_cache_ldb_createdb().

Referenced by samba_init_module().

static NTSTATUS cache_pull ( struct dcesrv_call_state *  dce_call,
TALLOC_CTX *  mem_ctx,
void *  r 
)
static

Analyze EcDoRpc MAPI requests

This function loops over EcDoRpc MAPI calls and search for the opnums required by the cache module to monitor Stream traffic properly.

Parameters
dce_callthe session context
mem_ctxthe memory context
rgeneric pointer on EcDoRpc operation
Returns
NT_STATUS_OK

References cache_pull_OpenAttach(), cache_pull_OpenMessage(), cache_pull_OpenStream(), and cache_pull_Release().

Referenced by samba_init_module().

static NTSTATUS cache_pull_OpenAttach ( struct dcesrv_call_state *  dce_call,
TALLOC_CTX *  mem_ctx,
struct EcDoRpc_MAPI_REQ  mapi_req,
struct EcDoRpc *  EcDoRpc 
)
static

Monitor OpenAttach requests and register an attachment in the mpm_messages list.

This is the first step for attachment registration. This function first ensures the attachment is not already registered, otherwise delete it. It next creates the attachment entry in the global mpm_message structure.

Parameters
dce_callpointer to the session context
mem_ctxthe memory context
mapi_reqreference to the OpenAttach EcDoRpc_MAPI_REQ entry
EcDoRpcpointer to the EcDoRpc operation
Returns
NT_STATUS_OK on success, otherwise NT_STATUS_NO_MEMORY

References mpm_session_cmp(), and mpm_session_init().

Referenced by cache_pull().

static NTSTATUS cache_pull_OpenMessage ( struct dcesrv_call_state *  dce_call,
TALLOC_CTX *  mem_ctx,
struct OpenMessage_req  request 
)
static

Monitor OpenMessage requests and register a message in the mpm_messages list.

This is the first step for message registration: set Folder ID and Message ID set the handle to 0xFFFFFFFF Insert the message to the list

Parameters
dce_callpointer to the session context
mem_ctxthe memory context
requestreference to the OpenMessage request
Returns
NT_STATUS_OK on success

References mpm_session_cmp(), and mpm_session_init().

Referenced by cache_pull().

static NTSTATUS cache_pull_OpenStream ( struct dcesrv_call_state *  dce_call,
TALLOC_CTX *  mem_ctx,
struct EcDoRpc_MAPI_REQ  mapi_req,
struct EcDoRpc *  EcDoRpc 
)
static

Monitor OpenStream requests and register a stream in the mpm_streams list.

We are only interested in monitoring streams related to attachments or messages. This is the first step for stream registration:

Look whether this stream inherits from a message or attachment Fill the stream element according to previous statement Add it to the mpm_stream list

Parameters
dce_callpointer to the session context
mem_ctxthe memory context
mapi_reqreference to the OpenStream MAPI request
EcDoRpcpointer to the current EcDoRpc operation
Returns
NT_STATUS_OK on success, otherwise NT_STATUS_NO_MEMORY

References mpm_session_cmp(), and mpm_session_init().

Referenced by cache_pull().

static NTSTATUS cache_pull_Release ( struct dcesrv_call_state *  dce_call,
struct EcDoRpc *  EcDoRpc,
uint32_t  handle_idx 
)
static

Track down Release calls and update the mpm_cache global list - removing associated entries.

This function recursively remove child entries whenever necessary.

Parameters
dce_callpointer to the session context
EcDoRpcpointer to the EcDoRpc operation
handle_idxthe handle to track down
Returns
NT_STATUS_OK

References mpm_cache_stream_close(), mpm_session_cmp(), and mpm_session_release().

Referenced by cache_pull().

static NTSTATUS cache_push ( struct dcesrv_call_state *  dce_call,
TALLOC_CTX *  mem_ctx,
void *  r 
)
static

Analyze EcDoRpc MAPI responses

This function loops over EcDoRpc MAPI calls and search for the opnums required by the cache module to monitor Stream traffic properly.

Parameters
dce_callpointer to the session context
mem_ctxthe memory context
rgeneric pointer on EcDoRpc operation
Returns
NT_STATUS_OK

References cache_find_call_request_index(), cache_push_OpenAttach(), cache_push_OpenMessage(), cache_push_OpenStream(), and cache_push_ReadStream().

Referenced by samba_init_module().

static NTSTATUS cache_push_OpenAttach ( struct dcesrv_call_state *  dce_call,
struct EcDoRpc_MAPI_REQ  mapi_req,
struct EcDoRpc_MAPI_REPL  mapi_repl,
struct EcDoRpc *  EcDoRpc 
)
static

Monitor OpenAttach replies and store OpenAttach MAPI handle.

This is the second step for attachment registration:

Seek for a given parent_handle/attachmentID in the mpm_attachments list.

if a match is found (expected) and MAPI retval is set to MAPI_E_SUCCESS, update the handle parameter for the element and commit this attachment in the tdb store.

If retval is different from MAPI_E_SUCCESS, then delete the element.

Parameters
dce_callpointer to the session context
mapi_reqreference to the OpenAttach request entry
mapi_replreference to the OpenAttach MAPI response entry
EcDoRpcpointer to the current EcDoRpc operation
Returns
NT_STATUS_OK

References mpm_cache_ldb_add_attachment(), and mpm_session_cmp().

Referenced by cache_push().

static NTSTATUS cache_push_OpenMessage ( struct dcesrv_call_state *  dce_call,
struct EcDoRpc_MAPI_REQ  mapi_req,
struct EcDoRpc_MAPI_REPL  mapi_repl,
struct EcDoRpc *  EcDoRpc 
)
static

Monitor OpenMessage replies and store OpenMessage MAPI handle.

This is the second step for message registration:

Seek for a given FolderId/MessageId in the mpm_message list

If a match is found (expected) and MAPI retval is set to MAPI_E_SUCCESS, update the handle field for the element and commit this message in the tdb store.

If retval is different from MAPI_E_SUCCESS, then delete the record

Parameters
dce_callpointer to the session context
mapi_reqreference to the OpenMessage MAPI request entry
mapi_replreference to the OpenMessage MAPI response entry
EcDoRpcpointer to the current EcDoRpc operation
Returns
NT_STATUS_OK

References mpm_cache_ldb_add_message(), and mpm_session_cmp().

Referenced by cache_push().

static NTSTATUS cache_push_OpenStream ( struct dcesrv_call_state *  dce_call,
struct EcDoRpc_MAPI_REQ  mapi_req,
struct EcDoRpc_MAPI_REPL  mapi_repl,
struct EcDoRpc *  EcDoRpc 
)
static

Monitor OpenStream replies and store the OpenStream MAPI handle.

This is the second step for stream registration:

Seek the parent_handle/PropertyTag couple in the mpm_streams list.

If a match is found (expected) and MAPI retval is set to MAPI_E_SUCCESS, update the handle field and StreamSize parameters for the element and commit this stream in the tdb store.

If retval is different from MAPI_E_SUCCESS, then delete the element.

Parameters
dce_callpointer to the session context
mapi_reqreference to the OpenStream MAPI request entry
mapi_replreference to the OpenStream MAPI response entry
EcDoRpcpointer to the current EcDoRpc operation
Returns
NT_STATUS_OK

References mpm_cache_ldb_add_stream(), and mpm_session_cmp().

Referenced by cache_push().

static NTSTATUS cache_push_ReadStream ( struct dcesrv_call_state *  dce_call,
struct EcDoRpc_MAPI_REQ  mapi_req,
struct EcDoRpc_MAPI_REPL  mapi_repl,
struct EcDoRpc *  EcDoRpc 
)
static

Monitor ReadStream replies.

This function writes ReadStream data received from remote server and associated to messages or attachments to the opened associated file. This function only writes data if the file is not already cached, otherwise it just returns.

Parameters
dce_callpointer to the session context
mapi_reqreference to the ReadStream MAPI request
mapi_replreference to the ReadStream MAPI reply
EcDoRpcpointer to the current EcDoRpc operation
Returns
NT_STATUS_OK
See Also
cache_dispatch

References cache_dump_stream_stat(), cache_exec_sync_cmd(), mpm_cache_stream_write(), and mpm_session_cmp().

Referenced by cache_push().

NTSTATUS samba_init_module ( void  )

Entry point for the cache mapiproxy module

Returns
NT_STATUS_OK on success, otherwise NTSTATUS error

References cache_dispatch(), cache_init(), cache_pull(), and cache_push().


Creative Commons License
Creative Commons Attribution icon Creative Commons Share Alike icon
This content is licensed under the Creative Commons
Attribution ShareAlike License v. 3.0:
http://creativecommons.org/licenses/by-sa/3.0/

openchange-2.0/apidocs/html/mapiproxy/mpm__cache__ldb_8c.html000066400000000000000000000324461223057412600244260ustar00rootroot00000000000000 MAPIProxy 2.0 API Documentation
mpm_cache_ldb.c File Reference

LDB routines for the cache module. More...

#include "mapiproxy/dcesrv_mapiproxy.h"
#include "mapiproxy/libmapiproxy/libmapiproxy.h"
#include "mapiproxy/modules/mpm_cache.h"
#include "libmapi/libmapi.h"
#include "libmapi/libmapi_private.h"
#include <util/debug.h>

Functions

NTSTATUS mpm_cache_ldb_add_attachment (TALLOC_CTX *mem_ctx, struct ldb_context *ldb_ctx, struct mpm_attachment *attach)
static NTSTATUS mpm_cache_ldb_add_folder (TALLOC_CTX *mem_ctx, struct ldb_context *ldb_ctx, uint64_t FolderId)
NTSTATUS mpm_cache_ldb_add_message (TALLOC_CTX *mem_ctx, struct ldb_context *ldb_ctx, struct mpm_message *message)
NTSTATUS mpm_cache_ldb_add_stream (struct mpm_cache *mpm, struct ldb_context *ldb_ctx, struct mpm_stream *stream)
NTSTATUS mpm_cache_ldb_createdb (struct dcesrv_context *dce_ctx, const char *database, struct ldb_context **ldb_ctx)

Detailed Description

LDB routines for the cache module.

Function Documentation

NTSTATUS mpm_cache_ldb_add_attachment ( TALLOC_CTX *  mem_ctx,
struct ldb_context *  ldb_ctx,
struct mpm_attachment *  attach 
)

Add an attachment record to the TDB store

Parameters
mem_ctxpointer to the memory context
ldb_ctxpointer to the LDB context
attachpointer to the mpm_attachment entry
Returns
NT_STATUS_OK on success, otherwise a NT error

Referenced by cache_push_OpenAttach().

static NTSTATUS mpm_cache_ldb_add_folder ( TALLOC_CTX *  mem_ctx,
struct ldb_context *  ldb_ctx,
uint64_t  FolderId 
)
static

Add a folder record to the TDB store

Parameters
mem_ctxpointer to the memory context
ldb_ctxpointer to the LDB context
FolderIdthe ID we will be using to uniquely create the record
Returns
NT_STATUS_OK on success, otherwise NT_STATUS_NOT_FOUND

Referenced by mpm_cache_ldb_add_message().

NTSTATUS mpm_cache_ldb_add_message ( TALLOC_CTX *  mem_ctx,
struct ldb_context *  ldb_ctx,
struct mpm_message *  message 
)

Add a message record to the TDB store

Parameters
mem_ctxpointer to the memory context
ldb_ctxpointer to the LDB context
messagepointer to the mpm_message entry with the folder and message ID
Returns
NT_STATUS_OK on success, otherwise a NT error

References mpm_cache_ldb_add_folder().

Referenced by cache_push_OpenMessage().

NTSTATUS mpm_cache_ldb_add_stream ( struct mpm_cache *  mpm,
struct ldb_context *  ldb_ctx,
struct mpm_stream stream 
)

Add stream references to a message or attachment in the TDB store

Parameters
mpmpointer to the cache module general structure
ldb_ctxpointer to the LDB context
streampointer to the mpm_stream entry
Returns
NT_STATUS_OK on success, otherwise NT error

References mpm_cache_stream_open().

Referenced by cache_push_OpenStream().

NTSTATUS mpm_cache_ldb_createdb ( struct dcesrv_context *  dce_ctx,
const char *  database,
struct ldb_context **  ldb_ctx 
)

Create the cache database

Parameters
dce_ctxpointer to the session context
databasethe complete path to the tdb store
ldb_ctxpointer to pointer on the the LDB context
Returns
NT_STATUS_OK on success, otherwise NT_ERROR: NT_STATUS_NO_MEMORY, NT_STATUS_NOT_FOUND.

Referenced by cache_init().


Creative Commons License
Creative Commons Attribution icon Creative Commons Share Alike icon
This content is licensed under the Creative Commons
Attribution ShareAlike License v. 3.0:
http://creativecommons.org/licenses/by-sa/3.0/

openchange-2.0/apidocs/html/mapiproxy/mpm__cache__stream_8c.html000066400000000000000000000310651223057412600251540ustar00rootroot00000000000000 MAPIProxy 2.0 API Documentation
mpm_cache_stream.c File Reference

Storage routines for the cache module. More...

#include "mapiproxy/dcesrv_mapiproxy.h"
#include "mapiproxy/libmapiproxy/libmapiproxy.h"
#include "mapiproxy/modules/mpm_cache.h"
#include "libmapi/libmapi.h"
#include "libmapi/libmapi_private.h"
#include <util/debug.h>

Functions

NTSTATUS mpm_cache_stream_close (struct mpm_stream *stream)
stat h types h NTSTATUS mpm_cache_stream_open (struct mpm_cache *mpm, struct mpm_stream *stream)
NTSTATUS mpm_cache_stream_read (struct mpm_stream *stream, size_t input_size, size_t *length, uint8_t **data)
NTSTATUS mpm_cache_stream_reset (struct mpm_stream *stream)
NTSTATUS mpm_cache_stream_write (struct mpm_stream *stream, uint16_t length, uint8_t *data)

Detailed Description

Storage routines for the cache module.

Function Documentation

NTSTATUS mpm_cache_stream_close ( struct mpm_stream stream)

Close the filesystem stream

Parameters
streampointer to the mpm_stream entry
Returns
NT_STATUS_OK on success, otherwise NT_STATUS_NOT_FOUND

Referenced by cache_exec_sync_cmd(), and cache_pull_Release().

stat h types h NTSTATUS mpm_cache_stream_open ( struct mpm_cache *  mpm,
struct mpm_stream stream 
)

Create a file: message or attachment in the cache

If the stream is attached to an attachment: FolderID/MessageID/AttachmentID.stream If the stream is attached to a message: FolderID/MessageID.stream

Parameters
mpmpointer to the cache module general structure
streampointer to the mpm_stream entry
Returns
Return a FILE pointer otherwise NULL

Referenced by cache_exec_sync_cmd(), and mpm_cache_ldb_add_stream().

NTSTATUS mpm_cache_stream_read ( struct mpm_stream stream,
size_t  input_size,
size_t *  length,
uint8_t **  data 
)

Read input_size bytes from a local binary stream

Parameters
streampointer to the mpm_stream entry
input_sizethe number of bytes to read
lengthoutput pointer to the length effectively read from the stream
dataoutput pointer to the binary data read from the stream
Returns
NT_STATUS_OK

Referenced by cache_dispatch().

NTSTATUS mpm_cache_stream_reset ( struct mpm_stream stream)

Rewind a stream to the beginning

Parameters
streampointer to the mpm_stream entry
Returns
NT_STATUS_OK on success

Referenced by cache_dispatch().

NTSTATUS mpm_cache_stream_write ( struct mpm_stream stream,
uint16_t  length,
uint8_t *  data 
)

Write length bytes to a local stream

Parameters
streampointer to the mpm_stream entry
lengththe data length to write to the stream
datapointer to the data to write to the stream
Returns
NT_STATUS_OK on success, otherwise NT_STATUS_UNSUCCESSFUL

Referenced by cache_dispatch(), and cache_push_ReadStream().


Creative Commons License
Creative Commons Attribution icon Creative Commons Share Alike icon
This content is licensed under the Creative Commons
Attribution ShareAlike License v. 3.0:
http://creativecommons.org/licenses/by-sa/3.0/

openchange-2.0/apidocs/html/mapiproxy/mpm__downgrade_8c.html000066400000000000000000000203071223057412600243460ustar00rootroot00000000000000 MAPIProxy 2.0 API Documentation
mpm_downgrade.c File Reference

Downgrade EMSMDB protocol version EcDoConnect/EcDoRpc. More...

#include "mapiproxy/dcesrv_mapiproxy.h"
#include "mapiproxy/dcesrv_mapiproxy_proto.h"
#include "mapiproxy/libmapiproxy/libmapiproxy.h"
#include <util/debug.h>

Functions

static NTSTATUS downgrade_dispatch (struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx, void *r, struct mapiproxy *mapiproxy)
static bool downgrade_EcDoConnect (struct dcesrv_call_state *dce_call, struct EcDoConnect *r)
NTSTATUS samba_init_module (void)

Detailed Description

Downgrade EMSMDB protocol version EcDoConnect/EcDoRpc.

Function Documentation

static NTSTATUS downgrade_dispatch ( struct dcesrv_call_state *  dce_call,
TALLOC_CTX *  mem_ctx,
void *  r,
struct mapiproxy *  mapiproxy 
)
static

Returns the nca_op_rng_error DCERPC status code when Outlook sends an EcDoConnectEx requrest.

Parameters
dce_callpointer to the session context
mem_ctxpointer to the memory context
rgeneric pointer to EcDoConnectEx structure
mapiproxypointer to the mapiproxy structure
Returns
NT_STATUS_NET_WRITE_FAULT when EcDoConnectEx is detected, otherwise NT_STATUS_OK

Referenced by samba_init_module().

static bool downgrade_EcDoConnect ( struct dcesrv_call_state *  dce_call,
struct EcDoConnect *  r 
)
static

This function replaces the store_version short array returned by Exchange in EcDoConnect with a version matching Exchange 2000. Otherwise Outlook tries to upgrade indefinitely.

Parameters
dce_callpointer to the session context
rpointer to the EcDoConnect structure
Returns
true on success
NTSTATUS samba_init_module ( void  )

Entry point for the downgrade mapiproxy module

Returns
NT_STATUS_OK on success, otherwise NTSTATUS error

References downgrade_dispatch().


Creative Commons License
Creative Commons Attribution icon Creative Commons Share Alike icon
This content is licensed under the Creative Commons
Attribution ShareAlike License v. 3.0:
http://creativecommons.org/licenses/by-sa/3.0/

openchange-2.0/apidocs/html/mapiproxy/mpm__pack_8c.html000066400000000000000000000230261223057412600233130ustar00rootroot00000000000000 MAPIProxy 2.0 API Documentation
mpm_pack.c File Reference

Pack/Unpack specified MAPI calls into/from a custom MAPI call. More...

#include "mapiproxy/dcesrv_mapiproxy.h"
#include "mapiproxy/libmapiproxy/libmapiproxy.h"
#include <util/debug.h>

Functions

static bool pack (TALLOC_CTX *mem_ctx, struct EcDoRpc *EcDoRpc)
static NTSTATUS pack_init (struct dcesrv_context *dce_ctx)
static NTSTATUS pack_pull (struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx, void *r)
NTSTATUS samba_init_module (void)
static bool unpack (TALLOC_CTX *mem_ctx, struct EcDoRpc *EcDoRpc)

Detailed Description

Pack/Unpack specified MAPI calls into/from a custom MAPI call.

Function Documentation

static bool pack ( TALLOC_CTX *  mem_ctx,
struct EcDoRpc *  EcDoRpc 
)
static

pack EcDoRpc calls into proxypack

Referenced by pack_pull().

static NTSTATUS pack_init ( struct dcesrv_context *  dce_ctx)
static

Initialize the pack module and retrieve configuration from smb.conf.

Possible parameters: mpm_pack:opnums = 0x1, 0x2, 0x3 mpm_pack:lasthop = true|false

static NTSTATUS pack_pull ( struct dcesrv_call_state *  dce_call,
TALLOC_CTX *  mem_ctx,
void *  r 
)
static

pack EcDoRpc MAPI requests

This function searches for MAPI opnums to pack in the requests, add this opnums to the mapiproxy opnum DATA blob and refactor the request to remove references to these calls in the original request.

References pack(), and unpack().

NTSTATUS samba_init_module ( void  )

Entry point for the pack mapiproxy module

Returns
NT_STATUS_OK on success, otherwise NTSTATUS error

References dcerpc_server_mapiproxy_init().

static bool unpack ( TALLOC_CTX *  mem_ctx,
struct EcDoRpc *  EcDoRpc 
)
static

unpack proxypack contents and restore the original EcDoRpc request

Referenced by pack_pull().


Creative Commons License
Creative Commons Attribution icon Creative Commons Share Alike icon
This content is licensed under the Creative Commons
Attribution ShareAlike License v. 3.0:
http://creativecommons.org/licenses/by-sa/3.0/

openchange-2.0/apidocs/html/mapiproxy/mpm_cache_case_one.png000066400000000000000000000261011223057412600243600ustar00rootroot00000000000000‰PNG  IHDR÷üjÅíPsBIT|dˆ pHYs × ×B(›xtEXtSoftwarewww.inkscape.org›î< IDATxœíÝwœ]Eýÿñ×; ¤H(л鈕"R©*"‚  XùÙá‹( ¢b¥èW¿ MPAPzIB=4 Hÿüþ˜9Ù³wïÖìîÝ=û~>çqïi³sËÞÏÌœ93Ь’t$p20/oZØ5"&5.Wffý‡¤€Q¥MDÄ^ÊOwÒè Øb¬RZ£Q1k‹¤QÀÚ5›ˆw‘³’yÀš¥õ‡•‘îäànf½a/àÿ€…y}>°0±a92«0w3ë †•ÖßnTFÌ÷þíNà`{à5àQàÕ†æÈ̬¹xظ¸£±Ùér‡ºþOÒYÀĈ8«Ñy1«GÒ§?—6Ͷ7Ë[ÃIKú Ûè¼t×Üͬ7Ü ¼ü x¦¡92«0w3ëqñ"ðIÛÏFąΓY• jtÌÌ̬{9¸›™™UŒƒ»™™YÅ8¸›™™UŒ;ÔUÇI!Ýb4'?ή·ó–K33ëqîÕ1‚4Äç°¼ -=o¶.i‰šsR¿ ÐV!¡ÍD{ÇFÄÜn~ýff–9¸WÇ«ñ£®œ(iÍ ­=¯·o)`ùNžW0TÊÆBR! W ¤Œ9]y¿ÌÌú:w#"ïä¥!$‰¦@g ÀáÀ²8o0TÒPš0˜K7 :²/ïRà`R ûï’>Üœ,é;Àk$m %½8ØTX™,-ét`çˆhµÔ.iï|î À’¾< lMj’Û3çß̬ßêƒw’t¤pñnR¡ Ö Òe“¡ÀÀ¤K"ªÊ¸j.ŽˆW%ýødDœZŒYØ("æJÚx 8="uÊ‘ôðË6j³WDÄùØÛ€}"âuI›߈ˆÃ$=\7•òpiDœ×.¥÷%àC1SÒöÀñEIÅeˆëÃH/ˆˆïå^»+~[—¾|."”tðùˆø”¤«€õ#âä6Î53³êÌ$¹óæ.¤@©ïÂëÀ¤Öçב*_˫ءû¯ßSêéy+©3Ù½’îNˆˆ§:Æ’–'•¦.* Þhï¼2I«—•Ò˜–/—t;)€“Ï91ÿݧH-[Óvp߆ԂéÒÃmkff=(÷Q88”ÔÊðð—°¾|_ÒgI×ô#õ|Ú^1]ÒÀáunc˜U'·DÄI“ƒëtàûpppmDÌÎ×”>¬!é4ïTRÏýÀF¤Î…[“¼™™õ²|ûäÙÀ椞ò×ãÚº´ZUC$LTbIgçDĽ’®.‰ˆ‹»’°¤Oïöþ–w]œ&iBDü´d~ \,é_¤‚È’q"©Äñ’¶~ÑN§—Kº†Ô<³0"NÉë®$}v‡tMIÒˤkóË’‚ösí¤6p^NàøvŽ73³ž18&"vûd_!R/ï¥mDÄ+’Þ ¼ÓšîÝçõ"bœ¤¥€u#âÁ¼}$ð~ÒµŒ;"âÙRkkDÄí5io<³JÛ†&ÕÌoˆ·òö1ÀÆÀøüøxQ:“ô.`zDLÏë#roç4f•ÒØ("n­ù{»“:î= ˆg%mß·ðå׺3pcñ¥’4Þ÷TæBÙĈ8«§ÿ–ÙâèÌ 6f½%ÿ^OŒˆ±ÎKwQ…ú XîÖ_8¸[_TÅà>¨ýCÌÌ̬?qp733«w33³Šé“Á]Ògrg7333ë¤îy¬ööŽ–{´# -[{Ü’*Íù\gzF$ ÍãÑ×û;Cò}‹Òk/offfýMÍV&iSÒ˜ï3r@ýIù–³|ŒHcÏ/ ,!éZÒ`0[gKšEº…m"p;°ðCIïF”.éEàÛyЛ_›æ¤ŸŽÎƒÑœG{~c`UI_¾ Œ•ôTD|ª§Þ33³ÞÖ“S‘>ï´6piHÚ²­H“×|$§Œ'_ˆGóö¡Àñå¼~°gD¼&é(ÒD1gÇEÄü|ÌïH“ÜÜAšŒfVD¼OÒî¤ÉnÖˆç$ýGÒ†1©ß 33³^Ó“Á}„¤SµH3 íX瘇‘’&çÒú„WHÚˆ4Ý…y<à‘¤¹–Ïö’ôiRKÀXÒ|îŘóÅ<ì“Hõ#Ï=D¡ÏÁÝÌÌ*¡'ƒûQ¤Q㾘h1Œk¼@IìNº«`G`Yà·áÀ^#“Ü›Á³vG‚igj¦³iL;|þâSw¨3ëÑÀGI·'nN £Hdþ_i`ö©L{»fºhr¡l!‹wÍti ‡.ïš©™u–ƒ{ÅIZ8ø,©)t(°Té™À¿£%-Ccj¦õ‚é\ïºim0íLÍtaGß_3³¾ÈÁ½‚ò}¬G'+Óö»#€÷fÞ[œÚéÌNž_®™:˜š™u#÷ Šˆù’~"¾’jð_öÉÓçš™Y?åfy "ÞþÕè|˜™ÙâsÍÝÌ̬bÜÍÌÌ*ÆÁÝÌ̬bÜÍÌÌ*ÆÁÝÌ̬bÜÍÌÌ*ÆÁÝÌ̬bÜÍÌÌ*ÆÁÝÌ̬bÜÍÌÌ*ÆÁÝÌ̬bÜÍÌÌ*ÆÁÝÌ̬bÜÍÌÌ*ÆÁÝÌ̬bÜÍÌÌ*ÆÁÝÌ̬bÜÍÌÌ*ÆÁÝÌ̬bÜÍÌÌ*ÆÁÝÌ̬bÜÍÌÌ*ÆÁÝÌ̬bÜÍÌÌ*ÆÁÝÌ̬bÜÍÌÌ*ÆÁÝÌ̬bÜÍÌÌ*ÆÁÝÌ̬bÜÍÌÌ*ÆÁÝÌ̬bÜÍÌÌ*ÆÁÝÌ̬bÜÍÌÌ*ÆÁÝÌ̬bÜÍÌÌ*ÆÁÝÌ̬bÜÍÌÌ*ÆÁÝÌ̬bÜÍÌÌ*ÆÁÝÌ̬bÜÍÌÌ*ÆÁÝÌ̬bÜÍÌÌ*ÆÁÝÌ̬bÜÍÌÌ*ÆÁÝÌ̬bÜÍÌÌ*ÆÁÝÌ̬bÜ«cˆ¤å 33k¼!΀u›•€Ûs€x˜\óøðBD,hX.Í̬Ç9¸WÇ ±€¤1ÀÀšyÙ8 ?_EÒ\ZýEˆ˜ÕûÙ73³îâà^Añ ð po½ý’FÐ<ø¯| x.ið­ÔþsúffÖG9¸@ñ60)/-H ¬JóÀn4ÿ1Àk´^ûŸó{øe˜™Y+Ü­…|M~r^n¯wL¾¶_þ[ûæç«JšOËZ¹ö?³‡_†™Ù€åàn]ÓéÀýõöK¬Nó¦ÿíiªý^¢õÚÿ´ˆˆ~ff•äàn=""ÞžÈK ’«Ð¼öÿAš +IšAëÁÿùˆ˜×Ã/Ã̬_rp·†ˆˆ…À”¼Œ«wŒ¤eiü7öÊÏW“´xžV ñf¿ 3³>ÉÁÝú¬ˆxxx Þ~ICiÙô¿ MMÿKSi½ö?ÕMÿfVEîÖoEÄ੼´ IÀÊ4¯ýïHSA`¬¤·hô‹çÏç¿afÖ¯8¸[eåZù‹y™PïI£hü7öÈÏWÏ„¶šþgôðË03ë4wÐ"â ࡼ´ iI`5š7ýoISÓÿhàeZ¯ý¿”û˜™õw³6DÄ\à¿yi!×ìW¢yíàSyÛÊ’fQœÿɤá~g÷ðË0³ÆÁÝl1ä¦ÿ©y¹«Þ1¹c_9ø¯ìJSÓÿÒ]ukÿñZ¿ 3«w³oä¥IK†û-7ý”¦¦ÿåHs´ÖôÿboÎô—‡Þ¸Òc ˜õMîf –ä³y©KÒŠ4¯ý¿øDÞ¶Š¤ÙԿݯ¨ý¿Óù}EÒºÀTIçgDċݕ¾™->w³~ "¦Ó€{êí—´̓ÿZÀN4Õþ—¤i¦¿zÁÿÕNféTÒˆ‚ß¾,ið㈸¥“é˜Ypp7«€ˆ˜<–—òuýòLk{ÒüW^¥~í2ðBy¦¿ˆI& $´;°­¤7IÿOdÖ8îf@ÌEо­Þ19À—kÿ[ûçm«JšGËàÿ#à—ÀÒÀ¨¼œ üXÒeÀ/"¢nÃÌzŽƒ»™›æ_î«·?ÏôWþkëª9t©üx8p¤ç€Ÿìþ\›Y=îfÖ!¹SÞãyAÒ†ÀuÀ’­œ2(ïÛ8ø"ð$mt4³îáànf&éÀŸ€¡À`yý5`©óߤ~ODÄ;’NkLŽÍ–!’v"ÝW»$ðOà†þ0d¦¤Û"â‹qþö1¾§Òï­4Íz‹¤ÁÀ/“ÆÜ¸›tÿcÀÓ½yϽ™ÕWÔÜ?ÜA*}ÿX¸´Q™ê„õ»z¢¤AÀe¤Ä­9¥«é·¡Ëy6ëFgFıΈ™µn@D|/"®Œˆ›_oïDI_t­¤[%–·ÌÛÿ%éØ<©’–”ôIIWIú¤mòö­$#é"I»”Ò¾PÒç$Ý"釒F”ÒÿI7Jút+ù%éw’¾-iœ¤•$m&é·’.•´{>ô€åókø©¤$‘Ó/iYà3¥t·”tv9¯’ŽôáÒ1—tˆ¤¡’.Èù?KÒæÿHÌú®ˆ˜S3kÛ :Ûnjë$Ikåãö! CycÞu0ؘ|7o?’tìç€ý€)yÈÍK€³€³%­œßXØ‹tíÞyû·súûfæªí¥ éÒÂQÀÛÀ.À,àBà4R‡žïJZø 0="öŒˆã€a¤¦ÆWókzƒ4H’–. Ýâs pJ¾mèàÿ•þö7€…À)±p&ð›ÖßM33³îÕ,¸K:‘Ïjç¼é¤[aN¶ŒˆçóìX#HAn%àcùøƒ€ŸåRÿ¬ˆx‰4zÖ]qoD<ü•´æ’†´œ \E ¶úœ™·ÿoù{ø]DÌ! Ô1#çåóÀLZo™x9"Ήˆ95}ö˯ù@àRဈ˜@šøcUIëC#âÁ<œèº’~ߣ%m#¿fffÝfQoyIß¶!­h뤈xKÒ&¤ö%Ý| Ü SXÞž—j'˜Ì/­Ï+åçÒ4˜ïjÕäô‹Î:åsk½X ÎÃH3vMÈëHƒoÔóB+Û‡/Ö¤ñl~þàPR¡æ|€üÞ| 8š4U裤Á=¦¶‘g33³n1@Ò7IµÓ/ËIZ>o#é˜Ú“$­ŒŒˆ IMï[ä²—“FµšÜJªíBj~ÿš¤¥% Ééßl/i#I«“&Á¸ªüþ82¥yD_ãÀfÀ´Ü§àaRáa!ðFž£=¶^Êiø¤_sH­eãr3HýŽÍiüX&ï{¸ø{D…™ó$Ýì–_ßÛu^›™™Y·S;-ðÖH: ˜íõ•0k¨<ˆÍ³áÁl¬ÏÈ}¢&FDeúFÕë-offfý˜ƒ»™™YÅ8¸›™™UL·÷×Õ<,/é÷]=ßÌ̬¿ërp—´„¤Hš×—"Ý.6 ¸‹4cTqìXÒˆtÛKzo)™á’vÉC¹þ Ü’ÏS~_Ik·’%í#é}ùþ÷w;JÚNÒz’–’´Acþ#¥óÖ“ô®š´ÖÉ- «Ölß*ߣ¿›¤•ò¶$mÕÉ·Íl@‘4LÒú’v•ôY`[š†“6³Ò¥ùÜ%}tÏùõÀé’N"Ý[¾° iÈ×ûHÃÈBªÉv$Ý~WÞ~.ðtNã˜<@Ì‘Àˤ!p¯ž"· pBM>ö! uûw`WÒ½ï[îAß“4Îûhà"Ò¨tã%ý›4ÜT`¡¤e"â<~üH÷º"鹈øNV÷&Ò ;OgI:—40Ír’ÉcÓ› (ùcE`V–UI#J>Oúÿ›L½ò©Fä×l éRp'à¯EÄm’.~—t °kDœT>8"î”ô-i$©0ààn•£4ãê´¼G‘ â“i à÷’F…œ L‰ˆù5ižFÓÐÍfÖCºÜ?@Óð¯÷“jÕ]QÔàŸÖ)…’Ž.‘¤YÖ®®9ÿ à‡Àã’þJ!¯ž;K?2»»Jº6¯Þ%é9R ÀTÒÏÒ9OOSóHtÆŸ2çqfîg`Ö¯äZ÷XÚ®uÏ¡©Æ],wÏ#âÞϹ™uDWƒûxRó÷x`SR€oÏ,Ò,eíMPspYžböIk—gk‹ˆgCóuÿsI×òþSçï”'­¹ X*"¾P>@ÒÁÀƒñ-IÃo¶‘Oëg}ZnUj«Ö=’T-î À¥ùù‹y¾3뇺Üÿ8CÒ?IÓ°þ´çÜüBÒ„ˆøQ{çNm§’Æ‘_ ¸§fV$JšÞõMRþq1CÒ›¹ùïVZÎw-pŒ¤ó€{H=óEê3p²¤)¤æþé˜õAù’ÕÊ´¸W!ÍeP[ëGS­û­ÞϹ™õ–.-Ÿk·»7çùÕɽޗˆ'[9g5`ˆ¸UÒv¤æòȵŒµ#â!Ik’jÚSIÍý&¹·Np_Ô‰o>pSÑL˜ü6%u蛬ל»ðàáˆx ”Þ¤‰åÇ#âIÛGÄø|ÌÀ‚ˆx!¯ï ÆcËWKîÜÙV­{8ð-ƒw±¼Tû¿ÒWxly닪8¶¼'Ž©÷þCÒ`ÒõìÖ÷JÀLZÜ“óL‡ý’ƒ»õEU î]m–7³:$¦õÀ½:°$éÖÎrÀ¾©ô|j¸Ämf‹ÉÁݬƒò I«Ñzð^xƒæûIR“ÉÀóñvïçÜÌw³LÒr´]ëLº²¼ÿSz>͵n3ë Üm@´$m׺W ÝyQÜ×ÑTëžÝû973ë<w«„|§Fk{5@¤;'ÊÁû_4uR{¥Ù63ëîÖçåAŠÚº5l9Ò¸åÀýp5MàÎéýœ›™5†ƒû&iT_BTR[“¬,¤ùä#“hªu{À!3³÷&>ôiÒD=Gzw÷ôßk«Ö=x…æû~à*šjÝóZ¦lff­qp $­G/ÿ0ÒØû»£ì-Fš" ºÒÖä#óhYë¾—¦Z÷ë‹“33kÉÁ½Âò0¼{'#H3}7wàü´¸× M…[LùY,w—çç/ÔNùiff=ÏÁ½‚$¾|•4"Ú2y×;ÀqjümMù¹ 0›–µî;iªu7üz½™™µäà^!’¶Žv!õÚ©oFKú/°-§ü\‚§ü43ë×Üû¹ÜamS𮥫S&{EÄ›=733k ÷þ¯è´öd~\ IjR,MSÀ¬/i¿ˆ˜ÑûÙ53³žæàÞÏEÄS’&QšòUÒÀú¤Nt›ÛcH€JÚ#"jLÎÍ̬§8¸WP¾/üѼ\^lÏèÖ"ýM€£$ý6"&5"ŸffÖ3܈Xü7/W78;ffÖC5:fffÖ½ÜÍÌÌ*ÆÁÝÌ̬bÜÍÌÌ*ÆÁÝÌ̬bÜÍÌÌ*ÆÁÝÌ̬bÜÍÌÌ*ÆÁÝÌ̬bÜÍÌÌ*ÆÁÝÌ̬bÜÍÌÌ*ÆÁÝÌ̬bÜÍÌÌ*ÆÁÝÌ̬bÜÍÌÌ*ÆÁÝÌ̬bÜÍÌÌ*ÆÁÝÌ̬bÜÍÌÌ*ÆÁÝÌ̬bÜÍÌÌ*ÆÁÝÌ̬bÜÍÌÌ*ÆÁÝÌ̬bÜÍÌÌ*ÆÁÝÌ̬bÜÍÌÌ*ÆÁÝÌ̬bÜÍÌÌ*ÆÁÝÌ̬bÜÍÌÌ*ÆÁÝÌ̬bÜÍÌÌ*ÆÁÝÌ̬bÜÍÌÌ*ÆÁÝÌ̬bÜÍÌÌ*ÆÁÝÌ̬bÜÍÌÌ*ÆÁÝÌ̬bÜÍÌÌ*ÆÁÝÌ̬bÜÍÌÌ*ÆÁÝÌ̬bÜÍÌÌ*ÆÁÝÌ̬bÜÍÌÌ*ÆÁÝÌ̬bÜÍÌÌ*ÆÁÝÌ̬bÜÍÌÌ*ÆÁÝÌ̬bÜÍÌÌ*ÆÁÝÌ̬bÜÍÌÌ*ÆÁÝÌ̬bÜÍÌÌ*ÆÁÝÌ̬bÜÍÌÌ*ÆÁÝÌ̬bÜÍÌÌ*ÆÁ½“ô)Iß—ô„¤õ/3³þBÒÀÍÀò’–tqƒ³Ô-†4:¶XFï*­¿?Sëƒ$-, †K ¼ ›33†äçïžm\VºkîfÖ><  L6mhŽÌ*̵<3ë ƒ€1¥õ%•³ÀÁ½{¸X˜×¼Þ¸ì˜™õ;hÞWƒòÑ­Üû±ˆÐè|˜™õWñ•Fç¡'8¸›Yo¸øEi}!ðBƒòbVyŠˆFçÁÌÌ̺‘{Ë›™™UŒƒ»™™YÅ8¸›™™UŒ;Ô ’>LÕîÆˆ˜&iG`àΈx¦±¹³ª«ýþ5:?fUæš{H:^Ò켜^³ïžÒ¾jö\Ú÷ƒš}»–öÍ–ô–¤G%ýPÒ°|Ìwò¾›º˜õ_‘†X8.¯ïÜÅôZômIKÚ£»Ò´Ê¨ýþY%é]’¶«³¬Ô i#é,IÛuG^{“¤!’v‘t°¤ý$m.©OV’Ü»fi<â¡Àç$´3°uiߢ÷W’€ÃKûËÛ ƒòö%€+{€õ€ŸÕüÝ%»éuüøiÒ„î²#ðIRÞÍ"𥳠²IDATʾIú¾=ÒèŒX»~ Œ¯³tǸ{GÓ|^Œ>OÒjÀcÀÀ_HˆMNoë¼Fqp_<¯#Ïæõc€y¤ \jí¬A_ûñü|—:Ç-ˆˆƒ"bà´¼mŸŽfHÒhI¿ôˆ¤’’ôþV?T{ß,Ÿ;HÒç%Ý-éUI÷Júl)íC%M”tjnQxVÒU’¶ÏûÏ"w€ãò±Çå}'Jº]Òë’ž‘ô·Ž¾&ë^’–ÊŸÍDIä™°•t ¤m%Ý‘¿7_,ó‘Ü*5-†÷×ì?$§÷³üý˜œ×Ë-8Ÿ'}ßÖÌ眙ù¼¤¿Iš*é:Ikçýcòþ{sËÖ=’®ËûÞÏ™"é¹ÜZ´NÞ·s>–4RÒ’î“´™¤+óþÍKù¿$oÛ¦Gßüþgð?¥e‚¤ÁùwfTqP~ŸGKZº|rÞ¶…¤•ë%žÓj1“eÞ¾Ž¤­$­.©YE)§;:¯j#ý5Š<çÔTª4VÒFJ“µåx`=à&àcyù ð|¿»rNsHÍö‘9Cò²‰¤¥ó¶¡¥ãŠ÷sdÍù«+µª ®Ù¾L>~°¤¡’6%"¼tr¾p))X?¬ Ìþ ü7ïߥtÎó¶“óóóKûwËÛææõaÀeyÛ#yÛñyýŽVò5˜ôÏÀkÀ¹À¿CóþGËù®ÉëŸÍëÇæõ§H%÷'óúyÿ7òú|àÒ0Ü÷ŸLÍÛ µ@E ø‘óv©yöFŽu–ÉŸGo·åçsHÓ›¹yÛ:ùœ#€ òwðçÀô¼ï¼ÿë¥ïÆC¤Z^‘f‘Fí÷ïê¼>¸˜œ×ÎßåUJù|›4Üò…¤‚ñyûÀùù‹À²9í ó¶gåç?Ëû¾“×›××Ìë/ƒýùô…ø[~ON¯³o(©ÆÀA¤a¯ÿ׿™Y¸¡ôùðµ¼ïº¼þ»ü™Ÿù6yÿhàšs¶Êû—/m?9çæ“jÒCò1cJßÁù;[œ³|>f›ü*ÿ/ÙÆ{Rü†ÿÚÊ1Ûæ×R¤ùù÷5ï/¾«?&ýFMñäüÒq?ÎÛ~“×w£)®0 دt|ñ¿s"0 XÐð/Q\JÆ%¤ÚzšÑ#ašwRí~fÞ¶>°Q~þ°TéÃ+>¸©¤³býè|L{Á½¢ €UJÛ‹/|{Á½øGûé:ü yý¡¼¿îÓhºD0Ÿ4ÚXñó|ÌWJÿÓyÛu¤&û1þ òBóà^ç7óúOòúßê|Ž£ó÷ô«À­yÿ/ó¾"¸¿DÓàX÷åm'´òý+‚û_òú ù»¤ÉrpÿRÿ¿ÛKÛžÉÛŽ*½Æ§ó÷3H?ôÅÿÁrùÿk0øVùµ{iöùÏÊ¿GŲIÞ¿aÞ7T€Šü¿¯üÛPÍ»#ó÷£¨dÁý-R+ ÿ›÷/M R»Φô»Góàþé÷êå¼þþ|LQ ›”¿¯ãJç,ŸÿÆš‚ë~y}°}+ïÉGKi¼M*¼|œ\ Ìß¹â7ô`ÿ¼¾Ø6S÷ùÀå¤Q×!‚ßÌßG‘ƺ`s`µ¼oðeRêMRh½œnÜçNs³üâ;Ÿô%Ýw×9æã¤¹¬gšröÍ猤å5¬ •Šo •lwŽˆ³;˜—µòãcñâ¢#æ·wbn>*š¶N%5=ý0¯¯Ssøí1?"æ³I_ÆåÚHþrR©zGàb`ª¤[:Ð f=ïŽüX|_ŠI3¦çÇ1’>Oªi\Mó륵ŸûÄÈ¿6¤xhú^µæ>€ˆx•T8€ØË.*=_­ø[¥m—÷EÄ›Àÿ’ZN+þ"â5RÍ~ð Òå)€óÚÉç@ô6̓{ñN"Ul–¾Gjš>,ö’¦ó àcñ‡ˆøuDü©&íó#âxR+!ÀN9í·€kI— &µ×k?#,¥|8?žg_«9o[`UÒïð `‹üú‘‚r ñORáöR¿§%µàlOú®¿I*àl^Jsßšäþ‹ˆoEÄ«HŽ}Iš5»"âü7—&ýoŒ!½¿SI­»®I÷ÇqhD|ÍÁ}1å‘?æÕÖ:VžG“®Ñü„ôaVsìüˆØ3"öŽˆ/EÄ-ÈÎóãÆ’Ö(6v$ˆæ¾â‡õ `ÙÒRûOõNéùš}³òãðÒ¶yq鋹+p/)ÐïÖ^¾¬ÇŸeñ9Î΃kŽû©·kDlBª Õ³uézà–ùqJ;yx/€ROì"¨—¯c.Œˆòl‡ÏåÇ÷”¶mVÞ—¯Ûô}œüJRyÊÙ3óãñ¤Ö¶Û#â‰vò9][”–I¥}÷Ñô½yž¦¾FEo&)µæ¾üX|ç†HÚˆÔÒr"©¶ZÌA0¢£i*S ¤åÇÂèü8˜P÷ÍÏ'’ 0õDÄõñ!Òïâ±yó>’–ÏÛ ö"Må4Ô$ucÍúòã!¤–N€sjò:²”nm _”nŸìÂß}Ô Ó¢#]þ‘Ù‘ôOð~š¦d]¸ØE©fwGj.ÝxXÒ?±¤Im©¹ž_®‡ŸNªm϶#ý8ØÆyeדšÞ¿+ioR+ÀZ’>IªÎ'•Jç‘®ÍZÿð4©¶þ]I¯{¶rÜhà1I3Iw©J[ö—t M­IÀÖjüç’zÞo+ié‡| R€¹4f/&ÕÌ?G*Tž \ i¯HTü¯iZKc$mQZ9"^ʽ.!¯ À¤>7ß#5•Ï#U`Ž’ô;RZ=×R EÀ š;4§ûçˆøŠ¤c€Ï´’¿ÖÒ¸‹T«ýœ¤ÇiYs4?öˆÉ’6¤e &ï;ŽTºžtiòé¼kH>§¸ dér×”|ÞF¤÷£lvÍúõ¤‚é¤À=“ô¦”î|`§\¡DÒÖ4UÈZ¤ëš{שæWn-*jï3IÍ«ÖÒ§€ûKK$Ï"õúéwâ9àxI»FÄtRÇÙ ½Ç/’î,úTÿæuùñHII¹Î:‰ô}:€Ô1¸Ù]ñ(ðR¿¡'%—ôéwsKêÛ’ô=šB*´^–·ÿ%ÿþ?Dz_†OK—Ó|”ÔDߪüÛ}.© 0 ¸("fæ}ÿ&ý_,Oº¤y»¤gHý¼Öj-MÏ gf‹MÒ×I?ôEÄÁ<çjà#¤»1zµæ,i)Ò­y¿&þ_oþý¾.·´mTg×í¤ÂÿѤÚèÏ#bn®Eî ¼Tô’´-é6ÞUI5Ý?Gă’!ÝRvEnAYÔéîõˆ8=Ÿû¡|î4RËÏá¤Ë3?4œ¦&ñDÄB¥Ñ·nˆsk‘*ÓH• rË1I»“.Ž%õ3™\SÖš÷d`wR_‘Ta\ JÇíAº_¤9>§9KÒ‘¤~!EÄã5鯜ßWj÷çÛ÷öÞG òÓògq]DÌÉÿ£€ßý­ÜÍl±õÃྀÔrù<©ø›½ù÷­gIÚ€t‰à`%RSÿƤŽlŸodÞz‹ƒ»™-¶\ûZtMö±ž³)©2)"ÚêxÕírÍt©#]íõPëçr­ýR_ H—.NŠˆY­œV)ÿ4f äÏÝIEND®B`‚openchange-2.0/apidocs/html/mapiproxy/mpm_cache_case_two.png000066400000000000000000000471741223057412600244250ustar00rootroot00000000000000‰PNG  IHDR® œ!RsBIT|dˆ pHYs × ×B(›xtEXtSoftwarewww.inkscape.org›î< IDATxœìg”\ÅцŸW¤€ DQ‘M2˜L2`À$cÂGlc¢1L´ 6Æ`À€M9g0YäŒ @B" R}?ª¯öîhfwfvvgvUÏ9}fnè¾=ñ½Õ]]%3#‚ + énàÏföX…õ~ìff;¶OÏš]ë,à]3»°½¯ÕUéVïAÔù€Y«¨70oûRй€Ù;èZ]’õî@3’V¾fÖn6³±’–ÖÆwšÙWéü™u%/€»Íì³\{³[3÷´rí¾ÀÀBÀXà63û¾àœy€Í€×ÍìÙ‚c âÿ›÷™Ùi7à'ÀŠÀdà!3{· îæÀ@àá2Þ¦ Æâ’t»¤Çså‚z÷)h’n*øL/®wŸ‚ºóàR`°0ÐWÒÀ}ÀrÀÀK’¤ówvúÛ¯Hš@Rwà!àd`eà~`ή}4.<}€§%Í”;>/p° p¥¤‹²’Öž~¬<'itø§ÀaÀÀšÀPIkçêþ¸ Üü¸Œ÷©b$í.é©ÜïíiIs´ÇµêŽ™5Dž,Wî¨wŸ¢´ù3Zð™ÞSï>Eiöù¬Ž[ï§ò!°E;_ó"à-@i{.à`ÅÜ9×g•¨=plz¾#0èž¶WIß³Ë臀7€­ÓööÀT`´½ðY®íaÀž¹úG–hûhÜ’·§ó§í^ÀDà¨vxoO(ø½Ôû{Ö%† ƒ`Æf. gn»#Faî³ôO‹¯üNRv|!Ü*BÒÜÀÁÀúÀ€´B:o%àf6%m¿|^ꢒû¤¶zó‹æNyÉÌF˜Ù{É¢$é`)`cIë¤sûˤv{‡¦v—ć¿È½¾7ÍlLj÷IOµö-ÂAGóqî¹áóBSrû¿NGàŽ ;šÙIÅEÜ’é^Ðvávžsð9¦Ìì3I÷Ó\´'œ?%µ—‰ìu¸…š?>¼¹°'ð.°3nue},üŸm©A4Ì0x ˜<ˆ›æAçæààü3}³¾Ý ð?ò™ÙÓY†§ã·&Ñêü"W÷Y`ÝÜ<Õj”ðÖ“Ôw¹6‰Öœ¸ÓG«˜ÙÀ«À²}|!×ÇûÍì3› ü²àõ-&iáÔ¾¸#G{0 æ€×ðßÛ÷-Ö褔eq%¯™¥pÓ¼wÚýœ™=W«Ž˜ÙŽiBö%3Û¨VíõÃÌv‘Ôx?>Ó†d4p°<îå÷<|saf_HÚ¸JÒ“øŸïòøÎé¸SÃù’6½ýÞËU¿Øx[Ò½øר×™,é*àI/VÐÕ}›$m<‰Ï} ì ü¸.y$®Ž GvÝ’þ‚;œ\ ¬¼RÁuËÆÌ®Ký¸¸ÅÌ®më4jj.q‚ÔŸ´í]pèD3;¡¦i®­žt rÂÕ¯Þ} Š#é( Ÿ™Õ×ZøÞÌF쟷DzáÖÖsÙ<˜¤Åp¯Ágqë½—™½™Žõ6ÂÝá#’•Tìú+áÞŒã^€ß˜Ù’úã/åÎ]xÑ̾MÛ}q¯Á¹q|ÂÌ&¥cýñ9®áÀH`q˹ÓKú)îÿ8þ_:ÑÌŠŠl[™„«‹«;þF¿‹O8®Ü®= ‚ Ëbfo•Ø?¸¹Ä±øTB±c?Ð|ýV‹£@föMC|çö|RpîÛ_w—h÷ÜÅ?ãÙ‚ãO¶Ô¯ 2Ê™ãÌef‹gµs‚ ‚ EZµ¸Òdãg­AA#yAA«„pAŠX€A—%­ñ€/rΗ‰ÖšKuа4¢puKA4'பSëÝ¡ Ÿ´@y`U<`ïòøz«Oñÿºž©ÌLN¡—žHåi3û¦ý*§…kàϸ ~¯´ø¹ÃÿMÈ•ñÛ%Kr¡ ‚  Ö†í솯¡z ò~'pR‘:óák²~Š/t^VÒxpßû:ªïAu”9cM¹On÷A’vJÏ7·‚ü3mà[3Û£•þOüÖ»…2g©c)üK1¾£Lñ+,fö]u/7‚jH©CþŒ/:¾Ø0[˜ÜiÝØõ© iVjåô²IIéZÃ¥Ž¥ºÅ˜L•bˆ‹xŒÃAIsᲄ÷¦¶Ž¢˜ÙD®ÃElTòz…‹[š/ ¬R‰h¥¹Öí€}€Õð<^¯àŸë$Ü?$éM<Ãòå•Ì›™Ù•)éím’V /ÝŽ§Õ ÈId@îzDäÚSÆ‹Þø¼áA¸CC!™œ‡Åý¿‰-´«^rA¬Æôy øMrM/·ÞÞ¸`¿\Ü[Ê]>Yc«›àk¸N*•9¹Dw÷›Ù¹åÖ© íñÏðÚJƒ;Dä ŽÖ–XHZ8­)x>½‰ÀXà^<‹ï Ù¼œ¤cñ4öY¨µrÊ\ÛÅæ{IšJ™N3¹ç?Ã-%Kk©Zt°‘´p >Ôû33{¥Œ÷p2)N¡¤yðaÕ—%ýŸ™=ÔZýÄÁÀS’†¤H5ÃÌ®–t%0BÒÛÀe¸ˆ½_ËëtVÂâ Ú•°¸:Iw_à–ÇmÀ-9H: ègfGÕ¸/åÌ–~À¯€'qÒéÄŸ«Êi&ócpïÕrjJY’ëàq©™Xæk<XÚÌv¬ø j½íøÆºÀ¸Ñû©×•rx ‹+‚NCšë j§jæ %ýècfÛµpÎL¸ˆ­ü8xŠÒ^¦ó–8–/³âs‡ßÇH:‰ÖDp4>wxîSx¼êô)föƒ¤-pËpi|.r)à$àdI#h±ÑÕ\£³Â]„4Ÿtk½ûQ-ÉÂ8ؾ¥óÌl’¤Éx$CÌìš\»Íç¯ÁÅðŠ Ýü¹çãð˜‰Û3½u(IUG¤IåP\ àÿÙ™ÓÎÒÀÉxLÅ·ñCÚú^tB¸‚ h6>2³gÊ8÷¯øh›E ¦E£É–XŒMK ž.1³W[ª›÷=î€sðü½›ÕÌ–†úr¬Ï°¸‚ ¨;Éq5<‹qKçýØX¼Ìv×v³†V°>ì0àIç·ädafÏKš$i3{®Ì¶[ê·ða¿ßâ"5wpy¸x|Fv‹+‚F`)às3û¸•óÖž1³O[:IRwI§áÎ ïâ /Ã×´#éÊÀ·EÌìE<ÀïÆe¼†‡€Ÿ”q^‹$'•‹µ€sq§f6ÐÌv7³ÿÎÈ¢aqAÐ, ¼UÆyËà!œZã7øú§Íì³üIâ‘5†JZ©Œ˜…ûákªZâ5`Õ2úÖ³áÞ’]v¨¯­„ÅA#Ð_dÛƒq(‰¤Ù€c€= E ÀÌ&˜ÙîxÔùcʸæíÀz%²‘çy ÷îkföuˆVË„pAД+\hî¨PŒÙ€îe¤9ØOÒ-”â~,ÖJ{¯ãk«‚v&„+‚F ;å ×{´î˜ñ=žu{–NJkœ†[–qÝçie0y9~%i`ím „+‚Fà[Z·¤À…kPK'¤%ÇâÙŠw´\ §?¬\ÆuÇâ1[ãt ÍE©MVR^”žÍïK¬ƒ2á ‚ a0³/%üSÒº­YiXîpI/C$}\¼ŒÄ-œ%SÙ x¼;¶¥v“ÈÍüþ»³¤Bki^`<.<âëÐÃÝëó"õik¯#¨Œ® ÚŒ¤î-e ®‹p+çÿð­bfWKºøÂi`!\P†ãb²ð0·¤•˜~¸./L³ãpqú0øOÒ˜Í-ͬ$I[3™Ù¡mzåAY„pAPi¨lC`àLÜÊi3ff’öÇç®îmÍ:Ê1YãF¦¥ßãô5Í-¢1¸Kü4‡3ûTÒMÀ»fvX×ÞøO™ý ÚHW!©?î@ñ[\vlm>ªRÌìeIî“´ГÖ=îf¦¹§Ýà}|x0¥±ex"io¯¶}Ú8 XÛÌ&•QåhàªÜ7èB¸‚ (I²&öÀ‡Ùúâr£C<Š{é«×¦^j)+=™~MÒ»¸“C¶} °°½™}Ù/3ßïíðìÈ[—‘Ï‹3qw<3sÐA„pA0’ÖÆÅjs` >”1O¬x.°‹¤b¢47ð9Ó‹Ò£4·’¾(£/û^´‹™•¢©"Ò|ÝÁ¸olf/—Yõdàïföq­û”&„+$͈§é‡Ï[ÍÚ ˜ 6ÌDéàšDéC3›\‹~%—÷£$=\'é"à´Zy1JZİޙ(³Þ:xlÅ%kÑ |B¸‚  “¢6 Ä]Ã,( á"s?ð|if [sÔR†Yq/ÂCjèß"fö€¤•oI:¸,EŒ¯I áC}Ç—»Þ* ¡þØ£ÚëÕ˜äáWJ”Ä-§ÑÀ¨\y ¸6·}ð4°)°žZdE\Ìãs[ßâÿ½Ò¥gýè~,i‹Z9F´F’ûEZ‡u8p¬¤Ë»€çZsHÎ ûâ!š®–7³qvårÜ!ã¾ ë5 „+” | ¥Ei ž#jTAš{>®µ ¯Yl»ä&þr*ÿÍŸ ±,þg¿ °8ÐXxUÒÆföz ^vY˜Ù À¯$-‚mž ¬ i.ŸàsqSqËqI\ŒçNÇÿ lSŽk|!’NæÄ­´ „pAHsJ¥DiA<åüXš‹Ò3À ÙvG S™ÙWøZ¨'ð¨YÿçÃÅl9àIç›Ù[íÝŸ‚¾½Gòl”ÔXX·4»Ñ”sð&àOÀÛm ¿$éh|1óz•F¤jGW´)‡Ó¤¬L¢¹(Ä£gÛc«I‘ÑQ¤ˆc†.KÎ ÏQ$B{-ô|iÀzU -5$„+è¤!¡ÑµòTk+’æ eQêÇÉËiž3éæl_,Xí¤5i§¿Ö¯ UÐN„p ‹¤nø:¢ƒ‡ÍìôºnO|-R)QZŸ;É‹Ò(<“n¶olGyÛ퇤¹ñœ_“€5ÊÍù´/!\AÑæ~öÁÀöÇ“øQÃöûQZ”Â'ð?¢¹(½ ÜžíKó>AFÒ&¸ëý¥ÀÉ™'^«a†‚I‹ákÚvÆÓ´ü²Ì »AÂÔIƒð?‰=Ò®Þ§LnL2êÁôë–îÉ=oŽ ñIkå¶Á‡¦—®–‰ØƒMWPI½pAù¤ãûÉÙb_ÜÙ"[ÀÚ­ÄéÝÙñ(÷Ñd-ÅäxPK–ÀEëbàæ°°:!\A3$mƒ‹Ë¸pL–ô8pŒ™=Ue»ÓðïÝdÜ3¯%áZŸwº0朂öÀÌ^ų8ˆRÁŒË–x̺ÙL,zë÷§HÚcf˜Ù¯Í¬'>—µ žA÷Ràà+|xð+<.x\¼=§$ÍSÝË ‚ «WPÈDàRn`e< è`\HöÂÓYTMŠ:0x8¿?¹©/,‡îYÊYxIÒ¶ÕZ|AtB¸‚B ÓT<“ÒGü3mÏ×^NÙm‡¦2äy¸$0HRïH#36!\A3JD{ÈÓ=ÑQ}É0³‰ÀK©A0ƒs\A‹HZ•}xÏ_AP7B¸‚’Húð ¾(ø]`ÃpG‚ Þ„pE‘´©ADÅ‚ á ¦CÒŸð=qG‰5Íld}{Aà„sFÐ IÇ'¥Íoñ¨{géÝÍì²zô-‚B¸‚éœ{>p\ÁñW€® êFWPÈ0à‘Ž¿ÓQ ‚ (FWÐ 3;8¹Þý‚ (E8gAа¸‚AÒÆ@?`8ðVІAP1!\AG1?°DwIãpŽGä 7³Ñõëb® C0³ÿÔXœ»ðc`'`II³á ž‡Ó\ØÞ2³o‹4Á FWÐᤤo§rGþ˜¤á‚–•Ò㢒>¡ÀBKå3³{AÔ•® ¡0³/(žÚ¤;°0n¡- ,l—¶ûHÊ[i™°½)P‚ ëÂt Rº•©Ü™?&ivš,´¥€_Ò”¿ë3¦·ÐÞF…•“® Ócf_Ϥ2 IÝp+-µÁÀ6éy?IoSdèÑÌÆwXçƒ ¨˜® ËbfSñt,ïwçIê ,AÓÐã/Òãâ’¾ ˆÇ#02µA á fHÌìkà¹T¦‘¬´i>ô¸Uz>gÎJ+ôxüªãz36!\A#YTï§roþ˜¤Þ4÷xü9ðÜJûšâï§ù¹vCÒÀ03Ñž× ‚F!„+Ê$y(>ŸÊ4ä9_Òd¡- lžûKAñÅÖ_Ö¨kO/Iz8ÞÌži­BtfB¸‚ $ïÄQ©ÜŸ?&©>—–Yi›¿–ô Å=ß«ÄJ3³O$í <l(éU<Í]á9tEB¸‚ 1³o€S™F²Òæ§ÉB[Ø8mÏ#é]Š{<~^â:I:8X ¸øBÒ ÀUf6©ö¯.êCWÔd Nåü±öjqš†† Ò’’&2½…6÷œ<¿å€>©œüEÒÙÀáDtB¸‚ ÁH1_N¥’æ§¹ƒÈ†éq^Ü¡d$wÙ‘t)pf3:3!\AЉ0³1Àà¡ü~I³àv "UgKûIzø£™½ÐŽÝ ‚v!IA×`Nà` g çuOeàyI·¦º ¤9%mß×Û1v®e›ý$íTË6ƒæ„pA'GÒVø<×ÊÀ¬ÀxàK`ðð ð08ØXXØø¬ã{]’E¿tàõÎÜW¤K$åÛXø[›z´H A'EÒLÀiÀöx³w€7€÷hZD=º5×zwpœ11³5hfc\³6_ú× Ý aqAç¥p¤™-hf+™Ùfv‚™]af˜ÙÈZDíô+IK'éMI›JšOÒÓiZvÞÒ’‘ÔCÒ¯%)é/’>t½¤rçÎ!é_’F¦vo(¸æž’Þ’ôh²(³ý”ôI×HúXÒÚ’•t·¤$½*iÇÜù‡I:BÒå’FKºLÒ¢¹ãHZBÒ¬’^*RúIZ@Ò’FI“Úš=Õ?\ŸÎßVÒ 4‡˜]c¡Tœ¤×$ý:wì·é5]šúw¹¤Amý̺:!\AÐI1³ïRRÎvCRààd¬¼mfcï€_åNßx=õ©?ð[ÜME‡¸¾ä`½Tgrz&¥‰B wpªwŒ™3³!ÀÃé½ÊxÂÌ®NýûWzo‚á ‚ $I¶Â“sŽ‘t•¤…Óᛀ’VJÇß1³—rÕ_Í=ÿè…»å/€‹ÑtëÔ¦?ñ|ݹsÛÏæž/ŒIâ’ñ>|—ñJ m5CÒÀ©Àϳ(%’æÃÃyšêNæ(ÕF §e ¥úWø>ÍSfÛ3,!\A´ˆ™=jf›ãÞwŽLû'ãÌ~À>4·¶ZbnÅ­\e—òVÍH`Ióæö­Œ­´QIƒ«€í "íÜhf;›Ù©ø°džÉ”vt Ì]àu¸Z‘6‚ á ‚ $’‘´¥<¥‹pÑø wÊÅøüΊÀµå´ifâóR§KZKR_I›UÙÅ×p ìLI‹I:Xøw%$g‹;ñ9µ±’N¥0X^Ò<’6v+¨þ°SrN™=À̆Og$§}u€Ë*©AFW-aÀÞxà»pkéüiÍFâÂqu (œ1wÍϘ <‚¯+ÿóŸûzjøZЇç€,¸ð[¸›v}óW÷À6v~ifÙðà;¸ƒHÆ·øXÆ“øz·9ÒkÛ ¸<<•kãTü}:X ø³ŒmÓë¿+½îsKÞM}Ìøw Z@”õ@Ò७­IýðdŠýêÝ— 8’Žú™ÙQUÔ “µÌìÖÎÚI×·˜YYpg$,® ªBÒá¸eqIˆVБDäŒ ˜É/ ®‚»› ‚ Ý á ‚I=ñ5E+à u³Ç×)ÈÚ\.)´Qt8!\AÐÅ4Ó Ôb¸#ÀËøº¦³—Íì£4dž® 褤 »K1½H‰&º©af6©N] ‚šÂ€¬¨¸@½LΊªW?ƒ #á ‚"YQƒi.P+àë„2º8 ·¢&ש«AP7B¸IO{šÙëõîKP{rVT^ ¥¹uaEA3B¸›ÀLõîDÐ6Š ‚ÚÂÕ ’ÖÆï€–nÍ¢F§ãÝ€ÍÓñ7Ìì¡ÚÚ Oi°.0·™]–êo,‚ç2z¸DÝYñT ‹ŸwšÙW騦ÀsùˆÚ’ÖÁ#VŒªî•Õ¢¿ TfEe÷¯„ÕÂÕ:ÆÉõÀ“á-i3{.%‰»XOñp‚¤Íl¿mÝ<†ÇK6M‡² IDAT{*݉ßGÊ~8XÒÃf¶‘ºûãwí#€Ó$ý8‰èÎxŒ´?g—Ň.Ýö—#gE:LÍ*¬¨ ¨1!\åñ…™m i<Ôó9` \0æ6³‰’þ Œ”tQ.ˆf!÷›Ùi©­>f¶RÚ>øPÒyf6,_ÉÌÎÉoKºOFwžÐï&I'¤ì³»¤¨A)°¢2 +*êDWyÜ‘{þ"žÆ<½ø#)í7f6JÒÀñdqŸ7÷|M ›¤Ësû&à\3á’´™z}`NàGÀ›éºC%}„'ü» Ïô§Ê^bc#IÖΡ˴¢îÎ$¬¨ ¨!\å1!÷| нÈóŒx ƒRä3µžúáÂܾ ñ;ùBŽÃ‡·1³%]BóÏïB`?IãpQ»£HI}ƒðT%ç«hwÓ Ô¢xЉÌaâ^Ü£ïãRíAÐñ„pµ¡À’z›ÙIKàÎÏ•Yÿ\vKC|À4‡B6öH¢5°%pCîøUÀÀ)Àeùö:#)Ê€ßã1®²™ð¹¾B‡‰©¸8½Œ[Qgo†OW0³{%ݼ+é.<ÞÙföj™M\Š{$Ž–t ªg}Ü{°0õøåÀ%é:›Ó_t}ÚÀôŽÝirœ¸øM[Óx˜Ù«’~ Ü!iPj³&BAPoB¸ZAÒ`àj`ÇJæ³$ÍËôsR5©R˜ÙXIë×wJÚ.Å ‚ èÔ„pµ€¤þÀxfá’¢U†H]`fcÚ½Ó9Ìl‚¤­p‘¼Ï&AЩ á*¤Y€[«ÌìŠÜþ¼HeÃ~Ýhrœ¨‹H•Â̦HÚxTÒáfvV½ûAкŒpIZ˜ÇÌžªA[Â×@}<#éšÄªMŽÿö¯D¤RȦ¥ðĉ ¦2Wø»ðq3û´­¯#ÃÌ&IÚ>½–§ÍìÑZµAÐÑtzá’48·~ViC;óÒdAm ,‰ Id¶b‘ʵ=5¸5ðS<ÈîûÀ{À(©m/ƒ Úªç¸$í%éZIÏHzKÒ³’n”´Sr.hCÓ:÷è;èKqÑïÿúøb÷6\à àB3û¢ÒŠ’~ üذ=E+Ã̾7³=ñuf·¦ÌË•¶1ªqX­ûAО´Å9ã0`G`U`q|Ni[àܪ†¾@oà—ÀäT ||;LMuzko§…¶Õ²D·"$Í•êíkfo·áúcf§à.õվߧ{§×AÐ)h‹et?p.ð>d·°O:¶‡¤CÍì« Ûüof f;$uÇӈ̕JÿÜãü©Ìö˜æ™1³÷˽¨¤e€îföJ…ýwqÿ¯™Ý^EÝZ°ð”¤CÌìüJ*¦µ]Cpç–£Û¥wA5¦já2³CòÛÉi`;|Îi*.fm&9%|œJYHªôÚ[wVXI«áîê[WZ·V˜Ù7’¶ž–t¿™ «°‰óqÈ® :5YÇ•ˆ‹Àýµ YT)f6¹Â*[ày¶*åÀ™õNbfïgáD*­; ˜’¢àA4jג诓«„j…k|4‚ aérÂÕf6_¯ÔÌ)BÒ¥À7xØ£Á¸…6÷ÁôÎ!o™ÙxIÿN¡)fM‘Ô ø)°_…Uç¢B±KN0=Rø§ ‚†e†®¸øC‘䘅óh[ã I¼ ¬-i42©Ô´· žÏl;3ËGy/•»rû4͇³ ÊsŸgXj¥æÑ26+–Š&E ù+ðpޤS€KªH¢AP”KÂ[wÒá—̬ÒhèµìÃæÀéÀJföCÛêl,G“_(=Î‹Ç |÷h,*^kIàq`|¾*/lóãŽ$…Î!ÃÍì;IךÙ%-´¿n‘}LÆã.žÛZ~1Iýð€ÂýÚòú‚öCÒQ@?3;ªÞ} ÚŽ¤k[ÌìÚz÷¥½á*ÞÛñ?õÃêÙJ4xÑÌN+r,?–/ƒp mà_øìÌ}ºy4Içâ‹­gÃCepp†™.ѯ®'„«k1#W gW|˜ï3«ÆË°C‘´)“±èš¯4öz*ùzÂ_ëÑø<ÛÀž¸ûþ$¦wÝÿ+°1°$ž\Èö–t p’™ «é‹ ‚ ( „«fö¥¤_÷KzÍÌÞ¨wŸJ!i)à `[3û¦’ºiþjmàr3ûkA»sS|íG€r§Îœ·¶–ô8p¬™ ­æõA´FW ÌìI‡7IZ-¥Wi($ý¸ 8ÒÌž¨¢þ‚xn°¥ ™ÙÇxš“Grço\ƒ§M)üîôHeC`ÝëT<Š~AÍájä!¸ pWò4ü¤Þ}ÊH®éCð±ìË«læXàÂÖ^WŠÙx.°>¿UŒÌiC¸¶îä²Í-´ ‚6ÂÕ fö{IÇC%mÙÆ)¬ÓñˆöUM¨Kü÷xlé¼¥€ÛqGŽ xlÆY€I¸[ÿû¸·â;¸«ÿH`¤™}–ê÷Ã×§AÔ„®20³% ’´›™U™¢&HZf7pX¢Zœœ×RIËàᬮÇjd*£Úê¾AP-!\ebf×Jz¸AÒÀß­ƒ×$‡‘ ñ,ÿiC;?Æç¢öoé<3{Ø·ÚëA´ò©’§Üš¸Ý‹’~Þו4HÒU¸;úfm­Ù€«€ßGÒÈ :#!\bf#Íl]àÀ)’O.å5GÒ’.žÀ#m 6³çÛØì9ÀЮ¼81‚®M V‰™Ý%én`'à2Iï—÷·% ròà[wSß\¼îø’¶Mm¯ÜÖ¶‚ êEWHs\×HºØØ ±q牻IñKµ‘L.€An¬[WwâÖgµèkаy¥ •ƒ ‰®‚ñ^ \*iV\|6ǽñ–4_ÌûQzì…‹Õü@O` 0¸ODÙbàÚJIQ0îN1³kÙvAGÂUcRº»È¥"Ik™æN¥?¾þj 0¦•¤mFÒœÀÀufvA{^+‚ #áê’8} ¼Õ‘×M!¡îî4³ªdA4áUØEIVÞ½À#fvt½ûAP+B¸º ’–žÃEë÷õîOA-‰¡Â.†¤]³CÌìº:öc>`Y<ønAÍáê"¤,ÇçëwT0à4$¹l*Ëåž»õÇBç jJW@ÒºÀùÀp`53ßטO$™§åp×þ×q‘z wéÍÌ>Oõúá‚APB¸:1’ÎVÄ#ÅßZƒ6{‹3½5î™ ÔùÀ«f6º­× ‚ ¨„®NHÊÇu8°>Ÿõk3›TE; 1½@-|@“@]•ž0³)5yAm „«‘²1ïÇ0¼XÞÌ>*£^¦ŸƒZø §Wq×ù³7[ QAPoB¸œËp'\°f.–0³OKœ»lAYèN“@=\ÏCU 8‚ ^„p5’úâw×Mei<úÅQÀƒff’fJkµ ‡ùæ†Ñ4Ìw'>5®Ã_HA;ÂU$ ز;_*ó ‹Ïàbõ1°$°°¤eE€wi²¢.IïutVæ ‚Ž&„«$«é÷¸(ÞÀ#]ôJe0°pd:'¨[€Sðy¨ÉuèzAÝ áê`RàÛeÛÓãÚéqMõ8ðOàu3›P§®A4$!\íDZ°»4Ó{óõÁìf"uî(ñIºAЩáj# vóµ¾`7¨¿á5²N] ‚ ètá’´„™µ[¾«äP± Ó‡ÚÌ&¦ã ãÌìû‚ë Ï<>;ðnîü™~i?Iý€)f6¾H½fö]»¼!U ii`î"‡Þ6³69I:X¸ÄÌoK[Mšó\ÿÝÞ^7³Æ[SkfQ¢´Z€½îè ë½œ®·q½_{#àOé}¹÷ ³ôÙÌ\—¶³2èê˜ö=<—žO~ŽGÌ0àS`ïܵV†åÚ›œŽ/t=¶àZ¼’«÷fnÿ·Àþõ~ïr¯kH‘¾pp Ú¾+µµG½_g…ý¼Wä=¹°Þ}+VzHZ/iØ$3{24I½€UÓæfÖ,»°¤5ðu:ß™ÙЂc+}3m¾Þ1³os笛~/™Ù—T@ºö~øÝÀYé®óà#3;²’¶‚¶‘î¼ÅÿG™ÙÔ‚ãÙ÷\ÀH3û"wl~ ?ðM:Þlå³5ð"p*08Ø¡³}€í€ƒsõÖþ| lÜ‘ê\€‹ÛÀ%’ú7óWÏŽÄÿàîÅãPn…ßd\|ZPïDàyàïÀ?$½fe… nÍm?)©;Ð03û ¦Y"½ÈY”iü»ý‘™}XØxjk3{§Èþ…p‹õ`Lö»I¿—Ùñ|)©/~ó1¶Hû‹Ÿ¥óú¥Ý_YR¢ ­Þ#…ñï¹xè½U¯ ®)`üÿ½Y›’zã£xði¨¥wÓó‰–¬ùÜûùƒ™MHûºá–Þ,©Ýɹvû¦6Æ3á¡›©ëŠ9>,·ÿÁu^,wl 0°àø3L¯Ü_“»£Éí_¯Š»ƒ_§º¤í5Óö;5¼Yõõf½ï.¡PÄâJ_öosŸåûÀÏrÇ×Þ*ø®l”Ž=Qðýø’æwûaqÿ2‹ktÁþÒþËð5=†B“ÅõNÚÞ8÷ÞÀ×pMJÛóë§ç€ž©Îiß]iûð´=$× Ò¾ñ©'äþþRï÷/õ1³¸.(rl&š,ÙÝÒ¾{Òöi{qూïïÒ±Ìâú'¾nÑ€áÀOÓñ>øM^¾îà'éx¿ÜþñÐwSR»Ùç0.º†¯Õ:+W§:g š[½ßûµðž\žÎ;˜¥Ä9kÒü÷<¡à7›õél|} Ç¥Ç+rçšÿq«t®ÝÏ€mrçJûO¾KïG³7ðÒtb7\)K ׉iÿéñè‚ãÙõ:ü/û¢LVHç”%\øxþ2À’@÷´¯P¸fÅUxÑ‚º=p‘]èQplöô%>ö¿`A½Ÿ¥kŒKçõ+¨¿hêWïzÿ;èÇÞL¸€mhœÃ ÓöWøÝö<øâGn~ ¬™êl+ý&÷]ö>ÂUêsÈ„ë?û¿Kû‡/åÊ‹é;ž ×Íéü•Óö¹62á”û|ßÏ?4í{"÷ ×¶4 ¾TPN¯÷û—ú8$×Çq¹²b:¾þ§ü%pZ:÷®ô>vÏ}7‡¦ßÅo€_§º™pOuïNÛ§ã½ðÿÏ ñàÆÿHÇŸNÇóÂõð‡Ô·iÿ•¹ßÚpÜšÎßöÇ­¡±iû`K`$þÿ»f‰÷dó\ßâ{t|ö\?ŽÅ-ípY=“ ׸Õ}6þÿû}z?fKïáûé¼p+kBjçÀtÍ/Ió°©ÝL¸¾þƒ‹ë´Î¾š:˜¶ÿ™Îß5m?FºKÇo0³?™…sm/ ,Uï÷/õ%®qøŸmVçÎù¿Üo|40WÚ?˜¦›ð…Š´ ×?ÒöºiûÍÜ9«¿þ Ü—Ž›Žå…k­´ïâ´}\ÚÎŒŠÝÓö*¹:ýqQÌÄóš[½g·ð¾l„[ÈøO áIDATþk/»ÑÙ„¦Ó¬ÍçÓ¾ÓÓ9™p]TÐn6÷ú+ÜùÀgÒ±=rïqÖnfÕ’ÎÉ„ëø¬Í¼;üßqËeo\Å'àN…¬ƒ…fúXJÒjEÎ[Ò2øYæÁø~‘óŠq$ð;|~ìüÏðþr*¦‡â7`‘4LÒsøÄo«iÌÌò¿ÇñÏvüFää´ÿnüÆm-`¢¤+Íl8p>>äö–¤§$ ^~\Õ+k?n4³ÕseXîØ‹4…Â[ÐÂ,³ÖJ‘…^Êæ€f´$ðþŸönL;^ÀóéqbÁ9½Óc6_\Ö)ûmvÇçB·Æ?—i!놙=`fá¯ñwi÷’æÊµÙ#×ff}F¡¨`û’ô¸K*àó¬ù¾öεûmjW¥ÚÍ»Ã?Œ¹Ãÿä/ÀÕµÝÓãµf6YÒÀþÀn¸ªç9,•ŒÿšÙÃEÚ,Ævéñ3;-=¿®Ìº›ã¯í]\dÁ'£³±ûksçaf×'g”ã€uÌìZI×á?úo,çþ-é“ÔæaÀ“À­föj™ýêJ¼Š'ý\Ò_ñáÁårÇ2V•´¡™=˜&Y{áwß â–úö’–ÅoT‚Öy”&§‡i˜Ùÿҟ⮸5; ¿£¿-òLª÷FÚ›¶¿Í5sþgôyjó÷’îÃoÒfLJ¦.±äLefŸJZŸ£˜ÿ³ÁÌ~+éü~@jï8àÎÚ¼5cž”x1c¬™Jÿ×áS&Cñáì“pç”×ñØ^À’þžê.hfïæÚÊþÌ­àš»¤v¯6³$ØBÿ2G§Â6žÁßó}$ £¹ó 4}ÆÝ_˜ÙH˜¶  h,JIÇà7:÷á7'Y¬Ø,=J¾Í-ÍìƒToYü»–§Ð äÜ`ÙŸk›ðÿí{°WUÇ?«ÞÔFÁDÊGZ£–’â8–©ùHÒ™ÆÉfÊbj¦kÆI1•c>’¡ ŠŽ…Œ©)”N cƒh2Š–&äƒ ˆ^”ÕßµïÙ¿ÃïÞ‹—ß岿3{îoí×oŸsîïì½Ö^û»€9Q¶"þ¾ŒóÊ!æH¶UúM*áh4%5x :·Ói*D«áŽÈ[†6-“9qÕæaRKïB/¤o& L}ìÉT˜Ì‘g6)ëÖT\–©ngO®É<¸_È? yFÈG…ü|í»E6æ|3ñÂf×ПÛš ÛЦ²SÙ¨ý S›ë³{ô"Z9~9þ^Žüåè“þ¯ÆEÛb*,©W]»Ã_å3C¾9S<ïÄ/Dùd*3êKñ¿›Ìx îðÈ,èÈòp4•)u9Ú{rÀ£<7Œ¼«C¾<äéœx0ûœœ3® y3ÒðV†<±‹{27ëckö9ÿ=OÍÆ¾„ʤwF”'Sáø&ýçÇ'êfîÛ"ÒîÓ»?9´$SaçR?€< ™ÖV¸ûJ3[+?-ä›À^‘ˆ›³ZÌÏêßçîWðÿaÒlÎ5³{]«»1.SDOH³xòÖIn˜Ç¡‰6GWÁÖ:Í^f¶»»'u|³»­¶ND“÷)hõÚŸ± ]ã“.ÜCЄv0š”»ûSw?ÇÌæÇîðhŸrS¬¨ÎBf×™h5ÖFeJž†Vëÿîí +Øåp+•‘cIl%<ƒ^´W¸û›fv:09àîךÙRdÖÚYs’[ýÍháþpÈÏ¡ßMÒR—Äaþ3ÐÂzÚOKxƒê]’ÌzwGûÅÑÇ?Ìì“ȹi-Z8Þ‰^üë£N]ë]O÷Zïw‘vþ)t8û4uZ¹Üý<3»™Œ‡Sí ÞU¦Çç'šô?ikPi[ §!ëÍX4,kMV…«Æßp8¼Sãj2KÖ5®…4Ñ0€+#^È Î]Ìð=i\£ÑƒM«†ç‰ NzÖ¸Þ‹Z:š¼îGª¯Syª$kß4®È[‘óéÈ{­ÀþFå¹óÃV¯"K*©¤]#Å»ñf¤dœŸ½§®oõØvTzÕ쾞mñp”?‡æ!×Ëëkõ¦Å =ÑÅü©Ì4é3á"*×ÈmàîO™ÙhEZ}¤Ã‹¦q…¼*äd›ÛÌŽGG •üb4Ù¤ï»ÙoÓ¦ëýÑGZ)lÛ'"·÷Tï¤þC÷ãïȆ[PPP°#°9ÄL yR.lÙˆv0JX“‚‚‚‚‚ …¾ `„™ýØÌfšÙ=×.(è[(WAÁ®‰“ÐÑ–‘-GAÁ;F1¼k0³¢½ÃwŸÜêñì,ˆP$†<¹Ú€¹ûª(ìîîÿ­µŒÎ V»ûú¬,‘˜nq÷²äuwoÏêŒ@Çžs÷Wã{ ïÐ-È`µ7cw¹"ïâ!gâPùH´~ƃ$ÕÌ>@0ç¸ûÆìš =ñqí^Í~0®«“˜µ  GѸ ÞM|­â'¶z ;Ú ÂUh£ýY3›kfgGþ*3[/tÂ=»¹t?ŒXÙ3;èþoî5³tøs™ý*ûΛ¯áCþu´™õŸˆ~'ÆwŒò È `ð‡(›ˆ‚&,Јã0äÉ9°V6$ú|¤O²òˆìxÿ,¯“ ÅMhúY›¶46tVfXV>æVËÐh—H@-}WÖçàZ›mÈ’ûBBš‡£‰ä¢L^‹<]ÓÌS¢þXÖçsÈë5ü¼ ʇ #ê³ ×¯_Š:‹BþZÈ7†¼ML¿§â»Û#îiê³yÿyÜnF^¿—ÇxßDç#Œ¾¿í¡sDNDŠ@§‹²çïhr{O«ŸMI}3µ|%õÒƒ­˜.@ú]OÅXýð¬M:§—¿ ÎËÊS?S©˜/ÖÇDù!‘×ò¬¯ŸQ±k< :?ˆ¼;³ðdd꺑Æñ,>íRˆ[Bžò}h’~i/¢<1<ÙêgÓäY¥‰ê+!§s9¿ù—42; D´fSÖóhí^¤‰«j; ¦P]M\³C6ªs”_¥qâš”=1Ä/ÉòïÅY^ÎV1/Ë7*†1(‚€SZý\J껩˜ û?ŽFfŸÛÑËg>Ús¸™örŽÀ»Pd€£P ÂÁÀUMˆ‰Ï@{Yw FŒ™±ÇÑ>&©ÇeÍ%µò“ў˥1ÞKÑ x%¢"»i³£þè û™f6MŒíè¥ú¯¸–=Љ|€ ñwFãl%«Ëºø›ØRP½D²zšè'¢ƒõk#¿NPü¼»§MìÄÓF÷x:ù‡ÒžX½MN¢ÚÙrÞî¡ìs'—e|Oâû;ÃtĦRPЭž9KêD¥q­yÕŠw_´¿™‚@&¾Æ‘è4þ44Á½F#`Ò¸¦„¼gÖçt¯q¥ CN“ƵŽ,ü _ÙY!ÉúJÚÚ~Tœm\rQ–%þ­êW!sÖ^­~6MžUÒ¸F„œX_¯fÒ.S¨Œå!Ÿ×–øñþåIãz;žÉîTZÜùQ§+뱨gݧiÔ¸Ú²±O Ò¼÷AT@‰¥æÜ¨sx\ã ˆ4 ª¦>†"í>ñUþõݾÇ%õ¯T4®þ´ºM«ø×ÝýY—Wâi¡³ V”áHëI¬Ïõ•|â {™Š±y»Vò4†>ɱÈßÔWò/vQ–Ê7ÑÈk¸]Ãñˆqào}'ÄŸãï (ÏA]Ô[‡´ÒÕha±Ž*ÄDWØ-ê/G“âw_ÖMý[Q»=Ñýÿ íþpCD˜‹öD¿AÖbv„ËÀÝ;ÐÄ™œKêÌ< èɼS°ó£Æ iXDo5±XŸjfû£ý‹f8ÕÌf¡õ$ôqôÂê “ÌìçÀé!×ÉŽë¡þ‰¼Ê&˜Ù"*SßFªFW#g¥È¼9×ÌÆºûfw÷9qÚ“ƒ¾ûBü)ú-¦0B3Ð^Ý#!/DnêÉÜv1ºÇFÞcHûªP?‚œ=& gªWnó3ÉoE­ÍµH3:iG)&×[TôpÏÊÝ·šÙ hB:iòËP¨ö-A¦|âú¼ÀÌ&¡‰ô0*º´ß è+(znAA×hµÊWRï$¶ CrPȯeu’§ÙÁÈ ±=äG»ò†OŠúÉT¸:këÀuQÞ©0o³85ê$SáìÚø?ƒ&)§2!m%¢M£ߎ&¸Ä0ï(~Ù÷'SâZ2Èþœ¨L… ÞA›d*ì’»Ç{U”ß [}ÿJêû©h\ý aHФ4…Æ o—¡½‹vwßAõÎF&›YÈâ#è|NŽï#·ùCQèßFþšøŽMÆ3ñ†Â/ˆü¥Ñ¦!§»?hfGæ¥QÈTx›»'­cïhw‹»¿afßC‚™ÙnîþŠ»¿ff³‘sÇMî^xWÐ70™(ï@.õÝ¢0gl7"Ñg‘¶4;êAZÀæ„8èz,ò^Ü8Ð#lAß‚™ C–€M=V.( ìqô_ƒÎ.½ˆ»–I«Â3*ª‚‚íÁÿ1t³ OXxIEND®B`‚openchange-2.0/apidocs/html/mapiproxy/mpm_pack_pack.png000066400000000000000000001416351223057412600234070ustar00rootroot00000000000000‰PNG  IHDRµ ˆ3ûÅsBIT|dˆ pHYs × ×B(›xtEXtSoftwarewww.inkscape.org›î< IDATxœìwTTÇÇ¿³½°KïM;öÞ{ï½Å$FMbŠÆXbª½E£&QcîػØ*¢Azï° l/óûC×T0(¨ïsΞ³oæÎÌÝ·ï½ûfæÎPJQÝ?j˜TFzmÊHŸÀºŒ:†•!Û@ƒRi<SðJ¥7гŒ:†¨Q*ÍÀ„2dÛhYFú§,J¥y\†luK¥‰žêÌ.•î  [uŒàZ*Íþ ê<€w©4 €)eÈ6йŒô1œJ¥9S†lgÍÊHŸ@R*ÍÀ€7¤óö¥Ò\Œ,C¶ßRiì§:‹J¥×ЧŒ:ð*•fàÓ2d[hÿuþ¯÷Ï»xÏ—¥3sÏÿ?íMßóCP:£:~°˜•‘ÎÀ/#Ý «T€¸ Ya2yzòI©tauˆpÊ©³à:K^ ³è:s_ siYA9uf¿AEeèÌB)SKßÀìü¯‚ÒÿëKtæ¾AÍÊÐùE×â¿t~JY×"÷×¢è×bY:ó߲Εqÿ0÷ü¿ufîù×")q200000¼Ó°ªZ†Ê‚1j ï ï„Q#„´"„¸Tµ ÕBˆ˜2¦Bsj„žLÔVzJiQ9Û­@F)••Sž÷ôb¨D4yéïÄ\-ÃûÇ;aÔ!|J)c¤þ…iNí]y£î À³ª•`````¨¶tz'zjN¨¶^t U ¥T`O¥µâûzQòBåC1uãÚ‘Ÿ]Ò#•Q/¥ô?y[20000|TÚð#ÕQ;½x›&Ã0ˆ-!‰ªhÃ܈¾òY•Uu&þž¿ÙÝcó4Šü ŸÏ¼Ô0nfÜM¾Rž^n×U†w›T¹Ak¿NÙb-ej(Go³~ªŠ¸¸ytS«»¶)™vsßt÷ã+Úw®È}°aHÃ#‹›õ€Ã‹š<¿qx}ˆ¹½SâÿK½ñ»g»,|QÙ»§Õ8¾¢}ç«:u?¿ÊúuËÙu}›]Úª×Ëd®ïšRó௠F¿n9‰wßêºáJë©ÅÏR´6j©G½#Ò6|¶.ažâ~A€v»ì²v£EgÞ{é2zT|mǧÿPP.a±å/¯ói;j}ïZ­Æ¿pýÝÎYëZ ^òƒw›I…pbE‡« ¬bY,nº{Ã~‹;NÜûö~ÃÛâA¦^òÉ‘Âl—Mô¹ £Eä7Ö›_V¦Ý¦‚7>³<`:®¹2w¦“„e ”í(aå¯í'¹PÇ–Süæµg0‘}ùsº¸ïµ“»uÿO<ÄÝÝ·P¯UvÈM©ãÖÀIYžzŠó’j¨Š²›8ÉbsÕlO÷O-cÐk¬]êõÜö¢²)Ïת [sùâû!§Í?¿2aÜòŒo+ú[X\¾ŽÅá½tÙ›+0°Ø\UEë6qò÷.A“Öù¾nùŠRiFMohÊ⓾ [öøQç´¼¼£Úúyÿ¥nBˆ€|Ji~¥([I™3’Í>»4åeFq„»gC¥ñ÷üÍ¢on­Ó}Úá`WHƒOüloЪšFßÜÚ4)üD^©‡ÃÀ«Å˜ÉíÆü™tà'ŸORžª”§Ï<ð­·{ƒ~)®oj^¿ËWAM‡ߨ=­¥FÒ~ÜÆÐëTäʶ‰ukuH¿¨~«¡ËïØÖh®}–·ý£:ÅyInVÎ ›n>†ªcé5E³6nܘ5}%AP¨¡Ï݉2ƒ0$]o9¸.?‚Ót §C5ÎR>Ñv÷âåÀ­©–»D\b{@ÞyÕ ¥ïªÞ’Û!:sWs¶êìc­ógÍ…±\6èùX­­ƒKÝÀSdjï^šÎÂAÂR¥è­Ç4$sÙOæªuQÇÔBƒ¸C ^–¯#ç½|­,¸|q@ê£óÃ, ::Ï”² a={™ÍI¼Ë»¶srƒ^k֤߇½š.ž<#Îo6 ÓXr¸‚gÏ36W âðDÚÓkz´Rå åð„¡y)¡õüìÓqįQ[Mrk8¢QYg€'4¿6zQüš¼Ô0îñåíî…ž]bëÛknŽF‘Ï:÷×ÀŽJyF=¯–cý›õÿõÙ‚Ñ3k{7/ȈìÁá‰Òû͸¸ƒÃhÙ¾Ž-kÓMd—Ú™+¤÷˜vä¨Ä¦¦žÍèY\þ3C~~•õ£k‡òE–)=>? 2w2\Þ:Þ[)O·Vç9éÔENÍGú·´8ãØ²6Ý(¨hß|¯/¹|³Œ¡?†:±ªsû¢Üøv¡Žµ;î<Éïqeü'„€Ö•6ühTQ¶ˆÄ˜ŽE>5á"EW`´­„êÍQyá¹* ‹«2hUÞ7÷Mw =_le€}ó½¦ßÜûÅjYfTçݳ]üƒŽÎsÌM v¡ BEAjó‚ôÈ¥ëã ÍÓ}Ú£‹¢”§÷ÝòÿöoEAjyV´hÇwv›B|—vì»3m·@nò}^JÄÿ{'~ù»(7¾Ã©5=NlÒöΫ¹.+.p”FYàšðÚC •‡Cô‘ÙÇG9z3òɳ%*#öÊ»O=ZÔýÐCw‹¿óÇä)ÜÐ ½¥ÁöÅ8­ÛÍ$céú%ì¢\%5»›¦³üäpш þ…ýï§ëòTF^‹¿óÇ®¿­löʼn¢žwÉzÀÃ,½ä“Ã…#'*ì6FãÕôϼ‚ÓtÐvSþèc4µâò VƒTõßÖ9yWY8ŸÓ*eÝ5Š|VüÝýÃÅ–.‡JæŸZÓã”^§¶dq¸Ê뻦$†À±åm÷tj+ž@’V\ò™I¾0;¶W^j˜µ[ãd‹ËšGZ»4z¨.Îozm¯pçðl§âüäÏJ…[îIAEVÎ °ïÇZûTEÙ^b ç/­Û¸ÿk7Ø9Ëñ¼´ða–NõαØ\…ª(‡•ŸÑHžÓ sú§E]ZÉ7³ŽÓªäG–´Ø¹É÷Ý‹râÀÙõýš„œYüPj«QÉ\-hü7ä§=hxw­A§6ç ¥©‘WþÜÖ®cˆÎÂÁ'ÐʹAÄ¥-c}òÓ|iíÒð¬¹}­«:M‘ ÿ#€¢Jë©ÑQ>—H! òŸ¢¥ôÞ­ãMÐfÔÚ#×v|jûø–ßÁ˜Û;" §­gÝØUùˆ«Väõ·<½/‡+¤‡øM¸ç?h䂘¿·c‘_¯ó—[vŸ™gª')üø'IáÇ:ua7KÇz¿¥F«]¿™Ñ¸ÏüìK[Æú€Rþø•™ŸÀŽ™6»/lQ¯~ׯc)5š{4>§ÝØ¿,nš“xw€pƒN]ß½aÿ™Zõá—®â»s­{l“}b)$òÑ wçv?|”£7K–lnOµÚ Ÿ/j½9XUkvqäo—º¿Hn•¬ç‹ãEm 5T–¡÷XÕÇì((´Fñù­6‰¸Ä°1Håé$aågqêþ‘÷i\¾A…j4Íâ1Kûí©¢;BÔÞuí8Á**™Õ^t¿¾=§\¡ë>tXlŽ–Ë7 Ø0¤Z™ß§ÝØ¿Ÿß0ôW¸°iD=›“9ò·¨Í°{¶KãÓ‹:ɳß5ŠG-Œ]{æº5 ôùÞzË!ËÒßò+[8=î8qkìñíw楄ŽÏ´Hê°×$«.θýó¡FƒÞÃÒ±îgn ú*÷íJÅævµîO(½–üàÔ@—º=¶´ÊfãVf¶ãp…@pY¿K`f}rðÜ SNmÿÆüzÌí’’ùy)¡ƒf6gxBsOh~/3öÆ“ ‡+¸?â·¨-à7ÃzÌU¿½:NÜs{‡®×—'ïOæð@fz­RØaüæ ‰MÍJ[{L)Õ®4£Æ!]—…gŽòk:)ÕÞkMr*«ê†“wgõ¨Eqk¬ Ø0¤azÔÅ¿.ü32¨Ñ`¿gŽû–§¢„ËG¾¨ž@#”ÚÇ7¸`‰ƒg[MÌí‹“ܸÏülÈMiÉå›…›ä¹éýü´ð–b aµûw"8xµ ¾µýK°vmücBÈáñ÷Š$Ö5þ:?äð›9 åÅÅœ­Þ9\zÀåÝ¡j·9Ń»xðÒ/Äió”Ô¼ãæ‚a@) âr_ø2Xßž“í,eï!=Ïçã…8­­«9;CÄ}Ãòf’ε¾='Ã$ïiÅN?¥qiáÂͱ³òlÄ,-´påfl RµqÉ)-„WÇ(ÂaÁ8¹¹0pj aÜ>ï<6îÍd<¾²†Ã»ÔíñlΩ07ÞƒÍᥚŽ9åà˜ÒõP£^ê÷­ÕQJ©Pjçµ¼tÏ®QÏYGî›ÿƒß kÂbRƒÞ~âêü~/Ó_ ±Ýçÿkƒý®0Š'²x¤”¥b±¹éF£ÞÚÁ³í —-¼.ÝOÍÒó3ç—EéOüQÑP“bt•´àpáKzð©%’èË›ôjuV¹†Â !Þ$ô•F­<¼†Q³ x啼-£VÕ˜ŒÚ¤?ä­ªZ—’0F­zb2j÷¾°ÚYÕº˜xŸZepàgŸ•ò̱ö­çôþêÌÝ7ٖɨõŸyåÚ›l§¼¼†Qc¿±)¥~ø°t¨£³rª7¿ªõ`x7¨eÍVLo-º^Õz0”Ÿ§kÔ¶¾R°¿"ãë·ÑΛâi8Å¢w%J?CðÅVƳ/Tµ ï6b–ö£&‚ĪփáMÂ5†÷†w¨B,Ÿ†@a`````ø„.!Äû0jšp®j%ª-\ÞH@UëÀÀÀðá¡ÉKW^ü?x(¥JÇß £ö:æÇsSÃN1»eWFeñ;³×Wf±‘·'LmUÕz|¨dßê^[A¡Ì1žú«ïkïUÆðß!¤°Â±HßO£¦Í7Äßù‡ܪVåCE«P¼ ‘drýÃu‡ýÃuïŒ~¡ò^)õöQ( R™} «ã«Ežç½4jZ­6Z«Ízµ Ã…VdeÕS 10®ª§Ò"µW2o- à y?!Ä@&¥ô•±Ò!€3„Bæí»*QB2)¥ÕõNb©£yU«ñ!CtJcqAV*YUëR +±eMGf¬§jQd'äÈx¥ Bˆ@Ïw¨P(÷p–™¥½…½gEÖÌ›V@©Š$FpÙ Õº»,€€Ôô¨«Ùz\¹Â¯1T>w|aQ\P=/W_cýþ¿É«Z•ˆsËÍã²ËîׄÀƒw¨QJ£+ZÆÓ·¿Â¥Qßjwð}&'õ'1:à_{)UGX"3£­KêÛ›d¨R¬<˜ã*‚V…¦/žŽ Å2îª ï , „XBžõÚ!.„fSI†w SOÍÀ1Bˆ;!d€MxâjËÀÀÀÀÀPí!„°! ”>$„| à€)¥ÕfÑSCý:sk bÃLÃÖø@<€yO7\«…·uf sSWzVªªÀ…§z100000ü Ji¥t³ÉpIL¥”¡”Nõ4­Ü<è-ŸûEñ‚ ÚÍù§´Ó*YYeeô5Š|VfÜM¾^§zn [fÜM¾F‘_n#®×©ÈÑe­{@عå6g×õmjÊ‹¼ú·ÅÑ¥­zŸøÙþEe3ãnòËÒ£"å&pŽ-oÛõUrG—¶êùºm|¨dÆÝäï™ë>ïøŠöK¦ïýÁcæ‘ÅÍûV¤®³ÖÝ>4ËüfX6¥ü­Á¨3löø¹îÄ•ÝûƒÇ·{æºÏÛ7¿Öçþà[‘kô9¾³Ûvn¹ÍËdvÏqýõü†¡ ^§þ;‡g;ÝØ=­Æë”}Ÿxxy½åñí;—þœü½KÛªÖ­,ô:‘eF=ç/ËŒâœZݵ͡¾ÃÎýÙ¿±RžÎ®Œ¶öͯõEäտߊG4 (¥4!„캀O)­ÐbH»‘|¿Ú[%Íx,¿7¡hepfmïž§×ôˆ;º¤åSÚ±emº^Ó#îä·­²€Uþp d%Üv*ȈìÑÛ¤AGæœÔ*eÎzuq™Ë6¯ú}ìsúžÏ­ïh×,§€³ÿ(ÊM¨ðÒ yv ·0;vÄ«ä sâÆU´n{çÕœõººwyÖc¾F‘7± =â;SÚé?z¶Tå|¤¥v«H]F½ÖÅt-ظ6^Jy:»8?ù‹ÁóîNñkä ïuQÎd¡Ä.Œ'¤eÆ^_tâ÷ÎC_ç÷غ7ßèäݹðe2ö­¸5ì—ô:õ'‡Ÿì’yîµt{Ÿ(Hh^œŸÜº8?¹u~Zø¯²¬èqÅùÉ­‹ò›WµneqmǧÞÇ—·Ûe:޹½SrdIËëòì˜.½F’4ùþÉ®•Ñ–F‘×§07^\u½ B¼t€ À…âE)-w!ûåZõ]Õ°9ü» YÚ0û 0'v$›+¸SR&52@~á÷&n½'2wz¶N%þž¿ÙÃ+5®ÝzB˜)Í£éð‘ÄÞ?ùÁ)Qè™%£X~´ÔÎ+DUœ+J =*®á;H!§Úé´J6°XœÄ‰«óûéu*²gŽë®‹›Gw4çöYàÉïŠßÇM}{Îwòî¬.©×Ùõýšô~ÛQëîÚº7Ó8zwú¢®ÿcžŸanÔkYEùI6½§Ÿ6•q¬ÕayÉ:BN/´ËM ³ë>Å?xÒ{½¾{j'?º¶É·Qïî¹5諌ºþ¹N]Ô¤ ãQöÙõý¸­†­ JìŒWü>n¨*Ì´·«ÙòQ›‘$WÊŸR!,%‹ÍK9¿qxýîSü#òÓÂGòDG¨Q/€¼Ô0îå­ã+åé¸é}Ÿ¶ïjÜg~¶F‘Ï:ù{—ÁÅ)#¹|³P”س0?=b€[‡øþM»#KZnHl®Àˆ_"w@À†! óSÃ;ŽZ»ê´ÿì†OûÉòËš‹ó“‡ð×(òYg×÷ëZ˜7œÅæf»5軥ý¸ pbUçöǫ̀aƒÖElá¼ØOáòRÃg'܉×( ØW¶´€Ã%i”…Rûã]?Ý»×Ú¥‘.7é^W6‡λͤÂÓ í¢·Òªd-„R‡Ó]>ÙíoíÒH·{Žë¯B3ÛâüäQ,.?ѧݧ«<Û*dé#ÇL»z6n7 ÄÖò´èKŸ :gBXEÃ~ û¤ä}ô¾Ònì߉ÀÎïìj˜Y×86xnЩ£K[õ¼´yŒONÒÝÎ<‘e²£Wû°Ä°cƒŒÄÒ±î…îÓs¸BzióUQ¶¥º8ÇY§.vòl1ú@ó 3àôš­äÙ;RJÙ¶5Zï>Å?âào GX8Ö‰ÈIê+¶t 0ëúe“.wÏvJ¸h¨ØÒ%¬÷Wg®s¸BzuÇ'ž…9qÎ:u‘¥FYàE@tFƒÎuß|¯/Å–.áê¢w®Àìê˜%É ŸV³­äï;»¾_“‚ŒÈNÞOtœ°%-l<ÄʹaDfìõ>|¡Eb—O÷œ´pðÑÀ=_¸§Dœ!¶r½ûNÿ3L7œ€ ¦È Vrߦ"/ƒâJ©”pF,/€è÷íöàâVF£ÁšÍ<3Þ‡ø½øÏ¨ý²ŒGÝüRï乿ùÀñ•:]ÛõÙ¢Üøöw}ÿ§I>úÆæ ¡Gfå§…‹µêÂúÔ ·“eFµÉнÑëö¡Yφ–".­]˜Û£¤.®Â.Öª íàøŠöþÚp§<3ºÃ…÷™†6 iè÷­ÕɼÔðþò¬Ç®íœÜ!-ê¢(õáÙM¸µåã[~~ñ÷þš—6Üï[«#™q7ù°ÓÔÞ®ïxùÏyÙ w†î˜i³K)Ogç$óS"ÎìÜ÷õÚ¢Ü¸Ž—¶Œ9wÛ¦KNR°•Ѩ·Õªdõd™Qm sâxûª½#/%¤F‘_#)üÄ°Êø?ª3æöµd'Üžüà”H¯SûÍlï›ò.o?X]”ӶͨuÓ8ŠÅâ(ÛŽ^?I«(hziËØá Ó×Wç˜@ø…5ëÄÎa½§ŸùX«’{_Ý>©/è5ŠfÊÂ̶­G¬žÌቒnÿØ¥n•ØÂÉ/¶>6aUöÇ}¾>w'5êÂwv5[mø{Þк>ŸÍYV8~ßûDQn ”‡gWp…æ©VNõ£ó3:‰¤‘–NõÎç$ß›r|y»þŸÑ0;1h­A¯‘r’´‡—×ï€[¾uÍI žcéXï‚…c ­’Å)§?º8_lá|¯0;vО¹nóà̺>Í]ß´U(±{T˜Ûsß<5Ÿî“›to­V%wµpð¹*0³‰!,–ÌÂÁ'ÐÆµq‚¹}ípº¨û_êN¸í?Ó¥äoØ5ÛyY~Zx©MÍ ¤°ã¿œXÙ±#ç%O‰8ý£Pj©”gt>»¾ßçpî¯A¾±w÷l™;†åÄõ4´•ígñ/!|BHK“Q» ` €¾ÖPWtøñ ㊠Îñ½ ±•›Rø‰á‘Wÿ*’:.™WœŸ<©^—é“Ç,IZdnëµ>7)x8È3£Æ¸Ôé>kÌ’¤Å>[K×éÛknŽ™•ÛYOô`ÔÂØõu:LÙ£.ʡשHÈé…v½¶V¯é§€ .;¿³ÿÛï[«“”Ìõœud™Q×j5~öèÅ +}:|6Cžõø#ÈN¸3ÆÜÁ{íØ¥É¿ŽY’´dÀ¬ë—þõ£(åOX•3qÜò´Ùl® 6èÐìçÆñ¯lÿ¨5ÍÆ­ÈøfìÒä_9\Ñ㋛Ǵ}RÔhÞ°û·ßY’¼P`fëŸqº{ûqØþcKǺGF-Œ]oãÖXcÔëjz4á7rÁã£Åÿ^9ÿFõ¥Ûgû¯êÔEmïž=D ¶> Bž-sQfö´qk²Ã«ùè¢ß]ۣשeÆÝäæÄu“Úzîõi?Y>dþý£„ÅÎyY^ÍGqøâÀ‹ÿŒê¸Mª×*›÷˜vø‚)?+áÎY ·ç z—¦ý~ö€ÂÜ„þ„°!§MÈN êf4÷í–{c€ÈÜi_Ç [âøb+cÛQëþ=œHˆ¦ëgûwx5]dãÖd‡ª0»{ÉìгKl­§B–ÖàâæÑŸRv±,µ¿)ßÁ«ÝöZ­Æ¹ÕïsR§.jSÖoâòÄQ™±7æZÐh˜ƒgÛBWøÁ/Jí™|¢ãÄ­±}¾:dáX'Q‘ŸR‹Íá§* R{›ä8\὿Fmúcè!Âbç]ß5¥¦FY  Ô(ÑiŠÍZYÒkú©{&y©}­í¾¿q©Í¨µ?hUò^ŸÑWjãñ÷ÀÙÏ úI§U´2ͱ8¼ØQ c×÷ž~:Xjç•@»¨×—'ï·±:¥Ç´#a.uº¤UÊ<ºñÏñ3mý\üÃ*'ñ.O¯)ncåÜð4›+T ¥ögäYŸM×X:ÖݾðãÓc³7­DUáäÝYÍJ¯px¢ï6“žM ;x¶Õ;+äôB;HtÑ—Ãß6Gðàæ¾éµ 1ôh½ò´cåÒp§,ãáuqîк¾8ðÿ¢í8qkìyÁ'ÄN]ý{žÄ¦¦žÅ„¹Öï½tªìŸ~&‡'¾´§ÉËÚ2èÕuMß5*Y}‘…ãý’ùÖnYì'C^O>9 û)ü,´',¶Ê`ÐòMǃæÜ>;qu~ÿÚ­'~^¹à¿xo¾+x·ýäk—FÓMs&DR‡39IÁãR#„Ç–¶ÊæºÔí¡’Øxœ/ÌŽžüà”èØ²6ݨÑàôª6zL=NFs…,c²G³{Ê”™väO¦¸ãõ]SjJm=ªymëtOìõåÉû<¡¹Ò­a?…GËã YÚˆ;‡g;OæOÿU¥â ›F ÍŒ»ÉÏIº;J(±;W2»åeé„ÅÉTçÚvž´#´i¿Ÿ#8<‘öeú‹ÌâõZ¥‡©7p៑u»OññÛ£e,6'--ò|™žÀäÿ·Šª8§§³O×uƒçÝ=eÐi,_UT–Åé=ýtð¸ߨÕl9»0'XnòývpiËX6›ëàÙV#Ø^,È|Ôx2·PÒrȲôÒõZ9×Ï£Ôøì…ãö¡YΦÿPbSSÂR³ØUûq‹S£ñà#£Æ®µ0v}·Ïz™ÎB©ÝeYfT;àÉð©Ñ¨wå9ª$8–âID‘/üÀ ÀTT *>$ÌSø*#ôíô2Ú˜? ÿ’ïÊ~àõ§ÙÕJ׺³$iqYéf–®~áçÿ'êÆ–ë¥¬‡ƒg›¹`nçµ'%âÌŠ½?x\Ò©‹^j`Lôýæü­íßX,as º~_–L×Éûv_Ñ~Úõ]SjZ8xoJ?±lßžW@Xzƒ^m;viÊ/¶îM÷dÆÞX¸w^Íf„ÅV™Y¹…Ôí8-´TUdçwö³8¼,ƒVU¿Å Å¿<×Χ{íüÎ^¾ó;û¿øb«»:u‘‡¹}í³¾½æÜÇ Jn¤?œ¾÷¦NÞ&?8õ5_dy_¯U:s¸‚Ð÷uX‰/²4p¸‚`hÚï§ì¦ý~º<¡y®VU íÆm8|mǧü‹›GïæòÅ!Þm'Íž YžZÝÝéòÖñû9!¶ž Ûwœ¼«Ì—ÑÿJzôeº8—ãÑtxqyäS#„é¯X´´ø™—ùöo-ÏÖïòÕD3 µW«qÿš»Œ½»WâÕ|t…®m¥<ýàâöÞm&e›¼K~~•µ…ƒÊ­A_eyꋼú·…éVQ®íøÜ2ö®_>¥´Bžõ&£Æp @8žôÔx”ÒOÿ%ü£V*jÔ!m¤”g^íeFímrëÀ·® !‡'èµJï «r&¼É¶LFmÜò´Ùo²òµò“w“n}ÿÃ<‘Å…Ñ‹âW¿É¶CНíütã„U¹¯½v±²ùPZe`2j&€÷е§SfCL±5z=ÝaZN)­ÐÎlo/]qÁ{%§×vmûàÒïÏæ CÏ.²»wêgû{§Ö<½®[Ð(óYgÿìÝ"%┊ò8úšÊÄí”\ñçyu½å­ƒ_»™Ò•òtöÅ-ÃëÀÅ-#ë%„4;õGçö±A;%%e6 h|ru‡Î1W¥õ¼¹oZ«Ûw)YÆÄƒK¿[_Ù1Á»²ÎIeÁ¢”^1}$ãÉ"l*ÐXkàçÒØ¼Þ+RžYè?}KaNlçг‹ü-n8 bîîyuÝÖ¤ð£sU…™·Œ¬w௲ÌGݯ옰ïÐ↣$Ö5õ¹Iw'øÿæ3Y£ÌgÝ>4cƒ,+ÚK!OÄÜÙ±ÍÔÆ…ÍûdÆÝ˜ ©Îm¹¹oÚ†¢¼„ö¿>ple«Þ°q`ïü´°~Jyzƒ ÿ =xf}ÖrÐlçlÿÄð£3TòŒú!ç,©ÿ¥­£ê†ž]¸Ã ÓT›¡HB!lÎÓ€ƒ$¨  ʱøÚ ¤¬ˆ^òÍ%mBXP¤®TåóÝY{êì“VZpdBH7ñ”Ò·¶%xEˆÜ&¼úw;Jl[·¦%w¾.‹œÄ»<Û͵ÀÓ­7ìbK—Ì®Ÿî­®.Î ÿ‘/Oµ JÕyhôà™ñ‰r÷é‰ìÆWPÜø³Â(“L_?Y¿´"£µ€msgnÂ×mDá^ÖìêâÌÅPADæNG†Î ß°Ô6ìüò]ö!lÙØ%™ŸÀÞÝ’ØxnôýÝ÷ÏüfqiÍ.û:ŽßþÃÅ­£Ž\X¯>›+HôýÝ“¸%é쟽Zöúâ윘ñ6nÍÖ™Ú“ÚÕö0óæù+;&x§<<ó €3OË ôŸîžs5» #r€[¡çwçòÄá£$-(­wÄ•µŠrã?ónóég--¯NÁ $Ƙbkõ°@ ¥t€ëx²ö+¡:Jø®¬ÓuöI[6²l+mÃY Š5Ì­ä^[ªé~a'VvìxëÀ·G5Š|O­Jîšvì»—É+åéì“«»Þ2gÆÞæ&‡l+ÎOn}eêöo,.îÿÿÃûß}µ{PªÎãô‹ƒaÓ­¶/ì&¾$âç"®¨tô¹Xw±Úzé…F¡é8En°ßI|aïHó£Ù £Ùœ€âv%å TF®Fÿ¤#LßKS¬¥ìÒiF ¤Ê cµnöþ`éP7 õ˜“C©Á2)ü¨¸i°IF¯)jiW³U84éýS6¥Fi\ð^‰s*‘¹ãºhP½N_=Û1ÝÂÞ{g^Zظ»Çæ8 :Ç^ŸŸ¾kÊs©Û3 ÚÞøØ¨×Ô×ëTäÔ;ìœm»71ìè­² žA§¬ªÂÌö"s§ ²ô–g=þͱîêjfЀ'ëbwšºŽ*bÑ„ ÜQÎYs–Ág·ô éØc•YPH«‚ôÜ#šö6CùG*CÓò­O« 2M°pðY6hÎís¥ód™QœË[Ç÷Ôª týÆ¿nÇi²€¿÷5Š÷Í÷ú’'4Oñí5ç"!ÐŒY’´öΫ9+)ìø(6W°+#æZ}PÊÒZŒY’¼0üü*ëG×6ã‹­’zL;|^dîd>ñ³}JÄ™¦ ”¨yÞ^-Æìyºi(.ü3²nnbpwƒAg!µõ¼Ôæåëo÷ì0˜x”£·¶²Š,„,töàåšòv†ªÝ¶ÞS5Së)ÏJÀ*þs äâ¹ÇZ§Ì"£ÍŒÓE=…¢½ü©å!às`¨iÉVi$x8/ ¸ÔX‘û¥-')_e”þÖÍìüÕ­óùXm=ðuà$m"½5Væ~YÛš“’«4JÍxDµ²·Ù….\Ùç‹}/Äjë 8D«5Pέ©VûÞþúðeEÕyu½%!¬B÷†ƒAÇæ‚°XÏü8<³àœÄ ú’Â/¬°!„(<›. :ú½³Ržö‰Hê°êÁÅU‹v›5z}yîÊžyN?ÇÞÝý…H긧d{iQçë7éýÓ¥[¦{°8¼G®d<œìT»Ó¢®ŸøGYÚdHQ¾¢)$vÊÂÌÆþõ\s­×{lê£sœ^×]Õgúù[¥ó« J)ð, òE6á‰óȪ×5$)K•µ©Ò6Ü{•£jõ†Ç—„ɳO;²¤EŸ˜ÛÿŸLÕ(òYG—¶>¥×©Ìùb«¤ #óüCŠ-ë?ˆÖÂÁ'ÐʹAdéú z-›ÃÏËM¾ï^±Z%Ïldnï}ñæ¾éî÷O-8ÌY¤ªŠ²ëùÿÚ`/ä&Ýs–e§£5ö¦¼•ו· •ž¹5Åj_gNʺ[ªzSZã$¬ÜßûHΙ ÜNÑ9üuGåµìš²C7n4j¨dTCÁƒ iV»9päÇ"5M/}b¹ïÖ«Ý¡™z÷ qZ[Ph©¨Ÿ/òþV;»zò¯¾©l G#5M޳8tu²åAÆ ½=²Ô‘ûö˜yïÔ/[DæN~eÉØº7?$ÏŽ™¾ÿgï–n™;m/ÊKàDnYoåÜè§¿Ä®ˆîàÂz€ÃR™¿F%éÛsîÁ’uɳ¢'íÿÙóÛİ#k$Ö5w—/ Ɉ¹6cÿÏž3)CM²ºÏ>§S¶ÞóƒË2ÿu>9´¨þ8Sž[ý¾)õ:}5.7ùÞÏ'WwèüfÎÎëcê©IØQJÓl'„t#„§–¯ÜœÓZäӬ滲þrú\˜\éÚVCÏ»»þ̺> sâGÞØóù²»Ç~Ø?fIò ›F´d±¹éëQÀá Ãîü­Gïé'Çßó×õúòä}ˆ¿çoF)úͰ>H©ÑŒÅæ¦Õëüåáİc>„Åν8aìÿÉ{²Pb·wðÜ SNmÿÆâRøùUO¼¦QŒY’¸öÿXÛ-=úr×ú½w%Zu¡Uƒnß^vkЗ™{©B\ÌÙêŸY¸Ÿ®7ߦ®5õXÑÈÕ}qÈNÌRç)–öžrÙ„—UÏÝT½{šÔ(›Ò\x{D~ ðÙD;¶‘ ö„©kzÛrR¥|¢€V®ÜØ#‘Ïnž¼6qbcaŒm$ˆí·CÖ ÀÅ~>üN› &Ö·ç$Mi. éQ‹W¡X{ ¯‡{ƒse™<=šŒØÛ|àÒt¨ÙxØI£^ólx¸ÛäCᲬ¨~×wOîаÛ÷›ë´Ÿ*{|{›Ô±V§Ÿ»M>ÆnþþÑ >¦2\¾$'Põj1þ9·û]fÌH ?Ú¬Nû©;v›• CçG¬¾¸yXS­RfáÝ{þæäˆSîàÙlt‘g³Ñ6ôUÊÒÜ=›¹^¿ròîªôj1¾H$u•qÒóÍŸ©Ša2j=ð|Dê–’Ä”·"Ùe­4éWåVŽ9+°ÞóM•¨#!ÖTÕ(ÂÉ3øb+ã 9·Ï8¸M¸ÿë«×wMÙ­¥ùPj0“eFµO”([•=/HˆºÕ°•;ÕØÔÔ@bØ1°9ü(“ˆNSì)6w¼a:f±¹©éQ—j€ÊbqRLé<¡yŠBžÞ¡†ï Eƃ'¦=º0áÒ–±³DæŽ~#~}´ UJ'޼‰“YpŠÜ`q1NëöSñ} Ÿ(.byUª/Í" #žKÞZx§¿ÿ¹ëˆË†ŽË~â­\Ëš-?öHól><³Ø(máÌM+.ß nâÄ‘Çæ̬D,9,ëivNу!êšS šfµÙFÌbb§¾af6ªßÝznx¯Y¿ÿzFXØûèûϸ~Ét\»Õ¤ÂÚ­&…›Ž]ë÷UºÖï{.¨;IY˜1Þ§íäñ¥ëqðj_بǜ3%Ó8\!í9íÔ³¨Ú­&=(™ßcʱP¡¥ŽuÚO•Õi?µÚŒÈB¸j™†Ãñü"ìÚRË[™ü†N’8_¹…-!¡ Κ/ªD=M4ÆÏÌjÇ=_¸›¾Û¸5QÐq…R­G³§©Ñ(<7è¯Q c×Z»¾íèõwEæN€èô:Õ³‡¨w›I…&ƒV+÷‹ YzGàIïΠ×Öê0áŸP0èµbïî•€BžÞÞÌÒõrQn§ÓGÛcÆ.Ký±qïyÔòŒ]ä oŸ/*}w¦¸Ù‘HÓòkÊ:wSuÞã|Ñf,»;kìy×SÑ¿ûj÷¿ï¨¼ÀËŠ±åžªþîPu¹‡úùð3rFËÎû.¿¦¬’®óšÐDlB ?ž/n¿'LíºøŠ¢C'×3N7¿“ª·t°”B.ÑpÙ¤:ï®ð^`åÜp™³w·üÊ®—'4O÷i;y|i'+Çzó%Ö/~¾¼'pÔà¥4‚2†ð4s¥ô…®Æ%Ѥ¸ ³›PQ=ö¹ø™Å-@Ü€”àš IDAT“bÿ‘ £24¥”^¨ŒzÞ‰¡G¾Š ÚÝ„Åæ¦z[Øú@«¡+Ò >xÿþ}?Ö:Àb±ó½ƒ­{³Å}¾ ¸-0³öß=ÛÅŸÃ?h=|Õªò´ÓrØŠk6Žèæ7Ãú (åKmj®|b ‡usÏ{oîùBÇæò› øíê-ÿõÒ£/¯bsøqF£ÁÂÌÊmÛ< /§¯7/É/Dí³õžÊ×Í‚ÿçéÁ6nÜ|8=Ñâø®PµûÖ{êFb.ÑŒo,xË{™îQ{^Iкõ$÷¯Ãñ²fÿkçƒAuùwLßY¸>ÙÒoÅ eýD™ÁâÂÇ–ÛÌXౡßXzð¡¦î”æÂ ±¾‚d ô¯ÛÊfvf¬Â?úIŽ› Èûþð«rú~}ùÚ›¨·tÏÏDÿ™7«í3´²xj³N“ŠL›B,=ÿ0sv˜$xæ#¿¡“$ÌUüUZVèÁö÷ö“”¹cuA€‘“0'_®Œ¡åî –_G‘sݶã,Þf”þôèË‚ÔGç-[ Z\¦¿{l¾C­–ãr-|þóÃ"1ô¨Ø¥^O%‡+¤pv}¿&Ù‰A_ŒY’ôiìí]RŸö“å&Ù¼Ô0nÌ]v{ÍÍà‹­ÞÚÛwÀ¦áÖ©NgPJs_-]5BêŽm$ü|]³ÂªÖåmá¶<÷«äïmÖVµ&=ÔXþ|Qq-M®¯´5­•!ÄAdîhcãÚ„ÓåãýÌã[æüÆAZeafö[ßOͼ·È÷ºÅ=´åäÝYíäÝù…½R“‹}ePÃwP™Û`p¸BZÒ €µK#µK£ê¶–„¡ŠèP“÷àÕR %1è5œ[M –º×‰Ïðš¨sH$€×º^«Mˆ†×ã©å'U­Cõg×péåªÖრ˶ØÍs™¤Ì…ìo‚¢pµ9ÏŽ£á;p^º­:E'4(Œ±ÿ6(l`‹X†WÉVùW•’´Vìë–'Œ!Ä@&³ý CU på¼5oÐüËzß­}U›y狜TÉ:©uwqøËä^—ô2÷¬Cr°µ(yìü‘eâ›h§4l ÛPÁÐÞ…{ìùN5<‰xÂìÀÀÀðÞCõ”PHþ…ì–Ò®(Lí ¬Á•Õ^ìp, ù¯|¯‚« w®5[Á³ã( ÷l‘}¦a-¡W^ã{›ÈÌýrW®[k7Hšý]fS÷o¬ \¸/íù•&cŸ¬žï·s,>1Þ˜Ôçmµÿ€Àƒw¨QJ£«Z†·Aq„Ú†cÁÖŠŒÜ¼€âÚ¾‡ÝN=þ>óìÝw|Eûðgvo¯÷Kï Uº ¤ˆˆ"(M±ëëOA_±÷ö׆ RTz¯Ò¤'„ôÞ¯×ÝÛÝùýc%\˜ïçãG27;ûÜ&wÏÎîìLŸšÎp‰–ö[ÿtÇuþ&zljé%Ã¥a¿Ff¹®ëϱ›K¾²$–|aIŒ¾Û˜wtbáXÛ>O1æ1U?¡›R<\ô‰LݲN_Fo“†ÿÓ;¢‚V×^v\¢ D¨oª•ÂóI âZ¤¿^YÀh¿¶§¢ÂqØ‚yL© i%èoPòQVù»=†·‹ŠS— À i¸Ä%ÑR|ø$]zÁš!N&Ÿ3éBØ­Ú,Ìý{ÂkZ[ï¾ýÏ5@D!ÜšZ]$©×, UN|ZË“ùH/ Œ‘®Ÿ²²êw{于ûÂå R›éFMyÍFWbçobv ¸E𫿥Kí]"&ëþΞ_٣ˆM»ÆUøbýÕê ‘†Jöý­¤x¦ç#[«6øöb[e¾t×â9†–ŽäZÅ:mç,mÒ¨ô›g¬ðËZ:Žk˜Íí#÷Êë“Ç2NÆHs” ‰2/ã†J¼ƒ„‘ê*óWìáq…cd‘‡•>25sØ=?e6ž~žÿì´7 _oж‚ÝÎÅ÷$ùýÃ^g¾oÕºˆ¼¿—©­zþöÛ_Îü&P¶ìåÎwyíc1tÑÎö½¦ü÷†iŸ^é¾üñÌ'‘›Þyÿ2ò˜òeò ýqÒ¿¯Ð+ˆ@uŠUÞÛÏxÁÏñºSΨ±©š2–ÇÔË«úU´{lª:?-\·&Mrù1e‘fSü‹ªô¨‡EÖ.£d(Ó²Òm „"„⚪½ú¬§"]–¢ë]–¢ëÍÅG?uTçvYŠ®wTç¤5×>¯Äš÷Gܲê½ÁÏ~ÞòÕ”´ßÎÜäqTtösîÐ’ŒMÏ4Õ¾X·erSµìLý$oÔ#«oõÈêÛhF~Z¡X6ê‘Õ·}lã$ÞïEy/SÔžxýã¼3–T”Ö/«ÈÝ#+:±VY¿Ü\rŒ©_`«È<ïIiö¾4ÖòSJ½rJ lÇw³’ÝÖ’Ù}n}óÁ™ï[oJê{çSÚÐöÿzžó|m:kò%¬ÛrÎ÷EC<_í³¤®Jwt›ªÍ¾µ‹ö”Ã'^ðØ à½Õ£?ûü"½#×ÕµWœ¢D%¥ü¯¬¸eK–+²ù#oBj„ÐŒ&(bYÏ\Gù0÷Q¾'æq¨a”tgSµ yÐlgcÿ³áøîÿtc㻎û|à]_ä/{¹ó´ßßT–µc¼!"u§D¦òU‰áí¯_è ­Y8l€LipXÊÒû"|ÝØg—&÷›îäý^´fÁÐQ{Yo„h_»ž“~îwÛ»¥K_L­ K>b.=>*4®çº‘¬8ˆeÛ¢i+ó÷‰½nk |݇£úÒŒ‚µWfu`Ýæ~¢àXò\Ò#!ñ=·Uæì¹Kiˆþâö—2Ÿiæ«@{¬ÛBmütü£2µCÿ™Ë®û\ÀÒSg‡Æ÷Ú[‘³ûµ1nÿ˜Ç6ì’0 °ñº›KŽŽ ë¹®¹Žy0’0 ‘8€­ý ñˆ¢„ˆÄìOOǾ‚EA%ø½¥JÃæ“Û>:f-Ïx!ʳë‡{!:uÄÃçürjå;†Û+³fa,ª0•ŒL½ÿηŠ_øa^øg‹jLIú}w¼–óñ⹡‹)Zbül`Sl÷·Ç=±mOIÆ&ÅÎïï~†÷{StaÉ_Mxz߯µŒ¼Þ\tä1 ˜A€8ZªÌÄ"¿xnØ72¥~ŸLe,¤(IUDò@7@ÿ)ÞÛ¦Ï'v­ÌÙó=¢h[rß»Þè7yAÉó¿D”Ä*ø½©c¹)¶Ûk7Ïݱ«"wlë—S^ä9OWð`’ܮоBo»±©šôáɪ €Á‰ª³sî/ò=bël÷ Ê›;iÓ'tÑ¿»­º‡Ïe3)¹)ÞÀÔÌr˜BOì¢-°{ù†Lg’FN³N9Ýœ(Ë5ûÃWÌŠ[±äˆ­ÝÆLWªIE;ïêi8Ù=Zn=Zê3¬8nOqs¢¬Âá×NÕ¦Oï©ÏEàó½–ÔÝùî$–ÇLßxeî¼!!ÇZê8]€Ö6Ù@‘Êo}cÍ+Ù½9Âó²8ú›Ð)²Š¦jc\zf^¯«Êm-¹¯ðøšgTº¨£†èÎå.KQŒ64qÆ”p øäºÛ¿™`¯ÊQš¹mDª°ˆ"¯ükÙÜÖ½?r¨³&ÿ–¸ž«Ô¦øý¬Û"pY‹Ÿ©*80Gmˆ=P–µãù¯vŸ°ìåÎw–œÚôœÊs´<{×Ü_ŸO¹À^™5¨^÷Ñè>·P‘½ë¿í®›øÎŒ…5Ó´aI+ò/ŸQf(ZbŸù¾e|TÇ¡ó¬eéwì_þä@ ˜žù¾e\§a> ð\—«zÌÛ )êÌEû-ƒŸXY>hÕIGL Ü͉ô++GÏêc8þÚM;~:lëgæTO =,gûýÔ˜µ¯Œß_·­| §x_½Œæý^5Æ‚‹<5æ?ëÿ<ãë\ÀXšÔ{êÛãŸüs{Dbÿ7ݶ²›¼öŠq±Æ¼:~Þ®É}ïzÞçª9{Ÿ†‘©wM~ñäÏ#î[š.Uè (ZZ5ú‘5‡»zªfÒ Ç5Åv{Õc+õ÷ê—¶ÿøTÔÞïE»~¸·=`,ц%‘ʵ©\»»àÈï6©Žï{küS»·iC¿uYІxleãbÒF½6þÉ?·Ç¤ÝøÅ22-M¡ ßèé¦oÿ$âǧ¢,žò“¹ä؃~ÖÕ?P‘ªvz{©<£èĺ.}n}#b¿ܰvÉóÉeìüL¨¯ KÚ pôO 1Æê㛘ÜÖâácüV€®#çš%©Ø¶hZGšQìOê=µÁ@}DG~ú{•t9o”\òWeî_ýñfß1;?Ó ~¶GÞá/,žö½2k&çu ©³ÝV€ÁÓx¶+€ËR4LmˆÝÐëæ—+)‰4½Iè5hF/}î·SbÔJß´õ»õ›ÂÛ1øí¸#AÁPìêtgâ7û­däÿí„ãœ1~Q”ܼ¨àŽçÖUŽè«(¸½». F'­¼¹“¦D&Aâæ,W»!‰ªÓqÆ;6US¦`(öH©Ïª’X&vÑÅèï$õéÙî£R ¨ùk+nØéŒjo’¶ÚÕ7šaF‘°iòJ‰žÚÁUˆšºí–pÝ­goÔ.{¹ó;Õ…o‘*t4#/æ9otà5F¡+¨½D…ù-¥'¥ãŸÚ½ZšôCeþþ‡|2r󖯦ÔÞ£CÈŸÒV@xbÿQàÁß®]ÛJRÝ_.Š|T }©RÁewnž»c×ô÷*~ï’~<çé¾ñÓñýÌ%Ç:bÀŒ­"³¿­"³?E3¹:$p–åëuóË•R¹Æ*м@ü Ý'”œ‰…Lyu hF~öÞTî¡_Rã6ÍXPsgXBŸÿui!öŸ­ƒR%Ìx¯jNÚ‡ïÁ¯ü{õ‹ïj°nKÄ™ÿScY\—›ì4£(æ¼öˆ@,òaÉ+EŸMhF.BŸñžã^¨šüâÉŸÚ°Ån[逄î·8EU¸ïׇf,¨º{Æ‚ê³>°Þxö½Id,-U`¨}Àh©¢„ó9Âÿ‰Aˆ¨¿¢ñâ Œ÷É¡¡G›·œ0³3×Î ¢D¯ \×Ç+K¯W–ÞÝÇxp|'mnCÛ3ůž“°ä§»bWÍzLÁ @¯ Îþ} "Ð4…ÎNùE!ýBí‚­‚³å D^Ä”„ømvü¯=c¥¿±whyéˆæ;WîŠï©q¢¤â_RÜ3ÊL€ò/¼±¼E-¢~¼òðj!„ÔÀaŒ¹¦jóRQ”äì—ºŸu ÷øÖ¡ ½¹žŒ}Á3—¹žðô¾°qé‹i3« Ž€ À˜ùkéã}Ç=±mwî¡e70rÍN©\½ýÈú7'tŸ°n×÷’H•{ê4w6©BWãuTh?ïYòh|ßÛÞ)’0 ×å&™ÚÓíÆ'nùròü‘¬øÂÓÍpáÁŒ\³ãøæÚ÷œ¼ñèÆ·À™/1âÒ!Šòxìå=×}4Új.:<çbõ·.ššê¨Êi¯L˦EµÀ³goÅw¬Y8¬ÂQ;H"Uî×GtäÃÛõ[_trݧ«ÞXâ¶•^GQLIÚàmù‡—ÿ«Ýn£žª9²þ æ·úÖGt̵•ŸJòy,íôa)û}ns¨ÏY=9¬]ß§•º(AªÐmÚöõ¯‡Æ÷úA8)ë2‡ÞúÌÁµç‹92ià¦ü#¿ÿoõ{ƒ ]Öâž‹dŸ+´ø-q`{ey;£Ô³¿Èkôñ¢´[”ÜÒ#Fn^~ÌÑ['§Øž± k™ƒ—s‚HÑ@.¡¸›_£g.y¹­)ê¼/ÿ2÷»¥‹6ÿT«wr¢²OœÂ²=Û^éâC6g¹"»G),;rÜ)Ó{é•9x¹Ï/ÒwöÔçöŠUT=½¦örekƒ’@Ì'5Þ&JÌ+ÙÏͰ ðcB%F´2ùsÍ¢&ˆ3`0dÀEWkmNruÈ’uŽZ@ÑLñžî×<ö?œ×~EIjD‘7$÷½k.B”ÓRvrö÷O˜C€øö='ψNùMщµÏÿ„iÄGuÖàPúžã^8¸åËÉ|ÿ„i¹>¼Ãçn[Y¯ì}‹o¢hi(ò!ŒLuðÆ? 1µûpÍÂa?Qm>D–´èÖùÎûe×yìwy‡W¼õý¦9%1{¾º×2)~³BQUûï„-Ú°¤âÀkÝGÏÿäÄ–…S­eéc#’d-;ÑÀÕé_g×jSüFCT§|©RÏVåíK+=µy˜Li8Òëæ—_ ÔчwøÂ^•3\®2¤ùÏú·†Íù9ó¯¥Ï*8úû4™ÒxzÌ£ë>0Fw-æ|Î îIè>áÞʼ}ƒ­åtlç1‡r.‰©)>rÍÈË"ÌýèÚ¿¦½YôÚ†OÆõ¨)>r+Bˆ7Fw]  6ÆþaŒéZP{B©ø`ðÌorh‰ì¾ÂkfÉաǤ ÝÓ!±Ý.i1G¢af7¯œ·ªb Ç‹L„–±<Øß´Ý ¤ýó‡‡núþµûë[ªB”RÊ÷ø Ý ðÌè¥ßûÒÆÊÁ%íziTø_ FæœõZt šÕ3gW£š¤ª(²résW–ÝhTJ\/ _x-É$+^yÒ‘úù^‹áÆꌑ4e>Ý뛫†rfŒJÚùèÀ]Wçˆ4š z5ÙÊ׿U¬É_åúáLµ<¾`ª±+_7†R©ŒKì}¿ªÏä×íMÝ6@íPi}DG64¡÷%õ³÷ý qÛJäÝGϯ”}ûÍÑÙ9»§oÿÄÐiè#ç¬9–sðÍùOuÁAiÞáå!=o~©§`Ëx[î×ÊDSžlNø·7ŸS`£@yc`?¦ž9šòFÄþÂjú±|P<&=5„P¸ÏŒX#‚hÓrž«ÔkK»•'f—Œ–G3VJAùiâS?‰Ú—÷zu'×)_(B8³ (_b­^íH’†J\¢KÒþõשGˇ¶.ô¯òŸíÉŠ8Æ‘0/äìF¶½£u·;¼î>Õ©rkèÍšŠÀÏúþʳk°Ñ*Šõ[F!iµ—aBRèI :@ä·pAW¨ãû‘{¤áîЈüñ–í®Ä^[Ú­`o÷œéå?Úº˜nTçÐrÄ—ýdëÎUóÒÔO£¶¿³ø&y cIý(ò@Ýf%Ê/‹`$CBÜ#¦ý”‰~Ë™™»é8ì3VþfO­[¦ë«,Öø§wPð^MGo_ßùëèÝMüÖšÆØ ƒ"©Aµ4Ý奙•÷Á@ä° |¢.½z½3Ñ4\ï>ÍÃnÖ–Ÿz¬|hÚ§Q›JYR ?4§Ä?fÊ ´5S_5S_x¡ý”ÿb‹-ýÞÚ'b²îpî+U#¦è TZ}o ‚â95‚ ˆ«)ðœ-¥ú…?,ŽPu`¼Wsÿ®“>ƒº³ÜøÝ2ÇoÅ  Pæ·2Û~O„<–qÊcWÍ+TÉ2;¹Ž{šîŠF­ãè+õ+}…~màgUšÌÂè¾DÙdD€ò/X7]žú½2³QÏ©¤FQO ©Iªò(…±¥ã¹–P G úôÆ>|—B=  c\ÞÒ±qíЇtÈvׯµtך˙& !¤€1A‘ÔÀ­v()Am“³&?åø×ƒo§i,ß•AÏé£<~–Ú–‹Vþ7Å/ cœÓÒ1qíÁ€©ëÂù˜qää¤ú*ðð"úêoVmfåžocÌ@AP$5‚ ˆ–"¥‘&%“©_NV¤Ø+š@šL“EA´AÑSCQP; 3ªIAœãLž0KOm¤´tAD«¥€ñAÑS€@ÖR'‚ Îcì€oƒ"©aŒÉÈ#‚ ⢂"©A´u2Q»r= NVLj“IÐyÇl:튜¨ªÔysku§O”«d;4¿o¹U IDATIUØ?AYsõ¢o=‚åžAD›µ-Ûñénó ë”EÓzêp‚H_h›vÕ µy…³ wnÏquI02–h­ÄñÞöš!ÿiîÔÜq·FAÑSC%€ clkáP‚ šÜ¶lWBŸ8EÎÍ4%×Ç+ÏN>œUÍ©üÛÚ)ßÌ…IReÍêcÌúñ-Éá5sW•ÔÈ(ïg“¢· j¯*í.sj4ûë[»zê³^ÜXyC´Ž±í/ô&¾ySøÆb›_½ü¸½3À“ºéOOVUxý˜š·ª|h´ž±-ñÆ÷o§Ì¾ÿzS†‚Aâ'±+O:º¸8Qo`ªßùgK§ AÉ g°ôÔ"@ÝÒAA4‡1©êœí¹î../±ø-Ñ/à³ ÿwuùØÁ‰êÂÿMŠÚðw±7nõIGìÌÞú­œr.¹9Ъ]‚l{Ž+1%TVÎ ˜Þ_äIS0÷ËôØß Jš[°³fØý×›ÍéküûmÕ7Ú½Ë"u°Ø“ÊP ~19zMv5þÕ>K*À×û-Þ±mÙ̸ßìo:|µMcERÃï×´tAÍa@;UÍï³âì©(ÛtÚ™6ö«üe^~¤ÔgðòX¶¯ÐýÑŸ–n!¼5Û•|¾vžXU>þ¡¥7…ªhçýÇd4Å=4À”.“ qý)WlZ¸¬èºh¹µg¬ÂÚ1\V´*Ý ¡ÿÐÓ ƒ’öOî¦;y°ÈÓÀ¤’8^ØP9pÉ[»x£Ô}uŽHãaŒYŒñÞ ¸üHÑÖé´ÿ¡ÆŒ‡3æüZ2êŽö×ÅÈ+å4°×Ç+KÏT+5(éóŽ_8>rUÇp™3ðs¥“—«e”[r¦û‹"E!8;ø„F ò"¦PµƒND×vz¾›³nMº3zs¶+yÉ{ï?îŽ_Úäo¾ EO ¢-ûý„#îh©Ï[éJ|HÏXEÅõñJ³€|¼H MRUôŠ•×HiÂÔÛÑ2o£ÖzßIWx²‚?UéÓž(÷éÒ+Ùø[:k ü–,ÚgIus"½â¸#µW¬"Ÿå1ú»Øk×ISúÆØð?}<–º¹ `ii¤§FÑÂ|¼H¿½­j“•&¥ÄqsšæHß8…àõ±~9lï´hŸµ?C?­‡þïNrûÌ^†¿—³uùå°½ûwScÖŤåJ)Å×mWJ#!ÁÀœ]d3TM³÷7íxg[Í €ÿçÓ6£’本 1($Ž*¯ºëÇâÛúÄ+sî»Þ˜Á‹˜úàÏšNŸ¨ÔÈ)ÏŒ^ú½*)Õª'Š•¯B c\ÔÒ±ÑöV¾–*ô§v‘z¸¿ÆÕÒ15''+H&}Wñr¶ –i²R c\ÝÒ±Ñö!„B@ÛÒq`Ç×\JE„KOòLAWÉ™hr\( ŠžAA\ Òû!‚ Ú ’Ô‚ ˆ6#Xî©AÄy!„0AÑSC݈Jlé8‚ ˆVK ³ƒb BÈ^Œ±¯¥c!‚ ZŸ@O-(’AA\Š ¸üHA—‚$5‚ ¢ÍФ†R#„f4PÞ !4 ò‰¡ðzeQ¡[¨;!Ô¹^š’×+OA o 1¡„ze:„дêö@õm |2B(¤bNE i q¡Øze„Ð ÔíêÝ@ùgîwÖ-‹Ek î3ÓÕ-“ž‰YZ¯¼)bî‹êÑ@ù4„®^YBhLu‡#„Rê•ÉÏÄL×+ïŒØ@· „¢ê•… „&_Ř›âóŽšØ@Ý¡n ”Ï8³¸oݲD„Ð Ô=g ùÌ_QÌ×êg¾7Bh`Œ[ý@@xå*Ð6PÒzeR05PWªzeá@Õ+W€¾6 o æ°êª@sž˜™fˆY ºÚ0€¬^™B¨«9OÌ¡ ©W&ãybVÖ+CgbFͳºò0 ë•ÉÀÐ@]=(ê•Qgbnèo±¡˜M ü-2rcnªÏOC1këÿ-ž)oDÌçûüÏüåÅ|-æÃÉ@‚ ¢ÍŠËAq)HR#‚ Ú ’Ô‚ ˆ6ƒ$5‚ ¢Í I ‚h3HR#‚ Ú ’Ô‚ ˆ6ƒ¬§FÄ5!„Z:¢ùMRCÉ@Ñ)°ŽüA¶E¾S6Œ-ö¦h !¤ˆQ4E[Dk㇠cÌ]ÎÖ!DËSi&>h¾ûˆK'úó=Áô‹¥ÔºÑjYÈ,2J#ÚÐVëËÞ¦k1F¡Šy0F*‹›®M¢5à\G»òý|¸¬¤@3ñ]û¥ä{¤y+rÞ% ¦¤€Qñ䋪A²ü&¿·+“w(å|S·K´,䯢/^‹¸–‘"AD›A’ADàëµ>ËbÆÜU[À{Ë=U £°èjõ9#¸.?!Gá½y÷±X°õ„XD©3UQo¾-ÓO±:‹ætÃØ+ÕÆÿt°9ömÏ7L`³`Á•HË’Wê“wþÞû!š†·úýHÖº|ÈWt$·Ð²vGuí×lðT¾+Qt³KµcM½_¿{Ò]þâPÑ_ÔÔŨlQÇ||!)¹ïÔJØónâw¼c_<Å9KžP0ʾÏë“Önv•>ÄÚWO6¥¥¿Ùû6gtš/ú+&¢îŠ7¤mÜnL=ü¢Ô­òVP«ÏºÁŒsnUsöµŸS’lEØ÷ɳæ!Ú”)ú«e¼çÀ@Þó÷ÈæÚ¿ÀåwGHf•X°F7×~ˆ+ç©|=Î]þÒQ0·§¤ñû%³óÞ£gBôVò²·úÃþͱowÙü1{j"¢õE1Ö¶üC[Vßûšc_DãaÑEù]{Ÿ¡eÉËCº”ÝÚµj¨:òå Œªw6€è/3`ÁÒ¯¹ö¯¹ç{S§Œ>¡]«†j¢ß½Elìy“ÏYìµµ =µfä©xùFDI‹õ)ý(Sä¸Jç%‹|Õ@Qj9ÕñD©* þþÀž{ãÍ €D‰²÷*mÂ’}Ž‚i}D¾<€æE6gЪRuÔ»‹Îwön옾ÀœžÐìo–¸">ËÓ(‰i15³îÙö"wÙSI~£Àw±çÝÄÓ²”buôû§\%¦ñžCÝ­3«c>ÚAËR8gñ}]ii¢E`³M‚/=M¢ìuLóqFCûÖ¶[ö% _øÙž7.ÇïÞû’ÈW.¢$áB3¾mâx«ÿ…1«™½3Ð{V„>\àwïUrޝcì¯9ù€®Ý¯wJ”=¼Öì3D¶`AKѺýêèw^—é'Ú\eÏ·÷Y¾Žfâ6 löLZÑùsCòÖ?Ú¿2쉲À¿å¦Ù5®ò—3EERó¿óËCzjÍˆÑ ÿ‹¾ëéëî÷T¼W÷5‰¢»QŠB@ò2‰<íO‰¢ëaKfçÿã½Gqû(&ò(çÜü¦#â@ÍêÄ{=%°YchE§õ˜·uvÍþöj__'š¢”,ºRëÿlvÆ‚‹®-è&°Ù1–ÌNOø¬?* ÖxÞ{|š-û†%‚/CÀ96Üë­~ÿ=αúE‘¯NõYÿlË8©¡}Ÿ›¸h°(C´¡U^^ºÖ(ß*A”â„«ä©ï-™½ç¸JŸJ¼Æ¨ú{ÍЗ’ê“·NÑ'o¨¹­Ù#ï¹Â 2ý­óµq_Œ XgÉÜW°`“cÁÙWä+®SG¿u—DÙý#ÞsôEgñCσ«ìÙDëéwšÓ“ß,(!s–_÷~9HRkFªˆ õ GEåõžªw7šO„­´å ™€E%7ÞeF”¦QÊRm»ßþÔÄ}{ÄïÚ©¹â{d†ióõI;þÐ'ï^JK~ô{Üy¶Q,ÊŒ=¦k¿v‹¶ÝÒG°èëà,šÝ«ß&Ñ”aO.¤(ôT½·Î|"tõt{9Ç:-€¶Ýï»’Jä©«©é tí×lu•ÎM¹’™êè…“Œ©™o™:—Í 8gÑ=ÿi3ÆNÅ·Ór^`T}çó¾“óD¾ò‚Câyï19ïÞ;–µÿ’ÜSk=ôIfÐòŽßŠþòÁÞšE¿×œˆûÆUö|{„¤~@€%ò4V"OcD6ÿZš°‚–%Z6OŨú¬Â‚}hß?-7ÎøTnš]£OÚ¸Ñêœs×MçÛ¿è¯ÐŠ‚9 ®N€h/Æ|«=‘&I­™éÚ¯Ùjê\6K÷íõ”¬ÝrÞsä%gጠÕe­¿&`еüô¾ùDèzó‰ÐõWp'`X ¢UGmÕ¢é"W•ÞÑLd†©S§ÂÇTQï £å¿ýe#…w®Ø,iCõyϾî€h—§âå'-íß²d´ ° óÙËBˆÙ{örUÈ£{ ZŸù›¨óÅ °YR{ÞØO€Ræè“w}Óôï’¸\EWŸ!eÇŠ.%Ó51 †`ÄZ—œ÷¾'Æ\”ÀõTü’§úã—8ן÷"Zóï9¬ª­|ªÈ õ)ZŸØz¾ö´ñ_1¥e¾Òµ| 8CÊžy­udQ{_Ë[³h3Ïfß ”ŒŒÿÕGHZLIc7;ìû¾þö¬}`¹«ìùöê¨WóDÁÚQÚÓ—²DióD¾jЕ¿“æAzjÍÈY4û:WÉÃiŸ½5_„aÑÑQªrJs‹®ög?”asË%?å­^xïù[ ò•´§òõ³÷Y0fÛ; gô°çXTË w¾ºïŒhjžÊ×ãêÞõ»vê‹rÀ" €(y¹(ØM×ÕÀ¿1fã)I¨K·èXà?E裥:X0÷ ümyk>HbV˜æTÔß·è/‘ز OÞõÅÄ™XZWÙü$sF§ÿ:‹èê³.3Øó§ôØÜ»(Z{@öx&Æþp{þý]eÏ·Ç¢‹¢å)?lÞ [ÎØQœs›Ú]ñZœ5{ø-ÿ´ŠÖòó#žª…QÖìa°àê%ÓYÙÐþ-§ûÍt•>™â©ZeË9Nð—L£˜È­WçÝ7é©5#‘¯2ùÝ=ç³þ,E@;0æb)‰i½&þ‡Eʰ§þrÎoNÛ†¼ÀÔ¹l–"ä‘'¼5ÿ{Ë–3|/¢dùûCiiâ7Êðg¿@´f7çÜô”ùD¨c.R¢ìý¬Üx—¹¡ý[2’_ùÊ;Á5ǵÐòŽoRœsöF´,oÍWÿç©z¿3Ek`Jì×#J}XûéZÞy³ß½ûsz\?Zš°CŸ¼kçÜø¡·æ³_}ÖŸw#JQ…[ZÞùG}Ò–µµ­J\–ôö Z}JäÍ£%ÊÞÏ.]×eÏŸ4 ¶áˆR³e 8{ÙQ½à1™aª¥~}âê’(ºYXÛJ k_õ¢Ïö›!ÚJ1a[4q‹>ÈÓXF=àiÞó÷x¿kw´L7æ~CÊ®¥Öìaï=>ÞÇbª)&úŸ?¢-”,a§§ò½€bT×?¥Ž~7«¡ýcÁç3ÿxAƒ¤š–%}aHÞüãÕy÷‡0Ž{Á!…:ò¹yèSAwY„µ­Ð \žJ¦½©†>s#÷b8çVµà;®‘é'WΜ­§{ÍÆ‚¹“1-žÏò£‰QpÐÒvþæ¾ù‰žKÅãÕØ™Óð%×FB(ÖhLú 2˜æ~ĘCî’ÿKãÙ¬‘¦¥í 5q_«[G`³¤žÊ·S)iœMñb!@íCÙ~×ö΋”DÑ=Ký^6€9=îcš‰þ‹QÙï÷He”}N©¢ÞÌmhßÞêO"üî½çŒºTE¾t4ðˆ@ká³}I»ŠæaŒ]—³=BI5#;\Ë;‹MóY—|Úµz`KÇÒ”ÎLhÌ‘žÚU Óßf[c¶‘j†»@3ü¼ÜóõΈà„«cÿ—éç«CËR¸ú‰N>¿ÂçŸo›3‰¬Ád }¤BúÈ9—% "‘¤D$Š®GDyIKÇA´~­ËFSeKÇA´>rãÔ,zmé8š IjAD÷ÍÑ–Ž†Ž'>jéˆÖ‰Qõ÷0ªþmö»„Œ~$‚ Ú ’Ô‚ ˆ6#¨.?r¬•’z6‘DÜÆ°¾¢&ÿr¬ Éä…äo¥­áLCú­@ÛÒ¡͢ć1ö4EK! Èû›¢-¢µñøŽTaŒ½—³5B@Ñ´1­ˆ4I ‚ .†\ž!‚ Ú ’Ô‚ ˆ6ƒ$5‚ ¢Í #€ˆ6§vP\p1L"haŒñ%ÍŸÚ„ Ê&Œ‡h]|A“ÔB FÕ+QªV»â*qy0oÇ~ïÑ"Œ±¯)Ú£¥qzF7*”¢´dT›"‚ß¹Ý9WÐ-3Lˆa4ÃÉUª6FðoÍWA“ÔÍHZ|³ôæ.{ò{›pÖJŽdÚñHª¾áœeVˆ &rÈîÞÅɈ¢  0Ü4+8—ÆÃF{jADB’AÑf¤FA´$©A4¿û@£¦ßâ}2Q°6z”®Àå3"_I‹‚•æ}²Ænl{œHR#‚höüÛ\>s©õùw<ì.9¥ñû™6ÕYôpwé;;ò§ÝÛØíƒ#ÚýîÒgÒ.µ>IjAgðžÃrGáÝ=l9£Ç8 gõ ”Ûs' ±žp§»üÅvgëzËm9£ÆZ³‡Mùʳ= Ëgl¹ãFbÌ!Ÿu‰Ñš=|‚ϲØxÝYühš5{øŒÅs ÆrÎêi=ÝÿNoõçá¬}Öš5x’-{ä8αYs¾¸…sº[O_?Ýž?¥Ýr¿û€Âš=l‚5kè­>ë2€»â8gÉã­Yƒn÷Y—9Çf5{ÄxOÕ¨úíÚó§ôw?šfË5ÀU2·ƒ-gÌè@ò¶çOéh‹µ­Ô9 fô¶åŒ8¼/CfË5ÖUúd €«ô©doõçáãç(˜Ù €µý¦·f¿Å[óuèÙãTòxGkö° b£F铤Fq†ßý—žµ¯þŒå=‡Y³N ¼Æ¨úòš?î©|/Z¬´-ç¦/­³S’ˆ Ñ_Éø;tÖ¬áïÑLL¥§âõwÙ³Ïвöù®²^aík´¶Ü[†rÎÍ“(‰©Z䫇×ß¿%£ËK›—(Qö>"ò Á—¡¥eÉ9Qé(ºïõ†böT¾ãwí˜ÆhFìA”æ_+]¾tÍD—Ò²ö®ÒyopÎ-=Xë²çii|¾è¯”9Šî}›–&y«ÿ÷¸»ü•øמGü®?GH”}2-§ûÍäÜ{ú!Ú`³e|½öõ½÷ùÛG JcsÝÿ“Àå%м9Êž;ñ[ÎèO¥v±ö5·[³GŒÇ‚Sî©þd€³ä‰®0Þ]ñV¬«äÉhYûwÅk/ú¬Ë ö¼I9ûºi”$´JôWÞØ˜ß!IjAu JuBŸ¸r›6þ»Ï®x(€(XÂXǺÛ0ÍÚW p=Ô‡bÂöèÚ-Ý£k÷ó>‰¢«ÀUöì—Š»hâ>?ÎÚVÝ„1fü®=7ˆ2OÕûÃߩ኿ҵ[º‡¢uëîWô—H0öFRv-ÕÄ~˜¡Š|©€b¢½¼çà`¿çÐh½‰ Ý·“(º80挜}åZ–d®û-KôòÞ“}ýî½ãsažÊwbhiüZmÂYÛŠXâw gí«ë'QÛîç/ÔQ¯æ‰\ñX,8¢yïÑaXpvaík´HÔ¶ûù+}ÒÚM€h·!e÷UÄùÊnžÊwb’—ëگإŠ|åSÍ©‰ûììi¢`¥6g”:úõ¬mÙX bà8I½ÕŸ ç½'‡ËM3éÚýºÑúýùýÕÃ×AÍs!œ{!©Ù]þR‚ÈWw0¥zÕ’ÙçŒ9…DžZÆ{œÓƒ åißùÌ?Ü£}øDëË$ÒèÓúÄ5›¯[NuØÓ&(ǘ3ÕÝ–bbx 0æBR à©|÷NFuývMÜçÇkŽG®ý%ç ‘jÇ8B:Íq?–æ­þø=UÄÓg{—®Òù·PÒ¸ }âÊm5'ã¾y‹Ñj;% /,ì0tØósƒÇQ>‰<­ý§¼X÷ù‡Œz;ð²=$^D;këiÀX¨úY=ÕŸkxïQ#¢ä•µï3b¯=wü$„¤vFÕ߃hC¹DZ¤OÚ°þŸãÔ#L`óŒP„1רµIR#‚ø,1§'½‹± iG})ÓO¬ðÖ|hNïð Æ¾ЉܣŠ|¡Ðg]ê1§§¼ ˆâ5±ÿ[ ÿj½«d®ÝšÙçuuÌûo¸JæÎ3g¤õ,È¥º1¿ÈôWzÍßÎãÉn¨—Ô$ò´e–ŒÔ÷)ªe÷í´4á8ëØx/—žäÀ Nè(º·›ß¹s ©ц¿ë¾FËS38çæÍéI£óçÜ“Ó&|»×’Ù{¨9#õ9L3Ê^ëµ ?hh?ŒzèŽÂ9Ï’Ús:S§¬g/tõ 7%ÑgšÓS^,¨dú _(Bî]é*¿A¦{?€&fá&{Þäù挴ë r©vä¯2Ãí«½5_äwPø¬¿ÄpÎ3=•ïEcÑE‰þ‰«dnŸuI£î›4™~¢Í²kiKÇA\>rO¸¦aÞ’„A±Öe6Ä„U‰þ²>ówZOåûÝT‘Ï?)7ͪ¶dt~ÑÚ"OÕ»!.T†Ï+ lï*{æM„¤fD)ª½5Ÿ+Mi§^säO½ öÖ¾ª=%‰8iHٱ–3j¬Àæ B’ Á—¨ööˆ£èÞn~ÇÖYš¸/^´é³üæ)ý+$ Ù…[wÅ;'¢xOåûÝ vÝÃÙיܕï¾DÑútOåÂcêáÿs—½Ôµ¯z¢5y"_=6¸JŸ(™WŸ´a½«ì™I´4.QʳgÍæŒÎO!JêÄ坯I5C—hâ¾<xÍ–{Ë0Á—> Ü‚Ew'€Úg”XûêˆÖyª>ŠÒµûåM,zâ_úõ¬M ß©Ÿå‡­Ë÷V}ÔÞÔ)ûiGѽÝ8ÇÖÙvÄïÞïD” Øé³-A1‘k\eóß¡™¸-1¥H\ IDATœ{Tn¸ãû«ñ;¿¼ç°œ–§pˆR7ùí¿û€ârz —Ûfc÷'°ÙR$ (Ú”«\žqM£¤1‡iiû]úäÍ«­;aL=¾P¢HûÕg]ÒßYxO/‘¡˜È6¦"ÿbïÛSµ0 ‹ÎdŠ‰Î¦˜èCœsçmu_ç½ÇoÕ&üü’)íäÛhëXw;Å„ ˜¨\ŒÙ0Ö¾&Ѻ ©î–?tí–îamË'"Ú˜E1‘y€™³øÑ4¿sçeøão;ìûÞ²ý7™þ¶ÃˆRç;ìû0‡‹RŠ +Ó'­ÿñr‡MÍœ‘öŒ½`úcœcë%_V½KfßÙÛó'}ÜTíÔ> à(œñäù^wÜõLcÚ³çÝ~¯«d^×+ìòØó§ô<¬}9HR#®u¸î¨2D©*kÿ¯vèÕ`Á©ĸ(ZçÈ;•éÆmªßEëj‡<#Êùj©«äñg(iL¹"ô¡_óúÚ½`цõ#$qbÌ«0î¼vÉÏÄ¡r#J]U[&õ`Á¡ÆØ¯Jqfµ„âG È¥ ÄÁÕþŸa1ö×½úºí‹þ*%å¥hƒ–ÆKucë éÆ Å„òg‚©ÝæUˆÒØ(ZçªoøV¢ìa­=~"ª}‹~5¢UVŠÖ9uÿ_õ€ AFIBÏ®T(F o¹iv:úÿýåq–Œ®ß`̵øÀŽ‚™½°`íK3Q¢¿DQ{rèDOÕ‡‘gf½˜˜Ã[óe˜³øÑ4kÖÐ‰Ž‚é½YÛozkÖàIžÊ÷¢ë¶é*›Ÿ$r…­YCoõÖ|pæÞföð ~÷Þ³«p;‹êlË7Rô—œsÍgþ6Äš=|Bà2­»â­XgÉÿ¥Z³Ofí EMµ½,[öÈq΢ºf‘(¯[_Ûþ#\¥O'Y³O\"öY—­Yƒn·åŒS7–ú3‡Ø²GŽp•>dË560÷$ƲåÞ<ž?­_`¿Ž‚é½ï¥îL'îŠ×âlÙ#Çž¹óÖ|jÍ<Éš5xò™KæãYûº[íy“6ö÷@’qc”=3x6{Ìù>@šø/þÄ¢7Jð—E‰|‰g³Ï^ì­ùê~kÖÀ)‹ŒÜ4»@d®0ÖSõÁÀ´4f«åT·çìy· ” $á‡eº›¾´åÝö^Ý{j#ÓßèwïiÍ6AôWöWǼ»QöÞà³|ÿkÖ Û±àì ÕÝtXðeM´fŸ òUƒê¶¡Ž~+!šØ‚DQ°k6'¦îë´´ÝF[ÎØÿZ2ûÎÆØÀ¨.Øìá¢àÐl^2`Ž¢˜ˆS¬í÷;œE÷u“jG-Ù‚Á¢`Ó \A{ÌÛ‰¢ÇïîÒgŸ³åÞ2Ôž7q°Ü8ÃŒEoŒ5{ÄxgÉã½5ßF’°R@´ZAR“({”P‰²ûiα¹#k[úÅ„W8‹ÿó ÍD–¹+ß|ÅUöl"çÜ’ÌÚV¼F1¡•œkçý®ÒùOPLt‰§êÃ×þÕ¦¢›í’(»eJäÝ€•ß½{¢TNGÁÌ,§®{˜÷žLC”ÊmÍörÝí=U £\å/¾C3‘e®’'?ðY›üέÝYë²iil!%1øýî½3¬Ù£ÞJéñ{ö÷»v? àwÿu7çÚ9šµ-{€b¢‹=ï¼ ø2µyZ&¢õvGÁôWÏw\ü®½÷û[ÇJT½2­Y7ÜÁ9·¥$¡5öܛߨ¿ÛsXô*EIçÜþjí6{¦ñ¾,yÝl9£Ç°Ö¥·QÒèr{þ”wܯ?+QtÊ”ÈSO‹¼E”¼š¢õ%e÷ÂËù’¤F\ÓÔÑïd«£^yb¬ ã]§ä¦käÆÇ䯙›(I¸`ê”õÍÄ”"JíR†>v¼~аG>£˜èbS§ÌÇtí–=KÑZ»Ü8ã¹a곆{R„<°‹#ÕŽÉ—g‘glÑÄ~œ¡ âuÞ{âì¥.™v´YnœúMmÓO*L3ÖŸ‰i³Ü8ó¨*ò…B]Âs)Ix¥1õÐ=´´_›°ø "ìÿÞ£˜ˆREØãsäÆ)ʰÇÊ•á?MÑz‹2üÉGäÆ'ä†;³äÆ+Lrž”(»ž DEÈýÿz6ɲýw™î–%e×à Ó=ÿßÞy‡GQ}}üÜi;Û[zƒ„„* Šˆ4EAAQ׆+*XD”&±,(Š]‘* ‚RHï}ûÌ–i÷ýc³qÄþ÷ó<>nfîœ{çnÈ9÷œï™FªÒC·×º¯Ÿ€¥î›Ë/u™{nÙÄZ®{Q±}ÒsÆŸÍ eRÕ«µ^×lLÛ°K—´â ÀE놘z|~+ɤ԰¦+ª :¾!B1¦®Ÿõwì_ý^413둼.qiAÅm1¦~°Gp=€T¥}nèþî>Z3p½àþntëùŒ©í&¨øÝ¤*m1uý^DhªCÁ4¬yªÉ듞+F("É”þõ:SÏ·„°©aŒ"µ¤K¾ÜXv Wß8>I©û­7twÉöÜèkym$Á¤|mèþî>J3€î(´©Ç¦­ÆÔ^ïìþhÝùïS×ïE¤¶„oX’LPÑ~‘ß3Zòe.»³`¨V°>eÍ]Ââ9Pq)VøÑ{p –ù^~ûÛV,ó©æž?|nÎØùB¤ëDó+ù '`,èE~ßXÀþD®nn‚Ô— îÍ×)R£…1\ä!]AÇUkã«ú_DE"DÖrƒµÜ``Ü*ÓD¸‚¡Å†îoïïìZ„(·:êöMô=õ¡c”æ,¿1íÓíÛjbfÖkbfÖ‡r„_ @ªz Úø*ã¥nh“:zFc¨ ­ÎuÃjg?úžzè`Kó@Äù…ü?k+¢(¡KüŠ"§¢«ê¿cƒYešØirsWúöÛß³ªÌ“í®Ò‰c©©›¥×/kOÕ§ÈïS“lOá÷†ðœMŒá"wÈm,ùް“,Ú ú­ê]5 ¨f®ÌòÛµ›Œ´~8Gfcœ›L¬y²ã÷ôß‘¢Èá~´ô›‰±`ÀŠ?š ÌX ˜°â‹¥Õ}?3öøl»½ðì›±ìê€ ÖrÝ:mü¼Ê–£©Ï#D{d–R÷ßdLûd§Èï½öÛ Üo €Ì"ÂPaÉ:¸ÚqlèuŠÔÒ @Q©cf®ð5¿t`™E¤¾ÊÒëà˶¼Œ'ÕQ·­‘…2³àÙq)­ò½ì?–eÎÜýž¯yM¬·ùÅiÖì£Ï†ÆlËË\ˆ¢Žºý _˺ëK‚ŽÉ7gìüˆ«}¨gÀ¹ézLL·½¦ž›¿´¼+|,0¦mxNðlOS¤Æ8¡xL?‚Ô»iŸn÷TÝÑGôhH^ý»ò¦Û1˜b–¬_Ÿw•]u¾ä;r iÝy›B. DZó® Þ&UÆËÞÖ%-?fËë±ãÄŠ?šRç|.Ì*r{Ì"÷ã(Èo9Ú} BŒcQÏƼjHYwN<Õwçž­-Y¿.FˆÁ­ó~5çØ|€à?TWù”‡ Ý^_r¿„tò*>Wÿø÷Šd£}Í/2glÿä÷öoËï5Ïš]¸Ð–Ÿ=ל±mÉÉ”#\åW5¦~¸çßm×Çó×ÙËyÄÔã³§R´8]ø;4€“ýaï’„•cC¾~áH‚ŽÉ×'­ìRšÄÍ™S™&µw¶Ž bÚögÛÄŽ»vbÛ¾B þ³ Z8g„û〉T¥ÿÕ»ü^E¨¯2MúМ±åAÑwøJK¯}¯³Öë_%è„Cç'—`…ÏÒ&,ZfÉ.˜-z÷Okµü¿ßDÐ ‡¬9%a…‹÷6­HÀدG”¥ÄšSò`ÀñÉP’évÀšS<Ë\ß°$Y3ó%oó óÎ/féŸY­O~þWY¬ àkY{­°­Ã˜­´fðwÖìü§}-ë®cô£¿Ô'¯\¡ˆuƒE~Ÿ:àÜ8]÷ÈóÖœ¢ÇL=7鮜Þ0&õI+Ÿ#¨è®æÁ @ñ² øµê¨é»DïáËnÛ$•aì®öá1ˆŠªÔ'­\ ØS=3[òå^Hk‡|jÉÎ]¾ ˜3w¯WGݺ–T¥í –ØÀН»&æþµ–¬ƒ÷K¾£íò˜°â¥0˜Z?gš3¶ÎÓÅÏ{Bôì˜ò7|År $K¶îʛθ¾˜ªÈŽóBáå\ͬ ±Ì¥sµs/]ƒeW?]ⲕ€E•§úž»å@©N«ÏíÌ>ß°$ÙoÏ |»åjfe†‡lcÅ›Òúÿ$À"êrus{„oÚK¾#¬Èí¾ÃÛ¸,Qävjƒöö©Î&è€,”Ó‚ûƒ·ù…øpe¿ý=+W7·GÇöÞæâCaê¡ñ„އ·ûM)åC›MÇ9PÌð K’ÃÛ†©‘$†ÔH"üý{|¶Ýšsl¾9ãÇO$›õwcéuà•£ßgÄ›£;¿¦A—ðdY𨬰å¥?KP1‡Q¢"{Ò¢\aOH‘Ûç ‘ª´ D+Eî§4Ší•  HÍéŒá¢M¡ó¿·‡!í£|ã³€Muh• ¢÷¹Ê§UdÛY†îï¼ÔqÌšØÙ¹Xqg‰ÜvAävȈÐUJÞƒ¬bƒáá­wâ/ÈÁ²³'W;炎«ÅÏ£«¸Ú9„¯ù¥8¬øâµñO”Ûò{O,j¹Ú9I€d¤{äyoÓóSmy=ocôcVº½v(dß–—¹QæR‚ÐÛ±ÌuåPGÝÖlqâ곈`K :Ib­7µpõó—¢öÿ÷•Ä'ùó,¢Ûæ] ׯ=6›o\¼6"Ee¼Ô-r;ø:]ÌDn§ÖU1m AYsË4k¹ö%Oõ}S¢öcïfM“^Ô%-?Öñ:{áYwVh ÔN¬ðŒ>é¹Áóƒ°dõ;?#‹5ûø†ÅÝä@É@Œ‹oXä°ôúeMȆ·qEÏ€óãŽÃÛ¸"Ue¸ømâÓù|ÃâéˆÔ5¶}÷asÆö»iRƒ–"ÒP†AR©£g,P¤FÒQ4âQ’N:¤‰¾çË]wÅõ£Ép}‘BO•™3w¯çjÅ#‚mñÛÞ4Xs t¦Fr&£ÈR멽•üýb©…  >ÝÕ@NFW•QÎø'(Œ„•@´:zÆ·Xv%üv\68KÆŽóTÝÑ€ä;þˆÜ®Ë½Ë±a¸6nÎàQPê>? îo'·ž¦‰{hŸãØy·L÷Í€(ÞY:q$€&úîE϶ù¸£³±!B­L·ï€P»ôÉÏ¿Aë.ØÊÇÚ Êr(˜Œ¸OímZÏZoþ¦ÔQ36¨£ïüˆÖ j·F±Ù_ð ‹—’L·­ŒnØ7š¸¹ï©ÌS7ÑÚ³Dßáh}ÊÚ×(6çcÉ—; ý<ù’4Q·¥ÈÎÓnQúÓj¦é¹É_p¹)ýëyÖì¼ÅŠØ4¤ãC ¶Ê’udk¹æ9Û>‘ Í2£þ`…ÀW;g°§jÆDY ,Y‡^´få.“ŽÂ¡KiÍÀïL=7nR}×ÏihAˆuÊBÕØÐqÖrÍ+–¬#+0öÅc, Éwä cêGóÃÕHÎdøºy™îò©wþÓýr5³ú¹Ê¯¾%ü˜»ò–Ëùº¹Yµ÷5¯‰u–Œ÷ό«J,gÄ¢F±Y;(u7©Êø@iÔS?ØC©löÛß¹Juó-!‚õ˜3v|lîùÝr,;¢‚Š €èmÜÜÏŽsæ×ˆŠ’Léßl ™nEîªÛïù½C¡QLé_½„Ç]9m–ä;§Žº¥Ym¶Ü×òòT_ó‹×(ˆÒô¯ Ô}èS^ÜNPÑ?kã|üyÍÆpÑ|ýÓŽ'R+r $É]9m6–QúäßÊpñ*¾qÙt’I)"ÙŒÏ:›ËvãW÷sRlöÎSµ;] Ô½¿—üw蓟o G÷ÛÞ¹+‚Õv´Ç Œ1ÇGW ÄÔZ{—>`Í)uÂx% Fˆm{ªTÄÊÛüÒc´î‚ý”ºÏf¬ø«¥`É:ü©J=Æ7.›ë,½´Ct) P¨Ðï „±ìl÷o!2¸¿A€e_??Upo¾–5OùŽ -‡±d³bÅ«Aˆö¶ïa@¤O‘]耧zæƒÓ¬‰¹÷©í,;L#ÊÛi·—æ,7ÖqlØÿ…”A®/ žª;ú8‹/﮸~p¨]HAD*ã;ÚàjÌàjfe:ŠÎ¿š«›“Î7<•â(9)X-:ˆ»âº³]eWŽ87ƒØA\e“‡]ÉÎ’ñyªgf‡ÎùíïYELVÄú˜ŽýÒÚ!¿ÒÚsê}ÍkbƒŠ##¯ðTßÙÀïüè\É_x…£häÁR:;µÎâ /ãžNéhÇ]yóY\탎¢‘“BÂAE’3ÇλV‘$_¿°›³øÂËD~&¨(2q@08ÄU6é¾~~jhe¡œvU\;Ä×¼&6¤Âr…+b å,¾h¼£hø”âJhÞE#'uüwpn4¹Ê§œw¢ïïŒp?†ç™{þðyÇÏ­ÇE5š3¶}Úîç°kÝ¿jãçm ýÜ1Oɘº~/´…Öš3~ü X½Öœ±ó#9P̸ʮ¼› ¬ûÃó9B˜Ò¿û*ô:¥5`Oû6ß| ߆~ÖÆ/¨ÐÆ/XÕÙLªhÉ:ôbø±ÖÈĶèD֥Ι-x¶$œ—Òº¡KDþçËÝ7€&î‘#žê™«ýˆn÷µ©kç9<ÛF(’­/­=÷]¿ííEˆ4ÿB©³wsÕ÷>¡2^z¿­ Ï,‚Ð7¡qÛ ,2gîzÌS}Ïýz€›}-¯EK¾ƒ—À.GÑÈçݰ·DnÇ(gɸdmÜ#»¸ÚG–3ú/ Ü7”åèqýЇ°Â«Eþ§{iݰ•××wôSÏTt“"TÛ(M¿B¬ð„«üšµ´nØj¿íõ{$_îFcêûmy"·ëJJ3è wÅ /[s § ÜŽ‹±Ì'3ú‘oyªî"y\Ni}æ*›²Î’{ƒ"6ts¸R‘zSlŸ-€hÙײîvMììyžªbÅ«”‘Ûý ­±8àøp†"T¤Žšž(““$­U|ÃS‹UÆq·\_[øú§–0† _À §‹ox*Å×òêÚ˜ûÛ©¶„sF,j„PÈigX³ N8a]…Tõ,YGVüY;þ^Xë?cÉÆ B§„°U¦«*b=Åšÿo.A'I­Z–ë“…*ZešÔNÆHešÐ„ÏËíìš';hí Û¸šÎ#éÄf‚Š•u‰Oßçw|Ü_÷È"ElP°¦ÉKƒí§¬@TŒÌèGïù½½T¦Iý¶7Ä’uèY¾vNAÅùÌ™»ÞçžNQÄz>ù…7:ÞAÇ~KÐIU*óÕ;BÉÝKKeA7÷^DšD’I-ÙG¦{ªn?:_h<ˆÐ)Öì‚'Ý•Óûc…#B!ÛÆ›æóuÃèG~€e×g¬åêH6+ÐzËiVÌÛ6rµ¤+²MËèGN#Ui§ÍÛ"tŠ"5v“EÃ0åm~i©êY(ËncÚ§ÛÝ•7z$_î ¾n¾Š ¶º¿³ßUv+Šu´EkúlL]¿×–×£šµ\ó6îѪ–£ÝnÀ’³·¹OÐåÛ’›| ©/öTÏÌùŸÎ¡Ô6yªïÎ,ĉރc+Œì/ìÁ7.•I&å{C÷wö;K/5)b]§yoÿƒ1õ£ÝÎ’‹ ‚{Ë Z;8WòåÙõIϸ+o>‹ ¢~6¦~°‡«™ek k—ÌÏƾ§O~!ß^Ðw(Wó@Zwîû†n¯²åg=®2_½V—°¨Ô^Ð÷®æþþæÌß´íñ:"õÅÆ´ »|-¯YDn§VòoL]ÿ ·qÅ@‚ŽÞnL}ÿ'OõL—àÙr™ŽÍ<(Êr$%7°ÂruóûÈþüÞ”fÀ»áûþ€%£¯ù奆n¯Þ^o®#ÿÙE-B€V £è“Wåt ä)ltÌÍ£Øì€.aQiG;$“*†{Z•K¶´³ÙÚ‡.ñÙb€ÖœÃNóbpø˜Â•<Úµ#X ÃS?h÷æß:Ævã$H³lLýhwÇñº½úkÇû4¦ml·?¬KXܦ:º‡àçãÕHNÜ•· % µfY¹+®ì,;ÎU>uè©îÅ]yËgÉØñîÊ›Ï:.@à”¿óû‰Ð]âÒ¢;¬út…1\\¡H-gÛò2žÂ²»Ó€ €à ¶¼Œ§å@éÅ'jw"hÍ€E,±åõ\ÚÃÖ'=W€eW?‚4å#B§¨£niF¤¾Æ–ßk¾-?ûQGÑÈIºäçs±Â'Úò2ž–…ªÑ¿§OMÜ#U ¬¶¼^ ÔÑ3êQ^[^æBÉ»ï*ÖrÍ—Û‹Þ_'Ùò2žDs¥ÜXË5_ŠÜOSƒù¶4GëFØüö÷æêŸ}œÑ\*wcèþúEjº”1\ÜVx+¾[^Ï%¢÷àdµõ†ohÍÙEr ê"[^ÏÅXñ%蓟ߡHM}mù½æÙòs ]kéõË„¨€½ ÿ½'ºÏ3BQÄS™…‘í IDAT=3[ešXÕY¹õ¿Á³UpnJ =Áÿ<Õ3³®OgSlÖ'”zÀ±Îžb[Žv[G©2>Wdg¬"Ö!™n_š3÷tšò6­¼K‘y²P66ªwå ®fV¦ßñÑ#ÇOrœg;Úc­¶QcAoÍ)šÛÙýÐÚ³}ˆÐþp~/¸¾¸I7w©Êr­Ív4ý5h^ô6½ø°·q¥QQ»(ÍYþ€k8gí]7ÙS=3ÛoïjRÕýuEjhÍ)uü¤ùIÀþkïú‰r ˜q]jHyéq‘ßkõ;>¼Ž ¢_Å2—`Í)y¨µnWfëüµª®à€c‰Þ_¯2¤¬~TTª½MËï#¨¨—dVŸüÒ’Ð/¥ß¹¡,|oà oÓªø‚¾¯å•˜PÒ¹¯yM,¥éëiUó¨dô£l’ÿ¨–Ò âŽâµñ *øúÝ :™WGÝÒ²‡±€øºy=T¦ u‚û‡hÛy£·qY=uKC('2àúr4B´ÆÍXqk±ÂY¼Ë㸖ðD^_óšXÖz]3"tŠä;ÂbÙI Ü ­=ÛAë†ñÞÆeÉšØÙÕáz‚{³^ô˜¦Žºs>k¾²1àÜdIJDbÖrƒÍ×òJŒÊ<ÙFfY‘¤èÙ¦W$Za-7ؼM+TÆËZÂ{%¾*4”æ,VøE¬gù†§SÂ÷÷°Â~Û»ÑáU"œ^„¢¹ÿ *ã¥n•ñÒáÇôI+  ðÏÚ>gÄ¢IÅ ÒÐ( UñŠØØT¥¶¹ ×7Š`­75zW„J"”¤Y&Ué6Dê ÊlSĆdh‹BC[JP±²:zF#߸8^pÿ`@ˆâØz¿ã#è¢Ì»­Ù…msŽâÑ—tÌ Ÿœ©‘Ä ŸCë.höµ¼Ó¦,‚’HR[oX©HMÀ¹ñ!Ej$ƒcÓT°–«+®Mi‚ëËtD `øí^ô¹>ۛɀý mj%Tt‘Àý˜†HC5I'×(bc& @°Ê±dcŽ, øº…®ETT6î±*‘ßû­§êö…@¨­ÙyKN4†oó ñ¾¦çg"ÒXæk~>Ã’uø!_óê«ÎO‹¡ñJþ¼*ãåëCjû·ùš_Y€U#Á$ÿ,WÞl‘|¹g5Þ¦çkvî2OÕ}îïn!è˜C"ÿHƒp Îïüx ­ºh}JŲ3FLJ.D™œŠP=ÖoÛâmZÕ_—¸ä~•i¢Ã^pÖ“ˆ4Tz›–fjbX*x¶õùŸî"(ëϾæÎF¤ùW„(Ÿ¯e]ϨÞå÷„î+àÜØ!.àúl–í{ü¶·W"ʺ›Ñ_ð_¿h&"T¾aqšÊxÉZŠíÛÌ×/xQQ;°ììÃ7<›‹!yWö7glZØ÷æ6UZ¨ÜàmZù"´u~Û±Öœâ9žª;úž-S©¯õ6¯Šú+"‰ÿI0ì/TuUãQ3ˆ4È+KÞƒ,©îø'«6ÈB9;sÝuÉŸ¯"™±+µì:S0èºÒV8B”1§šÛßûtäŒ9*ãøÍ"¿jÐÝötJPHSa¹Ú3\¥“&TÔÏÆ>kžìÀXf]×ájç^×>A¶,¸ºÇÓ¸ºÇÓüö·­šè{·Éþ’ Þ¦ !• €€sSwWéå#dž>CP±_2úQA™s%cÇ{jîË@JHÏ ‘AŸ¼*Ÿ`·¹Ê¦LPd×`®ö‘tOõýW“tÂn]Òò_©ù®nn_óšØpÀÐÈZ£âccô£7ë’V¼Ik‡üª{ô "6 õ6.KùŸ/úµÚÛ´*Þ×òêUÁˆ> Ô´öÜú”Õ¯ÓÚ!û}-¯E3ºáún¯>ŽOV8!ÚÅÕ>’ÞÉþUü¶·.C¤¡œ ãËÉSuÇ@SƶՒ¿à2Ñ»š©ÇKt‰KJBjÁÂ…˜ÔÄÌzÎÜsëgšØÙyP @HXn†±€ÏÖÉšèË,™{ß2gìø˜µÜð "4e–̽o…»]:þ ©ê¹ÝÔóû¯iþÕ’udÉf~ì·½y®»òÖ!˜ èø2DK|¶·Æµ¶ûÅ’ud%AÇí ¨¨KÖ¯Ï#DzÃu õ)/ç†ÆLPQ> ˜FkvÞbŠÍiPhKÖ‘•¬ùª϶˃ƒQÕY³>Ki¾€IKÖ‘·“¯_Ø/dS3³¾MÕ¤5”1\ò¦%ëðsKz9PÌž-Wt¯P‚¾{x±ÌÓ˺XWÙUzP:b/<ûfg鄇½MÏw·åg=~¦èÙÑå æGÑùW;‹/~Œ¯_˜ãª¸vö±á*›2“¯_xœhgðu÷rWÞ4 +a?vδ6'Qúàëtw•^>À×¼&ÞU6å8OVGŽ wÅõ3º2¦Î8#5ŠÍÞE©ûÛ)ußBJÓ¿€R÷Í£ÔJµñ *T¦‰«½M+o\_Ð%.yTðl¿!J4öøt-ÀoJ”º·‹b³w?;(u;Åfï o@µ~6¥mœ¥5)_‚HmyøØhMÿ&DèË×ã×ãÎOû¨L]ꨛžôÛÞœp~:.dKä®HM‰´~Ô;Öì¼ÅÆ´O^ÄX¢EnϹú¤sH6ó;Šíã0¤¼òa¨!AZv îo/A¤ÞfLÿꂊ•5q=,¸¾¾Ø×²æjÀ¿¹¬I6‹#Ù¬6õ }ÒŠGD~ÏÙžê»ïUÄF#¥îëg­7<å³½y AÇå†Ú©L“–ùZÖ]OªRsI¶×­cxTòçe¹+o™¥µVùíï]驾÷•qÂò`$×+nûy¾–uiÉ—þWBj7AÝ´vÈFF?ª<¨ÎÑZ`Q­)a+‰!ך»âú›@ñj5±³>„¥&@VT´ÿ·ædÛn{¥-Ä©k@„–ÊOͤÑM±Ù¿¨Œ—n ¶ÓÝzˆöTt«‹ôËB…æD·‰M€";hUA¤ÑXVǨjí[ã …w#Äø°ìÑv°Ôî¡Ö¶B*À’‘'AÝŒnø+¤*ã_Õý“ gÉÅ—„j*b Rù}jwåôþ\탊X=‘ âŽÊþ¢x,;‘tâQÆp¡'àÜhržèky-€¯ŸŸê©¹¿—£hø”pE‘p\åS‡ºÊ®á*»êüߎ]=4¨:råpwå]eWŒÀ Gpu§É’©p˜1\\IiÎÚ, å´«lÒÁý,Wù5ç´*¾<$¬ ੾³·£xÌ„Ž…DÏV§ê¶~AU“€s£Iòç«Ü•7¤µç6К!‡¸šú(B厢‘W„Ä­Ý•7t–Œ/Š™p{÷·ˆ¾Ã“œÅ^:æ,7ÖU~õÐh¸"ÖPáª)”ºOiîüm®º¯®pF¸C‰~áå ôÉ/æµ}jèµéè±æ©vÖ‚¶Ÿ(ׯ?±¢£­Žªž‚¹ç–v2[¦ô¯¿ }¦Ô}ýæŒíŸðõóS‘~K֯힚4Ñ÷Ôk¢ï9NL™Ñâý¨¶Ê*Ó$§Ê4éð6º„E¥º„EK¹º9éççéÇÏ%@p3—1\ØÎ搜º­ò‰&vv­&vö[Ý㿉Ê4i£ÏöÖ,DmXጲXßÀ—\z+­9ëBq–\:Ûš·!Úé(º`2kžòc;ŠìHð6­¸ c1€Ò ÞÈ×?9×ïüì „ŘöévOõÌGñè‰ú¤•ß…Ü*”ºoaÀõù®ò)n†RÖl³v¥,Ö' D z~'ڸǪ|-¯Ee–jΡ4C6üžë¡/²¹Ie¼x{gç)í$ï‰Àf¯HMIˆPåuÖîEvŒ$‘j«ä=8ÜQt~º6nÞ×"·çÿ`¿Èï2‹ÜWhãç=°ÞKiúT /ò{¼”¦‘·ñÙ$_óšY´aô›|ÃSóÁ.<[†ÈÊKýÈI:á¸Dt¬p„àÞü"­9kž¢p{Aÿ–¬_Ÿ<ÛQªô×T¦Ë·Ûò³%™ä_±~{áÙs´ñO¬ ü”¦_‰EnÏu$“ú³ä/ì,HȾ£—1Ʊ¯sµ¤œßFëG¾ÇÕÍ}Š ãô6­8W”¡ØÞÛ%ß‘Ñðqh,”:Çç®üîNfˆÜ®‡©åM‚Ži™’/w0k½q¸¾æ(M¿B‚éÀJ Eög¢WÙ•w‡‹N¤±Ë®æÐˆ"Û/ QÆ’ïÈ(WÙd•©Ç¦möcÃVUSvŽr–\ÜMešôK«¢ÉAÁ³íIRÕã-ÖtÅÖŽóv"ΈEí߯œ±óø´˜ÖEòo ÄÐ%,.Ñ%,~æï°ýo£_PÁZ®ÅÕ<8”P¥–©­7Ô)bÍ!MGOõÝ6¬p„¹×þGøºÇ{!*&R0elY멺ól‚Šq1úÑ[#Sßÿ)àú2Ï×üòZ7ò€)ý«Û½M«²©o MÖ'¯Ê§5ýŸ½cÃØE¨,P[§T¤† “$kNÑžÊ[aůÒÄÜŸ+ Õ*E¬/P[®ÿŽ`ºyXËÿ½¡2^Ö~o¡q2ÆK›±â3tÜšsìOå-ƒÔÑwÿÀš';d¡œV¤úׂ}ß'J*Xë´ÍÕî°%ëà2¾nnO‚Šñ©ÌS_aô£\*˔Քv×h¸ð'‘Ûy„o|v(­pðß*òg@„6×ÔcÓVÉ{p³lÒsðuÇ6¬åZW7‡‰NûZÖðºÄg‹í…ƒnÀ)‘Û=@a|-kGªŸw”Úkß'SnÉM~!ªÅœ¹ç]Ej$½+†…~q°d?—5O^ÄÕÎâõIÏHÞƒm.}sÆ+íý?&èÄoôÉ«Ú úͬЭãQy–\ åçkb\¡Žº­É–—þKø8‚[ HòTßÕ—`¾RĺþŠÔâf c¾Ä²C Àš§4y—s¡{Gˆn1gî^Ðr´Û+ííÅ5)RK“.qi‘·qY"Aö›z|¾…«}°:àúv‚§úžFÀB¼è=8@¡%Qº  mLQvKæOowýÛ‹,j"©ê){|¶=ôs¸Hqè…}†0@P‘ãývòBmoüm:›”º¯¿äO+­oò¡ÅÈ Ð¾ø"B ¯ÆÞ àPGßÕ:®_PÑÑv(ŒŸb³T˜×¡£M’IµñO”0†KÜLë8~+;ô1X—¸ô¸<±peZ7œ7é†wª1zZÐá+ð»Í16’M÷ãÖ2V"à8ñßpÒRKPÖÚðGѰ©ˆ4œ4íc) @òd‘Á  D¹Z‚­²=™®öáþ€Ô•ŠÔn/¬M¨À2ýÛ‘ 2 VPhZsV“àþþhxdt¸¨qh~‘E-B„Ú)[^úRŒeµÊ0ö’I¡®³åe< kBÑÓ¡K~îWéÚò³û–UŒaôqîÝ–Ü„O¢úÔµ+º‹€ðÙòz,ÇX¡iÍàõ¯¡Ô}6Úó{? ˆq Åš»¬c¿ã‹àÞr·1í“;ù†…ÜÅÎÔ%=÷Š§êŽ‡lùÙCˬÊ4á]Æ8ñ3¿ýÝû×W<`ñ¸D9Z;d¯ßñþíºÄÅ…~_1È-ªðÅ:š[^¯šØVŸl&5q8ŠFÝjËÏ™£¶ÞtÜk½©ÅÛ¼ºÚ–ßk>)Ttk¹æÇÎlu•3BQ$ÂéMDQ$B—ø‡E‚¡îe••,Dn§¶«îT‘Û©%èx±cø»ß±ÁìmxúÚðŠXá[~ÎË–ÌÝwaÅGt¼¦ãõá±]EðlÕ‘ªÔ@(‰+!û‹˜?’ðwЙjÊï%¤(rFD?FˆðwÁ7<•b?vÎ':oËï5ï÷سô½?1v2'³kËÏzìtÑü<]¡Øì@Gi¦ß³?Hë†ó-N¬y²£c‰(@ &¨˜$lA ]ßÕ1„ÃèGqáª$ˆÐ)ÿ+ @Ðþg´p"‹Z„ÿ°„K’ýÅŒ·iED8íAˆÁ–^û׺e„®ÙS‹ðŸ&˜ÿÎl‚4ó6­H¶æ”ÎæjçLSdG‚ŠúËž]‚gûxMÌÌgmy=#BÓàkY›€Ö<ùA¿ý­Gu ONçjç<íFkóÛßÔ[³ ŸpW\?J‘lñ×)ùTY(Bì81ÆS}÷ƒ€ÑÛ¼ºÊ’¹·-õÁY:q¤ì?:ÛìmXì·d^ஸv>"ÔM¾–uZkvÁ“ÿÐtE€“+hH¾#,©Jº¢ÐÌÑjž²­ÔH*’¢Øì€(f¡Vºr݉laÙ}œ:ȩƊ±ˆ:êPžŒ“Í•,”ÓˆÐ(áoÄ HöUè-²+ê%‘7µÿi×ãýèu–¬Ã«1.®ö¡ž”*s“¥×/k¡‚rZH¶d^Åè/z³3[¬õ†µ–¬#+°âKÐDßõ3AZb²P5öÄ£PTæŒ- ­ÙO*B]»$SÉwd’¡Ûó­ÙyÏ(²£O(¹UeºòUKÖ‘ æp%‘?¡²*Ÿ›v‹ÏöFl×mÝt±«bÚøSµs•ÿß¹ŽcCŸáëæí8vÞµÎÒËæxWvI Ä^8䦎Ǹڇû»«fŒ;u¿S‡r5³2ÜUwŒpWÜ0©+}†8é\UNÏÕ>ÜŸoX’*í%zvè\7œ°¬ÌÉÔKBDÞÔ"ü§ÁXb©o}*$ýXv«HUZõ /B'A«ŒÚBà1§zæC´vÈ&Ö[üïÝ͇Ȣ!B„°¿·>iéZcê‡KËÆÐq’íÝ.Of€»âúá1^kvÁ“ˆÐT`Å«¦Øì"tå®òkf’ªôoþ{ø/ÙS‹!B„N@TôOõ½(4 ò¤ùR´ö¼boÓªi¶¼Œl¬xÛ Å²æÉz›_üÀ˜öÑ'»>Â_GdQ‹!B„N°ôúù ‘Û©¥´çxCåX¬9%ývþ—µ¡ÏšØÙµ¬õúéŠPK‡'DËò(’Nø°«I×þ<‘E-B„N­Îwµ-AÅÊáUœ=Õwö½.4¤¼üüß3ºYÔ"Dˆáo@Ÿ¼ú(=eÃ)‘@‘"DˆpÆYÔ"Dˆ!ÂÃiå~”ýGox*²ŸaH¢Ó£þQ„3ŒeP¤ÆH"ô™ÀéUOæ” #œ®㿤VEÅE!uzTÄqæÅZAò—W=¼« „hJÝ;‘†È/Ç™†À¢÷—†ÿ<9ÖoÞ5´IEND®B`‚openchange-2.0/apidocs/html/mapiproxy/mpm_pack_unpack.png000066400000000000000000001352621223057412600237510ustar00rootroot00000000000000‰PNG  IHDR´*91ðsBIT|dˆ pHYs × ×B(›xtEXtSoftwarewww.inkscape.org›î< IDATxœìwXTÇ×Ç¿sïݾKi" ˆ(ö öÞQcLŒ&ñ—Þ5–$ÆDcbL11jb½;ö®X•"é½,Ûwçýc *(,–ûy`ê™eÙsgæh`¥•¿´зšò`]«) ¨šò±|«)@ãjÊß`S¥LQV.¬RÞÀ´jÆð0±šò†WSÞÉku­RÆÖáZÇ7ÐZ}ª)­ÖX‡k ¬¦||=¯õµjÆö©Ãµvj µ²UÊ]h­Ãëp­Š*å6Xkp5å}ëp­`­ƒ«)ïú¸k€Ü«i,­º ²r9Y5åV$Õ”ÛUSn @PM¹}5/SVNª”sì«CÀ¶šr1ë'a­eÔÕZmª)·ÄZ…Õ”Û=åk7ÀZíêy­ÒZkÕ1 ´Vë:\+S¥œµÀZåÕ”+êp­\¬ÕªšrÙ㮕C)Uƒ‡‡‡‡‡ç)ƒ¢Ð‰TÒÈ<<<<<¹•e ;¼Ð‘ .b™} üó™ë‘ýž¡‰7v~³ÿ§Þ/ÀæÙ^¥EûØÊÑû¬Pb}7?ý–,7åz“’ÜÄ‘P”Ó#ãΙe¬P’O©Iptùè}›rÝF™Ÿ2.íüÔíü–÷vÄŠlj2 þ:pä¥\oRvë'MIޝXîºesNR¨Ð¡I»d¢±rò¹lëpýÚþùNÙ —¾²qö;eëpÄhЊ÷oÁÃÃÃc)n(þL}Çø« IÚ ã¨¸·•«©ž6HˆDÀÕãÕ©µËîès)ÊŽ}ɹY÷måå©‘G%F½6`âÂäoGμtDfã¶:7ùê ƒ^M Ze÷!Ÿ;âó !2[÷-UÇ ìó~>'§sBÙÝ~on¿Õ¤õðªÂ´‰p~ÓÛCbʼnòÝšA[Úgí6ǯXpC¢pú;xê†˜Ìøó"ƒ®´³[àaV ÑHfFmiþˆÎc—|4äÃcG}quù®±2œHv~ìÜðíãçǬ" SxrÍ”æ•ë“ÃöJ¬NKN™r;XP*8³aº0¬ é¥oã5ëÊN(¹riçg:þ>€®Ãˆ7ú¾±í¶NU ¢Ô$×k•ŠöÃç‡~ÿÈåºø[ððððÔ7Gt6úlÓ$ÛAÂi-vZ­ößl5Ú¤¥¾ Ÿ—v´¤„{BÈ4†RšG)­“PVmÏÞ§.É~ÑdÔ;÷~}ctyyüÕ­®„asÊ+S :•Wâµr¢³qö3€TÑè¡—Ý^ú-™0láÑ?G·RÜèìóÂúò:N$;þêÏ…}<‡ P+s¦„YìsîïÆ”RQaft×ÂÌè®FƒÖF,w¼”ró€”R“¸Yçɼ¨æ„ÒÔòŸYNt·(+¦iåz½¦ÄÏdÐ5*_$³ ¡ÔD€á„ÉåíVP¨×–ü'«A——ÞuiÞëƒâœøÁ~î²û»öCöðððð< äý« ëÞ¬óäBå•=_¸@Qvì 5™ÇÊÑgCÆÓs@©°ïô­‘Uëû¾±í¶Dî¸îÖ‰_?ì9eu!lß ¯o}iAܲ—Ä-ëûƶ]CT,'ºsôÏÑ­4—VUØÍ W“’ÜDΠSµmÙçý •ëM÷ƒ0šò±GͺòG‡ß$=hL†asÓcNZ@af47à{Â^^œþ‰«_ïwKò’^ªÉkÀÃÃÃÓÐ MDˆd±'[aàÆHqǤ†³%å ”(¥Yuúêů£WWWnÓÈ÷ûÐ=³×†îc`Yaj«~Ÿ[·–?Fž^þwÔ™*†ár«ë[•þ3v…lç÷ÂÞóûûµé8zÑêÓë_?{eÏËì-ˆù駈¥J2±Ìîäøob—7òê²$3öÌgë?v¤”šD^mÇ~^uBÕÆÏ\÷S€•X9oôé0¡$'ñJÅN«÷ëOíû±Ç ë>²ßÉ0lžÉhpm3xö”É/µqÛväû?#B–d+½öfFȲÂd“É`oëÒbyM^žêÑ(³úšÆëd‚®©Á&È…KŸ×[vóA}6„i<&‰S@©£ìŒ½%=ÀIΔŒÅutZBö§ ÂLÜSh‚‚º¹Æªµ<¤4”Ò¦„!„eNMýz¿¶½ðq¢íÇ…nVøt˜pÏ1Ÿª(M‹:.}Øñ_9±—6(ÎoyçPß7¶÷soÑ¿ÆÖ4a‡::x´SVí~d±ƒ}ã Òªå›¿hú '’eöš²f›º$›ór_sþÂÌh..t³}ÐÀ™Ùœ@Bk*¤Çœß½}Ø®ì~í¾DY!½vøGN[œý v<{àΰÌ_ì>c6Î~†êŒJj‚«o°ÆÕ7øÊŒ‡‡§fœNÔ5 (N€þ¢Œòº8ãŸWÔm‹4&éK­ÄaÓÚK?c>ì&96Õvµ‡5[ðËEU6Ëò_1Qàïkjo©€h6†k|Q‰9¢[}Mí_Ý:ü’÷ú´Ý%Cº5ƾÝYršØ°é“ƒÄ)1íÔ6Ü\t³¹[:¥­8YÄÝŽ-8+˜œWÛŠ“|ØÒþÍ„·öFi›¹Y1Š^ÝYÜ{û-{ËFÏF(0ßuŠ_{²ûí '¶þ¶Ä(°Ï‡ÆÃÃSgBšxÀteÅ_:HwKÊácϪÊîÍB[ü’7mw¤ÖMk œ­„”ôñ¦@oaŠ·[­R2Dû}û¿«–ÛI˜Šöe¸JŠš! z`Éÿ•à˜Œ&01]{Ûnõ—ÕÍ~¿¤î¼9B«Ü3ÉÚ"§Mõë;’dÉmXO”mÊTuj¶ÏÃÃóüAq$„¼K‰àSŽ >pÚ’ò,9§ò»•e>Î;¯sP騸[Aî[%wì¥D3&@”Ö֕˲0q ¨„#Ú¸<£´6ó ÷Ý9£m™Rh”l½©qW驸‡§ R‹.»#µ®©EFqHœ®ÅpQl\žQš\h”|ò‚4zaù‰»…FÇúXÿó Wöª¨®œ«yxxž}!Ãü@G&˜-¦ËÑØE)ý•ÒÃ’²å”š¤SvÔ¨ÐÍŠÍÙSvÈYÎh`ñ@ù¿KÏ«:~p@é$õü>²-œ |»³ää[{‹8ȘâåÃg¼íÙÿypMS[¦Â€ìÅ@qjbñæø-E#eLñoÃ{ÊëZ8rñ…ªÛ.8i²ÕBtcT QÚ¹d½ý'‡JèŒ8HIÑ—½eÇ,óŠðfÖûQ ` ¥ô©±ž®KäB¢·—2Ï„ÁÇS„5€±µ1 1(•Y)Jå#¹ZñÔ¼E*E¡”BæXÀ¿ì«=€ >*'£VC)m0†f˜Ÿ(s˜Ÿ(³¡åxž ”æXQc…F)5Bø§žç2+²„²¯„Î6ˆàWÖL `¥”¿âij¬Ð!VB¹sc€ã-#Ò‚Ô©mÈÃS”Ý£Íð.€·Ì-«Ò8K)m$f+GOé”Ò†vk®í°y t’ˆØ%¿±£AçñðBÜüóZ;Ji!dÌÇàÙ^lHùxx8]ÂCb–ãпFíxêžÔÈÓÿ ÊÃc !£ü à˜M„[V05ö§”*RFžçBˆ€3G)åÍHyxxª¥Ìßl)€~FPJ/Uªö‡y·6™Ró qL1ðæL }°Uê³€@0úЇ‡§Z!­l†9úGJiq•&¾RJ÷ü§sN$h•'´µŠÄÁSw¨tÏöî™RZ`=¯Ðxxxþ!ä]ó|L)]Ÿf)ÖÕ`¸ð“ zKG_çù/UHž9x…ÆÃÃS!ÄÀNºPJ靖(¥Çk8, ÞòIà‰· „0•³¿BĵqÐç!-$<¯^ý<<^l‘—r™-̾SŒ'_©}A¹I)ÝK`ÌñBkó9xê)ÉgfüyQuåÎÞÝ´õ1_}P˜ÍEŸÿ»‘_·×³lœýêäŸòЯƒ:x‰ ~§ .ÆãáyTÊ,ľ0À”Zì¼jŒ}ã¶êöCfñˆ]ß´yZ"ûà{BÈnœ­á¡BD<9Jéîú’,úì*ëË»>ß&“Áa.ºMü}‚O‡ OÔ<3þ¼(dù¨e“Ìž^^öÏg®‹z/à ²¢Ï®òvòì8{ðG/=hœš›rí ²" ø«;Ï£R–¿l€ A”Ò܇táá©O\4ƒ9åPk˜3Q×$Œ˜@`½Þ¡ùuŸ^ä×}úPØ<ÛëCPÊNø.ñÇ«ÿ~ÙH™—$>½nj#UQ†í ÷…ÿk‚¿2/Ùͯûô+¾]_+€”›¤Ia{œöM”é1'}zLþëŠÂ¡©0ïš.nû°N]dã00¼ÝÐyÙç6Îðtðh[pc§¯K@zçqK²b\K;·ÀìvCçe@jäQIüÕ­®6|‹’Âö´‘Ù5N3è5í/ÚVbÕ¨HS’£0ê5þS–æ+#')´"={af4waëûí:ŒXpÃѳƒÎmœáÙÈ»k^µm>Rk×Âî/¯H,ooЫÉÑßGt²s ä#}ð48„)~ð5¥tYCËÃót¢M5 2Wkš™46ýNö˜Ã ð?Jé]Bˆ7ÌA±?{X'Ji!€ bwéŸñZUA†&I¬>òû0CnÊõ9¡4åÒŽOÞ¸yl鎱ó"¶E]Õ<ãÎÉe +Še¢” Ú,3çF‰µ³qï÷]÷ ¥6'êã®lôl7tުİݟÆ_ÝÚ˜JÃs’BýÃv_œðmÂOIa{d§×¿¾ˆc2îœr>·*aÒ¢»_F]åyt%à ã"y¸A¯‘ƒRQaftWuqf’³¬Édt8òÇÈ ÿÛåŠkϢ΋sâ& ÄV×þ:è#{÷V¿ýèÄùİݟÆ_ÛæÈ $±ý…æé1'ÿæÎŸ·O.³½ºoÞ?œPz=÷îu/“Qߤ!^{Bˆ5€åZèM)½ÙÀ"ñ<¥Ü™V2@føZÂ@Èz>Îx”ÒU„6„îvØX›þ fåȰ\úä2ß©Tt#tïç̸ó·òÓ"Þ° (¥²ñó£_ÉìL>uþý̆é<ƒFFSj·èñÖºÖ>»çˆD ¶º0qaÒ"UQ:»užÿ¹’ÜÄ_oü¶'”FLZt÷+XûõÙ¸ÐÍ?šÇ7Úšu¥‡Â¡©!5ò¨äØŠqŸ¾´ ®âiuÇüV?gÜ9½xÍûVb¹Ã†N£¿_åÕnœ²(;vjëþŸ¼4pVΙ Ó½’Ã÷}à<ˆ¤¶g^Z·,ìðBǰË7ø3úüßÁ±ÕÙ‰ “iKó™M³šü'‡O}Céó‡Äa(¥|:"žGÆ~¤0ÔaŒ¨gÞ¿ÚÖÊk†¯wS®L»¼¸ôîÝ[‡Néµ%>CT,+Œöë>mvÇ‘ßý'û-!ä?2‹åöaš’œ z51tþµ{Åž!B® -ÇsHöýJ+6¡,¨°E%{™ñçE¶Îþúòÿ3À|O-–;˜ô Y•}?öèÕqÔ‹b™½ñÌúi=†vî`¾'¿~à›Î {Ïô੪ ÏUn‰]UŽÚ²çû.ý‡~t"„HªýÌ€—woÝÿ“kC,ºxŠøÀÜ!sê3W¥,D›/G)=RŸÒÕ‰ÂñFInâë[æø4Ö©‹ÚúJ„ü9&0+áâd¡Äæ¶NSÔB Vœ/¯Ó©‹zmšÕDhЩü…RÛ}6Î~†Vý?9q~ÓÛolœÙø+£^Û„Ê.ùuŸ^t7òhãÊãÚ8ûXV´ñs÷b…Ó5(ÍO/”X_0õ¶:uÑ@Ï ‘SÀÊÑkeÔ™¿%\Ýv c2¤&-ºŸÌÍ:¿ròúÁ¯ošÕD`Ы½AžÙŒ¶ ënÜòÖqC ò¼Pk0†è—HªZG ó}YEPa ‹w_®íŸï~äûë"©íšIߧέT*’Úlšô}Ú¬šŽ•Ÿzsvf왉6Îþª¢ìØqNÀ±•ã÷I»Ä Ǽûõ=øsÿ–Ý ” V֢׌™í‡}]ëLÆÅÙq:õ±)´¢¬˜aÙIWî<ŠBÛþUÀd¡Ä:cÄçžÙ|s”Òc„L˜ýÏÎPJ/Ö°«€«ÅîКÚN©‰€gÛÑ;YNT9~ôìkûNü=éNQv¬wЀÏ×'†ínÍ:MŠˆdJ³õˆÍ…£¦iÛ±ù¶¼·K]’åîÚ¬çšÞÓ6E—·±soµ˜šŒ¬ÂÁkGðkëî€O‡ %>& 9ðs¿.ÖNÍÓ_˜ø{rÙø‰,+¸'ÓÄïïN8³~š/(Eïi›¢ÿ5!º03ÆO!³½ÚyÜOßÙ»·ÖÀ¨/®îÏI =z~Ë»Á„0Æ=g\€ÆviÞ³âŸÁ¹Y÷iЪßÇy>' ùslo[×€-F½FÐ8ppzÝ¿Ò À‰x-[ÌQ?ù»Ò×7$±æB™ë4M$ÍÙbë.‚zóýË\¯i"oÃåË9‹=°$ÌTJ q¯tÙëÏúN)½l)yjaØ4½®´C^j¸ÀÞ½µ>öò†±¬@|+‹ª(=µnj»V}?ºéÞ¢Å_In"wzýë ¬øÿwjÚQãâÛë7Øû}×¾å¬ù^Š­ÔáG;”ß¹Ç^ڠȈ=ãØcòª˜²4(lšå17öÒ†‰í‡}½´|Ì#¿kÓ¸åàÄ=gV–ëäêɾ%ùÉ.­ú~ê4²Ô¥Y%"™)3þ¼(êÌÊ& Ï¢¬¸sÞ}ߨ~©|ççæ×çï&C+Þ1ÖX%^ßé3ðý;‘?Ç¿{ýÀ7í¼Ú»Ý¢çŒÂÔÈ£mi~;ƒ®4ãð²¡ù~/L‹ñ YzâïI~ÅÙqM­ýâË?ïžF!®zT*JЄ"­‰_dYœÑƒSh•Mè;ùá?G½_ß üºO¿ ^íÆ)½Ú«x³vÿKJùÏ÷ócÖ0äãSgª«+¿g+Ç3hd©gÐÈèÊeœ@BËdô™¶9 @Tuã9zvМyéžn¯WׯVþ}л+þ9¥Ö®ÆŸ_©n¬g “Ž ÔI”‰š õã 1yhjâP½ P_ íæÈ¢R_6;{«¦¥ÃQ”ë’„ú˜çaBZÃTø:ª*üAL"‰Íñ3ë§õõEè2w¨ÔªÑ½¦¤ùcdPfìéob«óÇW½4Onç±fÌܰ§×MõI¼±ûw¡Dq.ìÈâw)5:@ZÔqiêíÃèQZ˜Ú™R“õVU IDAT¬03º«@$ϼ{ûpp럽 W÷Í›Á°‚B++KÃ0‚bƒAã'×Li~÷æ¯9‘<<+ñ²Ï­ã¿\|q~ôßa‡:†ýqˉX85tïWÏ ‘›R£BÖªŠÒ;Þ¹°Ö-)l÷–&²BiÔæ9ÞsýºNÞyÜ’Ô”›~ÉìÞqôì²ù‹¦Ÿtªf¬P¿î#û/‚|þVëŸå¦F…¬ÏŒ;Ê D)WvÏšŸ¾w–»¿x£QçN©QZ˜]š“|5ýܦ·ç‘<.=æDg_ZôOW·0ÄZ -€\5vô¦b9:z´[íÒ¼grCËñ¼Bi`‰!XìŽ {»Æ_Ñ–+HY¬i® ×»ÕrÖDÕr»uˆ&É(¹ó^I0Õ3S‰UGAÕƒÄÌ(îf( 2F ÿZëSwÞ/élÝInÝMsç’>­öÛì'œùþ–êA”z«{Ö*$¦{va&@—m²Üc}¸äšÞ:é[Uç†Ph„÷`Î"ý¥tƒ¥ç·¼-áÚ¶o/šÁ Ä1 +,-¯ËM¾:Öº‘ï¯#g^:riûÇî1Ö¬°3ýΩ¡2[·uã¾¼µ)üÈb‡kû¿þÿS“Ö#6Ä]ÞØá¥qË z5ùçS—woÿÅλý¸"miþÈ#¿RÞvÃ'–›L{j2Ùøtœ82îœoãâ¿jø§gO¨ŠÒÙm_ì7èÕ«ï\\7L$µ=QÙº*Ôdtî5m]°GàÕÖ¹ÍßLŽøwpçqK*”gµírº¨G¹ëö¯[¾saíÖ>[NM;.ðö¿7v}Û.¢ ýöàÁïþê։߮ %V‰eö¸}ò÷¶-½[ù„ÊÒäl×:foÐŒ7–ROj‚üöð¢w É÷ßjU«´d”ÒTk !+Œ-·¾%„l¯Í8 !¤;!DV›NO*ß=p­ª?e(»«IÐCèÂd[rnC•Pˆ¡Ä$y°AGmöR=åJoé+Õ~vý„±­Ûìc%æ8vëÔž¬‚èšýª8-tfK27¨=½ÉCÓVª;G½V<¤ÉLé…reºl“èîÏê¶•¿ÒÿTT–¡äºÞ†³"*P´iSŒ–5dGÙàeŸe/Lü=™R“4;ñòû¶®-·U®Ók•Ýüû†æS“Éà’sR¬×”´³ui­|–KöÇ÷œ@BÅrÇm‘§~1äϱ½Y¡äZå°sC–ع¶ü ¢’¼DGЩ‹{fF¿¶þc§Õ;æ­b.7üÈŽeþ VN>W4à bËïÉäöM"tê•ëoøµ£ÉdpZÿ±Óêõ;­Vg÷1uÖåõ½^]2·£^[­Ïª“g‡¹w#~½öÛ£;¾œð yêVF’D.Ìš:ê €ù„^„PvjWS8|džG†âào˜ïj>й¡ä‘·æ²@`Ï(U±F…:ÞhoÛ[˜ BW¶”× Îê£Câ—ÊÀˆ9gE b&Wkt±~A˜_Ûye\±¡„J@g” œ˜Â‡õ©cz¸…: *lIvMþ)ÉOž<àí}—ö,ìäQ^ΉdWÓ£O´Äd^Ùó… aØ,Wß`@$/ÌŠiàväéå6Ôd|¨e­÷é[oún«VUêФÝï•ëzNY îß%Ás²..0P Vœ—Y»^9ëò¡Êmã®l¼X’“ÐÀ}•šÉhðN9)võ Ö(óï$Ö7*×ûv›zõâ¶K^Y’=µºþ¬ð¿†% êL&CElܲk—ñ!Kì¯ïŸ¿/òôòCUïùêÇq¢Çq¢ºŒ2³ æû³^®¢†Çe›²Ö¥ôB ÃóA™s6c1ÌGÑN¡ZUl‚…‰é«Õ¬¹®¼¡oj×O˜à²WîYÔy€K³›ïÞ:´pÓ¬&mX8G§. šüCæÛÞ^ÚwûÄomüÜÝÉR8$Ìܰ•Ç! “lå‹+"ù-­º°w³N/¿Y¹Þ·ëkÅ×þýêäúV‹evç zu#‘ÔöΘ¹a;î'¿u£æ³.-ØüEÓF^í_ÜsaÍ7b©Ý“Q/' ›kieVPJ)!ä"€»0gÙ¶GÍb9ûLÝ¡ñXBˆÌ~M0§>ÌwfŸŒ ª}µYê«\¢>ßÈH›±Ù[¨U1z‘,€Í`DTkÌåé³ÂäE¥íÇŠ.±VPq6P9¿" M˜]Ò™°Ääòš(\¡·k2Kr‘cÚê–%×u2VF*ü XyÕlU×èó“ìPÚrMkis6Óa„0ÅR¯Iÿÿ¾“OžA# r“Cÿ“Ä»ý‹'•ùw¯ÀÀwö_ÏK vnÓÿz´8ë/¿îÓ‹³YzÌÉWvÍ öî8acaF”“gШ¡ÄŠº4ëùxwx)SU”9»òج@”.’ÙÞcEÙÈ»ëØÊ¿û÷xó]uq–´ç+ÇôêÑG– ë¬SÚ7m;f?´öuVûa_;øË€NÚÒ(kzU8BÈ(¥{zR*•Y1P>†¨!„¼àwýʈfã̉øxxˆFSTvûoÝð<±†[„~ÕTSJ#k:à&Ìf× Ê…íï6±skU˜¾§™ÂÁ+§ë¸ß’ îÊEVâ%;±ÜA“~çDÀ°Ïž€•#ƒœ}zÜ ìýQ[5¦Uëþ3£›tÐå§… ®øª…_×i± 7v¸õœ¼¦"¥KÈÊQ­ƒ_ÛqaëÛޮ̓³î\^ßÒÙ§{|ÛAó²À W“Óë_m¡*JsöáÍ+Uw^W÷ÏuΈ9ÑÒ#pXxëþ3s*×Å_ݬH ßãÑçõ­·ëûõ²„_ÛL¢”FTª*°ŠRjÑ Äà ’…bë«7OüvøÛ5œP–¾ùíS¿]i~ââüôˆî!+GMœømêÌ#ˇ~Åp¢l±Â)*9|÷º´öú¸ù÷WŸX3Á?3îÌN –|óßÉ7÷ 8¡,"ïîõ¶ W7ï;7jõ±•£;dÜÁ $iw~8ãæ‰¥›Fͼ¾Ë W“-s=ÿ`J¬nDŸ_ÔºÿÌË忼ë÷;—ÖüîàÑî¾Y«Ÿ&Ê>ˆøœRZ5Cn€…–—Šç)¤ÑÐæ¢Wš90Oex®g,%nŠÐlF5ÍŸ ²®¦¼¦WZ1OÔ™6'’]›ðMÊW½šlœår>'9t Pj’½¼({ ìü®Õ¡ÄæÔø¯ãÒªò™-ó¼.ä§…/ýEÄ[æ6Y¿é ·%&£ÎeôásER;“Pb}ðÒîOFŒñØ’n’ÌÖ½"­†XæpxܼèUÉ{d§7¼zÀêoºàJè¾/\²âÏEdF½`×ñ¿Æ¶#„&-Ì|£ªÜé·Zß<4Å#`ðG½¦üóÔ=–E®Þ` ¥t}5MŽSJMÕ”óðü9Cæö–5´Ï+Ë/©íZ†ðX;´2KëÈ'J¡‰e€9wË ãoú& ì÷Š`¢eng+¯} ’Ú™XVwuÿ¼€þoî ³s ü3;éò6׿ÁÃDRsÊóƃÿI¸¾mYFì©=:MIŸ^S6,(KaïMZ,ˆþú¡ùNÅ9q¶woü†åDI,'Ê1´- 03º»Pj[m„î’¼¤™r»ÆKžeÆØ ŒRº º6¼2ãáá©K(¥w|õ¸ãE©ˆ½&–Ù…ªŠ3[æû.£QïݺßgQÉ{d¹w¯Ï—Ù6ž—•pa~~Z¸º½´< „)9µ~ÊçB±â˜K³^>SÊüäH‹:*¥¢¶ƒæegÜ99ÙÊÁ{ÝÄoÓ>³qnqe¯‘•£ÏEª°Mur;zvüŸª(㎋;©®þ)ãw˜×<£¡áááy²1™ØìMšFTO« ‰Wk!~„u„(BH!dymú3„W!¶u!Ìã¢×–tÙ2·Éœf:­H¬B*+Ÿr¼ÛM8ªUåÜ2×sö–9D냼ºiÏm™ñÔÊy㸹Q %6Ç,6§¼•ƒ×miÞ.̓ÿ©<–º$gè–yM?;±vâ:±¢Ñ? ’9„çÄ¿¾í+Ÿ÷r’CßFYÔÞS7_¡&ƒÍÆY.Ëv,hñ궯›W¤½(œ º¾¸lRq^Âk»µ]o/P=C™ €ùPV<<<âÖ¢#ú]NûY½=ì…“7ͪÅö€OеŒàÁ8 <!‡­ùÿ̰ÔÚegï×6G€w‡‰áÙ +Ò« œÝ²ÏGƒ,ÒÍÑ£ýÚŽ#§å§… ìÝZoøöáË0òóÐ_N¬žÐQ«ÊgDR;“ÔÚ%½8'þr¯WÖßcãìÓýkuI¶“ƒGÛ­åV•£gÝØqbÍ„Û%¹ MƒÎ^›xcGsÀ|¼ùò÷9“N¯ŸÒÎSÏÁÍLƒbäÆÂÉÝ=…·í¥Lé⳪Z9sÜ­ÙûÐnû{þÔ£¯Úüãaê`î1åÐ A¼ ³*‡Ìì);új[q’Åñ”aTQ&áCåFBb|×)þ}Ìáø(¥”²Àë5íüÄ(4ËR–?è €ß)¥[ZžgE¦Òd{"^'ìí-Ì­ïÉ~½¨jÝ«©ðæß£­Î–U\˜(°þ†Æóò]½ë›%·‚\¸âí75î¥:*ýúDi{ £^2H~æË.µuåŠ~<§ò[s]Ý~T QêOçU-ؼ=QÚf‹*.Š9—žWp 1½ßUe+aôJe. ôuäòÇëšNi#¾ìe^÷•T½Í¦pMóŒ“U;WAÚg=¤Oý‰ÕSr{DÑ“.ÍVȧÖÁÅdÔe.D‚Útæ!oØA)Í«I½¦X~ëäRG–åøm¸…`ãÃ[ÕBˆæ$zç(¥|âÏà”!ka~èms a ³ó½ô~Ý`¶:{@"CðŸpqõÉø@qêø@qªRGÙÞ¼´âŠº™›£4™À×UJrÜW©,(?ÔÅC/šE Œ)S`-&ˆÉ5Ú9+˜Š€«‚)ˆÊ6ÚõðDŽT@Ô. F ÍØ¢5×L¶°m‚õÖΪÚ\W8© —°ñEëõõXª§ÖDDâJ#¯–—q r³°ø±Æ5ûÀ^ªe·"»Ÿø;4FLL²æ¢í N—zc.êE¡_W[ß™™ÕÃqüεAÉCÛõ|ÜËO‹C™ `ÌyÍ,òÄÌóôC)5Â|’³ƒÒÀgFãÿwf•QÈ0€RGieIY¯¥é­[9 Š,¨\HŒ,£\Hôc[ŠÓ¾:^Šù}d×dŒÔzjŽ$"ªìR“¨òÍ^ÊèÊ•YuŒk)Šûß’!ÎM”„gšÎî% €R•Õ9õo&Ì>£óìà.H0˜@ü9庱V§M§½~Ì}G­§§$òÔ>T¶:f3³¡e(§L æ=ñ ÍP`â²v5sªÈ¼>4y0gŨõ…F‰ÛÛçñÖ©©«ò½rö—4ceŒÎd0‡©Ê;ªtÊØTègÒSÖ¾Ÿ<Ñ¡¿"#òíô^­77IX˜ÓRäÊ•6~Ó.¾|mš^¬Ë3 +Ï+vhlEÈ­Ü#J7§áŠhwìc‹Ã4Н«­­ÚJžš€«„¾ЃRšó°ö<<÷!À-˜ ݪÔ)aŽ˜>¥¡˜6„i|Ä·m$gòK´TêjÅäMï ‰gð¿Î’“Ã6ŽqD¯ÒSqáíýäaÃýDá3ö– ‘ ‰öô4Û5™§ScAA3—ÜiyþË& Ò£©0ª…§L+6‰­Å¤øËãÊÞsŽsDûçÅáÔb£xàšÂÉ®VL®Ö®¯0ìiVfO*!D @ó¤?Qe E& hRôöN5ÝB”Üžžì<Þ:5s{q@û£žÿ*#µò[SR‡@Êïymü–ºœe¤Œñöëi}Ü^µMr®ˆ ›2€ˆÉçk#•çÈ9¬t)º¢r©\æ8D‘è4Ü*£ü÷Ò(­£ë+6‘ i"(*¼ rzZ!$Àz#)¥±kÏÃSBÐÀ›zØà ˜/ìåeÍJÌ¢”.k!ËøyˆâÊÂþôê<£¼…#WRÙ‡ì½.ÒØ÷ºHc£r r7+Vc%2Î –Ýš,«8ÙIøÄáªã6µeÕ‘ØÿU¹ì¯ÑVg‹µô"Ç€Vöc²Dñ-»-I…F‰g¥]ßÍ÷ìWEæÍíY%¯ÌêÀd˜jw—ÖØb«£Ò$6–š*â|Éš KIÙæ®Þ!iin H¼y&eìûÉ3ç7~Ëîü£Ì-i"(T'ëår´¹]°ü©pÊ&„xøÀ[”ÒçÞ÷ާæBœ`Ž­7æ;Š?¼F)UBvÀ|‡¦ƒÙÔz(¥ô‰ˆ’#Skgî¾y´ü¹: íV®«£²2 ú ¹xB@ÌXÔ•ÉeaeŒ‘cþ ¥cÑ55˜ÏÄå-Å©Vm%YN#­ÒНªmŽ˜"ßJn±Üõß„Ù]íûÉÓå-DojÇò ë’{ºØUp ªmYzò¯yíe¾¢¢Òm#ÛÒ –Yå£S–Öü€Å”ÒÝ -Ï“OÙn,æÝX?˜Ý;^¢”^­Ô¦€0'U 0œRZï>fO. FsøU› oÉSÇØË•… ©†Êjs ¹3(µé.MÔæ8Û`Ylù¼å?û|ßèôÝßó%‚"ÇኛÚ\ç½ÀéRÖÖ"ÏÈÿ¥¿ g‚…Éa˜"ZÖRTèõ¥ÓÙ¼“ÊF§J‘DÄ t½× ÁŠÊk”·¸½a{=cSa3ß_]BtÆZE~T Åô‘Rü”ù íp˜Rú[ÝJÅó¬Aqð*̪U0'N£”–TÓüm˜Ow~†9£9|VCÌÇ“ -ÇsH€ µVJT MîSvEEñÔ$7âg”¿W*~.%PœÖ”=þ½8Bq„öuƒ¤+™ÛÂÌøSòž#¥€"%í[˹á™òdµñ—/{Ê^ æT <<ÕBéónl€=&?èè°Ì)Ì»²§ÎÒ—çÙ¤ì¡JUk…&·nÚ¼ÉÔS„y¢rƒ>Û4’ÂvU5~ 4ЗRÚ ]!‰7C`[a4ÀSÏP= %†”Òúl–9¡Ny7¦‡y7ö¥´&FN~0+3Þ¸ˆç‰ƒ+;Ï«MBÇœk+Æ:Ë´.oÉSd«¸#v£,Ùèƒ „Ì€ù~£¥T[ïÂ=@acÆÙw…åôYÑy½ƒ´9[,pdxŒ®Š2*@©[ÝqÚccRS¶4Êh%oÍ FjÏX¥––Dî{Néónl0€}¦RJkuL)½ùxRòðÔ€a0ßµÔØÊQ!0I¦· ½ì… ùù\­4ÑÊ‹jpÓI`ÌÊ,¿¾e« "'Öbg³Úd­•¬Wú°93Vh܉FÛ‚úãZ·‚1R6+ù«R—¦_ÉÛ f×ÇÖû !/À¬Ä†ÁœUáMJéÙ÷ªJõT°ö†Æ¡!ææRKLµ¹®xZ±0ö‰Âóp!^0_èO¥”^khyʰøÝ™2Üà,oÍå©îl OéšîµÙ9¹¨ñ½:Á(WE[üc}4bháHY 2K# ò¬šV-wZJ˜]Ú6c­ºi£‰âÄ[c GfïàR…ÎŒ²²23i)1´pxå9 KŒ­ÛTk‘½CÛÂa¸0º¾×]…æ„m0§ÝX àÃZÇk­[ ÷Eiví»SØy óEEVKQ¯”½ÇWð í)§ì‚ÿ€¯)¥u‘ÿ‘!„¼ h¸L¿6½„±œ51Èü¹ÌâPƒcé-ƒ£ÝQgE VI½Uëm(¢Ò¨WŠ{›´à“ÈI° ÆdïÔvècOúwÂê4NqOWýcf”t•4eó\^“$Õ×ïC:€w)¥'-<ïý¸«5 Õ‚FÁ<Õó\¤ûâÚS !D óåþJéʇµ·€<.öè 3€1 & ‡{Žj­:pÅ¡zçWÄÉ¥‘›ž‚xûÁ”ÒÛ†F[­ÍéA””UÝ1Ê Oë›ÙöÜN˜£ òZ ¿'“º6ÃtÏΓ°øÏ‘pìû%@@}~’‡ÖÇÚ‚’Rz¥æ½örÛÆÎ”4´ Ï3¥©Y,r—Ûp„Oéâ`ÍÓp”…zù@¥tvËB`¾¯ù æpH¡n MìÁr6D'taK©Áü*rcJ„NDí0T”^t¡Ä=¬OÁ(¡3S$tfUVò6\zÄÐÂ!  &‹Ã Oé=¼³î,È¿=¡¨¯6Õ(¹›ð ÚôKYăd0©)StQïÍYUX¿‚‘òV‚TŸ%ò«êó¬cãÀ´ ~“ùÔ@Ü:¿VQZÚÐbX@W˜¬žH…Vª3±Gb”n…jƒØÏIœßÕSúÀ;ZeDÜÿþ<Uâª1PÎVÌj{øÈ²Øgç9q Ìá^&6¤„›aαVÛo Lª˜ÿ)eçVÆZ-`”‹˜ÿ)ø?öî;>Š¢ÿøgv÷zÏ¥ÒHPEQAAl(*öîóØËcï"Š€ *ˆté5 é=—ëmïvç÷GH~‚ˆ’B˜÷ëåË8·»óK¼¹™ýPäÍ“a_扒ûC“Ùðü¤kK®-€|U¢Žua€#ÕU󂨚TVþ·¢™~à·7 P.lüYò7ÅÑêBuRÇœ¨Rr4¾çèùùr:8°qn§n<üÀ¬@)]ÐÞÁKnuÀxï¢ÊË%jóL>ðáÆúA½bUËŒêc/Ëÿiñ5__×õ+“¦!‰ñ«kk/ì¯)Ë”emí÷ ³®¹¨»¡¢íZqòBîp€sÚëÎúð2Ù‡Ñu]† `;¥t;!„óì ¿ïÙÃ&OÚ»bNGz#;ôÚüάa©ºì'GE7Ùìn|RàÇ}®®ÙÕÁè)ýLyÝ"•ÞeùîxHV½±®®ŸQÍî¹înÝ–lQú>Ù\ŸùíngŸ³“´µ_ír¦%G(œkxS>/j |±Ý‘¡ˆtÍ™æ:%'¹ƒ’0o»3#Á¤pm)ñu™ÔÇ´¿_µöVL¿äºSk=a}ßxMÅuÌG5 u\ à4/™B)àôËŠùÛÖïw§÷í¢®š±¬zÔÏÙîxúךQÝ"•õã{ó„´†€ß~€™hت£´-êlŽ¢!„¼`€4G'w Õu ô"ÞDœÆ³„·ãnÑLÕöà¿ I7Ü罨=cêÐwhWõ7²hùÀ{]=¿Úé8;#JUúÎÄø•宯´ƒµÐ/^U¼(Û•ùü˜˜?'“¢­ir€U¥”r <82j=P òÒűëU‘¿ÙåLɈV•Þ6$"vVø×ôƤG)]aYæ_³Þ¨æÃÁVôt—e(ó‡e•Ý'i†§êª†¥êZ}h½¤KXô½††%Ù¹0¡5BF˜À @ÓÂ!4 ?2 sH}ùÿ;ÅÞ¤.ß7Ö9 X, Ý!YhX)×!'”/ên¨¸¨»¡Â+Êüõ Ê&ü°×•¬Up¢LÁm*öuŽãhw«â˜ÊS££WeF«œ»Ä²‰:«–³7.)¬Í1z¡)¯_Œ^pÔÍéQJ—VÉùçì’#®%9.!À[—ÅÿøÙf{ï¿*;£_¼¦èù±1­ºy¦FUë­/~$ò¯kÍzŽtxOµ7Ñ>)Œ†Ž+@@  q™ 0 sšðf‡Õöebï>)3T/Ÿ¯?Cx©=ãd(Ðá:´Üê€1#Zíâ  SrÏAÖ(¸Ð…Ýõïn´q÷ ·îÒ)Ækƒ‡—ië”œÏæ“”ÍïÐÌZ.xä–çÍ;^¡/zeuí‰b{X¢$¯&˜pÿˆÈm”ž ¬ÛY°œÑEm_È×µ_‚¦$,©V¥ç…‹c6…elºðÃC7H›Zs%¯Ðˆjmijí6Ê>üœÛÕhØÄq ö²£aEãKhXÑhàðd{eög:—pÈOêJv(,çy%Jxʬ–,ËY®©Ø¿ÖÜwÔªUºˆ“2-ñÓ+ÃÎzÕ;ë­ };Ħ̵ ‚™Ž5¡çd‘¦ f²$nº¦]v-'„¨$ y'ãö¹ÓÖTõŒÔñOPÖ$˜u—ô4”À5ýÍÜüuÙ8µÀ…¼¢¬:?CŸwëÙ¹£2ô9,®mPqþÙS~ý;õœ™ ±§Eªª&^2I¦ ç¤èò»˜þ2GHcÖ®Y«jFÈD«ä‚Ï^³¦ÂÒÜömùÄXƒP/†©bdš~_'z Éá»ö÷š—BÎð,€{¼s¸8€†¥û ó¯­ýì†å9+^Y %Â9 ÇÛ Ç9¦¾Vwm{Çw¤u_LO-Íþuê5/•>Žª<á§W†Í¦TÖs_Ÿ³öÝÌÃo›2h⬽ºº¾|ïUÖO²&ôíÉ¥“_Ðíp©ë¾ðïˇò<Õg¥ù‘vE w‡žC{ìü¨ŽˆÜYâéR­JOóNãÚ3Íמi.(²‹Ú½"ÐxvÛˆÜÆ¹0X}{êœ#¯›jUzÝ”üMó²çÇÆüáe^àˆ¬þ?k¹Š‡øÕÔÄEÕî°:Æ 4ÝÅþxcÒ‚Âú.É¢ð6?¾3#„$¢aXñV;ðh‚|öD¶b˜¿rÁô¯sŒ€/þû¶Ö·fÒ;¿ß°àΤ|a(ÜõC Ç+ÂC®|=ý¼[û}ó€KŸÝŸ92{W½áu”i¤P@pÕD¹û—¦¹ž²œåšK_@å°"cðÔí݇Mw®ž}M÷Ä>ãÊóÖÜ'匉9=GÞÕÔY„C~²òƒËûw8eúàëܽæ‹»®Pµ%;RBA·9ôöÿõqýÍ1™5åy«qœ`¿ö•ÊëÀç¬à¥P°éÓ«dïí¾5o÷:ÿ¦ÛïÜVϾ¦{ÚYW—ì]õFßøŒgŒ}¢)«‡£*OX?ÿö³“úŒËiÕ7þ_0Vx4iü"ïÞð£íQ?¥ÔàÛÝ¡€J 4=Ré9ÖëÉ¥ïdÕÕ8|Ù’æ(xB3¢ŽWgsx.m)€—)¥‹!4|+r˜Ý®Á1§…Âß?P°í«.¼B}Б´jÙ»ãSüîêþ¯t®ø`Ò‘‰ýg^|ÿÊMû7Îé¶ß Ê"ÂñιDþgêÿê¦Ú¾P¿î‹é?©õ‘‹@)Éþí=s÷aÓ¿/Ù÷Ë¥ÙËœ •vï¶Ÿžz,wÃÇŸ]þäî…æßž\°íëw*ýæêÂ?ßñËóK'?›ÿqþÆ9Ã]µ‡îâE‰J±I–D¥’ÅQ•7$,úvr‚Ò/…ƒ©¿Í½©Ûˆ©³ ´¦ø¦Ï•ožê~SÀk¦P鳿z2ý¡”3&>4üº•ìû岜åÕ‚BSP[¼í©âÝ?¿5áÑÍK×|z]fñžÅo)5†õ»–¾x'•¥ˆöü4Wü¬7+á?Ú<^Kdû2Ñì? ]ÁiH['ãþ“ß¡µ§³ÂÿóÍÉ_µwííðøô"¿PJßJ©›B¼J)õ·k€ÌiC¡6l½zfѬfEK~ÿêî¤Êý¿UÛ+s.° Çy®{µúVøì~ËÒm??c+ÙÏñBÅ€ñÏÍIxÕŸ6wÕYº|{ù“»nûùé˜}«ßš`aYÎòKµ¦¸/¯x&{^Ñ®Eºµs®_àãçЩ¯ÖÜ+>¼¢Wåþµý¦<ð áŽjÙ»—&nÿö‹ÂßJZSÜœq¬þœÔÔ箾bÒã;Æ"SÂ?Î2ªBÂá¿wãk ¥®) Ï+Jk ·$ŽºýûmßÎè½yÃüÛoüúÞƒ =F½rÞMóóÀÚ¥ÏpÉŒê½+_©È_£ÎA± }^€ä~¼ œç…&€B¥;f~Nsl÷ðäçöàƒÕŸ\ݽdßÒ·W|py‰Î’PI¥pì/jL$Nx…º¨ñ¼.Y£v€µk¿ÒÚ¢-] pŸÓmÈb8sÜS5{V¼Úa’ô]k¾ËõGHïݶèû õ† o{Çİ¢a.„aZ2 A®oaãóí•­„9=q¼¢iuŸ½bßô¸Œ/\3«ì1µ>êÏw.äèíR…†NyþàÛ7¼á¡·tý±{¬q5ãäçöxhûÂù»–Í©PéóNxa3ÄgŽ|(匉õ ±\^çª9øœó—¹ùkÆoþþáóÒκz~}ù¾ØÄÞÿiþi˜Ó°ŒüÝga !f…Ê‘ÐK›¨ N|l˜•­ìpcw6•®°â©Uþ`‰ý…³2;èq–Û(¥­º[!d06êC)ÝÑšu1!$2¡÷ظѷ,´µw,ÇòÙý–_{wÏõ.™Ñaæ§N¦ß>¾6¢`Ï5”Ò´Á'!D{2¹ÛûÆ•tX*¦\öµɵ+°ÿß\ç¯üã;´:Ÿ$(íâQOó3'W½_´4Ü×*ïoö=æÌXgÆtzÖ.}^ŒÏ8—Íw!d€”Ò¿=©Wâ¼³w† ©ý˜Öfðn´Á¾„(4«u´þ¸+tjvÇF]b¨j­X¼ûƒ:^ËIêE›­îôˆªÂ‡%5\­s}BÈœ`¥´ClIÁt2¢LªŠþP´w§« •;á^ -ëðÏ¡ÉʹvúÿV‡VüfÝ ¨K ?¶F3jzûŠV*Q©H¸×œ„õÇ?«c#„Lp'€!‡Ÿã`˜“Î^³þöéͦöŽãô:mFÓBÈX(¥­tð/Q€†(û©êV† I÷[wûkœ®í~SÉÛ¶¾ª8EÓr ,¤.yÇ–vHê„["²U±Š@ñ›u=3fÅî¨þÎÕEòÊBüTsñ±+=Z·§£÷6þ¼yè¡Ë%¯Ìóºcgçïè!#¼àüÖ~®9­Õ{íeŽö‚Ái‘AP Ã5IYpíÄØWû“»Owãs"½Z׿ς®k<^=,ë½øÕŽ-~«m¥'òÿ[5$å¿‘ÛUñŠ@ÎíçžñCâ2¢ÜG«Ïplñ%öÿ1iqó: _©ëáØàMj^3É”ÛR§gßà‹Œœÿï̲| ` ¥4»½ãa:¯ÃÙdN‹S¦ýÞÎjˆ@)ÝuÜ£;e¬àˆ©«€ƒOT$¯ÌSD“ªôi’•¾’·mxó‚q%oÙú€”Y¤\úÌØ¿÷>pcÊÃQ«xýŸ;#Ë0m•*FøÓnÆ3ÔõGÖïÞ0<[3´÷œ.+Z¯•­‹` €(¥kÛ9†a˜“A`ëðshÍîO´ ¯ã$BÉ+ó®~3†&µ)ÊÚ´gc¶ª~É+óœ’È9·•érƒeSåG߸)¦’æZØ.)ƒU!móºÂnåŸæ”<ÙCþƒ•#{~Ôe…ªKÛ- 9™‹YàJé‚öއaæd8¼s[‡ïÐ8‘4ÉŠzФ(ëËîzgĶ=×”^ 0ó~}u¤>µùàŒš3Ã.I­´ Þ.7Yr9-J}<*[›¦t–¼gËHy(*·ñZ‘c Õ‘c ™Ç­êW ˆ”wåpèñnüÚ¶\íøoB üA)u¼ã†aN5'œœXaT_ ëIº·r\L3r®XÇõúµ¾t»üO“B> à2Jé);ÿÇ0 s,!är+)¥k%’N—¼y@ï—~R(U§ÍRÐöÆ *ºcɳ–z>!äi=ŒdÃ0•`/ÿß=!,zME+©Uö dñ…!üØ  ö¸2 ÀuÎ><ÎÌ0 Ó©BLÎ(¥ù'r"¥2Ÿ¬÷¥_ÕOÝJ¡1Gš¿+Hë|êÞÊ…r!€™†SJO¸3d†9Eäÿ£E!„íßEý·ïê˜gþ® æDÏ!„ô0ÀJé“Ã0LÇ@) Èiƒ]¶˜¶FIDÃV0·QJ7µw< Ã0muh !ÄŒ†M:_¦”þÐÞñ0 ôŽ2•òWÐ1!D `€¥”Ò·Û;†a˜¶$XÀÓÞ0ÿ!„ø@5€ÿ¶s8 Ã0mæðMÙRZÚÞÁ0'ÅKºEÿîÓò Ã0ƒÿdƒÏ¶´©Øg]™ïN©rK¦8£à¼ipľ8ƒpÌtS¿z#3¢Ôî(=€÷7Ög•ÚCf¥€ÐÐ]ÙyéúJ¾nuG¹À%†RJƒíÃ0L[:¼9qi‡]Rî ižZZ=.=Je›6в#R'xë½aÕ_óÉö³öTšæ×ò¤i•D̈RÙ¾ØæèÿØâª¡­yÛ"„Œð(€±”R{{ÇÃ0 Ó^:ìÚ¯yî®ÉÊÊ)g˜ `@¢¦éúÒVÏÝjï±·"ÐõÌ®šÂ›[rÿ(öG;Ę6Ú†ÌÝf¾5!n9ôŠUWOèm,í¯¶Ý³¨â2¿Oÿ¦|ôÙÉš¢eyžž·œmÝdRqÁy;}ÜI36Ë;©©¦S>z@WMéªýžî}âÕ¥w µî‰ÐòâoÞèyÛý~IoRs¾O&'üÚï!d€Œ¡”µG Ã0G¹•bmï@Ž4.ËXRT/ÆÝðeÙØ6Ö÷p¥¦Î÷É¥U#bô‚gö”„Å®€¤þh“=kT†¾2ɬ¬¾mˆuãçW%,1iø¦MK½¢Ì¿×•žbQV@~m0ñP](âÓ) ?“¢­yrYõØ ½Œy\½áó­öÁ;ËîòÔ»ª#>¾²Ëâ`˜ò¯¬©ïÿnr÷9Ö- ¯Oüþáó£7´õ{„4?¸RzÂYD†a: ;w¸-Òc B`ñÍÉsÏK×çï(÷'Œÿ´øºÍÅ>«;( ‡lb|¹+l|umÝÁ0›Š|éǺÎûëG^7¿ì2¿H•÷ˆü£±ü¶!»uJNÚ\ì‹´jy×¹iºêôH¥ghŠnÿÒ;I[Þxܸž†ýǺÆíC"ÖLèmüÓJNž@N0+ü–Áñ„4mÏsÅmJ¼,𜠞P ðê¥që×ôÆ,Íu§Mú¬dðÓ’æk¤­¶™WøÀW”ÒOÚ¨N†a˜ŽÌ à‡»(dÍoÌoÞh‰6Ì™¬ãzÅ©«¬:^L¶(«ÕMÃRµÕÃRµÕ*HgT8òk‚'RÏÈ4]U7lÞTì³–ØCš ‡|™c2 ¯±ÍÞ3¦Ü'›í=ûĪ‹€†Õ—ç¦éªgŽ‹ý]-`…3t¹ÿ…·äSJŸjÃ:†a:,Ji˜Rjë°‹Bfo¶|eM­Ñ â|}â5¥Wõ7ÀS£c~›»ÍÞóª/J':*CŸsf‚Æ>¥¿)gÎ{ßÉsK.ûàò.‹ÍJ[„–?j{²EYÕ¼ž'.ˆZþùV{O@Ö\Þ×´½q h„–÷N™[ryVŒºôÁ‘‘Ûà³-öþ³VÖXt*>0:S¿¯[¤ÒÛVï €Ñ0ÜÈ0 Ã4Cx)¥9dÖ¸cµ.¢KҮ¤—ǘ;}¶ý‘ïºqÍ©Ÿ¶w.qjvÔª¿ö;Ê«þéŽÕ Ã0àj,—c ¬ZÁÙÞ10 Ã0ÂB´€9BÇ;átôí ‰ßµw Ã0ÌqY\.PJÅöŽ„a†aþ;€/:좆a†ù;¯ñuØeû Ã0 s"8BH !„Ý©1 Ã0§4 ÛŽ˜Ú;†a†ù'!!Ä*ü“ôIŽ ç{|™KÛ1Gs‹ÛQœaæØL.?á¡F…Rë, Z, ¶+r⯯½c`†éˆ(¥6žP‡Fe‰Já°ßç®îôYB:"IÙ—†a˜c ”þ½ÏHBˆ@Lë†Ãü .Jie{Á0 ÓÑÉ*ØÖ Ã0Ì©Œ0€®½a†a˜‚¢ „týÛCŽ Ã0 ÓB,.aÃ0 Ó)°ÔW Ã0L§À:4†a¦Sà!Y„u{Â0 Ã0ÿ €ª±€48êÎíðŽ 'ZNZ(çÿ¢ü¨ !| eÇ*'Q~²ÚÄÚÚ9ÛÚR쬭¬­-¶õ/ÚÄÚzì6µZ[ !*BH&G)ýRêlöZ_£Ž¼€¡‡ÿ9Ò(ý[( G å“$´P~3ëAjÜ|øßÍY¤×´Pžq8ž#õÇÉkkF å× uÛ:¹…ò8µÛ:­…k$¡õÛÚ·…ò‰8ymUql Z¿­ƒ[(¿§v[Ïk¡|Z¿­æ#Ê 8ym×Bù@´~[ãšîœNV[¯h¡¼5Û* JéŸþAÃÝš®…r M å:êÊ ”-”-”›ðG”‘Ãåäˆr€¹…kL-”+Z(W·r[M­ÜVc'lkK¿?E´UÅÚzÊØ’˜ï IDAT¶UÛmåŽ(ãNb[õ¡­‡¬¶¶ôûkõ¶²eû Ã0L§ÀV92 Ã0ëІa˜Nuh Ã0L§À:4†a¦S`Ã0 Ó)°a†éX‡Æ0 Ãt ¬Cc†a:Ö¡1 Ã0‚ÐÞ0!D@CJ$¦¢”†Ú;†iÄ:4¦uizÆ+µLBÌt¢gkÀÁöŽãï „hUª³ ”Ù—«N‡£A÷–JJ©[ „hš3ºR^φ;áÀ¶* 8Ú+5Õñº¸ á’äöŠiîÂ1GmÒ…e‚ Ž¾Kjï@˜“+àøJtopøMa<×Å>Á>p:ѵTá,½­½Ã`†i쮌a†éX‡Æ0Ç rTþÚwbåpu›­QÙÃùëÞ‹¡Tdó= À_÷^Œè^¥oëzƒö/#õŸ[dÇpÊ/ ñ×ÍŽâ•ñA¥qŒ«½ca:OùƒAÇ×RÙÛàÝÞÊ',¼ªÛ–Ìí³Ã¾íjgáe¯Y{–ÜÙuÛózß#‰¥×poå2'D®´dîxpz6%pªÏëu¿ªPõ¼Ãœ¾îR^tì2…ð&›©ÛÒ'»^I,TØóÏ\ Pç­øo5¯îó±9må’“]×ÉtÊvhõyn‘ÅÒË(¨Õç5t}ëJµeJ½ýÀ—”³¤¯ZÔuÛrz=DÃuçRLáÕ™³"2ÿø¬5êaÚGÐñí]„ÓZ2þ¸“S$„E×/FÑõk%›‚JŽó[«nNˆ=¨‰þÏEêˆëmþº÷b¼•OÎwMÙhJ]¼ªµêd:&wé­½åPù]ìŒ š¨{*À]|CÂ%õ= ”µFÝœ%i£¾Jóp¥"qŒöo<ìß½JÐô ´F'Ã)Ù¡y+ŸM’‚…·k£ïš¨‹›Qî’Û{óÊÄÐpMmµá^ŸÍiÏ\-ºWþ§µê`Ú¥"¡’k°B7è>N‘¥q¬KiëwÉ´×À¶/z¨,×=¤ïòÚ~gÁ…†ý»¦S*ÆN›«Ž¸ùy]ÜŒ"9T&ØóûË«û|,öÜL©dæ]¿1gnù€åQÛÅ›ÒVüÒø³&òŽjí¿Iœ °í4öm=›mNcg†¤Ïv€³à e©îBH¶m_ôÅ„ø#¢GÞKúÏ­¾ªÉ’ó,äT©_Z2¶|öü3odAÛ»SÙ5ÍAMämOkcŸ,9²nÂéemÌÃe@ˆ’ª#®ûÃS¶Å,ºWFš¾mõœ¨SrMt¯L8Uacg†Ä÷÷*tC|ÎÂ+‡J¡ŠIr¨rbÝÞ¸E¶ìŒç è\l´eg>[»'zu힘åõygÞFeöýï¬Ïí{¯-;cf힨uu{æ{Êÿ›q¬úÍéË—“?ßpÁÖo-Ó–QRNˆ\*ºW½PŸ×ë~wñÔ3›¿®‹›õ0˜ÓÖN6§­¬‹ñ€«èªA!ß–§úÿ3¥,Íñ‘;uï½'‡«yJC„ÊîR ÷ruä÷) £‘B¥W:޼XÂþÝj®?‡S$lk­ö2—ÊtÙ¯Tö ´e'¾ã8xî„ s‘©ñ5còW+9Þº‚W$Îoø[\ù*¥"ñV<üˆÂ­ïòæå*ó•JÁ‚ëœ*{c¤à¡;yUò:C»㠧)õ×¾õ^ãç`KœcGÙóϸÅ[ñÈÛœ2ñ#môƒ¶3NÑM9}%•iuû’>´ï?wR ~nÓ¤¥1éÓMœû#'ÄþdN_5Ùœ¾l¸Kïø +ôqÏ^¥±^§,–_ì8xñ$ ’'RKoá„è½ÆÄ/%¼yßöù‡’X¨h¯62íÇÒ}ç …îìç¨äÌ:úض7úGWÑ”ÁÀ)¢EàÕYA^$DICÞS8>r™ Xòm1+M–PŠóU¿’ÚxMAÛo¾.öébcò—›9!f‰$÷W1P*WáeÏ€S—˜ÒV~ߺ-f:"mì“%ÚØ§FÞpHòï»Í]|Ãoõ¹ORÙÃÞ"Dá$^ä aoùý=¨ÈP™.ûJWª9UŠƒ"×JÁü ¯I8Mž9mí"•åªz]ü ¯Sìæ­|â˜_Þe©.ž†í™”ŠqB‡ÿJ9ª#¦Ú¨:ß_ûöd)7Í]zßÓÞÊç2u[ôœ Î Â…)(ÔYAðU¿Ú…Jž³U—^IeÀ Ñ>N³R‹.°Q”Z27| ¼*íMûþs¯öV·ÿTö$€(Ü4lNY¡±Þüœ.î©â–ê¯Ï뻪ҼL¡ô±)õ»umÑþ¿ëp.Ç2r¶[rbfPŠ.m¶útMN,‰… {^߽Ƥùg)M—tª‡ÿÝ…cpmÈoï8þBˆN;3étNN\ŸÛýQ€#zd¿ÖÞ±œLÇW‚§ä–J©û”¼C3$~°À1ŸãUébD榹æ6–)tgù­=ö¾à¿L¶fe¿àÅãÕÑ}ÇûÞ?Á°†a˜VtJvh sªà]ÂJ㸩‚î,o{ÇœÞÔ×͸N½b–uhÔÖkQÉ¥lï8˜Î‡%5&/`~0íNóøQA:Ö¡ÐF?СŸ~g†aŽï”ÌÂ0 Ã0GbwhL« ¯$W>C%ÛÛ«“EG¸½c8¢˜OPóN›îmÇ´`IÓg  Q™Æ' Ú^ì§“‘Cuœß1¯Œ†<í¶lŸ£áïŒé„(¥§D§F¨Ú;¦Õˆ”ÒÀƒý¢;³¥4ÔÞA0 ô6Bi§^ÅÉ0 Ü&Ø¢†a¦S`Ã0 Ó)°UŽL«âUi ¼"FÓÞq0'_(¸»¶=Bˆl­@gE)¥^!¶3sç%Òvœ(åÑjcòg<Ç™Ž0sÊÝËO郧ÒVuwWNwZ&Éî¼dˆŽïD†;4•Òxa’ :æ.ÜÌ)*äßICž Úyiµpl×åN…œzs ºþP›&œ¶Ùö;%Y$¢sqÓ+M/r*mÃü=®’;Øó_ Ü6N¥!†a†9&Ö¡1 Ã0ëІa˜Nuh Ã0L§À:4†a¦S`Ã0Ì y·t¸daÿ5¥b«¬l¦²‡ r:üƒé¬Cc†ùêóMküÙYxÅë²dïPã9]þTÀöEäɺž»ôŽ^®¢©À[5+ÙU4íê“uíÖÂR_1 ǯúåY,žhß?Ò¡4ŽÚ¾ªSCÞ­½µ1®T™Æ¹ÀSþHZØ¿3CŸðú*Al58•hJùz#8 ¯:[‹»)tgoÕ'¼–’X¨p—Üu.•=&CÂë‹ë’%;ï*ºî­1iöjNˆ‘¨ìá\EןC8ߘm¼KjNP÷øÞ˜ôÙöwóp¥~øg¦”pŠø•žŠ'†¶o©!¼©JÿBÁŸcÖ4§¯X¬yx¡®î¨Ÿo¥’§W8{Ž®K“Cç êÞnJE‹èüy¼ Î¨;Ñ÷ûŸbCŽ Ã0 ùSHA7øð%@8M™¾ËËï4vxÍqÊ$õ¬5€*Olº"®A” @i8¾mBoÀ¾Ð"‰…#¬=þ×~༠4\—*è׋¢Ž¬‡WwÿLtþ|£óàcœ"áO9\ ov4üÛX%‡k­@e_$¯LúƒJ«,9L KžÄ†Ø"…tô „5†®oç¨Ì“Ö‡ý{&Û²3ž 6\Ë:u—$Vœ]ŸÛïž¿Š—W¥‹¼2áw[væ³¶œ^×ç¾Þ]rK_[vÆs¢{Õ8›w·Eg€Fó`2KNÜù¸Jî Aû—)¥í–m_©’fLž/p‚…@Ðñ£ÉSñØí֬엠n_â'‘½Jnn¯øZr²cªÏís¿&òŽš¨Ûª…“‡ê¸…'ëúǬ7oÐ4¥þœ‹N&ѵTá)¹¯"®®?Ù×n „“!yNWµiB¨µë :¾7+£]„Óõ™ò¬Ó)ôÃ9§$‡Ê„úüsÞŽÈÜp7¥!Â+Sšâ]+ Jã(wóãÃþ=j4}'gØ¿GÝüoÐ4Âëìr¨&]ß好•3®¤4`R›¯øV÷Tq}Þ iÝ7Ïi{{óó¥Pi¦,ŒI,ë%‰EFI,N”Äâ¦ÔoŸ“CÕý|5oÆIba¬,¼Ô”òåL*{¬îâ‡ñª” 1éóW-™›ž—ÙcBÞZwé]=¥@ÞHsÚÒ™ú.¯În¬Çqð¢1!ïÆqÆäÏ—7¯_W¥\D¯zʹ•W¥æh£îþÂoûäɦכ«2wÞ¸Suۻ津¿Jbiº,Œ’ÄÂh)Xp©1yÎK”Lž²zûëfG…¼'Y2ÖÌÕîâéCþTw¨bˆB´tßöº»äö鼺{®)åË7ƒŽo€oëÔˆ{ž5§-©ÐöpBô¥aôg–Œ5ß»‹oMeŸÙ˜øáë¢kÙ½aÿµ,–fÉáª,Kæ†Ç½U3ÊáÚ®–Ì3Ãþìóýu³£‚ŽïnÒÅü÷CkÏü§Õ–«JNößs4Ž·HÝ·Ì>þ‘LKÚ¤C“ÄB…}ÿÈËÚ¢®“Åq`Ô%!ïFm{Ôí<4q„¯öí¸ö¨»­N·OóP™6æÁ}²äLÔÏ·Böwó”?tW ~Áµ á¿ú4eEàU©«MŸ'Df‡<ëÓ€¢6 Úþ¥áüUáÀÁa¶ÆUtíöü!QÙŸè¯ý gÈ»q¸ °„W¦„š¾Ó5ìß=Ý’¹éNˆ9ê«1é£Å„()•œ=M)_oÔDÞRp¡ ãÇ#·åþˬ œ"î7…nˆW$d‡ûÓõó†Q*FØ÷|Xקˡʮ¾‘MÉŸýBˆ’ÊaÛ wÓgá”Jüu³£xeê/¶ìô—Ývd]’X|ˆÞ€j¢î~C©fy7^`GݾÔ7 Q8°NÐôÿÁ”ºpƒ-;í@ðNmSèÎ^+ºW^‚¦ßb•yB®·òé‡#zìzľä¼29O è§2OX¬‹{¦È¾ø•œSaJ]¸(‰-;ícBN™¼ã#êÂ}ç‚RAi<ï[C×÷ö9Œ'‰EC@m½þ}ÂiÃþºO¯ k8EÌ>KÆoߊžß/R/*v;ÃÔíÇguV°>·Ï*óåßÉR½Vt-¿ TVòêÌuæn?®®Ïí{•ƒf@RY{xôOïavúK'‚p¡ˆ»Ÿ÷UÍL ØæÞ Â…)•Túø3ÔSmÇ‹îuCü°ÍéöïÈJ€È–î[i>§r*4}D½Ë–ÝýC×·_#œ1§‘9ÞtTÆ1ï;ŽyTÒpBT¶%sã¼Æóµ1÷¯w—ÞûH}NÖ9„7ï&¼ÕÏ ÖZ€—€ðUœ`uÊá:3!‚Û–ÝýuŽ×—º¾ý^8¯ñV<úX}nßaD0ï%B¤[ßåå<ûþá=mÙi/ƒ¨lÖ¬ìY„3æ›R¿ÿÍYxuÐQ0éºÆ9±†8M ,4‘Ógûë>¾1h_¨Q.x”Æ ¿ôUÏzDéàëjP™.]t|uØ»}'X*9Áê(¡’³ 8!ÒFe¯_ûH©è^¹«áÿ)Jº!ß“?ßÖRݺ˜ÿÌöÕ¼~Íþm4À…¬=óŸró<À…@TvC×·vùëfWúë>¸É¾x²>þù%îÒ»§×çd½$¨»/VG¹I•¥Œ¢¼`Lúpµ£`âT[vú‹ˆ&úž7uŸN¤²'Dði£ïÿ°Uþ N!ÎÂÉCoôÊbE´9mÉ wé½$±$®1[†³pòŽp‡9ÝõñÏýâ«}§•ƒ*SÊüµ„ÓË!ï·âñó†{t±O”¸Kïè¥4\P¦2Otì -!÷ª®†ÄöøëfGì †h£îüMežè:}5oœ 9 ÓDݾ\q­yLœí‚û“ÍiË~q—Ýß] ä%ß[%:±†¼Û®çqë•ú¡E²dçÝÅ7#¼ÅeLút‡®æ=ež)Kn'X\†®ïìlžíƒR‘¸Š® ( ªŒÉs×p¼Ej¼Ž®‹ÑÅ>¶TiãòVÍL ¹×ôÕÅÏX¥Ð ñ5Æç­|¶¯$^fß?Ò§Ÿ±œSÄ…Ü¥wŸ/hz´ÆœìqW9Öí‰]lHüð9\§ôT<úUTŸšó‡& —IJnÝ7Ï‘%;ï­x*St­¸R¡ü3¯Lª÷×}ürdïŠ+Ü¥÷f…<¿oHüègáäY‘½ ï©Û³LŸðÊÕ*Ë”z[vÆ»‘½Šî¨ÛÛåkMäô‡uqÏÕíK}ØøîS‚n°·>§ïÇ‘½Knt¼hŒØ?DðZ{îÂ]zo–è^5Κµï庽]çX2×ÝÒ¸ˆR‘ÔíÿÝÚóÀ0Ž·Huû’ß5&¾ÿ¨ªRz«^xÈœ¶ô ûQoEö*j–±åôzXiõ£Ê8ºÂ]z×S¦”…O8 ¯œ¡‹~–¿öÝQ„ÓzŒI³—ÕçýIdïÒlÙi¯hc}™WÆ]%w¼`ÍÚ{¯-»Ç]Ü“ÿm~ú39\Í{+Ÿë.ºVLV†ÇñVo ~Ác m»x4•}zKÆšï¯Ïí{ŸB?l…<” ‰…­Y¹Ï×çy› 9ãcÒ'»þî/·#®rl+ÎCGÇÛ - IDATÈ¡ª®Í;Cæä9W9Öí[Ä)â—ªLã :¾¿„ð¦jNSöící¹ÿ‰º½ñ 9E—å„ÓÛ¤`ÞTAÝë9\Á 1ûMiK–Øö¥ÎU臾öm¿LÐü4¨”ÄÒôˆî[?©Ïx3§ˆ/àq6ѽúJ…aÄBѵüvsÚÒ{´ýå1^•êÔFÝ]ùÿ1uù’¢6)M—,]ËG€p¯LÙöm™hHüèYWñM/*´¾ÖDݾË]2}† éÿƒªHdNŸðæ·Ž‚±kš3žS™'mõÕ¼ú€ é»DׯRÙo4§/ŸcËNߤО9C×&NWoÉXÿuݾ”·uż2¡JШ :ê+‰Å}ÚkD÷ê›#{ÝÑŸ·ò™dݧO©,_ÑFß{оÿÜwÚþ ¼a¼"a—9}ÅÏÿê{Ä*Çã9rÊ*•y¼S1ÙF8ÍAàñuTöD‹îÕúúÜ~„ý{{€@–‚…©@8m¨#&QÉ•ú§ëÞ¥²L©ox.r”Š„÷èâž)ÐYiãj¸¡œ$*Tæ+¶É²ë,^Ýc5º¾™Cew7WÑõˆ`Þ×|iëáús8Þ"‹IžòG§újÞœBxkn ~^©+›O%g÷{ÍhOù£S g( ù¶_ÓÅ>¶4Èë*¹c§LX Töføkßžì)t*Ç›òåP¥ 4^øº¯úÕ{mÙÝ^k>L%º–ëóÎz?ìÏÎ@¥ÀÁ†÷ˆoø¶Í)bê¨ìŒ9æÛ/Dç5´Io“C•ÑÇý}1…~Ä~…þœÍíÓ™pAsúÊOtqOËáê äpmzØ¿o•œ†¹€%cÍlsú²ÎoN_±Xi¼èg)TÖÏSv_O"Xv™R¾Þ¨²\ñaØ·cŒ!iö9T5äPÕPcÒGëDϺq€¬ y~¿TÖzÊ ‘ù!ïS¤@NªÚrå_˜‰dLYð¡>þ¹Cr¨ì"*9Âþ]çQÉÝ4È¢´+ à ¤À~•¼ÝÃìá²dO’IJQ@ˆ&ßœ¾b1Ì!*yzÿ¶Ê‘ ¯«óÍiË–h£ïûFUõó×}Mï7§ý²ÌøÑnMä-5aö¥C†÷‹@ÅXOÙƒ™Ñ)£k@·!áÜ sq$!J›)õ‡µúø—Þ \t²CÿjÙ~Ðñc"á4ejË¿{«f] ¹ Kγ<¦‰®UÃ9e×:‰JzçÁqcyuZ1!‚÷ðwMßÞ oØï(¸ô|^[¢pÞ,{«ž{F9ýú@ýüÇõsw«#¦ÚxeÊò kéKÚè¦á(D•iœËÍi*tg­W[oÞ°™¤‹›Qè·ÍIr—Ý×C¡\Íñ¦0¯L\A! †.³¾ Ø¿IVG\]ç«~@CÊBø@Ø·sª>á÷5ı‰SvÍÓÅ>ù{ þ‹JC„ãM~cò¼ç]EW=°¥¾·²á=ú)‰pÚR•eâ&_ÕËãüí;,æŸk|ÿæ¤!¼»iÈŸ¨KÌiK^9üeº!Cá‚MÏžþp•JAÓ¯Ft­´€$–X ¯«äx‹DxS®}ÿð+ oÊㄉp†JA¾Ò˜ÞVûé뮺¹ ´²ë×ʨÙE2ÃÓ¼ÖµiRÝ]ˆ–5D`'€&þ«×xO~Š­ìñWD¶"@5ûUα«««vÖHQpÚäß—“LÌ)[ù3/s®1˜”¦m¢$).FÝÿsRÒò©nˆ@›´v`´•=þ ïÉK`ô°•KÉÚ­ü1UÅ~rœ BóÝ ŸŽ YŸSò¶')y;%Kß @Éo©¡¤™û@J3öP²[ê)yÛS”¬]žoÌÛäRòvM4ÕþkœO¡á|8ªÆ'_ާª³&;ÞkY­ñ˜—ëµ3b/|Æ¥c¯x1ýbòKÙ+_jåž½Ü EœÏcVäëH{ÅèÌË­û¿ ­è¼ÌRØ'Û˜—9Þ˜—1éBåe!O×’˜Œ¹©Óx瞇¤úá«$š{æÝ9“%šþ?ÈÃ_^Í9÷ 0æeL2æ¦ÌpÕ¿eÌË|ÕV>z4l-)EÇÃçµIÙã[éÈ׌y™ã¹iÙŸQ²6‚‰ÜgÌM}Ó˜—1Áœß¥‰£É$p$³3@ícä¹Ú ¤é^’ŽÚeÌMžcÌKŸì¨ž”$Õ=üÇøÅ3ƼŒ ÆÜäÙ¼ë4°<"$ ÆÜ´lÞ{JFP†ãÆÜ”é^Ó²1Mÿï/4n—ÊUW qÖLMð˜W<Ò\×ËÏÕPapTOJò˜–cÔ½ªc?;z%uÝÌÜl{h9q‹ …Ï\¬ŒŽ1/c¢D;hEsqÕ áÛ¯l½‹^Fðžj¥OÛ÷Å¥œo)ì=Qz£?õÇ{r“ç2 'úŽSfÊÃ_™®=׿uÉÂ^Üv.}À‹Á^þlkPÅ.:ë{Â{ò$öògïÓ¥l[q©õþ÷Ð΅ǼB'Ñ´\ìÿdsuŽóÁÚ6ª(Y+·ß«õRÚù»²ÍÕ<.õs?[B‹\ ø4赬ÖЪnŽ 9®]ì\ÿ´RˆÔ0²’”¤œ×#J>áõ+mƒQÞYGË;Nú»ˆü ×'^Ëj³nö ,Ø#!5«b,¥]\¦mÆbÑ«õy™nÿÀ§©È9ÿì 0šÄ•süu8kçÄx­«{êR¶-µ?ÐKðÝFJRvj[®ÞÊ»Imeÿ†E{ Àœºyû®úù‘ãW`Ñ.Ñ øFðšWŽDyUÏ_T1æ6?c™ó;‚+œ  …ºÔ]ßž©¯îîÆÅOB<­è´^÷ÕAÞ[мH4åwNÖ§îYâ³yF¬(X³Œyé“)Y»-ÓÒž®ºwÚRòök5 Ëwû&˜ÑýE¾>•Vv]§Žýì(Æ<X@Ö’aE®º…ÈU·œYÛzµ£zêƒXt$ÚûRFM/6çwHâùºV´²ë:À"`)º·à-ºƒ #ŽTh­"rê>ÀàO^‰mÑRݰ%ŠÈ)7T˜ÍµÂ¿js±\ìysUKiçïÊ6Wó¸ÔÏýøžèšú.\ÌyW¦nr!®zÉ$pn¥Í‘…>wÅ릌º·=8™Ý˜\¹\ðžzRùÆ"‚Ž.´W¼0@9ýsCFþ,ØÂíϧ³ö-JÖ¾q´*fÁuÜ×s :’°—nëi\4V9íg[éãE®&QŸ¶¦àÍïæjXi/õ"ÕªèwçcÁ~Örš«þ½7¤úGVé[š*Ѭd”wÖéÒöLSÇ}ù>kýõœ+öòÑmcÒq2[ýÞÊÀÏhE–E—²i†&ñ§·Yû¶ÇH&f+%kó£2PD¼^Ži±!=o–&á»=Xdåš„åÓ8çŸ#ìeO>„HµE›´îmÖ¶ùÿD¾Ž¹ê[¶T.²å "[ÑU›´îM©adƒ¿^GÕÄ'H¦E±"|Ü—Ó’×}c\Ó 0+Ó·:2[ô–Æli¬³vF¬à-¸S›´nšÈÕe lE²ÈÕÑ"WÓ@`K†ÑЬ½Rýc_yLßxƒQ÷µ!RÓd¿áôÚ>!_ àÓÕ³—?ÛÚ^1f ‚EG-¡¡òÐÑ'­%Ã5æÄLËo]®Iüi»ÿ3¯mc¸×üÃH@¢;ÉÝøùY)=·T?ì7Ÿ,áå]‡¤WÝ ÖKQ¿Nèªÿ0.°<)MÙàêö#ò¦¶º´ýób°£fšÃcü2@1imà’kßÒž`âv“’d–”$íù†&*$I+üO§îÆOÏëuÄçÜ'£YîkmÇ• x Dª…s©á\,þq¸ã1‹wŽärÅ‘.Æ)„‰/¾ÜÊ/J’TOJÏݼXÛ†>"W“úweD¶‚æ]GG"çü³¯¥ð®ïì•/§¯<ï:ò< Š÷?Δßùñ˱ëßÄUÿA‚£jâYRG×3Xt¶ØÚYýF&AjO8«&¥^Cú‰éˆUˆ„T?ì°ÈյǢƒÀ˜E³@ªt¬£jâL¯eµ†”$í#¨ð£~u eôÛ{ÊpÜcZš)òu$íM®³ï‹‚çØ®ðÙá Xǃ¤úG?WÇ-y@TbÑ}Öw‘*Ñq2[—²õEι·ÉÓ k]ÓVuûI›ôë "˜#¡°è–U¢­æˆ5ù!!¨Ðý´¼ÃFCzÞ,]ê¶ñŠˆ ¥M+`šLf>ÛÔùŽª ©¾‰XPJ ÿ×@2±MÊ2ª;‰lE'Q0“{ªóY¥‰b þ[É®ÿ*¾eYÖ’!ùì\a7Ö’a;*ÇÝzeu<¸ ðï•൬ÔYKzóÂ%ÏÏŸÐ8çž`¿1/c" Ýaˆ;¢OݳķðÙÓ˜$¨°\]êÎe>Å W8 Ú¡IX>ÏUÿ~:çØ6 Æ¢„db·‰\egD(ªô­Ž½ËÚ·v$ÙŠ"ÖþGçØ>“€iWL&$ œ9¿Ë¤Ó{!˜ cö ’Ô}~•wã¢0Wý»£‹4"uÅê¸Ï–¢MÚ¤u`ƒ¥¨ï=^ËÏ/¨¢ßm.è9Xä*³/ yúyø+U€(›¶åÚΚ©Enã’ñ°ÄœÛ‘7¦ˆ4"ä5úVÇÞcmëÕöÊqÏæeˆ×ê[ùÐoƒ¹àö¡"Wß@ÈÃ'¿ånXðÆBŒMßêØ{îÆEa®º·Ç`cA*ÕÏ»¥ BéÐ$þ´Ý\Ðí!R’T¤Šùàˆ9ÿŽg1v(.eóF3`×ôÝ‹}+GP![e`e¡ÏïtTMxÎt²c„>mÿbYZÙãké° ”¬Í&Dj‹©ãRS„+"³—;«_̘›<amÒºlDjK*„E”¾ž BÎÚ‘‡ŽþÊÕðѬu’Qöøät}…ˆù”S¨#PD¼^Î9vì4ŸÌšˆr!RÕˆH Hõ)ß5ùK…$ð8ˆWÝÜh‘-l.èiaÔ½¸jg'rÎý­åáã6ùWHU“x÷áeô{›W‚XÛzµ×òs‚à-‰%¥©Åª˜sy÷1©«þÝ ‘k0LL­,ì…|Gå˽(yûeÔì"{Ř Ršj’‡>_c+ÑQ¢}°Àcþ6S“ðÃ.[éð,yøøcÎÚ™í¡ðˆ\]ˆ&ñûMˆPŠöŠ1œëà­”´UŽ*váa„ŒEa+û_g‘­ˆ—…=ÿ[`ÿ¬§õGLÞø”嵬Ժêç÷F¤Ö¨m¹z‹­ôñ‚· %ïpP³ ïBcf-~ð‘«Ž¥UÝ÷*£fùnb§¶«!«ã—n÷)¨ì–;ª^ëCJâ®Xû‚ÆÞßWGÉ;¬Ö$,ßݘ·–¸_L+á¨z5c^bÈ(œdÎïú¨£jR7DªíH4d7h÷]ZCÆ©q9 Xû%=J,º%§ï ±!ãÔ8s~×Gµ3³¡t!BÞ O;8ÃtòÖQ{ÎHåœ>cÌi9@ÓòçÉî†O¢]Öªã¾8ðW¾ ?ò°±»l¥#Æl -°Åw‡d–²—jã6-*eÆÞhcnò,:Z1ê>Ó°èQ#RW¤OÛû¥ñDëqŽêIIœ}GGR’¸OÛríÆ³ÆLôª©)Õ§íÿÌRÔïnDªk•³¿rT¿þˆ­ìíx÷‘,ZÑåGuü’Çc¾Ä¢›Æ¢G@ §ÏW`Ñ%µ•ý¯3 Æ¥j1k©³fú{ùs]oAR’²Y“øýfD(EGÕø¯õW­!=gî%^ûkB²jCFþ”À÷ '³›—Ó&ýþ+üz¦L«ãó‘Ù¥ŠÈì·e©üH´ƒ§Ÿ¯íÓ_Ä7š¼c_ê’7ýðÒÿÅ=§»´2jz±2júØæïK4ýg7O÷ùá€zvùß×·:²Àçâ,Ñôÿ0ðÿ¤úG7Ÿ«}Yèsµ²Ðçšxë[ùÀ¬IXöç™ÃRòök8Çî§e‘£>¤Yn}«ÃÒsÞö <⃒µ¶"”¼íIJÖÆÀÚ~@JRöÛ+^˜.ÑôÑœû#{”4õ˜õÔ€Y†ŒSãüç³ö-˪÷e·)¬}óý–S"%šAG½Öuóiy‡”¼c¥èžOhyǯ¼æ•ñ®c;$šÇœu³§ñîcsÎÝCÕñKÇÙ+_ÊÚÖ'¥inÖ¾í9uü7söm¯LÜ¥«5¸5ûô^´œQvßÍÚ~ïc)ê£KÞ¼Út¢Ý[$“°’ßrTd+eó”1/cIGåNf®úù‘®úy3uŸ°`÷­h`–¦•ÝÿôZWµ– Õj–ïn>NÍ¡•]÷{Í+žŒ?eTÝë½¶õïÓò¬7¶"Ózê~¥6yãZkÉд¢ëbι§ß•^§Kr ‘hô!,r•-e!O—ú?çÝÇ’ *¤€`b‹E®*‘úÓj #I·(@ˆ¶pÎÝúÀúið•#5"ß&pшÔÕøÞÓž3P–VÜö©!óÔXC橱”¬G,©RÝ#…çëƒÛ¸¸5 ¦Þcú>!i=€D÷P1l>[S¥ŽÿöM‚Ž^ûŽu:3PtD)AJy×±D‘ohE˳ΫEFJ’ˆ\E†ÈÕ¶qTMz °@#D`,Xie×rߘÈ+ücú×RÏÞSéX0¦;ª&=†E—2"rú"_oÌËXh-Úå\m_ÏÐòNZÑéÊän‚\ˆP¸°`Ñ©ã½p©Þyÿuu_ Ò©Š~ÿ„ÿiLÙâ­ÅšÄwr-í‡Egç:tœiÓ׆À:R½_“øãEäÔÏÉ»¡8¦MZÿ›ÈUÉ’—kÚ.÷¡à9ÙW:ªŽ’¶Z嵬Z ŠùðMJÖz•³fú}öòѽH&Ö—Ú^]Êæ%Ú¤ßÖcì ó-Ñ{i¯õ—‡±èÙ²®¬}‹cA¦MÞ¸Fóa®<ü•*ξu )I8Ð\‚Êcú¶/-ï¸DûÙQÿÄ…›Òk]=0¯äÝ9]ሼ1Äk]û0Æ"Ã:þ¸ýtk“ÖmhüIà*Û9ª'%!BY¬IXö§D3è»+¼LWæåHÒ-¶YK†=Î9wË]uï´…<³K`Kú¸êßâ]ûï§•·o½’úe†‘;oÁ}öòQmoQßs•ùúHGõ‰Žê7y÷1))IÜì¨zå α]᪛}º”ÔQ51É\Ðí!αóyZuÇ§Šˆ‰»£Õo$:ª& %™˜Ó¶"L+²Üú´ý‹E¾¾«Çô­/ºß“ÓßUÿn”À–ô‘…>»‡’µÙà1÷¸×ºVí¬ÓÜ.„€VõZ„Ãw#ŠY¥²ÅÜ éy³BÚÔö À"À»† BV€sZ©ã6`VÀ»sC€ÕbÌ"ÁSØ› Õû] g¨ã—ü!pUÝyÏÉ~Ѝé«} rιﴀ€ïž˜sþù„!=o&£êö3Æ‚ŒVd¹„³ô Iâw¼;g0k[ß$Ä…  Õ"ßáÍ9÷ÉxOÞ}†ô3HiêæsÕˆ»á£‘«ºÕ~b:IGíÌI}ýõ+ÈyÀ˜¢åýý¸ ÃßÕy1\´RH r%IY‹H­¨IZ·œ¤[ÚÊž˹öÅK´ƒ-RÝз<Æ%ÑÊîËT1æÒò[*(YëÔ¬Í1JÞ®ÔW_«-”´µ•’µ>ì+Óî¯r§2¤úÇŒò°—¦ðîc­ R—G21Md)Yæ>,XÃYëš{Yëš{Yû&½6iýjRšzÀVþÌˬcW2A‡sºƒµm¸€“_ÖÄ»@ñúDÖ¶®AG”jZ®YáëoÒ™”ͽs9ÇÎ(‚ŽÚçnüb¸D;ø]‰¦¿M“¸b'-ïô«£jüξ¹mS»Z¤díªTÑïd4÷.uÖÌ|ÂcZ6#j’Ö­%è°¯eåýˆÒíPF¿}‚`Zö?„Vtú˜’µ«‡¯”èþÈUÿÞOãâ‡X`ËCmåϼ,x‹Ó”-f/bÔ}m´¢ÓrwÃÂýŽ7"^ËJ­µøþXt®úw£¬%ÃÎv\ø‡±•ý¯Ý…Ký{\ª2ʵu޾;k¦&x­kÏŠåû¯BБsÓ²Ïw]uïo•c'ó2'sSfž]‚Ws“çxÌ?>/ÑÞ¿ªÙ¹vDjNsS¦³Öµÿ“hïÿÑœû»S—²mï>ö«aA$Aê‚ÔEˆ¶œñF”Õ^þÔ›ÆÜ–ï’¤_b0BÒzcnZ6kßò("”"É$®7æ&Í5æeLôÜP’–'¥úoÛÊŸë1¯ÐùíQ¶xë‘«ioÌkõ†1/süéåHdÌMËæÝyý/4VíÀFŒ=QÆÜÔ7®²ÛùË ¶ B^cÌMžÍ;þz¡z/ÄUW ¹Úó2Ç#Dð¢`×¥l×<˜ïßÀtâ–ç(ù­».Eéþâën3–Vݹ^ýþ‰«]÷¤Ò˜û9-k¿T¢|ÜQýÆ,FÙã³ÀÔ)çÜÛˆ‹Ý¤¾WCÅæJ TỉûÔžûì}Às~—áºÔÝߘN´+ }q©,äÉÓ‰[ÆPŠ;Î¥ÆT 9?^ËJ-£¾ÛxÝU¯¦x­ëiâ¿þ€”¦°ç»¦£¢aÌMË–hú-SFÏËðýßÒóž<L Ë;kÛ¨j -òu$ïΕ5‡9¬m£ŠRtpùÕ?ÎUçßžoߢ¼˜¶8çnyS Ê‹äŸV ¹Ú¨ã}(xòå~wäk"òoIiÚ?s"˜ü-¿õ¢þ¹n¬%Ã:óîCw“tÌauâ¿Z û<¢7Jà*Sœ5Óú”WÙÂVö¤À9w÷ŒIyØó %úa ¶’¡}¶üVJÖf³*vá^-ï/ruíÍîc»t)ÛÎ<]› îxXäê3©®PEÏûŽVvsšNf= PXt…É O~!¥ê´TÛ0‚Ôœåaå¬ÃÚÖv¹†tDHŒê®ß¼Ö5‘LÜmòÆ5"_GÚJ»G`ËÛS²¶›5 Ëw[ŠúÞƒE\ä*³ÔñK¦9*Ç= ò¦$‚ )`ÔwíVD¾Yb-~ ïÉëN2q´I¿­÷·g¯x>ݯ&Â(»¯°œxŸÈVt UÝW¨c?;Ê9¶+U“‰‚5Z¢éû³²ÅÛ¦“þr«ÈUf1ê>K9çž®Xt…ÊÃ^ú,PZËœße¸&ñ‡åŽêìLÁ{2M—²s¹9ÿ¶š–«¾ÃX ½–•Z‘«ïéª{KﵬÜÀ»ŽÞjÌMJJ’¶i“ÖÿÖ|Œ‚œÍ¹D&ÖNÒ‘'.cu¡ÉÌœßåQ‚ËóOf¶J±yÝçšx*\`Táý{Ó¼ŽK™Ì.v⼬Éìü+«¯ZÑÅu-'3ß?èßc_ RÝPSó­ƒ°óIDAT`Ù›¯e¥–sÿn®ÀÕ¦Ú˞ꢈœò#"•yú´‹(E§ :r«.yójÖ¾ù)mÒ¯stiNgÔw›l%Ã{aÁ©Ñ¥îžÅ»ÝÇ9v)*l;­ºsIàd {å7CFþ‚Ž,vT¿Þ@`KF2ê»7KÔ÷þà6~1Àm\2A9傎,,4QÙb½à-~@÷Ù[ó2¯uÍMËUÓxoAιOf+Ù‹.¥Ïžƒ÷±¶õj«Ìùúd]êÎלÕÙ=1`R¿tŽÀ–Þ'x‹Cìϧóž‚,}Úþ™"WÝÊQõêaUÌ‚<¿šˆ*ö“ã¾Lܪ؅sXÛÆQöŠ1ÏP²ŒMü×ó=æŸFˆ|͈¸QÓçzL˾dTwn¥ä·lr7|Üd cÊQ=¥ çÜÝO`«nǘEWݠ‘¯é*Ѷ R}Dö⇧Ã\‹Î0MËÕÙ¼'o/EJËAú|Íçþ]êîoýÒp~ôi]i½7 —=¡9k¦&ØJGtĘEóò3ÞŠæ‚;¾:¦]{<æåzË©þ½¯µ7nã—H:j%oïa”·mä='Îë©IÉÚþh.è±Àœû+"WC ÞÂ"ßÐÊœßu&¼æ)ç;×Y;m¨1/ý5Ás²—ÈÕ¶@HV¨Œš]¤Œž—Eg¼O‰ñRÝP“*îóÍ7ý*t'­ìæ$¨°|’‰ÛëSW”yÌËâoQ‘«ÏðÛã1¯H`”w¬'¨pAàÊo•¨ûl£YnDê÷pŽ]=@t¶0ÌšˆEwç$6o3uü—ë}w¹˜ycëØÙÏZ:|,&N;-‰šÄ—ꆚ¡ÈQ¶˜[(Õ>tR¬ÉMÇó–=¼ûH'À¬– uyÖâÁw](æŒVtÚpºÏåÓ7-þ®ì_¸ÏÙj2ÿ"WIý][‚·ùºKî¼…L`ÎÆ«ÅåÚ# fòjÝ,]ö„F2ñvRÒ²³oS:«^;#8,°e7Í xNªoqÖµ¶ãfB¢îw\äëÛpîãmI&þÐùʪ¢ßÙ’Y6 ‘ªZgí̳dâöÒófé[™¨l1ó"dV,:š¤ˆù:RäÛÒófLô>>¦æj¾e‘>­Z’€Ïñe<=É!„á´çª?Ä‚ £÷’’ø=Ù3Û·×DÈX’Ž=ÈÚ6uá=y,˜ÛP²Öû¥;iHÏ›eÈ(xMóÁ–¦íMžÖ©ýöú^kŽIuC–Òófé’7¼â×Mý+œw¿Mõæq‘«í…y %¿åOÞyà%J–Þ4–16‘¯ÿKå‘‚¿Ï‹7¬ÓÑÕÀ\Øk ¥°ÏWíìô£=[ù¨ž¶ÒÇï|ÏRØ{€?ÀZ2ì1{娗R§)¿óHË©û&¸ê?Œ¿¨òê(anª —ìXå¨|¹µdè—zÞ¹øÛYÚݸ(ÌÝðáp}«cï6ùR¢ø"U^Ö¶©%muT`Ëc9Ç.‹Žtc^údeÔìójcnÊLŒ9 £¾ë³À eGõ‰^ó÷O QºSâ­9‰ó¢l‚œ’µÿY“¸b§17émʉ©‘VÜökßô(%k·V¢tÂY3u¼¾Õ‘I悞O’„‚§ ½D;h"2»Ô\Ðí!‚ ¯ØâL,8¢)"5Åú´ƒ m¥Ã³8群$a6é÷uM•OBóuïݾ4ÖSƒ'I´¾ó‘ø÷ijo@œ<ìÅæuT½:Ë×LJõ#>”‡¿RnÌËXˆcĘSKµ| Œž—ïßüØÚRxφŒü)9‰ï#DÛ0vG‘’ä5"[Þc^%}n¶?näFG:ªÎc^¾×˜›4êRUüûÛD®†F¤Æ— ±cª±Àrjà«€y Ê©ˆþàD*E[éãVEäïHõnr5|ô¤9ÿö8âC‚ *ì€OyDU†HM1À¹Õ0e÷Ŗ»æ’Ö#R×drET¨‘º*Ÿ]†F@4ï;Ö–TˆS3½­ì‰{²ß!H]A…ºT±m´– ÔzjЀ˜R’بˆ|³Äœß5Õ˜›2 í‹•-æùÛ¤å–óÒ¦ÒÊ;V!R]§•_üöÊÃÆ}æn˜?Âcú.€ô2NfŸ«_¥ã RÓ$“ £yDêRŠN›•Q3rLöµŠˆ×ž'ÑøÙcþa8çÜsQºJ‚ qôù†Ö.¼œµ3bωᤤ崪w9çÜ'sV¿Ö‹VÞq\9¥ŒslW¸MK“D¶¼A…7 RéVÅ|œc-Ü]òÔaD8wã¢TYÈÓùŽê‰}c$ ý‡T7Äì¬+òF9ï:ØF:z“È7H¼æoonï>&å=ù÷»êD°ö?`Þ¤3t¨ûìUDL.ð˜¾6¸Kî…<µ]ªzÆiÇQ5>YdËî'%i_I4÷Öøö{íZ‰fÐÿï kߢtÖθ ÅI´úÕQhåíG•QÓ‹m¥wÀ¢]¡Žÿz"”¢µäá.iÜy‰´"+‡dlöŠ1¼;××KÈÚ¤u¶„¶—éIJ’*U1óó|v~kp7.º²«æCpA/ÇÆœ¸Ï”‘Ù“5Ó¦”>í&éèb@„(°åÉÊÈé?ÙËG½iÈ<5 áXØVC«C½½Ö_õ®ºycš+BpÎ}2wã§i¬mà ÚäßGîM5 ÿ]ýö0‰n¨É˜›òQHféèÆã-¾—…<5A™]Ú˜“ø¾:ö£)”¢³Ó”×ö³ÖåOXŠîé+x îD9 ¯û”Ú·ö7¤çÌm<ó¥.uûÓ–¢þc *¤X—²m…1/mª<ôùOe¡ÏÕz­kÕ^ó©¬ãgC2ËŸ0æeN¨û¬òo¸:k²ã=¦¥Ïc,2íÀ=y×!©¥xð¼ÌÒçl¥#:òîœNòð——9*_ý.¤M]WÝÜh·ñË‘ºÔݳ¹©›BZWÞ鬙ÚÒkY;È~ü¿Gà-dÌ…½ß É,}®ñXÄZUÜâa"W-uT¿þ]h›ú»¬Åƒ» \u‚>uÏW—zqo$/Ǜֶ^ín\Ô‹,Ã{Ž?’Yþäµ¶éjñ_órôZVkìcH4ýÞ‘ž(´^D+»~»¢äVQ²ÌJWýKhEÖ,FÝ'ÇU7ïu}«Ã/˜rÓÖR²6!Báùú²§~gí[ÑýøHgÍ´dÖºv$­ê±Œµm|V“ðÃË~é[ƒ£jü‡Ýi2Ã%Κ© :¶Þk]õ’:î˱QØZ2l!£ê5‹N™,tôa[éˆÏ$º!ÓhE×ZWíÌá€$‚T7lé톌‰ǣ—”þ£é·†µoíJÒ1§õ=ù¼çxïÜß^äkÛû”¡â?b”·/áÝ9YY¤ˆ˜´ÃZòèGŒªÇG¬cÇH‚2×§\xɦ™—ã—’Ô»>DË;|[œÈÕuPDL>o`,"¤§:š—è†1ö4 öµ•>ÖÑV:ìM‘­ˆÀ”ײ²©ª7"íÝP“O³é8£Ä9-£îkó¹bB`Kh‰vÈQ´e‘ÒV›|ëX´·´•>ÞQÚ¿›?ÉÄ•úšÐ–±Ž‰æ‚žƒUãLj|}ˆÞ(,Ú[ÊBG•š„EWB„W9µ‰*ˆÇüC4"äÕŒúžbQ°øösi)€4ä©,º[øÆD–ƒ}A„î&}ØŠ¿ÖŽ ¦V¢éo“è†!ó=±ÐQXpÕÏo@HišcŽDqºäÍÏ^k{‚\>í@+ Ò.wÒcúª%¢tG4 ßï–èþ”w¾€ Uµ-×n”‡>_„£âÅöÿƒÀUÜÊ{ ºÐª^’’–nÞ}¼“Ï{— sÕ½Ó€dâשã—îgí[;RÒŒ•êø¥ûIIü¯6T¸ˆ1Óò[On(YÛŸ4 ßíA¤ö˜«vv"kÛÔ@¤9Ç®~€‰³&ûL ˜Tÿ¨Ñ¯vBÉÚx¶:µox0¦\õó³5Óz‘’äŸÕñKhÜÁ¨îtøËKuCÌ"ol¯OÛû¥6yãZ,zÂ}û{«b/TFÍ>³Ê y² ÂœWÙC“°â5{Ř Àlç:t=!‚'¿³ö­.$÷»:~é~Jš±új]§ Nh»W`KSD¾qéé@÷PZy›¯p5,ˆ¼ú4ïÉÏôi‰µ-ÄØV,(­Eýïµ—?Û!ÊyZh÷Ì="U–Sï´—?ÝmE¤VtÖNÏ–…<õ8ï><¯êA2 ¼¶õs¤ºGÏxqÎ=÷¹êÞi!²ÕÝ“‰\u[FÙ} A…1æ"H:z›µä‘‘~å_›º}”¬íóɬ™©Êsа`OvÖL‹sÕ½3””$lÀ¢³½òå4ë©TØßÄQœ«þÝ(GÕ¤!¸AnPH&Ó¶\»QÛrõÖÿ’'ëÍ%kW¢× ²eD(|9s&Á%A޲Ž?ž‘hún,H±èh©Œš^쨚4`bó é'¦¢Í¢`” Ri H}=¬,8Ï¡œA²»Ï8Š RéSÞ@„€E/MêJÖþgCzÞ¬Öÿ§Múõ÷sõÁV6òVNjH?1‘ê|ÀI·¨Æ‚5¢iIô×ꢜڸˆd8@ˆmž6Æ·2±0[1e2%oï¡d·Ô#B•ëÛ7>™mÈ,~™dZÔcÑ×?,Z›H ^ œÐd!ÿÛIIÓ>¢dm<Œ²çJZžõ €_ÙJ‘Qßý±ÇøÕ}¼s¯,‚…HIRÖÖ¥Œšñ£(˜¢Yû–;iE§i”´uÓ §„¤ƒ@s®}]T1 ³þR*Ð$, Vç>ÞVûé뮺¹ ´²ë×ʨÙE2ÃÓ¼Ö_R¤º!»!- ÌgF0ÑÝÆ¯†I #fR²6yØ ŸpÎ]w ÞâdJ~ËMÒÚå$]`+{r,çÜ›@ÉÚX(iúvMâÊm´²ë Gõ”6æ*"&NôZ~îO0±yÚ–¿ü@šœc{BÐ&­ù*pHI’‡”¤nê™çnürÉÄRÒÔ_ûx%»¥ž’¥ï„›”ëMàÒmºÜ>Ø+FgŠ|é¬ë¿ rý# yº‰Ñ˜›:sü9Tj¾ªyJvË,zZ*"³K©.EHÒ@J[åñî#s“ÞÌ«šŸ§ˆš¶Gäko5æ¦Ìù†ŽÍ?§åíþðšWėǰèhaÌM™%°wž¯®KåºR ¹J ŽêIIÓ²qŒº÷B¿CŠ1/c‚D{ßOÅÿÓ×gÍôWýJךëqÍkY­qTO~Öž;àúPçhÎ¥Út¹}0æ$¾§Š[ü†£zòƒ$[èO r#ð_ÛC rr=+…(Â'¼~áR£¼³Ž–wœ­¯ˆ˜¼˜VvùÇYÍ ¹yÿt;72®ú÷{aÞØÍ˜—N¨¢ç/ŒIÓ‰vc0fÕò°—ËBž®wÕ¿å1~=€åã—zjYO êAÉÛ•*"³K-E÷ô•hæ\£oI¼ÈUÝJÐaÇu);—;*Ç¥r®}íD®>ƒ #ŽkZ®ZÉ»ËìϽ € R’ºCÛrõË©=o~7„$V}«£ïûÛ²•=Ñ^äªÃ•Ñïn±—?;@äRåíëT±‹ŽzÌËõ®ÚY#ÆgÅ Ù+_NcmæTЍ7ß÷ZV¥ñ®Ã÷ Bb‘ê‡ÿàÏšk[¯¶W DVMJSvh[®ÙôÏ\… AnN®+¥YèsµWZ£îmo.=#Õ?jü74 R'ÈBžlø§Û¹‘‘…>ó"•Ç éy³uo;]Rý°U´¼ã¿²…«~ÁDEÔŒ¯%ºÁk5Óš8S\Eªà- ØÊL-U lY¬À–u×$þ8]äêÚ¹êçG lI„à-¹O“°l{Ùw’¯:nÉ;ºÔ?gžÜ¾œs·Ü^1&Cðœì©MZ?KÙâÏýíXŠîéË9w÷WÇ/Ù`+{â‚Ô5j“Ö½íµmú?‘¯#ÕS_¢U½~•ž\ŽEWë@EÁLzÍ?WFMûL›´v%kã”êÉ5däO‘ž\æ6~qNoGgíì{H&î˜!#ª"âæi-Hë…ëê -ÈD(räáã+y÷±FË©{Lß@t·tT˜—ÿÝéþR’¸™’µñTH.çØ‘@P¡RòöFÕk³×º~ ïÎ=ä¨;éÁ¢;Öݰ0ƒ÷ät Ö‘Lwæ¦sÞ}ô)}zÞ‚Ô "W}lQ–¢~] ÑÝðI ]1ªè÷N¸êæ6‰÷rVMNG”&7ðÆÊQ9®§£zbG,ØšìÅú‘hØánX0Ö˜Ó²/£é¿˜Vd]±àr ÿ%®«'´ 7?”4ÝÕd‰®™²…Tÿ¨i™6iÝÛ†ô¼YÚ¤uo~N†J«ŠÂ˜EX°´û«"@¶Ê§ª! ¦Ö³ˆsîmG21Ç]õï÷ ˜˜ýú´ý37€ˆ(iæÁs§Eh#­¸m¾ß³• BЊοÒóféR·—GL.C„´Îݸ(Œsî–cÑ“h£<|l>l©~¯X,:Þ“7X—òÇ,©î᥀…³2¯H4÷ E¯Ê#&ÏöZ}9ãäæÀRÔ§ß’ãðz"ø„ä_…’µñ :ìˆ17-[³`ž_¡2ѯl!Q÷ýÄRÔw`AFP¡¹ºÔÝßøÏ—‡¿¼Ã^ñâDS^úíˆÔE¤ÁMP†R@¤¾–  V‘oÔ"DÙ¹i爐\³àcÞ“/sVOšl:ÑöDi#*Ä®l1÷¤¹ [†17i. ‰Ñžû"ÔùšÄ•Û¬%ü–SŒPDNûÖYýúcÆÜä!k“Ÿ*ÕøÄU÷öX$THzR’ÌÒòߘ zÎ@‚<ü•ù”¬Íæü.sILˆ ùÃg«¦J õ5i°ÙËŸë-°%w^FÕó‹í¢¹(¬%wA¤Ú)²ÕaÚ¤uí£3¶Ù>¹+LÒsg“LÜ&cnÒ\_"Ò @I’³ ˜ ˆô"Ü´²ç7¶Ò‘¯b¬€9…6iíLKÑ=³ÉjNª{¤Rd«·{­«ÿǹíÖ¥lýùÚööÆ!8¡ $ÈE¨£IXö'üé1¯ÐI´-º”í?pÎ}k(y;17é3mò†u¼ëÐfRšÂúsÖ©ã€#^ËJ-£éoEˆÁº´ã9ûv¥D;Ð  Ž_rþF 6ȹNhA‚ r™HuC̯ýB½¶Ïÿ^ ˜{ qŠ©ü“YË'‡$H W}ÚE×Ú†ÿ"Á -H A‚Ü'´ A‚ rSœÐ‚ $ÈMApB $H 7Á -H A‚Ü'´ A‚ rSœÐ‚ $ÈMApB $H 7Á -H A‚Ü¥¯‚ü³`è1}NÿÕn.D¾n°Š"‡DÞŒ®µA®&MS="Ѳ[b¥^è› kOnɵLð‰’Bp%àf…Ã_vÂÌ„ŠVÜ~­írõ¸¯à-©ø{]LîOôIEND®B`‚openchange-2.0/apidocs/html/mapiproxy/mpm_stack.png000066400000000000000000000445111223057412600225730ustar00rootroot00000000000000‰PNG  IHDR~ÌíM®7sBIT|dˆ pHYs × ×B(›xtEXtSoftwarewww.inkscape.org›î< IDATxœìÝwxSeûðû9Ù³ištïIKK¡-Z6²— ™NÔWý9DEEÅ-(‚НˆÈÞ{hY-´´¥{ï™¶Ùy~@ú(Pš’ÜŸëâj’ç9ç܉µýöŒûJ) d „vN•]+†¼´µþæ±µøøÊœ;W|mgíÍcë>ðó‘:×ÜnLâèW;êý5·ŒÍ÷÷;xÕžu¨ú–±¼D׆1o«º—±õwòˆê±oŸ¬luLè ûN\ŽŒmXÐÙÍé'ÌM(¿ylã§¡n K`˜ðÞÙ²›Ç6}ÖÕ…0ÓíÆ€:ñý‹¥·Œ-ìæ ”’‰$–Ü<¶ùóîN&£šýÄüä¢{û*ÚÑ iäLþ(å–±m_Ç*ÕMUü)§ÜÓØ7½êÆJAkcÛ¿íçШ*O]‘wóØŽïÉjò%·«Ê“Ný43÷æ±K†Ø«Ê³dS?Ëʹyl×ÒQ²ÚÒùôÏr²ïelÿòÇ¥‰ÊéŸåfÝ·Œñ2–{ç¡Dìàwoc";¶[Ðp"Qøß2ÆÉÙ.AƒˆTØÊ˜’í4à¶cÎ}‰Ô±Ó­c%ÛÙ¯/HnH9N>½ÀΩ3ç^Æ„R7Ž£O$ÈœÃnÉ\9JÏ(¹ÜÛ˜ØÞƒãàÖ…È\Ão]ÎÞ“ëàÚì[˽9r—ÐÛŽÙ9w¹[·[Æìü¹Ç»G°o“ûp¥J?»GÞÓ˜DÀ•È܉ƒg÷[Ǿ<‰Ì8ôcQÊ´yLª ä‰í\ˆ[È6%¬ÆdN~<¡Ä™x…e†{ã˜"';ÞqÌ»ë6ÃðoøÌøB±’øu›Ìb8ÂÇýy¡ã×}:ÃpDm³s àóøvŒO÷i ‡gwØTîÃ7µÚŠÜøº?þØt÷Ÿ,Y‚{üµxnq£«¥k@u|&06­ž-½e?B¶€±t!„B¨}`ðC!„²üU „p+ .°-]B!Ô‘aðCÖB™zâ'©¥‹@u|zM !„Xº „,÷ kQþØ\üC!tGªÊ<æÀŠq lç‚lþ¢DVRj:-]B¨cã‰í©GçáU ½ëd„¬?„B6ƒË—ÒÈÑŸ4RJõ–®!KÀà‡B!d#0ø!„BÙ ~È*`;„Bèî0ø!kí\B¡»Àà‡¬EyX¿Yõ–.!Ô±©*ó˜­_v÷$„ˆ-] B–€ÁYJ©^æj°t¡Ž Û¹ [‡Á!„ÍÀv.ÈÖaðC!„²üB!„l?d!œÚ¢dlç‚BÝ?d-/ûÛ¹ „Bw€ÁY‹Šà>ÿ‡í\Bw„í\­Ãà‡¬¥T§ðˆÀv.¡;â‰í©{ð jÀv.ÈFaðC!d3¸|)ûe¶sA¶ ƒB!„À« º®ºø2'åè–®!t+Ô©)jÔ§¥–®¡G?d!ìñï^dIŒ÷»Ž¢ÔýRUÑ•—ŠàÆYBèß1è›xe%Ç2`ünéZzÔaðCÖÂ)éàWv}¦­¨þ7+áó쌣Ǭ¼ü ŠBý{Y™{Ožú’eé:²x޲•z¾ ²t¡ŽMU“Çlÿº'¶sA6 ƒ² ”R­Ò·'^¥‡º#žÀž:úöª¥kAÈ0ø!„²\¾”öœ¸XE)Åà‡l?„B!Á!„BÈF`ðCV®/ÏÀ«þB¡;Àà‡¬…SÒÁ¯ì,]B!Ô‘aðCÖÛ¹ „îJU“Çìø&ÆÛ¹ […ÁYlç‚j ߎ*<"êÛ¹ …Á!dutZ«¨ðŒÌÒu Ž‡+Ñ^S–Öc;d«0ø!„¬NzÚV·¿×yËÒu „PGƒÁ!du¼|”xì‹•–®!„:¶¥ @èA „°&ÌOa$ö^&KׂnïïucF‡w›qîâù_{jµuâа'Ou˜‘³{ÇKýªª®ºw žp¶gÌ›iåÜCûßî]U•æI)e\\"®ñcÃp(À?' —’|鯈¦Ær/ŸIûò@}]¾ 3cwp×nÏçl\?ndç°©‰—WwW«+e~þÃ/ôíÿñ%€Œ«;®$¯u÷ˆÍMI^×ÓÉ)<{èˆO;òQxNöp þÃ{÷Ù W3ÿlž224lú…ΓŠœi0hÙ]»=åðÁ¹Mœ´y›#0TW]îÛóÆ° OlÜÆåIŒøÈBè¸ÇY çÄ=Ÿâ9]\AþÉ>‡ö¿5M*u¯”J=ËŽš÷ÊŸ«NW««Ånn=®ž:ùÅÓçÏþìP[“-Ôëy¡aÓOyû HÊÊÜÛ{˦©ÃÌëÊÏ?Ñëàþ·žãñ$jG§°¬Ä +žØ»ûµ^5ÕY’‚¼1ÿÛî‰ØƒûÞ|N(TÔ;8tÊ?¿dúáƒïFT”§8ddìz6aÉHW·è«n½ ÷ïÕã\ÂÒ©ry@QüéÅOÜÿVw6G`’Ûû—Ø;땪˜—xq¥ÏÅó¿M •åè¦*/¿r*î«PóvãN|ÞC¥*vÂЇê(p²Uþ=žÅïçG€·ï ø£–Ÿøq±W¤Ñ¨çLšº}@EE²GVÖÞÈî¯d¹¹÷¬0iÓ€¢Â32½^ÍIOÛ2ö˜×åäžüø„¿˜LVFúöÃF,=ÝÚv]Ý£/Œ·ú0À?'qÓ®l`ÞCh4h…ÿsµ³KdÀáƒsŸö vpôã¿زi ;5åïÁ ùöìcC¿;[\|6ðïucžTÕzED½´ÁÇ÷±J?¿¡'Ò®lîmÞ›˜“}(¶kÄ Ûʉ&9¼b’™“b ”6Xº„ÚîñCVRªqñëí\¾¾C²ÍB‡JGǰ,ós‰Ô£²¡¾ØÀ W3ÿ]Ñó™{¾·mËÓ3²3÷öÒinØ«ëêÖ£yY?ÿajuµÓí¶ëáÙ»y®·ÏÀæòùöåæÐG©‰hÔ5޾~C2š×0<]£©UšŸ›¸~SuUFg‘عhÀ /.˜_ïÓïÄúú|ßü¼cÎ/÷5µüØ>ï&ßÛ'„&lç‚l?„P»bXìæó0 J†¶|n~|ìȇ:JòúìüÏÿïõ«‹‚;?q€Þ°®úº|{ó㊊T6›×t»íÖVgËÍ«ª®:°Xÿ›ËbqšC! e³yMU•éÍó+ÊS”-çïÝõƒByi]]ž_ê•næ×¥vž'çnçÏœú.ærÒ±ž½O³X<<ï´Áv.ÈÖaðCuHª†b›-PÔÕæ ®¦m‹¹yNAÁÉnµ5Ù‚ÆÆrnÆÕÑr‡ +·[_^úúB~}}!?'ë@”BrÛ¹Šà”ÌŒÝÑõõ…üšêLafÆ®ž eð€øÓ‹‚ òOÆNxbãòΡS·Ø;{FCC)×¼ldÔË' âbÊË’»öŒyëÔ¿ûBèÁÂs¢BRLì»ñ›6Œ ÿa‘Û|£QÇ÷ôêW__èÝrŽLæ“ÿß=ß§ÔÈâò¤5'mZ~»õIí<‹W.|ßdÒsB‡²a#–î¾ÝÜá#Þ¶yã3~ý)ìS b‰kþˆQË·•–^”Æøâéž1o¯qqªsqŠ+->¸iÃøÉÏ>j @Hè”Â#‡ß¯ârÅ î15ìA¡€@¤¥‹@í®žRšq÷iB3åãLW¾Ôù¾«]>ôCEÊá7§NßsöAÖ†þŠò±ƒ"°ÑÜÆÅìûï\>îÛÿã?»>›[QqEììÜ­þvëXôµâóa#–þ4¶¸²*íŽs[ª®º*$„{¹ÿm!ßÌ W3Ë–øÍïÞcæÆ˜Þso»Wµ]VæÇ“§¾4 ›}äôf4±iõliíƒX×£Œ"ÜdsØ‘®Šg&…úVZºÔ>Œ&JþHÌh€o,]ËærzË›ŠÆšÂGïÑ]dé‚Ѓ¡tì|Ç+/Y,ž©­AŽÍ´y.€Ü!°ÍàÌ©o‚S¯lŽæ ä•úPG'ò°Ѿ³‹±t!¨ÝÔ^-³…vã«Ñ!™–.µFõGb†³¥ëxª‚z>ÏI9¶¤6õÄ/»¯œøYÀbq2Ø<ñY¾X™èàžÜcü·Ù<¡O´·~þÃ::†µéPª_ÀðCrEP›ßýR««Î.™={͹ø°·…ٿr¢;™“¬§”6ZºKâˆx¼þ«ŸNc‹xØgÒFì¾, wñ"«@)Õ<·¸Qç40ñìö÷†¥ÿi£Ñ  3ª»èšjë˯’ì ¹ ‹Ãæ ÏóDì“#†ÏO“»…c˜GÐè±«Ž¶uîØqk=ÄRšµlí‚:&OLå.U5EÉøÿ=²IüÕé>æógߨ!ÇÖ<û›Á ‰¦Ô$1™Œú º.H§©ÛP•k*¼²W@V9Ãâf³ØÜ|©Äݾ¡¡”+;c«„:MSµËŸs•k ‹]ɰ¸Õ,6·’ÅTqy’JžÈ¡J¢ð©rï4¤Ò#täÏs2;í׺̳ëñÿqd“0ø!«¢mªfÒO­”W%)ì]C©)I1tê~”sÃDJEôzO8j2ºMjW“AÓ åÔ¥ª›ª0ø!ÔÁp¸¢Z;çN+õ•ƒA§v04 ƒ¶Ñ_]_ª e©ò’ÌcŠôÓ«„0•„aU1 »ŠaØ• ‹SŰù•l® ŠÃ—TQj*"s’² ‚Rª¶ð[ûW!aB)ÅÓXP›`ðC!„NàØÊ×æÇ„0.”šd„0õ„aU†UI€èh«ç.B(ÃåIv*½£W;ûõ)¨H9üæÝ.&@µ?›§9ûÈá»Í+HÞ%,LÛ¯PUåʵ • V¥0êÕFƒÆI¯­nª-Rz{p%!DåPqÓ×Ö^«è€ŸYFÙ ¿Y[ÇôàaðCA±‡Öƒ\k_¹ð¿ÄåPvýkœ¿þ¼2tÀLì5£Jâàc8¿ë#§äËÁ ßçDL,'M,÷^3éÇÝN¾±Z€kí\úG=T¡#›4/z؈¥§-]˽R×2WMv#s’î¹ËõðTsý_úÝæBCëA1úÝôš!¤ÚkÌŽRúåõóýñõ&À0PB–ÀJJiÞ½¼gd}0øÙ ½ÉÄ'„ „»‡9 ­¹ ˆ»éõjKž\lnç°éÓ·MF½³Xî5¯ëw·øG?ÕæÃMM•dú1íz7½®ATV–4ÐÝ#vG{n¡ûUW—磪+èRW—ß.ç»™Lz¶Á { ±Y<1•86V&=ôv.×&V^ÿwW„( õ ÿû#ÜüšˆR--@ðàÚ¹$×ÿÍ€· !—áÚÁd¬±¥+º ~6H­7(`>Üæâá¦sè(¥ÜEYçÖI}zîøÜº¯ïuYßÈ)µðíC(ëŽÊ²O¹‹u½‚û,nïm#t? ÷Ç-14ö·€Ÿ…RgM{lS qz !“+ѾÓWÔæœû»£]¤”R#\ûù[Ö–ù„\ æ £n3{ýkwøLªœÊ+©ËOþ6gÐ]÷^"ëÁÏIyÜ¢úÆ™–®ãað‹šªò‹ššz?ËŠdnưAoV=èšî¦±¶P&Kl¡ûqa÷‚0€òìSÁ£ßŒ;hézl¥TÅPL íékÉMpmO ² -ä‚,عMw¿)Ü—ª¬J,PÜüz—·K#,æ¶§ÐT_.ìNñàÉEÇžÞò0·{Ú©ùg‚GcQ­˜N}üJœzùÚü}–ÿû ~/n;ѯXÕtÃ7€‹DX¹blŸcwZî“£Ââ + *ãsU>2IÅ“áWƒvm¾æØ¿ö?n0Q‹!Æ(WEÖ+Ñ!iJ!ß&;°ŸÈ+µw“5¾ré#݇ !ôèHØúŽ¥&;Uuî0Ààga„9ð5\;¼«‡kÏñáÚE+IpÎÀJi©y9û`—·]úú·éÎäï÷¯HÈÄ“‹n¸0.tæ€ÏYw~ÙëϤ,=6Säj—j2˜8º:µa1zïñ]7Ç.›×–m'~¾wª®VíȵT\úî ‹Çiì6ø¯^ŒÍiËòÖäøsk¨rªÜGµæ~×q_ÁïHNq?.‹¥ñ±—dÝËrGsKºdUׇD¸(âË4‰%Õ]–%¤¾2<À}óÚ‰ö·i9%wq–• xµë.gXt*yöž§†Îéåádsüßθçb<œÎ.Óû„¥k±4B3ma!á dxñBQAÊî„P¢×¨[º[v½›Âð”À8výëEJiõƒÜžÈÃ>u|â{?Ün\¯Ò° ÷¥:B¨×ã]JÍ{Y<¶jbê‡_™ç{{·”¥ÇÞ` ¹Úߌ;g~½>£\Xž'wX.t±»áP¼²‡ÏñÁ[þ³`[ô×/§ývrh§cÐV7rŒZ8JôyÛ/;+"=jÄžòNA0é¤è@šR[ÓÄõV‘ðo¹?±®VÍÖ7hY"w™¶`wŠ£ÐÍNíî®(9–!׫´á!å7ïá,:¦àÉ…:E¤g}}F¹Pâ«PCò«ù|±ž-âo^ËϬ`wг¼‹[­,عñæzò¶_r•ø8¨œûø×u,mm“D§ÒHëÒË„ m’x;Üó©÷}¨·›‹Câíš‘R²ðØÅÐÔŠZW{¯ñÕèÄÎŽö Ž"Aá–©ƒ·›ç~u2)ø³c‰ó¾»”ÿVl—4€ôÊ:áÒø”®õZ½`X€{úÔ0¿þ˜ê{òµ3ü¿ßðáW'.õÛ:mð6€¥ñ)þÁJûšäòj‡óÅ•žùº]}ºkÀ ýœ–ƧøÇVøpXŒá©pÿK|\où‹gù¹4_7‰°±¼Q-8’SðVlØ™pgÕ†äl·=ARWýVlØEO;qó‡¾3=ßiSJN¨¯\R>!Ä'gkZž×û}»¦è&òþ¡s‘ Eç\ÿ†Yq>Ý[)âkÆvò*ÐŒÌçÇòkê#\ùsbšϹȯkà/?›œ]Sïä-“”Ïêš|"¯TÑ ÓËÒ+k}ÞÙŸ îìh_þÌMïÓÆ¸Äoy˾ϴôBèFMõ¥cÌw¡@…Çÿœáß÷ÉUwm…‚ŠPX o[úœìsìè–úóñ—»‘-àÔ_øtwííBbÔÂ1+ÎçïÉùûü8sðÛ?æçq%G2Æqí…Eº:µ³ßÔ¨U½™ÚêN i€2»ähÆóó/þ5´æJI¨¾^#',bÔÕª]}'G®êóÛôcWÿ{ÚëìûÛß0é|ž½°äì¼­¢©ù çݼÞÓ³6õ-‹ËŠ1Œ\“ÞÄó²Ûwrdʉ—þzÝ Ò:£eØ,mÿ5Ï|ëÒ/ Z[ÝÈÙÙoñ5!,!·Vê§¼\TØÄÁ™3•Ñ^u;û?/ð™›#>y þ-1e'3{N¼òá×§^Û“ù×Ùç¸RA©®Níªˆô<8âàëöúy|åùüÞ\;A¹¾AkïÔËç¸ûД²S9ƒ¨ÁÈÝ3|Ù\žLP9î¼ïõ¿Õ?ǯQo`Eþ¼åí*µÖ£›³Ã‰"U“óW'“øŒïßê္½ÃS×&e]Ü’šóVl—´¸ü2ûñë,qØ5Ž"AÑÖ´Ü'ãòË~[:2æTk˳Æ ÒéÍ—®ÃO ©ãµF£ÀD)ÛY,Ìß––7=¾°|ŲQ±q}Wí|æriuŸ0'ùI›Ñ~q"Éq€ë†›×ûë¹Ôáu½ƒÆ`:Ø].mPó?Ûp¨ÏÑÜ’‘!JY|e“ÆqSJöÄ#Ïš¤°kúêdRðÇ“Þòµ—$Æ•wÿ#1ƒ«6%ï÷íúv­VÇþ)áÊìwû„?+ðô×ÖŸ6ÌÝNT4¶“׎U7fÅöüåÒÔoâ. ß“QpöÀ3#ÖU4i8‘¿lý.ÐÁî¼RȯڟUØËW.©)kP‹´£¨¢Iã˜XReþËÈ–ƒ_µo·‰œ»OCݯê¢$ŽQ¯íÞâ%¦,;n ´¡^GñoÚ¹t4”ÒÄöÜ^Sqÿ–ˆ/^7?çÉEU#¾ñWy|Žìʲc¯ùNŠø=ö§)' ‹¡M%uÜ;­Kå•Qq&g(@êÏÇýJŽfŒ‹ýeê{þÓ»žû`G·”ÎôyÅu@`€®N-ÉÙtѵìT¶{ÉÑŒ!òp·3-××XPÚëû'>z!&÷úòo¿Ü碬“sãÙ÷·¿!sKxlÓ ›8¾ñNµ5•ÔG|<òÓ.o=–°)ø“¹oyÆð}¯L»ýðTü››§<~îÝŸNÏÜØ_W«VŽ<6{–}ˆKÃÞá˦RmÓï¡üÉNk^ìõýÄŸë•WŸQ.Üóí7I_îOò2:«,.kä¨ã³gšÏ‡ÔT4pøJ±¾è`êUN•רøw–·e;­¹ïà·ûjÁdÅ—k7?tUÛ÷ôð ÿ·#®•Zë‘=kòç–]©­q“ ³kT:7J.à§¾þÄ—/ï8™ºîrÖÓ_ ‰ŽqØF€miyÝÏ–û\)¯íT«Ñ:}20rõÍëÌ™=e>ÀKÛO¦ý’3u٨ظE§.],®¼÷éá¯Çz:Ýõ„V½ÉÄ+|kÚ\€c¹%ò}™…“V=Þ÷½‰}Š–mžóöþø!Û§ Ùúë¹´Iý½]¶›÷féä“æÃ 7ª½e]ŽŽš(Û¤7’‚½WÂŽ’LÿéÝ ¢>}1íדª¼-‰®OÔ\.Š93{S˜®NíÌWŠsmx~KËõñ䢂 brÍ˧.?Ñ”½á| "Ò³D_¯qŠøpø~óáÝ;ÕÆµ›CŸºLÅm(¨ ³s½|zÖ¦0™‹ËÖÖ”FT%…ÊB\.šwz1öXù™œ‘mù,³7œëÂóª*/¸UœËw“‰p¤üŠÒ¸¬Náï¹Âó*Ž>µúy÷¡!'»}0,‘¯?°ï×û~ý}\¶½Û'ü¸ù¹“X H­¨ K/¶5ôè&›!:€üºß(WE‚yì•îÁ‰k“2_:‘[*à^PÕ¤U4é‚Ò†&o©8ÝÄÌ:)dÉæÇÏG]Z{)óåÓe²ÓåþŽ"Af[B@Âî’ùñ®«¾,†è¾<ü»S— ¥”QiõöuFJIe“Æ{¨¿ûŸæù==œ’6_ÉñkËv2ªëL”²b~Ûþ &J ‹ÝñÜR·—£‚SWžOçz-Z·0ÂEÿnŸðã=Ümî|F„åÕ•_F)¶|ÍhÐu.JÝ/p òH\dÖ‘Û¹tt\;AU¯%“niÚ­¯S Ø"^5Ãaµùëš”wŽ„_ÁpXÔШp¤üNÓáˆyÕz•–o~îÔÛßà-ÿÙÞ_ÍßûÝ‚ÃSÿ;vèÎWþùß|î ¿×9"^®^#P—©„„Åèå]ÜêÛRO.l¾ø>A4 IDATE•[)¢WiEÔ`b]¯«É¥à“Ö à+DÍÛUDxÜ1[P½‘e~¬«×ˆÀÔTTÛ|«P‡p÷óŠî^Ù£ãÞü8aîÖþ9/Œ¹ºêÔŒN/÷ù-êÓÑdï}?!‡­i-€0LFJ™{YWN­*ÀK&Î @¨ÑD›?­ÑÄP`1¤ùjFDàž×ztÎÌ®®ĬØñÅ [Oôÿ︾GÌã¦Û×M ‹a(CÀd‚ÿ­ûnìùܾQX„è§…ù»vמkœÅÂF¹V›ÞdjÞ®ÁdjÞ‡a(Оe>Ô«1æqœÄ‚éáþG[lîð@׉P—÷æÔ¹Ÿ½Ðe_Faakö~óÙ ¨¯^yd­ „¬ƒNS? nøùNh/ì^ë<¯îµQÝ< ³7^ð,;-kK«•ÊóùÒ¢Ci#{øú) s’ {›ÇkSKEêŠ_Y°óú›—{Ê5üùÌ››?*‹Ë:âëWÐTR`ÔèŸcªK/jª½äa®%.ýKáýí¬”%G;u}Xʽ¼/Ç>µ,>§NèbWÙwÕ“Gnç;JŠk¯”À~€´§‚[Ž ”ââš”w¸P•TØÙ<&uÍ+=–1ºÇ¢ Z»@Cì)× \7c/ì=2í¿Cs7_õéèDŽ„¯6j ü›çß‹~Ž_¨“<}kj& çnmVõÖ“›ŽŒ¬nÒzþ2º÷2{qÆåòš.FJw±¡?Å_‰pØu}¼œo9ißW.U?Ó-`ÍÊóéÏ—¨šâ\$B@ze]¨‘ÒM,Bèª éá".»*ÚMY××Û%c÷Ղ鲊ƒýÜÚÔIÝl\°Wæò³©BÁÈ6_„ 7š€£Hµ?«0ìž3â ËÃÍsd|®ÁAÈÏ[“”é÷~ß®)e jn~]c¨¿ƒ]&@°R–—_6à?‘Vš/þ0RJÌëç°º`@dÒ‚‘IQ¿leÎ.îôjtH¦½€WUÕ¤±»—÷B÷#aë;nÔd2ï0ߥ‡¡”ŠUU¹ÃÛºX=MEƒÛ¾‘?MhùZ¯'íîüFÿŒ´ßN^<çw†ÍÒnújŽË€ÀS»S ]¤é!¯öËpŒõÝ™¼äÈKgóÙ9V_*ò¶çÕmyÏ>º®Ëù'qÊž!?:*»{]UåT9êê5¢¡;_ù'lÖÀ}Ç_\»`׀x;–Ïè„4ßÁJí}9gã…IÇžýC«Ê©rS—©<¹vüJ€ÈOF%fo¼³{Ð’¹.}ýóD U‰…þÃ;_° rª½ôõþáN±~—*ÎæuWF{%øM‰JÎý'qÚqËLj=åå½~xâLë•ßÞ}¿Ã9ÅÃ~ø;Úü\ÊãÔœyܲ¥#cNœ)( úaãÒ¥,^k4òüäÒœõO Ü [ÛÐ9øÇMsµƒ°V£w¶p‹?ù…9ˆ}=¤Ç®Qk÷Í÷^´þK¹€W’[« )*xŸÍjõv`_ Ž>¿þrÖø×w²iÊc;Ø Ñû,Zÿ¹£HPQ]×ýÅÈN?¼’¹%5w×Ä ¿ t°Kà°‡aôÇfŒúãnï·—‡SíøŸÕ %¾µ:1#U)ä—Ö7zwwS&¬8`ÿÌž×Ï?tþݰe›½5£ˆEˆ¡åòÑnÊSߟNþ¿m©¹—KÔÞön‘ylù˜Þûc~Ûæöí_?)ìÎL”[£ê|ú?cæÍ?t¾OBQEwo™8«^«—æÕ5„,ÓûO€¡þîç–œI~©Ë²ÍÝÝ”W>Þ÷è½þw´„òô—•„áò± BAAÊî@ÀL„& L¥&1P*Ôk±­‹µséBrÛÛr>~vîâ¸ÿÛЯ6­ÔO•]it|@åUêã»×¤3pXŽÖ©—Ob·†oñÛ¥ù*_)Ö<È×µjïµe£Ý”·|S\ïMxÃN c¼ÞÓ¯Õ{)Êø\žï5ž¡cîØ>!tÌm\aê}#§Œ®+KóRח´……óþzßtêÚ§•¶.êÚBæàïÓ\Éœ :Ji›ï…µ¸§‹0îRQ¾‹Dhñ¿ä”"ÚM"¼§;› ûG)mòê2F{÷™¡{u­ Sëß}úˆ>Ó~Ín96maá<®@ö‡¦±jÈí–ïH®Äö^jx¤÷r¡ÿyló‹;;ÂÞ>€gê=ÛQ÷ö™Y]ðÛÿÌðõ·Û[Øž&‡ú%¼ôx‡øFD¡£±®8Ø¿û´q±S~Îmm|ÚÂÂyžøBAò.akã Oè`ê÷Ìï5”RüCÙ¤~U/B!ëÒwúŠ5N¾±w JS>Éý¼,;Ž×^5!„îÕíñC!ô`Ý-ôÝë<„å`ðC!„²üU „¸øë¹¥ë@!„:2 ~ÈZÔx†Ži´t¡ŽMS_Êìþa !¤Ã_ˆ‚ÐÀÁYlç‚j Âæ€ÈÎY ØÎÙ(v±ªI8}Ó‘à»OEÖ€R MzC…¥ë@!Kà Lýž][½z¶ÿP€Œ?¼ ›¹í­Øu1¨uBvVuýYÕõ–®µ/Ãݧ „²fµi¥[ãßþGjé:PûbSJU–.!„Bí‹Ršq÷YÈÚà9~!„B6ƒ² ØÎ!„º; ~ÈZÔzÀv.¡;ÒÔ—2{âŒí\­Âà‡¬¥´Ñ»Ûx¼J!tG„ÍD©lç‚l?„B6ÃÜÎ…RŠ("›„Á!„BÈF`ðC!„²üB!„l?d!®'Ö¿„í\B¡;Àà‡¬E½kàÀ&KêØ° ²uüU ”6øELÖXº„PÇF 8{=˜,] B–€Á!„ÍàI”¦A/l¨¢”âŠÈ&aðC!„²üB!„l?„B!ÁYBˆË© ÿgoé:B¡Ž ƒ²*GïÄÉÚ½š<Èy¡¶ÓÔ—2û–Žp"„,] B–€ÁYJiƒgÔ–®£-v.î;*aë;nwš³cQïAqë^h¯š²„°€Í€Zº„,ƒBíLâà›zrù–3›g{´6¾ý»ØÁÕÅ—¿ŒúKF{׆µãI”¦A/n®Äv.ÈVaðC¨ z~C P*N?µrçÍáoÇ¢Þƒª‹’V²9‚ólŽ÷H „z 0ø!dl®è0¥&‡ôS+wÖ–¦¹ìXÔg`UQÒr "{.!„Âà‡ˆí=öÂ4Pj²/ËŽ[”ŠªŠJ„†ôý¿ã–®!„õÁà‡¬Â£ÖÎ¥sÿ×SJùÀ¢Ô$¥Ô$»ú;+°çsõ.!„Âà‡¬Å#ÓÎÀ?ú)Ãâ\½þ”×[·=O$ßa©º²všúRfÿÏc± ²UüUx”Ú¹˜ñEòD{Ët ˆƒ* !«G B(`;d£0ø!d! Ϩƒ@ÀÐò5ÄÔïé?R,UBÖŽ'Qš{y[¶sA¶ ƒB2pÆú+È ÁÍÅ6.!„ ~Y›+: ×9B° B¡‡ ƒBt­­ i ¸ØÆ!„ÐÄÁYBˆó©¯?2í\ÌZ´u†ÅÎÆ6.!„& ~ÈZ4Éݹ“µ¯·uÉÀ6.=|ØÎÙ:¶¥ @èA ”Ö?·¸Qlé:î—/=¬i¬ ´ö6.ªªv܆W»YºŽ‡IdçZÝgúŠ,K×nÛ¹ [‡Á¡VìýiD÷öÚ›'*€Æj^Û l¯í Äʺ~O¯¾z÷™NS]1KÎËøØ`¯êöÜn{©ªhǽ” íüJ2Žò“|ÖÛº™ZUH©Éîa¿Ú9”õšøCþƒ\§¹ËêÙÒGîB?„Z!ÒfMÙÝ·²}¶æ{Ô—‡uí±¢¶Q-ŒK¿œ íüØÆøÆÌØvßn{Ø¿7ÝùäÙ4Ò^Û«,¸ É &„ôu¯i¯mšõÞ,Æ-A ¡Ö6ªKT²Ì³çŽÀ ~Ù: ~µ‚!@Þ˜Ø~eò .yNöíÝgþ{§.ç(Ne\l·€‚¾ˆ«1Ç:ƒtÜŸIÞÙg‹-]BV/î@¨h¯Ð‡BȶaðCVâ|fÓ,™¥ë@!„:2 ~ÈZ4É\:ë,]ê˜Î+´×h wýyg2QrætžƒÉDñPø\=•ç@ÛðtF&ãt¾¼=jj+­ª‚9øËX%!„oéZ² ~È*PJë;žØdé:þŒÂJqIU}›~]É-“TÔ6pvMÖâééëÞK¼Xt×ßõõö“ÓÖ-(*ªÃPpš-kñ¤u kÕw=G<ç|‘ìû)ë>lºÚŠR#˜(%€áÙ$ ~uoþ´cÂwŽ÷hËÜW¿ßòì/Û΄?ìš²6|©³iÈ+ÛË)¥jKׂ%àU½!‹Û±ýŠÛÑ#YþAAÊÒ]»Ò¢årAíG †ÊË­-ÿ%¾/›ÍgÍîs4"Ò­Ö¼ÌÂOEÅŸÉḭ̈ˆqøðNç^z¥gšylË?ÉkVŸïËb3Ægž:Ñr[o¿¹³ï€~™#FlÝ’â~òDŽß·‹Fk­¶%?œ =z8+Üh4± ò¿8kvŸËësxPެ:ïWšQ©ÊøM)‡³»Ù»JÊŸúnÄÁ+ÇrœŽ¯¾#”ñƾÛï¸['e5Q²vîÞ˜ÜÄ’@.Ÿ­é5¹Ë™>OvÍi^ßÊsþg6%÷â 8šA/v¿áó\þÂ?C>u. —gµynYvµÃ”…Câ[«mó'‡#®žÎïLB£Æ'<öŸh«¼*¡Ž ÷ø!ÔF™öéÚ‰‡/d:MýdíÄ óÿ˜¶õdŠ{mƒšóÊ¢†Žÿ`õô¿^ôi¹Ìö¸÷'>Z3eäÜ•3Þúig?ƒÑÔ|x)·´Føôçë=oÕ³_¬=Ñr¹•»?ÿó¯5¨µ¬iŸ®Ø Ö²Z«íÈÅ,ÇéŸý5~ÄܕϿ±dÛ &¾ÕyÕ•+eŽûö¦ß²%¹OL¬Wrnn÷Œg7<÷é'‡&* u:#ç?/nzÍ<άý7¬O×)Ä1ÛÍMZþÃ÷'žÿáû“¡Gg9¾÷îž™B·)<Ü%óËÏO1L͇Åâ º¥¦–+ZnûlBA×Öêš=sû€Õ¿Ÿ×)Ø17"Ò=íßÏÿ쓃Qó³xò’JÜã7'N9’Ý-¸¯÷¥üË¥MøëÙ]‹âF{uuÉ®-U)~~nÓ óüŸú{ô…]iƒý»»_Hy æxõÄŸ‰>'Ö\ôùgá‘—¤Ž¢*—@‡Âõìªå¶2â z”fUÛ™Ÿç\,vÏL(èÜZ]K¦m“°%eˆo¤[º[°2gçw'Ÿ>ðs|ÐÃúB·Â=~µ‘F§g%¤ô/©R¹ôéâs6·´ÚùÕ{_ñr¶ÏpWÊJ=”yŸþqðU/'û/cü+œ»ê“êúÎ/»Þèâu¢G´güö¸”¾“>^ã±óË¿·û‡ô/èõ&ÞšµSÿP(D:/OûÚÞßûæ¼÷.yþ…è«ál×.‹¾9w®Ð>*ʽæÐÁŒÇFÙýù—Ããžyj½`ÓßICfÎêüÛ¯ñ}<=eWÿükê'g‰ê«/޼~¯õ &²ooúˆ™³ú¬4ïM4MÌž=éý>øð±söÝ?x€ÌÛýì„!”a3ƽ?žþÏË+Ç>4°´,«úÊ'W,¬+oà ¤|CúɼÃ^ëµjôÛ×öf~1üwÙ‘Uçõy²ëŠãk.öóu>ÿêê'v°¹ GV{æ^ë©È«¤Ì4c阯£Æ4ÕiD§6\ê7ø•éöÝ#„nƒ² „çN1/ÈzNü¾öî³ÿ±½;5±Ïe“‰’.3¾ëi'â×ÿ€¤¬âNÛâR‚cüOüº#¾¿‡£]ÆÚ¦ýàé$«ùdõYÙ%ÕÛÏð¨kÔ(-~ék±€g|elLJä¾ÿê~êùiëé!a¾.çV¼óÄ.€Ç"òƾÿûÂŒÂÊM÷Î.¥RT¨PˆtÝ"Ý*&O ÏàóÙ&‰˜W“x±Héå)kllÔɆ l>Dëvá|Q€Šòepˆc†ylò”𬯿{SÜìrC(€Gg§J6Õ>4°ÀÉOÞÄb3ºìsE| Oo2š8±S»4f¾Qniçw¤ ¨¯ltŒÙéˆy¬ûã!GVÝ{î½z*ß(¿çxzÃPÊ &.OÈQýë7‹j3 ~ÈZ4É\:‹ÛcCcb;g0 ¡v"~e¸¿k¶yÌÑ^\QXQçPQÛàîïšl›< kÎÂ5‡ô‰EŠÌ¢J¥“½$ϼ÷NÈç]Òì›·Õåµ ®…u¼è——RJ ¥@X 1\Î.‘?JÁÒÎríˆ8—Ëny;J)…HÏb1úÔ+åŠ~ýý*²²ª”<[ pÔååÍ-D/ÛSJ›OkáòXÚ•®ùªÝ’âúVÛxzÉš€.øtèïÆ•< ·ÙnCn»-?ß–žvÙŠäîvE•ùµJ.ÿÚçÉåsÔ5->£¼K%-—gsXÚ¦: Ïü¼®¼¡ÕÏSîn×èkNZææ\¿ïëßÒª*˜ãë_T95”R¼_/²9x޲ íÙÎ…Ãbn¸¡.‹aZý…*àqšÊjšI&ç”J F×Q&n²ñÕõMš~AÖ6¨›ç y­Vghþeš˜Y|Û^hB§¡w˜÷‰„_Þøüìò™ Ïý:ó³´5ïÌß7Ì*ïqÊ0„úøÊSvîLíQYÙÈMO¯ÇÅåFwê¤LˆŒrO½š^’x±X¦Ó™¿%Ķ\>8Ø)ãlBAgƒÁD2®VŠÏ&´zΞ““DëåeŸöÓ²SCJJ®µÙ1LäØÑ,å×íGée¯¶w‘dûý|Œ¦AËÊ>W$˽Páî’àÕÅùJîÅ’ð’«•bMƒ–ufcrÏ–Ë;8d$Î ¥&Jr.Ëò/—µz¾d§X¯*‰ƒ°dӂê›8Ú&=+õD®¢µù ¥F0hÕ,Àv.ÈFaðCè!‰ òHNÏ/OÍ—ktæûM'úËÄ‚Òè`ÏêÑ1!™M½ô·×Nl_µûl@]ƒÆÉ¼ìîùåµE•uüµ–µj÷ÙÞwØNR\rnï3Wòšƒãá ™N·›o >û|Øæêê&eÿ>?2vôœ¦¯¾¹àýùƒÎzzɲ&?ñçG=»ÿ8ß`0²¹\VsëŽéOu»ØÐ •D„/þì‰ Ìõ÷w¸íU¥ß-½¶¡A+îßç—/zõXúNDøâÏþøý|›Zî;x—Ã2…ùºÔM{¬Ûºo×{ù—í§«\N“·³ýó²#üË=”—†¾õÛÇ Ãb:{¼Ýv>qø‰¾QÙ?óùúùvbA¹Þ`ä xœ†S¯}Ó>ïôß›ûsßpÑü< PÑ™óîk-眽0s¡ùqT”{Í©3¯}“qµR̰²æ_âl6C·nöÏÜÜšDBŽAé(ÖÀ&óxžÕGO¼²$ãj¥ØÏß¡‘¹~€L&зÜn×n®µ‡¾¼¬¢¼›S-v¬—Jù†‡ð²ÓÉîÝÝ‹Êòýå§Ó3:wvújÈõÛ•¡{ãànW;bVïÍ /™*åp–×ÑÿžŸîæ\Ösbh¥kCÝ; ~Y‡Í2õ ñJ ÷sÝ3wù®w,]5ùkýôæž}ýúûU$$ä‡ýñû¹˜!Cÿ±d]ª‘sz7ßv0¸weÊ‘ìÈsÛ¯tÁà‡Ð£ ÏñCÈ|]äMŸÌzfxNE–®Åš &R]Õ¤tr–TYº–GYE^àÂÎ4×uóöõ¬-UyDëœdéšB÷÷øˆÈÊ®IDAT!«@q é÷ª]ôد° jöÊKÿ 7™(룃ã,]Ë£ìøê‹Á§7^ÑX«vêÜßw_øÐÀKׄº?¸ÇY ÐÎÛ¹ foÎÞÑ/!>¿×ÒŸÇýô(Üf­#›ðáÀ ß^žùÙžŸW˜R²êÕmC,]ÓýÒª*˜C+&;Bø–®!KÀà‡¬¥´6´ÿllç‚`îÛ»z<1øÇe/éÑÃÓêoµÖ^Ü:)|"\ RÊ;Yº–ûE©ôêàï?d£ð!dUÞŸ·'fÏî´áß/»¤o?ß K×ó¨;ý÷eOóãœ Å²Ìø‚h¹›ô‘=7•/u6 {})¥ôŽ÷rFÈZá9~YÈûÎûiõ6À‘‹™ÞéöÓë–Åç²M–®íQ¶kgêð¦&½Ý‹ÏoüÐüš¿¿"iï~³d]ª>;üÔºyû¤l.K£Viå.Фç—ÙnéºB÷ƒB²zß¹¡ƒ‰ã¦°Ë8p.#`htàr7…ÞFê_H¼hïíZ³ò<çó¡Öù}j¢À ŠK×µ!”RK×€ÐñÜâFWK×€êøL`lZ=[Zké:²¼¸!„BÈF`ðCVÛ¹ „Bw‡ÁY O$Çv.¡;Ò6U1ÇV?kí\­Â‹;U ”Ö<·¸Q`é:B5衱¶€ØÎÙ(Üã‡BÈf˜Û¹PJ± ²IüB!„l?„B!Á!„BÈF`ðCV¢8¿ëClç‚BÝ?d-LlŽÈdé"B¶sA¶Û¹ «@)­~nq#ßÒu „:6“N 5yÀv.ÈFá?„B6C s7œu¤Û¹ […Á!„BÈF`ðC!„²üB!„l?d!w/Xº„B¨#Ãà‡¬aáEê¡;Ó©kÉñµ/È!\Kׂ%àoJd(¥UÏ-nľ\¡;2jˆªìª8 ³t=µ7Üã‡BÈfdsŽQJ-] B–€Á!„BÈF`ðC!„²üB!„l?d° B!twüÕÀv.¡»Ñ©kIÜ_ÿ±Ãv.ÈVáoJd° B¨-ŒÚR]’"€JÀv.Èá?„B6C s7~3®Û¹ […Á!„BÈF`ðC!„²üB!„l?d!‰ûb;„Bè0ø!«AK—€êà° ²uØÎYlç‚j lç‚lîñC!d3° ²uüB!„l?„B!Á!„BÈF`ðCV"OÚÿ•ØÒu „B?d-ƒ¾¿ŸBw¤S×’Óë_“b;d«° ² ”ÒÊç7âr„Ði5u¤²à‚T¶sA6÷ „²{/Óè·OPJ,] B–€Á!„BÈF`ðC!„²üB!„l?d° B!twüµÀv.¡»ÒiêÉ™M³%ØÎý;÷ÒDpünnn·s³©Yºþ(&id¡%E%EEB õ""_ôBzå«^TjÚ¤à ( }!á¡|±YS›ÔTD]›yËyêÔmº9—·æn¦[/|Ó¼§ØõÒû}Þ~ùÝqpÏ#Vpœ Øà8@<Â!?îïÑ`æÇà8 Bð‡€h¨4ÚÈùÊÞ)8Έ,üD~" ?‘€…Øp×X;ž’¨f35î±nªÙ{ ×÷N䦱¾&Âe3nL³ÂIëÑm Y15¬“£ÚÄ`‹ÂamÜ&‡Zå“_[Ñík«|rHxsXÛäƒ- T›ÖÉ™fÁÍIë™~tsÙ ‰c}M²}ïL´÷6 nî±n™ÍÔ€lÞñ^™íËkåµÏ/‘m~zPJ)ä;O‹Føû œÃRÚH‘‘e_ßçFh#E.s¬ Æzì ´‘"ÃK>Þ÷Ÿõ2k-àÔ~‡„6R$ÇÎòÇÎJh#EüA-ðJh#E²^&×–|kÍcçµeŽÅi#E.Îüµy¯ °«lÊ)ËûPá™Ê…õÁúññޤTm(óN¯™?ÖjIÕ6.kï)D{”Iiá¬üÓ‚ÚP{M&¡Lý¥-8ÇŸÓ×m—*È•]ûËø­½f»$XÝ]xA`«ÎÀp<š}ð2â~5[±hÏ.ØtÕ["«!iNñUÄóÝO_ႲÜC×5³®fshÉ'Ë-AÌ餅‚ó²=Gn æªRƒ—<ïh¹°¦¯JùésùÇn:×·ý=MÀÃ(óßâÍý« ~x¸éÇì72ÿÄí™õÍò¡Zí6« NVL iVÕÇѧÚYxa&)EmuI³&UFV‘3-§$sMÃ3Òe7¨ M–;ûÀÅ•x›µû™rfX§–*“Üy%å1mô E0æwꨛÛWZ±o³~¥°¼M^áXOaÙÝpLëy#éiH±noñ¥Z.Þ6bnI´vÕ'ýÌüáËÏC1sßÚ¤–®úä/í;~åÅÒŸmrô“ÔÒU¿i~ƲPz½!ˆjêôœU ;‹ F¿f‘1¥EtåIEND®B`‚openchange-2.0/apidocs/html/mapiproxy/nav_f.png000066400000000000000000000002311223057412600216750ustar00rootroot00000000000000‰PNG  IHDR8³»`IDATxíÝK€ EÑ–·[†øBÑmkâÄÂH—prÓ¼.‚Žó‚ꎤR6Z VI±E‚5j³„lóš›iI˜¬ÞêçJ0ŒÑÑ/Žû›™uøñóÞ¿6sH ÝõyIEND®B`‚openchange-2.0/apidocs/html/mapiproxy/nav_g.png000066400000000000000000000001371223057412600217030ustar00rootroot00000000000000‰PNG  IHDRô1&IDATxíÝ1 ÁOHf„á_ ->~¸åM iËMèÀƒS½ü‚<IEND®B`‚openchange-2.0/apidocs/html/mapiproxy/nav_h.png000066400000000000000000000001421223057412600217000ustar00rootroot00000000000000‰PNG  IHDR ,é@)IDATxíÝA @BQ­³šÛ›Ð¢Žáà) )ëý éaÅèÜ¿Æo‡RlÐßIEND®B`‚openchange-2.0/apidocs/html/mapiproxy/nav_tab.gif000066400000000000000000000014541223057412600222070ustar00rootroot00000000000000GIF89aPæïïïþþþýþýûüúõ÷óñôïøú÷ýýüúûù÷ùöôöòöøõïóíðôîóöñùúøüýûòõðïòìîòëíñëòõïõõõÿÿÿúúúîòìðóîêëéðððôôôñññýýýñôðÆÉÅìîëÇÊÆÈÊÆÏÏÎÇÊÅËÍÊêìéïóîçèæÎÏÍÐÐÐõ÷ôÊÍÉïñíÆÈÄÊÌÊêêéïóìüýüÊËÉÏÏÏèêçÕ×ÓüüûÍÎÌëíêÌÍËíñêÏÐÏùûøêëêòöðóõñÉÊÇñôîîñì!ù,Pÿ€ˆ‰Š‹ŒŽ‘ˆ‚@;/Ÿ ¡¢£¤¥¦§¨E(ƒ )·¸¹º»¼½¾¿À¸ 7„23ËÌÍÎÏÐÑÒÓÔÐ=*"DÝÞßàáâãäåæä8 îïðñòóôõö÷õ.A þÿ H° ÁƒM R ¡Ã‡#JœH±¢ÅŠ0)ˆÀ±£Ç CŠI²$Ɉ8Xɲ¥Ë—0cÊœIsæD-èÜɳ§ÏŸ@ƒ *”¢’*]Ê´©Ó§P£J:Q‚X³jÝʵ«×¯`­È@‚³hÓª]˶­Û·p‰ßÆ@ôÀݻxóêÝË·¯ß¿~O Bð °áÈ+^̸±ãÆ< @@¹²å˘3kÞ̹3gˆr Mº´éÓ¨S«^Ízõ D4 ÈžM»¶íÛ¸sëÞ­»¢Àƒ N¼¸ñãÈ“'·H€óçУKŸN½ºõë×} À½»÷ïàËO¾|y;openchange-2.0/apidocs/html/mapiproxy/open.png000066400000000000000000000001731223057412600215520ustar00rootroot00000000000000‰PNG  IHDR à‘BIDATxíÝÁ €0 Ð׬ՙ\Àº€39—b!©9{|ðI>$#Àß´ý8/¨ÄØzƒ/Ï>2À[ÎgiU,/¬~¼Ï\ Ä9Ù¸IEND®B`‚openchange-2.0/apidocs/html/mapiproxy/openchangedb_8c.html000066400000000000000000002464241223057412600240130ustar00rootroot00000000000000 MAPIProxy 2.0 API Documentation
openchangedb.c File Reference

OpenChange Dispatcher database routines. More...

#include <inttypes.h>
#include "mapiproxy/dcesrv_mapiproxy.h"
#include "mapiproxy/libmapiproxy/libmapiproxy.h"
#include "libmapi/libmapi.h"
#include "libmapi/libmapi_private.h"

Functions

_PUBLIC_ enum MAPISTATUS openchangedb_create_folder (struct ldb_context *ldb_ctx, uint64_t parentFolderID, uint64_t fid, uint64_t changeNumber, const char *MAPIStoreURI, int systemIdx)
_PUBLIC_ enum MAPISTATUS openchangedb_create_mailbox (struct ldb_context *ldb_ctx, const char *username, int systemIdx, uint64_t *fidp)
_PUBLIC_ enum MAPISTATUS openchangedb_get_distinguishedName (TALLOC_CTX *parent_ctx, struct ldb_context *ldb_ctx, uint64_t fid, char **distinguishedName)
_PUBLIC_ enum MAPISTATUS openchangedb_get_fid (struct ldb_context *ldb_ctx, const char *mapistoreURL, uint64_t *fidp)
_PUBLIC_ enum MAPISTATUS openchangedb_get_fid_by_name (struct ldb_context *ldb_ctx, uint64_t parent_fid, const char *foldername, uint64_t *fid)
_PUBLIC_ enum MAPISTATUS openchangedb_get_folder_count (struct ldb_context *ldb_ctx, uint64_t fid, uint32_t *RowCount)
_PUBLIC_ enum MAPISTATUS openchangedb_get_folder_property (TALLOC_CTX *parent_ctx, struct ldb_context *ldb_ctx, uint32_t proptag, uint64_t fid, void **data)
_PUBLIC_ enum MAPISTATUS openchangedb_get_mailboxDN (TALLOC_CTX *parent_ctx, struct ldb_context *ldb_ctx, uint64_t fid, char **mailboxDN)
_PUBLIC_ enum MAPISTATUS openchangedb_get_MailboxGuid (struct ldb_context *ldb_ctx, const char *recipient, struct GUID *MailboxGUID)
_PUBLIC_ enum MAPISTATUS openchangedb_get_MailboxReplica (struct ldb_context *ldb_ctx, const char *recipient, uint16_t *ReplID, struct GUID *ReplGUID)
_PUBLIC_ enum MAPISTATUS openchangedb_get_mapistoreURI (TALLOC_CTX *parent_ctx, struct ldb_context *ldb_ctx, uint64_t fid, char **mapistoreURL, bool mailboxstore)
_PUBLIC_ enum MAPISTATUS openchangedb_get_MAPIStoreURIs (struct ldb_context *ldb_ctx, const char *username, TALLOC_CTX *mem_ctx, struct StringArrayW_r **urisP)
_PUBLIC_ enum MAPISTATUS openchangedb_get_message_count (struct ldb_context *ldb_ctx, uint64_t fid, uint32_t *RowCount, bool fai)
_PUBLIC_ enum MAPISTATUS openchangedb_get_mid_by_subject (struct ldb_context *ldb_ctx, uint64_t parent_fid, const char *subject, bool mailboxstore, uint64_t *mid)
_PUBLIC_ enum MAPISTATUS openchangedb_get_new_changeNumber (struct ldb_context *ldb_ctx, uint64_t *cn)
_PUBLIC_ enum MAPISTATUS openchangedb_get_new_changeNumbers (struct ldb_context *ldb_ctx, TALLOC_CTX *mem_ctx, uint64_t max, struct UI8Array_r **cns_p)
_PUBLIC_ enum MAPISTATUS openchangedb_get_new_folderID (struct ldb_context *ldb_ctx, uint64_t *fid)
_PUBLIC_ enum MAPISTATUS openchangedb_get_new_folderIDs (struct ldb_context *ldb_ctx, TALLOC_CTX *mem_ctx, uint64_t max, struct UI8Array_r **fids_p)
_PUBLIC_ enum MAPISTATUS openchangedb_get_next_changeNumber (struct ldb_context *ldb_ctx, uint64_t *cn)
_PUBLIC_ enum MAPISTATUS openchangedb_get_parent_fid (struct ldb_context *ldb_ctx, uint64_t fid, uint64_t *parent_fidp, bool mailboxstore)
void * openchangedb_get_property_data (TALLOC_CTX *mem_ctx, struct ldb_result *res, uint32_t pos, uint32_t proptag, const char *PidTagAttr)
void * openchangedb_get_property_data_message (TALLOC_CTX *mem_ctx, struct ldb_message *msg, uint32_t proptag, const char *PidTagAttr)
_PUBLIC_ enum MAPISTATUS openchangedb_get_PublicFolderID (struct ldb_context *ldb_ctx, uint32_t SystemIdx, uint64_t *FolderId)
_PUBLIC_ enum MAPISTATUS openchangedb_get_PublicFolderReplica (struct ldb_context *ldb_ctx, uint16_t *ReplID, struct GUID *ReplGUID)
_PUBLIC_ enum MAPISTATUS openchangedb_get_ReceiveFolder (TALLOC_CTX *parent_ctx, struct ldb_context *ldb_ctx, const char *recipient, const char *MessageClass, uint64_t *fid, const char **ExplicitMessageClass)
void * openchangedb_get_special_property (TALLOC_CTX *mem_ctx, struct ldb_context *ldb_ctx, struct ldb_result *res, uint32_t proptag, const char *PidTagAttr)
_PUBLIC_ enum MAPISTATUS openchangedb_get_system_idx (struct ldb_context *ldb_ctx, uint64_t fid, int *system_idx_p)
_PUBLIC_ enum MAPISTATUS openchangedb_get_SystemFolderID (struct ldb_context *ldb_ctx, const char *recipient, uint32_t SystemIdx, uint64_t *FolderId)
_PUBLIC_ enum MAPISTATUS openchangedb_get_table_property (TALLOC_CTX *parent_ctx, struct ldb_context *ldb_ctx, const char *ldb_filter, uint32_t proptag, uint32_t pos, void **data)
_PUBLIC_ enum MAPISTATUS openchangedb_get_TransportFolder (struct ldb_context *ldb_ctx, const char *recipient, uint64_t *FolderId)
_PUBLIC_ enum MAPISTATUS openchangedb_lookup_folder_property (struct ldb_context *ldb_ctx, uint32_t proptag, uint64_t fid)
_PUBLIC_ enum MAPISTATUS openchangedb_reserve_fmid_range (struct ldb_context *ldb_ctx, uint64_t range_len, uint64_t *first_fmidp)
_PUBLIC_ char * openchangedb_set_folder_property_data (TALLOC_CTX *mem_ctx, struct SPropValue *value)
_PUBLIC_ enum MAPISTATUS openchangedb_set_mapistoreURI (struct ldb_context *ldb_ctx, uint64_t fid, const char *mapistoreURL, bool mailboxstore)
_PUBLIC_ enum MAPISTATUS openchangedb_set_ReceiveFolder (struct ldb_context *ldb_ctx, const char *recipient, const char *MessageClass, uint64_t fid)

Detailed Description

OpenChange Dispatcher database routines.

Function Documentation

_PUBLIC_ enum MAPISTATUS openchangedb_create_folder ( struct ldb_context *  ldb_ctx,
uint64_t  parentFolderID,
uint64_t  fid,
uint64_t  changeNumber,
const char *  MAPIStoreURI,
int  systemIdx 
)

Create a folder in openchangedb

Parameters
ldb_ctxpointer to the openchangedb LDB context
parentFolderIDthe FID of the parent folder
fidthe FID of the folder to create
MAPIStoreURIthe mapistore URI to associate to this folder
nt_timethe creation time of the folder
changeNumberthe change number
Returns
MAPISTORE_SUCCESS on success, otherwise MAPISTORE error

References openchangedb_get_distinguishedName(), and openchangedb_get_mailboxDN().

Referenced by emsmdbp_mailbox_provision().

_PUBLIC_ enum MAPISTATUS openchangedb_create_mailbox ( struct ldb_context *  ldb_ctx,
const char *  username,
int  systemIdx,
uint64_t *  fidp 
)

Create a folder in openchangedb

Parameters
ldb_ctxpointer to the openchangedb LDB context
usernamethe owner of the mailbox
systemIdxthe id of the mailbox
fidpa pointer to the fid of the mailbox
Returns
MAPISTORE_SUCCESS on success, otherwise MAPISTORE error

References openchangedb_get_new_changeNumber(), and openchangedb_get_new_folderID().

Referenced by emsmdbp_mailbox_provision().

_PUBLIC_ enum MAPISTATUS openchangedb_get_distinguishedName ( TALLOC_CTX *  parent_ctx,
struct ldb_context *  ldb_ctx,
uint64_t  fid,
char **  distinguishedName 
)

Retrieve the distinguishedName associated to a mailbox system folder.

Parameters
parent_ctxpointer to the parent memory context
ldb_ctxpointer to the openchange LDB context
fidthe Folder identifier to search for
distinguishedNamepointer on pointer to the distinguishedName string the function returns
Returns
MAPI_E_SUCCESS on success, otherwise MAPI_E_NOT_FOUND

Referenced by openchangedb_create_folder(), openchangedb_message_create(), and openchangedb_set_ReceiveFolder().

_PUBLIC_ enum MAPISTATUS openchangedb_get_fid ( struct ldb_context *  ldb_ctx,
const char *  mapistoreURL,
uint64_t *  fidp 
)

Retrieve the fid associated with a mapistore URI.

Parameters
ldb_ctxpointer to the openchange LDB context
fidthe Folder identifier to search for
mapistoreURLpointer on pointer to the mapistore URI the function returns
mailboxstoreboolean value which defines whether the record has to be searched within Public folders hierarchy or not
Returns
MAPI_E_SUCCESS on success, otherwise MAPI_E_NOT_FOUND

Referenced by emsmdbp_mailbox_provision().

_PUBLIC_ enum MAPISTATUS openchangedb_get_fid_by_name ( struct ldb_context *  ldb_ctx,
uint64_t  parent_fid,
const char *  foldername,
uint64_t *  fid 
)

Retrieve the folder ID associated with a given folder name

This function looks up the specified foldername (as a PidTagDisplayName) and returns the associated folder ID. Note that folder names are only unique in the context of a parent folder, so the parent folder needs to be provided.

Parameters
ldb_ctxpointer to the openchange LDB context
parent_fidthe folder ID of the parent folder
foldernamethe name to look up
fidthe folder ID for the folder with the specified name (0 if not found)
Returns
MAPI_E_SUCCESS on success, otherwise MAPI_E_NOT_FOUND

Referenced by emsmdbp_mailbox_provision().

_PUBLIC_ enum MAPISTATUS openchangedb_get_folder_count ( struct ldb_context *  ldb_ctx,
uint64_t  fid,
uint32_t *  RowCount 
)

Retrieve the number of sub folders for a given fid

Parameters
ldb_ctxpointer to the openchange LDB context
fidthe folder identifier to use for the search
RowCountpointer to the returned number of results
Returns
MAPI_E_SUCCESS on success, otherwise MAPI_E_NOT_FOUND
_PUBLIC_ enum MAPISTATUS openchangedb_get_folder_property ( TALLOC_CTX *  parent_ctx,
struct ldb_context *  ldb_ctx,
uint32_t  proptag,
uint64_t  fid,
void **  data 
)

Retrieve a MAPI property value from a folder record

Parameters
parent_ctxpointer to the memory context
ldb_ctxpointer to the openchange LDB context
proptagthe MAPI property tag to retrieve value for
fidthe record folder identifier
datapointer on pointer to the data the function returns
Returns
MAPI_E_SUCCESS on success, otherwise MAPI_E_NOT_FOUND

References openchangedb_get_property_data(), and openchangedb_get_special_property().

Referenced by emsmdbp_mailbox_provision().

_PUBLIC_ enum MAPISTATUS openchangedb_get_mailboxDN ( TALLOC_CTX *  parent_ctx,
struct ldb_context *  ldb_ctx,
uint64_t  fid,
char **  mailboxDN 
)

Retrieve the mailboxDN associated to a mailbox system folder.

Parameters
parent_ctxpointer to the parent memory context
ldb_ctxpointer to the openchange LDB context
fidthe folder identifier to search for
mailboxDNpointer on pointer to the mailboxDN string the function returns
Returns
MAPI_E_SUCCESS on success, otherwise MAPI_E_NOT_FOUND

Referenced by openchangedb_create_folder(), and openchangedb_message_create().

_PUBLIC_ enum MAPISTATUS openchangedb_get_MailboxGuid ( struct ldb_context *  ldb_ctx,
const char *  recipient,
struct GUID *  MailboxGUID 
)

Retrieve the mailbox GUID for given recipient from openchange dispatcher database

Parameters
ldb_ctxpointer to the OpenChange LDB context
recipientthe mailbox username
MailboxGUIDpointer to the mailbox GUID the function returns
Returns
MAPI_E_SUCCESS on success, otherwise MAPI error

Referenced by emsmdbp_mailbox_provision(), and RopLogon_Mailbox().

_PUBLIC_ enum MAPISTATUS openchangedb_get_MailboxReplica ( struct ldb_context *  ldb_ctx,
const char *  recipient,
uint16_t *  ReplID,
struct GUID *  ReplGUID 
)

Retrieve the mailbox replica identifier and GUID for given recipient from openchange dispatcher database

Parameters
ldb_ctxpointer to the OpenChange LDB context
recipientthe mailbox username
ReplIDpointer to the replica identifier the function returns
ReplGUIDpointer to the replica GUID the function returns
Returns
MAPI_E_SUCCESS on success, otherwise MAPI error

Referenced by EcDoRpc_RopSyncImportDeletes(), EcDoRpc_RopSyncImportHierarchyChange(), EcDoRpc_RopSyncImportMessageChange(), emsmdbp_mailbox_provision(), emsmdbp_object_synccontext_init(), emsmdbp_verify_user(), and RopLogon_Mailbox().

_PUBLIC_ enum MAPISTATUS openchangedb_get_mapistoreURI ( TALLOC_CTX *  parent_ctx,
struct ldb_context *  ldb_ctx,
uint64_t  fid,
char **  mapistoreURL,
bool  mailboxstore 
)

Retrieve the mapistore URI associated to a mailbox system folder.

Parameters
parent_ctxpointer to the memory context
ldb_ctxpointer to the openchange LDB context
fidthe Folder identifier to search for
mapistoreURLpointer on pointer to the mapistore URI the function returns
ownerpointer on pointer to the owner of the parent mailbox
mailboxstoreboolean value which defines whether the record has to be searched within Public folders hierarchy or not
Returns
MAPI_E_SUCCESS on success, otherwise MAPI_E_NOT_FOUND

Referenced by emsmdbp_mailbox_provision().

_PUBLIC_ enum MAPISTATUS openchangedb_get_MAPIStoreURIs ( struct ldb_context *  ldb_ctx,
const char *  username,
TALLOC_CTX *  mem_ctx,
struct StringArrayW_r **  urisP 
)

Retrieve a list of mapistore URI in use for a certain user

Parameters
ldb_ctxpointer to the openchange LDB context
fidthe Folder identifier to search for
mapistoreURLpointer on pointer to the mapistore URI the function returns
mailboxstoreboolean value which defines whether the record has to be searched within Public folders hierarchy or not
Returns
MAPI_E_SUCCESS on success, otherwise MAPI_E_NOT_FOUND

Referenced by emsmdbp_mailbox_provision().

_PUBLIC_ enum MAPISTATUS openchangedb_get_message_count ( struct ldb_context *  ldb_ctx,
uint64_t  fid,
uint32_t *  RowCount,
bool  fai 
)

Retrieve the number of messages within the specified folder

Parameters
ldb_ctxpointer to the openchange LDB context
fidthe folder identifier to use for the search
RowCountpointer to the returned number of results
Returns
MAPI_E_SUCCESS on success, otherwise MAPI_E_NOT_FOUND
_PUBLIC_ enum MAPISTATUS openchangedb_get_mid_by_subject ( struct ldb_context *  ldb_ctx,
uint64_t  parent_fid,
const char *  subject,
bool  mailboxstore,
uint64_t *  mid 
)

Retrieve the message ID associated with a given subject (normalized)

Parameters
ldb_ctxpointer to the openchange LDB context
parent_fidthe folder ID of the parent folder
subjectthe normalized subject to look up
midthe message ID for the message (0 if not found)
Returns
MAPI_E_SUCCESS on success, otherwise MAPI_E_NOT_FOUND
_PUBLIC_ enum MAPISTATUS openchangedb_get_new_changeNumber ( struct ldb_context *  ldb_ctx,
uint64_t *  cn 
)

Allocates a new change number and returns it

Parameters
ldb_ctxpointer to the openchange LDB context
cnpointer to the cn value the function returns
Returns
MAPI_E_SUCCESS on success, otherwise MAPI error

Referenced by EcDoRpc_RopCreateFolder(), EcDoRpc_RopSyncImportHierarchyChange(), emsmdbp_mailbox_provision(), and openchangedb_create_mailbox().

_PUBLIC_ enum MAPISTATUS openchangedb_get_new_changeNumbers ( struct ldb_context *  ldb_ctx,
TALLOC_CTX *  mem_ctx,
uint64_t  max,
struct UI8Array_r **  cns_p 
)

Allocates a batch of new change numbers and returns them

Parameters
ldb_ctxpointer to the openchange LDB context
cnpointer to the cn value the function returns
Returns
MAPI_E_SUCCESS on success, otherwise MAPI error
_PUBLIC_ enum MAPISTATUS openchangedb_get_new_folderID ( struct ldb_context *  ldb_ctx,
uint64_t *  fid 
)

Allocates a new FolderID and returns it

Parameters
ldb_ctxpointer to the openchange LDB context
fidpointer to the fid value the function returns
Returns
MAPI_E_SUCCESS on success, otherwise MAPI error

Referenced by EcDoRpc_RopCreateFolder(), EcDoRpc_RopCreateMessage(), EcDoRpc_RopOpenEmbeddedMessage(), emsmdbp_mailbox_provision(), and openchangedb_create_mailbox().

_PUBLIC_ enum MAPISTATUS openchangedb_get_new_folderIDs ( struct ldb_context *  ldb_ctx,
TALLOC_CTX *  mem_ctx,
uint64_t  max,
struct UI8Array_r **  fids_p 
)

Allocates a batch of new folder ids and returns them

Parameters
ldb_ctxpointer to the openchange LDB context
fidpointer to the fid value the function returns
Returns
MAPI_E_SUCCESS on success, otherwise MAPI error
_PUBLIC_ enum MAPISTATUS openchangedb_get_next_changeNumber ( struct ldb_context *  ldb_ctx,
uint64_t *  cn 
)

Returns the change number that will be allocated when openchangedb_get_new_changeNumber is next invoked

Parameters
ldb_ctxpointer to the openchange LDB context
cnpointer to the cn value the function returns
Returns
MAPI_E_SUCCESS on success, otherwise MAPI error
_PUBLIC_ enum MAPISTATUS openchangedb_get_parent_fid ( struct ldb_context *  ldb_ctx,
uint64_t  fid,
uint64_t *  parent_fidp,
bool  mailboxstore 
)

Retrieve the parent fid associated to a mailbox system folder.

Parameters
ldb_ctxpointer to the openchange LDB context
fidthe Folder identifier to search for
parent_fidppointer to the parent_fid the function returns
mailboxstoreboolean value which defines whether the record has to be searched within Public folders hierarchy or not
Returns
MAPI_E_SUCCESS on success, otherwise MAPI_E_NOT_FOUND
void* openchangedb_get_property_data ( TALLOC_CTX *  mem_ctx,
struct ldb_result *  res,
uint32_t  pos,
uint32_t  proptag,
const char *  PidTagAttr 
)

Retrieve a MAPI property from a OpenChange LDB result set

Parameters
mem_ctxpointer to the memory context
respointer to the LDB results
posthe LDB result index
proptagthe MAPI property tag to lookup
PidTagAttrthe mapped MAPI property name
Returns
valid data pointer on success, otherwise NULL

References openchangedb_get_property_data_message().

Referenced by openchangedb_get_folder_property(), and openchangedb_get_table_property().

void* openchangedb_get_property_data_message ( TALLOC_CTX *  mem_ctx,
struct ldb_message *  msg,
uint32_t  proptag,
const char *  PidTagAttr 
)

Retrieve a MAPI property from an OpenChange LDB message

Parameters
mem_ctxpointer to the memory context
msgpointer to the LDB message
proptagthe MAPI property tag to lookup
PidTagAttrthe mapped MAPI property name
Returns
valid data pointer on success, otherwise NULL

Referenced by openchangedb_get_property_data(), and openchangedb_message_get_property().

_PUBLIC_ enum MAPISTATUS openchangedb_get_PublicFolderID ( struct ldb_context *  ldb_ctx,
uint32_t  SystemIdx,
uint64_t *  FolderId 
)

Retrieve the public folder FolderID (fid) for a given folder type

Parameters
ldb_ctxpointer to the OpenChange LDB context
SystemIdxthe system folder index
FolderIdpointer to the folder identifier the function returns
Returns
MAPI_E_SUCCESS on success, otherwise MAPI error

Referenced by emsmdbp_object_mailbox_init(), and RopLogon_PublicFolder().

_PUBLIC_ enum MAPISTATUS openchangedb_get_PublicFolderReplica ( struct ldb_context *  ldb_ctx,
uint16_t *  ReplID,
struct GUID *  ReplGUID 
)

Retrieve the public folder replica identifier and GUID from the openchange dispatcher database

Parameters
ldb_ctxpointer to the OpenChange LDB context
ReplIDpointer to the replica identifier the function returns
ReplGUIDpointer to the replica GUID the function returns
Returns
MAPI_E_SUCCESS on success, otherwise MAPI error

Referenced by RopLogon_PublicFolder().

_PUBLIC_ enum MAPISTATUS openchangedb_get_ReceiveFolder ( TALLOC_CTX *  parent_ctx,
struct ldb_context *  ldb_ctx,
const char *  recipient,
const char *  MessageClass,
uint64_t *  fid,
const char **  ExplicitMessageClass 
)

Retrieve the Explicit message class and Folder identifier associated to the MessageClass search pattern.

Parameters
parent_ctxpointer to the memory context
ldb_ctxpointer to the openchange LDB context
recipientpointer to the mailbox's username
MessageClasssubstring to search for
fidpointer to the folder identifier the function returns
ExplicitMessageClasspointer on pointer to the complete message class the function returns
Returns
MAPI_E_SUCCESS on success, otherwise MAPI_E_NOT_FOUND

Referenced by RopGetReceiveFolder().

void* openchangedb_get_special_property ( TALLOC_CTX *  mem_ctx,
struct ldb_context *  ldb_ctx,
struct ldb_result *  res,
uint32_t  proptag,
const char *  PidTagAttr 
)

Retrieve a special MAPI property from an openchangedb record

Parameters
mem_ctxpointer to the memory context
ldb_ctxpointer to the OpenChange LDB context
respointer to the LDB result
proptagthe MAPI property tag to lookup
PidTagAttrthe mapped MAPI property name
Returns
pointer to valid data on success, otherwise NULL

Referenced by openchangedb_get_folder_property(), and openchangedb_get_table_property().

_PUBLIC_ enum MAPISTATUS openchangedb_get_system_idx ( struct ldb_context *  ldb_ctx,
uint64_t  fid,
int *  system_idx_p 
)

Retrieve the system idx associated with a folder record

Parameters
ldb_ctxpointer to the openchange LDB context
fidthe folder identifier to use for the search
system_idx_ppointer to the returned value
Returns
MAPI_E_SUCCESS on success, otherwise MAPI_E_NOT_FOUND
_PUBLIC_ enum MAPISTATUS openchangedb_get_SystemFolderID ( struct ldb_context *  ldb_ctx,
const char *  recipient,
uint32_t  SystemIdx,
uint64_t *  FolderId 
)

Retrieve the mailbox FolderID for given recipient from openchange dispatcher database

Parameters
ldb_ctxpointer to the OpenChange LDB context
recipientthe mailbox username
SystemIdxthe system folder index
FolderIdpointer to the folder identifier the function returns
Returns
MAPI_E_SUCCESS on success, otherwise MAPI error

Referenced by emsmdbp_mailbox_provision(), emsmdbp_object_mailbox_init(), and RopLogon_Mailbox().

_PUBLIC_ enum MAPISTATUS openchangedb_get_table_property ( TALLOC_CTX *  parent_ctx,
struct ldb_context *  ldb_ctx,
const char *  ldb_filter,
uint32_t  proptag,
uint32_t  pos,
void **  data 
)

Retrieve a MAPI property from a table (ldb search results)

Parameters
parent_ctxpointer to the memory context
ldb_ctxpointer to the openchange LDB context
ldb_filterthe ldb search string
proptagthe MAPI property tag to retrieve value for
posthe record position in search results
datapointer on pointer to the data the function returns
Returns
MAPI_E_SUCCESS on success, otherwise MAPI_E_NOT_FOUND

References openchangedb_get_property_data(), and openchangedb_get_special_property().

_PUBLIC_ enum MAPISTATUS openchangedb_get_TransportFolder ( struct ldb_context *  ldb_ctx,
const char *  recipient,
uint64_t *  FolderId 
)

Retrieve the Transport Folder FolderID for given recipient from openchange dispatcher database

Parameters
ldb_ctxpointer to the OpenChange LDB context
recipientthe mailbox username
FolderIdpointer to the folder identifier the function returns
Returns
MAPI_E_SUCCESS on success, otherwise MAPI error

Referenced by EcDoRpc_RopGetTransportFolder().

_PUBLIC_ enum MAPISTATUS openchangedb_lookup_folder_property ( struct ldb_context *  ldb_ctx,
uint32_t  proptag,
uint64_t  fid 
)

Check if a property exists within an openchange dispatcher database record

Parameters
ldb_ctxpointer to the openchange LDB context
proptagthe MAPI property tag to lookup
fidthe record folder identifier
Returns
MAPI_E_SUCCESS on success, otherwise MAPI_E_NOT_FOUND
_PUBLIC_ enum MAPISTATUS openchangedb_reserve_fmid_range ( struct ldb_context *  ldb_ctx,
uint64_t  range_len,
uint64_t *  first_fmidp 
)

Reserve a range of FMID

Parameters
ldb_ctxpointer to the openchange LDB context
fidpointer to the fid value the function returns
Returns
MAPI_E_SUCCESS on success, otherwise MAPI error

Referenced by EcDoRpc_RopGetLocalReplicaIds().

_PUBLIC_ char* openchangedb_set_folder_property_data ( TALLOC_CTX *  mem_ctx,
struct SPropValue *  value 
)

Build a MAPI property suitable for a OpenChange LDB message

Parameters
mem_ctxpointer to the memory context
valuethe MAPI property
Returns
valid string pointer on success, otherwise NULL

Referenced by openchangedb_message_set_properties().

_PUBLIC_ enum MAPISTATUS openchangedb_set_mapistoreURI ( struct ldb_context *  ldb_ctx,
uint64_t  fid,
const char *  mapistoreURL,
bool  mailboxstore 
)

Store the mapistore URI associated to a mailbox system folder.

Parameters
parent_ctxpointer to the memory context
ldb_ctxpointer to the openchange LDB context
fidthe Folder identifier to search for
mapistoreURLpointer on pointer to the mapistore URI the function returns
ownerpointer on pointer to the owner of the parent mailbox
mailboxstoreboolean value which defines whether the record has to be searched within Public folders hierarchy or not
Returns
MAPI_E_SUCCESS on success, otherwise MAPI_E_NOT_FOUND
_PUBLIC_ enum MAPISTATUS openchangedb_set_ReceiveFolder ( struct ldb_context *  ldb_ctx,
const char *  recipient,
const char *  MessageClass,
uint64_t  fid 
)

Set the receive folder for a specific message class.

Parameters
parent_ctxpointer to the memory context
ldb_ctxpointer to the openchange LDB context
recipientpointer to the mailbox's username
MessageClassmessage class (e.g. IPM.whatever) to set
fidfolder identifier for the recipient folder for the message class
Returns
MAPI_E_SUCCESS on success, otherwise MAPI_E_NOT_FOUND

References openchangedb_get_distinguishedName().

Referenced by emsmdbp_mailbox_provision(), and RopSetReceiveFolder().


Creative Commons License
Creative Commons Attribution icon Creative Commons Share Alike icon
This content is licensed under the Creative Commons
Attribution ShareAlike License v. 3.0:
http://creativecommons.org/licenses/by-sa/3.0/

openchange-2.0/apidocs/html/mapiproxy/openchangedb__message_8c.html000066400000000000000000000352171223057412600256520ustar00rootroot00000000000000 MAPIProxy 2.0 API Documentation
openchangedb_message.c File Reference

OpenChange Dispatcher database message routines. More...

#include <inttypes.h>
#include "mapiproxy/dcesrv_mapiproxy.h"
#include "mapiproxy/libmapistore/mapistore.h"
#include "libmapiproxy.h"
#include "libmapi/libmapi_private.h"

Functions

_PUBLIC_ enum MAPISTATUS openchangedb_message_create (TALLOC_CTX *mem_ctx, struct ldb_context *ldb_ctx, uint64_t messageID, uint64_t folderID, bool fai, void **message_object)
_PUBLIC_ enum MAPISTATUS openchangedb_message_get_property (TALLOC_CTX *mem_ctx, void *message_object, uint32_t proptag, void **data)
_PUBLIC_ enum MAPISTATUS openchangedb_message_open (TALLOC_CTX *mem_ctx, struct ldb_context *ldb_ctx, uint64_t messageID, uint64_t folderID, void **message_object, void **msgp)
_PUBLIC_ enum MAPISTATUS openchangedb_message_save (void *_msg, uint8_t SaveFlags)
_PUBLIC_ enum MAPISTATUS openchangedb_message_set_properties (TALLOC_CTX *mem_ctx, void *message_object, struct SRow *row)

Detailed Description

OpenChange Dispatcher database message routines.

Function Documentation

_PUBLIC_ enum MAPISTATUS openchangedb_message_create ( TALLOC_CTX *  mem_ctx,
struct ldb_context *  ldb_ctx,
uint64_t  messageID,
uint64_t  folderID,
bool  fai,
void **  message_object 
)

Initialize and create a message object

Parameters
mem_ctxpointer to the memory context to use for allocation
ldb_ctxpointer to the ldb context
messageIDthe identifier of the message to create
folderIDthe identifier of the folder where the message is created
message_objectpointer on pointer to the message object to return
Returns
MAPI_E_SUCCESS on success, otherwise MAPI error

References openchangedb_get_distinguishedName(), and openchangedb_get_mailboxDN().

Referenced by EcDoRpc_RopCreateMessage().

_PUBLIC_ enum MAPISTATUS openchangedb_message_get_property ( TALLOC_CTX *  mem_ctx,
void *  message_object,
uint32_t  proptag,
void **  data 
)

Retrieve a property on a LDB message

Parameters
mem_ctxpointer to the memory context
message_objectthe openchangedb message to retrieve data from
proptagthe MAPI property tag to lookup
datapointer on pointer to the data to return
Returns
MAPI_E_SUCCESS on success, otherwise MAPI error

References openchangedb_get_property_data_message().

_PUBLIC_ enum MAPISTATUS openchangedb_message_open ( TALLOC_CTX *  mem_ctx,
struct ldb_context *  ldb_ctx,
uint64_t  messageID,
uint64_t  folderID,
void **  message_object,
void **  msgp 
)

Initialize and open a message object

Parameters
mem_ctxpointer to the memory context to use for allocation
ldb_ctxpointer to the ldb context
messageIDthe identifier of the message to open
folderIDthe identifier of the folder where the message is stored
message_objectpointer on pointer to the message object to return
msgppointer on pointer to the mapistore message to return
Returns
MAPI_E_SUCCESS on success, otherwise MAPISTORE error
_PUBLIC_ enum MAPISTATUS openchangedb_message_save ( void *  _msg,
uint8_t  SaveFlags 
)

Save (commit) message in openchangedb database

Parameters
msgthe message object
SaveFlagsflags associated to the save operation
Returns
MAPI_E_SUCCESS on success, otherwise MAPI error

Referenced by EcDoRpc_RopSaveChangesMessage().

_PUBLIC_ enum MAPISTATUS openchangedb_message_set_properties ( TALLOC_CTX *  mem_ctx,
void *  message_object,
struct SRow *  row 
)

Set a list of properties on a message

Parameters
mem_ctxpointer to the memory context
message_objectpointer to the openchangedb message object
rowpointer to the SRow structure holding the array of properties to set on the message
Returns
MAPI_E_SUCCESS on success, otherwise MAPI errors.

References openchangedb_set_folder_property_data().


Creative Commons License
Creative Commons Attribution icon Creative Commons Share Alike icon
This content is licensed under the Creative Commons
Attribution ShareAlike License v. 3.0:
http://creativecommons.org/licenses/by-sa/3.0/

openchange-2.0/apidocs/html/mapiproxy/openchangedb__table_8c.html000066400000000000000000000160761223057412600253170ustar00rootroot00000000000000 MAPIProxy 2.0 API Documentation
openchangedb_table.c File Reference

OpenChange Dispatcher database table routines. More...

#include <inttypes.h>
#include "mapiproxy/dcesrv_mapiproxy.h"
#include "libmapiproxy.h"
#include "libmapi/libmapi.h"
#include "libmapi/libmapi_private.h"

Functions

_PUBLIC_ enum MAPISTATUS openchangedb_table_init (TALLOC_CTX *mem_ctx, uint8_t table_type, uint64_t folderID, void **table_object)
 /details Initialize an openchangedb table
_PUBLIC_ enum MAPISTATUS openchangedb_table_set_sort_order (void *table_object, struct SSortOrderSet *lpSortCriteria)

Detailed Description

OpenChange Dispatcher database table routines.

Function Documentation

_PUBLIC_ enum MAPISTATUS openchangedb_table_init ( TALLOC_CTX *  mem_ctx,
uint8_t  table_type,
uint64_t  folderID,
void **  table_object 
)

/details Initialize an openchangedb table

Parameters
mem_ctxpointer to the memory context to use for allocation
table_typethe type of table this object represents
folderIDthe identifier of the folder this table represents
table_objectpointer on pointer to the table object to return
Returns
MAPI_E_SUCCESS on success, otherwise MAPISTORE error
_PUBLIC_ enum MAPISTATUS openchangedb_table_set_sort_order ( void *  table_object,
struct SSortOrderSet *  lpSortCriteria 
)

Set sort order to specified openchangedb table object

Parameters
table_objectpointer to the table object
lpSortCriteriapointer to the sort order to save
Returns
MAPI_E_SUCCESS on success, otherwise MAPI error

Referenced by EcDoRpc_RopSortTable().


Creative Commons License
Creative Commons Attribution icon Creative Commons Share Alike icon
This content is licensed under the Creative Commons
Attribution ShareAlike License v. 3.0:
http://creativecommons.org/licenses/by-sa/3.0/

openchange-2.0/apidocs/html/mapiproxy/oxcfold_8c.html000066400000000000000000001206031223057412600230220ustar00rootroot00000000000000 MAPIProxy 2.0 API Documentation
oxcfold.c File Reference

Folder object routines and Rops. More...

#include "mapiproxy/dcesrv_mapiproxy.h"
#include "mapiproxy/libmapiproxy/libmapiproxy.h"
#include "mapiproxy/libmapiserver/libmapiserver.h"
#include "dcesrv_exchange_emsmdb.h"

Functions

enum MAPISTATUS EcDoRpc_RopCopyFolder (TALLOC_CTX *mem_ctx, struct emsmdbp_context *emsmdbp_ctx, struct EcDoRpc_MAPI_REQ *mapi_req, struct EcDoRpc_MAPI_REPL *mapi_repl, uint32_t *handles, uint16_t *size)
_PUBLIC_ enum MAPISTATUS EcDoRpc_RopCreateFolder (TALLOC_CTX *mem_ctx, struct emsmdbp_context *emsmdbp_ctx, struct EcDoRpc_MAPI_REQ *mapi_req, struct EcDoRpc_MAPI_REPL *mapi_repl, uint32_t *handles, uint16_t *size)
_PUBLIC_ enum MAPISTATUS EcDoRpc_RopDeleteFolder (TALLOC_CTX *mem_ctx, struct emsmdbp_context *emsmdbp_ctx, struct EcDoRpc_MAPI_REQ *mapi_req, struct EcDoRpc_MAPI_REPL *mapi_repl, uint32_t *handles, uint16_t *size)
_PUBLIC_ enum MAPISTATUS EcDoRpc_RopDeleteMessages (TALLOC_CTX *mem_ctx, struct emsmdbp_context *emsmdbp_ctx, struct EcDoRpc_MAPI_REQ *mapi_req, struct EcDoRpc_MAPI_REPL *mapi_repl, uint32_t *handles, uint16_t *size)
_PUBLIC_ enum MAPISTATUS EcDoRpc_RopEmptyFolder (TALLOC_CTX *mem_ctx, struct emsmdbp_context *emsmdbp_ctx, struct EcDoRpc_MAPI_REQ *mapi_req, struct EcDoRpc_MAPI_REPL *mapi_repl, uint32_t *handles, uint16_t *size)
_PUBLIC_ enum MAPISTATUS EcDoRpc_RopGetContentsTable (TALLOC_CTX *mem_ctx, struct emsmdbp_context *emsmdbp_ctx, struct EcDoRpc_MAPI_REQ *mapi_req, struct EcDoRpc_MAPI_REPL *mapi_repl, uint32_t *handles, uint16_t *size)
_PUBLIC_ enum MAPISTATUS EcDoRpc_RopGetHierarchyTable (TALLOC_CTX *mem_ctx, struct emsmdbp_context *emsmdbp_ctx, struct EcDoRpc_MAPI_REQ *mapi_req, struct EcDoRpc_MAPI_REPL *mapi_repl, uint32_t *handles, uint16_t *size)
_PUBLIC_ enum MAPISTATUS EcDoRpc_RopGetSearchCriteria (TALLOC_CTX *mem_ctx, struct emsmdbp_context *emsmdbp_ctx, struct EcDoRpc_MAPI_REQ *mapi_req, struct EcDoRpc_MAPI_REPL *mapi_repl, uint32_t *handles, uint16_t *size)
enum MAPISTATUS EcDoRpc_RopMoveFolder (TALLOC_CTX *mem_ctx, struct emsmdbp_context *emsmdbp_ctx, struct EcDoRpc_MAPI_REQ *mapi_req, struct EcDoRpc_MAPI_REPL *mapi_repl, uint32_t *handles, uint16_t *size)
_PUBLIC_ enum MAPISTATUS EcDoRpc_RopOpenFolder (TALLOC_CTX *mem_ctx, struct emsmdbp_context *emsmdbp_ctx, struct EcDoRpc_MAPI_REQ *mapi_req, struct EcDoRpc_MAPI_REPL *mapi_repl, uint32_t *handles, uint16_t *size)
_PUBLIC_ enum MAPISTATUS EcDoRpc_RopSetSearchCriteria (TALLOC_CTX *mem_ctx, struct emsmdbp_context *emsmdbp_ctx, struct EcDoRpc_MAPI_REQ *mapi_req, struct EcDoRpc_MAPI_REPL *mapi_repl, uint32_t *handles, uint16_t *size)

Detailed Description

Folder object routines and Rops.

Function Documentation

enum MAPISTATUS EcDoRpc_RopCopyFolder ( TALLOC_CTX *  mem_ctx,
struct emsmdbp_context *  emsmdbp_ctx,
struct EcDoRpc_MAPI_REQ *  mapi_req,
struct EcDoRpc_MAPI_REPL *  mapi_repl,
uint32_t *  handles,
uint16_t *  size 
)

EcDoRpc EmptyFolder (0x58) Rop. This operation removes the sub-folders and messages from a given parent folder.

Parameters
mem_ctxpointer to the memory context
emsmdbp_ctxpointer to the emsmdb provider context
mapi_reqpointer to the EmptyFolder EcDoRpc_MAPI_REQ structure
mapi_replpointer to the EmptyFolder EcDoRpc_MAPI_REPL structure
handlespointer to the MAPI handles array
sizepointer to the mapi_response size to update
Returns
MAPI_E_SUCCESS on success, otherwise MAPI error

References emsmdbp_get_contextID(), emsmdbp_is_mapistore(), libmapiserver_RopCopyFolder_size(), mapi_handles_get_private_data(), and mapi_handles_search().

_PUBLIC_ enum MAPISTATUS EcDoRpc_RopCreateFolder ( TALLOC_CTX *  mem_ctx,
struct emsmdbp_context *  emsmdbp_ctx,
struct EcDoRpc_MAPI_REQ *  mapi_req,
struct EcDoRpc_MAPI_REPL *  mapi_repl,
uint32_t *  handles,
uint16_t *  size 
)

EcDoRpc CreateFolder (0x1c) Rop. This operation creates a folder on the remote server.

Parameters
mem_ctxpointer to the memory context
emsmdbp_ctxpointer to the emsmdb provider context
mapi_reqpointer to the CreateFolder EcDoRpc_MAPI_REQ structure
mapi_replpointer to the CreateFolder EcDoRpc_MAPI_REPL structure
handlespointer to the MAPI handles array
sizepointer to the mapi_response size to update
Returns
MAPI_E_SUCCESS on success, otherwise MAPI error
Note
We do not provide support for GhostInfo

References emsmdbp_object_open_folder_by_fid(), libmapiserver_ROP_request_to_properties(), libmapiserver_RopCreateFolder_size(), mapi_handles_add(), mapi_handles_delete(), mapi_handles_get_private_data(), mapi_handles_search(), mapi_handles_set_private_data(), openchangedb_get_new_changeNumber(), and openchangedb_get_new_folderID().

_PUBLIC_ enum MAPISTATUS EcDoRpc_RopDeleteFolder ( TALLOC_CTX *  mem_ctx,
struct emsmdbp_context *  emsmdbp_ctx,
struct EcDoRpc_MAPI_REQ *  mapi_req,
struct EcDoRpc_MAPI_REPL *  mapi_repl,
uint32_t *  handles,
uint16_t *  size 
)

EcDoRpc DeleteFolder (0x1d) Rop. This operation deletes a folder on the remote server.

Parameters
mem_ctxpointer to the memory context
emsmdbp_ctxpointer to the emsmdb provider context
mapi_reqpointer to the DeleteFolder EcDoRpc_MAPI_REQ structure
mapi_replpointer to the DeleteFolder EcDoRpc_MAPI_REPL structure
handlespointer to the MAPI handles array
sizepointer to the mapi_response size to update
Returns
MAPI_E_SUCCESS on success, otherwise MAPI error

References libmapiserver_RopDeleteFolder_size(), mapi_handles_get_private_data(), and mapi_handles_search().

_PUBLIC_ enum MAPISTATUS EcDoRpc_RopDeleteMessages ( TALLOC_CTX *  mem_ctx,
struct emsmdbp_context *  emsmdbp_ctx,
struct EcDoRpc_MAPI_REQ *  mapi_req,
struct EcDoRpc_MAPI_REPL *  mapi_repl,
uint32_t *  handles,
uint16_t *  size 
)

EcDoRpc DeleteMessage (0x1e) Rop. This operation (soft) deletes a message on the server.

Parameters
mem_ctxpointer to the memory context
emsmdbp_ctxpointer to the emsmdb provider context
mapi_reqpointer to the DeleteMessage EcDoRpc_MAPI_REQ structure
mapi_replpointer to the DeleteMessage EcDoRpc_MAPI_REPL structure
handlespointer to the MAPI handles array
sizepointer to the mapi_response size to update
Returns
MAPI_E_SUCCESS on success, otherwise MAPI error

References emsmdbp_get_contextID(), emsmdbp_get_owner(), emsmdbp_is_mapistore(), libmapiserver_RopDeleteMessage_size(), mapi_handles_get_private_data(), and mapi_handles_search().

_PUBLIC_ enum MAPISTATUS EcDoRpc_RopEmptyFolder ( TALLOC_CTX *  mem_ctx,
struct emsmdbp_context *  emsmdbp_ctx,
struct EcDoRpc_MAPI_REQ *  mapi_req,
struct EcDoRpc_MAPI_REPL *  mapi_repl,
uint32_t *  handles,
uint16_t *  size 
)

EcDoRpc EmptyFolder (0x58) Rop. This operation removes the sub-folders and messages from a given parent folder.

Parameters
mem_ctxpointer to the memory context
emsmdbp_ctxpointer to the emsmdb provider context
mapi_reqpointer to the EmptyFolder EcDoRpc_MAPI_REQ structure
mapi_replpointer to the EmptyFolder EcDoRpc_MAPI_REPL structure
handlespointer to the MAPI handles array
sizepointer to the mapi_response size to update
Returns
MAPI_E_SUCCESS on success, otherwise MAPI error

References emsmdbp_is_mapistore(), libmapiserver_RopEmptyFolder_size(), mapi_handles_get_private_data(), and mapi_handles_search().

_PUBLIC_ enum MAPISTATUS EcDoRpc_RopGetContentsTable ( TALLOC_CTX *  mem_ctx,
struct emsmdbp_context *  emsmdbp_ctx,
struct EcDoRpc_MAPI_REQ *  mapi_req,
struct EcDoRpc_MAPI_REPL *  mapi_repl,
uint32_t *  handles,
uint16_t *  size 
)

EcDoRpc GetContentsTable (0x05) Rop. This operation get the content table of a container.

Parameters
mem_ctxpointer to the memory context
emsmdbp_ctxpointer to the emsmdb provider context
mapi_reqpointer to the GetContentsTable EcDoRpc_MAPI_REQ structure
mapi_replpointer to the GetContentsTable EcDoRpc_MAPI_REPL structure
handlespointer to the MAPI handles array
sizepointer to the mapi_response size to update
Returns
MAPI_E_SUCCESS on success, otherwise MAPI error

References libmapiserver_RopGetContentsTable_size(), mapi_handles_add(), mapi_handles_get_private_data(), mapi_handles_search(), and mapi_handles_set_private_data().

_PUBLIC_ enum MAPISTATUS EcDoRpc_RopGetHierarchyTable ( TALLOC_CTX *  mem_ctx,
struct emsmdbp_context *  emsmdbp_ctx,
struct EcDoRpc_MAPI_REQ *  mapi_req,
struct EcDoRpc_MAPI_REPL *  mapi_repl,
uint32_t *  handles,
uint16_t *  size 
)

EcDoRpc GetHierarchyTable (0x04) Rop. This operation gets the subfolder hierarchy table for a folder.

Parameters
mem_ctxpointer to the memory context
emsmdbp_ctxpointer to the emsmdb provider context
mapi_reqpointer to the GetHierarchyTable EcDoRpc_MAPI_REQ structure
mapi_replpointer to the GetHierarchyTable EcDoRpc_MAPI_REPL structure
handlespointer to the MAPI handles array
sizepointer to the mapi_response size to update
Returns
MAPI_E_SUCCESS on success, otherwise MAPI error

References libmapiserver_RopGetHierarchyTable_size(), mapi_handles_add(), mapi_handles_get_private_data(), mapi_handles_search(), and mapi_handles_set_private_data().

_PUBLIC_ enum MAPISTATUS EcDoRpc_RopGetSearchCriteria ( TALLOC_CTX *  mem_ctx,
struct emsmdbp_context *  emsmdbp_ctx,
struct EcDoRpc_MAPI_REQ *  mapi_req,
struct EcDoRpc_MAPI_REPL *  mapi_repl,
uint32_t *  handles,
uint16_t *  size 
)

EcDoRpc GetSearchCriteria (0x31) Rop. This operation gets the search criteria for a search folder.

Parameters
mem_ctxpointer to the memory context
emsmdbp_ctxpointer to the emsmdb provider context
mapi_reqpointer to the GetSearchCriteria EcDoRpc_MAPI_REQ structure
mapi_replpointer to the GetSearchCriteria EcDoRpc_MAPI_REPL structure
handlespointer to the MAPI handles array
sizepointer to the mapi_response size to update
Returns
MAPI_E_SUCCESS on success, otherwise MAPI error

References libmapiserver_RopGetSearchCriteria_size().

enum MAPISTATUS EcDoRpc_RopMoveFolder ( TALLOC_CTX *  mem_ctx,
struct emsmdbp_context *  emsmdbp_ctx,
struct EcDoRpc_MAPI_REQ *  mapi_req,
struct EcDoRpc_MAPI_REPL *  mapi_repl,
uint32_t *  handles,
uint16_t *  size 
)

EcDoRpc EmptyFolder (0x58) Rop. This operation removes the sub-folders and messages from a given parent folder.

Parameters
mem_ctxpointer to the memory context
emsmdbp_ctxpointer to the emsmdb provider context
mapi_reqpointer to the EmptyFolder EcDoRpc_MAPI_REQ structure
mapi_replpointer to the EmptyFolder EcDoRpc_MAPI_REPL structure
handlespointer to the MAPI handles array
sizepointer to the mapi_response size to update
Returns
MAPI_E_SUCCESS on success, otherwise MAPI error

References libmapiserver_RopMoveFolder_size(), mapi_handles_get_private_data(), and mapi_handles_search().

_PUBLIC_ enum MAPISTATUS EcDoRpc_RopOpenFolder ( TALLOC_CTX *  mem_ctx,
struct emsmdbp_context *  emsmdbp_ctx,
struct EcDoRpc_MAPI_REQ *  mapi_req,
struct EcDoRpc_MAPI_REPL *  mapi_repl,
uint32_t *  handles,
uint16_t *  size 
)

EcDoRpc OpenFolder (0x02) Rop. This operation opens an existing folder.

Parameters
mem_ctxpointer to the memory context
emsmdbp_ctxpointer to the emsmdb provider context
mapi_reqpointer to the OpenFolder EcDoRpc_MAPI_REQ structure
mapi_replpointer to the OpenFolder EcDoRpc_MAPI_REPL structure
handlespointer to the MAPI handles array
sizepointer to the mapi_response size to update
Returns
MAPI_E_SUCCESS on success, otherwise MAPI error

References emsmdbp_object_open_folder_by_fid(), libmapiserver_RopOpenFolder_size(), mapi_handles_add(), mapi_handles_get_private_data(), mapi_handles_search(), and mapi_handles_set_private_data().

_PUBLIC_ enum MAPISTATUS EcDoRpc_RopSetSearchCriteria ( TALLOC_CTX *  mem_ctx,
struct emsmdbp_context *  emsmdbp_ctx,
struct EcDoRpc_MAPI_REQ *  mapi_req,
struct EcDoRpc_MAPI_REPL *  mapi_repl,
uint32_t *  handles,
uint16_t *  size 
)

EcDoRpc SetSearchCriteria (0x30) Rop. This operation sets the search criteria for a search folder.

Parameters
mem_ctxpointer to the memory context
emsmdbp_ctxpointer to the emsmdb provider context
mapi_reqpointer to the SetSearchCriteria EcDoRpc_MAPI_REQ structure
mapi_replpointer to the SetSearchCriteria EcDoRpc_MAPI_REPL structure
handlespointer to the MAPI handles array
sizepointer to the mapi_response size to update
Returns
MAPI_E_SUCCESS on success, otherwise MAPI error

References libmapiserver_RopSetSearchCriteria_size().


Creative Commons License
Creative Commons Attribution icon Creative Commons Share Alike icon
This content is licensed under the Creative Commons
Attribution ShareAlike License v. 3.0:
http://creativecommons.org/licenses/by-sa/3.0/

openchange-2.0/apidocs/html/mapiproxy/oxcfxics_8c.html000066400000000000000000001722061223057412600232200ustar00rootroot00000000000000 MAPIProxy 2.0 API Documentation
oxcfxics.c File Reference

FastTransfer and ICS object routines and Rops. More...

#include "mapiproxy/libmapiserver/libmapiserver.h"
#include "dcesrv_exchange_emsmdb.h"

Functions

static bool convertIdToFMID (const struct GUID *replica_guid, uint8_t *data, uint32_t size, uint64_t *fmidP)
_PUBLIC_ enum MAPISTATUS EcDoRpc_RopFastTransferSourceCopyTo (TALLOC_CTX *mem_ctx, struct emsmdbp_context *emsmdbp_ctx, struct EcDoRpc_MAPI_REQ *mapi_req, struct EcDoRpc_MAPI_REPL *mapi_repl, uint32_t *handles, uint16_t *size)
_PUBLIC_ enum MAPISTATUS EcDoRpc_RopFastTransferSourceGetBuffer (TALLOC_CTX *mem_ctx, struct emsmdbp_context *emsmdbp_ctx, struct EcDoRpc_MAPI_REQ *mapi_req, struct EcDoRpc_MAPI_REPL *mapi_repl, uint32_t *handles, uint16_t *size)
_PUBLIC_ enum MAPISTATUS EcDoRpc_RopGetLocalReplicaIds (TALLOC_CTX *mem_ctx, struct emsmdbp_context *emsmdbp_ctx, struct EcDoRpc_MAPI_REQ *mapi_req, struct EcDoRpc_MAPI_REPL *mapi_repl, uint32_t *handles, uint16_t *size)
_PUBLIC_ enum MAPISTATUS EcDoRpc_RopSetLocalReplicaMidsetDeleted (TALLOC_CTX *mem_ctx, struct emsmdbp_context *emsmdbp_ctx, struct EcDoRpc_MAPI_REQ *mapi_req, struct EcDoRpc_MAPI_REPL *mapi_repl, uint32_t *handles, uint16_t *size)
_PUBLIC_ enum MAPISTATUS EcDoRpc_RopSyncConfigure (TALLOC_CTX *mem_ctx, struct emsmdbp_context *emsmdbp_ctx, struct EcDoRpc_MAPI_REQ *mapi_req, struct EcDoRpc_MAPI_REPL *mapi_repl, uint32_t *handles, uint16_t *size)
_PUBLIC_ enum MAPISTATUS EcDoRpc_RopSyncGetTransferState (TALLOC_CTX *mem_ctx, struct emsmdbp_context *emsmdbp_ctx, struct EcDoRpc_MAPI_REQ *mapi_req, struct EcDoRpc_MAPI_REPL *mapi_repl, uint32_t *handles, uint16_t *size)
_PUBLIC_ enum MAPISTATUS EcDoRpc_RopSyncImportDeletes (TALLOC_CTX *mem_ctx, struct emsmdbp_context *emsmdbp_ctx, struct EcDoRpc_MAPI_REQ *mapi_req, struct EcDoRpc_MAPI_REPL *mapi_repl, uint32_t *handles, uint16_t *size)
_PUBLIC_ enum MAPISTATUS EcDoRpc_RopSyncImportHierarchyChange (TALLOC_CTX *mem_ctx, struct emsmdbp_context *emsmdbp_ctx, struct EcDoRpc_MAPI_REQ *mapi_req, struct EcDoRpc_MAPI_REPL *mapi_repl, uint32_t *handles, uint16_t *size)
_PUBLIC_ enum MAPISTATUS EcDoRpc_RopSyncImportMessageChange (TALLOC_CTX *mem_ctx, struct emsmdbp_context *emsmdbp_ctx, struct EcDoRpc_MAPI_REQ *mapi_req, struct EcDoRpc_MAPI_REPL *mapi_repl, uint32_t *handles, uint16_t *size)
_PUBLIC_ enum MAPISTATUS EcDoRpc_RopSyncImportReadStateChanges (TALLOC_CTX *mem_ctx, struct emsmdbp_context *emsmdbp_ctx, struct EcDoRpc_MAPI_REQ *mapi_req, struct EcDoRpc_MAPI_REPL *mapi_repl, uint32_t *handles, uint16_t *size)
_PUBLIC_ enum MAPISTATUS EcDoRpc_RopSyncOpenCollector (TALLOC_CTX *mem_ctx, struct emsmdbp_context *emsmdbp_ctx, struct EcDoRpc_MAPI_REQ *mapi_req, struct EcDoRpc_MAPI_REPL *mapi_repl, uint32_t *handles, uint16_t *size)
_PUBLIC_ enum MAPISTATUS EcDoRpc_RopSyncUploadStateStreamBegin (TALLOC_CTX *mem_ctx, struct emsmdbp_context *emsmdbp_ctx, struct EcDoRpc_MAPI_REQ *mapi_req, struct EcDoRpc_MAPI_REPL *mapi_repl, uint32_t *handles, uint16_t *size)
_PUBLIC_ enum MAPISTATUS EcDoRpc_RopSyncUploadStateStreamContinue (TALLOC_CTX *mem_ctx, struct emsmdbp_context *emsmdbp_ctx, struct EcDoRpc_MAPI_REQ *mapi_req, struct EcDoRpc_MAPI_REPL *mapi_repl, uint32_t *handles, uint16_t *size)
_PUBLIC_ enum MAPISTATUS EcDoRpc_RopSyncUploadStateStreamEnd (TALLOC_CTX *mem_ctx, struct emsmdbp_context *emsmdbp_ctx, struct EcDoRpc_MAPI_REQ *mapi_req, struct EcDoRpc_MAPI_REPL *mapi_repl, uint32_t *handles, uint16_t *size)
static struct MessageReadState * get_MessageReadState (TALLOC_CTX *mem_ctx, struct Binary_r *bin)
static void oxcfxics_push_folderChange (struct emsmdbp_context *emsmdbp_ctx, struct emsmdbp_object_synccontext *synccontext, const char *owner, struct emsmdbp_object *topmost_folder_object, struct oxcfxics_sync_data *sync_data, struct emsmdbp_object *folder_object)
static bool oxcfxics_push_messageChange (struct emsmdbp_context *emsmdbp_ctx, struct emsmdbp_object_synccontext *synccontext, const char *owner, struct oxcfxics_sync_data *sync_data, struct emsmdbp_object *folder_object)

Detailed Description

FastTransfer and ICS object routines and Rops.

Function Documentation

static bool convertIdToFMID ( const struct GUID *  replica_guid,
uint8_t *  data,
uint32_t  size,
uint64_t *  fmidP 
)
static

EcDoRpc SyncImportMessageMove (0x78) Rop.

Parameters
mem_ctxpointer to the memory context
emsmdbp_ctxpointer to the emsmdb provider context
mapi_reqpointer to the SyncImportMessageMove EcDoRpc_MAPI_REQ
mapi_replpointer to the SyncImportMessageMove EcDoRpc_MAPI_REPL
handlespointer to the MAPI handles array
sizepointer to the mapi_response size to update
Returns
MAPI_E_SUCCESS on success, otherwise MAPI error
_PUBLIC_ enum MAPISTATUS EcDoRpc_RopFastTransferSourceCopyTo ( TALLOC_CTX *  mem_ctx,
struct emsmdbp_context *  emsmdbp_ctx,
struct EcDoRpc_MAPI_REQ *  mapi_req,
struct EcDoRpc_MAPI_REPL *  mapi_repl,
uint32_t *  handles,
uint16_t *  size 
)

EcDoRpc EcDoRpc_RopFastTransferSourceCopyTo (0x4d) Rop. This operation initializes a FastTransfer operation to download content from a given messaging object and its descendant subobjects.

Parameters
mem_ctxpointer to the memory context
emsmdbp_ctxpointer to the emsmdb provider context
mapi_reqpointer to the EcDoRpc_RopFastTransferSourceCopyTo EcDoRpc_MAPI_REQ structure
mapi_replpointer to the EcDoRpc_RopFastTransferSourceCopyTo EcDoRpc_MAPI_REPL structure
handlespointer to the MAPI handles array
sizepointer to the mapi_response size to update
Returns
MAPI_E_SUCCESS on success, otherwise MAPI error

References emsmdbp_object_ftcontext_init(), libmapiserver_RopFastTransferSourceCopyTo_size(), mapi_handles_add(), mapi_handles_get_private_data(), mapi_handles_search(), and mapi_handles_set_private_data().

_PUBLIC_ enum MAPISTATUS EcDoRpc_RopFastTransferSourceGetBuffer ( TALLOC_CTX *  mem_ctx,
struct emsmdbp_context *  emsmdbp_ctx,
struct EcDoRpc_MAPI_REQ *  mapi_req,
struct EcDoRpc_MAPI_REPL *  mapi_repl,
uint32_t *  handles,
uint16_t *  size 
)

EcDoRpc EcDoRpc_RopFastTransferSourceGetBuffer (0x4e) Rop. This operation downloads the next portion of a FastTransfer stream that is produced by a previously configured download operation.

Parameters
mem_ctxpointer to the memory context
emsmdbp_ctxpointer to the emsmdb provider context
mapi_reqpointer to the FastTransferSourceGetBuffer EcDoRpc_MAPI_REQ structure
mapi_replpointer to the FastTransferSourceGetBuffer EcDoRpc_MAPI_REPL structure
handlespointer to the MAPI handles array
sizepointer to the mapi_response size to update
Returns
MAPI_E_SUCCESS on success, otherwise MAPI error

References libmapiserver_RopFastTransferSourceGetBuffer_size(), mapi_handles_get_private_data(), and mapi_handles_search().

_PUBLIC_ enum MAPISTATUS EcDoRpc_RopGetLocalReplicaIds ( TALLOC_CTX *  mem_ctx,
struct emsmdbp_context *  emsmdbp_ctx,
struct EcDoRpc_MAPI_REQ *  mapi_req,
struct EcDoRpc_MAPI_REPL *  mapi_repl,
uint32_t *  handles,
uint16_t *  size 
)

EcDoRpc EcDoRpc_RopGetLocalReplicaIds (0x7f) Rop. This operation reserves a range of IDs to be used by a local replica.

Parameters
mem_ctxpointer to the memory context
emsmdbp_ctxpointer to the emsmdb provider context
mapi_reqpointer to the GetLocalReplicaIds EcDoRpc_MAPI_REQ structure
mapi_replpointer to the GetLocalReplicaIds EcDoRpc_MAPI_REPL structure
handlespointer to the MAPI handles array
sizepointer to the mapi_response size to update
Returns
MAPI_E_SUCCESS on success, otherwise MAPI error

References libmapiserver_RopGetLocalReplicaIds_size(), mapi_handles_get_private_data(), mapi_handles_search(), and openchangedb_reserve_fmid_range().

_PUBLIC_ enum MAPISTATUS EcDoRpc_RopSetLocalReplicaMidsetDeleted ( TALLOC_CTX *  mem_ctx,
struct emsmdbp_context *  emsmdbp_ctx,
struct EcDoRpc_MAPI_REQ *  mapi_req,
struct EcDoRpc_MAPI_REPL *  mapi_repl,
uint32_t *  handles,
uint16_t *  size 
)

EcDoRpc SetLocalReplicaMidsetDeleted (0x93) Rop.

Parameters
mem_ctxpointer to the memory context
emsmdbp_ctxpointer to the emsmdb provider context
mapi_reqpointer to the SetLocalReplicaMidsetDeleted EcDoRpc_MAPI_REQ
mapi_replpointer to the SetLocalReplicaMidsetDeleted EcDoRpc_MAPI_REPL
handlespointer to the MAPI handles array
sizepointer to the mapi_response size to update
Returns
MAPI_E_SUCCESS on success, otherwise MAPI error

References libmapiserver_RopSetLocalReplicaMidsetDeleted_size().

_PUBLIC_ enum MAPISTATUS EcDoRpc_RopSyncConfigure ( TALLOC_CTX *  mem_ctx,
struct emsmdbp_context *  emsmdbp_ctx,
struct EcDoRpc_MAPI_REQ *  mapi_req,
struct EcDoRpc_MAPI_REPL *  mapi_repl,
uint32_t *  handles,
uint16_t *  size 
)

EcDoRpc EcDoRpc_RopSyncConfigure (0x70) Rop.

Parameters
mem_ctxpointer to the memory context
emsmdbp_ctxpointer to the emsmdb provider context
mapi_reqpointer to the SyncConfigure EcDoRpc_MAPI_REQ structure
mapi_replpointer to the SyncConfigure EcDoRpc_MAPI_REPL structure
handlespointer to the MAPI handles array
sizepointer to the mapi_response size to update
Returns
MAPI_E_SUCCESS on success, otherwise MAPI error

References emsmdbp_object_synccontext_init(), libmapiserver_RopSyncConfigure_size(), mapi_handles_add(), mapi_handles_get_private_data(), mapi_handles_search(), and mapi_handles_set_private_data().

_PUBLIC_ enum MAPISTATUS EcDoRpc_RopSyncGetTransferState ( TALLOC_CTX *  mem_ctx,
struct emsmdbp_context *  emsmdbp_ctx,
struct EcDoRpc_MAPI_REQ *  mapi_req,
struct EcDoRpc_MAPI_REPL *  mapi_repl,
uint32_t *  handles,
uint16_t *  size 
)

EcDoRpc EcDoRpc_RopSyncGetTransferState (0x82) Rop.

Parameters
mem_ctxpointer to the memory context
emsmdbp_ctxpointer to the emsmdb provider context
mapi_reqpointer to the SyncGetTransferState EcDoRpc_MAPI_REQ structure
mapi_replpointer to the SyncGetTransferState EcDoRpc_MAPI_REPL structure
handlespointer to the MAPI handles array
sizepointer to the mapi_response size to update
Returns
MAPI_E_SUCCESS on success, otherwise MAPI error

References emsmdbp_get_owner(), emsmdbp_object_ftcontext_init(), libmapiserver_RopSyncGetTransferState_size(), mapi_handles_add(), mapi_handles_get_private_data(), mapi_handles_search(), and mapi_handles_set_private_data().

_PUBLIC_ enum MAPISTATUS EcDoRpc_RopSyncImportDeletes ( TALLOC_CTX *  mem_ctx,
struct emsmdbp_context *  emsmdbp_ctx,
struct EcDoRpc_MAPI_REQ *  mapi_req,
struct EcDoRpc_MAPI_REPL *  mapi_repl,
uint32_t *  handles,
uint16_t *  size 
)

EcDoRpc SyncImportDeletes (0x74) Rop.

Parameters
mem_ctxpointer to the memory context
emsmdbp_ctxpointer to the emsmdb provider context
mapi_reqpointer to the SyncImportDeletes EcDoRpc_MAPI_REQ
mapi_replpointer to the SyncImportDeletes EcDoRpc_MAPI_REPL
handlespointer to the MAPI handles array
sizepointer to the mapi_response size to update
Returns
MAPI_E_SUCCESS on success, otherwise MAPI error

References emsmdbp_get_contextID(), emsmdbp_get_owner(), emsmdbp_is_mapistore(), libmapiserver_RopSyncImportDeletes_size(), mapi_handles_get_private_data(), mapi_handles_search(), and openchangedb_get_MailboxReplica().

_PUBLIC_ enum MAPISTATUS EcDoRpc_RopSyncImportHierarchyChange ( TALLOC_CTX *  mem_ctx,
struct emsmdbp_context *  emsmdbp_ctx,
struct EcDoRpc_MAPI_REQ *  mapi_req,
struct EcDoRpc_MAPI_REPL *  mapi_repl,
uint32_t *  handles,
uint16_t *  size 
)

EcDoRpc EcDoRpc_RopSyncImportHierarchyChange (0x73) Rop.

Parameters
mem_ctxpointer to the memory context
emsmdbp_ctxpointer to the emsmdb provider context
mapi_reqpointer to the SyncImportHierarchyChange EcDoRpc_MAPI_REQ structure
mapi_replpointer to the SyncImportHierarchyChange EcDoRpc_MAPI_REPL structure
handlespointer to the MAPI handles array
sizepointer to the mapi_response size to update
Returns
MAPI_E_SUCCESS on success, otherwise MAPI error

References emsmdbp_get_owner(), emsmdbp_object_open_folder_by_fid(), libmapiserver_RopSyncImportHierarchyChange_size(), mapi_handles_get_private_data(), mapi_handles_search(), openchangedb_get_MailboxReplica(), and openchangedb_get_new_changeNumber().

_PUBLIC_ enum MAPISTATUS EcDoRpc_RopSyncImportMessageChange ( TALLOC_CTX *  mem_ctx,
struct emsmdbp_context *  emsmdbp_ctx,
struct EcDoRpc_MAPI_REQ *  mapi_req,
struct EcDoRpc_MAPI_REPL *  mapi_repl,
uint32_t *  handles,
uint16_t *  size 
)

EcDoRpc EcDoRpc_RopSyncImportMessageChange (0x72) Rop.

Parameters
mem_ctxpointer to the memory context
emsmdbp_ctxpointer to the emsmdb provider context
mapi_reqpointer to the SyncImportMessageChange EcDoRpc_MAPI_REQ structure
mapi_replpointer to the SyncImportMessageChange EcDoRpc_MAPI_REPL structure
handlespointer to the MAPI handles array
sizepointer to the mapi_response size to update
Returns
MAPI_E_SUCCESS on success, otherwise MAPI error

References emsmdbp_get_contextID(), emsmdbp_get_owner(), emsmdbp_is_mapistore(), emsmdbp_object_message_init(), libmapiserver_RopSyncImportMessageChange_size(), mapi_handles_add(), mapi_handles_delete(), mapi_handles_get_private_data(), mapi_handles_search(), mapi_handles_set_private_data(), and openchangedb_get_MailboxReplica().

_PUBLIC_ enum MAPISTATUS EcDoRpc_RopSyncImportReadStateChanges ( TALLOC_CTX *  mem_ctx,
struct emsmdbp_context *  emsmdbp_ctx,
struct EcDoRpc_MAPI_REQ *  mapi_req,
struct EcDoRpc_MAPI_REPL *  mapi_repl,
uint32_t *  handles,
uint16_t *  size 
)

EcDoRpc SyncImportReadStateChanges (0x80) Rop.

Parameters
mem_ctxpointer to the memory context
emsmdbp_ctxpointer to the emsmdb provider context
mapi_reqpointer to the SyncImportReadStateChanges EcDoRpc_MAPI_REQ
mapi_replpointer to the SyncImportReadStateChanges EcDoRpc_MAPI_REPL
handlespointer to the MAPI handles array
sizepointer to the mapi_response size to update
Returns
MAPI_E_SUCCESS on success, otherwise MAPI error

References emsmdbp_get_contextID(), emsmdbp_get_owner(), emsmdbp_is_mapistore(), get_MessageReadState(), libmapiserver_RopSyncImportReadStateChanges_size(), mapi_handles_get_private_data(), and mapi_handles_search().

_PUBLIC_ enum MAPISTATUS EcDoRpc_RopSyncOpenCollector ( TALLOC_CTX *  mem_ctx,
struct emsmdbp_context *  emsmdbp_ctx,
struct EcDoRpc_MAPI_REQ *  mapi_req,
struct EcDoRpc_MAPI_REPL *  mapi_repl,
uint32_t *  handles,
uint16_t *  size 
)

EcDoRpc EcDoRpc_RopSyncOpenCollector (0x7e) Rop.

Parameters
mem_ctxpointer to the memory context
emsmdbp_ctxpointer to the emsmdb provider context
mapi_reqpointer to the SyncOpenCollector EcDoRpc_MAPI_REQ structure
mapi_replpointer to the SyncOpenCollector EcDoRpc_MAPI_REPL structure
handlespointer to the MAPI handles array
sizepointer to the mapi_response size to update
Returns
MAPI_E_SUCCESS on success, otherwise MAPI error

References emsmdbp_object_synccontext_init(), libmapiserver_RopSyncOpenCollector_size(), mapi_handles_add(), mapi_handles_get_private_data(), mapi_handles_search(), and mapi_handles_set_private_data().

_PUBLIC_ enum MAPISTATUS EcDoRpc_RopSyncUploadStateStreamBegin ( TALLOC_CTX *  mem_ctx,
struct emsmdbp_context *  emsmdbp_ctx,
struct EcDoRpc_MAPI_REQ *  mapi_req,
struct EcDoRpc_MAPI_REPL *  mapi_repl,
uint32_t *  handles,
uint16_t *  size 
)

EcDoRpc EcDoRpc_RopSyncUploadStateStreamBegin (0x75) Rop.

Parameters
mem_ctxpointer to the memory context
emsmdbp_ctxpointer to the emsmdb provider context
mapi_reqpointer to the SyncUploadStateStreamBegin EcDoRpc_MAPI_REQ structure
mapi_replpointer to the SyncUploadStateStreamBegin EcDoRpc_MAPI_REPL structure
handlespointer to the MAPI handles array
sizepointer to the mapi_response size to update
Returns
MAPI_E_SUCCESS on success, otherwise MAPI error

References libmapiserver_RopSyncUploadStateStreamBegin_size(), mapi_handles_get_private_data(), and mapi_handles_search().

_PUBLIC_ enum MAPISTATUS EcDoRpc_RopSyncUploadStateStreamContinue ( TALLOC_CTX *  mem_ctx,
struct emsmdbp_context *  emsmdbp_ctx,
struct EcDoRpc_MAPI_REQ *  mapi_req,
struct EcDoRpc_MAPI_REPL *  mapi_repl,
uint32_t *  handles,
uint16_t *  size 
)

EcDoRpc EcDoRpc_RopSyncUploadStateStreamContinue (0x76) Rop.

Parameters
mem_ctxpointer to the memory context
emsmdbp_ctxpointer to the emsmdb provider context
mapi_reqpointer to the SyncUploadStateStreamContinue EcDoRpc_MAPI_REQ structure
mapi_replpointer to the SyncUploadStateStreamContinue EcDoRpc_MAPI_REPL structure
handlespointer to the MAPI handles array
sizepointer to the mapi_response size to update
Returns
MAPI_E_SUCCESS on success, otherwise MAPI error

References libmapiserver_RopSyncUploadStateStreamContinue_size(), mapi_handles_get_private_data(), and mapi_handles_search().

_PUBLIC_ enum MAPISTATUS EcDoRpc_RopSyncUploadStateStreamEnd ( TALLOC_CTX *  mem_ctx,
struct emsmdbp_context *  emsmdbp_ctx,
struct EcDoRpc_MAPI_REQ *  mapi_req,
struct EcDoRpc_MAPI_REPL *  mapi_repl,
uint32_t *  handles,
uint16_t *  size 
)

EcDoRpc EcDoRpc_RopSyncUploadStateStreamEnd (0x77) Rop.

Parameters
mem_ctxpointer to the memory context
emsmdbp_ctxpointer to the emsmdb provider context
mapi_reqpointer to the SyncUploadStateStreamEnd EcDoRpc_MAPI_REQ structure
mapi_replpointer to the SyncUploadStateStreamEnd EcDoRpc_MAPI_REPL structure
handlespointer to the MAPI handles array
sizepointer to the mapi_response size to update
Returns
MAPI_E_SUCCESS on success, otherwise MAPI error

References libmapiserver_RopSyncUploadStateStreamEnd_size(), mapi_handles_get_private_data(), and mapi_handles_search().

static struct MessageReadState* get_MessageReadState ( TALLOC_CTX *  mem_ctx,
struct Binary_r *  bin 
)
staticread

Retrieve a MessageReadState structure from a binary blob

Parameters
mem_ctxpointer to the memory context
binpointer to the Binary_r structure with raw MessageReadState data
Returns
Allocated MessageReadState structure on success, otherwise NULL
Note
Developers must free the allocated MessageReadState when finished.

Referenced by EcDoRpc_RopSyncImportReadStateChanges().

static void oxcfxics_push_folderChange ( struct emsmdbp_context *  emsmdbp_ctx,
struct emsmdbp_object_synccontext *  synccontext,
const char *  owner,
struct emsmdbp_object *  topmost_folder_object,
struct oxcfxics_sync_data *  sync_data,
struct emsmdbp_object *  folder_object 
)
static

fixed header props

remaining props

References emsmdbp_get_contextID(), and emsmdbp_is_mapistore().

static bool oxcfxics_push_messageChange ( struct emsmdbp_context *  emsmdbp_ctx,
struct emsmdbp_object_synccontext *  synccontext,
const char *  owner,
struct oxcfxics_sync_data *  sync_data,
struct emsmdbp_object *  folder_object 
)
static

fixed header props

remaining props

References emsmdbp_get_contextID(), and emsmdbp_is_mapistore().


Creative Commons License
Creative Commons Attribution icon Creative Commons Share Alike icon
This content is licensed under the Creative Commons
Attribution ShareAlike License v. 3.0:
http://creativecommons.org/licenses/by-sa/3.0/

openchange-2.0/apidocs/html/mapiproxy/oxcmsg_8c.html000066400000000000000000001351261223057412600226720ustar00rootroot00000000000000 MAPIProxy 2.0 API Documentation
oxcmsg.c File Reference

Message and Attachment object routines and Rops. More...

#include "mapiproxy/dcesrv_mapiproxy.h"
#include "mapiproxy/libmapiproxy/libmapiproxy.h"
#include "mapiproxy/libmapiserver/libmapiserver.h"
#include "dcesrv_exchange_emsmdb.h"

Functions

_PUBLIC_ enum MAPISTATUS EcDoRpc_RopCreateAttach (TALLOC_CTX *mem_ctx, struct emsmdbp_context *emsmdbp_ctx, struct EcDoRpc_MAPI_REQ *mapi_req, struct EcDoRpc_MAPI_REPL *mapi_repl, uint32_t *handles, uint16_t *size)
_PUBLIC_ enum MAPISTATUS EcDoRpc_RopCreateMessage (TALLOC_CTX *mem_ctx, struct emsmdbp_context *emsmdbp_ctx, struct EcDoRpc_MAPI_REQ *mapi_req, struct EcDoRpc_MAPI_REPL *mapi_repl, uint32_t *handles, uint16_t *size)
_PUBLIC_ enum MAPISTATUS EcDoRpc_RopGetAttachmentTable (TALLOC_CTX *mem_ctx, struct emsmdbp_context *emsmdbp_ctx, struct EcDoRpc_MAPI_REQ *mapi_req, struct EcDoRpc_MAPI_REPL *mapi_repl, uint32_t *handles, uint16_t *size)
_PUBLIC_ enum MAPISTATUS EcDoRpc_RopModifyRecipients (TALLOC_CTX *mem_ctx, struct emsmdbp_context *emsmdbp_ctx, struct EcDoRpc_MAPI_REQ *mapi_req, struct EcDoRpc_MAPI_REPL *mapi_repl, uint32_t *handles, uint16_t *size)
_PUBLIC_ enum MAPISTATUS EcDoRpc_RopOpenAttach (TALLOC_CTX *mem_ctx, struct emsmdbp_context *emsmdbp_ctx, struct EcDoRpc_MAPI_REQ *mapi_req, struct EcDoRpc_MAPI_REPL *mapi_repl, uint32_t *handles, uint16_t *size)
_PUBLIC_ enum MAPISTATUS EcDoRpc_RopOpenEmbeddedMessage (TALLOC_CTX *mem_ctx, struct emsmdbp_context *emsmdbp_ctx, struct EcDoRpc_MAPI_REQ *mapi_req, struct EcDoRpc_MAPI_REPL *mapi_repl, uint32_t *handles, uint16_t *size)
_PUBLIC_ enum MAPISTATUS EcDoRpc_RopOpenMessage (TALLOC_CTX *mem_ctx, struct emsmdbp_context *emsmdbp_ctx, struct EcDoRpc_MAPI_REQ *mapi_req, struct EcDoRpc_MAPI_REPL *mapi_repl, uint32_t *handles, uint16_t *size)
_PUBLIC_ enum MAPISTATUS EcDoRpc_RopReloadCachedInformation (TALLOC_CTX *mem_ctx, struct emsmdbp_context *emsmdbp_ctx, struct EcDoRpc_MAPI_REQ *mapi_req, struct EcDoRpc_MAPI_REPL *mapi_repl, uint32_t *handles, uint16_t *size)
_PUBLIC_ enum MAPISTATUS EcDoRpc_RopRemoveAllRecipients (TALLOC_CTX *mem_ctx, struct emsmdbp_context *emsmdbp_ctx, struct EcDoRpc_MAPI_REQ *mapi_req, struct EcDoRpc_MAPI_REPL *mapi_repl, uint32_t *handles, uint16_t *size)
_PUBLIC_ enum MAPISTATUS EcDoRpc_RopSaveChangesAttachment (TALLOC_CTX *mem_ctx, struct emsmdbp_context *emsmdbp_ctx, struct EcDoRpc_MAPI_REQ *mapi_req, struct EcDoRpc_MAPI_REPL *mapi_repl, uint32_t *handles, uint16_t *size)
_PUBLIC_ enum MAPISTATUS EcDoRpc_RopSaveChangesMessage (TALLOC_CTX *mem_ctx, struct emsmdbp_context *emsmdbp_ctx, struct EcDoRpc_MAPI_REQ *mapi_req, struct EcDoRpc_MAPI_REPL *mapi_repl, uint32_t *handles, uint16_t *size)
_PUBLIC_ enum MAPISTATUS EcDoRpc_RopSetMessageReadFlag (TALLOC_CTX *mem_ctx, struct emsmdbp_context *emsmdbp_ctx, struct EcDoRpc_MAPI_REQ *mapi_req, struct EcDoRpc_MAPI_REPL *mapi_repl, uint32_t *handles, uint16_t *size)

Detailed Description

Message and Attachment object routines and Rops.

Function Documentation

_PUBLIC_ enum MAPISTATUS EcDoRpc_RopCreateAttach ( TALLOC_CTX *  mem_ctx,
struct emsmdbp_context *  emsmdbp_ctx,
struct EcDoRpc_MAPI_REQ *  mapi_req,
struct EcDoRpc_MAPI_REPL *  mapi_repl,
uint32_t *  handles,
uint16_t *  size 
)

EcDoRpc CreateAttach (0x23) Rop. This operation open an attachment from the message handle.

Parameters
mem_ctxpointer to the memory context
emsmdbp_ctxpointer to the emsmdb provider context
mapi_reqpointer to the CreateAttach EcDoRpc_MAPI_REQ structure
mapi_replpointer to the CreateAttach EcDoRpc_MAPI_REPL structure
handlespointer to the MAPI handles array
sizepointer to the mapi_response size to update
Returns
MAPI_E_SUCCESS on success, otherwise MAPI error

References emsmdbp_get_contextID(), emsmdbp_is_mapistore(), emsmdbp_object_attachment_init(), libmapiserver_RopCreateAttach_size(), mapi_handles_add(), mapi_handles_delete(), mapi_handles_get_private_data(), mapi_handles_search(), and mapi_handles_set_private_data().

_PUBLIC_ enum MAPISTATUS EcDoRpc_RopCreateMessage ( TALLOC_CTX *  mem_ctx,
struct emsmdbp_context *  emsmdbp_ctx,
struct EcDoRpc_MAPI_REQ *  mapi_req,
struct EcDoRpc_MAPI_REPL *  mapi_repl,
uint32_t *  handles,
uint16_t *  size 
)

EcDoRpc CreateMessage (0x06) Rop. This operation creates a message object in the mailbox.

Parameters
mem_ctxpointer to the memory context
emsmdbp_ctxpointer to the emsmdb provider context
mapi_reqpointer to the CreateMessage EcDoRpc_MAPI_REQ structure
mapi_replpointer to the CreateMessage EcDoRpc_MAPI_REPL structure
handlespointer to the MAPI handles array
sizepointer to the mapi_response size to update
Returns
MAPI_E_SUCCESS on success, otherwise MAPI error

References emsmdbp_get_contextID(), emsmdbp_is_mapistore(), emsmdbp_object_message_init(), emsmdbp_object_open_folder_by_fid(), entryid_set_AB_EntryID(), libmapiserver_RopCreateMessage_size(), mapi_handles_add(), mapi_handles_get_private_data(), mapi_handles_search(), mapi_handles_set_private_data(), openchangedb_get_new_folderID(), and openchangedb_message_create().

_PUBLIC_ enum MAPISTATUS EcDoRpc_RopGetAttachmentTable ( TALLOC_CTX *  mem_ctx,
struct emsmdbp_context *  emsmdbp_ctx,
struct EcDoRpc_MAPI_REQ *  mapi_req,
struct EcDoRpc_MAPI_REPL *  mapi_repl,
uint32_t *  handles,
uint16_t *  size 
)

EcDoRpc GetAttachmentTable (0x21) Rop. This operation gets the attachment table of a message.

Parameters
mem_ctxpointer to the memory context
emsmdbp_ctxpointer to the emsmdb provider context
mapi_reqpointer to the GetAttachmentTable EcDoRpc_MAPI_REQ structure
mapi_replpointer to the GetAttachmentTable EcDoRpc_MAPI_REPL structure
handlespointer to the MAPI handles array
sizepointer to the mapi_response size to update
Returns
MAPI_E_SUCCESS on success, otherwise MAPI error

References libmapiserver_RopGetAttachmentTable_size(), mapi_handles_add(), mapi_handles_delete(), mapi_handles_get_private_data(), mapi_handles_search(), and mapi_handles_set_private_data().

_PUBLIC_ enum MAPISTATUS EcDoRpc_RopModifyRecipients ( TALLOC_CTX *  mem_ctx,
struct emsmdbp_context *  emsmdbp_ctx,
struct EcDoRpc_MAPI_REQ *  mapi_req,
struct EcDoRpc_MAPI_REPL *  mapi_repl,
uint32_t *  handles,
uint16_t *  size 
)

EcDoRpc ModifyRecipients (0x0e) Rop. This operation modifies an existing message to add recipients (TO, CC, BCC).

Parameters
mem_ctxpointer to the memory context
emsmdbp_ctxpointer to the emsmdb provider context
mapi_reqpointer to the ModifyRecipients EcDoRpc_MAPI_REQ structure
mapi_replpointer to the ModifyRecipients EcDoRpc_MAPI_REPL structure
handlespointer to the MAPI handles array
sizepointer to the mapi_response size to update
Returns
MAPI_E_SUCCESS on success, otherwise MAPI error

References emsmdbp_get_contextID(), emsmdbp_is_mapistore(), libmapiserver_RopModifyRecipients_size(), mapi_handles_get_private_data(), and mapi_handles_search().

_PUBLIC_ enum MAPISTATUS EcDoRpc_RopOpenAttach ( TALLOC_CTX *  mem_ctx,
struct emsmdbp_context *  emsmdbp_ctx,
struct EcDoRpc_MAPI_REQ *  mapi_req,
struct EcDoRpc_MAPI_REPL *  mapi_repl,
uint32_t *  handles,
uint16_t *  size 
)

EcDoRpc OpenAttach (0x22) Rop. This operation open an attachment from the message handle.

Parameters
mem_ctxpointer to the memory context
emsmdbp_ctxpointer to the emsmdb provider context
mapi_reqpointer to the OpenAttach EcDoRpc_MAPI_REQ structure
mapi_replpointer to the OpenAttach EcDoRpc_MAPI_REPL structure
handlespointer to the MAPI handles array
sizepointer to the mapi_response size to update
Returns
MAPI_E_SUCCESS on success, otherwise MAPI error

References emsmdbp_get_contextID(), emsmdbp_is_mapistore(), emsmdbp_object_attachment_init(), libmapiserver_RopOpenAttach_size(), mapi_handles_add(), mapi_handles_delete(), mapi_handles_get_private_data(), mapi_handles_search(), and mapi_handles_set_private_data().

_PUBLIC_ enum MAPISTATUS EcDoRpc_RopOpenEmbeddedMessage ( TALLOC_CTX *  mem_ctx,
struct emsmdbp_context *  emsmdbp_ctx,
struct EcDoRpc_MAPI_REQ *  mapi_req,
struct EcDoRpc_MAPI_REPL *  mapi_repl,
uint32_t *  handles,
uint16_t *  size 
)

EcDoRpc OpenEmbeddedMessage (0x46) Rop. This operation open an attachment from the message handle.

Parameters
mem_ctxpointer to the memory context
emsmdbp_ctxpointer to the emsmdb provider context
mapi_reqpointer to the OpenEmbeddedMessage EcDoRpc_MAPI_REQ structure
mapi_replpointer to the OpenEmbeddedMessage EcDoRpc_MAPI_REPL structure
handlespointer to the MAPI handles array
sizepointer to the mapi_response size to update
Returns
MAPI_E_SUCCESS on success, otherwise MAPI error

References emsmdbp_get_contextID(), emsmdbp_is_mapistore(), emsmdbp_object_message_init(), libmapiserver_RopOpenEmbeddedMessage_size(), mapi_handles_add(), mapi_handles_get_private_data(), mapi_handles_search(), mapi_handles_set_private_data(), and openchangedb_get_new_folderID().

_PUBLIC_ enum MAPISTATUS EcDoRpc_RopOpenMessage ( TALLOC_CTX *  mem_ctx,
struct emsmdbp_context *  emsmdbp_ctx,
struct EcDoRpc_MAPI_REQ *  mapi_req,
struct EcDoRpc_MAPI_REPL *  mapi_repl,
uint32_t *  handles,
uint16_t *  size 
)

EcDoRpc OpenMessage (0x03) Rop. This operation opens an existing message in a mailbox.

Parameters
mem_ctxpointer to the memory context
emsmdbp_ctxpointer to the emsmdb provider context
mapi_reqpointer to the OpenMessage EcDoRpc_MAPI_REQ structure
mapi_replpointer to the OpenMessage EcDoRpc_MAPI_REPL structure
handlespointer to the MAPI handles array
sizepointer to the mapi_response size to update
Returns
MAPI_E_SUCCESS on success, otherwise MAPI error

References libmapiserver_RopOpenMessage_size(), mapi_handles_add(), mapi_handles_delete(), mapi_handles_get_private_data(), mapi_handles_search(), and mapi_handles_set_private_data().

_PUBLIC_ enum MAPISTATUS EcDoRpc_RopReloadCachedInformation ( TALLOC_CTX *  mem_ctx,
struct emsmdbp_context *  emsmdbp_ctx,
struct EcDoRpc_MAPI_REQ *  mapi_req,
struct EcDoRpc_MAPI_REPL *  mapi_repl,
uint32_t *  handles,
uint16_t *  size 
)

EcDoRpc ReloadCachedInformation (0x10) Rop. This operation gets message and recipient information from a message.

Parameters
mem_ctxpointer to the memory context
emsmdbp_ctxpointer to the emsmdb provider context
mapi_reqpointer to the ReloadCachedInformation EcDoRpc_MAPI_REQ structure
mapi_replpointer to the ReloadCachedInformation EcDoRpc_MAPI_REPL structure
handlespointer to the MAPI handles array
sizepointer to the mapi_response size to update
Returns
MAPI_E_SUCCESS on success, otherwise MAPI error

References emsmdbp_get_contextID(), emsmdbp_is_mapistore(), libmapiserver_RopReloadCachedInformation_size(), mapi_handles_get_private_data(), and mapi_handles_search().

_PUBLIC_ enum MAPISTATUS EcDoRpc_RopRemoveAllRecipients ( TALLOC_CTX *  mem_ctx,
struct emsmdbp_context *  emsmdbp_ctx,
struct EcDoRpc_MAPI_REQ *  mapi_req,
struct EcDoRpc_MAPI_REPL *  mapi_repl,
uint32_t *  handles,
uint16_t *  size 
)

EcDoRpc RemoveAllRecipients (0x0d) Rop. This operation removes all recipients from a message.

Parameters
mem_ctxpointer to the memory context
emsmdbp_ctxpointer to the emsmdb provider context
mapi_reqpointer to the RemoveAllRecipients EcDoRpc_MAPI_REQ structure
mapi_replpointer to the RemoveAllRecipients EcDoRpc_MAPI_REPL structure
handlespointer to the MAPI handles array
sizepointer to the mapi_response size to update
Returns
MAPI_E_SUCCESS on success, otherwise MAPI error

References emsmdbp_get_contextID(), emsmdbp_is_mapistore(), libmapiserver_RopRemoveAllRecipients_size(), mapi_handles_get_private_data(), and mapi_handles_search().

_PUBLIC_ enum MAPISTATUS EcDoRpc_RopSaveChangesAttachment ( TALLOC_CTX *  mem_ctx,
struct emsmdbp_context *  emsmdbp_ctx,
struct EcDoRpc_MAPI_REQ *  mapi_req,
struct EcDoRpc_MAPI_REPL *  mapi_repl,
uint32_t *  handles,
uint16_t *  size 
)

EcDoRpc SaveChangesAttachment (0x25) Rop. This operation open an attachment from the message handle.

Parameters
mem_ctxpointer to the memory context
emsmdbp_ctxpointer to the emsmdb provider context
mapi_reqpointer to the SaveChangesAttachment EcDoRpc_MAPI_REQ structure
mapi_replpointer to the SaveChangesAttachment EcDoRpc_MAPI_REPL structure
handlespointer to the MAPI handles array
sizepointer to the mapi_response size to update
Returns
MAPI_E_SUCCESS on success, otherwise MAPI error

References libmapiserver_RopSaveChangesAttachment_size().

_PUBLIC_ enum MAPISTATUS EcDoRpc_RopSaveChangesMessage ( TALLOC_CTX *  mem_ctx,
struct emsmdbp_context *  emsmdbp_ctx,
struct EcDoRpc_MAPI_REQ *  mapi_req,
struct EcDoRpc_MAPI_REPL *  mapi_repl,
uint32_t *  handles,
uint16_t *  size 
)

EcDoRpc SaveChangesMessage (0x0c) Rop. This operation operation commits the changes made to a message.

Parameters
mem_ctxpointer to the memory context
emsmdbp_ctxpointer to the emsmdb provider context
mapi_reqpointer to the SaveChangesMessage EcDoRpc_MAPI_REQ structure
mapi_replpointer to the SaveChangesMessage EcDoRpc_MAPI_REPL structure
handlespointer to the MAPI handles array
sizepointer to the mapi_response size to update
Returns
MAPI_E_SUCCESS on success, otherwise MAPI error

References emsmdbp_get_contextID(), emsmdbp_get_owner(), emsmdbp_is_mapistore(), libmapiserver_RopSaveChangesMessage_size(), mapi_handles_get_private_data(), mapi_handles_search(), and openchangedb_message_save().

_PUBLIC_ enum MAPISTATUS EcDoRpc_RopSetMessageReadFlag ( TALLOC_CTX *  mem_ctx,
struct emsmdbp_context *  emsmdbp_ctx,
struct EcDoRpc_MAPI_REQ *  mapi_req,
struct EcDoRpc_MAPI_REPL *  mapi_repl,
uint32_t *  handles,
uint16_t *  size 
)

EcDoRpc SetMessageReadFlag (0x11) Rop. This operation sets or clears the message read flag.

Parameters
mem_ctxpointer to the memory context
emsmdbp_ctxpointer to the emsmdb provider context
mapi_reqpointer to the SetMessageReadFlag EcDoRpc_MAPI_REQ structure
mapi_replpointer to the SetMessageReadFlag EcDoRpc_MAPI_REPL structure
handlespointer to the MAPI handles array
sizepointer to the mapi_response size to update
Returns
MAPI_E_SUCCESS on success, otherwise MAPI error

References emsmdbp_get_contextID(), emsmdbp_is_mapistore(), libmapiserver_RopSetMessageReadFlag_size(), mapi_handles_get_private_data(), and mapi_handles_search().


Creative Commons License
Creative Commons Attribution icon Creative Commons Share Alike icon
This content is licensed under the Creative Commons
Attribution ShareAlike License v. 3.0:
http://creativecommons.org/licenses/by-sa/3.0/

openchange-2.0/apidocs/html/mapiproxy/oxcnotif_8c.html000066400000000000000000000155501223057412600232210ustar00rootroot00000000000000 MAPIProxy 2.0 API Documentation
oxcnotif.c File Reference

Core Notifications routines and Rops. More...

#include "mapiproxy/dcesrv_mapiproxy.h"
#include "mapiproxy/libmapiproxy/libmapiproxy.h"
#include "mapiproxy/libmapiserver/libmapiserver.h"
#include "dcesrv_exchange_emsmdb.h"

Functions

_PUBLIC_ enum MAPISTATUS EcDoRpc_RopRegisterNotification (TALLOC_CTX *mem_ctx, struct emsmdbp_context *emsmdbp_ctx, struct EcDoRpc_MAPI_REQ *mapi_req, struct EcDoRpc_MAPI_REPL *mapi_repl, uint32_t *handles, uint16_t *size)

Detailed Description

Core Notifications routines and Rops.

Function Documentation

_PUBLIC_ enum MAPISTATUS EcDoRpc_RopRegisterNotification ( TALLOC_CTX *  mem_ctx,
struct emsmdbp_context *  emsmdbp_ctx,
struct EcDoRpc_MAPI_REQ *  mapi_req,
struct EcDoRpc_MAPI_REPL *  mapi_repl,
uint32_t *  handles,
uint16_t *  size 
)

EcDoRpc RegisterNotification (0x29) Rop. This operation subscribes for specified notifications on the server and returns a handle of the subscription to the client.

Parameters
mem_ctxpointer to the memory context
emsmdbp_ctxpointer to the emsmdb provider context
mapi_reqpointer to the RegisterNotification EcDoRpc_MAPI_REQ structure
mapi_replpointer to the RegisterNotification EcDoRpc_MAPI_REPL structure
handlespointer to the MAPI handles array
sizepointer to the mapi_response size to update
Returns
MAPI_E_SUCCESS on success, otherwise MAPI error

References emsmdbp_object_subscription_init(), libmapiserver_RopRegisterNotification_size(), mapi_handles_add(), mapi_handles_get_private_data(), mapi_handles_search(), and mapi_handles_set_private_data().


Creative Commons License
Creative Commons Attribution icon Creative Commons Share Alike icon
This content is licensed under the Creative Commons
Attribution ShareAlike License v. 3.0:
http://creativecommons.org/licenses/by-sa/3.0/

openchange-2.0/apidocs/html/mapiproxy/oxcperm_8c.html000066400000000000000000000242461223057412600230470ustar00rootroot00000000000000 MAPIProxy 2.0 API Documentation
oxcperm.c File Reference

Access and Operation Permissions Rops. More...

#include "mapiproxy/dcesrv_mapiproxy.h"
#include "mapiproxy/libmapiproxy/libmapiproxy.h"
#include "mapiproxy/libmapiserver/libmapiserver.h"
#include "dcesrv_exchange_emsmdb.h"

Functions

_PUBLIC_ enum MAPISTATUS EcDoRpc_RopGetPermissionsTable (TALLOC_CTX *mem_ctx, struct emsmdbp_context *emsmdbp_ctx, struct EcDoRpc_MAPI_REQ *mapi_req, struct EcDoRpc_MAPI_REPL *mapi_repl, uint32_t *handles, uint16_t *size)
_PUBLIC_ enum MAPISTATUS EcDoRpc_RopModifyPermissions (TALLOC_CTX *mem_ctx, struct emsmdbp_context *emsmdbp_ctx, struct EcDoRpc_MAPI_REQ *mapi_req, struct EcDoRpc_MAPI_REPL *mapi_repl, uint32_t *handles, uint16_t *size)

Detailed Description

Access and Operation Permissions Rops.

Function Documentation

_PUBLIC_ enum MAPISTATUS EcDoRpc_RopGetPermissionsTable ( TALLOC_CTX *  mem_ctx,
struct emsmdbp_context *  emsmdbp_ctx,
struct EcDoRpc_MAPI_REQ *  mapi_req,
struct EcDoRpc_MAPI_REPL *  mapi_repl,
uint32_t *  handles,
uint16_t *  size 
)

EcDoRpc GetPermissionsTable (0x3e) Rop. This operation get the permissions table of a folder.

Parameters
mem_ctxpointer to the memory context
emsmdbp_ctxpointer to the emsmdb provider context
mapi_reqpointer to the GetPermissionsTable EcDoRpc_MAPI_REQ structure
mapi_replpointer to the GetPermissionsTable EcDoRpc_MAPI_REPL structure
handlespointer to the MAPI handles array
sizepointer to the mapi_response size to update
Returns
MAPI_E_SUCCESS on success, otherwise MAPI error

References emsmdbp_is_mapistore(), emsmdbp_object_table_init(), mapi_handles_add(), mapi_handles_delete(), mapi_handles_get_private_data(), mapi_handles_search(), and mapi_handles_set_private_data().

_PUBLIC_ enum MAPISTATUS EcDoRpc_RopModifyPermissions ( TALLOC_CTX *  mem_ctx,
struct emsmdbp_context *  emsmdbp_ctx,
struct EcDoRpc_MAPI_REQ *  mapi_req,
struct EcDoRpc_MAPI_REPL *  mapi_repl,
uint32_t *  handles,
uint16_t *  size 
)

EcDoRpc ModifyPermissions (0x40) Rop. This operation gets the GUID of a public folder's per-user information.

Parameters
mem_ctxpointer to the memory context
emsmdbp_ctxpointer to the emsmdb provider context
mapi_reqpointer to the GetPerUserLongTermIds EcDoRpc_MAPI_REQ
mapi_replpointer to the GetPerUserLongTermIds EcDoRpc_MAPI_REPL
handlespointer to the MAPI handles array
sizepointer to the mapi_response size to update
Returns
MAPI_E_SUCCESS on success, otherwise MAPI error

References emsmdbp_get_contextID(), emsmdbp_is_mapistore(), mapi_handles_get_private_data(), and mapi_handles_search().


Creative Commons License
Creative Commons Attribution icon Creative Commons Share Alike icon
This content is licensed under the Creative Commons
Attribution ShareAlike License v. 3.0:
http://creativecommons.org/licenses/by-sa/3.0/

openchange-2.0/apidocs/html/mapiproxy/oxcprpt_8c.html000066400000000000000000001547041223057412600230740ustar00rootroot00000000000000 MAPIProxy 2.0 API Documentation
oxcprpt.c File Reference

Property and Stream Object routines and Rops. More...

#include <stdlib.h>
#include <unistd.h>
#include "libmapi/libmapi.h"
#include "mapiproxy/dcesrv_mapiproxy.h"
#include "mapiproxy/libmapiproxy/libmapiproxy.h"
#include "mapiproxy/libmapiserver/libmapiserver.h"
#include "dcesrv_exchange_emsmdb.h"

Functions

_PUBLIC_ enum MAPISTATUS EcDoRpc_RopCommitStream (TALLOC_CTX *mem_ctx, struct emsmdbp_context *emsmdbp_ctx, struct EcDoRpc_MAPI_REQ *mapi_req, struct EcDoRpc_MAPI_REPL *mapi_repl, uint32_t *handles, uint16_t *size)
_PUBLIC_ enum MAPISTATUS EcDoRpc_RopCopyTo (TALLOC_CTX *mem_ctx, struct emsmdbp_context *emsmdbp_ctx, struct EcDoRpc_MAPI_REQ *mapi_req, struct EcDoRpc_MAPI_REPL *mapi_repl, uint32_t *handles, uint16_t *size)
_PUBLIC_ enum MAPISTATUS EcDoRpc_RopDeleteProperties (TALLOC_CTX *mem_ctx, struct emsmdbp_context *emsmdbp_ctx, struct EcDoRpc_MAPI_REQ *mapi_req, struct EcDoRpc_MAPI_REPL *mapi_repl, uint32_t *handles, uint16_t *size)
_PUBLIC_ enum MAPISTATUS EcDoRpc_RopDeletePropertiesNoReplicate (TALLOC_CTX *mem_ctx, struct emsmdbp_context *emsmdbp_ctx, struct EcDoRpc_MAPI_REQ *mapi_req, struct EcDoRpc_MAPI_REPL *mapi_repl, uint32_t *handles, uint16_t *size)
_PUBLIC_ enum MAPISTATUS EcDoRpc_RopGetNamesFromIDs (TALLOC_CTX *mem_ctx, struct emsmdbp_context *emsmdbp_ctx, struct EcDoRpc_MAPI_REQ *mapi_req, struct EcDoRpc_MAPI_REPL *mapi_repl, uint32_t *handles, uint16_t *size)
_PUBLIC_ enum MAPISTATUS EcDoRpc_RopGetPropertiesAll (TALLOC_CTX *mem_ctx, struct emsmdbp_context *emsmdbp_ctx, struct EcDoRpc_MAPI_REQ *mapi_req, struct EcDoRpc_MAPI_REPL *mapi_repl, uint32_t *handles, uint16_t *size)
_PUBLIC_ enum MAPISTATUS EcDoRpc_RopGetPropertiesList (TALLOC_CTX *mem_ctx, struct emsmdbp_context *emsmdbp_ctx, struct EcDoRpc_MAPI_REQ *mapi_req, struct EcDoRpc_MAPI_REPL *mapi_repl, uint32_t *handles, uint16_t *size)
types h _PUBLIC_ enum MAPISTATUS EcDoRpc_RopGetPropertiesSpecific (TALLOC_CTX *mem_ctx, struct emsmdbp_context *emsmdbp_ctx, struct EcDoRpc_MAPI_REQ *mapi_req, struct EcDoRpc_MAPI_REPL *mapi_repl, uint32_t *handles, uint16_t *size)
_PUBLIC_ enum MAPISTATUS EcDoRpc_RopGetPropertyIdsFromNames (TALLOC_CTX *mem_ctx, struct emsmdbp_context *emsmdbp_ctx, struct EcDoRpc_MAPI_REQ *mapi_req, struct EcDoRpc_MAPI_REPL *mapi_repl, uint32_t *handles, uint16_t *size)
_PUBLIC_ enum MAPISTATUS EcDoRpc_RopGetStreamSize (TALLOC_CTX *mem_ctx, struct emsmdbp_context *emsmdbp_ctx, struct EcDoRpc_MAPI_REQ *mapi_req, struct EcDoRpc_MAPI_REPL *mapi_repl, uint32_t *handles, uint16_t *size)
_PUBLIC_ enum MAPISTATUS EcDoRpc_RopOpenStream (TALLOC_CTX *mem_ctx, struct emsmdbp_context *emsmdbp_ctx, struct EcDoRpc_MAPI_REQ *mapi_req, struct EcDoRpc_MAPI_REPL *mapi_repl, uint32_t *handles, uint16_t *size)
_PUBLIC_ enum MAPISTATUS EcDoRpc_RopReadStream (TALLOC_CTX *mem_ctx, struct emsmdbp_context *emsmdbp_ctx, struct EcDoRpc_MAPI_REQ *mapi_req, struct EcDoRpc_MAPI_REPL *mapi_repl, uint32_t *handles, uint16_t *size)
_PUBLIC_ enum MAPISTATUS EcDoRpc_RopSeekStream (TALLOC_CTX *mem_ctx, struct emsmdbp_context *emsmdbp_ctx, struct EcDoRpc_MAPI_REQ *mapi_req, struct EcDoRpc_MAPI_REPL *mapi_repl, uint32_t *handles, uint16_t *size)
_PUBLIC_ enum MAPISTATUS EcDoRpc_RopSetProperties (TALLOC_CTX *mem_ctx, struct emsmdbp_context *emsmdbp_ctx, struct EcDoRpc_MAPI_REQ *mapi_req, struct EcDoRpc_MAPI_REPL *mapi_repl, uint32_t *handles, uint16_t *size)
_PUBLIC_ enum MAPISTATUS EcDoRpc_RopSetStreamSize (TALLOC_CTX *mem_ctx, struct emsmdbp_context *emsmdbp_ctx, struct EcDoRpc_MAPI_REQ *mapi_req, struct EcDoRpc_MAPI_REPL *mapi_repl, uint32_t *handles, uint16_t *size)
_PUBLIC_ enum MAPISTATUS EcDoRpc_RopWriteStream (TALLOC_CTX *mem_ctx, struct emsmdbp_context *emsmdbp_ctx, struct EcDoRpc_MAPI_REQ *mapi_req, struct EcDoRpc_MAPI_REPL *mapi_repl, uint32_t *handles, uint16_t *size)

Detailed Description

Property and Stream Object routines and Rops.

Function Documentation

_PUBLIC_ enum MAPISTATUS EcDoRpc_RopCommitStream ( TALLOC_CTX *  mem_ctx,
struct emsmdbp_context *  emsmdbp_ctx,
struct EcDoRpc_MAPI_REQ *  mapi_req,
struct EcDoRpc_MAPI_REPL *  mapi_repl,
uint32_t *  handles,
uint16_t *  size 
)

EcDoRpc CommitStream (0x5d) Rop.

Parameters
mem_ctxpointer to the memory context
emsmdbp_ctxpointer to the emsmdb provider context
mapi_reqpointer to the DeleteProperties EcDoRpc_MAPI_REQ structure
mapi_replpointer to the DeleteProperties EcDoRpc_MAPI_REPL structure
handlespointer to the MAPI handles array
sizepointer to the mapi_response size to update
Returns
MAPI_E_SUCCESS on success, otherwise MAPI error

References libmapiserver_RopCommitStream_size(), mapi_handles_get_private_data(), and mapi_handles_search().

_PUBLIC_ enum MAPISTATUS EcDoRpc_RopCopyTo ( TALLOC_CTX *  mem_ctx,
struct emsmdbp_context *  emsmdbp_ctx,
struct EcDoRpc_MAPI_REQ *  mapi_req,
struct EcDoRpc_MAPI_REPL *  mapi_repl,
uint32_t *  handles,
uint16_t *  size 
)

EcDoRpc CopyTo (0x39) Rop. This operation copy messages from one folder to another.

Parameters
mem_ctxpointer to the memory context
emsmdbp_ctxpointer to the emsmdb provider context
mapi_reqpointer to the DeleteProperties EcDoRpc_MAPI_REQ structure
mapi_replpointer to the DeleteProperties EcDoRpc_MAPI_REPL structure
handlespointer to the MAPI handles array
sizepointer to the mapi_response size to update
Returns
MAPI_E_SUCCESS on success, otherwise MAPI error

References emsmdbp_object_copy_properties(), libmapiserver_RopCopyTo_size(), mapi_handles_get_private_data(), and mapi_handles_search().

_PUBLIC_ enum MAPISTATUS EcDoRpc_RopDeleteProperties ( TALLOC_CTX *  mem_ctx,
struct emsmdbp_context *  emsmdbp_ctx,
struct EcDoRpc_MAPI_REQ *  mapi_req,
struct EcDoRpc_MAPI_REPL *  mapi_repl,
uint32_t *  handles,
uint16_t *  size 
)

EcDoRpc DeleteProperties (0x0b) Rop. This operation deletes property values for an object.

Parameters
mem_ctxpointer to the memory context
emsmdbp_ctxpointer to the emsmdb provider context
mapi_reqpointer to the DeleteProperties EcDoRpc_MAPI_REQ structure
mapi_replpointer to the DeleteProperties EcDoRpc_MAPI_REPL structure
handlespointer to the MAPI handles array
sizepointer to the mapi_response size to update
Returns
MAPI_E_SUCCESS on success, otherwise MAPI error

References libmapiserver_RopDeleteProperties_size().

_PUBLIC_ enum MAPISTATUS EcDoRpc_RopDeletePropertiesNoReplicate ( TALLOC_CTX *  mem_ctx,
struct emsmdbp_context *  emsmdbp_ctx,
struct EcDoRpc_MAPI_REQ *  mapi_req,
struct EcDoRpc_MAPI_REPL *  mapi_repl,
uint32_t *  handles,
uint16_t *  size 
)

EcDoRpc DeletePropertiesNoReplicate (0x7a) Rop. deletes property values from an object without invoking replication.

Parameters
mem_ctxpointer to the memory context
emsmdbp_ctxpointer to the emsmdb provider context
mapi_reqpointer to the DeletePropertiesNoReplicate EcDoRpc_MAPI_REQ structure
mapi_replpointer to the DeletePropertiesNoReplicate EcDoRpc_MAPI_REPL structure
handlespointer to the MAPI handles array
sizepointer to the mapi_response size to update
Returns
MAPI_E_SUCCESS on success, otherwise MAPI error

References libmapiserver_RopDeletePropertiesNoReplicate_size().

_PUBLIC_ enum MAPISTATUS EcDoRpc_RopGetNamesFromIDs ( TALLOC_CTX *  mem_ctx,
struct emsmdbp_context *  emsmdbp_ctx,
struct EcDoRpc_MAPI_REQ *  mapi_req,
struct EcDoRpc_MAPI_REPL *  mapi_repl,
uint32_t *  handles,
uint16_t *  size 
)

EcDoRpc GetNamesFromIDs (0x56) Rop. This operation gets property IDs for specified property names.

Parameters
mem_ctxpointer to the memory context
emsmdbp_ctxpointer to the emsmdb provider context
mapi_reqpointer to the GetNamesFromIDs EcDoRpc_MAPI_REQ structure
mapi_replpointer to the GetNamesFromIDs EcDoRpc_MAPI_REPL structure
handlespointer to the MAPI handles array
sizepointer to the mapi_response size to update
Returns
MAPI_E_SUCCESS on success, otherwise MAPI error

References libmapiserver_RopGetNamesFromIDs_size().

_PUBLIC_ enum MAPISTATUS EcDoRpc_RopGetPropertiesAll ( TALLOC_CTX *  mem_ctx,
struct emsmdbp_context *  emsmdbp_ctx,
struct EcDoRpc_MAPI_REQ *  mapi_req,
struct EcDoRpc_MAPI_REPL *  mapi_repl,
uint32_t *  handles,
uint16_t *  size 
)

EcDoRpc GetPropertiesAll (0x08) Rop. This operation gets all the property values for an object.

Parameters
mem_ctxpointer to the memory context
emsmdbp_ctxpointer to the emsmdb provider context
mapi_reqpointer to the GetPropertiesAll EcDoRpc_MAPI_REQ structure
mapi_replpointer to the GetPropertiesAll EcDoRpc_MAPI_REPL structure
handlespointer to the MAPI handles array
sizepointer to the mapi_response size to update
Returns
MAPI_E_SUCCESS on success, otherwise MAPI error

References libmapiserver_RopGetPropertiesAll_size(), mapi_handles_get_private_data(), and mapi_handles_search().

_PUBLIC_ enum MAPISTATUS EcDoRpc_RopGetPropertiesList ( TALLOC_CTX *  mem_ctx,
struct emsmdbp_context *  emsmdbp_ctx,
struct EcDoRpc_MAPI_REQ *  mapi_req,
struct EcDoRpc_MAPI_REPL *  mapi_repl,
uint32_t *  handles,
uint16_t *  size 
)

EcDoRpc GetPropertiesList (0x9) Rop. This operation retrieves the list of MAPI tags for an object.

Parameters
mem_ctxpointer to the memory context
emsmdbp_ctxpointer to the emsmdb provider context
mapi_reqpointer to the SetProperties EcDoRpc_MAPI_REQ structure
mapi_replpointer to the SetProperties EcDoRpc_MAPI_REPL structure
handlespointer to the MAPI handles array
sizepointer to the mapi_response size to update
Returns
MAPI_E_SUCCESS on success, otherwise MAPI error

References libmapiserver_RopGetPropertiesList_size(), mapi_handles_get_private_data(), and mapi_handles_search().

types h _PUBLIC_ enum MAPISTATUS EcDoRpc_RopGetPropertiesSpecific ( TALLOC_CTX *  mem_ctx,
struct emsmdbp_context *  emsmdbp_ctx,
struct EcDoRpc_MAPI_REQ *  mapi_req,
struct EcDoRpc_MAPI_REPL *  mapi_repl,
uint32_t *  handles,
uint16_t *  size 
)

EcDoRpc GetPropertiesSpecific (0x07) Rop. This operation retrieves from properties data from specified object.

Parameters
mem_ctxpointer to the memory context
emsmdbp_ctxpointer to the emsmdb provider context
mapi_reqpointer to the GetPropertiesSpecific EcDoRpc_MAPI_REQ structure
mapi_replpointer to the GetPropertiesSpecific EcDoRpc_MAPI_REPL structure
handlespointer to the MAPI handles array
sizepointer to the mapi_response size to update
Returns
MAPI_E_SUCCESS on success, otherwise MAPI error

References libmapiserver_RopGetPropertiesSpecific_size(), mapi_handles_get_private_data(), and mapi_handles_search().

_PUBLIC_ enum MAPISTATUS EcDoRpc_RopGetPropertyIdsFromNames ( TALLOC_CTX *  mem_ctx,
struct emsmdbp_context *  emsmdbp_ctx,
struct EcDoRpc_MAPI_REQ *  mapi_req,
struct EcDoRpc_MAPI_REPL *  mapi_repl,
uint32_t *  handles,
uint16_t *  size 
)

EcDoRpc GetPropertyIdsFromNames (0x56) Rop. This operation gets property IDs for specified property names.

Parameters
mem_ctxpointer to the memory context
emsmdbp_ctxpointer to the emsmdb provider context
mapi_reqpointer to the GetPropertyIdsFromNames EcDoRpc_MAPI_REQ structure
mapi_replpointer to the GetPropertyIdsFromNames EcDoRpc_MAPI_REPL structure
handlespointer to the MAPI handles array
sizepointer to the mapi_response size to update
Returns
MAPI_E_SUCCESS on success, otherwise MAPI error

References libmapiserver_RopGetPropertyIdsFromNames_size().

_PUBLIC_ enum MAPISTATUS EcDoRpc_RopGetStreamSize ( TALLOC_CTX *  mem_ctx,
struct emsmdbp_context *  emsmdbp_ctx,
struct EcDoRpc_MAPI_REQ *  mapi_req,
struct EcDoRpc_MAPI_REPL *  mapi_repl,
uint32_t *  handles,
uint16_t *  size 
)

EcDoRpc GetStreamSize (0x5e) Rop. This operation returns the number of bytes in a stream.

Parameters
mem_ctxpointer to the memory context
emsmdbp_ctxpointer to the emsmdb provider context
mapi_reqpointer to the WriteStream EcDoRpc_MAPI_REQ structure
mapi_replpointer to the WriteStream EcDoRpc_MAPI_REPL structure
handlespointer to the MAPI handles array
sizepointer to the mapi response size to update
Returns
MAPI_E_SUCCESS on success, otherwise MAPI error

References libmapiserver_RopGetStreamSize_size(), mapi_handles_get_private_data(), and mapi_handles_search().

_PUBLIC_ enum MAPISTATUS EcDoRpc_RopOpenStream ( TALLOC_CTX *  mem_ctx,
struct emsmdbp_context *  emsmdbp_ctx,
struct EcDoRpc_MAPI_REQ *  mapi_req,
struct EcDoRpc_MAPI_REPL *  mapi_repl,
uint32_t *  handles,
uint16_t *  size 
)

EcDoRpc OpenStream (0x2b) Rop. This operation opens a property for streaming access.

Parameters
mem_ctxpointer to the memory context
emsmdbp_ctxpointer to the emsmdb provider context
mapi_reqpointer to the OpenStream EcDoRpc_MAPI_REQ structure
mapi_replpointer to the OpenStream EcDoRpc_MAPI_REPL structure
handlespointer to the MAPI handles array
sizepointer to the mapi response size to update
Returns
MAPI_E_SUCCESS on success, otherwise MAPI error

References emsmdbp_object_stream_init(), libmapiserver_RopOpenStream_size(), mapi_handles_add(), mapi_handles_get_private_data(), mapi_handles_search(), and mapi_handles_set_private_data().

_PUBLIC_ enum MAPISTATUS EcDoRpc_RopReadStream ( TALLOC_CTX *  mem_ctx,
struct emsmdbp_context *  emsmdbp_ctx,
struct EcDoRpc_MAPI_REQ *  mapi_req,
struct EcDoRpc_MAPI_REPL *  mapi_repl,
uint32_t *  handles,
uint16_t *  size 
)

EcDoRpc ReadStream (0x2c) Rop. This operation reads bytes from a stream.

Parameters
mem_ctxpointer to the memory context
emsmdbp_ctxpointer to the emsmdb provider context
mapi_reqpointer to the ReadStream EcDoRpc_MAPI_REQ structure
mapi_replpointer to the ReadStream EcDoRpc_MAPI_REPL structure
handlespointer to the MAPI handles array
sizepointer to the mapi response size to update
Returns
MAPI_E_SUCCESS on success, otherwise MAPI error

References libmapiserver_RopReadStream_size(), mapi_handles_get_private_data(), and mapi_handles_search().

_PUBLIC_ enum MAPISTATUS EcDoRpc_RopSeekStream ( TALLOC_CTX *  mem_ctx,
struct emsmdbp_context *  emsmdbp_ctx,
struct EcDoRpc_MAPI_REQ *  mapi_req,
struct EcDoRpc_MAPI_REPL *  mapi_repl,
uint32_t *  handles,
uint16_t *  size 
)

EcDoRpc SeekStream (0x2e) Rop. This operation positions the cursor in the stream.

Parameters
mem_ctxpointer to the memory context
emsmdbp_ctxpointer to the emsmdb provider context
mapi_reqpointer to the WriteStream EcDoRpc_MAPI_REQ structure
mapi_replpointer to the WriteStream EcDoRpc_MAPI_REPL structure
handlespointer to the MAPI handles array
sizepointer to the mapi response size to update
Returns
MAPI_E_SUCCESS on success, otherwise MAPI error

References libmapiserver_RopSeekStream_size(), mapi_handles_get_private_data(), and mapi_handles_search().

_PUBLIC_ enum MAPISTATUS EcDoRpc_RopSetProperties ( TALLOC_CTX *  mem_ctx,
struct emsmdbp_context *  emsmdbp_ctx,
struct EcDoRpc_MAPI_REQ *  mapi_req,
struct EcDoRpc_MAPI_REPL *  mapi_repl,
uint32_t *  handles,
uint16_t *  size 
)

EcDoRpc SetProperties (0x0a) Rop. This operation sets property values for an object.

Parameters
mem_ctxpointer to the memory context
emsmdbp_ctxpointer to the emsmdb provider context
mapi_reqpointer to the SetProperties EcDoRpc_MAPI_REQ structure
mapi_replpointer to the SetProperties EcDoRpc_MAPI_REPL structure
handlespointer to the MAPI handles array
sizepointer to the mapi_response size to update
Returns
MAPI_E_SUCCESS on success, otherwise MAPI error

References libmapiserver_RopSetProperties_size(), mapi_handles_get_private_data(), and mapi_handles_search().

_PUBLIC_ enum MAPISTATUS EcDoRpc_RopSetStreamSize ( TALLOC_CTX *  mem_ctx,
struct emsmdbp_context *  emsmdbp_ctx,
struct EcDoRpc_MAPI_REQ *  mapi_req,
struct EcDoRpc_MAPI_REPL *  mapi_repl,
uint32_t *  handles,
uint16_t *  size 
)

EcDoRpc SetStreamSize (0x2f) Rop. This operation copy messages from one folder to another.

Parameters
mem_ctxpointer to the memory context
emsmdbp_ctxpointer to the emsmdb provider context
mapi_reqpointer to the DeleteProperties EcDoRpc_MAPI_REQ structure
mapi_replpointer to the DeleteProperties EcDoRpc_MAPI_REPL structure
handlespointer to the MAPI handles array
sizepointer to the mapi_response size to update
Returns
MAPI_E_SUCCESS on success, otherwise MAPI error

References libmapiserver_RopSetStreamSize_size(), mapi_handles_get_private_data(), and mapi_handles_search().

_PUBLIC_ enum MAPISTATUS EcDoRpc_RopWriteStream ( TALLOC_CTX *  mem_ctx,
struct emsmdbp_context *  emsmdbp_ctx,
struct EcDoRpc_MAPI_REQ *  mapi_req,
struct EcDoRpc_MAPI_REPL *  mapi_repl,
uint32_t *  handles,
uint16_t *  size 
)

EcDoRpc WriteStream (0x2d) Rop. This operation writes bytes to a stream.

Parameters
mem_ctxpointer to the memory context
emsmdbp_ctxpointer to the emsmdb provider context
mapi_reqpointer to the WriteStream EcDoRpc_MAPI_REQ structure
mapi_replpointer to the WriteStream EcDoRpc_MAPI_REPL structure
handlespointer to the MAPI handles array
sizepointer to the mapi response size to update
Returns
MAPI_E_SUCCESS on success, otherwise MAPI error

References libmapiserver_RopWriteStream_size(), mapi_handles_get_private_data(), and mapi_handles_search().


Creative Commons License
Creative Commons Attribution icon Creative Commons Share Alike icon
This content is licensed under the Creative Commons
Attribution ShareAlike License v. 3.0:
http://creativecommons.org/licenses/by-sa/3.0/

openchange-2.0/apidocs/html/mapiproxy/oxcstor_8c.html000066400000000000000000001345231223057412600230730ustar00rootroot00000000000000 MAPIProxy 2.0 API Documentation
oxcstor.c File Reference

Server-side store objects routines and Rops. More...

#include "mapiproxy/dcesrv_mapiproxy.h"
#include "mapiproxy/libmapiproxy/libmapiproxy.h"
#include "mapiproxy/libmapiserver/libmapiserver.h"
#include "dcesrv_exchange_emsmdb.h"
#include <string.h>

Functions

_PUBLIC_ enum MAPISTATUS EcDoRpc_RopGetPerUserGuid (TALLOC_CTX *mem_ctx, struct emsmdbp_context *emsmdbp_ctx, struct EcDoRpc_MAPI_REQ *mapi_req, struct EcDoRpc_MAPI_REPL *mapi_repl, uint32_t *handles, uint16_t *size)
_PUBLIC_ enum MAPISTATUS EcDoRpc_RopGetPerUserLongTermIds (TALLOC_CTX *mem_ctx, struct emsmdbp_context *emsmdbp_ctx, struct EcDoRpc_MAPI_REQ *mapi_req, struct EcDoRpc_MAPI_REPL *mapi_repl, uint32_t *handles, uint16_t *size)
_PUBLIC_ enum MAPISTATUS EcDoRpc_RopGetReceiveFolder (TALLOC_CTX *mem_ctx, struct emsmdbp_context *emsmdbp_ctx, struct EcDoRpc_MAPI_REQ *mapi_req, struct EcDoRpc_MAPI_REPL *mapi_repl, uint32_t *handles, uint16_t *size)
_PUBLIC_ enum MAPISTATUS EcDoRpc_RopGetStoreState (TALLOC_CTX *mem_ctx, struct emsmdbp_context *emsmdbp_ctx, struct EcDoRpc_MAPI_REQ *mapi_req, struct EcDoRpc_MAPI_REPL *mapi_repl, uint32_t *handles, uint16_t *size)
_PUBLIC_ enum MAPISTATUS EcDoRpc_RopIdFromLongTermId (TALLOC_CTX *mem_ctx, struct emsmdbp_context *emsmdbp_ctx, struct EcDoRpc_MAPI_REQ *mapi_req, struct EcDoRpc_MAPI_REPL *mapi_repl, uint32_t *handles, uint16_t *size)
_PUBLIC_ enum MAPISTATUS EcDoRpc_RopLogon (TALLOC_CTX *mem_ctx, struct emsmdbp_context *emsmdbp_ctx, struct EcDoRpc_MAPI_REQ *mapi_req, struct EcDoRpc_MAPI_REPL *mapi_repl, uint32_t *handles, uint16_t *size)
_PUBLIC_ enum MAPISTATUS EcDoRpc_RopLongTermIdFromId (TALLOC_CTX *mem_ctx, struct emsmdbp_context *emsmdbp_ctx, struct EcDoRpc_MAPI_REQ *mapi_req, struct EcDoRpc_MAPI_REPL *mapi_repl, uint32_t *handles, uint16_t *size)
_PUBLIC_ enum MAPISTATUS EcDoRpc_RopReadPerUserInformation (TALLOC_CTX *mem_ctx, struct emsmdbp_context *emsmdbp_ctx, struct EcDoRpc_MAPI_REQ *mapi_req, struct EcDoRpc_MAPI_REPL *mapi_repl, uint32_t *handles, uint16_t *size)
_PUBLIC_ enum MAPISTATUS EcDoRpc_RopRelease (TALLOC_CTX *mem_ctx, struct emsmdbp_context *emsmdbp_ctx, struct EcDoRpc_MAPI_REQ *request, uint32_t *handles, uint16_t *size)
_PUBLIC_ enum MAPISTATUS EcDoRpc_RopSetReceiveFolder (TALLOC_CTX *mem_ctx, struct emsmdbp_context *emsmdbp_ctx, struct EcDoRpc_MAPI_REQ *mapi_req, struct EcDoRpc_MAPI_REPL *mapi_repl, uint32_t *handles, uint16_t *size)
static enum MAPISTATUS RopGetReceiveFolder (TALLOC_CTX *mem_ctx, struct emsmdbp_context *emsmdbp_ctx, struct EcDoRpc_MAPI_REQ *mapi_req, struct EcDoRpc_MAPI_REPL *mapi_repl, uint32_t *handles)
static enum MAPISTATUS RopLogon_Mailbox (TALLOC_CTX *mem_ctx, struct emsmdbp_context *emsmdbp_ctx, struct EcDoRpc_MAPI_REQ *mapi_req, struct EcDoRpc_MAPI_REPL *mapi_repl)
static enum MAPISTATUS RopLogon_PublicFolder (TALLOC_CTX *mem_ctx, struct emsmdbp_context *emsmdbp_ctx, struct EcDoRpc_MAPI_REQ *mapi_req, struct EcDoRpc_MAPI_REPL *mapi_repl)
static enum MAPISTATUS RopSetReceiveFolder (TALLOC_CTX *mem_ctx, struct emsmdbp_context *emsmdbp_ctx, struct EcDoRpc_MAPI_REQ *mapi_req, struct EcDoRpc_MAPI_REPL *mapi_repl, uint32_t *handles)

Detailed Description

Server-side store objects routines and Rops.

Function Documentation

_PUBLIC_ enum MAPISTATUS EcDoRpc_RopGetPerUserGuid ( TALLOC_CTX *  mem_ctx,
struct emsmdbp_context *  emsmdbp_ctx,
struct EcDoRpc_MAPI_REQ *  mapi_req,
struct EcDoRpc_MAPI_REPL *  mapi_repl,
uint32_t *  handles,
uint16_t *  size 
)

EcDoRpc GetPerUserGuid (0x61) Rop. This operation gets the GUID of a public folder's per-user information.

Parameters
mem_ctxpointer to the memory context
emsmdbp_ctxpointer to the emsmdb provider context
mapi_reqpointer to the GetPerUserLongTermIds EcDoRpc_MAPI_REQ
mapi_replpointer to the GetPerUserLongTermIds EcDoRpc_MAPI_REPL
handlespointer to the MAPI handles array
sizepointer to the mapi_response size to update
Returns
MAPI_E_SUCCESS on success, otherwise MAPI error

References libmapiserver_RopGetPerUserGuid_size().

_PUBLIC_ enum MAPISTATUS EcDoRpc_RopGetPerUserLongTermIds ( TALLOC_CTX *  mem_ctx,
struct emsmdbp_context *  emsmdbp_ctx,
struct EcDoRpc_MAPI_REQ *  mapi_req,
struct EcDoRpc_MAPI_REPL *  mapi_repl,
uint32_t *  handles,
uint16_t *  size 
)

EcDoRpc GetPerUserLongTermIds (0x60) Rop. This operations gets the long-term ID of a public folder that is identified by the per-user GUID of the logged on user.

Parameters
mem_ctxpointer to the memory context
emsmdbp_ctxpointer to the emsmdb provider context
mapi_reqpointer to the GetPerUserLongTermIds EcDoRpc_MAPI_REQ
mapi_replpointer to the GetPerUserLongTermIds EcDoRpc_MAPI_REPL
handlespointer to the MAPI handles array
sizepointer to the mapi_response size to update
Returns
MAPI_E_SUCCESS on success, otherwise MAPI error

References libmapiserver_RopGetPerUserLongTermIds_size().

_PUBLIC_ enum MAPISTATUS EcDoRpc_RopGetReceiveFolder ( TALLOC_CTX *  mem_ctx,
struct emsmdbp_context *  emsmdbp_ctx,
struct EcDoRpc_MAPI_REQ *  mapi_req,
struct EcDoRpc_MAPI_REPL *  mapi_repl,
uint32_t *  handles,
uint16_t *  size 
)

EcDoRpc GetReceiveFolder (0x27) Rop. This operation gets the receive folder for incoming messages of a particular message class

Parameters
mem_ctxpointer to the memory context
emsmdbp_ctxpointer to the emsmdb provider context
mapi_reqpointer to the GetReceiveFolder EcDoRpc_MAPI_REQ
mapi_replpointer to the GetReceiveFolder EcDoRpc_MAPI_REPL
handlespointer to the MAPI handles array
sizepointer to the mapi_response size to update
Returns
MAPI_E_SUCCESS on success, otherwise MAPI error

References libmapiserver_RopGetReceiveFolder_size(), and RopGetReceiveFolder().

_PUBLIC_ enum MAPISTATUS EcDoRpc_RopGetStoreState ( TALLOC_CTX *  mem_ctx,
struct emsmdbp_context *  emsmdbp_ctx,
struct EcDoRpc_MAPI_REQ *  mapi_req,
struct EcDoRpc_MAPI_REPL *  mapi_repl,
uint32_t *  handles,
uint16_t *  size 
)

EcDoRpc GetStoreState (0x63) Rop. This operation gets per-user information for a public folder.

Parameters
mem_ctxpointer to the memory context
emsmdbp_ctxpointer to the emsmdb provider context
mapi_reqpointer to the GetStoreState EcDoRpc_MAPI_REQ
mapi_replpointer to the GetStoreState EcDoRpc_MAPI_REPL
handlespointer to the MAPI handles array
sizepointer to the mapi_response size to update
Returns
MAPI_E_SUCCESS on success, otherwise MAPI error

References libmapiserver_RopGetStoreState_size().

_PUBLIC_ enum MAPISTATUS EcDoRpc_RopIdFromLongTermId ( TALLOC_CTX *  mem_ctx,
struct emsmdbp_context *  emsmdbp_ctx,
struct EcDoRpc_MAPI_REQ *  mapi_req,
struct EcDoRpc_MAPI_REPL *  mapi_repl,
uint32_t *  handles,
uint16_t *  size 
)

EcDoRpc (0x44) Rop. This operation sets or clears the message read flag.

Parameters
mem_ctxpointer to the memory context
emsmdbp_ctxpointer to the emsmdb provider context
mapi_reqpointer to the SetMessageReadFlag EcDoRpc_MAPI_REQ structure
mapi_replpointer to the SetMessageReadFlag EcDoRpc_MAPI_REPL structure
handlespointer to the MAPI handles array
sizepointer to the mapi_response size to update
Returns
MAPI_E_SUCCESS on success, otherwise MAPI error

References libmapiserver_RopIdFromLongTermId_size(), mapi_handles_get_private_data(), and mapi_handles_search().

_PUBLIC_ enum MAPISTATUS EcDoRpc_RopLogon ( TALLOC_CTX *  mem_ctx,
struct emsmdbp_context *  emsmdbp_ctx,
struct EcDoRpc_MAPI_REQ *  mapi_req,
struct EcDoRpc_MAPI_REPL *  mapi_repl,
uint32_t *  handles,
uint16_t *  size 
)

EcDoRpc Logon (0xFE) Rop. This operation logs on to a private mailbox or public folder.

Parameters
mem_ctxpointer to the memory context
emsmdbp_ctxpointer to the emsmdb provider context
mapi_reqpointer to the Logon EcDoRpc_MAPI_REQ structure
mapi_replpointer to the Logon EcDoRpc_MAPI_REPL structure the function returns
handlespointer to the MAPI handles array
sizepointer to the mapi_response size to update
Note
Users are only allowed to open their own mailbox at the moment. This limitation will be removed when significant progress have been made.
Returns
MAPI_E_SUCCESS on success, otherwise MAPI error

References emsmdbp_object_mailbox_init(), libmapiserver_RopLogon_size(), mapi_handles_add(), mapi_handles_set_private_data(), RopLogon_Mailbox(), and RopLogon_PublicFolder().

_PUBLIC_ enum MAPISTATUS EcDoRpc_RopLongTermIdFromId ( TALLOC_CTX *  mem_ctx,
struct emsmdbp_context *  emsmdbp_ctx,
struct EcDoRpc_MAPI_REQ *  mapi_req,
struct EcDoRpc_MAPI_REPL *  mapi_repl,
uint32_t *  handles,
uint16_t *  size 
)

EcDoRpc EcDoRpc_RopLongTermIdFromId (0x43) Rop.

Parameters
mem_ctxpointer to the memory context
emsmdbp_ctxpointer to the emsmdb provider context
mapi_reqpointer to the LongTermIdFromId EcDoRpc_MAPI_REQ structure
mapi_replpointer to the LongTermIdFromId EcDoRpc_MAPI_REPL structure
handlespointer to the MAPI handles array
sizepointer to the mapi_response size to update
Returns
MAPI_E_SUCCESS on success, otherwise MAPI error

References libmapiserver_RopLongTermIdFromId_size(), mapi_handles_get_private_data(), and mapi_handles_search().

_PUBLIC_ enum MAPISTATUS EcDoRpc_RopReadPerUserInformation ( TALLOC_CTX *  mem_ctx,
struct emsmdbp_context *  emsmdbp_ctx,
struct EcDoRpc_MAPI_REQ *  mapi_req,
struct EcDoRpc_MAPI_REPL *  mapi_repl,
uint32_t *  handles,
uint16_t *  size 
)

EcDoRpc ReadPerUserInformation (0x63) Rop. This operation gets per-user information for a public folder.

Parameters
mem_ctxpointer to the memory context
emsmdbp_ctxpointer to the emsmdb provider context
mapi_reqpointer to the ReadPerUserInformation EcDoRpc_MAPI_REQ
mapi_replpointer to the ReadPerUserInformation EcDoRpc_MAPI_REPL
handlespointer to the MAPI handles array
sizepointer to the mapi_response size to update
Returns
MAPI_E_SUCCESS on success, otherwise MAPI error

References libmapiserver_RopReadPerUserInformation_size().

_PUBLIC_ enum MAPISTATUS EcDoRpc_RopRelease ( TALLOC_CTX *  mem_ctx,
struct emsmdbp_context *  emsmdbp_ctx,
struct EcDoRpc_MAPI_REQ *  request,
uint32_t *  handles,
uint16_t *  size 
)

EcDoRpc Release (0x01) Rop. This operation releases an existing MAPI handle.

Parameters
mem_ctxpointer to the memory context
emsmdbp_ctxpointer to the emsmdb provider context
requestpointer to the Release EcDoRpc_MAPI_REQ
handlespointer to the MAPI handles array
sizepointer to the mapi_response size to update
Returns
MAPI_E_SUCCESS on success, otherwise MAPI error

References mapi_handles_delete().

_PUBLIC_ enum MAPISTATUS EcDoRpc_RopSetReceiveFolder ( TALLOC_CTX *  mem_ctx,
struct emsmdbp_context *  emsmdbp_ctx,
struct EcDoRpc_MAPI_REQ *  mapi_req,
struct EcDoRpc_MAPI_REPL *  mapi_repl,
uint32_t *  handles,
uint16_t *  size 
)

EcDoRpc SetReceiveFolder (0x26) Rop. This operation sets the receive folder for incoming messages of a particular message class

Parameters
mem_ctxpointer to the memory context
emsmdbp_ctxpointer to the emsmdb provider context
mapi_reqpointer to the SetReceiveFolder EcDoRpc_MAPI_REQ
mapi_replpointer to the SetReceiveFolder EcDoRpc_MAPI_REPL
handlespointer to the MAPI handles array
sizepointer to the mapi_response size to update
Returns
MAPI_E_SUCCESS on success, otherwise MAPI error

References libmapiserver_RopSetReceiveFolder_size(), and RopSetReceiveFolder().

static enum MAPISTATUS RopGetReceiveFolder ( TALLOC_CTX *  mem_ctx,
struct emsmdbp_context *  emsmdbp_ctx,
struct EcDoRpc_MAPI_REQ *  mapi_req,
struct EcDoRpc_MAPI_REPL *  mapi_repl,
uint32_t *  handles 
)
static

EcDoRpc GetReceiveFolder (0x27) Rop Internals. This routine performs the GetReceiveFolder internals.

Parameters
mem_ctxpointer to the memory context
emsmdbp_ctxpointer to the emsmdb provider context
mapi_reqpointer to the GetReceiveFolder EcDoRpc_MAPI_REQ
mapi_replpointer to the GetReceiveFolder EcDoRpc_MAPI_REPL
handlespointer to the MAPI handles array
Returns
MAPI_E_SUCCESS on success, otherwise MAPI error

References mapi_handles_get_private_data(), mapi_handles_search(), and openchangedb_get_ReceiveFolder().

Referenced by EcDoRpc_RopGetReceiveFolder().

static enum MAPISTATUS RopLogon_Mailbox ( TALLOC_CTX *  mem_ctx,
struct emsmdbp_context *  emsmdbp_ctx,
struct EcDoRpc_MAPI_REQ *  mapi_req,
struct EcDoRpc_MAPI_REPL *  mapi_repl 
)
static

Logs on a private mailbox

Parameters
mem_ctxpointer to the memory context
emsmdbp_ctxpointer to the emsmdb provider context
mapi_reqpointer to the RopLogon EcDoRpc_MAPI_REQ structure
mapi_replpointer to the RopLogon EcDoRpc_MAPI_REPL structure the function returns
Returns
MAPI_E_SUCCESS on success, otherwise MAPI error

References emsmdbp_mailbox_provision(), openchangedb_get_MailboxGuid(), openchangedb_get_MailboxReplica(), and openchangedb_get_SystemFolderID().

Referenced by EcDoRpc_RopLogon().

static enum MAPISTATUS RopLogon_PublicFolder ( TALLOC_CTX *  mem_ctx,
struct emsmdbp_context *  emsmdbp_ctx,
struct EcDoRpc_MAPI_REQ *  mapi_req,
struct EcDoRpc_MAPI_REPL *  mapi_repl 
)
static

Logs on a public folder store

Parameters
mem_ctxpointer to the memory context
emsmdbp_ctxpointer to the emsmdb provider context
mapi_reqpointer to the RopLogon EcDoRpc_MAPI_REQ structure
mapi_replpointer to the RopLogon EcDoRpc_MAPI_REPL structure that the function returns
Returns
MAPI_E_SUCCESS on success, otherwise MAPI error

References openchangedb_get_PublicFolderID(), and openchangedb_get_PublicFolderReplica().

Referenced by EcDoRpc_RopLogon().

static enum MAPISTATUS RopSetReceiveFolder ( TALLOC_CTX *  mem_ctx,
struct emsmdbp_context *  emsmdbp_ctx,
struct EcDoRpc_MAPI_REQ *  mapi_req,
struct EcDoRpc_MAPI_REPL *  mapi_repl,
uint32_t *  handles 
)
static

EcDoRpc SetReceiveFolder (0x26) Rop Internals. This routine performs the SetReceiveFolder internals.

Parameters
mem_ctxpointer to the memory context
emsmdbp_ctxpointer to the emsmdb provider context
mapi_reqpointer to the SetReceiveFolder EcDoRpc_MAPI_REQ
mapi_replpointer to the SetReceiveFolder EcDoRpc_MAPI_REPL
handlespointer to the MAPI handles array
Returns
MAPI_E_SUCCESS on success, otherwise MAPI error

References mapi_handles_get_private_data(), mapi_handles_search(), and openchangedb_set_ReceiveFolder().

Referenced by EcDoRpc_RopSetReceiveFolder().


Creative Commons License
Creative Commons Attribution icon Creative Commons Share Alike icon
This content is licensed under the Creative Commons
Attribution ShareAlike License v. 3.0:
http://creativecommons.org/licenses/by-sa/3.0/

openchange-2.0/apidocs/html/mapiproxy/oxctabl_8c.html000066400000000000000000000743701223057412600230310ustar00rootroot00000000000000 MAPIProxy 2.0 API Documentation
oxctabl.c File Reference

Table object routines and Rops. More...

#include "mapiproxy/dcesrv_mapiproxy.h"
#include "mapiproxy/libmapiproxy/libmapiproxy.h"
#include "mapiproxy/libmapiserver/libmapiserver.h"
#include "dcesrv_exchange_emsmdb.h"
#include "libmapi/libmapi_private.h"

Functions

_PUBLIC_ enum MAPISTATUS EcDoRpc_RopFindRow (TALLOC_CTX *mem_ctx, struct emsmdbp_context *emsmdbp_ctx, struct EcDoRpc_MAPI_REQ *mapi_req, struct EcDoRpc_MAPI_REPL *mapi_repl, uint32_t *handles, uint16_t *size)
_PUBLIC_ enum MAPISTATUS EcDoRpc_RopQueryPosition (TALLOC_CTX *mem_ctx, struct emsmdbp_context *emsmdbp_ctx, struct EcDoRpc_MAPI_REQ *mapi_req, struct EcDoRpc_MAPI_REPL *mapi_repl, uint32_t *handles, uint16_t *size)
_PUBLIC_ enum MAPISTATUS EcDoRpc_RopQueryRows (TALLOC_CTX *mem_ctx, struct emsmdbp_context *emsmdbp_ctx, struct EcDoRpc_MAPI_REQ *mapi_req, struct EcDoRpc_MAPI_REPL *mapi_repl, uint32_t *handles, uint16_t *size)
_PUBLIC_ enum MAPISTATUS EcDoRpc_RopResetTable (TALLOC_CTX *mem_ctx, struct emsmdbp_context *emsmdbp_ctx, struct EcDoRpc_MAPI_REQ *mapi_req, struct EcDoRpc_MAPI_REPL *mapi_repl, uint32_t *handles, uint16_t *size)
_PUBLIC_ enum MAPISTATUS EcDoRpc_RopRestrict (TALLOC_CTX *mem_ctx, struct emsmdbp_context *emsmdbp_ctx, struct EcDoRpc_MAPI_REQ *mapi_req, struct EcDoRpc_MAPI_REPL *mapi_repl, uint32_t *handles, uint16_t *size)
_PUBLIC_ enum MAPISTATUS EcDoRpc_RopSeekRow (TALLOC_CTX *mem_ctx, struct emsmdbp_context *emsmdbp_ctx, struct EcDoRpc_MAPI_REQ *mapi_req, struct EcDoRpc_MAPI_REPL *mapi_repl, uint32_t *handles, uint16_t *size)
_PUBLIC_ enum MAPISTATUS EcDoRpc_RopSetColumns (TALLOC_CTX *mem_ctx, struct emsmdbp_context *emsmdbp_ctx, struct EcDoRpc_MAPI_REQ *mapi_req, struct EcDoRpc_MAPI_REPL *mapi_repl, uint32_t *handles, uint16_t *size)
_PUBLIC_ enum MAPISTATUS EcDoRpc_RopSortTable (TALLOC_CTX *mem_ctx, struct emsmdbp_context *emsmdbp_ctx, struct EcDoRpc_MAPI_REQ *mapi_req, struct EcDoRpc_MAPI_REPL *mapi_repl, uint32_t *handles, uint16_t *size)

Detailed Description

Table object routines and Rops.

E-mail rules object routines and Rops.

Function Documentation

_PUBLIC_ enum MAPISTATUS EcDoRpc_RopFindRow ( TALLOC_CTX *  mem_ctx,
struct emsmdbp_context *  emsmdbp_ctx,
struct EcDoRpc_MAPI_REQ *  mapi_req,
struct EcDoRpc_MAPI_REPL *  mapi_repl,
uint32_t *  handles,
uint16_t *  size 
)

EcDoRpc FindRow (0x4f) Rop. This operation moves the cursor to a row in a table that matches specific search criteria.

Parameters
mem_ctxpointer to the memory context
emsmdbp_ctxpointer to the emsmdb provider context
mapi_reqpointer to the FindRow EcDoRpc_MAPI_REQ structure
mapi_replpointer to the FindRow EcDoRpc_MAPI_REPL structure
handlespointer to the MAPI handles array
sizepointer to the mapi_response size to update
Returns
MAPI_E_SUCCESS on success, otherwise MAPI error

References emsmdbp_get_contextID(), emsmdbp_is_mapistore(), libmapiserver_push_property(), libmapiserver_RopFindRow_size(), mapi_handles_get_private_data(), and mapi_handles_search().

_PUBLIC_ enum MAPISTATUS EcDoRpc_RopQueryPosition ( TALLOC_CTX *  mem_ctx,
struct emsmdbp_context *  emsmdbp_ctx,
struct EcDoRpc_MAPI_REQ *  mapi_req,
struct EcDoRpc_MAPI_REPL *  mapi_repl,
uint32_t *  handles,
uint16_t *  size 
)

EcDoRpc QueryPosition (0x17) Rop. This operation returns the location of cursor in the table.

Parameters
mem_ctxpointer to the memory context
emsmdbp_ctxpointer to the emsmdb provider context
mapi_reqpointer to the QueryPosition EcDoRpc_MAPI_REQ structure
mapi_replpointer to the QueryPosition EcDoRpc_MAPI_REPL structure
handlespointer to the MAPI handles array
sizepointer to the mapi_response size to update
Returns
MAPI_E_SUCCESS on success, otherwise MAPI error

References libmapiserver_RopQueryPosition_size(), mapi_handles_get_private_data(), and mapi_handles_search().

_PUBLIC_ enum MAPISTATUS EcDoRpc_RopQueryRows ( TALLOC_CTX *  mem_ctx,
struct emsmdbp_context *  emsmdbp_ctx,
struct EcDoRpc_MAPI_REQ *  mapi_req,
struct EcDoRpc_MAPI_REPL *  mapi_repl,
uint32_t *  handles,
uint16_t *  size 
)

EcDoRpc QueryRows (0x15) Rop. This operation retrieves rows from a table.

Parameters
mem_ctxpointer to the memory context
emsmdbp_ctxpointer to the emsmdb provider context
mapi_reqpointer to the QueryRows EcDoRpc_MAPI_REQ structure
mapi_replpointer to the QueryRows EcDoRpc_MAPI_REPL structure
handlespointer to the MAPI handles array
sizepointer to the mapi_response size to update

References libmapiserver_RopQueryRows_size(), mapi_handles_get_private_data(), and mapi_handles_search().

_PUBLIC_ enum MAPISTATUS EcDoRpc_RopResetTable ( TALLOC_CTX *  mem_ctx,
struct emsmdbp_context *  emsmdbp_ctx,
struct EcDoRpc_MAPI_REQ *  mapi_req,
struct EcDoRpc_MAPI_REPL *  mapi_repl,
uint32_t *  handles,
uint16_t *  size 
)

EcDoRpc ResetTable (0x81) Rop. This operation resets the table as follows:

  • Removes the existing column set, restriction, and sort order (ignored) from the table.
  • Invalidates bookmarks. (ignored)
  • Resets the cursor to the beginning of the table.
Parameters
mem_ctxpointer to the memory context
emsmdbp_ctxpointer to the emsmdb provider context
mapi_reqpointer to the SetColumns EcDoRpc_MAPI_REQ structure
mapi_replpointer to the SetColumns EcDoRpc_MAPI_REPL structure
handlespointer to the MAPI handles array
sizepointer to the mapi_response size to update
Returns
MAPI_E_SUCCESS on success, otherwise MAPI error

References emsmdbp_get_contextID(), emsmdbp_is_mapistore(), libmapiserver_RopResetTable_size(), mapi_handles_get_private_data(), and mapi_handles_search().

_PUBLIC_ enum MAPISTATUS EcDoRpc_RopRestrict ( TALLOC_CTX *  mem_ctx,
struct emsmdbp_context *  emsmdbp_ctx,
struct EcDoRpc_MAPI_REQ *  mapi_req,
struct EcDoRpc_MAPI_REPL *  mapi_repl,
uint32_t *  handles,
uint16_t *  size 
)

EcDoRpc SortTable (0x14) Rop. This operation establishes a filter for a table.

Parameters
mem_ctxpointer to the memory context
emsmdbp_ctxpointer to the emsmdb provider context
mapi_reqpointer to the Restrict EcDoRpc_MAPI_REQ structure
mapi_replpointer to the Restrict EcDoRpc_MAPI_REPL structure
handlespointer to the MAPI handles array
sizepointer to the mapi_response size to update
Returns
MAPI_E_SUCCESS on success, otherwise MAPI error

References emsmdbp_get_contextID(), emsmdbp_is_mapistore(), libmapiserver_RopRestrict_size(), mapi_handles_get_private_data(), and mapi_handles_search().

_PUBLIC_ enum MAPISTATUS EcDoRpc_RopSeekRow ( TALLOC_CTX *  mem_ctx,
struct emsmdbp_context *  emsmdbp_ctx,
struct EcDoRpc_MAPI_REQ *  mapi_req,
struct EcDoRpc_MAPI_REPL *  mapi_repl,
uint32_t *  handles,
uint16_t *  size 
)

EcDoRpc SeekRow (0x18) Rop. This operation moves the cursor to a specific position in a table.

Parameters
mem_ctxpointer to the memory context
emsmdbp_ctxpointer to the emsmdb provider context
mapi_reqpointer to the SeekRow EcDoRpc_MAPI_REQ structure
mapi_replpointer to the SeekRow EcDoRpc_MAPI_REPL structure
handlespointer to the MAPI handles array
sizepointer to the mapi_response size to update
Returns
MAPI_E_SUCCESS on success, otherwise MAPI error

References libmapiserver_RopSeekRow_size(), mapi_handles_get_private_data(), and mapi_handles_search().

_PUBLIC_ enum MAPISTATUS EcDoRpc_RopSetColumns ( TALLOC_CTX *  mem_ctx,
struct emsmdbp_context *  emsmdbp_ctx,
struct EcDoRpc_MAPI_REQ *  mapi_req,
struct EcDoRpc_MAPI_REPL *  mapi_repl,
uint32_t *  handles,
uint16_t *  size 
)

EcDoRpc SetColumns (0x12) Rop. This operation sets the properties to be included in the table.

Parameters
mem_ctxpointer to the memory context
emsmdbp_ctxpointer to the emsmdb provider context
mapi_reqpointer to the SetColumns EcDoRpc_MAPI_REQ structure
mapi_replpointer to the SetColumns EcDoRpc_MAPI_REPL structure
handlespointer to the MAPI handles array
sizepointer to the mapi_response size to update
Returns
MAPI_E_SUCCESS on success, otherwise MAPI error

References emsmdbp_get_contextID(), emsmdbp_is_mapistore(), libmapiserver_RopSetColumns_size(), mapi_handles_get_private_data(), and mapi_handles_search().

_PUBLIC_ enum MAPISTATUS EcDoRpc_RopSortTable ( TALLOC_CTX *  mem_ctx,
struct emsmdbp_context *  emsmdbp_ctx,
struct EcDoRpc_MAPI_REQ *  mapi_req,
struct EcDoRpc_MAPI_REPL *  mapi_repl,
uint32_t *  handles,
uint16_t *  size 
)

EcDoRpc SortTable (0x13) Rop. This operation defines the order of rows of a table based on sort criteria.

Parameters
mem_ctxpointer to the memory context
emsmdbp_ctxpointer to the emsmdb provider context
mapi_reqpointer to the SortTable EcDoRpc_MAPI_REQ structure
mapi_replpointer to the SortTable EcDoRpc_MAPI_REPL structure
handlespointer to the MAPI handles array
sizepointer to the mapi_response size to update
Returns
MAPI_E_SUCCESS on success, otherwise MAPI error

References emsmdbp_get_contextID(), emsmdbp_is_mapistore(), libmapiserver_RopSortTable_size(), mapi_handles_get_private_data(), mapi_handles_search(), and openchangedb_table_set_sort_order().


Creative Commons License
Creative Commons Attribution icon Creative Commons Share Alike icon
This content is licensed under the Creative Commons
Attribution ShareAlike License v. 3.0:
http://creativecommons.org/licenses/by-sa/3.0/

openchange-2.0/apidocs/html/mapiproxy/oxomsg_8c.html000066400000000000000000000544321223057412600227060ustar00rootroot00000000000000 MAPIProxy 2.0 API Documentation
oxomsg.c File Reference

Server-side message routines and Rops. More...

#include "mapiproxy/libmapiserver/libmapiserver.h"
#include "dcesrv_exchange_emsmdb.h"

Functions

_PUBLIC_ enum MAPISTATUS EcDoRpc_RopGetAddressTypes (TALLOC_CTX *mem_ctx, struct emsmdbp_context *emsmdbp_ctx, struct EcDoRpc_MAPI_REQ *mapi_req, struct EcDoRpc_MAPI_REPL *mapi_repl, uint32_t *handles, uint16_t *size)
_PUBLIC_ enum MAPISTATUS EcDoRpc_RopGetTransportFolder (TALLOC_CTX *mem_ctx, struct emsmdbp_context *emsmdbp_ctx, struct EcDoRpc_MAPI_REQ *mapi_req, struct EcDoRpc_MAPI_REPL *mapi_repl, uint32_t *handles, uint16_t *size)
_PUBLIC_ enum MAPISTATUS EcDoRpc_RopOptionsData (TALLOC_CTX *mem_ctx, struct emsmdbp_context *emsmdbp_ctx, struct EcDoRpc_MAPI_REQ *mapi_req, struct EcDoRpc_MAPI_REPL *mapi_repl, uint32_t *handles, uint16_t *size)
_PUBLIC_ enum MAPISTATUS EcDoRpc_RopSetSpooler (TALLOC_CTX *mem_ctx, struct emsmdbp_context *emsmdbp_ctx, struct EcDoRpc_MAPI_REQ *mapi_req, struct EcDoRpc_MAPI_REPL *mapi_repl, uint32_t *handles, uint16_t *size)
_PUBLIC_ enum MAPISTATUS EcDoRpc_RopSubmitMessage (TALLOC_CTX *mem_ctx, struct emsmdbp_context *emsmdbp_ctx, struct EcDoRpc_MAPI_REQ *mapi_req, struct EcDoRpc_MAPI_REPL *mapi_repl, uint32_t *handles, uint16_t *size)
_PUBLIC_ enum MAPISTATUS EcDoRpc_RopTransportSend (TALLOC_CTX *mem_ctx, struct emsmdbp_context *emsmdbp_ctx, struct EcDoRpc_MAPI_REQ *mapi_req, struct EcDoRpc_MAPI_REPL *mapi_repl, uint32_t *handles, uint16_t *size)

Detailed Description

Server-side message routines and Rops.

Function Documentation

_PUBLIC_ enum MAPISTATUS EcDoRpc_RopGetAddressTypes ( TALLOC_CTX *  mem_ctx,
struct emsmdbp_context *  emsmdbp_ctx,
struct EcDoRpc_MAPI_REQ *  mapi_req,
struct EcDoRpc_MAPI_REPL *  mapi_repl,
uint32_t *  handles,
uint16_t *  size 
)

EcDoRpc GetAddressTypes (0x49) Rop. This operation gets the valid address types (e.g. "SMTP", "X400", "EX")

Parameters
mem_ctxpointer to the memory context
emsmdbp_ctxpointer to the emsmdb provider context
mapi_reqpointer to the AddressTypes EcDoRpc_MAPI_REQ
mapi_replpointer to the AddressTypes EcDoRpc_MAPI_REPL
handlespointer to the MAPI handles array
sizepointer to the mapi_response size to update
Returns
MAPI_E_SUCCESS on success, otherwise MAPI error

References libmapiserver_RopGetAddressTypes_size().

_PUBLIC_ enum MAPISTATUS EcDoRpc_RopGetTransportFolder ( TALLOC_CTX *  mem_ctx,
struct emsmdbp_context *  emsmdbp_ctx,
struct EcDoRpc_MAPI_REQ *  mapi_req,
struct EcDoRpc_MAPI_REPL *  mapi_repl,
uint32_t *  handles,
uint16_t *  size 
)

EcDoRpc GetTransportFolder (0x6d) ROP.

Parameters
mem_ctxpointer to the memory context
emsmdbp_ctxpointer to the emsmdb provider context
mapi_reqpointer to the GetTransportFolder EcDoRpc_MAPI_REQ
mapi_replpointer to the GetTransportFolder EcDoRpc_MAPI_REPL
handlespointer to the MAPI handles array
sizepointer to the mapi_response size to update
Returns
MAPI_E_SUCCESS on success, otherwise MAPI error

References libmapiserver_RopGetTransportFolder_size(), mapi_handles_get_private_data(), mapi_handles_search(), and openchangedb_get_TransportFolder().

_PUBLIC_ enum MAPISTATUS EcDoRpc_RopOptionsData ( TALLOC_CTX *  mem_ctx,
struct emsmdbp_context *  emsmdbp_ctx,
struct EcDoRpc_MAPI_REQ *  mapi_req,
struct EcDoRpc_MAPI_REPL *  mapi_repl,
uint32_t *  handles,
uint16_t *  size 
)

EcDoRpc OptionsData (0x6f) Rop. This doesn't really do anything, but could be used to provide HelpData if we wanted to do something like that later.

Parameters
mem_ctxpointer to the memory context
emsmdbp_ctxpointer to the emsmdb provider context
mapi_reqpointer to the OptionsData EcDoRpc_MAPI_REQ
mapi_replpointer to the OptionsData EcDoRpc_MAPI_REPL
handlespointer to the MAPI handles array
sizepointer to the mapi_response size to update
Returns
MAPI_E_SUCCESS on success, otherwise MAPI error

References libmapiserver_RopOptionsData_size().

_PUBLIC_ enum MAPISTATUS EcDoRpc_RopSetSpooler ( TALLOC_CTX *  mem_ctx,
struct emsmdbp_context *  emsmdbp_ctx,
struct EcDoRpc_MAPI_REQ *  mapi_req,
struct EcDoRpc_MAPI_REPL *  mapi_repl,
uint32_t *  handles,
uint16_t *  size 
)

EcDoRpc SetSpooler (0x47) Rop. This operation informs the server that the client intends to act as a mail spooler

Parameters
mem_ctxpointer to the memory context
emsmdbp_ctxpointer to the emsmdbp provider context
mapi_reqpointer to the SeSpooler EcDoRpc_MAPI_REQ
mapi_replpointer to the SetSpooler EcDoRpc_MAPI_REPL
handlespointer to the MAPI handles array
sizepointer to the mapi_response size to update
Returns
MAPI_E_SUCCESS on success, otherwise MAPI error

References libmapiserver_RopSetSpooler_size().

_PUBLIC_ enum MAPISTATUS EcDoRpc_RopSubmitMessage ( TALLOC_CTX *  mem_ctx,
struct emsmdbp_context *  emsmdbp_ctx,
struct EcDoRpc_MAPI_REQ *  mapi_req,
struct EcDoRpc_MAPI_REPL *  mapi_repl,
uint32_t *  handles,
uint16_t *  size 
)

EcDoRpc SubmitMessage (0x32) Rop. This operation marks a message as being ready to send (subject to some flags).

Parameters
mem_ctxpointer to the memory context
emsmdbp_ctxpointer to the emsmdb provider context
mapi_reqpointer to the SubmitMessage EcDoRpc_MAPI_REQ structure
mapi_replpointer to the SubmitMessage EcDoRpc_MAPI_REPL structure
handlespointer to the MAPI handles array
sizepointer to the mapi_response size to update
Returns
MAPI_E_SUCCESS on success, otherwise MAPI error

References emsmdbp_get_contextID(), emsmdbp_get_owner(), emsmdbp_is_mapistore(), libmapiserver_RopSubmitMessage_size(), mapi_handles_get_private_data(), and mapi_handles_search().

_PUBLIC_ enum MAPISTATUS EcDoRpc_RopTransportSend ( TALLOC_CTX *  mem_ctx,
struct emsmdbp_context *  emsmdbp_ctx,
struct EcDoRpc_MAPI_REQ *  mapi_req,
struct EcDoRpc_MAPI_REPL *  mapi_repl,
uint32_t *  handles,
uint16_t *  size 
)

EcDoRpc TransportSend (0x4a) Rop. This operation sends a message.

Parameters
mem_ctxpointer to the memory context
emsmdbp_ctxpointer to the emsmdb provider context
mapi_reqpointer to the TransportSend EcDoRpc_MAPI_REQ structure
mapi_replpointer to the TransportSend EcDoRpc_MAPI_REPL structure
handlespointer to the MAPI handles array
sizepointer to the mapi_response size to update
Returns
MAPI_E_SUCCESS on success, otherwise MAPI error

References emsmdbp_get_contextID(), emsmdbp_is_mapistore(), libmapiserver_RopTransportSend_size(), mapi_handles_get_private_data(), and mapi_handles_search().


Creative Commons License
Creative Commons Attribution icon Creative Commons Share Alike icon
This content is licensed under the Creative Commons
Attribution ShareAlike License v. 3.0:
http://creativecommons.org/licenses/by-sa/3.0/

openchange-2.0/apidocs/html/mapiproxy/pages.html000066400000000000000000000046631223057412600221000ustar00rootroot00000000000000 MAPIProxy 2.0 API Documentation
Related Pages
Here is a list of all related documentation pages:

Creative Commons License
Creative Commons Attribution icon Creative Commons Share Alike icon
This content is licensed under the Creative Commons
Attribution ShareAlike License v. 3.0:
http://creativecommons.org/licenses/by-sa/3.0/

openchange-2.0/apidocs/html/mapiproxy/pixel_grey.gif000066400000000000000000000000531223057412600227360ustar00rootroot00000000000000GIF89a€îîî!ù,D;openchange-2.0/apidocs/html/mapiproxy/structEphemeralEntryID.html000066400000000000000000000051051223057412600253770ustar00rootroot00000000000000 MAPIProxy 2.0 API Documentation
EphemeralEntryID Struct Reference

EphemeralEntryID structure. More...

#include <dcesrv_exchange_nsp.h>

Detailed Description

EphemeralEntryID structure.


The documentation for this struct was generated from the following file:
  • mapiproxy/servers/default/nspi/dcesrv_exchange_nsp.h

Creative Commons License
Creative Commons Attribution icon Creative Commons Share Alike icon
This content is licensed under the Creative Commons
Attribution ShareAlike License v. 3.0:
http://creativecommons.org/licenses/by-sa/3.0/

openchange-2.0/apidocs/html/mapiproxy/structPermanentEntryID.html000066400000000000000000000051051223057412600254260ustar00rootroot00000000000000 MAPIProxy 2.0 API Documentation
PermanentEntryID Struct Reference

PermanentEntryID structure. More...

#include <dcesrv_exchange_nsp.h>

Detailed Description

PermanentEntryID structure.


The documentation for this struct was generated from the following file:
  • mapiproxy/servers/default/nspi/dcesrv_exchange_nsp.h

Creative Commons License
Creative Commons Attribution icon Creative Commons Share Alike icon
This content is licensed under the Creative Commons
Attribution ShareAlike License v. 3.0:
http://creativecommons.org/licenses/by-sa/3.0/

openchange-2.0/apidocs/html/mapiproxy/structmpm__stream.html000066400000000000000000000046271223057412600245510ustar00rootroot00000000000000 MAPIProxy 2.0 API Documentation
mpm_stream Struct Reference

A stream can either be for a message or attachment. More...

#include <mpm_cache.h>

Detailed Description

A stream can either be for a message or attachment.


The documentation for this struct was generated from the following file:
  • mapiproxy/modules/mpm_cache.h

Creative Commons License
Creative Commons Attribution icon Creative Commons Share Alike icon
This content is licensed under the Creative Commons
Attribution ShareAlike License v. 3.0:
http://creativecommons.org/licenses/by-sa/3.0/

openchange-2.0/apidocs/html/mapiproxy/sync_off.png000066400000000000000000000015251223057412600224210ustar00rootroot00000000000000‰PNG  IHDRàw=øIDATxíÝKhTWÀñÿä1I&3™8M¦Iš™†I3Ú©b$cÌ I1V1±-(Tö±±Ð.* t!‚K[¥Ä¥ˆ„¨´f£`l(øl©"Y”¤6ÆgÌTú}·sgîܹ ±d{8?æÌ¹÷;çÜuíÚ`:!±F¬¢BäŠ?ŰÄm'yÊÅ>ÑlU¯½üý‰è_‹?€Œê ]€Y(ŠNñ±8fý1°Öqún-eâ¨øtºmâÈ Ó0}b›ù%·©µ×Œ®=Ÿ0´³?Š1sŸ‹0€¯8À‘;_ ‹W|%\ Zð— >舽ln¨p©.aÇ{ )t;Ú b nŸš¯›65°¢¡2çÅÔ?Žž>Oдàuönm¤¢Ì`×­Z¬WjC~>‘Ö¾0+á {{©fÝ×Mæ·æÅ•ìÙ¼˜` Ý›%uA6´½ÅÆö¨Á,]k¢ÄW¼™u±›]‹ˆ7§¯iòh€ ¶¶¬ÏÖu1 ló —Ҷ̺–:ÞÍ\ÄcãÏxøhR²Êè‡Qt$¿ß§¨ ª fdºü<4BÿÙ[•f¸d7=.Mé9/—éªÃëù/ÿO Üaàò}€,‘j?Ÿõ.5Úšm?œÿŸ®ŽXÿ2¬#¸d píæ(£?cÛú¼!½›a1¥Þ—ŽòØ©ܾ7dÔK:‚ùÒ‰ì)Ê3‚Ü™àÌà]€,±H€µ+køöäu<|`·LhC7¹ÔeÍ Ÿ×Ÿ˜tÜ‹ óH$^2%l.êaeÐäýE”ÌÉ|ÅÜìî‰Ýsä }¸ýDû^hzé~ðR›¦Ã¡¿]|#ü¯@×—Ö‡[k¹–<|š(Ç*€Ý¹dÇtMé:Ýñø«Ø,êÅû¢]”' øXÓ_nò¡Æ|Øý /c§fžâOIEND®B`‚openchange-2.0/apidocs/html/mapiproxy/sync_on.png000066400000000000000000000015151223057412600222620ustar00rootroot00000000000000‰PNG  IHDRàw=øIDATxíÝ_HTYÀñï8ã¤ó§i§4-g6ÆËÕ&kQ)¨Ô!Š0ÒURKÚ…„ê¡/»PEÁ>ìK-+KÁ²Ñ.Y”¾dEPaA‰ø°¥¶›ZSÓïÜ;3wºŠ–¯—߯gfîïœsçœWKÇñ.€ÉøD­¨a‘'¬âq_ôˆk¢ÀŒ ÀDŽøQ´ÄïC¨¶åñÏÿgÅ ñ 0„Y‚:qZ¦Á)~õâ€èLý0HVñ× žz-¿‰C“%¨g¦˜6€é8%Úõ¬ëwêÙUÏ¿˜ª³Ä }? ?€·3ÀÀž©Š À”K• @hà a±ðaÇæUe‹ sù~ë2²ì“&Ú&B*AÄljæºììi*˨,Ëçí»÷oÆ£T”,d[˜¼3-*ÁÀ…>å‡Ë çLÉŸçfk˜Ò éw#*AEjKUy>ûšËÉõ&{µ¢8—m5Ki¬ jjƒD*¿NŽÖigwÃ7Dª’mz骹úKÛ¾±ˆ¶M!æ¤ÍkÐ?šoý¬_åÓlXí#Ò~–¸¬ê×ÒÑXŠÓ‘ùRÙ*Eû‚ՂדðEÜ;6«e"Q(²Ù=–¿Ezæ5Kؼָ_ 1òzBªJë ±XŒì96åªjL^7{ùãJÑ÷1½i@%8'7M©_\Qœ#ÓUŒËñýÿyõ Wo Éx8¼s¥v¯ªì|×SnÜ q_m Ýé î>bèÕí[JX,½4[Tú{R£ë¼ôˆ¾þa€tÝjjzzÅ'ÅìȶiIžŽòwÏs ¡€—ÕKøõâC^ŽŒ˜Y­¨µÉ%6¨´êˆº]vÛðhâ½iWv–hôëê°Ò¨¾'æÌ‚·ñ|[ßìúÅ^€YrD=<ýDû]äÇ÷s€Ïõ‹8™ºCì? À ¨—t4õᩎ¡Jã‡W‹É± îr¼cjMɘìx| šE©øNÔ‰œøA¢þ«–€Z¼ñ‡jó î#™§¢¢4gIEND®B`‚openchange-2.0/apidocs/html/mapiproxy/tab_a.png000066400000000000000000000002161223057412600216550ustar00rootroot00000000000000‰PNG  IHDR$ÇÇ[UIDATxíK €0C'o¤(Šˆ[Žà%Üxÿ#Ù©­ç ùÁöó¦W¦e# 3t I 3+¼øEã~\D½9¯Ûàè’wM·¿öÿ}Yõ_êA4Yžã}IEND®B`‚openchange-2.0/apidocs/html/mapiproxy/tab_b.png000066400000000000000000000002471223057412600216620ustar00rootroot00000000000000‰PNG  IHDR$ÇÇ[nIDATxíÝQ Â0„áàœR¥Xc±I7IÓ¨g|òÕÙœäãgY˜3˜Ï÷‡u{£ÔW—ÊSíŒ1Ü ¼CjˆiC†G¬ýççJ+| ÖÝs7ùŒ+Ù›`t‚3Ü‚a¢K¤Gq°ûQÍZÝT=@*éC݇LIEND®B`‚openchange-2.0/apidocs/html/mapiproxy/tab_h.png000066400000000000000000000003001223057412600216560ustar00rootroot00000000000000‰PNG  IHDR$ÇÇ[‡IDATxíÝË ‚@EÑ 7êÂX’Ñø AADùjGü€ Z€e؈£ ë8¹›—Wƒx¾ÞìUK.µ%„0mɤ&+4iÑ$džÈt“׿ÍzWf5AZá'w¼øÆ"2¶Wœðòg%öªdæ)æþ™ÉR15F®dìž ÉБßO«×Áô»C"à@¯g=IEND®B`‚openchange-2.0/apidocs/html/mapiproxy/tab_s.png000066400000000000000000000002701223057412600216770ustar00rootroot00000000000000‰PNG  IHDR$ÇÇ[IDATxíÝ ‚@@Ñ£?Q…¤"š¢%¦I‘—Šf–6[´HÃäQƒ<Þâõþ]ždr Í’s?ˆO=Ñññw'ÌF‡Ž íðö-~rÃ[œèŠ­ì¬mƒÖ¬ƒݯнŠÕF)Yº% §`nÌ,9B ™’©!ÑŒ\ý<Å#üîî•IEND®B`‚openchange-2.0/apidocs/html/mapiproxy/tabs.css000066400000000000000000000022131223057412600215430ustar00rootroot00000000000000.tabs, .tabs2, .tabs3 { background-image: url('tab_b.png'); width: 100%; z-index: 101; font-size: 13px; font-family: 'Lucida Grande',Geneva,Helvetica,Arial,sans-serif; } .tabs2 { font-size: 10px; } .tabs3 { font-size: 9px; } .tablist { margin: 0; padding: 0; display: table; } .tablist li { float: left; display: table-cell; background-image: url('tab_b.png'); line-height: 36px; list-style: none; } .tablist a { display: block; padding: 0 20px; font-weight: bold; background-image:url('tab_s.png'); background-repeat:no-repeat; background-position:right; color: #283A5D; text-shadow: 0px 1px 1px rgba(255, 255, 255, 0.9); text-decoration: none; outline: none; } .tabs3 .tablist a { padding: 0 10px; } .tablist a:hover { background-image: url('tab_h.png'); background-repeat:repeat-x; color: #fff; text-shadow: 0px 1px 1px rgba(0, 0, 0, 1.0); text-decoration: none; } .tablist li.current a { background-image: url('tab_a.png'); background-repeat:repeat-x; color: #fff; text-shadow: 0px 1px 1px rgba(0, 0, 0, 1.0); } openchange-2.0/apidocs/html/mapiproxy/userdoc.png000066400000000000000000000022531223057412600222560ustar00rootroot00000000000000‰PNG  IHDRàw=ørIDATH‰•VßkGÿÌìÌÎÞÞ®wIËÙ*6F¤9é¯C@_$-m BñMh}ÊS¥¥P(¥¥–úô¡‹}ðMTˆ‚Ô¶&Zc ˜ÄR/ôõÎÜÝÞîÎìLtLrV?°/ßa>ŸÏw¾?X‚ÿÁÜÜÓZÇñ”1æCù›sþ=¥ôÇC‡é§Ý'ý®]»FÇ)DQtN1^©Tàº. Óé Ñh I’sBˆGGGe?º]pff†0ÆhEß …ñ½{÷¢X,‚B|ßǾ}û „˜ìõz_>-ƒm”RĶíá8Ž?ÚµkÙš(¥»wïFÇŸ\½zµò\iš"Žã Çq缯;ÇqÀ9Q?³À™3gHÇDkýJ_æ­††ú±ÍcÇŽéùóçÎ9Œ1RBJ cÌ#W”‚1Î9¢(B’$­gȆáïI’@J ¥”RH’`Û6@k à8Îýx¶­Ácüš$ÉòÊÊJN–e`Œ!KKKPJÍ=ztî¹<Ïs]×ýeaa>çœs0ÆÀCX\\D±X¼réÒ¥W/_¾¼íLm NOO¿†á§Œ±w|ßçÝnkkk¨V«Ø³g`uu·o߯þýûáû>Â0ÄÆÆFCñC¡PøöðáÃÛ \¸pá+˲>&ùsܽ{7oÞDǵg­VÃÐÐP>#RJÜ»wõz}©T*ÕŸ¸xñ⇄Ÿkµ,ËÊE1ÐZ#Ill<2¶cÇŽü©6a½^Ç;w¦'''ßËfggÙúúúâÁƒ‡³}ó<0Æ MSB@)ÅÌÌ (¥£³laa1ÆŽ$I2ìº.Œ1y·d»çiÄYv½^”R¸®‹;wbmmí€YV©T^X^^/‹R"Š"h­ÁƒeY°,k‹PFœÍG†PJR B<ÏCEoKÓ´·¾¾þúÈÈ:ºÝ.Œ1Bä"ÙÅ,;­5Ò4Í )¥ µÎ͸®‹(ŠÞvëÖ­øÁƒopÎÑn·Ñjµ`Û6¤”OgHÓJ)H)‘¦iO’¶mƒ!,Ë*Ÿ={öeÖh4F„n–jð}?ïŒ~üø?yõNŸ>ýAÇßh­_ó<Õj®ë¶í|=o†”qc~~ÍfB(¥V‹ÅâSSS?Û,»S§N½E)}ŸR“RPJ½àEJ)ÏVÈãzIMÿZ–µBùËs…1öÛÉ“'ó_™ÿÒJ:—©Ôy¨IEND®B`‚openchange-2.0/apidocs/html/mapitest/000077500000000000000000000000001223057412600177005ustar00rootroot00000000000000openchange-2.0/apidocs/html/mapitest/24px-Cc-by_white.svg.png000066400000000000000000000053061223057412600241400ustar00rootroot00000000000000‰PNG  IHDR°çá»bKGDÿÿÿÿÿÿ X÷Ü pHYsHHFÉk> IDATXýXmP”U¾vˆeY pW$gQH–%ãËc*$åÃIkFmiØ‘ttrê‡C öa3 Œc†D$ e¬±X, «@³ Â.Èîõþy›uÓ÷·÷úóÌœçÜϹîëºçÜç<þxHØNÛNÛN½+zWô®.–_,¿X|»æÛ5ß® Q†(C`4F#p×ý®û]w@qRqRqðÿÎÿ;ÿcaÇÂŽIÅIÅIÅ@˜$L&Ämâ6qÛòÀ‡Ä-í-í--ùVë[­oµ’ <. … ¡B¨øSRT(*’’IŽ$‡”æHs¤9¤S’S’S‰ð>°Ï÷ˆôˆôˆ$Óôiú4=Ù2Ú2Ú2JZ•V¥Uù`^‚û9À3<Ã3À7ýßôÓl?Ø~°¸ªºªºªœ‡œ‡œ‡€ 6Øpx&õ™ÔgR0—0—0ÀMá¦pSB©P*”–õ–õ–õ@²GÙ£šª›ª›ª¦mMÛš¶#êõˆðj÷j÷jöeïËÞ— äÎäÎäÎÒ^i¯´÷að£ýȳégÓϦ“K{–ö,í±+¦êRu©ºÈŠÎŠÎŠNòöÔí©ÛSë£sñsñsñd{^{^{™u%ëJÖÒÅÛÅÛÅ›IER‘”ÔìÕìÕì%ÇSÇSÇS~gAuuu¤|µ|µ|5)øJð•à+rGËŽ–-äÀ±cÇþs‚å)ËS–§ÈÒ-¥[J·ž»=w{î&µ‚ZA-™÷BÞ y/³£³£³£‹$psäæÈÍR•¨JT%ÚßñýŽïw|OšÌ&³Éü¿'þWX­ÖFòÔ“§ž<õ$é6â6â6Bºæ»æ»æ“ÕÕÕ÷&°Ÿû¹Ÿ<”p(áP‚xxQxQxyëÀ­·üóÄÿŠùçœÿ‘Ô®Ô®Ô®´óŠx.⹈çÈÁÎÁÎÁN7ŽÜ8rã¹æÙ5Ï®y–tŠwŠwŠ'+++ÿÿÄÿŠã€qÀH¿üzðë¤(H$ "‹4Eš" ) ø0àÀ:³ñÌÆ3··7à é é  pNwNwN¦º¦º¦º€ZS­©Ö\K¹–r-èÎíÎíΆg†g†gOgOgOgÀ˜bL1¦õâzq½XÒ·¤oI SÊ”2%033TÿQýGõ€h§h§h'àëëkßdÜÜÝÜÝ܉sç&Î õ õ õÀ¸iÜ4n°uÕÖU[WÙ-*4š ©õ^^^r¹Ãr‡å¤S•S•SéêêJºMºMºM’»rwåîÊ%ûûûIE¤"RIîÙ¼góžÍäÜÆ¹sÉý'öŸØ‚”'Êå‰dÛ–¶-m[îï„N£Óè4¤ÇÛo{¼MŠä"¹HN {]z]z]Ñ:Ñ:Ñ:@¥T)UÊE¶Û!q¸k¾k¾k2e™²LÐÛÛ ¤½Ÿö~ÚûÀ¥ÉK“—&ÿVÿVÿV c.c.c¨­­Ê®•]+»œK>—|.ˆÔDj"5@[t[t[4 _ª_ª_ºpýÕΫW;>Y>Y>Y€õwëïÖ߈§ÄSâ)R'‰“Ä‘Í7›o6ß\¨€Ál0̤¼SÞ)ï$ƒR‚R‚RÈ—3_Î|9“ô³øYü,dÒ¤I7H‹ŸÅÏâGöÕôÕôÕAùAùAù¤Ä 1H dÈùó!çɲÀ²À²@R\".—Å?ÿTüÓÂõïîîÈ(×(×(W{Åç:æ:æ:¡£ÐQèˆÒDi¢´E:žAª U L©§ÔSj`$a$a$pLvLvL†¶mÚ VVV~‰~‰~‰À®_wýºëWÀrÄrÄrÈPf(3”ÀóåÏ—?_|ôÉGŸ|ô ·!nC܆E–o4 šQ¨(Tj*ŠÅŠb`V2+™•o‹·Å{±– ‚€5Ôj Ò­éÖt+P¡þBý ðzáõÂë@÷+ݯt¿èôú{x`c`c`#à~Úý´ûi À` °K>_òù’ϵ«ÚUí È5r\³È!2Ï–g˦ççÃïy}9úrôe»%%×K®—\_¤„ú }†>R!UHRò1ŸÇ|ó!ãZãZãZIe´2ZM.»³ìβ;d{{{¿=¾á†7Þ =.x\ð¸@Ö)ë”uJ²¥­¥­¥\öȲG–=B~œúqêÇ‹z²{²{²Iß}¾û|÷ÝSBª¯U_«¾¶'ÔTßTßTÌý6÷ÛÜoöqéyéyéyàÅÒK_,ÔoªßT¿ xj=µžZ F#‘'kOÖž¬B2B2B2ìñò+ò+ò+ÀK›^ÚôÒ&@Þ!ïw2³Ì,3¿Düñ  ($ ÉBt't't'€Á̓›7+›V6­lÐÜÜL>ŠGñ(Hï×¼_ó~¼úóÕŸ¯þ|5¬a iK±¥ØRH[€-À@Ú²mÙ¶l’{¸‡{þ¦#íænî&mkmkmkIÆ1Žq$ýéOÒ*° ¬Òö¥íKÛ—ö°™’™’™2ùpòáäÃvås r r H˜½Ì^f/r[Ö¶¬mYö Y]Y]Y]¤ùóæþávû7¨\W¹®r)žψgHŸ­>[}¶’º]‰®äžÃ\K]K]KéuÉë’×%Rü©øSñ§di|i|i#FQ`$c¼b¼b¼ÈŽ‹;.Þ_€^êg3f3f3Èʵ•k+×’êUêUêU¤Ãr‡åËIÇq'=4 ¹~lýØú12*+*+*‹ŒÍÍÍ'Ueª2Uéû®ï»¾ï’!!!v¥W„­[FjõZ½VO' ' '<ØÁ‡þ+ñ'†††È¢²¢²¢22\® ב2™ƒÌNèAOßbßbßb2Ç%Ç%Ç…ÔéuzžœŸŸx>ÿ^5¡–ü+^:tEXtComment Created with Inkscape (http://www.inkscape.org/) ã+ldIEND®B`‚openchange-2.0/apidocs/html/mapitest/24px-Cc-sa_white.svg.png000066400000000000000000000053061223057412600241310ustar00rootroot00000000000000‰PNG  IHDR°çá»bKGDÿÿÿÿÿÿ X÷Ü pHYsHHFÉk> IDATXÕX}LÓW>¿ ´–.Ôb±‚" Cèê(lS„9ÉuN&n ʹŒ,+&+™“à&3[a`Ë$™ãs‰3Ö¨L(ŠX¸Åñá¬EÄ4ElK¡åyÿy÷–¼µ/¾çŸ›ÜsŸsžûœÓ{· þmô”¶ðà?¬Y3²†èBý…ú õD—7\ÞpyÑpâpâp"‘Ñh4DóÏÌ?3ÿ QPmPmP-QØoa¿…ýFw"îDÜ ¢ŒÊŒÊŒJ¢8n7ŽKäwÃï†ß§eCDxJ3›ŠMÅÀgW?»úÙU ‚‰`"€Ä bý#À>Ê>Ê> p ¸Ü€WÀ+àË3–g,Ïèú†¾q¯Ø°%` ===è&tº ÀéŠtE.Í‹ñVœÁœ!ºxçâ‹wˆ>5|jøÔ@Ô#ë‘õȈ|Ç|Ç|Lj^,z±èÅ"¢m»·íÞ¶›(Žljãùùù±x,‹G4;;K499IÔÞÚÞÚÞJÔ¾§}Oû"s‚9Áœ@$4 BQa~a~a>Ñ!Û!Û!o„7Âyš ¬Çz¬ßi|§ñ`ÕЪ¡UCnÅdý²~Y?ÐÔ×Ô×ÔLÍLÍLÍÂGø8¶ãØŽc;ÜÄãËãËãËS‘©ÈTäxÏ®ž]=»€Wv^Ùy´ Z­SÏÔ3õ‹~Ü&¶‰mÄ_‰¿ ;v( 05›šMÍžqÝÎng7P¼¶xmñZwœ—^éõ—^îõÝë»×Ð`é`é`)°áµ ¯mx Xž²äeò2y™'ñA„ B”ØJl%6 nUݪºU€*Z­ŠÄÄÄ“Ïä3€å[Ë·–o½ãq·qØkÝkÝkõl¥ÏÕŸ«?W{Â?~< $®H\‘¸Â½Þg®w®w®—ˆ³Œ³Œ³ŒˆÍÎfgQuQ—§¯È_‘¿"'Ò˜5f™Hë¯õ×úûëØ_Çþ"âïçïçïÿß.ëi=­'ò©õ©õ©õtϧϧϧ{Î3LÓAÄ–²¥l)éHG:"VPePeP%‘ƒëà:¸D³³³ÞóOØ'ìv¢Õ©«SW§åìËÙ—³È,7ËÍr"G…£ÂQá?—7—7—G4ùóäÏ“?{ú\WÀõœ_P-¨TDÖxk¼5~‘ckçÖέî’TýQõGÕÞ;à|Öù¬óY@ÀÉ€“'Þ:Þ:Þ:@œ&N§cccÞñÝ‚nA·ý$úIô“;/š?ÍŸtƒºAÝN¡¡ü¡ü¡| ¤0¤0¤pQë}RôIÑ'¯³¾ÎúpŒ9ÆO 2Z3Z3ZÄŒ9s㇓w%ïJ޴ŶŶÅwDwDwDÀÅ÷/¾ñ}`Ëw[¾Ûò'îÍóožó<`}×ú®õ]ϼgfÏÌž™XZ––¥Ö¶¯m_ÛP‡¤CÒ!$ ~ø!ÐógÏŸ=zW²V]«®Uœ:N§n¡(Š¢(À?Ê?Ê? Í Í Íxž…gñ$ê u…º€®³]g»Îzæ±UÙªlU€¼D^"/Yto¨ Ôj€ìB»Ð.ö(ö(ö(Ü ýŠ~E?`ï²wÙ»<;„¡ChÞм¡y±D,ë 7ò¬V +Ø”»)wS.pI}I}Ií]¨æèæèæhÀÏægó³Á™Á™Á™€¾J_¥¯Zô1§Óê´:- ¼"¼"¼ø}ï÷½ß÷@uJuJu àZp-¸<8wþîü0ì7ì7ìJ5¥šR ùwæß™ÛÓ·§oOÞî|»óíNà”ñ”ñ”ý–ý€~@Äì‹Ù³Ï-@qqq?° ].HmÀ5åšrMǧOŸXm¬6V°²deÉÊàtÆéŒÓ€óWç¯Î_½'F ZÐ8ßs¾ç|˜+Ÿ+Ÿ+\®W€ILbÒ;ü¦ô¦ô¦ØÜ°¹asƒ›xÒñ¤ãIÇñeãËÆ—¹×{¼   ¥F©QjV:+•ð[ø-ü@=®W÷ÎÝ;wïÜÒ„–2[Ž-Ç–4O7O7O76nlt—<”<”<zózózó<ñ^ßÄ–dK²%PVVx¾<_ž/À\b.1—I¶$[’ |Éÿ’ÿ%Ðwê;õÀdÅdÅd` ³†YÃk‹µÅÚÌlÙ:³>0|`øP¯®W׫ù«òWå¯Ü:n·`ŒŒ‘1IÂ$a’è½Ð{¡÷‚w–|Ô;ö:ö:öÍÏ7?ßü<šš øˆ}Ä>b€4¤!   P(ØÉØÉØI Q‘¨HTÉG’$d5²Y r2ädÈIÀçŸ|^p+½&nMÜš8 x x xß1¾c|ÇÒ|ê%þ±±gÇž{(¯)¯)¯âõñúx=àÃ÷áûð—>…þC*C*C*N§€èôúÀ™âLq¦<=ŸYΧюéÈ:tEXtComment Created with Inkscape (http://www.inkscape.org/) ã+ldIEND®B`‚openchange-2.0/apidocs/html/mapitest/CC_SomeRightsReserved.png000066400000000000000000000064521223057412600245460ustar00rootroot00000000000000‰PNG  IHDRZ¬a x pHYs  šœtIMEÕ ÌIðbKGDÿÿÿ ½§“ ·IDATx^í™iŒUEÇû¾{ßÚÝ6ë"²Š‚@!`˜DÇ¡Ä "Œ2 ×%Æ(ê—D£ñƒ1¨â’Œ@Pƒ¢HezXš¦é†¶~¯ßrç÷ïÜêyV¼ 1í„VòçÔz«þuêÔ¹÷9%¿Nr@$Bd\ºP¤Ç¤KˆÒ•HD€’È|² È h‘,Ò›= lœ)Ò›Íøí´2$Ù"ír«,n¤…˜Õ?À+B¸4d¤à `d‘ž—Þ†vL‘_‰h×&By#Äl ,‹OHIÚyû¤Ø°N‡¤g¡èäÒùnÑ‹0 g­Kë!í i6IÁ¶dËŠ…‚bÉFÝ?Ÿ-ÚŠ°áÙ–eÈO&“‰gŸ}vä–-[¦œ8qâŽ\.7çÌ™3Ó÷ìÙ3áý÷ß¿büøñÝdÉňÅb©Ç{lÐ÷ßÿ‡ãÇÏ ÏÜæææ¿8p`ÎòåË+§L™ÒËz– {®ƒö½´Ú?Å­cݦ[e‰â²áÇw]¶lÙ´¾}ûBfxrçfÞ_|±»bÅŠ!ƒ *ÿ}]xÍÒ’V™OŸï ¤­{–.¸Xrì“O>ù“!yûöí 7ß|óêT*õwÊÖ<óÌ3ûNž<™S]±%Óg˜!yóæÍM7ÞxãÚÒÒÒ¥lÀâW^yeÝéÓ§3ª3Ï q5nHÞÎW‹ŽXVœ ½ÄŒ/¾øâè|p¢Ø·o_ãСC¿J§Ó­‘ˆÁ€Ê>ûì³—^ziµÚÍŸ?¿âÕW_í!}çΧG޹9“ÉüÄZ9%.}*{öì¹ð,–kK»¬p>Z´‰s£[å6\ÉÊÊÊ¡f€—_~ù_±#“½{÷:|ÈlÒ­·ÞÚÁôyþùç Ù³ýð¶mÛÒ¼È ýG2$ïXh—äµ?Ñá °7£OŸ>ÝÍøéc¶»Q+êp±ú˜é³råÊûb³78¶ 1Ë@Îï8ڱɷõb²ñÑqÓøÈ‘#9Ûê‹`ÜI²¢¢¢mîÇŽioŠÉ ß\#C²†óÐu„è>ˆ„µÃU´˜L÷îÝcöÆXäy Ååè›>;wöl²Î‘<'l íî:|ßïÐ^ƒmܸÑûâ‹/R555‰£G&!#ÉÍŸjiiI€$~4‘ÍfS<3U(ù|>!YWW÷Ã%—\ÒScÜvÛm=Þyçã´ñ€ "À´a¤<²y×®]±Ñ£G»êsÓM7¥/^|š0γD"qd©)D£Ñ‚ëº>(ñ<Ï!ïÁD€KÄâ^pÁ^×®]½þýûGG»æšk²í壎hÿ—ì&t¯ºêªDÇŽSç/‰ü1Á DB„Cr²“È/ñï¾û®Ú=oÞ¼Á«V­Ú€•»l‚ ’ýnݺ9o½õVçIˆË}ùå—ˆ.UŸ‡z¨ÓºuëWsvIž€ï/ýõ×õÒò7òˆ|P"‚ãñx+ɉDB$ srª¢½{÷Ž:êtåI¿”§VKqöÆç>8dF°4Y³‡èä©S§â”'xÃK@r\0dƒ¸ÈfÑ©×^{m . \ãa_¸pa͆ 2eee¥×]w]§Ù³gwÁÚ´‘GÔF$}øá‡{õêå)_UUuúÍ7߬ٺuë:uÊOœ8±ãÔ©SB^ ‹ÿ+äf »b3œ¡:@†x= Ùiü~¦C‡é.]º¤ÙØ QN3ýE´c‘z.ût Ñã• 'ôÜwÒœC‡űæ8¯Ã²è˜ˆ†ä¸¬ZRD$Çò²êaX—ûî»od—…ÎÜ÷Kn¸á†ƒÈV]ÀêܧŸ~ºë…^;[Ÿ»îºk‘!¤A‹ò\ÂÑ­`#Óll Va61­S`Nz8ܧžzêrë±Ñ%amŠÛâE`)$¤°ž$H±¨V“ÿMqEJÒYd î¯]»¶™§Øƒÿ›P¨¯¯ÏàN¾ñÆGñë9Ú°´zvÍš5M¸™,㔀ˆéÓØØxŠ7ÌÚ?þx#d·@bIyy¹ƒŒX¯ "Pç"=ê$]¤GY4„#Ût›3ÆG;ç°3þ9„>>ĉ´$DuAZ ×!b£" –%G%!$J[å¥{HwQ © ô­KQÒEF°´¶èEV òëׯo¤_=$çØì2+ g±È,® Ɔ—°yÅ £ e¾Ñ6/ÊI?%&)’€hî£ëtt´^~ä}‘Œlõ딹ä[A>á’Q ’uZZ@–òlȧÒPÂmiÝ1”àp_ä‡í¤Êb<‘*²Ñ•$[‰ HÑ’Ê»"2% Éå!URd;"8€X³’¤A„ä—ä{$‘/QˆDIr³Áüäzb¤2«r…ƒg#ÖÒC91á]…UîôIaÖl„N^£+ŽÕÊÛˆ’Fò’&/˜ÐN1´¤±nG©Øª€acÝH§ØºE0R¹²æ"Œ/=t?´¡`.ÄšM:«±àDæÎ;ž[ÎsÏ=7’ ©O¿~ýoûh#Øåy›6mêÅGšÞ¯{T¦~Lêµ½þúë')o±^N})Ÿ9ï Þüî»ï*ÔJ¦HcÇŽ­ä¢Ià³Ëˆ›¯ tÅÇû¡„V1.¢èôéÓ/G÷„Ûo¿}0Ò%Vî?cÆŒA?üpß%K–t&Bé‡/¯Ï&JP[éJÖ¼ûþùç=xNœ‹-~íµ×þž—¡±<çwšÃK/½4Œ²Ê÷Þ{oëÓúèÞξ¥s eKu¤¦M›¶öJW;AþLõÒ L×°Œpn¹üŸ1WCBšèá«Ã‡¯¡,W]]ý-ñmý#zTܨêŠ]ª)ã›ù)Þ./“.‹Þüõ×_ïâm*Ë—³²œÊ£ó Ü|°wÑ¢E²¦¶zŽHžÎ°ÓÊÛàRÛ*ÿ©yŽì¼*^`ªd‘¼Ììfü<ñî>\×q^:²lÈA¬þ ãØ"H¯­­=Ì‹Pý ’K—.=¦·?Œ¢^yÕ ¤Z¾›R‘Ìiiâ µ«Ý¯2æšÁ5œàÌ.>­V3FÒªpaÛ5Oꛃµl1ëÓéxüñÇkUÆÿ’UãÆ;‰;Ép¯l ã@ÙŠèý úÉ'Ÿlš5kÖIÞós¼Å€”ê=zäT/BL;£•W Ê[¨D*ǹŽ;@ãÖæRúa&œƒ˜zȯg¬ßEØ€£ÒqeÇ8ÒÒ% I—ظ33gÎLKW½ú©þ»‰gæÉ7˜ñ±ò:=bk™GíO%ƒŽñ}CãÙQQ mEõLŽzÏÌ«LÏ4m!ÚçBup›)½ä´­Å¬¿ÃÊÇá.è7±ÏÅáCŒÏDýÝ»wûJøÈVië,ºµíœ9s|;Ùí¹©}.Ÿ”aŒ>dû,ÆçHZ}Btk¾çöL{®öv}ø8Òq¡¡˜²!C†ø&Lðq]¾DÿÊé7üFôÿÿj|w‚%&IEND®B`‚openchange-2.0/apidocs/html/mapitest/annotated.html000066400000000000000000000076341223057412600225550ustar00rootroot00000000000000 MAPITests 2.0 API Documentation
Data Structures
Here are the data structures with brief descriptions:
oCmapitestThe context structure for a mapitest run
oCmapitest_statmapitest statistics
oCmapitest_suiteA list of test suites
oCmapitest_testA list of mapitest tests
oCmapitest_unitList of test names
\Cmt_common_tf_ctxContext for mapitest test folder

Creative Commons License
Creative Commons Attribution icon Creative Commons Share Alike icon
This content is licensed under the Creative Commons
Attribution ShareAlike License v. 3.0:
http://creativecommons.org/licenses/by-sa/3.0/

openchange-2.0/apidocs/html/mapitest/apidocs.css000066400000000000000000000362151223057412600220430ustar00rootroot00000000000000/* ** WEBSITE ** */ BODY,H1,H2,H3,H4,H5,H6,P,CENTER,TD,TH,UL,DL,DIV { font-family: Geneva, Arial, Helvetica, sans-serif; } BODY,TD { font-size: 90%; } H1 { text-align: center; font-size: 160%; } H2 { font-size: 19px; font-weight: bold; color: #3E93D5; } H3 { font-size: 100%; } P { text-align: justify; } LI { li-style-type: square; li-style-position: outside; display: list-item; } CAPTION { font-weight: bold } DIV.qindex { width: 100%; background-color: #e8eef2; border: 1px solid #84b0c7; text-align: center; margin: 2px; padding: 2px; line-height: 140%; } DIV.nav { width: 100%; background-color: #e8eef2; border: 1px solid #84b0c7; text-align: center; margin: 2px; padding: 2px; line-height: 140%; } DIV.navtab { background-color: #e8eef2; border: 1px solid #84b0c7; text-align: center; margin: 2px; margin-right: 15px; padding: 2px; } TD.navtab { font-size: 70%; } A.qindex { text-decoration: none; font-weight: bold; color: #1A419D; } A.qindex:visited { text-decoration: none; font-weight: bold; color: #1A419D } A.qindex:hover { text-decoration: none; background-color: #ddddff; } A.qindexHL { text-decoration: none; font-weight: bold; background-color: #6666cc; color: #ffffff; border: 1px double #9295C2; } A.qindexHL:hover { text-decoration: none; background-color: #6666cc; color: #ffffff; } A.qindexHL:visited { text-decoration: none; background-color: #6666cc; color: #ffffff } A.el { text-decoration: none; font-weight: bold } A.elRef { font-weight: bold } A.code:link { text-decoration: none; font-weight: normal; color: #0000FF} A.code:visited { text-decoration: none; font-weight: normal; color: #0000FF} A.codeRef:link { font-weight: normal; color: #0000FF} A.codeRef:visited { font-weight: normal; color: #0000FF} A:hover { text-decoration: none; background-color: #f2f2ff } DL.el { margin-left: -1cm } .fragment { font-family: monospace, fixed; font-size: 95%; } PRE.fragment { border: 1px solid #CCCCCC; background-color: #f5f5f5; font-size: 11px; margin-top: 4px; margin-bottom: 4px; margin-left: 2px; margin-right: 8px; padding-left: 6px; padding-right: 6px; padding-top: 4px; padding-bottom: 4px; } DIV.ah { background-color: black; font-weight: bold; color: #ffffff; margin-bottom: 3px; margin-top: 3px } DIV.groupHeader { margin-left: 16px; margin-top: 12px; margin-bottom: 6px; font-weight: bold; } DIV.groupText { margin-left: 16px; font-style: italic; font-size: 90% } BODY { background: white; color: black; margin-right: 20px; margin-left: 20px; } TD.indexkey { background-color: #e8eef2; font-weight: bold; padding-right : 10px; padding-top : 2px; padding-left : 10px; padding-bottom : 2px; margin-left : 0px; margin-right : 0px; margin-top : 2px; margin-bottom : 2px; border: 1px solid #CCCCCC; } TD.indexvalue { background-color: #e8eef2; font-style: italic; padding-right : 10px; padding-top : 2px; padding-left : 10px; padding-bottom : 2px; margin-left : 0px; margin-right : 0px; margin-top : 2px; margin-bottom : 2px; border: 1px solid #CCCCCC; } TR.memlist { background-color: #f0f0f0; } P.formulaDsp { text-align: center; } IMG.formulaDsp { } IMG.formulaInl { vertical-align: middle; } SPAN.keyword { color: #008000 } SPAN.keywordtype { color: #604020 } SPAN.keywordflow { color: #e08000 } SPAN.comment { color: #800000 } SPAN.preprocessor { color: #806020 } SPAN.stringliteral { color: #002080 } SPAN.charliteral { color: #008080 } .mdescLeft { padding: 0px 8px 4px 8px; font-size: 80%; font-style: italic; background-color: #FAFAFA; border-top: 1px none #E0E0E0; border-right: 1px none #E0E0E0; border-bottom: 1px none #E0E0E0; border-left: 1px none #E0E0E0; margin: 0px; } .mdescRight { padding: 0px 8px 4px 8px; font-size: 80%; font-style: italic; background-color: #FAFAFA; border-top: 1px none #E0E0E0; border-right: 1px none #E0E0E0; border-bottom: 1px none #E0E0E0; border-left: 1px none #E0E0E0; margin: 0px; } .memItemLeft { padding: 1px 0px 0px 8px; margin: 4px; border-top-width: 1px; border-right-width: 1px; border-bottom-width: 1px; border-left-width: 1px; border-top-color: #E0E0E0; border-right-color: #E0E0E0; border-bottom-color: #E0E0E0; border-left-color: #E0E0E0; border-top-style: solid; border-right-style: none; border-bottom-style: none; border-left-style: none; background-color: #FAFAFA; font-size: 80%; } .memItemRight { padding: 1px 8px 0px 8px; margin: 4px; border-top-width: 1px; border-right-width: 1px; border-bottom-width: 1px; border-left-width: 1px; border-top-color: #E0E0E0; border-right-color: #E0E0E0; border-bottom-color: #E0E0E0; border-left-color: #E0E0E0; border-top-style: solid; border-right-style: none; border-bottom-style: none; border-left-style: none; background-color: #FAFAFA; font-size: 80%; } .memTemplItemLeft { padding: 1px 0px 0px 8px; margin: 4px; border-top-width: 1px; border-right-width: 1px; border-bottom-width: 1px; border-left-width: 1px; border-top-color: #E0E0E0; border-right-color: #E0E0E0; border-bottom-color: #E0E0E0; border-left-color: #E0E0E0; border-top-style: none; border-right-style: none; border-bottom-style: none; border-left-style: none; background-color: #FAFAFA; font-size: 80%; } .memTemplItemRight { padding: 1px 8px 0px 8px; margin: 4px; border-top-width: 1px; border-right-width: 1px; border-bottom-width: 1px; border-left-width: 1px; border-top-color: #E0E0E0; border-right-color: #E0E0E0; border-bottom-color: #E0E0E0; border-left-color: #E0E0E0; border-top-style: none; border-right-style: none; border-bottom-style: none; border-left-style: none; background-color: #FAFAFA; font-size: 80%; } .memTemplParams { padding: 1px 0px 0px 8px; margin: 4px; border-top-width: 1px; border-right-width: 1px; border-bottom-width: 1px; border-left-width: 1px; border-top-color: #E0E0E0; border-right-color: #E0E0E0; border-bottom-color: #E0E0E0; border-left-color: #E0E0E0; border-top-style: solid; border-right-style: none; border-bottom-style: none; border-left-style: none; color: #606060; background-color: #FAFAFA; font-size: 80%; } .search { color: #003399; font-weight: bold; } FORM.search { margin-bottom: 0px; margin-top: 0px; } INPUT.search { font-size: 75%; color: #000080; font-weight: normal; background-color: #e8eef2; } TD.tiny { font-size: 75%; } a { color: #1A41A8; } a:visited { color: #2A3798; } .dirtab { padding: 4px; border-collapse: collapse; border: 1px solid #84b0c7; } TH.dirtab { background: #e8eef2; font-weight: bold; } HR { height: 1px; border: none; border-top: 1px solid black; margin-bottom: 50px; } /* Style for detailed member documentation */ .memtemplate { font-size: 80%; color: #606060; font-weight: normal; } .memnav { background-color: #e8eef2; border: 1px solid #84b0c7; text-align: center; margin: 2px; margin-right: 15px; padding: 2px; } .memitem { padding: 4px; background-color: white; border-width: 1px; border-style: solid; border-color: #ccc; -moz-border-radius: 8px 8px 8px 8px; margin-bottom: 30px; } .memname { white-space: nowrap; font-weight: bold; font-size: 12px; margin: 10px 10px 10px 10px; } .memname EM { color: #45417e; } .memdoc{ padding-left: 10px; padding-right: 10px; } .memdoc EM, TD { font-size: 12px; } .memproto { background-color: #e9e9f4; width: 100%; border-width: 1px; border-style: solid; border-color: #ccc; font-weight: bold; -moz-border-radius: 8px 8px 8px 8px; } .paramkey { text-align: right; } .paramtype { white-space: nowrap; } .paramname { color: #602020; font-style: italic; white-space: nowrap; } /* End Styling for detailed member documentation */ /* for the tree view */ .ftvtree { font-family: sans-serif; margin:0.5em; } .directory { font-size: 9pt; font-weight: bold; } .directory h3 { margin: 0px; margin-top: 1em; font-size: 11pt; } .directory > h3 { margin-top: 0; } .directory p { margin: 0px; white-space: nowrap; } .directory div { display: none; margin: 0px; } .directory img { vertical-align: -30%; } #website { width: 820px; height: 100%; margin-left: auto; margin-right: auto; text-align: left; /* IE hack */ * position: absolute; * left: 50%; * margin-left: -410px; } /* ** HEADER ** */ .header { height: 200px; background: url(header.jpg) no-repeat top center; } body { background: #fff url(body_top_bg2.jpg) top left repeat-x; font-family: Arial, Trebuchet MS, Tahoma, Verdana, Helvetica, sans-serif; font-size: 11px; line-height: 17px; color: #444; color: #3a3a3a; fdpadding-top: 15px; text-align: center; background-color: #fbfbfb; } h1 { font: 24px bold Trebuchet MS, Arial; color: #FFF; padding: 0; margin: 0; } /* ** MIDDLE SIDE ** */ #middle_side { display: block; height: 100%; width: 800px; margin-top: 7px; backsground: url(middle_bg.jpg) top left repeat-x; background-color: #fbfbfb; } /* left and right side */ #left_side { background-color: #fff; clear: both; margin-bottom: 10px; border-bottom: 1px solid #eee; border-left: 1px solid #eee; border-right: 1px solid #eee; -moz-border-radius: 0 0 8px 8px; height: 29px; } /* ** MENU HORIZONTAL ** */ /************ Global Navigation *************/ DIV.tabs { float : left; width : 100%; background : url("tab_b.gif") repeat-x bottom; margin-top : 10px; margin-bottom : 4px; } DIV.tabs ul { margin : 0px; padding-left : 10px; list-style : none; } DIV.tabs li { display : inline; margin : 0px; padding : 0px; } DIV.tabs A { float : left; background : url("tab_r.gif") no-repeat right top; border-bottom : 1px solid #84B0C7; font-size : x-small; font-weight : bold; text-decoration : none; } DIV.tabs A:link, .tabs A:visited, DIV.tabs A:active, .tabs A:hover { color: #1A419D; } DIV.tabs SPAN { float : left; display : block; background : url("tab_l.gif") no-repeat left top; padding : 5px 10px; white-space : nowrap; } DIV.tabs TD { font-size : x-small; font-weight : bold; text-decoration : none; } /* Commented Backslash Hack hides rule from IE5-Mac \*/ DIV.tabs SPAN {float : none;} /* End IE5-Mac hack */ DIV.tabs A:hover SPAN { background-position: 0% -150px; } DIV.tabs LI.current A { background-position: 100% -150px; border-width : 0px; } DIV.tabs LI.current SPAN { background-position: 0% -150px; padding-bottom : 6px; } DIV.nav { background : none; border : none; border-bottom : 1px solid #84B0C7; } #right_side_home { font-family: "Lucida Grande", Arial, Verdana, sans-serif; background-color: white; padding: 0px 20px; border: 1px solid #ebebeb; border: 1px solid #ddd; -moz-border-radius: 10px 10px; width: 750px; * width: 800px; * margin-left: 0px; padding-bottom: 10px; } #right_side_home td { line-height: 17px; margin: 0 0 5px 0; padding: 10px 0 15px 7px display: table-cell; border-spacing: 2px 2px; vertical-align: middle; text-align: left; border-bottom: 1px solid #EEEEEE; } #right_side_home td h2, a.anchor { font-size: 19px; font-weight: bold; color: #3E93D5; } #right_side_home td.indexkey { border-bottom: none; } #right_side_home li { list-style-position: inside; valign: middle; } TD.indexkey { background-color: #e8eef2; font-size : 12px; font-weight : bold; padding-right : 10px; padding-top : 2px; padding-left : 10px; padding-bottom : 2px; margin-left : 0px; margin-right : 0px; margin-top : 2px; margin-bottom : 2px; border : 1px solid #CCCCCC; } TD.indexvalue { background-color: #e8eef2; font-style : italic; font-size : 12px; padding-right : 10px; padding-top : 2px; padding-left : 10px; padding-bottom : 2px; margin-left : 0px; margin-right : 0px; margin-top : 2px; margin-bottom : 2px; border : 1px solid #CCCCCC; } TR.memlist { background-color: #f0f0f0; } .mdescLeft { padding: 0px 8px 4px 8px; font-size: 80%; font-style: italic; background-color: #FAFAFA; border-top: 1px none #E0E0E0; border-right: 1px none #E0E0E0; border-bottom: 1px none #E0E0E0; border-left: 1px none #E0E0E0; margin: 0px; } .mdescRight { padding: 0px 8px 4px 8px; font-size: 80%; font-style: italic; background-color: #FAFAFA; border-top: 1px none #E0E0E0; border-right: 1px none #E0E0E0; border-bottom: 1px none #E0E0E0; border-left: 1px none #E0E0E0; margin: 0px; } .memItemLeft { padding: 1px 0px 0px 8px; margin: 4px; border-top-width: 1px; border-right-width: 1px; border-bottom-width: 1px; border-left-width: 1px; border-top-color: #E0E0E0; border-right-color: #E0E0E0; border-bottom-color: #E0E0E0; border-left-color: #E0E0E0; border-top-style: solid; border-right-style: none; border-bottom-style: none; border-left-style: none; background-color: #FAFAFA; font-size: 80%; } .memItemRight { padding: 1px 8px 0px 8px; margin: 4px; border-top-width: 1px; border-right-width: 1px; border-bottom-width: 1px; border-left-width: 1px; border-top-color: #E0E0E0; border-right-color: #E0E0E0; border-bottom-color: #E0E0E0; border-left-color: #E0E0E0; border-top-style: solid; border-right-style: none; border-bottom-style: none; border-left-style: none; background-color: #FAFAFA; font-size: 80%; } .memTemplItemLeft { padding: 1px 0px 0px 8px; margin: 4px; border-top-width: 1px; border-right-width: 1px; border-bottom-width: 1px; border-left-width: 1px; border-top-color: #E0E0E0; border-right-color: #E0E0E0; border-bottom-color: #E0E0E0; border-left-color: #E0E0E0; border-top-style: none; border-right-style: none; border-bottom-style: none; border-left-style: none; background-color: #FAFAFA; font-size: 80%; } .memTemplItemRight { padding: 1px 8px 0px 8px; margin: 4px; border-top-width: 1px; border-right-width: 1px; border-bottom-width: 1px; border-left-width: 1px; border-top-color: #E0E0E0; border-right-color: #E0E0E0; border-bottom-color: #E0E0E0; border-left-color: #E0E0E0; border-top-style: none; border-right-style: none; border-bottom-style: none; border-left-style: none; background-color: #FAFAFA; font-size: 80%; } .memTemplParams { padding: 1px 0px 0px 8px; margin: 4px; border-top-width: 1px; border-right-width: 1px; border-bottom-width: 1px; border-left-width: 1px; border-top-color: #E0E0E0; border-right-color: #E0E0E0; border-bottom-color: #E0E0E0; border-left-color: #E0E0E0; border-top-style: solid; border-right-style: none; border-bottom-style: none; border-left-style: none; color: #606060; background-color: #FAFAFA; font-size: 80%; } code { display: block; width: 100%; border: 1px solid #ccc; background-color: #e8edf3; padding-top: 10px; padding-bottom: 10px; padding-left: 5px; padding-right: 5px; margin-bottom: 10px; margin-top: 10px; } openchange-2.0/apidocs/html/mapitest/bc_s.png000066400000000000000000000012501223057412600213120ustar00rootroot00000000000000‰PNG  IHDR /ð9ÐoIDATxíMLAÇßìN»»¥ívKùPJik±R5^ŒChÂŃ!Dzƒ *U4VƒbÄD1~`8xà@ˆ^¿?ð𤡸Ý@јÝná`JLLÝØ¦ƒÜXi v«9ê)·}aV±&Ò0)›¼ð(‰zÛküNcFPÛù'@é¨KZK%!13§5£}Ý€ÒdÀã°’>´Åç´çhï¹G…ÉZ ïz×Ú—Éi£“ì–º=…@O¹«È‚1Ó¯¦3ãF«[ºä’d²¾JÒã`|^3˜Ý\›¿¡]²ó•'fçÓùyˆÄîçâÙ@¥Cos˧d:?$lhûnÝ× nm\†$cÔL6Ñý »Ì´x@N¦oPÀ®Î‘òÕ”€GÔ÷>9¹¨Q@ã±á“.‡qŠÜ´¼°Ø ”PCt(á«yŒQ$±°hÔNý8¤¥Ë MNjÿ$þßþŲo_ƒsLIEND®B`‚openchange-2.0/apidocs/html/mapitest/bdwn.png000066400000000000000000000002231223057412600213350ustar00rootroot00000000000000‰PNG  IHDR5åZIDATxíË € DŸP–1ñlžmÀ r±j².e è†D[ØÉ¾ÙÏÔ¼µ¦ã´Þ|陣6€Všë3´Å?Ls'(}¬>+ žKó÷¥¿ch`‚ ^׃ÞnIEND®B`‚openchange-2.0/apidocs/html/mapitest/body_top_bg2.jpg000066400000000000000000000006541223057412600227600ustar00rootroot00000000000000ÿØÿàJFIFddÿìDuckydÿîAdobedÀÿÛ„ÿÀ–ÿÄh að¡q‘QáR’¢ð!‘1aQÿÚ ?Ô¢±Õœ|W¼ í|ua³Dbe­‚hŒ*ø VÁ&ÅrV¹´,¸^Â-~TbÁÐéÊ—=©xj䮤*ÿRb²r %7L‘ñÜŠ¶5ø¦ èªÞV¶ ÿÙopenchange-2.0/apidocs/html/mapitest/classes.html000066400000000000000000000062721223057412600222320ustar00rootroot00000000000000 MAPITests 2.0 API Documentation

Creative Commons License
Creative Commons Attribution icon Creative Commons Share Alike icon
This content is licensed under the Creative Commons
Attribution ShareAlike License v. 3.0:
http://creativecommons.org/licenses/by-sa/3.0/

openchange-2.0/apidocs/html/mapitest/closed.png000066400000000000000000000002041223057412600216530ustar00rootroot00000000000000‰PNG  IHDR à‘KIDATxíÝm @!†ÑGk™É7À-`&séts¦Àñþòð@åk}ª2€… P%Á_Ëþ¿N² .:0Dk¥‹Â›x" Ö›)¡xÒ5õIEND®B`‚openchange-2.0/apidocs/html/mapitest/dir_0dca20aea40c40a954fff3a7948754aa.html000066400000000000000000000203201223057412600261230ustar00rootroot00000000000000 MAPITests 2.0 API Documentation
modules Directory Reference

Files

file  mapitest.doxy
file  module_errorchecks.c
 Error / sanity-check path tests.
file  module_lcid.c
 Language Code checks (MS-LCID)
file  module_lzxpress.c
 LZXPRESS compression and decompression test suite.
file  module_mapidump.c
 mapidump function tests
file  module_noserver.c
 Non connection oriented tests.
file  module_nspi.c
 NSPI tests.
file  module_oxcfold.c
 Folder Object Protocol test suite.
file  module_oxcfxics.c
 Bulk Data Transfer Protocol test suite.
file  module_oxcmsg.c
 Message and Attachment Object Protocol test suite.
file  module_oxcnotif.c
 Core Notifications Protocol test suite.
file  module_oxcperm.c
 Permissions Protocol test suite.
file  module_oxcprpt.c
 Property and Stream Object Protocol test suite.
file  module_oxcstor.c
 Store Object Protocol test suite.
file  module_oxctable.c
 Table Object Protocol test suite.
file  module_oxomsg.c
 E-Mail Object Protocol test suite.
file  module_oxorule.c
 E-Mail Rules Protocol test suite.

Creative Commons License
Creative Commons Attribution icon Creative Commons Share Alike icon
This content is licensed under the Creative Commons
Attribution ShareAlike License v. 3.0:
http://creativecommons.org/licenses/by-sa/3.0/

openchange-2.0/apidocs/html/mapitest/dir_cbdb8362360e11eafe2fa3bc74cf0ffd.html000066400000000000000000000045031223057412600264310ustar00rootroot00000000000000 MAPITests 2.0 API Documentation
utils Directory Reference

Directories

directory  mapitest

Creative Commons License
Creative Commons Attribution icon Creative Commons Share Alike icon
This content is licensed under the Creative Commons
Attribution ShareAlike License v. 3.0:
http://creativecommons.org/licenses/by-sa/3.0/

openchange-2.0/apidocs/html/mapitest/dir_e0b450741923cfc7aff431a9234e11bf.html000066400000000000000000000122121223057412600257650ustar00rootroot00000000000000 MAPITests 2.0 API Documentation
mapitest Directory Reference

Directories

directory  modules

Files

file  mapitest.c
 Core of mapitest implementation.
file  mapitest.h
 Data structures for mapitest.
file  mapitest_common.c
 Support functions for mapitest modules.
file  mapitest_print.c
 Print / display functions for mapitest output.
file  mapitest_proto.h
file  mapitest_stat.c
 mapitest statistics functions
file  mapitest_suite.c
 mapitest test suite functions
file  module.c
file  proto.h

Creative Commons License
Creative Commons Attribution icon Creative Commons Share Alike icon
This content is licensed under the Creative Commons
Attribution ShareAlike License v. 3.0:
http://creativecommons.org/licenses/by-sa/3.0/

openchange-2.0/apidocs/html/mapitest/doxygen.png000066400000000000000000000073031223057412600220660ustar00rootroot00000000000000‰PNG  IHDRh ;ˆØŠIDATxí]y\•Õº~45%TL Q”PE"q–Û11±]8a„w*©¨(*â" ˆzÀè`8 ¨‰¢mÅ,’òà„p$%”œBó(8k†Ü÷ýÜû6lòö»§k÷Ç÷[ÏÞß·Ö;?k½ëßÕÕÕPxÑêÏ't´ÏùÈ€zÀÇÅ3_€Q4€g@œmÿ ¾ò‰âci‰ôçÿ{ ðÇð¬ù~½Á€4:õHcÂü ðŸÁ³„ª'ÕPÆæ P7^h،♠zb„cóP¨„ 3‚† Ò}çÿO²qÁºNkÝTÛ(É?d Ç~z<’«4Óǡ؞Þv­zµÙ¦õ¬ZâdÛ,Ë6Ók±]Fz< ¾ZçƒsÕ?ìƒsUø2SÉåwê1”c`[ì—}%ѽ.Ô¼6‚BLZ˜û!F8[ ¹…×TéÛ— »Þ#gó]å:vžu?‡vèbÙR˜?wùŽŸ¾ÊÐgbÑÉÌÕ$kF~Ê;عÆ•¢ïX®?ÉèlÆÙôõà»Nʪ¼­,ìHC§gAz•ÆlÓº­gÑú ]œjÎñåM…3ÓÚæoÒ³'=‘$Ò÷f}G•ŸS_‡öèco.Êȹ :ó£ Ãds®Ù:1=¼{ƒå9?÷ý…zqÛvîÓi‰D’p¿Ë šmÙíoÛâýaÖüEqÒµwÌ}¿~{òj€ç{ôºŸFNëí[ëOq·ÇOSúXO]°>‚‚muæÄ¾e¤“5Ë{¨JÕ¯£(›´«bÂçû’ÍlÓÅ}žïú`éUÞy„ac§Á†ÔCºŠóAkl‘±y¥†ô¢ùôs÷Aø¬7ÄõôoJ±äÄ ù.¥Be. Z¬Ð×ÇÈöå¹­ù'Ù-PëìŠyF.ž‚žÝÚ€lp&.êˆð•jò7’re’z19»ã§HGíø%œüq°ïüz׈c¬_k_")ŸHJnÐÑ~ˆÐÖ˜á´äÕ5 µÁq€ÿ5#¸·îà¶+9T‘‚ ðŽ÷Rܸrz“Ï´Ì =Ï…{ðáO£Èf ¡Íwg|Ž’Ü/¢Þ$÷¯¢ëðúÀ;¿à¨Ö™âÒÆ­]¯ÜW"Þ/< ‡÷DÏà°½üB}çyIEc^—ƒ=[V“Ýh²ëMä$l];Kû®¸ýr¦È*Åò ÿtÒõ$]•MŸ÷´;×I€1èó!‚œõ¸M õ¨(fÌæ<ÁÎÎò5~z¿ù¶ž mÌêÕ >–âÚ©âëˆIÎÞçz;ãu[i·eç^ÆÜÙÓ³NÞëF6B\}7†»+üŽÓ,Ã'a ½˜-yHY¿,‘^—ñfú~ß?Hcø¸…¸ñó{Z+4\såƒû·¯Ù·nߣð«íFÆ¡sغëû§D¾?ò<–Ævkx0ÅM±ælذÁIÓxÿd”žÜÉ÷EE»AªM«g*È£YEí7Û™^[uíý®v[wGå†=Ed¼n×¶ÆæÖÅl¡'¨pGÚk+‹æ¢À¬¨C8ªâš2 dz3H£ß ¡¨BÒûSÃÅù[wŘ ~xpçútÁæmö¤Å£¥iQæ­‰AB1ÉfÙ‰›4u¹ïìIÒ]Ë6äò%ÿ†† 1t.’NJph¬zÌ ÎR1Ž"3-"¸‡‹&ìó°1âüžìó[:‡ï„¼‘……N m–“W0®_èÜœ ×õ6ùò&»)Æìꦬýæ}¬ñ~»{múù]z½£M•ºP~^Îá:eQTÙ_*7ÕÄ9É8—·Ëï 3°¶47E•î¿u÷“SÉ»U¯ _ NíºôW¬e¸ÄNÓ|»;™¿;ŒæÅd"ȉôøòÞµõï¾®½"èÄ´ÖMM+bYµ‘_ÉæEÝüÎ]P»¹XKÐI½Þ¥oE<_¹(„EP±Œ|mÇÁ¡‘Ý,ŠÓ©ººZ±Îߺ§×kÝ,kÍMš`Äø…jzeU»æ ™Át3ÓÀ½˜6—ÒöùË·r¨¹Ñ}““wö:Χùë¼ ¿|‚TܵÉQˆKßç_ÁâÀ™œ”pÑÐóໃ¼Ydâ0!®àa –øöçW$ÃÁ‘Á$/\¬$ð 2ÞímÞLH‹Ÿ èd£HVÜ,:ò½»RÍZšJ­a„z*>‹_…NT(ù‚^SVF­U¹8ñEþôñ܈óùnd;«®8™\C]ø=Èêm¬Æ:‚´ÆbãDd=Áãßžˆ‹UU5O‹|]þð®Pèêv‰á\]2ßìÿ"yÈ[ïyʧz£g{Y«{„Ùø5©ÿ;w{N3é­nâĨw§Á¢ÍK¢Ý­ûÏ29Id¿’ì y)ìPÞò8ŒÅ©¯‰±@mPÔñwjl,6 áhWÕ˜d öà uõmÁp®.™á£Ç…twöR x­BδYcŒxg*vo  yò‘•“[¬?ÜVœ˜0ÒN¡O난~Žó’¯·h#´Hkýœ±8kÓß^Àq@]àÓ“ø,56´¯÷Í-κU»n…[>]@nîøÏœp›[œ6# €4tën¯:ŽÒþ}…—8äT9_žY$/´G’K™©ù†•(óÑ’Mø©`ŸÉdѺ;ùO‹B Ó&P{qöhJÉ+Úé–§¦l2«MïöÝ_1ÑÓ«’t¸½±l€ëØya ¦ô©«®½ÆL^¬žêñš¸ùy.¾Û½Š[ u/]½‹iS}øN>²e1™q‡jfÚ&¢©iT\=kÏ›ÀXô-.84V5ðu!TE˜ þ.ŒOH´¶4—zwTr.ï‰¦Ë xõµ·œÖ„HÆù£žÈHùg Ñhñ’T$ßyq¸zþ¨p¿´ë< q•ró÷š‰wÿÍÑð–I]´–æI²é²˜sÂ"×:Õ–bÕ¦“ÈÙL6¢9VÊÓWž§<æ;”3?ý©Mê3AV#µ±ËÞ¯‘ž K£UrÝ9!›qát¦H£Ù+6ÇV…/TS^pÃùqgLP'Ú5E ‚–ÀÞºîÄ Ën"2|Ÿ;®W»Îý"Ö¬TwÖâµtúŽO'› á+W Ã+¦âZÌ–<ÕÆ&nOÝ,IŠ£06.ÁZ.Çñúøh*INÚ’Oe½ÉgBXÐÔZóäøä9èü“hÒíDSš¥¡Ê µA¯/Ôc¸ö“`A§¯"zå|‘ €ÅŸ¨ú;HÍ#‚Î|%ÄOˆƒ«OàÌÉÐÜD ž mÜðâc–ƤÉÂqm¶uË&~÷núÒË £ÇÏ€ZÕj =«_n[‡‡÷nN§ÏÝ$_¾bE˜‚€Õ)ù8¾?6‘lú“ÍÙæÖ}#bW( œ³d-®•p&¡ý’œÖa”"9öõņÐ$’Ú›AÜ!ä;ÐÑõè{~á¹8‘ÛÞ£1ÛÓÉ0ž`²#´kÒuäNÅÖ Q¹bhæ ”8ûÓMáŽa›•¿”w±h²¢®qŠæ°(bK ‚’Z¾Ò%ÐÆémáãÖË(Éý‚ÛJ)@> þ›7% ï{y Á“¾ÆÒîohfòô>{pÿ.­_Î%±ÉèägëlZØ\B2B #™¸ÚüÒºp‚hÝšü®[¥Ü<‹#SpñÌA7’ãØHƒt4:Ÿ|g¨tÓL¶*($Æ©»ì…®ù’ó÷$;b›ÔÙ`=¶£¦M„MÌÄ5ò«·Ç¾“H·ÌH.¼žHeAîº5}r­dõ¨±)ÀT};€Q5iÖ2…O0ü…0óñÃ;óæ,Š´²µ냔}g‘£]‹7å9ˆà©_{üèîêžC>úhê{Ž .ÈìðIIð€?[Kswz6Òuíý¬;µ€ç§OåâJÉa˶zv°éd† ¤µâ‚l´é舊«Åüy¾c÷ÁèÖÍ'ràúÅ™TWÕôÓ°¡L €|ʽŒ¼ì­høBã ÝTëî'ò]Kø£ìâÏ(=¹Kx €¿ LÌ,Pý¤Êµu‡¹…׈ §Å¾÷à1Ý«Äý;¿pGDäxZYÛ kfæ6¸ùóæ7®œ®þ6·ÕoÚ¾ÔH~ò®Þ¸â 8Uø“p<ºw3¡a£ÏÑ’‘3èÏ"€bˆ-ÎܺÏ_ªÅ]+ËM©zü°s“f-êçhÇãÑýÊãôÿ5}ZQNb{Ó?å%ÿ\SUõعIÓæ}~}p[œoÔÄ„êÐMMZáNÅå@>Œ„²á6(?¡Åé âK½+ü?À%ÝÝ·/Ç1‚9áUø?B)”ÕèâÞlÈÒêÏ @=àùÄÞžk­®ÅIEND®B`‚openchange-2.0/apidocs/html/mapitest/dynsections.js000066400000000000000000000041341223057412600226020ustar00rootroot00000000000000function toggleVisibility(linkObj) { var base = $(linkObj).attr('id'); var summary = $('#'+base+'-summary'); var content = $('#'+base+'-content'); var trigger = $('#'+base+'-trigger'); var src=$(trigger).attr('src'); if (content.is(':visible')===true) { content.hide(); summary.show(); $(linkObj).addClass('closed').removeClass('opened'); $(trigger).attr('src',src.substring(0,src.length-8)+'closed.png'); } else { content.show(); summary.hide(); $(linkObj).removeClass('closed').addClass('opened'); $(trigger).attr('src',src.substring(0,src.length-10)+'open.png'); } return false; } function updateStripes() { $('table.directory tr'). removeClass('even').filter(':visible:even').addClass('even'); } function toggleLevel(level) { $('table.directory tr').each(function(){ var l = this.id.split('_').length-1; var i = $('#img'+this.id.substring(3)); var a = $('#arr'+this.id.substring(3)); if (l MAPITests 2.0 API Documentation
File List
Here is a list of all documented files with brief descriptions:
[detail level 1234]
\-utils
 \-mapitest
  o-modules
  |o*module_errorchecks.cError / sanity-check path tests
  |o*module_lcid.cLanguage Code checks (MS-LCID)
  |o*module_lzxpress.cLZXPRESS compression and decompression test suite
  |o*module_mapidump.cMapidump function tests
  |o*module_noserver.cNon connection oriented tests
  |o*module_nspi.cNSPI tests
  |o*module_oxcfold.cFolder Object Protocol test suite
  |o*module_oxcfxics.cBulk Data Transfer Protocol test suite
  |o*module_oxcmsg.cMessage and Attachment Object Protocol test suite
  |o*module_oxcnotif.cCore Notifications Protocol test suite
  |o*module_oxcperm.cPermissions Protocol test suite
  |o*module_oxcprpt.cProperty and Stream Object Protocol test suite
  |o*module_oxcstor.cStore Object Protocol test suite
  |o*module_oxctable.cTable Object Protocol test suite
  |o*module_oxomsg.cE-Mail Object Protocol test suite
  |\*module_oxorule.cE-Mail Rules Protocol test suite
  o*mapitest.cCore of mapitest implementation
  o*mapitest.hData structures for mapitest
  o*mapitest_common.cSupport functions for mapitest modules
  o*mapitest_print.cPrint / display functions for mapitest output
  o*mapitest_stat.cMapitest statistics functions
  \*mapitest_suite.cMapitest test suite functions

Creative Commons License
Creative Commons Attribution icon Creative Commons Share Alike icon
This content is licensed under the Creative Commons
Attribution ShareAlike License v. 3.0:
http://creativecommons.org/licenses/by-sa/3.0/

openchange-2.0/apidocs/html/mapitest/ftv2blank.png000066400000000000000000000001261223057412600222760ustar00rootroot00000000000000‰PNG  IHDRɪ|IDATxíݱðøScOx@ –¨y}IEND®B`‚openchange-2.0/apidocs/html/mapitest/ftv2cl.png000066400000000000000000000007051223057412600216100ustar00rootroot00000000000000‰PNG  IHDRÚ}\ˆŒIDATxíÝ;H#AÇño4Љႇ œ„K‰‡‚á ’ê,m„ØØ vÚžJ°²¹ÚÎþî‚§ XY ÅB|dr³cvo—˜Ä°Ý ù0Ã’™3ÿͤõ”Ëe×´¸Éõ¯1XÞ8Œ‰nQˆ88ööÖ§3*rbñ¯¢û-$¨‚þ´˜“P1Žè@Z…-# Ïú01ÑÏÎêÄ1HkKŸ w¶O@¥ªÈóñ!f§ñu˜åác÷;’sá×Bý[E´Añ±—Í\ß>°ùý¿ÏËÊÂ]–P€zØf| Íñ¯“+Ù´gð5…b  i5ümM³œ_æÍq,ÒcŽõèoÓd´ !¶äò©ô•,ôðÀ{¹¨µYß,€zTÍ8H]𤕘ï7¼»/òó8ËQæ !F€~6ãá?Y ÀA@ŨÁ.@ƒ¶TäÄYïŠËë±r‘µ8Ð*·é>€Šçÿ?€×þŸe[6«xÂIEND®B`‚openchange-2.0/apidocs/html/mapitest/ftv2doc.png000066400000000000000000000013521223057412600217560ustar00rootroot00000000000000‰PNG  IHDRÚ}\ˆ±IDATxíMOS[…Ÿžsúa?-XZ(PD4‚ AWbu`b 77wäHFÆCËÔÂÿà/`vo„ˆAPòq‹P @ ­ûÝè980 îà¤+»§Ýy×^ïZï9SW¹\83g‰3'°Nâçl¹¸_b¯p ïåûÆVÜÖ¡€Ÿ×"¬Ö†X€d]Ðà3“ÉÃÄÌ™xŸ ßMàœ[<çSPkvc—hÈ'…™˜^Åm™hØ7 `Û™¦ èÀåráq›‘œ¾!daeKŸþÆÕ˜:Ì*³_דâèi?I–eP*B7Ÿ¿åô!¹Ýgr6Ër6oKbëþãðôrI”ËTˆüªŒ¨xóö=›ù¢&‰(e+ßóÄkýÇ`ëÁÜb.“¸ÐW×w0¥°jÑzN™¬|©WEãµ¢a¯6[öX†AkÓù*/œ¨‰€ÉY­ ÿV’§–u²jÂ>1W *½·°PGŽzÿ¨/Eg{ ŸÇâaoŠÁVú:è¿™¤1$ôR§W,–ªà¨@ŠË56¾ÀÔÜ-¾,mê¸Î/æè¹– òr5¥T*S(Vf8ö9u’ Õ£w›ùóa=Í<{Ò¡UŒ÷r¯+ÉådDÏF$è°…£é¿`zþ»ÎúöN‘µÜ®0Q3£~_^Ëóâ¯N=ˆvpTà±LžT}ˆîkq†Òm<¼ÎÓ?Zh¿X£ï_þÝ¥[)ƒ `gêÃa_Ô*äÔ2`'=õ´Fÿ2EâÁPú ÷»›l=8‹Wv°%THqÉ¿<"¤ïG¾ÆxH{#ÆÖ«aÔJÕÞ‡—m‹„ çñKsÿàñVŠØ¡°·MâÒ^ TÁ– Ý›r¥ß½ømüÿ_™?ªWİ÷#uIEND®B`‚openchange-2.0/apidocs/html/mapitest/ftv2folderclosed.png000066400000000000000000000011501223057412600236520ustar00rootroot00000000000000‰PNG  IHDRÚ}\ˆ/IDATxí]MOÔ@~ÚúuØlp]ö¿#›Å]PYECˆ\9ù¼yÑß`ÖÄÿàÿÀÉxóâ¢C &=qÐÄ£—vZçv¶3m؃‡vžLûNç}Þ÷}Þ½ZA@n° OäNp ’xóþK°ññ€xÜj”°8sÑ€“ “€œ_¼[Âíæ§ïD'‚•yye+ø¼û 7#rNŸlïük* ¾0Ь_d«_(àñÖ±àôz=ñxõv§÷h©‰z¹€šØP-äóä’̪uý¼$»\DãJc—B4¯ãÝÖ.:£Ï-ÑÏß}µŠLEíºþ #—ûáºÀÏgN;BŠ€6ïýñ䬜…ö@’Ðåñp&™h>p9¤™EEά¨ÎÊ‘" u¥n€$R"?{¹<˜…ë…%PNtâ$‰ß¶±úá+^<é"§2 ªDq”q´\¬«Ò™a–Œ‘©Aÿ€"Ôµ ™êŸèP£}#Eàz{û.8i îp³ê(ADwD¦E<ê¬cE¦$ HdÊÄ ”.:Ù GŽ-`ŒL‚ý¾'¢‰Ä<¤CIª½;ÙÇTZd±i};>èôß‚z×;K×§8t ¤Ž q”:uvÿv•Ý›¬²ÙvEân{„M·FXg¼ÌfZÖ¨°¹‰*›ßÌß©±ù©:›j–YqèÜë#3çÏSøWøÿÿÑr'ø Ôùù‚ ©¡IEND®B`‚openchange-2.0/apidocs/html/mapitest/ftv2folderopen.png000066400000000000000000000011251223057412600233440ustar00rootroot00000000000000‰PNG  IHDRÚ}\ˆIDATxí]?oÓPÿ9iš4i°;ii“¶‰ZЉ‘‰ÀÀ7`bèÔÙ¬Øù,HìU'ô$*Tµ]‚T¡DPÚÄ6wÏ}‰;¡C; a¿ÓߟûÝïîž¼jAÀ­InSþ}€9H“ÓŽ|?íÁ÷ =_ÊÆŠ­†¥Àue*;¯YEäsYäæB¢Ÿ¿þÄ—£sÙ½½ÙŒ† É«›©ÀYÇq !GÇ¿v̇¹ÑØ®š °Œ‚ÔF¹}q¥b]÷7í·0)Úd›¾ÿð-èº}Pfä£ÖY{4™ÑÂ@}úæôñ2ÛüÔ—ñúåNŒI‚ÁǃcçÁº%£¬UаI³mc±ô˜å¼ÔÆüÈ>é¸xþt9Æ$µý OæVE*õU´Ì‚ç#ž×ˆ•ïûr@l$øPÿrHaaÇ¥ ²›dZ®rè‘ãqI„o¼øT\Ž,tªj2FAxv-LŸp׌p TÄI/ \¥sfí½; jViTƒèú¤o^cpÅü¼ûû»Ïb]”€¢¤<†aþÕœ²“ßÓ˜y“£§9:Œîù+À³€ñà,E žf³6éNˆÄE£KU}Ü^;¶ØnZ¢uß­US4— ѬëbížN¶.Úk¦ØjTÄöº%µªâ i¯VÄÊÝò§™ Èù¸)ùÿG€™òºJ@T x”IEND®B`‚openchange-2.0/apidocs/html/mapitest/ftv2lastnode.png000066400000000000000000000001261223057412600230200ustar00rootroot00000000000000‰PNG  IHDRɪ|IDATxíݱðøScOx@ –¨y}IEND®B`‚openchange-2.0/apidocs/html/mapitest/ftv2link.png000066400000000000000000000013521223057412600221460ustar00rootroot00000000000000‰PNG  IHDRÚ}\ˆ±IDATxíMOS[…Ÿžsúa?-XZ(PD4‚ AWbu`b 77wäHFÆCËÔÂÿà/`vo„ˆAPòq‹P @ ­ûÝè980 îà¤+»§Ýy×^ïZï9SW¹\83g‰3'°Nâçl¹¸_b¯p ïåûÆVÜÖ¡€Ÿ×"¬Ö†X€d]Ðà3“ÉÃÄÌ™xŸ ßMàœ[<çSPkvc—hÈ'…™˜^Åm™hØ7 `Û™¦ èÀåráq›‘œ¾!daeKŸþÆÕ˜:Ì*³_דâèi?I–eP*B7Ÿ¿åô!¹Ýgr6Ër6oKbëþãðôrI”ËTˆüªŒ¨xóö=›ù¢&‰(e+ßóÄkýÇ`ëÁÜb.“¸ÐW×w0¥°jÑzN™¬|©WEãµ¢a¯6[öX†AkÓù*/œ¨‰€ÉY­ ÿV’§–u²jÂ>1W *½·°PGŽzÿ¨/Eg{ ŸÇâaoŠÁVú:è¿™¤1$ôR§W,–ªà¨@ŠË56¾ÀÔÜ-¾,mê¸Î/æè¹– òr5¥T*S(Vf8ö9u’ Õ£w›ùóa=Í<{Ò¡UŒ÷r¯+ÉådDÏF$è°…£é¿`zþ»ÎúöN‘µÜ®0Q3£~_^Ëóâ¯N=ˆvpTà±LžT}ˆîkq†Òm<¼ÎÓ?Zh¿X£ï_þÝ¥[)ƒ `gêÃa_Ô*äÔ2`'=õ´Fÿ2EâÁPú ÷»›l=8‹Wv°%THqÉ¿<"¤ïG¾ÆxH{#ÆÖ«aÔJÕÞ‡—m‹„ çñKsÿàñVŠØ¡°·MâÒ^ TÁ– Ý›r¥ß½ømüÿ_™?ªWİ÷#uIEND®B`‚openchange-2.0/apidocs/html/mapitest/ftv2mlastnode.png000066400000000000000000000003661223057412600232030ustar00rootroot00000000000000‰PNG  IHDRɪ|½IDATxíÝ!NAÅñ¤‡à\ ÷à Um@`Ô5iÒ`ëh ‚ÅW7] b§ÝˆŠ&oföÍd¾YÔ4 üšcø ‡€´‹Åòù3v=¼]†§µ\B… I¿‹=B·™B¡®;¸k´µ W°ÍN@vyÍÑÖ4ãß÷]ÈâYìã§|M}]ÔÚx6a }ôdׇØYüú¨>¤||5?Ó>|žB"¡î'¡IEND®B`‚openchange-2.0/apidocs/html/mapitest/ftv2mnode.png000066400000000000000000000003661223057412600223170ustar00rootroot00000000000000‰PNG  IHDRɪ|½IDATxíÝ!NAÅñ¤‡à\ ÷à Um@`Ô5iÒ`ëh ‚ÅW7] b§ÝˆŠ&oföÍd¾YÔ4 üšcø ‡€´‹Åòù3v=¼]†§µ\B… I¿‹=B·™B¡®;¸k´µ W°ÍN@vyÍÑÖ4ãß÷]ÈâYìã§|M}]ÔÚx6a }ôdׇØYüú¨>¤||5?Ó>|žB"¡î'¡IEND®B`‚openchange-2.0/apidocs/html/mapitest/ftv2mo.png000066400000000000000000000006231223057412600216240ustar00rootroot00000000000000‰PNG  IHDRÚ}\ˆZIDATxí1Kû@ÆiƒØB…Ò¡(h¬"EÄI'ÁoàªèÚ©ßÀáâä 8ùçR-‚â B«TPˆï]z¥B’3 _Þã’»ç}ŸË]VÇ÷}€ÌÈdIæ®i쟯JØ–b¸šÍÃõ+º™|KÂ…°,[Pï\ʘMÆ¢#€ä…F`JݤìÛk³úA±àþè?ØY4ck6"¹Z)ê¸0SHM¨@ï㋺WÖmo¼4èHJ¨Àÿö+…QobŒút ¤ú’*Ð~êè8_+3Y-ñðÜå½÷ ˜PwA¶+^ý}ºì£+xìhÏ•MAE]€TD~EÞߴ^R)`ÖAùŸÏ9©pÔq-Û¾õÛ3tÝÊÆ›ˆÃTÐHÈ)€ ½Š’ICªxëd#1ôú§é€ m@Vüý?Zæßgo_½3-³\IEND®B`‚openchange-2.0/apidocs/html/mapitest/ftv2node.png000066400000000000000000000001261223057412600221340ustar00rootroot00000000000000‰PNG  IHDRɪ|IDATxíݱðøScOx@ –¨y}IEND®B`‚openchange-2.0/apidocs/html/mapitest/ftv2ns.png000066400000000000000000000006041223057412600216300ustar00rootroot00000000000000‰PNG  IHDRÚ}\ˆKIDATxíÝ1K1Àñ­ž ØG•â‚n‚Šà ‚âælÁE¿€‹“ (nºêââêäࢋƒÐMAá@°‹ µât¾ÄK¡à%Ü•Û ý]BIïå%áuÍ…a™€,e × v¯ç¥«ˆi‹º¨Õö–î\tòòuénÄ0ã æÜÉoV\Ì$G.&@Y=ÆË%$um·¢ûÛ6–'Úß«9Qó\bÙ)²º0Ðë-Zœ¥TèHÍ`pÀcsm µö5:>Áë‡Þ¦I µØ ‚F‹Çà]» ›jg—ìoÏáõ©[ œõ š­onë €Ô¬¨vqõ„?\Ðç”  6»øüÒTe ÃÉéŸeç ÀÅlQ ¡c”€ª¬ü3*d€ÅWTMÏ\rÿÿh6™ø1±F ‹°fžIEND®B`‚openchange-2.0/apidocs/html/mapitest/ftv2plastnode.png000066400000000000000000000003451223057412600232030ustar00rootroot00000000000000‰PNG  IHDRɪ|¬IDATxí=QF‘Ø¥D«ÔkÄ:‰F©PK؃=V@§Õ³ Õ8SHxñÌ0bnrróŠ{ò½¿¾’$ ÀÏTŠP  ö¼X¬OÛd6êìòð"°²S´±O¥B€(¡àQé)š+YĈ ÒªËRÉÐ>VtÉsˆm9(ê„䜥k‚-@ȧ-Ü$ó b Ò[he ¿Kp-ôl|CùÿApRG'rÍ­aIEND®B`‚openchange-2.0/apidocs/html/mapitest/ftv2pnode.png000066400000000000000000000003451223057412600223170ustar00rootroot00000000000000‰PNG  IHDRɪ|¬IDATxí=QF‘Ø¥D«ÔkÄ:‰F©PK؃=V@§Õ³ Õ8SHxñÌ0bnrróŠ{ò½¿¾’$ ÀÏTŠP  ö¼X¬OÛd6êìòð"°²S´±O¥B€(¡àQé)š+YĈ ÒªËRÉÐ>VtÉsˆm9(ê„䜥k‚-@ȧ-Ü$ó b Ò[he ¿Kp-ôl|CùÿApRG'rÍ­aIEND®B`‚openchange-2.0/apidocs/html/mapitest/ftv2splitbar.png000066400000000000000000000004721223057412600230330ustar00rootroot00000000000000‰PNG  IHDRM¸¿IDATxíÝ¡JCa‡ñç(˜ ëƒ%±Ø4 b±È˜Í¶3˜v^Á±˜…ãó–ŽELƒõ…¥•³ ,ÿb;íç{Ã/¼ðÞÀaYÕ¯åóøq:¼º¹›\òIIIIIIIIIIIIIIIIII-Òçl¹›«õ抢è_t/Ï»ã£ÑíYQVõðêäíã÷´×ùY¬Úÿµ§¦ivók¾_íåýÛ£I@$I@$I@$I@$I@$I@$I@$I@$I@$I@$I@$I@$I@$I@$I@$I@$I@$I@$ýC[Vì=ü[„fÆIEND®B`‚openchange-2.0/apidocs/html/mapitest/ftv2vertline.png000066400000000000000000000001261223057412600230370ustar00rootroot00000000000000‰PNG  IHDRɪ|IDATxíݱðøScOx@ –¨y}IEND®B`‚openchange-2.0/apidocs/html/mapitest/functions.html000066400000000000000000000165171223057412600226100ustar00rootroot00000000000000 MAPITests 2.0 API Documentation
Here is a list of all documented struct and union fields with links to the struct/union documentation for each field:

- c -

- d -

- e -

- f -

- m -

- n -

- o -

- p -

- r -

- s -

- t -

- x -


Creative Commons License
Creative Commons Attribution icon Creative Commons Share Alike icon
This content is licensed under the Creative Commons
Attribution ShareAlike License v. 3.0:
http://creativecommons.org/licenses/by-sa/3.0/

openchange-2.0/apidocs/html/mapitest/functions_vars.html000066400000000000000000000163031223057412600236340ustar00rootroot00000000000000 MAPITests 2.0 API Documentation
 

- c -

- d -

- e -

- f -

- m -

- n -

- o -

- p -

- r -

- s -

- t -

- x -


Creative Commons License
Creative Commons Attribution icon Creative Commons Share Alike icon
This content is licensed under the Creative Commons
Attribution ShareAlike License v. 3.0:
http://creativecommons.org/licenses/by-sa/3.0/

openchange-2.0/apidocs/html/mapitest/globals.html000066400000000000000000000722441223057412600222220ustar00rootroot00000000000000 MAPITests 2.0 API Documentation
Here is a list of all documented functions, variables, defines, enums, and typedefs with links to the documentation:

- a -

- e -

- f -

- m -

- n -

- p -

- t -

- u -


Creative Commons License
Creative Commons Attribution icon Creative Commons Share Alike icon
This content is licensed under the Creative Commons
Attribution ShareAlike License v. 3.0:
http://creativecommons.org/licenses/by-sa/3.0/

openchange-2.0/apidocs/html/mapitest/globals_enum.html000066400000000000000000000050041223057412600232340ustar00rootroot00000000000000 MAPITests 2.0 API Documentation

Creative Commons License
Creative Commons Attribution icon Creative Commons Share Alike icon
This content is licensed under the Creative Commons
Attribution ShareAlike License v. 3.0:
http://creativecommons.org/licenses/by-sa/3.0/

openchange-2.0/apidocs/html/mapitest/globals_eval.html000066400000000000000000000066611223057412600232310ustar00rootroot00000000000000 MAPITests 2.0 API Documentation
 

Creative Commons License
Creative Commons Attribution icon Creative Commons Share Alike icon
This content is licensed under the Creative Commons
Attribution ShareAlike License v. 3.0:
http://creativecommons.org/licenses/by-sa/3.0/

openchange-2.0/apidocs/html/mapitest/globals_func.html000066400000000000000000000655671223057412600232470ustar00rootroot00000000000000 MAPITests 2.0 API Documentation
 

- m -


Creative Commons License
Creative Commons Attribution icon Creative Commons Share Alike icon
This content is licensed under the Creative Commons
Attribution ShareAlike License v. 3.0:
http://creativecommons.org/licenses/by-sa/3.0/

openchange-2.0/apidocs/html/mapitest/header.jpg000066400000000000000000002264161223057412600216450ustar00rootroot00000000000000ÿØÿàJFIFddÿìDuckydÿîAdobedÀÿÛ„ÿÀÍ4ÿÄû     a!Qqð1A‘¡¢d ±"Ô%U•ÕV–Ö”WÑñ#EÁá2DT·BR3C$uµ&g(8x’S£³4…6¦hbc¤´Å†G§)   !1AQq"“ÓT”ÔUa2‘¡Ò#³´u6±BRVÁÑb²3$v'7ðár&ñ‚’¢CS%Âsƒ£4Dct¤5ef(ÿÚ ?ýAîÊåSñMÁÙB8v)¸;(GÅ7eáØ¦àì¡;Ü”#‡b›ƒ²„pìSpvPŽŠnÊñMÁÙB8v)¸;(GÅ7eáØ¦àì¡;Ü”#‡b›ƒ²„pìSpvPŽŠnÊñMÁÙB8v)¸;(GÅ7eáØ¦àì¡;Ü”#‡b›ƒ²„pìSpvPŽŠnÊñMÁÙB8v)¸;(GÅ7eáØ¦àì¡;Ü”#‡b›ƒ²„pìSpvPŽŠnÊñMÁÙB8v)¸;(GÅ7eáØ¦àì¡;Ü”#‡b›ƒ²„pìSpvPŽŠnÊñMÁÙB8v)¸;(GÅ7eáØ¦àì¡;Ü”#‡b›ƒ²„pìSpvPŽŠnÊñMÁÙB8v)¸;(GÅ7eáØ¦àì¡;Ü”#‡b›ƒ²„pìSpvPŽŠnÊñMÁÙB8v)¸;(GÅ7eáØ¦àì¡;Ü”#‡b›ƒ²„pìSpvPŽŠnÊñMÁÙB8v)¸;(GÅ7eáØ¦àì¡;Ü”#‡b›ƒ²„pìSpvPŽŠnÊñMÁÙB8v)¸;(GÅ7eáØ¦àì¡;Ü”#‡b›ƒ²„pìSpvPŽŠnÊñMÁÙB8v)¸;(GÅ7eáØ¦àì¡;Ü”#‡b›ƒ²„pìSpvPŽŠnÊñMÁÙB8v)¸;(GÅ7eáØ¦àì¡;Ü”#‡b›ƒ²„pìSpvPŽŠnÊñMÁÙB8v)¸;(GÅ7eáØ¦àì¡;Ü”#‡b›ƒ²„pì__gÓâ£êE~•²O\VݪÏãžà…·#÷Á?Nž•cÏ´Ôô™Û£¾!àÞÖ²x¬.c;s÷<%Íåå+ÝÁ’¾ºckO¦‹£Êcq0}ç)sµµi®W¶6׳SÈpo× 'ü߯Wí¬?þ«[7ð¿™áÜï¨]ù¥‚øócûëëvþqkúß„ÿ›øÇñå­õ¥?á2ÿùßP»óHøócûçëpyůëvþoc/Ç–¿Ö”¿†Ëÿç=BëÍ#ãÍïœW­Áçýn¿ÍÜeøî×úÒá‡2¿Ã¹ÏPºóIüy²=óŠõ¸<â×õ· 7qŸã»_ëJ?†Êÿç=BëÍ#㽑ïœW­ÁçýlÂÿÍÌiøê×úÒ—ðÇ™?áÜç¨]y¤|w²=óŠõ¸<â×õ¯ ÿ6ñ§ã«cë:?†<Êÿç=BëÍ#㽑ïœW­Áç¿­XcùµÛYÑü1æOø{9ê^iì|â½n8§ëNþlãoÇ6ÏÖt ¹“þÎzךGÇ{#ß8¯[ƒÎ-Z0×óg~8¶~³£øeÌðösÔn¼Ò>:Ù>ùÅzÜqkúφÿ›ßñųõ/áŸ2?ÃÙ¿QºóHøëdûçëpyÅ?Y°à÷²¾8üom}gGðË™áìߨÝy¤þ:Ù>ùÅzÔqkú͇šøãñ½µõ•Ã>d‡³~£uæ‘ñÖÉ÷Î+Ö óŠ~²áßæ¶9ümm}eGðϘÿáìߨÝy¤|u²}óŠõ¨<â×õ“5q×ãkoë*_ÃNcÿ‡ó~£uæ‘ñÎÊ÷Æ+Ö ó‹_ÖiìÏ{âýj8µýVÅÌ›ñtÃéy…îÏ©\ù´|o³=ï‹õ¨<⟪¸°{Ù&Äü]ðú?‡<Â÷gÔ®|Ú>6Ù¾÷ÆzÔqkú©‹™/âØ‡Ñü9æ¸s>¥sæÑñ¶Í÷¾3Ö ó‹_ÕL[üDZÀü>á×0}Ùõ+Ÿ6ŸÆÛ7ÞøÏZƒÎ)ú§‹¿˜ö7âȇÑü:æ¸s>¥sæÑñ¶Í÷¾3Ö ó‹_Õ,_üƱ¿A|:—ðï˜âÌz•Ï›GÆÛ7ÞøÏZƒÎ-Tq€÷²-Ž?þë‚øuþ`{‹1êW>mìß{ã=j8§ê†1þbYŠà¾Gðï˜âÌz•Ï›GÆ»;ÞøÏZƒÎ-Sñ—óÈüUðê?‡{ÿÜYR¹óhø×g{ßëPyÅ?Sñ—óÉüUðê_ÃÍÿî,Ç©\ù´þ5ÙÞöÆzÌqkúŒÿ˜VWâ˜?‡Qü<ßþâÌzÏ›GÆ»;ÞØÏYƒÎ-Sq ÷²•ø¦á´w÷¸³§sæÑñ®Î÷¶3Ö`óŠ~¦c_æ —ø¢á´w÷¸³§sæÑñ¦Î÷¶3Öaó‹_Ô¼müÀ²ÿB|6áîþ÷cÔî|Ú>4ÙþöÆzÌ>qOÔ¬müÀ³?Â|6—ð÷{/êw>mlÿ{c=fËZþ¤ã¿öoâx_†Ñü>ß¾ãËúÏ›GÆ›?ÞØÏY‡òÔýIǬßÄп £ø}¿}Ç—õ;Ÿ66½±¾³å­R1ÏßÛ;ñ4/Ã(þoßqåýNçÍ£ãMŸïlo¬Ãùk_Ô|s÷öÎüK ðÊ_Ãýûî<¿©Üù´þ3ÙþöÆúÌ?–§ê6:ûùgþ%†øeÃýùî<¿©Üy´|g´=íõ˜-kúŽþýÙÿ‰a¾Gðÿ~{“/êwmí{c}fËSõýû´?Cü2€7ß¹2þ§qæÑñžÐ÷¶7Öaüµ¯ê&<ûõh~$‡øe/€7ß¹2Þ§qæÑñžÐ÷®7Öaüµ?Pñïß«Gñ?Ã)ü¾ýÉ—õ;6Œö‡½q¾³å­Pñ÷ß›GñGÂé|¾ýÉ–õ;6Œ¶‡½q¾³å©ú…¾üZ_ˆâ>GÀ;ïÜ™oS¸óiüe´}ëõ˜-kúƒþüZ_ˆ¢>GÀ;ëÜ™oS¸ói|e´}ëõ˜-OÔ÷ÞÓüEðº_ï¯re½Rãͧñ–Ñ÷®7Öaüµ¯ê÷ÚÓüCðº>ß>åËz¥Ç›GÆ[GÞ¸ßY‡òÔû`ýöµ?Äü.€·×¹2Þ©qæÑñ–Ñ÷®7Öaüµ¯Ûëï­©ø‚'át|¾}Ë–õK6Œv½q¾³å©öúÂûëjþ ‰øUoŸrå½RãÍ£ã£ï\o¬Ãùk_·¶ßKWñW¨ø |û—-ê—mízã}fËSíå‡÷ÒÖú~+áT¾ßåÊú¥Ç›GÆ;KÞ¸ïY‡òÖ¿o,?¾–·Óñ_ £à=ñî\¯ª\y´|c´½ëŽõ˜-O·v'ß;_éø¯…Qð&ø÷.WÕ.<Ú>1Ú^õÇzÌ?–µûwbýòµþŸ‹øUïrå}RãͧñŽÒ÷®;Öaüµ>ÝX¿|­§¢þGÀ{ãܹ_T¸óhøÇi{×ë0þZŸn¬o¾6ÇÓÑ £àMñî\¯ª\y´|a´½ëŽõ˜-köæÆûãl}=ðª>ÞþåÊú¥Ç›GÆOÞ˜ïY‡òÔûqcýð¶~ŒøM/7¿¹²¾©qæÑñ†Ò÷¦;Öaüµ¯Û‹ï…³ôìgÂhø{û›+ê—mm?zc½fËSíÅ‘÷ÂÙúv3á4| ½ýÍ•õK6Œ6Ÿ½1Þ³å©öÞÈûßm}9ðš>ÞÞæÊú¥Ç›GÆOÞ˜ïY‡òÔûodýï¶¾œŒøMïose}Rãͣ㠧ïLw¬Ãùk_¶ÖOÞëkéÈÏ„Ñð.÷÷6WÕ.<Ú>/Ú~ôÇzÄ?–§Ûk+ïu·ôÜoÂhø{{›+ê—mm?zc½fËZýµ²¾÷[MÆü&w·¹²¾©qæÑñ~Ó÷¦;Ö!üµ>ÚÙ_{m¿¦ã~Kàmíîl¯ª\y´þ/Ú~ôÇzÄ?–§Û[/ïm¹ôÜoÂhø{{›)ê—m/Œ6Ÿ½1Þ±å©öÒËûÛn}7ðš>ÞÞæÊz¥Ç›GÆOÞ˜ïY‡òÔûieýí·>›øMoose=Rãͣ㠧ïLw¬Ãùj}´²þöÛŸMÆü&··¹²ž©qæÑñ†Ó÷¦;Öaüµ>ÚY{mϦã~GÀÛÛÜÙOT¸óhøÃiûÓë0þZŸm,¿½¶çÓq¿ £àmíîl§ª\y´|a´ýéŽõ˜-O¶–_ÞÛsé¸ß„Ñð6ö÷6SÕ.<Ú>0Ú~ôÇzÌ?–§ÛK/ïm¹ôÜoÂhø{{›)ê—mm?zc½fËSí¥—÷¶Üún7á4| ½½Í”õK6Œ6Ÿ½1Þ³å©öÒËûÛn}7ðš>ÞÞæÊz¥Ç›GÆOÞ˜ïY‡òÔûieýí·>›øMoose=Rãͣ㠧ïLw¬Ãùj}´²þöÛŸMÆü&··¹²ž©qæÑñ†Ó÷¦;Öaüµ>ÚY{mϦã~GÀÛÛÜÙOT¸óhøÃiûÓë0þZŸm,¿½¶çÓq¿ £àmíîl§ª\y´|a´ýéŽõ˜-O¶–_ÞÛsé¸ß„Ñð6ö÷6SÕ.<Ú>0Ú~ôÇzÌ?–§ÛK/ïm¹ôÜoÂhø{{›)ê—mm?zc½fËSí¥—÷¶Üún7á4| ½½Í”õK6Œ6Ÿ½1Þ³å©öÒËûÛn}7ðš>ÞÞæÊz¥Ç›GÆOÞ˜ïY‡òÔûieýí·>›øMoose=Rãͣ㠧ïLw¬Ãùj}´²þöÛŸMÆü&··¹²ž©qæÑñ†Ó÷¦;ÖaüµÈ[.Õâ)8há'(,™Ed"©,’¥¦ªJLEP‚Sˆ¡ZÜðMk;í®ctw1¼µìp-s\ÓG5Í4-sH ‚P¬ô3Eqn-Þ×Àö‡5Í!ÍsH¨s\ AÄ/£³éñWÔ¹+ô©Ùôø¨ú‘_¥bï¼JÆàXññ‰¶•Èeƒ‹\D[G2NJ&CC6*ä1ORöêÜ 6¾ñÈîKÞsS,û«×> §hð'•¿jGÐ8A<‹H/u†–ð«‚ònió6Û`ãÛ«Y.á¸i10ý–7£½xtÖ¡£†§Æ€¯oL…xäi¥® Òᑸ$Ö1÷T|¹Ì‹DÎmïFhV±í?䤉˜sk_§[khmÍn'mYÃidÐ*Ðò8j‘ÿjGž·<—Õð¶sqf·-ó²9ˉn.[ƒýV7ì±£©­.( uV|µb*”ë©ÓDꔪmÓÜþŠ’;SªPS¸)P& PSn½=ú’ÔU()ÕRZª©ANº)Õ)UÛã¤GjuJ wM`¥*›u÷jKSªPSnÞ*’ÔꔨÓN…UL íñÒ¢uJU:½ÊšR‚}‹SªR©·ÇPZR‚•ORuLUzüƒJ©Õ)TÛ§Oz•N©ANà¨-L ¦Ýj UU)Tê÷*t”ÁL XRN½‰J¦Þ¡¥¤'T §UAjuJ uÔ§T¥So½SBª©AOëè¤{Mºûµ%¡:¥*›t©-N©AJ‚ÔꔪmñÒ¡N©ANò…MªR©×ÑH´& R©¶ µ:¥*KU”Û¯MMN©ANò…*'T §^ЩÒR‚›jKSªPS¸* S)TÛ®Á©¥ª@S¤<´“ª`S¯¢•uH m©-N©@üõ©‚ªsPÔ–§T §pRâR‚›u¥@RU%©Õ(yõ©-Nªà~ª’ÔꔚŠQ:¤ŸNš<)Õ()J€§T€}µ%©×ëH)Õ 9ô©-N©ãÓSDU 9ôé¥Ç­:¤ÒàSW…-)Ô¤=Iju€~z)ñWs I¨ª@?8x©S±5p?0ÿM.=iÔ¤ÑÀ£‚¸)Q:•p5M¨ëWÒÒŸ\ SBŠö«„<4¨ª¸<5:SVs .!UÀÂT'^Õp?pQNÄS±\ J‰ÔŽ•®´¨Š…`0ôÒ¢t À`è¥E4ZÒIkB¡ P…(B”!J¥R„)B¡ P…(B”!J¥R„,®Áw ¹f"Éc “8±K^ð$Óþ@è§_›ûç÷Û1ûVïôò/»¶‡îž/öu·èX²?³îÒµo¶/À§gÝ¥…~pxš»e®Üõ•K¹2ÇŒ½ni57fÞ*Ù”u‚D¦ÑL}4ÞPÆ0òˆ×ì?%0V.U` Ç°5³ãmî^zÝ-ÌMžGÒ|g+ÐÐ@ ó{š[¼¶ÿÊËxíF+é hêÀ÷DÀ;õ*ꔪXTÐ'TÅSn¾íIjuJ mÒ¤µ:¥* SªR©·]ƒJŠª”é(TÒ©Õ0)×ÑRZR•Mµ%©Õ()ÕÑQ¥:¥:È4¨R•M½CR@N½©ANà¤ZR•MºÔ§T¥SnžåAjª¦:ú)'T ¦ßMuJ uR-N©ANº‚ÔꔪsžçôT–§T §pT¦bR©·Çߥ@R‚U%©Õ()×PZª© §0éÝâ©-N©ANà¥Å:¥*›|u4ªPSª‘jª¥6ëPZRU%©Õ((=54¢uH mÓ¦—…:¥óÒ =ª@?0Ô–ªªP?=N”ê§æ¡¨-N©Nz\SªPSn½Þ:\:ÐKObuHÛRZ~¤€~z’ÔêÌ:ôÔ–§T€~~JT#¡4…?0ëKÂ{RéR½¯b@?0÷tT{UÀýu%©×±\ ú "ª@8ôÔiNªàpè飈OÀ4¸u¢½ªàz(Ÿ ¦‰×µ\4ˆ@§R¸<<•:S©Væ’;Sª¸|<´´¦®})P„+†•{Sª¸Žà¬ (Ž#¡_ZTOWjÔ˜iQ>[{ž•¢¶ 4’¢Ö’JP…(B”!J¥R„)BYðÒ–¨<;ï\ùU0ø«ó{|þûf?jÝþžE÷vÐýÒÅþζý `ö;<•«T-‹þÝ*v;<”T#þÝ+ò•ŸÍ»žshkÞ˹$4—”Í~Öò¨Êý·ûú¤+óü÷šý­yúÄ‹©€ýU¾­N©@ýu%©Õ )·J‚Ôêš'T ¦Ý;¼TxSJçÿMRuH mê’Ôê”çä©-N© ¦Ýj Sªû™6y éQí\½xàà›v¬ÐUË•Ô0èTÑAUNo×ÒÇfYÜÖBÑR礞[ùÀ\ãÐOàYKcðožïTÐr[IKyŠú®n5>/W³0”@bRªø ©Ã@2e 5¯7ÌókcaÜcuÛg¿Õ‹ÇãÙ«ƒz»|+mÆì}Ë“ðÛ=±ž5p§¯Â<+¸à2è†dçn„ƒEÛ ©XGª)¦.I¯½Qs ”1¬Tļ¢<•ªÅÎìMäÝÕ•»ŠHÔáS@]Ð:*ÐOJÊͰo,ÁûãÈ¡¡£M:iÓÆ´<;*¶ÙÚ±)ÿçƒÒ¡È.b„©ïhôÆn7Cx{ýí9DC½]«~k™Èÿtiû2Ÿý=«„íá;ª[H‚ºÆàá®àˆrá«Y¦.\ šJKº ²b²~Žå#%5KCrD `Ö¶+`cîãl¯ŠFÆâE{(iÄ#¾#¤®ÆÔž²F—Ž®Úñ ‘кVn͹mÓÆQª‘0HGEÐäå×}=t^PïVÝi—ÇÞÌH5£À¬Î6ö׌Œ%½£ˆ\dëò dhB©MºtÒ-N½©AJ‚Õ@¥*›u©-N©J§UM uL uÒ N©J¦ßIjuJ uT–§T §]AjuJU6éîTЧUÚ¸kßÛ!@ã\{Y†uSˆ(º‚Þ6&9¸’S÷TôH¸Ô5:§C‰¦E9mcwîÌ&ÈÀO¸óòì UïyàÈão Oyà8¹Å­pÎíͽ”Ý9x°¸vk¼”õš5iï=MhâOz ˆÖ»—†ogg1QŒø¯ÉÒWîF~Å'«Ú±on&†äû@ûfÃ2sñQ«†".å¤IÈ”D‚AÔ…ùœÝçŸ3ndŸ—0ã¶ûZٞ؜ziãKr oxà\Èb%WIú5ü¹åNÆ…‘o[¹/sh&6:FýXà!íiè–@Ò)Ð>7{,ø·]K/dIÜQ“Ý$¸Á@Ê>ºAÓåÐ)tôxlŒåó[°¦L¦TÌã%Sz ”ÇÌ„8î¹—üÃr茖òµ¶ÊàZGxö²?ÿÕ¬0ž€,.Ž´q* ØüšÞ€Ùm©æÇåÈ:]!$ô'.véŽPúTðy¡Ä>¿¸gÉ1ÖAj¨dFFÛ¸˜‚ƒ v@¨±ÑBZ)UCDÅ7 ”ÑfËJmJ$9þ¢å÷0°ÆÁ37„qkÓ,N§y ”©cÀémxñ^Þ"†­ ¼6n_ee‹Ê4MQÈß±++@æ“Äv9§‹OŠÒÅWn½5½P­N©J§W”)Pê˜ëè©-N© ¦ßAjuL TéUT¥W¯È54N©J¦Ý:{Ô¨ªPS¸*KSªb©·Z‚ÔêªuTé)Õ0+Éà%Mz=íá×pÛgá«´ÓW×ùçK4iy•¥Pc¢­Çˆz*j¦@o¢²Šk¦º€‡5|ÏÉ.iîmñ—ËÙn7Àè,û¾ëDa‡Æ|­5 šðcWºsO``¶¦7u…l¢[}æ·—±‘N8¸¯9ÐpUS*…C ×ÒbŽ ÃÏB¾S®‘j*”ªsžçôTé)Õ0)ýaI0{•Mºûµ:BuJ uT–§T §]AjuHU6øêtªª`S«hRER•Mºû´¨ª@Sn•%ªª”¨-N©AM¾:)Õ()Ïã ”ÁìJU6ëîÒ N©ANªE©Õ )×PZR‚›t÷?¢¤µ:¤9ùv…M uJU6õ / uJ sÒÓØRù†¤µ:¤÷AjuJ >½5:Sª@Sª—ÒúépER–”궤µ:ýJàpè©-N©@ãÏ­AjuWõyiP§T qç×ËK‚jàz4ö'^Ä€na©!íHç©-M\ Ì:TRÇÃËS¥5p8séÓKˆN©ãGpëWÒ¢~p7pR!:ö«Ç¦¤µp8R¡N¥\ >©#µ:«ù§Jjà`ðÒ⬢½©×µ\ÝÞ¢ÀÛ|tQB¶´¨ž¥`0ÔÑ>[{ž•¢×]hIkI%(B”!J¥Y‰Ã"Zµt:wݸý!¼5ù½¾}³µnÿX‘}Ý´?tñ³­¿BŘ½vµª­NÇ»Z¿%œB˜ Ÿów´Ì90QRxÔt.¸ÁÔ`9p¬rU¶ªö/»BRòŽ¥3 cx¥þ€¾ÁtW}ÔM‘À;…[Bþ׬ý+L=Áµïß##™Ä WéT•Ã%0z«uœ1lªNY±lGGP§Uºí[z:E1A¹;!U° aÐÄÝY[qq]ops^ò@¨TõšÐÖ¾õÃmËZHkšæ´H$)NÒà6tT»uÐ(£¤À@éiÛ4PL'2J”Šö§HU DtÝ0ˆw‚³Ö™››g‡>ˆõô8vŠŠOè\ca˜‹ êêðý…bÍׄ;~áó3e%¸²ÌôìÚÉ•2†Lœ€T]ƒ©Š:r›”¼¡èÍé÷hÃåÖûZÑÕâYôöÓéâ:ºV§}¶ÅËÜÖQ“õ§ÛðýKæ¡¥íÉâæY,Åësn¨ŠÀÈ S¦r “P‡(€Š"^‘ÈYå-ÅÍ“Ãã=#è#¤-òÊæÂcËK_øm¥Sª»ÄÕªPS¯¢¦:¥6øé¢©ANª‚ÕUJ uÔ§T¥Sn”¨Sª`Sú¦0R‚›u÷i§Uï²ù„!ᓉŽ*åcŠòJÜgv¤˜(,6Æ/²P¾d2T¥¦œì”ˆ&¨Q:ŒSäÔ¡¯Â¿Íýæâßø\A!m¤‚'štw×sºÝ®pë1±•o`‘Üx•õw!í-°ÛC/½ef«†wéîíâ8Ø÷:‡´°v/ÎmËv^yÊÿ¹ò ñ0îjáºæžMLÉ:Pç3‡o DŠcfÙ=Ô›¢MA2HR€}7€ÀÚYØÁˆÆF!Æ[FØã`àZ)õ“Òç.q.$’Jð¼¾Zâæê\óÌ—ó¼½î=$Ÿè €€.Ml-ò>bAìTÜCÖ’‘R±Î–g!'ºnØ¿bñ¹ÓpÕë7ID”!Šr bˆl·vÖæÙöÓµ¯†F¹®µÍp!Í ð ƒB ÁÙ¸‚fÏ ‹$cƒšA¡‚è Š‚:è ‰PâCÙ}‰¸ŸœI±¯Ë[BFj]š w/¤n„pýþÙºiãx雼È=ôtôìŲ`<„øƒ–lŸ–œþÈìkg8bî ¬k 'ÅýîÜšô¹ÕšN§µõ>ùt[ã”6[®pÓÅÔh¿îóØ×IGPti‹¯ø<à“ñ¹jôŸ“²îtç®I^ËM‘ ~ß¶­™F.eŸ:Žzvñ‰ŠVúnKÛ® "‰Ì œ¤Ž÷Ìþyo=“̶müD1]â´E¶ýÝd’YXàÆ‡¶¯§{ éhÔà AÔj[•;gtlgfr2Éo¼µÑŒŽ7´¸–š7ìjq $P(­f\ÞÇ®øŒÂѰy I)Gmm˜|Å55|FÛ“So\›йnÖÉǬñÚ…!Vun3Ž(˜ }ÒjjÆå2ßÍ?ýÕ5æ<@Àe}Œq[>HØÑW0àMtù:'‚ïXc¹ y|Üv׆gnß$ÍcÜMá(“®·k;h8¬Aã[†ü%eVV¹dœNØ×“S–Àñ""ùvlÜ‘´œ¿bšMTœ€U ²ˆ”©,ƒ„V$* )ûw'y­mÌý¾ë¹£m¾rÙâ;ˆÚIn¢*Ù#©'»P8’×5í«ƒCå|Êåôû0-£{¦ÅNÒø^áãP9 [ "€‡5ÔÒ3^ßá#†°Ì`ã®beåÃw‘3BbÈG²Ì×AUZðA½¾â2nRàbÐå3õÌõœk%Næ0¦ª¾9›ç/0÷þë¸Ûšd1c- ^ÊÖ8:ŽÓÞVPøÙœ‰¢9&ú©¬ô¼_,önÐÛðçy˜éd¾¸E«öÒ£VŠFZ÷HÑöÝ­‘°5&Žv㋱W³ƒŽÖ'¾pžX‡Šs0Ê"æy5"õÓDTI°É:‰œ»o(yèvΦUÒŽ”jõ 9Na)?ÊÄe¹Ï~U]Ñß²ÍmÉ$ s¢dlš-’(-ßÈK¥‰ñš=~Êå70-ä²ÚͺÆf˜Â懹ï$tUÌ’YšöEC$cÅA<:p7á"¯ÅͷÞ[báºÍò¶eÞÊ9éÛ*ªh$åB:Œ~RýE$á²ÀPíT¦ÓßWÐ;›µÜªºß»RF—ýÀO {A’ÞM$µÍ¯:—Žà¶{›Ì }£¸àß½÷R†šTMZîÇpsM8´ƒÖ½!Íü;{:øC¹Ô›Î7Ï4Òàd̶fŒ›”{qºi);–IHYy±håúG#uWxÁ‘{#¦Qp®¥OæýµÍŽyóÛ­¥½Ä/qžýñ±±Ôš²&6FICH. ŽI A:ÅÞÙœåç*6Uñ»Ï¾âhdhî­÷Òž4Ž,sBꆒö0Pôqۆá~÷⃲Ï[/±›IçÓvÔ¤ÂøšÔ‹Nภf#î‰Yçì¦Fß\ŽX®ÉâV0•1)Äæ2Y]½Í¾gìÎ`ZìÞh¾ »KçÆÖLÆDÂÞõÝÜr1в&º>ðÈÙ#®Pt3<ºØ{›gÜnm„Ù­®m÷:7:GjîÛ­ì{e|ŽÑã1Ìyi45%¸YÁw ’¼[_îa’V ǵڳ–¾nVȦáÓ6VU(Øh¤•Õ›3UÁªIYcN̨©îÙæ¥,öã2"6Üfnœæ[BI sš|#w¦êŽqs u·Ê¹yËû½óšuž³2Ý¡ÓÈHÖ0ßGi'ƒC\â ]™ÕËì…ÃWš˜¢ä¶/ËÞfAX’ø†œ½åb!ä[j“Óɺ‡½­ÖÏÔb࢚¿ź!V)ŠÑð¬~SùÜXѸ­o¬l­¦`’+gÅl×½§‹CCíåsC‡ßLÓJEW¬^cù…½8k‹[«©ãv‰'l“9­pàK‹&Œ:‡î¢p­EEñµÂ±áì\ň®U®ì” ȰRN¥ æ%üÌZ×!“lÙ²2ðif ‰{b‚'"¢aÜQOGäç8o·­ÅÖÖÝ6ÛwØêÖ [#XáÉa$²XÞ@‘ é:mZÝ'™|µµÚðÛç¶ô®ŸmÝÓIqsæ—´jjcÙRÃMB„:¦„ú›Ç$áî÷ǘG#ñ=’ÝØ8Ÿ·|ñìdYŒ”Íó;sCÛ‰CÛ‘«7Aü¢‚bB.u[±j£ÅRÔÄQ¹QbüË}É»0ùÌž/eZ6ç; s¾Ä,òHàK[ýqG=Á€ð!䆟£7¾näñV7û¦àÁ‰´a%­ûR¹íf–4€]ýSPÖ—ÐZ#0¾1öjñŽÎî°8ˆ½1ÎA‚<Ó7Ò·r²Å*현ëx»†íº æbI¼n“´w›¹pP(§¾U ë9®`së–2Úå·eÅžC,¡Žcc€2´'»/ŠdcËC‹ã¶­5¡ióÌ^ÏåûŽã·a¹²ËG ç>RêT a²K+Ð⇊î<¨#ÍÜ]‚®|ÄppÞ.›F\ñ÷½Éh\²eIWlⳓ žU$ñI7i ¹ÛÆH®ɾMð0}5œæ>'Ëçó5ÒX›H¦Š:†¹îœ0E6Dâ¢7Ë èZݿˡ´ð1fùŽé$½¸%³ Å*+¢‘–½Ïí¸½‘°5&ŽwÛŒñÏ³ëŒÆSvŸÊ^x(ÄŹ—gq:—~ñËDTI¸È8‹™º.Ø™¸–îI„“g‰Êcn—¿ŠÊs¼±ºŠÿy¾Ï/·ä1α°jtµñÃãyé2Dö=û ʽùo%žØmÎ72Æ4=Ïq#¢¥¯–V½ ‘PÉñÓÀ/0o[js_V<º›•Ëg̼„–nCï¢+µ>‰ºj ”¢»íÌEÐS@íP¦Ó–¾ªÛÙìvæÃÛæñŽÕes^Úð –¸u9¦­pêp#©|û™ÃÞà²Sb¯Û¦ê NŠŽ±Ú(ZzÁl`¦ÚÌ–¬]R‚œõ%©Õ()·ÇQ¥:ö¥:B’uJU:éP'T€¦Ú’Ôꔩ-N©J¦Þ¡¨-N½©N%*ÁìJU6ëJƒ­:¤ÒÒRÇŸü5©×êHŽŠ’Ôê”×SDêŠ\zÓª@S®•骯֔5¨¨W‡EIjª¤MN”U :)qN©ýt¸&iN¥ ˜ÃRZЏž§J¤€na©#µWóù*tö&¥Ät§Up?=Á )iOR¸•¨ëWMN”ü à`šUX !ÞD'Up?8xªt¦®÷tR⮢½©×µ\E;AÔ¬ÛJˆ© ÚÒ¢u Àaé¥Dè ¶ðtR¢TZÒIkBJP…š¼/¥«%ÇNû•‡Æq¯ÍÝóûí˜ý«wúyÝÛC÷Oû:Ûô,Y•Øì%jËbS±Ø>J¿"E›wˆLî^AÓ2äðñ^ó•ûmÊ^Ví¯ØÿÕ!_˜;üÿçÌßí{ÏÖ$]:}+}-Z•RǦ¤µ:«ÃŸü%©Ô¥¦ˆª@Sª—…4 §_»Jƒ©:¤íÓ`÷iRZV}p'ÁܧײÒÓÈ®ÏYÎP5Èü¦;aœúBË'E(™.Ñí^*MN‹}ºBxo;9³mËl3ml‹_¹®Ú{–ô÷lè38uÐðŒwO}?–{ãzd4˜{r †´ÖãÄF ¥^EHoG ýOÚöE³í˜èf­áã3lÕ„dB ƢѓtÀ­Ù7*'A"9@‚0ˆˆ˜F¿2²yœŽw%%õã-ËÞ\çÈKËœOð$ý<P_qãñVx‹&ZÛ€ÈÚÐX@ph Ãô®•ÉR™mÙ26oÌòÎÑ(n¬¼œ˜,Î(«€êº†kG*ûýGUÓ7€+rÛØ·ºÍ×Ré&~†ž ÆQϧPÔâÆðþˇjÕ³™Xb¼À†²&kpë/}ZÀGI£Cÿ¬Ò°Ç%ܳnÓ21Ò±=ªÄIwÒë‘è"©€‡8™ER€a0ê¥{ÙÆØDðû¸åš€ÈÅ\HãØkà^G¹2ykÚEc¦8I£žç^.  óÿ(Ý ­rN¾É¬u’¹&ÞÛwMQh“.™"£[î.ýu”Mªc¨¡¸Q(W¿m«ëo ¾)ú#·´p:µW¼Ô4P¸öñ5â¼Ö÷\×ËutÇÈ纮0=”#WWàà†œ´KÙ踟ï`3¦poܧïùDp»dÞ †ºŽœºÖjò×--Ö±i`ÁÒ5½ 9ÞÑoÜÚ>wÿ…ßåqY ¶Ü1•Ní’Id M !8©Í®ø€¬fG\ᨓRh™€6W}˜Ü–÷‹8ÍGK$‡€8¯ŠNšÐ[pxtU®ÿ%h¹ 2|ù ‹†Ï $S1;6ÇRHñŽVLM¡Š²R̘$s¦ è Bòë aß·¬ -’9¢ãSâêÿêýwºmÙïƒ8}`E£Ì„I¢Ý\q²úìÝ©K²ìǹ0ªŸ`C9ng ©ÄNQÓPä÷_û”[²FØÊÉcpã¸8pã@hïĹMûæ{ ÃÇ´ý¡Ðxý ò}|Çr LfØ”O(Bo71Duôg €ª¡˜,n›C å/½ÔµÖÁenðwBXxÛ»í0žŸiÄ~?É’³·ÊÀbž‚Aö\:ùâüKß³{õÄ|ƒu¼j ¦»u‹¸¡  Aï”ä1G¼bˆr {¥…í¾JÕ·VƱ»ñ°¼²öÎk ƒo8£‡AíD/œê®ÑjëU()×Q¥:¥*›¢•;SªPS¸)P'T ¦Ýz{õ%©Õ()ÕRZR‚u{ª÷¯ÙâÑ,ÙÀ/ü>D™²—‹är<\{E쀆É8ÑË>AÁÌ©@¡ö–Ðj;©P u÷ÚüüȶM³Î]¿¼gÔ1Õ¹.¥xÚܹÓ4pÿåHÃÛãpê_[òL³9Ë<ÆÚ‹I¾×0èž¶'?üÆ?èñWçfÄh´y2|ÕvR Ü.Ñë7h¨ÝÛGm”2.9n±Hª¬A)ÈpÀ !¨WÙûxÅ-³fˆ‡FáPAx‚àAA æ\À’9Ìr״Ђ(A ƒÐGEe‚~A­ˆµaj½Ã⥠`¯bõ¥.Â:äÈ XL££]ê›Ôeî\¨læá’ÈDÉ8a àªû¢‘ɸmÈ?Ÿ8‹¶oæƒ!ŸÆ%…£æ«ÛöK!µÀõ‡<´‚:A¨à¾ÃÉ[»mòÓ| .îzC¥œÝ–‘ÔZÀA Š+®1r˰Ë35š†”›O|†›q\‘f$¡@@wN™Ä¦ð€ˆ%wwHÕüÍãôxÿV™upœ‹¾#ÿœÿÓļ&³­”ݲ (mý7ŠmD SwÀ@C”š¾ÅÆâÙ45“Bù²úùÑËFp¢ý5ûDÈÒköÌZõ;ɼã¢îWoÑ2¾.¸S±~ÖíŒ$]B®ªd3„ùNB€è:WÁ¢ž|]Îõn ‘XÛ“iñkœECÑÀWIì%}qÌh¢¿‡kœˆ«ä½ƒYpãG÷]åGÓýaô.Sí0K€ÙKóEñ…‘rÝ©6ÖÒ‘weDج¥œA­þdèÊ?]V6eƈJ.ò94Õ(¬C(¤"@ÉË®hZbo?‡ö¶ZÉrÑ3¦-ÖÖx­ã4g@$p"®w¡‘æ]¾Ã¸È[|a=ÜS²Ûqn’ïðþ1-ñè à±ÝþÈ^²E©—1ÞdÎ-î«AÃLJ’†¹]±pœŒcØyrMÇmtÍät‚©œ€¡@Ú€€€ z~æÆÿ0[³>/Ä}ÃZ¥ñ‡.kÚæ“rêæ‚ ÑpwÜÛÙx²øë숼„’ÝLyiÔÒÒŠ‚ ¨\<3Î(ÏÞÖü;‘ð¼Ë‰ÛRåb¡&ýÔ ½¼à×$”#¤Ög2Ý£¥Ìœdk0*À˜ÄС¨F²X=Áµ?—ì¾ÞÜ1ˆî¢†rÖ‡¶A¡ò5â…„ã9ü+ZÔõ®•ÎW¸9ÃŽÌáž_o$‘T–¹‡[X暇OŠÆ”¥RèÏlC5$xî’ne cðï€Íé„<&0HÖoùq·3òþ޾Oþ°X¾uÊ"Þ»¯îÑAYí쮈J/„þ.Ûwˆ»YU Aå&ñ±¼± ;£ÉïŠPç­+ù‘´m¦ÿÛa.kOÿÔµm’¸7C6]ÐïÐ9|>ÉiGÐüqauÛÂb^Q.¯ã]62‚ûÒ qRrvà©(UP”t±’î˜Nch:€içémï16å…ÿ,ˆ8³GÝi“§‡µ ×…]ÞPƒk³3Wvœ/Cä Žš²Þ¬ü&ŸI_Ÿ»NK…Êï_ª¢¦UCœçPÂsÆ0˜Æ1¨˜Æ0ê"<µö>6Ä]÷ý•óMõ×p4·¥väܦF‘†´Þ_פ¥è£jI]í¨Ï@ID|_éò±l½ LD»4‹ÙÂÐB¸Û´qVye,­mã¿}uJØØÙ¨ÕÚžjEMOÒ©Û‹!sdÛ ©æ}›i¦7=ŧF’Z(:(8ìo¶ù¹Åœ!·ÝÞ`1m»DD»Ã§6£_.±w»ƒ<ÞºÅúI×Óé~Œ>%ÝT“ýH—KûíÔc8Ÿrô£ª‡Äwzb#Ìy›HÃå-zó-bÛ~YE(ûG%ÿòæZ#®Ý6ú’>¡c/úñ.«šÆ¹+4{I³¾5Æ2Î`®lÍ’VáIëèä-Ø6’O×™–xò8Åv›dQp²„D=òY »¹ð›K“69ÃgÇEŽ·¤E­y–G5¡Œk]âÔº†§ì€^x4®žk”Ü\Í»Æažb½’öjÈ šÀI{‰oƒíÒVReLìÔáÊèq Ä~XËÙ¿0¦Vn.¸¸‡ÎÌf«,͹Ð+ÂÆ‘bÌ«Q!ÊÙÜ뇤DH"A Ÿá÷G:wͰÈìü~7¶Ü\!t€P€ã]:«®†£S-ÚÂkÖ Ü2XWíIÍ–ä¼¾ÈfÀëXMA R´¦ž:]3œ:¨³G‡Ù~dø,â¹Ï öíßmY¨Z¹H—[Åg‹¾^ç.'2‚ᩞÎÏœ|TfåÐ o”Þ÷Â>[½­÷Õ·1°mß“ÚÏ’ïmŒfDzè4Ž?V£ÐxSŠß¶´ÛN}•–;F+ˆ¬»¹ÃĤ’_Ütнü4Ó¬q¯†žÃÇÊ<½3ha0’Æ€ÓQ×ûý@ÿzŸó9!~×ÄWÓ$ý^Ȇgò4ôf®¼\,¦/«½G*œà7,àŽñ„DDej"""""5ôvß²ûŬZº;¦ª‰æn»›‰4ô÷Žþ’½ÈâíG{$¸lTLvW.4d™À¤&˜Cß Z§¢e!Dl ®š›wQ—¶” ´þb³‘EÀ5·ë/…Çð’Oô/{Ürºã’¸©$âI„~Êâr^1ÞšÞöGpôÚÜt¢,nìI¢·Ð©»<­¨þè–nçt€BÝHAðŠ©ˆˆ÷ñ›I.ÿ˜,ÕÅà­Är_ÒelL#ÿÁáÿ„•ÞÝlm¿'1pÛBöZê êÒ8ÿ„/ð]¨Ý{ç=Xw• ÞÑT{ûÅŸ7ø+ëL¶9ŽÛ7Ò;í}Îcÿå¹|뎽ss¶‘·£ïQýö¯_½¥ ãd=¡Çͤƒ’m£æwÈeSø­Þe‘o 'H c(ODTú”DÁÉ_'rV[›~Xn›:ýé‚åÌ¡§ŽÛ0[Ç«8¯¡ù£oÜ,4û»ŒßøMÉüUYíOéçFqi2­¯4…ªýÍe4•^hÇ“ #$ùc²´n &³¶)¦¨v¤?bŠZ“MÑ+”—<ɵÅÝü mc-«î%tÅ¡úšÏ¼eaÒ‰«Ç¥mƃcÜd-þ-žî9Ù îÛqn’ïðãQ Ç 7‚Å,5uû(pFAµò­ƒ—s;{žÓ]Úñlj¸2pœ„kÈ—Í$£`5QËGlª™È Ž÷ €€W¤n,w=÷FlWŠ6€¥ñ‡.ii7ÐA¡ZN÷”˜ ¬Yl}î@]ÂM55妭- $OZÂÞ2óÖ6Î\UÜYH8•´ç-ËE³™'1p‹»šˆˆJ%ÙÖe,Ù«½äZ³A >àÄL4×JõžJás›[jEƒÎ´2ê9¥!¡Íx {Ë… IIq¥zJó®idñ[ƒpÉ–Ä»U»âŒ–’æ·I¨p€tu.´M]JQäå½Öœ*¼’©ÁMºt÷©Sµ:¥;‚–”êªm©-N©ANà¨-N©AMºô÷êhBuJU:½Ê^ê”î T¡:¤*›jKSªPSž µ:¥6øûµ©-N©N~J\SªR©·_v¦:¤…"Ôê”ë©-N©áÑRZRǦ¢”èN©MºtÑáN©@ô¨BuHz’Ôê5%©×± 9ô©-N©ãÓSNÄêútÒãÖŠ¤.4€p¤ZO… yêKS¨W‡†§J|UÀÜÃRB*Î*TìM\Ì4¸õ§T€z8pW…"©Wm©¢ujà~zZS⮩¡EUÀÂjhª¸<4´¦®Ì4¸„T…`8ÑÁ:޵p?pQDS±\ J‰ÔŽ•®´¨Š‚¬šTN[x)QM Ξ’ÞTy×T|f~noŸßlÇí[¿ÓȾîÚºx¿ÙÖß¡bÌþÃg+V[†Ï P…øòâDÛ¼EgÀïfœ¦+æt+öã•þVí¯øú¤+òû˜ÿ>fëï{ÏÖ$]2 sÖýÅj5ìHæ(ð§áH륧±:¤ó›¤µ:¤óù* Sª@>Þïr¤µ:ýk|·â\sQp1ÉŠ¯e^ É¹wL`®p&ù€ #¸™DLm<5׺¸ŽÒÝ÷SEK€ ®{x]q3`í8Óþÿ©~½¸c¶m<€l{R%©A`fÔæj‰H‹éiyUP;éG‚)˜ÅŽÕ/h±À@‰ ]wJZü§æmþSzoÛì•Ë¿4á¨ñk#`!¬oê´4t¸’zI_kòÎêô!‚6Öáò¸5ƒq$ç“@]C@Sä̾ò,î—q:„CxöÏdSh†úG~f(è"(]¦gæD†ß16ð€—NÿÚÚ1]†²(4’9¬.r²„A² Z‹xÖ¨¨‚@& •c2”yké¼&ÏÅ lÎ2Û‰mÚÐØèàÀI5{ˆ'ñEI¯Bð»ýÁw5ç} od‡\ƯBå¾ø»ØÙᑈ,¤&Š´ÖÊÖ£¨=‡Æað·ƒ\åéÍñ‚}Ÿ|vÎHæŒÄu·„rMÒ'•¾lëŒ!˜ªöy]Õ_ÊLcÙùËfU„Ë•Œb=‹xâ-ÒÚ®PYS(ªß+í~`s’¬nÙÜøI²¸H˜dŒ¿ÅgCZˈ㕎`Y¬l!-h o¾ç¶.yœóœÁe#Çå%ñ¤cÃx»¤—B÷ÆàãÐç±åŽ>7ŒI.ú¬n¸áMã<«Äo–J=ºdåáìÆ*¡õû1:ÈKBvﺯpEt@ÄA""Øç ÕÓQ1ŽSp󧛼ǵ~ÜØ›zëà²K‡¹ík¸Løà†Þ Ð¸—<,s]B±ønXòëeNÜÖìÌ[ß>È@hipâ+_,“PŠ€4´žp^RûB¸ã–ã{*C#n°‘€Ä6½ic@?:a ùËó ·dúmŽ«rJÊ¢I¤N©¶LSçXêz7(yW/±N‚W6|ýÑk®%h:@mtE4:RKˆî$hn—Ì]ÿ.ñÈ £k¢Ä[‚!cˆÔkö¤}8juÑ@I.'Øþ -Ì?5즻í|ù>½§‰¦nKª&î¹›8]¢öñdnË}¬4ÂnjøŒuÄ«EDë"«RupQC´ ðŽqKŸÆsþÞãkÄ'ÎÃi⌀CôÃ!{%µÕx !Ü|BEë¶}Ê ¡ÏHbÄÉq+^ðH,¬Œ u@4£ôž ·ûCMWGbÿfß6 ÊÊû¾8Î÷¦ ‚]ŒÉ´˜¶#]\°È,ÅÊK£xHÄ·Žv‰®»AYGd"u d÷‹¿æzÝàßÁmœ¾î™† òÙØžE ØÎå¯/oÖ¿KXhçíVß“›^ß*ܶ[;e.݉ÂBÐX×HÐjçw¥¡§€qmK…CCIa?´ßXÎ*3ÅšÏ?yúk…SxÚɸ‹ˆç—<“Èçs—s6Ë$Ýã&<+$b•`M¯l%LVɳrW•÷;3oÌÌës™";*#¡Á’ kG½ÒiWiÁ¡ÇÍ ùæËÆìSœ1V@ˆŸBÒ÷’ ¤€@ñZ7Uu£mãÂoµg XæXÊþâ{£Ú4}8´\r K=lÙ¥ÀŒ#i×ñ,¯.êYšO=³ä¥#WE=MÙ‘Auä'nïÞAn»›¬MŒÙ]“tî†8è–k,kŒ3D f·0Ç &‚¤hôoï£ÍÜù¸ñû¦Òí#Æ è-Dò´5Áì q :øîໃn fÍüFñ#‰2ª6ÜdÉmË »;rZ6QÛ¶.cÌämG2÷<å(FNŒ-š¢Ð‰´rb®e³)Ë—ÜÜÉæ2웵v> !tÏg{rçH×4Nô2&BÍCÆ{žKÛVDv dlítwéËYÞÚîîÖ88E{²é+¨|V†€×QÄð¨Á¼1±®BöÙyµ¬Ÿ…±²¹5høÓý´-›J؇V.%WjH¸÷o’hW/TÞìý-ÁÀ`Ý0úÎghe1|“¾Û }ÎW<,ð$šY¥|šÜ©Ik+¡¢ …ç˜ÍÇaÍ\뙆 Ý´†’ÈãŠ6³H.#KM58ôjqâQ{Q/Ë'!ñ¹%qãûÆÖ¾­ÓØV3"OY× MÏ wº#¶…”„vù‰œ¶1€Lß ˆoW_ùyÄåpÛ*,ŵť躘˜æñ<áBXð×Põqê\ÜäÈØd÷D—XÙḵ6ñøÞÙP F¦’*:ÅVsû^4,ÕR¶)7Ì™€5ŽšO 6îàÂçóRæ¬o,ã™Ñh3Ã$Aô’btÐê ¥hí[O83X|¦2îÚåñ‰5ˆ¥d…µd`j qÓRM:bàþË;öÈǹùiûþòµlhÆ7;›¼n‹f _8”¶TA˜IMÓü=bÛÙ;%ÀàÞ$l$Ϋ7s ưMIM[7ŸN!¼Ûئ7ms(Ñ7`ųääã–@‚cd8ºÕ€ÞüÝ78«)r{6åßÔÔ|@If²Æ¸Å4`–ks rh*@fÀ2ûWšø È]Ga¹àÖ ñ¨ô‡‰#}5iax]ÇpÿÜ"p…*¦fâˆ\Y“’·c¥ËoÙ5·å#¤Ý:dᜠ°æVã‘»¤ˆÍÑ…»dš\‰V2ƒÙ”ÅÊî>aï¾bÙ·llÌ%ýƒ¥{;Û‡:F¹ êw‘²ÔxÎ/%í«CF¢C ³6–˹9íÏ•´»µÚ! cƒ‰WAsÝ#¨|V†€×QÄðªò+äÛ[2çÛ!Ú6\=…mMH »iÂFEIJˆ„‹bÖ*8ª³‡nÞ<²O[²/0‹¥”ÐÆ.ƒ_Jl Ûwkˆ¼¸’òþ&ög¹Î/‘Î.u Év–“¥•㤠€W†ï Äy¬¼ù+hYmg#†ˆšÐÖ4¶¡  D N§õ‰¡_I¡J +Òx-¼S•M´‹Sª@S«¢ µ0R‚SBªPSn=ÚR¢uJ sÒÓØR‚›j SªPS«¢¤µ:¥:êhSªPSn4¼)Õ()S§±:¤*›jKSªP?pT–ª!TÛ¯MM(Š¥:B—UJ uôTÐU m"Ôëõ¤õÔ§T€}ºwxªKSªP??’¦‡©:¤9† uJ¥@zª@?0Ô–§^Ô€z‚ÔëØÌ:l©-N©üþJTìM ˜{¿ÃKÂRùéP„+Þ‘ju)ãRZGR¸<5:Sª@8óëRZUÀüü”¨GB¹†•{S¯j¸ŠŽ ÁJŠªUÀÚxjHEB¸ž§J|UÀÀ=á¥DUX !¶¦5p8tR¡M\n´ªBu*àq£‚8+‚Š"ŠÀ4¨Hé^€p¨–ôY‡Nú‡-~lï¯ß|Ïí[¿Ö$_víÝ<_ìëoбfŸa³ÍÕ–ÅE; žhЊ/Ưæâ?ˆ÷´Í¹X9Ê@ óßi¯jòÙºšàÖ88p=-5 ±c,bg5„jèýÔ¾»ûÓa¥ÎÉP;£2@ñŽÖ*B¡Šæu"V]Crœ„\ŒÊp×@=«¨î¬>ðâwSJöþ4¯"– ‚+¡ßˆ…ÆmÉå‘I2ª·ìÙ9;6.Ö§!¸Š.C³n¡{6ŽJEH"tôï×ýÕ£".–Hõ4ëP=‡á}*íY+ŸÝèêtp¡èãÕÒ»ÊÖ™›R5{_ Ã9go$±¤XJLöq-Ù–& #£ó¤ìL@Ý¢(”ÞQéËZ®FLtÒ6ç 7nÚM#¡Ôé¥WJÊÛÃsLw -ŒW¦€Ôq¨·BÜ®kË5«3p–½’íV(*ÝTõåÝ:'ÿ(w‡–·,LϹ°c¥¾+‡ao¢e mµóÚÏönñ‡€ÿßTeSmd V:©ANzšꔪm×§»Z\ª@S«Ê´Õ:¥:ú*KS)TÛPZUÄÀr‰L€†ƒPYQCШ8Ž ®/iµ~aU0ÜPyuAÖ°×xˆç:›Ò²vùÅâž…°Èpcn™c‰5ïj=êÆÿqÉÐOÜþôe*ªæp–ÓXÀ@Êœ£§~²v˜¸­øÓŠèÜ_¾nKÙhŒ­‹{³>1ÉV ~F–•”<^?{xÛ­oyÔÈV{ÔÔaj/"Iç„;6Ê*›s¤™Œô¢!òùÛ[‚oæZÇ9…ã°M‚0ë‘ ¦‘o3H3÷`‚@¡wI¤¯£¶¦o$.ñR]Û7*é^D&V H3FA—k5Ÿ³Ð ê^Û–¢®™B(bƒQ¯¦¬q/’M%xeÞA¬’…v,¨„z€²žýNþ¦åk5iŠd[ºV.ã éF‘з‰ˆ²‰èb†ø èÏwŽå´ë\V÷„Ô.2À;€±û=ÉäÒ°ÇúÒ§JÉz7¦œW5‡·[Æ¢bœÁ ˆÖNÛÈJq]ï_3«Ôí¤Q~/ü¡6õq·ÖÍÞõÕS¯œè»µ¿ÊGI° ~PÐÉ]‹›a‹¹9›¾wÎ&m­¶våõ´÷mÝãô±Üʘ¢da¬säuK†HpÛ0{iíLŒYüînÒx­Ý®6 ÔáÅ®á$Ž~“ã1µÔ©ÌŽ3øoŧY&«¶Öd$Te‹bñ;7ÊZ°¤^' ñóeff%Þ½Gß GLÂ& ˆû_(ö<»'nɸ-vAï3N[Å¢G†‚ÐzÃÖ2¿Ö-$p+Ëyº£Ý9™r0‚Û6°G<¡¤Hê.sœêuCкÆRÜm,Ô…P ƒ§.µí· ¸`í/,†íð¾ ð\8,ÀÛ€±û-{ÚòiX¿îgÖ•:Wûͧ«ŠçöõºÞºŸNQQÖ²V¶ ·+£qvé…ÌJ§Uw WV©ANòR¢uJ mêT Õ()RZR‚›u¨-N©J¦Ý*KSªPS¯¢¦…:¥*›z†•uJ uT–§T ¦ÝjKSªR©ÕPZª©AN¾ŠT(ªB©·¨iP'T §=NžÄê”ÛÝîÔ–§T€~®Š‚ÕUJ Á©¥T ¦Ý)xUU()J€ô"©û{½Ê’ÕUHç©-ERüÃÔ5%ªª”çòTТ©NaÖ—´ÒéiìN½‰@üÃRZ{UÀüõ%©Õ ˜zªKSª@??’•èM!OÌ4¼)Õ •èE{ù†‘ ×µ zjKS±\$ê=5%¡:«Ã¢•M yéxQ^Õp=¯B~p7w†¦‰Ôõ«‡ŸÇH„pêWóÔéOЏ0Ò¢*®-Nš¸:)P„Õ€iU:•èÏ ÉoC”t0¯Íõûï™ý«wúÄ‹îí¡û§‹ýmú,Úì6y+U[†Ï%_‹Ž' »Ä§¥æÎ9d•%¨ª@8ôÔéNªàpèé¤ZRƦ‰Ô,ºÀ²ní“°s’®î¹†êFYé²Px9 7mÓ‘¼£9)D·vÑ&{ÅÉu= ¢D5Ò÷;,ïíÍ•ûÚÌcf¸ÿã2&6ÿhx²½Òqš;£Q![Ö"9mìc’÷Ť´ÿd¸ŸÂ;Òõbâ¾,¢ZSØ®Š!bÏ02“nc·`÷ã çOdä]H¹xåc‚Š*(î Óå•,ðÙÙ3po9|Y¥¿ûόǚ½º"kXƱ­hZÝU¡è[ìw°Eg&66-ˆGÀôõ¹Î$’I4&€à±êÊOcI+fÁô)ËÊžJBkµŠX±æ`Ì¢éI4gÔC&]æL"";Îç¾›rn(ò¹ímŠ2ØéÝ3V³À¸¹ÏwŠ ñkAÂu1ï8ëSmdiª¤“ýcBßM+Ú±[+ÚºÅUäD¢AA“täRNc³ª›ÄXÇ•”I”jMÑÞÞß2¯x“—~Âgv´÷ÝÙŠéÒ-% 7‡M$þ%‡¼°»kìãÓÇ£²µXH³"Oª¢· ÈѲ+˪V+Ò©DD=ñ‰p£aŠ;½ü3Õ±ZÈ!¦¯u‰‰%•¥¢wzš½»v´”ÈÊ”aíkqÂÅ“¶žÄ¤Ôc6…AÊŽ»PÊw5Ð4Þ×½ÉZ”ù˜ÍÀö[#ƒZ$ÔÒãSð,£E§Ü¦kÞtpâ8žž¥Æ®; 2¶mEfßM̵E»øÒ¼·n¨¶äUÂnÜ<1 Ýx¥ÌàSéÈ`(ià¬Ø›q\Êö°C¨#[xPtb½œ+ÿ¦·ûnH\Y¸b ÙÂÛ±³íˆ`Ý%ÎÌW v…)ŠþN4‚`å×R‰uõsœniÃSîŸÓý ªeÍ›>Í»^>’» ƒf~›Þ"Ù´4pDníf—fRM3iƒ„‚8tÔG”G¾нÆI+÷‹«‡šIOÔ?Ì»L¿ Å ÞÊT­W:Ü-´½¸ª×1m§O"Z,»¸›RÊ¡'èm½<ȶ(ɦAtQT8{”+·q6RÙß’{~Ûº*hhMkÙõ®Åíëû÷ËÓV´ô V”!b¬­ÓsK¨ç³ÌkªíMÙ€öZÖháqђﺆÝ'€qúÇêXæß]HÆ»¾&¿WÔ¶ÛžàNï4¡4ÂnNÉùݱtäȱ"ï cvÀ€:Q@ß05åÛ]KhÙ÷'21¡Ìs™ÑNƒÃ¢Ÿ÷.Ôã/‰.i wOhãÓÚ»/¸{öpÌž÷¢ä´ASDª·UC¹HÔGû$Êp&¥8sVW÷eþ½ø¨íô,&ᎌ†N±©§ê5 °ANºÎÐ-f©M¾>í)§T ~%AjuìJ s IjuH TЧTÀ§]*êÛ§¹Hµ:¥÷AjuJU9†¤µ:¥*hSªÙeâ“•(úò t/,Ûr(WnÚäÀVáÌ‘È%ä »ka4Ž…3Ìev¢·Sú¹ËW R•Mµªª”ê©¡N©AN¿%*'T ¦ßN”ꔩ-N©J¦Ýj SªR©·Or¤‚SŸÖ¨R•M¾:E©Õ()ÕPZª©ANº‚ÔꔪmñÔЧTÀ§WE*ÁJU:Ý©-N©J¦Ý*KSªPS¸*4§UµËF!*€¤§. <¾}Úê\Ú¶áš\»\:T.¾=‚ A5L ˆ÷€G½­`Ý…p4i:VU¹0EHâ¹½k¶ˆþÓ@2Ÿí‡”u®ý¦5–ü¬º—7¯›‡Rç%S@Ъ²«¥T §UN’R‚äTN©A]¾:šê˜ç©-N©J¦Ýj UU)TÛ§¹S¤§T §^ÐþŠI‚”ªmñ÷êhªPSª‘juJ uÔ§T¥SnžçôT§T §pRLÄ¥Sn¾í*ê”ê©-N©ANº‚ÔêªmÓÜ©-UT §?“ú)qLÄ ¦ÝzjhT §U"ÕUJ mÖ µ:¤6éRZR‚u4!:¤*›téîÒ—…:¥)R½ Õ(˜jKQT€~z’ÕUH s»Z‚Ôêçä¥Å:¥6ëK‡Z*´§R·ü5%©×êH N”êÌ:ô÷kRZRùù)P¦·^ï%.iÕ •;^Ä€naîè©!:ö«úêKS¯b¸<¥I Õ zjt¦®Žš8„ê4¸"½©ôS±?¸¦‰×µ\=5$#À® -)Ô«€ó I©ÕzcÂ:[Ði9J>2kóW}þüfjÝþ±"ûÃgþébÿg[~…‹7ûÖ­Çé[GŒhãô¡~'8¢6œLñQöuËɲÿ¸¿p¹LßùU¶áüwêp¯Ë~`þþç?kÞ~±"èÐ0†·ò£R4¨B¸„øõ$s .íWóù)iM\ Ò¤„ê»âؾ$¬·ökæïå±R)á»n–nÖUË9-Y®DÀP6ìТUDÁ¾dÌÐy5›üU¶V) {é èK€:A”8}!•Óô¯B³•ñXC§ Æßõ?γ/[ ú䞺̻‚,Æß¥p+µœ3)E”„nvM¤ÛÆÌ‚ÅÜpÕœ„`.;¥WU›PPÇï‰Aþµ™Û¯{îd‰ä9Ѱ´‘Ð\ uôW‡Ô°»™´²ü@t•´ Óñ.. mÒ¶ÒÕ¥U()SNÄêªmÒ—…4 §pR êL…SoPÔ–§^Ô §UIjuJU6ëPZWzYü5ñ[äºìœ•®›id޳YÈ+䑌M08œb¶Ž:RÂQLCF¨ïh]5Ò²ÜÆØ8+ó‹Ìæ±vÙhèå¹…a4ûm/?×ÓÃBÙñû3wemþ7=‘d9®èÚ;£úµ]E%' ò&f=ôL¬s…ZHFI´pÂA‹´L$Y³Æn“IÃg 41R˜£È![e½Åµä º´‘’ÚÈÐæ½Žcšz×4Aê Э~hf¶™Ö÷ tw 4s\ \Ò:A„ÖªùM½C\¥«Ž©AJ’ÔÁJU9† µ:¥:©P§T §@ÔÐ'T ¦ß"Ôꔨ-UUÝ–gù÷!Áý¦±°ÎN»-ÑŠ36MÃ#ðSíRG¾nÀíä•HɈˆS b€é™Ž`lLï÷no1µÈuÇ-ÄL{kJkiuX x©l¸ÝŸºòö¿}Åão§³ê|pÈæÝ$6ާXmHúÂêéX¹{~Mì,ô\”Ìkƒµ’‰—dæ6J=Òc¢Ÿ0z’.š¸LGßBÁá Ùín­oí™yc,sÙÈÐæ=Žcšz \ÒZàzˆ$,ŽŤñܰÑÌsK\Ò:œ×Aú øÁN¾Šç \UJ mñÔ–§T §UAjuJ uÔ–§T¥SmM uLU;‚• R•Mºûµ%©Õ)TÛ¥AjuJ ]Iju]fáü¿‘#šÇø«$_PÍ_+æZϱ®{š1¼š-Ú»Z9wð±oZ¤ý¯QTȘà¡SX†ÐåÖòû¿iíû–Ù粘ë+Ç0<2{˜aya.hxli-.k€p%®¨+7ŽÛ›‹1¹ÄØ^Ý[5å¥ðÁ,­Òæ5À84‘ZЃÐBäR|;ñ #55‚3444Cr’ÒÒ˜Â÷aÝGoäd_»ƒE«&,š¤uYS4Ó(˜Â5жæÀ¾¹ŽÎÏ9‡šògµ‘ÆËËg=ïy kÖÈKœçÐ $€Wn}»í`}ÍÎ+%´l.{Ým3ZÖ´UÎs‹kZ$’¤®Ÿ:ú+n-Zà)J¦Ú‚ÕUJ utTéìLÉUµî¦ÖÛ+É͵>…¡%$´<}Ö¼4Š6ÛùvégL§Nرn¤I#èS*R”DJXæe1rd_‡Žæe£ŒHøŒ362@tUÖI8€ÒH¡]ÇX_²É¹'Á3qÏyce,pÏK%4— - u-Û§Mw¨ ê×µ0)Ü%©Õ()·Z‚ÔꔪmÓÜ©-*ª”ëÚ(¯bb©·Çߥ@SªPSª¤µUR‚u©Õ)TÛ§Oz¤´§UºEGÊMÈ3ˆ…/- ¹0ŒŠhâBAó•9nÍ“TÕråsøB˜Ãà ë]\ÛY[¾îöHáµµsÞàÖ4’ç8€í$Ío÷S6ÞÕ’áækAsœOPh“ô»>êÁY²Å‡ûCxâ|‡mAµ˜š´g#㚊›€™æûª8çÏu:t´:®œKAë ;Ú{£m÷Ì–>ò N·¾µ£ÿ-£~€ê~%ÕeSn•´­~©ANº‚Ôꔪmê’ÒR‚]•U)Të÷jhT ¦Ý)ªªPS® µ:¤*›z†§JuíJ wJu[¤T|œä‹xXçÓòncÑÃù)®T*MÙ±bÑ5];táSHše1Îa®½ÕÍ­•»ï/dd6‘4¹ï{ƒÆRç9Ä5­‰$€Jæ·‚{©ÙmjÇÉs#ƒZÖç9Ç€ h©$žR¾‰h©{zMì$üT”Ìjæk#0ÅÔd›$Ó}»ÖRAÓUɨjES½ê‹K«L…³/l%Ž{9©’F潎ok\ÒZáô‚B»›{›9Ýkyâ¹a£˜ö–=§±Íp Š¯¹Ý¹rÇBCܲüÛrâ;äíûäKö°“ªE¸3I4áåVnFgŽtQIpACŠ*”ú%uâÈãn/fÆÛÜ@ü¸i–&È×IxÔÃ$`—3[|fêPâ*$–7ÐZÅ}42²ÊbáŽc„rš;CÈÒí'ƒ´“CÀñ[@)·Jí–®µR‚ÁJ…0{M½CK‡ZuJ祧±:¤íî÷j Sª@?pT–§T }ºÔ–§U¿ÅÛ×Ó ™Hx ¹XËq²O. È§ÏØA4\çMS/ «x¶Ë(™ŠE2e0”@Dº79,}”ðÚÞ\AÍË‹bcÞÖ>WRØÚâ È  ·oc}u ·°Ë%¼ ‘ÍcœØÚz È0P´‚uÜ ]T€p¤Zª¿Z@8óÔ¢£À‹UU yõ¨-EUÀáÑKŠi@ý~Z\ð¤…Sª¸˜jHE{Rùêtªª¸˜jHíERÇÃËS§±5p8søèâRÆ—pW…*'Ç©\ ÍH„ëÚ½Já-ë}°éßI!ñ¦Aäñ׿ŽüýøÌþÖ»ýbE÷–ÏýÒÅþζý sv=ÚÖ©ÿn…±)Ø÷kGýº¿ ó—Ão&A¸k÷”£þUmŸø{úœ+òߘ5ø÷9û^óõ‰Dƒ¢½…jWxjH Õ\ÏKJÀÜÃRBu*àq¥Døx„ø¬ýáfÖ°²L;«{#½fÙx™f,.ÎÈPP¥e1©*Ø®ÖE·¤‹cœ ¢NÓ7¾˜µáüÁÍn-»vëœn– *ÙÚ5jh5{ÚŽ%ºÀà[N{Ô³Çå,!mì¢'†Q„Ò„´é-5 vÇ¡f]ÊâÚ‹;´Å™êˆç|G tìˆ)»bš´D…&ºróù~,dïešNíŽ"MÀPº¼ZâOk‰4Y›è ¶yŽ*<4‘¨Vœ:8Àº=ò-U6ôö†9Îc&át\{³X"tÛ  S€ººÖóo$ÌŒ‰t:ƒ¨Ö+ÒOWÒ°R†Ö­è[S(øÅc§"&£[º„¸Ìñ)ÖÆ(œ’MÙòÙN]ôÑ @£¼÷À 4ï"/s$µqmËÓJñ ð÷öp+‰²¸¾ÁXÃ/·¼œ^J䘈zví£!Ú,“uaH¡Ô¥ èê&w*¶ä1S\Û†ÿ-g¡Ý»Šä‹(àcdŒMzOgi§«é\BÂÑÕsÜü:ðùkaù †ç†œuq’êdÍ87Ί܆g¨Û–ªº§dºª»L¦*Å0ˆ<5ªîLÕæWL tN:À¯:EOObîE¬žéÇU>•”ïÛBL£gì“{ènÌ".›”ÄIôzåY£Ä¨Š6] ÝÐu.µ©1·1=¤º­ =GªŸŽ«•²ž£Ä-åÀ¢šn7Žeç÷¤Pºo Îrˆ‰Í®¿äë]i-ËYZŽŠPt ó®Q3öŠÐË‘EWQ¾è”Ü@ê€ t€Â:{ã”F˜Œµl½5¯ƒÂ¨=äTNÅMÅ`0‰È¡•ô(¨•0H»„1D…0‰‡Qðìä«€é#Å"”êÝ)§T ë ‚Ôê®ÛÝîT–§T §=M uJU6õRð§UœÏœUgåž#áÓÈlI/aã«^éË7\"‰tg#¬v$vÖ)Ëeqã'.Z‹†æ‘Ër#éÄCÆ9õº2Û[—³;!‹9¹†Æ ¡÷.-sÁZá~‡ 8µÀÔ霦ÁcóÛÂ1–h“g·R³¤=°¶¡¤u´¼·Sx‡6­"„® •øÄâ,߯¯—Ù*ñ¶ {[^سîy»rÛ²#˜¥Šˆ¶#"1lÁ(ÆÉ&Nܤ œ¢§2‚&¬Þ×å&ÄÚØ6a!ÇZ\šiáŽY®^~Ü“=íqqy$é'KAÒÐX¼÷0·f{*윷·xß›Ž_p´}–FÖ††Š ©ÄUÄž+(3$œNðAmñ+y&ƒœß‡rÂXZø¼Á² ¤r‘)„ͯ)q(܈¥!7åê “WtV2ETê‰Ê!æ»FѼ¶çEÇ.±ÍÙy|YÈ[[Ô–ZܲC̈Kc”5Ò×Hq`m(Ví¸®½¹gòÈ€íÍŽ¿sM@q ˜¤¥žÂàÀzHÔOH_~Vàç…®®è[S3q?v%!u[öôÜTU•‹BfJÙe8ܦ4ýò²³ Å¤Y•R¢ÍºYûa)ä)¸6·79›¿±Se6~Úµ0ZÏ,o}ÅïvÉÿelZœý:K¤“DMqÑWHäÏrïcm„v7p%ž(ÞÖÃm­Ñµãý¤Ä¿HmjªBѪ‚ ·W€‹õ§ {y[Œ­[VÊ[-Îfw/öEžA’oÍ’NUU@2jvhÙL^ß±)œÄÎz`ååí¾ö†Îáù;«Ác<ß» \[÷]D8]æŸödÈaʬ¬{Æm¯-Ä-±‚ØÝ>ðƒÝ 05wúA' éÑ«íÔjÒ Öû ÂÇÙ±­Ùnð½o Ó-Zì…ÊÆÊÈ8ä–ƒLŸ™Uš I¤Ì‚í%†ª·`ùHX ÂU“é^s?~lÙmrËÂZYí[»†Bë‹[¾ýÖoÒ?½1Ñ´9„ø¯’7im âKîÕ¶ÅÚ{–;‹M‘”¸¹ÏÛÂé öýйk_Ü8=Ä:œZÇG£€pÙ1_ ¸Âãá¥&2–p[Û-rÃüy) …ž­É1,›[sã†m,ä[I¶4¥Õ*ñBp Ú6d“‡j, ‡f~îçæ~åÇóܸÛ8Q‘É;Û¦HgÆÂé{·:à–1 MÔ÷Èèâk*ýC«ƒØ˜KÍ–7¦s&l¬›~ëw0Bd{€X€áªW ;KZÀùïIã÷‡kÈŘ×=áŒ7bl3;i˜.Ëu bîµ.û|uâeÙ³bñ)ÍÖYP0„OAÞæÈì^`fó[Ÿ#±w…„6;« sþbS4Á-(øÜæµÍ,%­s\*I¨¥×´1˜Ì–êÛ—rÝà/$|_ŒG,RÇÒÇ€ç4‡\<ë¨+Ч]zÉjóê­îÞuÚvÄóe^Á¡-´Ë$dÖy“ÄO"Õ”éЏfS¢(€Žº‡~ºwñÝÉc4vN ½tO¸ô5å¤1ÄPÔPžv-.¢}ÓKíD/¤°¨Ž$Tt¯o¸Žµ8¶Î× ån òãË󷇶‚ôpÎUoe<Æì"¡#›))`nØrÎi6Êt©.ôtÓ1S*eI?Œ9y”åNÈÃ|/ÍìS,wæ›ï3ä,ÃnÜùDŒºîæk£, T–ÇPçââç}5¼¬9º2_ßܺÈ:ëkãî"³º›vµ¸Èxp&”sè@ 0+‰kû0gÃãÜŸˆå­®!m¸¶XÞfb]›È»»+/+*Í•âZìTaRzŠÊ*šNˆ£„ß ¡9LRB½Ë—8-¥²±|þÚËEs°.%uÜqÆæ¾ Æ9×’5ï«H .a 1è ’Jò­é•Ü;Ÿ#ŽÄg1òC»¡`·{Þ eº.pl%ì-m5À¸?UA‹³¤øPáŽË¾Ú`ŒƒÅÌfnYÄ|,ÄŒ7ø×Ú7„¢hú=¯1p¸žc.÷°tá4W|š)7ncÿnŠj”šÕ·4¹“˜Á¿|`vÌ2l°×É%»Ñ}=» ¬ÑÄ"tm«Asc.sžˆ^ÒsSì-“Ê·jåó’3sÖ=Ì·×iÎ¥"|…í{¨Hx­¯¦Ž¯`ø8ŸBW‹býž=µtð¿b¿¼gl.Ã7)œÇwN\Ç.Ê&n-D·\Q2‚‚å&¨~÷›¶/µÚÙ<xÆn[æÀçètàú´‡>7‡1íÔ¦š8Ž+mË›¦OŸ±ÊÊ`¾ÁÚºRÝM–œ[BKHcÛG5Ô®— ¯°F i˜¬Î n·+˜0ž.y‘2B1'éÜ 6Qr[…”zÔc’?cþêR¬!¯ù5°o}ñ6ÑÌ`qqÛ6værm´./-1Žkµž?d–øV#kmX÷7-~ùÌGbn ﯊MFžŽšÈ{{„\…°¦vÍ\D«mœ«w({n>Ëyp]®& §RˆbÊ×i»Ó=ŠI¨,æIû„’M™½!Îè¦&æÆô»Þ9‘³vø¿Ébä€wϸlPåˆÈçLç†éyv–CLƒ¼y-vû>^í‹}µŒÝ;—0lì¯Ù/æÛ ’Rö<1¢ Òu0 ºG¸Ï´%àŽ'Ãf$³±¥–¸‰Ë%•“Ö˜qЬkÍFæ¾®;V)âmò—<œ¤LU»àU!ÐI]ãºI@:gÔ @ÊÞóuå÷%ÖÕåö*ÚòïØÅíÍÍÁ†Ú)žÒï»Ç¡’>WŠç6Ž®Xë]—·ñØ[}Á¼/æ¶·¾/6°A’y"i§|ýNc#i¨-‹¨=!n¡ÁQ.¼•aÁbLµmÞX²ý²&²Y²t“% ÏaÙÖš¨%y+~Û>–íäL¥¼«¶é1P©»UÊZ"‰Å>©ç!ÅíËëí׊¸³Üö7±ÙýÍŽ}æâpM¸µ›KZöJçBXÖ;ƒˆhw8å ¿ÍZZíü„8+»WÜýåÍ,0Cc(y4 , ¸—4}­Mn¹6mŽ;7·®s„ɽѱҴBøåcƒÙF¢Ð+S¨PÑGÉ?ü%AÞq¸š‰k®bþ~þ*ÕÓbc¸ù¼Y;4 HÝ™%¹BNu“'.Šš®›>ºˆ$%9K®·~óZ÷&ê°Û–°àcò6 ›·Gzø£©.Ð!ÑœHcÍGki9“´y}k’fß¼ÍÏ&Yïk °[µö­{éA«½Ôö´ ›Àÿ£BÑ85}ugŒÙ‚o;ê2Ì’ÃÖ%Ýw¸º Ðîm÷¿g¤-¦ì\?QuZ9‹€¹ñWŠ*Ýÿ¹k¹¹9Ã/cawÆÆKË|½ôui•½ë&. 8>V¾YP×8ý [ Ëio÷^Ojä®Ùm>6ÒYŒ´¬nîÝiq$ÆæÈ]BZÙ%}Iðá…o¬”æpng¹okÏ Z®/‹¢6ä°¾ÊÀ]V¤P˜'æm–w&ÍÔˆ+7É‚ÊJA!DÂbñžbo<&g½°öÖXlÍж…ðÝwòÁ;ÿÙGp45Ž/>)1 Ôê4¡±²öÆWsµ²SÜäñ–æy[$ÔrÄÏö„ë.£5‚µ¥€q¤(µrçy"ã±còS©„1­¥fZhÜ×Läd „™ÊÝRC!'Â.«‰&cv®ˆ`Q3h ÞËoÍɺ®¶žÀÇ[ß\c[¼žâs ¾P\È¡sä-¸FZá^ަ?há-0û‡x^Ík ëž-¢†!,¯lfŽ•ÚœÆµÄ:\ A¢Þr ¬`pÜç_ëå¥8u±¶¥²µ¤“sAËÛ‘Œ}!’ܵ9†xÞž è›3¶PJ¢©€(==³ÍY¯çÜqîËâ›·#ÓRa9=äs=Ô-kC‡æ‡u§Œí«Zïv3¼¾ŠÎ,+öíáÈÓålUˆÄ‡ÆÖÔ8öž=x0´Ð¹¼W+ÿ« /‚a'üJM/ ¨ZÎ&Zc£+‰™_\}–Vei¤f”I“zä{"6€¨bH¿â72eÂé܇á.뾺î—榮øF#1‚cüà‹Q}›7/Ä]çt^-ëhÙ맺// ˆd mx:ä "ãÆ7µÏîæ…eqÚRîá¥EAU¹—lxéšÆ"b»ÍÌESt½¢*ÚºW¯à3˜íË…¶Ïbœ_Ž»‰²0‘CCÒ8ÑÍ5k…Mê^m—Å^àò“â2 Ó{o!cÀâ*:Áëk…ÓN ‚¸™TÛ¯k-¤,}V{ð)w[2Ù†·•»²Åç×·0õýu,›(h[ñ3øñ–]' ¡ßÌ“ÑÁ ˜¢‰ŠMå T•ðŽxâr7ö˜‹Ãgq‘Ú¶y6BÖ]$‘ø®Ð263¯S¡Ô ¨Ð\ßYåNBÊÒç%l.a²Ü6F;;‰Hk!>3uCÿKˆê T×vÌ+~>¸l¸~_0/cµ™IÝòô[(X÷eºùƒ´žº—ô) ­H¶Å"¿¦8j‘ŠSTNrŸU½“üÆÇŒ{ NákÙÜHÛqes­sK[¦@xiîÚ÷_h#aµg76MáËe"¼Èá‹]ß1Ó¨%Í!Åú])hã«[šÅ$Wĸb'-þ¥d«Šámˆp¦?p”Å6£'—CƸ$VNÛ²í–;'óNJ€(c¦T‹º¢€"rþ£º÷•ÞÓþíÛxûwe÷ûK"Œ9°µÝÓšâgB(ÇP\jÖžÃ@ÛÛbßpýû7{3qÛḃHúK{Çî›â™x6¤Š 8ô€yeÀqµÏŒï£ÃÞHŸ½ZãQdã YW¥®µvÄÀH,£v÷LZ‘ò2QÓ1I¬‘ÅÁ ¸vÉNqïqXýý¸ñ›’Ïls”™-BÖâÞc4•€ ÃØÇÆòÐMCÜCZ:HÈ^m %þç=³¯fºŽÇI¸‚x„r²7¬Òç5ì¨:€¡h“Ð=_…Ì-ecÜ]’2Î{ql²ÉØý¥ÑjÅZ¥î‡NÛ‘ÁÙ¢F*?I­¼Äª¦S?p™{UOÙ”€%¬|ÏÞy­Á“Û›SÛ™±—î†IßpØá´Ð8ê .•Ô$DÂt´j$‚²¯Ø[c‡°Íî» ŠúÌJÈ™ |¥äVƒIp¶ wޤÐEÓÏ›^V¡4òú·ò•™hÞVÙ£SŒs6ÚìA»2MãÔP~‹òöb˜«¼P‚`.ðVå±÷ÈÜø{ûܼ,±Èbï'·ºYxŒÁÄ»QkIioé¥C€­³ºö™Àäí-qÒ:îÎþÚ­äÒ^%à§QÁÜ)^°M*»b_„èç[«Edfd·±u”ÖñÌ*b!Da¬´o)4“F,ݪ¬ÚÌÑ~‚h"URUuûB›³Ž%Õ-9¹#ö5®íºÇ<ä2—®·°³Ž@d¸%å‘—9Í0â×8µÍkt‘«SAØ.9pÆî˹ozß¹ØZ‰¯.^ x i:ËCšÚ‚çjN“AgÃæÊׂ|<勞ë¾ìˆ×BöUóe¥m«xÀÄn »Û9û)7Àg­ˆ¡L“ ƒ…·€=茒ówí‹Ë7smk‚½°‹‹kƒ0·–J÷m¸k˜ßЇHá´ë¨ #Ù»o=mr6vB{Œµ¬.”Ã<#4lûn…Ís¼aÒá¨×«‰_e‹Ã>0w„ì\픳_éí±rÎܯâR¶ÎN.æEÔ{–ËV ®âEg`Ðë9UDJ“4ÀÛûÁ\YÎeîx·¥öÆÛ_ï ´ÈÇ™„Q#÷:g8ÀÝA¬hqt‡¢”+“±°2m{MÙžÊ}ÎÂydc˜"2<–8µ¢ ÒK‰¡.% 0tÖ«'IÖreµ¾ùyHòÒ(BI9@Z¹ˆIâÉÆ¾rÔÅ)›.í‘H¡Ó!Œ! i^½bë¹la’ýŠýÑ0ÈÆA’‚ö‡u†º °*¼Þí¶ÑÝÊË7¹ö‘ÁŽ"…̆¸Ž¢[BGQà¶â©¶»«‚«1øJl¢9Sˆ™D’3,d:qmzBbtdÛØŽ-‹¨¦>ñb »•×8€Q1>È`ñîlHü·÷_/m‰ï³w­PжÊÚ“\º½D†µ££U\Úž úW.ØÜqÈo9À1b­IŠ£ºž±@>šç4é[¯¨—"Ú8o‰¦"Šd›e;;#=ÍæùFÁH°Ï¼)4ìrC´MväL(·›MâëÕå{ÎÝËf9i9!¸Û“qiZñ²º=ãZÞÞæG¼ôj}A\ûùƒ5Æo¨…]}†ç躷]ÙÞ°4témOH]“0ÎÙ’á‹7”«È;iÕßšÓ“’aY·H/é6!"Ìá©]‘˦‘ÀNR(&åÓA×,æÉÛs3}O‡‰“ä›gŽÐÇ?»i?uejú;MWH…j³—1XO±6”Y9‹®oµ9¬ÖGûéâÔV® Ã1ÌwávëÛÓÀuà B(-cd¸<9¦Ži.uÚ<†ñ.ªêȰVN”°pÆožŸÉíXH9€gvØå¶­\„ê)¢¯GÛrE—vö%Â[(¢^š˜Ê^þèåÚo÷þùÛ6±ç·ž }°ùÙ]Ï}=£^àÖ¾fwml€8€îìð'¶8 M›´³×ÄmŒ¬ÓgšÇÄÐwQ\âØ¬¹†€‘¬q§eHÛq_ –Ù‡¦³GÊdÆÖ®Pua\LßÛÎez3(‰S’£W!!s;–+b³wRI59„1³ºy‘—Åov~ÝÅœåÖ-·P¹²†6®–F~qÎ Yy“U\âÖW.¾ßØøÜ†Ú—ræòp¶·¿6ò5Ñ—:ñ:)sô†R€<š4…¼[|9bKžÇÉU,ØîX¹ ­¬Ê^^ÐtêJ~xÈÇ©¸cƒ†¯”¸^:ìh)¦EU! ažK˜»³œÆíga[q¹/±îÑÇpÖ²)ÞÒ!h‰­f§IRx†µ¥Ä.Í–ÉÛ—ø«íÀÜ£¡ÁÚ^ˆš÷ÂK¤ak\ Xwxâí-eá©ÎÃòn±£±D>nÄW¬åÛc¹¼W°'˜Ý0-àn+zåN3ã†à©>zÉã'qâSï³ L'0'™Û;×9qº¦Ù;ºÊ LÛlÅÔN‚S,RÂ_Ýš5®kšúŠš;€bó»[Þ‹um»©nq.¹6ò6XÄrG(n±].s\ÒÞ<:*:jiÉßáþ,3D@äŒí;!xHÅÇȈ0µ#n«JÒ^A P#ßOšt§]™NTY¤]À6šã ÞÆÏ ¯öÞ ðñÊæG÷Ùßó†kl]Õ"èox領]ù¶ÎÈÄ­3™iŸ“|msþë e†áö]'yùÂÞ“ }ªîž°%±ŽxÎaŒr«+ ÌIÊYml£)n_ÑòÖ<ìŠ%›É,ªP¦‰9œLGEÍ»2ÁºµiœÀß¹=ÇÉ™7>Þ‰ö¢IË“ßMjøîba–d×%PX{§ê ±m7gØa9žÌjF\1Ï€wAñÜ5ðHà^Hf–UÝüãt‚x9ut>>} ÅKìa•®¤,»*Ù‚‘’cñÄI^àöBDŽ fc“–PØC?IR íBŽöéuÒ¶{ÍÁsæÕƒsâ­]𽹕Œw{Þ›m,e%æ1WÈÒ ‡‹CÂ¥köØX%¶Üà27 ÅÚÁœÞï»ês«Û¯ƒXàtŸ½4 ©³!mãñ]ÅoÎ9¹í|«b²ºbd–+ÛLqo=mœ»œÁ,²:€!¾et†œ»fÎÝÒî;Œ®;!mr˜«çA#õ+Õ!´€âPoO®îm´Ì8ûÛ)]qÈZ6V8·I­$Š€š˜Éh'¬ž…Û’œ$¹m•c1[KѲàñ‹ ‘™.9˜ÿF†Æ-Å$fÙ¨VîÖVWâÆ‹ dͼoé$׳)T9u+^mG&Õ—uKdçE>Möxøc~©/N­¸U 3[ƒ6š‰h;Ç.ÍÃÞŽé¢H¬s{#ÛFZ:žÓBKô‚Ò8·V¡ö@$R/✅Á ‚rµÇsd+väÛ[^ï³ n7¾™EªI…¤õ¼“Å[¾"Z¨‹GIöÊ€€éJ¢„»­ý»¶Ä–÷›ïmm·®&lnžÞã¾6®wí,h-¯HÃ¥½ ìmé G¥"ªBG-›Ë‘E é9; y5QòždZg`æp>xuw‘‘S,tñšA#ÓÒà <`¦ìKŒ}Äc2d†T»û$õø*(OUGUVkHÆÈÛî“¶%ç+$@nv©¼rF6Фw"ä­âç á14A@[]wÒ †•æy»+æ ÎåÑV ð¨i„xÍ¡áÄ}kn½ÅÏm!Š'°tPôƒÐGQ¯Ð¶ÇÆU±»ŒLŠæHçHH¢ªÞNØ€:öb òVjôt/•þ©­ÄJÃô­˜ÆjìälOHjSHs&ºº@JÂsv…Ð4]à×@Ò÷isº¼+¦8tš…Ä%!¤Ñjç}Gj šŠŠIûS.rh`íìN˜ÉŽ‚!¯'‚³6—VÒHÑP$ T‚8£é¯RêÈÉ#ããið™sì9-!+f ¤³BF¹m3(Ù…ÒlœsS¦1äjˆ¥ì„‚n]Ð.ÊÔw,‹&ã ]£iÄ’H$ŸÁô®í±kâñxËÔ)OÆx.ÞMÙLCé¡Ä¿Û)¸c§ìÓÜÔ *x’µÇBC…xu ý&¾Ùèéÿx(I^ÇtÀ "øE1 ö€A|Dˆ`Ôû¾ÀÔhužº‚5Úð¯i?ç)‰h>Áü?÷-í“—àS¡¡Ûn½²¤M$„å8 j¨ªÇM4ÌTÇP.£ËÊ5Òš{~JÑ-iARiÖ'_à]¸m¯&«âˆèë&£ë4[ÜkB¬à)0YP"mdÑzä `)^>7f͸€j"'8ìïWNæg2>ùwQ‘þÒâ¬oþ«\~ ²Ö±Èá“5Òö £à/û#ð•Ü6ý¨ñ€œ‰Ã¶Pÿè‹ìËâî’jþ‰„ºî¢u÷Õ¦ä2ÐÈx<££PÓOQlc¤ý.'À¶;k e>ï飵Jÿ ¿ú£ÿ >µÄstls otÄôm%w4û(È[6ºzêX¾Š ‰S!—t©ö§7„5ËìÉnï³öóÞ=ò[Z“;µgM  ð.¦P[ÇlYnƳX é$ŸÆh¼QÈ­˜Â\jÆ»$ƒ[Q‡ZA!Éô¿¤.öqÂ"_xfä–vª(˜¼†A }gµÛ$ØßïšXû§™OKYÁ±ƒØK@q®+Å7<ÍvKîÌ5l ¨ëwK¿§€Á@ûkb-Zõ~´ q¥DêÏ¥/ uJë¥AÔŠ¤óPÔ–§T€~%Ij`¬»à‡;Û¼?ñn]×»uãÉø©Ü‘nš«.Ÿy1çÏŠÝ휧ð»U"ê*Š"e•åçÙ ÷°î1Xgçà–;«RHÏnímmO^ÝL$ç㤿òÓtZm=ÙC&ÒìD±¾ ŠTžêfés¨8'KÈHiT…Ú7³ˆ´¢|)m¡ñdûµÇÙBømy)è c–˜TòíKnË ÝbâN$’\§Ü9Ó.ýkxæ`ÿwiÞWÂnhÕÌS2X¥ÇŽíÝë Ææjqnš´8Ñfò<žÝß|®Ú„e0rº°\Á$ncØOŠ^uŽíÀ@ZW&âRÔáã…«Sƒ¨+ÂÞ½²tþIW2g¹K>E »jÖ’B8s¶žlc5•}‚ 8~Tµ+gÄ éXÝ…m“ßÜͺæåõ¥Å–Ûƒ,1Œ†9¦aË-ÙˆøÌkÉsb'‹ãxáV®îížÃhìx9ykq Îj[Ͻß:'ǃ4Gn89Í9ôû/oOŒ²‡Î¸…ÎA[×V'±>Û@IcleæF*~ÜL¶ä³H2Í®´K3un¦-WMÉr™¨Ý@10Ê_5äW6vËØw½Ó}÷;øò7’†>)zÇIÀÀZÇ6S¨°—‚ Gwnkr÷wnmÙö×ï6³¶asdóo â%p1ð!ÁÎ¥¦ ž w?XÕ·׎‡¼ñë·L¸2µ8a´òÖ”tÆ/¸3 €2sMØNKz.BÚ”“ž]‚Ç\ šÎ)ÅDÌmFï—ûŠNYZoK»;öDýá>b{X 㼊ÂëDeÑèñÙ3ehmKY&²F—°Ûîü37ÍÆÙ·¹´sÛ·"ÆÅq(kí¤»ƒSÃ_«ÅtnsÜÂMs4€j ãv;®6ñÌ•ÏåK†Žm u 9"ï-¾Âø´8~V.µ·,tí©–R÷$µÒ‰ÔA²[qrS9Ô"JdsQògpÛÛ`¶ÅöãÜùl„ѱ¶-È^Ð7P.–äÍ™! 9ÆFÕ¤P5®{zxÇó/4ùl害î7FÎÚ¥ÚHÃݽ®‘òе¡†Ž*I 8mq¼Qç²¢Üz©S*®øé~áR¢B¤‰T_] œL¾õ4ÀÆ÷¥@JõÜ|Bæ~âWKvK@¯A}âzÏÒ¼êòC'"¡‘Ôvèqú8ÚJ~ Žù?ÿåÆ þ¨/pÿå™ú¼ ÿþ˜ÍWü5oúh”åüÆ~Û›ôr/9N௡hBñÐW(³][MîÛYÅèÑôœ…ǵٿ¢Ê>¶R“jyæqÎGÿf~æ,ª‘?Ø(`c2ñddÅ]G‡{#˺ÞAž51³ž:Ú¤¸u€BîãŸdÌ„É5ÏÇ ˜ekMèÆ°ÓÔâÚ€zŠôG%ð3–˜ßÇ¿¸3BO*ákt$±Å÷ޝçSè¹nŠ® .¥+=/ èÆIEI 1»âEAT“ùÿns¯jÍ‚.oº<^ñ¥—v×p=±ÈA KX褎FÑÀ4šÐis½{5Ë üYc•åÈ}þÛ”‡[Ïo3KØcÈsdcØj p)R©£½óVaý![€hÜýq±¿ø†Á÷ó‹»1ÈGʰ».[FÄ5Ýú"ѹ®Ç.‘šºÑƒD«#¬ªÄQ®ùÌ à«8Ò6vÒø­›êãb[¾Ã`æ¬ {3Ü÷l“ÃÃLp ipkZCèîË#Ú7&âø}ÛR×3n÷v2ìËvæ¹²Éë\Ȥ‘¤‡Ê€$[R|pçõîcàw4ež%îÌ…`%qàü¹~Jå¬àÂç·ÆË‡³.é…îYI)%¤“Z9kQk¤fê& œ[fCï]ƒhó«gín\Zà3¦K}銱e›ñΆ_¼Iqb1¬ !ârÖ»P:F³¨Šb7,w&z\eñ!“mŒ…Óî[zÙcîY ¯29Îqp-1á¤GOjG5Ê–M{A-\i1!)–0ö'äY±igl˜(ØHBI8XŒ]+0ý58Ã"‚Ú•2œÅóÉ6ÆW—œ·ØYMDZÛb³¢êúŒskÄ•¦F¨Ú@—…[!ÑBâÐwgqûËzîÛ,‘¾{üI‚Ö®NøXÖǤ—¸9ƒW SßùO `N7$²´C+.VàáÒy´E™'1¥ê¼{A~w«yƒ—nã ='Fé.ë± kÙå)ŒO0¹¶7žúÙ–Û^gÞZÁ¸"2\27‹pçi¤BWµòÓÆsY«Ki¨‚@XŸ³ó»gjni³Ñ¶Úypï …Ïi˜´j¬†6’[|PçSQû €Jé)O§žÎ±ïkÄG’ö³ktå“kÎ>`ÿ÷ø¯Õî±¾¿é¶Ïÿ…v6VÆ·X#…ËÛÆ…ý-ˆq >Éö TŒbwU£-g‹vq“ÊÁÌ ã\™‘1û,—ž¸~½-IX)æñS®!¾&^Fº²mœ&rvôÂWcÖ+Ö‡Ò(Š)˜TIÁ6™9{Îmm&î=¹¿~ÜÁç­çd±Ç=ý´mx¸šÑš,f-m1È*ãã¸ite£+²qÖܼÜ' š¼´nk+ˆš'Fð×Åi3ËL1Ü;S£x“Kµ°Ð}–Mx'´¬bq£eÜ’÷VJ°øjá¦Ì°˜LIÉæ§øƒú+C"ÁÒlÚÙç·¥JÜoî-þÁ2T;DÕ1u2†"*ë9·rs1Ž‹·/·ãÌ_IŽmýæ§UÍ.uÇzÇ2&ÅöœdƒCžÜæ-¼ÉÆÞÉ™´Âáq¶Œ{xëKj 4ÐCݸ:GIöZx‚GC]áì̺ósÓ.E39–“&àQ@SߺUÒ¢›T΢mÓ€#¥}©ihË;H¬ã¯wm`©ÔhÖ†Š¸Ð“AÓA^•ó Åînd¹}5È÷8ÐPUēë§£©|%SnÞ*ç-\U^¬áLI‘³_³ví´1}®êî¹RâôÓ'Šfî5šÅŒeŠí$;í¥^°l$EW©@'þ@×O—7–ëÛÛ3ùˆ´Ën[–ÚcŽÓîÃÜ׸kuìä6Œk×uS‡J÷µ·ó;›“7츽‡^Z–ÚÄ «‹GG]x¬t‘àŒxçòÒXNq´t['R/ÜžrÎ9[²d‚Ž].b¥qS1„ Q0€rz¿=ùKwq­¾f\Jö± Gp*ç8ÅN$Ä€´é¹OÌ;x_q62VÃKœuÃÀ4TžW€ !8L|—Õ^1/äd•‘¿œ†<øÝâÖ½á†Mƒ«Þð•*{À0Q,X˜Œ;tÌ‘ž1@j¡´jÂîon1Ê,Œ[Ø7ïW÷eâÚMmµ»+ÿÅ{œ ºHpSA:ehÛ¶£—8SÌ\°yšìýÞÎÜ8´ÎÍM3ÌêQm#Ô(_BGÉì‹*Ñ០#.HÝO%8zâJï’±2Ô“¥–Y‚y =c¸Bå“zs¬Œåµ? ‚2›|Ü•Ä šîfï-ÌŽNÞíK{VE¿öìÐ2æÅ8Ú¸ac@9¢cX(\Ó*4fq¶Øý“Ì›]Á5äÚ¨¦tn$–‹†š‰î!ñÈæ¶G8Ô5ÚÝC¨ vŒözfö·t³\†hlsŠ-öÒòÓ9ÊRNFÄ%ºÁ³…㦢ým's˜ˆ•Ɉ9'n© ¸pA¹çöË—¸6CtÜ:6Gc$eÏzâã~¨Ëcî¼bçŸéñI¨Zt< Üñä$fcº²ÀB×½÷ÎsvÐK^Ú>¯×À5£Æ¼`(Vó~Š û7ðù[.w ‰Ä½îFº€ž–;~ÑnÀÊÂMóîˆé¨é­tðZÝüÄeÌ€6C¶íª¨½Š¢´§Eh+Ó@»m#“8á.g÷Üô4¥GvúTÒ½•ú×0zÒÖ”àÃèÛåú‘vT—7£ ÂM%c­gw{†÷ôÖœQœJЍÐwDºéX˜fÊ[s‹zÜá#æcÛöî·a¶àÄÒ:ä }+#,vò×kÔyüÄ͙աlFb$p=D2¦«-硸²²ók[{ Øx§ðËq@üQxÄÛX‹ìœ¶?+¶B[‚fõ¹ÍÍHÏK4Pæ1QP(áOxC{CyMç*³;-Ù ã}”Ës*Ky{ËwÍßÇu¥ßšŽÞG"Ô¸wAƒÆ x£Ðní¹ŒÜí³ÛV–íÉ™¢fÇiÝ> ·óš@÷ºGŠžYqà ñŽÈ‘¿íÓí nrXÿòî'®ã‡üØÿö›?Òß.«OüÓÞ°.Gh°ïƒëmq¥Ë®œåÁñ0J½w™-›ÿجWœr°ÿ¹noønïýP»ýÆ7ŸÜ:pµp`Ø¢_¸ºÏ‘ÅYψ}œí­,Ñò‡”}ñÓc„|ûVÊ..w LDuîkø-ˇå0·=†ö”ÙZäîÙ{i9Ãx®Ôk'”&.{Æ>Àqh´rU®. Åâ'”d™Ñlt¸¤¹È¹LMÎоgÌ­ïÊmñµn1øÎç1º. s,£†ÞGÝ ÜÚDà{±$aŽ!Ï-ÔÐXAÕ¤ï;ksjno/ûÜnÞPë§Ë3na²4e.h!¥¡ÔqR£Ÿa<¯{EñaðŒn< ºéÌ.²Ž³r,›zø^PÌÞ@DÄܽ”C)ƱMHå›S ˜¸&šj<ôÚ·Ø[«¸÷¤™î›\Cl²’J%¶”3Se’Hk#¢sÜY#ÅAÑ©Õsš—ÚùûLœƒ µÙgýãq’7VpÜ1†9ã.¡Œ’ŒkÃsš¨(Ö¸¾éšâRÇÂYn{-ÂaLq[/lHÛq®/²â¯Œ¤7KFÉÂÁ¡oI7‘dÞ5»€pwŠ‘DÑíHCf1{».\f÷®&ÇiÍšÏ\Ûܶåó:öáöÖ]Ñd’XXâò4ÚAwØ$jðßÜïl^×ÈÝî(±xˆ&Ð66ÚÂÉî»ÀZæ0Fàæ†ƒ¨¼‚Úé$tWÓðT<ü<Æþ™o£ù£yÿÄþ‡-S˜Çÿ mØíþ²…);#a«.øÈ/ü ]Mê«UE1u9`LAIÝV»ÖP†Qgì²,"dhA•4QÉï•(ŸóNÛ7·w…îÃÜo‹X-Ã…tÇu¬‚g8ºÒBd< s‹’· >/5¶­r¹—ûjO,Ô4«íߥ‰ õ¹· ƒˆºGÖ\f“Ì_ê,.fËîö÷,t%ýÅ·ŠŸ\z C®’Jàö‹>,-û¡Ìµçdðû„íM’rYÞ4Ç Ý&‹™‹ËyÜKæÏæU—8‘4JÔåSE½öé½àæòÓr«!‹m¦÷pf²×e¬f=·—}ãÉpÔÙ[#KcŠ—Šx¼*Õzh´©î_yÊ[Û¹såÜÎy iºÝŽ$6§HãÑSN…³Úÿ°Wú|µ“þ"‡®æ\ÏÌHáŸô².®7þäkÅú6/ªP7³æl¨t›‹&ep¢eßQ4@§L‚:åLD@<#\Wáãù€ƒ»Éð›¨A?{–•=•\–š&åï ñ©4û´u§ÓE•9ÞÏ6TôTO Ön<·pOÙÛ}ÜUk Œ¥žŽZ)¢Ów ùz^M¤Îš¤Á`PÊ5 ‹tÄ¥0ˆ|³Ø™« nù¯y‘¸ß_x•²ØºKÖžáV¶ö倂Í4÷E ^˜²ÝØ«¸íùwmeÒî#,» µx‘¥€É%Äóô:µ¨PõpÉ6aí6ÅN$äY³²ÛɤÕãù\cvÇ1âM=däž&š%(ñÕ)@9@+§¶’åŸ+´o¨¼s´ñ.kY{Ý^“â1¤¸ž€ +³yß.=iÕ ž•B@8R-N§Â<õ%©Ô+ÃÃS¥:¯^ø4OzÖ;í¢<íӯ̽ûûóšý­yúÄ‹ï]û£Šýmú,ðìvŒkS[ŽÀñ_…+ÄŠn%C½¦ÌâÈ·Wîg)þíø{úœ+òÓ˜_¿ÙÊ{âóõ™Aë^E¨T…`0…¨=*à~à¤;ÀÀ4"§­X !Þ(Ÿ¥p?=NžÄÒ­•:@å$×H‹¶rTÕ.ò`»7);js—A&G(N_öiï¼a¬fZÉ×Ö/¼%¥Z~‘þ~#ëY<>Cûºý—ÿeZv½¸{²¶¹´uµÄdøÂŽd”á¨8P‡MAÀÚ½§¹ ³A3dà°á^#‡FžÂg3Gâá2psr°ÉâÆŽ•…”Û÷ 2‘©‰œöb %ñ€4¬t–°ÎíE¿œm%ŽÿÚiñ” ‰#ûTw„>°j"JJP¢vë@Y%)SQWŒ$ Ü J&ûhùˆ ª˜5¤(&”¾é0£›wrÃZ!k‡¥Í¯¥qºâÕü%¶ŒŸôjßè4üK‹O½HƼÇì^·tA"Åe~ÜN@0  ñ#n”GT'(rdíáÊ襵è«Oõ¡ßåë\“ýx_à#ü…r¸'%dÕ˜îA»t Îo"¡HEJnª:Žð€ ®¼µÕ¹ŠÿYuÎF>ôŠP[šWüŠ»ûÍ[’ߦCÇësF®]ÃØXP §¡Dª->õa0‘C¦}¼…ÝÔ@L‡–(ÇûLÁ=‚&Ž‘Û_誦]BÑHì¢I{ŠÞûp³–¤hþÛ‚D¥T“8dÞ&/)^¼2¢U chœµÒ‘¸ØçÌË«‡pûRÔÿám8.Ôwwã„FGú,ñš­í½°ÑáÁ[Žz^qN]QUë‚¶ÔâQM‚GM±SÓ“Mšº’e¦„hÅÛÁnÎÐÖêáÚóWWëRèß3ëu#äãÖISzÔ»’ÒbÙªiÇ1'Úvi‰)L¢€A(ï)ºDÌaè<£ ~´¬ÅÍIJ—\ÉWR¦§ x8žµ²aÃc5kG`<;?Ëô.Ûe¶âe„L_ìôÝ( sŽš€Duæ­N[¦j$ž+`û¼’4 VBâ:z>’z8u¬Eâû Ââë=7ʼE{¶u³ÈË&8§Ij“¤Á;†ër™4›52mª%ÿvqÉïLcÔù_ˆ½Ü9?¹BÇ7LJ\?¨éã5ë5¬Žh?Õmx€«ºnáÂØÙÈ3DMí'†¡×N zÅHà¼7:çYE9„Ê*s(sˆ‰ŽqG^QÔF¾Ïclc@}|èù#Ì’q{‰$ý'ŠÔÏËOObš«ù‡¨i§T€~z)Õ ˜jKSªPSž• uH mÒ—…4€~१±:­É¬´‹4¶g"õ«g¤Þ7nítv˜éŠnRMBr jº40‡†ºòÚÛÌöÉ4ltŒ5i-´ôÔ8€xv.V\M\ÈÞæ±Ãˆ€|4à~µóùêËTUe÷|GÃñ˜G"Ù,n[b%l{gÙnãæjÝó£Ûñ~€ÿ·,Kçm–v~RÇ1Ê(w«ÉùKËÛ½´þÌ¾Þæè_Ïp×FZÞõú›Mmihé p=oüÂÞû»pÿ{ã[<Ha-yÇ»n—WCˆ-=@ŸX” WªñZ ~µ¸-&ýÚ-[º|íÓv$2lpåe‘f™€€b5MC˜È`H  PÐæ áe½¼Ot‘1¬‘æ® \{IIéí\¯šYÖHç´PIÁÙÑÔ€ê÷+µER‚}ªªÛPZR‚œô¨z“ªÜ˜ËHÇ †zÄ˳XYº]°¬Ÿ³PQ:b¡5ð¡]y­­î±àM¡í‹–9憦'9•hH¨ì4_8)ÕÑ\ºj¢«ïNIé*À•ŠêeÙ‘Â¥j²¤ÝÜUVÅ8"¢…Ü % š¸m ”Næ7¿h u ;éjäÈbpˆš‘SB{HèFšÆLå:g2jÅ9S LC”u)Š`˜¢€÷ÀjœÀàZáV”ƒˆ5#ð¯©Ã×/;—ŽváQUÕT]uD QULcœ@¥åðWp²áhlc 8*|‘Åò8¹ç¤“R~µR©·ÇUNÔª¾öR/#Ö :bà bìÜ*Ù`!ƒCDäP ok × ÖðÜ3»|}ŽÀx.Hæ–k‰ÎkûA þ$}©Œ"cxÆ1Œ#©„G”DDyDDj´(85©©é_z’oœ Ý«‡®ÖlÐ [,áelÓx¢s™4@Ú» é\ ¶†7ºXØÑ#þÑï OÖ¹]4¯cc{œæ7 h<«êB Ué§BŠ¥6øûµ©§juL t‡”)Rªª”ëè©-@)J¦Ú‚ÕUJ TЧU÷šIê­b£ÇJ1ns(Ý™Ü*f¨(q9Žt[˜âŠG9”0ˆ@DL<ã\"[)œ1¢w 5Ã=' uõÊfÆ"sÝ€I ðŽ´ESn5zAQT §pT–¦ ûÍ ñVÈ2QÛ•¶1ÌÝ¡×Tí›™Cê aI#(c˜J¨ˆë\Þ&ÈéšÆ‰]ÒàM:*zM>•Êe‘̹ÎîÛÐ+P+ÓAÐ>¤ESn•T*j˜ëè©N«1±þLá†W[vNb±²E¥uZN'K%àp´ž¾ ç¦ìÑ>é^9 ÅveIªä\û©¡¸* ¾GžÛ|˵ܗ9­¡}Ž»Åݶ2lòx1[IK{ËWBXRç´´UÄšý>‹‰ÍlkŒ$8½Çk{on^Ír;$5ÑpÙKC´Òpq൫qž-ü®\oeãëfJÑÄønØqkXQS¯Ñ‘¹übá“—Æá™Iœ¼ã–¨™T›’ §¨ÛÚ¿Ë͵ŽG3Ÿ¹Žïuf.D×O‰¥·@-Šƒ¼sAÎ s¨ã^N==纬óâˈöûŠHà騂ù$#Åy¡¼:Mxc™$ž‘¢ŒñÉXª ,«2¸T­X74UFà~Äê&_|%×Þ‡0W¡:Þ(œ±½ø Ô`=4âxW­i¢if 物4'¶ATÛã«¡QT §WE*& b©Ð>íIju_z²œ ƒW®Ù°6l»••A¸w@Hç2i4÷ •×m¬½ÒÆÆ6Gt'ÂGõ®gO3Ø#{œæ7 h< }HJ²Õ_s™ÕŸGÈKžzI5?„ª‚ŸÖËRªPSnµ¢*¾Åºpš¸tådš”HÙ%—UT›Û b C˜J‰L. Päjâd1Fç=Œh{\@ŸoIéí\®–G´5î%­è’ƒ³êT:êèU 9é§T ¥AjuHÛ§wФµURœþJšŠ¥*œÃÕKÂRè¥zª@?0÷tT–§^Ô€~z‚ÔÁìHæÔêÏä©¥:HSó êJ€ô"«Ù. ÓÞ´£‹1Ôv¶K½_˜Ûû†úÍ~Ö¼ýbE÷ÆÎýÑÅ~Ͷý zöA³ÅZVÇÅNÈ6x¨ª8¯Áç§(]ßn4ì•!• &Fè'|¢á}Ó€9ÒoÈ#Èÿeh¹)5´†š—;ñŒÿBØñO0ÈñâøúzÑ—³‘…ì—÷•âè ˆv¬á Z¨CK\Ó—jœ[‡A9D¦.§û“tµ9Ä“mmŒ®çʳ‹i×À¾B˜™Zj?I?e¿iÇ£…HÌÞä­m,ß!¶ÂºYZ8šŸìŽ©Àt4_Ì·–®ÌÍ{J^÷k;ÇÆ*,c[¨¡£`â1ý"13èlÑ5Sî–PÆPÚ ·K÷–ÏÚvG2É´-s¿¬ç´ç·8ñ>…óVéÜsî,ƒ®OpŠ?îêphêI+­@áÑ[QjÖkØ54N½©Nz\Sð$)ù‡ª—U œI¼m›Êøêí¼&˜[ÖäO¦ÇÇ|c1&¹1iéÒÎØF´í×P Ú.²I]L`ZÄæòøÝ»‰¹Îæ$îqvºY_¥ïÑ\í,kžêÐÖ¸ž W½Ìä!Åc™Þ_ÜHØãmZÝOq£F§´Tõ¸€:ÊܲF:¾1 ïpcŒ“n¼µo[YÙXÎA½Q¢ê´YVè»nt°pî=û7lÜ&²¬³uÑPª&sÀ#Á··uá Ü;zá—X{–jŽF‡à i«\æ¹®®kÚ×5ÀµÀBæÌaò{'.1 É@í/c¨H$(ZK\ µÍ%®H ­âàÄYÔÆØó/O[ÞŽò«‹¥…püoëãçlª°—"³“s9ñl¢&KW­›m7’“CWVÃvmì¦á¿Ú–7óø¶Â똴HÞè\0I Öæß­„;óo~ž‡i<=ÞßËØa­3÷pèÄ_kaÖaqdž q{t¸SÇkkÒÚŽ+®ýÁ[•‡ªû™¶xý^Á‹W/—Ü:‚‹Tp°&˜j¢š$9÷¢:h\I ×;šÆV•qTô žW$qÉ+´ÆÒçtÐM>¥Ø¶î#È·V7ÈYvÞôì{ŠÜ[-/Û‡ãx&¿¸¼eS„¶Óø©ä›iÉOŒdÖ*Z²là¨ë¼¨ššµì†êÛø½Ãaµ/®4gòm™ÖÑwrô[°É)ÖÖÙ¡€ŸÎ=…Ý Ôx,½ž1}†»ÏÚůbcÉ©ƒA™Ú#ñKƒÝ©Ä®§K¨8®¹6ÖÃ¥aêê¥áN©NºTª@Sn5%ªª”Ü%©ÕvÎ"Âyc;Ü*ÚØ’Ș½f7’­c¢ˆ˜¤y9;*å„5Q)UxåÌpÝä­Wuï-­²,Ou^Ãghçin­N|ŽþÌq°:I\ØØâ(³Ø µžÝ7fÇk%ÍÀvš°v½î-cÒ÷4ÁwBà‰BÃs1þH€û9/;kÃ^qLþ5„—ô«jà*戒íàd¥¡é…lìT9'»ïÈ]C\ÛÝ8 ßg-þÞŸï\Én÷h’=3ENñ”•ŒqÓQãZkÁÅeóx ¾Ý¹ŽÓ3sq, ™£[X䮇UŽp¡àHpëuè)ÏYú°õJU6ëÓJ©Õ()ÒP©ÓTê»/*bœƒ„oYw“íÿ³7ŒKxçRá+ 3èèJ±BE‚Ÿ[òRÑJöìœús uÐÀ×6ÆèÀï<4{ƒmO÷œD®{[&‰#©c‹4ÊÆ ât‘¶A œÞõ¡µ t:M d…†@Òc$Âz—j e[¸²ì cþoæ©ÙkHÕ½ÿ9fâ§‹l¿eèƒ-é°Ý„áÁÒA6¨Ÿ]ò˜S÷õ¬é¶FC)Š7?ïøh5ã{¹3âïší]Þ™+H‹Ü:à³£lgM†@Aþç“•ÑÛ;\œ{$îœÚkÔÊ?Ŭ€ô‚GÆo‹2èÆ×tõ‰zÆ|Mu[/9é±ò"ÉéMS£éÑ.ßG9Њw‘YBr÷ûõ“Âæ1›s '}‹¹f¸ß¥ìÔÒH®—µ¯oÐæƒô.†S}…ÈKŠÉÇÝ_Àý/n¦»Kºi©…Í?Q!oVV1¾òEó;gÁüm­µnëÑׯpÑÿÛȘåVC°”dâGtSìšuÇNBWK3¹px »+¼ýÕÖFàAnÝ;¼”ÒŒ«àΟ´òÖý+³ŒÁås÷WXè»È,¡2Ìu1º#.£œÒïô-è˜['šÝÅ×`[:Ûù¢vBÛÆ’[Áö–j*t¶Ëö^‹ñ·¦Ãöf;GéµHß唟¾®™Þ[hd2x¯¼ÿ¿á d׌îåüÌo‹¾kµhÓ%cñ©{‡AÜdmœá³°¿î?Ý2rº;gkódÛ›Mz™Gøµ4Hⶺ¼¬;ºâ±.˜7 .»MÂÍ®(”g.1Š·"J.*½…s!ª)ro*šÇH7ƒßWžÄg16ùÌdí“tÐbyX51àš ðè]<Ž#%ŠÈMŠ¿‰Ì¿·q0ý$Rµs ›AQÄ>•ÄNò…e¨>©AN¾ŠE¨)TÛã¨-UT ¥F”ê˜è Ò¡N©J¦Ý:{Ô¨ªPS¸*KS)TÛ­AjuJU:ªtªªR©×Ñß©N©Š®ß*ê”ê©-N©J§]AjuHU6éîT–§TÀ§?Œ*S±)TÛã¥@RU%©Õ()×RZR•Mº{•ªª”çåè¥B€R‚›z‡Ü¥@R‚•:UU )¶¤µ:¤:º* SªPS jiDê‚›téîÒ—…:¥)P"©üÃRZª©üõ%©‚”§æ¡¨-N©NR¡M ˜u¥Ã­J¥§±:¤ó IjuíHç©ÒRù‡¨jKSªö§‚’kgDc¸v$où<%bæ¯c@ ž²À:½`ïìšð^‡ƒÝÕ‰¶“­l‡¤v‘OíqÚkwO;×hš𤹠›¨ÙTõU3h ‚ÉåSAÐÉŸt€~M5 Ö!Æ_ž-ï¼Axx´ÉG6±qŒñ`ŽÐGá[#Û¾×–J¹\¤IdÊ£èõ‘?¢©Ê%MRoêˆ8ßÝy`0w´×?n'ŒªH¨¯ÀV:HK N’?Ê8JÞ-X%'n,xÙ‹’*œe®” H•DÔí&lALtÜ´ÿ wDj/¯73áû–:ÊÞJ´ñ‘Í¥< õ.{hqÅÚîe{hGÙþú}k'¡x¤ÆNx[^'$M'Ô}t©»ù2 ƒ6.•f`ÈÐÚ9 Љ€¤ÓQ8€V¥6ÖÎÆ6AöM–Ytµ  ¸‡×‡ p4ú|Íe+¤6½èdm©ï MOÑ¥eÊVÖBq7Òeš1’ŠE¸k,À[8,’(r²¾»WmÄŠDå0€è;£È:†âÁßcå6·Z ËkPê‚Úñ­ý¾š.Í´Í{u R½Bœ~µ‘ñ×)IÙ© •8‚d0©¼'ÝÔJ‚]©ÌpOÃÈ=þýh÷‚jâê0qLæo-µöåõ$|8» $±¥ÝÛg¸7-ñä âèZ[BkMZÞõ¾ –†ñ˜¬^?=™µ«%ü±šœ·E„ø¬'¢GPA.qÈ® 0̓Ã?´=àÛ€×U×pÚ64áì+™“è¸Ö²¦,bÝ“(\ñ¢ÕÁÞO¿·®´›ªÝDQAÊ ˜É‰NB@æþðÎóØ=éc÷[[ »Øþó š÷»ïÜ÷˜_¨ÄÙb˜¸<9Îc˜ªÒNÝ˹ŠÙœØÊ훳<÷vöÏî$k[ܾõâFÐÕîŽHÃKHÁäŠAâtÊБñ 40öY± ï_šöu•¾õçžæÜy¶‰ŽÞ6¶V ŒØ5±ïžV´ð9í:^<`׸p£W¶nK™¶Ï*ðx\[ŒC3ßÜݹ¼ ºÖňâXÖ‘VôÐxÔ¬`á0ÝXgˆþ+µ²: =S1#Œîå„Y8;…®D_¯.ò¥™¦bå_‘ÑãRl-Ôj’‰•S(%0‘röÛ{æv}æëæ0XÍ0È ‘:×ýÙ°Uç»{ Lçê!Å¡ Šz.ñŸkžOmþâ Àç±mYtH.?>eñ¶¹ÚŒaºKAÄЮkÄf#¸¿Ã6;éáµ-n±Í÷î·j[v=¯4¼¼Š ‡Þªåg.µKP1H£‚œÅ1J%?/·Øåï)³¨ ûÖZmÛwmkt‰®ftb6Ôyè$0´MFGxmOŒy…ŽÆK/qo[Ïq-+ÝÃ^^à:É%­4.‚CcŒYÁo÷T¦ÂÑyŸäçQ ¼Kx_·U¿r@d)kz)äÇÄפ(v#k++ª‰(És!)„ÂsÖÞ7çç-qqo=ã.%¶Û,M¾‚Úa–Õ’½±÷–ò:GwÁsA4T@LŒÕpø.[ï{÷í·JË6èä6²Ï,rGpøÚ_¢f7º.kI†ƒj@c¸0À˜žÈÁRÜHq8…òú!ÎA{Œ1Æ*²_Ç@L]·4+w ÜR7Âý¤ÃÛq*´]±…»I@Á¨ï&U3Û—|îœÖ÷‹—œ¶u“.Û`Û˻ۆ¾Xà†BLŠ&¹äÏkƧiÐáØâÜNjàq›^Mã½EÓ­ÍÙ¶·µ…Ícå‘€™$ŽÑsN‘«SOh²Ö÷/Íx áÈoX{j÷Kåàmû9 cƒH–âwЈÜ XÖ´‡<ÒºOŠAw[‚ÅáŸ0Y‘²|=žîÇy}[öÖ²R—ýÑu'yµ¼$P…Š˜²nñQoEãGiä“t©Æ&€@:Ö¾cí,Ä–ÛøZd6˜±šàäma|ÜÀÃ#㸈½íÒæ5ÝÛ˜j\5¯‹ÏwŠÙ[‡ÉöÞ,÷ »Šg<­”L&pc_ 5kˆÖפtqíkãð+ƒò)°CG5^W,2ñðy3Û7 -«rhe’I¡i!½õÀ‘š$”6¬ÐÐÚê-©¦{)‡ånÙÌ|'˜+›ØËYqy‘±‘H@.î¡,v¦GZ;Q.àêp[õ‘ÀÝ œ8£ÅY¦ë¸S Ü9NÞ¾ífèW0h!)t9<tÛA¾1ÜG"ºfQÒ'D‹é¡Ç£šçfn÷emѳ­mÝ‘Ìæ"²–Úbh$%ì’Ëâ÷dÈÐ+š@cƒË:—gÊü]¶çÎ`w-ÄͲÆcdºŽx€âÀæJYÇ]â]p«šZÖ¾kC ðm™ñRɶ™³^*áæJÒ{|«7#oßsõ™u-&Ê58¦-cá£-ëÒZFD9ãXB™nÙ3 ‘åËooìýÛŒÛyOîl¥ÆàŽvÛÙ-´v·†9åîs¤|¶ñ²@ãÀM 3C…ý·ËÉ·¯³vÞváß§/ts¾xe.kt´5Žg¹…£‰„ÕÚšjÞ¼É8—Ýü1/Äv ˆ¿,ulì¢Ó^vmïqÇÝhÈ5’†FN2牗g¢.̳´RY¸“³ã‰J@H¦_?·wVøÄó)¼¼ÞÒØÞ¶óëË{‹had…†HÜ÷‚Ú5ů­x6¤ê!˜|ÖßÚÙw–ÖŽêÔÛ_ i¡žFÊÀæÊdž´ƒR›Jq4H.í,µ‰x3áѦq{Cfl…rdì/`dö”5Ñ oD@–áM÷Æ—®aVzùY¨‰¤R VJwí’ë;Wusƒ˜2憛Çcs7V­žHd–I{¢ÝwB@Ö†´‡K1$¸ÈÑcC«œÏíþ[ìèñ¯ÉÇ’¼¼¾ÆÁ;¢d¬‘÷Ú¤ï %ÄÇn‡¼êm8%ÿÃ.°³¶2e=–%­Î²Ö?‹Ë–Ýû#é·r¤›NS´×kå˜Ýæ|Ý6Ý¿¢ú: ¹"ª&cèŽsÌåØù)¬qQ\s~û­Xý0Øæƒ8sÞÜi%úuëqcš×CÖ+-²6Ö+uXÅu$;'!hÛ¸çsuJ"sIÖ‘Þ꺴éhpq‚ÕÜØË‡ Ä\Œƒ°w¸±ûû~qþ?Ë÷Œ€MZR’‘ê?Fïdkb2=¬â)w™½íNR¦p­?rs}òúÞ<î7·2Gqn¬-ÙÝÎÆHàטß>Gº2ø‘ýK‡ - ³6žñ™øœF/5a+á{ »™Úâs˜Ò扛Ý5úé ¾¼)…öwgC]¶Ö@‘E¥ýe¥â†b¤´û‰òšÎumÜ[€‹Žb£2?I~ÙG &¨¦bŠãßvÛÍÿÌbnl#{ì. ¯yŽ ˆEþðÙ´¼k{Ü$1é ¡ÀÐדi϶YÉì¡ÈAvö¶î>‰Ýr?2b«N–µ¥áÕ.!Ô"¡u}©‰­»ZÂö|å¨÷÷ ×RÍ“-n/å æßfŸ˜™BÆ `5LÑÊ8jˆÀŠªvªêo{Þ­›)º²9<îþÚ· ·ìf7Dæ²’¸ÜX:G÷¯Ôu€ãFpG+a·ì¬q;G? æ7·ù7‰çV1ÜÞ5ÐÚx¤ãq5èÈÓpVõ¹ŽeçSbÙ’0¶ã˜É'7oIHd];T»Æ"‚‚&)JÒ9}/8!åM†so¿2ÊĺI#–Y®ãˆ¸¸É0{.“K»¦1§h‘à’FѼcå¼¼Á»Åf‘’þêì6[†=‘Çn÷é ŒµÆF²£¼sÈ⡤^—„á>:ÖžãjȽ&g•—áóH\¶ÓÈ'åŠe<'D$àN²;gFrÂFÓuŽØ]Ã(%ŽšÖå{ÍKŒ†ÌÍaá€ZgòL†fÊÝnЇD­‰À¶Žd{Cèj:GBÖmv6{Ÿ’’Sqˆ²t‘–;Cdá©…í¡«\ÂÒ[QJÒ«›OÂ3ºxSök[*»A…Ë–2´å˜, Ÿ$Î_4„s¥Y¸( ÝϺmÀƒ¦•†±¾—Í.cdíà öØ«Z*ÒèñÚÚ8U¤Ž"¢£‚Ê]ÚǰvUŒÅ²Q¸´ÑÀ>óI-`b±Ê ŠÝ™Ž èíöÛ§sâ9‰Ù›¡Ö’Zd±’)bc£Õ{nA¸¡Ïwæû¯Î4µ¥y\û’Ù—›ŸÛ†\YdZÉ#‘áôµ˜R-oÞx„ý“BhÏñŸŽømÂwÔš³–³ÍÏp¶3ÖáŒ`”P²ØìÞCÝŸù¯ì»‹èðŠ»6™b‰»u bÜ;(n&à‰‘ŠÆ@4IÊÉ7\®Ì:iª©ºhQÓZÔîöŽAŸþŽã¼‹û/¯ýãýU¸Zo (/!1¿¬¶„~êñ–øÑk¢Û îÁš©é h3‘ËöÊ ±3g­ÓQ1!ûBHMÒ”7@§(ã~á¹-ÜDðÐ ¯Ghý}=«/W0;†4v;SúW-€`AI¤ñ“õ¶>ógL1Èö­Ôm_ÊÀ¢# €d÷ˆb¢q áF ì‘i}¬†Vôè §ej¹¼qLq,»„ÓãµwÄW–µƒÚß¶;œ+u..”AFd]Ã¥Žªª9QÊ¥XÇLÂM0&á@F±_ç2—âñÙ=¤p€vqð©“qàí¡“ŽÆµÇ†”ükƒÎqS~ÉÊqÀ„88“}º® ¢i]äˆdTCB˜Cw„Á  ¹ûN\ØÓ~í`t€4è©p=€¼Þï.:-'ûN<~¦´ÿ”ø:ÈJ¿•r£·î”r²ªS˜Ú{EGyC!L¡¹L ˜yGQ­òÖÆÖÆ.æÕŒú:O„ôŸ­i·W×WÒw·O/ÓÐ< }Kã󇊻WU\ ¯xjHN¥ B•¨WП @70Ò (¨Wóù)iM ˜jHíEUÀãá©Òš@8søêKUT¬šàÒàƒµø®áê⹦¢­Ûz-YRS3³²,â!¢cšM6UÓù9I›²`ɲE(ª§!PÔD¼ã›¶¹.Wçñøèe¸¿›pÈ⎒G½ÑÖ±Îq<Z ' -Ë—wv¶[ëyy#!´Žþ=ïpcÐðKœçÖ€8’HveÉÄ\Æãç.g¼W78ÙŸ9rm’ñ’HÈ[Ý•;.%Güz˲•·.¨_Ù.‘”&Š&áo‘3†»Ø›Ç‘˜­¹á’·ìcp{ f¶¸ŽÖ ×éxd°ÈÞ- â…Àæ¯7uÎÛæþéÁÈÉXܽÓÁkƒ£žÏ!-ÔÒC£•‡CÚjYÁÇVGácð?ˆ'mùÌQ‘2ùxc+‚)ÍÝd[Y킾î{FfÝŽ;UTKȱf‚ ‘Dˆ¨r>3É=½Í[MѼçÝÏè—kmä‘tì qƒÇh<–xÛ'³o&§¢Ž‚†l&§¾zÕùͱ÷œ»íöû6ÞáØ=çime’–(ÜæÚºÚâ*ÝJæ´µ6n|#]‡yB]¤,ï-wNÚj6mË4MÊí«‰®¬£{ÚÓ8žÒÚH."ä6C¦¤ ©]CÀod´§8”³¯L°¾$¹ø—k! œÜŒÞÕËP·Ì+û•t\X@Ü.n§¤|ë³¥©@Û…8¨žÙÎþZ;+e·rØ|[r¸Ý¹;›&4tÏc+"ŽF ¥ˆC•«¸Ò¤»_ånöYœ~FüØ^æbeéèŠéŽ‘ìt„¥’^êpáZ\2öEâÙêâÚ% &ÑRaž4±°NT³ò=ß‘n÷I ÌåVûä!,Dƒ§Ž ’Ä)ƒ†*š ;aîÖ?°vÑLn£uÝÎJÊ{H- ó”.•¦K¦šh¥Í$t¸T·m—/ºðøËËíÛ»£|b‹xl®b¸–âRÕ» ¸ŽÞ2û—BøØÇÜ6!Ró©Ž{Øßë<}–js{›?sÛnk­Ñi™¹‚Ë#Ÿ·.…ó?L"F½Îl.ÓH£ƒZçu4ôº<ŸY¼3q«jÞ\A`éÌ¥±¥´Â"À²oÈ‹„åB2bQTQm>EЊ¸.7ª;8ž.4]8f‚eQq/lB†;sf³¼Àæ>ÎÉáð9¨v͆JgIuqlø¸¾6LT/Š&†ŠM6†ÈâZÊè%w0xÌVÐÙ{’Ç#–ÆKœ»²¬‚Ù'½Ä !²HêšÇ§1 SP „ÞMmŒ­ìÞáå{'c(ûŸ‡I¬Òâü°îK½Œ5îñ+Òüw3ż°(úmGLž $Ý)©Žbæ2J¹œD¹-¯üÃgÝÉIÜãŵÌ0:Kv›{fÇ'}(£c s]^’€Òq™ì³¼œÄ6ÒöÉ—¸y/ ðI+Y1N^Îê3Åä‚)Ð H–2Zèâg ZÜ^ÙNf¯X9¬U“¸!¶øx¿ï6Z>èFÉVçláGŽ ‡» å#‘ó}AËd2‚C @‡ó¬g.7ŽO”÷‘ÙÙÏçÆï9²¶¶÷ t&àB@hoxâÈǼÆï°÷46 á¹ßoM·cÌ gÜÜÅ& ÷lÇa<°½²ˆL€ÔÜXæ´=¿i­$БCÓÜé”°`1^G¼ï±pH[Ò° "-ؤ•ÏzPtáÞâM슰öQbm›ÿvg9³µ]Ëݱ€ÎZeòRBË©omooced’ºI^Cdw‰F5•tÔYㆰëÛGob¹{ŸÇ9–Å\c¬™+ ŽÖá³Mu#£s#k#h.`ñªç:ŽÒâ’áÆm[²ÒâÓ…ÀÁ²¹ÂÅ™«æ;»(ÙÄÈ·6••[¹i)ø7+Òü_s±œ”8 ‹U"$RAEŽß'“ÅåyWÌÏml/²{;!ˆ‚Êãî‘î-eµ dRºøÏ…Ñ0js>É.$U¬t¬o±ûûcü1=Ý¥Žä³ÈËsÞ$Cû´ñÙ-í¾ù‚{©ç.H!qÖØ[Ž—7²FµÞ+Ô£ÛG¶­p+æ¬Þ5¸|´øØî ºŠl°½²G#zZö¹…ÃÆiŠÕ¦­wW*›u¬ÑjÅÕz!ÕÑae.2—×]÷kbÛ²O%BælWvß’F…±¥®&ñÖÌí­qO‚*§¢ð±Ä35U)’QUM®†L¥SÀyƒÎížec9¯‹±ºÉââÇI½‚ÙåË"/|ÑMUP$yàÖŽâ[ëÛ>÷œÙÜ¿¿º‚Æý÷¬¼µ–wh…ò67Å#ètU àI=~$ñ…ƒÂ„u›–.ì³d_™âÙË6Ñbã IzA^m m…Å1)‘'#ؼo¤#-Ð\ªo,š‚ —µ"\îÜÙÞi\^mlV*öÇcÜ⮡¹¼¾·–ÞGK×—ûªÊêxb¼¸ŠÄDÇ=­|¥’Ê_Ý´çéi€‚iT–eçi5öwåû)ÍÓn6¼äø…´f£mæã¹ä!›@B¢æ]ŒŽK*î1ºÉ‡pšFH†(€˜–_–—ŸøœÌv×ÃÅ€ž7Î#y…²d"7J†¼‚ipqÇdqìåCùá'åâ{b/h•̰¶2u‚.€GJÊî.x{q™pÁ) –°¥¡(Ç„¬-)mdëù¥‡*Ös:ow´<«ak1eÝ8Ar´:®Û®¦DJªb>]ÊýЋrÛ^b³7vÏÝy²k;W\±Ò~e¦h:£–kš^LJðx-rß9ƒ´_¸äÁÏmÆ[ÎÍ¿f×Gs8ÁŸœ"Q¨QñÔ¹§I.ioÑÁ}–ötáÝ)ð-öíµæ,N°)1=™–îÀµ†¾hk ¡~ª›¢×i&_Gjá]ävR¹M@Hr7û'˜å†w5 ­Ì9¼þwï×1\Œ{ŸCj x÷ÎgŒö¶Žs Í/.rZn Í÷ŠÆKq˜¼F+î°ÝÈ+¼ ¨Ÿÿ;ÅkZÁÓG®ÔáªêɸÿˆHû»ŠÓKà v–µµ<0ë…¶ÖÞKá#‰L#XWåÁyc[¶™2ìcgCIÄ¿Ay3¶“z vÊ3F5NÐMNÌÊ%¿ºUÁëœÍ“#·9­·7·÷vFûogy†Î\HÇÈÒV6”/©új[Eç;;,×/ó[[ï–v™Y®m¥gÞel,sà]G;¦¦´„¶´«xG Ø¡€ýšÐãzÚA/bæ{îRøŠŽ$¬Ø·™­ V’7[yéVëQe)¬ì¨¦váÚDœµÔ~9ñß1¯>åw÷Kì=³-ŸÜÉ¢áíÇ9;N™\×ø…±—ïŠð]†å±_ ì»o¼Ûýâ×%;§oxÍP´Þ‡‡JÚÖ6–øÀ¼[Æ´â¹ÆcÁ66OâžïÌíx—áÌ0ãëýÑrÍ'”"qÃÅÇ(ÀeâÛ[)G³2ÎÌÉT£NÈ˵|c¦b*]á)pÛC|f¶×,-6t»spü^ËC fÍýÌxwvó1£ccuL$ |tp-4ä÷ÕÅç7ÝÆä7†øq÷bY÷–÷Œktëhˆq{Î’#,.kêÒǃ2â6ÃÊW¯´s!¹¸a-¦y79ÇŒ.9hØI[¡ÖöÄ X¸÷ë5púnJ&Ìͪ²fWtw„7†&åæwla¹y·ã·šæ\n\Kvèc|Œ„Êó4®{Ú#š$qkHmxt ‹xâ³¹=å˜|ÑAö4ÇnÙÖ>QDQ†µÄ=Ìc]¡µp&œzW G X¥À¾Í¸q½-0—±³5õ){Å ÇVtc¼Ô„«I©¦zM¼ÁÔX ”ÖvTS;pí "NZÌ¿›;瘷sºû¥îÙ–Ïî¤Ñpöã‹È¦’¹¯ñ c.!Þ)à±­ËbþÙvÿy·ûÅ®JwLÞñš¡i¼•µ¬m-ñ}oÊíë ã‰N:øÄILcFÀæO•¬ "örÅ’É;q…š´f·:NU‹ôE’‰qº¡?htÁ2”1J:–w¸­y!´\Üuì—ØŒ­ÕͳaÞ[?xüÉú{jS¨ÐHØ19|4üÔÜm7¶¬µÈãî­á™Ò7¹t’w%¿¶„5Ô š‘AR@]!ÁäCxl镸P».;~^ 7Ø·n*y?iJä¶¼#cœOÚwDDƒr¤Œ©¡ž´p“s @ á}  ÖëÍËÉ/6F+šx»yá¾ÂßA|اa†cÞ"žjYÞ5Í/®–ðêZ¿.­™mºoö üÑIk”´–ÔɻȄÍi’)XáÁÚpoV§q]OÆÞC‡½3Ü䦠}ÄQPøfÂA3&£tmüzÜÑ.‚¨ˆ¹AåÀ/WIR—C¢¡4­¯’ø ¼6Å‚÷*?úöZY2DÔ-ÑÖ* H-‹»ii<×U¯ó;/o“Ý’ÚãÿþÑ–pBvãA¡2k Ž–±,î õbÕçÕJU6ÔªªR©ÕÑS¤§TÀ§@ù¦‰Õ()·ÇJ€§T ¥IjuJU6ëPZR•Mº{•:JuL XTª)TÛãïÒÒT §UIjª¥:ê SªR©·ÇSBR•N­¡R˜)J¦Ý}ÚE¡:¥6éRZR‚•©Õ()·ÇS¥UR‚]êIÕ)Tëè© ER•MºT–ªªPSž¤µ:¥6õ Fš'T€§VФS›u¥@R›t©-N©ANº’ÔêÛ§wŠ µ:¥9ü”¨SªR©·]”¸u§T€¥-=‰Õ(mAjuHêÚ%©Õ (<úÔé¢u^ép>]lx!ç‰ÿÜGݯ˾`~þfÿkÞ~±"ûÿfþèb¿fÚþ‹Ð-ÀÛäþŠÔVȦàmòE_^.ï]Äïþ!sOúȹk÷?”ô§lÃØïÔá_–\ÂýþÎ~ؼýfEUèKOR„)B¡ P…(B”!J¥VR NªÀpðÒÒŽ à<ÃSDø…`6”QíWÒNƒ©\B*B°0éEPUÀãáå©Òš¸e" uWxjhª¸Ÿ’‘jÀÜÃRBªžµp8Ò⎀p¡>)ÜÃJ€¢¡\Î*)«ù‡«üTˆíN©üþJ’ÔÕÀüÃRZRƦˆ¨HŠ<)ñJšT¡0UÀáÏ¥IjuHš’ÔêúT–§T€q©¢*< @è¥áUT §]*U n4‹SªP??’ µ0RüÃRZRœõ4)Õ)TÛÕK‡ZuJ w-=‰Õ )·_v¤µ:¥:ª SªPR§JuHU6éîE/ iANà¥@˜=‰AMºôÔ–§T §UAjª¥:êt§T¥SnžçôT‘ÚR‚ÁJ0R‚›uéïÔ–¢«!¸ƒÏîóôž0’ym7¶ 0Õ•‡ÐI´š²…—mf¸šp”ê§U“!f»ñ™3p ŸfÚòh aű-²Vðܺädr÷ä–wfàF BŽv Þ_²(¶ýÝ»$Ý“XÍ$-ƒîXØm.Ö!/:Í@¡v¿³Æ”é+ ÁNºÞ‹V§T¥Wm*´ê”î šÁJU6ëîÔ–§T ¦Ý;¼U%©Õ()Q¦ ª˜ªíñÒ§juJ uyB•N«)pŸP2Ùœ{jb¦3£¶Ó‘vÎk}vJ¨{*"}ŠQÎÍ b DÆÝ©œ¼—¤‘Dʸ”S17ʧ˜ï>^ßïl”å2’7d1Ѿls``ûÄ‘8½½åήóº.Ò]‚š‡BÝëlï M­e,¶ ;¥Í{c½t¯=Ë$hiÑàƒdÔÕJPq˜W2‡1Îsç0œç9„Ç9Œ:˜Æ1„DÆ0Ž¢=ñ¯HîÃF(Ò5jx’® wN“ÔŠ¥zÈ4¨S›té¥@UU()ܨ)TÛ­Ijª¥*›tîæ¨ÒSª`S¯¢’uJU6øéi Õ()ÕPZR‚u©Õ)TÛãïTUU()ýaý“¯bb©·_v‘hN©J¦Ý* SªPR µ:¥*›z†• uíJ t‡”*hR•N¾ŠE¡0R•Mµ©Õ()RZª©J¦Ýz{õ4!:¥:CʨR‚{B§H= Õ()¶¤µ:¥;‚ µ0R•MºìšQ:¤:CËKÂS}¨ )¶¤µ:¥óÔ¦ B©Ì=CRZR‚ÁKŠuJU6ëÝã¥@RU%©Õ{¿ÀçÿÀÄñŸþAµ~[s÷÷9û^óõ‰èÌýÏÄþ͵ý •¨-•J¿\\ÿÞ»‰ßüBæŸõ‘r×î(ÿéNØÿ‡±ß©Â¿,¹…ûýœý±yúÌ‹«Ð–ž¥R„)B¡ P…(B”!J¥R„)B€ÃÓJ:«€vR¡B¾µ4N¤-@Â" ô«ûƒú)'NÅp0 ©*àna¢‰Ôp?8xªt¦¬ï *U CmMuV‡EN”ü ÜÃSDWµ\4qO‡R¸(OZ@8óøéPÀááä©Òš@0øZ’ª¸ŸÉS¥:¤ó I ×µ ž• +ØúQáOÂ×KObuH};¼U%©Õ |5Sª@>ßðT–§_­ (>TN©MºRð¦”×Jƒ©Hæ¡©-N©üþJ’Ôê”Ì5©Õ )J…:¥6øûµ¥@R‚]‹Sª@S¯¢ µ:¥6éRZª©JšS¡:¥*›ixQT §pTÐê”Û¯»RZR‚U%ªª”¨§buJU6øéSµ:¥:º)Pê”Û¯»RZR‚›tîñT§T€¥Nšt'TÅSoަ©Õ()Ò¨ uJ uôT–§T¥SmAjª¥;‚§IêN©Š¦Ýi'T¥SnžåMN©ANà©-L¥SmAjuJU:ªhUU)Tëò $Wð¦*›z†§H)Õ()ÕRZª©ANº‚ÔꔪmþŠ’ uJ w*&bb©·_ Ô–§T §UIjuJ sÔªªPSo»Zšꔪt‡”)Q:¦:ú*KSªR©¶¤µ:¥?¬* SªPSn½=úšR•MºyB‘:¥<[*KUU)TÛRZR‚]©Õ()Ð>í*R•MºtÔR‚”´ö'T¥SmAjuH wIjuL t»SBªB©·Nžõ/ uJ RÒ:“ªR©·»š µ:¤*KSªPSn½=ÚÔé¢u^õp5ËaÛÃÏ ÿ'µ¯Ë.a~ÿg?l^~³"ýÙŸ¹øŸÙ¶¿ bôµ²©BàK‹Ÿû×q;ÿˆ\Óþ².ZýÏåý)Ûðö;õ8Wå—0¿³Ÿ¶/?Y‘cÕzÓÔ¡ P…(B”!J¥R„)B¡ P…(B”!JµÔB„UX>ZZSVÔУÀ¯­*'R€Â‘PUÀô'CÔ®¡íVw†‘ ðêWó…-)ñWs I¨ª¸zii «Ã¢¤µ?¸jh{RèâW…$ëÚ=4i¯b¸:*t”ê<úÔ–§Up?UIjuìHæ’¯j@Sž—ëØÌ:QÀô¢½©üþJ)¤óPÔ–§T€~%IjuWó IjuíJ sÒ¡N© ~aÓgø©pëN©@üþJZ{ ˜uØ5%©Õ )ÕPZR‚›{½Ú’Ôê¥Å:¥6ëÝÏJH m÷*KUU()×ÑRZФ*›j UU()ÏJ…:¥6øûµ©§juJ utRÓTê”芒Ôê”ÛÝîT§T€¥MèN©Š¦ßv´©ÚR‚!ÑJ•N©AN¾Š‚ÔÁHU6Ô–§T ¥MRuL íצ¦©Õ)TÛ§”)iUR‚ÁRZ˜)J¦Ú‚ÔꔪuTЦ PS¯ÉSDꘪmêZjR‚ÁRZR•MºÔªªR©·Or¤‚R‚ŸÖ4ESM¾>ý"ÕUJ uT§T §]IjuJUvøêhSªPS«¢•ª¦:¤µJU6ÔªªPR§JuJU6ëÓß©¡N©J¦Ñ(R N©Nà©-L¥SmAjuH utT–ª1Tëò M *”ªmñÒ UT ¥IjuJU6ëPZR‚]%©Õ()×¶¦…:¥6øéP'T §=-=‰Õ()·Z‚Ôêêè¨-UT §_»J…J mñ÷iJ‰Õ()ÏS§±0W¾Ü ð »ÿDÿÉÍkò·˜_¿ùÏÛ¿¬È¿Aö_îv'öe¯è½­=lªP…øâçþõÜNÿâ4ÿ¬‹–¿sùGÿJvÇü=ŽýNùeÌ/ßìçí‹ÏÖdXõ^„´õ(B”!J¥R„)B¡ P…(B”!J¥R„)B¡ P…¨‡xh¢uVóÒÒŽ à` M < ÚÒ¢u*ÀqþºÀ«û»ô“ãÔ®¡íW=*ü àpðòRÒš¸˜jHíEUÀãáå©Òš¸9ütˆ)‚z•ÀÃSDTu«èL} Áà\¯j@8ôÒ-MX‹J*=5BuW‡E"ÔÁJzš'^Õp?=.)øù†—U ŸÉHµ:¤ó»¤µ:¤óÔéN©üÃRZRœô¸§^Ä¥So»Z\ª@?õ…-)Õ(nµ©Õ )ÕRZRÇž¦‰Ôx‚T¸õ¦”è%*U )·Nš’ÕUJçòT¦ B©¶¤µ:¥*hSªPSn½4¨ªPSnžå"Ôê”þ°¨-L…SmIjuJ TЧTÀ¦ÝziSµ:¥6éîTéªuH wIj`¥*›j UU()Ü4)‚˜ë¥DU()·Nš5U^Ô §pT–§T¥Snµ©Õ)Tê¥BR‚}4LÅSoŽ‘juH uTªª`S® µ:¥*»|t¨SªPS¸*hªb©·_v‘juJ mÒ µ:¥* SªR©·]ƒJŠª”é(TÐ'TÀ§_EIjuJU6øêKSªR©ÕÑPZ˜)ANò *'T¥SoPÔ¯jPS¸)§T¥Snµ©Õ)TÛ§¹PZª©N¾ŠTN©J¦Þ¡© 'T §U"Ôê”ë¨-N©J¦Ý=Ïè©-N©ANà©LÄ¥So¿J:¥:ªKSªPS® µUWÖÑ%]¹nÕ¹ ¢îVMS/(¨¢§ ßt®ŽFòÛa6Jõá–DéãÐÖ°|.Õ•¥ÅýäV6­/¹šF± t—8Ь•ú#àêXk>1±Š;­XµnSi  [·M ^PܯɌÖEÙŒÍÞ]⺺–b; ¯sÈÿÞ_¢Ø«&ã1–ØÖš¶Þãè¿äYÃXÅßR„/À—?÷®âwÿ¹§ýd\µûŸÊ?úS¶?áìwêp¯Ë.a~ÿg?l^~³"Ǫô%§©B¡ P…(B”!J¥R„)B¡ P…(B”!J¥R„)B¡ P…¨‡†Šê®ç©ÒŽ À`ð *#ˆVÖ•¯j¸—øp8PŽ!\„Tu«„6Ò 'àV‡EN’š¸˜iÚUÀüáS¥ÀÀ>I Ô«Ä)Q:„€zÇ©\ Ì4¸ëÚÏËHµ5p8xJ’T€qðòÔéM\útÔ–§R54N£ëH ñHÛ¯M*Ф‡E-)Õ yõ¨-N©üüžåIjª¤=MT€¥.)¥6ëÓJ:¤õR-N©@ýu%©Õ\Û¥AjuJ MªPSnÞ*<)¥óòûµ4I×± )·¨jKSª@SŸ’¤µ:¥*›u¨-N©ANª\SªPS iP'T ¦Ý:i§T §=Aj`¤*œÃ­AjuJ uR¡N©NºšêÛ§M"ÔëÚ”¨-UT¥Snµ%©Õ)Tê©¡LÀ§]*ꔪmñÔ–§T §UIjuJ uÔ§T¥SnžåI:¥;‚•uìJU6ëîÔ–§T §UIjª¦* SªR«·ÇSDê”êò…*ê˜ëè©-N© ¦ßAjuL wNžÅUJ ôjhŠ¥6éÓJUR‚ÁRZSMµ©Õ!Tê©ÒSª`S¯¢¦‰‚”ªíñÒ N©ANª’ÕUJ uÔ§T¥SnžçôTé)Õ()Ü“±1TÛ¯»S¤'T §UIjuJ uÔ§T…SoާJª§!Œs¥)Œs¥ „Æ0è DDDkŽI#Š7K+ƒbh$’@$’x:ÉàÆÇÈñ@¹î4 ’O@t•˜¼:`雎àa-$ÅRn*C3l¢c¼–ð€zBÅ÷ªGÞ”yKßJøŸæ´ÎBý™´åï1¥Ãï3´ø²i5î£=l¨«Ü8:šEZM~©å,.12·sî(ô_Só¸qeGûGŽ§ÓƒZx·í:”ýâëE;RÞhÐ8"@0né˺óxkåô:ìê¥_ŸÎ"ý’ØâïÉwæEޏr¡¥² åsß-‹1iŒci[²qôô‹xÄ~ÄúRè»~r¢EVYR¦(qÔÃõvÝþp¹™¶vý†Û°±Á>Çg ´n’£#£‚6ÄÂòÛÖ4¼µ€¸µ­Ö€ð,Ïòç²s™{¬ÕÝÖU·W—2ÎðÉmÃå{¤ph6Î! ¸†‚ç)ROŽÿ´%·óÎJúVØü£Yîk{¿oy ÏoXß– ƒé™+mìŠ~ЖßÏ9+é[cò;ÜÖ÷~ÞòžÞ– ƒé™+mìŠ~ЖßÏ9+é[cò;ÜÖ÷~ÞòžÞ– ƒé™+mìŠ~ЖßÏ9+é[cò;ÜÖ÷~ÞòžÞ– ƒé™+mìŠ~ЖßÏ9+é[cò;ÜÖ÷~ÞòžÞ– ƒé™+mìŠ~ЖßÏ9+é[cò;ÜÖ÷~ÞòžÞ– ƒé™+mìŠ~ЖßÏ9+é[cò;ÜÖ÷~ÞòžÞ– ƒé™+mìŠ~ЖßÏ9+é[cò;ÜÖ÷~ÞòžÞ– ƒé™+mìŠ~ЖßÏ9+é[cò;ÜÖ÷~ÞòžÞ– ƒé™+mìŠ~ЖßÏ9+é[cò;ÜÖ÷~ÞòžÞ– ƒé™+mìŠ~ЖßÏ9+é[cò;ÜÖ÷~ÞòžÞ– ƒé™+mìŠ~ЖßÏ9+é[cò;ÜÖ÷~ÞòžÞ– ƒé™+mìŠ~ЖßÏ9+é[cò;ÜÖ÷~ÞòžÞ– ƒé™+mìŠ~ЖßÏ9+é[cò;ÜÖ÷~ÞòžÞ– ƒé™+mìŠ~ЖßÏ9+é[cò;ÜÖ÷~ÞòžÞ– ƒé™+mìŠ~ЖßÏ9+é[cò;ÜÖ÷~ÞòžÞ– ƒé™+mìŠ~ЖßÏ9+é[cò;ÜÖ÷~ÞòžÞ– ƒé™+mìŠ~ЖßÏ9+é[cò;ÜÖ÷~ÞòžÞ– ƒé™+mìŠ~ЖßÏ9+é[cò;ÜÖ÷~ÞòžÞ– ƒé™+mìŠ~ЖßÏ9+é[cò;ÜÖ÷~ÞòžÞ– ƒé™+mìŠ~ЖßÏ9+é[cò;ÜÖ÷~ÞòžÞ– ƒé™+mìŠ~ЖßÏ9+é[cò;ÜÖ÷~ÞòžÞ– ƒé™+mìŠ~ЖßÏ9+é[cò;¼Ö÷~ÞòžÞ– ƒé™+mìŠÁ솷ûç%})l~Q£çwšÞïÛÞBóÛÓù`Ø>™˜ò¶Þȵý¡íÏž2OÒ–Çå*_;œÖ÷~ÞòžÞ—ËÁôÌÇ•¶öE?h{s眓ô¥±ùJÎk{¿oy ÏoOåƒ`ÿy˜ò¶Þȵý¢-ÐþùÉ?J[”©|íó[Ýû{È^{z,;ÒòþVßÙU¿h«{猓ô¥±ùJŸÎç5½ß·¼…ç·¥òÁ°}31åm½•kûEÛßXv¥åü­¿²«~ÑÖÿÏ#éKgò/®jû¿oy ÏnGËÂôÌÇ•¶öU¯íoüï‘þ”¶)ÑóµÍ_wíï!yíÈùbØ^—˜ò¶þʵd„|d¥-ŸÊt¾vy©îý½ä/=¹?–-…éy+oì«_ÚFç|ôµùR—ÎÇ5=ß·ü…ç·%òŰ½//åmý•kûI@ü“¶¿*Qó¯ÍOwíÿ!yíÉü±ì/KËù[eVd¤{äo¤í¯Ê”|ëóSÝûÈ^{r>Xö¥åü­¿²­iX/ò/Òv×åJ>uù©îý¿ä/=¹?–=…éy+oì«PöKÁ‡z_"ý'm~U¥ó¯ÍOwíÿ!yíÈùcØ^——ò¶þÊ­ûLAüí‘>“¶ÿ*Ñó­Í?wíÿ!yíÈùdØ~——ò¶þÊ {&¡½-‘>“¶ÿ*ÒùÕæŸ»öÿ¼öäþY6¥åü­¿²«~ÓpŸ;d?¤­¿ÊÔ¾u9§èÈ]ûr>Y6¥åü­¿²­iØ_²ÒVßåj_:|Òô ¿ä.ý¹,ÛÒòþVßÙUƒÙ? ÞÙé+sòµ:|Óô »öä|²ì?KËù[eZþÔß:ä/¤­ÏÊô|éóKÐ6ÿ»öäþY¶¥åü­¿²«²Š?½rôÉ[Ÿ•é|ésKÐ6ÿ»öä|³l?KËù[eZþÔpÿ:䤭ßÊô|ésKÐ0BïÛ‘òϱ=//åmý•[ö¥ˆù× þñ·+ÒùÐæ `<…ß·#åŸaú^_ÊÛû*×ö§‰ùÓ }#nþX¥ó¡Í@Ày ¿nOåŸbz^_ÊÛû*°{*bƒûÓ }#nþX£ç?š>€ò~Ü–}‰éy+oìªßµTWΗÿÒ6÷åš>sù£è!wíÉü´lOKËù[eVý«bþt¿‡ÿxÛß–i|çsCÐ0BïÛ‘òѱ=//åmý•jÊèÀïIßßHÛß–i|æóCÐ0BïÛ‘òÓ±}//åmý•[ö°ŒùÎýúBßüµKç3š€ò~ÜŸËNÅô¼·•·öU¨{,£CûÎýúBßüµKç/™þ€ò~Ü–­‹éyo+oìªßµ¤wÎWçÒÿåª>rùŸè!wí¨ùjؾ—–ò¶þʬËhðïI_ŸH[ÿ–èùËæyÿö!wí©üµl_KËy[eZþÖñÿ9_H@~[¥ó•Ìÿ@Àù ¿mGË^Åô¼·•·öU`ö]0ï+ìz_À~[¥ó“Ìï@Àù ¿mOå¯bú^[ÊÛû*·ívÄ?¼o¯ãà?.RùÈæw `|…ß¶£å³cz^[ÊÛû*°{/™÷óü|åÊ_8üÎô‘»öÔ|¶loKËy[eVf0ïHß?ÇÀþ]£ç™Þò~ÚŸËnÆô¼·•·öU¯í„Ïç ãøøË´¾q¹›è8#wí¨ùmØÞ—–ò¶þʬÌFýá|u¿‚ü»GÎ/3}änýµ?–Ýéyo+oìªß¶3_œ/ã ¿/RùÄæg à¼ß¶£å»cú^[ÊÛû*°{2÷…ïütåê_8|Ìô‘»öÔ|·lKËy[eVfSpïH^ßÇAþ_£ç™žƒ‚ò7^ÚŸË~Çô¬·•·öUoÛ1¿ú}ëütåú_8\Ìô‘ºöÔ|·ìKËy[eVfrþzõ½ƒü¿Kç™~ƒ‚ò7^ڟˆÇô¬¯•·öU¯í úuéül'Ô¾p9—è8/#uí¨ùpÙ—•ò¶þʬÍ$ƒüúóþ6ê _7üÊô‘ºöÔ|¸ìJÊù[fVf¢aÞ}yÿ õ 7üÊô‘ºöÔþ\vG¥e|­¿³+~ÚÉÿ¦Þ_ÆÂýCKæû™^ƒƒò7^Ú—‘éY_+oìÊÁìÙ žÞ?ÆBýEKæ÷™>ƒƒò7^ÚŸË–Èô¬¯•·öe`öm”?Ïoã!~¢¥óyÌŸAÁù¯lGËžÈô¬¯•·öeoÛt?Ó/ã!¾¢¥ówÌŸAÁù¯lOåÏdúVWÊÛû2°{7ôÿ<¼:ÞC}GGÍß2}än½±.{'Ò²¾VßÙ•¿nóË¿øÈ¨èùºæG àü×¶#åÓdúVWÊÛû2·íÈoôË»ø¸©*~ny‘è8?#uí‰üºlŸJÊùX=™jÎSùåÝü\?Ô”|ÜsÐp~FëÛòë²}++å öeoÛ ÿéwoñqRÒù·æ?¡a<×¶'òí²}++å öepöu(çw`ô»ˆú–›~cúÈÝ{b>]¶O¥e|¤̵gb¡Þwvõ-/›ncúÈÝ{b.Û+Ò²žRfVý»–ÿJºÿЉúš—ͯ1½ än½±.û+Ò²žRfVgŠáþuuõ5/›>czÈÝ{b>]öW¥e<¤̬Ï5üêêþ*'êz_6|Æô,'‘ºöÄþ^6W¥e<¤Ì­ûz¸ÿIºŠŠúž›>czÈÝ{b>^6W¥e<¤̬Ïw!þstõE/›búÈÝ{b/;/Ò²žRfVý¾]¤]ÄÅ}QKæÃ˜¾……ò7^Ø——éYO)³+~ßnÿÒ.âbþ¨¥ó_ÌOBÂùŸlGËÖËô¬§”ƒÙ•ƒÙúð;Î.âbþ©¥ó_ÌOBÂùŸlOåëeúVSÊAìÊßõyÿŸ¹¿‰ŒúªšîbzÈÜûb>^ö_¥e<¤̬=÷û—ø˜Ïª©|Öóа¾FçÛù{Ùž•”ò{2°pø?ßîOâ#>ª¥óYÌ?BÂùŸkGËæÌô¬§”ƒÙ•¿ê ÿÿ=rõ]/š¾aúÈÜûZ/›3Ò²žRfV$ýþãëqõ]5|Ãô<7‘¹ö´|¾lÏIÉùH=™[þ¡R!ÞZãþ"7êÊ>j¹…èX_#síhù}Ùž•”ò{2dx ß.ò—Ã^Rv;¢ÃÙÇÚu…qKüÓsF6×Çë6Š«§ äùÙlxs§É8£,4>0ø]÷øB9Ê ž0©¨Q.ó‡w<ÂUŠ[Þ&è5yVëæ†ùÞŒ0g²¾Èš÷, Š/¢¬Œ4>FMdv¯AÛÛ iíw qq²è w®¬’}4{Ë‹kÖ¤} Ѽk†!,–艧۔¥ÔÛ…×PþºsÖ€·Þ…)HP)C@Є+P…(Bø|]¯ü'Ñ÷¿ûÍ5¡ æùÔüÚ§Èž§æÐ…>Dõ?6„)ò'©ù´!O‘=OÍ¡ |‰ê~mSäOSóhBŸ"zŸ›BùÔüÚ§Èž§æÐ…>Dõ?6„)ò'©ù´!O‘=OÍ¡ |‰ê~mSäOSóhBŸ"zŸ›BùÔüÚ§Èž§æÐ…>Dõ?6„)ò'©ù´!O‘=OÍ¡ |‰ê~mSäOSóhBŸ"zŸ›BùÔüÚ§Èž§æÐ…>Dõ?6„)ò'©ù´!O‘=OÍ¡ |‰ê~mSäOSóhBŸ"zŸ›BùÔüÚ§Èž§æÐ…>Dõ?6„)ò'©ù´!O‘=OÍ¡ |‰ê~mSäOSóhBŸ"zŸ›BùÔüÚ§Èž§æÐ…>Dõ?6„)ò'©ù´!O‘=OÍ¡ |‰ê~mSäOSóhBŸ"zŸ›BùÔüÚ§Èž§æÐ…>Dõ?6„)ò'©ù´!O‘=OÍ¡ |‰ê~mSäOSóhBŸ"zŸ›BùÔüÚ§Èž§æÐ…>Dõ?6„)ò'©ù´!O‘=OÍ¡ |‰ê~mSäOSóhBŸ"zŸ›BùÔüÚ§Èž§æÐ…>Dõ?6„)ò'©ù´!O‘=OÍ¡ |‰ê~mSäOSóhBŸ"zŸ›BùÔüÚ§Èž§æÐ…>Dõ?6„)ò'©ù´!O‘=OÍ¡ |‰ê~mSäOSóhBŸ"zŸ›BùÔüÚ§Èž§æÐ…>Dõ?6„)ò'©ù´!O‘=OÍ¡ |‰ê~mSäOSóhBŸ"zŸ›BùÔüÚ§Èž§æÐ…>Dõ?6„)ò'©ù´!O‘=OÍ¡ |‰ê~mSäOSóhBŸ"zŸ›BùÔüÚ¾ô=Oì; ?û¿à¡ é¡ P…(B”!ÿÙopenchange-2.0/apidocs/html/mapitest/index.html000066400000000000000000000043371223057412600217040ustar00rootroot00000000000000 MAPITests 2.0 API Documentation
mapitest documentation

mapitest acts as stand-alone torture test of a range of MAPI function calls. It is intended to validate the implementation of various functions, and to ensure that existing functionality does not suffer regression between releases.

As a general principle, mapitest calls should leave the system in the same state at the end as at the start - it is meant to clean up after itself.


Creative Commons License
Creative Commons Attribution icon Creative Commons Share Alike icon
This content is licensed under the Creative Commons
Attribution ShareAlike License v. 3.0:
http://creativecommons.org/licenses/by-sa/3.0/

openchange-2.0/apidocs/html/mapitest/mapitest_8c.html000066400000000000000000000063751223057412600230210ustar00rootroot00000000000000 MAPITests 2.0 API Documentation
mapitest.c File Reference

Core of mapitest implementation. More...

#include <popt.h>
#include "config.h"

Functions

int main (int argc, const char *argv[])
 main program

Detailed Description

Core of mapitest implementation.


Creative Commons License
Creative Commons Attribution icon Creative Commons Share Alike icon
This content is licensed under the Creative Commons
Attribution ShareAlike License v. 3.0:
http://creativecommons.org/licenses/by-sa/3.0/

openchange-2.0/apidocs/html/mapitest/mapitest_8h.html000066400000000000000000000237671223057412600230320ustar00rootroot00000000000000 MAPITests 2.0 API Documentation
mapitest.h File Reference

Data structures for mapitest. More...

Data Structures

struct  mapitest
 The context structure for a mapitest run. More...
struct  mapitest_stat
 mapitest statistics More...
struct  mapitest_suite
 A list of test suites. More...
struct  mapitest_test
 A list of mapitest tests. More...
struct  mapitest_unit
 List of test names. More...
struct  mt_common_tf_ctx
 Context for mapitest test folder. More...

Enumerations

enum  TestApplicabilityFlags { ApplicableToAllVersions = 0, NotInExchange2010 = 0x1, NotInExchange2010SP0 = 0x2, ExpectedFail = 0x8000 }
 Flags for changing test applicability. More...
enum  TestResult { Pass, Fail, UnexpectedPass, ExpectedFailure }
 List of possible test results. More...

Detailed Description

Data structures for mapitest.

Enumeration Type Documentation

Flags for changing test applicability.

If you add values here, you also need to add a matching description to applicabilityFlagsDescription and suitable logic to mapitest_suite_test_is_applicable().

Enumerator:
ApplicableToAllVersions 

This test is always applicable

NotInExchange2010 

This test is not applicable to Exchange 2010

NotInExchange2010SP0 

This test is not applicable to Exchange 2010 Service Pack 0, but is applicable to later versions

ExpectedFail 

This test is expected to fail

enum TestResult

List of possible test results.

Enumerator:
Pass 

The test was expected to pass, and it did

Fail 

The test was expected to pass, but it failed

UnexpectedPass 

The test was expected to fail, but it passed instead

ExpectedFailure 

The test was expected to fail, and it did


Creative Commons License
Creative Commons Attribution icon Creative Commons Share Alike icon
This content is licensed under the Creative Commons
Attribution ShareAlike License v. 3.0:
http://creativecommons.org/licenses/by-sa/3.0/

openchange-2.0/apidocs/html/mapitest/mapitest__common_8c.html000066400000000000000000000623121223057412600245210ustar00rootroot00000000000000 MAPITests 2.0 API Documentation
mapitest_common.c File Reference

Support functions for mapitest modules. More...

Functions

void mapitest_common_cleanup (struct mapitest *mt)
 Convenience function to clean up after logging into the server.
bool mapitest_common_create_filled_test_folder (struct mapitest *mt)
 Create a test folder, and fill with 10 sample messages.
bool mapitest_common_find_folder (struct mapitest *mt, mapi_object_t *obj_parent, mapi_object_t *obj_child, const char *name)
 Find a folder within a container.
bool mapitest_common_folder_open (struct mapitest *mt, mapi_object_t *obj_parent, mapi_object_t *obj_child, uint32_t olNum)
 Opens a default folder.
char * mapitest_common_genblob (TALLOC_CTX *mem_ctx, size_t len)
 Generate a random blob of readable data.
bool mapitest_common_message_create (struct mapitest *mt, mapi_object_t *obj_folder, mapi_object_t *obj_message, const char *subject)
 Create a message ready to submit.
bool mapitest_common_message_delete_by_subject (struct mapitest *mt, mapi_object_t *obj_folder, const char *subject)
 This function deletes messages in a folder, based on matching the subject name.
bool mapitest_common_message_fill (struct mapitest *mt, mapi_object_t *obj_message, const char *subject)
 Create a message ready to submit.
bool mapitest_common_setup (struct mapitest *mt, mapi_object_t *obj_htable, uint32_t *count)
 Convenience function to login to the server.

Detailed Description

Support functions for mapitest modules.

These functions implement commonly needed functionality that would otherwise be copied into each module implementation

Function Documentation

bool mapitest_common_create_filled_test_folder ( struct mapitest mt)

Create a test folder, and fill with 10 sample messages.

This function creates a test folder (name set by the MT_DIRNAME_TEST define), and fills it with 5 messages with the same subject and 5 messages with the same sender.

Parameters
mtpointer to the mapitest context

References mapitest_common_message_create(), mapitest_print(), mapitest_print_retval(), and mapitest::mem_ctx.

Referenced by mapitest_common_setup().

bool mapitest_common_folder_open ( struct mapitest mt,
mapi_object_t *  obj_parent,
mapi_object_t *  obj_child,
uint32_t  olNum 
)

Opens a default folder.

This function opens one of the default (standard) folders, returning the folder as obj_child. olNum may be one of:

  • olFolderTopInformationStore
  • olFolderDeletedItems
  • olFolderOutbox
  • olFolderSentMail
  • olFolderInbox
  • olFolderCalendar
  • olFolderContacts
  • olFolderJournal
  • olFolderNotes
  • olFolderTasks
  • olFolderDrafts
Parameters
mtpointer to the top level mapitest structure
obj_parentparent folder (usually the message store, must be opened)
obj_childthe folder that has been opened
olNumthe folder identifier (see list above)
Returns
true on success, false on failure

References mapitest_print().

Referenced by mapitest_common_setup(), mapitest_oxcfold_CopyFolder(), mapitest_oxcfold_MoveFolder(), mapitest_oxcmsg_CreateMessage(), mapitest_oxcmsg_GetValidAttachments(), mapitest_oxcmsg_OpenEmbeddedMessage(), mapitest_oxcmsg_SetMessageReadFlag(), mapitest_oxcnotif_RegisterNotification(), mapitest_oxomsg_SpoolerLockMessage(), mapitest_oxomsg_TransportSend(), and mapitest_oxorule_GetRulesTable().

char* mapitest_common_genblob ( TALLOC_CTX *  mem_ctx,
size_t  len 
)

Generate a random blob of readable data.

Parameters
mem_ctxthe talloc memory context to create the blob in
lenthe length of the blob to create
Returns
random blob of readable data, of length len bytes, with a null terminator.
Note
the data is from 0..len, and the null terminator is at position len+1. So the returned array is actually len+1 bytes in total.

Referenced by mapitest_oxcprpt_CopyToStream(), mapitest_oxcprpt_Stream(), and mapitest_oxcprpt_WriteAndCommitStream().

bool mapitest_common_message_delete_by_subject ( struct mapitest mt,
mapi_object_t *  obj_folder,
const char *  subject 
)

This function deletes messages in a folder, based on matching the subject name.

This is meant to clean up a folder after a test has been run.

Parameters
mtpointer to the top level mapitest structure
obj_folderthe folder to search through
subjectthe message subject to match

References mapitest_print(), mapitest_print_retval(), and mapitest::mem_ctx.

Referenced by mapitest_oxomsg_AbortSubmit(), mapitest_oxomsg_SubmitMessage(), and mapitest_oxomsg_TransportSend().

bool mapitest_common_setup ( struct mapitest mt,
mapi_object_t *  obj_htable,
uint32_t *  count 
)

Convenience function to login to the server.

This functions logs into the server, gets the top level store, and gets the hierarchy table for the top level store (which is returned as obj_htable). It also creates a test folder with 10 test messages.

Parameters
mtpointer to the top-level mapitest structure
obj_htablethe hierarchy table for the top level store
countthe number of rows in the top level hierarchy table
Returns
true on success, otherwise false

References mapitest_common_create_filled_test_folder(), mapitest_common_folder_open(), mapitest_print_retval(), and mapitest::mem_ctx.

Referenced by mapitest_oxcfold_HardDeleteMessagesAndSubfolders(), mapitest_oxcfxics_CopyFolder(), mapitest_oxcfxics_CopyMessages(), mapitest_oxcfxics_CopyProperties(), mapitest_oxcfxics_CopyTo(), mapitest_oxcfxics_DestConfigure(), mapitest_oxcfxics_SetLocalReplicaMidsetDeleted(), mapitest_oxcfxics_SyncConfigure(), mapitest_oxcfxics_SyncOpenCollector(), mapitest_oxcmsg_SetReadFlags(), mapitest_oxctable_Category(), mapitest_oxctable_CreateBookmark(), mapitest_oxctable_GetStatus(), mapitest_oxctable_QueryColumns(), mapitest_oxctable_QueryRows(), mapitest_oxctable_Restrict(), mapitest_oxctable_SeekRow(), mapitest_oxctable_SeekRowApprox(), mapitest_oxctable_SeekRowBookmark(), mapitest_oxctable_SetColumns(), and mapitest_oxomsg_TransportNewMail().


Creative Commons License
Creative Commons Attribution icon Creative Commons Share Alike icon
This content is licensed under the Creative Commons
Attribution ShareAlike License v. 3.0:
http://creativecommons.org/licenses/by-sa/3.0/

openchange-2.0/apidocs/html/mapitest/mapitest__print_8c.html000066400000000000000000002347751223057412600244030ustar00rootroot00000000000000 MAPITests 2.0 API Documentation
mapitest_print.c File Reference

Print / display functions for mapitest output. More...

Functions

void mapitest_deindent (void)
void mapitest_indent (void)
void mapitest_print (struct mapitest *mt, const char *format,...)
void mapitest_print_headers (struct mapitest *mt)
void mapitest_print_headers_info (struct mapitest *mt)
void mapitest_print_headers_server_info (struct mapitest *mt)
void mapitest_print_line (struct mapitest *mt, int len, char delim)
void mapitest_print_module_title_end (struct mapitest *mt)
void mapitest_print_module_title_start (struct mapitest *mt, const char *str)
void mapitest_print_newline (struct mapitest *mt, int count)
void mapitest_print_PAB_entry (struct mapitest *mt, struct PropertyRow_r *aRow)
 Output a row of the public address book.
void mapitest_print_retval (struct mapitest *mt, char *name)
void mapitest_print_retval_clean (struct mapitest *mt, char *name, enum MAPISTATUS retval)
void mapitest_print_retval_fmt (struct mapitest *mt, char *name, const char *format,...)
void mapitest_print_retval_fmt_clean (struct mapitest *mt, char *name, enum MAPISTATUS retval, const char *format,...)
void mapitest_print_retval_step (struct mapitest *mt, char *step, char *name, enum MAPISTATUS retval)
void mapitest_print_retval_step_fmt (struct mapitest *mt, char *step, char *name, const char *format,...)
void mapitest_print_SPropValue (struct mapitest *mt, struct SPropValue lpProp, const char *sep)
 Output a row of the public address book.
void mapitest_print_SRowSet (struct mapitest *mt, struct SRowSet *rowset, const char *sep)
 Output a set of rows from a table.
void mapitest_print_tab (struct mapitest *mt)
void mapitest_print_test_result (struct mapitest *mt, char *name, bool ret)
void mapitest_print_test_title_end (struct mapitest *mt)
void mapitest_print_test_title_start (struct mapitest *mt, const char *str)
void mapitest_print_title (struct mapitest *mt, const char *str, char delim)
void mapitest_underline (struct mapitest *mt, const char *str, char delim)

Detailed Description

Print / display functions for mapitest output.

Function Documentation

void mapitest_print ( struct mapitest mt,
const char *  format,
  ... 
)

Print a string in the stream

Parameters
mtpointer to the top-level mapitest structure
formatthe format string
...the format string parameters

References mapitest_print_tab(), and mapitest::subunit_output.

Referenced by mapitest_common_cleanup(), mapitest_common_create_filled_test_folder(), mapitest_common_folder_open(), mapitest_common_message_delete_by_subject(), mapitest_errorchecks_simplemapi_c(), mapitest_lcid_langcode2langtag(), mapitest_mapidump_freebusy(), mapitest_mapidump_task(), mapitest_noserver_lzfu(), mapitest_noserver_mapi_properties(), mapitest_noserver_proptagvalue(), mapitest_noserver_rtfcp(), mapitest_noserver_rtfcp_large(), mapitest_noserver_srowset(), mapitest_nspi_CompareMIds(), mapitest_nspi_GetPropList(), mapitest_nspi_ModProps(), mapitest_nspi_QueryColumns(), mapitest_nspi_ResolveNames(), mapitest_nspi_UpdateStat(), mapitest_oxcfold_CopyFolder(), mapitest_oxcfold_CreateDeleteFolder(), mapitest_oxcfold_CreateFolder(), mapitest_oxcfold_CreateFolderVariants(), mapitest_oxcfold_DeleteMessages(), mapitest_oxcfold_HardDeleteMessages(), mapitest_oxcfold_HardDeleteMessagesAndSubfolders(), mapitest_oxcfold_MoveCopyMessages(), mapitest_oxcfold_MoveFolder(), mapitest_oxcfold_OpenFolder(), mapitest_oxcfxics_CopyFolder(), mapitest_oxcfxics_CopyMessages(), mapitest_oxcfxics_CopyProperties(), mapitest_oxcfxics_CopyTo(), mapitest_oxcfxics_DestConfigure(), mapitest_oxcfxics_GetLocalReplicaIds(), mapitest_oxcfxics_SetLocalReplicaMidsetDeleted(), mapitest_oxcmsg_GetValidAttachments(), mapitest_oxcmsg_ModifyRecipients(), mapitest_oxcmsg_OpenEmbeddedMessage(), mapitest_oxcmsg_ReadRecipients(), mapitest_oxcmsg_RemoveAllRecipients(), mapitest_oxcmsg_SetMessageReadFlag(), mapitest_oxcmsg_SetMessageStatus(), mapitest_oxcmsg_SetReadFlags(), mapitest_oxcprpt_CopyProps(), mapitest_oxcprpt_CopyTo(), mapitest_oxcprpt_CopyToStream(), mapitest_oxcprpt_DeleteProps(), mapitest_oxcprpt_NameId(), mapitest_oxcprpt_NameId_PSMAPI(), mapitest_oxcprpt_NoReplicate(), mapitest_oxcprpt_SetProps(), mapitest_oxcprpt_Stream(), mapitest_oxcprpt_WriteAndCommitStream(), mapitest_oxcstor_GetOwningServers(), mapitest_oxcstor_GetReceiveFolder(), mapitest_oxcstor_IsMailboxFolder(), mapitest_oxcstor_LongTermId(), mapitest_oxcstor_PublicFolderIsGhosted(), mapitest_oxctable_Category(), mapitest_oxctable_GetStatus(), mapitest_oxctable_QueryColumns(), mapitest_oxctable_QueryRows(), mapitest_oxctable_Restrict(), mapitest_oxomsg_AddressTypes(), mapitest_oxomsg_SpoolerLockMessage(), mapitest_oxomsg_TransportSend(), mapitest_print_headers_info(), mapitest_print_headers_server_info(), mapitest_print_module_title_start(), mapitest_print_retval(), mapitest_print_retval_clean(), mapitest_print_retval_fmt(), mapitest_print_retval_fmt_clean(), mapitest_print_retval_step(), mapitest_print_retval_step_fmt(), mapitest_print_test_result(), mapitest_print_test_title_start(), and mapitest_stat_dump().

void mapitest_print_headers ( struct mapitest mt)

Print mapitest report headers

Parameters
mtpointer to the top-level mapitest structure

References mapitest_deindent(), mapitest_indent(), mapitest_print_headers_info(), mapitest_print_headers_server_info(), mapitest_print_newline(), mapitest::no_server, and mapitest::subunit_output.

Referenced by main().

void mapitest_print_headers_info ( struct mapitest mt)

Print mapitest report headers information

Parameters
mtpointer to the top-level mapitest structure

References mapitest::confidential, mapitest_deindent(), mapitest_indent(), mapitest_print(), and mapitest_print_newline().

Referenced by mapitest_print_headers().

void mapitest_print_headers_server_info ( struct mapitest mt)

Print a report of the Exchange server and account information

Parameters
mtpointer to the top-level mapitest structure

References mapitest::confidential, mapitest_deindent(), mapitest_indent(), mapitest_print(), mapitest_print_newline(), and mapitest::online.

Referenced by mapitest_print_headers().

void mapitest_print_line ( struct mapitest mt,
int  len,
char  delim 
)

Print a line using a delimiter

Parameters
mtpointer to the top-level mapitest structure
lenthe length of the line to print
delimthe line delimiter

References mapitest_print_newline(), and mapitest::subunit_output.

Referenced by mapitest_print_module_title_end(), mapitest_print_module_title_start(), mapitest_print_test_result(), mapitest_print_test_title_end(), mapitest_print_test_title_start(), and mapitest_underline().

void mapitest_print_module_title_end ( struct mapitest mt)

Print the content at the end of the module

Parameters
mtpointer to the top-level mapitest structure

References mapitest_deindent(), mapitest_print_line(), mapitest_print_newline(), and mapitest_print_tab().

Referenced by mapitest_run_all().

void mapitest_print_module_title_start ( struct mapitest mt,
const char *  str 
)

Print the module title

Parameters
mtpointer to the top-level mapitest structure
strthe module title string

References mapitest_indent(), mapitest_print(), mapitest_print_line(), mapitest_print_tab(), and mapitest::mem_ctx.

Referenced by mapitest_run_all().

void mapitest_print_newline ( struct mapitest mt,
int  count 
)

Print newline characters

Parameters
mtpointer to the top-level mapitest structure
countnumber of newline characters to print

References mapitest::subunit_output.

Referenced by mapitest_print_headers(), mapitest_print_headers_info(), mapitest_print_headers_server_info(), mapitest_print_line(), mapitest_print_module_title_end(), and mapitest_print_test_result().

void mapitest_print_PAB_entry ( struct mapitest mt,
struct PropertyRow_r *  aRow 
)

Output a row of the public address book.

Parameters
mtpointer to the top-level mapitest structure
aRowone row of the public address book (Global Address List)

This function is usually used with GetGALTable, which can obtain several rows at once - you'll need to iterate over the rows.

The SRow is assumed to contain entries for PR_ADDRTYPE_UNICODE, PR_DISPLAY_NAME_UNICODE, PR_EMAIL_ADDRESS_UNICODE and PR_ACCOUNT_UNICODE.

Note
this is a simple wrapper for mapidump_PAB_entry(), only for use in mapitest.

References mapitest::subunit_output.

Referenced by mapitest_nspi_GetGALTable().

void mapitest_print_retval ( struct mapitest mt,
char *  name 
)

Print mapitest return value

Parameters
mtpointer to the top-level mapitest structure
namethe test name
See Also
mapitest_print_retval_fmt for a version providing an additional format string
mapitest_print_retval_clean for a version that doesn't rely on GetLastError()

References mapitest::color, mapitest_print(), and mapitest::subunit_output.

Referenced by mapitest_common_create_filled_test_folder(), mapitest_common_message_create(), mapitest_common_message_delete_by_subject(), mapitest_common_message_fill(), mapitest_common_setup(), mapitest_noserver_lzfu(), mapitest_noserver_rtfcp(), mapitest_nspi_GetPropList(), mapitest_nspi_GetProps(), mapitest_nspi_UpdateStat(), mapitest_oxcfold_CopyFolder(), mapitest_oxcfold_CreateDeleteFolder(), mapitest_oxcfold_CreateFolder(), mapitest_oxcfold_GetContentsTable(), mapitest_oxcfold_GetHierarchyTable(), mapitest_oxcfold_GetSearchCriteria(), mapitest_oxcfold_HardDeleteMessages(), mapitest_oxcfold_HardDeleteMessagesAndSubfolders(), mapitest_oxcfold_MoveCopyMessages(), mapitest_oxcfold_MoveFolder(), mapitest_oxcfold_OpenFolder(), mapitest_oxcfold_SetSearchCriteria(), mapitest_oxcfxics_GetLocalReplicaIds(), mapitest_oxcmsg_CreateMessage(), mapitest_oxcmsg_ModifyRecipients(), mapitest_oxcmsg_ReadRecipients(), mapitest_oxcmsg_ReloadCachedInformation(), mapitest_oxcmsg_RemoveAllRecipients(), mapitest_oxcmsg_SaveChangesMessage(), mapitest_oxcmsg_SetMessageReadFlag(), mapitest_oxcmsg_SetMessageStatus(), mapitest_oxcnotif_RegisterNotification(), mapitest_oxcperm_GetPermissionsTable(), mapitest_oxcperm_ModifyPermissions(), mapitest_oxcprpt_CopyTo(), mapitest_oxcprpt_CopyToStream(), mapitest_oxcprpt_GetPropList(), mapitest_oxcprpt_GetProps(), mapitest_oxcprpt_GetPropsAll(), mapitest_oxcprpt_NameId(), mapitest_oxcprpt_Stream(), mapitest_oxcprpt_WriteAndCommitStream(), mapitest_oxcstor_GetOwningServers(), mapitest_oxcstor_GetReceiveFolderTable(), mapitest_oxcstor_GetStoreState(), mapitest_oxcstor_IsMailboxFolder(), mapitest_oxcstor_Logon(), mapitest_oxcstor_LongTermId(), mapitest_oxcstor_PublicFolderIsGhosted(), mapitest_oxctable_Category(), mapitest_oxctable_GetStatus(), mapitest_oxctable_QueryColumns(), mapitest_oxctable_QueryRows(), mapitest_oxctable_Restrict(), mapitest_oxctable_SeekRowBookmark(), mapitest_oxctable_SetColumns(), mapitest_oxomsg_AbortSubmit(), mapitest_oxomsg_AddressTypes(), mapitest_oxomsg_SetSpooler(), mapitest_oxomsg_SpoolerLockMessage(), mapitest_oxomsg_SubmitMessage(), mapitest_oxomsg_TransportSend(), and mapitest_oxorule_GetRulesTable().

void mapitest_print_retval_clean ( struct mapitest mt,
char *  name,
enum MAPISTATUS  retval 
)

Print mapitest return value

This version takes an explicit return status value

Parameters
mtpointer to the top-level mapitest structure
namethe test name
retvalthe return value to output
See Also
mapitest_print_retval_fmt_clean for a version providing an additional format string

References mapitest::color, mapitest_print(), and mapitest::subunit_output.

Referenced by mapitest_noserver_rtfcp_large(), mapitest_nspi_CompareMIds(), mapitest_nspi_DNToMId(), mapitest_nspi_GetGALTable(), mapitest_nspi_GetIDsFromNames(), mapitest_nspi_GetMatches(), mapitest_nspi_GetNamesFromIDs(), mapitest_nspi_GetProps(), mapitest_nspi_GetSpecialTable(), mapitest_nspi_GetTemplateInfo(), mapitest_nspi_ModLinkAtt(), mapitest_nspi_ModProps(), mapitest_nspi_QueryColumns(), mapitest_nspi_QueryRows(), mapitest_nspi_ResolveNames(), mapitest_nspi_ResortRestriction(), mapitest_nspi_SeekEntries(), mapitest_oxcfold_CreateFolderVariants(), mapitest_oxcfold_DeleteMessages(), mapitest_oxcfxics_CopyFolder(), mapitest_oxcfxics_CopyMessages(), mapitest_oxcfxics_CopyProperties(), mapitest_oxcfxics_CopyTo(), mapitest_oxcfxics_DestConfigure(), mapitest_oxcfxics_SetLocalReplicaMidsetDeleted(), mapitest_oxcfxics_SyncConfigure(), mapitest_oxcfxics_SyncOpenCollector(), mapitest_oxcmsg_GetMessageStatus(), mapitest_oxcmsg_GetValidAttachments(), mapitest_oxcmsg_ModifyRecipients(), mapitest_oxcmsg_ReadRecipients(), mapitest_oxcmsg_RemoveAllRecipients(), mapitest_oxcmsg_SetMessageStatus(), mapitest_oxcmsg_SetReadFlags(), mapitest_oxcnotif_SyncOpenAdvisor(), mapitest_oxcprpt_CopyTo(), mapitest_oxcprpt_NameId_PSMAPI(), mapitest_oxcprpt_WriteAndCommitStream(), mapitest_oxcstor_GetReceiveFolder(), and mapitest_oxomsg_TransportNewMail().

void mapitest_print_retval_fmt_clean ( struct mapitest mt,
char *  name,
enum MAPISTATUS  retval,
const char *  format,
  ... 
)

Print mapitest return value with additional format string

Parameters
mtpointer to the top-level mapitest structure
namethe test name
retvalthe return value to output
formatthe format string
...the format string parameters

References mapitest::color, and mapitest_print().

Referenced by mapitest_oxcmsg_GetValidAttachments(), mapitest_oxcprpt_WriteAndCommitStream(), mapitest_oxctable_CreateBookmark(), and mapitest_oxctable_SeekRowBookmark().

void mapitest_print_retval_step ( struct mapitest mt,
char *  step,
char *  name,
enum MAPISTATUS  retval 
)

Print mapitest return value for a given step

Parameters
mtpointer to the top-level mapitest structure
stepthe test step
namethe test name
retvalthe return value
See Also
mapitest_print_retval_step_fmt for a version providing an additional format string

References mapitest::color, and mapitest_print().

Referenced by mapitest_oxcprpt_CopyProps(), mapitest_oxcprpt_DeleteProps(), mapitest_oxcprpt_NoReplicate(), and mapitest_oxcstor_SetReceiveFolder().

void mapitest_print_retval_step_fmt ( struct mapitest mt,
char *  step,
char *  name,
const char *  format,
  ... 
)

Print mapitest return value for a given step with additional format string

Parameters
mtpointer to the top-level mapitest structure
stepthe test step
namethe test name
formatthe format string
...the format string parameters

References mapitest::color, and mapitest_print().

Referenced by mapitest_oxcprpt_CopyProps(), mapitest_oxcprpt_DeleteProps(), mapitest_oxcprpt_NoReplicate(), mapitest_oxcprpt_SetProps(), and mapitest_oxcstor_SetReceiveFolder().

void mapitest_print_SPropValue ( struct mapitest mt,
struct SPropValue  lpProp,
const char *  sep 
)

Output a row of the public address book.

Parameters
mtpointer to the top-level mapitest structure
lpPropthe property to print
sepa separator / spacer to insert in front of the label
Note
this is a simple wrapper for mapidump_SPropValue(), only for use in mapitest.

References mapitest::subunit_output.

Referenced by mapitest_oxomsg_TransportSend().

void mapitest_print_SRowSet ( struct mapitest mt,
struct SRowSet *  rowset,
const char *  sep 
)

Output a set of rows from a table.

Parameters
mtpointer to the top-level mapitest structure
rowsetthe rows to output
sepa separator / spacer to insert in front of the label
Note
this is a simple wrapper for mapidump_SRowSet(), only for use in mapitest.

References mapitest::subunit_output.

Referenced by mapitest_oxcmsg_OpenEmbeddedMessage(), and mapitest_oxcstor_GetReceiveFolderTable().

void mapitest_print_tab ( struct mapitest mt)

Print tabulations given the internal counter

Parameters
mtpointer to the top-level mapitest structure

Referenced by mapitest_print(), mapitest_print_module_title_end(), mapitest_print_module_title_start(), mapitest_print_test_result(), mapitest_print_test_title_end(), mapitest_print_test_title_start(), and mapitest_underline().

void mapitest_print_test_result ( struct mapitest mt,
char *  name,
bool  ret 
)

Print mapitest test result

Parameters
mtpointer to the top-level mapitest structure
namethe test name
retboolean value with the test result

References mapitest_print(), mapitest_print_line(), mapitest_print_newline(), mapitest_print_tab(), and mapitest::subunit_output.

void mapitest_print_test_title_end ( struct mapitest mt)

Write the content at the end of a test

Parameters
mtpointer to the top-level mapitest structure

References mapitest_deindent(), mapitest_print_line(), and mapitest_print_tab().

Referenced by mapitest_stat_dump().

void mapitest_print_test_title_start ( struct mapitest mt,
const char *  str 
)

print the test title

Parameters
mtpointer to the top-level mapitest structure
strthe test title

References mapitest_indent(), mapitest_print(), mapitest_print_line(), mapitest_print_tab(), mapitest::mem_ctx, and mapitest::subunit_output.

void mapitest_print_title ( struct mapitest mt,
const char *  str,
char  delim 
)

Private general routine used to print a title

Avoid code redundancy over the API

Parameters
mtpointer to the top-level mapitest structure
strthe title
delimthe underline delimiter

References mapitest_indent(), mapitest_underline(), and mapitest::subunit_output.

Referenced by mapitest_stat_dump().

void mapitest_underline ( struct mapitest mt,
const char *  str,
char  delim 
)

Underline a string

Parameters
mtpointer to the top-level mapitest structure
strstring to underline
delimthe line delimiter

References mapitest_print_line(), and mapitest_print_tab().

Referenced by mapitest_print_title().


Creative Commons License
Creative Commons Attribution icon Creative Commons Share Alike icon
This content is licensed under the Creative Commons
Attribution ShareAlike License v. 3.0:
http://creativecommons.org/licenses/by-sa/3.0/

openchange-2.0/apidocs/html/mapitest/mapitest__stat_8c.html000066400000000000000000000340071223057412600242040ustar00rootroot00000000000000 MAPITests 2.0 API Documentation
mapitest_stat.c File Reference

mapitest statistics functions More...

Functions

uint32_t mapitest_stat_add_result (struct mapitest_suite *suite, const char *name, enum TestResult testresult)
uint32_t mapitest_stat_add_skipped_test (struct mapitest_suite *suite, const char *name, enum TestApplicabilityFlags flags)
int32_t mapitest_stat_dump (struct mapitest *mt)
struct mapitest_statmapitest_stat_init (TALLOC_CTX *mem_ctx)

Detailed Description

mapitest statistics functions

mapitest records and prints the results of each test using these functions

Function Documentation

uint32_t mapitest_stat_add_result ( struct mapitest_suite suite,
const char *  name,
enum TestResult  testresult 
)

Add test result to the suite statistic parameter

Parameters
suitethe suite container
namethe test name
testresultthe test result
Returns
MAPITEST_SUCCESS on success, otherwise MAPITEST_ERROR

References mapitest_stat::enabled, ExpectedFailure, Fail, mapitest_stat::failure, mapitest_stat::failure_info, mapitest_unit::name, Pass, mapitest_unit::reason, mapitest_suite::stat, mapitest_stat::success, UnexpectedPass, and mapitest_stat::x_fail.

uint32_t mapitest_stat_add_skipped_test ( struct mapitest_suite suite,
const char *  name,
enum TestApplicabilityFlags  flags 
)

Add a skipped test to the suite statistic parameters

Parameters
suitethe suite container
namethe test name
flagsflags to indicate the reason why the test was skipped
Returns
MAPITEST_SUCCESS on success, otherwise MAPITEST_ERROR

References mapitest_stat::enabled, mapitest_unit::name, mapitest_stat::skip_info, mapitest_stat::skipped, and mapitest_suite::stat.

int32_t mapitest_stat_dump ( struct mapitest mt)
struct mapitest_stat* mapitest_stat_init ( TALLOC_CTX *  mem_ctx)
read

Initialize the mapitest statistic structure

Parameters
mem_ctxmemory allocation context
Returns
Allocated stat structure on success, otherwise NULL

References mapitest_stat::enabled, mapitest_stat::failure, mapitest_stat::failure_info, mapitest_stat::skip_info, mapitest_stat::skipped, mapitest_stat::success, and mapitest_stat::x_fail.

Referenced by mapitest_suite_init().


Creative Commons License
Creative Commons Attribution icon Creative Commons Share Alike icon
This content is licensed under the Creative Commons
Attribution ShareAlike License v. 3.0:
http://creativecommons.org/licenses/by-sa/3.0/

openchange-2.0/apidocs/html/mapitest/mapitest__suite_8c.html000066400000000000000000000603561223057412600243700ustar00rootroot00000000000000 MAPITests 2.0 API Documentation
mapitest_suite.c File Reference

mapitest test suite functions More...

Functions

void mapitest_run_all (struct mapitest *mt)
bool mapitest_run_test (struct mapitest *mt, const char *name)
uint32_t mapitest_suite_add_test (struct mapitest_suite *suite, const char *name, const char *description, bool(*run)(struct mapitest *test))
uint32_t mapitest_suite_add_test_flagged (struct mapitest_suite *suite, const char *name, const char *description, bool(*run)(struct mapitest *test), enum TestApplicabilityFlags applicability)
struct mapitest_suitemapitest_suite_find (struct mapitest *mt, const char *name)
struct mapitest_suitemapitest_suite_init (struct mapitest *mt, const char *name, const char *description, bool online)
uint32_t mapitest_suite_register (struct mapitest *mt, struct mapitest_suite *suite)
bool mapitest_suite_run_test (struct mapitest *mt, struct mapitest_suite *suite, const char *name)

Detailed Description

mapitest test suite functions

Function Documentation

void mapitest_run_all ( struct mapitest mt)

all tests from all suites

Parameters
mtthe top-level mapitest structure
Returns
true on success, otherwise -1

References mapitest::mapi_suite, mapitest_print_module_title_end(), mapitest_print_module_title_start(), mapitest_suite::name, mapitest_suite::next, mapitest_suite::online, and mapitest::online.

Referenced by main().

bool mapitest_run_test ( struct mapitest mt,
const char *  name 
)

run a specific test from a particular suite

Parameters
mtthe top-level mapitest structure
namethe mapitest test name
Returns
true on success, otherwise -1

References mapitest::mapi_suite, mapitest_suite_run_test(), mapitest_test::name, mapitest_test::next, mapitest_suite::next, mapitest_suite::online, mapitest::online, and mapitest_suite::tests.

Referenced by main().

uint32_t mapitest_suite_add_test ( struct mapitest_suite suite,
const char *  name,
const char *  description,
bool(*)(struct mapitest *test)  run 
)

add a test to the mapitest suite with description

Parameters
suitepointer on the parent suite
namethe test name
descriptionthe test description
runthe test function
Returns
MAPITEST_SUCCESS on success, otherwise MAPITEST_ERROR
See Also
mapitest_suite_init, mapitest_suite_register
mapitest_suite_add_test_flagged for an alternative function allowing the test to only be run under some conditions.

References ApplicableToAllVersions, and mapitest_suite_add_test_flagged().

uint32_t mapitest_suite_add_test_flagged ( struct mapitest_suite suite,
const char *  name,
const char *  description,
bool(*)(struct mapitest *test)  run,
enum TestApplicabilityFlags  applicability 
)

add a test to the mapitest suite with description and flags

This is very similar to mapitest_suite_add_test(), except it allows a test to have special applicability (e.g. to only run when a particular server configuration is available).

Parameters
suitepointer to the parent test suite
namethe test name
descriptionthe test description
runthe test function
applicabilitya set of applicability flags
Returns
MAPITEST_SUCCESS on success, otherwise MAPITEST_ERROR
See Also
mapitest_suite_init, mapitest_suite_register, mapitest_suite_add_test

References mapitest_test::description, mapitest_test::flags, mapitest_test::fn, mapitest_test::name, mapitest_suite::name, mapitest_test::next, and mapitest_suite::tests.

Referenced by mapitest_suite_add_test().

struct mapitest_suite* mapitest_suite_find ( struct mapitest mt,
const char *  name 
)
read

Find a suite given its name

Parameters
mttop-level mapitest structure
namethe suite name to be searched
Returns
Pointer on a suite on success, otherwise NULL

References mapitest::mapi_suite, mapitest_suite::name, and mapitest_suite::next.

struct mapitest_suite* mapitest_suite_init ( struct mapitest mt,
const char *  name,
const char *  description,
bool  online 
)
read

Initialize a mapitest suite

Parameters
mtthe top-level mapitest structure
namethe suite name
descriptionthe suite description
onlinewhether this suite requires online (server) access
Returns
An allocated mapitest_suite pointer, otherwise NULL.

References mapitest_suite::description, mapitest_stat_init(), mapitest::mem_ctx, mapitest_suite::name, mapitest_suite::online, mapitest_suite::stat, and mapitest_suite::tests.

uint32_t mapitest_suite_register ( struct mapitest mt,
struct mapitest_suite suite 
)

Register a mapitest suite

Parameters
mtthe top-level mapitest structure
suitethe mapitest suite we want to add
Returns
MAPITEST_SUCCESS on success, otherwise MAPITEST_ERROR
See Also
mapitest_suite_init

References mapitest::mapi_suite, mapitest::mem_ctx, mapitest_suite::name, and mapitest_suite::next.

bool mapitest_suite_run_test ( struct mapitest mt,
struct mapitest_suite suite,
const char *  name 
)

run a test from a suite given its name

Parameters
mtpointer on the top-level mapitest structure
suitepointer on the mapitest suite
namethe name of the test to be run
Returns
true on success, otherwise false

References mapitest_test::name, mapitest_test::next, and mapitest_suite::tests.

Referenced by mapitest_run_test().


Creative Commons License
Creative Commons Attribution icon Creative Commons Share Alike icon
This content is licensed under the Creative Commons
Attribution ShareAlike License v. 3.0:
http://creativecommons.org/licenses/by-sa/3.0/

openchange-2.0/apidocs/html/mapitest/middle_bg.jpg000066400000000000000000000005251223057412600223120ustar00rootroot00000000000000ÿØÿàJFIFddÿìDuckydÿîAdobedÀÿÛ„ÿÀdÿÄU Q¡Ña‘ÿÚ ?ßÀ#¿ªÚ0 ïæ¶œ ‡3Yû žñݲ ?ÿÙopenchange-2.0/apidocs/html/mapitest/module__errorchecks_8c.html000066400000000000000000000105701223057412600252010ustar00rootroot00000000000000 MAPITests 2.0 API Documentation
module_errorchecks.c File Reference

Error / sanity-check path tests. More...

Functions

bool mapitest_errorchecks_simplemapi_c (struct mapitest *mt)

Detailed Description

Error / sanity-check path tests.

Note
These tests do not show how to use libmapi properly, and should not be used as a programming reference.

Function Documentation

bool mapitest_errorchecks_simplemapi_c ( struct mapitest mt)

Verify simplemapi.c functions

This function:

  1. Tests the sanity checks in GetDefaultPublicFolder
  2. Tests the sanity checks in GetDefaultFolder
Parameters
mtpointer to the top-level mapitest structure
Returns
true on success, otherwise false

References mapitest_print().


Creative Commons License
Creative Commons Attribution icon Creative Commons Share Alike icon
This content is licensed under the Creative Commons
Attribution ShareAlike License v. 3.0:
http://creativecommons.org/licenses/by-sa/3.0/

openchange-2.0/apidocs/html/mapitest/module__lcid_8c.html000066400000000000000000000105111223057412600235750ustar00rootroot00000000000000 MAPITests 2.0 API Documentation
module_lcid.c File Reference

Language Code checks (MS-LCID) More...

Functions

bool mapitest_lcid_langcode2langtag (struct mapitest *mt)

Detailed Description

Language Code checks (MS-LCID)

Note
This is low level (internal) checking, and application programmers do not normally need to deal with the functions checked in this test suite.

Function Documentation

bool mapitest_lcid_langcode2langtag ( struct mapitest mt)

Verify libmapi/util/lcid.c functions

This function:

  1. exercises lcid_langcode2langtag()
Parameters
mtpointer to the top-level mapitest structure
Returns
true on success, otherwise false

References mapitest_print().


Creative Commons License
Creative Commons Attribution icon Creative Commons Share Alike icon
This content is licensed under the Creative Commons
Attribution ShareAlike License v. 3.0:
http://creativecommons.org/licenses/by-sa/3.0/

openchange-2.0/apidocs/html/mapitest/module__lzxpress_8c.html000066400000000000000000000054051223057412600245620ustar00rootroot00000000000000 MAPITests 2.0 API Documentation
module_lzxpress.c File Reference

LZXPRESS compression and decompression test suite. More...

#include "gen_ndr/ndr_exchange.h"
#include "libmapi/libmapi_private.h"

Detailed Description

LZXPRESS compression and decompression test suite.


Creative Commons License
Creative Commons Attribution icon Creative Commons Share Alike icon
This content is licensed under the Creative Commons
Attribution ShareAlike License v. 3.0:
http://creativecommons.org/licenses/by-sa/3.0/

openchange-2.0/apidocs/html/mapitest/module__mapidump_8c.html000066400000000000000000001076711223057412600245140ustar00rootroot00000000000000 MAPITests 2.0 API Documentation
module_mapidump.c File Reference

mapidump function tests More...

Functions

bool mapitest_mapidump_appointment (struct mapitest *mt)
bool mapitest_mapidump_contact (struct mapitest *mt)
bool mapitest_mapidump_foldercopied (struct mapitest *mt)
bool mapitest_mapidump_foldercreated (struct mapitest *mt)
bool mapitest_mapidump_folderdeleted (struct mapitest *mt)
bool mapitest_mapidump_foldermoved (struct mapitest *mt)
bool mapitest_mapidump_freebusy (struct mapitest *mt)
bool mapitest_mapidump_message (struct mapitest *mt)
bool mapitest_mapidump_messagecopied (struct mapitest *mt)
bool mapitest_mapidump_messagecreated (struct mapitest *mt)
bool mapitest_mapidump_messagedeleted (struct mapitest *mt)
bool mapitest_mapidump_messagemodified (struct mapitest *mt)
bool mapitest_mapidump_messagemoved (struct mapitest *mt)
bool mapitest_mapidump_newmail (struct mapitest *mt)
bool mapitest_mapidump_note (struct mapitest *mt)
bool mapitest_mapidump_pabentry (struct mapitest *mt)
bool mapitest_mapidump_recipients (struct mapitest *mt)
bool mapitest_mapidump_sproptagarray (struct mapitest *mt)
bool mapitest_mapidump_spropvalue (struct mapitest *mt)
bool mapitest_mapidump_srowset (struct mapitest *mt)
bool mapitest_mapidump_task (struct mapitest *mt)

Detailed Description

mapidump function tests

Note
These tests do not show how to use libmapi properly, and should not be used as a programming reference.

Function Documentation

bool mapitest_mapidump_appointment ( struct mapitest mt)

Test message dump using mapidump_appointment

This function:

  1. Tests the mapidump_appointment() function
Parameters
mtpointer to the top-level mapitest structure
Returns
true on success, otherwise false
Note
This currently doesn't check the results are sane, so manual inspection is required

References mapitest::mem_ctx.

bool mapitest_mapidump_contact ( struct mapitest mt)

Test dump using mapidump_contact

This function:

  1. Tests the mapidump_contact() function
Parameters
mtpointer to the top-level mapitest structure
Returns
true on success, otherwise false
Note
This currently doesn't check the results are sane, so manual inspection is required

References mapitest::mem_ctx.

bool mapitest_mapidump_foldercopied ( struct mapitest mt)

Test dump of a folder copy notification

This function:

  1. Creates a FolderMoveCopyNotification structure
  2. Dumps that structure out using mapidump_foldercopy()
  3. Tests mapidump_foldercopy() with a null argument
Parameters
mtpointer to the top-level mapitest structure
Returns
true on success, otherwise false
Note
This currently doesn't check the results are sane, so manual inspection is required
bool mapitest_mapidump_foldercreated ( struct mapitest mt)

Test dump of a Folder creation notification

This function:

  1. Creates a FolderCreatedNotification structure with a null tag set
  2. Dumps that structure out using mapidump_foldercreated()
  3. Adds a set of tags to the FolderCreatedNotification
  4. Dumps the modified FolderCreatedNotification structure using mapidump_foldercreated()
  5. Tests mapidump_foldercreated() with a null argument
Parameters
mtpointer to the top-level mapitest structure
Returns
true on success, otherwise false
Note
This currently doesn't check the results are sane, so manual inspection is required

References mapitest::mem_ctx.

bool mapitest_mapidump_folderdeleted ( struct mapitest mt)

Test dump of a Folder deletion notification

This function:

  1. Creates a FolderDeletedNotification structure
  2. Dumps that structure out using mapidump_folderdeleted()
  3. Tests mapidump_folderdeleted() with a null argument
Parameters
mtpointer to the top-level mapitest structure
Returns
true on success, otherwise false
Note
This currently doesn't check the results are sane, so manual inspection is required
bool mapitest_mapidump_foldermoved ( struct mapitest mt)

Test dump of a folder move notification

This function:

  1. Creates a FolderMoveCopyNotification structure
  2. Dumps that structure out using mapidump_foldermoved()
  3. Tests mapidump_foldermoved() with a null argument
Parameters
mtpointer to the top-level mapitest structure
Returns
true on success, otherwise false
Note
This currently doesn't check the results are sane, so manual inspection is required
bool mapitest_mapidump_freebusy ( struct mapitest mt)

Test dump of a free/busy event

This function:

  1. builds a freebusy binary event
  2. tests dumping it using mapidump_freebusy_event()
  3. modifies the event, and dumps it again
  4. modifies the event, and dumps it again
  5. tests dumping a date using mapidump_freebusy_date()
  6. tests each months for mapidump_freebusy_month()
Parameters
mtpointer to the top-level mapitest structure
Returns
true on success, otherwise false
Note
This currently doesn't check the results are sane, so manual inspection is required

References mapitest_print(), and mapitest::mem_ctx.

bool mapitest_mapidump_message ( struct mapitest mt)

Test dump of an email message using mapidump_message

This function:

  1. Builds an indicative email using mapi_SPropValues (sets no codepage)
  2. Calls the mapidump_appointment() function
Parameters
mtpointer to the top-level mapitest structure
Returns
true on success, otherwise false
Note
This currently doesn't check the results are sane, so manual inspection is required

References mapitest::mem_ctx.

bool mapitest_mapidump_messagecopied ( struct mapitest mt)

Test dump of a Message copied notification

This function:

  1. Creates a MessageCopiedNotification structure
  2. Dumps that structure out using mapidump_messagecopied()
  3. Tests mapidump_messagecopied() with a null argument
Parameters
mtpointer to the top-level mapitest structure
Returns
true on success, otherwise false
Note
This currently doesn't check the results are sane, so manual inspection is required
bool mapitest_mapidump_messagecreated ( struct mapitest mt)

Test dump of a Message creation notification

This function:

  1. Creates a MessageCreatedNotification structure
  2. Dumps that structure out using mapidump_messagecreated()
  3. Adds tags to the MessageCreatedNotification structure
  4. Dumps the structure again.
  5. Tests mapidump_messagecreated() with a null argument
Parameters
mtpointer to the top-level mapitest structure
Returns
true on success, otherwise false
Note
This currently doesn't check the results are sane, so manual inspection is required

References mapitest::mem_ctx.

bool mapitest_mapidump_messagedeleted ( struct mapitest mt)

Test dump of a Message deletion notification

This function:

  1. Creates a MessageDeletedNotification structure
  2. Dumps that structure out using mapidump_messagedeleted()
  3. Tests mapidump_messagedeleted() with a null argument
Parameters
mtpointer to the top-level mapitest structure
Returns
true on success, otherwise false
Note
This currently doesn't check the results are sane, so manual inspection is required
bool mapitest_mapidump_messagemodified ( struct mapitest mt)

Test dump of a Message modification notification

This function:

  1. Creates a MessageModifiedNotification structure
  2. Dumps that structure out using mapidump_messagemodified()
  3. Adds tags to the MessageModifiedNotification structure
  4. Dumps the structure again.
  5. Tests mapidump_messagemodified() with a null argument
Parameters
mtpointer to the top-level mapitest structure
Returns
true on success, otherwise false
Note
This currently doesn't check the results are sane, so manual inspection is required

References mapitest::mem_ctx.

bool mapitest_mapidump_messagemoved ( struct mapitest mt)

Test dump of a Message moved notification

This function:

  1. Creates a MessageMovedNotification structure
  2. Dumps that structure out using mapidump_messagemoved()
  3. Tests mapidump_messagemoved() with a null argument
Parameters
mtpointer to the top-level mapitest structure
Returns
true on success, otherwise false
Note
This currently doesn't check the results are sane, so manual inspection is required
bool mapitest_mapidump_newmail ( struct mapitest mt)

Test dump of an new mail notification

This function:

  1. Tests the mapidump_msgflags function with no bits set
  2. Tests the mapidump_msgflags function with one bit set
  3. Tests the mapidump_msgflags function with all bits set
  4. Builds an indicative new mail notification
  5. Calls the mapidump_newmail function to test dumping of that new mail notification
Parameters
mtpointer to the top-level mapitest structure
Returns
true on success, otherwise false
Note
This currently doesn't check the results are sane, so manual inspection is required
bool mapitest_mapidump_note ( struct mapitest mt)

Test dump using mapidump_note

This function:

  1. Tests the mapidump_note() function on a plain text message
  2. Tests the mapidump_note() function on a HTML message
Parameters
mtpointer to the top-level mapitest structure
Returns
true on success, otherwise false
Note
This currently doesn't check the results are sane, so manual inspection is required

References mapitest::mem_ctx.

bool mapitest_mapidump_pabentry ( struct mapitest mt)

Test dump using mapidump_pabentry

This function:

  1. Tests the mapidump_PAB_entry() function
Parameters
mtpointer to the top-level mapitest structure
Returns
true on success, otherwise false
Note
This currently doesn't check the results are sane, so manual inspection is required

References mapitest::mem_ctx.

bool mapitest_mapidump_recipients ( struct mapitest mt)

Test dump of a set of recipients

This function:

  1. builds a recipient list
  2. dumps out the recipient list using mapidump_Recipients()
Parameters
mtpointer to the top-level mapitest structure
Returns
true on success, otherwise false
Note
This currently doesn't check the results are sane, so manual inspection is required

References mapitest::mem_ctx.

bool mapitest_mapidump_sproptagarray ( struct mapitest mt)

Test dump using mapidump_SPropTagArray

This function:

  1. Tests the mapidump_SPropTagArray() function
Parameters
mtpointer to the top-level mapitest structure
Returns
true on success, otherwise false
Note
This currently doesn't check the results are sane, so manual inspection is required

References mapitest::mem_ctx.

bool mapitest_mapidump_spropvalue ( struct mapitest mt)

Test dump using mapidump_SPropValue

This function:

  1. Tests the mapidump_SPropValue() function
Parameters
mtpointer to the top-level mapitest structure
Returns
true on success, otherwise false
Note
This currently doesn't check the results are sane, so manual inspection is required

References mapitest::mem_ctx.

bool mapitest_mapidump_srowset ( struct mapitest mt)

Test dump using mapidump_SRowSet

This function:

  1. Tests the mapidump_SRowSet() function
  2. Indirectly tests the mapidump_SRow() function
Parameters
mtpointer to the top-level mapitest structure
Returns
true on success, otherwise false
Note
This currently doesn't check the results are sane, so manual inspection is required

References mapitest::mem_ctx.

bool mapitest_mapidump_task ( struct mapitest mt)

Test dump using mapidump_task

This function:

  1. Tests the mapidump_task() function
  2. modifies the task to be completed
  3. Tests the associated get_importance() function
  4. Tests the associated get_task_status() function
Parameters
mtpointer to the top-level mapitest structure
Returns
true on success, otherwise false
Note
This currently doesn't check the results are sane, so manual inspection is required

References mapitest_print(), and mapitest::mem_ctx.


Creative Commons License
Creative Commons Attribution icon Creative Commons Share Alike icon
This content is licensed under the Creative Commons
Attribution ShareAlike License v. 3.0:
http://creativecommons.org/licenses/by-sa/3.0/

openchange-2.0/apidocs/html/mapitest/module__noserver_8c.html000066400000000000000000000324151223057412600245340ustar00rootroot00000000000000 MAPITests 2.0 API Documentation
module_noserver.c File Reference

Non connection oriented tests. More...

Functions

bool mapitest_noserver_lzfu (struct mapitest *mt)
bool mapitest_noserver_mapi_properties (struct mapitest *mt)
bool mapitest_noserver_properties (struct mapitest *mt)
bool mapitest_noserver_proptagvalue (struct mapitest *mt)
bool mapitest_noserver_rtfcp (struct mapitest *mt)
bool mapitest_noserver_rtfcp_large (struct mapitest *mt)
bool mapitest_noserver_srowset (struct mapitest *mt)

Detailed Description

Non connection oriented tests.

Function Documentation

bool mapitest_noserver_lzfu ( struct mapitest mt)

Test the Compressed RTF decompression routine.

This function:

  1. Loads some test data and checks it
  2. Decompresses the test data
  3. Checks that the decompressed data matches the expected result
Parameters
mtpointer on the top-level mapitest structure
Returns
true on success, otherwise false

References mapitest_print(), mapitest_print_retval(), and mapitest::mem_ctx.

bool mapitest_noserver_mapi_properties ( struct mapitest mt)

Test the mapi_SPropValue_array handling

This function:

  1. Builds a mapi_SPropValue_array
  2. Checks that appropriate values can be retrieved
Parameters
mtpointer on the top-level mapitest structure
Returns
true on success, otherwise false

References mapitest_print(), and mapitest::mem_ctx.

bool mapitest_noserver_properties ( struct mapitest mt)

Test the property setter / getter code

This function:

  1. Checks setting / getting on an SPropValue
Parameters
mtpointer on the top-level mapitest structure
Returns
true on success, otherwise false
bool mapitest_noserver_proptagvalue ( struct mapitest mt)

Test the get_proptag_value() function

This function:

  1. Checks the first value in the list
  2. Checks a random value from the list
  3. Checks the last value in the list
  4. Checks a value that doesn't exist
Parameters
mtpointer on the top-level mapitest structure
Returns
true on success, otherwise false

References mapitest_print().

bool mapitest_noserver_rtfcp ( struct mapitest mt)

Test the Compressed RTF compression routine.

This function:

  1. Loads some test data and checks it
  2. Compresses the test data
  3. Checks that the compressed data matches the expected result
Parameters
mtpointer to the top-level mapitest structure
Returns
true on success, otherwise false

References mapitest_print(), mapitest_print_retval(), and mapitest::mem_ctx.

bool mapitest_noserver_rtfcp_large ( struct mapitest mt)

Test the Compressed RTF compression / decompression routines on a larger file

Parameters
mtpointer to the top-level mapitest structure
Returns
true on success, otherwise false

References mapitest_print(), mapitest_print_retval_clean(), and mapitest::mem_ctx.

bool mapitest_noserver_srowset ( struct mapitest mt)

Test the SRowSet parsing / assembly code

This function:

  1. Loads some test data and checks it
  2. Parses the test data
  3. Checks that the parsed data matches the expected result
Parameters
mtpointer on the top-level mapitest structure
Returns
true on success, otherwise false

References mapitest_print().


Creative Commons License
Creative Commons Attribution icon Creative Commons Share Alike icon
This content is licensed under the Creative Commons
Attribution ShareAlike License v. 3.0:
http://creativecommons.org/licenses/by-sa/3.0/

openchange-2.0/apidocs/html/mapitest/module__nspi_8c.html000066400000000000000000000671401223057412600236450ustar00rootroot00000000000000 MAPITests 2.0 API Documentation
module_nspi.c File Reference

NSPI tests. More...

Functions

bool mapitest_nspi_CompareMIds (struct mapitest *mt)
bool mapitest_nspi_DNToMId (struct mapitest *mt)
bool mapitest_nspi_GetGALTable (struct mapitest *mt)
bool mapitest_nspi_GetIDsFromNames (struct mapitest *mt)
bool mapitest_nspi_GetMatches (struct mapitest *mt)
bool mapitest_nspi_GetNamesFromIDs (struct mapitest *mt)
bool mapitest_nspi_GetPropList (struct mapitest *mt)
bool mapitest_nspi_GetProps (struct mapitest *mt)
bool mapitest_nspi_GetSpecialTable (struct mapitest *mt)
bool mapitest_nspi_GetTemplateInfo (struct mapitest *mt)
bool mapitest_nspi_ModLinkAtt (struct mapitest *mt)
bool mapitest_nspi_ModProps (struct mapitest *mt)
bool mapitest_nspi_QueryColumns (struct mapitest *mt)
bool mapitest_nspi_QueryRows (struct mapitest *mt)
bool mapitest_nspi_ResolveNames (struct mapitest *mt)
bool mapitest_nspi_ResortRestriction (struct mapitest *mt)
bool mapitest_nspi_SeekEntries (struct mapitest *mt)
bool mapitest_nspi_UpdateStat (struct mapitest *mt)

Detailed Description

NSPI tests.

Function Documentation

bool mapitest_nspi_CompareMIds ( struct mapitest mt)

Test the NspiCompareMIds RPC operation (0x0a)

Parameters
mtpointer to the top-level mapitest structure
Returns
true on success, otherwise false

References mapitest_print(), and mapitest_print_retval_clean().

bool mapitest_nspi_DNToMId ( struct mapitest mt)

Test the NspiDNToMId RPC operation (0x7)

Parameters
mtpointer on the top-level mapitest structure
Returns
true on success, otherwise false

References mapitest::mapi_ctx, and mapitest_print_retval_clean().

bool mapitest_nspi_GetGALTable ( struct mapitest mt)

Test the GetGALTable function

Parameters
mtpointer to the top-level mapitest structure
Returns
true on success, otherwise false

References mapitest_print_PAB_entry(), mapitest_print_retval_clean(), and mapitest::mem_ctx.

bool mapitest_nspi_GetIDsFromNames ( struct mapitest mt)

Test the NspiGetIDsFromNames RPC operation (0x12)

Parameters
mtpointer on the top-level mapitest structure
Returns
true on success, otherwise false

References mapitest_print_retval_clean().

bool mapitest_nspi_GetMatches ( struct mapitest mt)

Test the NspiGetMatches RPC operation (0x5)

Parameters
mtpointer on the top-level mapitest structure
Returns
true on success, otherwise false

References mapitest::mapi_ctx, and mapitest_print_retval_clean().

bool mapitest_nspi_GetNamesFromIDs ( struct mapitest mt)

Test the NspiGetNamesFromIDs RPC operation (0x11)

Parameters
mtpointer on the top-level mapitest structure
Returns
true on success, otherwise false

References mapitest_print_retval_clean().

bool mapitest_nspi_GetPropList ( struct mapitest mt)

Test the NspiGetPropList RPC operation (0x08)

Parameters
mtpointer on the top-level mapitest structure
Returns
true on success, otherwise false

References mapitest::mapi_ctx, mapitest_print(), mapitest_print_retval(), and mapitest::mem_ctx.

bool mapitest_nspi_GetProps ( struct mapitest mt)

Test the NspiGetProps RPC operation (0x09)

Parameters
mtpointer to the top-level mapitest structure
Returns
true on success, otherwise false

References mapitest::mapi_ctx, mapitest_print_retval(), and mapitest_print_retval_clean().

bool mapitest_nspi_GetSpecialTable ( struct mapitest mt)

Test the NspiGetSpecialTable RPC operation (0x0c)

Parameters
mtpointer on the top-level mapitest structure
Returns
true on success, otherwise false

References mapitest_print_retval_clean(), and mapitest::mem_ctx.

bool mapitest_nspi_GetTemplateInfo ( struct mapitest mt)

Test the NspiGetTemplateInfo RPC operation (0x0d)

Parameters
mtpointer on the top-level mapitest structure
Returns
true on success, otherwise false

References mapitest_print_retval_clean().

bool mapitest_nspi_ModLinkAtt ( struct mapitest mt)

Test the NspiModLinkAtt RPC operation (0x0e)

Parameters
mtpointer on the top-level mapitest structure
Returns
true on success, otherwise false

References mapitest_print_retval_clean(), and mapitest::mem_ctx.

bool mapitest_nspi_ModProps ( struct mapitest mt)

Test the NspiModProps RPC operation (0xb)

Parameters
mtpointer on the top-level mapitest structure
Returns
true on success, otherwise false

References mapitest::mapi_ctx, mapitest_print(), and mapitest_print_retval_clean().

bool mapitest_nspi_QueryColumns ( struct mapitest mt)

Test the NspiQueryColumns RPC operation (0x10)

Parameters
mtpointer on the top-level mapitest structure
Returns
true on success, otherwise false

References mapitest_print(), and mapitest_print_retval_clean().

bool mapitest_nspi_QueryRows ( struct mapitest mt)

Test the NspiQueryRows RPC operation (0x3)

Parameters
mtpointer on the top-level mapitest structure
Returns
true on success, otherwise false

References mapitest::mapi_ctx, and mapitest_print_retval_clean().

bool mapitest_nspi_ResolveNames ( struct mapitest mt)

Test the NspiResolveNames and NspiResolveNamesW RPC operations (0x13 and 0x14)

Parameters
mtpointer on the top-level mapitest structure
Returns
true on success, otherwise false

References mapitest_print(), mapitest_print_retval_clean(), and mapitest::mem_ctx.

bool mapitest_nspi_ResortRestriction ( struct mapitest mt)

Test the NspiResortRestriction RPC operation (0x6)

Parameters
mtpointer on the top-level mapitest structure
Returns
true on success, otherwise false

References mapitest_print_retval_clean().

bool mapitest_nspi_SeekEntries ( struct mapitest mt)

Test the NspiSeekEntries RPC operation (0x04)

Parameters
mtpointer on the top-level mapitest structure
Returns
true on success, otherwise false

References mapitest_print_retval_clean().

bool mapitest_nspi_UpdateStat ( struct mapitest mt)

Test the NspiUpdateStat RPC operation (0x02)

Parameters
mtpointer on the top-level mapitest structure
Returns
true on success, otherwise false

References mapitest_print(), and mapitest_print_retval().


Creative Commons License
Creative Commons Attribution icon Creative Commons Share Alike icon
This content is licensed under the Creative Commons
Attribution ShareAlike License v. 3.0:
http://creativecommons.org/licenses/by-sa/3.0/

openchange-2.0/apidocs/html/mapitest/module__oxcfold_8c.html000066400000000000000000000707041223057412600243320ustar00rootroot00000000000000 MAPITests 2.0 API Documentation
module_oxcfold.c File Reference

Folder Object Protocol test suite. More...

Functions

bool mapitest_oxcfold_CopyFolder (struct mapitest *mt)
bool mapitest_oxcfold_CreateDeleteFolder (struct mapitest *mt)
bool mapitest_oxcfold_CreateFolder (struct mapitest *mt)
bool mapitest_oxcfold_CreateFolderVariants (struct mapitest *mt)
bool mapitest_oxcfold_DeleteMessages (struct mapitest *mt)
bool mapitest_oxcfold_GetContentsTable (struct mapitest *mt)
bool mapitest_oxcfold_GetHierarchyTable (struct mapitest *mt)
bool mapitest_oxcfold_GetSearchCriteria (struct mapitest *mt)
bool mapitest_oxcfold_HardDeleteMessages (struct mapitest *mt)
bool mapitest_oxcfold_HardDeleteMessagesAndSubfolders (struct mapitest *mt)
bool mapitest_oxcfold_MoveCopyMessages (struct mapitest *mt)
bool mapitest_oxcfold_MoveFolder (struct mapitest *mt)
bool mapitest_oxcfold_OpenFolder (struct mapitest *mt)
bool mapitest_oxcfold_SetSearchCriteria (struct mapitest *mt)

Detailed Description

Folder Object Protocol test suite.

Function Documentation

bool mapitest_oxcfold_CopyFolder ( struct mapitest mt)

Test the CopyFolder (0x36) operation.

This function:

  1. Log on the user private mailbox
  2. Open the Inbox folder (source)
  3. Create a temporary folder
  4. Create a subdirectory
  5. Open the Deleted Items folder (destination)
  6. Copy the temporary folder from Inbox to DeletedItems
  7. Empty and delete the original and copied folder
Parameters
mtpointer on the top-level mapitest structure
Returns
true on success, otherwise false

References mapitest_common_find_folder(), mapitest_common_folder_open(), mapitest_print(), and mapitest_print_retval().

bool mapitest_oxcfold_CreateDeleteFolder ( struct mapitest mt)

Test the CreateFolder (0x1c) and DeleteFolder (0x1d) operations

This is a simpler version of the CreateFolder test below.

This function:

  1. Log on the user private mailbox
  2. Open the top information folder
  3. Create a test directory
  4. Delete the folder
Parameters
mtthe top-level mapitest structure
Returns
true on success, otherwise false

References mapitest_print(), and mapitest_print_retval().

bool mapitest_oxcfold_CreateFolder ( struct mapitest mt)

Test the CreateFolder (0x1c) operation

This function:

  1. Log on the user private mailbox
  2. Open the top information folder
  3. Create a test directory
  4. Create sub directories with different container classes
  5. Empty the folder
  6. Delete the folder
Parameters
mtthe top-level mapitest structure
Returns
true on success, otherwise false

References mapitest_deindent(), mapitest_indent(), mapitest_print(), mapitest_print_retval(), and mapitest_print_retval_fmt().

bool mapitest_oxcfold_CreateFolderVariants ( struct mapitest mt)

Test the CreateFolder (0x1c) operations

This tests different combinations of folder creation.

This function:

  1. Log on the user private mailbox
  2. Open the top information folder
  3. Create a test directory (or open the directory if it already exists)
  4. Delete the test directory
  5. Create the test directory again (it should not exist)
  6. Try to create another directory with the same name (should error out)
  7. Try to create another directory with the same name, but use open if exists
  8. Create a generic subfolder
  9. Try to create another generic subfolder with the same name (should error out)
  10. Try to create another generic subfolder with the same name, but use open if exists
  11. Delete the generic subfolder
  12. Delete the test directory
    Parameters
    mtthe top-level mapitest structure
    Returns
    true on success, otherwise false

References mapitest_print(), and mapitest_print_retval_clean().

bool mapitest_oxcfold_DeleteMessages ( struct mapitest mt)

Test the DeleteMessages (0x1e) operation

This function:

  1. Log on the user private mailbox
  2. Open the top of information store
  3. Create a test folder
  4. Create and save three messages
  5. Save the messages
  6. Delete the messages
  7. Delete the test folder
Parameters
mtpointer on the top-level mapitest structure
Returns
true on success, otherwise false

References mapitest_print(), and mapitest_print_retval_clean().

bool mapitest_oxcfold_GetContentsTable ( struct mapitest mt)

Test the GetContentsTable (0x5) operation

This function:

  1. Log on the user private mailbox
  2. Open the top information folder
  3. Call the GetContentsTable operation
Parameters
mtpointer on the top-level mapitest structure
Returns
true on success, otherwise false

References mapitest_print_retval(), and mapitest_print_retval_fmt().

bool mapitest_oxcfold_GetHierarchyTable ( struct mapitest mt)

Test the GetHierarchyTable (0x4) operation

This function:

  1. Log on the user private mailbox
  2. Open the top information folder
  3. Call the GetHierarchyTable operation
Parameters
mtpointer on the top-level mapitest structure
Returns
true on success, otherwise false

References mapitest_print_retval(), and mapitest_print_retval_fmt().

bool mapitest_oxcfold_GetSearchCriteria ( struct mapitest mt)

Test the GetSearchCriteria (0x31) operation

This function:

  1. Log on the user private mailbox
  2. Retrieve the inbox folder ID
  3. Open the default search folder
  4. Create a search folder within this folder
  5. Set the message class property on this container
  6. Set a restriction criteria
  7. Call SetSearchCriteria
  8. Call GetSearchCriteria
  9. Delete the test search folder
Parameters
mtpointer on the top-level mapitest structure
Returns
true on success, otherwise false

References mapitest::mapi_ctx, and mapitest_print_retval().

bool mapitest_oxcfold_HardDeleteMessages ( struct mapitest mt)

Test the HardDeleteMessages (0x91) operation.

This function:

  1. Log on the user private mailbox
  2. Open the Inbox folder (source)
  3. Creates 3 sample messages
  4. Hard delete the sample messages
Parameters
mtpointer to the top-level mapitest structure
Returns
true on success, otherwise false

References mapitest::mapi_ctx, mapitest_common_message_create(), mapitest_print(), mapitest_print_retval(), and mapitest::mem_ctx.

bool mapitest_oxcfold_HardDeleteMessagesAndSubfolders ( struct mapitest mt)

Test the HardDeleteMessagesAndSubfolder (0x92) operation.

This function:

  1. Creates a filled test folder
  2. Creates 2 subdirectories in the test folder
  3. Hard deletes the sample messages and subdirectories
Parameters
mtpointer to the top-level mapitest structure
Returns
true on success, otherwise false

References mapitest_common_cleanup(), mapitest_common_setup(), mapitest_print(), and mapitest_print_retval().

bool mapitest_oxcfold_MoveCopyMessages ( struct mapitest mt)

Test the MoveCopyMessages (0x33) operation.

This function:

  1. Log on the user private mailbox
  2. Open the Inbox folder (source)
  3. Open the Deleted Items folder (destination)
  4. Creates 3 sample messages
  5. Move messages from source to destination
Parameters
mtpointer on the top-level mapitest structure
Returns
true on success, otherwise false

References mapitest::mapi_ctx, mapitest_common_message_create(), mapitest_print(), mapitest_print_retval(), and mapitest::mem_ctx.

bool mapitest_oxcfold_MoveFolder ( struct mapitest mt)

Test the MoveFolder (0x35) operation.

This function:

  1. Log on the user private mailbox
  2. Open the Inbox folder (source)
  3. Create a temporary folder
  4. Create 1 message in this new folder
  5. Open the Deleted Items folder (destination)
  6. Move the temporary folder from Inbox to DeletedItems
  7. Empty and delete the moved temporary folder
Parameters
mtpointer on the top-level mapitest structure
Returns
true on success, otherwise false

References mapitest_common_find_folder(), mapitest_common_folder_open(), mapitest_common_message_create(), mapitest_print(), and mapitest_print_retval().

bool mapitest_oxcfold_OpenFolder ( struct mapitest mt)

Test the OpenFolder (0x2) operation

This function:

  1. Log on the user private mailbox
  2. Open folders located within the top information store folder
  3. Open folders located within the Inbox folder
Parameters
mtthe top-level mapitest structure
Returns
true on success, otherwise false

References mapitest_deindent(), mapitest_indent(), mapitest_print(), mapitest_print_retval(), and mapitest_print_retval_fmt().

bool mapitest_oxcfold_SetSearchCriteria ( struct mapitest mt)

Test the SetSearchCriteria (0x30) operation

This function:

  1. Log on the user private mailbox
  2. Retrieve the inbox folder ID
  3. Open the default search folder
  4. Create a search folder within this folder
  5. Set the message class property on this container
  6. Set a restriction criteria
  7. Call SetSearchCriteria
  8. Delete the test search folder
Parameters
mtpointer on the top-level mapitest structure
Returns
true on success, otherwise false

References mapitest::mapi_ctx, and mapitest_print_retval().


Creative Commons License
Creative Commons Attribution icon Creative Commons Share Alike icon
This content is licensed under the Creative Commons
Attribution ShareAlike License v. 3.0:
http://creativecommons.org/licenses/by-sa/3.0/

openchange-2.0/apidocs/html/mapitest/module__oxcfxics_8c.html000066400000000000000000000425551223057412600245250ustar00rootroot00000000000000 MAPITests 2.0 API Documentation
module_oxcfxics.c File Reference

Bulk Data Transfer Protocol test suite. More...

Functions

bool mapitest_oxcfxics_CopyFolder (struct mapitest *mt)
bool mapitest_oxcfxics_CopyMessages (struct mapitest *mt)
bool mapitest_oxcfxics_CopyProperties (struct mapitest *mt)
bool mapitest_oxcfxics_CopyTo (struct mapitest *mt)
bool mapitest_oxcfxics_DestConfigure (struct mapitest *mt)
bool mapitest_oxcfxics_GetLocalReplicaIds (struct mapitest *mt)
bool mapitest_oxcfxics_SetLocalReplicaMidsetDeleted (struct mapitest *mt)
bool mapitest_oxcfxics_SyncConfigure (struct mapitest *mt)
bool mapitest_oxcfxics_SyncOpenCollector (struct mapitest *mt)

Detailed Description

Bulk Data Transfer Protocol test suite.

Function Documentation

bool mapitest_oxcfxics_CopyFolder ( struct mapitest mt)

Test the FastTransferCopyFolder (0x4C), FastTransferGetBuffer (0x4E) and TellVersion (0x86) operations

This function:

  1. Log on private message store
  2. Creates a test folder
  3. Setup source
  4. Sends the "server version"

References mapitest_common_cleanup(), mapitest_common_setup(), mapitest_print(), mapitest_print_retval_clean(), and mapitest::mem_ctx.

bool mapitest_oxcfxics_CopyMessages ( struct mapitest mt)

Test the FastTransferCopyMessages (0x4B) and FastTransferGetBuffer (0x4E) operations

This function:

  1. Log on private message store
  2. Cremapidump_fx_bufferates a test folder
  3. Setup source
  4. Get data

References mapitest::mapi_ctx, mapitest_common_cleanup(), mapitest_common_setup(), mapitest_print(), mapitest_print_retval_clean(), and mapitest::mem_ctx.

bool mapitest_oxcfxics_CopyProperties ( struct mapitest mt)

Test the FastTransferCopyProperties (0x69) and FastTransferSourceGetBuffer (0x4e) operations

This function:

  1. Log on private message store
  2. Creates a test folder
  3. Setup source
  4. Get data

References mapitest_common_cleanup(), mapitest_common_setup(), mapitest_print(), mapitest_print_retval_clean(), and mapitest::mem_ctx.

bool mapitest_oxcfxics_CopyTo ( struct mapitest mt)

Test the FastTransferCopyTo (0x4D) and FastTransferGetBuffer (0x4E) operations

This function:

  1. Log on private message store
  2. Creates a test folder
  3. Setup source
  4. Get data

References mapitest::mapi_ctx, mapitest_common_cleanup(), mapitest_common_setup(), mapitest_print(), mapitest_print_retval_clean(), and mapitest::mem_ctx.

bool mapitest_oxcfxics_DestConfigure ( struct mapitest mt)

Test the FastTransferDestinationConfigure (0x53), TellVersion (0x86) and FastTransferDestinationPutBuffer (0x54) operations

This function:

  1. Log on private message store
  2. Creates a test folder
  3. Setup destination
  4. Sends the "server version"

References mapitest_common_cleanup(), mapitest_common_setup(), mapitest_print(), and mapitest_print_retval_clean().

bool mapitest_oxcfxics_GetLocalReplicaIds ( struct mapitest mt)

Test the GetLocalReplicaIds (0x7f) operation

This function:

  1. Log on private message store
  2. Reserve a range of Ids

References mapitest_print(), mapitest_print_retval(), and mapitest::mem_ctx.

bool mapitest_oxcfxics_SetLocalReplicaMidsetDeleted ( struct mapitest mt)

Test the GetLocalReplicaId (0x7f) and SetLocalReplicaMidsetDeleted (0x93) operations

This function:

  1. Log on private message store
  2. Creates a test folder
  3. Gets a local replica ID range
  4. Sets the local replica ID range as deleted (on the test folder)
  5. cleans up

References mapitest_common_cleanup(), mapitest_common_setup(), mapitest_print(), mapitest_print_retval_clean(), and mapitest::mem_ctx.

bool mapitest_oxcfxics_SyncConfigure ( struct mapitest mt)

Test the RopSynchronizationConfigure (0x70), RopSynchronizationUploadStateStreamBegin (0x75), RopSynchronizationUploadStateStreamContinue (0x76), RopSynchronizationUploadStateStreamEnd (0x77) and RopSynchronizationGetTransferState (0x82) operations

This function:

  1. Log on private message store
  2. Creates a test folder
  3. Sets up sync configure context
  4. Uploads an empty ICS state
  5. cleans up.

References mapitest_common_cleanup(), mapitest_common_setup(), mapitest_print_retval_clean(), and mapitest::mem_ctx.

bool mapitest_oxcfxics_SyncOpenCollector ( struct mapitest mt)

Test the RopSynchronizationOpenCollector (0x7e), operation.

This function:

  1. Log on private message store
  2. Creates a test folder
  3. Opens a sync collector context for content
  4. Opens a sync collector context for hierachy
  5. cleans up.

References mapitest_common_cleanup(), mapitest_common_setup(), and mapitest_print_retval_clean().


Creative Commons License
Creative Commons Attribution icon Creative Commons Share Alike icon
This content is licensed under the Creative Commons
Attribution ShareAlike License v. 3.0:
http://creativecommons.org/licenses/by-sa/3.0/

openchange-2.0/apidocs/html/mapitest/module__oxcmsg_8c.html000066400000000000000000000622261223057412600241740ustar00rootroot00000000000000 MAPITests 2.0 API Documentation
module_oxcmsg.c File Reference

Message and Attachment Object Protocol test suite. More...

Functions

bool mapitest_oxcmsg_CreateMessage (struct mapitest *mt)
bool mapitest_oxcmsg_GetMessageStatus (struct mapitest *mt)
bool mapitest_oxcmsg_GetValidAttachments (struct mapitest *mt)
bool mapitest_oxcmsg_ModifyRecipients (struct mapitest *mt)
bool mapitest_oxcmsg_OpenEmbeddedMessage (struct mapitest *mt)
bool mapitest_oxcmsg_ReadRecipients (struct mapitest *mt)
bool mapitest_oxcmsg_ReloadCachedInformation (struct mapitest *mt)
bool mapitest_oxcmsg_RemoveAllRecipients (struct mapitest *mt)
bool mapitest_oxcmsg_SaveChangesMessage (struct mapitest *mt)
bool mapitest_oxcmsg_SetMessageReadFlag (struct mapitest *mt)
bool mapitest_oxcmsg_SetMessageStatus (struct mapitest *mt)
bool mapitest_oxcmsg_SetReadFlags (struct mapitest *mt)

Detailed Description

Message and Attachment Object Protocol test suite.

Function Documentation

bool mapitest_oxcmsg_CreateMessage ( struct mapitest mt)

Test the CreateMessage (0x6) operation

This function:

  1. Log on the user private mailbox
  2. Open the Outbox folder
  3. Create the message
  4. Delete the message
Parameters
mtpointer on the top-level mapitest structure
Returns
true on success, otherwise false

References mapitest_common_folder_open(), and mapitest_print_retval().

bool mapitest_oxcmsg_GetMessageStatus ( struct mapitest mt)

Test the GetMessageStatus (0x1f) operation

This function:

  1. Log on the user private mailbox
  2. Open the outbox folder
  3. Create the message
  4. Save the message
  5. Get outbox contents table
  6. Get messages status
  7. Delete the message
Parameters
mtpointer on the top-level mapitest structure
Returns
true on success, otherwise false

References mapitest_print_retval_clean(), and mapitest::mem_ctx.

bool mapitest_oxcmsg_GetValidAttachments ( struct mapitest mt)

Test the GetValidAttachments (0x52) and CreateAttach (0x23) operations

This function:

  1. Logs on the user private mailbox
  2. Open the Inbox folder
  3. Create a test message
  4. Check the number of valid attachments is zero
  5. Create two attachments
  6. Check the number of valid attachments is two (numbered 0 and 1)
  7. Delete the first attachment
  8. Check the number of valid attachments is one (numbered 1)
  9. Delete the test message
Parameters
mtpointer to the top-level mapitest structure
Returns
true on success, otherwise false

References mapitest_common_folder_open(), mapitest_common_message_create(), mapitest_print(), mapitest_print_retval_clean(), and mapitest_print_retval_fmt_clean().

bool mapitest_oxcmsg_ModifyRecipients ( struct mapitest mt)

Test the ModifyRecipients (0xe) operation

This function:

  1. Log on the user private mailbox
  2. Open the Outbox folder
  3. Create the message
  4. Resolve recipients names
  5. Call ModifyRecipients operation for MAPI_TO, MAPI_CC, MAPI_BCC
  6. Delete the message
Parameters
mtpointer on the top-level mapitest structure
Returns
true on success, otherwise false

References mapitest_print(), mapitest_print_retval(), mapitest_print_retval_clean(), mapitest_print_retval_fmt(), and mapitest::mem_ctx.

bool mapitest_oxcmsg_OpenEmbeddedMessage ( struct mapitest mt)

Test the OpenEmbeddedMessage (0x46) and CreateAttach (0x23) operations

This function:

  1. Logs on the user private mailbox
  2. Open the Inbox folder
  3. Create a test message
  4. Embed a message in the test message
  5. Delete the test message
Parameters
mtpointer to the top-level mapitest structure
Returns
true on success, otherwise false

References mapitest_common_folder_open(), mapitest_common_message_create(), mapitest_common_message_fill(), mapitest_print(), and mapitest_print_SRowSet().

bool mapitest_oxcmsg_ReadRecipients ( struct mapitest mt)

Test the ReadRecipients (0xf) operation

This function:

  1. Log on the use private mailbox
  2. Open the Outbox folder
  3. Create the message, set recipients
  4. Save the message
  5. Read message recipients
  6. Delete the message
Parameters
mtpoint on the top-level mapitest structure
Returns
true on success, otherwise false

References mapitest_print(), mapitest_print_retval(), mapitest_print_retval_clean(), mapitest_print_retval_fmt(), and mapitest::mem_ctx.

bool mapitest_oxcmsg_ReloadCachedInformation ( struct mapitest mt)

Test the ReloadCachedInformation (0x10) operation

This function:

  1. Logs on to the user private mailbox
  2. Open the outbox folder
  3. Create the message
  4. Save the message
  5. Reloads the cached message information
  6. Delete the message
Parameters
mtpointer to the top-level mapitest structure
Returns
true on success, otherwise false

References mapitest_print_retval().

bool mapitest_oxcmsg_RemoveAllRecipients ( struct mapitest mt)

Test the RemoveAllRecipients (0xd) operation

This function:

  1. Log on the use private mailbox
  2. Open the Outbox folder
  3. Create the message, set recipients
  4. Save the message
  5. Remove all recipients
  6. Delete the message
Parameters
mtpoint on the top-level mapitest structure
Returns
true on success, otherwise false

References mapitest_print(), mapitest_print_retval(), mapitest_print_retval_clean(), mapitest_print_retval_fmt(), and mapitest::mem_ctx.

bool mapitest_oxcmsg_SaveChangesMessage ( struct mapitest mt)

Test the SaveChangesMessage (0xc) operation

This function:

  1. Log on the user private mailbox
  2. Open the Outbox folder
  3. Create the message
  4. Save the message
  5. Delete the message
Parameters
mtpointer on the top-level mapitest structure
Returns
true on success, otherwise false

References mapitest_print_retval().

bool mapitest_oxcmsg_SetMessageReadFlag ( struct mapitest mt)

Test the SetMessageReadFlag (0x11) operation

This function:

  1. Log on the user private mailbox
  2. Open the Inbox folder
  3. Create a tmp message
  4. Play with SetMessageReadFlag
  5. Delete the message

Note: We can test either SetMessageReadFlag was effective by checking its old/new value with GetProps on PR_MESSAGE_FLAGS property.

Parameters
mtpointer on the top-level mapitest structure
Returns
true on success, otherwise false

References mapitest_common_folder_open(), mapitest_common_message_create(), mapitest_print(), mapitest_print_retval(), mapitest_print_retval_fmt(), and mapitest::mem_ctx.

bool mapitest_oxcmsg_SetMessageStatus ( struct mapitest mt)

Test the GetMessageStatus (0x1f) operation

This function:

  1. Log on the user private mailbox
  2. Open the outbox folder
  3. Create the message
  4. Save the message
  5. Get outbox contents table
  6. Set different messages status, then get them and compare values
  7. Delete the message
Parameters
mtpointer on the top-level mapitest structure
Returns
true on success, otherwise false

References mapitest_print(), mapitest_print_retval(), mapitest_print_retval_clean(), and mapitest::mem_ctx.

bool mapitest_oxcmsg_SetReadFlags ( struct mapitest mt)

Test the SetReadFlags (0x66) operation

This function:

  1. Opens the Inbox folder and creates some test content
  2. Checks that the PR_MESSAGE_FLAGS property on each message is 0x0
  3. Apply SetReadFlags() on every second messages
  4. Check the results are as expected
  5. Apply SetReadFlags() again
  6. Check the results are as expected
  7. Cleanup
Parameters
mtpointer on the top-level mapitest structure
Returns
true on success, otherwise false

References mapitest_common_cleanup(), mapitest_common_setup(), mapitest_print(), mapitest_print_retval_clean(), and mapitest::mem_ctx.


Creative Commons License
Creative Commons Attribution icon Creative Commons Share Alike icon
This content is licensed under the Creative Commons
Attribution ShareAlike License v. 3.0:
http://creativecommons.org/licenses/by-sa/3.0/

openchange-2.0/apidocs/html/mapitest/module__oxcnotif_8c.html000066400000000000000000000133731223057412600245240ustar00rootroot00000000000000 MAPITests 2.0 API Documentation
module_oxcnotif.c File Reference

Core Notifications Protocol test suite. More...

Functions

bool mapitest_oxcnotif_RegisterNotification (struct mapitest *mt)
bool mapitest_oxcnotif_SyncOpenAdvisor (struct mapitest *mt)

Detailed Description

Core Notifications Protocol test suite.

Function Documentation

bool mapitest_oxcnotif_RegisterNotification ( struct mapitest mt)

Test the RegisterNotification (0x29) operation

This function:

Parameters
mtpointer on the top-level mapitest structure
Returns
true on success, otherwise false

References mapitest_common_folder_open(), and mapitest_print_retval().

bool mapitest_oxcnotif_SyncOpenAdvisor ( struct mapitest mt)

Test the SyncOpenAdvisor (0x83) and SetSyncNotificationGuid (0x88) operations

This function:

  1. logs on
  2. creates a notification advisor
  3. sets a GUID on the advisor
  4. cleans up
Parameters
mtpointer on the top-level mapitest structure
Returns
true on success, otherwise false

References mapitest_print_retval_clean().


Creative Commons License
Creative Commons Attribution icon Creative Commons Share Alike icon
This content is licensed under the Creative Commons
Attribution ShareAlike License v. 3.0:
http://creativecommons.org/licenses/by-sa/3.0/

openchange-2.0/apidocs/html/mapitest/module__oxcperm_8c.html000066400000000000000000000131431223057412600243430ustar00rootroot00000000000000 MAPITests 2.0 API Documentation
module_oxcperm.c File Reference

Permissions Protocol test suite. More...

Functions

bool mapitest_oxcperm_GetPermissionsTable (struct mapitest *mt)
bool mapitest_oxcperm_ModifyPermissions (struct mapitest *mt)

Detailed Description

Permissions Protocol test suite.

Function Documentation

bool mapitest_oxcperm_GetPermissionsTable ( struct mapitest mt)

Test the GetPermissionsTable (0x3e) operation

This function:

  1. Log on private message store
  2. Open the top store folder
  3. Gets the permissions table handle
  4. Fetches properties from the permissions table

References mapitest_print_retval(), and mapitest::mem_ctx.

bool mapitest_oxcperm_ModifyPermissions ( struct mapitest mt)

Test the ModifyPermissions (0x40) operation

This function:

  1. Log on private message store
  2. Open the top store folder
  3. Creates a temporary folder
  4. Adds permissions for the admin user, and checks them
  5. Modifies permissions for the admin user, and checks them
  6. Removes permissions for the admin user, and checks them
  7. Deletes the folder

References mapitest_print_retval(), and mapitest::mem_ctx.


Creative Commons License
Creative Commons Attribution icon Creative Commons Share Alike icon
This content is licensed under the Creative Commons
Attribution ShareAlike License v. 3.0:
http://creativecommons.org/licenses/by-sa/3.0/

openchange-2.0/apidocs/html/mapitest/module__oxcprpt_8c.html000066400000000000000000000745421223057412600243770ustar00rootroot00000000000000 MAPITests 2.0 API Documentation
module_oxcprpt.c File Reference

Property and Stream Object Protocol test suite. More...

Functions

bool mapitest_oxcprpt_CopyProps (struct mapitest *mt)
bool mapitest_oxcprpt_CopyTo (struct mapitest *mt)
bool mapitest_oxcprpt_CopyToStream (struct mapitest *mt)
bool mapitest_oxcprpt_DeleteProps (struct mapitest *mt)
bool mapitest_oxcprpt_GetPropList (struct mapitest *mt)
bool mapitest_oxcprpt_GetProps (struct mapitest *mt)
bool mapitest_oxcprpt_GetPropsAll (struct mapitest *mt)
bool mapitest_oxcprpt_NameId (struct mapitest *mt)
bool mapitest_oxcprpt_NameId_PSMAPI (struct mapitest *mt)
bool mapitest_oxcprpt_NoReplicate (struct mapitest *mt)
bool mapitest_oxcprpt_SetProps (struct mapitest *mt)
bool mapitest_oxcprpt_Stream (struct mapitest *mt)
bool mapitest_oxcprpt_WriteAndCommitStream (struct mapitest *mt)

Detailed Description

Property and Stream Object Protocol test suite.

Function Documentation

bool mapitest_oxcprpt_CopyProps ( struct mapitest mt)

Test the CopyProps (0x67) operation

This function:

  1. Opens the mailbox
  2. Creates a test folder
  3. Creates a reference email, and sets some properties on it
  4. Checks those properties are set correctly
  5. Creates a second email, and sets some (different) properties on it
  6. Checks those properties on the second folder are set correctly
  7. Copies properties from the reference email to the second email (no overwrite)
  8. Checks that properties on both emails are correct
  9. Copies properties again, but with overwrite
  10. Checks that properties on both emails are correct
  11. Moves properties from the original email to the second email (no overwrite)
  12. Checks that properties on both emails are correct
  13. Deletes both emails and the test folder
Todo:
It would be useful to test the problem return values
Parameters
mtpointer to the top-level mapitest structure
Returns
true on success, otherwise false

References mapitest_common_message_create(), mapitest_print(), mapitest_print_retval_step(), mapitest_print_retval_step_fmt(), and mapitest::mem_ctx.

bool mapitest_oxcprpt_CopyTo ( struct mapitest mt)

Test the CopyTo (0x39) operation

This function:

  1. Opens the mailbox
  2. Creates a test folder
  3. Creates a reference email, and sets some properties on it
  4. Checks those properties are set correctly
  5. Creates a second email, and sets some (different) properties on it
  6. Checks those properties on the second folder are set correctly
  7. Copies properties from the reference email to the second email (no overwrite)
  8. Checks that properties on both emails are correct
  9. Copies properties again, but with overwrite
  10. Checks that properties on both emails are correct
  11. Moves properties from the original email to the second email (no overwrite)
  12. Checks that properties on both emails are correct
  13. Creates an attachment (with properties) on the reference email
  14. Creates an attachment (with different properties) on the target email
  15. Copies the properties on the reference email to the target
  16. Checks the properties on both attachments are correct
  17. Creates another folder
  18. Copies properties from the test folder to the new folder
  19. Checks that the properties on both folders are correct
  20. Deletes both emails and the test folders
Todo:
It would be useful to test the problem return values
Parameters
mtpointer to the top-level mapitest structure
Returns
true on success, otherwise false

References mapitest_common_message_create(), mapitest_print(), mapitest_print_retval(), mapitest_print_retval_clean(), mapitest_print_retval_fmt(), and mapitest::mem_ctx.

bool mapitest_oxcprpt_CopyToStream ( struct mapitest mt)

Test the CopyToStream (0x3a) operation

This function:

  1. Logon the mailbox
  2. Open the inbox folder
  3. Create a sample messages with an attachment
  4. Create 2 streams
  5. Fill the first stream with random data
  6. Seek stream positions to the beginning
  7. CopyToStream data from first stream to the second stream
  8. Read dst stream and compare with src stream
  9. Delete the message
Parameters
mtpointer to the top-level mapitest structure
Returns
true on success, otherwise false

References mapitest_common_genblob(), mapitest_common_message_create(), mapitest_print(), mapitest_print_retval(), mapitest_print_retval_fmt(), and mapitest::mem_ctx.

bool mapitest_oxcprpt_DeleteProps ( struct mapitest mt)

Test the DeleteProps (0xb) operation)

This function:

  1. Opens the mailbox
  2. Create a test folder
  3. Creates a reference email, and sets some properties on it
  4. Delete properties from this message
  5. Checks that properties got deleted
  6. Deletes both email and the test folder
Todo:
It would be useful to test the problem return values
Parameters
mtpointer to the top-level mapitest structure
Returns
true on success, otherwise false

References mapitest_common_message_create(), mapitest_print(), mapitest_print_retval_step(), mapitest_print_retval_step_fmt(), and mapitest::mem_ctx.

bool mapitest_oxcprpt_GetPropList ( struct mapitest mt)

Test the GetPropList (0x9) operation

This function:

  1. Log on the user private mailbox
  2. Retrieve the list of properties associated to the store object object
Parameters
mtpointer on the top-level mapitest structure
Returns
true on success, otherwise false

References mapitest_print_retval(), and mapitest::mem_ctx.

bool mapitest_oxcprpt_GetProps ( struct mapitest mt)

Test the GetProps (0x7) operation

This function:

  1. Log on the user private mailbox
  2. Retrieve the properties list using GetPropList
  3. Retrieve their associated values using the GetProps operation
Parameters
mtpointer on the top-level mapitest structure
Returns
true on success, otherwise false

References mapitest_print_retval(), and mapitest::mem_ctx.

bool mapitest_oxcprpt_GetPropsAll ( struct mapitest mt)

Test the GetPropsAll (0x8) operation

This function:

  1. Log on the user private mailbox
  2. Retrieve the whole set of properties and values associated to the store object
Parameters
mtpointer on the top-level mapitest structure
Returns
true on success, otherwise false

References mapitest_print_retval().

bool mapitest_oxcprpt_NameId ( struct mapitest mt)

Test the GetPropertyIdsFromNames (0x56), GetNamesFromPropertyIds (0x55) and QueryNamesFromIDs (0x5f) operations

This function:

  1. Logs into the server
  2. Create a test folder and test message
  3. Creates one MNID_ID property
  4. Creates one MNID_STRING property
  5. Builds a table of Name, ID pairs using QueryNamesFromIDs()
  6. Iterates over names, and calls GetIDsFromNames() on each name
  7. Iterates over IDs, and calls GetNamesFromIDs() on each ID
  8. Cleans up
Parameters
mtpointer to the top-level mapitest structure
Returns
true on success, otherwise false

References mapitest_common_message_create(), mapitest_print(), mapitest_print_retval(), mapitest_print_retval_fmt(), and mapitest::mem_ctx.

bool mapitest_oxcprpt_NameId_PSMAPI ( struct mapitest mt)

Test the GetPropertyIdsFromNames (0x56) and GetNamesFromPropertyIds (0x55) operations for the special case of the PS_MAPI namespace

This function:

  1. Logs into the server
  2. Gets a property ID for a known property name
  3. Gets a property name for a known property ID
  4. Cleans up

Refer to MS-OXPROPS for the list of properties

Parameters
mtpointer to the top-level mapitest structure
Returns
true on success, otherwise false

References mapitest_print(), mapitest_print_retval_clean(), and mapitest::mem_ctx.

bool mapitest_oxcprpt_NoReplicate ( struct mapitest mt)

Test the SetPropertiesNoReplicate (0x79) and DeletePropertiesNoReplicate (0x7a) operations

This function:

  1. Opens the mailbox
  2. Create a test folder
  3. Sets some properties on the test folder
  4. Delete properties from the test folder
  5. Deletes the test folder
Todo:
It would be useful to test the problem return values
Parameters
mtpointer to the top-level mapitest structure
Returns
true on success, otherwise false

References mapitest_print(), mapitest_print_retval_step(), mapitest_print_retval_step_fmt(), and mapitest::mem_ctx.

bool mapitest_oxcprpt_SetProps ( struct mapitest mt)

Test the SetProps (0xa) operation

This function:

  1. Logon Private mailbox
  2. Use GetProps to retrieve the mailbox name
  3. Change it using SetProps
  4. Reset the mailbox name to its original value
Parameters
mtpointer to the top-level mapitest structure
Returns
true on success, otherwise false

References mapitest_print(), mapitest_print_retval_step_fmt(), and mapitest::mem_ctx.

bool mapitest_oxcprpt_Stream ( struct mapitest mt)

Test Stream operations. This test uses related stream operations: OpenStream (0x2b), SetStreamSize (0x2f), WriteStream (0x2d), CommitStream (0x5d), ReadStream (0x2c), SeekStream (0x2e), LockRegionStream (0x5b), UnlockRegionStream (0x5c), CloneStream (0x3b)

This function:

  1. Logon
  2. Open Outbox folder
  3. Create message
  4. Create attachment and set properties
  5. Open the stream
  6. Set the stream size
  7. Write into the stream
  8. Commit the stream
  9. Save the message
  10. Get stream size and compare values
  11. Open the stream again with different permissions
  12. Read the stream and compare buffers
  13. SeekStream at 0x1000 from the end of the stream
  14. Read the 0x1000 last bytes and check if it matches
  15. Lock a range of the stream
  16. TODO: test if the locking works
  17. Unlock a range of the stream
  18. Clone the stream
  19. Delete the message;
Parameters
mtpointer to the top-level mapitest structure
Returns
true on success, otherwise -1

References mapitest_common_genblob(), mapitest_common_message_create(), mapitest_print(), mapitest_print_retval(), mapitest_print_retval_fmt(), and mapitest::mem_ctx.

bool mapitest_oxcprpt_WriteAndCommitStream ( struct mapitest mt)

Test WriteAndCommitStream (0x90) operation.

This function:

  1. Logs in
  2. Opens the Outbox folder
  3. Creates a test message
  4. Creates an attachment on the test messages and set properties on the attachment
  5. Opens a stream on the attachment
  6. Sets the stream size
  7. Write and commits into the stream
  8. Saves the message
  9. Gets stream size and compare values
  10. Opens the stream again with different permissions
  11. Reads the stream and compares buffers
  12. Deletes the test message
Parameters
mtpointer to the top-level mapitest structure
Returns
true on success, otherwise -1

References mapitest_common_genblob(), mapitest_common_message_create(), mapitest_print(), mapitest_print_retval(), mapitest_print_retval_clean(), mapitest_print_retval_fmt_clean(), and mapitest::mem_ctx.


Creative Commons License
Creative Commons Attribution icon Creative Commons Share Alike icon
This content is licensed under the Creative Commons
Attribution ShareAlike License v. 3.0:
http://creativecommons.org/licenses/by-sa/3.0/

openchange-2.0/apidocs/html/mapitest/module__oxcstor_8c.html000066400000000000000000000410261223057412600243700ustar00rootroot00000000000000 MAPITests 2.0 API Documentation
module_oxcstor.c File Reference

Store Object Protocol test suite. More...

#include "libmapi/libmapi_private.h"

Functions

bool mapitest_oxcstor_GetOwningServers (struct mapitest *mt)
bool mapitest_oxcstor_GetReceiveFolder (struct mapitest *mt)
bool mapitest_oxcstor_GetReceiveFolderTable (struct mapitest *mt)
bool mapitest_oxcstor_GetStoreState (struct mapitest *mt)
bool mapitest_oxcstor_IsMailboxFolder (struct mapitest *mt)
bool mapitest_oxcstor_Logon (struct mapitest *mt)
bool mapitest_oxcstor_LongTermId (struct mapitest *mt)
bool mapitest_oxcstor_PublicFolderIsGhosted (struct mapitest *mt)
bool mapitest_oxcstor_SetReceiveFolder (struct mapitest *mt)

Detailed Description

Store Object Protocol test suite.

Function Documentation

bool mapitest_oxcstor_GetOwningServers ( struct mapitest mt)

Test the GetOwningServers (0x42) operation

This function:

  1. Log on the public folders store
  2. Open a public folder
  3. Call the GetOwningServers operation
Parameters
mtthe top-level mapitest structure
Returns
true on success, otherwise false

References mapitest_print(), and mapitest_print_retval().

bool mapitest_oxcstor_GetReceiveFolder ( struct mapitest mt)

Test the GetReceiveFolder (0x27) operation

This function:

  1. Log on the user private mailbox
  2. Call the GetReceiveFolder operation
  3. Call the GetReceiveFolder with different explicit message class values
Parameters
mtthe top-level mapitest structure
Returns
true on success, otherwise false

References mapitest_print(), and mapitest_print_retval_clean().

bool mapitest_oxcstor_GetReceiveFolderTable ( struct mapitest mt)

Test the GetReceiveFolderTable (0x68) operation

This function:

  1. Log on the user private mailbox
  2. Call the GetReceiveFolderTable operation
Parameters
mtthe top-level mapitest structure
Returns
true on success, otherwise false

References mapitest_print_retval(), and mapitest_print_SRowSet().

bool mapitest_oxcstor_GetStoreState ( struct mapitest mt)

Test the GetStoreState (0x7b) operation

This function:

  1. Logs into the user private mailbox
  2. Retrieve the store state
Parameters
mtpointer on the top-level mapitest structure
Returns
true on success, otherwise false

References mapitest_print_retval().

bool mapitest_oxcstor_IsMailboxFolder ( struct mapitest mt)

Test the IsMailboxFolder convenience function

This function:

  1. Logs into the user private mailbox
Parameters
mtpointer on the top-level mapitest structure
Returns
true on success, otherwise false

References mapitest_print(), and mapitest_print_retval().

bool mapitest_oxcstor_Logon ( struct mapitest mt)

Test the Logon (0xFE) operation

This function:

  1. Log on the user private mailbox
  2. Log on the public folder store
Parameters
mtpointer on the top-level mapitest structure
Returns
true on success, otherwise false

References mapitest_print_retval().

bool mapitest_oxcstor_LongTermId ( struct mapitest mt)

Test the LongTermIdFromId (0x43) and IdFromLongTermId (0x44) operations

This function:

  1. Logs into the user private mailbox
  2. Open the Receive Folder
  3. Looks up the long term id for the receive folder FID
  4. Looks up the short term id for the long term id
  5. Checks the id matches the original FID
Parameters
mtpointer on the top-level mapitest structure
Returns
true on success, otherwise false

References mapitest_print(), and mapitest_print_retval().

bool mapitest_oxcstor_PublicFolderIsGhosted ( struct mapitest mt)

Test the PublicFolderIsGhosted (0x45) operation

This function:

  1. Log on the public folders store
  2. Open a public folder
  3. Call the PublicFolderIsGhosted operation
Parameters
mtthe top-level mapitest structure
Returns
true on success, otherwise false

References mapitest_print(), and mapitest_print_retval().

bool mapitest_oxcstor_SetReceiveFolder ( struct mapitest mt)

Test the SetReceiveFolder (0x26) operation

This function:

  1. Log on the user private mailbox
  2. Call the SetReceiveFolder operations
  3. Clean up
Parameters
mtthe top-level mapitest structure
Returns
true on success, otherwise false

References mapitest_print_retval_step(), and mapitest_print_retval_step_fmt().


Creative Commons License
Creative Commons Attribution icon Creative Commons Share Alike icon
This content is licensed under the Creative Commons
Attribution ShareAlike License v. 3.0:
http://creativecommons.org/licenses/by-sa/3.0/

openchange-2.0/apidocs/html/mapitest/module__oxctable_8c.html000066400000000000000000000525101223057412600244700ustar00rootroot00000000000000 MAPITests 2.0 API Documentation
module_oxctable.c File Reference

Table Object Protocol test suite. More...

Functions

bool mapitest_oxctable_Category (struct mapitest *mt)
bool mapitest_oxctable_CreateBookmark (struct mapitest *mt)
bool mapitest_oxctable_GetStatus (struct mapitest *mt)
bool mapitest_oxctable_QueryColumns (struct mapitest *mt)
bool mapitest_oxctable_QueryRows (struct mapitest *mt)
bool mapitest_oxctable_Restrict (struct mapitest *mt)
bool mapitest_oxctable_SeekRow (struct mapitest *mt)
bool mapitest_oxctable_SeekRowApprox (struct mapitest *mt)
bool mapitest_oxctable_SeekRowBookmark (struct mapitest *mt)
bool mapitest_oxctable_SetColumns (struct mapitest *mt)

Detailed Description

Table Object Protocol test suite.

Function Documentation

bool mapitest_oxctable_Category ( struct mapitest mt)

Test the SortTable (0x13), ExpandRow (0x59), CollapseRow(0x5a), GetCollapseState(0x6b) and SetCollapseState (0x6c) operations

This function:

  1. Opens the Inbox folder and creates some test content
  2. Checks that the content is OK
  3. Applies a sort and categorisation
  4. Checks the results are as expected.
  5. Save away the Row ID and Insatnce Number for the first header
  6. Collapse the first category
  7. Checks the results are as expected.
  8. Save the "collapse state"
  9. Expand the first category again
  10. Checks the results are as expected
  11. Restore the saved "collapse state"
  12. Checks the results are as expected
  13. Cleans up
Parameters
mtpointer on the top-level mapitest structure
Returns
true on success, otherwise false

References mapitest_common_cleanup(), mapitest_common_setup(), mapitest_print(), mapitest_print_retval(), and mapitest::mem_ctx.

bool mapitest_oxctable_CreateBookmark ( struct mapitest mt)

Test the CreateBookmark (0x1b) operation

This function:

  1. Opens the Inbox folder and gets the hierarchy table
  2. Customize the MAPI table view
  3. CreateBookmark for each table's row
  4. Free Bookmark for each created bookmark
  5. Cleans up
Parameters
mtpointer on the top-level mapitest structure
Returns
true on success, otherwise false

References mapitest_common_cleanup(), mapitest_common_setup(), mapitest_print_retval_fmt_clean(), and mapitest::mem_ctx.

bool mapitest_oxctable_GetStatus ( struct mapitest mt)

Test the GetStatus (0x16) operation

This function:

  1. Opens the Inbox folder and gets the hierarchy table
  2. Call GetStatus
  3. Cleans up

References mapitest_common_cleanup(), mapitest_common_setup(), mapitest_print(), and mapitest_print_retval().

bool mapitest_oxctable_QueryColumns ( struct mapitest mt)

Test the QueryColumns (0x37) operation

This function:

  1. Opens the Inbox folder and gets the hierarchy table

Calls the QueryColumn operation

  1. Calls SetColumns on the test folder
  2. Checks that QueryColumns on the test folder is correct
  3. Cleans up
Parameters
mtpointer to the top-level mapitest structure
Returns
true on success, otherwise false

References mapitest_common_cleanup(), mapitest_common_setup(), mapitest_print(), and mapitest_print_retval().

bool mapitest_oxctable_QueryRows ( struct mapitest mt)

Test the QueryRows (0x15) operation

This function:

  1. Opens the Inbox folder and gets the hierarchy table
  2. Set the required columns
  3. Calls QueryRows until the end of the table
  4. Open the test folder, and get its contents
  5. Calls QueryRows until the end of the test folder
  6. Checks the results are as expected.
  7. Cleans up
Parameters
mtpointer on the top-level mapitest structure
Returns
true on success, otherwise false

References mapitest_common_cleanup(), mapitest_common_setup(), mapitest_print(), mapitest_print_retval(), and mapitest::mem_ctx.

bool mapitest_oxctable_Restrict ( struct mapitest mt)

Test the Restrict (0x14) operation

This function:

  1. Opens the Inbox folder and creates some test content
  2. Checks that the content is OK
  3. Applies a filter
  4. Checks the results are as expected.
  5. Resets the table
  6. Checks the results are as expected.
  7. Cleans up
Parameters
mtpointer on the top-level mapitest structure
Returns
true on success, otherwise false

References mapitest_common_cleanup(), mapitest_common_setup(), mapitest_print(), and mapitest_print_retval().

bool mapitest_oxctable_SeekRow ( struct mapitest mt)

Test the SeekRow (0x18) operation

This function:

  1. Opens the Inbox folder and gets the hierarchy table
  2. SeekRow with BOOKMARK_BEGINNING
  3. SeekRow with BOOKMARK_END
  4. SeekRow with BOOKMARK_CURRENT
  5. Cleans up
Parameters
mtpointer on the top-level mapitest structure
Returns
true on success, otherwise false

References mapitest_common_cleanup(), mapitest_common_setup(), and mapitest_print_retval_fmt().

bool mapitest_oxctable_SeekRowApprox ( struct mapitest mt)

Test the SeekRowApprox (0x1a) operation

This function:

  1. Opens the Inbox folder and gets the hierarchy table
  2. SeekRowApprox with 0/1, 1/1 and 1/2 fractional values
  3. Cleans up
Parameters
mtpointer on the top-level mapitest structure
Returns
true on success, otherwise false

References mapitest_common_cleanup(), mapitest_common_setup(), and mapitest_print_retval_fmt().

bool mapitest_oxctable_SeekRowBookmark ( struct mapitest mt)

Test the SeekRowBookmark (0x19) operation

This function:

  1. Open the Inbox folder and retrieve the hierarchy table
  2. Customize the MAPI table view
  3. SeekBookmark for each table's row
  4. Free Bookmark for each created bookmark
Parameters
mtpointer on the top-level mapitest structure
Returns
true on success, otherwise false

References mapitest_common_cleanup(), mapitest_common_setup(), mapitest_print_retval(), mapitest_print_retval_fmt_clean(), and mapitest::mem_ctx.

bool mapitest_oxctable_SetColumns ( struct mapitest mt)

Test the SetColumns (0x12) operation

This function:

  1. Opens the Inbox folder and gets the hierarchy table
  2. Calls the SetColumns operation
  3. Cleans up
Parameters
mtpointer to the top-level mapitest structure
Returns
true on success, otherwise false

References mapitest_common_cleanup(), mapitest_common_setup(), mapitest_print_retval(), and mapitest::mem_ctx.


Creative Commons License
Creative Commons Attribution icon Creative Commons Share Alike icon
This content is licensed under the Creative Commons
Attribution ShareAlike License v. 3.0:
http://creativecommons.org/licenses/by-sa/3.0/

openchange-2.0/apidocs/html/mapitest/module__oxomsg_8c.html000066400000000000000000000420161223057412600242030ustar00rootroot00000000000000 MAPITests 2.0 API Documentation
module_oxomsg.c File Reference

E-Mail Object Protocol test suite. More...

Functions

bool mapitest_oxomsg_AbortSubmit (struct mapitest *mt)
bool mapitest_oxomsg_AddressTypes (struct mapitest *mt)
bool mapitest_oxomsg_GetTransportFolder (struct mapitest *mt)
bool mapitest_oxomsg_SetSpooler (struct mapitest *mt)
bool mapitest_oxomsg_SpoolerLockMessage (struct mapitest *mt)
bool mapitest_oxomsg_SubmitMessage (struct mapitest *mt)
bool mapitest_oxomsg_TransportNewMail (struct mapitest *mt)
bool mapitest_oxomsg_TransportSend (struct mapitest *mt)

Detailed Description

E-Mail Object Protocol test suite.

Function Documentation

bool mapitest_oxomsg_AbortSubmit ( struct mapitest mt)

Test the AbortSubmit (0x34) operation

This function:

  1. Log on the user private mailbox
  2. Open the Outbox folder
  3. Create a sample message
  4. Submit the message
  5. Abort the submit operation
  6. Delete the message
  7. Clean up folders

Note: This operation may fail since it depends on how busy the server is when we submit the message. It is possible the message gets already processed before we have time to abort the message.

From preliminary tests, AbortSubmit returns MAPI_E_SUCCESS when we call SubmitMessage with SubmitFlags set to 0x2.

Parameters
mtpointer on the top-level mapitest structure
Returns
true on success, otherwise false

References mapitest_common_message_create(), mapitest_common_message_delete_by_subject(), and mapitest_print_retval().

bool mapitest_oxomsg_AddressTypes ( struct mapitest mt)

Test the AddressTypes (0x49) and OptionsData (0x6f) operations

This function:

  1. Log on the user private mailbox
  2. Call the AddressTypes operation
  3. Call the OptionsData operation on each address type
Parameters
mtpointer on the top-level mapitest structure
Returns
true on success, otherwise false

References mapitest_print(), and mapitest_print_retval().

bool mapitest_oxomsg_GetTransportFolder ( struct mapitest mt)

Test the GetTransportFolder (0x6d) operation

This function:

  1. Log on the user private mailbox
  2. Retrieves the folder ID of temporary transport folder
Parameters
mtpointer on the top-level mapitest structure
Returns
true on success, otherwise false

References mapitest_print_retval_fmt().

bool mapitest_oxomsg_SetSpooler ( struct mapitest mt)

Test the SetSpooler (0x47) operation

This function:

  1. Log on the user private mailbox
  2. Informs the server it will acts as an email spooler
Parameters
mtpointer on the top-level mapitest structure
Returns
true on success, otherwise false

References mapitest_print_retval().

bool mapitest_oxomsg_SpoolerLockMessage ( struct mapitest mt)

Test the SpoolerLockMessage (0x48) operation

This function:

  1. Log on the user private mailbox
  2. Informs the server it will acts as an email spooler
  3. Create a message in the outbox folder
  4. Save message changes and Submit the message
  5. Lock the message
  6. Unlock-Finish the message
  7. Deletes the message
Parameters
mtpointer on the top-level mapitest structure
Returns
true on success, otherwise false

References mapitest_common_folder_open(), mapitest_common_message_create(), mapitest_print(), mapitest_print_retval(), and mapitest_print_retval_fmt().

bool mapitest_oxomsg_SubmitMessage ( struct mapitest mt)

Test the SubmitMessage (0x32) operation

This function:

  1. Log on the user private mailbox
  2. Open the Outbox folder
  3. Create a sample message
  4. Submit the message
  5. Delete the message
  6. Clean up folders
Parameters
mtpointer on the top-level mapitest structure
Returns
true on success, otherwise false

References mapitest_common_message_create(), mapitest_common_message_delete_by_subject(), and mapitest_print_retval().

bool mapitest_oxomsg_TransportNewMail ( struct mapitest mt)

Test the TransportNewMail (0x51) operation

This function:

  1. Logs on to the user private mailbox
  2. Create a filled test folder, and open it.
  3. Perform the TransportNewMail operation
  4. Clean up test environment
Parameters
mtpointer on the top-level mapitest structure
Returns
true on success, otherwise false

References mapitest_common_cleanup(), mapitest_common_setup(), and mapitest_print_retval_clean().

bool mapitest_oxomsg_TransportSend ( struct mapitest mt)

Test the TransportSend (0x4a) operation

This function:

  1. Logs on to the user private mailbox
  2. Opens the outbox folder
  3. Create the test message
  4. Save changes to the message
  5. Perform the TransportSend operation
  6. Dump the properties
  7. Clean up folders
Parameters
mtpointer on the top-level mapitest structure
Returns
true on success, otherwise false

References mapitest_common_folder_open(), mapitest_common_message_create(), mapitest_common_message_delete_by_subject(), mapitest_print(), mapitest_print_retval(), mapitest_print_SPropValue(), and mapitest::mem_ctx.


Creative Commons License
Creative Commons Attribution icon Creative Commons Share Alike icon
This content is licensed under the Creative Commons
Attribution ShareAlike License v. 3.0:
http://creativecommons.org/licenses/by-sa/3.0/

openchange-2.0/apidocs/html/mapitest/module__oxorule_8c.html000066400000000000000000000105211223057412600243600ustar00rootroot00000000000000 MAPITests 2.0 API Documentation
module_oxorule.c File Reference

E-Mail Rules Protocol test suite. More...

Functions

bool mapitest_oxorule_GetRulesTable (struct mapitest *mt)

Detailed Description

E-Mail Rules Protocol test suite.

Function Documentation

bool mapitest_oxorule_GetRulesTable ( struct mapitest mt)

Test the GetRulesTable (0x3f) operation

This function:

  1. Log on the user private mailbox
  2. Open the inbox folder
  3. Retrieve the rules table
Parameters
mtpointer on the top-level mapitest structure
Returns
true on success, otherwise false

References mapitest_common_folder_open(), and mapitest_print_retval().


Creative Commons License
Creative Commons Attribution icon Creative Commons Share Alike icon
This content is licensed under the Creative Commons
Attribution ShareAlike License v. 3.0:
http://creativecommons.org/licenses/by-sa/3.0/

openchange-2.0/apidocs/html/mapitest/nav_f.png000066400000000000000000000002311223057412600214730ustar00rootroot00000000000000‰PNG  IHDR8³»`IDATxíÝK€ EÑ–·[†øBÑmkâÄÂH—prÓ¼.‚Žó‚ꎤR6Z VI±E‚5j³„lóš›iI˜¬ÞêçJ0ŒÑÑ/Žû›™uøñóÞ¿6sH ÝõyIEND®B`‚openchange-2.0/apidocs/html/mapitest/nav_g.png000066400000000000000000000001371223057412600215010ustar00rootroot00000000000000‰PNG  IHDRô1&IDATxíÝ1 ÁOHf„á_ ->~¸åM iËMèÀƒS½ü‚<IEND®B`‚openchange-2.0/apidocs/html/mapitest/nav_h.png000066400000000000000000000001421223057412600214760ustar00rootroot00000000000000‰PNG  IHDR ,é@)IDATxíÝA @BQ­³šÛ›Ð¢Žáà) )ëý éaÅèÜ¿Æo‡RlÐßIEND®B`‚openchange-2.0/apidocs/html/mapitest/nav_tab.gif000066400000000000000000000014541223057412600220050ustar00rootroot00000000000000GIF89aPæïïïþþþýþýûüúõ÷óñôïøú÷ýýüúûù÷ùöôöòöøõïóíðôîóöñùúøüýûòõðïòìîòëíñëòõïõõõÿÿÿúúúîòìðóîêëéðððôôôñññýýýñôðÆÉÅìîëÇÊÆÈÊÆÏÏÎÇÊÅËÍÊêìéïóîçèæÎÏÍÐÐÐõ÷ôÊÍÉïñíÆÈÄÊÌÊêêéïóìüýüÊËÉÏÏÏèêçÕ×ÓüüûÍÎÌëíêÌÍËíñêÏÐÏùûøêëêòöðóõñÉÊÇñôîîñì!ù,Pÿ€ˆ‰Š‹ŒŽ‘ˆ‚@;/Ÿ ¡¢£¤¥¦§¨E(ƒ )·¸¹º»¼½¾¿À¸ 7„23ËÌÍÎÏÐÑÒÓÔÐ=*"DÝÞßàáâãäåæä8 îïðñòóôõö÷õ.A þÿ H° ÁƒM R ¡Ã‡#JœH±¢ÅŠ0)ˆÀ±£Ç CŠI²$Ɉ8Xɲ¥Ë—0cÊœIsæD-èÜɳ§ÏŸ@ƒ *”¢’*]Ê´©Ó§P£J:Q‚X³jÝʵ«×¯`­È@‚³hÓª]˶­Û·p‰ßÆ@ôÀݻxóêÝË·¯ß¿~O Bð °áÈ+^̸±ãÆ< @@¹²å˘3kÞ̹3gˆr Mº´éÓ¨S«^Ízõ D4 ÈžM»¶íÛ¸sëÞ­»¢Àƒ N¼¸ñãÈ“'·H€óçУKŸN½ºõë×} À½»÷ïàËO¾|y;openchange-2.0/apidocs/html/mapitest/open.png000066400000000000000000000001731223057412600213500ustar00rootroot00000000000000‰PNG  IHDR à‘BIDATxíÝÁ €0 Ð׬ՙ\Àº€39—b!©9{|ðI>$#Àß´ý8/¨ÄØzƒ/Ï>2À[ÎgiU,/¬~¼Ï\ Ä9Ù¸IEND®B`‚openchange-2.0/apidocs/html/mapitest/pages.html000066400000000000000000000042301223057412600216640ustar00rootroot00000000000000 MAPITests 2.0 API Documentation
Related Pages
Here is a list of all related documentation pages:

Creative Commons License
Creative Commons Attribution icon Creative Commons Share Alike icon
This content is licensed under the Creative Commons
Attribution ShareAlike License v. 3.0:
http://creativecommons.org/licenses/by-sa/3.0/

openchange-2.0/apidocs/html/mapitest/pixel_grey.gif000066400000000000000000000000531223057412600225340ustar00rootroot00000000000000GIF89a€îîî!ù,D;openchange-2.0/apidocs/html/mapitest/structmapitest.html000066400000000000000000000521311223057412600236630ustar00rootroot00000000000000 MAPITests 2.0 API Documentation
mapitest Struct Reference

The context structure for a mapitest run. More...

#include <mapitest.h>

Data Fields

bool color
bool confidential
bool mapi_all
struct mapi_context * mapi_ctx
struct mapitest_suitemapi_suite
TALLOC_CTX * mem_ctx
bool no_server
bool online
bool subunit_output

Detailed Description

The context structure for a mapitest run.

Field Documentation

bool mapitest::confidential

true if confidential information should be omitted

Referenced by main(), mapitest_print_headers_info(), and mapitest_print_headers_server_info().

bool mapitest::mapi_all

true if all tests should be run

Referenced by main().

struct mapitest_suite* mapitest::mapi_suite
TALLOC_CTX* mapitest::mem_ctx

talloc memory context for memory allocations

Referenced by main(), mapitest_common_create_filled_test_folder(), mapitest_common_find_folder(), mapitest_common_message_delete_by_subject(), mapitest_common_message_fill(), mapitest_common_setup(), mapitest_mapidump_appointment(), mapitest_mapidump_contact(), mapitest_mapidump_foldercreated(), mapitest_mapidump_freebusy(), mapitest_mapidump_message(), mapitest_mapidump_messagecreated(), mapitest_mapidump_messagemodified(), mapitest_mapidump_note(), mapitest_mapidump_pabentry(), mapitest_mapidump_recipients(), mapitest_mapidump_sproptagarray(), mapitest_mapidump_spropvalue(), mapitest_mapidump_srowset(), mapitest_mapidump_task(), mapitest_noserver_lzfu(), mapitest_noserver_mapi_properties(), mapitest_noserver_rtfcp(), mapitest_noserver_rtfcp_large(), mapitest_nspi_GetGALTable(), mapitest_nspi_GetPropList(), mapitest_nspi_GetSpecialTable(), mapitest_nspi_ModLinkAtt(), mapitest_nspi_ResolveNames(), mapitest_oxcfold_HardDeleteMessages(), mapitest_oxcfold_MoveCopyMessages(), mapitest_oxcfxics_CopyFolder(), mapitest_oxcfxics_CopyMessages(), mapitest_oxcfxics_CopyProperties(), mapitest_oxcfxics_CopyTo(), mapitest_oxcfxics_GetLocalReplicaIds(), mapitest_oxcfxics_SetLocalReplicaMidsetDeleted(), mapitest_oxcfxics_SyncConfigure(), mapitest_oxcmsg_GetMessageStatus(), mapitest_oxcmsg_ModifyRecipients(), mapitest_oxcmsg_ReadRecipients(), mapitest_oxcmsg_RemoveAllRecipients(), mapitest_oxcmsg_SetMessageReadFlag(), mapitest_oxcmsg_SetMessageStatus(), mapitest_oxcmsg_SetReadFlags(), mapitest_oxcperm_GetPermissionsTable(), mapitest_oxcperm_ModifyPermissions(), mapitest_oxcprpt_CopyProps(), mapitest_oxcprpt_CopyTo(), mapitest_oxcprpt_CopyToStream(), mapitest_oxcprpt_DeleteProps(), mapitest_oxcprpt_GetPropList(), mapitest_oxcprpt_GetProps(), mapitest_oxcprpt_NameId(), mapitest_oxcprpt_NameId_PSMAPI(), mapitest_oxcprpt_NoReplicate(), mapitest_oxcprpt_SetProps(), mapitest_oxcprpt_Stream(), mapitest_oxcprpt_WriteAndCommitStream(), mapitest_oxctable_Category(), mapitest_oxctable_CreateBookmark(), mapitest_oxctable_QueryRows(), mapitest_oxctable_SeekRowBookmark(), mapitest_oxctable_SetColumns(), mapitest_oxomsg_TransportSend(), mapitest_print_module_title_start(), mapitest_print_test_title_start(), mapitest_suite_init(), and mapitest_suite_register().

bool mapitest::no_server

true if only non-server tests should be run

Referenced by main(), and mapitest_print_headers().

bool mapitest::online

true if the server could be accessed

Referenced by main(), mapitest_print_headers_server_info(), mapitest_run_all(), and mapitest_run_test().


The documentation for this struct was generated from the following file:

Creative Commons License
Creative Commons Attribution icon Creative Commons Share Alike icon
This content is licensed under the Creative Commons
Attribution ShareAlike License v. 3.0:
http://creativecommons.org/licenses/by-sa/3.0/

openchange-2.0/apidocs/html/mapitest/structmapitest__stat.html000066400000000000000000000234731223057412600250640ustar00rootroot00000000000000 MAPITests 2.0 API Documentation
mapitest_stat Struct Reference

mapitest statistics More...

#include <mapitest.h>

Data Fields

bool enabled
uint32_t failure
struct mapitest_unitfailure_info
struct mapitest_unitskip_info
uint32_t skipped
uint32_t success
uint32_t x_fail

Detailed Description

mapitest statistics

During a mapitest run, mapitest collects statistics on each test suite.

This data structure records the results for one run of a test suite.

There should be one entry in the failure_info list for each failure.

Field Documentation

bool mapitest_stat::enabled

Whether this statistics structure is valid

Referenced by mapitest_stat_add_result(), mapitest_stat_add_skipped_test(), mapitest_stat_dump(), and mapitest_stat_init().

uint32_t mapitest_stat::failure

Number of tests in this suite that failed

Referenced by mapitest_stat_add_result(), mapitest_stat_dump(), and mapitest_stat_init().

struct mapitest_unit* mapitest_stat::failure_info

List of names of the tests that failed

Referenced by mapitest_stat_add_result(), mapitest_stat_dump(), and mapitest_stat_init().

struct mapitest_unit* mapitest_stat::skip_info

List of names of the tests that were skipped, and why

Referenced by mapitest_stat_add_skipped_test(), mapitest_stat_dump(), and mapitest_stat_init().

uint32_t mapitest_stat::skipped

Number of tests in this suite that were skipped

Referenced by mapitest_stat_add_skipped_test(), mapitest_stat_dump(), and mapitest_stat_init().

uint32_t mapitest_stat::success

Number of tests in this suite that passed

Referenced by mapitest_stat_add_result(), mapitest_stat_dump(), and mapitest_stat_init().

uint32_t mapitest_stat::x_fail

Number of tests in this suite that were expected failures

Referenced by mapitest_stat_add_result(), mapitest_stat_dump(), and mapitest_stat_init().


The documentation for this struct was generated from the following file:

Creative Commons License
Creative Commons Attribution icon Creative Commons Share Alike icon
This content is licensed under the Creative Commons
Attribution ShareAlike License v. 3.0:
http://creativecommons.org/licenses/by-sa/3.0/

openchange-2.0/apidocs/html/mapitest/structmapitest__suite.html000066400000000000000000000241171223057412600252360ustar00rootroot00000000000000 MAPITests 2.0 API Documentation
mapitest_suite Struct Reference

A list of test suites. More...

#include <mapitest.h>

Data Fields

char * description
char * name
struct mapitest_suitenext
bool online
struct mapitest_suiteprev
struct mapitest_statstat
struct mapitest_testtests

Detailed Description

A list of test suites.

mapitest executes a set of tests. Those tests are grouped into suites of related tests (e.g. all tests that do not require a server are in one suite, the tests for NSPI are in another suite, and so on). This linked list data structure represents the various test suites to be executed.

Field Documentation

char* mapitest_suite::description

Description of the test suite

Referenced by mapitest_suite_init().

struct mapitest_suite* mapitest_suite::next
bool mapitest_suite::online

Whether this suite requires a server

Referenced by mapitest_run_all(), mapitest_run_test(), and mapitest_suite_init().

struct mapitest_suite* mapitest_suite::prev

Pointer to the previous test suite

struct mapitest_stat* mapitest_suite::stat
struct mapitest_test* mapitest_suite::tests

The documentation for this struct was generated from the following file:

Creative Commons License
Creative Commons Attribution icon Creative Commons Share Alike icon
This content is licensed under the Creative Commons
Attribution ShareAlike License v. 3.0:
http://creativecommons.org/licenses/by-sa/3.0/

openchange-2.0/apidocs/html/mapitest/structmapitest__test.html000066400000000000000000000177051223057412600250710ustar00rootroot00000000000000 MAPITests 2.0 API Documentation
mapitest_test Struct Reference

A list of mapitest tests. More...

#include <mapitest.h>

Data Fields

char * description
enum TestApplicabilityFlags flags
void * fn
char * name
struct mapitest_testnext
struct mapitest_testprev

Detailed Description

A list of mapitest tests.

mapitest tests are grouped into test suites. This linked list data structure represents the various tests as a list of tests (i.e. the linked list is a suite of tests).

The function that executes the test is pointed to by the fn element (i.e. fn is a function pointer).

Field Documentation

char* mapitest_test::description

The description of this test

Referenced by mapitest_suite_add_test_flagged().

enum TestApplicabilityFlags mapitest_test::flags

any applicability for this test

Referenced by mapitest_suite_add_test_flagged().

void* mapitest_test::fn

pointer to the test function

Referenced by mapitest_suite_add_test_flagged().

char* mapitest_test::name
struct mapitest_test* mapitest_test::next
struct mapitest_test* mapitest_test::prev

The previous test in the list


The documentation for this struct was generated from the following file:

Creative Commons License
Creative Commons Attribution icon Creative Commons Share Alike icon
This content is licensed under the Creative Commons
Attribution ShareAlike License v. 3.0:
http://creativecommons.org/licenses/by-sa/3.0/

openchange-2.0/apidocs/html/mapitest/structmapitest__unit.html000066400000000000000000000144651223057412600250710ustar00rootroot00000000000000 MAPITests 2.0 API Documentation
mapitest_unit Struct Reference

List of test names. More...

#include <mapitest.h>

Data Fields

char * name
struct mapitest_unitnext
struct mapitest_unitprev
char * reason

Detailed Description

List of test names.

This linked list data structure has a list of names of tests. It is used with mapitest_stat to record the failed tests.

Field Documentation

char* mapitest_unit::name
struct mapitest_unit* mapitest_unit::next

The next test in the list

Referenced by main(), and mapitest_stat_dump().

struct mapitest_unit* mapitest_unit::prev

The previous test in the list

char* mapitest_unit::reason

Why this test was skipped or failed (if applicable)

Referenced by mapitest_stat_add_result(), and mapitest_stat_dump().


The documentation for this struct was generated from the following file:

Creative Commons License
Creative Commons Attribution icon Creative Commons Share Alike icon
This content is licensed under the Creative Commons
Attribution ShareAlike License v. 3.0:
http://creativecommons.org/licenses/by-sa/3.0/

openchange-2.0/apidocs/html/mapitest/structmt__common__tf__ctx.html000066400000000000000000000047601223057412600260360ustar00rootroot00000000000000 MAPITests 2.0 API Documentation
mt_common_tf_ctx Struct Reference

Context for mapitest test folder. More...

#include <mapitest.h>

Detailed Description

Context for mapitest test folder.


The documentation for this struct was generated from the following file:

Creative Commons License
Creative Commons Attribution icon Creative Commons Share Alike icon
This content is licensed under the Creative Commons
Attribution ShareAlike License v. 3.0:
http://creativecommons.org/licenses/by-sa/3.0/

openchange-2.0/apidocs/html/mapitest/sync_off.png000066400000000000000000000015251223057412600222170ustar00rootroot00000000000000‰PNG  IHDRàw=øIDATxíÝKhTWÀñÿä1I&3™8M¦Iš™†I3Ú©b$cÌ I1V1±-(Tö±±Ð.* t!‚K[¥Ä¥ˆ„¨´f£`l(øl©"Y”¤6ÆgÌTú}·sgîܹ ±d{8?æÌ¹÷;çÜuíÚ`:!±F¬¢BäŠ?ŰÄm'yÊÅ>ÑlU¯½üý‰è_‹?€Œê ]€Y(ŠNñ±8fý1°Öqún-eâ¨øtºmâÈ Ó0}b›ù%·©µ×Œ®=Ÿ0´³?Š1sŸ‹0€¯8À‘;_ ‹W|%\ Zð— >舽ln¨p©.aÇ{ )t;Ú b nŸš¯›65°¢¡2çÅÔ?Žž>Oдàuönm¤¢Ì`×­Z¬WjC~>‘Ö¾0+á {{©fÝ×Mæ·æÅ•ìÙ¼˜` Ý›%uA6´½ÅÆö¨Á,]k¢ÄW¼™u±›]‹ˆ7§¯iòh€ ¶¶¬ÏÖu1 ló —Ҷ̺–:ÞÍ\ÄcãÏxøhR²Êè‡Qt$¿ß§¨ ª fdºü<4BÿÙ[•f¸d7=.Mé9/—éªÃëù/ÿO Üaàò}€,‘j?Ÿõ.5Úšm?œÿŸ®ŽXÿ2¬#¸d píæ(£?cÛú¼!½›a1¥Þ—ŽòØ©ܾ7dÔK:‚ùÒ‰ì)Ê3‚Ü™àÌà]€,±H€µ+køöäu<|`·LhC7¹ÔeÍ Ÿ×Ÿ˜tÜ‹ óH$^2%l.êaeÐäýE”ÌÉ|ÅÜìî‰Ýsä }¸ýDû^hzé~ðR›¦Ã¡¿]|#ü¯@×—Ö‡[k¹–<|š(Ç*€Ý¹dÇtMé:Ýñø«Ø,êÅû¢]”' øXÓ_nò¡Æ|Øý /c§fžâOIEND®B`‚openchange-2.0/apidocs/html/mapitest/sync_on.png000066400000000000000000000015151223057412600220600ustar00rootroot00000000000000‰PNG  IHDRàw=øIDATxíÝ_HTYÀñï8ã¤ó§i§4-g6ÆËÕ&kQ)¨Ô!Š0ÒURKÚ…„ê¡/»PEÁ>ìK-+KÁ²Ñ.Y”¾dEPaA‰ø°¥¶›ZSÓïÜ;3wºŠ–¯—߯gfîïœsçœWKÇñ.€ÉøD­¨a‘'¬âq_ôˆk¢ÀŒ ÀDŽøQ´ÄïC¨¶åñÏÿgÅ ñ 0„Y‚:qZ¦Á)~õâ€èLý0HVñ× žz-¿‰C“%¨g¦˜6€é8%Úõ¬ëwêÙUÏ¿˜ª³Ä }? ?€·3ÀÀž©Š À”K• @hà a±ðaÇæUe‹ sù~ë2²ì“&Ú&B*AÄljæºììi*˨,Ëçí»÷oÆ£T”,d[˜¼3-*ÁÀ…>å‡Ë çLÉŸçfk˜Ò éw#*AEjKUy>ûšËÉõ&{µ¢8—m5Ki¬ jjƒD*¿NŽÖigwÃ7Dª’mz骹úKÛ¾±ˆ¶M!æ¤ÍkÐ?šoý¬_åÓlXí#Ò~–¸¬ê×ÒÑXŠÓ‘ùRÙ*Eû‚ՂדðEÜ;6«e"Q(²Ù=–¿Ezæ5Kؼָ_ 1òzBªJë ±XŒì96åªjL^7{ùãJÑ÷1½i@%8'7M©_\Qœ#ÓUŒËñýÿyõ Wo Éx8¼s¥v¯ªì|×SnÜ q_m Ýé î>bèÕí[JX,½4[Tú{R£ë¼ôˆ¾þa€tÝjjzzÅ'ÅìȶiIžŽòwÏs ¡€—ÕKøõâC^ŽŒ˜Y­¨µÉ%6¨´êˆº]vÛðhâ½iWv–hôëê°Ò¨¾'æÌ‚·ñ|[ßìúÅ^€YrD=<ýDû]äÇ÷s€Ïõ‹8™ºCì? À ¨—t4õᩎ¡Jã‡W‹É± îr¼cjMɘìx| šE©øNÔ‰œøA¢þ«–€Z¼ñ‡jó î#™§¢¢4gIEND®B`‚openchange-2.0/apidocs/html/mapitest/tab_a.png000066400000000000000000000002161223057412600214530ustar00rootroot00000000000000‰PNG  IHDR$ÇÇ[UIDATxíK €0C'o¤(Šˆ[Žà%Üxÿ#Ù©­ç ùÁöó¦W¦e# 3t I 3+¼øEã~\D½9¯Ûàè’wM·¿öÿ}Yõ_êA4Yžã}IEND®B`‚openchange-2.0/apidocs/html/mapitest/tab_b.png000066400000000000000000000002471223057412600214600ustar00rootroot00000000000000‰PNG  IHDR$ÇÇ[nIDATxíÝQ Â0„áàœR¥Xc±I7IÓ¨g|òÕÙœäãgY˜3˜Ï÷‡u{£ÔW—ÊSíŒ1Ü ¼CjˆiC†G¬ýççJ+| ÖÝs7ùŒ+Ù›`t‚3Ü‚a¢K¤Gq°ûQÍZÝT=@*éC݇LIEND®B`‚openchange-2.0/apidocs/html/mapitest/tab_h.png000066400000000000000000000003001223057412600214540ustar00rootroot00000000000000‰PNG  IHDR$ÇÇ[‡IDATxíÝË ‚@EÑ 7êÂX’Ñø AADùjGü€ Z€e؈£ ë8¹›—Wƒx¾ÞìUK.µ%„0mɤ&+4iÑ$džÈt“׿ÍzWf5AZá'w¼øÆ"2¶Wœðòg%öªdæ)æþ™ÉR15F®dìž ÉБßO«×Áô»C"à@¯g=IEND®B`‚openchange-2.0/apidocs/html/mapitest/tab_s.png000066400000000000000000000002701223057412600214750ustar00rootroot00000000000000‰PNG  IHDR$ÇÇ[IDATxíÝ ‚@@Ñ£?Q…¤"š¢%¦I‘—Šf–6[´HÃäQƒ<Þâõþ]ždr Í’s?ˆO=Ñññw'ÌF‡Ž íðö-~rÃ[œèŠ­ì¬mƒÖ¬ƒݯнŠÕF)Yº% §`nÌ,9B ™’©!ÑŒ\ý<Å#üîî•IEND®B`‚openchange-2.0/apidocs/html/mapitest/tabs.css000066400000000000000000000022131223057412600213410ustar00rootroot00000000000000.tabs, .tabs2, .tabs3 { background-image: url('tab_b.png'); width: 100%; z-index: 101; font-size: 13px; font-family: 'Lucida Grande',Geneva,Helvetica,Arial,sans-serif; } .tabs2 { font-size: 10px; } .tabs3 { font-size: 9px; } .tablist { margin: 0; padding: 0; display: table; } .tablist li { float: left; display: table-cell; background-image: url('tab_b.png'); line-height: 36px; list-style: none; } .tablist a { display: block; padding: 0 20px; font-weight: bold; background-image:url('tab_s.png'); background-repeat:no-repeat; background-position:right; color: #283A5D; text-shadow: 0px 1px 1px rgba(255, 255, 255, 0.9); text-decoration: none; outline: none; } .tabs3 .tablist a { padding: 0 10px; } .tablist a:hover { background-image: url('tab_h.png'); background-repeat:repeat-x; color: #fff; text-shadow: 0px 1px 1px rgba(0, 0, 0, 1.0); text-decoration: none; } .tablist li.current a { background-image: url('tab_a.png'); background-repeat:repeat-x; color: #fff; text-shadow: 0px 1px 1px rgba(0, 0, 0, 1.0); } openchange-2.0/apidocs/html/mapitest/todo.html000066400000000000000000000055161223057412600215420ustar00rootroot00000000000000 MAPITests 2.0 API Documentation
Todo List
Global mapitest_oxcprpt_CopyProps (struct mapitest *mt)
It would be useful to test the problem return values
Global mapitest_oxcprpt_CopyTo (struct mapitest *mt)
It would be useful to test the problem return values
Global mapitest_oxcprpt_DeleteProps (struct mapitest *mt)
It would be useful to test the problem return values
Global mapitest_oxcprpt_NoReplicate (struct mapitest *mt)
It would be useful to test the problem return values

Creative Commons License
Creative Commons Attribution icon Creative Commons Share Alike icon
This content is licensed under the Creative Commons
Attribution ShareAlike License v. 3.0:
http://creativecommons.org/licenses/by-sa/3.0/

openchange-2.0/apidocs/html/overview/000077500000000000000000000000001223057412600177205ustar00rootroot00000000000000openchange-2.0/apidocs/html/overview/24px-Cc-by_white.svg.png000066400000000000000000000053061223057412600241600ustar00rootroot00000000000000‰PNG  IHDR°çá»bKGDÿÿÿÿÿÿ X÷Ü pHYsHHFÉk> IDATXýXmP”U¾vˆeY pW$gQH–%ãËc*$åÃIkFmiØ‘ttrê‡C öa3 Œc†D$ e¬±X, «@³ Â.Èîõþy›uÓ÷·÷úóÌœçÜϹîëºçÜç<þxHØNÛNÛN½+zWô®.–_,¿X|»æÛ5ß® Q†(C`4F#p×ý®û]w@qRqRqðÿÎÿ;ÿcaÇÂŽIÅIÅIÅ@˜$L&Ämâ6qÛòÀ‡Ä-í-í--ùVë[­oµ’ <. … ¡B¨øSRT(*’’IŽ$‡”æHs¤9¤S’S’S‰ð>°Ï÷ˆôˆôˆ$Óôiú4=Ù2Ú2Ú2JZ•V¥Uù`^‚û9À3<Ã3À7ýßôÓl?Ø~°¸ªºªºªœ‡œ‡œ‡€ 6Øpx&õ™ÔgR0—0—0ÀMá¦pSB©P*”–õ–õ–õ@²GÙ£šª›ª›ª¦mMÛš¶#êõˆðj÷j÷jöeïËÞ— äÎäÎäÎÒ^i¯´÷að£ýȳégÓϦ“K{–ö,í±+¦êRu©ºÈŠÎŠÎŠNòöÔí©ÛSë£sñsñsñd{^{^{™u%ëJÖÒÅÛÅÛÅ›IER‘”ÔìÕìÕì%ÇSÇSÇS~gAuuu¤|µ|µ|5)øJð•à+rGËŽ–-äÀ±cÇþs‚å)ËS–§ÈÒ-¥[J·ž»=w{î&µ‚ZA-™÷BÞ y/³£³£³£‹$psäæÈÍR•¨JT%ÚßñýŽïw|OšÌ&³Éü¿'þWX­ÖFòÔ“§ž<õ$é6â6â6Bºæ»æ»æ“ÕÕÕ÷&°Ÿû¹Ÿ<”p(áP‚xxQxQxyëÀ­·üóÄÿŠùçœÿ‘Ô®Ô®Ô®´óŠx.⹈çÈÁÎÁÎÁN7ŽÜ8rã¹æÙ5Ï®y–tŠwŠwŠ'+++ÿÿÄÿŠã€qÀH¿üzðë¤(H$ "‹4Eš" ) ø0àÀ:³ñÌÆ3··7à é é  pNwNwN¦º¦º¦º€ZS­©Ö\K¹–r-èÎíÎíΆg†g†gOgOgOgÀ˜bL1¦õâzq½XÒ·¤oI SÊ”2%033TÿQýGõ€h§h§h'àëëkßdÜÜÝÜÝ܉sç&Î õ õ õÀ¸iÜ4n°uÕÖU[WÙ-*4š ©õ^^^r¹Ãr‡å¤S•S•SéêêJºMºMºM’»rwåîÊ%ûûûIE¤"RIîÙ¼góžÍäÜÆ¹sÉý'öŸØ‚”'Êå‰dÛ–¶-m[îï„N£Óè4¤ÇÛo{¼MŠä"¹HN {]z]z]Ñ:Ñ:Ñ:@¥T)UÊE¶Û!q¸k¾k¾k2e™²LÐÛÛ ¤½Ÿö~ÚûÀ¥ÉK“—&ÿVÿVÿV c.c.c¨­­Ê®•]+»œK>—|.ˆÔDj"5@[t[t[4 _ª_ª_ºpýÕΫW;>Y>Y>Y€õwëïÖ߈§ÄSâ)R'‰“Ä‘Í7›o6ß\¨€Ál0̤¼SÞ)ï$ƒR‚R‚RÈ—3_Î|9“ô³øYü,dÒ¤I7H‹ŸÅÏâGöÕôÕôÕAùAùAù¤Ä 1H dÈùó!çɲÀ²À²@R\".—Å?ÿTüÓÂõïîîÈ(×(×(W{Åç:æ:æ:¡£ÐQèˆÒDi¢´E:žAª U L©§ÔSj`$a$a$pLvLvL†¶mÚ VVV~‰~‰~‰À®_wýºëWÀrÄrÄrÈPf(3”ÀóåÏ—?_|ôÉGŸ|ô ·!nC܆E–o4 šQ¨(Tj*ŠÅŠb`V2+™•o‹·Å{±– ‚€5Ôj Ò­éÖt+P¡þBý ðzáõÂë@÷+ݯt¿èôú{x`c`c`#à~Úý´ûi À` °K>_òù’ϵ«ÚUí È5r\³È!2Ï–g˦ççÃïy}9úrôe»%%×K®—\_¤„ú }†>R!UHRò1ŸÇ|ó!ãZãZãZIe´2ZM.»³ìβ;d{{{¿=¾á†7Þ =.x\ð¸@Ö)ë”uJ²¥­¥­¥\öȲG–=B~œúqêÇ‹z²{²{²Iß}¾û|÷ÝSBª¯U_«¾¶'ÔTßTßTÌý6÷ÛÜoöqéyéyéyàÅÒK_,ÔoªßT¿ xj=µžZ F#‘'kOÖž¬B2B2B2ìñò+ò+ò+ÀK›^ÚôÒ&@Þ!ïw2³Ì,3¿Düñ  ($ ÉBt't't'€Á̓›7+›V6­lÐÜÜL>ŠGñ(Hï×¼_ó~¼úóÕŸ¯þ|5¬a iK±¥ØRH[€-À@Ú²mÙ¶l’{¸‡{þ¦#íænî&mkmkmkIÆ1Žq$ýéOÒ*° ¬Òö¥íKÛ—ö°™’™’™2ùpòáäÃvås r r H˜½Ì^f/r[Ö¶¬mYö Y]Y]Y]¤ùóæþávû7¨\W¹®r)žψgHŸ­>[}¶’º]‰®äžÃ\K]K]KéuÉë’×%Rü©øSñ§di|i|i#FQ`$c¼b¼b¼ÈŽ‹;.Þ_€^êg3f3f3Èʵ•k+×’êUêUêU¤Ãr‡åËIÇq'=4 ¹~lýØú12*+*+*‹ŒÍÍÍ'Ueª2Uéû®ï»¾ï’!!!v¥W„­[FjõZ½VO' ' '<ØÁ‡þ+ñ'†††È¢²¢²¢22\® ב2™ƒÌNèAOßbßbßb2Ç%Ç%Ç…ÔéuzžœŸŸx>ÿ^5¡–ü+^:tEXtComment Created with Inkscape (http://www.inkscape.org/) ã+ldIEND®B`‚openchange-2.0/apidocs/html/overview/24px-Cc-sa_white.svg.png000066400000000000000000000053061223057412600241510ustar00rootroot00000000000000‰PNG  IHDR°çá»bKGDÿÿÿÿÿÿ X÷Ü pHYsHHFÉk> IDATXÕX}LÓW>¿ ´–.Ôb±‚" Cèê(lS„9ÉuN&n ʹŒ,+&+™“à&3[a`Ë$™ãs‰3Ö¨L(ŠX¸Åñá¬EÄ4ElK¡åyÿy÷–¼µ/¾çŸ›ÜsŸsžûœÓ{· þmô”¶ðà?¬Y3²†èBý…ú õD—7\ÞpyÑpâpâp"‘Ñh4DóÏÌ?3ÿ QPmPmP-QØoa¿…ýFw"îDÜ ¢ŒÊŒÊŒJ¢8n7ŽKäwÃï†ß§eCDxJ3›ŠMÅÀgW?»úÙU ‚‰`"€Ä bý#À>Ê>Ê> p ¸Ü€WÀ+àË3–g,Ïèú†¾q¯Ø°%` ===è&tº ÀéŠtE.Í‹ñVœÁœ!ºxçâ‹wˆ>5|jøÔ@Ô#ë‘õȈ|Ç|Ç|Lj^,z±èÅ"¢m»·íÞ¶›(Žljãùùù±x,‹G4;;K499IÔÞÚÞÚÞJÔ¾§}Oû"s‚9Áœ@$4 BQa~a~a>Ñ!Û!Û!o„7Âyš ¬Çz¬ßi|§ñ`ÕЪ¡UCnÅdý²~Y?ÐÔ×Ô×ÔLÍLÍLÍÂGø8¶ãØŽc;ÜÄãËãËãËS‘©ÈTäxÏ®ž]=»€Wv^Ùy´ Z­SÏÔ3õ‹~Ü&¶‰mÄ_‰¿ ;v( 05›šMÍžqÝÎng7P¼¶xmñZwœ—^éõ—^îõÝë»×Ð`é`é`)°áµ ¯mx Xž²äeò2y™'ñA„ B”ØJl%6 nUݪºU€*Z­ŠÄÄÄ“Ïä3€å[Ë·–o½ãq·qØkÝkÝkõl¥ÏÕŸ«?W{Â?~< $®H\‘¸Â½Þg®w®w®—ˆ³Œ³Œ³ŒˆÍÎfgQuQ—§¯È_‘¿"'Ò˜5f™Hë¯õ×úûëØ_Çþ"âïçïçïÿß.ëi=­'ò©õ©õ©õtϧϧϧ{Î3LÓAÄ–²¥l)éHG:"VPePeP%‘ƒëà:¸D³³³ÞóOØ'ìv¢Õ©«SW§åìËÙ—³È,7ËÍr"G…£ÂQá?—7—7—G4ùóäÏ“?{ú\WÀõœ_P-¨TDÖxk¼5~‘ckçÖέî’TýQõGÕÞ;à|Öù¬óY@ÀÉ€“'Þ:Þ:Þ:@œ&N§cccÞñÝ‚nA·ý$úIô“;/š?ÍŸtƒºAÝN¡¡ü¡ü¡| ¤0¤0¤pQë}RôIÑ'¯³¾ÎúpŒ9ÆO 2Z3Z3ZÄŒ9s㇓w%ïJ޴ŶŶÅwDwDwDÀÅ÷/¾ñ}`Ëw[¾Ûò'îÍóožó<`}×ú®õ]ϼgfÏÌž™XZ––¥Ö¶¯m_ÛP‡¤CÒ!$ ~ø!ÐógÏŸ=zW²V]«®Uœ:N§n¡(Š¢(À?Ê?Ê? Í Í Íxž…gñ$ê u…º€®³]g»Îzæ±UÙªlU€¼D^"/Yto¨ Ôj€ìB»Ð.ö(ö(ö(Ü ýŠ~E?`ï²wÙ»<;„¡ChÞм¡y±D,ë 7ò¬V +Ø”»)wS.pI}I}Ií]¨æèæèæhÀÏægó³Á™Á™Á™€¾J_¥¯Zô1§Óê´:- ¼"¼"¼ø}ï÷½ß÷@uJuJu àZp-¸<8wþîü0ì7ì7ìJ5¥šR ùwæß™ÛÓ·§oOÞî|»óíNà”ñ”ñ”ý–ý€~@Äì‹Ù³Ï-@qqq?° ].HmÀ5åšrMǧOŸXm¬6V°²deÉÊàtÆéŒÓ€óWç¯Î_½'F ZÐ8ßs¾ç|˜+Ÿ+Ÿ+\®W€ILbÒ;ü¦ô¦ô¦ØÜ°¹asƒ›xÒñ¤ãIÇñeãËÆ—¹×{¼   ¥F©QjV:+•ð[ø-ü@=®W÷ÎÝ;wïÜÒ„–2[Ž-Ç–4O7O7O76nlt—<”<”<zózózó<ñ^ßÄ–dK²%PVVx¾<_ž/À\b.1—I¶$[’ |Éÿ’ÿ%Ðwê;õÀdÅdÅd` ³†YÃk‹µÅÚÌlÙ:³>0|`øP¯®W׫ù«òWå¯Ü:n·`ŒŒ‘1IÂ$a’è½Ð{¡÷‚w–|Ô;ö:ö:öÍÏ7?ßü<šš øˆ}Ä>b€4¤!   P(ØÉØÉØI Q‘¨HTÉG’$d5²Y r2ädÈIÀçŸ|^p+½&nMÜš8 x x xß1¾c|ÇÒ|ê%þ±±gÇž{(¯)¯)¯âõñúx=àÃ÷áûð—>…þC*C*C*N§€èôúÀ™âLq¦<=ŸYΧюéÈ:tEXtComment Created with Inkscape (http://www.inkscape.org/) ã+ldIEND®B`‚openchange-2.0/apidocs/html/overview/CC_SomeRightsReserved.png000066400000000000000000000064521223057412600245660ustar00rootroot00000000000000‰PNG  IHDRZ¬a x pHYs  šœtIMEÕ ÌIðbKGDÿÿÿ ½§“ ·IDATx^í™iŒUEÇû¾{ßÚÝ6ë"²Š‚@!`˜DÇ¡Ä "Œ2 ×%Æ(ê—D£ñƒ1¨â’Œ@Pƒ¢HezXš¦é†¶~¯ßrç÷ïÜêyV¼ 1í„VòçÔz«þuêÔ¹÷9%¿Nr@$Bd\ºP¤Ç¤KˆÒ•HD€’È|² È h‘,Ò›= lœ)Ò›Íøí´2$Ù"ír«,n¤…˜Õ?À+B¸4d¤à `d‘ž—Þ†vL‘_‰h×&By#Äl ,‹OHIÚyû¤Ø°N‡¤g¡èäÒùnÑ‹0 g­Kë!í i6IÁ¶dËŠ…‚bÉFÝ?Ÿ-ÚŠ°áÙ–eÈO&“‰gŸ}vä–-[¦œ8qâŽ\.7çÌ™3Ó÷ìÙ3áý÷ß¿büøñÝdÉňÅb©Ç{lÐ÷ßÿ‡ãÇÏ ÏÜæææ¿8p`ÎòåË+§L™ÒËz– {®ƒö½´Ú?Å­cݦ[e‰â²áÇw]¶lÙ´¾}ûBfxrçfÞ_|±»bÅŠ!ƒ *ÿ}]xÍÒ’V™OŸï ¤­{–.¸Xrì“O>ù“!yûöí 7ß|óêT*õwÊÖ<óÌ3ûNž<™S]±%Óg˜!yóæÍM7ÞxãÚÒÒÒ¥lÀâW^yeÝéÓ§3ª3Ï q5nHÞÎW‹ŽXVœ ½ÄŒ/¾øâè|p¢Ø·o_ãСC¿J§Ó­‘ˆÁ€Ê>ûì³—^ziµÚÍŸ?¿âÕW_í!}çΧG޹9“ÉüÄZ9%.}*{öì¹ð,–kK»¬p>Z´‰s£[å6\ÉÊÊÊ¡f€—_~ù_±#“½{÷:|ÈlÒ­·ÞÚÁôyþùç Ù³ýð¶mÛÒ¼È ýG2$ïXh—äµ?Ñá °7£OŸ>ÝÍøéc¶»Q+êp±ú˜é³råÊûb³78¶ 1Ë@Îï8ڱɷõb²ñÑqÓøÈ‘#9Ûê‹`ÜI²¢¢¢mîÇŽioŠÉ ß\#C²†óÐu„è>ˆ„µÃU´˜L÷îÝcöÆXäy Ååè›>;wöl²Î‘<'l íî:|ßïÐ^ƒmܸÑûâ‹/R555‰£G&!#ÉÍŸjiiI€$~4‘ÍfS<3U(ù|>!YWW÷Ã%—\ÒScÜvÛm=Þyçã´ñ€ "À´a¤<²y×®]±Ñ£G»êsÓM7¥/^|š0γD"qd©)D£Ñ‚ëº>(ñ<Ï!ïÁD€KÄâ^pÁ^×®]½þýûGG»æšk²í壎hÿ—ì&t¯ºêªDÇŽSç/‰ü1Á DB„Cr²“È/ñï¾û®Ú=oÞ¼Á«V­Ú€•»l‚ ’ýnݺ9o½õVçIˆË}ùå—ˆ.UŸ‡z¨ÓºuëWsvIž€ï/ýõ×õÒò7òˆ|P"‚ãñx+ɉDB$ srª¢½{÷Ž:êtåI¿”§VKqöÆç>8dF°4Y³‡èä©S§â”'xÃK@r\0dƒ¸ÈfÑ©×^{m . \ãa_¸pa͆ 2eee¥×]w]§Ù³gwÁÚ´‘GÔF$}øá‡{õêå)_UUuúÍ7߬ٺuë:uÊOœ8±ãÔ©SB^ ‹ÿ+äf »b3œ¡:@†x= Ùiü~¦C‡é.]º¤ÙØ QN3ýE´c‘z.ût Ñã• 'ôÜwÒœC‡űæ8¯Ã²è˜ˆ†ä¸¬ZRD$Çò²êaX—ûî»od—…ÎÜ÷Kn¸á†ƒÈV]ÀêܧŸ~ºë…^;[Ÿ»îºk‘!¤A‹ò\ÂÑ­`#Óll Va61­S`Nz8ܧžzêrë±Ñ%amŠÛâE`)$¤°ž$H±¨V“ÿMqEJÒYd î¯]»¶™§Øƒÿ›P¨¯¯ÏàN¾ñÆGñë9Ú°´zvÍš5M¸™,㔀ˆéÓØØxŠ7ÌÚ?þx#d·@bIyy¹ƒŒX¯ "Pç"=ê$]¤GY4„#Ût›3ÆG;ç°3þ9„>>ĉ´$DuAZ ×!b£" –%G%!$J[å¥{HwQ © ô­KQÒEF°´¶èEV òëׯo¤_=$çØì2+ g±È,® Ɔ—°yÅ £ e¾Ñ6/ÊI?%&)’€hî£ëtt´^~ä}‘Œlõ딹ä[A>á’Q ’uZZ@–òlȧÒPÂmiÝ1”àp_ä‡í¤Êb<‘*²Ñ•$[‰ HÑ’Ê»"2% Éå!URd;"8€X³’¤A„ä—ä{$‘/QˆDIr³Áüäzb¤2«r…ƒg#ÖÒC91á]…UîôIaÖl„N^£+ŽÕÊÛˆ’Fò’&/˜ÐN1´¤±nG©Øª€acÝH§ØºE0R¹²æ"Œ/=t?´¡`.ÄšM:«±àDæÎ;ž[ÎsÏ=7’ ©O¿~ýoûh#Øåy›6mêÅGšÞ¯{T¦~Lêµ½þúë')o±^N})Ÿ9ï Þüî»ï*ÔJ¦HcÇŽ­ä¢Ià³Ëˆ›¯ tÅÇû¡„V1.¢èôéÓ/G÷„Ûo¿}0Ò%Vî?cÆŒA?üpß%K–t&Bé‡/¯Ï&JP[éJÖ¼ûþùç=xNœ‹-~íµ×þž—¡±<çwšÃK/½4Œ²Ê÷Þ{oëÓúèÞξ¥s eKu¤¦M›¶öJW;AþLõÒ L×°Œpn¹üŸ1WCBšèá«Ã‡¯¡,W]]ý-ñmý#zTܨêŠ]ª)ã›ù)Þ./“.‹Þüõ×_ïâm*Ë—³²œÊ£ó Ü|°wÑ¢E²¦¶zŽHžÎ°ÓÊÛàRÛ*ÿ©yŽì¼*^`ªd‘¼Ììfü<ñî>\×q^:²lÈA¬þ ãØ"H¯­­=Ì‹Pý ’K—.=¦·?Œ¢^yÕ ¤Z¾›R‘Ìiiâ µ«Ý¯2æšÁ5œàÌ.>­V3FÒªpaÛ5Oꛃµl1ëÓéxüñÇkUÆÿ’UãÆ;‰;Ép¯l ã@ÙŠèý úÉ'Ÿlš5kÖIÞós¼Å€”ê=zäT/BL;£•W Ê[¨D*ǹŽ;@ãÖæRúa&œƒ˜zȯg¬ßEØ€£ÒqeÇ8ÒÒ% I—ظ33gÎLKW½ú©þ»‰gæÉ7˜ñ±ò:=bk™GíO%ƒŽñ}CãÙQQ mEõLŽzÏÌ«LÏ4m!ÚçBup›)½ä´­Å¬¿ÃÊÇá.è7±ÏÅáCŒÏDýÝ»wûJøÈVië,ºµíœ9s|;Ùí¹©}.Ÿ”aŒ>dû,ÆçHZ}Btk¾çöL{®öv}ø8Òq¡¡˜²!C†ø&Lðq]¾DÿÊé7üFôÿÿj|w‚%&IEND®B`‚openchange-2.0/apidocs/html/overview/apidocs.css000066400000000000000000000362151223057412600220630ustar00rootroot00000000000000/* ** WEBSITE ** */ BODY,H1,H2,H3,H4,H5,H6,P,CENTER,TD,TH,UL,DL,DIV { font-family: Geneva, Arial, Helvetica, sans-serif; } BODY,TD { font-size: 90%; } H1 { text-align: center; font-size: 160%; } H2 { font-size: 19px; font-weight: bold; color: #3E93D5; } H3 { font-size: 100%; } P { text-align: justify; } LI { li-style-type: square; li-style-position: outside; display: list-item; } CAPTION { font-weight: bold } DIV.qindex { width: 100%; background-color: #e8eef2; border: 1px solid #84b0c7; text-align: center; margin: 2px; padding: 2px; line-height: 140%; } DIV.nav { width: 100%; background-color: #e8eef2; border: 1px solid #84b0c7; text-align: center; margin: 2px; padding: 2px; line-height: 140%; } DIV.navtab { background-color: #e8eef2; border: 1px solid #84b0c7; text-align: center; margin: 2px; margin-right: 15px; padding: 2px; } TD.navtab { font-size: 70%; } A.qindex { text-decoration: none; font-weight: bold; color: #1A419D; } A.qindex:visited { text-decoration: none; font-weight: bold; color: #1A419D } A.qindex:hover { text-decoration: none; background-color: #ddddff; } A.qindexHL { text-decoration: none; font-weight: bold; background-color: #6666cc; color: #ffffff; border: 1px double #9295C2; } A.qindexHL:hover { text-decoration: none; background-color: #6666cc; color: #ffffff; } A.qindexHL:visited { text-decoration: none; background-color: #6666cc; color: #ffffff } A.el { text-decoration: none; font-weight: bold } A.elRef { font-weight: bold } A.code:link { text-decoration: none; font-weight: normal; color: #0000FF} A.code:visited { text-decoration: none; font-weight: normal; color: #0000FF} A.codeRef:link { font-weight: normal; color: #0000FF} A.codeRef:visited { font-weight: normal; color: #0000FF} A:hover { text-decoration: none; background-color: #f2f2ff } DL.el { margin-left: -1cm } .fragment { font-family: monospace, fixed; font-size: 95%; } PRE.fragment { border: 1px solid #CCCCCC; background-color: #f5f5f5; font-size: 11px; margin-top: 4px; margin-bottom: 4px; margin-left: 2px; margin-right: 8px; padding-left: 6px; padding-right: 6px; padding-top: 4px; padding-bottom: 4px; } DIV.ah { background-color: black; font-weight: bold; color: #ffffff; margin-bottom: 3px; margin-top: 3px } DIV.groupHeader { margin-left: 16px; margin-top: 12px; margin-bottom: 6px; font-weight: bold; } DIV.groupText { margin-left: 16px; font-style: italic; font-size: 90% } BODY { background: white; color: black; margin-right: 20px; margin-left: 20px; } TD.indexkey { background-color: #e8eef2; font-weight: bold; padding-right : 10px; padding-top : 2px; padding-left : 10px; padding-bottom : 2px; margin-left : 0px; margin-right : 0px; margin-top : 2px; margin-bottom : 2px; border: 1px solid #CCCCCC; } TD.indexvalue { background-color: #e8eef2; font-style: italic; padding-right : 10px; padding-top : 2px; padding-left : 10px; padding-bottom : 2px; margin-left : 0px; margin-right : 0px; margin-top : 2px; margin-bottom : 2px; border: 1px solid #CCCCCC; } TR.memlist { background-color: #f0f0f0; } P.formulaDsp { text-align: center; } IMG.formulaDsp { } IMG.formulaInl { vertical-align: middle; } SPAN.keyword { color: #008000 } SPAN.keywordtype { color: #604020 } SPAN.keywordflow { color: #e08000 } SPAN.comment { color: #800000 } SPAN.preprocessor { color: #806020 } SPAN.stringliteral { color: #002080 } SPAN.charliteral { color: #008080 } .mdescLeft { padding: 0px 8px 4px 8px; font-size: 80%; font-style: italic; background-color: #FAFAFA; border-top: 1px none #E0E0E0; border-right: 1px none #E0E0E0; border-bottom: 1px none #E0E0E0; border-left: 1px none #E0E0E0; margin: 0px; } .mdescRight { padding: 0px 8px 4px 8px; font-size: 80%; font-style: italic; background-color: #FAFAFA; border-top: 1px none #E0E0E0; border-right: 1px none #E0E0E0; border-bottom: 1px none #E0E0E0; border-left: 1px none #E0E0E0; margin: 0px; } .memItemLeft { padding: 1px 0px 0px 8px; margin: 4px; border-top-width: 1px; border-right-width: 1px; border-bottom-width: 1px; border-left-width: 1px; border-top-color: #E0E0E0; border-right-color: #E0E0E0; border-bottom-color: #E0E0E0; border-left-color: #E0E0E0; border-top-style: solid; border-right-style: none; border-bottom-style: none; border-left-style: none; background-color: #FAFAFA; font-size: 80%; } .memItemRight { padding: 1px 8px 0px 8px; margin: 4px; border-top-width: 1px; border-right-width: 1px; border-bottom-width: 1px; border-left-width: 1px; border-top-color: #E0E0E0; border-right-color: #E0E0E0; border-bottom-color: #E0E0E0; border-left-color: #E0E0E0; border-top-style: solid; border-right-style: none; border-bottom-style: none; border-left-style: none; background-color: #FAFAFA; font-size: 80%; } .memTemplItemLeft { padding: 1px 0px 0px 8px; margin: 4px; border-top-width: 1px; border-right-width: 1px; border-bottom-width: 1px; border-left-width: 1px; border-top-color: #E0E0E0; border-right-color: #E0E0E0; border-bottom-color: #E0E0E0; border-left-color: #E0E0E0; border-top-style: none; border-right-style: none; border-bottom-style: none; border-left-style: none; background-color: #FAFAFA; font-size: 80%; } .memTemplItemRight { padding: 1px 8px 0px 8px; margin: 4px; border-top-width: 1px; border-right-width: 1px; border-bottom-width: 1px; border-left-width: 1px; border-top-color: #E0E0E0; border-right-color: #E0E0E0; border-bottom-color: #E0E0E0; border-left-color: #E0E0E0; border-top-style: none; border-right-style: none; border-bottom-style: none; border-left-style: none; background-color: #FAFAFA; font-size: 80%; } .memTemplParams { padding: 1px 0px 0px 8px; margin: 4px; border-top-width: 1px; border-right-width: 1px; border-bottom-width: 1px; border-left-width: 1px; border-top-color: #E0E0E0; border-right-color: #E0E0E0; border-bottom-color: #E0E0E0; border-left-color: #E0E0E0; border-top-style: solid; border-right-style: none; border-bottom-style: none; border-left-style: none; color: #606060; background-color: #FAFAFA; font-size: 80%; } .search { color: #003399; font-weight: bold; } FORM.search { margin-bottom: 0px; margin-top: 0px; } INPUT.search { font-size: 75%; color: #000080; font-weight: normal; background-color: #e8eef2; } TD.tiny { font-size: 75%; } a { color: #1A41A8; } a:visited { color: #2A3798; } .dirtab { padding: 4px; border-collapse: collapse; border: 1px solid #84b0c7; } TH.dirtab { background: #e8eef2; font-weight: bold; } HR { height: 1px; border: none; border-top: 1px solid black; margin-bottom: 50px; } /* Style for detailed member documentation */ .memtemplate { font-size: 80%; color: #606060; font-weight: normal; } .memnav { background-color: #e8eef2; border: 1px solid #84b0c7; text-align: center; margin: 2px; margin-right: 15px; padding: 2px; } .memitem { padding: 4px; background-color: white; border-width: 1px; border-style: solid; border-color: #ccc; -moz-border-radius: 8px 8px 8px 8px; margin-bottom: 30px; } .memname { white-space: nowrap; font-weight: bold; font-size: 12px; margin: 10px 10px 10px 10px; } .memname EM { color: #45417e; } .memdoc{ padding-left: 10px; padding-right: 10px; } .memdoc EM, TD { font-size: 12px; } .memproto { background-color: #e9e9f4; width: 100%; border-width: 1px; border-style: solid; border-color: #ccc; font-weight: bold; -moz-border-radius: 8px 8px 8px 8px; } .paramkey { text-align: right; } .paramtype { white-space: nowrap; } .paramname { color: #602020; font-style: italic; white-space: nowrap; } /* End Styling for detailed member documentation */ /* for the tree view */ .ftvtree { font-family: sans-serif; margin:0.5em; } .directory { font-size: 9pt; font-weight: bold; } .directory h3 { margin: 0px; margin-top: 1em; font-size: 11pt; } .directory > h3 { margin-top: 0; } .directory p { margin: 0px; white-space: nowrap; } .directory div { display: none; margin: 0px; } .directory img { vertical-align: -30%; } #website { width: 820px; height: 100%; margin-left: auto; margin-right: auto; text-align: left; /* IE hack */ * position: absolute; * left: 50%; * margin-left: -410px; } /* ** HEADER ** */ .header { height: 200px; background: url(header.jpg) no-repeat top center; } body { background: #fff url(body_top_bg2.jpg) top left repeat-x; font-family: Arial, Trebuchet MS, Tahoma, Verdana, Helvetica, sans-serif; font-size: 11px; line-height: 17px; color: #444; color: #3a3a3a; fdpadding-top: 15px; text-align: center; background-color: #fbfbfb; } h1 { font: 24px bold Trebuchet MS, Arial; color: #FFF; padding: 0; margin: 0; } /* ** MIDDLE SIDE ** */ #middle_side { display: block; height: 100%; width: 800px; margin-top: 7px; backsground: url(middle_bg.jpg) top left repeat-x; background-color: #fbfbfb; } /* left and right side */ #left_side { background-color: #fff; clear: both; margin-bottom: 10px; border-bottom: 1px solid #eee; border-left: 1px solid #eee; border-right: 1px solid #eee; -moz-border-radius: 0 0 8px 8px; height: 29px; } /* ** MENU HORIZONTAL ** */ /************ Global Navigation *************/ DIV.tabs { float : left; width : 100%; background : url("tab_b.gif") repeat-x bottom; margin-top : 10px; margin-bottom : 4px; } DIV.tabs ul { margin : 0px; padding-left : 10px; list-style : none; } DIV.tabs li { display : inline; margin : 0px; padding : 0px; } DIV.tabs A { float : left; background : url("tab_r.gif") no-repeat right top; border-bottom : 1px solid #84B0C7; font-size : x-small; font-weight : bold; text-decoration : none; } DIV.tabs A:link, .tabs A:visited, DIV.tabs A:active, .tabs A:hover { color: #1A419D; } DIV.tabs SPAN { float : left; display : block; background : url("tab_l.gif") no-repeat left top; padding : 5px 10px; white-space : nowrap; } DIV.tabs TD { font-size : x-small; font-weight : bold; text-decoration : none; } /* Commented Backslash Hack hides rule from IE5-Mac \*/ DIV.tabs SPAN {float : none;} /* End IE5-Mac hack */ DIV.tabs A:hover SPAN { background-position: 0% -150px; } DIV.tabs LI.current A { background-position: 100% -150px; border-width : 0px; } DIV.tabs LI.current SPAN { background-position: 0% -150px; padding-bottom : 6px; } DIV.nav { background : none; border : none; border-bottom : 1px solid #84B0C7; } #right_side_home { font-family: "Lucida Grande", Arial, Verdana, sans-serif; background-color: white; padding: 0px 20px; border: 1px solid #ebebeb; border: 1px solid #ddd; -moz-border-radius: 10px 10px; width: 750px; * width: 800px; * margin-left: 0px; padding-bottom: 10px; } #right_side_home td { line-height: 17px; margin: 0 0 5px 0; padding: 10px 0 15px 7px display: table-cell; border-spacing: 2px 2px; vertical-align: middle; text-align: left; border-bottom: 1px solid #EEEEEE; } #right_side_home td h2, a.anchor { font-size: 19px; font-weight: bold; color: #3E93D5; } #right_side_home td.indexkey { border-bottom: none; } #right_side_home li { list-style-position: inside; valign: middle; } TD.indexkey { background-color: #e8eef2; font-size : 12px; font-weight : bold; padding-right : 10px; padding-top : 2px; padding-left : 10px; padding-bottom : 2px; margin-left : 0px; margin-right : 0px; margin-top : 2px; margin-bottom : 2px; border : 1px solid #CCCCCC; } TD.indexvalue { background-color: #e8eef2; font-style : italic; font-size : 12px; padding-right : 10px; padding-top : 2px; padding-left : 10px; padding-bottom : 2px; margin-left : 0px; margin-right : 0px; margin-top : 2px; margin-bottom : 2px; border : 1px solid #CCCCCC; } TR.memlist { background-color: #f0f0f0; } .mdescLeft { padding: 0px 8px 4px 8px; font-size: 80%; font-style: italic; background-color: #FAFAFA; border-top: 1px none #E0E0E0; border-right: 1px none #E0E0E0; border-bottom: 1px none #E0E0E0; border-left: 1px none #E0E0E0; margin: 0px; } .mdescRight { padding: 0px 8px 4px 8px; font-size: 80%; font-style: italic; background-color: #FAFAFA; border-top: 1px none #E0E0E0; border-right: 1px none #E0E0E0; border-bottom: 1px none #E0E0E0; border-left: 1px none #E0E0E0; margin: 0px; } .memItemLeft { padding: 1px 0px 0px 8px; margin: 4px; border-top-width: 1px; border-right-width: 1px; border-bottom-width: 1px; border-left-width: 1px; border-top-color: #E0E0E0; border-right-color: #E0E0E0; border-bottom-color: #E0E0E0; border-left-color: #E0E0E0; border-top-style: solid; border-right-style: none; border-bottom-style: none; border-left-style: none; background-color: #FAFAFA; font-size: 80%; } .memItemRight { padding: 1px 8px 0px 8px; margin: 4px; border-top-width: 1px; border-right-width: 1px; border-bottom-width: 1px; border-left-width: 1px; border-top-color: #E0E0E0; border-right-color: #E0E0E0; border-bottom-color: #E0E0E0; border-left-color: #E0E0E0; border-top-style: solid; border-right-style: none; border-bottom-style: none; border-left-style: none; background-color: #FAFAFA; font-size: 80%; } .memTemplItemLeft { padding: 1px 0px 0px 8px; margin: 4px; border-top-width: 1px; border-right-width: 1px; border-bottom-width: 1px; border-left-width: 1px; border-top-color: #E0E0E0; border-right-color: #E0E0E0; border-bottom-color: #E0E0E0; border-left-color: #E0E0E0; border-top-style: none; border-right-style: none; border-bottom-style: none; border-left-style: none; background-color: #FAFAFA; font-size: 80%; } .memTemplItemRight { padding: 1px 8px 0px 8px; margin: 4px; border-top-width: 1px; border-right-width: 1px; border-bottom-width: 1px; border-left-width: 1px; border-top-color: #E0E0E0; border-right-color: #E0E0E0; border-bottom-color: #E0E0E0; border-left-color: #E0E0E0; border-top-style: none; border-right-style: none; border-bottom-style: none; border-left-style: none; background-color: #FAFAFA; font-size: 80%; } .memTemplParams { padding: 1px 0px 0px 8px; margin: 4px; border-top-width: 1px; border-right-width: 1px; border-bottom-width: 1px; border-left-width: 1px; border-top-color: #E0E0E0; border-right-color: #E0E0E0; border-bottom-color: #E0E0E0; border-left-color: #E0E0E0; border-top-style: solid; border-right-style: none; border-bottom-style: none; border-left-style: none; color: #606060; background-color: #FAFAFA; font-size: 80%; } code { display: block; width: 100%; border: 1px solid #ccc; background-color: #e8edf3; padding-top: 10px; padding-bottom: 10px; padding-left: 5px; padding-right: 5px; margin-bottom: 10px; margin-top: 10px; } openchange-2.0/apidocs/html/overview/bc_s.png000066400000000000000000000012501223057412600213320ustar00rootroot00000000000000‰PNG  IHDR /ð9ÐoIDATxíMLAÇßìN»»¥ívKùPJik±R5^ŒChÂŃ!Dzƒ *U4VƒbÄD1~`8xà@ˆ^¿?ð𤡸Ý@јÝná`JLLÝØ¦ƒÜXi v«9ê)·}aV±&Ò0)›¼ð(‰zÛküNcFPÛù'@é¨KZK%!13§5£}Ý€ÒdÀã°’>´Åç´çhï¹G…ÉZ ïz×Ú—Éi£“ì–º=…@O¹«È‚1Ó¯¦3ãF«[ºä’d²¾JÒã`|^3˜Ý\›¿¡]²ó•'fçÓùyˆÄîçâÙ@¥Cos˧d:?$lhûnÝ× nm\†$cÔL6Ñý »Ì´x@N¦oPÀ®Î‘òÕ”€GÔ÷>9¹¨Q@ã±á“.‡qŠÜ´¼°Ø ”PCt(á«yŒQ$±°hÔNý8¤¥Ë MNjÿ$þßþŲo_ƒsLIEND®B`‚openchange-2.0/apidocs/html/overview/bdwn.png000066400000000000000000000002231223057412600213550ustar00rootroot00000000000000‰PNG  IHDR5åZIDATxíË € DŸP–1ñlžmÀ r±j².e è†D[ØÉ¾ÙÏÔ¼µ¦ã´Þ|陣6€Všë3´Å?Ls'(}¬>+ žKó÷¥¿ch`‚ ^׃ÞnIEND®B`‚openchange-2.0/apidocs/html/overview/body_top_bg2.jpg000066400000000000000000000006541223057412600230000ustar00rootroot00000000000000ÿØÿàJFIFddÿìDuckydÿîAdobedÀÿÛ„ÿÀ–ÿÄh að¡q‘QáR’¢ð!‘1aQÿÚ ?Ô¢±Õœ|W¼ í|ua³Dbe­‚hŒ*ø VÁ&ÅrV¹´,¸^Â-~TbÁÐéÊ—=©xj䮤*ÿRb²r %7L‘ñÜŠ¶5ø¦ èªÞV¶ ÿÙopenchange-2.0/apidocs/html/overview/closed.png000066400000000000000000000002041223057412600216730ustar00rootroot00000000000000‰PNG  IHDR à‘KIDATxíÝm @!†ÑGk™É7À-`&séts¦Àñþòð@åk}ª2€… P%Á_Ëþ¿N² .:0Dk¥‹Â›x" Ö›)¡xÒ5õIEND®B`‚openchange-2.0/apidocs/html/overview/doxygen.png000066400000000000000000000073031223057412600221060ustar00rootroot00000000000000‰PNG  IHDRh ;ˆØŠIDATxí]y\•Õº~45%TL Q”PE"q–Û11±]8a„w*©¨(*â" ˆzÀè`8 ¨‰¢mÅ,’òà„p$%”œBó(8k†Ü÷ýÜû6lòö»§k÷Ç÷[ÏÞß·Ö;?k½ëßÕÕÕPxÑêÏ't´ÏùÈ€zÀÇÅ3_€Q4€g@œmÿ ¾ò‰âci‰ôçÿ{ ðÇð¬ù~½Á€4:õHcÂü ðŸÁ³„ª'ÕPÆæ P7^h،♠zb„cóP¨„ 3‚† Ò}çÿO²qÁºNkÝTÛ(É?d Ç~z<’«4Óǡ؞Þv­zµÙ¦õ¬ZâdÛ,Ë6Ók±]Fz< ¾ZçƒsÕ?ìƒsUø2SÉåwê1”c`[ì—}%ѽ.Ô¼6‚BLZ˜û!F8[ ¹…×TéÛ— »Þ#gó]å:vžu?‡vèbÙR˜?wùŽŸ¾ÊÐgbÑÉÌÕ$kF~Ê;عÆ•¢ïX®?ÉèlÆÙôõà»Nʪ¼­,ìHC§gAz•ÆlÓº­gÑú ]œjÎñåM…3ÓÚæoÒ³'=‘$Ò÷f}G•ŸS_‡öèco.Êȹ :ó£ Ãds®Ù:1=¼{ƒå9?÷ý…zqÛvîÓi‰D’p¿Ë šmÙíoÛâýaÖüEqÒµwÌ}¿~{òj€ç{ôºŸFNëí[ëOq·ÇOSúXO]°>‚‚muæÄ¾e¤“5Ë{¨JÕ¯£(›´«bÂçû’ÍlÓÅ}žïú`éUÞy„ac§Á†ÔCºŠóAkl‘±y¥†ô¢ùôs÷Aø¬7ÄõôoJ±äÄ ù.¥Be. Z¬Ð×ÇÈöå¹­ù'Ù-PëìŠyF.ž‚žÝÚ€lp&.êˆð•jò7’re’z19»ã§HGíø%œüq°ïüz׈c¬_k_")ŸHJnÐÑ~ˆÐÖ˜á´äÕ5 µÁq€ÿ5#¸·îà¶+9T‘‚ ðŽ÷Rܸrz“Ï´Ì =Ï…{ðáO£Èf ¡Íwg|Ž’Ü/¢Þ$÷¯¢ëðúÀ;¿à¨Ö™âÒÆ­]¯ÜW"Þ/< ‡÷DÏà°½üB}çyIEc^—ƒ=[V“Ýh²ëMä$l];Kû®¸ýr¦È*Åò ÿtÒõ$]•MŸ÷´;×I€1èó!‚œõ¸M õ¨(fÌæ<ÁÎÎò5~z¿ù¶ž mÌêÕ >–âÚ©âëˆIÎÞçz;ãu[i·eç^ÆÜÙÓ³NÞëF6B\}7†»+üŽÓ,Ã'a ½˜-yHY¿,‘^—ñfú~ß?Hcø¸…¸ñó{Z+4\såƒû·¯Ù·nߣð«íFÆ¡sغëû§D¾?ò<–Ævkx0ÅM±ælذÁIÓxÿd”žÜÉ÷EE»AªM«g*È£YEí7Û™^[uíý®v[wGå†=Ed¼n×¶ÆæÖÅl¡'¨pGÚk+‹æ¢À¬¨C8ªâš2 dz3H£ß ¡¨BÒûSÃÅù[wŘ ~xpçútÁæmö¤Å£¥iQæ­‰AB1ÉfÙ‰›4u¹ïìIÒ]Ë6äò%ÿ†† 1t.’NJph¬zÌ ÎR1Ž"3-"¸‡‹&ìó°1âüžìó[:‡ï„¼‘……N m–“W0®_èÜœ ×õ6ùò&»)Æìꦬýæ}¬ñ~»{múù]z½£M•ºP~^Îá:eQTÙ_*7ÕÄ9É8—·Ëï 3°¶47E•î¿u÷“SÉ»U¯ _ NíºôW¬e¸ÄNÓ|»;™¿;ŒæÅd"ȉôøòÞµõï¾®½"èÄ´ÖMM+bYµ‘_ÉæEÝüÎ]P»¹XKÐI½Þ¥oE<_¹(„EP±Œ|mÇÁ¡‘Ý,ŠÓ©ººZ±Îߺ§×kÝ,kÍMš`Äø…jzeU»æ ™Át3ÓÀ½˜6—ÒöùË·r¨¹Ñ}““wö:Χùë¼ ¿|‚TܵÉQˆKßç_ÁâÀ™œ”pÑÐóໃ¼Ydâ0!®àa –øöçW$ÃÁ‘Á$/\¬$ð 2ÞímÞLH‹Ÿ èd£HVÜ,:ò½»RÍZšJ­a„z*>‹_…NT(ù‚^SVF­U¹8ñEþôñ܈óùnd;«®8™\C]ø=Èêm¬Æ:‚´ÆbãDd=Áãßžˆ‹UU5O‹|]þð®Pèêv‰á\]2ßìÿ"yÈ[ïyʧz£g{Y«{„Ùø5©ÿ;w{N3é­nâĨw§Á¢ÍK¢Ý­ûÏ29Id¿’ì y)ìPÞò8ŒÅ©¯‰±@mPÔñwjl,6 áhWÕ˜d öà uõmÁp®.™á£Ç…twöR x­BδYcŒxg*vo  yò‘•“[¬?ÜVœ˜0ÒN¡O난~Žó’¯·h#´Hkýœ±8kÓß^Àq@]àÓ“ø,56´¯÷Í-κU»n…[>]@nîøÏœp›[œ6# €4tën¯:ŽÒþ}…—8äT9_žY$/´G’K™©ù†•(óÑ’Mø©`ŸÉdѺ;ùO‹B Ó&P{qöhJÉ+Úé–§¦l2«MïöÝ_1ÑÓ«’t¸½±l€ëØya ¦ô©«®½ÆL^¬žêñš¸ùy.¾Û½Š[ u/]½‹iS}øN>²e1™q‡jfÚ&¢©iT\=kÏ›ÀXô-.84V5ðu!TE˜ þ.ŒOH´¶4—zwTr.ï‰¦Ë xõµ·œÖ„HÆù£žÈHùg Ñhñ’T$ßyq¸zþ¨p¿´ë< q•ró÷š‰wÿÍÑð–I]´–æI²é²˜sÂ"×:Õ–bÕ¦“ÈÙL6¢9VÊÓWž§<æ;”3?ý©Mê3AV#µ±ËÞ¯‘ž K£UrÝ9!›qát¦H£Ù+6ÇV…/TS^pÃùqgLP'Ú5E ‚–ÀÞºîÄ Ën"2|Ÿ;®W»Îý"Ö¬TwÖâµtúŽO'› á+W Ã+¦âZÌ–<ÕÆ&nOÝ,IŠ£06.ÁZ.Çñúøh*INÚ’Oe½ÉgBXÐÔZóäøä9èü“hÒíDSš¥¡Ê µA¯/Ôc¸ö“`A§¯"zå|‘ €ÅŸ¨ú;HÍ#‚Î|%ÄOˆƒ«OàÌÉÐÜD ž mÜðâc–ƤÉÂqm¶uË&~÷núÒË £ÇÏ€ZÕj =«_n[‡‡÷nN§ÏÝ$_¾bE˜‚€Õ)ù8¾?6‘lú“ÍÙæÖ}#bW( œ³d-®•p&¡ý’œÖa”"9öõņÐ$’Ú›AÜ!ä;ÐÑõè{~á¹8‘ÛÞ£1ÛÓÉ0ž`²#´kÒuäNÅÖ Q¹bhæ ”8ûÓMáŽa›•¿”w±h²¢®qŠæ°(bK ‚’Z¾Ò%ÐÆémáãÖË(Éý‚ÛJ)@> þ›7% ï{y Á“¾ÆÒîohfòô>{pÿ.­_Î%±ÉèägëlZØ\B2B #™¸ÚüÒºp‚hÝšü®[¥Ü<‹#SpñÌA7’ãØHƒt4:Ÿ|g¨tÓL¶*($Æ©»ì…®ù’ó÷$;b›ÔÙ`=¶£¦M„MÌÄ5ò«·Ç¾“H·ÌH.¼žHeAîº5}r­dõ¨±)ÀT};€Q5iÖ2…O0ü…0óñÃ;óæ,Š´²µ냔}g‘£]‹7å9ˆà©_{üèîêžC>úhê{Ž .ÈìðIIð€?[Kswz6Òuíý¬;µ€ç§OåâJÉa˶zv°éd† ¤µâ‚l´é舊«Åüy¾c÷ÁèÖÍ'ràúÅ™TWÕôÓ°¡L €|ʽŒ¼ì­høBã ÝTëî'ò]Kø£ìâÏ(=¹Kx €¿ LÌ,Pý¤Êµu‡¹…׈ §Å¾÷à1Ý«Äý;¿pGDäxZYÛ kfæ6¸ùóæ7®œ®þ6·ÕoÚ¾ÔH~ò®Þ¸â 8Uø“p<ºw3¡a£ÏÑ’‘3èÏ"€bˆ-ÎܺÏ_ªÅ]+ËM©zü°s“f-êçhÇãÑýÊãôÿ5}ZQNb{Ó?å%ÿ\SUõعIÓæ}~}p[œoÔÄ„êÐMMZáNÅå@>Œ„²á6(?¡Åé âK½+ü?À%ÝÝ·/Ç1‚9áUø?B)”ÕèâÞlÈÒêÏ @=àùÄÞžk­®ÅIEND®B`‚openchange-2.0/apidocs/html/overview/dynsections.js000066400000000000000000000041341223057412600226220ustar00rootroot00000000000000function toggleVisibility(linkObj) { var base = $(linkObj).attr('id'); var summary = $('#'+base+'-summary'); var content = $('#'+base+'-content'); var trigger = $('#'+base+'-trigger'); var src=$(trigger).attr('src'); if (content.is(':visible')===true) { content.hide(); summary.show(); $(linkObj).addClass('closed').removeClass('opened'); $(trigger).attr('src',src.substring(0,src.length-8)+'closed.png'); } else { content.show(); summary.hide(); $(linkObj).removeClass('closed').addClass('opened'); $(trigger).attr('src',src.substring(0,src.length-10)+'open.png'); } return false; } function updateStripes() { $('table.directory tr'). removeClass('even').filter(':visible:even').addClass('even'); } function toggleLevel(level) { $('table.directory tr').each(function(){ var l = this.id.split('_').length-1; var i = $('#img'+this.id.substring(3)); var a = $('#arr'+this.id.substring(3)); if (l°ùý¿ÏËÊÂ]–P€zØf| Íñ¯“+Ù´gð5…b  i5ümM³œ_æÍq,ÒcŽõèoÓd´ !¶äò©ô•,ôðÀ{¹¨µYß,€zTÍ8H]𤕘ï7¼»/òó8ËQæ !F€~6ãá?Y ÀA@ŨÁ.@ƒ¶TäÄYïŠËë±r‘µ8Ð*·é>€Šçÿ?€×þŸe[6«xÂIEND®B`‚openchange-2.0/apidocs/html/overview/ftv2doc.png000066400000000000000000000013521223057412600217760ustar00rootroot00000000000000‰PNG  IHDRÚ}\ˆ±IDATxíMOS[…Ÿžsúa?-XZ(PD4‚ AWbu`b 77wäHFÆCËÔÂÿà/`vo„ˆAPòq‹P @ ­ûÝè980 îà¤+»§Ýy×^ïZï9SW¹\83g‰3'°Nâçl¹¸_b¯p ïåûÆVÜÖ¡€Ÿ×"¬Ö†X€d]Ðà3“ÉÃÄÌ™xŸ ßMàœ[<çSPkvc—hÈ'…™˜^Åm™hØ7 `Û™¦ èÀåráq›‘œ¾!daeKŸþÆÕ˜:Ì*³_דâèi?I–eP*B7Ÿ¿åô!¹Ýgr6Ër6oKbëþãðôrI”ËTˆüªŒ¨xóö=›ù¢&‰(e+ßóÄkýÇ`ëÁÜb.“¸ÐW×w0¥°jÑzN™¬|©WEãµ¢a¯6[öX†AkÓù*/œ¨‰€ÉY­ ÿV’§–u²jÂ>1W *½·°PGŽzÿ¨/Eg{ ŸÇâaoŠÁVú:è¿™¤1$ôR§W,–ªà¨@ŠË56¾ÀÔÜ-¾,mê¸Î/æè¹– òr5¥T*S(Vf8ö9u’ Õ£w›ùóa=Í<{Ò¡UŒ÷r¯+ÉådDÏF$è°…£é¿`zþ»ÎúöN‘µÜ®0Q3£~_^Ëóâ¯N=ˆvpTà±LžT}ˆîkq†Òm<¼ÎÓ?Zh¿X£ï_þÝ¥[)ƒ `gêÃa_Ô*äÔ2`'=õ´Fÿ2EâÁPú ÷»›l=8‹Wv°%THqÉ¿<"¤ïG¾ÆxH{#ÆÖ«aÔJÕÞ‡—m‹„ çñKsÿàñVŠØ¡°·MâÒ^ TÁ– Ý›r¥ß½ømüÿ_™?ªWİ÷#uIEND®B`‚openchange-2.0/apidocs/html/overview/ftv2folderclosed.png000066400000000000000000000011501223057412600236720ustar00rootroot00000000000000‰PNG  IHDRÚ}\ˆ/IDATxí]MOÔ@~ÚúuØlp]ö¿#›Å]PYECˆ\9ù¼yÑß`ÖÄÿàÿÀÉxóâ¢C &=qÐÄ£—vZçv¶3m؃‡vžLûNç}Þ÷}Þ½ZA@n° OäNp ’xóþK°ññ€xÜj”°8sÑ€“ “€œ_¼[Âíæ§ïD'‚•yye+ø¼û 7#rNŸlïük* ¾0Ь_d«_(àñÖ±àôz=ñxõv§÷h©‰z¹€šØP-äóä’̪uý¼$»\DãJc—B4¯ãÝÖ.:£Ï-ÑÏß}µŠLEíºþ #—ûáºÀÏgN;BŠ€6ïýñ䬜…ö@’Ðåñp&™h>p9¤™EEά¨ÎÊ‘" u¥n€$R"?{¹<˜…ë…%PNtâ$‰ß¶±úá+^<é"§2 ªDq”q´\¬«Ò™a–Œ‘©Aÿ€"Ôµ ™êŸèP£}#Eàz{û.8i îp³ê(ADwD¦E<ê¬cE¦$ HdÊÄ ”.:Ù GŽ-`ŒL‚ý¾'¢‰Ä<¤CIª½;ÙÇTZd±i};>èôß‚z×;K×§8t ¤Ž q”:uvÿv•Ý›¬²ÙvEân{„M·FXg¼ÌfZÖ¨°¹‰*›ßÌß©±ù©:›j–YqèÜë#3çÏSøWøÿÿÑr'ø Ôùù‚ ©¡IEND®B`‚openchange-2.0/apidocs/html/overview/ftv2folderopen.png000066400000000000000000000011251223057412600233640ustar00rootroot00000000000000‰PNG  IHDRÚ}\ˆIDATxí]?oÓPÿ9iš4i°;ii“¶‰ZЉ‘‰ÀÀ7`bèÔÙ¬Øù,HìU'ô$*Tµ]‚T¡DPÚÄ6wÏ}‰;¡C; a¿ÓߟûÝïîž¼jAÀ­InSþ}€9H“ÓŽ|?íÁ÷ =_ÊÆŠ­†¥Àue*;¯YEäsYäæB¢Ÿ¿þÄ—£sÙ½½ÙŒ† É«›©ÀYÇq !GÇ¿v̇¹ÑØ®š °Œ‚ÔF¹}q¥b]÷7í·0)Úd›¾ÿð-èº}Pfä£ÖY{4™ÑÂ@}úæôñ2ÛüÔ—ñúåNŒI‚ÁǃcçÁº%£¬UаI³mc±ô˜å¼ÔÆüÈ>é¸xþt9Æ$µý OæVE*õU´Ì‚ç#ž×ˆ•ïûr@l$øPÿrHaaÇ¥ ²›dZ®rè‘ãqI„o¼øT\Ž,tªj2FAxv-LŸp׌p TÄI/ \¥sfí½; jViTƒèú¤o^cpÅü¼ûû»Ïb]”€¢¤<†aþÕœ²“ßÓ˜y“£§9:Œîù+À³€ñà,E žf³6éNˆÄE£KU}Ü^;¶ØnZ¢uß­US4— ѬëbížN¶.Úk¦ØjTÄöº%µªâ i¯VÄÊÝò§™ Èù¸)ùÿG€™òºJ@T x”IEND®B`‚openchange-2.0/apidocs/html/overview/ftv2lastnode.png000066400000000000000000000001261223057412600230400ustar00rootroot00000000000000‰PNG  IHDRɪ|IDATxíݱðøScOx@ –¨y}IEND®B`‚openchange-2.0/apidocs/html/overview/ftv2link.png000066400000000000000000000013521223057412600221660ustar00rootroot00000000000000‰PNG  IHDRÚ}\ˆ±IDATxíMOS[…Ÿžsúa?-XZ(PD4‚ AWbu`b 77wäHFÆCËÔÂÿà/`vo„ˆAPòq‹P @ ­ûÝè980 îà¤+»§Ýy×^ïZï9SW¹\83g‰3'°Nâçl¹¸_b¯p ïåûÆVÜÖ¡€Ÿ×"¬Ö†X€d]Ðà3“ÉÃÄÌ™xŸ ßMàœ[<çSPkvc—hÈ'…™˜^Åm™hØ7 `Û™¦ èÀåráq›‘œ¾!daeKŸþÆÕ˜:Ì*³_דâèi?I–eP*B7Ÿ¿åô!¹Ýgr6Ër6oKbëþãðôrI”ËTˆüªŒ¨xóö=›ù¢&‰(e+ßóÄkýÇ`ëÁÜb.“¸ÐW×w0¥°jÑzN™¬|©WEãµ¢a¯6[öX†AkÓù*/œ¨‰€ÉY­ ÿV’§–u²jÂ>1W *½·°PGŽzÿ¨/Eg{ ŸÇâaoŠÁVú:è¿™¤1$ôR§W,–ªà¨@ŠË56¾ÀÔÜ-¾,mê¸Î/æè¹– òr5¥T*S(Vf8ö9u’ Õ£w›ùóa=Í<{Ò¡UŒ÷r¯+ÉådDÏF$è°…£é¿`zþ»ÎúöN‘µÜ®0Q3£~_^Ëóâ¯N=ˆvpTà±LžT}ˆîkq†Òm<¼ÎÓ?Zh¿X£ï_þÝ¥[)ƒ `gêÃa_Ô*äÔ2`'=õ´Fÿ2EâÁPú ÷»›l=8‹Wv°%THqÉ¿<"¤ïG¾ÆxH{#ÆÖ«aÔJÕÞ‡—m‹„ çñKsÿàñVŠØ¡°·MâÒ^ TÁ– Ý›r¥ß½ømüÿ_™?ªWİ÷#uIEND®B`‚openchange-2.0/apidocs/html/overview/ftv2mlastnode.png000066400000000000000000000003661223057412600232230ustar00rootroot00000000000000‰PNG  IHDRɪ|½IDATxíÝ!NAÅñ¤‡à\ ÷à Um@`Ô5iÒ`ëh ‚ÅW7] b§ÝˆŠ&oföÍd¾YÔ4 üšcø ‡€´‹Åòù3v=¼]†§µ\B… I¿‹=B·™B¡®;¸k´µ W°ÍN@vyÍÑÖ4ãß÷]ÈâYìã§|M}]ÔÚx6a }ôdׇØYüú¨>¤||5?Ó>|žB"¡î'¡IEND®B`‚openchange-2.0/apidocs/html/overview/ftv2mnode.png000066400000000000000000000003661223057412600223370ustar00rootroot00000000000000‰PNG  IHDRɪ|½IDATxíÝ!NAÅñ¤‡à\ ÷à Um@`Ô5iÒ`ëh ‚ÅW7] b§ÝˆŠ&oföÍd¾YÔ4 üšcø ‡€´‹Åòù3v=¼]†§µ\B… I¿‹=B·™B¡®;¸k´µ W°ÍN@vyÍÑÖ4ãß÷]ÈâYìã§|M}]ÔÚx6a }ôdׇØYüú¨>¤||5?Ó>|žB"¡î'¡IEND®B`‚openchange-2.0/apidocs/html/overview/ftv2mo.png000066400000000000000000000006231223057412600216440ustar00rootroot00000000000000‰PNG  IHDRÚ}\ˆZIDATxí1Kû@ÆiƒØB…Ò¡(h¬"EÄI'ÁoàªèÚ©ßÀáâä 8ùçR-‚â B«TPˆï]z¥B’3 _Þã’»ç}ŸË]VÇ÷}€ÌÈdIæ®i쟯JØ–b¸šÍÃõ+º™|KÂ…°,[Pï\ʘMÆ¢#€ä…F`JݤìÛk³úA±àþè?ØY4ck6"¹Z)ê¸0SHM¨@ï㋺WÖmo¼4èHJ¨Àÿö+…QobŒút ¤ú’*Ð~êè8_+3Y-ñðÜå½÷ ˜PwA¶+^ý}ºì£+xìhÏ•MAE]€TD~EÞߴ^R)`ÖAùŸÏ9©pÔq-Û¾õÛ3tÝÊÆ›ˆÃTÐHÈ)€ ½Š’ICªxëd#1ôú§é€ m@Vüý?Zæßgo_½3-³\IEND®B`‚openchange-2.0/apidocs/html/overview/ftv2node.png000066400000000000000000000001261223057412600221540ustar00rootroot00000000000000‰PNG  IHDRɪ|IDATxíݱðøScOx@ –¨y}IEND®B`‚openchange-2.0/apidocs/html/overview/ftv2ns.png000066400000000000000000000006041223057412600216500ustar00rootroot00000000000000‰PNG  IHDRÚ}\ˆKIDATxíÝ1K1Àñ­ž ØG•â‚n‚Šà ‚âælÁE¿€‹“ (nºêââêäࢋƒÐMAá@°‹ µât¾ÄK¡à%Ü•Û ý]BIïå%áuÍ…a™€,e × v¯ç¥«ˆi‹º¨Õö–î\tòòuénÄ0ã æÜÉoV\Ì$G.&@Y=ÆË%$um·¢ûÛ6–'Úß«9Qó\bÙ)²º0Ðë-Zœ¥TèHÍ`pÀcsm µö5:>Áë‡Þ¦I µØ ‚F‹Çà]» ›jg—ìoÏáõ©[ œõ š­onë €Ô¬¨vqõ„?\Ðç”  6»øüÒTe ÃÉéŸeç ÀÅlQ ¡c”€ª¬ü3*d€ÅWTMÏ\rÿÿh6™ø1±F ‹°fžIEND®B`‚openchange-2.0/apidocs/html/overview/ftv2plastnode.png000066400000000000000000000003451223057412600232230ustar00rootroot00000000000000‰PNG  IHDRɪ|¬IDATxí=QF‘Ø¥D«ÔkÄ:‰F©PK؃=V@§Õ³ Õ8SHxñÌ0bnrróŠ{ò½¿¾’$ ÀÏTŠP  ö¼X¬OÛd6êìòð"°²S´±O¥B€(¡àQé)š+YĈ ÒªËRÉÐ>VtÉsˆm9(ê„䜥k‚-@ȧ-Ü$ó b Ò[he ¿Kp-ôl|CùÿApRG'rÍ­aIEND®B`‚openchange-2.0/apidocs/html/overview/ftv2pnode.png000066400000000000000000000003451223057412600223370ustar00rootroot00000000000000‰PNG  IHDRɪ|¬IDATxí=QF‘Ø¥D«ÔkÄ:‰F©PK؃=V@§Õ³ Õ8SHxñÌ0bnrróŠ{ò½¿¾’$ ÀÏTŠP  ö¼X¬OÛd6êìòð"°²S´±O¥B€(¡àQé)š+YĈ ÒªËRÉÐ>VtÉsˆm9(ê„䜥k‚-@ȧ-Ü$ó b Ò[he ¿Kp-ôl|CùÿApRG'rÍ­aIEND®B`‚openchange-2.0/apidocs/html/overview/ftv2splitbar.png000066400000000000000000000004721223057412600230530ustar00rootroot00000000000000‰PNG  IHDRM¸¿IDATxíÝ¡JCa‡ñç(˜ ëƒ%±Ø4 b±È˜Í¶3˜v^Á±˜…ãó–ŽELƒõ…¥•³ ,ÿb;íç{Ã/¼ðÞÀaYÕ¯åóøq:¼º¹›\òIIIIIIIIIIIIIIIIII-Òçl¹›«õ抢è_t/Ï»ã£ÑíYQVõðêäíã÷´×ùY¬Úÿµ§¦ivók¾_íåýÛ£I@$I@$I@$I@$I@$I@$I@$I@$I@$I@$I@$I@$I@$I@$I@$I@$I@$I@$ýC[Vì=ü[„fÆIEND®B`‚openchange-2.0/apidocs/html/overview/ftv2vertline.png000066400000000000000000000001261223057412600230570ustar00rootroot00000000000000‰PNG  IHDRɪ|IDATxíݱðøScOx@ –¨y}IEND®B`‚openchange-2.0/apidocs/html/overview/header.jpg000066400000000000000000002264161223057412600216650ustar00rootroot00000000000000ÿØÿàJFIFddÿìDuckydÿîAdobedÀÿÛ„ÿÀÍ4ÿÄû     a!Qqð1A‘¡¢d ±"Ô%U•ÕV–Ö”WÑñ#EÁá2DT·BR3C$uµ&g(8x’S£³4…6¦hbc¤´Å†G§)   !1AQq"“ÓT”ÔUa2‘¡Ò#³´u6±BRVÁÑb²3$v'7ðár&ñ‚’¢CS%Âsƒ£4Dct¤5ef(ÿÚ ?ýAîÊåSñMÁÙB8v)¸;(GÅ7eáØ¦àì¡;Ü”#‡b›ƒ²„pìSpvPŽŠnÊñMÁÙB8v)¸;(GÅ7eáØ¦àì¡;Ü”#‡b›ƒ²„pìSpvPŽŠnÊñMÁÙB8v)¸;(GÅ7eáØ¦àì¡;Ü”#‡b›ƒ²„pìSpvPŽŠnÊñMÁÙB8v)¸;(GÅ7eáØ¦àì¡;Ü”#‡b›ƒ²„pìSpvPŽŠnÊñMÁÙB8v)¸;(GÅ7eáØ¦àì¡;Ü”#‡b›ƒ²„pìSpvPŽŠnÊñMÁÙB8v)¸;(GÅ7eáØ¦àì¡;Ü”#‡b›ƒ²„pìSpvPŽŠnÊñMÁÙB8v)¸;(GÅ7eáØ¦àì¡;Ü”#‡b›ƒ²„pìSpvPŽŠnÊñMÁÙB8v)¸;(GÅ7eáØ¦àì¡;Ü”#‡b›ƒ²„pìSpvPŽŠnÊñMÁÙB8v)¸;(GÅ7eáØ¦àì¡;Ü”#‡b›ƒ²„pìSpvPŽŠnÊñMÁÙB8v)¸;(GÅ7eáØ¦àì¡;Ü”#‡b›ƒ²„pìSpvPŽŠnÊñMÁÙB8v)¸;(GÅ7eáØ¦àì¡;Ü”#‡b›ƒ²„pìSpvPŽŠnÊñMÁÙB8v)¸;(GÅ7eáØ¦àì¡;Ü”#‡b›ƒ²„pìSpvPŽŠnÊñMÁÙB8v)¸;(GÅ7eáØ¦àì¡;Ü”#‡b›ƒ²„pì__gÓâ£êE~•²O\VݪÏãžà…·#÷Á?Nž•cÏ´Ôô™Û£¾!àÞÖ²x¬.c;s÷<%Íåå+ÝÁ’¾ºckO¦‹£Êcq0}ç)sµµi®W¶6׳SÈpo× 'ü߯Wí¬?þ«[7ð¿™áÜï¨]ù¥‚øócûëëvþqkúß„ÿ›øÇñå­õ¥?á2ÿùßP»óHøócûçëpyůëvþoc/Ç–¿Ö”¿†Ëÿç=BëÍ#ãÍïœW­Áçýn¿ÍÜeøî×úÒá‡2¿Ã¹ÏPºóIüy²=óŠõ¸<â×õ· 7qŸã»_ëJ?†Êÿç=BëÍ#㽑ïœW­ÁçýlÂÿÍÌiøê×úÒ—ðÇ™?áÜç¨]y¤|w²=óŠõ¸<â×õ¯ ÿ6ñ§ã«cë:?†<Êÿç=BëÍ#㽑ïœW­Áç¿­XcùµÛYÑü1æOø{9ê^iì|â½n8§ëNþlãoÇ6ÏÖt ¹“þÎzךGÇ{#ß8¯[ƒÎ-Z0×óg~8¶~³£øeÌðösÔn¼Ò>:Ù>ùÅzÜqkúφÿ›ßñųõ/áŸ2?ÃÙ¿QºóHøëdûçëpyÅ?Y°à÷²¾8üom}gGðË™áìߨÝy¤þ:Ù>ùÅzÔqkú͇šøãñ½µõ•Ã>d‡³~£uæ‘ñÖÉ÷Î+Ö óŠ~²áßæ¶9ümm}eGðϘÿáìߨÝy¤|u²}óŠõ¨<â×õ“5q×ãkoë*_ÃNcÿ‡ó~£uæ‘ñÎÊ÷Æ+Ö ó‹_ÖiìÏ{âýj8µýVÅÌ›ñtÃéy…îÏ©\ù´|o³=ï‹õ¨<⟪¸°{Ù&Äü]ðú?‡<Â÷gÔ®|Ú>6Ù¾÷ÆzÔqkú©‹™/âØ‡Ñü9æ¸s>¥sæÑñ¶Í÷¾3Ö ó‹_ÕL[üDZÀü>á×0}Ùõ+Ÿ6ŸÆÛ7ÞøÏZƒÎ)ú§‹¿˜ö7âȇÑü:æ¸s>¥sæÑñ¶Í÷¾3Ö ó‹_Õ,_üƱ¿A|:—ðï˜âÌz•Ï›GÆÛ7ÞøÏZƒÎ-Tq€÷²-Ž?þë‚øuþ`{‹1êW>mìß{ã=j8§ê†1þbYŠà¾Gðï˜âÌz•Ï›GÆ»;ÞøÏZƒÎ-Sñ—óÈüUðê?‡{ÿÜYR¹óhø×g{ßëPyÅ?Sñ—óÉüUðê_ÃÍÿî,Ç©\ù´þ5ÙÞöÆzÌqkúŒÿ˜VWâ˜?‡Qü<ßþâÌzÏ›GÆ»;ÞØÏYƒÎ-Sq ÷²•ø¦á´w÷¸³§sæÑñ®Î÷¶3Ö`óŠ~¦c_æ —ø¢á´w÷¸³§sæÑñ¦Î÷¶3Öaó‹_Ô¼müÀ²ÿB|6áîþ÷cÔî|Ú>4ÙþöÆzÌ>qOÔ¬müÀ³?Â|6—ð÷{/êw>mlÿ{c=fËZþ¤ã¿öoâx_†Ñü>ß¾ãËúÏ›GÆ›?ÞØÏY‡òÔýIǬßÄп £ø}¿}Ç—õ;Ÿ66½±¾³å­R1ÏßÛ;ñ4/Ã(þoßqåýNçÍ£ãMŸïlo¬Ãùk_Ô|s÷öÎüK ðÊ_Ãýûî<¿©Üù´þ3ÙþöÆúÌ?–§ê6:ûùgþ%†øeÃýùî<¿©Üy´|g´=íõ˜-kúŽþýÙÿ‰a¾Gðÿ~{“/êwmí{c}fËSõýû´?Cü2€7ß¹2þ§qæÑñžÐ÷¶7Öaüµ¯ê&<ûõh~$‡øe/€7ß¹2Þ§qæÑñžÐ÷®7Öaüµ?Pñïß«Gñ?Ã)ü¾ýÉ—õ;6Œö‡½q¾³å­Pñ÷ß›GñGÂé|¾ýÉ–õ;6Œ¶‡½q¾³å©ú…¾üZ_ˆâ>GÀ;ïÜ™oS¸óiüe´}ëõ˜-kúƒþüZ_ˆ¢>GÀ;ëÜ™oS¸ói|e´}ëõ˜-OÔ÷ÞÓüEðº_ï¯re½Rãͧñ–Ñ÷®7Öaüµ¯ê÷ÚÓüCðº>ß>åËz¥Ç›GÆ[GÞ¸ßY‡òÔû`ýöµ?Äü.€·×¹2Þ©qæÑñ–Ñ÷®7Öaüµ¯Ûëï­©ø‚'át|¾}Ë–õK6Œv½q¾³å©öúÂûëjþ ‰øUoŸrå½RãÍ£ã£ï\o¬Ãùk_·¶ßKWñW¨ø |û—-ê—mízã}fËSíå‡÷ÒÖú~+áT¾ßåÊú¥Ç›GÆ;KÞ¸ïY‡òÖ¿o,?¾–·Óñ_ £à=ñî\¯ª\y´|c´½ëŽõ˜-O·v'ß;_éø¯…Qð&ø÷.WÕ.<Ú>1Ú^õÇzÌ?–µûwbýòµþŸ‹øUïrå}RãͧñŽÒ÷®;Öaüµ>ÝX¿|­§¢þGÀ{ãܹ_T¸óhøÇi{×ë0þZŸn¬o¾6ÇÓÑ £àMñî\¯ª\y´|a´½ëŽõ˜-köæÆûãl}=ðª>ÞþåÊú¥Ç›GÆOÞ˜ïY‡òÔûqcýð¶~ŒøM/7¿¹²¾©qæÑñ†Ò÷¦;Öaüµ¯Û‹ï…³ôìgÂhø{û›+ê—mm?zc½fËSíÅ‘÷ÂÙúv3á4| ½ýÍ•õK6Œ6Ÿ½1Þ³å©öÞÈûßm}9ðš>ÞÞæÊú¥Ç›GÆOÞ˜ïY‡òÔûodýï¶¾œŒøMïose}Rãͣ㠧ïLw¬Ãùk_¶ÖOÞëkéÈÏ„Ñð.÷÷6WÕ.<Ú>/Ú~ôÇzÄ?–§Ûk+ïu·ôÜoÂhø{{›+ê—mm?zc½fËZýµ²¾÷[MÆü&w·¹²¾©qæÑñ~Ó÷¦;Ö!üµ>ÚÙ_{m¿¦ã~Kàmíîl¯ª\y´þ/Ú~ôÇzÄ?–§Û[/ïm¹ôÜoÂhø{{›)ê—m/Œ6Ÿ½1Þ±å©öÒËûÛn}7ðš>ÞÞæÊz¥Ç›GÆOÞ˜ïY‡òÔûieýí·>›øMoose=Rãͣ㠧ïLw¬Ãùj}´²þöÛŸMÆü&··¹²ž©qæÑñ†Ó÷¦;Öaüµ>ÚY{mϦã~GÀÛÛÜÙOT¸óhøÃiûÓë0þZŸm,¿½¶çÓq¿ £àmíîl§ª\y´|a´ýéŽõ˜-O¶–_ÞÛsé¸ß„Ñð6ö÷6SÕ.<Ú>0Ú~ôÇzÌ?–§ÛK/ïm¹ôÜoÂhø{{›)ê—mm?zc½fËSí¥—÷¶Üún7á4| ½½Í”õK6Œ6Ÿ½1Þ³å©öÒËûÛn}7ðš>ÞÞæÊz¥Ç›GÆOÞ˜ïY‡òÔûieýí·>›øMoose=Rãͣ㠧ïLw¬Ãùj}´²þöÛŸMÆü&··¹²ž©qæÑñ†Ó÷¦;Öaüµ>ÚY{mϦã~GÀÛÛÜÙOT¸óhøÃiûÓë0þZŸm,¿½¶çÓq¿ £àmíîl§ª\y´|a´ýéŽõ˜-O¶–_ÞÛsé¸ß„Ñð6ö÷6SÕ.<Ú>0Ú~ôÇzÌ?–§ÛK/ïm¹ôÜoÂhø{{›)ê—mm?zc½fËSí¥—÷¶Üún7á4| ½½Í”õK6Œ6Ÿ½1Þ³å©öÒËûÛn}7ðš>ÞÞæÊz¥Ç›GÆOÞ˜ïY‡òÔûieýí·>›øMoose=Rãͣ㠧ïLw¬Ãùj}´²þöÛŸMÆü&··¹²ž©qæÑñ†Ó÷¦;ÖaüµÈ[.Õâ)8há'(,™Ed"©,’¥¦ªJLEP‚Sˆ¡ZÜðMk;í®ctw1¼µìp-s\ÓG5Í4-sH ‚P¬ô3Eqn-Þ×Àö‡5Í!ÍsH¨s\ AÄ/£³éñWÔ¹+ô©Ùôø¨ú‘_¥bï¼JÆàXññ‰¶•Èeƒ‹\D[G2NJ&CC6*ä1ORöêÜ 6¾ñÈîKÞsS,û«×> §hð'•¿jGÐ8A<‹H/u†–ð«‚ònió6Û`ãÛ«Y.á¸i10ý–7£½xtÖ¡£†§Æ€¯oL…xäi¥® Òᑸ$Ö1÷T|¹Ì‹DÎmïFhV±í?䤉˜sk_§[khmÍn'mYÃidÐ*Ðò8j‘ÿjGž·<—Õð¶sqf·-ó²9ˉn.[ƒýV7ì±£©­.( uV|µb*”ë©ÓDꔪmÓÜþŠ’;SªPS¸)P& PSn½=ú’ÔU()ÕRZª©ANº)Õ)UÛã¤GjuJ wM`¥*›u÷jKSªPSnÞ*’ÔꔨÓN…UL íñÒ¢uJU:½ÊšR‚}‹SªR©·ÇPZR‚•ORuLUzüƒJ©Õ)TÛ§Oz•N©ANà¨-L ¦Ýj UU)Tê÷*t”ÁL XRN½‰J¦Þ¡¥¤'T §UAjuJ uÔ§T¥So½SBª©AOëè¤{Mºûµ%¡:¥*›t©-N©AJ‚ÔꔪmñÒ¡N©ANò…MªR©×ÑH´& R©¶ µ:¥*KU”Û¯MMN©ANò…*'T §^ЩÒR‚›jKSªPS¸* S)TÛ®Á©¥ª@S¤<´“ª`S¯¢•uH m©-N©@üõ©‚ªsPÔ–§T §pRâR‚›u¥@RU%©Õ(yõ©-Nªà~ª’ÔꔚŠQ:¤ŸNš<)Õ()J€§T€}µ%©×ëH)Õ 9ô©-N©ãÓSDU 9ôé¥Ç­:¤ÒàSW…-)Ô¤=Iju€~z)ñWs I¨ª@?8x©S±5p?0ÿM.=iÔ¤ÑÀ£‚¸)Q:•p5M¨ëWÒÒŸ\ SBŠö«„<4¨ª¸<5:SVs .!UÀÂT'^Õp?pQNÄS±\ J‰ÔŽ•®´¨Š…`0ôÒ¢t À`è¥E4ZÒIkB¡ P…(B”!J¥R„)B¡ P…(B”!J¥R„,®Áw ¹f"Éc “8±K^ð$Óþ@è§_›ûç÷Û1ûVïôò/»¶‡îž/öu·èX²?³îÒµo¶/À§gÝ¥…~pxš»e®Üõ•K¹2ÇŒ½ni57fÞ*Ù”u‚D¦ÑL}4ÞPÆ0òˆ×ì?%0V.U` Ç°5³ãmî^zÝ-ÌMžGÒ|g+ÐÐ@ ó{š[¼¶ÿÊËxíF+é hêÀ÷DÀ;õ*ꔪXTÐ'TÅSn¾íIjuJ mÒ¤µ:¥* SªR©·]ƒJŠª”é(TÒ©Õ0)×ÑRZR•Mµ%©Õ()ÕÑQ¥:¥:È4¨R•M½CR@N½©ANà¤ZR•MºÔ§T¥SnžåAjª¦:ú)'T ¦ßMuJ uR-N©ANº‚ÔꔪsžçôT–§T §pT¦bR©·Çߥ@R‚U%©Õ()×PZª© §0éÝâ©-N©ANà¥Å:¥*›|u4ªPSª‘jª¥6ëPZRU%©Õ((=54¢uH mÓ¦—…:¥óÒ =ª@?0Ô–ªªP?=N”ê§æ¡¨-N©Nz\SªPSn½Þ:\:ÐKObuHÛRZ~¤€~z’ÔêÌ:ôÔ–§T€~~JT#¡4…?0ëKÂ{RéR½¯b@?0÷tT{UÀýu%©×±\ ú "ª@8ôÔiNªàpè飈OÀ4¸u¢½ªàz(Ÿ ¦‰×µ\4ˆ@§R¸<<•:S©Væ’;Sª¸|<´´¦®})P„+†•{Sª¸Žà¬ (Ž#¡_ZTOWjÔ˜iQ>[{ž•¢¶ 4’¢Ö’JP…(B”!J¥R„)BYðÒ–¨<;ï\ùU0ø«ó{|þûf?jÝþžE÷vÐýÒÅþζý `ö;<•«T-‹þÝ*v;<”T#þÝ+ò•ŸÍ»žshkÞ˹$4—”Í~Öò¨Êý·ûú¤+óü÷šý­yúÄ‹©€ýU¾­N©@ýu%©Õ )·J‚Ôêš'T ¦Ý;¼TxSJçÿMRuH mê’Ôê”çä©-N© ¦Ýj Sªû™6y éQí\½xàà›v¬ÐUË•Ô0èTÑAUNo×ÒÇfYÜÖBÑR礞[ùÀ\ãÐOàYKcðožïTÐr[IKyŠú®n5>/W³0”@bRªø ©Ã@2e 5¯7ÌókcaÜcuÛg¿Õ‹ÇãÙ«ƒz»|+mÆì}Ë“ðÛ=±ž5p§¯Â<+¸à2è†dçn„ƒEÛ ©XGª)¦.I¯½Qs ”1¬Tļ¢<•ªÅÎìMäÝÕ•»ŠHÔáS@]Ð:*ÐOJÊͰo,ÁûãÈ¡¡£M:iÓÆ´<;*¶ÙÚ±)ÿçƒÒ¡È.b„©ïhôÆn7Cx{ýí9DC½]«~k™Èÿtiû2Ÿý=«„íá;ª[H‚ºÆàá®àˆrá«Y¦.\ šJKº ²b²~Žå#%5KCrD `Ö¶+`cîãl¯ŠFÆâE{(iÄ#¾#¤®ÆÔž²F—Ž®Úñ ‘кVn͹mÓÆQª‘0HGEÐäå×}=t^PïVÝi—ÇÞÌH5£À¬Î6ö׌Œ%½£ˆ\dëò dhB©MºtÒ-N½©AJ‚Õ@¥*›u©-N©J§UM uL uÒ N©J¦ßIjuJ uT–§T §]AjuJU6éîTЧUÚ¸kßÛ!@ã\{Y†uSˆ(º‚Þ6&9¸’S÷TôH¸Ô5:§C‰¦E9mcwîÌ&ÈÀO¸óòì UïyàÈão Oyà8¹Å­pÎíͽ”Ý9x°¸vk¼”õš5iï=MhâOz ˆÖ»—†ogg1QŒø¯ÉÒWîF~Å'«Ú±on&†äû@ûfÃ2sñQ«†".å¤IÈ”D‚AÔ…ùœÝçŸ3ndŸ—0ã¶ûZٞ؜ziãKr oxà\Èb%WIú5ü¹åNÆ…‘o[¹/sh&6:FýXà!íiè–@Ò)Ð>7{,ø·]K/dIÜQ“Ý$¸Á@Ê>ºAÓåÐ)tôxlŒåó[°¦L¦TÌã%Sz ”ÇÌ„8î¹—üÃr茖òµ¶ÊàZGxö²?ÿÕ¬0ž€,.Ž´q* ØüšÞ€Ùm©æÇåÈ:]!$ô'.véŽPúTðy¡Ä>¿¸gÉ1ÖAj¨dFFÛ¸˜‚ƒ v@¨±ÑBZ)UCDÅ7 ”ÑfËJmJ$9þ¢å÷0°ÆÁ37„qkÓ,N§y ”©cÀémxñ^Þ"†­ ¼6n_ee‹Ê4MQÈß±++@æ“Äv9§‹OŠÒÅWn½5½P­N©J§W”)Pê˜ëè©-N© ¦ßAjuL TéUT¥W¯È54N©J¦Ý:{Ô¨ªPS¸*KSªb©·Z‚ÔêªuTé)Õ0+Éà%Mz=íá×pÛgá«´ÓW×ùçK4iy•¥Pc¢­Çˆz*j¦@o¢²Šk¦º€‡5|ÏÉ.iîmñ—ËÙn7Àè,û¾ëDa‡Æ|­5 šðcWºsO``¶¦7u…l¢[}æ·—±‘N8¸¯9ÐpUS*…C ×ÒbŽ ÃÏB¾S®‘j*”ªsžçôTé)Õ0)ýaI0{•Mºûµ:BuJ uT–§T §]AjuHU6øêtªª`S«hRER•Mºû´¨ª@Sn•%ªª”¨-N©AM¾:)Õ()Ïã ”ÁìJU6ëîÒ N©ANªE©Õ )×PZR‚›t÷?¢¤µ:¤9ùv…M uJU6õ / uJ sÒÓØRù†¤µ:¤÷AjuJ >½5:Sª@Sª—ÒúépER–”궤µ:ýJàpè©-N©@ãÏ­AjuWõyiP§T qç×ËK‚jàz4ö'^Ä€na©!íHç©-M\ Ì:TRÇÃËS¥5p8séÓKˆN©ãGpëWÒ¢~p7pR!:ö«Ç¦¤µp8R¡N¥\ >©#µ:«ù§Jjà`ðÒ⬢½©×µ\ÝÞ¢ÀÛ|tQB¶´¨ž¥`0ÔÑ>[{ž•¢×]hIkI%(B”!J¥Y‰Ã"Zµt:wݸý!¼5ù½¾}³µnÿX‘}Ý´?tñ³­¿BŘ½vµª­NÇ»Z¿%œB˜ Ÿów´Ì90QRxÔt.¸ÁÔ`9p¬rU¶ªö/»BRòŽ¥3 cx¥þ€¾ÁtW}ÔM‘À;…[Bþ׬ý+L=Áµïß##™Ä WéT•Ã%0z«uœ1lªNY±lGGP§Uºí[z:E1A¹;!U° aÐÄÝY[qq]ops^ò@¨TõšÐÖ¾õÃmËZHkšæ´H$)NÒà6tT»uÐ(£¤À@éiÛ4PL'2J”Šö§HU DtÝ0ˆw‚³Ö™››g‡>ˆõô8vŠŠOè\ca˜‹ êêðý…bÍׄ;~áó3e%¸²ÌôìÚÉ•2†Lœ€T]ƒ©Š:r›”¼¡èÍé÷hÃåÖûZÑÕâYôöÓéâ:ºV§}¶ÅËÜÖQ“õ§ÛðýKæ¡¥íÉâæY,Åësn¨ŠÀÈ S¦r “P‡(€Š"^‘ÈYå-ÅÍ“Ãã=#è#¤-òÊæÂcËK_øm¥Sª»ÄÕªPS¯¢¦:¥6øé¢©ANª‚ÕUJ uÔ§T¥Sn”¨Sª`Sú¦0R‚›u÷i§Uï²ù„!ᓉŽ*åcŠòJÜgv¤˜(,6Æ/²P¾d2T¥¦œì”ˆ&¨Q:ŒSäÔ¡¯Â¿Íýæâßø\A!m¤‚'štw×sºÝ®pë1±•o`‘Üx•õw!í-°ÛC/½ef«†wéîíâ8Ø÷:‡´°v/ÎmËv^yÊÿ¹ò ñ0îjáºæžMLÉ:Pç3‡o DŠcfÙ=Ô›¢MA2HR€}7€ÀÚYØÁˆÆF!Æ[FØã`àZ)õ“Òç.q.$’Jð¼¾Zâæê\óÌ—ó¼½î=$Ÿè €€.Ml-ò>bAìTÜCÖ’‘R±Î–g!'ºnØ¿bñ¹ÓpÕë7ID”!Šr bˆl·vÖæÙöÓµ¯†F¹®µÍp!Í ð ƒB ÁÙ¸‚fÏ ‹$cƒšA¡‚è Š‚:è ‰PâCÙ}‰¸ŸœI±¯Ë[BFj]š w/¤n„pýþÙºiãx雼È=ôtôìŲ`<„øƒ–lŸ–œþÈìkg8bî ¬k 'ÅýîÜšô¹ÕšN§µõ>ùt[ã”6[®pÓÅÔh¿îóØ×IGPti‹¯ø<à“ñ¹jôŸ“²îtç®I^ËM‘ ~ß¶­™F.eŸ:Žzvñ‰ŠVúnKÛ® "‰Ì œ¤Ž÷Ìþyo=“̶müD1]â´E¶ýÝd’YXàÆ‡¶¯§{ éhÔà AÔj[•;gtlgfr2Éo¼µÑŒŽ7´¸–š7ìjq $P(­f\ÞÇ®øŒÂѰy I)Gmm˜|Å55|FÛ“So\›йnÖÉǬñÚ…!Vun3Ž(˜ }ÒjjÆå2ßÍ?ýÕ5æ<@Àe}Œq[>HØÑW0àMtù:'‚ïXc¹ y|Üv׆gnß$ÍcÜMá(“®·k;h8¬Aã[†ü%eVV¹dœNØ×“S–Àñ""ùvlÜ‘´œ¿bšMTœ€U ²ˆ”©,ƒ„V$* )ûw'y­mÌý¾ë¹£m¾rÙâ;ˆÚIn¢*Ù#©'»P8’×5í«ƒCå|Êåôû0-£{¦ÅNÒø^áãP9 [ "€‡5ÔÒ3^ßá#†°Ì`ã®beåÃw‘3BbÈG²Ì×AUZðA½¾â2nRàbÐå3õÌõœk%Næ0¦ª¾9›ç/0÷þë¸Ûšd1c- ^ÊÖ8:ŽÓÞVPøÙœ‰¢9&ú©¬ô¼_,önÐÛðçy˜éd¾¸E«öÒ£VŠFZ÷HÑöÝ­‘°5&Žv㋱W³ƒŽÖ'¾pžX‡Šs0Ê"æy5"õÓDTI°É:‰œ»o(yèvΦUÒŽ”jõ 9Na)?ÊÄe¹Ï~U]Ñß²ÍmÉ$ s¢dlš-’(-ßÈK¥‰ñš=~Êå70-ä²ÚͺÆf˜Â懹ï$tUÌ’YšöEC$cÅA<:p7á"¯ÅͷÞ[báºÍò¶eÞÊ9éÛ*ªh$åB:Œ~RýE$á²ÀPíT¦ÓßWÐ;›µÜªºß»RF—ýÀO {A’ÞM$µÍ¯:—Žà¶{›Ì }£¸àß½÷R†šTMZîÇpsM8´ƒÖ½!Íü;{:øC¹Ô›Î7Ï4Òàd̶fŒ›”{qºi);–IHYy±håúG#uWxÁ‘{#¦Qp®¥OæýµÍŽyóÛ­¥½Ä/qžýñ±±Ôš²&6FICH. ŽI A:ÅÞÙœåç*6Uñ»Ï¾âhdhî­÷Òž4Ž,sBꆒö0Pôqۆá~÷⃲Ï[/±›IçÓvÔ¤ÂøšÔ‹Nภf#î‰Yçì¦Fß\ŽX®ÉâV0•1)Äæ2Y]½Í¾gìÎ`ZìÞh¾ »KçÆÖLÆDÂÞõÝÜr1в&º>ðÈÙ#®Pt3<ºØ{›gÜnm„Ù­®m÷:7:GjîÛ­ì{e|ŽÑã1Ìyi45%¸YÁw ’¼[_îa’V ǵڳ–¾nVȦáÓ6VU(Øh¤•Õ›3UÁªIYcN̨©îÙæ¥,öã2"6Üfnœæ[BI sš|#w¦êŽqs u·Ê¹yËû½óšuž³2Ý¡ÓÈHÖ0ßGi'ƒC\â ]™ÕËì…ÃWš˜¢ä¶/ËÞfAX’ø†œ½åb!ä[j“Óɺ‡½­ÖÏÔb࢚¿ź!V)ŠÑð¬~SùÜXѸ­o¬l­¦`’+gÅl×½§‹CCíåsC‡ßLÓJEW¬^cù…½8k‹[«©ãv‰'l“9­pàK‹&Œ:‡î¢p­EEñµÂ±áì\ň®U®ì” ȰRN¥ æ%üÌZ×!“lÙ²2ðif ‰{b‚'"¢aÜQOGäç8o·­ÅÖÖÝ6ÛwØêÖ [#XáÉa$²XÞ@‘ é:mZÝ'™|µµÚðÛç¶ô®ŸmÝÓIqsæ—´jjcÙRÃMB„:¦„ú›Ç$áî÷ǘG#ñ=’ÝØ8Ÿ·|ñìdYŒ”Íó;sCÛ‰CÛ‘«7Aü¢‚bB.u[±j£ÅRÔÄQ¹QbüË}É»0ùÌž/eZ6ç; s¾Ä,òHàK[ýqG=Á€ð!䆟£7¾näñV7û¦àÁ‰´a%­ûR¹íf–4€]ýSPÖ—ÐZ#0¾1öjñŽÎî°8ˆ½1ÎA‚<Ó7Ò·r²Å*현ëx»†íº æbI¼n“´w›¹pP(§¾U ë9®`së–2Úå·eÅžC,¡Žcc€2´'»/ŠdcËC‹ã¶­5¡ióÌ^ÏåûŽã·a¹²ËG ç>RêT a²K+Ð⇊î<¨#ÍÜ]‚®|ÄppÞ.›F\ñ÷½Éh\²eIWlⳓ žU$ñI7i ¹ÛÆH®ɾMð0}5œæ>'Ëçó5ÒX›H¦Š:†¹îœ0E6Dâ¢7Ë èZݿˡ´ð1fùŽé$½¸%³ Å*+¢‘–½Ïí¸½‘°5&ŽwÛŒñÏ³ëŒÆSvŸÊ^x(ÄŹ—gq:—~ñËDTI¸È8‹™º.Ø™¸–îI„“g‰Êcn—¿ŠÊs¼±ºŠÿy¾Ï/·ä1α°jtµñÃãyé2Dö=û ʽùo%žØmÎ72Æ4=Ïq#¢¥¯–V½ ‘PÉñÓÀ/0o[js_V<º›•Ëg̼„–nCï¢+µ>‰ºj ”¢»íÌEÐS@íP¦Ó–¾ªÛÙìvæÃÛæñŽÕes^Úð –¸u9¦­pêp#©|û™ÃÞà²Sb¯Û¦ê NŠŽ±Ú(ZzÁl`¦ÚÌ–¬]R‚œõ%©Õ()·ÇQ¥:ö¥:B’uJU:éP'T€¦Ú’Ôꔩ-N©J¦Þ¡¨-N½©N%*ÁìJU6ëJƒ­:¤ÒÒRÇŸü5©×êHŽŠ’Ôê”×SDêŠ\zÓª@S®•骯֔5¨¨W‡EIjª¤MN”U :)qN©ýt¸&iN¥ ˜ÃRZЏž§J¤€na©#µWóù*tö&¥Ät§Up?=Á )iOR¸•¨ëWMN”ü à`šUX !ÞD'Up?8xªt¦®÷tR⮢½©×µ\E;AÔ¬ÛJˆ© ÚÒ¢u Àaé¥Dè ¶ðtR¢TZÒIkBJP…š¼/¥«%ÇNû•‡Æq¯ÍÝóûí˜ý«wúyÝÛC÷Oû:Ûô,Y•Øì%jËbS±Ø>J¿"E›wˆLî^AÓ2äðñ^ó•ûmÊ^Ví¯ØÿÕ!_˜;üÿçÌßí{ÏÖ$]:}+}-Z•RǦ¤µ:«ÃŸü%©Ô¥¦ˆª@Sª—…4 §_»Jƒ©:¤íÓ`÷iRZV}p'ÁܧײÒÓÈ®ÏYÎP5Èü¦;aœúBË'E(™.Ñí^*MN‹}ºBxo;9³mËl3ml‹_¹®Ú{–ô÷lè38uÐðŒwO}?–{ãzd4˜{r †´ÖãÄF ¥^EHoG ýOÚöE³í˜èf­áã3lÕ„dB ƢѓtÀ­Ù7*'A"9@‚0ˆˆ˜F¿2²yœŽw%%õã-ËÞ\çÈKËœOð$ý<P_qãñVx‹&ZÛ€ÈÚÐX@ph Ãô®•ÉR™mÙ26oÌòÎÑ(n¬¼œ˜,Î(«€êº†kG*ûýGUÓ7€+rÛØ·ºÍ×Ré&~†ž ÆQϧPÔâÆðþˇjÕ³™Xb¼À†²&kpë/}ZÀGI£Cÿ¬Ò°Ç%ܳnÓ21Ò±=ªÄIwÒë‘è"©€‡8™ER€a0ê¥{ÙÆØDðû¸åš€ÈÅ\HãØkà^G¹2ykÚEc¦8I£žç^.  óÿ(Ý ­rN¾É¬u’¹&ÞÛwMQh“.™"£[î.ýu”Mªc¨¡¸Q(W¿m«ëo ¾)ú#·´p:µW¼Ô4P¸öñ5â¼Ö÷\×ËutÇÈ纮0=”#WWàà†œ´KÙ踟ï`3¦poܧïùDp»dÞ †ºŽœºÖjò×--Ö±i`ÁÒ5½ 9ÞÑoÜÚ>wÿ…ßåqY ¶Ü1•Ní’Id M !8©Í®ø€¬fG\ᨓRh™€6W}˜Ü–÷‹8ÍGK$‡€8¯ŠNšÐ[pxtU®ÿ%h¹ 2|ù ‹†Ï $S1;6ÇRHñŽVLM¡Š²R̘$s¦ è Bòë aß·¬ -’9¢ãSâêÿêýwºmÙïƒ8}`E£Ì„I¢Ý\q²úìÝ©K²ìǹ0ªŸ`C9ng ©ÄNQÓPä÷_û”[²FØÊÉcpã¸8pã@hïĹMûæ{ ÃÇ´ý¡Ðxý ò}|Çr LfØ”O(Bo71Duôg €ª¡˜,n›C å/½ÔµÖÁenðwBXxÛ»í0žŸiÄ~?É’³·ÊÀbž‚Aö\:ùâüKß³{õÄ|ƒu¼j ¦»u‹¸¡  Aï”ä1G¼bˆr {¥…í¾JÕ·VƱ»ñ°¼²öÎk ƒo8£‡AíD/œê®ÑjëU()×Q¥:¥*›¢•;SªPS¸)P'T ¦Ýz{õ%©Õ()ÕRZR‚u{ª÷¯ÙâÑ,ÙÀ/ü>D™²—‹är<\{E쀆É8ÑË>AÁÌ©@¡ö–Ðj;©P u÷ÚüüȶM³Î]¿¼gÔ1Õ¹.¥xÚܹÓ4pÿåHÃÛãpê_[òL³9Ë<ÆÚ‹I¾×0èž¶'?üÆ?èñWçfÄh´y2|ÕvR Ü.Ñë7h¨ÝÛGm”2.9n±Hª¬A)ÈpÀ !¨WÙûxÅ-³fˆ‡FáPAx‚àAA æ\À’9Ìr״Ђ(A ƒÐGEe‚~A­ˆµaj½Ã⥠`¯bõ¥.Â:äÈ XL££]ê›Ôeî\¨læá’ÈDÉ8a àªû¢‘ɸmÈ?Ÿ8‹¶oæƒ!ŸÆ%…£æ«ÛöK!µÀõ‡<´‚:A¨à¾ÃÉ[»mòÓ| .îzC¥œÝ–‘ÔZÀA Š+®1r˰Ë35š†”›O|†›q\‘f$¡@@wN™Ä¦ð€ˆ%wwHÕüÍãôxÿV™upœ‹¾#ÿœÿÓļ&³­”ݲ (mý7ŠmD SwÀ@C”š¾ÅÆâÙ45“Bù²úùÑËFp¢ý5ûDÈÒköÌZõ;ɼã¢îWoÑ2¾.¸S±~ÖíŒ$]B®ªd3„ùNB€è:WÁ¢ž|]Îõn ‘XÛ“iñkœECÑÀWIì%}qÌh¢¿‡kœˆ«ä½ƒYpãG÷]åGÓýaô.Sí0K€ÙKóEñ…‘rÝ©6ÖÒ‘weDج¥œA­þdèÊ?]V6eƈJ.ò94Õ(¬C(¤"@ÉË®hZbo?‡ö¶ZÉrÑ3¦-ÖÖx­ã4g@$p"®w¡‘æ]¾Ã¸È[|a=ÜS²Ûqn’ïðþ1-ñè à±ÝþÈ^²E©—1ÞdÎ-î«AÃLJ’†¹]±pœŒcØyrMÇmtÍät‚©œ€¡@Ú€€€ z~æÆÿ0[³>/Ä}ÃZ¥ñ‡.kÚæ“rêæ‚ ÑpwÜÛÙx²øë숼„’ÝLyiÔÒÒŠ‚ ¨\<3Î(ÏÞÖü;‘ð¼Ë‰ÛRåb¡&ýÔ ½¼à×$”#¤Ög2Ý£¥Ìœdk0*À˜ÄС¨F²X=Áµ?—ì¾ÞÜ1ˆî¢†rÖ‡¶A¡ò5â…„ã9ü+ZÔõ®•ÎW¸9ÃŽÌáž_o$‘T–¹‡[X暇OŠÆ”¥RèÏlC5$xî’ne cðï€Íé„<&0HÖoùq·3òþ޾Oþ°X¾uÊ"Þ»¯îÑAYí쮈J/„þ.Ûwˆ»YU Aå&ñ±¼± ;£ÉïŠPç­+ù‘´m¦ÿÛa.kOÿÔµm’¸7C6]ÐïÐ9|>ÉiGÐüqauÛÂb^Q.¯ã]62‚ûÒ qRrvà©(UP”t±’î˜Nch:€içémï16å…ÿ,ˆ8³GÝi“§‡µ ×…]ÞPƒk³3Wvœ/Cä Žš²Þ¬ü&ŸI_Ÿ»NK…Êï_ª¢¦UCœçPÂsÆ0˜Æ1¨˜Æ0ê"<µö>6Ä]÷ý•óMõ×p4·¥väܦF‘†´Þ_פ¥è£jI]í¨Ï@ID|_éò±l½ LD»4‹ÙÂÐB¸Û´qVye,­mã¿}uJØØÙ¨ÕÚžjEMOÒ©Û‹!sdÛ ©æ}›i¦7=ŧF’Z(:(8ìo¶ù¹Åœ!·ÝÞ`1m»DD»Ã§6£_.±w»ƒ<ÞºÅúI×Óé~Œ>%ÝT“ýH—KûíÔc8Ÿrô£ª‡Äwzb#Ìy›HÃå-zó-bÛ~YE(ûG%ÿòæZ#®Ý6ú’>¡c/úñ.«šÆ¹+4{I³¾5Æ2Î`®lÍ’VáIëèä-Ø6’O×™–xò8Åv›dQp²„D=òY »¹ð›K“69ÃgÇEŽ·¤E­y–G5¡Œk]âÔº†§ì€^x4®žk”Ü\Í»Æažb½’öjÈ šÀI{‰oƒíÒVReLìÔáÊèq Ä~XËÙ¿0¦Vn.¸¸‡ÎÌf«,͹Ð+ÂÆ‘bÌ«Q!ÊÙÜ뇤DH"A Ÿá÷G:wͰÈìü~7¶Ü\!t€P€ã]:«®†£S-ÚÂkÖ Ü2XWíIÍ–ä¼¾ÈfÀëXMA R´¦ž:]3œ:¨³G‡Ù~dø,â¹Ï öíßmY¨Z¹H—[Åg‹¾^ç.'2‚ᩞÎÏœ|TfåÐ o”Þ÷Â>[½­÷Õ·1°mß“ÚÏ’ïmŒfDzè4Ž?V£ÐxSŠß¶´ÛN}•–;F+ˆ¬»¹ÃĤ’_Ütнü4Ó¬q¯†žÃÇÊ<½3ha0’Æ€ÓQ×ûý@ÿzŸó9!~×ÄWÓ$ý^Ȇgò4ôf®¼\,¦/«½G*œà7,àŽñ„DDej"""""5ôvß²ûŬZº;¦ª‰æn»›‰4ô÷Žþ’½ÈâíG{$¸lTLvW.4d™À¤&˜Cß Z§¢e!Dl ®š›wQ—¶” ´þb³‘EÀ5·ë/…Çð’Oô/{Ürºã’¸©$âI„~Êâr^1ÞšÞöGpôÚÜt¢,nìI¢·Ð©»<­¨þè–nçt€BÝHAðŠ©ˆˆ÷ñ›I.ÿ˜,ÕÅà­Är_ÒelL#ÿÁáÿ„•ÞÝlm¿'1pÛBöZê êÒ8ÿ„/ð]¨Ý{ç=Xw• ÞÑT{ûÅŸ7ø+ëL¶9ŽÛ7Ò;í}Îcÿå¹|뎽ss¶‘·£ïQýö¯_½¥ ãd=¡Çͤƒ’m£æwÈeSø­Þe‘o 'H c(ODTú”DÁÉ_'rV[›~Xn›:ýé‚åÌ¡§ŽÛ0[Ç«8¯¡ù£oÜ,4û»ŒßøMÉüUYíOéçFqi2­¯4…ªýÍe4•^hÇ“ #$ùc²´n &³¶)¦¨v¤?bŠZ“MÑ+”—<ɵÅÝü mc-«î%tÅ¡úšÏ¼eaÒ‰«Ç¥mƃcÜd-þ-žî9Ù îÛqn’ïðãQ Ç 7‚Å,5uû(pFAµò­ƒ—s;{žÓ]Úñlj¸2pœ„kÈ—Í$£`5QËGlª™È Ž÷ €€W¤n,w=÷FlWŠ6€¥ñ‡.ii7ÐA¡ZN÷”˜ ¬Yl}î@]ÂM55妭- $OZÂÞ2óÖ6Î\UÜYH8•´ç-ËE³™'1p‹»šˆˆJ%ÙÖe,Ù«½äZ³A >àÄL4×JõžJás›[jEƒÎ´2ê9¥!¡Íx {Ë… IIq¥zJó®idñ[ƒpÉ–Ä»U»âŒ–’æ·I¨p€tu.´M]JQäå½Öœ*¼’©ÁMºt÷©Sµ:¥;‚–”êªm©-N©ANà¨-N©AMºô÷êhBuJU:½Ê^ê”î T¡:¤*›jKSªPSž µ:¥6øûµ©-N©N~J\SªR©·_v¦:¤…"Ôê”ë©-N©áÑRZRǦ¢”èN©MºtÑáN©@ô¨BuHz’Ôê5%©×± 9ô©-N©ãÓSNÄêútÒãÖŠ¤.4€p¤ZO… yêKS¨W‡†§J|UÀÜÃRB*Î*TìM\Ì4¸õ§T€z8pW…"©Wm©¢ujà~zZS⮩¡EUÀÂjhª¸<4´¦®Ì4¸„T…`8ÑÁ:޵p?pQDS±\ J‰ÔŽ•®´¨Š‚¬šTN[x)QM Ξ’ÞTy×T|f~noŸßlÇí[¿ÓȾîÚºx¿ÙÖß¡bÌþÃg+V[†Ï P…øòâDÛ¼EgÀïfœ¦+æt+öã•þVí¯øú¤+òû˜ÿ>fëï{ÏÖ$]2 sÖýÅj5ìHæ(ð§áH륧±:¤ó›¤µ:¤óù* Sª@>Þïr¤µ:ýk|·â\sQp1ÉŠ¯e^ É¹wL`®p&ù€ #¸™DLm<5׺¸ŽÒÝ÷SEK€ ®{x]q3`í8Óþÿ©~½¸c¶m<€l{R%©A`fÔæj‰H‹éiyUP;éG‚)˜ÅŽÕ/h±À@‰ ]wJZü§æmþSzoÛì•Ë¿4á¨ñk#`!¬oê´4t¸’zI_kòÎêô!‚6Öáò¸5ƒq$ç“@]C@Sä̾ò,î—q:„CxöÏdSh†úG~f(è"(]¦gæD†ß16ð€—NÿÚÚ1]†²(4’9¬.r²„A² Z‹xÖ¨¨‚@& •c2”yké¼&ÏÅ lÎ2Û‰mÚÐØèàÀI5{ˆ'ñEI¯Bð»ýÁw5ç} od‡\ƯBå¾ø»ØÙᑈ,¤&Š´ÖÊÖ£¨=‡Æað·ƒ\åéÍñ‚}Ÿ|vÎHæŒÄu·„rMÒ'•¾lëŒ!˜ªöy]Õ_ÊLcÙùËfU„Ë•Œb=‹xâ-ÒÚ®PYS(ªß+í~`s’¬nÙÜøI²¸H˜dŒ¿ÅgCZˈ㕎`Y¬l!-h o¾ç¶.yœóœÁe#Çå%ñ¤cÃx»¤—B÷ÆàãÐç±åŽ>7ŒI.ú¬n¸áMã<«Äo–J=ºdåáìÆ*¡õû1:ÈKBvﺯpEt@ÄA""Øç ÕÓQ1ŽSp󧛼ǵ~ÜØ›zëà²K‡¹ík¸Løà†Þ Ð¸—<,s]B±ønXòëeNÜÖìÌ[ß>È@hipâ+_,“PŠ€4´žp^RûB¸ã–ã{*C#n°‘€Ä6½ic@?:a ùËó ·dúmŽ«rJÊ¢I¤N©¶LSçXêz7(yW/±N‚W6|ýÑk®%h:@mtE4:RKˆî$hn—Ì]ÿ.ñÈ £k¢Ä[‚!cˆÔkö¤}8juÑ@I.'Øþ -Ì?5즻í|ù>½§‰¦nKª&î¹›8]¢öñdnË}¬4ÂnjøŒuÄ«EDë"«RupQC´ ðŽqKŸÆsþÞãkÄ'ÎÃi⌀CôÃ!{%µÕx !Ü|BEë¶}Ê ¡ÏHbÄÉq+^ðH,¬Œ u@4£ôž ·ûCMWGbÿfß6 ÊÊû¾8Î÷¦ ‚]ŒÉ´˜¶#]\°È,ÅÊK£xHÄ·Žv‰®»AYGd"u d÷‹¿æzÝàßÁmœ¾î™† òÙØžE ØÎå¯/oÖ¿KXhçíVß“›^ß*ܶ[;e.݉ÂBÐX×HÐjçw¥¡§€qmK…CCIa?´ßXÎ*3ÅšÏ?yúk…SxÚɸ‹ˆç—<“Èçs—s6Ë$Ýã&<+$b•`M¯l%LVɳrW•÷;3oÌÌës™";*#¡Á’ kG½ÒiWiÁ¡ÇÍ ùæËÆìSœ1V@ˆŸBÒ÷’ ¤€@ñZ7Uu£mãÂoµg XæXÊþâ{£Ú4}8´\r K=lÙ¥ÀŒ#i×ñ,¯.êYšO=³ä¥#WE=MÙ‘Auä'nïÞAn»›¬MŒÙ]“tî†8è–k,kŒ3D f·0Ç &‚¤hôoï£ÍÜù¸ñû¦Òí#Æ è-Dò´5Áì q :øîໃn fÍüFñ#‰2ª6ÜdÉmË »;rZ6QÛ¶.cÌämG2÷<å(FNŒ-š¢Ð‰´rb®e³)Ë—ÜÜÉæ2웵v> !tÏg{rçH×4Nô2&BÍCÆ{žKÛVDv dlítwéËYÞÚîîÖ88E{²é+¨|V†€×QÄð¨Á¼1±®BöÙyµ¬Ÿ…±²¹5høÓý´-›J؇V.%WjH¸÷o’hW/TÞìý-ÁÀ`Ý0úÎghe1|“¾Û }ÎW<,ð$šY¥|šÜ©Ik+¡¢ …ç˜ÍÇaÍ\뙆 Ý´†’ÈãŠ6³H.#KM58ôjqâQ{Q/Ë'!ñ¹%qãûÆÖ¾­ÓØV3"OY× MÏ wº#¶…”„vù‰œ¶1€Lß ˆoW_ùyÄåpÛ*,ŵť躘˜æñ<áBXð×Põqê\ÜäÈØd÷D—XÙḵ6ñøÞÙP F¦’*:ÅVsû^4,ÕR¶)7Ì™€5ŽšO 6îàÂçóRæ¬o,ã™Ñh3Ã$Aô’btÐê ¥hí[O83X|¦2îÚåñ‰5ˆ¥d…µd`j qÓRM:bàþË;öÈǹùiûþòµlhÆ7;›¼n‹f _8”¶TA˜IMÓü=bÛÙ;%ÀàÞ$l$Ϋ7s ưMIM[7ŸN!¼Ûئ7ms(Ñ7`ųääã–@‚cd8ºÕ€ÞüÝ78«)r{6åßÔÔ|@If²Æ¸Å4`–ks rh*@fÀ2ûWšø È]Ga¹àÖ ñ¨ô‡‰#}5iax]ÇpÿÜ"p…*¦fâˆ\Y“’·c¥ËoÙ5·å#¤Ý:dᜠ°æVã‘»¤ˆÍÑ…»dš\‰V2ƒÙ”ÅÊî>aï¾bÙ·llÌ%ýƒ¥{;Û‡:F¹ êw‘²ÔxÎ/%í«CF¢C ³6–˹9íÏ•´»µÚ! cƒ‰WAsÝ#¨|V†€×QÄðªò+äÛ[2çÛ!Ú6\=…mMH »iÂFEIJˆ„‹bÖ*8ª³‡nÞ<²O[²/0‹¥”ÐÆ.ƒ_Jl Ûwkˆ¼¸’òþ&ög¹Î/‘Î.u Év–“¥•㤠€W†ï Äy¬¼ù+hYmg#†ˆšÐÖ4¶¡  D N§õ‰¡_I¡J +Òx-¼S•M´‹Sª@S«¢ µ0R‚SBªPSn=ÚR¢uJ sÒÓØR‚›j SªPS«¢¤µ:¥:êhSªPSn4¼)Õ()S§±:¤*›jKSªP?pT–ª!TÛ¯MM(Š¥:B—UJ uôTÐU m"Ôëõ¤õÔ§T€}ºwxªKSªP??’¦‡©:¤9† uJ¥@zª@?0Ô–§^Ô€z‚ÔëØÌ:l©-N©üþJTìM ˜{¿ÃKÂRùéP„+Þ‘ju)ãRZGR¸<5:Sª@8óëRZUÀüü”¨GB¹†•{S¯j¸ŠŽ ÁJŠªUÀÚxjHEB¸ž§J|UÀÀ=á¥DUX !¶¦5p8tR¡M\n´ªBu*àq£‚8+‚Š"ŠÀ4¨Hé^€p¨–ôY‡Nú‡-~lï¯ß|Ïí[¿Ö$_víÝ<_ìëoбfŸa³ÍÕ–ÅE; žhЊ/Ưæâ?ˆ÷´Í¹X9Ê@ óßi¯jòÙºšàÖ88p=-5 ±c,bg5„jèýÔ¾»ûÓa¥ÎÉP;£2@ñŽÖ*B¡Šæu"V]Crœ„\ŒÊp×@=«¨î¬>ðâwSJöþ4¯"– ‚+¡ßˆ…ÆmÉå‘I2ª·ìÙ9;6.Ö§!¸Š.C³n¡{6ŽJEH"tôï×ýÕ£".–Hõ4ëP=‡á}*íY+ŸÝèêtp¡èãÕÒ»ÊÖ™›R5{_ Ã9go$±¤XJLöq-Ù–& #£ó¤ìL@Ý¢(”ÞQéËZ®FLtÒ6ç 7nÚM#¡Ôé¥WJÊÛÃsLw -ŒW¦€Ôq¨·BÜ®kË5«3p–½’íV(*ÝTõåÝ:'ÿ(w‡–·,LϹ°c¥¾+‡ao¢e mµóÚÏönñ‡€ÿßTeSmd V:©ANzšꔪm×§»Z\ª@S«Ê´Õ:¥:ú*KS)TÛPZUÄÀr‰L€†ƒPYQCШ8Ž ®/iµ~aU0ÜPyuAÖ°×xˆç:›Ò²vùÅâž…°Èpcn™c‰5ïj=êÆÿqÉÐOÜþôe*ªæp–ÓXÀ@Êœ£§~²v˜¸­øÓŠèÜ_¾nKÙhŒ­‹{³>1ÉV ~F–•”<^?{xÛ­oyÔÈV{ÔÔaj/"Iç„;6Ê*›s¤™Œô¢!òùÛ[‚oæZÇ9…ã°M‚0ë‘ ¦‘o3H3÷`‚@¡wI¤¯£¶¦o$.ñR]Û7*é^D&V H3FA—k5Ÿ³Ð ê^Û–¢®™B(bƒQ¯¦¬q/’M%xeÞA¬’…v,¨„z€²žýNþ¦åk5iŠd[ºV.ã éF‘з‰ˆ²‰èb†ø èÏwŽå´ë\V÷„Ô.2À;€±û=ÉäÒ°ÇúÒ§JÉz7¦œW5‡·[Æ¢bœÁ ˆÖNÛÈJq]ï_3«Ôí¤Q~/ü¡6õq·ÖÍÞõÕS¯œè»µ¿ÊGI° ~PÐÉ]‹›a‹¹9›¾wÎ&m­¶våõ´÷mÝãô±Üʘ¢da¬säuK†HpÛ0{iíLŒYüînÒx­Ý®6 ÔáÅ®á$Ž~“ã1µÔ©ÌŽ3øoŧY&«¶Öd$Te‹bñ;7ÊZ°¤^' ñóeff%Þ½Gß GLÂ& ˆû_(ö<»'nɸ-vAï3N[Å¢G†‚ÐzÃÖ2¿Ö-$p+Ëyº£Ý9™r0‚Û6°G<¡¤Hê.sœêuCкÆRÜm,Ô…P ƒ§.µí· ¸`í/,†íð¾ ð\8,ÀÛ€±û-{ÚòiX¿îgÖ•:Wûͧ«ŠçöõºÞºŸNQQÖ²V¶ ·+£qvé…ÌJ§Uw WV©ANòR¢uJ mêT Õ()RZR‚›u¨-N©J¦Ý*KSªPS¯¢¦…:¥*›z†•uJ uT–§T ¦ÝjKSªR©ÕPZª©AN¾ŠT(ªB©·¨iP'T §=NžÄê”ÛÝîÔ–§T€~®Š‚ÕUJ Á©¥T ¦Ý)xUU()J€ô"©û{½Ê’ÕUHç©-ERüÃÔ5%ªª”çòTТ©NaÖ—´ÒéiìN½‰@üÃRZ{UÀüõ%©Õ ˜zªKSª@??’•èM!OÌ4¼)Õ •èE{ù†‘ ×µ zjKS±\$ê=5%¡:«Ã¢•M yéxQ^Õp=¯B~p7w†¦‰Ôõ«‡ŸÇH„pêWóÔéOЏ0Ò¢*®-Nš¸:)P„Õ€iU:•èÏ ÉoC”t0¯Íõûï™ý«wúÄ‹îí¡û§‹ýmú,Úì6y+U[†Ï%_‹Ž' »Ä§¥æÎ9d•%¨ª@8ôÔéNªàpèé¤ZRƦ‰Ô,ºÀ²ní“°s’®î¹†êFYé²Px9 7mÓ‘¼£9)D·vÑ&{ÅÉu= ¢D5Ò÷;,ïíÍ•ûÚÌcf¸ÿã2&6ÿhx²½Òqš;£Q![Ö"9mìc’÷Ť´ÿd¸ŸÂ;Òõbâ¾,¢ZSØ®Š!bÏ02“nc·`÷ã çOdä]H¹xåc‚Š*(î Óå•,ðÙÙ3po9|Y¥¿ûόǚ½º"kXƱ­hZÝU¡è[ìw°Eg&66-ˆGÀôõ¹Î$’I4&€à±êÊOcI+fÁô)ËÊžJBkµŠX±æ`Ì¢éI4gÔC&]æL"";Îç¾›rn(ò¹ímŠ2ØéÝ3V³À¸¹ÏwŠ ñkAÂu1ï8ëSmdiª¤“ýcBßM+Ú±[+ÚºÅUäD¢AA“täRNc³ª›ÄXÇ•”I”jMÑÞÞß2¯x“—~Âgv´÷ÝÙŠéÒ-% 7‡M$þ%‡¼°»kìãÓÇ£²µXH³"Oª¢· ÈѲ+˪V+Ò©DD=ñ‰p£aŠ;½ü3Õ±ZÈ!¦¯u‰‰%•¥¢wzš½»v´”ÈÊ”aíkqÂÅ“¶žÄ¤Ôc6…AÊŽ»PÊw5Ð4Þ×½ÉZ”ù˜ÍÀö[#ƒZ$ÔÒãSð,£E§Ü¦kÞtpâ8žž¥Æ®; 2¶mEfßM̵E»øÒ¼·n¨¶äUÂnÜ<1 Ýx¥ÌàSéÈ`(ià¬Ø›q\Êö°C¨#[xPtb½œ+ÿ¦·ûnH\Y¸b ÙÂÛ±³íˆ`Ý%ÎÌW v…)ŠþN4‚`å×R‰uõsœniÃSîŸÓý ªeÍ›>Í»^>’» ƒf~›Þ"Ù´4pDníf—fRM3iƒ„‚8tÔG”G¾нÆI+÷‹«‡šIOÔ?Ì»L¿ Å ÞÊT­W:Ü-´½¸ª×1m§O"Z,»¸›RÊ¡'èm½<ȶ(ɦAtQT8{”+·q6RÙß’{~Ûº*hhMkÙõ®Åíëû÷ËÓV´ô V”!b¬­ÓsK¨ç³ÌkªíMÙ€öZÖháqђﺆÝ'€qúÇêXæß]HÆ»¾&¿WÔ¶ÛžàNï4¡4ÂnNÉùݱtäȱ"ï cvÀ€:Q@ß05åÛ]KhÙ÷'21¡Ìs™ÑNƒÃ¢Ÿ÷.Ôã/‰.i wOhãÓÚ»/¸{öpÌž÷¢ä´ASDª·UC¹HÔGû$Êp&¥8sVW÷eþ½ø¨íô,&ᎌ†N±©§ê5 °ANºÎÐ-f©M¾>í)§T ~%AjuìJ s IjuH TЧTÀ§]*êÛ§¹Hµ:¥÷AjuJU9†¤µ:¥*hSªÙeâ“•(úò t/,Ûr(WnÚäÀVáÌ‘È%ä »ka4Ž…3Ìev¢·Sú¹ËW R•Mµªª”ê©¡N©AN¿%*'T ¦ßN”ꔩ-N©J¦Ýj SªR©·Or¤‚SŸÖ¨R•M¾:E©Õ()ÕPZª©ANº‚ÔꔪmñÔЧTÀ§WE*ÁJU:Ý©-N©J¦Ý*KSªPS¸*4§UµËF!*€¤§. <¾}Úê\Ú¶áš\»\:T.¾=‚ A5L ˆ÷€G½­`Ý…p4i:VU¹0EHâ¹½k¶ˆþÓ@2Ÿí‡”u®ý¦5–ü¬º—7¯›‡Rç%S@Ъ²«¥T §UN’R‚äTN©A]¾:šê˜ç©-N©J¦Ýj UU)TÛ§¹S¤§T §^ÐþŠI‚”ªmñ÷êhªPSª‘juJ uÔ§T¥SnžçôT§T §pRLÄ¥Sn¾í*ê”ê©-N©ANº‚ÔêªmÓÜ©-UT §?“ú)qLÄ ¦ÝzjhT §U"ÕUJ mÖ µ:¤6éRZR‚u4!:¤*›téîÒ—…:¥)R½ Õ(˜jKQT€~z’ÕUH s»Z‚Ôêçä¥Å:¥6ëK‡Z*´§R·ü5%©×êH N”êÌ:ô÷kRZRùù)P¦·^ï%.iÕ •;^Ä€naîè©!:ö«úêKS¯b¸<¥I Õ zjt¦®Žš8„ê4¸"½©ôS±?¸¦‰×µ\=5$#À® -)Ô«€ó I©ÕzcÂ:[Ði9J>2kóW}þüfjÝþ±"ûÃgþébÿg[~…‹7ûÖ­Çé[GŒhãô¡~'8¢6œLñQöuËɲÿ¸¿p¹LßùU¶áüwêp¯Ë~`þþç?kÞ~±"èÐ0†·ò£R4¨B¸„øõ$s .íWóù)iM\ Ò¤„ê»âؾ$¬·ökæïå±R)á»n–nÖUË9-Y®DÀP6ìТUDÁ¾dÌÐy5›üU¶V) {é èK€:A”8}!•Óô¯B³•ñXC§ Æßõ?γ/[ ú䞺̻‚,Æß¥p+µœ3)E”„nvM¤ÛÆÌ‚ÅÜpÕœ„`.;¥WU›PPÇï‰Aþµ™Û¯{îd‰ä9Ѱ´‘Ð\ uôW‡Ô°»™´²ü@t•´ Óñ.. mÒ¶ÒÕ¥U()SNÄêªmÒ—…4 §pR êL…SoPÔ–§^Ô §UIjuJU6ëPZWzYü5ñ[äºìœ•®›id޳YÈ+䑌M08œb¶Ž:RÂQLCF¨ïh]5Ò²ÜÆØ8+ó‹Ìæ±vÙhèå¹…a4ûm/?×ÓÃBÙñû3wemþ7=‘d9®èÚ;£úµ]E%' ò&f=ôL¬s…ZHFI´pÂA‹´L$Y³Æn“IÃg 41R˜£È![e½Åµä º´‘’ÚÈÐæ½Žcšz×4Aê Э~hf¶™Ö÷ tw 4s\ \Ò:A„ÖªùM½C\¥«Ž©AJ’ÔÁJU9† µ:¥:©P§T §@ÔÐ'T ¦ß"Ôꔨ-UUÝ–gù÷!Áý¦±°ÎN»-ÑŠ36MÃ#ðSíRG¾nÀíä•HɈˆS b€é™Ž`lLï÷no1µÈuÇ-ÄL{kJkiuX x©l¸ÝŸºòö¿}Åão§³ê|pÈæÝ$6ާXmHúÂêéX¹{~Mì,ô\”Ìkƒµ’‰—dæ6J=Òc¢Ÿ0z’.š¸LGßBÁá Ùín­oí™yc,sÙÈÐæ=Žcšz \ÒZàzˆ$,ŽŤñܰÑÌsK\Ò:œ×Aú øÁN¾Šç \UJ mñÔ–§T §UAjuJ uÔ–§T¥SmM uLU;‚• R•Mºûµ%©Õ)TÛ¥AjuJ ]Iju]fáü¿‘#šÇø«$_PÍ_+æZϱ®{š1¼š-Ú»Z9wð±oZ¤ý¯QTȘà¡SX†ÐåÖòû¿iíû–Ù粘ë+Ç0<2{˜aya.hxli-.k€p%®¨+7ŽÛ›‹1¹ÄØ^Ý[5å¥ðÁ,­Òæ5À84‘ZЃÐBäR|;ñ #55‚3444Cr’ÒÒ˜Â÷aÝGoäd_»ƒE«&,š¤uYS4Ó(˜Â5жæÀ¾¹ŽÎÏ9‡šògµ‘ÆËËg=ïy kÖÈKœçÐ $€Wn}»í`}ÍÎ+%´l.{Ým3ZÖ´UÎs‹kZ$’¤®Ÿ:ú+n-Zà)J¦Ú‚ÕUJ utTéìLÉUµî¦ÖÛ+É͵>…¡%$´<}Ö¼4Š6ÛùvégL§Nرn¤I#èS*R”DJXæe1rd_‡Žæe£ŒHøŒ362@tUÖI8€ÒH¡]ÇX_²É¹'Á3qÏyce,pÏK%4— - u-Û§Mw¨ ê×µ0)Ü%©Õ()·Z‚ÔꔪmÓÜ©-*ª”ëÚ(¯bb©·Çߥ@SªPSª¤µUR‚u©Õ)TÛ§Oz¤´§UºEGÊMÈ3ˆ…/- ¹0ŒŠhâBAó•9nÍ“TÕråsøB˜Ãà ë]\ÛY[¾îöHáµµsÞàÖ4’ç8€í$Ío÷S6ÞÕ’áækAsœOPh“ô»>êÁY²Å‡ûCxâ|‡mAµ˜š´g#㚊›€™æûª8çÏu:t´:®œKAë ;Ú{£m÷Ì–>ò N·¾µ£ÿ-£~€ê~%ÕeSn•´­~©ANº‚Ôꔪmê’ÒR‚]•U)Të÷jhT ¦Ý)ªªPS® µ:¤*›z†§JuíJ wJu[¤T|œä‹xXçÓòncÑÃù)®T*MÙ±bÑ5];táSHše1Îa®½ÕÍ­•»ï/dd6‘4¹ï{ƒÆRç9Ä5­‰$€Jæ·‚{©ÙmjÇÉs#ƒZÖç9Ç€ h©$žR¾‰h©{zMì$üT”Ìjæk#0ÅÔd›$Ó}»ÖRAÓUɨjES½ê‹K«L…³/l%Ž{9©’F潎ok\ÒZáô‚B»›{›9Ýkyâ¹a£˜ö–=§±Íp Š¯¹Ý¹rÇBCܲüÛrâ;äíûäKö°“ªE¸3I4áåVnFgŽtQIpACŠ*”ú%uâÈãn/fÆÛÜ@ü¸i–&È×IxÔÃ$`—3[|fêPâ*$–7ÐZÅ}42²ÊbáŽc„rš;CÈÒí'ƒ´“CÀñ[@)·Jí–®µR‚ÁJ…0{M½CK‡ZuJ祧±:¤íî÷j Sª@?pT–§T }ºÔ–§U¿ÅÛ×Ó ™Hx ¹XËq²O. È§ÏØA4\çMS/ «x¶Ë(™ŠE2e0”@Dº79,}”ðÚÞ\AÍË‹bcÞÖ>WRØÚâ È  ·oc}u ·°Ë%¼ ‘ÍcœØÚz È0P´‚uÜ ]T€p¤Zª¿Z@8óÔ¢£À‹UU yõ¨-EUÀáÑKŠi@ý~Z\ð¤…Sª¸˜jHE{Rùêtªª¸˜jHíERÇÃËS§±5p8søèâRÆ—pW…*'Ç©\ ÍH„ëÚ½Já-ë}°éßI!ñ¦Aäñ׿ŽüýøÌþÖ»ýbE÷–ÏýÒÅþζý sv=ÚÖ©ÿn…±)Ø÷kGýº¿ ó—Ão&A¸k÷”£þUmŸø{úœ+òߘ5ø÷9û^óõ‰Dƒ¢½…jWxjH Õ\ÏKJÀÜÃRBu*àq¥Døx„ø¬ýáfÖ°²L;«{#½fÙx™f,.ÎÈPP¥e1©*Ø®ÖE·¤‹cœ ¢NÓ7¾˜µáüÁÍn-»vëœn– *ÙÚ5jh5{ÚŽ%ºÀà[N{Ô³Çå,!mì¢'†Q„Ò„´é-5 vÇ¡f]ÊâÚ‹;´Å™êˆç|G tìˆ)»bš´D…&ºróù~,dïešNíŽ"MÀPº¼ZâOk‰4Y›è ¶yŽ*<4‘¨Vœ:8Àº=ò-U6ôö†9Îc&át\{³X"tÛ  S€ººÖóo$ÌŒ‰t:ƒ¨Ö+ÒOWÒ°R†Ö­è[S(øÅc§"&£[º„¸Ìñ)ÖÆ(œ’MÙòÙN]ôÑ @£¼÷À 4ï"/s$µqmËÓJñ ð÷öp+‰²¸¾ÁXÃ/·¼œ^J䘈zví£!Ú,“uaH¡Ô¥ èê&w*¶ä1S\Û†ÿ-g¡Ý»Šä‹(àcdŒMzOgi§«é\BÂÑÕsÜü:ðùkaù †ç†œuq’êdÍ87Ί܆g¨Û–ªº§dºª»L¦*Å0ˆ<5ªîLÕæWL tN:À¯:EOObîE¬žéÇU>•”ïÛBL£gì“{ènÌ".›”ÄIôzåY£Ä¨Š6] ÝÐu.µ©1·1=¤º­ =GªŸŽ«•²ž£Ä-åÀ¢šn7Žeç÷¤Pºo Îrˆ‰Í®¿äë]i-ËYZŽŠPt ó®Q3öŠÐË‘EWQ¾è”Ü@ê€ t€Â:{ã”F˜Œµl½5¯ƒÂ¨=äTNÅMÅ`0‰È¡•ô(¨•0H»„1D…0‰‡Qðìä«€é#Å"”êÝ)§T ë ‚Ôê®ÛÝîT–§T §=M uJU6õRð§UœÏœUgåž#áÓÈlI/aã«^éË7\"‰tg#¬v$vÖ)Ëeqã'.Z‹†æ‘Ër#éÄCÆ9õº2Û[—³;!‹9¹†Æ ¡÷.-sÁZá~‡ 8µÀÔ霦ÁcóÛÂ1–h“g·R³¤=°¶¡¤u´¼·Sx‡6­"„® •øÄâ,߯¯—Ù*ñ¶ {[^سîy»rÛ²#˜¥Šˆ¶#"1lÁ(ÆÉ&Nܤ œ¢§2‚&¬Þ×å&ÄÚØ6a!ÇZ\šiáŽY®^~Ü“=íqqy$é'KAÒÐX¼÷0·f{*윷·xß›Ž_p´}–FÖ††Š ©ÄUÄž+(3$œNðAmñ+y&ƒœß‡rÂXZø¼Á² ¤r‘)„ͯ)q(܈¥!7åê “WtV2ETê‰Ê!æ»FѼ¶çEÇ.±ÍÙy|YÈ[[Ô–ZܲC̈Kc”5Ò×Hq`m(Ví¸®½¹gòÈ€íÍŽ¿sM@q ˜¤¥žÂàÀzHÔOH_~Vàç…®®è[S3q?v%!u[öôÜTU•‹BfJÙe8ܦ4ýò²³ Å¤Y•R¢ÍºYûa)ä)¸6·79›¿±Se6~Úµ0ZÏ,o}ÅïvÉÿelZœý:K¤“DMqÑWHäÏrïcm„v7p%ž(ÞÖÃm­Ñµãý¤Ä¿HmjªBѪ‚ ·W€‹õ§ {y[Œ­[VÊ[-Îfw/öEžA’oÍ’NUU@2jvhÙL^ß±)œÄÎz`ååí¾ö†Îáù;«Ác<ß» \[÷]D8]æŸödÈaʬ¬{Æm¯-Ä-±‚ØÝ>ðƒÝ 05wúA' éÑ«íÔjÒ Öû ÂÇÙ±­Ùnð½o Ó-Zì…ÊÆÊÈ8ä–ƒLŸ™Uš I¤Ì‚í%†ª·`ùHX ÂU“é^s?~lÙmrËÂZYí[»†Bë‹[¾ýÖoÒ?½1Ñ´9„ø¯’7im âKîÕ¶ÅÚ{–;‹M‘”¸¹ÏÛÂé öýйk_Ü8=Ä:œZÇG£€pÙ1_ ¸Âãá¥&2–p[Û-rÃüy) …ž­É1,›[sã†m,ä[I¶4¥Õ*ñBp Ú6d“‡j, ‡f~îçæ~åÇóܸÛ8Q‘É;Û¦HgÆÂé{·:à–1 MÔ÷Èèâk*ýC«ƒØ˜KÍ–7¦s&l¬›~ëw0Bd{€X€áªW ;KZÀùïIã÷‡kÈŘ×=áŒ7bl3;i˜.Ëu bîµ.û|uâeÙ³bñ)ÍÖYP0„OAÞæÈì^`fó[Ÿ#±w…„6;« sþbS4Á-(øÜæµÍ,%­s\*I¨¥×´1˜Ì–êÛ—rÝà/$|_ŒG,RÇÒÇ€ç4‡\<ë¨+Ч]zÉjóê­îÞuÚvÄóe^Á¡-´Ë$dÖy“ÄO"Õ”éЏfS¢(€Žº‡~ºwñÝÉc4vN ½tO¸ô5å¤1ÄPÔPžv-.¢}ÓKíD/¤°¨Ž$Tt¯o¸Žµ8¶Î× ån òãË󷇶‚ôpÎUoe<Æì"¡#›))`nØrÎi6Êt©.ôtÓ1S*eI?Œ9y”åNÈÃ|/ÍìS,wæ›ï3ä,ÃnÜùDŒºîæk£, T–ÇPçââç}5¼¬9º2_ßܺÈ:ëkãî"³º›vµ¸Èxp&”sè@ 0+‰kû0gÃãÜŸˆå­®!m¸¶XÞfb]›È»»+/+*Í•âZìTaRzŠÊ*šNˆ£„ß ¡9LRB½Ë—8-¥²±|þÚËEs°.%uÜqÆæ¾ Æ9×’5ï«H .a 1è ’Jò­é•Ü;Ÿ#ŽÄg1òC»¡`·{Þ eº.pl%ì-m5À¸?UA‹³¤øPáŽË¾Ú`ŒƒÅÌfnYÄ|,ÄŒ7ø×Ú7„¢hú=¯1p¸žc.÷°tá4W|š)7ncÿnŠj”šÕ·4¹“˜Á¿|`vÌ2l°×É%»Ñ}=» ¬ÑÄ"tm«Asc.sžˆ^ÒsSì-“Ê·jåó’3sÖ=Ì·×iÎ¥"|…í{¨Hx­¯¦Ž¯`ø8ŸBW‹býž=µtð¿b¿¼gl.Ã7)œÇwN\Ç.Ê&n-D·\Q2‚‚å&¨~÷›¶/µÚÙ<xÆn[æÀçètàú´‡>7‡1íÔ¦š8Ž+mË›¦OŸ±ÊÊ`¾ÁÚºRÝM–œ[BKHcÛG5Ô®— ¯°F i˜¬Î n·+˜0ž.y‘2B1'éÜ 6Qr[…”zÔc’?cþêR¬!¯ù5°o}ñ6ÑÌ`qqÛ6værm´./-1Žkµž?d–øV#kmX÷7-~ùÌGbn ﯊MFžŽšÈ{{„\…°¦vÍ\D«mœ«w({n>Ëyp]®& §RˆbÊ×i»Ó=ŠI¨,æIû„’M™½!Îè¦&æÆô»Þ9‘³vø¿Ébä€wϸlPåˆÈçLç†éyv–CLƒ¼y-vû>^í‹}µŒÝ;—0lì¯Ù/æÛ ’Rö<1¢ Òu0 ºG¸Ï´%àŽ'Ãf$³±¥–¸‰Ë%•“Ö˜qЬkÍFæ¾®;V)âmò—<œ¤LU»àU!ÐI]ãºI@:gÔ @ÊÞóuå÷%ÖÕåö*ÚòïØÅíÍÍÁ†Ú)žÒï»Ç¡’>WŠç6Ž®Xë]—·ñØ[}Á¼/æ¶·¾/6°A’y"i§|ýNc#i¨-‹¨=!n¡ÁQ.¼•aÁbLµmÞX²ý²&²Y²t“% ÏaÙÖš¨%y+~Û>–íäL¥¼«¶é1P©»UÊZ"‰Å>©ç!ÅíËëí׊¸³Üö7±ÙýÍŽ}æâpM¸µ›KZöJçBXÖ;ƒˆhw8å ¿ÍZZíü„8+»WÜýåÍ,0Cc(y4 , ¸—4}­Mn¹6mŽ;7·®s„ɽѱҴBøåcƒÙF¢Ð+S¨PÑGÉ?ü%AÞq¸š‰k®bþ~þ*ÕÓbc¸ù¼Y;4 HÝ™%¹BNu“'.Šš®›>ºˆ$%9K®·~óZ÷&ê°Û–°àcò6 ›·Gzø£©.Ð!ÑœHcÍGki9“´y}k’fß¼ÍÏ&Yïk °[µö­{éA«½Ôö´ ›Àÿ£BÑ85}ugŒÙ‚o;ê2Ì’ÃÖ%Ýw¸º Ðîm÷¿g¤-¦ì\?QuZ9‹€¹ñWŠ*Ýÿ¹k¹¹9Ã/cawÆÆKË|½ôui•½ë&. 8>V¾YP×8ý [ Ëio÷^Ojä®Ùm>6ÒYŒ´¬nîÝiq$ÆæÈ]BZÙ%}Iðá…o¬”æpng¹okÏ Z®/‹¢6ä°¾ÊÀ]V¤P˜'æm–w&ÍÔˆ+7É‚ÊJA!DÂbñžbo<&g½°öÖXlÍж…ðÝwòÁ;ÿÙGp45Ž/>)1 Ôê4¡±²öÆWsµ²SÜäñ–æy[$ÔrÄÏö„ë.£5‚µ¥€q¤(µrçy"ã±còS©„1­¥fZhÜ×Läd „™ÊÝRC!'Â.«‰&cv®ˆ`Q3h ÞËoÍɺ®¶žÀÇ[ß\c[¼žâs ¾P\È¡sä-¸FZá^ަ?há-0û‡x^Ík ëž-¢†!,¯lfŽ•ÚœÆµÄ:\ A¢Þr ¬`pÜç_ëå¥8u±¶¥²µ¤“sAËÛ‘Œ}!’ܵ9†xÞž è›3¶PJ¢©€(==³ÍY¯çÜqîËâ›·#ÓRa9=äs=Ô-kC‡æ‡u§Œí«Zïv3¼¾ŠÎ,+öíáÈÓålUˆÄ‡ÆÖÔ8öž=x0´Ð¹¼W+ÿ« /‚a'üJM/ ¨ZÎ&Zc£+‰™_\}–Vei¤f”I“zä{"6€¨bH¿â72eÂé܇á.뾺î—榮øF#1‚cüà‹Q}›7/Ä]çt^-ëhÙ맺// ˆd mx:ä "ãÆ7µÏîæ…eqÚRîá¥EAU¹—lxéšÆ"b»ÍÌESt½¢*ÚºW¯à3˜íË…¶Ïbœ_Ž»‰²0‘CCÒ8ÑÍ5k…Mê^m—Å^àò“â2 Ó{o!cÀâ*:Áëk…ÓN ‚¸™TÛ¯k-¤,}V{ð)w[2Ù†·•»²Åç×·0õýu,›(h[ñ3øñ–]' ¡ßÌ“ÑÁ ˜¢‰ŠMå T•ðŽxâr7ö˜‹Ãgq‘Ú¶y6BÖ]$‘ø®Ð263¯S¡Ô ¨Ð\ßYåNBÊÒç%l.a²Ü6F;;‰Hk!>3uCÿKˆê T×vÌ+~>¸l¸~_0/cµ™IÝòô[(X÷eºùƒ´žº—ô) ­H¶Å"¿¦8j‘ŠSTNrŸU½“üÆÇŒ{ NákÙÜHÛqes­sK[¦@xiîÚ÷_h#aµg76MáËe"¼Èá‹]ß1Ó¨%Í!Åú])hã«[šÅ$Wĸb'-þ¥d«Šámˆp¦?p”Å6£'—CƸ$VNÛ²í–;'óNJ€(c¦T‹º¢€"rþ£º÷•ÞÓþíÛxûwe÷ûK"Œ9°µÝÓšâgB(ÇP\jÖžÃ@ÛÛbßpýû7{3qÛḃHúK{Çî›â™x6¤Š 8ô€yeÀqµÏŒï£ÃÞHŸ½ZãQdã YW¥®µvÄÀH,£v÷LZ‘ò2QÓ1I¬‘ÅÁ ¸vÉNqïqXýý¸ñ›’Ïls”™-BÖâÞc4•€ ÃØÇÆòÐMCÜCZ:HÈ^m %þç=³¯fºŽÇI¸‚x„r²7¬Òç5ì¨:€¡h“Ð=_…Ì-ecÜ]’2Î{ql²ÉØý¥ÑjÅZ¥î‡NÛ‘ÁÙ¢F*?I­¼Äª¦S?p™{UOÙ”€%¬|ÏÞy­Á“Û›SÛ™±—î†IßpØá´Ð8ê .•Ô$DÂt´j$‚²¯Ø[c‡°Íî» ŠúÌJÈ™ |¥äVƒIp¶ wޤÐEÓÏ›^V¡4òú·ò•™hÞVÙ£SŒs6ÚìA»2MãÔP~‹òöb˜«¼P‚`.ðVå±÷ÈÜø{ûܼ,±Èbï'·ºYxŒÁÄ»QkIioé¥C€­³ºö™Àäí-qÒ:îÎþÚ­äÒ^%à§QÁÜ)^°M*»b_„èç[«Edfd·±u”ÖñÌ*b!Da¬´o)4“F,ݪ¬ÚÌÑ~‚h"URUuûB›³Ž%Õ-9¹#ö5®íºÇ<ä2—®·°³Ž@d¸%å‘—9Í0â×8µÍkt‘«SAØ.9pÆî˹ozß¹ØZ‰¯.^ x i:ËCšÚ‚çjN“AgÃæÊׂ|<勞ë¾ìˆ×BöUóe¥m«xÀÄn »Û9û)7Àg­ˆ¡L“ ƒ…·€=茒ówí‹Ë7smk‚½°‹‹kƒ0·–J÷m¸k˜ßЇHá´ë¨ #Ù»o=mr6vB{Œµ¬.”Ã<#4lûn…Ís¼aÒá¨×«‰_e‹Ã>0w„ì\픳_éí±rÎܯâR¶ÎN.æEÔ{–ËV ®âEg`Ðë9UDJ“4ÀÛûÁ\YÎeîx·¥öÆÛ_ï ´ÈÇ™„Q#÷:g8ÀÝA¬hqt‡¢”+“±°2m{MÙžÊ}ÎÂydc˜"2<–8µ¢ ÒK‰¡.% 0tÖ«'IÖreµ¾ùyHòÒ(BI9@Z¹ˆIâÉÆ¾rÔÅ)›.í‘H¡Ó!Œ! i^½bë¹la’ýŠýÑ0ÈÆA’‚ö‡u†º °*¼Þí¶ÑÝÊË7¹ö‘ÁŽ"…̆¸Ž¢[BGQà¶â©¶»«‚«1øJl¢9Sˆ™D’3,d:qmzBbtdÛØŽ-‹¨¦>ñb »•×8€Q1>È`ñîlHü·÷_/m‰ï³w­PжÊÚ“\º½D†µ££U\Úž úW.ØÜqÈo9À1b­IŠ£ºž±@>šç4é[¯¨—"Ú8o‰¦"Šd›e;;#=ÍæùFÁH°Ï¼)4ìrC´MväL(·›MâëÕå{ÎÝËf9i9!¸Û“qiZñ²º=ãZÞÞæG¼ôj}A\ûùƒ5Æo¨…]}†ç躷]ÙÞ°4témOH]“0ÎÙ’á‹7”«È;iÕßšÓ“’aY·H/é6!"Ìá©]‘˦‘ÀNR(&åÓA×,æÉÛs3}O‡‰“ä›gŽÐÇ?»i?uejú;MWH…j³—1XO±6”Y9‹®oµ9¬ÖGûéâÔV® Ã1ÌwávëÛÓÀuà B(-cd¸<9¦Ži.uÚ<†ñ.ªêȰVN”°pÆožŸÉíXH9€gvØå¶­\„ê)¢¯GÛrE—vö%Â[(¢^š˜Ê^þèåÚo÷þùÛ6±ç·ž }°ùÙ]Ï}=£^àÖ¾fwml€8€îìð'¶8 M›´³×ÄmŒ¬ÓgšÇÄÐwQ\âØ¬¹†€‘¬q§eHÛq_ –Ù‡¦³GÊdÆÖ®Pua\LßÛÎez3(‰S’£W!!s;–+b³wRI59„1³ºy‘—Åov~ÝÅœåÖ-·P¹²†6®–F~qÎ Yy“U\âÖW.¾ßØøÜ†Ú—ræòp¶·¿6ò5Ñ—:ñ:)sô†R€<š4…¼[|9bKžÇÉU,ØîX¹ ­¬Ê^^ÐtêJ~xÈÇ©¸cƒ†¯”¸^:ìh)¦EU! ažK˜»³œÆíga[q¹/±îÑÇpÖ²)ÞÒ!h‰­f§IRx†µ¥Ä.Í–ÉÛ—ø«íÀÜ£¡ÁÚ^ˆš÷ÂK¤ak\ Xwxâí-eá©ÎÃòn±£±D>nÄW¬åÛc¹¼W°'˜Ý0-àn+zåN3ã†à©>zÉã'qâSï³ L'0'™Û;×9qº¦Ù;ºÊ LÛlÅÔN‚S,RÂ_Ýš5®kšúŠš;€bó»[Þ‹um»©nq.¹6ò6XÄrG(n±].s\ÒÞ<:*:jiÉßáþ,3D@äŒí;!xHÅÇȈ0µ#n«JÒ^A P#ßOšt§]™NTY¤]À6šã ÞÆÏ ¯öÞ ðñÊæG÷Ùßó†kl]Õ"èox領]ù¶ÎÈÄ­3™iŸ“|msþë e†áö]'yùÂÞ“ }ªîž°%±ŽxÎaŒr«+ ÌIÊYml£)n_ÑòÖ<ìŠ%›É,ªP¦‰9œLGEÍ»2ÁºµiœÀß¹=ÇÉ™7>Þ‰ö¢IË“ßMjøîba–d×%PX{§ê ±m7gØa9žÌjF\1Ï€wAñÜ5ðHà^Hf–UÝüãt‚x9ut>>} ÅKìa•®¤,»*Ù‚‘’cñÄI^àöBDŽ fc“–PØC?IR íBŽöéuÒ¶{ÍÁsæÕƒsâ­]𽹕Œw{Þ›m,e%æ1WÈÒ ‡‹CÂ¥köØX%¶Üà27 ÅÚÁœÞï»ês«Û¯ƒXàtŸ½4 ©³!mãñ]ÅoÎ9¹í|«b²ºbd–+ÛLqo=mœ»œÁ,²:€!¾et†œ»fÎÝÒî;Œ®;!mr˜«çA#õ+Õ!´€âPoO®îm´Ì8ûÛ)]qÈZ6V8·I­$Š€š˜Éh'¬ž…Û’œ$¹m•c1[KѲàñ‹ ‘™.9˜ÿF†Æ-Å$fÙ¨VîÖVWâÆ‹ dͼoé$׳)T9u+^mG&Õ—uKdçE>Möxøc~©/N­¸U 3[ƒ6š‰h;Ç.ÍÃÞŽé¢H¬s{#ÛFZ:žÓBKô‚Ò8·V¡ö@$R/✅Á ‚rµÇsd+väÛ[^ï³ n7¾™EªI…¤õ¼“Å[¾"Z¨‹GIöÊ€€éJ¢„»­ý»¶Ä–÷›ïmm·®&lnžÞã¾6®wí,h-¯HÃ¥½ ìmé G¥"ªBG-›Ë‘E é9; y5QòždZg`æp>xuw‘‘S,tñšA#ÓÒà <`¦ìKŒ}Äc2d†T»û$õø*(OUGUVkHÆÈÛî“¶%ç+$@nv©¼rF6Фw"ä­âç á14A@[]wÒ †•æy»+æ ÎåÑV ð¨i„xÍ¡áÄ}kn½ÅÏm!Š'°tPôƒÐGQ¯Ð¶ÇÆU±»ŒLŠæHçHH¢ªÞNØ€:öb òVjôt/•þ©­ÄJÃô­˜ÆjìälOHjSHs&ºº@JÂsv…Ð4]à×@Ò÷isº¼+¦8tš…Ä%!¤Ñjç}Gj šŠŠIûS.rh`íìN˜ÉŽ‚!¯'‚³6—VÒHÑP$ T‚8£é¯RêÈÉ#ããið™sì9-!+f ¤³BF¹m3(Ù…ÒlœsS¦1äjˆ¥ì„‚n]Ð.ÊÔw,‹&ã ]£iÄ’H$ŸÁô®í±kâñxËÔ)OÆx.ÞMÙLCé¡Ä¿Û)¸c§ìÓÜÔ *x’µÇBC…xu ý&¾Ùèéÿx(I^ÇtÀ "øE1 ö€A|Dˆ`Ôû¾ÀÔhužº‚5Úð¯i?ç)‰h>Áü?÷-í“—àS¡¡Ûn½²¤M$„å8 j¨ªÇM4ÌTÇP.£ËÊ5Òš{~JÑ-iARiÖ'_à]¸m¯&«âˆèë&£ë4[ÜkB¬à)0YP"mdÑzä `)^>7f͸€j"'8ìïWNæg2>ùwQ‘þÒâ¬oþ«\~ ²Ö±Èá“5Òö £à/û#ð•Ü6ý¨ñ€œ‰Ã¶Pÿè‹ìËâî’jþ‰„ºî¢u÷Õ¦ä2ÐÈx<££PÓOQlc¤ý.'À¶;k e>ï飵Jÿ ¿ú£ÿ >µÄstls otÄôm%w4û(È[6ºzêX¾Š ‰S!—t©ö§7„5ËìÉnï³öóÞ=ò[Z“;µgM  ð.¦P[ÇlYnƳX é$ŸÆh¼QÈ­˜Â\jÆ»$ƒ[Q‡ZA!Éô¿¤.öqÂ"_xfä–vª(˜¼†A }gµÛ$ØßïšXû§™OKYÁ±ƒØK@q®+Å7<ÍvKîÌ5l ¨ëwK¿§€Á@ûkb-Zõ~´ q¥DêÏ¥/ uJë¥AÔŠ¤óPÔ–§T€~%Ij`¬»à‡;Û¼?ñn]×»uãÉø©Ü‘nš«.Ÿy1çÏŠÝ휧ð»U"ê*Š"e•åçÙ ÷°î1Xgçà–;«RHÏnímmO^ÝL$ç㤿òÓtZm=ÙC&ÒìD±¾ ŠTžêfés¨8'KÈHiT…Ú7³ˆ´¢|)m¡ñdûµÇÙBømy)è c–˜TòíKnË ÝbâN$’\§Ü9Ó.ýkxæ`ÿwiÞWÂnhÕÌS2X¥ÇŽíÝë Ææjqnš´8Ñfò<žÝß|®Ú„e0rº°\Á$ncØOŠ^uŽíÀ@ZW&âRÔáã…«Sƒ¨+ÂÞ½²tþIW2g¹K>E »jÖ’B8s¶žlc5•}‚ 8~Tµ+gÄ éXÝ…m“ßÜͺæåõ¥Å–Ûƒ,1Œ†9¦aË-ÙˆøÌkÉsb'‹ãxáV®îížÃhìx9ykq Îj[Ͻß:'ǃ4Gn89Í9ôû/oOŒ²‡Î¸…ÎA[×V'±>Û@IcleæF*~ÜL¶ä³H2Í®´K3un¦-WMÉr™¨Ý@10Ê_5äW6vËØw½Ó}÷;øò7’†>)zÇIÀÀZÇ6S¨°—‚ Gwnkr÷wnmÙö×ï6³¶asdóo â%p1ð!ÁÎ¥¦ ž w?XÕ·׎‡¼ñë·L¸2µ8a´òÖ”tÆ/¸3 €2sMØNKz.BÚ”“ž]‚Ç\ šÎ)ÅDÌmFï—ûŠNYZoK»;öDýá>b{X 㼊ÂëDeÑèñÙ3ehmKY&²F—°Ûîü37ÍÆÙ·¹´sÛ·"ÆÅq(kí¤»ƒSÃ_«ÅtnsÜÂMs4€j ãv;®6ñÌ•ÏåK†Žm u 9"ï-¾Âø´8~V.µ·,tí©–R÷$µÒ‰ÔA²[qrS9Ô"JdsQògpÛÛ`¶ÅöãÜùl„ѱ¶-È^Ð7P.–äÍ™! 9ÆFÕ¤P5®{zxÇó/4ùl害î7FÎÚ¥ÚHÃݽ®‘òе¡†Ž*I 8mq¼Qç²¢Üz©S*®øé~áR¢B¤‰T_] œL¾õ4ÀÆ÷¥@JõÜ|Bæ~âWKvK@¯A}âzÏÒ¼êòC'"¡‘Ôvèqú8ÚJ~ Žù?ÿåÆ þ¨/pÿå™ú¼ ÿþ˜ÍWü5oúh”åüÆ~Û›ôr/9N௡hBñÐW(³][MîÛYÅèÑôœ…ǵٿ¢Ê>¶R“jyæqÎGÿf~æ,ª‘?Ø(`c2ñddÅ]G‡{#˺ÞAž51³ž:Ú¤¸u€BîãŸdÌ„É5ÏÇ ˜ekMèÆ°ÓÔâÚ€zŠôG%ð3–˜ßÇ¿¸3BO*ákt$±Å÷ޝçSè¹nŠ® .¥+=/ èÆIEI 1»âEAT“ùÿns¯jÍ‚.oº<^ñ¥—v×p=±ÈA KX褎FÑÀ4šÐis½{5Ë üYc•åÈ}þÛ”‡[Ïo3KØcÈsdcØj p)R©£½óVaý![€hÜýq±¿ø†Á÷ó‹»1ÈGʰ».[FÄ5Ýú"ѹ®Ç.‘šºÑƒD«#¬ªÄQ®ùÌ à«8Ò6vÒø­›êãb[¾Ã`æ¬ {3Ü÷l“ÃÃLp ipkZCèîË#Ú7&âø}ÛR×3n÷v2ìËvæ¹²Éë\Ȥ‘¤‡Ê€$[R|pçõîcàw4ež%îÌ…`%qàü¹~Jå¬àÂç·ÆË‡³.é…îYI)%¤“Z9kQk¤fê& œ[fCï]ƒhó«gín\Zà3¦K}銱e›ñΆ_¼Iqb1¬ !ârÖ»P:F³¨Šb7,w&z\eñ!“mŒ…Óî[zÙcîY ¯29Îqp-1á¤GOjG5Ê–M{A-\i1!)–0ö'äY±igl˜(ØHBI8XŒ]+0ý58Ã"‚Ú•2œÅóÉ6ÆW—œ·ØYMDZÛb³¢êúŒskÄ•¦F¨Ú@—…[!ÑBâÐwgqûËzîÛ,‘¾{üI‚Ö®NøXÖǤ—¸9ƒW SßùO `N7$²´C+.VàáÒy´E™'1¥ê¼{A~w«yƒ—nã ='Fé.ë± kÙå)ŒO0¹¶7žúÙ–Û^gÞZÁ¸"2\27‹pçi¤BWµòÓÆsY«Ki¨‚@XŸ³ó»gjni³Ñ¶Úypï …Ïi˜´j¬†6’[|PçSQû €Jé)O§žÎ±ïkÄG’ö³ktå“kÎ>`ÿ÷ø¯Õî±¾¿é¶Ïÿ…v6VÆ·X#…ËÛÆ…ý-ˆq >Éö TŒbwU£-g‹vq“ÊÁÌ ã\™‘1û,—ž¸~½-IX)æñS®!¾&^Fº²mœ&rvôÂWcÖ+Ö‡Ò(Š)˜TIÁ6™9{Îmm&î=¹¿~ÜÁç­çd±Ç=ý´mx¸šÑš,f-m1È*ãã¸ite£+²qÖܼÜ' š¼´nk+ˆš'Fð×Åi3ËL1Ü;S£x“Kµ°Ð}–Mx'´¬bq£eÜ’÷VJ°øjá¦Ì°˜LIÉæ§øƒú+C"ÁÒlÚÙç·¥JÜoî-þÁ2T;DÕ1u2†"*ë9·rs1Ž‹·/·ãÌ_IŽmýæ§UÍ.uÇzÇ2&ÅöœdƒCžÜæ-¼ÉÆÞÉ™´Âáq¶Œ{xëKj 4ÐCݸ:GIöZx‚GC]áì̺ósÓ.E39–“&àQ@SߺUÒ¢›T΢mÓ€#¥}©ihË;H¬ã¯wm`©ÔhÖ†Š¸Ð“AÓA^•ó Åînd¹}5È÷8ÐPUēë§£©|%SnÞ*ç-\U^¬áLI‘³_³ví´1}®êî¹RâôÓ'Šfî5šÅŒeŠí$;í¥^°l$EW©@'þ@×O—7–ëÛÛ3ùˆ´Ën[–ÚcŽÓîÃÜ׸kuìä6Œk×uS‡J÷µ·ó;›“7츽‡^Z–ÚÄ «‹GG]x¬t‘àŒxçòÒXNq´t['R/ÜžrÎ9[²d‚Ž].b¥qS1„ Q0€rz¿=ùKwq­¾f\Jö± Gp*ç8ÅN$Ä€´é¹OÌ;x_q62VÃKœuÃÀ4TžW€ !8L|—Õ^1/äd•‘¿œ†<øÝâÖ½á†Mƒ«Þð•*{À0Q,X˜Œ;tÌ‘ž1@j¡´jÂîon1Ê,Œ[Ø7ïW÷eâÚMmµ»+ÿÅ{œ ºHpSA:ehÛ¶£—8SÌ\°yšìýÞÎÜ8´ÎÍM3ÌêQm#Ô(_BGÉì‹*Ñ០#.HÝO%8zâJï’±2Ô“¥–Y‚y =c¸Bå“zs¬Œåµ? ‚2›|Ü•Ä šîfï-ÌŽNÞíK{VE¿öìÐ2æÅ8Ú¸ac@9¢cX(\Ó*4fq¶Øý“Ì›]Á5äÚ¨¦tn$–‹†š‰î!ñÈæ¶G8Ô5ÚÝC¨ vŒözfö·t³\†hlsŠ-öÒòÓ9ÊRNFÄ%ºÁ³…㦢ým's˜ˆ•Ɉ9'n© ¸pA¹çöË—¸6CtÜ:6Gc$eÏzâã~¨Ëcî¼bçŸéñI¨Zt< Üñä$fcº²ÀB×½÷ÎsvÐK^Ú>¯×À5£Æ¼`(Vó~Š û7ðù[.w ‰Ä½îFº€ž–;~ÑnÀÊÂMóîˆé¨é­tðZÝüÄeÌ€6C¶íª¨½Š¢´§Eh+Ó@»m#“8á.g÷Üô4¥GvúTÒ½•ú×0zÒÖ”àÃèÛåú‘vT—7£ ÂM%c­gw{†÷ôÖœQœJЍÐwDºéX˜fÊ[s‹zÜá#æcÛöî·a¶àÄÒ:ä }+#,vò×kÔyüÄ͙աlFb$p=D2¦«-硸²²ók[{ Øx§ðËq@üQxÄÛX‹ìœ¶?+¶B[‚fõ¹ÍÍHÏK4Pæ1QP(áOxC{CyMç*³;-Ù ã}”Ës*Ky{ËwÍßÇu¥ßšŽÞG"Ô¸wAƒÆ x£Ðní¹ŒÜí³ÛV–íÉ™¢fÇiÝ> ·óš@÷ºGŠžYqà ñŽÈ‘¿íÓí nrXÿòî'®ã‡üØÿö›?Òß.«OüÓÞ°.Gh°ïƒëmq¥Ë®œåÁñ0J½w™-›ÿجWœr°ÿ¹noønïýP»ýÆ7ŸÜ:pµp`Ø¢_¸ºÏ‘ÅYψ}œí­,Ñò‡”}ñÓc„|ûVÊ..w LDuîkø-ˇå0·=†ö”ÙZäîÙ{i9Ãx®Ôk'”&.{Æ>Àqh´rU®. Åâ'”d™Ñlt¸¤¹È¹LMÎоgÌ­ïÊmñµn1øÎç1º. s,£†ÞGÝ ÜÚDà{±$aŽ!Ï-ÔÐXAÕ¤ï;ksjno/ûÜnÞPë§Ë3na²4e.h!¥¡ÔqR£Ÿa<¯{EñaðŒn< ºéÌ.²Ž³r,›zø^PÌÞ@DÄܽ”C)ƱMHå›S ˜¸&šj<ôÚ·Ø[«¸÷¤™î›\Cl²’J%¶”3Se’Hk#¢sÜY#ÅAÑ©Õsš—ÚùûLœƒ µÙgýãq’7VpÜ1†9ã.¡Œ’ŒkÃsš¨(Ö¸¾éšâRÇÂYn{-ÂaLq[/lHÛq®/²â¯Œ¤7KFÉÂÁ¡oI7‘dÞ5»€pwŠ‘DÑíHCf1{».\f÷®&ÇiÍšÏ\Ûܶåó:öáöÖ]Ñd’XXâò4ÚAwØ$jðßÜïl^×ÈÝî(±xˆ&Ð66ÚÂÉî»ÀZæ0Fàæ†ƒ¨¼‚Úé$tWÓðT<ü<Æþ™o£ù£yÿÄþ‡-S˜Çÿ mØíþ²…);#a«.øÈ/ü ]Mê«UE1u9`LAIÝV»ÖP†Qgì²,"dhA•4QÉï•(ŸóNÛ7·w…îÃÜo‹X-Ã…tÇu¬‚g8ºÒBd< s‹’· >/5¶­r¹—ûjO,Ô4«íߥ‰ õ¹· ƒˆºGÖ\f“Ì_ê,.fËîö÷,t%ýÅ·ŠŸ\z C®’Jàö‹>,-û¡Ìµçdðû„íM’rYÞ4Ç Ý&‹™‹ËyÜKæÏæU—8‘4JÔåSE½öé½àæòÓr«!‹m¦÷pf²×e¬f=·—}ãÉpÔÙ[#KcŠ—Šx¼*Õzh´©î_yÊ[Û¹såÜÎy iºÝŽ$6§HãÑSN…³Úÿ°Wú|µ“þ"‡®æ\ÏÌHáŸô².®7þäkÅú6/ªP7³æl¨t›‹&ep¢eßQ4@§L‚:åLD@<#\Wáãù€ƒ»Éð›¨A?{–•=•\–š&åï ñ©4û´u§ÓE•9ÞÏ6TôTO Ön<·pOÙÛ}ÜUk Œ¥žŽZ)¢Ów ùz^M¤Îš¤Á`PÊ5 ‹tÄ¥0ˆ|³Ø™« nù¯y‘¸ß_x•²ØºKÖžáV¶ö倂Í4÷E ^˜²ÝØ«¸íùwmeÒî#,» µx‘¥€É%Äóô:µ¨PõpÉ6aí6ÅN$äY³²ÛɤÕãù\cvÇ1âM=däž&š%(ñÕ)@9@+§¶’åŸ+´o¨¼s´ñ.kY{Ý^“â1¤¸ž€ +³yß.=iÕ ž•B@8R-N§Â<õ%©Ô+ÃÃS¥:¯^ø4OzÖ;í¢<íӯ̽ûûóšý­yúÄ‹ï]û£Šýmú,ðìvŒkS[ŽÀñ_…+ÄŠn%C½¦ÌâÈ·Wîg)þíø{úœ+òÓ˜_¿ÙÊ{âóõ™Aë^E¨T…`0…¨=*à~à¤;ÀÀ4"§­X !Þ(Ÿ¥p?=NžÄÒ­•:@å$×H‹¶rTÕ.ò`»7);js—A&G(N_öiï¼a¬fZÉ×Ö/¼%¥Z~‘þ~#ëY<>Cûºý—ÿeZv½¸{²¶¹´uµÄdøÂŽd”á¨8P‡MAÀÚ½§¹ ³A3dà°á^#‡FžÂg3Gâá2psr°ÉâÆŽ•…”Û÷ 2‘©‰œöb %ñ€4¬t–°ÎíE¿œm%ŽÿÚiñ” ‰#ûTw„>°j"JJP¢vë@Y%)SQWŒ$ Ü J&ûhùˆ ª˜5¤(&”¾é0£›wrÃZ!k‡¥Í¯¥qºâÕü%¶ŒŸôjßè4üK‹O½HƼÇì^·tA"Åe~ÜN@0  ñ#n”GT'(rdíáÊ襵è«Oõ¡ßåë\“ýx_à#ü…r¸'%dÕ˜îA»t Îo"¡HEJnª:Žð€ ®¼µÕ¹ŠÿYuÎF>ôŠP[šWüŠ»ûÍ[’ߦCÇësF®]ÃØXP §¡Dª->õa0‘C¦}¼…ÝÔ@L‡–(ÇûLÁ=‚&Ž‘Û_誦]BÑHì¢I{ŠÞûp³–¤hþÛ‚D¥T“8dÞ&/)^¼2¢U chœµÒ‘¸ØçÌË«‡pûRÔÿám8.Ôwwã„FGú,ñš­í½°ÑáÁ[Žz^qN]QUë‚¶ÔâQM‚GM±SÓ“Mšº’e¦„hÅÛÁnÎÐÖêáÚóWWëRèß3ëu#äãÖISzÔ»’ÒbÙªiÇ1'Úvi‰)L¢€A(ï)ºDÌaè<£ ~´¬ÅÍIJ—\ÉWR¦§ x8žµ²aÃc5kG`<;?Ëô.Ûe¶âe„L_ìôÝ( sŽš€Duæ­N[¦j$ž+`û¼’4 VBâ:z>’z8u¬Eâû Ââë=7ʼE{¶u³ÈË&8§Ij“¤Á;†ër™4›52mª%ÿvqÉïLcÔù_ˆ½Ü9?¹BÇ7LJ\?¨éã5ë5¬Žh?Õmx€«ºnáÂØÙÈ3DMí'†¡×N zÅHà¼7:çYE9„Ê*s(sˆ‰ŽqG^QÔF¾Ïclc@}|èù#Ì’q{‰$ý'ŠÔÏËOObš«ù‡¨i§T€~z)Õ ˜jKSªPSž• uH mÒ—…4€~१±:­É¬´‹4¶g"õ«g¤Þ7nítv˜éŠnRMBr jº40‡†ºòÚÛÌöÉ4ltŒ5i-´ôÔ8€xv.V\M\ÈÞæ±Ãˆ€|4à~µóùêËTUe÷|GÃñ˜G"Ù,n[b%l{gÙnãæjÝó£Ûñ~€ÿ·,Kçm–v~RÇ1Ê(w«ÉùKËÛ½´þÌ¾Þæè_Ïp×FZÞõú›Mmihé p=oüÂÞû»pÿ{ã[<Ha-yÇ»n—WCˆ-=@ŸX” WªñZ ~µ¸-&ýÚ-[º|íÓv$2lpåe‘f™€€b5MC˜È`H  PÐæ áe½¼Ot‘1¬‘æ® \{IIéí\¯šYÖHç´PIÁÙÑÔ€ê÷+µER‚}ªªÛPZR‚œô¨z“ªÜ˜ËHÇ †zÄ˳XYº]°¬Ÿ³PQ:b¡5ð¡]y­­î±àM¡í‹–9憦'9•hH¨ì4_8)ÕÑ\ºj¢«ïNIé*À•ŠêeÙ‘Â¥j²¤ÝÜUVÅ8"¢…Ü % š¸m ”Næ7¿h u ;éjäÈbpˆš‘SB{HèFšÆLå:g2jÅ9S LC”u)Š`˜¢€÷ÀjœÀàZáV”ƒˆ5#ð¯©Ã×/;—ŽváQUÕT]uD QULcœ@¥åðWp²áhlc 8*|‘Åò8¹ç¤“R~µR©·ÇUNÔª¾öR/#Ö :bà bìÜ*Ù`!ƒCDäP ok × ÖðÜ3»|}ŽÀx.Hæ–k‰ÎkûA þ$}©Œ"cxÆ1Œ#©„G”DDyDDj´(85©©é_z’oœ Ý«‡®ÖlÐ [,áelÓx¢s™4@Ú» é\ ¶†7ºXØÑ#þÑï OÖ¹]4¯cc{œæ7 h<«êB Ué§BŠ¥6øûµ©§juL t‡”)Rªª”ëè©-@)J¦Ú‚ÕUJ TЧU÷šIê­b£ÇJ1ns(Ý™Ü*f¨(q9Žt[˜âŠG9”0ˆ@DL<ã\"[)œ1¢w 5Ã=' uõÊfÆ"sÝ€I ðŽ´ESn5zAQT §pT–¦ ûÍ ñVÈ2QÛ•¶1ÌÝ¡×Tí›™Cê aI#(c˜J¨ˆë\Þ&ÈéšÆ‰]ÒàM:*zM>•Êe‘̹ÎîÛÐ+P+ÓAÐ>¤ESn•T*j˜ëè©N«1±þLá†W[vNb±²E¥uZN'K%àp´ž¾ ç¦ìÑ>é^9 ÅveIªä\û©¡¸* ¾GžÛ|˵ܗ9­¡}Ž»Åݶ2lòx1[IK{ËWBXRç´´UÄšý>‹‰ÍlkŒ$8½Çk{on^Ír;$5ÑpÙKC´Òpq൫qž-ü®\oeãëfJÑÄønØqkXQS¯Ñ‘¹übá“—Æá™Iœ¼ã–¨™T›’ §¨ÛÚ¿Ë͵ŽG3Ÿ¹Žïuf.D×O‰¥·@-Šƒ¼sAÎ s¨ã^N==纬óâˈöûŠHà騂ù$#Åy¡¼:Mxc™$ž‘¢ŒñÉXª ,«2¸T­X74UFà~Äê&_|%×Þ‡0W¡:Þ(œ±½ø Ô`=4âxW­i¢if 物4'¶ATÛã«¡QT §WE*& b©Ð>íIju_z²œ ƒW®Ù°6l»••A¸w@Hç2i4÷ •×m¬½ÒÆÆ6Gt'ÂGõ®gO3Ø#{œæ7 h< }HJ²Õ_s™ÕŸGÈKžzI5?„ª‚ŸÖËRªPSnµ¢*¾Åºpš¸tådš”HÙ%—UT›Û b C˜J‰L. Päjâd1Fç=Œh{\@ŸoIéí\®–G´5î%­è’ƒ³êT:êèU 9é§T ¥AjuHÛ§wФµURœþJšŠ¥*œÃÕKÂRè¥zª@?0÷tT–§^Ô€~z‚ÔÁìHæÔêÏä©¥:HSó êJ€ô"«Ù. ÓÞ´£‹1Ôv¶K½_˜Ûû†úÍ~Ö¼ýbE÷ÆÎýÑÅ~Ͷý zöA³ÅZVÇÅNÈ6x¨ª8¯Áç§(]ßn4ì•!• &Fè'|¢á}Ó€9ÒoÈ#Èÿeh¹)5´†š—;ñŒÿBØñO0ÈñâøúzÑ—³‘…ì—÷•âè ˆv¬á Z¨CK\Ó—jœ[‡A9D¦.§û“tµ9Ä“mmŒ®çʳ‹i×À¾B˜™Zj?I?e¿iÇ£…HÌÞä­m,ß!¶ÂºYZ8šŸìŽ©Àt4_Ì·–®ÌÍ{J^÷k;ÇÆ*,c[¨¡£`â1ý"13èlÑ5Sî–PÆPÚ ·K÷–ÏÚvG2É´-s¿¬ç´ç·8ñ>…óVéÜsî,ƒ®OpŠ?îêphêI+­@áÑ[QjÖkØ54N½©Nz\Sð$)ù‡ª—U œI¼m›Êøêí¼&˜[ÖäO¦ÇÇ|c1&¹1iéÒÎØF´í×P Ú.²I]L`ZÄæòøÝ»‰¹Îæ$îqvºY_¥ïÑ\í,kžêÐÖ¸ž W½Ìä!Åc™Þ_ÜHØãmZÝOq£F§´Tõ¸€:ÊܲF:¾1 ïpcŒ“n¼µo[YÙXÎA½Q¢ê´YVè»nt°pî=û7lÜ&²¬³uÑPª&sÀ#Á··uá Ü;zá—X{–jŽF‡à i«\æ¹®®kÚ×5ÀµÀBæÌaò{'.1 É@í/c¨H$(ZK\ µÍ%®H ­âàÄYÔÆØó/O[ÞŽò«‹¥…püoëãçlª°—"³“s9ñl¢&KW­›m7’“CWVÃvmì¦á¿Ú–7óø¶Â똴HÞè\0I Öæß­„;óo~ž‡i<=ÞßËØa­3÷pèÄ_kaÖaqdž q{t¸SÇkkÒÚŽ+®ýÁ[•‡ªû™¶xý^Á‹W/—Ü:‚‹Tp°&˜j¢š$9÷¢:h\I ×;šÆV•qTô žW$qÉ+´ÆÒçtÐM>¥Ø¶î#È·V7ÈYvÞôì{ŠÜ[-/Û‡ãx&¿¸¼eS„¶Óø©ä›iÉOŒdÖ*Z²là¨ë¼¨ššµì†êÛø½Ãaµ/®4gòm™ÖÑwrô[°É)ÖÖÙ¡€ŸÎ=…Ý Ôx,½ž1}†»ÏÚůbcÉ©ƒA™Ú#ñKƒÝ©Ä®§K¨8®¹6ÖÃ¥aêê¥áN©NºTª@Sn5%ªª”Ü%©ÕvÎ"Âyc;Ü*ÚØ’Ș½f7’­c¢ˆ˜¤y9;*å„5Q)UxåÌpÝä­Wuï-­²,Ou^Ãghçin­N|ŽþÌq°:I\ØØâ(³Ø µžÝ7fÇk%ÍÀvš°v½î-cÒ÷4ÁwBà‰BÃs1þH€û9/;kÃ^qLþ5„—ô«jà*戒íàd¥¡é…lìT9'»ïÈ]C\ÛÝ8 ßg-þÞŸï\Én÷h’=3ENñ”•ŒqÓQãZkÁÅeóx ¾Ý¹ŽÓ3sq, ™£[X䮇UŽp¡àHpëuè)ÏYú°õJU6ëÓJ©Õ()ÒP©ÓTê»/*bœƒ„oYw“íÿ³7ŒKxçRá+ 3èèJ±BE‚Ÿ[òRÑJöìœús uÐÀ×6ÆèÀï<4{ƒmO÷œD®{[&‰#©c‹4ÊÆ ât‘¶A œÞõ¡µ t:M d…†@Òc$Âz—j e[¸²ì cþoæ©ÙkHÕ½ÿ9fâ§‹l¿eèƒ-é°Ý„áÁÒA6¨Ÿ]ò˜S÷õ¬é¶FC)Š7?ïøh5ã{¹3âïší]Þ™+H‹Ü:à³£lgM†@Aþç“•ÑÛ;\œ{$îœÚkÔÊ?Ŭ€ô‚GÆo‹2èÆ×tõ‰zÆ|Mu[/9é±ò"ÉéMS£éÑ.ßG9Њw‘YBr÷ûõ“Âæ1›s '}‹¹f¸ß¥ìÔÒH®—µ¯oÐæƒô.†S}…ÈKŠÉÇÝ_Àý/n¦»Kºi©…Í?Q!oVV1¾òEó;gÁüm­µnëÑׯpÑÿÛȘåVC°”dâGtSìšuÇNBWK3¹px »+¼ýÕÖFàAnÝ;¼”ÒŒ«àΟ´òÖý+³ŒÁås÷WXè»È,¡2Ìu1º#.£œÒïô-è˜['šÝÅ×`[:Ûù¢vBÛÆ’[Áö–j*t¶Ëö^‹ñ·¦Ãöf;GéµHß唟¾®™Þ[hd2x¯¼ÿ¿á d׌îåüÌo‹¾kµhÓ%cñ©{‡AÜdmœá³°¿î?Ý2rº;gkódÛ›Mz™Gøµ4Hⶺ¼¬;ºâ±.˜7 .»MÂÍ®(”g.1Š·"J.*½…s!ª)ro*šÇH7ƒßWžÄg16ùÌdí“tÐbyX51àš ðè]<Ž#%ŠÈMŠ¿‰Ì¿·q0ý$Rµs ›AQÄ>•ÄNò…e¨>©AN¾ŠE¨)TÛã¨-UT ¥F”ê˜è Ò¡N©J¦Ý:{Ô¨ªPS¸*KS)TÛ­AjuJU:ªtªªR©×Ñß©N©Š®ß*ê”ê©-N©J§]AjuHU6éîT–§TÀ§?Œ*S±)TÛã¥@RU%©Õ()×RZR•Mº{•ªª”çåè¥B€R‚›z‡Ü¥@R‚•:UU )¶¤µ:¤:º* SªPS jiDê‚›téîÒ—…:¥)P"©üÃRZª©üõ%©‚”§æ¡¨-N©NR¡M ˜u¥Ã­J¥§±:¤ó IjuíHç©ÒRù‡¨jKSªö§‚’kgDc¸v$où<%bæ¯c@ ž²À:½`ïìšð^‡ƒÝÕ‰¶“­l‡¤v‘OíqÚkwO;×hš𤹠›¨ÙTõU3h ‚ÉåSAÐÉŸt€~M5 Ö!Æ_ž-ï¼Axx´ÉG6±qŒñ`ŽÐGá[#Û¾×–J¹\¤IdÊ£èõ‘?¢©Ê%MRoêˆ8ßÝy`0w´×?n'ŒªH¨¯ÀV:HK N’?Ê8JÞ-X%'n,xÙ‹’*œe®” H•DÔí&lALtÜ´ÿ wDj/¯73áû–:ÊÞJ´ñ‘Í¥< õ.{hqÅÚîe{hGÙþú}k'¡x¤ÆNx[^'$M'Ô}t©»ù2 ƒ6.•f`ÈÐÚ9 Љ€¤ÓQ8€V¥6ÖÎÆ6AöM–Ytµ  ¸‡×‡ p4ú|Íe+¤6½èdm©ï MOÑ¥eÊVÖBq7Òeš1’ŠE¸k,À[8,’(r²¾»WmÄŠDå0€è;£È:†âÁßcå6·Z ËkPê‚Úñ­ý¾š.Í´Í{u R½Bœ~µ‘ñ×)IÙ© •8‚d0©¼'ÝÔJ‚]©ÌpOÃÈ=þýh÷‚jâê0qLæo-µöåõ$|8» $±¥ÝÛg¸7-ñä âèZ[BkMZÞõ¾ –†ñ˜¬^?=™µ«%ü±šœ·E„ø¬'¢GPA.qÈ® 0̓Ã?´=àÛ€×U×pÚ64áì+™“è¸Ö²¦,bÝ“(\ñ¢ÕÁÞO¿·®´›ªÝDQAÊ ˜É‰NB@æþðÎóØ=éc÷[[ »Øþó š÷»ïÜ÷˜_¨ÄÙb˜¸<9Îc˜ªÒNÝ˹ŠÙœØÊ훳<÷vöÏî$k[ܾõâFÐÕîŽHÃKHÁäŠAâtÊБñ 40öY± ï_šöu•¾õçžæÜy¶‰ŽÞ6¶V ŒØ5±ïžV´ð9í:^<`׸p£W¶nK™¶Ï*ðx\[ŒC3ßÜݹ¼ ºÖňâXÖ‘VôÐxÔ¬`á0ÝXgˆþ+µ²: =S1#Œîå„Y8;…®D_¯.ò¥™¦bå_‘ÑãRl-Ôj’‰•S(%0‘röÛ{æv}æëæ0XÍ0È ‘:×ýÙ°Uç»{ Lçê!Å¡ Šz.ñŸkžOmþâ Àç±mYtH.?>eñ¶¹ÚŒaºKAÄЮkÄf#¸¿Ã6;éáµ-n±Í÷î·j[v=¯4¼¼Š ‡Þªåg.µKP1H£‚œÅ1J%?/·Øåï)³¨ ûÖZmÛwmkt‰®ftb6Ôyè$0´MFGxmOŒy…ŽÆK/qo[Ïq-+ÝÃ^^à:É%­4.‚CcŒYÁo÷T¦ÂÑyŸäçQ ¼Kx_·U¿r@d)kz)äÇÄפ(v#k++ª‰(És!)„ÂsÖÞ7çç-qqo=ã.%¶Û,M¾‚Úa–Õ’½±÷–ò:GwÁsA4T@LŒÕpø.[ï{÷í·JË6èä6²Ï,rGpøÚ_¢f7º.kI†ƒj@c¸0À˜žÈÁRÜHq8…òú!ÎA{Œ1Æ*²_Ç@L]·4+w ÜR7Âý¤ÃÛq*´]±…»I@Á¨ï&U3Û—|îœÖ÷‹—œ¶u“.Û`Û˻ۆ¾Xà†BLŠ&¹äÏkƧiÐáØâÜNjàq›^Mã½EÓ­ÍÙ¶·µ…Ícå‘€™$ŽÑsN‘«SOh²Ö÷/Íx áÈoX{j÷Kåàmû9 cƒH–âwЈÜ XÖ´‡<ÒºOŠAw[‚ÅáŸ0Y‘²|=žîÇy}[öÖ²R—ýÑu'yµ¼$P…Š˜²nñQoEãGiä“t©Æ&€@:Ö¾cí,Ä–ÛøZd6˜±šàäma|ÜÀÃ#㸈½íÒæ5ÝÛ˜j\5¯‹ÏwŠÙ[‡ÉöÞ,÷ »Šg<­”L&pc_ 5kˆÖפtqíkãð+ƒò)°CG5^W,2ñðy3Û7 -«rhe’I¡i!½õÀ‘š$”6¬ÐÐÚê-©¦{)‡ånÙÌ|'˜+›ØËYqy‘±‘H@.î¡,v¦GZ;Q.àêp[õ‘ÀÝ œ8£ÅY¦ë¸S Ü9NÞ¾ífèW0h!)t9<tÛA¾1ÜG"ºfQÒ'D‹é¡Ç£šçfn÷emѳ­mÝ‘Ìæ"²–Úbh$%ì’Ëâ÷dÈÐ+š@cƒË:—gÊü]¶çÎ`w-ÄͲÆcdºŽx€âÀæJYÇ]â]p«šZÖ¾kC ðm™ñRɶ™³^*áæJÒ{|«7#oßsõ™u-&Ê58¦-cá£-ëÒZFD9ãXB™nÙ3 ‘åËooìýÛŒÛyOîl¥ÆàŽvÛÙ-´v·†9åîs¤|¶ñ²@ãÀM 3C…ý·ËÉ·¯³vÞváß§/ts¾xe.kt´5Žg¹…£‰„ÕÚšjÞ¼É8—Ýü1/Äv ˆ¿,ulì¢Ó^vmïqÇÝhÈ5’†FN2牗g¢.̳´RY¸“³ã‰J@H¦_?·wVøÄó)¼¼ÞÒØÞ¶óëË{‹had…†HÜ÷‚Ú5ů­x6¤ê!˜|ÖßÚÙw–ÖŽêÔÛ_ i¡žFÊÀæÊdž´ƒR›Jq4H.í,µ‰x3áѦq{Cfl…rdì/`dö”5Ñ oD@–áM÷Æ—®aVzùY¨‰¤R VJwí’ë;Wusƒ˜2憛Çcs7V­žHd–I{¢ÝwB@Ö†´‡K1$¸ÈÑcC«œÏíþ[ìèñ¯ÉÇ’¼¼¾ÆÁ;¢d¬‘÷Ú¤ï %ÄÇn‡¼êm8%ÿÃ.°³¶2e=–%­Î²Ö?‹Ë–Ýû#é·r¤›NS´×kå˜Ýæ|Ý6Ý¿¢ú: ¹"ª&cèŽsÌåØù)¬qQ\s~û­Xý0Øæƒ8sÞÜi%úuëqcš×CÖ+-²6Ö+uXÅu$;'!hÛ¸çsuJ"sIÖ‘Þ꺴éhpq‚ÕÜØË‡ Ä\Œƒ°w¸±ûû~qþ?Ë÷Œ€MZR’‘ê?Fïdkb2=¬â)w™½íNR¦p­?rs}òúÞ<î7·2Gqn¬-ÙÝÎÆHàטß>Gº2ø‘ýK‡ - ³6žñ™øœF/5a+á{ »™Úâs˜Ò扛Ý5úé ¾¼)…öwgC]¶Ö@‘E¥ýe¥â†b¤´û‰òšÎumÜ[€‹Žb£2?I~ÙG &¨¦bŠãßvÛÍÿÌbnl#{ì. ¯yŽ ˆEþðÙ´¼k{Ü$1é ¡ÀÐדi϶YÉì¡ÈAvö¶î>‰Ýr?2b«N–µ¥áÕ.!Ô"¡u}©‰­»ZÂö|å¨÷÷ ×RÍ“-n/å æßfŸ˜™BÆ `5LÑÊ8jˆÀŠªvªêo{Þ­›)º²9<îþÚ· ·ìf7Dæ²’¸ÜX:G÷¯Ôu€ãFpG+a·ì¬q;G? æ7·ù7‰çV1ÜÞ5ÐÚx¤ãq5èÈÓpVõ¹ŽeçSbÙ’0¶ã˜É'7oIHd];T»Æ"‚‚&)JÒ9}/8!åM†so¿2ÊĺI#–Y®ãˆ¸¸É0{.“K»¦1§h‘à’FѼcå¼¼Á»Åf‘’þêì6[†=‘Çn÷é ŒµÆF²£¼sÈ⡤^—„á>:ÖžãjȽ&g•—áóH\¶ÓÈ'åŠe<'D$àN²;gFrÂFÓuŽØ]Ã(%ŽšÖå{ÍKŒ†ÌÍaá€ZgòL†fÊÝnЇD­‰À¶Žd{Cèj:GBÖmv6{Ÿ’’Sqˆ²t‘–;Cdá©…í¡«\ÂÒ[QJÒ«›OÂ3ºxSök[*»A…Ë–2´å˜, Ÿ$Î_4„s¥Y¸( ÝϺmÀƒ¦•†±¾—Í.cdíà öØ«Z*ÒèñÚÚ8U¤Ž"¢£‚Ê]ÚǰvUŒÅ²Q¸´ÑÀ>óI-`b±Ê ŠÝ™Ž èíöÛ§sâ9‰Ù›¡Ö’Zd±’)bc£Õ{nA¸¡Ïwæû¯Î4µ¥y\û’Ù—›ŸÛ†\YdZÉ#‘áôµ˜R-oÞx„ý“BhÏñŸŽømÂwÔš³–³ÍÏp¶3ÖáŒ`”P²ØìÞCÝŸù¯ì»‹èðŠ»6™b‰»u bÜ;(n&à‰‘ŠÆ@4IÊÉ7\®Ì:iª©ºhQÓZÔîöŽAŸþŽã¼‹û/¯ýãýU¸Zo (/!1¿¬¶„~êñ–øÑk¢Û îÁš©é h3‘ËöÊ ±3g­ÓQ1!ûBHMÒ”7@§(ã~á¹-ÜDðÐ ¯Ghý}=«/W0;†4v;SúW-€`AI¤ñ“õ¶>ógL1Èö­Ôm_ÊÀ¢# €d÷ˆb¢q áF ì‘i}¬†Vôè §ej¹¼qLq,»„ÓãµwÄW–µƒÚß¶;œ+u..”AFd]Ã¥Žªª9QÊ¥XÇLÂM0&á@F±_ç2—âñÙ=¤p€vqð©“qàí¡“ŽÆµÇ†”ükƒÎqS~ÉÊqÀ„88“}º® ¢i]äˆdTCB˜Cw„Á  ¹ûN\ØÓ~í`t€4è©p=€¼Þï.:-'ûN<~¦´ÿ”ø:ÈJ¿•r£·î”r²ªS˜Ú{EGyC!L¡¹L ˜yGQ­òÖÆÖÆ.æÕŒú:O„ôŸ­i·W×WÒw·O/ÓÐ< }Kã󇊻WU\ ¯xjHN¥ B•¨WП @70Ò (¨Wóù)iM ˜jHíEUÀãá©Òš@8søêKUT¬šàÒàƒµø®áê⹦¢­Ûz-YRS3³²,â!¢cšM6UÓù9I›²`ɲE(ª§!PÔD¼ã›¶¹.Wçñøèe¸¿›pÈ⎒G½ÑÖ±Îq<Z ' -Ë—wv¶[ëyy#!´Žþ=ïpcÐðKœçÖ€8’HveÉÄ\Æãç.g¼W78ÙŸ9rm’ñ’HÈ[Ý•;.%Güz˲•·.¨_Ù.‘”&Š&áo‘3†»Ø›Ç‘˜­¹á’·ìcp{ f¶¸ŽÖ ×éxd°ÈÞ- â…Àæ¯7uÎÛæþéÁÈÉXܽÓÁkƒ£žÏ!-ÔÒC£•‡CÚjYÁÇVGácð?ˆ'mùÌQ‘2ùxc+‚)ÍÝd[Y킾î{FfÝŽ;UTKȱf‚ ‘Dˆ¨r>3É=½Í[MѼçÝÏè—kmä‘tì qƒÇh<–xÛ'³o&§¢Ž‚†l&§¾zÕùͱ÷œ»íöû6ÞáØ=çime’–(ÜæÚºÚâ*ÝJæ´µ6n|#]‡yB]¤,ï-wNÚj6mË4MÊí«‰®¬£{ÚÓ8žÒÚH."ä6C¦¤ ©]CÀod´§8”³¯L°¾$¹ø—k! œÜŒÞÕËP·Ì+û•t\X@Ü.n§¤|ë³¥©@Û…8¨žÙÎþZ;+e·rØ|[r¸Ý¹;›&4tÏc+"ŽF ¥ˆC•«¸Ò¤»_ånöYœ~FüØ^æbeéèŠéŽ‘ìt„¥’^êpáZ\2öEâÙêâÚ% &ÑRaž4±°NT³ò=ß‘n÷I ÌåVûä!,Dƒ§Ž ’Ä)ƒ†*š ;aîÖ?°vÑLn£uÝÎJÊ{H- ó”.•¦K¦šh¥Í$t¸T·m—/ºðøËËíÛ»£|b‹xl®b¸–âRÕ» ¸ŽÞ2û—BøØÇÜ6!Ró©Ž{Øßë<}–js{›?sÛnk­Ñi™¹‚Ë#Ÿ·.…ó?L"F½Îl.ÓH£ƒZçu4ôº<ŸY¼3q«jÞ\A`éÌ¥±¥´Â"À²oÈ‹„åB2bQTQm>EЊ¸.7ª;8ž.4]8f‚eQq/lB†;sf³¼Àæ>ÎÉáð9¨v͆JgIuqlø¸¾6LT/Š&†ŠM6†ÈâZÊè%w0xÌVÐÙ{’Ç#–ÆKœ»²¬‚Ù'½Ä !²HêšÇ§1 SP „ÞMmŒ­ìÞáå{'c(ûŸ‡I¬Òâü°îK½Œ5îñ+Òüw3ż°(úmGLž $Ý)©Žbæ2J¹œD¹-¯üÃgÝÉIÜãŵÌ0:Kv›{fÇ'}(£c s]^’€Òq™ì³¼œÄ6ÒöÉ—¸y/ ðI+Y1N^Îê3Åä‚)Ð H–2Zèâg ZÜ^ÙNf¯X9¬U“¸!¶øx¿ï6Z>èFÉVçláGŽ ‡» å#‘ó}AËd2‚C @‡ó¬g.7ŽO”÷‘ÙÙÏçÆï9²¶¶÷ t&àB@hoxâÈǼÆï°÷46 á¹ßoM·cÌ gÜÜÅ& ÷lÇa<°½²ˆL€ÔÜXæ´=¿i­$БCÓÜé”°`1^G¼ï±pH[Ò° "-ؤ•ÏzPtáÞâM슰öQbm›ÿvg9³µ]Ëݱ€ÎZeòRBË©omooced’ºI^Cdw‰F5•tÔYㆰëÛGob¹{ŸÇ9–Å\c¬™+ ŽÖá³Mu#£s#k#h.`ñªç:ŽÒâ’áÆm[²ÒâÓ…ÀÁ²¹ÂÅ™«æ;»(ÙÄÈ·6••[¹i)ø7+Òü_s±œ”8 ‹U"$RAEŽß'“ÅåyWÌÏml/²{;!ˆ‚Êãî‘î-eµ dRºøÏ…Ñ0js>É.$U¬t¬o±ûûcü1=Ý¥Žä³ÈËsÞ$Cû´ñÙ-í¾ù‚{©ç.H!qÖØ[Ž—7²FµÞ+Ô£ÛG¶­p+æ¬Þ5¸|´øØî ºŠl°½²G#zZö¹…ÃÆiŠÕ¦­wW*›u¬ÑjÅÕz!ÕÑae.2—×]÷kbÛ²O%BælWvß’F…±¥®&ñÖÌí­qO‚*§¢ð±Ä35U)’QUM®†L¥SÀyƒÎížec9¯‹±ºÉââÇI½‚ÙåË"/|ÑMUP$yàÖŽâ[ëÛ>÷œÙÜ¿¿º‚Æý÷¬¼µ–wh…ò67Å#ètU àI=~$ñ…ƒÂ„u›–.ì³d_™âÙË6Ñbã IzA^m m…Å1)‘'#ؼo¤#-Ð\ªo,š‚ —µ"\îÜÙÞi\^mlV*öÇcÜ⮡¹¼¾·–ÞGK×—ûªÊêxb¼¸ŠÄDÇ=­|¥’Ê_Ý´çéi€‚iT–eçi5öwåû)ÍÓn6¼äø…´f£mæã¹ä!›@B¢æ]ŒŽK*î1ºÉ‡pšFH†(€˜–_–—ŸøœÌv×ÃÅ€ž7Î#y…²d"7J†¼‚ipqÇdqìåCùá'åâ{b/h•̰¶2u‚.€GJÊî.x{q™pÁ) –°¥¡(Ç„¬-)mdëù¥‡*Ös:ow´<«ak1eÝ8Ar´:®Û®¦DJªb>]ÊýЋrÛ^b³7vÏÝy²k;W\±Ò~e¦h:£–kš^LJðx-rß9ƒ´_¸äÁÏmÆ[ÎÍ¿f×Gs8ÁŸœ"Q¨QñÔ¹§I.ioÑÁ}–ötáÝ)ð-öíµæ,N°)1=™–îÀµ†¾hk ¡~ª›¢×i&_Gjá]ävR¹M@Hr7û'˜å†w5 ­Ì9¼þwï×1\Œ{ŸCj x÷ÎgŒö¶Žs Í/.rZn Í÷ŠÆKq˜¼F+î°ÝÈ+¼ ¨Ÿÿ;ÅkZÁÓG®ÔáªêɸÿˆHû»ŠÓKà v–µµ<0ë…¶ÖÞKá#‰L#XWåÁyc[¶™2ìcgCIÄ¿Ay3¶“z vÊ3F5NÐMNÌÊ%¿ºUÁëœÍ“#·9­·7·÷vFûogy†Î\HÇÈÒV6”/©új[Eç;;,×/ó[[ï–v™Y®m¥gÞel,sà]G;¦¦´„¶´«xG Ø¡€ýšÐãzÚA/bæ{îRøŠŽ$¬Ø·™­ V’7[yéVëQe)¬ì¨¦váÚDœµÔ~9ñß1¯>åw÷Kì=³-ŸÜÉ¢áíÇ9;N™\×ø…±—ïŠð]†å±_ ì»o¼Ûýâ×%;§oxÍP´Þ‡‡JÚÖ6–øÀ¼[Æ´â¹ÆcÁ66OâžïÌíx—áÌ0ãëýÑrÍ'”"qÃÅÇ(ÀeâÛ[)G³2ÎÌÉT£NÈ˵|c¦b*]á)pÛC|f¶×,-6t»spü^ËC fÍýÌxwvó1£ccuL$ |tp-4ä÷ÕÅç7ÝÆä7†øq÷bY÷–÷Œktëhˆq{Î’#,.kêÒǃ2â6ÃÊW¯´s!¹¸a-¦y79ÇŒ.9hØI[¡ÖöÄ X¸÷ë5púnJ&Ìͪ²fWtw„7†&åæwla¹y·ã·šæ\n\Kvèc|Œ„Êó4®{Ú#š$qkHmxt ‹xâ³¹=å˜|ÑAö4ÇnÙÖ>QDQ†µÄ=Ìc]¡µp&œzW G X¥À¾Í¸q½-0—±³5õ){Å ÇVtc¼Ô„«I©¦zM¼ÁÔX ”ÖvTS;pí "NZÌ¿›;瘷sºû¥îÙ–Ïî¤Ñpöã‹È¦’¹¯ñ c.!Þ)à±­ËbþÙvÿy·ûÅ®JwLÞñš¡i¼•µ¬m-ñ}oÊíë ã‰N:øÄILcFÀæO•¬ "örÅ’É;q…š´f·:NU‹ôE’‰qº¡?htÁ2”1J:–w¸­y!´\Üuì—ØŒ­ÕͳaÞ[?xüÉú{jS¨ÐHØ19|4üÔÜm7¶¬µÈãî­á™Ò7¹t’w%¿¶„5Ô š‘AR@]!ÁäCxl镸P».;~^ 7Ø·n*y?iJä¶¼#cœOÚwDDƒr¤Œ©¡ž´p“s @ á}  ÖëÍËÉ/6F+šx»yá¾ÂßA|اa†cÞ"žjYÞ5Í/®–ðêZ¿.­™mºoö üÑIk”´–ÔɻȄÍi’)XáÁÚpoV§q]OÆÞC‡½3Ü䦠}ÄQPøfÂA3&£tmüzÜÑ.‚¨ˆ¹AåÀ/WIR—C¢¡4­¯’ø ¼6Å‚÷*?úöZY2DÔ-ÑÖ* H-‹»ii<×U¯ó;/o“Ý’ÚãÿþÑ–pBvãA¡2k Ž–±,î õbÕçÕJU6ÔªªR©ÕÑS¤§TÀ§@ù¦‰Õ()·ÇJ€§T ¥IjuJU6ëPZR•Mº{•:JuL XTª)TÛãïÒÒT §UIjª¥:ê SªR©·ÇSBR•N­¡R˜)J¦Ý}ÚE¡:¥6éRZR‚•©Õ()·ÇS¥UR‚]êIÕ)Tëè© ER•MºT–ªªPSž¤µ:¥6õ Fš'T€§VФS›u¥@R›t©-N©ANº’ÔêÛ§wŠ µ:¥9ü”¨SªR©·]”¸u§T€¥-=‰Õ(mAjuHêÚ%©Õ (<úÔé¢u^ép>]lx!ç‰ÿÜGݯ˾`~þfÿkÞ~±"ûÿfþèb¿fÚþ‹Ð-ÀÛäþŠÔVȦàmòE_^.ï]Äïþ!sOúȹk÷?”ô§lÃØïÔá_–\ÂýþÎ~ؼýfEUèKOR„)B¡ P…(B”!J¥VR NªÀpðÒÒŽ à<ÃSDø…`6”QíWÒNƒ©\B*B°0éEPUÀãáå©Òš¸e" uWxjhª¸Ÿ’‘jÀÜÃRBªžµp8Ò⎀p¡>)ÜÃJ€¢¡\Î*)«ù‡«üTˆíN©üþJ’ÔÕÀüÃRZRƦˆ¨HŠ<)ñJšT¡0UÀáÏ¥IjuHš’ÔêúT–§T€q©¢*< @è¥áUT §]*U n4‹SªP??’ µ0RüÃRZRœõ4)Õ)TÛÕK‡ZuJ w-=‰Õ )·_v¤µ:¥:ª SªPR§JuHU6éîE/ iANà¥@˜=‰AMºôÔ–§T §UAjª¥:êt§T¥SnžçôT‘ÚR‚ÁJ0R‚›uéïÔ–¢«!¸ƒÏîóôž0’ym7¶ 0Õ•‡ÐI´š²…—mf¸šp”ê§U“!f»ñ™3p ŸfÚòh aű-²Vðܺädr÷ä–wfàF BŽv Þ_²(¶ýÝ»$Ý“XÍ$-ƒîXØm.Ö!/:Í@¡v¿³Æ”é+ ÁNºÞ‹V§T¥Wm*´ê”î šÁJU6ëîÔ–§T ¦Ý;¼U%©Õ()Q¦ ª˜ªíñÒ§juJ uyB•N«)pŸP2Ùœ{jb¦3£¶Ó‘vÎk}vJ¨{*"}ŠQÎÍ b DÆÝ©œ¼—¤‘Dʸ”S17ʧ˜ï>^ßïl”å2’7d1Ѿls``ûÄ‘8½½åήóº.Ò]‚š‡BÝëlï M­e,¶ ;¥Í{c½t¯=Ë$hiÑàƒdÔÕJPq˜W2‡1Îsç0œç9„Ç9Œ:˜Æ1„DÆ0Ž¢=ñ¯HîÃF(Ò5jx’® wN“ÔŠ¥zÈ4¨S›té¥@UU()ܨ)TÛ­Ijª¥*›tîæ¨ÒSª`S¯¢’uJU6øéi Õ()ÕPZR‚u©Õ)TÛãïTUU()ýaý“¯bb©·_v‘hN©J¦Ý* SªPR µ:¥*›z†• uíJ t‡”*hR•N¾ŠE¡0R•Mµ©Õ()RZª©J¦Ýz{õ4!:¥:CʨR‚{B§H= Õ()¶¤µ:¥;‚ µ0R•MºìšQ:¤:CËKÂS}¨ )¶¤µ:¥óÔ¦ B©Ì=CRZR‚ÁKŠuJU6ëÝã¥@RU%©Õ{¿ÀçÿÀÄñŸþAµ~[s÷÷9û^óõ‰èÌýÏÄþ͵ý •¨-•J¿\\ÿÞ»‰ßüBæŸõ‘r×î(ÿéNØÿ‡±ß©Â¿,¹…ûýœý±yúÌ‹«Ð–ž¥R„)B¡ P…(B”!J¥R„)B€ÃÓJ:«€vR¡B¾µ4N¤-@Â" ô«ûƒú)'NÅp0 ©*àna¢‰Ôp?8xªt¦¬ï *U CmMuV‡EN”ü ÜÃSDWµ\4qO‡R¸(OZ@8óøéPÀááä©Òš@0øZ’ª¸ŸÉS¥:¤ó I ×µ ž• +ØúQáOÂ×KObuH};¼U%©Õ |5Sª@>ßðT–§_­ (>TN©MºRð¦”×Jƒ©Hæ¡©-N©üþJ’Ôê”Ì5©Õ )J…:¥6øûµ¥@R‚]‹Sª@S¯¢ µ:¥6éRZª©JšS¡:¥*›ixQT §pTÐê”Û¯»RZR‚U%ªª”¨§buJU6øéSµ:¥:º)Pê”Û¯»RZR‚›tîñT§T€¥Nšt'TÅSoަ©Õ()Ò¨ uJ uôT–§T¥SmAjª¥;‚§IêN©Š¦Ýi'T¥SnžåMN©ANà©-L¥SmAjuJU:ªhUU)Tëò $Wð¦*›z†§H)Õ()ÕRZª©ANº‚ÔꔪmþŠ’ uJ w*&bb©·_ Ô–§T §UIjuJ sÔªªPSo»Zšꔪt‡”)Q:¦:ú*KSªR©¶¤µ:¥?¬* SªPSn½=úšR•MºyB‘:¥<[*KUU)TÛRZR‚]©Õ()Ð>í*R•MºtÔR‚”´ö'T¥SmAjuH wIjuL t»SBªB©·Nžõ/ uJ RÒ:“ªR©·»š µ:¤*KSªPSn½=ÚÔé¢u^õp5ËaÛÃÏ ÿ'µ¯Ë.a~ÿg?l^~³"ýÙŸ¹øŸÙ¶¿ bôµ²©BàK‹Ÿû×q;ÿˆ\Óþ².ZýÏåý)Ûðö;õ8Wå—0¿³Ÿ¶/?Y‘cÕzÓÔ¡ P…(B”!J¥R„)B¡ P…(B”!JµÔB„UX>ZZSVÔУÀ¯­*'R€Â‘PUÀô'CÔ®¡íVw†‘ ðêWó…-)ñWs I¨ª¸zii «Ã¢¤µ?¸jh{RèâW…$ëÚ=4i¯b¸:*t”ê<úÔ–§Up?UIjuìHæ’¯j@Sž—ëØÌ:QÀô¢½©üþJ)¤óPÔ–§T€~%IjuWó IjuíJ sÒ¡N© ~aÓgø©pëN©@üþJZ{ ˜uØ5%©Õ )ÕPZR‚›{½Ú’Ôê¥Å:¥6ëÝÏJH m÷*KUU()×ÑRZФ*›j UU()ÏJ…:¥6øûµ©§juJ utRÓTê”芒Ôê”ÛÝîT§T€¥MèN©Š¦ßv´©ÚR‚!ÑJ•N©AN¾Š‚ÔÁHU6Ô–§T ¥MRuL íצ¦©Õ)TÛ§”)iUR‚ÁRZ˜)J¦Ú‚ÔꔪuTЦ PS¯ÉSDꘪmêZjR‚ÁRZR•MºÔªªR©·Or¤‚R‚ŸÖ4ESM¾>ý"ÕUJ uT§T §]IjuJUvøêhSªPS«¢•ª¦:¤µJU6ÔªªPR§JuJU6ëÓß©¡N©J¦Ñ(R N©Nà©-L¥SmAjuH utT–ª1Tëò M *”ªmñÒ UT ¥IjuJU6ëPZR‚]%©Õ()×¶¦…:¥6øéP'T §=-=‰Õ()·Z‚Ôêêè¨-UT §_»J…J mñ÷iJ‰Õ()ÏS§±0W¾Ü ð »ÿDÿÉÍkò·˜_¿ùÏÛ¿¬È¿Aö_îv'öe¯è½­=lªP…øâçþõÜNÿâ4ÿ¬‹–¿sùGÿJvÇü=ŽýNùeÌ/ßìçí‹ÏÖdXõ^„´õ(B”!J¥R„)B¡ P…(B”!J¥R„)B¡ P…¨‡xh¢uVóÒÒŽ à` M < ÚÒ¢u*ÀqþºÀ«û»ô“ãÔ®¡íW=*ü àpðòRÒš¸˜jHíEUÀãáå©Òš¸9ütˆ)‚z•ÀÃSDTu«èL} Áà\¯j@8ôÒ-MX‹J*=5BuW‡E"ÔÁJzš'^Õp?=.)øù†—U ŸÉHµ:¤ó»¤µ:¤óÔéN©üÃRZRœô¸§^Ä¥So»Z\ª@?õ…-)Õ(nµ©Õ )ÕRZRÇž¦‰Ôx‚T¸õ¦”è%*U )·Nš’ÕUJçòT¦ B©¶¤µ:¥*hSªPSn½4¨ªPSnžå"Ôê”þ°¨-L…SmIjuJ TЧTÀ¦ÝziSµ:¥6éîTéªuH wIj`¥*›j UU()Ü4)‚˜ë¥DU()·Nš5U^Ô §pT–§T¥Snµ©Õ)Tê¥BR‚}4LÅSoŽ‘juH uTªª`S® µ:¥*»|t¨SªPS¸*hªb©·_v‘juJ mÒ µ:¥* SªR©·]ƒJŠª”é(TÐ'TÀ§_EIjuJU6øêKSªR©ÕÑPZ˜)ANò *'T¥SoPÔ¯jPS¸)§T¥Snµ©Õ)TÛ§¹PZª©N¾ŠTN©J¦Þ¡© 'T §U"Ôê”ë¨-N©J¦Ý=Ïè©-N©ANà©LÄ¥So¿J:¥:ªKSªPS® µUWÖÑ%]¹nÕ¹ ¢îVMS/(¨¢§ ßt®ŽFòÛa6Jõá–DéãÐÖ°|.Õ•¥ÅýäV6­/¹šF± t—8Ь•ú#àêXk>1±Š;­XµnSi  [·M ^PܯɌÖEÙŒÍÞ]⺺–b; ¯sÈÿÞ_¢Ø«&ã1–ØÖš¶Þãè¿äYÃXÅßR„/À—?÷®âwÿ¹§ýd\µûŸÊ?úS¶?áìwêp¯Ë.a~ÿg?l^~³"Ǫô%§©B¡ P…(B”!J¥R„)B¡ P…(B”!J¥R„)B¡ P…¨‡†Šê®ç©ÒŽ À`ð *#ˆVÖ•¯j¸—øp8PŽ!\„Tu«„6Ò 'àV‡EN’š¸˜iÚUÀüáS¥ÀÀ>I Ô«Ä)Q:„€zÇ©\ Ì4¸ëÚÏËHµ5p8xJ’T€qðòÔéM\útÔ–§R54N£ëH ñHÛ¯M*Ф‡E-)Õ yõ¨-N©üüžåIjª¤=MT€¥.)¥6ëÓJ:¤õR-N©@ýu%©Õ\Û¥AjuJ MªPSnÞ*<)¥óòûµ4I×± )·¨jKSª@SŸ’¤µ:¥*›u¨-N©ANª\SªPS iP'T ¦Ý:i§T §=Aj`¤*œÃ­AjuJ uR¡N©NºšêÛ§M"ÔëÚ”¨-UT¥Snµ%©Õ)Tê©¡LÀ§]*ꔪmñÔ–§T §UIjuJ uÔ§T¥SnžåI:¥;‚•uìJU6ëîÔ–§T §UIjª¦* SªR«·ÇSDê”êò…*ê˜ëè©-N© ¦ßAjuL wNžÅUJ ôjhŠ¥6éÓJUR‚ÁRZSMµ©Õ!Tê©ÒSª`S¯¢¦‰‚”ªíñÒ N©ANª’ÕUJ uÔ§T¥SnžçôTé)Õ()Ü“±1TÛ¯»S¤'T §UIjuJ uÔ§T…SoާJª§!Œs¥)Œs¥ „Æ0è DDDkŽI#Š7K+ƒbh$’@$’x:ÉàÆÇÈñ@¹î4 ’O@t•˜¼:`雎àa-$ÅRn*C3l¢c¼–ð€zBÅ÷ªGÞ”yKßJøŸæ´ÎBý™´åï1¥Ãï3´ø²i5î£=l¨«Ü8:šEZM~©å,.12·sî(ô_Só¸qeGûGŽ§ÓƒZx·í:”ýâëE;RÞhÐ8"@0né˺óxkåô:ìê¥_ŸÎ"ý’ØâïÉwæEޏr¡¥² åsß-‹1iŒci[²qôô‹xÄ~ÄúRè»~r¢EVYR¦(qÔÃõvÝþp¹™¶vý†Û°±Á>Çg ´n’£#£‚6ÄÂòÛÖ4¼µ€¸µ­Ö€ð,Ïòç²s™{¬ÕÝÖU·W—2ÎðÉmÃå{¤ph6Î! ¸†‚ç)ROŽÿ´%·óÎJúVØü£Yîk{¿oy ÏoXß– ƒé™+mìŠ~ЖßÏ9+é[cò;ÜÖ÷~ÞòžÞ– ƒé™+mìŠ~ЖßÏ9+é[cò;ÜÖ÷~ÞòžÞ– ƒé™+mìŠ~ЖßÏ9+é[cò;ÜÖ÷~ÞòžÞ– ƒé™+mìŠ~ЖßÏ9+é[cò;ÜÖ÷~ÞòžÞ– ƒé™+mìŠ~ЖßÏ9+é[cò;ÜÖ÷~ÞòžÞ– ƒé™+mìŠ~ЖßÏ9+é[cò;ÜÖ÷~ÞòžÞ– ƒé™+mìŠ~ЖßÏ9+é[cò;ÜÖ÷~ÞòžÞ– ƒé™+mìŠ~ЖßÏ9+é[cò;ÜÖ÷~ÞòžÞ– ƒé™+mìŠ~ЖßÏ9+é[cò;ÜÖ÷~ÞòžÞ– ƒé™+mìŠ~ЖßÏ9+é[cò;ÜÖ÷~ÞòžÞ– ƒé™+mìŠ~ЖßÏ9+é[cò;ÜÖ÷~ÞòžÞ– ƒé™+mìŠ~ЖßÏ9+é[cò;ÜÖ÷~ÞòžÞ– ƒé™+mìŠ~ЖßÏ9+é[cò;ÜÖ÷~ÞòžÞ– ƒé™+mìŠ~ЖßÏ9+é[cò;ÜÖ÷~ÞòžÞ– ƒé™+mìŠ~ЖßÏ9+é[cò;ÜÖ÷~ÞòžÞ– ƒé™+mìŠ~ЖßÏ9+é[cò;ÜÖ÷~ÞòžÞ– ƒé™+mìŠ~ЖßÏ9+é[cò;ÜÖ÷~ÞòžÞ– ƒé™+mìŠ~ЖßÏ9+é[cò;ÜÖ÷~ÞòžÞ– ƒé™+mìŠ~ЖßÏ9+é[cò;ÜÖ÷~ÞòžÞ– ƒé™+mìŠ~ЖßÏ9+é[cò;ÜÖ÷~ÞòžÞ– ƒé™+mìŠ~ЖßÏ9+é[cò;ÜÖ÷~ÞòžÞ– ƒé™+mìŠ~ЖßÏ9+é[cò;¼Ö÷~ÞòžÞ– ƒé™+mìŠÁ솷ûç%})l~Q£çwšÞïÛÞBóÛÓù`Ø>™˜ò¶Þȵý¡íÏž2OÒ–Çå*_;œÖ÷~ÞòžÞ—ËÁôÌÇ•¶öE?h{s眓ô¥±ùJÎk{¿oy ÏoOåƒ`ÿy˜ò¶Þȵý¢-ÐþùÉ?J[”©|íó[Ýû{È^{z,;ÒòþVßÙU¿h«{猓ô¥±ùJŸÎç5½ß·¼…ç·¥òÁ°}31åm½•kûEÛßXv¥åü­¿²«~ÑÖÿÏ#éKgò/®jû¿oy ÏnGËÂôÌÇ•¶öU¯íoüï‘þ”¶)ÑóµÍ_wíï!yíÈùbØ^—˜ò¶þʵd„|d¥-ŸÊt¾vy©îý½ä/=¹?–-…éy+oì«_ÚFç|ôµùR—ÎÇ5=ß·ü…ç·%òŰ½//åmý•kûI@ü“¶¿*Qó¯ÍOwíÿ!yíÉü±ì/KËù[eVd¤{äo¤í¯Ê”|ëóSÝûÈ^{r>Xö¥åü­¿²­iX/ò/Òv×åJ>uù©îý¿ä/=¹?–=…éy+oì«PöKÁ‡z_"ý'm~U¥ó¯ÍOwíÿ!yíÈùcØ^——ò¶þÊ­ûLAüí‘>“¶ÿ*Ñó­Í?wíÿ!yíÈùdØ~——ò¶þÊ {&¡½-‘>“¶ÿ*ÒùÕæŸ»öÿ¼öäþY6¥åü­¿²«~ÓpŸ;d?¤­¿ÊÔ¾u9§èÈ]ûr>Y6¥åü­¿²­iØ_²ÒVßåj_:|Òô ¿ä.ý¹,ÛÒòþVßÙUƒÙ? ÞÙé+sòµ:|Óô »öä|²ì?KËù[eZþÔß:ä/¤­ÏÊô|éóKÐ6ÿ»öäþY¶¥åü­¿²«²Š?½rôÉ[Ÿ•é|ésKÐ6ÿ»öä|³l?KËù[eZþÔpÿ:䤭ßÊô|ésKÐ0BïÛ‘òϱ=//åmý•[ö¥ˆù× þñ·+ÒùÐæ `<…ß·#åŸaú^_ÊÛû*×ö§‰ùÓ }#nþX¥ó¡Í@Ày ¿nOåŸbz^_ÊÛû*°{*bƒûÓ }#nþX£ç?š>€ò~Ü–}‰éy+oìªßµTWΗÿÒ6÷åš>sù£è!wíÉü´lOKËù[eVý«bþt¿‡ÿxÛß–i|çsCÐ0BïÛ‘òѱ=//åmý•jÊèÀïIßßHÛß–i|æóCÐ0BïÛ‘òÓ±}//åmý•[ö°ŒùÎýúBßüµKç3š€ò~ÜŸËNÅô¼·•·öU¨{,£CûÎýúBßüµKç/™þ€ò~Ü–­‹éyo+oìªßµ¤wÎWçÒÿåª>rùŸè!wí¨ùjؾ—–ò¶þʬËhðïI_ŸH[ÿ–èùËæyÿö!wí©üµl_KËy[eZþÖñÿ9_H@~[¥ó•Ìÿ@Àù ¿mGË^Åô¼·•·öU`ö]0ï+ìz_À~[¥ó“Ìï@Àù ¿mOå¯bú^[ÊÛû*·ívÄ?¼o¯ãà?.RùÈæw `|…ß¶£å³cz^[ÊÛû*°{/™÷óü|åÊ_8üÎô‘»öÔ|¶loKËy[eVf0ïHß?ÇÀþ]£ç™Þò~ÚŸËnÆô¼·•·öU¯í„Ïç ãøøË´¾q¹›è8#wí¨ùmØÞ—–ò¶þʬÌFýá|u¿‚ü»GÎ/3}änýµ?–Ýéyo+oìªß¶3_œ/ã ¿/RùÄæg à¼ß¶£å»cú^[ÊÛû*°{2÷…ïütåê_8|Ìô‘»öÔ|·lKËy[eVfSpïH^ßÇAþ_£ç™žƒ‚ò7^ÚŸË~Çô¬·•·öUoÛ1¿ú}ëütåú_8\Ìô‘ºöÔ|·ìKËy[eVfrþzõ½ƒü¿Kç™~ƒ‚ò7^ڟˆÇô¬¯•·öU¯í úuéül'Ô¾p9—è8/#uí¨ùpÙ—•ò¶þʬÍ$ƒüúóþ6ê _7üÊô‘ºöÔ|¸ìJÊù[fVf¢aÞ}yÿ õ 7üÊô‘ºöÔþ\vG¥e|­¿³+~ÚÉÿ¦Þ_ÆÂýCKæû™^ƒƒò7^Ú—‘éY_+oìÊÁìÙ žÞ?ÆBýEKæ÷™>ƒƒò7^ÚŸË–Èô¬¯•·öe`öm”?Ïoã!~¢¥óyÌŸAÁù¯lGËžÈô¬¯•·öeoÛt?Ó/ã!¾¢¥ówÌŸAÁù¯lOåÏdúVWÊÛû2°{7ôÿ<¼:ÞC}GGÍß2}än½±.{'Ò²¾VßÙ•¿nóË¿øÈ¨èùºæG àü×¶#åÓdúVWÊÛû2·íÈoôË»ø¸©*~ny‘è8?#uí‰üºlŸJÊùX=™jÎSùåÝü\?Ô”|ÜsÐp~FëÛòë²}++å öeoÛ ÿéwoñqRÒù·æ?¡a<×¶'òí²}++å öepöu(çw`ô»ˆú–›~cúÈÝ{b>]¶O¥e|¤̵gb¡Þwvõ-/›ncúÈÝ{b.Û+Ò²žRfVý»–ÿJºÿЉúš—ͯ1½ än½±.û+Ò²žRfVgŠáþuuõ5/›>czÈÝ{b>]öW¥e<¤̬Ï5üêêþ*'êz_6|Æô,'‘ºöÄþ^6W¥e<¤Ì­ûz¸ÿIºŠŠúž›>czÈÝ{b>^6W¥e<¤̬Ïw!þstõE/›búÈÝ{b/;/Ò²žRfVý¾]¤]ÄÅ}QKæÃ˜¾……ò7^Ø——éYO)³+~ßnÿÒ.âbþ¨¥ó_ÌOBÂùŸlGËÖËô¬§”ƒÙ•ƒÙúð;Î.âbþ©¥ó_ÌOBÂùŸlOåëeúVSÊAìÊßõyÿŸ¹¿‰ŒúªšîbzÈÜûb>^ö_¥e<¤̬=÷û—ø˜Ïª©|Öóа¾FçÛù{Ùž•”ò{2°pø?ßîOâ#>ª¥óYÌ?BÂùŸkGËæÌô¬§”ƒÙ•¿ê ÿÿ=rõ]/š¾aúÈÜûZ/›3Ò²žRfV$ýþãëqõ]5|Ãô<7‘¹ö´|¾lÏIÉùH=™[þ¡R!ÞZãþ"7êÊ>j¹…èX_#síhù}Ùž•”ò{2dx ß.ò—Ã^Rv;¢ÃÙÇÚu…qKüÓsF6×Çë6Š«§ äùÙlxs§É8£,4>0ø]÷øB9Ê ž0©¨Q.ó‡w<ÂUŠ[Þ&è5yVëæ†ùÞŒ0g²¾Èš÷, Š/¢¬Œ4>FMdv¯AÛÛ iíw qq²è w®¬’}4{Ë‹kÖ¤} Ѽk†!,–艧۔¥ÔÛ…×PþºsÖ€·Þ…)HP)C@Є+P…(Bø|]¯ü'Ñ÷¿ûÍ5¡ æùÔüÚ§Èž§æÐ…>Dõ?6„)ò'©ù´!O‘=OÍ¡ |‰ê~mSäOSóhBŸ"zŸ›BùÔüÚ§Èž§æÐ…>Dõ?6„)ò'©ù´!O‘=OÍ¡ |‰ê~mSäOSóhBŸ"zŸ›BùÔüÚ§Èž§æÐ…>Dõ?6„)ò'©ù´!O‘=OÍ¡ |‰ê~mSäOSóhBŸ"zŸ›BùÔüÚ§Èž§æÐ…>Dõ?6„)ò'©ù´!O‘=OÍ¡ |‰ê~mSäOSóhBŸ"zŸ›BùÔüÚ§Èž§æÐ…>Dõ?6„)ò'©ù´!O‘=OÍ¡ |‰ê~mSäOSóhBŸ"zŸ›BùÔüÚ§Èž§æÐ…>Dõ?6„)ò'©ù´!O‘=OÍ¡ |‰ê~mSäOSóhBŸ"zŸ›BùÔüÚ§Èž§æÐ…>Dõ?6„)ò'©ù´!O‘=OÍ¡ |‰ê~mSäOSóhBŸ"zŸ›BùÔüÚ§Èž§æÐ…>Dõ?6„)ò'©ù´!O‘=OÍ¡ |‰ê~mSäOSóhBŸ"zŸ›BùÔüÚ§Èž§æÐ…>Dõ?6„)ò'©ù´!O‘=OÍ¡ |‰ê~mSäOSóhBŸ"zŸ›BùÔüÚ§Èž§æÐ…>Dõ?6„)ò'©ù´!O‘=OÍ¡ |‰ê~mSäOSóhBŸ"zŸ›BùÔüÚ§Èž§æÐ…>Dõ?6„)ò'©ù´!O‘=OÍ¡ |‰ê~mSäOSóhBŸ"zŸ›BùÔüÚ§Èž§æÐ…>Dõ?6„)ò'©ù´!O‘=OÍ¡ |‰ê~mSäOSóhBŸ"zŸ›BùÔüÚ¾ô=Oì; ?û¿à¡ é¡ P…(B”!ÿÙopenchange-2.0/apidocs/html/overview/index.html000066400000000000000000000067321223057412600217250ustar00rootroot00000000000000 OpenChange 2.0 API Documentation
The OpenChange Library API Reference

This is the online reference for developing with the OpenChange client libraries.Among other things, the OpenChange client libraries provide:

OpenChange Project Goals

The OpenChange Project aims to provide a portable Open Source implementation of Microsoft Exchange Server and Exchange protocols. Exchange is a groupware server designed to work with Microsoft Outlook, and providing features such as a messaging server, shared calendars, contact databases, public folders, notes and tasks.

The OpenChange project has three goals:

  • To provide a library for interoperability with Exchange protocols, and to assist implementors to use this to create groupware that interoperates with both Exchange and other OpenChange-based software.
  • To provide an alternative to Microsoft Exchange Server which uses native Exchange protocols and provides exactly equivalent functionality when viewed from Microsoft Outlook clients.
  • To develop a body of knowledge about the most popular groupware protocols in use commercially today in order to promote development of a documented and unencumbered standard, with all the benefits that standards bring.

More information

Visit the OpenChange web site for other useful information.


Creative Commons License
Creative Commons Attribution icon Creative Commons Share Alike icon
This content is licensed under the Creative Commons
Attribution ShareAlike License v. 3.0:
http://creativecommons.org/licenses/by-sa/3.0/

openchange-2.0/apidocs/html/overview/middle_bg.jpg000066400000000000000000000005251223057412600223320ustar00rootroot00000000000000ÿØÿàJFIFddÿìDuckydÿîAdobedÀÿÛ„ÿÀdÿÄU Q¡Ña‘ÿÚ ?ßÀ#¿ªÚ0 ïæ¶œ ‡3Yû žñݲ ?ÿÙopenchange-2.0/apidocs/html/overview/nav_f.png000066400000000000000000000002311223057412600215130ustar00rootroot00000000000000‰PNG  IHDR8³»`IDATxíÝK€ EÑ–·[†øBÑmkâÄÂH—prÓ¼.‚Žó‚ꎤR6Z VI±E‚5j³„lóš›iI˜¬ÞêçJ0ŒÑÑ/Žû›™uøñóÞ¿6sH ÝõyIEND®B`‚openchange-2.0/apidocs/html/overview/nav_g.png000066400000000000000000000001371223057412600215210ustar00rootroot00000000000000‰PNG  IHDRô1&IDATxíÝ1 ÁOHf„á_ ->~¸åM iËMèÀƒS½ü‚<IEND®B`‚openchange-2.0/apidocs/html/overview/nav_h.png000066400000000000000000000001421223057412600215160ustar00rootroot00000000000000‰PNG  IHDR ,é@)IDATxíÝA @BQ­³šÛ›Ð¢Žáà) )ëý éaÅèÜ¿Æo‡RlÐßIEND®B`‚openchange-2.0/apidocs/html/overview/nav_tab.gif000066400000000000000000000014541223057412600220250ustar00rootroot00000000000000GIF89aPæïïïþþþýþýûüúõ÷óñôïøú÷ýýüúûù÷ùöôöòöøõïóíðôîóöñùúøüýûòõðïòìîòëíñëòõïõõõÿÿÿúúúîòìðóîêëéðððôôôñññýýýñôðÆÉÅìîëÇÊÆÈÊÆÏÏÎÇÊÅËÍÊêìéïóîçèæÎÏÍÐÐÐõ÷ôÊÍÉïñíÆÈÄÊÌÊêêéïóìüýüÊËÉÏÏÏèêçÕ×ÓüüûÍÎÌëíêÌÍËíñêÏÐÏùûøêëêòöðóõñÉÊÇñôîîñì!ù,Pÿ€ˆ‰Š‹ŒŽ‘ˆ‚@;/Ÿ ¡¢£¤¥¦§¨E(ƒ )·¸¹º»¼½¾¿À¸ 7„23ËÌÍÎÏÐÑÒÓÔÐ=*"DÝÞßàáâãäåæä8 îïðñòóôõö÷õ.A þÿ H° ÁƒM R ¡Ã‡#JœH±¢ÅŠ0)ˆÀ±£Ç CŠI²$Ɉ8Xɲ¥Ë—0cÊœIsæD-èÜɳ§ÏŸ@ƒ *”¢’*]Ê´©Ó§P£J:Q‚X³jÝʵ«×¯`­È@‚³hÓª]˶­Û·p‰ßÆ@ôÀݻxóêÝË·¯ß¿~O Bð °áÈ+^̸±ãÆ< @@¹²å˘3kÞ̹3gˆr Mº´éÓ¨S«^Ízõ D4 ÈžM»¶íÛ¸sëÞ­»¢Àƒ N¼¸ñãÈ“'·H€óçУKŸN½ºõë×} À½»÷ïàËO¾|y;openchange-2.0/apidocs/html/overview/open.png000066400000000000000000000001731223057412600213700ustar00rootroot00000000000000‰PNG  IHDR à‘BIDATxíÝÁ €0 Ð׬ՙ\Àº€39—b!©9{|ðI>$#Àß´ý8/¨ÄØzƒ/Ï>2À[ÎgiU,/¬~¼Ï\ Ä9Ù¸IEND®B`‚openchange-2.0/apidocs/html/overview/pixel_grey.gif000066400000000000000000000000531223057412600225540ustar00rootroot00000000000000GIF89a€îîî!ù,D;openchange-2.0/apidocs/html/overview/sync_off.png000066400000000000000000000015251223057412600222370ustar00rootroot00000000000000‰PNG  IHDRàw=øIDATxíÝKhTWÀñÿä1I&3™8M¦Iš™†I3Ú©b$cÌ I1V1±-(Tö±±Ð.* t!‚K[¥Ä¥ˆ„¨´f£`l(øl©"Y”¤6ÆgÌTú}·sgîܹ ±d{8?æÌ¹÷;çÜuíÚ`:!±F¬¢BäŠ?ŰÄm'yÊÅ>ÑlU¯½üý‰è_‹?€Œê ]€Y(ŠNñ±8fý1°Öqún-eâ¨øtºmâÈ Ó0}b›ù%·©µ×Œ®=Ÿ0´³?Š1sŸ‹0€¯8À‘;_ ‹W|%\ Zð— >舽ln¨p©.aÇ{ )t;Ú b nŸš¯›65°¢¡2çÅÔ?Žž>Oдàuönm¤¢Ì`×­Z¬WjC~>‘Ö¾0+á {{©fÝ×Mæ·æÅ•ìÙ¼˜` Ý›%uA6´½ÅÆö¨Á,]k¢ÄW¼™u±›]‹ˆ7§¯iòh€ ¶¶¬ÏÖu1 ló —Ҷ̺–:ÞÍ\ÄcãÏxøhR²Êè‡Qt$¿ß§¨ ª fdºü<4BÿÙ[•f¸d7=.Mé9/—éªÃëù/ÿO Üaàò}€,‘j?Ÿõ.5Úšm?œÿŸ®ŽXÿ2¬#¸d píæ(£?cÛú¼!½›a1¥Þ—ŽòØ©ܾ7dÔK:‚ùÒ‰ì)Ê3‚Ü™àÌà]€,±H€µ+køöäu<|`·LhC7¹ÔeÍ Ÿ×Ÿ˜tÜ‹ óH$^2%l.êaeÐäýE”ÌÉ|ÅÜìî‰Ýsä }¸ýDû^hzé~ðR›¦Ã¡¿]|#ü¯@×—Ö‡[k¹–<|š(Ç*€Ý¹dÇtMé:Ýñø«Ø,êÅû¢]”' øXÓ_nò¡Æ|Øý /c§fžâOIEND®B`‚openchange-2.0/apidocs/html/overview/sync_on.png000066400000000000000000000015151223057412600221000ustar00rootroot00000000000000‰PNG  IHDRàw=øIDATxíÝ_HTYÀñï8ã¤ó§i§4-g6ÆËÕ&kQ)¨Ô!Š0ÒURKÚ…„ê¡/»PEÁ>ìK-+KÁ²Ñ.Y”¾dEPaA‰ø°¥¶›ZSÓïÜ;3wºŠ–¯—߯gfîïœsçœWKÇñ.€ÉøD­¨a‘'¬âq_ôˆk¢ÀŒ ÀDŽøQ´ÄïC¨¶åñÏÿgÅ ñ 0„Y‚:qZ¦Á)~õâ€èLý0HVñ× žz-¿‰C“%¨g¦˜6€é8%Úõ¬ëwêÙUÏ¿˜ª³Ä }? ?€·3ÀÀž©Š À”K• @hà a±ðaÇæUe‹ sù~ë2²ì“&Ú&B*AÄljæºììi*˨,Ëçí»÷oÆ£T”,d[˜¼3-*ÁÀ…>å‡Ë çLÉŸçfk˜Ò éw#*AEjKUy>ûšËÉõ&{µ¢8—m5Ki¬ jjƒD*¿NŽÖigwÃ7Dª’mz骹úKÛ¾±ˆ¶M!æ¤ÍkÐ?šoý¬_åÓlXí#Ò~–¸¬ê×ÒÑXŠÓ‘ùRÙ*Eû‚ՂדðEÜ;6«e"Q(²Ù=–¿Ezæ5Kؼָ_ 1òzBªJë ±XŒì96åªjL^7{ùãJÑ÷1½i@%8'7M©_\Qœ#ÓUŒËñýÿyõ Wo Éx8¼s¥v¯ªì|×SnÜ q_m Ýé î>bèÕí[JX,½4[Tú{R£ë¼ôˆ¾þa€tÝjjzzÅ'ÅìȶiIžŽòwÏs ¡€—ÕKøõâC^ŽŒ˜Y­¨µÉ%6¨´êˆº]vÛðhâ½iWv–hôëê°Ò¨¾'æÌ‚·ñ|[ßìúÅ^€YrD=<ýDû]äÇ÷s€Ïõ‹8™ºCì? À ¨—t4õᩎ¡Jã‡W‹É± îr¼cjMɘìx| šE©øNÔ‰œøA¢þ«–€Z¼ñ‡jó î#™§¢¢4gIEND®B`‚openchange-2.0/apidocs/html/overview/tab_a.png000066400000000000000000000002161223057412600214730ustar00rootroot00000000000000‰PNG  IHDR$ÇÇ[UIDATxíK €0C'o¤(Šˆ[Žà%Üxÿ#Ù©­ç ùÁöó¦W¦e# 3t I 3+¼øEã~\D½9¯Ûàè’wM·¿öÿ}Yõ_êA4Yžã}IEND®B`‚openchange-2.0/apidocs/html/overview/tab_b.png000066400000000000000000000002471223057412600215000ustar00rootroot00000000000000‰PNG  IHDR$ÇÇ[nIDATxíÝQ Â0„áàœR¥Xc±I7IÓ¨g|òÕÙœäãgY˜3˜Ï÷‡u{£ÔW—ÊSíŒ1Ü ¼CjˆiC†G¬ýççJ+| ÖÝs7ùŒ+Ù›`t‚3Ü‚a¢K¤Gq°ûQÍZÝT=@*éC݇LIEND®B`‚openchange-2.0/apidocs/html/overview/tab_h.png000066400000000000000000000003001223057412600214740ustar00rootroot00000000000000‰PNG  IHDR$ÇÇ[‡IDATxíÝË ‚@EÑ 7êÂX’Ñø AADùjGü€ Z€e؈£ ë8¹›—Wƒx¾ÞìUK.µ%„0mɤ&+4iÑ$džÈt“׿ÍzWf5AZá'w¼øÆ"2¶Wœðòg%öªdæ)æþ™ÉR15F®dìž ÉБßO«×Áô»C"à@¯g=IEND®B`‚openchange-2.0/apidocs/html/overview/tab_s.png000066400000000000000000000002701223057412600215150ustar00rootroot00000000000000‰PNG  IHDR$ÇÇ[IDATxíÝ ‚@@Ñ£?Q…¤"š¢%¦I‘—Šf–6[´HÃäQƒ<Þâõþ]ždr Í’s?ˆO=Ñññw'ÌF‡Ž íðö-~rÃ[œèŠ­ì¬mƒÖ¬ƒݯнŠÕF)Yº% §`nÌ,9B ™’©!ÑŒ\ý<Å#üîî•IEND®B`‚openchange-2.0/apidocs/html/overview/tabs.css000066400000000000000000000022131223057412600213610ustar00rootroot00000000000000.tabs, .tabs2, .tabs3 { background-image: url('tab_b.png'); width: 100%; z-index: 101; font-size: 13px; font-family: 'Lucida Grande',Geneva,Helvetica,Arial,sans-serif; } .tabs2 { font-size: 10px; } .tabs3 { font-size: 9px; } .tablist { margin: 0; padding: 0; display: table; } .tablist li { float: left; display: table-cell; background-image: url('tab_b.png'); line-height: 36px; list-style: none; } .tablist a { display: block; padding: 0 20px; font-weight: bold; background-image:url('tab_s.png'); background-repeat:no-repeat; background-position:right; color: #283A5D; text-shadow: 0px 1px 1px rgba(255, 255, 255, 0.9); text-decoration: none; outline: none; } .tabs3 .tablist a { padding: 0 10px; } .tablist a:hover { background-image: url('tab_h.png'); background-repeat:repeat-x; color: #fff; text-shadow: 0px 1px 1px rgba(0, 0, 0, 1.0); text-decoration: none; } .tablist li.current a { background-image: url('tab_a.png'); background-repeat:repeat-x; color: #fff; text-shadow: 0px 1px 1px rgba(0, 0, 0, 1.0); } openchange-2.0/apidocs/man/000077500000000000000000000000001223057412600156615ustar00rootroot00000000000000openchange-2.0/apidocs/man/man3/000077500000000000000000000000001223057412600165175ustar00rootroot00000000000000openchange-2.0/apidocs/man/man3/Abort.3000066400000000000000000000000301223057412600176430ustar00rootroot00000000000000.so man3/IMAPITable.c.3 openchange-2.0/apidocs/man/man3/AbortSubmit.3000066400000000000000000000000261223057412600210340ustar00rootroot00000000000000.so man3/IMessage.c.3 openchange-2.0/apidocs/man/man3/AddUserPermission.3000066400000000000000000000000311223057412600221750ustar00rootroot00000000000000.so man3/simple_mapi.c.3 openchange-2.0/apidocs/man/man3/AddressTypes.3000066400000000000000000000000261223057412600212130ustar00rootroot00000000000000.so man3/IXPLogon.c.3 openchange-2.0/apidocs/man/man3/ChangeProfilePassword.3000066400000000000000000000000301223057412600230250ustar00rootroot00000000000000.so man3/IProfAdmin.c.3 openchange-2.0/apidocs/man/man3/CloneStream.3000066400000000000000000000000251223057412600210140ustar00rootroot00000000000000.so man3/IStream.c.3 openchange-2.0/apidocs/man/man3/CollapseRow.3000066400000000000000000000000301223057412600210260ustar00rootroot00000000000000.so man3/IMAPITable.c.3 openchange-2.0/apidocs/man/man3/CommitStream.3000066400000000000000000000000251223057412600212040ustar00rootroot00000000000000.so man3/IStream.c.3 openchange-2.0/apidocs/man/man3/CopyFolder.3000066400000000000000000000000311223057412600206430ustar00rootroot00000000000000.so man3/IMAPIFolder.c.3 openchange-2.0/apidocs/man/man3/CopyProfile.3000066400000000000000000000000301223057412600210270ustar00rootroot00000000000000.so man3/IProfAdmin.c.3 openchange-2.0/apidocs/man/man3/CopyProps.3000066400000000000000000000000271223057412600205400ustar00rootroot00000000000000.so man3/IMAPIProp.c.3 openchange-2.0/apidocs/man/man3/CopyTo.3000066400000000000000000000000271223057412600200170ustar00rootroot00000000000000.so man3/IMAPIProp.c.3 openchange-2.0/apidocs/man/man3/CopyToStream.3000066400000000000000000000000251223057412600211710ustar00rootroot00000000000000.so man3/IStream.c.3 openchange-2.0/apidocs/man/man3/CreateAttach.3000066400000000000000000000000261223057412600211310ustar00rootroot00000000000000.so man3/IMessage.c.3 openchange-2.0/apidocs/man/man3/CreateBookmark.3000066400000000000000000000000301223057412600214650ustar00rootroot00000000000000.so man3/IMAPITable.c.3 openchange-2.0/apidocs/man/man3/CreateFolder.3000066400000000000000000000000311223057412600211340ustar00rootroot00000000000000.so man3/IMAPIFolder.c.3 openchange-2.0/apidocs/man/man3/CreateMessage.3000066400000000000000000000000311223057412600213050ustar00rootroot00000000000000.so man3/IMAPIFolder.c.3 openchange-2.0/apidocs/man/man3/CreateProfile.3000066400000000000000000000000301223057412600213200ustar00rootroot00000000000000.so man3/IProfAdmin.c.3 openchange-2.0/apidocs/man/man3/CreateProfileStore.3000066400000000000000000000000301223057412600223350ustar00rootroot00000000000000.so man3/IProfAdmin.c.3 openchange-2.0/apidocs/man/man3/DeleteAttach.3000066400000000000000000000000261223057412600211300ustar00rootroot00000000000000.so man3/IMessage.c.3 openchange-2.0/apidocs/man/man3/DeleteFolder.3000066400000000000000000000000311223057412600211330ustar00rootroot00000000000000.so man3/IMAPIFolder.c.3 openchange-2.0/apidocs/man/man3/DeleteMessage.3000066400000000000000000000000311223057412600213040ustar00rootroot00000000000000.so man3/IMAPIFolder.c.3 openchange-2.0/apidocs/man/man3/DeleteProfile.3000066400000000000000000000000301223057412600213170ustar00rootroot00000000000000.so man3/IProfAdmin.c.3 openchange-2.0/apidocs/man/man3/DeletePropertiesNoReplicate.3000066400000000000000000000000271223057412600242070ustar00rootroot00000000000000.so man3/IMAPIProp.c.3 openchange-2.0/apidocs/man/man3/DeleteProps.3000066400000000000000000000000271223057412600210300ustar00rootroot00000000000000.so man3/IMAPIProp.c.3 openchange-2.0/apidocs/man/man3/DispatchNotifications.3000066400000000000000000000000321223057412600230670ustar00rootroot00000000000000.so man3/IMAPISupport.c.3 openchange-2.0/apidocs/man/man3/DuplicateProfile.3000066400000000000000000000000301223057412600220270ustar00rootroot00000000000000.so man3/IProfAdmin.c.3 openchange-2.0/apidocs/man/man3/EcDoRpc_RopCommitStream.3000066400000000000000000000000251223057412600232240ustar00rootroot00000000000000.so man3/oxcprpt.c.3 openchange-2.0/apidocs/man/man3/EcDoRpc_RopCopyFolder.3000066400000000000000000000000251223057412600226660ustar00rootroot00000000000000.so man3/oxcfold.c.3 openchange-2.0/apidocs/man/man3/EcDoRpc_RopCopyTo.3000066400000000000000000000000251223057412600220350ustar00rootroot00000000000000.so man3/oxcprpt.c.3 openchange-2.0/apidocs/man/man3/EcDoRpc_RopCreateAttach.3000066400000000000000000000000241223057412600231470ustar00rootroot00000000000000.so man3/oxcmsg.c.3 openchange-2.0/apidocs/man/man3/EcDoRpc_RopCreateFolder.3000066400000000000000000000000251223057412600231570ustar00rootroot00000000000000.so man3/oxcfold.c.3 openchange-2.0/apidocs/man/man3/EcDoRpc_RopCreateMessage.3000066400000000000000000000000241223057412600233270ustar00rootroot00000000000000.so man3/oxcmsg.c.3 openchange-2.0/apidocs/man/man3/EcDoRpc_RopDeleteFolder.3000066400000000000000000000000251223057412600231560ustar00rootroot00000000000000.so man3/oxcfold.c.3 openchange-2.0/apidocs/man/man3/EcDoRpc_RopDeleteMessages.3000066400000000000000000000000251223057412600235120ustar00rootroot00000000000000.so man3/oxcfold.c.3 openchange-2.0/apidocs/man/man3/EcDoRpc_RopDeleteProperties.3000066400000000000000000000000251223057412600240770ustar00rootroot00000000000000.so man3/oxcprpt.c.3 openchange-2.0/apidocs/man/man3/EcDoRpc_RopDeletePropertiesNoReplicate.3000066400000000000000000000000251223057412600262250ustar00rootroot00000000000000.so man3/oxcprpt.c.3 openchange-2.0/apidocs/man/man3/EcDoRpc_RopEmptyFolder.3000066400000000000000000000000251223057412600230520ustar00rootroot00000000000000.so man3/oxcfold.c.3 openchange-2.0/apidocs/man/man3/EcDoRpc_RopFastTransferSourceCopyTo.3000066400000000000000000000000261223057412600255420ustar00rootroot00000000000000.so man3/oxcfxics.c.3 openchange-2.0/apidocs/man/man3/EcDoRpc_RopFastTransferSourceGetBuffer.3000066400000000000000000000000261223057412600261760ustar00rootroot00000000000000.so man3/oxcfxics.c.3 openchange-2.0/apidocs/man/man3/EcDoRpc_RopFindRow.3000066400000000000000000000000251223057412600221700ustar00rootroot00000000000000.so man3/oxctabl.c.3 openchange-2.0/apidocs/man/man3/EcDoRpc_RopGetAddressTypes.3000066400000000000000000000000241223057412600236710ustar00rootroot00000000000000.so man3/oxomsg.c.3 openchange-2.0/apidocs/man/man3/EcDoRpc_RopGetAttachmentTable.3000066400000000000000000000000241223057412600243170ustar00rootroot00000000000000.so man3/oxcmsg.c.3 openchange-2.0/apidocs/man/man3/EcDoRpc_RopGetContentsTable.3000066400000000000000000000000251223057412600240250ustar00rootroot00000000000000.so man3/oxcfold.c.3 openchange-2.0/apidocs/man/man3/EcDoRpc_RopGetHierarchyTable.3000066400000000000000000000000251223057412600241460ustar00rootroot00000000000000.so man3/oxcfold.c.3 openchange-2.0/apidocs/man/man3/EcDoRpc_RopGetLocalReplicaIds.3000066400000000000000000000000261223057412600242530ustar00rootroot00000000000000.so man3/oxcfxics.c.3 openchange-2.0/apidocs/man/man3/EcDoRpc_RopGetNamesFromIDs.3000066400000000000000000000000251223057412600235470ustar00rootroot00000000000000.so man3/oxcprpt.c.3 openchange-2.0/apidocs/man/man3/EcDoRpc_RopGetPerUserGuid.3000066400000000000000000000000251223057412600234560ustar00rootroot00000000000000.so man3/oxcstor.c.3 openchange-2.0/apidocs/man/man3/EcDoRpc_RopGetPerUserLongTermIds.3000066400000000000000000000000251223057412600247550ustar00rootroot00000000000000.so man3/oxcstor.c.3 openchange-2.0/apidocs/man/man3/EcDoRpc_RopGetPermissionsTable.3000066400000000000000000000000251223057412600245430ustar00rootroot00000000000000.so man3/oxcperm.c.3 openchange-2.0/apidocs/man/man3/EcDoRpc_RopGetPropertiesAll.3000066400000000000000000000000251223057412600240450ustar00rootroot00000000000000.so man3/oxcprpt.c.3 openchange-2.0/apidocs/man/man3/EcDoRpc_RopGetPropertiesList.3000066400000000000000000000000251223057412600242500ustar00rootroot00000000000000.so man3/oxcprpt.c.3 openchange-2.0/apidocs/man/man3/EcDoRpc_RopGetPropertiesSpecific.3000066400000000000000000000000251223057412600250620ustar00rootroot00000000000000.so man3/oxcprpt.c.3 openchange-2.0/apidocs/man/man3/EcDoRpc_RopGetPropertyIdsFromNames.3000066400000000000000000000000251223057412600253540ustar00rootroot00000000000000.so man3/oxcprpt.c.3 openchange-2.0/apidocs/man/man3/EcDoRpc_RopGetReceiveFolder.3000066400000000000000000000000251223057412600237760ustar00rootroot00000000000000.so man3/oxcstor.c.3 openchange-2.0/apidocs/man/man3/EcDoRpc_RopGetSearchCriteria.3000066400000000000000000000000251223057412600241500ustar00rootroot00000000000000.so man3/oxcfold.c.3 openchange-2.0/apidocs/man/man3/EcDoRpc_RopGetStoreState.3000066400000000000000000000000251223057412600233550ustar00rootroot00000000000000.so man3/oxcstor.c.3 openchange-2.0/apidocs/man/man3/EcDoRpc_RopGetStreamSize.3000066400000000000000000000000251223057412600233460ustar00rootroot00000000000000.so man3/oxcprpt.c.3 openchange-2.0/apidocs/man/man3/EcDoRpc_RopGetTransportFolder.3000066400000000000000000000000241223057412600244070ustar00rootroot00000000000000.so man3/oxomsg.c.3 openchange-2.0/apidocs/man/man3/EcDoRpc_RopIdFromLongTermId.3000066400000000000000000000000251223057412600237250ustar00rootroot00000000000000.so man3/oxcstor.c.3 openchange-2.0/apidocs/man/man3/EcDoRpc_RopLogon.3000066400000000000000000000000251223057412600216760ustar00rootroot00000000000000.so man3/oxcstor.c.3 openchange-2.0/apidocs/man/man3/EcDoRpc_RopLongTermIdFromId.3000066400000000000000000000000251223057412600237250ustar00rootroot00000000000000.so man3/oxcstor.c.3 openchange-2.0/apidocs/man/man3/EcDoRpc_RopModifyPermissions.3000066400000000000000000000000251223057412600243030ustar00rootroot00000000000000.so man3/oxcperm.c.3 openchange-2.0/apidocs/man/man3/EcDoRpc_RopModifyRecipients.3000066400000000000000000000000241223057412600240740ustar00rootroot00000000000000.so man3/oxcmsg.c.3 openchange-2.0/apidocs/man/man3/EcDoRpc_RopMoveFolder.3000066400000000000000000000000251223057412600226620ustar00rootroot00000000000000.so man3/oxcfold.c.3 openchange-2.0/apidocs/man/man3/EcDoRpc_RopOpenAttach.3000066400000000000000000000000241223057412600226450ustar00rootroot00000000000000.so man3/oxcmsg.c.3 openchange-2.0/apidocs/man/man3/EcDoRpc_RopOpenEmbeddedMessage.3000066400000000000000000000000241223057412600244370ustar00rootroot00000000000000.so man3/oxcmsg.c.3 openchange-2.0/apidocs/man/man3/EcDoRpc_RopOpenFolder.3000066400000000000000000000000251223057412600226550ustar00rootroot00000000000000.so man3/oxcfold.c.3 openchange-2.0/apidocs/man/man3/EcDoRpc_RopOpenMessage.3000066400000000000000000000000241223057412600230250ustar00rootroot00000000000000.so man3/oxcmsg.c.3 openchange-2.0/apidocs/man/man3/EcDoRpc_RopOpenStream.3000066400000000000000000000000251223057412600226750ustar00rootroot00000000000000.so man3/oxcprpt.c.3 openchange-2.0/apidocs/man/man3/EcDoRpc_RopOptionsData.3000066400000000000000000000000241223057412600230440ustar00rootroot00000000000000.so man3/oxomsg.c.3 openchange-2.0/apidocs/man/man3/EcDoRpc_RopQueryPosition.3000066400000000000000000000000251223057412600234520ustar00rootroot00000000000000.so man3/oxctabl.c.3 openchange-2.0/apidocs/man/man3/EcDoRpc_RopQueryRows.3000066400000000000000000000000251223057412600226000ustar00rootroot00000000000000.so man3/oxctabl.c.3 openchange-2.0/apidocs/man/man3/EcDoRpc_RopReadPerUserInformation.3000066400000000000000000000000251223057412600252070ustar00rootroot00000000000000.so man3/oxcstor.c.3 openchange-2.0/apidocs/man/man3/EcDoRpc_RopReadStream.3000066400000000000000000000000251223057412600226470ustar00rootroot00000000000000.so man3/oxcprpt.c.3 openchange-2.0/apidocs/man/man3/EcDoRpc_RopRegisterNotification.3000066400000000000000000000000261223057412600247540ustar00rootroot00000000000000.so man3/oxcnotif.c.3 openchange-2.0/apidocs/man/man3/EcDoRpc_RopRelease.3000066400000000000000000000000251223057412600222000ustar00rootroot00000000000000.so man3/oxcstor.c.3 openchange-2.0/apidocs/man/man3/EcDoRpc_RopReloadCachedInformation.3000066400000000000000000000000241223057412600253230ustar00rootroot00000000000000.so man3/oxcmsg.c.3 openchange-2.0/apidocs/man/man3/EcDoRpc_RopRemoveAllRecipients.3000066400000000000000000000000241223057412600245330ustar00rootroot00000000000000.so man3/oxcmsg.c.3 openchange-2.0/apidocs/man/man3/EcDoRpc_RopResetTable.3000066400000000000000000000000251223057412600226520ustar00rootroot00000000000000.so man3/oxctabl.c.3 openchange-2.0/apidocs/man/man3/EcDoRpc_RopRestrict.3000066400000000000000000000000251223057412600224170ustar00rootroot00000000000000.so man3/oxctabl.c.3 openchange-2.0/apidocs/man/man3/EcDoRpc_RopSaveChangesAttachment.3000066400000000000000000000000241223057412600250170ustar00rootroot00000000000000.so man3/oxcmsg.c.3 openchange-2.0/apidocs/man/man3/EcDoRpc_RopSaveChangesMessage.3000066400000000000000000000000241223057412600243130ustar00rootroot00000000000000.so man3/oxcmsg.c.3 openchange-2.0/apidocs/man/man3/EcDoRpc_RopSeekRow.3000066400000000000000000000000251223057412600221770ustar00rootroot00000000000000.so man3/oxctabl.c.3 openchange-2.0/apidocs/man/man3/EcDoRpc_RopSeekStream.3000066400000000000000000000000251223057412600226630ustar00rootroot00000000000000.so man3/oxcprpt.c.3 openchange-2.0/apidocs/man/man3/EcDoRpc_RopSetColumns.3000066400000000000000000000000251223057412600227140ustar00rootroot00000000000000.so man3/oxctabl.c.3 openchange-2.0/apidocs/man/man3/EcDoRpc_RopSetLocalReplicaMidsetDeleted.3000066400000000000000000000000261223057412600262640ustar00rootroot00000000000000.so man3/oxcfxics.c.3 openchange-2.0/apidocs/man/man3/EcDoRpc_RopSetMessageReadFlag.3000066400000000000000000000000241223057412600242450ustar00rootroot00000000000000.so man3/oxcmsg.c.3 openchange-2.0/apidocs/man/man3/EcDoRpc_RopSetProperties.3000066400000000000000000000000251223057412600234300ustar00rootroot00000000000000.so man3/oxcprpt.c.3 openchange-2.0/apidocs/man/man3/EcDoRpc_RopSetReceiveFolder.3000066400000000000000000000000251223057412600240120ustar00rootroot00000000000000.so man3/oxcstor.c.3 openchange-2.0/apidocs/man/man3/EcDoRpc_RopSetSearchCriteria.3000066400000000000000000000000251223057412600241640ustar00rootroot00000000000000.so man3/oxcfold.c.3 openchange-2.0/apidocs/man/man3/EcDoRpc_RopSetSpooler.3000066400000000000000000000000241223057412600227160ustar00rootroot00000000000000.so man3/oxomsg.c.3 openchange-2.0/apidocs/man/man3/EcDoRpc_RopSetStreamSize.3000066400000000000000000000000251223057412600233620ustar00rootroot00000000000000.so man3/oxcprpt.c.3 openchange-2.0/apidocs/man/man3/EcDoRpc_RopSortTable.3000066400000000000000000000000251223057412600225170ustar00rootroot00000000000000.so man3/oxctabl.c.3 openchange-2.0/apidocs/man/man3/EcDoRpc_RopSubmitMessage.3000066400000000000000000000000241223057412600233670ustar00rootroot00000000000000.so man3/oxomsg.c.3 openchange-2.0/apidocs/man/man3/EcDoRpc_RopSyncConfigure.3000066400000000000000000000000261223057412600233770ustar00rootroot00000000000000.so man3/oxcfxics.c.3 openchange-2.0/apidocs/man/man3/EcDoRpc_RopSyncGetTransferState.3000066400000000000000000000000261223057412600247030ustar00rootroot00000000000000.so man3/oxcfxics.c.3 openchange-2.0/apidocs/man/man3/EcDoRpc_RopSyncImportDeletes.3000066400000000000000000000000261223057412600242360ustar00rootroot00000000000000.so man3/oxcfxics.c.3 openchange-2.0/apidocs/man/man3/EcDoRpc_RopSyncImportHierarchyChange.3000066400000000000000000000000261223057412600256750ustar00rootroot00000000000000.so man3/oxcfxics.c.3 openchange-2.0/apidocs/man/man3/EcDoRpc_RopSyncImportMessageChange.3000066400000000000000000000000261223057412600253430ustar00rootroot00000000000000.so man3/oxcfxics.c.3 openchange-2.0/apidocs/man/man3/EcDoRpc_RopSyncImportReadStateChanges.3000066400000000000000000000000261223057412600260160ustar00rootroot00000000000000.so man3/oxcfxics.c.3 openchange-2.0/apidocs/man/man3/EcDoRpc_RopSyncOpenCollector.3000066400000000000000000000000261223057412600242260ustar00rootroot00000000000000.so man3/oxcfxics.c.3 openchange-2.0/apidocs/man/man3/EcDoRpc_RopSyncUploadStateStreamBegin.3000066400000000000000000000000261223057412600260240ustar00rootroot00000000000000.so man3/oxcfxics.c.3 openchange-2.0/apidocs/man/man3/EcDoRpc_RopSyncUploadStateStreamContinue.3000066400000000000000000000000261223057412600265640ustar00rootroot00000000000000.so man3/oxcfxics.c.3 openchange-2.0/apidocs/man/man3/EcDoRpc_RopSyncUploadStateStreamEnd.3000066400000000000000000000000261223057412600255060ustar00rootroot00000000000000.so man3/oxcfxics.c.3 openchange-2.0/apidocs/man/man3/EcDoRpc_RopTransportSend.3000066400000000000000000000000241223057412600234250ustar00rootroot00000000000000.so man3/oxomsg.c.3 openchange-2.0/apidocs/man/man3/EcDoRpc_RopWriteStream.3000066400000000000000000000000251223057412600230660ustar00rootroot00000000000000.so man3/oxcprpt.c.3 openchange-2.0/apidocs/man/man3/EmptyFolder.3000066400000000000000000000000311223057412600210270ustar00rootroot00000000000000.so man3/IMAPIFolder.c.3 openchange-2.0/apidocs/man/man3/EntryIDFromSourceIDForMessage.3000066400000000000000000000000231223057412600243120ustar00rootroot00000000000000.so man3/utils.c.3 openchange-2.0/apidocs/man/man3/EphemeralEntryID.3000066400000000000000000000006141223057412600217450ustar00rootroot00000000000000.TH "EphemeralEntryID" 3 "Thu Jan 24 2013" "Version 2.0" "MAPIProxy" \" -*- nroff -*- .ad l .nh .SH NAME EphemeralEntryID \- .PP \fBEphemeralEntryID\fP structure\&. .SH SYNOPSIS .br .PP .PP \fC#include \fP .SH "Detailed Description" .PP \fBEphemeralEntryID\fP structure\&. .SH "Author" .PP Generated automatically by Doxygen for MAPIProxy from the source code\&. openchange-2.0/apidocs/man/man3/ExpandRow.3000066400000000000000000000000301223057412600205030ustar00rootroot00000000000000.so man3/IMAPITable.c.3 openchange-2.0/apidocs/man/man3/FXCopyFolder.3000066400000000000000000000000231223057412600211020ustar00rootroot00000000000000.so man3/FXICS.c.3 openchange-2.0/apidocs/man/man3/FXCopyMessages.3000066400000000000000000000000231223057412600214360ustar00rootroot00000000000000.so man3/FXICS.c.3 openchange-2.0/apidocs/man/man3/FXCopyProperties.3000066400000000000000000000000231223057412600220230ustar00rootroot00000000000000.so man3/FXICS.c.3 openchange-2.0/apidocs/man/man3/FXCopyTo.3000066400000000000000000000000231223057412600202510ustar00rootroot00000000000000.so man3/FXICS.c.3 openchange-2.0/apidocs/man/man3/FXDestConfigure.3000066400000000000000000000000231223057412600215750ustar00rootroot00000000000000.so man3/FXICS.c.3 openchange-2.0/apidocs/man/man3/FXGetBuffer.3000066400000000000000000000000231223057412600207050ustar00rootroot00000000000000.so man3/FXICS.c.3 openchange-2.0/apidocs/man/man3/FXPutBuffer.3000066400000000000000000000000231223057412600207360ustar00rootroot00000000000000.so man3/FXICS.c.3 openchange-2.0/apidocs/man/man3/FindProfileAttr.3000066400000000000000000000000301223057412600216300ustar00rootroot00000000000000.so man3/IProfAdmin.c.3 openchange-2.0/apidocs/man/man3/FindRow.3000066400000000000000000000000301223057412600201440ustar00rootroot00000000000000.so man3/IMAPITable.c.3 openchange-2.0/apidocs/man/man3/FreeBookmark.3000066400000000000000000000000301223057412600211430ustar00rootroot00000000000000.so man3/IMAPITable.c.3 openchange-2.0/apidocs/man/man3/GLOBSET_parse.3000066400000000000000000000000231223057412600210670ustar00rootroot00000000000000.so man3/idset.c.3 openchange-2.0/apidocs/man/man3/GetABRecipientInfo.3000066400000000000000000000000321223057412600221770ustar00rootroot00000000000000.so man3/IABContainer.c.3 openchange-2.0/apidocs/man/man3/GetAttachmentTable.3000066400000000000000000000000261223057412600223010ustar00rootroot00000000000000.so man3/IMessage.c.3 openchange-2.0/apidocs/man/man3/GetBestBody.3000066400000000000000000000000311223057412600207500ustar00rootroot00000000000000.so man3/simple_mapi.c.3 openchange-2.0/apidocs/man/man3/GetCollapseState.3000066400000000000000000000000301223057412600217770ustar00rootroot00000000000000.so man3/IMAPITable.c.3 openchange-2.0/apidocs/man/man3/GetContentsTable.3000066400000000000000000000000341223057412600220050ustar00rootroot00000000000000.so man3/IMAPIContainer.c.3 openchange-2.0/apidocs/man/man3/GetDefaultFolder.3000066400000000000000000000000311223057412600217550ustar00rootroot00000000000000.so man3/simple_mapi.c.3 openchange-2.0/apidocs/man/man3/GetDefaultProfile.3000066400000000000000000000000301223057412600221410ustar00rootroot00000000000000.so man3/IProfAdmin.c.3 openchange-2.0/apidocs/man/man3/GetDefaultPublicFolder.3000066400000000000000000000000311223057412600231140ustar00rootroot00000000000000.so man3/simple_mapi.c.3 openchange-2.0/apidocs/man/man3/GetFIDFromEntryID.3000066400000000000000000000000231223057412600217230ustar00rootroot00000000000000.so man3/utils.c.3 openchange-2.0/apidocs/man/man3/GetFolderItemsCount.3000066400000000000000000000000311223057412600224630ustar00rootroot00000000000000.so man3/simple_mapi.c.3 openchange-2.0/apidocs/man/man3/GetFreeBusyYear.3000066400000000000000000000000261223057412600216060ustar00rootroot00000000000000.so man3/freebusy.c.3 openchange-2.0/apidocs/man/man3/GetGALTable.3000066400000000000000000000000321223057412600206110ustar00rootroot00000000000000.so man3/IABContainer.c.3 openchange-2.0/apidocs/man/man3/GetGALTableCount.3000066400000000000000000000000321223057412600216220ustar00rootroot00000000000000.so man3/IABContainer.c.3 openchange-2.0/apidocs/man/man3/GetHierarchyTable.3000066400000000000000000000000341223057412600221260ustar00rootroot00000000000000.so man3/IMAPIContainer.c.3 openchange-2.0/apidocs/man/man3/GetIDsFromNames.3000066400000000000000000000000271223057412600215310ustar00rootroot00000000000000.so man3/IMAPIProp.c.3 openchange-2.0/apidocs/man/man3/GetIdFromLongTermId.3000066400000000000000000000000261223057412600223460ustar00rootroot00000000000000.so man3/IUnknown.c.3 openchange-2.0/apidocs/man/man3/GetLastError.3000066400000000000000000000000261223057412600211560ustar00rootroot00000000000000.so man3/IUnknown.c.3 openchange-2.0/apidocs/man/man3/GetLoadparmContext.3000066400000000000000000000000261223057412600223450ustar00rootroot00000000000000.so man3/cdo_mapi.c.3 openchange-2.0/apidocs/man/man3/GetLocalReplicaIds.3000066400000000000000000000000231223057412600222300ustar00rootroot00000000000000.so man3/FXICS.c.3 openchange-2.0/apidocs/man/man3/GetLongTermIdFromId.3000066400000000000000000000000261223057412600223460ustar00rootroot00000000000000.so man3/IUnknown.c.3 openchange-2.0/apidocs/man/man3/GetMessageStatus.3000066400000000000000000000000311223057412600220250ustar00rootroot00000000000000.so man3/IMAPIFolder.c.3 openchange-2.0/apidocs/man/man3/GetNamesFromIDs.3000066400000000000000000000000271223057412600215310ustar00rootroot00000000000000.so man3/IMAPIProp.c.3 openchange-2.0/apidocs/man/man3/GetNewLogonId.3000066400000000000000000000000311223057412600212420ustar00rootroot00000000000000.so man3/IMSProvider.c.3 openchange-2.0/apidocs/man/man3/GetOutboxFolder.3000066400000000000000000000000271223057412600216560ustar00rootroot00000000000000.so man3/IMsgStore.c.3 openchange-2.0/apidocs/man/man3/GetOwningServers.3000066400000000000000000000000271223057412600220550ustar00rootroot00000000000000.so man3/IMsgStore.c.3 openchange-2.0/apidocs/man/man3/GetPermissionsTable.3000066400000000000000000000000341223057412600225230ustar00rootroot00000000000000.so man3/IMAPIContainer.c.3 openchange-2.0/apidocs/man/man3/GetProfileAttr.3000066400000000000000000000000301223057412600214670ustar00rootroot00000000000000.so man3/IProfAdmin.c.3 openchange-2.0/apidocs/man/man3/GetProfileTable.3000066400000000000000000000000301223057412600216040ustar00rootroot00000000000000.so man3/IProfAdmin.c.3 openchange-2.0/apidocs/man/man3/GetPropList.3000066400000000000000000000000271223057412600210160ustar00rootroot00000000000000.so man3/IMAPIProp.c.3 openchange-2.0/apidocs/man/man3/GetProps.3000066400000000000000000000000271223057412600203450ustar00rootroot00000000000000.so man3/IMAPIProp.c.3 openchange-2.0/apidocs/man/man3/GetPropsAll.3000066400000000000000000000000271223057412600207760ustar00rootroot00000000000000.so man3/IMAPIProp.c.3 openchange-2.0/apidocs/man/man3/GetReceiveFolder.3000066400000000000000000000000271223057412600217600ustar00rootroot00000000000000.so man3/IMsgStore.c.3 openchange-2.0/apidocs/man/man3/GetReceiveFolderTable.3000066400000000000000000000000271223057412600227300ustar00rootroot00000000000000.so man3/IMsgStore.c.3 openchange-2.0/apidocs/man/man3/GetRecipientTable.3000066400000000000000000000000261223057412600221330ustar00rootroot00000000000000.so man3/IMessage.c.3 openchange-2.0/apidocs/man/man3/GetRulesTable.3000066400000000000000000000000341223057412600213020ustar00rootroot00000000000000.so man3/IMAPIContainer.c.3 openchange-2.0/apidocs/man/man3/GetSearchCriteria.3000066400000000000000000000000341223057412600221300ustar00rootroot00000000000000.so man3/IMAPIContainer.c.3 openchange-2.0/apidocs/man/man3/GetStatus.3000066400000000000000000000000301223057412600205170ustar00rootroot00000000000000.so man3/IMAPITable.c.3 openchange-2.0/apidocs/man/man3/GetStoreState.3000066400000000000000000000000271223057412600213370ustar00rootroot00000000000000.so man3/IMsgStore.c.3 openchange-2.0/apidocs/man/man3/GetStreamSize.3000066400000000000000000000000251223057412600213260ustar00rootroot00000000000000.so man3/IStream.c.3 openchange-2.0/apidocs/man/man3/GetTransportFolder.3000066400000000000000000000000271223057412600223720ustar00rootroot00000000000000.so man3/IMsgStore.c.3 openchange-2.0/apidocs/man/man3/GetUserFreeBusyData.3000066400000000000000000000000261223057412600224160ustar00rootroot00000000000000.so man3/freebusy.c.3 openchange-2.0/apidocs/man/man3/GetValidAttach.3000066400000000000000000000000261223057412600214250ustar00rootroot00000000000000.so man3/IMessage.c.3 openchange-2.0/apidocs/man/man3/HardDeleteMessage.3000066400000000000000000000000311223057412600221030ustar00rootroot00000000000000.so man3/IMAPIFolder.c.3 openchange-2.0/apidocs/man/man3/HardDeleteMessagesAndSubfolders.3000066400000000000000000000000311223057412600247420ustar00rootroot00000000000000.so man3/IMAPIFolder.c.3 openchange-2.0/apidocs/man/man3/ICSSyncConfigure.3000066400000000000000000000000231223057412600217130ustar00rootroot00000000000000.so man3/FXICS.c.3 openchange-2.0/apidocs/man/man3/ICSSyncGetTransferState.3000066400000000000000000000000231223057412600232170ustar00rootroot00000000000000.so man3/FXICS.c.3 openchange-2.0/apidocs/man/man3/ICSSyncOpenCollector.3000066400000000000000000000000231223057412600225420ustar00rootroot00000000000000.so man3/FXICS.c.3 openchange-2.0/apidocs/man/man3/ICSSyncUploadStateBegin.3000066400000000000000000000000231223057412600231640ustar00rootroot00000000000000.so man3/FXICS.c.3 openchange-2.0/apidocs/man/man3/ICSSyncUploadStateContinue.3000066400000000000000000000000231223057412600237240ustar00rootroot00000000000000.so man3/FXICS.c.3 openchange-2.0/apidocs/man/man3/ICSSyncUploadStateEnd.3000066400000000000000000000000231223057412600226460ustar00rootroot00000000000000.so man3/FXICS.c.3 openchange-2.0/apidocs/man/man3/IDSET_dump.3000066400000000000000000000000231223057412600204730ustar00rootroot00000000000000.so man3/idset.c.3 openchange-2.0/apidocs/man/man3/IDSET_includes_eid.3000066400000000000000000000000231223057412600221550ustar00rootroot00000000000000.so man3/idset.c.3 openchange-2.0/apidocs/man/man3/IDSET_includes_guid_glob.3000066400000000000000000000000231223057412600233470ustar00rootroot00000000000000.so man3/idset.c.3 openchange-2.0/apidocs/man/man3/IDSET_merge_idsets.3000066400000000000000000000000231223057412600222000ustar00rootroot00000000000000.so man3/idset.c.3 openchange-2.0/apidocs/man/man3/IDSET_parse.3000066400000000000000000000000231223057412600206400ustar00rootroot00000000000000.so man3/idset.c.3 openchange-2.0/apidocs/man/man3/IDSET_serialize.3000066400000000000000000000000231223057412600215150ustar00rootroot00000000000000.so man3/idset.c.3 openchange-2.0/apidocs/man/man3/INVALID_HANDLE_VALUE.3000066400000000000000000000000311223057412600216320ustar00rootroot00000000000000.so man3/mapi_object.c.3 openchange-2.0/apidocs/man/man3/IsFreeBusyConflict.3000066400000000000000000000000261223057412600223030ustar00rootroot00000000000000.so man3/freebusy.c.3 openchange-2.0/apidocs/man/man3/IsMailboxFolder.3000066400000000000000000000000311223057412600216200ustar00rootroot00000000000000.so man3/simple_mapi.c.3 openchange-2.0/apidocs/man/man3/LoadProfile.3000066400000000000000000000000301223057412600207740ustar00rootroot00000000000000.so man3/IProfAdmin.c.3 openchange-2.0/apidocs/man/man3/LockRegionStream.3000066400000000000000000000000251223057412600220100ustar00rootroot00000000000000.so man3/IStream.c.3 openchange-2.0/apidocs/man/man3/Logoff.3000066400000000000000000000000311223057412600200110ustar00rootroot00000000000000.so man3/IMSProvider.c.3 openchange-2.0/apidocs/man/man3/MAPIAllocateBuffer.3000066400000000000000000000000261223057412600221260ustar00rootroot00000000000000.so man3/IUnknown.c.3 openchange-2.0/apidocs/man/man3/MAPIFreeBuffer.3000066400000000000000000000000261223057412600212630ustar00rootroot00000000000000.so man3/IUnknown.c.3 openchange-2.0/apidocs/man/man3/MAPIInitialize.3000066400000000000000000000000261223057412600213510ustar00rootroot00000000000000.so man3/cdo_mapi.c.3 openchange-2.0/apidocs/man/man3/MAPISTORE_ERROR.3000066400000000000000000000000361223057412600211160ustar00rootroot00000000000000.so man3/mapistore_errors.h.3 openchange-2.0/apidocs/man/man3/MAPISTORE_ERR_ALREADY_INITIALIZED.3000066400000000000000000000000361223057412600236430ustar00rootroot00000000000000.so man3/mapistore_errors.h.3 openchange-2.0/apidocs/man/man3/MAPISTORE_ERR_BACKEND_INIT.3000066400000000000000000000000361223057412600226070ustar00rootroot00000000000000.so man3/mapistore_errors.h.3 openchange-2.0/apidocs/man/man3/MAPISTORE_ERR_BACKEND_REGISTER.3000066400000000000000000000000361223057412600232700ustar00rootroot00000000000000.so man3/mapistore_errors.h.3 openchange-2.0/apidocs/man/man3/MAPISTORE_ERR_CONTEXT_FAILED.3000066400000000000000000000000361223057412600230650ustar00rootroot00000000000000.so man3/mapistore_errors.h.3 openchange-2.0/apidocs/man/man3/MAPISTORE_ERR_CORRUPTED.3000066400000000000000000000000361223057412600223040ustar00rootroot00000000000000.so man3/mapistore_errors.h.3 openchange-2.0/apidocs/man/man3/MAPISTORE_ERR_DATABASE_INIT.3000066400000000000000000000000361223057412600227240ustar00rootroot00000000000000.so man3/mapistore_errors.h.3 openchange-2.0/apidocs/man/man3/MAPISTORE_ERR_DATABASE_OPS.3000066400000000000000000000000361223057412600226220ustar00rootroot00000000000000.so man3/mapistore_errors.h.3 openchange-2.0/apidocs/man/man3/MAPISTORE_ERR_DENIED.3000066400000000000000000000000361223057412600216650ustar00rootroot00000000000000.so man3/mapistore_errors.h.3 openchange-2.0/apidocs/man/man3/MAPISTORE_ERR_EXIST.3000066400000000000000000000000361223057412600216310ustar00rootroot00000000000000.so man3/mapistore_errors.h.3 openchange-2.0/apidocs/man/man3/MAPISTORE_ERR_INVALID_DATA.3000066400000000000000000000000361223057412600226140ustar00rootroot00000000000000.so man3/mapistore_errors.h.3 openchange-2.0/apidocs/man/man3/MAPISTORE_ERR_INVALID_NAMESPACE.3000066400000000000000000000000361223057412600233770ustar00rootroot00000000000000.so man3/mapistore_errors.h.3 openchange-2.0/apidocs/man/man3/MAPISTORE_ERR_INVALID_PARAMETER.3000066400000000000000000000000361223057412600234230ustar00rootroot00000000000000.so man3/mapistore_errors.h.3 openchange-2.0/apidocs/man/man3/MAPISTORE_ERR_MSG_RCV.3000066400000000000000000000000361223057412600220750ustar00rootroot00000000000000.so man3/mapistore_errors.h.3 openchange-2.0/apidocs/man/man3/MAPISTORE_ERR_MSG_SEND.3000066400000000000000000000000361223057412600221740ustar00rootroot00000000000000.so man3/mapistore_errors.h.3 openchange-2.0/apidocs/man/man3/MAPISTORE_ERR_NOT_FOUND.3000066400000000000000000000000361223057412600223300ustar00rootroot00000000000000.so man3/mapistore_errors.h.3 openchange-2.0/apidocs/man/man3/MAPISTORE_ERR_NOT_IMPLEMENTED.3000066400000000000000000000000361223057412600232200ustar00rootroot00000000000000.so man3/mapistore_errors.h.3 openchange-2.0/apidocs/man/man3/MAPISTORE_ERR_NOT_INITIALIZED.3000066400000000000000000000000361223057412600232220ustar00rootroot00000000000000.so man3/mapistore_errors.h.3 openchange-2.0/apidocs/man/man3/MAPISTORE_ERR_NO_DIRECTORY.3000066400000000000000000000000361223057412600226750ustar00rootroot00000000000000.so man3/mapistore_errors.h.3 openchange-2.0/apidocs/man/man3/MAPISTORE_ERR_NO_MEMORY.3000066400000000000000000000000361223057412600223410ustar00rootroot00000000000000.so man3/mapistore_errors.h.3 openchange-2.0/apidocs/man/man3/MAPISTORE_ERR_REF_COUNT.3000066400000000000000000000000361223057412600223210ustar00rootroot00000000000000.so man3/mapistore_errors.h.3 openchange-2.0/apidocs/man/man3/MAPISTORE_SUCCESS.3000066400000000000000000000000361223057412600213350ustar00rootroot00000000000000.so man3/mapistore_errors.h.3 openchange-2.0/apidocs/man/man3/MAPIUninitialize.3000066400000000000000000000000261223057412600217140ustar00rootroot00000000000000.so man3/cdo_mapi.c.3 openchange-2.0/apidocs/man/man3/MapiLogonEx.3000066400000000000000000000000261223057412600207630ustar00rootroot00000000000000.so man3/cdo_mapi.c.3 openchange-2.0/apidocs/man/man3/MapiLogonProvider.3000066400000000000000000000000261223057412600222010ustar00rootroot00000000000000.so man3/cdo_mapi.c.3 openchange-2.0/apidocs/man/man3/ModifyPermissions.3000066400000000000000000000000341223057412600222630ustar00rootroot00000000000000.so man3/IMAPIContainer.c.3 openchange-2.0/apidocs/man/man3/ModifyRecipients.3000066400000000000000000000000261223057412600220560ustar00rootroot00000000000000.so man3/IMessage.c.3 openchange-2.0/apidocs/man/man3/ModifyUserPermission.3000066400000000000000000000000311223057412600227340ustar00rootroot00000000000000.so man3/simple_mapi.c.3 openchange-2.0/apidocs/man/man3/MonitorNotification.3000066400000000000000000000000321223057412600225740ustar00rootroot00000000000000.so man3/IMAPISupport.c.3 openchange-2.0/apidocs/man/man3/MoveCopyMessages.3000066400000000000000000000000311223057412600220260ustar00rootroot00000000000000.so man3/IMAPIFolder.c.3 openchange-2.0/apidocs/man/man3/MoveFolder.3000066400000000000000000000000311223057412600206370ustar00rootroot00000000000000.so man3/IMAPIFolder.c.3 openchange-2.0/apidocs/man/man3/OpenAttach.3000066400000000000000000000000261223057412600206270ustar00rootroot00000000000000.so man3/IMessage.c.3 openchange-2.0/apidocs/man/man3/OpenEmbeddedMessage.3000066400000000000000000000000261223057412600224210ustar00rootroot00000000000000.so man3/IMessage.c.3 openchange-2.0/apidocs/man/man3/OpenFolder.3000066400000000000000000000000271223057412600206370ustar00rootroot00000000000000.so man3/IMsgStore.c.3 openchange-2.0/apidocs/man/man3/OpenMessage.3000066400000000000000000000000321223057412600210040ustar00rootroot00000000000000.so man3/IStoreFolder.c.3 openchange-2.0/apidocs/man/man3/OpenMsgStore.3000066400000000000000000000000321223057412600211630ustar00rootroot00000000000000.so man3/IMAPISession.c.3 openchange-2.0/apidocs/man/man3/OpenProfile.3000066400000000000000000000000301223057412600210160ustar00rootroot00000000000000.so man3/IProfAdmin.c.3 openchange-2.0/apidocs/man/man3/OpenPublicFolder.3000066400000000000000000000000321223057412600217720ustar00rootroot00000000000000.so man3/IMAPISession.c.3 openchange-2.0/apidocs/man/man3/OpenPublicFolderByName.3000066400000000000000000000000271223057412600230720ustar00rootroot00000000000000.so man3/IMsgStore.c.3 openchange-2.0/apidocs/man/man3/OpenStream.3000066400000000000000000000000251223057412600206550ustar00rootroot00000000000000.so man3/IStream.c.3 openchange-2.0/apidocs/man/man3/OpenUserMailbox.3000066400000000000000000000000321223057412600216520ustar00rootroot00000000000000.so man3/IMAPISession.c.3 openchange-2.0/apidocs/man/man3/OptionsData.3000066400000000000000000000000261223057412600210260ustar00rootroot00000000000000.so man3/IXPLogon.c.3 openchange-2.0/apidocs/man/man3/PermanentEntryID.3000066400000000000000000000006141223057412600217740ustar00rootroot00000000000000.TH "PermanentEntryID" 3 "Thu Jan 24 2013" "Version 2.0" "MAPIProxy" \" -*- nroff -*- .ad l .nh .SH NAME PermanentEntryID \- .PP \fBPermanentEntryID\fP structure\&. .SH SYNOPSIS .br .PP .PP \fC#include \fP .SH "Detailed Description" .PP \fBPermanentEntryID\fP structure\&. .SH "Author" .PP Generated automatically by Doxygen for MAPIProxy from the source code\&. openchange-2.0/apidocs/man/man3/ProcessNetworkProfile.3000066400000000000000000000000301223057412600231050ustar00rootroot00000000000000.so man3/IProfAdmin.c.3 openchange-2.0/apidocs/man/man3/PropertyRowSet_propcpy.3000066400000000000000000000000261223057412600233450ustar00rootroot00000000000000.so man3/property.c.3 openchange-2.0/apidocs/man/man3/PropertyRow_addprop.3000066400000000000000000000000261223057412600226260ustar00rootroot00000000000000.so man3/property.c.3 openchange-2.0/apidocs/man/man3/PublicFolderIsGhosted.3000066400000000000000000000000271223057412600227660ustar00rootroot00000000000000.so man3/IMsgStore.c.3 openchange-2.0/apidocs/man/man3/QueryColumns.3000066400000000000000000000000301223057412600212420ustar00rootroot00000000000000.so man3/IMAPITable.c.3 openchange-2.0/apidocs/man/man3/QueryNamedProperties.3000066400000000000000000000000271223057412600227310ustar00rootroot00000000000000.so man3/IMAPIProp.c.3 openchange-2.0/apidocs/man/man3/QueryPosition.3000066400000000000000000000000301223057412600214260ustar00rootroot00000000000000.so man3/IMAPITable.c.3 openchange-2.0/apidocs/man/man3/QueryRows.3000066400000000000000000000000301223057412600205540ustar00rootroot00000000000000.so man3/IMAPITable.c.3 openchange-2.0/apidocs/man/man3/ReadRecipients.3000066400000000000000000000000261223057412600215020ustar00rootroot00000000000000.so man3/IMessage.c.3 openchange-2.0/apidocs/man/man3/ReadStream.3000066400000000000000000000000251223057412600206270ustar00rootroot00000000000000.so man3/IStream.c.3 openchange-2.0/apidocs/man/man3/RegisterAsyncNotification.3000066400000000000000000000000311223057412600237260ustar00rootroot00000000000000.so man3/IMSProvider.c.3 openchange-2.0/apidocs/man/man3/RegisterNotification.3000066400000000000000000000000311223057412600227300ustar00rootroot00000000000000.so man3/IMSProvider.c.3 openchange-2.0/apidocs/man/man3/Release.3000066400000000000000000000000261223057412600201610ustar00rootroot00000000000000.so man3/IUnknown.c.3 openchange-2.0/apidocs/man/man3/ReloadCachedInformation.3000066400000000000000000000000321223057412600233020ustar00rootroot00000000000000.so man3/IStoreFolder.c.3 openchange-2.0/apidocs/man/man3/RemoveAllRecipients.3000066400000000000000000000000261223057412600225150ustar00rootroot00000000000000.so man3/IMessage.c.3 openchange-2.0/apidocs/man/man3/RemoveUserPermission.3000066400000000000000000000000311223057412600227420ustar00rootroot00000000000000.so man3/simple_mapi.c.3 openchange-2.0/apidocs/man/man3/RenameProfile.3000066400000000000000000000000301223057412600213240ustar00rootroot00000000000000.so man3/IProfAdmin.c.3 openchange-2.0/apidocs/man/man3/Reset.3000066400000000000000000000000301223057412600176560ustar00rootroot00000000000000.so man3/IMAPITable.c.3 openchange-2.0/apidocs/man/man3/ResolveNames.3000066400000000000000000000000321223057412600212010ustar00rootroot00000000000000.so man3/IABContainer.c.3 openchange-2.0/apidocs/man/man3/Restrict.3000066400000000000000000000000301223057412600203730ustar00rootroot00000000000000.so man3/IMAPITable.c.3 openchange-2.0/apidocs/man/man3/RfrGetFQDNFromLegacyDN.3000066400000000000000000000000311223057412600226320ustar00rootroot00000000000000.so man3/IMSProvider.c.3 openchange-2.0/apidocs/man/man3/RfrGetNewDSA.3000066400000000000000000000000311223057412600207700ustar00rootroot00000000000000.so man3/IMSProvider.c.3 openchange-2.0/apidocs/man/man3/RopGetReceiveFolder.3000066400000000000000000000000251223057412600224370ustar00rootroot00000000000000.so man3/oxcstor.c.3 openchange-2.0/apidocs/man/man3/RopLogon_Mailbox.3000066400000000000000000000000251223057412600220120ustar00rootroot00000000000000.so man3/oxcstor.c.3 openchange-2.0/apidocs/man/man3/RopLogon_PublicFolder.3000066400000000000000000000000251223057412600227710ustar00rootroot00000000000000.so man3/oxcstor.c.3 openchange-2.0/apidocs/man/man3/RopSetReceiveFolder.3000066400000000000000000000000251223057412600224530ustar00rootroot00000000000000.so man3/oxcstor.c.3 openchange-2.0/apidocs/man/man3/SPropTagArray_add.3000066400000000000000000000000261223057412600221070ustar00rootroot00000000000000.so man3/property.c.3 openchange-2.0/apidocs/man/man3/SPropTagArray_delete.3000066400000000000000000000000261223057412600226210ustar00rootroot00000000000000.so man3/property.c.3 openchange-2.0/apidocs/man/man3/SPropTagArray_find.3000066400000000000000000000000261223057412600222770ustar00rootroot00000000000000.so man3/property.c.3 openchange-2.0/apidocs/man/man3/SRowSet_propcpy.3000066400000000000000000000000261223057412600217230ustar00rootroot00000000000000.so man3/property.c.3 openchange-2.0/apidocs/man/man3/SRow_addprop.3000066400000000000000000000000261223057412600212040ustar00rootroot00000000000000.so man3/property.c.3 openchange-2.0/apidocs/man/man3/SaveChangesAttachment.3000066400000000000000000000000271223057412600230020ustar00rootroot00000000000000.so man3/IMAPIProp.c.3 openchange-2.0/apidocs/man/man3/SaveChangesMessage.3000066400000000000000000000000261223057412600222750ustar00rootroot00000000000000.so man3/IMessage.c.3 openchange-2.0/apidocs/man/man3/SeekRow.3000066400000000000000000000000301223057412600201530ustar00rootroot00000000000000.so man3/IMAPITable.c.3 openchange-2.0/apidocs/man/man3/SeekRowApprox.3000066400000000000000000000000301223057412600213450ustar00rootroot00000000000000.so man3/IMAPITable.c.3 openchange-2.0/apidocs/man/man3/SeekRowBookmark.3000066400000000000000000000000301223057412600216410ustar00rootroot00000000000000.so man3/IMAPITable.c.3 openchange-2.0/apidocs/man/man3/SeekStream.3000066400000000000000000000000251223057412600206430ustar00rootroot00000000000000.so man3/IStream.c.3 openchange-2.0/apidocs/man/man3/SetCollapseState.3000066400000000000000000000000301223057412600220130ustar00rootroot00000000000000.so man3/IMAPITable.c.3 openchange-2.0/apidocs/man/man3/SetColumns.3000066400000000000000000000000301223057412600206700ustar00rootroot00000000000000.so man3/IMAPITable.c.3 openchange-2.0/apidocs/man/man3/SetDefaultProfile.3000066400000000000000000000000301223057412600221550ustar00rootroot00000000000000.so man3/IProfAdmin.c.3 openchange-2.0/apidocs/man/man3/SetLocalReplicaMidsetDeleted.3000066400000000000000000000000231223057412600242410ustar00rootroot00000000000000.so man3/FXICS.c.3 openchange-2.0/apidocs/man/man3/SetMAPIDebugLevel.3000066400000000000000000000000261223057412600217420ustar00rootroot00000000000000.so man3/cdo_mapi.c.3 openchange-2.0/apidocs/man/man3/SetMAPIDumpData.3000066400000000000000000000000261223057412600214230ustar00rootroot00000000000000.so man3/cdo_mapi.c.3 openchange-2.0/apidocs/man/man3/SetMessageReadFlag.3000066400000000000000000000000261223057412600222270ustar00rootroot00000000000000.so man3/IMessage.c.3 openchange-2.0/apidocs/man/man3/SetMessageStatus.3000066400000000000000000000000311223057412600220410ustar00rootroot00000000000000.so man3/IMAPIFolder.c.3 openchange-2.0/apidocs/man/man3/SetPropertiesNoReplicate.3000066400000000000000000000000271223057412600235400ustar00rootroot00000000000000.so man3/IMAPIProp.c.3 openchange-2.0/apidocs/man/man3/SetProps.3000066400000000000000000000000271223057412600203610ustar00rootroot00000000000000.so man3/IMAPIProp.c.3 openchange-2.0/apidocs/man/man3/SetReadFlags.3000066400000000000000000000000311223057412600211010ustar00rootroot00000000000000.so man3/IMAPIFolder.c.3 openchange-2.0/apidocs/man/man3/SetReceiveFolder.3000066400000000000000000000000271223057412600217740ustar00rootroot00000000000000.so man3/IMsgStore.c.3 openchange-2.0/apidocs/man/man3/SetRecipientType.3000066400000000000000000000000261223057412600220410ustar00rootroot00000000000000.so man3/IMessage.c.3 openchange-2.0/apidocs/man/man3/SetSearchCriteria.3000066400000000000000000000000341223057412600221440ustar00rootroot00000000000000.so man3/IMAPIContainer.c.3 openchange-2.0/apidocs/man/man3/SetSpooler.3000066400000000000000000000000261223057412600207000ustar00rootroot00000000000000.so man3/IXPLogon.c.3 openchange-2.0/apidocs/man/man3/SetStreamSize.3000066400000000000000000000000251223057412600213420ustar00rootroot00000000000000.so man3/IStream.c.3 openchange-2.0/apidocs/man/man3/SetSyncNotificationGuid.3000066400000000000000000000000231223057412600233460ustar00rootroot00000000000000.so man3/notif.c.3 openchange-2.0/apidocs/man/man3/ShutDown.3000066400000000000000000000000301223057412600203470ustar00rootroot00000000000000.so man3/IProfAdmin.c.3 openchange-2.0/apidocs/man/man3/SortTable.3000066400000000000000000000000301223057412600204730ustar00rootroot00000000000000.so man3/IMAPITable.c.3 openchange-2.0/apidocs/man/man3/SpoolerLockMessage.3000066400000000000000000000000261223057412600223420ustar00rootroot00000000000000.so man3/IXPLogon.c.3 openchange-2.0/apidocs/man/man3/SubmitMessage.3000066400000000000000000000000261223057412600213510ustar00rootroot00000000000000.so man3/IMessage.c.3 openchange-2.0/apidocs/man/man3/Subscribe.3000066400000000000000000000000321223057412600205170ustar00rootroot00000000000000.so man3/IMAPISupport.c.3 openchange-2.0/apidocs/man/man3/SyncOpenAdvisor.3000066400000000000000000000000231223057412600216640ustar00rootroot00000000000000.so man3/notif.c.3 openchange-2.0/apidocs/man/man3/TellVersion.3000066400000000000000000000000231223057412600210440ustar00rootroot00000000000000.so man3/FXICS.c.3 openchange-2.0/apidocs/man/man3/TransportNewMail.3000066400000000000000000000000271223057412600220530ustar00rootroot00000000000000.so man3/IMsgStore.c.3 openchange-2.0/apidocs/man/man3/TransportSend.3000066400000000000000000000000261223057412600214070ustar00rootroot00000000000000.so man3/IMessage.c.3 openchange-2.0/apidocs/man/man3/UnlockRegionStream.3000066400000000000000000000000251223057412600223530ustar00rootroot00000000000000.so man3/IStream.c.3 openchange-2.0/apidocs/man/man3/Unsubscribe.3000066400000000000000000000000321223057412600210620ustar00rootroot00000000000000.so man3/IMAPISupport.c.3 openchange-2.0/apidocs/man/man3/WrapCompressedRTFStream.3000066400000000000000000000000221223057412600232630ustar00rootroot00000000000000.so man3/lzfu.c.3 openchange-2.0/apidocs/man/man3/WriteAndCommitStream.3000066400000000000000000000000251223057412600226420ustar00rootroot00000000000000.so man3/IStream.c.3 openchange-2.0/apidocs/man/man3/WriteStream.3000066400000000000000000000000251223057412600210460ustar00rootroot00000000000000.so man3/IStream.c.3 openchange-2.0/apidocs/man/man3/_tmp_openchange-2.0-QUADRANT_doc_.3000066400000000000000000000003721223057412600244310ustar00rootroot00000000000000.TH "doc/ Directory Reference" 3 "Thu Jan 24 2013" "Version 2.0" "MAPIClientLibraries" \" -*- nroff -*- .ad l .nh .SH NAME doc/ Directory Reference \- .SH SYNOPSIS .br .PP .SS "Directories" .in +1c .ti -1c .RI "directory \fBdoxygen\fP" .br .in -1c openchange-2.0/apidocs/man/man3/_tmp_openchange-2.0-QUADRANT_doc_doxygen_.3000066400000000000000000000005711223057412600261670ustar00rootroot00000000000000.TH "doc/doxygen/ Directory Reference" 3 "Thu Jan 24 2013" "Version 2.0" "MAPIClientLibraries" \" -*- nroff -*- .ad l .nh .SH NAME doc/doxygen/ Directory Reference \- .SH SYNOPSIS .br .PP .SS "Files" .in +1c .ti -1c .RI "file \fBlibmapi-concepts\&.doxy\fP" .br .ti -1c .RI "file \fBlibmapi-examples\&.doxy\fP" .br .ti -1c .RI "file \fBlibmapi-mainpage\&.doxy\fP" .br .in -1c openchange-2.0/apidocs/man/man3/_tmp_openchange-2.0-QUADRANT_libmapi_.3000066400000000000000000000101261223057412600252770ustar00rootroot00000000000000.TH "libmapi/ Directory Reference" 3 "Thu Jan 24 2013" "Version 2.0" "MAPIClientLibraries" \" -*- nroff -*- .ad l .nh .SH NAME libmapi/ Directory Reference \- .SH SYNOPSIS .br .PP .SS "Files" .in +1c .ti -1c .RI "file \fBasync_emsmdb\&.c\fP" .br .RI "\fIAsync_EMSMDB stack functions\&. \fP" .ti -1c .RI "file \fBcdo_mapi\&.c\fP" .br .RI "\fIMAPI subsystem related operations\&. \fP" .ti -1c .RI "file \fBcodepage_lcid\&.c\fP" .br .RI "\fICodepage and Locale ID operations\&. \fP" .ti -1c .RI "file \fBemsmdb\&.c\fP" .br .RI "\fIEMSMDB stack functions\&. \fP" .ti -1c .RI "file \fBemsmdb\&.h\fP" .br .ti -1c .RI "file \fBfreebusy\&.c\fP" .br .RI "\fIConvenient API to access FreeBusy\&. \fP" .ti -1c .RI "file \fBFXICS\&.c\fP" .br .RI "\fIFast Transfer and Incremental Change Synchronization operations\&. \fP" .ti -1c .RI "file \fBfxparser\&.c\fP" .br .RI "\fIFast Transfer stream parser\&. \fP" .ti -1c .RI "file \fBfxparser\&.h\fP" .br .ti -1c .RI "file \fBIABContainer\&.c\fP" .br .RI "\fIProvides access to address book containers -- Used to perform name resolution\&. \fP" .ti -1c .RI "file \fBidset\&.c\fP" .br .RI "\fIParsing of GLOBSET structures\&. \fP" .ti -1c .RI "file \fBidset\&.h\fP" .br .ti -1c .RI "file \fBIMAPIContainer\&.c\fP" .br .RI "\fIContainers and tables related operations\&. \fP" .ti -1c .RI "file \fBIMAPIFolder\&.c\fP" .br .RI "\fIFolder related functions\&. \fP" .ti -1c .RI "file \fBIMAPIProp\&.c\fP" .br .RI "\fIProperties and named properties operations\&. \fP" .ti -1c .RI "file \fBIMAPISession\&.c\fP" .br .RI "\fISession initialization options\&. \fP" .ti -1c .RI "file \fBIMAPISupport\&.c\fP" .br .RI "\fIMAPI notifications functions\&. \fP" .ti -1c .RI "file \fBIMAPITable\&.c\fP" .br .RI "\fIOperations on tables\&. \fP" .ti -1c .RI "file \fBIMessage\&.c\fP" .br .RI "\fIOperations on messages\&. \fP" .ti -1c .RI "file \fBIMsgStore\&.c\fP" .br .RI "\fIFolders related operations\&. \fP" .ti -1c .RI "file \fBIMSProvider\&.c\fP" .br .RI "\fIProvider operations\&. \fP" .ti -1c .RI "file \fBIProfAdmin\&.c\fP" .br .RI "\fIMAPI Profiles interface\&. \fP" .ti -1c .RI "file \fBIStoreFolder\&.c\fP" .br .RI "\fIOpen messages\&. \fP" .ti -1c .RI "file \fBIStream\&.c\fP" .br .RI "\fIFunctions for operating on Streams on MAPI objects\&. \fP" .ti -1c .RI "file \fBIUnknown\&.c\fP" .br .RI "\fIVarious miscellaneous (ungrouped) functions\&. \fP" .ti -1c .RI "file \fBIXPLogon\&.c\fP" .br .RI "\fITransport provider status information\&. \fP" .ti -1c .RI "file \fBlibmapi\&.h\fP" .br .ti -1c .RI "file \fBlzfu\&.c\fP" .br .RI "\fICompressed RTF related functions\&. \fP" .ti -1c .RI "file \fBmapi_context\&.h\fP" .br .ti -1c .RI "file \fBmapi_id_array\&.c\fP" .br .RI "\fImapi_id_array support functions \fP" .ti -1c .RI "file \fBmapi_id_array\&.h\fP" .br .ti -1c .RI "file \fBmapi_nameid\&.c\fP" .br .RI "\fImapi_nameid convenience API \fP" .ti -1c .RI "file \fBmapi_nameid\&.h\fP" .br .ti -1c .RI "file \fBmapi_notification\&.h\fP" .br .ti -1c .RI "file \fBmapi_object\&.c\fP" .br .RI "\fImapi_object_t support functions \fP" .ti -1c .RI "file \fBmapi_object\&.h\fP" .br .ti -1c .RI "file \fBmapi_profile\&.h\fP" .br .ti -1c .RI "file \fBmapi_provider\&.h\fP" .br .ti -1c .RI "file \fBmapicode\&.c\fP" .br .ti -1c .RI "file \fBmapicode\&.h\fP" .br .ti -1c .RI "file \fBmapidefs\&.h\fP" .br .ti -1c .RI "file \fBmapidump\&.c\fP" .br .RI "\fIFunctions for displaying various data structures, mainly for debugging\&. \fP" .ti -1c .RI "file \fBmapidump\&.h\fP" .br .ti -1c .RI "file \fBnotif\&.c\fP" .br .RI "\fINotification (MS-OXCNOTIF) operations\&. \fP" .ti -1c .RI "file \fBnspi\&.c\fP" .br .RI "\fIName Service Provider (NSPI) stack functions\&. \fP" .ti -1c .RI "file \fBnspi\&.h\fP" .br .ti -1c .RI "file \fBproperty\&.c\fP" .br .RI "\fIFunctions for manipulating MAPI properties\&. \fP" .ti -1c .RI "file \fBproperty_altnames\&.h\fP" .br .ti -1c .RI "file \fBproperty_tags\&.c\fP" .br .ti -1c .RI "file \fBproperty_tags\&.h\fP" .br .ti -1c .RI "file \fBsimple_mapi\&.c\fP" .br .RI "\fIConvenience functions\&. \fP" .ti -1c .RI "file \fButils\&.c\fP" .br .RI "\fIGeneral utility functions\&. \fP" .ti -1c .RI "file \fBx500\&.c\fP" .br .in -1c openchange-2.0/apidocs/man/man3/_tmp_openchange-2.0-QUADRANT_libmapiadmin_.3000066400000000000000000000010711223057412600263070ustar00rootroot00000000000000.TH "libmapiadmin/ Directory Reference" 3 "Thu Jan 24 2013" "Version 2.0" "libmapiadmin" \" -*- nroff -*- .ad l .nh .SH NAME libmapiadmin/ Directory Reference \- .SH SYNOPSIS .br .PP .SS "Files" .in +1c .ti -1c .RI "file \fBlibmapiadmin-mainpage\&.doxy\fP" .br .ti -1c .RI "file \fBlibmapiadmin\&.h\fP" .br .RI "\fIStructures for MAPI admin functions\&. \fP" .ti -1c .RI "file \fBmapiadmin\&.c\fP" .br .RI "\fIHousekeeping functions for mapiadmin\&. \fP" .ti -1c .RI "file \fBmapiadmin_user\&.c\fP" .br .RI "\fIUser management functions for mapiadmin\&. \fP" .in -1c openchange-2.0/apidocs/man/man3/_tmp_openchange-2.0-QUADRANT_libocpf_.3000066400000000000000000000015501223057412600253010ustar00rootroot00000000000000.TH "libocpf/ Directory Reference" 3 "Thu Jan 24 2013" "Version 2.0" "OpenChange Property Files" \" -*- nroff -*- .ad l .nh .SH NAME libocpf/ Directory Reference \- .SH SYNOPSIS .br .PP .SS "Files" .in +1c .ti -1c .RI "file \fBlex\&.h\fP" .br .ti -1c .RI "file \fBocpf-documentation\&.doxy\fP" .br .ti -1c .RI "file \fBocpf\&.h\fP" .br .ti -1c .RI "file \fBocpf\&.tab\&.c\fP" .br .ti -1c .RI "file \fBocpf\&.tab\&.h\fP" .br .ti -1c .RI "file \fBocpf_context\&.c\fP" .br .RI "\fIOCPF context API\&. \fP" .ti -1c .RI "file \fBocpf_dump\&.c\fP" .br .RI "\fIocpf Dump API \fP" .ti -1c .RI "file \fBocpf_dump\&.h\fP" .br .ti -1c .RI "file \fBocpf_public\&.c\fP" .br .RI "\fIpublic OCPF API \fP" .ti -1c .RI "file \fBocpf_server\&.c\fP" .br .RI "\fIocpf public API for server side\&. \fP" .ti -1c .RI "file \fBocpf_write\&.c\fP" .br .RI "\fIpublic OCPF write API \fP" .in -1c openchange-2.0/apidocs/man/man3/_tmp_openchange-2.0-QUADRANT_mapiproxy_.3000066400000000000000000000004241223057412600257120ustar00rootroot00000000000000.TH "mapiproxy/ Directory Reference" 3 "Thu Jan 24 2013" "Version 2.0" "OpenChange mapistore library" \" -*- nroff -*- .ad l .nh .SH NAME mapiproxy/ Directory Reference \- .SH SYNOPSIS .br .PP .SS "Directories" .in +1c .ti -1c .RI "directory \fBlibmapistore\fP" .br .in -1c openchange-2.0/apidocs/man/man3/_tmp_openchange-2.0-QUADRANT_mapiproxy_documentation_.3000066400000000000000000000006151223057412600306450ustar00rootroot00000000000000.TH "mapiproxy/documentation/ Directory Reference" 3 "Thu Jan 24 2013" "Version 2.0" "MAPIProxy" \" -*- nroff -*- .ad l .nh .SH NAME mapiproxy/documentation/ Directory Reference \- .SH SYNOPSIS .br .PP .SS "Files" .in +1c .ti -1c .RI "file \fBMainpage\&.doxy\fP" .br .ti -1c .RI "file \fBmapiproxy-documentation\&.doxy\fP" .br .ti -1c .RI "file \fBmapistore-documentation\&.doxy\fP" .br .in -1c openchange-2.0/apidocs/man/man3/_tmp_openchange-2.0-QUADRANT_mapiproxy_libmapiproxy_.3000066400000000000000000000022531223057412600305130ustar00rootroot00000000000000.TH "mapiproxy/libmapiproxy/ Directory Reference" 3 "Thu Jan 24 2013" "Version 2.0" "MAPIProxy" \" -*- nroff -*- .ad l .nh .SH NAME mapiproxy/libmapiproxy/ Directory Reference \- .SH SYNOPSIS .br .PP .SS "Files" .in +1c .ti -1c .RI "file \fBdcesrv_mapiproxy_module\&.c\fP" .br .RI "\fImapiproxy modules management \fP" .ti -1c .RI "file \fBdcesrv_mapiproxy_server\&.c\fP" .br .RI "\fImapiproxy server modules management \fP" .ti -1c .RI "file \fBdcesrv_mapiproxy_session\&.c\fP" .br .RI "\fIsession API for mapiproxy modules \fP" .ti -1c .RI "file \fBentryid\&.c\fP" .br .RI "\fIEntryID convenient routines\&. \fP" .ti -1c .RI "file \fBlibmapiproxy\&.h\fP" .br .ti -1c .RI "file \fBmapi_handles\&.c\fP" .br .RI "\fIAPI for MAPI handles management\&. \fP" .ti -1c .RI "file \fBmodules\&.c\fP" .br .ti -1c .RI "file \fBopenchangedb\&.c\fP" .br .RI "\fIOpenChange Dispatcher database routines\&. \fP" .ti -1c .RI "file \fBopenchangedb_message\&.c\fP" .br .RI "\fIOpenChange Dispatcher database message routines\&. \fP" .ti -1c .RI "file \fBopenchangedb_property\&.c\fP" .br .ti -1c .RI "file \fBopenchangedb_table\&.c\fP" .br .RI "\fIOpenChange Dispatcher database table routines\&. \fP" .in -1c openchange-2.0/apidocs/man/man3/_tmp_openchange-2.0-QUADRANT_mapiproxy_libmapiserver_.3000066400000000000000000000026131223057412600306400ustar00rootroot00000000000000.TH "mapiproxy/libmapiserver/ Directory Reference" 3 "Thu Jan 24 2013" "Version 2.0" "MAPIProxy" \" -*- nroff -*- .ad l .nh .SH NAME mapiproxy/libmapiserver/ Directory Reference \- .SH SYNOPSIS .br .PP .SS "Files" .in +1c .ti -1c .RI "file \fBlibmapiserver\&.h\fP" .br .ti -1c .RI "file \fBlibmapiserver_oxcdata\&.c\fP" .br .RI "\fIOXCDATA Data Structures\&. \fP" .ti -1c .RI "file \fBlibmapiserver_oxcfold\&.c\fP" .br .RI "\fIOXCFOLD ROP Response size calculations\&. \fP" .ti -1c .RI "file \fBlibmapiserver_oxcfxics\&.c\fP" .br .RI "\fIOXCFXICS ROP Response size calculations\&. \fP" .ti -1c .RI "file \fBlibmapiserver_oxcmsg\&.c\fP" .br .RI "\fIOXCMSG ROP Response size calculations\&. \fP" .ti -1c .RI "file \fBlibmapiserver_oxcnotif\&.c\fP" .br .RI "\fIOXCNOTIF ROP Response size calculations\&. \fP" .ti -1c .RI "file \fBlibmapiserver_oxcperm\&.c\fP" .br .ti -1c .RI "file \fBlibmapiserver_oxcprpt\&.c\fP" .br .RI "\fIOXCPRPT ROP Response size calculations\&. \fP" .ti -1c .RI "file \fBlibmapiserver_oxcstor\&.c\fP" .br .RI "\fIOXCSTOR ROP Response size calculations\&. \fP" .ti -1c .RI "file \fBlibmapiserver_oxctabl\&.c\fP" .br .RI "\fIOXCTABL ROP Response size calculations\&. \fP" .ti -1c .RI "file \fBlibmapiserver_oxomsg\&.c\fP" .br .RI "\fIOXOMSG ROP Response size calculations\&. \fP" .ti -1c .RI "file \fBlibmapiserver_oxorule\&.c\fP" .br .RI "\fIOXORULE ROP Response size calculations\&. \fP" .in -1c openchange-2.0/apidocs/man/man3/_tmp_openchange-2.0-QUADRANT_mapiproxy_libmapistore_.3000066400000000000000000000024151223057412600304660ustar00rootroot00000000000000.TH "mapiproxy/libmapistore/ Directory Reference" 3 "Thu Jan 24 2013" "Version 2.0" "OpenChange mapistore library" \" -*- nroff -*- .ad l .nh .SH NAME mapiproxy/libmapistore/ Directory Reference \- .SH SYNOPSIS .br .PP .SS "Directories" .in +1c .ti -1c .RI "directory \fBmgmt\fP" .br .ti -1c .RI "directory \fBtests\fP" .br .in -1c .SS "Files" .in +1c .ti -1c .RI "file \fBmapistore\&.h\fP" .br .RI "\fIMAPISTORE general API\&. \fP" .ti -1c .RI "file \fBmapistore_backend\&.c\fP" .br .RI "\fImapistore backends management API \fP" .ti -1c .RI "file \fBmapistore_backend_defaults\&.c\fP" .br .RI "\fIInitialize default behavior for mapistore backends\&. \fP" .ti -1c .RI "file \fBmapistore_errors\&.h\fP" .br .RI "\fIThis header provides a set of result codes for MAPISTORE function calls\&. \fP" .ti -1c .RI "file \fBmapistore_indexing\&.c\fP" .br .RI "\fIMAPISTORE internal indexing functions\&. \fP" .ti -1c .RI "file \fBmapistore_interface\&.c\fP" .br .ti -1c .RI "file \fBmapistore_ldb_wrap\&.c\fP" .br .ti -1c .RI "file \fBmapistore_namedprops\&.c\fP" .br .ti -1c .RI "file \fBmapistore_notification\&.c\fP" .br .ti -1c .RI "file \fBmapistore_processing\&.c\fP" .br .ti -1c .RI "file \fBmapistore_replica_mapping\&.c\fP" .br .ti -1c .RI "file \fBmapistore_tdb_wrap\&.c\fP" .br .in -1c openchange-2.0/apidocs/man/man3/_tmp_openchange-2.0-QUADRANT_mapiproxy_libmapistore_mgmt_.3000066400000000000000000000014221223057412600315070ustar00rootroot00000000000000.TH "mapiproxy/libmapistore/mgmt/ Directory Reference" 3 "Thu Jan 24 2013" "Version 2.0" "OpenChange mapistore library" \" -*- nroff -*- .ad l .nh .SH NAME mapiproxy/libmapistore/mgmt/ Directory Reference \- .SH SYNOPSIS .br .PP .SS "Files" .in +1c .ti -1c .RI "file \fBmapistore_mgmt\&.c\fP" .br .RI "\fIProvides mapistore management routine for administrative/services tools\&. \fP" .ti -1c .RI "file \fBmapistore_mgmt\&.h\fP" .br .ti -1c .RI "file \fBmapistore_mgmt_messages\&.c\fP" .br .RI "\fIProcess IPC messages received on command message queue\&. \fP" .ti -1c .RI "file \fBmapistore_mgmt_send\&.c\fP" .br .RI "\fIProvides mapistore management routine for sending messages/notifications from administrative/services tools to OpenChange Server/listener process\&. \fP" .in -1c openchange-2.0/apidocs/man/man3/_tmp_openchange-2.0-QUADRANT_mapiproxy_libmapistore_tests_.3000066400000000000000000000005431223057412600317100ustar00rootroot00000000000000.TH "mapiproxy/libmapistore/tests/ Directory Reference" 3 "Thu Jan 24 2013" "Version 2.0" "OpenChange mapistore library" \" -*- nroff -*- .ad l .nh .SH NAME mapiproxy/libmapistore/tests/ Directory Reference \- .SH SYNOPSIS .br .PP .SS "Files" .in +1c .ti -1c .RI "file \fBmapistore_test\&.c\fP" .br .RI "\fITest mapistore implementation\&. \fP" .in -1c openchange-2.0/apidocs/man/man3/_tmp_openchange-2.0-QUADRANT_mapiproxy_modules_.3000066400000000000000000000015371223057412600274500ustar00rootroot00000000000000.TH "mapiproxy/modules/ Directory Reference" 3 "Thu Jan 24 2013" "Version 2.0" "MAPIProxy" \" -*- nroff -*- .ad l .nh .SH NAME mapiproxy/modules/ Directory Reference \- .SH SYNOPSIS .br .PP .SS "Files" .in +1c .ti -1c .RI "file \fBmpm_cache\&.c\fP" .br .RI "\fICache messages and attachments so we can reduce WAN traffic\&. \fP" .ti -1c .RI "file \fBmpm_cache\&.h\fP" .br .ti -1c .RI "file \fBmpm_cache_ldb\&.c\fP" .br .RI "\fILDB routines for the cache module\&. \fP" .ti -1c .RI "file \fBmpm_cache_stream\&.c\fP" .br .RI "\fIStorage routines for the cache module\&. \fP" .ti -1c .RI "file \fBmpm_downgrade\&.c\fP" .br .RI "\fIDowngrade EMSMDB protocol version EcDoConnect/EcDoRpc\&. \fP" .ti -1c .RI "file \fBmpm_dummy\&.c\fP" .br .ti -1c .RI "file \fBmpm_pack\&.c\fP" .br .RI "\fIPack/Unpack specified MAPI calls into/from a custom MAPI call\&. \fP" .in -1c openchange-2.0/apidocs/man/man3/_tmp_openchange-2.0-QUADRANT_mapiproxy_servers_.3000066400000000000000000000004141223057412600274620ustar00rootroot00000000000000.TH "mapiproxy/servers/ Directory Reference" 3 "Thu Jan 24 2013" "Version 2.0" "MAPIProxy" \" -*- nroff -*- .ad l .nh .SH NAME mapiproxy/servers/ Directory Reference \- .SH SYNOPSIS .br .PP .SS "Directories" .in +1c .ti -1c .RI "directory \fBdefault\fP" .br .in -1c openchange-2.0/apidocs/man/man3/_tmp_openchange-2.0-QUADRANT_mapiproxy_servers_default_.3000066400000000000000000000005501223057412600311670ustar00rootroot00000000000000.TH "mapiproxy/servers/default/ Directory Reference" 3 "Thu Jan 24 2013" "Version 2.0" "MAPIProxy" \" -*- nroff -*- .ad l .nh .SH NAME mapiproxy/servers/default/ Directory Reference \- .SH SYNOPSIS .br .PP .SS "Directories" .in +1c .ti -1c .RI "directory \fBemsmdb\fP" .br .ti -1c .RI "directory \fBnspi\fP" .br .ti -1c .RI "directory \fBrfr\fP" .br .in -1c openchange-2.0/apidocs/man/man3/_tmp_openchange-2.0-QUADRANT_mapiproxy_servers_default_emsmdb_.3000066400000000000000000000031311223057412600325140ustar00rootroot00000000000000.TH "mapiproxy/servers/default/emsmdb/ Directory Reference" 3 "Thu Jan 24 2013" "Version 2.0" "MAPIProxy" \" -*- nroff -*- .ad l .nh .SH NAME mapiproxy/servers/default/emsmdb/ Directory Reference \- .SH SYNOPSIS .br .PP .SS "Files" .in +1c .ti -1c .RI "file \fBdcesrv_exchange_emsmdb\&.c\fP" .br .RI "\fIOpenChange EMSMDB Server implementation\&. \fP" .ti -1c .RI "file \fBdcesrv_exchange_emsmdb\&.h\fP" .br .ti -1c .RI "file \fBemsmdbp\&.c\fP" .br .RI "\fIEMSMDB Provider implementation\&. \fP" .ti -1c .RI "file \fBemsmdbp_object\&.c\fP" .br .RI "\fIServer-side specific objects init/release routines\&. \fP" .ti -1c .RI "file \fBemsmdbp_provisioning\&.c\fP" .br .RI "\fIAccount provisioning\&. \fP" .ti -1c .RI "file \fBoxcfold\&.c\fP" .br .RI "\fIFolder object routines and Rops\&. \fP" .ti -1c .RI "file \fBoxcfxics\&.c\fP" .br .RI "\fIFastTransfer and ICS object routines and Rops\&. \fP" .ti -1c .RI "file \fBoxcmsg\&.c\fP" .br .RI "\fIMessage and Attachment object routines and Rops\&. \fP" .ti -1c .RI "file \fBoxcnotif\&.c\fP" .br .RI "\fICore Notifications routines and Rops\&. \fP" .ti -1c .RI "file \fBoxcperm\&.c\fP" .br .RI "\fIAccess and Operation Permissions Rops\&. \fP" .ti -1c .RI "file \fBoxcprpt\&.c\fP" .br .RI "\fIProperty and Stream Object routines and Rops\&. \fP" .ti -1c .RI "file \fBoxcstor\&.c\fP" .br .RI "\fIServer-side store objects routines and Rops\&. \fP" .ti -1c .RI "file \fBoxctabl\&.c\fP" .br .RI "\fITable object routines and Rops\&. \fP" .ti -1c .RI "file \fBoxomsg\&.c\fP" .br .RI "\fIServer-side message routines and Rops\&. \fP" .ti -1c .RI "file \fBoxorule\&.c\fP" .br .in -1c openchange-2.0/apidocs/man/man3/_tmp_openchange-2.0-QUADRANT_mapiproxy_servers_default_nspi_.3000066400000000000000000000012561223057412600322240ustar00rootroot00000000000000.TH "mapiproxy/servers/default/nspi/ Directory Reference" 3 "Thu Jan 24 2013" "Version 2.0" "MAPIProxy" \" -*- nroff -*- .ad l .nh .SH NAME mapiproxy/servers/default/nspi/ Directory Reference \- .SH SYNOPSIS .br .PP .SS "Files" .in +1c .ti -1c .RI "file \fBdcesrv_exchange_nsp\&.c\fP" .br .RI "\fIOpenChange NSPI Server implementation\&. \fP" .ti -1c .RI "file \fBdcesrv_exchange_nsp\&.h\fP" .br .ti -1c .RI "file \fBemsabp\&.c\fP" .br .RI "\fIAddress Book Provider implementation\&. \fP" .ti -1c .RI "file \fBemsabp_property\&.c\fP" .br .RI "\fIProperty Tag to AD attributes mapping\&. \fP" .ti -1c .RI "file \fBemsabp_tdb\&.c\fP" .br .RI "\fIEMSABP TDB database API\&. \fP" .in -1c openchange-2.0/apidocs/man/man3/_tmp_openchange-2.0-QUADRANT_mapiproxy_servers_default_rfr_.3000066400000000000000000000006311223057412600320400ustar00rootroot00000000000000.TH "mapiproxy/servers/default/rfr/ Directory Reference" 3 "Thu Jan 24 2013" "Version 2.0" "MAPIProxy" \" -*- nroff -*- .ad l .nh .SH NAME mapiproxy/servers/default/rfr/ Directory Reference \- .SH SYNOPSIS .br .PP .SS "Files" .in +1c .ti -1c .RI "file \fBdcesrv_exchange_ds_rfr\&.c\fP" .br .RI "\fIOpenChange RFR Server implementation\&. \fP" .ti -1c .RI "file \fBdcesrv_exchange_ds_rfr\&.h\fP" .br .in -1c openchange-2.0/apidocs/man/man3/cache_dispatch.3000066400000000000000000000000271223057412600215240ustar00rootroot00000000000000.so man3/mpm_cache.c.3 openchange-2.0/apidocs/man/man3/cache_dump_stream_stat.3000066400000000000000000000000271223057412600233000ustar00rootroot00000000000000.so man3/mpm_cache.c.3 openchange-2.0/apidocs/man/man3/cache_exec_sync_cmd.3000066400000000000000000000000271223057412600225300ustar00rootroot00000000000000.so man3/mpm_cache.c.3 openchange-2.0/apidocs/man/man3/cache_find_call_request_index.3000066400000000000000000000000271223057412600245770ustar00rootroot00000000000000.so man3/mpm_cache.c.3 openchange-2.0/apidocs/man/man3/cache_init.3000066400000000000000000000000271223057412600206700ustar00rootroot00000000000000.so man3/mpm_cache.c.3 openchange-2.0/apidocs/man/man3/cache_pull.3000066400000000000000000000000271223057412600207010ustar00rootroot00000000000000.so man3/mpm_cache.c.3 openchange-2.0/apidocs/man/man3/cache_pull_OpenAttach.3000066400000000000000000000000271223057412600230070ustar00rootroot00000000000000.so man3/mpm_cache.c.3 openchange-2.0/apidocs/man/man3/cache_pull_OpenMessage.3000066400000000000000000000000271223057412600231670ustar00rootroot00000000000000.so man3/mpm_cache.c.3 openchange-2.0/apidocs/man/man3/cache_pull_OpenStream.3000066400000000000000000000000271223057412600230360ustar00rootroot00000000000000.so man3/mpm_cache.c.3 openchange-2.0/apidocs/man/man3/cache_pull_Release.3000066400000000000000000000000271223057412600223410ustar00rootroot00000000000000.so man3/mpm_cache.c.3 openchange-2.0/apidocs/man/man3/cache_push.3000066400000000000000000000000271223057412600207040ustar00rootroot00000000000000.so man3/mpm_cache.c.3 openchange-2.0/apidocs/man/man3/cache_push_OpenAttach.3000066400000000000000000000000271223057412600230120ustar00rootroot00000000000000.so man3/mpm_cache.c.3 openchange-2.0/apidocs/man/man3/cache_push_OpenMessage.3000066400000000000000000000000271223057412600231720ustar00rootroot00000000000000.so man3/mpm_cache.c.3 openchange-2.0/apidocs/man/man3/cache_push_OpenStream.3000066400000000000000000000000271223057412600230410ustar00rootroot00000000000000.so man3/mpm_cache.c.3 openchange-2.0/apidocs/man/man3/cache_push_ReadStream.3000066400000000000000000000000271223057412600230130ustar00rootroot00000000000000.so man3/mpm_cache.c.3 openchange-2.0/apidocs/man/man3/cast_PropertyRowSet_to_SRowSet.3000066400000000000000000000000261223057412600247330ustar00rootroot00000000000000.so man3/property.c.3 openchange-2.0/apidocs/man/man3/cast_PropertyRow_to_SRow.3000066400000000000000000000000261223057412600236030ustar00rootroot00000000000000.so man3/property.c.3 openchange-2.0/apidocs/man/man3/cast_PropertyValue_to_SPropValue.3000066400000000000000000000000261223057412600252560ustar00rootroot00000000000000.so man3/property.c.3 openchange-2.0/apidocs/man/man3/cast_SPropValue.3000066400000000000000000000000261223057412600216530ustar00rootroot00000000000000.so man3/property.c.3 openchange-2.0/apidocs/man/man3/cast_mapi_SPropValue.3000066400000000000000000000000261223057412600226610ustar00rootroot00000000000000.so man3/property.c.3 openchange-2.0/apidocs/man/man3/convertIdToFMID.3000066400000000000000000000000261223057412600215010ustar00rootroot00000000000000.so man3/oxcfxics.c.3 openchange-2.0/apidocs/man/man3/dcerpc_server_mapiproxy_init.3000066400000000000000000000000361223057412600245630ustar00rootroot00000000000000.so man3/dcesrv_mapiproxy.c.3 openchange-2.0/apidocs/man/man3/dcesrv_EcDoAsyncConnectEx.3000066400000000000000000000000441223057412600235660ustar00rootroot00000000000000.so man3/dcesrv_exchange_emsmdb.c.3 openchange-2.0/apidocs/man/man3/dcesrv_EcDoConnect.3000066400000000000000000000000441223057412600222730ustar00rootroot00000000000000.so man3/dcesrv_exchange_emsmdb.c.3 openchange-2.0/apidocs/man/man3/dcesrv_EcDoConnectEx.3000066400000000000000000000000441223057412600225700ustar00rootroot00000000000000.so man3/dcesrv_exchange_emsmdb.c.3 openchange-2.0/apidocs/man/man3/dcesrv_EcDoDisconnect.3000066400000000000000000000000441223057412600227730ustar00rootroot00000000000000.so man3/dcesrv_exchange_emsmdb.c.3 openchange-2.0/apidocs/man/man3/dcesrv_EcDoRpc.3000066400000000000000000000000441223057412600214260ustar00rootroot00000000000000.so man3/dcesrv_exchange_emsmdb.c.3 openchange-2.0/apidocs/man/man3/dcesrv_EcDoRpcExt.3000066400000000000000000000000441223057412600221070ustar00rootroot00000000000000.so man3/dcesrv_exchange_emsmdb.c.3 openchange-2.0/apidocs/man/man3/dcesrv_EcDoRpcExt2.3000066400000000000000000000000441223057412600221710ustar00rootroot00000000000000.so man3/dcesrv_exchange_emsmdb.c.3 openchange-2.0/apidocs/man/man3/dcesrv_EcDummyRpc.3000066400000000000000000000000441223057412600221570ustar00rootroot00000000000000.so man3/dcesrv_exchange_emsmdb.c.3 openchange-2.0/apidocs/man/man3/dcesrv_EcGetMoreRpc.3000066400000000000000000000000441223057412600224260ustar00rootroot00000000000000.so man3/dcesrv_exchange_emsmdb.c.3 openchange-2.0/apidocs/man/man3/dcesrv_EcRGetDCName.3000066400000000000000000000000441223057412600222700ustar00rootroot00000000000000.so man3/dcesrv_exchange_emsmdb.c.3 openchange-2.0/apidocs/man/man3/dcesrv_EcRNetGetDCName.3000066400000000000000000000000441223057412600227370ustar00rootroot00000000000000.so man3/dcesrv_exchange_emsmdb.c.3 openchange-2.0/apidocs/man/man3/dcesrv_EcRRegisterPushNotification.3000066400000000000000000000000441223057412600255340ustar00rootroot00000000000000.so man3/dcesrv_exchange_emsmdb.c.3 openchange-2.0/apidocs/man/man3/dcesrv_EcRUnregisterPushNotification.3000066400000000000000000000000441223057412600260770ustar00rootroot00000000000000.so man3/dcesrv_exchange_emsmdb.c.3 openchange-2.0/apidocs/man/man3/dcesrv_EcUnknown0xC.3000066400000000000000000000000441223057412600224310ustar00rootroot00000000000000.so man3/dcesrv_exchange_emsmdb.c.3 openchange-2.0/apidocs/man/man3/dcesrv_EcUnknown0xD.3000066400000000000000000000000441223057412600224320ustar00rootroot00000000000000.so man3/dcesrv_exchange_emsmdb.c.3 openchange-2.0/apidocs/man/man3/dcesrv_NspiBind.3000066400000000000000000000000411223057412600216520ustar00rootroot00000000000000.so man3/dcesrv_exchange_nsp.c.3 openchange-2.0/apidocs/man/man3/dcesrv_NspiCompareMIds.3000066400000000000000000000000411223057412600231410ustar00rootroot00000000000000.so man3/dcesrv_exchange_nsp.c.3 openchange-2.0/apidocs/man/man3/dcesrv_NspiDNToMId.3000066400000000000000000000000411223057412600221740ustar00rootroot00000000000000.so man3/dcesrv_exchange_nsp.c.3 openchange-2.0/apidocs/man/man3/dcesrv_NspiDeleteEntries.3000066400000000000000000000000411223057412600235320ustar00rootroot00000000000000.so man3/dcesrv_exchange_nsp.c.3 openchange-2.0/apidocs/man/man3/dcesrv_NspiGetIDsFromNames.3000066400000000000000000000000411223057412600237250ustar00rootroot00000000000000.so man3/dcesrv_exchange_nsp.c.3 openchange-2.0/apidocs/man/man3/dcesrv_NspiGetMatches.3000066400000000000000000000000411223057412600230220ustar00rootroot00000000000000.so man3/dcesrv_exchange_nsp.c.3 openchange-2.0/apidocs/man/man3/dcesrv_NspiGetNamesFromIDs.3000066400000000000000000000000411223057412600237250ustar00rootroot00000000000000.so man3/dcesrv_exchange_nsp.c.3 openchange-2.0/apidocs/man/man3/dcesrv_NspiGetPropList.3000066400000000000000000000000411223057412600232120ustar00rootroot00000000000000.so man3/dcesrv_exchange_nsp.c.3 openchange-2.0/apidocs/man/man3/dcesrv_NspiGetProps.3000066400000000000000000000000411223057412600225410ustar00rootroot00000000000000.so man3/dcesrv_exchange_nsp.c.3 openchange-2.0/apidocs/man/man3/dcesrv_NspiGetSpecialTable.3000066400000000000000000000000411223057412600237660ustar00rootroot00000000000000.so man3/dcesrv_exchange_nsp.c.3 openchange-2.0/apidocs/man/man3/dcesrv_NspiGetTemplateInfo.3000066400000000000000000000000411223057412600240250ustar00rootroot00000000000000.so man3/dcesrv_exchange_nsp.c.3 openchange-2.0/apidocs/man/man3/dcesrv_NspiModLinkAtt.3000066400000000000000000000000411223057412600230040ustar00rootroot00000000000000.so man3/dcesrv_exchange_nsp.c.3 openchange-2.0/apidocs/man/man3/dcesrv_NspiModProps.3000066400000000000000000000000411223057412600225410ustar00rootroot00000000000000.so man3/dcesrv_exchange_nsp.c.3 openchange-2.0/apidocs/man/man3/dcesrv_NspiQueryColumns.3000066400000000000000000000000411223057412600234440ustar00rootroot00000000000000.so man3/dcesrv_exchange_nsp.c.3 openchange-2.0/apidocs/man/man3/dcesrv_NspiQueryRows.3000066400000000000000000000000411223057412600227560ustar00rootroot00000000000000.so man3/dcesrv_exchange_nsp.c.3 openchange-2.0/apidocs/man/man3/dcesrv_NspiResolveNames.3000066400000000000000000000000411223057412600234010ustar00rootroot00000000000000.so man3/dcesrv_exchange_nsp.c.3 openchange-2.0/apidocs/man/man3/dcesrv_NspiResolveNamesW.3000066400000000000000000000000411223057412600235300ustar00rootroot00000000000000.so man3/dcesrv_exchange_nsp.c.3 openchange-2.0/apidocs/man/man3/dcesrv_NspiResortRestriction.3000066400000000000000000000000411223057412600245020ustar00rootroot00000000000000.so man3/dcesrv_exchange_nsp.c.3 openchange-2.0/apidocs/man/man3/dcesrv_NspiSeekEntries.3000066400000000000000000000000411223057412600232170ustar00rootroot00000000000000.so man3/dcesrv_exchange_nsp.c.3 openchange-2.0/apidocs/man/man3/dcesrv_NspiUnbind.3000066400000000000000000000000411223057412600222150ustar00rootroot00000000000000.so man3/dcesrv_exchange_nsp.c.3 openchange-2.0/apidocs/man/man3/dcesrv_NspiUpdateStat.3000066400000000000000000000000411223057412600230540ustar00rootroot00000000000000.so man3/dcesrv_exchange_nsp.c.3 openchange-2.0/apidocs/man/man3/dcesrv_RfrGetFQDNFromLegacyDN.3000066400000000000000000000000441223057412600242040ustar00rootroot00000000000000.so man3/dcesrv_exchange_ds_rfr.c.3 openchange-2.0/apidocs/man/man3/dcesrv_RfrGetNewDSA.3000066400000000000000000000000441223057412600223420ustar00rootroot00000000000000.so man3/dcesrv_exchange_ds_rfr.c.3 openchange-2.0/apidocs/man/man3/dcesrv_exchange_ds_rfr_dispatch.3000066400000000000000000000000441223057412600251470ustar00rootroot00000000000000.so man3/dcesrv_exchange_ds_rfr.c.3 openchange-2.0/apidocs/man/man3/dcesrv_exchange_ds_rfr_init.3000066400000000000000000000000441223057412600243130ustar00rootroot00000000000000.so man3/dcesrv_exchange_ds_rfr.c.3 openchange-2.0/apidocs/man/man3/dcesrv_exchange_ds_rfr_unbind.3000066400000000000000000000000441223057412600246270ustar00rootroot00000000000000.so man3/dcesrv_exchange_ds_rfr.c.3 openchange-2.0/apidocs/man/man3/dcesrv_exchange_emsmdb_dispatch.3000066400000000000000000000000441223057412600251370ustar00rootroot00000000000000.so man3/dcesrv_exchange_emsmdb.c.3 openchange-2.0/apidocs/man/man3/dcesrv_exchange_emsmdb_init.3000066400000000000000000000000441223057412600243030ustar00rootroot00000000000000.so man3/dcesrv_exchange_emsmdb.c.3 openchange-2.0/apidocs/man/man3/dcesrv_exchange_emsmdb_unbind.3000066400000000000000000000000441223057412600246170ustar00rootroot00000000000000.so man3/dcesrv_exchange_emsmdb.c.3 openchange-2.0/apidocs/man/man3/dcesrv_exchange_nsp_dispatch.3000066400000000000000000000000411223057412600244650ustar00rootroot00000000000000.so man3/dcesrv_exchange_nsp.c.3 openchange-2.0/apidocs/man/man3/dcesrv_exchange_nsp_init.3000066400000000000000000000000411223057412600236310ustar00rootroot00000000000000.so man3/dcesrv_exchange_nsp.c.3 openchange-2.0/apidocs/man/man3/dcesrv_exchange_nsp_unbind.3000066400000000000000000000000411223057412600241450ustar00rootroot00000000000000.so man3/dcesrv_exchange_nsp.c.3 openchange-2.0/apidocs/man/man3/downgrade_EcDoConnect.3000066400000000000000000000000331223057412600227550ustar00rootroot00000000000000.so man3/mpm_downgrade.c.3 openchange-2.0/apidocs/man/man3/downgrade_dispatch.3000066400000000000000000000000331223057412600224300ustar00rootroot00000000000000.so man3/mpm_downgrade.c.3 openchange-2.0/apidocs/man/man3/emsabp_EphemeralEntryID_to_Binary_r.3000066400000000000000000000000241223057412600256160ustar00rootroot00000000000000.so man3/emsabp.c.3 openchange-2.0/apidocs/man/man3/emsabp_PermanentEntryID_to_Binary_r.3000066400000000000000000000000241223057412600256450ustar00rootroot00000000000000.so man3/emsabp.c.3 openchange-2.0/apidocs/man/man3/emsabp_ab_container_by_id.3000066400000000000000000000000241223057412600237200ustar00rootroot00000000000000.so man3/emsabp.c.3 openchange-2.0/apidocs/man/man3/emsabp_ab_container_enum.3000066400000000000000000000000241223057412600235760ustar00rootroot00000000000000.so man3/emsabp.c.3 openchange-2.0/apidocs/man/man3/emsabp_fetch_attrs.3000066400000000000000000000000241223057412600224340ustar00rootroot00000000000000.so man3/emsabp.c.3 openchange-2.0/apidocs/man/man3/emsabp_fetch_attrs_from_msg.3000066400000000000000000000000241223057412600243250ustar00rootroot00000000000000.so man3/emsabp.c.3 openchange-2.0/apidocs/man/man3/emsabp_get_CreationTemplatesTable.3000066400000000000000000000000241223057412600253600ustar00rootroot00000000000000.so man3/emsabp.c.3 openchange-2.0/apidocs/man/man3/emsabp_get_HierarchyTable.3000066400000000000000000000000241223057412600236530ustar00rootroot00000000000000.so man3/emsabp.c.3 openchange-2.0/apidocs/man/man3/emsabp_get_account_info.3000066400000000000000000000000241223057412600234340ustar00rootroot00000000000000.so man3/emsabp.c.3 openchange-2.0/apidocs/man/man3/emsabp_init.3000066400000000000000000000000241223057412600210710ustar00rootroot00000000000000.so man3/emsabp.c.3 openchange-2.0/apidocs/man/man3/emsabp_property_get_attribute.3000066400000000000000000000000351223057412600247360ustar00rootroot00000000000000.so man3/emsabp_property.c.3 openchange-2.0/apidocs/man/man3/emsabp_property_get_ref_attr.3000066400000000000000000000000351223057412600245410ustar00rootroot00000000000000.so man3/emsabp_property.c.3 openchange-2.0/apidocs/man/man3/emsabp_property_get_ulPropTag.3000066400000000000000000000000351223057412600246500ustar00rootroot00000000000000.so man3/emsabp_property.c.3 openchange-2.0/apidocs/man/man3/emsabp_property_is_ref.3000066400000000000000000000000351223057412600233430ustar00rootroot00000000000000.so man3/emsabp_property.c.3 openchange-2.0/apidocs/man/man3/emsabp_query.3000066400000000000000000000000241223057412600212730ustar00rootroot00000000000000.so man3/emsabp.c.3 openchange-2.0/apidocs/man/man3/emsabp_search.3000066400000000000000000000000241223057412600213730ustar00rootroot00000000000000.so man3/emsabp.c.3 openchange-2.0/apidocs/man/man3/emsabp_search_dn.3000066400000000000000000000000241223057412600220540ustar00rootroot00000000000000.so man3/emsabp.c.3 openchange-2.0/apidocs/man/man3/emsabp_search_legacyExchangeDN.3000066400000000000000000000000241223057412600246040ustar00rootroot00000000000000.so man3/emsabp.c.3 openchange-2.0/apidocs/man/man3/emsabp_set_EphemeralEntryID.3000066400000000000000000000000241223057412600241420ustar00rootroot00000000000000.so man3/emsabp.c.3 openchange-2.0/apidocs/man/man3/emsabp_set_PermanentEntryID.3000066400000000000000000000000241223057412600241710ustar00rootroot00000000000000.so man3/emsabp.c.3 openchange-2.0/apidocs/man/man3/emsabp_table_fetch_attrs.3000066400000000000000000000000241223057412600236030ustar00rootroot00000000000000.so man3/emsabp.c.3 openchange-2.0/apidocs/man/man3/emsabp_tdb_close.3000066400000000000000000000000301223057412600220610ustar00rootroot00000000000000.so man3/emsabp_tdb.c.3 openchange-2.0/apidocs/man/man3/emsabp_tdb_fetch.3000066400000000000000000000000301223057412600220450ustar00rootroot00000000000000.so man3/emsabp_tdb.c.3 openchange-2.0/apidocs/man/man3/emsabp_tdb_fetch_MId.3000066400000000000000000000000301223057412600225760ustar00rootroot00000000000000.so man3/emsabp_tdb.c.3 openchange-2.0/apidocs/man/man3/emsabp_tdb_fetch_dn_from_MId.3000066400000000000000000000000301223057412600243020ustar00rootroot00000000000000.so man3/emsabp_tdb.c.3 openchange-2.0/apidocs/man/man3/emsabp_tdb_init.3000066400000000000000000000000301223057412600217170ustar00rootroot00000000000000.so man3/emsabp_tdb.c.3 openchange-2.0/apidocs/man/man3/emsabp_tdb_init_tmp.3000066400000000000000000000000301223057412600225770ustar00rootroot00000000000000.so man3/emsabp_tdb.c.3 openchange-2.0/apidocs/man/man3/emsabp_tdb_insert.3000066400000000000000000000000301223057412600222600ustar00rootroot00000000000000.so man3/emsabp_tdb.c.3 openchange-2.0/apidocs/man/man3/emsabp_tdb_lookup_MId.3000066400000000000000000000000301223057412600230160ustar00rootroot00000000000000.so man3/emsabp_tdb.c.3 openchange-2.0/apidocs/man/man3/emsabp_verify_codepage.3000066400000000000000000000000241223057412600232610ustar00rootroot00000000000000.so man3/emsabp.c.3 openchange-2.0/apidocs/man/man3/emsabp_verify_user.3000066400000000000000000000000241223057412600224700ustar00rootroot00000000000000.so man3/emsabp.c.3 openchange-2.0/apidocs/man/man3/emsmdb_async_connect.3000066400000000000000000000000241223057412600227540ustar00rootroot00000000000000.so man3/emsmdb.c.3 openchange-2.0/apidocs/man/man3/emsmdb_async_waitex.3000066400000000000000000000000321223057412600226230ustar00rootroot00000000000000.so man3/async_emsmdb.c.3 openchange-2.0/apidocs/man/man3/emsmdb_bind_notification.3000066400000000000000000000000241223057412600236100ustar00rootroot00000000000000.so man3/emsmdb.c.3 openchange-2.0/apidocs/man/man3/emsmdb_connect.3000066400000000000000000000000241223057412600215570ustar00rootroot00000000000000.so man3/emsmdb.c.3 openchange-2.0/apidocs/man/man3/emsmdb_connect_ex.3000066400000000000000000000000241223057412600222530ustar00rootroot00000000000000.so man3/emsmdb.c.3 openchange-2.0/apidocs/man/man3/emsmdb_disconnect.3000066400000000000000000000000241223057412600222570ustar00rootroot00000000000000.so man3/emsmdb.c.3 openchange-2.0/apidocs/man/man3/emsmdb_disconnect_dtor.3000066400000000000000000000000241223057412600233070ustar00rootroot00000000000000.so man3/emsmdb.c.3 openchange-2.0/apidocs/man/man3/emsmdb_get_SPropValue.3000066400000000000000000000000241223057412600230250ustar00rootroot00000000000000.so man3/emsmdb.c.3 openchange-2.0/apidocs/man/man3/emsmdb_get_SRow.3000066400000000000000000000000241223057412600216570ustar00rootroot00000000000000.so man3/emsmdb.c.3 openchange-2.0/apidocs/man/man3/emsmdb_get_SRowSet.3000066400000000000000000000000241223057412600223330ustar00rootroot00000000000000.so man3/emsmdb.c.3 openchange-2.0/apidocs/man/man3/emsmdb_get_info.3000066400000000000000000000000241223057412600217200ustar00rootroot00000000000000.so man3/emsmdb.c.3 openchange-2.0/apidocs/man/man3/emsmdb_register_notification.3000066400000000000000000000000241223057412600245200ustar00rootroot00000000000000.so man3/emsmdb.c.3 openchange-2.0/apidocs/man/man3/emsmdb_transaction.3000066400000000000000000000000241223057412600224530ustar00rootroot00000000000000.so man3/emsmdb.c.3 openchange-2.0/apidocs/man/man3/emsmdb_transaction_ext2.3000066400000000000000000000000241223057412600234150ustar00rootroot00000000000000.so man3/emsmdb.c.3 openchange-2.0/apidocs/man/man3/emsmdb_transaction_null.3000066400000000000000000000000241223057412600235050ustar00rootroot00000000000000.so man3/emsmdb.c.3 openchange-2.0/apidocs/man/man3/emsmdbp_get_contextID.3000066400000000000000000000000341223057412600230470ustar00rootroot00000000000000.so man3/emsmdbp_object.c.3 openchange-2.0/apidocs/man/man3/emsmdbp_get_owner.3000066400000000000000000000000341223057412600223000ustar00rootroot00000000000000.so man3/emsmdbp_object.c.3 openchange-2.0/apidocs/man/man3/emsmdbp_init.3000066400000000000000000000000251223057412600212520ustar00rootroot00000000000000.so man3/emsmdbp.c.3 openchange-2.0/apidocs/man/man3/emsmdbp_is_mailboxstore.3000066400000000000000000000000341223057412600235120ustar00rootroot00000000000000.so man3/emsmdbp_object.c.3 openchange-2.0/apidocs/man/man3/emsmdbp_is_mapistore.3000066400000000000000000000000341223057412600230050ustar00rootroot00000000000000.so man3/emsmdbp_object.c.3 openchange-2.0/apidocs/man/man3/emsmdbp_mailbox_provision.3000066400000000000000000000000421223057412600240510ustar00rootroot00000000000000.so man3/emsmdbp_provisioning.c.3 openchange-2.0/apidocs/man/man3/emsmdbp_mapi_handles_destructor.3000066400000000000000000000000251223057412600252110ustar00rootroot00000000000000.so man3/emsmdbp.c.3 openchange-2.0/apidocs/man/man3/emsmdbp_mapi_store_destructor.3000066400000000000000000000000251223057412600247270ustar00rootroot00000000000000.so man3/emsmdbp.c.3 openchange-2.0/apidocs/man/man3/emsmdbp_object_attachment_init.3000066400000000000000000000000341223057412600250100ustar00rootroot00000000000000.so man3/emsmdbp_object.c.3 openchange-2.0/apidocs/man/man3/emsmdbp_object_copy_properties.3000066400000000000000000000000341223057412600250630ustar00rootroot00000000000000.so man3/emsmdbp_object.c.3 openchange-2.0/apidocs/man/man3/emsmdbp_object_destructor.3000066400000000000000000000000341223057412600240330ustar00rootroot00000000000000.so man3/emsmdbp_object.c.3 openchange-2.0/apidocs/man/man3/emsmdbp_object_folder_init.3000066400000000000000000000000341223057412600241330ustar00rootroot00000000000000.so man3/emsmdbp_object.c.3 openchange-2.0/apidocs/man/man3/emsmdbp_object_ftcontext_init.3000066400000000000000000000000341223057412600246760ustar00rootroot00000000000000.so man3/emsmdbp_object.c.3 openchange-2.0/apidocs/man/man3/emsmdbp_object_init.3000066400000000000000000000000341223057412600226000ustar00rootroot00000000000000.so man3/emsmdbp_object.c.3 openchange-2.0/apidocs/man/man3/emsmdbp_object_mailbox_init.3000066400000000000000000000000341223057412600243130ustar00rootroot00000000000000.so man3/emsmdbp_object.c.3 openchange-2.0/apidocs/man/man3/emsmdbp_object_message_init.3000066400000000000000000000000341223057412600243040ustar00rootroot00000000000000.so man3/emsmdbp_object.c.3 openchange-2.0/apidocs/man/man3/emsmdbp_object_open_folder_by_fid.3000066400000000000000000000000341223057412600254450ustar00rootroot00000000000000.so man3/emsmdbp_object.c.3 openchange-2.0/apidocs/man/man3/emsmdbp_object_stream_init.3000066400000000000000000000000341223057412600241530ustar00rootroot00000000000000.so man3/emsmdbp_object.c.3 openchange-2.0/apidocs/man/man3/emsmdbp_object_subscription_init.3000066400000000000000000000000341223057412600254040ustar00rootroot00000000000000.so man3/emsmdbp_object.c.3 openchange-2.0/apidocs/man/man3/emsmdbp_object_synccontext_init.3000066400000000000000000000000341223057412600252410ustar00rootroot00000000000000.so man3/emsmdbp_object.c.3 openchange-2.0/apidocs/man/man3/emsmdbp_object_table_init.3000066400000000000000000000000341223057412600237470ustar00rootroot00000000000000.so man3/emsmdbp_object.c.3 openchange-2.0/apidocs/man/man3/emsmdbp_openchange_ldb_init.3000066400000000000000000000000251223057412600242620ustar00rootroot00000000000000.so man3/emsmdbp.c.3 openchange-2.0/apidocs/man/man3/emsmdbp_resolve_recipient.3000066400000000000000000000000251223057412600240300ustar00rootroot00000000000000.so man3/emsmdbp.c.3 openchange-2.0/apidocs/man/man3/emsmdbp_verify_user.3000066400000000000000000000000251223057412600226510ustar00rootroot00000000000000.so man3/emsmdbp.c.3 openchange-2.0/apidocs/man/man3/emsmdbp_verify_userdn.3000066400000000000000000000000251223057412600231730ustar00rootroot00000000000000.so man3/emsmdbp.c.3 openchange-2.0/apidocs/man/man3/entryid_set_AB_EntryID.3000066400000000000000000000000251223057412600230710ustar00rootroot00000000000000.so man3/entryid.c.3 openchange-2.0/apidocs/man/man3/entryid_set_folder_EntryID.3000066400000000000000000000000251223057412600240620ustar00rootroot00000000000000.so man3/entryid.c.3 openchange-2.0/apidocs/man/man3/exchange_globcnt.3000066400000000000000000000000231223057412600220700ustar00rootroot00000000000000.so man3/idset.c.3 openchange-2.0/apidocs/man/man3/free_emsmdb_property.3000066400000000000000000000000241223057412600230130ustar00rootroot00000000000000.so man3/emsmdb.c.3 openchange-2.0/apidocs/man/man3/fxparser_init.3000066400000000000000000000000261223057412600214560ustar00rootroot00000000000000.so man3/fxparser.c.3 openchange-2.0/apidocs/man/man3/fxparser_parse.3000066400000000000000000000000261223057412600216250ustar00rootroot00000000000000.so man3/fxparser.c.3 openchange-2.0/apidocs/man/man3/fxparser_set_delprop_callback.3000066400000000000000000000000261223057412600246470ustar00rootroot00000000000000.so man3/fxparser.c.3 openchange-2.0/apidocs/man/man3/fxparser_set_marker_callback.3000066400000000000000000000000261223057412600244630ustar00rootroot00000000000000.so man3/fxparser.c.3 openchange-2.0/apidocs/man/man3/fxparser_set_namedprop_callback.3000066400000000000000000000000261223057412600251670ustar00rootroot00000000000000.so man3/fxparser.c.3 openchange-2.0/apidocs/man/man3/fxparser_set_property_callback.3000066400000000000000000000000261223057412600250660ustar00rootroot00000000000000.so man3/fxparser.c.3 openchange-2.0/apidocs/man/man3/get_AddressBookEntryId.3000066400000000000000000000000261223057412600231370ustar00rootroot00000000000000.so man3/property.c.3 openchange-2.0/apidocs/man/man3/get_FolderEntryId.3000066400000000000000000000000261223057412600221520ustar00rootroot00000000000000.so man3/property.c.3 openchange-2.0/apidocs/man/man3/get_GlobalObjectId.3000066400000000000000000000000261223057412600222440ustar00rootroot00000000000000.so man3/property.c.3 openchange-2.0/apidocs/man/man3/get_MessageEntryId.3000066400000000000000000000000261223057412600223230ustar00rootroot00000000000000.so man3/property.c.3 openchange-2.0/apidocs/man/man3/get_MessageReadState.3000066400000000000000000000000261223057412600226210ustar00rootroot00000000000000.so man3/oxcfxics.c.3 openchange-2.0/apidocs/man/man3/get_PtypServerId.3000066400000000000000000000000261223057412600220400ustar00rootroot00000000000000.so man3/property.c.3 openchange-2.0/apidocs/man/man3/get_RecurrencePattern.3000066400000000000000000000000261223057412600230730ustar00rootroot00000000000000.so man3/property.c.3 openchange-2.0/apidocs/man/man3/get_TimeZoneStruct.3000066400000000000000000000000261223057412600223770ustar00rootroot00000000000000.so man3/property.c.3 openchange-2.0/apidocs/man/man3/get_TypedString.3000066400000000000000000000000261223057412600217140ustar00rootroot00000000000000.so man3/property.c.3 openchange-2.0/apidocs/man/man3/get_mapi_SRestriction_size.3000066400000000000000000000000301223057412600241230ustar00rootroot00000000000000.so man3/IMAPITable.c.3 openchange-2.0/apidocs/man/man3/get_utf8_utf16_conv_length.3000066400000000000000000000000261223057412600237410ustar00rootroot00000000000000.so man3/property.c.3 openchange-2.0/apidocs/man/man3/libmapiadmin.h.3000066400000000000000000000042221223057412600214570ustar00rootroot00000000000000.TH "libmapiadmin/libmapiadmin.h" 3 "Thu Jan 24 2013" "Version 2.0" "libmapiadmin" \" -*- nroff -*- .ad l .nh .SH NAME libmapiadmin/libmapiadmin.h \- .PP Structures for MAPI admin functions\&. .SH SYNOPSIS .br .PP \fC#include \fP .br \fC#include \fP .br \fC#include \fP .br \fC#include \fP .br \fC#include \fP .br \fC#include \fP .br \fC#include \fP .br \fC#include \fP .br \fC#include \fP .br \fC#include \fP .br \fC#include \fP .br \fC#include 'libmapi/libmapi\&.h'\fP .br .SS "Data Structures" .in +1c .ti -1c .RI "struct \fBmapiadmin_ctx\fP" .br .RI "\fIMAPI admin function context\&. \fP" .in -1c .SS "Functions" .in +1c .ti -1c .RI "struct \fBmapiadmin_ctx\fP * \fBmapiadmin_init\fP (struct mapi_session *)" .br .RI "\fICreate and initialise a \fBmapiadmin_ctx\fP structure\&. \fP" .ti -1c .RI "enum MAPISTATUS \fBmapiadmin_release\fP (struct \fBmapiadmin_ctx\fP *)" .br .RI "\fIClean up a \fBmapiadmin_ctx\fP structure\&. \fP" .ti -1c .RI "enum MAPISTATUS \fBmapiadmin_user_add\fP (struct \fBmapiadmin_ctx\fP *)" .br .RI "\fIAdd a user to Active Directory\&. \fP" .ti -1c .RI "enum MAPISTATUS \fBmapiadmin_user_del\fP (struct \fBmapiadmin_ctx\fP *)" .br .RI "\fIDelete a user from Active Directory\&. \fP" .ti -1c .RI "enum MAPISTATUS \fBmapiadmin_user_extend\fP (struct \fBmapiadmin_ctx\fP *)" .br .RI "\fIExtend user attributes to be Exchange user\&. \fP" .in -1c .SH "Detailed Description" .PP Structures for MAPI admin functions\&. .SH "Function Documentation" .PP .SS "struct \fBmapiadmin_ctx\fP* mapiadmin_init (struct mapi_session *session)\fC [read]\fP" .PP Create and initialise a \fBmapiadmin_ctx\fP structure\&. You should use mapiadmin_release to clean up the \fBmapiadmin_ctx\fP structure when done\&. .SS "enum MAPISTATUS mapiadmin_release (struct \fBmapiadmin_ctx\fP *mapiadmin_ctx)" .PP Clean up a \fBmapiadmin_ctx\fP structure\&. The structure is assumed to have been allocated using \fBmapiadmin_init()\fP or equivalent code\&. .SH "Author" .PP Generated automatically by Doxygen for libmapiadmin from the source code\&. openchange-2.0/apidocs/man/man3/libmapiserver_LongTermId_size.3000066400000000000000000000000431223057412600245620ustar00rootroot00000000000000.so man3/libmapiserver_oxcdata.c.3 openchange-2.0/apidocs/man/man3/libmapiserver_PropertyName_size.3000066400000000000000000000000431223057412600252030ustar00rootroot00000000000000.so man3/libmapiserver_oxcdata.c.3 openchange-2.0/apidocs/man/man3/libmapiserver_ROP_request_to_properties.3000066400000000000000000000000431223057412600267120ustar00rootroot00000000000000.so man3/libmapiserver_oxcprpt.c.3 openchange-2.0/apidocs/man/man3/libmapiserver_RecipientRow_size.3000066400000000000000000000000431223057412600251700ustar00rootroot00000000000000.so man3/libmapiserver_oxcdata.c.3 openchange-2.0/apidocs/man/man3/libmapiserver_RopCommitStream_size.3000066400000000000000000000000431223057412600256430ustar00rootroot00000000000000.so man3/libmapiserver_oxcprpt.c.3 openchange-2.0/apidocs/man/man3/libmapiserver_RopCopyFolder_size.3000066400000000000000000000000431223057412600253050ustar00rootroot00000000000000.so man3/libmapiserver_oxcfold.c.3 openchange-2.0/apidocs/man/man3/libmapiserver_RopCopyTo_size.3000066400000000000000000000000431223057412600244540ustar00rootroot00000000000000.so man3/libmapiserver_oxcprpt.c.3 openchange-2.0/apidocs/man/man3/libmapiserver_RopCreateAttach_size.3000066400000000000000000000000421223057412600255660ustar00rootroot00000000000000.so man3/libmapiserver_oxcmsg.c.3 openchange-2.0/apidocs/man/man3/libmapiserver_RopCreateFolder_size.3000066400000000000000000000000431223057412600255760ustar00rootroot00000000000000.so man3/libmapiserver_oxcfold.c.3 openchange-2.0/apidocs/man/man3/libmapiserver_RopCreateMessage_size.3000066400000000000000000000000421223057412600257460ustar00rootroot00000000000000.so man3/libmapiserver_oxcmsg.c.3 openchange-2.0/apidocs/man/man3/libmapiserver_RopDeleteFolder_size.3000066400000000000000000000000431223057412600255750ustar00rootroot00000000000000.so man3/libmapiserver_oxcfold.c.3 openchange-2.0/apidocs/man/man3/libmapiserver_RopDeleteMessage_size.3000066400000000000000000000000431223057412600257460ustar00rootroot00000000000000.so man3/libmapiserver_oxcfold.c.3 openchange-2.0/apidocs/man/man3/libmapiserver_RopDeletePropertiesNoReplicate_size.3000066400000000000000000000000431223057412600306440ustar00rootroot00000000000000.so man3/libmapiserver_oxcprpt.c.3 openchange-2.0/apidocs/man/man3/libmapiserver_RopDeleteProperties_size.3000066400000000000000000000000431223057412600265160ustar00rootroot00000000000000.so man3/libmapiserver_oxcprpt.c.3 openchange-2.0/apidocs/man/man3/libmapiserver_RopEmptyFolder_size.3000066400000000000000000000000431223057412600254710ustar00rootroot00000000000000.so man3/libmapiserver_oxcfold.c.3 openchange-2.0/apidocs/man/man3/libmapiserver_RopFastTransferSourceCopyTo_size.3000066400000000000000000000000441223057412600301610ustar00rootroot00000000000000.so man3/libmapiserver_oxcfxics.c.3 openchange-2.0/apidocs/man/man3/libmapiserver_RopFastTransferSourceGetBuffer_size.3000066400000000000000000000000441223057412600306150ustar00rootroot00000000000000.so man3/libmapiserver_oxcfxics.c.3 openchange-2.0/apidocs/man/man3/libmapiserver_RopFindRow_size.3000066400000000000000000000000431223057412600246070ustar00rootroot00000000000000.so man3/libmapiserver_oxctabl.c.3 openchange-2.0/apidocs/man/man3/libmapiserver_RopGetAddressTypes_size.3000066400000000000000000000000421223057412600263100ustar00rootroot00000000000000.so man3/libmapiserver_oxomsg.c.3 openchange-2.0/apidocs/man/man3/libmapiserver_RopGetAttachmentTable_size.3000066400000000000000000000000421223057412600267360ustar00rootroot00000000000000.so man3/libmapiserver_oxcmsg.c.3 openchange-2.0/apidocs/man/man3/libmapiserver_RopGetContentsTable_size.3000066400000000000000000000000431223057412600264440ustar00rootroot00000000000000.so man3/libmapiserver_oxcfold.c.3 openchange-2.0/apidocs/man/man3/libmapiserver_RopGetHierarchyTable_size.3000066400000000000000000000000431223057412600265650ustar00rootroot00000000000000.so man3/libmapiserver_oxcfold.c.3 openchange-2.0/apidocs/man/man3/libmapiserver_RopGetLocalReplicaIds_size.3000066400000000000000000000000441223057412600266720ustar00rootroot00000000000000.so man3/libmapiserver_oxcfxics.c.3 openchange-2.0/apidocs/man/man3/libmapiserver_RopGetNamesFromIDs_size.3000066400000000000000000000000431223057412600261660ustar00rootroot00000000000000.so man3/libmapiserver_oxcprpt.c.3 openchange-2.0/apidocs/man/man3/libmapiserver_RopGetPerUserGuid_size.3000066400000000000000000000000431223057412600260750ustar00rootroot00000000000000.so man3/libmapiserver_oxcstor.c.3 openchange-2.0/apidocs/man/man3/libmapiserver_RopGetPerUserLongTermIds_size.3000066400000000000000000000000431223057412600273740ustar00rootroot00000000000000.so man3/libmapiserver_oxcstor.c.3 openchange-2.0/apidocs/man/man3/libmapiserver_RopGetPropertiesAll_size.3000066400000000000000000000000431223057412600264640ustar00rootroot00000000000000.so man3/libmapiserver_oxcprpt.c.3 openchange-2.0/apidocs/man/man3/libmapiserver_RopGetPropertiesList_size.3000066400000000000000000000000431223057412600266670ustar00rootroot00000000000000.so man3/libmapiserver_oxcprpt.c.3 openchange-2.0/apidocs/man/man3/libmapiserver_RopGetPropertiesSpecific_size.3000066400000000000000000000000431223057412600275010ustar00rootroot00000000000000.so man3/libmapiserver_oxcprpt.c.3 openchange-2.0/apidocs/man/man3/libmapiserver_RopGetPropertyIdsFromNames_size.3000066400000000000000000000000431223057412600277730ustar00rootroot00000000000000.so man3/libmapiserver_oxcprpt.c.3 openchange-2.0/apidocs/man/man3/libmapiserver_RopGetReceiveFolderTable_size.3000066400000000000000000000000431223057412600273650ustar00rootroot00000000000000.so man3/libmapiserver_oxcstor.c.3 openchange-2.0/apidocs/man/man3/libmapiserver_RopGetReceiveFolder_size.3000066400000000000000000000000431223057412600264150ustar00rootroot00000000000000.so man3/libmapiserver_oxcstor.c.3 openchange-2.0/apidocs/man/man3/libmapiserver_RopGetRulesTable_size.3000066400000000000000000000000431223057412600257410ustar00rootroot00000000000000.so man3/libmapiserver_oxorule.c.3 openchange-2.0/apidocs/man/man3/libmapiserver_RopGetSearchCriteria_size.3000066400000000000000000000000431223057412600265670ustar00rootroot00000000000000.so man3/libmapiserver_oxcfold.c.3 openchange-2.0/apidocs/man/man3/libmapiserver_RopGetStoreState_size.3000066400000000000000000000000431223057412600257740ustar00rootroot00000000000000.so man3/libmapiserver_oxcstor.c.3 openchange-2.0/apidocs/man/man3/libmapiserver_RopGetStreamSize_size.3000066400000000000000000000000431223057412600257650ustar00rootroot00000000000000.so man3/libmapiserver_oxcprpt.c.3 openchange-2.0/apidocs/man/man3/libmapiserver_RopGetTransportFolder_size.3000066400000000000000000000000421223057412600270260ustar00rootroot00000000000000.so man3/libmapiserver_oxomsg.c.3 openchange-2.0/apidocs/man/man3/libmapiserver_RopIdFromLongTermId_size.3000066400000000000000000000000431223057412600263440ustar00rootroot00000000000000.so man3/libmapiserver_oxcstor.c.3 openchange-2.0/apidocs/man/man3/libmapiserver_RopLogon_size.3000066400000000000000000000000431223057412600243150ustar00rootroot00000000000000.so man3/libmapiserver_oxcstor.c.3 openchange-2.0/apidocs/man/man3/libmapiserver_RopLongTermIdFromId_size.3000066400000000000000000000000431223057412600263440ustar00rootroot00000000000000.so man3/libmapiserver_oxcstor.c.3 openchange-2.0/apidocs/man/man3/libmapiserver_RopModifyRecipients_size.3000066400000000000000000000000421223057412600265130ustar00rootroot00000000000000.so man3/libmapiserver_oxcmsg.c.3 openchange-2.0/apidocs/man/man3/libmapiserver_RopModifyRules_size.3000066400000000000000000000000431223057412600255010ustar00rootroot00000000000000.so man3/libmapiserver_oxorule.c.3 openchange-2.0/apidocs/man/man3/libmapiserver_RopMoveCopyMessages_size.3000066400000000000000000000000431223057412600264700ustar00rootroot00000000000000.so man3/libmapiserver_oxcfold.c.3 openchange-2.0/apidocs/man/man3/libmapiserver_RopMoveFolder_size.3000066400000000000000000000000431223057412600253010ustar00rootroot00000000000000.so man3/libmapiserver_oxcfold.c.3 openchange-2.0/apidocs/man/man3/libmapiserver_RopNotify_size.3000066400000000000000000000000441223057412600245100ustar00rootroot00000000000000.so man3/libmapiserver_oxcnotif.c.3 openchange-2.0/apidocs/man/man3/libmapiserver_RopOpenAttach_size.3000066400000000000000000000000421223057412600252640ustar00rootroot00000000000000.so man3/libmapiserver_oxcmsg.c.3 openchange-2.0/apidocs/man/man3/libmapiserver_RopOpenEmbeddedMessage_size.3000066400000000000000000000000421223057412600270560ustar00rootroot00000000000000.so man3/libmapiserver_oxcmsg.c.3 openchange-2.0/apidocs/man/man3/libmapiserver_RopOpenFolder_size.3000066400000000000000000000000431223057412600252740ustar00rootroot00000000000000.so man3/libmapiserver_oxcfold.c.3 openchange-2.0/apidocs/man/man3/libmapiserver_RopOpenMessage_size.3000066400000000000000000000000421223057412600254440ustar00rootroot00000000000000.so man3/libmapiserver_oxcmsg.c.3 openchange-2.0/apidocs/man/man3/libmapiserver_RopOpenStream_size.3000066400000000000000000000000431223057412600253140ustar00rootroot00000000000000.so man3/libmapiserver_oxcprpt.c.3 openchange-2.0/apidocs/man/man3/libmapiserver_RopOptionsData_size.3000066400000000000000000000000421223057412600254630ustar00rootroot00000000000000.so man3/libmapiserver_oxomsg.c.3 openchange-2.0/apidocs/man/man3/libmapiserver_RopQueryPosition_size.3000066400000000000000000000000431223057412600260710ustar00rootroot00000000000000.so man3/libmapiserver_oxctabl.c.3 openchange-2.0/apidocs/man/man3/libmapiserver_RopQueryRows_size.3000066400000000000000000000000431223057412600252170ustar00rootroot00000000000000.so man3/libmapiserver_oxctabl.c.3 openchange-2.0/apidocs/man/man3/libmapiserver_RopReadPerUserInformation_size.3000066400000000000000000000000431223057412600276260ustar00rootroot00000000000000.so man3/libmapiserver_oxcstor.c.3 openchange-2.0/apidocs/man/man3/libmapiserver_RopReadStream_size.3000066400000000000000000000000431223057412600252660ustar00rootroot00000000000000.so man3/libmapiserver_oxcprpt.c.3 openchange-2.0/apidocs/man/man3/libmapiserver_RopRegisterNotification_size.3000066400000000000000000000000441223057412600273730ustar00rootroot00000000000000.so man3/libmapiserver_oxcnotif.c.3 openchange-2.0/apidocs/man/man3/libmapiserver_RopReloadCachedInformation_size.3000066400000000000000000000000421223057412600277420ustar00rootroot00000000000000.so man3/libmapiserver_oxcmsg.c.3 openchange-2.0/apidocs/man/man3/libmapiserver_RopRemoveAllRecipients_size.3000066400000000000000000000000421223057412600271520ustar00rootroot00000000000000.so man3/libmapiserver_oxcmsg.c.3 openchange-2.0/apidocs/man/man3/libmapiserver_RopResetTable_size.3000066400000000000000000000000431223057412600252710ustar00rootroot00000000000000.so man3/libmapiserver_oxctabl.c.3 openchange-2.0/apidocs/man/man3/libmapiserver_RopRestrict_size.3000066400000000000000000000000431223057412600250360ustar00rootroot00000000000000.so man3/libmapiserver_oxctabl.c.3 openchange-2.0/apidocs/man/man3/libmapiserver_RopSaveChangesAttachment_size.3000066400000000000000000000000421223057412600274360ustar00rootroot00000000000000.so man3/libmapiserver_oxcmsg.c.3 openchange-2.0/apidocs/man/man3/libmapiserver_RopSaveChangesMessage_size.3000066400000000000000000000000421223057412600267320ustar00rootroot00000000000000.so man3/libmapiserver_oxcmsg.c.3 openchange-2.0/apidocs/man/man3/libmapiserver_RopSeekRow_size.3000066400000000000000000000000431223057412600246160ustar00rootroot00000000000000.so man3/libmapiserver_oxctabl.c.3 openchange-2.0/apidocs/man/man3/libmapiserver_RopSeekStream_size.3000066400000000000000000000000431223057412600253020ustar00rootroot00000000000000.so man3/libmapiserver_oxcprpt.c.3 openchange-2.0/apidocs/man/man3/libmapiserver_RopSetColumns_size.3000066400000000000000000000000431223057412600253330ustar00rootroot00000000000000.so man3/libmapiserver_oxctabl.c.3 openchange-2.0/apidocs/man/man3/libmapiserver_RopSetLocalReplicaMidsetDeleted_size.3000066400000000000000000000000441223057412600307030ustar00rootroot00000000000000.so man3/libmapiserver_oxcfxics.c.3 openchange-2.0/apidocs/man/man3/libmapiserver_RopSetMessageReadFlag_size.3000066400000000000000000000000421223057412600266640ustar00rootroot00000000000000.so man3/libmapiserver_oxcmsg.c.3 openchange-2.0/apidocs/man/man3/libmapiserver_RopSetProperties_size.3000066400000000000000000000000431223057412600260470ustar00rootroot00000000000000.so man3/libmapiserver_oxcprpt.c.3 openchange-2.0/apidocs/man/man3/libmapiserver_RopSetReceiveFolder_size.3000066400000000000000000000000431223057412600264310ustar00rootroot00000000000000.so man3/libmapiserver_oxcstor.c.3 openchange-2.0/apidocs/man/man3/libmapiserver_RopSetSearchCriteria_size.3000066400000000000000000000000431223057412600266030ustar00rootroot00000000000000.so man3/libmapiserver_oxcfold.c.3 openchange-2.0/apidocs/man/man3/libmapiserver_RopSetSpooler_size.3000066400000000000000000000000421223057412600253350ustar00rootroot00000000000000.so man3/libmapiserver_oxomsg.c.3 openchange-2.0/apidocs/man/man3/libmapiserver_RopSetStreamSize_size.3000066400000000000000000000000431223057412600260010ustar00rootroot00000000000000.so man3/libmapiserver_oxcprpt.c.3 openchange-2.0/apidocs/man/man3/libmapiserver_RopSortTable_size.3000066400000000000000000000000431223057412600251360ustar00rootroot00000000000000.so man3/libmapiserver_oxctabl.c.3 openchange-2.0/apidocs/man/man3/libmapiserver_RopSubmitMessage_size.3000066400000000000000000000000421223057412600260060ustar00rootroot00000000000000.so man3/libmapiserver_oxomsg.c.3 openchange-2.0/apidocs/man/man3/libmapiserver_RopSyncConfigure_size.3000066400000000000000000000000441223057412600260160ustar00rootroot00000000000000.so man3/libmapiserver_oxcfxics.c.3 openchange-2.0/apidocs/man/man3/libmapiserver_RopSyncGetTransferState_size.3000066400000000000000000000000441223057412600273220ustar00rootroot00000000000000.so man3/libmapiserver_oxcfxics.c.3 openchange-2.0/apidocs/man/man3/libmapiserver_RopSyncImportDeletes_size.3000066400000000000000000000000441223057412600266550ustar00rootroot00000000000000.so man3/libmapiserver_oxcfxics.c.3 openchange-2.0/apidocs/man/man3/libmapiserver_RopSyncImportHierarchyChange_size.3000066400000000000000000000000441223057412600303140ustar00rootroot00000000000000.so man3/libmapiserver_oxcfxics.c.3 openchange-2.0/apidocs/man/man3/libmapiserver_RopSyncImportMessageChange_size.3000066400000000000000000000000441223057412600277620ustar00rootroot00000000000000.so man3/libmapiserver_oxcfxics.c.3 openchange-2.0/apidocs/man/man3/libmapiserver_RopSyncImportMessageMove_size.3000066400000000000000000000000441223057412600275030ustar00rootroot00000000000000.so man3/libmapiserver_oxcfxics.c.3 openchange-2.0/apidocs/man/man3/libmapiserver_RopSyncImportReadStateChanges_size.3000066400000000000000000000000441223057412600304350ustar00rootroot00000000000000.so man3/libmapiserver_oxcfxics.c.3 openchange-2.0/apidocs/man/man3/libmapiserver_RopSyncOpenCollector_size.3000066400000000000000000000000441223057412600266450ustar00rootroot00000000000000.so man3/libmapiserver_oxcfxics.c.3 openchange-2.0/apidocs/man/man3/libmapiserver_RopSyncUploadStateStreamBegin_size.3000066400000000000000000000000441223057412600304430ustar00rootroot00000000000000.so man3/libmapiserver_oxcfxics.c.3 openchange-2.0/apidocs/man/man3/libmapiserver_RopSyncUploadStateStreamContinue_size.3000066400000000000000000000000441223057412600312030ustar00rootroot00000000000000.so man3/libmapiserver_oxcfxics.c.3 openchange-2.0/apidocs/man/man3/libmapiserver_RopSyncUploadStateStreamEnd_size.3000066400000000000000000000000441223057412600301250ustar00rootroot00000000000000.so man3/libmapiserver_oxcfxics.c.3 openchange-2.0/apidocs/man/man3/libmapiserver_RopTransportSend_size.3000066400000000000000000000000421223057412600260440ustar00rootroot00000000000000.so man3/libmapiserver_oxomsg.c.3 openchange-2.0/apidocs/man/man3/libmapiserver_RopWriteStream_size.3000066400000000000000000000000431223057412600255050ustar00rootroot00000000000000.so man3/libmapiserver_oxcprpt.c.3 openchange-2.0/apidocs/man/man3/libmapiserver_TypedString_size.3000066400000000000000000000000431223057412600250320ustar00rootroot00000000000000.so man3/libmapiserver_oxcdata.c.3 openchange-2.0/apidocs/man/man3/libmapiserver_mapi_SPropValue_size.3000066400000000000000000000000431223057412600256240ustar00rootroot00000000000000.so man3/libmapiserver_oxcdata.c.3 openchange-2.0/apidocs/man/man3/libmapiserver_push_property.3000066400000000000000000000000431223057412600244470ustar00rootroot00000000000000.so man3/libmapiserver_oxcprpt.c.3 openchange-2.0/apidocs/man/man3/mapi_copy_spropvalues.3000066400000000000000000000000261223057412600232240ustar00rootroot00000000000000.so man3/property.c.3 openchange-2.0/apidocs/man/man3/mapi_get_cpid_from_language.3000066400000000000000000000000331223057412600242510ustar00rootroot00000000000000.so man3/codepage_lcid.c.3 openchange-2.0/apidocs/man/man3/mapi_get_cpid_from_lcid.3000066400000000000000000000000331223057412600234010ustar00rootroot00000000000000.so man3/codepage_lcid.c.3 openchange-2.0/apidocs/man/man3/mapi_get_cpid_from_locale.3000066400000000000000000000000331223057412600237250ustar00rootroot00000000000000.so man3/codepage_lcid.c.3 openchange-2.0/apidocs/man/man3/mapi_get_language_from_group.3000066400000000000000000000000331223057412600244660ustar00rootroot00000000000000.so man3/codepage_lcid.c.3 openchange-2.0/apidocs/man/man3/mapi_get_language_from_lcid.3000066400000000000000000000000331223057412600242450ustar00rootroot00000000000000.so man3/codepage_lcid.c.3 openchange-2.0/apidocs/man/man3/mapi_get_language_from_locale.3000066400000000000000000000000331223057412600245710ustar00rootroot00000000000000.so man3/codepage_lcid.c.3 openchange-2.0/apidocs/man/man3/mapi_get_lcid_from_language.3000066400000000000000000000000331223057412600242450ustar00rootroot00000000000000.so man3/codepage_lcid.c.3 openchange-2.0/apidocs/man/man3/mapi_get_lcid_from_locale.3000066400000000000000000000000331223057412600237210ustar00rootroot00000000000000.so man3/codepage_lcid.c.3 openchange-2.0/apidocs/man/man3/mapi_get_locale_from_language.3000066400000000000000000000000331223057412600245710ustar00rootroot00000000000000.so man3/codepage_lcid.c.3 openchange-2.0/apidocs/man/man3/mapi_get_locale_from_lcid.3000066400000000000000000000000331223057412600237210ustar00rootroot00000000000000.so man3/codepage_lcid.c.3 openchange-2.0/apidocs/man/man3/mapi_get_system_locale.3000066400000000000000000000000331223057412600233070ustar00rootroot00000000000000.so man3/codepage_lcid.c.3 openchange-2.0/apidocs/man/man3/mapi_handles_add.3000066400000000000000000000000321223057412600220320ustar00rootroot00000000000000.so man3/mapi_handles.c.3 openchange-2.0/apidocs/man/man3/mapi_handles_delete.3000066400000000000000000000000321223057412600225440ustar00rootroot00000000000000.so man3/mapi_handles.c.3 openchange-2.0/apidocs/man/man3/mapi_handles_get_private_data.3000066400000000000000000000000321223057412600246040ustar00rootroot00000000000000.so man3/mapi_handles.c.3 openchange-2.0/apidocs/man/man3/mapi_handles_init.3000066400000000000000000000000321223057412600222450ustar00rootroot00000000000000.so man3/mapi_handles.c.3 openchange-2.0/apidocs/man/man3/mapi_handles_release.3000066400000000000000000000000321223057412600227220ustar00rootroot00000000000000.so man3/mapi_handles.c.3 openchange-2.0/apidocs/man/man3/mapi_handles_search.3000066400000000000000000000000321223057412600225470ustar00rootroot00000000000000.so man3/mapi_handles.c.3 openchange-2.0/apidocs/man/man3/mapi_handles_set_private_data.3000066400000000000000000000000321223057412600246200ustar00rootroot00000000000000.so man3/mapi_handles.c.3 openchange-2.0/apidocs/man/man3/mapi_handles_tdb_free.3000066400000000000000000000000321223057412600230540ustar00rootroot00000000000000.so man3/mapi_handles.c.3 openchange-2.0/apidocs/man/man3/mapi_handles_tdb_update.3000066400000000000000000000000321223057412600234150ustar00rootroot00000000000000.so man3/mapi_handles.c.3 openchange-2.0/apidocs/man/man3/mapi_handles_traverse_delete.3000066400000000000000000000000321223057412600244570ustar00rootroot00000000000000.so man3/mapi_handles.c.3 openchange-2.0/apidocs/man/man3/mapi_handles_traverse_null.3000066400000000000000000000000321223057412600241670ustar00rootroot00000000000000.so man3/mapi_handles.c.3 openchange-2.0/apidocs/man/man3/mapi_id_array_add_id.3000066400000000000000000000000331223057412600226630ustar00rootroot00000000000000.so man3/mapi_id_array.c.3 openchange-2.0/apidocs/man/man3/mapi_id_array_add_obj.3000066400000000000000000000000331223057412600230410ustar00rootroot00000000000000.so man3/mapi_id_array.c.3 openchange-2.0/apidocs/man/man3/mapi_id_array_del_id.3000066400000000000000000000000331223057412600226770ustar00rootroot00000000000000.so man3/mapi_id_array.c.3 openchange-2.0/apidocs/man/man3/mapi_id_array_del_obj.3000066400000000000000000000000331223057412600230550ustar00rootroot00000000000000.so man3/mapi_id_array.c.3 openchange-2.0/apidocs/man/man3/mapi_id_array_get.3000066400000000000000000000000331223057412600222360ustar00rootroot00000000000000.so man3/mapi_id_array.c.3 openchange-2.0/apidocs/man/man3/mapi_id_array_init.3000066400000000000000000000000331223057412600224220ustar00rootroot00000000000000.so man3/mapi_id_array.c.3 openchange-2.0/apidocs/man/man3/mapi_id_array_release.3000066400000000000000000000000331223057412600230770ustar00rootroot00000000000000.so man3/mapi_id_array.c.3 openchange-2.0/apidocs/man/man3/mapi_nameid_GetIDsFromNames.3000066400000000000000000000000311223057412600240470ustar00rootroot00000000000000.so man3/mapi_nameid.c.3 openchange-2.0/apidocs/man/man3/mapi_nameid_OOM_add.3000066400000000000000000000000311223057412600223620ustar00rootroot00000000000000.so man3/mapi_nameid.c.3 openchange-2.0/apidocs/man/man3/mapi_nameid_OOM_lookup.3000066400000000000000000000000311223057412600231430ustar00rootroot00000000000000.so man3/mapi_nameid.c.3 openchange-2.0/apidocs/man/man3/mapi_nameid_SPropTagArray.3000066400000000000000000000000311223057412600236160ustar00rootroot00000000000000.so man3/mapi_nameid.c.3 openchange-2.0/apidocs/man/man3/mapi_nameid_canonical_add.3000066400000000000000000000000311223057412600236570ustar00rootroot00000000000000.so man3/mapi_nameid.c.3 openchange-2.0/apidocs/man/man3/mapi_nameid_custom_lid_add.3000066400000000000000000000000311223057412600240720ustar00rootroot00000000000000.so man3/mapi_nameid.c.3 openchange-2.0/apidocs/man/man3/mapi_nameid_custom_string_add.3000066400000000000000000000000311223057412600246300ustar00rootroot00000000000000.so man3/mapi_nameid.c.3 openchange-2.0/apidocs/man/man3/mapi_nameid_lid_add.3000066400000000000000000000000311223057412600225000ustar00rootroot00000000000000.so man3/mapi_nameid.c.3 openchange-2.0/apidocs/man/man3/mapi_nameid_lid_lookup.3000066400000000000000000000000311223057412600232610ustar00rootroot00000000000000.so man3/mapi_nameid.c.3 openchange-2.0/apidocs/man/man3/mapi_nameid_lid_lookup_canonical.3000066400000000000000000000000311223057412600252700ustar00rootroot00000000000000.so man3/mapi_nameid.c.3 openchange-2.0/apidocs/man/man3/mapi_nameid_lookup_SPropTagArray.3000066400000000000000000000000311223057412600252070ustar00rootroot00000000000000.so man3/mapi_nameid.c.3 openchange-2.0/apidocs/man/man3/mapi_nameid_lookup_SPropValue.3000066400000000000000000000000311223057412600245510ustar00rootroot00000000000000.so man3/mapi_nameid.c.3 openchange-2.0/apidocs/man/man3/mapi_nameid_map_SPropTagArray.3000066400000000000000000000000311223057412600244530ustar00rootroot00000000000000.so man3/mapi_nameid.c.3 openchange-2.0/apidocs/man/man3/mapi_nameid_map_SPropValue.3000066400000000000000000000000311223057412600240150ustar00rootroot00000000000000.so man3/mapi_nameid.c.3 openchange-2.0/apidocs/man/man3/mapi_nameid_new.3000066400000000000000000000000311223057412600217110ustar00rootroot00000000000000.so man3/mapi_nameid.c.3 openchange-2.0/apidocs/man/man3/mapi_nameid_property_lookup.3000066400000000000000000000000311223057412600243750ustar00rootroot00000000000000.so man3/mapi_nameid.c.3 openchange-2.0/apidocs/man/man3/mapi_nameid_string_add.3000066400000000000000000000000311223057412600232360ustar00rootroot00000000000000.so man3/mapi_nameid.c.3 openchange-2.0/apidocs/man/man3/mapi_nameid_string_lookup.3000066400000000000000000000000311223057412600240170ustar00rootroot00000000000000.so man3/mapi_nameid.c.3 openchange-2.0/apidocs/man/man3/mapi_nameid_string_lookup_canonical.3000066400000000000000000000000311223057412600260260ustar00rootroot00000000000000.so man3/mapi_nameid.c.3 openchange-2.0/apidocs/man/man3/mapi_nameid_unmap_SPropTagArray.3000066400000000000000000000000311223057412600250160ustar00rootroot00000000000000.so man3/mapi_nameid.c.3 openchange-2.0/apidocs/man/man3/mapi_nameid_unmap_SPropValue.3000066400000000000000000000000311223057412600243600ustar00rootroot00000000000000.so man3/mapi_nameid.c.3 openchange-2.0/apidocs/man/man3/mapi_obj_bookmark.3000066400000000000000000000005741223057412600222560ustar00rootroot00000000000000.TH "mapi_obj_bookmark" 3 "Thu Jan 24 2013" "Version 2.0" "MAPIClientLibraries" \" -*- nroff -*- .ad l .nh .SH NAME mapi_obj_bookmark \- .PP IMAPITable object\&. .SH SYNOPSIS .br .PP .PP \fC#include \fP .SH "Detailed Description" .PP IMAPITable object\&. .SH "Author" .PP Generated automatically by Doxygen for MAPIClientLibraries from the source code\&. openchange-2.0/apidocs/man/man3/mapi_obj_store.3000066400000000000000000000005641223057412600216040ustar00rootroot00000000000000.TH "mapi_obj_store" 3 "Thu Jan 24 2013" "Version 2.0" "MAPIClientLibraries" \" -*- nroff -*- .ad l .nh .SH NAME mapi_obj_store \- .PP IMsgStore object\&. .SH SYNOPSIS .br .PP .PP \fC#include \fP .SH "Detailed Description" .PP IMsgStore object\&. .SH "Author" .PP Generated automatically by Doxygen for MAPIClientLibraries from the source code\&. openchange-2.0/apidocs/man/man3/mapi_object_bookmark_debug.3000066400000000000000000000000311223057412600241040ustar00rootroot00000000000000.so man3/mapi_object.c.3 openchange-2.0/apidocs/man/man3/mapi_object_bookmark_find.3000066400000000000000000000000311223057412600237360ustar00rootroot00000000000000.so man3/mapi_object.c.3 openchange-2.0/apidocs/man/man3/mapi_object_bookmark_get_count.3000066400000000000000000000000311223057412600250050ustar00rootroot00000000000000.so man3/mapi_object.c.3 openchange-2.0/apidocs/man/man3/mapi_object_copy.3000066400000000000000000000000311223057412600221030ustar00rootroot00000000000000.so man3/mapi_object.c.3 openchange-2.0/apidocs/man/man3/mapi_object_debug.3000066400000000000000000000000311223057412600222170ustar00rootroot00000000000000.so man3/mapi_object.c.3 openchange-2.0/apidocs/man/man3/mapi_object_get_handle.3000066400000000000000000000000311223057412600232230ustar00rootroot00000000000000.so man3/mapi_object.c.3 openchange-2.0/apidocs/man/man3/mapi_object_get_id.3000066400000000000000000000000311223057412600223640ustar00rootroot00000000000000.so man3/mapi_object.c.3 openchange-2.0/apidocs/man/man3/mapi_object_get_logon_id.3000066400000000000000000000000311223057412600235620ustar00rootroot00000000000000.so man3/mapi_object.c.3 openchange-2.0/apidocs/man/man3/mapi_object_get_session.3000066400000000000000000000000311223057412600234530ustar00rootroot00000000000000.so man3/mapi_object.c.3 openchange-2.0/apidocs/man/man3/mapi_object_init.3000066400000000000000000000000311223057412600220740ustar00rootroot00000000000000.so man3/mapi_object.c.3 openchange-2.0/apidocs/man/man3/mapi_object_is_invalid.3000066400000000000000000000000311223057412600232520ustar00rootroot00000000000000.so man3/mapi_object.c.3 openchange-2.0/apidocs/man/man3/mapi_object_release.3000066400000000000000000000000311223057412600225510ustar00rootroot00000000000000.so man3/mapi_object.c.3 openchange-2.0/apidocs/man/man3/mapi_object_set_handle.3000066400000000000000000000000311223057412600232370ustar00rootroot00000000000000.so man3/mapi_object.c.3 openchange-2.0/apidocs/man/man3/mapi_object_set_id.3000066400000000000000000000000311223057412600224000ustar00rootroot00000000000000.so man3/mapi_object.c.3 openchange-2.0/apidocs/man/man3/mapi_object_set_logon_id.3000066400000000000000000000000311223057412600235760ustar00rootroot00000000000000.so man3/mapi_object.c.3 openchange-2.0/apidocs/man/man3/mapi_object_set_logon_store.3000066400000000000000000000000311223057412600243360ustar00rootroot00000000000000.so man3/mapi_object.c.3 openchange-2.0/apidocs/man/man3/mapi_object_set_session.3000066400000000000000000000000311223057412600234670ustar00rootroot00000000000000.so man3/mapi_object.c.3 openchange-2.0/apidocs/man/man3/mapi_object_table_init.3000066400000000000000000000000311223057412600232430ustar00rootroot00000000000000.so man3/mapi_object.c.3 openchange-2.0/apidocs/man/man3/mapi_profile_add_string_attr.3000066400000000000000000000000301223057412600244720ustar00rootroot00000000000000.so man3/IProfAdmin.c.3 openchange-2.0/apidocs/man/man3/mapi_profile_delete_string_attr.3000066400000000000000000000000301223057412600252040ustar00rootroot00000000000000.so man3/IProfAdmin.c.3 openchange-2.0/apidocs/man/man3/mapi_profile_get_ldif_path.3000066400000000000000000000000301223057412600241130ustar00rootroot00000000000000.so man3/IProfAdmin.c.3 openchange-2.0/apidocs/man/man3/mapi_profile_modify_string_attr.3000066400000000000000000000000301223057412600252310ustar00rootroot00000000000000.so man3/IProfAdmin.c.3 openchange-2.0/apidocs/man/man3/mapi_recipients_RecipientFlags.3000066400000000000000000000000261223057412600247330ustar00rootroot00000000000000.so man3/IMessage.c.3 openchange-2.0/apidocs/man/man3/mapi_verify_cpid.3000066400000000000000000000000331223057412600221100ustar00rootroot00000000000000.so man3/codepage_lcid.c.3 openchange-2.0/apidocs/man/man3/mapiadmin_ctx.3000066400000000000000000000005731223057412600214250ustar00rootroot00000000000000.TH "mapiadmin_ctx" 3 "Thu Jan 24 2013" "Version 2.0" "libmapiadmin" \" -*- nroff -*- .ad l .nh .SH NAME mapiadmin_ctx \- .PP MAPI admin function context\&. .SH SYNOPSIS .br .PP .PP \fC#include \fP .SH "Detailed Description" .PP MAPI admin function context\&. .SH "Author" .PP Generated automatically by Doxygen for libmapiadmin from the source code\&. openchange-2.0/apidocs/man/man3/mapiadmin_init.3000066400000000000000000000000321223057412600215600ustar00rootroot00000000000000.so man3/libmapiadmin.h.3 openchange-2.0/apidocs/man/man3/mapiadmin_release.3000066400000000000000000000000321223057412600222350ustar00rootroot00000000000000.so man3/libmapiadmin.h.3 openchange-2.0/apidocs/man/man3/mapiadmin_user_add.3000066400000000000000000000000321223057412600224030ustar00rootroot00000000000000.so man3/libmapiadmin.h.3 openchange-2.0/apidocs/man/man3/mapiadmin_user_del.3000066400000000000000000000000321223057412600224170ustar00rootroot00000000000000.so man3/libmapiadmin.h.3 openchange-2.0/apidocs/man/man3/mapiadmin_user_extend.3000066400000000000000000000000321223057412600231420ustar00rootroot00000000000000.so man3/libmapiadmin.h.3 openchange-2.0/apidocs/man/man3/mapiconcepts.3000066400000000000000000000041221223057412600212670ustar00rootroot00000000000000.TH "mapiconcepts" 3 "Thu Jan 24 2013" "Version 2.0" "MAPIClientLibraries" \" -*- nroff -*- .ad l .nh .SH NAME mapiconcepts \- MAPI Concepts .SS "MAPI objects" .PP Almost any MAPI data you access, read or edit is associated with an object\&. No matter whether you intend to browse mailbox hierarchy, open folders, create tables or access items (messages, appointments, contacts, tasks, notes), you will have to initialize and use MAPI objects: \fIobject understanding and manipulation is fundamental\fP\&. .PP .IP "\(bu" 2 When developing MAPI clients with Microsoft framework, instantiated objects inherit from parent classes\&. As a matter of fact, developers know which methods they can apply to objects and we suppose it makes their life easier\&. .IP "\(bu" 2 In OpenChange, objects are opaque\&. They are generic data structures which content is set and accessed through MAPI public functions\&. Therefore, Linux MAPI developers must know what they are doing\&. .PP .PP An example of MAPI object manipulation is shown below: .PP .nf mapi_object obj_store; [\&.\&.\&.] mapi_object_init(&obj_store); retval = OpenMsgStore(&obj_store); if (retval != MAPI_E_SUCCESS) { mapi_errstr('OpenMsgStore', GetLastError()); exit (1); } mapi_object_release(&obj_store); .fi .PP .PP .SS "MAPI Handles" .PP Beyond memory management considerations, understanding MAPI handles role in object manipulation provides a better understanding why \fBmapi_object_release()\fP matters\&. .PP Handles are temporary identifiers returned by Exchange when you access or create objects on the server\&. They are used to make reference to a particular object all along its session lifetime\&. They are stored in unsigned integers, are unique for each object but temporary along MAPI session\&. Handles are the only links between objects accessed on the client side and efficiently stored on the server side\&. .PP Although OpenChange MAPI makes handles manipulation transparent for developers, \fBmapi_object_release()\fP frees both the allocated memory for the object on client side, but also releases the object on the server\&. openchange-2.0/apidocs/man/man3/mapidump_PAB_entry.3000066400000000000000000000000261223057412600223200ustar00rootroot00000000000000.so man3/mapidump.c.3 openchange-2.0/apidocs/man/man3/mapidump_SPropValue.3000066400000000000000000000000261223057412600225350ustar00rootroot00000000000000.so man3/mapidump.c.3 openchange-2.0/apidocs/man/man3/mapidump_appointment.3000066400000000000000000000000261223057412600230330ustar00rootroot00000000000000.so man3/mapidump.c.3 openchange-2.0/apidocs/man/man3/mapidump_contact.3000066400000000000000000000000261223057412600221300ustar00rootroot00000000000000.so man3/mapidump.c.3 openchange-2.0/apidocs/man/man3/mapidump_date_SPropValue.3000066400000000000000000000000261223057412600235320ustar00rootroot00000000000000.so man3/mapidump.c.3 openchange-2.0/apidocs/man/man3/mapidump_languages_list.3000066400000000000000000000000261223057412600234760ustar00rootroot00000000000000.so man3/mapidump.c.3 openchange-2.0/apidocs/man/man3/mapidump_message.3000066400000000000000000000000261223057412600221210ustar00rootroot00000000000000.so man3/mapidump.c.3 openchange-2.0/apidocs/man/man3/mapidump_message_summary.3000066400000000000000000000000261223057412600236760ustar00rootroot00000000000000.so man3/mapidump.c.3 openchange-2.0/apidocs/man/man3/mapidump_note.3000066400000000000000000000000261223057412600214420ustar00rootroot00000000000000.so man3/mapidump.c.3 openchange-2.0/apidocs/man/man3/mapidump_task.3000066400000000000000000000000261223057412600214370ustar00rootroot00000000000000.so man3/mapidump.c.3 openchange-2.0/apidocs/man/man3/mapiproxy-documentation.3000066400000000000000000001330021223057412600235010ustar00rootroot00000000000000.TH "mapiproxy-documentation" 3 "Thu Jan 24 2013" "Version 2.0" "MAPIProxy" \" -*- nroff -*- .ad l .nh .SH NAME mapiproxy-documentation \- .PP .SH "Contents" .PP .PD 0 .IP "\(bu" 2 \fCRevision History \fP .IP "\(bu" 2 \fC1\&. Introduction \fP .PD 0 .IP " \(bu" 4 \fC1\&.1\&. Purpose and Scope\fP .IP " \(bu" 4 \fC1\&.2\&. General Overview\fP .IP " \(bu" 4 \fC1\&.3\&. Bugs and Limitations \fP .PP .IP "\(bu" 2 \fC2\&. Installation\fP .PD 0 .IP " \(bu" 4 \fC2\&.1\&. Download MAPIProxy\fP .IP " \(bu" 4 \fC2\&.2\&. Samba4 installation\fP .IP " \(bu" 4 \fC2\&.3\&. MAPIProxy installation\fP .PP .IP "\(bu" 2 \fC3\&. Configuration\fP .PD 0 .IP " \(bu" 4 \fC3\&.1\&. 5-Minute Configuration\fP .PP .IP "\(bu" 2 \fC4\&. Technical Concepts\fP .PD 0 .IP " \(bu" 4 \fC4\&.1\&. NSPI Bindings Replacement\fP .IP " \(bu" 4 \fC4\&.2\&. NSPI Referral FQDN Replacement\fP .IP " \(bu" 4 \fC4\&.3\&. Force EMSMDB Protocol Version\fP .IP " \(bu" 4 \fC4\&.4\&. OpenChange IDL file\fP .PP .IP "\(bu" 2 \fC5\&. Stackable Modules \fP .PD 0 .IP " \(bu" 4 \fC5\&.1\&. General Overview\fP .IP " \(bu" 4 \fC5\&.2\&. Module entry point\fP .IP " \(bu" 4 \fC5\&.3\&. Module Hooks\fP .IP " \(bu" 4 \fC5\&.4\&. mapiproxy structure\fP .PP .IP "\(bu" 2 \fC6\&. Available Modules \fP .PD 0 .IP " \(bu" 4 \fC6\&.1\&. Downgrade Module\fP .IP " \(bu" 4 \fC6\&.2\&. Pack Module\fP .IP " \(bu" 4 \fC6\&.3\&. Cache Module\fP .PP .IP "\(bu" 2 \fC7\&. Server Mode \fP .PD 0 .IP " \(bu" 4 \fC7\&.1\&. 5-Minute Configuration\fP .IP " \(bu" 4 \fC7\&.2\&. General Overview \fP .PP .IP "\(bu" 2 \fC8\&. Frequently Asked Questions\fP .PD 0 .IP " \(bu" 4 \fC8\&.1\&. The action could not be completed\fP .IP " \(bu" 4 \fC8\&.2\&. Profile creation goes fine, but Outlook can't open your default e-mail folders\fP .IP " \(bu" 4 \fC8\&.3\&. Does MAPIProxy need to be domain controller?\fP .IP " \(bu" 4 \fC8\&.4\&. Generating Samba's private keys takes infinite time\fP .IP " \(bu" 4 \fC8\&.5\&. On Ubuntu \fImake samba-git\fP exits with \fIgmake: not found\fP\fP .PP .PP .br .PP .SS "Revision History" .PP \fBDate\fP \fBRevision Number\fP \fBAuthor\fP \fBRevision Content\fP 27/11/2010 \fB0\&.6\&.3\fP Brad Hards Fix tracker link and a couple of typos\&. 03/03/09 \fB0\&.6\&.2\fP Julien Kerihuel Add configuration info for server mode\&. 01/02/09 \fB0\&.6\&.1\fP Julien Kerihuel Add configuration info for server mode\&. 04/01/09 \fB0\&.6\fP Julien Kerihuel server mode documented, update mapiproxy naming to MAPIProxy\&. 29/12/08 \fB0\&.5\&.5\fP Julien Kerihuel Add 3 new questions to FAQ section 09/12/08 \fB0\&.5\&.4\fP Julien Kerihuel Add dcesrv:assoc group checking to smb\&.conf configuration requirements 10/07/08 \fB0\&.5\&.3\fP Julien Kerihuel Rename smbd process to samba session API and update documentation 08/26/08 \fB0\&.5\&.2\fP Julien Kerihuel documentation update on NSPI replacement and new FAQ question added 08/26/08 \fB0\&.5\&.1\fP Julien Kerihuel documentation on NSPI referral added 08/11/08 \fB0\&.5\fP Julien Kerihuel unbind hook added, cache module documentation and scenario added 07/23/08 \fB0\&.4\fP Julien Kerihuel MAPIProxy API hooks, IDL update, mapiproxy structure description and documentation added for the cache module 06/25/08 \fB0\&.3\&.2\fP Julien Kerihuel Minor installation update 06/04/08 \fB0\&.3\&.1\fP Brad Hards Minor edits 05/27/08 \fB0\&.3\fP Julien Kerihuel Available modules section added 05/24/08 \fB0\&.2\fP Julien Kerihuel EMSMDB protocol version subsection updated, modules system section added, 5-minute configuration updated 05/15/08 \fB0\&.1\fP Julien Kerihuel Initial Revision .br .PP .SS "1\&. Introduction" .PP .SS "1\&.1\&. Purpose and Scope" .PP MAPIProxy is an endpoint server for Samba4 which proxies ExchangeRPC traffic from MAPI clients (Outlook, openchangeclient, etc\&.) to Microsoft Exchange Server (and back)\&. It can either act as a transparent proxy, for hacking, monitoring or debugging purposes or modify traffic on the fly and so provide new features\&. It is primarily developed for - but not limited to - third-party implementors looking for a development framework they can use for MAPI acceleration purposes\&. .PP This project is originally based on dcerpc_remote\&.c code from Stefan Metzemacher (Samba4 trunk) and is released under GPLv3 or later\&. It creates a dynamic shared object file which is loaded into samba and uses the Samba configuration file (smb\&.conf) to set common options\&. .PP .br .SS "1\&.2\&. General overview" .PP Figure 1\&. General MAPIProxy network overview .PP The MAPIProxy traffic can be divided into 3 different parts as described in the figure above: .PP .PD 0 .IP "\(bu" 2 \fB[1] clients to MAPIProxy:\fP .br The origin of a client connect does not have much importance: it can either be an incoming connection from a real MAPI client, a connection relayed from another third-party proxy or another MAPIProxy instance\&. MAPIProxy runs as an endpoint server registered when samba starts\&. When the Samba4 endpoint mapper receives an incoming connection asking for one of the ExchangeRPC endpoints: NSPI (Name Service Provider Interface - Address Book) or EMSMDB (Exchange Message Store), the endpoint mapper redirects ExchangeRPC traffic to MAPIProxy which will pull, push and dispatch MAPI operations\&. .PP .IP "\(bu" 2 \fB[2] MAPIProxy to MAPIProxy:\fP .br The main objective of MAPIProxy is not to directly connect to the remote message server, but rather to relay some kind of modified MAPI traffic to the next MAPIProxy hop\&. This configuration can be used to add a compression layer between MAPIProxy instances, or to send specific third-party vendor information\&. However, a proxied connection directly from a MAPI client to an Exchange server (i\&.e\&. \fIclient-MAPIProxy-server\fP is possible and such a configuration could be used for many other purposes\&. .br .PP .IP "\(bu" 2 \fB[3] MAPIProxy to server:\fP .br This last node is responsible for restoring MAPI contents and pushing it to the real Exchange server\&. .PP .br .PP .SS "1\&.3\&. Bugs and Limitations" .PP If you find bugs, limitations or have features you would like to see included in MAPIProxy, please register on the \fCOpenChange Tracker System\fP and create new tickets\&. .br .PP .SS "2\&. Installation" .PP .SS "2\&.1\&. Download MAPIProxy" .PP MAPIProxy is only available through SVN at the moment\&. A tarball release will only be made when we have a stabilized API with a preliminary set of useful features\&. You will need a \fCSVN client\fP to download openchange (including MAPIProxy)\&. .PP .PP .nf $ svn co https://svn\&.openchange\&.org/openchange/trunk openchange .fi .PP .PP .SS "2\&.2\&. Samba4 installation" .PP The MAPIProxy implementation requires a very recent Samba4 version in order to run properly\&. If Samba4 is planned to be installed from scratch for MAPIProxy only, please use the \fImake samba-git\fP compilation rule provided in the build system\&. This command will automate most part of the samba4 installation process\&. The only requirement for this step is to have an up to date \fCGIT version\fP installed on the system\&. .PP .PP .nf # make samba-git .fi .PP .PP When the installation process is finished, a running samba4 installation will be located in \fI/usr/local/samba/\fP\&. You will possibly be required to run \fIldconfig\fP before you move to next steps\&. Please refer to \fIdoc/howto\&.txt\fP for further information on openchange compilation\&. .br .PP .SS "2\&.3\&. MAPIProxy installation" .PP If you have existing OpenChange DSO in the \fI/usr/local/samba/modules/dcerpc_server/\fP folder, such as \fIdcesrv_exchange\&.so\fP, \fBplease remove them prior loading samba with MAPIProxy\&.\fP .PP .PP .nf $ \&./autogen\&.sh $ \&./configure --prefix=/usr/local/samba $ make # make install # rm -rf /usr/local/samba/modules/dcerpc_server/dcesrv_exchange\&.so .fi .PP .PP .br .PP .SS "3\&. Configuration" .PP .SS "3\&.1\&. 5-Minute Configuration" .PP This 5-Minute configuration will help you set up a minimal MAPIProxy using specified credentials and relaying traffic from Outlook clients to a remote Exchange server\&. This configuration will be performed in three steps: .PP .PD 0 .IP "\(bu" 2 \fB[1] Provision Samba\fP: .br From samba4/source4 directory, run under the root account: .PP .nf # \&./setup/provision --realm=OPENCHANGE\&.LOCAL --domain=OPENCHANGE \ --adminpass=openchange --server-role='domain controller' .fi .PP .PP If you don't have DNS resolution and your realm can't be resolved, samba will be unable to authenticate the user in its user database\&. You must specify a realm which MAPI clients and MAPIProxy can resolve\&. .PP If everything works fine, the provisioning script will have created all the databases, populated the AD (Active Directory) and generated a valid smb\&.conf file\&. .PP .IP "\(bu" 2 \fB[2] Add a user account\fP: .br .PP In this configuration, we'll set the same credentials both for the user in the windows domain and on the Samba4 server\&. Let say there is already a user named \fItestuser\fP with its password set to \fIopenchange\fP on the Exchange server: .PP .nf # \&./setup/newuser testuser New Password: openchange .fi .PP .PP .IP "\(bu" 2 \fB[3] Configure MAPIProxy options\fP: .br .PP In this final step, we only need to customize a small set of parameters: .PD 0 .IP " \(bu" 4 \fBdcerpc endpoint servers\fP: .br MUST include epmapper and mapiproxy separated with comma\&. .PP .IP " \(bu" 4 \fBdcerpc_mapiproxy:binding\fP: .br This is the binding string used to connect to the remote Exchange server\&. The format of this string is: transport:address[flags]\&. In the example below, we'll be using the TCP over IP transport, connect on 192\&.168\&.1\&.1 and add the print flag so MAPI packets get dissected on samba stdout (or logfile)\&. .PP .IP " \(bu" 4 \fBdcerpc_mapiproxy:username\fP and \fBdcerpc_mapiproxy:password\fP: .br The specified credentials we will be using to connect to the remote Exchange server\&. .PP .IP " \(bu" 4 \fBdcerpc_mapiproxy:domain\fP: .br The Windows domain the remote Exchange server belongs to\&. .PP .IP " \(bu" 4 \fBdcerpc_mapiproxy:interfaces\fP: .br In our case, we want to relay the whole ExchangeRPC traffic, so we need to load both the EMSMDB and NSP interface\&. In the meantime, people interested in NSPI proxy only would only have to load the exchange_nsp interface\&. .PP .IP " \(bu" 4 \fBdcerpc_mapiproxy:modules\fP: .br MAPIProxy provides a stackable modular system which primary objective is to provide developers an API for modules development\&. In our case we want to activate the \fIdowngrade\fP module responsible for the EcDoConnect/EcDoRpc EMSMDB RPC functions negotiation\&. .PP .PP .PP .PP .nf [globals] netbios name = MAPIPROXY workgroup = OPENCHANGE realm = OPENCHANGE\&.LOCAL server role = domain controller ### Configuration required by mapiproxy ### dcesrv:assoc group checking = false dcerpc endpoint servers = epmapper, mapiproxy dcerpc_mapiproxy:binding = ncacn_ip_tcp:192\&.168\&.1\&.1[print] dcerpc_mapiproxy:username = testuser dcerpc_mapiproxy:password = openchange dcerpc_mapiproxy:domain = EXCHANGE dcerpc_mapiproxy:interfaces = exchange_emsmdb, exchange_nsp, exchange_ds_rfr dcerpc_mapiproxy:modules = downgrade ### Configuration required by mapiproxy ### [netlogon] path = /usr/local/samba/var/locks/sysvol/openchange\&.local/scripts read only = no [sysvol] path = /usr/local/samba/var/locks/sysvol read only = no .fi .PP .PP .PP We are now ready to run samba: .PP .nf # samba -d5 -i -M single .fi .PP .PP If everything works properly, the following lines should be displayed in samba output: .PP .nf DCERPC endpoint server 'exchange_emsmdb' registered DCERPC endpoint server 'exchange_nsp' registered DCERPC endpoint server 'exchange_ds_rfr' registered DCERPC endpoint server 'mapiproxy' registered dcesrv_interface_register: interface 'epmapper' registered on endpoint 'ncacn_np:[\pipe\epmapper]' dcesrv_interface_register: interface 'epmapper' registered on endpoint 'ncacn_ip_tcp:[135]' dcesrv_interface_register: interface 'epmapper' registered on endpoint 'ncalrpc:[EPMAPPER]' MAPIPROXY module 'downgrade' registered MAPIPROXY module 'downgrade' loaded mapiproxy_module_load 'downgrade' (Downgrade EMSMDB protocol version EcDoConnect/EcDoRpc) dcesrv_interface_register: interface 'exchange_emsmdb' registered on endpoint 'ncacn_np:[\pipe\lsass]' dcesrv_interface_register: interface 'exchange_emsmdb' registered on endpoint 'ncacn_np:[\pipe\protected_storage]' dcesrv_interface_register: interface 'exchange_emsmdb' registered on endpoint 'ncacn_ip_tcp:' dcesrv_interface_register: interface 'exchange_nsp' registered on endpoint 'ncacn_np:[\pipe\lsass]' dcesrv_interface_register: interface 'exchange_nsp' registered on endpoint 'ncacn_np:[\pipe\protected_storage]' dcesrv_interface_register: interface 'exchange_nsp' registered on endpoint 'ncacn_ip_tcp:[]' dcesrv_interface_register: interface 'exchange_ds_rfr' registered on endpoint 'ncacn_np:[\pipe\lsass]' dcesrv_interface_register: interface 'exchange_ds_rfr' registered on endpoint 'ncacn_np:[\pipe\protected_storage]' dcesrv_interface_register: interface 'exchange_ds_rfr' registered on endpoint 'ncacn_ip_tcp:[]' .fi .PP .PP \fBYou should now be able to configure Outlook to use an Exchange account with the proxy IP address and run Outlook seamlessly (both online or cached exchange mode)\&.\fP .br .PP .SS "4\&. Technical Concepts" .PP .SS "4\&.1\&. NSPI Bindings Replacement" .PP When Outlook sets up an Exchange account using either the mail applet from the configuration panel or the account editor within Outlook, it uses the NSPI protocol (Name Service Provider Interface, effectively the address book provider)\&. In this case, NSPI is used to resolve the Exchange username and fetch from Exchange server all information needed by Outlook to initiate direct connection to the EMSMDB pipe (effectively the message store) the next time it connects to the server\&. .br .PP At some point of the profile's creation process, Outlook queries Exchange for some specific connection information using the \fBNspiGetProps (0x9) RPC operation \fP\&. More specifically, when Outlook requests for the \fBPR_EMS_AB_NETWORK_ADDRESS\fP MAPI property, Exchange returns a list \fBbinding strings\fP\&. Outlook next stores these binding strings at some location - associated to the Outlook profile - in the windows registry and uses them for future connections\&. .br .PP Outlook can also rely on other information returned by NSPI functions and connect to the real Exchange server rather than MAPIProxy\&. Such case occurs when Outlook is able to resolve the exchange server using its hostname\&. This reference to the original Exchange server can be found when Outlook requests for the \fBPR_EMS_AB_HOME_MDB\fP MAPI property during the \fBNspiQueryRows (0x3) RPC operation\fP\&. MAPIProxy replaces the Exchange server name with its own netbios name and forward the reply to the client\&. .br .PP In the meantime, this information is next used by Outlook to query a minimal entry ID for a distinguished name using this server name\&. MAPIProxy needs to substitute the server name in the inbound request string with the original exchange one\&. .br .PP MAPIProxy needs to avoid Outlook clients being aware of this remote server address and trying to communicate directly with the remote server instead of using the proxy\&. In order to do this, MAPIProxy alters the Outlook-Exchange MAPI traffic and replaces these binding strings with the MAPIProxy FQDN and netbios name\&. .PP .br .SS "4\&.2\&. NSPI Referral Replacement" .PP The Address Book Name Service Provider Interface (NSPI) Referral Service is a service used by Outlook to retrieve the name of an NSPI server\&. No NSPI connection should be initiated without first querying for the correct NSPI server\&. In this case, RFR returns the fully qualified domain name of the real Exchange server and starts using it if available\&. .br .PP MAPIProxy needs to avoid Outlook clients being aware of this server address and trying to communicate directly with the remote server instead of using the proxy\&. In order to do this, MAPIProxy alters the Outlook-Exchange MAPI traffic and replaces the server DN returned by \fBRfrGetNewDSA (0x0) RPC operation\fP with the MAPIProxy realm as specified in smb\&.conf\&. .PP .br .SS "4\&.3\&. Force EMSMDB Protocol Version" .PP When Outlook starts and presumably calls MapiLogonEx, it first opens a connection to the Exchange server on the NSPI pipe, then on the EMSMDB pipe\&. Under Outlook 2003, the very first EMSMDB RPC call Outlook makes can be considered as a kind of \fIprotocol version negotiation\fP\&. Depending on which version of Outlook is used, and how the Exchange server replies to the EMSMDB connect request, Outlook will either keep using the same pool of RPC calls or downgrade\&. .PP For example Outlook 2003 (default behavior) tests if the remote server supports the 2 new EMSMDB calls (EcDoConnectEx/EcDoRpcExt2) introduced in Exchange 2003\&. If Exchange replies to the EcDoConnectEx request with a dcerpc_fault, it means the server does not support the RPC operation, presumably has a version before 2003, and Outlook needs to downgrade its version in order to communicate with the server: .PD 0 .IP "\(bu" 2 EcDoConnectEx (0xa) call .PD 0 .IP " \(bu" 4 On success, Outlook will use EcDoRpcExt2 (0xb) to handle MAPI traffic .IP " \(bu" 4 On failure (dcerpc_fault: nca_op_rng_error), Outlook calls EcDoConnect (0x0) and use EcDoRpc (0x2) to handle MAPI traffic .PP .PP .PP If MAPIProxy runs in an environment with Outlook clients and Exchange servers using a version above 2003, a last step is required to successfully use Outlook\&. The EcDoConnect RPC reply returns the Exchange server version (as an array of 3 short integers)\&. When Outlook detects this particular server version, it automatically closes the connection and keep requesting indefinitely for EcDoConnectEx\&. To deal with this, MAPIProxy modifies the EcDoConnect reply sent by Exchange and replaces the server version with a one equal to that sent by Exchange 2000\&. .PP In the meantime, if we reproduce this test with Outlook 2000 which doesn't support these 2 new RPC calls, Outlook will directly call EcDoConnect\&. .PP The main difference between the EcDoConnectEx/EcDoRpcExt2 operations and the EcDoConnect/EcDoRpc operations is that the former use both XOR 0xA5 obfuscation and LZ77 compression/Direct2 encoding; while the latter only use the XOR obfuscation to handle MAPI content\&. If MAPIProxy wants to act as an intelligent proxy (for example, to be able to analyze MAPI content on the fly, compress MAPI data etc), receiving non compressed MAPI traffic would probably improve the overall process\&. .PP Below is a list of Exchange/Outlook pairs and the EMSMDB connect function they will use by default: \fBExchange version\fP \fBOutlook version\fP \fBEMSMDB connect function\fP 5\&.5/2000 any EcDoConnect (0x0) 2003 2000 EcDoConnect (0x0) 2007 2000 EcDoConnect (0x0) .br Microsoft officially says it is unsupported 2003 2003-2007 EcDoConnectEx (0xa) 2007 2003 EcDoConnectEx (0xa) 2007 2007 EcDoConnectEx (0xa) .PP MAPIProxy reproduces the Exchange 2000 behavior and prevents Outlook from communicating with the Exchange server using the EcDoConnectEx/EcDoRpcExt2 as described in Figure 2 below\&. When Outlook sends an EcDoConnectEx request, MAPIProxy does not relay the request to the remote Exchange server and immediately returns a dcerpc_fault to Outlook\&. Outlook, assuming the server doesn't support this call uses EcDoConnect instead\&. From this call, MAPIProxy relay the information to Exchange\&. .PP Figure 2\&. MAPIProxy behavior on Outlook EMSMDB connection .PP From the Exchange side, the server will analyze this EcDoConnect request as a call sent by Outlook 2000 or below version\&. Exchange works fine using this protocol version unless Exchange 2007 SP1 which appears to introduce client version restrictions \fIby default\fP\&. In the meantime, existing tests demonstrate similar restrictions would apply to Outlook 2003 connection (without MAPIProxy) and prevent Outlook version before 2007 connecting to Exchange 2007\&. Further information and solution is available at the following addresses: .PD 0 .IP "\(bu" 2 \fCEarlier Outlook clients cant connect to Exchange 2007 Server\fP .IP "\(bu" 2 \fCExchange 12 and Public Folders\fP .PP .br .PP .SS "4\&.4\&. OpenChange IDL File " .PP IDL stands for Interface Definition Language and OpenChange uses this format to describe ExchangeRPC communications\&. This file is processed by pidl (Perl IDL compiler provided by Samba4) which turns this protocol description into C-code dealing with the push, pull and print operations\&. .PP OpenChange development policy in trunk used to push a new MAPI call in the IDL only when the associated libmapi implementation and mapitest unit is developed, but this was preventing from distributing MAPIProxy with further openchange releases\&. Furthermore, the OpenChange IDL is now almost complete and merging back to the trunk helps improving libmapi reliability\&. .PP .br .PP .SS "5\&. Stackable Modules" .PP .SS "5\&.1\&. General Overview" .PP The MAPIProxy stackable modules system provides implementers a development framework to add new features\&. This stackable mechanism allows developers to write modules with a very specific scope of which modifications will transparently be relayed to the next module until it is finally pushed by MAPIProxy to the next hop (Figure 3\&.)\&. .PP Figure 3\&. MAPIProxy module stack and EcDoRpc interaction .PP With this system, developers can focus their effort on ExchangeRPC traffic - or any other protocol samba supports - interception, modification, analysis and avoid spending time on implementing a new endpoint server\&. Furthermore it provides an easier way for implementers to divide the work in smaller units and develop each of them in a separated module\&. .br .PP MAPIProxy modules are dynamic shared objects with an entry point and a limited set of hooks\&. These modules have to be installed in the \fIdcerpc_mapiproxy\fP folder within the samba4 modules directory (e\&.g\&. \fI/usr/local/samba/modules\fP)\&. MAPIProxy modules specified in the Samba configuration file (smb\&.conf) will be loaded into MAPIProxy at runtime and interact with each other in the same order they were defined: .PP .PP .nf dcerpc_mapiproxy:modules = downgrade,dummy .fi .PP .PP All MAPIProxy modules will be registered but only those specified on the \fBdcerpc_mapiproxy:modules\fP parametric option line will be added to the chained list of effective modules\&. .br .br .PP .SS "5\&.2\&. Module entry point" .PP MAPIProxy modules must have an entry point function named \fBsamba_init_module\fP\&. This function needs to set general information about the module, specify the module's hooks and finally call the \fBmapiproxy_module_register\fP function to register itself in the MAPIProxy module subsystem\&. .PP .PP .nf NTSTATUS samba_init_module(void) { struct mapiproxy_module module; NTSTATUS ret; /* Fill in our name */ module\&.name = 'sample'; module\&.description = 'A sample module'; module\&.endpoint = 'any'; /* Fill in all the operations */ module\&.init = sample_init; module\&.push = sample_push; module\&.ndr_pull = sample_ndr_pull; module\&.pull = sample_pull; module\&.dispatch = NULL; module\&.unbind = NULL; /* Register ourselves with the MAPIPROXY subsytem */ ret = mapiproxy_module_register(&module); if (!NT_STATUS_IS_OK(ret)) { DEBUG(0, ('Failed to register 'sample' mapiproxy module!\n')); return ret; } return ret; } .fi .PP .PP .PD 0 .IP "\(bu" 2 \fBmodule\&.name\fP: .br This is the module name\&. This name will be used by dcerpc_mapiproxy:modules in smb\&.conf to load the module .PP .IP "\(bu" 2 \fBmodule\&.description\fP: .br This field lets developers specify a brief module description for information purpose only\&. .PP .IP "\(bu" 2 \fBmodule\&.endpoint\fP: .br This field defines the interface which this module is designed to work with\&. The primary objective is to avoid calling the module hooks if the module doesn't have any impact on the requests or replies\&. For example, a module only interacting with the EcDoRpc function should define \fIexchange_emsmdb\fP\&. .PP In the meantime, it can happen that a module requires to interact with more than a single interface\&. In such case, use the '\fBany\fP' keyword which will call the modules functions with any endpoints proxied by MAPIProxy\&. .PP .PP .SS "5\&.3\&. Module Hooks" .PP MAPIProxy offers a set of hooks which modules can implement to modify/change/alter client to server MAPI traffic\&. The figure below shows how and when hooks are called during a request/response lifetime\&. .PP Figure 4\&. Usage of MAPIProxy Hooks during a request/response life time .PP .PD 0 .IP "\(bu" 2 \fBinit\fP: This is the initialization function for the module which is only called once - when the module is loaded\&. It is generally used to retrieve smb\&.conf parametric options for the module and initialize some global structures .PP .IP "\(bu" 2 \fBpull\fP: This is the function called when MAPIProxy receives a MAPI request\&. The request has already been extracted and its information filled into MAPI structures .PP .IP "\(bu" 2 \fBpush\fP: This is the function called when MAPIProxy receive a MAPI response\&. The response has already been extracted and its information filled into MAPI structures .PP .IP "\(bu" 2 \fBdispatch\fP: Similarly to the MAPIProxy top-level dispatch function, it is used to dispatch the information\&. This function is called after the pull but before the push\&. Moreover it is called before the request is forward to the remote endpoint\&. .PP .IP "\(bu" 2 \fBndr_pull\fP: This is the function called before data from a request is extracted from the NDR blob\&. .PP .IP "\(bu" 2 \fBndr_push\fP: This is the function called before data from a response is extracted from the NDR blob\&. .PP .IP "\(bu" 2 \fBunbind\fP: This is the function called when the connection closes\&. It can be used to free data associated to a given session and stored within a module global list\&. .PP .PP .PP \fBPlease note that the module API is still under development and is likely to change in further revisions\&.\fP .PP .SS "5\&.4\&. mapiproxy structure " .PP MAPIProxy uses a structure modules can modify in their dispatch routine and which impact on the general MAPIProxy behavior\&. .PP Figure 5\&. overview of mapiproxy structure variables scope .PP .PD 0 .IP "\(bu" 2 \fBnorelay\fP: This boolean variable can be used by modules to tell MAPIProxy not to relay the incoming \fBrequest\fP to the remote server through \fIdcerpc_ndr_request()\fP but directly jump to the push (response) MAPIProxy code\&. This variable is for example in use within the cache module when we read stream from the local filesystem and play it back to MAPI clients\&. .PP .IP "\(bu" 2 \fBahead\fP: This boolean variable can be used by modules to tell MAPIProxy not to relay the incoming \fBresponse\fP to the client through the \fIpush\fP and \fIdcerpc_ndr_request\fP routine but loop over the dispatch routine\&. This variable is for example in use within the cache module when we want to read a stream ahead from Exchange server to the remote MAPIProxy instance\&. .PP .PP .PP .br .PP .SS "6\&. Available Modules " .PP .SS "6\&.1\&. Downgrade Module" .PP The \fBdowngrade\fP module implements the EcDoConnect/EcDoRpc negotiation as described in \fCsection 4\&.2\fP\&. It ensures Outlook will not send compressed information or use functions other than EcDoRpc for EMSMDB transport\&. In order to use the downgrade module, edit smb\&.conf and add \fIdowngrade\fP to \fIdcerpc_mapiproxy:modules\fP\&. .PP .PP .nf dcerpc_mapiproxy:modules = downgrade .fi .PP .PP .br .PP .SS "6\&.2\&. Pack Module " .PP \fBNote that this module only works with an infrastructure using two or more instances of MAPIProxy as described in \fCFigure 1\fP\fP .PP The \fBpack\fP module implements routines designed to manipulate and factorize MAPI content between different MAPIProxy instances\&. It also offers a developer overview on how to manipulate mapi requests\&. Last but not least, it provides data which can next be used by subsequent MAPIProxy modules for example to compress or encrypt this proxypack blob\&. .PP .PD 0 .IP "\(bu" 2 First, MAPIProxy extracts and removes specific MAPI calls from the request, pack them within the proxypack MAPI call data blob, prefix them with their real offset in the array of mapi requests and finally append this custom call at the end of the mapi requests array (Figure 4)\&. .PP Figure 6\&. Pack process .PP .IP "\(bu" 2 Final MAPIProxy hop will seek the mapi requests array looking for the proxypack call\&. If found, it unpacks MAPI data and restore these calls at their initial location within the mapi requests array (Figure 6)\&. .PP Figure 7\&. Unpack process .PP .PP .PP This module has two configuration options: .PD 0 .IP "\(bu" 2 \fBmpm_pack:opnums\fP .br This option takes a list of MAPI calls to pack into the proxypack data blob\&. It can take one or more MAPI opnums, each of them separated with a comma\&. .PP .IP "\(bu" 2 \fBmpm_pack:lasthop\fP .br This options takes either \fItrue\fP or \fIfalse\fP\&.the lasthop option defines whether this is a MAPIProxy directly connected to Outlook/Exchange or yet another proxy inserted within the MAPIProxy chain of hops\&. If this MAPIProxy instance is not a last hop, then it will skip the pack/unpack operations and forward the request to the next one\&. .PP .PP .PP .nf mpm_pack:opnums = 0x70,0x75,0x76,0x77,0xa mpm_pack:lasthop = true .fi .PP .PP In order to use the pack module, edit smb\&.conf and add \fIpack\fP to \fIdcerpc_mapiproxy:modules\fP\&. .PP .PP .nf dcerpc_mapiproxy:modules = downgrade,pack .fi .PP .PP .br .PP .SS "6\&.3\&. Cache Module " .PP The \fBcache\fP module implements a cache mechanism for streams related to messages or attachments\&. This module reduces communication latency between MAPI clients (using \fIonline\fP mode) and Exchange\&. When configured with online mode, MAPI clients retrieve data from Exchange each time they access a message and don't have any offline storage mechanisms enabled - data are downloaded and stored within a \fItemporary files\fP folder\&. This module also offers a preliminary synchronization mechanism which can be used to transfer files between different MAPIProxy instances and use different protocols than MAPI for data transfer (such as rsync or wget)\&. .PP The cache module is designed to cover different cases: .PP .SS "Scenario 1: Replay attachments" .PP This scenario only requires a single MAPIProxy instance and requires a single configuration option: .PP .nf mpm_cache:path = /tmp/cache .fi .PP .PP Figure 8\&. Replay stream scenario .PP .PD 0 .IP "\(bu" 2 \fB1\&. Outlook reads a stream for the first time\fP: .br MAPIProxy monitors the Outlook-Exchange traffic and store the attachment on the local filesystem\&. .PP .IP "\(bu" 2 \fB2\&. Outlook requests this stream again\fP: .br MAPIProxy looks over its cache, find the requested stream and directly communicate with Outlook without forwarding requests to the remote server\&. .PP .PP .br .PP .SS "Scenario 2: Read stream ahead" .PP This scenario requires two MAPIProxy instances and requires different configuration options for local and remote MAPIProxy: .PP .PD 0 .IP "\(bu" 2 \fBlocal MAPIProxy smb\&.conf sample\fP: .br .PP .nf mpm_cache:path = /tmp/cache mpm_cache:ahead = false mpm_cache:sync = true mpm_cache:sync_cmd = /usr/bin/rsync -z mapiproxy@192\&.168\&.102\&.2:__FILE__ __FILE__ .fi .PP .PP .IP "\(bu" 2 \fBremote MAPIProxy smb\&.conf sample\fP: .br .PP .nf mpm_cache:path = /tmp/cache mpm_cache:ahead = true mpm_cache:sync = false .fi .PP .PP .PP .PP Figure 9\&. Read ahead scenario with synchronization mechanism .PP .PD 0 .IP "\(bu" 2 \fBThis scenario uses 2 MAPIProxy instances\fP\&. We call \fIremote MAPIProxy\fP, the MAPIProxy instance connected to the Exchange server network and \fIlocal MAPIProxy\fP the instance connected to the MAPI clients network\&. .PP .IP "\(bu" 2 \fB1\&. Outlook wants to read an attachment for the first time\fP: .br The remote MAPIProxy monitors the first ReadStream request and read the full stream ahead on its own and stores it on its local filesystem\&. .PP .IP "\(bu" 2 \fB2\&. remote MAPIProxy replies to local MAPIProxy and local MAPIProxy runs the synchronization mechanism\&.\fP The current implementation provides a fork/execve/waitpid process which allows to run any command with parameters\&. When local MAPIProxy finishes to store the file locally through the synchronization mechanism, it marks the stream as being cached\&. .PP .IP "\(bu" 2 \fB3\&. local MAPIProxy plays the attachment back to the client from cache\fP\&. .PP .PP .PP The module monitors OpenMessage, OpenAttach, OpenStream, ReadStream and Release MAPI calls and stores streams on the local filesystem with indexation in a TDB database\&. Note that the module doesn't yet provide semantics needed to remove entries from the TDB database\&. .PP This module has different configuration options and modes: .PD 0 .IP "\(bu" 2 \fBmpm_cache:path\fP .br This option takes the full path to an existing folder on the filesystem\&. This folder will be the storage root path for the cache module and will hold the TDB store, a folder hierarchy and stream files\&. .PP .PP .nf mpm_cache:path = /tmp/cache .fi .PP .PP .IP "\(bu" 2 \fBmpm_cache:ahead\fP .br This option takes a boolean value (true or false) and defines whether the ahead mechanism should be enabled or not\&. This mode should only be enabled on the remote MAPIProxy instance\&. It can be enabled on local MAPIProxy instance, however there won't be any benefit but Outlook unexpectedly falling in some time out mode and close the connection\&. .PP .PP .nf mpm_cache:ahead = true .fi .PP .PP .IP "\(bu" 2 \fBmpm_cache:sync\fP .br This option takes a boolean value (true or false) and defines whether the synchronization mechanism should be enabled or not\&. This mode only makes sense on the local MAPIProxy instance and \fBmpm_cache:sync_cmd\fP must also be configured\&. .PP .PP .nf mpm_cache:sync = true .fi .PP .PP .IP "\(bu" 2 \fBmpm_cache:sync_cmd\fP .br This option takes the command line to execute for the synchronization process\&. A preliminary substitution variable mechanism is available but should be improved over time\&. For the moment, the cache module only provides \fB__FILE__\fP which will be substituted by the full path to the cached file\&. The synchronization process currently assumes local and remote MAPIProxy instances have the same storage path (\fImpm_cache:path\fP)\&. .PP .PP .nf mpm_cache:sync_cmd = /usr/bin/rsync -z mapiproxy@192\&.168\&.102\&.2:__FILE__ __FILE__ .fi .PP .PP .PP .PP .PP In order to use the cache module, edit smb\&.conf and add \fIcache\fP to \fIdcerpc_mapiproxy:modules\fP\&. .PP .PP .nf dcerpc_mapiproxy:modules = downgrade,cache .fi .PP .br .PP .SS "Notes" .PP .PD 0 .IP "\(bu" 2 While the cache module implements a preliminary \fIsession\fP mechanism (multiple clients support), this mode is currently only implemented up to 50%\&. Multiple clients will work for files already cached, but will cause unexpected behaviors while synchronizing a remote file at the same moment from different session\&. This bug should be fixed when the streaming and lock mechanism will be implemented\&. .PP .IP "\(bu" 2 The synchronization mechanism is yet experimental and we have deliberately changed the storage path permissions from 0700 to 0777 for trivial setup\&. File permissions will become parametric smb\&.conf options in the future\&. .PP .PP .PP .br .PP .SS "7\&. Server Mode" .PP .SS "7\&.1\&. 5-Minute Configuration" .PP This 5-Minute configuration will help you set up a preliminary OpenChange server\&. This configuration will be performed in three steps\&. Before running these commands, make sure you have followed \fBstep 1 (Provision Samba)\fP and \fBstep 2 (Add a user account)\fP in \fCMAPIProxy 5-Minute configuration section\fP\&. .PP .PD 0 .IP "\(bu" 2 \fB[1] Provision OpenChange\fP: .br From openchange root directory, run under the root account: .PP .nf # \&./setup/openchange_provision .fi .PP .PP This script will extends Samba4 Active Directory with Exchange classes and attributes needed to run OpenChange server\&. Note that this operation may require several minutes to complete\&. .PP .IP "\(bu" 2 \fB[2] Create the Exchange user account\fP: .br OpenChange \fBdoes not create\fP the user account the way Samba does\&. It only extends existing users from the SAM database and add attributes required to access OpenChange server\&. The underlying concept is that system administrators may want to give access to Samba shares to a specific user but do not want him to access OpenChange server\&.\fBThe user must have been created using the Samba4 \fIsamba-tool newuser\fP script\fP before you run this command\&. Run under the root account: .PP .nf # \&./setup/openchange_newuser --create .fi .PP where username is the user account you want to give access to OpenChange server .PP .IP "\(bu" 2 \fB[3] Create the OpenChange Dispatcher database\fP: .br OpenChange uses a dispatcher database designed to store generic and top-level information about user mailbox\&. The following command will create a blank openchangedb ldb database: .PP .nf # \&./setup/openchange_provision --openchangedb .fi .PP .PP .IP "\(bu" 2 \fB[4] Create a mailbox for the user in the OpenChange Dispatcher database\fP: .br Run under the root account: .PP .nf # \&./setup/openchange_newuser --mailbox .fi .PP .PP .IP "\(bu" 2 \fB[5] Configure OpenChange server options\fP: .br OpenChange server only requires a very limited set of options to be added to \fIsmb\&.conf\fP in order to run\&. Note that the following configuration also works with existing MAPIProxy configuration\&. This configuration will turn MAPIProxy into OpenChange server only and no remote connection to Exchange server will be made: .PP .PP .nf [globals] netbios name = MAPIPROXY workgroup = OPENCHANGE realm = OPENCHANGE\&.LOCAL server role = domain controller ### Configuration required by OpenChange server ### dcerpc endpoint servers = epmapper, mapiproxy dcerpc_mapiproxy:server = true dcerpc_mapiproxy:interfaces = exchange_emsmdb, exchange_nsp, exchange_ds_rfr ### Configuration required by OpenChange server ### [netlogon] path = /usr/local/samba/var/locks/sysvol/openchange\&.local/scripts read only = no [sysvol] path = /usr/local/samba/var/locks/sysvol read only = no .fi .PP .PP .PP .br .br .SS "7\&.2\&. General Overview" .PP Although \fCsection 1\&.1\fP only describes MAPIProxy as a proxy, recent work makes it possible to turn MAPIProxy either into a \fBcomplete and real stand-alone server\fP or server/proxy hybrid\&. .PP MAPIProxy behaviour is controlled through the \fIdcerpc_mapiproxy:server\fP parametric option\&. To use MAPIProxy as an independent server, set .PP .PP .nf dcerpc_mapiproxy:server = true .fi .PP .PP .PD 0 .IP "\(bu" 2 \fBdcerpc_mapiproxy:server = true\fP .br When this parametric option is set to true, MAPIProxy will not initiate connections to a remote server, but instead will direct client connections to its own default NSPI, RFR and EMSMDB servers and work as a stand-alone server\&. .br .PP .IP "\(bu" 2 \fBdcerpc_mapiproxy:server = false\fP .br If this option is unset or set to false (default behavior), MAPIProxy will work in proxy mode only and initiates a connection to a remote server using the binding/credentials configuration as specified in \fCsection 3\&.1\fP (5-Minute Configuration)\&. .PP .br .PP In addition to the server mode described above, MAPIProxy provides an additional set of configuration options which makes possible to override and customize MAPIProxy behavior\&. The server mode has been designed to supply a modular mechanism somewhat similar to the modules one described in \fCsection 5\fP\&. While MAPIProxy modules are stackable and can be chained, server modules only support a single module for a given endpoint: .PD 0 .IP "\(bu" 2 When dcerpc_mapiproxy:server is set to true, MAPIProxy registers dynamic shared object stored at a specific location (modules/dcerpc_mapiproxy_servers) and load server modules tagged with the \fBMAPIPROXY_DEFAULT\fP status\&. For each of the endpoints MAPIProxy can handle (exchange_nsp, exchange_emsmdb, exchange_ds_rfr), the associated default server will be loaded\&. These default servers are located within mapiproxy/servers/modules\&. (Figure 10\&.) .br .PP Figure 10\&. Server mode enabled .PP .IP "\(bu" 2 When dcerpc_mapiproxy:server is set to false, MAPIProxy still registers server dynamic shared objects but does not load any of them, which means that ExchangeRPC traffic will be relayed to remote server\&. .PP .PP However there may be some cases where developers would like to run a custom server they have developed, or handle a limited set of ExchangeRPC traffic on their own for a given endpoint\&. This configuration is made possible through 3 parametric options: .PP .PP .nf dcerpc_mapiproxy:nspi_server = nspi_server dcerpc_mapiproxy:emsmdb_server = emsmdb_server dcerpc_mapiproxy:rfr_server = exchange_ds_rfr .fi .PP .PP Each of these options specifies the server module name to be loaded for a given endpoint\&. Note that these options override the dcerpc_mapiproxy:server state: .PD 0 .IP "\(bu" 2 If dcerpc_mapiproxy:server is set to true, specifying one or all of these options will override default servers with your own custom servers\&. For example Figure 11 shows a mapiproxy configuration where server mode is enabled but where the NSPI server has been replaced with a custom one\&. .PP Figure 11\&. Server mode enabled but custom NSPI server loaded .PP .IP "\(bu" 2 If dcerpc_mapiproxy:server is set to false, specifying one or all of these options will force MAPIProxy to relay the associated traffic to default or custom server\&. For example, Figure 12 shows a mapiproxy configuration where NSPI traffic is handled by OpenChange NSPI server while EMSMDB and RFR traffic is relayed to the remote server\&. .PP Figure 12\&. Server mode disabled but NSPI server loaded .PP .PP .br .PP .SS "8\&. Frequently Asked Questions" .PP .SS "8\&.1\&. The action could not be completed" .PP Figure 13\&. Outlook error: The action could not be completed .PP If you have followed the \fC5-Minute Configuration\fP instructions and the above error message box (Figure 13) is displayed each time you click the \fICheck Name\fP button, then you need to: .PD 0 .IP "\(bu" 2 Click on \fBMore Settings\fP .IP "\(bu" 2 Open the security Tab .IP "\(bu" 2 Tick the \fBAlways prompt for username and password\fP checkbox in the User Configuration section (Figure 14) .PP .PP Figure 14\&. Resolution: Always prompt for username and password .PP Next time you click on \fICheck Name\fP, Outlook will prompt for username and password\&. A similar credentials dialog will be displayed each time Outlook is launched\&. .PP .br .PP .SS "8\&.2\&. Profile creation goes fine, but Outlook can't open your default e-mail folders" .PP The profile was properly created using the mail applet from the configuration panel (or using Outlook wizard)\&. However when I launch Outlook, I keep having the following error message: .PP Figure 15\&. Outlook error: Unable to Open your default e-mail folders .PP This probably means Outlook is unable to lookup the resolved name of your MAPIProxy/samba4 server\&. You can either: .PD 0 .IP "\(bu" 2 1\&. Make your Windows workstation points to a domain name server able to resolve MAPIProxy fully qualified name\&. .PP .IP "\(bu" 2 2\&. Open .PP .nf C:\WINDOWS\system32\etc\drivers\hosts .fi .PP file and add an entry for mapiproxy\&. For example if I have mapiproxy\&.openchange\&.local pointing at 192\&.168\&.102\&.2, then hosts file should hold the following line: .PP .nf 192\&.168\&.102\&.2 mapiproxy\&.openchange\&.local mapiproxy .fi .PP .PP .PP .br .PP .SS "8\&.3\&. Does MAPIProxy need to be domain controller?" .PP No it doesn't\&. MAPIProxy works fine as a member server of a Windows domain\&. However, since delegated credentials and forwarded kerberos credentials don't yet work, you'll need to force samba to rely on the local SAM database\&. To force this behavior, add to smb\&.conf within the global section: .PP .PP .nf server role = member server aux_methods:member server = sam .fi .PP .PP .br .PP .SS "8\&.4\&. Generating Samba's private keys takes infinite time" .PP For some configuration, the private keys generation process at Samba startup can be very long\&. In case private keys are not generated within a couple of minutes, it is suggested to recompile Samba with gnutls disabled as in the example below: .PP .PP .nf $ \&./configure\&.developer --enable-debug --disable-gnutls $ gmake idl_full $ gmake $ sudo gmake install .fi .PP .PP .br .PP .SS "8\&.5\&. On Ubuntu \fImake samba-git\fP exits with \fIgmake: not found\fP" .PP On Ubuntu, I have the following output while trying to install samba4 from OpenChange sources: .PP .PP .nf To build Samba, run /usr/bin/make Step2: Compile Samba4 (IDL) \&./script/installsamba4\&.sh: 332: gmake: not found Step3: Compile Samba4 (Source) \&./script/installsamba4\&.sh: 332: gmake: not found Error in Step3 (error code 127) .fi .PP .PP gmake is make on Ubuntu\&. Creating the following symbolic link will fix the issue: .PP .PP .nf $ sudo ln -s /usr/bin/make /usr/bin/gmake .fi .PP openchange-2.0/apidocs/man/man3/mapiproxy_NspiDNToMId.3000066400000000000000000000000431223057412600227400ustar00rootroot00000000000000.so man3/dcesrv_mapiproxy_nspi.c.3 openchange-2.0/apidocs/man/man3/mapiproxy_NspiGetProps.3000066400000000000000000000000431223057412600233050ustar00rootroot00000000000000.so man3/dcesrv_mapiproxy_nspi.c.3 openchange-2.0/apidocs/man/man3/mapiproxy_NspiQueryRows.3000066400000000000000000000000431223057412600235220ustar00rootroot00000000000000.so man3/dcesrv_mapiproxy_nspi.c.3 openchange-2.0/apidocs/man/man3/mapiproxy_RfrGetNewDSA.3000066400000000000000000000000421223057412600231020ustar00rootroot00000000000000.so man3/dcesrv_mapiproxy_rfr.c.3 openchange-2.0/apidocs/man/man3/mapiproxy_op_bind.3000066400000000000000000000000361223057412600223240ustar00rootroot00000000000000.so man3/dcesrv_mapiproxy.c.3 openchange-2.0/apidocs/man/man3/mapiproxy_op_dispatch.3000066400000000000000000000000361223057412600232070ustar00rootroot00000000000000.so man3/dcesrv_mapiproxy.c.3 openchange-2.0/apidocs/man/man3/mapiproxy_op_init_server.3000066400000000000000000000000361223057412600237410ustar00rootroot00000000000000.so man3/dcesrv_mapiproxy.c.3 openchange-2.0/apidocs/man/man3/mapiproxy_op_ndr_pull.3000066400000000000000000000000361223057412600232270ustar00rootroot00000000000000.so man3/dcesrv_mapiproxy.c.3 openchange-2.0/apidocs/man/man3/mapiproxy_op_ndr_push.3000066400000000000000000000000361223057412600232320ustar00rootroot00000000000000.so man3/dcesrv_mapiproxy.c.3 openchange-2.0/apidocs/man/man3/mapiproxy_op_unbind.3000066400000000000000000000000361223057412600226670ustar00rootroot00000000000000.so man3/dcesrv_mapiproxy.c.3 openchange-2.0/apidocs/man/man3/mapiproxy_register_one_iface.3000066400000000000000000000000361223057412600245260ustar00rootroot00000000000000.so man3/dcesrv_mapiproxy.c.3 openchange-2.0/apidocs/man/man3/mapiproxy_server_emsabp_tdb_init.3000066400000000000000000000000451223057412600254230ustar00rootroot00000000000000.so man3/dcesrv_mapiproxy_server.c.3 openchange-2.0/apidocs/man/man3/mapiproxy_server_init.3000066400000000000000000000000451223057412600232430ustar00rootroot00000000000000.so man3/dcesrv_mapiproxy_server.c.3 openchange-2.0/apidocs/man/man3/mapiproxy_server_openchange_ldb_init.3000066400000000000000000000000451223057412600262530ustar00rootroot00000000000000.so man3/dcesrv_mapiproxy_server.c.3 openchange-2.0/apidocs/man/man3/mapistore-documentation.3000066400000000000000000000447301223057412600234650ustar00rootroot00000000000000.TH "mapistore-documentation" 3 "Thu Jan 24 2013" "Version 2.0" "MAPIProxy" \" -*- nroff -*- .ad l .nh .SH NAME mapistore-documentation \- .PP .SH "Contents" .PP .PD 0 .IP "\(bu" 2 \fCRevision History \fP .IP "\(bu" 2 \fC1\&. Introduction \fP .PD 0 .IP " \(bu" 4 \fC1\&.1\&. Purpose and Scope\fP .IP " \(bu" 4 \fC1\&.2\&. General Overview\fP .PP .IP "\(bu" 2 \fC2\&. Technical / MAPI Considerations\fP .PD 0 .IP " \(bu" 4 \fC2\&.1\&. MAPI objects\fP .IP " \(bu" 4 \fC2\&.2\&. MAPI tables\fP .IP " \(bu" 4 \fC2\&.3\&. MAPI properties and mapping\fP .IP " \(bu" 4 \fC2\&.4\&. Named properties vs known properties\fP .PP .IP "\(bu" 2 \fC3\&. MAPIStore architecture\fP .PD 0 .IP " \(bu" 4 \fC3\&.1\&. INTERFACE layer\fP .IP " \(bu" 4 \fC3\&.2\&. PROCESSING layer\fP .IP " \(bu" 4 \fC3\&.3\&. BACKENDS layer\fP .IP " \(bu" 4 \fC3\&.4\&. Relationship to OpenChange Dispatcher database\fP .IP " \(bu" 4 \fC3\&.5\&. Object mapping\fP .PP .IP "\(bu" 2 \fC4\&. MAPIStore API\fP .PD 0 .IP " \(bu" 4 \fC4\&.1\&. Initialization\fP .IP " \(bu" 4 \fC4\&.2\&. Backend contexts\fP .PP .IP "\(bu" 2 \fC5\&. FSOCPF backend\fP .PD 0 .IP " \(bu" 4 \fC5\&.1\&. Definition \fP .IP " \(bu" 4 \fC5\&.2\&. Namespace and Attributes \fP .IP " \(bu" 4 \fC5\&.3\&. Overview \fP .IP " \(bu" 4 \fC5\&.4\&. Documentation and References\fP .PP .PP .PP .SS "Revision History" .PP \fBDate\fP \fBRevision Number\fP \fBAuthor\fP \fBRevision Content\fP 21/05/10 \fB0\&.3\fP Julien Kerihuel Add API documentation for initialization, backend connection contexts and add programming samples 21/05/10 \fB0\&.2\fP Julien Kerihuel Merge initial Wiki document and add FSOCPF section 20/05/10 \fB0\&.1\fP Julien Kerihuel Draft document\&. .br .PP .SS "1\&. Introduction" .PP .SS "1\&.1\&. Purpose and Scope" .PP MAPIStore is the SAL component of OpenChange server\&. SAL stands for Storage Abstraction Layer\&. It is the component used by OpenChange Server to push/get information (messages, folders) to/from storage backends\&. The following document intends to describe the overall/theoretical SAL behavior and constraints we need to consider when dealing with MAPI/EMSMDB\&. It also describes the semantics and inner working of its storage backends\&. .PP .br .SS "1\&.2\&. General overview" .PP The main objective of mapistore is to provide an interface layer with a common set of atomic functions (operations) used to trigger and dispatch data and commands to the appropriate backend\&. MAPIStore relies on a backend mechanism specifically designed to transparently handle some of the MAPI semantics required by any Exchange compatible server\&. .PP The initial idea was to provide to OpenChange a highly customizable storage backend mechanism which would fit in any situation and any environments\&. One of the greatest limitation we have found with existing groupware is the storage layer which is generally limited to a single solution, service or format and is neither scalable nor modifiable when user requirements evolve upon time\&. .PP MAPIStore solves this problem and go beyond classical limitations\&. It is not a revolutionary concept, but the way openchange uses it makes the whole difference and offer administrators an innovative way to customize storage\&. .PP MAPIStore allows you to: .IP "\(bu" 2 \fBuse a different backend for any top-folder\fP .IP "\(bu" 2 \fBtransparently move/copy data across backends\fP .IP "\(bu" 2 develop new backends quickly .IP "\(bu" 2 access all the different backends through an unique API .PP .PP For example (assuming all associated backends were developed) a user could have the following storage organization for his mailbox: .IP "\(bu" 2 Mails stored using an IMAP backend (Cyrus-IMAP or dovecot) .IP "\(bu" 2 Calendar items stored in CalDAV or pushed in Google calendar .IP "\(bu" 2 Sent emails and archives/backup stored in a compression backend .IP "\(bu" 2 Tasks stored in a MySQL database .IP "\(bu" 2 Notes stored on the filesystem .PP .PP If the user is not satisfied with one of the backend's performance, they would just have to use an administration tool, change the backend, wait for the replication, synchronization to finish and there data will be available from the new backend\&. .PP Information can be completely decentralized, stored on one of several servers and still be accessible transparently from OpenChange server\&. .PP .br .SS "2\&. Technical / MAPI Considerations" .PP .SS "2\&.1\&. MAPI objects" .PP An object is a physical (message, folder) or temporary (table) but generic entity which can be represented as a 2 columns fixed array with \fIn\fP rows, where each row contains a property of that entity\&. One column repesents the property tags (names), and the other represents the property value (or values)\&. .PP From a MAPI perspective (network layer), opening an object means: .PP .IP "\(bu" 2 opening either a \fBprivate mailbox\fP or \fBpublic folder store\fP\&. These are referenced by \fBEssDN and not IDs\fP .IP "\(bu" 2 opening a \fBmessage\fP given its \fBPR_MID\fP (Message identifier) .IP "\(bu" 2 opening a \fBfolder/container\fP given its \fBPR_FID\fP (Folder identifier) .PP .PP .SS "2\&.2\&. MAPI tables" .PP Another category of MAPI objects are tables (also known as \fIviews\fP) created with MAPI ROPs such as \fIGetContentsTable\fP, \fIGetHierarchyTable\fP, \fIGetAttachmentTable\fP or \fIGetRulesTable\fP\&. Views are temporary representation of the elements that a container holds at a specific moment\&. It can be represented as a list of \fIn\fP rows (elements) with \fIn\fP columns (property values): .IP "\(bu" 2 \fIGetContentsTables\fP creates a view listing all messages available within a container .IP "\(bu" 2 \fIGetHierarchyTable\fP creates a view listing all containers within a container .IP "\(bu" 2 \fIGetAttachmentTable\fP creates a view listing all the attachment of a message .IP "\(bu" 2 \fIGetRulesTable\fP creates a view listing all permissions associated to a container .PP .PP Tables are customized through the \fISetColumns\fP MAPI ROP which will define the property identifiers to be retrieved\&. The \fIQueryRows\fP MAPI ROP can then be called to sequentially retrieve rows and associated property values\&. A table is similar to a MAPI object except it is virtual, created on demand to represent a list of objects rather than a unique object\&. .PP .SS "2\&.3\&. MAPI properties and mapping" .PP There is a large set of fixed and known MAPI properties available\&. If appropriate backends are developed, there can be a 1-1 mapping between MAPI properties and backend properties for some of them\&. This mapping may even be enough for common purposes\&. However there will still be a set of MAPI properties which won't fit in this process\&. .PP There are different way to workaround this issue\&. For example, Kolab is using a Cyrus/IMAP backend and associate/store MAPI properties to the message using ANNOTATE-MORE within a XML file format\&. .PP OpenChange provides similar mechanism with its OCPF file format\&. .PP .SS "2\&.4\&. Named properties vs known properties" .PP OpenChange server needs to support named properties\&. An initial set of named properties can be defined at provisioning time, but this list must not be static\&. Users must be able to add, delete, change new entries and create their own set of custom named properties as required\&. .PP .br .SS "3\&. MAPIStore Architecture" .PP Given that objects representation are similar to SQL database records, an architecture like the sqlite one makes sense for our purpose: .PP \fBComponent\fP \fBBrief description\fP INTERFACE convenient top-level functions (Public API) accessed through EMSMDB providers PROCESSING set of atomic operations (open, read, write, close, mkdir, rmdir etc\&.) BACKENDS The code which \fIdoes things\fP in the specified storage system (mysql, fsocpf, imap etc\&.) .PP .SS "3\&.1\&. INTERFACE layer" .PP The interface layer doesn't have any knowledge about mapistore internals, how or where objects are stored\&. The interface uses MAPI data structure, supplies PR_FID and PR_MID values and assumes the interface layer will return a pack of data it can directly use without further or significant modifications\&. The interface layer functions should also have (as a parameter) a pointer to a mapistore context with private/opaque set of information (void *) about the object\&. .PP .SS "3\&.2\&. PROCESSING layer" .PP The processing layer is responsible for: .IP "\(bu" 2 mapping OpenChange objects identifiers (PR_FID, PR_MID) to unique backends object identifiers (on purpose, depending on the kind of backend)\&. .IP "\(bu" 2 format input/output data: glue between INTERFACE and BACKENDS .IP "\(bu" 2 relay input requests to the correct backend through atomic operations .IP "\(bu" 2 maintain mapistore's integrity .PP .PP .SS "3\&.3\&. BACKENDS layer" .PP The backends layer has a list of modules identified at mapistore initialization and available across user sessions, which means unique initialization at server start-up\&. Each module is a backend (fsocpf, sqlite, imap, etc\&.) and similarly to many other openchange components is loaded as a DSO object (dynamic shared object) .PP .SS "3\&.4\&. Relationship to OpenChange Dispatcher database" .PP MAPIStore and the openchange 'dispatcher' database (openchange\&.ldb) are completely unrelated\&. MAPIStore is a standalone API and developers can use it independently from OpenChange server\&. .PP However, the mapistore API has initially been designed to be used by OpenChange server, and OpenChange server is using a tiny indexing database which describes user mailboxes top level containers\&. In openchange\&.ldb the mapistore_uri attribute is attached to top level containers and its value points to a valid mapistore URI (namespace + path)\&. Note that a single user can have several different types of mapistore databases in use (one for each of the top level containers)\&. .PP The is the only relationship between the database and the store: The database points to store locations\&. .PP .SS "3\&.5\&. Object mapping" .PP MAPIStore needs to maintain a hash database linking unique OpenChange identifiers to unique backend identifiers\&. This hash table can be stored within a TDB database\&. .PP MAPIStore is responsible for managing IDs mapping between OpenChange objects and backend specific objects\&. It maintains a list of free identifiers which it reallocates on demand whenever a backend needs (mapistore_register_id()) one or where it wants to release one (mapistore_unregister_id())\&. .PP .br .SS "4\&. MAPIStore API" .PP MAPIStore relies on the talloc library for memory allocation\&. .PP .SS "4\&.1\&. Initialization" .PP If there was a 'hello mapistore' program, it would only require to make 2 calls: .IP "\(bu" 2 \fBmapistore_init\fP: .br The initialization routine initializes the mapistore general context used along all mapistore calls, the mapping context databases (described below) and finally load all the backends available (DSO)\&. When this operation is successful, developers are ready to make mapistore calls\&. .IP "\(bu" 2 \fBmapistore_release\fP: .br The release operation uninitializes the mapistore general context, closes connections to database and frees the remaining allocated memory\&. .PP .PP \fBmapistore_sample1\&.c\fP .PP .nf #include int main(int ac, const char *av[]) { TALLOC_CTX *mem_ctx; struct mapistore_context *mstore_ctx; int retval; /* Step 1\&. Create the talloc memory context */ mem_ctx = talloc_named(NULL, 0, 'mapistore_sample1'); /* Step 2\&. Initialize mapistore system */ mstore_ctx = mapistore_init(mem_ctx, NULL); if (!mstore_ctx) { exit (1); } /* Step 3\&. Uninitialize mapistore system */ retval = mapistore_release(mstore_ctx); if (retval != MAPISTORE_SUCCESS) { exit (1); } return 0; } .fi .PP .PP .PP .nf $ export PKG_CONFIG_PATH=/usr/local/samba/lib/pkgconfig $ gcc mapistore_sample1\&.c -o mapistore_sample1 `pkg-config --cflags --libs libmapistore` $ \&./mapistore_sample1 $ .fi .PP .PP .br .SS "4\&.2\&. Backend contexts" .PP MAPIStore registers and loads its backends upon initialization\&. It means they are only instantiated/initialized one time during the whole server lifetime and the same code is used for all users and all mapistore folders\&. .PP These backend contexts (or connection contexts) are identified by a \fBcontext id\fP, which is an unsigned 32 bit integer which references the context during its lifetime\&. If OpenChange is used in a very large environment with many top folders (which implies the same number of mapistore contexts), or if OpenChange server has an incredibly long uptime, it would be possible to run out of available context identifiers\&. .PP In order to prevent this situation from happening, mapistore implements context databases where it stores available/free/used context identifiers: .IP "\(bu" 2 \fBmapistore_id_mapping_used\&.tdb\fP: TDB database with used IDs .IP "\(bu" 2 \fBmapistore_id_mapping_free\&.tdb\fP: TDB database with available pool of IDs .PP .PP MAPIStore provides a convenient set of functions to manage backend contexts: .IP "\(bu" 2 \fBmapistore_set_mapping_path\fP: Defines the path where context databases are stored\&. Call to this function is optional and default path would be used instead\&. However if a call to this function has to be made, it must be done before any call to mapistore (even mapistore_init)\&. .IP "\(bu" 2 \fBmapistore_add_context\fP: Add a new connection context to mapistore .IP "\(bu" 2 \fBmapistore_del_context\fP: Delete a connection context from mapistore .PP .PP \fBmapistore_sample2\&.c\fP: .PP .nf #include int main(int ac, const char *av[]) { TALLOC_CTX *mem_ctx; struct mapistore_context *mstore_ctx; int retval; uint32_t context_id = 0; uint32_t context_id2 = 0; /* Step 1\&. Create the talloc memory context */ mem_ctx = talloc_named(NULL, 0, 'mapistore_sample1'); /* Step 2\&. Set the mapping path to /tmp */ retval = mapistore_set_mapping_path('/tmp'); if (retval != MAPISTORE_SUCCESS) { exit (1); } /* Step 3\&. Initialize mapistore system */ mstore_ctx = mapistore_init(mem_ctx, NULL); if (!mstore_ctx) { exit (1); } /* Step 4\&. Add connection contexts */ retval = mapistore_add_context(mstore_ctx, 'fsocpf:///tmp/Inbox', &context_id); if (retval != MAPISTORE_SUCCESS) { exit (1); } retval = mapistore_add_context(mstore_ctx, 'fsocpf:///tmp/Sent Items', &context_id2); if (retval != MAPISTORE_SUCCESS) { exit (1); } /* Step 5\&. Release connection contexts */ retval = mapistore_del_context(mstore_ctx, context_id); retval = mapistore_del_context(mstore_ctx, context_id2); /* Step 6\&. Uninitialize mapistore system */ retval = mapistore_release(mstore_ctx); if (retval != MAPISTORE_SUCCESS) { exit (1); } return 0; } .fi .PP .PP .PP .nf $ \&./mapistore_sample2 sqlite3 backend initialized fsocpf backend initialized namespace is fsocpf:// and backend_uri is '/tmp/Inbox' [fsocpf_create_context:49] namespace is fsocpf:// and backend_uri is '/tmp/Sent Items' [fsocpf_create_context:49] $ .fi .PP .PP .br .SS "5\&. FSOCPF Backend" .PP .SS "5\&.1\&. Definition" .PP FSOCPF stands for FileSystem and OpenChange Property Files\&. It is a backend designed to help developers testing OpenChange server code easily\&. The main idea is to have a backend we can manipulate, analyze and modify from the Linux console without having to develop a specific tool\&. This backend uses the UNIX filesystem for folder semantics and the OCPF file format as a way to store MAPI objects easily\&. .PP .SS "5\&.2\&. Namespace and Attributes" .PP The namespace for this backend is: .PP .nf fsocpf:// .fi .PP .PP The mapistore_uri attribute for the folder definition in openchange\&.ldb must be a valid path where the last part of the URI is the FSOCPF container folder to create on the filesystem\&. .PP .SS "5\&.3\&. Overview" .PP .PP .nf [+] Private user storage space | +-[+] Top-MAPIStore folder (Inbox) | +-[+] 0xf1000001 (mapistore folder1) | | | +-[+] \&.properties (OCPF) | | | +-[+] 0xe10000001\&.ocpf (message - OCPF) | | | +-[+] 0xe10000001 (attachment folder) | | | +-[+] 1\&.ocpf (PR_ATTACH_NUM) | | | +-[+] 1\&.data (attachment / stream data) | +-[+] 0xf2000001 (mapistore folder2) | +-[+] \&.properties (OCPF) .fi .PP .PP The figure above exposes the storage architecture of the FSOCPF backend using a real-world example\&. In this use case, we have decided to associate the FSOCPF backend to the Inbox folder\&. It means that any folder created under Inbox or any message stored within Inbox at any level of depth is stored and retrieved from the path defined in openchange\&.ldb\&. .PP In openchange\&.ldb, the mapistore_uri attribute of the Inbox record points to: .PP .nf fsocpf://Private user storage space/Inbox .fi .PP where \fIPrivate user storage space\fP can for example be .PP .nf /usr/local/samba/private/mapistore/$username .fi .PP .PP Under Inbox, we have created 2 folders: .IP "\(bu" 2 0xf1000001 folder1 .IP "\(bu" 2 0xf2000001 folder2 .PP .PP These folders are identified/named using their FID\&. Since they are classical filesystem folders, we can't associate attributes to them such as a folder comment, or the container class\&. All these attributes with the displayable name are stored into the \fB\&.properties\fP file within the folder\&. .PP Inside 0xf1000001 folder, we have 1 message named 0xe10000001\&.ocpf stored in the OCPF file format (property/value pair)\&. Any properties associated to the message (subject, recipient, body) are stored within this file\&. .PP This message also has attachments\&. Attachments are stored within a directory at the same level named 0xe10000001 (message name without OCPF extension)\&. Within this directory, we find the attachments named using the PR_ATTACH_NUM property value and the OCPF file extension\&. The content of the attachment is stored in $PR_ATTACH_NUM\&.data - in this case 1\&.data\&. .PP .br .SS "5\&.4\&. Documentation and References" .PP .IP "\(bu" 2 \fCOpenChange Property File format (OCPF) documentation\fP .PP openchange-2.0/apidocs/man/man3/mapistore.h.3000066400000000000000000001100611223057412600210330ustar00rootroot00000000000000.TH "mapiproxy/libmapistore/mapistore.h" 3 "Thu Jan 24 2013" "Version 2.0" "OpenChange mapistore library" \" -*- nroff -*- .ad l .nh .SH NAME mapiproxy/libmapistore/mapistore.h \- .PP MAPISTORE general API\&. .SH SYNOPSIS .br .PP \fC#include \fP .br \fC#include \fP .br \fC#include \fP .br \fC#include \fP .br \fC#include \fP .br \fC#include \fP .br \fC#include \fP .br \fC#include \fP .br \fC#include \fP .br \fC#include \fP .br \fC#include \fP .br \fC#include 'libmapi/libmapi\&.h'\fP .br .SS "Functions" .in +1c .ti -1c .RI "enum \fBmapistore_error\fP \fBmapistore_add_context\fP (struct mapistore_context *, const char *, const char *, uint64_t, uint32_t *, void **)" .br .ti -1c .RI "enum \fBmapistore_error\fP \fBmapistore_add_context_ref_count\fP (struct mapistore_context *, uint32_t)" .br .ti -1c .RI "const char * \fBmapistore_backend_get_installdir\fP (void)" .br .ti -1c .RI "init_backend_fn * \fBmapistore_backend_load\fP (TALLOC_CTX *, const char *)" .br .ti -1c .RI "struct backend_context * \fBmapistore_backend_lookup\fP (struct backend_context_list *, uint32_t)" .br .ti -1c .RI "struct backend_context * \fBmapistore_backend_lookup_by_name\fP (TALLOC_CTX *, const char *)" .br .ti -1c .RI "struct backend_context * \fBmapistore_backend_lookup_by_uri\fP (struct backend_context_list *, const char *)" .br .ti -1c .RI "enum \fBmapistore_error\fP \fBmapistore_backend_register\fP (const void *)" .br .ti -1c .RI "bool \fBmapistore_backend_run_init\fP (init_backend_fn *)" .br .ti -1c .RI "enum \fBmapistore_error\fP \fBmapistore_del_context\fP (struct mapistore_context *, uint32_t)" .br .ti -1c .RI "const char * \fBmapistore_errstr\fP (enum \fBmapistore_error\fP)" .br .ti -1c .RI "enum \fBmapistore_error\fP \fBmapistore_folder_create_folder\fP (struct mapistore_context *, uint32_t, void *, TALLOC_CTX *, uint64_t, struct SRow *, void **)" .br .ti -1c .RI "enum \fBmapistore_error\fP \fBmapistore_folder_create_message\fP (struct mapistore_context *, uint32_t, void *, TALLOC_CTX *, uint64_t, uint8_t, void **)" .br .ti -1c .RI "enum \fBmapistore_error\fP \fBmapistore_folder_delete\fP (struct mapistore_context *, uint32_t, void *, uint8_t)" .br .ti -1c .RI "enum \fBmapistore_error\fP \fBmapistore_folder_delete_message\fP (struct mapistore_context *, uint32_t, void *, uint64_t, uint8_t)" .br .ti -1c .RI "enum \fBmapistore_error\fP \fBmapistore_folder_get_child_count\fP (struct mapistore_context *, uint32_t, void *, enum mapistore_table_type, uint32_t *)" .br .ti -1c .RI "enum \fBmapistore_error\fP \fBmapistore_folder_get_deleted_fmids\fP (struct mapistore_context *, uint32_t, void *, TALLOC_CTX *, enum mapistore_table_type, uint64_t, struct UI8Array_r **, uint64_t *)" .br .ti -1c .RI "enum \fBmapistore_error\fP \fBmapistore_folder_open_folder\fP (struct mapistore_context *, uint32_t, void *, TALLOC_CTX *, uint64_t, void **)" .br .ti -1c .RI "enum \fBmapistore_error\fP \fBmapistore_folder_open_message\fP (struct mapistore_context *, uint32_t, void *, TALLOC_CTX *, uint64_t, bool, void **)" .br .ti -1c .RI "enum MAPISTATUS \fBmapistore_get_queued_notifications\fP (struct mapistore_context *, struct mapistore_subscription *, struct mapistore_notification_list **)" .br .ti -1c .RI "enum MAPISTATUS \fBmapistore_get_queued_notifications_named\fP (struct mapistore_context *, const char *, struct mapistore_notification_list **)" .br .ti -1c .RI "enum \fBmapistore_error\fP \fBmapistore_indexing_record_add_fid\fP (struct mapistore_context *, uint32_t, const char *, uint64_t)" .br .ti -1c .RI "enum \fBmapistore_error\fP \fBmapistore_indexing_record_add_mid\fP (struct mapistore_context *, uint32_t, const char *, uint64_t)" .br .ti -1c .RI "enum \fBmapistore_error\fP \fBmapistore_indexing_record_del_fid\fP (struct mapistore_context *, uint32_t, const char *, uint64_t, uint8_t)" .br .ti -1c .RI "enum \fBmapistore_error\fP \fBmapistore_indexing_record_del_mid\fP (struct mapistore_context *, uint32_t, const char *, uint64_t, uint8_t)" .br .ti -1c .RI "enum \fBmapistore_error\fP \fBmapistore_indexing_record_get_uri\fP (struct mapistore_context *, const char *, TALLOC_CTX *, uint64_t, char **, bool *)" .br .ti -1c .RI "struct mapistore_context * \fBmapistore_init\fP (TALLOC_CTX *, struct loadparm_context *, const char *)" .br .ti -1c .RI "enum \fBmapistore_error\fP \fBmapistore_message_get_message_data\fP (struct mapistore_context *, uint32_t, void *, TALLOC_CTX *, struct mapistore_message **)" .br .ti -1c .RI "enum \fBmapistore_error\fP \fBmapistore_message_modify_recipients\fP (struct mapistore_context *, uint32_t, void *, struct SPropTagArray *, uint16_t, struct mapistore_message_recipient *)" .br .ti -1c .RI "enum \fBmapistore_error\fP \fBmapistore_message_save\fP (struct mapistore_context *, uint32_t, void *)" .br .ti -1c .RI "enum \fBmapistore_error\fP \fBmapistore_message_set_read_flag\fP (struct mapistore_context *, uint32_t, void *, uint8_t)" .br .ti -1c .RI "enum \fBmapistore_error\fP \fBmapistore_message_submit\fP (struct mapistore_context *, uint32_t, void *, enum SubmitFlags)" .br .ti -1c .RI "enum \fBmapistore_error\fP \fBmapistore_namedprops_create_id\fP (struct ldb_context *, struct MAPINAMEID, uint16_t)" .br .ti -1c .RI "enum \fBmapistore_error\fP \fBmapistore_namedprops_get_mapped_id\fP (struct ldb_context *ldb_ctx, struct MAPINAMEID, uint16_t *)" .br .ti -1c .RI "enum \fBmapistore_error\fP \fBmapistore_namedprops_get_nameid\fP (struct ldb_context *, uint16_t, TALLOC_CTX *mem_ctx, struct MAPINAMEID **)" .br .ti -1c .RI "enum \fBmapistore_error\fP \fBmapistore_namedprops_get_nameid_type\fP (struct ldb_context *, uint16_t, uint16_t *)" .br .ti -1c .RI "uint16_t \fBmapistore_namedprops_next_unused_id\fP (struct ldb_context *)" .br .ti -1c .RI "enum \fBmapistore_error\fP \fBmapistore_release\fP (struct mapistore_context *)" .br .ti -1c .RI "enum \fBmapistore_error\fP \fBmapistore_replica_mapping_guid_to_replid\fP (struct mapistore_context *, const char *username, const struct GUID *, uint16_t *)" .br .ti -1c .RI "enum \fBmapistore_error\fP \fBmapistore_replica_mapping_replid_to_guid\fP (struct mapistore_context *, const char *username, uint16_t, struct GUID *)" .br .ti -1c .RI "enum \fBmapistore_error\fP \fBmapistore_search_context_by_uri\fP (struct mapistore_context *, const char *, uint32_t *, void **)" .br .ti -1c .RI "enum \fBmapistore_error\fP \fBmapistore_set_connection_info\fP (struct mapistore_context *, struct ldb_context *, struct ldb_context *, const char *)" .br .ti -1c .RI "enum \fBmapistore_error\fP \fBmapistore_set_mapping_path\fP (const char *)" .br .in -1c .SH "Detailed Description" .PP MAPISTORE general API\&. This header contains general functions, primarily for users of the store (rather than storage providers)\&. .SH "Function Documentation" .PP .SS "enum \fBmapistore_error\fP mapistore_add_context (struct mapistore_context *mstore_ctx, const char *owner, const char *uri, uint64_tfid, uint32_t *context_id, void **backend_object)" Add a new connection context to mapistore .PP \fBParameters:\fP .RS 4 \fImstore_ctx\fP pointer to the mapistore context .br \fIuri\fP the connection context URI .br \fIcontext_id\fP pointer to the context identifier the function returns .RE .PP \fBReturns:\fP .RS 4 MAPISTORE_SUCCESS on success, otherwise MAPISTORE error .RE .PP .PP References mapistore_add_context(), mapistore_backend_create_context(), MAPISTORE_ERR_CONTEXT_FAILED, MAPISTORE_ERR_INVALID_NAMESPACE, mapistore_indexing_add(), and MAPISTORE_SUCCESS\&. .PP Referenced by mapistore_add_context()\&. .SS "enum \fBmapistore_error\fP mapistore_add_context_ref_count (struct mapistore_context *mstore_ctx, uint32_tcontext_id)" Increase the reference counter of an existing context .PP \fBParameters:\fP .RS 4 \fImstore_ctx\fP pointer to the mapistore context .br \fIcontex_id\fP the context identifier referencing the context to update .RE .PP \fBReturns:\fP .RS 4 MAPISTORE_SUCCESS on success, otherwise MAPISTORE error .RE .PP .PP References mapistore_add_context_ref_count(), mapistore_backend_add_ref_count(), mapistore_backend_lookup(), MAPISTORE_ERR_INVALID_PARAMETER, and MAPISTORE_ERROR\&. .PP Referenced by mapistore_add_context_ref_count()\&. .SS "const char* mapistore_backend_get_installdir (void)" Return the full path where mapistore backends are installed\&. .PP \fBReturns:\fP .RS 4 Pointer to the full path where backends are installed\&. .RE .PP .PP Referenced by mapistore_backend_load()\&. .SS "init_backend_fn* mapistore_backend_load (TALLOC_CTX *mem_ctx, const char *path)" Load the initialization functions from backends DSO .PP \fBParameters:\fP .RS 4 \fImem_ctx\fP pointer to the memory context .br \fIpath\fP pointer to the backend's DSO folder .RE .PP \fBReturns:\fP .RS 4 allocated array of functions pointers to initialization functions on success, otherwise NULL\&. .RE .PP .PP References mapistore_backend_get_installdir()\&. .PP Referenced by mapistore_backend_init()\&. .SS "struct backend_context* mapistore_backend_lookup (struct backend_context_list *backend_list_ctx, uint32_tcontext_id)\fC [read]\fP" find the context matching given context identifier .PP \fBParameters:\fP .RS 4 \fIbackend_list_ctx\fP pointer to the backend context list .br \fIcontext_id\fP the context identifier to search .RE .PP \fBReturns:\fP .RS 4 Pointer to the mapistore_backend context on success, otherwise NULL .RE .PP .PP Referenced by mapistore_add_context_ref_count(), mapistore_del_context(), mapistore_folder_create_folder(), mapistore_folder_create_message(), mapistore_folder_delete(), mapistore_folder_delete_message(), mapistore_folder_get_child_count(), mapistore_folder_get_deleted_fmids(), mapistore_folder_open_folder(), mapistore_folder_open_message(), mapistore_indexing_record_add_fmid(), mapistore_indexing_record_del_fmid(), mapistore_message_get_message_data(), mapistore_message_modify_recipients(), mapistore_message_save(), mapistore_message_set_read_flag(), and mapistore_message_submit()\&. .SS "struct backend_context* mapistore_backend_lookup_by_name (TALLOC_CTX *mem_ctx, const char *name)\fC [read]\fP" Return a pointer on backend functions given its name .PP \fBParameters:\fP .RS 4 \fImem_ctx\fP pointer to the memory context .br \fIname\fP the backend name to lookup .RE .PP \fBReturns:\fP .RS 4 Allocated pointer to the mapistore_backend context on success, otherwise NULL .RE .PP .PP Referenced by mapistore_mgmt_generate_uri()\&. .SS "struct backend_context* mapistore_backend_lookup_by_uri (struct backend_context_list *backend_list_ctx, const char *uri)\fC [read]\fP" find the context matching given uri string .PP \fBParameters:\fP .RS 4 \fIbackend_list_ctx\fP pointer to the backend context list .br \fIuri\fP the uri string to search .RE .PP \fBReturns:\fP .RS 4 Pointer to the mapistore_backend context on success, otherwise NULL .RE .PP .PP Referenced by mapistore_search_context_by_uri()\&. .SS "enum \fBmapistore_error\fP mapistore_backend_register (const void *_backend)" Register mapistore backends .PP \fBParameters:\fP .RS 4 \fIbackend\fP pointer to the mapistore backend to register .RE .PP \fBReturns:\fP .RS 4 MAPISTORE_SUCCESS on success .RE .PP .PP References MAPISTORE_ERR_INVALID_PARAMETER, and MAPISTORE_SUCCESS\&. .SS "bool mapistore_backend_run_init (init_backend_fn *fns)" Run specified initialization functions\&. .PP \fBParameters:\fP .RS 4 \fIfns\fP pointer to an array of mapistore backends initialization functions .RE .PP \fBReturns:\fP .RS 4 true on success, otherwise false .RE .PP .PP Referenced by mapistore_backend_init()\&. .SS "enum \fBmapistore_error\fP mapistore_del_context (struct mapistore_context *mstore_ctx, uint32_tcontext_id)" Delete an existing connection context from mapistore .PP \fBParameters:\fP .RS 4 \fImstore_ctx\fP pointer to the mapistore context .br \fIcontext_id\fP the context identifier referencing the context to delete .RE .PP \fBReturns:\fP .RS 4 MAPISTORE_SUCCESS on success, otherwise MAPISTORE error .RE .PP .PP References mapistore_backend_delete_context(), mapistore_backend_lookup(), mapistore_del_context(), MAPISTORE_ERR_INVALID_PARAMETER, MAPISTORE_ERR_REF_COUNT, MAPISTORE_ERROR, and MAPISTORE_SUCCESS\&. .PP Referenced by mapistore_del_context()\&. .SS "const char* mapistore_errstr (enum \fBmapistore_error\fPmapistore_err)" return a string explaining what a mapistore error constant means\&. .PP \fBParameters:\fP .RS 4 \fImapistore_err\fP the mapistore error constant .RE .PP \fBReturns:\fP .RS 4 constant string .RE .PP .PP References MAPISTORE_ERR_ALREADY_INITIALIZED, MAPISTORE_ERR_BACKEND_INIT, MAPISTORE_ERR_BACKEND_REGISTER, MAPISTORE_ERR_CONTEXT_FAILED, MAPISTORE_ERR_CORRUPTED, MAPISTORE_ERR_DATABASE_INIT, MAPISTORE_ERR_DATABASE_OPS, MAPISTORE_ERR_DENIED, MAPISTORE_ERR_EXIST, MAPISTORE_ERR_INVALID_DATA, MAPISTORE_ERR_INVALID_NAMESPACE, MAPISTORE_ERR_INVALID_PARAMETER, MAPISTORE_ERR_MSG_RCV, MAPISTORE_ERR_MSG_SEND, MAPISTORE_ERR_NO_DIRECTORY, MAPISTORE_ERR_NO_MEMORY, MAPISTORE_ERR_NOT_FOUND, MAPISTORE_ERR_NOT_IMPLEMENTED, MAPISTORE_ERR_NOT_INITIALIZED, MAPISTORE_ERR_REF_COUNT, MAPISTORE_ERROR, mapistore_errstr(), and MAPISTORE_SUCCESS\&. .PP Referenced by mapistore_errstr(), and mapistore_init()\&. .SS "enum \fBmapistore_error\fP mapistore_folder_create_folder (struct mapistore_context *mstore_ctx, uint32_tcontext_id, void *folder, TALLOC_CTX *mem_ctx, uint64_tfid, struct SRow *aRow, void **child_folder)" Create a directory in mapistore .PP \fBParameters:\fP .RS 4 \fImstore_ctx\fP pointer to the mapistore context .br \fIcontext_id\fP the context identifier referencing the backend where the directory will be created .br \fIparent_fid\fP the parent folder identifier .br \fInew_fid\fP the folder identifier for the new folder .br \fIaRow\fP pointer to MAPI data structures with properties to be added to the new folder .RE .PP \fBReturns:\fP .RS 4 MAPISTORE_SUCCESS on success, otherwise MAPISTORE errors .RE .PP .PP References mapistore_backend_lookup(), MAPISTORE_ERR_INVALID_PARAMETER, and mapistore_folder_create_folder()\&. .PP Referenced by mapistore_folder_create_folder()\&. .SS "enum \fBmapistore_error\fP mapistore_folder_create_message (struct mapistore_context *mstore_ctx, uint32_tcontext_id, void *folder, TALLOC_CTX *mem_ctx, uint64_tmid, uint8_tassociated, void **messagep)" Create a message in mapistore .PP \fBParameters:\fP .RS 4 \fImstore_ctx\fP pointer to the mapistore context .br \fIcontext_id\fP the context identifier referencing the backend where the messagewill be created .br \fIparent_fid\fP the parent folder identifier .br \fImid\fP the message identifier to create .RE .PP \fBReturns:\fP .RS 4 MAPISTORE_SUCCESS on success, otherwise MAPISTORE errors .RE .PP .PP References mapistore_backend_lookup(), MAPISTORE_ERR_INVALID_PARAMETER, and mapistore_folder_create_message()\&. .PP Referenced by mapistore_folder_create_message()\&. .SS "enum \fBmapistore_error\fP mapistore_folder_delete (struct mapistore_context *mstore_ctx, uint32_tcontext_id, void *folder, uint8_tflags)" Remove a directory in mapistore .PP \fBParameters:\fP .RS 4 \fImstore_ctx\fP pointer to the mapistore context .br \fIcontext_id\fP the context identifier referencing the backend .br \fIparent_fid\fP the parent folder identifier .br \fIfid\fP the folder identifier representing the folder to delete .br \fIflags\fP flags that control the behaviour of the operation .RE .PP \fBReturns:\fP .RS 4 MAPISTORE_SUCCESS on success, otherwise MAPISTORE errors .RE .PP .PP References mapistore_backend_lookup(), MAPISTORE_ERR_EXIST, MAPISTORE_ERR_INVALID_PARAMETER, mapistore_folder_delete(), and MAPISTORE_SUCCESS\&. .PP Referenced by mapistore_folder_delete()\&. .SS "enum \fBmapistore_error\fP mapistore_folder_delete_message (struct mapistore_context *mstore_ctx, uint32_tcontext_id, void *folder, uint64_tmid, uint8_tflags)" Delete a message from mapistore .PP \fBParameters:\fP .RS 4 \fImstore_ctx\fP pointer to the mapistore context .br \fIcontext_id\fP the context identifier referencing the backend where the message's to be located is stored .br \fImid\fP the message identifier of the folder to delete .br \fIflags\fP flags that control the behaviour of the operation (MAPISTORE_SOFT_DELETE or MAPISTORE_PERMANENT_DELETE) .RE .PP \fBReturns:\fP .RS 4 MAPISTORE_SUCCESS on success, otherwise MAPISTORE errors .RE .PP .PP References mapistore_backend_lookup(), MAPISTORE_ERR_INVALID_PARAMETER, and mapistore_folder_delete_message()\&. .PP Referenced by mapistore_folder_delete_message()\&. .SS "enum \fBmapistore_error\fP mapistore_folder_get_child_count (struct mapistore_context *mstore_ctx, uint32_tcontext_id, void *folder, enum mapistore_table_typetable_type, uint32_t *RowCount)" Retrieve the number of child messages within a mapistore folder .PP \fBParameters:\fP .RS 4 \fImstore_ctx\fP pointer to the mapistore context .br \fIcontext_id\fP the context identifier referencing the backend .br \fIfid\fP the folder identifier .br \fIRowCount\fP pointer to the count result to return .RE .PP \fBReturns:\fP .RS 4 MAPISTORE_SUCCESS on success, otherwise MAPISTORE errors .RE .PP .PP References mapistore_backend_lookup(), MAPISTORE_ERR_INVALID_PARAMETER, and mapistore_folder_get_child_count()\&. .PP Referenced by mapistore_folder_get_child_count()\&. .SS "enum \fBmapistore_error\fP mapistore_folder_get_deleted_fmids (struct mapistore_context *mstore_ctx, uint32_tcontext_id, void *folder, TALLOC_CTX *mem_ctx, enum mapistore_table_typetable_type, uint64_tchange_num, struct UI8Array_r **fmidsp, uint64_t *cnp)" Get the array of deleted items following a specific change number .PP \fBParameters:\fP .RS 4 \fImstore_ctx\fP pointer to the mapistore context .br \fIcontext_id\fP the context identifier referencing the backend where the message's to be located is stored .br \fIfolder\fP the folder backend object .br \fImem_ctx\fP the TALLOC_CTX that should be used as parent for the returned array .br \fItable_type\fP the type of object that we want to take into account .br \fIchange_num\fP the reference change number .br \fIfmidsp\fP a pointer to the returned array .RE .PP \fBReturns:\fP .RS 4 MAPISTORE_SUCCESS on success, otherwise MAPISTORE errors .RE .PP .PP References mapistore_backend_lookup(), MAPISTORE_ERR_INVALID_PARAMETER, and mapistore_folder_get_deleted_fmids()\&. .PP Referenced by mapistore_folder_get_deleted_fmids()\&. .SS "enum \fBmapistore_error\fP mapistore_folder_open_folder (struct mapistore_context *mstore_ctx, uint32_tcontext_id, void *folder, TALLOC_CTX *mem_ctx, uint64_tfid, void **child_folder)" Open a directory in mapistore .PP \fBParameters:\fP .RS 4 \fImstore_ctx\fP pointer to the mapistore context .br \fIcontext_id\fP the context identifier referencing the backend where the directory will be opened .br \fIparent_fid\fP the parent folder identifier .br \fIfid\fP folder identifier to open .RE .PP \fBReturns:\fP .RS 4 MAPISTORE_SUCCESS on success, otherwise MAPISTORE errors .RE .PP .PP References mapistore_backend_lookup(), MAPISTORE_ERR_INVALID_PARAMETER, and mapistore_folder_open_folder()\&. .PP Referenced by mapistore_folder_open_folder()\&. .SS "enum \fBmapistore_error\fP mapistore_folder_open_message (struct mapistore_context *mstore_ctx, uint32_tcontext_id, void *folder, TALLOC_CTX *mem_ctx, uint64_tmid, boolread_write, void **messagep)" Open a message in mapistore .PP \fBParameters:\fP .RS 4 \fImstore_ctx\fP pointer to the mapistore context .br \fIcontext_id\fP the context identifier referencing the backend where the directory will be opened .br \fIparent_fid\fP the parent folder identifier .br \fImid\fP the message identifier to open .br \fIpointer\fP to the mapistore_message structure .RE .PP \fBReturns:\fP .RS 4 MAPISTORE SUCCESS on success, otherwise MAPISTORE errors .RE .PP .PP References mapistore_backend_lookup(), MAPISTORE_ERR_INVALID_PARAMETER, and mapistore_folder_open_message()\&. .PP Referenced by mapistore_folder_open_message()\&. .SS "enum MAPISTATUS mapistore_get_queued_notifications (struct mapistore_context *mstore_ctx, struct mapistore_subscription *s, struct mapistore_notification_list **nl)" Return the list of pending mapistore notifications within the queue pointed by the mapistore subscription structure\&. .PP \fBParameters:\fP .RS 4 \fImstore_ctx\fP pointer to the mapistore context .br \fIs\fP pointer to the mapistore subscription where the mqueue file descriptor is stored .br \fInl\fP pointer on pointer to the list of mapistore noficiations to return .RE .PP \fBReturns:\fP .RS 4 MAPISTORE_SUCCESS on success, otherwise MAPISTORE error .RE .PP .PP References MAPISTORE_ERR_INVALID_PARAMETER, MAPISTORE_ERR_NOT_FOUND, MAPISTORE_ERR_NOT_INITIALIZED, mapistore_get_queued_notifications(), and MAPISTORE_SUCCESS\&. .PP Referenced by mapistore_get_queued_notifications()\&. .SS "enum MAPISTATUS mapistore_get_queued_notifications_named (struct mapistore_context *mstore_ctx, const char *mqueue_name, struct mapistore_notification_list **nl)" Return the list of pending mapistore notifications available on the queue name specified in argument\&. .PP \fBParameters:\fP .RS 4 \fImstore_ctx\fP pointer to the mapistore context .br \fImqueue_name\fP the name of the queue to open .br \fInl\fP pointer on pointer to the list of mapistore notifications to return .RE .PP \fBReturns:\fP .RS 4 MAPISTORE_SUCCESS on success, otherwise MAPISTORE error\&. .RE .PP .PP References MAPISTORE_ERR_INVALID_PARAMETER, MAPISTORE_ERR_NOT_FOUND, MAPISTORE_ERR_NOT_INITIALIZED, mapistore_get_queued_notifications_named(), and MAPISTORE_SUCCESS\&. .PP Referenced by mapistore_get_queued_notifications_named()\&. .SS "enum \fBmapistore_error\fP mapistore_indexing_record_add_fid (struct mapistore_context *mstore_ctx, uint32_tcontext_id, const char *username, uint64_tfid)" Add a fid record to the indexing database .PP \fBParameters:\fP .RS 4 \fImstore_ctx\fP pointer to the mapistore context .br \fIcontext_id\fP the context identifier referencing the indexing database to update .br \fIfid\fP the fid to add .RE .PP \fBNote:\fP .RS 4 This is a wrapper to the internal common mapistore_indexing_record_add_fmid function\&. .RE .PP \fBReturns:\fP .RS 4 MAPISTORE_SUCCESS on success, otherwise MAPISTORE error .RE .PP .PP References mapistore_indexing_record_add_fmid()\&. .SS "enum \fBmapistore_error\fP mapistore_indexing_record_add_mid (struct mapistore_context *mstore_ctx, uint32_tcontext_id, const char *username, uint64_tmid)" Add a mid record to the indexing database .PP \fBParameters:\fP .RS 4 \fImstore_ctx\fP pointer to the mapistore context .br \fIcontext_id\fP the context identifier referencing the indexing database to update .br \fImid\fP the mid to add .RE .PP \fBNote:\fP .RS 4 This is a wrapper to the internal common mapistore_indexing_record_add_fmid function\&. .RE .PP \fBReturns:\fP .RS 4 MAPISTORE_SUCCESS on success, otherwise MAPISTORE error .RE .PP .PP References mapistore_indexing_record_add_fmid()\&. .SS "enum \fBmapistore_error\fP mapistore_indexing_record_del_fid (struct mapistore_context *mstore_ctx, uint32_tcontext_id, const char *username, uint64_tfid, uint8_tflags)" Delete a fid record from the indexing database .PP \fBParameters:\fP .RS 4 \fImstore_ctx\fP pointer to the mapistore context .br \fIcontext_id\fP the context identifier referencing the indexing database to update .br \fIfid\fP the fid to remove .br \fIflags\fP the type of deletion MAPISTORE_SOFT_DELETE or MAPISTORE_PERMANENT_DELETE .RE .PP \fBReturns:\fP .RS 4 MAPISTORE_SUCCESS on success, otherwise MAPISTORE error .RE .PP .PP References mapistore_indexing_record_del_fmid()\&. .SS "enum \fBmapistore_error\fP mapistore_indexing_record_del_mid (struct mapistore_context *mstore_ctx, uint32_tcontext_id, const char *username, uint64_tmid, uint8_tflags)" Delete a mid record from the indexing database .PP \fBParameters:\fP .RS 4 \fImstore_ctx\fP pointer to the mapistore context .br \fIcontext_id\fP the context identifier referencing the indexing database to update .br \fImid\fP the mid to remove .br \fIflags\fP the type of deletion MAPISTORE_SOFT_DELETE or MAPISTORE_PERMANENT_DELETE .RE .PP \fBReturns:\fP .RS 4 MAPISTORE_SUCCESS on success, otherwise MAPISTORE error .RE .PP .PP References mapistore_indexing_record_del_fmid()\&. .SS "enum \fBmapistore_error\fP mapistore_indexing_record_get_uri (struct mapistore_context *mstore_ctx, const char *username, TALLOC_CTX *mem_ctx, uint64_tfmid, char **urip, bool *soft_deletedp)" Returns record data .PP \fBParameters:\fP .RS 4 \fImstore_ctx\fP pointer to the mapistore context .br \fIusername\fP the name of the account where to look for the indexing database .br \fImem_ctx\fP pointer to the memory context .br \fIfmid\fP the fmid/key to the record .br \fIurip\fP pointer to the uri pointer .br \fIsoft_deletedp\fP pointer to the soft deleted pointer .RE .PP \fBReturns:\fP .RS 4 MAPISTORE_SUCCESS on success, otherwise MAPISTORE error .RE .PP .PP References MAPISTORE_ERR_NOT_FOUND, MAPISTORE_ERR_NOT_INITIALIZED, MAPISTORE_ERROR, mapistore_indexing_add(), and MAPISTORE_SUCCESS\&. .SS "struct mapistore_context* mapistore_init (TALLOC_CTX *mem_ctx, struct loadparm_context *lp_ctx, const char *path)\fC [read]\fP" Initialize the mapistore context .PP \fBParameters:\fP .RS 4 \fImem_ctx\fP pointer to the memory context .br \fIpath\fP the path to the location to load the backend providers from (NULL for default) .RE .PP \fBReturns:\fP .RS 4 allocate mapistore context on success, otherwise NULL .RE .PP .PP References mapistore_backend_init(), mapistore_errstr(), mapistore_init(), mapistore_set_mapping_path(), and MAPISTORE_SUCCESS\&. .PP Referenced by mapistore_init()\&. .SS "enum \fBmapistore_error\fP mapistore_message_get_message_data (struct mapistore_context *mstore_ctx, uint32_tcontext_id, void *message, TALLOC_CTX *mem_ctx, struct mapistore_message **msg)" Modify recipients of a message in mapistore .PP \fBParameters:\fP .RS 4 \fImstore_ctx\fP pointer to the mapistore context .br \fIcontext_id\fP the context identifier referencing the backend where properties will be stored .br \fImid\fP the identifier referencing the message the array of recipient rows the number of elements in the array .RE .PP \fBReturns:\fP .RS 4 MAPISTORE_SUCCESS on success, otherwise MAPISTORE errors .RE .PP .PP References mapistore_backend_lookup(), MAPISTORE_ERR_INVALID_PARAMETER, and mapistore_message_get_message_data()\&. .PP Referenced by mapistore_message_get_message_data()\&. .SS "enum \fBmapistore_error\fP mapistore_message_modify_recipients (struct mapistore_context *mstore_ctx, uint32_tcontext_id, void *message, struct SPropTagArray *columns, uint16_tcount, struct mapistore_message_recipient *recipients)" Modify recipients of a message in mapistore .PP \fBParameters:\fP .RS 4 \fImstore_ctx\fP pointer to the mapistore context .br \fIcontext_id\fP the context identifier referencing the backend where properties will be stored .br \fImid\fP the identifier referencing the message the array of recipient rows the number of elements in the array .RE .PP \fBReturns:\fP .RS 4 MAPISTORE_SUCCESS on success, otherwise MAPISTORE errors .RE .PP .PP References mapistore_backend_lookup(), MAPISTORE_ERR_INVALID_PARAMETER, and mapistore_message_modify_recipients()\&. .PP Referenced by mapistore_message_modify_recipients()\&. .SS "enum \fBmapistore_error\fP mapistore_message_save (struct mapistore_context *mstore_ctx, uint32_tcontext_id, void *message)" Commit the changes made to a message in mapistore .PP \fBParameters:\fP .RS 4 \fImstore_ctx\fP pointer to the mapistore context .br \fIcontext_id\fP the context identifier referencing the backend where the message's changes will be saved .br \fImid\fP the message identifier to save .br \fIflags\fP flags associated to the commit operation .RE .PP \fBReturns:\fP .RS 4 MAPISTORE_SUCCESS on success, otherwise MAPISTORE errors .RE .PP .PP References mapistore_backend_lookup(), MAPISTORE_ERR_INVALID_PARAMETER, and mapistore_message_save()\&. .PP Referenced by mapistore_message_save()\&. .SS "enum \fBmapistore_error\fP mapistore_message_set_read_flag (struct mapistore_context *mstore_ctx, uint32_tcontext_id, void *message, uint8_tflag)" Commit the changes made to a message in mapistore .PP \fBParameters:\fP .RS 4 \fImstore_ctx\fP pointer to the mapistore context .br \fIcontext_id\fP the context identifier referencing the backend where the message's changes will be saved .br \fImid\fP the message identifier to save .br \fIflags\fP flags associated to the commit operation .RE .PP \fBReturns:\fP .RS 4 MAPISTORE_SUCCESS on success, otherwise MAPISTORE errors .RE .PP .PP References mapistore_backend_lookup(), MAPISTORE_ERR_INVALID_PARAMETER, and mapistore_message_set_read_flag()\&. .PP Referenced by mapistore_message_set_read_flag()\&. .SS "enum \fBmapistore_error\fP mapistore_message_submit (struct mapistore_context *mstore_ctx, uint32_tcontext_id, void *message, enum SubmitFlagsflags)" Submits a message for sending\&. .PP \fBParameters:\fP .RS 4 \fImstore_ctx\fP pointer to the mapistore context .br \fIcontext_id\fP the context identifier referencing the backend where the message will be submitted .br \fImid\fP the message identifier representing the message to submit .br \fIflags\fP flags associated to the submit operation .RE .PP \fBReturns:\fP .RS 4 MAPISTORE_SUCCESS on success, otherwise MAPISTORE errors .RE .PP .PP References mapistore_backend_lookup(), MAPISTORE_ERR_INVALID_PARAMETER, and mapistore_message_submit()\&. .PP Referenced by mapistore_message_submit()\&. .SS "enum \fBmapistore_error\fP mapistore_namedprops_create_id (struct ldb_context *ldb_ctx, struct MAPINAMEIDnameid, uint16_tmapped_id)" return the mapped property ID matching the nameid structure passed in parameter\&. .PP \fBParameters:\fP .RS 4 \fIldb_ctx\fP pointer to the namedprops ldb context .br \fInameid\fP the MAPINAMEID structure to lookup .br \fIpropID\fP pointer to the property ID the function returns .RE .PP \fBReturns:\fP .RS 4 MAPISTORE_SUCCESS on success, otherwise MAPISTORE_ERROR .RE .PP .PP References MAPISTORE_ERR_DATABASE_INIT, and mapistore_namedprops_create_id()\&. .PP Referenced by mapistore_namedprops_create_id()\&. .SS "enum \fBmapistore_error\fP mapistore_namedprops_get_mapped_id (struct ldb_context *ldb_ctx, struct MAPINAMEIDnameid, uint16_t *propID)" return the mapped property ID matching the nameid structure passed in parameter\&. .PP \fBParameters:\fP .RS 4 \fIldb_ctx\fP pointer to the namedprops ldb context .br \fInameid\fP the MAPINAMEID structure to lookup .br \fIpropID\fP pointer to the property ID the function returns .RE .PP \fBReturns:\fP .RS 4 MAPISTORE_SUCCESS on success, otherwise MAPISTORE_ERROR .RE .PP .PP References MAPISTORE_ERROR, mapistore_namedprops_get_mapped_id(), and MAPISTORE_SUCCESS\&. .PP Referenced by mapistore_namedprops_get_mapped_id()\&. .SS "enum \fBmapistore_error\fP mapistore_namedprops_get_nameid (struct ldb_context *ldb_ctx, uint16_tpropID, TALLOC_CTX *mem_ctx, struct MAPINAMEID **nameidp)" return the nameid structture matching the mapped property ID passed in parameter\&. .PP \fBParameters:\fP .RS 4 \fIldb_ctx\fP pointer to the namedprops ldb context .br \fIpropID\fP the property ID to lookup .br \fInameid\fP pointer to the MAPINAMEID structure the function returns .RE .PP \fBReturns:\fP .RS 4 MAPISTORE_SUCCESS on success, otherwise MAPISTORE_ERROR .RE .PP .PP References MAPISTORE_ERROR, mapistore_namedprops_get_nameid(), and MAPISTORE_SUCCESS\&. .PP Referenced by mapistore_namedprops_get_nameid()\&. .SS "enum \fBmapistore_error\fP mapistore_namedprops_get_nameid_type (struct ldb_context *ldb_ctx, uint16_tpropID, uint16_t *propTypeP)" return the type matching the mapped property ID passed in parameter\&. .PP \fBParameters:\fP .RS 4 \fIldb_ctx\fP pointer to the namedprops ldb context .br \fIpropID\fP the property ID to lookup .br \fIpropTypeP\fP pointer to the uint16_t that will receive the property type .RE .PP \fBReturns:\fP .RS 4 MAPISTORE_SUCCESS on success, otherwise MAPISTORE_ERROR .RE .PP .PP References MAPISTORE_ERROR, mapistore_namedprops_get_nameid_type(), and MAPISTORE_SUCCESS\&. .PP Referenced by mapistore_namedprops_get_nameid_type()\&. .SS "uint16_t mapistore_namedprops_next_unused_id (struct ldb_context *ldb_ctx)" return the next unmapped property ID .PP \fBParameters:\fP .RS 4 \fIldb_ctx\fP pointer to the namedprops ldb context .RE .PP \fBReturns:\fP .RS 4 0 on error, the next mapped id otherwise .RE .PP .PP References mapistore_namedprops_next_unused_id()\&. .PP Referenced by mapistore_namedprops_next_unused_id()\&. .SS "enum \fBmapistore_error\fP mapistore_release (struct mapistore_context *mstore_ctx)" Release the mapistore context and destroy any data associated .PP \fBParameters:\fP .RS 4 \fImstore_ctx\fP pointer to the mapistore context .RE .PP \fBNote:\fP .RS 4 The function needs to rely on talloc destructors which is not implemented in code yet\&. .RE .PP \fBReturns:\fP .RS 4 MAPISTORE_SUCCESS on success, otherwise MAPISTORE error .RE .PP .PP References MAPISTORE_ERR_NOT_INITIALIZED, mapistore_release(), and MAPISTORE_SUCCESS\&. .PP Referenced by mapistore_release()\&. .SS "enum \fBmapistore_error\fP mapistore_replica_mapping_guid_to_replid (struct mapistore_context *mstore_ctx, const char *username, const struct GUID *guidP, uint16_t *replidP)" Search a replica guid in the database, creates it if it does not exist .PP \fBParameters:\fP .RS 4 \fImstore_ctx\fP pointer to the mapistore context .br \fIguidP\fP the replica guid .br \fIreplidP\fP pointer to the returned replica id .RE .PP \fBReturns:\fP .RS 4 MAPISTORE_SUCCESS on success, otherwise MAPISTORE error .RE .PP .PP References MAPISTORE_ERROR, mapistore_replica_mapping_guid_to_replid(), and MAPISTORE_SUCCESS\&. .PP Referenced by mapistore_replica_mapping_guid_to_replid()\&. .SS "enum \fBmapistore_error\fP mapistore_replica_mapping_replid_to_guid (struct mapistore_context *mstore_ctx, const char *username, uint16_treplid, struct GUID *guidP)" Search a replica id in the database .PP \fBParameters:\fP .RS 4 \fImstore_ctx\fP pointer to the mapistore context .br \fIreplid\fP the replica id .br \fIguidP\fP pointer to the returned replica guid .RE .PP \fBReturns:\fP .RS 4 MAPISTORE_SUCCESS on success, otherwise MAPISTORE error .RE .PP .PP References MAPISTORE_ERROR, mapistore_replica_mapping_replid_to_guid(), and MAPISTORE_SUCCESS\&. .PP Referenced by mapistore_replica_mapping_replid_to_guid()\&. .SS "enum \fBmapistore_error\fP mapistore_search_context_by_uri (struct mapistore_context *mstore_ctx, const char *uri, uint32_t *context_id, void **backend_object)" Search for an existing context given its uri .PP \fBParameters:\fP .RS 4 \fImstore_ctx\fP pointer to the mapistore context .br \fIuri\fP the URI to lookup .br \fIcontext_id\fP pointer to the context identifier to return .RE .PP \fBReturns:\fP .RS 4 MAPISTORE_SUCCESS on success, otherwise MAPISTORE error .RE .PP .PP References mapistore_backend_lookup_by_uri(), MAPISTORE_ERR_NOT_FOUND, MAPISTORE_ERROR, mapistore_search_context_by_uri(), and MAPISTORE_SUCCESS\&. .PP Referenced by mapistore_search_context_by_uri()\&. .SS "enum \fBmapistore_error\fP mapistore_set_connection_info (struct mapistore_context *mstore_ctx, struct ldb_context *sam_ctx, struct ldb_context *oc_ctx, const char *username)" Set connection info for current mapistore context .PP \fBParameters:\fP .RS 4 \fImstore_ctx\fP pointer to the mapistore context .br \fIoc_ctx\fP pointer to the openchange ldb database .br \fIusername\fP pointer to the current username .RE .PP \fBReturns:\fP .RS 4 MAPISTORE_SUCCESS on success, otherwise MAPISTORE error .RE .PP .PP References MAPISTORE_ERR_INVALID_PARAMETER, MAPISTORE_ERR_NOT_INITIALIZED, mapistore_set_connection_info(), and MAPISTORE_SUCCESS\&. .PP Referenced by mapistore_set_connection_info()\&. .SS "enum \fBmapistore_error\fP mapistore_set_mapping_path (const char *path)" Set the mapping path .PP \fBParameters:\fP .RS 4 \fIpath\fP pointer to the mapping path .RE .PP \fBNote:\fP .RS 4 The mapping path can be set unless id_mapping_context is initialized\&. If path is NULL and mapping path is not yet initialized, then mapping_path will be reset to its default value when the initialization routine is called\&. .RE .PP \fBReturns:\fP .RS 4 MAPISTORE_SUCCESS on success, otherwise MAPISTORE error .RE .PP .PP References MAPISTORE_ERR_NO_DIRECTORY, mapistore_set_mapping_path(), and MAPISTORE_SUCCESS\&. .PP Referenced by mapistore_init(), and mapistore_set_mapping_path()\&. .SH "Author" .PP Generated automatically by Doxygen for OpenChange mapistore library from the source code\&. openchange-2.0/apidocs/man/man3/mapistore_add_context.3000066400000000000000000000000271223057412600231610ustar00rootroot00000000000000.so man3/mapistore.h.3 openchange-2.0/apidocs/man/man3/mapistore_add_context_ref_count.3000066400000000000000000000000271223057412600252250ustar00rootroot00000000000000.so man3/mapistore.h.3 openchange-2.0/apidocs/man/man3/mapistore_backend_add_ref_count.3000066400000000000000000000000371223057412600251310ustar00rootroot00000000000000.so man3/mapistore_backend.c.3 openchange-2.0/apidocs/man/man3/mapistore_backend_create_context.3000066400000000000000000000000371223057412600253440ustar00rootroot00000000000000.so man3/mapistore_backend.c.3 openchange-2.0/apidocs/man/man3/mapistore_backend_delete_context.3000066400000000000000000000000371223057412600253430ustar00rootroot00000000000000.so man3/mapistore_backend.c.3 openchange-2.0/apidocs/man/man3/mapistore_backend_get_installdir.3000066400000000000000000000000271223057412600253400ustar00rootroot00000000000000.so man3/mapistore.h.3 openchange-2.0/apidocs/man/man3/mapistore_backend_init.3000066400000000000000000000000371223057412600233000ustar00rootroot00000000000000.so man3/mapistore_backend.c.3 openchange-2.0/apidocs/man/man3/mapistore_backend_list_contexts.3000066400000000000000000000000371223057412600252370ustar00rootroot00000000000000.so man3/mapistore_backend.c.3 openchange-2.0/apidocs/man/man3/mapistore_backend_load.3000066400000000000000000000000271223057412600232530ustar00rootroot00000000000000.so man3/mapistore.h.3 openchange-2.0/apidocs/man/man3/mapistore_backend_lookup.3000066400000000000000000000000271223057412600236450ustar00rootroot00000000000000.so man3/mapistore.h.3 openchange-2.0/apidocs/man/man3/mapistore_backend_lookup_by_name.3000066400000000000000000000000271223057412600253370ustar00rootroot00000000000000.so man3/mapistore.h.3 openchange-2.0/apidocs/man/man3/mapistore_backend_lookup_by_uri.3000066400000000000000000000000271223057412600252160ustar00rootroot00000000000000.so man3/mapistore.h.3 openchange-2.0/apidocs/man/man3/mapistore_backend_register.3000066400000000000000000000000271223057412600241600ustar00rootroot00000000000000.so man3/mapistore.h.3 openchange-2.0/apidocs/man/man3/mapistore_backend_registered.3000066400000000000000000000000371223057412600244720ustar00rootroot00000000000000.so man3/mapistore_backend.c.3 openchange-2.0/apidocs/man/man3/mapistore_backend_run_init.3000066400000000000000000000000271223057412600241630ustar00rootroot00000000000000.so man3/mapistore.h.3 openchange-2.0/apidocs/man/man3/mapistore_del_context.3000066400000000000000000000000271223057412600231750ustar00rootroot00000000000000.so man3/mapistore.h.3 openchange-2.0/apidocs/man/man3/mapistore_error.3000066400000000000000000000000361223057412600220160ustar00rootroot00000000000000.so man3/mapistore_errors.h.3 openchange-2.0/apidocs/man/man3/mapistore_errors.h.3000066400000000000000000000075761223057412600224470ustar00rootroot00000000000000.TH "mapiproxy/libmapistore/mapistore_errors.h" 3 "Thu Jan 24 2013" "Version 2.0" "OpenChange mapistore library" \" -*- nroff -*- .ad l .nh .SH NAME mapiproxy/libmapistore/mapistore_errors.h \- .PP This header provides a set of result codes for MAPISTORE function calls\&. .SH SYNOPSIS .br .PP .SS "Enumerations" .in +1c .ti -1c .RI "enum \fBmapistore_error\fP { \fBMAPISTORE_SUCCESS\fP = 0, \fBMAPISTORE_ERROR\fP = 1, \fBMAPISTORE_ERR_NO_MEMORY\fP = 2, \fBMAPISTORE_ERR_ALREADY_INITIALIZED\fP = 3, \fBMAPISTORE_ERR_NOT_INITIALIZED\fP = 4, \fBMAPISTORE_ERR_CORRUPTED\fP = 5, \fBMAPISTORE_ERR_INVALID_PARAMETER\fP = 6, \fBMAPISTORE_ERR_NO_DIRECTORY\fP = 7, \fBMAPISTORE_ERR_DATABASE_INIT\fP = 8, \fBMAPISTORE_ERR_DATABASE_OPS\fP = 9, \fBMAPISTORE_ERR_BACKEND_REGISTER\fP = 10, \fBMAPISTORE_ERR_BACKEND_INIT\fP = 11, \fBMAPISTORE_ERR_CONTEXT_FAILED\fP = 12, \fBMAPISTORE_ERR_INVALID_NAMESPACE\fP = 13, \fBMAPISTORE_ERR_NOT_FOUND\fP = 14, \fBMAPISTORE_ERR_REF_COUNT\fP = 15, \fBMAPISTORE_ERR_EXIST\fP = 16, \fBMAPISTORE_ERR_INVALID_DATA\fP = 17, \fBMAPISTORE_ERR_MSG_SEND\fP = 18, \fBMAPISTORE_ERR_MSG_RCV\fP = 19, \fBMAPISTORE_ERR_DENIED\fP = 20, \fBMAPISTORE_ERR_NOT_IMPLEMENTED\fP }" .br .in -1c .SH "Detailed Description" .PP This header provides a set of result codes for MAPISTORE function calls\&. .SH "Enumeration Type Documentation" .PP .SS "enum \fBmapistore_error\fP" .PP \fBEnumerator: \fP .in +1c .TP \fB\fIMAPISTORE_SUCCESS \fP\fP The function call succeeded\&. .TP \fB\fIMAPISTORE_ERROR \fP\fP The function call failed for some non-specific reason\&. .TP \fB\fIMAPISTORE_ERR_NO_MEMORY \fP\fP The function call failed because it was unable to allocate the memory required by underlying operations\&. .TP \fB\fIMAPISTORE_ERR_ALREADY_INITIALIZED \fP\fP The function call failed because underlying context has already been initialized\&. .TP \fB\fIMAPISTORE_ERR_NOT_INITIALIZED \fP\fP The function call failed because context has not been initialized\&. .TP \fB\fIMAPISTORE_ERR_CORRUPTED \fP\fP The function call failed because an internal mapistore storage component has corrupted data\&. .TP \fB\fIMAPISTORE_ERR_INVALID_PARAMETER \fP\fP The function call failed because one of the function parameters is invalid\&. .TP \fB\fIMAPISTORE_ERR_NO_DIRECTORY \fP\fP The function call failed because the directory doesn't exist\&. .TP \fB\fIMAPISTORE_ERR_DATABASE_INIT \fP\fP The function call failed because the underlying function couldn't open a database\&. .TP \fB\fIMAPISTORE_ERR_DATABASE_OPS \fP\fP The function call failed because the underlying function didn't run a database operation successfully\&. .TP \fB\fIMAPISTORE_ERR_BACKEND_REGISTER \fP\fP The function failed to register a storage backend\&. .TP \fB\fIMAPISTORE_ERR_BACKEND_INIT \fP\fP One of more storage backend initialization functions failed to complete successfully\&. .TP \fB\fIMAPISTORE_ERR_CONTEXT_FAILED \fP\fP The function failed because mapistore failed to create a context\&. .TP \fB\fIMAPISTORE_ERR_INVALID_NAMESPACE \fP\fP The function failed because the provided namespace is invalid\&. .TP \fB\fIMAPISTORE_ERR_NOT_FOUND \fP\fP The function failed to find requested record/data\&. .TP \fB\fIMAPISTORE_ERR_REF_COUNT \fP\fP The function still has a reference count\&. .TP \fB\fIMAPISTORE_ERR_EXIST \fP\fP The function already have record/data for the searched element\&. .TP \fB\fIMAPISTORE_ERR_INVALID_DATA \fP\fP The function failed to generate requested data/payload\&. .TP \fB\fIMAPISTORE_ERR_MSG_SEND \fP\fP The function failed to send message\&. .TP \fB\fIMAPISTORE_ERR_MSG_RCV \fP\fP The function failed to receive message\&. .TP \fB\fIMAPISTORE_ERR_DENIED \fP\fP The operation required privileges that the user does not have\&. .TP \fB\fIMAPISTORE_ERR_NOT_IMPLEMENTED \fP\fP The function is not implemented\&. .SH "Author" .PP Generated automatically by Doxygen for OpenChange mapistore library from the source code\&. openchange-2.0/apidocs/man/man3/mapistore_errstr.3000066400000000000000000000000271223057412600222060ustar00rootroot00000000000000.so man3/mapistore.h.3 openchange-2.0/apidocs/man/man3/mapistore_folder_create_folder.3000066400000000000000000000000271223057412600250160ustar00rootroot00000000000000.so man3/mapistore.h.3 openchange-2.0/apidocs/man/man3/mapistore_folder_create_message.3000066400000000000000000000000271223057412600251670ustar00rootroot00000000000000.so man3/mapistore.h.3 openchange-2.0/apidocs/man/man3/mapistore_folder_delete.3000066400000000000000000000000271223057412600234620ustar00rootroot00000000000000.so man3/mapistore.h.3 openchange-2.0/apidocs/man/man3/mapistore_folder_delete_message.3000066400000000000000000000000271223057412600251660ustar00rootroot00000000000000.so man3/mapistore.h.3 openchange-2.0/apidocs/man/man3/mapistore_folder_get_child_count.3000066400000000000000000000000271223057412600253520ustar00rootroot00000000000000.so man3/mapistore.h.3 openchange-2.0/apidocs/man/man3/mapistore_folder_get_deleted_fmids.3000066400000000000000000000000271223057412600256470ustar00rootroot00000000000000.so man3/mapistore.h.3 openchange-2.0/apidocs/man/man3/mapistore_folder_open_folder.3000066400000000000000000000000271223057412600245140ustar00rootroot00000000000000.so man3/mapistore.h.3 openchange-2.0/apidocs/man/man3/mapistore_folder_open_message.3000066400000000000000000000000271223057412600246650ustar00rootroot00000000000000.so man3/mapistore.h.3 openchange-2.0/apidocs/man/man3/mapistore_get_queued_notifications.3000066400000000000000000000000271223057412600257450ustar00rootroot00000000000000.so man3/mapistore.h.3 openchange-2.0/apidocs/man/man3/mapistore_get_queued_notifications_named.3000066400000000000000000000000271223057412600271110ustar00rootroot00000000000000.so man3/mapistore.h.3 openchange-2.0/apidocs/man/man3/mapistore_indexing_add.3000066400000000000000000000000401223057412600232750ustar00rootroot00000000000000.so man3/mapistore_indexing.c.3 openchange-2.0/apidocs/man/man3/mapistore_indexing_record_add_fid.3000066400000000000000000000000271223057412600254620ustar00rootroot00000000000000.so man3/mapistore.h.3 openchange-2.0/apidocs/man/man3/mapistore_indexing_record_add_fmid.3000066400000000000000000000000401223057412600256320ustar00rootroot00000000000000.so man3/mapistore_indexing.c.3 openchange-2.0/apidocs/man/man3/mapistore_indexing_record_add_mid.3000066400000000000000000000000271223057412600254710ustar00rootroot00000000000000.so man3/mapistore.h.3 openchange-2.0/apidocs/man/man3/mapistore_indexing_record_del_fid.3000066400000000000000000000000271223057412600254760ustar00rootroot00000000000000.so man3/mapistore.h.3 openchange-2.0/apidocs/man/man3/mapistore_indexing_record_del_fmid.3000066400000000000000000000000401223057412600256460ustar00rootroot00000000000000.so man3/mapistore_indexing.c.3 openchange-2.0/apidocs/man/man3/mapistore_indexing_record_del_mid.3000066400000000000000000000000271223057412600255050ustar00rootroot00000000000000.so man3/mapistore.h.3 openchange-2.0/apidocs/man/man3/mapistore_indexing_record_get_uri.3000066400000000000000000000000271223057412600255460ustar00rootroot00000000000000.so man3/mapistore.h.3 openchange-2.0/apidocs/man/man3/mapistore_indexing_search.3000066400000000000000000000000401223057412600240120ustar00rootroot00000000000000.so man3/mapistore_indexing.c.3 openchange-2.0/apidocs/man/man3/mapistore_indexing_search_existing_fmid.3000066400000000000000000000000401223057412600267230ustar00rootroot00000000000000.so man3/mapistore_indexing.c.3 openchange-2.0/apidocs/man/man3/mapistore_init.3000066400000000000000000000000271223057412600216300ustar00rootroot00000000000000.so man3/mapistore.h.3 openchange-2.0/apidocs/man/man3/mapistore_message_get_message_data.3000066400000000000000000000000271223057412600256450ustar00rootroot00000000000000.so man3/mapistore.h.3 openchange-2.0/apidocs/man/man3/mapistore_message_modify_recipients.3000066400000000000000000000000271223057412600261050ustar00rootroot00000000000000.so man3/mapistore.h.3 openchange-2.0/apidocs/man/man3/mapistore_message_save.3000066400000000000000000000000271223057412600233270ustar00rootroot00000000000000.so man3/mapistore.h.3 openchange-2.0/apidocs/man/man3/mapistore_message_set_read_flag.3000066400000000000000000000000271223057412600251500ustar00rootroot00000000000000.so man3/mapistore.h.3 openchange-2.0/apidocs/man/man3/mapistore_message_submit.3000066400000000000000000000000271223057412600236740ustar00rootroot00000000000000.so man3/mapistore.h.3 openchange-2.0/apidocs/man/man3/mapistore_mgmt_generate_uri.3000066400000000000000000000000341223057412600243600ustar00rootroot00000000000000.so man3/mapistore_mgmt.c.3 openchange-2.0/apidocs/man/man3/mapistore_mgmt_init.3000066400000000000000000000000341223057412600226520ustar00rootroot00000000000000.so man3/mapistore_mgmt.c.3 openchange-2.0/apidocs/man/man3/mapistore_mgmt_register_message.3000066400000000000000000000000341223057412600252370ustar00rootroot00000000000000.so man3/mapistore_mgmt.c.3 openchange-2.0/apidocs/man/man3/mapistore_mgmt_registered_backend.3000066400000000000000000000000341223057412600255130ustar00rootroot00000000000000.so man3/mapistore_mgmt.c.3 openchange-2.0/apidocs/man/man3/mapistore_mgmt_registered_folder_subscription.3000066400000000000000000000000341223057412600302030ustar00rootroot00000000000000.so man3/mapistore_mgmt.c.3 openchange-2.0/apidocs/man/man3/mapistore_mgmt_registered_message.3000066400000000000000000000000341223057412600255500ustar00rootroot00000000000000.so man3/mapistore_mgmt.c.3 openchange-2.0/apidocs/man/man3/mapistore_mgmt_registered_users.3000066400000000000000000000000341223057412600252650ustar00rootroot00000000000000.so man3/mapistore_mgmt.c.3 openchange-2.0/apidocs/man/man3/mapistore_mgmt_release.3000066400000000000000000000000341223057412600233270ustar00rootroot00000000000000.so man3/mapistore_mgmt.c.3 openchange-2.0/apidocs/man/man3/mapistore_mgmt_send_newmail_notification.3000066400000000000000000000000411223057412600271200ustar00rootroot00000000000000.so man3/mapistore_mgmt_send.c.3 openchange-2.0/apidocs/man/man3/mapistore_mgmt_set_verbosity.3000066400000000000000000000000341223057412600246100ustar00rootroot00000000000000.so man3/mapistore_mgmt.c.3 openchange-2.0/apidocs/man/man3/mapistore_namedprops_create_id.3000066400000000000000000000000271223057412600250340ustar00rootroot00000000000000.so man3/mapistore.h.3 openchange-2.0/apidocs/man/man3/mapistore_namedprops_get_mapped_id.3000066400000000000000000000000271223057412600256760ustar00rootroot00000000000000.so man3/mapistore.h.3 openchange-2.0/apidocs/man/man3/mapistore_namedprops_get_nameid.3000066400000000000000000000000271223057412600252110ustar00rootroot00000000000000.so man3/mapistore.h.3 openchange-2.0/apidocs/man/man3/mapistore_namedprops_get_nameid_type.3000066400000000000000000000000271223057412600262520ustar00rootroot00000000000000.so man3/mapistore.h.3 openchange-2.0/apidocs/man/man3/mapistore_namedprops_next_unused_id.3000066400000000000000000000000271223057412600261320ustar00rootroot00000000000000.so man3/mapistore.h.3 openchange-2.0/apidocs/man/man3/mapistore_release.3000066400000000000000000000000271223057412600223050ustar00rootroot00000000000000.so man3/mapistore.h.3 openchange-2.0/apidocs/man/man3/mapistore_replica_mapping_guid_to_replid.3000066400000000000000000000000271223057412600270700ustar00rootroot00000000000000.so man3/mapistore.h.3 openchange-2.0/apidocs/man/man3/mapistore_replica_mapping_replid_to_guid.3000066400000000000000000000000271223057412600270700ustar00rootroot00000000000000.so man3/mapistore.h.3 openchange-2.0/apidocs/man/man3/mapistore_search_context_by_uri.3000066400000000000000000000000271223057412600252470ustar00rootroot00000000000000.so man3/mapistore.h.3 openchange-2.0/apidocs/man/man3/mapistore_set_connection_info.3000066400000000000000000000000271223057412600247120ustar00rootroot00000000000000.so man3/mapistore.h.3 openchange-2.0/apidocs/man/man3/mapistore_set_mapping_path.3000066400000000000000000000000271223057412600242070ustar00rootroot00000000000000.so man3/mapistore.h.3 openchange-2.0/apidocs/man/man3/mpm_cache_ldb_add_attachment.3000066400000000000000000000000331223057412600243540ustar00rootroot00000000000000.so man3/mpm_cache_ldb.c.3 openchange-2.0/apidocs/man/man3/mpm_cache_ldb_add_folder.3000066400000000000000000000000331223057412600234770ustar00rootroot00000000000000.so man3/mpm_cache_ldb.c.3 openchange-2.0/apidocs/man/man3/mpm_cache_ldb_add_message.3000066400000000000000000000000331223057412600236500ustar00rootroot00000000000000.so man3/mpm_cache_ldb.c.3 openchange-2.0/apidocs/man/man3/mpm_cache_ldb_add_stream.3000066400000000000000000000000331223057412600235170ustar00rootroot00000000000000.so man3/mpm_cache_ldb.c.3 openchange-2.0/apidocs/man/man3/mpm_cache_ldb_createdb.3000066400000000000000000000000331223057412600231650ustar00rootroot00000000000000.so man3/mpm_cache_ldb.c.3 openchange-2.0/apidocs/man/man3/mpm_cache_stream_close.3000066400000000000000000000000361223057412600232560ustar00rootroot00000000000000.so man3/mpm_cache_stream.c.3 openchange-2.0/apidocs/man/man3/mpm_cache_stream_open.3000066400000000000000000000000361223057412600231120ustar00rootroot00000000000000.so man3/mpm_cache_stream.c.3 openchange-2.0/apidocs/man/man3/mpm_cache_stream_read.3000066400000000000000000000000361223057412600230640ustar00rootroot00000000000000.so man3/mpm_cache_stream.c.3 openchange-2.0/apidocs/man/man3/mpm_cache_stream_reset.3000066400000000000000000000000361223057412600232730ustar00rootroot00000000000000.so man3/mpm_cache_stream.c.3 openchange-2.0/apidocs/man/man3/mpm_cache_stream_write.3000066400000000000000000000000361223057412600233030ustar00rootroot00000000000000.so man3/mpm_cache_stream.c.3 openchange-2.0/apidocs/man/man3/mpm_session_cmp.3000066400000000000000000000000461223057412600217760ustar00rootroot00000000000000.so man3/dcesrv_mapiproxy_session.c.3 openchange-2.0/apidocs/man/man3/mpm_session_cmp_sub.3000066400000000000000000000000461223057412600226470ustar00rootroot00000000000000.so man3/dcesrv_mapiproxy_session.c.3 openchange-2.0/apidocs/man/man3/mpm_session_increment_ref_count.3000066400000000000000000000000461223057412600252470ustar00rootroot00000000000000.so man3/dcesrv_mapiproxy_session.c.3 openchange-2.0/apidocs/man/man3/mpm_session_init.3000066400000000000000000000000461223057412600221620ustar00rootroot00000000000000.so man3/dcesrv_mapiproxy_session.c.3 openchange-2.0/apidocs/man/man3/mpm_session_new.3000066400000000000000000000000461223057412600220100ustar00rootroot00000000000000.so man3/dcesrv_mapiproxy_session.c.3 openchange-2.0/apidocs/man/man3/mpm_session_release.3000066400000000000000000000000461223057412600226370ustar00rootroot00000000000000.so man3/dcesrv_mapiproxy_session.c.3 openchange-2.0/apidocs/man/man3/mpm_session_set_destructor.3000066400000000000000000000000461223057412600242700ustar00rootroot00000000000000.so man3/dcesrv_mapiproxy_session.c.3 openchange-2.0/apidocs/man/man3/mpm_session_set_private_data.3000066400000000000000000000000461223057412600245350ustar00rootroot00000000000000.so man3/dcesrv_mapiproxy_session.c.3 openchange-2.0/apidocs/man/man3/mpm_stream.3000066400000000000000000000006321223057412600207500ustar00rootroot00000000000000.TH "mpm_stream" 3 "Thu Jan 24 2013" "Version 2.0" "MAPIProxy" \" -*- nroff -*- .ad l .nh .SH NAME mpm_stream \- .PP A stream can either be for a message or attachment\&. .SH SYNOPSIS .br .PP .PP \fC#include \fP .SH "Detailed Description" .PP A stream can either be for a message or attachment\&. .SH "Author" .PP Generated automatically by Doxygen for MAPIProxy from the source code\&. openchange-2.0/apidocs/man/man3/ndr_push_idset.3000066400000000000000000000000231223057412600216100ustar00rootroot00000000000000.so man3/idset.c.3 openchange-2.0/apidocs/man/man3/nspi_CompareMIds.3000066400000000000000000000000221223057412600217710ustar00rootroot00000000000000.so man3/nspi.c.3 openchange-2.0/apidocs/man/man3/nspi_DNToMId.3000066400000000000000000000000221223057412600210240ustar00rootroot00000000000000.so man3/nspi.c.3 openchange-2.0/apidocs/man/man3/nspi_GetIDsFromNames.3000066400000000000000000000000221223057412600225550ustar00rootroot00000000000000.so man3/nspi.c.3 openchange-2.0/apidocs/man/man3/nspi_GetMatches.3000066400000000000000000000000221223057412600216520ustar00rootroot00000000000000.so man3/nspi.c.3 openchange-2.0/apidocs/man/man3/nspi_GetNamesFromIDs.3000066400000000000000000000000221223057412600225550ustar00rootroot00000000000000.so man3/nspi.c.3 openchange-2.0/apidocs/man/man3/nspi_GetPropList.3000066400000000000000000000000221223057412600220420ustar00rootroot00000000000000.so man3/nspi.c.3 openchange-2.0/apidocs/man/man3/nspi_GetProps.3000066400000000000000000000000221223057412600213710ustar00rootroot00000000000000.so man3/nspi.c.3 openchange-2.0/apidocs/man/man3/nspi_GetSpecialTable.3000066400000000000000000000000221223057412600226160ustar00rootroot00000000000000.so man3/nspi.c.3 openchange-2.0/apidocs/man/man3/nspi_GetTemplateInfo.3000066400000000000000000000000221223057412600226550ustar00rootroot00000000000000.so man3/nspi.c.3 openchange-2.0/apidocs/man/man3/nspi_ModLinkAtt.3000066400000000000000000000000221223057412600216340ustar00rootroot00000000000000.so man3/nspi.c.3 openchange-2.0/apidocs/man/man3/nspi_ModProps.3000066400000000000000000000000221223057412600213710ustar00rootroot00000000000000.so man3/nspi.c.3 openchange-2.0/apidocs/man/man3/nspi_QueryColumns.3000066400000000000000000000000221223057412600222740ustar00rootroot00000000000000.so man3/nspi.c.3 openchange-2.0/apidocs/man/man3/nspi_QueryRows.3000066400000000000000000000000221223057412600216060ustar00rootroot00000000000000.so man3/nspi.c.3 openchange-2.0/apidocs/man/man3/nspi_ResolveNames.3000066400000000000000000000000221223057412600222310ustar00rootroot00000000000000.so man3/nspi.c.3 openchange-2.0/apidocs/man/man3/nspi_ResolveNamesW.3000066400000000000000000000000221223057412600223600ustar00rootroot00000000000000.so man3/nspi.c.3 openchange-2.0/apidocs/man/man3/nspi_ResortRestriction.3000066400000000000000000000000221223057412600233320ustar00rootroot00000000000000.so man3/nspi.c.3 openchange-2.0/apidocs/man/man3/nspi_SeekEntries.3000066400000000000000000000000221223057412600220470ustar00rootroot00000000000000.so man3/nspi.c.3 openchange-2.0/apidocs/man/man3/nspi_UpdateStat.3000066400000000000000000000000221223057412600217040ustar00rootroot00000000000000.so man3/nspi.c.3 openchange-2.0/apidocs/man/man3/nspi_bind.3000066400000000000000000000000221223057412600205420ustar00rootroot00000000000000.so man3/nspi.c.3 openchange-2.0/apidocs/man/man3/nspi_disconnect_dtor.3000066400000000000000000000000221223057412600230070ustar00rootroot00000000000000.so man3/nspi.c.3 openchange-2.0/apidocs/man/man3/nspi_unbind.3000066400000000000000000000000221223057412600211050ustar00rootroot00000000000000.so man3/nspi.c.3 openchange-2.0/apidocs/man/man3/ocpf_OpenFolder.3000066400000000000000000000000311223057412600216410ustar00rootroot00000000000000.so man3/ocpf_public.c.3 openchange-2.0/apidocs/man/man3/ocpf_clear_props.3000066400000000000000000000000311223057412600221150ustar00rootroot00000000000000.so man3/ocpf_public.c.3 openchange-2.0/apidocs/man/man3/ocpf_context_add.3000066400000000000000000000000321223057412600221010ustar00rootroot00000000000000.so man3/ocpf_context.c.3 openchange-2.0/apidocs/man/man3/ocpf_context_delete.3000066400000000000000000000000321223057412600226130ustar00rootroot00000000000000.so man3/ocpf_context.c.3 openchange-2.0/apidocs/man/man3/ocpf_context_init.3000066400000000000000000000000321223057412600223140ustar00rootroot00000000000000.so man3/ocpf_context.c.3 openchange-2.0/apidocs/man/man3/ocpf_context_search_by_context_id.3000066400000000000000000000000321223057412600255300ustar00rootroot00000000000000.so man3/ocpf_context.c.3 openchange-2.0/apidocs/man/man3/ocpf_context_search_by_filename.3000066400000000000000000000000321223057412600251500ustar00rootroot00000000000000.so man3/ocpf_context.c.3 openchange-2.0/apidocs/man/man3/ocpf_del_context.3000066400000000000000000000000311223057412600221140ustar00rootroot00000000000000.so man3/ocpf_public.c.3 openchange-2.0/apidocs/man/man3/ocpf_dump_folder.3000066400000000000000000000000271223057412600221110ustar00rootroot00000000000000.so man3/ocpf_dump.c.3 openchange-2.0/apidocs/man/man3/ocpf_dump_oleguid.3000066400000000000000000000000271223057412600222660ustar00rootroot00000000000000.so man3/ocpf_dump.c.3 openchange-2.0/apidocs/man/man3/ocpf_dump_recipients.3000066400000000000000000000000271223057412600230030ustar00rootroot00000000000000.so man3/ocpf_dump.c.3 openchange-2.0/apidocs/man/man3/ocpf_dump_type.3000066400000000000000000000000271223057412600216170ustar00rootroot00000000000000.so man3/ocpf_dump.c.3 openchange-2.0/apidocs/man/man3/ocpf_get_SPropValue.3000066400000000000000000000000311223057412600225030ustar00rootroot00000000000000.so man3/ocpf_public.c.3 openchange-2.0/apidocs/man/man3/ocpf_get_recipients.3000066400000000000000000000000311223057412600226100ustar00rootroot00000000000000.so man3/ocpf_public.c.3 openchange-2.0/apidocs/man/man3/ocpf_init.3000066400000000000000000000000311223057412600205470ustar00rootroot00000000000000.so man3/ocpf_public.c.3 openchange-2.0/apidocs/man/man3/ocpf_new_context.3000066400000000000000000000000311223057412600221410ustar00rootroot00000000000000.so man3/ocpf_public.c.3 openchange-2.0/apidocs/man/man3/ocpf_parse.3000066400000000000000000000000311223057412600207160ustar00rootroot00000000000000.so man3/ocpf_public.c.3 openchange-2.0/apidocs/man/man3/ocpf_release.3000066400000000000000000000000311223057412600212240ustar00rootroot00000000000000.so man3/ocpf_public.c.3 openchange-2.0/apidocs/man/man3/ocpf_server_add_SPropValue.3000066400000000000000000000000311223057412600240420ustar00rootroot00000000000000.so man3/ocpf_server.c.3 openchange-2.0/apidocs/man/man3/ocpf_server_set_SPropValue.3000066400000000000000000000000311223057412600241050ustar00rootroot00000000000000.so man3/ocpf_server.c.3 openchange-2.0/apidocs/man/man3/ocpf_server_set_type.3000066400000000000000000000000311223057412600230260ustar00rootroot00000000000000.so man3/ocpf_server.c.3 openchange-2.0/apidocs/man/man3/ocpf_server_sync.3000066400000000000000000000000311223057412600221460ustar00rootroot00000000000000.so man3/ocpf_server.c.3 openchange-2.0/apidocs/man/man3/ocpf_set_Recipients.3000066400000000000000000000000311223057412600225640ustar00rootroot00000000000000.so man3/ocpf_public.c.3 openchange-2.0/apidocs/man/man3/ocpf_set_SPropValue.3000066400000000000000000000000311223057412600225170ustar00rootroot00000000000000.so man3/ocpf_public.c.3 openchange-2.0/apidocs/man/man3/ocpf_write_auto.3000066400000000000000000000000301223057412600217650ustar00rootroot00000000000000.so man3/ocpf_write.c.3 openchange-2.0/apidocs/man/man3/ocpf_write_commit.3000066400000000000000000000000301223057412600223050ustar00rootroot00000000000000.so man3/ocpf_write.c.3 openchange-2.0/apidocs/man/man3/ocpf_write_init.3000066400000000000000000000000301223057412600217600ustar00rootroot00000000000000.so man3/ocpf_write.c.3 openchange-2.0/apidocs/man/man3/openchangedb_create_folder.3000066400000000000000000000000321223057412600240710ustar00rootroot00000000000000.so man3/openchangedb.c.3 openchange-2.0/apidocs/man/man3/openchangedb_create_mailbox.3000066400000000000000000000000321223057412600242510ustar00rootroot00000000000000.so man3/openchangedb.c.3 openchange-2.0/apidocs/man/man3/openchangedb_get_MAPIStoreURIs.3000066400000000000000000000000321223057412600244400ustar00rootroot00000000000000.so man3/openchangedb.c.3 openchange-2.0/apidocs/man/man3/openchangedb_get_MailboxGuid.3000066400000000000000000000000321223057412600243360ustar00rootroot00000000000000.so man3/openchangedb.c.3 openchange-2.0/apidocs/man/man3/openchangedb_get_MailboxReplica.3000066400000000000000000000000321223057412600250250ustar00rootroot00000000000000.so man3/openchangedb.c.3 openchange-2.0/apidocs/man/man3/openchangedb_get_PublicFolderID.3000066400000000000000000000000321223057412600247210ustar00rootroot00000000000000.so man3/openchangedb.c.3 openchange-2.0/apidocs/man/man3/openchangedb_get_PublicFolderReplica.3000066400000000000000000000000321223057412600260040ustar00rootroot00000000000000.so man3/openchangedb.c.3 openchange-2.0/apidocs/man/man3/openchangedb_get_ReceiveFolder.3000066400000000000000000000000321223057412600246500ustar00rootroot00000000000000.so man3/openchangedb.c.3 openchange-2.0/apidocs/man/man3/openchangedb_get_SystemFolderID.3000066400000000000000000000000321223057412600247670ustar00rootroot00000000000000.so man3/openchangedb.c.3 openchange-2.0/apidocs/man/man3/openchangedb_get_TransportFolder.3000066400000000000000000000000321223057412600252620ustar00rootroot00000000000000.so man3/openchangedb.c.3 openchange-2.0/apidocs/man/man3/openchangedb_get_distinguishedName.3000066400000000000000000000000321223057412600255760ustar00rootroot00000000000000.so man3/openchangedb.c.3 openchange-2.0/apidocs/man/man3/openchangedb_get_fid.3000066400000000000000000000000321223057412600226740ustar00rootroot00000000000000.so man3/openchangedb.c.3 openchange-2.0/apidocs/man/man3/openchangedb_get_fid_by_name.3000066400000000000000000000000321223057412600243660ustar00rootroot00000000000000.so man3/openchangedb.c.3 openchange-2.0/apidocs/man/man3/openchangedb_get_folder_count.3000066400000000000000000000000321223057412600246150ustar00rootroot00000000000000.so man3/openchangedb.c.3 openchange-2.0/apidocs/man/man3/openchangedb_get_folder_property.3000066400000000000000000000000321223057412600253510ustar00rootroot00000000000000.so man3/openchangedb.c.3 openchange-2.0/apidocs/man/man3/openchangedb_get_mailboxDN.3000066400000000000000000000000321223057412600240070ustar00rootroot00000000000000.so man3/openchangedb.c.3 openchange-2.0/apidocs/man/man3/openchangedb_get_mapistoreURI.3000066400000000000000000000000321223057412600245150ustar00rootroot00000000000000.so man3/openchangedb.c.3 openchange-2.0/apidocs/man/man3/openchangedb_get_message_count.3000066400000000000000000000000321223057412600247660ustar00rootroot00000000000000.so man3/openchangedb.c.3 openchange-2.0/apidocs/man/man3/openchangedb_get_mid_by_subject.3000066400000000000000000000000321223057412600251140ustar00rootroot00000000000000.so man3/openchangedb.c.3 openchange-2.0/apidocs/man/man3/openchangedb_get_new_changeNumber.3000066400000000000000000000000321223057412600254010ustar00rootroot00000000000000.so man3/openchangedb.c.3 openchange-2.0/apidocs/man/man3/openchangedb_get_new_changeNumbers.3000066400000000000000000000000321223057412600255640ustar00rootroot00000000000000.so man3/openchangedb.c.3 openchange-2.0/apidocs/man/man3/openchangedb_get_new_folderID.3000066400000000000000000000000321223057412600244730ustar00rootroot00000000000000.so man3/openchangedb.c.3 openchange-2.0/apidocs/man/man3/openchangedb_get_new_folderIDs.3000066400000000000000000000000321223057412600246560ustar00rootroot00000000000000.so man3/openchangedb.c.3 openchange-2.0/apidocs/man/man3/openchangedb_get_next_changeNumber.3000066400000000000000000000000321223057412600255660ustar00rootroot00000000000000.so man3/openchangedb.c.3 openchange-2.0/apidocs/man/man3/openchangedb_get_parent_fid.3000066400000000000000000000000321223057412600242450ustar00rootroot00000000000000.so man3/openchangedb.c.3 openchange-2.0/apidocs/man/man3/openchangedb_get_property_data.3000066400000000000000000000000321223057412600250070ustar00rootroot00000000000000.so man3/openchangedb.c.3 openchange-2.0/apidocs/man/man3/openchangedb_get_property_data_message.3000066400000000000000000000000321223057412600265130ustar00rootroot00000000000000.so man3/openchangedb.c.3 openchange-2.0/apidocs/man/man3/openchangedb_get_special_property.3000066400000000000000000000000321223057412600255160ustar00rootroot00000000000000.so man3/openchangedb.c.3 openchange-2.0/apidocs/man/man3/openchangedb_get_system_idx.3000066400000000000000000000000321223057412600243220ustar00rootroot00000000000000.so man3/openchangedb.c.3 openchange-2.0/apidocs/man/man3/openchangedb_get_table_property.3000066400000000000000000000000321223057412600251650ustar00rootroot00000000000000.so man3/openchangedb.c.3 openchange-2.0/apidocs/man/man3/openchangedb_lookup_folder_property.3000066400000000000000000000000321223057412600261030ustar00rootroot00000000000000.so man3/openchangedb.c.3 openchange-2.0/apidocs/man/man3/openchangedb_message_create.3000066400000000000000000000000421223057412600242430ustar00rootroot00000000000000.so man3/openchangedb_message.c.3 openchange-2.0/apidocs/man/man3/openchangedb_message_get_property.3000066400000000000000000000000421223057412600255230ustar00rootroot00000000000000.so man3/openchangedb_message.c.3 openchange-2.0/apidocs/man/man3/openchangedb_message_open.3000066400000000000000000000000421223057412600237410ustar00rootroot00000000000000.so man3/openchangedb_message.c.3 openchange-2.0/apidocs/man/man3/openchangedb_message_save.3000066400000000000000000000000421223057412600237360ustar00rootroot00000000000000.so man3/openchangedb_message.c.3 openchange-2.0/apidocs/man/man3/openchangedb_message_set_properties.3000066400000000000000000000000421223057412600260470ustar00rootroot00000000000000.so man3/openchangedb_message.c.3 openchange-2.0/apidocs/man/man3/openchangedb_reserve_fmid_range.3000066400000000000000000000000321223057412600251210ustar00rootroot00000000000000.so man3/openchangedb.c.3 openchange-2.0/apidocs/man/man3/openchangedb_set_ReceiveFolder.3000066400000000000000000000000321223057412600246640ustar00rootroot00000000000000.so man3/openchangedb.c.3 openchange-2.0/apidocs/man/man3/openchangedb_set_folder_property_data.3000066400000000000000000000000321223057412600263560ustar00rootroot00000000000000.so man3/openchangedb.c.3 openchange-2.0/apidocs/man/man3/openchangedb_set_mapistoreURI.3000066400000000000000000000000321223057412600245310ustar00rootroot00000000000000.so man3/openchangedb.c.3 openchange-2.0/apidocs/man/man3/openchangedb_table_init.3000066400000000000000000000000401223057412600234040ustar00rootroot00000000000000.so man3/openchangedb_table.c.3 openchange-2.0/apidocs/man/man3/openchangedb_table_set_sort_order.3000066400000000000000000000000401223057412600254760ustar00rootroot00000000000000.so man3/openchangedb_table.c.3 openchange-2.0/apidocs/man/man3/oxcfxics_push_folderChange.3000066400000000000000000000000261223057412600241270ustar00rootroot00000000000000.so man3/oxcfxics.c.3 openchange-2.0/apidocs/man/man3/oxcfxics_push_messageChange.3000066400000000000000000000000261223057412600243000ustar00rootroot00000000000000.so man3/oxcfxics.c.3 openchange-2.0/apidocs/man/man3/pack.3000066400000000000000000000000261223057412600175170ustar00rootroot00000000000000.so man3/mpm_pack.c.3 openchange-2.0/apidocs/man/man3/pack_init.3000066400000000000000000000000261223057412600205420ustar00rootroot00000000000000.so man3/mpm_pack.c.3 openchange-2.0/apidocs/man/man3/pack_pull.3000066400000000000000000000000261223057412600205530ustar00rootroot00000000000000.so man3/mpm_pack.c.3 openchange-2.0/apidocs/man/man3/pull_emsmdb_property.3000066400000000000000000000000241223057412600230460ustar00rootroot00000000000000.so man3/emsmdb.c.3 openchange-2.0/apidocs/man/man3/samba_init_module.3000066400000000000000000000000361223057412600222550ustar00rootroot00000000000000.so man3/dcesrv_mapiproxy.c.3 openchange-2.0/apidocs/man/man3/set_SPropTagArray.3000066400000000000000000000000261223057412600221520ustar00rootroot00000000000000.so man3/property.c.3 openchange-2.0/apidocs/man/man3/unpack.3000066400000000000000000000000261223057412600200620ustar00rootroot00000000000000.so man3/mpm_pack.c.3 openchange-2.0/apidocs/man/man3/x500_get_servername.3000066400000000000000000000000431223057412600223620ustar00rootroot00000000000000.so man3/dcesrv_mapiproxy_nspi.c.3 openchange-2.0/autogen.sh000077500000000000000000000034501223057412600154670ustar00rootroot00000000000000#!/bin/sh # Run this script to build openchange from SVN ## insert all possible names (only works with ## autoconf 2.x TESTAUTOHEADER="autoheader autoheader-2.53 autoheader2.50 autoheader259 autoheader253" TESTAUTOCONF="autoconf autoconf-2.53 autoconf2.50 autoconf259 autoconf253" TESTACLOCAL="aclocal aclocal19" AUTOHEADERFOUND="0" AUTOCONFFOUND="0" ACLOCALFOUND="0" ## ## Look for autoheader ## for i in $TESTAUTOHEADER; do if which $i > /dev/null 2>&1; then if test `$i --version | head -n 1 | cut -d. -f 2 | tr -d [:alpha:]` -ge 53; then AUTOHEADER=$i AUTOHEADERFOUND="1" break fi fi done ## ## Look for autoconf ## for i in $TESTAUTOCONF; do if which $i > /dev/null 2>&1; then if test `$i --version | head -n 1 | cut -d. -f 2 | tr -d [:alpha:]` -ge 53; then AUTOCONF=$i AUTOCONFFOUND="1" break fi fi done ## ## Look for aclocal ## for i in $TESTACLOCAL; do if which $i > /dev/null 2>&1; then ACLOCAL=$i ACLOCALFOUND="1" break fi done ## ## do we have it? ## if test "$AUTOCONFFOUND" = "0" -o "$AUTOHEADERFOUND" = "0"; then echo "$0: need autoconf 2.53 or later to build openchange from SVN" >&2 exit 1 fi if test "$ACLOCALFOUND" = "0"; then echo "$0: aclocal not found" >&2 exit 1 fi rm -rf autom4te*.cache rm -f configure include/config.h* echo "$0: running $ACLOCAL" $ACLOCAL || exit 1 echo "$0: running $AUTOHEADER" $AUTOHEADER || exit 1 echo "$0: running $AUTOCONF" $AUTOCONF || exit 1 rm -rf autom4te*.cache echo "Now run ./configure and gmake" exit 0 openchange-2.0/bin/000077500000000000000000000000001223057412600142345ustar00rootroot00000000000000openchange-2.0/bin/.dummy000066400000000000000000000001101223057412600153600ustar00rootroot00000000000000# This file is here so that git creates the bin/ directory on checkout. openchange-2.0/config.guess000077500000000000000000001322641223057412600160140ustar00rootroot00000000000000#! /bin/sh # Attempt to guess a canonical system name. # Copyright (C) 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, # 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008 # Free Software Foundation, Inc. timestamp='2009-04-27' # This file is free software; you can redistribute it and/or modify it # under the terms of the GNU General Public License as published by # the Free Software Foundation; either version 2 of the License, or # (at your option) any later version. # # This program is distributed in the hope that it will be useful, but # WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU # General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program; if not, write to the Free Software # Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston, MA # 02110-1301, USA. # # As a special exception to the GNU General Public License, if you # distribute this file as part of a program that contains a # configuration script generated by Autoconf, you may include it under # the same distribution terms that you use for the rest of that program. # Originally written by Per Bothner . # Please send patches to . Submit a context # diff and a properly formatted ChangeLog entry. # # This script attempts to guess a canonical system name similar to # config.sub. If it succeeds, it prints the system name on stdout, and # exits with 0. Otherwise, it exits with 1. # # The plan is that this can be called by configure scripts if you # don't specify an explicit build system type. me=`echo "$0" | sed -e 's,.*/,,'` usage="\ Usage: $0 [OPTION] Output the configuration name of the system \`$me' is run on. Operation modes: -h, --help print this help, then exit -t, --time-stamp print date of last modification, then exit -v, --version print version number, then exit Report bugs and patches to ." version="\ GNU config.guess ($timestamp) Originally written by Per Bothner. Copyright (C) 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008 Free Software Foundation, Inc. This is free software; see the source for copying conditions. There is NO warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE." help=" Try \`$me --help' for more information." # Parse command line while test $# -gt 0 ; do case $1 in --time-stamp | --time* | -t ) echo "$timestamp" ; exit ;; --version | -v ) echo "$version" ; exit ;; --help | --h* | -h ) echo "$usage"; exit ;; -- ) # Stop option processing shift; break ;; - ) # Use stdin as input. break ;; -* ) echo "$me: invalid option $1$help" >&2 exit 1 ;; * ) break ;; esac done if test $# != 0; then echo "$me: too many arguments$help" >&2 exit 1 fi trap 'exit 1' 1 2 15 # CC_FOR_BUILD -- compiler used by this script. Note that the use of a # compiler to aid in system detection is discouraged as it requires # temporary files to be created and, as you can see below, it is a # headache to deal with in a portable fashion. # Historically, `CC_FOR_BUILD' used to be named `HOST_CC'. We still # use `HOST_CC' if defined, but it is deprecated. # Portable tmp directory creation inspired by the Autoconf team. set_cc_for_build=' trap "exitcode=\$?; (rm -f \$tmpfiles 2>/dev/null; rmdir \$tmp 2>/dev/null) && exit \$exitcode" 0 ; trap "rm -f \$tmpfiles 2>/dev/null; rmdir \$tmp 2>/dev/null; exit 1" 1 2 13 15 ; : ${TMPDIR=/tmp} ; { tmp=`(umask 077 && mktemp -d "$TMPDIR/cgXXXXXX") 2>/dev/null` && test -n "$tmp" && test -d "$tmp" ; } || { test -n "$RANDOM" && tmp=$TMPDIR/cg$$-$RANDOM && (umask 077 && mkdir $tmp) ; } || { tmp=$TMPDIR/cg-$$ && (umask 077 && mkdir $tmp) && echo "Warning: creating insecure temp directory" >&2 ; } || { echo "$me: cannot create a temporary directory in $TMPDIR" >&2 ; exit 1 ; } ; dummy=$tmp/dummy ; tmpfiles="$dummy.c $dummy.o $dummy.rel $dummy" ; case $CC_FOR_BUILD,$HOST_CC,$CC in ,,) echo "int x;" > $dummy.c ; for c in cc gcc c89 c99 ; do if ($c -c -o $dummy.o $dummy.c) >/dev/null 2>&1 ; then CC_FOR_BUILD="$c"; break ; fi ; done ; if test x"$CC_FOR_BUILD" = x ; then CC_FOR_BUILD=no_compiler_found ; fi ;; ,,*) CC_FOR_BUILD=$CC ;; ,*,*) CC_FOR_BUILD=$HOST_CC ;; esac ; set_cc_for_build= ;' # This is needed to find uname on a Pyramid OSx when run in the BSD universe. # (ghazi@noc.rutgers.edu 1994-08-24) if (test -f /.attbin/uname) >/dev/null 2>&1 ; then PATH=$PATH:/.attbin ; export PATH fi UNAME_MACHINE=`(uname -m) 2>/dev/null` || UNAME_MACHINE=unknown UNAME_RELEASE=`(uname -r) 2>/dev/null` || UNAME_RELEASE=unknown UNAME_SYSTEM=`(uname -s) 2>/dev/null` || UNAME_SYSTEM=unknown UNAME_VERSION=`(uname -v) 2>/dev/null` || UNAME_VERSION=unknown # Note: order is significant - the case branches are not exclusive. case "${UNAME_MACHINE}:${UNAME_SYSTEM}:${UNAME_RELEASE}:${UNAME_VERSION}" in *:NetBSD:*:*) # NetBSD (nbsd) targets should (where applicable) match one or # more of the tupples: *-*-netbsdelf*, *-*-netbsdaout*, # *-*-netbsdecoff* and *-*-netbsd*. For targets that recently # switched to ELF, *-*-netbsd* would select the old # object file format. This provides both forward # compatibility and a consistent mechanism for selecting the # object file format. # # Note: NetBSD doesn't particularly care about the vendor # portion of the name. We always set it to "unknown". sysctl="sysctl -n hw.machine_arch" UNAME_MACHINE_ARCH=`(/sbin/$sysctl 2>/dev/null || \ /usr/sbin/$sysctl 2>/dev/null || echo unknown)` case "${UNAME_MACHINE_ARCH}" in armeb) machine=armeb-unknown ;; arm*) machine=arm-unknown ;; sh3el) machine=shl-unknown ;; sh3eb) machine=sh-unknown ;; sh5el) machine=sh5le-unknown ;; *) machine=${UNAME_MACHINE_ARCH}-unknown ;; esac # The Operating System including object format, if it has switched # to ELF recently, or will in the future. case "${UNAME_MACHINE_ARCH}" in arm*|i386|m68k|ns32k|sh3*|sparc|vax) eval $set_cc_for_build if echo __ELF__ | $CC_FOR_BUILD -E - 2>/dev/null \ | grep __ELF__ >/dev/null then # Once all utilities can be ECOFF (netbsdecoff) or a.out (netbsdaout). # Return netbsd for either. FIX? os=netbsd else os=netbsdelf fi ;; *) os=netbsd ;; esac # The OS release # Debian GNU/NetBSD machines have a different userland, and # thus, need a distinct triplet. However, they do not need # kernel version information, so it can be replaced with a # suitable tag, in the style of linux-gnu. case "${UNAME_VERSION}" in Debian*) release='-gnu' ;; *) release=`echo ${UNAME_RELEASE}|sed -e 's/[-_].*/\./'` ;; esac # Since CPU_TYPE-MANUFACTURER-KERNEL-OPERATING_SYSTEM: # contains redundant information, the shorter form: # CPU_TYPE-MANUFACTURER-OPERATING_SYSTEM is used. echo "${machine}-${os}${release}" exit ;; *:OpenBSD:*:*) UNAME_MACHINE_ARCH=`arch | sed 's/OpenBSD.//'` echo ${UNAME_MACHINE_ARCH}-unknown-openbsd${UNAME_RELEASE} exit ;; *:ekkoBSD:*:*) echo ${UNAME_MACHINE}-unknown-ekkobsd${UNAME_RELEASE} exit ;; *:SolidBSD:*:*) echo ${UNAME_MACHINE}-unknown-solidbsd${UNAME_RELEASE} exit ;; macppc:MirBSD:*:*) echo powerpc-unknown-mirbsd${UNAME_RELEASE} exit ;; *:MirBSD:*:*) echo ${UNAME_MACHINE}-unknown-mirbsd${UNAME_RELEASE} exit ;; alpha:OSF1:*:*) case $UNAME_RELEASE in *4.0) UNAME_RELEASE=`/usr/sbin/sizer -v | awk '{print $3}'` ;; *5.*) UNAME_RELEASE=`/usr/sbin/sizer -v | awk '{print $4}'` ;; esac # According to Compaq, /usr/sbin/psrinfo has been available on # OSF/1 and Tru64 systems produced since 1995. I hope that # covers most systems running today. This code pipes the CPU # types through head -n 1, so we only detect the type of CPU 0. ALPHA_CPU_TYPE=`/usr/sbin/psrinfo -v | sed -n -e 's/^ The alpha \(.*\) processor.*$/\1/p' | head -n 1` case "$ALPHA_CPU_TYPE" in "EV4 (21064)") UNAME_MACHINE="alpha" ;; "EV4.5 (21064)") UNAME_MACHINE="alpha" ;; "LCA4 (21066/21068)") UNAME_MACHINE="alpha" ;; "EV5 (21164)") UNAME_MACHINE="alphaev5" ;; "EV5.6 (21164A)") UNAME_MACHINE="alphaev56" ;; "EV5.6 (21164PC)") UNAME_MACHINE="alphapca56" ;; "EV5.7 (21164PC)") UNAME_MACHINE="alphapca57" ;; "EV6 (21264)") UNAME_MACHINE="alphaev6" ;; "EV6.7 (21264A)") UNAME_MACHINE="alphaev67" ;; "EV6.8CB (21264C)") UNAME_MACHINE="alphaev68" ;; "EV6.8AL (21264B)") UNAME_MACHINE="alphaev68" ;; "EV6.8CX (21264D)") UNAME_MACHINE="alphaev68" ;; "EV6.9A (21264/EV69A)") UNAME_MACHINE="alphaev69" ;; "EV7 (21364)") UNAME_MACHINE="alphaev7" ;; "EV7.9 (21364A)") UNAME_MACHINE="alphaev79" ;; esac # A Pn.n version is a patched version. # A Vn.n version is a released version. # A Tn.n version is a released field test version. # A Xn.n version is an unreleased experimental baselevel. # 1.2 uses "1.2" for uname -r. echo ${UNAME_MACHINE}-dec-osf`echo ${UNAME_RELEASE} | sed -e 's/^[PVTX]//' | tr 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' 'abcdefghijklmnopqrstuvwxyz'` exit ;; Alpha\ *:Windows_NT*:*) # How do we know it's Interix rather than the generic POSIX subsystem? # Should we change UNAME_MACHINE based on the output of uname instead # of the specific Alpha model? echo alpha-pc-interix exit ;; 21064:Windows_NT:50:3) echo alpha-dec-winnt3.5 exit ;; Amiga*:UNIX_System_V:4.0:*) echo m68k-unknown-sysv4 exit ;; *:[Aa]miga[Oo][Ss]:*:*) echo ${UNAME_MACHINE}-unknown-amigaos exit ;; *:[Mm]orph[Oo][Ss]:*:*) echo ${UNAME_MACHINE}-unknown-morphos exit ;; *:OS/390:*:*) echo i370-ibm-openedition exit ;; *:z/VM:*:*) echo s390-ibm-zvmoe exit ;; *:OS400:*:*) echo powerpc-ibm-os400 exit ;; arm:RISC*:1.[012]*:*|arm:riscix:1.[012]*:*) echo arm-acorn-riscix${UNAME_RELEASE} exit ;; arm:riscos:*:*|arm:RISCOS:*:*) echo arm-unknown-riscos exit ;; SR2?01:HI-UX/MPP:*:* | SR8000:HI-UX/MPP:*:*) echo hppa1.1-hitachi-hiuxmpp exit ;; Pyramid*:OSx*:*:* | MIS*:OSx*:*:* | MIS*:SMP_DC-OSx*:*:*) # akee@wpdis03.wpafb.af.mil (Earle F. Ake) contributed MIS and NILE. if test "`(/bin/universe) 2>/dev/null`" = att ; then echo pyramid-pyramid-sysv3 else echo pyramid-pyramid-bsd fi exit ;; NILE*:*:*:dcosx) echo pyramid-pyramid-svr4 exit ;; DRS?6000:unix:4.0:6*) echo sparc-icl-nx6 exit ;; DRS?6000:UNIX_SV:4.2*:7* | DRS?6000:isis:4.2*:7*) case `/usr/bin/uname -p` in sparc) echo sparc-icl-nx7; exit ;; esac ;; s390x:SunOS:*:*) echo ${UNAME_MACHINE}-ibm-solaris2`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'` exit ;; sun4H:SunOS:5.*:*) echo sparc-hal-solaris2`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'` exit ;; sun4*:SunOS:5.*:* | tadpole*:SunOS:5.*:*) echo sparc-sun-solaris2`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'` exit ;; i86pc:SunOS:5.*:* | i86xen:SunOS:5.*:*) eval $set_cc_for_build SUN_ARCH="i386" # If there is a compiler, see if it is configured for 64-bit objects. # Note that the Sun cc does not turn __LP64__ into 1 like gcc does. # This test works for both compilers. if [ "$CC_FOR_BUILD" != 'no_compiler_found' ]; then if (echo '#ifdef __amd64'; echo IS_64BIT_ARCH; echo '#endif') | \ (CCOPTS= $CC_FOR_BUILD -E - 2>/dev/null) | \ grep IS_64BIT_ARCH >/dev/null then SUN_ARCH="x86_64" fi fi echo ${SUN_ARCH}-pc-solaris2`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'` exit ;; sun4*:SunOS:6*:*) # According to config.sub, this is the proper way to canonicalize # SunOS6. Hard to guess exactly what SunOS6 will be like, but # it's likely to be more like Solaris than SunOS4. echo sparc-sun-solaris3`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'` exit ;; sun4*:SunOS:*:*) case "`/usr/bin/arch -k`" in Series*|S4*) UNAME_RELEASE=`uname -v` ;; esac # Japanese Language versions have a version number like `4.1.3-JL'. echo sparc-sun-sunos`echo ${UNAME_RELEASE}|sed -e 's/-/_/'` exit ;; sun3*:SunOS:*:*) echo m68k-sun-sunos${UNAME_RELEASE} exit ;; sun*:*:4.2BSD:*) UNAME_RELEASE=`(sed 1q /etc/motd | awk '{print substr($5,1,3)}') 2>/dev/null` test "x${UNAME_RELEASE}" = "x" && UNAME_RELEASE=3 case "`/bin/arch`" in sun3) echo m68k-sun-sunos${UNAME_RELEASE} ;; sun4) echo sparc-sun-sunos${UNAME_RELEASE} ;; esac exit ;; aushp:SunOS:*:*) echo sparc-auspex-sunos${UNAME_RELEASE} exit ;; # The situation for MiNT is a little confusing. The machine name # can be virtually everything (everything which is not # "atarist" or "atariste" at least should have a processor # > m68000). The system name ranges from "MiNT" over "FreeMiNT" # to the lowercase version "mint" (or "freemint"). Finally # the system name "TOS" denotes a system which is actually not # MiNT. But MiNT is downward compatible to TOS, so this should # be no problem. atarist[e]:*MiNT:*:* | atarist[e]:*mint:*:* | atarist[e]:*TOS:*:*) echo m68k-atari-mint${UNAME_RELEASE} exit ;; atari*:*MiNT:*:* | atari*:*mint:*:* | atarist[e]:*TOS:*:*) echo m68k-atari-mint${UNAME_RELEASE} exit ;; *falcon*:*MiNT:*:* | *falcon*:*mint:*:* | *falcon*:*TOS:*:*) echo m68k-atari-mint${UNAME_RELEASE} exit ;; milan*:*MiNT:*:* | milan*:*mint:*:* | *milan*:*TOS:*:*) echo m68k-milan-mint${UNAME_RELEASE} exit ;; hades*:*MiNT:*:* | hades*:*mint:*:* | *hades*:*TOS:*:*) echo m68k-hades-mint${UNAME_RELEASE} exit ;; *:*MiNT:*:* | *:*mint:*:* | *:*TOS:*:*) echo m68k-unknown-mint${UNAME_RELEASE} exit ;; m68k:machten:*:*) echo m68k-apple-machten${UNAME_RELEASE} exit ;; powerpc:machten:*:*) echo powerpc-apple-machten${UNAME_RELEASE} exit ;; RISC*:Mach:*:*) echo mips-dec-mach_bsd4.3 exit ;; RISC*:ULTRIX:*:*) echo mips-dec-ultrix${UNAME_RELEASE} exit ;; VAX*:ULTRIX*:*:*) echo vax-dec-ultrix${UNAME_RELEASE} exit ;; 2020:CLIX:*:* | 2430:CLIX:*:*) echo clipper-intergraph-clix${UNAME_RELEASE} exit ;; mips:*:*:UMIPS | mips:*:*:RISCos) eval $set_cc_for_build sed 's/^ //' << EOF >$dummy.c #ifdef __cplusplus #include /* for printf() prototype */ int main (int argc, char *argv[]) { #else int main (argc, argv) int argc; char *argv[]; { #endif #if defined (host_mips) && defined (MIPSEB) #if defined (SYSTYPE_SYSV) printf ("mips-mips-riscos%ssysv\n", argv[1]); exit (0); #endif #if defined (SYSTYPE_SVR4) printf ("mips-mips-riscos%ssvr4\n", argv[1]); exit (0); #endif #if defined (SYSTYPE_BSD43) || defined(SYSTYPE_BSD) printf ("mips-mips-riscos%sbsd\n", argv[1]); exit (0); #endif #endif exit (-1); } EOF $CC_FOR_BUILD -o $dummy $dummy.c && dummyarg=`echo "${UNAME_RELEASE}" | sed -n 's/\([0-9]*\).*/\1/p'` && SYSTEM_NAME=`$dummy $dummyarg` && { echo "$SYSTEM_NAME"; exit; } echo mips-mips-riscos${UNAME_RELEASE} exit ;; Motorola:PowerMAX_OS:*:*) echo powerpc-motorola-powermax exit ;; Motorola:*:4.3:PL8-*) echo powerpc-harris-powermax exit ;; Night_Hawk:*:*:PowerMAX_OS | Synergy:PowerMAX_OS:*:*) echo powerpc-harris-powermax exit ;; Night_Hawk:Power_UNIX:*:*) echo powerpc-harris-powerunix exit ;; m88k:CX/UX:7*:*) echo m88k-harris-cxux7 exit ;; m88k:*:4*:R4*) echo m88k-motorola-sysv4 exit ;; m88k:*:3*:R3*) echo m88k-motorola-sysv3 exit ;; AViiON:dgux:*:*) # DG/UX returns AViiON for all architectures UNAME_PROCESSOR=`/usr/bin/uname -p` if [ $UNAME_PROCESSOR = mc88100 ] || [ $UNAME_PROCESSOR = mc88110 ] then if [ ${TARGET_BINARY_INTERFACE}x = m88kdguxelfx ] || \ [ ${TARGET_BINARY_INTERFACE}x = x ] then echo m88k-dg-dgux${UNAME_RELEASE} else echo m88k-dg-dguxbcs${UNAME_RELEASE} fi else echo i586-dg-dgux${UNAME_RELEASE} fi exit ;; M88*:DolphinOS:*:*) # DolphinOS (SVR3) echo m88k-dolphin-sysv3 exit ;; M88*:*:R3*:*) # Delta 88k system running SVR3 echo m88k-motorola-sysv3 exit ;; XD88*:*:*:*) # Tektronix XD88 system running UTekV (SVR3) echo m88k-tektronix-sysv3 exit ;; Tek43[0-9][0-9]:UTek:*:*) # Tektronix 4300 system running UTek (BSD) echo m68k-tektronix-bsd exit ;; *:IRIX*:*:*) echo mips-sgi-irix`echo ${UNAME_RELEASE}|sed -e 's/-/_/g'` exit ;; ????????:AIX?:[12].1:2) # AIX 2.2.1 or AIX 2.1.1 is RT/PC AIX. echo romp-ibm-aix # uname -m gives an 8 hex-code CPU id exit ;; # Note that: echo "'`uname -s`'" gives 'AIX ' i*86:AIX:*:*) echo i386-ibm-aix exit ;; ia64:AIX:*:*) if [ -x /usr/bin/oslevel ] ; then IBM_REV=`/usr/bin/oslevel` else IBM_REV=${UNAME_VERSION}.${UNAME_RELEASE} fi echo ${UNAME_MACHINE}-ibm-aix${IBM_REV} exit ;; *:AIX:2:3) if grep bos325 /usr/include/stdio.h >/dev/null 2>&1; then eval $set_cc_for_build sed 's/^ //' << EOF >$dummy.c #include main() { if (!__power_pc()) exit(1); puts("powerpc-ibm-aix3.2.5"); exit(0); } EOF if $CC_FOR_BUILD -o $dummy $dummy.c && SYSTEM_NAME=`$dummy` then echo "$SYSTEM_NAME" else echo rs6000-ibm-aix3.2.5 fi elif grep bos324 /usr/include/stdio.h >/dev/null 2>&1; then echo rs6000-ibm-aix3.2.4 else echo rs6000-ibm-aix3.2 fi exit ;; *:AIX:*:[456]) IBM_CPU_ID=`/usr/sbin/lsdev -C -c processor -S available | sed 1q | awk '{ print $1 }'` if /usr/sbin/lsattr -El ${IBM_CPU_ID} | grep ' POWER' >/dev/null 2>&1; then IBM_ARCH=rs6000 else IBM_ARCH=powerpc fi if [ -x /usr/bin/oslevel ] ; then IBM_REV=`/usr/bin/oslevel` else IBM_REV=${UNAME_VERSION}.${UNAME_RELEASE} fi echo ${IBM_ARCH}-ibm-aix${IBM_REV} exit ;; *:AIX:*:*) echo rs6000-ibm-aix exit ;; ibmrt:4.4BSD:*|romp-ibm:BSD:*) echo romp-ibm-bsd4.4 exit ;; ibmrt:*BSD:*|romp-ibm:BSD:*) # covers RT/PC BSD and echo romp-ibm-bsd${UNAME_RELEASE} # 4.3 with uname added to exit ;; # report: romp-ibm BSD 4.3 *:BOSX:*:*) echo rs6000-bull-bosx exit ;; DPX/2?00:B.O.S.:*:*) echo m68k-bull-sysv3 exit ;; 9000/[34]??:4.3bsd:1.*:*) echo m68k-hp-bsd exit ;; hp300:4.4BSD:*:* | 9000/[34]??:4.3bsd:2.*:*) echo m68k-hp-bsd4.4 exit ;; 9000/[34678]??:HP-UX:*:*) HPUX_REV=`echo ${UNAME_RELEASE}|sed -e 's/[^.]*.[0B]*//'` case "${UNAME_MACHINE}" in 9000/31? ) HP_ARCH=m68000 ;; 9000/[34]?? ) HP_ARCH=m68k ;; 9000/[678][0-9][0-9]) if [ -x /usr/bin/getconf ]; then sc_cpu_version=`/usr/bin/getconf SC_CPU_VERSION 2>/dev/null` sc_kernel_bits=`/usr/bin/getconf SC_KERNEL_BITS 2>/dev/null` case "${sc_cpu_version}" in 523) HP_ARCH="hppa1.0" ;; # CPU_PA_RISC1_0 528) HP_ARCH="hppa1.1" ;; # CPU_PA_RISC1_1 532) # CPU_PA_RISC2_0 case "${sc_kernel_bits}" in 32) HP_ARCH="hppa2.0n" ;; 64) HP_ARCH="hppa2.0w" ;; '') HP_ARCH="hppa2.0" ;; # HP-UX 10.20 esac ;; esac fi if [ "${HP_ARCH}" = "" ]; then eval $set_cc_for_build sed 's/^ //' << EOF >$dummy.c #define _HPUX_SOURCE #include #include int main () { #if defined(_SC_KERNEL_BITS) long bits = sysconf(_SC_KERNEL_BITS); #endif long cpu = sysconf (_SC_CPU_VERSION); switch (cpu) { case CPU_PA_RISC1_0: puts ("hppa1.0"); break; case CPU_PA_RISC1_1: puts ("hppa1.1"); break; case CPU_PA_RISC2_0: #if defined(_SC_KERNEL_BITS) switch (bits) { case 64: puts ("hppa2.0w"); break; case 32: puts ("hppa2.0n"); break; default: puts ("hppa2.0"); break; } break; #else /* !defined(_SC_KERNEL_BITS) */ puts ("hppa2.0"); break; #endif default: puts ("hppa1.0"); break; } exit (0); } EOF (CCOPTS= $CC_FOR_BUILD -o $dummy $dummy.c 2>/dev/null) && HP_ARCH=`$dummy` test -z "$HP_ARCH" && HP_ARCH=hppa fi ;; esac if [ ${HP_ARCH} = "hppa2.0w" ] then eval $set_cc_for_build # hppa2.0w-hp-hpux* has a 64-bit kernel and a compiler generating # 32-bit code. hppa64-hp-hpux* has the same kernel and a compiler # generating 64-bit code. GNU and HP use different nomenclature: # # $ CC_FOR_BUILD=cc ./config.guess # => hppa2.0w-hp-hpux11.23 # $ CC_FOR_BUILD="cc +DA2.0w" ./config.guess # => hppa64-hp-hpux11.23 if echo __LP64__ | (CCOPTS= $CC_FOR_BUILD -E - 2>/dev/null) | grep __LP64__ >/dev/null then HP_ARCH="hppa2.0w" else HP_ARCH="hppa64" fi fi echo ${HP_ARCH}-hp-hpux${HPUX_REV} exit ;; ia64:HP-UX:*:*) HPUX_REV=`echo ${UNAME_RELEASE}|sed -e 's/[^.]*.[0B]*//'` echo ia64-hp-hpux${HPUX_REV} exit ;; 3050*:HI-UX:*:*) eval $set_cc_for_build sed 's/^ //' << EOF >$dummy.c #include int main () { long cpu = sysconf (_SC_CPU_VERSION); /* The order matters, because CPU_IS_HP_MC68K erroneously returns true for CPU_PA_RISC1_0. CPU_IS_PA_RISC returns correct results, however. */ if (CPU_IS_PA_RISC (cpu)) { switch (cpu) { case CPU_PA_RISC1_0: puts ("hppa1.0-hitachi-hiuxwe2"); break; case CPU_PA_RISC1_1: puts ("hppa1.1-hitachi-hiuxwe2"); break; case CPU_PA_RISC2_0: puts ("hppa2.0-hitachi-hiuxwe2"); break; default: puts ("hppa-hitachi-hiuxwe2"); break; } } else if (CPU_IS_HP_MC68K (cpu)) puts ("m68k-hitachi-hiuxwe2"); else puts ("unknown-hitachi-hiuxwe2"); exit (0); } EOF $CC_FOR_BUILD -o $dummy $dummy.c && SYSTEM_NAME=`$dummy` && { echo "$SYSTEM_NAME"; exit; } echo unknown-hitachi-hiuxwe2 exit ;; 9000/7??:4.3bsd:*:* | 9000/8?[79]:4.3bsd:*:* ) echo hppa1.1-hp-bsd exit ;; 9000/8??:4.3bsd:*:*) echo hppa1.0-hp-bsd exit ;; *9??*:MPE/iX:*:* | *3000*:MPE/iX:*:*) echo hppa1.0-hp-mpeix exit ;; hp7??:OSF1:*:* | hp8?[79]:OSF1:*:* ) echo hppa1.1-hp-osf exit ;; hp8??:OSF1:*:*) echo hppa1.0-hp-osf exit ;; i*86:OSF1:*:*) if [ -x /usr/sbin/sysversion ] ; then echo ${UNAME_MACHINE}-unknown-osf1mk else echo ${UNAME_MACHINE}-unknown-osf1 fi exit ;; parisc*:Lites*:*:*) echo hppa1.1-hp-lites exit ;; C1*:ConvexOS:*:* | convex:ConvexOS:C1*:*) echo c1-convex-bsd exit ;; C2*:ConvexOS:*:* | convex:ConvexOS:C2*:*) if getsysinfo -f scalar_acc then echo c32-convex-bsd else echo c2-convex-bsd fi exit ;; C34*:ConvexOS:*:* | convex:ConvexOS:C34*:*) echo c34-convex-bsd exit ;; C38*:ConvexOS:*:* | convex:ConvexOS:C38*:*) echo c38-convex-bsd exit ;; C4*:ConvexOS:*:* | convex:ConvexOS:C4*:*) echo c4-convex-bsd exit ;; CRAY*Y-MP:*:*:*) echo ymp-cray-unicos${UNAME_RELEASE} | sed -e 's/\.[^.]*$/.X/' exit ;; CRAY*[A-Z]90:*:*:*) echo ${UNAME_MACHINE}-cray-unicos${UNAME_RELEASE} \ | sed -e 's/CRAY.*\([A-Z]90\)/\1/' \ -e y/ABCDEFGHIJKLMNOPQRSTUVWXYZ/abcdefghijklmnopqrstuvwxyz/ \ -e 's/\.[^.]*$/.X/' exit ;; CRAY*TS:*:*:*) echo t90-cray-unicos${UNAME_RELEASE} | sed -e 's/\.[^.]*$/.X/' exit ;; CRAY*T3E:*:*:*) echo alphaev5-cray-unicosmk${UNAME_RELEASE} | sed -e 's/\.[^.]*$/.X/' exit ;; CRAY*SV1:*:*:*) echo sv1-cray-unicos${UNAME_RELEASE} | sed -e 's/\.[^.]*$/.X/' exit ;; *:UNICOS/mp:*:*) echo craynv-cray-unicosmp${UNAME_RELEASE} | sed -e 's/\.[^.]*$/.X/' exit ;; F30[01]:UNIX_System_V:*:* | F700:UNIX_System_V:*:*) FUJITSU_PROC=`uname -m | tr 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' 'abcdefghijklmnopqrstuvwxyz'` FUJITSU_SYS=`uname -p | tr 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' 'abcdefghijklmnopqrstuvwxyz' | sed -e 's/\///'` FUJITSU_REL=`echo ${UNAME_RELEASE} | sed -e 's/ /_/'` echo "${FUJITSU_PROC}-fujitsu-${FUJITSU_SYS}${FUJITSU_REL}" exit ;; 5000:UNIX_System_V:4.*:*) FUJITSU_SYS=`uname -p | tr 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' 'abcdefghijklmnopqrstuvwxyz' | sed -e 's/\///'` FUJITSU_REL=`echo ${UNAME_RELEASE} | tr 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' 'abcdefghijklmnopqrstuvwxyz' | sed -e 's/ /_/'` echo "sparc-fujitsu-${FUJITSU_SYS}${FUJITSU_REL}" exit ;; i*86:BSD/386:*:* | i*86:BSD/OS:*:* | *:Ascend\ Embedded/OS:*:*) echo ${UNAME_MACHINE}-pc-bsdi${UNAME_RELEASE} exit ;; sparc*:BSD/OS:*:*) echo sparc-unknown-bsdi${UNAME_RELEASE} exit ;; *:BSD/OS:*:*) echo ${UNAME_MACHINE}-unknown-bsdi${UNAME_RELEASE} exit ;; *:FreeBSD:*:*) case ${UNAME_MACHINE} in pc98) echo i386-unknown-freebsd`echo ${UNAME_RELEASE}|sed -e 's/[-(].*//'` ;; amd64) echo x86_64-unknown-freebsd`echo ${UNAME_RELEASE}|sed -e 's/[-(].*//'` ;; *) echo ${UNAME_MACHINE}-unknown-freebsd`echo ${UNAME_RELEASE}|sed -e 's/[-(].*//'` ;; esac exit ;; i*:CYGWIN*:*) echo ${UNAME_MACHINE}-pc-cygwin exit ;; *:MINGW*:*) echo ${UNAME_MACHINE}-pc-mingw32 exit ;; i*:windows32*:*) # uname -m includes "-pc" on this system. echo ${UNAME_MACHINE}-mingw32 exit ;; i*:PW*:*) echo ${UNAME_MACHINE}-pc-pw32 exit ;; *:Interix*:[3456]*) case ${UNAME_MACHINE} in x86) echo i586-pc-interix${UNAME_RELEASE} exit ;; EM64T | authenticamd | genuineintel) echo x86_64-unknown-interix${UNAME_RELEASE} exit ;; IA64) echo ia64-unknown-interix${UNAME_RELEASE} exit ;; esac ;; [345]86:Windows_95:* | [345]86:Windows_98:* | [345]86:Windows_NT:*) echo i${UNAME_MACHINE}-pc-mks exit ;; i*:Windows_NT*:* | Pentium*:Windows_NT*:*) # How do we know it's Interix rather than the generic POSIX subsystem? # It also conflicts with pre-2.0 versions of AT&T UWIN. Should we # UNAME_MACHINE based on the output of uname instead of i386? echo i586-pc-interix exit ;; i*:UWIN*:*) echo ${UNAME_MACHINE}-pc-uwin exit ;; amd64:CYGWIN*:*:* | x86_64:CYGWIN*:*:*) echo x86_64-unknown-cygwin exit ;; p*:CYGWIN*:*) echo powerpcle-unknown-cygwin exit ;; prep*:SunOS:5.*:*) echo powerpcle-unknown-solaris2`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'` exit ;; *:GNU:*:*) # the GNU system echo `echo ${UNAME_MACHINE}|sed -e 's,[-/].*$,,'`-unknown-gnu`echo ${UNAME_RELEASE}|sed -e 's,/.*$,,'` exit ;; *:GNU/*:*:*) # other systems with GNU libc and userland echo ${UNAME_MACHINE}-unknown-`echo ${UNAME_SYSTEM} | sed 's,^[^/]*/,,' | tr '[A-Z]' '[a-z]'``echo ${UNAME_RELEASE}|sed -e 's/[-(].*//'`-gnu exit ;; i*86:Minix:*:*) echo ${UNAME_MACHINE}-pc-minix exit ;; arm*:Linux:*:*) eval $set_cc_for_build if echo __ARM_EABI__ | $CC_FOR_BUILD -E - 2>/dev/null \ | grep -q __ARM_EABI__ then echo ${UNAME_MACHINE}-unknown-linux-gnu else echo ${UNAME_MACHINE}-unknown-linux-gnueabi fi exit ;; avr32*:Linux:*:*) echo ${UNAME_MACHINE}-unknown-linux-gnu exit ;; cris:Linux:*:*) echo cris-axis-linux-gnu exit ;; crisv32:Linux:*:*) echo crisv32-axis-linux-gnu exit ;; frv:Linux:*:*) echo frv-unknown-linux-gnu exit ;; ia64:Linux:*:*) echo ${UNAME_MACHINE}-unknown-linux-gnu exit ;; m32r*:Linux:*:*) echo ${UNAME_MACHINE}-unknown-linux-gnu exit ;; m68*:Linux:*:*) echo ${UNAME_MACHINE}-unknown-linux-gnu exit ;; mips:Linux:*:*) eval $set_cc_for_build sed 's/^ //' << EOF >$dummy.c #undef CPU #undef mips #undef mipsel #if defined(__MIPSEL__) || defined(__MIPSEL) || defined(_MIPSEL) || defined(MIPSEL) CPU=mipsel #else #if defined(__MIPSEB__) || defined(__MIPSEB) || defined(_MIPSEB) || defined(MIPSEB) CPU=mips #else CPU= #endif #endif EOF eval "`$CC_FOR_BUILD -E $dummy.c 2>/dev/null | sed -n ' /^CPU/{ s: ::g p }'`" test x"${CPU}" != x && { echo "${CPU}-unknown-linux-gnu"; exit; } ;; mips64:Linux:*:*) eval $set_cc_for_build sed 's/^ //' << EOF >$dummy.c #undef CPU #undef mips64 #undef mips64el #if defined(__MIPSEL__) || defined(__MIPSEL) || defined(_MIPSEL) || defined(MIPSEL) CPU=mips64el #else #if defined(__MIPSEB__) || defined(__MIPSEB) || defined(_MIPSEB) || defined(MIPSEB) CPU=mips64 #else CPU= #endif #endif EOF eval "`$CC_FOR_BUILD -E $dummy.c 2>/dev/null | sed -n ' /^CPU/{ s: ::g p }'`" test x"${CPU}" != x && { echo "${CPU}-unknown-linux-gnu"; exit; } ;; or32:Linux:*:*) echo or32-unknown-linux-gnu exit ;; ppc:Linux:*:*) echo powerpc-unknown-linux-gnu exit ;; ppc64:Linux:*:*) echo powerpc64-unknown-linux-gnu exit ;; alpha:Linux:*:*) case `sed -n '/^cpu model/s/^.*: \(.*\)/\1/p' < /proc/cpuinfo` in EV5) UNAME_MACHINE=alphaev5 ;; EV56) UNAME_MACHINE=alphaev56 ;; PCA56) UNAME_MACHINE=alphapca56 ;; PCA57) UNAME_MACHINE=alphapca56 ;; EV6) UNAME_MACHINE=alphaev6 ;; EV67) UNAME_MACHINE=alphaev67 ;; EV68*) UNAME_MACHINE=alphaev68 ;; esac objdump --private-headers /bin/sh | grep ld.so.1 >/dev/null if test "$?" = 0 ; then LIBC="libc1" ; else LIBC="" ; fi echo ${UNAME_MACHINE}-unknown-linux-gnu${LIBC} exit ;; padre:Linux:*:*) echo sparc-unknown-linux-gnu exit ;; parisc:Linux:*:* | hppa:Linux:*:*) # Look for CPU level case `grep '^cpu[^a-z]*:' /proc/cpuinfo 2>/dev/null | cut -d' ' -f2` in PA7*) echo hppa1.1-unknown-linux-gnu ;; PA8*) echo hppa2.0-unknown-linux-gnu ;; *) echo hppa-unknown-linux-gnu ;; esac exit ;; parisc64:Linux:*:* | hppa64:Linux:*:*) echo hppa64-unknown-linux-gnu exit ;; s390:Linux:*:* | s390x:Linux:*:*) echo ${UNAME_MACHINE}-ibm-linux exit ;; sh64*:Linux:*:*) echo ${UNAME_MACHINE}-unknown-linux-gnu exit ;; sh*:Linux:*:*) echo ${UNAME_MACHINE}-unknown-linux-gnu exit ;; sparc:Linux:*:* | sparc64:Linux:*:*) echo ${UNAME_MACHINE}-unknown-linux-gnu exit ;; vax:Linux:*:*) echo ${UNAME_MACHINE}-dec-linux-gnu exit ;; x86_64:Linux:*:*) echo x86_64-unknown-linux-gnu exit ;; xtensa*:Linux:*:*) echo ${UNAME_MACHINE}-unknown-linux-gnu exit ;; i*86:Linux:*:*) # The BFD linker knows what the default object file format is, so # first see if it will tell us. cd to the root directory to prevent # problems with other programs or directories called `ld' in the path. # Set LC_ALL=C to ensure ld outputs messages in English. ld_supported_targets=`cd /; LC_ALL=C ld --help 2>&1 \ | sed -ne '/supported targets:/!d s/[ ][ ]*/ /g s/.*supported targets: *// s/ .*// p'` case "$ld_supported_targets" in elf32-i386) TENTATIVE="${UNAME_MACHINE}-pc-linux-gnu" ;; a.out-i386-linux) echo "${UNAME_MACHINE}-pc-linux-gnuaout" exit ;; "") # Either a pre-BFD a.out linker (linux-gnuoldld) or # one that does not give us useful --help. echo "${UNAME_MACHINE}-pc-linux-gnuoldld" exit ;; esac # Determine whether the default compiler is a.out or elf eval $set_cc_for_build sed 's/^ //' << EOF >$dummy.c #include #ifdef __ELF__ # ifdef __GLIBC__ # if __GLIBC__ >= 2 LIBC=gnu # else LIBC=gnulibc1 # endif # else LIBC=gnulibc1 # endif #else #if defined(__INTEL_COMPILER) || defined(__PGI) || defined(__SUNPRO_C) || defined(__SUNPRO_CC) LIBC=gnu #else LIBC=gnuaout #endif #endif #ifdef __dietlibc__ LIBC=dietlibc #endif EOF eval "`$CC_FOR_BUILD -E $dummy.c 2>/dev/null | sed -n ' /^LIBC/{ s: ::g p }'`" test x"${LIBC}" != x && { echo "${UNAME_MACHINE}-pc-linux-${LIBC}" exit } test x"${TENTATIVE}" != x && { echo "${TENTATIVE}"; exit; } ;; i*86:DYNIX/ptx:4*:*) # ptx 4.0 does uname -s correctly, with DYNIX/ptx in there. # earlier versions are messed up and put the nodename in both # sysname and nodename. echo i386-sequent-sysv4 exit ;; i*86:UNIX_SV:4.2MP:2.*) # Unixware is an offshoot of SVR4, but it has its own version # number series starting with 2... # I am not positive that other SVR4 systems won't match this, # I just have to hope. -- rms. # Use sysv4.2uw... so that sysv4* matches it. echo ${UNAME_MACHINE}-pc-sysv4.2uw${UNAME_VERSION} exit ;; i*86:OS/2:*:*) # If we were able to find `uname', then EMX Unix compatibility # is probably installed. echo ${UNAME_MACHINE}-pc-os2-emx exit ;; i*86:XTS-300:*:STOP) echo ${UNAME_MACHINE}-unknown-stop exit ;; i*86:atheos:*:*) echo ${UNAME_MACHINE}-unknown-atheos exit ;; i*86:syllable:*:*) echo ${UNAME_MACHINE}-pc-syllable exit ;; i*86:LynxOS:2.*:* | i*86:LynxOS:3.[01]*:* | i*86:LynxOS:4.0*:*) echo i386-unknown-lynxos${UNAME_RELEASE} exit ;; i*86:*DOS:*:*) echo ${UNAME_MACHINE}-pc-msdosdjgpp exit ;; i*86:*:4.*:* | i*86:SYSTEM_V:4.*:*) UNAME_REL=`echo ${UNAME_RELEASE} | sed 's/\/MP$//'` if grep Novell /usr/include/link.h >/dev/null 2>/dev/null; then echo ${UNAME_MACHINE}-univel-sysv${UNAME_REL} else echo ${UNAME_MACHINE}-pc-sysv${UNAME_REL} fi exit ;; i*86:*:5:[678]*) # UnixWare 7.x, OpenUNIX and OpenServer 6. case `/bin/uname -X | grep "^Machine"` in *486*) UNAME_MACHINE=i486 ;; *Pentium) UNAME_MACHINE=i586 ;; *Pent*|*Celeron) UNAME_MACHINE=i686 ;; esac echo ${UNAME_MACHINE}-unknown-sysv${UNAME_RELEASE}${UNAME_SYSTEM}${UNAME_VERSION} exit ;; i*86:*:3.2:*) if test -f /usr/options/cb.name; then UNAME_REL=`sed -n 's/.*Version //p' /dev/null >/dev/null ; then UNAME_REL=`(/bin/uname -X|grep Release|sed -e 's/.*= //')` (/bin/uname -X|grep i80486 >/dev/null) && UNAME_MACHINE=i486 (/bin/uname -X|grep '^Machine.*Pentium' >/dev/null) \ && UNAME_MACHINE=i586 (/bin/uname -X|grep '^Machine.*Pent *II' >/dev/null) \ && UNAME_MACHINE=i686 (/bin/uname -X|grep '^Machine.*Pentium Pro' >/dev/null) \ && UNAME_MACHINE=i686 echo ${UNAME_MACHINE}-pc-sco$UNAME_REL else echo ${UNAME_MACHINE}-pc-sysv32 fi exit ;; pc:*:*:*) # Left here for compatibility: # uname -m prints for DJGPP always 'pc', but it prints nothing about # the processor, so we play safe by assuming i586. # Note: whatever this is, it MUST be the same as what config.sub # prints for the "djgpp" host, or else GDB configury will decide that # this is a cross-build. echo i586-pc-msdosdjgpp exit ;; Intel:Mach:3*:*) echo i386-pc-mach3 exit ;; paragon:*:*:*) echo i860-intel-osf1 exit ;; i860:*:4.*:*) # i860-SVR4 if grep Stardent /usr/include/sys/uadmin.h >/dev/null 2>&1 ; then echo i860-stardent-sysv${UNAME_RELEASE} # Stardent Vistra i860-SVR4 else # Add other i860-SVR4 vendors below as they are discovered. echo i860-unknown-sysv${UNAME_RELEASE} # Unknown i860-SVR4 fi exit ;; mini*:CTIX:SYS*5:*) # "miniframe" echo m68010-convergent-sysv exit ;; mc68k:UNIX:SYSTEM5:3.51m) echo m68k-convergent-sysv exit ;; M680?0:D-NIX:5.3:*) echo m68k-diab-dnix exit ;; M68*:*:R3V[5678]*:*) test -r /sysV68 && { echo 'm68k-motorola-sysv'; exit; } ;; 3[345]??:*:4.0:3.0 | 3[34]??A:*:4.0:3.0 | 3[34]??,*:*:4.0:3.0 | 3[34]??/*:*:4.0:3.0 | 4400:*:4.0:3.0 | 4850:*:4.0:3.0 | SKA40:*:4.0:3.0 | SDS2:*:4.0:3.0 | SHG2:*:4.0:3.0 | S7501*:*:4.0:3.0) OS_REL='' test -r /etc/.relid \ && OS_REL=.`sed -n 's/[^ ]* [^ ]* \([0-9][0-9]\).*/\1/p' < /etc/.relid` /bin/uname -p 2>/dev/null | grep 86 >/dev/null \ && { echo i486-ncr-sysv4.3${OS_REL}; exit; } /bin/uname -p 2>/dev/null | /bin/grep entium >/dev/null \ && { echo i586-ncr-sysv4.3${OS_REL}; exit; } ;; 3[34]??:*:4.0:* | 3[34]??,*:*:4.0:*) /bin/uname -p 2>/dev/null | grep 86 >/dev/null \ && { echo i486-ncr-sysv4; exit; } ;; NCR*:*:4.2:* | MPRAS*:*:4.2:*) OS_REL='.3' test -r /etc/.relid \ && OS_REL=.`sed -n 's/[^ ]* [^ ]* \([0-9][0-9]\).*/\1/p' < /etc/.relid` /bin/uname -p 2>/dev/null | grep 86 >/dev/null \ && { echo i486-ncr-sysv4.3${OS_REL}; exit; } /bin/uname -p 2>/dev/null | /bin/grep entium >/dev/null \ && { echo i586-ncr-sysv4.3${OS_REL}; exit; } /bin/uname -p 2>/dev/null | /bin/grep pteron >/dev/null \ && { echo i586-ncr-sysv4.3${OS_REL}; exit; } ;; m68*:LynxOS:2.*:* | m68*:LynxOS:3.0*:*) echo m68k-unknown-lynxos${UNAME_RELEASE} exit ;; mc68030:UNIX_System_V:4.*:*) echo m68k-atari-sysv4 exit ;; TSUNAMI:LynxOS:2.*:*) echo sparc-unknown-lynxos${UNAME_RELEASE} exit ;; rs6000:LynxOS:2.*:*) echo rs6000-unknown-lynxos${UNAME_RELEASE} exit ;; PowerPC:LynxOS:2.*:* | PowerPC:LynxOS:3.[01]*:* | PowerPC:LynxOS:4.0*:*) echo powerpc-unknown-lynxos${UNAME_RELEASE} exit ;; SM[BE]S:UNIX_SV:*:*) echo mips-dde-sysv${UNAME_RELEASE} exit ;; RM*:ReliantUNIX-*:*:*) echo mips-sni-sysv4 exit ;; RM*:SINIX-*:*:*) echo mips-sni-sysv4 exit ;; *:SINIX-*:*:*) if uname -p 2>/dev/null >/dev/null ; then UNAME_MACHINE=`(uname -p) 2>/dev/null` echo ${UNAME_MACHINE}-sni-sysv4 else echo ns32k-sni-sysv fi exit ;; PENTIUM:*:4.0*:*) # Unisys `ClearPath HMP IX 4000' SVR4/MP effort # says echo i586-unisys-sysv4 exit ;; *:UNIX_System_V:4*:FTX*) # From Gerald Hewes . # How about differentiating between stratus architectures? -djm echo hppa1.1-stratus-sysv4 exit ;; *:*:*:FTX*) # From seanf@swdc.stratus.com. echo i860-stratus-sysv4 exit ;; i*86:VOS:*:*) # From Paul.Green@stratus.com. echo ${UNAME_MACHINE}-stratus-vos exit ;; *:VOS:*:*) # From Paul.Green@stratus.com. echo hppa1.1-stratus-vos exit ;; mc68*:A/UX:*:*) echo m68k-apple-aux${UNAME_RELEASE} exit ;; news*:NEWS-OS:6*:*) echo mips-sony-newsos6 exit ;; R[34]000:*System_V*:*:* | R4000:UNIX_SYSV:*:* | R*000:UNIX_SV:*:*) if [ -d /usr/nec ]; then echo mips-nec-sysv${UNAME_RELEASE} else echo mips-unknown-sysv${UNAME_RELEASE} fi exit ;; BeBox:BeOS:*:*) # BeOS running on hardware made by Be, PPC only. echo powerpc-be-beos exit ;; BeMac:BeOS:*:*) # BeOS running on Mac or Mac clone, PPC only. echo powerpc-apple-beos exit ;; BePC:BeOS:*:*) # BeOS running on Intel PC compatible. echo i586-pc-beos exit ;; BePC:Haiku:*:*) # Haiku running on Intel PC compatible. echo i586-pc-haiku exit ;; SX-4:SUPER-UX:*:*) echo sx4-nec-superux${UNAME_RELEASE} exit ;; SX-5:SUPER-UX:*:*) echo sx5-nec-superux${UNAME_RELEASE} exit ;; SX-6:SUPER-UX:*:*) echo sx6-nec-superux${UNAME_RELEASE} exit ;; SX-7:SUPER-UX:*:*) echo sx7-nec-superux${UNAME_RELEASE} exit ;; SX-8:SUPER-UX:*:*) echo sx8-nec-superux${UNAME_RELEASE} exit ;; SX-8R:SUPER-UX:*:*) echo sx8r-nec-superux${UNAME_RELEASE} exit ;; Power*:Rhapsody:*:*) echo powerpc-apple-rhapsody${UNAME_RELEASE} exit ;; *:Rhapsody:*:*) echo ${UNAME_MACHINE}-apple-rhapsody${UNAME_RELEASE} exit ;; *:Darwin:*:*) UNAME_PROCESSOR=`uname -p` || UNAME_PROCESSOR=unknown case $UNAME_PROCESSOR in unknown) UNAME_PROCESSOR=powerpc ;; esac echo ${UNAME_PROCESSOR}-apple-darwin${UNAME_RELEASE} exit ;; *:procnto*:*:* | *:QNX:[0123456789]*:*) UNAME_PROCESSOR=`uname -p` if test "$UNAME_PROCESSOR" = "x86"; then UNAME_PROCESSOR=i386 UNAME_MACHINE=pc fi echo ${UNAME_PROCESSOR}-${UNAME_MACHINE}-nto-qnx${UNAME_RELEASE} exit ;; *:QNX:*:4*) echo i386-pc-qnx exit ;; NSE-?:NONSTOP_KERNEL:*:*) echo nse-tandem-nsk${UNAME_RELEASE} exit ;; NSR-?:NONSTOP_KERNEL:*:*) echo nsr-tandem-nsk${UNAME_RELEASE} exit ;; *:NonStop-UX:*:*) echo mips-compaq-nonstopux exit ;; BS2000:POSIX*:*:*) echo bs2000-siemens-sysv exit ;; DS/*:UNIX_System_V:*:*) echo ${UNAME_MACHINE}-${UNAME_SYSTEM}-${UNAME_RELEASE} exit ;; *:Plan9:*:*) # "uname -m" is not consistent, so use $cputype instead. 386 # is converted to i386 for consistency with other x86 # operating systems. if test "$cputype" = "386"; then UNAME_MACHINE=i386 else UNAME_MACHINE="$cputype" fi echo ${UNAME_MACHINE}-unknown-plan9 exit ;; *:TOPS-10:*:*) echo pdp10-unknown-tops10 exit ;; *:TENEX:*:*) echo pdp10-unknown-tenex exit ;; KS10:TOPS-20:*:* | KL10:TOPS-20:*:* | TYPE4:TOPS-20:*:*) echo pdp10-dec-tops20 exit ;; XKL-1:TOPS-20:*:* | TYPE5:TOPS-20:*:*) echo pdp10-xkl-tops20 exit ;; *:TOPS-20:*:*) echo pdp10-unknown-tops20 exit ;; *:ITS:*:*) echo pdp10-unknown-its exit ;; SEI:*:*:SEIUX) echo mips-sei-seiux${UNAME_RELEASE} exit ;; *:DragonFly:*:*) echo ${UNAME_MACHINE}-unknown-dragonfly`echo ${UNAME_RELEASE}|sed -e 's/[-(].*//'` exit ;; *:*VMS:*:*) UNAME_MACHINE=`(uname -p) 2>/dev/null` case "${UNAME_MACHINE}" in A*) echo alpha-dec-vms ; exit ;; I*) echo ia64-dec-vms ; exit ;; V*) echo vax-dec-vms ; exit ;; esac ;; *:XENIX:*:SysV) echo i386-pc-xenix exit ;; i*86:skyos:*:*) echo ${UNAME_MACHINE}-pc-skyos`echo ${UNAME_RELEASE}` | sed -e 's/ .*$//' exit ;; i*86:rdos:*:*) echo ${UNAME_MACHINE}-pc-rdos exit ;; i*86:AROS:*:*) echo ${UNAME_MACHINE}-pc-aros exit ;; esac #echo '(No uname command or uname output not recognized.)' 1>&2 #echo "${UNAME_MACHINE}:${UNAME_SYSTEM}:${UNAME_RELEASE}:${UNAME_VERSION}" 1>&2 eval $set_cc_for_build cat >$dummy.c < # include #endif main () { #if defined (sony) #if defined (MIPSEB) /* BFD wants "bsd" instead of "newsos". Perhaps BFD should be changed, I don't know.... */ printf ("mips-sony-bsd\n"); exit (0); #else #include printf ("m68k-sony-newsos%s\n", #ifdef NEWSOS4 "4" #else "" #endif ); exit (0); #endif #endif #if defined (__arm) && defined (__acorn) && defined (__unix) printf ("arm-acorn-riscix\n"); exit (0); #endif #if defined (hp300) && !defined (hpux) printf ("m68k-hp-bsd\n"); exit (0); #endif #if defined (NeXT) #if !defined (__ARCHITECTURE__) #define __ARCHITECTURE__ "m68k" #endif int version; version=`(hostinfo | sed -n 's/.*NeXT Mach \([0-9]*\).*/\1/p') 2>/dev/null`; if (version < 4) printf ("%s-next-nextstep%d\n", __ARCHITECTURE__, version); else printf ("%s-next-openstep%d\n", __ARCHITECTURE__, version); exit (0); #endif #if defined (MULTIMAX) || defined (n16) #if defined (UMAXV) printf ("ns32k-encore-sysv\n"); exit (0); #else #if defined (CMU) printf ("ns32k-encore-mach\n"); exit (0); #else printf ("ns32k-encore-bsd\n"); exit (0); #endif #endif #endif #if defined (__386BSD__) printf ("i386-pc-bsd\n"); exit (0); #endif #if defined (sequent) #if defined (i386) printf ("i386-sequent-dynix\n"); exit (0); #endif #if defined (ns32000) printf ("ns32k-sequent-dynix\n"); exit (0); #endif #endif #if defined (_SEQUENT_) struct utsname un; uname(&un); if (strncmp(un.version, "V2", 2) == 0) { printf ("i386-sequent-ptx2\n"); exit (0); } if (strncmp(un.version, "V1", 2) == 0) { /* XXX is V1 correct? */ printf ("i386-sequent-ptx1\n"); exit (0); } printf ("i386-sequent-ptx\n"); exit (0); #endif #if defined (vax) # if !defined (ultrix) # include # if defined (BSD) # if BSD == 43 printf ("vax-dec-bsd4.3\n"); exit (0); # else # if BSD == 199006 printf ("vax-dec-bsd4.3reno\n"); exit (0); # else printf ("vax-dec-bsd\n"); exit (0); # endif # endif # else printf ("vax-dec-bsd\n"); exit (0); # endif # else printf ("vax-dec-ultrix\n"); exit (0); # endif #endif #if defined (alliant) && defined (i860) printf ("i860-alliant-bsd\n"); exit (0); #endif exit (1); } EOF $CC_FOR_BUILD -o $dummy $dummy.c 2>/dev/null && SYSTEM_NAME=`$dummy` && { echo "$SYSTEM_NAME"; exit; } # Apollos put the system type in the environment. test -d /usr/apollo && { echo ${ISP}-apollo-${SYSTYPE}; exit; } # Convex versions that predate uname can use getsysinfo(1) if [ -x /usr/convex/getsysinfo ] then case `getsysinfo -f cpu_type` in c1*) echo c1-convex-bsd exit ;; c2*) if getsysinfo -f scalar_acc then echo c32-convex-bsd else echo c2-convex-bsd fi exit ;; c34*) echo c34-convex-bsd exit ;; c38*) echo c38-convex-bsd exit ;; c4*) echo c4-convex-bsd exit ;; esac fi cat >&2 < in order to provide the needed information to handle your system. config.guess timestamp = $timestamp uname -m = `(uname -m) 2>/dev/null || echo unknown` uname -r = `(uname -r) 2>/dev/null || echo unknown` uname -s = `(uname -s) 2>/dev/null || echo unknown` uname -v = `(uname -v) 2>/dev/null || echo unknown` /usr/bin/uname -p = `(/usr/bin/uname -p) 2>/dev/null` /bin/uname -X = `(/bin/uname -X) 2>/dev/null` hostinfo = `(hostinfo) 2>/dev/null` /bin/universe = `(/bin/universe) 2>/dev/null` /usr/bin/arch -k = `(/usr/bin/arch -k) 2>/dev/null` /bin/arch = `(/bin/arch) 2>/dev/null` /usr/bin/oslevel = `(/usr/bin/oslevel) 2>/dev/null` /usr/convex/getsysinfo = `(/usr/convex/getsysinfo) 2>/dev/null` UNAME_MACHINE = ${UNAME_MACHINE} UNAME_RELEASE = ${UNAME_RELEASE} UNAME_SYSTEM = ${UNAME_SYSTEM} UNAME_VERSION = ${UNAME_VERSION} EOF exit 1 # Local variables: # eval: (add-hook 'write-file-hooks 'time-stamp) # time-stamp-start: "timestamp='" # time-stamp-format: "%:y-%02m-%02d" # time-stamp-end: "'" # End: openchange-2.0/config.h.in000066400000000000000000000045061223057412600155140ustar00rootroot00000000000000/* config.h.in. Generated from configure.ac by autoheader. */ /* Whether or not we have comparison_fn_t */ #undef HAVE_COMPARISON_FN_T /* Define to 1 if you have the `dlopen' function. */ #undef HAVE_DLOPEN /* Define if you want to use gthread for thread safety */ #undef HAVE_GTHREAD /* Define to 1 if you have the header file. */ #undef HAVE_INTTYPES_H /* Define if you want to use libmagic */ #undef HAVE_LIBMAGIC /* Define if you want to use libpopt */ #undef HAVE_LIBPOPT /* Define to 1 if you have the `z' library (-lz). */ #undef HAVE_LIBZ /* Define to 1 if you have the header file. */ #undef HAVE_MEMORY_H /* Define to 1 if you have the `mq_open' function. */ #undef HAVE_MQ_OPEN /* Define if you want to use pthread for thread safety */ #undef HAVE_PTHREADS /* Define to 1 if you have the header file. */ #undef HAVE_STDINT_H /* Define to 1 if you have the header file. */ #undef HAVE_STDLIB_H /* Define to 1 if you have the `strcasestr' function. */ #undef HAVE_STRCASESTR /* Define to 1 if you have the header file. */ #undef HAVE_STRINGS_H /* Define to 1 if you have the header file. */ #undef HAVE_STRING_H /* Define if you want to use subunit */ #undef HAVE_SUBUNIT /* Define to 1 if you have the header file. */ #undef HAVE_SYS_CDEFS_H /* Define to 1 if you have the header file. */ #undef HAVE_SYS_SOCKIO_H /* Define to 1 if you have the header file. */ #undef HAVE_SYS_STAT_H /* Define to 1 if you have the header file. */ #undef HAVE_SYS_TYPES_H /* Define to 1 if you have the header file. */ #undef HAVE_UNISTD_H /* Name of package */ #undef PACKAGE /* Define to the address where bug reports for this package should be sent. */ #undef PACKAGE_BUGREPORT /* Define to the full name of this package. */ #undef PACKAGE_NAME /* Define to the full name and version of this package. */ #undef PACKAGE_STRING /* Define to the one symbol short name of this package. */ #undef PACKAGE_TARNAME /* Define to the home page for this package. */ #undef PACKAGE_URL /* Define to the version of this package. */ #undef PACKAGE_VERSION /* Define to 1 if you have the ANSI C header files. */ #undef STDC_HEADERS /* Version number of package */ #undef VERSION /* Use GNU extensions */ #undef _GNU_SOURCE openchange-2.0/config.mk.in000066400000000000000000000060441223057412600156730ustar00rootroot00000000000000# Mode (Release or snapshot?) SNAPSHOT=@OPENCHANGE_VERSION_IS_SVN_SNAPSHOT@ # Binary CC=@CC@ CXX=@CXX@ BISON=@BISON@ FLEX=@FLEX@ PIDL=@PIDL@ PERL=@PERL@ DOXYGEN=@DOXYGEN@ INSTALL=@INSTALL@ SED=sed -i 's/"\(.*\)\/\(.*\)\.h"/<\1\/\2.h>/g' PYTHON=@PYTHON@ PYTHON_CONFIG=@PYTHON_CONFIG@ PYTHON_CFLAGS=@PYTHON_CFLAGS@ PYTHON_LIBS=@PYTHON_LIBS@ prefix=@prefix@ exec_prefix=@exec_prefix@ bindir=@bindir@ sbindir=@sbindir@ libdir=@libdir@ modulesdir=@modulesdir@ datarootdir=@datarootdir@ datadir=@datadir@ includedir=@includedir@ mandir=@mandir@ top_builddir=@builddir@ pythondir=@pythondir@ sambaprefix=@sambaprefix@ DSOOPT=-shared -fPIC CFLAGS=@CFLAGS@ @COMPILER_OPTIONS_C@ @ASSERT_DEFINITION@ @SUBUNIT_CFLAGS@ \ -DDEFAULT_LDIF=\"$(datadir)/setup/profiles\" \ -DMAPISTORE_LDIF=\"$(datadir)/setup/mapistore\" \ -DMAPISTORE_BACKEND_INSTALLDIR=\"$(libdir)/mapistore_backends\" \ -DLZXPRESS_DATADIR=\"$(datadir)/mapitest/lzxpress\" \ -DLZFU_DATADIR=\"$(datadir)/mapitest/lzfu\" \ -DHAVE_ICAL_0_46=@have_libical_0_46@ # This value should be determined by configure at some point SHLIBEXT=so PACKAGE_VERSION=@PACKAGE_VERSION@ SAMBA_CFLAGS=@SAMBA_CFLAGS@ SAMBA_LIBS=@SAMBA_LIBS@ LDB_CFLAGS=@LDB_CFLAGS@ LDB_LIBS=@LDB_LIBS@ TDB_CFLAGS=@TDB_CFLAGS@ TDB_LIBS=@TDB_LIBS@ TALLOC_CFLAGS=@TALLOC_CFLAGS@ TALLOC_LIBS=@TALLOC_LIBS@ CFLAGS+=$(SAMBA_CFLAGS) $(LDB_CFLAGS) $(TALLOC_CFLAGS) $(TDB_CFLAGS) $(THREAD_CFLAGS) LIBS+=$(SAMBA_LIBS) $(LDB_LIBS) $(TALLOC_LIBS) $(THREAD_LIBS) $(RT_LIBS) LDFLAGS+=@LDFLAGS@ THREAD_LIBS=@THREAD_LIBS@ THREAD_CFLAGS=@THREAD_CFLAGS@ SAMBASERVER_CFLAGS=@SAMBASERVER_CFLAGS@ SAMBASERVER_LIBS=@SAMBASERVER_LIBS@ DL_LIBS=@DL_LIBS@ RT_LIBS=@RT_LIBS@ # Assign CFLAGS to CXXFLAGS CXXFLAGS=@CFLAGS@ @COMPILER_OPTIONS_CXX@ $(SAMBA_CFLAGS) $(LDB_CFLAGS) $(TALLOC_CFLAGS) $(TDB_CFLAGS) $(THREAD_CFLAGS) # OPENCHANGE LIBRARIES OC_IDL=@OC_IDL@ OC_LIBS=@OC_LIBS@ OC_LIBS_INSTALL=@OC_LIBS_INSTALL@ OC_LIBS_UNINSTALL=@OC_LIBS_UNINSTALL@ OC_LIBS_INSTALLPC=@OC_LIBS_INSTALLPC@ OC_LIBS_INSTALLHEADER=@OC_LIBS_INSTALLHEADER@ OC_LIBS_INSTALLLIB=@OC_LIBS_INSTALLLIB@ LIBMAPIADMIN_LIBS+=@SAMR_LIBS@ LIBMAPIADMIN_CFLAGS=@SAMR_CFLAGS@ # TORTURE DCERPC_SERVER_MODULESDIR=@DCERPC_SERVER_MODULESDIR@ # TOOLS OC_TOOLS=@OC_TOOLS@ OC_TOOLS_INSTALL=@OC_TOOLS_INSTALL@ OC_TOOLS_UNINSTALL=@OC_TOOLS_UNINSTALL@ MAGIC_LIBS=@MAGIC_LIBS@ ICAL_CFLAGS=@ICAL_CFLAGS@ ICAL_LIBS=@ICAL_LIBS@ # SERVER OC_SERVER=@OC_SERVER@ OC_SERVER_INSTALL=@OC_SERVER_INSTALL@ OC_SERVER_UNINSTALL=@OC_SERVER_UNINSTALL@ # MAPISTORE BACKENDS OC_MAPISTORE=@OC_MAPISTORE@ OC_MAPISTORE_CLEAN=@OC_MAPISTORE_CLEAN@ OC_MAPISTORE_INSTALL=@OC_MAPISTORE_INSTALL@ OC_MAPISTORE_UNINSTALL=@OC_MAPISTORE_UNINSTALL@ MAPISTORE_TEST=@MAPISTORE_TEST@ SUBUNIT_LIBS=@SUBUNIT_LIBS@ # Python PYMAPIALL=@PYMAPIALL@ PYMAPIINSTALL=@PYMAPIINSTALL@ PYMAPIUNINSTALL=@PYMAPIUNINSTALL@ PYCDIR=@PYCDIR@ # Coverage COVERAGE_INIT=@COVERAGE_INIT@ MANUALLY_CREATE_SYMLINKS=@MANUALLY_CREATE_SYMLINKS@ # Qt support QT4_CXXFLAGS=@Qt4_CFLAGS@ QT4_LIBS=@Qt4_LIBS@ MOC=@MOC@ OPENCHANGE_QT4=@OPENCHANGE_QT4@ openchange-2.0/config.sub000077500000000000000000001022401223057412600154460ustar00rootroot00000000000000#! /bin/sh # Configuration validation subroutine script. # Copyright (C) 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, # 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008 # Free Software Foundation, Inc. timestamp='2009-04-17' # This file is (in principle) common to ALL GNU software. # The presence of a machine in this file suggests that SOME GNU software # can handle that machine. It does not imply ALL GNU software can. # # This file is free software; you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by # the Free Software Foundation; either version 2 of the License, or # (at your option) any later version. # # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program; if not, write to the Free Software # Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston, MA # 02110-1301, USA. # # As a special exception to the GNU General Public License, if you # distribute this file as part of a program that contains a # configuration script generated by Autoconf, you may include it under # the same distribution terms that you use for the rest of that program. # Please send patches to . Submit a context # diff and a properly formatted ChangeLog entry. # # Configuration subroutine to validate and canonicalize a configuration type. # Supply the specified configuration type as an argument. # If it is invalid, we print an error message on stderr and exit with code 1. # Otherwise, we print the canonical config type on stdout and succeed. # This file is supposed to be the same for all GNU packages # and recognize all the CPU types, system types and aliases # that are meaningful with *any* GNU software. # Each package is responsible for reporting which valid configurations # it does not support. The user should be able to distinguish # a failure to support a valid configuration from a meaningless # configuration. # The goal of this file is to map all the various variations of a given # machine specification into a single specification in the form: # CPU_TYPE-MANUFACTURER-OPERATING_SYSTEM # or in some cases, the newer four-part form: # CPU_TYPE-MANUFACTURER-KERNEL-OPERATING_SYSTEM # It is wrong to echo any other type of specification. me=`echo "$0" | sed -e 's,.*/,,'` usage="\ Usage: $0 [OPTION] CPU-MFR-OPSYS $0 [OPTION] ALIAS Canonicalize a configuration name. Operation modes: -h, --help print this help, then exit -t, --time-stamp print date of last modification, then exit -v, --version print version number, then exit Report bugs and patches to ." version="\ GNU config.sub ($timestamp) Copyright (C) 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008 Free Software Foundation, Inc. This is free software; see the source for copying conditions. There is NO warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE." help=" Try \`$me --help' for more information." # Parse command line while test $# -gt 0 ; do case $1 in --time-stamp | --time* | -t ) echo "$timestamp" ; exit ;; --version | -v ) echo "$version" ; exit ;; --help | --h* | -h ) echo "$usage"; exit ;; -- ) # Stop option processing shift; break ;; - ) # Use stdin as input. break ;; -* ) echo "$me: invalid option $1$help" exit 1 ;; *local*) # First pass through any local machine types. echo $1 exit ;; * ) break ;; esac done case $# in 0) echo "$me: missing argument$help" >&2 exit 1;; 1) ;; *) echo "$me: too many arguments$help" >&2 exit 1;; esac # Separate what the user gave into CPU-COMPANY and OS or KERNEL-OS (if any). # Here we must recognize all the valid KERNEL-OS combinations. maybe_os=`echo $1 | sed 's/^\(.*\)-\([^-]*-[^-]*\)$/\2/'` case $maybe_os in nto-qnx* | linux-gnu* | linux-dietlibc | linux-newlib* | linux-uclibc* | \ uclinux-uclibc* | uclinux-gnu* | kfreebsd*-gnu* | knetbsd*-gnu* | netbsd*-gnu* | \ kopensolaris*-gnu* | \ storm-chaos* | os2-emx* | rtmk-nova*) os=-$maybe_os basic_machine=`echo $1 | sed 's/^\(.*\)-\([^-]*-[^-]*\)$/\1/'` ;; *) basic_machine=`echo $1 | sed 's/-[^-]*$//'` if [ $basic_machine != $1 ] then os=`echo $1 | sed 's/.*-/-/'` else os=; fi ;; esac ### Let's recognize common machines as not being operating systems so ### that things like config.sub decstation-3100 work. We also ### recognize some manufacturers as not being operating systems, so we ### can provide default operating systems below. case $os in -sun*os*) # Prevent following clause from handling this invalid input. ;; -dec* | -mips* | -sequent* | -encore* | -pc532* | -sgi* | -sony* | \ -att* | -7300* | -3300* | -delta* | -motorola* | -sun[234]* | \ -unicom* | -ibm* | -next | -hp | -isi* | -apollo | -altos* | \ -convergent* | -ncr* | -news | -32* | -3600* | -3100* | -hitachi* |\ -c[123]* | -convex* | -sun | -crds | -omron* | -dg | -ultra | -tti* | \ -harris | -dolphin | -highlevel | -gould | -cbm | -ns | -masscomp | \ -apple | -axis | -knuth | -cray) os= basic_machine=$1 ;; -sim | -cisco | -oki | -wec | -winbond) os= basic_machine=$1 ;; -scout) ;; -wrs) os=-vxworks basic_machine=$1 ;; -chorusos*) os=-chorusos basic_machine=$1 ;; -chorusrdb) os=-chorusrdb basic_machine=$1 ;; -hiux*) os=-hiuxwe2 ;; -sco6) os=-sco5v6 basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` ;; -sco5) os=-sco3.2v5 basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` ;; -sco4) os=-sco3.2v4 basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` ;; -sco3.2.[4-9]*) os=`echo $os | sed -e 's/sco3.2./sco3.2v/'` basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` ;; -sco3.2v[4-9]*) # Don't forget version if it is 3.2v4 or newer. basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` ;; -sco5v6*) # Don't forget version if it is 3.2v4 or newer. basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` ;; -sco*) os=-sco3.2v2 basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` ;; -udk*) basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` ;; -isc) os=-isc2.2 basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` ;; -clix*) basic_machine=clipper-intergraph ;; -isc*) basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` ;; -lynx*) os=-lynxos ;; -ptx*) basic_machine=`echo $1 | sed -e 's/86-.*/86-sequent/'` ;; -windowsnt*) os=`echo $os | sed -e 's/windowsnt/winnt/'` ;; -psos*) os=-psos ;; -mint | -mint[0-9]*) basic_machine=m68k-atari os=-mint ;; esac # Decode aliases for certain CPU-COMPANY combinations. case $basic_machine in # Recognize the basic CPU types without company name. # Some are omitted here because they have special meanings below. 1750a | 580 \ | a29k \ | alpha | alphaev[4-8] | alphaev56 | alphaev6[78] | alphapca5[67] \ | alpha64 | alpha64ev[4-8] | alpha64ev56 | alpha64ev6[78] | alpha64pca5[67] \ | am33_2.0 \ | arc | arm | arm[bl]e | arme[lb] | armv[2345] | armv[345][lb] | avr | avr32 \ | bfin \ | c4x | clipper \ | d10v | d30v | dlx | dsp16xx \ | fido | fr30 | frv \ | h8300 | h8500 | hppa | hppa1.[01] | hppa2.0 | hppa2.0[nw] | hppa64 \ | i370 | i860 | i960 | ia64 \ | ip2k | iq2000 \ | lm32 \ | m32c | m32r | m32rle | m68000 | m68k | m88k \ | maxq | mb | microblaze | mcore | mep | metag \ | mips | mipsbe | mipseb | mipsel | mipsle \ | mips16 \ | mips64 | mips64el \ | mips64octeon | mips64octeonel \ | mips64orion | mips64orionel \ | mips64r5900 | mips64r5900el \ | mips64vr | mips64vrel \ | mips64vr4100 | mips64vr4100el \ | mips64vr4300 | mips64vr4300el \ | mips64vr5000 | mips64vr5000el \ | mips64vr5900 | mips64vr5900el \ | mipsisa32 | mipsisa32el \ | mipsisa32r2 | mipsisa32r2el \ | mipsisa64 | mipsisa64el \ | mipsisa64r2 | mipsisa64r2el \ | mipsisa64sb1 | mipsisa64sb1el \ | mipsisa64sr71k | mipsisa64sr71kel \ | mipstx39 | mipstx39el \ | mn10200 | mn10300 \ | moxie \ | mt \ | msp430 \ | nios | nios2 \ | ns16k | ns32k \ | or32 \ | pdp10 | pdp11 | pj | pjl \ | powerpc | powerpc64 | powerpc64le | powerpcle | ppcbe \ | pyramid \ | score \ | sh | sh[1234] | sh[24]a | sh[24]aeb | sh[23]e | sh[34]eb | sheb | shbe | shle | sh[1234]le | sh3ele \ | sh64 | sh64le \ | sparc | sparc64 | sparc64b | sparc64v | sparc86x | sparclet | sparclite \ | sparcv8 | sparcv9 | sparcv9b | sparcv9v \ | spu | strongarm \ | tahoe | thumb | tic4x | tic80 | tron \ | v850 | v850e \ | we32k \ | x86 | xc16x | xscale | xscalee[bl] | xstormy16 | xtensa \ | z8k | z80) basic_machine=$basic_machine-unknown ;; m6811 | m68hc11 | m6812 | m68hc12) # Motorola 68HC11/12. basic_machine=$basic_machine-unknown os=-none ;; m88110 | m680[12346]0 | m683?2 | m68360 | m5200 | v70 | w65 | z8k) ;; ms1) basic_machine=mt-unknown ;; # We use `pc' rather than `unknown' # because (1) that's what they normally are, and # (2) the word "unknown" tends to confuse beginning users. i*86 | x86_64) basic_machine=$basic_machine-pc ;; # Object if more than one company name word. *-*-*) echo Invalid configuration \`$1\': machine \`$basic_machine\' not recognized 1>&2 exit 1 ;; # Recognize the basic CPU types with company name. 580-* \ | a29k-* \ | alpha-* | alphaev[4-8]-* | alphaev56-* | alphaev6[78]-* \ | alpha64-* | alpha64ev[4-8]-* | alpha64ev56-* | alpha64ev6[78]-* \ | alphapca5[67]-* | alpha64pca5[67]-* | arc-* \ | arm-* | armbe-* | armle-* | armeb-* | armv*-* \ | avr-* | avr32-* \ | bfin-* | bs2000-* \ | c[123]* | c30-* | [cjt]90-* | c4x-* | c54x-* | c55x-* | c6x-* \ | clipper-* | craynv-* | cydra-* \ | d10v-* | d30v-* | dlx-* \ | elxsi-* \ | f30[01]-* | f700-* | fido-* | fr30-* | frv-* | fx80-* \ | h8300-* | h8500-* \ | hppa-* | hppa1.[01]-* | hppa2.0-* | hppa2.0[nw]-* | hppa64-* \ | i*86-* | i860-* | i960-* | ia64-* \ | ip2k-* | iq2000-* \ | lm32-* \ | m32c-* | m32r-* | m32rle-* \ | m68000-* | m680[012346]0-* | m68360-* | m683?2-* | m68k-* \ | m88110-* | m88k-* | maxq-* | mcore-* | metag-* \ | mips-* | mipsbe-* | mipseb-* | mipsel-* | mipsle-* \ | mips16-* \ | mips64-* | mips64el-* \ | mips64octeon-* | mips64octeonel-* \ | mips64orion-* | mips64orionel-* \ | mips64r5900-* | mips64r5900el-* \ | mips64vr-* | mips64vrel-* \ | mips64vr4100-* | mips64vr4100el-* \ | mips64vr4300-* | mips64vr4300el-* \ | mips64vr5000-* | mips64vr5000el-* \ | mips64vr5900-* | mips64vr5900el-* \ | mipsisa32-* | mipsisa32el-* \ | mipsisa32r2-* | mipsisa32r2el-* \ | mipsisa64-* | mipsisa64el-* \ | mipsisa64r2-* | mipsisa64r2el-* \ | mipsisa64sb1-* | mipsisa64sb1el-* \ | mipsisa64sr71k-* | mipsisa64sr71kel-* \ | mipstx39-* | mipstx39el-* \ | mmix-* \ | mt-* \ | msp430-* \ | nios-* | nios2-* \ | none-* | np1-* | ns16k-* | ns32k-* \ | orion-* \ | pdp10-* | pdp11-* | pj-* | pjl-* | pn-* | power-* \ | powerpc-* | powerpc64-* | powerpc64le-* | powerpcle-* | ppcbe-* \ | pyramid-* \ | romp-* | rs6000-* \ | sh-* | sh[1234]-* | sh[24]a-* | sh[24]aeb-* | sh[23]e-* | sh[34]eb-* | sheb-* | shbe-* \ | shle-* | sh[1234]le-* | sh3ele-* | sh64-* | sh64le-* \ | sparc-* | sparc64-* | sparc64b-* | sparc64v-* | sparc86x-* | sparclet-* \ | sparclite-* \ | sparcv8-* | sparcv9-* | sparcv9b-* | sparcv9v-* | strongarm-* | sv1-* | sx?-* \ | tahoe-* | thumb-* \ | tic30-* | tic4x-* | tic54x-* | tic55x-* | tic6x-* | tic80-* | tile-* \ | tron-* \ | v850-* | v850e-* | vax-* \ | we32k-* \ | x86-* | x86_64-* | xc16x-* | xps100-* | xscale-* | xscalee[bl]-* \ | xstormy16-* | xtensa*-* \ | ymp-* \ | z8k-* | z80-*) ;; # Recognize the basic CPU types without company name, with glob match. xtensa*) basic_machine=$basic_machine-unknown ;; # Recognize the various machine names and aliases which stand # for a CPU type and a company and sometimes even an OS. 386bsd) basic_machine=i386-unknown os=-bsd ;; 3b1 | 7300 | 7300-att | att-7300 | pc7300 | safari | unixpc) basic_machine=m68000-att ;; 3b*) basic_machine=we32k-att ;; a29khif) basic_machine=a29k-amd os=-udi ;; abacus) basic_machine=abacus-unknown ;; adobe68k) basic_machine=m68010-adobe os=-scout ;; alliant | fx80) basic_machine=fx80-alliant ;; altos | altos3068) basic_machine=m68k-altos ;; am29k) basic_machine=a29k-none os=-bsd ;; amd64) basic_machine=x86_64-pc ;; amd64-*) basic_machine=x86_64-`echo $basic_machine | sed 's/^[^-]*-//'` ;; amdahl) basic_machine=580-amdahl os=-sysv ;; amiga | amiga-*) basic_machine=m68k-unknown ;; amigaos | amigados) basic_machine=m68k-unknown os=-amigaos ;; amigaunix | amix) basic_machine=m68k-unknown os=-sysv4 ;; apollo68) basic_machine=m68k-apollo os=-sysv ;; apollo68bsd) basic_machine=m68k-apollo os=-bsd ;; aros) basic_machine=i386-pc os=-aros ;; aux) basic_machine=m68k-apple os=-aux ;; balance) basic_machine=ns32k-sequent os=-dynix ;; blackfin) basic_machine=bfin-unknown os=-linux ;; blackfin-*) basic_machine=bfin-`echo $basic_machine | sed 's/^[^-]*-//'` os=-linux ;; c90) basic_machine=c90-cray os=-unicos ;; cegcc) basic_machine=arm-unknown os=-cegcc ;; convex-c1) basic_machine=c1-convex os=-bsd ;; convex-c2) basic_machine=c2-convex os=-bsd ;; convex-c32) basic_machine=c32-convex os=-bsd ;; convex-c34) basic_machine=c34-convex os=-bsd ;; convex-c38) basic_machine=c38-convex os=-bsd ;; cray | j90) basic_machine=j90-cray os=-unicos ;; craynv) basic_machine=craynv-cray os=-unicosmp ;; cr16) basic_machine=cr16-unknown os=-elf ;; crds | unos) basic_machine=m68k-crds ;; crisv32 | crisv32-* | etraxfs*) basic_machine=crisv32-axis ;; cris | cris-* | etrax*) basic_machine=cris-axis ;; crx) basic_machine=crx-unknown os=-elf ;; da30 | da30-*) basic_machine=m68k-da30 ;; decstation | decstation-3100 | pmax | pmax-* | pmin | dec3100 | decstatn) basic_machine=mips-dec ;; decsystem10* | dec10*) basic_machine=pdp10-dec os=-tops10 ;; decsystem20* | dec20*) basic_machine=pdp10-dec os=-tops20 ;; delta | 3300 | motorola-3300 | motorola-delta \ | 3300-motorola | delta-motorola) basic_machine=m68k-motorola ;; delta88) basic_machine=m88k-motorola os=-sysv3 ;; dicos) basic_machine=i686-pc os=-dicos ;; djgpp) basic_machine=i586-pc os=-msdosdjgpp ;; dpx20 | dpx20-*) basic_machine=rs6000-bull os=-bosx ;; dpx2* | dpx2*-bull) basic_machine=m68k-bull os=-sysv3 ;; ebmon29k) basic_machine=a29k-amd os=-ebmon ;; elxsi) basic_machine=elxsi-elxsi os=-bsd ;; encore | umax | mmax) basic_machine=ns32k-encore ;; es1800 | OSE68k | ose68k | ose | OSE) basic_machine=m68k-ericsson os=-ose ;; fx2800) basic_machine=i860-alliant ;; genix) basic_machine=ns32k-ns ;; gmicro) basic_machine=tron-gmicro os=-sysv ;; go32) basic_machine=i386-pc os=-go32 ;; h3050r* | hiux*) basic_machine=hppa1.1-hitachi os=-hiuxwe2 ;; h8300hms) basic_machine=h8300-hitachi os=-hms ;; h8300xray) basic_machine=h8300-hitachi os=-xray ;; h8500hms) basic_machine=h8500-hitachi os=-hms ;; harris) basic_machine=m88k-harris os=-sysv3 ;; hp300-*) basic_machine=m68k-hp ;; hp300bsd) basic_machine=m68k-hp os=-bsd ;; hp300hpux) basic_machine=m68k-hp os=-hpux ;; hp3k9[0-9][0-9] | hp9[0-9][0-9]) basic_machine=hppa1.0-hp ;; hp9k2[0-9][0-9] | hp9k31[0-9]) basic_machine=m68000-hp ;; hp9k3[2-9][0-9]) basic_machine=m68k-hp ;; hp9k6[0-9][0-9] | hp6[0-9][0-9]) basic_machine=hppa1.0-hp ;; hp9k7[0-79][0-9] | hp7[0-79][0-9]) basic_machine=hppa1.1-hp ;; hp9k78[0-9] | hp78[0-9]) # FIXME: really hppa2.0-hp basic_machine=hppa1.1-hp ;; hp9k8[67]1 | hp8[67]1 | hp9k80[24] | hp80[24] | hp9k8[78]9 | hp8[78]9 | hp9k893 | hp893) # FIXME: really hppa2.0-hp basic_machine=hppa1.1-hp ;; hp9k8[0-9][13679] | hp8[0-9][13679]) basic_machine=hppa1.1-hp ;; hp9k8[0-9][0-9] | hp8[0-9][0-9]) basic_machine=hppa1.0-hp ;; hppa-next) os=-nextstep3 ;; hppaosf) basic_machine=hppa1.1-hp os=-osf ;; hppro) basic_machine=hppa1.1-hp os=-proelf ;; i370-ibm* | ibm*) basic_machine=i370-ibm ;; # I'm not sure what "Sysv32" means. Should this be sysv3.2? i*86v32) basic_machine=`echo $1 | sed -e 's/86.*/86-pc/'` os=-sysv32 ;; i*86v4*) basic_machine=`echo $1 | sed -e 's/86.*/86-pc/'` os=-sysv4 ;; i*86v) basic_machine=`echo $1 | sed -e 's/86.*/86-pc/'` os=-sysv ;; i*86sol2) basic_machine=`echo $1 | sed -e 's/86.*/86-pc/'` os=-solaris2 ;; i386mach) basic_machine=i386-mach os=-mach ;; i386-vsta | vsta) basic_machine=i386-unknown os=-vsta ;; iris | iris4d) basic_machine=mips-sgi case $os in -irix*) ;; *) os=-irix4 ;; esac ;; isi68 | isi) basic_machine=m68k-isi os=-sysv ;; m68knommu) basic_machine=m68k-unknown os=-linux ;; m68knommu-*) basic_machine=m68k-`echo $basic_machine | sed 's/^[^-]*-//'` os=-linux ;; m88k-omron*) basic_machine=m88k-omron ;; magnum | m3230) basic_machine=mips-mips os=-sysv ;; merlin) basic_machine=ns32k-utek os=-sysv ;; mingw32) basic_machine=i386-pc os=-mingw32 ;; mingw32ce) basic_machine=arm-unknown os=-mingw32ce ;; miniframe) basic_machine=m68000-convergent ;; *mint | -mint[0-9]* | *MiNT | *MiNT[0-9]*) basic_machine=m68k-atari os=-mint ;; mips3*-*) basic_machine=`echo $basic_machine | sed -e 's/mips3/mips64/'` ;; mips3*) basic_machine=`echo $basic_machine | sed -e 's/mips3/mips64/'`-unknown ;; monitor) basic_machine=m68k-rom68k os=-coff ;; morphos) basic_machine=powerpc-unknown os=-morphos ;; msdos) basic_machine=i386-pc os=-msdos ;; ms1-*) basic_machine=`echo $basic_machine | sed -e 's/ms1-/mt-/'` ;; mvs) basic_machine=i370-ibm os=-mvs ;; ncr3000) basic_machine=i486-ncr os=-sysv4 ;; netbsd386) basic_machine=i386-unknown os=-netbsd ;; netwinder) basic_machine=armv4l-rebel os=-linux ;; news | news700 | news800 | news900) basic_machine=m68k-sony os=-newsos ;; news1000) basic_machine=m68030-sony os=-newsos ;; news-3600 | risc-news) basic_machine=mips-sony os=-newsos ;; necv70) basic_machine=v70-nec os=-sysv ;; next | m*-next ) basic_machine=m68k-next case $os in -nextstep* ) ;; -ns2*) os=-nextstep2 ;; *) os=-nextstep3 ;; esac ;; nh3000) basic_machine=m68k-harris os=-cxux ;; nh[45]000) basic_machine=m88k-harris os=-cxux ;; nindy960) basic_machine=i960-intel os=-nindy ;; mon960) basic_machine=i960-intel os=-mon960 ;; nonstopux) basic_machine=mips-compaq os=-nonstopux ;; np1) basic_machine=np1-gould ;; nsr-tandem) basic_machine=nsr-tandem ;; op50n-* | op60c-*) basic_machine=hppa1.1-oki os=-proelf ;; openrisc | openrisc-*) basic_machine=or32-unknown ;; os400) basic_machine=powerpc-ibm os=-os400 ;; OSE68000 | ose68000) basic_machine=m68000-ericsson os=-ose ;; os68k) basic_machine=m68k-none os=-os68k ;; pa-hitachi) basic_machine=hppa1.1-hitachi os=-hiuxwe2 ;; paragon) basic_machine=i860-intel os=-osf ;; parisc) basic_machine=hppa-unknown os=-linux ;; parisc-*) basic_machine=hppa-`echo $basic_machine | sed 's/^[^-]*-//'` os=-linux ;; pbd) basic_machine=sparc-tti ;; pbb) basic_machine=m68k-tti ;; pc532 | pc532-*) basic_machine=ns32k-pc532 ;; pc98) basic_machine=i386-pc ;; pc98-*) basic_machine=i386-`echo $basic_machine | sed 's/^[^-]*-//'` ;; pentium | p5 | k5 | k6 | nexgen | viac3) basic_machine=i586-pc ;; pentiumpro | p6 | 6x86 | athlon | athlon_*) basic_machine=i686-pc ;; pentiumii | pentium2 | pentiumiii | pentium3) basic_machine=i686-pc ;; pentium4) basic_machine=i786-pc ;; pentium-* | p5-* | k5-* | k6-* | nexgen-* | viac3-*) basic_machine=i586-`echo $basic_machine | sed 's/^[^-]*-//'` ;; pentiumpro-* | p6-* | 6x86-* | athlon-*) basic_machine=i686-`echo $basic_machine | sed 's/^[^-]*-//'` ;; pentiumii-* | pentium2-* | pentiumiii-* | pentium3-*) basic_machine=i686-`echo $basic_machine | sed 's/^[^-]*-//'` ;; pentium4-*) basic_machine=i786-`echo $basic_machine | sed 's/^[^-]*-//'` ;; pn) basic_machine=pn-gould ;; power) basic_machine=power-ibm ;; ppc) basic_machine=powerpc-unknown ;; ppc-*) basic_machine=powerpc-`echo $basic_machine | sed 's/^[^-]*-//'` ;; ppcle | powerpclittle | ppc-le | powerpc-little) basic_machine=powerpcle-unknown ;; ppcle-* | powerpclittle-*) basic_machine=powerpcle-`echo $basic_machine | sed 's/^[^-]*-//'` ;; ppc64) basic_machine=powerpc64-unknown ;; ppc64-*) basic_machine=powerpc64-`echo $basic_machine | sed 's/^[^-]*-//'` ;; ppc64le | powerpc64little | ppc64-le | powerpc64-little) basic_machine=powerpc64le-unknown ;; ppc64le-* | powerpc64little-*) basic_machine=powerpc64le-`echo $basic_machine | sed 's/^[^-]*-//'` ;; ps2) basic_machine=i386-ibm ;; pw32) basic_machine=i586-unknown os=-pw32 ;; rdos) basic_machine=i386-pc os=-rdos ;; rom68k) basic_machine=m68k-rom68k os=-coff ;; rm[46]00) basic_machine=mips-siemens ;; rtpc | rtpc-*) basic_machine=romp-ibm ;; s390 | s390-*) basic_machine=s390-ibm ;; s390x | s390x-*) basic_machine=s390x-ibm ;; sa29200) basic_machine=a29k-amd os=-udi ;; sb1) basic_machine=mipsisa64sb1-unknown ;; sb1el) basic_machine=mipsisa64sb1el-unknown ;; sde) basic_machine=mipsisa32-sde os=-elf ;; sei) basic_machine=mips-sei os=-seiux ;; sequent) basic_machine=i386-sequent ;; sh) basic_machine=sh-hitachi os=-hms ;; sh5el) basic_machine=sh5le-unknown ;; sh64) basic_machine=sh64-unknown ;; sparclite-wrs | simso-wrs) basic_machine=sparclite-wrs os=-vxworks ;; sps7) basic_machine=m68k-bull os=-sysv2 ;; spur) basic_machine=spur-unknown ;; st2000) basic_machine=m68k-tandem ;; stratus) basic_machine=i860-stratus os=-sysv4 ;; sun2) basic_machine=m68000-sun ;; sun2os3) basic_machine=m68000-sun os=-sunos3 ;; sun2os4) basic_machine=m68000-sun os=-sunos4 ;; sun3os3) basic_machine=m68k-sun os=-sunos3 ;; sun3os4) basic_machine=m68k-sun os=-sunos4 ;; sun4os3) basic_machine=sparc-sun os=-sunos3 ;; sun4os4) basic_machine=sparc-sun os=-sunos4 ;; sun4sol2) basic_machine=sparc-sun os=-solaris2 ;; sun3 | sun3-*) basic_machine=m68k-sun ;; sun4) basic_machine=sparc-sun ;; sun386 | sun386i | roadrunner) basic_machine=i386-sun ;; sv1) basic_machine=sv1-cray os=-unicos ;; symmetry) basic_machine=i386-sequent os=-dynix ;; t3e) basic_machine=alphaev5-cray os=-unicos ;; t90) basic_machine=t90-cray os=-unicos ;; tic54x | c54x*) basic_machine=tic54x-unknown os=-coff ;; tic55x | c55x*) basic_machine=tic55x-unknown os=-coff ;; tic6x | c6x*) basic_machine=tic6x-unknown os=-coff ;; tile*) basic_machine=tile-unknown os=-linux-gnu ;; tx39) basic_machine=mipstx39-unknown ;; tx39el) basic_machine=mipstx39el-unknown ;; toad1) basic_machine=pdp10-xkl os=-tops20 ;; tower | tower-32) basic_machine=m68k-ncr ;; tpf) basic_machine=s390x-ibm os=-tpf ;; udi29k) basic_machine=a29k-amd os=-udi ;; ultra3) basic_machine=a29k-nyu os=-sym1 ;; v810 | necv810) basic_machine=v810-nec os=-none ;; vaxv) basic_machine=vax-dec os=-sysv ;; vms) basic_machine=vax-dec os=-vms ;; vpp*|vx|vx-*) basic_machine=f301-fujitsu ;; vxworks960) basic_machine=i960-wrs os=-vxworks ;; vxworks68) basic_machine=m68k-wrs os=-vxworks ;; vxworks29k) basic_machine=a29k-wrs os=-vxworks ;; w65*) basic_machine=w65-wdc os=-none ;; w89k-*) basic_machine=hppa1.1-winbond os=-proelf ;; xbox) basic_machine=i686-pc os=-mingw32 ;; xps | xps100) basic_machine=xps100-honeywell ;; ymp) basic_machine=ymp-cray os=-unicos ;; z8k-*-coff) basic_machine=z8k-unknown os=-sim ;; z80-*-coff) basic_machine=z80-unknown os=-sim ;; none) basic_machine=none-none os=-none ;; # Here we handle the default manufacturer of certain CPU types. It is in # some cases the only manufacturer, in others, it is the most popular. w89k) basic_machine=hppa1.1-winbond ;; op50n) basic_machine=hppa1.1-oki ;; op60c) basic_machine=hppa1.1-oki ;; romp) basic_machine=romp-ibm ;; mmix) basic_machine=mmix-knuth ;; rs6000) basic_machine=rs6000-ibm ;; vax) basic_machine=vax-dec ;; pdp10) # there are many clones, so DEC is not a safe bet basic_machine=pdp10-unknown ;; pdp11) basic_machine=pdp11-dec ;; we32k) basic_machine=we32k-att ;; sh[1234] | sh[24]a | sh[24]aeb | sh[34]eb | sh[1234]le | sh[23]ele) basic_machine=sh-unknown ;; sparc | sparcv8 | sparcv9 | sparcv9b | sparcv9v) basic_machine=sparc-sun ;; cydra) basic_machine=cydra-cydrome ;; orion) basic_machine=orion-highlevel ;; orion105) basic_machine=clipper-highlevel ;; mac | mpw | mac-mpw) basic_machine=m68k-apple ;; pmac | pmac-mpw) basic_machine=powerpc-apple ;; *-unknown) # Make sure to match an already-canonicalized machine name. ;; *) echo Invalid configuration \`$1\': machine \`$basic_machine\' not recognized 1>&2 exit 1 ;; esac # Here we canonicalize certain aliases for manufacturers. case $basic_machine in *-digital*) basic_machine=`echo $basic_machine | sed 's/digital.*/dec/'` ;; *-commodore*) basic_machine=`echo $basic_machine | sed 's/commodore.*/cbm/'` ;; *) ;; esac # Decode manufacturer-specific aliases for certain operating systems. if [ x"$os" != x"" ] then case $os in # First match some system type aliases # that might get confused with valid system types. # -solaris* is a basic system type, with this one exception. -solaris1 | -solaris1.*) os=`echo $os | sed -e 's|solaris1|sunos4|'` ;; -solaris) os=-solaris2 ;; -svr4*) os=-sysv4 ;; -unixware*) os=-sysv4.2uw ;; -gnu/linux*) os=`echo $os | sed -e 's|gnu/linux|linux-gnu|'` ;; # First accept the basic system types. # The portable systems comes first. # Each alternative MUST END IN A *, to match a version number. # -sysv* is not here because it comes later, after sysvr4. -gnu* | -bsd* | -mach* | -minix* | -genix* | -ultrix* | -irix* \ | -*vms* | -sco* | -esix* | -isc* | -aix* | -sunos | -sunos[34]*\ | -hpux* | -unos* | -osf* | -luna* | -dgux* | -solaris* | -sym* \ | -kopensolaris* \ | -amigaos* | -amigados* | -msdos* | -newsos* | -unicos* | -aof* \ | -aos* | -aros* \ | -nindy* | -vxsim* | -vxworks* | -ebmon* | -hms* | -mvs* \ | -clix* | -riscos* | -uniplus* | -iris* | -rtu* | -xenix* \ | -hiux* | -386bsd* | -knetbsd* | -mirbsd* | -netbsd* \ | -openbsd* | -solidbsd* \ | -ekkobsd* | -kfreebsd* | -freebsd* | -riscix* | -lynxos* \ | -bosx* | -nextstep* | -cxux* | -aout* | -elf* | -oabi* \ | -ptx* | -coff* | -ecoff* | -winnt* | -domain* | -vsta* \ | -udi* | -eabi* | -lites* | -ieee* | -go32* | -aux* \ | -chorusos* | -chorusrdb* | -cegcc* \ | -cygwin* | -pe* | -psos* | -moss* | -proelf* | -rtems* \ | -mingw32* | -linux-gnu* | -linux-newlib* | -linux-uclibc* \ | -uxpv* | -beos* | -mpeix* | -udk* \ | -interix* | -uwin* | -mks* | -rhapsody* | -darwin* | -opened* \ | -openstep* | -oskit* | -conix* | -pw32* | -nonstopux* \ | -storm-chaos* | -tops10* | -tenex* | -tops20* | -its* \ | -os2* | -vos* | -palmos* | -uclinux* | -nucleus* \ | -morphos* | -superux* | -rtmk* | -rtmk-nova* | -windiss* \ | -powermax* | -dnix* | -nx6 | -nx7 | -sei* | -dragonfly* \ | -skyos* | -haiku* | -rdos* | -toppers* | -drops*) # Remember, each alternative MUST END IN *, to match a version number. ;; -qnx*) case $basic_machine in x86-* | i*86-*) ;; *) os=-nto$os ;; esac ;; -nto-qnx*) ;; -nto*) os=`echo $os | sed -e 's|nto|nto-qnx|'` ;; -sim | -es1800* | -hms* | -xray | -os68k* | -none* | -v88r* \ | -windows* | -osx | -abug | -netware* | -os9* | -beos* | -haiku* \ | -macos* | -mpw* | -magic* | -mmixware* | -mon960* | -lnews*) ;; -mac*) os=`echo $os | sed -e 's|mac|macos|'` ;; -linux-dietlibc) os=-linux-dietlibc ;; -linux*) os=`echo $os | sed -e 's|linux|linux-gnu|'` ;; -sunos5*) os=`echo $os | sed -e 's|sunos5|solaris2|'` ;; -sunos6*) os=`echo $os | sed -e 's|sunos6|solaris3|'` ;; -opened*) os=-openedition ;; -os400*) os=-os400 ;; -wince*) os=-wince ;; -osfrose*) os=-osfrose ;; -osf*) os=-osf ;; -utek*) os=-bsd ;; -dynix*) os=-bsd ;; -acis*) os=-aos ;; -atheos*) os=-atheos ;; -syllable*) os=-syllable ;; -386bsd) os=-bsd ;; -ctix* | -uts*) os=-sysv ;; -nova*) os=-rtmk-nova ;; -ns2 ) os=-nextstep2 ;; -nsk*) os=-nsk ;; # Preserve the version number of sinix5. -sinix5.*) os=`echo $os | sed -e 's|sinix|sysv|'` ;; -sinix*) os=-sysv4 ;; -tpf*) os=-tpf ;; -triton*) os=-sysv3 ;; -oss*) os=-sysv3 ;; -svr4) os=-sysv4 ;; -svr3) os=-sysv3 ;; -sysvr4) os=-sysv4 ;; # This must come after -sysvr4. -sysv*) ;; -ose*) os=-ose ;; -es1800*) os=-ose ;; -xenix) os=-xenix ;; -*mint | -mint[0-9]* | -*MiNT | -MiNT[0-9]*) os=-mint ;; -aros*) os=-aros ;; -kaos*) os=-kaos ;; -zvmoe) os=-zvmoe ;; -dicos*) os=-dicos ;; -none) ;; *) # Get rid of the `-' at the beginning of $os. os=`echo $os | sed 's/[^-]*-//'` echo Invalid configuration \`$1\': system \`$os\' not recognized 1>&2 exit 1 ;; esac else # Here we handle the default operating systems that come with various machines. # The value should be what the vendor currently ships out the door with their # machine or put another way, the most popular os provided with the machine. # Note that if you're going to try to match "-MANUFACTURER" here (say, # "-sun"), then you have to tell the case statement up towards the top # that MANUFACTURER isn't an operating system. Otherwise, code above # will signal an error saying that MANUFACTURER isn't an operating # system, and we'll never get to this point. case $basic_machine in score-*) os=-elf ;; spu-*) os=-elf ;; *-acorn) os=-riscix1.2 ;; arm*-rebel) os=-linux ;; arm*-semi) os=-aout ;; c4x-* | tic4x-*) os=-coff ;; # This must come before the *-dec entry. pdp10-*) os=-tops20 ;; pdp11-*) os=-none ;; *-dec | vax-*) os=-ultrix4.2 ;; m68*-apollo) os=-domain ;; i386-sun) os=-sunos4.0.2 ;; m68000-sun) os=-sunos3 # This also exists in the configure program, but was not the # default. # os=-sunos4 ;; m68*-cisco) os=-aout ;; mep-*) os=-elf ;; mips*-cisco) os=-elf ;; mips*-*) os=-elf ;; or32-*) os=-coff ;; *-tti) # must be before sparc entry or we get the wrong os. os=-sysv3 ;; sparc-* | *-sun) os=-sunos4.1.1 ;; *-be) os=-beos ;; *-haiku) os=-haiku ;; *-ibm) os=-aix ;; *-knuth) os=-mmixware ;; *-wec) os=-proelf ;; *-winbond) os=-proelf ;; *-oki) os=-proelf ;; *-hp) os=-hpux ;; *-hitachi) os=-hiux ;; i860-* | *-att | *-ncr | *-altos | *-motorola | *-convergent) os=-sysv ;; *-cbm) os=-amigaos ;; *-dg) os=-dgux ;; *-dolphin) os=-sysv3 ;; m68k-ccur) os=-rtu ;; m88k-omron*) os=-luna ;; *-next ) os=-nextstep ;; *-sequent) os=-ptx ;; *-crds) os=-unos ;; *-ns) os=-genix ;; i370-*) os=-mvs ;; *-next) os=-nextstep3 ;; *-gould) os=-sysv ;; *-highlevel) os=-bsd ;; *-encore) os=-bsd ;; *-sgi) os=-irix ;; *-siemens) os=-sysv4 ;; *-masscomp) os=-rtu ;; f30[01]-fujitsu | f700-fujitsu) os=-uxpv ;; *-rom68k) os=-coff ;; *-*bug) os=-coff ;; *-apple) os=-macos ;; *-atari*) os=-mint ;; *) os=-none ;; esac fi # Here we handle the case where we know the os, and the CPU type, but not the # manufacturer. We pick the logical manufacturer. vendor=unknown case $basic_machine in *-unknown) case $os in -riscix*) vendor=acorn ;; -sunos*) vendor=sun ;; -aix*) vendor=ibm ;; -beos*) vendor=be ;; -hpux*) vendor=hp ;; -mpeix*) vendor=hp ;; -hiux*) vendor=hitachi ;; -unos*) vendor=crds ;; -dgux*) vendor=dg ;; -luna*) vendor=omron ;; -genix*) vendor=ns ;; -mvs* | -opened*) vendor=ibm ;; -os400*) vendor=ibm ;; -ptx*) vendor=sequent ;; -tpf*) vendor=ibm ;; -vxsim* | -vxworks* | -windiss*) vendor=wrs ;; -aux*) vendor=apple ;; -hms*) vendor=hitachi ;; -mpw* | -macos*) vendor=apple ;; -*mint | -mint[0-9]* | -*MiNT | -MiNT[0-9]*) vendor=atari ;; -vos*) vendor=stratus ;; esac basic_machine=`echo $basic_machine | sed "s/unknown/$vendor/"` ;; esac echo $basic_machine$os exit # Local variables: # eval: (add-hook 'write-file-hooks 'time-stamp) # time-stamp-start: "timestamp='" # time-stamp-format: "%:y-%02m-%02d" # time-stamp-end: "'" # End: openchange-2.0/configure000077500000000000000000011227401223057412600154020ustar00rootroot00000000000000#! /bin/sh # Guess values for system-dependent variables and create Makefiles. # Generated by GNU Autoconf 2.69 for openchange 2.0. # # Report bugs to . # # # Copyright (C) 1992-1996, 1998-2012 Free Software Foundation, Inc. # # # This configure script is free software; the Free Software Foundation # gives unlimited permission to copy, distribute and modify it. ## -------------------- ## ## M4sh Initialization. ## ## -------------------- ## # Be more Bourne compatible DUALCASE=1; export DUALCASE # for MKS sh if test -n "${ZSH_VERSION+set}" && (emulate sh) >/dev/null 2>&1; then : emulate sh NULLCMD=: # Pre-4.2 versions of Zsh do word splitting on ${1+"$@"}, which # is contrary to our usage. Disable this feature. alias -g '${1+"$@"}'='"$@"' setopt NO_GLOB_SUBST else case `(set -o) 2>/dev/null` in #( *posix*) : set -o posix ;; #( *) : ;; esac fi as_nl=' ' export as_nl # Printing a long string crashes Solaris 7 /usr/bin/printf. as_echo='\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\' as_echo=$as_echo$as_echo$as_echo$as_echo$as_echo as_echo=$as_echo$as_echo$as_echo$as_echo$as_echo$as_echo # Prefer a ksh shell builtin over an external printf program on Solaris, # but without wasting forks for bash or zsh. if test -z "$BASH_VERSION$ZSH_VERSION" \ && (test "X`print -r -- $as_echo`" = "X$as_echo") 2>/dev/null; then as_echo='print -r --' as_echo_n='print -rn --' elif (test "X`printf %s $as_echo`" = "X$as_echo") 2>/dev/null; then as_echo='printf %s\n' as_echo_n='printf %s' else if test "X`(/usr/ucb/echo -n -n $as_echo) 2>/dev/null`" = "X-n $as_echo"; then as_echo_body='eval /usr/ucb/echo -n "$1$as_nl"' as_echo_n='/usr/ucb/echo -n' else as_echo_body='eval expr "X$1" : "X\\(.*\\)"' as_echo_n_body='eval arg=$1; case $arg in #( *"$as_nl"*) expr "X$arg" : "X\\(.*\\)$as_nl"; arg=`expr "X$arg" : ".*$as_nl\\(.*\\)"`;; esac; expr "X$arg" : "X\\(.*\\)" | tr -d "$as_nl" ' export as_echo_n_body as_echo_n='sh -c $as_echo_n_body as_echo' fi export as_echo_body as_echo='sh -c $as_echo_body as_echo' fi # The user is always right. if test "${PATH_SEPARATOR+set}" != set; then PATH_SEPARATOR=: (PATH='/bin;/bin'; FPATH=$PATH; sh -c :) >/dev/null 2>&1 && { (PATH='/bin:/bin'; FPATH=$PATH; sh -c :) >/dev/null 2>&1 || PATH_SEPARATOR=';' } fi # IFS # We need space, tab and new line, in precisely that order. Quoting is # there to prevent editors from complaining about space-tab. # (If _AS_PATH_WALK were called with IFS unset, it would disable word # splitting by setting IFS to empty value.) IFS=" "" $as_nl" # Find who we are. Look in the path if we contain no directory separator. as_myself= case $0 in #(( *[\\/]* ) as_myself=$0 ;; *) as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. test -r "$as_dir/$0" && as_myself=$as_dir/$0 && break done IFS=$as_save_IFS ;; esac # We did not find ourselves, most probably we were run as `sh COMMAND' # in which case we are not to be found in the path. if test "x$as_myself" = x; then as_myself=$0 fi if test ! -f "$as_myself"; then $as_echo "$as_myself: error: cannot find myself; rerun with an absolute file name" >&2 exit 1 fi # Unset variables that we do not need and which cause bugs (e.g. in # pre-3.0 UWIN ksh). But do not cause bugs in bash 2.01; the "|| exit 1" # suppresses any "Segmentation fault" message there. '((' could # trigger a bug in pdksh 5.2.14. for as_var in BASH_ENV ENV MAIL MAILPATH do eval test x\${$as_var+set} = xset \ && ( (unset $as_var) || exit 1) >/dev/null 2>&1 && unset $as_var || : done PS1='$ ' PS2='> ' PS4='+ ' # NLS nuisances. LC_ALL=C export LC_ALL LANGUAGE=C export LANGUAGE # CDPATH. (unset CDPATH) >/dev/null 2>&1 && unset CDPATH # Use a proper internal environment variable to ensure we don't fall # into an infinite loop, continuously re-executing ourselves. if test x"${_as_can_reexec}" != xno && test "x$CONFIG_SHELL" != x; then _as_can_reexec=no; export _as_can_reexec; # We cannot yet assume a decent shell, so we have to provide a # neutralization value for shells without unset; and this also # works around shells that cannot unset nonexistent variables. # Preserve -v and -x to the replacement shell. BASH_ENV=/dev/null ENV=/dev/null (unset BASH_ENV) >/dev/null 2>&1 && unset BASH_ENV ENV case $- in # (((( *v*x* | *x*v* ) as_opts=-vx ;; *v* ) as_opts=-v ;; *x* ) as_opts=-x ;; * ) as_opts= ;; esac exec $CONFIG_SHELL $as_opts "$as_myself" ${1+"$@"} # Admittedly, this is quite paranoid, since all the known shells bail # out after a failed `exec'. $as_echo "$0: could not re-execute with $CONFIG_SHELL" >&2 as_fn_exit 255 fi # We don't want this to propagate to other subprocesses. { _as_can_reexec=; unset _as_can_reexec;} if test "x$CONFIG_SHELL" = x; then as_bourne_compatible="if test -n \"\${ZSH_VERSION+set}\" && (emulate sh) >/dev/null 2>&1; then : emulate sh NULLCMD=: # Pre-4.2 versions of Zsh do word splitting on \${1+\"\$@\"}, which # is contrary to our usage. Disable this feature. alias -g '\${1+\"\$@\"}'='\"\$@\"' setopt NO_GLOB_SUBST else case \`(set -o) 2>/dev/null\` in #( *posix*) : set -o posix ;; #( *) : ;; esac fi " as_required="as_fn_return () { (exit \$1); } as_fn_success () { as_fn_return 0; } as_fn_failure () { as_fn_return 1; } as_fn_ret_success () { return 0; } as_fn_ret_failure () { return 1; } exitcode=0 as_fn_success || { exitcode=1; echo as_fn_success failed.; } as_fn_failure && { exitcode=1; echo as_fn_failure succeeded.; } as_fn_ret_success || { exitcode=1; echo as_fn_ret_success failed.; } as_fn_ret_failure && { exitcode=1; echo as_fn_ret_failure succeeded.; } if ( set x; as_fn_ret_success y && test x = \"\$1\" ); then : else exitcode=1; echo positional parameters were not saved. fi test x\$exitcode = x0 || exit 1 test -x / || exit 1" as_suggested=" as_lineno_1=";as_suggested=$as_suggested$LINENO;as_suggested=$as_suggested" as_lineno_1a=\$LINENO as_lineno_2=";as_suggested=$as_suggested$LINENO;as_suggested=$as_suggested" as_lineno_2a=\$LINENO eval 'test \"x\$as_lineno_1'\$as_run'\" != \"x\$as_lineno_2'\$as_run'\" && test \"x\`expr \$as_lineno_1'\$as_run' + 1\`\" = \"x\$as_lineno_2'\$as_run'\"' || exit 1 test \$(( 1 + 1 )) = 2 || exit 1" if (eval "$as_required") 2>/dev/null; then : as_have_required=yes else as_have_required=no fi if test x$as_have_required = xyes && (eval "$as_suggested") 2>/dev/null; then : else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR as_found=false for as_dir in /bin$PATH_SEPARATOR/usr/bin$PATH_SEPARATOR$PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. as_found=: case $as_dir in #( /*) for as_base in sh bash ksh sh5; do # Try only shells that exist, to save several forks. as_shell=$as_dir/$as_base if { test -f "$as_shell" || test -f "$as_shell.exe"; } && { $as_echo "$as_bourne_compatible""$as_required" | as_run=a "$as_shell"; } 2>/dev/null; then : CONFIG_SHELL=$as_shell as_have_required=yes if { $as_echo "$as_bourne_compatible""$as_suggested" | as_run=a "$as_shell"; } 2>/dev/null; then : break 2 fi fi done;; esac as_found=false done $as_found || { if { test -f "$SHELL" || test -f "$SHELL.exe"; } && { $as_echo "$as_bourne_compatible""$as_required" | as_run=a "$SHELL"; } 2>/dev/null; then : CONFIG_SHELL=$SHELL as_have_required=yes fi; } IFS=$as_save_IFS if test "x$CONFIG_SHELL" != x; then : export CONFIG_SHELL # We cannot yet assume a decent shell, so we have to provide a # neutralization value for shells without unset; and this also # works around shells that cannot unset nonexistent variables. # Preserve -v and -x to the replacement shell. BASH_ENV=/dev/null ENV=/dev/null (unset BASH_ENV) >/dev/null 2>&1 && unset BASH_ENV ENV case $- in # (((( *v*x* | *x*v* ) as_opts=-vx ;; *v* ) as_opts=-v ;; *x* ) as_opts=-x ;; * ) as_opts= ;; esac exec $CONFIG_SHELL $as_opts "$as_myself" ${1+"$@"} # Admittedly, this is quite paranoid, since all the known shells bail # out after a failed `exec'. $as_echo "$0: could not re-execute with $CONFIG_SHELL" >&2 exit 255 fi if test x$as_have_required = xno; then : $as_echo "$0: This script requires a shell more modern than all" $as_echo "$0: the shells that I found on your system." if test x${ZSH_VERSION+set} = xset ; then $as_echo "$0: In particular, zsh $ZSH_VERSION has bugs and should" $as_echo "$0: be upgraded to zsh 4.3.4 or later." else $as_echo "$0: Please tell bug-autoconf@gnu.org and $0: openchange@openchange.org about your system, including $0: any error possibly output before this message. Then $0: install a modern shell, or manually run the script $0: under such a shell if you do have one." fi exit 1 fi fi fi SHELL=${CONFIG_SHELL-/bin/sh} export SHELL # Unset more variables known to interfere with behavior of common tools. CLICOLOR_FORCE= GREP_OPTIONS= unset CLICOLOR_FORCE GREP_OPTIONS ## --------------------- ## ## M4sh Shell Functions. ## ## --------------------- ## # as_fn_unset VAR # --------------- # Portably unset VAR. as_fn_unset () { { eval $1=; unset $1;} } as_unset=as_fn_unset # as_fn_set_status STATUS # ----------------------- # Set $? to STATUS, without forking. as_fn_set_status () { return $1 } # as_fn_set_status # as_fn_exit STATUS # ----------------- # Exit the shell with STATUS, even in a "trap 0" or "set -e" context. as_fn_exit () { set +e as_fn_set_status $1 exit $1 } # as_fn_exit # as_fn_mkdir_p # ------------- # Create "$as_dir" as a directory, including parents if necessary. as_fn_mkdir_p () { case $as_dir in #( -*) as_dir=./$as_dir;; esac test -d "$as_dir" || eval $as_mkdir_p || { as_dirs= while :; do case $as_dir in #( *\'*) as_qdir=`$as_echo "$as_dir" | sed "s/'/'\\\\\\\\''/g"`;; #'( *) as_qdir=$as_dir;; esac as_dirs="'$as_qdir' $as_dirs" as_dir=`$as_dirname -- "$as_dir" || $as_expr X"$as_dir" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \ X"$as_dir" : 'X\(//\)[^/]' \| \ X"$as_dir" : 'X\(//\)$' \| \ X"$as_dir" : 'X\(/\)' \| . 2>/dev/null || $as_echo X"$as_dir" | sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ s//\1/ q } /^X\(\/\/\)[^/].*/{ s//\1/ q } /^X\(\/\/\)$/{ s//\1/ q } /^X\(\/\).*/{ s//\1/ q } s/.*/./; q'` test -d "$as_dir" && break done test -z "$as_dirs" || eval "mkdir $as_dirs" } || test -d "$as_dir" || as_fn_error $? "cannot create directory $as_dir" } # as_fn_mkdir_p # as_fn_executable_p FILE # ----------------------- # Test if FILE is an executable regular file. as_fn_executable_p () { test -f "$1" && test -x "$1" } # as_fn_executable_p # as_fn_append VAR VALUE # ---------------------- # Append the text in VALUE to the end of the definition contained in VAR. Take # advantage of any shell optimizations that allow amortized linear growth over # repeated appends, instead of the typical quadratic growth present in naive # implementations. if (eval "as_var=1; as_var+=2; test x\$as_var = x12") 2>/dev/null; then : eval 'as_fn_append () { eval $1+=\$2 }' else as_fn_append () { eval $1=\$$1\$2 } fi # as_fn_append # as_fn_arith ARG... # ------------------ # Perform arithmetic evaluation on the ARGs, and store the result in the # global $as_val. Take advantage of shells that can avoid forks. The arguments # must be portable across $(()) and expr. if (eval "test \$(( 1 + 1 )) = 2") 2>/dev/null; then : eval 'as_fn_arith () { as_val=$(( $* )) }' else as_fn_arith () { as_val=`expr "$@" || test $? -eq 1` } fi # as_fn_arith # as_fn_error STATUS ERROR [LINENO LOG_FD] # ---------------------------------------- # Output "`basename $0`: error: ERROR" to stderr. If LINENO and LOG_FD are # provided, also output the error to LOG_FD, referencing LINENO. Then exit the # script with STATUS, using 1 if that was 0. as_fn_error () { as_status=$1; test $as_status -eq 0 && as_status=1 if test "$4"; then as_lineno=${as_lineno-"$3"} as_lineno_stack=as_lineno_stack=$as_lineno_stack $as_echo "$as_me:${as_lineno-$LINENO}: error: $2" >&$4 fi $as_echo "$as_me: error: $2" >&2 as_fn_exit $as_status } # as_fn_error if expr a : '\(a\)' >/dev/null 2>&1 && test "X`expr 00001 : '.*\(...\)'`" = X001; then as_expr=expr else as_expr=false fi if (basename -- /) >/dev/null 2>&1 && test "X`basename -- / 2>&1`" = "X/"; then as_basename=basename else as_basename=false fi if (as_dir=`dirname -- /` && test "X$as_dir" = X/) >/dev/null 2>&1; then as_dirname=dirname else as_dirname=false fi as_me=`$as_basename -- "$0" || $as_expr X/"$0" : '.*/\([^/][^/]*\)/*$' \| \ X"$0" : 'X\(//\)$' \| \ X"$0" : 'X\(/\)' \| . 2>/dev/null || $as_echo X/"$0" | sed '/^.*\/\([^/][^/]*\)\/*$/{ s//\1/ q } /^X\/\(\/\/\)$/{ s//\1/ q } /^X\/\(\/\).*/{ s//\1/ q } s/.*/./; q'` # Avoid depending upon Character Ranges. as_cr_letters='abcdefghijklmnopqrstuvwxyz' as_cr_LETTERS='ABCDEFGHIJKLMNOPQRSTUVWXYZ' as_cr_Letters=$as_cr_letters$as_cr_LETTERS as_cr_digits='0123456789' as_cr_alnum=$as_cr_Letters$as_cr_digits as_lineno_1=$LINENO as_lineno_1a=$LINENO as_lineno_2=$LINENO as_lineno_2a=$LINENO eval 'test "x$as_lineno_1'$as_run'" != "x$as_lineno_2'$as_run'" && test "x`expr $as_lineno_1'$as_run' + 1`" = "x$as_lineno_2'$as_run'"' || { # Blame Lee E. McMahon (1931-1989) for sed's syntax. :-) sed -n ' p /[$]LINENO/= ' <$as_myself | sed ' s/[$]LINENO.*/&-/ t lineno b :lineno N :loop s/[$]LINENO\([^'$as_cr_alnum'_].*\n\)\(.*\)/\2\1\2/ t loop s/-\n.*// ' >$as_me.lineno && chmod +x "$as_me.lineno" || { $as_echo "$as_me: error: cannot create $as_me.lineno; rerun with a POSIX shell" >&2; as_fn_exit 1; } # If we had to re-execute with $CONFIG_SHELL, we're ensured to have # already done that, so ensure we don't try to do so again and fall # in an infinite loop. This has already happened in practice. _as_can_reexec=no; export _as_can_reexec # Don't try to exec as it changes $[0], causing all sort of problems # (the dirname of $[0] is not the place where we might find the # original and so on. Autoconf is especially sensitive to this). . "./$as_me.lineno" # Exit status is that of the last command. exit } ECHO_C= ECHO_N= ECHO_T= case `echo -n x` in #((((( -n*) case `echo 'xy\c'` in *c*) ECHO_T=' ';; # ECHO_T is single tab character. xy) ECHO_C='\c';; *) echo `echo ksh88 bug on AIX 6.1` > /dev/null ECHO_T=' ';; esac;; *) ECHO_N='-n';; esac rm -f conf$$ conf$$.exe conf$$.file if test -d conf$$.dir; then rm -f conf$$.dir/conf$$.file else rm -f conf$$.dir mkdir conf$$.dir 2>/dev/null fi if (echo >conf$$.file) 2>/dev/null; then if ln -s conf$$.file conf$$ 2>/dev/null; then as_ln_s='ln -s' # ... but there are two gotchas: # 1) On MSYS, both `ln -s file dir' and `ln file dir' fail. # 2) DJGPP < 2.04 has no symlinks; `ln -s' creates a wrapper executable. # In both cases, we have to default to `cp -pR'. ln -s conf$$.file conf$$.dir 2>/dev/null && test ! -f conf$$.exe || as_ln_s='cp -pR' elif ln conf$$.file conf$$ 2>/dev/null; then as_ln_s=ln else as_ln_s='cp -pR' fi else as_ln_s='cp -pR' fi rm -f conf$$ conf$$.exe conf$$.dir/conf$$.file conf$$.file rmdir conf$$.dir 2>/dev/null if mkdir -p . 2>/dev/null; then as_mkdir_p='mkdir -p "$as_dir"' else test -d ./-p && rmdir ./-p as_mkdir_p=false fi as_test_x='test -x' as_executable_p=as_fn_executable_p # Sed expression to map a string onto a valid CPP name. as_tr_cpp="eval sed 'y%*$as_cr_letters%P$as_cr_LETTERS%;s%[^_$as_cr_alnum]%_%g'" # Sed expression to map a string onto a valid variable name. as_tr_sh="eval sed 'y%*+%pp%;s%[^_$as_cr_alnum]%_%g'" test -n "$DJDIR" || exec 7<&0 &1 # Name of the host. # hostname on some systems (SVR3.2, old GNU/Linux) returns a bogus exit status, # so uname gets run too. ac_hostname=`(hostname || uname -n) 2>/dev/null | sed 1q` # # Initializations. # ac_default_prefix=/usr/local ac_clean_files= ac_config_libobj_dir=. LIBOBJS= cross_compiling=no subdirs= MFLAGS= MAKEFLAGS= # Identity of this package. PACKAGE_NAME='openchange' PACKAGE_TARNAME='openchange' PACKAGE_VERSION='2.0' PACKAGE_STRING='openchange 2.0' PACKAGE_BUGREPORT='openchange@openchange.org' PACKAGE_URL='' # Factoring default headers for most tests. ac_includes_default="\ #include #ifdef HAVE_SYS_TYPES_H # include #endif #ifdef HAVE_SYS_STAT_H # include #endif #ifdef STDC_HEADERS # include # include #else # ifdef HAVE_STDLIB_H # include # endif #endif #ifdef HAVE_STRING_H # if !defined STDC_HEADERS && defined HAVE_MEMORY_H # include # endif # include #endif #ifdef HAVE_STRINGS_H # include #endif #ifdef HAVE_INTTYPES_H # include #endif #ifdef HAVE_STDINT_H # include #endif #ifdef HAVE_UNISTD_H # include #endif" ac_subst_vars='am__EXEEXT_FALSE am__EXEEXT_TRUE LTLIBOBJS LIBOBJS OPENCHANGE_QT4 MOC Qt4_LIBS Qt4_CFLAGS SUBUNIT_LIBS SUBUNIT_CFLAGS DOXYGEN PYMAPIUNINSTALL PYMAPIINSTALL PYMAPIALL PYCDIR modulesdir OC_SERVER_UNINSTALL OC_SERVER_INSTALL OC_SERVER_CLEAN OC_SERVER OC_SERVER_INSTALLLIB OC_SERVER_INSTALLHEADER OC_SERVER_INSTALLPC OC_MAPISTORE_UNINSTALL OC_MAPISTORE_INSTALL OC_MAPISTORE_CLEAN OC_MAPISTORE RT_LIBS MAGIC_LIBS OC_TOOLS_UNINSTALL OC_TOOLS_INSTALL OC_TOOLS_CLEAN OC_TOOLS OC_TOOLS_INSTALLLIB OC_TOOLS_INSTALLHEADER OC_TOOLS_INSTALLPC MAPISTORE_TEST have_libical_0_46 ICAL_0_46_LIBS ICAL_0_46_CFLAGS ICAL_LIBS ICAL_CFLAGS SAMR_LIBS SAMR_CFLAGS BISON BOOST_LIB_SUFFIX am__fastdepCXX_FALSE am__fastdepCXX_TRUE CXXDEPMODE ac_ct_CXX CXXFLAGS CXX THREAD_CFLAGS THREAD_LIBS GTHREAD_LIBS GTHREAD_CFLAGS DL_LIBS OC_IDL OC_LIBS_UNINSTALL OC_LIBS_INSTALL OC_LIBS_CLEAN OC_LIBS OC_LIBS_INSTALLLIB OC_LIBS_INSTALLHEADER OC_LIBS_INSTALLPC TYPE NAME DCERPC_SERVER_MODULESDIR LDB_LIBS LDB_CFLAGS TDB_LIBS TDB_CFLAGS SAMBASERVER_LIBS SAMBASERVER_CFLAGS SAMBA_LIBS SAMBA_CFLAGS TALLOC_LIBS TALLOC_CFLAGS FLEX pythondir PYTHON_LIBS PYTHON_CFLAGS PYTHON_CONFIG PYTHON PIDL PERL ASSERT_DEFINITION OPENCHANGE_VERSION_IS_SVN_SNAPSHOT COMPILER_OPTIONS_CXX COMPILER_OPTIONS_C COVERAGE_INIT EGREP GREP CPP am__fastdepCC_FALSE am__fastdepCC_TRUE CCDEPMODE am__nodep AMDEPBACKSLASH AMDEP_FALSE AMDEP_TRUE am__quote am__include DEPDIR OBJEXT EXEEXT ac_ct_CC CPPFLAGS LDFLAGS CFLAGS CC sambaprefix MANUALLY_CREATE_SYMLINKS BUILD_FOR_SOLARIS BUILD_FOR_FREEBSD host_os host_vendor host_cpu host build_os build_vendor build_cpu build PKG_CONFIG_LIBDIR PKG_CONFIG_PATH PKG_CONFIG am__untar am__tar AMTAR am__leading_dot SET_MAKE AWK mkdir_p MKDIR_P INSTALL_STRIP_PROGRAM STRIP install_sh MAKEINFO AUTOHEADER AUTOMAKE AUTOCONF ACLOCAL VERSION PACKAGE CYGPATH_W am__isrc INSTALL_DATA INSTALL_SCRIPT INSTALL_PROGRAM target_alias host_alias build_alias LIBS ECHO_T ECHO_N ECHO_C DEFS mandir localedir libdir psdir pdfdir dvidir htmldir infodir docdir oldincludedir includedir localstatedir sharedstatedir sysconfdir datadir datarootdir libexecdir sbindir bindir program_transform_name prefix exec_prefix PACKAGE_URL PACKAGE_BUGREPORT PACKAGE_STRING PACKAGE_VERSION PACKAGE_TARNAME PACKAGE_NAME PATH_SEPARATOR SHELL' ac_subst_files='' ac_user_opts=' enable_option_checking with_samba enable_dependency_tracking enable_coverage with_modulesdir enable_pymapi enable_openchange_qt4 ' ac_precious_vars='build_alias host_alias target_alias PKG_CONFIG PKG_CONFIG_PATH PKG_CONFIG_LIBDIR CC CFLAGS LDFLAGS LIBS CPPFLAGS CPP FLEX TALLOC_CFLAGS TALLOC_LIBS SAMBA_CFLAGS SAMBA_LIBS SAMBASERVER_CFLAGS SAMBASERVER_LIBS TDB_CFLAGS TDB_LIBS LDB_CFLAGS LDB_LIBS NAME TYPE GTHREAD_CFLAGS GTHREAD_LIBS CXX CXXFLAGS CCC BOOST_LIB_SUFFIX BISON SAMR_CFLAGS SAMR_LIBS ICAL_CFLAGS ICAL_LIBS ICAL_0_46_CFLAGS ICAL_0_46_LIBS SUBUNIT_CFLAGS SUBUNIT_LIBS Qt4_CFLAGS Qt4_LIBS' # Initialize some variables set by options. ac_init_help= ac_init_version=false ac_unrecognized_opts= ac_unrecognized_sep= # The variables have the same names as the options, with # dashes changed to underlines. cache_file=/dev/null exec_prefix=NONE no_create= no_recursion= prefix=NONE program_prefix=NONE program_suffix=NONE program_transform_name=s,x,x, silent= site= srcdir= verbose= x_includes=NONE x_libraries=NONE # Installation directory options. # These are left unexpanded so users can "make install exec_prefix=/foo" # and all the variables that are supposed to be based on exec_prefix # by default will actually change. # Use braces instead of parens because sh, perl, etc. also accept them. # (The list follows the same order as the GNU Coding Standards.) bindir='${exec_prefix}/bin' sbindir='${exec_prefix}/sbin' libexecdir='${exec_prefix}/libexec' datarootdir='${prefix}/share' datadir='${datarootdir}' sysconfdir='${prefix}/etc' sharedstatedir='${prefix}/com' localstatedir='${prefix}/var' includedir='${prefix}/include' oldincludedir='/usr/include' docdir='${datarootdir}/doc/${PACKAGE_TARNAME}' infodir='${datarootdir}/info' htmldir='${docdir}' dvidir='${docdir}' pdfdir='${docdir}' psdir='${docdir}' libdir='${exec_prefix}/lib' localedir='${datarootdir}/locale' mandir='${datarootdir}/man' ac_prev= ac_dashdash= for ac_option do # If the previous option needs an argument, assign it. if test -n "$ac_prev"; then eval $ac_prev=\$ac_option ac_prev= continue fi case $ac_option in *=?*) ac_optarg=`expr "X$ac_option" : '[^=]*=\(.*\)'` ;; *=) ac_optarg= ;; *) ac_optarg=yes ;; esac # Accept the important Cygnus configure options, so we can diagnose typos. case $ac_dashdash$ac_option in --) ac_dashdash=yes ;; -bindir | --bindir | --bindi | --bind | --bin | --bi) ac_prev=bindir ;; -bindir=* | --bindir=* | --bindi=* | --bind=* | --bin=* | --bi=*) bindir=$ac_optarg ;; -build | --build | --buil | --bui | --bu) ac_prev=build_alias ;; -build=* | --build=* | --buil=* | --bui=* | --bu=*) build_alias=$ac_optarg ;; -cache-file | --cache-file | --cache-fil | --cache-fi \ | --cache-f | --cache- | --cache | --cach | --cac | --ca | --c) ac_prev=cache_file ;; -cache-file=* | --cache-file=* | --cache-fil=* | --cache-fi=* \ | --cache-f=* | --cache-=* | --cache=* | --cach=* | --cac=* | --ca=* | --c=*) cache_file=$ac_optarg ;; --config-cache | -C) cache_file=config.cache ;; -datadir | --datadir | --datadi | --datad) ac_prev=datadir ;; -datadir=* | --datadir=* | --datadi=* | --datad=*) datadir=$ac_optarg ;; -datarootdir | --datarootdir | --datarootdi | --datarootd | --dataroot \ | --dataroo | --dataro | --datar) ac_prev=datarootdir ;; -datarootdir=* | --datarootdir=* | --datarootdi=* | --datarootd=* \ | --dataroot=* | --dataroo=* | --dataro=* | --datar=*) datarootdir=$ac_optarg ;; -disable-* | --disable-*) ac_useropt=`expr "x$ac_option" : 'x-*disable-\(.*\)'` # Reject names that are not valid shell variable names. expr "x$ac_useropt" : ".*[^-+._$as_cr_alnum]" >/dev/null && as_fn_error $? "invalid feature name: $ac_useropt" ac_useropt_orig=$ac_useropt ac_useropt=`$as_echo "$ac_useropt" | sed 's/[-+.]/_/g'` case $ac_user_opts in *" "enable_$ac_useropt" "*) ;; *) ac_unrecognized_opts="$ac_unrecognized_opts$ac_unrecognized_sep--disable-$ac_useropt_orig" ac_unrecognized_sep=', ';; esac eval enable_$ac_useropt=no ;; -docdir | --docdir | --docdi | --doc | --do) ac_prev=docdir ;; -docdir=* | --docdir=* | --docdi=* | --doc=* | --do=*) docdir=$ac_optarg ;; -dvidir | --dvidir | --dvidi | --dvid | --dvi | --dv) ac_prev=dvidir ;; -dvidir=* | --dvidir=* | --dvidi=* | --dvid=* | --dvi=* | --dv=*) dvidir=$ac_optarg ;; -enable-* | --enable-*) ac_useropt=`expr "x$ac_option" : 'x-*enable-\([^=]*\)'` # Reject names that are not valid shell variable names. expr "x$ac_useropt" : ".*[^-+._$as_cr_alnum]" >/dev/null && as_fn_error $? "invalid feature name: $ac_useropt" ac_useropt_orig=$ac_useropt ac_useropt=`$as_echo "$ac_useropt" | sed 's/[-+.]/_/g'` case $ac_user_opts in *" "enable_$ac_useropt" "*) ;; *) ac_unrecognized_opts="$ac_unrecognized_opts$ac_unrecognized_sep--enable-$ac_useropt_orig" ac_unrecognized_sep=', ';; esac eval enable_$ac_useropt=\$ac_optarg ;; -exec-prefix | --exec_prefix | --exec-prefix | --exec-prefi \ | --exec-pref | --exec-pre | --exec-pr | --exec-p | --exec- \ | --exec | --exe | --ex) ac_prev=exec_prefix ;; -exec-prefix=* | --exec_prefix=* | --exec-prefix=* | --exec-prefi=* \ | --exec-pref=* | --exec-pre=* | --exec-pr=* | --exec-p=* | --exec-=* \ | --exec=* | --exe=* | --ex=*) exec_prefix=$ac_optarg ;; -gas | --gas | --ga | --g) # Obsolete; use --with-gas. with_gas=yes ;; -help | --help | --hel | --he | -h) ac_init_help=long ;; -help=r* | --help=r* | --hel=r* | --he=r* | -hr*) ac_init_help=recursive ;; -help=s* | --help=s* | --hel=s* | --he=s* | -hs*) ac_init_help=short ;; -host | --host | --hos | --ho) ac_prev=host_alias ;; -host=* | --host=* | --hos=* | --ho=*) host_alias=$ac_optarg ;; -htmldir | --htmldir | --htmldi | --htmld | --html | --htm | --ht) ac_prev=htmldir ;; -htmldir=* | --htmldir=* | --htmldi=* | --htmld=* | --html=* | --htm=* \ | --ht=*) htmldir=$ac_optarg ;; -includedir | --includedir | --includedi | --included | --include \ | --includ | --inclu | --incl | --inc) ac_prev=includedir ;; -includedir=* | --includedir=* | --includedi=* | --included=* | --include=* \ | --includ=* | --inclu=* | --incl=* | --inc=*) includedir=$ac_optarg ;; -infodir | --infodir | --infodi | --infod | --info | --inf) ac_prev=infodir ;; -infodir=* | --infodir=* | --infodi=* | --infod=* | --info=* | --inf=*) infodir=$ac_optarg ;; -libdir | --libdir | --libdi | --libd) ac_prev=libdir ;; -libdir=* | --libdir=* | --libdi=* | --libd=*) libdir=$ac_optarg ;; -libexecdir | --libexecdir | --libexecdi | --libexecd | --libexec \ | --libexe | --libex | --libe) ac_prev=libexecdir ;; -libexecdir=* | --libexecdir=* | --libexecdi=* | --libexecd=* | --libexec=* \ | --libexe=* | --libex=* | --libe=*) libexecdir=$ac_optarg ;; -localedir | --localedir | --localedi | --localed | --locale) ac_prev=localedir ;; -localedir=* | --localedir=* | --localedi=* | --localed=* | --locale=*) localedir=$ac_optarg ;; -localstatedir | --localstatedir | --localstatedi | --localstated \ | --localstate | --localstat | --localsta | --localst | --locals) ac_prev=localstatedir ;; -localstatedir=* | --localstatedir=* | --localstatedi=* | --localstated=* \ | --localstate=* | --localstat=* | --localsta=* | --localst=* | --locals=*) localstatedir=$ac_optarg ;; -mandir | --mandir | --mandi | --mand | --man | --ma | --m) ac_prev=mandir ;; -mandir=* | --mandir=* | --mandi=* | --mand=* | --man=* | --ma=* | --m=*) mandir=$ac_optarg ;; -nfp | --nfp | --nf) # Obsolete; use --without-fp. with_fp=no ;; -no-create | --no-create | --no-creat | --no-crea | --no-cre \ | --no-cr | --no-c | -n) no_create=yes ;; -no-recursion | --no-recursion | --no-recursio | --no-recursi \ | --no-recurs | --no-recur | --no-recu | --no-rec | --no-re | --no-r) no_recursion=yes ;; -oldincludedir | --oldincludedir | --oldincludedi | --oldincluded \ | --oldinclude | --oldinclud | --oldinclu | --oldincl | --oldinc \ | --oldin | --oldi | --old | --ol | --o) ac_prev=oldincludedir ;; -oldincludedir=* | --oldincludedir=* | --oldincludedi=* | --oldincluded=* \ | --oldinclude=* | --oldinclud=* | --oldinclu=* | --oldincl=* | --oldinc=* \ | --oldin=* | --oldi=* | --old=* | --ol=* | --o=*) oldincludedir=$ac_optarg ;; -prefix | --prefix | --prefi | --pref | --pre | --pr | --p) ac_prev=prefix ;; -prefix=* | --prefix=* | --prefi=* | --pref=* | --pre=* | --pr=* | --p=*) prefix=$ac_optarg ;; -program-prefix | --program-prefix | --program-prefi | --program-pref \ | --program-pre | --program-pr | --program-p) ac_prev=program_prefix ;; -program-prefix=* | --program-prefix=* | --program-prefi=* \ | --program-pref=* | --program-pre=* | --program-pr=* | --program-p=*) program_prefix=$ac_optarg ;; -program-suffix | --program-suffix | --program-suffi | --program-suff \ | --program-suf | --program-su | --program-s) ac_prev=program_suffix ;; -program-suffix=* | --program-suffix=* | --program-suffi=* \ | --program-suff=* | --program-suf=* | --program-su=* | --program-s=*) program_suffix=$ac_optarg ;; -program-transform-name | --program-transform-name \ | --program-transform-nam | --program-transform-na \ | --program-transform-n | --program-transform- \ | --program-transform | --program-transfor \ | --program-transfo | --program-transf \ | --program-trans | --program-tran \ | --progr-tra | --program-tr | --program-t) ac_prev=program_transform_name ;; -program-transform-name=* | --program-transform-name=* \ | --program-transform-nam=* | --program-transform-na=* \ | --program-transform-n=* | --program-transform-=* \ | --program-transform=* | --program-transfor=* \ | --program-transfo=* | --program-transf=* \ | --program-trans=* | --program-tran=* \ | --progr-tra=* | --program-tr=* | --program-t=*) program_transform_name=$ac_optarg ;; -pdfdir | --pdfdir | --pdfdi | --pdfd | --pdf | --pd) ac_prev=pdfdir ;; -pdfdir=* | --pdfdir=* | --pdfdi=* | --pdfd=* | --pdf=* | --pd=*) pdfdir=$ac_optarg ;; -psdir | --psdir | --psdi | --psd | --ps) ac_prev=psdir ;; -psdir=* | --psdir=* | --psdi=* | --psd=* | --ps=*) psdir=$ac_optarg ;; -q | -quiet | --quiet | --quie | --qui | --qu | --q \ | -silent | --silent | --silen | --sile | --sil) silent=yes ;; -sbindir | --sbindir | --sbindi | --sbind | --sbin | --sbi | --sb) ac_prev=sbindir ;; -sbindir=* | --sbindir=* | --sbindi=* | --sbind=* | --sbin=* \ | --sbi=* | --sb=*) sbindir=$ac_optarg ;; -sharedstatedir | --sharedstatedir | --sharedstatedi \ | --sharedstated | --sharedstate | --sharedstat | --sharedsta \ | --sharedst | --shareds | --shared | --share | --shar \ | --sha | --sh) ac_prev=sharedstatedir ;; -sharedstatedir=* | --sharedstatedir=* | --sharedstatedi=* \ | --sharedstated=* | --sharedstate=* | --sharedstat=* | --sharedsta=* \ | --sharedst=* | --shareds=* | --shared=* | --share=* | --shar=* \ | --sha=* | --sh=*) sharedstatedir=$ac_optarg ;; -site | --site | --sit) ac_prev=site ;; -site=* | --site=* | --sit=*) site=$ac_optarg ;; -srcdir | --srcdir | --srcdi | --srcd | --src | --sr) ac_prev=srcdir ;; -srcdir=* | --srcdir=* | --srcdi=* | --srcd=* | --src=* | --sr=*) srcdir=$ac_optarg ;; -sysconfdir | --sysconfdir | --sysconfdi | --sysconfd | --sysconf \ | --syscon | --sysco | --sysc | --sys | --sy) ac_prev=sysconfdir ;; -sysconfdir=* | --sysconfdir=* | --sysconfdi=* | --sysconfd=* | --sysconf=* \ | --syscon=* | --sysco=* | --sysc=* | --sys=* | --sy=*) sysconfdir=$ac_optarg ;; -target | --target | --targe | --targ | --tar | --ta | --t) ac_prev=target_alias ;; -target=* | --target=* | --targe=* | --targ=* | --tar=* | --ta=* | --t=*) target_alias=$ac_optarg ;; -v | -verbose | --verbose | --verbos | --verbo | --verb) verbose=yes ;; -version | --version | --versio | --versi | --vers | -V) ac_init_version=: ;; -with-* | --with-*) ac_useropt=`expr "x$ac_option" : 'x-*with-\([^=]*\)'` # Reject names that are not valid shell variable names. expr "x$ac_useropt" : ".*[^-+._$as_cr_alnum]" >/dev/null && as_fn_error $? "invalid package name: $ac_useropt" ac_useropt_orig=$ac_useropt ac_useropt=`$as_echo "$ac_useropt" | sed 's/[-+.]/_/g'` case $ac_user_opts in *" "with_$ac_useropt" "*) ;; *) ac_unrecognized_opts="$ac_unrecognized_opts$ac_unrecognized_sep--with-$ac_useropt_orig" ac_unrecognized_sep=', ';; esac eval with_$ac_useropt=\$ac_optarg ;; -without-* | --without-*) ac_useropt=`expr "x$ac_option" : 'x-*without-\(.*\)'` # Reject names that are not valid shell variable names. expr "x$ac_useropt" : ".*[^-+._$as_cr_alnum]" >/dev/null && as_fn_error $? "invalid package name: $ac_useropt" ac_useropt_orig=$ac_useropt ac_useropt=`$as_echo "$ac_useropt" | sed 's/[-+.]/_/g'` case $ac_user_opts in *" "with_$ac_useropt" "*) ;; *) ac_unrecognized_opts="$ac_unrecognized_opts$ac_unrecognized_sep--without-$ac_useropt_orig" ac_unrecognized_sep=', ';; esac eval with_$ac_useropt=no ;; --x) # Obsolete; use --with-x. with_x=yes ;; -x-includes | --x-includes | --x-include | --x-includ | --x-inclu \ | --x-incl | --x-inc | --x-in | --x-i) ac_prev=x_includes ;; -x-includes=* | --x-includes=* | --x-include=* | --x-includ=* | --x-inclu=* \ | --x-incl=* | --x-inc=* | --x-in=* | --x-i=*) x_includes=$ac_optarg ;; -x-libraries | --x-libraries | --x-librarie | --x-librari \ | --x-librar | --x-libra | --x-libr | --x-lib | --x-li | --x-l) ac_prev=x_libraries ;; -x-libraries=* | --x-libraries=* | --x-librarie=* | --x-librari=* \ | --x-librar=* | --x-libra=* | --x-libr=* | --x-lib=* | --x-li=* | --x-l=*) x_libraries=$ac_optarg ;; -*) as_fn_error $? "unrecognized option: \`$ac_option' Try \`$0 --help' for more information" ;; *=*) ac_envvar=`expr "x$ac_option" : 'x\([^=]*\)='` # Reject names that are not valid shell variable names. case $ac_envvar in #( '' | [0-9]* | *[!_$as_cr_alnum]* ) as_fn_error $? "invalid variable name: \`$ac_envvar'" ;; esac eval $ac_envvar=\$ac_optarg export $ac_envvar ;; *) # FIXME: should be removed in autoconf 3.0. $as_echo "$as_me: WARNING: you should use --build, --host, --target" >&2 expr "x$ac_option" : ".*[^-._$as_cr_alnum]" >/dev/null && $as_echo "$as_me: WARNING: invalid host type: $ac_option" >&2 : "${build_alias=$ac_option} ${host_alias=$ac_option} ${target_alias=$ac_option}" ;; esac done if test -n "$ac_prev"; then ac_option=--`echo $ac_prev | sed 's/_/-/g'` as_fn_error $? "missing argument to $ac_option" fi if test -n "$ac_unrecognized_opts"; then case $enable_option_checking in no) ;; fatal) as_fn_error $? "unrecognized options: $ac_unrecognized_opts" ;; *) $as_echo "$as_me: WARNING: unrecognized options: $ac_unrecognized_opts" >&2 ;; esac fi # Check all directory arguments for consistency. for ac_var in exec_prefix prefix bindir sbindir libexecdir datarootdir \ datadir sysconfdir sharedstatedir localstatedir includedir \ oldincludedir docdir infodir htmldir dvidir pdfdir psdir \ libdir localedir mandir do eval ac_val=\$$ac_var # Remove trailing slashes. case $ac_val in */ ) ac_val=`expr "X$ac_val" : 'X\(.*[^/]\)' \| "X$ac_val" : 'X\(.*\)'` eval $ac_var=\$ac_val;; esac # Be sure to have absolute directory names. case $ac_val in [\\/$]* | ?:[\\/]* ) continue;; NONE | '' ) case $ac_var in *prefix ) continue;; esac;; esac as_fn_error $? "expected an absolute directory name for --$ac_var: $ac_val" done # There might be people who depend on the old broken behavior: `$host' # used to hold the argument of --host etc. # FIXME: To remove some day. build=$build_alias host=$host_alias target=$target_alias # FIXME: To remove some day. if test "x$host_alias" != x; then if test "x$build_alias" = x; then cross_compiling=maybe elif test "x$build_alias" != "x$host_alias"; then cross_compiling=yes fi fi ac_tool_prefix= test -n "$host_alias" && ac_tool_prefix=$host_alias- test "$silent" = yes && exec 6>/dev/null ac_pwd=`pwd` && test -n "$ac_pwd" && ac_ls_di=`ls -di .` && ac_pwd_ls_di=`cd "$ac_pwd" && ls -di .` || as_fn_error $? "working directory cannot be determined" test "X$ac_ls_di" = "X$ac_pwd_ls_di" || as_fn_error $? "pwd does not report name of working directory" # Find the source files, if location was not specified. if test -z "$srcdir"; then ac_srcdir_defaulted=yes # Try the directory containing this script, then the parent directory. ac_confdir=`$as_dirname -- "$as_myself" || $as_expr X"$as_myself" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \ X"$as_myself" : 'X\(//\)[^/]' \| \ X"$as_myself" : 'X\(//\)$' \| \ X"$as_myself" : 'X\(/\)' \| . 2>/dev/null || $as_echo X"$as_myself" | sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ s//\1/ q } /^X\(\/\/\)[^/].*/{ s//\1/ q } /^X\(\/\/\)$/{ s//\1/ q } /^X\(\/\).*/{ s//\1/ q } s/.*/./; q'` srcdir=$ac_confdir if test ! -r "$srcdir/$ac_unique_file"; then srcdir=.. fi else ac_srcdir_defaulted=no fi if test ! -r "$srcdir/$ac_unique_file"; then test "$ac_srcdir_defaulted" = yes && srcdir="$ac_confdir or .." as_fn_error $? "cannot find sources ($ac_unique_file) in $srcdir" fi ac_msg="sources are in $srcdir, but \`cd $srcdir' does not work" ac_abs_confdir=`( cd "$srcdir" && test -r "./$ac_unique_file" || as_fn_error $? "$ac_msg" pwd)` # When building in place, set srcdir=. if test "$ac_abs_confdir" = "$ac_pwd"; then srcdir=. fi # Remove unnecessary trailing slashes from srcdir. # Double slashes in file names in object file debugging info # mess up M-x gdb in Emacs. case $srcdir in */) srcdir=`expr "X$srcdir" : 'X\(.*[^/]\)' \| "X$srcdir" : 'X\(.*\)'`;; esac for ac_var in $ac_precious_vars; do eval ac_env_${ac_var}_set=\${${ac_var}+set} eval ac_env_${ac_var}_value=\$${ac_var} eval ac_cv_env_${ac_var}_set=\${${ac_var}+set} eval ac_cv_env_${ac_var}_value=\$${ac_var} done # # Report the --help message. # if test "$ac_init_help" = "long"; then # Omit some internal or obsolete options to make the list less imposing. # This message is too long to be a string in the A/UX 3.1 sh. cat <<_ACEOF \`configure' configures openchange 2.0 to adapt to many kinds of systems. Usage: $0 [OPTION]... [VAR=VALUE]... To assign environment variables (e.g., CC, CFLAGS...), specify them as VAR=VALUE. See below for descriptions of some of the useful variables. Defaults for the options are specified in brackets. Configuration: -h, --help display this help and exit --help=short display options specific to this package --help=recursive display the short help of all the included packages -V, --version display version information and exit -q, --quiet, --silent do not print \`checking ...' messages --cache-file=FILE cache test results in FILE [disabled] -C, --config-cache alias for \`--cache-file=config.cache' -n, --no-create do not create output files --srcdir=DIR find the sources in DIR [configure dir or \`..'] Installation directories: --prefix=PREFIX install architecture-independent files in PREFIX [$ac_default_prefix] --exec-prefix=EPREFIX install architecture-dependent files in EPREFIX [PREFIX] By default, \`make install' will install all the files in \`$ac_default_prefix/bin', \`$ac_default_prefix/lib' etc. You can specify an installation prefix other than \`$ac_default_prefix' using \`--prefix', for instance \`--prefix=\$HOME'. For better control, use the options below. Fine tuning of the installation directories: --bindir=DIR user executables [EPREFIX/bin] --sbindir=DIR system admin executables [EPREFIX/sbin] --libexecdir=DIR program executables [EPREFIX/libexec] --sysconfdir=DIR read-only single-machine data [PREFIX/etc] --sharedstatedir=DIR modifiable architecture-independent data [PREFIX/com] --localstatedir=DIR modifiable single-machine data [PREFIX/var] --libdir=DIR object code libraries [EPREFIX/lib] --includedir=DIR C header files [PREFIX/include] --oldincludedir=DIR C header files for non-gcc [/usr/include] --datarootdir=DIR read-only arch.-independent data root [PREFIX/share] --datadir=DIR read-only architecture-independent data [DATAROOTDIR] --infodir=DIR info documentation [DATAROOTDIR/info] --localedir=DIR locale-dependent data [DATAROOTDIR/locale] --mandir=DIR man documentation [DATAROOTDIR/man] --docdir=DIR documentation root [DATAROOTDIR/doc/openchange] --htmldir=DIR html documentation [DOCDIR] --dvidir=DIR dvi documentation [DOCDIR] --pdfdir=DIR pdf documentation [DOCDIR] --psdir=DIR ps documentation [DOCDIR] _ACEOF cat <<\_ACEOF Program names: --program-prefix=PREFIX prepend PREFIX to installed program names --program-suffix=SUFFIX append SUFFIX to installed program names --program-transform-name=PROGRAM run sed PROGRAM on installed program names System types: --build=BUILD configure for building on BUILD [guessed] --host=HOST cross-compile to build programs to run on HOST [BUILD] _ACEOF fi if test -n "$ac_init_help"; then case $ac_init_help in short | recursive ) echo "Configuration of openchange 2.0:";; esac cat <<\_ACEOF Optional Features: --disable-option-checking ignore unrecognized --enable/--with options --disable-FEATURE do not include FEATURE (same as --enable-FEATURE=no) --enable-FEATURE[=ARG] include FEATURE [ARG=yes] --disable-dependency-tracking speeds up one-time build --enable-dependency-tracking do not reject slow dependency extractors --enable-coverage Compile the library with code coverage support (default is NO) --enable-pymapi build Python bindings for libmapi --enable-openchange-qt4 Compile OpenChange Qt4 wrapper. Optional Packages: --with-PACKAGE[=ARG] use PACKAGE [ARG=yes] --without-PACKAGE do not use PACKAGE (same as --with-PACKAGE=no) --with-samba Override location Samba is installed --with-modulesdir Modules path to use Some influential environment variables: PKG_CONFIG path to pkg-config utility PKG_CONFIG_PATH directories to add to pkg-config's search path PKG_CONFIG_LIBDIR path overriding pkg-config's built-in search path CC C compiler command CFLAGS C compiler flags LDFLAGS linker flags, e.g. -L if you have libraries in a nonstandard directory LIBS libraries to pass to the linker, e.g. -l CPPFLAGS (Objective) C/C++ preprocessor flags, e.g. -I if you have headers in a nonstandard directory CPP C preprocessor FLEX Location of the flex program. TALLOC_CFLAGS C compiler flags for TALLOC, overriding pkg-config TALLOC_LIBS linker flags for TALLOC, overriding pkg-config SAMBA_CFLAGS C compiler flags for SAMBA, overriding pkg-config SAMBA_LIBS linker flags for SAMBA, overriding pkg-config SAMBASERVER_CFLAGS C compiler flags for SAMBASERVER, overriding pkg-config SAMBASERVER_LIBS linker flags for SAMBASERVER, overriding pkg-config TDB_CFLAGS C compiler flags for TDB, overriding pkg-config TDB_LIBS linker flags for TDB, overriding pkg-config LDB_CFLAGS C compiler flags for LDB, overriding pkg-config LDB_LIBS linker flags for LDB, overriding pkg-config NAME rule name TYPE rule type GTHREAD_CFLAGS C compiler flags for GTHREAD, overriding pkg-config GTHREAD_LIBS linker flags for GTHREAD, overriding pkg-config CXX C++ compiler command CXXFLAGS C++ compiler flags BOOST_LIB_SUFFIX Boost library name suffix BISON Location of the bison program. SAMR_CFLAGS C compiler flags for SAMR, overriding pkg-config SAMR_LIBS linker flags for SAMR, overriding pkg-config ICAL_CFLAGS C compiler flags for ICAL, overriding pkg-config ICAL_LIBS linker flags for ICAL, overriding pkg-config ICAL_0_46_CFLAGS C compiler flags for ICAL_0_46, overriding pkg-config ICAL_0_46_LIBS linker flags for ICAL_0_46, overriding pkg-config SUBUNIT_CFLAGS C compiler flags for SUBUNIT, overriding pkg-config SUBUNIT_LIBS linker flags for SUBUNIT, overriding pkg-config Qt4_CFLAGS C compiler flags for Qt4, overriding pkg-config Qt4_LIBS linker flags for Qt4, overriding pkg-config Use these variables to override the choices made by `configure' or to help it to find libraries and programs with nonstandard names/locations. Report bugs to . _ACEOF ac_status=$? fi if test "$ac_init_help" = "recursive"; then # If there are subdirs, report their specific --help. for ac_dir in : $ac_subdirs_all; do test "x$ac_dir" = x: && continue test -d "$ac_dir" || { cd "$srcdir" && ac_pwd=`pwd` && srcdir=. && test -d "$ac_dir"; } || continue ac_builddir=. case "$ac_dir" in .) ac_dir_suffix= ac_top_builddir_sub=. ac_top_build_prefix= ;; *) ac_dir_suffix=/`$as_echo "$ac_dir" | sed 's|^\.[\\/]||'` # A ".." for each directory in $ac_dir_suffix. ac_top_builddir_sub=`$as_echo "$ac_dir_suffix" | sed 's|/[^\\/]*|/..|g;s|/||'` case $ac_top_builddir_sub in "") ac_top_builddir_sub=. ac_top_build_prefix= ;; *) ac_top_build_prefix=$ac_top_builddir_sub/ ;; esac ;; esac ac_abs_top_builddir=$ac_pwd ac_abs_builddir=$ac_pwd$ac_dir_suffix # for backward compatibility: ac_top_builddir=$ac_top_build_prefix case $srcdir in .) # We are building in place. ac_srcdir=. ac_top_srcdir=$ac_top_builddir_sub ac_abs_top_srcdir=$ac_pwd ;; [\\/]* | ?:[\\/]* ) # Absolute name. ac_srcdir=$srcdir$ac_dir_suffix; ac_top_srcdir=$srcdir ac_abs_top_srcdir=$srcdir ;; *) # Relative name. ac_srcdir=$ac_top_build_prefix$srcdir$ac_dir_suffix ac_top_srcdir=$ac_top_build_prefix$srcdir ac_abs_top_srcdir=$ac_pwd/$srcdir ;; esac ac_abs_srcdir=$ac_abs_top_srcdir$ac_dir_suffix cd "$ac_dir" || { ac_status=$?; continue; } # Check for guested configure. if test -f "$ac_srcdir/configure.gnu"; then echo && $SHELL "$ac_srcdir/configure.gnu" --help=recursive elif test -f "$ac_srcdir/configure"; then echo && $SHELL "$ac_srcdir/configure" --help=recursive else $as_echo "$as_me: WARNING: no configuration information is in $ac_dir" >&2 fi || ac_status=$? cd "$ac_pwd" || { ac_status=$?; break; } done fi test -n "$ac_init_help" && exit $ac_status if $ac_init_version; then cat <<\_ACEOF openchange configure 2.0 generated by GNU Autoconf 2.69 Copyright (C) 2012 Free Software Foundation, Inc. This configure script is free software; the Free Software Foundation gives unlimited permission to copy, distribute and modify it. _ACEOF exit fi ## ------------------------ ## ## Autoconf initialization. ## ## ------------------------ ## # ac_fn_c_try_compile LINENO # -------------------------- # Try to compile conftest.$ac_ext, and return whether this succeeded. ac_fn_c_try_compile () { as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack rm -f conftest.$ac_objext if { { ac_try="$ac_compile" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" $as_echo "$ac_try_echo"; } >&5 (eval "$ac_compile") 2>conftest.err ac_status=$? if test -s conftest.err; then grep -v '^ *+' conftest.err >conftest.er1 cat conftest.er1 >&5 mv -f conftest.er1 conftest.err fi $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 test $ac_status = 0; } && { test -z "$ac_c_werror_flag" || test ! -s conftest.err } && test -s conftest.$ac_objext; then : ac_retval=0 else $as_echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 ac_retval=1 fi eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno as_fn_set_status $ac_retval } # ac_fn_c_try_compile # ac_fn_c_try_cpp LINENO # ---------------------- # Try to preprocess conftest.$ac_ext, and return whether this succeeded. ac_fn_c_try_cpp () { as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack if { { ac_try="$ac_cpp conftest.$ac_ext" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" $as_echo "$ac_try_echo"; } >&5 (eval "$ac_cpp conftest.$ac_ext") 2>conftest.err ac_status=$? if test -s conftest.err; then grep -v '^ *+' conftest.err >conftest.er1 cat conftest.er1 >&5 mv -f conftest.er1 conftest.err fi $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 test $ac_status = 0; } > conftest.i && { test -z "$ac_c_preproc_warn_flag$ac_c_werror_flag" || test ! -s conftest.err }; then : ac_retval=0 else $as_echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 ac_retval=1 fi eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno as_fn_set_status $ac_retval } # ac_fn_c_try_cpp # ac_fn_c_check_header_mongrel LINENO HEADER VAR INCLUDES # ------------------------------------------------------- # Tests whether HEADER exists, giving a warning if it cannot be compiled using # the include files in INCLUDES and setting the cache variable VAR # accordingly. ac_fn_c_check_header_mongrel () { as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack if eval \${$3+:} false; then : { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $2" >&5 $as_echo_n "checking for $2... " >&6; } if eval \${$3+:} false; then : $as_echo_n "(cached) " >&6 fi eval ac_res=\$$3 { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5 $as_echo "$ac_res" >&6; } else # Is the header compilable? { $as_echo "$as_me:${as_lineno-$LINENO}: checking $2 usability" >&5 $as_echo_n "checking $2 usability... " >&6; } cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ $4 #include <$2> _ACEOF if ac_fn_c_try_compile "$LINENO"; then : ac_header_compiler=yes else ac_header_compiler=no fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_header_compiler" >&5 $as_echo "$ac_header_compiler" >&6; } # Is the header present? { $as_echo "$as_me:${as_lineno-$LINENO}: checking $2 presence" >&5 $as_echo_n "checking $2 presence... " >&6; } cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include <$2> _ACEOF if ac_fn_c_try_cpp "$LINENO"; then : ac_header_preproc=yes else ac_header_preproc=no fi rm -f conftest.err conftest.i conftest.$ac_ext { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_header_preproc" >&5 $as_echo "$ac_header_preproc" >&6; } # So? What about this header? case $ac_header_compiler:$ac_header_preproc:$ac_c_preproc_warn_flag in #(( yes:no: ) { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $2: accepted by the compiler, rejected by the preprocessor!" >&5 $as_echo "$as_me: WARNING: $2: accepted by the compiler, rejected by the preprocessor!" >&2;} { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $2: proceeding with the compiler's result" >&5 $as_echo "$as_me: WARNING: $2: proceeding with the compiler's result" >&2;} ;; no:yes:* ) { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $2: present but cannot be compiled" >&5 $as_echo "$as_me: WARNING: $2: present but cannot be compiled" >&2;} { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $2: check for missing prerequisite headers?" >&5 $as_echo "$as_me: WARNING: $2: check for missing prerequisite headers?" >&2;} { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $2: see the Autoconf documentation" >&5 $as_echo "$as_me: WARNING: $2: see the Autoconf documentation" >&2;} { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $2: section \"Present But Cannot Be Compiled\"" >&5 $as_echo "$as_me: WARNING: $2: section \"Present But Cannot Be Compiled\"" >&2;} { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $2: proceeding with the compiler's result" >&5 $as_echo "$as_me: WARNING: $2: proceeding with the compiler's result" >&2;} ( $as_echo "## ---------------------------------------- ## ## Report this to openchange@openchange.org ## ## ---------------------------------------- ##" ) | sed "s/^/$as_me: WARNING: /" >&2 ;; esac { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $2" >&5 $as_echo_n "checking for $2... " >&6; } if eval \${$3+:} false; then : $as_echo_n "(cached) " >&6 else eval "$3=\$ac_header_compiler" fi eval ac_res=\$$3 { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5 $as_echo "$ac_res" >&6; } fi eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno } # ac_fn_c_check_header_mongrel # ac_fn_c_try_run LINENO # ---------------------- # Try to link conftest.$ac_ext, and return whether this succeeded. Assumes # that executables *can* be run. ac_fn_c_try_run () { as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack if { { ac_try="$ac_link" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" $as_echo "$ac_try_echo"; } >&5 (eval "$ac_link") 2>&5 ac_status=$? $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 test $ac_status = 0; } && { ac_try='./conftest$ac_exeext' { { case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" $as_echo "$ac_try_echo"; } >&5 (eval "$ac_try") 2>&5 ac_status=$? $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 test $ac_status = 0; }; }; then : ac_retval=0 else $as_echo "$as_me: program exited with status $ac_status" >&5 $as_echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 ac_retval=$ac_status fi rm -rf conftest.dSYM conftest_ipa8_conftest.oo eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno as_fn_set_status $ac_retval } # ac_fn_c_try_run # ac_fn_c_check_header_compile LINENO HEADER VAR INCLUDES # ------------------------------------------------------- # Tests whether HEADER exists and can be compiled using the include files in # INCLUDES, setting the cache variable VAR accordingly. ac_fn_c_check_header_compile () { as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $2" >&5 $as_echo_n "checking for $2... " >&6; } if eval \${$3+:} false; then : $as_echo_n "(cached) " >&6 else cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ $4 #include <$2> _ACEOF if ac_fn_c_try_compile "$LINENO"; then : eval "$3=yes" else eval "$3=no" fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext fi eval ac_res=\$$3 { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5 $as_echo "$ac_res" >&6; } eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno } # ac_fn_c_check_header_compile # ac_fn_c_try_link LINENO # ----------------------- # Try to link conftest.$ac_ext, and return whether this succeeded. ac_fn_c_try_link () { as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack rm -f conftest.$ac_objext conftest$ac_exeext if { { ac_try="$ac_link" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" $as_echo "$ac_try_echo"; } >&5 (eval "$ac_link") 2>conftest.err ac_status=$? if test -s conftest.err; then grep -v '^ *+' conftest.err >conftest.er1 cat conftest.er1 >&5 mv -f conftest.er1 conftest.err fi $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 test $ac_status = 0; } && { test -z "$ac_c_werror_flag" || test ! -s conftest.err } && test -s conftest$ac_exeext && { test "$cross_compiling" = yes || test -x conftest$ac_exeext }; then : ac_retval=0 else $as_echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 ac_retval=1 fi # Delete the IPA/IPO (Inter Procedural Analysis/Optimization) information # created by the PGI compiler (conftest_ipa8_conftest.oo), as it would # interfere with the next link command; also delete a directory that is # left behind by Apple's compiler. We do this before executing the actions. rm -rf conftest.dSYM conftest_ipa8_conftest.oo eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno as_fn_set_status $ac_retval } # ac_fn_c_try_link # ac_fn_c_check_func LINENO FUNC VAR # ---------------------------------- # Tests whether FUNC exists, setting the cache variable VAR accordingly ac_fn_c_check_func () { as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $2" >&5 $as_echo_n "checking for $2... " >&6; } if eval \${$3+:} false; then : $as_echo_n "(cached) " >&6 else cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ /* Define $2 to an innocuous variant, in case declares $2. For example, HP-UX 11i declares gettimeofday. */ #define $2 innocuous_$2 /* System header to define __stub macros and hopefully few prototypes, which can conflict with char $2 (); below. Prefer to if __STDC__ is defined, since exists even on freestanding compilers. */ #ifdef __STDC__ # include #else # include #endif #undef $2 /* Override any GCC internal prototype to avoid an error. Use char because int might match the return type of a GCC builtin and then its argument prototype would still apply. */ #ifdef __cplusplus extern "C" #endif char $2 (); /* The GNU C library defines this for functions which it implements to always fail with ENOSYS. Some functions are actually named something starting with __ and the normal name is an alias. */ #if defined __stub_$2 || defined __stub___$2 choke me #endif int main () { return $2 (); ; return 0; } _ACEOF if ac_fn_c_try_link "$LINENO"; then : eval "$3=yes" else eval "$3=no" fi rm -f core conftest.err conftest.$ac_objext \ conftest$ac_exeext conftest.$ac_ext fi eval ac_res=\$$3 { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5 $as_echo "$ac_res" >&6; } eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno } # ac_fn_c_check_func # ac_fn_c_check_type LINENO TYPE VAR INCLUDES # ------------------------------------------- # Tests whether TYPE exists after having included INCLUDES, setting cache # variable VAR accordingly. ac_fn_c_check_type () { as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $2" >&5 $as_echo_n "checking for $2... " >&6; } if eval \${$3+:} false; then : $as_echo_n "(cached) " >&6 else eval "$3=no" cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ $4 int main () { if (sizeof ($2)) return 0; ; return 0; } _ACEOF if ac_fn_c_try_compile "$LINENO"; then : cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ $4 int main () { if (sizeof (($2))) return 0; ; return 0; } _ACEOF if ac_fn_c_try_compile "$LINENO"; then : else eval "$3=yes" fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext fi eval ac_res=\$$3 { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5 $as_echo "$ac_res" >&6; } eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno } # ac_fn_c_check_type # ac_fn_cxx_try_compile LINENO # ---------------------------- # Try to compile conftest.$ac_ext, and return whether this succeeded. ac_fn_cxx_try_compile () { as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack rm -f conftest.$ac_objext if { { ac_try="$ac_compile" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" $as_echo "$ac_try_echo"; } >&5 (eval "$ac_compile") 2>conftest.err ac_status=$? if test -s conftest.err; then grep -v '^ *+' conftest.err >conftest.er1 cat conftest.er1 >&5 mv -f conftest.er1 conftest.err fi $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 test $ac_status = 0; } && { test -z "$ac_cxx_werror_flag" || test ! -s conftest.err } && test -s conftest.$ac_objext; then : ac_retval=0 else $as_echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 ac_retval=1 fi eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno as_fn_set_status $ac_retval } # ac_fn_cxx_try_compile # ac_fn_cxx_try_link LINENO # ------------------------- # Try to link conftest.$ac_ext, and return whether this succeeded. ac_fn_cxx_try_link () { as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack rm -f conftest.$ac_objext conftest$ac_exeext if { { ac_try="$ac_link" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" $as_echo "$ac_try_echo"; } >&5 (eval "$ac_link") 2>conftest.err ac_status=$? if test -s conftest.err; then grep -v '^ *+' conftest.err >conftest.er1 cat conftest.er1 >&5 mv -f conftest.er1 conftest.err fi $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 test $ac_status = 0; } && { test -z "$ac_cxx_werror_flag" || test ! -s conftest.err } && test -s conftest$ac_exeext && { test "$cross_compiling" = yes || test -x conftest$ac_exeext }; then : ac_retval=0 else $as_echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 ac_retval=1 fi # Delete the IPA/IPO (Inter Procedural Analysis/Optimization) information # created by the PGI compiler (conftest_ipa8_conftest.oo), as it would # interfere with the next link command; also delete a directory that is # left behind by Apple's compiler. We do this before executing the actions. rm -rf conftest.dSYM conftest_ipa8_conftest.oo eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno as_fn_set_status $ac_retval } # ac_fn_cxx_try_link cat >config.log <<_ACEOF This file contains any messages produced by compilers while running configure, to aid debugging if configure makes a mistake. It was created by openchange $as_me 2.0, which was generated by GNU Autoconf 2.69. Invocation command line was $ $0 $@ _ACEOF exec 5>>config.log { cat <<_ASUNAME ## --------- ## ## Platform. ## ## --------- ## hostname = `(hostname || uname -n) 2>/dev/null | sed 1q` uname -m = `(uname -m) 2>/dev/null || echo unknown` uname -r = `(uname -r) 2>/dev/null || echo unknown` uname -s = `(uname -s) 2>/dev/null || echo unknown` uname -v = `(uname -v) 2>/dev/null || echo unknown` /usr/bin/uname -p = `(/usr/bin/uname -p) 2>/dev/null || echo unknown` /bin/uname -X = `(/bin/uname -X) 2>/dev/null || echo unknown` /bin/arch = `(/bin/arch) 2>/dev/null || echo unknown` /usr/bin/arch -k = `(/usr/bin/arch -k) 2>/dev/null || echo unknown` /usr/convex/getsysinfo = `(/usr/convex/getsysinfo) 2>/dev/null || echo unknown` /usr/bin/hostinfo = `(/usr/bin/hostinfo) 2>/dev/null || echo unknown` /bin/machine = `(/bin/machine) 2>/dev/null || echo unknown` /usr/bin/oslevel = `(/usr/bin/oslevel) 2>/dev/null || echo unknown` /bin/universe = `(/bin/universe) 2>/dev/null || echo unknown` _ASUNAME as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. $as_echo "PATH: $as_dir" done IFS=$as_save_IFS } >&5 cat >&5 <<_ACEOF ## ----------- ## ## Core tests. ## ## ----------- ## _ACEOF # Keep a trace of the command line. # Strip out --no-create and --no-recursion so they do not pile up. # Strip out --silent because we don't want to record it for future runs. # Also quote any args containing shell meta-characters. # Make two passes to allow for proper duplicate-argument suppression. ac_configure_args= ac_configure_args0= ac_configure_args1= ac_must_keep_next=false for ac_pass in 1 2 do for ac_arg do case $ac_arg in -no-create | --no-c* | -n | -no-recursion | --no-r*) continue ;; -q | -quiet | --quiet | --quie | --qui | --qu | --q \ | -silent | --silent | --silen | --sile | --sil) continue ;; *\'*) ac_arg=`$as_echo "$ac_arg" | sed "s/'/'\\\\\\\\''/g"` ;; esac case $ac_pass in 1) as_fn_append ac_configure_args0 " '$ac_arg'" ;; 2) as_fn_append ac_configure_args1 " '$ac_arg'" if test $ac_must_keep_next = true; then ac_must_keep_next=false # Got value, back to normal. else case $ac_arg in *=* | --config-cache | -C | -disable-* | --disable-* \ | -enable-* | --enable-* | -gas | --g* | -nfp | --nf* \ | -q | -quiet | --q* | -silent | --sil* | -v | -verb* \ | -with-* | --with-* | -without-* | --without-* | --x) case "$ac_configure_args0 " in "$ac_configure_args1"*" '$ac_arg' "* ) continue ;; esac ;; -* ) ac_must_keep_next=true ;; esac fi as_fn_append ac_configure_args " '$ac_arg'" ;; esac done done { ac_configure_args0=; unset ac_configure_args0;} { ac_configure_args1=; unset ac_configure_args1;} # When interrupted or exit'd, cleanup temporary files, and complete # config.log. We remove comments because anyway the quotes in there # would cause problems or look ugly. # WARNING: Use '\'' to represent an apostrophe within the trap. # WARNING: Do not start the trap code with a newline, due to a FreeBSD 4.0 bug. trap 'exit_status=$? # Save into config.log some information that might help in debugging. { echo $as_echo "## ---------------- ## ## Cache variables. ## ## ---------------- ##" echo # The following way of writing the cache mishandles newlines in values, ( for ac_var in `(set) 2>&1 | sed -n '\''s/^\([a-zA-Z_][a-zA-Z0-9_]*\)=.*/\1/p'\''`; do eval ac_val=\$$ac_var case $ac_val in #( *${as_nl}*) case $ac_var in #( *_cv_*) { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: cache variable $ac_var contains a newline" >&5 $as_echo "$as_me: WARNING: cache variable $ac_var contains a newline" >&2;} ;; esac case $ac_var in #( _ | IFS | as_nl) ;; #( BASH_ARGV | BASH_SOURCE) eval $ac_var= ;; #( *) { eval $ac_var=; unset $ac_var;} ;; esac ;; esac done (set) 2>&1 | case $as_nl`(ac_space='\'' '\''; set) 2>&1` in #( *${as_nl}ac_space=\ *) sed -n \ "s/'\''/'\''\\\\'\'''\''/g; s/^\\([_$as_cr_alnum]*_cv_[_$as_cr_alnum]*\\)=\\(.*\\)/\\1='\''\\2'\''/p" ;; #( *) sed -n "/^[_$as_cr_alnum]*_cv_[_$as_cr_alnum]*=/p" ;; esac | sort ) echo $as_echo "## ----------------- ## ## Output variables. ## ## ----------------- ##" echo for ac_var in $ac_subst_vars do eval ac_val=\$$ac_var case $ac_val in *\'\''*) ac_val=`$as_echo "$ac_val" | sed "s/'\''/'\''\\\\\\\\'\'''\''/g"`;; esac $as_echo "$ac_var='\''$ac_val'\''" done | sort echo if test -n "$ac_subst_files"; then $as_echo "## ------------------- ## ## File substitutions. ## ## ------------------- ##" echo for ac_var in $ac_subst_files do eval ac_val=\$$ac_var case $ac_val in *\'\''*) ac_val=`$as_echo "$ac_val" | sed "s/'\''/'\''\\\\\\\\'\'''\''/g"`;; esac $as_echo "$ac_var='\''$ac_val'\''" done | sort echo fi if test -s confdefs.h; then $as_echo "## ----------- ## ## confdefs.h. ## ## ----------- ##" echo cat confdefs.h echo fi test "$ac_signal" != 0 && $as_echo "$as_me: caught signal $ac_signal" $as_echo "$as_me: exit $exit_status" } >&5 rm -f core *.core core.conftest.* && rm -f -r conftest* confdefs* conf$$* $ac_clean_files && exit $exit_status ' 0 for ac_signal in 1 2 13 15; do trap 'ac_signal='$ac_signal'; as_fn_exit 1' $ac_signal done ac_signal=0 # confdefs.h avoids OS command line length limits that DEFS can exceed. rm -f -r conftest* confdefs.h $as_echo "/* confdefs.h */" > confdefs.h # Predefined preprocessor variables. cat >>confdefs.h <<_ACEOF #define PACKAGE_NAME "$PACKAGE_NAME" _ACEOF cat >>confdefs.h <<_ACEOF #define PACKAGE_TARNAME "$PACKAGE_TARNAME" _ACEOF cat >>confdefs.h <<_ACEOF #define PACKAGE_VERSION "$PACKAGE_VERSION" _ACEOF cat >>confdefs.h <<_ACEOF #define PACKAGE_STRING "$PACKAGE_STRING" _ACEOF cat >>confdefs.h <<_ACEOF #define PACKAGE_BUGREPORT "$PACKAGE_BUGREPORT" _ACEOF cat >>confdefs.h <<_ACEOF #define PACKAGE_URL "$PACKAGE_URL" _ACEOF # Let the site file select an alternate cache file if it wants to. # Prefer an explicitly selected file to automatically selected ones. ac_site_file1=NONE ac_site_file2=NONE if test -n "$CONFIG_SITE"; then # We do not want a PATH search for config.site. case $CONFIG_SITE in #(( -*) ac_site_file1=./$CONFIG_SITE;; */*) ac_site_file1=$CONFIG_SITE;; *) ac_site_file1=./$CONFIG_SITE;; esac elif test "x$prefix" != xNONE; then ac_site_file1=$prefix/share/config.site ac_site_file2=$prefix/etc/config.site else ac_site_file1=$ac_default_prefix/share/config.site ac_site_file2=$ac_default_prefix/etc/config.site fi for ac_site_file in "$ac_site_file1" "$ac_site_file2" do test "x$ac_site_file" = xNONE && continue if test /dev/null != "$ac_site_file" && test -r "$ac_site_file"; then { $as_echo "$as_me:${as_lineno-$LINENO}: loading site script $ac_site_file" >&5 $as_echo "$as_me: loading site script $ac_site_file" >&6;} sed 's/^/| /' "$ac_site_file" >&5 . "$ac_site_file" \ || { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 $as_echo "$as_me: error: in \`$ac_pwd':" >&2;} as_fn_error $? "failed to load site script $ac_site_file See \`config.log' for more details" "$LINENO" 5; } fi done if test -r "$cache_file"; then # Some versions of bash will fail to source /dev/null (special files # actually), so we avoid doing that. DJGPP emulates it as a regular file. if test /dev/null != "$cache_file" && test -f "$cache_file"; then { $as_echo "$as_me:${as_lineno-$LINENO}: loading cache $cache_file" >&5 $as_echo "$as_me: loading cache $cache_file" >&6;} case $cache_file in [\\/]* | ?:[\\/]* ) . "$cache_file";; *) . "./$cache_file";; esac fi else { $as_echo "$as_me:${as_lineno-$LINENO}: creating cache $cache_file" >&5 $as_echo "$as_me: creating cache $cache_file" >&6;} >$cache_file fi # Check that the precious variables saved in the cache have kept the same # value. ac_cache_corrupted=false for ac_var in $ac_precious_vars; do eval ac_old_set=\$ac_cv_env_${ac_var}_set eval ac_new_set=\$ac_env_${ac_var}_set eval ac_old_val=\$ac_cv_env_${ac_var}_value eval ac_new_val=\$ac_env_${ac_var}_value case $ac_old_set,$ac_new_set in set,) { $as_echo "$as_me:${as_lineno-$LINENO}: error: \`$ac_var' was set to \`$ac_old_val' in the previous run" >&5 $as_echo "$as_me: error: \`$ac_var' was set to \`$ac_old_val' in the previous run" >&2;} ac_cache_corrupted=: ;; ,set) { $as_echo "$as_me:${as_lineno-$LINENO}: error: \`$ac_var' was not set in the previous run" >&5 $as_echo "$as_me: error: \`$ac_var' was not set in the previous run" >&2;} ac_cache_corrupted=: ;; ,);; *) if test "x$ac_old_val" != "x$ac_new_val"; then # differences in whitespace do not lead to failure. ac_old_val_w=`echo x $ac_old_val` ac_new_val_w=`echo x $ac_new_val` if test "$ac_old_val_w" != "$ac_new_val_w"; then { $as_echo "$as_me:${as_lineno-$LINENO}: error: \`$ac_var' has changed since the previous run:" >&5 $as_echo "$as_me: error: \`$ac_var' has changed since the previous run:" >&2;} ac_cache_corrupted=: else { $as_echo "$as_me:${as_lineno-$LINENO}: warning: ignoring whitespace changes in \`$ac_var' since the previous run:" >&5 $as_echo "$as_me: warning: ignoring whitespace changes in \`$ac_var' since the previous run:" >&2;} eval $ac_var=\$ac_old_val fi { $as_echo "$as_me:${as_lineno-$LINENO}: former value: \`$ac_old_val'" >&5 $as_echo "$as_me: former value: \`$ac_old_val'" >&2;} { $as_echo "$as_me:${as_lineno-$LINENO}: current value: \`$ac_new_val'" >&5 $as_echo "$as_me: current value: \`$ac_new_val'" >&2;} fi;; esac # Pass precious variables to config.status. if test "$ac_new_set" = set; then case $ac_new_val in *\'*) ac_arg=$ac_var=`$as_echo "$ac_new_val" | sed "s/'/'\\\\\\\\''/g"` ;; *) ac_arg=$ac_var=$ac_new_val ;; esac case " $ac_configure_args " in *" '$ac_arg' "*) ;; # Avoid dups. Use of quotes ensures accuracy. *) as_fn_append ac_configure_args " '$ac_arg'" ;; esac fi done if $ac_cache_corrupted; then { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 $as_echo "$as_me: error: in \`$ac_pwd':" >&2;} { $as_echo "$as_me:${as_lineno-$LINENO}: error: changes in the environment can compromise the build" >&5 $as_echo "$as_me: error: changes in the environment can compromise the build" >&2;} as_fn_error $? "run \`make distclean' and/or \`rm $cache_file' and start over" "$LINENO" 5 fi ## -------------------- ## ## Main body of script. ## ## -------------------- ## ac_ext=c ac_cpp='$CPP $CPPFLAGS' ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' ac_compiler_gnu=$ac_cv_c_compiler_gnu ac_config_headers="$ac_config_headers config.h" am__api_version='1.11' ac_aux_dir= for ac_dir in "$srcdir" "$srcdir/.." "$srcdir/../.."; do if test -f "$ac_dir/install-sh"; then ac_aux_dir=$ac_dir ac_install_sh="$ac_aux_dir/install-sh -c" break elif test -f "$ac_dir/install.sh"; then ac_aux_dir=$ac_dir ac_install_sh="$ac_aux_dir/install.sh -c" break elif test -f "$ac_dir/shtool"; then ac_aux_dir=$ac_dir ac_install_sh="$ac_aux_dir/shtool install -c" break fi done if test -z "$ac_aux_dir"; then as_fn_error $? "cannot find install-sh, install.sh, or shtool in \"$srcdir\" \"$srcdir/..\" \"$srcdir/../..\"" "$LINENO" 5 fi # These three variables are undocumented and unsupported, # and are intended to be withdrawn in a future Autoconf release. # They can cause serious problems if a builder's source tree is in a directory # whose full name contains unusual characters. ac_config_guess="$SHELL $ac_aux_dir/config.guess" # Please don't use this var. ac_config_sub="$SHELL $ac_aux_dir/config.sub" # Please don't use this var. ac_configure="$SHELL $ac_aux_dir/configure" # Please don't use this var. # Find a good install program. We prefer a C program (faster), # so one script is as good as another. But avoid the broken or # incompatible versions: # SysV /etc/install, /usr/sbin/install # SunOS /usr/etc/install # IRIX /sbin/install # AIX /bin/install # AmigaOS /C/install, which installs bootblocks on floppy discs # AIX 4 /usr/bin/installbsd, which doesn't work without a -g flag # AFS /usr/afsws/bin/install, which mishandles nonexistent args # SVR4 /usr/ucb/install, which tries to use the nonexistent group "staff" # OS/2's system install, which has a completely different semantic # ./install, which can be erroneously created by make from ./install.sh. # Reject install programs that cannot install multiple files. { $as_echo "$as_me:${as_lineno-$LINENO}: checking for a BSD-compatible install" >&5 $as_echo_n "checking for a BSD-compatible install... " >&6; } if test -z "$INSTALL"; then if ${ac_cv_path_install+:} false; then : $as_echo_n "(cached) " >&6 else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. # Account for people who put trailing slashes in PATH elements. case $as_dir/ in #(( ./ | .// | /[cC]/* | \ /etc/* | /usr/sbin/* | /usr/etc/* | /sbin/* | /usr/afsws/bin/* | \ ?:[\\/]os2[\\/]install[\\/]* | ?:[\\/]OS2[\\/]INSTALL[\\/]* | \ /usr/ucb/* ) ;; *) # OSF1 and SCO ODT 3.0 have their own names for install. # Don't use installbsd from OSF since it installs stuff as root # by default. for ac_prog in ginstall scoinst install; do for ac_exec_ext in '' $ac_executable_extensions; do if as_fn_executable_p "$as_dir/$ac_prog$ac_exec_ext"; then if test $ac_prog = install && grep dspmsg "$as_dir/$ac_prog$ac_exec_ext" >/dev/null 2>&1; then # AIX install. It has an incompatible calling convention. : elif test $ac_prog = install && grep pwplus "$as_dir/$ac_prog$ac_exec_ext" >/dev/null 2>&1; then # program-specific install script used by HP pwplus--don't use. : else rm -rf conftest.one conftest.two conftest.dir echo one > conftest.one echo two > conftest.two mkdir conftest.dir if "$as_dir/$ac_prog$ac_exec_ext" -c conftest.one conftest.two "`pwd`/conftest.dir" && test -s conftest.one && test -s conftest.two && test -s conftest.dir/conftest.one && test -s conftest.dir/conftest.two then ac_cv_path_install="$as_dir/$ac_prog$ac_exec_ext -c" break 3 fi fi fi done done ;; esac done IFS=$as_save_IFS rm -rf conftest.one conftest.two conftest.dir fi if test "${ac_cv_path_install+set}" = set; then INSTALL=$ac_cv_path_install else # As a last resort, use the slow shell script. Don't cache a # value for INSTALL within a source directory, because that will # break other packages using the cache if that directory is # removed, or if the value is a relative name. INSTALL=$ac_install_sh fi fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $INSTALL" >&5 $as_echo "$INSTALL" >&6; } # Use test -z because SunOS4 sh mishandles braces in ${var-val}. # It thinks the first close brace ends the variable substitution. test -z "$INSTALL_PROGRAM" && INSTALL_PROGRAM='${INSTALL}' test -z "$INSTALL_SCRIPT" && INSTALL_SCRIPT='${INSTALL}' test -z "$INSTALL_DATA" && INSTALL_DATA='${INSTALL} -m 644' { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether build environment is sane" >&5 $as_echo_n "checking whether build environment is sane... " >&6; } # Just in case sleep 1 echo timestamp > conftest.file # Reject unsafe characters in $srcdir or the absolute working directory # name. Accept space and tab only in the latter. am_lf=' ' case `pwd` in *[\\\"\#\$\&\'\`$am_lf]*) as_fn_error $? "unsafe absolute working directory name" "$LINENO" 5;; esac case $srcdir in *[\\\"\#\$\&\'\`$am_lf\ \ ]*) as_fn_error $? "unsafe srcdir value: \`$srcdir'" "$LINENO" 5;; esac # Do `set' in a subshell so we don't clobber the current shell's # arguments. Must try -L first in case configure is actually a # symlink; some systems play weird games with the mod time of symlinks # (eg FreeBSD returns the mod time of the symlink's containing # directory). if ( set X `ls -Lt "$srcdir/configure" conftest.file 2> /dev/null` if test "$*" = "X"; then # -L didn't work. set X `ls -t "$srcdir/configure" conftest.file` fi rm -f conftest.file if test "$*" != "X $srcdir/configure conftest.file" \ && test "$*" != "X conftest.file $srcdir/configure"; then # If neither matched, then we have a broken ls. This can happen # if, for instance, CONFIG_SHELL is bash and it inherits a # broken ls alias from the environment. This has actually # happened. Such a system could not be considered "sane". as_fn_error $? "ls -t appears to fail. Make sure there is not a broken alias in your environment" "$LINENO" 5 fi test "$2" = conftest.file ) then # Ok. : else as_fn_error $? "newly created file is older than distributed files! Check your system clock" "$LINENO" 5 fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 $as_echo "yes" >&6; } test "$program_prefix" != NONE && program_transform_name="s&^&$program_prefix&;$program_transform_name" # Use a double $ so make ignores it. test "$program_suffix" != NONE && program_transform_name="s&\$&$program_suffix&;$program_transform_name" # Double any \ or $. # By default was `s,x,x', remove it if useless. ac_script='s/[\\$]/&&/g;s/;s,x,x,$//' program_transform_name=`$as_echo "$program_transform_name" | sed "$ac_script"` # expand $ac_aux_dir to an absolute path am_aux_dir=`cd $ac_aux_dir && pwd` if test x"${MISSING+set}" != xset; then case $am_aux_dir in *\ * | *\ *) MISSING="\${SHELL} \"$am_aux_dir/missing\"" ;; *) MISSING="\${SHELL} $am_aux_dir/missing" ;; esac fi # Use eval to expand $SHELL if eval "$MISSING --run true"; then am_missing_run="$MISSING --run " else am_missing_run= { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: \`missing' script is too old or missing" >&5 $as_echo "$as_me: WARNING: \`missing' script is too old or missing" >&2;} fi if test x"${install_sh}" != xset; then case $am_aux_dir in *\ * | *\ *) install_sh="\${SHELL} '$am_aux_dir/install-sh'" ;; *) install_sh="\${SHELL} $am_aux_dir/install-sh" esac fi # Installed binaries are usually stripped using `strip' when the user # run `make install-strip'. However `strip' might not be the right # tool to use in cross-compilation environments, therefore Automake # will honor the `STRIP' environment variable to overrule this program. if test "$cross_compiling" != no; then if test -n "$ac_tool_prefix"; then # Extract the first word of "${ac_tool_prefix}strip", so it can be a program name with args. set dummy ${ac_tool_prefix}strip; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } if ${ac_cv_prog_STRIP+:} false; then : $as_echo_n "(cached) " >&6 else if test -n "$STRIP"; then ac_cv_prog_STRIP="$STRIP" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then ac_cv_prog_STRIP="${ac_tool_prefix}strip" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS fi fi STRIP=$ac_cv_prog_STRIP if test -n "$STRIP"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: $STRIP" >&5 $as_echo "$STRIP" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi fi if test -z "$ac_cv_prog_STRIP"; then ac_ct_STRIP=$STRIP # Extract the first word of "strip", so it can be a program name with args. set dummy strip; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } if ${ac_cv_prog_ac_ct_STRIP+:} false; then : $as_echo_n "(cached) " >&6 else if test -n "$ac_ct_STRIP"; then ac_cv_prog_ac_ct_STRIP="$ac_ct_STRIP" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then ac_cv_prog_ac_ct_STRIP="strip" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS fi fi ac_ct_STRIP=$ac_cv_prog_ac_ct_STRIP if test -n "$ac_ct_STRIP"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_STRIP" >&5 $as_echo "$ac_ct_STRIP" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi if test "x$ac_ct_STRIP" = x; then STRIP=":" else case $cross_compiling:$ac_tool_warned in yes:) { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 $as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} ac_tool_warned=yes ;; esac STRIP=$ac_ct_STRIP fi else STRIP="$ac_cv_prog_STRIP" fi fi INSTALL_STRIP_PROGRAM="\$(install_sh) -c -s" { $as_echo "$as_me:${as_lineno-$LINENO}: checking for a thread-safe mkdir -p" >&5 $as_echo_n "checking for a thread-safe mkdir -p... " >&6; } if test -z "$MKDIR_P"; then if ${ac_cv_path_mkdir+:} false; then : $as_echo_n "(cached) " >&6 else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH$PATH_SEPARATOR/opt/sfw/bin do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_prog in mkdir gmkdir; do for ac_exec_ext in '' $ac_executable_extensions; do as_fn_executable_p "$as_dir/$ac_prog$ac_exec_ext" || continue case `"$as_dir/$ac_prog$ac_exec_ext" --version 2>&1` in #( 'mkdir (GNU coreutils) '* | \ 'mkdir (coreutils) '* | \ 'mkdir (fileutils) '4.1*) ac_cv_path_mkdir=$as_dir/$ac_prog$ac_exec_ext break 3;; esac done done done IFS=$as_save_IFS fi test -d ./--version && rmdir ./--version if test "${ac_cv_path_mkdir+set}" = set; then MKDIR_P="$ac_cv_path_mkdir -p" else # As a last resort, use the slow shell script. Don't cache a # value for MKDIR_P within a source directory, because that will # break other packages using the cache if that directory is # removed, or if the value is a relative name. MKDIR_P="$ac_install_sh -d" fi fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $MKDIR_P" >&5 $as_echo "$MKDIR_P" >&6; } mkdir_p="$MKDIR_P" case $mkdir_p in [\\/$]* | ?:[\\/]*) ;; */*) mkdir_p="\$(top_builddir)/$mkdir_p" ;; esac for ac_prog in gawk mawk nawk awk do # Extract the first word of "$ac_prog", so it can be a program name with args. set dummy $ac_prog; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } if ${ac_cv_prog_AWK+:} false; then : $as_echo_n "(cached) " >&6 else if test -n "$AWK"; then ac_cv_prog_AWK="$AWK" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then ac_cv_prog_AWK="$ac_prog" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS fi fi AWK=$ac_cv_prog_AWK if test -n "$AWK"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: $AWK" >&5 $as_echo "$AWK" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi test -n "$AWK" && break done { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether ${MAKE-make} sets \$(MAKE)" >&5 $as_echo_n "checking whether ${MAKE-make} sets \$(MAKE)... " >&6; } set x ${MAKE-make} ac_make=`$as_echo "$2" | sed 's/+/p/g; s/[^a-zA-Z0-9_]/_/g'` if eval \${ac_cv_prog_make_${ac_make}_set+:} false; then : $as_echo_n "(cached) " >&6 else cat >conftest.make <<\_ACEOF SHELL = /bin/sh all: @echo '@@@%%%=$(MAKE)=@@@%%%' _ACEOF # GNU make sometimes prints "make[1]: Entering ...", which would confuse us. case `${MAKE-make} -f conftest.make 2>/dev/null` in *@@@%%%=?*=@@@%%%*) eval ac_cv_prog_make_${ac_make}_set=yes;; *) eval ac_cv_prog_make_${ac_make}_set=no;; esac rm -f conftest.make fi if eval test \$ac_cv_prog_make_${ac_make}_set = yes; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 $as_echo "yes" >&6; } SET_MAKE= else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } SET_MAKE="MAKE=${MAKE-make}" fi rm -rf .tst 2>/dev/null mkdir .tst 2>/dev/null if test -d .tst; then am__leading_dot=. else am__leading_dot=_ fi rmdir .tst 2>/dev/null if test "`cd $srcdir && pwd`" != "`pwd`"; then # Use -I$(srcdir) only when $(srcdir) != ., so that make's output # is not polluted with repeated "-I." am__isrc=' -I$(srcdir)' # test to see if srcdir already configured if test -f $srcdir/config.status; then as_fn_error $? "source directory already configured; run \"make distclean\" there first" "$LINENO" 5 fi fi # test whether we have cygpath if test -z "$CYGPATH_W"; then if (cygpath --version) >/dev/null 2>/dev/null; then CYGPATH_W='cygpath -w' else CYGPATH_W=echo fi fi # Define the identity of the package. PACKAGE='openchange' VERSION='2.0' cat >>confdefs.h <<_ACEOF #define PACKAGE "$PACKAGE" _ACEOF cat >>confdefs.h <<_ACEOF #define VERSION "$VERSION" _ACEOF # Some tools Automake needs. ACLOCAL=${ACLOCAL-"${am_missing_run}aclocal-${am__api_version}"} AUTOCONF=${AUTOCONF-"${am_missing_run}autoconf"} AUTOMAKE=${AUTOMAKE-"${am_missing_run}automake-${am__api_version}"} AUTOHEADER=${AUTOHEADER-"${am_missing_run}autoheader"} MAKEINFO=${MAKEINFO-"${am_missing_run}makeinfo"} # We need awk for the "check" target. The system "awk" is bad on # some platforms. # Always define AMTAR for backward compatibility. Yes, it's still used # in the wild :-( We should find a proper way to deprecate it ... AMTAR='$${TAR-tar}' am__tar='$${TAR-tar} chof - "$$tardir"' am__untar='$${TAR-tar} xf -' $as_echo "#define _GNU_SOURCE 1" >>confdefs.h if test "x$ac_cv_env_PKG_CONFIG_set" != "xset"; then if test -n "$ac_tool_prefix"; then # Extract the first word of "${ac_tool_prefix}pkg-config", so it can be a program name with args. set dummy ${ac_tool_prefix}pkg-config; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } if ${ac_cv_path_PKG_CONFIG+:} false; then : $as_echo_n "(cached) " >&6 else case $PKG_CONFIG in [\\/]* | ?:[\\/]*) ac_cv_path_PKG_CONFIG="$PKG_CONFIG" # Let the user override the test with a path. ;; *) as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then ac_cv_path_PKG_CONFIG="$as_dir/$ac_word$ac_exec_ext" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS ;; esac fi PKG_CONFIG=$ac_cv_path_PKG_CONFIG if test -n "$PKG_CONFIG"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: $PKG_CONFIG" >&5 $as_echo "$PKG_CONFIG" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi fi if test -z "$ac_cv_path_PKG_CONFIG"; then ac_pt_PKG_CONFIG=$PKG_CONFIG # Extract the first word of "pkg-config", so it can be a program name with args. set dummy pkg-config; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } if ${ac_cv_path_ac_pt_PKG_CONFIG+:} false; then : $as_echo_n "(cached) " >&6 else case $ac_pt_PKG_CONFIG in [\\/]* | ?:[\\/]*) ac_cv_path_ac_pt_PKG_CONFIG="$ac_pt_PKG_CONFIG" # Let the user override the test with a path. ;; *) as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then ac_cv_path_ac_pt_PKG_CONFIG="$as_dir/$ac_word$ac_exec_ext" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS ;; esac fi ac_pt_PKG_CONFIG=$ac_cv_path_ac_pt_PKG_CONFIG if test -n "$ac_pt_PKG_CONFIG"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_pt_PKG_CONFIG" >&5 $as_echo "$ac_pt_PKG_CONFIG" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi if test "x$ac_pt_PKG_CONFIG" = x; then PKG_CONFIG="" else case $cross_compiling:$ac_tool_warned in yes:) { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 $as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} ac_tool_warned=yes ;; esac PKG_CONFIG=$ac_pt_PKG_CONFIG fi else PKG_CONFIG="$ac_cv_path_PKG_CONFIG" fi fi if test -n "$PKG_CONFIG"; then _pkg_min_version=0.20 { $as_echo "$as_me:${as_lineno-$LINENO}: checking pkg-config is at least version $_pkg_min_version" >&5 $as_echo_n "checking pkg-config is at least version $_pkg_min_version... " >&6; } if $PKG_CONFIG --atleast-pkgconfig-version $_pkg_min_version; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 $as_echo "yes" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } PKG_CONFIG="" fi fi if test -z "$CFLAGS"; then CFLAGS="-g"; fi CFLAGS="-I. $CFLAGS" # Make sure we can run config.sub. $SHELL "$ac_aux_dir/config.sub" sun4 >/dev/null 2>&1 || as_fn_error $? "cannot run $SHELL $ac_aux_dir/config.sub" "$LINENO" 5 { $as_echo "$as_me:${as_lineno-$LINENO}: checking build system type" >&5 $as_echo_n "checking build system type... " >&6; } if ${ac_cv_build+:} false; then : $as_echo_n "(cached) " >&6 else ac_build_alias=$build_alias test "x$ac_build_alias" = x && ac_build_alias=`$SHELL "$ac_aux_dir/config.guess"` test "x$ac_build_alias" = x && as_fn_error $? "cannot guess build type; you must specify one" "$LINENO" 5 ac_cv_build=`$SHELL "$ac_aux_dir/config.sub" $ac_build_alias` || as_fn_error $? "$SHELL $ac_aux_dir/config.sub $ac_build_alias failed" "$LINENO" 5 fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_build" >&5 $as_echo "$ac_cv_build" >&6; } case $ac_cv_build in *-*-*) ;; *) as_fn_error $? "invalid value of canonical build" "$LINENO" 5;; esac build=$ac_cv_build ac_save_IFS=$IFS; IFS='-' set x $ac_cv_build shift build_cpu=$1 build_vendor=$2 shift; shift # Remember, the first character of IFS is used to create $*, # except with old shells: build_os=$* IFS=$ac_save_IFS case $build_os in *\ *) build_os=`echo "$build_os" | sed 's/ /-/g'`;; esac { $as_echo "$as_me:${as_lineno-$LINENO}: checking host system type" >&5 $as_echo_n "checking host system type... " >&6; } if ${ac_cv_host+:} false; then : $as_echo_n "(cached) " >&6 else if test "x$host_alias" = x; then ac_cv_host=$ac_cv_build else ac_cv_host=`$SHELL "$ac_aux_dir/config.sub" $host_alias` || as_fn_error $? "$SHELL $ac_aux_dir/config.sub $host_alias failed" "$LINENO" 5 fi fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_host" >&5 $as_echo "$ac_cv_host" >&6; } case $ac_cv_host in *-*-*) ;; *) as_fn_error $? "invalid value of canonical host" "$LINENO" 5;; esac host=$ac_cv_host ac_save_IFS=$IFS; IFS='-' set x $ac_cv_host shift host_cpu=$1 host_vendor=$2 shift; shift # Remember, the first character of IFS is used to create $*, # except with old shells: host_os=$* IFS=$ac_save_IFS case $host_os in *\ *) host_os=`echo "$host_os" | sed 's/ /-/g'`;; esac case "${host}" in *freebsd*) BUILD_FOR_FREEBSD=yes MANUALLY_CREATE_SYMLINKS=yes ;; *solaris*) BUILD_FOR_SOLARIS=yes MANUALLY_CREATE_SYMLINKS=yes ;; esac # # OC_CHECK_SAMBA_PATH([PATH],[action-if-found],[action-if-not-found]) # ------------------------------------------------------------------- { $as_echo "$as_me:${as_lineno-$LINENO}: checking for samba 4" >&5 $as_echo_n "checking for samba 4... " >&6; } # Check whether --with-samba was given. if test "${with_samba+set}" = set; then : withval=$with_samba; sambaprefix="$withval" else for p in "$prefix" /usr/local/samba /usr/local /usr do old_PKG_CONFIG_PATH="$PKG_CONFIG_PATH" PKG_CONFIG_PATH="$p/lib64/pkgconfig:$p/lib/pkgconfig${PKG_CONFIG_PATH:+:$PKG_CONFIG_PATH}" export PKG_CONFIG_PATH if test -n "$PKG_CONFIG" && \ { { $as_echo "$as_me:${as_lineno-$LINENO}: \$PKG_CONFIG --exists --print-errors \"samba-hostconfig\""; } >&5 ($PKG_CONFIG --exists --print-errors "samba-hostconfig") 2>&5 ac_status=$? $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 test $ac_status = 0; }; then found=1 else found=0 fi PKG_CONFIG_PATH="$old_PKG_CONFIG_PATH" if test $found = 1; then sambaprefix="$p" fi if test -n "${sambaprefix:-}"; then break fi done fi old_PKG_CONFIG_PATH="$PKG_CONFIG_PATH" PKG_CONFIG_PATH="$sambaprefix/lib64/pkgconfig:$sambaprefix/lib/pkgconfig${PKG_CONFIG_PATH:+:$PKG_CONFIG_PATH}" export PKG_CONFIG_PATH if test -n "$PKG_CONFIG" && \ { { $as_echo "$as_me:${as_lineno-$LINENO}: \$PKG_CONFIG --exists --print-errors \"samba-hostconfig\""; } >&5 ($PKG_CONFIG --exists --print-errors "samba-hostconfig") 2>&5 ac_status=$? $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 test $ac_status = 0; }; then found=1 else found=0 fi PKG_CONFIG_PATH="$old_PKG_CONFIG_PATH" if test $found = 1; then echo -n else as_fn_error $? "Samba 4 not found" "$LINENO" 5 fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $sambaprefix" >&5 $as_echo "$sambaprefix" >&6; } PKG_CONFIG_PATH="$sambaprefix/lib/pkgconfig:$PKG_CONFIG_PATH" PATH="$sambaprefix/bin:$PATH" # # OC_SETVAL([NAME]) # ----------------- # # OC_CHECK_SAMBA_VERSION([RELEASE],[VERSION], [action-if-found],[action-if-not-found], # [action-if-cross-compiling]) # ------------------------------------------------------------------------------------ # # OC_RULE_ADD([NAME], [TYPE]) # --------------------------- DEPDIR="${am__leading_dot}deps" ac_config_commands="$ac_config_commands depfiles" am_make=${MAKE-make} cat > confinc << 'END' am__doit: @echo this is the am__doit target .PHONY: am__doit END # If we don't find an include directive, just comment out the code. { $as_echo "$as_me:${as_lineno-$LINENO}: checking for style of include used by $am_make" >&5 $as_echo_n "checking for style of include used by $am_make... " >&6; } am__include="#" am__quote= _am_result=none # First try GNU make style include. echo "include confinc" > confmf # Ignore all kinds of additional output from `make'. case `$am_make -s -f confmf 2> /dev/null` in #( *the\ am__doit\ target*) am__include=include am__quote= _am_result=GNU ;; esac # Now try BSD make style include. if test "$am__include" = "#"; then echo '.include "confinc"' > confmf case `$am_make -s -f confmf 2> /dev/null` in #( *the\ am__doit\ target*) am__include=.include am__quote="\"" _am_result=BSD ;; esac fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $_am_result" >&5 $as_echo "$_am_result" >&6; } rm -f confinc confmf # Check whether --enable-dependency-tracking was given. if test "${enable_dependency_tracking+set}" = set; then : enableval=$enable_dependency_tracking; fi if test "x$enable_dependency_tracking" != xno; then am_depcomp="$ac_aux_dir/depcomp" AMDEPBACKSLASH='\' am__nodep='_no' fi if test "x$enable_dependency_tracking" != xno; then AMDEP_TRUE= AMDEP_FALSE='#' else AMDEP_TRUE='#' AMDEP_FALSE= fi ac_ext=c ac_cpp='$CPP $CPPFLAGS' ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' ac_compiler_gnu=$ac_cv_c_compiler_gnu if test -n "$ac_tool_prefix"; then # Extract the first word of "${ac_tool_prefix}gcc", so it can be a program name with args. set dummy ${ac_tool_prefix}gcc; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } if ${ac_cv_prog_CC+:} false; then : $as_echo_n "(cached) " >&6 else if test -n "$CC"; then ac_cv_prog_CC="$CC" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then ac_cv_prog_CC="${ac_tool_prefix}gcc" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS fi fi CC=$ac_cv_prog_CC if test -n "$CC"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: $CC" >&5 $as_echo "$CC" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi fi if test -z "$ac_cv_prog_CC"; then ac_ct_CC=$CC # Extract the first word of "gcc", so it can be a program name with args. set dummy gcc; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } if ${ac_cv_prog_ac_ct_CC+:} false; then : $as_echo_n "(cached) " >&6 else if test -n "$ac_ct_CC"; then ac_cv_prog_ac_ct_CC="$ac_ct_CC" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then ac_cv_prog_ac_ct_CC="gcc" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS fi fi ac_ct_CC=$ac_cv_prog_ac_ct_CC if test -n "$ac_ct_CC"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_CC" >&5 $as_echo "$ac_ct_CC" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi if test "x$ac_ct_CC" = x; then CC="" else case $cross_compiling:$ac_tool_warned in yes:) { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 $as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} ac_tool_warned=yes ;; esac CC=$ac_ct_CC fi else CC="$ac_cv_prog_CC" fi if test -z "$CC"; then if test -n "$ac_tool_prefix"; then # Extract the first word of "${ac_tool_prefix}cc", so it can be a program name with args. set dummy ${ac_tool_prefix}cc; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } if ${ac_cv_prog_CC+:} false; then : $as_echo_n "(cached) " >&6 else if test -n "$CC"; then ac_cv_prog_CC="$CC" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then ac_cv_prog_CC="${ac_tool_prefix}cc" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS fi fi CC=$ac_cv_prog_CC if test -n "$CC"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: $CC" >&5 $as_echo "$CC" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi fi fi if test -z "$CC"; then # Extract the first word of "cc", so it can be a program name with args. set dummy cc; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } if ${ac_cv_prog_CC+:} false; then : $as_echo_n "(cached) " >&6 else if test -n "$CC"; then ac_cv_prog_CC="$CC" # Let the user override the test. else ac_prog_rejected=no as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then if test "$as_dir/$ac_word$ac_exec_ext" = "/usr/ucb/cc"; then ac_prog_rejected=yes continue fi ac_cv_prog_CC="cc" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS if test $ac_prog_rejected = yes; then # We found a bogon in the path, so make sure we never use it. set dummy $ac_cv_prog_CC shift if test $# != 0; then # We chose a different compiler from the bogus one. # However, it has the same basename, so the bogon will be chosen # first if we set CC to just the basename; use the full file name. shift ac_cv_prog_CC="$as_dir/$ac_word${1+' '}$@" fi fi fi fi CC=$ac_cv_prog_CC if test -n "$CC"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: $CC" >&5 $as_echo "$CC" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi fi if test -z "$CC"; then if test -n "$ac_tool_prefix"; then for ac_prog in cl.exe do # Extract the first word of "$ac_tool_prefix$ac_prog", so it can be a program name with args. set dummy $ac_tool_prefix$ac_prog; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } if ${ac_cv_prog_CC+:} false; then : $as_echo_n "(cached) " >&6 else if test -n "$CC"; then ac_cv_prog_CC="$CC" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then ac_cv_prog_CC="$ac_tool_prefix$ac_prog" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS fi fi CC=$ac_cv_prog_CC if test -n "$CC"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: $CC" >&5 $as_echo "$CC" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi test -n "$CC" && break done fi if test -z "$CC"; then ac_ct_CC=$CC for ac_prog in cl.exe do # Extract the first word of "$ac_prog", so it can be a program name with args. set dummy $ac_prog; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } if ${ac_cv_prog_ac_ct_CC+:} false; then : $as_echo_n "(cached) " >&6 else if test -n "$ac_ct_CC"; then ac_cv_prog_ac_ct_CC="$ac_ct_CC" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then ac_cv_prog_ac_ct_CC="$ac_prog" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS fi fi ac_ct_CC=$ac_cv_prog_ac_ct_CC if test -n "$ac_ct_CC"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_CC" >&5 $as_echo "$ac_ct_CC" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi test -n "$ac_ct_CC" && break done if test "x$ac_ct_CC" = x; then CC="" else case $cross_compiling:$ac_tool_warned in yes:) { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 $as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} ac_tool_warned=yes ;; esac CC=$ac_ct_CC fi fi fi test -z "$CC" && { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 $as_echo "$as_me: error: in \`$ac_pwd':" >&2;} as_fn_error $? "no acceptable C compiler found in \$PATH See \`config.log' for more details" "$LINENO" 5; } # Provide some information about the compiler. $as_echo "$as_me:${as_lineno-$LINENO}: checking for C compiler version" >&5 set X $ac_compile ac_compiler=$2 for ac_option in --version -v -V -qversion; do { { ac_try="$ac_compiler $ac_option >&5" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" $as_echo "$ac_try_echo"; } >&5 (eval "$ac_compiler $ac_option >&5") 2>conftest.err ac_status=$? if test -s conftest.err; then sed '10a\ ... rest of stderr output deleted ... 10q' conftest.err >conftest.er1 cat conftest.er1 >&5 fi rm -f conftest.er1 conftest.err $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 test $ac_status = 0; } done cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ int main () { ; return 0; } _ACEOF ac_clean_files_save=$ac_clean_files ac_clean_files="$ac_clean_files a.out a.out.dSYM a.exe b.out" # Try to create an executable without -o first, disregard a.out. # It will help us diagnose broken compilers, and finding out an intuition # of exeext. { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether the C compiler works" >&5 $as_echo_n "checking whether the C compiler works... " >&6; } ac_link_default=`$as_echo "$ac_link" | sed 's/ -o *conftest[^ ]*//'` # The possible output files: ac_files="a.out conftest.exe conftest a.exe a_out.exe b.out conftest.*" ac_rmfiles= for ac_file in $ac_files do case $ac_file in *.$ac_ext | *.xcoff | *.tds | *.d | *.pdb | *.xSYM | *.bb | *.bbg | *.map | *.inf | *.dSYM | *.o | *.obj ) ;; * ) ac_rmfiles="$ac_rmfiles $ac_file";; esac done rm -f $ac_rmfiles if { { ac_try="$ac_link_default" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" $as_echo "$ac_try_echo"; } >&5 (eval "$ac_link_default") 2>&5 ac_status=$? $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 test $ac_status = 0; }; then : # Autoconf-2.13 could set the ac_cv_exeext variable to `no'. # So ignore a value of `no', otherwise this would lead to `EXEEXT = no' # in a Makefile. We should not override ac_cv_exeext if it was cached, # so that the user can short-circuit this test for compilers unknown to # Autoconf. for ac_file in $ac_files '' do test -f "$ac_file" || continue case $ac_file in *.$ac_ext | *.xcoff | *.tds | *.d | *.pdb | *.xSYM | *.bb | *.bbg | *.map | *.inf | *.dSYM | *.o | *.obj ) ;; [ab].out ) # We found the default executable, but exeext='' is most # certainly right. break;; *.* ) if test "${ac_cv_exeext+set}" = set && test "$ac_cv_exeext" != no; then :; else ac_cv_exeext=`expr "$ac_file" : '[^.]*\(\..*\)'` fi # We set ac_cv_exeext here because the later test for it is not # safe: cross compilers may not add the suffix if given an `-o' # argument, so we may need to know it at that point already. # Even if this section looks crufty: it has the advantage of # actually working. break;; * ) break;; esac done test "$ac_cv_exeext" = no && ac_cv_exeext= else ac_file='' fi if test -z "$ac_file"; then : { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } $as_echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 $as_echo "$as_me: error: in \`$ac_pwd':" >&2;} as_fn_error 77 "C compiler cannot create executables See \`config.log' for more details" "$LINENO" 5; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 $as_echo "yes" >&6; } fi { $as_echo "$as_me:${as_lineno-$LINENO}: checking for C compiler default output file name" >&5 $as_echo_n "checking for C compiler default output file name... " >&6; } { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_file" >&5 $as_echo "$ac_file" >&6; } ac_exeext=$ac_cv_exeext rm -f -r a.out a.out.dSYM a.exe conftest$ac_cv_exeext b.out ac_clean_files=$ac_clean_files_save { $as_echo "$as_me:${as_lineno-$LINENO}: checking for suffix of executables" >&5 $as_echo_n "checking for suffix of executables... " >&6; } if { { ac_try="$ac_link" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" $as_echo "$ac_try_echo"; } >&5 (eval "$ac_link") 2>&5 ac_status=$? $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 test $ac_status = 0; }; then : # If both `conftest.exe' and `conftest' are `present' (well, observable) # catch `conftest.exe'. For instance with Cygwin, `ls conftest' will # work properly (i.e., refer to `conftest.exe'), while it won't with # `rm'. for ac_file in conftest.exe conftest conftest.*; do test -f "$ac_file" || continue case $ac_file in *.$ac_ext | *.xcoff | *.tds | *.d | *.pdb | *.xSYM | *.bb | *.bbg | *.map | *.inf | *.dSYM | *.o | *.obj ) ;; *.* ) ac_cv_exeext=`expr "$ac_file" : '[^.]*\(\..*\)'` break;; * ) break;; esac done else { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 $as_echo "$as_me: error: in \`$ac_pwd':" >&2;} as_fn_error $? "cannot compute suffix of executables: cannot compile and link See \`config.log' for more details" "$LINENO" 5; } fi rm -f conftest conftest$ac_cv_exeext { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_exeext" >&5 $as_echo "$ac_cv_exeext" >&6; } rm -f conftest.$ac_ext EXEEXT=$ac_cv_exeext ac_exeext=$EXEEXT cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include int main () { FILE *f = fopen ("conftest.out", "w"); return ferror (f) || fclose (f) != 0; ; return 0; } _ACEOF ac_clean_files="$ac_clean_files conftest.out" # Check that the compiler produces executables we can run. If not, either # the compiler is broken, or we cross compile. { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether we are cross compiling" >&5 $as_echo_n "checking whether we are cross compiling... " >&6; } if test "$cross_compiling" != yes; then { { ac_try="$ac_link" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" $as_echo "$ac_try_echo"; } >&5 (eval "$ac_link") 2>&5 ac_status=$? $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 test $ac_status = 0; } if { ac_try='./conftest$ac_cv_exeext' { { case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" $as_echo "$ac_try_echo"; } >&5 (eval "$ac_try") 2>&5 ac_status=$? $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 test $ac_status = 0; }; }; then cross_compiling=no else if test "$cross_compiling" = maybe; then cross_compiling=yes else { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 $as_echo "$as_me: error: in \`$ac_pwd':" >&2;} as_fn_error $? "cannot run C compiled programs. If you meant to cross compile, use \`--host'. See \`config.log' for more details" "$LINENO" 5; } fi fi fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $cross_compiling" >&5 $as_echo "$cross_compiling" >&6; } rm -f conftest.$ac_ext conftest$ac_cv_exeext conftest.out ac_clean_files=$ac_clean_files_save { $as_echo "$as_me:${as_lineno-$LINENO}: checking for suffix of object files" >&5 $as_echo_n "checking for suffix of object files... " >&6; } if ${ac_cv_objext+:} false; then : $as_echo_n "(cached) " >&6 else cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ int main () { ; return 0; } _ACEOF rm -f conftest.o conftest.obj if { { ac_try="$ac_compile" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" $as_echo "$ac_try_echo"; } >&5 (eval "$ac_compile") 2>&5 ac_status=$? $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 test $ac_status = 0; }; then : for ac_file in conftest.o conftest.obj conftest.*; do test -f "$ac_file" || continue; case $ac_file in *.$ac_ext | *.xcoff | *.tds | *.d | *.pdb | *.xSYM | *.bb | *.bbg | *.map | *.inf | *.dSYM ) ;; *) ac_cv_objext=`expr "$ac_file" : '.*\.\(.*\)'` break;; esac done else $as_echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 $as_echo "$as_me: error: in \`$ac_pwd':" >&2;} as_fn_error $? "cannot compute suffix of object files: cannot compile See \`config.log' for more details" "$LINENO" 5; } fi rm -f conftest.$ac_cv_objext conftest.$ac_ext fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_objext" >&5 $as_echo "$ac_cv_objext" >&6; } OBJEXT=$ac_cv_objext ac_objext=$OBJEXT { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether we are using the GNU C compiler" >&5 $as_echo_n "checking whether we are using the GNU C compiler... " >&6; } if ${ac_cv_c_compiler_gnu+:} false; then : $as_echo_n "(cached) " >&6 else cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ int main () { #ifndef __GNUC__ choke me #endif ; return 0; } _ACEOF if ac_fn_c_try_compile "$LINENO"; then : ac_compiler_gnu=yes else ac_compiler_gnu=no fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext ac_cv_c_compiler_gnu=$ac_compiler_gnu fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_c_compiler_gnu" >&5 $as_echo "$ac_cv_c_compiler_gnu" >&6; } if test $ac_compiler_gnu = yes; then GCC=yes else GCC= fi ac_test_CFLAGS=${CFLAGS+set} ac_save_CFLAGS=$CFLAGS { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether $CC accepts -g" >&5 $as_echo_n "checking whether $CC accepts -g... " >&6; } if ${ac_cv_prog_cc_g+:} false; then : $as_echo_n "(cached) " >&6 else ac_save_c_werror_flag=$ac_c_werror_flag ac_c_werror_flag=yes ac_cv_prog_cc_g=no CFLAGS="-g" cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ int main () { ; return 0; } _ACEOF if ac_fn_c_try_compile "$LINENO"; then : ac_cv_prog_cc_g=yes else CFLAGS="" cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ int main () { ; return 0; } _ACEOF if ac_fn_c_try_compile "$LINENO"; then : else ac_c_werror_flag=$ac_save_c_werror_flag CFLAGS="-g" cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ int main () { ; return 0; } _ACEOF if ac_fn_c_try_compile "$LINENO"; then : ac_cv_prog_cc_g=yes fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext ac_c_werror_flag=$ac_save_c_werror_flag fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_prog_cc_g" >&5 $as_echo "$ac_cv_prog_cc_g" >&6; } if test "$ac_test_CFLAGS" = set; then CFLAGS=$ac_save_CFLAGS elif test $ac_cv_prog_cc_g = yes; then if test "$GCC" = yes; then CFLAGS="-g -O2" else CFLAGS="-g" fi else if test "$GCC" = yes; then CFLAGS="-O2" else CFLAGS= fi fi { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $CC option to accept ISO C89" >&5 $as_echo_n "checking for $CC option to accept ISO C89... " >&6; } if ${ac_cv_prog_cc_c89+:} false; then : $as_echo_n "(cached) " >&6 else ac_cv_prog_cc_c89=no ac_save_CC=$CC cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include #include struct stat; /* Most of the following tests are stolen from RCS 5.7's src/conf.sh. */ struct buf { int x; }; FILE * (*rcsopen) (struct buf *, struct stat *, int); static char *e (p, i) char **p; int i; { return p[i]; } static char *f (char * (*g) (char **, int), char **p, ...) { char *s; va_list v; va_start (v,p); s = g (p, va_arg (v,int)); va_end (v); return s; } /* OSF 4.0 Compaq cc is some sort of almost-ANSI by default. It has function prototypes and stuff, but not '\xHH' hex character constants. These don't provoke an error unfortunately, instead are silently treated as 'x'. The following induces an error, until -std is added to get proper ANSI mode. Curiously '\x00'!='x' always comes out true, for an array size at least. It's necessary to write '\x00'==0 to get something that's true only with -std. */ int osf4_cc_array ['\x00' == 0 ? 1 : -1]; /* IBM C 6 for AIX is almost-ANSI by default, but it replaces macro parameters inside strings and character constants. */ #define FOO(x) 'x' int xlc6_cc_array[FOO(a) == 'x' ? 1 : -1]; int test (int i, double x); struct s1 {int (*f) (int a);}; struct s2 {int (*f) (double a);}; int pairnames (int, char **, FILE *(*)(struct buf *, struct stat *, int), int, int); int argc; char **argv; int main () { return f (e, argv, 0) != argv[0] || f (e, argv, 1) != argv[1]; ; return 0; } _ACEOF for ac_arg in '' -qlanglvl=extc89 -qlanglvl=ansi -std \ -Ae "-Aa -D_HPUX_SOURCE" "-Xc -D__EXTENSIONS__" do CC="$ac_save_CC $ac_arg" if ac_fn_c_try_compile "$LINENO"; then : ac_cv_prog_cc_c89=$ac_arg fi rm -f core conftest.err conftest.$ac_objext test "x$ac_cv_prog_cc_c89" != "xno" && break done rm -f conftest.$ac_ext CC=$ac_save_CC fi # AC_CACHE_VAL case "x$ac_cv_prog_cc_c89" in x) { $as_echo "$as_me:${as_lineno-$LINENO}: result: none needed" >&5 $as_echo "none needed" >&6; } ;; xno) { $as_echo "$as_me:${as_lineno-$LINENO}: result: unsupported" >&5 $as_echo "unsupported" >&6; } ;; *) CC="$CC $ac_cv_prog_cc_c89" { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_prog_cc_c89" >&5 $as_echo "$ac_cv_prog_cc_c89" >&6; } ;; esac if test "x$ac_cv_prog_cc_c89" != xno; then : fi ac_ext=c ac_cpp='$CPP $CPPFLAGS' ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' ac_compiler_gnu=$ac_cv_c_compiler_gnu depcc="$CC" am_compiler_list= { $as_echo "$as_me:${as_lineno-$LINENO}: checking dependency style of $depcc" >&5 $as_echo_n "checking dependency style of $depcc... " >&6; } if ${am_cv_CC_dependencies_compiler_type+:} false; then : $as_echo_n "(cached) " >&6 else if test -z "$AMDEP_TRUE" && test -f "$am_depcomp"; then # We make a subdir and do the tests there. Otherwise we can end up # making bogus files that we don't know about and never remove. For # instance it was reported that on HP-UX the gcc test will end up # making a dummy file named `D' -- because `-MD' means `put the output # in D'. rm -rf conftest.dir mkdir conftest.dir # Copy depcomp to subdir because otherwise we won't find it if we're # using a relative directory. cp "$am_depcomp" conftest.dir cd conftest.dir # We will build objects and dependencies in a subdirectory because # it helps to detect inapplicable dependency modes. For instance # both Tru64's cc and ICC support -MD to output dependencies as a # side effect of compilation, but ICC will put the dependencies in # the current directory while Tru64 will put them in the object # directory. mkdir sub am_cv_CC_dependencies_compiler_type=none if test "$am_compiler_list" = ""; then am_compiler_list=`sed -n 's/^#*\([a-zA-Z0-9]*\))$/\1/p' < ./depcomp` fi am__universal=false case " $depcc " in #( *\ -arch\ *\ -arch\ *) am__universal=true ;; esac for depmode in $am_compiler_list; do # Setup a source with many dependencies, because some compilers # like to wrap large dependency lists on column 80 (with \), and # we should not choose a depcomp mode which is confused by this. # # We need to recreate these files for each test, as the compiler may # overwrite some of them when testing with obscure command lines. # This happens at least with the AIX C compiler. : > sub/conftest.c for i in 1 2 3 4 5 6; do echo '#include "conftst'$i'.h"' >> sub/conftest.c # Using `: > sub/conftst$i.h' creates only sub/conftst1.h with # Solaris 8's {/usr,}/bin/sh. touch sub/conftst$i.h done echo "${am__include} ${am__quote}sub/conftest.Po${am__quote}" > confmf # We check with `-c' and `-o' for the sake of the "dashmstdout" # mode. It turns out that the SunPro C++ compiler does not properly # handle `-M -o', and we need to detect this. Also, some Intel # versions had trouble with output in subdirs am__obj=sub/conftest.${OBJEXT-o} am__minus_obj="-o $am__obj" case $depmode in gcc) # This depmode causes a compiler race in universal mode. test "$am__universal" = false || continue ;; nosideeffect) # after this tag, mechanisms are not by side-effect, so they'll # only be used when explicitly requested if test "x$enable_dependency_tracking" = xyes; then continue else break fi ;; msvc7 | msvc7msys | msvisualcpp | msvcmsys) # This compiler won't grok `-c -o', but also, the minuso test has # not run yet. These depmodes are late enough in the game, and # so weak that their functioning should not be impacted. am__obj=conftest.${OBJEXT-o} am__minus_obj= ;; none) break ;; esac if depmode=$depmode \ source=sub/conftest.c object=$am__obj \ depfile=sub/conftest.Po tmpdepfile=sub/conftest.TPo \ $SHELL ./depcomp $depcc -c $am__minus_obj sub/conftest.c \ >/dev/null 2>conftest.err && grep sub/conftst1.h sub/conftest.Po > /dev/null 2>&1 && grep sub/conftst6.h sub/conftest.Po > /dev/null 2>&1 && grep $am__obj sub/conftest.Po > /dev/null 2>&1 && ${MAKE-make} -s -f confmf > /dev/null 2>&1; then # icc doesn't choke on unknown options, it will just issue warnings # or remarks (even with -Werror). So we grep stderr for any message # that says an option was ignored or not supported. # When given -MP, icc 7.0 and 7.1 complain thusly: # icc: Command line warning: ignoring option '-M'; no argument required # The diagnosis changed in icc 8.0: # icc: Command line remark: option '-MP' not supported if (grep 'ignoring option' conftest.err || grep 'not supported' conftest.err) >/dev/null 2>&1; then :; else am_cv_CC_dependencies_compiler_type=$depmode break fi fi done cd .. rm -rf conftest.dir else am_cv_CC_dependencies_compiler_type=none fi fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $am_cv_CC_dependencies_compiler_type" >&5 $as_echo "$am_cv_CC_dependencies_compiler_type" >&6; } CCDEPMODE=depmode=$am_cv_CC_dependencies_compiler_type if test "x$enable_dependency_tracking" != xno \ && test "$am_cv_CC_dependencies_compiler_type" = gcc3; then am__fastdepCC_TRUE= am__fastdepCC_FALSE='#' else am__fastdepCC_TRUE='#' am__fastdepCC_FALSE= fi ac_ext=c ac_cpp='$CPP $CPPFLAGS' ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' ac_compiler_gnu=$ac_cv_c_compiler_gnu { $as_echo "$as_me:${as_lineno-$LINENO}: checking how to run the C preprocessor" >&5 $as_echo_n "checking how to run the C preprocessor... " >&6; } # On Suns, sometimes $CPP names a directory. if test -n "$CPP" && test -d "$CPP"; then CPP= fi if test -z "$CPP"; then if ${ac_cv_prog_CPP+:} false; then : $as_echo_n "(cached) " >&6 else # Double quotes because CPP needs to be expanded for CPP in "$CC -E" "$CC -E -traditional-cpp" "/lib/cpp" do ac_preproc_ok=false for ac_c_preproc_warn_flag in '' yes do # Use a header file that comes with gcc, so configuring glibc # with a fresh cross-compiler works. # Prefer to if __STDC__ is defined, since # exists even on freestanding compilers. # On the NeXT, cc -E runs the code through the compiler's parser, # not just through cpp. "Syntax error" is here to catch this case. cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #ifdef __STDC__ # include #else # include #endif Syntax error _ACEOF if ac_fn_c_try_cpp "$LINENO"; then : else # Broken: fails on valid input. continue fi rm -f conftest.err conftest.i conftest.$ac_ext # OK, works on sane cases. Now check whether nonexistent headers # can be detected and how. cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include _ACEOF if ac_fn_c_try_cpp "$LINENO"; then : # Broken: success on invalid input. continue else # Passes both tests. ac_preproc_ok=: break fi rm -f conftest.err conftest.i conftest.$ac_ext done # Because of `break', _AC_PREPROC_IFELSE's cleaning code was skipped. rm -f conftest.i conftest.err conftest.$ac_ext if $ac_preproc_ok; then : break fi done ac_cv_prog_CPP=$CPP fi CPP=$ac_cv_prog_CPP else ac_cv_prog_CPP=$CPP fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $CPP" >&5 $as_echo "$CPP" >&6; } ac_preproc_ok=false for ac_c_preproc_warn_flag in '' yes do # Use a header file that comes with gcc, so configuring glibc # with a fresh cross-compiler works. # Prefer to if __STDC__ is defined, since # exists even on freestanding compilers. # On the NeXT, cc -E runs the code through the compiler's parser, # not just through cpp. "Syntax error" is here to catch this case. cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #ifdef __STDC__ # include #else # include #endif Syntax error _ACEOF if ac_fn_c_try_cpp "$LINENO"; then : else # Broken: fails on valid input. continue fi rm -f conftest.err conftest.i conftest.$ac_ext # OK, works on sane cases. Now check whether nonexistent headers # can be detected and how. cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include _ACEOF if ac_fn_c_try_cpp "$LINENO"; then : # Broken: success on invalid input. continue else # Passes both tests. ac_preproc_ok=: break fi rm -f conftest.err conftest.i conftest.$ac_ext done # Because of `break', _AC_PREPROC_IFELSE's cleaning code was skipped. rm -f conftest.i conftest.err conftest.$ac_ext if $ac_preproc_ok; then : else { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 $as_echo "$as_me: error: in \`$ac_pwd':" >&2;} as_fn_error $? "C preprocessor \"$CPP\" fails sanity check See \`config.log' for more details" "$LINENO" 5; } fi ac_ext=c ac_cpp='$CPP $CPPFLAGS' ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' ac_compiler_gnu=$ac_cv_c_compiler_gnu { $as_echo "$as_me:${as_lineno-$LINENO}: checking for grep that handles long lines and -e" >&5 $as_echo_n "checking for grep that handles long lines and -e... " >&6; } if ${ac_cv_path_GREP+:} false; then : $as_echo_n "(cached) " >&6 else if test -z "$GREP"; then ac_path_GREP_found=false # Loop through the user's path and test for each of PROGNAME-LIST as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH$PATH_SEPARATOR/usr/xpg4/bin do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_prog in grep ggrep; do for ac_exec_ext in '' $ac_executable_extensions; do ac_path_GREP="$as_dir/$ac_prog$ac_exec_ext" as_fn_executable_p "$ac_path_GREP" || continue # Check for GNU ac_path_GREP and select it if it is found. # Check for GNU $ac_path_GREP case `"$ac_path_GREP" --version 2>&1` in *GNU*) ac_cv_path_GREP="$ac_path_GREP" ac_path_GREP_found=:;; *) ac_count=0 $as_echo_n 0123456789 >"conftest.in" while : do cat "conftest.in" "conftest.in" >"conftest.tmp" mv "conftest.tmp" "conftest.in" cp "conftest.in" "conftest.nl" $as_echo 'GREP' >> "conftest.nl" "$ac_path_GREP" -e 'GREP$' -e '-(cannot match)-' < "conftest.nl" >"conftest.out" 2>/dev/null || break diff "conftest.out" "conftest.nl" >/dev/null 2>&1 || break as_fn_arith $ac_count + 1 && ac_count=$as_val if test $ac_count -gt ${ac_path_GREP_max-0}; then # Best one so far, save it but keep looking for a better one ac_cv_path_GREP="$ac_path_GREP" ac_path_GREP_max=$ac_count fi # 10*(2^10) chars as input seems more than enough test $ac_count -gt 10 && break done rm -f conftest.in conftest.tmp conftest.nl conftest.out;; esac $ac_path_GREP_found && break 3 done done done IFS=$as_save_IFS if test -z "$ac_cv_path_GREP"; then as_fn_error $? "no acceptable grep could be found in $PATH$PATH_SEPARATOR/usr/xpg4/bin" "$LINENO" 5 fi else ac_cv_path_GREP=$GREP fi fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_path_GREP" >&5 $as_echo "$ac_cv_path_GREP" >&6; } GREP="$ac_cv_path_GREP" { $as_echo "$as_me:${as_lineno-$LINENO}: checking for egrep" >&5 $as_echo_n "checking for egrep... " >&6; } if ${ac_cv_path_EGREP+:} false; then : $as_echo_n "(cached) " >&6 else if echo a | $GREP -E '(a|b)' >/dev/null 2>&1 then ac_cv_path_EGREP="$GREP -E" else if test -z "$EGREP"; then ac_path_EGREP_found=false # Loop through the user's path and test for each of PROGNAME-LIST as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH$PATH_SEPARATOR/usr/xpg4/bin do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_prog in egrep; do for ac_exec_ext in '' $ac_executable_extensions; do ac_path_EGREP="$as_dir/$ac_prog$ac_exec_ext" as_fn_executable_p "$ac_path_EGREP" || continue # Check for GNU ac_path_EGREP and select it if it is found. # Check for GNU $ac_path_EGREP case `"$ac_path_EGREP" --version 2>&1` in *GNU*) ac_cv_path_EGREP="$ac_path_EGREP" ac_path_EGREP_found=:;; *) ac_count=0 $as_echo_n 0123456789 >"conftest.in" while : do cat "conftest.in" "conftest.in" >"conftest.tmp" mv "conftest.tmp" "conftest.in" cp "conftest.in" "conftest.nl" $as_echo 'EGREP' >> "conftest.nl" "$ac_path_EGREP" 'EGREP$' < "conftest.nl" >"conftest.out" 2>/dev/null || break diff "conftest.out" "conftest.nl" >/dev/null 2>&1 || break as_fn_arith $ac_count + 1 && ac_count=$as_val if test $ac_count -gt ${ac_path_EGREP_max-0}; then # Best one so far, save it but keep looking for a better one ac_cv_path_EGREP="$ac_path_EGREP" ac_path_EGREP_max=$ac_count fi # 10*(2^10) chars as input seems more than enough test $ac_count -gt 10 && break done rm -f conftest.in conftest.tmp conftest.nl conftest.out;; esac $ac_path_EGREP_found && break 3 done done done IFS=$as_save_IFS if test -z "$ac_cv_path_EGREP"; then as_fn_error $? "no acceptable egrep could be found in $PATH$PATH_SEPARATOR/usr/xpg4/bin" "$LINENO" 5 fi else ac_cv_path_EGREP=$EGREP fi fi fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_path_EGREP" >&5 $as_echo "$ac_cv_path_EGREP" >&6; } EGREP="$ac_cv_path_EGREP" { $as_echo "$as_me:${as_lineno-$LINENO}: checking for ANSI C header files" >&5 $as_echo_n "checking for ANSI C header files... " >&6; } if ${ac_cv_header_stdc+:} false; then : $as_echo_n "(cached) " >&6 else cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include #include #include #include int main () { ; return 0; } _ACEOF if ac_fn_c_try_compile "$LINENO"; then : ac_cv_header_stdc=yes else ac_cv_header_stdc=no fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext if test $ac_cv_header_stdc = yes; then # SunOS 4.x string.h does not declare mem*, contrary to ANSI. cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include _ACEOF if (eval "$ac_cpp conftest.$ac_ext") 2>&5 | $EGREP "memchr" >/dev/null 2>&1; then : else ac_cv_header_stdc=no fi rm -f conftest* fi if test $ac_cv_header_stdc = yes; then # ISC 2.0.2 stdlib.h does not declare free, contrary to ANSI. cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include _ACEOF if (eval "$ac_cpp conftest.$ac_ext") 2>&5 | $EGREP "free" >/dev/null 2>&1; then : else ac_cv_header_stdc=no fi rm -f conftest* fi if test $ac_cv_header_stdc = yes; then # /bin/cc in Irix-4.0.5 gets non-ANSI ctype macros unless using -ansi. if test "$cross_compiling" = yes; then : : else cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include #include #if ((' ' & 0x0FF) == 0x020) # define ISLOWER(c) ('a' <= (c) && (c) <= 'z') # define TOUPPER(c) (ISLOWER(c) ? 'A' + ((c) - 'a') : (c)) #else # define ISLOWER(c) \ (('a' <= (c) && (c) <= 'i') \ || ('j' <= (c) && (c) <= 'r') \ || ('s' <= (c) && (c) <= 'z')) # define TOUPPER(c) (ISLOWER(c) ? ((c) | 0x40) : (c)) #endif #define XOR(e, f) (((e) && !(f)) || (!(e) && (f))) int main () { int i; for (i = 0; i < 256; i++) if (XOR (islower (i), ISLOWER (i)) || toupper (i) != TOUPPER (i)) return 2; return 0; } _ACEOF if ac_fn_c_try_run "$LINENO"; then : else ac_cv_header_stdc=no fi rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext \ conftest.$ac_objext conftest.beam conftest.$ac_ext fi fi fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_header_stdc" >&5 $as_echo "$ac_cv_header_stdc" >&6; } if test $ac_cv_header_stdc = yes; then $as_echo "#define STDC_HEADERS 1" >>confdefs.h fi # On IRIX 5.3, sys/types and inttypes.h are conflicting. for ac_header in sys/types.h sys/stat.h stdlib.h string.h memory.h strings.h \ inttypes.h stdint.h unistd.h do : as_ac_Header=`$as_echo "ac_cv_header_$ac_header" | $as_tr_sh` ac_fn_c_check_header_compile "$LINENO" "$ac_header" "$as_ac_Header" "$ac_includes_default " if eval test \"x\$"$as_ac_Header"\" = x"yes"; then : cat >>confdefs.h <<_ACEOF #define `$as_echo "HAVE_$ac_header" | $as_tr_cpp` 1 _ACEOF fi done for ac_header in sys/cdefs.h string.h sys/sockio.h do : as_ac_Header=`$as_echo "ac_cv_header_$ac_header" | $as_tr_sh` ac_fn_c_check_header_mongrel "$LINENO" "$ac_header" "$as_ac_Header" "$ac_includes_default" if eval test \"x\$"$as_ac_Header"\" = x"yes"; then : cat >>confdefs.h <<_ACEOF #define `$as_echo "HAVE_$ac_header" | $as_tr_cpp` 1 _ACEOF fi done for ac_func in strcasestr do : ac_fn_c_check_func "$LINENO" "strcasestr" "ac_cv_func_strcasestr" if test "x$ac_cv_func_strcasestr" = xyes; then : cat >>confdefs.h <<_ACEOF #define HAVE_STRCASESTR 1 _ACEOF fi done if test x"$BUILD_FOR_FREEBSD" = x"yes"; then CFLAGS="$CFLAGS -I/usr/local/include" LDFLAGS="$LDFLAGS -L/usr/local/lib" CXXFLAGS="$CXXFLAGS -I/usr/local/include" fi ac_fn_c_check_type "$LINENO" "comparison_fn_t" "ac_cv_type_comparison_fn_t" "#include " if test "x$ac_cv_type_comparison_fn_t" = xyes; then : $as_echo "#define HAVE_COMPARISON_FN_T 1" >>confdefs.h fi ac_ext=c ac_cpp='$CPP $CPPFLAGS' ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' ac_compiler_gnu=$ac_cv_c_compiler_gnu if test -n "$ac_tool_prefix"; then # Extract the first word of "${ac_tool_prefix}gcc", so it can be a program name with args. set dummy ${ac_tool_prefix}gcc; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } if ${ac_cv_prog_CC+:} false; then : $as_echo_n "(cached) " >&6 else if test -n "$CC"; then ac_cv_prog_CC="$CC" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then ac_cv_prog_CC="${ac_tool_prefix}gcc" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS fi fi CC=$ac_cv_prog_CC if test -n "$CC"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: $CC" >&5 $as_echo "$CC" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi fi if test -z "$ac_cv_prog_CC"; then ac_ct_CC=$CC # Extract the first word of "gcc", so it can be a program name with args. set dummy gcc; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } if ${ac_cv_prog_ac_ct_CC+:} false; then : $as_echo_n "(cached) " >&6 else if test -n "$ac_ct_CC"; then ac_cv_prog_ac_ct_CC="$ac_ct_CC" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then ac_cv_prog_ac_ct_CC="gcc" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS fi fi ac_ct_CC=$ac_cv_prog_ac_ct_CC if test -n "$ac_ct_CC"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_CC" >&5 $as_echo "$ac_ct_CC" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi if test "x$ac_ct_CC" = x; then CC="" else case $cross_compiling:$ac_tool_warned in yes:) { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 $as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} ac_tool_warned=yes ;; esac CC=$ac_ct_CC fi else CC="$ac_cv_prog_CC" fi if test -z "$CC"; then if test -n "$ac_tool_prefix"; then # Extract the first word of "${ac_tool_prefix}cc", so it can be a program name with args. set dummy ${ac_tool_prefix}cc; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } if ${ac_cv_prog_CC+:} false; then : $as_echo_n "(cached) " >&6 else if test -n "$CC"; then ac_cv_prog_CC="$CC" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then ac_cv_prog_CC="${ac_tool_prefix}cc" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS fi fi CC=$ac_cv_prog_CC if test -n "$CC"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: $CC" >&5 $as_echo "$CC" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi fi fi if test -z "$CC"; then # Extract the first word of "cc", so it can be a program name with args. set dummy cc; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } if ${ac_cv_prog_CC+:} false; then : $as_echo_n "(cached) " >&6 else if test -n "$CC"; then ac_cv_prog_CC="$CC" # Let the user override the test. else ac_prog_rejected=no as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then if test "$as_dir/$ac_word$ac_exec_ext" = "/usr/ucb/cc"; then ac_prog_rejected=yes continue fi ac_cv_prog_CC="cc" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS if test $ac_prog_rejected = yes; then # We found a bogon in the path, so make sure we never use it. set dummy $ac_cv_prog_CC shift if test $# != 0; then # We chose a different compiler from the bogus one. # However, it has the same basename, so the bogon will be chosen # first if we set CC to just the basename; use the full file name. shift ac_cv_prog_CC="$as_dir/$ac_word${1+' '}$@" fi fi fi fi CC=$ac_cv_prog_CC if test -n "$CC"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: $CC" >&5 $as_echo "$CC" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi fi if test -z "$CC"; then if test -n "$ac_tool_prefix"; then for ac_prog in cl.exe do # Extract the first word of "$ac_tool_prefix$ac_prog", so it can be a program name with args. set dummy $ac_tool_prefix$ac_prog; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } if ${ac_cv_prog_CC+:} false; then : $as_echo_n "(cached) " >&6 else if test -n "$CC"; then ac_cv_prog_CC="$CC" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then ac_cv_prog_CC="$ac_tool_prefix$ac_prog" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS fi fi CC=$ac_cv_prog_CC if test -n "$CC"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: $CC" >&5 $as_echo "$CC" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi test -n "$CC" && break done fi if test -z "$CC"; then ac_ct_CC=$CC for ac_prog in cl.exe do # Extract the first word of "$ac_prog", so it can be a program name with args. set dummy $ac_prog; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } if ${ac_cv_prog_ac_ct_CC+:} false; then : $as_echo_n "(cached) " >&6 else if test -n "$ac_ct_CC"; then ac_cv_prog_ac_ct_CC="$ac_ct_CC" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then ac_cv_prog_ac_ct_CC="$ac_prog" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS fi fi ac_ct_CC=$ac_cv_prog_ac_ct_CC if test -n "$ac_ct_CC"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_CC" >&5 $as_echo "$ac_ct_CC" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi test -n "$ac_ct_CC" && break done if test "x$ac_ct_CC" = x; then CC="" else case $cross_compiling:$ac_tool_warned in yes:) { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 $as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} ac_tool_warned=yes ;; esac CC=$ac_ct_CC fi fi fi test -z "$CC" && { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 $as_echo "$as_me: error: in \`$ac_pwd':" >&2;} as_fn_error $? "no acceptable C compiler found in \$PATH See \`config.log' for more details" "$LINENO" 5; } # Provide some information about the compiler. $as_echo "$as_me:${as_lineno-$LINENO}: checking for C compiler version" >&5 set X $ac_compile ac_compiler=$2 for ac_option in --version -v -V -qversion; do { { ac_try="$ac_compiler $ac_option >&5" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" $as_echo "$ac_try_echo"; } >&5 (eval "$ac_compiler $ac_option >&5") 2>conftest.err ac_status=$? if test -s conftest.err; then sed '10a\ ... rest of stderr output deleted ... 10q' conftest.err >conftest.er1 cat conftest.er1 >&5 fi rm -f conftest.er1 conftest.err $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 test $ac_status = 0; } done { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether we are using the GNU C compiler" >&5 $as_echo_n "checking whether we are using the GNU C compiler... " >&6; } if ${ac_cv_c_compiler_gnu+:} false; then : $as_echo_n "(cached) " >&6 else cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ int main () { #ifndef __GNUC__ choke me #endif ; return 0; } _ACEOF if ac_fn_c_try_compile "$LINENO"; then : ac_compiler_gnu=yes else ac_compiler_gnu=no fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext ac_cv_c_compiler_gnu=$ac_compiler_gnu fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_c_compiler_gnu" >&5 $as_echo "$ac_cv_c_compiler_gnu" >&6; } if test $ac_compiler_gnu = yes; then GCC=yes else GCC= fi ac_test_CFLAGS=${CFLAGS+set} ac_save_CFLAGS=$CFLAGS { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether $CC accepts -g" >&5 $as_echo_n "checking whether $CC accepts -g... " >&6; } if ${ac_cv_prog_cc_g+:} false; then : $as_echo_n "(cached) " >&6 else ac_save_c_werror_flag=$ac_c_werror_flag ac_c_werror_flag=yes ac_cv_prog_cc_g=no CFLAGS="-g" cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ int main () { ; return 0; } _ACEOF if ac_fn_c_try_compile "$LINENO"; then : ac_cv_prog_cc_g=yes else CFLAGS="" cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ int main () { ; return 0; } _ACEOF if ac_fn_c_try_compile "$LINENO"; then : else ac_c_werror_flag=$ac_save_c_werror_flag CFLAGS="-g" cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ int main () { ; return 0; } _ACEOF if ac_fn_c_try_compile "$LINENO"; then : ac_cv_prog_cc_g=yes fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext ac_c_werror_flag=$ac_save_c_werror_flag fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_prog_cc_g" >&5 $as_echo "$ac_cv_prog_cc_g" >&6; } if test "$ac_test_CFLAGS" = set; then CFLAGS=$ac_save_CFLAGS elif test $ac_cv_prog_cc_g = yes; then if test "$GCC" = yes; then CFLAGS="-g -O2" else CFLAGS="-g" fi else if test "$GCC" = yes; then CFLAGS="-O2" else CFLAGS= fi fi { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $CC option to accept ISO C89" >&5 $as_echo_n "checking for $CC option to accept ISO C89... " >&6; } if ${ac_cv_prog_cc_c89+:} false; then : $as_echo_n "(cached) " >&6 else ac_cv_prog_cc_c89=no ac_save_CC=$CC cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include #include struct stat; /* Most of the following tests are stolen from RCS 5.7's src/conf.sh. */ struct buf { int x; }; FILE * (*rcsopen) (struct buf *, struct stat *, int); static char *e (p, i) char **p; int i; { return p[i]; } static char *f (char * (*g) (char **, int), char **p, ...) { char *s; va_list v; va_start (v,p); s = g (p, va_arg (v,int)); va_end (v); return s; } /* OSF 4.0 Compaq cc is some sort of almost-ANSI by default. It has function prototypes and stuff, but not '\xHH' hex character constants. These don't provoke an error unfortunately, instead are silently treated as 'x'. The following induces an error, until -std is added to get proper ANSI mode. Curiously '\x00'!='x' always comes out true, for an array size at least. It's necessary to write '\x00'==0 to get something that's true only with -std. */ int osf4_cc_array ['\x00' == 0 ? 1 : -1]; /* IBM C 6 for AIX is almost-ANSI by default, but it replaces macro parameters inside strings and character constants. */ #define FOO(x) 'x' int xlc6_cc_array[FOO(a) == 'x' ? 1 : -1]; int test (int i, double x); struct s1 {int (*f) (int a);}; struct s2 {int (*f) (double a);}; int pairnames (int, char **, FILE *(*)(struct buf *, struct stat *, int), int, int); int argc; char **argv; int main () { return f (e, argv, 0) != argv[0] || f (e, argv, 1) != argv[1]; ; return 0; } _ACEOF for ac_arg in '' -qlanglvl=extc89 -qlanglvl=ansi -std \ -Ae "-Aa -D_HPUX_SOURCE" "-Xc -D__EXTENSIONS__" do CC="$ac_save_CC $ac_arg" if ac_fn_c_try_compile "$LINENO"; then : ac_cv_prog_cc_c89=$ac_arg fi rm -f core conftest.err conftest.$ac_objext test "x$ac_cv_prog_cc_c89" != "xno" && break done rm -f conftest.$ac_ext CC=$ac_save_CC fi # AC_CACHE_VAL case "x$ac_cv_prog_cc_c89" in x) { $as_echo "$as_me:${as_lineno-$LINENO}: result: none needed" >&5 $as_echo "none needed" >&6; } ;; xno) { $as_echo "$as_me:${as_lineno-$LINENO}: result: unsupported" >&5 $as_echo "unsupported" >&6; } ;; *) CC="$CC $ac_cv_prog_cc_c89" { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_prog_cc_c89" >&5 $as_echo "$ac_cv_prog_cc_c89" >&6; } ;; esac if test "x$ac_cv_prog_cc_c89" != xno; then : fi ac_ext=c ac_cpp='$CPP $CPPFLAGS' ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' ac_compiler_gnu=$ac_cv_c_compiler_gnu depcc="$CC" am_compiler_list= { $as_echo "$as_me:${as_lineno-$LINENO}: checking dependency style of $depcc" >&5 $as_echo_n "checking dependency style of $depcc... " >&6; } if ${am_cv_CC_dependencies_compiler_type+:} false; then : $as_echo_n "(cached) " >&6 else if test -z "$AMDEP_TRUE" && test -f "$am_depcomp"; then # We make a subdir and do the tests there. Otherwise we can end up # making bogus files that we don't know about and never remove. For # instance it was reported that on HP-UX the gcc test will end up # making a dummy file named `D' -- because `-MD' means `put the output # in D'. rm -rf conftest.dir mkdir conftest.dir # Copy depcomp to subdir because otherwise we won't find it if we're # using a relative directory. cp "$am_depcomp" conftest.dir cd conftest.dir # We will build objects and dependencies in a subdirectory because # it helps to detect inapplicable dependency modes. For instance # both Tru64's cc and ICC support -MD to output dependencies as a # side effect of compilation, but ICC will put the dependencies in # the current directory while Tru64 will put them in the object # directory. mkdir sub am_cv_CC_dependencies_compiler_type=none if test "$am_compiler_list" = ""; then am_compiler_list=`sed -n 's/^#*\([a-zA-Z0-9]*\))$/\1/p' < ./depcomp` fi am__universal=false case " $depcc " in #( *\ -arch\ *\ -arch\ *) am__universal=true ;; esac for depmode in $am_compiler_list; do # Setup a source with many dependencies, because some compilers # like to wrap large dependency lists on column 80 (with \), and # we should not choose a depcomp mode which is confused by this. # # We need to recreate these files for each test, as the compiler may # overwrite some of them when testing with obscure command lines. # This happens at least with the AIX C compiler. : > sub/conftest.c for i in 1 2 3 4 5 6; do echo '#include "conftst'$i'.h"' >> sub/conftest.c # Using `: > sub/conftst$i.h' creates only sub/conftst1.h with # Solaris 8's {/usr,}/bin/sh. touch sub/conftst$i.h done echo "${am__include} ${am__quote}sub/conftest.Po${am__quote}" > confmf # We check with `-c' and `-o' for the sake of the "dashmstdout" # mode. It turns out that the SunPro C++ compiler does not properly # handle `-M -o', and we need to detect this. Also, some Intel # versions had trouble with output in subdirs am__obj=sub/conftest.${OBJEXT-o} am__minus_obj="-o $am__obj" case $depmode in gcc) # This depmode causes a compiler race in universal mode. test "$am__universal" = false || continue ;; nosideeffect) # after this tag, mechanisms are not by side-effect, so they'll # only be used when explicitly requested if test "x$enable_dependency_tracking" = xyes; then continue else break fi ;; msvc7 | msvc7msys | msvisualcpp | msvcmsys) # This compiler won't grok `-c -o', but also, the minuso test has # not run yet. These depmodes are late enough in the game, and # so weak that their functioning should not be impacted. am__obj=conftest.${OBJEXT-o} am__minus_obj= ;; none) break ;; esac if depmode=$depmode \ source=sub/conftest.c object=$am__obj \ depfile=sub/conftest.Po tmpdepfile=sub/conftest.TPo \ $SHELL ./depcomp $depcc -c $am__minus_obj sub/conftest.c \ >/dev/null 2>conftest.err && grep sub/conftst1.h sub/conftest.Po > /dev/null 2>&1 && grep sub/conftst6.h sub/conftest.Po > /dev/null 2>&1 && grep $am__obj sub/conftest.Po > /dev/null 2>&1 && ${MAKE-make} -s -f confmf > /dev/null 2>&1; then # icc doesn't choke on unknown options, it will just issue warnings # or remarks (even with -Werror). So we grep stderr for any message # that says an option was ignored or not supported. # When given -MP, icc 7.0 and 7.1 complain thusly: # icc: Command line warning: ignoring option '-M'; no argument required # The diagnosis changed in icc 8.0: # icc: Command line remark: option '-MP' not supported if (grep 'ignoring option' conftest.err || grep 'not supported' conftest.err) >/dev/null 2>&1; then :; else am_cv_CC_dependencies_compiler_type=$depmode break fi fi done cd .. rm -rf conftest.dir else am_cv_CC_dependencies_compiler_type=none fi fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $am_cv_CC_dependencies_compiler_type" >&5 $as_echo "$am_cv_CC_dependencies_compiler_type" >&6; } CCDEPMODE=depmode=$am_cv_CC_dependencies_compiler_type if test "x$enable_dependency_tracking" != xno \ && test "$am_cv_CC_dependencies_compiler_type" = gcc3; then am__fastdepCC_TRUE= am__fastdepCC_FALSE='#' else am__fastdepCC_TRUE='#' am__fastdepCC_FALSE= fi # Check whether --enable-coverage was given. if test "${enable_coverage+set}" = set; then : enableval=$enable_coverage; use_cov=$enableval else use_cov=no fi if test "x$use_cov" = x"yes"; then COVERAGE_INIT="coverage-init" fi { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether we are really using the Sun C compiler" >&5 $as_echo_n "checking whether we are really using the Sun C compiler... " >&6; } if ${ac_cv_c_compiler_suncc+:} false; then : $as_echo_n "(cached) " >&6 else cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ int main () { #ifndef __SUNPRO_C choke me #endif ; return 0; } _ACEOF if ac_fn_c_try_compile "$LINENO"; then : ac_compiler_suncc=yes else ac_compiler_suncc=no fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext ac_cv_c_compiler_suncc=$ac_compiler_suncc fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_c_compiler_suncc" >&5 $as_echo "$ac_cv_c_compiler_suncc" >&6; } { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether we are really using the Intel C compiler" >&5 $as_echo_n "checking whether we are really using the Intel C compiler... " >&6; } if ${ac_cv_c_compiler_icc+:} false; then : $as_echo_n "(cached) " >&6 else cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ int main () { #ifndef __INTEL_COMPILER choke me #endif ; return 0; } _ACEOF if ac_fn_c_try_compile "$LINENO"; then : ac_compiler_icc=yes else ac_compiler_icc=no fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext ac_cv_c_compiler_icc=$ac_compiler_icc fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_c_compiler_icc" >&5 $as_echo "$ac_cv_c_compiler_icc" >&6; } if test x"$ac_cv_c_compiler_suncc" = x"yes"; then COMPILER_OPTIONS_SHARED="-D__FUNCTION__=__func__" COMPILER_OPTIONS_C="$COMPILER_OPTIONS_SHARED" COMPILER_OPTIONS_CXX="$COMPILER_OPTIONS_SHARED" LDFLAGS="$LDFLAGS -z ignore -R '\$\$ORIGIN/../lib'" elif test x"$ac_cv_c_compiler_icc" = x"yes"; then COMPILER_OPTIONS_SHARED="-Wall -fstrict-aliasing -Wmissing-prototypes -Wstrict-prototypes -wd2259,188,593,869,981,181,1419,2218" COMPILER_OPTIONS_C="$COMPILER_OPTIONS_SHARED" COMPILER_OPTIONS_CXX="$COMPILER_OPTIONS_SHARED" else COMPILER_OPTIONS_SHARED="-Wall -fstrict-aliasing -Wp,-D_FORTIFY_SOURCE=2" if test "x$use_cov" = "xyes"; then COMPILER_OPTIONS_SHARED="-O0 $COMPILER_OPTIONS_SHARED" else COMPILER_OPTIONS_SHARED="$COMPILER_OPTIONS_SHARED" fi COMPILER_OPTIONS_C="$COMPILER_OPTIONS_SHARED -Wmissing-prototypes -Wstrict-prototypes" if test "x$use_cov" = "xyes"; then COMPILER_OPTIONS_C="$COMPILER_OPTIONS_C -fprofile-arcs -ftest-coverage" LDFLAGS="$LDFLAGS -lgcov --coverage" fi COMPILER_OPTIONS_CXX="$COMPILER_OPTIONS_SHARED" if test "x$use_cov" = "xyes"; then COMPILER_OPTIONS_CXX="$COMPILER_OPTIONS_CXX -fprofile-arcs -ftest-coverage" LDFLAGS="$LDFLAGS -lgcov --coverage" fi fi . `dirname $0`/VERSION if test x"$OPENCHANGE_VERSION_IS_SVN_SNAPSHOT" = x"yes"; then ASSERT_DEFINITION="-DENABLE_ASSERTS" fi # Extract the first word of "perl", so it can be a program name with args. set dummy perl; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } if ${ac_cv_path_PERL+:} false; then : $as_echo_n "(cached) " >&6 else case $PERL in [\\/]* | ?:[\\/]*) ac_cv_path_PERL="$PERL" # Let the user override the test with a path. ;; *) as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then ac_cv_path_PERL="$as_dir/$ac_word$ac_exec_ext" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS ;; esac fi PERL=$ac_cv_path_PERL if test -n "$PERL"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: $PERL" >&5 $as_echo "$PERL" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi if test x"$PERL" = x""; then { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: No version of perl was found!" >&5 $as_echo "$as_me: WARNING: No version of perl was found!" >&2;} as_fn_error $? "Please install perl http://www.perl.com" "$LINENO" 5 fi # Extract the first word of "pidl", so it can be a program name with args. set dummy pidl; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } if ${ac_cv_path_PIDL+:} false; then : $as_echo_n "(cached) " >&6 else case $PIDL in [\\/]* | ?:[\\/]*) ac_cv_path_PIDL="$PIDL" # Let the user override the test with a path. ;; *) as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then ac_cv_path_PIDL="$as_dir/$ac_word$ac_exec_ext" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS ;; esac fi PIDL=$ac_cv_path_PIDL if test -n "$PIDL"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: $PIDL" >&5 $as_echo "$PIDL" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi if test x"$PIDL" = x""; then { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: No version of pidl was found!" >&5 $as_echo "$as_me: WARNING: No version of pidl was found!" >&2;} as_fn_error $? "Please install pidl" "$LINENO" 5 fi # Extract the first word of "python", so it can be a program name with args. set dummy python; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } if ${ac_cv_path_PYTHON+:} false; then : $as_echo_n "(cached) " >&6 else case $PYTHON in [\\/]* | ?:[\\/]*) ac_cv_path_PYTHON="$PYTHON" # Let the user override the test with a path. ;; *) as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then ac_cv_path_PYTHON="$as_dir/$ac_word$ac_exec_ext" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS ;; esac fi PYTHON=$ac_cv_path_PYTHON if test -n "$PYTHON"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: $PYTHON" >&5 $as_echo "$PYTHON" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi if test x"$PYTHON" = x""; then { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: No version of python was found!" >&5 $as_echo "$as_me: WARNING: No version of python was found!" >&2;} as_fn_error $? "Please install python" "$LINENO" 5 fi # Extract the first word of "python-config", so it can be a program name with args. set dummy python-config; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } if ${ac_cv_path_PYTHON_CONFIG+:} false; then : $as_echo_n "(cached) " >&6 else case $PYTHON_CONFIG in [\\/]* | ?:[\\/]*) ac_cv_path_PYTHON_CONFIG="$PYTHON_CONFIG" # Let the user override the test with a path. ;; *) as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then ac_cv_path_PYTHON_CONFIG="$as_dir/$ac_word$ac_exec_ext" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS ;; esac fi PYTHON_CONFIG=$ac_cv_path_PYTHON_CONFIG if test -n "$PYTHON_CONFIG"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: $PYTHON_CONFIG" >&5 $as_echo "$PYTHON_CONFIG" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi if test x"$PYTHON_CONFIG" = x""; then { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: No version of python-config was found!" >&5 $as_echo "$as_me: WARNING: No version of python-config was found!" >&2;} as_fn_error $? "Please install python-dev 2.7" "$LINENO" 5 fi { $as_echo "$as_me:${as_lineno-$LINENO}: checking python cflags" >&5 $as_echo_n "checking python cflags... " >&6; } PYTHON_CFLAGS=`$PYTHON_CONFIG --cflags` { $as_echo "$as_me:${as_lineno-$LINENO}: result: $PYTHON_CFLAGS" >&5 $as_echo "$PYTHON_CFLAGS" >&6; } { $as_echo "$as_me:${as_lineno-$LINENO}: checking python libs" >&5 $as_echo_n "checking python libs... " >&6; } PYTHON_LIBS=`$PYTHON_CONFIG --libs` { $as_echo "$as_me:${as_lineno-$LINENO}: result: $PYTHON_LIBS" >&5 $as_echo "$PYTHON_LIBS" >&6; } { $as_echo "$as_me:${as_lineno-$LINENO}: checking python library directory" >&5 $as_echo_n "checking python library directory... " >&6; } pythondir=`$PYTHON -c "from distutils import sysconfig; print sysconfig.get_python_lib(1, 0, '\\${prefix}')"` { $as_echo "$as_me:${as_lineno-$LINENO}: result: $pythondir" >&5 $as_echo "$pythondir" >&6; } if test x"$OPENCHANGE_VERSION_IS_SVN_SNAPSHOT" = x"yes"; then # Extract the first word of "flex", so it can be a program name with args. set dummy flex; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } if ${ac_cv_prog_FLEX+:} false; then : $as_echo_n "(cached) " >&6 else if test -n "$FLEX"; then ac_cv_prog_FLEX="$FLEX" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then ac_cv_prog_FLEX="flex" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS fi fi FLEX=$ac_cv_prog_FLEX if test -n "$FLEX"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: $FLEX" >&5 $as_echo "$FLEX" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi if test x"$FLEX" = x""; then { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: No version of flex was found!" >&5 $as_echo "$as_me: WARNING: No version of flex was found!" >&2;} as_fn_error $? "Please install flex" "$LINENO" 5 else V=`$FLEX --version | awk '{print $NF}'` W=`echo $V | awk -F. '{if (((($1*100 + $2)*100 + $3) > 20535) || $3 == 4) print "no"}'` if test "x$W" != x ; then { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: Adjust your FLEX environment variable" >&5 $as_echo "$as_me: WARNING: Adjust your FLEX environment variable" >&2;} as_fn_error $? "Flex version 2.5.35 or below is needed. You have $V" "$LINENO" 5 fi fi fi pkg_failed=no { $as_echo "$as_me:${as_lineno-$LINENO}: checking for TALLOC" >&5 $as_echo_n "checking for TALLOC... " >&6; } if test -n "$TALLOC_CFLAGS"; then pkg_cv_TALLOC_CFLAGS="$TALLOC_CFLAGS" elif test -n "$PKG_CONFIG"; then if test -n "$PKG_CONFIG" && \ { { $as_echo "$as_me:${as_lineno-$LINENO}: \$PKG_CONFIG --exists --print-errors \"talloc\""; } >&5 ($PKG_CONFIG --exists --print-errors "talloc") 2>&5 ac_status=$? $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 test $ac_status = 0; }; then pkg_cv_TALLOC_CFLAGS=`$PKG_CONFIG --cflags "talloc" 2>/dev/null` test "x$?" != "x0" && pkg_failed=yes else pkg_failed=yes fi else pkg_failed=untried fi if test -n "$TALLOC_LIBS"; then pkg_cv_TALLOC_LIBS="$TALLOC_LIBS" elif test -n "$PKG_CONFIG"; then if test -n "$PKG_CONFIG" && \ { { $as_echo "$as_me:${as_lineno-$LINENO}: \$PKG_CONFIG --exists --print-errors \"talloc\""; } >&5 ($PKG_CONFIG --exists --print-errors "talloc") 2>&5 ac_status=$? $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 test $ac_status = 0; }; then pkg_cv_TALLOC_LIBS=`$PKG_CONFIG --libs "talloc" 2>/dev/null` test "x$?" != "x0" && pkg_failed=yes else pkg_failed=yes fi else pkg_failed=untried fi if test $pkg_failed = yes; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } if $PKG_CONFIG --atleast-pkgconfig-version 0.20; then _pkg_short_errors_supported=yes else _pkg_short_errors_supported=no fi if test $_pkg_short_errors_supported = yes; then TALLOC_PKG_ERRORS=`$PKG_CONFIG --short-errors --print-errors --cflags --libs "talloc" 2>&1` else TALLOC_PKG_ERRORS=`$PKG_CONFIG --print-errors --cflags --libs "talloc" 2>&1` fi # Put the nasty error message in config.log where it belongs echo "$TALLOC_PKG_ERRORS" >&5 as_fn_error $? "Package requirements (talloc) were not met: $TALLOC_PKG_ERRORS Consider adjusting the PKG_CONFIG_PATH environment variable if you installed software in a non-standard prefix. Alternatively, you may set the environment variables TALLOC_CFLAGS and TALLOC_LIBS to avoid the need to call pkg-config. See the pkg-config man page for more details." "$LINENO" 5 elif test $pkg_failed = untried; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 $as_echo "$as_me: error: in \`$ac_pwd':" >&2;} as_fn_error $? "The pkg-config script could not be found or is too old. Make sure it is in your PATH or set the PKG_CONFIG environment variable to the full path to pkg-config. Alternatively, you may set the environment variables TALLOC_CFLAGS and TALLOC_LIBS to avoid the need to call pkg-config. See the pkg-config man page for more details. To get pkg-config, see . See \`config.log' for more details" "$LINENO" 5; } else TALLOC_CFLAGS=$pkg_cv_TALLOC_CFLAGS TALLOC_LIBS=$pkg_cv_TALLOC_LIBS { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 $as_echo "yes" >&6; } fi pkg_failed=no { $as_echo "$as_me:${as_lineno-$LINENO}: checking for SAMBA" >&5 $as_echo_n "checking for SAMBA... " >&6; } if test -n "$SAMBA_CFLAGS"; then pkg_cv_SAMBA_CFLAGS="$SAMBA_CFLAGS" elif test -n "$PKG_CONFIG"; then if test -n "$PKG_CONFIG" && \ { { $as_echo "$as_me:${as_lineno-$LINENO}: \$PKG_CONFIG --exists --print-errors \"dcerpc ndr samba-hostconfig samba-util tevent samba-credentials\""; } >&5 ($PKG_CONFIG --exists --print-errors "dcerpc ndr samba-hostconfig samba-util tevent samba-credentials") 2>&5 ac_status=$? $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 test $ac_status = 0; }; then pkg_cv_SAMBA_CFLAGS=`$PKG_CONFIG --cflags "dcerpc ndr samba-hostconfig samba-util tevent samba-credentials" 2>/dev/null` test "x$?" != "x0" && pkg_failed=yes else pkg_failed=yes fi else pkg_failed=untried fi if test -n "$SAMBA_LIBS"; then pkg_cv_SAMBA_LIBS="$SAMBA_LIBS" elif test -n "$PKG_CONFIG"; then if test -n "$PKG_CONFIG" && \ { { $as_echo "$as_me:${as_lineno-$LINENO}: \$PKG_CONFIG --exists --print-errors \"dcerpc ndr samba-hostconfig samba-util tevent samba-credentials\""; } >&5 ($PKG_CONFIG --exists --print-errors "dcerpc ndr samba-hostconfig samba-util tevent samba-credentials") 2>&5 ac_status=$? $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 test $ac_status = 0; }; then pkg_cv_SAMBA_LIBS=`$PKG_CONFIG --libs "dcerpc ndr samba-hostconfig samba-util tevent samba-credentials" 2>/dev/null` test "x$?" != "x0" && pkg_failed=yes else pkg_failed=yes fi else pkg_failed=untried fi if test $pkg_failed = yes; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } if $PKG_CONFIG --atleast-pkgconfig-version 0.20; then _pkg_short_errors_supported=yes else _pkg_short_errors_supported=no fi if test $_pkg_short_errors_supported = yes; then SAMBA_PKG_ERRORS=`$PKG_CONFIG --short-errors --print-errors --cflags --libs "dcerpc ndr samba-hostconfig samba-util tevent samba-credentials" 2>&1` else SAMBA_PKG_ERRORS=`$PKG_CONFIG --print-errors --cflags --libs "dcerpc ndr samba-hostconfig samba-util tevent samba-credentials" 2>&1` fi # Put the nasty error message in config.log where it belongs echo "$SAMBA_PKG_ERRORS" >&5 as_fn_error $? "Package requirements (dcerpc ndr samba-hostconfig samba-util tevent samba-credentials) were not met: $SAMBA_PKG_ERRORS Consider adjusting the PKG_CONFIG_PATH environment variable if you installed software in a non-standard prefix. Alternatively, you may set the environment variables SAMBA_CFLAGS and SAMBA_LIBS to avoid the need to call pkg-config. See the pkg-config man page for more details." "$LINENO" 5 elif test $pkg_failed = untried; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 $as_echo "$as_me: error: in \`$ac_pwd':" >&2;} as_fn_error $? "The pkg-config script could not be found or is too old. Make sure it is in your PATH or set the PKG_CONFIG environment variable to the full path to pkg-config. Alternatively, you may set the environment variables SAMBA_CFLAGS and SAMBA_LIBS to avoid the need to call pkg-config. See the pkg-config man page for more details. To get pkg-config, see . See \`config.log' for more details" "$LINENO" 5; } else SAMBA_CFLAGS=$pkg_cv_SAMBA_CFLAGS SAMBA_LIBS=$pkg_cv_SAMBA_LIBS { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 $as_echo "yes" >&6; } fi pkg_failed=no { $as_echo "$as_me:${as_lineno-$LINENO}: checking for SAMBASERVER" >&5 $as_echo_n "checking for SAMBASERVER... " >&6; } if test -n "$SAMBASERVER_CFLAGS"; then pkg_cv_SAMBASERVER_CFLAGS="$SAMBASERVER_CFLAGS" elif test -n "$PKG_CONFIG"; then if test -n "$PKG_CONFIG" && \ { { $as_echo "$as_me:${as_lineno-$LINENO}: \$PKG_CONFIG --exists --print-errors \"dcerpc_server samdb\""; } >&5 ($PKG_CONFIG --exists --print-errors "dcerpc_server samdb") 2>&5 ac_status=$? $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 test $ac_status = 0; }; then pkg_cv_SAMBASERVER_CFLAGS=`$PKG_CONFIG --cflags "dcerpc_server samdb" 2>/dev/null` test "x$?" != "x0" && pkg_failed=yes else pkg_failed=yes fi else pkg_failed=untried fi if test -n "$SAMBASERVER_LIBS"; then pkg_cv_SAMBASERVER_LIBS="$SAMBASERVER_LIBS" elif test -n "$PKG_CONFIG"; then if test -n "$PKG_CONFIG" && \ { { $as_echo "$as_me:${as_lineno-$LINENO}: \$PKG_CONFIG --exists --print-errors \"dcerpc_server samdb\""; } >&5 ($PKG_CONFIG --exists --print-errors "dcerpc_server samdb") 2>&5 ac_status=$? $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 test $ac_status = 0; }; then pkg_cv_SAMBASERVER_LIBS=`$PKG_CONFIG --libs "dcerpc_server samdb" 2>/dev/null` test "x$?" != "x0" && pkg_failed=yes else pkg_failed=yes fi else pkg_failed=untried fi if test $pkg_failed = yes; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } if $PKG_CONFIG --atleast-pkgconfig-version 0.20; then _pkg_short_errors_supported=yes else _pkg_short_errors_supported=no fi if test $_pkg_short_errors_supported = yes; then SAMBASERVER_PKG_ERRORS=`$PKG_CONFIG --short-errors --print-errors --cflags --libs "dcerpc_server samdb" 2>&1` else SAMBASERVER_PKG_ERRORS=`$PKG_CONFIG --print-errors --cflags --libs "dcerpc_server samdb" 2>&1` fi # Put the nasty error message in config.log where it belongs echo "$SAMBASERVER_PKG_ERRORS" >&5 { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: No mapiproxy support" >&5 $as_echo "$as_me: WARNING: No mapiproxy support" >&2;} elif test $pkg_failed = untried; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: No mapiproxy support" >&5 $as_echo "$as_me: WARNING: No mapiproxy support" >&2;} else SAMBASERVER_CFLAGS=$pkg_cv_SAMBASERVER_CFLAGS SAMBASERVER_LIBS=$pkg_cv_SAMBASERVER_LIBS { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 $as_echo "yes" >&6; } fi pkg_failed=no { $as_echo "$as_me:${as_lineno-$LINENO}: checking for TDB" >&5 $as_echo_n "checking for TDB... " >&6; } if test -n "$TDB_CFLAGS"; then pkg_cv_TDB_CFLAGS="$TDB_CFLAGS" elif test -n "$PKG_CONFIG"; then if test -n "$PKG_CONFIG" && \ { { $as_echo "$as_me:${as_lineno-$LINENO}: \$PKG_CONFIG --exists --print-errors \"tdb\""; } >&5 ($PKG_CONFIG --exists --print-errors "tdb") 2>&5 ac_status=$? $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 test $ac_status = 0; }; then pkg_cv_TDB_CFLAGS=`$PKG_CONFIG --cflags "tdb" 2>/dev/null` test "x$?" != "x0" && pkg_failed=yes else pkg_failed=yes fi else pkg_failed=untried fi if test -n "$TDB_LIBS"; then pkg_cv_TDB_LIBS="$TDB_LIBS" elif test -n "$PKG_CONFIG"; then if test -n "$PKG_CONFIG" && \ { { $as_echo "$as_me:${as_lineno-$LINENO}: \$PKG_CONFIG --exists --print-errors \"tdb\""; } >&5 ($PKG_CONFIG --exists --print-errors "tdb") 2>&5 ac_status=$? $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 test $ac_status = 0; }; then pkg_cv_TDB_LIBS=`$PKG_CONFIG --libs "tdb" 2>/dev/null` test "x$?" != "x0" && pkg_failed=yes else pkg_failed=yes fi else pkg_failed=untried fi if test $pkg_failed = yes; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } if $PKG_CONFIG --atleast-pkgconfig-version 0.20; then _pkg_short_errors_supported=yes else _pkg_short_errors_supported=no fi if test $_pkg_short_errors_supported = yes; then TDB_PKG_ERRORS=`$PKG_CONFIG --short-errors --print-errors --cflags --libs "tdb" 2>&1` else TDB_PKG_ERRORS=`$PKG_CONFIG --print-errors --cflags --libs "tdb" 2>&1` fi # Put the nasty error message in config.log where it belongs echo "$TDB_PKG_ERRORS" >&5 as_fn_error $? "Package requirements (tdb) were not met: $TDB_PKG_ERRORS Consider adjusting the PKG_CONFIG_PATH environment variable if you installed software in a non-standard prefix. Alternatively, you may set the environment variables TDB_CFLAGS and TDB_LIBS to avoid the need to call pkg-config. See the pkg-config man page for more details." "$LINENO" 5 elif test $pkg_failed = untried; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 $as_echo "$as_me: error: in \`$ac_pwd':" >&2;} as_fn_error $? "The pkg-config script could not be found or is too old. Make sure it is in your PATH or set the PKG_CONFIG environment variable to the full path to pkg-config. Alternatively, you may set the environment variables TDB_CFLAGS and TDB_LIBS to avoid the need to call pkg-config. See the pkg-config man page for more details. To get pkg-config, see . See \`config.log' for more details" "$LINENO" 5; } else TDB_CFLAGS=$pkg_cv_TDB_CFLAGS TDB_LIBS=$pkg_cv_TDB_LIBS { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 $as_echo "yes" >&6; } fi pkg_failed=no { $as_echo "$as_me:${as_lineno-$LINENO}: checking for LDB" >&5 $as_echo_n "checking for LDB... " >&6; } if test -n "$LDB_CFLAGS"; then pkg_cv_LDB_CFLAGS="$LDB_CFLAGS" elif test -n "$PKG_CONFIG"; then if test -n "$PKG_CONFIG" && \ { { $as_echo "$as_me:${as_lineno-$LINENO}: \$PKG_CONFIG --exists --print-errors \"ldb\""; } >&5 ($PKG_CONFIG --exists --print-errors "ldb") 2>&5 ac_status=$? $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 test $ac_status = 0; }; then pkg_cv_LDB_CFLAGS=`$PKG_CONFIG --cflags "ldb" 2>/dev/null` test "x$?" != "x0" && pkg_failed=yes else pkg_failed=yes fi else pkg_failed=untried fi if test -n "$LDB_LIBS"; then pkg_cv_LDB_LIBS="$LDB_LIBS" elif test -n "$PKG_CONFIG"; then if test -n "$PKG_CONFIG" && \ { { $as_echo "$as_me:${as_lineno-$LINENO}: \$PKG_CONFIG --exists --print-errors \"ldb\""; } >&5 ($PKG_CONFIG --exists --print-errors "ldb") 2>&5 ac_status=$? $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 test $ac_status = 0; }; then pkg_cv_LDB_LIBS=`$PKG_CONFIG --libs "ldb" 2>/dev/null` test "x$?" != "x0" && pkg_failed=yes else pkg_failed=yes fi else pkg_failed=untried fi if test $pkg_failed = yes; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } if $PKG_CONFIG --atleast-pkgconfig-version 0.20; then _pkg_short_errors_supported=yes else _pkg_short_errors_supported=no fi if test $_pkg_short_errors_supported = yes; then LDB_PKG_ERRORS=`$PKG_CONFIG --short-errors --print-errors --cflags --libs "ldb" 2>&1` else LDB_PKG_ERRORS=`$PKG_CONFIG --print-errors --cflags --libs "ldb" 2>&1` fi # Put the nasty error message in config.log where it belongs echo "$LDB_PKG_ERRORS" >&5 as_fn_error $? "Package requirements (ldb) were not met: $LDB_PKG_ERRORS Consider adjusting the PKG_CONFIG_PATH environment variable if you installed software in a non-standard prefix. Alternatively, you may set the environment variables LDB_CFLAGS and LDB_LIBS to avoid the need to call pkg-config. See the pkg-config man page for more details." "$LINENO" 5 elif test $pkg_failed = untried; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 $as_echo "$as_me: error: in \`$ac_pwd':" >&2;} as_fn_error $? "The pkg-config script could not be found or is too old. Make sure it is in your PATH or set the PKG_CONFIG environment variable to the full path to pkg-config. Alternatively, you may set the environment variables LDB_CFLAGS and LDB_LIBS to avoid the need to call pkg-config. See the pkg-config man page for more details. To get pkg-config, see . See \`config.log' for more details" "$LINENO" 5; } else LDB_CFLAGS=$pkg_cv_LDB_CFLAGS LDB_LIBS=$pkg_cv_LDB_LIBS { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 $as_echo "yes" >&6; } fi oc_save_CPPFLAGS="$CPPFLAGS" CPPFLAGS="$CPPFLAGS `$PKG_CONFIG --cflags-only-I samba-hostconfig`" ac_fn_c_check_header_mongrel "$LINENO" "samba/version.h" "ac_cv_header_samba_version_h" "$ac_includes_default" if test "x$ac_cv_header_samba_version_h" = xyes; then : else as_fn_error $? "Could not find Samba4 headers. Re-run ./configure with --with-samba=XXX where XXX is the prefix that Samba4 was installed to." "$LINENO" 5 fi . `dirname $0`/script/samba4_ver.sh if test "$cross_compiling" = yes; then : { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 $as_echo "$as_me: error: in \`$ac_pwd':" >&2;} as_fn_error $? "cannot run test program while cross compiling See \`config.log' for more details" "$LINENO" 5; } else cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include int main() { if (!strcmp(SAMBA_VERSION_STRING, "$SAMBA4_RELEASE") || !strcmp(SAMBA_VERSION_STRING, "$SAMBA4_GIT_VER-GIT-$SAMBA4_GIT_REV")) {return 0; } else { return -1;} } _ACEOF if ac_fn_c_try_run "$LINENO"; then : else { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: The Samba4 version installed on your system doesn't meet OpenChange requirements ($SAMBA4_RELEASE or $SAMBA4_GIT_VER-GIT-$SAMBA4_GIT_REV)." >&5 $as_echo "$as_me: WARNING: The Samba4 version installed on your system doesn't meet OpenChange requirements ($SAMBA4_RELEASE or $SAMBA4_GIT_VER-GIT-$SAMBA4_GIT_REV)." >&2;} fi rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext \ conftest.$ac_objext conftest.beam conftest.$ac_ext fi CPPFLAGS="$oc_save_CPPFLAGS" { $as_echo "$as_me:${as_lineno-$LINENO}: checking for DCE/RPC server modules directory" >&5 $as_echo_n "checking for DCE/RPC server modules directory... " >&6; } DCERPC_SERVER_MODULESDIR=`$PKG_CONFIG --variable=modulesdir dcerpc_server` { $as_echo "$as_me:${as_lineno-$LINENO}: result: $DCERPC_SERVER_MODULESDIR" >&5 $as_echo "$DCERPC_SERVER_MODULESDIR" >&6; } if test "x$SAMBA_LIBS" != "x" ; then libmapi=1 fi if test "x${libmapi}set" != "xset"; then case "LIBS" in LIBS) OC_LIBS="$OC_LIBS libmapi" OC_LIBS_INSTALL="$OC_LIBS_INSTALL libmapi-install" OC_LIBS_UNINSTALL="$OC_LIBS_UNINSTALL libmapi-uninstall" OC_LIBS_INSTALLPC="$OC_LIBS_INSTALLPC libmapi-installpc" OC_LIBS_INSTALLHEADER="$OC_LIBS_INSTALLHEADER libmapi-installheader" OC_LIBS_INSTALLLIB="$OC_LIBS_INSTALLLIB libmapi-installlib" ;; TOOLS) OC_LIBS="$OC_LIBS libmapi" OC_LIBS_INSTALL="$OC_LIBS_INSTALL libmapi-install" OC_LIBS_UNINSTALL="$OC_LIBS_UNINSTALL libmapi-uninstall" ;; SERVER|MAPISTORE) OC_LIBS="$OC_LIBS libmapi" OC_LIBS_CLEAN="$OC_LIBS_CLEAN libmapi-clean" OC_LIBS_INSTALL="$OC_LIBS_INSTALL libmapi-install" OC_LIBS_UNINSTALL="$OC_LIBS_UNINSTALL libmapi-uninstall" ;; esac enable_libmapi="yes" fi OC_IDL="idl" { $as_echo "$as_me:${as_lineno-$LINENO}: checking for dlopen in -ldl" >&5 $as_echo_n "checking for dlopen in -ldl... " >&6; } if ${ac_cv_lib_dl_dlopen+:} false; then : $as_echo_n "(cached) " >&6 else ac_check_lib_save_LIBS=$LIBS LIBS="-ldl $LIBS" cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ /* Override any GCC internal prototype to avoid an error. Use char because int might match the return type of a GCC builtin and then its argument prototype would still apply. */ #ifdef __cplusplus extern "C" #endif char dlopen (); int main () { return dlopen (); ; return 0; } _ACEOF if ac_fn_c_try_link "$LINENO"; then : ac_cv_lib_dl_dlopen=yes else ac_cv_lib_dl_dlopen=no fi rm -f core conftest.err conftest.$ac_objext \ conftest$ac_exeext conftest.$ac_ext LIBS=$ac_check_lib_save_LIBS fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_dl_dlopen" >&5 $as_echo "$ac_cv_lib_dl_dlopen" >&6; } if test "x$ac_cv_lib_dl_dlopen" = xyes; then : DL_LIBS="-ldl" else for ac_func in dlopen do : ac_fn_c_check_func "$LINENO" "dlopen" "ac_cv_func_dlopen" if test "x$ac_cv_func_dlopen" = xyes; then : cat >>confdefs.h <<_ACEOF #define HAVE_DLOPEN 1 _ACEOF DL_LIBS="" else as_fn_error $? "unable to find dlopen" "$LINENO" 5 fi done fi enable_pthread=no enable_thread_lib="" { $as_echo "$as_me:${as_lineno-$LINENO}: checking for pthread_mutex_init in -lpthread" >&5 $as_echo_n "checking for pthread_mutex_init in -lpthread... " >&6; } if ${ac_cv_lib_pthread_pthread_mutex_init+:} false; then : $as_echo_n "(cached) " >&6 else ac_check_lib_save_LIBS=$LIBS LIBS="-lpthread $LIBS" cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ /* Override any GCC internal prototype to avoid an error. Use char because int might match the return type of a GCC builtin and then its argument prototype would still apply. */ #ifdef __cplusplus extern "C" #endif char pthread_mutex_init (); int main () { return pthread_mutex_init (); ; return 0; } _ACEOF if ac_fn_c_try_link "$LINENO"; then : ac_cv_lib_pthread_pthread_mutex_init=yes else ac_cv_lib_pthread_pthread_mutex_init=no fi rm -f core conftest.err conftest.$ac_objext \ conftest$ac_exeext conftest.$ac_ext LIBS=$ac_check_lib_save_LIBS fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_pthread_pthread_mutex_init" >&5 $as_echo "$ac_cv_lib_pthread_pthread_mutex_init" >&6; } if test "x$ac_cv_lib_pthread_pthread_mutex_init" = xyes; then : $as_echo "#define HAVE_PTHREADS 1" >>confdefs.h THREAD_LIBS=-lpthread enable_pthread="yes" enable_thread_lib="(pthread)" else { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: pthread is missing - library is not thread safe" >&5 $as_echo "$as_me: WARNING: pthread is missing - library is not thread safe" >&2;} enable_pthread="no" fi if test x"$enable_pthread" = x"no"; then pkg_failed=no { $as_echo "$as_me:${as_lineno-$LINENO}: checking for GTHREAD" >&5 $as_echo_n "checking for GTHREAD... " >&6; } if test -n "$GTHREAD_CFLAGS"; then pkg_cv_GTHREAD_CFLAGS="$GTHREAD_CFLAGS" elif test -n "$PKG_CONFIG"; then if test -n "$PKG_CONFIG" && \ { { $as_echo "$as_me:${as_lineno-$LINENO}: \$PKG_CONFIG --exists --print-errors \"gthread-2.0\""; } >&5 ($PKG_CONFIG --exists --print-errors "gthread-2.0") 2>&5 ac_status=$? $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 test $ac_status = 0; }; then pkg_cv_GTHREAD_CFLAGS=`$PKG_CONFIG --cflags "gthread-2.0" 2>/dev/null` test "x$?" != "x0" && pkg_failed=yes else pkg_failed=yes fi else pkg_failed=untried fi if test -n "$GTHREAD_LIBS"; then pkg_cv_GTHREAD_LIBS="$GTHREAD_LIBS" elif test -n "$PKG_CONFIG"; then if test -n "$PKG_CONFIG" && \ { { $as_echo "$as_me:${as_lineno-$LINENO}: \$PKG_CONFIG --exists --print-errors \"gthread-2.0\""; } >&5 ($PKG_CONFIG --exists --print-errors "gthread-2.0") 2>&5 ac_status=$? $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 test $ac_status = 0; }; then pkg_cv_GTHREAD_LIBS=`$PKG_CONFIG --libs "gthread-2.0" 2>/dev/null` test "x$?" != "x0" && pkg_failed=yes else pkg_failed=yes fi else pkg_failed=untried fi if test $pkg_failed = yes; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } if $PKG_CONFIG --atleast-pkgconfig-version 0.20; then _pkg_short_errors_supported=yes else _pkg_short_errors_supported=no fi if test $_pkg_short_errors_supported = yes; then GTHREAD_PKG_ERRORS=`$PKG_CONFIG --short-errors --print-errors --cflags --libs "gthread-2.0" 2>&1` else GTHREAD_PKG_ERRORS=`$PKG_CONFIG --print-errors --cflags --libs "gthread-2.0" 2>&1` fi # Put the nasty error message in config.log where it belongs echo "$GTHREAD_PKG_ERRORS" >&5 enable_pthread=no elif test $pkg_failed = untried; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } enable_pthread=no else GTHREAD_CFLAGS=$pkg_cv_GTHREAD_CFLAGS GTHREAD_LIBS=$pkg_cv_GTHREAD_LIBS { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 $as_echo "yes" >&6; } $as_echo "#define HAVE_GTHREAD 1" >>confdefs.h THREAD_LIBS=$GTHREAD_LIBS THREAD_CFLAGS=$GTHREAD_CFLAGS enable_pthread=yes enable_thread_lib="(gthread)" fi fi ac_ext=cpp ac_cpp='$CXXCPP $CPPFLAGS' ac_compile='$CXX -c $CXXFLAGS $CPPFLAGS conftest.$ac_ext >&5' ac_link='$CXX -o conftest$ac_exeext $CXXFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' ac_compiler_gnu=$ac_cv_cxx_compiler_gnu if test -z "$CXX"; then if test -n "$CCC"; then CXX=$CCC else if test -n "$ac_tool_prefix"; then for ac_prog in g++ c++ gpp aCC CC cxx cc++ cl.exe FCC KCC RCC xlC_r xlC do # Extract the first word of "$ac_tool_prefix$ac_prog", so it can be a program name with args. set dummy $ac_tool_prefix$ac_prog; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } if ${ac_cv_prog_CXX+:} false; then : $as_echo_n "(cached) " >&6 else if test -n "$CXX"; then ac_cv_prog_CXX="$CXX" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then ac_cv_prog_CXX="$ac_tool_prefix$ac_prog" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS fi fi CXX=$ac_cv_prog_CXX if test -n "$CXX"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: $CXX" >&5 $as_echo "$CXX" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi test -n "$CXX" && break done fi if test -z "$CXX"; then ac_ct_CXX=$CXX for ac_prog in g++ c++ gpp aCC CC cxx cc++ cl.exe FCC KCC RCC xlC_r xlC do # Extract the first word of "$ac_prog", so it can be a program name with args. set dummy $ac_prog; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } if ${ac_cv_prog_ac_ct_CXX+:} false; then : $as_echo_n "(cached) " >&6 else if test -n "$ac_ct_CXX"; then ac_cv_prog_ac_ct_CXX="$ac_ct_CXX" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then ac_cv_prog_ac_ct_CXX="$ac_prog" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS fi fi ac_ct_CXX=$ac_cv_prog_ac_ct_CXX if test -n "$ac_ct_CXX"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_CXX" >&5 $as_echo "$ac_ct_CXX" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi test -n "$ac_ct_CXX" && break done if test "x$ac_ct_CXX" = x; then CXX="g++" else case $cross_compiling:$ac_tool_warned in yes:) { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 $as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} ac_tool_warned=yes ;; esac CXX=$ac_ct_CXX fi fi fi fi # Provide some information about the compiler. $as_echo "$as_me:${as_lineno-$LINENO}: checking for C++ compiler version" >&5 set X $ac_compile ac_compiler=$2 for ac_option in --version -v -V -qversion; do { { ac_try="$ac_compiler $ac_option >&5" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" $as_echo "$ac_try_echo"; } >&5 (eval "$ac_compiler $ac_option >&5") 2>conftest.err ac_status=$? if test -s conftest.err; then sed '10a\ ... rest of stderr output deleted ... 10q' conftest.err >conftest.er1 cat conftest.er1 >&5 fi rm -f conftest.er1 conftest.err $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 test $ac_status = 0; } done { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether we are using the GNU C++ compiler" >&5 $as_echo_n "checking whether we are using the GNU C++ compiler... " >&6; } if ${ac_cv_cxx_compiler_gnu+:} false; then : $as_echo_n "(cached) " >&6 else cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ int main () { #ifndef __GNUC__ choke me #endif ; return 0; } _ACEOF if ac_fn_cxx_try_compile "$LINENO"; then : ac_compiler_gnu=yes else ac_compiler_gnu=no fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext ac_cv_cxx_compiler_gnu=$ac_compiler_gnu fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_cxx_compiler_gnu" >&5 $as_echo "$ac_cv_cxx_compiler_gnu" >&6; } if test $ac_compiler_gnu = yes; then GXX=yes else GXX= fi ac_test_CXXFLAGS=${CXXFLAGS+set} ac_save_CXXFLAGS=$CXXFLAGS { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether $CXX accepts -g" >&5 $as_echo_n "checking whether $CXX accepts -g... " >&6; } if ${ac_cv_prog_cxx_g+:} false; then : $as_echo_n "(cached) " >&6 else ac_save_cxx_werror_flag=$ac_cxx_werror_flag ac_cxx_werror_flag=yes ac_cv_prog_cxx_g=no CXXFLAGS="-g" cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ int main () { ; return 0; } _ACEOF if ac_fn_cxx_try_compile "$LINENO"; then : ac_cv_prog_cxx_g=yes else CXXFLAGS="" cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ int main () { ; return 0; } _ACEOF if ac_fn_cxx_try_compile "$LINENO"; then : else ac_cxx_werror_flag=$ac_save_cxx_werror_flag CXXFLAGS="-g" cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ int main () { ; return 0; } _ACEOF if ac_fn_cxx_try_compile "$LINENO"; then : ac_cv_prog_cxx_g=yes fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext ac_cxx_werror_flag=$ac_save_cxx_werror_flag fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_prog_cxx_g" >&5 $as_echo "$ac_cv_prog_cxx_g" >&6; } if test "$ac_test_CXXFLAGS" = set; then CXXFLAGS=$ac_save_CXXFLAGS elif test $ac_cv_prog_cxx_g = yes; then if test "$GXX" = yes; then CXXFLAGS="-g -O2" else CXXFLAGS="-g" fi else if test "$GXX" = yes; then CXXFLAGS="-O2" else CXXFLAGS= fi fi ac_ext=cpp ac_cpp='$CXXCPP $CPPFLAGS' ac_compile='$CXX -c $CXXFLAGS $CPPFLAGS conftest.$ac_ext >&5' ac_link='$CXX -o conftest$ac_exeext $CXXFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' ac_compiler_gnu=$ac_cv_cxx_compiler_gnu depcc="$CXX" am_compiler_list= { $as_echo "$as_me:${as_lineno-$LINENO}: checking dependency style of $depcc" >&5 $as_echo_n "checking dependency style of $depcc... " >&6; } if ${am_cv_CXX_dependencies_compiler_type+:} false; then : $as_echo_n "(cached) " >&6 else if test -z "$AMDEP_TRUE" && test -f "$am_depcomp"; then # We make a subdir and do the tests there. Otherwise we can end up # making bogus files that we don't know about and never remove. For # instance it was reported that on HP-UX the gcc test will end up # making a dummy file named `D' -- because `-MD' means `put the output # in D'. rm -rf conftest.dir mkdir conftest.dir # Copy depcomp to subdir because otherwise we won't find it if we're # using a relative directory. cp "$am_depcomp" conftest.dir cd conftest.dir # We will build objects and dependencies in a subdirectory because # it helps to detect inapplicable dependency modes. For instance # both Tru64's cc and ICC support -MD to output dependencies as a # side effect of compilation, but ICC will put the dependencies in # the current directory while Tru64 will put them in the object # directory. mkdir sub am_cv_CXX_dependencies_compiler_type=none if test "$am_compiler_list" = ""; then am_compiler_list=`sed -n 's/^#*\([a-zA-Z0-9]*\))$/\1/p' < ./depcomp` fi am__universal=false case " $depcc " in #( *\ -arch\ *\ -arch\ *) am__universal=true ;; esac for depmode in $am_compiler_list; do # Setup a source with many dependencies, because some compilers # like to wrap large dependency lists on column 80 (with \), and # we should not choose a depcomp mode which is confused by this. # # We need to recreate these files for each test, as the compiler may # overwrite some of them when testing with obscure command lines. # This happens at least with the AIX C compiler. : > sub/conftest.c for i in 1 2 3 4 5 6; do echo '#include "conftst'$i'.h"' >> sub/conftest.c # Using `: > sub/conftst$i.h' creates only sub/conftst1.h with # Solaris 8's {/usr,}/bin/sh. touch sub/conftst$i.h done echo "${am__include} ${am__quote}sub/conftest.Po${am__quote}" > confmf # We check with `-c' and `-o' for the sake of the "dashmstdout" # mode. It turns out that the SunPro C++ compiler does not properly # handle `-M -o', and we need to detect this. Also, some Intel # versions had trouble with output in subdirs am__obj=sub/conftest.${OBJEXT-o} am__minus_obj="-o $am__obj" case $depmode in gcc) # This depmode causes a compiler race in universal mode. test "$am__universal" = false || continue ;; nosideeffect) # after this tag, mechanisms are not by side-effect, so they'll # only be used when explicitly requested if test "x$enable_dependency_tracking" = xyes; then continue else break fi ;; msvc7 | msvc7msys | msvisualcpp | msvcmsys) # This compiler won't grok `-c -o', but also, the minuso test has # not run yet. These depmodes are late enough in the game, and # so weak that their functioning should not be impacted. am__obj=conftest.${OBJEXT-o} am__minus_obj= ;; none) break ;; esac if depmode=$depmode \ source=sub/conftest.c object=$am__obj \ depfile=sub/conftest.Po tmpdepfile=sub/conftest.TPo \ $SHELL ./depcomp $depcc -c $am__minus_obj sub/conftest.c \ >/dev/null 2>conftest.err && grep sub/conftst1.h sub/conftest.Po > /dev/null 2>&1 && grep sub/conftst6.h sub/conftest.Po > /dev/null 2>&1 && grep $am__obj sub/conftest.Po > /dev/null 2>&1 && ${MAKE-make} -s -f confmf > /dev/null 2>&1; then # icc doesn't choke on unknown options, it will just issue warnings # or remarks (even with -Werror). So we grep stderr for any message # that says an option was ignored or not supported. # When given -MP, icc 7.0 and 7.1 complain thusly: # icc: Command line warning: ignoring option '-M'; no argument required # The diagnosis changed in icc 8.0: # icc: Command line remark: option '-MP' not supported if (grep 'ignoring option' conftest.err || grep 'not supported' conftest.err) >/dev/null 2>&1; then :; else am_cv_CXX_dependencies_compiler_type=$depmode break fi fi done cd .. rm -rf conftest.dir else am_cv_CXX_dependencies_compiler_type=none fi fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $am_cv_CXX_dependencies_compiler_type" >&5 $as_echo "$am_cv_CXX_dependencies_compiler_type" >&6; } CXXDEPMODE=depmode=$am_cv_CXX_dependencies_compiler_type if test "x$enable_dependency_tracking" != xno \ && test "$am_cv_CXX_dependencies_compiler_type" = gcc3; then am__fastdepCXX_TRUE= am__fastdepCXX_FALSE='#' else am__fastdepCXX_TRUE='#' am__fastdepCXX_FALSE= fi { $as_echo "$as_me:${as_lineno-$LINENO}: checking C++ compiler availability" >&5 $as_echo_n "checking C++ compiler availability... " >&6; } if ${ac_cv_libmapixx_gxx_works+:} false; then : $as_echo_n "(cached) " >&6 else ac_ext=cpp ac_cpp='$CXXCPP $CPPFLAGS' ac_compile='$CXX -c $CXXFLAGS $CPPFLAGS conftest.$ac_ext >&5' ac_link='$CXX -o conftest$ac_exeext $CXXFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' ac_compiler_gnu=$ac_cv_cxx_compiler_gnu cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ int main() { return 0; } _ACEOF if ac_fn_cxx_try_compile "$LINENO"; then : ac_cv_libmapixx_gxx_works=yes else ac_cv_libmapixx_gxx_works=no fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext ac_ext=c ac_cpp='$CPP $CPPFLAGS' ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' ac_compiler_gnu=$ac_cv_c_compiler_gnu fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_libmapixx_gxx_works" >&5 $as_echo "$ac_cv_libmapixx_gxx_works" >&6; } { $as_echo "$as_me:${as_lineno-$LINENO}: checking for boost_thread$BOOST_LIB_SUFFIX library" >&5 $as_echo_n "checking for boost_thread$BOOST_LIB_SUFFIX library... " >&6; } if ${ov_cv_boost_thread+:} false; then : $as_echo_n "(cached) " >&6 else ov_cv_boost_thread=no ov_save_LIBS=$LIBS LIBS="-lboost_thread$BOOST_LIB_SUFFIX $LIBS" ac_ext=cpp ac_cpp='$CXXCPP $CPPFLAGS' ac_compile='$CXX -c $CXXFLAGS $CPPFLAGS conftest.$ac_ext >&5' ac_link='$CXX -o conftest$ac_exeext $CXXFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' ac_compiler_gnu=$ac_cv_cxx_compiler_gnu cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include int main () { boost::thread t ; return 0; } _ACEOF if ac_fn_cxx_try_link "$LINENO"; then : ov_cv_boost_thread=yes fi rm -f core conftest.err conftest.$ac_objext \ conftest$ac_exeext conftest.$ac_ext ac_ext=c ac_cpp='$CPP $CPPFLAGS' ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' ac_compiler_gnu=$ac_cv_c_compiler_gnu LIBS=$ov_save_LIBS fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ov_cv_boost_thread" >&5 $as_echo "$ov_cv_boost_thread" >&6; } if test x"$ac_cv_libmapixx_gxx_works" = "xyes"; then if test x"$ov_cv_boost_thread" = "xyes"; then ac_ext=cpp ac_cpp='$CXXCPP $CPPFLAGS' ac_compile='$CXX -c $CXXFLAGS $CPPFLAGS conftest.$ac_ext >&5' ac_link='$CXX -o conftest$ac_exeext $CXXFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' ac_compiler_gnu=$ac_cv_cxx_compiler_gnu if test -z "$CXX"; then if test -n "$CCC"; then CXX=$CCC else if test -n "$ac_tool_prefix"; then for ac_prog in g++ c++ gpp aCC CC cxx cc++ cl.exe FCC KCC RCC xlC_r xlC do # Extract the first word of "$ac_tool_prefix$ac_prog", so it can be a program name with args. set dummy $ac_tool_prefix$ac_prog; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } if ${ac_cv_prog_CXX+:} false; then : $as_echo_n "(cached) " >&6 else if test -n "$CXX"; then ac_cv_prog_CXX="$CXX" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then ac_cv_prog_CXX="$ac_tool_prefix$ac_prog" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS fi fi CXX=$ac_cv_prog_CXX if test -n "$CXX"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: $CXX" >&5 $as_echo "$CXX" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi test -n "$CXX" && break done fi if test -z "$CXX"; then ac_ct_CXX=$CXX for ac_prog in g++ c++ gpp aCC CC cxx cc++ cl.exe FCC KCC RCC xlC_r xlC do # Extract the first word of "$ac_prog", so it can be a program name with args. set dummy $ac_prog; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } if ${ac_cv_prog_ac_ct_CXX+:} false; then : $as_echo_n "(cached) " >&6 else if test -n "$ac_ct_CXX"; then ac_cv_prog_ac_ct_CXX="$ac_ct_CXX" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then ac_cv_prog_ac_ct_CXX="$ac_prog" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS fi fi ac_ct_CXX=$ac_cv_prog_ac_ct_CXX if test -n "$ac_ct_CXX"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_CXX" >&5 $as_echo "$ac_ct_CXX" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi test -n "$ac_ct_CXX" && break done if test "x$ac_ct_CXX" = x; then CXX="g++" else case $cross_compiling:$ac_tool_warned in yes:) { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 $as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} ac_tool_warned=yes ;; esac CXX=$ac_ct_CXX fi fi fi fi # Provide some information about the compiler. $as_echo "$as_me:${as_lineno-$LINENO}: checking for C++ compiler version" >&5 set X $ac_compile ac_compiler=$2 for ac_option in --version -v -V -qversion; do { { ac_try="$ac_compiler $ac_option >&5" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" $as_echo "$ac_try_echo"; } >&5 (eval "$ac_compiler $ac_option >&5") 2>conftest.err ac_status=$? if test -s conftest.err; then sed '10a\ ... rest of stderr output deleted ... 10q' conftest.err >conftest.er1 cat conftest.er1 >&5 fi rm -f conftest.er1 conftest.err $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 test $ac_status = 0; } done { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether we are using the GNU C++ compiler" >&5 $as_echo_n "checking whether we are using the GNU C++ compiler... " >&6; } if ${ac_cv_cxx_compiler_gnu+:} false; then : $as_echo_n "(cached) " >&6 else cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ int main () { #ifndef __GNUC__ choke me #endif ; return 0; } _ACEOF if ac_fn_cxx_try_compile "$LINENO"; then : ac_compiler_gnu=yes else ac_compiler_gnu=no fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext ac_cv_cxx_compiler_gnu=$ac_compiler_gnu fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_cxx_compiler_gnu" >&5 $as_echo "$ac_cv_cxx_compiler_gnu" >&6; } if test $ac_compiler_gnu = yes; then GXX=yes else GXX= fi ac_test_CXXFLAGS=${CXXFLAGS+set} ac_save_CXXFLAGS=$CXXFLAGS { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether $CXX accepts -g" >&5 $as_echo_n "checking whether $CXX accepts -g... " >&6; } if ${ac_cv_prog_cxx_g+:} false; then : $as_echo_n "(cached) " >&6 else ac_save_cxx_werror_flag=$ac_cxx_werror_flag ac_cxx_werror_flag=yes ac_cv_prog_cxx_g=no CXXFLAGS="-g" cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ int main () { ; return 0; } _ACEOF if ac_fn_cxx_try_compile "$LINENO"; then : ac_cv_prog_cxx_g=yes else CXXFLAGS="" cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ int main () { ; return 0; } _ACEOF if ac_fn_cxx_try_compile "$LINENO"; then : else ac_cxx_werror_flag=$ac_save_cxx_werror_flag CXXFLAGS="-g" cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ int main () { ; return 0; } _ACEOF if ac_fn_cxx_try_compile "$LINENO"; then : ac_cv_prog_cxx_g=yes fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext ac_cxx_werror_flag=$ac_save_cxx_werror_flag fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_prog_cxx_g" >&5 $as_echo "$ac_cv_prog_cxx_g" >&6; } if test "$ac_test_CXXFLAGS" = set; then CXXFLAGS=$ac_save_CXXFLAGS elif test $ac_cv_prog_cxx_g = yes; then if test "$GXX" = yes; then CXXFLAGS="-g -O2" else CXXFLAGS="-g" fi else if test "$GXX" = yes; then CXXFLAGS="-O2" else CXXFLAGS= fi fi ac_ext=c ac_cpp='$CPP $CPPFLAGS' ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' ac_compiler_gnu=$ac_cv_c_compiler_gnu depcc="$CXX" am_compiler_list= { $as_echo "$as_me:${as_lineno-$LINENO}: checking dependency style of $depcc" >&5 $as_echo_n "checking dependency style of $depcc... " >&6; } if ${am_cv_CXX_dependencies_compiler_type+:} false; then : $as_echo_n "(cached) " >&6 else if test -z "$AMDEP_TRUE" && test -f "$am_depcomp"; then # We make a subdir and do the tests there. Otherwise we can end up # making bogus files that we don't know about and never remove. For # instance it was reported that on HP-UX the gcc test will end up # making a dummy file named `D' -- because `-MD' means `put the output # in D'. rm -rf conftest.dir mkdir conftest.dir # Copy depcomp to subdir because otherwise we won't find it if we're # using a relative directory. cp "$am_depcomp" conftest.dir cd conftest.dir # We will build objects and dependencies in a subdirectory because # it helps to detect inapplicable dependency modes. For instance # both Tru64's cc and ICC support -MD to output dependencies as a # side effect of compilation, but ICC will put the dependencies in # the current directory while Tru64 will put them in the object # directory. mkdir sub am_cv_CXX_dependencies_compiler_type=none if test "$am_compiler_list" = ""; then am_compiler_list=`sed -n 's/^#*\([a-zA-Z0-9]*\))$/\1/p' < ./depcomp` fi am__universal=false case " $depcc " in #( *\ -arch\ *\ -arch\ *) am__universal=true ;; esac for depmode in $am_compiler_list; do # Setup a source with many dependencies, because some compilers # like to wrap large dependency lists on column 80 (with \), and # we should not choose a depcomp mode which is confused by this. # # We need to recreate these files for each test, as the compiler may # overwrite some of them when testing with obscure command lines. # This happens at least with the AIX C compiler. : > sub/conftest.c for i in 1 2 3 4 5 6; do echo '#include "conftst'$i'.h"' >> sub/conftest.c # Using `: > sub/conftst$i.h' creates only sub/conftst1.h with # Solaris 8's {/usr,}/bin/sh. touch sub/conftst$i.h done echo "${am__include} ${am__quote}sub/conftest.Po${am__quote}" > confmf # We check with `-c' and `-o' for the sake of the "dashmstdout" # mode. It turns out that the SunPro C++ compiler does not properly # handle `-M -o', and we need to detect this. Also, some Intel # versions had trouble with output in subdirs am__obj=sub/conftest.${OBJEXT-o} am__minus_obj="-o $am__obj" case $depmode in gcc) # This depmode causes a compiler race in universal mode. test "$am__universal" = false || continue ;; nosideeffect) # after this tag, mechanisms are not by side-effect, so they'll # only be used when explicitly requested if test "x$enable_dependency_tracking" = xyes; then continue else break fi ;; msvc7 | msvc7msys | msvisualcpp | msvcmsys) # This compiler won't grok `-c -o', but also, the minuso test has # not run yet. These depmodes are late enough in the game, and # so weak that their functioning should not be impacted. am__obj=conftest.${OBJEXT-o} am__minus_obj= ;; none) break ;; esac if depmode=$depmode \ source=sub/conftest.c object=$am__obj \ depfile=sub/conftest.Po tmpdepfile=sub/conftest.TPo \ $SHELL ./depcomp $depcc -c $am__minus_obj sub/conftest.c \ >/dev/null 2>conftest.err && grep sub/conftst1.h sub/conftest.Po > /dev/null 2>&1 && grep sub/conftst6.h sub/conftest.Po > /dev/null 2>&1 && grep $am__obj sub/conftest.Po > /dev/null 2>&1 && ${MAKE-make} -s -f confmf > /dev/null 2>&1; then # icc doesn't choke on unknown options, it will just issue warnings # or remarks (even with -Werror). So we grep stderr for any message # that says an option was ignored or not supported. # When given -MP, icc 7.0 and 7.1 complain thusly: # icc: Command line warning: ignoring option '-M'; no argument required # The diagnosis changed in icc 8.0: # icc: Command line remark: option '-MP' not supported if (grep 'ignoring option' conftest.err || grep 'not supported' conftest.err) >/dev/null 2>&1; then :; else am_cv_CXX_dependencies_compiler_type=$depmode break fi fi done cd .. rm -rf conftest.dir else am_cv_CXX_dependencies_compiler_type=none fi fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $am_cv_CXX_dependencies_compiler_type" >&5 $as_echo "$am_cv_CXX_dependencies_compiler_type" >&6; } CXXDEPMODE=depmode=$am_cv_CXX_dependencies_compiler_type if test "x$enable_dependency_tracking" != xno \ && test "$am_cv_CXX_dependencies_compiler_type" = gcc3; then am__fastdepCXX_TRUE= am__fastdepCXX_FALSE='#' else am__fastdepCXX_TRUE='#' am__fastdepCXX_FALSE= fi libmapixx=1 if test "x${libmapixx}set" != "xset"; then case "LIBS" in LIBS) OC_LIBS="$OC_LIBS libmapixx" OC_LIBS_INSTALL="$OC_LIBS_INSTALL libmapixx-install" OC_LIBS_UNINSTALL="$OC_LIBS_UNINSTALL libmapixx-uninstall" OC_LIBS_INSTALLPC="$OC_LIBS_INSTALLPC libmapixx-installpc" OC_LIBS_INSTALLHEADER="$OC_LIBS_INSTALLHEADER libmapixx-installheader" OC_LIBS_INSTALLLIB="$OC_LIBS_INSTALLLIB libmapixx-installlib" ;; TOOLS) OC_LIBS="$OC_LIBS libmapixx" OC_LIBS_INSTALL="$OC_LIBS_INSTALL libmapixx-install" OC_LIBS_UNINSTALL="$OC_LIBS_UNINSTALL libmapixx-uninstall" ;; SERVER|MAPISTORE) OC_LIBS="$OC_LIBS libmapixx" OC_LIBS_CLEAN="$OC_LIBS_CLEAN libmapixx-clean" OC_LIBS_INSTALL="$OC_LIBS_INSTALL libmapixx-install" OC_LIBS_UNINSTALL="$OC_LIBS_UNINSTALL libmapixx-uninstall" ;; esac enable_libmapixx="yes" fi fi fi if test x"$OPENCHANGE_VERSION_IS_SVN_SNAPSHOT" = x"yes"; then # Extract the first word of "bison", so it can be a program name with args. set dummy bison; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } if ${ac_cv_path_BISON+:} false; then : $as_echo_n "(cached) " >&6 else case $BISON in [\\/]* | ?:[\\/]*) ac_cv_path_BISON="$BISON" # Let the user override the test with a path. ;; *) as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then ac_cv_path_BISON="$as_dir/$ac_word$ac_exec_ext" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS test -z "$ac_cv_path_BISON" && ac_cv_path_BISON="bison" ;; esac fi BISON=$ac_cv_path_BISON if test -n "$BISON"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: $BISON" >&5 $as_echo "$BISON" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi if test x"$BISON" != x""; then libocpf=1 if test "x${libocpf}set" != "xset"; then case "LIBS" in LIBS) OC_LIBS="$OC_LIBS libocpf" OC_LIBS_INSTALL="$OC_LIBS_INSTALL libocpf-install" OC_LIBS_UNINSTALL="$OC_LIBS_UNINSTALL libocpf-uninstall" OC_LIBS_INSTALLPC="$OC_LIBS_INSTALLPC libocpf-installpc" OC_LIBS_INSTALLHEADER="$OC_LIBS_INSTALLHEADER libocpf-installheader" OC_LIBS_INSTALLLIB="$OC_LIBS_INSTALLLIB libocpf-installlib" ;; TOOLS) OC_LIBS="$OC_LIBS libocpf" OC_LIBS_INSTALL="$OC_LIBS_INSTALL libocpf-install" OC_LIBS_UNINSTALL="$OC_LIBS_UNINSTALL libocpf-uninstall" ;; SERVER|MAPISTORE) OC_LIBS="$OC_LIBS libocpf" OC_LIBS_CLEAN="$OC_LIBS_CLEAN libocpf-clean" OC_LIBS_INSTALL="$OC_LIBS_INSTALL libocpf-install" OC_LIBS_UNINSTALL="$OC_LIBS_UNINSTALL libocpf-uninstall" ;; esac enable_libocpf="yes" fi fi else libocpf=1 if test "x${libocpf}set" != "xset"; then case "LIBS" in LIBS) OC_LIBS="$OC_LIBS libocpf" OC_LIBS_INSTALL="$OC_LIBS_INSTALL libocpf-install" OC_LIBS_UNINSTALL="$OC_LIBS_UNINSTALL libocpf-uninstall" OC_LIBS_INSTALLPC="$OC_LIBS_INSTALLPC libocpf-installpc" OC_LIBS_INSTALLHEADER="$OC_LIBS_INSTALLHEADER libocpf-installheader" OC_LIBS_INSTALLLIB="$OC_LIBS_INSTALLLIB libocpf-installlib" ;; TOOLS) OC_LIBS="$OC_LIBS libocpf" OC_LIBS_INSTALL="$OC_LIBS_INSTALL libocpf-install" OC_LIBS_UNINSTALL="$OC_LIBS_UNINSTALL libocpf-uninstall" ;; SERVER|MAPISTORE) OC_LIBS="$OC_LIBS libocpf" OC_LIBS_CLEAN="$OC_LIBS_CLEAN libocpf-clean" OC_LIBS_INSTALL="$OC_LIBS_INSTALL libocpf-install" OC_LIBS_UNINSTALL="$OC_LIBS_UNINSTALL libocpf-uninstall" ;; esac enable_libocpf="yes" fi fi if test -n "$PKG_CONFIG" && \ { { $as_echo "$as_me:${as_lineno-$LINENO}: \$PKG_CONFIG --exists --print-errors \" dcerpc_samr \""; } >&5 ($PKG_CONFIG --exists --print-errors " dcerpc_samr ") 2>&5 ac_status=$? $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 test $ac_status = 0; }; then enable_libmapiadmin="yes" else enable_libmapiadmin="no" fi if test x"$enable_libmapiadmin" = x"yes"; then pkg_failed=no { $as_echo "$as_me:${as_lineno-$LINENO}: checking for SAMR" >&5 $as_echo_n "checking for SAMR... " >&6; } if test -n "$SAMR_CFLAGS"; then pkg_cv_SAMR_CFLAGS="$SAMR_CFLAGS" elif test -n "$PKG_CONFIG"; then if test -n "$PKG_CONFIG" && \ { { $as_echo "$as_me:${as_lineno-$LINENO}: \$PKG_CONFIG --exists --print-errors \"dcerpc_samr ndr_standard\""; } >&5 ($PKG_CONFIG --exists --print-errors "dcerpc_samr ndr_standard") 2>&5 ac_status=$? $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 test $ac_status = 0; }; then pkg_cv_SAMR_CFLAGS=`$PKG_CONFIG --cflags "dcerpc_samr ndr_standard" 2>/dev/null` test "x$?" != "x0" && pkg_failed=yes else pkg_failed=yes fi else pkg_failed=untried fi if test -n "$SAMR_LIBS"; then pkg_cv_SAMR_LIBS="$SAMR_LIBS" elif test -n "$PKG_CONFIG"; then if test -n "$PKG_CONFIG" && \ { { $as_echo "$as_me:${as_lineno-$LINENO}: \$PKG_CONFIG --exists --print-errors \"dcerpc_samr ndr_standard\""; } >&5 ($PKG_CONFIG --exists --print-errors "dcerpc_samr ndr_standard") 2>&5 ac_status=$? $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 test $ac_status = 0; }; then pkg_cv_SAMR_LIBS=`$PKG_CONFIG --libs "dcerpc_samr ndr_standard" 2>/dev/null` test "x$?" != "x0" && pkg_failed=yes else pkg_failed=yes fi else pkg_failed=untried fi if test $pkg_failed = yes; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } if $PKG_CONFIG --atleast-pkgconfig-version 0.20; then _pkg_short_errors_supported=yes else _pkg_short_errors_supported=no fi if test $_pkg_short_errors_supported = yes; then SAMR_PKG_ERRORS=`$PKG_CONFIG --short-errors --print-errors --cflags --libs "dcerpc_samr ndr_standard" 2>&1` else SAMR_PKG_ERRORS=`$PKG_CONFIG --print-errors --cflags --libs "dcerpc_samr ndr_standard" 2>&1` fi # Put the nasty error message in config.log where it belongs echo "$SAMR_PKG_ERRORS" >&5 as_fn_error $? "Package requirements (dcerpc_samr ndr_standard) were not met: $SAMR_PKG_ERRORS Consider adjusting the PKG_CONFIG_PATH environment variable if you installed software in a non-standard prefix. Alternatively, you may set the environment variables SAMR_CFLAGS and SAMR_LIBS to avoid the need to call pkg-config. See the pkg-config man page for more details." "$LINENO" 5 elif test $pkg_failed = untried; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 $as_echo "$as_me: error: in \`$ac_pwd':" >&2;} as_fn_error $? "The pkg-config script could not be found or is too old. Make sure it is in your PATH or set the PKG_CONFIG environment variable to the full path to pkg-config. Alternatively, you may set the environment variables SAMR_CFLAGS and SAMR_LIBS to avoid the need to call pkg-config. See the pkg-config man page for more details. To get pkg-config, see . See \`config.log' for more details" "$LINENO" 5; } else SAMR_CFLAGS=$pkg_cv_SAMR_CFLAGS SAMR_LIBS=$pkg_cv_SAMR_LIBS { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 $as_echo "yes" >&6; } fi libmapiadmin=1 if test "x${libmapiadmin}set" != "xset"; then case "LIBS" in LIBS) OC_LIBS="$OC_LIBS libmapiadmin" OC_LIBS_INSTALL="$OC_LIBS_INSTALL libmapiadmin-install" OC_LIBS_UNINSTALL="$OC_LIBS_UNINSTALL libmapiadmin-uninstall" OC_LIBS_INSTALLPC="$OC_LIBS_INSTALLPC libmapiadmin-installpc" OC_LIBS_INSTALLHEADER="$OC_LIBS_INSTALLHEADER libmapiadmin-installheader" OC_LIBS_INSTALLLIB="$OC_LIBS_INSTALLLIB libmapiadmin-installlib" ;; TOOLS) OC_LIBS="$OC_LIBS libmapiadmin" OC_LIBS_INSTALL="$OC_LIBS_INSTALL libmapiadmin-install" OC_LIBS_UNINSTALL="$OC_LIBS_UNINSTALL libmapiadmin-uninstall" ;; SERVER|MAPISTORE) OC_LIBS="$OC_LIBS libmapiadmin" OC_LIBS_CLEAN="$OC_LIBS_CLEAN libmapiadmin-clean" OC_LIBS_INSTALL="$OC_LIBS_INSTALL libmapiadmin-install" OC_LIBS_UNINSTALL="$OC_LIBS_UNINSTALL libmapiadmin-uninstall" ;; esac enable_libmapiadmin="yes" fi fi pkg_failed=no { $as_echo "$as_me:${as_lineno-$LINENO}: checking for ICAL" >&5 $as_echo_n "checking for ICAL... " >&6; } if test -n "$ICAL_CFLAGS"; then pkg_cv_ICAL_CFLAGS="$ICAL_CFLAGS" elif test -n "$PKG_CONFIG"; then if test -n "$PKG_CONFIG" && \ { { $as_echo "$as_me:${as_lineno-$LINENO}: \$PKG_CONFIG --exists --print-errors \"libical\""; } >&5 ($PKG_CONFIG --exists --print-errors "libical") 2>&5 ac_status=$? $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 test $ac_status = 0; }; then pkg_cv_ICAL_CFLAGS=`$PKG_CONFIG --cflags "libical" 2>/dev/null` test "x$?" != "x0" && pkg_failed=yes else pkg_failed=yes fi else pkg_failed=untried fi if test -n "$ICAL_LIBS"; then pkg_cv_ICAL_LIBS="$ICAL_LIBS" elif test -n "$PKG_CONFIG"; then if test -n "$PKG_CONFIG" && \ { { $as_echo "$as_me:${as_lineno-$LINENO}: \$PKG_CONFIG --exists --print-errors \"libical\""; } >&5 ($PKG_CONFIG --exists --print-errors "libical") 2>&5 ac_status=$? $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 test $ac_status = 0; }; then pkg_cv_ICAL_LIBS=`$PKG_CONFIG --libs "libical" 2>/dev/null` test "x$?" != "x0" && pkg_failed=yes else pkg_failed=yes fi else pkg_failed=untried fi if test $pkg_failed = yes; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } if $PKG_CONFIG --atleast-pkgconfig-version 0.20; then _pkg_short_errors_supported=yes else _pkg_short_errors_supported=no fi if test $_pkg_short_errors_supported = yes; then ICAL_PKG_ERRORS=`$PKG_CONFIG --short-errors --print-errors --cflags --libs "libical" 2>&1` else ICAL_PKG_ERRORS=`$PKG_CONFIG --print-errors --cflags --libs "libical" 2>&1` fi # Put the nasty error message in config.log where it belongs echo "$ICAL_PKG_ERRORS" >&5 have_libical="no" elif test $pkg_failed = untried; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } have_libical="no" else ICAL_CFLAGS=$pkg_cv_ICAL_CFLAGS ICAL_LIBS=$pkg_cv_ICAL_LIBS { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 $as_echo "yes" >&6; } have_libical="yes" fi pkg_failed=no { $as_echo "$as_me:${as_lineno-$LINENO}: checking for ICAL_0_46" >&5 $as_echo_n "checking for ICAL_0_46... " >&6; } if test -n "$ICAL_0_46_CFLAGS"; then pkg_cv_ICAL_0_46_CFLAGS="$ICAL_0_46_CFLAGS" elif test -n "$PKG_CONFIG"; then if test -n "$PKG_CONFIG" && \ { { $as_echo "$as_me:${as_lineno-$LINENO}: \$PKG_CONFIG --exists --print-errors \"libical >= 0.46\""; } >&5 ($PKG_CONFIG --exists --print-errors "libical >= 0.46") 2>&5 ac_status=$? $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 test $ac_status = 0; }; then pkg_cv_ICAL_0_46_CFLAGS=`$PKG_CONFIG --cflags "libical >= 0.46" 2>/dev/null` test "x$?" != "x0" && pkg_failed=yes else pkg_failed=yes fi else pkg_failed=untried fi if test -n "$ICAL_0_46_LIBS"; then pkg_cv_ICAL_0_46_LIBS="$ICAL_0_46_LIBS" elif test -n "$PKG_CONFIG"; then if test -n "$PKG_CONFIG" && \ { { $as_echo "$as_me:${as_lineno-$LINENO}: \$PKG_CONFIG --exists --print-errors \"libical >= 0.46\""; } >&5 ($PKG_CONFIG --exists --print-errors "libical >= 0.46") 2>&5 ac_status=$? $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 test $ac_status = 0; }; then pkg_cv_ICAL_0_46_LIBS=`$PKG_CONFIG --libs "libical >= 0.46" 2>/dev/null` test "x$?" != "x0" && pkg_failed=yes else pkg_failed=yes fi else pkg_failed=untried fi if test $pkg_failed = yes; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } if $PKG_CONFIG --atleast-pkgconfig-version 0.20; then _pkg_short_errors_supported=yes else _pkg_short_errors_supported=no fi if test $_pkg_short_errors_supported = yes; then ICAL_0_46_PKG_ERRORS=`$PKG_CONFIG --short-errors --print-errors --cflags --libs "libical >= 0.46" 2>&1` else ICAL_0_46_PKG_ERRORS=`$PKG_CONFIG --print-errors --cflags --libs "libical >= 0.46" 2>&1` fi # Put the nasty error message in config.log where it belongs echo "$ICAL_0_46_PKG_ERRORS" >&5 have_libical_0_46="0" elif test $pkg_failed = untried; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } have_libical_0_46="0" else ICAL_0_46_CFLAGS=$pkg_cv_ICAL_0_46_CFLAGS ICAL_0_46_LIBS=$pkg_cv_ICAL_0_46_LIBS { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 $as_echo "yes" >&6; } have_libical_0_46="1" fi { $as_echo "$as_me:${as_lineno-$LINENO}: checking for poptFreeContext in -lpopt" >&5 $as_echo_n "checking for poptFreeContext in -lpopt... " >&6; } if ${ac_cv_lib_popt_poptFreeContext+:} false; then : $as_echo_n "(cached) " >&6 else ac_check_lib_save_LIBS=$LIBS LIBS="-lpopt $LIBS" cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ /* Override any GCC internal prototype to avoid an error. Use char because int might match the return type of a GCC builtin and then its argument prototype would still apply. */ #ifdef __cplusplus extern "C" #endif char poptFreeContext (); int main () { return poptFreeContext (); ; return 0; } _ACEOF if ac_fn_c_try_link "$LINENO"; then : ac_cv_lib_popt_poptFreeContext=yes else ac_cv_lib_popt_poptFreeContext=no fi rm -f core conftest.err conftest.$ac_objext \ conftest$ac_exeext conftest.$ac_ext LIBS=$ac_check_lib_save_LIBS fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_popt_poptFreeContext" >&5 $as_echo "$ac_cv_lib_popt_poptFreeContext" >&6; } if test "x$ac_cv_lib_popt_poptFreeContext" = xyes; then : $as_echo "#define HAVE_LIBPOPT 1" >>confdefs.h enable_libpopt="yes" else { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: libpopt is missing - can't build openchange tools" >&5 $as_echo "$as_me: WARNING: libpopt is missing - can't build openchange tools" >&2;} enable_libpopt="no" fi if test x"$enable_libpopt" = x"yes"; then if test x"$enable_libmapiadmin" = x"yes"; then openchangepfadmin=1 mapitest=1 fi if test x"$enable_libocpf" = x"yes"; then openchangeclient=1 fi if test x"$have_libical" = x"yes"; then exchange2ical=1 fi MAPISTORE_TEST=mapistore_test mapiprofile=1 openchangemapidump=1 schemaIDGUID=1 check_fasttransfer=1 test_asyncnotif=1 fi if test "x${openchangeclient}set" != "xset"; then case "TOOLS" in LIBS) OC_TOOLS="$OC_TOOLS openchangeclient" OC_TOOLS_INSTALL="$OC_TOOLS_INSTALL openchangeclient-install" OC_TOOLS_UNINSTALL="$OC_TOOLS_UNINSTALL openchangeclient-uninstall" OC_TOOLS_INSTALLPC="$OC_TOOLS_INSTALLPC openchangeclient-installpc" OC_TOOLS_INSTALLHEADER="$OC_TOOLS_INSTALLHEADER openchangeclient-installheader" OC_TOOLS_INSTALLLIB="$OC_TOOLS_INSTALLLIB openchangeclient-installlib" ;; TOOLS) OC_TOOLS="$OC_TOOLS openchangeclient" OC_TOOLS_INSTALL="$OC_TOOLS_INSTALL openchangeclient-install" OC_TOOLS_UNINSTALL="$OC_TOOLS_UNINSTALL openchangeclient-uninstall" ;; SERVER|MAPISTORE) OC_TOOLS="$OC_TOOLS openchangeclient" OC_TOOLS_CLEAN="$OC_TOOLS_CLEAN openchangeclient-clean" OC_TOOLS_INSTALL="$OC_TOOLS_INSTALL openchangeclient-install" OC_TOOLS_UNINSTALL="$OC_TOOLS_UNINSTALL openchangeclient-uninstall" ;; esac enable_openchangeclient="yes" fi #OC_RULE_ADD(mapistore_fsocpf, MAPISTORE) if test "x${exchange2ical}set" != "xset"; then case "TOOLS" in LIBS) OC_TOOLS="$OC_TOOLS exchange2ical" OC_TOOLS_INSTALL="$OC_TOOLS_INSTALL exchange2ical-install" OC_TOOLS_UNINSTALL="$OC_TOOLS_UNINSTALL exchange2ical-uninstall" OC_TOOLS_INSTALLPC="$OC_TOOLS_INSTALLPC exchange2ical-installpc" OC_TOOLS_INSTALLHEADER="$OC_TOOLS_INSTALLHEADER exchange2ical-installheader" OC_TOOLS_INSTALLLIB="$OC_TOOLS_INSTALLLIB exchange2ical-installlib" ;; TOOLS) OC_TOOLS="$OC_TOOLS exchange2ical" OC_TOOLS_INSTALL="$OC_TOOLS_INSTALL exchange2ical-install" OC_TOOLS_UNINSTALL="$OC_TOOLS_UNINSTALL exchange2ical-uninstall" ;; SERVER|MAPISTORE) OC_TOOLS="$OC_TOOLS exchange2ical" OC_TOOLS_CLEAN="$OC_TOOLS_CLEAN exchange2ical-clean" OC_TOOLS_INSTALL="$OC_TOOLS_INSTALL exchange2ical-install" OC_TOOLS_UNINSTALL="$OC_TOOLS_UNINSTALL exchange2ical-uninstall" ;; esac enable_exchange2ical="yes" fi if test "x${openchangepfadmin}set" != "xset"; then case "TOOLS" in LIBS) OC_TOOLS="$OC_TOOLS openchangepfadmin" OC_TOOLS_INSTALL="$OC_TOOLS_INSTALL openchangepfadmin-install" OC_TOOLS_UNINSTALL="$OC_TOOLS_UNINSTALL openchangepfadmin-uninstall" OC_TOOLS_INSTALLPC="$OC_TOOLS_INSTALLPC openchangepfadmin-installpc" OC_TOOLS_INSTALLHEADER="$OC_TOOLS_INSTALLHEADER openchangepfadmin-installheader" OC_TOOLS_INSTALLLIB="$OC_TOOLS_INSTALLLIB openchangepfadmin-installlib" ;; TOOLS) OC_TOOLS="$OC_TOOLS openchangepfadmin" OC_TOOLS_INSTALL="$OC_TOOLS_INSTALL openchangepfadmin-install" OC_TOOLS_UNINSTALL="$OC_TOOLS_UNINSTALL openchangepfadmin-uninstall" ;; SERVER|MAPISTORE) OC_TOOLS="$OC_TOOLS openchangepfadmin" OC_TOOLS_CLEAN="$OC_TOOLS_CLEAN openchangepfadmin-clean" OC_TOOLS_INSTALL="$OC_TOOLS_INSTALL openchangepfadmin-install" OC_TOOLS_UNINSTALL="$OC_TOOLS_UNINSTALL openchangepfadmin-uninstall" ;; esac enable_openchangepfadmin="yes" fi if test "x${mapitest}set" != "xset"; then case "TOOLS" in LIBS) OC_TOOLS="$OC_TOOLS mapitest" OC_TOOLS_INSTALL="$OC_TOOLS_INSTALL mapitest-install" OC_TOOLS_UNINSTALL="$OC_TOOLS_UNINSTALL mapitest-uninstall" OC_TOOLS_INSTALLPC="$OC_TOOLS_INSTALLPC mapitest-installpc" OC_TOOLS_INSTALLHEADER="$OC_TOOLS_INSTALLHEADER mapitest-installheader" OC_TOOLS_INSTALLLIB="$OC_TOOLS_INSTALLLIB mapitest-installlib" ;; TOOLS) OC_TOOLS="$OC_TOOLS mapitest" OC_TOOLS_INSTALL="$OC_TOOLS_INSTALL mapitest-install" OC_TOOLS_UNINSTALL="$OC_TOOLS_UNINSTALL mapitest-uninstall" ;; SERVER|MAPISTORE) OC_TOOLS="$OC_TOOLS mapitest" OC_TOOLS_CLEAN="$OC_TOOLS_CLEAN mapitest-clean" OC_TOOLS_INSTALL="$OC_TOOLS_INSTALL mapitest-install" OC_TOOLS_UNINSTALL="$OC_TOOLS_UNINSTALL mapitest-uninstall" ;; esac enable_mapitest="yes" fi if test "x${mapiprofile}set" != "xset"; then case "TOOLS" in LIBS) OC_TOOLS="$OC_TOOLS mapiprofile" OC_TOOLS_INSTALL="$OC_TOOLS_INSTALL mapiprofile-install" OC_TOOLS_UNINSTALL="$OC_TOOLS_UNINSTALL mapiprofile-uninstall" OC_TOOLS_INSTALLPC="$OC_TOOLS_INSTALLPC mapiprofile-installpc" OC_TOOLS_INSTALLHEADER="$OC_TOOLS_INSTALLHEADER mapiprofile-installheader" OC_TOOLS_INSTALLLIB="$OC_TOOLS_INSTALLLIB mapiprofile-installlib" ;; TOOLS) OC_TOOLS="$OC_TOOLS mapiprofile" OC_TOOLS_INSTALL="$OC_TOOLS_INSTALL mapiprofile-install" OC_TOOLS_UNINSTALL="$OC_TOOLS_UNINSTALL mapiprofile-uninstall" ;; SERVER|MAPISTORE) OC_TOOLS="$OC_TOOLS mapiprofile" OC_TOOLS_CLEAN="$OC_TOOLS_CLEAN mapiprofile-clean" OC_TOOLS_INSTALL="$OC_TOOLS_INSTALL mapiprofile-install" OC_TOOLS_UNINSTALL="$OC_TOOLS_UNINSTALL mapiprofile-uninstall" ;; esac enable_mapiprofile="yes" fi if test "x${openchangemapidump}set" != "xset"; then case "TOOLS" in LIBS) OC_TOOLS="$OC_TOOLS openchangemapidump" OC_TOOLS_INSTALL="$OC_TOOLS_INSTALL openchangemapidump-install" OC_TOOLS_UNINSTALL="$OC_TOOLS_UNINSTALL openchangemapidump-uninstall" OC_TOOLS_INSTALLPC="$OC_TOOLS_INSTALLPC openchangemapidump-installpc" OC_TOOLS_INSTALLHEADER="$OC_TOOLS_INSTALLHEADER openchangemapidump-installheader" OC_TOOLS_INSTALLLIB="$OC_TOOLS_INSTALLLIB openchangemapidump-installlib" ;; TOOLS) OC_TOOLS="$OC_TOOLS openchangemapidump" OC_TOOLS_INSTALL="$OC_TOOLS_INSTALL openchangemapidump-install" OC_TOOLS_UNINSTALL="$OC_TOOLS_UNINSTALL openchangemapidump-uninstall" ;; SERVER|MAPISTORE) OC_TOOLS="$OC_TOOLS openchangemapidump" OC_TOOLS_CLEAN="$OC_TOOLS_CLEAN openchangemapidump-clean" OC_TOOLS_INSTALL="$OC_TOOLS_INSTALL openchangemapidump-install" OC_TOOLS_UNINSTALL="$OC_TOOLS_UNINSTALL openchangemapidump-uninstall" ;; esac enable_openchangemapidump="yes" fi if test "x${schemaIDGUID}set" != "xset"; then case "TOOLS" in LIBS) OC_TOOLS="$OC_TOOLS schemaIDGUID" OC_TOOLS_INSTALL="$OC_TOOLS_INSTALL schemaIDGUID-install" OC_TOOLS_UNINSTALL="$OC_TOOLS_UNINSTALL schemaIDGUID-uninstall" OC_TOOLS_INSTALLPC="$OC_TOOLS_INSTALLPC schemaIDGUID-installpc" OC_TOOLS_INSTALLHEADER="$OC_TOOLS_INSTALLHEADER schemaIDGUID-installheader" OC_TOOLS_INSTALLLIB="$OC_TOOLS_INSTALLLIB schemaIDGUID-installlib" ;; TOOLS) OC_TOOLS="$OC_TOOLS schemaIDGUID" OC_TOOLS_INSTALL="$OC_TOOLS_INSTALL schemaIDGUID-install" OC_TOOLS_UNINSTALL="$OC_TOOLS_UNINSTALL schemaIDGUID-uninstall" ;; SERVER|MAPISTORE) OC_TOOLS="$OC_TOOLS schemaIDGUID" OC_TOOLS_CLEAN="$OC_TOOLS_CLEAN schemaIDGUID-clean" OC_TOOLS_INSTALL="$OC_TOOLS_INSTALL schemaIDGUID-install" OC_TOOLS_UNINSTALL="$OC_TOOLS_UNINSTALL schemaIDGUID-uninstall" ;; esac enable_schemaIDGUID="yes" fi if test "x${check_fasttransfer}set" != "xset"; then case "TOOLS" in LIBS) OC_TOOLS="$OC_TOOLS check_fasttransfer" OC_TOOLS_INSTALL="$OC_TOOLS_INSTALL check_fasttransfer-install" OC_TOOLS_UNINSTALL="$OC_TOOLS_UNINSTALL check_fasttransfer-uninstall" OC_TOOLS_INSTALLPC="$OC_TOOLS_INSTALLPC check_fasttransfer-installpc" OC_TOOLS_INSTALLHEADER="$OC_TOOLS_INSTALLHEADER check_fasttransfer-installheader" OC_TOOLS_INSTALLLIB="$OC_TOOLS_INSTALLLIB check_fasttransfer-installlib" ;; TOOLS) OC_TOOLS="$OC_TOOLS check_fasttransfer" OC_TOOLS_INSTALL="$OC_TOOLS_INSTALL check_fasttransfer-install" OC_TOOLS_UNINSTALL="$OC_TOOLS_UNINSTALL check_fasttransfer-uninstall" ;; SERVER|MAPISTORE) OC_TOOLS="$OC_TOOLS check_fasttransfer" OC_TOOLS_CLEAN="$OC_TOOLS_CLEAN check_fasttransfer-clean" OC_TOOLS_INSTALL="$OC_TOOLS_INSTALL check_fasttransfer-install" OC_TOOLS_UNINSTALL="$OC_TOOLS_UNINSTALL check_fasttransfer-uninstall" ;; esac enable_check_fasttransfer="yes" fi if test "x${test_asyncnotif}set" != "xset"; then case "TOOLS" in LIBS) OC_TOOLS="$OC_TOOLS test_asyncnotif" OC_TOOLS_INSTALL="$OC_TOOLS_INSTALL test_asyncnotif-install" OC_TOOLS_UNINSTALL="$OC_TOOLS_UNINSTALL test_asyncnotif-uninstall" OC_TOOLS_INSTALLPC="$OC_TOOLS_INSTALLPC test_asyncnotif-installpc" OC_TOOLS_INSTALLHEADER="$OC_TOOLS_INSTALLHEADER test_asyncnotif-installheader" OC_TOOLS_INSTALLLIB="$OC_TOOLS_INSTALLLIB test_asyncnotif-installlib" ;; TOOLS) OC_TOOLS="$OC_TOOLS test_asyncnotif" OC_TOOLS_INSTALL="$OC_TOOLS_INSTALL test_asyncnotif-install" OC_TOOLS_UNINSTALL="$OC_TOOLS_UNINSTALL test_asyncnotif-uninstall" ;; SERVER|MAPISTORE) OC_TOOLS="$OC_TOOLS test_asyncnotif" OC_TOOLS_CLEAN="$OC_TOOLS_CLEAN test_asyncnotif-clean" OC_TOOLS_INSTALL="$OC_TOOLS_INSTALL test_asyncnotif-install" OC_TOOLS_UNINSTALL="$OC_TOOLS_UNINSTALL test_asyncnotif-uninstall" ;; esac enable_test_asyncnotif="yes" fi { $as_echo "$as_me:${as_lineno-$LINENO}: checking for magic_open in -lmagic" >&5 $as_echo_n "checking for magic_open in -lmagic... " >&6; } if ${ac_cv_lib_magic_magic_open+:} false; then : $as_echo_n "(cached) " >&6 else ac_check_lib_save_LIBS=$LIBS LIBS="-lmagic $LIBS" cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ /* Override any GCC internal prototype to avoid an error. Use char because int might match the return type of a GCC builtin and then its argument prototype would still apply. */ #ifdef __cplusplus extern "C" #endif char magic_open (); int main () { return magic_open (); ; return 0; } _ACEOF if ac_fn_c_try_link "$LINENO"; then : ac_cv_lib_magic_magic_open=yes else ac_cv_lib_magic_magic_open=no fi rm -f core conftest.err conftest.$ac_objext \ conftest$ac_exeext conftest.$ac_ext LIBS=$ac_check_lib_save_LIBS fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_magic_magic_open" >&5 $as_echo "$ac_cv_lib_magic_magic_open" >&6; } if test "x$ac_cv_lib_magic_magic_open" = xyes; then : $as_echo "#define HAVE_LIBMAGIC 1" >>confdefs.h MAGIC_LIBS="-lmagic -lz" enable_libmagic="yes" else { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: libmagic is missing - can't build exchange2mbox" >&5 $as_echo "$as_me: WARNING: libmagic is missing - can't build exchange2mbox" >&2;} enable_libmagic="no" fi if test x"$enable_libmagic" = x"yes"; then { $as_echo "$as_me:${as_lineno-$LINENO}: checking for gzopen in -lz" >&5 $as_echo_n "checking for gzopen in -lz... " >&6; } if ${ac_cv_lib_z_gzopen+:} false; then : $as_echo_n "(cached) " >&6 else ac_check_lib_save_LIBS=$LIBS LIBS="-lz $LIBS" cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ /* Override any GCC internal prototype to avoid an error. Use char because int might match the return type of a GCC builtin and then its argument prototype would still apply. */ #ifdef __cplusplus extern "C" #endif char gzopen (); int main () { return gzopen (); ; return 0; } _ACEOF if ac_fn_c_try_link "$LINENO"; then : ac_cv_lib_z_gzopen=yes else ac_cv_lib_z_gzopen=no fi rm -f core conftest.err conftest.$ac_objext \ conftest$ac_exeext conftest.$ac_ext LIBS=$ac_check_lib_save_LIBS fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_z_gzopen" >&5 $as_echo "$ac_cv_lib_z_gzopen" >&6; } if test "x$ac_cv_lib_z_gzopen" = xyes; then : cat >>confdefs.h <<_ACEOF #define HAVE_LIBZ 1 _ACEOF LIBS="-lz $LIBS" else as_fn_error 1 "Z library not found, please install zlib-devel." "$LINENO" 5 fi if test x"$enable_libpopt" = x"yes"; then exchange2mbox=1 fi fi if test "x${exchange2mbox}set" != "xset"; then case "TOOLS" in LIBS) OC_TOOLS="$OC_TOOLS exchange2mbox" OC_TOOLS_INSTALL="$OC_TOOLS_INSTALL exchange2mbox-install" OC_TOOLS_UNINSTALL="$OC_TOOLS_UNINSTALL exchange2mbox-uninstall" OC_TOOLS_INSTALLPC="$OC_TOOLS_INSTALLPC exchange2mbox-installpc" OC_TOOLS_INSTALLHEADER="$OC_TOOLS_INSTALLHEADER exchange2mbox-installheader" OC_TOOLS_INSTALLLIB="$OC_TOOLS_INSTALLLIB exchange2mbox-installlib" ;; TOOLS) OC_TOOLS="$OC_TOOLS exchange2mbox" OC_TOOLS_INSTALL="$OC_TOOLS_INSTALL exchange2mbox-install" OC_TOOLS_UNINSTALL="$OC_TOOLS_UNINSTALL exchange2mbox-uninstall" ;; SERVER|MAPISTORE) OC_TOOLS="$OC_TOOLS exchange2mbox" OC_TOOLS_CLEAN="$OC_TOOLS_CLEAN exchange2mbox-clean" OC_TOOLS_INSTALL="$OC_TOOLS_INSTALL exchange2mbox-install" OC_TOOLS_UNINSTALL="$OC_TOOLS_UNINSTALL exchange2mbox-uninstall" ;; esac enable_exchange2mbox="yes" fi { $as_echo "$as_me:${as_lineno-$LINENO}: checking for mq_open in -lrt" >&5 $as_echo_n "checking for mq_open in -lrt... " >&6; } if ${ac_cv_lib_rt_mq_open+:} false; then : $as_echo_n "(cached) " >&6 else ac_check_lib_save_LIBS=$LIBS LIBS="-lrt $LIBS" cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ /* Override any GCC internal prototype to avoid an error. Use char because int might match the return type of a GCC builtin and then its argument prototype would still apply. */ #ifdef __cplusplus extern "C" #endif char mq_open (); int main () { return mq_open (); ; return 0; } _ACEOF if ac_fn_c_try_link "$LINENO"; then : ac_cv_lib_rt_mq_open=yes else ac_cv_lib_rt_mq_open=no fi rm -f core conftest.err conftest.$ac_objext \ conftest$ac_exeext conftest.$ac_ext LIBS=$ac_check_lib_save_LIBS fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_rt_mq_open" >&5 $as_echo "$ac_cv_lib_rt_mq_open" >&6; } if test "x$ac_cv_lib_rt_mq_open" = xyes; then : RT_LIBS="-lrt" else for ac_func in mq_open do : ac_fn_c_check_func "$LINENO" "mq_open" "ac_cv_func_mq_open" if test "x$ac_cv_func_mq_open" = xyes; then : cat >>confdefs.h <<_ACEOF #define HAVE_MQ_OPEN 1 _ACEOF RT_LIBS="" else as_fn_error $? "unable to find mq_open" "$LINENO" 5 fi done fi OC_MAPISTORE= OC_MAPISTORE_CLEAN= OC_MAPISTORE_INSTALL= OC_MAPISTORE_UNINSTALL= if test x$PYTHON != x; then if test "x$SAMBASERVER_LIBS" != x ; then mapiproxy=1 fi fi if test "x${mapiproxy}set" != "xset"; then case "SERVER" in LIBS) OC_SERVER="$OC_SERVER mapiproxy" OC_SERVER_INSTALL="$OC_SERVER_INSTALL mapiproxy-install" OC_SERVER_UNINSTALL="$OC_SERVER_UNINSTALL mapiproxy-uninstall" OC_SERVER_INSTALLPC="$OC_SERVER_INSTALLPC mapiproxy-installpc" OC_SERVER_INSTALLHEADER="$OC_SERVER_INSTALLHEADER mapiproxy-installheader" OC_SERVER_INSTALLLIB="$OC_SERVER_INSTALLLIB mapiproxy-installlib" ;; TOOLS) OC_SERVER="$OC_SERVER mapiproxy" OC_SERVER_INSTALL="$OC_SERVER_INSTALL mapiproxy-install" OC_SERVER_UNINSTALL="$OC_SERVER_UNINSTALL mapiproxy-uninstall" ;; SERVER|MAPISTORE) OC_SERVER="$OC_SERVER mapiproxy" OC_SERVER_CLEAN="$OC_SERVER_CLEAN mapiproxy-clean" OC_SERVER_INSTALL="$OC_SERVER_INSTALL mapiproxy-install" OC_SERVER_UNINSTALL="$OC_SERVER_UNINSTALL mapiproxy-uninstall" ;; esac enable_mapiproxy="yes" fi # Check whether --with-modulesdir was given. if test "${with_modulesdir+set}" = set; then : withval=$with_modulesdir; modulesdir="$withval"; else modulesdir="\${prefix}/modules"; fi # Check whether --enable-pymapi was given. if test "${enable_pymapi+set}" = set; then : enableval=$enable_pymapi; enable_pymapi="$enableval" else enable_pymapi=no fi PYCDIR=`$PYTHON -c "import distutils.sysconfig; print distutils.sysconfig.get_python_lib(1, prefix='\\$(prefix)')"` PYMAPIALL="$PYMAPIALL pyopenchange" PYMAPIINSTALL="$PYMAPIALLINSTALL pyopenchange-install" PYMAPIUNINSTALL="$PYMAPIUNINSTALL pyopenchange-uninstall" # Extract the first word of "doxygen", so it can be a program name with args. set dummy doxygen; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } if ${ac_cv_path_DOXYGEN+:} false; then : $as_echo_n "(cached) " >&6 else case $DOXYGEN in [\\/]* | ?:[\\/]*) ac_cv_path_DOXYGEN="$DOXYGEN" # Let the user override the test with a path. ;; *) as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then ac_cv_path_DOXYGEN="$as_dir/$ac_word$ac_exec_ext" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS ;; esac fi DOXYGEN=$ac_cv_path_DOXYGEN if test -n "$DOXYGEN"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: $DOXYGEN" >&5 $as_echo "$DOXYGEN" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi if test x"$DOXYGEN" = x""; then { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: doxygen" >&5 $as_echo "$as_me: WARNING: doxygen" >&2;} enable_doxygen="no" else enable_doxygen="yes" fi pkg_failed=no { $as_echo "$as_me:${as_lineno-$LINENO}: checking for SUBUNIT" >&5 $as_echo_n "checking for SUBUNIT... " >&6; } if test -n "$SUBUNIT_CFLAGS"; then pkg_cv_SUBUNIT_CFLAGS="$SUBUNIT_CFLAGS" elif test -n "$PKG_CONFIG"; then if test -n "$PKG_CONFIG" && \ { { $as_echo "$as_me:${as_lineno-$LINENO}: \$PKG_CONFIG --exists --print-errors \"libsubunit\""; } >&5 ($PKG_CONFIG --exists --print-errors "libsubunit") 2>&5 ac_status=$? $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 test $ac_status = 0; }; then pkg_cv_SUBUNIT_CFLAGS=`$PKG_CONFIG --cflags "libsubunit" 2>/dev/null` test "x$?" != "x0" && pkg_failed=yes else pkg_failed=yes fi else pkg_failed=untried fi if test -n "$SUBUNIT_LIBS"; then pkg_cv_SUBUNIT_LIBS="$SUBUNIT_LIBS" elif test -n "$PKG_CONFIG"; then if test -n "$PKG_CONFIG" && \ { { $as_echo "$as_me:${as_lineno-$LINENO}: \$PKG_CONFIG --exists --print-errors \"libsubunit\""; } >&5 ($PKG_CONFIG --exists --print-errors "libsubunit") 2>&5 ac_status=$? $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 test $ac_status = 0; }; then pkg_cv_SUBUNIT_LIBS=`$PKG_CONFIG --libs "libsubunit" 2>/dev/null` test "x$?" != "x0" && pkg_failed=yes else pkg_failed=yes fi else pkg_failed=untried fi if test $pkg_failed = yes; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } if $PKG_CONFIG --atleast-pkgconfig-version 0.20; then _pkg_short_errors_supported=yes else _pkg_short_errors_supported=no fi if test $_pkg_short_errors_supported = yes; then SUBUNIT_PKG_ERRORS=`$PKG_CONFIG --short-errors --print-errors --cflags --libs "libsubunit" 2>&1` else SUBUNIT_PKG_ERRORS=`$PKG_CONFIG --print-errors --cflags --libs "libsubunit" 2>&1` fi # Put the nasty error message in config.log where it belongs echo "$SUBUNIT_PKG_ERRORS" >&5 found_subunit=no elif test $pkg_failed = untried; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } found_subunit=no else SUBUNIT_CFLAGS=$pkg_cv_SUBUNIT_CFLAGS SUBUNIT_LIBS=$pkg_cv_SUBUNIT_LIBS { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 $as_echo "yes" >&6; } found_subunit=yes fi if test x"$found_subunit" = x"yes"; then $as_echo "#define HAVE_SUBUNIT 1" >>confdefs.h have_subunit="yes" else have_subunit="no" fi # Check whether --enable-openchange-qt4 was given. if test "${enable_openchange_qt4+set}" = set; then : enableval=$enable_openchange_qt4; enable_openchange_qt4=$enableval else enable_openchange_qt4="no" fi if test x$enable_openchange_qt4 = xyes; then pkg_failed=no { $as_echo "$as_me:${as_lineno-$LINENO}: checking for Qt4" >&5 $as_echo_n "checking for Qt4... " >&6; } if test -n "$Qt4_CFLAGS"; then pkg_cv_Qt4_CFLAGS="$Qt4_CFLAGS" elif test -n "$PKG_CONFIG"; then if test -n "$PKG_CONFIG" && \ { { $as_echo "$as_me:${as_lineno-$LINENO}: \$PKG_CONFIG --exists --print-errors \"QtCore >= 4.3.0 QtGui >= 4.3.0\""; } >&5 ($PKG_CONFIG --exists --print-errors "QtCore >= 4.3.0 QtGui >= 4.3.0") 2>&5 ac_status=$? $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 test $ac_status = 0; }; then pkg_cv_Qt4_CFLAGS=`$PKG_CONFIG --cflags "QtCore >= 4.3.0 QtGui >= 4.3.0" 2>/dev/null` test "x$?" != "x0" && pkg_failed=yes else pkg_failed=yes fi else pkg_failed=untried fi if test -n "$Qt4_LIBS"; then pkg_cv_Qt4_LIBS="$Qt4_LIBS" elif test -n "$PKG_CONFIG"; then if test -n "$PKG_CONFIG" && \ { { $as_echo "$as_me:${as_lineno-$LINENO}: \$PKG_CONFIG --exists --print-errors \"QtCore >= 4.3.0 QtGui >= 4.3.0\""; } >&5 ($PKG_CONFIG --exists --print-errors "QtCore >= 4.3.0 QtGui >= 4.3.0") 2>&5 ac_status=$? $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 test $ac_status = 0; }; then pkg_cv_Qt4_LIBS=`$PKG_CONFIG --libs "QtCore >= 4.3.0 QtGui >= 4.3.0" 2>/dev/null` test "x$?" != "x0" && pkg_failed=yes else pkg_failed=yes fi else pkg_failed=untried fi if test $pkg_failed = yes; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } if $PKG_CONFIG --atleast-pkgconfig-version 0.20; then _pkg_short_errors_supported=yes else _pkg_short_errors_supported=no fi if test $_pkg_short_errors_supported = yes; then Qt4_PKG_ERRORS=`$PKG_CONFIG --short-errors --print-errors --cflags --libs "QtCore >= 4.3.0 QtGui >= 4.3.0" 2>&1` else Qt4_PKG_ERRORS=`$PKG_CONFIG --print-errors --cflags --libs "QtCore >= 4.3.0 QtGui >= 4.3.0" 2>&1` fi # Put the nasty error message in config.log where it belongs echo "$Qt4_PKG_ERRORS" >&5 as_fn_error $? "Package requirements (QtCore >= 4.3.0 QtGui >= 4.3.0) were not met: $Qt4_PKG_ERRORS Consider adjusting the PKG_CONFIG_PATH environment variable if you installed software in a non-standard prefix. Alternatively, you may set the environment variables Qt4_CFLAGS and Qt4_LIBS to avoid the need to call pkg-config. See the pkg-config man page for more details." "$LINENO" 5 elif test $pkg_failed = untried; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 $as_echo "$as_me: error: in \`$ac_pwd':" >&2;} as_fn_error $? "The pkg-config script could not be found or is too old. Make sure it is in your PATH or set the PKG_CONFIG environment variable to the full path to pkg-config. Alternatively, you may set the environment variables Qt4_CFLAGS and Qt4_LIBS to avoid the need to call pkg-config. See the pkg-config man page for more details. To get pkg-config, see . See \`config.log' for more details" "$LINENO" 5; } else Qt4_CFLAGS=$pkg_cv_Qt4_CFLAGS Qt4_LIBS=$pkg_cv_Qt4_LIBS { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 $as_echo "yes" >&6; } fi MOC=`$PKG_CONFIG --variable=moc_location QtCore` elif test x$enable_openchange_qt4 = xtry; then pkg_failed=no { $as_echo "$as_me:${as_lineno-$LINENO}: checking for Qt4" >&5 $as_echo_n "checking for Qt4... " >&6; } if test -n "$Qt4_CFLAGS"; then pkg_cv_Qt4_CFLAGS="$Qt4_CFLAGS" elif test -n "$PKG_CONFIG"; then if test -n "$PKG_CONFIG" && \ { { $as_echo "$as_me:${as_lineno-$LINENO}: \$PKG_CONFIG --exists --print-errors \"QtCore >= 4.3.0 QtGui >= 4.3.0\""; } >&5 ($PKG_CONFIG --exists --print-errors "QtCore >= 4.3.0 QtGui >= 4.3.0") 2>&5 ac_status=$? $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 test $ac_status = 0; }; then pkg_cv_Qt4_CFLAGS=`$PKG_CONFIG --cflags "QtCore >= 4.3.0 QtGui >= 4.3.0" 2>/dev/null` test "x$?" != "x0" && pkg_failed=yes else pkg_failed=yes fi else pkg_failed=untried fi if test -n "$Qt4_LIBS"; then pkg_cv_Qt4_LIBS="$Qt4_LIBS" elif test -n "$PKG_CONFIG"; then if test -n "$PKG_CONFIG" && \ { { $as_echo "$as_me:${as_lineno-$LINENO}: \$PKG_CONFIG --exists --print-errors \"QtCore >= 4.3.0 QtGui >= 4.3.0\""; } >&5 ($PKG_CONFIG --exists --print-errors "QtCore >= 4.3.0 QtGui >= 4.3.0") 2>&5 ac_status=$? $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 test $ac_status = 0; }; then pkg_cv_Qt4_LIBS=`$PKG_CONFIG --libs "QtCore >= 4.3.0 QtGui >= 4.3.0" 2>/dev/null` test "x$?" != "x0" && pkg_failed=yes else pkg_failed=yes fi else pkg_failed=untried fi if test $pkg_failed = yes; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } if $PKG_CONFIG --atleast-pkgconfig-version 0.20; then _pkg_short_errors_supported=yes else _pkg_short_errors_supported=no fi if test $_pkg_short_errors_supported = yes; then Qt4_PKG_ERRORS=`$PKG_CONFIG --short-errors --print-errors --cflags --libs "QtCore >= 4.3.0 QtGui >= 4.3.0" 2>&1` else Qt4_PKG_ERRORS=`$PKG_CONFIG --print-errors --cflags --libs "QtCore >= 4.3.0 QtGui >= 4.3.0" 2>&1` fi # Put the nasty error message in config.log where it belongs echo "$Qt4_PKG_ERRORS" >&5 enable_openchange_qt4="no" elif test $pkg_failed = untried; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } enable_openchange_qt4="no" else Qt4_CFLAGS=$pkg_cv_Qt4_CFLAGS Qt4_LIBS=$pkg_cv_Qt4_LIBS { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 $as_echo "yes" >&6; } enable_openchange_qt4="yes" MOC=`$PKG_CONFIG --variable=moc_location QtCore` fi fi if test "x$enable_openchange_qt4" = "xyes"; then OPENCHANGE_QT4="openchange_qt4" fi ac_config_files="$ac_config_files config.mk libmapi.pc libmapiadmin.pc libocpf.pc mapiproxy/libmapiproxy.pc mapiproxy/libmapiserver.pc mapiproxy/libmapistore.pc libmapi++.pc Doxyfile libmapi++/Doxyfile libocpf/Doxyfile libmapiadmin/Doxyfile libmapi/Doxyfile mapiproxy/Doxyfile utils/mapitest/Doxyfile mapiproxy/libmapistore/Doxyfile" cat >confcache <<\_ACEOF # This file is a shell script that caches the results of configure # tests run on this system so they can be shared between configure # scripts and configure runs, see configure's option --config-cache. # It is not useful on other systems. If it contains results you don't # want to keep, you may remove or edit it. # # config.status only pays attention to the cache file if you give it # the --recheck option to rerun configure. # # `ac_cv_env_foo' variables (set or unset) will be overridden when # loading this file, other *unset* `ac_cv_foo' will be assigned the # following values. _ACEOF # The following way of writing the cache mishandles newlines in values, # but we know of no workaround that is simple, portable, and efficient. # So, we kill variables containing newlines. # Ultrix sh set writes to stderr and can't be redirected directly, # and sets the high bit in the cache file unless we assign to the vars. ( for ac_var in `(set) 2>&1 | sed -n 's/^\([a-zA-Z_][a-zA-Z0-9_]*\)=.*/\1/p'`; do eval ac_val=\$$ac_var case $ac_val in #( *${as_nl}*) case $ac_var in #( *_cv_*) { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: cache variable $ac_var contains a newline" >&5 $as_echo "$as_me: WARNING: cache variable $ac_var contains a newline" >&2;} ;; esac case $ac_var in #( _ | IFS | as_nl) ;; #( BASH_ARGV | BASH_SOURCE) eval $ac_var= ;; #( *) { eval $ac_var=; unset $ac_var;} ;; esac ;; esac done (set) 2>&1 | case $as_nl`(ac_space=' '; set) 2>&1` in #( *${as_nl}ac_space=\ *) # `set' does not quote correctly, so add quotes: double-quote # substitution turns \\\\ into \\, and sed turns \\ into \. sed -n \ "s/'/'\\\\''/g; s/^\\([_$as_cr_alnum]*_cv_[_$as_cr_alnum]*\\)=\\(.*\\)/\\1='\\2'/p" ;; #( *) # `set' quotes correctly as required by POSIX, so do not add quotes. sed -n "/^[_$as_cr_alnum]*_cv_[_$as_cr_alnum]*=/p" ;; esac | sort ) | sed ' /^ac_cv_env_/b end t clear :clear s/^\([^=]*\)=\(.*[{}].*\)$/test "${\1+set}" = set || &/ t end s/^\([^=]*\)=\(.*\)$/\1=${\1=\2}/ :end' >>confcache if diff "$cache_file" confcache >/dev/null 2>&1; then :; else if test -w "$cache_file"; then if test "x$cache_file" != "x/dev/null"; then { $as_echo "$as_me:${as_lineno-$LINENO}: updating cache $cache_file" >&5 $as_echo "$as_me: updating cache $cache_file" >&6;} if test ! -f "$cache_file" || test -h "$cache_file"; then cat confcache >"$cache_file" else case $cache_file in #( */* | ?:*) mv -f confcache "$cache_file"$$ && mv -f "$cache_file"$$ "$cache_file" ;; #( *) mv -f confcache "$cache_file" ;; esac fi fi else { $as_echo "$as_me:${as_lineno-$LINENO}: not updating unwritable cache $cache_file" >&5 $as_echo "$as_me: not updating unwritable cache $cache_file" >&6;} fi fi rm -f confcache test "x$prefix" = xNONE && prefix=$ac_default_prefix # Let make expand exec_prefix. test "x$exec_prefix" = xNONE && exec_prefix='${prefix}' DEFS=-DHAVE_CONFIG_H ac_libobjs= ac_ltlibobjs= U= for ac_i in : $LIBOBJS; do test "x$ac_i" = x: && continue # 1. Remove the extension, and $U if already installed. ac_script='s/\$U\././;s/\.o$//;s/\.obj$//' ac_i=`$as_echo "$ac_i" | sed "$ac_script"` # 2. Prepend LIBOBJDIR. When used with automake>=1.10 LIBOBJDIR # will be set to the directory where LIBOBJS objects are built. as_fn_append ac_libobjs " \${LIBOBJDIR}$ac_i\$U.$ac_objext" as_fn_append ac_ltlibobjs " \${LIBOBJDIR}$ac_i"'$U.lo' done LIBOBJS=$ac_libobjs LTLIBOBJS=$ac_ltlibobjs if test -n "$EXEEXT"; then am__EXEEXT_TRUE= am__EXEEXT_FALSE='#' else am__EXEEXT_TRUE='#' am__EXEEXT_FALSE= fi if test -z "${AMDEP_TRUE}" && test -z "${AMDEP_FALSE}"; then as_fn_error $? "conditional \"AMDEP\" was never defined. Usually this means the macro was only invoked conditionally." "$LINENO" 5 fi if test -z "${am__fastdepCC_TRUE}" && test -z "${am__fastdepCC_FALSE}"; then as_fn_error $? "conditional \"am__fastdepCC\" was never defined. Usually this means the macro was only invoked conditionally." "$LINENO" 5 fi if test -z "${am__fastdepCC_TRUE}" && test -z "${am__fastdepCC_FALSE}"; then as_fn_error $? "conditional \"am__fastdepCC\" was never defined. Usually this means the macro was only invoked conditionally." "$LINENO" 5 fi if test -z "${am__fastdepCXX_TRUE}" && test -z "${am__fastdepCXX_FALSE}"; then as_fn_error $? "conditional \"am__fastdepCXX\" was never defined. Usually this means the macro was only invoked conditionally." "$LINENO" 5 fi if test -z "${am__fastdepCXX_TRUE}" && test -z "${am__fastdepCXX_FALSE}"; then as_fn_error $? "conditional \"am__fastdepCXX\" was never defined. Usually this means the macro was only invoked conditionally." "$LINENO" 5 fi : "${CONFIG_STATUS=./config.status}" ac_write_fail=0 ac_clean_files_save=$ac_clean_files ac_clean_files="$ac_clean_files $CONFIG_STATUS" { $as_echo "$as_me:${as_lineno-$LINENO}: creating $CONFIG_STATUS" >&5 $as_echo "$as_me: creating $CONFIG_STATUS" >&6;} as_write_fail=0 cat >$CONFIG_STATUS <<_ASEOF || as_write_fail=1 #! $SHELL # Generated by $as_me. # Run this file to recreate the current configuration. # Compiler output produced by configure, useful for debugging # configure, is in config.log if it exists. debug=false ac_cs_recheck=false ac_cs_silent=false SHELL=\${CONFIG_SHELL-$SHELL} export SHELL _ASEOF cat >>$CONFIG_STATUS <<\_ASEOF || as_write_fail=1 ## -------------------- ## ## M4sh Initialization. ## ## -------------------- ## # Be more Bourne compatible DUALCASE=1; export DUALCASE # for MKS sh if test -n "${ZSH_VERSION+set}" && (emulate sh) >/dev/null 2>&1; then : emulate sh NULLCMD=: # Pre-4.2 versions of Zsh do word splitting on ${1+"$@"}, which # is contrary to our usage. Disable this feature. alias -g '${1+"$@"}'='"$@"' setopt NO_GLOB_SUBST else case `(set -o) 2>/dev/null` in #( *posix*) : set -o posix ;; #( *) : ;; esac fi as_nl=' ' export as_nl # Printing a long string crashes Solaris 7 /usr/bin/printf. as_echo='\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\' as_echo=$as_echo$as_echo$as_echo$as_echo$as_echo as_echo=$as_echo$as_echo$as_echo$as_echo$as_echo$as_echo # Prefer a ksh shell builtin over an external printf program on Solaris, # but without wasting forks for bash or zsh. if test -z "$BASH_VERSION$ZSH_VERSION" \ && (test "X`print -r -- $as_echo`" = "X$as_echo") 2>/dev/null; then as_echo='print -r --' as_echo_n='print -rn --' elif (test "X`printf %s $as_echo`" = "X$as_echo") 2>/dev/null; then as_echo='printf %s\n' as_echo_n='printf %s' else if test "X`(/usr/ucb/echo -n -n $as_echo) 2>/dev/null`" = "X-n $as_echo"; then as_echo_body='eval /usr/ucb/echo -n "$1$as_nl"' as_echo_n='/usr/ucb/echo -n' else as_echo_body='eval expr "X$1" : "X\\(.*\\)"' as_echo_n_body='eval arg=$1; case $arg in #( *"$as_nl"*) expr "X$arg" : "X\\(.*\\)$as_nl"; arg=`expr "X$arg" : ".*$as_nl\\(.*\\)"`;; esac; expr "X$arg" : "X\\(.*\\)" | tr -d "$as_nl" ' export as_echo_n_body as_echo_n='sh -c $as_echo_n_body as_echo' fi export as_echo_body as_echo='sh -c $as_echo_body as_echo' fi # The user is always right. if test "${PATH_SEPARATOR+set}" != set; then PATH_SEPARATOR=: (PATH='/bin;/bin'; FPATH=$PATH; sh -c :) >/dev/null 2>&1 && { (PATH='/bin:/bin'; FPATH=$PATH; sh -c :) >/dev/null 2>&1 || PATH_SEPARATOR=';' } fi # IFS # We need space, tab and new line, in precisely that order. Quoting is # there to prevent editors from complaining about space-tab. # (If _AS_PATH_WALK were called with IFS unset, it would disable word # splitting by setting IFS to empty value.) IFS=" "" $as_nl" # Find who we are. Look in the path if we contain no directory separator. as_myself= case $0 in #(( *[\\/]* ) as_myself=$0 ;; *) as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. test -r "$as_dir/$0" && as_myself=$as_dir/$0 && break done IFS=$as_save_IFS ;; esac # We did not find ourselves, most probably we were run as `sh COMMAND' # in which case we are not to be found in the path. if test "x$as_myself" = x; then as_myself=$0 fi if test ! -f "$as_myself"; then $as_echo "$as_myself: error: cannot find myself; rerun with an absolute file name" >&2 exit 1 fi # Unset variables that we do not need and which cause bugs (e.g. in # pre-3.0 UWIN ksh). But do not cause bugs in bash 2.01; the "|| exit 1" # suppresses any "Segmentation fault" message there. '((' could # trigger a bug in pdksh 5.2.14. for as_var in BASH_ENV ENV MAIL MAILPATH do eval test x\${$as_var+set} = xset \ && ( (unset $as_var) || exit 1) >/dev/null 2>&1 && unset $as_var || : done PS1='$ ' PS2='> ' PS4='+ ' # NLS nuisances. LC_ALL=C export LC_ALL LANGUAGE=C export LANGUAGE # CDPATH. (unset CDPATH) >/dev/null 2>&1 && unset CDPATH # as_fn_error STATUS ERROR [LINENO LOG_FD] # ---------------------------------------- # Output "`basename $0`: error: ERROR" to stderr. If LINENO and LOG_FD are # provided, also output the error to LOG_FD, referencing LINENO. Then exit the # script with STATUS, using 1 if that was 0. as_fn_error () { as_status=$1; test $as_status -eq 0 && as_status=1 if test "$4"; then as_lineno=${as_lineno-"$3"} as_lineno_stack=as_lineno_stack=$as_lineno_stack $as_echo "$as_me:${as_lineno-$LINENO}: error: $2" >&$4 fi $as_echo "$as_me: error: $2" >&2 as_fn_exit $as_status } # as_fn_error # as_fn_set_status STATUS # ----------------------- # Set $? to STATUS, without forking. as_fn_set_status () { return $1 } # as_fn_set_status # as_fn_exit STATUS # ----------------- # Exit the shell with STATUS, even in a "trap 0" or "set -e" context. as_fn_exit () { set +e as_fn_set_status $1 exit $1 } # as_fn_exit # as_fn_unset VAR # --------------- # Portably unset VAR. as_fn_unset () { { eval $1=; unset $1;} } as_unset=as_fn_unset # as_fn_append VAR VALUE # ---------------------- # Append the text in VALUE to the end of the definition contained in VAR. Take # advantage of any shell optimizations that allow amortized linear growth over # repeated appends, instead of the typical quadratic growth present in naive # implementations. if (eval "as_var=1; as_var+=2; test x\$as_var = x12") 2>/dev/null; then : eval 'as_fn_append () { eval $1+=\$2 }' else as_fn_append () { eval $1=\$$1\$2 } fi # as_fn_append # as_fn_arith ARG... # ------------------ # Perform arithmetic evaluation on the ARGs, and store the result in the # global $as_val. Take advantage of shells that can avoid forks. The arguments # must be portable across $(()) and expr. if (eval "test \$(( 1 + 1 )) = 2") 2>/dev/null; then : eval 'as_fn_arith () { as_val=$(( $* )) }' else as_fn_arith () { as_val=`expr "$@" || test $? -eq 1` } fi # as_fn_arith if expr a : '\(a\)' >/dev/null 2>&1 && test "X`expr 00001 : '.*\(...\)'`" = X001; then as_expr=expr else as_expr=false fi if (basename -- /) >/dev/null 2>&1 && test "X`basename -- / 2>&1`" = "X/"; then as_basename=basename else as_basename=false fi if (as_dir=`dirname -- /` && test "X$as_dir" = X/) >/dev/null 2>&1; then as_dirname=dirname else as_dirname=false fi as_me=`$as_basename -- "$0" || $as_expr X/"$0" : '.*/\([^/][^/]*\)/*$' \| \ X"$0" : 'X\(//\)$' \| \ X"$0" : 'X\(/\)' \| . 2>/dev/null || $as_echo X/"$0" | sed '/^.*\/\([^/][^/]*\)\/*$/{ s//\1/ q } /^X\/\(\/\/\)$/{ s//\1/ q } /^X\/\(\/\).*/{ s//\1/ q } s/.*/./; q'` # Avoid depending upon Character Ranges. as_cr_letters='abcdefghijklmnopqrstuvwxyz' as_cr_LETTERS='ABCDEFGHIJKLMNOPQRSTUVWXYZ' as_cr_Letters=$as_cr_letters$as_cr_LETTERS as_cr_digits='0123456789' as_cr_alnum=$as_cr_Letters$as_cr_digits ECHO_C= ECHO_N= ECHO_T= case `echo -n x` in #((((( -n*) case `echo 'xy\c'` in *c*) ECHO_T=' ';; # ECHO_T is single tab character. xy) ECHO_C='\c';; *) echo `echo ksh88 bug on AIX 6.1` > /dev/null ECHO_T=' ';; esac;; *) ECHO_N='-n';; esac rm -f conf$$ conf$$.exe conf$$.file if test -d conf$$.dir; then rm -f conf$$.dir/conf$$.file else rm -f conf$$.dir mkdir conf$$.dir 2>/dev/null fi if (echo >conf$$.file) 2>/dev/null; then if ln -s conf$$.file conf$$ 2>/dev/null; then as_ln_s='ln -s' # ... but there are two gotchas: # 1) On MSYS, both `ln -s file dir' and `ln file dir' fail. # 2) DJGPP < 2.04 has no symlinks; `ln -s' creates a wrapper executable. # In both cases, we have to default to `cp -pR'. ln -s conf$$.file conf$$.dir 2>/dev/null && test ! -f conf$$.exe || as_ln_s='cp -pR' elif ln conf$$.file conf$$ 2>/dev/null; then as_ln_s=ln else as_ln_s='cp -pR' fi else as_ln_s='cp -pR' fi rm -f conf$$ conf$$.exe conf$$.dir/conf$$.file conf$$.file rmdir conf$$.dir 2>/dev/null # as_fn_mkdir_p # ------------- # Create "$as_dir" as a directory, including parents if necessary. as_fn_mkdir_p () { case $as_dir in #( -*) as_dir=./$as_dir;; esac test -d "$as_dir" || eval $as_mkdir_p || { as_dirs= while :; do case $as_dir in #( *\'*) as_qdir=`$as_echo "$as_dir" | sed "s/'/'\\\\\\\\''/g"`;; #'( *) as_qdir=$as_dir;; esac as_dirs="'$as_qdir' $as_dirs" as_dir=`$as_dirname -- "$as_dir" || $as_expr X"$as_dir" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \ X"$as_dir" : 'X\(//\)[^/]' \| \ X"$as_dir" : 'X\(//\)$' \| \ X"$as_dir" : 'X\(/\)' \| . 2>/dev/null || $as_echo X"$as_dir" | sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ s//\1/ q } /^X\(\/\/\)[^/].*/{ s//\1/ q } /^X\(\/\/\)$/{ s//\1/ q } /^X\(\/\).*/{ s//\1/ q } s/.*/./; q'` test -d "$as_dir" && break done test -z "$as_dirs" || eval "mkdir $as_dirs" } || test -d "$as_dir" || as_fn_error $? "cannot create directory $as_dir" } # as_fn_mkdir_p if mkdir -p . 2>/dev/null; then as_mkdir_p='mkdir -p "$as_dir"' else test -d ./-p && rmdir ./-p as_mkdir_p=false fi # as_fn_executable_p FILE # ----------------------- # Test if FILE is an executable regular file. as_fn_executable_p () { test -f "$1" && test -x "$1" } # as_fn_executable_p as_test_x='test -x' as_executable_p=as_fn_executable_p # Sed expression to map a string onto a valid CPP name. as_tr_cpp="eval sed 'y%*$as_cr_letters%P$as_cr_LETTERS%;s%[^_$as_cr_alnum]%_%g'" # Sed expression to map a string onto a valid variable name. as_tr_sh="eval sed 'y%*+%pp%;s%[^_$as_cr_alnum]%_%g'" exec 6>&1 ## ----------------------------------- ## ## Main body of $CONFIG_STATUS script. ## ## ----------------------------------- ## _ASEOF test $as_write_fail = 0 && chmod +x $CONFIG_STATUS || ac_write_fail=1 cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 # Save the log message, to keep $0 and so on meaningful, and to # report actual input values of CONFIG_FILES etc. instead of their # values after options handling. ac_log=" This file was extended by openchange $as_me 2.0, which was generated by GNU Autoconf 2.69. Invocation command line was CONFIG_FILES = $CONFIG_FILES CONFIG_HEADERS = $CONFIG_HEADERS CONFIG_LINKS = $CONFIG_LINKS CONFIG_COMMANDS = $CONFIG_COMMANDS $ $0 $@ on `(hostname || uname -n) 2>/dev/null | sed 1q` " _ACEOF case $ac_config_files in *" "*) set x $ac_config_files; shift; ac_config_files=$*;; esac case $ac_config_headers in *" "*) set x $ac_config_headers; shift; ac_config_headers=$*;; esac cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 # Files that config.status was made for. config_files="$ac_config_files" config_headers="$ac_config_headers" config_commands="$ac_config_commands" _ACEOF cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 ac_cs_usage="\ \`$as_me' instantiates files and other configuration actions from templates according to the current configuration. Unless the files and actions are specified as TAGs, all are instantiated by default. Usage: $0 [OPTION]... [TAG]... -h, --help print this help, then exit -V, --version print version number and configuration settings, then exit --config print configuration, then exit -q, --quiet, --silent do not print progress messages -d, --debug don't remove temporary files --recheck update $as_me by reconfiguring in the same conditions --file=FILE[:TEMPLATE] instantiate the configuration file FILE --header=FILE[:TEMPLATE] instantiate the configuration header FILE Configuration files: $config_files Configuration headers: $config_headers Configuration commands: $config_commands Report bugs to ." _ACEOF cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 ac_cs_config="`$as_echo "$ac_configure_args" | sed 's/^ //; s/[\\""\`\$]/\\\\&/g'`" ac_cs_version="\\ openchange config.status 2.0 configured by $0, generated by GNU Autoconf 2.69, with options \\"\$ac_cs_config\\" Copyright (C) 2012 Free Software Foundation, Inc. This config.status script is free software; the Free Software Foundation gives unlimited permission to copy, distribute and modify it." ac_pwd='$ac_pwd' srcdir='$srcdir' INSTALL='$INSTALL' MKDIR_P='$MKDIR_P' AWK='$AWK' test -n "\$AWK" || AWK=awk _ACEOF cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 # The default lists apply if the user does not specify any file. ac_need_defaults=: while test $# != 0 do case $1 in --*=?*) ac_option=`expr "X$1" : 'X\([^=]*\)='` ac_optarg=`expr "X$1" : 'X[^=]*=\(.*\)'` ac_shift=: ;; --*=) ac_option=`expr "X$1" : 'X\([^=]*\)='` ac_optarg= ac_shift=: ;; *) ac_option=$1 ac_optarg=$2 ac_shift=shift ;; esac case $ac_option in # Handling of the options. -recheck | --recheck | --rechec | --reche | --rech | --rec | --re | --r) ac_cs_recheck=: ;; --version | --versio | --versi | --vers | --ver | --ve | --v | -V ) $as_echo "$ac_cs_version"; exit ;; --config | --confi | --conf | --con | --co | --c ) $as_echo "$ac_cs_config"; exit ;; --debug | --debu | --deb | --de | --d | -d ) debug=: ;; --file | --fil | --fi | --f ) $ac_shift case $ac_optarg in *\'*) ac_optarg=`$as_echo "$ac_optarg" | sed "s/'/'\\\\\\\\''/g"` ;; '') as_fn_error $? "missing file argument" ;; esac as_fn_append CONFIG_FILES " '$ac_optarg'" ac_need_defaults=false;; --header | --heade | --head | --hea ) $ac_shift case $ac_optarg in *\'*) ac_optarg=`$as_echo "$ac_optarg" | sed "s/'/'\\\\\\\\''/g"` ;; esac as_fn_append CONFIG_HEADERS " '$ac_optarg'" ac_need_defaults=false;; --he | --h) # Conflict between --help and --header as_fn_error $? "ambiguous option: \`$1' Try \`$0 --help' for more information.";; --help | --hel | -h ) $as_echo "$ac_cs_usage"; exit ;; -q | -quiet | --quiet | --quie | --qui | --qu | --q \ | -silent | --silent | --silen | --sile | --sil | --si | --s) ac_cs_silent=: ;; # This is an error. -*) as_fn_error $? "unrecognized option: \`$1' Try \`$0 --help' for more information." ;; *) as_fn_append ac_config_targets " $1" ac_need_defaults=false ;; esac shift done ac_configure_extra_args= if $ac_cs_silent; then exec 6>/dev/null ac_configure_extra_args="$ac_configure_extra_args --silent" fi _ACEOF cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 if \$ac_cs_recheck; then set X $SHELL '$0' $ac_configure_args \$ac_configure_extra_args --no-create --no-recursion shift \$as_echo "running CONFIG_SHELL=$SHELL \$*" >&6 CONFIG_SHELL='$SHELL' export CONFIG_SHELL exec "\$@" fi _ACEOF cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 exec 5>>config.log { echo sed 'h;s/./-/g;s/^.../## /;s/...$/ ##/;p;x;p;x' <<_ASBOX ## Running $as_me. ## _ASBOX $as_echo "$ac_log" } >&5 _ACEOF cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 # # INIT-COMMANDS # AMDEP_TRUE="$AMDEP_TRUE" ac_aux_dir="$ac_aux_dir" _ACEOF cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 # Handling of arguments. for ac_config_target in $ac_config_targets do case $ac_config_target in "config.h") CONFIG_HEADERS="$CONFIG_HEADERS config.h" ;; "depfiles") CONFIG_COMMANDS="$CONFIG_COMMANDS depfiles" ;; "config.mk") CONFIG_FILES="$CONFIG_FILES config.mk" ;; "libmapi.pc") CONFIG_FILES="$CONFIG_FILES libmapi.pc" ;; "libmapiadmin.pc") CONFIG_FILES="$CONFIG_FILES libmapiadmin.pc" ;; "libocpf.pc") CONFIG_FILES="$CONFIG_FILES libocpf.pc" ;; "mapiproxy/libmapiproxy.pc") CONFIG_FILES="$CONFIG_FILES mapiproxy/libmapiproxy.pc" ;; "mapiproxy/libmapiserver.pc") CONFIG_FILES="$CONFIG_FILES mapiproxy/libmapiserver.pc" ;; "mapiproxy/libmapistore.pc") CONFIG_FILES="$CONFIG_FILES mapiproxy/libmapistore.pc" ;; "libmapi++.pc") CONFIG_FILES="$CONFIG_FILES libmapi++.pc" ;; "Doxyfile") CONFIG_FILES="$CONFIG_FILES Doxyfile" ;; "libmapi++/Doxyfile") CONFIG_FILES="$CONFIG_FILES libmapi++/Doxyfile" ;; "libocpf/Doxyfile") CONFIG_FILES="$CONFIG_FILES libocpf/Doxyfile" ;; "libmapiadmin/Doxyfile") CONFIG_FILES="$CONFIG_FILES libmapiadmin/Doxyfile" ;; "libmapi/Doxyfile") CONFIG_FILES="$CONFIG_FILES libmapi/Doxyfile" ;; "mapiproxy/Doxyfile") CONFIG_FILES="$CONFIG_FILES mapiproxy/Doxyfile" ;; "utils/mapitest/Doxyfile") CONFIG_FILES="$CONFIG_FILES utils/mapitest/Doxyfile" ;; "mapiproxy/libmapistore/Doxyfile") CONFIG_FILES="$CONFIG_FILES mapiproxy/libmapistore/Doxyfile" ;; *) as_fn_error $? "invalid argument: \`$ac_config_target'" "$LINENO" 5;; esac done # If the user did not use the arguments to specify the items to instantiate, # then the envvar interface is used. Set only those that are not. # We use the long form for the default assignment because of an extremely # bizarre bug on SunOS 4.1.3. if $ac_need_defaults; then test "${CONFIG_FILES+set}" = set || CONFIG_FILES=$config_files test "${CONFIG_HEADERS+set}" = set || CONFIG_HEADERS=$config_headers test "${CONFIG_COMMANDS+set}" = set || CONFIG_COMMANDS=$config_commands fi # Have a temporary directory for convenience. Make it in the build tree # simply because there is no reason against having it here, and in addition, # creating and moving files from /tmp can sometimes cause problems. # Hook for its removal unless debugging. # Note that there is a small window in which the directory will not be cleaned: # after its creation but before its name has been assigned to `$tmp'. $debug || { tmp= ac_tmp= trap 'exit_status=$? : "${ac_tmp:=$tmp}" { test ! -d "$ac_tmp" || rm -fr "$ac_tmp"; } && exit $exit_status ' 0 trap 'as_fn_exit 1' 1 2 13 15 } # Create a (secure) tmp directory for tmp files. { tmp=`(umask 077 && mktemp -d "./confXXXXXX") 2>/dev/null` && test -d "$tmp" } || { tmp=./conf$$-$RANDOM (umask 077 && mkdir "$tmp") } || as_fn_error $? "cannot create a temporary directory in ." "$LINENO" 5 ac_tmp=$tmp # Set up the scripts for CONFIG_FILES section. # No need to generate them if there are no CONFIG_FILES. # This happens for instance with `./config.status config.h'. if test -n "$CONFIG_FILES"; then ac_cr=`echo X | tr X '\015'` # On cygwin, bash can eat \r inside `` if the user requested igncr. # But we know of no other shell where ac_cr would be empty at this # point, so we can use a bashism as a fallback. if test "x$ac_cr" = x; then eval ac_cr=\$\'\\r\' fi ac_cs_awk_cr=`$AWK 'BEGIN { print "a\rb" }' /dev/null` if test "$ac_cs_awk_cr" = "a${ac_cr}b"; then ac_cs_awk_cr='\\r' else ac_cs_awk_cr=$ac_cr fi echo 'BEGIN {' >"$ac_tmp/subs1.awk" && _ACEOF { echo "cat >conf$$subs.awk <<_ACEOF" && echo "$ac_subst_vars" | sed 's/.*/&!$&$ac_delim/' && echo "_ACEOF" } >conf$$subs.sh || as_fn_error $? "could not make $CONFIG_STATUS" "$LINENO" 5 ac_delim_num=`echo "$ac_subst_vars" | grep -c '^'` ac_delim='%!_!# ' for ac_last_try in false false false false false :; do . ./conf$$subs.sh || as_fn_error $? "could not make $CONFIG_STATUS" "$LINENO" 5 ac_delim_n=`sed -n "s/.*$ac_delim\$/X/p" conf$$subs.awk | grep -c X` if test $ac_delim_n = $ac_delim_num; then break elif $ac_last_try; then as_fn_error $? "could not make $CONFIG_STATUS" "$LINENO" 5 else ac_delim="$ac_delim!$ac_delim _$ac_delim!! " fi done rm -f conf$$subs.sh cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 cat >>"\$ac_tmp/subs1.awk" <<\\_ACAWK && _ACEOF sed -n ' h s/^/S["/; s/!.*/"]=/ p g s/^[^!]*!// :repl t repl s/'"$ac_delim"'$// t delim :nl h s/\(.\{148\}\)..*/\1/ t more1 s/["\\]/\\&/g; s/^/"/; s/$/\\n"\\/ p n b repl :more1 s/["\\]/\\&/g; s/^/"/; s/$/"\\/ p g s/.\{148\}// t nl :delim h s/\(.\{148\}\)..*/\1/ t more2 s/["\\]/\\&/g; s/^/"/; s/$/"/ p b :more2 s/["\\]/\\&/g; s/^/"/; s/$/"\\/ p g s/.\{148\}// t delim ' >$CONFIG_STATUS || ac_write_fail=1 rm -f conf$$subs.awk cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 _ACAWK cat >>"\$ac_tmp/subs1.awk" <<_ACAWK && for (key in S) S_is_set[key] = 1 FS = "" } { line = $ 0 nfields = split(line, field, "@") substed = 0 len = length(field[1]) for (i = 2; i < nfields; i++) { key = field[i] keylen = length(key) if (S_is_set[key]) { value = S[key] line = substr(line, 1, len) "" value "" substr(line, len + keylen + 3) len += length(value) + length(field[++i]) substed = 1 } else len += 1 + keylen } print line } _ACAWK _ACEOF cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 if sed "s/$ac_cr//" < /dev/null > /dev/null 2>&1; then sed "s/$ac_cr\$//; s/$ac_cr/$ac_cs_awk_cr/g" else cat fi < "$ac_tmp/subs1.awk" > "$ac_tmp/subs.awk" \ || as_fn_error $? "could not setup config files machinery" "$LINENO" 5 _ACEOF # VPATH may cause trouble with some makes, so we remove sole $(srcdir), # ${srcdir} and @srcdir@ entries from VPATH if srcdir is ".", strip leading and # trailing colons and then remove the whole line if VPATH becomes empty # (actually we leave an empty line to preserve line numbers). if test "x$srcdir" = x.; then ac_vpsub='/^[ ]*VPATH[ ]*=[ ]*/{ h s/// s/^/:/ s/[ ]*$/:/ s/:\$(srcdir):/:/g s/:\${srcdir}:/:/g s/:@srcdir@:/:/g s/^:*// s/:*$// x s/\(=[ ]*\).*/\1/ G s/\n// s/^[^=]*=[ ]*$// }' fi cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 fi # test -n "$CONFIG_FILES" # Set up the scripts for CONFIG_HEADERS section. # No need to generate them if there are no CONFIG_HEADERS. # This happens for instance with `./config.status Makefile'. if test -n "$CONFIG_HEADERS"; then cat >"$ac_tmp/defines.awk" <<\_ACAWK || BEGIN { _ACEOF # Transform confdefs.h into an awk script `defines.awk', embedded as # here-document in config.status, that substitutes the proper values into # config.h.in to produce config.h. # Create a delimiter string that does not exist in confdefs.h, to ease # handling of long lines. ac_delim='%!_!# ' for ac_last_try in false false :; do ac_tt=`sed -n "/$ac_delim/p" confdefs.h` if test -z "$ac_tt"; then break elif $ac_last_try; then as_fn_error $? "could not make $CONFIG_HEADERS" "$LINENO" 5 else ac_delim="$ac_delim!$ac_delim _$ac_delim!! " fi done # For the awk script, D is an array of macro values keyed by name, # likewise P contains macro parameters if any. Preserve backslash # newline sequences. ac_word_re=[_$as_cr_Letters][_$as_cr_alnum]* sed -n ' s/.\{148\}/&'"$ac_delim"'/g t rset :rset s/^[ ]*#[ ]*define[ ][ ]*/ / t def d :def s/\\$// t bsnl s/["\\]/\\&/g s/^ \('"$ac_word_re"'\)\(([^()]*)\)[ ]*\(.*\)/P["\1"]="\2"\ D["\1"]=" \3"/p s/^ \('"$ac_word_re"'\)[ ]*\(.*\)/D["\1"]=" \2"/p d :bsnl s/["\\]/\\&/g s/^ \('"$ac_word_re"'\)\(([^()]*)\)[ ]*\(.*\)/P["\1"]="\2"\ D["\1"]=" \3\\\\\\n"\\/p t cont s/^ \('"$ac_word_re"'\)[ ]*\(.*\)/D["\1"]=" \2\\\\\\n"\\/p t cont d :cont n s/.\{148\}/&'"$ac_delim"'/g t clear :clear s/\\$// t bsnlc s/["\\]/\\&/g; s/^/"/; s/$/"/p d :bsnlc s/["\\]/\\&/g; s/^/"/; s/$/\\\\\\n"\\/p b cont ' >$CONFIG_STATUS || ac_write_fail=1 cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 for (key in D) D_is_set[key] = 1 FS = "" } /^[\t ]*#[\t ]*(define|undef)[\t ]+$ac_word_re([\t (]|\$)/ { line = \$ 0 split(line, arg, " ") if (arg[1] == "#") { defundef = arg[2] mac1 = arg[3] } else { defundef = substr(arg[1], 2) mac1 = arg[2] } split(mac1, mac2, "(") #) macro = mac2[1] prefix = substr(line, 1, index(line, defundef) - 1) if (D_is_set[macro]) { # Preserve the white space surrounding the "#". print prefix "define", macro P[macro] D[macro] next } else { # Replace #undef with comments. This is necessary, for example, # in the case of _POSIX_SOURCE, which is predefined and required # on some systems where configure will not decide to define it. if (defundef == "undef") { print "/*", prefix defundef, macro, "*/" next } } } { print } _ACAWK _ACEOF cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 as_fn_error $? "could not setup config headers machinery" "$LINENO" 5 fi # test -n "$CONFIG_HEADERS" eval set X " :F $CONFIG_FILES :H $CONFIG_HEADERS :C $CONFIG_COMMANDS" shift for ac_tag do case $ac_tag in :[FHLC]) ac_mode=$ac_tag; continue;; esac case $ac_mode$ac_tag in :[FHL]*:*);; :L* | :C*:*) as_fn_error $? "invalid tag \`$ac_tag'" "$LINENO" 5;; :[FH]-) ac_tag=-:-;; :[FH]*) ac_tag=$ac_tag:$ac_tag.in;; esac ac_save_IFS=$IFS IFS=: set x $ac_tag IFS=$ac_save_IFS shift ac_file=$1 shift case $ac_mode in :L) ac_source=$1;; :[FH]) ac_file_inputs= for ac_f do case $ac_f in -) ac_f="$ac_tmp/stdin";; *) # Look for the file first in the build tree, then in the source tree # (if the path is not absolute). The absolute path cannot be DOS-style, # because $ac_f cannot contain `:'. test -f "$ac_f" || case $ac_f in [\\/$]*) false;; *) test -f "$srcdir/$ac_f" && ac_f="$srcdir/$ac_f";; esac || as_fn_error 1 "cannot find input file: \`$ac_f'" "$LINENO" 5;; esac case $ac_f in *\'*) ac_f=`$as_echo "$ac_f" | sed "s/'/'\\\\\\\\''/g"`;; esac as_fn_append ac_file_inputs " '$ac_f'" done # Let's still pretend it is `configure' which instantiates (i.e., don't # use $as_me), people would be surprised to read: # /* config.h. Generated by config.status. */ configure_input='Generated from '` $as_echo "$*" | sed 's|^[^:]*/||;s|:[^:]*/|, |g' `' by configure.' if test x"$ac_file" != x-; then configure_input="$ac_file. $configure_input" { $as_echo "$as_me:${as_lineno-$LINENO}: creating $ac_file" >&5 $as_echo "$as_me: creating $ac_file" >&6;} fi # Neutralize special characters interpreted by sed in replacement strings. case $configure_input in #( *\&* | *\|* | *\\* ) ac_sed_conf_input=`$as_echo "$configure_input" | sed 's/[\\\\&|]/\\\\&/g'`;; #( *) ac_sed_conf_input=$configure_input;; esac case $ac_tag in *:-:* | *:-) cat >"$ac_tmp/stdin" \ || as_fn_error $? "could not create $ac_file" "$LINENO" 5 ;; esac ;; esac ac_dir=`$as_dirname -- "$ac_file" || $as_expr X"$ac_file" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \ X"$ac_file" : 'X\(//\)[^/]' \| \ X"$ac_file" : 'X\(//\)$' \| \ X"$ac_file" : 'X\(/\)' \| . 2>/dev/null || $as_echo X"$ac_file" | sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ s//\1/ q } /^X\(\/\/\)[^/].*/{ s//\1/ q } /^X\(\/\/\)$/{ s//\1/ q } /^X\(\/\).*/{ s//\1/ q } s/.*/./; q'` as_dir="$ac_dir"; as_fn_mkdir_p ac_builddir=. case "$ac_dir" in .) ac_dir_suffix= ac_top_builddir_sub=. ac_top_build_prefix= ;; *) ac_dir_suffix=/`$as_echo "$ac_dir" | sed 's|^\.[\\/]||'` # A ".." for each directory in $ac_dir_suffix. ac_top_builddir_sub=`$as_echo "$ac_dir_suffix" | sed 's|/[^\\/]*|/..|g;s|/||'` case $ac_top_builddir_sub in "") ac_top_builddir_sub=. ac_top_build_prefix= ;; *) ac_top_build_prefix=$ac_top_builddir_sub/ ;; esac ;; esac ac_abs_top_builddir=$ac_pwd ac_abs_builddir=$ac_pwd$ac_dir_suffix # for backward compatibility: ac_top_builddir=$ac_top_build_prefix case $srcdir in .) # We are building in place. ac_srcdir=. ac_top_srcdir=$ac_top_builddir_sub ac_abs_top_srcdir=$ac_pwd ;; [\\/]* | ?:[\\/]* ) # Absolute name. ac_srcdir=$srcdir$ac_dir_suffix; ac_top_srcdir=$srcdir ac_abs_top_srcdir=$srcdir ;; *) # Relative name. ac_srcdir=$ac_top_build_prefix$srcdir$ac_dir_suffix ac_top_srcdir=$ac_top_build_prefix$srcdir ac_abs_top_srcdir=$ac_pwd/$srcdir ;; esac ac_abs_srcdir=$ac_abs_top_srcdir$ac_dir_suffix case $ac_mode in :F) # # CONFIG_FILE # case $INSTALL in [\\/$]* | ?:[\\/]* ) ac_INSTALL=$INSTALL ;; *) ac_INSTALL=$ac_top_build_prefix$INSTALL ;; esac ac_MKDIR_P=$MKDIR_P case $MKDIR_P in [\\/$]* | ?:[\\/]* ) ;; */*) ac_MKDIR_P=$ac_top_build_prefix$MKDIR_P ;; esac _ACEOF cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 # If the template does not know about datarootdir, expand it. # FIXME: This hack should be removed a few years after 2.60. ac_datarootdir_hack=; ac_datarootdir_seen= ac_sed_dataroot=' /datarootdir/ { p q } /@datadir@/p /@docdir@/p /@infodir@/p /@localedir@/p /@mandir@/p' case `eval "sed -n \"\$ac_sed_dataroot\" $ac_file_inputs"` in *datarootdir*) ac_datarootdir_seen=yes;; *@datadir@*|*@docdir@*|*@infodir@*|*@localedir@*|*@mandir@*) { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $ac_file_inputs seems to ignore the --datarootdir setting" >&5 $as_echo "$as_me: WARNING: $ac_file_inputs seems to ignore the --datarootdir setting" >&2;} _ACEOF cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 ac_datarootdir_hack=' s&@datadir@&$datadir&g s&@docdir@&$docdir&g s&@infodir@&$infodir&g s&@localedir@&$localedir&g s&@mandir@&$mandir&g s&\\\${datarootdir}&$datarootdir&g' ;; esac _ACEOF # Neutralize VPATH when `$srcdir' = `.'. # Shell code in configure.ac might set extrasub. # FIXME: do we really want to maintain this feature? cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 ac_sed_extra="$ac_vpsub $extrasub _ACEOF cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 :t /@[a-zA-Z_][a-zA-Z_0-9]*@/!b s|@configure_input@|$ac_sed_conf_input|;t t s&@top_builddir@&$ac_top_builddir_sub&;t t s&@top_build_prefix@&$ac_top_build_prefix&;t t s&@srcdir@&$ac_srcdir&;t t s&@abs_srcdir@&$ac_abs_srcdir&;t t s&@top_srcdir@&$ac_top_srcdir&;t t s&@abs_top_srcdir@&$ac_abs_top_srcdir&;t t s&@builddir@&$ac_builddir&;t t s&@abs_builddir@&$ac_abs_builddir&;t t s&@abs_top_builddir@&$ac_abs_top_builddir&;t t s&@INSTALL@&$ac_INSTALL&;t t s&@MKDIR_P@&$ac_MKDIR_P&;t t $ac_datarootdir_hack " eval sed \"\$ac_sed_extra\" "$ac_file_inputs" | $AWK -f "$ac_tmp/subs.awk" \ >$ac_tmp/out || as_fn_error $? "could not create $ac_file" "$LINENO" 5 test -z "$ac_datarootdir_hack$ac_datarootdir_seen" && { ac_out=`sed -n '/\${datarootdir}/p' "$ac_tmp/out"`; test -n "$ac_out"; } && { ac_out=`sed -n '/^[ ]*datarootdir[ ]*:*=/p' \ "$ac_tmp/out"`; test -z "$ac_out"; } && { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $ac_file contains a reference to the variable \`datarootdir' which seems to be undefined. Please make sure it is defined" >&5 $as_echo "$as_me: WARNING: $ac_file contains a reference to the variable \`datarootdir' which seems to be undefined. Please make sure it is defined" >&2;} rm -f "$ac_tmp/stdin" case $ac_file in -) cat "$ac_tmp/out" && rm -f "$ac_tmp/out";; *) rm -f "$ac_file" && mv "$ac_tmp/out" "$ac_file";; esac \ || as_fn_error $? "could not create $ac_file" "$LINENO" 5 ;; :H) # # CONFIG_HEADER # if test x"$ac_file" != x-; then { $as_echo "/* $configure_input */" \ && eval '$AWK -f "$ac_tmp/defines.awk"' "$ac_file_inputs" } >"$ac_tmp/config.h" \ || as_fn_error $? "could not create $ac_file" "$LINENO" 5 if diff "$ac_file" "$ac_tmp/config.h" >/dev/null 2>&1; then { $as_echo "$as_me:${as_lineno-$LINENO}: $ac_file is unchanged" >&5 $as_echo "$as_me: $ac_file is unchanged" >&6;} else rm -f "$ac_file" mv "$ac_tmp/config.h" "$ac_file" \ || as_fn_error $? "could not create $ac_file" "$LINENO" 5 fi else $as_echo "/* $configure_input */" \ && eval '$AWK -f "$ac_tmp/defines.awk"' "$ac_file_inputs" \ || as_fn_error $? "could not create -" "$LINENO" 5 fi # Compute "$ac_file"'s index in $config_headers. _am_arg="$ac_file" _am_stamp_count=1 for _am_header in $config_headers :; do case $_am_header in $_am_arg | $_am_arg:* ) break ;; * ) _am_stamp_count=`expr $_am_stamp_count + 1` ;; esac done echo "timestamp for $_am_arg" >`$as_dirname -- "$_am_arg" || $as_expr X"$_am_arg" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \ X"$_am_arg" : 'X\(//\)[^/]' \| \ X"$_am_arg" : 'X\(//\)$' \| \ X"$_am_arg" : 'X\(/\)' \| . 2>/dev/null || $as_echo X"$_am_arg" | sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ s//\1/ q } /^X\(\/\/\)[^/].*/{ s//\1/ q } /^X\(\/\/\)$/{ s//\1/ q } /^X\(\/\).*/{ s//\1/ q } s/.*/./; q'`/stamp-h$_am_stamp_count ;; :C) { $as_echo "$as_me:${as_lineno-$LINENO}: executing $ac_file commands" >&5 $as_echo "$as_me: executing $ac_file commands" >&6;} ;; esac case $ac_file$ac_mode in "depfiles":C) test x"$AMDEP_TRUE" != x"" || { # Autoconf 2.62 quotes --file arguments for eval, but not when files # are listed without --file. Let's play safe and only enable the eval # if we detect the quoting. case $CONFIG_FILES in *\'*) eval set x "$CONFIG_FILES" ;; *) set x $CONFIG_FILES ;; esac shift for mf do # Strip MF so we end up with the name of the file. mf=`echo "$mf" | sed -e 's/:.*$//'` # Check whether this is an Automake generated Makefile or not. # We used to match only the files named `Makefile.in', but # some people rename them; so instead we look at the file content. # Grep'ing the first line is not enough: some people post-process # each Makefile.in and add a new line on top of each file to say so. # Grep'ing the whole file is not good either: AIX grep has a line # limit of 2048, but all sed's we know have understand at least 4000. if sed -n 's,^#.*generated by automake.*,X,p' "$mf" | grep X >/dev/null 2>&1; then dirpart=`$as_dirname -- "$mf" || $as_expr X"$mf" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \ X"$mf" : 'X\(//\)[^/]' \| \ X"$mf" : 'X\(//\)$' \| \ X"$mf" : 'X\(/\)' \| . 2>/dev/null || $as_echo X"$mf" | sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ s//\1/ q } /^X\(\/\/\)[^/].*/{ s//\1/ q } /^X\(\/\/\)$/{ s//\1/ q } /^X\(\/\).*/{ s//\1/ q } s/.*/./; q'` else continue fi # Extract the definition of DEPDIR, am__include, and am__quote # from the Makefile without running `make'. DEPDIR=`sed -n 's/^DEPDIR = //p' < "$mf"` test -z "$DEPDIR" && continue am__include=`sed -n 's/^am__include = //p' < "$mf"` test -z "am__include" && continue am__quote=`sed -n 's/^am__quote = //p' < "$mf"` # When using ansi2knr, U may be empty or an underscore; expand it U=`sed -n 's/^U = //p' < "$mf"` # Find all dependency output files, they are included files with # $(DEPDIR) in their names. We invoke sed twice because it is the # simplest approach to changing $(DEPDIR) to its actual value in the # expansion. for file in `sed -n " s/^$am__include $am__quote\(.*(DEPDIR).*\)$am__quote"'$/\1/p' <"$mf" | \ sed -e 's/\$(DEPDIR)/'"$DEPDIR"'/g' -e 's/\$U/'"$U"'/g'`; do # Make sure the directory exists. test -f "$dirpart/$file" && continue fdir=`$as_dirname -- "$file" || $as_expr X"$file" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \ X"$file" : 'X\(//\)[^/]' \| \ X"$file" : 'X\(//\)$' \| \ X"$file" : 'X\(/\)' \| . 2>/dev/null || $as_echo X"$file" | sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ s//\1/ q } /^X\(\/\/\)[^/].*/{ s//\1/ q } /^X\(\/\/\)$/{ s//\1/ q } /^X\(\/\).*/{ s//\1/ q } s/.*/./; q'` as_dir=$dirpart/$fdir; as_fn_mkdir_p # echo "creating $dirpart/$file" echo '# dummy' > "$dirpart/$file" done done } ;; esac done # for ac_tag as_fn_exit 0 _ACEOF ac_clean_files=$ac_clean_files_save test $ac_write_fail = 0 || as_fn_error $? "write failure creating $CONFIG_STATUS" "$LINENO" 5 # configure is writing to config.log, and then calls config.status. # config.status does its own redirection, appending to config.log. # Unfortunately, on DOS this fails, as config.log is still kept open # by configure, so config.status won't be able to write to it; its # output is simply discarded. So we exec the FD to /dev/null, # effectively closing config.log, so it can be properly (re)opened and # appended to by config.status. When coming back to configure, we # need to make the FD available again. if test "$no_create" != yes; then ac_cs_success=: ac_config_status_args= test "$silent" = yes && ac_config_status_args="$ac_config_status_args --quiet" exec 5>/dev/null $SHELL $CONFIG_STATUS $ac_config_status_args || ac_cs_success=false exec 5>>config.log # Use ||, not &&, to avoid exiting from the if with $? = 1, which # would make configure fail if this is the last instruction. $ac_cs_success || as_fn_exit 1 fi if test -n "$ac_unrecognized_opts" && test "$enable_option_checking" != no; then { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: unrecognized options: $ac_unrecognized_opts" >&5 $as_echo "$as_me: WARNING: unrecognized options: $ac_unrecognized_opts" >&2;} fi if test x"$enable_libmapi" = x""; then enable_libmapi="no" fi if test x"$enable_libmapiadmin" = x""; then enable_libmapiadmin="no" fi if test x"$enable_libocpf" = x""; then enable_libocpf="no" fi if test x"$enable_libmapixx" = x""; then enable_libmapixx="no" fi if test x"$enable_openchangeclient" = x""; then enable_openchangeclient="no" fi if test x"$enable_mapiprofile" = x""; then enable_mapiprofile="no" fi if test x"$enable_openchangepfadmin" = x""; then enable_openchangepfadmin="no" fi if test x"$enable_exchange2mbox" = x""; then enable_exchange2mbox="no" fi if test x"$enable_exchange2ical" = x""; then enable_exchange2ical="no" fi if test x"$enable_mapitest" = x""; then enable_mapitest="no" fi if test x"$enable_openchangemapidump" = x""; then enable_openchangemapidump="no" fi if test x"$enable_schemaIDGUID" = x""; then enable_schemaIDGUID="no" fi if test x"$enable_mapiproxy" = x""; then enable_mapiproxy="no" fi if test x"$enable_doxygen" = x""; then enable_doxygen="no" fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: =============================================================== OpenChange Configuration (Please review) * OpenChange Libraries: - libmapi (C library): $enable_libmapi Thread support: $enable_pthread $enable_thread_lib - libmapi++ (C++ library): $enable_libmapixx - libmapiadmin: $enable_libmapiadmin - libocpf: $enable_libocpf * OpenChange Server: - mapiproxy: $enable_mapiproxy * OpenChange mapistore backends: - backends dependencies goes here * OpenChange Tools: - openchangeclient: $enable_openchangeclient - mapiprofile: $enable_mapiprofile - openchangepfadmin: $enable_openchangepfadmin - exchange2mbox: $enable_exchange2mbox - exchange2ical: $enable_exchange2ical - mapitest: $enable_mapitest - openchangemapidump: $enable_openchangemapidump - schemaIDGUID: $enable_schemaIDGUID * subunit format (mapitest): $have_subunit * OpenChange Documentation: $enable_doxygen * Coverage Tests: $use_cov * OpenChange Bindings: - Qt4: $enable_openchange_qt4 * Installation prefix: $prefix =============================================================== " >&5 $as_echo " =============================================================== OpenChange Configuration (Please review) * OpenChange Libraries: - libmapi (C library): $enable_libmapi Thread support: $enable_pthread $enable_thread_lib - libmapi++ (C++ library): $enable_libmapixx - libmapiadmin: $enable_libmapiadmin - libocpf: $enable_libocpf * OpenChange Server: - mapiproxy: $enable_mapiproxy * OpenChange mapistore backends: - backends dependencies goes here * OpenChange Tools: - openchangeclient: $enable_openchangeclient - mapiprofile: $enable_mapiprofile - openchangepfadmin: $enable_openchangepfadmin - exchange2mbox: $enable_exchange2mbox - exchange2ical: $enable_exchange2ical - mapitest: $enable_mapitest - openchangemapidump: $enable_openchangemapidump - schemaIDGUID: $enable_schemaIDGUID * subunit format (mapitest): $have_subunit * OpenChange Documentation: $enable_doxygen * Coverage Tests: $use_cov * OpenChange Bindings: - Qt4: $enable_openchange_qt4 * Installation prefix: $prefix =============================================================== " >&6; } openchange-2.0/configure.ac000066400000000000000000000640101223057412600157530ustar00rootroot00000000000000# Simple configuration script for OpenChange # Written by Jelmer Vernooij AC_PREREQ(2.57) AC_INIT(openchange, 2.0, [openchange@openchange.org]) AC_CONFIG_HEADER([config.h]) AM_INIT_AUTOMAKE AC_DEFINE(_GNU_SOURCE, 1, [Use GNU extensions]) PKG_PROG_PKG_CONFIG([0.20]) if test -z "$CFLAGS"; then CFLAGS="-g"; fi CFLAGS="-I. $CFLAGS" dnl ################################################################# dnl Check for OS dependent options dnl ################################################################# AC_CANONICAL_HOST case "${host}" in *freebsd*) BUILD_FOR_FREEBSD=yes AC_SUBST(BUILD_FOR_FREEBSD) MANUALLY_CREATE_SYMLINKS=yes ;; *solaris*) BUILD_FOR_SOLARIS=yes AC_SUBST(BUILD_FOR_SOLARIS) MANUALLY_CREATE_SYMLINKS=yes ;; esac AC_SUBST(MANUALLY_CREATE_SYMLINKS) # # OC_CHECK_SAMBA_PATH([PATH],[action-if-found],[action-if-not-found]) # ------------------------------------------------------------------- AC_DEFUN([OC_CHECK_SAMBA_PATH], [ old_PKG_CONFIG_PATH="$PKG_CONFIG_PATH" PKG_CONFIG_PATH="$1/lib64/pkgconfig:$1/lib/pkgconfig${PKG_CONFIG_PATH:+:$PKG_CONFIG_PATH}" export PKG_CONFIG_PATH PKG_CHECK_EXISTS([samba-hostconfig], [found=1], [found=0]) PKG_CONFIG_PATH="$old_PKG_CONFIG_PATH" if test $found = 1; then ifelse([$2],[], [echo -n ], [$2]) ifelse([$3],[],[],[else [$3]]) fi ]) AC_MSG_CHECKING([for samba 4]) AC_ARG_WITH(samba, [AC_HELP_STRING([--with-samba], [Override location Samba is installed])], [ sambaprefix="$withval" ],[ for p in "$prefix" /usr/local/samba /usr/local /usr do OC_CHECK_SAMBA_PATH($p, [sambaprefix="$p"]) if test -n "${sambaprefix:-}"; then break fi done ]) AC_SUBST(sambaprefix) OC_CHECK_SAMBA_PATH($sambaprefix,[], AC_MSG_ERROR(Samba 4 not found)) AC_MSG_RESULT($sambaprefix) PKG_CONFIG_PATH="$sambaprefix/lib/pkgconfig:$PKG_CONFIG_PATH" PATH="$sambaprefix/bin:$PATH" # # OC_SETVAL([NAME]) # ----------------- AC_DEFUN([OC_SETVAL], [ AC_ARG_VAR([NAME], [var name]) if test x"$enable_$1" = x""; then enable_$1="no" fi[] ]) # # OC_CHECK_SAMBA_VERSION([RELEASE],[VERSION], [action-if-found],[action-if-not-found], # [action-if-cross-compiling]) # ------------------------------------------------------------------------------------ AC_DEFUN([OC_CHECK_SAMBA_VERSION], [ AC_RUN_IFELSE([AC_LANG_SOURCE([[ #include int main() { if (!strcmp(SAMBA_VERSION_STRING, "$1") || !strcmp(SAMBA_VERSION_STRING, "$2")) {return 0; } else { return -1;} } ]])],[$3],[ ifelse([$4],[],[AC_MSG_WARN([The Samba4 version installed on your system doesn't meet OpenChange requirements ($1 or $2).])],[$4])],[$5]) ]) # # OC_RULE_ADD([NAME], [TYPE]) # --------------------------- AC_DEFUN([OC_RULE_ADD], [ AC_ARG_VAR([NAME], [rule name]) AC_ARG_VAR([TYPE], [rule type]) if test "x${$1}set" != "xset"; then case "$2" in LIBS) OC_$2="$OC_$2 $1" OC_$2_INSTALL="$OC_$2_INSTALL $1-install" OC_$2_UNINSTALL="$OC_$2_UNINSTALL $1-uninstall" OC_$2_INSTALLPC="$OC_$2_INSTALLPC $1-installpc" OC_$2_INSTALLHEADER="$OC_$2_INSTALLHEADER $1-installheader" OC_$2_INSTALLLIB="$OC_$2_INSTALLLIB $1-installlib" AC_SUBST(OC_$2_INSTALLPC) AC_SUBST(OC_$2_INSTALLHEADER) AC_SUBST(OC_$2_INSTALLLIB) ;; TOOLS) OC_$2="$OC_$2 $1" OC_$2_INSTALL="$OC_$2_INSTALL $1-install" OC_$2_UNINSTALL="$OC_$2_UNINSTALL $1-uninstall" ;; SERVER|MAPISTORE) OC_$2="$OC_$2 $1" OC_$2_CLEAN="$OC_$2_CLEAN $1-clean" OC_$2_INSTALL="$OC_$2_INSTALL $1-install" OC_$2_UNINSTALL="$OC_$2_UNINSTALL $1-uninstall" ;; esac AC_SUBST(OC_$2) AC_SUBST(OC_$2_CLEAN) AC_SUBST(OC_$2_INSTALL) AC_SUBST(OC_$2_UNINSTALL) enable_$1="yes" fi[] ]) dnl ################################################################## dnl Some general portability stuff dnl ################################################################## AC_CHECK_HEADERS( sys/cdefs.h string.h sys/sockio.h) AC_CHECK_FUNCS(strcasestr) dnl ########################################################################### dnl _AC_LANG_COMPILER_ICC dnl Check whether the compiler for the current language is really ICC. dnl ########################################################################### m4_define([AC_LANG_COMPILER_ICC], [AC_CACHE_CHECK([whether we are really using the Intel _AC_LANG compiler], [ac_cv_[]_AC_LANG_ABBREV[]_compiler_icc], [_AC_COMPILE_IFELSE([AC_LANG_PROGRAM([], [[#ifndef __INTEL_COMPILER choke me #endif ]])], [ac_compiler_icc=yes], [ac_compiler_icc=no]) ac_cv_[]_AC_LANG_ABBREV[]_compiler_icc=$ac_compiler_icc ])]) dnl ########################################################################### dnl _AC_LANG_COMPILER_SUNCC dnl Check whether the compiler for the current language is really Sun compiler. dnl ########################################################################### m4_define([AC_LANG_COMPILER_SUNCC], [AC_CACHE_CHECK([whether we are really using the Sun _AC_LANG compiler], [ac_cv_[]_AC_LANG_ABBREV[]_compiler_suncc], [_AC_COMPILE_IFELSE([AC_LANG_PROGRAM([], [[#ifndef __SUNPRO_C choke me #endif ]])], [ac_compiler_suncc=yes], [ac_compiler_suncc=no]) ac_cv_[]_AC_LANG_ABBREV[]_compiler_suncc=$ac_compiler_suncc ])]) dnl ########################################################################### dnl FreeBSD installs some libraries such as libpopt in the non default dnl search path /usr/local/{include,lib}. This nasty hack ensures dnl configure.ac will find the library if available and additional dnl flags be correctly added while compiling. dnl ########################################################################### if test x"$BUILD_FOR_FREEBSD" = x"yes"; then CFLAGS="$CFLAGS -I/usr/local/include" LDFLAGS="$LDFLAGS -L/usr/local/lib" CXXFLAGS="$CXXFLAGS -I/usr/local/include" fi dnl ---------------------------------------------------------------------------- dnl Check for comparison_fn_t dnl ---------------------------------------------------------------------------- AC_CHECK_TYPE(comparison_fn_t, [AC_DEFINE(HAVE_COMPARISON_FN_T, 1,[Whether or not we have comparison_fn_t])], [], [[#include ]]) dnl ########################################################################### dnl libmapi and required dependencies dnl ########################################################################### dnl --------------------------------------------------------------------------- dnl Check for CC dnl --------------------------------------------------------------------------- AC_PROG_CC dnl --------------------------------------------------------------------------- dnl coverage testing dnl --------------------------------------------------------------------------- AC_ARG_ENABLE([coverage], AS_HELP_STRING([--enable-coverage], [Compile the library with code coverage support (default is NO)]), [use_cov=$enableval], [use_cov=no]) if test "x$use_cov" = x"yes"; then COVERAGE_INIT="coverage-init" fi AC_SUBST(COVERAGE_INIT) dnl --------------------------------------------------------------------------- dnl Set up the right compiler options dnl --------------------------------------------------------------------------- AC_LANG_COMPILER_SUNCC AC_LANG_COMPILER_ICC if test x"$ac_cv_c_compiler_suncc" = x"yes"; then dnl Sun Studio Compiler COMPILER_OPTIONS_SHARED="-D__FUNCTION__=__func__" COMPILER_OPTIONS_C="$COMPILER_OPTIONS_SHARED" COMPILER_OPTIONS_CXX="$COMPILER_OPTIONS_SHARED" LDFLAGS="$LDFLAGS -z ignore -R '\$\$ORIGIN/../lib'" elif test x"$ac_cv_c_compiler_icc" = x"yes"; then dnl Intel Compiler COMPILER_OPTIONS_SHARED="-Wall -fstrict-aliasing -Wmissing-prototypes -Wstrict-prototypes -wd2259,188,593,869,981,181,1419,2218" COMPILER_OPTIONS_C="$COMPILER_OPTIONS_SHARED" COMPILER_OPTIONS_CXX="$COMPILER_OPTIONS_SHARED" else dnl GNU Compiler COMPILER_OPTIONS_SHARED="-Wall -fstrict-aliasing -Wp,-D_FORTIFY_SOURCE=2" if test "x$use_cov" = "xyes"; then COMPILER_OPTIONS_SHARED="-O0 $COMPILER_OPTIONS_SHARED" else COMPILER_OPTIONS_SHARED="$COMPILER_OPTIONS_SHARED" fi COMPILER_OPTIONS_C="$COMPILER_OPTIONS_SHARED -Wmissing-prototypes -Wstrict-prototypes" if test "x$use_cov" = "xyes"; then COMPILER_OPTIONS_C="$COMPILER_OPTIONS_C -fprofile-arcs -ftest-coverage" LDFLAGS="$LDFLAGS -lgcov --coverage" fi COMPILER_OPTIONS_CXX="$COMPILER_OPTIONS_SHARED" if test "x$use_cov" = "xyes"; then COMPILER_OPTIONS_CXX="$COMPILER_OPTIONS_CXX -fprofile-arcs -ftest-coverage" LDFLAGS="$LDFLAGS -lgcov --coverage" fi fi AC_SUBST(COMPILER_OPTIONS_C) AC_SUBST(COMPILER_OPTIONS_CXX) dnl --------------------------------------------------------------------------- dnl Define an assert macro if this is a development release dnl --------------------------------------------------------------------------- . `dirname $0`/VERSION AC_SUBST(OPENCHANGE_VERSION_IS_SVN_SNAPSHOT) if test x"$OPENCHANGE_VERSION_IS_SVN_SNAPSHOT" = x"yes"; then ASSERT_DEFINITION="-DENABLE_ASSERTS" fi AC_SUBST(ASSERT_DEFINITION) dnl --------------------------------------------------------------------------- dnl Check for install dnl --------------------------------------------------------------------------- AC_PROG_INSTALL dnl --------------------------------------------------------------------------- dnl Check for Perl dnl --------------------------------------------------------------------------- AC_PATH_PROG(PERL, perl) if test x"$PERL" = x""; then AC_MSG_WARN([No version of perl was found!]) AC_MSG_ERROR([Please install perl http://www.perl.com]) fi AC_SUBST(PERL) dnl --------------------------------------------------------------------------- dnl Check for Pidl dnl --------------------------------------------------------------------------- AC_PATH_PROG(PIDL, pidl) if test x"$PIDL" = x""; then AC_MSG_WARN([No version of pidl was found!]) AC_MSG_ERROR([Please install pidl]) fi AC_SUBST(PIDL) dnl --------------------------------------------------------------------------- dnl Check for Python dnl --------------------------------------------------------------------------- AC_PATH_PROG(PYTHON, python) if test x"$PYTHON" = x""; then AC_MSG_WARN([No version of python was found!]) AC_MSG_ERROR([Please install python]) fi AC_SUBST(PYTHON) AC_PATH_PROG(PYTHON_CONFIG, python-config) if test x"$PYTHON_CONFIG" = x""; then AC_MSG_WARN([No version of python-config was found!]) AC_MSG_ERROR([Please install python-dev 2.7]) fi AC_SUBST(PYTHON_CONFIG) AC_MSG_CHECKING(python cflags) PYTHON_CFLAGS=`$PYTHON_CONFIG --cflags` AC_MSG_RESULT($PYTHON_CFLAGS) AC_SUBST(PYTHON_CFLAGS) AC_MSG_CHECKING(python libs) PYTHON_LIBS=`$PYTHON_CONFIG --libs` AC_MSG_RESULT($PYTHON_LIBS) AC_SUBST(PYTHON_LIBS) AC_MSG_CHECKING(python library directory) pythondir=`$PYTHON -c "from distutils import sysconfig; print sysconfig.get_python_lib(1, 0, '\\${prefix}')"` AC_MSG_RESULT($pythondir) AC_SUBST(pythondir) dnl ---------------------------------------------------------------------------- dnl Check for Flex dnl Flex version < 2.5.35 is fine but 2.5.4 beta is not. This is the dnl default version provided under FreeBSD or RHL5 dnl ---------------------------------------------------------------------------- if test x"$OPENCHANGE_VERSION_IS_SVN_SNAPSHOT" = x"yes"; then AC_ARG_VAR([FLEX], [Location of the flex program.]) AC_CHECK_PROG([FLEX], [flex], [flex]) if test x"$FLEX" = x""; then AC_MSG_WARN([No version of flex was found!]) AC_MSG_ERROR([Please install flex]) else V=`$FLEX --version | awk '{print $NF}'` W=`echo $V | awk -F. '{if (((($1*100 + $2)*100 + $3) > 20535) || $3 == 4) print "no"}'` if test "x$W" != x ; then AC_MSG_WARN([Adjust your FLEX environment variable]) AC_MSG_ERROR([Flex version 2.5.35 or below is needed. You have $V]) fi fi AC_SUBST(FLEX) fi dnl --------------------------------------------------------------------------- dnl Samba4 modules dnl --------------------------------------------------------------------------- PKG_CHECK_MODULES(TALLOC, talloc) PKG_CHECK_MODULES(SAMBA, dcerpc ndr samba-hostconfig samba-util tevent samba-credentials) PKG_CHECK_MODULES(SAMBASERVER, dcerpc_server samdb, [], [AC_MSG_WARN(No mapiproxy support)]) PKG_CHECK_MODULES(TDB, tdb) PKG_CHECK_MODULES(LDB, ldb) dnl --------------------------------------------------------------------------- dnl Check a particular Samba4 git revision dnl --------------------------------------------------------------------------- oc_save_CPPFLAGS="$CPPFLAGS" CPPFLAGS="$CPPFLAGS `$PKG_CONFIG --cflags-only-I samba-hostconfig`" AC_CHECK_HEADER([samba/version.h],, AC_MSG_ERROR([Could not find Samba4 headers. Re-run ./configure with --with-samba=XXX where XXX is the prefix that Samba4 was installed to.])) . `dirname $0`/script/samba4_ver.sh OC_CHECK_SAMBA_VERSION([$SAMBA4_RELEASE],[$SAMBA4_GIT_VER-GIT-$SAMBA4_GIT_REV]) CPPFLAGS="$oc_save_CPPFLAGS" AC_MSG_CHECKING([for DCE/RPC server modules directory]) DCERPC_SERVER_MODULESDIR=`$PKG_CONFIG --variable=modulesdir dcerpc_server` AC_SUBST(DCERPC_SERVER_MODULESDIR) AC_MSG_RESULT($DCERPC_SERVER_MODULESDIR) dnl --------------------------------------------------------------------------- dnl Finally add libmapi to the library list dnl --------------------------------------------------------------------------- if test "x$SAMBA_LIBS" != "x" ; then libmapi=1 fi OC_RULE_ADD(libmapi, LIBS) dnl nasty hack: only compile IDL if we have a library dnl libraries require libmapi and libmapi require IDL OC_IDL="idl" AC_SUBST(OC_IDL) dnl --------------------------------------------------------------------------- dnl Check for dl libs dnl --------------------------------------------------------------------------- AC_CHECK_LIB([dl], [dlopen], [ DL_LIBS="-ldl" AC_SUBST(DL_LIBS) ], [ AC_CHECK_FUNCS(dlopen, [ DL_LIBS="" AC_SUBST(DL_LIBS) ], [ AC_MSG_ERROR([unable to find dlopen]) ]) ]) dnl --------------------------------------------------------------------------- dnl Check for pthread libs dnl --------------------------------------------------------------------------- enable_pthread=no enable_thread_lib="" AC_CHECK_LIB([pthread], [pthread_mutex_init], [ AC_DEFINE(HAVE_PTHREADS, 1, [Define if you want to use pthread for thread safety]) THREAD_LIBS=-lpthread enable_pthread="yes" enable_thread_lib="(pthread)" ], [ AC_MSG_WARN([pthread is missing - library is not thread safe]) enable_pthread="no" ]) if test x"$enable_pthread" = x"no"; then dnl Check for gthread-2.0 / glib based implementation PKG_CHECK_MODULES(GTHREAD, gthread-2.0, [ AC_DEFINE(HAVE_GTHREAD, 1, [Define if you want to use gthread for thread safety]) THREAD_LIBS=$GTHREAD_LIBS THREAD_CFLAGS=$GTHREAD_CFLAGS enable_pthread=yes enable_thread_lib="(gthread)" ], [ enable_pthread=no ]) fi AC_SUBST(THREAD_LIBS) AC_SUBST(THREAD_CFLAGS) dnl Additional thread library detection is required here: dnl FreeBSD (pthreads), glib etc. dnl ########################################################################### dnl libmapi++ dependencies dnl ########################################################################### dnl --------------------------------------------------------------------------- dnl Check for g++ dnl --------------------------------------------------------------------------- AC_CACHE_CHECK([C++ compiler availability], [ac_cv_libmapixx_gxx_works], [ AC_LANG_PUSH([C++]) AC_COMPILE_IFELSE([AC_LANG_SOURCE([[int main() { return 0; }]])], [ac_cv_libmapixx_gxx_works=yes], [ac_cv_libmapixx_gxx_works=no]) AC_LANG_POP([C++]) ]) dnl --------------------------------------------------------------------------- dnl Check for boost-thread dnl --------------------------------------------------------------------------- AC_ARG_VAR([BOOST_LIB_SUFFIX], [Boost library name suffix]) AC_CACHE_CHECK([for boost_thread$BOOST_LIB_SUFFIX library], [ov_cv_boost_thread], [ ov_cv_boost_thread=no ov_save_LIBS=$LIBS LIBS="-lboost_thread$BOOST_LIB_SUFFIX $LIBS" AC_LANG_PUSH([C++]) AC_LINK_IFELSE([AC_LANG_PROGRAM([[#include ]], [[boost::thread t]])], [ov_cv_boost_thread=yes]) AC_LANG_POP([C++]) LIBS=$ov_save_LIBS ]) if test x"$ac_cv_libmapixx_gxx_works" = "xyes"; then if test x"$ov_cv_boost_thread" = "xyes"; then AC_PROG_CXX libmapixx=1 OC_RULE_ADD(libmapixx, LIBS) fi fi dnl ########################################################################### dnl libocpf dependencies dnl ########################################################################### dnl --------------------------------------------------------------------------- dnl Check for Bison dnl --------------------------------------------------------------------------- if test x"$OPENCHANGE_VERSION_IS_SVN_SNAPSHOT" = x"yes"; then AC_ARG_VAR([BISON], [Location of the bison program.]) AC_PATH_PROG([BISON], [bison], [bison]) if test x"$BISON" != x""; then libocpf=1 OC_RULE_ADD(libocpf, LIBS) AC_SUBST(BISON) fi else libocpf=1 OC_RULE_ADD(libocpf, LIBS) fi dnl ########################################################################### dnl libmapiadmin dependencies dnl ########################################################################### PKG_CHECK_EXISTS([ dcerpc_samr ], [ enable_libmapiadmin="yes" ], [ enable_libmapiadmin="no" ]) if test x"$enable_libmapiadmin" = x"yes"; then PKG_CHECK_MODULES(SAMR, dcerpc_samr ndr_standard) libmapiadmin=1 OC_RULE_ADD(libmapiadmin, LIBS) fi dnl ########################################################################## dnl tools dependencies dnl ########################################################################## dnl -------------------------------------------------------------------------- dnl Check for libical dnl -------------------------------------------------------------------------- PKG_CHECK_MODULES([ICAL], [libical], [have_libical="yes"], [have_libical="no"]) AC_SUBST(ICAL_CFLAGS) AC_SUBST(ICAL_LIBS) PKG_CHECK_MODULES([ICAL_0_46], [libical >= 0.46], [have_libical_0_46="1"], [have_libical_0_46="0"]) AC_SUBST(have_libical_0_46) dnl -------------------------------------------------------------------------- dnl Check for popt dnl -------------------------------------------------------------------------- AC_CHECK_LIB([popt], [poptFreeContext], [ AC_DEFINE(HAVE_LIBPOPT, 1, [Define if you want to use libpopt]) enable_libpopt="yes" ], [ AC_MSG_WARN([libpopt is missing - can't build openchange tools]) enable_libpopt="no" ]) if test x"$enable_libpopt" = x"yes"; then if test x"$enable_libmapiadmin" = x"yes"; then openchangepfadmin=1 mapitest=1 fi if test x"$enable_libocpf" = x"yes"; then openchangeclient=1 fi if test x"$have_libical" = x"yes"; then exchange2ical=1 fi MAPISTORE_TEST=mapistore_test mapiprofile=1 openchangemapidump=1 schemaIDGUID=1 check_fasttransfer=1 test_asyncnotif=1 fi AC_SUBST(MAPISTORE_TEST) OC_RULE_ADD(openchangeclient, TOOLS) #OC_RULE_ADD(mapistore_fsocpf, MAPISTORE) OC_RULE_ADD(exchange2ical, TOOLS) OC_RULE_ADD(openchangepfadmin, TOOLS) OC_RULE_ADD(mapitest, TOOLS) OC_RULE_ADD(mapiprofile, TOOLS) OC_RULE_ADD(openchangemapidump, TOOLS) OC_RULE_ADD(schemaIDGUID, TOOLS) OC_RULE_ADD(check_fasttransfer, TOOLS) OC_RULE_ADD(test_asyncnotif, TOOLS) dnl -------------------------------------------------------------------------- dnl Check for libmagic dnl -------------------------------------------------------------------------- AC_CHECK_LIB([magic], [magic_open], [ AC_DEFINE(HAVE_LIBMAGIC, 1, [Define if you want to use libmagic]) MAGIC_LIBS="-lmagic -lz" enable_libmagic="yes" ], AC_SUBST(MAGIC_LIBS) [ AC_MSG_WARN([libmagic is missing - can't build exchange2mbox]) enable_libmagic="no" ]) if test x"$enable_libmagic" = x"yes"; then AC_CHECK_LIB([z], [gzopen], [], [ AC_MSG_ERROR([Z library not found, please install zlib-devel.], [1]) ]) if test x"$enable_libpopt" = x"yes"; then exchange2mbox=1 fi fi OC_RULE_ADD(exchange2mbox, TOOLS) dnl ########################################################################## dnl libmapistore dependencies dnl ########################################################################## AC_CHECK_LIB([rt], [mq_open], [ RT_LIBS="-lrt" AC_SUBST(RT_LIBS) ], [ AC_CHECK_FUNCS(mq_open, [ RT_LIBS="" AC_SUBST(RT_LIBS) ], [ AC_MSG_ERROR([unable to find mq_open]) ]) ]) dnl ########################################################################## dnl libmapistore backends dependencies dnl ########################################################################## OC_MAPISTORE= OC_MAPISTORE_CLEAN= OC_MAPISTORE_INSTALL= OC_MAPISTORE_UNINSTALL= AC_SUBST(OC_MAPISTORE) AC_SUBST(OC_MAPISTORE_CLEAN) AC_SUBST(OC_MAPISTORE_INSTALL) AC_SUBST(OC_MAPISTORE_UNINSTALL) dnl ########################################################################## dnl mapiproxy server dnl ########################################################################## if test x$PYTHON != x; then if test "x$SAMBASERVER_LIBS" != x ; then mapiproxy=1 fi fi OC_RULE_ADD(mapiproxy, SERVER) AC_ARG_WITH(modulesdir, [AS_HELP_STRING([--with-modulesdir], [Modules path to use])], [modulesdir="$withval"; ], [modulesdir="\${prefix}/modules"; ]) AC_SUBST(modulesdir) dnl ########################################################################## dnl Python bindings dependencies dnl ########################################################################## AC_ARG_ENABLE(pymapi, AC_HELP_STRING([--enable-pymapi], [build Python bindings for libmapi]), enable_pymapi="$enableval", enable_pymapi=no) PYCDIR=`$PYTHON -c "import distutils.sysconfig; print distutils.sysconfig.get_python_lib(1, prefix='\\$(prefix)')"` AC_SUBST(PYCDIR) dnl Enable pyopenchange by default PYMAPIALL="$PYMAPIALL pyopenchange" PYMAPIINSTALL="$PYMAPIALLINSTALL pyopenchange-install" PYMAPIUNINSTALL="$PYMAPIUNINSTALL pyopenchange-uninstall" AC_SUBST(PYMAPIALL) AC_SUBST(PYMAPIINSTALL) AC_SUBST(PYMAPIUNINSTALL) dnl ########################################################################## dnl Documentation dependencies dnl ########################################################################## AC_PATH_PROG(DOXYGEN, doxygen) if test x"$DOXYGEN" = x""; then AC_MSG_WARN(doxygen) enable_doxygen="no" else enable_doxygen="yes" AC_SUBST(DOXYGEN) fi dnl ########################################################################## dnl (Optional) subunit support in mapitest dnl ########################################################################## PKG_CHECK_MODULES(SUBUNIT, libsubunit, found_subunit=yes, found_subunit=no) AC_SUBST(SUBUNIT_CFLAGS) AC_SUBST(SUBUNIT_LIBS) if test x"$found_subunit" = x"yes"; then AC_DEFINE(HAVE_SUBUNIT, 1, [Define if you want to use subunit]) have_subunit="yes" else have_subunit="no" fi dnl ########################################################################## dnl Qt4 support dnl ########################################################################## AC_ARG_ENABLE(openchange-qt4, AC_HELP_STRING([--enable-openchange-qt4], [Compile OpenChange Qt4 wrapper.]), enable_openchange_qt4=$enableval, enable_openchange_qt4="no") if test x$enable_openchange_qt4 = xyes; then PKG_CHECK_MODULES(Qt4, QtCore >= 4.3.0 QtGui >= 4.3.0) MOC=`$PKG_CONFIG --variable=moc_location QtCore` elif test x$enable_openchange_qt4 = xtry; then PKG_CHECK_MODULES(Qt4, QtCore >= 4.3.0 QtGui >= 4.3.0, [enable_openchange_qt4="yes" MOC=`$PKG_CONFIG --variable=moc_location QtCore`], [enable_openchange_qt4="no"]) fi AC_SUBST(Qt4_CFLAGS) AC_SUBST(Qt4_LIBS) AC_SUBST(MOC) if test "x$enable_openchange_qt4" = "xyes"; then OPENCHANGE_QT4="openchange_qt4" fi AC_SUBST(OPENCHANGE_QT4) dnl *********************** dnl Makefiles dnl *********************** AC_CONFIG_FILES([config.mk libmapi.pc libmapiadmin.pc libocpf.pc mapiproxy/libmapiproxy.pc mapiproxy/libmapiserver.pc mapiproxy/libmapistore.pc libmapi++.pc Doxyfile libmapi++/Doxyfile libocpf/Doxyfile libmapiadmin/Doxyfile libmapi/Doxyfile mapiproxy/Doxyfile utils/mapitest/Doxyfile mapiproxy/libmapistore/Doxyfile]) AC_OUTPUT dnl ########################################################################## dnl Print configuration info dnl ########################################################################## OC_SETVAL(libmapi) OC_SETVAL(libmapiadmin) OC_SETVAL(libocpf) OC_SETVAL(libmapixx) OC_SETVAL(openchangeclient) OC_SETVAL(mapiprofile) OC_SETVAL(openchangepfadmin) OC_SETVAL(exchange2mbox) OC_SETVAL(exchange2ical) OC_SETVAL(mapitest) OC_SETVAL(openchangemapidump) OC_SETVAL(schemaIDGUID) OC_SETVAL(mapiproxy) OC_SETVAL(doxygen) AC_MSG_RESULT([ =============================================================== OpenChange Configuration (Please review) * OpenChange Libraries: - libmapi (C library): $enable_libmapi Thread support: $enable_pthread $enable_thread_lib - libmapi++ (C++ library): $enable_libmapixx - libmapiadmin: $enable_libmapiadmin - libocpf: $enable_libocpf * OpenChange Server: - mapiproxy: $enable_mapiproxy * OpenChange mapistore backends: - backends dependencies goes here * OpenChange Tools: - openchangeclient: $enable_openchangeclient - mapiprofile: $enable_mapiprofile - openchangepfadmin: $enable_openchangepfadmin - exchange2mbox: $enable_exchange2mbox - exchange2ical: $enable_exchange2ical - mapitest: $enable_mapitest - openchangemapidump: $enable_openchangemapidump - schemaIDGUID: $enable_schemaIDGUID * subunit format (mapitest): $have_subunit * OpenChange Documentation: $enable_doxygen * Coverage Tests: $use_cov * OpenChange Bindings: - Qt4: $enable_openchange_qt4 * Installation prefix: $prefix =============================================================== ]) openchange-2.0/doc/000077500000000000000000000000001223057412600142315ustar00rootroot00000000000000openchange-2.0/doc/doxygen/000077500000000000000000000000001223057412600157065ustar00rootroot00000000000000openchange-2.0/doc/doxygen/apidocs.css000066400000000000000000000362151223057412600200510ustar00rootroot00000000000000/* ** WEBSITE ** */ BODY,H1,H2,H3,H4,H5,H6,P,CENTER,TD,TH,UL,DL,DIV { font-family: Geneva, Arial, Helvetica, sans-serif; } BODY,TD { font-size: 90%; } H1 { text-align: center; font-size: 160%; } H2 { font-size: 19px; font-weight: bold; color: #3E93D5; } H3 { font-size: 100%; } P { text-align: justify; } LI { li-style-type: square; li-style-position: outside; display: list-item; } CAPTION { font-weight: bold } DIV.qindex { width: 100%; background-color: #e8eef2; border: 1px solid #84b0c7; text-align: center; margin: 2px; padding: 2px; line-height: 140%; } DIV.nav { width: 100%; background-color: #e8eef2; border: 1px solid #84b0c7; text-align: center; margin: 2px; padding: 2px; line-height: 140%; } DIV.navtab { background-color: #e8eef2; border: 1px solid #84b0c7; text-align: center; margin: 2px; margin-right: 15px; padding: 2px; } TD.navtab { font-size: 70%; } A.qindex { text-decoration: none; font-weight: bold; color: #1A419D; } A.qindex:visited { text-decoration: none; font-weight: bold; color: #1A419D } A.qindex:hover { text-decoration: none; background-color: #ddddff; } A.qindexHL { text-decoration: none; font-weight: bold; background-color: #6666cc; color: #ffffff; border: 1px double #9295C2; } A.qindexHL:hover { text-decoration: none; background-color: #6666cc; color: #ffffff; } A.qindexHL:visited { text-decoration: none; background-color: #6666cc; color: #ffffff } A.el { text-decoration: none; font-weight: bold } A.elRef { font-weight: bold } A.code:link { text-decoration: none; font-weight: normal; color: #0000FF} A.code:visited { text-decoration: none; font-weight: normal; color: #0000FF} A.codeRef:link { font-weight: normal; color: #0000FF} A.codeRef:visited { font-weight: normal; color: #0000FF} A:hover { text-decoration: none; background-color: #f2f2ff } DL.el { margin-left: -1cm } .fragment { font-family: monospace, fixed; font-size: 95%; } PRE.fragment { border: 1px solid #CCCCCC; background-color: #f5f5f5; font-size: 11px; margin-top: 4px; margin-bottom: 4px; margin-left: 2px; margin-right: 8px; padding-left: 6px; padding-right: 6px; padding-top: 4px; padding-bottom: 4px; } DIV.ah { background-color: black; font-weight: bold; color: #ffffff; margin-bottom: 3px; margin-top: 3px } DIV.groupHeader { margin-left: 16px; margin-top: 12px; margin-bottom: 6px; font-weight: bold; } DIV.groupText { margin-left: 16px; font-style: italic; font-size: 90% } BODY { background: white; color: black; margin-right: 20px; margin-left: 20px; } TD.indexkey { background-color: #e8eef2; font-weight: bold; padding-right : 10px; padding-top : 2px; padding-left : 10px; padding-bottom : 2px; margin-left : 0px; margin-right : 0px; margin-top : 2px; margin-bottom : 2px; border: 1px solid #CCCCCC; } TD.indexvalue { background-color: #e8eef2; font-style: italic; padding-right : 10px; padding-top : 2px; padding-left : 10px; padding-bottom : 2px; margin-left : 0px; margin-right : 0px; margin-top : 2px; margin-bottom : 2px; border: 1px solid #CCCCCC; } TR.memlist { background-color: #f0f0f0; } P.formulaDsp { text-align: center; } IMG.formulaDsp { } IMG.formulaInl { vertical-align: middle; } SPAN.keyword { color: #008000 } SPAN.keywordtype { color: #604020 } SPAN.keywordflow { color: #e08000 } SPAN.comment { color: #800000 } SPAN.preprocessor { color: #806020 } SPAN.stringliteral { color: #002080 } SPAN.charliteral { color: #008080 } .mdescLeft { padding: 0px 8px 4px 8px; font-size: 80%; font-style: italic; background-color: #FAFAFA; border-top: 1px none #E0E0E0; border-right: 1px none #E0E0E0; border-bottom: 1px none #E0E0E0; border-left: 1px none #E0E0E0; margin: 0px; } .mdescRight { padding: 0px 8px 4px 8px; font-size: 80%; font-style: italic; background-color: #FAFAFA; border-top: 1px none #E0E0E0; border-right: 1px none #E0E0E0; border-bottom: 1px none #E0E0E0; border-left: 1px none #E0E0E0; margin: 0px; } .memItemLeft { padding: 1px 0px 0px 8px; margin: 4px; border-top-width: 1px; border-right-width: 1px; border-bottom-width: 1px; border-left-width: 1px; border-top-color: #E0E0E0; border-right-color: #E0E0E0; border-bottom-color: #E0E0E0; border-left-color: #E0E0E0; border-top-style: solid; border-right-style: none; border-bottom-style: none; border-left-style: none; background-color: #FAFAFA; font-size: 80%; } .memItemRight { padding: 1px 8px 0px 8px; margin: 4px; border-top-width: 1px; border-right-width: 1px; border-bottom-width: 1px; border-left-width: 1px; border-top-color: #E0E0E0; border-right-color: #E0E0E0; border-bottom-color: #E0E0E0; border-left-color: #E0E0E0; border-top-style: solid; border-right-style: none; border-bottom-style: none; border-left-style: none; background-color: #FAFAFA; font-size: 80%; } .memTemplItemLeft { padding: 1px 0px 0px 8px; margin: 4px; border-top-width: 1px; border-right-width: 1px; border-bottom-width: 1px; border-left-width: 1px; border-top-color: #E0E0E0; border-right-color: #E0E0E0; border-bottom-color: #E0E0E0; border-left-color: #E0E0E0; border-top-style: none; border-right-style: none; border-bottom-style: none; border-left-style: none; background-color: #FAFAFA; font-size: 80%; } .memTemplItemRight { padding: 1px 8px 0px 8px; margin: 4px; border-top-width: 1px; border-right-width: 1px; border-bottom-width: 1px; border-left-width: 1px; border-top-color: #E0E0E0; border-right-color: #E0E0E0; border-bottom-color: #E0E0E0; border-left-color: #E0E0E0; border-top-style: none; border-right-style: none; border-bottom-style: none; border-left-style: none; background-color: #FAFAFA; font-size: 80%; } .memTemplParams { padding: 1px 0px 0px 8px; margin: 4px; border-top-width: 1px; border-right-width: 1px; border-bottom-width: 1px; border-left-width: 1px; border-top-color: #E0E0E0; border-right-color: #E0E0E0; border-bottom-color: #E0E0E0; border-left-color: #E0E0E0; border-top-style: solid; border-right-style: none; border-bottom-style: none; border-left-style: none; color: #606060; background-color: #FAFAFA; font-size: 80%; } .search { color: #003399; font-weight: bold; } FORM.search { margin-bottom: 0px; margin-top: 0px; } INPUT.search { font-size: 75%; color: #000080; font-weight: normal; background-color: #e8eef2; } TD.tiny { font-size: 75%; } a { color: #1A41A8; } a:visited { color: #2A3798; } .dirtab { padding: 4px; border-collapse: collapse; border: 1px solid #84b0c7; } TH.dirtab { background: #e8eef2; font-weight: bold; } HR { height: 1px; border: none; border-top: 1px solid black; margin-bottom: 50px; } /* Style for detailed member documentation */ .memtemplate { font-size: 80%; color: #606060; font-weight: normal; } .memnav { background-color: #e8eef2; border: 1px solid #84b0c7; text-align: center; margin: 2px; margin-right: 15px; padding: 2px; } .memitem { padding: 4px; background-color: white; border-width: 1px; border-style: solid; border-color: #ccc; -moz-border-radius: 8px 8px 8px 8px; margin-bottom: 30px; } .memname { white-space: nowrap; font-weight: bold; font-size: 12px; margin: 10px 10px 10px 10px; } .memname EM { color: #45417e; } .memdoc{ padding-left: 10px; padding-right: 10px; } .memdoc EM, TD { font-size: 12px; } .memproto { background-color: #e9e9f4; width: 100%; border-width: 1px; border-style: solid; border-color: #ccc; font-weight: bold; -moz-border-radius: 8px 8px 8px 8px; } .paramkey { text-align: right; } .paramtype { white-space: nowrap; } .paramname { color: #602020; font-style: italic; white-space: nowrap; } /* End Styling for detailed member documentation */ /* for the tree view */ .ftvtree { font-family: sans-serif; margin:0.5em; } .directory { font-size: 9pt; font-weight: bold; } .directory h3 { margin: 0px; margin-top: 1em; font-size: 11pt; } .directory > h3 { margin-top: 0; } .directory p { margin: 0px; white-space: nowrap; } .directory div { display: none; margin: 0px; } .directory img { vertical-align: -30%; } #website { width: 820px; height: 100%; margin-left: auto; margin-right: auto; text-align: left; /* IE hack */ * position: absolute; * left: 50%; * margin-left: -410px; } /* ** HEADER ** */ .header { height: 200px; background: url(header.jpg) no-repeat top center; } body { background: #fff url(body_top_bg2.jpg) top left repeat-x; font-family: Arial, Trebuchet MS, Tahoma, Verdana, Helvetica, sans-serif; font-size: 11px; line-height: 17px; color: #444; color: #3a3a3a; fdpadding-top: 15px; text-align: center; background-color: #fbfbfb; } h1 { font: 24px bold Trebuchet MS, Arial; color: #FFF; padding: 0; margin: 0; } /* ** MIDDLE SIDE ** */ #middle_side { display: block; height: 100%; width: 800px; margin-top: 7px; backsground: url(middle_bg.jpg) top left repeat-x; background-color: #fbfbfb; } /* left and right side */ #left_side { background-color: #fff; clear: both; margin-bottom: 10px; border-bottom: 1px solid #eee; border-left: 1px solid #eee; border-right: 1px solid #eee; -moz-border-radius: 0 0 8px 8px; height: 29px; } /* ** MENU HORIZONTAL ** */ /************ Global Navigation *************/ DIV.tabs { float : left; width : 100%; background : url("tab_b.gif") repeat-x bottom; margin-top : 10px; margin-bottom : 4px; } DIV.tabs ul { margin : 0px; padding-left : 10px; list-style : none; } DIV.tabs li { display : inline; margin : 0px; padding : 0px; } DIV.tabs A { float : left; background : url("tab_r.gif") no-repeat right top; border-bottom : 1px solid #84B0C7; font-size : x-small; font-weight : bold; text-decoration : none; } DIV.tabs A:link, .tabs A:visited, DIV.tabs A:active, .tabs A:hover { color: #1A419D; } DIV.tabs SPAN { float : left; display : block; background : url("tab_l.gif") no-repeat left top; padding : 5px 10px; white-space : nowrap; } DIV.tabs TD { font-size : x-small; font-weight : bold; text-decoration : none; } /* Commented Backslash Hack hides rule from IE5-Mac \*/ DIV.tabs SPAN {float : none;} /* End IE5-Mac hack */ DIV.tabs A:hover SPAN { background-position: 0% -150px; } DIV.tabs LI.current A { background-position: 100% -150px; border-width : 0px; } DIV.tabs LI.current SPAN { background-position: 0% -150px; padding-bottom : 6px; } DIV.nav { background : none; border : none; border-bottom : 1px solid #84B0C7; } #right_side_home { font-family: "Lucida Grande", Arial, Verdana, sans-serif; background-color: white; padding: 0px 20px; border: 1px solid #ebebeb; border: 1px solid #ddd; -moz-border-radius: 10px 10px; width: 750px; * width: 800px; * margin-left: 0px; padding-bottom: 10px; } #right_side_home td { line-height: 17px; margin: 0 0 5px 0; padding: 10px 0 15px 7px display: table-cell; border-spacing: 2px 2px; vertical-align: middle; text-align: left; border-bottom: 1px solid #EEEEEE; } #right_side_home td h2, a.anchor { font-size: 19px; font-weight: bold; color: #3E93D5; } #right_side_home td.indexkey { border-bottom: none; } #right_side_home li { list-style-position: inside; valign: middle; } TD.indexkey { background-color: #e8eef2; font-size : 12px; font-weight : bold; padding-right : 10px; padding-top : 2px; padding-left : 10px; padding-bottom : 2px; margin-left : 0px; margin-right : 0px; margin-top : 2px; margin-bottom : 2px; border : 1px solid #CCCCCC; } TD.indexvalue { background-color: #e8eef2; font-style : italic; font-size : 12px; padding-right : 10px; padding-top : 2px; padding-left : 10px; padding-bottom : 2px; margin-left : 0px; margin-right : 0px; margin-top : 2px; margin-bottom : 2px; border : 1px solid #CCCCCC; } TR.memlist { background-color: #f0f0f0; } .mdescLeft { padding: 0px 8px 4px 8px; font-size: 80%; font-style: italic; background-color: #FAFAFA; border-top: 1px none #E0E0E0; border-right: 1px none #E0E0E0; border-bottom: 1px none #E0E0E0; border-left: 1px none #E0E0E0; margin: 0px; } .mdescRight { padding: 0px 8px 4px 8px; font-size: 80%; font-style: italic; background-color: #FAFAFA; border-top: 1px none #E0E0E0; border-right: 1px none #E0E0E0; border-bottom: 1px none #E0E0E0; border-left: 1px none #E0E0E0; margin: 0px; } .memItemLeft { padding: 1px 0px 0px 8px; margin: 4px; border-top-width: 1px; border-right-width: 1px; border-bottom-width: 1px; border-left-width: 1px; border-top-color: #E0E0E0; border-right-color: #E0E0E0; border-bottom-color: #E0E0E0; border-left-color: #E0E0E0; border-top-style: solid; border-right-style: none; border-bottom-style: none; border-left-style: none; background-color: #FAFAFA; font-size: 80%; } .memItemRight { padding: 1px 8px 0px 8px; margin: 4px; border-top-width: 1px; border-right-width: 1px; border-bottom-width: 1px; border-left-width: 1px; border-top-color: #E0E0E0; border-right-color: #E0E0E0; border-bottom-color: #E0E0E0; border-left-color: #E0E0E0; border-top-style: solid; border-right-style: none; border-bottom-style: none; border-left-style: none; background-color: #FAFAFA; font-size: 80%; } .memTemplItemLeft { padding: 1px 0px 0px 8px; margin: 4px; border-top-width: 1px; border-right-width: 1px; border-bottom-width: 1px; border-left-width: 1px; border-top-color: #E0E0E0; border-right-color: #E0E0E0; border-bottom-color: #E0E0E0; border-left-color: #E0E0E0; border-top-style: none; border-right-style: none; border-bottom-style: none; border-left-style: none; background-color: #FAFAFA; font-size: 80%; } .memTemplItemRight { padding: 1px 8px 0px 8px; margin: 4px; border-top-width: 1px; border-right-width: 1px; border-bottom-width: 1px; border-left-width: 1px; border-top-color: #E0E0E0; border-right-color: #E0E0E0; border-bottom-color: #E0E0E0; border-left-color: #E0E0E0; border-top-style: none; border-right-style: none; border-bottom-style: none; border-left-style: none; background-color: #FAFAFA; font-size: 80%; } .memTemplParams { padding: 1px 0px 0px 8px; margin: 4px; border-top-width: 1px; border-right-width: 1px; border-bottom-width: 1px; border-left-width: 1px; border-top-color: #E0E0E0; border-right-color: #E0E0E0; border-bottom-color: #E0E0E0; border-left-color: #E0E0E0; border-top-style: solid; border-right-style: none; border-bottom-style: none; border-left-style: none; color: #606060; background-color: #FAFAFA; font-size: 80%; } code { display: block; width: 100%; border: 1px solid #ccc; background-color: #e8edf3; padding-top: 10px; padding-bottom: 10px; padding-left: 5px; padding-right: 5px; margin-bottom: 10px; margin-top: 10px; } openchange-2.0/doc/doxygen/footer.html000066400000000000000000000016311223057412600200730ustar00rootroot00000000000000
Creative Commons License
Creative Commons Attribution icon Creative Commons Share Alike icon
This content is licensed under the Creative Commons
Attribution ShareAlike License v. 3.0:
http://creativecommons.org/licenses/by-sa/3.0/

openchange-2.0/doc/doxygen/header.html000066400000000000000000000005231223057412600200240ustar00rootroot00000000000000 $projectname $projectnumber API Documentation
openchange-2.0/doc/doxygen/index.html000066400000000000000000000005411223057412600177030ustar00rootroot00000000000000 OpenChange API Documentation

Redirecting you to the OpenChange API documentation overview.

openchange-2.0/doc/doxygen/libmapi-concepts.doxy000066400000000000000000000037421223057412600220520ustar00rootroot00000000000000/** \page mapiconcepts MAPI Concepts

MAPI objects

Almost any MAPI data you access, read or edit is associated with an object. No matter whether you intend to browse mailbox hierarchy, open folders, create tables or access items (messages, appointments, contacts, tasks, notes), you will have to initialize and use MAPI objects: object understanding and manipulation is fundamental. - When developing MAPI clients with Microsoft framework, instantiated objects inherit from parent classes. As a matter of fact, developers know which methods they can apply to objects and we suppose it makes their life easier. - In OpenChange, objects are opaque. They are generic data structures which content is set and accessed through MAPI public functions. Therefore, Linux MAPI developers must know what they are doing. An example of MAPI object manipulation is shown below: \code mapi_object obj_store; [...] mapi_object_init(&obj_store); retval = OpenMsgStore(&obj_store); if (retval != MAPI_E_SUCCESS) { mapi_errstr("OpenMsgStore", GetLastError()); exit (1); } mapi_object_release(&obj_store); \endcode

MAPI Handles

Beyond memory management considerations, understanding MAPI handles role in object manipulation provides a better understanding why mapi_object_release() matters. Handles are temporary identifiers returned by Exchange when you access or create objects on the server. They are used to make reference to a particular object all along its session lifetime. They are stored in unsigned integers, are unique for each object but temporary along MAPI session. Handles are the only links between objects accessed on the client side and efficiently stored on the server side. Although OpenChange MAPI makes handles manipulation transparent for developers, mapi_object_release() frees both the allocated memory for the object on client side, but also releases the object on the server. */ openchange-2.0/doc/doxygen/libmapi-examples.doxy000066400000000000000000000112551223057412600220500ustar00rootroot00000000000000/** \example mapi_sample1.c This example shows a very basic MAPI program, including setup, login, and teardown. The first MAPI library function called is MAPIInitialize(). As its name suggests, this function initializes MAPI library: It creates the MAPI global context, opens the profile database store (database path passed as function parameter) and initialize Samba4 transport layer. This function must be called prior any other MAPI library operations. Once MAPI is initialized, we need to create a connection to Exchange and open MAPI sessions with the user credentials. This is the purpose of MapiLogonEx() which needs to be executed prior doing any effective code. This function takes a pointer on a mapi_session structure, the profile username and an optional password in case you decided to store it outside the profile. In the example above, we retrieve the default profile name from the database using GetDefaultProfile() Note that MapiLogonEx() opens connections to both the EMSMDB and EMSABP store providers. If you intend to interact with a single provider, use MapiLogonProvider() instead. Finally we call MAPIUninitialize() prior to leaving the function. This opaque function will clean up the memory allocated during the session and stored within the global MAPI context. */ /** \example fetchmail.c This example shows how to fetch mail from the server. We initialize MAPI library with the profiles database path, retrieve the default profile name and open connections to both the Exchange message store provider (EMSMDB) and Exchange Address Book provider (EMSABP). \section ex-fetchmail-openstore Open the message store Now we have opened a connection to the Exchange message store provider, we can open the user mailbox store with OpenMsgStore() This function will return a set of pre-defined folder unique IDs (stored on double values) and a \em pointer to the upper object we can access in MAPI hierarchy. \section ex-fetchmail-openinbox Opening the Inbox folder We now open the Inbox folder. Since OpenMsgStore() returns a set of \em common folders identifiers we store in the message store object (obj_store), we can retrieve them using the convenient GetDefaultFolder() function. This function doesn't generate any network traffic, but returns the folder identifier associated with the constant passed as argument (here olFolderInbox). We could have used MAPI tables and GetHierarchyTable() function to find Inbox folder identifier. We would have had to retrieve the Top Information Store hierarchy table, customize the view with PR_FID (Folder ID MAPI property) and PR_DISPLAY_NAME, find the IPM_SUBTREE folder identifier, open it, retrieve the Hierarchy Table, call SetColumns() with PR_FID and finally browse table rows until we found the Inbox folder.folders to store emails within IPM_SUBTREE folder hierarchy. \section ex-fetchmail-retrievecontentstable Retrieve contents table Once the Inbox folder is opened, we can call GetContentsTable() to create the view needed to list all the children objects. In the current example we suppose we will only retrieve IPM.Post objects (emails). \section ex-fetchmail-customview Customizing the MAPI view We now customize the MAPI view and set the columns with the property tags we want to access: PR_FID (Folder Identifier) and PR_MID (Message identifier). MAPI uses unique and permanent identifiers to classify objects. These identifiers are double values (8 bytes) and never change until you move the object to another location. We now enter the last step of the fetching process: - Call QueryPosition() to retrieve the current cursor position in the contents table. The function returns the approximate fractional position with a Numerator and Denominator. Denominator is the total number of rows in the table. - Recursively call QueryRows() with the TBL_ADVANCE flag to fetch table rows. - Iterate through QueryRows results - Retrieve columns values for each row with the convenient find_SPropValue_data() - Open the message given its folder and message ids. - Call GetPropsAll() rather than GetProps() to retrieve all properties associated with a given object - Call one of OpenChange mapidump API function to display nice messages dump on standard output. We finally release mapi objects and clean up the MAPI library before returning */ /** \example fetchappointment.c This example shows how to fetch an appointment from the server. This is very similar to the fetchmail.c example, except two minor changes: - We change the default folder constant from olFolderInbox to olFolderContact so any further operations are performed on a child of the calendar folder. - We use mapidump_appointment() rather than mapidump_message() to dump appointments on standard output. */ openchange-2.0/doc/doxygen/libmapi-mainpage.doxy000066400000000000000000000072171223057412600220160ustar00rootroot00000000000000/** \mainpage Opening Exchange to a wider world

OpenChange Project Goals

The OpenChange Project aims to provide a portable Open Source implementation of Microsoft Exchange Server and Exchange protocols. Exchange is a groupware server designed to work with Microsoft Outlook, and providing features such as a messaging server, shared calendars, contact databases, public folders, notes and tasks. The OpenChange project has three goals: - To provide a library for interoperability with Exchange protocols, and to assist implementors to use this to create groupware that interoperates with both Exchange and other OpenChange-based software. - To provide an alternative to Microsoft Exchange Server which uses native Exchange protocols and provides exactly equivalent functionality when viewed from Microsoft Outlook clients. - To develop a body of knowledge about the most popular groupware protocols in use commercially today in order to promote development of a documented and unencumbered standard, with all the benefits that standards bring.

MAPI Overview

MAPI is the glue between Exchange and Outlook, but a common misconception is to consider it as a network protocol. MAPI, an acronym for Messaging Application Programming Interface, refers to a proprietary set of function call interfaces developed by Microsoft before Microsoft Exchange existed. By purchasing licenses to Microsoft's proprietary and Windows-only MAPI libraries, anyone can create message services that communicate using these functions. A mail server implemented in this way is what Microsoft calls a MAPI Service Provider. Any protocol could be used as a transport for these MAPI communications. When Microsoft Exchange 5.5 was developed in 1997, the decision was taken to create a proprietary transport protocol for MAPI which closely matches the MAPI calling interface. This protocol is called ExchangeRPC and used in Outlook-Exchange communications. ExchangeRPC is the only transport OpenChange supports, and in practice is the only transport of interest today. Most of the world is being forced to use Microsoft Exchange servers, so that defines the transport that matters. When OpenChange team members first looked at the network network traffic these generated by calling MAPI functions on Windows operating systems, we noticed blobs of data first either compressed or obfuscated, then encapsulated by an RPC transport protocol function (EMSMDB) and finally pushed on the wire. Transporting memory-image blobs on the wire is not good protocol design, however for a number of reasons the result now works quite reliably.

Looking at a MAPI Conversation

A high-level view of a MAPI conversation follows. We also introduce important terminology: - MAPI applications call MAPI providers, using the API to pass data (eg a mail message body) or MAPI conversation requests and responses (eg 'search for this address'). - MAPI providers pack the client or server MAPI information in a blob. There are only two really important providers, one for data destined for what is somewhat strangely termed the Message Store (although it handles more than just messages), and the other for data to be sent to the Address Book. These are called the EMSMDB and EMSABP providers, respectively. - ExchangeRPC protocol is used to transport the MAPI information over the wire, encapsulating inside it one of two MAPI-specific protocols: the EMSMDB Message Store Protocol, or the NSPI Addressbook Protocol. - The store provider on the server side associated with the protocol used (either EMSMDB or EMSABP) extracts the MAPI blob from RPC protocol functions, analyzes its content and performs operations embedded within it. */ openchange-2.0/doc/doxygen/pictures/000077500000000000000000000000001223057412600175445ustar00rootroot00000000000000openchange-2.0/doc/doxygen/pictures/24px-Cc-by_white.svg.png000066400000000000000000000053061223057412600240040ustar00rootroot00000000000000‰PNG  IHDR°çá»bKGDÿÿÿÿÿÿ X÷Ü pHYsHHFÉk> IDATXýXmP”U¾vˆeY pW$gQH–%ãËc*$åÃIkFmiØ‘ttrê‡C öa3 Œc†D$ e¬±X, «@³ Â.Èîõþy›uÓ÷·÷úóÌœçÜϹîëºçÜç<þxHØNÛNÛN½+zWô®.–_,¿X|»æÛ5ß® Q†(C`4F#p×ý®û]w@qRqRqðÿÎÿ;ÿcaÇÂŽIÅIÅIÅ@˜$L&Ämâ6qÛòÀ‡Ä-í-í--ùVë[­oµ’ <. … ¡B¨øSRT(*’’IŽ$‡”æHs¤9¤S’S’S‰ð>°Ï÷ˆôˆôˆ$Óôiú4=Ù2Ú2Ú2JZ•V¥Uù`^‚û9À3<Ã3À7ýßôÓl?Ø~°¸ªºªºªœ‡œ‡œ‡€ 6Øpx&õ™ÔgR0—0—0ÀMá¦pSB©P*”–õ–õ–õ@²GÙ£šª›ª›ª¦mMÛš¶#êõˆðj÷j÷jöeïËÞ— äÎäÎäÎÒ^i¯´÷að£ýȳégÓϦ“K{–ö,í±+¦êRu©ºÈŠÎŠÎŠNòöÔí©ÛSë£sñsñsñd{^{^{™u%ëJÖÒÅÛÅÛÅ›IER‘”ÔìÕìÕì%ÇSÇSÇS~gAuuu¤|µ|µ|5)øJð•à+rGËŽ–-äÀ±cÇþs‚å)ËS–§ÈÒ-¥[J·ž»=w{î&µ‚ZA-™÷BÞ y/³£³£³£‹$psäæÈÍR•¨JT%ÚßñýŽïw|OšÌ&³Éü¿'þWX­ÖFòÔ“§ž<õ$é6â6â6Bºæ»æ»æ“ÕÕÕ÷&°Ÿû¹Ÿ<”p(áP‚xxQxQxyëÀ­·üóÄÿŠùçœÿ‘Ô®Ô®Ô®´óŠx.⹈çÈÁÎÁÎÁN7ŽÜ8rã¹æÙ5Ï®y–tŠwŠwŠ'+++ÿÿÄÿŠã€qÀH¿üzðë¤(H$ "‹4Eš" ) ø0àÀ:³ñÌÆ3··7à é é  pNwNwN¦º¦º¦º€ZS­©Ö\K¹–r-èÎíÎíΆg†g†gOgOgOgÀ˜bL1¦õâzq½XÒ·¤oI SÊ”2%033TÿQýGõ€h§h§h'àëëkßdÜÜÝÜÝ܉sç&Î õ õ õÀ¸iÜ4n°uÕÖU[WÙ-*4š ©õ^^^r¹Ãr‡å¤S•S•SéêêJºMºMºM’»rwåîÊ%ûûûIE¤"RIîÙ¼góžÍäÜÆ¹sÉý'öŸØ‚”'Êå‰dÛ–¶-m[îï„N£Óè4¤ÇÛo{¼MŠä"¹HN {]z]z]Ñ:Ñ:Ñ:@¥T)UÊE¶Û!q¸k¾k¾k2e™²LÐÛÛ ¤½Ÿö~ÚûÀ¥ÉK“—&ÿVÿVÿV c.c.c¨­­Ê®•]+»œK>—|.ˆÔDj"5@[t[t[4 _ª_ª_ºpýÕΫW;>Y>Y>Y€õwëïÖ߈§ÄSâ)R'‰“Ä‘Í7›o6ß\¨€Ál0̤¼SÞ)ï$ƒR‚R‚RÈ—3_Î|9“ô³øYü,dÒ¤I7H‹ŸÅÏâGöÕôÕôÕAùAùAù¤Ä 1H dÈùó!çɲÀ²À²@R\".—Å?ÿTüÓÂõïîîÈ(×(×(W{Åç:æ:æ:¡£ÐQèˆÒDi¢´E:žAª U L©§ÔSj`$a$a$pLvLvL†¶mÚ VVV~‰~‰~‰À®_wýºëWÀrÄrÄrÈPf(3”ÀóåÏ—?_|ôÉGŸ|ô ·!nC܆E–o4 šQ¨(Tj*ŠÅŠb`V2+™•o‹·Å{±– ‚€5Ôj Ò­éÖt+P¡þBý ðzáõÂë@÷+ݯt¿èôú{x`c`c`#à~Úý´ûi À` °K>_òù’ϵ«ÚUí È5r\³È!2Ï–g˦ççÃïy}9úrôe»%%×K®—\_¤„ú }†>R!UHRò1ŸÇ|ó!ãZãZãZIe´2ZM.»³ìβ;d{{{¿=¾á†7Þ =.x\ð¸@Ö)ë”uJ²¥­¥­¥\öȲG–=B~œúqêÇ‹z²{²{²Iß}¾û|÷ÝSBª¯U_«¾¶'ÔTßTßTÌý6÷ÛÜoöqéyéyéyàÅÒK_,ÔoªßT¿ xj=µžZ F#‘'kOÖž¬B2B2B2ìñò+ò+ò+ÀK›^ÚôÒ&@Þ!ïw2³Ì,3¿Düñ  ($ ÉBt't't'€Á̓›7+›V6­lÐÜÜL>ŠGñ(Hï×¼_ó~¼úóÕŸ¯þ|5¬a iK±¥ØRH[€-À@Ú²mÙ¶l’{¸‡{þ¦#íænî&mkmkmkIÆ1Žq$ýéOÒ*° ¬Òö¥íKÛ—ö°™’™’™2ùpòáäÃvås r r H˜½Ì^f/r[Ö¶¬mYö Y]Y]Y]¤ùóæþávû7¨\W¹®r)žψgHŸ­>[}¶’º]‰®äžÃ\K]K]KéuÉë’×%Rü©øSñ§di|i|i#FQ`$c¼b¼b¼ÈŽ‹;.Þ_€^êg3f3f3Èʵ•k+×’êUêUêU¤Ãr‡åËIÇq'=4 ¹~lýØú12*+*+*‹ŒÍÍÍ'Ueª2Uéû®ï»¾ï’!!!v¥W„­[FjõZ½VO' ' '<ØÁ‡þ+ñ'†††È¢²¢²¢22\® ב2™ƒÌNèAOßbßbßb2Ç%Ç%Ç…ÔéuzžœŸŸx>ÿ^5¡–ü+^:tEXtComment Created with Inkscape (http://www.inkscape.org/) ã+ldIEND®B`‚openchange-2.0/doc/doxygen/pictures/24px-Cc-sa_white.svg.png000066400000000000000000000053061223057412600237750ustar00rootroot00000000000000‰PNG  IHDR°çá»bKGDÿÿÿÿÿÿ X÷Ü pHYsHHFÉk> IDATXÕX}LÓW>¿ ´–.Ôb±‚" Cèê(lS„9ÉuN&n ʹŒ,+&+™“à&3[a`Ë$™ãs‰3Ö¨L(ŠX¸Åñá¬EÄ4ElK¡åyÿy÷–¼µ/¾çŸ›ÜsŸsžûœÓ{· þmô”¶ðà?¬Y3²†èBý…ú õD—7\ÞpyÑpâpâp"‘Ñh4DóÏÌ?3ÿ QPmPmP-QØoa¿…ýFw"îDÜ ¢ŒÊŒÊŒJ¢8n7ŽKäwÃï†ß§eCDxJ3›ŠMÅÀgW?»úÙU ‚‰`"€Ä bý#À>Ê>Ê> p ¸Ü€WÀ+àË3–g,Ïèú†¾q¯Ø°%` ===è&tº ÀéŠtE.Í‹ñVœÁœ!ºxçâ‹wˆ>5|jøÔ@Ô#ë‘õȈ|Ç|Ç|Lj^,z±èÅ"¢m»·íÞ¶›(Žljãùùù±x,‹G4;;K499IÔÞÚÞÚÞJÔ¾§}Oû"s‚9Áœ@$4 BQa~a~a>Ñ!Û!Û!o„7Âyš ¬Çz¬ßi|§ñ`ÕЪ¡UCnÅdý²~Y?ÐÔ×Ô×ÔLÍLÍLÍÂGø8¶ãØŽc;ÜÄãËãËãËS‘©ÈTäxÏ®ž]=»€Wv^Ùy´ Z­SÏÔ3õ‹~Ü&¶‰mÄ_‰¿ ;v( 05›šMÍžqÝÎng7P¼¶xmñZwœ—^éõ—^îõÝë»×Ð`é`é`)°áµ ¯mx Xž²äeò2y™'ñA„ B”ØJl%6 nUݪºU€*Z­ŠÄÄÄ“Ïä3€å[Ë·–o½ãq·qØkÝkÝkõl¥ÏÕŸ«?W{Â?~< $®H\‘¸Â½Þg®w®w®—ˆ³Œ³Œ³ŒˆÍÎfgQuQ—§¯È_‘¿"'Ò˜5f™Hë¯õ×úûëØ_Çþ"âïçïçïÿß.ëi=­'ò©õ©õ©õtϧϧϧ{Î3LÓAÄ–²¥l)éHG:"VPePeP%‘ƒëà:¸D³³³ÞóOØ'ìv¢Õ©«SW§åìËÙ—³È,7ËÍr"G…£ÂQá?—7—7—G4ùóäÏ“?{ú\WÀõœ_P-¨TDÖxk¼5~‘ckçÖέî’TýQõGÕÞ;à|Öù¬óY@ÀÉ€“'Þ:Þ:Þ:@œ&N§cccÞñÝ‚nA·ý$úIô“;/š?ÍŸtƒºAÝN¡¡ü¡ü¡| ¤0¤0¤pQë}RôIÑ'¯³¾ÎúpŒ9ÆO 2Z3Z3ZÄŒ9s㇓w%ïJ޴ŶŶÅwDwDwDÀÅ÷/¾ñ}`Ëw[¾Ûò'îÍóožó<`}×ú®õ]ϼgfÏÌž™XZ––¥Ö¶¯m_ÛP‡¤CÒ!$ ~ø!ÐógÏŸ=zW²V]«®Uœ:N§n¡(Š¢(À?Ê?Ê? Í Í Íxž…gñ$ê u…º€®³]g»Îzæ±UÙªlU€¼D^"/Yto¨ Ôj€ìB»Ð.ö(ö(ö(Ü ýŠ~E?`ï²wÙ»<;„¡ChÞм¡y±D,ë 7ò¬V +Ø”»)wS.pI}I}Ií]¨æèæèæhÀÏægó³Á™Á™Á™€¾J_¥¯Zô1§Óê´:- ¼"¼"¼ø}ï÷½ß÷@uJuJu àZp-¸<8wþîü0ì7ì7ìJ5¥šR ùwæß™ÛÓ·§oOÞî|»óíNà”ñ”ñ”ý–ý€~@Äì‹Ù³Ï-@qqq?° ].HmÀ5åšrMǧOŸXm¬6V°²deÉÊàtÆéŒÓ€óWç¯Î_½'F ZÐ8ßs¾ç|˜+Ÿ+Ÿ+\®W€ILbÒ;ü¦ô¦ô¦ØÜ°¹asƒ›xÒñ¤ãIÇñeãËÆ—¹×{¼   ¥F©QjV:+•ð[ø-ü@=®W÷ÎÝ;wïÜÒ„–2[Ž-Ç–4O7O7O76nlt—<”<”<zózózó<ñ^ßÄ–dK²%PVVx¾<_ž/À\b.1—I¶$[’ |Éÿ’ÿ%Ðwê;õÀdÅdÅd` ³†YÃk‹µÅÚÌlÙ:³>0|`øP¯®W׫ù«òWå¯Ü:n·`ŒŒ‘1IÂ$a’è½Ð{¡÷‚w–|Ô;ö:ö:öÍÏ7?ßü<šš øˆ}Ä>b€4¤!   P(ØÉØÉØI Q‘¨HTÉG’$d5²Y r2ädÈIÀçŸ|^p+½&nMÜš8 x x xß1¾c|ÇÒ|ê%þ±±gÇž{(¯)¯)¯âõñúx=àÃ÷áûð—>…þC*C*C*N§€èôúÀ™âLq¦<=ŸYΧюéÈ:tEXtComment Created with Inkscape (http://www.inkscape.org/) ã+ldIEND®B`‚openchange-2.0/doc/doxygen/pictures/CC_SomeRightsReserved.png000066400000000000000000000064521223057412600244120ustar00rootroot00000000000000‰PNG  IHDRZ¬a x pHYs  šœtIMEÕ ÌIðbKGDÿÿÿ ½§“ ·IDATx^í™iŒUEÇû¾{ßÚÝ6ë"²Š‚@!`˜DÇ¡Ä "Œ2 ×%Æ(ê—D£ñƒ1¨â’Œ@Pƒ¢HezXš¦é†¶~¯ßrç÷ïÜêyV¼ 1í„VòçÔz«þuêÔ¹÷9%¿Nr@$Bd\ºP¤Ç¤KˆÒ•HD€’È|² È h‘,Ò›= lœ)Ò›Íøí´2$Ù"ír«,n¤…˜Õ?À+B¸4d¤à `d‘ž—Þ†vL‘_‰h×&By#Äl ,‹OHIÚyû¤Ø°N‡¤g¡èäÒùnÑ‹0 g­Kë!í i6IÁ¶dËŠ…‚bÉFÝ?Ÿ-ÚŠ°áÙ–eÈO&“‰gŸ}vä–-[¦œ8qâŽ\.7çÌ™3Ó÷ìÙ3áý÷ß¿büøñÝdÉňÅb©Ç{lÐ÷ßÿ‡ãÇÏ ÏÜæææ¿8p`ÎòåË+§L™ÒËz– {®ƒö½´Ú?Å­cݦ[e‰â²áÇw]¶lÙ´¾}ûBfxrçfÞ_|±»bÅŠ!ƒ *ÿ}]xÍÒ’V™OŸï ¤­{–.¸Xrì“O>ù“!yûöí 7ß|óêT*õwÊÖ<óÌ3ûNž<™S]±%Óg˜!yóæÍM7ÞxãÚÒÒÒ¥lÀâW^yeÝéÓ§3ª3Ï q5nHÞÎW‹ŽXVœ ½ÄŒ/¾øâè|p¢Ø·o_ãСC¿J§Ó­‘ˆÁ€Ê>ûì³—^ziµÚÍŸ?¿âÕW_í!}çΧG޹9“ÉüÄZ9%.}*{öì¹ð,–kK»¬p>Z´‰s£[å6\ÉÊÊÊ¡f€—_~ù_±#“½{÷:|ÈlÒ­·ÞÚÁôyþùç Ù³ýð¶mÛÒ¼È ýG2$ïXh—äµ?Ñá °7£OŸ>ÝÍøéc¶»Q+êp±ú˜é³råÊûb³78¶ 1Ë@Îï8ڱɷõb²ñÑqÓøÈ‘#9Ûê‹`ÜI²¢¢¢mîÇŽioŠÉ ß\#C²†óÐu„è>ˆ„µÃU´˜L÷îÝcöÆXäy Ååè›>;wöl²Î‘<'l íî:|ßïÐ^ƒmܸÑûâ‹/R555‰£G&!#ÉÍŸjiiI€$~4‘ÍfS<3U(ù|>!YWW÷Ã%—\ÒScÜvÛm=Þyçã´ñ€ "À´a¤<²y×®]±Ñ£G»êsÓM7¥/^|š0γD"qd©)D£Ñ‚ëº>(ñ<Ï!ïÁD€KÄâ^pÁ^×®]½þýûGG»æšk²í壎hÿ—ì&t¯ºêªDÇŽSç/‰ü1Á DB„Cr²“È/ñï¾û®Ú=oÞ¼Á«V­Ú€•»l‚ ’ýnݺ9o½õVçIˆË}ùå—ˆ.UŸ‡z¨ÓºuëWsvIž€ï/ýõ×õÒò7òˆ|P"‚ãñx+ɉDB$ srª¢½{÷Ž:êtåI¿”§VKqöÆç>8dF°4Y³‡èä©S§â”'xÃK@r\0dƒ¸ÈfÑ©×^{m . \ãa_¸pa͆ 2eee¥×]w]§Ù³gwÁÚ´‘GÔF$}øá‡{õêå)_UUuúÍ7߬ٺuë:uÊOœ8±ãÔ©SB^ ‹ÿ+äf »b3œ¡:@†x= Ùiü~¦C‡é.]º¤ÙØ QN3ýE´c‘z.ût Ñã• 'ôÜwÒœC‡űæ8¯Ã²è˜ˆ†ä¸¬ZRD$Çò²êaX—ûî»od—…ÎÜ÷Kn¸á†ƒÈV]ÀêܧŸ~ºë…^;[Ÿ»îºk‘!¤A‹ò\ÂÑ­`#Óll Va61­S`Nz8ܧžzêrë±Ñ%amŠÛâE`)$¤°ž$H±¨V“ÿMqEJÒYd î¯]»¶™§Øƒÿ›P¨¯¯ÏàN¾ñÆGñë9Ú°´zvÍš5M¸™,㔀ˆéÓØØxŠ7ÌÚ?þx#d·@bIyy¹ƒŒX¯ "Pç"=ê$]¤GY4„#Ût›3ÆG;ç°3þ9„>>ĉ´$DuAZ ×!b£" –%G%!$J[å¥{HwQ © ô­KQÒEF°´¶èEV òëׯo¤_=$çØì2+ g±È,® Ɔ—°yÅ £ e¾Ñ6/ÊI?%&)’€hî£ëtt´^~ä}‘Œlõ딹ä[A>á’Q ’uZZ@–òlȧÒPÂmiÝ1”àp_ä‡í¤Êb<‘*²Ñ•$[‰ HÑ’Ê»"2% Éå!URd;"8€X³’¤A„ä—ä{$‘/QˆDIr³Áüäzb¤2«r…ƒg#ÖÒC91á]…UîôIaÖl„N^£+ŽÕÊÛˆ’Fò’&/˜ÐN1´¤±nG©Øª€acÝH§ØºE0R¹²æ"Œ/=t?´¡`.ÄšM:«±àDæÎ;ž[ÎsÏ=7’ ©O¿~ýoûh#Øåy›6mêÅGšÞ¯{T¦~Lêµ½þúë')o±^N})Ÿ9ï Þüî»ï*ÔJ¦HcÇŽ­ä¢Ià³Ëˆ›¯ tÅÇû¡„V1.¢èôéÓ/G÷„Ûo¿}0Ò%Vî?cÆŒA?üpß%K–t&Bé‡/¯Ï&JP[éJÖ¼ûþùç=xNœ‹-~íµ×þž—¡±<çwšÃK/½4Œ²Ê÷Þ{oëÓúèÞξ¥s eKu¤¦M›¶öJW;AþLõÒ L×°Œpn¹üŸ1WCBšèá«Ã‡¯¡,W]]ý-ñmý#zTܨêŠ]ª)ã›ù)Þ./“.‹Þüõ×_ïâm*Ë—³²œÊ£ó Ü|°wÑ¢E²¦¶zŽHžÎ°ÓÊÛàRÛ*ÿ©yŽì¼*^`ªd‘¼Ììfü<ñî>\×q^:²lÈA¬þ ãØ"H¯­­=Ì‹Pý ’K—.=¦·?Œ¢^yÕ ¤Z¾›R‘Ìiiâ µ«Ý¯2æšÁ5œàÌ.>­V3FÒªpaÛ5Oꛃµl1ëÓéxüñÇkUÆÿ’UãÆ;‰;Ép¯l ã@ÙŠèý úÉ'Ÿlš5kÖIÞós¼Å€”ê=zäT/BL;£•W Ê[¨D*ǹŽ;@ãÖæRúa&œƒ˜zȯg¬ßEØ€£ÒqeÇ8ÒÒ% I—ظ33gÎLKW½ú©þ»‰gæÉ7˜ñ±ò:=bk™GíO%ƒŽñ}CãÙQQ mEõLŽzÏÌ«LÏ4m!ÚçBup›)½ä´­Å¬¿ÃÊÇá.è7±ÏÅáCŒÏDýÝ»wûJøÈVië,ºµíœ9s|;Ùí¹©}.Ÿ”aŒ>dû,ÆçHZ}Btk¾çöL{®öv}ø8Òq¡¡˜²!C†ø&Lðq]¾DÿÊé7üFôÿÿj|w‚%&IEND®B`‚openchange-2.0/doc/doxygen/pictures/body_top_bg2.jpg000066400000000000000000000006541223057412600226240ustar00rootroot00000000000000ÿØÿàJFIFddÿìDuckydÿîAdobedÀÿÛ„ÿÀ–ÿÄh að¡q‘QáR’¢ð!‘1aQÿÚ ?Ô¢±Õœ|W¼ í|ua³Dbe­‚hŒ*ø VÁ&ÅrV¹´,¸^Â-~TbÁÐéÊ—=©xj䮤*ÿRb²r %7L‘ñÜŠ¶5ø¦ èªÞV¶ ÿÙopenchange-2.0/doc/doxygen/pictures/header.jpg000066400000000000000000002264161223057412600215110ustar00rootroot00000000000000ÿØÿàJFIFddÿìDuckydÿîAdobedÀÿÛ„ÿÀÍ4ÿÄû     a!Qqð1A‘¡¢d ±"Ô%U•ÕV–Ö”WÑñ#EÁá2DT·BR3C$uµ&g(8x’S£³4…6¦hbc¤´Å†G§)   !1AQq"“ÓT”ÔUa2‘¡Ò#³´u6±BRVÁÑb²3$v'7ðár&ñ‚’¢CS%Âsƒ£4Dct¤5ef(ÿÚ ?ýAîÊåSñMÁÙB8v)¸;(GÅ7eáØ¦àì¡;Ü”#‡b›ƒ²„pìSpvPŽŠnÊñMÁÙB8v)¸;(GÅ7eáØ¦àì¡;Ü”#‡b›ƒ²„pìSpvPŽŠnÊñMÁÙB8v)¸;(GÅ7eáØ¦àì¡;Ü”#‡b›ƒ²„pìSpvPŽŠnÊñMÁÙB8v)¸;(GÅ7eáØ¦àì¡;Ü”#‡b›ƒ²„pìSpvPŽŠnÊñMÁÙB8v)¸;(GÅ7eáØ¦àì¡;Ü”#‡b›ƒ²„pìSpvPŽŠnÊñMÁÙB8v)¸;(GÅ7eáØ¦àì¡;Ü”#‡b›ƒ²„pìSpvPŽŠnÊñMÁÙB8v)¸;(GÅ7eáØ¦àì¡;Ü”#‡b›ƒ²„pìSpvPŽŠnÊñMÁÙB8v)¸;(GÅ7eáØ¦àì¡;Ü”#‡b›ƒ²„pìSpvPŽŠnÊñMÁÙB8v)¸;(GÅ7eáØ¦àì¡;Ü”#‡b›ƒ²„pìSpvPŽŠnÊñMÁÙB8v)¸;(GÅ7eáØ¦àì¡;Ü”#‡b›ƒ²„pìSpvPŽŠnÊñMÁÙB8v)¸;(GÅ7eáØ¦àì¡;Ü”#‡b›ƒ²„pìSpvPŽŠnÊñMÁÙB8v)¸;(GÅ7eáØ¦àì¡;Ü”#‡b›ƒ²„pìSpvPŽŠnÊñMÁÙB8v)¸;(GÅ7eáØ¦àì¡;Ü”#‡b›ƒ²„pì__gÓâ£êE~•²O\VݪÏãžà…·#÷Á?Nž•cÏ´Ôô™Û£¾!àÞÖ²x¬.c;s÷<%Íåå+ÝÁ’¾ºckO¦‹£Êcq0}ç)sµµi®W¶6׳SÈpo× 'ü߯Wí¬?þ«[7ð¿™áÜï¨]ù¥‚øócûëëvþqkúß„ÿ›øÇñå­õ¥?á2ÿùßP»óHøócûçëpyůëvþoc/Ç–¿Ö”¿†Ëÿç=BëÍ#ãÍïœW­Áçýn¿ÍÜeøî×úÒá‡2¿Ã¹ÏPºóIüy²=óŠõ¸<â×õ· 7qŸã»_ëJ?†Êÿç=BëÍ#㽑ïœW­ÁçýlÂÿÍÌiøê×úÒ—ðÇ™?áÜç¨]y¤|w²=óŠõ¸<â×õ¯ ÿ6ñ§ã«cë:?†<Êÿç=BëÍ#㽑ïœW­Áç¿­XcùµÛYÑü1æOø{9ê^iì|â½n8§ëNþlãoÇ6ÏÖt ¹“þÎzךGÇ{#ß8¯[ƒÎ-Z0×óg~8¶~³£øeÌðösÔn¼Ò>:Ù>ùÅzÜqkúφÿ›ßñųõ/áŸ2?ÃÙ¿QºóHøëdûçëpyÅ?Y°à÷²¾8üom}gGðË™áìߨÝy¤þ:Ù>ùÅzÔqkú͇šøãñ½µõ•Ã>d‡³~£uæ‘ñÖÉ÷Î+Ö óŠ~²áßæ¶9ümm}eGðϘÿáìߨÝy¤|u²}óŠõ¨<â×õ“5q×ãkoë*_ÃNcÿ‡ó~£uæ‘ñÎÊ÷Æ+Ö ó‹_ÖiìÏ{âýj8µýVÅÌ›ñtÃéy…îÏ©\ù´|o³=ï‹õ¨<⟪¸°{Ù&Äü]ðú?‡<Â÷gÔ®|Ú>6Ù¾÷ÆzÔqkú©‹™/âØ‡Ñü9æ¸s>¥sæÑñ¶Í÷¾3Ö ó‹_ÕL[üDZÀü>á×0}Ùõ+Ÿ6ŸÆÛ7ÞøÏZƒÎ)ú§‹¿˜ö7âȇÑü:æ¸s>¥sæÑñ¶Í÷¾3Ö ó‹_Õ,_üƱ¿A|:—ðï˜âÌz•Ï›GÆÛ7ÞøÏZƒÎ-Tq€÷²-Ž?þë‚øuþ`{‹1êW>mìß{ã=j8§ê†1þbYŠà¾Gðï˜âÌz•Ï›GÆ»;ÞøÏZƒÎ-Sñ—óÈüUðê?‡{ÿÜYR¹óhø×g{ßëPyÅ?Sñ—óÉüUðê_ÃÍÿî,Ç©\ù´þ5ÙÞöÆzÌqkúŒÿ˜VWâ˜?‡Qü<ßþâÌzÏ›GÆ»;ÞØÏYƒÎ-Sq ÷²•ø¦á´w÷¸³§sæÑñ®Î÷¶3Ö`óŠ~¦c_æ —ø¢á´w÷¸³§sæÑñ¦Î÷¶3Öaó‹_Ô¼müÀ²ÿB|6áîþ÷cÔî|Ú>4ÙþöÆzÌ>qOÔ¬müÀ³?Â|6—ð÷{/êw>mlÿ{c=fËZþ¤ã¿öoâx_†Ñü>ß¾ãËúÏ›GÆ›?ÞØÏY‡òÔýIǬßÄп £ø}¿}Ç—õ;Ÿ66½±¾³å­R1ÏßÛ;ñ4/Ã(þoßqåýNçÍ£ãMŸïlo¬Ãùk_Ô|s÷öÎüK ðÊ_Ãýûî<¿©Üù´þ3ÙþöÆúÌ?–§ê6:ûùgþ%†øeÃýùî<¿©Üy´|g´=íõ˜-kúŽþýÙÿ‰a¾Gðÿ~{“/êwmí{c}fËSõýû´?Cü2€7ß¹2þ§qæÑñžÐ÷¶7Öaüµ¯ê&<ûõh~$‡øe/€7ß¹2Þ§qæÑñžÐ÷®7Öaüµ?Pñïß«Gñ?Ã)ü¾ýÉ—õ;6Œö‡½q¾³å­Pñ÷ß›GñGÂé|¾ýÉ–õ;6Œ¶‡½q¾³å©ú…¾üZ_ˆâ>GÀ;ïÜ™oS¸óiüe´}ëõ˜-kúƒþüZ_ˆ¢>GÀ;ëÜ™oS¸ói|e´}ëõ˜-OÔ÷ÞÓüEðº_ï¯re½Rãͧñ–Ñ÷®7Öaüµ¯ê÷ÚÓüCðº>ß>åËz¥Ç›GÆ[GÞ¸ßY‡òÔû`ýöµ?Äü.€·×¹2Þ©qæÑñ–Ñ÷®7Öaüµ¯Ûëï­©ø‚'át|¾}Ë–õK6Œv½q¾³å©öúÂûëjþ ‰øUoŸrå½RãÍ£ã£ï\o¬Ãùk_·¶ßKWñW¨ø |û—-ê—mízã}fËSíå‡÷ÒÖú~+áT¾ßåÊú¥Ç›GÆ;KÞ¸ïY‡òÖ¿o,?¾–·Óñ_ £à=ñî\¯ª\y´|c´½ëŽõ˜-O·v'ß;_éø¯…Qð&ø÷.WÕ.<Ú>1Ú^õÇzÌ?–µûwbýòµþŸ‹øUïrå}RãͧñŽÒ÷®;Öaüµ>ÝX¿|­§¢þGÀ{ãܹ_T¸óhøÇi{×ë0þZŸn¬o¾6ÇÓÑ £àMñî\¯ª\y´|a´½ëŽõ˜-köæÆûãl}=ðª>ÞþåÊú¥Ç›GÆOÞ˜ïY‡òÔûqcýð¶~ŒøM/7¿¹²¾©qæÑñ†Ò÷¦;Öaüµ¯Û‹ï…³ôìgÂhø{û›+ê—mm?zc½fËSíÅ‘÷ÂÙúv3á4| ½ýÍ•õK6Œ6Ÿ½1Þ³å©öÞÈûßm}9ðš>ÞÞæÊú¥Ç›GÆOÞ˜ïY‡òÔûodýï¶¾œŒøMïose}Rãͣ㠧ïLw¬Ãùk_¶ÖOÞëkéÈÏ„Ñð.÷÷6WÕ.<Ú>/Ú~ôÇzÄ?–§Ûk+ïu·ôÜoÂhø{{›+ê—mm?zc½fËZýµ²¾÷[MÆü&w·¹²¾©qæÑñ~Ó÷¦;Ö!üµ>ÚÙ_{m¿¦ã~Kàmíîl¯ª\y´þ/Ú~ôÇzÄ?–§Û[/ïm¹ôÜoÂhø{{›)ê—m/Œ6Ÿ½1Þ±å©öÒËûÛn}7ðš>ÞÞæÊz¥Ç›GÆOÞ˜ïY‡òÔûieýí·>›øMoose=Rãͣ㠧ïLw¬Ãùj}´²þöÛŸMÆü&··¹²ž©qæÑñ†Ó÷¦;Öaüµ>ÚY{mϦã~GÀÛÛÜÙOT¸óhøÃiûÓë0þZŸm,¿½¶çÓq¿ £àmíîl§ª\y´|a´ýéŽõ˜-O¶–_ÞÛsé¸ß„Ñð6ö÷6SÕ.<Ú>0Ú~ôÇzÌ?–§ÛK/ïm¹ôÜoÂhø{{›)ê—mm?zc½fËSí¥—÷¶Üún7á4| ½½Í”õK6Œ6Ÿ½1Þ³å©öÒËûÛn}7ðš>ÞÞæÊz¥Ç›GÆOÞ˜ïY‡òÔûieýí·>›øMoose=Rãͣ㠧ïLw¬Ãùj}´²þöÛŸMÆü&··¹²ž©qæÑñ†Ó÷¦;Öaüµ>ÚY{mϦã~GÀÛÛÜÙOT¸óhøÃiûÓë0þZŸm,¿½¶çÓq¿ £àmíîl§ª\y´|a´ýéŽõ˜-O¶–_ÞÛsé¸ß„Ñð6ö÷6SÕ.<Ú>0Ú~ôÇzÌ?–§ÛK/ïm¹ôÜoÂhø{{›)ê—mm?zc½fËSí¥—÷¶Üún7á4| ½½Í”õK6Œ6Ÿ½1Þ³å©öÒËûÛn}7ðš>ÞÞæÊz¥Ç›GÆOÞ˜ïY‡òÔûieýí·>›øMoose=Rãͣ㠧ïLw¬Ãùj}´²þöÛŸMÆü&··¹²ž©qæÑñ†Ó÷¦;ÖaüµÈ[.Õâ)8há'(,™Ed"©,’¥¦ªJLEP‚Sˆ¡ZÜðMk;í®ctw1¼µìp-s\ÓG5Í4-sH ‚P¬ô3Eqn-Þ×Àö‡5Í!ÍsH¨s\ AÄ/£³éñWÔ¹+ô©Ùôø¨ú‘_¥bï¼JÆàXññ‰¶•Èeƒ‹\D[G2NJ&CC6*ä1ORöêÜ 6¾ñÈîKÞsS,û«×> §hð'•¿jGÐ8A<‹H/u†–ð«‚ònió6Û`ãÛ«Y.á¸i10ý–7£½xtÖ¡£†§Æ€¯oL…xäi¥® Òᑸ$Ö1÷T|¹Ì‹DÎmïFhV±í?䤉˜sk_§[khmÍn'mYÃidÐ*Ðò8j‘ÿjGž·<—Õð¶sqf·-ó²9ˉn.[ƒýV7ì±£©­.( uV|µb*”ë©ÓDꔪmÓÜþŠ’;SªPS¸)P& PSn½=ú’ÔU()ÕRZª©ANº)Õ)UÛã¤GjuJ wM`¥*›u÷jKSªPSnÞ*’ÔꔨÓN…UL íñÒ¢uJU:½ÊšR‚}‹SªR©·ÇPZR‚•ORuLUzüƒJ©Õ)TÛ§Oz•N©ANà¨-L ¦Ýj UU)Tê÷*t”ÁL XRN½‰J¦Þ¡¥¤'T §UAjuJ uÔ§T¥So½SBª©AOëè¤{Mºûµ%¡:¥*›t©-N©AJ‚ÔꔪmñÒ¡N©ANò…MªR©×ÑH´& R©¶ µ:¥*KU”Û¯MMN©ANò…*'T §^ЩÒR‚›jKSªPS¸* S)TÛ®Á©¥ª@S¤<´“ª`S¯¢•uH m©-N©@üõ©‚ªsPÔ–§T §pRâR‚›u¥@RU%©Õ(yõ©-Nªà~ª’ÔꔚŠQ:¤ŸNš<)Õ()J€§T€}µ%©×ëH)Õ 9ô©-N©ãÓSDU 9ôé¥Ç­:¤ÒàSW…-)Ô¤=Iju€~z)ñWs I¨ª@?8x©S±5p?0ÿM.=iÔ¤ÑÀ£‚¸)Q:•p5M¨ëWÒÒŸ\ SBŠö«„<4¨ª¸<5:SVs .!UÀÂT'^Õp?pQNÄS±\ J‰ÔŽ•®´¨Š…`0ôÒ¢t À`è¥E4ZÒIkB¡ P…(B”!J¥R„)B¡ P…(B”!J¥R„,®Áw ¹f"Éc “8±K^ð$Óþ@è§_›ûç÷Û1ûVïôò/»¶‡îž/öu·èX²?³îÒµo¶/À§gÝ¥…~pxš»e®Üõ•K¹2ÇŒ½ni57fÞ*Ù”u‚D¦ÑL}4ÞPÆ0òˆ×ì?%0V.U` Ç°5³ãmî^zÝ-ÌMžGÒ|g+ÐÐ@ ó{š[¼¶ÿÊËxíF+é hêÀ÷DÀ;õ*ꔪXTÐ'TÅSn¾íIjuJ mÒ¤µ:¥* SªR©·]ƒJŠª”é(TÒ©Õ0)×ÑRZR•Mµ%©Õ()ÕÑQ¥:¥:È4¨R•M½CR@N½©ANà¤ZR•MºÔ§T¥SnžåAjª¦:ú)'T ¦ßMuJ uR-N©ANº‚ÔꔪsžçôT–§T §pT¦bR©·Çߥ@R‚U%©Õ()×PZª© §0éÝâ©-N©ANà¥Å:¥*›|u4ªPSª‘jª¥6ëPZRU%©Õ((=54¢uH mÓ¦—…:¥óÒ =ª@?0Ô–ªªP?=N”ê§æ¡¨-N©Nz\SªPSn½Þ:\:ÐKObuHÛRZ~¤€~z’ÔêÌ:ôÔ–§T€~~JT#¡4…?0ëKÂ{RéR½¯b@?0÷tT{UÀýu%©×±\ ú "ª@8ôÔiNªàpè飈OÀ4¸u¢½ªàz(Ÿ ¦‰×µ\4ˆ@§R¸<<•:S©Væ’;Sª¸|<´´¦®})P„+†•{Sª¸Žà¬ (Ž#¡_ZTOWjÔ˜iQ>[{ž•¢¶ 4’¢Ö’JP…(B”!J¥R„)BYðÒ–¨<;ï\ùU0ø«ó{|þûf?jÝþžE÷vÐýÒÅþζý `ö;<•«T-‹þÝ*v;<”T#þÝ+ò•ŸÍ»žshkÞ˹$4—”Í~Öò¨Êý·ûú¤+óü÷šý­yúÄ‹©€ýU¾­N©@ýu%©Õ )·J‚Ôêš'T ¦Ý;¼TxSJçÿMRuH mê’Ôê”çä©-N© ¦Ýj Sªû™6y éQí\½xàà›v¬ÐUË•Ô0èTÑAUNo×ÒÇfYÜÖBÑR礞[ùÀ\ãÐOàYKcðožïTÐr[IKyŠú®n5>/W³0”@bRªø ©Ã@2e 5¯7ÌókcaÜcuÛg¿Õ‹ÇãÙ«ƒz»|+mÆì}Ë“ðÛ=±ž5p§¯Â<+¸à2è†dçn„ƒEÛ ©XGª)¦.I¯½Qs ”1¬Tļ¢<•ªÅÎìMäÝÕ•»ŠHÔáS@]Ð:*ÐOJÊͰo,ÁûãÈ¡¡£M:iÓÆ´<;*¶ÙÚ±)ÿçƒÒ¡È.b„©ïhôÆn7Cx{ýí9DC½]«~k™Èÿtiû2Ÿý=«„íá;ª[H‚ºÆàá®àˆrá«Y¦.\ šJKº ²b²~Žå#%5KCrD `Ö¶+`cîãl¯ŠFÆâE{(iÄ#¾#¤®ÆÔž²F—Ž®Úñ ‘кVn͹mÓÆQª‘0HGEÐäå×}=t^PïVÝi—ÇÞÌH5£À¬Î6ö׌Œ%½£ˆ\dëò dhB©MºtÒ-N½©AJ‚Õ@¥*›u©-N©J§UM uL uÒ N©J¦ßIjuJ uT–§T §]AjuJU6éîTЧUÚ¸kßÛ!@ã\{Y†uSˆ(º‚Þ6&9¸’S÷TôH¸Ô5:§C‰¦E9mcwîÌ&ÈÀO¸óòì UïyàÈão Oyà8¹Å­pÎíͽ”Ý9x°¸vk¼”õš5iï=MhâOz ˆÖ»—†ogg1QŒø¯ÉÒWîF~Å'«Ú±on&†äû@ûfÃ2sñQ«†".å¤IÈ”D‚AÔ…ùœÝçŸ3ndŸ—0ã¶ûZٞ؜ziãKr oxà\Èb%WIú5ü¹åNÆ…‘o[¹/sh&6:FýXà!íiè–@Ò)Ð>7{,ø·]K/dIÜQ“Ý$¸Á@Ê>ºAÓåÐ)tôxlŒåó[°¦L¦TÌã%Sz ”ÇÌ„8î¹—üÃr茖òµ¶ÊàZGxö²?ÿÕ¬0ž€,.Ž´q* ØüšÞ€Ùm©æÇåÈ:]!$ô'.véŽPúTðy¡Ä>¿¸gÉ1ÖAj¨dFFÛ¸˜‚ƒ v@¨±ÑBZ)UCDÅ7 ”ÑfËJmJ$9þ¢å÷0°ÆÁ37„qkÓ,N§y ”©cÀémxñ^Þ"†­ ¼6n_ee‹Ê4MQÈß±++@æ“Äv9§‹OŠÒÅWn½5½P­N©J§W”)Pê˜ëè©-N© ¦ßAjuL TéUT¥W¯È54N©J¦Ý:{Ô¨ªPS¸*KSªb©·Z‚ÔêªuTé)Õ0+Éà%Mz=íá×pÛgá«´ÓW×ùçK4iy•¥Pc¢­Çˆz*j¦@o¢²Šk¦º€‡5|ÏÉ.iîmñ—ËÙn7Àè,û¾ëDa‡Æ|­5 šðcWºsO``¶¦7u…l¢[}æ·—±‘N8¸¯9ÐpUS*…C ×ÒbŽ ÃÏB¾S®‘j*”ªsžçôTé)Õ0)ýaI0{•Mºûµ:BuJ uT–§T §]AjuHU6øêtªª`S«hRER•Mºû´¨ª@Sn•%ªª”¨-N©AM¾:)Õ()Ïã ”ÁìJU6ëîÒ N©ANªE©Õ )×PZR‚›t÷?¢¤µ:¤9ùv…M uJU6õ / uJ sÒÓØRù†¤µ:¤÷AjuJ >½5:Sª@Sª—ÒúépER–”궤µ:ýJàpè©-N©@ãÏ­AjuWõyiP§T qç×ËK‚jàz4ö'^Ä€na©!íHç©-M\ Ì:TRÇÃËS¥5p8séÓKˆN©ãGpëWÒ¢~p7pR!:ö«Ç¦¤µp8R¡N¥\ >©#µ:«ù§Jjà`ðÒ⬢½©×µ\ÝÞ¢ÀÛ|tQB¶´¨ž¥`0ÔÑ>[{ž•¢×]hIkI%(B”!J¥Y‰Ã"Zµt:wݸý!¼5ù½¾}³µnÿX‘}Ý´?tñ³­¿BŘ½vµª­NÇ»Z¿%œB˜ Ÿów´Ì90QRxÔt.¸ÁÔ`9p¬rU¶ªö/»BRòŽ¥3 cx¥þ€¾ÁtW}ÔM‘À;…[Bþ׬ý+L=Áµïß##™Ä WéT•Ã%0z«uœ1lªNY±lGGP§Uºí[z:E1A¹;!U° aÐÄÝY[qq]ops^ò@¨TõšÐÖ¾õÃmËZHkšæ´H$)NÒà6tT»uÐ(£¤À@éiÛ4PL'2J”Šö§HU DtÝ0ˆw‚³Ö™››g‡>ˆõô8vŠŠOè\ca˜‹ êêðý…bÍׄ;~áó3e%¸²ÌôìÚÉ•2†Lœ€T]ƒ©Š:r›”¼¡èÍé÷hÃåÖûZÑÕâYôöÓéâ:ºV§}¶ÅËÜÖQ“õ§ÛðýKæ¡¥íÉâæY,Åësn¨ŠÀÈ S¦r “P‡(€Š"^‘ÈYå-ÅÍ“Ãã=#è#¤-òÊæÂcËK_øm¥Sª»ÄÕªPS¯¢¦:¥6øé¢©ANª‚ÕUJ uÔ§T¥Sn”¨Sª`Sú¦0R‚›u÷i§Uï²ù„!ᓉŽ*åcŠòJÜgv¤˜(,6Æ/²P¾d2T¥¦œì”ˆ&¨Q:ŒSäÔ¡¯Â¿Íýæâßø\A!m¤‚'štw×sºÝ®pë1±•o`‘Üx•õw!í-°ÛC/½ef«†wéîíâ8Ø÷:‡´°v/ÎmËv^yÊÿ¹ò ñ0îjáºæžMLÉ:Pç3‡o DŠcfÙ=Ô›¢MA2HR€}7€ÀÚYØÁˆÆF!Æ[FØã`àZ)õ“Òç.q.$’Jð¼¾Zâæê\óÌ—ó¼½î=$Ÿè €€.Ml-ò>bAìTÜCÖ’‘R±Î–g!'ºnØ¿bñ¹ÓpÕë7ID”!Šr bˆl·vÖæÙöÓµ¯†F¹®µÍp!Í ð ƒB ÁÙ¸‚fÏ ‹$cƒšA¡‚è Š‚:è ‰PâCÙ}‰¸ŸœI±¯Ë[BFj]š w/¤n„pýþÙºiãx雼È=ôtôìŲ`<„øƒ–lŸ–œþÈìkg8bî ¬k 'ÅýîÜšô¹ÕšN§µõ>ùt[ã”6[®pÓÅÔh¿îóØ×IGPti‹¯ø<à“ñ¹jôŸ“²îtç®I^ËM‘ ~ß¶­™F.eŸ:Žzvñ‰ŠVúnKÛ® "‰Ì œ¤Ž÷Ìþyo=“̶müD1]â´E¶ýÝd’YXàÆ‡¶¯§{ éhÔà AÔj[•;gtlgfr2Éo¼µÑŒŽ7´¸–š7ìjq $P(­f\ÞÇ®øŒÂѰy I)Gmm˜|Å55|FÛ“So\›йnÖÉǬñÚ…!Vun3Ž(˜ }ÒjjÆå2ßÍ?ýÕ5æ<@Àe}Œq[>HØÑW0àMtù:'‚ïXc¹ y|Üv׆gnß$ÍcÜMá(“®·k;h8¬Aã[†ü%eVV¹dœNØ×“S–Àñ""ùvlÜ‘´œ¿bšMTœ€U ²ˆ”©,ƒ„V$* )ûw'y­mÌý¾ë¹£m¾rÙâ;ˆÚIn¢*Ù#©'»P8’×5í«ƒCå|Êåôû0-£{¦ÅNÒø^áãP9 [ "€‡5ÔÒ3^ßá#†°Ì`ã®beåÃw‘3BbÈG²Ì×AUZðA½¾â2nRàbÐå3õÌõœk%Næ0¦ª¾9›ç/0÷þë¸Ûšd1c- ^ÊÖ8:ŽÓÞVPøÙœ‰¢9&ú©¬ô¼_,önÐÛðçy˜éd¾¸E«öÒ£VŠFZ÷HÑöÝ­‘°5&Žv㋱W³ƒŽÖ'¾pžX‡Šs0Ê"æy5"õÓDTI°É:‰œ»o(yèvΦUÒŽ”jõ 9Na)?ÊÄe¹Ï~U]Ñß²ÍmÉ$ s¢dlš-’(-ßÈK¥‰ñš=~Êå70-ä²ÚͺÆf˜Â懹ï$tUÌ’YšöEC$cÅA<:p7á"¯ÅͷÞ[báºÍò¶eÞÊ9éÛ*ªh$åB:Œ~RýE$á²ÀPíT¦ÓßWÐ;›µÜªºß»RF—ýÀO {A’ÞM$µÍ¯:—Žà¶{›Ì }£¸àß½÷R†šTMZîÇpsM8´ƒÖ½!Íü;{:øC¹Ô›Î7Ï4Òàd̶fŒ›”{qºi);–IHYy±håúG#uWxÁ‘{#¦Qp®¥OæýµÍŽyóÛ­¥½Ä/qžýñ±±Ôš²&6FICH. ŽI A:ÅÞÙœåç*6Uñ»Ï¾âhdhî­÷Òž4Ž,sBꆒö0Pôqۆá~÷⃲Ï[/±›IçÓvÔ¤ÂøšÔ‹Nภf#î‰Yçì¦Fß\ŽX®ÉâV0•1)Äæ2Y]½Í¾gìÎ`ZìÞh¾ »KçÆÖLÆDÂÞõÝÜr1в&º>ðÈÙ#®Pt3<ºØ{›gÜnm„Ù­®m÷:7:GjîÛ­ì{e|ŽÑã1Ìyi45%¸YÁw ’¼[_îa’V ǵڳ–¾nVȦáÓ6VU(Øh¤•Õ›3UÁªIYcN̨©îÙæ¥,öã2"6Üfnœæ[BI sš|#w¦êŽqs u·Ê¹yËû½óšuž³2Ý¡ÓÈHÖ0ßGi'ƒC\â ]™ÕËì…ÃWš˜¢ä¶/ËÞfAX’ø†œ½åb!ä[j“Óɺ‡½­ÖÏÔb࢚¿ź!V)ŠÑð¬~SùÜXѸ­o¬l­¦`’+gÅl×½§‹CCíåsC‡ßLÓJEW¬^cù…½8k‹[«©ãv‰'l“9­pàK‹&Œ:‡î¢p­EEñµÂ±áì\ň®U®ì” ȰRN¥ æ%üÌZ×!“lÙ²2ðif ‰{b‚'"¢aÜQOGäç8o·­ÅÖÖÝ6ÛwØêÖ [#XáÉa$²XÞ@‘ é:mZÝ'™|µµÚðÛç¶ô®ŸmÝÓIqsæ—´jjcÙRÃMB„:¦„ú›Ç$áî÷ǘG#ñ=’ÝØ8Ÿ·|ñìdYŒ”Íó;sCÛ‰CÛ‘«7Aü¢‚bB.u[±j£ÅRÔÄQ¹QbüË}É»0ùÌž/eZ6ç; s¾Ä,òHàK[ýqG=Á€ð!䆟£7¾näñV7û¦àÁ‰´a%­ûR¹íf–4€]ýSPÖ—ÐZ#0¾1öjñŽÎî°8ˆ½1ÎA‚<Ó7Ò·r²Å*현ëx»†íº æbI¼n“´w›¹pP(§¾U ë9®`së–2Úå·eÅžC,¡Žcc€2´'»/ŠdcËC‹ã¶­5¡ióÌ^ÏåûŽã·a¹²ËG ç>RêT a²K+Ð⇊î<¨#ÍÜ]‚®|ÄppÞ.›F\ñ÷½Éh\²eIWlⳓ žU$ñI7i ¹ÛÆH®ɾMð0}5œæ>'Ëçó5ÒX›H¦Š:†¹îœ0E6Dâ¢7Ë èZݿˡ´ð1fùŽé$½¸%³ Å*+¢‘–½Ïí¸½‘°5&ŽwÛŒñÏ³ëŒÆSvŸÊ^x(ÄŹ—gq:—~ñËDTI¸È8‹™º.Ø™¸–îI„“g‰Êcn—¿ŠÊs¼±ºŠÿy¾Ï/·ä1α°jtµñÃãyé2Dö=û ʽùo%žØmÎ72Æ4=Ïq#¢¥¯–V½ ‘PÉñÓÀ/0o[js_V<º›•Ëg̼„–nCï¢+µ>‰ºj ”¢»íÌEÐS@íP¦Ó–¾ªÛÙìvæÃÛæñŽÕes^Úð –¸u9¦­pêp#©|û™ÃÞà²Sb¯Û¦ê NŠŽ±Ú(ZzÁl`¦ÚÌ–¬]R‚œõ%©Õ()·ÇQ¥:ö¥:B’uJU:éP'T€¦Ú’Ôꔩ-N©J¦Þ¡¨-N½©N%*ÁìJU6ëJƒ­:¤ÒÒRÇŸü5©×êHŽŠ’Ôê”×SDêŠ\zÓª@S®•骯֔5¨¨W‡EIjª¤MN”U :)qN©ýt¸&iN¥ ˜ÃRZЏž§J¤€na©#µWóù*tö&¥Ät§Up?=Á )iOR¸•¨ëWMN”ü à`šUX !ÞD'Up?8xªt¦®÷tR⮢½©×µ\E;AÔ¬ÛJˆ© ÚÒ¢u Àaé¥Dè ¶ðtR¢TZÒIkBJP…š¼/¥«%ÇNû•‡Æq¯ÍÝóûí˜ý«wúyÝÛC÷Oû:Ûô,Y•Øì%jËbS±Ø>J¿"E›wˆLî^AÓ2äðñ^ó•ûmÊ^Ví¯ØÿÕ!_˜;üÿçÌßí{ÏÖ$]:}+}-Z•RǦ¤µ:«ÃŸü%©Ô¥¦ˆª@Sª—…4 §_»Jƒ©:¤íÓ`÷iRZV}p'ÁܧײÒÓÈ®ÏYÎP5Èü¦;aœúBË'E(™.Ñí^*MN‹}ºBxo;9³mËl3ml‹_¹®Ú{–ô÷lè38uÐðŒwO}?–{ãzd4˜{r †´ÖãÄF ¥^EHoG ýOÚöE³í˜èf­áã3lÕ„dB ƢѓtÀ­Ù7*'A"9@‚0ˆˆ˜F¿2²yœŽw%%õã-ËÞ\çÈKËœOð$ý<P_qãñVx‹&ZÛ€ÈÚÐX@ph Ãô®•ÉR™mÙ26oÌòÎÑ(n¬¼œ˜,Î(«€êº†kG*ûýGUÓ7€+rÛØ·ºÍ×Ré&~†ž ÆQϧPÔâÆðþˇjÕ³™Xb¼À†²&kpë/}ZÀGI£Cÿ¬Ò°Ç%ܳnÓ21Ò±=ªÄIwÒë‘è"©€‡8™ER€a0ê¥{ÙÆØDðû¸åš€ÈÅ\HãØkà^G¹2ykÚEc¦8I£žç^.  óÿ(Ý ­rN¾É¬u’¹&ÞÛwMQh“.™"£[î.ýu”Mªc¨¡¸Q(W¿m«ëo ¾)ú#·´p:µW¼Ô4P¸öñ5â¼Ö÷\×ËutÇÈ纮0=”#WWàà†œ´KÙ踟ï`3¦poܧïùDp»dÞ †ºŽœºÖjò×--Ö±i`ÁÒ5½ 9ÞÑoÜÚ>wÿ…ßåqY ¶Ü1•Ní’Id M !8©Í®ø€¬fG\ᨓRh™€6W}˜Ü–÷‹8ÍGK$‡€8¯ŠNšÐ[pxtU®ÿ%h¹ 2|ù ‹†Ï $S1;6ÇRHñŽVLM¡Š²R̘$s¦ è Bòë aß·¬ -’9¢ãSâêÿêýwºmÙïƒ8}`E£Ì„I¢Ý\q²úìÝ©K²ìǹ0ªŸ`C9ng ©ÄNQÓPä÷_û”[²FØÊÉcpã¸8pã@hïĹMûæ{ ÃÇ´ý¡Ðxý ò}|Çr LfØ”O(Bo71Duôg €ª¡˜,n›C å/½ÔµÖÁenðwBXxÛ»í0žŸiÄ~?É’³·ÊÀbž‚Aö\:ùâüKß³{õÄ|ƒu¼j ¦»u‹¸¡  Aï”ä1G¼bˆr {¥…í¾JÕ·VƱ»ñ°¼²öÎk ƒo8£‡AíD/œê®ÑjëU()×Q¥:¥*›¢•;SªPS¸)P'T ¦Ýz{õ%©Õ()ÕRZR‚u{ª÷¯ÙâÑ,ÙÀ/ü>D™²—‹är<\{E쀆É8ÑË>AÁÌ©@¡ö–Ðj;©P u÷ÚüüȶM³Î]¿¼gÔ1Õ¹.¥xÚܹÓ4pÿåHÃÛãpê_[òL³9Ë<ÆÚ‹I¾×0èž¶'?üÆ?èñWçfÄh´y2|ÕvR Ü.Ñë7h¨ÝÛGm”2.9n±Hª¬A)ÈpÀ !¨WÙûxÅ-³fˆ‡FáPAx‚àAA æ\À’9Ìr״Ђ(A ƒÐGEe‚~A­ˆµaj½Ã⥠`¯bõ¥.Â:äÈ XL££]ê›Ôeî\¨læá’ÈDÉ8a àªû¢‘ɸmÈ?Ÿ8‹¶oæƒ!ŸÆ%…£æ«ÛöK!µÀõ‡<´‚:A¨à¾ÃÉ[»mòÓ| .îzC¥œÝ–‘ÔZÀA Š+®1r˰Ë35š†”›O|†›q\‘f$¡@@wN™Ä¦ð€ˆ%wwHÕüÍãôxÿV™upœ‹¾#ÿœÿÓļ&³­”ݲ (mý7ŠmD SwÀ@C”š¾ÅÆâÙ45“Bù²úùÑËFp¢ý5ûDÈÒköÌZõ;ɼã¢îWoÑ2¾.¸S±~ÖíŒ$]B®ªd3„ùNB€è:WÁ¢ž|]Îõn ‘XÛ“iñkœECÑÀWIì%}qÌh¢¿‡kœˆ«ä½ƒYpãG÷]åGÓýaô.Sí0K€ÙKóEñ…‘rÝ©6ÖÒ‘weDج¥œA­þdèÊ?]V6eƈJ.ò94Õ(¬C(¤"@ÉË®hZbo?‡ö¶ZÉrÑ3¦-ÖÖx­ã4g@$p"®w¡‘æ]¾Ã¸È[|a=ÜS²Ûqn’ïðþ1-ñè à±ÝþÈ^²E©—1ÞdÎ-î«AÃLJ’†¹]±pœŒcØyrMÇmtÍät‚©œ€¡@Ú€€€ z~æÆÿ0[³>/Ä}ÃZ¥ñ‡.kÚæ“rêæ‚ ÑpwÜÛÙx²øë숼„’ÝLyiÔÒÒŠ‚ ¨\<3Î(ÏÞÖü;‘ð¼Ë‰ÛRåb¡&ýÔ ½¼à×$”#¤Ög2Ý£¥Ìœdk0*À˜ÄС¨F²X=Áµ?—ì¾ÞÜ1ˆî¢†rÖ‡¶A¡ò5â…„ã9ü+ZÔõ®•ÎW¸9ÃŽÌáž_o$‘T–¹‡[X暇OŠÆ”¥RèÏlC5$xî’ne cðï€Íé„<&0HÖoùq·3òþ޾Oþ°X¾uÊ"Þ»¯îÑAYí쮈J/„þ.Ûwˆ»YU Aå&ñ±¼± ;£ÉïŠPç­+ù‘´m¦ÿÛa.kOÿÔµm’¸7C6]ÐïÐ9|>ÉiGÐüqauÛÂb^Q.¯ã]62‚ûÒ qRrvà©(UP”t±’î˜Nch:€içémï16å…ÿ,ˆ8³GÝi“§‡µ ×…]ÞPƒk³3Wvœ/Cä Žš²Þ¬ü&ŸI_Ÿ»NK…Êï_ª¢¦UCœçPÂsÆ0˜Æ1¨˜Æ0ê"<µö>6Ä]÷ý•óMõ×p4·¥väܦF‘†´Þ_פ¥è£jI]í¨Ï@ID|_éò±l½ LD»4‹ÙÂÐB¸Û´qVye,­mã¿}uJØØÙ¨ÕÚžjEMOÒ©Û‹!sdÛ ©æ}›i¦7=ŧF’Z(:(8ìo¶ù¹Åœ!·ÝÞ`1m»DD»Ã§6£_.±w»ƒ<ÞºÅúI×Óé~Œ>%ÝT“ýH—KûíÔc8Ÿrô£ª‡Äwzb#Ìy›HÃå-zó-bÛ~YE(ûG%ÿòæZ#®Ý6ú’>¡c/úñ.«šÆ¹+4{I³¾5Æ2Î`®lÍ’VáIëèä-Ø6’O×™–xò8Åv›dQp²„D=òY »¹ð›K“69ÃgÇEŽ·¤E­y–G5¡Œk]âÔº†§ì€^x4®žk”Ü\Í»Æažb½’öjÈ šÀI{‰oƒíÒVReLìÔáÊèq Ä~XËÙ¿0¦Vn.¸¸‡ÎÌf«,͹Ð+ÂÆ‘bÌ«Q!ÊÙÜ뇤DH"A Ÿá÷G:wͰÈìü~7¶Ü\!t€P€ã]:«®†£S-ÚÂkÖ Ü2XWíIÍ–ä¼¾ÈfÀëXMA R´¦ž:]3œ:¨³G‡Ù~dø,â¹Ï öíßmY¨Z¹H—[Åg‹¾^ç.'2‚ᩞÎÏœ|TfåÐ o”Þ÷Â>[½­÷Õ·1°mß“ÚÏ’ïmŒfDzè4Ž?V£ÐxSŠß¶´ÛN}•–;F+ˆ¬»¹ÃĤ’_Ütнü4Ó¬q¯†žÃÇÊ<½3ha0’Æ€ÓQ×ûý@ÿzŸó9!~×ÄWÓ$ý^Ȇgò4ôf®¼\,¦/«½G*œà7,àŽñ„DDej"""""5ôvß²ûŬZº;¦ª‰æn»›‰4ô÷Žþ’½ÈâíG{$¸lTLvW.4d™À¤&˜Cß Z§¢e!Dl ®š›wQ—¶” ´þb³‘EÀ5·ë/…Çð’Oô/{Ürºã’¸©$âI„~Êâr^1ÞšÞöGpôÚÜt¢,nìI¢·Ð©»<­¨þè–nçt€BÝHAðŠ©ˆˆ÷ñ›I.ÿ˜,ÕÅà­Är_ÒelL#ÿÁáÿ„•ÞÝlm¿'1pÛBöZê êÒ8ÿ„/ð]¨Ý{ç=Xw• ÞÑT{ûÅŸ7ø+ëL¶9ŽÛ7Ò;í}Îcÿå¹|뎽ss¶‘·£ïQýö¯_½¥ ãd=¡Çͤƒ’m£æwÈeSø­Þe‘o 'H c(ODTú”DÁÉ_'rV[›~Xn›:ýé‚åÌ¡§ŽÛ0[Ç«8¯¡ù£oÜ,4û»ŒßøMÉüUYíOéçFqi2­¯4…ªýÍe4•^hÇ“ #$ùc²´n &³¶)¦¨v¤?bŠZ“MÑ+”—<ɵÅÝü mc-«î%tÅ¡úšÏ¼eaÒ‰«Ç¥mƃcÜd-þ-žî9Ù îÛqn’ïðãQ Ç 7‚Å,5uû(pFAµò­ƒ—s;{žÓ]Úñlj¸2pœ„kÈ—Í$£`5QËGlª™È Ž÷ €€W¤n,w=÷FlWŠ6€¥ñ‡.ii7ÐA¡ZN÷”˜ ¬Yl}î@]ÂM55妭- $OZÂÞ2óÖ6Î\UÜYH8•´ç-ËE³™'1p‹»šˆˆJ%ÙÖe,Ù«½äZ³A >àÄL4×JõžJás›[jEƒÎ´2ê9¥!¡Íx {Ë… IIq¥zJó®idñ[ƒpÉ–Ä»U»âŒ–’æ·I¨p€tu.´M]JQäå½Öœ*¼’©ÁMºt÷©Sµ:¥;‚–”êªm©-N©ANà¨-N©AMºô÷êhBuJU:½Ê^ê”î T¡:¤*›jKSªPSž µ:¥6øûµ©-N©N~J\SªR©·_v¦:¤…"Ôê”ë©-N©áÑRZRǦ¢”èN©MºtÑáN©@ô¨BuHz’Ôê5%©×± 9ô©-N©ãÓSNÄêútÒãÖŠ¤.4€p¤ZO… yêKS¨W‡†§J|UÀÜÃRB*Î*TìM\Ì4¸õ§T€z8pW…"©Wm©¢ujà~zZS⮩¡EUÀÂjhª¸<4´¦®Ì4¸„T…`8ÑÁ:޵p?pQDS±\ J‰ÔŽ•®´¨Š‚¬šTN[x)QM Ξ’ÞTy×T|f~noŸßlÇí[¿ÓȾîÚºx¿ÙÖß¡bÌþÃg+V[†Ï P…øòâDÛ¼EgÀïfœ¦+æt+öã•þVí¯øú¤+òû˜ÿ>fëï{ÏÖ$]2 sÖýÅj5ìHæ(ð§áH륧±:¤ó›¤µ:¤óù* Sª@>Þïr¤µ:ýk|·â\sQp1ÉŠ¯e^ É¹wL`®p&ù€ #¸™DLm<5׺¸ŽÒÝ÷SEK€ ®{x]q3`í8Óþÿ©~½¸c¶m<€l{R%©A`fÔæj‰H‹éiyUP;éG‚)˜ÅŽÕ/h±À@‰ ]wJZü§æmþSzoÛì•Ë¿4á¨ñk#`!¬oê´4t¸’zI_kòÎêô!‚6Öáò¸5ƒq$ç“@]C@Sä̾ò,î—q:„CxöÏdSh†úG~f(è"(]¦gæD†ß16ð€—NÿÚÚ1]†²(4’9¬.r²„A² Z‹xÖ¨¨‚@& •c2”yké¼&ÏÅ lÎ2Û‰mÚÐØèàÀI5{ˆ'ñEI¯Bð»ýÁw5ç} od‡\ƯBå¾ø»ØÙᑈ,¤&Š´ÖÊÖ£¨=‡Æað·ƒ\åéÍñ‚}Ÿ|vÎHæŒÄu·„rMÒ'•¾lëŒ!˜ªöy]Õ_ÊLcÙùËfU„Ë•Œb=‹xâ-ÒÚ®PYS(ªß+í~`s’¬nÙÜøI²¸H˜dŒ¿ÅgCZˈ㕎`Y¬l!-h o¾ç¶.yœóœÁe#Çå%ñ¤cÃx»¤—B÷ÆàãÐç±åŽ>7ŒI.ú¬n¸áMã<«Äo–J=ºdåáìÆ*¡õû1:ÈKBvﺯpEt@ÄA""Øç ÕÓQ1ŽSp󧛼ǵ~ÜØ›zëà²K‡¹ík¸Løà†Þ Ð¸—<,s]B±ønXòëeNÜÖìÌ[ß>È@hipâ+_,“PŠ€4´žp^RûB¸ã–ã{*C#n°‘€Ä6½ic@?:a ùËó ·dúmŽ«rJÊ¢I¤N©¶LSçXêz7(yW/±N‚W6|ýÑk®%h:@mtE4:RKˆî$hn—Ì]ÿ.ñÈ £k¢Ä[‚!cˆÔkö¤}8juÑ@I.'Øþ -Ì?5즻í|ù>½§‰¦nKª&î¹›8]¢öñdnË}¬4ÂnjøŒuÄ«EDë"«RupQC´ ðŽqKŸÆsþÞãkÄ'ÎÃi⌀CôÃ!{%µÕx !Ü|BEë¶}Ê ¡ÏHbÄÉq+^ðH,¬Œ u@4£ôž ·ûCMWGbÿfß6 ÊÊû¾8Î÷¦ ‚]ŒÉ´˜¶#]\°È,ÅÊK£xHÄ·Žv‰®»AYGd"u d÷‹¿æzÝàßÁmœ¾î™† òÙØžE ØÎå¯/oÖ¿KXhçíVß“›^ß*ܶ[;e.݉ÂBÐX×HÐjçw¥¡§€qmK…CCIa?´ßXÎ*3ÅšÏ?yúk…SxÚɸ‹ˆç—<“Èçs—s6Ë$Ýã&<+$b•`M¯l%LVɳrW•÷;3oÌÌës™";*#¡Á’ kG½ÒiWiÁ¡ÇÍ ùæËÆìSœ1V@ˆŸBÒ÷’ ¤€@ñZ7Uu£mãÂoµg XæXÊþâ{£Ú4}8´\r K=lÙ¥ÀŒ#i×ñ,¯.êYšO=³ä¥#WE=MÙ‘Auä'nïÞAn»›¬MŒÙ]“tî†8è–k,kŒ3D f·0Ç &‚¤hôoï£ÍÜù¸ñû¦Òí#Æ è-Dò´5Áì q :øîໃn fÍüFñ#‰2ª6ÜdÉmË »;rZ6QÛ¶.cÌämG2÷<å(FNŒ-š¢Ð‰´rb®e³)Ë—ÜÜÉæ2웵v> !tÏg{rçH×4Nô2&BÍCÆ{žKÛVDv dlítwéËYÞÚîîÖ88E{²é+¨|V†€×QÄð¨Á¼1±®BöÙyµ¬Ÿ…±²¹5høÓý´-›J؇V.%WjH¸÷o’hW/TÞìý-ÁÀ`Ý0úÎghe1|“¾Û }ÎW<,ð$šY¥|šÜ©Ik+¡¢ …ç˜ÍÇaÍ\뙆 Ý´†’ÈãŠ6³H.#KM58ôjqâQ{Q/Ë'!ñ¹%qãûÆÖ¾­ÓØV3"OY× MÏ wº#¶…”„vù‰œ¶1€Lß ˆoW_ùyÄåpÛ*,ŵť躘˜æñ<áBXð×Põqê\ÜäÈØd÷D—XÙḵ6ñøÞÙP F¦’*:ÅVsû^4,ÕR¶)7Ì™€5ŽšO 6îàÂçóRæ¬o,ã™Ñh3Ã$Aô’btÐê ¥hí[O83X|¦2îÚåñ‰5ˆ¥d…µd`j qÓRM:bàþË;öÈǹùiûþòµlhÆ7;›¼n‹f _8”¶TA˜IMÓü=bÛÙ;%ÀàÞ$l$Ϋ7s ưMIM[7ŸN!¼Ûئ7ms(Ñ7`ųääã–@‚cd8ºÕ€ÞüÝ78«)r{6åßÔÔ|@If²Æ¸Å4`–ks rh*@fÀ2ûWšø È]Ga¹àÖ ñ¨ô‡‰#}5iax]ÇpÿÜ"p…*¦fâˆ\Y“’·c¥ËoÙ5·å#¤Ý:dᜠ°æVã‘»¤ˆÍÑ…»dš\‰V2ƒÙ”ÅÊî>aï¾bÙ·llÌ%ýƒ¥{;Û‡:F¹ êw‘²ÔxÎ/%í«CF¢C ³6–˹9íÏ•´»µÚ! cƒ‰WAsÝ#¨|V†€×QÄðªò+äÛ[2çÛ!Ú6\=…mMH »iÂFEIJˆ„‹bÖ*8ª³‡nÞ<²O[²/0‹¥”ÐÆ.ƒ_Jl Ûwkˆ¼¸’òþ&ög¹Î/‘Î.u Év–“¥•㤠€W†ï Äy¬¼ù+hYmg#†ˆšÐÖ4¶¡  D N§õ‰¡_I¡J +Òx-¼S•M´‹Sª@S«¢ µ0R‚SBªPSn=ÚR¢uJ sÒÓØR‚›j SªPS«¢¤µ:¥:êhSªPSn4¼)Õ()S§±:¤*›jKSªP?pT–ª!TÛ¯MM(Š¥:B—UJ uôTÐU m"Ôëõ¤õÔ§T€}ºwxªKSªP??’¦‡©:¤9† uJ¥@zª@?0Ô–§^Ô€z‚ÔëØÌ:l©-N©üþJTìM ˜{¿ÃKÂRùéP„+Þ‘ju)ãRZGR¸<5:Sª@8óëRZUÀüü”¨GB¹†•{S¯j¸ŠŽ ÁJŠªUÀÚxjHEB¸ž§J|UÀÀ=á¥DUX !¶¦5p8tR¡M\n´ªBu*àq£‚8+‚Š"ŠÀ4¨Hé^€p¨–ôY‡Nú‡-~lï¯ß|Ïí[¿Ö$_víÝ<_ìëoбfŸa³ÍÕ–ÅE; žhЊ/Ưæâ?ˆ÷´Í¹X9Ê@ óßi¯jòÙºšàÖ88p=-5 ±c,bg5„jèýÔ¾»ûÓa¥ÎÉP;£2@ñŽÖ*B¡Šæu"V]Crœ„\ŒÊp×@=«¨î¬>ðâwSJöþ4¯"– ‚+¡ßˆ…ÆmÉå‘I2ª·ìÙ9;6.Ö§!¸Š.C³n¡{6ŽJEH"tôï×ýÕ£".–Hõ4ëP=‡á}*íY+ŸÝèêtp¡èãÕÒ»ÊÖ™›R5{_ Ã9go$±¤XJLöq-Ù–& #£ó¤ìL@Ý¢(”ÞQéËZ®FLtÒ6ç 7nÚM#¡Ôé¥WJÊÛÃsLw -ŒW¦€Ôq¨·BÜ®kË5«3p–½’íV(*ÝTõåÝ:'ÿ(w‡–·,LϹ°c¥¾+‡ao¢e mµóÚÏönñ‡€ÿßTeSmd V:©ANzšꔪm×§»Z\ª@S«Ê´Õ:¥:ú*KS)TÛPZUÄÀr‰L€†ƒPYQCШ8Ž ®/iµ~aU0ÜPyuAÖ°×xˆç:›Ò²vùÅâž…°Èpcn™c‰5ïj=êÆÿqÉÐOÜþôe*ªæp–ÓXÀ@Êœ£§~²v˜¸­øÓŠèÜ_¾nKÙhŒ­‹{³>1ÉV ~F–•”<^?{xÛ­oyÔÈV{ÔÔaj/"Iç„;6Ê*›s¤™Œô¢!òùÛ[‚oæZÇ9…ã°M‚0ë‘ ¦‘o3H3÷`‚@¡wI¤¯£¶¦o$.ñR]Û7*é^D&V H3FA—k5Ÿ³Ð ê^Û–¢®™B(bƒQ¯¦¬q/’M%xeÞA¬’…v,¨„z€²žýNþ¦åk5iŠd[ºV.ã éF‘з‰ˆ²‰èb†ø èÏwŽå´ë\V÷„Ô.2À;€±û=ÉäÒ°ÇúÒ§JÉz7¦œW5‡·[Æ¢bœÁ ˆÖNÛÈJq]ï_3«Ôí¤Q~/ü¡6õq·ÖÍÞõÕS¯œè»µ¿ÊGI° ~PÐÉ]‹›a‹¹9›¾wÎ&m­¶våõ´÷mÝãô±Üʘ¢da¬säuK†HpÛ0{iíLŒYüînÒx­Ý®6 ÔáÅ®á$Ž~“ã1µÔ©ÌŽ3øoŧY&«¶Öd$Te‹bñ;7ÊZ°¤^' ñóeff%Þ½Gß GLÂ& ˆû_(ö<»'nɸ-vAï3N[Å¢G†‚ÐzÃÖ2¿Ö-$p+Ëyº£Ý9™r0‚Û6°G<¡¤Hê.sœêuCкÆRÜm,Ô…P ƒ§.µí· ¸`í/,†íð¾ ð\8,ÀÛ€±û-{ÚòiX¿îgÖ•:Wûͧ«ŠçöõºÞºŸNQQÖ²V¶ ·+£qvé…ÌJ§Uw WV©ANòR¢uJ mêT Õ()RZR‚›u¨-N©J¦Ý*KSªPS¯¢¦…:¥*›z†•uJ uT–§T ¦ÝjKSªR©ÕPZª©AN¾ŠT(ªB©·¨iP'T §=NžÄê”ÛÝîÔ–§T€~®Š‚ÕUJ Á©¥T ¦Ý)xUU()J€ô"©û{½Ê’ÕUHç©-ERüÃÔ5%ªª”çòTТ©NaÖ—´ÒéiìN½‰@üÃRZ{UÀüõ%©Õ ˜zªKSª@??’•èM!OÌ4¼)Õ •èE{ù†‘ ×µ zjKS±\$ê=5%¡:«Ã¢•M yéxQ^Õp=¯B~p7w†¦‰Ôõ«‡ŸÇH„pêWóÔéOЏ0Ò¢*®-Nš¸:)P„Õ€iU:•èÏ ÉoC”t0¯Íõûï™ý«wúÄ‹îí¡û§‹ýmú,Úì6y+U[†Ï%_‹Ž' »Ä§¥æÎ9d•%¨ª@8ôÔéNªàpèé¤ZRƦ‰Ô,ºÀ²ní“°s’®î¹†êFYé²Px9 7mÓ‘¼£9)D·vÑ&{ÅÉu= ¢D5Ò÷;,ïíÍ•ûÚÌcf¸ÿã2&6ÿhx²½Òqš;£Q![Ö"9mìc’÷Ť´ÿd¸ŸÂ;Òõbâ¾,¢ZSØ®Š!bÏ02“nc·`÷ã çOdä]H¹xåc‚Š*(î Óå•,ðÙÙ3po9|Y¥¿ûόǚ½º"kXƱ­hZÝU¡è[ìw°Eg&66-ˆGÀôõ¹Î$’I4&€à±êÊOcI+fÁô)ËÊžJBkµŠX±æ`Ì¢éI4gÔC&]æL"";Îç¾›rn(ò¹ímŠ2ØéÝ3V³À¸¹ÏwŠ ñkAÂu1ï8ëSmdiª¤“ýcBßM+Ú±[+ÚºÅUäD¢AA“täRNc³ª›ÄXÇ•”I”jMÑÞÞß2¯x“—~Âgv´÷ÝÙŠéÒ-% 7‡M$þ%‡¼°»kìãÓÇ£²µXH³"Oª¢· ÈѲ+˪V+Ò©DD=ñ‰p£aŠ;½ü3Õ±ZÈ!¦¯u‰‰%•¥¢wzš½»v´”ÈÊ”aíkqÂÅ“¶žÄ¤Ôc6…AÊŽ»PÊw5Ð4Þ×½ÉZ”ù˜ÍÀö[#ƒZ$ÔÒãSð,£E§Ü¦kÞtpâ8žž¥Æ®; 2¶mEfßM̵E»øÒ¼·n¨¶äUÂnÜ<1 Ýx¥ÌàSéÈ`(ià¬Ø›q\Êö°C¨#[xPtb½œ+ÿ¦·ûnH\Y¸b ÙÂÛ±³íˆ`Ý%ÎÌW v…)ŠþN4‚`å×R‰uõsœniÃSîŸÓý ªeÍ›>Í»^>’» ƒf~›Þ"Ù´4pDníf—fRM3iƒ„‚8tÔG”G¾нÆI+÷‹«‡šIOÔ?Ì»L¿ Å ÞÊT­W:Ü-´½¸ª×1m§O"Z,»¸›RÊ¡'èm½<ȶ(ɦAtQT8{”+·q6RÙß’{~Ûº*hhMkÙõ®Åíëû÷ËÓV´ô V”!b¬­ÓsK¨ç³ÌkªíMÙ€öZÖháqђﺆÝ'€qúÇêXæß]HÆ»¾&¿WÔ¶ÛžàNï4¡4ÂnNÉùݱtäȱ"ï cvÀ€:Q@ß05åÛ]KhÙ÷'21¡Ìs™ÑNƒÃ¢Ÿ÷.Ôã/‰.i wOhãÓÚ»/¸{öpÌž÷¢ä´ASDª·UC¹HÔGû$Êp&¥8sVW÷eþ½ø¨íô,&ᎌ†N±©§ê5 °ANºÎÐ-f©M¾>í)§T ~%AjuìJ s IjuH TЧTÀ§]*êÛ§¹Hµ:¥÷AjuJU9†¤µ:¥*hSªÙeâ“•(úò t/,Ûr(WnÚäÀVáÌ‘È%ä »ka4Ž…3Ìev¢·Sú¹ËW R•Mµªª”ê©¡N©AN¿%*'T ¦ßN”ꔩ-N©J¦Ýj SªR©·Or¤‚SŸÖ¨R•M¾:E©Õ()ÕPZª©ANº‚ÔꔪmñÔЧTÀ§WE*ÁJU:Ý©-N©J¦Ý*KSªPS¸*4§UµËF!*€¤§. <¾}Úê\Ú¶áš\»\:T.¾=‚ A5L ˆ÷€G½­`Ý…p4i:VU¹0EHâ¹½k¶ˆþÓ@2Ÿí‡”u®ý¦5–ü¬º—7¯›‡Rç%S@Ъ²«¥T §UN’R‚äTN©A]¾:šê˜ç©-N©J¦Ýj UU)TÛ§¹S¤§T §^ÐþŠI‚”ªmñ÷êhªPSª‘juJ uÔ§T¥SnžçôT§T §pRLÄ¥Sn¾í*ê”ê©-N©ANº‚ÔêªmÓÜ©-UT §?“ú)qLÄ ¦ÝzjhT §U"ÕUJ mÖ µ:¤6éRZR‚u4!:¤*›téîÒ—…:¥)R½ Õ(˜jKQT€~z’ÕUH s»Z‚Ôêçä¥Å:¥6ëK‡Z*´§R·ü5%©×êH N”êÌ:ô÷kRZRùù)P¦·^ï%.iÕ •;^Ä€naîè©!:ö«úêKS¯b¸<¥I Õ zjt¦®Žš8„ê4¸"½©ôS±?¸¦‰×µ\=5$#À® -)Ô«€ó I©ÕzcÂ:[Ði9J>2kóW}þüfjÝþ±"ûÃgþébÿg[~…‹7ûÖ­Çé[GŒhãô¡~'8¢6œLñQöuËɲÿ¸¿p¹LßùU¶áüwêp¯Ë~`þþç?kÞ~±"èÐ0†·ò£R4¨B¸„øõ$s .íWóù)iM\ Ò¤„ê»âؾ$¬·ökæïå±R)á»n–nÖUË9-Y®DÀP6ìТUDÁ¾dÌÐy5›üU¶V) {é èK€:A”8}!•Óô¯B³•ñXC§ Æßõ?γ/[ ú䞺̻‚,Æß¥p+µœ3)E”„nvM¤ÛÆÌ‚ÅÜpÕœ„`.;¥WU›PPÇï‰Aþµ™Û¯{îd‰ä9Ѱ´‘Ð\ uôW‡Ô°»™´²ü@t•´ Óñ.. mÒ¶ÒÕ¥U()SNÄêªmÒ—…4 §pR êL…SoPÔ–§^Ô §UIjuJU6ëPZWzYü5ñ[äºìœ•®›id޳YÈ+䑌M08œb¶Ž:RÂQLCF¨ïh]5Ò²ÜÆØ8+ó‹Ìæ±vÙhèå¹…a4ûm/?×ÓÃBÙñû3wemþ7=‘d9®èÚ;£úµ]E%' ò&f=ôL¬s…ZHFI´pÂA‹´L$Y³Æn“IÃg 41R˜£È![e½Åµä º´‘’ÚÈÐæ½Žcšz×4Aê Э~hf¶™Ö÷ tw 4s\ \Ò:A„ÖªùM½C\¥«Ž©AJ’ÔÁJU9† µ:¥:©P§T §@ÔÐ'T ¦ß"Ôꔨ-UUÝ–gù÷!Áý¦±°ÎN»-ÑŠ36MÃ#ðSíRG¾nÀíä•HɈˆS b€é™Ž`lLï÷no1µÈuÇ-ÄL{kJkiuX x©l¸ÝŸºòö¿}Åão§³ê|pÈæÝ$6ާXmHúÂêéX¹{~Mì,ô\”Ìkƒµ’‰—dæ6J=Òc¢Ÿ0z’.š¸LGßBÁá Ùín­oí™yc,sÙÈÐæ=Žcšz \ÒZàzˆ$,ŽŤñܰÑÌsK\Ò:œ×Aú øÁN¾Šç \UJ mñÔ–§T §UAjuJ uÔ–§T¥SmM uLU;‚• R•Mºûµ%©Õ)TÛ¥AjuJ ]Iju]fáü¿‘#šÇø«$_PÍ_+æZϱ®{š1¼š-Ú»Z9wð±oZ¤ý¯QTȘà¡SX†ÐåÖòû¿iíû–Ù粘ë+Ç0<2{˜aya.hxli-.k€p%®¨+7ŽÛ›‹1¹ÄØ^Ý[5å¥ðÁ,­Òæ5À84‘ZЃÐBäR|;ñ #55‚3444Cr’ÒÒ˜Â÷aÝGoäd_»ƒE«&,š¤uYS4Ó(˜Â5жæÀ¾¹ŽÎÏ9‡šògµ‘ÆËËg=ïy kÖÈKœçÐ $€Wn}»í`}ÍÎ+%´l.{Ým3ZÖ´UÎs‹kZ$’¤®Ÿ:ú+n-Zà)J¦Ú‚ÕUJ utTéìLÉUµî¦ÖÛ+É͵>…¡%$´<}Ö¼4Š6ÛùvégL§Nرn¤I#èS*R”DJXæe1rd_‡Žæe£ŒHøŒ362@tUÖI8€ÒH¡]ÇX_²É¹'Á3qÏyce,pÏK%4— - u-Û§Mw¨ ê×µ0)Ü%©Õ()·Z‚ÔꔪmÓÜ©-*ª”ëÚ(¯bb©·Çߥ@SªPSª¤µUR‚u©Õ)TÛ§Oz¤´§UºEGÊMÈ3ˆ…/- ¹0ŒŠhâBAó•9nÍ“TÕråsøB˜Ãà ë]\ÛY[¾îöHáµµsÞàÖ4’ç8€í$Ío÷S6ÞÕ’áækAsœOPh“ô»>êÁY²Å‡ûCxâ|‡mAµ˜š´g#㚊›€™æûª8çÏu:t´:®œKAë ;Ú{£m÷Ì–>ò N·¾µ£ÿ-£~€ê~%ÕeSn•´­~©ANº‚Ôꔪmê’ÒR‚]•U)Të÷jhT ¦Ý)ªªPS® µ:¤*›z†§JuíJ wJu[¤T|œä‹xXçÓòncÑÃù)®T*MÙ±bÑ5];táSHše1Îa®½ÕÍ­•»ï/dd6‘4¹ï{ƒÆRç9Ä5­‰$€Jæ·‚{©ÙmjÇÉs#ƒZÖç9Ç€ h©$žR¾‰h©{zMì$üT”Ìjæk#0ÅÔd›$Ó}»ÖRAÓUɨjES½ê‹K«L…³/l%Ž{9©’F潎ok\ÒZáô‚B»›{›9Ýkyâ¹a£˜ö–=§±Íp Š¯¹Ý¹rÇBCܲüÛrâ;äíûäKö°“ªE¸3I4áåVnFgŽtQIpACŠ*”ú%uâÈãn/fÆÛÜ@ü¸i–&È×IxÔÃ$`—3[|fêPâ*$–7ÐZÅ}42²ÊbáŽc„rš;CÈÒí'ƒ´“CÀñ[@)·Jí–®µR‚ÁJ…0{M½CK‡ZuJ祧±:¤íî÷j Sª@?pT–§T }ºÔ–§U¿ÅÛ×Ó ™Hx ¹XËq²O. È§ÏØA4\çMS/ «x¶Ë(™ŠE2e0”@Dº79,}”ðÚÞ\AÍË‹bcÞÖ>WRØÚâ È  ·oc}u ·°Ë%¼ ‘ÍcœØÚz È0P´‚uÜ ]T€p¤Zª¿Z@8óÔ¢£À‹UU yõ¨-EUÀáÑKŠi@ý~Z\ð¤…Sª¸˜jHE{Rùêtªª¸˜jHíERÇÃËS§±5p8søèâRÆ—pW…*'Ç©\ ÍH„ëÚ½Já-ë}°éßI!ñ¦Aäñ׿ŽüýøÌþÖ»ýbE÷–ÏýÒÅþζý sv=ÚÖ©ÿn…±)Ø÷kGýº¿ ó—Ão&A¸k÷”£þUmŸø{úœ+òߘ5ø÷9û^óõ‰Dƒ¢½…jWxjH Õ\ÏKJÀÜÃRBu*àq¥Døx„ø¬ýáfÖ°²L;«{#½fÙx™f,.ÎÈPP¥e1©*Ø®ÖE·¤‹cœ ¢NÓ7¾˜µáüÁÍn-»vëœn– *ÙÚ5jh5{ÚŽ%ºÀà[N{Ô³Çå,!mì¢'†Q„Ò„´é-5 vÇ¡f]ÊâÚ‹;´Å™êˆç|G tìˆ)»bš´D…&ºróù~,dïešNíŽ"MÀPº¼ZâOk‰4Y›è ¶yŽ*<4‘¨Vœ:8Àº=ò-U6ôö†9Îc&át\{³X"tÛ  S€ººÖóo$ÌŒ‰t:ƒ¨Ö+ÒOWÒ°R†Ö­è[S(øÅc§"&£[º„¸Ìñ)ÖÆ(œ’MÙòÙN]ôÑ @£¼÷À 4ï"/s$µqmËÓJñ ð÷öp+‰²¸¾ÁXÃ/·¼œ^J䘈zví£!Ú,“uaH¡Ô¥ èê&w*¶ä1S\Û†ÿ-g¡Ý»Šä‹(àcdŒMzOgi§«é\BÂÑÕsÜü:ðùkaù †ç†œuq’êdÍ87Ί܆g¨Û–ªº§dºª»L¦*Å0ˆ<5ªîLÕæWL tN:À¯:EOObîE¬žéÇU>•”ïÛBL£gì“{ènÌ".›”ÄIôzåY£Ä¨Š6] ÝÐu.µ©1·1=¤º­ =GªŸŽ«•²ž£Ä-åÀ¢šn7Žeç÷¤Pºo Îrˆ‰Í®¿äë]i-ËYZŽŠPt ó®Q3öŠÐË‘EWQ¾è”Ü@ê€ t€Â:{ã”F˜Œµl½5¯ƒÂ¨=äTNÅMÅ`0‰È¡•ô(¨•0H»„1D…0‰‡Qðìä«€é#Å"”êÝ)§T ë ‚Ôê®ÛÝîT–§T §=M uJU6õRð§UœÏœUgåž#áÓÈlI/aã«^éË7\"‰tg#¬v$vÖ)Ëeqã'.Z‹†æ‘Ër#éÄCÆ9õº2Û[—³;!‹9¹†Æ ¡÷.-sÁZá~‡ 8µÀÔ霦ÁcóÛÂ1–h“g·R³¤=°¶¡¤u´¼·Sx‡6­"„® •øÄâ,߯¯—Ù*ñ¶ {[^سîy»rÛ²#˜¥Šˆ¶#"1lÁ(ÆÉ&Nܤ œ¢§2‚&¬Þ×å&ÄÚØ6a!ÇZ\šiáŽY®^~Ü“=íqqy$é'KAÒÐX¼÷0·f{*윷·xß›Ž_p´}–FÖ††Š ©ÄUÄž+(3$œNðAmñ+y&ƒœß‡rÂXZø¼Á² ¤r‘)„ͯ)q(܈¥!7åê “WtV2ETê‰Ê!æ»FѼ¶çEÇ.±ÍÙy|YÈ[[Ô–ZܲC̈Kc”5Ò×Hq`m(Ví¸®½¹gòÈ€íÍŽ¿sM@q ˜¤¥žÂàÀzHÔOH_~Vàç…®®è[S3q?v%!u[öôÜTU•‹BfJÙe8ܦ4ýò²³ Å¤Y•R¢ÍºYûa)ä)¸6·79›¿±Se6~Úµ0ZÏ,o}ÅïvÉÿelZœý:K¤“DMqÑWHäÏrïcm„v7p%ž(ÞÖÃm­Ñµãý¤Ä¿HmjªBѪ‚ ·W€‹õ§ {y[Œ­[VÊ[-Îfw/öEžA’oÍ’NUU@2jvhÙL^ß±)œÄÎz`ååí¾ö†Îáù;«Ác<ß» \[÷]D8]æŸödÈaʬ¬{Æm¯-Ä-±‚ØÝ>ðƒÝ 05wúA' éÑ«íÔjÒ Öû ÂÇÙ±­Ùnð½o Ó-Zì…ÊÆÊÈ8ä–ƒLŸ™Uš I¤Ì‚í%†ª·`ùHX ÂU“é^s?~lÙmrËÂZYí[»†Bë‹[¾ýÖoÒ?½1Ñ´9„ø¯’7im âKîÕ¶ÅÚ{–;‹M‘”¸¹ÏÛÂé öýйk_Ü8=Ä:œZÇG£€pÙ1_ ¸Âãá¥&2–p[Û-rÃüy) …ž­É1,›[sã†m,ä[I¶4¥Õ*ñBp Ú6d“‡j, ‡f~îçæ~åÇóܸÛ8Q‘É;Û¦HgÆÂé{·:à–1 MÔ÷Èèâk*ýC«ƒØ˜KÍ–7¦s&l¬›~ëw0Bd{€X€áªW ;KZÀùïIã÷‡kÈŘ×=áŒ7bl3;i˜.Ëu bîµ.û|uâeÙ³bñ)ÍÖYP0„OAÞæÈì^`fó[Ÿ#±w…„6;« sþbS4Á-(øÜæµÍ,%­s\*I¨¥×´1˜Ì–êÛ—rÝà/$|_ŒG,RÇÒÇ€ç4‡\<ë¨+Ч]zÉjóê­îÞuÚvÄóe^Á¡-´Ë$dÖy“ÄO"Õ”éЏfS¢(€Žº‡~ºwñÝÉc4vN ½tO¸ô5å¤1ÄPÔPžv-.¢}ÓKíD/¤°¨Ž$Tt¯o¸Žµ8¶Î× ån òãË󷇶‚ôpÎUoe<Æì"¡#›))`nØrÎi6Êt©.ôtÓ1S*eI?Œ9y”åNÈÃ|/ÍìS,wæ›ï3ä,ÃnÜùDŒºîæk£, T–ÇPçââç}5¼¬9º2_ßܺÈ:ëkãî"³º›vµ¸Èxp&”sè@ 0+‰kû0gÃãÜŸˆå­®!m¸¶XÞfb]›È»»+/+*Í•âZìTaRzŠÊ*šNˆ£„ß ¡9LRB½Ë—8-¥²±|þÚËEs°.%uÜqÆæ¾ Æ9×’5ï«H .a 1è ’Jò­é•Ü;Ÿ#ŽÄg1òC»¡`·{Þ eº.pl%ì-m5À¸?UA‹³¤øPáŽË¾Ú`ŒƒÅÌfnYÄ|,ÄŒ7ø×Ú7„¢hú=¯1p¸žc.÷°tá4W|š)7ncÿnŠj”šÕ·4¹“˜Á¿|`vÌ2l°×É%»Ñ}=» ¬ÑÄ"tm«Asc.sžˆ^ÒsSì-“Ê·jåó’3sÖ=Ì·×iÎ¥"|…í{¨Hx­¯¦Ž¯`ø8ŸBW‹býž=µtð¿b¿¼gl.Ã7)œÇwN\Ç.Ê&n-D·\Q2‚‚å&¨~÷›¶/µÚÙ<xÆn[æÀçètàú´‡>7‡1íÔ¦š8Ž+mË›¦OŸ±ÊÊ`¾ÁÚºRÝM–œ[BKHcÛG5Ô®— ¯°F i˜¬Î n·+˜0ž.y‘2B1'éÜ 6Qr[…”zÔc’?cþêR¬!¯ù5°o}ñ6ÑÌ`qqÛ6værm´./-1Žkµž?d–øV#kmX÷7-~ùÌGbn ﯊MFžŽšÈ{{„\…°¦vÍ\D«mœ«w({n>Ëyp]®& §RˆbÊ×i»Ó=ŠI¨,æIû„’M™½!Îè¦&æÆô»Þ9‘³vø¿Ébä€wϸlPåˆÈçLç†éyv–CLƒ¼y-vû>^í‹}µŒÝ;—0lì¯Ù/æÛ ’Rö<1¢ Òu0 ºG¸Ï´%àŽ'Ãf$³±¥–¸‰Ë%•“Ö˜qЬkÍFæ¾®;V)âmò—<œ¤LU»àU!ÐI]ãºI@:gÔ @ÊÞóuå÷%ÖÕåö*ÚòïØÅíÍÍÁ†Ú)žÒï»Ç¡’>WŠç6Ž®Xë]—·ñØ[}Á¼/æ¶·¾/6°A’y"i§|ýNc#i¨-‹¨=!n¡ÁQ.¼•aÁbLµmÞX²ý²&²Y²t“% ÏaÙÖš¨%y+~Û>–íäL¥¼«¶é1P©»UÊZ"‰Å>©ç!ÅíËëí׊¸³Üö7±ÙýÍŽ}æâpM¸µ›KZöJçBXÖ;ƒˆhw8å ¿ÍZZíü„8+»WÜýåÍ,0Cc(y4 , ¸—4}­Mn¹6mŽ;7·®s„ɽѱҴBøåcƒÙF¢Ð+S¨PÑGÉ?ü%AÞq¸š‰k®bþ~þ*ÕÓbc¸ù¼Y;4 HÝ™%¹BNu“'.Šš®›>ºˆ$%9K®·~óZ÷&ê°Û–°àcò6 ›·Gzø£©.Ð!ÑœHcÍGki9“´y}k’fß¼ÍÏ&Yïk °[µö­{éA«½Ôö´ ›Àÿ£BÑ85}ugŒÙ‚o;ê2Ì’ÃÖ%Ýw¸º Ðîm÷¿g¤-¦ì\?QuZ9‹€¹ñWŠ*Ýÿ¹k¹¹9Ã/cawÆÆKË|½ôui•½ë&. 8>V¾YP×8ý [ Ëio÷^Ojä®Ùm>6ÒYŒ´¬nîÝiq$ÆæÈ]BZÙ%}Iðá…o¬”æpng¹okÏ Z®/‹¢6ä°¾ÊÀ]V¤P˜'æm–w&ÍÔˆ+7É‚ÊJA!DÂbñžbo<&g½°öÖXlÍж…ðÝwòÁ;ÿÙGp45Ž/>)1 Ôê4¡±²öÆWsµ²SÜäñ–æy[$ÔrÄÏö„ë.£5‚µ¥€q¤(µrçy"ã±còS©„1­¥fZhÜ×Läd „™ÊÝRC!'Â.«‰&cv®ˆ`Q3h ÞËoÍɺ®¶žÀÇ[ß\c[¼žâs ¾P\È¡sä-¸FZá^ަ?há-0û‡x^Ík ëž-¢†!,¯lfŽ•ÚœÆµÄ:\ A¢Þr ¬`pÜç_ëå¥8u±¶¥²µ¤“sAËÛ‘Œ}!’ܵ9†xÞž è›3¶PJ¢©€(==³ÍY¯çÜqîËâ›·#ÓRa9=äs=Ô-kC‡æ‡u§Œí«Zïv3¼¾ŠÎ,+öíáÈÓålUˆÄ‡ÆÖÔ8öž=x0´Ð¹¼W+ÿ« /‚a'üJM/ ¨ZÎ&Zc£+‰™_\}–Vei¤f”I“zä{"6€¨bH¿â72eÂé܇á.뾺î—榮øF#1‚cüà‹Q}›7/Ä]çt^-ëhÙ맺// ˆd mx:ä "ãÆ7µÏîæ…eqÚRîá¥EAU¹—lxéšÆ"b»ÍÌESt½¢*ÚºW¯à3˜íË…¶Ïbœ_Ž»‰²0‘CCÒ8ÑÍ5k…Mê^m—Å^àò“â2 Ó{o!cÀâ*:Áëk…ÓN ‚¸™TÛ¯k-¤,}V{ð)w[2Ù†·•»²Åç×·0õýu,›(h[ñ3øñ–]' ¡ßÌ“ÑÁ ˜¢‰ŠMå T•ðŽxâr7ö˜‹Ãgq‘Ú¶y6BÖ]$‘ø®Ð263¯S¡Ô ¨Ð\ßYåNBÊÒç%l.a²Ü6F;;‰Hk!>3uCÿKˆê T×vÌ+~>¸l¸~_0/cµ™IÝòô[(X÷eºùƒ´žº—ô) ­H¶Å"¿¦8j‘ŠSTNrŸU½“üÆÇŒ{ NákÙÜHÛqes­sK[¦@xiîÚ÷_h#aµg76MáËe"¼Èá‹]ß1Ó¨%Í!Åú])hã«[šÅ$Wĸb'-þ¥d«Šámˆp¦?p”Å6£'—CƸ$VNÛ²í–;'óNJ€(c¦T‹º¢€"rþ£º÷•ÞÓþíÛxûwe÷ûK"Œ9°µÝÓšâgB(ÇP\jÖžÃ@ÛÛbßpýû7{3qÛḃHúK{Çî›â™x6¤Š 8ô€yeÀqµÏŒï£ÃÞHŸ½ZãQdã YW¥®µvÄÀH,£v÷LZ‘ò2QÓ1I¬‘ÅÁ ¸vÉNqïqXýý¸ñ›’Ïls”™-BÖâÞc4•€ ÃØÇÆòÐMCÜCZ:HÈ^m %þç=³¯fºŽÇI¸‚x„r²7¬Òç5ì¨:€¡h“Ð=_…Ì-ecÜ]’2Î{ql²ÉØý¥ÑjÅZ¥î‡NÛ‘ÁÙ¢F*?I­¼Äª¦S?p™{UOÙ”€%¬|ÏÞy­Á“Û›SÛ™±—î†IßpØá´Ð8ê .•Ô$DÂt´j$‚²¯Ø[c‡°Íî» ŠúÌJÈ™ |¥äVƒIp¶ wޤÐEÓÏ›^V¡4òú·ò•™hÞVÙ£SŒs6ÚìA»2MãÔP~‹òöb˜«¼P‚`.ðVå±÷ÈÜø{ûܼ,±Èbï'·ºYxŒÁÄ»QkIioé¥C€­³ºö™Àäí-qÒ:îÎþÚ­äÒ^%à§QÁÜ)^°M*»b_„èç[«Edfd·±u”ÖñÌ*b!Da¬´o)4“F,ݪ¬ÚÌÑ~‚h"URUuûB›³Ž%Õ-9¹#ö5®íºÇ<ä2—®·°³Ž@d¸%å‘—9Í0â×8µÍkt‘«SAØ.9pÆî˹ozß¹ØZ‰¯.^ x i:ËCšÚ‚çjN“AgÃæÊׂ|<勞ë¾ìˆ×BöUóe¥m«xÀÄn »Û9û)7Àg­ˆ¡L“ ƒ…·€=茒ówí‹Ë7smk‚½°‹‹kƒ0·–J÷m¸k˜ßЇHá´ë¨ #Ù»o=mr6vB{Œµ¬.”Ã<#4lûn…Ís¼aÒá¨×«‰_e‹Ã>0w„ì\픳_éí±rÎܯâR¶ÎN.æEÔ{–ËV ®âEg`Ðë9UDJ“4ÀÛûÁ\YÎeîx·¥öÆÛ_ï ´ÈÇ™„Q#÷:g8ÀÝA¬hqt‡¢”+“±°2m{MÙžÊ}ÎÂydc˜"2<–8µ¢ ÒK‰¡.% 0tÖ«'IÖreµ¾ùyHòÒ(BI9@Z¹ˆIâÉÆ¾rÔÅ)›.í‘H¡Ó!Œ! i^½bë¹la’ýŠýÑ0ÈÆA’‚ö‡u†º °*¼Þí¶ÑÝÊË7¹ö‘ÁŽ"…̆¸Ž¢[BGQà¶â©¶»«‚«1øJl¢9Sˆ™D’3,d:qmzBbtdÛØŽ-‹¨¦>ñb »•×8€Q1>È`ñîlHü·÷_/m‰ï³w­PжÊÚ“\º½D†µ££U\Úž úW.ØÜqÈo9À1b­IŠ£ºž±@>šç4é[¯¨—"Ú8o‰¦"Šd›e;;#=ÍæùFÁH°Ï¼)4ìrC´MväL(·›MâëÕå{ÎÝËf9i9!¸Û“qiZñ²º=ãZÞÞæG¼ôj}A\ûùƒ5Æo¨…]}†ç躷]ÙÞ°4témOH]“0ÎÙ’á‹7”«È;iÕßšÓ“’aY·H/é6!"Ìá©]‘˦‘ÀNR(&åÓA×,æÉÛs3}O‡‰“ä›gŽÐÇ?»i?uejú;MWH…j³—1XO±6”Y9‹®oµ9¬ÖGûéâÔV® Ã1ÌwávëÛÓÀuà B(-cd¸<9¦Ži.uÚ<†ñ.ªêȰVN”°pÆožŸÉíXH9€gvØå¶­\„ê)¢¯GÛrE—vö%Â[(¢^š˜Ê^þèåÚo÷þùÛ6±ç·ž }°ùÙ]Ï}=£^àÖ¾fwml€8€îìð'¶8 M›´³×ÄmŒ¬ÓgšÇÄÐwQ\âØ¬¹†€‘¬q§eHÛq_ –Ù‡¦³GÊdÆÖ®Pua\LßÛÎez3(‰S’£W!!s;–+b³wRI59„1³ºy‘—Åov~ÝÅœåÖ-·P¹²†6®–F~qÎ Yy“U\âÖW.¾ßØøÜ†Ú—ræòp¶·¿6ò5Ñ—:ñ:)sô†R€<š4…¼[|9bKžÇÉU,ØîX¹ ­¬Ê^^ÐtêJ~xÈÇ©¸cƒ†¯”¸^:ìh)¦EU! ažK˜»³œÆíga[q¹/±îÑÇpÖ²)ÞÒ!h‰­f§IRx†µ¥Ä.Í–ÉÛ—ø«íÀÜ£¡ÁÚ^ˆš÷ÂK¤ak\ Xwxâí-eá©ÎÃòn±£±D>nÄW¬åÛc¹¼W°'˜Ý0-àn+zåN3ã†à©>zÉã'qâSï³ L'0'™Û;×9qº¦Ù;ºÊ LÛlÅÔN‚S,RÂ_Ýš5®kšúŠš;€bó»[Þ‹um»©nq.¹6ò6XÄrG(n±].s\ÒÞ<:*:jiÉßáþ,3D@äŒí;!xHÅÇȈ0µ#n«JÒ^A P#ßOšt§]™NTY¤]À6šã ÞÆÏ ¯öÞ ðñÊæG÷Ùßó†kl]Õ"èox領]ù¶ÎÈÄ­3™iŸ“|msþë e†áö]'yùÂÞ“ }ªîž°%±ŽxÎaŒr«+ ÌIÊYml£)n_ÑòÖ<ìŠ%›É,ªP¦‰9œLGEÍ»2ÁºµiœÀß¹=ÇÉ™7>Þ‰ö¢IË“ßMjøîba–d×%PX{§ê ±m7gØa9žÌjF\1Ï€wAñÜ5ðHà^Hf–UÝüãt‚x9ut>>} ÅKìa•®¤,»*Ù‚‘’cñÄI^àöBDŽ fc“–PØC?IR íBŽöéuÒ¶{ÍÁsæÕƒsâ­]𽹕Œw{Þ›m,e%æ1WÈÒ ‡‹CÂ¥köØX%¶Üà27 ÅÚÁœÞï»ês«Û¯ƒXàtŸ½4 ©³!mãñ]ÅoÎ9¹í|«b²ºbd–+ÛLqo=mœ»œÁ,²:€!¾et†œ»fÎÝÒî;Œ®;!mr˜«çA#õ+Õ!´€âPoO®îm´Ì8ûÛ)]qÈZ6V8·I­$Š€š˜Éh'¬ž…Û’œ$¹m•c1[KѲàñ‹ ‘™.9˜ÿF†Æ-Å$fÙ¨VîÖVWâÆ‹ dͼoé$׳)T9u+^mG&Õ—uKdçE>Möxøc~©/N­¸U 3[ƒ6š‰h;Ç.ÍÃÞŽé¢H¬s{#ÛFZ:žÓBKô‚Ò8·V¡ö@$R/✅Á ‚rµÇsd+väÛ[^ï³ n7¾™EªI…¤õ¼“Å[¾"Z¨‹GIöÊ€€éJ¢„»­ý»¶Ä–÷›ïmm·®&lnžÞã¾6®wí,h-¯HÃ¥½ ìmé G¥"ªBG-›Ë‘E é9; y5QòždZg`æp>xuw‘‘S,tñšA#ÓÒà <`¦ìKŒ}Äc2d†T»û$õø*(OUGUVkHÆÈÛî“¶%ç+$@nv©¼rF6Фw"ä­âç á14A@[]wÒ †•æy»+æ ÎåÑV ð¨i„xÍ¡áÄ}kn½ÅÏm!Š'°tPôƒÐGQ¯Ð¶ÇÆU±»ŒLŠæHçHH¢ªÞNØ€:öb òVjôt/•þ©­ÄJÃô­˜ÆjìälOHjSHs&ºº@JÂsv…Ð4]à×@Ò÷isº¼+¦8tš…Ä%!¤Ñjç}Gj šŠŠIûS.rh`íìN˜ÉŽ‚!¯'‚³6—VÒHÑP$ T‚8£é¯RêÈÉ#ããið™sì9-!+f ¤³BF¹m3(Ù…ÒlœsS¦1äjˆ¥ì„‚n]Ð.ÊÔw,‹&ã ]£iÄ’H$ŸÁô®í±kâñxËÔ)OÆx.ÞMÙLCé¡Ä¿Û)¸c§ìÓÜÔ *x’µÇBC…xu ý&¾Ùèéÿx(I^ÇtÀ "øE1 ö€A|Dˆ`Ôû¾ÀÔhužº‚5Úð¯i?ç)‰h>Áü?÷-í“—àS¡¡Ûn½²¤M$„å8 j¨ªÇM4ÌTÇP.£ËÊ5Òš{~JÑ-iARiÖ'_à]¸m¯&«âˆèë&£ë4[ÜkB¬à)0YP"mdÑzä `)^>7f͸€j"'8ìïWNæg2>ùwQ‘þÒâ¬oþ«\~ ²Ö±Èá“5Òö £à/û#ð•Ü6ý¨ñ€œ‰Ã¶Pÿè‹ìËâî’jþ‰„ºî¢u÷Õ¦ä2ÐÈx<££PÓOQlc¤ý.'À¶;k e>ï飵Jÿ ¿ú£ÿ >µÄstls otÄôm%w4û(È[6ºzêX¾Š ‰S!—t©ö§7„5ËìÉnï³öóÞ=ò[Z“;µgM  ð.¦P[ÇlYnƳX é$ŸÆh¼QÈ­˜Â\jÆ»$ƒ[Q‡ZA!Éô¿¤.öqÂ"_xfä–vª(˜¼†A }gµÛ$ØßïšXû§™OKYÁ±ƒØK@q®+Å7<ÍvKîÌ5l ¨ëwK¿§€Á@ûkb-Zõ~´ q¥DêÏ¥/ uJë¥AÔŠ¤óPÔ–§T€~%Ij`¬»à‡;Û¼?ñn]×»uãÉø©Ü‘nš«.Ÿy1çÏŠÝ휧ð»U"ê*Š"e•åçÙ ÷°î1Xgçà–;«RHÏnímmO^ÝL$ç㤿òÓtZm=ÙC&ÒìD±¾ ŠTžêfés¨8'KÈHiT…Ú7³ˆ´¢|)m¡ñdûµÇÙBømy)è c–˜TòíKnË ÝbâN$’\§Ü9Ó.ýkxæ`ÿwiÞWÂnhÕÌS2X¥ÇŽíÝë Ææjqnš´8Ñfò<žÝß|®Ú„e0rº°\Á$ncØOŠ^uŽíÀ@ZW&âRÔáã…«Sƒ¨+ÂÞ½²tþIW2g¹K>E »jÖ’B8s¶žlc5•}‚ 8~Tµ+gÄ éXÝ…m“ßÜͺæåõ¥Å–Ûƒ,1Œ†9¦aË-ÙˆøÌkÉsb'‹ãxáV®îížÃhìx9ykq Îj[Ͻß:'ǃ4Gn89Í9ôû/oOŒ²‡Î¸…ÎA[×V'±>Û@IcleæF*~ÜL¶ä³H2Í®´K3un¦-WMÉr™¨Ý@10Ê_5äW6vËØw½Ó}÷;øò7’†>)zÇIÀÀZÇ6S¨°—‚ Gwnkr÷wnmÙö×ï6³¶asdóo â%p1ð!ÁÎ¥¦ ž w?XÕ·׎‡¼ñë·L¸2µ8a´òÖ”tÆ/¸3 €2sMØNKz.BÚ”“ž]‚Ç\ šÎ)ÅDÌmFï—ûŠNYZoK»;öDýá>b{X 㼊ÂëDeÑèñÙ3ehmKY&²F—°Ûîü37ÍÆÙ·¹´sÛ·"ÆÅq(kí¤»ƒSÃ_«ÅtnsÜÂMs4€j ãv;®6ñÌ•ÏåK†Žm u 9"ï-¾Âø´8~V.µ·,tí©–R÷$µÒ‰ÔA²[qrS9Ô"JdsQògpÛÛ`¶ÅöãÜùl„ѱ¶-È^Ð7P.–äÍ™! 9ÆFÕ¤P5®{zxÇó/4ùl害î7FÎÚ¥ÚHÃݽ®‘òе¡†Ž*I 8mq¼Qç²¢Üz©S*®øé~áR¢B¤‰T_] œL¾õ4ÀÆ÷¥@JõÜ|Bæ~âWKvK@¯A}âzÏÒ¼êòC'"¡‘Ôvèqú8ÚJ~ Žù?ÿåÆ þ¨/pÿå™ú¼ ÿþ˜ÍWü5oúh”åüÆ~Û›ôr/9N௡hBñÐW(³][MîÛYÅèÑôœ…ǵٿ¢Ê>¶R“jyæqÎGÿf~æ,ª‘?Ø(`c2ñddÅ]G‡{#˺ÞAž51³ž:Ú¤¸u€BîãŸdÌ„É5ÏÇ ˜ekMèÆ°ÓÔâÚ€zŠôG%ð3–˜ßÇ¿¸3BO*ákt$±Å÷ޝçSè¹nŠ® .¥+=/ èÆIEI 1»âEAT“ùÿns¯jÍ‚.oº<^ñ¥—v×p=±ÈA KX褎FÑÀ4šÐis½{5Ë üYc•åÈ}þÛ”‡[Ïo3KØcÈsdcØj p)R©£½óVaý![€hÜýq±¿ø†Á÷ó‹»1ÈGʰ».[FÄ5Ýú"ѹ®Ç.‘šºÑƒD«#¬ªÄQ®ùÌ à«8Ò6vÒø­›êãb[¾Ã`æ¬ {3Ü÷l“ÃÃLp ipkZCèîË#Ú7&âø}ÛR×3n÷v2ìËvæ¹²Éë\Ȥ‘¤‡Ê€$[R|pçõîcàw4ež%îÌ…`%qàü¹~Jå¬àÂç·ÆË‡³.é…îYI)%¤“Z9kQk¤fê& œ[fCï]ƒhó«gín\Zà3¦K}銱e›ñΆ_¼Iqb1¬ !ârÖ»P:F³¨Šb7,w&z\eñ!“mŒ…Óî[zÙcîY ¯29Îqp-1á¤GOjG5Ê–M{A-\i1!)–0ö'äY±igl˜(ØHBI8XŒ]+0ý58Ã"‚Ú•2œÅóÉ6ÆW—œ·ØYMDZÛb³¢êúŒskÄ•¦F¨Ú@—…[!ÑBâÐwgqûËzîÛ,‘¾{üI‚Ö®NøXÖǤ—¸9ƒW SßùO `N7$²´C+.VàáÒy´E™'1¥ê¼{A~w«yƒ—nã ='Fé.ë± kÙå)ŒO0¹¶7žúÙ–Û^gÞZÁ¸"2\27‹pçi¤BWµòÓÆsY«Ki¨‚@XŸ³ó»gjni³Ñ¶Úypï …Ïi˜´j¬†6’[|PçSQû €Jé)O§žÎ±ïkÄG’ö³ktå“kÎ>`ÿ÷ø¯Õî±¾¿é¶Ïÿ…v6VÆ·X#…ËÛÆ…ý-ˆq >Éö TŒbwU£-g‹vq“ÊÁÌ ã\™‘1û,—ž¸~½-IX)æñS®!¾&^Fº²mœ&rvôÂWcÖ+Ö‡Ò(Š)˜TIÁ6™9{Îmm&î=¹¿~ÜÁç­çd±Ç=ý´mx¸šÑš,f-m1È*ãã¸ite£+²qÖܼÜ' š¼´nk+ˆš'Fð×Åi3ËL1Ü;S£x“Kµ°Ð}–Mx'´¬bq£eÜ’÷VJ°øjá¦Ì°˜LIÉæ§øƒú+C"ÁÒlÚÙç·¥JÜoî-þÁ2T;DÕ1u2†"*ë9·rs1Ž‹·/·ãÌ_IŽmýæ§UÍ.uÇzÇ2&ÅöœdƒCžÜæ-¼ÉÆÞÉ™´Âáq¶Œ{xëKj 4ÐCݸ:GIöZx‚GC]áì̺ósÓ.E39–“&àQ@SߺUÒ¢›T΢mÓ€#¥}©ihË;H¬ã¯wm`©ÔhÖ†Š¸Ð“AÓA^•ó Åînd¹}5È÷8ÐPUēë§£©|%SnÞ*ç-\U^¬áLI‘³_³ví´1}®êî¹RâôÓ'Šfî5šÅŒeŠí$;í¥^°l$EW©@'þ@×O—7–ëÛÛ3ùˆ´Ën[–ÚcŽÓîÃÜ׸kuìä6Œk×uS‡J÷µ·ó;›“7츽‡^Z–ÚÄ «‹GG]x¬t‘àŒxçòÒXNq´t['R/ÜžrÎ9[²d‚Ž].b¥qS1„ Q0€rz¿=ùKwq­¾f\Jö± Gp*ç8ÅN$Ä€´é¹OÌ;x_q62VÃKœuÃÀ4TžW€ !8L|—Õ^1/äd•‘¿œ†<øÝâÖ½á†Mƒ«Þð•*{À0Q,X˜Œ;tÌ‘ž1@j¡´jÂîon1Ê,Œ[Ø7ïW÷eâÚMmµ»+ÿÅ{œ ºHpSA:ehÛ¶£—8SÌ\°yšìýÞÎÜ8´ÎÍM3ÌêQm#Ô(_BGÉì‹*Ñ០#.HÝO%8zâJï’±2Ô“¥–Y‚y =c¸Bå“zs¬Œåµ? ‚2›|Ü•Ä šîfï-ÌŽNÞíK{VE¿öìÐ2æÅ8Ú¸ac@9¢cX(\Ó*4fq¶Øý“Ì›]Á5äÚ¨¦tn$–‹†š‰î!ñÈæ¶G8Ô5ÚÝC¨ vŒözfö·t³\†hlsŠ-öÒòÓ9ÊRNFÄ%ºÁ³…㦢ým's˜ˆ•Ɉ9'n© ¸pA¹çöË—¸6CtÜ:6Gc$eÏzâã~¨Ëcî¼bçŸéñI¨Zt< Üñä$fcº²ÀB×½÷ÎsvÐK^Ú>¯×À5£Æ¼`(Vó~Š û7ðù[.w ‰Ä½îFº€ž–;~ÑnÀÊÂMóîˆé¨é­tðZÝüÄeÌ€6C¶íª¨½Š¢´§Eh+Ó@»m#“8á.g÷Üô4¥GvúTÒ½•ú×0zÒÖ”àÃèÛåú‘vT—7£ ÂM%c­gw{†÷ôÖœQœJЍÐwDºéX˜fÊ[s‹zÜá#æcÛöî·a¶àÄÒ:ä }+#,vò×kÔyüÄ͙աlFb$p=D2¦«-硸²²ók[{ Øx§ðËq@üQxÄÛX‹ìœ¶?+¶B[‚fõ¹ÍÍHÏK4Pæ1QP(áOxC{CyMç*³;-Ù ã}”Ës*Ky{ËwÍßÇu¥ßšŽÞG"Ô¸wAƒÆ x£Ðní¹ŒÜí³ÛV–íÉ™¢fÇiÝ> ·óš@÷ºGŠžYqà ñŽÈ‘¿íÓí nrXÿòî'®ã‡üØÿö›?Òß.«OüÓÞ°.Gh°ïƒëmq¥Ë®œåÁñ0J½w™-›ÿجWœr°ÿ¹noønïýP»ýÆ7ŸÜ:pµp`Ø¢_¸ºÏ‘ÅYψ}œí­,Ñò‡”}ñÓc„|ûVÊ..w LDuîkø-ˇå0·=†ö”ÙZäîÙ{i9Ãx®Ôk'”&.{Æ>Àqh´rU®. Åâ'”d™Ñlt¸¤¹È¹LMÎоgÌ­ïÊmñµn1øÎç1º. s,£†ÞGÝ ÜÚDà{±$aŽ!Ï-ÔÐXAÕ¤ï;ksjno/ûÜnÞPë§Ë3na²4e.h!¥¡ÔqR£Ÿa<¯{EñaðŒn< ºéÌ.²Ž³r,›zø^PÌÞ@DÄܽ”C)ƱMHå›S ˜¸&šj<ôÚ·Ø[«¸÷¤™î›\Cl²’J%¶”3Se’Hk#¢sÜY#ÅAÑ©Õsš—ÚùûLœƒ µÙgýãq’7VpÜ1†9ã.¡Œ’ŒkÃsš¨(Ö¸¾éšâRÇÂYn{-ÂaLq[/lHÛq®/²â¯Œ¤7KFÉÂÁ¡oI7‘dÞ5»€pwŠ‘DÑíHCf1{».\f÷®&ÇiÍšÏ\Ûܶåó:öáöÖ]Ñd’XXâò4ÚAwØ$jðßÜïl^×ÈÝî(±xˆ&Ð66ÚÂÉî»ÀZæ0Fàæ†ƒ¨¼‚Úé$tWÓðT<ü<Æþ™o£ù£yÿÄþ‡-S˜Çÿ mØíþ²…);#a«.øÈ/ü ]Mê«UE1u9`LAIÝV»ÖP†Qgì²,"dhA•4QÉï•(ŸóNÛ7·w…îÃÜo‹X-Ã…tÇu¬‚g8ºÒBd< s‹’· >/5¶­r¹—ûjO,Ô4«íߥ‰ õ¹· ƒˆºGÖ\f“Ì_ê,.fËîö÷,t%ýÅ·ŠŸ\z C®’Jàö‹>,-û¡Ìµçdðû„íM’rYÞ4Ç Ý&‹™‹ËyÜKæÏæU—8‘4JÔåSE½öé½àæòÓr«!‹m¦÷pf²×e¬f=·—}ãÉpÔÙ[#KcŠ—Šx¼*Õzh´©î_yÊ[Û¹såÜÎy iºÝŽ$6§HãÑSN…³Úÿ°Wú|µ“þ"‡®æ\ÏÌHáŸô².®7þäkÅú6/ªP7³æl¨t›‹&ep¢eßQ4@§L‚:åLD@<#\Wáãù€ƒ»Éð›¨A?{–•=•\–š&åï ñ©4û´u§ÓE•9ÞÏ6TôTO Ön<·pOÙÛ}ÜUk Œ¥žŽZ)¢Ów ùz^M¤Îš¤Á`PÊ5 ‹tÄ¥0ˆ|³Ø™« nù¯y‘¸ß_x•²ØºKÖžáV¶ö倂Í4÷E ^˜²ÝØ«¸íùwmeÒî#,» µx‘¥€É%Äóô:µ¨PõpÉ6aí6ÅN$äY³²ÛɤÕãù\cvÇ1âM=däž&š%(ñÕ)@9@+§¶’åŸ+´o¨¼s´ñ.kY{Ý^“â1¤¸ž€ +³yß.=iÕ ž•B@8R-N§Â<õ%©Ô+ÃÃS¥:¯^ø4OzÖ;í¢<íӯ̽ûûóšý­yúÄ‹ï]û£Šýmú,ðìvŒkS[ŽÀñ_…+ÄŠn%C½¦ÌâÈ·Wîg)þíø{úœ+òÓ˜_¿ÙÊ{âóõ™Aë^E¨T…`0…¨=*à~à¤;ÀÀ4"§­X !Þ(Ÿ¥p?=NžÄÒ­•:@å$×H‹¶rTÕ.ò`»7);js—A&G(N_öiï¼a¬fZÉ×Ö/¼%¥Z~‘þ~#ëY<>Cûºý—ÿeZv½¸{²¶¹´uµÄdøÂŽd”á¨8P‡MAÀÚ½§¹ ³A3dà°á^#‡FžÂg3Gâá2psr°ÉâÆŽ•…”Û÷ 2‘©‰œöb %ñ€4¬t–°ÎíE¿œm%ŽÿÚiñ” ‰#ûTw„>°j"JJP¢vë@Y%)SQWŒ$ Ü J&ûhùˆ ª˜5¤(&”¾é0£›wrÃZ!k‡¥Í¯¥qºâÕü%¶ŒŸôjßè4üK‹O½HƼÇì^·tA"Åe~ÜN@0  ñ#n”GT'(rdíáÊ襵è«Oõ¡ßåë\“ýx_à#ü…r¸'%dÕ˜îA»t Îo"¡HEJnª:Žð€ ®¼µÕ¹ŠÿYuÎF>ôŠP[šWüŠ»ûÍ[’ߦCÇësF®]ÃØXP §¡Dª->õa0‘C¦}¼…ÝÔ@L‡–(ÇûLÁ=‚&Ž‘Û_誦]BÑHì¢I{ŠÞûp³–¤hþÛ‚D¥T“8dÞ&/)^¼2¢U chœµÒ‘¸ØçÌË«‡pûRÔÿám8.Ôwwã„FGú,ñš­í½°ÑáÁ[Žz^qN]QUë‚¶ÔâQM‚GM±SÓ“Mšº’e¦„hÅÛÁnÎÐÖêáÚóWWëRèß3ëu#äãÖISzÔ»’ÒbÙªiÇ1'Úvi‰)L¢€A(ï)ºDÌaè<£ ~´¬ÅÍIJ—\ÉWR¦§ x8žµ²aÃc5kG`<;?Ëô.Ûe¶âe„L_ìôÝ( sŽš€Duæ­N[¦j$ž+`û¼’4 VBâ:z>’z8u¬Eâû Ââë=7ʼE{¶u³ÈË&8§Ij“¤Á;†ër™4›52mª%ÿvqÉïLcÔù_ˆ½Ü9?¹BÇ7LJ\?¨éã5ë5¬Žh?Õmx€«ºnáÂØÙÈ3DMí'†¡×N zÅHà¼7:çYE9„Ê*s(sˆ‰ŽqG^QÔF¾Ïclc@}|èù#Ì’q{‰$ý'ŠÔÏËOObš«ù‡¨i§T€~z)Õ ˜jKSªPSž• uH mÒ—…4€~१±:­É¬´‹4¶g"õ«g¤Þ7nítv˜éŠnRMBr jº40‡†ºòÚÛÌöÉ4ltŒ5i-´ôÔ8€xv.V\M\ÈÞæ±Ãˆ€|4à~µóùêËTUe÷|GÃñ˜G"Ù,n[b%l{gÙnãæjÝó£Ûñ~€ÿ·,Kçm–v~RÇ1Ê(w«ÉùKËÛ½´þÌ¾Þæè_Ïp×FZÞõú›Mmihé p=oüÂÞû»pÿ{ã[<Ha-yÇ»n—WCˆ-=@ŸX” WªñZ ~µ¸-&ýÚ-[º|íÓv$2lpåe‘f™€€b5MC˜È`H  PÐæ áe½¼Ot‘1¬‘æ® \{IIéí\¯šYÖHç´PIÁÙÑÔ€ê÷+µER‚}ªªÛPZR‚œô¨z“ªÜ˜ËHÇ †zÄ˳XYº]°¬Ÿ³PQ:b¡5ð¡]y­­î±àM¡í‹–9憦'9•hH¨ì4_8)ÕÑ\ºj¢«ïNIé*À•ŠêeÙ‘Â¥j²¤ÝÜUVÅ8"¢…Ü % š¸m ”Næ7¿h u ;éjäÈbpˆš‘SB{HèFšÆLå:g2jÅ9S LC”u)Š`˜¢€÷ÀjœÀàZáV”ƒˆ5#ð¯©Ã×/;—ŽváQUÕT]uD QULcœ@¥åðWp²áhlc 8*|‘Åò8¹ç¤“R~µR©·ÇUNÔª¾öR/#Ö :bà bìÜ*Ù`!ƒCDäP ok × ÖðÜ3»|}ŽÀx.Hæ–k‰ÎkûA þ$}©Œ"cxÆ1Œ#©„G”DDyDDj´(85©©é_z’oœ Ý«‡®ÖlÐ [,áelÓx¢s™4@Ú» é\ ¶†7ºXØÑ#þÑï OÖ¹]4¯cc{œæ7 h<«êB Ué§BŠ¥6øûµ©§juL t‡”)Rªª”ëè©-@)J¦Ú‚ÕUJ TЧU÷šIê­b£ÇJ1ns(Ý™Ü*f¨(q9Žt[˜âŠG9”0ˆ@DL<ã\"[)œ1¢w 5Ã=' uõÊfÆ"sÝ€I ðŽ´ESn5zAQT §pT–¦ ûÍ ñVÈ2QÛ•¶1ÌÝ¡×Tí›™Cê aI#(c˜J¨ˆë\Þ&ÈéšÆ‰]ÒàM:*zM>•Êe‘̹ÎîÛÐ+P+ÓAÐ>¤ESn•T*j˜ëè©N«1±þLá†W[vNb±²E¥uZN'K%àp´ž¾ ç¦ìÑ>é^9 ÅveIªä\û©¡¸* ¾GžÛ|˵ܗ9­¡}Ž»Åݶ2lòx1[IK{ËWBXRç´´UÄšý>‹‰ÍlkŒ$8½Çk{on^Ír;$5ÑpÙKC´Òpq൫qž-ü®\oeãëfJÑÄønØqkXQS¯Ñ‘¹übá“—Æá™Iœ¼ã–¨™T›’ §¨ÛÚ¿Ë͵ŽG3Ÿ¹Žïuf.D×O‰¥·@-Šƒ¼sAÎ s¨ã^N==纬óâˈöûŠHà騂ù$#Åy¡¼:Mxc™$ž‘¢ŒñÉXª ,«2¸T­X74UFà~Äê&_|%×Þ‡0W¡:Þ(œ±½ø Ô`=4âxW­i¢if 物4'¶ATÛã«¡QT §WE*& b©Ð>íIju_z²œ ƒW®Ù°6l»••A¸w@Hç2i4÷ •×m¬½ÒÆÆ6Gt'ÂGõ®gO3Ø#{œæ7 h< }HJ²Õ_s™ÕŸGÈKžzI5?„ª‚ŸÖËRªPSnµ¢*¾Åºpš¸tådš”HÙ%—UT›Û b C˜J‰L. Päjâd1Fç=Œh{\@ŸoIéí\®–G´5î%­è’ƒ³êT:êèU 9é§T ¥AjuHÛ§wФµURœþJšŠ¥*œÃÕKÂRè¥zª@?0÷tT–§^Ô€~z‚ÔÁìHæÔêÏä©¥:HSó êJ€ô"«Ù. ÓÞ´£‹1Ôv¶K½_˜Ûû†úÍ~Ö¼ýbE÷ÆÎýÑÅ~Ͷý zöA³ÅZVÇÅNÈ6x¨ª8¯Áç§(]ßn4ì•!• &Fè'|¢á}Ó€9ÒoÈ#Èÿeh¹)5´†š—;ñŒÿBØñO0ÈñâøúzÑ—³‘…ì—÷•âè ˆv¬á Z¨CK\Ó—jœ[‡A9D¦.§û“tµ9Ä“mmŒ®çʳ‹i×À¾B˜™Zj?I?e¿iÇ£…HÌÞä­m,ß!¶ÂºYZ8šŸìŽ©Àt4_Ì·–®ÌÍ{J^÷k;ÇÆ*,c[¨¡£`â1ý"13èlÑ5Sî–PÆPÚ ·K÷–ÏÚvG2É´-s¿¬ç´ç·8ñ>…óVéÜsî,ƒ®OpŠ?îêphêI+­@áÑ[QjÖkØ54N½©Nz\Sð$)ù‡ª—U œI¼m›Êøêí¼&˜[ÖäO¦ÇÇ|c1&¹1iéÒÎØF´í×P Ú.²I]L`ZÄæòøÝ»‰¹Îæ$îqvºY_¥ïÑ\í,kžêÐÖ¸ž W½Ìä!Åc™Þ_ÜHØãmZÝOq£F§´Tõ¸€:ÊܲF:¾1 ïpcŒ“n¼µo[YÙXÎA½Q¢ê´YVè»nt°pî=û7lÜ&²¬³uÑPª&sÀ#Á··uá Ü;zá—X{–jŽF‡à i«\æ¹®®kÚ×5ÀµÀBæÌaò{'.1 É@í/c¨H$(ZK\ µÍ%®H ­âàÄYÔÆØó/O[ÞŽò«‹¥…püoëãçlª°—"³“s9ñl¢&KW­›m7’“CWVÃvmì¦á¿Ú–7óø¶Â똴HÞè\0I Öæß­„;óo~ž‡i<=ÞßËØa­3÷pèÄ_kaÖaqdž q{t¸SÇkkÒÚŽ+®ýÁ[•‡ªû™¶xý^Á‹W/—Ü:‚‹Tp°&˜j¢š$9÷¢:h\I ×;šÆV•qTô žW$qÉ+´ÆÒçtÐM>¥Ø¶î#È·V7ÈYvÞôì{ŠÜ[-/Û‡ãx&¿¸¼eS„¶Óø©ä›iÉOŒdÖ*Z²là¨ë¼¨ššµì†êÛø½Ãaµ/®4gòm™ÖÑwrô[°É)ÖÖÙ¡€ŸÎ=…Ý Ôx,½ž1}†»ÏÚůbcÉ©ƒA™Ú#ñKƒÝ©Ä®§K¨8®¹6ÖÃ¥aêê¥áN©NºTª@Sn5%ªª”Ü%©ÕvÎ"Âyc;Ü*ÚØ’Ș½f7’­c¢ˆ˜¤y9;*å„5Q)UxåÌpÝä­Wuï-­²,Ou^Ãghçin­N|ŽþÌq°:I\ØØâ(³Ø µžÝ7fÇk%ÍÀvš°v½î-cÒ÷4ÁwBà‰BÃs1þH€û9/;kÃ^qLþ5„—ô«jà*戒íàd¥¡é…lìT9'»ïÈ]C\ÛÝ8 ßg-þÞŸï\Én÷h’=3ENñ”•ŒqÓQãZkÁÅeóx ¾Ý¹ŽÓ3sq, ™£[X䮇UŽp¡àHpëuè)ÏYú°õJU6ëÓJ©Õ()ÒP©ÓTê»/*bœƒ„oYw“íÿ³7ŒKxçRá+ 3èèJ±BE‚Ÿ[òRÑJöìœús uÐÀ×6ÆèÀï<4{ƒmO÷œD®{[&‰#©c‹4ÊÆ ât‘¶A œÞõ¡µ t:M d…†@Òc$Âz—j e[¸²ì cþoæ©ÙkHÕ½ÿ9fâ§‹l¿eèƒ-é°Ý„áÁÒA6¨Ÿ]ò˜S÷õ¬é¶FC)Š7?ïøh5ã{¹3âïší]Þ™+H‹Ü:à³£lgM†@Aþç“•ÑÛ;\œ{$îœÚkÔÊ?Ŭ€ô‚GÆo‹2èÆ×tõ‰zÆ|Mu[/9é±ò"ÉéMS£éÑ.ßG9Њw‘YBr÷ûõ“Âæ1›s '}‹¹f¸ß¥ìÔÒH®—µ¯oÐæƒô.†S}…ÈKŠÉÇÝ_Àý/n¦»Kºi©…Í?Q!oVV1¾òEó;gÁüm­µnëÑׯpÑÿÛȘåVC°”dâGtSìšuÇNBWK3¹px »+¼ýÕÖFàAnÝ;¼”ÒŒ«àΟ´òÖý+³ŒÁås÷WXè»È,¡2Ìu1º#.£œÒïô-è˜['šÝÅ×`[:Ûù¢vBÛÆ’[Áö–j*t¶Ëö^‹ñ·¦Ãöf;GéµHß唟¾®™Þ[hd2x¯¼ÿ¿á d׌îåüÌo‹¾kµhÓ%cñ©{‡AÜdmœá³°¿î?Ý2rº;gkódÛ›Mz™Gøµ4Hⶺ¼¬;ºâ±.˜7 .»MÂÍ®(”g.1Š·"J.*½…s!ª)ro*šÇH7ƒßWžÄg16ùÌdí“tÐbyX51àš ðè]<Ž#%ŠÈMŠ¿‰Ì¿·q0ý$Rµs ›AQÄ>•ÄNò…e¨>©AN¾ŠE¨)TÛã¨-UT ¥F”ê˜è Ò¡N©J¦Ý:{Ô¨ªPS¸*KS)TÛ­AjuJU:ªtªªR©×Ñß©N©Š®ß*ê”ê©-N©J§]AjuHU6éîT–§TÀ§?Œ*S±)TÛã¥@RU%©Õ()×RZR•Mº{•ªª”çåè¥B€R‚›z‡Ü¥@R‚•:UU )¶¤µ:¤:º* SªPS jiDê‚›téîÒ—…:¥)P"©üÃRZª©üõ%©‚”§æ¡¨-N©NR¡M ˜u¥Ã­J¥§±:¤ó IjuíHç©ÒRù‡¨jKSªö§‚’kgDc¸v$où<%bæ¯c@ ž²À:½`ïìšð^‡ƒÝÕ‰¶“­l‡¤v‘OíqÚkwO;×hš𤹠›¨ÙTõU3h ‚ÉåSAÐÉŸt€~M5 Ö!Æ_ž-ï¼Axx´ÉG6±qŒñ`ŽÐGá[#Û¾×–J¹\¤IdÊ£èõ‘?¢©Ê%MRoêˆ8ßÝy`0w´×?n'ŒªH¨¯ÀV:HK N’?Ê8JÞ-X%'n,xÙ‹’*œe®” H•DÔí&lALtÜ´ÿ wDj/¯73áû–:ÊÞJ´ñ‘Í¥< õ.{hqÅÚîe{hGÙþú}k'¡x¤ÆNx[^'$M'Ô}t©»ù2 ƒ6.•f`ÈÐÚ9 Љ€¤ÓQ8€V¥6ÖÎÆ6AöM–Ytµ  ¸‡×‡ p4ú|Íe+¤6½èdm©ï MOÑ¥eÊVÖBq7Òeš1’ŠE¸k,À[8,’(r²¾»WmÄŠDå0€è;£È:†âÁßcå6·Z ËkPê‚Úñ­ý¾š.Í´Í{u R½Bœ~µ‘ñ×)IÙ© •8‚d0©¼'ÝÔJ‚]©ÌpOÃÈ=þýh÷‚jâê0qLæo-µöåõ$|8» $±¥ÝÛg¸7-ñä âèZ[BkMZÞõ¾ –†ñ˜¬^?=™µ«%ü±šœ·E„ø¬'¢GPA.qÈ® 0̓Ã?´=àÛ€×U×pÚ64áì+™“è¸Ö²¦,bÝ“(\ñ¢ÕÁÞO¿·®´›ªÝDQAÊ ˜É‰NB@æþðÎóØ=éc÷[[ »Øþó š÷»ïÜ÷˜_¨ÄÙb˜¸<9Îc˜ªÒNÝ˹ŠÙœØÊ훳<÷vöÏî$k[ܾõâFÐÕîŽHÃKHÁäŠAâtÊБñ 40öY± ï_šöu•¾õçžæÜy¶‰ŽÞ6¶V ŒØ5±ïžV´ð9í:^<`׸p£W¶nK™¶Ï*ðx\[ŒC3ßÜݹ¼ ºÖňâXÖ‘VôÐxÔ¬`á0ÝXgˆþ+µ²: =S1#Œîå„Y8;…®D_¯.ò¥™¦bå_‘ÑãRl-Ôj’‰•S(%0‘röÛ{æv}æëæ0XÍ0È ‘:×ýÙ°Uç»{ Lçê!Å¡ Šz.ñŸkžOmþâ Àç±mYtH.?>eñ¶¹ÚŒaºKAÄЮkÄf#¸¿Ã6;éáµ-n±Í÷î·j[v=¯4¼¼Š ‡Þªåg.µKP1H£‚œÅ1J%?/·Øåï)³¨ ûÖZmÛwmkt‰®ftb6Ôyè$0´MFGxmOŒy…ŽÆK/qo[Ïq-+ÝÃ^^à:É%­4.‚CcŒYÁo÷T¦ÂÑyŸäçQ ¼Kx_·U¿r@d)kz)äÇÄפ(v#k++ª‰(És!)„ÂsÖÞ7çç-qqo=ã.%¶Û,M¾‚Úa–Õ’½±÷–ò:GwÁsA4T@LŒÕpø.[ï{÷í·JË6èä6²Ï,rGpøÚ_¢f7º.kI†ƒj@c¸0À˜žÈÁRÜHq8…òú!ÎA{Œ1Æ*²_Ç@L]·4+w ÜR7Âý¤ÃÛq*´]±…»I@Á¨ï&U3Û—|îœÖ÷‹—œ¶u“.Û`Û˻ۆ¾Xà†BLŠ&¹äÏkƧiÐáØâÜNjàq›^Mã½EÓ­ÍÙ¶·µ…Ícå‘€™$ŽÑsN‘«SOh²Ö÷/Íx áÈoX{j÷Kåàmû9 cƒH–âwЈÜ XÖ´‡<ÒºOŠAw[‚ÅáŸ0Y‘²|=žîÇy}[öÖ²R—ýÑu'yµ¼$P…Š˜²nñQoEãGiä“t©Æ&€@:Ö¾cí,Ä–ÛøZd6˜±šàäma|ÜÀÃ#㸈½íÒæ5ÝÛ˜j\5¯‹ÏwŠÙ[‡ÉöÞ,÷ »Šg<­”L&pc_ 5kˆÖפtqíkãð+ƒò)°CG5^W,2ñðy3Û7 -«rhe’I¡i!½õÀ‘š$”6¬ÐÐÚê-©¦{)‡ånÙÌ|'˜+›ØËYqy‘±‘H@.î¡,v¦GZ;Q.àêp[õ‘ÀÝ œ8£ÅY¦ë¸S Ü9NÞ¾ífèW0h!)t9<tÛA¾1ÜG"ºfQÒ'D‹é¡Ç£šçfn÷emѳ­mÝ‘Ìæ"²–Úbh$%ì’Ëâ÷dÈÐ+š@cƒË:—gÊü]¶çÎ`w-ÄͲÆcdºŽx€âÀæJYÇ]â]p«šZÖ¾kC ðm™ñRɶ™³^*áæJÒ{|«7#oßsõ™u-&Ê58¦-cá£-ëÒZFD9ãXB™nÙ3 ‘åËooìýÛŒÛyOîl¥ÆàŽvÛÙ-´v·†9åîs¤|¶ñ²@ãÀM 3C…ý·ËÉ·¯³vÞváß§/ts¾xe.kt´5Žg¹…£‰„ÕÚšjÞ¼É8—Ýü1/Äv ˆ¿,ulì¢Ó^vmïqÇÝhÈ5’†FN2牗g¢.̳´RY¸“³ã‰J@H¦_?·wVøÄó)¼¼ÞÒØÞ¶óëË{‹had…†HÜ÷‚Ú5ů­x6¤ê!˜|ÖßÚÙw–ÖŽêÔÛ_ i¡žFÊÀæÊdž´ƒR›Jq4H.í,µ‰x3áѦq{Cfl…rdì/`dö”5Ñ oD@–áM÷Æ—®aVzùY¨‰¤R VJwí’ë;Wusƒ˜2憛Çcs7V­žHd–I{¢ÝwB@Ö†´‡K1$¸ÈÑcC«œÏíþ[ìèñ¯ÉÇ’¼¼¾ÆÁ;¢d¬‘÷Ú¤ï %ÄÇn‡¼êm8%ÿÃ.°³¶2e=–%­Î²Ö?‹Ë–Ýû#é·r¤›NS´×kå˜Ýæ|Ý6Ý¿¢ú: ¹"ª&cèŽsÌåØù)¬qQ\s~û­Xý0Øæƒ8sÞÜi%úuëqcš×CÖ+-²6Ö+uXÅu$;'!hÛ¸çsuJ"sIÖ‘Þ꺴éhpq‚ÕÜØË‡ Ä\Œƒ°w¸±ûû~qþ?Ë÷Œ€MZR’‘ê?Fïdkb2=¬â)w™½íNR¦p­?rs}òúÞ<î7·2Gqn¬-ÙÝÎÆHàטß>Gº2ø‘ýK‡ - ³6žñ™øœF/5a+á{ »™Úâs˜Ò扛Ý5úé ¾¼)…öwgC]¶Ö@‘E¥ýe¥â†b¤´û‰òšÎumÜ[€‹Žb£2?I~ÙG &¨¦bŠãßvÛÍÿÌbnl#{ì. ¯yŽ ˆEþðÙ´¼k{Ü$1é ¡ÀÐדi϶YÉì¡ÈAvö¶î>‰Ýr?2b«N–µ¥áÕ.!Ô"¡u}©‰­»ZÂö|å¨÷÷ ×RÍ“-n/å æßfŸ˜™BÆ `5LÑÊ8jˆÀŠªvªêo{Þ­›)º²9<îþÚ· ·ìf7Dæ²’¸ÜX:G÷¯Ôu€ãFpG+a·ì¬q;G? æ7·ù7‰çV1ÜÞ5ÐÚx¤ãq5èÈÓpVõ¹ŽeçSbÙ’0¶ã˜É'7oIHd];T»Æ"‚‚&)JÒ9}/8!åM†so¿2ÊĺI#–Y®ãˆ¸¸É0{.“K»¦1§h‘à’FѼcå¼¼Á»Åf‘’þêì6[†=‘Çn÷é ŒµÆF²£¼sÈ⡤^—„á>:ÖžãjȽ&g•—áóH\¶ÓÈ'åŠe<'D$àN²;gFrÂFÓuŽØ]Ã(%ŽšÖå{ÍKŒ†ÌÍaá€ZgòL†fÊÝnЇD­‰À¶Žd{Cèj:GBÖmv6{Ÿ’’Sqˆ²t‘–;Cdá©…í¡«\ÂÒ[QJÒ«›OÂ3ºxSök[*»A…Ë–2´å˜, Ÿ$Î_4„s¥Y¸( ÝϺmÀƒ¦•†±¾—Í.cdíà öØ«Z*ÒèñÚÚ8U¤Ž"¢£‚Ê]ÚǰvUŒÅ²Q¸´ÑÀ>óI-`b±Ê ŠÝ™Ž èíöÛ§sâ9‰Ù›¡Ö’Zd±’)bc£Õ{nA¸¡Ïwæû¯Î4µ¥y\û’Ù—›ŸÛ†\YdZÉ#‘áôµ˜R-oÞx„ý“BhÏñŸŽømÂwÔš³–³ÍÏp¶3ÖáŒ`”P²ØìÞCÝŸù¯ì»‹èðŠ»6™b‰»u bÜ;(n&à‰‘ŠÆ@4IÊÉ7\®Ì:iª©ºhQÓZÔîöŽAŸþŽã¼‹û/¯ýãýU¸Zo (/!1¿¬¶„~êñ–øÑk¢Û îÁš©é h3‘ËöÊ ±3g­ÓQ1!ûBHMÒ”7@§(ã~á¹-ÜDðÐ ¯Ghý}=«/W0;†4v;SúW-€`AI¤ñ“õ¶>ógL1Èö­Ôm_ÊÀ¢# €d÷ˆb¢q áF ì‘i}¬†Vôè §ej¹¼qLq,»„ÓãµwÄW–µƒÚß¶;œ+u..”AFd]Ã¥Žªª9QÊ¥XÇLÂM0&á@F±_ç2—âñÙ=¤p€vqð©“qàí¡“ŽÆµÇ†”ükƒÎqS~ÉÊqÀ„88“}º® ¢i]äˆdTCB˜Cw„Á  ¹ûN\ØÓ~í`t€4è©p=€¼Þï.:-'ûN<~¦´ÿ”ø:ÈJ¿•r£·î”r²ªS˜Ú{EGyC!L¡¹L ˜yGQ­òÖÆÖÆ.æÕŒú:O„ôŸ­i·W×WÒw·O/ÓÐ< }Kã󇊻WU\ ¯xjHN¥ B•¨WП @70Ò (¨Wóù)iM ˜jHíEUÀãá©Òš@8søêKUT¬šàÒàƒµø®áê⹦¢­Ûz-YRS3³²,â!¢cšM6UÓù9I›²`ɲE(ª§!PÔD¼ã›¶¹.Wçñøèe¸¿›pÈ⎒G½ÑÖ±Îq<Z ' -Ë—wv¶[ëyy#!´Žþ=ïpcÐðKœçÖ€8’HveÉÄ\Æãç.g¼W78ÙŸ9rm’ñ’HÈ[Ý•;.%Güz˲•·.¨_Ù.‘”&Š&áo‘3†»Ø›Ç‘˜­¹á’·ìcp{ f¶¸ŽÖ ×éxd°ÈÞ- â…Àæ¯7uÎÛæþéÁÈÉXܽÓÁkƒ£žÏ!-ÔÒC£•‡CÚjYÁÇVGácð?ˆ'mùÌQ‘2ùxc+‚)ÍÝd[Y킾î{FfÝŽ;UTKȱf‚ ‘Dˆ¨r>3É=½Í[MѼçÝÏè—kmä‘tì qƒÇh<–xÛ'³o&§¢Ž‚†l&§¾zÕùͱ÷œ»íöû6ÞáØ=çime’–(ÜæÚºÚâ*ÝJæ´µ6n|#]‡yB]¤,ï-wNÚj6mË4MÊí«‰®¬£{ÚÓ8žÒÚH."ä6C¦¤ ©]CÀod´§8”³¯L°¾$¹ø—k! œÜŒÞÕËP·Ì+û•t\X@Ü.n§¤|ë³¥©@Û…8¨žÙÎþZ;+e·rØ|[r¸Ý¹;›&4tÏc+"ŽF ¥ˆC•«¸Ò¤»_ånöYœ~FüØ^æbeéèŠéŽ‘ìt„¥’^êpáZ\2öEâÙêâÚ% &ÑRaž4±°NT³ò=ß‘n÷I ÌåVûä!,Dƒ§Ž ’Ä)ƒ†*š ;aîÖ?°vÑLn£uÝÎJÊ{H- ó”.•¦K¦šh¥Í$t¸T·m—/ºðøËËíÛ»£|b‹xl®b¸–âRÕ» ¸ŽÞ2û—BøØÇÜ6!Ró©Ž{Øßë<}–js{›?sÛnk­Ñi™¹‚Ë#Ÿ·.…ó?L"F½Îl.ÓH£ƒZçu4ôº<ŸY¼3q«jÞ\A`éÌ¥±¥´Â"À²oÈ‹„åB2bQTQm>EЊ¸.7ª;8ž.4]8f‚eQq/lB†;sf³¼Àæ>ÎÉáð9¨v͆JgIuqlø¸¾6LT/Š&†ŠM6†ÈâZÊè%w0xÌVÐÙ{’Ç#–ÆKœ»²¬‚Ù'½Ä !²HêšÇ§1 SP „ÞMmŒ­ìÞáå{'c(ûŸ‡I¬Òâü°îK½Œ5îñ+Òüw3ż°(úmGLž $Ý)©Žbæ2J¹œD¹-¯üÃgÝÉIÜãŵÌ0:Kv›{fÇ'}(£c s]^’€Òq™ì³¼œÄ6ÒöÉ—¸y/ ðI+Y1N^Îê3Åä‚)Ð H–2Zèâg ZÜ^ÙNf¯X9¬U“¸!¶øx¿ï6Z>èFÉVçláGŽ ‡» å#‘ó}AËd2‚C @‡ó¬g.7ŽO”÷‘ÙÙÏçÆï9²¶¶÷ t&àB@hoxâÈǼÆï°÷46 á¹ßoM·cÌ gÜÜÅ& ÷lÇa<°½²ˆL€ÔÜXæ´=¿i­$БCÓÜé”°`1^G¼ï±pH[Ò° "-ؤ•ÏzPtáÞâM슰öQbm›ÿvg9³µ]Ëݱ€ÎZeòRBË©omooced’ºI^Cdw‰F5•tÔYㆰëÛGob¹{ŸÇ9–Å\c¬™+ ŽÖá³Mu#£s#k#h.`ñªç:ŽÒâ’áÆm[²ÒâÓ…ÀÁ²¹ÂÅ™«æ;»(ÙÄÈ·6••[¹i)ø7+Òü_s±œ”8 ‹U"$RAEŽß'“ÅåyWÌÏml/²{;!ˆ‚Êãî‘î-eµ dRºøÏ…Ñ0js>É.$U¬t¬o±ûûcü1=Ý¥Žä³ÈËsÞ$Cû´ñÙ-í¾ù‚{©ç.H!qÖØ[Ž—7²FµÞ+Ô£ÛG¶­p+æ¬Þ5¸|´øØî ºŠl°½²G#zZö¹…ÃÆiŠÕ¦­wW*›u¬ÑjÅÕz!ÕÑae.2—×]÷kbÛ²O%BælWvß’F…±¥®&ñÖÌí­qO‚*§¢ð±Ä35U)’QUM®†L¥SÀyƒÎížec9¯‹±ºÉââÇI½‚ÙåË"/|ÑMUP$yàÖŽâ[ëÛ>÷œÙÜ¿¿º‚Æý÷¬¼µ–wh…ò67Å#ètU àI=~$ñ…ƒÂ„u›–.ì³d_™âÙË6Ñbã IzA^m m…Å1)‘'#ؼo¤#-Ð\ªo,š‚ —µ"\îÜÙÞi\^mlV*öÇcÜ⮡¹¼¾·–ÞGK×—ûªÊêxb¼¸ŠÄDÇ=­|¥’Ê_Ý´çéi€‚iT–eçi5öwåû)ÍÓn6¼äø…´f£mæã¹ä!›@B¢æ]ŒŽK*î1ºÉ‡pšFH†(€˜–_–—ŸøœÌv×ÃÅ€ž7Î#y…²d"7J†¼‚ipqÇdqìåCùá'åâ{b/h•̰¶2u‚.€GJÊî.x{q™pÁ) –°¥¡(Ç„¬-)mdëù¥‡*Ös:ow´<«ak1eÝ8Ar´:®Û®¦DJªb>]ÊýЋrÛ^b³7vÏÝy²k;W\±Ò~e¦h:£–kš^LJðx-rß9ƒ´_¸äÁÏmÆ[ÎÍ¿f×Gs8ÁŸœ"Q¨QñÔ¹§I.ioÑÁ}–ötáÝ)ð-öíµæ,N°)1=™–îÀµ†¾hk ¡~ª›¢×i&_Gjá]ävR¹M@Hr7û'˜å†w5 ­Ì9¼þwï×1\Œ{ŸCj x÷ÎgŒö¶Žs Í/.rZn Í÷ŠÆKq˜¼F+î°ÝÈ+¼ ¨Ÿÿ;ÅkZÁÓG®ÔáªêɸÿˆHû»ŠÓKà v–µµ<0ë…¶ÖÞKá#‰L#XWåÁyc[¶™2ìcgCIÄ¿Ay3¶“z vÊ3F5NÐMNÌÊ%¿ºUÁëœÍ“#·9­·7·÷vFûogy†Î\HÇÈÒV6”/©új[Eç;;,×/ó[[ï–v™Y®m¥gÞel,sà]G;¦¦´„¶´«xG Ø¡€ýšÐãzÚA/bæ{îRøŠŽ$¬Ø·™­ V’7[yéVëQe)¬ì¨¦váÚDœµÔ~9ñß1¯>åw÷Kì=³-ŸÜÉ¢áíÇ9;N™\×ø…±—ïŠð]†å±_ ì»o¼Ûýâ×%;§oxÍP´Þ‡‡JÚÖ6–øÀ¼[Æ´â¹ÆcÁ66OâžïÌíx—áÌ0ãëýÑrÍ'”"qÃÅÇ(ÀeâÛ[)G³2ÎÌÉT£NÈ˵|c¦b*]á)pÛC|f¶×,-6t»spü^ËC fÍýÌxwvó1£ccuL$ |tp-4ä÷ÕÅç7ÝÆä7†øq÷bY÷–÷Œktëhˆq{Î’#,.kêÒǃ2â6ÃÊW¯´s!¹¸a-¦y79ÇŒ.9hØI[¡ÖöÄ X¸÷ë5púnJ&Ìͪ²fWtw„7†&åæwla¹y·ã·šæ\n\Kvèc|Œ„Êó4®{Ú#š$qkHmxt ‹xâ³¹=å˜|ÑAö4ÇnÙÖ>QDQ†µÄ=Ìc]¡µp&œzW G X¥À¾Í¸q½-0—±³5õ){Å ÇVtc¼Ô„«I©¦zM¼ÁÔX ”ÖvTS;pí "NZÌ¿›;瘷sºû¥îÙ–Ïî¤Ñpöã‹È¦’¹¯ñ c.!Þ)à±­ËbþÙvÿy·ûÅ®JwLÞñš¡i¼•µ¬m-ñ}oÊíë ã‰N:øÄILcFÀæO•¬ "örÅ’É;q…š´f·:NU‹ôE’‰qº¡?htÁ2”1J:–w¸­y!´\Üuì—ØŒ­ÕͳaÞ[?xüÉú{jS¨ÐHØ19|4üÔÜm7¶¬µÈãî­á™Ò7¹t’w%¿¶„5Ô š‘AR@]!ÁäCxl镸P».;~^ 7Ø·n*y?iJä¶¼#cœOÚwDDƒr¤Œ©¡ž´p“s @ á}  ÖëÍËÉ/6F+šx»yá¾ÂßA|اa†cÞ"žjYÞ5Í/®–ðêZ¿.­™mºoö üÑIk”´–ÔɻȄÍi’)XáÁÚpoV§q]OÆÞC‡½3Ü䦠}ÄQPøfÂA3&£tmüzÜÑ.‚¨ˆ¹AåÀ/WIR—C¢¡4­¯’ø ¼6Å‚÷*?úöZY2DÔ-ÑÖ* H-‹»ii<×U¯ó;/o“Ý’ÚãÿþÑ–pBvãA¡2k Ž–±,î õbÕçÕJU6ÔªªR©ÕÑS¤§TÀ§@ù¦‰Õ()·ÇJ€§T ¥IjuJU6ëPZR•Mº{•:JuL XTª)TÛãïÒÒT §UIjª¥:ê SªR©·ÇSBR•N­¡R˜)J¦Ý}ÚE¡:¥6éRZR‚•©Õ()·ÇS¥UR‚]êIÕ)Tëè© ER•MºT–ªªPSž¤µ:¥6õ Fš'T€§VФS›u¥@R›t©-N©ANº’ÔêÛ§wŠ µ:¥9ü”¨SªR©·]”¸u§T€¥-=‰Õ(mAjuHêÚ%©Õ (<úÔé¢u^ép>]lx!ç‰ÿÜGݯ˾`~þfÿkÞ~±"ûÿfþèb¿fÚþ‹Ð-ÀÛäþŠÔVȦàmòE_^.ï]Äïþ!sOúȹk÷?”ô§lÃØïÔá_–\ÂýþÎ~ؼýfEUèKOR„)B¡ P…(B”!J¥VR NªÀpðÒÒŽ à<ÃSDø…`6”QíWÒNƒ©\B*B°0éEPUÀãáå©Òš¸e" uWxjhª¸Ÿ’‘jÀÜÃRBªžµp8Ò⎀p¡>)ÜÃJ€¢¡\Î*)«ù‡«üTˆíN©üþJ’ÔÕÀüÃRZRƦˆ¨HŠ<)ñJšT¡0UÀáÏ¥IjuHš’ÔêúT–§T€q©¢*< @è¥áUT §]*U n4‹SªP??’ µ0RüÃRZRœõ4)Õ)TÛÕK‡ZuJ w-=‰Õ )·_v¤µ:¥:ª SªPR§JuHU6éîE/ iANà¥@˜=‰AMºôÔ–§T §UAjª¥:êt§T¥SnžçôT‘ÚR‚ÁJ0R‚›uéïÔ–¢«!¸ƒÏîóôž0’ym7¶ 0Õ•‡ÐI´š²…—mf¸šp”ê§U“!f»ñ™3p ŸfÚòh aű-²Vðܺädr÷ä–wfàF BŽv Þ_²(¶ýÝ»$Ý“XÍ$-ƒîXØm.Ö!/:Í@¡v¿³Æ”é+ ÁNºÞ‹V§T¥Wm*´ê”î šÁJU6ëîÔ–§T ¦Ý;¼U%©Õ()Q¦ ª˜ªíñÒ§juJ uyB•N«)pŸP2Ùœ{jb¦3£¶Ó‘vÎk}vJ¨{*"}ŠQÎÍ b DÆÝ©œ¼—¤‘Dʸ”S17ʧ˜ï>^ßïl”å2’7d1Ѿls``ûÄ‘8½½åήóº.Ò]‚š‡BÝëlï M­e,¶ ;¥Í{c½t¯=Ë$hiÑàƒdÔÕJPq˜W2‡1Îsç0œç9„Ç9Œ:˜Æ1„DÆ0Ž¢=ñ¯HîÃF(Ò5jx’® wN“ÔŠ¥zÈ4¨S›té¥@UU()ܨ)TÛ­Ijª¥*›tîæ¨ÒSª`S¯¢’uJU6øéi Õ()ÕPZR‚u©Õ)TÛãïTUU()ýaý“¯bb©·_v‘hN©J¦Ý* SªPR µ:¥*›z†• uíJ t‡”*hR•N¾ŠE¡0R•Mµ©Õ()RZª©J¦Ýz{õ4!:¥:CʨR‚{B§H= Õ()¶¤µ:¥;‚ µ0R•MºìšQ:¤:CËKÂS}¨ )¶¤µ:¥óÔ¦ B©Ì=CRZR‚ÁKŠuJU6ëÝã¥@RU%©Õ{¿ÀçÿÀÄñŸþAµ~[s÷÷9û^óõ‰èÌýÏÄþ͵ý •¨-•J¿\\ÿÞ»‰ßüBæŸõ‘r×î(ÿéNØÿ‡±ß©Â¿,¹…ûýœý±yúÌ‹«Ð–ž¥R„)B¡ P…(B”!J¥R„)B€ÃÓJ:«€vR¡B¾µ4N¤-@Â" ô«ûƒú)'NÅp0 ©*àna¢‰Ôp?8xªt¦¬ï *U CmMuV‡EN”ü ÜÃSDWµ\4qO‡R¸(OZ@8óøéPÀááä©Òš@0øZ’ª¸ŸÉS¥:¤ó I ×µ ž• +ØúQáOÂ×KObuH};¼U%©Õ |5Sª@>ßðT–§_­ (>TN©MºRð¦”×Jƒ©Hæ¡©-N©üþJ’Ôê”Ì5©Õ )J…:¥6øûµ¥@R‚]‹Sª@S¯¢ µ:¥6éRZª©JšS¡:¥*›ixQT §pTÐê”Û¯»RZR‚U%ªª”¨§buJU6øéSµ:¥:º)Pê”Û¯»RZR‚›tîñT§T€¥Nšt'TÅSoަ©Õ()Ò¨ uJ uôT–§T¥SmAjª¥;‚§IêN©Š¦Ýi'T¥SnžåMN©ANà©-L¥SmAjuJU:ªhUU)Tëò $Wð¦*›z†§H)Õ()ÕRZª©ANº‚ÔꔪmþŠ’ uJ w*&bb©·_ Ô–§T §UIjuJ sÔªªPSo»Zšꔪt‡”)Q:¦:ú*KSªR©¶¤µ:¥?¬* SªPSn½=úšR•MºyB‘:¥<[*KUU)TÛRZR‚]©Õ()Ð>í*R•MºtÔR‚”´ö'T¥SmAjuH wIjuL t»SBªB©·Nžõ/ uJ RÒ:“ªR©·»š µ:¤*KSªPSn½=ÚÔé¢u^õp5ËaÛÃÏ ÿ'µ¯Ë.a~ÿg?l^~³"ýÙŸ¹øŸÙ¶¿ bôµ²©BàK‹Ÿû×q;ÿˆ\Óþ².ZýÏåý)Ûðö;õ8Wå—0¿³Ÿ¶/?Y‘cÕzÓÔ¡ P…(B”!J¥R„)B¡ P…(B”!JµÔB„UX>ZZSVÔУÀ¯­*'R€Â‘PUÀô'CÔ®¡íVw†‘ ðêWó…-)ñWs I¨ª¸zii «Ã¢¤µ?¸jh{RèâW…$ëÚ=4i¯b¸:*t”ê<úÔ–§Up?UIjuìHæ’¯j@Sž—ëØÌ:QÀô¢½©üþJ)¤óPÔ–§T€~%IjuWó IjuíJ sÒ¡N© ~aÓgø©pëN©@üþJZ{ ˜uØ5%©Õ )ÕPZR‚›{½Ú’Ôê¥Å:¥6ëÝÏJH m÷*KUU()×ÑRZФ*›j UU()ÏJ…:¥6øûµ©§juJ utRÓTê”芒Ôê”ÛÝîT§T€¥MèN©Š¦ßv´©ÚR‚!ÑJ•N©AN¾Š‚ÔÁHU6Ô–§T ¥MRuL íצ¦©Õ)TÛ§”)iUR‚ÁRZ˜)J¦Ú‚ÔꔪuTЦ PS¯ÉSDꘪmêZjR‚ÁRZR•MºÔªªR©·Or¤‚R‚ŸÖ4ESM¾>ý"ÕUJ uT§T §]IjuJUvøêhSªPS«¢•ª¦:¤µJU6ÔªªPR§JuJU6ëÓß©¡N©J¦Ñ(R N©Nà©-L¥SmAjuH utT–ª1Tëò M *”ªmñÒ UT ¥IjuJU6ëPZR‚]%©Õ()×¶¦…:¥6øéP'T §=-=‰Õ()·Z‚Ôêêè¨-UT §_»J…J mñ÷iJ‰Õ()ÏS§±0W¾Ü ð »ÿDÿÉÍkò·˜_¿ùÏÛ¿¬È¿Aö_îv'öe¯è½­=lªP…øâçþõÜNÿâ4ÿ¬‹–¿sùGÿJvÇü=ŽýNùeÌ/ßìçí‹ÏÖdXõ^„´õ(B”!J¥R„)B¡ P…(B”!J¥R„)B¡ P…¨‡xh¢uVóÒÒŽ à` M < ÚÒ¢u*ÀqþºÀ«û»ô“ãÔ®¡íW=*ü àpðòRÒš¸˜jHíEUÀãáå©Òš¸9ütˆ)‚z•ÀÃSDTu«èL} Áà\¯j@8ôÒ-MX‹J*=5BuW‡E"ÔÁJzš'^Õp?=.)øù†—U ŸÉHµ:¤ó»¤µ:¤óÔéN©üÃRZRœô¸§^Ä¥So»Z\ª@?õ…-)Õ(nµ©Õ )ÕRZRÇž¦‰Ôx‚T¸õ¦”è%*U )·Nš’ÕUJçòT¦ B©¶¤µ:¥*hSªPSn½4¨ªPSnžå"Ôê”þ°¨-L…SmIjuJ TЧTÀ¦ÝziSµ:¥6éîTéªuH wIj`¥*›j UU()Ü4)‚˜ë¥DU()·Nš5U^Ô §pT–§T¥Snµ©Õ)Tê¥BR‚}4LÅSoŽ‘juH uTªª`S® µ:¥*»|t¨SªPS¸*hªb©·_v‘juJ mÒ µ:¥* SªR©·]ƒJŠª”é(TÐ'TÀ§_EIjuJU6øêKSªR©ÕÑPZ˜)ANò *'T¥SoPÔ¯jPS¸)§T¥Snµ©Õ)TÛ§¹PZª©N¾ŠTN©J¦Þ¡© 'T §U"Ôê”ë¨-N©J¦Ý=Ïè©-N©ANà©LÄ¥So¿J:¥:ªKSªPS® µUWÖÑ%]¹nÕ¹ ¢îVMS/(¨¢§ ßt®ŽFòÛa6Jõá–DéãÐÖ°|.Õ•¥ÅýäV6­/¹šF± t—8Ь•ú#àêXk>1±Š;­XµnSi  [·M ^PܯɌÖEÙŒÍÞ]⺺–b; ¯sÈÿÞ_¢Ø«&ã1–ØÖš¶Þãè¿äYÃXÅßR„/À—?÷®âwÿ¹§ýd\µûŸÊ?úS¶?áìwêp¯Ë.a~ÿg?l^~³"Ǫô%§©B¡ P…(B”!J¥R„)B¡ P…(B”!J¥R„)B¡ P…¨‡†Šê®ç©ÒŽ À`ð *#ˆVÖ•¯j¸—øp8PŽ!\„Tu«„6Ò 'àV‡EN’š¸˜iÚUÀüáS¥ÀÀ>I Ô«Ä)Q:„€zÇ©\ Ì4¸ëÚÏËHµ5p8xJ’T€qðòÔéM\útÔ–§R54N£ëH ñHÛ¯M*Ф‡E-)Õ yõ¨-N©üüžåIjª¤=MT€¥.)¥6ëÓJ:¤õR-N©@ýu%©Õ\Û¥AjuJ MªPSnÞ*<)¥óòûµ4I×± )·¨jKSª@SŸ’¤µ:¥*›u¨-N©ANª\SªPS iP'T ¦Ý:i§T §=Aj`¤*œÃ­AjuJ uR¡N©NºšêÛ§M"ÔëÚ”¨-UT¥Snµ%©Õ)Tê©¡LÀ§]*ꔪmñÔ–§T §UIjuJ uÔ§T¥SnžåI:¥;‚•uìJU6ëîÔ–§T §UIjª¦* SªR«·ÇSDê”êò…*ê˜ëè©-N© ¦ßAjuL wNžÅUJ ôjhŠ¥6éÓJUR‚ÁRZSMµ©Õ!Tê©ÒSª`S¯¢¦‰‚”ªíñÒ N©ANª’ÕUJ uÔ§T¥SnžçôTé)Õ()Ü“±1TÛ¯»S¤'T §UIjuJ uÔ§T…SoާJª§!Œs¥)Œs¥ „Æ0è DDDkŽI#Š7K+ƒbh$’@$’x:ÉàÆÇÈñ@¹î4 ’O@t•˜¼:`雎àa-$ÅRn*C3l¢c¼–ð€zBÅ÷ªGÞ”yKßJøŸæ´ÎBý™´åï1¥Ãï3´ø²i5î£=l¨«Ü8:šEZM~©å,.12·sî(ô_Só¸qeGûGŽ§ÓƒZx·í:”ýâëE;RÞhÐ8"@0né˺óxkåô:ìê¥_ŸÎ"ý’ØâïÉwæEޏr¡¥² åsß-‹1iŒci[²qôô‹xÄ~ÄúRè»~r¢EVYR¦(qÔÃõvÝþp¹™¶vý†Û°±Á>Çg ´n’£#£‚6ÄÂòÛÖ4¼µ€¸µ­Ö€ð,Ïòç²s™{¬ÕÝÖU·W—2ÎðÉmÃå{¤ph6Î! ¸†‚ç)ROŽÿ´%·óÎJúVØü£Yîk{¿oy ÏoXß– ƒé™+mìŠ~ЖßÏ9+é[cò;ÜÖ÷~ÞòžÞ– ƒé™+mìŠ~ЖßÏ9+é[cò;ÜÖ÷~ÞòžÞ– ƒé™+mìŠ~ЖßÏ9+é[cò;ÜÖ÷~ÞòžÞ– ƒé™+mìŠ~ЖßÏ9+é[cò;ÜÖ÷~ÞòžÞ– ƒé™+mìŠ~ЖßÏ9+é[cò;ÜÖ÷~ÞòžÞ– ƒé™+mìŠ~ЖßÏ9+é[cò;ÜÖ÷~ÞòžÞ– ƒé™+mìŠ~ЖßÏ9+é[cò;ÜÖ÷~ÞòžÞ– ƒé™+mìŠ~ЖßÏ9+é[cò;ÜÖ÷~ÞòžÞ– ƒé™+mìŠ~ЖßÏ9+é[cò;ÜÖ÷~ÞòžÞ– ƒé™+mìŠ~ЖßÏ9+é[cò;ÜÖ÷~ÞòžÞ– ƒé™+mìŠ~ЖßÏ9+é[cò;ÜÖ÷~ÞòžÞ– ƒé™+mìŠ~ЖßÏ9+é[cò;ÜÖ÷~ÞòžÞ– ƒé™+mìŠ~ЖßÏ9+é[cò;ÜÖ÷~ÞòžÞ– ƒé™+mìŠ~ЖßÏ9+é[cò;ÜÖ÷~ÞòžÞ– ƒé™+mìŠ~ЖßÏ9+é[cò;ÜÖ÷~ÞòžÞ– ƒé™+mìŠ~ЖßÏ9+é[cò;ÜÖ÷~ÞòžÞ– ƒé™+mìŠ~ЖßÏ9+é[cò;ÜÖ÷~ÞòžÞ– ƒé™+mìŠ~ЖßÏ9+é[cò;ÜÖ÷~ÞòžÞ– ƒé™+mìŠ~ЖßÏ9+é[cò;ÜÖ÷~ÞòžÞ– ƒé™+mìŠ~ЖßÏ9+é[cò;ÜÖ÷~ÞòžÞ– ƒé™+mìŠ~ЖßÏ9+é[cò;ÜÖ÷~ÞòžÞ– ƒé™+mìŠ~ЖßÏ9+é[cò;¼Ö÷~ÞòžÞ– ƒé™+mìŠÁ솷ûç%})l~Q£çwšÞïÛÞBóÛÓù`Ø>™˜ò¶Þȵý¡íÏž2OÒ–Çå*_;œÖ÷~ÞòžÞ—ËÁôÌÇ•¶öE?h{s眓ô¥±ùJÎk{¿oy ÏoOåƒ`ÿy˜ò¶Þȵý¢-ÐþùÉ?J[”©|íó[Ýû{È^{z,;ÒòþVßÙU¿h«{猓ô¥±ùJŸÎç5½ß·¼…ç·¥òÁ°}31åm½•kûEÛßXv¥åü­¿²«~ÑÖÿÏ#éKgò/®jû¿oy ÏnGËÂôÌÇ•¶öU¯íoüï‘þ”¶)ÑóµÍ_wíï!yíÈùbØ^—˜ò¶þʵd„|d¥-ŸÊt¾vy©îý½ä/=¹?–-…éy+oì«_ÚFç|ôµùR—ÎÇ5=ß·ü…ç·%òŰ½//åmý•kûI@ü“¶¿*Qó¯ÍOwíÿ!yíÉü±ì/KËù[eVd¤{äo¤í¯Ê”|ëóSÝûÈ^{r>Xö¥åü­¿²­iX/ò/Òv×åJ>uù©îý¿ä/=¹?–=…éy+oì«PöKÁ‡z_"ý'm~U¥ó¯ÍOwíÿ!yíÈùcØ^——ò¶þÊ­ûLAüí‘>“¶ÿ*Ñó­Í?wíÿ!yíÈùdØ~——ò¶þÊ {&¡½-‘>“¶ÿ*ÒùÕæŸ»öÿ¼öäþY6¥åü­¿²«~ÓpŸ;d?¤­¿ÊÔ¾u9§èÈ]ûr>Y6¥åü­¿²­iØ_²ÒVßåj_:|Òô ¿ä.ý¹,ÛÒòþVßÙUƒÙ? ÞÙé+sòµ:|Óô »öä|²ì?KËù[eZþÔß:ä/¤­ÏÊô|éóKÐ6ÿ»öäþY¶¥åü­¿²«²Š?½rôÉ[Ÿ•é|ésKÐ6ÿ»öä|³l?KËù[eZþÔpÿ:䤭ßÊô|ésKÐ0BïÛ‘òϱ=//åmý•[ö¥ˆù× þñ·+ÒùÐæ `<…ß·#åŸaú^_ÊÛû*×ö§‰ùÓ }#nþX¥ó¡Í@Ày ¿nOåŸbz^_ÊÛû*°{*bƒûÓ }#nþX£ç?š>€ò~Ü–}‰éy+oìªßµTWΗÿÒ6÷åš>sù£è!wíÉü´lOKËù[eVý«bþt¿‡ÿxÛß–i|çsCÐ0BïÛ‘òѱ=//åmý•jÊèÀïIßßHÛß–i|æóCÐ0BïÛ‘òÓ±}//åmý•[ö°ŒùÎýúBßüµKç3š€ò~ÜŸËNÅô¼·•·öU¨{,£CûÎýúBßüµKç/™þ€ò~Ü–­‹éyo+oìªßµ¤wÎWçÒÿåª>rùŸè!wí¨ùjؾ—–ò¶þʬËhðïI_ŸH[ÿ–èùËæyÿö!wí©üµl_KËy[eZþÖñÿ9_H@~[¥ó•Ìÿ@Àù ¿mGË^Åô¼·•·öU`ö]0ï+ìz_À~[¥ó“Ìï@Àù ¿mOå¯bú^[ÊÛû*·ívÄ?¼o¯ãà?.RùÈæw `|…ß¶£å³cz^[ÊÛû*°{/™÷óü|åÊ_8üÎô‘»öÔ|¶loKËy[eVf0ïHß?ÇÀþ]£ç™Þò~ÚŸËnÆô¼·•·öU¯í„Ïç ãøøË´¾q¹›è8#wí¨ùmØÞ—–ò¶þʬÌFýá|u¿‚ü»GÎ/3}änýµ?–Ýéyo+oìªß¶3_œ/ã ¿/RùÄæg à¼ß¶£å»cú^[ÊÛû*°{2÷…ïütåê_8|Ìô‘»öÔ|·lKËy[eVfSpïH^ßÇAþ_£ç™žƒ‚ò7^ÚŸË~Çô¬·•·öUoÛ1¿ú}ëütåú_8\Ìô‘ºöÔ|·ìKËy[eVfrþzõ½ƒü¿Kç™~ƒ‚ò7^ڟˆÇô¬¯•·öU¯í úuéül'Ô¾p9—è8/#uí¨ùpÙ—•ò¶þʬÍ$ƒüúóþ6ê _7üÊô‘ºöÔ|¸ìJÊù[fVf¢aÞ}yÿ õ 7üÊô‘ºöÔþ\vG¥e|­¿³+~ÚÉÿ¦Þ_ÆÂýCKæû™^ƒƒò7^Ú—‘éY_+oìÊÁìÙ žÞ?ÆBýEKæ÷™>ƒƒò7^ÚŸË–Èô¬¯•·öe`öm”?Ïoã!~¢¥óyÌŸAÁù¯lGËžÈô¬¯•·öeoÛt?Ó/ã!¾¢¥ówÌŸAÁù¯lOåÏdúVWÊÛû2°{7ôÿ<¼:ÞC}GGÍß2}än½±.{'Ò²¾VßÙ•¿nóË¿øÈ¨èùºæG àü×¶#åÓdúVWÊÛû2·íÈoôË»ø¸©*~ny‘è8?#uí‰üºlŸJÊùX=™jÎSùåÝü\?Ô”|ÜsÐp~FëÛòë²}++å öeoÛ ÿéwoñqRÒù·æ?¡a<×¶'òí²}++å öepöu(çw`ô»ˆú–›~cúÈÝ{b>]¶O¥e|¤̵gb¡Þwvõ-/›ncúÈÝ{b.Û+Ò²žRfVý»–ÿJºÿЉúš—ͯ1½ än½±.û+Ò²žRfVgŠáþuuõ5/›>czÈÝ{b>]öW¥e<¤̬Ï5üêêþ*'êz_6|Æô,'‘ºöÄþ^6W¥e<¤Ì­ûz¸ÿIºŠŠúž›>czÈÝ{b>^6W¥e<¤̬Ïw!þstõE/›búÈÝ{b/;/Ò²žRfVý¾]¤]ÄÅ}QKæÃ˜¾……ò7^Ø——éYO)³+~ßnÿÒ.âbþ¨¥ó_ÌOBÂùŸlGËÖËô¬§”ƒÙ•ƒÙúð;Î.âbþ©¥ó_ÌOBÂùŸlOåëeúVSÊAìÊßõyÿŸ¹¿‰ŒúªšîbzÈÜûb>^ö_¥e<¤̬=÷û—ø˜Ïª©|Öóа¾FçÛù{Ùž•”ò{2°pø?ßîOâ#>ª¥óYÌ?BÂùŸkGËæÌô¬§”ƒÙ•¿ê ÿÿ=rõ]/š¾aúÈÜûZ/›3Ò²žRfV$ýþãëqõ]5|Ãô<7‘¹ö´|¾lÏIÉùH=™[þ¡R!ÞZãþ"7êÊ>j¹…èX_#síhù}Ùž•”ò{2dx ß.ò—Ã^Rv;¢ÃÙÇÚu…qKüÓsF6×Çë6Š«§ äùÙlxs§É8£,4>0ø]÷øB9Ê ž0©¨Q.ó‡w<ÂUŠ[Þ&è5yVëæ†ùÞŒ0g²¾Èš÷, Š/¢¬Œ4>FMdv¯AÛÛ iíw qq²è w®¬’}4{Ë‹kÖ¤} Ѽk†!,–艧۔¥ÔÛ…×PþºsÖ€·Þ…)HP)C@Є+P…(Bø|]¯ü'Ñ÷¿ûÍ5¡ æùÔüÚ§Èž§æÐ…>Dõ?6„)ò'©ù´!O‘=OÍ¡ |‰ê~mSäOSóhBŸ"zŸ›BùÔüÚ§Èž§æÐ…>Dõ?6„)ò'©ù´!O‘=OÍ¡ |‰ê~mSäOSóhBŸ"zŸ›BùÔüÚ§Èž§æÐ…>Dõ?6„)ò'©ù´!O‘=OÍ¡ |‰ê~mSäOSóhBŸ"zŸ›BùÔüÚ§Èž§æÐ…>Dõ?6„)ò'©ù´!O‘=OÍ¡ |‰ê~mSäOSóhBŸ"zŸ›BùÔüÚ§Èž§æÐ…>Dõ?6„)ò'©ù´!O‘=OÍ¡ |‰ê~mSäOSóhBŸ"zŸ›BùÔüÚ§Èž§æÐ…>Dõ?6„)ò'©ù´!O‘=OÍ¡ |‰ê~mSäOSóhBŸ"zŸ›BùÔüÚ§Èž§æÐ…>Dõ?6„)ò'©ù´!O‘=OÍ¡ |‰ê~mSäOSóhBŸ"zŸ›BùÔüÚ§Èž§æÐ…>Dõ?6„)ò'©ù´!O‘=OÍ¡ |‰ê~mSäOSóhBŸ"zŸ›BùÔüÚ§Èž§æÐ…>Dõ?6„)ò'©ù´!O‘=OÍ¡ |‰ê~mSäOSóhBŸ"zŸ›BùÔüÚ§Èž§æÐ…>Dõ?6„)ò'©ù´!O‘=OÍ¡ |‰ê~mSäOSóhBŸ"zŸ›BùÔüÚ§Èž§æÐ…>Dõ?6„)ò'©ù´!O‘=OÍ¡ |‰ê~mSäOSóhBŸ"zŸ›BùÔüÚ§Èž§æÐ…>Dõ?6„)ò'©ù´!O‘=OÍ¡ |‰ê~mSäOSóhBŸ"zŸ›BùÔüÚ¾ô=Oì; ?û¿à¡ é¡ P…(B”!ÿÙopenchange-2.0/doc/doxygen/pictures/middle_bg.jpg000066400000000000000000000005251223057412600221560ustar00rootroot00000000000000ÿØÿàJFIFddÿìDuckydÿîAdobedÀÿÛ„ÿÀdÿÄU Q¡Ña‘ÿÚ ?ßÀ#¿ªÚ0 ïæ¶œ ‡3Yû žñݲ ?ÿÙopenchange-2.0/doc/doxygen/pictures/nav_tab.gif000066400000000000000000000014541223057412600216510ustar00rootroot00000000000000GIF89aPæïïïþþþýþýûüúõ÷óñôïøú÷ýýüúûù÷ùöôöòöøõïóíðôîóöñùúøüýûòõðïòìîòëíñëòõïõõõÿÿÿúúúîòìðóîêëéðððôôôñññýýýñôðÆÉÅìîëÇÊÆÈÊÆÏÏÎÇÊÅËÍÊêìéïóîçèæÎÏÍÐÐÐõ÷ôÊÍÉïñíÆÈÄÊÌÊêêéïóìüýüÊËÉÏÏÏèêçÕ×ÓüüûÍÎÌëíêÌÍËíñêÏÐÏùûøêëêòöðóõñÉÊÇñôîîñì!ù,Pÿ€ˆ‰Š‹ŒŽ‘ˆ‚@;/Ÿ ¡¢£¤¥¦§¨E(ƒ )·¸¹º»¼½¾¿À¸ 7„23ËÌÍÎÏÐÑÒÓÔÐ=*"DÝÞßàáâãäåæä8 îïðñòóôõö÷õ.A þÿ H° ÁƒM R ¡Ã‡#JœH±¢ÅŠ0)ˆÀ±£Ç CŠI²$Ɉ8Xɲ¥Ë—0cÊœIsæD-èÜɳ§ÏŸ@ƒ *”¢’*]Ê´©Ó§P£J:Q‚X³jÝʵ«×¯`­È@‚³hÓª]˶­Û·p‰ßÆ@ôÀݻxóêÝË·¯ß¿~O Bð °áÈ+^̸±ãÆ< @@¹²å˘3kÞ̹3gˆr Mº´éÓ¨S«^Ízõ D4 ÈžM»¶íÛ¸sëÞ­»¢Àƒ N¼¸ñãÈ“'·H€óçУKŸN½ºõë×} À½»÷ïàËO¾|y;openchange-2.0/doc/doxygen/pictures/pixel_grey.gif000066400000000000000000000000531223057412600224000ustar00rootroot00000000000000GIF89a€îîî!ù,D;openchange-2.0/doc/examples/000077500000000000000000000000001223057412600160475ustar00rootroot00000000000000openchange-2.0/doc/examples/Makefile000066400000000000000000000012601223057412600175060ustar00rootroot00000000000000all: fetchappointment \ fetchmail \ mapi_sample1 \ multiple_notif \ fetch_addressbook clean: rm -f fetch_addressbook fetchappointment fetchmail mapi_sample1 multiple_notif fetchappointment: gcc fetchappointment.c -o fetchappointment `pkg-config libmapi --cflags --libs` fetchmail: gcc fetchmail.c -o fetchmail `pkg-config libmapi --cflags --libs` mapi_sample1: gcc mapi_sample1.c -o mapi_sample1 `pkg-config libmapi --cflags --libs` multiple_notif: gcc multiple_notif.c -o multiple_notif `pkg-config libmapi --cflags --libs` -lpthread -lpopt fetch_addressbook: fetch_addressbook.c gcc fetch_addressbook.c -o fetch_addressbook `pkg-config libmapi --cflags --libs` openchange-2.0/doc/examples/fetch_addressbook.c000066400000000000000000000060331223057412600216660ustar00rootroot00000000000000#include #define DEFAULT_PROFDB "%s/.openchange/profiles.ldb" int main(int argc, char *argv[]) { enum MAPISTATUS retval; struct mapi_context *mapi_ctx; TALLOC_CTX *mem_ctx; struct mapi_session *session = NULL; struct SPropTagArray *SPropTagArray; struct PropertyRowSet_r *srowset; mapi_id_t id_inbox; mapi_id_t *fid, *mid; char *profname; char *profdb; uint32_t i; uint32_t count = 1000; struct nspi_context *nspi_ctx = NULL; struct PropertyTagArray_r *MIds = NULL; struct PropertyValue_r *lpProp = NULL; struct Restriction_r Filter; mem_ctx = talloc_named(NULL, 0, "fetch_addressbook"); /* Initialize MAPI */ profdb = talloc_asprintf(mem_ctx, DEFAULT_PROFDB, getenv("HOME")); retval = MAPIInitialize(&mapi_ctx, profdb); MAPI_RETVAL_IF(retval, retval, NULL); /* Find Default Profile */ retval = GetDefaultProfile(mapi_ctx, &profname); MAPI_RETVAL_IF(retval, retval, NULL); /* Set up some debugging if you want to see more details */ /* SetMAPIDumpData(mapi_ctx, true); */ /* SetMAPIDebugLevel(mapi_ctx, 6); */ /* Log on EMSMDB and NSPI */ retval = MapiLogonEx(mapi_ctx, &session, profname, NULL); MAPI_RETVAL_IF(retval, retval, NULL); nspi_ctx = (struct nspi_context *)session->nspi->ctx; nspi_ctx->pStat->CurrentRec = 0; nspi_ctx->pStat->Delta = 0; nspi_ctx->pStat->NumPos = 0; nspi_ctx->pStat->TotalRecs = 0xffffffff; srowset = talloc_zero(mem_ctx, struct PropertyRowSet_r); /* build the filter - in this case, display names that start with the command line argument, or a default of "te". case insensitive match) */ lpProp = talloc_zero(mem_ctx, struct PropertyValue_r); lpProp->ulPropTag = PR_DISPLAY_NAME_UNICODE; lpProp->dwAlignPad = 0; if (argc > 1) { lpProp->value.lpszW = argv[1]; } else { lpProp->value.lpszW = "te"; } Filter.rt = RES_CONTENT; Filter.res.resContent.ulFuzzyLevel = (FL_LOOSE << 16) | FL_PREFIX; Filter.res.resContent.ulPropTag = PR_DISPLAY_NAME_UNICODE; Filter.res.resContent.lpProp = lpProp; /* construct an explicit table */ MIds = talloc_zero(mem_ctx, struct PropertyTagArray_r); retval = nspi_GetMatches(nspi_ctx, mem_ctx, NULL, &Filter, 5000, &srowset, &MIds); MAPI_RETVAL_IF(retval, retval, NULL); /* fetch the contents of the explicit table */ SPropTagArray = set_SPropTagArray(mem_ctx, 0xc, PR_INSTANCE_KEY, PR_ENTRYID, PR_DISPLAY_NAME_UNICODE, PR_EMAIL_ADDRESS_UNICODE, PR_DISPLAY_TYPE, PR_OBJECT_TYPE, PR_ADDRTYPE_UNICODE, PR_OFFICE_TELEPHONE_NUMBER_UNICODE, PR_OFFICE_LOCATION_UNICODE, PR_TITLE_UNICODE, PR_COMPANY_NAME_UNICODE, PR_ACCOUNT_UNICODE); retval = nspi_QueryRows(nspi_ctx, mem_ctx, SPropTagArray, MIds, count, &srowset); MAPI_RETVAL_IF(retval, retval, NULL); /* Show the contents */ for (i = 0; i < srowset->cRows; ++i) { mapidump_PAB_entry(&srowset->aRow[i]); } /* Uninitialize MAPI */ MAPIUninitialize(mapi_ctx); talloc_free(mem_ctx); return 0; } openchange-2.0/doc/examples/fetchappointment.c000066400000000000000000000070421223057412600215660ustar00rootroot00000000000000#include #define DEFAULT_PROFDB "%s/.openchange/profiles.ldb" int main(int argc, char *argv[]) { enum MAPISTATUS retval; struct mapi_context *mapi_ctx; TALLOC_CTX *mem_ctx; struct mapi_session *session = NULL; mapi_object_t obj_store; mapi_object_t obj_folder; mapi_object_t obj_table; mapi_object_t obj_message; struct mapi_SPropValue_array props_all; struct SRowSet rowset; struct SPropTagArray *SPropTagArray; mapi_id_t id_inbox; mapi_id_t *fid, *mid; char *profname; char *profdb; uint32_t Numerator; uint32_t Denominator; uint32_t i; mem_ctx = talloc_named(NULL, 0, "fetchappointment"); /* Initialize MAPI */ profdb = talloc_asprintf(mem_ctx, DEFAULT_PROFDB, getenv("HOME")); retval = MAPIInitialize(&mapi_ctx, profdb); MAPI_RETVAL_IF(retval, retval, NULL); /* Find Default Profile */ retval = GetDefaultProfile(mapi_ctx, &profname); MAPI_RETVAL_IF(retval, retval, NULL); /* Log on EMSMDB and NSPI */ retval = MapiLogonEx(mapi_ctx, &session, profname, NULL); MAPI_RETVAL_IF(retval, retval, NULL); /* Open Message Store */ mapi_object_init(&obj_store); retval = OpenMsgStore(session, &obj_store); MAPI_RETVAL_IF(retval, retval, NULL); /* Find Inbox default folder */ retval = GetDefaultFolder(&obj_store, &id_inbox, olFolderCalendar); MAPI_RETVAL_IF(retval, retval, NULL); /* Open Inbox folder */ mapi_object_init(&obj_folder); retval = OpenFolder(&obj_store, id_inbox, &obj_folder); MAPI_RETVAL_IF(retval, retval, NULL); /* Retrieve Inbox content table */ mapi_object_init(&obj_table); retval = GetContentsTable(&obj_folder, &obj_table, 0x0, NULL); MAPI_RETVAL_IF(retval, retval, NULL); /* Create the MAPI table view */ SPropTagArray = set_SPropTagArray(mem_ctx, 0x2, PR_FID, PR_MID); retval = SetColumns(&obj_table, SPropTagArray); MAPIFreeBuffer(SPropTagArray); MAPI_RETVAL_IF(retval, retval, mem_ctx); /* Get current cursor position */ retval = QueryPosition(&obj_table, &Numerator, &Denominator); MAPI_RETVAL_IF(retval, retval, NULL); /* Iterate through rows */ while ((retval = QueryRows(&obj_table, Denominator, TBL_ADVANCE, &rowset)) != -1 && rowset.cRows) { for (i = 0; i < rowset.cRows; i++) { fid = (mapi_id_t *)find_SPropValue_data(&(rowset.aRow[i]), PR_FID); mid = (mapi_id_t *)find_SPropValue_data(&(rowset.aRow[i]), PR_MID); mapi_object_init(&obj_message); retval = OpenMessage(&obj_store, *fid, *mid, &obj_message, 0x0); if (retval != MAPI_E_NOT_FOUND) { retval = GetPropsAll(&obj_message, MAPI_UNICODE, &props_all); mapidump_appointment(&props_all, NULL); mapi_object_release(&obj_message); } } } /* Release MAPI objects */ mapi_object_release(&obj_table); mapi_object_release(&obj_folder); Logoff(&obj_store); /* Uninitialize MAPI */ MAPIUninitialize(mapi_ctx); talloc_free(mem_ctx); return (0); } openchange-2.0/doc/examples/fetchmail.c000066400000000000000000000071371223057412600201570ustar00rootroot00000000000000#include #define DEFAULT_PROFDB "%s/.openchange/profiles.ldb" int main(int argc, char *argv[]) { enum MAPISTATUS retval; struct mapi_context *mapi_ctx; TALLOC_CTX *mem_ctx; struct mapi_session *session = NULL; mapi_object_t obj_store; mapi_object_t obj_folder; mapi_object_t obj_table; mapi_object_t obj_message; struct mapi_SPropValue_array props_all; struct SRowSet rowset; struct SPropTagArray *SPropTagArray; mapi_id_t id_inbox; mapi_id_t *fid, *mid; char *profname; char *profdb; uint32_t Numerator; uint32_t Denominator; uint32_t i; mem_ctx = talloc_named(NULL, 0, "fetchmail"); /* Initialize MAPI */ profdb = talloc_asprintf(mem_ctx, DEFAULT_PROFDB, getenv("HOME")); retval = MAPIInitialize(&mapi_ctx, profdb); MAPI_RETVAL_IF(retval, retval, mem_ctx); /* Find Default Profile */ retval = GetDefaultProfile(mapi_ctx, &profname); MAPI_RETVAL_IF(retval, retval, mem_ctx); /* Log on EMSMDB and NSPI */ retval = MapiLogonEx(mapi_ctx, &session, profname, NULL); MAPI_RETVAL_IF(retval, retval, mem_ctx); /* Open Message Store */ mapi_object_init(&obj_store); retval = OpenMsgStore(session, &obj_store); MAPI_RETVAL_IF(retval, retval, mem_ctx); /* Find Inbox default folder */ retval = GetDefaultFolder(&obj_store, &id_inbox, olFolderInbox); MAPI_RETVAL_IF(retval, retval, mem_ctx); /* Open Inbox folder */ mapi_object_init(&obj_folder); retval = OpenFolder(&obj_store, id_inbox, &obj_folder); MAPI_RETVAL_IF(retval, retval, mem_ctx); /* Retrieve Inbox content table */ mapi_object_init(&obj_table); retval = GetContentsTable(&obj_folder, &obj_table, 0x0, NULL); MAPI_RETVAL_IF(retval, retval, mem_ctx); /* Create the MAPI table view */ SPropTagArray = set_SPropTagArray(mem_ctx, 0x2, PR_FID, PR_MID); retval = SetColumns(&obj_table, SPropTagArray); MAPIFreeBuffer(SPropTagArray); MAPI_RETVAL_IF(retval, retval, mem_ctx); talloc_free(mem_ctx); /* Get current cursor position */ retval = QueryPosition(&obj_table, &Numerator, &Denominator); MAPI_RETVAL_IF(retval, retval, mem_ctx); /* Iterate through rows */ while ((retval = QueryRows(&obj_table, Denominator, TBL_ADVANCE, &rowset)) != -1 && rowset.cRows) { for (i = 0; i < rowset.cRows; i++) { fid = (mapi_id_t *)find_SPropValue_data(&(rowset.aRow[i]), PR_FID); mid = (mapi_id_t *)find_SPropValue_data(&(rowset.aRow[i]), PR_MID); mapi_object_init(&obj_message); retval = OpenMessage(&obj_store, *fid, *mid, &obj_message, 0x0); if (retval != MAPI_E_NOT_FOUND) { retval = GetPropsAll(&obj_message, MAPI_UNICODE, &props_all); mapidump_message(&props_all, NULL, &obj_message); mapi_object_release(&obj_message); } } } /* Release MAPI objects */ mapi_object_release(&obj_table); mapi_object_release(&obj_folder); Logoff(&obj_store); /* Uninitialize MAPI */ MAPIUninitialize(mapi_ctx); return (0); } openchange-2.0/doc/examples/mapi_sample1.c000066400000000000000000000020431223057412600205620ustar00rootroot00000000000000#include #define DEFAULT_PROFDB_PATH "%s/.openchange/profiles.ldb" int main(int argc, char *argv[]) { TALLOC_CTX *mem_ctx; struct mapi_context *mapi_ctx; enum MAPISTATUS retval; struct mapi_session *session = NULL; char *profdb; char *profname; mem_ctx = talloc_named(NULL, 0, "mapi_sample1"); profdb = talloc_asprintf(mem_ctx, DEFAULT_PROFDB_PATH, getenv("HOME")); retval = MAPIInitialize(&mapi_ctx, profdb); mapi_errstr("MAPIInitialize", GetLastError()); if (retval != MAPI_E_SUCCESS) return -1; retval = GetDefaultProfile(mapi_ctx, &profname); mapi_errstr("GetDefaultProfile", GetLastError()); if (retval != MAPI_E_SUCCESS) return -1; retval = MapiLogonEx(mapi_ctx, &session, profname, NULL); mapi_errstr("MapiLogonEx", GetLastError()); if (retval != MAPI_E_SUCCESS) return -1; MAPIUninitialize(mapi_ctx); talloc_free(mem_ctx); return 0; } openchange-2.0/doc/examples/multiple_notif.c000066400000000000000000000133731223057412600212540ustar00rootroot00000000000000/* Stand-alone MAPI application OpenChange Project Copyright (C) Julien Kerihuel 2010 This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see . */ /* This sample code shows how to use multiple sessions in OpenChange and shows notification system works with multiple sessions. To use this sample code, run in the console: ./multiple_notification --profileA=XXX --profileB=YYY Send an email using any MAPI compliant client (openchangeclient for example) to recipients matching profileA and profileB. If everything works properly, you should see the output above: $ ./multiple_notification --profileA=XXX --profileB=YYY profileA: New mail Received profileB: New mail received For further example on how to retrieve and analyse */ #include #include #include #define DEFAULT_PROFDB "%s/.openchange/profiles.ldb" static int callback(uint16_t NotificationType, void *NotificationData, void *private_data) { switch (NotificationType) { case fnevNewMail: case fnevNewMail|fnevMbit: DEBUG(0, ("%s: New mail Received\n", (const char *)private_data)); break; default: break; } return (0); } void *monitor(void *val) { enum MAPISTATUS retval; mapi_object_t *obj_store; obj_store = (mapi_object_t *) val; retval = MonitorNotification(mapi_object_get_session(obj_store), (void *)obj_store, NULL); if (retval != MAPI_E_SUCCESS) { mapi_errstr("MonitorNotification", GetLastError()); pthread_exit(NULL); } } int main(int ac, const char *av[]) { enum MAPISTATUS retval; TALLOC_CTX *mem_ctx; struct mapi_context *mapi_ctx; struct mapi_session *sessionA = NULL; struct mapi_session *sessionB = NULL; mapi_object_t obj_storeA; mapi_object_t obj_storeB; uint32_t ulConnectionA; uint32_t ulConnectionB; poptContext pc; int opt; const char *opt_profdb = NULL; const char *profileA = NULL; const char *profileB = NULL; pthread_t pthreadA; pthread_t pthreadB; enum { OPT_PROFILE_DB=1000, OPT_PROFILEA, OPT_PROFILEB }; struct poptOption long_options[] = { POPT_AUTOHELP {"database", 0, POPT_ARG_STRING, NULL, OPT_PROFILE_DB, "set the profile database path", NULL}, {"profileA", 0, POPT_ARG_STRING, NULL, OPT_PROFILEA, "profile A", NULL}, {"profileB", 0, POPT_ARG_STRING, NULL, OPT_PROFILEB, "profile B", NULL}, {NULL, 0, 0, NULL, 0, NULL, NULL} }; /* Step 1. Retrieve and parse command line options */ mem_ctx = talloc_named(NULL, 0, "multiple_notif"); pc = poptGetContext("multiple_notif", ac, av, long_options, 0); while ((opt = poptGetNextOpt(pc)) != -1) { switch (opt) { case OPT_PROFILE_DB: opt_profdb = poptGetOptArg(pc); break; case OPT_PROFILEA: profileA = poptGetOptArg(pc); break; case OPT_PROFILEB: profileB = poptGetOptArg(pc); break; } } if (!opt_profdb) { opt_profdb = talloc_asprintf(mem_ctx, DEFAULT_PROFDB, getenv("HOME")); } if (!profileA || !profileB) { printf("You need to specify 2 profiles (--profileA and --profileB options\n"); exit (1); } /* Step 2. Initialize MAPI subsystem */ retval = MAPIInitialize(&mapi_ctx, opt_profdb); if (retval != MAPI_E_SUCCESS) { mapi_errstr("MAPIInitialize", GetLastError()); exit (1); } retval = MapiLogonEx(mapi_ctx, &sessionA, profileA, NULL); if (retval != MAPI_E_SUCCESS) { mapi_errstr("MapiLogonEx for profileA", GetLastError()); exit (1); } retval = MapiLogonEx(mapi_ctx, &sessionB, profileB, NULL); if (retval != MAPI_E_SUCCESS) { mapi_errstr("MapiLogonEx for profileB", GetLastError()); exit (1); } /* Step 3. Open the stores */ mapi_object_init(&obj_storeA); retval = OpenMsgStore(sessionA, &obj_storeA); if (retval != MAPI_E_SUCCESS) { mapi_errstr("OpenMsgStore profileA", GetLastError()); exit (1); } mapi_object_init(&obj_storeB); retval = OpenMsgStore(sessionB, &obj_storeB); if (retval != MAPI_E_SUCCESS) { mapi_errstr("OpenMsgStore profileB", GetLastError()); exit (1); } /* Step 4. Register for notifications */ retval = RegisterNotification(sessionA); if (retval != MAPI_E_SUCCESS) { mapi_errstr("RegisterNotification profileA", GetLastError()); exit (1); } retval = RegisterNotification(sessionB); if (retval != MAPI_E_SUCCESS) { mapi_errstr("RegisterNotification profileB", GetLastError()); exit (1); } /* Step 5. Subscribe for newmail notifications */ retval = Subscribe(&obj_storeA, &ulConnectionA, fnevNewMail, true, (mapi_notify_callback_t)callback, (void *) "profileA"); if (retval != MAPI_E_SUCCESS) { mapi_errstr("Subscribe profileA", GetLastError()); exit (1); } retval = Subscribe(&obj_storeB, &ulConnectionB, fnevNewMail, true, (mapi_notify_callback_t)callback, (void *) "profileB"); if (retval != MAPI_E_SUCCESS) { mapi_errstr("Subscribe profileB", GetLastError()); exit (1); } /* Step 6. Create threads A and B and wait for notifications */ if (pthread_create(&pthreadA, NULL, monitor, (void *)&obj_storeA)) { mapi_errstr("Thread creation for profile A failed", GetLastError()); exit (1); } if (pthread_create(&pthreadB, NULL, monitor, (void *)&obj_storeB)) { mapi_errstr("Thread creation for profile B failed", GetLastError()); exit (1); } sleep(200); pthread_exit(NULL); MAPIUninitialize(mapi_ctx); return 0; } openchange-2.0/doc/howto.txt000066400000000000000000000320601223057412600161330ustar00rootroot00000000000000Copyright 2005-2010 OpenChange Project under the terms at http://creativecommons.org/licenses/by-sa/3.0/ OpenChange developer howto -------------------------- == Updated in May 2010 == ############### [0x0] CONTENTS ############### +------------------------------------+ [0x1] INTRODUCTION [0x1a] What is OpenChange? [0x1b] What is libmapi? [0x2] INSTALLATION [0x2a] Samba4 installation [0x2b] Requirements [0x2c] OpenChange installation [0x3] POST INSTALLATION [0x3a] Create a profile store [0x3b] Create a profile [0x3c] Test the profile [0x4] USING LIBMAPI [0x4a] Doxygen [0x4b] Sample applications [0x4c] External resources [0x5] OPENCHANGE SERVER [0x5a] Provision [0x5b] Extending users Samba AD schema [0x5c] Setting smb.conf [0x5d] Running the Server (EMSABP / EMSMDB / RFR) [0x5e] Solving problems +------------------------------------+ #################### [0x1] INTRODUCTION #################### [0x1a] What is OpenChange? ========================== OpenChange both provides an Open Source implementation of Microsoft Exchange protocols under unix/linux platforms and a server able to replace transparently Exchange in a company environment. [0x1b] What is libmapi? ======================= libmapi is the OpenChange MAPI implementation. It is a programming interface designed to offer Exchange support to third party applications. [0x1c] Why do I have to do all this compilation? ================================================ Several distributions (Debian, Ubuntu, SuSE and Fedora) contain packages for OpenChange. These packages are not maintained by the OpenChange team but by the distributions, and may be out of date. Furthermore the OpenChange project is moving along quickly and you may want to evaluate or benefit from latest features, changes and bug fixes we may supply in the future. #################### [0x2] INSTALLATION #################### [0x2a] Samba4 Installation ========================== [*] First of all, you need to install a Samba 4 version and pidl version compliant with OpenChange. Furthermore talloc became an external dependency and needs to be installed apart from Samba4. This task can automatically be done using the installsamba4.sh script located in the script directory. Note that the script relies on sudo for "make install" operations and requires your account to be in the sudoers file. Run the following command: $ make samba This should give you the libraries, headers and tools you need to compile OpenChange. It is rare that you will need to update Samba, when you have successfully done this once you should not need to do it again. As a hint, as well as your base compiler (apt-get install build-essential on Debian and Ubuntu) you will need pkg-config. If you want to control every detail of the Samba build, follow the instructions for checking out the git tree. You will require tools such as autoconf (apt-get install automake on Debian and Ubuntu), it will take more time and disk space, and there is more to go wrong. Since the libraries will be installed in /usr/local/samba/lib, ldconfig needs to know about it. On Linux, make sure this directory is listed in /etc/ld.so.conf and run 'ldconfig -v'. On FreeBSD, add this directory to the line 'ldconfig_paths' in /etc/rc.conf and then run 'ldconfig -rv'. Similarly, you need to have /usr/local/samba/bin in your PATH for the pidl binary. This is also where OpenChange installs its binaries. Eg, if your shell is bash: $ export PATH=$PATH:/usr/local/samba/bin If you did a standard Samba install to the normal Samba4 location you should not need to change PKG_CONFIG_PATH, however it does need to be set. Use $ echo $PKG_CONFIG_PATH to see if it has a current value. So if PKG_CONFIG_PATH points to a valid place and OpenChange configure still complains, you may have a problem with the Samba installation.) If you have installed Samba4 somewhere else, you need to change Samba references in ld.so.conf, and in the PATH and PKG_CONFIG_PATH environment variables. For example, if you installed to /opt/otherplace/samba run: $ export PATH=$PATH:/opt/otherplace/samba $ export PKG_CONFIG_PATH=$PKG_CONFIG_PATH:/opt/otherplace/samba/lib/pkgconfig pkg-config >= 0.20 is required. [0x2b] Requirements =================== OpenChange has only these dependencies in addition to Samba4's requirements: * automake (autogen will fail with 'autogen.sh: aclocal not found') * flex * libpopt Samba4 can *use* some of the above, and will tell you in the 'configure' summary that some of them have not been found, however it does not *require* them. OpenChange also includes a new build system which will gathers dependencies on your system and only build what can be compiled with your current system. If your system doesn't meet the requirements for a particular tool or library, you will need to install missing dependencies check below for the list of dependencies you need to install: * libmagic (with development headers): exchange2mbox. For example: # apt-get install libmagic-dev (Debian, Ubuntu) # pkg_add libmagic (BSD) * bison: libocpf, openchangeclient * dcerpc_samr (samba4 installation): libmapiadmin and openchangepfadmin * doxygen: build the documentation * boost-thread: thread support for libmapi++ Similarly for the others: # apt-get install automake flex bison libpopt or # pkg_add automake flex bison libpopt If you have boost development libraries installed, but they aren't being found by the configure script (see below), you may need to set the BOOST_LIB_SUFFIX environmental variable: $ export BOOST_LIB_SUFFIX=-mt [0x2c] OpenChange libmapi installation ====================================== If you retrieved the soure code from Subversion, run autogen.sh now: $ ./autogen.sh Now, run configure: $ ./configure --prefix=path_where_samba_is_installed The default is not /usr/local/samba as you might expect, but /usr/local . So you normally do need to specify --prefix. You should already have made sure that the output of 'ldconfig -v' mentions the samba library directory in the Samba installation step. If you didn't, OpenChange will not find the libraries it needs. You should now be able to build and install openchange MAPI library: $ make && make install You can test like this: $ openchangeclient --help ######################### [0x3] POST-INSTALLATION ######################### The MAPI library requires a profile database and a profile in that database before it can be used. [0x3a] Create a profile store ============================= $ mapiprofile --database=/tmp/profiles.ldb \ --ldif=/usr/local/samba/share/setup -n [0x3b] Create a profile ======================= $ mapiprofile --database=/tmp/profiles.ldb \ --profile=testuser-2000 \ --username=testuser \ --password=openchange \ --domain=OPENCHANGE \ -I 192.168.194.22 \ --create Profile testuser-2000 completed and added to database /tmp/profiles.ldb You need to specify: - the full path to the profile store database - the profile name you want to create - the username/password couple mapiprofile will use to connect to the Exchange server (you might want to use Administrator, on a test server) - the Windows domain your Exchange server belongs to - the IP address of the Exchange server (this must be real. Change the example!) - the create operation [0x3c] Test the profile ======================= You can next ensure your profile was correctly created by running the commands below: $ mapiprofile --database=/tmp/profiles.ldb --list We have 1 profiles in the database: Profile = testuser-2000 $ mapiprofile --database=/tmp/profiles.ldb --profile=testuser-2000 --dump Profile: testuser-2000 username == testuser password == openchange mailbox == /o=First Organization/ou=First Administrative Group/cn=Recipients/cn=testuser workstation == LOCALHOST domain == OPENCHANGE server == 192.168.194.22 #################### [0x4] USING LIBMAPI #################### [0x4a] Doxygen ============== HTML documentation and Man pages are supplied with the MAPI library so developers can have an overview on how to use each function properly. Run the following commands to generate and install man pages: $ make doxygen # make installman If you have troubles accessing man pages, be sure your MANPATH environment variable is set properly and point on openchange prefix installation path. $ export MANPATH=$MANPATH:/usr/local/samba/share/man The HTML documentation is available in the apidocs/html/ directory or can directly be browsed online at http://www.openchange.org/apidocs/. [0x4b] Sample applications ========================== A sample openchangeclient application is supplied so you can test the library and have an overview on how to use it into your applications. Please refer to the openchangeclient man page for further information on its command line option. $ openchangeclient --database=/tmp/profiles.ldb --profile=testuser-2000 --fetchmail For further examples see: $ man openchangeclient openchangeclient is also useful in its own right as a scriptable client. [0x4c] Web resources ==================== For up to date material on how to use libmapi + discussions, you are strongly encouraged to visit the OpenChange wiki: * http://apidocs.openchange.org * http://wiki.openchange.org * http://wiki.openchange.org/index.php/ClientSideProgramming ######################## [0x5] OPENCHANGE SERVER ######################## If you download one of the libmapi releases, please note that the server code is not supplied. Consider using subversion to retrieve the latest openchange revision: svn co https://svn.openchange.org/openchange/trunk [0x5a] Provision ================ In order to run the openchange server, you need to setup Samba4 correctly. If you have not already installed Samba4, please refer to section 2 for further information. Under your root account, provision the server. Starting from the openchange source directory, do the following steps (replacing the domain, realm and adminpass arguments with appropriate entries): # samba4/source4/setup/provision --domain=OPENCHANGE --realm=OPENCHANGE.LOCAL \ --adminpass=0Chas7secret --server-role='domain controller' If you need to add a user, run the following command (replacing and with appropriate entries): # samba4/bin/samba-tool user add [0x5b] Extending Samba AD schema ================================ In the OpenChange source directory, run the following command to extend Samba4 AD. This script will add necessary schema and attributes to run OpenChange Server # ./setup/openchange_provision [0x5c] Extending Samba AD users =============================== Finally running OpenChange server for a given user implies it belongs to the "Exchange Organization". The openchange_newuser script will extend existing user records and add attributes needed by OpenChange # ./setup/openchange_newuser --create Users created with this script are enabled by default. You can enable/disable these users at any time by running: # ./setup/openchange_newuser --enable # ./setup/openchange_newuser --disable You now need to add the dispatcher database for user mailboxes. # ./setup/openchange_provision --openchangedb Mailbox will automatically be provisioned by backends when user first logs in. [0x5c] Setting smb.conf ======================= In order to run OpenChange server, you need to set up additional parameters in the [global] section of smb.conf. OpenChange server being part of mapiproxy, detailed and up to date information can be found at the following address: http://mapiproxy.openchange.org Roughly, you need to add the following entries to the [globals] section: ### Configuration required by OpenChange server ### dcerpc endpoint servers = epmapper, mapiproxy dcerpc_mapiproxy:server = true dcerpc_mapiproxy:interfaces = exchange_emsmdb, exchange_nsp, exchange_ds_rfr ### Configuration required by OpenChange server ### [0x5d] Running the Server (EMSABP / EMSMDB / RFR) ================================================= The simplest is to just run "samba", but as a developer you may find the following more useful: # samba -d3 -i -M single that means "start samba server without messages in stdout, and running a single process". That mode of operation makes debugging samba with gdb particularly easy. [0x5e] Solving problems ================================================= The most common problem is not having sufficient rights - make sure you are doing the configuration and process startup as root. Also, make sure that you don't have any older versions (e.g. partial or full provisioning). As a last resort, considering deleting the whole samba installation directory and reinstalling both samba4 and OpenChange. If you still have problems, please post a detailed message to the development mailing list (devel@lists.openchange.org) showing what commands you followed and what the results of each command were. openchange-2.0/doc/man/000077500000000000000000000000001223057412600150045ustar00rootroot00000000000000openchange-2.0/doc/man/man1/000077500000000000000000000000001223057412600156405ustar00rootroot00000000000000openchange-2.0/doc/man/man1/exchange2ical.1000066400000000000000000000071651223057412600204300ustar00rootroot00000000000000.\" OpenChange Project Tools Man Pages .\" .\" This manpage is Copyright (C) 2008 Brad Hards .\" .\" Permission is granted to make and distribute verbatim copies of this .\" manual provided the copyright notice and this permission notice are .\" preserved on all copies. .\" .\" Permission is granted to copy and distribute modified versions of this .\" manual under the conditions for verbatim copying, provided that the .\" entire resulting derived work is distributed under the terms of a .\" permission notice identical to this one. .\" .\" Since the OpenChange and Samba4 libraries are constantly changing, this .\" manual page may be incorrect or out-of-date. The author(s) assume no .\" responsibility for errors or omissions, or for damages resulting from .\" the use of the information contained herein. The author(s) may not .\" have taken the same level of care in the production of this manual, .\" which is licensed free of charge, as they might when working .\" professionally. .\" .\" Formatted or processed versions of this manual, if unaccompanied by .\" the source, must acknowledge the copyright and authors of this work. .\" .\" Process this file with .\" groff -man -Tascii exchange2ical.1 .\" .TH EXCHANGE2ICAL 1 2013-01-24 "OpenChange 2.0 QUADRANT" "OpenChange Users' Manual" .SH NAME exchange2ical \- Convert Exchange calendar to ical file .SH SYNOPSIS .nf exchange2ical [-?V] [-?|--help] [--usage] [-f|--database=STRING] [-p|--profile=STRING] [-P|--password=STRING] [-i|--icalsync=STRING] [-o|--filename=STRING] [-R|--range=STRING] [-d|--debuglevel=STRING] [--dump-data] [-V|--version] .fi .SH DESCRIPTION exchange2ical provides a way to extract appointments from an Exchange calendar into the ical format. The ical is provided on stdout by default if the filename is not specified. .SH OPTIONS .B --database .TP .B -f Set the path to the profile database to use .TP .B --profile .TP .B -p Set the profile to use. If no profile is specified, exchange2ical tries to retrieve the default profile in the database. If no default profile has been set, exchange2ical returns .B MAPI_E_NOT_FOUND . .TP .B --password .TP .B -P Specify the password for the profile to use. This can be omitted if the password is stored in the profile. .TP .B --icalsync .TP .B -i Specify an icalendar file to be used to sync back to exchange. .TP .B --filename .TP .B -o Specify the filename for the icalendar output. The specified file will be overwritten with the new icalendar. If this is omitted, stdout will be used by default. .TP .B --range .TP .B -r Specify the range of exchange appointments to be converted into an icalendar. If there are no events, whos start date is within the specified range, an icalendar with no vevents will be returned. .B Format: MM/DD/YYYY-MM/DD/YYYY .TP .B --dump-data Dump the hex data. This is only required for debugging or educational purposes. .TP .B --debuglevel .TP .B -d Set the debug level. .SH EXAMPLES .B Extract appointments from the Exchange calendar: .nf exchange2ical > appointments.ical .fi .B Extract appointments from the Exchange calendar to a specified path .nf exchange2ical --filename=/path/to/file.ics .fi .B Extract only appointments which begin from June 25 2008 to July 26 2009 .nf exchange2ical --range=06/25/2008-07/26/2009 .fi .SH REMARKS If you are using the default profile database path and have set a default profile (using .B mapiprofile --profile=profile_name -S ) you do not need to specify these parameters on the command line. .SH AUTHOR exchange2ical was written by Julien Kerihuel This man page was written by Brad Hards openchange-2.0/doc/man/man1/exchange2mbox.1000066400000000000000000000063021223057412600204550ustar00rootroot00000000000000.\" OpenChange Project Tools Man Pages .\" .\" This manpage is Copyright (C) 2007 Julien Kerihuel; .\" .\" Permission is granted to make and distribute verbatim copies of this .\" manual provided the copyright notice and this permission notice are .\" preserved on all copies. .\" .\" Permission is granted to copy and distribute modified versions of this .\" manual under the conditions for verbatim copying, provided that the .\" entire resulting derived work is distributed under the terms of a .\" permission notice identical to this one. .\" .\" Since the OpenChange and Samba4 libraries are constantly changing, this .\" manual page may be incorrect or out-of-date. The author(s) assume no .\" responsibility for errors or omissions, or for damages resulting from .\" the use of the information contained herein. The author(s) may not .\" have taken the same level of care in the production of this manual, .\" which is licensed free of charge, as they might when working .\" professionally. .\" .\" Formatted or processed versions of this manual, if unaccompanied by .\" the source, must acknowledge the copyright and authors of this work. .\" .\" Process this file with .\" groff -man -Tascii exchange2mbox.1 .\" .TH EXCHANGE2MBOX 1 2013-01-24 "OpenChange 2.0 QUADRANT" "OpenChange Users' Manual" .SH NAME exchange2mbox \- Convert Exchange mailbox to mbox file .SH SYNOPSIS .nf exchange2mbox [-?|--help] [--usage] [-f|--database PATH] [-p|--profile PROFILE] [-P|--password PASSWORD] [-m|--mbox FILENAME] [-u|--update] [-d|--debuglevel LEVEL] [--dump-data] .fi .SH DESCRIPTION exchange2mbox provides a way to synchronize an Exchange mailbox with a mbox file. The tool is developed so it only retrieves mails not already stored in the message ID index database and reflects changes back to the Exchange server if the local message copy are deleted. .SH OPTIONS .TP .B --database .TP .B -f Set the path to the profile database to use .TP .B --profile .TP .B -p Set the profile to use. If no profile is specified, exchange2mbox try to retrieve the default profile in the database. If no default profile has been set, exchange2mbox returns .B MAPI_E_NOT_FOUND . .TP .B --password .TP .B -P Set the password for the profile to use. This can be omitted if the password is stored in the profile. .TP .B --mbox .TP .B -m Set the mbox file full path .TP .B --update .TP .B -u Synchronize the local mbox file with the remote Exchange server mailbox. .TP .B --dump-data Dump the hex data. This is only required for debugging or educational purposes. .TP .B --debuglevel LEVEL .TP .B -d Set the debug level. .SH EXAMPLES .B Create/Update the mbox file and indexes within the profile database: .nf exchange2mbox .fi .B Update the Exchange mailbox and indexes according to the changes made to the mbox file. .nf exchange2mbox -u .fi .SH REMARKS If no mbox file is specified, one will be automatically created in .B $(HOME)/.openchange/mbox . If you are using the default profile database path and have set a default profile (using .B mapiprofile --profile=profile_name -S ) you do not need to specify these parameters on the command line. .SH AUTHOR Julien Kerihuel Brad Hards openchange-2.0/doc/man/man1/mapiprofile.1000066400000000000000000000200401223057412600202250ustar00rootroot00000000000000.\" OpenChange Project Tools Man Pages .\" .\" This manpage is Copyright (C) 2007-2010 Julien Kerihuel; .\" This manpage is Copyright (C) 2008-2011 Brad Hards; .\" .\" Permission is granted to make and distribute verbatim copies of this .\" manual provided the copyright notice and this permission notice are .\" preserved on all copies. .\" .\" Permission is granted to copy and distribute modified versions of this .\" manual under the conditions for verbatim copying, provided that the .\" entire resulting derived work is distributed under the terms of a .\" permission notice identical to this one. .\" .\" Since the OpenChange and Samba4 libraries are constantly changing, this .\" manual page may be incorrect or out-of-date. The author(s) assume no .\" responsibility for errors or omissions, or for damages resulting from .\" the use of the information contained herein. The author(s) may not .\" have taken the same level of care in the production of this manual, .\" which is licensed free of charge, as they might when working .\" professionally. .\" .\" Formatted or processed versions of this manual, if unaccompanied by .\" the source, must acknowledge the copyright and authors of this work. .\" .\" Process this file with .\" groff -man -Tascii mapiprofile.1 .\" .TH MAPIPROFILE 1 2013-01-24 "OpenChange 2.0 QUADRANT" "OpenChange Users' Manual" .SH NAME mapiprofile \- administer OpenChange MAPI Profiles databases .SH SYNOPSIS .nf mapiprofile [-?GSnEcrlV] [-?|--help] [--usage] [-L|--ldif=PATH] [-G|--getdefault] [-S|--default] [-n|--newdb] [-f|--database=PATH] [-P|--profile=PROFILE] [-I|--address=xxx.xxx.xxx.xxx] [-M|--workstation=WORKSTATION_NAME] [-D|--domain=DOMAIN] [-R|--realm=REALM] [-E|--encrypt] [-v|--exchange-version=2000] [-u|--username=USERNAME] [-C|--language=LANGUAGE] [-s|--pattern=USERNAME] [-p|--password=PASSWORD] [--nopass] [-c|--create] [-r|--delete] [-R|--rename=STRING] [-l|--list] [--listlangs] [--dump] [-a|--attr=VALUE] [--dump-data] [-d|--debuglevel=LEVEL] [--getfqdn] [-k|--kerberos={yes|no}] [-V|--version] .fi .SH DESCRIPTION mapiprofile is a command line tool designed to provide administrative support for OpenChange MAPI profiles. A profile in this context represents a single user's connection to a server. It can be thought of as a user's account information stored on the client side. Most OpenChange utilities make use of the profile information stored in the local profile database, often by referring to the name of the profile. In addition, because most users only have a single account, it is possible to designate one profile as the default profile. If a profile is not specified, other utilities will use the default profile (if any) to establish a connection. mapiprofile is designed so it also provides sample code for developers interested in adding OpenChange MAPI profile support to their applications. .SH COMMANDS .TP .B --newdb .TP .B -n Create a new database. .TP .B --create .TP .B -c Create a new profile in the database. .TP .B --delete .TP .B -r Delete a profile from the database. .TP .B --rename PROFILE .TP .B -R Rename a profile in the database .TP .B --default .TP .B -S Set the default profile in the database. .TP .B --getdefault .TP .B -G Get the default profile name from the database. .TP .B --dump Display information about a specific profile from information stored in the database. .TP .B --list .TP .B -l List existing profiles in the database. .TP .B --listlangs List the available languages. These can be used to specify the language name (--language) when creating a profile. .SH OPTIONS .TP .B --database DATABASE .TP .B -f Path to the profile database. If no path database is specified then the default one will be used .B $HOME/.openchange/profiles.ldb .TP .B --ldif LDIF .TP .B -L Path to the LDIF files. If no LDIF directory is specified then the default one set at compilation time will be used. This option is only used when creating a new profile database. .TP .B --profile PROFILE .TP .B -p Set the profile name to use (e.g. the profile to create or delete, or to dump information about). .TP .B --address IP_ADDR|FQDN .TP .B -I Set the Exchange server IP address or fully qualified domain name. .TP .B --workstation WORKSTATION .TP .B -M Sets the local computer name. .TP .B --domain DOMAIN .TP .B -D Set the Windows domain name. .TP .B --encrypt .TP .B -E Require the connection to be encrypted. This is normally required only on Exchange 2010 (and will presumably also be required on future versions), but may be used on Exchange 2003 and Exchange 2007. .TP .B --exchange-version .TP .B -v Specify which version of the protocol to use. The reasonable options are 2000, 2003/2007 and 2010. 2000 means use EcDoConnect (0x0) / EcDoRpc (0x2) RPC calls, 2003 or 2007 means use EcDoConnectEx (0xA) / EcDoRpcExt2 (0xB) RPC calls, and 2010 means use EcDoConnectEx (0xA) / EcDoRpcExt2 (0xB) RPC calls over a sealed pipe. .TP .B --kerberos .TP .B -k Specify whether to force Kerberos (set to yes), not use Kerberos (set to no). If you omit this option, Kerberos will be used where practical. .TP .B --realm REALM .TP .B -R Set the Windows realm .TP .B --username .TP .B -u Set the username to use to log on the Exchange server. .TP .B --password .TP .B -p Set the password corresponding to the username described above. .TP .B --language .TP .B -C Specify the language to use with the account. When specifying the name, you use the name of the language returned within the list --listlangs option displays. See the --listlangs option for how to obtain the full list of languages. The default language code is the system one stored within the LC_CTYPE environment variable. .TP .B --pattern .TP .B -s Set a username string pattern mapiprofile should use rather than the default username. This option is used during mapi profile creation. .TP .B --nopass Do not save password in the profile. .TP .B --attr VALUE .TP .B -a Print an attribute value. .TP .B --dump-data Dump the hex data. .TP .B --debuglevel LEVEL .TP .B -d Set the debug level. .TP .B --getfqdn Returns the DNS fully qualified domain name of the NSPI server matching the legacyDN. .SH EXAMPLES .B Create a blank MAPI profile database: .nf mapiprofile --database=/tmp/profiles2.ldb --ldif=/usr/local/samba/share/setup --newdb .fi .B Create a new profile using NTLMSSP authentication: .nf mapiprofile --database=/tmp/profiles.ldb --profile=jkerihuel --username=jkerihuel --password=secret --language=French\\ \\(France\\) --address=192.168.194.22 --workstation=LOCALHOST --domain=OPENCHANGE --create Profile jkerihuel completed and added to database /tmp/profiles.ldb. Note that this account will use French. .fi .B Create a new profile using Kerberos authentication: .nf mapiprofile --database=/tmp/profiles.ldb --profile=jkerihuel --username=jkerihuel --password=secret --language=French\\ \\(France\\) --address=exchange.openchange.local --domain=OPENCHANGE --realm=OPENCHANGE.LOCAL --create .fi .B Delete a profile: .nf mapiprofile --database=/tmp/profiles.ldb --profile=jkerihuel --delete Profile jkerihuel deleted from database /tmp/profiles.ldb .fi .B List profiles: .nf mapiprofile --database=/tmp/profiles.ldb --list We have 2 profiles in the database: Profile = exchange-2000 Profile = jkerihuel .fi .B Dump a profile: .nf mapiprofile --database=/tmp/profiles.ldb --profile=jkerihuel --dump Profile: jkerihuel username == jkerihuel password == secret mailbox == /o=First Organization/ou=First Administrative Group/cn=Recipients/cn=jkerihuel workstation == LOCALHOST domain == OPENCHANGE server == exchange.openchange.local .fi .B Dump profile attribute: .nf mapiprofile --database=/tmp/profiles.ldb --profile=jkerihuel --attr=HomeMDB Profile jkerihuel: HomeMDB = /o=First Organization/ou=First Administrative Group/cn=Configuration/cn=Servers/cn=EXCHANGE2000 .fi .SH AUTHOR Julien Kerihuel Brad Hards .SH "SEE ALSO" The codes for various languages can be found in many places, including the Windows Language Code Identifier (LCID) Reference. openchange-2.0/doc/man/man1/mapitest.1000066400000000000000000000106611223057412600175540ustar00rootroot00000000000000.\" OpenChange Project Tools Man Pages .\" .\" This manpage is Copyright (C) 2008, 2010 Brad Hards .\" .\" Permission is granted to make and distribute verbatim copies of this .\" manual provided the copyright notice and this permission notice are .\" preserved on all copies. .\" .\" Permission is granted to copy and distribute modified versions of this .\" manual under the conditions for verbatim copying, provided that the .\" entire resulting derived work is distributed under the terms of a .\" permission notice identical to this one. .\" .\" Since the OpenChange and Samba4 libraries are constantly changing, this .\" manual page may be incorrect or out-of-date. The author(s) assume no .\" responsibility for errors or omissions, or for damages resulting from .\" the use of the information contained herein. The author(s) may not .\" have taken the same level of care in the production of this manual, .\" which is licensed free of charge, as they might when working .\" professionally. .\" .\" Formatted or processed versions of this manual, if unaccompanied by .\" the source, must acknowledge the copyright and authors of this work. .\" .\" Process this file with .\" groff -man -Tascii mapitest.1 .\" .TH MAPITEST 1 2013-01-24 "OpenChange 2.0 QUADRANT" "OpenChange Users' Manual" .SH NAME mapitest \- OpenChange torture test utility .SH SYNOPSIS .nf mapitest [-?|--help] [--usage] [-f|--database=STRING] [-p|--profile=STRING] [-p|--password=STRING] [--confidential] [--color] [--subunit] [-o|--outfile=STRING] [--mapi-calls=STRING] [--list-all] [--no-server] [--dump-data] [-d|--debuglevel=STRING] .fi .SH DESCRIPTION mapitest is a test harness / utility used for verifying correct operation of various ExchangeRPC calls / MAPI functions provided by the OpenChange MAPI libraries. mapitest is not normally required by users, but you may be asked to provide the output of mapitest for some kinds of bug investigations. Note that mapitest performs a lot of transactions, including deleting folders and messages. Unless you're very familiar with mapitest, we recommend only using it with a test account. .SH OPTIONS .TP .B --database .TP .B -f Set the path to the profile database to use .TP .B --profile .TP .B -p Set the profile to use. If no profile is specified, mapitest tries to retrieve the default profile in the database. If no default profile has been set, mapitest returns .B MAPI_E_NOT_FOUND . .TP .B --password .TP .B -P Specify the password for the profile to use. This can be omitted if the password is stored in the profile. .TP .B --confidential Remove any sensitive data from the report. .TP .B --color Use colors to indicate the results of each operation. .TP .B --subunit Produce output in subunit protocol format, instead of the normal text output. This disables colored output. Note that availability of this option depends on suitable libraries being available at build time, so check availability before relying on this. .TP .B --outfile .TP .B -o Redirect the output of the tests to a file. The filename must be specified as the argument to this option. .TP .B --mapi-calls Run a specific test. The name of the test must be specified as the argument to this option. See the --list-all option to obtain the name of the test. This can be specified more than once in order to run a subset of tests. This can also be used to run a "suite" of tests, by appending "-ALL" to the name of the suite. .TP .B --list-all Provide a list of all test suites and test names, along with a description of the test. No tests will be run. .TP .B --no-server Only run tests that do not require a server connection. This is the default if a connection to the server cannot be established. .TP .B --dump-data Dump the hex data. This is only required for debugging or educational purposes. .TP .B --debuglevel .TP .B -d Set the debug level. .SH EXAMPLES .B Run all tests .nf mapitest .fi .B Only run two specific tests .nf mapitest --mapi-calls=NOSERVER-SROWSET --mapi-calls=OXCPRPT-GET-PROPS .fi .B Run all the NSPI tests .nf mapitest --mapi-calls=NSPI-ALL .fi .SH REMARKS If you are using the default profile database path and have set a default profile (using .B mapiprofile --profile=profile_name -S ) you do not need to specify these parameters on the command line. .SH AUTHOR mapitest was written by Julien Kerihuel with contributions from other OpenChange developers. This man page was written by Brad Hards openchange-2.0/doc/man/man1/openchangeclient.1000066400000000000000000000353131223057412600212350ustar00rootroot00000000000000.\" OpenChange Project Tools Man Pages .\" .\" This manpage is Copyright (C) 2007 Julien Kerihuel; .\" This manpage is Copyright (C) 2008 Brad Hards .\" .\" Permission is granted to make and distribute verbatim copies of this .\" manual provided the copyright notice and this permission notice are .\" preserved on all copies. .\" .\" Permission is granted to copy and distribute modified versions of this .\" manual under the conditions for verbatim copying, provided that the .\" entire resulting derived work is distributed under the terms of a .\" permission notice identical to this one. .\" .\" Since the OpenChange and Samba4 libraries are constantly changing, this .\" manual page may be incorrect or out-of-date. The author(s) assume no .\" responsibility for errors or omissions, or for damages resulting from .\" the use of the information contained herein. The author(s) may not .\" have taken the same level of care in the production of this manual, .\" which is licensed free of charge, as they might when working .\" professionally. .\" .\" Formatted or processed versions of this manual, if unaccompanied by .\" the source, must acknowledge the copyright and authors of this work. .\" .\" Process this file with .\" groff -man -Tascii openchangeclient.1 .\" .TH OPENCHANGECLIENT 1 2013-01-24 "OpenChange 2.0 QUADRANT" "OpenChange Users' Manual" .SH NAME openchangeclient \- MAPI command line messaging tool .SH SYNOPSIS .nf openchangeclient [-?SFmDV] [-?|--help] [--usage] [-f|--database STRING] [--pf] [-p|--profile STRING] [-P|--password STRING] [-S|--sendmail] [--sendappointment] [--sendcontact] [--sendtask] [--sendnote] [-F|--fetchmail] [-G|--storemail STRING] [-i|--fetch-items STRING] [--freebusy=STRING] [--force] [--delete=STRING] [-u|--update STRING] [-m|--mailbox] [-D|--deletemail] [-A|--attachments STRING] [-I|--html-inline STRING] [-W|--html-file STRING] [-t|--to STRING] [-c|--cc STRING] [-b|--bcc STRING] [-s|--subject STRING] [-B|--body STRING] [--location=STRING] [--label=STRING] [--dtstart=STRING] [--dtend=STRING] [--busystatus=STRING] [--taskstatus=STRING] [--importance=STRING] [--email=STRING] [--fullname=STRING] [--cardname=STRING] [--color=STRING] [--notifications] [--folder=STRING] [--mkdir] [--rmdir] [--userlist] [--folder-name=STRING] [--folder-comment=STRING] [-d|--debuglevel STRING] [--dump-data] [--private] [--ocpf-file=STRING] [--ocpf-dump=STRING] [--ocpf-syntax] [--ocpf-sender] [-V|--version] .fi .SH DESCRIPTION openchangeclient is a MAPI command line tool designed to facilitate mail send, receive and delete operations using the MAPI protocol. It also provides operations on tasks, contacts (address book) and calendar operations. .SH COMMANDS .TP .B --fetchmail .TP .B -F Fetch Exchange user mails from the inbox and display general information from the mails on the standard output. .TP .B --storemail=DIRECTORY .TP .B -G Store mail attachments to the local filesystem in the specified directory. This is the normal way to retrieve attachments. .TP .B --fetch-items=STRING .TP .B -i Retrieve specific items from Exchange default folders. Possible value for STRING are Mail, Appointment, Contact, Task, Note. .TP .B --mkdir Create a folder within the mailbox or public folders store hierarchy. This command requires that the --folder-name option be used to specify the name of the folder to create. .TP .B --rmdir Deletes a folder within the mailbox or public folders store hierarchy. This option requires that the --folder-name option be used to specify the name of the folder to delete. .TP .B --mailbox .TP .B -m Display the user mailbox folder hierarchy with folder names, folder comments, the folder type, number of unread items in the folder and total number of items in the folder. .TP .B --notifications Monitor NEWMAIL notifications in the Inbox folder and display summary on standard output. .TP .B --sendmail .TP .B -S Send a mail to a user belonging to the Exchange organization. This requires specifying one or more recipients (see the --to, --cc and --bcc options), a subject (see the --subject option) and a body (see the --body, --html-file and --html-inline options). .TP .B --sendappointment Create an appointment in the default calendar folder. .TP .B --sendcontact Create a contact in the default contact folder. .TP .B --sendtask Create a task in the default task folder. .TP .B --sendnote Create a note in the default notes folder. .TP .B --deletemail .TP .B -D Delete a mail from the exchange user mailbox. This requires use of the --subject option to specify the mail to be deleted. .TP .B --userlist Display the users listed in the address book. .TP .B --delete=STRING Delete a specified item from the store by ID number. .TP .B --ocpf-dump=STRING Download a message (specified by the argument, which must be the folder ID and unique message ID for the message) as OCPF format. The message will be saved to a file given by the message ID, followed by a suffix of .ocpf See the separate (HTML) documentation for libocpf for more information on the OCPF format. .TP .B --ocpf-sender Send a message given in OCPF format to the server. This requires use of the .B --ocpf-file option to specify the file to load from. See the separate (HTML) documentation for libocpf for more information on the OCPF format. .TP .B --ocpf-syntax Check the syntax of an OCPF file. This does not perform any network operations. This requires use of the .B --ocpf-file option to specify the file to load from. See the separate (HTML) documentation for libocpf for more information on the OCPF format. .TP .B --freebusy=STRING Fetch the free / busy status for the user specified by the string. You will usually need to use the .B --pf option (see below) since free / busy status is normally obtained from the public folder store. .SH OPTIONS .TP .B --database=DATABASE .TP .B -f Set the MAPI profile database. If no database is specified, then openchangeclient tries to load the default one: .B $HOME/.openchange/profiles.ldb .TP .B --profile=PROFILE .TP .B -p Set the profile to use. If a profile is not specified, and one of the profiles has been set as the default in the profile database (for example, using mapiprofile -S), then that default profile will be used. .TP .B --password .TP .B -P Specify the password for the profile to be used. This can be omitted if the password is stored in the profile. .TP .B --pf Perform operations against the Public Folders store, rather than the normal operations against a user's private folders. .TP .B --folder Specify the folder name we want to work with want to open. This option is mandatory for public folders, but can also be used to open specific folders in the mailbox store. .TP .B --attachments="ATTACHMENT1;ATTACHMENT2" .TP .B -A Set attachments to send when sending a mail. Attached filenames need to be separated with .B semi-colons as specified in the description above. This is only meaningful with .B --sendmail .TP .B --subject=STRING .TP .B -s Specify the mail subject. If no subject is specified, the mail subject will be empty. This is only meaningful with .B --sendmail .TP .B --body=STRING .TP .B -B Set the body of the mail to be the UTF8 text only content specified on the command line. This is only meaningful with .B --sendmail .TP .B --html-inline=STRING .TP .B -I Set the body of the mail to be the HTML content specified on command line. This is only meaningful with .B --sendmail .TP .B --html-file=FILENAME .TP .B -W Set the body of the mail to be the content of the specified file. This is only meaningful with .B --sendmail .TP .B --to="USERNAME1,USERNAME2" .TP .B -t Specify .B To recipients for the mail. Usernames need to be separated with commas as specified in the example above. This is only meaningful with .B --sendmail .TP .B --cc="USERNAME1,USERNAME2" .TP .B -c Specify .B Cc recipients for the mail. Usernames need to be separated with commas as specified in the example above. This is only meaningful with .B --sendmail .TP .B --bcc="USERNAME1,USERNAME2" .TP .B -b Specify .B Bcc recipients for the mail. Usernames need to be separated with commas as specified in the example above. This is only meaningful with .B --sendmail .TP .B --location=STRING Specify the appointment location. This is only meaningful with .B --sendappointment .TP .B --dtstart=STRING Specify the start date of an event. The following date format needs to be used: .B "%Y-%m-%d %H:%M:%S" e.g: 2007-06-01 14:59:00. This is only meaningful with .B --sendappointment and .B --sendtask .TP .B --dtend=STRING Specify either the end date or due date of an event. The following date format needs to be used: .B "%Y-%m-%d %H:%M:%S" e.g: 2007-06-01 14:59:00 When no .B dtend parameter is specified, default value is set to .B dtstart This is only meaningful with .B --sendappointment and .B --sendtask .TP .B --force Add appointment to the calendar, even if it would overlap with an existing appointment. This is only meaningful with .B --sendappointment .TP .B --private Mark the appointment as private event. This is only meaningful with .B --sendappointment .TP .B --busystatus=STRING Set the busy status of an appointment. Possible values are FREE, TENTATIVE, BUSY or OUTOFOFFICE. This is only meaningful with .B --sendappointment .TP .B --label=STRING Set the type of appointment. Possible values are NONE, IMPORTANT, BUSINESS, PERSONAL, VACATION, MUST_ATTEND, TRAVEL_REQUIRED, NEEDS_PREPARATION, BIRTHDAY, ANNIVERSARY and PHONE_CALL. This is only meaningful with .B --sendappointment .TP .B --taskstatus=STRING Set the status of a task. Possible values are NOTSTARTED, PROGRESS, COMPLETED, WAITING, DEFERRED. This is only meaningful with .B --sendtask .TP .B --fullname=STRING Set the full name in a contact message. This is only meaningful with .B --sendcontact .TP .B --cardname=STRING Set the card name of a task or contact message. This is only meaningful with .B --sendcontact or .B --sendtask .TP .B --email=STRING Set the email address in a contact message. This is only meaningful with .B --sendcontact .TP .B --importance=STRING Set the relative importance of a task. Possible values are LOW, NORMAL and HIGH. This is only meaningful with .B --sendtask .TP .B --color=STRING Set the color of the note. The default color is Yellow. Other options are Blue, Green, Pink and White. This is only meaningful with .B --sendnote .TP .B --folder-name=STRING Set the folder name to create. This is only meaningful with .B --mkdir or .B --rmdir .TP .B --folder-comment=STRING Set the folder comment. This is only meaningful with .B --mkdir .TP .B --update=STRING .TP .B -u Change (update) an existing item, rather than creating a new one. This is only meaningful with .B --sendtask , .B --sendnote , .B --sendappointment and .B --sendcontact .TP .B --ocpf-file=STRING Specify the file to load OCPF data from. This is only meaningful with .B --ocpf-sender and .B --ocpf-syntax .TP .B --dump-data Display raw format data associated with the operation. You normally only need this when debugging. .TP .B --debug-level=LEVEL Display debugging information at the specified level (or higher). Level 10 is a lot of debug information. .SH EXAMPLES .B Fetching emails: .nf openchangeclient --database=/tmp/profiles.ldb --profile=2000 --fetchmail .fi .B Fetch emails and store attachments: .nf openchangeclient --database=/tmp/profiles.ldb --profile=2000 --fetchmail --storemail=test .fi All attachments from any mails will be stored in the test directory. If the specified directory does not exist, it will automatically be created. Note that if the attachment name is not unique amongst all emails, some attachments may be overwritten. .B Send a basic email: .nf openchangeclient --database=/tmp/profiles.ldb --profile=2000 --to="Adm,jker" --cc=Paul --bcc=Bill --subject="It is working" --body="This is a sample body" --sendmail .fi A mail with UTF8 (text only) content will be sent with the following recipients: to = Administrator and jkerihuel cc = Paul bcc = Bill .B Send an inline HTML email: .nf openchangeclient --database=/tmp/profiles.ldb --profile=2000 --to=Adm --subject="Inline HTML sample email" --html-inline="

My first HTML email

" --sendmail .fi Administrator will receive a mail with HTML body - yellow background and a title. .B Send a HTML mail using a file: .nf openchangeclient --database=/tmp/profiles.ldb --profile=2000 --to=Adm --subject="HTML file email" --html-file=/tmp/myfile.html --sendmail .fi The content of /tmp/myfile.html will be used to fill the HTML body. If the HTML file exceed a fixed size (0x4000 bytes), then PR_HTML content will be sent using MAPI streams. .B Send email with attachments: .nf openchangeclient --database=/tmp/profiles.ldb --profile=2000 --to=Adm --subject="Attachments" --attachments="/tmp/file1.jpg;/tmp/file2.jpg;tmp/file2.jpg" --body="These are sample attachments" --sendmail .fi The example above will send a UTF8 body mail to Administrator and attach file1,jpg, file2.jpg and file3.jpg to the email. .B Display the users in the address book .nf openchangeclient --userlist .fi .B Fetch calendar items: .nf openchangeclient --fetch-items=Appointment .fi .B Fetch contact items: .nf openchangeclient --fetch-items=Contact .fi .B Fetch task items: .nf openchangeclient --fetch-items=Task .fi .B Create appointment: .nf openchangeclient --sendappointment --dtstart="2007-06-01 22:00:00" \\ --dtend="2007-06-01 22:35:00" \\ --busystatus=FREE \\ --location="Home" \\ --subject="Check the Junk folder" .fi .B Create Task: .nf openchangeclient --sendtask --dtstart="2008-11-01 18:00:00" \\ --cardname="openchangeclient" --importance=HIGH \\ --taskstatus=COMPLETED --body="my new task" .fi .B Create contact: .nf openchangeclient --sendcontact --cardname="openchangeclient" \\ --fullname="OpenChange Client 3rd" \\ --email="openchangeclient@nonexistentdomain.com" .fi .B Create folder: .nf openchangeclient --mkdir --folder-name="openchange" \\ --folder-comment="comment" .fi This example will create a generic folder named openchange under the Inbox folder. .B Delete folder: .nf openchangeclient --rmdir --folder-name="openchange" .fi This example will delete the generic folder named openchange under Inbox folder. .B List Mailbox hierarchy: .nf openchangeclient --mailbox .fi .B Obtain free / busy status .nf openchangeclient --pf --freebusy="test user3" .fi .SH AUTHOR Julien Kerihuel openchange-2.0/doc/man/man1/openchangepfadmin.1000066400000000000000000000153551223057412600214010ustar00rootroot00000000000000.\" OpenChange Project Tools Man Pages .\" .\" This manpage is Copyright (C) 2007 Julien Kerihuel; .\" .\" Permission is granted to make and distribute verbatim copies of this .\" manual provided the copyright notice and this permission notice are .\" preserved on all copies. .\" .\" Permission is granted to copy and distribute modified versions of this .\" manual under the conditions for verbatim copying, provided that the .\" entire resulting derived work is distributed under the terms of a .\" permission notice identical to this one. .\" .\" Since the OpenChange and Samba4 libraries are constantly changing, this .\" manual page may be incorrect or out-of-date. The author(s) assume no .\" responsibility for errors or omissions, or for damages resulting from .\" the use of the information contained herein. The author(s) may not .\" have taken the same level of care in the production of this manual, .\" which is licensed free of charge, as they might when working .\" professionally. .\" .\" Formatted or processed versions of this manual, if unaccompanied by .\" the source, must acknowledge the copyright and authors of this work. .\" .\" Process this file with .\" groff -man -Tascii openchangepfadmin.1 .\" .TH OPENCHANGEPFADMIN 1 2013-01-24 "OpenChange 2.0 QUADRANT" "OpenChange Users' Manual" .SH NAME openchangepfadmin \- Exchange users and Public Folder administration tool .SH SYNOPSIS .nf openchangepfadmin [-?] [-?|--help] [--usage] [-f|--database PATH] [-p|--profile PROFILE] [-P|--password PASSWORD] [--apassword=PASSWORD] [--adesc=DESCRIPTION] [--acomment=COMMENT] [--afullname=NAME] [--list] [--mkdir] [--rmdir] [--comment=COMMENT] [--dirclass=CLASS] [--adduser=USERNAME] [--rmuser=USERNAME] [--addright=RIGHT] [--rmright] [--modright=RIGHT] [--debuglevel=LEVEL] [--dump-data] [--folder=FOLDER] [--username=USERNAME] .fi .SH DESCRIPTION openchangepfadmin is a administrative command line tool designed to facilitate user management related operations (create, delete, modify) on a remote Exchange server and manage public folder store and permissions. .SH COMMANDS .TP .B --adduser=USERNAME Create a Exchange user with the username specified by USERNAME .TP .B --rmuser=USERNAME Delete the Exchange user account specified by USERNAME .TP .B --list List Public Folder hierarchy (IPM_SUBTREE) .TP .B --mkdir Create a folder in the Public Folder store .TP .B --rmdir Delete a folder in the Public Folder store .TP .B --addright=RIGHT Add permission and roles for a user on a Public Folder directory. .TP .B --modright=RIGHT Modify permissions and roles for a user on a Public Folder directory .TP .B --rmright Delete permissions and roles for a specific user .SH OPTIONS .TP .B --database=DATABASE .TP .B -f Set the MAPI profile database. If no database is specified, then openchangeclient tries to load the default one: .B $HOME/.openchange/profiles.ldb .TP .B --profile=PROFILE .TP .B -p Set the profile to use. If a profile is not specified, and one of the profiles has been set as the default in the profile database (for example, using mapiprofile -S), then that default profile will be used. .TP .B --password .TP .B -P Set the password for the profile to use. This can be omitted if the password is stored in the profile. .TP .B --apassword=PASSWORD Define the password to set for the user specified with --adduser. If no password is explicitely supplied, openchangepfadmin will arbitrary set a random one. .TP .B --adesc=DESCRIPTION This command can only be used with --adduser and specifies a description for this account .TP .B --acomment=COMMENT This command can only be used with --adduser and specifies a comment for this account. .TP .B --afullname=NAME This command can only be used with --adduser and specifies the user full name for this account. .TP .B --comment=COMMENT This command can only be used with --mkdir and specifies a comment for the folder. .TP .B --dirclass=CLASS This command can only be used with --mkdir and specifies the container class of the directory we want to create. Possible values are: IPF.Appointment, IPF.Contact, IPF.Journal, IPF.Note, IPF.StickyNote, IPF.Task, IPF.Post .TP .B --folder=FOLDER This command can only be used with --addright, --modright and --rmright. Specify the folder where permissions and roles have to be changed. .TP .B --username=USERNAME This command can only be used with --addright, --modright and --rmright. Specify the username we want to change permissions and roles for. .TP .B --dump-data Dump the hex data. This is only required for debugging or educational purposes. .TP .B --debuglevel LEVEL .TP .B -d Set the debug level. .SH EXAMPLES .B Creating user .nf openchangepfadmin --adduser=linuxowner --apassword=linuxowner \\ --adesc="Linux Owner Test account" \\ --afullname="Linux Owner" mapiadmin_user_add : MAPI_E_SUCCESS (0x0) username: linuxowner password: linuxowner .fi Creates a user account with username and password set to linuxowner. .B Deleting user: .nf openchangepfadmin --rmuser=linuxowner mapiadmin_user_del : MAPI_E_SUCCESS (0x0) .fi .B Create Public Folder: .nf openchangepfadmin --mkdir --folder=public_events --dirclass=IPF.Appointment .fi Creates a folder in the Public Folder store named public_events with a container class set to Appointment. This folder will display calendar items. .B Delete Public Folder: .nf openchangepfadmin --rmdir --folder=public_events .fi .B List Public Folder hierarchy: .nf openchangepfadmin --list .fi .B Add Permission: .nf openchangepfadmin --username=linuxowner --folder=public_events \\ --addright=RoleOwner Permission RoleOwner added for linuxowner on folder public_events .fi .B Modify Permission .nf openchangepfadmin --username=Anonymous --folder=public_events \\ --modright=RoleNone Permission changed to RoleNone for Anonymous on folder appointment .fi Note that you can only change permissions for a user already listed in the ACL table. .SH NOTE Permissions and Roles possible values are: .IP "\(bu" 2 RightsNone .IP "\(bu" 2 RightsReadItems .IP "\(bu" 2 RightsCreateItems .IP "\(bu" 2 RightsEditOwn .IP "\(bu" 2 RightsDeleteOwn .IP "\(bu" 2 RightsEditAll .IP "\(bu" 2 RightsDeleteAll .IP "\(bu" 2 RightsCreateSubfolders .IP "\(bu" 2 RightsFolderOwner .IP "\(bu" 2 RightsFolderContact .IP "\(bu" 2 RoleNone .IP "\(bu" 2 RoleReviewer .IP "\(bu" 2 RoleContributor .IP "\(bu" 2 RoleNoneditingAuthor .IP "\(bu" 2 RoleAuthor .IP "\(bu" 2 RoleEditor .IP "\(bu" 2 RolePublishAuthor .IP "\(bu" 2 RolePublishEditor .IP "\(bu" 2 RightsAll .IP "\(bu" 2 RoleOwner .SH SEE ALSO AddUserPermission, ModifyUserPermission, RemoveUserPermission .SH AUTHOR Julien Kerihuel openchange-2.0/exchange.idl000066400000000000000000004317441223057412600157550ustar00rootroot00000000000000#include "idl_types.h" cpp_quote("#include ") /* http://support.microsoft.com/default.aspx?scid=KB;en-us;q159298 Any UUID starting with: A4 - store F5 - directory */ [ uuid("99e64010-b032-11d0-97a4-00c04fd6551d"), pointer_default(unique), version(3.0) ] interface exchange_store_admin3 { void ec_store_admin3_dummy(); } [ uuid("89742ace-a9ed-11cf-9c0c-08002be7ae86"), pointer_default(unique), version(2.0) ] interface exchange_store_admin2 { void ec_store_admin2_dummy(); } [ uuid("a4f1db00-ca47-1067-b31e-00dd010662da"), pointer_default(unique), version(1.0) ] interface exchange_store_admin1 { void ec_store_admin1_dummy(); } [ uuid("1544f5e0-613c-11d1-93df-00c04fd7bd09"), endpoint("ncacn_np:[\\pipe\\lsass]","ncacn_np:[\\pipe\\protected_storage]","ncacn_ip_tcp:[]"), authservice("exchangeRFR"), pointer_default(unique), version(1.0), helpstring("Exchange 2003 Directory Request For Response") ] interface exchange_ds_rfr { #include "properties_enum.h" #include "mapicodes_enum.h" /*****************/ /* Function 0x00 */ MAPISTATUS RfrGetNewDSA( [in] uint32 ulFlags, [in,string,charset(DOS)] uint8 *pUserDN, [in,out,unique,string,charset(DOS)] uint8 **ppszUnused, [in,out,unique,string,charset(DOS)] uint8 **ppszServer ); /*****************/ /* Function 0x01 */ MAPISTATUS RfrGetFQDNFromLegacyDN( [in] uint32 ulFlags, [in,range(10,1024)] uint32 cbMailboxServerDN, [in,string,charset(DOS),size_is(cbMailboxServerDN)] uint8 *szMailboxServerDN, [out,ref,string,charset(DOS)] uint8 **ppszServerFQDN ); } [ uuid("f930c514-1215-11d3-99a5-00a0c9b61b04"), helpstring("System Attendant Cluster Interface"), pointer_default(unique), version(1.0) ] interface exchange_sysatt_cluster { void sysatt_cluster_dummy(); } /* [83d72bf0-0d89-11ce-b13f-00aa003bac6c] MS Exchange System Attendant Private Interface */ [ uuid("469d6ec0-0d87-11ce-b13f-00aa003bac6c"), pointer_default(unique), helpstring("Exchange 5.5 System Attendant Request for Response") ] interface exchange_system_attendant { void sysatt_dummy(); } [ uuid("9e8ee830-4559-11ce-979b-00aa005ffebe"), pointer_default(unique), version(2.0), helpstring("Exchange 5.5 MTA") ] interface exchange_mta { /*****************/ /* Function 0x00 */ void MtaBind(); /*****************/ /* Function 0x01 */ void MtaBindAck(); } [ uuid("f5cc59b4-4264-101a-8c59-08002b2f8426"), pointer_default(unique), version(21.0), helpstring("Exchange 5.5 DRS") ] interface exchange_drs { /*****************/ /* Function 0x00 */ void ds_abandon(); /*****************/ /* Function 0x01 */ void ds_add_entry(); void ds_bind(); void ds_compare(); void ds_list(); void ds_modify_entry(); void ds_modify_rdn(); void ds_read(); void ds_receive_result(); void ds_remove_entry(); void ds_search(); void ds_unbind(); void ds_wait(); void dra_replica_add(); void dra_replica_delete(); void dra_replica_synchronize(); void dra_reference_update(); void dra_authorize_replica(); void dra_unauthorize_replica(); void dra_adopt(); void dra_set_status(); void dra_modify_entry(); void dra_delete_subref(); } [ uuid("f5cc5a7c-4264-101a-8c59-08002b2f8426"), version(21.0), pointer_default(unique), helpstring("Exchange 5.5 XDS") ] interface exchange_xds { void xds_dummy(); } [ uuid("38a94e72-a9bc-11d2-8faf-00c04fa378ff"), pointer_default(unique), version(1.0) ] interface exchange_mta_qadmin { void exchange_mta_qadmin(); } [ uuid("0e4a0156-dd5d-11d2-8c2f-00c04fb6bcde"), pointer_default(unique), version(1.0) ] interface exchange_store_information { void exchange_store_information_dummy(); } [ uuid("f5cc5a18-4264-101a-8c59-08002b2f8426"), endpoint("ncacn_np:[\\pipe\\lsass]","ncacn_np:[\\pipe\\protected_storage]","ncacn_ip_tcp:[]"), authservice("exchangeAB"), pointer_default(unique), version(56.0), helpstring("Exchange 5.5 Name Service Provider") ] interface exchange_nsp { #define PT_UNSPECIFIED 0x0000 #define PT_NULL 0x0001 #define PT_I2 0x0002 #define PT_LONG 0x0003 #define PT_R4 0x0004 #define PT_DOUBLE 0x0005 #define PT_CURRENCY 0x0006 #define PT_APPTIME 0x0007 #define PT_ERROR 0x000a /* means the given attr contains no value */ #define PT_BOOLEAN 0x000b #define PT_OBJECT 0x000d #define PT_I8 0x0014 #define PT_STRING8 0x001e #define PT_UNICODE 0x001f #define PT_SYSTIME 0x0040 #define PT_CLSID 0x0048 #define PT_SVREID 0x00fb #define PT_SRESTRICT 0x00fd #define PT_ACTIONS 0x00fe #define PT_BINARY 0x0102 /* Multi-valued properties */ #define PT_MV_I2 0x1002 #define PT_MV_LONG 0x1003 #define PT_MV_R4 0x1004 #define PT_MV_DOUBLE 0x1005 #define PT_MV_CURRENCY 0x1006 #define PT_MV_APPTIME 0x1007 #define PT_MV_I8 0x1014 #define PT_MV_STRING8 0x101e #define PT_MV_TSTRING 0x101e #define PT_MV_UNICODE 0x101f #define PT_MV_SYSTIME 0x1040 #define PT_MV_CLSID 0x1048 #define PT_MV_BINARY 0x1102 typedef [v1_enum] enum { SortTypeDisplayName = 0x00000000, SortTypePhoneticDisplayName = 0x00000003, SortTypeDisplayName_RO = 0x000003E8, SortTypeDisplayName_W = 0x000003E9 } TableSortOrders; typedef [v1_enum] enum { MID_BEGINNING_OF_TABLE = 0x0, MID_END_OF_TABLE = 0x2, MID_CURRENT = 0x1 } NSPI_MID; typedef struct { TableSortOrders SortType; uint32 ContainerID; NSPI_MID CurrentRec; int32 Delta; uint32 NumPos; uint32 TotalRecs; uint32 CodePage; uint32 TemplateLocale; uint32 SortLocale; } STAT; typedef struct { uint8 ab[16]; } FlatUID_r; /* like a SPropTagArray, but without the "value is a an enum MAPITAGS" semantics */ typedef struct { [range(0,100000)] uint32 cValues; [size_is(cValues+1), length_is(cValues)] uint32 aulPropTag[]; } PropertyTagArray_r; typedef struct { FlatUID_r *lpguid; uint32 ulReserved; uint32 lID; } PropertyName_r; typedef struct { [range(0,100000)] uint32 cNames; [size_is(cNames)] PropertyName_r aNames[]; } PropertyNameSet_r; typedef struct { [range(0,100000)] uint32 cValues; [string,size_is(cValues),charset(DOS)] uint8 **lppszA; } StringArray_r; typedef struct { [range(0,100000)] uint32 Count; [string,size_is(Count),charset(DOS)] uint8 *Strings[]; } StringsArray_r; typedef struct { [range(0,100000)] uint32 cValues; [string,size_is(cValues),charset(UTF16)] uint16 **lppszW; } StringArrayW_r; typedef struct { [range(0,100000)] uint32 Count; [string,size_is(Count),charset(UTF16)] uint16 *Strings[]; } StringsArrayW_r; typedef struct { [range(0,100001)] uint32 cValues; [size_is(cValues+1),length_is(cValues)] MAPITAGS aulPropTag[]; } SPropTagArray; typedef [public,noprint] struct { [range(0,2097152)] uint32 cb; [size_is(cb)] uint8 *lpb; } Binary_r; typedef [public] struct { uint32 dwLowDateTime; uint32 dwHighDateTime; } FILETIME; typedef struct { [range(0,100000)] uint32 cValues; [size_is(cValues)] uint16 *lpi; } ShortArray_r; typedef struct { [range(0,100000)] uint32 cValues; [size_is(cValues)] uint32 *lpl; } LongArray_r; typedef struct { [range(0,100000)] uint32 cValues; [size_is(cValues)] Binary_r *lpbin; } BinaryArray_r; typedef struct { [range(0,100000)]uint32 cValues; [size_is(cValues)] FlatUID_r **lpguid; } FlatUIDArray_r; typedef struct { [range(0,100000)] uint32 cValues; [size_is(cValues)] FILETIME *lpft; } DateTimeArray_r; typedef [switch_type(uint32)] union { [case(PT_I2)] uint16 i; [case(PT_LONG)] uint32 l; [case(PT_BOOLEAN)] uint8 b; [case(PT_STRING8)][unique][string,charset(DOS)] uint8 *lpszA; [case(PT_UNICODE)][string,charset(UTF16)] uint16 *lpszW; [case(PT_BINARY)] Binary_r bin; [case(PT_SVREID)] Binary_r bin; [case(PT_CLSID)] FlatUID_r *lpguid; [case(PT_SYSTIME)] FILETIME ft; [case(PT_ERROR)] MAPISTATUS err; [case(PT_MV_I2)] ShortArray_r MVi; [case(PT_MV_LONG)] LongArray_r MVl; [case(PT_MV_STRING8)] StringArray_r MVszA; [case(PT_MV_BINARY)] BinaryArray_r MVbin; [case(PT_MV_CLSID)] FlatUIDArray_r MVguid; [case(PT_MV_UNICODE)] StringArrayW_r MVszW; [case(PT_MV_SYSTIME)] DateTimeArray_r MVft; [case(PT_NULL)] uint32 null; } PROP_VAL_UNION; typedef [public]struct { MAPITAGS ulPropTag; uint32 dwAlignPad; [switch_is(ulPropTag & 0xFFFF)] PROP_VAL_UNION value; } PropertyValue_r; typedef struct { uint32 Reserved; [range(0,100000)] uint32 cValues; [size_is(cValues)] PropertyValue_r *lpProps; } PropertyRow_r; typedef [public] struct { [range(0,100000)] uint32 cRows; [size_is(cRows)] PropertyRow_r aRow[]; } PropertyRowSet_r; typedef struct { [range(0,100000)] uint32 cRes; [size_is(cRes)] Restriction_r *lpRes; } AndRestriction_r; typedef struct { [range(0,100000)] uint32 cRes; [size_is(cRes)] Restriction_r *lpRes; } OrRestriction_r; typedef struct { Restriction_r *lpRes; } NotRestriction_r; typedef struct { uint32 ulFuzzyLevel; MAPITAGS ulPropTag; PropertyValue_r *lpProp; } ContentRestriction_r; typedef struct { uint32 relop; MAPITAGS ulPropTag; PropertyValue_r *lpProp; } PropertyRestriction_r; typedef struct { uint32 relop; MAPITAGS ulPropTag1; MAPITAGS ulPropTag2; } ComparePropsRestriction_r; typedef struct { uint32 relMBR; MAPITAGS ulPropTag; uint32 ulMask; } BitMaskRestriction_r; typedef struct { uint32 relop; MAPITAGS ulPropTag; uint32 cb; } SizeRestriction_r; typedef struct { uint32 ulReserved1; MAPITAGS ulPropTag; uint32 ulReserved2; } ExistRestriction_r; typedef struct { uint32 ulSubObject; Restriction_r *lpRes; } SubRestriction_r; typedef [v1_enum] enum { RES_AND = 0x0, RES_OR = 0x1, RES_NOT = 0x2, RES_CONTENT = 0x3, RES_PROPERTY = 0x4, RES_COMPAREPROPS = 0x5, RES_BITMASK = 0x6, RES_SIZE = 0x7, RES_EXIST = 0x8, RES_SUBRESTRICTION = 0x9, RES_COMMENT = 0xA } RestrictionType_r; typedef [switch_type(uint32)] union { [case(RES_AND)] AndRestriction_r resAnd; [case(RES_OR)] OrRestriction_r resOr; [case(RES_NOT)] NotRestriction_r resNot; [case(RES_CONTENT)] ContentRestriction_r resContent; [case(RES_PROPERTY)] PropertyRestriction_r resProperty; [case(RES_COMPAREPROPS)] ComparePropsRestriction_r resCompareProps; [case(RES_BITMASK)] BitMaskRestriction_r resBitMask; [case(RES_SIZE)] SizeRestriction_r resSize; [case(RES_EXIST)] ExistRestriction_r resExist; [case(RES_SUBRESTRICTION)] SubRestriction_r resSub; } RestrictionUnion_r; typedef [public] struct _Restriction_r{ RestrictionType_r rt; [switch_is(rt)] RestrictionUnion_r res; } Restriction_r; /* Note: Those structs are used only internally by libmapi, the server code and the backend code, in order to provide 32 bits lengths to certain members (contrarily to mapi_SPropValue) and enable type-independence between different operations. They are derived from the PropertyValue_r/Row_r/RowSet_r structs and enhance them with certain types that are absent from NSPI and would otherwise break the data alignment on wire operations. However, they must be defined here as they make use of the same array types. */ typedef [nopush,nopull,noprint] struct { [range(0,100000)] uint32 cValues; [size_is(cValues)] hyper *lpui8; } UI8Array_r; typedef [switch_type(uint32),nopush,nopull,noprint] union { [case(PT_I2)] uint16 i; [case(PT_LONG)] uint32 l; [case(PT_DOUBLE)] double dbl; [case(PT_BOOLEAN)] uint8 b; [case(PT_I8)] dlong d; [case(PT_STRING8)][unique][string,charset(DOS)] uint8 *lpszA; [case(PT_BINARY)] Binary_r bin; [case(PT_SVREID)] Binary_r bin; [case(PT_UNICODE)][string,charset(UTF16)] uint16 *lpszW; [case(PT_CLSID)] FlatUID_r *lpguid; [case(PT_SYSTIME)] FILETIME ft; [case(PT_ERROR)] MAPISTATUS err; [case(PT_MV_I2)] ShortArray_r MVi; [case(PT_MV_LONG)] LongArray_r MVl; [case(PT_MV_I8)] UI8Array_r MVui8; [case(PT_MV_STRING8)] StringArray_r MVszA; [case(PT_MV_BINARY)] BinaryArray_r MVbin; [case(PT_MV_CLSID)] FlatUIDArray_r MVguid; [case(PT_MV_UNICODE)] StringArrayW_r MVszW; [case(PT_MV_SYSTIME)] DateTimeArray_r MVft; [case(PT_NULL)] uint32 null; [case(PT_OBJECT)] uint32 object; } SPropValue_CTR; typedef [public,noprint,nopush,nopull] struct { MAPITAGS ulPropTag; uint32 dwAlignPad; [switch_is(ulPropTag & 0xFFFF)] SPropValue_CTR value; } SPropValue; typedef [public,noprint,nopush,nopull] struct { uint32 ulAdrEntryPad; [range(0,100000)] uint32 cValues; [size_is(cValues)]SPropValue *lpProps; } SRow; typedef [public,noprint,nopush,nopull] struct { [range(0,100000)] uint32 cRows; [size_is(cRows)] SRow aRow[]; } SRowSet; /* /internal types */ /*****************/ /* Function 0x00 */ typedef [bitmap32bit] bitmap { fAnonymousLogin = 0x00000020 } NspiBind_dwFlags; MAPISTATUS NspiBind( [in] NspiBind_dwFlags dwFlags, [in] STAT *pStat, [in,out,unique] GUID *mapiuid, [out] policy_handle *handle ); /*****************/ /* Function 0x01 */ MAPISTATUS NspiUnbind( [in, out] policy_handle *handle, [in] uint32 Reserved ); /*****************/ /* Function 0x02 */ MAPISTATUS NspiUpdateStat( [in] policy_handle *handle, [in] uint32 Reserved, [in,out] STAT *pStat, [in,out,unique] uint32 *plDelta ); /*****************/ /* Function 0x03 */ typedef [bitmap32bit] bitmap { fSkipObjects = 0x00000001, fEphID = 0x00000002 } NspiQueryRows_dwFlags; MAPISTATUS NspiQueryRows( [in] policy_handle *handle, [in] NspiQueryRows_dwFlags dwFlags, [in,out] STAT *pStat, [in,range(0,100000)] uint32 dwETableCount, [in,unique,size_is(dwETableCount)] uint32 *lpETable, [in] uint32 Count, [in,unique] SPropTagArray *pPropTags, [out] PropertyRowSet_r **ppRows ); /*****************/ /* Function 0x04 */ MAPISTATUS NspiSeekEntries( [in] policy_handle *handle, [in] uint32 Reserved, [in,out] STAT *pStat, [in] PropertyValue_r *pTarget, [in,unique] PropertyTagArray_r *lpETable, [in,unique] SPropTagArray *pPropTags, [out] PropertyRowSet_r **pRows ); /*****************/ /* Function 0x05 */ MAPISTATUS NspiGetMatches( [in] policy_handle *handle, [in] uint32 Reserved, [in,out] STAT *pStat, [in][unique] SPropTagArray *pReserved, [in] uint32 Reserved2, [in][unique] Restriction_r *Filter, [in][unique] PropertyName_r *lpPropName, [in] uint32 ulRequested, [out] PropertyTagArray_r **ppOutMIds, [in][unique] SPropTagArray *pPropTags, [out] PropertyRowSet_r **ppRows ); /*****************/ /* Function 0x06 */ MAPISTATUS NspiResortRestriction( [in] policy_handle *handle, [in] uint32 Reserved, [in,out] STAT *pStat, [in] PropertyTagArray_r *pInMIds, [in,out] PropertyTagArray_r **ppMIds ); /*****************/ /* Function 0x07 */ MAPISTATUS NspiDNToMId( [in] policy_handle *handle, [in] uint32 Reserved, [in] StringsArray_r *pNames, [out] PropertyTagArray_r **ppMIds ); /*****************/ /* Function 0x08 */ MAPISTATUS NspiGetPropList( [in] policy_handle *handle, [in] uint32 dwFlags, [in] uint32 dwMId, [in] uint32 CodePage, [out] SPropTagArray **ppPropTags ); /*****************/ /* Function 0x09 */ MAPISTATUS NspiGetProps( [in] policy_handle *handle, [in] uint32 dwFlags, [in] STAT *pStat, [in,unique] SPropTagArray *pPropTags, [out] PropertyRow_r **ppRows ); /*****************/ /* Funcion 0xa */ MAPISTATUS NspiCompareMIds( [in] policy_handle *handle, [in] uint32 Reserved, [in] STAT *pStat, [in] uint32 MId1, [in] uint32 MId2, [out] uint32 *plResult ); /*****************/ /* Function 0xb */ MAPISTATUS NspiModProps( [in] policy_handle *handle, [in] uint32 Reserved, [in] STAT *pStat, [in,unique] SPropTagArray *pPropTags, [in] PropertyRow_r *pRow ); /*****************/ /* Function 0x0c */ typedef [bitmap32bit] bitmap { NspiAddressCreationTemplates = 0x00000002, NspiUnicodeStrings = 0x00000004 } NspiGetSpecialTable_dwFlags; MAPISTATUS NspiGetSpecialTable( [in] policy_handle *handle, [in] NspiGetSpecialTable_dwFlags dwFlags, [in] STAT *pStat, [in,out] uint32 *lpVersion, [out] PropertyRowSet_r **ppRows ); /*******************/ /* Function 0x0d */ typedef [bitmap32bit] bitmap { TI_TEMPLATE = 0x00000001, TI_SCRIPT = 0x00000004, TI_EMT = 0x00000010, TI_HELPFILE_NAME = 0x00000020, TI_HELPFILE_CONTENTS = 0x00000040 } TI_dwFlags; MAPISTATUS NspiGetTemplateInfo( [in] policy_handle *handle, [in] TI_dwFlags dwFlags, [in] uint32 ulType, [in,unique,string,charset(DOS)] uint8 *pDN, [in] uint32 dwCodePage, [in] uint32 dwLocaleID, [out] PropertyRow_r **ppData ); /*******************/ /* Function 0x0e */ MAPISTATUS NspiModLinkAtt( [in] policy_handle *handle, [in] uint32 dwFlags, [in] MAPITAGS ulPropTag, [in] uint32 MId, [in] BinaryArray_r *lpEntryIds ); /*************************************/ /* Function 0x0f: Not used on wire */ MAPISTATUS NspiDeleteEntries( [in] policy_handle *Reserved1, [in] uint32 Reserved2, [in] uint32 Reserved3, [in] BinaryArray_r *Reserved4 ); /*******************/ /* Function 0x10 */ typedef [bitmap32bit] bitmap { NspiUnicodeProptypes = 0x80000000 } NspiQueryColumns_dwFlags; MAPISTATUS NspiQueryColumns( [in] policy_handle *handle, [in] uint32 Reserved, [in] NspiQueryColumns_dwFlags dwFlags, [out] SPropTagArray **ppColumns ); /*******************/ /* Function 0x11 */ MAPISTATUS NspiGetNamesFromIDs( [in] policy_handle *handle, [in] uint32 Reserved, [in,unique] FlatUID_r *lpGuid, [in,unique] SPropTagArray *pPropTags, [out] SPropTagArray **ppReturnedPropTags, [out] PropertyNameSet_r **ppNames ); /*******************/ /* Function 0x12 */ MAPISTATUS NspiGetIDsFromNames( [in] policy_handle *handle, [in] uint32 Reserved, [in] uint32 dwFlags, [in,range(0,100000)] uint32 cPropNames, [in,size_is(cPropNames)] PropertyName_r **ppNames, [out] SPropTagArray **ppPropTags ); /*****************/ /* Function 0x13 */ MAPISTATUS NspiResolveNames( [in] policy_handle *handle, [in] uint32 Reserved, [in] STAT *pStat, [in,unique] SPropTagArray *pPropTags, [in] StringsArray_r *paStr, [out] PropertyTagArray_r **ppMIds, [out] PropertyRowSet_r **ppRows ); /*****************/ /* Function 0x14 */ MAPISTATUS NspiResolveNamesW( [in] policy_handle *handle, [in] uint32 Reserved, [in] STAT *pStat, [in,unique] SPropTagArray *pPropTags, [in] StringsArrayW_r *paWStr, [out] PropertyTagArray_r **ppMIds, [out] PropertyRowSet_r **ppRows ); } [ uuid("a4f1db00-ca47-1067-b31f-00dd010662da"), pointer_default(unique), endpoint("ncacn_np:[\\pipe\\lsass]","ncacn_np:[\\pipe\\protected_storage]","ncacn_ip_tcp:"), authservice("exchangeMDB"), //version(0.81), version(5308416), helpstring("Exchange 5.5 EMSMDB") ] interface exchange_emsmdb { /*****************/ /* Function 0x00 */ MAPISTATUS EcDoConnect( [out] policy_handle *handle, [in,string,charset(DOS)] uint8 szUserDN[], [in] uint32 ulFlags, [in] uint32 ulConMod, [in] uint32 cbLimit, [in] uint32 ulCpid, [in] uint32 ulLcidString, [in] uint32 ulLcidSort, [in] uint32 ulIcxrLink, [in] uint16 usFCanConvertCodePages, [out] uint32 *pcmsPollsMax, [out] uint32 *pcRetry, [out] uint32 *pcmsRetryDelay, [out] uint32 *picxr, [out,ref,string,charset(DOS)]uint8 **szDNPrefix, [out,ref,string,charset(DOS)]uint8 **szDisplayName, [out] uint16 rgwServerVersion[3], [in,out] uint16 rgwClientVersion[3], [in,out] uint32 *pullTimeStamp ); /*****************/ /* Function 0x01 */ MAPISTATUS EcDoDisconnect( [in,out] policy_handle *handle ); /*****************/ /* Function 0x02 */ /* EcDoRpc opnums */ typedef [public, enum8bit, flag(NDR_PAHEX)] enum { MAPI_STORE = 0x1, MAPI_ADDRBOOK = 0x2, MAPI_FOLDER = 0x3, MAPI_ABCONT = 0x4, MAPI_MESSAGE = 0x5, MAPI_MAILUSER = 0x6, /* Individual Recipient */ MAPI_ATTACH = 0x7, MAPI_DISTLIST = 0x8, MAPI_PROFSECT = 0x9, MAPI_STATUS = 0xA, MAPI_SESSION = 0xB, MAPI_FORMINFO = 0xC } MAPI_OBJTYPE; typedef [public, v1_enum, flag(NDR_PAHEX)] enum { RightsNone = 0x00000000, RightsReadItems = 0x00000001, RightsCreateItems = 0x00000002, RightsEditOwn = 0x00000008, RightsDeleteOwn = 0x00000010, RightsEditAll = 0x00000020, RightsDeleteAll = 0x00000040, RightsCreateSubfolders = 0x00000080, RightsFolderOwner = 0x00000100, RightsFolderContact = 0x00000200, RoleNone = 0x00000400, RoleReviewer = 0x00000401, RoleContributor = 0x00000402, RoleNoneditingAuthor = 0x00000413, RoleAuthor = 0x0000041B, RoleEditor = 0x0000047B, RolePublishAuthor = 0x0000049B, RolePublishEditor = 0x000004FB, RightsAll = 0x000005FB, RoleOwner = 0x000007FB } ACLRIGHTS; typedef [public, enum8bit, flag(NDR_PAHEX)] enum { op_MAPI_Release = 0x1, op_MAPI_OpenFolder = 0x2, op_MAPI_OpenMessage = 0x3, op_MAPI_GetHierarchyTable = 0x4, op_MAPI_GetContentsTable = 0x5, op_MAPI_CreateMessage = 0x6, op_MAPI_GetProps = 0x7, op_MAPI_GetPropsAll = 0x8, op_MAPI_GetPropList = 0x9, op_MAPI_SetProps = 0xa, op_MAPI_DeleteProps = 0xb, op_MAPI_SaveChangesMessage = 0xc, op_MAPI_RemoveAllRecipients = 0xd, op_MAPI_ModifyRecipients = 0xe, op_MAPI_ReadRecipients = 0xf, op_MAPI_ReloadCachedInformation = 0x10, op_MAPI_SetMessageReadFlag = 0x11, op_MAPI_SetColumns = 0x12, op_MAPI_SortTable = 0x13, op_MAPI_Restrict = 0x14, op_MAPI_QueryRows = 0x15, op_MAPI_GetStatus = 0x16, op_MAPI_QueryPosition = 0x17, op_MAPI_SeekRow = 0x18, op_MAPI_SeekRowBookmark = 0x19, op_MAPI_SeekRowApprox = 0x1a, op_MAPI_CreateBookmark = 0x1b, op_MAPI_CreateFolder = 0x1c, op_MAPI_DeleteFolder = 0x1d, op_MAPI_DeleteMessages = 0x1e, op_MAPI_GetMessageStatus = 0x1f, op_MAPI_SetMessageStatus = 0x20, op_MAPI_GetAttachmentTable = 0x21, op_MAPI_OpenAttach = 0x22, op_MAPI_CreateAttach = 0x23, op_MAPI_DeleteAttach = 0x24, op_MAPI_SaveChangesAttachment = 0x25, op_MAPI_SetReceiveFolder = 0x26, op_MAPI_GetReceiveFolder = 0x27, op_MAPI_RegisterNotification = 0x29, op_MAPI_Notify = 0x2a, op_MAPI_OpenStream = 0x2b, op_MAPI_ReadStream = 0x2c, op_MAPI_WriteStream = 0x2d, op_MAPI_SeekStream = 0x2e, op_MAPI_SetStreamSize = 0x2f, op_MAPI_SetSearchCriteria = 0x30, op_MAPI_GetSearchCriteria = 0x31, op_MAPI_SubmitMessage = 0x32, op_MAPI_MoveCopyMessages = 0x33, op_MAPI_AbortSubmit = 0x34, op_MAPI_MoveFolder = 0x35, op_MAPI_CopyFolder = 0x36, op_MAPI_QueryColumnsAll = 0x37, op_MAPI_Abort = 0x38, op_MAPI_CopyTo = 0x39, op_MAPI_CopyToStream = 0x3a, op_MAPI_CloneStream = 0x3b, op_MAPI_GetPermissionsTable = 0x3e, op_MAPI_GetRulesTable = 0x3f, op_MAPI_ModifyPermissions = 0x40, op_MAPI_ModifyRules = 0x41, op_MAPI_GetOwningServers = 0x42, op_MAPI_LongTermIdFromId = 0x43, op_MAPI_IdFromLongTermId = 0x44, op_MAPI_PublicFolderIsGhosted = 0x45, op_MAPI_OpenEmbeddedMessage = 0x46, op_MAPI_SetSpooler = 0x47, op_MAPI_SpoolerLockMessage = 0x48, op_MAPI_AddressTypes = 0x49, op_MAPI_TransportSend = 0x4a, op_MAPI_FastTransferSourceCopyMessages = 0x4b, op_MAPI_FastTransferSourceCopyFolder = 0x4c, op_MAPI_FastTransferSourceCopyTo = 0x4d, op_MAPI_FastTransferSourceGetBuffer = 0x4e, op_MAPI_FindRow = 0x4f, op_MAPI_Progress = 0x50, op_MAPI_TransportNewMail = 0x51, op_MAPI_GetValidAttachments = 0x52, op_MAPI_FastTransferDestConfigure = 0x53, op_MAPI_FastTransferDestPutBuffer = 0x54, op_MAPI_GetNamesFromIDs = 0x55, op_MAPI_GetIDsFromNames = 0x56, op_MAPI_UpdateDeferredActionMessages = 0x57, op_MAPI_EmptyFolder = 0x58, op_MAPI_ExpandRow = 0x59, op_MAPI_CollapseRow = 0x5a, op_MAPI_LockRegionStream = 0x5b, op_MAPI_UnlockRegionStream = 0x5c, op_MAPI_CommitStream = 0x5d, op_MAPI_GetStreamSize = 0x5e, op_MAPI_QueryNamedProperties = 0x5f, op_MAPI_GetPerUserLongTermIds = 0x60, op_MAPI_GetPerUserGuid = 0x61, op_MAPI_ReadPerUserInformation = 0x63, op_MAPI_WritePerUserInformation = 0x64, op_MAPI_SetReadFlags = 0x66, op_MAPI_CopyProperties = 0x67, op_MAPI_GetReceiveFolderTable = 0x68, op_MAPI_FastTransferSourceCopyProps = 0x69, op_MAPI_GetCollapseState = 0x6b, op_MAPI_SetCollapseState = 0x6c, op_MAPI_GetTransportFolder = 0x6d, op_MAPI_Pending = 0x6e, op_MAPI_OptionsData = 0x6f, op_MAPI_SyncConfigure = 0x70, op_MAPI_SyncImportMessageChange = 0x72, op_MAPI_SyncImportHierarchyChange = 0x73, op_MAPI_SyncImportDeletes = 0x74, op_MAPI_SyncUploadStateStreamBegin = 0x75, op_MAPI_SyncUploadStateStreamContinue = 0x76, op_MAPI_SyncUploadStateStreamEnd = 0x77, op_MAPI_SyncImportMessageMove = 0x78, op_MAPI_SetPropertiesNoReplicate = 0x79, op_MAPI_DeletePropertiesNoReplicate = 0x7a, op_MAPI_GetStoreState = 0x7b, op_MAPI_SyncOpenCollector = 0x7e, op_MAPI_GetLocalReplicaIds = 0x7f, op_MAPI_SyncImportReadStateChanges = 0x80, op_MAPI_ResetTable = 0x81, op_MAPI_SyncGetTransferState = 0x82, op_MAPI_SyncOpenAdvisor = 0x83, op_MAPI_TellVersion = 0x86, op_MAPI_OpenPublicFolderByName = 0x87, op_MAPI_SetSyncNotificationGuid = 0x88, op_MAPI_FreeBookmark = 0x89, op_MAPI_WriteAndCommitStream = 0x90, op_MAPI_HardDeleteMessages = 0x91, op_MAPI_HardDeleteMessagesAndSubfolders = 0x92, op_MAPI_SetLocalReplicaMidsetDeleted = 0x93, op_MAPI_Backoff = 0xf9, op_MAPI_Logon = 0xfe, op_MAPI_BufferTooSmall = 0xff, /****** custom MAPI opnum for mapiproxy ******/ op_MAPI_proxypack = 0xa5 } MAPI_OPNUM; typedef [public,noprint,flag(NDR_NOALIGN)] struct { uint16 cb; [flag(NDR_BUFFERS)]uint8 lpb[cb]; } SBinary_short; typedef [public] struct { uint32 cValues; uint32 lpl[cValues]; } mapi_MV_LONG_STRUCT; typedef struct { raw8string lppszA; } mapi_LPSTR; typedef [public] struct { uint32 cValues; mapi_LPSTR strings[cValues]; } mapi_SLPSTRArray; typedef [public] struct { [flag(STR_NULLTERM)] string lppszW; } mapi_LPWSTR; typedef [public] struct { uint32 cValues; mapi_LPWSTR strings[cValues]; } mapi_SLPSTRArrayW; typedef [public] struct { uint32 cValues; SBinary_short bin[cValues]; } mapi_SBinaryArray; typedef [public] struct { uint32 cValues; GUID lpguid[cValues]; } mapi_SGuidArray; /******* part of the no-pointer deep recursion hack *******/ typedef [nopull,nopush,noprint,flag(NDR_NOALIGN)] struct { uint8 wrap[0x8000]; } mapi_SRestriction_wrap; typedef [nopush,nopull,noprint,flag(NDR_NOALIGN)] struct { uint8 wrap[0x8000]; } mapi_SPropValue_wrap; typedef [nopush,nopull,noprint,flag(NDR_NOALIGN)] struct { uint8 wrap[0x8000]; } mapi_SPropValue_array_wrap; /**********************************************************/ typedef [enum8bit] enum { ActionType_OP_MOVE = 0x1, ActionType_OP_COPY = 0x2, ActionType_OP_REPLY = 0x3, ActionType_OP_OOF_REPLY = 0x4, ActionType_OP_DEFER_ACTION = 0x5, ActionType_OP_BOUNCE = 0x6, ActionType_OP_FORWARD = 0x7, ActionType_OP_DELEGATE = 0x8, ActionType_OP_TAG = 0x9, ActionType_OP_DELETE = 0xA, ActionType_OP_MARK_AS_READ = 0xB } ActionType; typedef [flag(NDR_NOALIGN)] struct { boolean8 FolderInThisStore; SBinary_short StoreEID; SBinary_short FolderEID; } MoveCopy_Action; typedef [flag(NDR_NOALIGN)] struct { hyper ReplyTemplateFID; hyper ReplyTemplateMID; GUID ReplyTemplateGUID; } ReplyOOF_Action; typedef [flag(NDR_NOALIGN)] struct { uint8 Reserved; mapi_SPropValue_array_wrap PropertyValue; } RecipientBlock; typedef [flag(NDR_NOALIGN)] enum { BOUNCE_MESSAGE_TOO_LARGE = 0x0000000d, BOUNCE_MESSAGE_NOT_DISPLAYED = 0x0000001f, BOUNCE_MESSAGE_DENIED = 0x00000026 } BounceCode; typedef [flag(NDR_NOALIGN)] struct { uint16 RecipientCount; RecipientBlock RecipientBlock[RecipientCount]; } ForwardDelegate_Action; typedef [nodiscriminant, flag(NDR_NOALIGN)] union { [case(ActionType_OP_MOVE)] MoveCopy_Action MoveAction; [case(ActionType_OP_COPY)] MoveCopy_Action CopyAction; [case(ActionType_OP_REPLY)] ReplyOOF_Action ReplyAction; [case(ActionType_OP_OOF_REPLY)] ReplyOOF_Action ReplyOOFAction; [case(ActionType_OP_DEFER_ACTION)][flag(NDR_REMAINING|NDR_NOALIGN)] DATA_BLOB DeferAction; [case(ActionType_OP_BOUNCE)] BounceCode BounceCode; [case(ActionType_OP_TAG)] mapi_SPropValue_wrap PropValue; [case(ActionType_OP_FORWARD)] ForwardDelegate_Action ForwardAction; [case(ActionType_OP_DELEGATE)] ForwardDelegate_Action DelegateAction; [case(ActionType_OP_DELETE)]; [case(ActionType_OP_MARK_AS_READ)]; } ActionData; typedef [flag(NDR_NOALIGN)] struct { ActionType ActionType; uint32 ActionFlavor; uint32 ActionFlags; [switch_is(ActionType)] ActionData ActionDataBuffer; } ActionBlockData; typedef [flag(NDR_NOALIGN)] struct { uint16 ActionLength; [subcontext(0),subcontext_size(ActionLength),flag(NDR_REMAINING|NDR_NOALIGN)] ActionBlockData ActionBlockData; } ActionBlock; typedef [flag(NDR_NOALIGN)] struct { uint16 count; ActionBlock ActionBlock[count]; } RuleAction; typedef [public,nodiscriminant,flag(NDR_NOALIGN)] union { [case(PT_NULL)]; [case(PT_I2)] uint16 i; [case(PT_LONG)] uint32 l; [case(PT_DOUBLE)] double dbl; [case(PT_ERROR)] uint32 err; [case(PT_BOOLEAN)] uint8 b; [case(PT_I8)] dlong d; [case(PT_STRING8)] raw8string lpszA; [case(PT_UNICODE)][flag(STR_NULLTERM)] string lpszW; [case(PT_SYSTIME)] FILETIME ft; [case(PT_CLSID)] GUID lpguid; [case(PT_SRESTRICT)] mapi_SRestriction_wrap Restrictions; [case(PT_ACTIONS)] RuleAction RuleAction; [case(PT_BINARY)] SBinary_short bin; [case(PT_SVREID)] SBinary_short bin; [case(PT_MV_LONG)] mapi_MV_LONG_STRUCT MVl; [case(PT_MV_STRING8)] mapi_SLPSTRArray MVszA; [case(PT_MV_UNICODE)] mapi_SLPSTRArrayW MVszW; [case(PT_MV_CLSID)] mapi_SGuidArray MVguid; [case(PT_MV_BINARY)] mapi_SBinaryArray MVbin; } mapi_SPropValue_CTR; typedef [public,flag(NDR_NOALIGN)] struct { MAPITAGS ulPropTag; [switch_is(ulPropTag & 0xFFFF)] mapi_SPropValue_CTR value; } mapi_SPropValue; typedef [public,flag(NDR_NOALIGN)] struct { uint16 cValues; [flag(NDR_REMAINING|NDR_NOALIGN)]mapi_SPropValue lpProps[cValues]; } mapi_SPropValue_array; typedef [flag(NDR_NOALIGN)] struct { uint16 cValues; MAPITAGS aulPropTag[cValues]; } mapi_SPropTagArray; typedef [enum8bit, flag(NDR_PAHEX)] enum { ROW_ADD = 0x1, ROW_MODIFY = 0x2, ROW_REMOVE = 0x4 } ulRowFlags; /**************************/ /* EcDoRpc Function 0x1 */ typedef [nopush,nopull,flag(NDR_NOALIGN)] struct { } Release_req; typedef [nopush,nopull,flag(NDR_NOALIGN)] struct { } Release_repl; /**************************/ /* EcDoRpc Function 0x2 */ typedef [enum8bit] enum { OpenModeFlags_Folder = 0x0, OpenModeFlags_SoftDeleted = 0x4 } OpenFolder_OpenModeFlags; typedef [flag(NDR_NOALIGN)] struct { uint8 handle_idx; hyper folder_id; OpenFolder_OpenModeFlags OpenModeFlags; } OpenFolder_req; typedef [flag(NDR_NOALIGN)] struct { uint16 ServerCount; uint16 CheapServerCount; astring Servers[ServerCount]; } OpenFolder_Replicas; typedef [nodiscriminant, flag(NDR_NOALIGN)] union { [case(0x0)]; [case(0x1)] OpenFolder_Replicas Replicas; } IsGhosted; typedef [flag(NDR_NOALIGN)] struct { boolean8 HasRules; boolean8 IsGhosted; [switch_is(IsGhosted)] IsGhosted Ghost; } OpenFolder_repl; /**************************/ /* EcDoRpc Function 0x3 */ typedef [enum8bit] enum { StringType_NONE = 0x0, StringType_EMPTY = 0x1, StringType_STRING8 = 0x2, StringType_UNICODE_REDUCED = 0x3, StringType_UNICODE = 0x4 } StringType; typedef [nodiscriminant, flag(NDR_NOALIGN)] union { [case(0x0)]; [case(0x1)]; [case(0x2)] raw8string lpszA; [case(0x3)] raw8string lpszW_reduced; [case(0x4)] [flag(STR_NULLTERM)] string lpszW; } String; typedef [flag(NDR_NOALIGN)] struct { StringType StringType; [switch_is(StringType)] String String; } TypedString; typedef [enum8bit] enum { ReadOnly = 0x0, ReadWrite = 0x1, BestAccess = 0x3, OpenSoftDelete = 0x4 } OpenMessage_OpenModeFlags; typedef [flag(NDR_NOALIGN)] struct { uint8 handle_idx; uint16 CodePageId; hyper FolderId; OpenMessage_OpenModeFlags OpenModeFlags; hyper MessageId; } OpenMessage_req; typedef [enum16bit, flag(NDR_PAHEX)] enum { CP_USASCII = 0x04E4, CP_UNICODE = 0x04B0, CP_JAUTODETECT = 0xC6F4, CP_KAUTODETECT = 0xC705, CP_ISO2022JPESC = 0xC42D, CP_ISO2022JPSIO = 0xC42E } CODEPAGEID; typedef [enum8bit, flag(NDR_PAHEX)] enum { MAPI_ORIG = 0x0, MAPI_TO = 0x1, MAPI_CC = 0x2, MAPI_BCC = 0x3 } ulRecipClass; typedef [enum8bit, flag(NDR_PAHEX)] enum { SINGLE_RECIPIENT = 0x0, DISTRIBUTION_LIST = 0x1 } addr_type; typedef [nodiscriminant, flag(NDR_NOALIGN)] union { [case(0x1)] uint8 prefix_size; [default]; } recipient_AddressPrefixUsed; typedef [nodiscriminant, flag(NDR_NOALIGN)] union { [case(0x1)] addr_type display_type; [default]; } recipient_DisplayType; typedef [nodiscriminant, flag(NDR_NOALIGN)] union { [case(0x1)] astring recipient_x500name; [default]; } recipient_X500DN; /* We're covering the PersonalDistributionList1 (0x0006) and PersonalDistributionList2 (0x0007) variations here, since we mask off the low bit in the switch. */ typedef [nodiscriminant, flag(NDR_NOALIGN)] union { [case(0x6)] SBinary_short entryid; [default]; } recipient_EntryId; /* We're covering the PersonalDistributionList1 (0x0006) and PersonalDistributionList2 (0x0007) variations here, since we mask off the low bit in the switch. */ typedef [nodiscriminant, flag(NDR_NOALIGN)] union { [case(0x6)] SBinary_short searchkey; [default]; } recipient_SearchKey; /* Present if the Type field is set to NoType (0x0) and the O flag (0x8000) is set */ typedef [nodiscriminant, flag(NDR_NOALIGN)] union { [case(0x8000)] astring lpszA; [default]; } recipient_AddressType; typedef [nodiscriminant, flag(NDR_NOALIGN)] union { [case(0x400)] raw8string lpszA; [case(0x600)][flag(STR_NULLTERM)] string lpszW; [default]; } recipient_SimpleDisplayName; typedef [nodiscriminant, flag(NDR_NOALIGN)] union { [case(0x20)] raw8string lpszA; [case(0x220)][flag(STR_NULLTERM)] string lpszW; [default]; } recipient_TransmittableDisplayName; typedef [nodiscriminant, flag(NDR_NOALIGN)] union { [case(0x10)] raw8string lpszA; [case(0x210)][flag(STR_NULLTERM)] string lpszW; [default]; } recipient_DisplayName; typedef [nodiscriminant, flag(NDR_NOALIGN)] union { [case(0x8)] astring lpszA; [case(0x208)][flag(STR_NULLTERM)] string lpszW; [default]; } recipient_EmailAddress; typedef [flag(NDR_NOALIGN)] struct { uint16 RecipientFlags; [switch_is(RecipientFlags & 0x0007)] recipient_AddressPrefixUsed AddressPrefixUsed; [switch_is(RecipientFlags & 0x0007)] recipient_DisplayType DisplayType; [switch_is(RecipientFlags & 0x0007)] recipient_X500DN X500DN; [switch_is(RecipientFlags & 0x0006)] recipient_EntryId EntryId; [switch_is(RecipientFlags & 0x0006)] recipient_SearchKey SearchKey; [switch_is(RecipientFlags & 0x8007)] recipient_AddressType AddressType; [switch_is(RecipientFlags & 0x0208)] recipient_EmailAddress EmailAddress; [switch_is(RecipientFlags & 0x0210)] recipient_DisplayName DisplayName; [switch_is(RecipientFlags & 0x0600)] recipient_SimpleDisplayName SimpleDisplayName; [switch_is(RecipientFlags & 0x0220)] recipient_TransmittableDisplayName TransmittableDisplayName; uint16 prop_count; // TODO: figure out if "layout" can go uint8 layout; // TODO: convert this to a proper structure - see if we already have one. [flag(NDR_REMAINING|NDR_NOALIGN)] DATA_BLOB prop_values; } RecipientRow; typedef [flag(NDR_NOALIGN)] struct { boolean8 HasNamedProperties; TypedString SubjectPrefix; TypedString NormalizedSubject; uint16 RecipientCount; mapi_SPropTagArray RecipientColumns; uint8 RowCount; OpenRecipientRow RecipientRows[RowCount]; } OpenMessage_repl; /**************************/ /* EcDoRpc Function 0x4 */ typedef [bitmap8bit] bitmap { TableFlags_Associated = 0x2, /* only for GetContentsTable */ TableFlags_Depth = 0x4, /* only for GetHierarchyTable */ TableFlags_DeferredErrors = 0x8, TableFlags_NoNotifications = 0x10, TableFlags_SoftDeletes = 0x20, TableFlags_UseUnicode = 0x40, TableFlags_SuppressNotifications = 0x80 } TableFlags; typedef [flag(NDR_NOALIGN)] struct { uint8 handle_idx; TableFlags TableFlags; } GetHierarchyTable_req; typedef [flag(NDR_NOALIGN)] struct { uint32 RowCount; } GetHierarchyTable_repl; /**************************/ /* EcDoRpc Function 0x5 */ typedef [flag(NDR_NOALIGN)] struct { uint8 handle_idx; TableFlags TableFlags; } GetContentsTable_req; typedef [flag(NDR_NOALIGN)] struct { uint32 RowCount; } GetContentsTable_repl; /**************************/ /* EcDoRpc Function 0x6 */ typedef [flag(NDR_NOALIGN)] struct { uint8 handle_idx; uint16 CodePageId; hyper FolderId; boolean8 AssociatedFlag; } CreateMessage_req; typedef [nodiscriminant, flag(NDR_NOALIGN)] union { [case(0x0)]; [case(0x1)] hyper MessageId; } CreateMessage_MessageId; typedef [flag(NDR_NOALIGN)] struct { boolean8 HasMessageId; [switch_is(HasMessageId)] CreateMessage_MessageId MessageId; } CreateMessage_repl; /*************************/ /* EcDoRpc Function 0x7 */ typedef [flag(NDR_NOALIGN)] struct { uint16 PropertySizeLimit; uint16 WantUnicode; uint16 prop_count; MAPITAGS properties[prop_count]; } GetProps_req; typedef [flag(NDR_NOALIGN)] struct { uint8 layout; [flag(NDR_REMAINING|NDR_NOALIGN)] DATA_BLOB prop_data; } GetProps_repl; /*************************/ /* EcDoRpc Function 0x8 */ typedef [flag(NDR_NOALIGN)] struct { uint16 PropertySizeLimit; uint16 WantUnicode; } GetPropsAll_req; typedef [flag(NDR_NOALIGN)] struct { mapi_SPropValue_array properties; } GetPropsAll_repl; /*************************/ /* EcDoRpc Function 0x9 */ typedef [flag(NDR_NOALIGN)] struct { } GetPropList_req; typedef [flag(NDR_NOALIGN)] struct { uint16 count; MAPITAGS tags[count]; } GetPropList_repl; /*************************/ /* EcDoRpc Function 0xa */ typedef [flag(NDR_NOALIGN)] struct { uint32 index; /* index into array of property tags */ MAPITAGS property_tag; /* property for which there was an error */ MAPISTATUS error_code; /* the error that occurred for this property */ } PropertyProblem; typedef [flag(NDR_NOALIGN)] struct { [subcontext(2)] mapi_SPropValue_array values; } SetProps_req; typedef [flag(NDR_NOALIGN)] struct { uint16 PropertyProblemCount; PropertyProblem PropertyProblem[PropertyProblemCount]; } SetProps_repl; /*************************/ /* EcDoRpc Function 0xb */ typedef [flag(NDR_NOALIGN)] struct { uint16 count; MAPITAGS tags[count]; } DeleteProps_req; typedef [flag(NDR_NOALIGN)] struct { uint16 PropertyProblemCount; PropertyProblem PropertyProblem[PropertyProblemCount]; } DeleteProps_repl; /*************************/ /* EcDoRpc Function 0xc */ typedef [enum8bit] enum { KeepOpenReadOnly = 0x9, KeepOpenReadWrite = 0xA, ForceSave = 0xC } SaveFlags; typedef [flag(NDR_NOALIGN)] struct { uint8 handle_idx; uint8 SaveFlags; } SaveChangesMessage_req; typedef [flag(NDR_NOALIGN)] struct { uint8 handle_idx; hyper MessageId; } SaveChangesMessage_repl; /*************************/ /* EcDoRpc Function 0xd */ typedef [flag(NDR_NOALIGN)] struct { uint32 ulReserved; } RemoveAllRecipients_req; typedef [flag(NDR_NOALIGN)] struct { } RemoveAllRecipients_repl; /*************************/ /* EcDoRpc Function 0xe */ /* * MODRECIP_NULL and INVALID are not part of the msdn flags * but are added for printing support */ typedef [enum8bit,flag(NDR_PAHEX)] enum { MODRECIP_NULL = 0x0, MODRECIP_INVALID = 0x1, MODRECIP_ADD = 0x2, MODRECIP_MODIFY = 0x4, MODRECIP_REMOVE = 0x8 } modrecip; typedef [flag(NDR_NOALIGN)]struct { uint32 idx; ulRecipClass RecipClass; [subcontext(2),flag(NDR_REMAINING|NDR_NOALIGN)] RecipientRow RecipientRow; } ModifyRecipientRow; typedef [flag(NDR_NOALIGN)] struct { uint16 prop_count; MAPITAGS properties[prop_count]; uint16 cValues; ModifyRecipientRow RecipientRow[cValues]; } ModifyRecipients_req; typedef [flag(NDR_NOALIGN)] struct { } ModifyRecipients_repl; /*************************/ /* EcDoRpc Function 0xf */ typedef [flag(NDR_NOALIGN)] struct { uint32 RowId; uint16 ulReserved; } ReadRecipients_req; typedef [flag(NDR_NOALIGN)] struct { uint32 RowId; ulRecipClass RecipClass; CODEPAGEID CodePageId; uint16 ulReserved; [subcontext(2)] RecipientRow RecipientRow; } ReadRecipientRow; typedef [flag(NDR_NOALIGN)] struct { uint8 RowCount; ReadRecipientRow RecipientRows[RowCount]; } ReadRecipients_repl; /*************************/ /* EcDoRpc Function 0x10 */ typedef [public,flag(NDR_NOALIGN)] struct { ulRecipClass RecipientType; CODEPAGEID CodePageId; uint16 Reserved; [subcontext(2)]RecipientRow RecipientRow; } OpenRecipientRow; typedef [flag(NDR_NOALIGN)] struct { uint16 Reserved; } ReloadCachedInformation_req; typedef [flag(NDR_NOALIGN)] struct { boolean8 HasNamedProperties; TypedString SubjectPrefix; TypedString NormalizedSubject; uint16 RecipientCount; mapi_SPropTagArray RecipientColumns; uint8 RowCount; OpenRecipientRow RecipientRows[RowCount]; } ReloadCachedInformation_repl; /*************************/ /* EcDoRpc Function 0x11 */ typedef [bitmap8bit] bitmap { SUPPRESS_RECEIPT = 0x01, CLEAR_READ_FLAG = 0x04, GENERATE_RECEIPT_ONLY = 0x10, CLEAR_RN_PENDING = 0x20, CLEAR_NRN_PENDING = 0x40 } MSGFLAG_READ; /* TODO: there is a variation that can provide "client data" here clientdata is a uint8 ClientData[24], but its existence within the request depends on flags associated to logon_id: it the private flag set or not */ typedef [flag(NDR_NOALIGN)] struct { uint8 handle_idx; MSGFLAG_READ flags; /* TEMP HACK for editing notes without crashing Outlook: [flag(NDR_REMAINING|NDR_NOALIGN)] DATA_BLOB clientdata; */ } SetMessageReadFlag_req; typedef [nodiscriminant, flag(NDR_NOALIGN)] union { [case(0x0)]; [case(0x1)] uint8 LogonId; } SetMessageReadFlag_LogonId; typedef [nodiscriminant, flag(NDR_NOALIGN)] union { [case(0x0)]; [case(0x1)] uint8 ClientData[24]; } SetMessageReadFlag_ClientData; typedef [flag(NDR_NOALIGN)] struct { boolean8 ReadStatusChanged; [switch_is(ReadStatusChanged)] SetMessageReadFlag_LogonId LogonId; /* TEMP HACK for editing notes without crashing Outlook: [switch_is(ReadStatusChanged)] SetMessageReadFlag_ClientData ClientData; */ } SetMessageReadFlag_repl; /*************************/ /* EcDoRpc Function 0x12 */ typedef [enum8bit] enum { SetColumns_TBL_SYNC = 0x0, SetColumns_TBL_ASYNC = 0x1 } SetColumnsFlags; typedef [enum8bit] enum { TBLSTAT_COMPLETE = 0x0, TBLSTAT_SORTING = 0x9, TBLSTAT_SORT_ERROR = 0xA, TBLSTAT_SETTING_COLS = 0xB, TBLSTAT_SETCOL_ERROR = 0xD, TBLSTAT_RESTRICTING = 0xE, TBLSTAT_RESTRICT_ERROR = 0xF } TableStatus; typedef [flag(NDR_NOALIGN)] struct { SetColumnsFlags SetColumnsFlags; uint16 prop_count; MAPITAGS properties[prop_count]; } SetColumns_req; typedef [flag(NDR_NOALIGN)] struct { TableStatus TableStatus; } SetColumns_repl; /**************************/ /* EcDoRpc Function 0x13 */ typedef [enum8bit, flag(NDR_PAHEX)] enum { TBL_ASYNC = 0x1, TBL_BATCH = 0x2 } TBL_FLAGS; typedef [enum8bit, flag(NDR_PAHEX)] enum { TABLE_SORT_ASCEND = 0x0, TABLE_SORT_DESCEND = 0x1, TABLE_SORT_MAXIMUM_CATEGORY = 0x4 /* old values : TABLE_SORT_COMBINE = 0x1, TABLE_SORT_DESCEND = 0x2 */ } TABLE_SORT; typedef [public, flag(NDR_NOALIGN)] struct _SSortOrder{ MAPITAGS ulPropTag; TABLE_SORT ulOrder; } SSortOrder; typedef [public, flag(NDR_NOALIGN)] struct _SSortOrderSet { uint16 cSorts; uint16 cCategories; uint16 cExpanded; SSortOrder aSort[cSorts]; } SSortOrderSet; typedef [flag(NDR_NOALIGN)] struct { uint8 SortTableFlags; SSortOrderSet lpSortCriteria; } SortTable_req; typedef [flag(NDR_NOALIGN)] struct { TableStatus TableStatus; } SortTable_repl; /**************************/ /* EcDoRpc Function 0x14 */ typedef [flag(NDR_NOALIGN)] struct { uint16 cRes; mapi_SRestriction_and res[cRes]; } mapi_SAndRestriction; typedef [flag(NDR_NOALIGN)] struct { uint16 cRes; mapi_SRestriction_or res[cRes]; } mapi_SOrRestriction; typedef [flag(NDR_NOALIGN)] struct { mapi_SRestriction_wrap res; } mapi_SNotRestriction; typedef [noprint, bitmap32bit] bitmap { FL_FULLSTRING = 0x00000, FL_SUBSTRING = 0x00001, FL_PREFIX = 0x00002, FL_IGNORECASE = 0x10000, FL_IGNORENONSPACE = 0x20000, FL_LOOSE = 0x40000 } fuzzyLevel; typedef [flag(NDR_NOALIGN)] struct { fuzzyLevel fuzzy; MAPITAGS ulPropTag; mapi_SPropValue lpProp; } mapi_SContentRestriction; typedef [enum8bit, flag(NDR_PAHEX)] enum { BMR_EQZ = 0x0, BMR_NEZ = 0x1 } relMBR; typedef [flag(NDR_NOALIGN)] struct { relMBR relMBR; MAPITAGS ulPropTag; uint32 ulMask; } mapi_SBitmaskRestriction; typedef [enum8bit, flag(NDR_PAHEX)] enum { RELOP_LT = 0x0, /* < */ RELOP_LE = 0x1, /* <= */ RELOP_GT = 0x2, /* > */ RELOP_GE = 0x3, /* >= */ RELOP_EQ = 0x4, /* == */ RELOP_NE = 0x5, /* != */ RELOP_RE = 0x6 /* LIKE (Regular expression) */ } CompareRelop; typedef [flag(NDR_NOALIGN)] struct { CompareRelop relop; MAPITAGS ulPropTag; uint32 size; } mapi_SSizeRestriction; typedef [flag(NDR_NOALIGN)] struct { uint8 relop; MAPITAGS ulPropTag; mapi_SPropValue lpProp; } mapi_SPropertyRestriction; typedef [flag(NDR_NOALIGN)] struct { CompareRelop relop; MAPITAGS ulPropTag1; MAPITAGS ulPropTag2; } mapi_SCompareProps; typedef [flag(NDR_NOALIGN)] struct { MAPITAGS ulPropTag; } mapi_SExistRestriction; typedef [flag(NDR_NOALIGN)] struct { MAPITAGS ulSubObject; mapi_SRestriction_sub res[ulSubObject - ulSubObject + 1]; /* nasty hack - generates fake pointer */ } mapi_SSubRestriction; typedef [nopush,nopull,noprint,nodiscriminant] union { [case(0x0)]; [case(0x1)] mapi_SRestriction_comment *res; } RestrictionVariable; typedef [flag(NDR_NOALIGN)] struct { uint8 TaggedValuesCount; mapi_SPropValue TaggedValues[TaggedValuesCount]; boolean8 RestrictionPresent; [switch_is(RestrictionPresent)] RestrictionVariable Restriction; } mapi_SCommentRestriction; typedef [public,nodiscriminant] union { [case(RES_AND)] mapi_SAndRestriction resAnd; [case(RES_OR)] mapi_SOrRestriction resOr; [case(RES_NOT)] mapi_SNotRestriction resNot; [case(RES_CONTENT)] mapi_SContentRestriction resContent; [case(RES_PROPERTY)] mapi_SPropertyRestriction resProperty; [case(RES_COMPAREPROPS)] mapi_SCompareProps resCompareProps; [case(RES_BITMASK)] mapi_SBitmaskRestriction resBitmask; [case(RES_SIZE)] mapi_SSizeRestriction resSize; [case(RES_EXIST)] mapi_SExistRestriction resExist; [case(RES_SUBRESTRICTION)] mapi_SSubRestriction resSub; [case(RES_COMMENT)] mapi_SCommentRestriction resComment; [default]; } mapi_SRestriction_CTR; typedef [public,flag(NDR_NOALIGN)] struct { uint8 rt; [switch_is(rt)] mapi_SRestriction_CTR res; } mapi_SRestriction; typedef [public,flag(NDR_NOALIGN)] struct _mapi_SRestriction { uint8 rt; [switch_is(rt)] mapi_SRestriction_CTR res; } mapi_SRestriction_and; typedef [public,flag(NDR_NOALIGN)] struct _mapi_SRestriction { uint8 rt; [switch_is(rt)] mapi_SRestriction_CTR res; } mapi_SRestriction_or; typedef [public,flag(NDR_NOALIGN)] struct _mapi_SRestriction { uint8 rt; [switch_is(rt)] mapi_SRestriction_CTR res; } mapi_SRestriction_sub; typedef [public,flag(NDR_NOALIGN)] struct _mapi_SRestriction { uint8 rt; [switch_is(rt)] mapi_SRestriction_CTR res; } mapi_SRestriction_comment; typedef [flag(NDR_NOALIGN)] struct { uint8 handle_idx; [subcontext(2)] mapi_SRestriction restrictions; } Restrict_req; typedef [flag(NDR_NOALIGN)] struct { TableStatus TableStatus; } Restrict_repl; /**************************/ /* EcDoRpc Function 0x15 */ typedef [v1_enum] enum { TBL_LEAF_ROW = 0x1, TBL_EMPTY_CATEGORY = 0x2, TBL_EXPANDED_CATEGORY = 0x3, TBL_COLLAPSED_CATEGORY = 0x4 } RowType; typedef [enum8bit] enum { TBL_ADVANCE = 0x0, TBL_NOADVANCE = 0x1, TBL_ENABLEPACKEDBUFFERS = 0x2 } QueryRowsFlags; typedef [flag(NDR_NOALIGN)] struct { QueryRowsFlags QueryRowsFlags; uint8 ForwardRead; uint16 RowCount; } QueryRows_req; typedef [nopush,nopull,flag(NDR_NOALIGN)] struct { uint8 Origin; uint16 RowCount; [flag(NDR_REMAINING|NDR_NOALIGN)]DATA_BLOB RowData; } QueryRows_repl; /**************************/ /* EcDoRpc Function 0x16 */ typedef [flag(NDR_NOALIGN)] struct { } GetStatus_req; typedef [flag(NDR_NOALIGN)] struct { TableStatus TableStatus; } GetStatus_repl; /**************************/ /* EcDoRpc Function 0x17 */ typedef [flag(NDR_NOALIGN)] struct { } QueryPosition_req; typedef [flag(NDR_NOALIGN)] struct { uint32 Numerator; uint32 Denominator; } QueryPosition_repl; /**************************/ /* EcDoRpc Function 0x18 */ typedef [enum8bit] enum { BOOKMARK_BEGINNING = 0x0, BOOKMARK_CURRENT = 0x1, BOOKMARK_END = 0x2, BOOKMARK_USER = 0x3 } BOOKMARK; typedef [flag(NDR_NOALIGN)] struct { BOOKMARK origin; int32 offset; boolean8 WantRowMovedCount; } SeekRow_req; typedef [flag(NDR_NOALIGN)] struct { boolean8 HasSoughtLess; int32 RowsSought; } SeekRow_repl; /**************************/ /* EcDoRpc Function 0x19 */ typedef [flag(NDR_NOALIGN)] struct { SBinary_short Bookmark; uint32 RowCount; boolean8 WantRowMovedCount; } SeekRowBookmark_req; typedef [flag(NDR_NOALIGN)] struct { boolean8 RowNoLongerVisible; boolean8 HasSoughtLess; uint32 RowsSought; } SeekRowBookmark_repl; /**************************/ /* EcDoRpc Function 0x1a */ typedef [flag(NDR_NOALIGN)] struct { uint32 ulNumerator; uint32 ulDenominator; } SeekRowApprox_req; typedef [flag(NDR_NOALIGN)] struct { } SeekRowApprox_repl; /**************************/ /* EcDoRpc Function 0x1b */ typedef [flag(NDR_NOALIGN)] struct { } CreateBookmark_req; typedef [flag(NDR_NOALIGN)] struct { SBinary_short bookmark; } CreateBookmark_repl; /**************************/ /* EcDoRpc Function 0x1c */ typedef [enum8bit] enum { FOLDER_GENERIC = 0x1, FOLDER_SEARCH = 0x2 } FOLDER_TYPE; typedef [enum8bit] enum { MAPI_FOLDER_ANSI = 0x0, MAPI_FOLDER_UNICODE = 0x1 } FOLDER_STRING; typedef [nodiscriminant, flag(NDR_NOALIGN)] union { [case(MAPI_FOLDER_ANSI)] raw8string lpszA; [case(MAPI_FOLDER_UNICODE)][flag(STR_NULLTERM)] string lpszW; } LPTSTR; typedef [enum16bit] enum { NONE = 0x0000, OPEN_IF_EXISTS = 0x0001 } FOLDER_FLAGS; typedef [flag(NDR_NOALIGN)] struct { uint8 handle_idx; FOLDER_TYPE ulFolderType; FOLDER_STRING ulType; FOLDER_FLAGS ulFlags; [switch_is(ulType)] LPTSTR FolderName; [switch_is(ulType)] LPTSTR FolderComment; } CreateFolder_req; typedef [flag(NDR_NOALIGN)] struct { boolean8 HasRules; boolean8 IsGhosted; [switch_is(IsGhosted)] IsGhosted Ghost; } CreateFolder_GhostInfo; typedef [nodiscriminant, flag(NDR_NOALIGN)] union { [case(0x0)]; [case(0x1)] CreateFolder_GhostInfo GhostInfo; } CreateFolder_GhostUnion; typedef [flag(NDR_NOALIGN)] struct { hyper folder_id; boolean8 IsExistingFolder; [switch_is(IsExistingFolder)] CreateFolder_GhostUnion GhostUnion; } CreateFolder_repl; /**************************/ /* EcDoRpc Function 0x1d */ typedef [bitmap8bit] bitmap { DEL_MESSAGES = 0x1, DEL_FOLDERS = 0x4, DELETE_HARD_DELETE = 0x10 } DeleteFolderFlags; typedef [flag(NDR_NOALIGN)] struct { DeleteFolderFlags DeleteFolderFlags; hyper FolderId; } DeleteFolder_req; typedef [flag(NDR_NOALIGN)] struct { boolean8 PartialCompletion; } DeleteFolder_repl; /**************************/ /* EcDoRpc Function 0x1e */ typedef [flag(NDR_NOALIGN)] struct { boolean8 WantAsynchronous; boolean8 NotifyNonRead; uint16 cn_ids; hyper message_ids[cn_ids]; } DeleteMessages_req; typedef [flag(NDR_NOALIGN)] struct { boolean8 PartialCompletion; } DeleteMessages_repl; /**************************/ /* EcDoRpc Function 0x1f */ typedef [flag(NDR_NOALIGN)] struct { hyper msgid; } GetMessageStatus_req; /**************************/ /* EcDoRpc Function 0x20 */ typedef [bitmap32bit] bitmap { MSGSTATUS_HIGHLIGHTED = 0x1, MSGSTATUS_TAGGED = 0x2, MSGSTATUS_HIDDEN = 0x4, MSGSTATUS_DELMARKED = 0x8, MSGSTATUS_REMOTE_DOWNLOAD = 0x1000, MSGSTATUS_REMOTE_DELETE = 0x2000 } ulMessageStatus; typedef [flag(NDR_NOALIGN)] struct { hyper msgid; uint32 ulNewStatus; ulMessageStatus ulNewStatusMask; } SetMessageStatus_req; typedef [flag(NDR_NOALIGN)] struct { ulMessageStatus ulOldStatus; } SetMessageStatus_repl; /**************************/ /* EcDoRpc Function 0x21 */ typedef [flag(NDR_NOALIGN)] struct { uint8 handle_idx; TableFlags TableFlags; } GetAttachmentTable_req; typedef [flag(NDR_NOALIGN)] struct { } GetAttachmentTable_repl; /*************************/ /* EcDoRpc Function 0x22 */ typedef [enum8bit] enum { OpenAttachmentFlags_ReadOnly = 0x0, OpenAttachmentFlags_ReadWrite = 0x1, OpenAttachmentFlags_BestAccess = 0x3 } OpenAttachmentFlags; typedef [flag(NDR_NOALIGN)] struct { uint8 handle_idx; OpenAttachmentFlags OpenAttachmentFlags; uint32 AttachmentID; } OpenAttach_req; typedef [flag(NDR_NOALIGN)] struct { } OpenAttach_repl; /*************************/ /* EcDoRpc Function 0x23 */ typedef [flag(NDR_NOALIGN)] struct { uint8 handle_idx; } CreateAttach_req; typedef [flag(NDR_NOALIGN)] struct { uint32 AttachmentID; } CreateAttach_repl; /*************************/ /* EcDoRpc Function 0x24 */ typedef [flag(NDR_NOALIGN)] struct { uint32 AttachmentID; } DeleteAttach_req; typedef [flag(NDR_NOALIGN)] struct { } DeleteAttach_repl; /*************************/ /* EcDoRpc Function 0x25 */ typedef [flag(NDR_NOALIGN)] struct { uint8 handle_idx; SaveFlags SaveFlags; } SaveChangesAttachment_req; typedef [flag(NDR_NOALIGN)] struct { } SaveChangesAttachment_repl; /*************************/ /* EcDoRpc Function 0x26 */ typedef [flag(NDR_NOALIGN)] struct { hyper fid; raw8string lpszMessageClass; } SetReceiveFolder_req; typedef [flag(NDR_NOALIGN)] struct { } SetReceiveFolder_repl; /*************************/ /* EcDoRpc Function 0x27 */ typedef [flag(NDR_NOALIGN)] struct { astring MessageClass; } GetReceiveFolder_req; typedef [flag(NDR_NOALIGN)] struct { hyper folder_id; astring MessageClass; } GetReceiveFolder_repl; /*************************/ /* EcDoRpc Function 0x29 */ typedef [bitmap16bit] bitmap { fnevCriticalError = 0x0001, fnevNewMail = 0x0002, fnevObjectCreated = 0x0004, fnevObjectDeleted = 0x0008, fnevObjectModified = 0x0010, fnevObjectMoved = 0x0020, fnevObjectCopied = 0x0040, fnevSearchComplete = 0x0080, fnevTableModified = 0x0100, fnevStatusObjectModified = 0x0200, fnevReserved = 0x0400, fnevTbit = 0x1000, fnevUbit = 0x2000, fnevSbit = 0x4000, fnevMbit = 0x8000 } NotificationFlags; typedef [nodiscriminant,flag(NDR_NOALIGN)] union { [case(0x0)] hyper ID; [case(0x1)]; } hyperbool; typedef [flag(NDR_NOALIGN)] struct { uint8 handle_idx; NotificationFlags NotificationFlags; boolean8 WantWholeStore; [switch_is(WantWholeStore)] hyperbool FolderId; [switch_is(WantWholeStore)] hyperbool MessageId; } RegisterNotification_req; typedef [flag(NDR_NOALIGN)] struct { } RegisterNotification_repl; /*************************/ /* EcDoRpc Function 0x2a */ typedef [bitmap32bit] bitmap { MSGFLAG_READ = 0x1, MSGFLAG_UNMODIFIED = 0x2, MSGFLAG_SUBMIT = 0x4, MSGFLAG_UNSENT = 0x8, MSGFLAG_HASATTACH = 0x10, MSGFLAG_FROMME = 0x20, MSGFLAG_ASSOCIATED = 0x40, MSGFLAG_RESEND = 0x80, MSGFLAG_RN_PENDING = 0x100, MSGFLAG_NRN_PENDING = 0x200 } MsgFlags; typedef [nodiscriminant, flag(NDR_NOALIGN)] union { [case(0x0)] raw8string lpszA; [case(0x1)][flag(STR_NULLTERM)] string lpszW; } MessageClass; typedef [public,nodiscriminant, flag(NDR_NOALIGN)] union { [case(0x1)] uint8 bytes[6]; [default] dlong value; } GLOBCNT; typedef [public,flag(NDR_NOALIGN)] struct { GUID GUID; [switch_is(1)] GLOBCNT GLOBCNT; } GID; typedef [public,flag(NDR_NOALIGN)] struct { uint16 ReplID; [switch_is(1)] GLOBCNT GLOBCNT; } ShortTermID; /* MID, FID, CN */ typedef [public,flag(NDR_NOALIGN)] struct { GUID GUID; uint8 Size; uint8 Data[Size]; } XID; typedef [enum16bit] enum { TABLE_CHANGED = 0x1, TABLE_ROW_ADDED = 0x3, TABLE_ROW_DELETED = 0x4, TABLE_ROW_MODIFIED = 0x5, TABLE_RESTRICT_DONE = 0x7 } RichTableNotificationType; typedef [nodiscriminant, flag(NDR_NOALIGN)] union { [case(0x0)]; [case(0xffff)]; [default] MAPITAGS Tags[level]; } NotificationTags; /* NewMailNotification: case 0x2 and 0x8002 */ typedef [flag(NDR_NOALIGN)] struct { hyper FID; hyper MID; MsgFlags MessageFlags; boolean8 UnicodeFlag; [switch_is(UnicodeFlag)] MessageClass MessageClass; } NewMailNotification; /* FolderCreatedNotification: case 0x4 */ typedef [flag(NDR_NOALIGN)] struct { hyper FID; hyper ParentFID; uint16 TagCount; [switch_is(TagCount)] NotificationTags NotificationTags; } FolderCreatedNotification; /* FolderDeletedNotification: case 0x8 */ typedef [flag(NDR_NOALIGN)] struct { hyper FID; hyper ParentFID; } FolderDeletedNotification; /* FolderModifiedNotification: case 0x10 */ typedef [flag(NDR_NOALIGN)] struct { hyper FID; uint16 TagCount; [switch_is(TagCount)] NotificationTags NotificationTags; } FolderModifiedNotification_10; /* FolderMoveCopyNotification: case 0x20 and 0x40 */ typedef [flag(NDR_NOALIGN)] struct { hyper FID; hyper ParentFID; hyper OldFID; hyper OldParentFID; } FolderMoveCopyNotification; /* SearchCompleteNotification: case 0x80 */ typedef [flag(NDR_NOALIGN)] struct { hyper FID; } SearchCompleteNotification; /* HierarchyTable: case 0x100 */ typedef [flag(NDR_NOALIGN)] struct { hyper FID; hyper InsertAfterFID; [subcontext(2)] DATA_BLOB Columns; } HierarchyRowAddedNotification; typedef [flag(NDR_NOALIGN)] struct { hyper FID; } HierarchyRowDeletedNotification; typedef [flag(NDR_NOALIGN)] struct { hyper FID; hyper InsertAfterFID; [subcontext(2)] DATA_BLOB Columns; } HierarchyRowModifiedNotification; typedef [nodiscriminant] union { [case(TABLE_ROW_ADDED)] HierarchyRowAddedNotification HierarchyRowAddedNotification; [case(TABLE_ROW_DELETED)] HierarchyRowDeletedNotification HierarchyRowDeletedNotification; [case(TABLE_ROW_MODIFIED)] HierarchyRowModifiedNotification HierarchyRowModifiedNotification; [default]; } HierarchyTableChangeUnion; typedef [flag(NDR_NOALIGN)] struct { RichTableNotificationType TableEvent; [switch_is(TableEvent)] HierarchyTableChangeUnion HierarchyTableChangeUnion; } HierarchyTableChange; /* IcsNotification: case 0x200 */ typedef [flag(NDR_NOALIGN)] struct { boolean8 HierChanged; uint32 GIDCount; GID GID[GIDCount]; } IcsNotification; /* FolderModifiedNotification: case 0x1010 */ typedef [flag(NDR_NOALIGN)] struct { hyper FID; uint16 TagCount; [switch_is(TagCount)] NotificationTags NotificationTags; uint32 TotalMessageCount; } FolderModifiedNotification_1010; /* FolderModifiedNotification: case 0x2010 */ typedef [flag(NDR_NOALIGN)] struct { hyper FID; uint16 TagCount; [switch_is(TagCount)] NotificationTags NotificationTags; uint32 UnreadMessageCount; } FolderModifiedNotification_2010; /* FolderModifiedNotification: case 0x3010 */ typedef [flag(NDR_NOALIGN)] struct { hyper FID; uint16 TagCount; [switch_is(TagCount)] NotificationTags NotificationTags; uint32 TotalMessageCount; uint32 UnreadMessageCount; } FolderModifiedNotification_3010; /* MessageCreatedNotification: case 0x8004 */ typedef [flag(NDR_NOALIGN)] struct { hyper FID; hyper MID; uint16 TagCount; [switch_is(TagCount)] NotificationTags NotificationTags; } MessageCreatedNotification; /* MessageDeletedNotification: case 0x8008 */ typedef [flag(NDR_NOALIGN)] struct { hyper FID; hyper MID; } MessageDeletedNotification; /* MessageModifiedNotification: case 0x8010 */ typedef [flag(NDR_NOALIGN)] struct { hyper FID; hyper MID; uint16 TagCount; [switch_is(TagCount)] NotificationTags NotificationTags; } MessageModifiedNotification; /* MessageMoveCopyNotification: case 0x8020 and 0x8040 */ typedef [flag(NDR_NOALIGN)] struct { hyper FID; hyper MID; hyper OldFID; hyper OldMID; } MessageMoveCopyNotification; /* ContentsTableChange: case 0x8100 and 0xc100 */ typedef [flag(NDR_NOALIGN)] struct { hyper FID; hyper MID; uint32 Instance; hyper InsertAfterFID; hyper InsertAfterMID; uint32 InsertAfterInstance; [subcontext(2)] DATA_BLOB Columns; } ContentsRowAddedNotification; typedef [flag(NDR_NOALIGN)] struct { hyper FID; hyper MID; uint32 Instance; } ContentsRowDeletedNotification; typedef [flag(NDR_NOALIGN)] struct { hyper FID; hyper MID; uint32 Instance; hyper InsertAfterFID; hyper InsertAfterMID; uint32 InsertAfterInstance; [subcontext(2)] DATA_BLOB Columns; } ContentsRowModifiedNotification; typedef [nodiscriminant] union { [case(TABLE_ROW_ADDED)] ContentsRowAddedNotification ContentsRowAddedNotification; [case(TABLE_ROW_DELETED)] ContentsRowDeletedNotification ContentsRowDeletedNotification; [case(TABLE_ROW_MODIFIED)] ContentsRowModifiedNotification ContentsRowModifiedNotification; [default]; } ContentsTableChangeUnion; typedef [flag(NDR_NOALIGN)] struct { RichTableNotificationType TableEvent; [switch_is(TableEvent)] ContentsTableChangeUnion ContentsTableChangeUnion; } ContentsTableChange; /* SearchMessageCreatedNotification: case 0xc004 */ typedef [flag(NDR_NOALIGN)] struct { hyper FID; hyper MID; hyper SearchFID; uint16 TagCount; [switch_is(TagCount)] NotificationTags NotificationTags; } SearchMessageCreatedNotification; /* SearchMessageRemovedNotification: case 0xc008 */ typedef [flag(NDR_NOALIGN)] struct { hyper FID; hyper MID; hyper SearchFID; } SearchMessageRemovedNotification; /* SearchMessageModifiedNotification: 0xc010 */ typedef [flag(NDR_NOALIGN)] struct { hyper FID; hyper MID; uint16 TagCount; [switch_is(TagCount)] NotificationTags NotificationTags; } SearchMessageModifiedNotification; typedef [nodiscriminant] union { [case(0x0002)] NewMailNotification NewMailNotification; [case(0x0004)] FolderCreatedNotification FolderCreatedNotification; [case(0x0008)] FolderDeletedNotification FolderDeletedNotification; [case(0x0010)] FolderModifiedNotification_10 FolderModifiedNotification_10; [case(0x0020)] FolderMoveCopyNotification FolderMoveNotification; [case(0x0040)] FolderMoveCopyNotification FolderCopyNotification; [case(0x0080)] SearchCompleteNotification SearchCompleteNotification; [case(0x0100)] HierarchyTableChange HierarchyTableChange; [case(0x0200)] IcsNotification IcsNotification; [case(0x1010)] FolderModifiedNotification_1010 FolderModifiedNotification_1010; [case(0x2010)] FolderModifiedNotification_2010 FolderModifiedNotification_2010; [case(0x3010)] FolderModifiedNotification_3010 FolderModifiedNotification_3010; [case(0x8002)] NewMailNotification NewMessageNotification; [case(0x8004)] MessageCreatedNotification MessageCreatedNotification; [case(0x8008)] MessageDeletedNotification MessageDeletedNotification; [case(0x8010)] MessageModifiedNotification MessageModifiedNotification; [case(0x8020)] MessageMoveCopyNotification MessageMoveNotification; [case(0x8040)] MessageMoveCopyNotification MessageCopyNotification; [case(0x8100)] ContentsTableChange ContentsTableChange; [case(0xc004)] SearchMessageCreatedNotification SearchMessageCreatedNotification; [case(0xc008)] SearchMessageRemovedNotification SearchMessageRemovedNotification; [case(0xc010)] SearchMessageModifiedNotification SearchMessageModifiedNotification; [case(0xc100)] ContentsTableChange SearchTableChange; } NotificationData; typedef [flag(NDR_NOALIGN)] struct { uint32 NotificationHandle; uint8 LogonId; NotificationFlags NotificationType; [switch_is(NotificationType)] NotificationData NotificationData; } Notify_repl; /*************************/ /* EcDoRpc Function 0x2b */ typedef [enum8bit] enum { OpenStream_ReadOnly = 0x0, OpenStream_ReadWrite = 0x1, OpenStream_Create = 0x2, OpenStream_BestAccess = 0x3 } OpenStream_OpenModeFlags; typedef [flag(NDR_NOALIGN)] struct { uint8 handle_idx; MAPITAGS PropertyTag; OpenStream_OpenModeFlags OpenModeFlags; } OpenStream_req; typedef [flag(NDR_NOALIGN)] struct { uint32 StreamSize; } OpenStream_repl; /*************************/ /* EcDoRpc Function 0x2c */ typedef [nodiscriminant, flag(NDR_NOALIGN)] union { [case(0xBABE)] uint32 value; [default]; } MaximumByteCount; typedef [flag(NDR_NOALIGN)] struct { uint16 ByteCount; [switch_is(ByteCount)] MaximumByteCount MaximumByteCount; } ReadStream_req; typedef [flag(NDR_NOALIGN)] struct { [subcontext(2), flag(NDR_REMAINING|NDR_NOALIGN)] DATA_BLOB data; } ReadStream_repl; /*************************/ /* EcDoRpc Function 0x2d */ typedef [flag(NDR_NOALIGN)] struct { [subcontext(2), flag(NDR_REMAINING|NDR_NOALIGN)] DATA_BLOB data; } WriteStream_req; typedef [flag(NDR_NOALIGN)] struct { uint16 WrittenSize; } WriteStream_repl; /*************************/ /* EcDoRpc Function 0x2e */ typedef [flag(NDR_NOALIGN)] struct { uint8 Origin; hyper Offset; } SeekStream_req; typedef [flag(NDR_NOALIGN)] struct { hyper NewPosition; } SeekStream_repl; /*************************/ /* EcDoRpc Function 0x2f */ typedef [flag(NDR_NOALIGN)] struct { hyper SizeStream; } SetStreamSize_req; typedef [flag(NDR_NOALIGN)] struct { } SetStreamSize_repl; /*************************/ /* EcDoRpc Function 0x30 */ typedef [public, bitmap32bit, flag(NDR_PAHEX)] bitmap { STOP_SEARCH = 0x00000001, RESTART_SEARCH = 0x00000002, RECURSIVE_SEARCH = 0x00000004, SHALLOW_SEARCH = 0x00000008, FOREGROUND_SEARCH = 0x00000010, BACKGROUND_SEARCH = 0x00000020, CONTENT_INDEXED_SEARCH = 0x00010000, NON_CONTENT_INDEXED_SEARCH = 0x00020000, STATIC_SEARCH = 0x00040000 } SearchFlags; typedef [flag(NDR_NOALIGN)] struct { [subcontext(2)] mapi_SRestriction res; uint16 FolderIdCount; hyper FolderIds[FolderIdCount]; SearchFlags SearchFlags; } SetSearchCriteria_req; typedef [flag(NDR_NOALIGN)] struct { } SetSearchCriteria_repl; /*************************/ /* EcDoRpc Function 0x31 */ typedef [flag(NDR_NOALIGN)] struct { boolean8 UseUnicode; boolean8 IncludeRestriction; boolean8 IncludeFolders; } GetSearchCriteria_req; typedef [nopush,nopull,noprint,flag(NDR_NOALIGN)] struct { uint16 RestrictionDataSize; [subcontext(0),subcontext_size(RestrictionDataSize)] mapi_SRestriction RestrictionData; uint8 LogonId; uint16 FolderIdCount; hyper FolderIds[FolderIdCount]; SearchFlags SearchFlags; } GetSearchCriteria_repl; /*************************/ /* EcDoRpc Function 0x32 */ typedef [enum8bit] enum { None = 0x0, /* None */ PreProcess = 0x1, /* Needs to be preprocessed by the server */ NeedsSpooler = 0x2 /* Is to be processed by a client spooler */ } SubmitFlags; typedef [flag(NDR_NOALIGN)] struct { SubmitFlags SubmitFlags; } SubmitMessage_req; typedef [flag(NDR_NOALIGN)] struct { } SubmitMessage_repl; /*************************/ /* EcDoRpc Function 0x33 */ typedef [flag(NDR_NOALIGN)] struct { uint8 handle_idx; uint16 count; hyper message_id[count]; boolean8 WantAsynchronous; boolean8 WantCopy; } MoveCopyMessages_req; typedef [flag(NDR_NOALIGN)] struct { boolean8 PartialCompletion; } MoveCopyMessages_repl; /*************************/ /* EcDoRpc Function 0x34 */ typedef [flag(NDR_NOALIGN)] struct { hyper FolderId; hyper MessageId; } AbortSubmit_req; typedef [flag(NDR_NOALIGN)] struct { } AbortSubmit_repl; /*************************/ /* EcDoRpc Function 0x35 */ typedef [nodiscriminant, flag(NDR_NOALIGN)] union { [case(0x0)] raw8string lpszA; [case(0x1)][flag(STR_NULLTERM)] string lpszW; } Folder_name; typedef [flag(NDR_NOALIGN)] struct { uint8 handle_idx; boolean8 WantAsynchronous; boolean8 UseUnicode; hyper FolderId; [switch_is(UseUnicode)] Folder_name NewFolderName; } MoveFolder_req; typedef [nopull,nopush,noprint,flag(NDR_NOALIGN)] struct { boolean8 HasDestHandleIndex; uint32 DestHandleIndex; boolean8 PartialCompletion; } MoveFolder_repl; /*************************/ /* EcDoRpc Function 0x36 */ typedef [flag(NDR_NOALIGN)] struct { uint8 handle_idx; boolean8 WantAsynchronous; boolean8 WantRecursive; boolean8 UseUnicode; hyper FolderId; [switch_is(UseUnicode)] Folder_name NewFolderName; } CopyFolder_req; typedef [nopull,nopush,noprint,flag(NDR_NOALIGN)] struct { boolean8 HasDestHandleIndex; uint32 DestHandleIndex; boolean8 PartialCompletion; } CopyFolder_repl; /*************************/ /* EcDoRpc Function 0x37 */ typedef [flag(NDR_NOALIGN)] struct { } QueryColumnsAll_req; typedef [flag(NDR_NOALIGN)] struct { uint16 PropertyTagCount; MAPITAGS PropertyTags[PropertyTagCount]; } QueryColumnsAll_repl; /*************************/ /* EcDoRpc Function 0x38 */ typedef [flag(NDR_NOALIGN)] struct { } Abort_req; typedef [flag(NDR_NOALIGN)] struct { TableStatus TableStatus; } Abort_repl; /*************************/ /* EcDoRpc Function 0x39 */ typedef [bitmap8bit] bitmap { CopyFlagsMove = 0x1, /* Move properties */ CopyFlagsNoOverwrite = 0x2 /* Do not overwrite existing properties */ } CopyFlags; typedef [flag(NDR_NOALIGN)] struct { uint8 handle_idx; boolean8 WantAsynchronous; boolean8 WantSubObjects; CopyFlags CopyFlags; mapi_SPropTagArray ExcludedTags; } CopyTo_req; typedef [flag(NDR_NOALIGN)] struct { uint16 PropertyProblemCount; PropertyProblem PropertyProblem[PropertyProblemCount]; } CopyTo_repl; /*************************/ /* EcDoRpc Function 0x3a */ typedef [flag(NDR_NOALIGN)] struct { uint8 handle_idx; hyper ByteCount; } CopyToStream_req; typedef [flag(NDR_NOALIGN)] struct { hyper ReadByteCount; hyper WrittenByteCount; } CopyToStream_repl; /*************************/ /* EcDoRpc Function 0x3b */ typedef [flag(NDR_NOALIGN)] struct { uint8 handle_idx; } CloneStream_req; typedef [flag(NDR_NOALIGN)] struct { } CloneStream_repl; /*************************/ /* EcDoRpc Function 0x3e */ typedef [bitmap8bit] bitmap { IncludeFreeBusy = 0x02 } PermissionsTableFlags; typedef [flag(NDR_NOALIGN)] struct { uint8 handle_idx; PermissionsTableFlags TableFlags; } GetPermissionsTable_req; typedef [flag(NDR_NOALIGN)] struct { } GetPermissionsTable_repl; /*************************/ /* EcDoRpc Function 0x3f */ typedef [bitmap8bit] bitmap { RulesTableFlags_Unicode = 0x40 } RulesTableFlags; typedef [flag(NDR_NOALIGN)] struct { uint8 handle_idx; RulesTableFlags TableFlags; } GetRulesTable_req; typedef [flag(NDR_NOALIGN)] struct { } GetRulesTable_repl; /*************************/ /* EcDoRpc Function 0x40 */ typedef [bitmap8bit] bitmap { ModifyPerms_IncludeFreeBusy = 0x02, ModifyPerms_ReplaceRows = 0x01 } ModifyPermissionsFlags; typedef [flag(NDR_NOALIGN)] struct { ulRowFlags PermissionDataFlags; mapi_SPropValue_array lpProps; } PermissionData; typedef [flag(NDR_NOALIGN)] struct { ModifyPermissionsFlags ModifyFlags; uint16 ModifyCount; PermissionData PermissionsData[ModifyCount]; } mapi_PermissionsData; typedef [flag(NDR_NOALIGN)] struct { mapi_PermissionsData rowList; } ModifyPermissions_req; typedef [flag(NDR_NOALIGN)] struct { } ModifyPermissions_repl; /*************************/ /* EcDoRpc Function 0x41 */ typedef [flag(NDR_NOALIGN)] struct { ulRowFlags RuleDataFlags; mapi_SPropValue_array PropertyValues; } RuleData; typedef [bitmap8bit] bitmap { ModifyRulesFlag_Replace = 0x01 } ModifyRulesFlag; typedef [flag(NDR_NOALIGN)] struct { ModifyRulesFlag ModifyRulesFlags; uint16 RulesCount; RuleData RulesData[RulesCount]; } ModifyRules_req; typedef [flag(NDR_NOALIGN)] struct { } ModifyRules_repl; /*************************/ /* EcDoRpc Function 0x42 */ typedef [flag(NDR_NOALIGN)] struct { hyper FolderId; } GetOwningServers_req; typedef [flag(NDR_NOALIGN)] struct { uint16 OwningServersCount; uint16 CheapServersCount; astring OwningServers[OwningServersCount]; } GetOwningServers_repl; /*************************/ /* EcDoRpc Function 0x43 */ typedef [flag(NDR_NOALIGN)] struct { hyper Id; } LongTermIdFromId_req; typedef [flag(NDR_NOALIGN)] struct { GUID DatabaseGuid; uint8 GlobalCounter[6]; uint16 padding; } LongTermId; typedef [flag(NDR_NOALIGN)] struct { LongTermId LongTermId; } LongTermIdFromId_repl; /*************************/ /* EcDoRpc Function 0x44 */ typedef [flag(NDR_NOALIGN)] struct { LongTermId LongTermId; } IdFromLongTermId_req; typedef [flag(NDR_NOALIGN)] struct { hyper Id; } IdFromLongTermId_repl; /*************************/ /* EcDoRpc Function 0x45 */ typedef [flag(NDR_NOALIGN)] struct { hyper FolderId; } PublicFolderIsGhosted_req; typedef [flag(NDR_NOALIGN)] struct { boolean8 IsGhosted; [switch_is(IsGhosted)] IsGhosted Ghost; } PublicFolderIsGhosted_repl; /*************************/ /* EcDoRpc Function 0x46 */ typedef [enum8bit, flag(NDR_PAHEX)] enum { MAPI_READONLY = 0x0, MAPI_READWRITE = 0x1, MAPI_CREATE = 0x2 } OpenEmbeddedMessage_OpenModeFlags; typedef [flag(NDR_NOALIGN)] struct { uint8 handle_idx; uint16 CodePageId; OpenEmbeddedMessage_OpenModeFlags OpenModeFlags; } OpenEmbeddedMessage_req; typedef [flag(NDR_NOALIGN)] struct { uint8 Reserved; hyper MessageId; boolean8 HasNamedProperties; TypedString SubjectPrefix; TypedString NormalizedSubject; uint16 RecipientCount; mapi_SPropTagArray RecipientColumns; uint8 RowCount; OpenRecipientRow RecipientRows[RowCount]; } OpenEmbeddedMessage_repl; /*************************/ /* EcDoRpc Function 0x47 */ typedef [flag(NDR_NOALIGN)] struct { } SetSpooler_req; typedef [flag(NDR_NOALIGN)] struct { } SetSpooler_repl; /*************************/ /* EcDoRpc Function 0x48 */ typedef [enum8bit] enum { LockState_1stLock = 0x0, LockState_1stUnlock = 0x1, LockState_1stFinished = 0x2 } LockState; typedef [flag(NDR_NOALIGN)] struct { hyper MessageId; LockState LockState; } SpoolerLockMessage_req; typedef [flag(NDR_NOALIGN)] struct { } SpoolerLockMessage_repl; /*************************/ /* EcDoRpc Function 0x49 */ typedef [flag(NDR_NOALIGN)] struct { } AddressTypes_req; typedef [flag(NDR_NOALIGN)] struct { uint16 cValues; uint16 size; mapi_LPSTR transport[cValues]; } AddressTypes_repl; /**************************/ /* EcDoRpc Function 0x4a */ typedef [flag(NDR_NOALIGN)] struct { } TransportSend_req; typedef [nodiscriminant] union { [case(0x0)] mapi_SPropValue_array lpProps; [case(0x1)]; } TransportSend_lpProps; typedef [flag(NDR_NOALIGN)] struct { boolean8 NoPropertiesReturned; [switch_is(NoPropertiesReturned)] TransportSend_lpProps properties; } TransportSend_repl; /**************************/ /* EcDoRpc Function 0x4b */ typedef [bitmap8bit] bitmap { FastTransferCopyMessage_Move = 0x01, FastTransferCopyMessage_Unknown1 = 0x02, FastTransferCopyMessage_Unknown2 = 0x04, FastTransferCopyMessage_Unknown3 = 0x08, FastTransferCopyMessage_BestBody = 0x10, FastTransferCopyMessage_SendEntryId = 0x20 } FastCopyMessagesCopyFlags; /* this one is used in a few ROPs */ typedef [bitmap8bit] bitmap { FastTransfer_Unicode = 0x01, FastTransfer_UseCpid = 0x02, FastTransfer_ForUpload = FastTransfer_Unicode | FastTransfer_UseCpid, FastTransfer_RecoverMode = 0x04, FastTransfer_ForceUnicode = 0x08, FastTransfer_PartialItem = 0x10 } FastCopySendOptions; typedef [flag(NDR_NOALIGN)] struct { uint8 handle_idx; uint16 MessageIdCount; hyper MessageIds[MessageIdCount]; FastCopyMessagesCopyFlags CopyFlags; FastCopySendOptions SendOptions; } FastTransferSourceCopyMessages_req; typedef [flag(NDR_NOALIGN)] struct { } FastTransferSourceCopyMessages_repl; /**************************/ /* EcDoRpc Function 0x4c */ typedef [bitmap8bit] bitmap { FastTransferCopyFolder_Move = 0x01, FastTransferCopyFolder_Unused1 = 0x02, FastTransferCopyFolder_Unused2 = 0x04, FastTransferCopyFolder_Unused3 = 0x08, FastTransferCopyFolder_CopySubfolders = 0x10, FastTransferCopyFolder_NoGhostedContent = 0x20 } FastCopyFolderCopyFlags; typedef [flag(NDR_NOALIGN)] struct { uint8 handle_idx; FastCopyFolderCopyFlags CopyFlags; FastCopySendOptions SendOptions; } FastTransferSourceCopyFolder_req; typedef [flag(NDR_NOALIGN)] struct { } FastTransferSourceCopyFolder_repl; /**************************/ /* EcDoRpc Function 0x4d */ typedef [bitmap32bit] bitmap { FastTransferCopyTo_Move = 0x00000001, FastTransferCopyToUnused1 = 0x00000002, FastTransferCopyToUnused2 = 0x00000004, FastTransferCopyToUnused3 = 0x00000008, FastTransferCopyToUnused4 = 0x00000200, FastTransferCopyToUnused5 = 0x00000400, FastTransferCopyTo_BestBody = 0x00002000 } FastCopyToCopyFlags; typedef [flag(NDR_NOALIGN)] struct { uint8 handle_idx; uint8 Level; FastCopyToCopyFlags CopyFlags; FastCopySendOptions SendOptions; mapi_SPropTagArray PropertyTags; } FastTransferSourceCopyTo_req; typedef [flag(NDR_NOALIGN)] struct { } FastTransferSourceCopyTo_repl; /**************************/ /* EcDoRpc Function 0x4e */ typedef [nodiscriminant] union { [case(0xBABE)] uint16 MaximumBufferSize; [default]; } FastTransferSourceGetBuffer_MaxBufferSize; typedef [flag(NDR_NOALIGN)] struct { uint16 BufferSize; [switch_is(BufferSize)] FastTransferSourceGetBuffer_MaxBufferSize MaximumBufferSize; } FastTransferSourceGetBuffer_req; typedef [enum16bit] enum { TransferStatus_Error = 0x0000, TransferStatus_Partial = 0x0001, TransferStatus_NoRoom = 0x0002, TransferStatus_Done = 0x0003 } TransferStatus; typedef [flag(NDR_NOALIGN)] struct { TransferStatus TransferStatus; uint16 InProgressCount; uint16 TotalStepCount; uint8 Reserved; uint16 TransferBufferSize; [subcontext(0),subcontext_size(TransferBufferSize),flag(NDR_REMAINING|NDR_NOALIGN)] DATA_BLOB TransferBuffer; } FastTransferSourceGetBuffer_repl; /**************************/ /* EcDoRpc Function 0x4f */ typedef [enum8bit] enum { DIR_FORWARD = 0x0, DIR_BACKWARD = 0x1 } FindRow_ulFlags; typedef [flag(NDR_NOALIGN)] struct { FindRow_ulFlags ulFlags; [subcontext(2)] mapi_SRestriction res; BOOKMARK origin; SBinary_short bookmark; } FindRow_req; typedef [flag(NDR_NOALIGN)] struct { uint8 RowNoLongerVisible; uint8 HasRowData; [flag(NDR_REMAINING|NDR_NOALIGN)] DATA_BLOB row; } FindRow_repl; /**************************/ /* EcDoRpc Function 0x50 */ typedef [flag(NDR_NOALIGN)] struct { boolean8 WantCancel; } Progress_req; typedef [flag(NDR_NOALIGN)] struct { uint32 CompletedTaskCount; uint32 TotalTaskCount; } Progress_repl; /**************************/ /* EcDoRpc Function 0x51 */ typedef [flag(NDR_NOALIGN)] struct { hyper MessageId; hyper FolderId; astring MessageClass; uint32 MessageFlags; } TransportNewMail_req; typedef [flag(NDR_NOALIGN)] struct { } TransportNewMail_repl; /**************************/ /* EcDoRpc Function 0x52 */ typedef [flag(NDR_NOALIGN)] struct { } GetValidAttachments_req; typedef [flag(NDR_NOALIGN)] struct { uint16 AttachmentIdCount; uint32 AttachmentIdArray[AttachmentIdCount]; } GetValidAttachments_repl; /**************************/ /* EcDoRpc Function 0x53 */ typedef [enum8bit] enum { FastTransferDest_CopyTo = 0x1, FastTransferDest_CopyProperties = 0x2, FastTransferDest_CopyMessages = 0x3, FastTransferDest_CopyFolder = 0x4 } FastTransferDestConfig_SourceOperation; typedef [bitmap8bit] bitmap { FastTransferDest_Move = 0x01 } FastTransferDestConfig_CopyFlags; typedef [flag(NDR_NOALIGN)] struct { uint8 handle_idx; FastTransferDestConfig_SourceOperation SourceOperation; FastTransferDestConfig_CopyFlags CopyFlags; } FastTransferDestinationConfigure_req; typedef [flag(NDR_NOALIGN)] struct { } FastTransferDestinationConfigure_repl; /**************************/ /* EcDoRpc Function 0x54 */ typedef [flag(NDR_NOALIGN)] struct { uint16 TransferBufferSize; [subcontext(0),subcontext_size(TransferBufferSize),flag(NDR_REMAINING|NDR_NOALIGN)] DATA_BLOB TransferBuffer; } FastTransferDestinationPutBuffer_req; typedef [flag(NDR_NOALIGN)] struct { TransferStatus TransferStatus; uint16 InProgressCount; uint16 TotalStepCount; uint8 Reserved; uint16 BufferUsedCount; } FastTransferDestinationPutBuffer_repl; /*************************/ /* EcDoRpc Function 0x55 */ typedef [enum8bit] enum { MNID_ID = 0, MNID_STRING = 1 } ulKind; typedef [flag(NDR_NOALIGN)] struct { uint8 NameSize; [flag(STR_NULLTERM)] string Name; } mapi_name; typedef [nodiscriminant] union { [case(MNID_ID)] uint32 lid; [case(MNID_STRING)] mapi_name lpwstr; } Kind; typedef [flag(NDR_NOALIGN)] struct { ulKind ulKind; GUID lpguid; [switch_is(ulKind)] Kind kind; } MAPINAMEID; typedef [flag(NDR_NOALIGN)] struct { uint16 PropertyIdCount; uint16 PropertyIds[PropertyIdCount]; } GetNamesFromIDs_req; typedef [flag(NDR_NOALIGN)] struct { uint16 count; MAPINAMEID nameid[count]; } GetNamesFromIDs_repl; /*************************/ /* EcDoRpc Function 0x56 */ typedef [enum8bit, flag(NDR_PAHEX)] enum { GetIDsFromNames_GetOnly = 0x00, GetIDsFromNames_GetOrCreate = 0x02 } GetIDsFromNamesFlags; typedef [flag(NDR_NOALIGN)] struct { GetIDsFromNamesFlags ulFlags; uint16 count; MAPINAMEID nameid[count]; } GetIDsFromNames_req; typedef [flag(NDR_NOALIGN)] struct { uint16 count; uint16 propID[count]; } GetIDsFromNames_repl; /*************************/ /* EcDoRpc Function 0x57 */ typedef [flag(NDR_NOALIGN)] struct { SBinary_short ServerEntryId; SBinary_short ClientEntryId; } UpdateDeferredActionMessages_req; typedef [flag(NDR_NOALIGN)] struct { } UpdateDeferredActionMessages_repl; /*************************/ /* EcDoRpc Function 0x58 */ typedef [flag(NDR_NOALIGN)] struct { boolean8 WantAsynchronous; boolean8 WantDeleteAssociated; } EmptyFolder_req; typedef [flag(NDR_NOALIGN)] struct { boolean8 PartialCompletion; } EmptyFolder_repl; /*************************/ /* EcDoRpc Function 0x59 */ typedef [flag(NDR_NOALIGN)] struct { uint16 MaxRowCount; hyper CategoryId; } ExpandRow_req; typedef [flag(NDR_NOALIGN)] struct { uint32 ExpandedRowCount; uint16 RowCount; [flag(NDR_REMAINING|NDR_NOALIGN)]DATA_BLOB RowData; } ExpandRow_repl; /*************************/ /* EcDoRpc Function 0x5a */ typedef [flag(NDR_NOALIGN)] struct { hyper CategoryId; } CollapseRow_req; typedef [flag(NDR_NOALIGN)] struct { uint32 CollapsedRowCount; } CollapseRow_repl; /*************************/ /* EcDoRpc Function 0x5b */ typedef [flag(NDR_NOALIGN)] struct { hyper RegionOffset; hyper RegionSize; uint32 LockFlags; } LockRegionStream_req; typedef [flag(NDR_NOALIGN)] struct { } LockRegionStream_repl; /*************************/ /* EcDoRpc Function 0x5c */ typedef [flag(NDR_NOALIGN)] struct { hyper RegionOffset; hyper RegionSize; uint32 LockFlags; } UnlockRegionStream_req; typedef [flag(NDR_NOALIGN)] struct { } UnlockRegionStream_repl; /*************************/ /* EcDoRpc Function 0x5d */ typedef [flag(NDR_NOALIGN)] struct { } CommitStream_req; typedef [flag(NDR_NOALIGN)] struct { } CommitStream_repl; /*************************/ /* EcDoRpc Function 0x5e */ typedef [flag(NDR_NOALIGN)] struct { } GetStreamSize_req; typedef [flag(NDR_NOALIGN)] struct { uint32 StreamSize; } GetStreamSize_repl; /*************************/ /* EcDoRpc Function 0x5f */ typedef [bitmap8bit] bitmap { NoStrings = 0x01, NoIds = 0x02 } QueryFlags; typedef [nodiscriminant] union { [case(0x0)]; [case(0x1)] GUID guid; } QueryNamedProperties_guid; typedef [flag(NDR_NOALIGN)] struct { QueryFlags QueryFlags; boolean8 HasGuid; [switch_is(HasGuid)] QueryNamedProperties_guid PropertyGuid; } QueryNamedProperties_req; typedef [flag(NDR_NOALIGN)] struct { uint16 IdCount; uint16 PropertyIds[IdCount]; MAPINAMEID PropertyNames[IdCount]; } QueryNamedProperties_repl; /*************************/ /* EcDoRpc Function 0x60 */ typedef [flag(NDR_NOALIGN)] struct { GUID DatabaseGuid; } GetPerUserLongTermIds_req; typedef [flag(NDR_NOALIGN)] struct { uint16 LongTermIdCount; LongTermId LongTermIds[LongTermIdCount]; } GetPerUserLongTermIds_repl; /*************************/ /* EcDoRpc Function 0x61 */ typedef [flag(NDR_NOALIGN)] struct { LongTermId LongTermId; } GetPerUserGuid_req; typedef [flag(NDR_NOALIGN)] struct { GUID DatabaseGuid; } GetPerUserGuid_repl; /*************************/ /* EcDoRpc Function 0x63 */ typedef [flag(NDR_NOALIGN)] struct { uint8 FolderId[24]; boolean8 WhatIfChanged; uint32 DataOffset; uint16 MaxDataSize; } ReadPerUserInformation_req; typedef [flag(NDR_NOALIGN)] struct { boolean8 HasFinished; uint16 DataSize; [subcontext(0), subcontext_size(DataSize), flag(NDR_REMAINING|NDR_NOALIGN)] DATA_BLOB Data; } ReadPerUserInformation_repl; /*************************/ /* EcDoRpc Function 0x64 */ typedef [flag(NDR_NOALIGN)] struct { LongTermId FolderId; boolean8 HasFinished; uint32 DataOffset; uint16 DataSize; [subcontext(0), subcontext_size(DataSize), flag(NDR_REMAINING|NDR_NOALIGN)] DATA_BLOB Data; GUID ReplGuid; /* Note: ReplGuid gets only included under specific circumstances */ } WritePerUserInformation_req; typedef [flag(NDR_NOALIGN)] struct { } WritePerUserInformation_repl; /*************************/ /* EcDoRpc Function 0x66 */ typedef [flag(NDR_NOALIGN)] struct { boolean8 WantAsynchronous; MSGFLAG_READ ReadFlags; uint16 MessageIdCount; hyper MessageIds[MessageIdCount]; } SetReadFlags_req; typedef [flag(NDR_NOALIGN)] struct { boolean8 PartialCompletion; } SetReadFlags_repl; /*************************/ /* EcDoRpc Function 0x67 */ typedef [flag(NDR_NOALIGN)] struct { uint8 handle_idx; boolean8 WantAsynchronous; CopyFlags CopyFlags; mapi_SPropTagArray PropertyTags; } CopyProperties_req; typedef [flag(NDR_NOALIGN)] struct { uint16 PropertyProblemCount; PropertyProblem PropertyProblem[PropertyProblemCount]; } CopyProperties_repl; /*************************/ /* EcDoRpc Function 0x68 */ typedef [flag(NDR_NOALIGN)] struct { uint8 unknown; hyper fid; astring lpszMessageClass; FILETIME modiftime; } ReceiveFolder; typedef [flag(NDR_NOALIGN)] struct { } GetReceiveFolderTable_req; typedef [flag(NDR_NOALIGN)] struct { uint32 cValues; ReceiveFolder entries[cValues]; } GetReceiveFolderTable_repl; /**************************/ /* EcDoRpc Function 0x69 */ typedef [bitmap8bit] bitmap { FastTransferCopyProperties_Move = 0x01, FastTransferCopyProperties_Unused1 = 0x02, FastTransferCopyProperties_Unused2 = 0x04, FastTransferCopyProperties_Unused3 = 0x08 } FastCopyPropertiesCopyFlags; typedef [flag(NDR_NOALIGN)] struct { uint8 handle_idx; uint8 Level; FastCopyPropertiesCopyFlags CopyFlags; FastCopySendOptions SendOptions; mapi_SPropTagArray PropertyTags; } FastTransferSourceCopyProperties_req; typedef [flag(NDR_NOALIGN)] struct { } FastTransferSourceCopyProperties_repl; /*************************/ /* EcDoRpc Function 0x6b */ typedef [flag(NDR_NOALIGN)] struct { hyper RowId; uint32 RowInstanceNumber; } GetCollapseState_req; typedef [flag(NDR_NOALIGN)] struct { SBinary_short CollapseState; } GetCollapseState_repl; /*************************/ /* EcDoRpc Function 0x6c */ typedef [flag(NDR_NOALIGN)] struct { SBinary_short CollapseState; } SetCollapseState_req; typedef [flag(NDR_NOALIGN)] struct { SBinary_short bookmark; } SetCollapseState_repl; /*************************/ /* EcDoRpc Function 0x6d */ typedef [flag(NDR_NOALIGN)] struct { } GetTransportFolder_req; typedef [flag(NDR_NOALIGN)] struct { hyper FolderId; } GetTransportFolder_repl; /*************************/ /* EcDoRpc Function 0x6e */ typedef [flag(NDR_NOALIGN)] struct { uint16 SessionIndex; } Pending_repl; /*************************/ /* EcDoRpc Function 0x6f */ typedef [flag(NDR_NOALIGN)] struct { astring AddressType; boolean8 WantWin32; } OptionsData_req; typedef [nodiscriminant, flag(NDR_NOALIGN)] union { [case(0x0)]; [default] raw8string HelpFileName; } OptionsData_HelpFileName; typedef [flag(NDR_NOALIGN)] struct { uint8 Reserved; SBinary_short OptionsInfo; uint16 HelpFileSize; uint8 HelpFile[HelpFileSize]; [switch_is(HelpFileSize)] OptionsData_HelpFileName HelpFileName; } OptionsData_repl; /*************************/ /* EcDoRpc Function 0x70 */ typedef [enum8bit] enum { Contents = 0x1, Hierarchy = 0x2 } SynchronizationType; typedef [bitmap8bit] bitmap { SendOptions_Unicode = 0x1, SendOptions_ForUpload = 0x3, SendOptions_RecoverMode = 0x4, SendOptions_ForceUnicode = 0x8, SendOptions_Partial = 0x10 } SendOptions; typedef [bitmap16bit] bitmap { SynchronizationFlag_Unicode = 0x1, SynchronizationFlag_NoDeletions = 0x2, SynchronizationFlag_NoSoftDeletions = 0x4, SynchronizationFlag_ReadState = 0x8, SynchronizationFlag_FAI = 0x10, SynchronizationFlag_Normal = 0x20, SynchronizationFlag_OnlySpecifiedProperties = 0x80, SynchronizationFlag_NoForeignIdentifiers = 0x100, SynchronizationFlag_Reserved = 0x1000, SynchronizationFlag_BestBody = 0x2000, SynchronizationFlag_IgnoreSpecifiedOnFAI = 0x4000, SynchronizationFlag_Progress = 0x8000 } SynchronizationFlag; typedef [bitmap32bit] bitmap { Eid = 0x00000001, MessageSize = 0x00000002, Cn = 0x00000004, OrderByDeliveryTime = 0x00000008 } SynchronizationExtraFlags; typedef [flag(NDR_NOALIGN)] struct { uint8 handle_idx; SynchronizationType SynchronizationType; SendOptions SendOptions; SynchronizationFlag SynchronizationFlag; uint16 RestrictionSize; [subcontext(0),subcontext_size(RestrictionSize),flag(NDR_REMAINING|NDR_NOALIGN)] DATA_BLOB RestrictionData; SynchronizationExtraFlags SynchronizationExtraFlags; mapi_SPropTagArray PropertyTags; } SyncConfigure_req; typedef [flag(NDR_NOALIGN)] struct { } SyncConfigure_repl; /*************************/ /* EcDoRpc Function 0x72 */ typedef [bitmap8bit] bitmap { ImportFlag_Associated = 0x10, ImportFlag_FailOnConflict = 0x40 } ImportFlag; typedef [flag(NDR_NOALIGN)] struct { uint8 handle_idx; ImportFlag ImportFlag; mapi_SPropValue_array PropertyValues; } SyncImportMessageChange_req; typedef [flag(NDR_NOALIGN)] struct { hyper MessageId; } SyncImportMessageChange_repl; /*************************/ /* EcDoRpc Function 0x73 */ typedef [flag(NDR_NOALIGN)] struct { mapi_SPropValue_array HierarchyValues; mapi_SPropValue_array PropertyValues; } SyncImportHierarchyChange_req; typedef [flag(NDR_NOALIGN)] struct { hyper FolderId; } SyncImportHierarchyChange_repl; /*************************/ /* EcDoRpc Function 0x74 */ typedef [bitmap8bit] bitmap { SyncImportDeletes_Hierarchy = 0x01, SyncImportDeletes_HardDelete = 0x02 } SyncImportDeletesFlags; typedef [flag(NDR_NOALIGN)] struct { SyncImportDeletesFlags Flags; mapi_SPropValue_array PropertyValues; } SyncImportDeletes_req; typedef [flag(NDR_NOALIGN)] struct { } SyncImportDeletes_repl; /*************************/ /* EcDoRpc Function 0x75 */ typedef [v1_enum,flag(NDR_PAHEX)] enum { SP_PidTagIdsetGiven = 0x40170003, SP_PidTagCnsetSeen = 0x67960102, SP_PidTagCnsetSeenFAI = 0x67da0102, SP_PidTagCnsetRead = 0x67d20102 } StateProperty; typedef [v1_enum,flag(NDR_PAHEX)] enum { DP_PidTagIdsetDeleted = 0x67e50102, DP_PidTagIdsetNoLongerInScope = 0x40210102, DP_PidTagIdsetExpired = 0x67930102, DP_PidTagIdsetRead = 0x402d0102, DP_PidTagIdsetUnread = 0x402e0102 } DeltaProperty; typedef [flag(NDR_NOALIGN)] struct { StateProperty StateProperty; uint32 TransferBufferSize; } SyncUploadStateStreamBegin_req; typedef [flag(NDR_NOALIGN)] struct { } SyncUploadStateStreamBegin_repl; /*************************/ /* EcDoRpc Function 0x76 */ typedef [flag(NDR_NOALIGN)] struct { uint32 StreamDataSize; uint8 StreamData[StreamDataSize]; } SyncUploadStateStreamContinue_req; typedef [flag(NDR_NOALIGN)] struct { } SyncUploadStateStreamContinue_repl; /*************************/ /* EcDoRpc Function 0x77 */ typedef [flag(NDR_NOALIGN)] struct { } SyncUploadStateStreamEnd_req; typedef [flag(NDR_NOALIGN)] struct { } SyncUploadStateStreamEnd_repl; /*************************/ /* EcDoRpc Function 0x78 */ typedef [flag(NDR_NOALIGN)] struct { uint32 SourceFolderIdSize; uint8 SourceFolderId[SourceFolderIdSize]; uint32 SourceMessageIdSize; uint8 SourceMessageId[SourceMessageIdSize]; uint32 PredecessorChangeListSize; uint8 PredecessorChangeList[PredecessorChangeListSize]; uint32 DestinationMessageIdSize; uint8 DestinationMessageId[DestinationMessageIdSize]; uint32 ChangeNumberSize; uint8 ChangeNumber[ChangeNumberSize]; } SyncImportMessageMove_req; typedef [flag(NDR_NOALIGN)] struct { hyper MessageId; } SyncImportMessageMove_repl; /*************************/ /* EcDoRpc Function 0x79 */ typedef [flag(NDR_NOALIGN)] struct { [subcontext(2)] mapi_SPropValue_array values; } SetPropertiesNoReplicate_req; typedef [flag(NDR_NOALIGN)] struct { uint16 PropertyProblemCount; PropertyProblem PropertyProblem[PropertyProblemCount]; } SetPropertiesNoReplicate_repl; /*************************/ /* EcDoRpc Function 0x7a */ typedef [flag(NDR_NOALIGN)] struct { mapi_SPropTagArray PropertyTags; } DeletePropertiesNoReplicate_req; typedef [flag(NDR_NOALIGN)] struct { uint16 PropertyProblemCount; PropertyProblem PropertyProblem[PropertyProblemCount]; } DeletePropertiesNoReplicate_repl; /*************************/ /* EcDoRpc Function 0x7b */ typedef [public,bitmap32bit] bitmap { STORE_HAS_SEARCHES = 0x010000000 } StoreState; typedef [flag(NDR_NOALIGN)] struct { } GetStoreState_req; typedef [flag(NDR_NOALIGN)] struct { StoreState StoreState; } GetStoreState_repl; /*************************/ /* EcDoRpc Function 0x7e */ typedef [flag(NDR_NOALIGN)] struct { uint8 handle_idx; boolean8 IsContentsCollector; } SyncOpenCollector_req; typedef [flag(NDR_NOALIGN)] struct { } SyncOpenCollector_repl; /*************************/ /* EcDoRpc Function 0x7f */ typedef [flag(NDR_NOALIGN)] struct { uint32 IdCount; } GetLocalReplicaIds_req; typedef [flag(NDR_NOALIGN)] struct { GUID ReplGuid; uint8 GlobalCount[6]; } GetLocalReplicaIds_repl; /*************************/ /* EcDoRpc Function 0x80 */ typedef [public,flag(NDR_NOALIGN)] struct { uint16 MessageIdSize; uint8 MessageId[MessageIdSize]; boolean8 MarkAsRead; } MessageReadState; typedef [flag(NDR_NOALIGN)] struct { [subcontext(2),flag(NDR_REMAINING|NDR_NOALIGN)] DATA_BLOB MessageReadStates; } SyncImportReadStateChanges_req; typedef [flag(NDR_NOALIGN)] struct { } SyncImportReadStateChanges_repl; /*************************/ /* EcDoRpc Function 0x81 */ typedef [flag(NDR_NOALIGN)] struct { } ResetTable_req; typedef [flag(NDR_NOALIGN)] struct { } ResetTable_repl; /*************************/ /* EcDoRpc Function 0x82 */ typedef [flag(NDR_NOALIGN)] struct { uint8 handle_idx; } SyncGetTransferState_req; typedef [flag(NDR_NOALIGN)] struct { } SyncGetTransferState_repl; /*************************/ /* EcDoRpc Function 0x83 */ typedef [flag(NDR_NOALIGN)] struct { uint8 handle_idx; } SyncOpenAdvisor_req; typedef [flag(NDR_NOALIGN)] struct { } SyncOpenAdvisor_repl; /*************************/ /* EcDoRpc Function 0x86 */ typedef [flag(NDR_NOALIGN)] struct { uint16 version[3]; } TellVersion_req; typedef [flag(NDR_NOALIGN)] struct { } TellVersion_repl; /*************************/ /* EcDoRpc Function 0x87 */ typedef [flag(NDR_NOALIGN)] struct { uint8 handle_idx; asclstr name; } OpenPublicFolderByName_req; typedef [flag(NDR_NOALIGN)] struct { boolean8 HasRules; boolean8 IsGhosted; [switch_is(IsGhosted)] IsGhosted Ghost; } OpenPublicFolderByName_repl; /*************************/ /* EcDoRpc Function 0x88 */ typedef [flag(NDR_NOALIGN)] struct { GUID NotificationGuid; } SetSyncNotificationGuid_req; typedef [flag(NDR_NOALIGN)] struct { } SetSyncNotificationGuid_repl; /*************************/ /* EcDoRpc Function 0x89 */ typedef [flag(NDR_NOALIGN)] struct { SBinary_short bookmark; } FreeBookmark_req; typedef [flag(NDR_NOALIGN)] struct { } FreeBookmark_repl; /*************************/ /* EcDoRpc Function 0x90 */ typedef [flag(NDR_NOALIGN)] struct { [subcontext(2), flag(NDR_REMAINING|NDR_NOALIGN)] DATA_BLOB data; } WriteAndCommitStream_req; typedef [flag(NDR_NOALIGN)] struct { uint16 WrittenSize; } WriteAndCommitStream_repl; /**************************/ /* EcDoRpc Function 0x91 */ typedef [flag(NDR_NOALIGN)] struct { boolean8 WantAsynchronous; boolean8 NotifyNonRead; uint16 MessageIdCount; hyper MessageIds[MessageIdCount]; } HardDeleteMessages_req; typedef [flag(NDR_NOALIGN)] struct { boolean8 PartialCompletion; } HardDeleteMessages_repl; /*************************/ /* EcDoRpc Function 0x92 */ typedef [flag(NDR_NOALIGN)] struct { boolean8 WantAsynchronous; boolean8 WantDeleteAssociated; } HardDeleteMessagesAndSubfolders_req; typedef [flag(NDR_NOALIGN)] struct { boolean8 PartialCompletion; } HardDeleteMessagesAndSubfolders_repl; /*************************/ /* EcDoRpc Function 0x93 */ typedef [public,flag(NDR_NOALIGN)] struct { LongTermId MinLongTermId; LongTermId MaxLongTermId; } LongTermIdRange; typedef [flag(NDR_NOALIGN)] struct { uint16 DataSize; uint32 LongTermIdRangeCount; LongTermIdRange LongTermIdRanges[LongTermIdRangeCount]; } SetLocalReplicaMidsetDeleted_req; typedef [flag(NDR_NOALIGN)] struct { } SetLocalReplicaMidsetDeleted_repl; /**************************/ /* EcDoRpc Function 0xF9 */ typedef [nopush,nopull,flag(NDR_NOALIGN)] struct { } Backoff_req; typedef [nopush,nopull,flag(NDR_NOALIGN)] struct { } Backoff_repl; /*************************/ /* EcDoRpc Function 0xFE */ typedef [public,bitmap8bit] bitmap { LogonPrivate = 0x1, UnderCover = 0x2, Ghosted = 0x4, SpIProcess = 0x8 } LogonFlags; typedef [public,bitmap32bit] bitmap { PUBLIC = 0x2, HOME_LOGON = 0x4, TAKE_OWNERSHIP = 0x8, ALTERNATE_SERVER = 0x100, IGNORE_HOME_MDB = 0x200, NO_MAIL = 0x400, USE_PER_MDB_REPLID_MAPPING = 0x010000000 } OpenFlags; typedef [enum8bit] enum { DayOfWeek_Sunday = 0x0, DayOfWeek_Monday = 0x1, DayOfWeek_Tuesday = 0x2, DayOfWeek_Wednesday = 0x3, DayOfWeek_Thursday = 0x4, DayOfWeek_Friday = 0x5, DayOfWeek_Saturday = 0x6 } DayOfWeek; typedef [flag(NDR_NOALIGN)] struct { uint8 Seconds; uint8 Minutes; uint8 Hour; DayOfWeek DayOfWeek; uint8 Day; uint8 Month; uint16 Year; } LogonTime; typedef [bitmap8bit] bitmap { ResponseFlags_Reserved = 0x1, ResponseFlags_OwnerRight = 0x2, ResponseFlags_SendAsRight = 0x4, ResponseFlags_OOF = 0x10 } ResponseFlags; typedef [flag(NDR_NOALIGN)] struct { /* folders */ hyper Root; hyper IPMSubTree; hyper NonIPMSubTree; hyper EFormsRegistry; hyper FreeBusy; hyper OAB; hyper LocalizedEFormsRegistry; hyper LocalFreeBusy; hyper LocalOAB; hyper NNTPIndex; hyper _empty[3]; uint16 ReplId; GUID Guid; GUID PerUserGuid; } store_pf; typedef [flag(NDR_NOALIGN)] struct { /* folders */ hyper Root; hyper DeferredAction; hyper SpoolerQueue; hyper IPMSubTree; hyper Inbox; hyper Outbox; hyper SentItems; hyper DeletedItems; hyper CommonViews; hyper Schedule; hyper Search; hyper Views; hyper Shortcuts; ResponseFlags ResponseFlags; GUID MailboxGuid; uint16 ReplId; GUID ReplGUID; LogonTime LogonTime; hyper GwartTime; StoreState StoreState; } store_mailbox; typedef [nodiscriminant] union { [case(0x0)] store_pf store_pf; [case(0x3)] store_mailbox store_mailbox; [case(0x9)] store_mailbox store_mailbox; [case(0x19)] store_mailbox store_mailbox; [case(LogonPrivate)] store_mailbox store_mailbox; } LogonType; typedef [nopush,flag(NDR_NOALIGN)] struct { LogonFlags LogonFlags; OpenFlags OpenFlags; StoreState StoreState; ascstr3 EssDN; } Logon_req; typedef [flag(NDR_NOALIGN)] struct { LogonFlags LogonFlags; [switch_is(LogonFlags)] LogonType LogonType; } Logon_repl; /* Logon redirect response buffer (error_code == ecWrongServer) */ typedef [public,flag(NDR_NOALIGN)] struct { LogonFlags LogonFlags; uint8 ServerNameSize; astring ServerName; } Logon_redirect; /**************************/ /* EcDoRpc Function 0xFF */ typedef [nopush,nopull,flag(NDR_NOALIGN)] struct { } BufferTooSmall_req; typedef [nopush,nopull,flag(NDR_NOALIGN)] struct { } BufferTooSmall_repl; /*************************/ /* EcDoRpc Function 0xA5 */ typedef [flag(NDR_NOALIGN)] struct { SBinary_short bin; } proxypack_req; typedef [flag(NDR_NOALIGN)] struct { SBinary_short bin; } proxypack_repl; typedef [public, nodiscriminant] union { [case(op_MAPI_Release)] Release_req mapi_Release; [case(op_MAPI_OpenFolder)] OpenFolder_req mapi_OpenFolder; [case(op_MAPI_OpenMessage)] OpenMessage_req mapi_OpenMessage; [case(op_MAPI_GetHierarchyTable)] GetHierarchyTable_req mapi_GetHierarchyTable; [case(op_MAPI_GetContentsTable)] GetContentsTable_req mapi_GetContentsTable; [case(op_MAPI_CreateMessage)] CreateMessage_req mapi_CreateMessage; [case(op_MAPI_GetProps)] GetProps_req mapi_GetProps; [case(op_MAPI_GetPropsAll)] GetPropsAll_req mapi_GetPropsAll; [case(op_MAPI_GetPropList)] GetPropList_req mapi_GetPropList; [case(op_MAPI_SetProps)] SetProps_req mapi_SetProps; [case(op_MAPI_DeleteProps)] DeleteProps_req mapi_DeleteProps; [case(op_MAPI_SaveChangesMessage)] SaveChangesMessage_req mapi_SaveChangesMessage; [case(op_MAPI_SetMessageReadFlag)] SetMessageReadFlag_req mapi_SetMessageReadFlag; [case(op_MAPI_ReloadCachedInformation)] ReloadCachedInformation_req mapi_ReloadCachedInformation; [case(op_MAPI_SetColumns)] SetColumns_req mapi_SetColumns; [case(op_MAPI_SortTable)] SortTable_req mapi_SortTable; [case(op_MAPI_Restrict)] Restrict_req mapi_Restrict; [case(op_MAPI_RemoveAllRecipients)] RemoveAllRecipients_req mapi_RemoveAllRecipients; [case(op_MAPI_ModifyRecipients)] ModifyRecipients_req mapi_ModifyRecipients; [case(op_MAPI_ReadRecipients)] ReadRecipients_req mapi_ReadRecipients; [case(op_MAPI_QueryRows)] QueryRows_req mapi_QueryRows; [case(op_MAPI_GetStatus)] GetStatus_req mapi_GetStatus; [case(op_MAPI_QueryPosition)] QueryPosition_req mapi_QueryPosition; [case(op_MAPI_SeekRow)] SeekRow_req mapi_SeekRow; [case(op_MAPI_SeekRowBookmark)] SeekRowBookmark_req mapi_SeekRowBookmark; [case(op_MAPI_SeekRowApprox)] SeekRowApprox_req mapi_SeekRowApprox; [case(op_MAPI_CreateBookmark)] CreateBookmark_req mapi_CreateBookmark; [case(op_MAPI_CreateFolder)] CreateFolder_req mapi_CreateFolder; [case(op_MAPI_DeleteFolder)] DeleteFolder_req mapi_DeleteFolder; [case(op_MAPI_DeleteMessages)] DeleteMessages_req mapi_DeleteMessages; [case(op_MAPI_GetMessageStatus)] GetMessageStatus_req mapi_GetMessageStatus; [case(op_MAPI_SetMessageStatus)] SetMessageStatus_req mapi_SetMessageStatus; [case(op_MAPI_GetAttachmentTable)] GetAttachmentTable_req mapi_GetAttachmentTable; [case(op_MAPI_OpenAttach)] OpenAttach_req mapi_OpenAttach; [case(op_MAPI_CreateAttach)] CreateAttach_req mapi_CreateAttach; [case(op_MAPI_DeleteAttach)] DeleteAttach_req mapi_DeleteAttach; [case(op_MAPI_SaveChangesAttachment)] SaveChangesAttachment_req mapi_SaveChangesAttachment; [case(op_MAPI_SetReceiveFolder)] SetReceiveFolder_req mapi_SetReceiveFolder; [case(op_MAPI_GetReceiveFolder)] GetReceiveFolder_req mapi_GetReceiveFolder; [case(op_MAPI_RegisterNotification)] RegisterNotification_req mapi_RegisterNotification; [case(op_MAPI_OpenStream)] OpenStream_req mapi_OpenStream; [case(op_MAPI_ReadStream)] ReadStream_req mapi_ReadStream; [case(op_MAPI_WriteStream)] WriteStream_req mapi_WriteStream; [case(op_MAPI_SeekStream)] SeekStream_req mapi_SeekStream; [case(op_MAPI_SetStreamSize)] SetStreamSize_req mapi_SetStreamSize; [case(op_MAPI_SetSearchCriteria)] SetSearchCriteria_req mapi_SetSearchCriteria; [case(op_MAPI_GetSearchCriteria)] GetSearchCriteria_req mapi_GetSearchCriteria; [case(op_MAPI_SubmitMessage)] SubmitMessage_req mapi_SubmitMessage; [case(op_MAPI_MoveCopyMessages)] MoveCopyMessages_req mapi_MoveCopyMessages; [case(op_MAPI_AbortSubmit)] AbortSubmit_req mapi_AbortSubmit; [case(op_MAPI_MoveFolder)] MoveFolder_req mapi_MoveFolder; [case(op_MAPI_CopyFolder)] CopyFolder_req mapi_CopyFolder; [case(op_MAPI_QueryColumnsAll)] QueryColumnsAll_req mapi_QueryColumnsAll; [case(op_MAPI_Abort)] Abort_req mapi_Abort; [case(op_MAPI_CopyTo)] CopyTo_req mapi_CopyTo; [case(op_MAPI_CopyToStream)] CopyToStream_req mapi_CopyToStream; [case(op_MAPI_CloneStream)] CloneStream_req mapi_CloneStream; [case(op_MAPI_GetPermissionsTable)] GetPermissionsTable_req mapi_GetPermissionsTable; [case(op_MAPI_GetRulesTable)] GetRulesTable_req mapi_GetRulesTable; [case(op_MAPI_ModifyPermissions)] ModifyPermissions_req mapi_ModifyPermissions; [case(op_MAPI_ModifyRules)] ModifyRules_req mapi_ModifyRules; [case(op_MAPI_GetOwningServers)] GetOwningServers_req mapi_GetOwningServers; [case(op_MAPI_LongTermIdFromId)] LongTermIdFromId_req mapi_LongTermIdFromId; [case(op_MAPI_IdFromLongTermId)] IdFromLongTermId_req mapi_IdFromLongTermId; [case(op_MAPI_PublicFolderIsGhosted)] PublicFolderIsGhosted_req mapi_PublicFolderIsGhosted; [case(op_MAPI_OpenEmbeddedMessage)] OpenEmbeddedMessage_req mapi_OpenEmbeddedMessage; [case(op_MAPI_SetSpooler)] SetSpooler_req mapi_SetSpooler; [case(op_MAPI_SpoolerLockMessage)] SpoolerLockMessage_req mapi_SpoolerLockMessage; [case(op_MAPI_AddressTypes)] AddressTypes_req mapi_AddressTypes; [case(op_MAPI_TransportSend)] TransportSend_req mapi_TransportSend; [case(op_MAPI_FastTransferSourceCopyMessages)] FastTransferSourceCopyMessages_req mapi_FastTransferSourceCopyMessages; [case(op_MAPI_FastTransferSourceCopyFolder)] FastTransferSourceCopyFolder_req mapi_FastTransferSourceCopyFolder; [case(op_MAPI_FastTransferSourceCopyTo)] FastTransferSourceCopyTo_req mapi_FastTransferSourceCopyTo; [case(op_MAPI_FastTransferSourceGetBuffer)] FastTransferSourceGetBuffer_req mapi_FastTransferSourceGetBuffer; [case(op_MAPI_FindRow)] FindRow_req mapi_FindRow; [case(op_MAPI_Progress)] Progress_req mapi_Progress; [case(op_MAPI_TransportNewMail)] TransportNewMail_req mapi_TransportNewMail; [case(op_MAPI_GetValidAttachments)] GetValidAttachments_req mapi_GetValidAttachments; [case(op_MAPI_FastTransferDestConfigure)] FastTransferDestinationConfigure_req mapi_FastTransferDestinationConfigure; [case(op_MAPI_FastTransferDestPutBuffer)] FastTransferDestinationPutBuffer_req mapi_FastTransferDestinationPutBuffer; [case(op_MAPI_GetNamesFromIDs)] GetNamesFromIDs_req mapi_GetNamesFromIDs; [case(op_MAPI_GetIDsFromNames)] GetIDsFromNames_req mapi_GetIDsFromNames; [case(op_MAPI_UpdateDeferredActionMessages)] UpdateDeferredActionMessages_req mapi_UpdateDeferredActionMessages; [case(op_MAPI_EmptyFolder)] EmptyFolder_req mapi_EmptyFolder; [case(op_MAPI_ExpandRow)] ExpandRow_req mapi_ExpandRow; [case(op_MAPI_CollapseRow)] CollapseRow_req mapi_CollapseRow; [case(op_MAPI_LockRegionStream)] LockRegionStream_req mapi_LockRegionStream; [case(op_MAPI_UnlockRegionStream)] UnlockRegionStream_req mapi_UnlockRegionStream; [case(op_MAPI_CommitStream)] CommitStream_req mapi_CommitStream; [case(op_MAPI_GetStreamSize)] GetStreamSize_req mapi_GetStreamSize; [case(op_MAPI_QueryNamedProperties)] QueryNamedProperties_req mapi_QueryNamedProperties; [case(op_MAPI_GetPerUserLongTermIds)] GetPerUserLongTermIds_req mapi_GetPerUserLongTermIds; [case(op_MAPI_GetPerUserGuid)] GetPerUserGuid_req mapi_GetPerUserGuid; [case(op_MAPI_ReadPerUserInformation)] ReadPerUserInformation_req mapi_ReadPerUserInformation; [case(op_MAPI_WritePerUserInformation)] WritePerUserInformation_req mapi_WritePerUserInformation; [case(op_MAPI_SetReadFlags)] SetReadFlags_req mapi_SetReadFlags; [case(op_MAPI_CopyProperties)] CopyProperties_req mapi_CopyProperties; [case(op_MAPI_GetReceiveFolderTable)] GetReceiveFolderTable_req mapi_GetReceiveFolderTable; [case(op_MAPI_FastTransferSourceCopyProps)] FastTransferSourceCopyProperties_req mapi_FastTransferSourceCopyProperties; [case(op_MAPI_GetCollapseState)] GetCollapseState_req mapi_GetCollapseState; [case(op_MAPI_SetCollapseState)] SetCollapseState_req mapi_SetCollapseState; [case(op_MAPI_GetTransportFolder)] GetTransportFolder_req mapi_GetTransportFolder; [case(op_MAPI_OptionsData)] OptionsData_req mapi_OptionsData; [case(op_MAPI_SyncConfigure)] SyncConfigure_req mapi_SyncConfigure; [case(op_MAPI_SyncImportMessageChange)] SyncImportMessageChange_req mapi_SyncImportMessageChange; [case(op_MAPI_SyncImportHierarchyChange)] SyncImportHierarchyChange_req mapi_SyncImportHierarchyChange; [case(op_MAPI_SyncImportDeletes)] SyncImportDeletes_req mapi_SyncImportDeletes; [case(op_MAPI_SyncUploadStateStreamBegin)] SyncUploadStateStreamBegin_req mapi_SyncUploadStateStreamBegin; [case(op_MAPI_SyncUploadStateStreamContinue)] SyncUploadStateStreamContinue_req mapi_SyncUploadStateStreamContinue; [case(op_MAPI_SyncUploadStateStreamEnd)] SyncUploadStateStreamEnd_req mapi_SyncUploadStateStreamEnd; [case(op_MAPI_SyncImportMessageMove)] SyncImportMessageMove_req mapi_SyncImportMessageMove; [case(op_MAPI_SetPropertiesNoReplicate)] SetPropertiesNoReplicate_req mapi_SetPropertiesNoReplicate; [case(op_MAPI_DeletePropertiesNoReplicate)] DeletePropertiesNoReplicate_req mapi_DeletePropertiesNoReplicate; [case(op_MAPI_GetStoreState)] GetStoreState_req mapi_GetStoreState; [case(op_MAPI_SyncOpenCollector)] SyncOpenCollector_req mapi_SyncOpenCollector; [case(op_MAPI_GetLocalReplicaIds)] GetLocalReplicaIds_req mapi_GetLocalReplicaIds; [case(op_MAPI_SyncImportReadStateChanges)] SyncImportReadStateChanges_req mapi_SyncImportReadStateChanges; [case(op_MAPI_ResetTable)] ResetTable_req mapi_ResetTable; [case(op_MAPI_SyncGetTransferState)] SyncGetTransferState_req mapi_SyncGetTransferState; [case(op_MAPI_SyncOpenAdvisor)] SyncOpenAdvisor_req mapi_SyncOpenAdvisor; [case(op_MAPI_TellVersion)] TellVersion_req mapi_TellVersion; [case(op_MAPI_OpenPublicFolderByName)] OpenPublicFolderByName_req mapi_OpenPublicFolderByName; [case(op_MAPI_SetSyncNotificationGuid)] SetSyncNotificationGuid_req mapi_SetSyncNotificationGuid; [case(op_MAPI_FreeBookmark)] FreeBookmark_req mapi_FreeBookmark; [case(op_MAPI_WriteAndCommitStream)] WriteAndCommitStream_req mapi_WriteAndCommitStream; [case(op_MAPI_HardDeleteMessages)] HardDeleteMessages_req mapi_HardDeleteMessages; [case(op_MAPI_HardDeleteMessagesAndSubfolders)] HardDeleteMessagesAndSubfolders_req mapi_HardDeleteMessagesAndSubfolders; [case(op_MAPI_SetLocalReplicaMidsetDeleted)] SetLocalReplicaMidsetDeleted_req mapi_SetLocalReplicaMidsetDeleted; [case(op_MAPI_Backoff)] Backoff_req mapi_Backoff; [case(op_MAPI_Logon)] Logon_req mapi_Logon; [case(op_MAPI_BufferTooSmall)] BufferTooSmall_req mapi_BufferTooSmall; [case(op_MAPI_proxypack)] proxypack_req mapi_proxypack; } EcDoRpc_MAPI_REQ_UNION; typedef [public, nodiscriminant] union { [case(op_MAPI_Release)] Release_repl mapi_Release; [case(op_MAPI_OpenFolder)] OpenFolder_repl mapi_OpenFolder; [case(op_MAPI_OpenMessage)] OpenMessage_repl mapi_OpenMessage; [case(op_MAPI_GetHierarchyTable)] GetHierarchyTable_repl mapi_GetHierarchyTable; [case(op_MAPI_GetContentsTable)] GetContentsTable_repl mapi_GetContentsTable; [case(op_MAPI_CreateMessage)] CreateMessage_repl mapi_CreateMessage; [case(op_MAPI_GetProps)] GetProps_repl mapi_GetProps; [case(op_MAPI_GetPropsAll)] GetPropsAll_repl mapi_GetPropsAll; [case(op_MAPI_GetPropList)] GetPropList_repl mapi_GetPropList; [case(op_MAPI_SetProps)] SetProps_repl mapi_SetProps; [case(op_MAPI_DeleteProps)] DeleteProps_repl mapi_DeleteProps; [case(op_MAPI_SaveChangesMessage)] SaveChangesMessage_repl mapi_SaveChangesMessage; [case(op_MAPI_RemoveAllRecipients)] RemoveAllRecipients_repl mapi_RemoveAllRecipients; [case(op_MAPI_ModifyRecipients)] ModifyRecipients_repl mapi_ModifyRecipients; [case(op_MAPI_ReadRecipients)] ReadRecipients_repl mapi_ReadRecipients; [case(op_MAPI_SetMessageReadFlag)] SetMessageReadFlag_repl mapi_SetMessageReadFlag; [case(op_MAPI_ReloadCachedInformation)] ReloadCachedInformation_repl mapi_ReloadCachedInformation; [case(op_MAPI_SetColumns)] SetColumns_repl mapi_SetColumns; [case(op_MAPI_SortTable)] SortTable_repl mapi_SortTable; [case(op_MAPI_Restrict)] Restrict_repl mapi_Restrict; [case(op_MAPI_QueryRows)] QueryRows_repl mapi_QueryRows; [case(op_MAPI_GetStatus)] GetStatus_repl mapi_GetStatus; [case(op_MAPI_QueryPosition)] QueryPosition_repl mapi_QueryPosition; [case(op_MAPI_SeekRow)] SeekRow_repl mapi_SeekRow; [case(op_MAPI_SeekRowBookmark)] SeekRowBookmark_repl mapi_SeekRowBookmark; [case(op_MAPI_SeekRowApprox)] SeekRowApprox_repl mapi_SeekRowApprox; [case(op_MAPI_CreateBookmark)] CreateBookmark_repl mapi_CreateBookmark; [case(op_MAPI_CreateFolder)] CreateFolder_repl mapi_CreateFolder; [case(op_MAPI_DeleteFolder)] DeleteFolder_repl mapi_DeleteFolder; [case(op_MAPI_DeleteMessages)] DeleteMessages_repl mapi_DeleteMessages; [case(op_MAPI_SetMessageStatus)] SetMessageStatus_repl mapi_SetMessageStatus; [case(op_MAPI_GetAttachmentTable)] GetAttachmentTable_repl mapi_GetAttachmentTable; [case(op_MAPI_OpenAttach)] OpenAttach_repl mapi_OpenAttach; [case(op_MAPI_CreateAttach)] CreateAttach_repl mapi_CreateAttach; [case(op_MAPI_DeleteAttach)] DeleteAttach_repl mapi_DeleteAttach; [case(op_MAPI_SaveChangesAttachment)] SaveChangesAttachment_repl mapi_SaveChangesAttachment; [case(op_MAPI_SetReceiveFolder)] SetReceiveFolder_repl mapi_SetReceiveFolder; [case(op_MAPI_GetReceiveFolder)] GetReceiveFolder_repl mapi_GetReceiveFolder; [case(op_MAPI_RegisterNotification)] RegisterNotification_repl mapi_RegisterNotification; [case(op_MAPI_Notify)] Notify_repl mapi_Notify; [case(op_MAPI_OpenStream)] OpenStream_repl mapi_OpenStream; [case(op_MAPI_ReadStream)] ReadStream_repl mapi_ReadStream; [case(op_MAPI_WriteStream)] WriteStream_repl mapi_WriteStream; [case(op_MAPI_SeekStream)] SeekStream_repl mapi_SeekStream; [case(op_MAPI_SetStreamSize)] SetStreamSize_repl mapi_SetStreamSize; [case(op_MAPI_SetSearchCriteria)] SetSearchCriteria_repl mapi_SetSearchCriteria; [case(op_MAPI_GetSearchCriteria)] GetSearchCriteria_repl mapi_GetSearchCriteria; [case(op_MAPI_SubmitMessage)] SubmitMessage_repl mapi_SubmitMessage; [case(op_MAPI_MoveCopyMessages)] MoveCopyMessages_repl mapi_MoveCopyMessages; [case(op_MAPI_AbortSubmit)] AbortSubmit_repl mapi_AbortSubmit; [case(op_MAPI_MoveFolder)] MoveFolder_repl mapi_MoveFolder; [case(op_MAPI_CopyFolder)] CopyFolder_repl mapi_CopyFolder; [case(op_MAPI_QueryColumnsAll)] QueryColumnsAll_repl mapi_QueryColumnsAll; [case(op_MAPI_Abort)] Abort_repl mapi_Abort; [case(op_MAPI_CopyTo)] CopyTo_repl mapi_CopyTo; [case(op_MAPI_CopyToStream)] CopyToStream_repl mapi_CopyToStream; [case(op_MAPI_CloneStream)] CloneStream_repl mapi_CloneStream; [case(op_MAPI_GetPermissionsTable)] GetPermissionsTable_repl mapi_GetPermissionsTable; [case(op_MAPI_GetRulesTable)] GetRulesTable_repl mapi_GetRulesTable; [case(op_MAPI_ModifyPermissions)] ModifyPermissions_repl mapi_ModifyPermissions; [case(op_MAPI_ModifyRules)] ModifyRules_repl mapi_ModifyRules; [case(op_MAPI_GetOwningServers)] GetOwningServers_repl mapi_GetOwningServers; [case(op_MAPI_LongTermIdFromId)] LongTermIdFromId_repl mapi_LongTermIdFromId; [case(op_MAPI_IdFromLongTermId)] IdFromLongTermId_repl mapi_IdFromLongTermId; [case(op_MAPI_PublicFolderIsGhosted)] PublicFolderIsGhosted_repl mapi_PublicFolderIsGhosted; [case(op_MAPI_OpenEmbeddedMessage)] OpenEmbeddedMessage_repl mapi_OpenEmbeddedMessage; [case(op_MAPI_SetSpooler)] SetSpooler_repl mapi_SetSpooler; [case(op_MAPI_SpoolerLockMessage)] SpoolerLockMessage_repl mapi_SpoolerLockMessage; [case(op_MAPI_AddressTypes)] AddressTypes_repl mapi_AddressTypes; [case(op_MAPI_TransportSend)] TransportSend_repl mapi_TransportSend; [case(op_MAPI_FastTransferSourceCopyMessages)] FastTransferSourceCopyMessages_repl mapi_FastTransferSourceCopyMessages; [case(op_MAPI_FastTransferSourceCopyFolder)] FastTransferSourceCopyFolder_repl mapi_FastTransferSourceCopyFolder; [case(op_MAPI_FastTransferSourceCopyTo)] FastTransferSourceCopyTo_repl mapi_FastTransferSourceCopyTo; [case(op_MAPI_FastTransferSourceGetBuffer)] FastTransferSourceGetBuffer_repl mapi_FastTransferSourceGetBuffer; [case(op_MAPI_FindRow)] FindRow_repl mapi_FindRow; [case(op_MAPI_Progress)] Progress_repl mapi_Progress; [case(op_MAPI_TransportNewMail)] TransportNewMail_repl mapi_TransportNewMail; [case(op_MAPI_GetValidAttachments)] GetValidAttachments_repl mapi_GetValidAttachments; [case(op_MAPI_FastTransferDestConfigure)] FastTransferDestinationConfigure_repl mapi_FastTransferDestinationConfigure; [case(op_MAPI_FastTransferDestPutBuffer)] FastTransferDestinationPutBuffer_repl mapi_FastTransferDestinationPutBuffer; [case(op_MAPI_GetNamesFromIDs)] GetNamesFromIDs_repl mapi_GetNamesFromIDs; [case(op_MAPI_GetIDsFromNames)] GetIDsFromNames_repl mapi_GetIDsFromNames; [case(op_MAPI_UpdateDeferredActionMessages)] UpdateDeferredActionMessages_repl mapi_UpdateDeferredActionMessages; [case(op_MAPI_EmptyFolder)] EmptyFolder_repl mapi_EmptyFolder; [case(op_MAPI_ExpandRow)] ExpandRow_repl mapi_ExpandRow; [case(op_MAPI_CollapseRow)] CollapseRow_repl mapi_CollapseRow; [case(op_MAPI_LockRegionStream)] LockRegionStream_repl mapi_LockRegionStream; [case(op_MAPI_UnlockRegionStream)] UnlockRegionStream_repl mapi_UnlockRegionStream; [case(op_MAPI_CommitStream)] CommitStream_repl mapi_CommitStream; [case(op_MAPI_GetStreamSize)] GetStreamSize_repl mapi_GetStreamSize; [case(op_MAPI_QueryNamedProperties)] QueryNamedProperties_repl mapi_QueryNamedProperties; [case(op_MAPI_GetPerUserLongTermIds)] GetPerUserLongTermIds_repl mapi_GetPerUserLongTermIds; [case(op_MAPI_GetPerUserGuid)] GetPerUserGuid_repl mapi_GetPerUserGuid; [case(op_MAPI_ReadPerUserInformation)] ReadPerUserInformation_repl mapi_ReadPerUserInformation; [case(op_MAPI_WritePerUserInformation)] WritePerUserInformation_repl mapi_WritePerUserInformation; [case(op_MAPI_SetReadFlags)] SetReadFlags_repl mapi_SetReadFlags; [case(op_MAPI_CopyProperties)] CopyProperties_repl mapi_CopyProperties; [case(op_MAPI_GetReceiveFolderTable)] GetReceiveFolderTable_repl mapi_GetReceiveFolderTable; [case(op_MAPI_Pending)] Pending_repl mapi_Pending; [case(op_MAPI_FastTransferSourceCopyProps)] FastTransferSourceCopyProperties_repl mapi_FastTransferSourceCopyProperties; [case(op_MAPI_GetCollapseState)] GetCollapseState_repl mapi_GetCollapseState; [case(op_MAPI_SetCollapseState)] SetCollapseState_repl mapi_SetCollapseState; [case(op_MAPI_GetTransportFolder)] GetTransportFolder_repl mapi_GetTransportFolder; [case(op_MAPI_OptionsData)] OptionsData_repl mapi_OptionsData; [case(op_MAPI_SyncConfigure)] SyncConfigure_repl mapi_SyncConfigure; [case(op_MAPI_SyncImportMessageChange)] SyncImportMessageChange_repl mapi_SyncImportMessageChange; [case(op_MAPI_SyncImportHierarchyChange)] SyncImportHierarchyChange_repl mapi_SyncImportHierarchyChange; [case(op_MAPI_SyncImportDeletes)] SyncImportDeletes_repl mapi_SyncImportDeletes; [case(op_MAPI_SyncUploadStateStreamBegin)] SyncUploadStateStreamBegin_repl mapi_SyncUploadStateStreamBegin; [case(op_MAPI_SyncUploadStateStreamContinue)] SyncUploadStateStreamContinue_repl mapi_SyncUploadStateStreamContinue; [case(op_MAPI_SyncUploadStateStreamEnd)] SyncUploadStateStreamEnd_repl mapi_SyncUploadStateStreamEnd; [case(op_MAPI_SyncImportMessageMove)] SyncImportMessageMove_repl mapi_SyncImportMessageMove; [case(op_MAPI_SetPropertiesNoReplicate)] SetPropertiesNoReplicate_repl mapi_SetPropertiesNoReplicate; [case(op_MAPI_DeletePropertiesNoReplicate)] DeletePropertiesNoReplicate_repl mapi_DeletePropertiesNoReplicate; [case(op_MAPI_GetStoreState)] GetStoreState_repl mapi_GetStoreState; [case(op_MAPI_SyncOpenCollector)] SyncOpenCollector_repl mapi_SyncOpenCollector; [case(op_MAPI_GetLocalReplicaIds)] GetLocalReplicaIds_repl mapi_GetLocalReplicaIds; [case(op_MAPI_SyncImportReadStateChanges)] SyncImportReadStateChanges_repl mapi_SyncImportReadStateChanges; [case(op_MAPI_ResetTable)] ResetTable_repl mapi_ResetTable; [case(op_MAPI_SyncGetTransferState)] SyncGetTransferState_repl mapi_SyncGetTransferState; [case(op_MAPI_SyncOpenAdvisor)] SyncOpenAdvisor_repl mapi_SyncOpenAdvisor; [case(op_MAPI_TellVersion)] TellVersion_repl mapi_TellVersion; [case(op_MAPI_OpenPublicFolderByName)] OpenPublicFolderByName_repl mapi_OpenPublicFolderByName; [case(op_MAPI_SetSyncNotificationGuid)] SetSyncNotificationGuid_repl mapi_SetSyncNotificationGuid; [case(op_MAPI_FreeBookmark)] FreeBookmark_repl mapi_FreeBookmark; [case(op_MAPI_WriteAndCommitStream)] WriteAndCommitStream_repl mapi_WriteAndCommitStream; [case(op_MAPI_HardDeleteMessages)] HardDeleteMessages_repl mapi_HardDeleteMessages; [case(op_MAPI_HardDeleteMessagesAndSubfolders)] HardDeleteMessagesAndSubfolders_repl mapi_HardDeleteMessagesAndSubfolders; [case(op_MAPI_SetLocalReplicaMidsetDeleted)] SetLocalReplicaMidsetDeleted_repl mapi_SetLocalReplicaMidsetDeleted; [case(op_MAPI_Backoff)] Backoff_repl mapi_Backoff; [case(op_MAPI_Logon)] Logon_repl mapi_Logon; [case(op_MAPI_BufferTooSmall)] BufferTooSmall_repl mapi_BufferTooSmall; [case(op_MAPI_proxypack)] proxypack_repl mapi_proxypack; } EcDoRpc_MAPI_REPL_UNION; typedef [public, nodiscriminant] union { [case(op_MAPI_Logon)] Logon_redirect mapi_Logon; [default]; } EcDoRpc_MAPI_REPL_UNION_SPECIAL; typedef [public,flag(NDR_NOALIGN)] struct { uint8 opnum; uint8 logon_id; uint8 handle_idx; [switch_is(opnum)] EcDoRpc_MAPI_REQ_UNION u; } EcDoRpc_MAPI_REQ; typedef [public,nopush,nopull,noprint,flag(NDR_NOALIGN)] struct { uint8 opnum; uint8 handle_idx; MAPISTATUS error_code; [switch_is(opnum)] EcDoRpc_MAPI_REPL_UNION u; [switch_is(opnum)] EcDoRpc_MAPI_REPL_UNION_SPECIAL us; } EcDoRpc_MAPI_REPL; /* Abstract way to represent MAPI content */ typedef [public,nopull,nopush,noprint] struct { uint32 mapi_len; /* whole mapi_data length */ uint16 length; /* content length */ EcDoRpc_MAPI_REQ *mapi_req; uint32 *handles; /* handles id array */ } mapi_request; typedef [public,nopull,nopush,noprint] struct { uint32 mapi_len; uint16 length; EcDoRpc_MAPI_REPL *mapi_repl; uint32 *handles; } mapi_response; [public,nopull,nopush] MAPISTATUS EcDoRpc( [in,out] policy_handle *handle, [in,out] uint32 size, [in,out] uint32 offset, [in] [subcontext(4),flag(NDR_REMAINING|NDR_NOALIGN)] mapi_request *mapi_request, [out][subcontext(4),flag(NDR_REMAINING|NDR_NOALIGN)] mapi_response *mapi_response, [in,out] uint16 *length, [in] uint16 max_data ); /*****************/ /* Function 0x03 */ void EcGetMoreRpc(); /*****************/ /* Function 0x04 */ /* we could directly use a NOTIFKEY structure rather than a uint8 array, but this makes the IDL more robust sockaddr array is made of: - family (unsigned short in) sa_family_t - address data sa_data[14]; */ typedef struct { uint16 cb; uint8 ab[cb]; } NOTIFKEY; MAPISTATUS EcRRegisterPushNotification( [in,out] policy_handle *handle, [in] uint32 iRpc, [in,size_is(cbContext)] uint8 rgbContext[*], [in] uint16 cbContext, [in] uint32 grbitAdviseBits, [in,size_is(cbCallbackAddress)] uint8 rgbCallbackAddress[*], [in] uint16 cbCallbackAddress, [out,ref] uint32 *hNotification ); /*****************/ /* Function 0x05 */ MAPISTATUS EcRUnregisterPushNotification( [in,out] policy_handle *handle, [in] uint32 unknown[2] ); /*****************/ /* Function 0x06 */ void EcDummyRpc(); /*****************/ /* Function 0x07 */ void EcRGetDCName(); /*****************/ /* Function 0x08 */ void EcRNetGetDCName(); /*****************/ /* Function 0x09 */ [public,noprint] MAPISTATUS EcDoRpcExt ( [in,out] policy_handle *handle, [in,out] uint32 *pulFlags, [in, size_is(cbIn)] uint8 rgbIn[], [in] uint32 cbIn, [out, length_is(*pcbOut), size_is(*pcbOut)] uint8 rgbOut[], [in,out][range(0x0,0x40000)] uint32 *pcbOut, [in,out,length_is(*Reserved1),size_is(*Reserved1)] uint8 Reserved0[], [in,out] uint32 *Reserved1, [out] uint32 *pulTransTime ); /*****************/ /* Function 0xa */ typedef [public,bitmap16bit] bitmap { RHEF_Compressed = 0x0001, RHEF_XorMagic = 0x0002, RHEF_Last = 0x0004 } RPC_HEADER_EXT_Flags; typedef [public] struct { uint16 Version; RPC_HEADER_EXT_Flags Flags; uint16 Size; uint16 SizeActual; } RPC_HEADER_EXT; typedef [enum8bit,flag(NDR_PAHEX)] enum { AUX_TYPE_PERF_REQUESTID = 0x01, AUX_TYPE_PERF_CLIENTDINFO = 0x02, AUX_TYPE_PERF_SERVERINFO = 0x03, AUX_TYPE_PERF_SESSIONINFO = 0x04, AUX_TYPE_PERF_DEFMDB_SUCCESS = 0x05, AUX_TYPE_PERF_DEFGC_SUCCESS = 0x06, AUX_TYPE_PERF_MDB_SUCCESS = 0x07, AUX_TYPE_PERF_GC_SUCCESS = 0x08, AUX_TYPE_PERF_FAILURE = 0x09, AUX_TYPE_CLIENT_CONTROL = 0x0A, AUX_TYPE_PERF_PROCESSINFO = 0x0B, AUX_TYPE_PERF_BG_DEFMDB_SUCCESS = 0x0C, AUX_TYPE_PERF_BG_DEFGC_SUCCESS = 0x0D, AUX_TYPE_PERF_BG_MDB_SUCCESS = 0x0E, AUX_TYPE_PERF_BG_GC_SUCCESS = 0x0F, AUX_TYPE_PERF_BG_FAILURE = 0x10, AUX_TYPE_PERF_FG_DEFMDB_SUCCESS = 0x11, AUX_TYPE_PERF_FG_DEFGC_SUCCESS = 0x12, AUX_TYPE_PERF_FG_MDB_SUCCESS = 0x13, AUX_TYPE_PERF_FG_GC_SUCCESS = 0x14, AUX_TYPE_PERF_FG_FAILURE = 0x15, AUX_TYPE_OSVERSIONINFO = 0x16, AUX_TYPE_EXORGINFO = 0x17 } AUX_HEADER_TYPE_1; typedef [enum8bit,flag(NDR_PAHEX)] enum { AUX_TYPE_PERF_SESSIONINFO_2 = 0x04, AUX_TYPE_PERF_MDB_SUCCESS_2 = 0x07, AUX_TYPE_PERF_GC_SUCCESS_2 = 0x08, AUX_TYPE_PERF_FAILURE_2 = 0x09 } AUX_HEADER_TYPE_2; typedef [public,enum8bit,flag(NDR_PAHEX)] enum { AUX_VERSION_1 = 0x1, AUX_VERSION_2 = 0x2 } AUX_VERSION; typedef [public,switch_type(uint8)] union { [case(AUX_VERSION_1)] AUX_HEADER_TYPE_1 Type; [case(AUX_VERSION_2)] AUX_HEADER_TYPE_2 Type_2; [default]; } AUX_HEADER_TYPE_ENUM; /*************************/ /* AUX_HEADER case (0x1) */ typedef [flag(NDR_NOALIGN)] struct { uint16 SessionID; uint16 RequestID; } AUX_PERF_REQUESTID; /*************************/ /* AUX_HEADER case (0x2) */ typedef [public,enum16bit, flag(NDR_PAHEX)] enum { CLIENTMODE_UNKNOWN = 0x0, CLIENTMODE_CLASSIC = 0x1, CLIENTMODE_CACHED = 0x2 } ClientMode; typedef [public,flag(NDR_NOALIGN)] struct { uint32 AdapterSpeed; uint16 ClientID; uint16 MachineNameOffset; uint16 UserNameOffset; uint16 ClientIPSize; uint16 ClientIPOffset; uint16 ClientIPMaskSize; uint16 ClientIPMaskOffset; uint16 AdapterNameOffset; uint16 MacAddressSize; uint16 MacAddressOffset; ClientMode ClientMode; uint16 Reserved; uint8 MacAddress[MacAddressSize]; uint8 ClientIP[ClientIPSize]; uint8 ClientIPMask[ClientIPMaskSize]; nstring MachineName; nstring UserName; nstring AdapterName; } AUX_PERF_CLIENTINFO; /*************************/ /* AUX_HEADER case (0x3) */ typedef [enum16bit,flag(NDR_PAHEX)] enum { SERVERTYPE_UNKNOWN = 0x0, SERVERTYPE_PRIVATE = 0x1, SERVERTYPE_PUBLIC = 0x2, SERVERTYPE_DIRECTORY = 0x3, SERVERTYPE_REFERRAL = 0x4 } SERVERINFO_ServerType; typedef [flag(NDR_NOALIGN)] struct { uint16 ServerID; SERVERINFO_ServerType ServerType; uint16 ServerDNOffset; uint16 ServerNameOffset; nstring ServerDN; nstring ServerName; } AUX_PERF_SERVERINFO; /*************************/ /* AUX_HEADER case (0x4) */ typedef [flag(NDR_NOALIGN)] struct { uint16 SessionID; uint16 Reserved; GUID SessionGuid; } AUX_PERF_SESSIONINFO; typedef [flag(NDR_NOALIGN)] struct { uint16 SessionID; uint16 Reserved; GUID SessionGuid; uint32 ConnectionID; } AUX_PERF_SESSIONINFO_V2; /**************************/ /* AUX_HEADER case (0x5) */ /* AUX_HEADER case (0xC) */ /* AUX_HEADER case (0x11) */ typedef [flag(NDR_NOALIGN)] struct { uint32 TimeSinceRequest; uint32 TimeToCompleteRequest; uint16 RequestID; uint16 Reserved; } AUX_PERF_DEFMDB_SUCCESS; /**************************/ /* AUX_HEADER case (0x6) */ /* AUX_HEADER case (0xD) */ typedef [flag(NDR_NOALIGN)] struct { uint16 ServerID; uint16 SessionID; uint32 TimeSinceRequest; uint32 TimeToCompleteRequest; uint8 RequestOperation; uint8 Reserved[3]; } AUX_PERF_DEFGC_SUCCESS; /**************************/ /* AUX_HEADER case (0x7) */ /* AUX_HEADER case (0xE) */ /* AUX_HEADER case (0x13) */ typedef [flag(NDR_NOALIGN)] struct { uint16 ClientID; uint16 ServerID; uint16 SessionID; uint16 RequestID; uint32 TimeSinceRequest; uint32 TimeToCompleteRequest; } AUX_PERF_MDB_SUCCESS; typedef [flag(NDR_NOALIGN)] struct { uint16 ProcessID; uint16 ClientID; uint16 ServerID; uint16 SessionID; uint16 RequestID; uint16 Reserved; uint32 TimeSinceRequest; uint32 TimeToCompleteRequest; } AUX_PERF_MDB_SUCCESS_V2; /**************************/ /* AUX_HEADER case (0x8) */ typedef [flag(NDR_NOALIGN)] struct { uint16 ClientID; uint16 ServerID; uint16 SessionID; uint16 Reserved_1; uint32 TimeSinceRequest; uint32 TimeToCompleteRequest; uint8 RequestOperation; uint8 Reserved_2[3]; } AUX_PERF_GC_SUCCESS; typedef [flag(NDR_NOALIGN)] struct { uint16 ProcessID; uint16 ClientID; uint16 ServerID; uint16 SessionID; uint32 TimeSinceRequest; uint32 TimeToCompleteRequest; uint8 RequestOperation; uint8 Reserved[3]; } AUX_PERF_GC_SUCCESS_V2; /**************************/ /* AUX_HEADER case (0x9) */ typedef [flag(NDR_NOALIGN)] struct { uint16 ClientID; uint16 ServerID; uint16 SessionID; uint16 RequestID; uint32 TimeSinceRequest; uint32 TimeToFailRequest; MAPISTATUS ResultCode; uint8 RequestOperation; uint8 Reserved[3]; } AUX_PERF_FAILURE; typedef [flag(NDR_NOALIGN)] struct { uint16 ProcessID; uint16 ClientID; uint16 ServerID; uint16 SessionID; uint16 RequestID; uint16 Reserved_1; uint32 TimeSinceRequest; uint32 TimeToFailRequest; MAPISTATUS ResultCode; uint8 RequestOperation; uint8 Reserved_2[3]; } AUX_PERF_FAILURE_V2; /**************************/ /* AUX_HEADER case (0xA) */ typedef [bitmap32bit] bitmap { ENABLE_PERF_SENDTOSERVER = 0x00000001, ENABLE_PERF_SENDTOMAILBOX = 0x00000002, ENABLE_COMPRESSION = 0x00000004, ENABLE_HTTP_TUNNELING = 0x00000008, ENABLE_PERF_SENDGCDATA = 0x00000010 } CLIENT_CONTROL_EnableFlags; typedef [flag(NDR_NOALIGN)] struct { CLIENT_CONTROL_EnableFlags EnableFlags; uint32 ExpiryTime; } AUX_CLIENT_CONTROL; /*************************/ /* AUX_HEADER case (0xB) */ typedef [nodiscriminant] union { [case(0x0)]; [default] nstring ProcessName; } ProcessNameString; typedef [flag(NDR_NOALIGN)] struct { uint16 ProcessID; uint16 Reserved1; GUID ProcessGuid; uint16 ProcessNameOffset; uint16 Reserved2; [switch_is(ProcessNameOffset)] ProcessNameString ProcessName; } AUX_PERF_PROCESSINFO; /**************************/ /* AUX_HEADER case (0x16) */ typedef [flag(NDR_NOALIGN)] struct { uint32 OSVersionInfoSize; uint32 MajorVersion; uint32 MinorVersion; uint32 BuildNumber; [subcontext(0), subcontext_size(132), flag(NDR_REMAINING|NDR_NOALIGN)] DATA_BLOB Reserved_1; uint16 ServicePackMajor; uint16 ServicePackMinor; uint32 Reserved_2; } AUX_OSVERSIONINFO; /**************************/ /* AUX_HEADER case (0x17) */ typedef [bitmap32bit] bitmap { PUBLIC_FOLDERS_ENABLED = 0x00000001 } EXORGINFO_OrgFlags; typedef [flag(NDR_NOALIGN)] struct { EXORGINFO_OrgFlags OrgFlags; } AUX_EXORGINFO; typedef [public,nodiscriminant,flag(NDR_NOALIGN)] union { [case(AUX_TYPE_PERF_REQUESTID)] AUX_PERF_REQUESTID AUX_PERF_REQUESTID; // [case(AUX_TYPE_PERF_CLIENTDINFO)] AUX_PERF_CLIENTINFO AUX_PERF_CLIENTINFO; [case(AUX_TYPE_PERF_SERVERINFO)] AUX_PERF_SERVERINFO AUX_PERF_SERVERINFO; [case(AUX_TYPE_PERF_SESSIONINFO)] AUX_PERF_SESSIONINFO AUX_PERF_SESSIONINFO; [case(AUX_TYPE_PERF_DEFMDB_SUCCESS)] AUX_PERF_DEFMDB_SUCCESS AUX_PERF_DEFMDB_SUCCESS; [case(AUX_TYPE_PERF_DEFGC_SUCCESS)] AUX_PERF_DEFGC_SUCCESS AUX_PERF_DEFGC_SUCCESS; [case(AUX_TYPE_PERF_MDB_SUCCESS)] AUX_PERF_MDB_SUCCESS AUX_PERF_MDB_SUCCESS; [case(AUX_TYPE_PERF_GC_SUCCESS)] AUX_PERF_GC_SUCCESS AUX_PERF_GC_SUCCESS; [case(AUX_TYPE_PERF_FAILURE)] AUX_PERF_FAILURE AUX_PERF_FAILURE; [case(AUX_TYPE_CLIENT_CONTROL)] AUX_CLIENT_CONTROL AUX_CLIENT_CONTROL; [case(AUX_TYPE_PERF_PROCESSINFO)] AUX_PERF_PROCESSINFO AUX_PERF_PROCESSINFO; [case(AUX_TYPE_PERF_BG_DEFMDB_SUCCESS)] AUX_PERF_DEFMDB_SUCCESS AUX_PERF_DEFMDB_SUCCESS; [case(AUX_TYPE_PERF_BG_DEFGC_SUCCESS)] AUX_PERF_DEFGC_SUCCESS AUX_PERF_DEFGC_SUCCESS; [case(AUX_TYPE_PERF_BG_MDB_SUCCESS)] AUX_PERF_MDB_SUCCESS AUX_PERF_MDB_SUCCESS; [case(AUX_TYPE_PERF_BG_GC_SUCCESS)] AUX_PERF_GC_SUCCESS AUX_PERF_GC_SUCCESS; [case(AUX_TYPE_PERF_BG_FAILURE)] AUX_PERF_FAILURE AUX_PERF_FAILURE; [case(AUX_TYPE_PERF_FG_DEFMDB_SUCCESS)] AUX_PERF_DEFMDB_SUCCESS AUX_PERF_DEFMDB_SUCCESS; [case(AUX_TYPE_PERF_FG_DEFGC_SUCCESS)] AUX_PERF_DEFGC_SUCCESS AUX_PERF_DEFGC_SUCCESS; [case(AUX_TYPE_PERF_FG_MDB_SUCCESS)] AUX_PERF_MDB_SUCCESS AUX_PERF_MDB_SUCCESS; [case(AUX_TYPE_PERF_FG_GC_SUCCESS)] AUX_PERF_GC_SUCCESS AUX_PERG_GC_SUCCESS; [case(AUX_TYPE_PERF_FG_FAILURE)] AUX_PERF_FAILURE AUX_PERF_FAILURE; [case(AUX_TYPE_OSVERSIONINFO)] AUX_OSVERSIONINFO AUX_OSVERSIONINFO; [case(AUX_TYPE_EXORGINFO)] AUX_EXORGINFO AUX_EXORGINFO; [default][flag(NDR_REMAINING|NDR_NOALIGN)] DATA_BLOB Payload; } AUX_HEADER_TYPE_UNION_1; typedef [public,nodiscriminant,flag(NDR_NOALIGN)] union { [case(AUX_TYPE_PERF_REQUESTID)] AUX_PERF_REQUESTID AUX_PERF_REQUESTID; // [case(AUX_TYPE_PERF_CLIENTDINFO)] AUX_PERF_CLIENTINFO AUX_PERF_CLIENTINFO; [case(AUX_TYPE_PERF_SERVERINFO)] AUX_PERF_SERVERINFO AUX_PERF_SERVERINFO; [case(AUX_TYPE_PERF_SESSIONINFO_2)] AUX_PERF_SESSIONINFO_V2 AUX_PERF_SESSIONINFO_V2; /* V2 specific */ [case(AUX_TYPE_PERF_DEFMDB_SUCCESS)] AUX_PERF_DEFMDB_SUCCESS AUX_PERF_DEFMDB_SUCCESS; [case(AUX_TYPE_PERF_DEFGC_SUCCESS)] AUX_PERF_DEFGC_SUCCESS AUX_PERF_DEFGC_SUCCESS; [case(AUX_TYPE_PERF_MDB_SUCCESS_2)] AUX_PERF_MDB_SUCCESS_V2 AUX_PERF_MDB_SUCCESS_V2; /* V2 specific */ [case(AUX_TYPE_PERF_GC_SUCCESS_2)] AUX_PERF_GC_SUCCESS_V2 AUX_PERF_GC_SUCCESS_V2; /* V2 specific */ [case(AUX_TYPE_PERF_FAILURE_2)] AUX_PERF_FAILURE_V2 AUX_PERF_FAILURE_V2; /* V2 specific*/ [case(AUX_TYPE_CLIENT_CONTROL)] AUX_CLIENT_CONTROL AUX_CLIENT_CONTROL; [case(AUX_TYPE_PERF_PROCESSINFO)] AUX_PERF_PROCESSINFO AUX_PERF_PROCESSINFO; [case(AUX_TYPE_PERF_BG_DEFMDB_SUCCESS)] AUX_PERF_DEFMDB_SUCCESS AUX_PERF_DEFMDB_SUCCESS; [case(AUX_TYPE_PERF_BG_DEFGC_SUCCESS)] AUX_PERF_DEFGC_SUCCESS AUX_PERF_DEFGC_SUCCESS; [case(AUX_TYPE_PERF_BG_MDB_SUCCESS)] AUX_PERF_MDB_SUCCESS AUX_PERF_MDB_SUCCESS; [case(AUX_TYPE_PERF_BG_GC_SUCCESS)] AUX_PERF_GC_SUCCESS AUX_PERF_GC_SUCCESS; [case(AUX_TYPE_PERF_BG_FAILURE)] AUX_PERF_FAILURE AUX_PERF_FAILURE; [case(AUX_TYPE_PERF_FG_DEFMDB_SUCCESS)] AUX_PERF_DEFMDB_SUCCESS AUX_PERF_DEFMDB_SUCCESS; [case(AUX_TYPE_PERF_FG_DEFGC_SUCCESS)] AUX_PERF_DEFGC_SUCCESS AUX_PERF_DEFGC_SUCCESS; [case(AUX_TYPE_PERF_FG_MDB_SUCCESS)] AUX_PERF_MDB_SUCCESS AUX_PERF_MDB_SUCCESS; [case(AUX_TYPE_PERF_FG_GC_SUCCESS)] AUX_PERF_GC_SUCCESS AUX_PERG_GC_SUCCESS; [case(AUX_TYPE_PERF_FG_FAILURE)] AUX_PERF_FAILURE AUX_PERF_FAILURE; [case(AUX_TYPE_OSVERSIONINFO)] AUX_OSVERSIONINFO AUX_OSVERSIONINFO; [case(AUX_TYPE_EXORGINFO)] AUX_EXORGINFO AUX_EXORGINFO; [default][flag(NDR_REMAINING|NDR_NOALIGN)] DATA_BLOB Payload; } AUX_HEADER_TYPE_UNION_2; typedef [public,nopull,noprint,flag(NDR_NOALIGN)] struct { uint16 Size; AUX_VERSION Version; uint8 Type; [switch_is(Type)] AUX_HEADER_TYPE_UNION_1 Payload_1; [switch_is(Type)] AUX_HEADER_TYPE_UNION_2 Payload_2; } AUX_HEADER; typedef [public,nopull,noprint] struct { RPC_HEADER_EXT RPC_HEADER_EXT; [subcontext(0), subcontext_size(RPC_HEADER_EXT.Size)] AUX_HEADER *AUX_HEADER; } mapi2k7_AuxInfo; [public,nopull,nopush,noprint] MAPISTATUS EcDoConnectEx( [out] policy_handle *handle, [in,string,charset(DOS)] uint8 szUserDN[], [in] uint32 ulFlags, [in] uint32 ulConMod, [in] uint32 cbLimit, [in] uint32 ulCpid, [in] uint32 ulLcidString, [in] uint32 ulLcidSort, [in] uint32 ulIcxrLink, [in] uint16 usFCanConvertCodePages, [out] uint32 *pcmsPollsMax, [out] uint32 *pcRetry, [out] uint32 *pcmsRetryDelay, [out] uint32 *picxr, [out,ref,string,charset(DOS)]uint8 **szDNPrefix, [out,ref,string,charset(DOS)]uint8 **szDisplayName, [in] uint16 rgwClientVersion[3], [out] uint16 rgwServerVersion[3], [out] uint16 rgwBestVersion[3], [in,out] uint32 *pulTimeStamp, [in,subcontext(4),flag(NDR_REMAINING|NDR_NOALIGN)] mapi2k7_AuxInfo *rgbAuxIn, [in] uint32 cbAuxIn, [out, length_is(*pcbAuxOut), size_is(*pcbAuxOut)] mapi2k7_AuxInfo *rgbAuxOut, [in,out][range(0,0x1008)] uint32 *pcbAuxOut ); /*****************/ /* Function 0xb */ typedef [public,bitmap32bit] bitmap { pulFlags_NoCompression = 0x00000001, pulFlags_NoXorMagic = 0x00000002, pulFlags_Chain = 0x00000004 } pulFlags; typedef [public,nopull] struct { RPC_HEADER_EXT header; [subcontext(0),flag(NDR_REMAINING|NDR_NOALIGN)] mapi_request *mapi_request; } mapi2k7_request; typedef [public,nopull] struct { RPC_HEADER_EXT header; [subcontext(0),flag(NDR_REMAINING|NDR_NOALIGN)] mapi_response *mapi_response; } mapi2k7_response; [public,noprint] MAPISTATUS EcDoRpcExt2( [in,out] policy_handle *handle, [in,out] uint32 *pulFlags, [in, size_is(cbIn)] uint8 rgbIn[], [in] uint32 cbIn, [out, length_is(*pcbOut), size_is(*pcbOut)] uint8 rgbOut[], [in,out][range(0x0,0x40000)] uint32 *pcbOut, [in, size_is(cbAuxIn)] uint8 rgbAuxIn[], [in] uint32 cbAuxIn, [out, length_is(*pcbAuxOut), size_is(*pcbAuxOut)] uint32 rgbAuxOut[], [in,out][range(0x0,0x1008)] uint32 *pcbAuxOut, [out] uint32 *pulTransTime ); /*****************/ /* Function 0xc */ void EcUnknown0xC(); /*****************/ /* Function 0xd */ void EcUnknown0xD(); /*****************/ /* Function 0xe */ [public] MAPISTATUS EcDoAsyncConnectEx( [in] policy_handle *handle, [out] policy_handle *async_handle ); } [ uuid("5261574a-4572-206e-b268-6b199213b4e4"), pointer_default(unique), endpoint("ncacn_ip_tcp:"), version(0.01) ] interface exchange_async_emsmdb { [public] MAPISTATUS EcDoAsyncWaitEx( [in] policy_handle *async_handle, [in] uint32 ulFlagsIn, [out] uint32 *pulFlagsOut ); } [ uuid("c840a7dc-42c0-1a10-b4b9-08002b2fe182"), pointer_default(unique), helpstring("Unknown") ] interface exchange_unknown { void unknown_dummy(); } openchange-2.0/idl_types.h000066400000000000000000000051721223057412600156360ustar00rootroot00000000000000#define STR_ASCII LIBNDR_FLAG_STR_ASCII #define STR_LEN4 LIBNDR_FLAG_STR_LEN4 #define STR_SIZE4 LIBNDR_FLAG_STR_SIZE4 #define STR_SIZE2 LIBNDR_FLAG_STR_SIZE2 #define STR_NOTERM LIBNDR_FLAG_STR_NOTERM #define STR_NULLTERM LIBNDR_FLAG_STR_NULLTERM #define STR_BYTESIZE LIBNDR_FLAG_STR_BYTESIZE #define STR_FIXLEN32 LIBNDR_FLAG_STR_FIXLEN32 #define STR_FIXLEN15 LIBNDR_FLAG_STR_FIXLEN15 #define STR_CONFORMANT LIBNDR_FLAG_STR_CONFORMANT #define STR_CHARLEN LIBNDR_FLAG_STR_CHARLEN #define STR_UTF8 LIBNDR_FLAG_STR_UTF8 #define STR_RAW8 LIBNDR_FLAG_STR_RAW8 #define STR_LARGE_SIZE LIBNDR_FLAG_STR_LARGE_SIZE /* a UCS2 string prefixed with [size], 32 bits */ #define lstring [flag(STR_SIZE4)] string /* a null terminated UCS2 string */ #define nstring [flag(STR_NULLTERM)] string /* fixed length 32 character UCS-2 string */ #define string32 [flag(STR_FIXLEN32)] string /* fixed length 16 character ascii string */ #define astring15 [flag(STR_ASCII|STR_FIXLEN15)] string /* an ascii string prefixed with [offset] [length], both 32 bits null terminated */ #define ascstr2 [flag(STR_ASCII|STR_LEN4)] string /* an ascii string prefixed with [size], 32 bits */ #define asclstr [flag(STR_ASCII|STR_SIZE4)] string /* an ascii string prefixed with [size], 16 bits null terminated */ #define ascstr3 [flag(STR_ASCII|STR_SIZE2)] string /* an ascii string prefixed with [size] [offset] [length], all 32 bits not null terminated */ #define ascstr_noterm [flag(STR_NOTERM|STR_ASCII|STR_SIZE4|STR_LEN4)] string /* a null terminated ascii string */ #define astring [flag(STR_ASCII|STR_NULLTERM)] string /* a null terminated UTF8 string */ #define utf8string [flag(STR_UTF8|STR_NULLTERM)] string /* a null terminated "raw" string (null terminated byte sequence) */ #define raw8string [flag(STR_RAW8|STR_NULLTERM)] string /* a null terminated UCS2 string */ #define nstring_array [flag(STR_NULLTERM)] string_array #define NDR_NOALIGN LIBNDR_FLAG_NOALIGN #define NDR_REMAINING LIBNDR_FLAG_REMAINING #define NDR_ALIGN2 LIBNDR_FLAG_ALIGN2 #define NDR_ALIGN4 LIBNDR_FLAG_ALIGN4 #define NDR_ALIGN8 LIBNDR_FLAG_ALIGN8 /* this flag is used to force a section of IDL as little endian. It is needed for the epmapper IDL, which is defined as always being LE */ #define NDR_LITTLE_ENDIAN LIBNDR_FLAG_LITTLE_ENDIAN #define NDR_BIG_ENDIAN LIBNDR_FLAG_BIGENDIAN /* these are used by the epmapper and mgmt interfaces */ #define error_status_t uint32 #define boolean32 uint32 #define unsigned32 uint32 /* this is used to control formatting of uint8 arrays */ #define NDR_PAHEX LIBNDR_PRINT_ARRAY_HEX #define bool8 uint8 openchange-2.0/install-sh000066400000000000000000000127361223057412600154760ustar00rootroot00000000000000#!/bin/sh # # install - install a program, script, or datafile # This comes from X11R5 (mit/util/scripts/install.sh). # # Copyright 1991 by the Massachusetts Institute of Technology # # Permission to use, copy, modify, distribute, and sell this software and its # documentation for any purpose is hereby granted without fee, provided that # the above copyright notice appear in all copies and that both that # copyright notice and this permission notice appear in supporting # documentation, and that the name of M.I.T. not be used in advertising or # publicity pertaining to distribution of the software without specific, # written prior permission. M.I.T. makes no representations about the # suitability of this software for any purpose. It is provided "as is" # without express or implied warranty. # # Calling this script install-sh is preferred over install.sh, to prevent # `make' implicit rules from creating a file called install from it # when there is no Makefile. # # This script is compatible with the BSD install script, but was written # from scratch. It can only install one file at a time, a restriction # shared with many OS's install programs. # set DOITPROG to echo to test this script # Don't use :- since 4.3BSD and earlier shells don't like it. doit="${DOITPROG-}" # put in absolute paths if you don't have them in your path; or use env. vars. mvprog="${MVPROG-mv}" cpprog="${CPPROG-cp}" chmodprog="${CHMODPROG-chmod}" chownprog="${CHOWNPROG-chown}" chgrpprog="${CHGRPPROG-chgrp}" stripprog="${STRIPPROG-strip}" rmprog="${RMPROG-rm}" mkdirprog="${MKDIRPROG-mkdir}" transformbasename="" transform_arg="" instcmd="$mvprog" chmodcmd="$chmodprog 0755" chowncmd="" chgrpcmd="" stripcmd="" rmcmd="$rmprog -f" mvcmd="$mvprog" src="" dst="" dir_arg="" while [ x"$1" != x ]; do case $1 in -c) instcmd="$cpprog" shift continue;; -d) dir_arg=true shift continue;; -m) chmodcmd="$chmodprog $2" shift shift continue;; -o) chowncmd="$chownprog $2" shift shift continue;; -g) chgrpcmd="$chgrpprog $2" shift shift continue;; -s) stripcmd="$stripprog" shift continue;; -t=*) transformarg=`echo $1 | sed 's/-t=//'` shift continue;; -b=*) transformbasename=`echo $1 | sed 's/-b=//'` shift continue;; *) if [ x"$src" = x ] then src=$1 else # this colon is to work around a 386BSD /bin/sh bug : dst=$1 fi shift continue;; esac done if [ x"$src" = x ] then echo "install: no input file specified" exit 1 else true fi if [ x"$dir_arg" != x ]; then dst=$src src="" if [ -d $dst ]; then instcmd=: chmodcmd="" else instcmd=mkdir fi else # Waiting for this to be detected by the "$instcmd $src $dsttmp" command # might cause directories to be created, which would be especially bad # if $src (and thus $dsttmp) contains '*'. if [ -f $src -o -d $src ] then true else echo "install: $src does not exist" exit 1 fi if [ x"$dst" = x ] then echo "install: no destination specified" exit 1 else true fi # If destination is a directory, append the input filename; if your system # does not like double slashes in filenames, you may need to add some logic if [ -d $dst ] then dst="$dst"/`basename $src` else true fi fi ## this sed command emulates the dirname command dstdir=`echo $dst | sed -e 's,[^/]*$,,;s,/$,,;s,^$,.,'` # Make sure that the destination directory exists. # this part is taken from Noah Friedman's mkinstalldirs script # Skip lots of stat calls in the usual case. if [ ! -d "$dstdir" ]; then defaultIFS=' ' IFS="${IFS-${defaultIFS}}" oIFS="${IFS}" # Some sh's can't handle IFS=/ for some reason. IFS='%' set - `echo ${dstdir} | sed -e 's@/@%@g' -e 's@^%@/@'` IFS="${oIFS}" pathcomp='' while [ $# -ne 0 ] ; do pathcomp="${pathcomp}${1}" shift if [ ! -d "${pathcomp}" ] ; then $mkdirprog "${pathcomp}" else true fi pathcomp="${pathcomp}/" done fi if [ x"$dir_arg" != x ] then $doit $instcmd $dst && if [ x"$chowncmd" != x ]; then $doit $chowncmd $dst; else true ; fi && if [ x"$chgrpcmd" != x ]; then $doit $chgrpcmd $dst; else true ; fi && if [ x"$stripcmd" != x ]; then $doit $stripcmd $dst; else true ; fi && if [ x"$chmodcmd" != x ]; then $doit $chmodcmd $dst; else true ; fi else # If we're going to rename the final executable, determine the name now. if [ x"$transformarg" = x ] then dstfile=`basename $dst` else dstfile=`basename $dst $transformbasename | sed $transformarg`$transformbasename fi # don't allow the sed command to completely eliminate the filename if [ x"$dstfile" = x ] then dstfile=`basename $dst` else true fi # Make a temp file name in the proper directory. dsttmp=$dstdir/#inst.$$# # Move or copy the file name to the temp name $doit $instcmd $src $dsttmp && trap "rm -f ${dsttmp}" 0 && # and set any options; do chmod last to preserve setuid bits # If any of these fail, we abort the whole thing. If we want to # ignore errors from any of these, just make sure not to ignore # errors from the above "$doit $instcmd $src $dsttmp" command. if [ x"$chowncmd" != x ]; then $doit $chowncmd $dsttmp; else true;fi && if [ x"$chgrpcmd" != x ]; then $doit $chgrpcmd $dsttmp; else true;fi && if [ x"$stripcmd" != x ]; then $doit $stripcmd $dsttmp; else true;fi && if [ x"$chmodcmd" != x ]; then $doit $chmodcmd $dsttmp; else true;fi && # Now rename the file to the real destination. $doit $rmcmd -f $dstdir/$dstfile && $doit $mvcmd $dsttmp $dstdir/$dstfile fi && exit 0 openchange-2.0/libexchange2ical/000077500000000000000000000000001223057412600166505ustar00rootroot00000000000000openchange-2.0/libexchange2ical/exchange2ical.c000066400000000000000000000731341223057412600215210ustar00rootroot00000000000000/* Common conversion routines for exchange2ical OpenChange Project Copyright (C) Julien Kerihuel 2008 This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see . */ #include "libexchange2ical/libexchange2ical.h" static void exchange2ical_init(TALLOC_CTX *mem_ctx, struct exchange2ical *exchange2ical) { exchange2ical->TimeZoneStruct = NULL; exchange2ical->TimeZoneDesc = NULL; exchange2ical->method = ICAL_METHOD_NONE; exchange2ical->vtimezone = NULL; exchange2ical->vcalendar = NULL; exchange2ical->mem_ctx = mem_ctx; exchange2ical->partstat = ICAL_PARTSTAT_NONE; exchange2ical->ResponseStatus = NULL; exchange2ical->Recurring = NULL; exchange2ical->RecurrencePattern = NULL; exchange2ical->AppointmentRecurrencePattern = NULL; exchange2ical->Keywords = NULL; exchange2ical->Contacts = NULL; exchange2ical->apptStateFlags = NULL; exchange2ical->sensitivity = NULL; exchange2ical->apptStartWhole = NULL; exchange2ical->apptEndWhole = NULL; exchange2ical->apptSubType = NULL; exchange2ical->OwnerCriticalChange = NULL; exchange2ical->body = NULL; exchange2ical->LastModified = NULL; exchange2ical->Location = NULL; exchange2ical->Importance = NULL; exchange2ical->ExceptionReplaceTime = NULL; exchange2ical->ResponseRequested = NULL; exchange2ical->NonSendableBcc = NULL; exchange2ical->Sequence = NULL; exchange2ical->Subject = NULL; exchange2ical->MessageLocaleId = NULL; exchange2ical->BusyStatus = NULL; exchange2ical->IntendedBusyStatus = NULL; exchange2ical->GlobalObjectId = NULL; exchange2ical->AttendeeCriticalChange = NULL; exchange2ical->OwnerApptId = NULL; exchange2ical->apptReplyTime = NULL; exchange2ical->NotAllowPropose = NULL; exchange2ical->AllowExternCheck = NULL; exchange2ical->apptLastSequence = NULL; exchange2ical->apptSeqTime = NULL; exchange2ical->AutoFillLocation = NULL; exchange2ical->AutoStartCheck = NULL; exchange2ical->CollaborateDoc = NULL; exchange2ical->ConfCheck = NULL; exchange2ical->ConfType = NULL; exchange2ical->Directory = NULL; exchange2ical->MWSURL = NULL; exchange2ical->NetShowURL = NULL; exchange2ical->OnlinePassword = NULL; exchange2ical->OrgAlias = NULL; exchange2ical->SenderName = NULL; exchange2ical->SenderEmailAddress = NULL; exchange2ical->ReminderSet = NULL; exchange2ical->ReminderDelta = NULL; exchange2ical->vevent = NULL; exchange2ical->valarm = NULL; exchange2ical->bodyHTML = NULL; exchange2ical->idx=0; } static void exchange2ical_clear(struct exchange2ical *exchange2ical) { if (exchange2ical->AppointmentRecurrencePattern){ talloc_free(exchange2ical->AppointmentRecurrencePattern); } if (exchange2ical->TimeZoneStruct) { talloc_free(exchange2ical->TimeZoneStruct); } exchange2ical_init(exchange2ical->mem_ctx, exchange2ical); } static void exchange2ical_reset(struct exchange2ical *exchange2ical) { if (exchange2ical->AppointmentRecurrencePattern){ talloc_free(exchange2ical->AppointmentRecurrencePattern); } if (exchange2ical->TimeZoneStruct) { talloc_free(exchange2ical->TimeZoneStruct); } exchange2ical->partstat = ICAL_PARTSTAT_NONE; exchange2ical->ResponseStatus = NULL; exchange2ical->Recurring = NULL; exchange2ical->RecurrencePattern = NULL; exchange2ical->AppointmentRecurrencePattern = NULL; exchange2ical->Keywords = NULL; exchange2ical->Contacts = NULL; exchange2ical->apptStateFlags = NULL; exchange2ical->sensitivity = NULL; exchange2ical->apptStartWhole = NULL; exchange2ical->apptEndWhole = NULL; exchange2ical->apptSubType = NULL; exchange2ical->OwnerCriticalChange = NULL; exchange2ical->body = NULL; exchange2ical->LastModified = NULL; exchange2ical->Location = NULL; exchange2ical->Importance = NULL; exchange2ical->ExceptionReplaceTime = NULL; exchange2ical->ResponseRequested = NULL; exchange2ical->NonSendableBcc = NULL; exchange2ical->Sequence = NULL; exchange2ical->Subject = NULL; exchange2ical->MessageLocaleId = NULL; exchange2ical->BusyStatus = NULL; exchange2ical->IntendedBusyStatus = NULL; exchange2ical->GlobalObjectId = NULL; exchange2ical->AttendeeCriticalChange = NULL; exchange2ical->OwnerApptId = NULL; exchange2ical->apptReplyTime = NULL; exchange2ical->NotAllowPropose = NULL; exchange2ical->AllowExternCheck = NULL; exchange2ical->apptLastSequence = NULL; exchange2ical->apptSeqTime = NULL; exchange2ical->AutoFillLocation = NULL; exchange2ical->AutoStartCheck = NULL; exchange2ical->CollaborateDoc = NULL; exchange2ical->ConfCheck = NULL; exchange2ical->ConfType = NULL; exchange2ical->Directory = NULL; exchange2ical->MWSURL = NULL; exchange2ical->NetShowURL = NULL; exchange2ical->OnlinePassword = NULL; exchange2ical->OrgAlias = NULL; exchange2ical->SenderName = NULL; exchange2ical->SenderEmailAddress = NULL; exchange2ical->ReminderSet = NULL; exchange2ical->ReminderDelta = NULL; exchange2ical->vevent = NULL; exchange2ical->valarm = NULL; exchange2ical->bodyHTML = NULL; exchange2ical->TimeZoneDesc = NULL; exchange2ical->TimeZoneStruct = NULL; } static int exchange2ical_get_properties(TALLOC_CTX *mem_ctx, struct SRow *aRow, struct exchange2ical *exchange2ical, enum exchange2ical_flags eFlags) { struct Binary_r *apptrecur; const char *messageClass; struct Binary_r *TimeZoneStruct; if(eFlags & VcalFlag){ messageClass = octool_get_propval(aRow, PR_MESSAGE_CLASS_UNICODE); exchange2ical->method = get_ical_method(messageClass); if (!exchange2ical->method) return -1; } if(((eFlags & RangeFlag) && !(eFlags & EntireFlag))|| (!(eFlags & RangeFlag) && (eFlags & EntireFlag))){ exchange2ical->apptStartWhole = (const struct FILETIME *)octool_get_propval(aRow, PidLidAppointmentStartWhole); } if(((eFlags & EventFlag) && !(eFlags & EntireFlag))|| (!(eFlags & EventFlag) && (eFlags & EntireFlag))){ exchange2ical->GlobalObjectId = (struct Binary_r *) octool_get_propval(aRow, PidLidGlobalObjectId); exchange2ical->Sequence = (uint32_t *) octool_get_propval(aRow, PidLidAppointmentSequence); } if(((eFlags & EventsFlag) && !(eFlags & EntireFlag))|| (!(eFlags & EventsFlag) && (eFlags & EntireFlag))){ exchange2ical->GlobalObjectId = (struct Binary_r *) octool_get_propval(aRow, PidLidGlobalObjectId); } if(eFlags & EntireFlag) { apptrecur = (struct Binary_r *) octool_get_propval(aRow, PidLidAppointmentRecur); exchange2ical->AppointmentRecurrencePattern = get_AppointmentRecurrencePattern(mem_ctx,apptrecur); exchange2ical->RecurrencePattern = &exchange2ical->AppointmentRecurrencePattern->RecurrencePattern; TimeZoneStruct = (struct Binary_r *) octool_get_propval(aRow, PidLidTimeZoneStruct); exchange2ical->TimeZoneStruct = get_TimeZoneStruct(mem_ctx, TimeZoneStruct); exchange2ical->TimeZoneDesc = (const char *) octool_get_propval(aRow, PidLidTimeZoneDescription); exchange2ical->Keywords = (const struct StringArray_r *) octool_get_propval(aRow, PidNameKeywords); exchange2ical->Recurring = (uint8_t *) octool_get_propval(aRow, PidLidRecurring); exchange2ical->TimeZoneDesc = (const char *) octool_get_propval(aRow, PidLidTimeZoneDescription); exchange2ical->ExceptionReplaceTime = (const struct FILETIME *)octool_get_propval(aRow, PidLidExceptionReplaceTime); exchange2ical->ResponseStatus = (uint32_t *) octool_get_propval(aRow, PidLidResponseStatus); exchange2ical->apptStateFlags = (uint32_t *) octool_get_propval(aRow, PidLidAppointmentStateFlags); exchange2ical->Contacts = (const struct StringArray_r *)octool_get_propval(aRow, PidLidContacts); exchange2ical->apptEndWhole = (const struct FILETIME *)octool_get_propval(aRow, PidLidAppointmentEndWhole); exchange2ical->apptSubType = (uint8_t *) octool_get_propval(aRow, PidLidAppointmentSubType); exchange2ical->OwnerCriticalChange = (const struct FILETIME *)octool_get_propval(aRow, PidLidOwnerCriticalChange); exchange2ical->Location = (const char *) octool_get_propval(aRow, PidLidLocation); exchange2ical->NonSendableBcc = (const char *) octool_get_propval(aRow, PidLidNonSendableBcc); exchange2ical->BusyStatus = (uint32_t *) octool_get_propval(aRow, PidLidBusyStatus); exchange2ical->IntendedBusyStatus = (uint32_t *) octool_get_propval(aRow, PidLidIntendedBusyStatus); exchange2ical->AttendeeCriticalChange = (const struct FILETIME *) octool_get_propval(aRow, PidLidAttendeeCriticalChange); exchange2ical->apptReplyTime = (const struct FILETIME *)octool_get_propval(aRow, PidLidAppointmentReplyTime); exchange2ical->NotAllowPropose = (uint8_t *) octool_get_propval(aRow, PidLidAppointmentNotAllowPropose); exchange2ical->AllowExternCheck = (uint8_t *) octool_get_propval(aRow, PidLidAllowExternalCheck); exchange2ical->apptLastSequence = (uint32_t *) octool_get_propval(aRow, PidLidAppointmentLastSequence); exchange2ical->apptSeqTime = (const struct FILETIME *)octool_get_propval(aRow, PidLidAppointmentSequenceTime); exchange2ical->AutoFillLocation = (uint8_t *) octool_get_propval(aRow, PidLidAutoFillLocation); exchange2ical->AutoStartCheck = (uint8_t *) octool_get_propval(aRow, PidLidAutoStartCheck); exchange2ical->CollaborateDoc = (const char *) octool_get_propval(aRow, PidLidCollaborateDoc); exchange2ical->ConfCheck = (uint8_t *) octool_get_propval(aRow, PidLidConferencingCheck); exchange2ical->ConfType = (uint32_t *) octool_get_propval(aRow, PidLidConferencingType); exchange2ical->Directory = (const char *) octool_get_propval(aRow, PidLidDirectory); exchange2ical->MWSURL = (const char *) octool_get_propval(aRow, PidLidMeetingWorkspaceUrl); exchange2ical->NetShowURL = (const char *) octool_get_propval(aRow, PidLidNetShowUrl); exchange2ical->OnlinePassword = (const char *) octool_get_propval(aRow, PidLidOnlinePassword); exchange2ical->OrgAlias = (const char *) octool_get_propval(aRow, PidLidOrganizerAlias); exchange2ical->ReminderSet = (uint8_t *) octool_get_propval(aRow, PidLidReminderSet); exchange2ical->ReminderDelta = (uint32_t *) octool_get_propval(aRow, PidLidReminderDelta); exchange2ical->sensitivity = (uint32_t *) octool_get_propval(aRow, PR_SENSITIVITY); exchange2ical->created = (const struct FILETIME *)octool_get_propval(aRow, PR_CREATION_TIME); exchange2ical->body = (const char *)octool_get_propval(aRow, PR_BODY_UNICODE); exchange2ical->LastModified = (const struct FILETIME *)octool_get_propval(aRow, PR_LAST_MODIFICATION_TIME); exchange2ical->Importance = (uint32_t *) octool_get_propval(aRow, PR_IMPORTANCE); exchange2ical->ResponseRequested = (uint8_t *) octool_get_propval(aRow, PR_RESPONSE_REQUESTED); exchange2ical->Subject = (const char *) octool_get_propval(aRow, PR_SUBJECT_UNICODE); exchange2ical->MessageLocaleId = (uint32_t *) octool_get_propval(aRow, PR_MESSAGE_LOCALE_ID); exchange2ical->OwnerApptId = (uint32_t *) octool_get_propval(aRow, PR_OWNER_APPT_ID); exchange2ical->SenderName = (const char *) octool_get_propval(aRow, PR_SENDER_NAME); exchange2ical->SenderEmailAddress = (const char *) octool_get_propval(aRow, PR_SENDER_EMAIL_ADDRESS); } return 0; } static uint8_t exchange2ical_exception_from_ExceptionInfo(struct exchange2ical *exchange2ical, struct exchange2ical_check *exchange2ical_check) { uint32_t i; icalproperty *prop; icalparameter *param; icaltimetype icaltime; /*sanity checks*/ if(!exchange2ical->AppointmentRecurrencePattern) return 1; if(!exchange2ical->AppointmentRecurrencePattern->ExceptionInfo) return 1; if(!exchange2ical->AppointmentRecurrencePattern->ExceptionCount) return 1; for(i=0; iAppointmentRecurrencePattern->ExceptionCount; i++) { /*Check to see if event is acceptable*/ struct tm apptStart=get_tm_from_minutes_UTC(exchange2ical->AppointmentRecurrencePattern->ExceptionInfo->StartDateTime); if (!checkEvent(exchange2ical, exchange2ical_check, &apptStart)){ return 0; } /*Create a new vevent*/ exchange2ical->vevent = icalcomponent_new_vevent(); if ( ! (exchange2ical->vevent) ) { return 1; } icalcomponent_add_component(exchange2ical->vcalendar, exchange2ical->vevent); /*dtstart from StartDateTime*/ if (exchange2ical->apptSubType && (*exchange2ical->apptSubType == 0x1)) { struct tm tm; tm = get_tm_from_minutes_UTC(exchange2ical->AppointmentRecurrencePattern->ExceptionInfo->StartDateTime); icaltime= get_icaldate_from_tm(&tm); prop = icalproperty_new_dtstart(icaltime); icalcomponent_add_property(exchange2ical->vevent, prop); }else { if(exchange2ical->TimeZoneDesc){ struct tm tm; tm = get_tm_from_minutes(exchange2ical->AppointmentRecurrencePattern->ExceptionInfo->StartDateTime); icaltime= get_icaldate_from_tm(&tm); prop = icalproperty_new_dtstart(icaltime); icalcomponent_add_property(exchange2ical->vevent, prop); param = icalparameter_new_tzid(exchange2ical->TimeZoneDesc); icalproperty_add_parameter(prop, param); } else { struct tm tm; tm = get_tm_from_minutes_UTC(exchange2ical->AppointmentRecurrencePattern->ExceptionInfo->StartDateTime); icaltime= get_icaldate_from_tm(&tm); prop = icalproperty_new_dtstart(icaltime); icalcomponent_add_property(exchange2ical->vevent, prop); } } /*dtend from EndDateTime*/ if (exchange2ical->apptSubType && (*exchange2ical->apptSubType == 0x1)) { struct tm tm; tm = get_tm_from_minutes_UTC(exchange2ical->AppointmentRecurrencePattern->ExceptionInfo->EndDateTime); icaltime= get_icaldate_from_tm(&tm); prop = icalproperty_new_dtend(icaltime); icalcomponent_add_property(exchange2ical->vevent, prop); }else { if(exchange2ical->TimeZoneDesc){ struct tm tm; tm = get_tm_from_minutes(exchange2ical->AppointmentRecurrencePattern->ExceptionInfo->EndDateTime); icaltime= get_icaldate_from_tm(&tm); prop = icalproperty_new_dtend(icaltime); icalcomponent_add_property(exchange2ical->vevent, prop); param = icalparameter_new_tzid(exchange2ical->TimeZoneDesc); icalproperty_add_parameter(prop, param); } else { struct tm tm; tm = get_tm_from_minutes_UTC(exchange2ical->AppointmentRecurrencePattern->ExceptionInfo->EndDateTime); icaltime= get_icaldate_from_tm(&tm); prop = icalproperty_new_dtend(icaltime); icalcomponent_add_property(exchange2ical->vevent, prop); } } /*recurrence-id from OriginalStartDate*/ if (exchange2ical->apptSubType && (*exchange2ical->apptSubType == 0x1)) { struct tm tm; tm = get_tm_from_minutes_UTC(exchange2ical->AppointmentRecurrencePattern->ExceptionInfo->OriginalStartDate); icaltime= get_icaldate_from_tm(&tm); prop = icalproperty_new_recurrenceid(icaltime); icalcomponent_add_property(exchange2ical->vevent, prop); }else { if(exchange2ical->TimeZoneDesc){ struct tm tm; tm = get_tm_from_minutes(exchange2ical->AppointmentRecurrencePattern->ExceptionInfo->OriginalStartDate); icaltime= get_icaldate_from_tm(&tm); prop = icalproperty_new_recurrenceid(icaltime); icalcomponent_add_property(exchange2ical->vevent, prop); param = icalparameter_new_tzid(exchange2ical->TimeZoneDesc); icalproperty_add_parameter(prop, param); } else { struct tm tm; tm = get_tm_from_minutes_UTC(exchange2ical->AppointmentRecurrencePattern->ExceptionInfo->OriginalStartDate); icaltime= get_icaldate_from_tm(&tm); prop = icalproperty_new_recurrenceid(icaltime); icalcomponent_add_property(exchange2ical->vevent, prop); } } /*summary from Subject if subject is set*/ if (exchange2ical->AppointmentRecurrencePattern->ExceptionInfo->OverrideFlags & 0x0001) { exchange2ical->Subject=(const char *) &exchange2ical->AppointmentRecurrencePattern->ExceptionInfo->Subject.subjectMsg.msg; ical_property_SUMMARY(exchange2ical); } /*Valarm*/ /*ReminderSet*/ if(exchange2ical->AppointmentRecurrencePattern->ExceptionInfo->OverrideFlags & 0x0008){ exchange2ical->ReminderSet=(uint8_t *) &exchange2ical->AppointmentRecurrencePattern->ExceptionInfo->ReminderDelta.rSet; /*Reminder Delta*/ if(exchange2ical->AppointmentRecurrencePattern->ExceptionInfo->OverrideFlags & 0x0004){ exchange2ical->ReminderDelta=&exchange2ical->AppointmentRecurrencePattern->ExceptionInfo->ReminderDelta.rDelta; } else { exchange2ical->ReminderDelta=NULL; } ical_component_VALARM(exchange2ical); } /*Location*/ if(exchange2ical->AppointmentRecurrencePattern->ExceptionInfo->OverrideFlags & 0x0010){ exchange2ical->Location=(const char *) &exchange2ical->AppointmentRecurrencePattern->ExceptionInfo->Location.locationMsg.msg; ical_property_LOCATION(exchange2ical); } /*Busy Status*/ if(exchange2ical->AppointmentRecurrencePattern->ExceptionInfo->OverrideFlags & 0x0020){ exchange2ical->BusyStatus=&exchange2ical->AppointmentRecurrencePattern->ExceptionInfo->BusyStatus.bStatus; ical_property_X_MICROSOFT_CDO_BUSYSTATUS(exchange2ical); } } return 0; } static uint8_t exchange2ical_exception_from_EmbeddedObj(struct exchange2ical *exchange2ical, struct exchange2ical_check *exchange2ical_check) { mapi_object_t obj_tb_attach; mapi_object_t obj_attach; struct SRowSet rowset_attach; struct SPropTagArray *SPropTagArray; const uint32_t *attach_num; struct SPropValue *lpProps; enum MAPISTATUS retval; unsigned int i; uint32_t count; struct SRow aRow2; struct SRow aRowT; mapi_object_init(&obj_tb_attach); retval = GetAttachmentTable(&exchange2ical->obj_message, &obj_tb_attach); if (retval != MAPI_E_SUCCESS) { return 1; }else { SPropTagArray = set_SPropTagArray(exchange2ical->mem_ctx, 0x1, PR_ATTACH_NUM); retval = SetColumns(&obj_tb_attach, SPropTagArray); MAPIFreeBuffer(SPropTagArray); retval = QueryRows(&obj_tb_attach, 0xa, TBL_ADVANCE, &rowset_attach); for (i = 0; i < rowset_attach.cRows; i++) { attach_num = (const uint32_t *)find_SPropValue_data(&(rowset_attach.aRow[i]), PR_ATTACH_NUM); retval = OpenAttach(&exchange2ical->obj_message, *attach_num, &obj_attach); if (retval != MAPI_E_SUCCESS) { return 1; }else { SPropTagArray = set_SPropTagArray(exchange2ical->mem_ctx, 0x3, PR_ATTACH_METHOD, PR_ATTACHMENT_FLAGS, PR_ATTACHMENT_HIDDEN ); lpProps = NULL; retval = GetProps(&obj_attach, 0, SPropTagArray, &lpProps, &count); MAPIFreeBuffer(SPropTagArray); if (retval != MAPI_E_SUCCESS) { return 1; }else { aRow2.ulAdrEntryPad = 0; aRow2.cValues = count; aRow2.lpProps = lpProps; uint32_t *attachmentFlags; uint32_t *attachMethod; uint8_t *attachmentHidden; attachmentFlags = (uint32_t *) octool_get_propval(&aRow2, PR_ATTACHMENT_FLAGS); attachMethod = (uint32_t *) octool_get_propval(&aRow2, PR_ATTACH_METHOD); attachmentHidden = (uint8_t *) octool_get_propval(&aRow2, PR_ATTACHMENT_HIDDEN); if(attachmentFlags && (*attachmentFlags & 0x00000002) && (*attachMethod == 0x00000005) && (attachmentHidden && (*attachmentHidden))) { struct exchange2ical exception; exchange2ical_init(exchange2ical->mem_ctx,&exception); mapi_object_init(&exception.obj_message); retval = OpenEmbeddedMessage(&obj_attach, &exception.obj_message, MAPI_READONLY); if (retval != MAPI_E_SUCCESS) { return 1; }else { SPropTagArray = set_SPropTagArray(exchange2ical->mem_ctx, 0x2d, PidLidFExceptionalBody, PidLidRecurring, PidLidAppointmentRecur, PidLidAppointmentStateFlags, PidLidTimeZoneDescription, PidLidTimeZoneStruct, PidLidAppointmentStartWhole, PidLidAppointmentEndWhole, PidLidAppointmentSubType, PidLidOwnerCriticalChange, PidLidLocation, PidLidExceptionReplaceTime, PidLidNonSendableBcc, PidLidAppointmentSequence, PidLidBusyStatus, PidLidIntendedBusyStatus, PidLidCleanGlobalObjectId, PidLidAttendeeCriticalChange, PidLidAppointmentReplyTime, PidLidAppointmentNotAllowPropose, PidLidAllowExternalCheck, PidLidAppointmentLastSequence, PidLidAppointmentSequenceTime, PidLidAutoFillLocation, PidLidAutoStartCheck, PidLidCollaborateDoc, PidLidConferencingCheck, PidLidConferencingType, PidLidDirectory, PidLidNetShowUrl, PidLidOnlinePassword, PidLidOrganizerAlias, PidLidReminderSet, PidLidReminderDelta, PR_MESSAGE_CLASS_UNICODE, PR_BODY_UNICODE, PR_CREATION_TIME, PR_LAST_MODIFICATION_TIME, PR_IMPORTANCE, PR_RESPONSE_REQUESTED, PR_SUBJECT_UNICODE, PR_OWNER_APPT_ID, PR_SENDER_NAME, PR_SENDER_EMAIL_ADDRESS, PR_MESSAGE_LOCALE_ID ); retval = GetProps(&exception.obj_message, MAPI_UNICODE, SPropTagArray, &lpProps, &count); if (retval == MAPI_E_SUCCESS) { aRow2.ulAdrEntryPad = 0; aRow2.cValues = count; aRow2.lpProps = lpProps; /*Get required properties to check if right event*/ exchange2ical_get_properties(exchange2ical->mem_ctx, &aRow2, &exception, exchange2ical_check->eFlags); /*Check to see if event is acceptable*/ if (!checkEvent(&exception, exchange2ical_check, get_tm_from_FILETIME(exception.apptStartWhole))){ break; } /*Grab Rest of Properties*/ exchange2ical_get_properties(exchange2ical->mem_ctx, &aRow2, &exception, exchange2ical_check->eFlags | EntireFlag); uint8_t *dBody = (uint8_t *) octool_get_propval(&aRow2, PidLidFExceptionalBody); retval = GetRecipientTable(&exception.obj_message, &exception.Recipients.SRowSet, &exception.Recipients.SPropTagArray); /*Check for set subject*/ if (!exception.Subject){ exception.Subject=exchange2ical->Subject; } /*Check for a set apptSubType*/ if (!exception.apptSubType){ exception.apptSubType=exchange2ical->apptSubType; } /*check for a set Location*/ if (!exception.Location){ exception.Location=exchange2ical->Location; } /*check for set valarm info*/ if(!exception.ReminderSet){ exception.ReminderSet=exchange2ical->ReminderSet; } if(!exception.ReminderDelta){ exception.ReminderDelta=exchange2ical->ReminderDelta; } /*Set to same vcalendar as parent*/ exception.vcalendar=exchange2ical->vcalendar; /*Set to same uid fallback in case GlobalObjId is missing*/ exception.idx=exchange2ical->idx; /*has a modified summary*/ if(dBody && *dBody){ SPropTagArray = set_SPropTagArray(exchange2ical->mem_ctx, 0x1, PR_BODY_HTML_UNICODE); retval = GetProps(&exception.obj_message, MAPI_UNICODE, SPropTagArray, &lpProps, &count); MAPIFreeBuffer(SPropTagArray); if (retval == MAPI_E_SUCCESS) { aRowT.ulAdrEntryPad = 0; aRowT.cValues = count; aRowT.lpProps = lpProps; exception.bodyHTML = (const char *)octool_get_propval(&aRowT, PR_BODY_HTML_UNICODE); } /* has the same summary as parent*/ } else{ exception.body=exchange2ical->body; exception.bodyHTML=exchange2ical->bodyHTML; } ical_component_VEVENT(&exception); exception.vcalendar=NULL; exchange2ical_clear(&exception); } } mapi_object_release(&exception.obj_message); } MAPIFreeBuffer(lpProps); } } } } mapi_object_release(&obj_tb_attach); return 0; } icalcomponent * _Exchange2Ical(mapi_object_t *obj_folder, struct exchange2ical_check *exchange2ical_check) { TALLOC_CTX *mem_ctx; enum MAPISTATUS retval; int ret; struct SRowSet SRowSet; struct SRow aRow; struct SRow aRowT; struct SPropValue *lpProps; struct SPropTagArray *SPropTagArray = NULL; struct exchange2ical exchange2ical; mapi_object_t obj_table; uint32_t count; int i; mem_ctx = talloc_named(mapi_object_get_session(obj_folder), 0, "exchange2ical"); exchange2ical_init(mem_ctx, &exchange2ical); /* Open the contents table */ mapi_object_init(&obj_table); retval = GetContentsTable(obj_folder, &obj_table, 0, &count); if (retval != MAPI_E_SUCCESS){ talloc_free(mem_ctx); return NULL; } DEBUG(0, ("MAILBOX (%d appointments)\n", count)); if (count == 0) { talloc_free(mem_ctx); return NULL; } SPropTagArray = set_SPropTagArray(mem_ctx, 0x2, PR_FID, PR_MID); retval = SetColumns(&obj_table, SPropTagArray); MAPIFreeBuffer(SPropTagArray); if (retval != MAPI_E_SUCCESS) { mapi_errstr("SetColumns", retval); talloc_free(mem_ctx); return NULL; } while ((retval = QueryRows(&obj_table, count, TBL_ADVANCE, &SRowSet)) != MAPI_E_NOT_FOUND && SRowSet.cRows) { count -= SRowSet.cRows; for (i = (SRowSet.cRows-1); i >= 0; i--) { mapi_object_init(&exchange2ical.obj_message); retval = OpenMessage(obj_folder, SRowSet.aRow[i].lpProps[0].value.d, SRowSet.aRow[i].lpProps[1].value.d, &exchange2ical.obj_message, 0); if (retval != MAPI_E_NOT_FOUND) { SPropTagArray = set_SPropTagArray(mem_ctx, 0x30, PidLidGlobalObjectId, PidNameKeywords, PidLidRecurring, PidLidAppointmentRecur, PidLidAppointmentStateFlags, PidLidTimeZoneDescription, PidLidTimeZoneStruct, PidLidContacts, PidLidAppointmentStartWhole, PidLidAppointmentEndWhole, PidLidAppointmentSubType, PidLidOwnerCriticalChange, PidLidLocation, PidLidNonSendableBcc, PidLidAppointmentSequence, PidLidBusyStatus, PidLidIntendedBusyStatus, PidLidAttendeeCriticalChange, PidLidAppointmentReplyTime, PidLidAppointmentNotAllowPropose, PidLidAllowExternalCheck, PidLidAppointmentLastSequence, PidLidAppointmentSequenceTime, PidLidAutoFillLocation, PidLidAutoStartCheck, PidLidCollaborateDoc, PidLidConferencingCheck, PidLidConferencingType, PidLidDirectory, PidLidMeetingWorkspaceUrl, PidLidNetShowUrl, PidLidOnlinePassword, PidLidOrganizerAlias, PidLidReminderSet, PidLidReminderDelta, PidLidResponseStatus, PR_MESSAGE_CLASS_UNICODE, PR_SENSITIVITY, PR_BODY_UNICODE, PR_CREATION_TIME, PR_LAST_MODIFICATION_TIME, PR_IMPORTANCE, PR_RESPONSE_REQUESTED, PR_SUBJECT_UNICODE, PR_OWNER_APPT_ID, PR_SENDER_NAME, PR_SENDER_EMAIL_ADDRESS, PR_MESSAGE_LOCALE_ID ); retval = GetProps(&exchange2ical.obj_message, MAPI_UNICODE, SPropTagArray, &lpProps, &count); MAPIFreeBuffer(SPropTagArray); if (retval == MAPI_E_SUCCESS) { aRow.ulAdrEntryPad = 0; aRow.cValues = count; aRow.lpProps = lpProps; /*Get Vcal info if first event*/ if(i==(SRowSet.cRows-1)){ ret = exchange2ical_get_properties(mem_ctx, &aRow, &exchange2ical, VcalFlag); /*TODO: exit nicely*/ ical_component_VCALENDAR(&exchange2ical); } /*Get required properties to check if right event*/ ret = exchange2ical_get_properties(mem_ctx, &aRow, &exchange2ical, exchange2ical_check->eFlags); /*Check to see if event is acceptable*/ if (!checkEvent(&exchange2ical, exchange2ical_check, get_tm_from_FILETIME(exchange2ical.apptStartWhole))){ continue; } /*Set RecipientTable*/ retval = GetRecipientTable(&exchange2ical.obj_message, &exchange2ical.Recipients.SRowSet, &exchange2ical.Recipients.SPropTagArray); /*Set PR_BODY_HTML for x_alt_desc property*/ SPropTagArray = set_SPropTagArray(mem_ctx, 0x1, PR_BODY_HTML_UNICODE); retval = GetProps(&exchange2ical.obj_message, MAPI_UNICODE, SPropTagArray, &lpProps, &count); MAPIFreeBuffer(SPropTagArray); if (retval == MAPI_E_SUCCESS) { aRowT.ulAdrEntryPad = 0; aRowT.cValues = count; aRowT.lpProps = lpProps; exchange2ical.bodyHTML = (const char *)octool_get_propval(&aRowT, PR_BODY_HTML_UNICODE); } /*Get rest of properties*/ ret = exchange2ical_get_properties(mem_ctx, &aRow, &exchange2ical, (exchange2ical_check->eFlags | EntireFlag)); /*add new vevent*/ ical_component_VEVENT(&exchange2ical); /*Exceptions to event*/ if(exchange2ical_check->eFlags != EventFlag){ ret = exchange2ical_exception_from_EmbeddedObj(&exchange2ical, exchange2ical_check); if (ret){ ret=exchange2ical_exception_from_ExceptionInfo(&exchange2ical, exchange2ical_check); } } /*REMOVE once globalobjid is fixed*/ exchange2ical.idx++; MAPIFreeBuffer(lpProps); exchange2ical_reset(&exchange2ical); } } mapi_object_release(&exchange2ical.obj_message); } } icalcomponent *icalendar = exchange2ical.vcalendar; exchange2ical_clear(&exchange2ical); /* Uninitialize MAPI subsystem */ mapi_object_release(&obj_table); talloc_free(mem_ctx); return icalendar; } openchange-2.0/libexchange2ical/exchange2ical.h000066400000000000000000000336341223057412600215270ustar00rootroot00000000000000/* Convert Exchange appointments to ICAL OpenChange Project Copyright (C) Julien Kerihuel 2008 This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see . */ #ifndef __EXCHANGE2ICAL_H_ #define __EXCHANGE2ICAL_H_ #include "libmapi/libmapi.h" #include "libmapi/mapi_nameid.h" #include #include "utils/openchange-tools.h" #include #include #ifndef __BEGIN_DECLS #ifdef __cplusplus #define __BEGIN_DECLS extern "C" { #define __END_DECLS } #else #define __BEGIN_DECLS #define __END_DECLS #endif #endif struct message_recipients { struct SRowSet SRowSet; struct SPropTagArray SPropTagArray; }; enum exchange2ical_flags{ EntireFlag = 0x00001, RangeFlag = 0x00010, VcalFlag = 0x00100, EventFlag = 0x01000, EventsFlag = 0x10000 }; struct exchange2ical_check { enum exchange2ical_flags eFlags; struct tm *begin; struct tm *end; struct GlobalObjectId *GlobalObjectId; uint32_t Sequence; }; struct exchange2ical { TALLOC_CTX *mem_ctx; struct message_recipients Recipients; enum icalproperty_method method; enum icalparameter_partstat partstat; uint32_t *ResponseStatus; uint8_t *Recurring; struct RecurrencePattern *RecurrencePattern; struct TimeZoneStruct *TimeZoneStruct; const char *TimeZoneDesc; const struct StringArray_r *Keywords; const struct StringArray_r *Contacts; uint32_t *apptStateFlags; uint32_t *sensitivity; uint32_t *Importance; const struct FILETIME *created; const char *body; const struct FILETIME *apptStartWhole; const struct FILETIME *apptEndWhole; const struct FILETIME *OwnerCriticalChange; const struct FILETIME *LastModified; const struct FILETIME *ExceptionReplaceTime; uint8_t *apptSubType; const char *Location; uint8_t *ResponseRequested; const char *NonSendableBcc; uint32_t *Sequence; const char *Subject; uint32_t *MessageLocaleId; uint32_t *BusyStatus; uint32_t *IntendedBusyStatus; struct Binary_r *GlobalObjectId; const struct FILETIME *AttendeeCriticalChange; uint32_t *OwnerApptId; const struct FILETIME *apptReplyTime; uint8_t *NotAllowPropose; uint8_t *AllowExternCheck; uint32_t *apptLastSequence; const struct FILETIME *apptSeqTime; uint8_t *AutoFillLocation; uint8_t *AutoStartCheck; const char *CollaborateDoc; uint8_t *ConfCheck; uint32_t *ConfType; const char *Directory; const char *MWSURL; const char *NetShowURL; const char *OnlinePassword; const char *OrgAlias; const char *SenderName; const char *SenderEmailAddress; uint8_t *ReminderSet; uint32_t *ReminderDelta; icalcomponent *vcalendar; icalcomponent *vevent; icalcomponent *vtimezone; icalcomponent *valarm; mapi_object_t obj_message; const char *bodyHTML; uint32_t idx; struct AppointmentRecurrencePattern *AppointmentRecurrencePattern; }; struct ical_method { enum icalproperty_method method; enum icalparameter_partstat partstat; const char *messageclass; }; struct ical_calendartype { uint16_t type; const char *calendar; }; struct ical_day { enum icalrecurrencetype_weekday ical; enum FirstDOW exchange; uint32_t rdfDays; }; struct ical_class { uint32_t sensivity; enum icalproperty_class classtype; }; #define OPENCHANGE_ICAL_PRODID "-//OpenChange Project/exchange2ical MIMEDIR//EN" #define OPENCHANGE_ICAL_VERSION "2.0" __BEGIN_DECLS /* definitions from exchang2ical.c */ icalcomponent * _Exchange2Ical(mapi_object_t *, struct exchange2ical_check *); /* definitions from exchange2ical_utils.c */ struct icaltimetype get_icaltime_from_FILETIME(const struct FILETIME *); struct icaltimetype get_icaltime_from_FILETIME_UTC(const struct FILETIME *); struct icaltimetype get_icaldate_from_FILETIME(const struct FILETIME *); struct tm *get_tm_from_FILETIME(const struct FILETIME *); struct icaltimetype get_icaldate_from_tm(struct tm *); struct icaltimetype get_icaltimetype_from_tm_UTC(struct tm *); struct icaltimetype get_icaltimetype_from_tm(struct tm *); struct FILETIME get_FILETIME_from_string(const char *); struct FILETIME get_FILETIME_from_icaltimetype(icaltimetype *); struct tm get_tm_from_minutes(uint32_t); struct tm get_tm_from_minutes_UTC(uint32_t); struct icaltimetype get_icaldate_from_GlobalObjectId(struct GlobalObjectId *); NTTIME FILETIME_to_NTTIME(struct FILETIME); enum icalproperty_method get_ical_method(const char *); enum icalparameter_partstat get_ical_partstat(const char *); enum icalproperty_class get_ical_class(uint32_t); enum icalparameter_partstat get_ical_partstat_from_status(uint32_t); enum FirstDOW get_exchange_day_from_ical(enum icalrecurrencetype_weekday); uint8_t set_exception_from_ExceptionInfo(struct exchange2ical *, struct exchange2ical_check *); uint8_t set_exception_from_EmbeddedObj(struct exchange2ical *, struct exchange2ical_check *); bool checkEvent(struct exchange2ical *, struct exchange2ical_check *, struct tm *); bool compareGlobalObjectIds(struct GlobalObjectId *, struct GlobalObjectId *); bool has_component_DAYLIGHT(struct exchange2ical *); uint16_t get_exchange_calendartype(const char *); uint32_t get_minutes_from_icaltimetype(icaltimetype); uint32_t get_exchange_rdfDays_from_ical(enum icalrecurrencetype_weekday); const char *get_ical_calendartype(uint16_t); char *get_ical_date(TALLOC_CTX *, struct SYSTEMTIME *); int compare_minutes(const void *, const void *); /* definitions from exchange2ical_component.c */ void ical_component_VCALENDAR(struct exchange2ical *); void ical_component_VEVENT(struct exchange2ical *); void ical_component_VTIMEZONE(struct exchange2ical *); void ical_component_STANDARD(struct exchange2ical *); void ical_component_DAYLIGHT(struct exchange2ical *); void ical_component_VALARM(struct exchange2ical *); /* definitions from exchange2ical_property.c */ void ical_property_ATTACH(struct exchange2ical *); void ical_property_ATTENDEE(struct exchange2ical *); void ical_property_CATEGORIES(struct exchange2ical *); void ical_property_CLASS(struct exchange2ical *); void ical_property_CONTACT(struct exchange2ical *); void ical_property_CREATED(struct exchange2ical *); void ical_property_DTEND(struct exchange2ical *); void ical_property_DTSTAMP(struct exchange2ical *); void ical_property_DTSTART(struct exchange2ical *); void ical_property_DESCRIPTION(struct exchange2ical *); void ical_property_EXDATE(struct exchange2ical *); void ical_property_LAST_MODIFIED(struct exchange2ical *); void ical_property_LOCATION(struct exchange2ical *); void ical_property_ORGANIZER(struct exchange2ical *); void ical_property_PRIORITY(struct exchange2ical *); void ical_property_RDATE(struct exchange2ical *); void ical_property_RRULE_Daily(struct exchange2ical *); void ical_property_RRULE_Weekly(struct exchange2ical *); void ical_property_RRULE_Monthly(struct exchange2ical *); void ical_property_RRULE_NthMonthly(struct exchange2ical *); void ical_property_RRULE_Yearly(struct exchange2ical *); void ical_property_RRULE_NthYearly(struct exchange2ical *); void ical_property_RRULE(struct exchange2ical *); void ical_property_RRULE_daylight_standard(icalcomponent*, struct SYSTEMTIME); void ical_property_RECURRENCE_ID(struct exchange2ical *); void ical_property_RESOURCES(struct exchange2ical *); void ical_property_SEQUENCE(struct exchange2ical *); void ical_property_SUMMARY(struct exchange2ical *); void ical_property_TRANSP(struct exchange2ical *); void ical_property_TRIGGER(struct exchange2ical *); void ical_property_UID(struct exchange2ical *); void ical_property_X_ALT_DESC(struct exchange2ical *); void ical_property_X_MICROSOFT_CDO_ATTENDEE_CRITICAL_CHANGE(struct exchange2ical *); void ical_property_X_MICROSOFT_CDO_BUSYSTATUS(struct exchange2ical *); void ical_property_X_MICROSOFT_CDO_INTENDEDSTATUS(struct exchange2ical *); void ical_property_X_MICROSOFT_CDO_OWNERAPPTID(struct exchange2ical *); void ical_property_X_MICROSOFT_CDO_OWNER_CRITICAL_CHANGE(struct exchange2ical *); void ical_property_X_MICROSOFT_CDO_REPLYTIME(struct exchange2ical *); void ical_property_X_MICROSOFT_DISALLOW_COUNTER(struct exchange2ical *); void ical_property_X_MS_OLK_ALLOWEXTERNCHECK(struct exchange2ical *); void ical_property_X_MS_OLK_APPTLASTSEQUENCE(struct exchange2ical *); void ical_property_X_MS_OLK_APPTSEQTIME(struct exchange2ical *); void ical_property_X_MS_OLK_AUTOFILLLOCATION(struct exchange2ical *); void ical_property_X_MS_OLK_AUTOSTARTCHECK(struct exchange2ical *); void ical_property_X_MS_OLK_COLLABORATEDOC(struct exchange2ical *); void ical_property_X_MS_OLK_CONFCHECK(struct exchange2ical *); void ical_property_X_MS_OLK_CONFTYPE(struct exchange2ical *); void ical_property_X_MS_OLK_DIRECTORY(struct exchange2ical *); void ical_property_X_MS_OLK_MWSURL(struct exchange2ical *); void ical_property_X_MS_OLK_NETSHOWURL(struct exchange2ical *); void ical_property_X_MS_OLK_ONLINEPASSWORD(struct exchange2ical *); void ical_property_X_MS_OLK_ORGALIAS(struct exchange2ical *); void ical_property_X_MS_OLK_SENDER(struct exchange2ical *); void ical_property_X_MICROSOFT_MSNCALENDAR_IMPORTANCE(struct exchange2ical *); struct ical2exchange{ TALLOC_CTX *mem_ctx; enum icalproperty_method method; icalproperty *classProp; icalproperty *commentProp; icalproperty *descriptionProp; icalproperty *dtendProp; icalproperty *dtstampProp; icalproperty *dtstartProp; icalproperty *durationProp; icalproperty *locationProp; icalproperty *organizerProp; icalproperty *priorityProp; icalproperty *recurrenceidProp; icalproperty *rruleProp; icalproperty *sequenceProp; icalproperty *statusProp; icalproperty *summaryProp; icalproperty *transpProp; icalproperty *uidProp; uint32_t rdateCount; uint32_t exdateCount; /* x properties */ icalproperty *x_busystatusProp; icalproperty *x_sequenceProp; icalproperty *x_importanceProp; icalproperty *x_intendedProp; icalproperty *x_ownerapptidProp; icalproperty *x_attendeecriticalchangeProp; icalproperty *x_replytimeProp; icalproperty *x_disallowcounterProp; icalproperty *x_isdraftProp; icalproperty *x_allowexterncheckProp; icalproperty *x_apptlastsequenceProp; icalproperty *x_apptseqtimeProp; icalproperty *x_autofilllocationProp; icalproperty *x_autostartcheckProp; icalproperty *x_confcheckProp; icalproperty *x_collaborateddocProp; icalproperty *x_conftypeProp; icalproperty *x_mwsurlProp; icalproperty *x_netshowurlProp; icalproperty *x_onlinepasswordProp; icalproperty *x_originalstartProp; icalproperty *x_originalendProp; icalproperty *x_orgaliasProp; icalproperty *x_ownercriticalchangeProp; /* Events */ icalcomponent *attachEvent; icalcomponent *attendeeEvent; icalcomponent *categoriesEvent; icalcomponent *contactEvent; icalcomponent *exdateEvent; icalcomponent *rdateEvent; icalcomponent *resourcesEvent; icalcomponent *valarmEvent; mapi_object_t *obj_message; struct SPropValue *lpProps; uint32_t cValues; }; /*ical2exchange file*/ void _IcalEvent2Exchange(mapi_object_t *, icalcomponent *); /*ical2exchange_property*/ void ical2exchange_property_ATTACH(struct ical2exchange *); //TODO ATTENDEE, ORGANIZER, x_ms_ok_sender void ical2exchange_property_CATEGORIES(struct ical2exchange *); void ical2exchange_property_CLASS(struct ical2exchange *); void ical2exchange_property_COMMENT(struct ical2exchange *); void ical2exchange_property_CONTACT(struct ical2exchange *); void ical2exchange_property_DESCRIPTION(struct ical2exchange *); void ical2exchange_property_DTSTAMP(struct ical2exchange *); void ical2exchange_property_DTSTART_DTEND(struct ical2exchange *); void ical2exchange_property_LOCATION(struct ical2exchange *); void ical2exchange_property_PRIORITY(struct ical2exchange *); void ical2exchange_property_RRULE_EXDATE_RDATE(struct ical2exchange *); void ical2exchange_property_SEQUENCE(struct ical2exchange *); void ical2exchange_property_STATUS(struct ical2exchange *); void ical2exchange_property_SUMMARY(struct ical2exchange *); void ical2exchange_property_VALARM(struct ical2exchange *); void ical2exchange_property_X_ALLOWEXTERNCHECK(struct ical2exchange *); void ical2exchange_property_X_APPTSEQTIME(struct ical2exchange *); void ical2exchange_property_X_APPTLASTSEQUENCE(struct ical2exchange *); void ical2exchange_property_X_ATTENDEE_CRITICAL_CHANGE(struct ical2exchange *); void ical2exchange_property_X_AUTOFILLLOCATION(struct ical2exchange *); void ical2exchange_property_X_AUTOSTARTCHECK(struct ical2exchange *); void ical2exchange_property_X_COLLABORATEDDOC(struct ical2exchange *); void ical2exchange_property_X_CONFCHECK(struct ical2exchange *); void ical2exchange_property_X_CONFTYPE(struct ical2exchange *); void ical2exchange_property_X_DISALLOW_COUNTER(struct ical2exchange *); void ical2exchange_property_X_INTENDEDSTATUS(struct ical2exchange *); void ical2exchange_property_X_ISDRAFT(struct ical2exchange *); void ical2exchange_property_X_MWSURL(struct ical2exchange *); void ical2exchange_property_X_NETSHOWURL(struct ical2exchange *); void ical2exchange_property_X_ONLINEPASSWORD(struct ical2exchange *); void ical2exchange_property_X_ORGALIAS(struct ical2exchange *); void ical2exchange_property_X_ORIGINALEND_ORIGINALSTART(struct ical2exchange *); void ical2exchange_property_X_OWNER_CRITICAL_CHANGE(struct ical2exchange *); void ical2exchange_property_X_OWNERAPPTID(struct ical2exchange *); void ical2exchange_property_X_REPLYTIME(struct ical2exchange *); __END_DECLS #endif /* __EXCHANGE2ICAL_H_ */ openchange-2.0/libexchange2ical/exchange2ical_component.c000066400000000000000000000205031223057412600235730ustar00rootroot00000000000000/* Convert Exchange appointments and meetings to ICAL files OpenChange Project Copyright (C) Julien Kerihuel 2008 This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see . */ #include "libexchange2ical/libexchange2ical.h" #include /* VCALENDAR component */ void ical_component_VCALENDAR(struct exchange2ical *exchange2ical) { icalproperty* prop; exchange2ical->vcalendar = icalcomponent_new_vcalendar(); if (!(exchange2ical->vcalendar)) { return; } prop = icalproperty_new_version(OPENCHANGE_ICAL_VERSION); icalcomponent_add_property(exchange2ical->vcalendar, prop); prop = icalproperty_new_prodid(OPENCHANGE_ICAL_PRODID); icalcomponent_add_property(exchange2ical->vcalendar, prop); prop = icalproperty_new_method(exchange2ical->method); icalcomponent_add_property(exchange2ical->vcalendar, prop); if (exchange2ical->RecurrencePattern && exchange2ical->RecurrencePattern->CalendarType) { prop = icalproperty_new_x(get_ical_calendartype(exchange2ical->RecurrencePattern->CalendarType)); icalproperty_set_x_name(prop, "X-MICROSOFT-CALSCALE"); icalcomponent_add_property(exchange2ical->vcalendar, prop); } ical_component_VTIMEZONE(exchange2ical); } /* VEVENT component */ void ical_component_VEVENT(struct exchange2ical *exchange2ical) { exchange2ical->vevent = icalcomponent_new_vevent(); if ( ! (exchange2ical->vevent) ) { return; } icalcomponent_add_component(exchange2ical->vcalendar, exchange2ical->vevent); ical_property_ATTACH(exchange2ical); ical_property_ATTENDEE(exchange2ical); ical_property_CATEGORIES(exchange2ical); ical_property_CLASS(exchange2ical); ical_property_CONTACT(exchange2ical); ical_property_CREATED(exchange2ical); ical_property_DESCRIPTION(exchange2ical); ical_property_DTEND(exchange2ical); ical_property_DTSTAMP(exchange2ical); ical_property_DTSTART(exchange2ical); ical_property_RECURRENCE_ID(exchange2ical); ical_property_EXDATE(exchange2ical); ical_property_LAST_MODIFIED(exchange2ical); ical_property_LOCATION(exchange2ical); ical_property_ORGANIZER(exchange2ical); ical_property_PRIORITY(exchange2ical); /*All possible RDATE properties are now exported as separate vevents. No longer a need for it*/ //ical_property_RDATE(exchange2ical); ical_property_RRULE(exchange2ical); ical_property_RESOURCES(exchange2ical); ical_property_SEQUENCE(exchange2ical); ical_property_SUMMARY(exchange2ical); ical_property_TRANSP(exchange2ical); ical_property_UID(exchange2ical); ical_property_X_ALT_DESC(exchange2ical); ical_property_X_MICROSOFT_CDO_ATTENDEE_CRITICAL_CHANGE(exchange2ical); ical_property_X_MICROSOFT_CDO_BUSYSTATUS(exchange2ical); /* Looks like this is no longer supposed to be used, and is ignored by most Outlook versions */ /* ical_property_X_MICROSOFT_MSNCALENDAR_IMPORTANCE(exchange2ical); */ ical_property_X_MICROSOFT_CDO_INTENDEDSTATUS(exchange2ical); ical_property_X_MICROSOFT_CDO_OWNERAPPTID(exchange2ical); ical_property_X_MICROSOFT_CDO_OWNER_CRITICAL_CHANGE(exchange2ical); ical_property_X_MICROSOFT_CDO_REPLYTIME(exchange2ical); ical_property_X_MICROSOFT_DISALLOW_COUNTER(exchange2ical); ical_property_X_MS_OLK_ALLOWEXTERNCHECK(exchange2ical); ical_property_X_MS_OLK_APPTLASTSEQUENCE(exchange2ical); ical_property_X_MS_OLK_APPTSEQTIME(exchange2ical); ical_property_X_MS_OLK_AUTOFILLLOCATION(exchange2ical); ical_property_X_MS_OLK_AUTOSTARTCHECK(exchange2ical); ical_property_X_MS_OLK_COLLABORATEDOC(exchange2ical); ical_property_X_MS_OLK_CONFCHECK(exchange2ical); ical_property_X_MS_OLK_CONFTYPE(exchange2ical); ical_property_X_MS_OLK_DIRECTORY(exchange2ical); ical_property_X_MS_OLK_MWSURL(exchange2ical); ical_property_X_MS_OLK_NETSHOWURL(exchange2ical); ical_property_X_MS_OLK_ONLINEPASSWORD(exchange2ical); ical_property_X_MS_OLK_ORGALIAS(exchange2ical); ical_property_X_MS_OLK_SENDER(exchange2ical); ical_component_VALARM(exchange2ical); } /* VTIMEZONE component */ void ical_component_VTIMEZONE(struct exchange2ical *exchange2ical) { exchange2ical->vtimezone = icalcomponent_new_vtimezone(); /* TZID property */ if (exchange2ical->TimeZoneDesc) { icalproperty *tzid = icalproperty_new_tzid(exchange2ical->TimeZoneDesc); icalcomponent_add_property(exchange2ical->vtimezone, tzid); } /* STANDARD sub-component */ if (exchange2ical->TimeZoneStruct) { icalcomponent_add_component(exchange2ical->vcalendar, exchange2ical->vtimezone); ical_component_STANDARD(exchange2ical); if (has_component_DAYLIGHT(exchange2ical)) { ical_component_DAYLIGHT(exchange2ical); } } else { icalcomponent_free(exchange2ical->vtimezone); } } /* STANDARD sub-component */ void ical_component_STANDARD(struct exchange2ical *exchange2ical) { char *dtstart = NULL; int32_t tzoffsetfrom; int32_t tzoffsetto; icalcomponent *standard; icalproperty *prop; standard = icalcomponent_new_xstandard(); icalcomponent_add_component(exchange2ical->vtimezone, standard); /* DTSTART property */ dtstart = get_ical_date(exchange2ical->mem_ctx, &(exchange2ical->TimeZoneStruct->stStandardDate)); if (dtstart) { prop = icalproperty_new_dtstart(icaltime_from_string(dtstart)); icalcomponent_add_property(standard, prop); talloc_free(dtstart); } /* RRULE Property */ if (has_component_DAYLIGHT(exchange2ical)){ ical_property_RRULE_daylight_standard(standard,exchange2ical->TimeZoneStruct->stStandardDate); } /* TZOFFSETFROM property */ tzoffsetfrom = (-60 * (exchange2ical->TimeZoneStruct->lBias + exchange2ical->TimeZoneStruct->lDaylightBias)); prop = icalproperty_new_tzoffsetfrom(tzoffsetfrom); icalcomponent_add_property(standard, prop); /* TZOFFSETTO property */ tzoffsetto = (-60 * (exchange2ical->TimeZoneStruct->lBias + exchange2ical->TimeZoneStruct->lStandardBias)); prop = icalproperty_new_tzoffsetto(tzoffsetto); icalcomponent_add_property(standard, prop); } /* DAYLIGHT sub-component */ void ical_component_DAYLIGHT(struct exchange2ical *exchange2ical) { char *dtstart = NULL; int32_t tzoffsetfrom; int32_t tzoffsetto; icalcomponent *daylight; icalproperty *prop; daylight = icalcomponent_new_xdaylight(); icalcomponent_add_component(exchange2ical->vtimezone, daylight); /* DTSTART property */ dtstart = get_ical_date(exchange2ical->mem_ctx, &exchange2ical->TimeZoneStruct->stDaylightDate); if (dtstart) { prop = icalproperty_new_dtstart(icaltime_from_string(dtstart)); icalcomponent_add_property(daylight, prop); talloc_free(dtstart); } /* RRULE property */ ical_property_RRULE_daylight_standard(daylight,exchange2ical->TimeZoneStruct->stDaylightDate); /* TZOFFSETFROM property */ tzoffsetfrom = (-60 * (exchange2ical->TimeZoneStruct->lBias + exchange2ical->TimeZoneStruct->lStandardBias)); prop = icalproperty_new_tzoffsetfrom(tzoffsetfrom); icalcomponent_add_property(daylight, prop); /* TZOFFSETTO property */ tzoffsetto = (-60 * (exchange2ical->TimeZoneStruct->lBias + exchange2ical->TimeZoneStruct->lDaylightBias)); prop = icalproperty_new_tzoffsetto(tzoffsetto); icalcomponent_add_property(daylight, prop); } /* VALARM component [MS-OXCICAL], Section 2.2.1.20.61 */ void ical_component_VALARM(struct exchange2ical *exchange2ical) { icalproperty *action; icalproperty *description; /* Sanity check */ if (!exchange2ical->vevent) return; if (!exchange2ical->ReminderSet) return; if (*exchange2ical->ReminderSet == false) return; exchange2ical->valarm = icalcomponent_new_valarm(); if (!(exchange2ical->valarm)) { printf("could not create new valarm\n"); return; } icalcomponent_add_component(exchange2ical->vevent, exchange2ical->valarm); ical_property_TRIGGER(exchange2ical); action = icalproperty_new_action(ICAL_ACTION_DISPLAY); icalcomponent_add_property(exchange2ical->valarm, action); description = icalproperty_new_description("Reminder"); icalcomponent_add_property(exchange2ical->valarm, description); } openchange-2.0/libexchange2ical/exchange2ical_property.c000066400000000000000000001272501223057412600234640ustar00rootroot00000000000000/* Convert Exchange appointments and meetings to ICAL files OpenChange Project Copyright (C) Julien Kerihuel 2008 This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see . */ #include "libexchange2ical/libexchange2ical.h" #include struct RRULE_byday { uint16_t DayOfWeek; const char *DayName; }; static const struct RRULE_byday RRULE_byday[] = { { 0x0000, "SU" }, { 0x0001, "MO" }, { 0x0002, "TU" }, { 0x0003, "WE" }, { 0x0004, "TH" }, { 0x0005, "FR" }, { 0x0006, "SA" }, { 0x0007, NULL } }; static const char *get_filename(const char *filename) { const char *substr; if (!filename) return NULL; substr = rindex(filename, '/'); if (substr) return substr; return filename; } void ical_property_ATTACH(struct exchange2ical *exchange2ical) { mapi_object_t obj_tb_attach; mapi_object_t obj_attach; mapi_object_t obj_stream; struct SRowSet rowset_attach; struct SPropTagArray *SPropTagArray = NULL; const uint32_t *attach_num = NULL; struct SPropValue *lpProps; enum MAPISTATUS retval; unsigned int i; uint32_t count; struct SRow aRow2; mapi_object_init(&obj_tb_attach); retval = GetAttachmentTable(&exchange2ical->obj_message, &obj_tb_attach); if (retval == MAPI_E_SUCCESS) { SPropTagArray = set_SPropTagArray(exchange2ical->mem_ctx, 0x1, PR_ATTACH_NUM); retval = SetColumns(&obj_tb_attach, SPropTagArray); MAPIFreeBuffer(SPropTagArray); retval = QueryRows(&obj_tb_attach, 0xa, TBL_ADVANCE, &rowset_attach); for (i = 0; i < rowset_attach.cRows; i++) { attach_num = (const uint32_t *)find_SPropValue_data(&(rowset_attach.aRow[i]), PR_ATTACH_NUM); retval = OpenAttach(&exchange2ical->obj_message, *attach_num, &obj_attach); if (retval == MAPI_E_SUCCESS) { SPropTagArray = set_SPropTagArray(exchange2ical->mem_ctx, 0x7, PR_ATTACH_FILENAME, PR_ATTACH_LONG_FILENAME, PR_ATTACH_METHOD, PR_ATTACHMENT_FLAGS, PR_ATTACHMENT_HIDDEN, PR_ATTACH_MIME_TAG, PR_ATTACH_DATA_BIN ); lpProps = NULL; retval = GetProps(&obj_attach, MAPI_UNICODE, SPropTagArray, &lpProps, &count); MAPIFreeBuffer(SPropTagArray); if (retval == MAPI_E_SUCCESS) { uint32_t *attachmentFlags = NULL; uint32_t *attachMethod = NULL; uint8_t *attachmentHidden = NULL; const char *data = NULL; const char *fmttype = NULL; const char *attach_filename = NULL; DATA_BLOB body; icalattach *icalattach = NULL; icalproperty *prop = NULL; icalparameter *param = NULL; aRow2.ulAdrEntryPad = 0; aRow2.cValues = count; aRow2.lpProps = lpProps; attachmentFlags = octool_get_propval(&aRow2, PR_ATTACHMENT_FLAGS); attachMethod = octool_get_propval(&aRow2, PR_ATTACH_METHOD); attachmentHidden = octool_get_propval(&aRow2, PR_ATTACHMENT_HIDDEN); if(attachmentFlags && !(*attachmentFlags & 0x00000007) && (*attachMethod == 0x00000001) && (!attachmentHidden || !(*attachmentHidden))) { /* Get data of attachment */ retval = OpenStream(&obj_attach, PR_ATTACH_DATA_BIN, 0, &obj_stream); retval = octool_get_stream(exchange2ical->mem_ctx, &obj_stream, &body); data=ldb_base64_encode(exchange2ical->mem_ctx, (const char *)body.data, body.length); /*Create a new icalattach from above data*/ #if HAVE_ICAL_0_46 /* the function signature for icalattach_new_from_data() changed in 0.46, released 2010-08-30 */ /* we can switch to just using the new signature after everyone has had a reasonable chance to update (say end of 2011) */ icalattach = icalattach_new_from_data(data, 0, 0); #else icalattach = icalattach_new_from_data((unsigned char *)data,0,0); #endif /*Add attach property to vevent component*/ prop = icalproperty_new_attach(icalattach); icalcomponent_add_property(exchange2ical->vevent, prop); /* Attachment filename for X-FILENAME parameter*/ attach_filename = get_filename(octool_get_propval(&aRow2, PR_ATTACH_LONG_FILENAME)); if (!attach_filename || (attach_filename && !strcmp(attach_filename, ""))) { attach_filename = get_filename(octool_get_propval(&aRow2, PR_ATTACH_FILENAME)); } /* fmttype parameter */ fmttype = (const char *) octool_get_propval(&aRow2, PR_ATTACH_MIME_TAG); if(fmttype) { param = icalparameter_new_fmttype(fmttype); icalproperty_add_parameter(prop, param); } /* ENCODING parameter */ param =icalparameter_new_encoding(ICAL_ENCODING_BASE64); icalproperty_add_parameter(prop,param); /* VALUE parameter */ param=icalparameter_new_value(ICAL_VALUE_BINARY); icalproperty_add_parameter(prop,param); /* X-FILENAME parameter */ param = icalparameter_new_x(attach_filename); icalparameter_set_xname(param,"X-FILENAME"); icalproperty_add_parameter(prop,param); } MAPIFreeBuffer(lpProps); } } } } mapi_object_release(&obj_tb_attach); } // TODO: check this - need an example void ical_property_ATTENDEE(struct exchange2ical *exchange2ical) { uint32_t i; const char *smtp; const char *display_name; uint32_t *RecipientFlags; uint32_t *RecipientType; uint32_t *TrackStatus; struct SRowSet *SRowSet; /* Sanity check */ if (!exchange2ical->apptStateFlags) return; if (!(*exchange2ical->apptStateFlags & 0x1)) return; SRowSet = &(exchange2ical->Recipients.SRowSet); /* Loop over the recipient table */ for (i = 0; i < SRowSet->cRows; i++) { smtp = (const char *) octool_get_propval(&(SRowSet->aRow[i]), PR_SMTP_ADDRESS); display_name = (const char *) octool_get_propval(&(SRowSet->aRow[i]), PR_RECIPIENT_DISPLAY_NAME); RecipientFlags = (uint32_t *) octool_get_propval(&(SRowSet->aRow[i]), PR_RECIPIENT_FLAGS); RecipientType = (uint32_t *) octool_get_propval(&(SRowSet->aRow[i]), PR_RECIPIENT_TYPE); TrackStatus = (uint32_t *) octool_get_propval(&(SRowSet->aRow[i]), PR_RECIPIENT_TRACKSTATUS); if (RecipientFlags && !(*RecipientFlags & 0x20) && !(*RecipientFlags & 0x2) && (RecipientType && *RecipientType)) { icalproperty *prop; icalparameter *cn; icalparameter *participantType; enum icalparameter_partstat partstat = ICAL_PARTSTAT_NONE; if (smtp) { char *mailtoURL; mailtoURL = talloc_strdup(exchange2ical->mem_ctx, "mailto:"); mailtoURL = talloc_strdup_append(mailtoURL, smtp); prop = icalproperty_new_attendee(mailtoURL); icalcomponent_add_property(exchange2ical->vevent, prop); } else { prop = icalproperty_new_attendee("invalid:nomail"); icalcomponent_add_property(exchange2ical->vevent, prop); } if (display_name) { cn = icalparameter_new_cn(display_name); icalproperty_add_parameter(prop, cn); } if (*RecipientType == 0x3) { icalparameter *cutype = icalparameter_new_cutype(ICAL_CUTYPE_RESOURCE); icalproperty_add_parameter(prop, cutype); } switch (*RecipientType) { case 0x00000002: participantType = icalparameter_new_role(ICAL_ROLE_OPTPARTICIPANT); icalproperty_add_parameter(prop, participantType); break; case 0x00000003: participantType = icalparameter_new_role(ICAL_ROLE_NONPARTICIPANT); icalproperty_add_parameter(prop, participantType); break; } if((exchange2ical->method==ICAL_METHOD_REPLY) || (exchange2ical->method==ICAL_METHOD_COUNTER)){ partstat = exchange2ical->partstat; }else if(exchange2ical->method==ICAL_METHOD_PUBLISH){ if(TrackStatus){ partstat = get_ical_partstat_from_status(*TrackStatus); }else if(exchange2ical->ResponseStatus){ partstat = get_ical_partstat_from_status(*exchange2ical->ResponseStatus); } } if (partstat != ICAL_PARTSTAT_NONE) { icalparameter *param; param = icalparameter_new_partstat(partstat); icalproperty_add_parameter(prop, param); } if (exchange2ical->ResponseRequested) { icalparameter *rsvp; if (*(exchange2ical->ResponseRequested)) { rsvp = icalparameter_new_rsvp(ICAL_RSVP_TRUE); } else { rsvp = icalparameter_new_rsvp(ICAL_RSVP_FALSE); } icalproperty_add_parameter(prop, rsvp); } } } } void ical_property_CATEGORIES(struct exchange2ical *exchange2ical) { uint32_t i; icalproperty *prop; /* Sanity check */ if (!exchange2ical->Keywords) return; if (!exchange2ical->Keywords->cValues) return; for (i = 0; i < exchange2ical->Keywords->cValues; i++) { prop = icalproperty_new_categories(exchange2ical->Keywords->lppszA[i]); icalcomponent_add_property(exchange2ical->vevent, prop); } } void ical_property_CLASS(struct exchange2ical *exchange2ical) { icalproperty *prop; /* Sanity check */ if (!exchange2ical->sensitivity) return; prop = icalproperty_new_class(get_ical_class(*exchange2ical->sensitivity)); icalcomponent_add_property(exchange2ical->vevent, prop); } void ical_property_CONTACT(struct exchange2ical *exchange2ical) { icalproperty *prop; uint32_t i; /* Sanity check */ if (!exchange2ical->Contacts) return; if (!exchange2ical->Contacts->cValues) return; for (i = 0; i < exchange2ical->Contacts->cValues; i++) { prop = icalproperty_new_contact(exchange2ical->Contacts->lppszA[i]); icalcomponent_add_property(exchange2ical->vevent, prop); } } void ical_property_CREATED(struct exchange2ical *exchange2ical) { icalproperty *prop; struct icaltimetype icaltime; /* Sanity check */ if (!exchange2ical->created) return; icaltime = get_icaltime_from_FILETIME_UTC(exchange2ical->created); prop = icalproperty_new_created(icaltime); icalcomponent_add_property(exchange2ical->vevent, prop); } void ical_property_DTSTART(struct exchange2ical *exchange2ical) { icalproperty *prop; icalparameter *tzid; struct icaltimetype icaltime; /* Sanity check */ if (!exchange2ical->apptStartWhole) return; /* If this is an all-day appointment */ if (exchange2ical->apptSubType && (*exchange2ical->apptSubType == 0x1)) { icaltime = get_icaldate_from_FILETIME(exchange2ical->apptStartWhole); prop = icalproperty_new_dtstart(icaltime); icalcomponent_add_property(exchange2ical->vevent, prop); } else { if (exchange2ical->TimeZoneDesc) { icaltime = get_icaltime_from_FILETIME(exchange2ical->apptStartWhole); prop = icalproperty_new_dtstart(icaltime); icalcomponent_add_property(exchange2ical->vevent, prop); tzid = icalparameter_new_tzid(exchange2ical->TimeZoneDesc); icalproperty_add_parameter(prop, tzid); } else { icaltime = get_icaltime_from_FILETIME_UTC(exchange2ical->apptStartWhole); prop = icalproperty_new_dtstart(icaltime); icalcomponent_add_property(exchange2ical->vevent, prop); } } } void ical_property_DTEND(struct exchange2ical *exchange2ical) { icalproperty *prop; icalparameter *tzid; struct icaltimetype icaltime; /* Sanity check */ if (!exchange2ical->apptEndWhole) return; /* If this is an all-day appointment */ if (exchange2ical->apptSubType && (*exchange2ical->apptSubType == 0x1)) { icaltime = get_icaldate_from_FILETIME(exchange2ical->apptEndWhole); prop = icalproperty_new_dtend(icaltime); icalcomponent_add_property(exchange2ical->vevent, prop); } else { if (exchange2ical->TimeZoneDesc) { icaltime = get_icaltime_from_FILETIME(exchange2ical->apptEndWhole); prop = icalproperty_new_dtend(icaltime); icalcomponent_add_property(exchange2ical->vevent, prop); tzid = icalparameter_new_tzid(exchange2ical->TimeZoneDesc); icalproperty_add_parameter(prop, tzid); } else { icaltime = get_icaltime_from_FILETIME_UTC(exchange2ical->apptEndWhole); prop = icalproperty_new_dtend(icaltime); icalcomponent_add_property(exchange2ical->vevent, prop); } } } void ical_property_DTSTAMP(struct exchange2ical *exchange2ical) { icalproperty *prop; struct icaltimetype icaltime; struct tm *tm; icalparameter *tzid; time_t t; /* Sanity check */ /*If OwnerCriticalChange field is null, get time system time*/ if (!exchange2ical->OwnerCriticalChange) { t=time(NULL); tm = gmtime(&t); icaltime = get_icaltimetype_from_tm_UTC(tm); prop = icalproperty_new_dtstamp(icaltime); icalcomponent_add_property(exchange2ical->vevent, prop); return; } else { icaltime = get_icaltime_from_FILETIME_UTC(exchange2ical->OwnerCriticalChange); prop = icalproperty_new_dtstamp(icaltime); icalcomponent_add_property(exchange2ical->vevent, prop); if (exchange2ical->TimeZoneDesc) { tzid = icalparameter_new_tzid(exchange2ical->TimeZoneDesc); icalproperty_add_parameter(prop, tzid); } } } void ical_property_DESCRIPTION(struct exchange2ical *exchange2ical) { icalproperty *prop; if (exchange2ical->method == ICAL_METHOD_REPLY) return; if (!exchange2ical->body) return; prop = icalproperty_new_description(exchange2ical->body); icalcomponent_add_property(exchange2ical->vevent, prop); } void ical_property_EXDATE(struct exchange2ical *exchange2ical) { uint32_t i; uint32_t j; uint8_t modified; struct icaltimetype icaltime; struct icaltimetype dttime; icalproperty *prop; struct RecurrencePattern *pat = exchange2ical->RecurrencePattern; /* Sanity check */ if (exchange2ical->Recurring && (*exchange2ical->Recurring == 0x0)) return; if (!pat) return; if (!pat->DeletedInstanceCount) return; for (i = 0; i < pat->DeletedInstanceCount; i++) { modified=0; if(pat->ModifiedInstanceDates && pat->ModifiedInstanceCount){ for(j=0; j < pat->ModifiedInstanceCount; j++){ if(pat->ModifiedInstanceDates[j]==pat->DeletedInstanceDates[i]){ modified=1; break; } } } /* If this is an all-day appointment */ if (!modified && exchange2ical->apptSubType && (*exchange2ical->apptSubType == 0x1)) { struct tm tm; tm = get_tm_from_minutes_UTC(pat->DeletedInstanceDates[i]); icaltime= get_icaldate_from_tm(&tm); prop = icalproperty_new_exdate(icaltime); icalcomponent_add_property(exchange2ical->vevent, prop); } else if (!modified){ /* number of minutes between midnight of the specified * day and midnight, January 1, 1601 */ struct tm tm; tm = get_tm_from_minutes_UTC(pat->DeletedInstanceDates[i]); icaltime= get_icaltimetype_from_tm(&tm); if (exchange2ical->TimeZoneDesc) { /*Get time from dtstart*/ if (exchange2ical->apptEndWhole){ dttime = get_icaltime_from_FILETIME(exchange2ical->apptStartWhole); icaltime.hour = dttime.hour; icaltime.minute = dttime.minute; } prop = icalproperty_new_exdate(icaltime); icalcomponent_add_property(exchange2ical->vevent, prop); icalparameter *tzid = icalparameter_new_tzid(exchange2ical->TimeZoneDesc); icalproperty_add_parameter(prop, tzid); } else { /*Get time from dtstart*/ icaltime.is_utc = 1; if (exchange2ical->apptEndWhole){ dttime = get_icaltime_from_FILETIME_UTC(exchange2ical->apptStartWhole); icaltime.hour = dttime.hour; icaltime.minute = dttime.minute; } prop = icalproperty_new_exdate(icaltime); icalcomponent_add_property(exchange2ical->vevent, prop); } } } } void ical_property_LAST_MODIFIED(struct exchange2ical *exchange2ical) { icalproperty *prop; struct icaltimetype icaltime; icalparameter *tzid; /* Sanity check */ if (!exchange2ical->LastModified) return; if (exchange2ical->TimeZoneDesc) { icaltime=get_icaltime_from_FILETIME(exchange2ical->LastModified); prop = icalproperty_new_lastmodified(icaltime); tzid = icalparameter_new_tzid(exchange2ical->TimeZoneDesc); icalproperty_add_parameter(prop, tzid); } else { icaltime=get_icaltime_from_FILETIME_UTC(exchange2ical->LastModified); prop = icalproperty_new_lastmodified(icaltime); } icalcomponent_add_property(exchange2ical->vevent, prop); } void ical_property_LOCATION(struct exchange2ical *exchange2ical) { icalproperty *prop; /* Sanity check */ if (!exchange2ical->Location) return; prop = icalproperty_new_location(exchange2ical->Location); icalcomponent_add_property(exchange2ical->vevent, prop); } void ical_property_ORGANIZER(struct exchange2ical *exchange2ical) { const char *smtp; const char *display_name; uint32_t *RecipientFlags; uint32_t *RecipientType; uint32_t i; struct SRowSet *SRowSet; /* Sanity check */ if (!exchange2ical->apptStateFlags) return; if (!(*exchange2ical->apptStateFlags & 0x1)) return; SRowSet = &(exchange2ical->Recipients.SRowSet); /* Loop over the recipient table */ for (i = 0; i < SRowSet->cRows; i++) { smtp = (const char *) octool_get_propval(&(SRowSet->aRow[i]), PR_SMTP_ADDRESS); display_name = (const char *) octool_get_propval(&(SRowSet->aRow[i]), PR_RECIPIENT_DISPLAY_NAME); RecipientFlags = (uint32_t *) octool_get_propval(&(SRowSet->aRow[i]), PR_RECIPIENT_FLAGS); RecipientType = (uint32_t *) octool_get_propval(&(SRowSet->aRow[i]), PR_RECIPIENT_TYPE); if (RecipientFlags && !(*RecipientFlags & 0x20) && ((*RecipientFlags & 0x2) || (RecipientType && !*RecipientType))) { icalproperty *prop; icalparameter *cn; if (smtp) { char *mailtoURL; mailtoURL = talloc_strdup(exchange2ical->mem_ctx, "mailto:"); mailtoURL = talloc_strdup_append(mailtoURL, smtp); prop = icalproperty_new_organizer(mailtoURL); icalcomponent_add_property(exchange2ical->vevent, prop); talloc_free(mailtoURL); } else { prop = icalproperty_new_organizer("invalid:nomail"); icalcomponent_add_property(exchange2ical->vevent, prop); } if (display_name) { cn = icalparameter_new_cn(display_name); icalproperty_add_parameter(prop, cn); } } } } void ical_property_PRIORITY(struct exchange2ical *exchange2ical) { icalproperty *prop; /* Sanity check */ if (!exchange2ical->Importance) return; switch (*exchange2ical->Importance) { case 0x00000000: prop = icalproperty_new_priority(9); break; case 0x00000001: prop = icalproperty_new_priority(5); break; case 0x00000002: prop = icalproperty_new_priority(1); break; default: prop = icalproperty_new_priority(5); } icalcomponent_add_property(exchange2ical->vevent, prop); } void ical_property_RRULE_Daily(struct exchange2ical *exchange2ical) { struct icalrecurrencetype recurrence; icalproperty *prop; struct RecurrencePattern *pat = exchange2ical->RecurrencePattern; icalrecurrencetype_clear(&recurrence); recurrence.freq = ICAL_DAILY_RECURRENCE; recurrence.interval = (pat->Period / 1440); if (pat->EndType == END_AFTER_N_OCCURRENCES || pat->EndType == END_AFTER_DATE) { recurrence.count = pat->OccurrenceCount; } prop = icalproperty_new_rrule(recurrence); icalcomponent_add_property(exchange2ical->vevent, prop); } void ical_property_RRULE_Weekly(struct exchange2ical *exchange2ical) { struct icalrecurrencetype recurrence; icalproperty *prop; struct RecurrencePattern *pat = exchange2ical->RecurrencePattern; uint32_t rdfDaysBitmask = pat->PatternTypeSpecific.WeekRecurrencePattern; short idx = 0; icalrecurrencetype_clear(&recurrence); recurrence.freq = ICAL_WEEKLY_RECURRENCE; recurrence.interval = pat->Period; if(pat->Period > 1){ switch(pat->FirstDOW){ case FirstDOW_Sunday: recurrence.week_start=ICAL_SUNDAY_WEEKDAY; break; case FirstDOW_Monday: recurrence.week_start=ICAL_MONDAY_WEEKDAY; break; case FirstDOW_Tuesday: recurrence.week_start=ICAL_TUESDAY_WEEKDAY; break; case FirstDOW_Wednesday: recurrence.week_start=ICAL_WEDNESDAY_WEEKDAY; break; case FirstDOW_Thursday: recurrence.week_start=ICAL_THURSDAY_WEEKDAY; break; case FirstDOW_Friday: recurrence.week_start=ICAL_FRIDAY_WEEKDAY; break; case FirstDOW_Saturday: recurrence.week_start=ICAL_SATURDAY_WEEKDAY; break; } } if (rdfDaysBitmask & Su) { recurrence.by_day[idx] = ICAL_SUNDAY_WEEKDAY; ++idx; } if (rdfDaysBitmask & M) { recurrence.by_day[idx] = ICAL_MONDAY_WEEKDAY; ++idx; } if (rdfDaysBitmask & Tu) { recurrence.by_day[idx] = ICAL_TUESDAY_WEEKDAY; ++idx; } if (rdfDaysBitmask & W) { recurrence.by_day[idx] = ICAL_WEDNESDAY_WEEKDAY; ++idx; } if (rdfDaysBitmask & Th) { recurrence.by_day[idx] = ICAL_THURSDAY_WEEKDAY; ++idx; } if (rdfDaysBitmask & F) { recurrence.by_day[idx] = ICAL_FRIDAY_WEEKDAY; ++idx; } if (rdfDaysBitmask & Sa) { recurrence.by_day[idx] = ICAL_FRIDAY_WEEKDAY; ++idx; } recurrence.by_day[idx] = ICAL_RECURRENCE_ARRAY_MAX; if (pat->EndType == END_AFTER_N_OCCURRENCES || pat->EndType == END_AFTER_DATE) { recurrence.count = pat->OccurrenceCount; } prop = icalproperty_new_rrule(recurrence); icalcomponent_add_property(exchange2ical->vevent, prop); } void ical_property_RRULE_Monthly(struct exchange2ical *exchange2ical) { struct icalrecurrencetype recurrence; icalproperty *prop; struct RecurrencePattern *pat = exchange2ical->RecurrencePattern; uint32_t day = pat->PatternTypeSpecific.Day; icalrecurrencetype_clear(&recurrence); recurrence.freq = ICAL_MONTHLY_RECURRENCE; recurrence.interval = pat->Period; if (day == 0x0000001F) { recurrence.by_month_day[0] = -1; } else { recurrence.by_month_day[0] = day; } recurrence.by_month_day[1] = ICAL_RECURRENCE_ARRAY_MAX; if (pat->EndType == END_AFTER_N_OCCURRENCES || pat->EndType == END_AFTER_DATE) { recurrence.count = pat->OccurrenceCount; } prop = icalproperty_new_rrule(recurrence); icalcomponent_add_property(exchange2ical->vevent, prop); } void ical_property_RRULE_NthMonthly(struct exchange2ical *exchange2ical) { struct icalrecurrencetype recurrence; icalproperty *prop; struct RecurrencePattern *pat = exchange2ical->RecurrencePattern; uint32_t rdfDaysBitmask = pat->PatternTypeSpecific.MonthRecurrencePattern.WeekRecurrencePattern; short idx = 0; enum RecurrenceN setpos = pat->PatternTypeSpecific.MonthRecurrencePattern.N; icalrecurrencetype_clear(&recurrence); recurrence.freq = ICAL_MONTHLY_RECURRENCE; recurrence.interval = pat->Period; if (rdfDaysBitmask & Su) { recurrence.by_day[idx] = ICAL_SUNDAY_WEEKDAY; ++idx; } if (rdfDaysBitmask & M) { recurrence.by_day[idx] = ICAL_MONDAY_WEEKDAY; ++idx; } if (rdfDaysBitmask & Tu) { recurrence.by_day[idx] = ICAL_TUESDAY_WEEKDAY; ++idx; } if (rdfDaysBitmask & W) { recurrence.by_day[idx] = ICAL_WEDNESDAY_WEEKDAY; ++idx; } if (rdfDaysBitmask & Th) { recurrence.by_day[idx] = ICAL_THURSDAY_WEEKDAY; ++idx; } if (rdfDaysBitmask & F) { recurrence.by_day[idx] = ICAL_FRIDAY_WEEKDAY; ++idx; } if (rdfDaysBitmask & Sa) { recurrence.by_day[idx] = ICAL_FRIDAY_WEEKDAY; ++idx; } recurrence.by_day[idx] = ICAL_RECURRENCE_ARRAY_MAX; if (setpos == RecurrenceN_First) { recurrence.by_set_pos[0] = 1; recurrence.by_set_pos[1] = ICAL_RECURRENCE_ARRAY_MAX; } else if (setpos == RecurrenceN_Second) { recurrence.by_set_pos[0] = 2; recurrence.by_set_pos[1] = ICAL_RECURRENCE_ARRAY_MAX; } else if (setpos == RecurrenceN_Third) { recurrence.by_set_pos[0] = 3; recurrence.by_set_pos[1] = ICAL_RECURRENCE_ARRAY_MAX; } else if (setpos == RecurrenceN_Fourth) { recurrence.by_set_pos[0] = 4; recurrence.by_set_pos[1] = ICAL_RECURRENCE_ARRAY_MAX; } else if (setpos == RecurrenceN_Last) { recurrence.by_set_pos[0] = -1; recurrence.by_set_pos[1] = ICAL_RECURRENCE_ARRAY_MAX; } if (pat->EndType == END_AFTER_N_OCCURRENCES || pat->EndType == END_AFTER_DATE) { recurrence.count = pat->OccurrenceCount; } prop = icalproperty_new_rrule(recurrence); icalcomponent_add_property(exchange2ical->vevent, prop); } void ical_property_RRULE_Yearly(struct exchange2ical *exchange2ical) { struct icalrecurrencetype recurrence; icalproperty *prop; struct RecurrencePattern *pat = exchange2ical->RecurrencePattern; uint32_t day = pat->PatternTypeSpecific.Day; struct icaltimetype icaltime; icalrecurrencetype_clear(&recurrence); recurrence.freq = ICAL_YEARLY_RECURRENCE; recurrence.interval = (pat->Period / 12); if (day == 0x0000001F) { recurrence.by_month_day[0] = -1; } else { recurrence.by_month_day[0] = day; } recurrence.by_month_day[1] = ICAL_RECURRENCE_ARRAY_MAX; icaltime = get_icaltime_from_FILETIME_UTC(exchange2ical->apptStartWhole); recurrence.by_month[0] = icaltime.month; recurrence.by_month[1] = ICAL_RECURRENCE_ARRAY_MAX; if (pat->EndType == END_AFTER_N_OCCURRENCES || pat->EndType == END_AFTER_DATE) { recurrence.count = pat->OccurrenceCount; } prop = icalproperty_new_rrule(recurrence); icalcomponent_add_property(exchange2ical->vevent, prop); } void ical_property_RRULE_NthYearly(struct exchange2ical *exchange2ical) { struct icalrecurrencetype recurrence; icalproperty *prop; struct RecurrencePattern *pat = exchange2ical->RecurrencePattern; uint32_t rdfDaysBitmask = pat->PatternTypeSpecific.MonthRecurrencePattern.WeekRecurrencePattern; short idx = 0; enum RecurrenceN setpos = pat->PatternTypeSpecific.MonthRecurrencePattern.N; struct icaltimetype icaltime; icalrecurrencetype_clear(&recurrence); recurrence.freq = ICAL_YEARLY_RECURRENCE; recurrence.interval = (pat->Period / 12); if (rdfDaysBitmask & Su) { recurrence.by_day[idx] = ICAL_SUNDAY_WEEKDAY; ++idx; } if (rdfDaysBitmask & M) { recurrence.by_day[idx] = ICAL_MONDAY_WEEKDAY; ++idx; } if (rdfDaysBitmask & Tu) { recurrence.by_day[idx] = ICAL_TUESDAY_WEEKDAY; ++idx; } if (rdfDaysBitmask & W) { recurrence.by_day[idx] = ICAL_WEDNESDAY_WEEKDAY; ++idx; } if (rdfDaysBitmask & Th) { recurrence.by_day[idx] = ICAL_THURSDAY_WEEKDAY; ++idx; } if (rdfDaysBitmask & F) { recurrence.by_day[idx] = ICAL_FRIDAY_WEEKDAY; ++idx; } if (rdfDaysBitmask & Sa) { recurrence.by_day[idx] = ICAL_FRIDAY_WEEKDAY; ++idx; } recurrence.by_day[idx] = ICAL_RECURRENCE_ARRAY_MAX; if (setpos == RecurrenceN_First) { recurrence.by_set_pos[0] = 1; recurrence.by_set_pos[1] = ICAL_RECURRENCE_ARRAY_MAX; } else if (setpos == RecurrenceN_Second) { recurrence.by_set_pos[0] = 2; recurrence.by_set_pos[1] = ICAL_RECURRENCE_ARRAY_MAX; } else if (setpos == RecurrenceN_Third) { recurrence.by_set_pos[0] = 3; recurrence.by_set_pos[1] = ICAL_RECURRENCE_ARRAY_MAX; } else if (setpos == RecurrenceN_Fourth) { recurrence.by_set_pos[0] = 4; recurrence.by_set_pos[1] = ICAL_RECURRENCE_ARRAY_MAX; } else if (setpos == RecurrenceN_Last) { recurrence.by_set_pos[0] = -1; recurrence.by_set_pos[1] = ICAL_RECURRENCE_ARRAY_MAX; } icaltime = get_icaltime_from_FILETIME(exchange2ical->apptStartWhole); recurrence.by_month[0] = icaltime.month; recurrence.by_month[1] = ICAL_RECURRENCE_ARRAY_MAX; if (pat->EndType == END_AFTER_N_OCCURRENCES || pat->EndType == END_AFTER_DATE) { recurrence.count = pat->OccurrenceCount; } prop = icalproperty_new_rrule(recurrence); icalcomponent_add_property(exchange2ical->vevent, prop); } void ical_property_RRULE(struct exchange2ical *exchange2ical) { struct RecurrencePattern *pat; /* Sanity check */ if (!(exchange2ical->RecurrencePattern)) return; pat = exchange2ical->RecurrencePattern; switch(pat->PatternType) { case PatternType_Day: ical_property_RRULE_Daily(exchange2ical); break; case PatternType_Week: ical_property_RRULE_Weekly(exchange2ical); break; case PatternType_Month: if ((pat->Period % 12 ) == 0) { ical_property_RRULE_Yearly(exchange2ical); } else { ical_property_RRULE_Monthly(exchange2ical); } break; case PatternType_MonthNth: if ((pat->Period % 12 ) == 0) { ical_property_RRULE_NthYearly(exchange2ical); } else { ical_property_RRULE_NthMonthly(exchange2ical); } break; default: printf("RRULE pattern type not implemented yet!:0x%x\n", pat->PatternType); } } void ical_property_RRULE_daylight_standard(icalcomponent* component , struct SYSTEMTIME st) { struct icalrecurrencetype recurrence; icalproperty *prop; icalrecurrencetype_clear(&recurrence); recurrence.freq = ICAL_YEARLY_RECURRENCE; if(st.wYear ==0x0000){ recurrence.by_month[0]=st.wMonth; /* Microsoft day of week = libIcal day of week +1; */ /* Day encode = day + occurrence*8 */ if (st.wDay==5){ /* Last occurrence of day in the month*/ recurrence.by_day[0] = -1 * (st.wDayOfWeek + 9); }else{ /* st.wDay occurrence of day in the month */ recurrence.by_day[0] = (st.wDayOfWeek + 1 + st.wDay*8); } }else{ recurrence.by_month_day[0]=st.wDay; recurrence.by_month[0]=st.wMonth; } prop = icalproperty_new_rrule(recurrence); icalcomponent_add_property(component, prop); } void ical_property_RECURRENCE_ID(struct exchange2ical *exchange2ical) { struct icaltimetype icaltime; icalproperty *prop; icalparameter *tzid; struct GlobalObjectId *GlbObjId; if (exchange2ical->ExceptionReplaceTime){ /*if parent has an all day event*/ if (exchange2ical->apptSubType && (*exchange2ical->apptSubType == 0x1)) { icaltime = get_icaldate_from_FILETIME(exchange2ical->ExceptionReplaceTime); prop = icalproperty_new_recurrenceid(icaltime); icalcomponent_add_property(exchange2ical->vevent, prop); } else { if (exchange2ical->TimeZoneDesc) { icaltime=get_icaltime_from_FILETIME(exchange2ical->ExceptionReplaceTime); prop = icalproperty_new_recurrenceid(icaltime); icalcomponent_add_property(exchange2ical->vevent, prop); tzid = icalparameter_new_tzid(exchange2ical->TimeZoneDesc); icalproperty_add_parameter(prop, tzid); } else { icaltime = get_icaltime_from_FILETIME_UTC(exchange2ical->ExceptionReplaceTime); prop = icalproperty_new_recurrenceid(icaltime); icalcomponent_add_property(exchange2ical->vevent, prop); } } } else if (exchange2ical->GlobalObjectId){ GlbObjId = get_GlobalObjectId(exchange2ical->mem_ctx, exchange2ical->GlobalObjectId); if(GlbObjId){ icaltime=get_icaldate_from_GlobalObjectId(GlbObjId); prop = icalproperty_new_recurrenceid(icaltime); icalcomponent_add_property(exchange2ical->vevent, prop); talloc_free(GlbObjId); } } } void ical_property_RESOURCES(struct exchange2ical *exchange2ical) { char *NonSendableBcc = NULL; icalproperty *prop; /* Sanity check */ if (!exchange2ical->NonSendableBcc) return; NonSendableBcc = talloc_strdup(exchange2ical->mem_ctx, exchange2ical->NonSendableBcc); all_string_sub(NonSendableBcc, ";", ",", 0); prop = icalproperty_new_resources(NonSendableBcc); icalcomponent_add_property(exchange2ical->vevent, prop); talloc_free(NonSendableBcc); } void ical_property_SEQUENCE(struct exchange2ical *exchange2ical) { icalproperty *prop; if (!exchange2ical->Sequence) { prop = icalproperty_new_sequence(0); } else { prop = icalproperty_new_sequence(*(exchange2ical->Sequence)); } icalcomponent_add_property(exchange2ical->vevent, prop); } void ical_property_SUMMARY(struct exchange2ical *exchange2ical) { icalproperty *prop; icalparameter *language; if (exchange2ical->Subject) { prop = icalproperty_new_summary(exchange2ical->Subject); } else { prop = icalproperty_new_summary(""); } if (exchange2ical->MessageLocaleId) { const char *langtag = mapi_get_locale_from_lcid( *(exchange2ical->MessageLocaleId) ); language = icalparameter_new_language( langtag ); icalproperty_add_parameter(prop, language); } icalcomponent_add_property(exchange2ical->vevent, prop); } void ical_property_TRANSP(struct exchange2ical *exchange2ical) { icalproperty *prop; /* Sanity check */ if (!exchange2ical->BusyStatus) return; switch (*exchange2ical->BusyStatus) { case 0x00000000: prop = icalproperty_new_transp(ICAL_TRANSP_TRANSPARENT); break; case 0x00000001: case 0x00000002: case 0x00000003: prop = icalproperty_new_transp(ICAL_TRANSP_OPAQUE); break; default: prop = icalproperty_new_transp(ICAL_TRANSP_NONE); } icalcomponent_add_property(exchange2ical->vevent, prop); } void ical_property_TRIGGER(struct exchange2ical *exchange2ical) { struct icaltriggertype duration; icalproperty *prop; if (!exchange2ical->ReminderDelta) return; if (*exchange2ical->ReminderDelta == 0x5AE980E1) { duration = icaltriggertype_from_int(-15 * 60); prop = icalproperty_new_trigger(duration); icalcomponent_add_property(exchange2ical->valarm, prop); } else { duration = icaltriggertype_from_int(*(exchange2ical->ReminderDelta) * -1 * 60); prop = icalproperty_new_trigger(duration); icalcomponent_add_property(exchange2ical->valarm, prop); } } #define GLOBAL_OBJECT_ID_DATA_START "\x76\x43\x61\x6c\x2d\x55\x69\x64\x01\x00\x00\x00" void ical_property_UID(struct exchange2ical *exchange2ical) { uint32_t i; const char *uid; char* outstr; struct GlobalObjectId *GlbObjId; icalproperty *prop; outstr = talloc_strdup(exchange2ical->mem_ctx, ""); if(exchange2ical->GlobalObjectId){ GlbObjId = get_GlobalObjectId(exchange2ical->mem_ctx, exchange2ical->GlobalObjectId); } if (exchange2ical->GlobalObjectId && (exchange2ical->GlobalObjectId->cb >= 36) && GlbObjId) { if (GlbObjId->Size >= 16 && (0 == memcmp(GlbObjId->Data, GLOBAL_OBJECT_ID_DATA_START, 12))) { fflush(0); for (i = 12; i < exchange2ical->GlobalObjectId->cb; i++) { char objID[6]; snprintf(objID, 6, "%.2X", exchange2ical->GlobalObjectId->lpb[i]); outstr = talloc_strdup_append(outstr, objID); } uid = (const char *)&(GlbObjId->Data[13]); outstr = talloc_strdup_append(outstr, uid); } else { fflush(0); for (i = 0; i < 16; i++) { char objID[6]; snprintf(objID, 6, "%.2X", exchange2ical->GlobalObjectId->lpb[i]); outstr = talloc_strdup_append(outstr, objID); } /* YH, YL, Month and D must be set to 0 */ outstr = talloc_strdup_append(outstr, "00000000"); for (i = 20; i < exchange2ical->GlobalObjectId->cb; i++) { char objID[6]; snprintf(objID, 6, "%.2X", exchange2ical->GlobalObjectId->lpb[i]); outstr = talloc_strdup_append(outstr, objID); } } talloc_free(GlbObjId); } else { char objID[32]; snprintf(objID, 32, "%i", exchange2ical->idx); outstr = talloc_strdup(outstr, objID); } prop = icalproperty_new_uid(outstr); icalcomponent_add_property(exchange2ical->vevent, prop); talloc_free(outstr); } static icalproperty * ical_property_add_x_property_value(icalcomponent *parent, const char *propname, const char *value) { icalproperty *prop; icalvalue *icalText; /* Sanity checks */ if (!parent) return NULL; if (!propname) return NULL; if (!value) return NULL; icalText = icalvalue_new_text(value); prop = icalproperty_new_x(icalvalue_as_ical_string(icalText)); icalvalue_free(icalText); icalproperty_set_x_name(prop, propname); icalcomponent_add_property(parent, prop); return prop; } void ical_property_X_ALT_DESC(struct exchange2ical *exchange2ical) { icalproperty *prop; icalparameter *param; /*sanity check */ if(!exchange2ical->bodyHTML) return; prop = ical_property_add_x_property_value(exchange2ical->vevent, "X-ALT-DESC",exchange2ical->bodyHTML); param = icalparameter_new_fmttype("text/html"); icalproperty_add_parameter(prop, param); } void ical_property_X_MICROSOFT_CDO_ATTENDEE_CRITICAL_CHANGE(struct exchange2ical *exchange2ical) { struct tm *tm; char outstr[200]; /* Sanity check */ if (!exchange2ical->AttendeeCriticalChange) return; tm = get_tm_from_FILETIME(exchange2ical->AttendeeCriticalChange); if (tm) { strftime(outstr, sizeof(outstr), "%Y%m%dT%H%M%SZ", tm); ical_property_add_x_property_value(exchange2ical->vevent, "X-MICROSOFT-CDO-ATTENDEE-CRITICAL-CHANGE", outstr); } } void ical_property_X_MICROSOFT_CDO_BUSYSTATUS(struct exchange2ical *exchange2ical) { /*sanity check*/ if(!exchange2ical->BusyStatus) return; switch (*exchange2ical->BusyStatus) { case 0x00000000: ical_property_add_x_property_value(exchange2ical->vevent, "X-MICROSOFT-CDO-BUSYSTATUS", "FREE"); break; case 0x00000001: ical_property_add_x_property_value(exchange2ical->vevent, "X-MICROSOFT-CDO-BUSYSTATUS", "TENTATIVE"); break; case 0x00000002: ical_property_add_x_property_value(exchange2ical->vevent, "X-MICROSOFT-CDO-BUSYSTATUS", "BUSY"); break; case 0x00000003: ical_property_add_x_property_value(exchange2ical->vevent, "X-MICROSOFT-CDO-BUSYSTATUS", "OOF"); break; } } void ical_property_X_MICROSOFT_MSNCALENDAR_IMPORTANCE(struct exchange2ical *exchange2ical) { /* Sanity check */ if (!exchange2ical->Importance) return; switch (*exchange2ical->Importance) { case 0x00000000: ical_property_add_x_property_value(exchange2ical->vevent, "X-MICROSOFT-MSNCALENDAR-IMPORTANCE", "0"); break; case 0x00000001: ical_property_add_x_property_value(exchange2ical->vevent, "X-MICROSOFT-MSNCALENDAR-IMPORTANCE", "1"); break; case 0x00000002: ical_property_add_x_property_value(exchange2ical->vevent, "X-MICROSOFT-MSNCALENDAR-IMPORTANCE", "2"); break; } } void ical_property_X_MICROSOFT_CDO_INTENDEDSTATUS(struct exchange2ical *exchange2ical) { if (!exchange2ical->IntendedBusyStatus) return; switch (*exchange2ical->IntendedBusyStatus) { case 0x00000000: ical_property_add_x_property_value(exchange2ical->vevent, "X-MICROSOFT-CDO-INTENDEDSTATUS", "FREE"); break; case 0x00000001: ical_property_add_x_property_value(exchange2ical->vevent, "X-MICROSOFT-CDO-INTENDEDSTATUS", "TENTATIVE"); break; case 0x00000002: ical_property_add_x_property_value(exchange2ical->vevent, "X-MICROSOFT-CDO-INTENDEDSTATUS", "BUSY"); break; case 0x00000003: ical_property_add_x_property_value(exchange2ical->vevent, "X-MICROSOFT-CDO-INTENDEDSTATUS", "OOF"); break; } } void ical_property_X_MICROSOFT_CDO_OWNERAPPTID(struct exchange2ical *exchange2ical) { char outstr[200]; /* Sanity check */ if (!exchange2ical->OwnerApptId) return; snprintf(outstr, 200, "%d", *(exchange2ical->OwnerApptId)); ical_property_add_x_property_value(exchange2ical->vevent, "X-MICROSOFT-CDO-OWNERAPPTID", outstr); } void ical_property_X_MICROSOFT_CDO_OWNER_CRITICAL_CHANGE(struct exchange2ical *exchange2ical) { struct tm *tm; char outstr[200]; /* Sanity check */ if (!exchange2ical->OwnerCriticalChange) return; tm = get_tm_from_FILETIME(exchange2ical->OwnerCriticalChange); if (tm) { strftime(outstr, sizeof(outstr), "%Y%m%dT%H%M%SZ", tm); ical_property_add_x_property_value(exchange2ical->vevent, "X-MICROSOFT-CDO-OWNER-CRITICAL-CHANGE", outstr); } } void ical_property_X_MICROSOFT_CDO_REPLYTIME(struct exchange2ical *exchange2ical) { struct tm *tm; char outstr[200]; /* Sanity check */ if (!exchange2ical->apptReplyTime) return; tm = get_tm_from_FILETIME(exchange2ical->apptReplyTime); if (tm) { strftime(outstr, sizeof(outstr), "%Y%m%dT%H%M%SZ", tm); ical_property_add_x_property_value(exchange2ical->vevent, "X-MICROSOFT-CDO-REPLYTIME", outstr); } } void ical_property_X_MICROSOFT_DISALLOW_COUNTER(struct exchange2ical *exchange2ical) { /* Sanity check */ if (!exchange2ical->NotAllowPropose) return; if (*(exchange2ical->NotAllowPropose) == true) { ical_property_add_x_property_value(exchange2ical->vevent, "X-MICROSOFT-DISALLOW-COUNTER", "TRUE"); } else { ical_property_add_x_property_value(exchange2ical->vevent, "X-MICROSOFT-DISALLOW-COUNTER", "FALSE"); } } void ical_property_X_MS_OLK_ALLOWEXTERNCHECK(struct exchange2ical *exchange2ical) { /* Sanity check */ if (!exchange2ical->AllowExternCheck) return; if (*(exchange2ical->AllowExternCheck) == true) { ical_property_add_x_property_value(exchange2ical->vevent, "X-MICROSOFT-ALLOWEXTERNCHECK", "TRUE"); } else { ical_property_add_x_property_value(exchange2ical->vevent, "X-MICROSOFT-ALLOWEXTERNCHECK", "FALSE"); } } void ical_property_X_MS_OLK_APPTLASTSEQUENCE(struct exchange2ical *exchange2ical) { char outstr[20]; /* Sanity check */ if (!exchange2ical->apptLastSequence) return; snprintf(outstr, 20, "%d", *exchange2ical->apptLastSequence); ical_property_add_x_property_value(exchange2ical->vevent, "X-MS-OLK-APPTLASTSEQUENCE", outstr); } void ical_property_X_MS_OLK_APPTSEQTIME(struct exchange2ical *exchange2ical) { struct tm *tm = NULL; char outstr[200]; /* Sanity check */ if (!exchange2ical->apptSeqTime) return; tm = get_tm_from_FILETIME(exchange2ical->apptSeqTime); if (tm) { strftime(outstr, sizeof(outstr), "%Y%m%dT%H%M%SZ", tm); ical_property_add_x_property_value(exchange2ical->vevent, "X-MS-OLK-APPTSEQTIME", outstr); } } void ical_property_X_MS_OLK_AUTOFILLLOCATION(struct exchange2ical *exchange2ical) { /* Sanity check */ if (!exchange2ical->AutoFillLocation) return; if (*(exchange2ical->AutoFillLocation) == true) { ical_property_add_x_property_value(exchange2ical->vevent, "X-MS-OLK-AUTOFILLLOCATION", "TRUE"); } else { ical_property_add_x_property_value(exchange2ical->vevent, "X-MS-OLK-AUTOFILLLOCATION", "FALSE"); } } void ical_property_X_MS_OLK_AUTOSTARTCHECK(struct exchange2ical *exchange2ical) { /* Sanity check */ if (!exchange2ical->AutoStartCheck) return; if (*(exchange2ical->AutoStartCheck) == true) { ical_property_add_x_property_value(exchange2ical->vevent, "X-MS-OLK-AUTOSTARTCHECK", "TRUE"); } else { ical_property_add_x_property_value(exchange2ical->vevent, "X-MS-OLK-AUTOSTARTCHECK", "FALSE"); } } void ical_property_X_MS_OLK_COLLABORATEDOC(struct exchange2ical *exchange2ical) { /* Sanity check */ if (!exchange2ical->CollaborateDoc) return; if(!(*exchange2ical->CollaborateDoc)) return; ical_property_add_x_property_value(exchange2ical->vevent, "X-MS-OLK-COLLABORATEDOC", exchange2ical->CollaborateDoc); } void ical_property_X_MS_OLK_CONFCHECK(struct exchange2ical *exchange2ical) { /* Sanity check */ if (!exchange2ical->ConfCheck) return; ical_property_add_x_property_value(exchange2ical->vevent, "X-MS-OLK-CONFCHECK", (*exchange2ical->ConfCheck == true) ? "TRUE" : "FALSE"); } void ical_property_X_MS_OLK_CONFTYPE(struct exchange2ical *exchange2ical) { char outstr[20]; /* Sanity check */ if (!exchange2ical->ConfType) return; snprintf(outstr, 20, "%d", *exchange2ical->ConfType); ical_property_add_x_property_value(exchange2ical->vevent, "X-MS-OLK-CONFTYPE", outstr); } void ical_property_X_MS_OLK_DIRECTORY(struct exchange2ical *exchange2ical) { /*Sanity Check*/ if(!exchange2ical->Directory) return; if(!(*exchange2ical->Directory)) return; ical_property_add_x_property_value(exchange2ical->vevent, "X-MS-OLK-DIRECTORY", exchange2ical->Directory); } void ical_property_X_MS_OLK_MWSURL(struct exchange2ical *exchange2ical) { /*Sanity Check*/ if(!exchange2ical->MWSURL) return; ical_property_add_x_property_value(exchange2ical->vevent, "X-MS-OLK-MWSURL", exchange2ical->MWSURL); } void ical_property_X_MS_OLK_NETSHOWURL(struct exchange2ical *exchange2ical) { /*Sanity Check*/ if(!exchange2ical->NetShowURL) return; if(!(*exchange2ical->NetShowURL)) return; ical_property_add_x_property_value(exchange2ical->vevent, "X-MS-OLK-NETSHOWURL", exchange2ical->NetShowURL); } void ical_property_X_MS_OLK_ONLINEPASSWORD(struct exchange2ical *exchange2ical) { /*Sanity Check*/ if(!exchange2ical->OnlinePassword) return; if(!(*exchange2ical->OnlinePassword)) return; ical_property_add_x_property_value(exchange2ical->vevent, "X-MS-OLK-ONLINEPASSWORD", exchange2ical->OnlinePassword); } void ical_property_X_MS_OLK_ORGALIAS(struct exchange2ical *exchange2ical) { /* Sanity check */ if(!exchange2ical->OrgAlias) return; if(!(*exchange2ical->OrgAlias)) return; ical_property_add_x_property_value(exchange2ical->vevent, "X-MS-OLK-ORGALIAS", exchange2ical->OrgAlias); } // TODO: double check this - need an example. void ical_property_X_MS_OLK_SENDER(struct exchange2ical *exchange2ical) { icalproperty *prop; icalparameter *param; char outstr[200]; /* Sanity check */ if (!exchange2ical->apptStateFlags) return; if (!(*exchange2ical->apptStateFlags & 0x1)) return; if (!exchange2ical->SenderName) return; if (exchange2ical->SenderEmailAddress) { snprintf(outstr, 200, "mailto:%s",exchange2ical->SenderEmailAddress); prop = icalproperty_new_x(outstr); } else { prop = icalproperty_new_x("invalid:nomail"); } icalproperty_set_x_name(prop, "X-MS-OLK-SENDER"); icalcomponent_add_property(exchange2ical->vevent, prop); param = icalparameter_new_cn(exchange2ical->SenderName); icalproperty_add_parameter(prop, param); } openchange-2.0/libexchange2ical/exchange2ical_utils.c000066400000000000000000000345241223057412600227410ustar00rootroot00000000000000/* Common conversion routines for exchange2ical OpenChange Project Copyright (C) Julien Kerihuel 2008 This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see . */ #include "libexchange2ical/libexchange2ical.h" static struct ical_method ical_method[] = { { ICAL_METHOD_PUBLISH, ICAL_PARTSTAT_NONE, "IPM.Appointment" }, { ICAL_METHOD_REQUEST, ICAL_PARTSTAT_NONE, "IPM.Schedule.Meeting.Request" }, { ICAL_METHOD_REPLY, ICAL_PARTSTAT_ACCEPTED, "IPM.Schedule.Meeting.Resp.Pos" }, { ICAL_METHOD_REPLY, ICAL_PARTSTAT_TENTATIVE,"IPM.Schedule.Meeting.Resp.Tent"}, { ICAL_METHOD_REPLY, ICAL_PARTSTAT_DECLINED, "IPM.Schedule.Meeting.Resp.Neg" }, { ICAL_METHOD_CANCEL, ICAL_PARTSTAT_NONE, "IPM.Schedule.Meeting.Canceled" }, { ICAL_METHOD_NONE, ICAL_PARTSTAT_NONE, NULL } }; static struct ical_calendartype ical_calendartype[] = { { 0x0001, "Gregorian" }, { 0x0002, "Gregorian_us" }, { 0x0003, "Japan" }, { 0x0004, "Taiwan" }, { 0x0005, "Korean" }, { 0x0006, "Hijri" }, { 0x0007, "Thai" }, { 0x0008, "Hebrew" }, { 0x0009, "GregorianMeFrench" }, { 0x000A, "GregorianArabic" }, { 0x000B, "GregorianXlitEnglish" }, { 0x000C, "GregorianXlitFrench" }, { 0x000E, "JapanLunar" }, { 0x000F, "ChineseLunar" }, { 0x0010, "Saka" }, { 0x0011, "LunarEtoChn" }, { 0x0012, "LunarEthoKor" }, { 0x0013, "LunarRockuyou" }, { 0x0014, "KoreanLunar" }, { 0x0017, "Umalqura" }, { 0x0000, NULL } }; static struct ical_class ical_class[] = { { 0x00000000, ICAL_CLASS_PUBLIC }, { 0x00000001, ICAL_CLASS_X }, { 0x00000002, ICAL_CLASS_PRIVATE }, { 0x00000003, ICAL_CLASS_CONFIDENTIAL }, { 0x00000000, ICAL_CLASS_NONE } }; static struct ical_day ical_day[] = { { ICAL_SUNDAY_WEEKDAY, FirstDOW_Sunday, Su }, { ICAL_MONDAY_WEEKDAY, FirstDOW_Monday, M }, { ICAL_TUESDAY_WEEKDAY, FirstDOW_Tuesday, Tu }, { ICAL_WEDNESDAY_WEEKDAY, FirstDOW_Wednesday, W }, { ICAL_THURSDAY_WEEKDAY, FirstDOW_Thursday, Th }, { ICAL_FRIDAY_WEEKDAY, FirstDOW_Friday, F }, { ICAL_SATURDAY_WEEKDAY, FirstDOW_Saturday, Sa }, { ICAL_NO_WEEKDAY, 0, 0 } }; bool has_component_DAYLIGHT(struct exchange2ical *exchange2ical) { if (!exchange2ical->TimeZoneStruct) return false; if (!exchange2ical->TimeZoneStruct->stStandardDate.wYear && !exchange2ical->TimeZoneStruct->stStandardDate.wMonth && !exchange2ical->TimeZoneStruct->stStandardDate.wDayOfWeek && !exchange2ical->TimeZoneStruct->stStandardDate.wDay && !exchange2ical->TimeZoneStruct->stStandardDate.wHour && !exchange2ical->TimeZoneStruct->stStandardDate.wMinute && !exchange2ical->TimeZoneStruct->stStandardDate.wSecond && !exchange2ical->TimeZoneStruct->stStandardDate.wMilliseconds) return false; return true; } struct FILETIME get_FILETIME_from_string(const char *time) { icaltimetype icaltime; icaltime = icaltime_from_string(time); return get_FILETIME_from_icaltimetype(&icaltime); } char *get_ical_date(TALLOC_CTX *mem_ctx, struct SYSTEMTIME *time) { char *date; date = talloc_asprintf(mem_ctx, "%.4d%.2d%.2dT%.2d%.2d%.2d", time->wYear + 1601, time->wMonth, time->wDay, time->wHour, time->wMinute, time->wSecond); return date; } enum icalproperty_method get_ical_method(const char *msgclass) { uint32_t i; /* Sanity check */ if (!msgclass) return ICAL_METHOD_NONE; for (i = 0; ical_method[i].messageclass; i++) { if (!strcmp(msgclass, ical_method[i].messageclass)) { return ical_method[i].method; } } return ICAL_METHOD_NONE; } uint16_t get_exchange_calendartype(const char *CalendarType) { uint32_t i; /* Sanity check */ if (!CalendarType) return 0x0000; for (i = 0; ical_calendartype[i].type; i++) { if (strcmp(CalendarType, ical_calendartype[i].calendar)) { return ical_calendartype[i].type; } } return 0x0000; } const char *get_ical_calendartype(uint16_t CalendarType) { uint32_t i; /* Sanity check */ if (!CalendarType) return NULL; for (i = 0; ical_calendartype[i].type; i++) { if (CalendarType == ical_calendartype[i].type) { return ical_calendartype[i].calendar; } } return NULL; } enum icalparameter_partstat get_ical_partstat_from_status(uint32_t status) { enum icalparameter_partstat partstat; switch(status){ case 0x00000003: partstat = ICAL_PARTSTAT_ACCEPTED; break; case 0x00000004: partstat = ICAL_PARTSTAT_DECLINED; break; case 0x00000002: partstat = ICAL_PARTSTAT_TENTATIVE; break; default: partstat = ICAL_PARTSTAT_NONE; } return partstat; } enum icalparameter_partstat get_ical_partstat(const char *msgclass) { uint32_t i; /* Sanity check */ if (!msgclass) return ICAL_PARTSTAT_NONE; for (i = 0; ical_method[i].messageclass; i++) { if (!strcmp(msgclass, ical_method[i].messageclass)) { return ical_method[i].partstat; } } return ICAL_PARTSTAT_NONE; } enum icalproperty_class get_ical_class(uint32_t sensivity) { uint32_t i; for (i = 0; ical_class[i].classtype != ICAL_CLASS_NONE; ++i) { if (sensivity == ical_class[i].sensivity) { return ical_class[i].classtype; } } return ICAL_CLASS_NONE; } enum FirstDOW get_exchange_day_from_ical(enum icalrecurrencetype_weekday weekday) { uint32_t i; for (i = 0; ical_day[i].ical != ICAL_NO_WEEKDAY; ++i) { if (weekday == ical_day[i].ical) { return ical_day[i].exchange; } } return 0x00000000; } uint32_t get_exchange_rdfDays_from_ical(enum icalrecurrencetype_weekday weekday){ uint32_t i; for (i = 0; ical_day[i].ical != ICAL_NO_WEEKDAY; ++i) { if (weekday == ical_day[i].ical) { return ical_day[i].rdfDays; } } return 0; } struct icaltimetype get_icaltimetype_from_tm(struct tm *tm) { struct icaltimetype tt; tt.year = tm->tm_year+1900; tt.month = tm->tm_mon+1; tt.day = tm->tm_mday; tt.hour = tm->tm_hour; tt.minute = tm->tm_min; tt.second = tm->tm_sec; tt.is_utc = 0; tt.is_date = 0; tt.is_daylight = 0; tt.zone = 0; return tt; } struct icaltimetype get_icaltimetype_from_tm_UTC(struct tm *tm) { struct icaltimetype tt; tt = get_icaltimetype_from_tm(tm); tt.is_utc = 1; return tt; } struct icaltimetype get_icaldate_from_tm(struct tm *tm) { struct icaltimetype tt; tt.year = tm->tm_year+1900; tt.month = tm->tm_mon+1; tt.day = tm->tm_mday; tt.hour = 0; tt.minute = 0; tt.second = 0; tt.is_utc = 1; tt.is_date = 1; tt.is_daylight = 0; tt.zone = NULL; return tt; } struct tm *get_tm_from_FILETIME(const struct FILETIME *ft) { NTTIME time; struct timeval t; struct tm *tm; /* Sanity checks */ if (ft == NULL) return NULL; time = FILETIME_to_NTTIME(*ft); nttime_to_timeval(&t, time); tm = localtime(&t.tv_sec); return tm; } struct icaltimetype get_icaltime_from_FILETIME(const struct FILETIME *ft) { struct icaltimetype tt; NTTIME nttime; struct timeval temp_timeval; struct tm *tm; nttime = FILETIME_to_NTTIME(*ft); nttime_to_timeval(&temp_timeval, nttime); tm = localtime(&temp_timeval.tv_sec); tt.year = tm->tm_year + 1900; tt.month = tm->tm_mon + 1; tt.day = tm->tm_mday; tt.hour = tm->tm_hour; tt.minute = tm->tm_min; tt.second = tm->tm_sec; tt.is_date = 0; tt.is_utc = 0; tt.is_daylight = 0; tt.zone = NULL; return tt; } struct icaltimetype get_icaltime_from_FILETIME_UTC(const struct FILETIME *ft) { struct icaltimetype tt; NTTIME nttime; struct timeval temp_timeval; struct tm *tm; nttime = FILETIME_to_NTTIME(*ft); nttime_to_timeval(&temp_timeval, nttime); tm = gmtime(&temp_timeval.tv_sec); tt.year = tm->tm_year + 1900; tt.month = tm->tm_mon + 1; tt.day = tm->tm_mday; tt.hour = tm->tm_hour; tt.minute = tm->tm_min; tt.second = tm->tm_sec; tt.is_date = 0; tt.is_utc = 1; tt.is_daylight = 0; tt.zone = NULL; return tt; } struct icaltimetype get_icaldate_from_FILETIME(const struct FILETIME *ft) { struct icaltimetype tt; NTTIME nttime; struct timeval temp_timeval; struct tm *tm; nttime = FILETIME_to_NTTIME(*ft); nttime_to_timeval(&temp_timeval, nttime); tm = gmtime(&temp_timeval.tv_sec); tt.year = tm->tm_year + 1900; tt.month = tm->tm_mon + 1; tt.day = tm->tm_mday; if (tm->tm_hour >= 12) { /* If the time is greater than or equal to 12, and we're representing midnight, then the actual day is one less (e.g. if we're at UTC+11 timezone, then local midnight is 1300 UTC, on the day before). So we add a day. */ tt.day++; } tt.hour = 0; tt.minute = 0; tt.second = 0; tt.is_date = 1; tt.is_utc = 1; tt.is_daylight = 0; tt.zone = NULL; return tt; } struct icaltimetype get_icaldate_from_GlobalObjectId(struct GlobalObjectId *GlobalObjectId) { struct icaltimetype tt; tt.year = GlobalObjectId->YH; tt.year = tt.year <<8; tt.year |= GlobalObjectId->YL; tt.month = GlobalObjectId->Month; tt.day = GlobalObjectId->D; tt.hour = 0; tt.minute = 0; tt.second = 0; tt.is_utc = 1; tt.is_date = 1; tt.is_daylight = 0; tt.zone = NULL; return tt; } struct tm get_tm_from_minutes(uint32_t mins) { struct timeval t; struct tm tm; NTTIME nt; nt = mins; nt *= 10000000; nt *= 60; nttime_to_timeval(&t, nt); tm= *localtime(&t.tv_sec); return tm; } struct tm get_tm_from_minutes_UTC(uint32_t mins) { struct timeval t; struct tm tm; NTTIME nt; nt = mins; nt *= 10000000; nt *= 60; nttime_to_timeval(&t, nt); tm= *gmtime(&t.tv_sec); return tm; } bool compareGlobalObjectIds(struct GlobalObjectId *glb1, struct GlobalObjectId *glb2) { int i; time_t creationTime1; time_t creationTime2; /* Sanity checks */ if (!&glb1->CreationTime || !&glb2->CreationTime) return false; creationTime1=mktime(get_tm_from_FILETIME(&glb1->CreationTime)); creationTime2=mktime(get_tm_from_FILETIME(&glb2->CreationTime)); if(difftime(creationTime1, creationTime2)!=0) return false; for(i=0; i<16; i++){ if(glb1->ByteArrayID[i]!=glb2->ByteArrayID[i]) return false; } if(glb1->YH!=glb2->YH) return false; if(glb1->YL!=glb2->YL) return false; if(glb1->Month!=glb2->Month) return false; if(glb1->D!=glb2->D) return false; for(i=0; i<8; i++){ if(glb1->X[i]!=glb2->X[i]) return false; } if(glb1->Size!=glb2->Size) return false; for(i=0; iSize; i++){ if(glb1->Data[i]!=glb2->Data[i]) return false; } return true; } bool checkEvent(struct exchange2ical *exchange2ical, struct exchange2ical_check *exchange2ical_check, struct tm *aptStart) { time_t beginTime; time_t endTime; time_t dtstart; struct GlobalObjectId *GlbObjId; enum exchange2ical_flags eFlags= exchange2ical_check->eFlags; if(eFlags & EntireFlag) return true; if(eFlags & RangeFlag){ dtstart = mktime(aptStart); if(dtstart==-1) return false; if(exchange2ical_check->begin){ beginTime=mktime(exchange2ical_check->begin); if(beginTime!=-1){ if(difftime(dtstart, beginTime)<0){ return false; } } } if(exchange2ical_check->end){ endTime=mktime(exchange2ical_check->end); if(endTime!=-1){ if(difftime(endTime, dtstart)<0){ return false; } } } return true; } if(eFlags & EventFlag){ if(!exchange2ical->Sequence) return false; GlbObjId = get_GlobalObjectId(exchange2ical->mem_ctx, exchange2ical->GlobalObjectId); if(!GlbObjId || !exchange2ical_check->GlobalObjectId) return false; if (!compareGlobalObjectIds(GlbObjId, exchange2ical_check->GlobalObjectId)) return false; if(*exchange2ical->Sequence != exchange2ical_check->Sequence) return false; talloc_free(GlbObjId); return true; } if(eFlags & EventsFlag){ GlbObjId = get_GlobalObjectId(exchange2ical->mem_ctx, exchange2ical->GlobalObjectId); if(!GlbObjId || !exchange2ical_check->GlobalObjectId) return false; if (!compareGlobalObjectIds(GlbObjId, exchange2ical_check->GlobalObjectId)) return false; talloc_free(GlbObjId); return true; } return false; } #define WIN32_UNIX_EPOCH_DIFF 194074560 uint32_t get_minutes_from_icaltimetype(icaltimetype icaltime) { struct tm tm; time_t time; NTTIME nttime; struct timeval t; tm.tm_year = icaltime.year - 1900; tm.tm_mon = icaltime.month - 1; tm.tm_mday = icaltime.day; tm.tm_hour = icaltime.hour; tm.tm_min = icaltime.minute; tm.tm_sec = icaltime.second; tm.tm_isdst = 0; /* TODO: fix this properly when we implement ical2exchange */ #if !defined(__FreeBSD__) if(timezone!=0){ tm.tm_hour-=timezone/3600; } #endif time = mktime(&tm); unix_to_nt_time(&nttime, time); nttime_to_timeval(&t, nttime); return t.tv_sec/60+WIN32_UNIX_EPOCH_DIFF; } struct FILETIME get_FILETIME_from_icaltimetype(icaltimetype *tt) { struct FILETIME ft; struct tm tm; time_t time; NTTIME nttime; tm.tm_year = tt->year - 1900; tm.tm_mon = tt->month - 1; tm.tm_mday = tt->day; tm.tm_hour = tt->hour; tm.tm_min = tt->minute; tm.tm_sec = tt->second; tm.tm_isdst = 0; /* TODO: fix this properly when we implement ical2exchange */ #if !defined(__FreeBSD__) if(timezone!=0){ tm.tm_hour-=timezone/3600; } #endif time = mktime(&tm); unix_to_nt_time(&nttime, time); ft.dwHighDateTime=(uint32_t) (nttime>>32); ft.dwLowDateTime=(uint32_t) (nttime); return ft; } NTTIME FILETIME_to_NTTIME(struct FILETIME ft) { NTTIME nt; nt = ft.dwHighDateTime; nt = nt << 32; nt |= ft.dwLowDateTime; return nt; } int compare_minutes(const void *min1, const void *min2) { if( *(uint32_t *) min1 > * (uint32_t *) min2) return -1; return 1; } openchange-2.0/libexchange2ical/ical2exchange.c000066400000000000000000000333751223057412600215240ustar00rootroot00000000000000/* Common conversion routines for exchange2ical OpenChange Project Copyright (C) Julien Kerihuel 2008 This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see . */ #include "libexchange2ical/libexchange2ical.h" static void ical2exchange_get_properties(struct ical2exchange *ical2exchange, icalcomponent *vevent){ icalproperty *icalProp = NULL; icalproperty *prop = NULL; const char *xname; enum icalproperty_kind propType; icalProp=icalcomponent_get_first_property(vevent, ICAL_ANY_PROPERTY); while(icalProp!=0){ propType=icalproperty_isa(icalProp); switch (propType){ case ICAL_ATTACH_PROPERTY: if(!ical2exchange->attachEvent){ ical2exchange->attachEvent=icalcomponent_new_vevent(); } prop = icalproperty_new_clone(icalProp); icalcomponent_add_property(ical2exchange->attachEvent, prop); break; case ICAL_ATTENDEE_PROPERTY: if(!ical2exchange->attendeeEvent){ ical2exchange->attendeeEvent=icalcomponent_new_vevent(); } prop = icalproperty_new_clone(icalProp); icalcomponent_add_property(ical2exchange->attendeeEvent, prop); break; case ICAL_CATEGORIES_PROPERTY: if(!ical2exchange->categoriesEvent){ ical2exchange->categoriesEvent=icalcomponent_new_vevent(); } prop = icalproperty_new_clone(icalProp); icalcomponent_add_property(ical2exchange->categoriesEvent, prop); break; case ICAL_CLASS_PROPERTY: ical2exchange->classProp=icalProp; break; case ICAL_COMMENT_PROPERTY: ical2exchange->commentProp=icalProp; break; case ICAL_CONTACT_PROPERTY: if(!ical2exchange->contactEvent){ ical2exchange->contactEvent=icalcomponent_new_vevent(); } prop = icalproperty_new_clone(icalProp); icalcomponent_add_property(ical2exchange->contactEvent, prop); break; case ICAL_CREATED_PROPERTY: break; case ICAL_DESCRIPTION_PROPERTY: ical2exchange->descriptionProp=icalProp; break; case ICAL_DTEND_PROPERTY: ical2exchange->dtendProp=icalProp; break; case ICAL_DTSTAMP_PROPERTY: ical2exchange->dtstampProp=icalProp; break; case ICAL_DTSTART_PROPERTY: ical2exchange->dtstartProp=icalProp; break; case ICAL_DURATION_PROPERTY: ical2exchange->durationProp=icalProp; break; case ICAL_EXDATE_PROPERTY: if(!ical2exchange->exdateEvent){ ical2exchange->exdateEvent=icalcomponent_new_vevent(); } prop = icalproperty_new_clone(icalProp); ical2exchange->exdateCount ++; icalcomponent_add_property(ical2exchange->exdateEvent, prop); break; case ICAL_LASTMODIFIED_PROPERTY: break; case ICAL_LOCATION_PROPERTY: ical2exchange->locationProp=icalProp; break; case ICAL_ORGANIZER_PROPERTY: //TODO: figure out how to MS-OXOABK ical2exchange->organizerProp=icalProp; break; case ICAL_PRIORITY_PROPERTY: ical2exchange->priorityProp=icalProp; break; case ICAL_RDATE_PROPERTY: if(!ical2exchange->rdateEvent){ ical2exchange->rdateEvent=icalcomponent_new_vevent(); } prop = icalproperty_new_clone(icalProp); ical2exchange->rdateCount ++; icalcomponent_add_property(ical2exchange->rdateEvent, prop); break; case ICAL_RECURRENCEID_PROPERTY: ical2exchange->recurrenceidProp=icalProp; break; case ICAL_RESOURCES_PROPERTY: if(!ical2exchange->resourcesEvent){ ical2exchange->resourcesEvent=icalcomponent_new_vevent(); } prop = icalproperty_new_clone(icalProp); icalcomponent_add_property(ical2exchange->resourcesEvent, prop); break; case ICAL_RRULE_PROPERTY: ical2exchange->rruleProp=icalProp; break; case ICAL_SEQUENCE_PROPERTY: ical2exchange->sequenceProp=icalProp; break; case ICAL_STATUS_PROPERTY: ical2exchange->statusProp=icalProp; break; case ICAL_SUMMARY_PROPERTY: ical2exchange->summaryProp=icalProp; break; case ICAL_TRANSP_PROPERTY: ical2exchange->transpProp=icalProp; break; case ICAL_UID_PROPERTY: //TODO ical2exchange->uidProp=icalProp; break; case ICAL_X_PROPERTY: xname=icalproperty_get_x_name(icalProp); if(!strcmp(xname,"X-MICROSOFT-CDO-BUSYSTATUS")){ ical2exchange->x_busystatusProp=icalProp; } else if(!strcmp(xname,"X-MICROSOFT-MSNCALENDAR-BUSYSTATUS")){ ical2exchange->x_busystatusProp=icalProp; } else if(!strcmp(xname,"X-MICROSOFT-CDO-APPT-SEQUENCE")){ ical2exchange->x_sequenceProp=icalProp; } else if(!strcmp(xname,"X-MICROSOFT-CDO-IMPORTANCE")){ ical2exchange->x_importanceProp=icalProp; } else if(!strcmp(xname,"X-MICROSOFT-MSNCALENDAR-IMPORTANCE")){ ical2exchange->x_importanceProp=icalProp; } else if(!strcmp(xname,"X-MICROSOFT-CDO-INTENDEDSTATUS")){ ical2exchange->x_intendedProp=icalProp; } else if(!strcmp(xname,"X-MICROSOFT-MSNCALENDAR-INTENDEDSTATUS")){ ical2exchange->x_intendedProp=icalProp; } else if(!strcmp(xname,"X-MICROSOFT-CDO-OWNERAPPTID")){ ical2exchange->x_ownerapptidProp=icalProp; } else if(!strcmp(xname,"X-MICROSOFT-CDO-ATTENDEE-CRITICAL-CHANGE")){ ical2exchange->x_attendeecriticalchangeProp=icalProp; } else if(!strcmp(xname,"X-MICROSOFT-CDO-OWNER-CRITICAL-CHANGE")){ ical2exchange->x_ownercriticalchangeProp=icalProp; } else if(!strcmp(xname,"X-MICROSOFT-CDO-REPLYTIME")){ ical2exchange->x_replytimeProp=icalProp; } else if(!strcmp(xname,"X-MICROSOFT-DISALLOW-COUNTER")){ ical2exchange->x_disallowcounterProp=icalProp; } else if(!strcmp(xname,"X-MICROSOFT-ISDRAFT")){ ical2exchange->x_isdraftProp=icalProp; } else if(!strcmp(xname,"X-MS-OLK-ALLOWEXTERNCHECK")){ ical2exchange->x_allowexterncheckProp=icalProp; } else if(!strcmp(xname,"X-MS-OLK-APPTLASTSEQUENCE")){ ical2exchange->x_apptlastsequenceProp=icalProp; } else if(!strcmp(xname,"X-MS-OLK-APPTSEQTIME")){ ical2exchange->x_apptseqtimeProp=icalProp; } else if(!strcmp(xname,"X-MS-OLK-AUTOFILLLOCATION")){ ical2exchange->x_autofilllocationProp=icalProp; } else if(!strcmp(xname,"X-MS-OLK-AUTOSTARTCHECK")){ ical2exchange->x_autostartcheckProp=icalProp; } else if(!strcmp(xname,"X-MS-OLK-CONFCHECK")){ ical2exchange->x_confcheckProp=icalProp; } else if(!strcmp(xname,"X-MS-OLK-COLLABORATEDDOC")){ ical2exchange->x_collaborateddocProp=icalProp; } else if(!strcmp(xname,"X-MS-OLK-CONFTYPE")){ ical2exchange->x_conftypeProp=icalProp; } else if(!strcmp(xname,"X-MS-OLK-MWSURL")){ ical2exchange->x_mwsurlProp=icalProp; } else if(!strcmp(xname,"X-MS-OLK-NETSHOWURL")){ ical2exchange->x_netshowurlProp=icalProp; } else if(!strcmp(xname,"X-MS-OLK-ONLINEPASSWORD")){ ical2exchange->x_onlinepasswordProp=icalProp; } else if(!strcmp(xname,"X-MS-OLK-ORGALIAS")){ ical2exchange->x_orgaliasProp=icalProp; } else if(!strcmp(xname,"X-MS-OLK-ORIGINALEND")){ ical2exchange->x_originalendProp=icalProp; } else if(!strcmp(xname,"X-MS-OLK-ORIGINALSTART")){ ical2exchange->x_originalstartProp=icalProp; } break; default: break; } icalProp=icalcomponent_get_next_property(vevent, ICAL_ANY_PROPERTY); } ical2exchange->valarmEvent = icalcomponent_get_first_component(vevent,ICAL_VALARM_COMPONENT); } static void ical2exchange_convert_event(struct ical2exchange *ical2exchange) { ical2exchange_property_ATTACH(ical2exchange); // //TODO ATTENDEE, ORGANIZER, x_ms_ok_sender ical2exchange_property_CATEGORIES(ical2exchange); ical2exchange_property_CLASS(ical2exchange); ical2exchange_property_COMMENT(ical2exchange); ical2exchange_property_CONTACT(ical2exchange); ical2exchange_property_DESCRIPTION(ical2exchange); ical2exchange_property_DTSTAMP(ical2exchange); ical2exchange_property_DTSTART_DTEND(ical2exchange); ical2exchange_property_LOCATION(ical2exchange); ical2exchange_property_PRIORITY(ical2exchange); ical2exchange_property_RRULE_EXDATE_RDATE(ical2exchange); ical2exchange_property_SEQUENCE(ical2exchange); ical2exchange_property_STATUS(ical2exchange); ical2exchange_property_SUMMARY(ical2exchange); ical2exchange_property_VALARM(ical2exchange); ical2exchange_property_X_ALLOWEXTERNCHECK(ical2exchange); ical2exchange_property_X_APPTSEQTIME(ical2exchange); ical2exchange_property_X_APPTLASTSEQUENCE(ical2exchange); ical2exchange_property_X_ATTENDEE_CRITICAL_CHANGE(ical2exchange); ical2exchange_property_X_AUTOFILLLOCATION(ical2exchange); ical2exchange_property_X_AUTOSTARTCHECK(ical2exchange); ical2exchange_property_X_COLLABORATEDDOC(ical2exchange); ical2exchange_property_X_CONFCHECK(ical2exchange); ical2exchange_property_X_CONFTYPE(ical2exchange); ical2exchange_property_X_DISALLOW_COUNTER(ical2exchange); ical2exchange_property_X_INTENDEDSTATUS(ical2exchange); ical2exchange_property_X_ISDRAFT(ical2exchange); ical2exchange_property_X_MWSURL(ical2exchange); ical2exchange_property_X_NETSHOWURL(ical2exchange); ical2exchange_property_X_ONLINEPASSWORD(ical2exchange); ical2exchange_property_X_ORGALIAS(ical2exchange); ical2exchange_property_X_ORIGINALEND_ORIGINALSTART(ical2exchange); ical2exchange_property_X_OWNER_CRITICAL_CHANGE(ical2exchange); ical2exchange_property_X_OWNERAPPTID(ical2exchange); ical2exchange_property_X_REPLYTIME(ical2exchange); } static void ical2exchange_init(struct ical2exchange *ical2exchange, TALLOC_CTX *mem_ctx) { ical2exchange->mem_ctx = mem_ctx; ical2exchange->classProp = NULL; ical2exchange->commentProp = NULL; ical2exchange->descriptionProp = NULL; ical2exchange->dtendProp = NULL; ical2exchange->dtstampProp = NULL; ical2exchange->dtstartProp = NULL; ical2exchange->durationProp = NULL; ical2exchange->locationProp = NULL; ical2exchange->organizerProp = NULL; ical2exchange->priorityProp = NULL; ical2exchange->recurrenceidProp = NULL; ical2exchange->rruleProp = NULL; ical2exchange->sequenceProp = NULL; ical2exchange->statusProp = NULL; ical2exchange->summaryProp = NULL; ical2exchange->transpProp = NULL; ical2exchange->uidProp = NULL; ical2exchange->attachEvent = NULL; ical2exchange->attendeeEvent = NULL; ical2exchange->categoriesEvent = NULL; ical2exchange->contactEvent = NULL; ical2exchange->exdateEvent = NULL; ical2exchange->rdateEvent = NULL; ical2exchange->resourcesEvent = NULL; ical2exchange->valarmEvent = NULL; ical2exchange->x_busystatusProp = NULL; ical2exchange->x_sequenceProp = NULL; ical2exchange->x_importanceProp = NULL; ical2exchange->x_intendedProp= NULL; ical2exchange->x_ownerapptidProp = NULL; ical2exchange->x_attendeecriticalchangeProp = NULL; ical2exchange->x_ownercriticalchangeProp = NULL; ical2exchange->x_replytimeProp = NULL; ical2exchange->x_disallowcounterProp = NULL; ical2exchange->x_isdraftProp = NULL; ical2exchange->x_allowexterncheckProp = NULL; ical2exchange->x_apptlastsequenceProp = NULL; ical2exchange->x_apptseqtimeProp = NULL; ical2exchange->x_autofilllocationProp = NULL; ical2exchange->x_autostartcheckProp = NULL; ical2exchange->x_confcheckProp = NULL; ical2exchange->x_collaborateddocProp = NULL; ical2exchange->x_conftypeProp = NULL; ical2exchange->x_mwsurlProp = NULL; ical2exchange->x_netshowurlProp = NULL; ical2exchange->x_onlinepasswordProp = NULL; ical2exchange->x_originalstartProp = NULL; ical2exchange->x_originalendProp = NULL; ical2exchange->x_orgaliasProp = NULL; ical2exchange->lpProps = NULL; ical2exchange->rdateCount = 0 ; ical2exchange->exdateCount = 0; ical2exchange->cValues = 0; } static void ical2exchange_reset(struct ical2exchange *ical2exchange) { if(ical2exchange->attachEvent){ icalcomponent_free(ical2exchange->attachEvent); } if(ical2exchange->attendeeEvent){ icalcomponent_free(ical2exchange->attendeeEvent); } if(ical2exchange->contactEvent){ icalcomponent_free(ical2exchange->contactEvent); } if(ical2exchange->exdateEvent){ icalcomponent_free(ical2exchange->exdateEvent); } if(ical2exchange->rdateEvent){ icalcomponent_free(ical2exchange->rdateEvent); } if(ical2exchange->resourcesEvent){ icalcomponent_free(ical2exchange->resourcesEvent); } if(ical2exchange->categoriesEvent){ icalcomponent_free(ical2exchange->categoriesEvent); } ical2exchange_init(ical2exchange, NULL); } void _IcalEvent2Exchange(mapi_object_t *obj_folder, icalcomponent *vevent) { struct ical2exchange ical2exchange; TALLOC_CTX *mem_ctx; enum MAPISTATUS retval; mapi_object_t obj_message; ical2exchange.obj_message = &obj_message; ical2exchange.method=ICAL_METHOD_PUBLISH; mapi_object_init(&obj_message); /*sanity check*/ if(icalcomponent_isa(vevent) != ICAL_VEVENT_COMPONENT) return; mem_ctx = talloc_named(mapi_object_get_session(obj_folder), 0, "ical2exchange"); ical2exchange.lpProps = talloc_array(mem_ctx, struct SPropValue, 2); ical2exchange_init(&ical2exchange, mem_ctx); ical2exchange_get_properties(&ical2exchange, vevent); ical2exchange_convert_event(&ical2exchange); retval = CreateMessage(obj_folder, &obj_message); if (retval != MAPI_E_SUCCESS){ mapi_errstr("CreateMessage", GetLastError()); } else { retval = SetProps(&obj_message, 0, ical2exchange.lpProps, ical2exchange.cValues); if (retval != MAPI_E_SUCCESS){ mapi_errstr("SetProps", GetLastError()); } else { retval = SaveChangesMessage(obj_folder, &obj_message, KeepOpenReadOnly); if (retval != MAPI_E_SUCCESS){ mapi_errstr("SaveChangesMessage", GetLastError()); } } } MAPIFreeBuffer(ical2exchange.lpProps); ical2exchange_reset(&ical2exchange); talloc_free(mem_ctx); } openchange-2.0/libexchange2ical/ical2exchange_property.c000066400000000000000000001116641223057412600234660ustar00rootroot00000000000000/* Common conversion routines for exchange2ical OpenChange Project Copyright (C) Julien Kerihuel 2008 This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see . */ #include "libexchange2ical/libexchange2ical.h" #define MAXCAT 100000 /*Taken from Samba4 code*/ /* this base64 decoder was taken from jitterbug (written by tridge). we might need to replace it with a new version */ static int ldb_base64_decode(char *s) { const char *b64 = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/"; int bit_offset=0, byte_offset, idx, i, n; uint8_t *d = (uint8_t *)s; char *p=NULL; n=i=0; while (*s && (p=strchr(b64,*s))) { idx = (int)(p - b64); byte_offset = (i*6)/8; bit_offset = (i*6)%8; d[byte_offset] &= ~((1<<(8-bit_offset))-1); if (bit_offset < 3) { d[byte_offset] |= (idx << (2-bit_offset)); n = byte_offset+1; } else { d[byte_offset] |= (idx >> (bit_offset-2)); d[byte_offset+1] = 0; d[byte_offset+1] |= (idx << (8-(bit_offset-2))) & 0xFF; n = byte_offset+2; } s++; i++; } if (bit_offset >= 3) { n--; } if (*s && !p) { /* the only termination allowed */ if (*s != '=') { return -1; } } /* null terminate */ d[n] = 0; return n; } void ical2exchange_property_ATTACH(struct ical2exchange *ical2exchange) { int data; char *extension = NULL; char *filename = NULL; const char *fmttype = NULL; icalattach *icalattach = NULL; icalparameter *fmttypePar = NULL; icalparameter *xfilePar = NULL; const char *xname = NULL; icalproperty *attachProp = NULL; /*sanity check*/ if(!ical2exchange->attachEvent) return; attachProp=icalcomponent_get_first_property(ical2exchange->attachEvent, ICAL_ATTACH_PROPERTY); while(attachProp){ icalattach = icalproperty_get_attach(attachProp); data = ldb_base64_decode((char *) icalattach_get_data (icalattach)); /*FMTTYPE*/ fmttypePar = icalproperty_get_first_parameter(attachProp, ICAL_FMTTYPE_PARAMETER); if(fmttypePar){ fmttype = icalparameter_get_fmttype(fmttypePar); } /*X-FIlename*/ xfilePar = icalproperty_get_first_parameter(attachProp, ICAL_X_PARAMETER); if(xfilePar){ xname = icalparameter_get_xname(xfilePar); if(!strcmp(xname,"X-FILENAME")){ filename = (char *) icalparameter_get_x(xfilePar); } } /*Extension*/ if(filename){ char buff[256]; char *temp; strncpy(buff,filename, 255); buff[255] = '\0'; extension = strtok(buff, "."); while((temp = strtok(NULL, "."))) extension = temp; } printf("Create a new attachment object with\n"); printf(" set PidTagAttachDataBinary to %d\n", data); printf(" set PidTagAttachExtension to %s\n", extension); printf(" set PidTagAttachFilename to %s\n", filename); printf(" set PidTagAttachLongFilename to %s\n", filename); printf(" set PidTagAttachMimeTag to %s\n", fmttype); printf(" set PidTagAttachFlags to 0x00000000\n"); printf(" set PidTagAttachMethod to 0x00000001\n"); printf(" set PidTagAttachmentContactPhoto to FALSE\n"); printf(" set PidTagAttachmentFlags to 0x00000000\n"); printf(" set PidTagAttachEncoding to empty SBinary"); printf(" set PidTagAttachmentHidden to FALSE\n"); printf(" set PidTagAttachmentLinkId to 0x00000000\n"); printf(" set PidTagDisplayName to %s\n", filename); printf(" set PidTagExceptionEndTime to 0x0CB34557A3DD4000\n"); printf(" set PidTagExceptionStartTime to 0x0CB34557A3DD4000\n"); printf(" set PidTagRenderingPosition to 0xFFFFFFFF\n"); attachProp=icalcomponent_get_next_property(ical2exchange->attachEvent, ICAL_ATTACH_PROPERTY); } } //TODO: void ical2exchange_property_CATEGORIES(struct ical2exchange *ical2exchange) { struct StringArray_r *sArray; char **stringArray = NULL; char string[256]; char *value; char *tok; icalproperty *categoriesProp; uint32_t i = 0; /*sanity check*/ if(!ical2exchange->categoriesEvent) return; sArray = talloc(ical2exchange->mem_ctx, struct StringArray_r); categoriesProp = icalcomponent_get_first_property(ical2exchange->categoriesEvent, ICAL_CATEGORIES_PROPERTY); sArray->cValues = 0; while(categoriesProp){ value = strdup(icalproperty_get_categories(categoriesProp)); tok = strtok(value, ","); while(tok){ if(!stringArray){ stringArray = talloc_array(ical2exchange->mem_ctx, char *, 1); } else { stringArray = talloc_realloc(ical2exchange->mem_ctx, stringArray, char *, sArray->cValues+2); } strcpy(string, ""); while(tok[i]){ if (strlen(string) == 255) break; //remove beginning and ending white spaces if((tok[i]!= ' ' || (tok[i+1] && tok[i+1] != ' ')) && (strlen(string) || tok[i]!=' ')){ strncat(string, &tok[i], 1); } i++; } stringArray[sArray->cValues] = talloc_strdup(ical2exchange->mem_ctx, string); sArray->cValues++; i=0; tok= strtok(NULL, ","); } categoriesProp = icalcomponent_get_next_property(ical2exchange->categoriesEvent, ICAL_CATEGORIES_PROPERTY); } sArray->lppszA= (const char **) stringArray; /* SetProps */ ical2exchange->lpProps = add_SPropValue(ical2exchange->mem_ctx, ical2exchange->lpProps, &ical2exchange->cValues, PidNameKeywords, (const void *) sArray); } void ical2exchange_property_CLASS(struct ical2exchange *ical2exchange) { enum icalproperty_class class; uint32_t temp = 0; uint32_t *tag; /*sanity check*/ if(!ical2exchange->classProp) return; class = icalproperty_get_class(ical2exchange->classProp); switch(class){ case ICAL_CLASS_PUBLIC: temp = 0x00000000; break; case ICAL_CLASS_X: temp = 0x00000001; break; case ICAL_CLASS_PRIVATE: temp = 0x00000002; break; case ICAL_CLASS_CONFIDENTIAL: temp = 0x00000003; break; case ICAL_CLASS_NONE: return; } tag = talloc(ical2exchange->mem_ctx, uint32_t); *tag = temp; /* SetProps */ ical2exchange->lpProps = add_SPropValue(ical2exchange->mem_ctx, ical2exchange->lpProps, &ical2exchange->cValues, PR_SENSITIVITY, (const void *) tag); } void ical2exchange_property_COMMENT(struct ical2exchange *ical2exchange) { const char *comment; /*sanity check*/ if(!ical2exchange->commentProp) return; if(ical2exchange->method != ICAL_METHOD_COUNTER && ical2exchange->method != ICAL_METHOD_REPLY) return; comment = icalproperty_get_comment(ical2exchange->commentProp); comment = talloc_strdup(ical2exchange->mem_ctx, comment); /* SetProps */ ical2exchange->lpProps = add_SPropValue(ical2exchange->mem_ctx, ical2exchange->lpProps, &ical2exchange->cValues, PR_BODY, (const void *) comment); } void ical2exchange_property_CONTACT(struct ical2exchange *ical2exchange) { struct StringArray_r *sArray; char *value; char **stringArray = NULL; icalproperty *contactProp; /*sanity check*/ if(!ical2exchange->contactEvent) return; contactProp=icalcomponent_get_first_property(ical2exchange->contactEvent, ICAL_CONTACT_PROPERTY); sArray = talloc(ical2exchange->mem_ctx, struct StringArray_r); sArray->cValues =0; while(contactProp){ if(!stringArray){ stringArray = talloc_array(ical2exchange->mem_ctx, char *, 1); } else { stringArray = talloc_realloc(ical2exchange->mem_ctx, stringArray, char *, sArray->cValues+2); } value = strdup(icalproperty_get_contact(contactProp)); if(strlen(value)<500){ stringArray[sArray->cValues] = talloc_strdup(ical2exchange->mem_ctx, value); } else { value[499] = '\0'; stringArray[sArray->cValues] = talloc_strndup(ical2exchange->mem_ctx, value, 500); } sArray->cValues++; contactProp=icalcomponent_get_next_property(ical2exchange->contactEvent, ICAL_CONTACT_PROPERTY); } /*set up struct*/ sArray->lppszA=(const char **) stringArray; /* SetProps */ ical2exchange->lpProps = add_SPropValue(ical2exchange->mem_ctx, ical2exchange->lpProps, &ical2exchange->cValues, PidLidContacts, (const void *) sArray); } void ical2exchange_property_DESCRIPTION(struct ical2exchange *ical2exchange) { const char *description; /*sanity check*/ if(!ical2exchange->descriptionProp) return; if(ical2exchange->method == ICAL_METHOD_COUNTER || ical2exchange->method == ICAL_METHOD_REPLY) return; description = icalproperty_get_description(ical2exchange->descriptionProp); description = talloc_strdup(ical2exchange->mem_ctx, description); /* SetProps */ ical2exchange->lpProps = add_SPropValue(ical2exchange->mem_ctx, ical2exchange->lpProps, &ical2exchange->cValues, PR_BODY, (const void *) description); } void ical2exchange_property_DTSTAMP(struct ical2exchange *ical2exchange) { struct FILETIME *ft; icaltimetype dtstamp; /*sanity check*/ if(!ical2exchange->dtstampProp) return; dtstamp = icalproperty_get_dtstamp(ical2exchange->dtstampProp); ft = talloc(ical2exchange->mem_ctx, struct FILETIME); *ft = get_FILETIME_from_icaltimetype(&dtstamp); if(ical2exchange->method == ICAL_METHOD_COUNTER || ical2exchange->method == ICAL_METHOD_REPLY){ ical2exchange->lpProps = add_SPropValue(ical2exchange->mem_ctx, ical2exchange->lpProps, &ical2exchange->cValues, PidLidAttendeeCriticalChange, (const void *) ft); } else { ical2exchange->lpProps = add_SPropValue(ical2exchange->mem_ctx, ical2exchange->lpProps, &ical2exchange->cValues, PidLidOwnerCriticalChange, (const void *) ft); } } void ical2exchange_property_DTSTART_DTEND(struct ical2exchange *ical2exchange) { icaltimetype dtstart; icaltimetype dtend; struct FILETIME *startft; struct FILETIME *endft; double difference; uint32_t *duration; /*sanity check*/ if(!ical2exchange->dtstartProp) return; if(!ical2exchange->dtendProp) return; /*dtstart property*/ dtstart = icalproperty_get_dtstart(ical2exchange->dtstartProp); startft = talloc(ical2exchange->mem_ctx, struct FILETIME); *startft = get_FILETIME_from_icaltimetype(&dtstart); /*dtend property*/ dtend = icalproperty_get_dtend(ical2exchange->dtendProp); endft = talloc(ical2exchange->mem_ctx, struct FILETIME); *endft = get_FILETIME_from_icaltimetype(&dtend); if(ical2exchange->method == ICAL_METHOD_COUNTER){ ical2exchange->lpProps = add_SPropValue(ical2exchange->mem_ctx, ical2exchange->lpProps, &ical2exchange->cValues, PidLidAppointmentProposedStartWhole, (const void *) startft); ical2exchange->lpProps = add_SPropValue(ical2exchange->mem_ctx, ical2exchange->lpProps, &ical2exchange->cValues, PidLidAppointmentProposedEndWhole, (const void *) endft); } else { ical2exchange->lpProps = add_SPropValue(ical2exchange->mem_ctx, ical2exchange->lpProps, &ical2exchange->cValues, PidLidAppointmentStartWhole, (const void *) startft); ical2exchange->lpProps = add_SPropValue(ical2exchange->mem_ctx, ical2exchange->lpProps, &ical2exchange->cValues, PidLidAppointmentEndWhole, (const void *) endft); /*duration property*/ duration = talloc(ical2exchange->mem_ctx, uint32_t); difference = difftime(nt_time_to_unix(FILETIME_to_NTTIME(*endft)), nt_time_to_unix(FILETIME_to_NTTIME(*startft))); *duration = difference/60; ical2exchange->lpProps = add_SPropValue(ical2exchange->mem_ctx, ical2exchange->lpProps, &ical2exchange->cValues, PidLidAppointmentDuration, (const void *) duration); /*check if all day appointment*/ if(*duration==1440 && dtstart.hour==0 && dtstart.minute==0){ uint32_t *allday = talloc(ical2exchange->mem_ctx, uint32_t); *allday = 0x00000001; ical2exchange->lpProps = add_SPropValue(ical2exchange->mem_ctx, ical2exchange->lpProps, &ical2exchange->cValues, PidLidAppointmentSubType, (const void *) allday); } } } void ical2exchange_property_LOCATION(struct ical2exchange *ical2exchange) { uint32_t *langtag; char location[256] = ""; icalparameter *param = NULL; const char *value; char *string; /*sanity check*/ if(!ical2exchange->locationProp) return; value = icalproperty_get_location(ical2exchange->locationProp); int i; for(i=0; i<255; i++){ if(!value[i]) break; char c = value[i]; if(c !='\xD' && c!='\xA' ) strncat(location, &c, 1); } string = talloc_strdup(ical2exchange->mem_ctx, location); /* SetProps */ ical2exchange->lpProps = add_SPropValue(ical2exchange->mem_ctx, ical2exchange->lpProps, &ical2exchange->cValues, PidLidLocation, (const void *) string); if((param=icalproperty_get_first_parameter(ical2exchange->locationProp, ICAL_LANGUAGE_PARAMETER))){ const char* langName; langtag = talloc(ical2exchange->mem_ctx, uint32_t); langName = icalparameter_get_language(param); *langtag = mapi_get_lcid_from_language(langName); ical2exchange->lpProps = add_SPropValue(ical2exchange->mem_ctx, ical2exchange->lpProps, &ical2exchange->cValues, PR_MESSAGE_LOCALE_ID, (const void *) langtag); } } void ical2exchange_property_PRIORITY(struct ical2exchange *ical2exchange) { uint32_t temp = 0; uint32_t *tag; if(ical2exchange->x_importanceProp){ const char *value = icalproperty_get_x(ical2exchange->x_importanceProp); switch(atoi(value)){ case 0: temp = 0x00000000; break; case 1: temp = 0x00000001; break; case 2: temp = 0x00000002; break; } } else if(ical2exchange->priorityProp){ switch(icalproperty_get_priority(ical2exchange->priorityProp)){ case 0: return; case 1: case 2: case 3: case 4: temp = 0x00000002; break; case 5: temp = 0x00000001; break; case 6: case 7: case 8: case 9: temp = 0x00000000; break; default: return; } } else return; tag = talloc(ical2exchange->mem_ctx, uint32_t); *tag = temp; /* SetProps */ ical2exchange->lpProps = add_SPropValue(ical2exchange->mem_ctx, ical2exchange->lpProps, &ical2exchange->cValues, PidLidAppointmentSequence, (const void *) tag); } //TODO: Finish this void ical2exchange_property_RRULE_EXDATE_RDATE(struct ical2exchange *ical2exchange) { struct RecurrencePattern rp; struct icalrecurrencetype irt; struct icaltimetype next; struct icaltimetype last; icalrecur_iterator *ritr; icaltimetype dtstart; icaltimetype rdate; icaltimetype exdate; icalproperty *exdateProp; icalproperty *rdateProp; enum CalendarType calendarType; enum EndType endType; enum icalrecurrencetype_weekday weekday; uint32_t startTime; uint32_t endTime; uint32_t occurrenceCount; uint32_t i; uint32_t modifiedInstanceDates[ical2exchange->rdateCount]; uint32_t deletedInstanceDates[ical2exchange->exdateCount+ical2exchange->rdateCount]; if(!ical2exchange->rruleProp) return; if(!ical2exchange->dtstartProp) return; irt = icalproperty_get_rrule(ical2exchange->rruleProp); /*StartTime*/ enum icalrecurrencetype_weekday icalrecurrencetype_day_day_of_week(short day); dtstart = icalproperty_get_dtstart(ical2exchange->dtstartProp); dtstart.hour = 0; dtstart.minute = 0; dtstart.second = 0; startTime = get_minutes_from_icaltimetype(dtstart); /*WeekDay*/ if(irt.week_start == ICAL_NO_WEEKDAY){ weekday = icalrecurrencetype_day_day_of_week(icaltime_day_of_week(dtstart)); } else { weekday = irt.week_start; } /*calendarType*/ //if(ical2exchange->calscaleProp){ //calendarType = get_exchange_calendartype(icalproperty_get_x(ical2exchange->calscaleProp)); //} else { calendarType = CAL_DEFAULT; //} /*endType occurrenceCount endTime*/ if(irt.count || !icaltime_is_null_time(irt.until)){ endType = END_AFTER_N_OCCURRENCES; occurrenceCount = irt.count; ritr = icalrecur_iterator_new(irt,dtstart); next=icalrecur_iterator_next(ritr); while (!icaltime_is_null_time(next)){ last = next; next=icalrecur_iterator_next(ritr); if(!irt.count) occurrenceCount++; } endTime = get_minutes_from_icaltimetype(last); icalrecur_iterator_free(ritr); } else { endType = END_NEVER_END; occurrenceCount = 0x0000000A; endTime = 0x5AE980DF; } /*Common values for all rrule*/ rp.ReaderVersion = 0x3004; rp.WriterVersion = 0x3004; rp.CalendarType = calendarType; rp.FirstDateTime = startTime; rp.SlidingFlag = 0x00000000; rp.EndType = endType; rp.OccurrenceCount = occurrenceCount; rp.FirstDOW = get_exchange_day_from_ical(weekday); rp.StartDate = startTime; rp.EndDate = endTime; /*Specific values*/ switch(irt.freq){ case ICAL_DAILY_RECURRENCE: rp.RecurFrequency = RecurFrequency_Daily; rp.PatternType = PatternType_Day; rp.Period = 1440 * irt.interval; break; case ICAL_WEEKLY_RECURRENCE: rp.RecurFrequency = RecurFrequency_Weekly; rp.PatternType = PatternType_Day; rp.Period = irt.interval; break; case ICAL_MONTHLY_RECURRENCE: rp.RecurFrequency = RecurFrequency_Monthly; rp.Period = irt.interval; if(irt.by_day[0] == ICAL_RECURRENCE_ARRAY_MAX){ rp.PatternType = PatternType_Month; if(irt.by_month_day[0] == -1){ rp.PatternTypeSpecific.Day = 0x0000001F; } else { rp.PatternTypeSpecific.Day = irt.by_month_day[0]; } } else { rp.PatternType = PatternType_MonthNth; i = 0; rp.PatternTypeSpecific.MonthRecurrencePattern.WeekRecurrencePattern = 0; while( irt.by_day[i] != ICAL_RECURRENCE_ARRAY_MAX){ rp.PatternTypeSpecific.MonthRecurrencePattern.WeekRecurrencePattern |= get_exchange_rdfDays_from_ical(irt.by_day[i]); i++; } if(irt.by_set_pos[0] == -1) rp.PatternTypeSpecific.MonthRecurrencePattern.N = RecurrenceN_Last; else rp.PatternTypeSpecific.MonthRecurrencePattern.N = irt.by_set_pos[0]; } break; case ICAL_YEARLY_RECURRENCE: rp.RecurFrequency = RecurFrequency_Yearly; rp.Period = 12 * irt.interval; /*Nth*/ if(irt.by_day[0] == ICAL_RECURRENCE_ARRAY_MAX){ rp.PatternType = PatternType_Month; if(irt.by_month_day[0] == -1){ rp.PatternTypeSpecific.Day = 0x0000001F; } else { rp.PatternTypeSpecific.Day = irt.by_month_day[0]; } } else { rp.PatternType = PatternType_MonthNth; i = 0; rp.PatternTypeSpecific.MonthRecurrencePattern.WeekRecurrencePattern = 0; while( irt.by_day[i] != ICAL_RECURRENCE_ARRAY_MAX){ rp.PatternTypeSpecific.MonthRecurrencePattern.WeekRecurrencePattern |= get_exchange_rdfDays_from_ical(irt.by_day[i]); i++; } if(irt.by_set_pos[0] == -1) rp.PatternTypeSpecific.MonthRecurrencePattern.N = RecurrenceN_Last; else rp.PatternTypeSpecific.MonthRecurrencePattern.N = irt.by_set_pos[0]; } break; default: printf("not handled yet\n"); } /*deletedInstanceDates & modifiedInstanceDates*/ if(ical2exchange->exdateEvent){ exdateProp=icalcomponent_get_first_property(ical2exchange->exdateEvent, ICAL_EXDATE_PROPERTY); for(i=0; iexdateCount; i++){ exdate = icalproperty_get_exdate(exdateProp); deletedInstanceDates[i] = get_minutes_from_icaltimetype(exdate); exdateProp=icalcomponent_get_first_property(ical2exchange->exdateEvent, ICAL_EXDATE_PROPERTY); } } if(ical2exchange->rdateEvent){ rdateProp = icalcomponent_get_first_property(ical2exchange->rdateEvent, ICAL_EXDATE_PROPERTY); for(i=0; irdateCount; i++){ rdate = icalproperty_get_exdate(rdateProp); deletedInstanceDates[i + ical2exchange->exdateCount] = get_minutes_from_icaltimetype(rdate); modifiedInstanceDates[i] = get_minutes_from_icaltimetype(rdate); rdateProp = icalcomponent_get_first_property(ical2exchange->rdateEvent, ICAL_EXDATE_PROPERTY); } } /*Sort array*/ qsort(deletedInstanceDates, ical2exchange->rdateCount + ical2exchange->exdateCount, sizeof(uint32_t), compare_minutes); qsort(modifiedInstanceDates, ical2exchange->rdateCount, sizeof(uint32_t), compare_minutes); rp.DeletedInstanceCount = ical2exchange->rdateCount + ical2exchange->exdateCount; rp.ModifiedInstanceCount = ical2exchange->rdateCount; rp.DeletedInstanceDates = deletedInstanceDates; rp.ModifiedInstanceDates = modifiedInstanceDates; } void ical2exchange_property_SEQUENCE(struct ical2exchange *ical2exchange) { uint32_t temp; uint32_t *tag; if(ical2exchange->x_sequenceProp){ temp = atoi(icalproperty_get_x(ical2exchange->x_sequenceProp)); } else if(ical2exchange->sequenceProp){ temp = icalproperty_get_sequence(ical2exchange->sequenceProp); } else return; tag = talloc(ical2exchange->mem_ctx, uint32_t); *tag = temp; /* SetProps */ ical2exchange->lpProps = add_SPropValue(ical2exchange->mem_ctx, ical2exchange->lpProps, &ical2exchange->cValues, PidLidAppointmentSequence, (const void *) tag); } void ical2exchange_property_STATUS(struct ical2exchange *ical2exchange) { enum icalproperty_status status; enum icalproperty_transp transp; uint32_t *tag; uint32_t temp = 0; const char *prop; if(ical2exchange->x_busystatusProp){ prop=icalproperty_get_x(ical2exchange->x_busystatusProp); if(!strcmp(prop, "FREE")){ temp = 0x00000000; } else if(!strcmp(prop, "TENTATIVE")){ temp = 0x00000001; } else if(!strcmp(prop, "BUSY")){ temp = 0x00000002; } else if(!strcmp(prop, "OOF")){ temp = 0x00000003; } } else if(ical2exchange->transpProp){ transp = icalproperty_get_transp(ical2exchange->transpProp); switch(transp){ case ICAL_TRANSP_TRANSPARENT: temp = 0x00000000; break; case ICAL_TRANSP_OPAQUE: temp = 0x00000002; break; default: return; } } else if(ical2exchange->statusProp){ status = icalproperty_get_status(ical2exchange->classProp); switch(status){ case ICAL_STATUS_CANCELLED: temp = 0x00000000; break; case ICAL_STATUS_TENTATIVE: temp = 0x00000001; break; case ICAL_STATUS_CONFIRMED: temp = 0x00000002; break; default: return; } } else return; tag = talloc(ical2exchange->mem_ctx, uint32_t); *tag = temp; /* SetProps */ ical2exchange->lpProps = add_SPropValue(ical2exchange->mem_ctx, ical2exchange->lpProps, &ical2exchange->cValues, PidLidBusyStatus, (const void *) tag); } void ical2exchange_property_SUMMARY(struct ical2exchange *ical2exchange) { const char *value; uint32_t langtag; char summary[256] = ""; icalparameter *param = NULL; char *string; /*sanity check*/ if(!ical2exchange->summaryProp) return; value = icalproperty_get_summary(ical2exchange->summaryProp); int i; for(i=0; i<255; i++){ if(!value[i]) break; char c = value[i]; if(c !='\xD' && c!='\xA' ) strncat(summary, &c, 1); } string = talloc_strdup(ical2exchange->mem_ctx, summary); ical2exchange->lpProps = add_SPropValue(ical2exchange->mem_ctx, ical2exchange->lpProps, &ical2exchange->cValues, PR_SUBJECT, (const void *) string); if((param=icalproperty_get_first_parameter(ical2exchange->summaryProp, ICAL_LANGUAGE_PARAMETER))){ const char *langName; langName = icalparameter_get_language(param); langtag = mapi_get_lcid_from_language(langName); ical2exchange->lpProps = add_SPropValue(ical2exchange->mem_ctx, ical2exchange->lpProps, &ical2exchange->cValues, PR_MESSAGE_LOCALE_ID, (const void *) &langtag); } } void ical2exchange_property_VALARM(struct ical2exchange *ical2exchange) { icalproperty *triggerProp = NULL; uint32_t *duration; icaltimetype dtstart; icaltimetype current; icaltimetype triggerSet; icaltimetype next; const icaltimezone *timezone; struct FILETIME *rtimeft; struct FILETIME *rsignalft; struct icalrecurrencetype irt; icalrecur_iterator *ritr; struct icaltriggertype trigger; bool *set; /*sanity check*/ if(!ical2exchange->valarmEvent) return; if(!ical2exchange->dtstartProp) return; triggerProp = icalcomponent_get_first_property(ical2exchange->valarmEvent, ICAL_TRIGGER_PROPERTY); if(!triggerProp) return; trigger = icalproperty_get_trigger(triggerProp); dtstart = icalproperty_get_dtstart(ical2exchange->dtstartProp); duration = talloc(ical2exchange->mem_ctx, uint32_t); if(trigger.duration.is_neg){ *duration = -trigger.duration.minutes; } else { *duration = trigger.duration.minutes; } timezone = icaltime_get_timezone(dtstart); current = icaltime_current_time_with_zone(timezone); if(icaltime_compare(dtstart, current)) { rtimeft = talloc(ical2exchange->mem_ctx, struct FILETIME); rsignalft = talloc(ical2exchange->mem_ctx, struct FILETIME); *rtimeft = get_FILETIME_from_icaltimetype(&dtstart); ical2exchange->lpProps = add_SPropValue(ical2exchange->mem_ctx, ical2exchange->lpProps, &ical2exchange->cValues, PidLidReminderTime, (const void *) rtimeft); triggerSet = icaltime_add(dtstart, trigger.duration); *rsignalft = get_FILETIME_from_icaltimetype(&triggerSet); ical2exchange->lpProps = add_SPropValue(ical2exchange->mem_ctx, ical2exchange->lpProps, &ical2exchange->cValues, PidLidReminderSignalTime, (const void *) rsignalft); } else if(ical2exchange->rruleProp) { irt = icalproperty_get_rrule(ical2exchange->rruleProp); ritr = icalrecur_iterator_new(irt,dtstart); next = icalrecur_iterator_next(ritr); while (!icaltime_is_null_time(next)){ if(icaltime_compare(next, current)) { rtimeft = talloc(ical2exchange->mem_ctx, struct FILETIME); rsignalft = talloc(ical2exchange->mem_ctx, struct FILETIME); *rtimeft = get_FILETIME_from_icaltimetype(&next); ical2exchange->lpProps = add_SPropValue(ical2exchange->mem_ctx, ical2exchange->lpProps, &ical2exchange->cValues, PidLidReminderTime, (const void *) rtimeft); triggerSet = icaltime_add(next, trigger.duration); *rsignalft = get_FILETIME_from_icaltimetype(&triggerSet); ical2exchange->lpProps = add_SPropValue(ical2exchange->mem_ctx, ical2exchange->lpProps, &ical2exchange->cValues, PidLidReminderSignalTime, (const void *) &rsignalft); break; } next=icalrecur_iterator_next(ritr); } } else return; set = talloc(ical2exchange->mem_ctx, bool); *set = true; ical2exchange->lpProps = add_SPropValue(ical2exchange->mem_ctx, ical2exchange->lpProps, &ical2exchange->cValues, PidLidReminderSet, (const void *) set); ical2exchange->lpProps = add_SPropValue(ical2exchange->mem_ctx, ical2exchange->lpProps, &ical2exchange->cValues, PidLidReminderDelta, (const void *) duration); } void ical2exchange_property_X_ALLOWEXTERNCHECK(struct ical2exchange *ical2exchange) { const char *prop; bool *allow; if(!ical2exchange->x_allowexterncheckProp) return; prop=icalproperty_get_x(ical2exchange->x_allowexterncheckProp); allow = talloc(ical2exchange->mem_ctx, bool); if(strcmp(prop, "TRUE")){ *allow = true; } else { *allow = false; } ical2exchange->lpProps = add_SPropValue(ical2exchange->mem_ctx, ical2exchange->lpProps, &ical2exchange->cValues, PidLidAllowExternalCheck, (const void *) allow); } void ical2exchange_property_X_APPTSEQTIME(struct ical2exchange *ical2exchange) { const char *prop; struct FILETIME *ft; if(!ical2exchange->x_apptseqtimeProp) return; ft = talloc(ical2exchange->mem_ctx, struct FILETIME); prop=icalproperty_get_x(ical2exchange->x_apptseqtimeProp); *ft = get_FILETIME_from_string(prop); ical2exchange->lpProps = add_SPropValue(ical2exchange->mem_ctx, ical2exchange->lpProps, &ical2exchange->cValues, PidLidAppointmentSequenceTime, (const void *) ft); } void ical2exchange_property_X_APPTLASTSEQUENCE(struct ical2exchange *ical2exchange) { uint32_t *tag; const char *prop; if(!ical2exchange->x_apptlastsequenceProp) return; prop=icalproperty_get_x(ical2exchange->x_apptlastsequenceProp); tag = talloc(ical2exchange->mem_ctx, uint32_t); *tag=atoi(prop); ical2exchange->lpProps = add_SPropValue(ical2exchange->mem_ctx, ical2exchange->lpProps, &ical2exchange->cValues, PidLidAppointmentLastSequence, (const void *) tag); } void ical2exchange_property_X_ATTENDEE_CRITICAL_CHANGE(struct ical2exchange *ical2exchange) { const char *prop; struct FILETIME *ft; if(!ical2exchange->x_attendeecriticalchangeProp) return; prop=icalproperty_get_x(ical2exchange->x_attendeecriticalchangeProp); ft = talloc(ical2exchange->mem_ctx, struct FILETIME); *ft = get_FILETIME_from_string(prop); ical2exchange->lpProps = add_SPropValue(ical2exchange->mem_ctx, ical2exchange->lpProps, &ical2exchange->cValues, PidLidAttendeeCriticalChange, (const void *) ft); } void ical2exchange_property_X_AUTOFILLLOCATION(struct ical2exchange *ical2exchange) { const char *prop; bool *autoFill; if(!ical2exchange->x_autofilllocationProp) return; prop=icalproperty_get_x(ical2exchange->x_autofilllocationProp); autoFill = talloc(ical2exchange->mem_ctx, bool); if(strcmp(prop, "TRUE")){ *autoFill = true; } else { *autoFill = false; } ical2exchange->lpProps = add_SPropValue(ical2exchange->mem_ctx, ical2exchange->lpProps, &ical2exchange->cValues, PidLidAutoFillLocation, (const void *) autoFill); } void ical2exchange_property_X_AUTOSTARTCHECK(struct ical2exchange *ical2exchange) { const char *prop; bool *autoStart; if(!ical2exchange->x_autostartcheckProp) return; prop=icalproperty_get_x(ical2exchange->x_autostartcheckProp); autoStart = talloc(ical2exchange->mem_ctx, bool); if(strcmp(prop, "TRUE")){ *autoStart = true; } else { *autoStart = false; } ical2exchange->lpProps = add_SPropValue(ical2exchange->mem_ctx, ical2exchange->lpProps, &ical2exchange->cValues, PidLidAutoStartCheck, (const void *) autoStart); } void ical2exchange_property_X_COLLABORATEDDOC(struct ical2exchange *ical2exchange) { const char *prop; if(!ical2exchange->x_collaborateddocProp) return; prop=icalproperty_get_x(ical2exchange->x_collaborateddocProp); prop = talloc_strdup(ical2exchange->mem_ctx, prop); ical2exchange->lpProps = add_SPropValue(ical2exchange->mem_ctx, ical2exchange->lpProps, &ical2exchange->cValues, PidLidCollaborateDoc, (const void *) prop); } void ical2exchange_property_X_CONFCHECK(struct ical2exchange *ical2exchange) { const char *prop; bool *confCheck; if(!ical2exchange->x_confcheckProp) return; prop=icalproperty_get_x(ical2exchange->x_confcheckProp); confCheck = talloc(ical2exchange->mem_ctx, bool); if(strcmp(prop, "TRUE")){ *confCheck = true; } else { *confCheck = false; } ical2exchange->lpProps = add_SPropValue(ical2exchange->mem_ctx, ical2exchange->lpProps, &ical2exchange->cValues, PidLidConferencingCheck, (const void *) confCheck); } void ical2exchange_property_X_CONFTYPE(struct ical2exchange *ical2exchange) { uint32_t *tag; const char *prop; if(!ical2exchange->x_conftypeProp) return; prop=icalproperty_get_x(ical2exchange->x_conftypeProp); tag = talloc(ical2exchange->mem_ctx, uint32_t); *tag=atoi(prop); ical2exchange->lpProps = add_SPropValue(ical2exchange->mem_ctx, ical2exchange->lpProps, &ical2exchange->cValues, PidLidConferencingType, (const void *) tag); } void ical2exchange_property_X_DISALLOW_COUNTER(struct ical2exchange *ical2exchange) { const char *prop; bool *disallow; if(!ical2exchange->x_disallowcounterProp) return; prop=icalproperty_get_x(ical2exchange->x_disallowcounterProp); disallow = talloc(ical2exchange->mem_ctx, bool); if(strcmp(prop, "TRUE")){ *disallow = true; } else { *disallow = false; } ical2exchange->lpProps = add_SPropValue(ical2exchange->mem_ctx, ical2exchange->lpProps, &ical2exchange->cValues, PidLidAppointmentNotAllowPropose, (const void *) disallow); } void ical2exchange_property_X_INTENDEDSTATUS(struct ical2exchange *ical2exchange) { uint32_t *tag; const char *prop; if(!ical2exchange->x_intendedProp) return; prop=icalproperty_get_x(ical2exchange->x_intendedProp); tag = talloc(ical2exchange->mem_ctx,uint32_t); if(!strcmp(prop, "FREE")){ *tag = 0x00000000; } else if(!strcmp(prop, "TENTATIVE")){ *tag = 0x00000001; } else if(!strcmp(prop, "BUSY")){ *tag = 0x00000002; } else if(!strcmp(prop, "OOF")){ *tag = 0x00000003; } ical2exchange->lpProps = add_SPropValue(ical2exchange->mem_ctx, ical2exchange->lpProps, &ical2exchange->cValues, PidLidIntendedBusyStatus, (const void *) tag); } void ical2exchange_property_X_ISDRAFT(struct ical2exchange *ical2exchange) { const char *prop; bool *isDraft; isDraft = talloc(ical2exchange->mem_ctx, bool); if(ical2exchange->method == ICAL_METHOD_COUNTER || ical2exchange->method == ICAL_METHOD_REPLY || ical2exchange->method == ICAL_METHOD_REQUEST || ical2exchange->method == ICAL_METHOD_CANCEL){ *isDraft = true; } else { if(ical2exchange->x_isdraftProp){ prop=icalproperty_get_x(ical2exchange->x_isdraftProp); if(strcmp(prop, "TRUE")){ *isDraft = true; } else { *isDraft = false; } } else { *isDraft = false; } } ical2exchange->lpProps = add_SPropValue(ical2exchange->mem_ctx, ical2exchange->lpProps, &ical2exchange->cValues, PidLidFInvited, (const void *) isDraft); } void ical2exchange_property_X_MWSURL(struct ical2exchange *ical2exchange) { char *mwsurl; const char *prop; if(!ical2exchange->x_mwsurlProp) return; prop = icalproperty_get_x(ical2exchange->x_mwsurlProp); mwsurl = talloc_strdup(ical2exchange->mem_ctx, prop); ical2exchange->lpProps = add_SPropValue(ical2exchange->mem_ctx, ical2exchange->lpProps, &ical2exchange->cValues, PidLidMeetingWorkspaceUrl, (const void *) mwsurl); } void ical2exchange_property_X_NETSHOWURL(struct ical2exchange *ical2exchange) { char *netshow; const char *prop; if(!ical2exchange->x_netshowurlProp) return; prop = icalproperty_get_x(ical2exchange->x_netshowurlProp); netshow = talloc_strdup(ical2exchange->mem_ctx, prop); ical2exchange->lpProps = add_SPropValue(ical2exchange->mem_ctx, ical2exchange->lpProps, &ical2exchange->cValues, PidLidNetShowUrl, (const void *) netshow); } void ical2exchange_property_X_ONLINEPASSWORD(struct ical2exchange *ical2exchange) { char *onlinepass; const char *prop; if(!ical2exchange->x_onlinepasswordProp) return; prop = icalproperty_get_x(ical2exchange->x_onlinepasswordProp); onlinepass = talloc_strdup(ical2exchange->mem_ctx, prop); ical2exchange->lpProps = add_SPropValue(ical2exchange->mem_ctx, ical2exchange->lpProps, &ical2exchange->cValues, PidLidOnlinePassword, (const void *) onlinepass); } void ical2exchange_property_X_ORGALIAS(struct ical2exchange *ical2exchange) { char *orgalias; const char *prop; if(!ical2exchange->x_orgaliasProp) return; prop = icalproperty_get_x(ical2exchange->x_orgaliasProp); orgalias = talloc_strdup(ical2exchange->mem_ctx, prop); ical2exchange->lpProps = add_SPropValue(ical2exchange->mem_ctx, ical2exchange->lpProps, &ical2exchange->cValues, PidLidOrganizerAlias, (const void *) orgalias); } void ical2exchange_property_X_ORIGINALEND_ORIGINALSTART(struct ical2exchange *ical2exchange) { const char *start; const char *end; double difference; uint32_t duration; struct FILETIME startft; struct FILETIME endft; /*sanity check*/ if(!ical2exchange->x_originalendProp) return; if(!ical2exchange->x_originalstartProp) return; if(ical2exchange->method != ICAL_METHOD_COUNTER) return; start = icalproperty_get_x(ical2exchange->x_originalstartProp); end = icalproperty_get_x(ical2exchange->x_originalendProp); startft = get_FILETIME_from_string(start); endft = get_FILETIME_from_string(end); /*duration property*/ difference = difftime(nt_time_to_unix(FILETIME_to_NTTIME(endft)), nt_time_to_unix(FILETIME_to_NTTIME(startft))); duration = difference/60; ical2exchange->lpProps = add_SPropValue(ical2exchange->mem_ctx, ical2exchange->lpProps, &ical2exchange->cValues, PidLidAppointmentStartWhole, (const void *) &startft); ical2exchange->lpProps = add_SPropValue(ical2exchange->mem_ctx, ical2exchange->lpProps, &ical2exchange->cValues, PidLidAppointmentEndWhole, (const void *) &endft); ical2exchange->lpProps = add_SPropValue(ical2exchange->mem_ctx, ical2exchange->lpProps, &ical2exchange->cValues, PidLidAppointmentDuration, (const void *) &duration); } void ical2exchange_property_X_OWNER_CRITICAL_CHANGE(struct ical2exchange *ical2exchange) { const char *prop; struct FILETIME ft; if(!ical2exchange->x_ownercriticalchangeProp) return; prop=icalproperty_get_x(ical2exchange->x_ownercriticalchangeProp); ft = get_FILETIME_from_string(prop); ical2exchange->lpProps = add_SPropValue(ical2exchange->mem_ctx, ical2exchange->lpProps, &ical2exchange->cValues, PidLidOwnerCriticalChange, (const void *) &ft); } void ical2exchange_property_X_OWNERAPPTID(struct ical2exchange *ical2exchange) { uint32_t *tag; const char *prop; if(!ical2exchange->x_ownerapptidProp) return; prop=icalproperty_get_x(ical2exchange->x_ownerapptidProp); tag = talloc(ical2exchange->mem_ctx, uint32_t); *tag = atoi(prop); ical2exchange->lpProps = add_SPropValue(ical2exchange->mem_ctx, ical2exchange->lpProps, &ical2exchange->cValues, PR_OWNER_APPT_ID, (const void *) tag); } void ical2exchange_property_X_REPLYTIME(struct ical2exchange *ical2exchange) { const char *prop; struct FILETIME *ft; if(!ical2exchange->x_replytimeProp) return; prop=icalproperty_get_x(ical2exchange->x_replytimeProp); ft = talloc(ical2exchange->mem_ctx, struct FILETIME); *ft = get_FILETIME_from_string(prop); /* SetProps */ ical2exchange->lpProps = add_SPropValue(ical2exchange->mem_ctx, ical2exchange->lpProps, &ical2exchange->cValues, PidLidAppointmentReplyTime, (const void *) ft); } openchange-2.0/libexchange2ical/libexchange2ical.c000066400000000000000000000037231223057412600222050ustar00rootroot00000000000000/* Convert Exchange appointments to ICAL OpenChange Project Copyright (C) Julien Kerihuel 2008 This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see . */ #include "libexchange2ical/libexchange2ical.h" icalcomponent * Exchange2Ical(mapi_object_t *obj_folder) { struct exchange2ical_check exchange2ical_check; exchange2ical_check.eFlags=EntireFlag; return _Exchange2Ical(obj_folder, &exchange2ical_check); } icalcomponent * Exchange2IcalRange(mapi_object_t *obj_folder, struct tm *begin, struct tm *end) { struct exchange2ical_check exchange2ical_check; exchange2ical_check.eFlags=RangeFlag; exchange2ical_check.begin = begin; exchange2ical_check.end = end; return _Exchange2Ical(obj_folder, &exchange2ical_check); } icalcomponent *Exchange2IcalEvent(mapi_object_t *obj_folder, struct GlobalObjectId *GlobalObjectId, uint32_t Sequence) { struct exchange2ical_check exchange2ical_check; exchange2ical_check.eFlags=EventFlag; exchange2ical_check.GlobalObjectId=GlobalObjectId; exchange2ical_check.Sequence=Sequence; return _Exchange2Ical(obj_folder, &exchange2ical_check); } icalcomponent *Exchange2IcalEvents(mapi_object_t *obj_folder, struct GlobalObjectId *GlobalObjectId) { struct exchange2ical_check exchange2ical_check; exchange2ical_check.eFlags=EventsFlag; exchange2ical_check.GlobalObjectId=GlobalObjectId; return _Exchange2Ical(obj_folder, &exchange2ical_check); } openchange-2.0/libexchange2ical/libexchange2ical.h000066400000000000000000000066031223057412600222120ustar00rootroot00000000000000/* Convert Exchange appointments to ICAL OpenChange Project Copyright (C) Julien Kerihuel 2008 This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see . */ #include #ifndef __LIBEXCHANGE2ICAL_H_ #define __LIBEXCHANGE2ICAL_H_ /** \details Retrieve entire exchange calendar as an Icalendar This function returns an Icalendar of the entire exchange calendar inside the obj_folder \param obj_folder the folder to operate in \return Icalendar on success, otherwise Null \note Developers should call ical_component_free() on the returned icalendar after use. */ icalcomponent * Exchange2Ical(mapi_object_t *obj_folder); /** \details Retrieve a range of exchange appointments as an Icalendar This function returns an Icalendar of exchange appointments that begin within the specified range. \param obj_folder the folder to operate in \param begin a tm that specifies the start date of the range \param end a tm that specifies the end date of the range \return Icalendar on success, otherwise Null \note Developers should call ical_component_free() on the returned icalendar after use. If no events are within the specified range, an icalendar will be returned without any vevents. */ icalcomponent * Exchange2IcalRange(mapi_object_t *obj_folder, struct tm *begin, struct tm *end); /** \details Retrieve a specific exchange appointment as an Icalendar This function returns an Icalendar with an appointments that match the specified GlobalObjectId and sequence number. \param obj_folder the folder to operate in \param GlobalObjectId the unique GlobalObjectId of the appointment \param Sequence the sequence number of the appointment \return Icalendar on success, otherwise Null \note Developers should call ical_component_free() on the returned icalendar after use. If no event's GlobalObjectId match the specifid GlobalObjectId, an icalendar will be returned without any vevents. */ icalcomponent *Exchange2IcalEvent(mapi_object_t *obj_folder, struct GlobalObjectId *GlobalObjectId, uint32_t Sequence); /** \details Retrieve an exchange appointment and its occurrences as an Icalendar This function returns an Icalendar with any appointments that match the specified GlobalObjectId and sequence number. \param obj_folder the folder to operate in \param GlobalObjectId the unique GlobalObjectId of the appointment \return Icalendar on success, otherwise Null \note Developers should call ical_component_free() on the returned icalendar after use. If no event's GlobalObjectId match the specifid GlobalObjectId, an icalendar will be returned without any vevents. */ icalcomponent *Exchange2IcalEvents(mapi_object_t *obj_folder, struct GlobalObjectId *GlobalObjectId); #endif /* __LIBEXCHANGE2ICAL_H_ */ openchange-2.0/libexchange2ical/libical2exchange.c000066400000000000000000000014551223057412600222050ustar00rootroot00000000000000/* Common conversion routines for exchange2ical OpenChange Project Copyright (C) Julien Kerihuel 2008 This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see . */ #include "libexchange2ical/libexchange2ical.h" openchange-2.0/libmapi++.pc.in000066400000000000000000000004701223057412600161610ustar00rootroot00000000000000prefix=@prefix@ exec_prefix=@exec_prefix@ libdir=@libdir@ includedir=@includedir@ datarootdir=@prefix@/share datadir=@datadir@ Name: OpenChange C++ bindings Description: C++ bindings for the OpenChange MAPI library Version: @PACKAGE_VERSION@ Libs: -L${libdir} -lmapipp Cflags: -I${includedir} Requires: libmapi openchange-2.0/libmapi++/000077500000000000000000000000001223057412600152275ustar00rootroot00000000000000openchange-2.0/libmapi++/Doxyfile.in000066400000000000000000001454031223057412600173510ustar00rootroot00000000000000# Doxyfile 1.5.2 # This file describes the settings to be used by the documentation system # doxygen (www.doxygen.org) for a project # # All text after a hash (#) is considered a comment and will be ignored # The format is: # TAG = value [value, ...] # For lists items can also be appended using: # TAG += value [value, ...] # Values that contain spaces should be placed between quotes (" ") #--------------------------------------------------------------------------- # Project related configuration options #--------------------------------------------------------------------------- # This tag specifies the encoding used for all characters in the config file that # follow. The default is UTF-8 which is also the encoding used for all text before # the first occurrence of this tag. Doxygen uses libiconv (or the iconv built into # libc) for the transcoding. See http://www.gnu.org/software/libiconv for the list of # possible encodings. DOXYFILE_ENCODING = UTF-8 # The PROJECT_NAME tag is a single word (or a sequence of words surrounded # by quotes) that should identify the project. PROJECT_NAME = MAPI C++ Client Library Bindings # The PROJECT_NUMBER tag can be used to enter a project or revision number. # This could be handy for archiving the generated documentation or # if some version control system is used. PROJECT_NUMBER = @PACKAGE_VERSION@ # The OUTPUT_DIRECTORY tag is used to specify the (relative or absolute) # base path where the generated documentation will be put. # If a relative path is entered, it will be relative to the location # where doxygen was started. If left blank the current directory will be used. OUTPUT_DIRECTORY = apidocs # If the CREATE_SUBDIRS tag is set to YES, then doxygen will create # 4096 sub-directories (in 2 levels) under the output directory of each output # format and will distribute the generated files over these directories. # Enabling this option can be useful when feeding doxygen a huge amount of # source files, where putting all generated files in the same directory would # otherwise cause performance problems for the file system. CREATE_SUBDIRS = NO # The OUTPUT_LANGUAGE tag is used to specify the language in which all # documentation generated by doxygen is written. Doxygen will use this # information to generate all constant output in the proper language. # The default language is English, other supported languages are: # Afrikaans, Arabic, Brazilian, Catalan, Chinese, Chinese-Traditional, # Croatian, Czech, Danish, Dutch, Finnish, French, German, Greek, Hungarian, # Italian, Japanese, Japanese-en (Japanese with English messages), Korean, # Korean-en, Lithuanian, Norwegian, Polish, Portuguese, Romanian, Russian, # Serbian, Slovak, Slovene, Spanish, Swedish, and Ukrainian. OUTPUT_LANGUAGE = English # If the BRIEF_MEMBER_DESC tag is set to YES (the default) Doxygen will # include brief member descriptions after the members that are listed in # the file and class documentation (similar to JavaDoc). # Set to NO to disable this. BRIEF_MEMBER_DESC = YES # If the REPEAT_BRIEF tag is set to YES (the default) Doxygen will prepend # the brief description of a member or function before the detailed description. # Note: if both HIDE_UNDOC_MEMBERS and BRIEF_MEMBER_DESC are set to NO, the # brief descriptions will be completely suppressed. REPEAT_BRIEF = YES # This tag implements a quasi-intelligent brief description abbreviator # that is used to form the text in various listings. Each string # in this list, if found as the leading text of the brief description, will be # stripped from the text and the result after processing the whole list, is # used as the annotated text. Otherwise, the brief description is used as-is. # If left blank, the following values are used ("$name" is automatically # replaced with the name of the entity): "The $name class" "The $name widget" # "The $name file" "is" "provides" "specifies" "contains" # "represents" "a" "an" "the" ABBREVIATE_BRIEF = # If the ALWAYS_DETAILED_SEC and REPEAT_BRIEF tags are both set to YES then # Doxygen will generate a detailed section even if there is only a brief # description. ALWAYS_DETAILED_SEC = NO # If the INLINE_INHERITED_MEMB tag is set to YES, doxygen will show all # inherited members of a class in the documentation of that class as if those # members were ordinary class members. Constructors, destructors and assignment # operators of the base classes will not be shown. INLINE_INHERITED_MEMB = NO # If the FULL_PATH_NAMES tag is set to YES then Doxygen will prepend the full # path before files name in the file list and in the header files. If set # to NO the shortest path that makes the file name unique will be used. FULL_PATH_NAMES = YES # If the FULL_PATH_NAMES tag is set to YES then the STRIP_FROM_PATH tag # can be used to strip a user-defined part of the path. Stripping is # only done if one of the specified strings matches the left-hand part of # the path. The tag can be used to show relative paths in the file list. # If left blank the directory from which doxygen is run is used as the # path to strip. STRIP_FROM_PATH = # The STRIP_FROM_INC_PATH tag can be used to strip a user-defined part of # the path mentioned in the documentation of a class, which tells # the reader which header file to include in order to use a class. # If left blank only the name of the header file containing the class # definition is used. Otherwise one should specify the include paths that # are normally passed to the compiler using the -I flag. STRIP_FROM_INC_PATH = # If the SHORT_NAMES tag is set to YES, doxygen will generate much shorter # (but less readable) file names. This can be useful is your file systems # doesn't support long names like on DOS, Mac, or CD-ROM. SHORT_NAMES = NO # If the JAVADOC_AUTOBRIEF tag is set to YES then Doxygen # will interpret the first line (until the first dot) of a JavaDoc-style # comment as the brief description. If set to NO, the JavaDoc # comments will behave just like the Qt-style comments (thus requiring an # explicit @brief command for a brief description. JAVADOC_AUTOBRIEF = YES # The MULTILINE_CPP_IS_BRIEF tag can be set to YES to make Doxygen # treat a multi-line C++ special comment block (i.e. a block of //! or /// # comments) as a brief description. This used to be the default behaviour. # The new default is to treat a multi-line C++ comment block as a detailed # description. Set this tag to YES if you prefer the old behaviour instead. MULTILINE_CPP_IS_BRIEF = NO # If the INHERIT_DOCS tag is set to YES (the default) then an undocumented # member inherits the documentation from any documented member that it # re-implements. INHERIT_DOCS = YES # If the SEPARATE_MEMBER_PAGES tag is set to YES, then doxygen will produce # a new page for each member. If set to NO, the documentation of a member will # be part of the file/class/namespace that contains it. SEPARATE_MEMBER_PAGES = NO # The TAB_SIZE tag can be used to set the number of spaces in a tab. # Doxygen uses this value to replace tabs by spaces in code fragments. TAB_SIZE = 8 # This tag can be used to specify a number of aliases that acts # as commands in the documentation. An alias has the form "name=value". # For example adding "sideeffect=\par Side Effects:\n" will allow you to # put the command \sideeffect (or @sideeffect) in the documentation, which # will result in a user-defined paragraph with heading "Side Effects:". # You can put \n's in the value part of an alias to insert newlines. ALIASES = # Set the OPTIMIZE_OUTPUT_FOR_C tag to YES if your project consists of C # sources only. Doxygen will then generate output that is more tailored for C. # For instance, some of the names that are used will be different. The list # of all members will be omitted, etc. OPTIMIZE_OUTPUT_FOR_C = NO # Set the OPTIMIZE_OUTPUT_JAVA tag to YES if your project consists of Java # sources only. Doxygen will then generate output that is more tailored for Java. # For instance, namespaces will be presented as packages, qualified scopes # will look different, etc. OPTIMIZE_OUTPUT_JAVA = NO # If you use STL classes (i.e. std::string, std::vector, etc.) but do not want to # include (a tag file for) the STL sources as input, then you should # set this tag to YES in order to let doxygen match functions declarations and # definitions whose arguments contain STL classes (e.g. func(std::string); v.s. # func(std::string) {}). This also make the inheritance and collaboration # diagrams that involve STL classes more complete and accurate. BUILTIN_STL_SUPPORT = NO # If you use Microsoft's C++/CLI language, you should set this option to YES to # enable parsing support. CPP_CLI_SUPPORT = NO # If member grouping is used in the documentation and the DISTRIBUTE_GROUP_DOC # tag is set to YES, then doxygen will reuse the documentation of the first # member in the group (if any) for the other members of the group. By default # all members of a group must be documented explicitly. DISTRIBUTE_GROUP_DOC = NO # Set the SUBGROUPING tag to YES (the default) to allow class member groups of # the same type (for instance a group of public functions) to be put as a # subgroup of that type (e.g. under the Public Functions section). Set it to # NO to prevent subgrouping. Alternatively, this can be done per class using # the \nosubgrouping command. SUBGROUPING = YES #--------------------------------------------------------------------------- # Build related configuration options #--------------------------------------------------------------------------- # If the EXTRACT_ALL tag is set to YES doxygen will assume all entities in # documentation are documented, even if no documentation was available. # Private class members and static file members will be hidden unless # the EXTRACT_PRIVATE and EXTRACT_STATIC tags are set to YES EXTRACT_ALL = NO # If the EXTRACT_PRIVATE tag is set to YES all private members of a class # will be included in the documentation. EXTRACT_PRIVATE = NO # If the EXTRACT_STATIC tag is set to YES all static members of a file # will be included in the documentation. EXTRACT_STATIC = NO # If the EXTRACT_LOCAL_CLASSES tag is set to YES classes (and structs) # defined locally in source files will be included in the documentation. # If set to NO only classes defined in header files are included. EXTRACT_LOCAL_CLASSES = NO # This flag is only useful for Objective-C code. When set to YES local # methods, which are defined in the implementation section but not in # the interface are included in the documentation. # If set to NO (the default) only methods in the interface are included. EXTRACT_LOCAL_METHODS = NO # If the HIDE_UNDOC_MEMBERS tag is set to YES, Doxygen will hide all # undocumented members of documented classes, files or namespaces. # If set to NO (the default) these members will be included in the # various overviews, but no documentation section is generated. # This option has no effect if EXTRACT_ALL is enabled. HIDE_UNDOC_MEMBERS = YES # If the HIDE_UNDOC_CLASSES tag is set to YES, Doxygen will hide all # undocumented classes that are normally visible in the class hierarchy. # If set to NO (the default) these classes will be included in the various # overviews. This option has no effect if EXTRACT_ALL is enabled. HIDE_UNDOC_CLASSES = YES # If the HIDE_FRIEND_COMPOUNDS tag is set to YES, Doxygen will hide all # friend (class|struct|union) declarations. # If set to NO (the default) these declarations will be included in the # documentation. HIDE_FRIEND_COMPOUNDS = YES # If the HIDE_IN_BODY_DOCS tag is set to YES, Doxygen will hide any # documentation blocks found inside the body of a function. # If set to NO (the default) these blocks will be appended to the # function's detailed documentation block. HIDE_IN_BODY_DOCS = NO # The INTERNAL_DOCS tag determines if documentation # that is typed after a \internal command is included. If the tag is set # to NO (the default) then the documentation will be excluded. # Set it to YES to include the internal documentation. INTERNAL_DOCS = NO # If the CASE_SENSE_NAMES tag is set to NO then Doxygen will only generate # file names in lower-case letters. If set to YES upper-case letters are also # allowed. This is useful if you have classes or files whose names only differ # in case and if your file system supports case sensitive file names. Windows # and Mac users are advised to set this option to NO. CASE_SENSE_NAMES = YES # If the HIDE_SCOPE_NAMES tag is set to NO (the default) then Doxygen # will show members with their full class and namespace scopes in the # documentation. If set to YES the scope will be hidden. HIDE_SCOPE_NAMES = NO # If the SHOW_INCLUDE_FILES tag is set to YES (the default) then Doxygen # will put a list of the files that are included by a file in the documentation # of that file. SHOW_INCLUDE_FILES = YES # If the INLINE_INFO tag is set to YES (the default) then a tag [inline] # is inserted in the documentation for inline members. INLINE_INFO = YES # If the SORT_MEMBER_DOCS tag is set to YES (the default) then doxygen # will sort the (detailed) documentation of file and class members # alphabetically by member name. If set to NO the members will appear in # declaration order. SORT_MEMBER_DOCS = YES # If the SORT_BRIEF_DOCS tag is set to YES then doxygen will sort the # brief documentation of file, namespace and class members alphabetically # by member name. If set to NO (the default) the members will appear in # declaration order. SORT_BRIEF_DOCS = YES # If the SORT_BY_SCOPE_NAME tag is set to YES, the class list will be # sorted by fully-qualified names, including namespaces. If set to # NO (the default), the class list will be sorted only by class name, # not including the namespace part. # Note: This option is not very useful if HIDE_SCOPE_NAMES is set to YES. # Note: This option applies only to the class list, not to the # alphabetical list. SORT_BY_SCOPE_NAME = NO # The GENERATE_TODOLIST tag can be used to enable (YES) or # disable (NO) the todo list. This list is created by putting \todo # commands in the documentation. GENERATE_TODOLIST = YES # The GENERATE_TESTLIST tag can be used to enable (YES) or # disable (NO) the test list. This list is created by putting \test # commands in the documentation. GENERATE_TESTLIST = YES # The GENERATE_BUGLIST tag can be used to enable (YES) or # disable (NO) the bug list. This list is created by putting \bug # commands in the documentation. GENERATE_BUGLIST = YES # The GENERATE_DEPRECATEDLIST tag can be used to enable (YES) or # disable (NO) the deprecated list. This list is created by putting # \deprecated commands in the documentation. GENERATE_DEPRECATEDLIST= YES # The ENABLED_SECTIONS tag can be used to enable conditional # documentation sections, marked by \if sectionname ... \endif. ENABLED_SECTIONS = # The MAX_INITIALIZER_LINES tag determines the maximum number of lines # the initial value of a variable or define consists of for it to appear in # the documentation. If the initializer consists of more lines than specified # here it will be hidden. Use a value of 0 to hide initializers completely. # The appearance of the initializer of individual variables and defines in the # documentation can be controlled using \showinitializer or \hideinitializer # command in the documentation regardless of this setting. MAX_INITIALIZER_LINES = 30 # Set the SHOW_USED_FILES tag to NO to disable the list of files generated # at the bottom of the documentation of classes and structs. If set to YES the # list will mention the files that were used to generate the documentation. SHOW_USED_FILES = YES # If the sources in your project are distributed over multiple directories # then setting the SHOW_DIRECTORIES tag to YES will show the directory hierarchy # in the documentation. The default is NO. SHOW_DIRECTORIES = NO # The FILE_VERSION_FILTER tag can be used to specify a program or script that # doxygen should invoke to get the current version for each file (typically from the # version control system). Doxygen will invoke the program by executing (via # popen()) the command , where is the value of # the FILE_VERSION_FILTER tag, and is the name of an input file # provided by doxygen. Whatever the program writes to standard output # is used as the file version. See the manual for examples. FILE_VERSION_FILTER = #--------------------------------------------------------------------------- # configuration options related to warning and progress messages #--------------------------------------------------------------------------- # The QUIET tag can be used to turn on/off the messages that are generated # by doxygen. Possible values are YES and NO. If left blank NO is used. QUIET = NO # The WARNINGS tag can be used to turn on/off the warning messages that are # generated by doxygen. Possible values are YES and NO. If left blank # NO is used. WARNINGS = YES # If WARN_IF_UNDOCUMENTED is set to YES, then doxygen will generate warnings # for undocumented members. If EXTRACT_ALL is set to YES then this flag will # automatically be disabled. WARN_IF_UNDOCUMENTED = YES # If WARN_IF_DOC_ERROR is set to YES, doxygen will generate warnings for # potential errors in the documentation, such as not documenting some # parameters in a documented function, or documenting parameters that # don't exist or using markup commands wrongly. WARN_IF_DOC_ERROR = YES # This WARN_NO_PARAMDOC option can be abled to get warnings for # functions that are documented, but have no documentation for their parameters # or return value. If set to NO (the default) doxygen will only warn about # wrong or incomplete parameter documentation, but not about the absence of # documentation. WARN_NO_PARAMDOC = NO # The WARN_FORMAT tag determines the format of the warning messages that # doxygen can produce. The string should contain the $file, $line, and $text # tags, which will be replaced by the file and line number from which the # warning originated and the warning text. Optionally the format may contain # $version, which will be replaced by the version of the file (if it could # be obtained via FILE_VERSION_FILTER) WARN_FORMAT = "$file:$line: $text" # The WARN_LOGFILE tag can be used to specify a file to which warning # and error messages should be written. If left blank the output is written # to stderr. WARN_LOGFILE = #--------------------------------------------------------------------------- # configuration options related to the input files #--------------------------------------------------------------------------- # The INPUT tag can be used to specify the files and/or directories that contain # documented source files. You may enter file names like "myfile.cpp" or # directories like "/usr/src/myproject". Separate the files or directories # with spaces. INPUT = libmapi++ # This tag can be used to specify the character encoding of the source files that # doxygen parses. Internally doxygen uses the UTF-8 encoding, which is also the default # input encoding. Doxygen uses libiconv (or the iconv built into libc) for the transcoding. # See http://www.gnu.org/software/libiconv for the list of possible encodings. INPUT_ENCODING = UTF-8 # If the value of the INPUT tag contains directories, you can use the # FILE_PATTERNS tag to specify one or more wildcard pattern (like *.cpp # and *.h) to filter out the source-files in the directories. If left # blank the following patterns are tested: # *.c *.cc *.cxx *.cpp *.c++ *.java *.ii *.ixx *.ipp *.i++ *.inl *.h *.hh *.hxx # *.hpp *.h++ *.idl *.odl *.cs *.php *.php3 *.inc *.m *.mm *.py FILE_PATTERNS = *.h *.doxy # The RECURSIVE tag can be used to turn specify whether or not subdirectories # should be searched for input files as well. Possible values are YES and NO. # If left blank NO is used. RECURSIVE = NO # The EXCLUDE tag can be used to specify files and/or directories that should # excluded from the INPUT source files. This way you can easily exclude a # subdirectory from a directory tree whose root is specified with the INPUT tag. EXCLUDE = # The EXCLUDE_SYMLINKS tag can be used select whether or not files or # directories that are symbolic links (a Unix filesystem feature) are excluded # from the input. EXCLUDE_SYMLINKS = NO # If the value of the INPUT tag contains directories, you can use the # EXCLUDE_PATTERNS tag to specify one or more wildcard patterns to exclude # certain files from those directories. Note that the wildcards are matched # against the file with absolute path, so to exclude all test directories # for example use the pattern */test/* EXCLUDE_PATTERNS = # The EXCLUDE_SYMBOLS tag can be used to specify one or more symbol names # (namespaces, classes, functions, etc.) that should be excluded from the output. # The symbol name can be a fully qualified name, a word, or if the wildcard * is used, # a substring. Examples: ANamespace, AClass, AClass::ANamespace, ANamespace::*Test EXCLUDE_SYMBOLS = # The EXAMPLE_PATH tag can be used to specify one or more files or # directories that contain example code fragments that are included (see # the \include command). EXAMPLE_PATH = libmapi++/tests libmapi++/examples # If the value of the EXAMPLE_PATH tag contains directories, you can use the # EXAMPLE_PATTERNS tag to specify one or more wildcard pattern (like *.cpp # and *.h) to filter out the source-files in the directories. If left # blank all files are included. EXAMPLE_PATTERNS = # If the EXAMPLE_RECURSIVE tag is set to YES then subdirectories will be # searched for input files to be used with the \include or \dontinclude # commands irrespective of the value of the RECURSIVE tag. # Possible values are YES and NO. If left blank NO is used. EXAMPLE_RECURSIVE = NO # The IMAGE_PATH tag can be used to specify one or more files or # directories that contain image that are included in the documentation (see # the \image command). IMAGE_PATH = doc/doxygen/pictures/ # The INPUT_FILTER tag can be used to specify a program that doxygen should # invoke to filter for each input file. Doxygen will invoke the filter program # by executing (via popen()) the command , where # is the value of the INPUT_FILTER tag, and is the name of an # input file. Doxygen will then use the output that the filter program writes # to standard output. If FILTER_PATTERNS is specified, this tag will be # ignored. INPUT_FILTER = # The FILTER_PATTERNS tag can be used to specify filters on a per file pattern # basis. Doxygen will compare the file name with each pattern and apply the # filter if there is a match. The filters are a list of the form: # pattern=filter (like *.cpp=my_cpp_filter). See INPUT_FILTER for further # info on how filters are used. If FILTER_PATTERNS is empty, INPUT_FILTER # is applied to all files. FILTER_PATTERNS = # If the FILTER_SOURCE_FILES tag is set to YES, the input filter (if set using # INPUT_FILTER) will be used to filter the input files when producing source # files to browse (i.e. when SOURCE_BROWSER is set to YES). FILTER_SOURCE_FILES = NO #--------------------------------------------------------------------------- # configuration options related to source browsing #--------------------------------------------------------------------------- # If the SOURCE_BROWSER tag is set to YES then a list of source files will # be generated. Documented entities will be cross-referenced with these sources. # Note: To get rid of all source code in the generated output, make sure also # VERBATIM_HEADERS is set to NO. SOURCE_BROWSER = NO # Setting the INLINE_SOURCES tag to YES will include the body # of functions and classes directly in the documentation. INLINE_SOURCES = NO # Setting the STRIP_CODE_COMMENTS tag to YES (the default) will instruct # doxygen to hide any special comment blocks from generated source code # fragments. Normal C and C++ comments will always remain visible. STRIP_CODE_COMMENTS = YES # If the REFERENCED_BY_RELATION tag is set to YES (the default) # then for each documented function all documented # functions referencing it will be listed. REFERENCED_BY_RELATION = YES # If the REFERENCES_RELATION tag is set to YES (the default) # then for each documented function all documented entities # called/used by that function will be listed. REFERENCES_RELATION = YES # If the REFERENCES_LINK_SOURCE tag is set to YES (the default) # and SOURCE_BROWSER tag is set to YES, then the hyperlinks from # functions in REFERENCES_RELATION and REFERENCED_BY_RELATION lists will # link to the source code. Otherwise they will link to the documentstion. REFERENCES_LINK_SOURCE = YES # If the USE_HTAGS tag is set to YES then the references to source code # will point to the HTML generated by the htags(1) tool instead of doxygen # built-in source browser. The htags tool is part of GNU's global source # tagging system (see http://www.gnu.org/software/global/global.html). You # will need version 4.8.6 or higher. USE_HTAGS = NO # If the VERBATIM_HEADERS tag is set to YES (the default) then Doxygen # will generate a verbatim copy of the header file for each class for # which an include is specified. Set to NO to disable this. VERBATIM_HEADERS = NO #--------------------------------------------------------------------------- # configuration options related to the alphabetical class index #--------------------------------------------------------------------------- # If the ALPHABETICAL_INDEX tag is set to YES, an alphabetical index # of all compounds will be generated. Enable this if the project # contains a lot of classes, structs, unions or interfaces. ALPHABETICAL_INDEX = NO # If the alphabetical index is enabled (see ALPHABETICAL_INDEX) then # the COLS_IN_ALPHA_INDEX tag can be used to specify the number of columns # in which this list will be split (can be a number in the range [1..20]) COLS_IN_ALPHA_INDEX = 5 # In case all classes in a project start with a common prefix, all # classes will be put under the same header in the alphabetical index. # The IGNORE_PREFIX tag can be used to specify one or more prefixes that # should be ignored while generating the index headers. IGNORE_PREFIX = #--------------------------------------------------------------------------- # configuration options related to the HTML output #--------------------------------------------------------------------------- # If the GENERATE_HTML tag is set to YES (the default) Doxygen will # generate HTML output. GENERATE_HTML = YES # The HTML_OUTPUT tag is used to specify where the HTML docs will be put. # If a relative path is entered the value of OUTPUT_DIRECTORY will be # put in front of it. If left blank `html' will be used as the default path. HTML_OUTPUT = html/libmapi++ # The HTML_FILE_EXTENSION tag can be used to specify the file extension for # each generated HTML page (for example: .htm,.php,.asp). If it is left blank # doxygen will generate files with .html extension. HTML_FILE_EXTENSION = .html # The HTML_HEADER tag can be used to specify a personal HTML header for # each generated HTML page. If it is left blank doxygen will generate a # standard header. HTML_HEADER = doc/doxygen/header.html # The HTML_FOOTER tag can be used to specify a personal HTML footer for # each generated HTML page. If it is left blank doxygen will generate a # standard footer. HTML_FOOTER = doc/doxygen/footer.html # The HTML_STYLESHEET tag can be used to specify a user-defined cascading # style sheet that is used by each HTML page. It can be used to # fine-tune the look of the HTML output. If the tag is left blank doxygen # will generate a default style sheet. Note that doxygen will try to copy # the style sheet file to the HTML output directory, so don't put your own # stylesheet in the HTML output directory as well, or it will be erased! HTML_STYLESHEET = doc/doxygen/apidocs.css # If the HTML_ALIGN_MEMBERS tag is set to YES, the members of classes, # files or namespaces will be aligned in HTML using tables. If set to # NO a bullet list will be used. HTML_ALIGN_MEMBERS = YES # If the GENERATE_HTMLHELP tag is set to YES, additional index files # will be generated that can be used as input for tools like the # Microsoft HTML help workshop to generate a compressed HTML help file (.chm) # of the generated HTML documentation. GENERATE_HTMLHELP = NO # If the GENERATE_HTMLHELP tag is set to YES, the CHM_FILE tag can # be used to specify the file name of the resulting .chm file. You # can add a path in front of the file if the result should not be # written to the html output directory. CHM_FILE = # If the GENERATE_HTMLHELP tag is set to YES, the HHC_LOCATION tag can # be used to specify the location (absolute path including file name) of # the HTML help compiler (hhc.exe). If non-empty doxygen will try to run # the HTML help compiler on the generated index.hhp. HHC_LOCATION = # If the GENERATE_HTMLHELP tag is set to YES, the GENERATE_CHI flag # controls if a separate .chi index file is generated (YES) or that # it should be included in the master .chm file (NO). GENERATE_CHI = NO # If the GENERATE_HTMLHELP tag is set to YES, the BINARY_TOC flag # controls whether a binary table of contents is generated (YES) or a # normal table of contents (NO) in the .chm file. BINARY_TOC = NO # The TOC_EXPAND flag can be set to YES to add extra items for group members # to the contents of the HTML help documentation and to the tree view. TOC_EXPAND = NO # The DISABLE_INDEX tag can be used to turn on/off the condensed index at # top of each HTML page. The value NO (the default) enables the index and # the value YES disables it. DISABLE_INDEX = NO # This tag can be used to set the number of enum values (range [1..20]) # that doxygen will group on one line in the generated HTML documentation. ENUM_VALUES_PER_LINE = 4 # If the GENERATE_TREEVIEW tag is set to YES, a side panel will be # generated containing a tree-like index structure (just like the one that # is generated for HTML Help). For this to work a browser that supports # JavaScript, DHTML, CSS and frames is required (for instance Mozilla 1.0+, # Netscape 6.0+, Internet explorer 5.0+, or Konqueror). Windows users are # probably better off using the HTML help feature. GENERATE_TREEVIEW = NO # If the treeview is enabled (see GENERATE_TREEVIEW) then this tag can be # used to set the initial width (in pixels) of the frame in which the tree # is shown. TREEVIEW_WIDTH = 250 #--------------------------------------------------------------------------- # configuration options related to the LaTeX output #--------------------------------------------------------------------------- # If the GENERATE_LATEX tag is set to YES (the default) Doxygen will # generate Latex output. GENERATE_LATEX = NO # The LATEX_OUTPUT tag is used to specify where the LaTeX docs will be put. # If a relative path is entered the value of OUTPUT_DIRECTORY will be # put in front of it. If left blank `latex' will be used as the default path. LATEX_OUTPUT = latex # The LATEX_CMD_NAME tag can be used to specify the LaTeX command name to be # invoked. If left blank `latex' will be used as the default command name. LATEX_CMD_NAME = latex # The MAKEINDEX_CMD_NAME tag can be used to specify the command name to # generate index for LaTeX. If left blank `makeindex' will be used as the # default command name. MAKEINDEX_CMD_NAME = makeindex # If the COMPACT_LATEX tag is set to YES Doxygen generates more compact # LaTeX documents. This may be useful for small projects and may help to # save some trees in general. COMPACT_LATEX = NO # The PAPER_TYPE tag can be used to set the paper type that is used # by the printer. Possible values are: a4, a4wide, letter, legal and # executive. If left blank a4wide will be used. PAPER_TYPE = letter # The EXTRA_PACKAGES tag can be to specify one or more names of LaTeX # packages that should be included in the LaTeX output. EXTRA_PACKAGES = # The LATEX_HEADER tag can be used to specify a personal LaTeX header for # the generated latex document. The header should contain everything until # the first chapter. If it is left blank doxygen will generate a # standard header. Notice: only use this tag if you know what you are doing! LATEX_HEADER = # If the PDF_HYPERLINKS tag is set to YES, the LaTeX that is generated # is prepared for conversion to pdf (using ps2pdf). The pdf file will # contain links (just like the HTML output) instead of page references # This makes the output suitable for online browsing using a pdf viewer. PDF_HYPERLINKS = YES # If the USE_PDFLATEX tag is set to YES, pdflatex will be used instead of # plain latex in the generated Makefile. Set this option to YES to get a # higher quality PDF documentation. USE_PDFLATEX = YES # If the LATEX_BATCHMODE tag is set to YES, doxygen will add the \\batchmode. # command to the generated LaTeX files. This will instruct LaTeX to keep # running if errors occur, instead of asking the user for help. # This option is also used when generating formulas in HTML. LATEX_BATCHMODE = NO # If LATEX_HIDE_INDICES is set to YES then doxygen will not # include the index chapters (such as File Index, Compound Index, etc.) # in the output. LATEX_HIDE_INDICES = NO #--------------------------------------------------------------------------- # configuration options related to the RTF output #--------------------------------------------------------------------------- # If the GENERATE_RTF tag is set to YES Doxygen will generate RTF output # The RTF output is optimized for Word 97 and may not look very pretty with # other RTF readers or editors. GENERATE_RTF = NO # The RTF_OUTPUT tag is used to specify where the RTF docs will be put. # If a relative path is entered the value of OUTPUT_DIRECTORY will be # put in front of it. If left blank `rtf' will be used as the default path. RTF_OUTPUT = rtf # If the COMPACT_RTF tag is set to YES Doxygen generates more compact # RTF documents. This may be useful for small projects and may help to # save some trees in general. COMPACT_RTF = NO # If the RTF_HYPERLINKS tag is set to YES, the RTF that is generated # will contain hyperlink fields. The RTF file will # contain links (just like the HTML output) instead of page references. # This makes the output suitable for online browsing using WORD or other # programs which support those fields. # Note: wordpad (write) and others do not support links. RTF_HYPERLINKS = NO # Load stylesheet definitions from file. Syntax is similar to doxygen's # config file, i.e. a series of assignments. You only have to provide # replacements, missing definitions are set to their default value. RTF_STYLESHEET_FILE = # Set optional variables used in the generation of an rtf document. # Syntax is similar to doxygen's config file. RTF_EXTENSIONS_FILE = #--------------------------------------------------------------------------- # configuration options related to the man page output #--------------------------------------------------------------------------- # If the GENERATE_MAN tag is set to YES (the default) Doxygen will # generate man pages GENERATE_MAN = NO # The MAN_OUTPUT tag is used to specify where the man pages will be put. # If a relative path is entered the value of OUTPUT_DIRECTORY will be # put in front of it. If left blank `man' will be used as the default path. MAN_OUTPUT = man # The MAN_EXTENSION tag determines the extension that is added to # the generated man pages (default is the subroutine's section .3) MAN_EXTENSION = .3 # If the MAN_LINKS tag is set to YES and Doxygen generates man output, # then it will generate one additional man file for each entity # documented in the real man page(s). These additional files # only source the real man page, but without them the man command # would be unable to find the correct page. The default is NO. MAN_LINKS = YES #--------------------------------------------------------------------------- # configuration options related to the XML output #--------------------------------------------------------------------------- # If the GENERATE_XML tag is set to YES Doxygen will # generate an XML file that captures the structure of # the code including all documentation. GENERATE_XML = NO # The XML_OUTPUT tag is used to specify where the XML pages will be put. # If a relative path is entered the value of OUTPUT_DIRECTORY will be # put in front of it. If left blank `xml' will be used as the default path. XML_OUTPUT = xml # The XML_SCHEMA tag can be used to specify an XML schema, # which can be used by a validating XML parser to check the # syntax of the XML files. XML_SCHEMA = # The XML_DTD tag can be used to specify an XML DTD, # which can be used by a validating XML parser to check the # syntax of the XML files. XML_DTD = # If the XML_PROGRAMLISTING tag is set to YES Doxygen will # dump the program listings (including syntax highlighting # and cross-referencing information) to the XML output. Note that # enabling this will significantly increase the size of the XML output. XML_PROGRAMLISTING = YES #--------------------------------------------------------------------------- # configuration options for the AutoGen Definitions output #--------------------------------------------------------------------------- # If the GENERATE_AUTOGEN_DEF tag is set to YES Doxygen will # generate an AutoGen Definitions (see autogen.sf.net) file # that captures the structure of the code including all # documentation. Note that this feature is still experimental # and incomplete at the moment. GENERATE_AUTOGEN_DEF = NO #--------------------------------------------------------------------------- # configuration options related to the Perl module output #--------------------------------------------------------------------------- # If the GENERATE_PERLMOD tag is set to YES Doxygen will # generate a Perl module file that captures the structure of # the code including all documentation. Note that this # feature is still experimental and incomplete at the # moment. GENERATE_PERLMOD = NO # If the PERLMOD_LATEX tag is set to YES Doxygen will generate # the necessary Makefile rules, Perl scripts and LaTeX code to be able # to generate PDF and DVI output from the Perl module output. PERLMOD_LATEX = NO # If the PERLMOD_PRETTY tag is set to YES the Perl module output will be # nicely formatted so it can be parsed by a human reader. This is useful # if you want to understand what is going on. On the other hand, if this # tag is set to NO the size of the Perl module output will be much smaller # and Perl will parse it just the same. PERLMOD_PRETTY = YES # The names of the make variables in the generated doxyrules.make file # are prefixed with the string contained in PERLMOD_MAKEVAR_PREFIX. # This is useful so different doxyrules.make files included by the same # Makefile don't overwrite each other's variables. PERLMOD_MAKEVAR_PREFIX = #--------------------------------------------------------------------------- # Configuration options related to the preprocessor #--------------------------------------------------------------------------- # If the ENABLE_PREPROCESSING tag is set to YES (the default) Doxygen will # evaluate all C-preprocessor directives found in the sources and include # files. ENABLE_PREPROCESSING = YES # If the MACRO_EXPANSION tag is set to YES Doxygen will expand all macro # names in the source code. If set to NO (the default) only conditional # compilation will be performed. Macro expansion can be done in a controlled # way by setting EXPAND_ONLY_PREDEF to YES. MACRO_EXPANSION = NO # If the EXPAND_ONLY_PREDEF and MACRO_EXPANSION tags are both set to YES # then the macro expansion is limited to the macros specified with the # PREDEFINED and EXPAND_AS_DEFINED tags. EXPAND_ONLY_PREDEF = NO # If the SEARCH_INCLUDES tag is set to YES (the default) the includes files # in the INCLUDE_PATH (see below) will be search if a #include is found. SEARCH_INCLUDES = YES # The INCLUDE_PATH tag can be used to specify one or more directories that # contain include files that are not input files but should be processed by # the preprocessor. INCLUDE_PATH = # You can use the INCLUDE_FILE_PATTERNS tag to specify one or more wildcard # patterns (like *.h and *.hpp) to filter out the header-files in the # directories. If left blank, the patterns specified with FILE_PATTERNS will # be used. INCLUDE_FILE_PATTERNS = # The PREDEFINED tag can be used to specify one or more macro names that # are defined before the preprocessor is started (similar to the -D option of # gcc). The argument of the tag is a list of macros of the form: name # or name=definition (no spaces). If the definition and the = are # omitted =1 is assumed. To prevent a macro definition from being # undefined via #undef or recursively expanded use the := operator # instead of the = operator. PREDEFINED = _PUBLIC_ # If the MACRO_EXPANSION and EXPAND_ONLY_PREDEF tags are set to YES then # this tag can be used to specify a list of macro names that should be expanded. # The macro definition that is found in the sources will be used. # Use the PREDEFINED tag if you want to use a different macro definition. EXPAND_AS_DEFINED = # If the SKIP_FUNCTION_MACROS tag is set to YES (the default) then # doxygen's preprocessor will remove all function-like macros that are alone # on a line, have an all uppercase name, and do not end with a semicolon. Such # function macros are typically used for boiler-plate code, and will confuse # the parser if not removed. SKIP_FUNCTION_MACROS = YES #--------------------------------------------------------------------------- # Configuration::additions related to external references #--------------------------------------------------------------------------- # The TAGFILES option can be used to specify one or more tagfiles. # Optionally an initial location of the external documentation # can be added for each tagfile. The format of a tag file without # this location is as follows: # TAGFILES = file1 file2 ... # Adding location for the tag files is done as follows: # TAGFILES = file1=loc1 "file2 = loc2" ... # where "loc1" and "loc2" can be relative or absolute paths or # URLs. If a location is present for each tag, the installdox tool # does not have to be run to correct the links. # Note that each tag file must have a unique name # (where the name does NOT include the path) # If a tag file is not located in the directory in which doxygen # is run, you must also specify the path to the tagfile here. TAGFILES = # When a file name is specified after GENERATE_TAGFILE, doxygen will create # a tag file that is based on the input files it reads. GENERATE_TAGFILE = # If the ALLEXTERNALS tag is set to YES all external classes will be listed # in the class index. If set to NO only the inherited external classes # will be listed. ALLEXTERNALS = NO # If the EXTERNAL_GROUPS tag is set to YES all external groups will be listed # in the modules index. If set to NO, only the current project's groups will # be listed. EXTERNAL_GROUPS = YES # The PERL_PATH should be the absolute path and name of the perl script # interpreter (i.e. the result of `which perl'). PERL_PATH = /usr/bin/perl #--------------------------------------------------------------------------- # Configuration options related to the dot tool #--------------------------------------------------------------------------- # If the CLASS_DIAGRAMS tag is set to YES (the default) Doxygen will # generate a inheritance diagram (in HTML, RTF and LaTeX) for classes with base # or super classes. Setting the tag to NO turns the diagrams off. Note that # this option is superseded by the HAVE_DOT option below. This is only a # fallback. It is recommended to install and use dot, since it yields more # powerful graphs. CLASS_DIAGRAMS = YES # You can define message sequence charts within doxygen comments using the \msc # command. Doxygen will then run the mscgen tool (see http://www.mcternan.me.uk/mscgen/) to # produce the chart and insert it in the documentation. The MSCGEN_PATH tag allows you to # specify the directory where the mscgen tool resides. If left empty the tool is assumed to # be found in the default search path. MSCGEN_PATH = # If set to YES, the inheritance and collaboration graphs will hide # inheritance and usage relations if the target is undocumented # or is not a class. HIDE_UNDOC_RELATIONS = YES # If you set the HAVE_DOT tag to YES then doxygen will assume the dot tool is # available from the path. This tool is part of Graphviz, a graph visualization # toolkit from AT&T and Lucent Bell Labs. The other options in this section # have no effect if this option is set to NO (the default) HAVE_DOT = NO # If the CLASS_GRAPH and HAVE_DOT tags are set to YES then doxygen # will generate a graph for each documented class showing the direct and # indirect inheritance relations. Setting this tag to YES will force the # the CLASS_DIAGRAMS tag to NO. CLASS_GRAPH = YES # If the COLLABORATION_GRAPH and HAVE_DOT tags are set to YES then doxygen # will generate a graph for each documented class showing the direct and # indirect implementation dependencies (inheritance, containment, and # class references variables) of the class with other documented classes. COLLABORATION_GRAPH = YES # If the GROUP_GRAPHS and HAVE_DOT tags are set to YES then doxygen # will generate a graph for groups, showing the direct groups dependencies GROUP_GRAPHS = YES # If the UML_LOOK tag is set to YES doxygen will generate inheritance and # collaboration diagrams in a style similar to the OMG's Unified Modeling # Language. UML_LOOK = NO # If set to YES, the inheritance and collaboration graphs will show the # relations between templates and their instances. TEMPLATE_RELATIONS = NO # If the ENABLE_PREPROCESSING, SEARCH_INCLUDES, INCLUDE_GRAPH, and HAVE_DOT # tags are set to YES then doxygen will generate a graph for each documented # file showing the direct and indirect include dependencies of the file with # other documented files. INCLUDE_GRAPH = YES # If the ENABLE_PREPROCESSING, SEARCH_INCLUDES, INCLUDED_BY_GRAPH, and # HAVE_DOT tags are set to YES then doxygen will generate a graph for each # documented header file showing the documented files that directly or # indirectly include this file. INCLUDED_BY_GRAPH = YES # If the CALL_GRAPH and HAVE_DOT tags are set to YES then doxygen will # generate a call dependency graph for every global function or class method. # Note that enabling this option will significantly increase the time of a run. # So in most cases it will be better to enable call graphs for selected # functions only using the \callgraph command. CALL_GRAPH = NO # If the CALLER_GRAPH and HAVE_DOT tags are set to YES then doxygen will # generate a caller dependency graph for every global function or class method. # Note that enabling this option will significantly increase the time of a run. # So in most cases it will be better to enable caller graphs for selected # functions only using the \callergraph command. CALLER_GRAPH = NO # If the GRAPHICAL_HIERARCHY and HAVE_DOT tags are set to YES then doxygen # will graphical hierarchy of all classes instead of a textual one. GRAPHICAL_HIERARCHY = YES # If the DIRECTORY_GRAPH, SHOW_DIRECTORIES and HAVE_DOT tags are set to YES # then doxygen will show the dependencies a directory has on other directories # in a graphical way. The dependency relations are determined by the #include # relations between the files in the directories. DIRECTORY_GRAPH = YES # The DOT_IMAGE_FORMAT tag can be used to set the image format of the images # generated by dot. Possible values are png, jpg, or gif # If left blank png will be used. DOT_IMAGE_FORMAT = png # The tag DOT_PATH can be used to specify the path where the dot tool can be # found. If left blank, it is assumed the dot tool can be found in the path. DOT_PATH = # The DOTFILE_DIRS tag can be used to specify one or more directories that # contain dot files that are included in the documentation (see the # \dotfile command). DOTFILE_DIRS = # The MAX_DOT_GRAPH_MAX_NODES tag can be used to set the maximum number of # nodes that will be shown in the graph. If the number of nodes in a graph # becomes larger than this value, doxygen will truncate the graph, which is # visualized by representing a node as a red box. Note that doxygen will always # show the root nodes and its direct children regardless of this setting. DOT_GRAPH_MAX_NODES = 50 # Set the DOT_TRANSPARENT tag to YES to generate images with a transparent # background. This is disabled by default, which results in a white background. # Warning: Depending on the platform used, enabling this option may lead to # badly anti-aliased labels on the edges of a graph (i.e. they become hard to # read). DOT_TRANSPARENT = NO # Set the DOT_MULTI_TARGETS tag to YES allow dot to generate multiple output # files in one run (i.e. multiple -o and -T options on the command line). This # makes dot run faster, but since only newer versions of dot (>1.8.10) # support this, this feature is disabled by default. DOT_MULTI_TARGETS = NO # If the GENERATE_LEGEND tag is set to YES (the default) Doxygen will # generate a legend page explaining the meaning of the various boxes and # arrows in the dot generated graphs. GENERATE_LEGEND = YES # If the DOT_CLEANUP tag is set to YES (the default) Doxygen will # remove the intermediate dot files that are used to generate # the various graphs. DOT_CLEANUP = YES #--------------------------------------------------------------------------- # Configuration::additions related to the search engine #--------------------------------------------------------------------------- # The SEARCHENGINE tag specifies whether or not a search engine should be # used. If set to NO the values of all tags below this one will be ignored. SEARCHENGINE = NO openchange-2.0/libmapi++/attachment.h000066400000000000000000000051021223057412600175260ustar00rootroot00000000000000/* libmapi C++ Wrapper Attachment Class Copyright (C) Alan Alvarez 2008. This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see . */ #ifndef LIBMAPIPP__ATTACHMENT_H__ #define LIBMAPIPP__ATTACHMENT_H__ #include //for debugging #include #include #include namespace libmapipp { class object; /** * \brief This class represents a message %attachment * * A message can contain both text content, and also have attached * (embedded) files and messages. This class represents the attachments * for one messaage. * * You may not need to create the attachments yourself, since you can * create a container with all the attachments using message::fetch_attachments(). */ class attachment : public object { public: /** \brief Constructor * * \param mapi_message the message that this attachment belongs to. * \param attach_num Attachment Number. */ attachment(message& mapi_message, const uint32_t attach_num) throw(mapi_exception); /** * \brief The %attachment number */ uint32_t get_num() const { return m_attach_num; } /** * \brief the contents of the %attachment * * \note the length of the array is given by get_data_size() */ const uint8_t* get_data() const { return m_bin_data; } /** * \brief the size of the %attachment * * \return the size of the %attachment in bytes */ uint32_t get_data_size() const { return m_data_size; } /** * \brief the filename of the %attachment * * \note not all attachments have file names * * \return string containing the file name of the %attachment, if any */ std::string get_filename() const { return m_filename; } /** * Destructor */ virtual ~attachment() throw() { if (m_bin_data) delete[] m_bin_data; } private: uint32_t m_attach_num; uint8_t* m_bin_data; // (same as unsigned char* ?) uint32_t m_data_size; std::string m_filename; }; } // namespace libmapipp #endif //!LIBMAPIPP__ATTACHMENT_H__ openchange-2.0/libmapi++/clibmapi.h000066400000000000000000000014721223057412600171640ustar00rootroot00000000000000/* libmapi C++ Wrapper Copyright (C) Alan Alvarez 2008. This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see . */ #ifndef __CLIBMAPI_H #define __CLIBMAPI_H extern "C" { #include } #endif /* ! __CLIBMAPI_H */ openchange-2.0/libmapi++/examples/000077500000000000000000000000001223057412600170455ustar00rootroot00000000000000openchange-2.0/libmapi++/examples/foldertree.cpp000066400000000000000000000060451223057412600217110ustar00rootroot00000000000000/* libmapi C++ Wrapper Sample folder tree list application Copyright (C) Brad Hards 2008. This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see . */ #include #include #include int main () { try { // Initialize MAPI Session libmapipp::session mapi_session; // You could log in with a non-default profile here mapi_session.login(); // Get the private (user) folders message store libmapipp::message_store &msg_store = mapi_session.get_message_store(); // Get a property of the top level message store libmapipp::property_container msg_store_props = msg_store.get_property_container(); msg_store_props << PR_DISPLAY_NAME; // you could use other properties here msg_store_props.fetch(); // Display the property. You can also use a property_container_iterator // to work through the properties, but in this case there is only one. std::cout << "Message store display name: " << (const char*)msg_store_props[PR_DISPLAY_NAME] << std::endl; // Fetch the folder list. // We start off by fetching the top level folder mapi_id_t top_folder_id = msg_store.get_default_folder(olFolderTopInformationStore); libmapipp::folder top_folder(msg_store, top_folder_id); // Now get the child folders of the top level folder. These are returned as // a std::vector of pointers to folders libmapipp::folder::hierarchy_container_type child_folders = top_folder.fetch_hierarchy(); // Display the name, total item count and unread item count for each folder for (unsigned int i = 0; i < child_folders.size(); ++i) { libmapipp::property_container child_props = child_folders[i]->get_property_container(); child_props << PR_DISPLAY_NAME << PR_CONTENT_COUNT << PR_CONTENT_UNREAD; child_props.fetch(); std::cout << "|-----> " << (const char*)child_props[PR_DISPLAY_NAME] << " (" << (*(int*)child_props[PR_CONTENT_COUNT]) << " items, " << (*(int*)child_props[PR_CONTENT_UNREAD]) << " unread)" << std::endl; } } catch (libmapipp::mapi_exception e) // Catch any MAPI exceptions { std::cout << "MAPI Exception in main: " << e.what() << std::endl; } catch (std::runtime_error e) // Catch any other runtime exceptions { std::cout << "std::runtime_error exception in main: " << e.what() << std::endl; } return 0; } openchange-2.0/libmapi++/examples/messages.cpp000066400000000000000000000053161223057412600213650ustar00rootroot00000000000000/* libmapi C++ Wrapper Sample folder message application Copyright (C) Brad Hards 2008. This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see . */ #include #include #include int main () { try { // Initialize MAPI Session libmapipp::session mapi_session; // You could log in with a non-default profile here mapi_session.login(); // Get the private (user) folders message store libmapipp::message_store &msg_store = mapi_session.get_message_store(); // We start off by fetching the inbox mapi_id_t inbox_id = msg_store.get_default_folder(olFolderInbox); libmapipp::folder inbox_folder(msg_store, inbox_id); // Now get the messages in this folder These are returned as // a std::vector of pointers to messages libmapipp::folder::message_container_type messages = inbox_folder.fetch_messages(); std::cout << "Inbox contains " << messages.size() << " messages" << std::endl; // Work through each message for (unsigned int i = 0; i < messages.size(); ++i) { // Get the properties we are interested in libmapipp::property_container msg_props = messages[i]->get_property_container(); // We get the "to" addressee, and the subject // You can get a lot of other properties here (e.g. sender, body, etc). msg_props << PR_DISPLAY_TO << PR_CONVERSATION_TOPIC; msg_props.fetch(); // Display those properties if (msg_props[PR_DISPLAY_TO] != 0) { std::cout << "|-----> " << (const char*)msg_props[PR_DISPLAY_TO]; if(msg_props[PR_CONVERSATION_TOPIC] != 0) { std::cout << "\t\t| " << (const char*)msg_props[PR_CONVERSATION_TOPIC]; } std::cout << std::endl; } } } catch (libmapipp::mapi_exception e) // Catch any MAPI exceptions { std::cout << "MAPI Exception in main: " << e.what() << std::endl; } catch (std::runtime_error e) // Catch any other runtime exceptions { std::cout << "std::runtime_error exception in main: " << e.what() << std::endl; } return 0; } openchange-2.0/libmapi++/folder.h000066400000000000000000000057361223057412600166660ustar00rootroot00000000000000/* libmapi C++ Wrapper Folder Class Copyright (C) Alan Alvarez 2008. This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see . */ #ifndef LIBMAPIPP__FOLDER_H__ #define LIBMAPIPP__FOLDER_H__ #include //for debugging #include #include #include #include #include #include namespace libmapipp { /** * This class represents a %folder or container within Exchange */ class folder : public object { public: /** * Pointer to a message */ typedef boost::shared_ptr message_shared_ptr; typedef std::vector message_container_type; /** * Pointer to a %folder */ typedef boost::shared_ptr folder_shared_ptr; /** * Hierarchy folders * * This is a vector (list) of child folders for a given %folder */ typedef std::vector hierarchy_container_type; /** * \brief Constructor * * \param parent_folder The parent of this %folder. * \param folder_id This folder's id. */ folder(object& parent_folder, const mapi_id_t folder_id) throw(mapi_exception) : object(parent_folder.get_session(), "folder"), m_id(folder_id) { if (OpenFolder(&parent_folder.data(), folder_id, &m_object) != MAPI_E_SUCCESS) throw mapi_exception(GetLastError(), "folder::folder : OpenFolder"); } /** * \brief Obtain %folder id * * \return This folder's id. */ mapi_id_t get_id() const { return m_id; } /** * \brief Delete a message that belongs to this %folder * * \param message_id The id of the message to delete. */ void delete_message(mapi_id_t message_id) throw (mapi_exception) { if (DeleteMessage(&m_object, &message_id, 1) != MAPI_E_SUCCESS) throw mapi_exception(GetLastError(), "folder::delete_message : DeleteMessage"); } /** * \brief Fetch all messages in this %folder * * \return A container of message shared pointers. */ message_container_type fetch_messages() throw(mapi_exception); /** * \brief Fetch all subfolders within this %folder * * \return A container of %folder shared pointers. */ hierarchy_container_type fetch_hierarchy() throw(mapi_exception); /** * Destructor */ virtual ~folder() throw() { } private: mapi_id_t m_id; }; } // namespace libmapipp #endif //!LIBMAPIPP__FOLDER_H__ openchange-2.0/libmapi++/libmapi++-example.doxy000066400000000000000000000026211223057412600213310ustar00rootroot00000000000000/** \example test.cpp An example that shows reading mail. */ /** \example attach_test.cpp An example that shows reading of attachments. */ /** \example foldertree.cpp This example lists the top level folders in the message store, with output like: \code Message store display name: Mailbox - Test User1 |-----> Calendar (0 items, 0 unread) |-----> Contacts (0 items, 0 unread) |-----> Deleted Items (0 items, 0 unread) |-----> Drafts (0 items, 0 unread) |-----> Inbox (26 items, 24 unread) |-----> Journal (0 items, 0 unread) |-----> Notes (0 items, 0 unread) |-----> Outbox (9 items, 0 unread) |-----> Sent Items (0 items, 0 unread) |-----> Tasks (0 items, 0 unread) \endcode The example shows how to create a session, get the message_store, get properties of the message store, and then gets the list of child folders and some associated folder properties. */ /** \example messages.cpp This example displays information about the messages in the inbox, with output like: \code Inbox contains 2 messages |-----> Test User1 | Working Remotely with Windows Small Business Server |-----> Test User1 | Welcome to Windows Small Business Server 2003 \endcode The example shows how to create a session, get the message_store, and open the inbox folder. It then determines how many messages are in the inbox folder, and retrieves and prints the intended addressee and the message subject. */ openchange-2.0/libmapi++/libmapi++-mainpage.doxy000066400000000000000000000117101223057412600214560ustar00rootroot00000000000000/** \mainpage libmapi++

libmapi++ - C++ Bindings for OpenChange Clients

libmapi++ provides C++ bindings for OpenChange client libraries (libmapi). It is intended to provide a higher level abstraction of the OpenChange client libraries for C++ users who would prefer to work with an object-oriented API.

Using libmapi++

\note libmapi++ classes live in the libmapipp namespace. When using libmapi++, you start by creating a session, and logging in to the server. \code // Initialize MAPI Session libmapipp::session mapi_session; // login() can use an optional profile_name, and an optional password mapi_session.login(); \endcode The session can then access the message store, which is the tree of private folders associated with a single user (containing various folders, such as the Inbox, Sent Mail, Calendar, Journal and so on). The message store is associated with the session, so you don't create it yourself. Instead, you obtain it using the session object's get_message_store() method. \code // Take a reference to the message store libmapipp::message_store &msg_store = mapi_session.get_message_store(); \endcode \note It has to be a reference, not a copy / assignment. Most objects in libmapi++ (and any kind of MAPI library) can be considered to have properties that belong to them, and subordinate (child) objects. For example, the name of the message store is a property of the message store, but the various folders in the message store (or equally, the messages in a folder, or the attachments to a message) are part of a hierachy. To get access to the properties of an object, you obtain the property_container associated with the object, set the properties you want to access, call fetch(), and then read off the various properties. \code // Get a property of the top level message store libmapipp::property_container msg_store_props = msg_store.get_property_container(); msg_store_props << PR_DISPLAY_NAME; // you could use other properties here msg_store_props.fetch(); std::cout << "Message store display name: " << (const char*)msg_store_props[PR_DISPLAY_NAME] << std::endl; \endcode Note that the operator[] is essentially a lookup operator. If you'd prefer to use an iterator, look at libmapipp::property_container_iterator. As noted above, the objects in libmapi++ can be considered as a hierachy. To get the child elements for an object, you use the hierachy table for that element. For example, to get the various folders in the private information store, you could use code like this: \code // We start off by fetching the top level folder mapi_id_t top_folder_id = msg_store.get_default_folder(olFolderTopInformationStore); libmapipp::folder top_folder(msg_store, top_folder_id); // Now get the child folders of the top level folder. These are returned as // a std::vector of pointers to folders libmapipp::folder::hierarchy_container_type child_folders = top_folder.fetch_hierarchy(); // Display the name, total item count and unread item count for each folder for (unsigned int i = 0; i < child_folders.size(); ++i) { libmapipp::property_container child_props = child_folders[i]->get_property_container(); child_props << PR_DISPLAY_NAME << PR_CONTENT_COUNT << PR_CONTENT_UNREAD; child_props.fetch(); std::cout << "|-----> " << (const char*)child_props[PR_DISPLAY_NAME] << " (" << (*(int*)child_props[PR_CONTENT_COUNT]) << " items, " << (*(int*)child_props[PR_CONTENT_UNREAD]) << " unread)" << std::endl; } \endcode As an alternative to working through the folder tree hierachy, you can also open folders directly. In the example below, we open the Inbox. The API documentation for message_store::get_default_folder() provides a list of other folder IDs that you may find useful. \code mapi_id_t inbox_id = msg_store.get_default_folder(olFolderInbox); libmapipp::folder inbox_folder(msg_store, inbox_id); \endcode You can then get each message in the folder: \code // These are returned as a std::vector of pointers to messages libmapipp::folder::message_container_type messages = inbox_folder.fetch_messages(); std::cout << "Inbox contains " << messages.size() << " messages" << std::endl; \endcode You can then get the various properties of each message in the same way as was used for the folder properties - you get the associated property_container, set the required properties, and call fetch() before reading off the required properties: \code // Work through each message for (unsigned int i = 0; i < messages.size(); ++i) { // Get the properties we are interested in libmapipp::property_container msg_props = messages[i]->get_property_container(); // We get the "to" addressee, and the subject msg_props << PR_DISPLAY_TO << PR_CONVERSATION_TOPIC; msg_props.fetch(); // Display those properties std::cout << "|-----> " << (const char*)msg_props[PR_DISPLAY_TO] << "\t\t| " << (const char*)msg_props[PR_CONVERSATION_TOPIC] << std::endl; } \endcode \todo Explain attachments. */ openchange-2.0/libmapi++/libmapi++.h000066400000000000000000000021331223057412600171420ustar00rootroot00000000000000/* libmapi C++ Wrapper MAPI Exception Class Copyright (C) Alan Alvarez 2008. This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see . */ #ifndef __LIBMAPIPP_H #define __LIBMAPIPP_H #include #include #include #include #include #include #include #include #include #endif /* ! __LIBMAPIPP_H */ openchange-2.0/libmapi++/mapi_exception.h000066400000000000000000000121311223057412600204020ustar00rootroot00000000000000/* libmapi C++ Wrapper MAPI Exception Class Copyright (C) Alan Alvarez 2007. This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see . */ #ifndef LIBMAPIPP__MAPI_EXCEPTION_H__ #define LIBMAPIPP__MAPI_EXCEPTION_H__ #include #include #include #include #include #include #define STATUS_TABLE_INSERT(status) sm_status_map.insert(status_map::value_type(status, #status)); namespace libmapipp { class mapi_exception : public std::exception { public: explicit mapi_exception(enum MAPISTATUS status, const std::string& origin = "") : std::exception(), m_status(status), m_origin(origin), m_what_string(origin) { status_map::iterator iter = sm_status_map.find(m_status); m_what_string += ": "; m_what_string += (iter != sm_status_map.end()) ? iter->second : "Unknown MAPISTATUS value"; } virtual const char* what() const throw() { return m_what_string.c_str(); } enum MAPISTATUS get_status() const { return m_status; } virtual ~mapi_exception() throw() {} private: enum MAPISTATUS m_status; std::string m_origin; std::string m_what_string; friend class session; typedef std::map status_map; static status_map sm_status_map; static void fill_status_map() { static bool filled = false; if (!filled) { STATUS_TABLE_INSERT(MAPI_E_SUCCESS); STATUS_TABLE_INSERT(MAPI_E_CALL_FAILED); STATUS_TABLE_INSERT(MAPI_E_NO_SUPPORT); STATUS_TABLE_INSERT(MAPI_E_BAD_CHARWIDTH); STATUS_TABLE_INSERT(MAPI_E_STRING_TOO_LONG); STATUS_TABLE_INSERT(MAPI_E_UNKNOWN_FLAGS); STATUS_TABLE_INSERT(MAPI_E_INVALID_ENTRYID); STATUS_TABLE_INSERT(MAPI_E_INVALID_OBJECT); STATUS_TABLE_INSERT(MAPI_E_OBJECT_CHANGED); STATUS_TABLE_INSERT(MAPI_E_OBJECT_DELETED); STATUS_TABLE_INSERT(MAPI_E_BUSY); STATUS_TABLE_INSERT(MAPI_E_NOT_ENOUGH_DISK); STATUS_TABLE_INSERT(MAPI_E_NOT_ENOUGH_RESOURCES); STATUS_TABLE_INSERT(MAPI_E_NOT_FOUND); STATUS_TABLE_INSERT(MAPI_E_VERSION); STATUS_TABLE_INSERT(MAPI_E_LOGON_FAILED); STATUS_TABLE_INSERT(MAPI_E_SESSION_LIMIT); STATUS_TABLE_INSERT(MAPI_E_USER_CANCEL); STATUS_TABLE_INSERT(MAPI_E_UNABLE_TO_ABORT); STATUS_TABLE_INSERT(MAPI_E_NETWORK_ERROR); STATUS_TABLE_INSERT(MAPI_E_DISK_ERROR); STATUS_TABLE_INSERT(MAPI_E_TOO_COMPLEX); STATUS_TABLE_INSERT(MAPI_E_BAD_COLUMN); STATUS_TABLE_INSERT(MAPI_E_EXTENDED_ERROR); STATUS_TABLE_INSERT(MAPI_E_COMPUTED); STATUS_TABLE_INSERT(MAPI_E_CORRUPT_DATA); STATUS_TABLE_INSERT(MAPI_E_UNCONFIGURED); STATUS_TABLE_INSERT(MAPI_E_FAILONEPROVIDER); STATUS_TABLE_INSERT(MAPI_E_UNKNOWN_CPID); STATUS_TABLE_INSERT(MAPI_E_UNKNOWN_LCID); STATUS_TABLE_INSERT(MAPI_E_PASSWORD_CHANGE_REQUIRED); STATUS_TABLE_INSERT(MAPI_E_PASSWORD_EXPIRED); STATUS_TABLE_INSERT(MAPI_E_INVALID_WORKSTATION_ACCOUNT); STATUS_TABLE_INSERT(MAPI_E_INVALID_ACCESS_TIME); STATUS_TABLE_INSERT(MAPI_E_ACCOUNT_DISABLED); STATUS_TABLE_INSERT(MAPI_E_END_OF_SESSION); STATUS_TABLE_INSERT(MAPI_E_UNKNOWN_ENTRYID); STATUS_TABLE_INSERT(MAPI_E_MISSING_REQUIRED_COLUMN); STATUS_TABLE_INSERT(MAPI_E_BAD_VALUE); STATUS_TABLE_INSERT(MAPI_E_INVALID_TYPE); STATUS_TABLE_INSERT(MAPI_E_TYPE_NO_SUPPORT); STATUS_TABLE_INSERT(MAPI_E_UNEXPECTED_TYPE); STATUS_TABLE_INSERT(MAPI_E_TOO_BIG); STATUS_TABLE_INSERT(MAPI_E_DECLINE_COPY); STATUS_TABLE_INSERT(MAPI_E_UNEXPECTED_ID); STATUS_TABLE_INSERT(MAPI_E_UNABLE_TO_COMPLETE); STATUS_TABLE_INSERT(MAPI_E_TIMEOUT); STATUS_TABLE_INSERT(MAPI_E_TABLE_EMPTY); STATUS_TABLE_INSERT(MAPI_E_TABLE_TOO_BIG); STATUS_TABLE_INSERT(MAPI_E_INVALID_BOOKMARK); STATUS_TABLE_INSERT(MAPI_E_WAIT); STATUS_TABLE_INSERT(MAPI_E_CANCEL); STATUS_TABLE_INSERT(MAPI_E_NOT_ME); STATUS_TABLE_INSERT(MAPI_E_CORRUPT_STORE); STATUS_TABLE_INSERT(MAPI_E_NOT_IN_QUEUE); STATUS_TABLE_INSERT(MAPI_E_NO_SUPPRESS); STATUS_TABLE_INSERT(MAPI_E_COLLISION); STATUS_TABLE_INSERT(MAPI_E_NOT_INITIALIZED); STATUS_TABLE_INSERT(MAPI_E_NON_STANDARD); STATUS_TABLE_INSERT(MAPI_E_NO_RECIPIENTS); STATUS_TABLE_INSERT(MAPI_E_SUBMITTED); STATUS_TABLE_INSERT(MAPI_E_HAS_FOLDERS); STATUS_TABLE_INSERT(MAPI_E_HAS_MESAGES); STATUS_TABLE_INSERT(MAPI_E_FOLDER_CYCLE); STATUS_TABLE_INSERT(MAPI_E_AMBIGUOUS_RECIP); STATUS_TABLE_INSERT(MAPI_E_NO_ACCESS); STATUS_TABLE_INSERT(MAPI_E_INVALID_PARAMETER); STATUS_TABLE_INSERT(MAPI_E_RESERVED); filled = true; } } }; } // namespace libmapipp #endif //!LIBMAPIPP__EXCEPTION_H__ openchange-2.0/libmapi++/message.h000066400000000000000000000051621223057412600170300ustar00rootroot00000000000000/* libmapi C++ Wrapper Message Class Copyright (C) Alan Alvarez 2008. This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see . */ #ifndef LIBMAPIPP__MESSAGE_H__ #define LIBMAPIPP__MESSAGE_H__ #include //for debugging #include #include #include #include #include #include #include namespace libmapipp { class attachment; /** * \brief This class represents a %message in Exchange. * * It is important to note that a %message is not necessarily an email %message. * It could be a contact, journal or anything else that is not a folder. */ class message : public object { public: typedef boost::shared_ptr attachment_shared_ptr; typedef std::vector attachment_container_type; /** * \brief Constructor * * \param mapi_session The session to use to retrieve this %message. * \param folder_id The id of the folder this %message belongs to. * \param message_id The %message id. */ message(session& mapi_session, const mapi_id_t folder_id, const mapi_id_t message_id) throw(mapi_exception) : object(mapi_session, "message"), m_folder_id(folder_id), m_id(message_id) { if (OpenMessage(&mapi_session.get_message_store().data(), folder_id, message_id, &m_object, 0) != MAPI_E_SUCCESS) throw mapi_exception(GetLastError(), "message::message : OpenMessage"); } /** * \brief Fetches all attachments in this %message. * * \return A container of attachment shared pointers. */ attachment_container_type fetch_attachments(); /** * \brief Get this %message's ID. */ mapi_id_t get_id() const { return m_id; } /** * \brief Get this message's parent folder ID. */ mapi_id_t get_folder_id() const { return m_folder_id; } /** * Destructor */ virtual ~message() throw() { } private: mapi_id_t m_folder_id; mapi_id_t m_id; }; } // namespace libmapipp #endif //!LIBMAPIPP__MESSAGE_H__ openchange-2.0/libmapi++/message_store.h000066400000000000000000000056451223057412600202520ustar00rootroot00000000000000/* libmapi C++ Wrapper Message Store Class Copyright (C) Alan Alvarez 2008. This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see . */ #ifndef LIBMAPIPP__MESSAGE_STORE_H__ #define LIBMAPIPP__MESSAGE_STORE_H__ #include #include #include #include namespace libmapipp { class session; /** * \brief This class represents the Message Store in Exchange. * * The message_store is the grouping of message folders (which could be the * users private store including mail, calendar, todo list, journal, contacts * and so on) or could be the public store (e.g. shared public folders). * * It is not possible for you, the user, to create a message_store object. * Instead, you should retrieve the message_store associated with a session * using session::get_message_store() */ class message_store : public object { public: /** * \brief Retrieves the folder id for the specified default folder in the Message Store. * * \param id The type of folder to search for. * * The following types of folders are supported: * - olFolderTopInformationStore * - olFolderDeletedItems * - olFolderOutbox * - olFolderSentMail * - olFolderInbox * - olFolderCalendar * - olFolderContacts * - olFolderJournal * - olFolderNotes * - olFolderTasks * - olFolderDrafts * * If you are trying to enumerate all folders, you should open the * olFolderTopInformationStore, and then get the hierarchy container for * that top level folder. * * \return The resulting folder id. */ mapi_id_t get_default_folder(const uint32_t id) const throw(mapi_exception) { mapi_id_t folder; if (GetDefaultFolder(const_cast(&m_object), &folder, id) != MAPI_E_SUCCESS) throw mapi_exception(GetLastError(), "message_store::get_default_folder() : GetDefaultFolder"); return folder; } private: friend class session; message_store(session& mapi_session) throw() : object(mapi_session, "message_store") {} void open(mapi_session *mapi_session) throw(mapi_exception) { if (OpenMsgStore(mapi_session, &m_object) != MAPI_E_SUCCESS) throw mapi_exception(GetLastError(), "message_store::open() : OpenMsgStore"); } ~message_store() throw() { } }; } // namespace libmapipp #endif //!LIBMAPIPP__MESSAGE_STORE_H__ openchange-2.0/libmapi++/object.h000066400000000000000000000057511223057412600166560ustar00rootroot00000000000000/* libmapi C++ Wrapper Base Object Class Copyright (C) Alan Alvarez 2008. This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see . */ #ifndef LIBMAPIPP__OBJECT_H__ #define LIBMAPIPP__OBJECT_H__ #include //for debugging #include #include /** * The libmapi++ classes and other definitions are all enclosed in * the libmapipp namespace. */ namespace libmapipp { // #define INVALID_HANDLE_VALUE 0xffffffff class property_container; class session; /** * Base Object class * * Most classes such as folder, message and message_store derive from this class. * It is important that objects be passed around as references and that no unnecessary * copies are made as this will call the class destructor which will call * mapi_object_release() and release the handle associated with this object. */ class object { public: /** * \brief Object Constructor * * \param mapi_session Session this object is to be associated with. * \param object_type The name of the type of object (to be set in a subclass) */ explicit object(session& mapi_session, const std::string& object_type = "") throw() : m_session(mapi_session), m_object_type(object_type) { mapi_object_init(&m_object); } /** * \brief Obtain a reference to the mapi_object_t associated with this object * * \return A reference to the C struct mapi_object_t associated with this object */ virtual mapi_object_t& data() throw() { return m_object; } /** * \brief Obtain a property_container to be used with this object. * * \return A property_container to be used with this object. */ virtual property_container get_property_container(); /** * \brief Obtain the session associated with this object. * * \return The session associated with this object */ virtual session& get_session() { return m_session; } /** * \brief Destructor * * Calls mapi_object_release() which releases the handle associated with this object. */ virtual ~object() throw() { // TODO: Check for invalid handle in libmapi 0.7 // if (m_object.handle != INVALID_HANDLE_VALUE) mapi_object_release(&m_object); // std::cout << "destroying object " << m_object_type << std::endl; } protected: mapi_object_t m_object; session& m_session; private: std::string m_object_type; // for debugging purposes }; } // namespace libmapipp #endif //!LIBMAPIPP__OBJECT_H__ openchange-2.0/libmapi++/profile.h000066400000000000000000000071451223057412600170470ustar00rootroot00000000000000/* libmapi C++ Wrapper Profile Class Copyright (C) Alan Alvarez 2008. This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see . */ #ifndef LIBMAPIPP__PROFILE_H__ #define LIBMAPIPP__PROFILE_H__ #include #include #include #include namespace libmapipp { /** * This class represents a user %profile database * * \todo possibly rename profile class to profile_database? * \todo we should be able to create a profile using libmapi++ classes * \todo we should be able to delete a profile using libmapi++ classes * \todo maybe move some of the session.h documentation on profiles to profile.h? */ class profile_database { public: /** * \brief Constructor * * \param profiledb_path An absolute path specifying the location of the * %profile database. If not specified (or "" is specified) the default * location will be used (~/.openchange.profiles.ldb). */ explicit profile_database(const std::string& profiledb_path = "") throw(std::runtime_error, mapi_exception); /* Create an new profile database * * \param profiledb the absolute path to the profile database intended to be created * \param ldif_path the absolute path to the LDIF information to use for initial setup * */ static bool create_profile_store(const char* profiledb, const char* ldif_path = NULL); /** * Create an new profile database * * \param profiledb the absolute path to the profile database intended to be created * \param ldif_path the absolute path to the LDIF information to use for initial setup * */ static bool create_profile_store(const std::string& profiledb, const std::string& ldif_path = ""); /** * Make the specified profile the default profile * * \param profname the name of the profile to make default */ bool set_default(const char* profname) { return (SetDefaultProfile(m_mapi_context, profname) == MAPI_E_SUCCESS); } /** * Make the specified profile the default profile * * \param profname the name of the profile to make default */ bool set_default(const std::string& profname) { return set_default(profname.c_str()); } /** * Get the default profile name * * \return the name of the default profile */ std::string get_default_profile_name() throw (mapi_exception); /** * \brief The path to the default %profile database * * This method is not normally required to be called by user applications * but might be useful under some circumstances. */ static std::string get_default_profile_path(); ~profile_database(); private: struct mapi_context *m_mapi_context; TALLOC_CTX *m_memory_ctx; }; class profile { public: ~profile() { if (m_profile) { ::ShutDown(m_profile); } if (m_mapi_context) { MAPIUninitialize(m_mapi_context); } talloc_free(m_memory_ctx); } private: mapi_profile *m_profile; struct mapi_context *m_mapi_context; TALLOC_CTX *m_memory_ctx; }; } // namespace libmapipp #endif //!LIBMAPIPP__PROFILE_H__ openchange-2.0/libmapi++/property_container.h000066400000000000000000000200351223057412600213260ustar00rootroot00000000000000/* libmapi C++ Wrapper Property Tag Container Class Copyright (C) Alan Alvarez 2008. This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see . */ #ifndef LIBMAPIPP__PROPERTY_CONTAINER_H__ #define LIBMAPIPP__PROPERTY_CONTAINER_H__ #include #include // for debugging only. #include #include // This is not declared in any of libmapi's headers, but it is defined in libmapi/property.c extern "C" { extern const void *get_mapi_SPropValue_data(struct mapi_SPropValue *lpProp); } namespace libmapipp { /// Iterator to use with Property Container class property_container_iterator { public: /// Default Constructor. Creates an invalid iterator. property_container_iterator() : m_property_values(NULL), m_mapi_property_values(NULL) {} property_container_iterator(SPropValue* property_values) : m_property_values(property_values), m_mapi_property_values(NULL) {} property_container_iterator(mapi_SPropValue* mapi_property_values) : m_property_values(NULL), m_mapi_property_values(mapi_property_values) {} /** \brief Get Property Tag Type. * \return Type of property this iterator points to or MAPI_PROP_RESERVED if this is an invalid iterator. * Valid Types are: * - PT_BOOLEAN * - PT_I2 * - PT_LONG * - PT_DOUBLE * - PT_I8 * - PT_SYSTIME * - PT_ERROR * - PT_STRING8 * - PT_UNICODE * - PT_BINARY * - PT_CLSID * - PT_ERROR * - PT_MV_SHORT * - PT_MV_LONG * - PT_MV_STRING8 * - PT_MV_BINARY * - PT_MV_CLSID * - PT_MV_UNICODE * - PT_MV_SYSTIME * - PT_NULL * - PT_OBJECT */ int get_type() { if (m_property_values) { return m_property_values->ulPropTag & 0xffff; } else if (m_mapi_property_values) { return m_mapi_property_values->ulPropTag & 0xffff; } else { return MAPI_PROP_RESERVED; } } /** * \brief Get Property Tag of the Property Value this operator points to. * * \return Property Tag of Property this iterator points to or MAPI_PROP_RESERVED if this is an invalid iterator. */ int get_tag() { if (m_property_values) { return m_property_values->ulPropTag; } else if (m_mapi_property_values) { return m_mapi_property_values->ulPropTag; } else { return MAPI_PROP_RESERVED; } } /// operator++ property_container_iterator& operator++() // prefix { if (m_property_values) ++m_property_values; else if (m_mapi_property_values) ++m_mapi_property_values; return *this; } /// operator++ postfix property_container_iterator operator++(int postfix) // postfix { property_container_iterator retval = *this; if (m_property_values) ++m_property_values; else if (m_mapi_property_values) ++m_mapi_property_values; return retval; } /// operator== bool operator==(const property_container_iterator& rhs) const { return ( (m_property_values == rhs.m_property_values) && (m_mapi_property_values == rhs.m_mapi_property_values) ); } /// operator!= bool operator!=(const property_container_iterator& rhs) const { return !(*this == rhs); } /** * \brief operator* * * \return The property value as a void pointer. */ const void* operator*() { if (m_property_values) return get_SPropValue_data(m_property_values); else return get_mapi_SPropValue_data(m_mapi_property_values); } private: SPropValue* m_property_values; mapi_SPropValue* m_mapi_property_values; }; /// A container of properties to be used with classes derived from object. class property_container { public: typedef property_container_iterator iterator; typedef const void* value_type; /// Constructor property_container(TALLOC_CTX* memory_ctx, mapi_object_t& mapi_object) : m_memory_ctx(memory_ctx), m_mapi_object(mapi_object), m_fetched(false), m_property_tag_array(NULL), m_cn_vals(0), m_property_values(0) { m_property_value_array.cValues = 0; m_property_value_array.lpProps = NULL; } /** * \brief Fetches properties with the tags supplied using operator<< * * \return The number of objects that were fetched. */ uint32_t fetch() { if (GetProps(&m_mapi_object, MAPI_UNICODE, m_property_tag_array, &m_property_values, &m_cn_vals) != MAPI_E_SUCCESS) throw mapi_exception(GetLastError(), "property_container::fetch : GetProps"); MAPIFreeBuffer(m_property_tag_array); m_property_tag_array = NULL; m_fetched = true; return m_cn_vals; } /// \brief Fetches \b ALL properties of the object associated with this container. void fetch_all() { if (GetPropsAll(&m_mapi_object, MAPI_UNICODE, &m_property_value_array) != MAPI_E_SUCCESS) throw mapi_exception(GetLastError(), "property_container::fetch_all : GetPropsAll"); // Free property_tag_array in case user used operator<< by mistake. if (m_property_tag_array) { MAPIFreeBuffer(m_property_tag_array); m_property_tag_array = NULL; } m_fetched = true; } /// \brief Adds a Property Tag to be fetched by fetch(). property_container& operator<<(uint32_t property_tag) { if (!m_property_tag_array) { m_property_tag_array = set_SPropTagArray(m_memory_ctx, 1, property_tag); } else { if (SPropTagArray_add(m_memory_ctx, m_property_tag_array, (enum MAPITAGS)property_tag) != MAPI_E_SUCCESS) throw mapi_exception(GetLastError(), "property_container::operator<< : SPropTagArray_add"); } return *this; } /** * \brief Finds the property value associated with a property tag * * \param property_tag The Property Tag to be searched for * * \return Property Value as a const void pointer */ const void* operator[](uint32_t property_tag) { if (!m_fetched) return NULL; if (m_property_values) return find_SPropValue_value(property_tag); else return find_mapi_SPropValue_data(&m_property_value_array, property_tag); } enum MAPITAGS get_tag_at(uint32_t pos) { if (m_property_values) return m_property_values[pos].ulPropTag; else return m_property_value_array.lpProps[pos].ulPropTag; } iterator begin() const { if (!m_fetched) return iterator(); if (m_property_values) return iterator(m_property_values); else return iterator(m_property_value_array.lpProps); } iterator end() const { if (!m_fetched) return iterator(); if (m_property_values) return iterator(m_property_values + m_cn_vals); else return iterator(m_property_value_array.lpProps + m_property_value_array.cValues); } /// \brief Get number of properties in container. size_t size() const { if (!m_fetched) return 0; if (m_property_values) return m_cn_vals; else return m_property_value_array.cValues; } /// Destructor ~property_container() { if (m_property_tag_array) MAPIFreeBuffer(m_property_tag_array); } private: TALLOC_CTX* m_memory_ctx; mapi_object_t& m_mapi_object; bool m_fetched; SPropTagArray* m_property_tag_array; // Used when calling GetProps (fetch) uint32_t m_cn_vals; SPropValue* m_property_values; // Used when calling GetPropsAll (fetch_all) mapi_SPropValue_array m_property_value_array; const void* find_SPropValue_value(uint32_t property_tag) { for (uint32_t i = 0; i < m_cn_vals; ++i) { if ((uint32_t)m_property_values[i].ulPropTag == property_tag) return get_SPropValue_data(&m_property_values[i]); } return NULL; } }; } // namespace libmapipp #endif //!LIBMAPIPP__PROPERTY_CONTAINER_H__ openchange-2.0/libmapi++/session.h000066400000000000000000000110671223057412600170700ustar00rootroot00000000000000/* libmapi C++ Wrapper Session Class Copyright (C) Alan Alvarez 2008. This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see . */ #ifndef LIBMAPIPP__SESSION_H__ #define LIBMAPIPP__SESSION_H__ #include #include #include #include #include // for debugging #include #include #include using std::cout; using std::endl; namespace libmapipp { /** * This class represents a MAPI %session with the Exchange Server * * The %session is best thought of as the connection by a single user to a * single server. It is possible to have multiple sessions open at the same * time. * * A key concept in the %session is that of a \em profile, and the %profile * database. The %profile is a pre-established data set that specifies the * server information (e.g. server name / IP address, and Exchange domain) * and client information (e.g. the user name, preferred language, and * optionally the users password). The profiles are stored in a local store * (Samba LDB database) known as the %profile store or %profile database. One * of the profiles in the %profile database can be designated as the default * %profile (which is particularly useful given that most users may only have * one). See the profile class documentation for more information. * * The general concept is that you create a %session %object, log in to the * %session using a selected %profile name, and then work with the message_store * associated with that %session. The message_store is only valid so long * as the session is valid. */ class session { public: /** * \brief Constructor * * \param profiledb An absolute path specifying the location of the * %profile database. If not specified (or "" is specified) the default * location will be used (~/.openchange.profiles.ldb). * * \param debug Whether to output debug information to stdout */ explicit session(const std::string& profiledb = "", const bool debug = false) throw(std::runtime_error, mapi_exception); /** * \brief Log-in to the Exchange Server * * \param profile_name The name of the profile to use to login with. * If not specified (or "" is specified), then the default %profile will * be used. * * \param password The password to use to login with. It is possible to * omit this if the password is stored in the %profile database. */ void login(const std::string& profile_name = "", const std::string& password = "") throw(mapi_exception); /** * \brief The name of the profile that is in use * * Calling this method only makes sense if login() has been called with * this %session object. */ std::string get_profile_name() const { return m_profile_name; } /** * \brief Obtain a reference to the message_store associated with this %session * * \return The message_store associated with this %session. */ message_store& get_message_store() throw() { return *m_message_store; } /** * \brief Obtain a talloc memory context for this %session * * This pointer can be used for subsequent memory allocations, and * these will be cleaned up when the %session is terminated. */ TALLOC_CTX* get_memory_ctx() throw() { return m_memory_ctx; } /** * \brief Uninitialize and clean up the MAPI %session. */ ~session() { uninitialize(); } /** * \brief The underlying mapi_session * * Exposing this is temporary. Maybe be removed when we sort it out */ mapi_session* get_mapi_session() throw() { return m_session; } private: mapi_session *m_session; struct mapi_context *m_mapi_context; TALLOC_CTX *m_memory_ctx; message_store *m_message_store; std::string m_profile_name; void uninitialize() throw() { if (m_message_store) { delete m_message_store; } if (m_mapi_context) { MAPIUninitialize(m_mapi_context); } talloc_free(m_memory_ctx); } }; } // namespace libmapipp #endif //!LIBMAPIPP__SESSION_H__ openchange-2.0/libmapi++/src/000077500000000000000000000000001223057412600160165ustar00rootroot00000000000000openchange-2.0/libmapi++/src/attachment.cpp000066400000000000000000000060431223057412600206550ustar00rootroot00000000000000/* libmapi C++ Wrapper Attachment Class implementation. Copyright (C) Alan Alvarez 2008. This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see . */ #include #include namespace libmapipp { attachment::attachment(message& mapi_message, const uint32_t attach_num) throw(mapi_exception) : object(mapi_message.get_session(), "attachment"), m_attach_num(attach_num), m_bin_data(NULL), m_data_size(0), m_filename("") { if (OpenAttach(&mapi_message.data(), attach_num, &m_object) != MAPI_E_SUCCESS) throw mapi_exception(GetLastError(), "attachment::attachment : OpenAttach"); property_container properties = get_property_container(); properties << PR_ATTACH_FILENAME << PR_ATTACH_LONG_FILENAME << PR_ATTACH_SIZE << PR_ATTACH_DATA_BIN << PR_ATTACH_METHOD; properties.fetch(); const char* filename = static_cast(properties[PR_ATTACH_LONG_FILENAME]); if (!filename) { filename = static_cast(properties[PR_ATTACH_FILENAME]); } if (filename) m_filename = filename; m_data_size = *(static_cast(properties[PR_ATTACH_SIZE])); const Binary_r* attachment_data = static_cast(properties[PR_ATTACH_DATA_BIN]); // Don't load PR_ATTACH_DATA_BIN if it's embedded in message. // NOTE: Use RopOpenEmbeddedMessage when it is implemented. const uint32_t attach_method = *static_cast(properties[PR_ATTACH_METHOD]); if (attach_method != ATTACH_BY_VALUE) return; // Get Binary Data. if (attachment_data) { m_data_size = attachment_data->cb; m_bin_data = new uint8_t[m_data_size]; memcpy(m_bin_data, attachment_data->lpb, attachment_data->cb); } else { mapi_object_t obj_stream; mapi_object_init(&obj_stream); if (OpenStream(&m_object, (enum MAPITAGS)PidTagAttachDataBinary, OpenStream_ReadOnly, &obj_stream) != MAPI_E_SUCCESS) throw mapi_exception(GetLastError(), "attachment::attachment : OpenStream"); if (GetStreamSize(&obj_stream, &m_data_size) != MAPI_E_SUCCESS) throw mapi_exception(GetLastError(), "attachment::attachment : GetStreamSize"); m_bin_data = new uint8_t[m_data_size]; uint32_t pos = 0; uint16_t bytes_read = 0; do { if (ReadStream(&obj_stream, m_bin_data+pos, 1024, &bytes_read) != MAPI_E_SUCCESS) throw mapi_exception(GetLastError(), "attachment::attachment : ReadStream"); pos += bytes_read; } while (bytes_read && pos < m_data_size); mapi_object_release(&obj_stream); } } } // namespace libmapipp openchange-2.0/libmapi++/src/folder.cpp000066400000000000000000000073271223057412600200060ustar00rootroot00000000000000/* libmapi C++ Wrapper Folder Class implementation. Copyright (C) Alan Alvarez 2008. This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see . */ #include namespace libmapipp { folder::message_container_type folder::fetch_messages() throw(mapi_exception) { uint32_t contents_table_row_count = 0; mapi_object_t contents_table; mapi_object_init(&contents_table); if (GetContentsTable(&m_object, &contents_table, 0, &contents_table_row_count) != MAPI_E_SUCCESS) { mapi_object_release(&contents_table); throw mapi_exception(GetLastError(), "folder::fetch_messages : GetContentsTable"); } SPropTagArray* property_tag_array = set_SPropTagArray(m_session.get_memory_ctx(), 0x2, PR_FID, PR_MID); if (SetColumns(&contents_table, property_tag_array) != MAPI_E_SUCCESS) { MAPIFreeBuffer(property_tag_array); mapi_object_release(&contents_table); throw mapi_exception(GetLastError(), "folder::fetch_messages : SetColumns"); } MAPIFreeBuffer(property_tag_array); uint32_t rows_to_read = contents_table_row_count; SRowSet row_set; message_container_type message_container; message_container.reserve(contents_table_row_count); while( (QueryRows(&contents_table, rows_to_read, TBL_ADVANCE, &row_set) == MAPI_E_SUCCESS) && row_set.cRows) { rows_to_read -= row_set.cRows; for (unsigned int i = 0; i < row_set.cRows; ++i) { try { message_container.push_back(message_shared_ptr(new message(m_session, m_id, row_set.aRow[i].lpProps[1].value.d))); } catch(mapi_exception e) { mapi_object_release(&contents_table); throw; } } } mapi_object_release(&contents_table); return message_container; } folder::hierarchy_container_type folder::fetch_hierarchy() throw(mapi_exception) { mapi_object_t hierarchy_table; uint32_t hierarchy_table_row_count = 0; mapi_object_init(&hierarchy_table); if (GetHierarchyTable(&m_object, &hierarchy_table, 0, &hierarchy_table_row_count) != MAPI_E_SUCCESS) { mapi_object_release(&hierarchy_table); throw mapi_exception(GetLastError(), "folder::fetch_hierarchy : GetHierarchyTable"); } SPropTagArray* property_tag_array = set_SPropTagArray(m_session.get_memory_ctx(), 0x1, PR_FID); if (SetColumns(&hierarchy_table, property_tag_array)) { MAPIFreeBuffer(property_tag_array); mapi_object_release(&hierarchy_table); throw mapi_exception(GetLastError(), "folder::fetch_hierarchy : SetColumns"); } MAPIFreeBuffer(property_tag_array); uint32_t rows_to_read = hierarchy_table_row_count; SRowSet row_set; hierarchy_container_type hierarchy_container; hierarchy_container.reserve(hierarchy_table_row_count); while( (QueryRows(&hierarchy_table, rows_to_read, TBL_ADVANCE, &row_set) == MAPI_E_SUCCESS) && row_set.cRows) { rows_to_read -= row_set.cRows; for (unsigned int i = 0; i < row_set.cRows; ++i) { try { hierarchy_container.push_back(folder_shared_ptr(new folder(*this, row_set.aRow[i].lpProps[0].value.d))); } catch(mapi_exception e) { mapi_object_release(&hierarchy_table); throw; } } } mapi_object_release(&hierarchy_table); return hierarchy_container; } } // namespace libmapipp openchange-2.0/libmapi++/src/mapi_exception.cpp000066400000000000000000000016201223057412600215250ustar00rootroot00000000000000/* libmapi C++ Wrapper mapi_exception Class implementation. Copyright (C) Alan Alvarez 2008. This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see . */ #include namespace libmapipp { mapi_exception::status_map mapi_exception::sm_status_map = status_map(); } // namespace libmapipp openchange-2.0/libmapi++/src/message.cpp000066400000000000000000000040561223057412600201530ustar00rootroot00000000000000/* libmapi C++ Wrapper Message class implementation Copyright (C) Alan Alvarez 2008. This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see . */ #include namespace libmapipp { message::attachment_container_type message::fetch_attachments() { mapi_object_t attachment_table; mapi_object_init(&attachment_table); if (GetAttachmentTable(&m_object, &attachment_table) != MAPI_E_SUCCESS) { mapi_object_release(&attachment_table); throw mapi_exception(GetLastError(), "message::fetch_attachments : GetAttachmentTable"); } SPropTagArray* property_tag_array = set_SPropTagArray(m_session.get_memory_ctx(), 0x1, PR_ATTACH_NUM); if (SetColumns(&attachment_table, property_tag_array) != MAPI_E_SUCCESS) { MAPIFreeBuffer(property_tag_array); mapi_object_release(&attachment_table); throw mapi_exception(GetLastError(), "message::fetch_attachments : SetColumns"); } MAPIFreeBuffer(property_tag_array); SRowSet row_set; attachment_container_type attachment_container; while( (QueryRows(&attachment_table, 0x32, TBL_ADVANCE, &row_set) == MAPI_E_SUCCESS) && row_set.cRows) { for (unsigned int i = 0; i < row_set.cRows; ++i) { try { attachment_container.push_back(attachment_shared_ptr(new attachment(*this, row_set.aRow[i].lpProps[0].value.l))); } catch(mapi_exception e) { mapi_object_release(&attachment_table); throw; } } } mapi_object_release(&attachment_table); return attachment_container; } } // namespace libmapipp openchange-2.0/libmapi++/src/object.cpp000066400000000000000000000017751223057412600200020ustar00rootroot00000000000000/* libmapi C++ Wrapper Object Class implementation. Copyright (C) Alan Alvarez 2008. This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see . */ #include #include #include namespace libmapipp { property_container object::get_property_container() { return property_container(m_session.get_memory_ctx(), m_object); } } // namespace libmapipp openchange-2.0/libmapi++/src/profile.cpp000066400000000000000000000055451223057412600201730ustar00rootroot00000000000000/* libmapi C++ Wrapper Profile and Profile database Classes Copyright (C) Alan Alvarez 2008. Copyright (C) Brad Hards 2010 This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see . */ #include namespace libmapipp { profile_database::profile_database(const std::string& profiledb_path) throw(std::runtime_error, mapi_exception) : m_mapi_context(0), m_memory_ctx(talloc_named(NULL, 0, "libmapipp-profile")) { std::string profile_path; // If profile is not provided, attempt to get it from default location // (~/.openchange/profiles.ldb) if (profiledb_path == "") { profile_path = get_default_profile_path(); if (profile_path == "") { talloc_free(m_memory_ctx); throw std::runtime_error("libmapipp::session(): Failed to get $HOME env variable"); } } else { profile_path = profiledb_path; } enum MAPISTATUS retval = MAPIInitialize(&m_mapi_context, profile_path.c_str()); if (retval != MAPI_E_SUCCESS) { talloc_free(m_memory_ctx); throw mapi_exception(retval, "session::session : MAPIInitialize"); } } profile_database::~profile_database() { if (m_mapi_context) { MAPIUninitialize(m_mapi_context); } talloc_free(m_memory_ctx); } std::string profile_database::get_default_profile_name() throw (mapi_exception) { char* profname = NULL; enum MAPISTATUS retval = GetDefaultProfile(m_mapi_context, &profname); if (retval != MAPI_E_SUCCESS) throw mapi_exception(retval, "profile::get_default_profile : GetDefaultProfile()"); return std::string(profname); } bool profile_database::create_profile_store(const char* profiledb, const char* ldif_path) { if (ldif_path == NULL) ldif_path = ::mapi_profile_get_ldif_path(); return (CreateProfileStore(profiledb, ldif_path) == MAPI_E_SUCCESS); } bool profile_database::create_profile_store(const std::string& profiledb, const std::string& ldif_path) { if (ldif_path == "") { return (create_profile_store(profiledb.c_str())); } else { return create_profile_store(profiledb.c_str(), ldif_path.c_str()); } } std::string profile_database::get_default_profile_path() { const char* profile_path = getenv("HOME"); std::string retval = ""; if (profile_path) { retval = profile_path; retval += "/.openchange/profiles.ldb"; } return retval; } } // namespace libmapippopenchange-2.0/libmapi++/src/session.cpp000066400000000000000000000047761223057412600202230ustar00rootroot00000000000000/* libmapi C++ Wrapper Session Class implementation. Copyright (C) Alan Alvarez 2008. This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see . */ #include #include #include namespace libmapipp { session::session(const std::string& profiledb, bool debug) throw(std::runtime_error, mapi_exception) : m_session(NULL), m_mapi_context(0), m_memory_ctx(talloc_named(NULL, 0, "libmapipp-session")), m_message_store(new message_store(*this)) { mapi_exception::fill_status_map(); std::string profile_path; // If profile is not provided, attempt to get it from default location // (~/.openchange/profiles.ldb) if (profiledb == "") { profile_path = profile_database::get_default_profile_path(); if (profile_path == "") { talloc_free(m_memory_ctx); delete m_message_store; throw std::runtime_error("libmapipp::session(): Failed to get $HOME env variable"); } } else { profile_path = profiledb; } if (MAPIInitialize(&m_mapi_context, profile_path.c_str()) != MAPI_E_SUCCESS) { talloc_free(m_memory_ctx); delete m_message_store; throw mapi_exception(GetLastError(), "session::session : MAPIInitialize"); } if (debug) { m_mapi_context->dumpdata = true; } } void session::login(const std::string& profile_name, const std::string& password) throw (mapi_exception) { m_profile_name = profile_name; if (m_profile_name == "") { // if profile is not set, try to get default profile try { m_profile_name = profile_database().get_default_profile_name(); } catch(mapi_exception e) { uninitialize(); throw; } } if (MapiLogonEx(m_mapi_context, &m_session, m_profile_name.c_str(), (password != "") ? password.c_str() : 0 ) != MAPI_E_SUCCESS) { uninitialize(); throw mapi_exception(GetLastError(), "session::session : MapiLogonEx"); } try { m_message_store->open(m_session); } catch (mapi_exception e) { throw; } } } // namespace libmapipp openchange-2.0/libmapi++/tests/000077500000000000000000000000001223057412600163715ustar00rootroot00000000000000openchange-2.0/libmapi++/tests/attach_test.cpp000066400000000000000000000061751223057412600214110ustar00rootroot00000000000000/* libmapi C++ Wrapper Sample attachment test application Copyright (C) Alan Alvarez 2008. This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see . */ #include #include using namespace std; using namespace libmapipp; static uint32_t get_attachment_count(message& mapi_message) { message::attachment_container_type attachment_container = mapi_message.fetch_attachments(); return attachment_container.size(); } static void print_messages_with_attachments(folder& up_folder) { folder::message_container_type messages = up_folder.fetch_messages(); for (folder::message_container_type::iterator Iter = messages.begin(); Iter != messages.end(); ++Iter) { uint32_t attachment_count = get_attachment_count(*(*Iter)); // cout << "Attachment Count: " << attachment_count << endl; if (attachment_count) { cout << "Message (" << (*Iter)->get_id() << ") has " << attachment_count << " attachments." << endl; } } } static void print_folder_tree(folder& up_folder, session& mapi_session, unsigned int deep = 0) { property_container up_folder_property_container = up_folder.get_property_container(); up_folder_property_container << PR_DISPLAY_NAME << PR_CONTENT_COUNT; up_folder_property_container.fetch(); string display_name = static_cast(up_folder_property_container[PR_DISPLAY_NAME]); const uint32_t message_count = *(static_cast(up_folder_property_container[PR_CONTENT_COUNT])); for (unsigned int i = 0; i < deep; ++i) { cout << "|----> "; } cout << display_name << " (id: " << up_folder.get_id() << ") (messages: " << message_count << ")" << endl; print_messages_with_attachments(up_folder); // Fetch Top Information Folder Hierarchy (child folders) folder::hierarchy_container_type hierarchy = up_folder.fetch_hierarchy(); for (unsigned int i = 0; i < hierarchy.size(); ++i) { print_folder_tree(*hierarchy[i], mapi_session, deep+1); } } int main() { try { session mapi_session; mapi_session.login(); // Get Default Top Information Store folder ID mapi_id_t top_folder_id = mapi_session.get_message_store().get_default_folder(olFolderTopInformationStore); // Open Top Information Folder folder top_folder(mapi_session.get_message_store(), top_folder_id); print_folder_tree(top_folder, mapi_session); } catch (mapi_exception e) // Catch any mapi exceptions { cout << "MAPI Exception @ main: " << e.what() << endl; } catch (std::runtime_error e) // Catch runtime exceptions { cout << "std::runtime_error exception @ main: " << e.what() << endl; } return 0; } openchange-2.0/libmapi++/tests/exception_test.cpp000066400000000000000000000004761223057412600221410ustar00rootroot00000000000000#include #include static void dotest() throw(libmapipp::mapi_exception) { throw libmapipp::mapi_exception(MAPI_E_SUCCESS, "mapi_exception test"); } int main() { try { dotest(); } catch (libmapipp::mapi_exception e) { std::cout << e.what() << std::endl; } return 0; } openchange-2.0/libmapi++/tests/profile_test.cpp000066400000000000000000000051401223057412600215740ustar00rootroot00000000000000/* libmapi C++ Wrapper Test application for profile database and profile classes Copyright (C) Brad Hards 2010. This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see . */ #include #include #include #include #define PROFILEDB_NAME_TEMPLATE "/tmp/mapidbXXXXXX" int main () { try { libmapipp::profile_database db; std::cout << "default profile name: " << db.get_default_profile_name() << std::endl; { char *tmpname = (char*) calloc(sizeof(PROFILEDB_NAME_TEMPLATE) + 1, sizeof(char)); strncpy(tmpname, PROFILEDB_NAME_TEMPLATE, sizeof(PROFILEDB_NAME_TEMPLATE)); int ret = mkstemp(tmpname); if (ret < 0) { std::cout << "failed to create temporary file: " << strerror(errno) << std::endl; } if (libmapipp::profile_database::create_profile_store(tmpname)) { std::cout << "success creating a temporary profile store" << std::endl; } else { std::cout << "failed to create a temporary profile store" << std::endl; } unlink(tmpname); } { char *tmpname2 = (char*) calloc(sizeof(PROFILEDB_NAME_TEMPLATE) + 1, sizeof(char)); strncpy(tmpname2, PROFILEDB_NAME_TEMPLATE, sizeof(PROFILEDB_NAME_TEMPLATE)); int ret = mkstemp(tmpname2); if (ret < 0) { std::cout << "failed to create temporary file: " << strerror(errno) << std::endl; } if (libmapipp::profile_database::create_profile_store(std::string(tmpname2))) { std::cout << "success creating a temporary profile store with std::string" << std::endl; } else { std::cout << "failed to create a temporary profile store with std::string" << std::endl; } unlink(tmpname2); } std::cout << "finished profile and profile database tests" << std::endl; } catch (libmapipp::mapi_exception e) // Catch any mapi exceptions { std::cout << "MAPI Exception @ main: " << e.what() << std::endl; } catch (std::runtime_error e) // Catch runtime exceptions { std::cout << "std::runtime_error exception @ main: " << e.what() << std::endl; } return 0; } openchange-2.0/libmapi++/tests/test.cpp000066400000000000000000000115051223057412600200560ustar00rootroot00000000000000/* libmapi C++ Wrapper Sample test application Copyright (C) Alan Alvarez 2008. This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see . */ #include #include #include #include using namespace libmapipp; using std::string; // The best way to get a folder message count is to get property PR_FOLDER_CHILD_COUNT. // This is only used to test opening all messages. static unsigned int get_message_count(folder& the_folder, session& mapi_session) { folder::message_container_type messages = the_folder.fetch_messages(); return messages.size(); } static void print_folder_tree(folder& up_folder, session& mapi_session, unsigned int deep = 0) { property_container up_folder_property_container = up_folder.get_property_container(); up_folder_property_container << PR_DISPLAY_NAME << PR_CONTAINER_CLASS; up_folder_property_container.fetch(); string display_name = static_cast(up_folder_property_container[PR_DISPLAY_NAME]); string container_class; if (up_folder_property_container[PR_CONTAINER_CLASS]) container_class = static_cast(up_folder_property_container[PR_CONTAINER_CLASS]); for (unsigned int i = 0; i < deep; ++i) { cout << "|----> "; } cout << display_name << " (id: " << up_folder.get_id() << ") (messages: " << get_message_count(up_folder, mapi_session) << ")" << " container class: " << container_class << endl; // Fetch Top Information Folder Hierarchy (child folders) folder::hierarchy_container_type hierarchy = up_folder.fetch_hierarchy(); for (unsigned int i = 0; i < hierarchy.size(); ++i) { print_folder_tree(*hierarchy[i], mapi_session, deep+1); } } int main () { try { // Initialize MAPI Session session mapi_session; mapi_session.login(); property_container store_properties = mapi_session.get_message_store().get_property_container(); store_properties << PR_DISPLAY_NAME; store_properties.fetch(); cout << "Mailbox Name: " << static_cast(*store_properties.begin()) << endl; // Get Default Inbox folder ID. mapi_id_t inbox_id = mapi_session.get_message_store().get_default_folder(olFolderInbox); cout << "inbox_id: " << inbox_id << endl; // Open Inbox Folder folder inbox_folder(mapi_session.get_message_store(), inbox_id); // Fetch messages in Inbox Folder folder::message_container_type messages = inbox_folder.fetch_messages(); cout << "Inbox size: " << messages.size() << endl; // Get and Print some information about the first message in the Inbox Folder if (messages.size() > 0) { // Get a property container associated to the first message property_container message_property_container = messages[0]->get_property_container(); // Add Property Tags to be fetched and then fetch the properties. message_property_container << PR_DISPLAY_TO << PR_CONVERSATION_TOPIC; message_property_container.fetch_all(); string to; string subject; // Get some property values using property_container::operator[] // to = static_cast(message_property_container[PR_DISPLAY_TO]); // subject = static_cast(message_property_container[PR_CONVERSATION_TOPIC]); // Print property values // cout << "To: " << to << endl; // cout << "Subject: " << subject << endl; for (property_container::iterator Iter = message_property_container.begin(); Iter != message_property_container.end(); Iter++) { if (Iter.get_tag() == PR_DISPLAY_TO) to = (const char*) *Iter; else if (Iter.get_tag() == PR_CONVERSATION_TOPIC) subject = (const char*) *Iter; } // Print property values cout << "To: " << to << endl; cout << "Subject: " << subject << endl; } // Get Default Top Information Store folder ID mapi_id_t top_folder_id = mapi_session.get_message_store().get_default_folder(olFolderTopInformationStore); // Open Top Information Folder folder top_folder(mapi_session.get_message_store(), top_folder_id); print_folder_tree(top_folder, mapi_session); cout << "finished session" << endl; } catch (mapi_exception e) // Catch any mapi exceptions { cout << "MAPI Exception @ main: " << e.what() << endl; } catch (std::runtime_error e) // Catch runtime exceptions { cout << "std::runtime_error exception @ main: " << e.what() << endl; } return 0; } openchange-2.0/libmapi.pc.in000066400000000000000000000005401223057412600160310ustar00rootroot00000000000000prefix=@prefix@ exec_prefix=@exec_prefix@ libdir=@libdir@ includedir=@includedir@ datarootdir=@prefix@/share datadir=@datadir@ Name: MAPI Description: MAPI Protocol Implementation Version: @PACKAGE_VERSION@ Libs: -L${libdir} -lmapi Libs.private: @LIBS@ Cflags: -I${includedir} Requires: talloc dcerpc ndr tevent Requires.private: samba-hostconfig ldb openchange-2.0/libmapi/000077500000000000000000000000001223057412600151015ustar00rootroot00000000000000openchange-2.0/libmapi/Doxyfile.in000066400000000000000000001473271223057412600172320ustar00rootroot00000000000000# Doxyfile 1.5.2 # This file describes the settings to be used by the documentation system # doxygen (www.doxygen.org) for a project # # All text after a hash (#) is considered a comment and will be ignored # The format is: # TAG = value [value, ...] # For lists items can also be appended using: # TAG += value [value, ...] # Values that contain spaces should be placed between quotes (" ") #--------------------------------------------------------------------------- # Project related configuration options #--------------------------------------------------------------------------- # This tag specifies the encoding used for all characters in the config file that # follow. The default is UTF-8 which is also the encoding used for all text before # the first occurrence of this tag. Doxygen uses libiconv (or the iconv built into # libc) for the transcoding. See http://www.gnu.org/software/libiconv for the list of # possible encodings. DOXYFILE_ENCODING = UTF-8 # The PROJECT_NAME tag is a single word (or a sequence of words surrounded # by quotes) that should identify the project. PROJECT_NAME = MAPI Client Libraries # The PROJECT_NUMBER tag can be used to enter a project or revision number. # This could be handy for archiving the generated documentation or # if some version control system is used. PROJECT_NUMBER = @PACKAGE_VERSION@ # The OUTPUT_DIRECTORY tag is used to specify the (relative or absolute) # base path where the generated documentation will be put. # If a relative path is entered, it will be relative to the location # where doxygen was started. If left blank the current directory will be used. OUTPUT_DIRECTORY = apidocs # If the CREATE_SUBDIRS tag is set to YES, then doxygen will create # 4096 sub-directories (in 2 levels) under the output directory of each output # format and will distribute the generated files over these directories. # Enabling this option can be useful when feeding doxygen a huge amount of # source files, where putting all generated files in the same directory would # otherwise cause performance problems for the file system. CREATE_SUBDIRS = NO # The OUTPUT_LANGUAGE tag is used to specify the language in which all # documentation generated by doxygen is written. Doxygen will use this # information to generate all constant output in the proper language. # The default language is English, other supported languages are: # Afrikaans, Arabic, Brazilian, Catalan, Chinese, Chinese-Traditional, # Croatian, Czech, Danish, Dutch, Finnish, French, German, Greek, Hungarian, # Italian, Japanese, Japanese-en (Japanese with English messages), Korean, # Korean-en, Lithuanian, Norwegian, Polish, Portuguese, Romanian, Russian, # Serbian, Slovak, Slovene, Spanish, Swedish, and Ukrainian. OUTPUT_LANGUAGE = English # If the BRIEF_MEMBER_DESC tag is set to YES (the default) Doxygen will # include brief member descriptions after the members that are listed in # the file and class documentation (similar to JavaDoc). # Set to NO to disable this. BRIEF_MEMBER_DESC = YES # If the REPEAT_BRIEF tag is set to YES (the default) Doxygen will prepend # the brief description of a member or function before the detailed description. # Note: if both HIDE_UNDOC_MEMBERS and BRIEF_MEMBER_DESC are set to NO, the # brief descriptions will be completely suppressed. REPEAT_BRIEF = YES # This tag implements a quasi-intelligent brief description abbreviator # that is used to form the text in various listings. Each string # in this list, if found as the leading text of the brief description, will be # stripped from the text and the result after processing the whole list, is # used as the annotated text. Otherwise, the brief description is used as-is. # If left blank, the following values are used ("$name" is automatically # replaced with the name of the entity): "The $name class" "The $name widget" # "The $name file" "is" "provides" "specifies" "contains" # "represents" "a" "an" "the" ABBREVIATE_BRIEF = # If the ALWAYS_DETAILED_SEC and REPEAT_BRIEF tags are both set to YES then # Doxygen will generate a detailed section even if there is only a brief # description. ALWAYS_DETAILED_SEC = NO # If the INLINE_INHERITED_MEMB tag is set to YES, doxygen will show all # inherited members of a class in the documentation of that class as if those # members were ordinary class members. Constructors, destructors and assignment # operators of the base classes will not be shown. INLINE_INHERITED_MEMB = NO # If the FULL_PATH_NAMES tag is set to YES then Doxygen will prepend the full # path before files name in the file list and in the header files. If set # to NO the shortest path that makes the file name unique will be used. FULL_PATH_NAMES = YES # If the FULL_PATH_NAMES tag is set to YES then the STRIP_FROM_PATH tag # can be used to strip a user-defined part of the path. Stripping is # only done if one of the specified strings matches the left-hand part of # the path. The tag can be used to show relative paths in the file list. # If left blank the directory from which doxygen is run is used as the # path to strip. STRIP_FROM_PATH = # The STRIP_FROM_INC_PATH tag can be used to strip a user-defined part of # the path mentioned in the documentation of a class, which tells # the reader which header file to include in order to use a class. # If left blank only the name of the header file containing the class # definition is used. Otherwise one should specify the include paths that # are normally passed to the compiler using the -I flag. STRIP_FROM_INC_PATH = # If the SHORT_NAMES tag is set to YES, doxygen will generate much shorter # (but less readable) file names. This can be useful is your file systems # doesn't support long names like on DOS, Mac, or CD-ROM. SHORT_NAMES = NO # If the JAVADOC_AUTOBRIEF tag is set to YES then Doxygen # will interpret the first line (until the first dot) of a JavaDoc-style # comment as the brief description. If set to NO, the JavaDoc # comments will behave just like the Qt-style comments (thus requiring an # explicit @brief command for a brief description. JAVADOC_AUTOBRIEF = YES # The MULTILINE_CPP_IS_BRIEF tag can be set to YES to make Doxygen # treat a multi-line C++ special comment block (i.e. a block of //! or /// # comments) as a brief description. This used to be the default behaviour. # The new default is to treat a multi-line C++ comment block as a detailed # description. Set this tag to YES if you prefer the old behaviour instead. MULTILINE_CPP_IS_BRIEF = NO # If the INHERIT_DOCS tag is set to YES (the default) then an undocumented # member inherits the documentation from any documented member that it # re-implements. INHERIT_DOCS = YES # If the SEPARATE_MEMBER_PAGES tag is set to YES, then doxygen will produce # a new page for each member. If set to NO, the documentation of a member will # be part of the file/class/namespace that contains it. SEPARATE_MEMBER_PAGES = NO # The TAB_SIZE tag can be used to set the number of spaces in a tab. # Doxygen uses this value to replace tabs by spaces in code fragments. TAB_SIZE = 8 # This tag can be used to specify a number of aliases that acts # as commands in the documentation. An alias has the form "name=value". # For example adding "sideeffect=\par Side Effects:\n" will allow you to # put the command \sideeffect (or @sideeffect) in the documentation, which # will result in a user-defined paragraph with heading "Side Effects:". # You can put \n's in the value part of an alias to insert newlines. ALIASES = # Set the OPTIMIZE_OUTPUT_FOR_C tag to YES if your project consists of C # sources only. Doxygen will then generate output that is more tailored for C. # For instance, some of the names that are used will be different. The list # of all members will be omitted, etc. OPTIMIZE_OUTPUT_FOR_C = YES # Set the OPTIMIZE_OUTPUT_JAVA tag to YES if your project consists of Java # sources only. Doxygen will then generate output that is more tailored for Java. # For instance, namespaces will be presented as packages, qualified scopes # will look different, etc. OPTIMIZE_OUTPUT_JAVA = NO # If you use STL classes (i.e. std::string, std::vector, etc.) but do not want to # include (a tag file for) the STL sources as input, then you should # set this tag to YES in order to let doxygen match functions declarations and # definitions whose arguments contain STL classes (e.g. func(std::string); v.s. # func(std::string) {}). This also make the inheritance and collaboration # diagrams that involve STL classes more complete and accurate. BUILTIN_STL_SUPPORT = NO # If you use Microsoft's C++/CLI language, you should set this option to YES to # enable parsing support. CPP_CLI_SUPPORT = NO # If member grouping is used in the documentation and the DISTRIBUTE_GROUP_DOC # tag is set to YES, then doxygen will reuse the documentation of the first # member in the group (if any) for the other members of the group. By default # all members of a group must be documented explicitly. DISTRIBUTE_GROUP_DOC = NO # Set the SUBGROUPING tag to YES (the default) to allow class member groups of # the same type (for instance a group of public functions) to be put as a # subgroup of that type (e.g. under the Public Functions section). Set it to # NO to prevent subgrouping. Alternatively, this can be done per class using # the \nosubgrouping command. SUBGROUPING = YES #--------------------------------------------------------------------------- # Build related configuration options #--------------------------------------------------------------------------- # If the EXTRACT_ALL tag is set to YES doxygen will assume all entities in # documentation are documented, even if no documentation was available. # Private class members and static file members will be hidden unless # the EXTRACT_PRIVATE and EXTRACT_STATIC tags are set to YES EXTRACT_ALL = NO # If the EXTRACT_PRIVATE tag is set to YES all private members of a class # will be included in the documentation. EXTRACT_PRIVATE = NO # If the EXTRACT_STATIC tag is set to YES all static members of a file # will be included in the documentation. EXTRACT_STATIC = NO # If the EXTRACT_LOCAL_CLASSES tag is set to YES classes (and structs) # defined locally in source files will be included in the documentation. # If set to NO only classes defined in header files are included. EXTRACT_LOCAL_CLASSES = NO # This flag is only useful for Objective-C code. When set to YES local # methods, which are defined in the implementation section but not in # the interface are included in the documentation. # If set to NO (the default) only methods in the interface are included. EXTRACT_LOCAL_METHODS = NO # If the HIDE_UNDOC_MEMBERS tag is set to YES, Doxygen will hide all # undocumented members of documented classes, files or namespaces. # If set to NO (the default) these members will be included in the # various overviews, but no documentation section is generated. # This option has no effect if EXTRACT_ALL is enabled. HIDE_UNDOC_MEMBERS = YES # If the HIDE_UNDOC_CLASSES tag is set to YES, Doxygen will hide all # undocumented classes that are normally visible in the class hierarchy. # If set to NO (the default) these classes will be included in the various # overviews. This option has no effect if EXTRACT_ALL is enabled. HIDE_UNDOC_CLASSES = YES # If the HIDE_FRIEND_COMPOUNDS tag is set to YES, Doxygen will hide all # friend (class|struct|union) declarations. # If set to NO (the default) these declarations will be included in the # documentation. HIDE_FRIEND_COMPOUNDS = YES # If the HIDE_IN_BODY_DOCS tag is set to YES, Doxygen will hide any # documentation blocks found inside the body of a function. # If set to NO (the default) these blocks will be appended to the # function's detailed documentation block. HIDE_IN_BODY_DOCS = NO # The INTERNAL_DOCS tag determines if documentation # that is typed after a \internal command is included. If the tag is set # to NO (the default) then the documentation will be excluded. # Set it to YES to include the internal documentation. INTERNAL_DOCS = NO # If the CASE_SENSE_NAMES tag is set to NO then Doxygen will only generate # file names in lower-case letters. If set to YES upper-case letters are also # allowed. This is useful if you have classes or files whose names only differ # in case and if your file system supports case sensitive file names. Windows # and Mac users are advised to set this option to NO. CASE_SENSE_NAMES = YES # If the HIDE_SCOPE_NAMES tag is set to NO (the default) then Doxygen # will show members with their full class and namespace scopes in the # documentation. If set to YES the scope will be hidden. HIDE_SCOPE_NAMES = NO # If the SHOW_INCLUDE_FILES tag is set to YES (the default) then Doxygen # will put a list of the files that are included by a file in the documentation # of that file. SHOW_INCLUDE_FILES = YES # If the INLINE_INFO tag is set to YES (the default) then a tag [inline] # is inserted in the documentation for inline members. INLINE_INFO = YES # If the SORT_MEMBER_DOCS tag is set to YES (the default) then doxygen # will sort the (detailed) documentation of file and class members # alphabetically by member name. If set to NO the members will appear in # declaration order. SORT_MEMBER_DOCS = YES # If the SORT_BRIEF_DOCS tag is set to YES then doxygen will sort the # brief documentation of file, namespace and class members alphabetically # by member name. If set to NO (the default) the members will appear in # declaration order. SORT_BRIEF_DOCS = YES # If the SORT_BY_SCOPE_NAME tag is set to YES, the class list will be # sorted by fully-qualified names, including namespaces. If set to # NO (the default), the class list will be sorted only by class name, # not including the namespace part. # Note: This option is not very useful if HIDE_SCOPE_NAMES is set to YES. # Note: This option applies only to the class list, not to the # alphabetical list. SORT_BY_SCOPE_NAME = NO # The GENERATE_TODOLIST tag can be used to enable (YES) or # disable (NO) the todo list. This list is created by putting \todo # commands in the documentation. GENERATE_TODOLIST = YES # The GENERATE_TESTLIST tag can be used to enable (YES) or # disable (NO) the test list. This list is created by putting \test # commands in the documentation. GENERATE_TESTLIST = YES # The GENERATE_BUGLIST tag can be used to enable (YES) or # disable (NO) the bug list. This list is created by putting \bug # commands in the documentation. GENERATE_BUGLIST = YES # The GENERATE_DEPRECATEDLIST tag can be used to enable (YES) or # disable (NO) the deprecated list. This list is created by putting # \deprecated commands in the documentation. GENERATE_DEPRECATEDLIST= YES # The ENABLED_SECTIONS tag can be used to enable conditional # documentation sections, marked by \if sectionname ... \endif. ENABLED_SECTIONS = # The MAX_INITIALIZER_LINES tag determines the maximum number of lines # the initial value of a variable or define consists of for it to appear in # the documentation. If the initializer consists of more lines than specified # here it will be hidden. Use a value of 0 to hide initializers completely. # The appearance of the initializer of individual variables and defines in the # documentation can be controlled using \showinitializer or \hideinitializer # command in the documentation regardless of this setting. MAX_INITIALIZER_LINES = 30 # Set the SHOW_USED_FILES tag to NO to disable the list of files generated # at the bottom of the documentation of classes and structs. If set to YES the # list will mention the files that were used to generate the documentation. SHOW_USED_FILES = YES # If the sources in your project are distributed over multiple directories # then setting the SHOW_DIRECTORIES tag to YES will show the directory hierarchy # in the documentation. The default is NO. SHOW_DIRECTORIES = NO # The FILE_VERSION_FILTER tag can be used to specify a program or script that # doxygen should invoke to get the current version for each file (typically from the # version control system). Doxygen will invoke the program by executing (via # popen()) the command , where is the value of # the FILE_VERSION_FILTER tag, and is the name of an input file # provided by doxygen. Whatever the program writes to standard output # is used as the file version. See the manual for examples. FILE_VERSION_FILTER = #--------------------------------------------------------------------------- # configuration options related to warning and progress messages #--------------------------------------------------------------------------- # The QUIET tag can be used to turn on/off the messages that are generated # by doxygen. Possible values are YES and NO. If left blank NO is used. QUIET = NO # The WARNINGS tag can be used to turn on/off the warning messages that are # generated by doxygen. Possible values are YES and NO. If left blank # NO is used. WARNINGS = YES # If WARN_IF_UNDOCUMENTED is set to YES, then doxygen will generate warnings # for undocumented members. If EXTRACT_ALL is set to YES then this flag will # automatically be disabled. WARN_IF_UNDOCUMENTED = YES # If WARN_IF_DOC_ERROR is set to YES, doxygen will generate warnings for # potential errors in the documentation, such as not documenting some # parameters in a documented function, or documenting parameters that # don't exist or using markup commands wrongly. WARN_IF_DOC_ERROR = YES # This WARN_NO_PARAMDOC option can be abled to get warnings for # functions that are documented, but have no documentation for their parameters # or return value. If set to NO (the default) doxygen will only warn about # wrong or incomplete parameter documentation, but not about the absence of # documentation. WARN_NO_PARAMDOC = NO # The WARN_FORMAT tag determines the format of the warning messages that # doxygen can produce. The string should contain the $file, $line, and $text # tags, which will be replaced by the file and line number from which the # warning originated and the warning text. Optionally the format may contain # $version, which will be replaced by the version of the file (if it could # be obtained via FILE_VERSION_FILTER) WARN_FORMAT = "$file:$line: $text" # The WARN_LOGFILE tag can be used to specify a file to which warning # and error messages should be written. If left blank the output is written # to stderr. WARN_LOGFILE = #--------------------------------------------------------------------------- # configuration options related to the input files #--------------------------------------------------------------------------- # The INPUT tag can be used to specify the files and/or directories that contain # documented source files. You may enter file names like "myfile.cpp" or # directories like "/usr/src/myproject". Separate the files or directories # with spaces. INPUT = libmapi doc/doxygen # This tag can be used to specify the character encoding of the source files that # doxygen parses. Internally doxygen uses the UTF-8 encoding, which is also the default # input encoding. Doxygen uses libiconv (or the iconv built into libc) for the transcoding. # See http://www.gnu.org/software/libiconv for the list of possible encodings. INPUT_ENCODING = UTF-8 # If the value of the INPUT tag contains directories, you can use the # FILE_PATTERNS tag to specify one or more wildcard pattern (like *.cpp # and *.h) to filter out the source-files in the directories. If left # blank the following patterns are tested: # *.c *.cc *.cxx *.cpp *.c++ *.java *.ii *.ixx *.ipp *.i++ *.inl *.h *.hh *.hxx # *.hpp *.h++ *.idl *.odl *.cs *.php *.php3 *.inc *.m *.mm *.py FILE_PATTERNS = *.h *.c *.doxy # The RECURSIVE tag can be used to turn specify whether or not subdirectories # should be searched for input files as well. Possible values are YES and NO. # If left blank NO is used. RECURSIVE = NO # The EXCLUDE tag can be used to specify files and/or directories that should # excluded from the INPUT source files. This way you can easily exclude a # subdirectory from a directory tree whose root is specified with the INPUT tag. EXCLUDE = *_private.h # The EXCLUDE_SYMLINKS tag can be used select whether or not files or # directories that are symbolic links (a Unix filesystem feature) are excluded # from the input. EXCLUDE_SYMLINKS = NO # If the value of the INPUT tag contains directories, you can use the # EXCLUDE_PATTERNS tag to specify one or more wildcard patterns to exclude # certain files from those directories. Note that the wildcards are matched # against the file with absolute path, so to exclude all test directories # for example use the pattern */test/* EXCLUDE_PATTERNS = *.yy.c *_private.h # The EXCLUDE_SYMBOLS tag can be used to specify one or more symbol names # (namespaces, classes, functions, etc.) that should be excluded from the output. # The symbol name can be a fully qualified name, a word, or if the wildcard * is used, # a substring. Examples: ANamespace, AClass, AClass::ANamespace, ANamespace::*Test EXCLUDE_SYMBOLS = # The EXAMPLE_PATH tag can be used to specify one or more files or # directories that contain example code fragments that are included (see # the \include command). EXAMPLE_PATH = doc/examples # If the value of the EXAMPLE_PATH tag contains directories, you can use the # EXAMPLE_PATTERNS tag to specify one or more wildcard pattern (like *.cpp # and *.h) to filter out the source-files in the directories. If left # blank all files are included. EXAMPLE_PATTERNS = # If the EXAMPLE_RECURSIVE tag is set to YES then subdirectories will be # searched for input files to be used with the \include or \dontinclude # commands irrespective of the value of the RECURSIVE tag. # Possible values are YES and NO. If left blank NO is used. EXAMPLE_RECURSIVE = NO # The IMAGE_PATH tag can be used to specify one or more files or # directories that contain image that are included in the documentation (see # the \image command). IMAGE_PATH = doc/doxygen/pictures/ # The INPUT_FILTER tag can be used to specify a program that doxygen should # invoke to filter for each input file. Doxygen will invoke the filter program # by executing (via popen()) the command , where # is the value of the INPUT_FILTER tag, and is the name of an # input file. Doxygen will then use the output that the filter program writes # to standard output. If FILTER_PATTERNS is specified, this tag will be # ignored. INPUT_FILTER = "sed \ -e '20,40s/.*\//' \ -e '20,40s/.*\//' \ -e '20,40s/.*\//' \ -e '20,40s/.*\//' \ -e '20,40s/.*\//' \ -e '20,40s/.*\//' \ -e '20,40s/.*\//' \ -e '20,40s/.*\//' \ -e '20,40s/.*\//' \ -e '20,40s/.*\//' \ -e '20,40s/.*\//' \ -e '20,40s/.*\//' \ -e '20,40s/.*\//' \ -e '20,40s/.*\//' \ -e '20,40s/.*\//' \ -e '20,40s/.*\//' \ -e '20,40s/.*\//' \ -e '20,40s/.*\//' \ -e '20,40s/.*\//' \ -e '20,40s/.*\//' \ -e '20,40s/_PUBLIC_//'" # The FILTER_PATTERNS tag can be used to specify filters on a per file pattern # basis. Doxygen will compare the file name with each pattern and apply the # filter if there is a match. The filters are a list of the form: # pattern=filter (like *.cpp=my_cpp_filter). See INPUT_FILTER for further # info on how filters are used. If FILTER_PATTERNS is empty, INPUT_FILTER # is applied to all files. FILTER_PATTERNS = # If the FILTER_SOURCE_FILES tag is set to YES, the input filter (if set using # INPUT_FILTER) will be used to filter the input files when producing source # files to browse (i.e. when SOURCE_BROWSER is set to YES). FILTER_SOURCE_FILES = NO #--------------------------------------------------------------------------- # configuration options related to source browsing #--------------------------------------------------------------------------- # If the SOURCE_BROWSER tag is set to YES then a list of source files will # be generated. Documented entities will be cross-referenced with these sources. # Note: To get rid of all source code in the generated output, make sure also # VERBATIM_HEADERS is set to NO. SOURCE_BROWSER = NO # Setting the INLINE_SOURCES tag to YES will include the body # of functions and classes directly in the documentation. INLINE_SOURCES = NO # Setting the STRIP_CODE_COMMENTS tag to YES (the default) will instruct # doxygen to hide any special comment blocks from generated source code # fragments. Normal C and C++ comments will always remain visible. STRIP_CODE_COMMENTS = YES # If the REFERENCED_BY_RELATION tag is set to YES (the default) # then for each documented function all documented # functions referencing it will be listed. REFERENCED_BY_RELATION = YES # If the REFERENCES_RELATION tag is set to YES (the default) # then for each documented function all documented entities # called/used by that function will be listed. REFERENCES_RELATION = YES # If the REFERENCES_LINK_SOURCE tag is set to YES (the default) # and SOURCE_BROWSER tag is set to YES, then the hyperlinks from # functions in REFERENCES_RELATION and REFERENCED_BY_RELATION lists will # link to the source code. Otherwise they will link to the documentstion. REFERENCES_LINK_SOURCE = YES # If the USE_HTAGS tag is set to YES then the references to source code # will point to the HTML generated by the htags(1) tool instead of doxygen # built-in source browser. The htags tool is part of GNU's global source # tagging system (see http://www.gnu.org/software/global/global.html). You # will need version 4.8.6 or higher. USE_HTAGS = NO # If the VERBATIM_HEADERS tag is set to YES (the default) then Doxygen # will generate a verbatim copy of the header file for each class for # which an include is specified. Set to NO to disable this. VERBATIM_HEADERS = NO #--------------------------------------------------------------------------- # configuration options related to the alphabetical class index #--------------------------------------------------------------------------- # If the ALPHABETICAL_INDEX tag is set to YES, an alphabetical index # of all compounds will be generated. Enable this if the project # contains a lot of classes, structs, unions or interfaces. ALPHABETICAL_INDEX = NO # If the alphabetical index is enabled (see ALPHABETICAL_INDEX) then # the COLS_IN_ALPHA_INDEX tag can be used to specify the number of columns # in which this list will be split (can be a number in the range [1..20]) COLS_IN_ALPHA_INDEX = 5 # In case all classes in a project start with a common prefix, all # classes will be put under the same header in the alphabetical index. # The IGNORE_PREFIX tag can be used to specify one or more prefixes that # should be ignored while generating the index headers. IGNORE_PREFIX = #--------------------------------------------------------------------------- # configuration options related to the HTML output #--------------------------------------------------------------------------- # If the GENERATE_HTML tag is set to YES (the default) Doxygen will # generate HTML output. GENERATE_HTML = YES # The HTML_OUTPUT tag is used to specify where the HTML docs will be put. # If a relative path is entered the value of OUTPUT_DIRECTORY will be # put in front of it. If left blank `html' will be used as the default path. HTML_OUTPUT = html/libmapi # The HTML_FILE_EXTENSION tag can be used to specify the file extension for # each generated HTML page (for example: .htm,.php,.asp). If it is left blank # doxygen will generate files with .html extension. HTML_FILE_EXTENSION = .html # The HTML_HEADER tag can be used to specify a personal HTML header for # each generated HTML page. If it is left blank doxygen will generate a # standard header. HTML_HEADER = doc/doxygen/header.html # The HTML_FOOTER tag can be used to specify a personal HTML footer for # each generated HTML page. If it is left blank doxygen will generate a # standard footer. HTML_FOOTER = doc/doxygen/footer.html # The HTML_STYLESHEET tag can be used to specify a user-defined cascading # style sheet that is used by each HTML page. It can be used to # fine-tune the look of the HTML output. If the tag is left blank doxygen # will generate a default style sheet. Note that doxygen will try to copy # the style sheet file to the HTML output directory, so don't put your own # stylesheet in the HTML output directory as well, or it will be erased! HTML_STYLESHEET = doc/doxygen/apidocs.css # If the HTML_ALIGN_MEMBERS tag is set to YES, the members of classes, # files or namespaces will be aligned in HTML using tables. If set to # NO a bullet list will be used. HTML_ALIGN_MEMBERS = YES # If the GENERATE_HTMLHELP tag is set to YES, additional index files # will be generated that can be used as input for tools like the # Microsoft HTML help workshop to generate a compressed HTML help file (.chm) # of the generated HTML documentation. GENERATE_HTMLHELP = NO # If the GENERATE_HTMLHELP tag is set to YES, the CHM_FILE tag can # be used to specify the file name of the resulting .chm file. You # can add a path in front of the file if the result should not be # written to the html output directory. CHM_FILE = # If the GENERATE_HTMLHELP tag is set to YES, the HHC_LOCATION tag can # be used to specify the location (absolute path including file name) of # the HTML help compiler (hhc.exe). If non-empty doxygen will try to run # the HTML help compiler on the generated index.hhp. HHC_LOCATION = # If the GENERATE_HTMLHELP tag is set to YES, the GENERATE_CHI flag # controls if a separate .chi index file is generated (YES) or that # it should be included in the master .chm file (NO). GENERATE_CHI = NO # If the GENERATE_HTMLHELP tag is set to YES, the BINARY_TOC flag # controls whether a binary table of contents is generated (YES) or a # normal table of contents (NO) in the .chm file. BINARY_TOC = NO # The TOC_EXPAND flag can be set to YES to add extra items for group members # to the contents of the HTML help documentation and to the tree view. TOC_EXPAND = NO # The DISABLE_INDEX tag can be used to turn on/off the condensed index at # top of each HTML page. The value NO (the default) enables the index and # the value YES disables it. DISABLE_INDEX = NO # This tag can be used to set the number of enum values (range [1..20]) # that doxygen will group on one line in the generated HTML documentation. ENUM_VALUES_PER_LINE = 4 # If the GENERATE_TREEVIEW tag is set to YES, a side panel will be # generated containing a tree-like index structure (just like the one that # is generated for HTML Help). For this to work a browser that supports # JavaScript, DHTML, CSS and frames is required (for instance Mozilla 1.0+, # Netscape 6.0+, Internet explorer 5.0+, or Konqueror). Windows users are # probably better off using the HTML help feature. GENERATE_TREEVIEW = NO # If the treeview is enabled (see GENERATE_TREEVIEW) then this tag can be # used to set the initial width (in pixels) of the frame in which the tree # is shown. TREEVIEW_WIDTH = 250 #--------------------------------------------------------------------------- # configuration options related to the LaTeX output #--------------------------------------------------------------------------- # If the GENERATE_LATEX tag is set to YES (the default) Doxygen will # generate Latex output. GENERATE_LATEX = NO # The LATEX_OUTPUT tag is used to specify where the LaTeX docs will be put. # If a relative path is entered the value of OUTPUT_DIRECTORY will be # put in front of it. If left blank `latex' will be used as the default path. LATEX_OUTPUT = latex # The LATEX_CMD_NAME tag can be used to specify the LaTeX command name to be # invoked. If left blank `latex' will be used as the default command name. LATEX_CMD_NAME = latex # The MAKEINDEX_CMD_NAME tag can be used to specify the command name to # generate index for LaTeX. If left blank `makeindex' will be used as the # default command name. MAKEINDEX_CMD_NAME = makeindex # If the COMPACT_LATEX tag is set to YES Doxygen generates more compact # LaTeX documents. This may be useful for small projects and may help to # save some trees in general. COMPACT_LATEX = NO # The PAPER_TYPE tag can be used to set the paper type that is used # by the printer. Possible values are: a4, a4wide, letter, legal and # executive. If left blank a4wide will be used. PAPER_TYPE = letter # The EXTRA_PACKAGES tag can be to specify one or more names of LaTeX # packages that should be included in the LaTeX output. EXTRA_PACKAGES = # The LATEX_HEADER tag can be used to specify a personal LaTeX header for # the generated latex document. The header should contain everything until # the first chapter. If it is left blank doxygen will generate a # standard header. Notice: only use this tag if you know what you are doing! LATEX_HEADER = # If the PDF_HYPERLINKS tag is set to YES, the LaTeX that is generated # is prepared for conversion to pdf (using ps2pdf). The pdf file will # contain links (just like the HTML output) instead of page references # This makes the output suitable for online browsing using a pdf viewer. PDF_HYPERLINKS = YES # If the USE_PDFLATEX tag is set to YES, pdflatex will be used instead of # plain latex in the generated Makefile. Set this option to YES to get a # higher quality PDF documentation. USE_PDFLATEX = YES # If the LATEX_BATCHMODE tag is set to YES, doxygen will add the \\batchmode. # command to the generated LaTeX files. This will instruct LaTeX to keep # running if errors occur, instead of asking the user for help. # This option is also used when generating formulas in HTML. LATEX_BATCHMODE = NO # If LATEX_HIDE_INDICES is set to YES then doxygen will not # include the index chapters (such as File Index, Compound Index, etc.) # in the output. LATEX_HIDE_INDICES = NO #--------------------------------------------------------------------------- # configuration options related to the RTF output #--------------------------------------------------------------------------- # If the GENERATE_RTF tag is set to YES Doxygen will generate RTF output # The RTF output is optimized for Word 97 and may not look very pretty with # other RTF readers or editors. GENERATE_RTF = NO # The RTF_OUTPUT tag is used to specify where the RTF docs will be put. # If a relative path is entered the value of OUTPUT_DIRECTORY will be # put in front of it. If left blank `rtf' will be used as the default path. RTF_OUTPUT = rtf # If the COMPACT_RTF tag is set to YES Doxygen generates more compact # RTF documents. This may be useful for small projects and may help to # save some trees in general. COMPACT_RTF = NO # If the RTF_HYPERLINKS tag is set to YES, the RTF that is generated # will contain hyperlink fields. The RTF file will # contain links (just like the HTML output) instead of page references. # This makes the output suitable for online browsing using WORD or other # programs which support those fields. # Note: wordpad (write) and others do not support links. RTF_HYPERLINKS = NO # Load stylesheet definitions from file. Syntax is similar to doxygen's # config file, i.e. a series of assignments. You only have to provide # replacements, missing definitions are set to their default value. RTF_STYLESHEET_FILE = # Set optional variables used in the generation of an rtf document. # Syntax is similar to doxygen's config file. RTF_EXTENSIONS_FILE = #--------------------------------------------------------------------------- # configuration options related to the man page output #--------------------------------------------------------------------------- # If the GENERATE_MAN tag is set to YES (the default) Doxygen will # generate man pages GENERATE_MAN = YES # The MAN_OUTPUT tag is used to specify where the man pages will be put. # If a relative path is entered the value of OUTPUT_DIRECTORY will be # put in front of it. If left blank `man' will be used as the default path. MAN_OUTPUT = man # The MAN_EXTENSION tag determines the extension that is added to # the generated man pages (default is the subroutine's section .3) MAN_EXTENSION = .3 # If the MAN_LINKS tag is set to YES and Doxygen generates man output, # then it will generate one additional man file for each entity # documented in the real man page(s). These additional files # only source the real man page, but without them the man command # would be unable to find the correct page. The default is NO. MAN_LINKS = YES #--------------------------------------------------------------------------- # configuration options related to the XML output #--------------------------------------------------------------------------- # If the GENERATE_XML tag is set to YES Doxygen will # generate an XML file that captures the structure of # the code including all documentation. GENERATE_XML = NO # The XML_OUTPUT tag is used to specify where the XML pages will be put. # If a relative path is entered the value of OUTPUT_DIRECTORY will be # put in front of it. If left blank `xml' will be used as the default path. XML_OUTPUT = xml # The XML_SCHEMA tag can be used to specify an XML schema, # which can be used by a validating XML parser to check the # syntax of the XML files. XML_SCHEMA = # The XML_DTD tag can be used to specify an XML DTD, # which can be used by a validating XML parser to check the # syntax of the XML files. XML_DTD = # If the XML_PROGRAMLISTING tag is set to YES Doxygen will # dump the program listings (including syntax highlighting # and cross-referencing information) to the XML output. Note that # enabling this will significantly increase the size of the XML output. XML_PROGRAMLISTING = YES #--------------------------------------------------------------------------- # configuration options for the AutoGen Definitions output #--------------------------------------------------------------------------- # If the GENERATE_AUTOGEN_DEF tag is set to YES Doxygen will # generate an AutoGen Definitions (see autogen.sf.net) file # that captures the structure of the code including all # documentation. Note that this feature is still experimental # and incomplete at the moment. GENERATE_AUTOGEN_DEF = NO #--------------------------------------------------------------------------- # configuration options related to the Perl module output #--------------------------------------------------------------------------- # If the GENERATE_PERLMOD tag is set to YES Doxygen will # generate a Perl module file that captures the structure of # the code including all documentation. Note that this # feature is still experimental and incomplete at the # moment. GENERATE_PERLMOD = NO # If the PERLMOD_LATEX tag is set to YES Doxygen will generate # the necessary Makefile rules, Perl scripts and LaTeX code to be able # to generate PDF and DVI output from the Perl module output. PERLMOD_LATEX = NO # If the PERLMOD_PRETTY tag is set to YES the Perl module output will be # nicely formatted so it can be parsed by a human reader. This is useful # if you want to understand what is going on. On the other hand, if this # tag is set to NO the size of the Perl module output will be much smaller # and Perl will parse it just the same. PERLMOD_PRETTY = YES # The names of the make variables in the generated doxyrules.make file # are prefixed with the string contained in PERLMOD_MAKEVAR_PREFIX. # This is useful so different doxyrules.make files included by the same # Makefile don't overwrite each other's variables. PERLMOD_MAKEVAR_PREFIX = #--------------------------------------------------------------------------- # Configuration options related to the preprocessor #--------------------------------------------------------------------------- # If the ENABLE_PREPROCESSING tag is set to YES (the default) Doxygen will # evaluate all C-preprocessor directives found in the sources and include # files. ENABLE_PREPROCESSING = YES # If the MACRO_EXPANSION tag is set to YES Doxygen will expand all macro # names in the source code. If set to NO (the default) only conditional # compilation will be performed. Macro expansion can be done in a controlled # way by setting EXPAND_ONLY_PREDEF to YES. MACRO_EXPANSION = NO # If the EXPAND_ONLY_PREDEF and MACRO_EXPANSION tags are both set to YES # then the macro expansion is limited to the macros specified with the # PREDEFINED and EXPAND_AS_DEFINED tags. EXPAND_ONLY_PREDEF = NO # If the SEARCH_INCLUDES tag is set to YES (the default) the includes files # in the INCLUDE_PATH (see below) will be search if a #include is found. SEARCH_INCLUDES = YES # The INCLUDE_PATH tag can be used to specify one or more directories that # contain include files that are not input files but should be processed by # the preprocessor. INCLUDE_PATH = # You can use the INCLUDE_FILE_PATTERNS tag to specify one or more wildcard # patterns (like *.h and *.hpp) to filter out the header-files in the # directories. If left blank, the patterns specified with FILE_PATTERNS will # be used. INCLUDE_FILE_PATTERNS = # The PREDEFINED tag can be used to specify one or more macro names that # are defined before the preprocessor is started (similar to the -D option of # gcc). The argument of the tag is a list of macros of the form: name # or name=definition (no spaces). If the definition and the = are # omitted =1 is assumed. To prevent a macro definition from being # undefined via #undef or recursively expanded use the := operator # instead of the = operator. PREDEFINED = _PUBLIC_ # If the MACRO_EXPANSION and EXPAND_ONLY_PREDEF tags are set to YES then # this tag can be used to specify a list of macro names that should be expanded. # The macro definition that is found in the sources will be used. # Use the PREDEFINED tag if you want to use a different macro definition. EXPAND_AS_DEFINED = # If the SKIP_FUNCTION_MACROS tag is set to YES (the default) then # doxygen's preprocessor will remove all function-like macros that are alone # on a line, have an all uppercase name, and do not end with a semicolon. Such # function macros are typically used for boiler-plate code, and will confuse # the parser if not removed. SKIP_FUNCTION_MACROS = YES #--------------------------------------------------------------------------- # Configuration::additions related to external references #--------------------------------------------------------------------------- # The TAGFILES option can be used to specify one or more tagfiles. # Optionally an initial location of the external documentation # can be added for each tagfile. The format of a tag file without # this location is as follows: # TAGFILES = file1 file2 ... # Adding location for the tag files is done as follows: # TAGFILES = file1=loc1 "file2 = loc2" ... # where "loc1" and "loc2" can be relative or absolute paths or # URLs. If a location is present for each tag, the installdox tool # does not have to be run to correct the links. # Note that each tag file must have a unique name # (where the name does NOT include the path) # If a tag file is not located in the directory in which doxygen # is run, you must also specify the path to the tagfile here. TAGFILES = # When a file name is specified after GENERATE_TAGFILE, doxygen will create # a tag file that is based on the input files it reads. GENERATE_TAGFILE = # If the ALLEXTERNALS tag is set to YES all external classes will be listed # in the class index. If set to NO only the inherited external classes # will be listed. ALLEXTERNALS = NO # If the EXTERNAL_GROUPS tag is set to YES all external groups will be listed # in the modules index. If set to NO, only the current project's groups will # be listed. EXTERNAL_GROUPS = YES # The PERL_PATH should be the absolute path and name of the perl script # interpreter (i.e. the result of `which perl'). PERL_PATH = /usr/bin/perl #--------------------------------------------------------------------------- # Configuration options related to the dot tool #--------------------------------------------------------------------------- # If the CLASS_DIAGRAMS tag is set to YES (the default) Doxygen will # generate a inheritance diagram (in HTML, RTF and LaTeX) for classes with base # or super classes. Setting the tag to NO turns the diagrams off. Note that # this option is superseded by the HAVE_DOT option below. This is only a # fallback. It is recommended to install and use dot, since it yields more # powerful graphs. CLASS_DIAGRAMS = YES # You can define message sequence charts within doxygen comments using the \msc # command. Doxygen will then run the mscgen tool (see http://www.mcternan.me.uk/mscgen/) to # produce the chart and insert it in the documentation. The MSCGEN_PATH tag allows you to # specify the directory where the mscgen tool resides. If left empty the tool is assumed to # be found in the default search path. MSCGEN_PATH = # If set to YES, the inheritance and collaboration graphs will hide # inheritance and usage relations if the target is undocumented # or is not a class. HIDE_UNDOC_RELATIONS = YES # If you set the HAVE_DOT tag to YES then doxygen will assume the dot tool is # available from the path. This tool is part of Graphviz, a graph visualization # toolkit from AT&T and Lucent Bell Labs. The other options in this section # have no effect if this option is set to NO (the default) HAVE_DOT = NO # If the CLASS_GRAPH and HAVE_DOT tags are set to YES then doxygen # will generate a graph for each documented class showing the direct and # indirect inheritance relations. Setting this tag to YES will force the # the CLASS_DIAGRAMS tag to NO. CLASS_GRAPH = YES # If the COLLABORATION_GRAPH and HAVE_DOT tags are set to YES then doxygen # will generate a graph for each documented class showing the direct and # indirect implementation dependencies (inheritance, containment, and # class references variables) of the class with other documented classes. COLLABORATION_GRAPH = YES # If the GROUP_GRAPHS and HAVE_DOT tags are set to YES then doxygen # will generate a graph for groups, showing the direct groups dependencies GROUP_GRAPHS = YES # If the UML_LOOK tag is set to YES doxygen will generate inheritance and # collaboration diagrams in a style similar to the OMG's Unified Modeling # Language. UML_LOOK = NO # If set to YES, the inheritance and collaboration graphs will show the # relations between templates and their instances. TEMPLATE_RELATIONS = NO # If the ENABLE_PREPROCESSING, SEARCH_INCLUDES, INCLUDE_GRAPH, and HAVE_DOT # tags are set to YES then doxygen will generate a graph for each documented # file showing the direct and indirect include dependencies of the file with # other documented files. INCLUDE_GRAPH = YES # If the ENABLE_PREPROCESSING, SEARCH_INCLUDES, INCLUDED_BY_GRAPH, and # HAVE_DOT tags are set to YES then doxygen will generate a graph for each # documented header file showing the documented files that directly or # indirectly include this file. INCLUDED_BY_GRAPH = YES # If the CALL_GRAPH and HAVE_DOT tags are set to YES then doxygen will # generate a call dependency graph for every global function or class method. # Note that enabling this option will significantly increase the time of a run. # So in most cases it will be better to enable call graphs for selected # functions only using the \callgraph command. CALL_GRAPH = NO # If the CALLER_GRAPH and HAVE_DOT tags are set to YES then doxygen will # generate a caller dependency graph for every global function or class method. # Note that enabling this option will significantly increase the time of a run. # So in most cases it will be better to enable caller graphs for selected # functions only using the \callergraph command. CALLER_GRAPH = NO # If the GRAPHICAL_HIERARCHY and HAVE_DOT tags are set to YES then doxygen # will graphical hierarchy of all classes instead of a textual one. GRAPHICAL_HIERARCHY = YES # If the DIRECTORY_GRAPH, SHOW_DIRECTORIES and HAVE_DOT tags are set to YES # then doxygen will show the dependencies a directory has on other directories # in a graphical way. The dependency relations are determined by the #include # relations between the files in the directories. DIRECTORY_GRAPH = YES # The DOT_IMAGE_FORMAT tag can be used to set the image format of the images # generated by dot. Possible values are png, jpg, or gif # If left blank png will be used. DOT_IMAGE_FORMAT = png # The tag DOT_PATH can be used to specify the path where the dot tool can be # found. If left blank, it is assumed the dot tool can be found in the path. DOT_PATH = # The DOTFILE_DIRS tag can be used to specify one or more directories that # contain dot files that are included in the documentation (see the # \dotfile command). DOTFILE_DIRS = # The MAX_DOT_GRAPH_MAX_NODES tag can be used to set the maximum number of # nodes that will be shown in the graph. If the number of nodes in a graph # becomes larger than this value, doxygen will truncate the graph, which is # visualized by representing a node as a red box. Note that doxygen will always # show the root nodes and its direct children regardless of this setting. DOT_GRAPH_MAX_NODES = 50 # Set the DOT_TRANSPARENT tag to YES to generate images with a transparent # background. This is disabled by default, which results in a white background. # Warning: Depending on the platform used, enabling this option may lead to # badly anti-aliased labels on the edges of a graph (i.e. they become hard to # read). DOT_TRANSPARENT = NO # Set the DOT_MULTI_TARGETS tag to YES allow dot to generate multiple output # files in one run (i.e. multiple -o and -T options on the command line). This # makes dot run faster, but since only newer versions of dot (>1.8.10) # support this, this feature is disabled by default. DOT_MULTI_TARGETS = NO # If the GENERATE_LEGEND tag is set to YES (the default) Doxygen will # generate a legend page explaining the meaning of the various boxes and # arrows in the dot generated graphs. GENERATE_LEGEND = YES # If the DOT_CLEANUP tag is set to YES (the default) Doxygen will # remove the intermediate dot files that are used to generate # the various graphs. DOT_CLEANUP = YES #--------------------------------------------------------------------------- # Configuration::additions related to the search engine #--------------------------------------------------------------------------- # The SEARCHENGINE tag specifies whether or not a search engine should be # used. If set to NO the values of all tags below this one will be ignored. SEARCHENGINE = NO openchange-2.0/libmapi/FXICS.c000066400000000000000000001665701223057412600161400ustar00rootroot00000000000000/* OpenChange MAPI implementation. Copyright (C) Julien Kerihuel 2007-2011. Copyright (C) Brad Hards 2010-2011. This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see . */ #include "libmapi/libmapi.h" #include "libmapi/libmapi_private.h" /** \file FXICS.c \brief Fast Transfer and Incremental Change Synchronization operations */ /** \details Reserves a range of IDs to be used by a local replica \param obj_store pointer on the store MAPI object \param IdCount ID range length to reserve \param ReplGuid pointer to the GUID structure returned by the server \param GlobalCount byte array that specifies the first allocated field \return MAPI_E_SUCCESS on success, otherwise MAPI error. \note Developers may also call GetLastError() to retrieve the last MAPI error code. Possible MAPI error codes are: - MAPI_E_NOT_INITIALIZED: MAPI subsystem has not been initialized - MAPI_E_INVALID_PARAMETER: one of the function parameters is invalid - MAPI_E_CALL_FAILED: A network problem was encountered during the transaction */ _PUBLIC_ enum MAPISTATUS GetLocalReplicaIds(mapi_object_t *obj_store, uint32_t IdCount, struct GUID *ReplGuid, uint8_t GlobalCount[6]) { struct mapi_request *mapi_request; struct mapi_response *mapi_response; struct EcDoRpc_MAPI_REQ *mapi_req; struct GetLocalReplicaIds_req request; struct GetLocalReplicaIds_repl *reply; struct mapi_session *session; NTSTATUS status; enum MAPISTATUS retval; uint32_t size = 0; TALLOC_CTX *mem_ctx; uint8_t logon_id = 0; /* Sanity checks */ OPENCHANGE_RETVAL_IF(!obj_store, MAPI_E_INVALID_PARAMETER, NULL); OPENCHANGE_RETVAL_IF(!ReplGuid, MAPI_E_INVALID_PARAMETER, NULL); session = mapi_object_get_session(obj_store); OPENCHANGE_RETVAL_IF(!session, MAPI_E_INVALID_PARAMETER, NULL); if ((retval = mapi_object_get_logon_id(obj_store, &logon_id)) != MAPI_E_SUCCESS) return retval; mem_ctx = talloc_named(session, 0, "GetLocalReplicaIds"); size = 0; /* Fill the GetLocalReplicaIds operation */ request.IdCount = IdCount; size += sizeof (uint32_t); /* Fill the MAPI_REQ structure */ mapi_req = talloc_zero(mem_ctx, struct EcDoRpc_MAPI_REQ); mapi_req->opnum = op_MAPI_GetLocalReplicaIds; mapi_req->logon_id = logon_id; mapi_req->handle_idx = 0; mapi_req->u.mapi_GetLocalReplicaIds = request; size += 5; /* Fill the mapi_request structure */ mapi_request = talloc_zero(mem_ctx, struct mapi_request); mapi_request->mapi_len = size + sizeof (uint32_t); mapi_request->length = (uint16_t)size; mapi_request->mapi_req = mapi_req; mapi_request->handles = talloc_array(mem_ctx, uint32_t, 1); mapi_request->handles[0] = mapi_object_get_handle(obj_store); status = emsmdb_transaction_wrapper(session, mem_ctx, mapi_request, &mapi_response); OPENCHANGE_RETVAL_IF(!NT_STATUS_IS_OK(status), MAPI_E_CALL_FAILED, mem_ctx); OPENCHANGE_RETVAL_IF(!mapi_response->mapi_repl, MAPI_E_CALL_FAILED, mem_ctx); retval = mapi_response->mapi_repl->error_code; OPENCHANGE_RETVAL_IF(retval, retval, mem_ctx); OPENCHANGE_CHECK_NOTIFICATION(session, mapi_response); /* Retrieve output parameters */ reply = &mapi_response->mapi_repl->u.mapi_GetLocalReplicaIds; *ReplGuid = reply->ReplGuid; memcpy(GlobalCount, reply->GlobalCount, 6); talloc_free(mapi_response); talloc_free(mem_ctx); return MAPI_E_SUCCESS; } /** \details Prepare a server for Fast Transfer receive This function is used to configure a server for fast-transfer receive operation. This could be the target server in a server->client->server copy, or for a client->server upload. \param obj the target object for the upload (folder, message or attachment) \param sourceOperation the type of transfer (one of FastTransferDest_CopyTo, FastTransferDest_CopyProperties,FastTransferDest_CopyMessages or FastTransferDest_CopyFolder) \param obj_destination_context the fast transfer context for future ROPs. \return MAPI_E_SUCCESS on success, otherwise MAPI error. \note Developers may also call GetLastError() to retrieve the last MAPI error code. Possible MAPI error codes are: - MAPI_E_NOT_INITIALIZED: MAPI subsystem has not been initialized - MAPI_E_INVALID_PARAMETER: one of the function parameters is invalid - MAPI_E_CALL_FAILED: A network problem was encountered during the transaction */ _PUBLIC_ enum MAPISTATUS FXDestConfigure(mapi_object_t *obj, enum FastTransferDestConfig_SourceOperation sourceOperation, mapi_object_t *obj_destination_context) { struct mapi_request *mapi_request; struct mapi_response *mapi_response; struct EcDoRpc_MAPI_REQ *mapi_req; struct FastTransferDestinationConfigure_req request; struct mapi_session *session; NTSTATUS status; enum MAPISTATUS retval; uint32_t size = 0; TALLOC_CTX *mem_ctx; uint8_t logon_id = 0; /* Sanity checks */ OPENCHANGE_RETVAL_IF(!obj, MAPI_E_INVALID_PARAMETER, NULL); session = mapi_object_get_session(obj); OPENCHANGE_RETVAL_IF(!session, MAPI_E_INVALID_PARAMETER, NULL); OPENCHANGE_RETVAL_IF(!obj_destination_context, MAPI_E_INVALID_PARAMETER, NULL); if ((retval = mapi_object_get_logon_id(obj, &logon_id)) != MAPI_E_SUCCESS) return retval; mem_ctx = talloc_named(session, 0, "FXDestConfigure"); size = 0; /* Fill the ConfigureDestination operation */ request.handle_idx = 0x01; size += sizeof(uint8_t); request.SourceOperation = sourceOperation; size += sizeof(uint8_t); request.CopyFlags = 0x00; /* we don't support move yet */ size += sizeof(uint8_t); /* Fill the MAPI_REQ structure */ mapi_req = talloc_zero(mem_ctx, struct EcDoRpc_MAPI_REQ); mapi_req->opnum = op_MAPI_FastTransferDestConfigure; mapi_req->logon_id = logon_id; mapi_req->handle_idx = 0; mapi_req->u.mapi_FastTransferDestinationConfigure = request; size += 5; /* Fill the mapi_request structure */ mapi_request = talloc_zero(mem_ctx, struct mapi_request); mapi_request->mapi_len = size + sizeof (uint32_t) * 2; mapi_request->length = (uint16_t)size; mapi_request->mapi_req = mapi_req; mapi_request->handles = talloc_array(mem_ctx, uint32_t, 2); mapi_request->handles[0] = mapi_object_get_handle(obj); mapi_request->handles[1] = 0xFFFFFFFF; status = emsmdb_transaction_wrapper(session, mem_ctx, mapi_request, &mapi_response); OPENCHANGE_RETVAL_IF(!NT_STATUS_IS_OK(status), MAPI_E_CALL_FAILED, mem_ctx); OPENCHANGE_RETVAL_IF(!mapi_response->mapi_repl, MAPI_E_CALL_FAILED, mem_ctx); retval = mapi_response->mapi_repl->error_code; OPENCHANGE_RETVAL_IF(retval, retval, mem_ctx); /* Set object session and handle */ mapi_object_set_session(obj_destination_context, session); mapi_object_set_handle(obj_destination_context, mapi_response->handles[1]); mapi_object_set_logon_id(obj_destination_context, logon_id); talloc_free(mapi_response); talloc_free(mem_ctx); return MAPI_E_SUCCESS; } /** \details Advise a server of the "other server" version This function is used to set up a fast server-client-server transfer. \param obj_store pointer to the store MAPI object \param version the server version \return MAPI_E_SUCCESS on success, otherwise MAPI error. \note Developers may also call GetLastError() to retrieve the last MAPI error code. Possible MAPI error codes are: - MAPI_E_NOT_INITIALIZED: MAPI subsystem has not been initialized - MAPI_E_INVALID_PARAMETER: one of the function parameter is invalid - MAPI_E_CALL_FAILED: A network problem was encountered during the transaction */ _PUBLIC_ enum MAPISTATUS TellVersion(mapi_object_t *obj_store, uint16_t version[3]) { struct mapi_request *mapi_request; struct mapi_response *mapi_response; struct EcDoRpc_MAPI_REQ *mapi_req; struct TellVersion_req request; struct mapi_session *session; NTSTATUS status; enum MAPISTATUS retval; uint32_t size = 0; TALLOC_CTX *mem_ctx; uint8_t logon_id = 0; /* Sanity checks */ OPENCHANGE_RETVAL_IF(!obj_store, MAPI_E_INVALID_PARAMETER, NULL); OPENCHANGE_RETVAL_IF(!version, MAPI_E_INVALID_PARAMETER, NULL); session = mapi_object_get_session(obj_store); OPENCHANGE_RETVAL_IF(!session, MAPI_E_INVALID_PARAMETER, NULL); if ((retval = mapi_object_get_logon_id(obj_store, &logon_id)) != MAPI_E_SUCCESS) return retval; mem_ctx = talloc_named(session, 0, "TellVersion"); size = 0; /* Fill the operation */ request.version[0] = version[0]; request.version[1] = version[1]; request.version[2] = version[2]; size += 3 * sizeof (uint16_t); /* Fill the MAPI_REQ structure */ mapi_req = talloc_zero(mem_ctx, struct EcDoRpc_MAPI_REQ); mapi_req->opnum = op_MAPI_TellVersion; mapi_req->logon_id = logon_id; mapi_req->handle_idx = 0; mapi_req->u.mapi_TellVersion = request; size += 5; /* Fill the mapi_request structure */ mapi_request = talloc_zero(mem_ctx, struct mapi_request); mapi_request->mapi_len = size + sizeof (uint32_t); mapi_request->length = (uint16_t)size; mapi_request->mapi_req = mapi_req; mapi_request->handles = talloc_array(mem_ctx, uint32_t, 1); mapi_request->handles[0] = mapi_object_get_handle(obj_store); status = emsmdb_transaction_wrapper(session, mem_ctx, mapi_request, &mapi_response); OPENCHANGE_RETVAL_IF(!NT_STATUS_IS_OK(status), MAPI_E_CALL_FAILED, mem_ctx); OPENCHANGE_RETVAL_IF(!mapi_response->mapi_repl, MAPI_E_CALL_FAILED, mem_ctx); retval = mapi_response->mapi_repl->error_code; OPENCHANGE_RETVAL_IF(retval, retval, mem_ctx); talloc_free(mapi_response); talloc_free(mem_ctx); return MAPI_E_SUCCESS; } /** \details Prepare a server for Fast Transfer transmission of a folder hierachy This function is used to configure a server for a fast-transfer folder hierachy send operation. This could be the origin server in a server->client->server copy, or for a server to client download. This operation copies the folder object, and any sub-objects (including folder properties and messages). It can optionally copy sub-folders, depending on copyFlags. \param obj the source object for the operation (folder) \param copyFlags flags that change the copy behaviour (see below) \param sendOptions flags that change the format of the transfer (see FXCopyMessages) \param obj_source_context the fast transfer source context for future ROPs \a copyflags can be zero or more of the following: - FastTransferCopyFolder_CopySubfolders to recursively copy any sub-folders and contained messages - FastTransferCopyFolder_NoGhostedContent to omit any ghosted content when copying public folders \return MAPI_E_SUCCESS on success, otherwise MAPI error. \note Developers may also call GetLastError() to retrieve the last MAPI error code. Possible MAPI error codes are: - MAPI_E_NOT_INITIALIZED: MAPI subsystem has not been initialized - MAPI_E_INVALID_PARAMETER: one of the function parameters is invalid - MAPI_E_CALL_FAILED: A network problem was encountered during the transaction */ _PUBLIC_ enum MAPISTATUS FXCopyFolder(mapi_object_t *obj, uint8_t copyFlags, uint8_t sendOptions, mapi_object_t *obj_source_context) { struct mapi_request *mapi_request; struct mapi_response *mapi_response; struct EcDoRpc_MAPI_REQ *mapi_req; struct FastTransferSourceCopyFolder_req request; struct mapi_session *session; NTSTATUS status; enum MAPISTATUS retval; uint32_t size = 0; TALLOC_CTX *mem_ctx; uint8_t logon_id = 0; /* Sanity checks */ OPENCHANGE_RETVAL_IF(!obj, MAPI_E_INVALID_PARAMETER, NULL); session = mapi_object_get_session(obj); OPENCHANGE_RETVAL_IF(!session, MAPI_E_INVALID_PARAMETER, NULL); OPENCHANGE_RETVAL_IF(!obj_source_context, MAPI_E_INVALID_PARAMETER, NULL); if ((retval = mapi_object_get_logon_id(obj, &logon_id)) != MAPI_E_SUCCESS) return retval; mem_ctx = talloc_named(session, 0, "FXCopyFolder"); size = 0; /* Fill the CopyFolder operation */ request.handle_idx = 0x01; size += sizeof(uint8_t); request.CopyFlags = copyFlags; size += sizeof(uint8_t); request.SendOptions = sendOptions; size += sizeof(uint8_t); /* Fill the MAPI_REQ structure */ mapi_req = talloc_zero(mem_ctx, struct EcDoRpc_MAPI_REQ); mapi_req->opnum = op_MAPI_FastTransferSourceCopyFolder; mapi_req->logon_id = logon_id; mapi_req->handle_idx = 0; mapi_req->u.mapi_FastTransferSourceCopyFolder = request; size += 5; /* Fill the mapi_request structure */ mapi_request = talloc_zero(mem_ctx, struct mapi_request); mapi_request->mapi_len = size + sizeof (uint32_t) * 2; mapi_request->length = (uint16_t)size; mapi_request->mapi_req = mapi_req; mapi_request->handles = talloc_array(mem_ctx, uint32_t, 2); mapi_request->handles[0] = mapi_object_get_handle(obj); mapi_request->handles[1] = 0xffffffff; status = emsmdb_transaction_wrapper(session, mem_ctx, mapi_request, &mapi_response); OPENCHANGE_RETVAL_IF(!NT_STATUS_IS_OK(status), MAPI_E_CALL_FAILED, mem_ctx); OPENCHANGE_RETVAL_IF(!mapi_response->mapi_repl, MAPI_E_CALL_FAILED, mem_ctx); retval = mapi_response->mapi_repl->error_code; OPENCHANGE_RETVAL_IF(retval, retval, mem_ctx); /* Set object session and handle */ mapi_object_set_session(obj_source_context, session); mapi_object_set_handle(obj_source_context, mapi_response->handles[1]); mapi_object_set_logon_id(obj_source_context, logon_id); talloc_free(mapi_response); talloc_free(mem_ctx); return MAPI_E_SUCCESS; } /** \details Prepare a server for Fast Transfer transmission of a list of messages This function is used to configure a server for a fast-transfer message send operation. This could be the origin server in a server->client->server copy, or for a server to client download. This operation copies the message objects, and any sub-objects (including attachments and embedded messages). \param obj the source object for the operation (folder) \param message_ids the message IDs for the messages to copy. \param copyFlags flags that change the copy behaviour (see below) \param sendOptions flags that change the format of the transfer (see below) \param obj_source_context the fast transfer source context for future ROPs \a copyflags can be zero or more of the following: - FastTransferCopyMessage_Move - configure output for move - FastTransferCopyMessage_BestBody - output message bodies in original format (if not set, output in RTF) - FastTransferCopyMessage_SendEntryId - include message and change identification in the output stream \a sendOptions can be zero or more of the following: - FastTransfer_Unicode - enable Unicode output - FastTransfer_UseCpid (not normally used directly - implied by ForUpload) - FastTransfer_ForUpload - (enable Unicode, and advise the server that transfer is server->client->server) - FastTransfer_RecoverMode - advise the server that the client supports recovery mode - FastTransfer_ForceUnicode - force Unicode output - FastTransfer_PartialItem - used for synchronisation download If the \a FastTransfer_ForUpload is set, the next call must be TellVersion() \return MAPI_E_SUCCESS on success, otherwise MAPI error. \note Developers may also call GetLastError() to retrieve the last MAPI error code. Possible MAPI error codes are: - MAPI_E_NOT_INITIALIZED: MAPI subsystem has not been initialized - MAPI_E_INVALID_PARAMETER: one of the function parameters is invalid - MAPI_E_CALL_FAILED: A network problem was encountered during the transaction */ _PUBLIC_ enum MAPISTATUS FXCopyMessages(mapi_object_t *obj, mapi_id_array_t *message_ids, uint8_t copyFlags, uint8_t sendOptions, mapi_object_t *obj_source_context) { struct mapi_request *mapi_request; struct mapi_response *mapi_response; struct EcDoRpc_MAPI_REQ *mapi_req; struct FastTransferSourceCopyMessages_req request; struct mapi_session *session; NTSTATUS status; enum MAPISTATUS retval; uint32_t size = 0; TALLOC_CTX *mem_ctx; uint8_t logon_id = 0; /* Sanity checks */ OPENCHANGE_RETVAL_IF(!obj, MAPI_E_INVALID_PARAMETER, NULL); session = mapi_object_get_session(obj); OPENCHANGE_RETVAL_IF(!session, MAPI_E_INVALID_PARAMETER, NULL); OPENCHANGE_RETVAL_IF(!obj_source_context, MAPI_E_INVALID_PARAMETER, NULL); OPENCHANGE_RETVAL_IF(!message_ids, MAPI_E_INVALID_PARAMETER, NULL); if ((retval = mapi_object_get_logon_id(obj, &logon_id)) != MAPI_E_SUCCESS) return retval; mem_ctx = talloc_named(session, 0, "FXCopyMessages"); size = 0; /* Fill the CopyMessages operation */ request.handle_idx = 0x01; size += sizeof(uint8_t); request.MessageIdCount = message_ids->count; size += sizeof (uint16_t); retval = mapi_id_array_get(mem_ctx, message_ids, &(request.MessageIds)); OPENCHANGE_RETVAL_IF(retval, retval, mem_ctx); size += request.MessageIdCount * sizeof (mapi_id_t); request.CopyFlags = copyFlags; size += sizeof(uint8_t); request.SendOptions = sendOptions; size += sizeof(uint8_t); /* Fill the MAPI_REQ structure */ mapi_req = talloc_zero(mem_ctx, struct EcDoRpc_MAPI_REQ); mapi_req->opnum = op_MAPI_FastTransferSourceCopyMessages; mapi_req->logon_id = logon_id; mapi_req->handle_idx = 0; mapi_req->u.mapi_FastTransferSourceCopyMessages = request; size += 5; /* Fill the mapi_request structure */ mapi_request = talloc_zero(mem_ctx, struct mapi_request); mapi_request->mapi_len = size + sizeof (uint32_t) * 2; mapi_request->length = (uint16_t)size; mapi_request->mapi_req = mapi_req; mapi_request->handles = talloc_array(mem_ctx, uint32_t, 2); mapi_request->handles[0] = mapi_object_get_handle(obj); mapi_request->handles[1] = 0xffffffff; status = emsmdb_transaction_wrapper(session, mem_ctx, mapi_request, &mapi_response); OPENCHANGE_RETVAL_IF(!NT_STATUS_IS_OK(status), MAPI_E_CALL_FAILED, mem_ctx); OPENCHANGE_RETVAL_IF(!mapi_response->mapi_repl, MAPI_E_CALL_FAILED, mem_ctx); retval = mapi_response->mapi_repl->error_code; OPENCHANGE_RETVAL_IF(retval, retval, mem_ctx); /* Set object session and handle */ mapi_object_set_session(obj_source_context, session); mapi_object_set_handle(obj_source_context, mapi_response->handles[1]); mapi_object_set_logon_id(obj_source_context, logon_id); talloc_free(mapi_response); talloc_free(mem_ctx); return MAPI_E_SUCCESS; } /** \details Prepare a server for Fast Transfer transmission of a folder, message or attachment This function is used to configure a server for a fast-transfer download of a folder, message or attachment. This could be the origin server in a server->client->server copy, or for a server to client download. This operation copies the source object, potentially omitting some properties. It can optionally copy sub-objects, depending on \a Level. \param obj the source object for the operation (folder, message or attachment) \param level whether to copy sub-objects of folders or messages (set to 0) or not (set to any other value) \param copyFlags flags that change the copy behaviour (see below) \param sendOptions flags that change the format of the transfer (see FXCopyMessages) \param excludes the list of properties to exclude from the transfer \param obj_source_context the fast transfer source context for future ROPs \a copyflags can be zero or more of the following: - FastTransferCopyTo_Move to configure as part of a move operation - FastTransferCopyTo_BestBody to use original format for message bodies (if not set, use RTF instead) Be careful in setting \a level to something other than zero. In particular, if \a level is non-zero for a message, then the list of recipients, and any attachments or embedded messages, will not be transferred. \return MAPI_E_SUCCESS on success, otherwise MAPI error. \note Developers may also call GetLastError() to retrieve the last MAPI error code. Possible MAPI error codes are: - MAPI_E_NOT_INITIALIZED: MAPI subsystem has not been initialized - MAPI_E_INVALID_PARAMETER: one of the function parameters is invalid - MAPI_E_CALL_FAILED: A network problem was encountered during the transaction */ _PUBLIC_ enum MAPISTATUS FXCopyTo(mapi_object_t *obj, uint8_t level, uint32_t copyFlags, uint8_t sendOptions, struct SPropTagArray *excludes, mapi_object_t *obj_source_context) { struct mapi_request *mapi_request; struct mapi_response *mapi_response; struct EcDoRpc_MAPI_REQ *mapi_req; struct FastTransferSourceCopyTo_req request; struct mapi_session *session; NTSTATUS status; enum MAPISTATUS retval; uint32_t size = 0; TALLOC_CTX *mem_ctx; uint8_t logon_id = 0; /* Sanity checks */ OPENCHANGE_RETVAL_IF(!obj, MAPI_E_INVALID_PARAMETER, NULL); session = mapi_object_get_session(obj); OPENCHANGE_RETVAL_IF(!session, MAPI_E_INVALID_PARAMETER, NULL); OPENCHANGE_RETVAL_IF(!obj_source_context, MAPI_E_INVALID_PARAMETER, NULL); OPENCHANGE_RETVAL_IF(!excludes, MAPI_E_INVALID_PARAMETER, NULL); if ((retval = mapi_object_get_logon_id(obj, &logon_id)) != MAPI_E_SUCCESS) return retval; mem_ctx = talloc_named(session, 0, "FXCopyTo"); size = 0; /* Fill the CopyTo operation */ request.handle_idx = 0x01; size += sizeof(uint8_t); request.Level = level; size += sizeof(uint8_t); request.CopyFlags = copyFlags; size += sizeof(uint32_t); request.SendOptions = sendOptions; size += sizeof(uint8_t); request.PropertyTags.cValues = excludes->cValues; size += sizeof(uint16_t); request.PropertyTags.aulPropTag = excludes->aulPropTag; size += excludes->cValues * sizeof(enum MAPITAGS); /* Fill the MAPI_REQ structure */ mapi_req = talloc_zero(mem_ctx, struct EcDoRpc_MAPI_REQ); mapi_req->opnum = op_MAPI_FastTransferSourceCopyTo; mapi_req->logon_id = logon_id; mapi_req->handle_idx = 0; mapi_req->u.mapi_FastTransferSourceCopyTo = request; size += 5; /* Fill the mapi_request structure */ mapi_request = talloc_zero(mem_ctx, struct mapi_request); mapi_request->mapi_len = size + sizeof (uint32_t) * 2; mapi_request->length = (uint16_t)size; mapi_request->mapi_req = mapi_req; mapi_request->handles = talloc_array(mem_ctx, uint32_t, 2); mapi_request->handles[0] = mapi_object_get_handle(obj); mapi_request->handles[1] = 0xffffffff; status = emsmdb_transaction_wrapper(session, mem_ctx, mapi_request, &mapi_response); OPENCHANGE_RETVAL_IF(!NT_STATUS_IS_OK(status), MAPI_E_CALL_FAILED, mem_ctx); OPENCHANGE_RETVAL_IF(!mapi_response->mapi_repl, MAPI_E_CALL_FAILED, mem_ctx); retval = mapi_response->mapi_repl->error_code; OPENCHANGE_RETVAL_IF(retval, retval, mem_ctx); /* Set object session and handle */ mapi_object_set_session(obj_source_context, session); mapi_object_set_handle(obj_source_context, mapi_response->handles[1]); mapi_object_set_logon_id(obj_source_context, logon_id); talloc_free(mapi_response); talloc_free(mem_ctx); return MAPI_E_SUCCESS; } /** \details Prepare a server for Fast Transfer transmission of the properties of a folder, message or attachment This function is used to configure a server for a fast-transfer download of properties. This could be the origin server in a server->client->server copy, or for a server to client download. This operation copies the specified properties of the source object. It can optionally copy properties of sub-objects, depending on \a Level. \param obj the source object for the operation (folder, message or attachment) \param level whether to copy properties of sub-objects of folders or messages (set to 0) or not (set to any other value) \param copyFlags flags that change the copy behaviour (see below) \param sendOptions flags that change the format of the transfer (see FXCopyMessages) \param properties the list of properties to transfer \param obj_source_context the fast transfer source context for future ROPs \a copyflags may be the following: - FastTransferCopyProperties_Move to configure as part of a move operation Be careful in setting \a level to something other than zero. In particular, if \a level is non-zero for a message, then the list of recipients, and any attachments or embedded messages, will not be transferred. \return MAPI_E_SUCCESS on success, otherwise MAPI error. \note Developers may also call GetLastError() to retrieve the last MAPI error code. Possible MAPI error codes are: - MAPI_E_NOT_INITIALIZED: MAPI subsystem has not been initialized - MAPI_E_INVALID_PARAMETER: one of the function parameters is invalid - MAPI_E_CALL_FAILED: A network problem was encountered during the transaction */ _PUBLIC_ enum MAPISTATUS FXCopyProperties(mapi_object_t *obj, uint8_t level, uint32_t copyFlags, uint8_t sendOptions, struct SPropTagArray *properties, mapi_object_t *obj_source_context) { struct mapi_request *mapi_request; struct mapi_response *mapi_response; struct EcDoRpc_MAPI_REQ *mapi_req; struct FastTransferSourceCopyProperties_req request; struct mapi_session *session; NTSTATUS status; enum MAPISTATUS retval; uint32_t size = 0; TALLOC_CTX *mem_ctx; uint8_t logon_id = 0; /* Sanity checks */ OPENCHANGE_RETVAL_IF(!obj, MAPI_E_INVALID_PARAMETER, NULL); session = mapi_object_get_session(obj); OPENCHANGE_RETVAL_IF(!session, MAPI_E_INVALID_PARAMETER, NULL); OPENCHANGE_RETVAL_IF(!obj_source_context, MAPI_E_INVALID_PARAMETER, NULL); OPENCHANGE_RETVAL_IF(!properties, MAPI_E_INVALID_PARAMETER, NULL); if ((retval = mapi_object_get_logon_id(obj, &logon_id)) != MAPI_E_SUCCESS) return retval; mem_ctx = talloc_named(session, 0, "FXCopyProperties"); size = 0; /* Fill the CopyProperties operation */ request.handle_idx = 0x01; size += sizeof(uint8_t); request.Level = level; size += sizeof(uint8_t); request.CopyFlags = copyFlags; size += sizeof(uint8_t); request.SendOptions = sendOptions; size += sizeof(uint8_t); request.PropertyTags.cValues = properties->cValues; size += sizeof(uint16_t); request.PropertyTags.aulPropTag = properties->aulPropTag; size += properties->cValues * sizeof(enum MAPITAGS); /* Fill the MAPI_REQ structure */ mapi_req = talloc_zero(mem_ctx, struct EcDoRpc_MAPI_REQ); mapi_req->opnum = op_MAPI_FastTransferSourceCopyProps; mapi_req->logon_id = logon_id; mapi_req->handle_idx = 0; mapi_req->u.mapi_FastTransferSourceCopyProperties = request; size += 5; /* Fill the mapi_request structure */ mapi_request = talloc_zero(mem_ctx, struct mapi_request); mapi_request->mapi_len = size + sizeof (uint32_t) * 2; mapi_request->length = (uint16_t)size; mapi_request->mapi_req = mapi_req; mapi_request->handles = talloc_array(mem_ctx, uint32_t, 2); mapi_request->handles[0] = mapi_object_get_handle(obj); mapi_request->handles[1] = 0xffffffff; status = emsmdb_transaction_wrapper(session, mem_ctx, mapi_request, &mapi_response); OPENCHANGE_RETVAL_IF(!NT_STATUS_IS_OK(status), MAPI_E_CALL_FAILED, mem_ctx); OPENCHANGE_RETVAL_IF(!mapi_response->mapi_repl, MAPI_E_CALL_FAILED, mem_ctx); retval = mapi_response->mapi_repl->error_code; OPENCHANGE_RETVAL_IF(retval, retval, mem_ctx); /* Set object session and handle */ mapi_object_set_session(obj_source_context, session); mapi_object_set_handle(obj_source_context, mapi_response->handles[1]); mapi_object_set_logon_id(obj_source_context, logon_id); talloc_free(mapi_response); talloc_free(mem_ctx); return MAPI_E_SUCCESS; } /** Get data from source fast transfer object Fast transfers are done in blocks, each block transfered over a call to FXGetBuffer. If the block is small, it will fit into a single call, and the transferStatus will indicate completion. However larger transfers will require multiple calls. \param obj_source_context the source object (from FXCopyTo, FXCopyProperties, FXCopyFolder or FXCopyMessages) \param maxSize the maximum size (pass 0 to indicate maximum available size) \param transferStatus result of the transfer \param progressStepCount the approximate number of steps (of totalStepCount) completed \param totalStepCount the approximate number of steps (total) \param blob this part of the transfer \return MAPI_E_SUCCESS on success, otherwise MAPI error. \note Developers may also call GetLastError() to retrieve the last MAPI error code. Possible MAPI error codes are: - MAPI_E_NOT_INITIALIZED: MAPI subsystem has not been initialized - MAPI_E_INVALID_PARAMETER: one of the function parameters is invalid - MAPI_E_CALL_FAILED: A network problem was encountered during the transaction */ _PUBLIC_ enum MAPISTATUS FXGetBuffer(mapi_object_t *obj_source_context, uint16_t maxSize, enum TransferStatus *transferStatus, uint16_t *progressStepCount, uint16_t *totalStepCount, DATA_BLOB *blob) { struct mapi_request *mapi_request; struct mapi_response *mapi_response; struct EcDoRpc_MAPI_REQ *mapi_req; struct FastTransferSourceGetBuffer_req request; struct FastTransferSourceGetBuffer_repl *reply; struct mapi_session *session; NTSTATUS status; enum MAPISTATUS retval; uint32_t size = 0; TALLOC_CTX *mem_ctx; uint8_t logon_id = 0; /* Sanity checks */ OPENCHANGE_RETVAL_IF(!obj_source_context, MAPI_E_INVALID_PARAMETER, NULL); session = mapi_object_get_session(obj_source_context); OPENCHANGE_RETVAL_IF(!session, MAPI_E_INVALID_PARAMETER, NULL); if ((retval = mapi_object_get_logon_id(obj_source_context, &logon_id)) != MAPI_E_SUCCESS) return retval; mem_ctx = talloc_named(session, 0, "FXGetBuffer"); size = 0; /* Fill the GetBuffer operation */ if ((maxSize == 0) || (maxSize < 15480)) { request.BufferSize = 0xBABE; size += sizeof(uint16_t); request.MaximumBufferSize.MaximumBufferSize = 0x8000; size += sizeof(uint16_t); } else { request.BufferSize = maxSize; size += sizeof(uint16_t); } /* Fill the MAPI_REQ structure */ mapi_req = talloc_zero(mem_ctx, struct EcDoRpc_MAPI_REQ); mapi_req->opnum = op_MAPI_FastTransferSourceGetBuffer; mapi_req->logon_id = logon_id; mapi_req->handle_idx = 0; mapi_req->u.mapi_FastTransferSourceGetBuffer = request; size += 5; /* Fill the mapi_request structure */ mapi_request = talloc_zero(mem_ctx, struct mapi_request); mapi_request->mapi_len = size + sizeof (uint32_t); mapi_request->length = (uint16_t)size; mapi_request->mapi_req = mapi_req; mapi_request->handles = talloc_array(mem_ctx, uint32_t, 1); mapi_request->handles[0] = mapi_object_get_handle(obj_source_context); // TODO: handle backoff (0x00000480) status = emsmdb_transaction_wrapper(session, mem_ctx, mapi_request, &mapi_response); OPENCHANGE_RETVAL_IF(!NT_STATUS_IS_OK(status), MAPI_E_CALL_FAILED, mem_ctx); OPENCHANGE_RETVAL_IF(!mapi_response->mapi_repl, MAPI_E_CALL_FAILED, mem_ctx); retval = mapi_response->mapi_repl->error_code; OPENCHANGE_RETVAL_IF(retval, retval, mem_ctx); /* Retrieve the result */ reply = &(mapi_response->mapi_repl->u.mapi_FastTransferSourceGetBuffer); *transferStatus = reply->TransferStatus; *progressStepCount = reply->InProgressCount; *totalStepCount = reply->TotalStepCount; blob->length = reply->TransferBufferSize; blob->data = (uint8_t *)talloc_size((TALLOC_CTX *)session, blob->length); memcpy(blob->data, reply->TransferBuffer.data, blob->length); talloc_free(mapi_response); talloc_free(mem_ctx); return MAPI_E_SUCCESS; } /** Send data to a destination fast transfer object Fast transfers are done in blocks, each block transfered over a call to FXGetBuffer. If the block is small, it will fit into a single call, and the transferStatus will indicate completion. However larger transfers will require multiple calls. \param obj_dest_context the destination object (from FXDestConfigure) \param blob this part of the transfer \param usedSize how many bytes of this part of the transfer that were used (only less than the total if an error occurred) \return MAPI_E_SUCCESS on success, otherwise MAPI error. \note Developers may also call GetLastError() to retrieve the last MAPI error code. Possible MAPI error codes are: - MAPI_E_NOT_INITIALIZED: MAPI subsystem has not been initialized - MAPI_E_INVALID_PARAMETER: one of the function parameters is invalid - MAPI_E_CALL_FAILED: A network problem was encountered during the transaction */ _PUBLIC_ enum MAPISTATUS FXPutBuffer(mapi_object_t *obj_dest_context, DATA_BLOB *blob, uint16_t *usedSize) { struct mapi_request *mapi_request; struct mapi_response *mapi_response; struct EcDoRpc_MAPI_REQ *mapi_req; struct FastTransferDestinationPutBuffer_req request; struct FastTransferDestinationPutBuffer_repl *reply; struct mapi_session *session; NTSTATUS status; enum MAPISTATUS retval; uint32_t size = 0; TALLOC_CTX *mem_ctx; uint8_t logon_id = 0; /* Sanity checks */ OPENCHANGE_RETVAL_IF(!obj_dest_context, MAPI_E_INVALID_PARAMETER, NULL); OPENCHANGE_RETVAL_IF(!blob, MAPI_E_INVALID_PARAMETER, NULL); OPENCHANGE_RETVAL_IF(!usedSize, MAPI_E_INVALID_PARAMETER, NULL); session = mapi_object_get_session(obj_dest_context); OPENCHANGE_RETVAL_IF(!session, MAPI_E_INVALID_PARAMETER, NULL); if ((retval = mapi_object_get_logon_id(obj_dest_context, &logon_id)) != MAPI_E_SUCCESS) return retval; mem_ctx = talloc_named(session, 0, "FXPutBuffer"); size = 0; /* Fill the PutBuffer operation */ request.TransferBufferSize = blob->length; size += sizeof(uint16_t); request.TransferBuffer = *blob; size += blob->length; /* Fill the MAPI_REQ structure */ mapi_req = talloc_zero(mem_ctx, struct EcDoRpc_MAPI_REQ); mapi_req->opnum = op_MAPI_FastTransferDestPutBuffer; mapi_req->logon_id = logon_id; mapi_req->handle_idx = 0; mapi_req->u.mapi_FastTransferDestinationPutBuffer = request; size += 5; /* Fill the mapi_request structure */ mapi_request = talloc_zero(mem_ctx, struct mapi_request); mapi_request->mapi_len = size + sizeof (uint32_t); mapi_request->length = (uint16_t)size; mapi_request->mapi_req = mapi_req; mapi_request->handles = talloc_array(mem_ctx, uint32_t, 1); mapi_request->handles[0] = mapi_object_get_handle(obj_dest_context); // TODO: handle backoff (0x00000480) status = emsmdb_transaction_wrapper(session, mem_ctx, mapi_request, &mapi_response); OPENCHANGE_RETVAL_IF(!NT_STATUS_IS_OK(status), MAPI_E_CALL_FAILED, mem_ctx); OPENCHANGE_RETVAL_IF(!mapi_response->mapi_repl, MAPI_E_CALL_FAILED, mem_ctx); retval = mapi_response->mapi_repl->error_code; OPENCHANGE_RETVAL_IF(retval, retval, mem_ctx); /* Retrieve the result */ reply = &(mapi_response->mapi_repl->u.mapi_FastTransferDestinationPutBuffer); *usedSize = reply->BufferUsedCount; /* we could pull more stuff here, but it doesn't seem useful */ talloc_free(mapi_response); talloc_free(mem_ctx); return MAPI_E_SUCCESS; } /** \details Prepare a server for ICS download This function is used to configure a server for ICS (Incremental Change Synchronization) download. You use the synchronization context handle for other ICS and Fast Transfer operations. \param obj the target object for the upload (folder) \param sync_type the type of synchronization that will be performed (just folder contents, or whole folder hierachy) \param send_options flags that change the format of the transfer (see FXCopyMessages) \param sync_flags flags that change the behavior of the transfer (see below) \param sync_extraflags additional flags that change the behavior of the transfer (see below) \param restriction a Restriction structure to limit downloads (only for sync_type == SynchronizationType_Content) \param property_tags the properties to exclude (or include, if SynchronizationFlag_OnlySpecifiedProperties flag is set) in the download \param obj_sync_context the resulting synchronization context handle \a sync_flags can be zero or more of the following: - SynchronizationFlag_Unicode to use Unicode format (must match in send_options) - SynchronizationFlag_NoDeletions - whether to download changes about message deletion - SynchronizationFlag_IgnoreNoLongerInScope - whether to download changes for messages that have gone out of scope. - SynchronizationFlag_ReadState - server to download changes to read state - SynchronizationFlag_FAI server to download changes to FAI messages - SynchronizationFlag_Normal - server to download changes to normal messages - SynchronizationFlag_OnlySpecifiedProperties - set means to include only properties that are listed in property_tags, not-set means to exclude properties that are listed in property_tags - SynchronizationFlag_NoForeignIdentifiers - ignore persisted values (usually want this set) - SynchronizationFlag_BestBody - format for outputting message bodies (set means original format, not-set means output in RTF) - SynchronizationFlag_IgnoreSpecifiedOnFAI - ignore property_tags restrictions for FAI messages - SynchronizationFlag_Progress - whether to output progress information. \note SynchronizationFlag_IgnoreNoLongerInScope, SynchronizationFlag_ReadState, SynchronizationFlag_FAI, SynchronizationFlag_Normal, SynchronizationFlag_OnlySpecifiedProperties, SynchronizationFlag_BestBody and SynchronizationFlag_IgnoreSpecifiedOnFAI are only valid if the synchronization type is SynchronizationType_Content. \a sync_extraflags can be zero or more of the following: - SynchronizationExtraFlag_Eid - whether the server includes the PR_FID / PR_MID in the download - SynchronizationExtraFlag_MessageSize - whether the server includes the PR_MESSAGE_SIZE property in the download (only for sync_type == SynchronizationType_Content) - SynchronizationExtraFlag_Cn - whether the server includes the PR_CHANGE_NUM property in the download. - SynchronizationExtraFlag_OrderByDeliveryTime - whether the server sends messages sorted by delivery time (only for sync_type == SynchronizationType_Content) \return MAPI_E_SUCCESS on success, otherwise MAPI error. \note Developers may also call GetLastError() to retrieve the last MAPI error code. Possible MAPI error codes are: - MAPI_E_NOT_INITIALIZED: MAPI subsystem has not been initialized - MAPI_E_INVALID_PARAMETER: one of the function parameters is invalid - MAPI_E_CALL_FAILED: A network problem was encountered during the transaction */ _PUBLIC_ enum MAPISTATUS ICSSyncConfigure(mapi_object_t *obj, enum SynchronizationType sync_type, uint8_t send_options, uint16_t sync_flags, uint32_t sync_extraflags, DATA_BLOB restriction, struct SPropTagArray *property_tags, mapi_object_t *obj_sync_context) { struct mapi_request *mapi_request; struct mapi_response *mapi_response; struct EcDoRpc_MAPI_REQ *mapi_req; struct SyncConfigure_req request; struct mapi_session *session; NTSTATUS status; enum MAPISTATUS retval; uint32_t size = 0; TALLOC_CTX *mem_ctx; uint8_t logon_id = 0; /* Sanity checks */ OPENCHANGE_RETVAL_IF(!obj, MAPI_E_INVALID_PARAMETER, NULL); session = mapi_object_get_session(obj); OPENCHANGE_RETVAL_IF(!session, MAPI_E_INVALID_PARAMETER, NULL); OPENCHANGE_RETVAL_IF(!obj_sync_context, MAPI_E_INVALID_PARAMETER, NULL); if ((retval = mapi_object_get_logon_id(obj, &logon_id)) != MAPI_E_SUCCESS) return retval; mem_ctx = talloc_named(session, 0, "RopSynchronizationConfigure"); size = 0; /* Fill the SyncConfigure operation */ request.handle_idx = 0x01; size += sizeof(uint8_t); request.SynchronizationType = sync_type; size += sizeof(uint8_t); request.SendOptions = send_options; size += sizeof(uint8_t); request.SynchronizationFlag = sync_flags; size += sizeof(uint16_t); request.RestrictionSize = restriction.length; size += sizeof(uint16_t); request.RestrictionData = restriction; size += request.RestrictionSize; /* for the RestrictionData BLOB */ request.SynchronizationExtraFlags = sync_extraflags; size += sizeof(uint32_t); request.PropertyTags.cValues = property_tags->cValues; size += sizeof(uint16_t); request.PropertyTags.aulPropTag = property_tags->aulPropTag; size += property_tags->cValues * sizeof(enum MAPITAGS); /* Fill the MAPI_REQ structure */ mapi_req = talloc_zero(mem_ctx, struct EcDoRpc_MAPI_REQ); mapi_req->opnum = op_MAPI_SyncConfigure; mapi_req->logon_id = logon_id; mapi_req->handle_idx = 0; mapi_req->u.mapi_SyncConfigure = request; size += 5; /* Fill the mapi_request structure */ mapi_request = talloc_zero(mem_ctx, struct mapi_request); mapi_request->mapi_len = size + sizeof (uint32_t) * 2; mapi_request->length = (uint16_t)size; mapi_request->mapi_req = mapi_req; mapi_request->handles = talloc_array(mem_ctx, uint32_t, 2); mapi_request->handles[0] = mapi_object_get_handle(obj); mapi_request->handles[1] = 0xFFFFFFFF; status = emsmdb_transaction_wrapper(session, mem_ctx, mapi_request, &mapi_response); OPENCHANGE_RETVAL_IF(!NT_STATUS_IS_OK(status), MAPI_E_CALL_FAILED, mem_ctx); OPENCHANGE_RETVAL_IF(!mapi_response->mapi_repl, MAPI_E_CALL_FAILED, mem_ctx); retval = mapi_response->mapi_repl->error_code; OPENCHANGE_RETVAL_IF(retval, retval, mem_ctx); /* Set object session and handle */ mapi_object_set_session(obj_sync_context, session); mapi_object_set_handle(obj_sync_context, mapi_response->handles[1]); mapi_object_set_logon_id(obj_sync_context, logon_id); talloc_free(mapi_response); talloc_free(mem_ctx); return MAPI_E_SUCCESS; } /** Initialize an ICS Initial State upload This is one of three operations (along with ICSSyncUploadStateContinue and ICSSyncUploadStateEnd) used to send the initial state for an ICS download to the server. \param obj_sync_context the synchronization context (from ICSSyncConfigure) \param state_property the type of ICS state that will be uploaded (see below) \param length the length (in bytes) of the ICS state that will be uploaded state_property can be one of the following: - PidTagIdsetGiven - PidTagCnsetSeen - PidTagCnsetSeenFAI - PidTagCnsetRead \return MAPI_E_SUCCESS on success, otherwise MAPI error. \note Developers may also call GetLastError() to retrieve the last MAPI error code. Possible MAPI error codes are: - MAPI_E_NOT_INITIALIZED: MAPI subsystem has not been initialized - MAPI_E_INVALID_PARAMETER: one of the function parameters is invalid - MAPI_E_CALL_FAILED: A network problem was encountered during the transaction */ _PUBLIC_ enum MAPISTATUS ICSSyncUploadStateBegin(mapi_object_t *obj_sync_context, enum StateProperty state_property, uint32_t length) { struct mapi_request *mapi_request; struct mapi_response *mapi_response; struct EcDoRpc_MAPI_REQ *mapi_req; struct SyncUploadStateStreamBegin_req request; struct mapi_session *session; NTSTATUS status; enum MAPISTATUS retval; uint32_t size = 0; TALLOC_CTX *mem_ctx; uint8_t logon_id = 0; /* Sanity checks */ OPENCHANGE_RETVAL_IF(!obj_sync_context, MAPI_E_INVALID_PARAMETER, NULL); session = mapi_object_get_session(obj_sync_context); OPENCHANGE_RETVAL_IF(!session, MAPI_E_INVALID_PARAMETER, NULL); if ((retval = mapi_object_get_logon_id(obj_sync_context, &logon_id)) != MAPI_E_SUCCESS) return retval; mem_ctx = talloc_named(session, 0, "ICSSyncUploadStateBegin"); size = 0; /* Fill the RopSynchronizationUploadStateBegin operation */ request.StateProperty = state_property; size += sizeof(uint32_t); request.TransferBufferSize = length; size += sizeof(uint32_t); /* Fill the MAPI_REQ structure */ mapi_req = talloc_zero(mem_ctx, struct EcDoRpc_MAPI_REQ); mapi_req->opnum = op_MAPI_SyncUploadStateStreamBegin; mapi_req->logon_id = logon_id; mapi_req->handle_idx = 0; mapi_req->u.mapi_SyncUploadStateStreamBegin = request; size += 5; /* Fill the mapi_request structure */ mapi_request = talloc_zero(mem_ctx, struct mapi_request); mapi_request->mapi_len = size + sizeof (uint32_t); mapi_request->length = (uint16_t)size; mapi_request->mapi_req = mapi_req; mapi_request->handles = talloc_array(mem_ctx, uint32_t, 1); mapi_request->handles[0] = mapi_object_get_handle(obj_sync_context); status = emsmdb_transaction_wrapper(session, mem_ctx, mapi_request, &mapi_response); OPENCHANGE_RETVAL_IF(!NT_STATUS_IS_OK(status), MAPI_E_CALL_FAILED, mem_ctx); OPENCHANGE_RETVAL_IF(!mapi_response->mapi_repl, MAPI_E_CALL_FAILED, mem_ctx); retval = mapi_response->mapi_repl->error_code; OPENCHANGE_RETVAL_IF(retval, retval, mem_ctx); talloc_free(mapi_response); talloc_free(mem_ctx); return MAPI_E_SUCCESS; } /** Send data for an ICS Initial State upload This is one of three operations (along with ICSSyncUploadStateBegin and ICSSyncUploadStateEnd) used to send the initial state for an ICS download to the server. \param obj_sync_context the synchronization context (from ICSSyncConfigure) \param state the state data for this part of the upload \return MAPI_E_SUCCESS on success, otherwise MAPI error. \note Developers may also call GetLastError() to retrieve the last MAPI error code. Possible MAPI error codes are: - MAPI_E_NOT_INITIALIZED: MAPI subsystem has not been initialized - MAPI_E_INVALID_PARAMETER: one of the function parameters is invalid - MAPI_E_CALL_FAILED: A network problem was encountered during the transaction */ _PUBLIC_ enum MAPISTATUS ICSSyncUploadStateContinue(mapi_object_t *obj_sync_context, DATA_BLOB state) { struct mapi_request *mapi_request; struct mapi_response *mapi_response; struct EcDoRpc_MAPI_REQ *mapi_req; struct SyncUploadStateStreamContinue_req request; struct mapi_session *session; NTSTATUS status; enum MAPISTATUS retval; uint32_t size = 0; TALLOC_CTX *mem_ctx; uint8_t logon_id = 0; /* Sanity checks */ OPENCHANGE_RETVAL_IF(!obj_sync_context, MAPI_E_INVALID_PARAMETER, NULL); session = mapi_object_get_session(obj_sync_context); OPENCHANGE_RETVAL_IF(!session, MAPI_E_INVALID_PARAMETER, NULL); if ((retval = mapi_object_get_logon_id(obj_sync_context, &logon_id)) != MAPI_E_SUCCESS) return retval; mem_ctx = talloc_named(session, 0, "ICSSyncUploadStateContinue"); size = 0; /* Fill the RopSynchronizationUploadStateBegin operation */ request.StreamDataSize = state.length; size += sizeof(uint32_t); request.StreamData = state.data; size += state.length; /* Fill the MAPI_REQ structure */ mapi_req = talloc_zero(mem_ctx, struct EcDoRpc_MAPI_REQ); mapi_req->opnum = op_MAPI_SyncUploadStateStreamContinue; mapi_req->logon_id = logon_id; mapi_req->handle_idx = 0; mapi_req->u.mapi_SyncUploadStateStreamContinue = request; size += 5; /* Fill the mapi_request structure */ mapi_request = talloc_zero(mem_ctx, struct mapi_request); mapi_request->mapi_len = size + sizeof (uint32_t); mapi_request->length = (uint16_t)size; mapi_request->mapi_req = mapi_req; mapi_request->handles = talloc_array(mem_ctx, uint32_t, 1); mapi_request->handles[0] = mapi_object_get_handle(obj_sync_context); status = emsmdb_transaction_wrapper(session, mem_ctx, mapi_request, &mapi_response); OPENCHANGE_RETVAL_IF(!NT_STATUS_IS_OK(status), MAPI_E_CALL_FAILED, mem_ctx); OPENCHANGE_RETVAL_IF(!mapi_response->mapi_repl, MAPI_E_CALL_FAILED, mem_ctx); retval = mapi_response->mapi_repl->error_code; OPENCHANGE_RETVAL_IF(retval, retval, mem_ctx); talloc_free(mapi_response); talloc_free(mem_ctx); return MAPI_E_SUCCESS; } /** Signal completion of an ICS Initial State upload This is one of three operations (along with ICSSyncUploadStateBegin and ICSSyncUploadStateContinue) used to send the initial state for an ICS download to the server. \param obj_sync_context the synchronization context (from ICSSyncConfigure) \return MAPI_E_SUCCESS on success, otherwise MAPI error. \note Developers may also call GetLastError() to retrieve the last MAPI error code. Possible MAPI error codes are: - MAPI_E_NOT_INITIALIZED: MAPI subsystem has not been initialized - MAPI_E_INVALID_PARAMETER: one of the function parameters is invalid - MAPI_E_CALL_FAILED: A network problem was encountered during the transaction */ _PUBLIC_ enum MAPISTATUS ICSSyncUploadStateEnd(mapi_object_t *obj_sync_context) { struct mapi_request *mapi_request; struct mapi_response *mapi_response; struct EcDoRpc_MAPI_REQ *mapi_req; struct mapi_session *session; NTSTATUS status; enum MAPISTATUS retval; uint32_t size = 0; TALLOC_CTX *mem_ctx; uint8_t logon_id = 0; /* Sanity checks */ OPENCHANGE_RETVAL_IF(!obj_sync_context, MAPI_E_INVALID_PARAMETER, NULL); session = mapi_object_get_session(obj_sync_context); OPENCHANGE_RETVAL_IF(!session, MAPI_E_INVALID_PARAMETER, NULL); if ((retval = mapi_object_get_logon_id(obj_sync_context, &logon_id)) != MAPI_E_SUCCESS) return retval; mem_ctx = talloc_named(session, 0, "ICSSyncUploadStateEnd"); size = 0; /* Fill the MAPI_REQ structure */ mapi_req = talloc_zero(mem_ctx, struct EcDoRpc_MAPI_REQ); mapi_req->opnum = op_MAPI_SyncUploadStateStreamEnd; mapi_req->logon_id = logon_id; mapi_req->handle_idx = 0; size += 5; /* Fill the mapi_request structure */ mapi_request = talloc_zero(mem_ctx, struct mapi_request); mapi_request->mapi_len = size + sizeof (uint32_t); mapi_request->length = (uint16_t)size; mapi_request->mapi_req = mapi_req; mapi_request->handles = talloc_array(mem_ctx, uint32_t, 1); mapi_request->handles[0] = mapi_object_get_handle(obj_sync_context); status = emsmdb_transaction_wrapper(session, mem_ctx, mapi_request, &mapi_response); OPENCHANGE_RETVAL_IF(!NT_STATUS_IS_OK(status), MAPI_E_CALL_FAILED, mem_ctx); OPENCHANGE_RETVAL_IF(!mapi_response->mapi_repl, MAPI_E_CALL_FAILED, mem_ctx); retval = mapi_response->mapi_repl->error_code; OPENCHANGE_RETVAL_IF(retval, retval, mem_ctx); talloc_free(mapi_response); talloc_free(mem_ctx); return MAPI_E_SUCCESS; } /** \details Mark a range of Message Ids as deleted / unused This function allows the client to specify that a specific range of message identifiers will never be used on a particular folder. This allows the server to make optimisations for message identifier sets during incremental change synchronisation operations. \param obj_folder pointer to the folder MAPI object \param ReplGuid the GUID for the MIDSET \param GlobalCountLow lower end of the range to be marked as deleted \param GlobalCountHigh upper end of the range to be marked as deleted \return MAPI_E_SUCCESS on success, otherwise MAPI error. \note Developers may also call GetLastError() to retrieve the last MAPI error code. Possible MAPI error codes are: - MAPI_E_NOT_INITIALIZED: MAPI subsystem has not been initialized - MAPI_E_INVALID_PARAMETER: one of the function parameters is invalid - MAPI_E_CALL_FAILED: A network problem was encountered during the transaction */ _PUBLIC_ enum MAPISTATUS SetLocalReplicaMidsetDeleted(mapi_object_t *obj_folder, const struct GUID ReplGuid, const uint8_t GlobalCountLow[6], const uint8_t GlobalCountHigh[6]) { struct mapi_request *mapi_request; struct mapi_response *mapi_response; struct EcDoRpc_MAPI_REQ *mapi_req; struct SetLocalReplicaMidsetDeleted_req request; struct mapi_session *session; NTSTATUS status; enum MAPISTATUS retval; uint32_t size = 0; TALLOC_CTX *mem_ctx; uint8_t logon_id = 0; uint32_t i = 0; /* Sanity checks */ OPENCHANGE_RETVAL_IF(!obj_folder, MAPI_E_INVALID_PARAMETER, NULL); session = mapi_object_get_session(obj_folder); OPENCHANGE_RETVAL_IF(!session, MAPI_E_INVALID_PARAMETER, NULL); if ((retval = mapi_object_get_logon_id(obj_folder, &logon_id)) != MAPI_E_SUCCESS) { return retval; } mem_ctx = talloc_named(session, 0, __FUNCTION__); size = 0; /* Fill the SetLocalReplicaMidsetDeleted operation */ request.DataSize = 0; size += sizeof(uint16_t); request.LongTermIdRangeCount = 1; /* this version only handles a single range */ request.DataSize += sizeof(uint32_t); /* the size of the LongTermIdRangeCount */ request.LongTermIdRanges = talloc_array(mem_ctx, struct LongTermIdRange, request.LongTermIdRangeCount); for (i = 0; i < request.LongTermIdRangeCount; ++i) { request.LongTermIdRanges[i].MinLongTermId.DatabaseGuid = ReplGuid; request.DataSize += sizeof(struct GUID); memcpy(request.LongTermIdRanges[i].MinLongTermId.GlobalCounter, GlobalCountLow, 6); request.DataSize += 6; request.LongTermIdRanges[i].MinLongTermId.padding = 0x0000; request.DataSize += sizeof(uint16_t); request.LongTermIdRanges[i].MaxLongTermId.DatabaseGuid = ReplGuid; request.DataSize += sizeof(struct GUID); memcpy(request.LongTermIdRanges[i].MaxLongTermId.GlobalCounter, GlobalCountHigh, 6); request.DataSize += 6; request.LongTermIdRanges[i].MaxLongTermId.padding = 0x0000; request.DataSize += sizeof(uint16_t); } size += request.DataSize; /* add that datasize to the overall length */ /* Fill the MAPI_REQ structure */ mapi_req = talloc_zero(mem_ctx, struct EcDoRpc_MAPI_REQ); mapi_req->opnum = op_MAPI_SetLocalReplicaMidsetDeleted; mapi_req->logon_id = logon_id; mapi_req->handle_idx = 0; mapi_req->u.mapi_SetLocalReplicaMidsetDeleted = request; size += 5; /* Fill the mapi_request structure */ mapi_request = talloc_zero(mem_ctx, struct mapi_request); mapi_request->mapi_len = size + sizeof (uint32_t); mapi_request->length = (uint16_t)size; mapi_request->mapi_req = mapi_req; mapi_request->handles = talloc_array(mem_ctx, uint32_t, 1); mapi_request->handles[0] = mapi_object_get_handle(obj_folder); status = emsmdb_transaction_wrapper(session, mem_ctx, mapi_request, &mapi_response); OPENCHANGE_RETVAL_IF(!NT_STATUS_IS_OK(status), MAPI_E_CALL_FAILED, mem_ctx); OPENCHANGE_RETVAL_IF(!mapi_response->mapi_repl, MAPI_E_CALL_FAILED, mem_ctx); retval = mapi_response->mapi_repl->error_code; OPENCHANGE_RETVAL_IF(retval, retval, mem_ctx); OPENCHANGE_CHECK_NOTIFICATION(session, mapi_response); talloc_free(mapi_response); talloc_free(mem_ctx); return MAPI_E_SUCCESS; } /** \details Prepare a folder for ICS upload \param folder the folder for the collector creation \param isContentsCollector true for contents collector, false for hierachy collector \param obj_collector pointer to the resulting ICS collector \return MAPI_E_SUCCESS on success, otherwise MAPI error. \note Developers may also call GetLastError() to retrieve the last MAPI error code. Possible MAPI error codes are: - MAPI_E_NOT_INITIALIZED: MAPI subsystem has not been initialized - MAPI_E_INVALID_PARAMETER: one of the function parameters is invalid - MAPI_E_CALL_FAILED: A network problem was encountered during the transaction */ _PUBLIC_ enum MAPISTATUS ICSSyncOpenCollector(mapi_object_t *folder, bool isContentsCollector, mapi_object_t *obj_collector) { struct mapi_request *mapi_request; struct mapi_response *mapi_response; struct EcDoRpc_MAPI_REQ *mapi_req; struct SyncOpenCollector_req request; struct mapi_session *session; NTSTATUS status; enum MAPISTATUS retval; uint32_t size = 0; TALLOC_CTX *mem_ctx; uint8_t logon_id = 0; /* Sanity checks */ OPENCHANGE_RETVAL_IF(!folder, MAPI_E_INVALID_PARAMETER, NULL); session = mapi_object_get_session(folder); OPENCHANGE_RETVAL_IF(!session, MAPI_E_INVALID_PARAMETER, NULL); OPENCHANGE_RETVAL_IF(!obj_collector, MAPI_E_INVALID_PARAMETER, NULL); if ((retval = mapi_object_get_logon_id(folder, &logon_id)) != MAPI_E_SUCCESS) return retval; mem_ctx = talloc_named(session, 0, __FUNCTION__); size = 0; /* Fill the SyncOpenCollector operation */ request.handle_idx = 0x01; size += sizeof(uint8_t); if (isContentsCollector) { request.IsContentsCollector = 0x01; } else { request.IsContentsCollector = 0x00; } size += sizeof(uint8_t); /* Fill the MAPI_REQ structure */ mapi_req = talloc_zero(mem_ctx, struct EcDoRpc_MAPI_REQ); mapi_req->opnum = op_MAPI_SyncOpenCollector; mapi_req->logon_id = logon_id; mapi_req->handle_idx = 0; mapi_req->u.mapi_SyncOpenCollector = request; size += 5; /* Fill the mapi_request structure */ mapi_request = talloc_zero(mem_ctx, struct mapi_request); mapi_request->mapi_len = size + sizeof (uint32_t) * 2; mapi_request->length = (uint16_t)size; mapi_request->mapi_req = mapi_req; mapi_request->handles = talloc_array(mem_ctx, uint32_t, 2); mapi_request->handles[0] = mapi_object_get_handle(folder); mapi_request->handles[1] = 0xFFFFFFFF; status = emsmdb_transaction_wrapper(session, mem_ctx, mapi_request, &mapi_response); OPENCHANGE_RETVAL_IF(!NT_STATUS_IS_OK(status), MAPI_E_CALL_FAILED, mem_ctx); OPENCHANGE_RETVAL_IF(!mapi_response->mapi_repl, MAPI_E_CALL_FAILED, mem_ctx); retval = mapi_response->mapi_repl->error_code; OPENCHANGE_RETVAL_IF(retval, retval, mem_ctx); /* Set object session and handle */ mapi_object_set_session(obj_collector, session); mapi_object_set_handle(obj_collector, mapi_response->handles[1]); mapi_object_set_logon_id(obj_collector, logon_id); talloc_free(mapi_response); talloc_free(mem_ctx); return MAPI_E_SUCCESS; } /** \details obtain an object to get the sync transfer state \param obj the source object \param obj_sync_context the synchronization transfer state object \return MAPI_E_SUCCESS on success, otherwise MAPI error. \note Developers may also call GetLastError() to retrieve the last MAPI error code. Possible MAPI error codes are: - MAPI_E_NOT_INITIALIZED: MAPI subsystem has not been initialized - MAPI_E_INVALID_PARAMETER: one of the function parameters is invalid - MAPI_E_CALL_FAILED: A network problem was encountered during the transaction */ _PUBLIC_ enum MAPISTATUS ICSSyncGetTransferState(mapi_object_t *obj, mapi_object_t *obj_sync_context) { struct mapi_request *mapi_request; struct mapi_response *mapi_response; struct EcDoRpc_MAPI_REQ *mapi_req; struct SyncGetTransferState_req request; struct mapi_session *session; NTSTATUS status; enum MAPISTATUS retval; uint32_t size = 0; TALLOC_CTX *mem_ctx; uint8_t logon_id = 0; /* Sanity checks */ OPENCHANGE_RETVAL_IF(!obj, MAPI_E_INVALID_PARAMETER, NULL); session = mapi_object_get_session(obj); OPENCHANGE_RETVAL_IF(!session, MAPI_E_INVALID_PARAMETER, NULL); OPENCHANGE_RETVAL_IF(!obj_sync_context, MAPI_E_INVALID_PARAMETER, NULL); if ((retval = mapi_object_get_logon_id(obj, &logon_id)) != MAPI_E_SUCCESS) { return retval; } mem_ctx = talloc_named(session, 0, __FUNCTION__); /* Fill the SyncGetTransferState operation */ request.handle_idx = 0x01; size += sizeof(uint8_t); /* Fill the MAPI_REQ structure */ mapi_req = talloc_zero(mem_ctx, struct EcDoRpc_MAPI_REQ); mapi_req->opnum = op_MAPI_SyncGetTransferState; mapi_req->logon_id = logon_id; mapi_req->handle_idx = 0; mapi_req->u.mapi_SyncGetTransferState = request; size += 5; /* Fill the mapi_request structure */ mapi_request = talloc_zero(mem_ctx, struct mapi_request); mapi_request->mapi_len = size + sizeof (uint32_t) * 2; mapi_request->length = (uint16_t)size; mapi_request->mapi_req = mapi_req; mapi_request->handles = talloc_array(mem_ctx, uint32_t, 2); mapi_request->handles[0] = mapi_object_get_handle(obj); mapi_request->handles[1] = 0xFFFFFFFF; status = emsmdb_transaction_wrapper(session, mem_ctx, mapi_request, &mapi_response); OPENCHANGE_RETVAL_IF(!NT_STATUS_IS_OK(status), MAPI_E_CALL_FAILED, mem_ctx); OPENCHANGE_RETVAL_IF(!mapi_response->mapi_repl, MAPI_E_CALL_FAILED, mem_ctx); retval = mapi_response->mapi_repl->error_code; OPENCHANGE_RETVAL_IF(retval, retval, mem_ctx); /* Set object session and handle */ mapi_object_set_session(obj_sync_context, session); mapi_object_set_handle(obj_sync_context, mapi_response->handles[1]); mapi_object_set_logon_id(obj_sync_context, logon_id); talloc_free(mapi_response); talloc_free(mem_ctx); return MAPI_E_SUCCESS; } openchange-2.0/libmapi/IABContainer.c000066400000000000000000000313301223057412600175030ustar00rootroot00000000000000/* OpenChange MAPI implementation. Copyright (C) Julien Kerihuel 2007-2008. This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see . */ #include "libmapi/libmapi.h" #include "libmapi/libmapi_private.h" /** \file IABContainer.c \brief Provides access to address book containers -- Used to perform name resolution */ /** \details Resolve user names against the Windows Address Book Provider \param session pointer to the MAPI session context \param usernames list of user names to resolve \param rowset resulting list of user details \param props resulting list of resolved names \param flaglist resulting list of resolution status (see below) \param flags if set to MAPI_UNICODE then UNICODE MAPITAGS can be used, otherwise only UTF8 encoded fields may be returned. Possible flaglist values are: -# MAPI_UNRESOLVED: could not be resolved -# MAPI_AMBIGUOUS: resolution match more than one entry -# MAPI_RESOLVED: resolution matched a single entry \return MAPI_E_SUCCESS on success, otherwise MAPI error. \note Developers may also call GetLastError() to retrieve the last MAPI error code. Possible MAPI error codes are: -# MAPI_E_NOT_INITIALIZED: MAPI subsystem has not been initialized -# MAPI_E_SESSION_LIMIT: No session has been opened on the provider -# MAPI_E_NOT_ENOUGH_RESOURCES: MAPI subsystem failed to allocate the necessary resources to operate properly -# MAPI_E_NOT_FOUND: No suitable profile database was found in the path pointed by profiledb -# MAPI_E_CALL_FAILED: A network problem was encountered during the transaction It is the developer responsibility to call MAPIFreeBuffer on rowset and flaglist once they have finished to use them. \sa MAPILogonProvider, GetLastError */ _PUBLIC_ enum MAPISTATUS ResolveNames(struct mapi_session *session, const char **usernames, struct SPropTagArray *props, struct PropertyRowSet_r **rowset, struct PropertyTagArray_r **flaglist, uint32_t flags) { TALLOC_CTX *mem_ctx; struct nspi_context *nspi; enum MAPISTATUS retval; /* Sanity Checks */ OPENCHANGE_RETVAL_IF(!session, MAPI_E_SESSION_LIMIT, NULL); OPENCHANGE_RETVAL_IF(!session->nspi, MAPI_E_SESSION_LIMIT, NULL); OPENCHANGE_RETVAL_IF(!session->nspi->ctx, MAPI_E_SESSION_LIMIT, NULL); OPENCHANGE_RETVAL_IF(!rowset, MAPI_E_INVALID_PARAMETER, NULL); nspi = (struct nspi_context *)session->nspi->ctx; mem_ctx = talloc_named(session, 0, "ResolveNames"); switch (flags) { case MAPI_UNICODE: retval = nspi_ResolveNamesW(nspi, mem_ctx, usernames, props, &rowset, &flaglist); break; default: retval = nspi_ResolveNames(nspi, mem_ctx, usernames, props, &rowset, &flaglist); break; } *rowset = talloc_steal(nspi->mem_ctx, *rowset); *flaglist = talloc_steal(nspi->mem_ctx, *flaglist); talloc_free(mem_ctx); if (retval != MAPI_E_SUCCESS) return retval; return MAPI_E_SUCCESS; } /** \details Retrieve the global address list The Global Address List is the full list of email addresses (and other account-type things, such as "rooms" and distribution lists) accessible on the server. A user will usually have access to both a personal address book, and to the Global Address List. Public Address Book is another name for Global Address List. You access the Global Address List by setting the list of things that you want to retrieve from the Global Address List as property names in the SPropTagArray argument, and then calling this function. The results are returned in SRowSet. You can get a convenient output of the results using mapidump_PAB_entry() for each row returned. \param session pointer to the MAPI session context \param SPropTagArray pointer to an array of MAPI properties we want to fetch \param SRowSet pointer to the rows of the table returned \param count the number of rows we want to fetch \param ulFlags specify the table cursor location Possible value for ulFlags: -# TABLE_START: Fetch rows from the beginning of the table -# TABLE_CUR: Fetch rows from current table location The Global Address List may be quite large (tens of thousands of entries in a large deployment), so you usually call this function with ulFlags set to TABLE_START the first time, and then subsequent calls will be made with TABLE_CUR to progress through the table. \return MAPI_E_SUCCESS on success, otherwise MAPI error. \note Developers may also call GetLastError() to retrieve the last MAPI error code. Possible MAPI error codes are: -# MAPI_E_NOT_INITIALIZED: MAPI subsystem has not been initialized -# MAPI_E_SESSION_LIMIT: No session has been opened on the provider -# MAPI_E_INVALID_PARAMETER: if a function parameter is invalid -# MAPI_E_CALL_FAILED: A network problem was encountered during the transaction \sa MapiLogonEx, MapiLogonProvider, mapidump_PAB_entry */ _PUBLIC_ enum MAPISTATUS GetGALTable(struct mapi_session *session, struct SPropTagArray *SPropTagArray, struct PropertyRowSet_r **rowsetp, uint32_t count, uint8_t ulFlags) { TALLOC_CTX *mem_ctx; struct nspi_context *nspi; struct PropertyRowSet_r *rowset; enum MAPISTATUS retval; /* Sanity checks */ OPENCHANGE_RETVAL_IF(!session, MAPI_E_SESSION_LIMIT, NULL); OPENCHANGE_RETVAL_IF(!session->nspi, MAPI_E_SESSION_LIMIT, NULL); OPENCHANGE_RETVAL_IF(!session->nspi->ctx, MAPI_E_SESSION_LIMIT, NULL); OPENCHANGE_RETVAL_IF(!rowsetp, MAPI_E_INVALID_PARAMETER, NULL); OPENCHANGE_RETVAL_IF(!SPropTagArray, MAPI_E_INVALID_PARAMETER, NULL); mem_ctx = talloc_named(session, 0, "GetGALTable"); nspi = (struct nspi_context *)session->nspi->ctx; if (ulFlags == TABLE_START) { nspi->pStat->CurrentRec = 0; nspi->pStat->Delta = 0; nspi->pStat->NumPos = 0; nspi->pStat->TotalRecs = 0xffffffff; } rowset = talloc_zero(mem_ctx, struct PropertyRowSet_r); retval = nspi_QueryRows(nspi, mem_ctx, SPropTagArray, NULL, count, &rowset); rowset = talloc_steal(session, rowset); *rowsetp = rowset; OPENCHANGE_RETVAL_IF(retval, retval, mem_ctx); talloc_free(mem_ctx); return MAPI_E_SUCCESS; } /** \details Retrieve the total number of records in the global address list The Global Address List is the full list of email addresses (and other account-type things, such as "rooms" and distribution lists) accessible on the server. A user will usually have access to both a personal address book, and to the Global Address List. Public Address Book is another name for Global Address List. \param session pointer to the MAPI session context \param totalRecs pointers to the total number of records in the global address list returned \return MAPI_E_SUCCESS on success, otherwise MAPI error. \note Developers may also call GetLastError() to retrieve the last MAPI error code. Possible MAPI error codes are: -# MAPI_E_NOT_INITIALIZED: MAPI subsystem has not been initialized -# MAPI_E_SESSION_LIMIT: No session has been opened on the provider -# MAPI_E_INVALID_PARAMETER: if a function parameter is invalid -# MAPI_E_CALL_FAILED: A network problem was encountered during the transaction */ _PUBLIC_ enum MAPISTATUS GetGALTableCount(struct mapi_session *session, uint32_t *totalRecs) { TALLOC_CTX *mem_ctx; struct nspi_context *nspi; enum MAPISTATUS retval; struct PropertyRowSet_r *rowset; /* Sanity Checks */ OPENCHANGE_RETVAL_IF(!session, MAPI_E_SESSION_LIMIT, NULL); OPENCHANGE_RETVAL_IF(!session->nspi, MAPI_E_SESSION_LIMIT, NULL); OPENCHANGE_RETVAL_IF(!session->nspi->ctx, MAPI_E_SESSION_LIMIT, NULL); mem_ctx = talloc_named(session, 0, "GetGALTableCount"); nspi = (struct nspi_context *) session->nspi->ctx; nspi->pStat->CurrentRec = 0; nspi->pStat->Delta = 0; nspi->pStat->NumPos = 0; nspi->pStat->TotalRecs = 0xffffffff; rowset = talloc_zero(mem_ctx, struct PropertyRowSet_r); retval = nspi_QueryRows(nspi, mem_ctx, NULL, NULL, 0, &rowset); *totalRecs = nspi->pStat->TotalRecs; OPENCHANGE_RETVAL_IF(retval, retval, mem_ctx); talloc_free(mem_ctx); return MAPI_E_SUCCESS; } /** \details Retrieve Address Book information for a given recipient \param session pointer to the MAPI session context \param username pointer to the username to retrieve information from \param pPropTags pointer to the property tags array to lookup \param ppRowSet pointer on pointer to the results Note that if pPropTags is NULL, then GetABNameInfo will fetch the following default property tags: -# PR_ADDRTYPE_UNICODE -# PR_EMAIL_ADDRESS_UNICODE -# PR_DISPLAY_NAME_UNICODE -# PR_OBJECT_TYPE \return MAPI_E_SUCCESS on success, otherwise MAPI error. \note Developers may also call GetLastError() to retrieve the last MAPI error code. Possible MAPI error codes are: -# MAPI_E_NOT_INITIALIZED if MAPI subsystem is not initialized -# MAPI_E_SESSION_LIMIT if the NSPI session is unavailable -# MAPI_E_INVALID_PARAMETER if a function parameter is invalid -# MAPI_E_NOT_FOUND if the username to lookup doesn't match any records \sa nspi_DNToMId, nspi_GetProps */ _PUBLIC_ enum MAPISTATUS GetABRecipientInfo(struct mapi_session *session, const char *username, struct SPropTagArray *pPropTags, struct PropertyRowSet_r **ppRowSet) { enum MAPISTATUS retval; TALLOC_CTX *mem_ctx; struct nspi_context *nspi_ctx; struct PropertyRowSet_r *RowSet; struct SPropTagArray *SPropTagArray = NULL; struct PropertyTagArray_r *pMId = NULL; struct PropertyTagArray_r *flaglist = NULL; struct StringsArray_r pNames; const char *usernames[2]; char *email = NULL; bool allocated = false; /* Sanity checks */ OPENCHANGE_RETVAL_IF(!session, MAPI_E_SESSION_LIMIT, NULL); OPENCHANGE_RETVAL_IF(!session->profile, MAPI_E_SESSION_LIMIT, NULL); OPENCHANGE_RETVAL_IF(!session->nspi, MAPI_E_SESSION_LIMIT, NULL); OPENCHANGE_RETVAL_IF(!session->nspi->ctx, MAPI_E_SESSION_LIMIT, NULL); OPENCHANGE_RETVAL_IF(!ppRowSet, MAPI_E_INVALID_PARAMETER, NULL); OPENCHANGE_RETVAL_IF(!username, MAPI_E_INVALID_PARAMETER, NULL); mem_ctx = talloc_named(session, 0, "GetABRecipientInfo"); nspi_ctx = (struct nspi_context *)session->nspi->ctx; /* Step 1. Resolve the username */ usernames[0] = username; usernames[1] = NULL; RowSet = talloc_zero(mem_ctx, struct PropertyRowSet_r); SPropTagArray = set_SPropTagArray(mem_ctx, 0xc, PR_ENTRYID, PR_DISPLAY_NAME_UNICODE, PR_ADDRTYPE_UNICODE, PR_OBJECT_TYPE, PR_DISPLAY_TYPE, PR_EMAIL_ADDRESS_UNICODE, PR_SEND_INTERNET_ENCODING, PR_SEND_RICH_INFO, PR_SEARCH_KEY, PR_TRANSMITTABLE_DISPLAY_NAME_UNICODE, PR_7BIT_DISPLAY_NAME_UNICODE, PR_SMTP_ADDRESS_UNICODE); retval = ResolveNames(session, usernames, SPropTagArray, &RowSet, &flaglist, MAPI_UNICODE); MAPIFreeBuffer(SPropTagArray); OPENCHANGE_RETVAL_IF(retval, retval, mem_ctx); OPENCHANGE_RETVAL_IF((flaglist->aulPropTag[0] != MAPI_RESOLVED), MAPI_E_NOT_FOUND, mem_ctx); email = talloc_strdup(mem_ctx, (const char *) get_PropertyValue_PropertyRowSet_data(RowSet, PR_EMAIL_ADDRESS_UNICODE)); MAPIFreeBuffer(RowSet); /* Step 2. Map recipient DN to MId */ pNames.Count = 0x1; pNames.Strings = (const char **) talloc_array(mem_ctx, char *, 1); pNames.Strings[0] = email; pMId = talloc_zero(mem_ctx, struct PropertyTagArray_r); retval = nspi_DNToMId(nspi_ctx, mem_ctx, &pNames, &pMId); MAPIFreeBuffer((char *)pNames.Strings[0]); MAPIFreeBuffer((char **)pNames.Strings); OPENCHANGE_RETVAL_IF(retval, retval, mem_ctx); /* Step 3. Get recipient's properties */ if (!pPropTags) { allocated = true; SPropTagArray = set_SPropTagArray(mem_ctx, 0x4, PR_ADDRTYPE_UNICODE, PR_EMAIL_ADDRESS_UNICODE, PR_DISPLAY_NAME_UNICODE, PR_OBJECT_TYPE); } else { SPropTagArray = pPropTags; } RowSet = talloc_zero(mem_ctx, struct PropertyRowSet_r); retval = nspi_GetProps(nspi_ctx, RowSet, SPropTagArray, pMId, &RowSet); if (allocated == true) { MAPIFreeBuffer(SPropTagArray); } MAPIFreeBuffer(pMId); OPENCHANGE_RETVAL_IF(retval, retval, mem_ctx); RowSet = talloc_steal((TALLOC_CTX *)session, RowSet); *ppRowSet = RowSet; talloc_free(mem_ctx); return MAPI_E_SUCCESS; } openchange-2.0/libmapi/IMAPIContainer.c000066400000000000000000000665111223057412600177600ustar00rootroot00000000000000/* OpenChange MAPI implementation. Copyright (C) Julien Kerihuel 2007-2008. This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see . */ #include "libmapi/libmapi.h" #include "libmapi/libmapi_private.h" /** \file IMAPIContainer.c \brief Containers and tables related operations */ /** \details Returns a pointer to a container's table object This function takes a pointer to a container object and returns a pointer to its associated contents \param obj_container the object to get the contents of \param obj_table the resulting table containing the container's contents. \param TableFlags flags controlling the type of table \param RowCount the number of rows in the hierarchy table TableFlags possible values: - TableFlags_Associated (0x2): Get the contents table for "Folder Associated Information" messages, rather than normal messages. - TableFlags_DeferredErrors (0x8): The call response can return immediately, possibly before the call execution is complete and in this case the ReturnValue as well the RowCount fields in the return buffer might not be accurate. Only retval reporting failure can be considered valid in this case. - TableFlags_NoNotifications (0x10): Disables all notifications on .this Table object. - TableFlags_SoftDeletes (0x20): Enables the client to get a list of the soft deleted folders. - TableFlags_UseUnicode (0x40): Requests that the columns that contain string data be returned in Unicode format. - TableFlags_SuppressNotifications (0x80): Suppresses notifications generated by this client’s actions on this Table object. Developers can either set RowCount to a valid pointer on uint32_t or set it to NULL. In this last case, GetHierarchyTable won't return any value to the calling function. \return MAPI_E_SUCCESS on success, otherwise MAPI error. \note Developers may also call GetLastError() to retrieve the last MAPI error code. Possible MAPI error codes are: - MAPI_E_NOT_INITIALIZED: MAPI subsystem has not been initialized - MAPI_E_CALL_FAILED: A network problem was encountered during the transaction \sa OpenFolder, GetHierarchyTable, GetLastError */ _PUBLIC_ enum MAPISTATUS GetContentsTable(mapi_object_t *obj_container, mapi_object_t *obj_table, uint8_t TableFlags, uint32_t *RowCount) { struct mapi_request *mapi_request; struct mapi_response *mapi_response; struct EcDoRpc_MAPI_REQ *mapi_req; struct GetContentsTable_req request; struct mapi_session *session; NTSTATUS status; enum MAPISTATUS retval; uint32_t size = 0; TALLOC_CTX *mem_ctx; uint8_t logon_id; /* Sanity checks */ OPENCHANGE_RETVAL_IF(!obj_container, MAPI_E_INVALID_PARAMETER, NULL); session = mapi_object_get_session(obj_container); OPENCHANGE_RETVAL_IF(!session, MAPI_E_INVALID_PARAMETER, NULL); if ((retval = mapi_object_get_logon_id(obj_container, &logon_id)) != MAPI_E_SUCCESS) return retval; mem_ctx = talloc_named(session, 0, "GetContentsTable"); size = 0; /* Fill the GetContentsTable operation */ request.handle_idx = 0x1; request.TableFlags = TableFlags; size += 2; /* Fill the MAPI_REQ request */ mapi_req = talloc_zero(mem_ctx, struct EcDoRpc_MAPI_REQ); mapi_req->opnum = op_MAPI_GetContentsTable; mapi_req->logon_id = logon_id; mapi_req->handle_idx = 0; mapi_req->u.mapi_GetContentsTable = request; size += 5; /* Fill the mapi_request structure */ mapi_request = talloc_zero(mem_ctx, struct mapi_request); mapi_request->mapi_len = size + sizeof (uint32_t) * 2; mapi_request->length = size; mapi_request->mapi_req = mapi_req; mapi_request->handles = talloc_array(mem_ctx, uint32_t, 2); mapi_request->handles[0] = mapi_object_get_handle(obj_container); mapi_request->handles[1] = 0xffffffff; status = emsmdb_transaction_wrapper(session, mem_ctx, mapi_request, &mapi_response); OPENCHANGE_RETVAL_IF(!NT_STATUS_IS_OK(status), MAPI_E_CALL_FAILED, mem_ctx); OPENCHANGE_RETVAL_IF(!mapi_response->mapi_repl, MAPI_E_CALL_FAILED, mem_ctx); retval = mapi_response->mapi_repl->error_code; OPENCHANGE_RETVAL_IF(retval, retval, mem_ctx); OPENCHANGE_CHECK_NOTIFICATION(session, mapi_response); /* set object session, handle and logon_id */ mapi_object_set_session(obj_table, session); mapi_object_set_handle(obj_table, mapi_response->handles[1]); mapi_object_set_logon_id(obj_table, logon_id); /* Retrieve RowCount if a valid pointer was set */ if (RowCount) { *RowCount = mapi_response->mapi_repl->u.mapi_GetContentsTable.RowCount; } /* new table */ mapi_object_table_init((TALLOC_CTX *)session, obj_table); talloc_free(mapi_response); talloc_free(mem_ctx); return MAPI_E_SUCCESS; } /** \details Returns a pointer to a container's table object This function takes a pointer to a container object and returns a pointer to its associated hierarchy table \param obj_container the object to get the contents of \param obj_table the resulting table containing the container's hierarchy \param TableFlags flags controlling the type of table \param RowCount the number of rows in the hierarchy table TableFlags possible values: - TableFlags_Depth (0x4): Fills the hierarchy table with containers from all levels. If this flag is not set, the hierarchy table contains only the container's immediate child containers. - TableFlags_DeferredErrors (0x8): The call response can return immediately, possibly before the call execution is complete and in this case the ReturnValue as well the RowCount fields in the return buffer might not be accurate. Only retval reporting failure can be considered valid in this case. - TableFlags_NoNotifications (0x10): Disables all notifications on .this Table object. - TableFlags_SoftDeletes (0x20): Enables the client to get a list of the soft deleted folders. - TableFlags_UseUnicode (0x40): Requests that the columns that contain string data be returned in Unicode format. - TableFlags_SuppressNotifications (0x80): Suppresses notifications generated by this client’s actions on this Table object. Developers can either set RowCount to a valid pointer on uint32_t or set it to NULL. In this last case, GetHierarchyTable won't return any value to the calling function. \return MAPI_E_SUCCESS on success, otherwise MAPI error. \note Developers may also call GetLastError() to retrieve the last MAPI error code. Possible MAPI error codes are: - MAPI_E_NOT_INITIALIZED: MAPI subsystem has not been initialized - MAPI_E_CALL_FAILED: A network problem was encountered during the transaction \sa OpenFolder, GetContentsTable, GetLastError */ _PUBLIC_ enum MAPISTATUS GetHierarchyTable(mapi_object_t *obj_container, mapi_object_t *obj_table, uint8_t TableFlags, uint32_t *RowCount) { struct mapi_request *mapi_request; struct mapi_response *mapi_response; struct EcDoRpc_MAPI_REQ *mapi_req; struct GetHierarchyTable_req request; struct mapi_session *session; NTSTATUS status; enum MAPISTATUS retval; uint32_t size = 0; TALLOC_CTX *mem_ctx; uint8_t logon_id; /* Sanity checks */ OPENCHANGE_RETVAL_IF(!obj_container, MAPI_E_INVALID_PARAMETER, NULL); session = mapi_object_get_session(obj_container); OPENCHANGE_RETVAL_IF(!session, MAPI_E_INVALID_PARAMETER, NULL); if ((retval = mapi_object_get_logon_id(obj_container, &logon_id)) != MAPI_E_SUCCESS) return retval; mem_ctx = talloc_named(session, 0, "GetHierarchyTable"); size = 0; /* Fill the GetHierarchyTable operation */ request.handle_idx = 0x1; request.TableFlags = TableFlags; size += 2; /* Fill the MAPI_REQ request */ mapi_req = talloc_zero(mem_ctx, struct EcDoRpc_MAPI_REQ); mapi_req->opnum = op_MAPI_GetHierarchyTable; mapi_req->logon_id = logon_id; mapi_req->handle_idx = 0; mapi_req->u.mapi_GetHierarchyTable = request; size += 5; /* Fill the mapi_request structure */ mapi_request = talloc_zero(mem_ctx, struct mapi_request); mapi_request->mapi_len = size + sizeof (uint32_t) * 2; mapi_request->length = size; mapi_request->mapi_req = mapi_req; mapi_request->handles = talloc_array(mem_ctx, uint32_t, 2); mapi_request->handles[0] = mapi_object_get_handle(obj_container); mapi_request->handles[1] = 0xffffffff; status = emsmdb_transaction_wrapper(session, mem_ctx, mapi_request, &mapi_response); OPENCHANGE_RETVAL_IF(!NT_STATUS_IS_OK(status), MAPI_E_CALL_FAILED, mem_ctx); OPENCHANGE_RETVAL_IF(!mapi_response->mapi_repl, MAPI_E_CALL_FAILED, mem_ctx); retval = mapi_response->mapi_repl->error_code; OPENCHANGE_RETVAL_IF(retval, retval, mem_ctx); OPENCHANGE_CHECK_NOTIFICATION(session, mapi_response); /* set object session, handle and logon_id */ mapi_object_set_session(obj_table, session); mapi_object_set_handle(obj_table, mapi_response->handles[1]); mapi_object_set_logon_id(obj_table, logon_id); /* Retrieve RowCount if a valid pointer was set */ if (RowCount) { *RowCount = mapi_response->mapi_repl->u.mapi_GetHierarchyTable.RowCount; } /* new table */ mapi_object_table_init((TALLOC_CTX *)session, obj_table); talloc_free(mapi_response); talloc_free(mem_ctx); return MAPI_E_SUCCESS; } /** \details Returns a pointer to the permission's table object. This function takes a pointer to a container object and returns a pointer to its associated permission table \param obj_container the object to get the contents of \param flags any special flags to pass \param obj_table the resulting table containing the container's permissions \return MAPI_E_SUCCESS on success, otherwise MAPI error. The only meaningful value for flags is IncludeFreeBusy (0x02). This should be set when getting permissions on the Calendar folder when using Exchange 2007 and later. It should not be set in other situations. \note Developers may also call GetLastError() to retrieve the last MAPI error code. Possible MAPI error codes are: - MAPI_E_NOT_INITIALIZED: MAPI subsystem has not been initialized - MAPI_E_CALL_FAILED: A network problem was encountered during the transaction \sa ModifyPermissions */ _PUBLIC_ enum MAPISTATUS GetPermissionsTable(mapi_object_t *obj_container, uint8_t flags, mapi_object_t *obj_table) { struct mapi_request *mapi_request; struct mapi_response *mapi_response; struct EcDoRpc_MAPI_REQ *mapi_req; struct GetPermissionsTable_req request; struct mapi_session *session; NTSTATUS status; enum MAPISTATUS retval; uint32_t size = 0; TALLOC_CTX *mem_ctx; uint8_t logon_id; /* Sanity checks */ OPENCHANGE_RETVAL_IF(!obj_container, MAPI_E_INVALID_PARAMETER, NULL); session = mapi_object_get_session(obj_container); OPENCHANGE_RETVAL_IF(!session, MAPI_E_INVALID_PARAMETER, NULL); if ((retval = mapi_object_get_logon_id(obj_container, &logon_id)) != MAPI_E_SUCCESS) return retval; mem_ctx = talloc_named(session, 0, "GetPermissionsTable"); size = 0; /* Fill the GetPermissionsTable operation */ request.handle_idx = 0x1; request.TableFlags = flags; size += 2; /* Fill the MAPI_REQ request */ mapi_req = talloc_zero(mem_ctx, struct EcDoRpc_MAPI_REQ); mapi_req->opnum = op_MAPI_GetPermissionsTable; mapi_req->logon_id = logon_id; mapi_req->handle_idx= 0; mapi_req->u.mapi_GetPermissionsTable = request; size += 5; /* Fill the mapi_request structure */ mapi_request = talloc_zero(mem_ctx, struct mapi_request); mapi_request->mapi_len = size + sizeof (uint32_t) * 2; mapi_request->length = size; mapi_request->mapi_req = mapi_req; mapi_request->handles = talloc_array(mem_ctx, uint32_t, 2); mapi_request->handles[0] = mapi_object_get_handle(obj_container); mapi_request->handles[1] = 0xffffffff; status = emsmdb_transaction_wrapper(session, mem_ctx, mapi_request, &mapi_response); OPENCHANGE_RETVAL_IF(!NT_STATUS_IS_OK(status), MAPI_E_CALL_FAILED, mem_ctx); OPENCHANGE_RETVAL_IF(!mapi_response->mapi_repl, MAPI_E_CALL_FAILED, mem_ctx); retval = mapi_response->mapi_repl->error_code; OPENCHANGE_RETVAL_IF(retval, retval, mem_ctx); OPENCHANGE_CHECK_NOTIFICATION(session, mapi_response); /* set object session, handle and logon_id */ mapi_object_set_session(obj_table, session); mapi_object_set_handle(obj_table, mapi_response->handles[1]); mapi_object_set_logon_id(obj_table, logon_id); /* new table */ mapi_object_table_init((TALLOC_CTX *)session, obj_table); talloc_free(mapi_response); talloc_free(mem_ctx); return MAPI_E_SUCCESS; } /** \details Gets the rules table of a folder \param obj_folder the folder we want to retrieve the rules table from \param obj_table the rules table \param TableFlags bitmask associated to the rules table Possible values for TableFlags: - RulesTableFlags_Unicode (0x40): Set if the client is requesting that string values in the table to be returned as Unicode strings. \return MAPI_E_SUCCESS on success, otherwise MAPI error. \note Developers may also call GetLastError() to retrieve the last MAPI error code. Possible MAPI error codes are: - MAPI_E_NOT_INITIALIZED: MAPI subsystem has not been initialized - MAPI_E_CALL_FAILED: A network problem was encountered during the transaction */ _PUBLIC_ enum MAPISTATUS GetRulesTable(mapi_object_t *obj_folder, mapi_object_t *obj_table, uint8_t TableFlags) { struct mapi_request *mapi_request; struct mapi_response *mapi_response; struct EcDoRpc_MAPI_REQ *mapi_req; struct GetRulesTable_req request; struct mapi_session *session; NTSTATUS status; enum MAPISTATUS retval; uint32_t size; TALLOC_CTX *mem_ctx; uint8_t logon_id; /* Sanity check */ OPENCHANGE_RETVAL_IF(!obj_folder, MAPI_E_INVALID_PARAMETER, NULL); OPENCHANGE_RETVAL_IF(!obj_table, MAPI_E_INVALID_PARAMETER, NULL); session = mapi_object_get_session(obj_folder); OPENCHANGE_RETVAL_IF(!session, MAPI_E_INVALID_PARAMETER, NULL); if ((retval = mapi_object_get_logon_id(obj_folder, &logon_id)) != MAPI_E_SUCCESS) return retval; mem_ctx = talloc_named(session, 0, "GetRulesTable"); size = 0; /* Fill the GetRulesTable operation */ request.handle_idx = 0x1; size += sizeof (uint8_t); request.TableFlags = TableFlags; size += sizeof (uint8_t); /* Fill the MAPI_REQ request */ mapi_req = talloc_zero(mem_ctx, struct EcDoRpc_MAPI_REQ); mapi_req->opnum = op_MAPI_GetRulesTable; mapi_req->logon_id = logon_id; mapi_req->handle_idx = 0; mapi_req->u.mapi_GetRulesTable = request; size += 5; /* Fill the mapi_request structure */ mapi_request = talloc_zero(mem_ctx, struct mapi_request); mapi_request->mapi_len = size + sizeof (uint32_t) * 2; mapi_request->length = size; mapi_request->mapi_req = mapi_req; mapi_request->handles = talloc_array(mem_ctx, uint32_t, 2); mapi_request->handles[0] = mapi_object_get_handle(obj_folder); mapi_request->handles[1] = 0xffffffff; status = emsmdb_transaction_wrapper(session, mem_ctx, mapi_request, &mapi_response); OPENCHANGE_RETVAL_IF(!NT_STATUS_IS_OK(status), MAPI_E_CALL_FAILED, mem_ctx); OPENCHANGE_RETVAL_IF(!mapi_response->mapi_repl, MAPI_E_CALL_FAILED, mem_ctx); retval = mapi_response->mapi_repl->error_code; OPENCHANGE_RETVAL_IF(retval, retval, mem_ctx); OPENCHANGE_CHECK_NOTIFICATION(session, mapi_response); /* set object session, handle and logon_id */ mapi_object_set_session(obj_table, session); mapi_object_set_handle(obj_table, mapi_response->handles[1]); mapi_object_set_logon_id(obj_table, logon_id); /* new table */ mapi_object_table_init((TALLOC_CTX *)session, obj_table); talloc_free(mapi_response); talloc_free(mem_ctx); return MAPI_E_SUCCESS; } /** \details Modify the entries of a permission table This function takes a pointer to a table object, a list of entries to modify and alter the permission table of its associated container. This function can be used to add, modify or remove permissions. \param obj_table the table containing the container's permissions \param flags any special flags to use \param permsdata the list of permissions table entries to modify Possible values for flags: - 0x02 for IncludeFreeBusy. This should be set when modifying permissions on the Calendar folder when using Exchange 2007 and later. It should not be set in other situations. - 0x01 for ReplaceRows. This means "remove all current permissions and use this set instead", so the permsdata must consist of ROW_ADD operations. \return MAPI_E_SUCCESS on success, otherwise MAPI error. \note Developers may also call GetLastError() to retrieve the last MAPI error code. Possible MAPI error codes are: - MAPI_E_NOT_INITIALIZED: MAPI subsystem has not been initialized - MAPI_E_CALL_FAILED: A network problem was encountered during the transaction \sa GetPermissionsTable, AddUserPermission, ModifyUserPermission, RemoveUserPermission */ _PUBLIC_ enum MAPISTATUS ModifyPermissions(mapi_object_t *obj_table, uint8_t flags, struct mapi_PermissionsData *permsdata) { struct mapi_request *mapi_request; struct mapi_response *mapi_response; struct EcDoRpc_MAPI_REQ *mapi_req; struct ModifyPermissions_req request; struct mapi_session *session; NTSTATUS status; enum MAPISTATUS retval; uint32_t size = 0; TALLOC_CTX *mem_ctx; uint32_t i, j; uint8_t logon_id; /* Sanity checks */ OPENCHANGE_RETVAL_IF(!obj_table, MAPI_E_INVALID_PARAMETER, NULL); OPENCHANGE_RETVAL_IF(!permsdata, MAPI_E_INVALID_PARAMETER, NULL); session = mapi_object_get_session(obj_table); OPENCHANGE_RETVAL_IF(!session, MAPI_E_INVALID_PARAMETER, NULL); if ((retval = mapi_object_get_logon_id(obj_table, &logon_id)) != MAPI_E_SUCCESS) return retval; mem_ctx = talloc_named(session, 0, "ModifyPermissions"); /* Fill the ModifyPermissions operation */ request.rowList = *permsdata; request.rowList.ModifyFlags = flags; size += sizeof (uint8_t) + sizeof (uint16_t); for (i = 0; i < permsdata->ModifyCount; i++) { size += sizeof (uint8_t); for (j = 0; j < permsdata->PermissionsData[i].lpProps.cValues; j++) { size += get_mapi_property_size(&(permsdata->PermissionsData[i].lpProps.lpProps[j])); size += sizeof (uint32_t); } size += sizeof (uint16_t); } /* Fill the MAPI_REQ request */ mapi_req = talloc_zero(mem_ctx, struct EcDoRpc_MAPI_REQ); mapi_req->opnum = op_MAPI_ModifyPermissions; mapi_req->logon_id = logon_id; mapi_req->handle_idx= 0; mapi_req->u.mapi_ModifyPermissions = request; size += 5; /* Fill the mapi_request structure */ mapi_request = talloc_zero(mem_ctx, struct mapi_request); mapi_request->mapi_len = size + sizeof (uint32_t); mapi_request->length = size; mapi_request->mapi_req = mapi_req; mapi_request->handles = talloc_array(mem_ctx, uint32_t, 1); mapi_request->handles[0] = mapi_object_get_handle(obj_table); status = emsmdb_transaction_wrapper(session, mem_ctx, mapi_request, &mapi_response); OPENCHANGE_RETVAL_IF(!NT_STATUS_IS_OK(status), MAPI_E_CALL_FAILED, mem_ctx); OPENCHANGE_RETVAL_IF(!mapi_response->mapi_repl, MAPI_E_CALL_FAILED, mem_ctx); retval = mapi_response->mapi_repl->error_code; OPENCHANGE_RETVAL_IF(retval, retval, mem_ctx); OPENCHANGE_CHECK_NOTIFICATION(session, mapi_response); talloc_free(mapi_response); talloc_free(mem_ctx); return MAPI_E_SUCCESS; } /** \details Establishes search criteria for the container \param obj_container the object we apply search criteria to \param res pointer to a mapi_SRestriction structure defining the search criteria \param SearchFlags bitmask of flags that controls how the search is performed \param lpContainerList pointer to a list of identifiers representing containers to be included in the search SearchFlags can take the following values: - BACKGROUND_SEARCH: Search run at normal priority relative to other searches. This flag is mutually exclusive with the FOREGROUND_SEARCH one. - FOREGROUND_SEARCH: Search run at high priority relative to other searches. This flag is mutually exclusive with the BACKGROUND_SEARCH one. - RECURSIVE_SEARCH: The search should include the containers specified in the lpContainerList parameter and all of their child container. This flag is mutually exclusive with the SHALLOW_SEARCH one. - RESTART_SEARCH: The search should be initiated, if this is the first call to SetSearchCriteria, or restarted, if the search is inactive. This flag is mutually exclusive with the STOP_SEARCH flag. - SHALLOW_SEARCH: The search should only look in the containers specified in the lpContainerList parameter for matching entries. This flag is mutually exclusive with the RECURSIVE_SEARCH one. - STOP_SEARCH: The search should be aborted. This flag is mutually exclusive with the RESTART_SEARCH one. \return MAPI_E_SUCCESS on success, otherwise MAPI error. \note Developers may also call GetLastError() to retrieve the last MAPI error code. Possible MAPI error codes are: - MAPI_E_NOT_INITIALIZED: MAPI subsystem has not been initialized - MAPI_E_INVALID_PARAMETER: One or more parameters were invalid (usually null pointer) - MAPI_E_CALL_FAILED: A network problem was encountered during the transaction \sa GetSearchCriteria */ _PUBLIC_ enum MAPISTATUS SetSearchCriteria(mapi_object_t *obj_container, struct mapi_SRestriction *res, uint32_t SearchFlags, mapi_id_array_t *lpContainerList) { struct mapi_request *mapi_request; struct mapi_response *mapi_response; struct EcDoRpc_MAPI_REQ *mapi_req; struct SetSearchCriteria_req request; struct mapi_session *session; NTSTATUS status; enum MAPISTATUS retval; uint32_t size; TALLOC_CTX *mem_ctx; uint8_t logon_id; /* Sanity checks */ OPENCHANGE_RETVAL_IF(!obj_container, MAPI_E_INVALID_PARAMETER, NULL); OPENCHANGE_RETVAL_IF(!res, MAPI_E_INVALID_PARAMETER, NULL); session = mapi_object_get_session(obj_container); OPENCHANGE_RETVAL_IF(!session, MAPI_E_INVALID_PARAMETER, NULL); if ((retval = mapi_object_get_logon_id(obj_container, &logon_id)) != MAPI_E_SUCCESS) return retval; mem_ctx = talloc_named(session, 0, "SetSearchCriteria"); size = 0; /* Fill the SetSearchCriteria operation */ request.res = *res; size += get_mapi_SRestriction_size(res); if (lpContainerList != NULL) { request.FolderIdCount = lpContainerList->count; size += sizeof (uint16_t); mapi_id_array_get(mem_ctx, lpContainerList, &request.FolderIds); size += lpContainerList->count * sizeof (uint64_t); } else { request.FolderIdCount = 0; size += sizeof (uint16_t); request.FolderIds = NULL; } request.SearchFlags = SearchFlags; size += sizeof (uint32_t); /* add subcontext size */ size += sizeof (uint16_t); /* Fill the MAPI_REQ request */ mapi_req = talloc_zero(mem_ctx, struct EcDoRpc_MAPI_REQ); mapi_req->opnum = op_MAPI_SetSearchCriteria; mapi_req->logon_id = logon_id; mapi_req->handle_idx = 0; mapi_req->u.mapi_SetSearchCriteria = request; size += 5; /* Fill the mapi_request structure */ mapi_request = talloc_zero(mem_ctx, struct mapi_request); mapi_request->mapi_len = size + sizeof (uint32_t); mapi_request->length = size; mapi_request->mapi_req = mapi_req; mapi_request->handles = talloc_array(mem_ctx, uint32_t, 1); mapi_request->handles[0] = mapi_object_get_handle(obj_container); status = emsmdb_transaction_wrapper(session, mem_ctx, mapi_request, &mapi_response); OPENCHANGE_RETVAL_IF(!NT_STATUS_IS_OK(status), MAPI_E_CALL_FAILED, mem_ctx); OPENCHANGE_RETVAL_IF(!mapi_response->mapi_repl, MAPI_E_CALL_FAILED, mem_ctx); retval = mapi_response->mapi_repl->error_code; OPENCHANGE_RETVAL_IF(retval, retval, mem_ctx); OPENCHANGE_CHECK_NOTIFICATION(session, mapi_response); talloc_free(mapi_response); talloc_free(mem_ctx); return MAPI_E_SUCCESS; } /** \details Obtains the search criteria for a container \param obj_container the object we retrieve search criteria from \param res pointer to a mapi_SRestriction structure defining the search criteria \param SearchFlags bitmask of flags that controls how the search is performed \param FolderIdCount number of FolderIds entries \param FolderIds pointer to a list of identifiers representing containers included in the search \return MAPI_E_SUCCESS on success, otherwise MAPI error. \note Developers may also call GetLastError() to retrieve the last MAPI error code. Possible MAPI error codes are: - MAPI_E_NOT_INITIALIZED: MAPI subsystem has not been initialized - MAPI_E_CALL_FAILED: A network problem was encountered during the transaction \sa SetSearchCriteria */ _PUBLIC_ enum MAPISTATUS GetSearchCriteria(mapi_object_t *obj_container, struct mapi_SRestriction *res, uint32_t *SearchFlags, uint16_t *FolderIdCount, uint64_t **FolderIds) { struct mapi_request *mapi_request; struct mapi_response *mapi_response; struct EcDoRpc_MAPI_REQ *mapi_req; struct GetSearchCriteria_req request; struct GetSearchCriteria_repl *reply; struct mapi_session *session; NTSTATUS status; enum MAPISTATUS retval; uint32_t size; TALLOC_CTX *mem_ctx; uint8_t logon_id; /* Sanity checks */ OPENCHANGE_RETVAL_IF(!obj_container, MAPI_E_INVALID_PARAMETER, NULL); OPENCHANGE_RETVAL_IF(!SearchFlags, MAPI_E_INVALID_PARAMETER, NULL); OPENCHANGE_RETVAL_IF(!FolderIdCount, MAPI_E_INVALID_PARAMETER, NULL); OPENCHANGE_RETVAL_IF(!FolderIds, MAPI_E_INVALID_PARAMETER, NULL); session = mapi_object_get_session(obj_container); OPENCHANGE_RETVAL_IF(!session, MAPI_E_INVALID_PARAMETER, NULL); if ((retval = mapi_object_get_logon_id(obj_container, &logon_id)) != MAPI_E_SUCCESS) return retval; mem_ctx = talloc_named(session, 0, "GetSearchCriteria"); size = 0; /* Fill the GetSearchCriteria operation */ request.UseUnicode = 0x1; request.IncludeRestriction = 0x1; request.IncludeFolders = 0x1; size += 3 * sizeof (uint8_t); /* Fill the MAPI_REQ request */ mapi_req = talloc_zero(mem_ctx, struct EcDoRpc_MAPI_REQ); mapi_req->opnum = op_MAPI_GetSearchCriteria; mapi_req->logon_id = logon_id; mapi_req->handle_idx = 0; mapi_req->u.mapi_GetSearchCriteria = request; size += 5; /* Fill the mapi_request structure */ mapi_request = talloc_zero(mem_ctx, struct mapi_request); mapi_request->mapi_len = size + sizeof (uint32_t); mapi_request->length = size; mapi_request->mapi_req = mapi_req; mapi_request->handles = talloc_array(mem_ctx, uint32_t, 1); mapi_request->handles[0] = mapi_object_get_handle(obj_container); status = emsmdb_transaction_wrapper(session, mem_ctx, mapi_request, &mapi_response); OPENCHANGE_RETVAL_IF(!NT_STATUS_IS_OK(status), MAPI_E_CALL_FAILED, mem_ctx); OPENCHANGE_RETVAL_IF(!mapi_response->mapi_repl, MAPI_E_CALL_FAILED, mem_ctx); retval = mapi_response->mapi_repl->error_code; OPENCHANGE_RETVAL_IF(retval, retval, mem_ctx); OPENCHANGE_CHECK_NOTIFICATION(session, mapi_response); reply = &mapi_response->mapi_repl->u.mapi_GetSearchCriteria; res = &reply->RestrictionData; *FolderIdCount = reply->FolderIdCount; *FolderIds = talloc_steal((TALLOC_CTX *)session, reply->FolderIds); *SearchFlags = reply->SearchFlags; talloc_free(mapi_response); talloc_free(mem_ctx); return MAPI_E_SUCCESS; } openchange-2.0/libmapi/IMAPIFolder.c000066400000000000000000001247061223057412600172520ustar00rootroot00000000000000/* OpenChange MAPI implementation. Copyright (C) Julien Kerihuel 2007-2011. This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see . */ #include "libmapi/libmapi.h" #include "libmapi/libmapi_private.h" /** \file IMAPIFolder.c \brief Folder related functions */ /** \details The function creates a message in the specified folder, and returns a pointer on this message. \param obj_folder the folder to create the message in. \param obj_message pointer to the newly created message. \return MAPI_E_SUCCESS on success, otherwise MAPI error. \note Developers may also call GetLastError() to retrieve the last MAPI error code. Possible MAPI error codes are: - MAPI_E_NOT_INITIALIZED: MAPI subsystem has not been initialized - MAPI_E_CALL_FAILED: A network problem was encountered during the transaction \sa OpenFolder, DeleteMessage, GetLastError */ _PUBLIC_ enum MAPISTATUS CreateMessage(mapi_object_t *obj_folder, mapi_object_t *obj_message) { struct mapi_request *mapi_request; struct mapi_response *mapi_response; struct EcDoRpc_MAPI_REQ *mapi_req; struct CreateMessage_req request; struct mapi_session *session; NTSTATUS status; enum MAPISTATUS retval; uint32_t size; TALLOC_CTX *mem_ctx; uint8_t logon_id; /* Sanity checks */ OPENCHANGE_RETVAL_IF(!obj_folder, MAPI_E_INVALID_PARAMETER, NULL); session = mapi_object_get_session(obj_folder); OPENCHANGE_RETVAL_IF(!session, MAPI_E_INVALID_PARAMETER, NULL); if ((retval = mapi_object_get_logon_id(obj_folder, &logon_id)) != MAPI_E_SUCCESS) return retval; mem_ctx = talloc_named(session, 0, "CreateMessage"); size = 0; /* Fill the OpenFolder operation */ request.handle_idx = 0x1; size += sizeof (uint8_t); request.CodePageId = 0xfff; size += sizeof (uint16_t); request.FolderId = mapi_object_get_id(obj_folder); size += sizeof (uint64_t); request.AssociatedFlag = 0; size += sizeof (uint8_t); /* Fill the MAPI_REQ request */ mapi_req = talloc_zero(mem_ctx, struct EcDoRpc_MAPI_REQ); mapi_req->opnum = op_MAPI_CreateMessage; mapi_req->logon_id = logon_id; mapi_req->handle_idx = 0; mapi_req->u.mapi_CreateMessage = request; size += 5; /* Fill the mapi_request structure */ mapi_request = talloc_zero(mem_ctx, struct mapi_request); mapi_request->mapi_len = size + sizeof(mapi_handle_t) * 2; mapi_request->length = size; mapi_request->mapi_req = mapi_req; mapi_request->handles = talloc_array(mem_ctx, mapi_handle_t, 2); mapi_request->handles[0] = mapi_object_get_handle(obj_folder); mapi_request->handles[1] = 0xffffffff; status = emsmdb_transaction_wrapper(session, mem_ctx, mapi_request, &mapi_response); OPENCHANGE_RETVAL_IF(!NT_STATUS_IS_OK(status), MAPI_E_CALL_FAILED, mem_ctx); OPENCHANGE_RETVAL_IF(!mapi_response->mapi_repl, MAPI_E_CALL_FAILED, mem_ctx); retval = mapi_response->mapi_repl->error_code; OPENCHANGE_RETVAL_IF(retval, retval, mem_ctx); OPENCHANGE_CHECK_NOTIFICATION(session, mapi_response); /* set object session and handle */ mapi_object_set_session(obj_message, session); mapi_object_set_handle(obj_message, mapi_response->handles[1]); mapi_object_set_logon_id(obj_message, logon_id); talloc_free(mapi_response); talloc_free(mem_ctx); return MAPI_E_SUCCESS; } /** \details Delete one or more messages This function deletes one or more messages based on their ids from a specified folder. \param obj_folder the folder to delete messages from \param id_messages the list of ids \param cn_messages the number of messages in the id list. \return MAPI_E_SUCCESS on success, otherwise MAPI error. \note Developers may also call GetLastError() to retrieve the last MAPI error code. Possible MAPI error codes are: - MAPI_E_NOT_INITIALIZED: MAPI subsystem has not been initialized - MAPI_E_CALL_FAILED: A network problem was encountered during the transaction \sa OpenFolder, CreateMessage, GetLastError */ _PUBLIC_ enum MAPISTATUS DeleteMessage(mapi_object_t *obj_folder, mapi_id_t *id_messages, uint32_t cn_messages) { struct mapi_request *mapi_request; struct mapi_response *mapi_response; struct EcDoRpc_MAPI_REQ *mapi_req; struct DeleteMessages_req request; struct mapi_session *session; NTSTATUS status; enum MAPISTATUS retval; uint32_t size; TALLOC_CTX *mem_ctx; uint8_t logon_id; /* Sanity checks */ OPENCHANGE_RETVAL_IF(!obj_folder, MAPI_E_INVALID_PARAMETER, NULL); session = mapi_object_get_session(obj_folder); OPENCHANGE_RETVAL_IF(!session, MAPI_E_INVALID_PARAMETER, NULL); if ((retval = mapi_object_get_logon_id(obj_folder, &logon_id)) != MAPI_E_SUCCESS) return retval; mem_ctx = talloc_named(session, 0, "DeleteMessages"); size = 0; /* Fill the DeleteMessages operation */ request.WantAsynchronous = 0x0; size += sizeof (uint8_t); request.NotifyNonRead = 0x1; size += sizeof(uint8_t); request.cn_ids = (uint16_t)cn_messages; size += sizeof(uint16_t); request.message_ids = id_messages; size += request.cn_ids * sizeof(mapi_id_t); /* Fill the MAPI_REQ request */ mapi_req = talloc_zero(mem_ctx, struct EcDoRpc_MAPI_REQ); mapi_req->opnum = op_MAPI_DeleteMessages; mapi_req->logon_id = logon_id; mapi_req->handle_idx = 0; mapi_req->u.mapi_DeleteMessages = request; size += 5; /* Fill the mapi_request structure */ mapi_request = talloc_zero(mem_ctx, struct mapi_request); mapi_request->mapi_len = size + sizeof (uint32_t); mapi_request->length = size; mapi_request->mapi_req = mapi_req; mapi_request->handles = talloc_array(mem_ctx, uint32_t, 1); mapi_request->handles[0] = mapi_object_get_handle(obj_folder); status = emsmdb_transaction_wrapper(session, mem_ctx, mapi_request, &mapi_response); OPENCHANGE_RETVAL_IF(!NT_STATUS_IS_OK(status), MAPI_E_CALL_FAILED, mem_ctx); OPENCHANGE_RETVAL_IF(!mapi_response->mapi_repl, MAPI_E_CALL_FAILED, mem_ctx); retval = mapi_response->mapi_repl->error_code; OPENCHANGE_RETVAL_IF(retval, retval, mem_ctx); OPENCHANGE_CHECK_NOTIFICATION(session, mapi_response); talloc_free(mapi_response); talloc_free(mem_ctx); return MAPI_E_SUCCESS; } /** \details Hard delete one or more messages This function hard deletes one or more messages based on their ids from a specified folder. \param obj_folder the folder to hard delete messages from \param id_messages the list of ids \param cn_messages the number of messages in the id list. \return MAPI_E_SUCCESS on success, otherwise MAPI error. \note Developers may also call GetLastError() to retrieve the last MAPI error code. Possible MAPI error codes are: - MAPI_E_NOT_INITIALIZED: MAPI subsystem has not been initialized - MAPI_E_INVALID_PARAMETER: the parent folder was not valid - MAPI_E_CALL_FAILED: A network problem was encountered during the transaction \sa OpenFolder, CreateMessage, GetLastError */ _PUBLIC_ enum MAPISTATUS HardDeleteMessage(mapi_object_t *obj_folder, mapi_id_t *id_messages, uint16_t cn_messages) { struct mapi_request *mapi_request; struct mapi_response *mapi_response; struct EcDoRpc_MAPI_REQ *mapi_req; struct HardDeleteMessages_req request; struct mapi_session *session; NTSTATUS status; enum MAPISTATUS retval; uint32_t size; TALLOC_CTX *mem_ctx; uint8_t logon_id; /* Sanity checks */ OPENCHANGE_RETVAL_IF(!obj_folder, MAPI_E_INVALID_PARAMETER, NULL); session = mapi_object_get_session(obj_folder); OPENCHANGE_RETVAL_IF(!session, MAPI_E_INVALID_PARAMETER, NULL); if ((retval = mapi_object_get_logon_id(obj_folder, &logon_id)) != MAPI_E_SUCCESS) return retval; mem_ctx = talloc_named(session, 0, "HardDeleteMessages"); size = 0; /* Fill the HardDeleteMessages operation */ request.WantAsynchronous = 0x0; size += sizeof (uint8_t); request.NotifyNonRead = 0x1; size += sizeof(uint8_t); request.MessageIdCount = cn_messages; size += sizeof(uint16_t); request.MessageIds = id_messages; size += request.MessageIdCount * sizeof(mapi_id_t); /* Fill the MAPI_REQ request */ mapi_req = talloc_zero(mem_ctx, struct EcDoRpc_MAPI_REQ); mapi_req->opnum = op_MAPI_HardDeleteMessages; mapi_req->logon_id = logon_id; mapi_req->handle_idx = 0; mapi_req->u.mapi_HardDeleteMessages = request; size += 5; /* Fill the mapi_request structure */ mapi_request = talloc_zero(mem_ctx, struct mapi_request); mapi_request->mapi_len = size + sizeof (uint32_t); mapi_request->length = size; mapi_request->mapi_req = mapi_req; mapi_request->handles = talloc_array(mem_ctx, uint32_t, 1); mapi_request->handles[0] = mapi_object_get_handle(obj_folder); status = emsmdb_transaction_wrapper(session, mem_ctx, mapi_request, &mapi_response); OPENCHANGE_RETVAL_IF(!NT_STATUS_IS_OK(status), MAPI_E_CALL_FAILED, mem_ctx); OPENCHANGE_RETVAL_IF(!mapi_response->mapi_repl, MAPI_E_CALL_FAILED, mem_ctx); retval = mapi_response->mapi_repl->error_code; OPENCHANGE_RETVAL_IF(retval, retval, mem_ctx); talloc_free(mapi_response); talloc_free(mem_ctx); return MAPI_E_SUCCESS; } /** \details Obtain the status associated with a message This function obtains the status associated with a message in the given folder. \param obj_folder the folder where the message is located \param msgid the message ID \param ulStatus the message status \return MAPI_E_SUCCESS on success, otherwise MAPI error. \note Developers may also call GetLastError() to retrieve the last MAPI error code. Possible MAPI error codes are: - MAPI_E_NOT_INITIALIZED: MAPI subsystem has not been initialized - MAPI_E_CALL_FAILED: A network problem was encountered during the transaction */ _PUBLIC_ enum MAPISTATUS GetMessageStatus(mapi_object_t *obj_folder, mapi_id_t msgid, uint32_t *ulStatus) { struct mapi_request *mapi_request; struct mapi_response *mapi_response; struct EcDoRpc_MAPI_REQ *mapi_req; struct GetMessageStatus_req request; struct mapi_session *session; NTSTATUS status; enum MAPISTATUS retval; uint32_t size; TALLOC_CTX *mem_ctx; uint8_t logon_id; /* Sanity checks */ OPENCHANGE_RETVAL_IF(!obj_folder, MAPI_E_INVALID_PARAMETER, NULL); OPENCHANGE_RETVAL_IF(!msgid, MAPI_E_INVALID_PARAMETER, NULL); session = mapi_object_get_session(obj_folder); OPENCHANGE_RETVAL_IF(!session, MAPI_E_INVALID_PARAMETER, NULL); if ((retval = mapi_object_get_logon_id(obj_folder, &logon_id)) != MAPI_E_SUCCESS) return retval; mem_ctx = talloc_named(session, 0, "GetMessageStatus"); size = 0; /* Fill the GetMessageStatus operation */ request.msgid = msgid; size += sizeof (uint64_t); /* Fill the MAPI_REQ request */ mapi_req = talloc_zero(mem_ctx, struct EcDoRpc_MAPI_REQ); mapi_req->opnum = op_MAPI_GetMessageStatus; mapi_req->logon_id = logon_id; mapi_req->handle_idx = 0; mapi_req->u.mapi_GetMessageStatus = request; size += 5; /* Fill the mapi_request structure */ mapi_request = talloc_zero(mem_ctx, struct mapi_request); mapi_request->mapi_len = size + sizeof (uint32_t); mapi_request->length = size; mapi_request->mapi_req = mapi_req; mapi_request->handles = talloc_array(mem_ctx, uint32_t, 1); mapi_request->handles[0] = mapi_object_get_handle(obj_folder); status = emsmdb_transaction_wrapper(session, mem_ctx, mapi_request, &mapi_response); OPENCHANGE_RETVAL_IF(!NT_STATUS_IS_OK(status), MAPI_E_CALL_FAILED, mem_ctx); OPENCHANGE_RETVAL_IF(!mapi_response->mapi_repl, MAPI_E_CALL_FAILED, mem_ctx); retval = mapi_response->mapi_repl->error_code; OPENCHANGE_RETVAL_IF(retval, retval, mem_ctx); OPENCHANGE_CHECK_NOTIFICATION(session, mapi_response); *ulStatus = mapi_response->mapi_repl->u.mapi_SetMessageStatus.ulOldStatus; talloc_free(mapi_response); talloc_free(mem_ctx); return MAPI_E_SUCCESS; } /** \details Set the status associated with a message This function sets the status associated with a message in the given folder. \param obj_folder the folder where the message is located \param msgid the message ID \param ulNewStatus the new status to be assigned \param ulNewStatusMask bitmask of flags hat is applied to the new status indicating the flags to be set \param ulOldStatus pointer on the previous status of the message ulNewStatusMask possible values: - MSGSTATUS_DELMARKED: the message is marked for deletion - MSGSTATUS_HIDDEN: the message is not to be displayed - MSGSTATUS_HIGHLIGHTED: the message is to be displayed highlighted - MSGSTATUS_REMOTE_DELETE: the message has been marked for deletion on the remote message store without downloading to the local client. - MSGSTATUS_REMOTE_DOWNLOAD: the message has been marked for downloading from the remote message store to the local client. - MSGSTATUS_TAGGED: The message has been tagged for a client-defined purpose. \return MAPI_E_SUCCESS on success, otherwise MAPI error. \note Developers may also call GetLastError() to retrieve the last MAPI error code. Possible MAPI error codes are: - MAPI_E_NOT_INITIALIZED: MAPI subsystem has not been initialized - MAPI_E_CALL_FAILED: A network problem was encountered during the transaction */ _PUBLIC_ enum MAPISTATUS SetMessageStatus(mapi_object_t *obj_folder, mapi_id_t msgid, uint32_t ulNewStatus, uint32_t ulNewStatusMask, uint32_t *ulOldStatus) { struct mapi_request *mapi_request; struct mapi_response *mapi_response; struct EcDoRpc_MAPI_REQ *mapi_req; struct SetMessageStatus_req request; struct mapi_session *session; NTSTATUS status; enum MAPISTATUS retval; uint32_t size; TALLOC_CTX *mem_ctx; uint8_t logon_id; /* Sanity checks */ OPENCHANGE_RETVAL_IF(!obj_folder, MAPI_E_INVALID_PARAMETER, NULL); OPENCHANGE_RETVAL_IF(!msgid, MAPI_E_INVALID_PARAMETER, NULL); session = mapi_object_get_session(obj_folder); OPENCHANGE_RETVAL_IF(!session, MAPI_E_INVALID_PARAMETER, NULL); if ((retval = mapi_object_get_logon_id(obj_folder, &logon_id)) != MAPI_E_SUCCESS) return retval; mem_ctx = talloc_named(session, 0, "SetMessageStatus"); size = 0; /* Fill the SetMessageStatus operation */ request.msgid = msgid; size += sizeof (uint64_t); request.ulNewStatus = ulNewStatus; size += sizeof (uint32_t); request.ulNewStatusMask = ulNewStatusMask; size += sizeof (uint32_t); /* Fill the MAPI_REQ request */ mapi_req = talloc_zero(mem_ctx, struct EcDoRpc_MAPI_REQ); mapi_req->opnum = op_MAPI_SetMessageStatus; mapi_req->logon_id = logon_id; mapi_req->handle_idx = 0; mapi_req->u.mapi_SetMessageStatus = request; size += 5; /* Fill the mapi_request structure */ mapi_request = talloc_zero(mem_ctx, struct mapi_request); mapi_request->mapi_len = size + sizeof (uint32_t); mapi_request->length = size; mapi_request->mapi_req = mapi_req; mapi_request->handles = talloc_array(mem_ctx, uint32_t, 1); mapi_request->handles[0] = mapi_object_get_handle(obj_folder); status = emsmdb_transaction_wrapper(session, mem_ctx, mapi_request, &mapi_response); OPENCHANGE_RETVAL_IF(!NT_STATUS_IS_OK(status), MAPI_E_CALL_FAILED, mem_ctx); OPENCHANGE_RETVAL_IF(!mapi_response->mapi_repl, MAPI_E_CALL_FAILED, mem_ctx); retval = mapi_response->mapi_repl->error_code; OPENCHANGE_RETVAL_IF(retval, retval, mem_ctx); OPENCHANGE_CHECK_NOTIFICATION(session, mapi_response); *ulOldStatus = mapi_response->mapi_repl->u.mapi_SetMessageStatus.ulOldStatus; talloc_free(mapi_response); talloc_free(mem_ctx); return MAPI_E_SUCCESS; } /** \details Copy or Move a message from a folder to another \param obj_src The source folder \param obj_dst The destination folder \param message_id pointer to container object for message ids. \param WantCopy boolean value, defines whether the operation is a copy or a move Possible values for WantCopy: -# 0: Move -# 1: Copy \return MAPI_E_SUCCESS on success, otherwise MAPI error. \note Developers may also call GetLastError() to retrieve the last MAPI error code. Possible MAPI error codes are: - MAPI_E_NOT_INITIALIZED: MAPI subsystem has not been initialized - MAPI_E_CALL_FAILED: A network problem was encountered during the transaction \sa OpenFolder, GetLastError */ _PUBLIC_ enum MAPISTATUS MoveCopyMessages(mapi_object_t *obj_src, mapi_object_t *obj_dst, mapi_id_array_t *message_id, bool WantCopy) { NTSTATUS status; TALLOC_CTX *mem_ctx; enum MAPISTATUS retval; struct mapi_request *mapi_request; struct mapi_response *mapi_response; struct EcDoRpc_MAPI_REQ *mapi_req; struct MoveCopyMessages_req request; struct mapi_session *session[2]; uint32_t size; uint8_t logon_id; /* Sanity checks */ OPENCHANGE_RETVAL_IF(!obj_src, MAPI_E_INVALID_PARAMETER, NULL); OPENCHANGE_RETVAL_IF(!obj_dst, MAPI_E_INVALID_PARAMETER, NULL); session[0] = mapi_object_get_session(obj_src); session[1] = mapi_object_get_session(obj_dst); OPENCHANGE_RETVAL_IF(!session[0], MAPI_E_INVALID_PARAMETER, NULL); OPENCHANGE_RETVAL_IF(!session[1], MAPI_E_INVALID_PARAMETER, NULL); OPENCHANGE_RETVAL_IF(session[0] != session[1], MAPI_E_INVALID_PARAMETER, NULL); if ((retval = mapi_object_get_logon_id(obj_src, &logon_id)) != MAPI_E_SUCCESS) return retval; mem_ctx = talloc_named(session[0], 0, "MoveCopyMessages"); size = 0; /* Fill the CopyMessage operation */ request.handle_idx = 0x1; size += sizeof (uint8_t); request.count = message_id->count; size += sizeof (uint16_t); retval = mapi_id_array_get(mem_ctx, message_id, &(request.message_id)); OPENCHANGE_RETVAL_IF(retval, retval, mem_ctx); size += request.count * sizeof (mapi_id_t); request.WantAsynchronous = 0; size += sizeof (uint8_t); request.WantCopy = WantCopy; size += sizeof (uint8_t); /* Fill the MAPI_REQ request */ mapi_req = talloc_zero(mem_ctx, struct EcDoRpc_MAPI_REQ); mapi_req->opnum = op_MAPI_MoveCopyMessages; mapi_req->logon_id = logon_id; mapi_req->handle_idx = 0; mapi_req->u.mapi_MoveCopyMessages = request; size += 5; /* Fill the mapi_request structure */ mapi_request = talloc_zero(mem_ctx, struct mapi_request); mapi_request->mapi_len = size + sizeof (uint32_t) * 2; mapi_request->length = size; mapi_request->mapi_req = mapi_req; mapi_request->handles = talloc_array(mem_ctx, uint32_t, 2); mapi_request->handles[0] = mapi_object_get_handle(obj_src); mapi_request->handles[1] = mapi_object_get_handle(obj_dst); status = emsmdb_transaction_wrapper(session[0], mem_ctx, mapi_request, &mapi_response); OPENCHANGE_RETVAL_IF(!NT_STATUS_IS_OK(status), MAPI_E_CALL_FAILED, mem_ctx); OPENCHANGE_RETVAL_IF(!mapi_response->mapi_repl, MAPI_E_CALL_FAILED, mem_ctx); retval = mapi_response->mapi_repl->error_code; OPENCHANGE_RETVAL_IF(retval, retval, mem_ctx); OPENCHANGE_CHECK_NOTIFICATION(session[0], mapi_response); talloc_free(mapi_response); talloc_free(mem_ctx); return MAPI_E_SUCCESS; } /** \details Create a folder The function creates a folder (defined with its name, comment and type) within a specified folder. \param obj_parent the folder to create the new folder in \param ulFolderType the type of the folder \param name the name of the new folder \param comment the comment associated with the new folder \param ulFlags flags associated with folder creation \param obj_child pointer to the newly created folder ulFlags possible values: - MAPI_UNICODE: use UNICODE folder name and comment - OPEN_IF_EXISTS: open the folder if it already exists ulFolderType possible values: - FOLDER_GENERIC - FOLDER_SEARCH \return MAPI_E_SUCCESS on success, otherwise MAPI error. \note Developers may also call GetLastError() to retrieve the last MAPI error code. Possible MAPI error codes are: - MAPI_E_NOT_INITIALIZED: MAPI subsystem has not been initialized - MAPI_E_CALL_FAILED: A network problem was encountered during the transaction \sa OpenFolder, DeleteFolder, EmptyFolder, GetLastError */ _PUBLIC_ enum MAPISTATUS CreateFolder(mapi_object_t *obj_parent, enum FOLDER_TYPE ulFolderType, const char *name, const char *comment, uint32_t ulFlags, mapi_object_t *obj_child) { struct mapi_request *mapi_request; struct mapi_response *mapi_response; struct EcDoRpc_MAPI_REQ *mapi_req; struct CreateFolder_req request; struct mapi_session *session; NTSTATUS status; enum MAPISTATUS retval; uint32_t size; TALLOC_CTX *mem_ctx; uint8_t logon_id; /* Sanity checks */ OPENCHANGE_RETVAL_IF(!obj_parent, MAPI_E_INVALID_PARAMETER, NULL); OPENCHANGE_RETVAL_IF(!name, MAPI_E_NOT_INITIALIZED, NULL); session = mapi_object_get_session(obj_parent); OPENCHANGE_RETVAL_IF(!session, MAPI_E_INVALID_PARAMETER, NULL); if ((retval = mapi_object_get_logon_id(obj_parent, &logon_id)) != MAPI_E_SUCCESS) return retval; /* Sanitify check on the folder type */ OPENCHANGE_RETVAL_IF((ulFolderType != FOLDER_GENERIC && ulFolderType != FOLDER_SEARCH), MAPI_E_INVALID_PARAMETER, NULL); mem_ctx = talloc_named(session, 0, "CreateFolder"); size = 0; /* Fill the CreateFolder operation */ request.handle_idx = 0x1; size+= sizeof(uint8_t); switch (ulFlags & 0xFFFF0000) { case MAPI_UNICODE: request.ulType = MAPI_FOLDER_UNICODE; break; default: request.ulType = MAPI_FOLDER_ANSI; break; } request.ulFolderType = ulFolderType; size += sizeof(uint16_t); request.ulFlags = (enum FOLDER_FLAGS)((int)ulFlags & 0xFFFF); size += sizeof(uint16_t); switch (request.ulType) { case MAPI_FOLDER_ANSI: request.FolderName.lpszA = name; size += strlen(name) + 1; break; case MAPI_FOLDER_UNICODE: request.FolderName.lpszW = name; size += get_utf8_utf16_conv_length(name); break; } if (comment) { switch(request.ulType) { case MAPI_FOLDER_ANSI: request.FolderComment.lpszA = comment; size += strlen(comment) + 1; break; case MAPI_FOLDER_UNICODE: request.FolderComment.lpszW = comment; size += get_utf8_utf16_conv_length(comment); break; } } else { switch(request.ulType) { case MAPI_FOLDER_ANSI: request.FolderComment.lpszA = ""; size += 1; break; case MAPI_FOLDER_UNICODE: request.FolderComment.lpszW = ""; size += 2; break; } } /* Fill the MAPI_REQ request */ mapi_req = talloc_zero(mem_ctx, struct EcDoRpc_MAPI_REQ); mapi_req->opnum = op_MAPI_CreateFolder; mapi_req->logon_id = logon_id; mapi_req->handle_idx = 0; mapi_req->u.mapi_CreateFolder = request; size += 5; /* Fill the mapi_request structure */ mapi_request = talloc_zero(mem_ctx, struct mapi_request); mapi_request->mapi_len = size + (2 * sizeof(uint32_t)); mapi_request->length = size; mapi_request->mapi_req = mapi_req; mapi_request->handles = talloc_array(mem_ctx, uint32_t, 2); mapi_request->handles[0] = mapi_object_get_handle(obj_parent); mapi_request->handles[1] = 0xffffffff; status = emsmdb_transaction_wrapper(session, mem_ctx, mapi_request, &mapi_response); OPENCHANGE_RETVAL_IF(!NT_STATUS_IS_OK(status), MAPI_E_CALL_FAILED, mem_ctx); OPENCHANGE_RETVAL_IF(!mapi_response->mapi_repl, MAPI_E_CALL_FAILED, mem_ctx); retval = mapi_response->mapi_repl->error_code; OPENCHANGE_RETVAL_IF(retval, retval, mem_ctx); OPENCHANGE_CHECK_NOTIFICATION(session, mapi_response); /* Set object session, handle and id */ mapi_object_init(obj_child); mapi_object_set_session(obj_child, session); mapi_object_set_handle(obj_child, mapi_response->handles[1]); mapi_object_set_id(obj_child, mapi_response->mapi_repl->u.mapi_CreateFolder.folder_id); mapi_object_set_logon_id(obj_child, logon_id); talloc_free(mapi_response); talloc_free(mem_ctx); return MAPI_E_SUCCESS; } /** \details Empty the contents of a folder This function empties (clears) the contents of a specified folder. \param obj_folder the folder to empty \return MAPI_E_SUCCESS on success, otherwise MAPI error. \note Developers may also call GetLastError() to retrieve the last MAPI error code. Possible MAPI error codes are: - MAPI_E_NOT_INITIALIZED: MAPI subsystem has not been initialized - MAPI_E_CALL_FAILED: A network problem was encountered during the transaction \sa OpenFolder, CreateFolder, DeleteFolder, GetLastError */ _PUBLIC_ enum MAPISTATUS EmptyFolder(mapi_object_t *obj_folder) { struct mapi_request *mapi_request; struct mapi_response *mapi_response; struct EcDoRpc_MAPI_REQ *mapi_req; struct EmptyFolder_req request; struct mapi_session *session; NTSTATUS status; enum MAPISTATUS retval; uint32_t size; TALLOC_CTX *mem_ctx; uint8_t logon_id; /* Sanity checks */ OPENCHANGE_RETVAL_IF(!obj_folder, MAPI_E_INVALID_PARAMETER, NULL); session = mapi_object_get_session(obj_folder); OPENCHANGE_RETVAL_IF(!session, MAPI_E_INVALID_PARAMETER, NULL); if ((retval = mapi_object_get_logon_id(obj_folder, &logon_id)) != MAPI_E_SUCCESS) return retval; mem_ctx = talloc_named(session, 0, "EmptyFolder"); size = 0; /* Fill the EmptyFolder operation */ request.WantAsynchronous = 0x0; size += sizeof (uint8_t); request.WantDeleteAssociated = 0x0; size += sizeof (uint8_t); /* Fill the MAPI_REQ request */ mapi_req = talloc_zero(mem_ctx, struct EcDoRpc_MAPI_REQ); mapi_req->opnum = op_MAPI_EmptyFolder; mapi_req->logon_id = logon_id; mapi_req->handle_idx = 0; mapi_req->u.mapi_EmptyFolder = request; size += 5; /* Fill the mapi_request structure */ mapi_request = talloc_zero(mem_ctx, struct mapi_request); mapi_request->mapi_len = size + sizeof(uint32_t); mapi_request->length = size; mapi_request->mapi_req = mapi_req; mapi_request->handles = talloc_array(mem_ctx, uint32_t, 1); mapi_request->handles[0] = mapi_object_get_handle(obj_folder); status = emsmdb_transaction_wrapper(session, mem_ctx, mapi_request, &mapi_response); OPENCHANGE_RETVAL_IF(!NT_STATUS_IS_OK(status), MAPI_E_CALL_FAILED, mem_ctx); OPENCHANGE_RETVAL_IF(!mapi_response->mapi_repl, MAPI_E_CALL_FAILED, mem_ctx); retval = mapi_response->mapi_repl->error_code; OPENCHANGE_RETVAL_IF(retval, retval, mem_ctx); OPENCHANGE_CHECK_NOTIFICATION(session, mapi_response); talloc_free(mapi_response); talloc_free(mem_ctx); return MAPI_E_SUCCESS; } /** \details Delete a folder The function deletes a specified folder. \param obj_parent the folder containing the folder to be deleted \param FolderId the ID of the folder to delete \param DeleteFolderFlags control DeleteFolder operation behavior \param PartialCompletion pointer on a boolean value which specify whether the operation was partially completed or not Possible values for DeleteFolderFlags are: -# DEL_MESSAGES Delete all the messages in the folder -# DEL_FOLDERS Delete the subfolder and all of its subfolders -# DELETE_HARD_DELETE Hard delete the folder \return MAPI_E_SUCCESS on success, otherwise MAPI error. \note Developers may also call GetLastError() to retrieve the last MAPI error code. Possible MAPI error codes are: - MAPI_E_NOT_INITIALIZED: MAPI subsystem has not been initialized - MAPI_E_CALL_FAILED: A network problem was encountered during the transaction \sa OpenFolder, CreateFolder, EmptyFolder, GetLastError */ _PUBLIC_ enum MAPISTATUS DeleteFolder(mapi_object_t *obj_parent, mapi_id_t FolderId, uint8_t DeleteFolderFlags, bool *PartialCompletion) { struct mapi_request *mapi_request; struct mapi_response *mapi_response; struct EcDoRpc_MAPI_REQ *mapi_req; struct DeleteFolder_req request; struct mapi_session *session; NTSTATUS status; enum MAPISTATUS retval; uint32_t size; TALLOC_CTX *mem_ctx; uint8_t logon_id; /* Sanity checks */ OPENCHANGE_RETVAL_IF(!obj_parent, MAPI_E_INVALID_PARAMETER, NULL); session = mapi_object_get_session(obj_parent); OPENCHANGE_RETVAL_IF(!session, MAPI_E_INVALID_PARAMETER, NULL); OPENCHANGE_RETVAL_IF((!(DeleteFolderFlags & 0x1)) && (!(DeleteFolderFlags & 0x4)) && (!(DeleteFolderFlags & 0x10)), MAPI_E_INVALID_PARAMETER, NULL); if ((retval = mapi_object_get_logon_id(obj_parent, &logon_id)) != MAPI_E_SUCCESS) return retval; mem_ctx = talloc_named(session, 0, "DeleteFolder"); size = 0; /* Fill the DeleteFolder operation */ request.DeleteFolderFlags = DeleteFolderFlags; size += sizeof (uint8_t); request.FolderId = FolderId; size += sizeof (uint64_t); /* Fill the MAPI_REQ request */ mapi_req = talloc_zero(mem_ctx, struct EcDoRpc_MAPI_REQ); mapi_req->opnum = op_MAPI_DeleteFolder; mapi_req->logon_id = logon_id; mapi_req->handle_idx = 0; mapi_req->u.mapi_DeleteFolder = request; size += 5; /* Fill the mapi_request structure */ mapi_request = talloc_zero(mem_ctx, struct mapi_request); mapi_request->mapi_len = size + sizeof(uint32_t); mapi_request->length = size; mapi_request->mapi_req = mapi_req; mapi_request->handles = talloc_array(mem_ctx, uint32_t, 1); mapi_request->handles[0] = mapi_object_get_handle(obj_parent); status = emsmdb_transaction_wrapper(session, mem_ctx, mapi_request, &mapi_response); OPENCHANGE_RETVAL_IF(!NT_STATUS_IS_OK(status), MAPI_E_CALL_FAILED, mem_ctx); OPENCHANGE_RETVAL_IF(!mapi_response->mapi_repl, MAPI_E_CALL_FAILED, mem_ctx); retval = mapi_response->mapi_repl->error_code; OPENCHANGE_RETVAL_IF(retval, retval, mem_ctx); OPENCHANGE_CHECK_NOTIFICATION(session, mapi_response); if (PartialCompletion) { *PartialCompletion = mapi_response->mapi_repl->u.mapi_DeleteFolder.PartialCompletion; } talloc_free(mapi_response); talloc_free(mem_ctx); return MAPI_E_SUCCESS; } /** \details Moves a folder \param obj_folder the folder to move \param obj_src source object where the folder to move is stored \param obj_dst destination object where the folder will be moved \param NewFolderName the new folder name in the destination folder \param UseUnicode whether the folder name is unicode encoded or not \return MAPI_E_SUCCESS on success, otherwise MAPI error. \note Developers may also call GetLastError() to retrieve the last MAPI error code. Possible MAPI error codes are: - MAPI_E_NOT_INITIALIZED: MAPI subsystem has not been initialized - MAPI_E_CALL_FAILED: A network problem was encountered during the transaction \sa OpenFolder, CopyFolder */ _PUBLIC_ enum MAPISTATUS MoveFolder(mapi_object_t *obj_folder, mapi_object_t *obj_src, mapi_object_t *obj_dst, char *NewFolderName, bool UseUnicode) { struct mapi_request *mapi_request; struct mapi_response *mapi_response; struct EcDoRpc_MAPI_REQ *mapi_req; struct MoveFolder_req request; struct mapi_session *session[3]; NTSTATUS status; enum MAPISTATUS retval; uint32_t size; TALLOC_CTX *mem_ctx; uint8_t logon_id; /* Sanity checks */ OPENCHANGE_RETVAL_IF(!obj_folder, MAPI_E_INVALID_PARAMETER, NULL); OPENCHANGE_RETVAL_IF(!obj_src, MAPI_E_INVALID_PARAMETER, NULL); OPENCHANGE_RETVAL_IF(!obj_dst, MAPI_E_INVALID_PARAMETER, NULL); OPENCHANGE_RETVAL_IF(!NewFolderName, MAPI_E_INVALID_PARAMETER, NULL); session[0] = mapi_object_get_session(obj_folder); session[1] = mapi_object_get_session(obj_src); session[2] = mapi_object_get_session(obj_dst); OPENCHANGE_RETVAL_IF(!session[0], MAPI_E_INVALID_PARAMETER, NULL); OPENCHANGE_RETVAL_IF(!session[1], MAPI_E_INVALID_PARAMETER, NULL); OPENCHANGE_RETVAL_IF(!session[2], MAPI_E_INVALID_PARAMETER, NULL); if ((retval = mapi_object_get_logon_id(obj_folder, &logon_id)) != MAPI_E_SUCCESS) return retval; mem_ctx = talloc_named(session[0], 0, "MoveFolder"); size = 0; /* Fill the MoveFolder operation */ request.handle_idx = 0x1; size += sizeof (uint8_t); request.WantAsynchronous = 0; size += sizeof (uint8_t); request.UseUnicode = UseUnicode; size += sizeof (uint8_t); request.FolderId = mapi_object_get_id(obj_folder); size += sizeof (uint64_t); if (!request.UseUnicode) { request.NewFolderName.lpszA = NewFolderName; size += strlen(NewFolderName) + 1; } else { request.NewFolderName.lpszW = NewFolderName; size += get_utf8_utf16_conv_length(NewFolderName); } /* Fill the MAPI_REQ request */ mapi_req = talloc_zero(mem_ctx, struct EcDoRpc_MAPI_REQ); mapi_req->opnum = op_MAPI_MoveFolder; mapi_req->logon_id = logon_id; mapi_req->handle_idx = 0; mapi_req->u.mapi_MoveFolder = request; size += 5; /* Fill the mapi_request structure */ mapi_request = talloc(mem_ctx, struct mapi_request); mapi_request->mapi_len = size + sizeof (uint32_t) * 2; mapi_request->length = size; mapi_request->mapi_req = mapi_req; mapi_request->handles = talloc_array(mem_ctx, uint32_t, 2); mapi_request->handles[0] = mapi_object_get_handle(obj_src); mapi_request->handles[1] = mapi_object_get_handle(obj_dst); status = emsmdb_transaction_wrapper(session[0], mem_ctx, mapi_request, &mapi_response); OPENCHANGE_RETVAL_IF(!NT_STATUS_IS_OK(status), MAPI_E_CALL_FAILED, mem_ctx); OPENCHANGE_RETVAL_IF(!mapi_response->mapi_repl, MAPI_E_CALL_FAILED, mem_ctx); retval = mapi_response->mapi_repl->error_code; OPENCHANGE_RETVAL_IF(retval, retval, mem_ctx); OPENCHANGE_CHECK_NOTIFICATION(session[0], mapi_response); talloc_free(mapi_response); talloc_free(mem_ctx); return MAPI_E_SUCCESS; } /** \details Copy a folder \param obj_folder the folder to copy \param obj_src source object where the folder to copy is stored \param obj_dst destination object where the folder will be copied \param NewFolderName the new folder name in the destination folder \param UseUnicode whether the folder name is unicode encoded or not \param WantRecursive whether we should copy folder's subdirectories or not \return MAPI_E_SUCCESS on success, otherwise MAPI error. \note Developer may also call GetLastError() to retrieve the last MAPI error code. Possible MAPI error codes are: - MAPI_E_NOT_INITIALIZED: MAPI subsystem has not been initialized - MAPI_E_CALL_FAILED: A network problem was encountered during the transaction \sa OpenFolder, MoveFolder */ _PUBLIC_ enum MAPISTATUS CopyFolder(mapi_object_t *obj_folder, mapi_object_t *obj_src, mapi_object_t *obj_dst, char *NewFolderName, bool UseUnicode, bool WantRecursive) { struct mapi_request *mapi_request; struct mapi_response *mapi_response; struct EcDoRpc_MAPI_REQ *mapi_req; struct CopyFolder_req request; struct mapi_session *session[3]; NTSTATUS status; enum MAPISTATUS retval; uint32_t size; TALLOC_CTX *mem_ctx; uint8_t logon_id; /* Sanity checks */ OPENCHANGE_RETVAL_IF(!obj_folder, MAPI_E_INVALID_PARAMETER, NULL); OPENCHANGE_RETVAL_IF(!obj_src, MAPI_E_INVALID_PARAMETER, NULL); OPENCHANGE_RETVAL_IF(!obj_dst, MAPI_E_INVALID_PARAMETER, NULL); OPENCHANGE_RETVAL_IF(!NewFolderName, MAPI_E_INVALID_PARAMETER, NULL); session[0] = mapi_object_get_session(obj_folder); session[1] = mapi_object_get_session(obj_src); session[2] = mapi_object_get_session(obj_dst); OPENCHANGE_RETVAL_IF(!session[0], MAPI_E_INVALID_PARAMETER, NULL); OPENCHANGE_RETVAL_IF(!session[1], MAPI_E_INVALID_PARAMETER, NULL); OPENCHANGE_RETVAL_IF(!session[2], MAPI_E_INVALID_PARAMETER, NULL); if ((retval = mapi_object_get_logon_id(obj_folder, &logon_id)) != MAPI_E_SUCCESS) return retval; mem_ctx = talloc_named(session[0], 0, "CopyFolder"); size = 0; /* Fill the CopyFolder operation */ request.handle_idx = 0x1; size += sizeof (uint8_t); request.WantAsynchronous = 0x0; size += sizeof (uint8_t); request.WantRecursive = WantRecursive; size += sizeof (uint8_t); request.UseUnicode = UseUnicode; size += sizeof (uint8_t); request.FolderId = mapi_object_get_id(obj_folder); size += sizeof (uint64_t); if (!request.UseUnicode) { request.NewFolderName.lpszA = NewFolderName; size += strlen(NewFolderName) + 1; } else { request.NewFolderName.lpszW = NewFolderName; size += get_utf8_utf16_conv_length(NewFolderName); } /* Fill the MAPI_REQ request */ mapi_req = talloc_zero(mem_ctx, struct EcDoRpc_MAPI_REQ); mapi_req->opnum = op_MAPI_CopyFolder; mapi_req->logon_id = logon_id; mapi_req->handle_idx = 0; mapi_req->u.mapi_CopyFolder = request; size += 5; /* Fill the mapi_request structure */ mapi_request = talloc(mem_ctx, struct mapi_request); mapi_request->mapi_len = size + sizeof (uint32_t) * 2; mapi_request->length = size; mapi_request->mapi_req = mapi_req; mapi_request->handles = talloc_array(mem_ctx, uint32_t, 2); mapi_request->handles[0] = mapi_object_get_handle(obj_src); mapi_request->handles[1] = mapi_object_get_handle(obj_dst); status = emsmdb_transaction_wrapper(session[0], mem_ctx, mapi_request, &mapi_response); OPENCHANGE_RETVAL_IF(!NT_STATUS_IS_OK(status), MAPI_E_CALL_FAILED, mem_ctx); OPENCHANGE_RETVAL_IF(!mapi_response->mapi_repl, MAPI_E_CALL_FAILED, mem_ctx); retval = mapi_response->mapi_repl->error_code; OPENCHANGE_RETVAL_IF(retval, retval, mem_ctx); OPENCHANGE_CHECK_NOTIFICATION(session[0], mapi_response); talloc_free(mapi_response); talloc_free(mem_ctx); return MAPI_E_SUCCESS; } /** \details Set the Read Flags on one or more messages \param obj_folder the folder containing the messages to change \param ReadFlags a bitmap of flags controlling the changes to PR_PROPERTY_FLAGS \param MessageIdCount the number of messages in the MessageIds array \param MessageIds an array of message ids to set Read flags for Note that the obj_folder argument is the object corresponding to the folder containing the messages (e.g. the result of CreateFolder() or OpenFolder(). It is \em not the content table of that folder (unlike SetMessageReadFlag().) \return MAPI_E_SUCCESS on success, otherwise MAPI error. \note Developers may also call GetLastError() to retrieve the last MAPI error code. Possible MAPI error codes are: - MAPI_E_NOT_INITIALIZED: MAPI subsystem has not been initialized - MAPI_E_CALL_FAILED: A network problem was encountered during the transaction \sa SetMessageReadFlags for a slightly different version, working on a single message */ _PUBLIC_ enum MAPISTATUS SetReadFlags(mapi_object_t *obj_folder, uint8_t ReadFlags, uint16_t MessageIdCount, uint64_t *MessageIds) { TALLOC_CTX *mem_ctx; uint32_t size; struct SetReadFlags_req request; struct EcDoRpc_MAPI_REQ *mapi_req; struct mapi_request *mapi_request; struct mapi_session *session; NTSTATUS status; struct mapi_response *mapi_response; enum MAPISTATUS retval; uint8_t logon_id; /* Sanity checks */ OPENCHANGE_RETVAL_IF(!obj_folder, MAPI_E_INVALID_PARAMETER, NULL); session = mapi_object_get_session(obj_folder); OPENCHANGE_RETVAL_IF(!session, MAPI_E_INVALID_PARAMETER, NULL); if ((retval = mapi_object_get_logon_id(obj_folder, &logon_id)) != MAPI_E_SUCCESS) return retval; mem_ctx = talloc_named(session, 0, "SetReadFlags"); size = 0; /* Fill the SetReadFlags operation */ request.WantAsynchronous = 0; size += sizeof(uint8_t); request.ReadFlags = ReadFlags; size += sizeof(uint8_t); request.MessageIdCount = MessageIdCount; size += sizeof(uint16_t); request.MessageIds = MessageIds; size += sizeof(uint64_t) * MessageIdCount; /* Fill the MAPI_REQ request */ mapi_req = talloc_zero(mem_ctx, struct EcDoRpc_MAPI_REQ); mapi_req->opnum = op_MAPI_SetReadFlags; mapi_req->logon_id = logon_id; mapi_req->handle_idx = 0; mapi_req->u.mapi_SetReadFlags = request; size += 5; /* Fill the mapi_request structure */ mapi_request = talloc_zero(mem_ctx, struct mapi_request); mapi_request->mapi_len = size + sizeof(uint32_t); mapi_request->length = size; mapi_request->mapi_req = mapi_req; mapi_request->handles = talloc_array(mem_ctx, uint32_t, 1); mapi_request->handles[0] = mapi_object_get_handle(obj_folder); status = emsmdb_transaction_wrapper(session, mem_ctx, mapi_request, &mapi_response); OPENCHANGE_RETVAL_IF(!NT_STATUS_IS_OK(status), MAPI_E_CALL_FAILED, mem_ctx); OPENCHANGE_RETVAL_IF(!mapi_response->mapi_repl, MAPI_E_CALL_FAILED, mem_ctx); retval = mapi_response->mapi_repl->error_code; OPENCHANGE_RETVAL_IF(retval, retval, mem_ctx); OPENCHANGE_CHECK_NOTIFICATION(session, mapi_response); /* TODO: parse response */ talloc_free(mapi_response); talloc_free(mem_ctx); return MAPI_E_SUCCESS; } /** \details Hard delete the contents of a folder, including subfolders This function empties (clears) the contents of a specified folder. \param obj_folder the folder to empty \return MAPI_E_SUCCESS on success, otherwise MAPI error. \note Developers may also call GetLastError() to retrieve the last MAPI error code. Possible MAPI error codes are: - MAPI_E_NOT_INITIALIZED: MAPI subsystem has not been initialized - MAPI_E_INVALID_PARAMETER: obj_folder is not valid - MAPI_E_CALL_FAILED: A network problem was encountered during the transaction \sa DeleteFolder, EmptyFolder */ _PUBLIC_ enum MAPISTATUS HardDeleteMessagesAndSubfolders(mapi_object_t *obj_folder) { struct mapi_request *mapi_request; struct mapi_response *mapi_response; struct EcDoRpc_MAPI_REQ *mapi_req; struct HardDeleteMessagesAndSubfolders_req request; struct mapi_session *session; NTSTATUS status; enum MAPISTATUS retval; uint32_t size; TALLOC_CTX *mem_ctx; uint8_t logon_id; /* Sanity checks */ OPENCHANGE_RETVAL_IF(!obj_folder, MAPI_E_INVALID_PARAMETER, NULL); session = mapi_object_get_session(obj_folder); OPENCHANGE_RETVAL_IF(!session, MAPI_E_INVALID_PARAMETER, NULL); if ((retval = mapi_object_get_logon_id(obj_folder, &logon_id)) != MAPI_E_SUCCESS) return retval; mem_ctx = talloc_named(session, 0, "HardDeleteMessagesAndSubfolders"); size = 0; /* Fill the EmptyFolder operation */ request.WantAsynchronous = 0x0; size += sizeof (uint8_t); request.WantDeleteAssociated = 0x0; size += sizeof (uint8_t); /* Fill the MAPI_REQ request */ mapi_req = talloc_zero(mem_ctx, struct EcDoRpc_MAPI_REQ); mapi_req->opnum = op_MAPI_HardDeleteMessagesAndSubfolders; mapi_req->logon_id = logon_id; mapi_req->handle_idx = 0; mapi_req->u.mapi_HardDeleteMessagesAndSubfolders = request; size += 5; /* Fill the mapi_request structure */ mapi_request = talloc_zero(mem_ctx, struct mapi_request); mapi_request->mapi_len = size + sizeof(uint32_t); mapi_request->length = size; mapi_request->mapi_req = mapi_req; mapi_request->handles = talloc_array(mem_ctx, uint32_t, 1); mapi_request->handles[0] = mapi_object_get_handle(obj_folder); status = emsmdb_transaction_wrapper(session, mem_ctx, mapi_request, &mapi_response); OPENCHANGE_RETVAL_IF(!NT_STATUS_IS_OK(status), MAPI_E_CALL_FAILED, mem_ctx); OPENCHANGE_RETVAL_IF(!mapi_response->mapi_repl, MAPI_E_CALL_FAILED, mem_ctx); retval = mapi_response->mapi_repl->error_code; OPENCHANGE_RETVAL_IF(retval, retval, mem_ctx); talloc_free(mapi_response); talloc_free(mem_ctx); return MAPI_E_SUCCESS; } openchange-2.0/libmapi/IMAPIProp.c000066400000000000000000001373261223057412600167610ustar00rootroot00000000000000/* OpenChange MAPI implementation. Copyright (C) Julien Kerihuel 2007-2011. Copyright (C) Brad Hards 2008. This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see . */ #include "libmapi/libmapi.h" #include "libmapi/mapi_nameid.h" #include "libmapi/libmapi_private.h" /** \file IMAPIProp.c \brief Properties and named properties operations. */ /** \details Returns values of one or more properties for an object The function takes a pointer on the object obj, a MAPITAGS array specified in mapitags, and the count of properties. The function returns associated values within the SPropValue values pointer. The array of MAPI property tags can be filled with both known and named properties. \param obj the object to get properties on \param flags Flags for behaviour; can be bit-OR of MAPI_UNICODE and MAPI_PROPS_SKIP_NAMEDID_CHECK constants \param SPropTagArray an array of MAPI property tags \param lpProps the result of the query \param PropCount the count of property tags \return MAPI_E_SUCCESS on success, otherwise MAPI error. \note Developers may also call GetLastError() to retrieve the last MAPI error code. Possible MAPI error codes are: - MAPI_E_NOT_INITIALIZED: MAPI subsystem has not been initialized - MAPI_E_INVALID_PARAMETER: obj or SPropTagArray are null, or the session context could not be obtained - MAPI_E_CALL_FAILED: A network problem was encountered during the transaction \sa SetProps, GetPropList, GetPropsAll, DeleteProps, GetLastError */ _PUBLIC_ enum MAPISTATUS GetProps(mapi_object_t *obj, uint32_t flags, struct SPropTagArray *SPropTagArray, struct SPropValue **lpProps, uint32_t *PropCount) { struct mapi_context *mapi_ctx; struct mapi_request *mapi_request; struct mapi_response *mapi_response; struct EcDoRpc_MAPI_REQ *mapi_req; struct GetProps_req request; struct mapi_session *session; struct mapi_nameid *nameid; struct SPropTagArray properties; struct SPropTagArray *SPropTagArray2 = NULL; NTSTATUS status; enum MAPISTATUS retval; enum MAPISTATUS mapistatus; uint32_t size; TALLOC_CTX *mem_ctx; bool named = false; uint8_t logon_id; /* Sanity checks */ OPENCHANGE_RETVAL_IF(!obj, MAPI_E_INVALID_PARAMETER, NULL); OPENCHANGE_RETVAL_IF(!SPropTagArray, MAPI_E_INVALID_PARAMETER, NULL); session = mapi_object_get_session(obj); OPENCHANGE_RETVAL_IF(!session, MAPI_E_INVALID_PARAMETER, NULL); mapi_ctx = session->mapi_ctx; OPENCHANGE_RETVAL_IF(!mapi_ctx, MAPI_E_NOT_INITIALIZED, NULL); if ((retval = mapi_object_get_logon_id(obj, &logon_id)) != MAPI_E_SUCCESS) return retval; mem_ctx = talloc_named(session, 0, "GetProps"); /* Named property mapping */ nameid = mapi_nameid_new(mem_ctx); if (!(flags & MAPI_PROPS_SKIP_NAMEDID_CHECK)) { retval = mapi_nameid_lookup_SPropTagArray(nameid, SPropTagArray); if (retval == MAPI_E_SUCCESS) { named = true; SPropTagArray2 = talloc_zero(mem_ctx, struct SPropTagArray); retval = GetIDsFromNames(obj, nameid->count, nameid->nameid, 0, &SPropTagArray2); OPENCHANGE_RETVAL_IF(retval, retval, mem_ctx); mapi_nameid_map_SPropTagArray(nameid, SPropTagArray, SPropTagArray2); MAPIFreeBuffer(SPropTagArray2); } } errno = 0; /* Reset */ *PropCount = 0; *lpProps = 0; size = 0; /* Fill the GetProps operation */ request.PropertySizeLimit = 0x0; size += sizeof (uint16_t); request.WantUnicode = (flags & MAPI_UNICODE) != 0 ? true : 0x0; size += sizeof (uint16_t); request.prop_count = (uint16_t) SPropTagArray->cValues; size += sizeof (uint16_t); properties.cValues = SPropTagArray->cValues; properties.aulPropTag = talloc_memdup(mem_ctx, SPropTagArray->aulPropTag, SPropTagArray->cValues * sizeof(enum MAPITAGS)); request.properties = properties.aulPropTag; size += request.prop_count * sizeof(uint32_t); /* Fill the MAPI_REQ request */ mapi_req = talloc_zero(mem_ctx, struct EcDoRpc_MAPI_REQ); mapi_req->opnum = op_MAPI_GetProps; mapi_req->logon_id = logon_id; mapi_req->handle_idx = 0; mapi_req->u.mapi_GetProps = request; size += 5; /* Fill the mapi_request structure */ mapi_request = talloc_zero(mem_ctx, struct mapi_request); mapi_request->mapi_len = size + sizeof (uint32_t); mapi_request->length = size; mapi_request->mapi_req = mapi_req; mapi_request->handles = talloc_array(mem_ctx, uint32_t, 1); mapi_request->handles[0] = mapi_object_get_handle(obj); status = emsmdb_transaction_wrapper(session, mem_ctx, mapi_request, &mapi_response); OPENCHANGE_RETVAL_IF(!NT_STATUS_IS_OK(status), MAPI_E_CALL_FAILED, mem_ctx); OPENCHANGE_RETVAL_IF(!mapi_response->mapi_repl, MAPI_E_CALL_FAILED, mem_ctx); retval = mapi_response->mapi_repl->error_code; OPENCHANGE_RETVAL_IF((retval && retval != MAPI_W_ERRORS_RETURNED), retval, mem_ctx); OPENCHANGE_CHECK_NOTIFICATION(session, mapi_response); /* Read the SPropValue array from data blob. fixme: replace the memory context by the object one. */ if (named == true) { mapi_nameid_unmap_SPropTagArray(nameid, SPropTagArray); } talloc_free(nameid); mapistatus = emsmdb_get_SPropValue((TALLOC_CTX *)session, &mapi_response->mapi_repl->u.mapi_GetProps.prop_data, &properties, lpProps, PropCount, mapi_response->mapi_repl->u.mapi_GetProps.layout); OPENCHANGE_RETVAL_IF(!mapistatus && (retval == MAPI_W_ERRORS_RETURNED), retval, mem_ctx); talloc_free(mapi_response); talloc_free(mem_ctx); return MAPI_E_SUCCESS; } /** \details Set one or more properties on a given object This function sets one or more properties on a specified object. \param obj the object to set properties on \param flags Flags for behaviour; can be MAPI_PROPS_SKIP_NAMEDID_CHECK \param lpProps the list of properties to set \param PropCount the number of properties \return MAPI_E_SUCCESS on success, otherwise MAPI error. \note Developers may also call GetLastError() to retrieve the last MAPI error code. Possible MAPI error codes are: - MAPI_E_NOT_INITIALIZED: MAPI subsystem has not been initialized - MAPI_E_CALL_FAILED: A network problem was encountered during the transaction \sa GetProps, GetPropList, GetPropsAll, DeleteProps, GetLastError */ _PUBLIC_ enum MAPISTATUS SetProps(mapi_object_t *obj, uint32_t flags, struct SPropValue *lpProps, unsigned long PropCount) { TALLOC_CTX *mem_ctx; struct mapi_request *mapi_request; struct mapi_response *mapi_response; struct EcDoRpc_MAPI_REQ *mapi_req; struct SetProps_req request; struct mapi_session *session; struct mapi_nameid *nameid; struct SPropTagArray *SPropTagArray = NULL; NTSTATUS status; enum MAPISTATUS retval; uint32_t size = 0; unsigned long i; struct mapi_SPropValue *mapi_props; bool named = false; uint8_t logon_id; /* Sanity checks */ OPENCHANGE_RETVAL_IF(!obj, MAPI_E_INVALID_PARAMETER, NULL); session = mapi_object_get_session(obj); OPENCHANGE_RETVAL_IF(!session, MAPI_E_INVALID_PARAMETER, NULL); if ((retval = mapi_object_get_logon_id(obj, &logon_id)) != MAPI_E_SUCCESS) return retval; mem_ctx = talloc_named(session, 0, "SetProps"); size = 0; /* Named property mapping */ nameid = mapi_nameid_new(mem_ctx); if (!(flags & MAPI_PROPS_SKIP_NAMEDID_CHECK)) { retval = mapi_nameid_lookup_SPropValue(nameid, lpProps, PropCount); if (retval == MAPI_E_SUCCESS) { named = true; SPropTagArray = talloc_zero(mem_ctx, struct SPropTagArray); retval = GetIDsFromNames(obj, nameid->count, nameid->nameid, 0, &SPropTagArray); OPENCHANGE_RETVAL_IF(retval, retval, mem_ctx); mapi_nameid_map_SPropValue(nameid, lpProps, PropCount, SPropTagArray); MAPIFreeBuffer(SPropTagArray); } } errno = 0; /* build the array */ request.values.lpProps = talloc_array(mem_ctx, struct mapi_SPropValue, PropCount); mapi_props = request.values.lpProps; for (i = 0; i < PropCount; i++) { size += cast_mapi_SPropValue((TALLOC_CTX *)request.values.lpProps, &mapi_props[i], &lpProps[i]); size += sizeof(uint32_t); } request.values.cValues = PropCount; size += sizeof(uint16_t); /* add the size of the subcontext that will be added on ndr layer */ size += sizeof(uint16_t); /* Fill the MAPI_REQ request */ mapi_req = talloc_zero(mem_ctx, struct EcDoRpc_MAPI_REQ); mapi_req->opnum = op_MAPI_SetProps; mapi_req->logon_id = logon_id; mapi_req->handle_idx = 0; mapi_req->u.mapi_SetProps = request; size += 5; /* Fill the mapi_request structure */ mapi_request = talloc_zero(mem_ctx, struct mapi_request); mapi_request->mapi_len = size + sizeof (uint32_t); mapi_request->length = size; mapi_request->mapi_req = mapi_req; mapi_request->handles = talloc_array(mem_ctx, uint32_t, 1); mapi_request->handles[0] = mapi_object_get_handle(obj); status = emsmdb_transaction_wrapper(session, mem_ctx, mapi_request, &mapi_response); OPENCHANGE_RETVAL_IF(!NT_STATUS_IS_OK(status), MAPI_E_CALL_FAILED, mem_ctx); OPENCHANGE_RETVAL_IF(!mapi_response->mapi_repl, MAPI_E_CALL_FAILED, mem_ctx); retval = mapi_response->mapi_repl->error_code; OPENCHANGE_RETVAL_IF(retval, retval, mem_ctx); OPENCHANGE_CHECK_NOTIFICATION(session, mapi_response); if (named == true) { mapi_nameid_unmap_SPropValue(nameid, lpProps, PropCount); } talloc_free(nameid); talloc_free(mapi_response); talloc_free(mem_ctx); return MAPI_E_SUCCESS; } /** \details Makes permanent any changes made to an attachment since the last save operation. \param obj_parent the parent of the object to save changes for \param obj_child the object to save changes for \param flags the access flags to set on the saved object Possible flags: - KeepOpenReadOnly - KeepOpenReadWrite - ForceSave \return MAPI_E_SUCCESS on success, otherwise MAPI error. \note Developers may also call GetLastError() to retrieve the last MAPI error code. Possible MAPI error codes are: - MAPI_E_NOT_INITIALIZED: MAPI subsystem has not been initialized - MAPI_E_CALL_FAILED: A network problem was encountered during the transaction \sa SetProps, ModifyRecipients, GetLastError */ _PUBLIC_ enum MAPISTATUS SaveChangesAttachment(mapi_object_t *obj_parent, mapi_object_t *obj_child, enum SaveFlags flags) { struct mapi_request *mapi_request; struct mapi_response *mapi_response; struct EcDoRpc_MAPI_REQ *mapi_req; struct SaveChangesAttachment_req request; struct mapi_session *session[2]; NTSTATUS status; enum MAPISTATUS retval; uint32_t size = 0; TALLOC_CTX *mem_ctx; uint8_t logon_id; /* Sanity Checks */ OPENCHANGE_RETVAL_IF(!obj_parent, MAPI_E_INVALID_PARAMETER, NULL); OPENCHANGE_RETVAL_IF(!obj_child, MAPI_E_INVALID_PARAMETER, NULL); OPENCHANGE_RETVAL_IF((flags != 0x9) && (flags != 0xA) && (flags != 0xC), MAPI_E_INVALID_PARAMETER, NULL); session[0] = mapi_object_get_session(obj_parent); session[1] = mapi_object_get_session(obj_child); OPENCHANGE_RETVAL_IF(!session[0], MAPI_E_INVALID_PARAMETER, NULL); OPENCHANGE_RETVAL_IF(!session[1], MAPI_E_INVALID_PARAMETER, NULL); OPENCHANGE_RETVAL_IF(session[0] != session[1], MAPI_E_INVALID_PARAMETER, NULL); if ((retval = mapi_object_get_logon_id(obj_parent, &logon_id)) != MAPI_E_SUCCESS) return retval; mem_ctx = talloc_named(session[0], 0, "SaveChangesAttachment"); size = 0; /* Fill the SaveChangesAttachment operation */ request.handle_idx = 0x0; request.SaveFlags = flags; size += sizeof(uint8_t) + sizeof(uint8_t); /* Fill the MAPI_REQ request */ mapi_req = talloc_zero(mem_ctx, struct EcDoRpc_MAPI_REQ); mapi_req->opnum = op_MAPI_SaveChangesAttachment; mapi_req->logon_id = logon_id; mapi_req->handle_idx = 0; mapi_req->u.mapi_SaveChangesAttachment = request; size += 5; /* Fill the mapi_request structure */ mapi_request = talloc_zero(mem_ctx, struct mapi_request); mapi_request->mapi_len = size + sizeof (uint32_t) * 2; mapi_request->length = size; mapi_request->mapi_req = mapi_req; mapi_request->handles = talloc_array(mem_ctx, uint32_t, 2); mapi_request->handles[0] = mapi_object_get_handle(obj_child); mapi_request->handles[1] = mapi_object_get_handle(obj_parent); status = emsmdb_transaction_wrapper(session[0], mem_ctx, mapi_request, &mapi_response); OPENCHANGE_RETVAL_IF(!NT_STATUS_IS_OK(status), MAPI_E_CALL_FAILED, mem_ctx); OPENCHANGE_RETVAL_IF(!mapi_response->mapi_repl, MAPI_E_CALL_FAILED, mem_ctx); retval = mapi_response->mapi_repl->error_code; OPENCHANGE_RETVAL_IF(retval, retval, mem_ctx); OPENCHANGE_CHECK_NOTIFICATION(session[0], mapi_response); talloc_free(mapi_response); talloc_free(mem_ctx); return MAPI_E_SUCCESS; } /** \details Retrieve all the properties associated with a given object \param obj the object to retrieve properties for \param proptags the resulting list of properties associated with the object \return MAPI_E_SUCCESS on success, otherwise MAPI error. \note Developers may also call GetLastError() to retrieve the last MAPI error code. Possible MAPI error codes are: - MAPI_E_NOT_INITIALIZED: MAPI subsystem has not been initialized - MAPI_E_CALL_FAILED: A network problem was encountered during the transaction The developer MUST provide an allocated SPropTagArray structure to the function. \sa GetProps, GetPropsAll, GetLastError */ _PUBLIC_ enum MAPISTATUS GetPropList(mapi_object_t *obj, struct SPropTagArray *proptags) { struct mapi_request *mapi_request; struct mapi_response *mapi_response; struct EcDoRpc_MAPI_REQ *mapi_req; struct mapi_session *session; NTSTATUS status; enum MAPISTATUS retval; uint32_t size = 0; TALLOC_CTX *mem_ctx; uint8_t logon_id; /* sanity checks */ OPENCHANGE_RETVAL_IF(!obj, MAPI_E_INVALID_PARAMETER, NULL); session = mapi_object_get_session(obj); OPENCHANGE_RETVAL_IF(!session, MAPI_E_INVALID_PARAMETER, NULL); if ((retval = mapi_object_get_logon_id(obj, &logon_id)) != MAPI_E_SUCCESS) return retval; mem_ctx = talloc_named(session, 0, "GetPropList"); /* Reset */ proptags->cValues = 0; size = 0; /* Fill the MAPI_REQ request */ mapi_req = talloc_zero(mem_ctx, struct EcDoRpc_MAPI_REQ); mapi_req->opnum = op_MAPI_GetPropList; mapi_req->logon_id = logon_id; mapi_req->handle_idx = 0; size += 5; /* Fill the mapi_request structure */ mapi_request = talloc_zero(mem_ctx, struct mapi_request); mapi_request->mapi_len = size + sizeof (uint32_t) * 1; mapi_request->length = size; mapi_request->mapi_req = mapi_req; mapi_request->handles = talloc_array(mem_ctx, uint32_t, 1); mapi_request->handles[0] = mapi_object_get_handle(obj); status = emsmdb_transaction_wrapper(session, mem_ctx, mapi_request, &mapi_response); OPENCHANGE_RETVAL_IF(!NT_STATUS_IS_OK(status), MAPI_E_CALL_FAILED, mem_ctx); OPENCHANGE_RETVAL_IF(!mapi_response->mapi_repl, MAPI_E_CALL_FAILED, mem_ctx); retval = mapi_response->mapi_repl->error_code; OPENCHANGE_RETVAL_IF(retval, retval, mem_ctx); OPENCHANGE_CHECK_NOTIFICATION(session, mapi_response); /* Get the repsonse */ proptags->cValues = mapi_response->mapi_repl->u.mapi_GetPropList.count; if (proptags->cValues) { size = proptags->cValues * sizeof(enum MAPITAGS); proptags->aulPropTag = talloc_array((TALLOC_CTX *) proptags, enum MAPITAGS, proptags->cValues); memcpy((void*)proptags->aulPropTag, (void*)mapi_response->mapi_repl->u.mapi_GetPropList.tags, size); } talloc_free(mapi_response); talloc_free(mem_ctx); return MAPI_E_SUCCESS; } /** \details Retrieve all properties and values associated with an object This function returns all the properties and and associated values for a given object. \param obj the object to get the properties for \param flags Flags for behaviour; can be a MAPI_UNICODE constant \param properties the properties / values for the object \return MAPI_E_SUCCESS on success, otherwise MAPI error. \note Developers may also call GetLastError() to retrieve the last MAPI error code. Possible MAPI error codes are: - MAPI_E_NOT_INITIALIZED: MAPI subsystem has not been initialized - MAPI_E_CALL_FAILED: A network problem was encountered during the transaction \sa GetProps, GetPropList, GetLastError */ _PUBLIC_ enum MAPISTATUS GetPropsAll(mapi_object_t *obj, uint32_t flags, struct mapi_SPropValue_array *properties) { TALLOC_CTX *mem_ctx; struct mapi_request *mapi_request; struct mapi_response *mapi_response; struct EcDoRpc_MAPI_REQ *mapi_req; struct GetPropsAll_req request; struct GetPropsAll_repl *reply; struct mapi_session *session; NTSTATUS status; enum MAPISTATUS retval; uint32_t size; uint8_t logon_id; /* Sanity checks */ OPENCHANGE_RETVAL_IF(!obj, MAPI_E_INVALID_PARAMETER, NULL); session = mapi_object_get_session(obj); OPENCHANGE_RETVAL_IF(!session, MAPI_E_INVALID_PARAMETER, NULL); if ((retval = mapi_object_get_logon_id(obj, &logon_id)) != MAPI_E_SUCCESS) return retval; mem_ctx = talloc_named(session, 0, "GetPropsAll"); size = 0; /* Fill the GetPropsAll operation */ request.PropertySizeLimit = 0; size += sizeof (uint16_t); request.WantUnicode = (flags & MAPI_UNICODE) != 0 ? true : 0x0; size += sizeof (uint16_t); /* Fill the MAPI_REQ request */ mapi_req = talloc_zero(mem_ctx, struct EcDoRpc_MAPI_REQ); mapi_req->opnum = op_MAPI_GetPropsAll; mapi_req->logon_id = logon_id; mapi_req->handle_idx = 0; mapi_req->u.mapi_GetPropsAll = request; size += 5; /* Fill the mapi_request structure */ mapi_request = talloc_zero(mem_ctx, struct mapi_request); mapi_request->mapi_len = size + sizeof (uint32_t); mapi_request->length = size; mapi_request->mapi_req = mapi_req; mapi_request->handles = talloc_array(mem_ctx, uint32_t, 1); mapi_request->handles[0] = mapi_object_get_handle(obj); status = emsmdb_transaction_wrapper(session, mem_ctx, mapi_request, &mapi_response); OPENCHANGE_RETVAL_IF(!NT_STATUS_IS_OK(status), MAPI_E_CALL_FAILED, mem_ctx); OPENCHANGE_RETVAL_IF(!mapi_response->mapi_repl, MAPI_E_CALL_FAILED, mem_ctx); retval = mapi_response->mapi_repl->error_code; OPENCHANGE_RETVAL_IF(retval, retval, mem_ctx); OPENCHANGE_CHECK_NOTIFICATION(session, mapi_response); reply = &mapi_response->mapi_repl->u.mapi_GetPropsAll; properties->cValues = reply->properties.cValues; properties->lpProps = talloc_steal((TALLOC_CTX *)session, reply->properties.lpProps); talloc_free(mapi_response); talloc_free(mem_ctx); return MAPI_E_SUCCESS; } /** \details Delete one or more properties from an object \param obj the object to remove properties from \param proptags the properties to remove from the given object \return MAPI_E_SUCCESS on success, otherwise MAPI error. \note Developers may also call GetLastError() to retrieve the last MAPI error code. Possible MAPI error codes are: - MAPI_E_NOT_INITIALIZED: MAPI subsystem has not been initialized - MAPI_E_CALL_FAILED: A network problem was encountered during the transaction \sa SetProps, GetLastError */ _PUBLIC_ enum MAPISTATUS DeleteProps(mapi_object_t *obj, struct SPropTagArray *proptags) { TALLOC_CTX *mem_ctx; struct mapi_request *mapi_request; struct mapi_response *mapi_response; struct EcDoRpc_MAPI_REQ *mapi_req; struct DeleteProps_req request; struct mapi_session *session; NTSTATUS status; enum MAPISTATUS retval; uint32_t size; uint8_t logon_id; /* Sanity checks */ OPENCHANGE_RETVAL_IF(!obj, MAPI_E_INVALID_PARAMETER, NULL); OPENCHANGE_RETVAL_IF(!proptags, MAPI_E_INVALID_PARAMETER, NULL); session = mapi_object_get_session(obj); OPENCHANGE_RETVAL_IF(!session, MAPI_E_INVALID_PARAMETER, NULL); if ((retval = mapi_object_get_logon_id(obj, &logon_id)) != MAPI_E_SUCCESS) return retval; mem_ctx = talloc_named(session, 0, "DeleteProps"); size = 0; /* Fill the DeleteProps operation */ request.count = proptags->cValues; size += sizeof(uint16_t); request.tags = proptags->aulPropTag; size += proptags->cValues * sizeof(enum MAPITAGS); /* Fill the MAPI_REQ request */ mapi_req = talloc_zero(mem_ctx, struct EcDoRpc_MAPI_REQ); mapi_req->opnum = op_MAPI_DeleteProps; mapi_req->logon_id = logon_id; mapi_req->handle_idx = 0; mapi_req->u.mapi_DeleteProps = request; size += 5; /* Fill the mapi_request structure */ mapi_request = talloc_zero(mem_ctx, struct mapi_request); mapi_request->mapi_len = size + sizeof (uint32_t); mapi_request->length = size; mapi_request->mapi_req = mapi_req; mapi_request->handles = talloc_array(mem_ctx, uint32_t, 1); mapi_request->handles[0] = mapi_object_get_handle(obj); status = emsmdb_transaction_wrapper(session, mem_ctx, mapi_request, &mapi_response); OPENCHANGE_RETVAL_IF(!NT_STATUS_IS_OK(status), MAPI_E_CALL_FAILED, mem_ctx); OPENCHANGE_RETVAL_IF(!mapi_response->mapi_repl, MAPI_E_CALL_FAILED, mem_ctx); retval = mapi_response->mapi_repl->error_code; OPENCHANGE_RETVAL_IF(retval, retval, mem_ctx); OPENCHANGE_CHECK_NOTIFICATION(session, mapi_response); talloc_free(mapi_response); talloc_free(mem_ctx); return MAPI_E_SUCCESS; } /** \details Set one or more properties on a given object without invoking replication. This function sets one or more properties on a specified object. It is the same as SetProps, except if the object is a folder, where this function does not result in folder properties being replicated. \param obj the object to set properties on \param flags Flags for behaviour; can be MAPI_PROPS_SKIP_NAMEDID_CHECK \param lpProps the list of properties to set \param PropCount the number of properties \return MAPI_E_SUCCESS on success, otherwise MAPI error. \note Developers may also call GetLastError() to retrieve the last MAPI error code. Possible MAPI error codes are: - MAPI_E_NOT_INITIALIZED: MAPI subsystem has not been initialized - MAPI_E_INVALID_PARAMETER: obj is not valid - MAPI_E_CALL_FAILED: A network problem was encountered during the transaction \sa SetProps, DeletePropertiesNoReplicate */ _PUBLIC_ enum MAPISTATUS SetPropertiesNoReplicate(mapi_object_t *obj, uint32_t flags, struct SPropValue *lpProps, unsigned long PropCount) { TALLOC_CTX *mem_ctx; struct mapi_request *mapi_request; struct mapi_response *mapi_response; struct EcDoRpc_MAPI_REQ *mapi_req; struct SetPropertiesNoReplicate_req request; struct mapi_session *session; struct mapi_nameid *nameid; struct SPropTagArray *SPropTagArray = NULL; NTSTATUS status; enum MAPISTATUS retval; uint32_t size = 0; unsigned long i; struct mapi_SPropValue *mapi_props; bool named = false; uint8_t logon_id; /* Sanity checks */ OPENCHANGE_RETVAL_IF(!obj, MAPI_E_INVALID_PARAMETER, NULL); session = mapi_object_get_session(obj); OPENCHANGE_RETVAL_IF(!session, MAPI_E_INVALID_PARAMETER, NULL); if ((retval = mapi_object_get_logon_id(obj, &logon_id)) != MAPI_E_SUCCESS) return retval; mem_ctx = talloc_named(session, 0, "SetPropertiesNoReplicate"); size = 0; /* Named property mapping */ nameid = mapi_nameid_new(mem_ctx); if (!(flags & MAPI_PROPS_SKIP_NAMEDID_CHECK)) { retval = mapi_nameid_lookup_SPropValue(nameid, lpProps, PropCount); if (retval == MAPI_E_SUCCESS) { named = true; SPropTagArray = talloc_zero(mem_ctx, struct SPropTagArray); retval = GetIDsFromNames(obj, nameid->count, nameid->nameid, 0, &SPropTagArray); OPENCHANGE_RETVAL_IF(retval, retval, mem_ctx); mapi_nameid_map_SPropValue(nameid, lpProps, PropCount, SPropTagArray); MAPIFreeBuffer(SPropTagArray); } } errno = 0; /* build the array */ request.values.lpProps = talloc_array(mem_ctx, struct mapi_SPropValue, PropCount); mapi_props = request.values.lpProps; for (i = 0; i < PropCount; i++) { size += cast_mapi_SPropValue((TALLOC_CTX *)request.values.lpProps, &mapi_props[i], &lpProps[i]); size += sizeof(uint32_t); } request.values.cValues = PropCount; size += sizeof(uint16_t); /* add the size of the subcontext that will be added on ndr layer */ size += sizeof(uint16_t); /* Fill the MAPI_REQ request */ mapi_req = talloc_zero(mem_ctx, struct EcDoRpc_MAPI_REQ); mapi_req->opnum = op_MAPI_SetPropertiesNoReplicate; mapi_req->logon_id = logon_id; mapi_req->handle_idx = 0; mapi_req->u.mapi_SetPropertiesNoReplicate = request; size += 5; /* Fill the mapi_request structure */ mapi_request = talloc_zero(mem_ctx, struct mapi_request); mapi_request->mapi_len = size + sizeof (uint32_t); mapi_request->length = size; mapi_request->mapi_req = mapi_req; mapi_request->handles = talloc_array(mem_ctx, uint32_t, 1); mapi_request->handles[0] = mapi_object_get_handle(obj); status = emsmdb_transaction_wrapper(session, mem_ctx, mapi_request, &mapi_response); OPENCHANGE_RETVAL_IF(!NT_STATUS_IS_OK(status), MAPI_E_CALL_FAILED, mem_ctx); OPENCHANGE_RETVAL_IF(!mapi_response->mapi_repl, MAPI_E_CALL_FAILED, mem_ctx); retval = mapi_response->mapi_repl->error_code; OPENCHANGE_RETVAL_IF(retval, retval, mem_ctx); if (named == true) { mapi_nameid_unmap_SPropValue(nameid, lpProps, PropCount); } talloc_free(nameid); talloc_free(mapi_response); talloc_free(mem_ctx); return MAPI_E_SUCCESS; } /** \details Deletes property values from an object without invoking replication. \param obj the object to remove properties from \param proptags the properties to remove from the given object \return MAPI_E_SUCCESS on success, otherwise MAPI error. \note Developers may also call GetLastError() to retrieve the last MAPI error code. Possible MAPI error codes are: - MAPI_E_NOT_INITIALIZED: MAPI subsystem has not been initialized - MAPI_E_CALL_FAILED: A network problem was encountered during the transaction \sa DeleteProps */ _PUBLIC_ enum MAPISTATUS DeletePropertiesNoReplicate(mapi_object_t *obj, struct SPropTagArray *proptags) { TALLOC_CTX *mem_ctx; struct mapi_request *mapi_request; struct mapi_response *mapi_response; struct EcDoRpc_MAPI_REQ *mapi_req; struct DeletePropertiesNoReplicate_req request; struct mapi_session *session; NTSTATUS status; enum MAPISTATUS retval; uint32_t size; uint8_t logon_id; /* Sanity checks */ OPENCHANGE_RETVAL_IF(!obj, MAPI_E_INVALID_PARAMETER, NULL); OPENCHANGE_RETVAL_IF(!proptags, MAPI_E_INVALID_PARAMETER, NULL); session = mapi_object_get_session(obj); OPENCHANGE_RETVAL_IF(!session, MAPI_E_INVALID_PARAMETER, NULL); if ((retval = mapi_object_get_logon_id(obj, &logon_id)) != MAPI_E_SUCCESS) return retval; mem_ctx = talloc_named(session, 0, "DeletePropertiesNoReplicate"); size = 0; /* Fill the DeletePropertiesNoReplicate operation */ request.PropertyTags.cValues = proptags->cValues; size += sizeof (uint16_t); request.PropertyTags.aulPropTag = proptags->aulPropTag; size += proptags->cValues * sizeof (enum MAPITAGS); /* Fill the MAPI_REQ request */ mapi_req = talloc_zero(mem_ctx, struct EcDoRpc_MAPI_REQ); mapi_req->opnum = op_MAPI_DeletePropertiesNoReplicate; mapi_req->logon_id = logon_id; mapi_req->handle_idx = 0; mapi_req->u.mapi_DeletePropertiesNoReplicate = request; size += 5; /* Fill the mapi_request structure */ mapi_request = talloc_zero(mem_ctx, struct mapi_request); mapi_request->mapi_len = size + sizeof (uint32_t); mapi_request->length = size; mapi_request->mapi_req = mapi_req; mapi_request->handles = talloc_array(mem_ctx, uint32_t, 1); mapi_request->handles[0] = mapi_object_get_handle(obj); status = emsmdb_transaction_wrapper(session, mem_ctx, mapi_request, &mapi_response); OPENCHANGE_RETVAL_IF(!NT_STATUS_IS_OK(status), MAPI_E_CALL_FAILED, mem_ctx); OPENCHANGE_RETVAL_IF(!mapi_response->mapi_repl, MAPI_E_CALL_FAILED, mem_ctx); retval = mapi_response->mapi_repl->error_code; OPENCHANGE_RETVAL_IF(retval, retval, mem_ctx); OPENCHANGE_CHECK_NOTIFICATION(session, mapi_response); talloc_free(mapi_response); talloc_free(mem_ctx); return MAPI_E_SUCCESS; } /** \details Provides the property names that correspond to one or more property identifiers. \param obj the object we are retrieving the names from \param ulPropTag the mapped property tag \param count count of property names pointed to by the nameid parameter returned by the server \param nameid pointer to a pointer to property names returned by the server ulPropTag must be a property with type set to PT_NULL \return MAPI_E_SUCCESS on success, otherwise MAPI error. \note Developers may also call GetLastError() to retrieve the last MAPI error code. Possible MAPI error codes are: - MAPI_E_NOT_INITIALIZED: MAPI subsystem has not been initialized - MAPI_E_CALL_FAILED: A network problem was encountered during the transaction \sa GetIDsFromNames, QueryNamesFromIDs */ _PUBLIC_ enum MAPISTATUS GetNamesFromIDs(mapi_object_t *obj, enum MAPITAGS ulPropTag, uint16_t *count, struct MAPINAMEID **nameid) { struct mapi_request *mapi_request; struct mapi_response *mapi_response; struct EcDoRpc_MAPI_REQ *mapi_req; struct GetNamesFromIDs_req request; struct GetNamesFromIDs_repl *reply; struct mapi_session *session; NTSTATUS status; enum MAPISTATUS retval; uint32_t size= 0; TALLOC_CTX *mem_ctx; uint8_t logon_id; /* sanity checks */ OPENCHANGE_RETVAL_IF(!obj, MAPI_E_INVALID_PARAMETER, NULL); session = mapi_object_get_session(obj); OPENCHANGE_RETVAL_IF(!session, MAPI_E_INVALID_PARAMETER, NULL); if ((retval = mapi_object_get_logon_id(obj, &logon_id)) != MAPI_E_SUCCESS) return retval; /* Initialization */ mem_ctx = talloc_named(session, 0, "GetNamesFromIDs"); size = 0; /* Fill the GetNamesFromIDs operation */ request.PropertyIdCount = 0x1; size += sizeof (uint16_t); request.PropertyIds = talloc_array(mem_ctx, uint16_t, request.PropertyIdCount); request.PropertyIds[0] = ((ulPropTag & 0xFFFF0000) >> 16); size += request.PropertyIdCount * sizeof (uint16_t); /* Fill the MAPI_REQ request */ mapi_req = talloc_zero(mem_ctx, struct EcDoRpc_MAPI_REQ); mapi_req->opnum = op_MAPI_GetNamesFromIDs; mapi_req->logon_id = logon_id; mapi_req->handle_idx = 0; mapi_req->u.mapi_GetNamesFromIDs = request; size += 5; /* Fill the mapi_request structure */ mapi_request = talloc_zero(mem_ctx, struct mapi_request); mapi_request->mapi_len = size + sizeof (uint32_t); mapi_request->length = size; mapi_request->mapi_req = mapi_req; mapi_request->handles = talloc_array(mem_ctx, uint32_t, 1); mapi_request->handles[0] = mapi_object_get_handle(obj); status = emsmdb_transaction_wrapper(session, mem_ctx, mapi_request, &mapi_response); OPENCHANGE_RETVAL_IF(!NT_STATUS_IS_OK(status), MAPI_E_CALL_FAILED, mem_ctx); OPENCHANGE_RETVAL_IF(!mapi_response->mapi_repl, MAPI_E_CALL_FAILED, mem_ctx); retval = mapi_response->mapi_repl->error_code; OPENCHANGE_RETVAL_IF(retval, retval, mem_ctx); OPENCHANGE_CHECK_NOTIFICATION(session, mapi_response); /* Fill in count */ reply = &mapi_response->mapi_repl->u.mapi_GetNamesFromIDs; *count = reply->count; /* Fill MAPINAMEID struct */ *nameid = talloc_steal((TALLOC_CTX *)session, reply->nameid); talloc_free(mapi_response); talloc_free(mem_ctx); return MAPI_E_SUCCESS; } /** \details Provides the property identifiers that correspond to one or more property names. \param obj the object we are retrieving the identifiers from \param count count of property names pointed to by the nameid parameter. \param nameid pointer to an array of property names \param ulFlags indicates how the property identifiers should be returned \param proptags pointer to a pointer to an array of property tags containing existing or newly assigned property identifiers. Property types in this array are set to PT_NULL. ulFlags can be set to: - 0 retrieves named properties from the server - MAPI_CREATE create the named properties if they don't exist on the server \note count and nameid parameter can automatically be built using the mapi_nameid API. \return MAPI_E_SUCCESS on success, otherwise MAPI error. \note Developers may also call GetLastError() to retrieve the last MAPI error code. Possible MAPI error codes are: - MAPI_E_NOT_INITIALIZED: MAPI subsystem has not been initialized - MAPI_E_CALL_FAILED: A network problem was encountered during the transaction \sa GetNamesFromIds, QueryNamesFromIDs, mapi_nameid_new */ _PUBLIC_ enum MAPISTATUS GetIDsFromNames(mapi_object_t *obj, uint16_t count, struct MAPINAMEID *nameid, uint32_t ulFlags, struct SPropTagArray **proptags) { struct mapi_request *mapi_request; struct mapi_response *mapi_response; struct EcDoRpc_MAPI_REQ *mapi_req; struct GetIDsFromNames_req request; struct mapi_session *session; NTSTATUS status; enum MAPISTATUS retval; uint32_t size = 0; TALLOC_CTX *mem_ctx; uint32_t i; uint8_t logon_id; /* sanity checks */ OPENCHANGE_RETVAL_IF(!obj, MAPI_E_INVALID_PARAMETER, NULL); OPENCHANGE_RETVAL_IF(!count, MAPI_E_INVALID_PARAMETER, NULL); OPENCHANGE_RETVAL_IF(!nameid, MAPI_E_INVALID_PARAMETER, NULL); OPENCHANGE_RETVAL_IF(!proptags, MAPI_E_INVALID_PARAMETER, NULL); OPENCHANGE_RETVAL_IF(!proptags[0], MAPI_E_INVALID_PARAMETER, NULL); session = mapi_object_get_session(obj); OPENCHANGE_RETVAL_IF(!session, MAPI_E_INVALID_PARAMETER, NULL); if ((retval = mapi_object_get_logon_id(obj, &logon_id)) != MAPI_E_SUCCESS) return retval; /* Initialization */ mem_ctx = talloc_named(session, 0, "GetIDsFromNames"); size = 0; /* Fill the GetIDsFromNames operation */ request.ulFlags = ulFlags; request.count = count; size += sizeof (uint8_t) + sizeof (uint16_t); request.nameid = nameid; for (i = 0; i < count; i++) { size += sizeof (uint8_t) + sizeof (request.nameid[i].lpguid); switch (request.nameid[i].ulKind) { case MNID_ID: size += sizeof (request.nameid[i].kind.lid); break; case MNID_STRING: size += get_utf8_utf16_conv_length(request.nameid[i].kind.lpwstr.Name); size += sizeof (uint8_t); break; default: break; } } /* Fill the MAPI_REQ request */ mapi_req = talloc_zero(mem_ctx, struct EcDoRpc_MAPI_REQ); mapi_req->opnum = op_MAPI_GetIDsFromNames; mapi_req->logon_id = logon_id; mapi_req->handle_idx = 0; mapi_req->u.mapi_GetIDsFromNames = request; size += 5; /* Fill the mapi_request structure */ mapi_request = talloc_zero(mem_ctx, struct mapi_request); mapi_request->mapi_len = size + sizeof (uint32_t); mapi_request->length = size; mapi_request->mapi_req = mapi_req; mapi_request->handles = talloc_array(mem_ctx, uint32_t, 1); mapi_request->handles[0] = mapi_object_get_handle(obj); status = emsmdb_transaction_wrapper(session, mem_ctx, mapi_request, &mapi_response); OPENCHANGE_RETVAL_IF(!NT_STATUS_IS_OK(status), MAPI_E_CALL_FAILED, mem_ctx); OPENCHANGE_RETVAL_IF(!mapi_response->mapi_repl, MAPI_E_CALL_FAILED, mem_ctx); retval = mapi_response->mapi_repl->error_code; OPENCHANGE_RETVAL_IF(retval, retval, mem_ctx); OPENCHANGE_CHECK_NOTIFICATION(session, mapi_response); /* Fill the SPropTagArray */ proptags[0]->cValues = mapi_response->mapi_repl->u.mapi_GetIDsFromNames.count; proptags[0]->aulPropTag = (enum MAPITAGS *) talloc_array((TALLOC_CTX *)proptags[0], uint32_t, proptags[0]->cValues); for (i = 0; i < proptags[0]->cValues; i++) { proptags[0]->aulPropTag[i] = (enum MAPITAGS)(((int)mapi_response->mapi_repl->u.mapi_GetIDsFromNames.propID[i] << 16) | PT_UNSPECIFIED); } talloc_free(mapi_response); talloc_free(mem_ctx); return MAPI_E_SUCCESS; } /** \details Provides the property names that correspond to one or more property identifiers. \param obj the object to obtain the properties for \param queryFlags A set of flags that can restrict the type of properties \param guid a pointer to the GUID for the property set to fetch (null for all property sets. \param count count of property names pointed to by the nameid and propID parameters returned by the server \param propID pointer to an array of property IDs returned by the server \param nameid pointer to an array of property names returned by the server \note queryFlags can be NoStrings (0x1) or NoIds (0x2), neither or both. NoStrings will produce only ID properties, NoIds will produce only named properties, and both will result in no output. \return MAPI_E_SUCCESS on success, otherwise MAPI error. \sa GetNamesFromIDs */ _PUBLIC_ enum MAPISTATUS QueryNamedProperties(mapi_object_t *obj, uint8_t queryFlags, struct GUID *guid, uint16_t *count, uint16_t **propID, struct MAPINAMEID **nameid) { struct mapi_request *mapi_request; struct mapi_response *mapi_response; struct EcDoRpc_MAPI_REQ *mapi_req; struct QueryNamedProperties_req request; struct QueryNamedProperties_repl *reply; struct mapi_session *session; NTSTATUS status; enum MAPISTATUS retval; uint32_t size; TALLOC_CTX *mem_ctx; uint8_t logon_id; /* Sanity checks */ OPENCHANGE_RETVAL_IF(!obj, MAPI_E_INVALID_PARAMETER, NULL); session = mapi_object_get_session(obj); OPENCHANGE_RETVAL_IF(!session, MAPI_E_INVALID_PARAMETER, NULL); if ((retval = mapi_object_get_logon_id(obj, &logon_id)) != MAPI_E_SUCCESS) return retval; /* Initialization */ mem_ctx = talloc_named(session, 0, "QueryNamesFromIDs"); size = 0; /* Fill the QueryNamedProperties operation */ request.QueryFlags = queryFlags; size += sizeof (uint8_t); if (guid) { request.HasGuid = 0x1; /* true */ size += sizeof (uint8_t); request.PropertyGuid.guid = *guid; size += sizeof (struct GUID); } else { request.HasGuid = 0x0; /* false */ size += sizeof (uint8_t); } /* Fill the MAPI_REQ request */ mapi_req = talloc_zero(mem_ctx, struct EcDoRpc_MAPI_REQ); mapi_req->opnum = op_MAPI_QueryNamedProperties; mapi_req->logon_id = logon_id; mapi_req->handle_idx = 0; mapi_req->u.mapi_QueryNamedProperties = request; size += 5; /* Fill the mapi_request structure */ mapi_request = talloc_zero(mem_ctx, struct mapi_request); mapi_request->mapi_len = size + sizeof (uint32_t); mapi_request->length = size; mapi_request->mapi_req = mapi_req; mapi_request->handles = talloc_array(mem_ctx, uint32_t, 1); mapi_request->handles[0] = mapi_object_get_handle(obj); status = emsmdb_transaction_wrapper(session, mem_ctx, mapi_request, &mapi_response); OPENCHANGE_RETVAL_IF(!NT_STATUS_IS_OK(status), MAPI_E_CALL_FAILED, mem_ctx); OPENCHANGE_RETVAL_IF(!mapi_response->mapi_repl, MAPI_E_CALL_FAILED, mem_ctx); retval = mapi_response->mapi_repl->error_code; OPENCHANGE_RETVAL_IF(retval, retval, mem_ctx); OPENCHANGE_CHECK_NOTIFICATION(session, mapi_response); /* Fill [out] parameters */ reply = &mapi_response->mapi_repl->u.mapi_QueryNamedProperties; *count = reply->IdCount; *propID = talloc_steal((TALLOC_CTX *)session, reply->PropertyIds); *nameid = talloc_steal((TALLOC_CTX *)session, reply->PropertyNames); talloc_free(mapi_response); talloc_free(mem_ctx); return MAPI_E_SUCCESS; } /** \details Copy properties from one object to another This function copies (or moves) specified properties from one object to another. \param obj_src the object to copy properties from \param obj_dst the object to set properties on \param copyFlags flags to determine whether to copy or move, and whether to overwrite existing properties. \param tags the list of properties to copy \param problemCount (return value) number of entries in the problems array \param problems (return value) array of problemCount entries. The caller is responsible for freeing the \b problems array using MAPIFreeBuffer(). If the \b problemCount pointer is NULL, then the problems array will not be returned. \return MAPI_E_SUCCESS on success, otherwise MAPI error. \note Developers may also call GetLastError() to retrieve the last MAPI error code. Possible MAPI error codes are: - MAPI_E_NOT_INITIALIZED: MAPI subsystem has not been initialized - MAPI_E_CALL_FAILED: A network problem was encountered during the transaction \sa GetProps, SetProps, DeleteProps, CopyTo, GetLastError */ _PUBLIC_ enum MAPISTATUS CopyProps(mapi_object_t *obj_src, mapi_object_t *obj_dst, struct SPropTagArray *tags, uint8_t copyFlags, uint16_t *problemCount, struct PropertyProblem **problems) { TALLOC_CTX *mem_ctx; struct mapi_request *mapi_request; struct mapi_response *mapi_response; struct EcDoRpc_MAPI_REQ *mapi_req; struct CopyProperties_req request; struct mapi_session *session[2]; NTSTATUS status; enum MAPISTATUS retval; uint32_t size; int i; uint8_t logon_id; /* Sanity checks */ OPENCHANGE_RETVAL_IF(!obj_src, MAPI_E_INVALID_PARAMETER, NULL); OPENCHANGE_RETVAL_IF(!obj_dst, MAPI_E_INVALID_PARAMETER, NULL); OPENCHANGE_RETVAL_IF(!tags, MAPI_E_INVALID_PARAMETER, NULL); session[0] = mapi_object_get_session(obj_src); session[1] = mapi_object_get_session(obj_dst); OPENCHANGE_RETVAL_IF(!session[0], MAPI_E_INVALID_PARAMETER, NULL); OPENCHANGE_RETVAL_IF(!session[1], MAPI_E_INVALID_PARAMETER, NULL); OPENCHANGE_RETVAL_IF(session[0] != session[1], MAPI_E_INVALID_PARAMETER, NULL); if ((retval = mapi_object_get_logon_id(obj_src, &logon_id)) != MAPI_E_SUCCESS) return retval; mem_ctx = talloc_named(session[0], 0, "CopyProps"); size = 0; /* Fill the CopyProperties operation */ request.handle_idx = 0x1; size += sizeof(uint8_t); request.WantAsynchronous = 0x0; size += sizeof(uint8_t); request.CopyFlags = copyFlags; size += sizeof(uint8_t); request.PropertyTags.cValues = tags->cValues; size += sizeof(uint16_t); request.PropertyTags.aulPropTag = tags->aulPropTag; size += tags->cValues * sizeof(enum MAPITAGS); /* Fill the MAPI_REQ request */ mapi_req = talloc_zero(mem_ctx, struct EcDoRpc_MAPI_REQ); mapi_req->opnum = op_MAPI_CopyProperties; mapi_req->logon_id = logon_id; mapi_req->handle_idx = 0; mapi_req->u.mapi_CopyProperties = request; size += 5; // sizeof( EcDoRpc_MAPI_REQ ) /* Fill the mapi_request structure */ mapi_request = talloc_zero(mem_ctx, struct mapi_request); mapi_request->mapi_len = size + sizeof (uint32_t) *2; mapi_request->length = size; mapi_request->mapi_req = mapi_req; mapi_request->handles = talloc_array(mem_ctx, uint32_t, 2); mapi_request->handles[0] = mapi_object_get_handle(obj_src); mapi_request->handles[1] = mapi_object_get_handle(obj_dst); status = emsmdb_transaction_wrapper(session[0], mem_ctx, mapi_request, &mapi_response); OPENCHANGE_RETVAL_IF(!NT_STATUS_IS_OK(status), MAPI_E_CALL_FAILED, mem_ctx); OPENCHANGE_RETVAL_IF(!mapi_response->mapi_repl, MAPI_E_CALL_FAILED, mem_ctx); retval = mapi_response->mapi_repl->error_code; OPENCHANGE_RETVAL_IF(retval, retval, mem_ctx); OPENCHANGE_CHECK_NOTIFICATION(session[0], mapi_response); if (problemCount) { *problemCount = mapi_response->mapi_repl->u.mapi_CopyProperties.PropertyProblemCount; *problems = talloc_array((TALLOC_CTX *)session[0], struct PropertyProblem, *problemCount); for(i = 0; i < *problemCount; i++) { (*(problems[i])).index = mapi_response->mapi_repl->u.mapi_CopyProperties.PropertyProblem[i].index; (*(problems[i])).property_tag = mapi_response->mapi_repl->u.mapi_CopyProperties.PropertyProblem[i].property_tag; (*(problems[i])).error_code = mapi_response->mapi_repl->u.mapi_CopyProperties.PropertyProblem[i].error_code; } } talloc_free(mapi_response); talloc_free(mem_ctx); return MAPI_E_SUCCESS; } /** \details Copy multiple properties from one object to another This function copies (or moves) properties from one object to another. Unlike CopyProperties, this function copies all properties except those identified. \param obj_src the object to copy properties from \param obj_dst the object to set properties on \param excludeTags the list of properties to \em not copy \param copyFlags flags to determine whether to copy or move, and whether to overwrite existing properties. \param problemCount (return value) number of entries in the problems array \param problems (return value) array of problemCount entries. The caller is responsible for freeing the \b problems array using MAPIFreeBuffer(). If the \b problemCount pointer is NULL, then the problems array will not be returned. \return MAPI_E_SUCCESS on success, otherwise MAPI error. \note Developers may also call GetLastError() to retrieve the last MAPI error code. Possible MAPI error codes are: - MAPI_E_NOT_INITIALIZED: MAPI subsystem has not been initialized - MAPI_E_CALL_FAILED: A network problem was encountered during the transaction \sa GetProps, SetProps, DeleteProps, CopyProps */ _PUBLIC_ enum MAPISTATUS CopyTo(mapi_object_t *obj_src, mapi_object_t *obj_dst, struct SPropTagArray *excludeTags, uint8_t copyFlags, uint16_t *problemCount, struct PropertyProblem **problems) { TALLOC_CTX *mem_ctx; struct mapi_request *mapi_request; struct mapi_response *mapi_response; struct EcDoRpc_MAPI_REQ *mapi_req; struct CopyTo_req request; struct mapi_session *session[2]; NTSTATUS status; enum MAPISTATUS retval; uint32_t size; int i; uint8_t logon_id; /* Sanity checks */ OPENCHANGE_RETVAL_IF(!obj_src, MAPI_E_INVALID_PARAMETER, NULL); OPENCHANGE_RETVAL_IF(!obj_dst, MAPI_E_INVALID_PARAMETER, NULL); OPENCHANGE_RETVAL_IF(!excludeTags, MAPI_E_INVALID_PARAMETER, NULL); session[0] = mapi_object_get_session(obj_src); session[1] = mapi_object_get_session(obj_dst); OPENCHANGE_RETVAL_IF(!session[0], MAPI_E_INVALID_PARAMETER, NULL); OPENCHANGE_RETVAL_IF(!session[1], MAPI_E_INVALID_PARAMETER, NULL); OPENCHANGE_RETVAL_IF(session[0] != session[1], MAPI_E_INVALID_PARAMETER, NULL); if ((retval = mapi_object_get_logon_id(obj_src, &logon_id)) != MAPI_E_SUCCESS) return retval; mem_ctx = talloc_named(session[0], 0, "CopyProps"); size = 0; /* Fill the CopyProperties operation */ request.handle_idx = 0x1; size += sizeof(uint8_t); request.WantAsynchronous = 0x0; size += sizeof(uint8_t); request.WantSubObjects = 0x1; size += sizeof(uint8_t); request.CopyFlags = copyFlags; size += sizeof(uint8_t); request.ExcludedTags.cValues = (uint16_t)excludeTags->cValues; size += sizeof(uint16_t); request.ExcludedTags.aulPropTag = excludeTags->aulPropTag; size += excludeTags->cValues * sizeof(enum MAPITAGS); /* Fill the MAPI_REQ request */ mapi_req = talloc_zero(mem_ctx, struct EcDoRpc_MAPI_REQ); mapi_req->opnum = op_MAPI_CopyTo; mapi_req->logon_id = logon_id; mapi_req->handle_idx = 0; mapi_req->u.mapi_CopyTo = request; size += 5; // sizeof( EcDoRpc_MAPI_REQ ) /* Fill the mapi_request structure */ mapi_request = talloc_zero(mem_ctx, struct mapi_request); mapi_request->mapi_len = size + sizeof (uint32_t) *2; mapi_request->length = size; mapi_request->mapi_req = mapi_req; mapi_request->handles = talloc_array(mem_ctx, uint32_t, 2); mapi_request->handles[0] = mapi_object_get_handle(obj_src); mapi_request->handles[1] = mapi_object_get_handle(obj_dst); status = emsmdb_transaction_wrapper(session[0], mem_ctx, mapi_request, &mapi_response); OPENCHANGE_RETVAL_IF(!NT_STATUS_IS_OK(status), MAPI_E_CALL_FAILED, mem_ctx); OPENCHANGE_RETVAL_IF(!mapi_response->mapi_repl, MAPI_E_CALL_FAILED, mem_ctx); retval = mapi_response->mapi_repl->error_code; OPENCHANGE_RETVAL_IF(retval, retval, mem_ctx); OPENCHANGE_CHECK_NOTIFICATION(session[0], mapi_response); if (problemCount) { *problemCount = mapi_response->mapi_repl->u.mapi_CopyTo.PropertyProblemCount; *problems = talloc_array((TALLOC_CTX *)session[0], struct PropertyProblem, *problemCount); for(i=0; i < *problemCount; ++i) { (*(problems[i])).index = mapi_response->mapi_repl->u.mapi_CopyTo.PropertyProblem[i].index; (*(problems[i])).property_tag = mapi_response->mapi_repl->u.mapi_CopyTo.PropertyProblem[i].property_tag; (*(problems[i])).error_code = mapi_response->mapi_repl->u.mapi_CopyTo.PropertyProblem[i].error_code; } } talloc_free(mapi_response); talloc_free(mem_ctx); return MAPI_E_SUCCESS; } openchange-2.0/libmapi/IMAPISession.c000066400000000000000000000376441223057412600174660ustar00rootroot00000000000000/* OpenChange MAPI implementation. Copyright (C) Julien Kerihuel 2007-2008. This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see . */ #include "libmapi/libmapi.h" #include "libmapi/libmapi_private.h" /** \file IMAPISession.c \brief Session initialization options */ static enum MAPISTATUS FindGoodServer(struct mapi_session *session, const char *legacyDN, bool server) { TALLOC_CTX *mem_ctx; enum MAPISTATUS retval; struct nspi_context *nspi; struct StringsArray_r pNames; struct PropertyRowSet_r *PropertyRowSet; struct SPropTagArray *SPropTagArray = NULL; struct PropertyTagArray_r *MId_array; struct StringArray_r *MVszA = NULL; const char *binding = NULL; char *HomeMDB = NULL; char *server_dn; uint32_t i; /* Sanity checks */ OPENCHANGE_RETVAL_IF(!session, MAPI_E_NOT_INITIALIZED, NULL); OPENCHANGE_RETVAL_IF(!session->nspi->ctx, MAPI_E_END_OF_SESSION, NULL); OPENCHANGE_RETVAL_IF(!legacyDN, MAPI_E_INVALID_PARAMETER, NULL); mem_ctx = talloc_named(session, 0, "FindGoodServer"); nspi = (struct nspi_context *) session->nspi->ctx; if (server == false) { /* Step 1. Retrieve a MID for our legacyDN */ pNames.Count = 0x1; pNames.Strings = (const char **) talloc_array(mem_ctx, char *, 1); pNames.Strings[0] = (const char *) talloc_strdup(pNames.Strings, legacyDN); MId_array = talloc_zero(mem_ctx, struct PropertyTagArray_r); retval = nspi_DNToMId(nspi, mem_ctx, &pNames, &MId_array); MAPIFreeBuffer(pNames.Strings); OPENCHANGE_RETVAL_IF(retval, retval, mem_ctx); /* Step 2. Retrieve the Server DN associated to this MId */ PropertyRowSet = talloc_zero(mem_ctx, struct PropertyRowSet_r); SPropTagArray = set_SPropTagArray(mem_ctx, 0x1, PR_EMS_AB_HOME_MDB); retval = nspi_GetProps(nspi, mem_ctx, SPropTagArray, MId_array, &PropertyRowSet); MAPIFreeBuffer(SPropTagArray); MAPIFreeBuffer(MId_array); OPENCHANGE_RETVAL_IF(retval, retval, mem_ctx); HomeMDB = (char *)find_PropertyValue_data(&(PropertyRowSet->aRow[0]), PR_EMS_AB_HOME_MDB); OPENCHANGE_RETVAL_IF(!HomeMDB, MAPI_E_NOT_FOUND, mem_ctx); server_dn = x500_truncate_dn_last_elements(mem_ctx, HomeMDB, 1); MAPIFreeBuffer(PropertyRowSet); } else { server_dn = talloc_strdup(mem_ctx, legacyDN); } /* Step 3. Retrieve the MId for this server DN */ pNames.Count = 0x1; pNames.Strings = (const char **) talloc_array(mem_ctx, char *, 1); pNames.Strings[0] = (const char *) talloc_strdup(pNames.Strings, server_dn); MId_array = talloc_zero(mem_ctx, struct PropertyTagArray_r); retval = nspi_DNToMId(nspi, mem_ctx, &pNames, &MId_array); MAPIFreeBuffer(pNames.Strings); OPENCHANGE_RETVAL_IF(retval, retval, mem_ctx); /* Step 4. Retrieve the binding strings associated to this DN */ PropertyRowSet = talloc_zero(mem_ctx, struct PropertyRowSet_r); SPropTagArray = set_SPropTagArray(mem_ctx, 0x1, PR_EMS_AB_NETWORK_ADDRESS); retval = nspi_GetProps(nspi, mem_ctx, SPropTagArray, MId_array, &PropertyRowSet); MAPIFreeBuffer(SPropTagArray); MAPIFreeBuffer(MId_array); MAPIFreeBuffer(server_dn); OPENCHANGE_RETVAL_IF(retval, retval, mem_ctx); /* Step 5. Extract host from ncacn_ip_tcp binding string */ MVszA = (struct StringArray_r *) find_PropertyValue_data(&(PropertyRowSet->aRow[0]), PR_EMS_AB_NETWORK_ADDRESS); OPENCHANGE_RETVAL_IF(!MVszA, MAPI_E_NOT_FOUND, mem_ctx); for (i = 0; i != MVszA->cValues; i++) { if (!strncasecmp(MVszA->lppszA[i], "ncacn_ip_tcp:", 13)) { binding = MVszA->lppszA[i] + 13; break; } } MAPIFreeBuffer(PropertyRowSet); OPENCHANGE_RETVAL_IF(!binding, MAPI_E_NOT_FOUND, mem_ctx); /* Step 6. Close the existing session and initiates it again */ talloc_free(session->emsmdb); session->emsmdb = talloc_zero(session, struct mapi_provider); talloc_set_destructor((void *)session->emsmdb, (int (*)(void *))emsmdb_disconnect_dtor); session->profile->server = talloc_strdup(session->profile, binding); retval = Logon(session, session->emsmdb, PROVIDER_ID_EMSMDB); OPENCHANGE_RETVAL_IF(retval, retval, NULL); talloc_free(mem_ctx); return MAPI_E_SUCCESS; } /** \details Open the Public Folder store This function opens the public folder store. This allows access to the public folders. \param obj_store the result of opening the store \param session pointer to the MAPI session context \return MAPI_E_SUCCESS on success, otherwise MAPI error. \note Developers may also call GetLastError() to retrieve the last MAPI error code. Possible MAPI error codes are: - MAPI_E_NOT_INITIALIZED: MAPI subsystem has not been initialized - MAPI_E_CALL_FAILED: A network problem was encountered during the transaction \sa MAPIInitialize which is required before opening the store \sa GetLastError to check the result of a failed call, if necessary \sa OpenMsgStore if you need access to the message store folders */ _PUBLIC_ enum MAPISTATUS OpenPublicFolder(struct mapi_session *session, mapi_object_t *obj_store) { struct mapi_request *mapi_request; struct mapi_response *mapi_response; struct EcDoRpc_MAPI_REQ *mapi_req; struct Logon_req request; NTSTATUS status; enum MAPISTATUS retval; uint32_t size; TALLOC_CTX *mem_ctx; mapi_object_store_t *store; uint8_t logon_id; bool retry = false; /* Sanity checks */ OPENCHANGE_RETVAL_IF(!session, MAPI_E_NOT_INITIALIZED, NULL); OPENCHANGE_RETVAL_IF(!session->profile, MAPI_E_NOT_INITIALIZED, NULL); /* Find the first available logon id */ retval = GetNewLogonId(session, &logon_id); OPENCHANGE_RETVAL_IF(retval, MAPI_E_FAILONEPROVIDER, NULL); retry: mem_ctx = talloc_named(session, 0, "OpenPublicFolder"); size = 0; /* Fill the Logon operation */ request.LogonFlags = 0; size += sizeof (uint8_t); request.OpenFlags = PUBLIC; size += sizeof (uint32_t); request.StoreState = 0; size += sizeof (uint32_t); request.EssDN = NULL; /* Fill the MAPI_REQ request */ mapi_req = talloc_zero(mem_ctx, struct EcDoRpc_MAPI_REQ); mapi_req->opnum = op_MAPI_Logon; mapi_req->logon_id = logon_id; mapi_req->handle_idx = 0; mapi_req->u.mapi_Logon = request; size += 5; /* Fill the mapi_request structure */ mapi_request = talloc_zero(mem_ctx, struct mapi_request); mapi_request->mapi_len = size + sizeof (uint32_t) + 2; mapi_request->length = size + 2; mapi_request->mapi_req = mapi_req; mapi_request->handles = talloc_array(mem_ctx, uint32_t, 1); mapi_request->handles[0] = 0xffffffff; status = emsmdb_transaction_wrapper(session, mem_ctx, mapi_request, &mapi_response); OPENCHANGE_RETVAL_IF(!NT_STATUS_IS_OK(status), MAPI_E_CALL_FAILED, mem_ctx); OPENCHANGE_RETVAL_IF(!mapi_response->mapi_repl, MAPI_E_CALL_FAILED, mem_ctx); retval = mapi_response->mapi_repl->error_code; if (retval == ecWrongServer && retry == false && mapi_response->mapi_repl->us.mapi_Logon.ServerName) { retval = FindGoodServer(session, mapi_response->mapi_repl->us.mapi_Logon.ServerName, true); OPENCHANGE_RETVAL_IF(retval, retval, mem_ctx); talloc_free(mem_ctx); retry = true; goto retry; } OPENCHANGE_RETVAL_IF(retval, retval, mem_ctx); OPENCHANGE_CHECK_NOTIFICATION(session, mapi_response); /* retrieve object session, handle and logon_id */ mapi_object_set_session(obj_store, session); mapi_object_set_handle(obj_store, mapi_response->handles[0]); mapi_object_set_logon_id(obj_store, logon_id); mapi_object_set_logon_store(obj_store); /* retrieve store content */ obj_store->private_data = talloc_zero((TALLOC_CTX *)session, mapi_object_store_t); store = (mapi_object_store_t*)obj_store->private_data; OPENCHANGE_RETVAL_IF(!obj_store->private_data, MAPI_E_NOT_ENOUGH_RESOURCES, mem_ctx); store->fid_pf_public_root = mapi_response->mapi_repl->u.mapi_Logon.LogonType.store_pf.Root; store->fid_pf_ipm_subtree = mapi_response->mapi_repl->u.mapi_Logon.LogonType.store_pf.IPMSubTree; store->fid_pf_non_ipm_subtree = mapi_response->mapi_repl->u.mapi_Logon.LogonType.store_pf.NonIPMSubTree; store->fid_pf_EFormsRegistryRoot = mapi_response->mapi_repl->u.mapi_Logon.LogonType.store_pf.EFormsRegistry; store->fid_pf_FreeBusyRoot = mapi_response->mapi_repl->u.mapi_Logon.LogonType.store_pf.FreeBusy; store->fid_pf_OfflineAB = mapi_response->mapi_repl->u.mapi_Logon.LogonType.store_pf.OAB; store->fid_pf_EFormsRegistry = mapi_response->mapi_repl->u.mapi_Logon.LogonType.store_pf.LocalizedEFormsRegistry; store->fid_pf_LocalSiteFreeBusy = mapi_response->mapi_repl->u.mapi_Logon.LogonType.store_pf.LocalFreeBusy; store->fid_pf_LocalSiteOfflineAB = mapi_response->mapi_repl->u.mapi_Logon.LogonType.store_pf.LocalOAB; store->fid_pf_NNTPArticle = mapi_response->mapi_repl->u.mapi_Logon.LogonType.store_pf.NNTPIndex; store->store_type = PublicFolder; store->guid = mapi_response->mapi_repl->u.mapi_Logon.LogonType.store_pf.Guid; talloc_free(mapi_response); talloc_free(mem_ctx); return MAPI_E_SUCCESS; } /** \details Open the Message Store This function opens the main message store. This allows access to the normal user folders. \param session pointer to the MAPI session context \param obj_store the result of opening the store \return MAPI_E_SUCCESS on success, otherwise MAPI error. \note Developers may also call GetLastError() to retrieve the last MAPI error code. Possible MAPI error codes are: - MAPI_E_NOT_INITIALIZED: MAPI subsystem has not been initialized - MAPI_E_CALL_FAILED: A network problem was encountered during the transaction \sa MAPIInitialize which is required before opening the store \sa GetLastError to check the result of a failed call, if necessary \sa OpenPublicFolder if you need access to the public folders */ _PUBLIC_ enum MAPISTATUS OpenMsgStore(struct mapi_session *session, mapi_object_t *obj_store) { enum MAPISTATUS retval; /* sanity checks */ OPENCHANGE_RETVAL_IF(!session, MAPI_E_NOT_INITIALIZED, NULL); OPENCHANGE_RETVAL_IF(!session->profile, MAPI_E_NOT_INITIALIZED, NULL); retval = OpenUserMailbox(session, session->profile->username, obj_store); /* Exchange clustered case */ if ((retval != MAPI_E_SUCCESS) && ((GetLastError() == ecUnknownUser) || (GetLastError() == MAPI_E_LOGON_FAILED))) { errno = 0; retval = OpenUserMailbox(session, NULL, obj_store); } return retval; } /** \details Open another user mailbox This function opens the main message store. This allows access to the normal user folders. \param session pointer to the MAPI session context \param username name of the user's mailbox to open \param obj_store the result of opening the store \return MAPI_E_SUCCESS on success, otherwise MAPI error. \note Developers may also call GetLastError() to retrieve the last MAPI error code. Possible MAPI error codes are: - MAPI_E_NOT_INITIALIZED: MAPI subsystem has not been initialized - MAPI_E_CALL_FAILED: A network problem was encountered during the transaction \sa MAPIInitialize which is required before opening the store \sa GetLastError to check the result of a failed call, if necessary \sa OpenPublicFolder if you need access to the public folders */ _PUBLIC_ enum MAPISTATUS OpenUserMailbox(struct mapi_session *session, const char *username, mapi_object_t *obj_store) { struct mapi_request *mapi_request; struct mapi_response *mapi_response; struct EcDoRpc_MAPI_REQ *mapi_req; struct Logon_req request; NTSTATUS status; enum MAPISTATUS retval; uint32_t size; TALLOC_CTX *mem_ctx; mapi_object_store_t *store; char *mailbox; uint8_t logon_id; bool retry = false; /* sanity checks */ OPENCHANGE_RETVAL_IF(!session, MAPI_E_NOT_INITIALIZED, NULL); OPENCHANGE_RETVAL_IF(!session->profile, MAPI_E_NOT_INITIALIZED, NULL); /* Find the first available logon id */ retval = GetNewLogonId(session, &logon_id); OPENCHANGE_RETVAL_IF(retval, MAPI_E_FAILONEPROVIDER, NULL); retry: mem_ctx = talloc_named(session, 0, "OpenMsgStore"); size = 0; if (!username) { mailbox = talloc_strdup(mem_ctx, session->profile->mailbox); } else { mailbox = talloc_asprintf(mem_ctx, "/o=%s/ou=%s/cn=Recipients/cn=%s", session->profile->org, session->profile->ou, username); } /* Fill the Logon operation */ request.LogonFlags = LogonPrivate; size += sizeof (uint8_t); request.OpenFlags = HOME_LOGON | TAKE_OWNERSHIP | NO_MAIL; size += sizeof (uint32_t); request.StoreState = 0; size += sizeof (uint32_t); request.EssDN = talloc_strdup(mem_ctx, mailbox); size += strlen(request.EssDN) + 1; /* Fill the MAPI_REQ request */ mapi_req = talloc_zero(mem_ctx, struct EcDoRpc_MAPI_REQ); mapi_req->opnum = op_MAPI_Logon; mapi_req->logon_id = logon_id; mapi_req->handle_idx = 0; mapi_req->u.mapi_Logon = request; size += 5; /* Fill the mapi_request structure */ mapi_request = talloc_zero(mem_ctx, struct mapi_request); mapi_request->mapi_len = size + sizeof (uint32_t) + 2; mapi_request->length = size + 2; mapi_request->mapi_req = mapi_req; mapi_request->handles = talloc_array(mem_ctx, uint32_t, 1); mapi_request->handles[0] = 0xffffffff; status = emsmdb_transaction_wrapper(session, mem_ctx, mapi_request, &mapi_response); OPENCHANGE_RETVAL_IF(!NT_STATUS_IS_OK(status), MAPI_E_CALL_FAILED, mem_ctx); OPENCHANGE_RETVAL_IF(!mapi_response->mapi_repl, MAPI_E_CALL_FAILED, mem_ctx); retval = mapi_response->mapi_repl->error_code; if (retval == ecWrongServer && retry == false) { retval = FindGoodServer(session, mailbox, false); OPENCHANGE_RETVAL_IF(retval, retval, mem_ctx); talloc_free(mem_ctx); retry = true; goto retry; } OPENCHANGE_RETVAL_CALL_IF(retval, retval, mapi_response, mem_ctx); OPENCHANGE_CHECK_NOTIFICATION(session, mapi_response); /* set object session, handle and logon_id */ mapi_object_set_session(obj_store, session); mapi_object_set_handle(obj_store, mapi_response->handles[0]); mapi_object_set_logon_id(obj_store, logon_id); mapi_object_set_logon_store(obj_store); /* retrieve store content */ obj_store->private_data = talloc_zero((TALLOC_CTX *)session, mapi_object_store_t); store = (mapi_object_store_t *)obj_store->private_data; OPENCHANGE_RETVAL_IF(!obj_store->private_data, MAPI_E_NOT_ENOUGH_RESOURCES, mem_ctx); store->fid_mailbox_root = mapi_response->mapi_repl->u.mapi_Logon.LogonType.store_mailbox.Root; store->fid_deferred_actions = mapi_response->mapi_repl->u.mapi_Logon.LogonType.store_mailbox.DeferredAction; store->fid_spooler_queue = mapi_response->mapi_repl->u.mapi_Logon.LogonType.store_mailbox.SpoolerQueue; store->fid_top_information_store = mapi_response->mapi_repl->u.mapi_Logon.LogonType.store_mailbox.IPMSubTree; store->fid_inbox = mapi_response->mapi_repl->u.mapi_Logon.LogonType.store_mailbox.Inbox; store->fid_outbox = mapi_response->mapi_repl->u.mapi_Logon.LogonType.store_mailbox.Outbox; store->fid_sent_items = mapi_response->mapi_repl->u.mapi_Logon.LogonType.store_mailbox.SentItems; store->fid_deleted_items = mapi_response->mapi_repl->u.mapi_Logon.LogonType.store_mailbox.DeletedItems; store->fid_common_views = mapi_response->mapi_repl->u.mapi_Logon.LogonType.store_mailbox.CommonViews; store->fid_schedule = mapi_response->mapi_repl->u.mapi_Logon.LogonType.store_mailbox.Schedule; store->fid_search = mapi_response->mapi_repl->u.mapi_Logon.LogonType.store_mailbox.Search; store->fid_views = mapi_response->mapi_repl->u.mapi_Logon.LogonType.store_mailbox.Views; store->fid_shortcuts = mapi_response->mapi_repl->u.mapi_Logon.LogonType.store_mailbox.Shortcuts; store->store_type = PrivateFolderWithoutCachedFids; store->guid = mapi_response->mapi_repl->u.mapi_Logon.LogonType.store_mailbox.MailboxGuid; talloc_free(mapi_response); talloc_free(mem_ctx); return MAPI_E_SUCCESS; } openchange-2.0/libmapi/IMAPISupport.c000066400000000000000000000374401223057412600175110ustar00rootroot00000000000000/* OpenChange MAPI implementation. Copyright (C) Julien Kerihuel 2007-2008. This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see . */ #include "libmapi/libmapi.h" #include "libmapi/libmapi_private.h" /** \file IMAPISupport.c \brief MAPI notifications functions */ /** \details Register an object to receive notifications This function registers notifications on the Exchange server for an object. The function holds the notifications intended to be monitored in as a bitmask. \param obj the object to get notifications for \param connection connection identifier for callback function \param NotificationFlags mask for events to provide notifications for (see below) \param WholeStore whether the scope for this notification is whole database \param notify_callback notification callback function. \param private_data the data to be passed at the callback function when invoked The Notification Flags can take the following values: - fnevCriticalError - fnevNewMail - fnevObjectCreated - fnevObjectDeleted - fnevObjectModified - fnevObjectMoved - fnevObjectCopied - fnevSearchComplete - fnevTableModified - fnevStatusObjectModified - fnevReservedForMapi - fnevExtended \return MAPI_E_SUCCESS on success, otherwise MAPI error. \note Developers may also call GetLastError() to retrieve the last MAPI error code. Possible MAPI error codes are: - MAPI_E_NOT_INITIALIZED: MAPI subsystem has not been initialized - MAPI_E_CALL_FAILED: A network problem was encountered during the transaction \sa RegisterNotification, Unsubscribe, MonitorNotification, GetLastError */ _PUBLIC_ enum MAPISTATUS Subscribe(mapi_object_t *obj, uint32_t *connection, uint16_t NotificationFlags, bool WholeStore, mapi_notify_callback_t notify_callback, void *private_data) { TALLOC_CTX *mem_ctx; struct mapi_request *mapi_request; struct mapi_response *mapi_response; struct EcDoRpc_MAPI_REQ *mapi_req; struct RegisterNotification_req request; struct notifications *notification; struct mapi_notify_ctx *notify_ctx; struct mapi_session *session; enum MAPISTATUS retval; NTSTATUS status; uint32_t size = 0; static uint32_t ulConnection = 0; uint8_t logon_id = 0; /* Sanity Checks */ OPENCHANGE_RETVAL_IF(!connection, MAPI_E_INVALID_PARAMETER, NULL); OPENCHANGE_RETVAL_IF(!obj, MAPI_E_INVALID_PARAMETER, NULL); session = mapi_object_get_session(obj); OPENCHANGE_RETVAL_IF(!session, MAPI_E_INVALID_PARAMETER, NULL); OPENCHANGE_RETVAL_IF(!session->notify_ctx, MAPI_E_INVALID_PARAMETER, NULL); if ((retval = mapi_object_get_logon_id(obj, &logon_id)) != MAPI_E_SUCCESS) return retval; mem_ctx = talloc_named(session, 0, "Subscribe"); /* Fill the Subscribe operation */ request.handle_idx = 0x1; size += sizeof (uint8_t); request.NotificationFlags = NotificationFlags; size += sizeof (uint16_t); request.WantWholeStore = WholeStore; size += sizeof (uint8_t); if (WholeStore == false) { request.FolderId.ID = mapi_object_get_id(obj); size += sizeof (uint64_t); request.MessageId.ID = 0x0; size += sizeof (uint64_t); } /* Fill the MAPI_REQ request */ mapi_req = talloc_zero(mem_ctx, struct EcDoRpc_MAPI_REQ); mapi_req->opnum = op_MAPI_RegisterNotification; mapi_req->logon_id = logon_id; mapi_req->handle_idx = 0; mapi_req->u.mapi_RegisterNotification = request; size += 5; /* Fill the mapi_request structure */ mapi_request = talloc_zero(mem_ctx, struct mapi_request); mapi_request->mapi_len = size + sizeof (uint32_t) * 2; mapi_request->length = size; mapi_request->mapi_req = mapi_req; mapi_request->handles = talloc_array(mem_ctx, uint32_t, 2); mapi_request->handles[0] = mapi_object_get_handle(obj); mapi_request->handles[1] = 0xffffffff; status = emsmdb_transaction_wrapper(session, mem_ctx, mapi_request, &mapi_response); OPENCHANGE_RETVAL_IF(!NT_STATUS_IS_OK(status), MAPI_E_CALL_FAILED, mem_ctx); OPENCHANGE_RETVAL_IF(!mapi_response->mapi_repl, MAPI_E_CALL_FAILED, mem_ctx); retval = mapi_response->mapi_repl->error_code; OPENCHANGE_RETVAL_IF(retval, retval, mem_ctx); /* add the notification to the list */ ulConnection++; notify_ctx = session->notify_ctx; notification = talloc_zero((TALLOC_CTX *)session, struct notifications); notification->ulConnection = ulConnection; notification->parentID = mapi_object_get_id(obj); *connection = ulConnection; /* set notification handle */ mapi_object_init(¬ification->obj_notif); mapi_object_set_handle(¬ification->obj_notif, mapi_response->handles[1]); mapi_object_set_session(¬ification->obj_notif, session); notification->NotificationFlags = NotificationFlags; notification->callback = notify_callback; notification->private_data = private_data; DLIST_ADD(notify_ctx->notifications, notification); talloc_free(mapi_response); talloc_free(mem_ctx); return MAPI_E_SUCCESS; } /** \details Unregister notifications on a given object. Cancel any notification registrations associated with the notify object. This function unregisters notifications on the Exchange server for the object specified with its connection number ulConnection. The function will releases the notification on the Exchange server and remove the entry from the internal notifications list. The function takes a callback to execute when such notification occurs and returns the ulConnection identifier we can use in further management. \return MAPI_E_SUCCESS on success, otherwise MAPI error. \note Developers may also call GetLastError() to retrieve the last MAPI error code. Possible MAPI error codes are: - MAPI_E_NOT_INITIALIZED: MAPI subsystem has not been initialized - MAPI_E_CALL_FAILED: A network problem was encountered during the transaction \sa RegisterNotification, Subscribe, MonitorNotification, GetLastError */ _PUBLIC_ enum MAPISTATUS Unsubscribe(struct mapi_session *session, uint32_t ulConnection) { enum MAPISTATUS retval; struct mapi_notify_ctx *notify_ctx; struct notifications *notification; /* Sanity checks */ OPENCHANGE_RETVAL_IF(!session, MAPI_E_INVALID_PARAMETER, NULL); OPENCHANGE_RETVAL_IF(!session->notify_ctx, MAPI_E_INVALID_PARAMETER, NULL); notify_ctx = session->notify_ctx; notification = notify_ctx->notifications; while (notification) { if (notification->ulConnection == ulConnection) { retval = Release(¬ification->obj_notif); OPENCHANGE_RETVAL_IF(retval, retval, NULL); DLIST_REMOVE(notify_ctx->notifications, notification); break; } notification = notification->next; } return MAPI_E_SUCCESS; } enum MAPISTATUS ProcessNotification(struct mapi_notify_ctx *notify_ctx, struct mapi_response *mapi_response) { struct notifications *notification; void *NotificationData; uint32_t i; OPENCHANGE_RETVAL_IF(!mapi_response, MAPI_E_INVALID_PARAMETER, NULL); OPENCHANGE_RETVAL_IF(!mapi_response->mapi_repl, MAPI_E_SUCCESS, NULL); for (i = 0; mapi_response->mapi_repl[i].opnum; i++) { if (mapi_response->mapi_repl[i].opnum == op_MAPI_Notify) { mapi_handle_t handle = mapi_response->mapi_repl[i].u.mapi_Notify.NotificationHandle; switch(mapi_response->mapi_repl[i].u.mapi_Notify.NotificationType) { case fnevNewMail: case fnevMbit|fnevNewMail: NotificationData = (void *)&(mapi_response->mapi_repl[i].u.mapi_Notify.NotificationData.NewMailNotification); break; case fnevObjectCreated: NotificationData = (void *)&(mapi_response->mapi_repl[i].u.mapi_Notify.NotificationData.FolderCreatedNotification); break; case fnevObjectDeleted: NotificationData = (void *)&(mapi_response->mapi_repl[i].u.mapi_Notify.NotificationData.FolderDeletedNotification); break; case fnevObjectModified: NotificationData = (void *)&(mapi_response->mapi_repl[i].u.mapi_Notify.NotificationData.FolderModifiedNotification_10); break; case fnevObjectMoved: NotificationData = (void *)&(mapi_response->mapi_repl[i].u.mapi_Notify.NotificationData.FolderMoveNotification); break; case fnevObjectCopied: NotificationData = (void *)&(mapi_response->mapi_repl[i].u.mapi_Notify.NotificationData.FolderCopyNotification); break; case fnevSearchComplete: NotificationData = (void *)&(mapi_response->mapi_repl[i].u.mapi_Notify.NotificationData.SearchCompleteNotification); break; case fnevTableModified: NotificationData = (void *)&(mapi_response->mapi_repl[i].u.mapi_Notify.NotificationData.HierarchyTableChange); break; case fnevStatusObjectModified: NotificationData = (void *)&(mapi_response->mapi_repl[i].u.mapi_Notify.NotificationData.IcsNotification); break; case fnevTbit|fnevObjectModified: NotificationData = (void *)&(mapi_response->mapi_repl[i].u.mapi_Notify.NotificationData.FolderModifiedNotification_1010); break; case fnevUbit|fnevObjectModified: NotificationData = (void *)&(mapi_response->mapi_repl[i].u.mapi_Notify.NotificationData.FolderModifiedNotification_2010); break; case fnevTbit|fnevUbit|fnevObjectModified: NotificationData = (void *)&(mapi_response->mapi_repl[i].u.mapi_Notify.NotificationData.FolderModifiedNotification_3010); break; case fnevMbit|fnevObjectCreated: NotificationData = (void *)&(mapi_response->mapi_repl[i].u.mapi_Notify.NotificationData.MessageCreatedNotification); break; case fnevMbit|fnevObjectDeleted: NotificationData = (void *)&(mapi_response->mapi_repl[i].u.mapi_Notify.NotificationData.MessageDeletedNotification); break; case fnevMbit|fnevObjectModified: NotificationData = (void *)&(mapi_response->mapi_repl[i].u.mapi_Notify.NotificationData.MessageModifiedNotification); break; case fnevMbit|fnevObjectMoved: NotificationData = (void *)&(mapi_response->mapi_repl[i].u.mapi_Notify.NotificationData.MessageMoveNotification); break; case fnevMbit|fnevObjectCopied: NotificationData = (void *)&(mapi_response->mapi_repl[i].u.mapi_Notify.NotificationData.MessageCopyNotification); break; case fnevMbit|fnevTableModified: NotificationData = (void *)&(mapi_response->mapi_repl[i].u.mapi_Notify.NotificationData.ContentsTableChange); break; case fnevMbit|fnevSbit|fnevObjectDeleted: NotificationData = (void *)&(mapi_response->mapi_repl[i].u.mapi_Notify.NotificationData.SearchMessageRemovedNotification); break; case fnevMbit|fnevSbit|fnevObjectModified: NotificationData = (void *)&(mapi_response->mapi_repl[i].u.mapi_Notify.NotificationData.SearchMessageModifiedNotification); break; case fnevMbit|fnevSbit|fnevTableModified: NotificationData = (void *)&(mapi_response->mapi_repl[i].u.mapi_Notify.NotificationData.SearchTableChange); break; default: NotificationData = NULL; break; } notification = notify_ctx->notifications; while (notification->ulConnection) { if ((notification->NotificationFlags & mapi_response->mapi_repl[i].u.mapi_Notify.NotificationType) && (handle == mapi_object_get_handle(&(notification->obj_notif)))) { if (notification->callback && NotificationData) { notification->callback(mapi_response->mapi_repl[i].u.mapi_Notify.NotificationType, (void *)NotificationData, notification->private_data); } } notification = notification->next; } } } return MAPI_E_SUCCESS; } /** \details Force notification of pending events This function force the server to send any pending notificaion and process them. These MAPI notifications are next compared to the registered ones and the callback specified in Subscribe() called if it matches. \return MAPI_E_SUCCESS on success, otherwise MAPI error. \note Developers may also call GetLastError() to retrieve the last MAPI error code. Possible MAPI error codes are: - MAPI_E_NOT_INITIALIZED: MAPI subsystem has not been initialized - MAPI_E_CALL_FAILED: A network problem was encountered during the transaction \sa RegisterNotification, Subscribe, Unsubscribe, GetLastError */ _PUBLIC_ enum MAPISTATUS DispatchNotifications(struct mapi_session *session) { struct mapi_response *mapi_response; enum MAPISTATUS retval; NTSTATUS status; /* sanity checks */ OPENCHANGE_RETVAL_IF(!session, MAPI_E_INVALID_PARAMETER, NULL); OPENCHANGE_RETVAL_IF(!session->notify_ctx, MAPI_E_INVALID_PARAMETER, NULL); status = emsmdb_transaction_null((struct emsmdb_context *)session->emsmdb->ctx, &mapi_response); if (!NT_STATUS_IS_OK(status)) return MAPI_E_CALL_FAILED; retval = ProcessNotification(session->notify_ctx, mapi_response); talloc_free(mapi_response); return retval; } /** \details Wait for notifications and process them This function waits for notifications on the UDP port and generates the traffic needed to receive MAPI notifications. These MAPI notifications are next compared to the registered ones and the callback specified in Subscribe() called if it matches. The function takes a callback in cb_data to check if it should continue to process notifications. Timeval in cb_data can be used to control the behavior of select. \return MAPI_E_SUCCESS on success, otherwise MAPI error. \note Developers may also call GetLastError() to retrieve the last MAPI error code. Possible MAPI error codes are: - MAPI_E_NOT_INITIALIZED: MAPI subsystem has not been initialized - MAPI_E_CALL_FAILED: A network problem was encountered during the transaction \sa RegisterNotification, Subscribe, Unsubscribe, GetLastError \note This code is experimental. The current implementation is non-threaded, only supports fnevNewmail and fnevCreatedObject notifications and will block your process until you send a signal. */ _PUBLIC_ enum MAPISTATUS MonitorNotification(struct mapi_session *session, void *private_data, struct mapi_notify_continue_callback_data *cb_data) { struct mapi_response *mapi_response; struct mapi_notify_ctx *notify_ctx; NTSTATUS status; int is_done; int err; char buf[512]; fd_set read_fds; int nread; mapi_notify_continue_callback_t callback; void *data; struct timeval *tv; struct timeval tvi; enum MAPISTATUS retval; /* sanity checks */ OPENCHANGE_RETVAL_IF(!session, MAPI_E_INVALID_PARAMETER, NULL); OPENCHANGE_RETVAL_IF(!session->notify_ctx, MAPI_E_INVALID_PARAMETER, NULL); notify_ctx = session->notify_ctx; callback = cb_data ? cb_data->callback : NULL; data = cb_data ? cb_data->data : NULL; tv = cb_data ? &tvi : NULL; nread = 0; is_done = 0; while (!is_done) { FD_ZERO(&read_fds); FD_SET(notify_ctx->fd, &read_fds); if( cb_data ) tvi = cb_data->tv; err = select(notify_ctx->fd + 1, &read_fds, NULL, NULL, tv); if (FD_ISSET(notify_ctx->fd, &read_fds)) { do { nread = read(notify_ctx->fd, buf, sizeof(buf)); if (nread > 0) { status = emsmdb_transaction_null((struct emsmdb_context *)session->emsmdb->ctx, &mapi_response); if (!NT_STATUS_IS_OK(status)) err = -1; else { retval = ProcessNotification(notify_ctx, mapi_response); OPENCHANGE_RETVAL_IF(retval, retval, NULL); } } } while (nread > 0 && err != -1); } if ((callback != NULL && callback (data)) || err < 0) is_done = 1; } return MAPI_E_SUCCESS; } openchange-2.0/libmapi/IMAPITable.c000066400000000000000000001766641223057412600171000ustar00rootroot00000000000000/* OpenChange MAPI implementation. Copyright (C) Julien Kerihuel 2007-2008. Copyright (C) Brad Hards 2008. This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see . */ #include "libmapi/libmapi.h" #include "libmapi/libmapi_private.h" /** \file IMAPITable.c \brief Operations on tables */ /** \details Defines the particular properties and order of properties to appear as columns in the table. \param obj_table the table the function is setting columns for \param properties the properties intended to be set \return MAPI_E_SUCCESS on success, otherwise MAPI error. \note Developers may also call GetLastError() to retrieve the last MAPI error code. Possible MAPI error codes are: - MAPI_E_NOT_INITIALIZED: MAPI subsystem has not been initialized - MAPI_E_INVALID_PARAMETER: obj_table is NULL - MAPI_W_ERROR_RETURNED: Problem encountered while trying to set one or more properties - MAPI_E_CALL_FAILED: A network problem was encountered during the transaction \sa QueryRows, QueryColumns, SeekRow, GetLastError */ _PUBLIC_ enum MAPISTATUS SetColumns(mapi_object_t *obj_table, struct SPropTagArray *properties) { struct mapi_request *mapi_request; struct mapi_response *mapi_response; struct EcDoRpc_MAPI_REQ *mapi_req; struct SetColumns_req request; struct mapi_session *session; TALLOC_CTX *mem_ctx; NTSTATUS status; enum MAPISTATUS retval; uint32_t size; mapi_object_table_t *table; uint8_t logon_id = 0; /* sanity checks */ OPENCHANGE_RETVAL_IF(!obj_table, MAPI_E_INVALID_PARAMETER, NULL); session = mapi_object_get_session(obj_table); OPENCHANGE_RETVAL_IF(!session, MAPI_E_INVALID_PARAMETER, NULL); if ((retval = mapi_object_get_logon_id(obj_table, &logon_id)) != MAPI_E_SUCCESS) return retval; mem_ctx = talloc_named(session, 0, "SetColumns"); size = 0; /* Fill the SetColumns operation */ request.SetColumnsFlags = SetColumns_TBL_SYNC; request.prop_count = properties->cValues; request.properties = properties->aulPropTag; size += 3 + request.prop_count * sizeof (uint32_t); /* Fill the MAPI_REQ request */ mapi_req = talloc_zero(mem_ctx, struct EcDoRpc_MAPI_REQ); mapi_req->opnum = op_MAPI_SetColumns; mapi_req->logon_id = logon_id; mapi_req->handle_idx = 0; mapi_req->u.mapi_SetColumns = request; size += 5; /* Fill the mapi_request structure */ mapi_request = talloc_zero(mem_ctx, struct mapi_request); mapi_request->mapi_len = size + sizeof (uint32_t); mapi_request->length = size; mapi_request->mapi_req = mapi_req; mapi_request->handles = talloc_array(mem_ctx, uint32_t, 1); mapi_request->handles[0] = mapi_object_get_handle(obj_table); status = emsmdb_transaction_wrapper(session, mem_ctx, mapi_request, &mapi_response); OPENCHANGE_RETVAL_IF(!NT_STATUS_IS_OK(status), MAPI_E_CALL_FAILED, mem_ctx); OPENCHANGE_RETVAL_IF(!mapi_response->mapi_repl, MAPI_E_CALL_FAILED, mem_ctx); retval = mapi_response->mapi_repl->error_code; OPENCHANGE_RETVAL_IF(retval && (retval != MAPI_W_ERRORS_RETURNED), retval, mem_ctx); OPENCHANGE_CHECK_NOTIFICATION(session, mapi_response); /* recopy property tags into table */ /* fixme: obj_table->private_data should be initialized during opening, not here */ if (obj_table->private_data == NULL) { obj_table->private_data = talloc((TALLOC_CTX *)session, mapi_object_table_t); } table = (mapi_object_table_t *)obj_table->private_data; if (table) { table->proptags.cValues = properties->cValues; table->proptags.aulPropTag = talloc_array((TALLOC_CTX *) table, enum MAPITAGS, table->proptags.cValues); memcpy((void*)table->proptags.aulPropTag, (void*)properties->aulPropTag, table->proptags.cValues * sizeof(enum MAPITAGS)); } talloc_free(mapi_response); talloc_free(mem_ctx); return MAPI_E_SUCCESS; } /** \details Returns the approximate cursor position \param obj_table pointer to the table's object \param Numerator pointer to the numerator of the fraction identifying the table position \param Denominator pointer to the denominator of the fraction identifying the table position \return MAPI_E_SUCCESS on success, otherwise MAPI error. \note Developers may also call GetLastError() to retrieve the last MAPI error code. Possible MAPI error codes are: - MAPI_E_NOT_INITIALIZED: MAPI subsystem has not been initialized - MAPI_E_INVALID_PARAMETER: obj_table is NULL - MAPI_E_CALL_FAILED: A network problem was encountered during the transaction \sa QueryRows */ _PUBLIC_ enum MAPISTATUS QueryPosition(mapi_object_t *obj_table, uint32_t *Numerator, uint32_t *Denominator) { struct mapi_request *mapi_request; struct mapi_response *mapi_response; struct EcDoRpc_MAPI_REQ *mapi_req; struct mapi_session *session; NTSTATUS status; enum MAPISTATUS retval; uint32_t size; TALLOC_CTX *mem_ctx; uint8_t logon_id = 0; /* Sanity Checks */ OPENCHANGE_RETVAL_IF(!obj_table, MAPI_E_INVALID_PARAMETER, NULL); session = mapi_object_get_session(obj_table); OPENCHANGE_RETVAL_IF(!session, MAPI_E_INVALID_PARAMETER, NULL); if ((retval = mapi_object_get_logon_id(obj_table, &logon_id)) != MAPI_E_SUCCESS) return retval; mem_ctx = talloc_named(session, 0, "QueryPosition"); size = 0; /* Fill the MAPI_REQ request */ mapi_req = talloc_zero(mem_ctx, struct EcDoRpc_MAPI_REQ); mapi_req->opnum = op_MAPI_QueryPosition; mapi_req->logon_id = logon_id; mapi_req->handle_idx = 0; size += 5; /* Fill the mapi_request structure */ mapi_request = talloc_zero(mem_ctx, struct mapi_request); mapi_request->mapi_len = size + sizeof (uint32_t); mapi_request->length = size; mapi_request->mapi_req = mapi_req; mapi_request->handles = talloc_array(mem_ctx, uint32_t, 1); mapi_request->handles[0] = mapi_object_get_handle(obj_table); status = emsmdb_transaction_wrapper(session, mem_ctx, mapi_request, &mapi_response); OPENCHANGE_RETVAL_IF(!NT_STATUS_IS_OK(status), MAPI_E_CALL_FAILED, mem_ctx); OPENCHANGE_RETVAL_IF(!mapi_response->mapi_repl, MAPI_E_CALL_FAILED, mem_ctx); retval = mapi_response->mapi_repl->error_code; OPENCHANGE_RETVAL_IF(retval, retval, mem_ctx); OPENCHANGE_CHECK_NOTIFICATION(session, mapi_response); if (Numerator) { *Numerator = mapi_response->mapi_repl->u.mapi_QueryPosition.Numerator; } if (Denominator) { *Denominator = mapi_response->mapi_repl->u.mapi_QueryPosition.Denominator; } talloc_free(mapi_response); talloc_free(mem_ctx); return MAPI_E_SUCCESS; } /** \details Returns a RowSet with the properties returned by the server \param obj_table the table we are requesting properties from \param row_count the maximum number of rows to retrieve \param flags flags to use for the query \param rowSet the results flags possible values: - TBL_ADVANCE: index automatically increased from last rowcount - TBL_NOADVANCE: should be used for a single QueryRows call - TBL_ENABLEPACKEDBUFFERS: (not yet implemented) \return MAPI_E_SUCCESS on success, otherwise MAPI error. \note Developers may also call GetLastError() to retrieve the last MAPI error code. Possible MAPI error codes are: - MAPI_E_NOT_INITIALIZED: MAPI subsystem has not been initialized - MAPI_E_INVALID_PARAMETER: obj_table is NULL - MAPI_E_CALL_FAILED: A network problem was encountered during the transaction \sa SetColumns, QueryPosition, QueryColumns, SeekRow */ _PUBLIC_ enum MAPISTATUS QueryRows(mapi_object_t *obj_table, uint16_t row_count, enum QueryRowsFlags flags, struct SRowSet *rowSet) { struct mapi_context *mapi_ctx; struct mapi_request *mapi_request; struct mapi_response *mapi_response; struct EcDoRpc_MAPI_REQ *mapi_req; struct QueryRows_req request; struct QueryRows_repl *reply; struct mapi_session *session; NTSTATUS status; enum MAPISTATUS retval; uint32_t size = 0; TALLOC_CTX *mem_ctx; mapi_object_table_t *table; uint8_t logon_id = 0; /* Sanity checks */ OPENCHANGE_RETVAL_IF(!obj_table, MAPI_E_INVALID_PARAMETER, NULL); session = mapi_object_get_session(obj_table); OPENCHANGE_RETVAL_IF(!session, MAPI_E_INVALID_PARAMETER, NULL); mapi_ctx = session->mapi_ctx; OPENCHANGE_RETVAL_IF(!mapi_ctx, MAPI_E_NOT_INITIALIZED, NULL); if ((retval = mapi_object_get_logon_id(obj_table, &logon_id)) != MAPI_E_SUCCESS) return retval; mem_ctx = talloc_named(session, 0, "QueryRows"); size = 0; /* Fill the QueryRows operation */ request.QueryRowsFlags = flags; /* TODO: search backwards for negative row_count */ request.ForwardRead = 1; request.RowCount = row_count; size += 4; /* Fill the MAPI_REQ request */ mapi_req = talloc_zero(mem_ctx, struct EcDoRpc_MAPI_REQ); mapi_req->opnum = op_MAPI_QueryRows; mapi_req->logon_id = logon_id; mapi_req->handle_idx = 0; mapi_req->u.mapi_QueryRows = request; size += 5; /* Fill the mapi_request structure */ mapi_request = talloc_zero(mem_ctx, struct mapi_request); mapi_request->mapi_len = size + sizeof (uint32_t); mapi_request->length = size; mapi_request->mapi_req = mapi_req; mapi_request->handles = talloc_array(mem_ctx, uint32_t, 1); mapi_request->handles[0] = mapi_object_get_handle(obj_table); status = emsmdb_transaction_wrapper(session, mem_ctx, mapi_request, &mapi_response); OPENCHANGE_RETVAL_IF(!NT_STATUS_IS_OK(status), MAPI_E_CALL_FAILED, mem_ctx); OPENCHANGE_RETVAL_IF(!mapi_response->mapi_repl, MAPI_E_CALL_FAILED, mem_ctx); retval = mapi_response->mapi_repl->error_code; OPENCHANGE_RETVAL_IF(retval, retval, mem_ctx); OPENCHANGE_CHECK_NOTIFICATION(session, mapi_response); /* table contains mapitags from previous SetColumns */ table = (mapi_object_table_t *)obj_table->private_data; OPENCHANGE_RETVAL_IF(!table, MAPI_E_INVALID_OBJECT, mem_ctx); /* TODO: handle Origin */ reply = &mapi_response->mapi_repl->u.mapi_QueryRows; rowSet->cRows = reply->RowCount; rowSet->aRow = talloc_array((TALLOC_CTX *)table, struct SRow, rowSet->cRows); emsmdb_get_SRowSet((TALLOC_CTX *)rowSet->aRow, rowSet, &table->proptags, &reply->RowData); talloc_free(mapi_response); talloc_free(mem_ctx); return MAPI_E_SUCCESS; } /** \details Retrieves the set of columns defined in the current table view \param obj_table the table we are retrieving columns from \param cols pointer to an array of property tags \return MAPI_E_SUCCESS on success, otherwise MAPI error. \note Developers may also call GetLastError() to retrieve the last MAPI error code. Possible MAPI error codes are: - MAPI_E_NOT_INITIALIZED: MAPI subsystem has not been initialized - MAPI_E_INVALID_PARAMETER: obj_table is NULL - MAPI_E_CALL_FAILED: A network problem was encountered during the transaction \sa SetColumns, QueryRows */ _PUBLIC_ enum MAPISTATUS QueryColumns(mapi_object_t *obj_table, struct SPropTagArray *cols) { struct mapi_request *mapi_request; struct mapi_response *mapi_response; struct EcDoRpc_MAPI_REQ *mapi_req; struct QueryColumnsAll_repl *reply; struct mapi_session *session; NTSTATUS status; enum MAPISTATUS retval; uint32_t size; TALLOC_CTX *mem_ctx; mapi_object_table_t *table; uint8_t logon_id = 0; /* Sanity checks */ OPENCHANGE_RETVAL_IF(!obj_table, MAPI_E_INVALID_PARAMETER, NULL); session = mapi_object_get_session(obj_table); OPENCHANGE_RETVAL_IF(!obj_table, MAPI_E_INVALID_PARAMETER, NULL); if ((retval = mapi_object_get_logon_id(obj_table, &logon_id)) != MAPI_E_SUCCESS) return retval; mem_ctx = talloc_named(session, 0, "QueryColumns"); cols->cValues = 0; size = 0; /* Fill the MAPI_REQ request */ mapi_req = talloc_zero(mem_ctx, struct EcDoRpc_MAPI_REQ); mapi_req->opnum = op_MAPI_QueryColumnsAll; mapi_req->logon_id = logon_id; mapi_req->handle_idx = 0; size += 5; /* Fill the mapi_request structure */ mapi_request = talloc_zero(mem_ctx, struct mapi_request); mapi_request->mapi_len = size + sizeof (uint32_t); mapi_request->length = size; mapi_request->mapi_req = mapi_req; mapi_request->handles = talloc_array(mem_ctx, uint32_t, 1); mapi_request->handles[0] = mapi_object_get_handle(obj_table); status = emsmdb_transaction_wrapper(session, mem_ctx, mapi_request, &mapi_response); OPENCHANGE_RETVAL_IF(!NT_STATUS_IS_OK(status), MAPI_E_CALL_FAILED, mem_ctx); OPENCHANGE_RETVAL_IF(!mapi_response->mapi_repl, MAPI_E_CALL_FAILED, mem_ctx); retval = mapi_response->mapi_repl->error_code; OPENCHANGE_RETVAL_IF(retval, retval, mem_ctx); OPENCHANGE_CHECK_NOTIFICATION(session, mapi_response); /* get columns SPropTagArray */ table = (mapi_object_table_t *)obj_table->private_data; OPENCHANGE_RETVAL_IF(!table, MAPI_E_INVALID_OBJECT, mem_ctx); reply = &mapi_response->mapi_repl->u.mapi_QueryColumnsAll; cols->cValues = reply->PropertyTagCount; cols->aulPropTag = talloc_array((TALLOC_CTX *)table, enum MAPITAGS, cols->cValues); memcpy((void *)cols->aulPropTag, (const void *)reply->PropertyTags, cols->cValues * sizeof(enum MAPITAGS)); talloc_free(mapi_response); talloc_free(mem_ctx); return MAPI_E_SUCCESS; } /** \details Move the table cursor at a specific location \param obj_table the table we are moving cursor on \param origin the table position where we start to seek \param offset a particular offset in the table \param row the position of the seeked row is returned in rows origin possible values: - BOOKMARK_BEGINNING: Beginning of the table - BOOKMARK_CURRENT: Current position in the table - BOKMARK_END: End of the table \return MAPI_E_SUCCESS on success, otherwise MAPI error. \note Developers may also call GetLastError() to retrieve the last MAPI error code. Possible MAPI error codes are: - MAPI_E_NOT_INITIALIZED: MAPI subsystem has not been initialized - MAPI_E_INVALID_PARAMETER: obj_table is NULL - MAPI_E_CALL_FAILED: A network problem was encountered during the transaction \sa SetColumns, QueryRows */ _PUBLIC_ enum MAPISTATUS SeekRow(mapi_object_t *obj_table, enum BOOKMARK origin, int32_t offset, uint32_t *row) { struct mapi_request *mapi_request; struct mapi_response *mapi_response; struct EcDoRpc_MAPI_REQ *mapi_req; struct SeekRow_req request; struct SeekRow_repl *reply; struct mapi_session *session; NTSTATUS status; enum MAPISTATUS retval; uint32_t size; TALLOC_CTX *mem_ctx; uint8_t logon_id = 0; /* Sanity checks */ OPENCHANGE_RETVAL_IF(!obj_table, MAPI_E_INVALID_PARAMETER, NULL); session = mapi_object_get_session(obj_table); OPENCHANGE_RETVAL_IF(!session, MAPI_E_INVALID_PARAMETER, NULL); if ((retval = mapi_object_get_logon_id(obj_table, &logon_id)) != MAPI_E_SUCCESS) return retval; mem_ctx = talloc_named(session, 0, "SeekRow"); *row = 0; /* Fill the SeekRow operation */ size = 0; request.origin = origin; size += 1; request.offset = offset; size += 4; request.WantRowMovedCount = 0; size += 1; /* Fill the MAPI_REQ request */ mapi_req = talloc_zero(mem_ctx, struct EcDoRpc_MAPI_REQ); mapi_req->opnum = op_MAPI_SeekRow; mapi_req->logon_id = logon_id; mapi_req->handle_idx = 0; mapi_req->u.mapi_SeekRow = request; size += 5; /* Fill the mapi_request structure */ mapi_request = talloc_zero(mem_ctx, struct mapi_request); mapi_request->mapi_len = size + sizeof (uint32_t); mapi_request->length = size; mapi_request->mapi_req = mapi_req; mapi_request->handles = talloc_array(mem_ctx, uint32_t, 1); mapi_request->handles[0] = mapi_object_get_handle(obj_table); status = emsmdb_transaction_wrapper(session, mem_ctx, mapi_request, &mapi_response); OPENCHANGE_RETVAL_IF(!NT_STATUS_IS_OK(status), MAPI_E_CALL_FAILED, mem_ctx); OPENCHANGE_RETVAL_IF(!mapi_response->mapi_repl, MAPI_E_CALL_FAILED, mem_ctx); retval = mapi_response->mapi_repl->error_code; OPENCHANGE_RETVAL_IF(retval, retval, mem_ctx); OPENCHANGE_CHECK_NOTIFICATION(session, mapi_response); reply = &mapi_response->mapi_repl->u.mapi_SeekRow; *row = reply->RowsSought; talloc_free(mapi_response); talloc_free(mem_ctx); return MAPI_E_SUCCESS; } /** \details Move the table cursor at a specific location given a bookmark \param obj_table the table we are moving cursor on \param lpbkPosition the bookmarked position \param RowCount a relative number of rows to the bookmark \param row the position of the seeked row is returned in rows \return MAPI_E_SUCCESS on success, otherwise MAPI error. \note Developers may also call GetLastError() to retrieve the last MAPI error code. Possible MAPI error codes are: - MAPI_E_NOT_INITIALIZED: MAPI subsystem has not been initialized - MAPI_E_INVALID_PARAMETER: obj_table is NULL - MAPI_E_INVALID_BOOKMARK: The bookmark specified is invalid or beyond the last row requested - MAPI_E_CALL_FAILED: A network problem was encountered during the transaction \sa CreateBookmark, FreeBookmark */ _PUBLIC_ enum MAPISTATUS SeekRowBookmark(mapi_object_t *obj_table, uint32_t lpbkPosition, uint32_t RowCount, uint32_t *row) { struct mapi_request *mapi_request; struct mapi_response *mapi_response; struct EcDoRpc_MAPI_REQ *mapi_req; struct SeekRowBookmark_req request; struct SeekRowBookmark_repl *reply; struct mapi_session *session; NTSTATUS status; enum MAPISTATUS retval; uint32_t size; TALLOC_CTX *mem_ctx; struct SBinary_short bin; uint8_t logon_id = 0; /* Sanity checks */ OPENCHANGE_RETVAL_IF(!obj_table, MAPI_E_INVALID_PARAMETER, NULL); session = mapi_object_get_session(obj_table); OPENCHANGE_RETVAL_IF(!session, MAPI_E_INVALID_PARAMETER, NULL); retval = mapi_object_bookmark_find(obj_table, lpbkPosition, &bin); OPENCHANGE_RETVAL_IF(retval, MAPI_E_INVALID_BOOKMARK, NULL); if ((retval = mapi_object_get_logon_id(obj_table, &logon_id)) != MAPI_E_SUCCESS) return retval; mem_ctx = talloc_named(session, 0, "SeekRowBookmark"); /* Fill the SeekRowBookmark operation */ size = 0; request.Bookmark.cb = bin.cb; size += sizeof (uint16_t); request.Bookmark.lpb = bin.lpb; size += bin.cb; request.RowCount = RowCount; size += sizeof (uint32_t); request.WantRowMovedCount = 0x1; size += sizeof (uint8_t); /* Fill the MAPI_REQ request */ mapi_req = talloc_zero(mem_ctx, struct EcDoRpc_MAPI_REQ); mapi_req->opnum = op_MAPI_SeekRowBookmark; mapi_req->logon_id = logon_id; mapi_req->handle_idx = 0; mapi_req->u.mapi_SeekRowBookmark = request; size += 5; /* Fill the mapi_request structure */ mapi_request = talloc_zero(mem_ctx, struct mapi_request); mapi_request->mapi_len = size + sizeof (uint32_t); mapi_request->length = size; mapi_request->mapi_req = mapi_req; mapi_request->handles = talloc_array(mem_ctx, uint32_t, 1); mapi_request->handles[0] = mapi_object_get_handle(obj_table); status = emsmdb_transaction_wrapper(session, mem_ctx, mapi_request, &mapi_response); OPENCHANGE_RETVAL_IF(!NT_STATUS_IS_OK(status), MAPI_E_CALL_FAILED, mem_ctx); OPENCHANGE_RETVAL_IF(!mapi_response->mapi_repl, MAPI_E_CALL_FAILED, mem_ctx); retval = mapi_response->mapi_repl->error_code; OPENCHANGE_RETVAL_IF(retval, retval, mem_ctx); OPENCHANGE_CHECK_NOTIFICATION(session, mapi_response); reply = &mapi_response->mapi_repl->u.mapi_SeekRowBookmark; *row = reply->RowsSought; talloc_free(mapi_response); talloc_free(mem_ctx); return MAPI_E_SUCCESS; } /** \details Moves the cursor to an approximate fractional position in the table \param obj_table the table we are moving cursor on \param ulNumerator numerator of the fraction representing the table position. \param ulDenominator denominator of the fraction representing the table position - If ulDenominator is NULL, then SeekRowApprox returns MAPI_E_INVALID_PARAMETER. - If ulNumerator is NULL, then SeekRowApprox moves the cursor to the beginning of the table. In such situation, SeekRowApprox call is similar to SeekRow with BOOKMARK_BEGINNING - If ulNumerator and ulDenominator have the same value, then SeekRowApprox moves the cursor to the end of the table. In such situation, SeekRowApprox call is similar to SeekRow with BOOKMARK_END \return MAPI_E_SUCCESS on success, otherwise MAPI error. \note Developers may also call GetLastError() to retrieve the last MAPI error code. Possible MAPI error codes are: - MAPI_E_NOT_INITIALIZED: MAPI subsystem has not been initialized - MAPI_E_INVALID_PARAMETER: obj_table is NULL - MAPI_E_CALL_FAILED: A network problem was encountered during the transaction \sa SeekRow, SeekRowBookmark */ _PUBLIC_ enum MAPISTATUS SeekRowApprox(mapi_object_t *obj_table, uint32_t ulNumerator, uint32_t ulDenominator) { struct mapi_request *mapi_request; struct mapi_response *mapi_response; struct EcDoRpc_MAPI_REQ *mapi_req; struct SeekRowApprox_req request; struct mapi_session *session; NTSTATUS status; enum MAPISTATUS retval; uint32_t size; TALLOC_CTX *mem_ctx; uint8_t logon_id = 0; /* Sanity checks */ OPENCHANGE_RETVAL_IF(!obj_table, MAPI_E_INVALID_PARAMETER, NULL); OPENCHANGE_RETVAL_IF(!ulDenominator, MAPI_E_INVALID_PARAMETER, NULL); session = mapi_object_get_session(obj_table); OPENCHANGE_RETVAL_IF(!session, MAPI_E_INVALID_PARAMETER, NULL); if ((retval = mapi_object_get_logon_id(obj_table, &logon_id)) != MAPI_E_SUCCESS) return retval; mem_ctx = talloc_named(session, 0, "SeekRowApprox"); /* Fill the SeekRowApprox operation */ size = 0; request.ulNumerator = ulNumerator; size += sizeof (uint32_t); request.ulDenominator = ulDenominator; size += sizeof (uint32_t); /* Fill the MAPI_REQ request */ mapi_req = talloc_zero(mem_ctx, struct EcDoRpc_MAPI_REQ); mapi_req->opnum = op_MAPI_SeekRowApprox; mapi_req->logon_id = logon_id; mapi_req->handle_idx = 0; mapi_req->u.mapi_SeekRowApprox = request; size += 5; /* Fill the mapi_request structure */ mapi_request = talloc_zero(mem_ctx, struct mapi_request); mapi_request->mapi_len = size + sizeof (uint32_t); mapi_request->length = size; mapi_request->mapi_req = mapi_req; mapi_request->handles = talloc_array(mem_ctx, uint32_t, 1); mapi_request->handles[0] = mapi_object_get_handle(obj_table); status = emsmdb_transaction_wrapper(session, mem_ctx, mapi_request, &mapi_response); OPENCHANGE_RETVAL_IF(!NT_STATUS_IS_OK(status), MAPI_E_CALL_FAILED, mem_ctx); OPENCHANGE_RETVAL_IF(!mapi_response->mapi_repl, MAPI_E_CALL_FAILED, mem_ctx); retval = mapi_response->mapi_repl->error_code; OPENCHANGE_RETVAL_IF(retval, retval, mem_ctx); OPENCHANGE_CHECK_NOTIFICATION(session, mapi_response); talloc_free(mapi_response); talloc_free(mem_ctx); return MAPI_E_SUCCESS; } /** \details Marks the table current position \param obj_table the table we are creating a bookmark in \param lpbkPosition pointer to the bookmark value. This bookmark can be passed in a call to the SeekRowBookmark method \return MAPI_E_SUCCESS on success, otherwise MAPI error. \note Developers may also call GetLastError() to retrieve the last MAPI error code. Possible MAPI error codes are: - MAPI_E_NOT_INITIALIZED: MAPI subsystem has not been initialized - MAPI_E_INVALID_PARAMETER: obj_table is NULL - MAPI_E_CALL_FAILED: A network problem was encountered during the transaction \sa SeekRowBookmark, FreeBookmark */ _PUBLIC_ enum MAPISTATUS CreateBookmark(mapi_object_t *obj_table, uint32_t *lpbkPosition) { struct mapi_request *mapi_request; struct mapi_response *mapi_response; struct EcDoRpc_MAPI_REQ *mapi_req; struct CreateBookmark_repl *reply; struct mapi_session *session; NTSTATUS status; enum MAPISTATUS retval; uint32_t size; TALLOC_CTX *mem_ctx; mapi_object_table_t *mapi_table; mapi_object_bookmark_t *bookmark; uint8_t logon_id = 0; /* Sanity checks */ OPENCHANGE_RETVAL_IF(!obj_table, MAPI_E_INVALID_PARAMETER, NULL); session = mapi_object_get_session(obj_table); OPENCHANGE_RETVAL_IF(!session, MAPI_E_INVALID_PARAMETER, NULL); if ((retval = mapi_object_get_logon_id(obj_table, &logon_id)) != MAPI_E_SUCCESS) return retval; mem_ctx = talloc_named(session, 0, "CreateBookmark"); size = 0; /* Fill the MAPI_REQ request */ mapi_req = talloc_zero(mem_ctx, struct EcDoRpc_MAPI_REQ); mapi_req->opnum = op_MAPI_CreateBookmark; mapi_req->logon_id = logon_id; mapi_req->handle_idx = 0; size += 5; /* Fill the mapi_request structure */ mapi_request = talloc_zero(mem_ctx, struct mapi_request); mapi_request->mapi_len = size + sizeof (uint32_t); mapi_request->length = size; mapi_request->mapi_req = mapi_req; mapi_request->handles = talloc_array(mem_ctx, uint32_t, 1); mapi_request->handles[0] = mapi_object_get_handle(obj_table); status = emsmdb_transaction_wrapper(session, mem_ctx, mapi_request, &mapi_response); OPENCHANGE_RETVAL_IF(!NT_STATUS_IS_OK(status), MAPI_E_CALL_FAILED, mem_ctx); OPENCHANGE_RETVAL_IF(!mapi_response->mapi_repl, MAPI_E_CALL_FAILED, mem_ctx); retval = mapi_response->mapi_repl->error_code; OPENCHANGE_RETVAL_IF(retval, retval, mem_ctx); OPENCHANGE_CHECK_NOTIFICATION(session, mapi_response); reply = &mapi_response->mapi_repl->u.mapi_CreateBookmark; mapi_table = (mapi_object_table_t *)obj_table->private_data; OPENCHANGE_RETVAL_IF(!mapi_table, MAPI_E_INVALID_PARAMETER, mem_ctx); /* Store CreateBookmark data in mapi_object_table private_data */ bookmark = talloc_zero((TALLOC_CTX *)mapi_table->bookmark, mapi_object_bookmark_t); mapi_table->bk_last++; bookmark->index = mapi_table->bk_last; bookmark->bin.cb = reply->bookmark.cb; bookmark->bin.lpb = talloc_array((TALLOC_CTX *)bookmark, uint8_t, reply->bookmark.cb); memcpy(bookmark->bin.lpb, reply->bookmark.lpb, reply->bookmark.cb); DLIST_ADD(mapi_table->bookmark, bookmark); *lpbkPosition = mapi_table->bk_last; obj_table->private_data = mapi_table; talloc_free(mapi_response); talloc_free(mem_ctx); return MAPI_E_SUCCESS; } /** \details Release the resources associated with a bookmark \param obj_table the table the bookmark is associated to \param bkPosition the bookmark to be freed \return MAPI_E_SUCCESS on success, otherwise MAPI error. \note Developers may also call GetLastError() to retrieve the last MAPI error code. Possible MAPI error codes are: - MAPI_E_NOT_INITIALIZED: MAPI subsystem has not been initialized - MAPI_E_INVALID_PARAMETER: obj_table is NULL - MAPI_E_INVALID_BOOKMARK: The bookmark specified is invalid or beyond the last row requested - MAPI_E_CALL_FAILED: A network problem was encountered during the transaction \sa CreateBookmark */ _PUBLIC_ enum MAPISTATUS FreeBookmark(mapi_object_t *obj_table, uint32_t bkPosition) { mapi_object_table_t *table; mapi_object_bookmark_t *bookmark; uint32_t size; TALLOC_CTX *mem_ctx; struct mapi_request *mapi_request; struct mapi_response *mapi_response; struct EcDoRpc_MAPI_REQ *mapi_req; struct FreeBookmark_req request; struct mapi_session *session; NTSTATUS status; enum MAPISTATUS retval; uint8_t logon_id = 0; /* Sanity check */ OPENCHANGE_RETVAL_IF(!obj_table, MAPI_E_INVALID_PARAMETER, NULL); session = mapi_object_get_session(obj_table); OPENCHANGE_RETVAL_IF(!session, MAPI_E_INVALID_PARAMETER, NULL); table = (mapi_object_table_t *)obj_table->private_data; OPENCHANGE_RETVAL_IF(!table, MAPI_E_INVALID_PARAMETER, NULL); OPENCHANGE_RETVAL_IF(bkPosition > table->bk_last, MAPI_E_INVALID_BOOKMARK, NULL); bookmark = table->bookmark; OPENCHANGE_RETVAL_IF(!bookmark, MAPI_E_INVALID_BOOKMARK, NULL); if ((retval = mapi_object_get_logon_id(obj_table, &logon_id)) != MAPI_E_SUCCESS) return retval; mem_ctx = talloc_named(session, 0, "FreeBookmark"); while (bookmark) { if (bookmark->index == bkPosition) { if (bookmark->index == table->bk_last) { table->bk_last--; } size = 0; /* Fill the FreeBookmark operation */ request.bookmark.cb = bookmark->bin.cb; size += sizeof (uint16_t); request.bookmark.lpb = bookmark->bin.lpb; size += bookmark->bin.cb; /* Fill the MAPI_REQ request */ mapi_req = talloc_zero(mem_ctx, struct EcDoRpc_MAPI_REQ); mapi_req->opnum = op_MAPI_FreeBookmark; mapi_req->logon_id = logon_id; mapi_req->handle_idx = 0; mapi_req->u.mapi_FreeBookmark = request; size += 5; /* Fill the mapi_request structure */ mapi_request = talloc_zero(mem_ctx, struct mapi_request); mapi_request->mapi_len = size + sizeof (uint32_t); mapi_request->length = size; mapi_request->mapi_req = mapi_req; mapi_request->handles = talloc_array(mem_ctx, uint32_t, 1); mapi_request->handles[0] = mapi_object_get_handle(obj_table); status = emsmdb_transaction_wrapper(session, mem_ctx, mapi_request, &mapi_response); OPENCHANGE_RETVAL_IF(!NT_STATUS_IS_OK(status), MAPI_E_CALL_FAILED, mem_ctx); OPENCHANGE_RETVAL_IF(!mapi_response->mapi_repl, MAPI_E_CALL_FAILED, mem_ctx); retval = mapi_response->mapi_repl->error_code; OPENCHANGE_RETVAL_IF(retval, retval, mem_ctx); OPENCHANGE_CHECK_NOTIFICATION(session, mapi_response); MAPIFreeBuffer(bookmark->bin.lpb); DLIST_REMOVE(table->bookmark, bookmark); talloc_free(mapi_response); talloc_free(mem_ctx); return MAPI_E_SUCCESS; } bookmark = bookmark->next; } talloc_free(mem_ctx); return MAPI_E_INVALID_BOOKMARK; } /** \details Order the rows of the table based on a criteria \param obj_table the table we are ordering rows on \param lpSortCriteria pointer on sort criterias to apply \return MAPI_E_SUCCESS on success, otherwise MAPI error. \note Developers may also call GetLastError() to retrieve the last MAPI error code. Possible MAPI error codes are: - MAPI_E_NOT_INITIALIZED: MAPI subsystem has not been initialized - MAPI_E_INVALID_PARAMETER: obj_table or lpSortCriteria is NULL - MAPI_E_CALL_FAILED: A network problem was encountered during the transaction */ _PUBLIC_ enum MAPISTATUS SortTable(mapi_object_t *obj_table, struct SSortOrderSet *lpSortCriteria) { struct mapi_request *mapi_request; struct mapi_response *mapi_response; struct EcDoRpc_MAPI_REQ *mapi_req; struct SortTable_req request; struct mapi_session *session; NTSTATUS status; enum MAPISTATUS retval; uint32_t size; TALLOC_CTX *mem_ctx; uint8_t logon_id = 0; /* Sanity checks */ OPENCHANGE_RETVAL_IF(!obj_table, MAPI_E_INVALID_PARAMETER, NULL); OPENCHANGE_RETVAL_IF(!lpSortCriteria, MAPI_E_INVALID_PARAMETER, NULL); session = mapi_object_get_session(obj_table); OPENCHANGE_RETVAL_IF(!session, MAPI_E_INVALID_PARAMETER, NULL); if ((retval = mapi_object_get_logon_id(obj_table, &logon_id)) != MAPI_E_SUCCESS) return retval; mem_ctx = talloc_named(session, 0, "SortTable"); /* Fill the SortTable operation */ size = 0; request.SortTableFlags = 0; size += sizeof (uint8_t); request.lpSortCriteria.cSorts = lpSortCriteria->cSorts; size += sizeof (uint16_t); request.lpSortCriteria.cCategories = lpSortCriteria->cCategories; size += sizeof (uint16_t); request.lpSortCriteria.cExpanded = lpSortCriteria->cExpanded; size += sizeof (uint16_t); request.lpSortCriteria.aSort = lpSortCriteria->aSort; size += lpSortCriteria->cSorts * (sizeof (uint32_t) + sizeof (uint8_t)); /* Fill the MAPI_REQ request */ mapi_req = talloc_zero(mem_ctx, struct EcDoRpc_MAPI_REQ); mapi_req->opnum = op_MAPI_SortTable; mapi_req->logon_id = logon_id; mapi_req->handle_idx = 0; mapi_req->u.mapi_SortTable = request; size += 5; /* Fill the mapi_request structure */ mapi_request = talloc_zero(mem_ctx, struct mapi_request); mapi_request->mapi_len = size + sizeof (uint32_t); mapi_request->length = size; mapi_request->mapi_req = mapi_req; mapi_request->handles = talloc_array(mem_ctx, uint32_t, 1); mapi_request->handles[0] = mapi_object_get_handle(obj_table); status = emsmdb_transaction_wrapper(session, mem_ctx, mapi_request, &mapi_response); OPENCHANGE_RETVAL_IF(!NT_STATUS_IS_OK(status), MAPI_E_CALL_FAILED, mem_ctx); OPENCHANGE_RETVAL_IF(!mapi_response->mapi_repl, MAPI_E_CALL_FAILED, mem_ctx); retval = mapi_response->mapi_repl->error_code; OPENCHANGE_RETVAL_IF(retval, retval, mem_ctx); OPENCHANGE_CHECK_NOTIFICATION(session, mapi_response); talloc_free(mapi_response); talloc_free(mem_ctx); return MAPI_E_SUCCESS; } /** \details Get the size associated to a mapi SRestriction \param res pointer on the mapi_SRestriction \return mapi_SRestriction size */ uint32_t get_mapi_SRestriction_size(struct mapi_SRestriction *res) { uint32_t size; uint32_t i; size = 0; size += sizeof (res->rt); switch(res->rt) { case RES_AND: size += sizeof (res->res.resAnd.cRes); for (i = 0; i < res->res.resAnd.cRes; i++) { size += get_mapi_SRestriction_size((struct mapi_SRestriction *)&(res->res.resAnd.res[i])); } break; case RES_OR: size += sizeof (res->res.resOr.cRes); for (i = 0; i < res->res.resOr.cRes; i++) { size += get_mapi_SRestriction_size((struct mapi_SRestriction *)&(res->res.resOr.res[i])); } break; /* case RES_NOT: */ /* size += get_mapi_SRestriction_size(res->res.resNot.res); */ /* break; */ case RES_CONTENT: size += sizeof (res->res.resContent.fuzzy); size += sizeof (res->res.resContent.ulPropTag); size += sizeof (res->res.resContent.lpProp.ulPropTag); size += get_mapi_property_size(&(res->res.resContent.lpProp)); break; case RES_PROPERTY: size += sizeof (res->res.resProperty.relop); size += sizeof (res->res.resProperty.ulPropTag); size += sizeof (res->res.resProperty.lpProp.ulPropTag); size += get_mapi_property_size(&(res->res.resProperty.lpProp)); break; case RES_COMPAREPROPS: size += sizeof (uint8_t); size += sizeof (res->res.resCompareProps.ulPropTag1); size += sizeof (res->res.resCompareProps.ulPropTag2); break; case RES_BITMASK: size += sizeof (uint8_t); size += sizeof (res->res.resBitmask.ulPropTag); size += sizeof (res->res.resBitmask.ulMask); break; case RES_SIZE: size += sizeof (uint8_t); size += sizeof (res->res.resSize.ulPropTag); size += sizeof (res->res.resSize.size); break; case RES_EXIST: size += sizeof (res->res.resExist.ulPropTag); break; } return (size); } /** \details Removes all filters that are currently on a table \param obj_table the table object to reset \return MAPI_E_SUCCESS on success, otherwise MAPI error. \note Developers may also call GetLastError() to retrieve the last MAPI error code. Possible MAPI error codes are: - MAPI_E_NOT_INITIALIZED: MAPI subsystem has not been initialized - MAPI_E_INVALID_PARAMETER: obj_table is NULL - MAPI_E_CALL_FAILED: A network problem was encountered during the transaction \sa Restrict */ _PUBLIC_ enum MAPISTATUS Reset(mapi_object_t *obj_table) { TALLOC_CTX *mem_ctx; uint32_t size; struct EcDoRpc_MAPI_REQ *mapi_req; struct mapi_request *mapi_request; struct mapi_response *mapi_response; struct mapi_session *session; NTSTATUS status; enum MAPISTATUS retval; uint8_t logon_id = 0; /* Sanity checks */ OPENCHANGE_RETVAL_IF(!obj_table, MAPI_E_INVALID_PARAMETER, NULL); session = mapi_object_get_session(obj_table); OPENCHANGE_RETVAL_IF(!session, MAPI_E_INVALID_PARAMETER, NULL); if ((retval = mapi_object_get_logon_id(obj_table, &logon_id)) != MAPI_E_SUCCESS) return retval; mem_ctx = talloc_named(session, 0, "Reset"); size = 0; /* Fill the MAPI_REQ request */ mapi_req = talloc_zero(mem_ctx, struct EcDoRpc_MAPI_REQ); mapi_req->opnum = op_MAPI_ResetTable; mapi_req->logon_id = logon_id; mapi_req->handle_idx = 0; size += 5; /* Fill the mapi_request structure */ mapi_request = talloc_zero(mem_ctx, struct mapi_request); mapi_request->mapi_len = size + sizeof (uint32_t); mapi_request->length = size; mapi_request->mapi_req = mapi_req; mapi_request->handles = talloc_array(mem_ctx, uint32_t, 1); mapi_request->handles[0] = mapi_object_get_handle(obj_table); status = emsmdb_transaction_wrapper(session, mem_ctx, mapi_request, &mapi_response); OPENCHANGE_RETVAL_IF(!NT_STATUS_IS_OK(status), MAPI_E_CALL_FAILED, mem_ctx); OPENCHANGE_RETVAL_IF(!mapi_response->mapi_repl, MAPI_E_CALL_FAILED, mem_ctx); retval = mapi_response->mapi_repl->error_code; OPENCHANGE_RETVAL_IF(retval, retval, mem_ctx); OPENCHANGE_CHECK_NOTIFICATION(session, mapi_response); talloc_free(mapi_response); talloc_free(mem_ctx); return MAPI_E_SUCCESS; } /** \details Applies a filter to a table, reducing the row set to only those rows matching the specified criteria. \param obj_table the object we are filtering \param res the filters we want to apply \param TableStatus the table status result TableStatus can either hold: - TBLSTAT_COMPLETE (0x0) - TBLSTAT_SORTING (0x9) - TBLSTAT_SORT_ERROR (0xA) - TBLSTAT_SETTING_COLS (0xB) - TBLSTAT_SETCOL_ERROR (0xD) - TBLSTAT_RESTRICTING (0xE) - TBLSTAT_RESTRICT_ERROR (0xF) Unlike MAPI, you don't pass a null restriction argument to remove the current restrictions. Use Reset() instead. TableStatus should be set to NULL if you don't want to retrieve the status of the table. \return MAPI_E_SUCCESS on success, otherwise MAPI error. \note Developers may also call GetLastError() to retrieve the last MAPI error code. Possible MAPI error codes are: - MAPI_E_NOT_INITIALIZED: MAPI subsystem has not been initialized - MAPI_E_INVALID_PARAMETER: obj_table is NULL - MAPI_E_CALL_FAILED: A network problem was encountered during the transaction \sa QueryRows, Reset */ _PUBLIC_ enum MAPISTATUS Restrict(mapi_object_t *obj_table, struct mapi_SRestriction *res, uint8_t *TableStatus) { struct mapi_request *mapi_request; struct mapi_response *mapi_response; struct EcDoRpc_MAPI_REQ *mapi_req; struct Restrict_req request; struct Restrict_repl *reply; struct mapi_session *session; NTSTATUS status; enum MAPISTATUS retval; uint32_t size; TALLOC_CTX *mem_ctx; uint8_t logon_id = 0; /* Sanity checks */ OPENCHANGE_RETVAL_IF(!obj_table, MAPI_E_INVALID_PARAMETER, NULL); OPENCHANGE_RETVAL_IF(!res, MAPI_E_INVALID_PARAMETER, NULL); session = mapi_object_get_session(obj_table); OPENCHANGE_RETVAL_IF(!session, MAPI_E_INVALID_PARAMETER, NULL); if ((retval = mapi_object_get_logon_id(obj_table, &logon_id)) != MAPI_E_SUCCESS) return retval; mem_ctx = talloc_named(session, 0, "Restrict"); /* Fill the Restrict operation */ size = 0; request.handle_idx = 0; size += sizeof (request.handle_idx); request.restrictions = *res; size += get_mapi_SRestriction_size(res); /* add subcontext size */ size += sizeof (uint16_t); /* Fill the MAPI_REQ request */ mapi_req = talloc_zero(mem_ctx, struct EcDoRpc_MAPI_REQ); mapi_req->opnum = op_MAPI_Restrict; mapi_req->logon_id = logon_id; mapi_req->handle_idx = 0; mapi_req->u.mapi_Restrict = request; size += 5; /* Fill the mapi_request structure */ mapi_request = talloc_zero(mem_ctx, struct mapi_request); mapi_request->mapi_len = size + sizeof (uint32_t); mapi_request->length = size; mapi_request->mapi_req = mapi_req; mapi_request->handles = talloc_array(mem_ctx, uint32_t, 1); mapi_request->handles[0] = mapi_object_get_handle(obj_table); status = emsmdb_transaction_wrapper(session, mem_ctx, mapi_request, &mapi_response); OPENCHANGE_RETVAL_IF(!NT_STATUS_IS_OK(status), MAPI_E_CALL_FAILED, mem_ctx); OPENCHANGE_RETVAL_IF(!mapi_response->mapi_repl, MAPI_E_CALL_FAILED, mem_ctx); retval = mapi_response->mapi_repl->error_code; OPENCHANGE_RETVAL_IF(retval, retval, mem_ctx); OPENCHANGE_CHECK_NOTIFICATION(session, mapi_response); if (TableStatus) { reply = &mapi_response->mapi_repl->u.mapi_Restrict; *TableStatus = reply->TableStatus; } talloc_free(mapi_response); talloc_free(mem_ctx); return MAPI_E_SUCCESS; } /** \details Find the next row in a table that matches specific search criteria \param obj_table the table we are searching in \param res pointer on search criterias \param bkOrigin bookmark identifying the row where FindRow should begin \param ulFlags controls the direction of the search \param SRowSet the resulting row bkOrigin can either take the value of a bookmark created with CreateBookmark or any of the default values: - BOOKMARK_BEGINNING - BOOKMARK_CURRENT - BOOKMARK_END ulFlags can be set either to DIR_FORWARD (0x0) or DIR_BACKWARD (0x1). \return MAPI_E_SUCCESS on success, otherwise MAPI error. \note Developers may also call GetLastError() to retrieve the last MAPI error code. Possible MAPI error codes are: - MAPI_E_NOT_INITIALIZED: MAPI subsystem has not been initialized - MAPI_E_INVALID_PARAMETER: obj_table is NULL - MAPI_E_INVALID_BOOKMARK: the bookmark specified is invalid or beyond the last row requested. - MAPI_E_CALL_FAILED: A network problem was encountered during the transaction \sa CreateBookmark */ _PUBLIC_ enum MAPISTATUS FindRow(mapi_object_t *obj_table, struct mapi_SRestriction *res, enum BOOKMARK bkOrigin, enum FindRow_ulFlags ulFlags, struct SRowSet *SRowSet) { struct mapi_context *mapi_ctx; struct mapi_request *mapi_request; struct mapi_response *mapi_response; struct EcDoRpc_MAPI_REQ *mapi_req; struct FindRow_req request; struct FindRow_repl *reply; struct mapi_session *session; NTSTATUS status; enum MAPISTATUS retval; uint32_t size; TALLOC_CTX *mem_ctx; mapi_object_table_t *table; struct SBinary_short bin; uint8_t logon_id = 0; /* Sanity checks */ OPENCHANGE_RETVAL_IF(!obj_table, MAPI_E_INVALID_PARAMETER, NULL); OPENCHANGE_RETVAL_IF(!res, MAPI_E_INVALID_PARAMETER, NULL); session = mapi_object_get_session(obj_table); OPENCHANGE_RETVAL_IF(!session, MAPI_E_INVALID_PARAMETER, NULL); mapi_ctx = session->mapi_ctx; OPENCHANGE_RETVAL_IF(!mapi_ctx, MAPI_E_NOT_INITIALIZED, NULL); if ((retval = mapi_object_get_logon_id(obj_table, &logon_id)) != MAPI_E_SUCCESS) return retval; if (bkOrigin >= 3) { retval = mapi_object_bookmark_find(obj_table, bkOrigin, &bin); OPENCHANGE_RETVAL_IF(retval, MAPI_E_INVALID_BOOKMARK, NULL); } mem_ctx = talloc_named(session, 0, "FindRow"); /* Fill the FindRow operation */ size = 0; request.ulFlags = ulFlags; size += sizeof (uint8_t); request.res = *res; size += get_mapi_SRestriction_size(res); request.origin = (bkOrigin > BOOKMARK_USER) ? BOOKMARK_USER : bkOrigin; size += sizeof (uint8_t); if (bkOrigin >= 3) { request.bookmark.cb = bin.cb; request.bookmark.lpb = bin.lpb; size += sizeof (uint16_t)+ bin.cb; } else { request.bookmark.cb = 0; request.bookmark.lpb = NULL; size += sizeof (uint16_t); } /* add subcontext size */ size += sizeof (uint16_t); /* Fill the MAPI_REQ request */ mapi_req = talloc_zero(mem_ctx, struct EcDoRpc_MAPI_REQ); mapi_req->opnum = op_MAPI_FindRow; mapi_req->logon_id = logon_id; mapi_req->handle_idx = 0; mapi_req->u.mapi_FindRow = request; size += 5; /* Fill the mapi_request structure */ mapi_request = talloc_zero(mem_ctx, struct mapi_request); mapi_request->mapi_len = size + sizeof (uint32_t); mapi_request->length = size; mapi_request->mapi_req = mapi_req; mapi_request->handles = talloc_array(mem_ctx, uint32_t, 1); mapi_request->handles[0] = mapi_object_get_handle(obj_table); status = emsmdb_transaction_wrapper(session, mem_ctx, mapi_request, &mapi_response); OPENCHANGE_RETVAL_IF(!NT_STATUS_IS_OK(status), MAPI_E_CALL_FAILED, mem_ctx); OPENCHANGE_RETVAL_IF(!mapi_response->mapi_repl, MAPI_E_CALL_FAILED, mem_ctx); retval = mapi_response->mapi_repl->error_code; OPENCHANGE_RETVAL_IF(retval, retval, mem_ctx); OPENCHANGE_CHECK_NOTIFICATION(session, mapi_response); /* table contains SPropTagArray from previous SetColumns call */ table = (mapi_object_table_t *)obj_table->private_data; OPENCHANGE_RETVAL_IF(!table, MAPI_E_INVALID_OBJECT, mem_ctx); reply = &mapi_response->mapi_repl->u.mapi_FindRow; SRowSet->cRows = 1; SRowSet->aRow = talloc_array((TALLOC_CTX *)table, struct SRow, SRowSet->cRows); emsmdb_get_SRowSet((TALLOC_CTX *)table, SRowSet, &table->proptags, &reply->row); talloc_free(mapi_response); talloc_free(mem_ctx); return MAPI_E_SUCCESS; } /** \details Get the status of a table \param obj_table the table we are retrieving the status from \param TableStatus the table status result TableStatus can either hold: - TBLSTAT_COMPLETE (0x0) - TBLSTAT_SORTING (0x9) - TBLSTAT_SORT_ERROR (0xA) - TBLSTAT_SETTING_COLS (0xB) - TBLSTAT_SETCOL_ERROR (0xD) - TBLSTAT_RESTRICTING (0xE) - TBLSTAT_RESTRICT_ERROR (0xF) \return MAPI_E_SUCCESS on success, otherwise MAPI error. \note Developers may also call GetLastError() to retrieve the last MAPI error code. Possible MAPI error codes are: - MAPI_E_NOT_INITIALIZED: MAPI subsystem has not been initialized - MAPI_E_INVALID_PARAMETER: obj_table is NULL - MAPI_E_INVALID_BOOKMARK: the bookmark specified is invalid or beyond the last row requested. - MAPI_E_CALL_FAILED: A network problem was encountered during the transaction \sa SetColumns, Restrict, FindRow, GetHierarchyTable, GetContentsTable */ _PUBLIC_ enum MAPISTATUS GetStatus(mapi_object_t *obj_table, uint8_t *TableStatus) { struct mapi_request *mapi_request; struct mapi_response *mapi_response; struct EcDoRpc_MAPI_REQ *mapi_req; struct GetStatus_repl *reply; struct mapi_session *session; NTSTATUS status; enum MAPISTATUS retval; uint32_t size; TALLOC_CTX *mem_ctx; uint8_t logon_id = 0; /* Sanity checks */ OPENCHANGE_RETVAL_IF(!obj_table, MAPI_E_INVALID_PARAMETER, NULL); session = mapi_object_get_session(obj_table); OPENCHANGE_RETVAL_IF(!session, MAPI_E_INVALID_PARAMETER, NULL); if ((retval = mapi_object_get_logon_id(obj_table, &logon_id)) != MAPI_E_SUCCESS) return retval; mem_ctx = talloc_named(session, 0, "GetStatus"); size = 0; /* Fill the MAPI_REQ request */ mapi_req = talloc_zero(mem_ctx, struct EcDoRpc_MAPI_REQ); mapi_req->opnum = op_MAPI_GetStatus; mapi_req->logon_id = logon_id; mapi_req->handle_idx = 0; size += 5; /* Fill the mapi_request structure */ mapi_request = talloc_zero(mem_ctx, struct mapi_request); mapi_request->mapi_len = size + sizeof (uint32_t); mapi_request->length = size; mapi_request->mapi_req = mapi_req; mapi_request->handles = talloc_array(mem_ctx, uint32_t, 1); mapi_request->handles[0] = mapi_object_get_handle(obj_table); status = emsmdb_transaction_wrapper(session, mem_ctx, mapi_request, &mapi_response); OPENCHANGE_RETVAL_IF(!NT_STATUS_IS_OK(status), MAPI_E_CALL_FAILED, mem_ctx); OPENCHANGE_RETVAL_IF(!mapi_response->mapi_repl, MAPI_E_CALL_FAILED, mem_ctx); retval = mapi_response->mapi_repl->error_code; OPENCHANGE_RETVAL_IF(retval, retval, mem_ctx); OPENCHANGE_CHECK_NOTIFICATION(session, mapi_response); /* Retrieve TableStatus */ reply = &mapi_response->mapi_repl->u.mapi_GetStatus; *TableStatus = reply->TableStatus; talloc_free(mapi_response); talloc_free(mem_ctx); return MAPI_E_SUCCESS; } /** \details Aborts an asynchronous table operation in progress \param obj_table the table object where we want to abort an asynchronous operation \param TableStatus pointer on the table status returned by the operation \return MAPI_E_SUCCESS on success, otherwise MAPI error. \note Developers may also call GetLastError() to retrieve the last MAPI error code. Possible MAPI error codes are: - MAPI_E_NOT_INITIALIZED: MAPI subsystem has not been initialized - MAPI_E_INVALID_PARAMETER: obj_table or TableStatus are null - MAPI_E_CALL_FAILED: A network problem was encountered during the transaction */ _PUBLIC_ enum MAPISTATUS Abort(mapi_object_t *obj_table, uint8_t *TableStatus) { struct mapi_request *mapi_request; struct mapi_response *mapi_response; struct EcDoRpc_MAPI_REQ *mapi_req; struct Abort_repl *reply; struct mapi_session *session; NTSTATUS status; enum MAPISTATUS retval; uint32_t size; TALLOC_CTX *mem_ctx; uint8_t logon_id = 0; /* Sanity checks */ OPENCHANGE_RETVAL_IF(!obj_table, MAPI_E_INVALID_PARAMETER, NULL); OPENCHANGE_RETVAL_IF(!TableStatus, MAPI_E_INVALID_PARAMETER, NULL); session = mapi_object_get_session(obj_table); OPENCHANGE_RETVAL_IF(!session, MAPI_E_INVALID_PARAMETER, NULL); if ((retval = mapi_object_get_logon_id(obj_table, &logon_id)) != MAPI_E_SUCCESS) return retval; mem_ctx = talloc_named(session, 0, "Abort"); size = 0; /* Fill the MAPI_REQ request */ mapi_req = talloc_zero(mem_ctx, struct EcDoRpc_MAPI_REQ); mapi_req->opnum = op_MAPI_Abort; mapi_req->logon_id = logon_id; mapi_req->handle_idx = 0; size += 5; /* Fill the mapi_request structure */ mapi_request = talloc_zero(mem_ctx, struct mapi_request); mapi_request->mapi_len = size + sizeof (uint32_t); mapi_request->length = size; mapi_request->mapi_req = mapi_req; mapi_request->handles = talloc_array(mem_ctx, uint32_t, 1); mapi_request->handles[0] = mapi_object_get_handle(obj_table); status = emsmdb_transaction_wrapper(session, mem_ctx, mapi_request, &mapi_response); OPENCHANGE_RETVAL_IF(!NT_STATUS_IS_OK(status), MAPI_E_CALL_FAILED, mem_ctx); OPENCHANGE_RETVAL_IF(!mapi_response->mapi_repl, MAPI_E_CALL_FAILED, mem_ctx); retval = mapi_response->mapi_repl->error_code; OPENCHANGE_RETVAL_IF(retval, retval, mem_ctx); OPENCHANGE_CHECK_NOTIFICATION(session, mapi_response); /* Retrieve TableStatus */ reply = &mapi_response->mapi_repl->u.mapi_Abort; *TableStatus = reply->TableStatus; talloc_free(mapi_response); talloc_free(mem_ctx); return MAPI_E_SUCCESS; } /** \details Expand a collapsed row in a table After a contents table has been sorted and categorized using SortTable, rows can be expanded and collapsed (using ExpandRow and CollapseRow repectively). \param obj_table the table we are collapsing the category in. \param categoryId the row identification for the heading row for the category being expanded. \param maxRows the maximum number of rows to retrieve (can be zero) \param rowData (result) the data rows under this category heading \param expandedRowCount (result) the number of rows that were added to the table when the row was expanded You obtain the categoryId argument from the PR_INST_ID property of the heading row for the category that is being collapsed. The maxRows argument specifies the upper limit on how many rows to return (as rowData) when the category is expanded. The expandedRowCount argument returns the number of rows that were added to the table. As an example, consider a collapsed category with 8 entries. If you set maxRows to 3, then rowData will contain the data for the first three rows, and expandedRowCount will be set to 8. If you now use QueryRows(), you can read the 5 additional rows. If you'd specified maxRows as 8 (or more), rowData would have contained all 8 rows and expandedRowCount still would have been 8. \return MAPI_E_SUCCESS on success, otherwise MAPI error. \note Developers may also call GetLastError() to retrieve the last MAPI error code. Possible MAPI error codes are: - MAPI_E_NOT_INITIALIZED: MAPI subsystem has not been initialized - MAPI_E_INVALID_PARAMETER: obj_table, rowData or rowCount are NULL - MAPI_E_CALL_FAILED: A network problem was encountered during the transaction \sa CollapseRow */ _PUBLIC_ enum MAPISTATUS ExpandRow(mapi_object_t *obj_table, uint64_t categoryId, uint16_t maxRows, struct SRowSet *rowData, uint32_t *expandedRowCount) { struct mapi_context *mapi_ctx; struct mapi_request *mapi_request; struct mapi_response *mapi_response; struct EcDoRpc_MAPI_REQ *mapi_req; struct ExpandRow_req request; struct ExpandRow_repl *reply; struct mapi_session *session; NTSTATUS status; enum MAPISTATUS retval; uint32_t size; mapi_object_table_t *table; TALLOC_CTX *mem_ctx; uint8_t logon_id = 0; /* Sanity checks */ OPENCHANGE_RETVAL_IF(!obj_table, MAPI_E_INVALID_PARAMETER, NULL); OPENCHANGE_RETVAL_IF(!rowData, MAPI_E_INVALID_PARAMETER, NULL); OPENCHANGE_RETVAL_IF(!expandedRowCount, MAPI_E_INVALID_PARAMETER, NULL); session = mapi_object_get_session(obj_table); OPENCHANGE_RETVAL_IF(!session, MAPI_E_INVALID_PARAMETER, NULL); mapi_ctx = session->mapi_ctx; OPENCHANGE_RETVAL_IF(!mapi_ctx, MAPI_E_NOT_INITIALIZED, NULL); if ((retval = mapi_object_get_logon_id(obj_table, &logon_id)) != MAPI_E_SUCCESS) return retval; mem_ctx = talloc_named(session, 0, "ExpandRow"); size = 0; /* Fill the ExpandRow operation */ request.MaxRowCount = maxRows; size += sizeof (uint16_t); request.CategoryId = categoryId; size += sizeof (uint64_t); /* Fill the MAPI_REQ request */ mapi_req = talloc_zero(mem_ctx, struct EcDoRpc_MAPI_REQ); mapi_req->opnum = op_MAPI_ExpandRow; mapi_req->logon_id = logon_id; mapi_req->handle_idx = 0; mapi_req->u.mapi_ExpandRow = request; size += 5; /* Fill the mapi_request structure */ mapi_request = talloc_zero(mem_ctx, struct mapi_request); mapi_request->mapi_len = size + sizeof (uint32_t); mapi_request->length = size; mapi_request->mapi_req = mapi_req; mapi_request->handles = talloc_array(mem_ctx, uint32_t, 1); mapi_request->handles[0] = mapi_object_get_handle(obj_table); status = emsmdb_transaction_wrapper(session, mem_ctx, mapi_request, &mapi_response); OPENCHANGE_RETVAL_IF(!NT_STATUS_IS_OK(status), MAPI_E_CALL_FAILED, mem_ctx); OPENCHANGE_RETVAL_IF(!mapi_response->mapi_repl, MAPI_E_CALL_FAILED, mem_ctx); retval = mapi_response->mapi_repl->error_code; OPENCHANGE_RETVAL_IF(retval, retval, mem_ctx); OPENCHANGE_CHECK_NOTIFICATION(session, mapi_response); /* table contains mapitags from previous SetColumns */ table = (mapi_object_table_t *)obj_table->private_data; OPENCHANGE_RETVAL_IF(!table, MAPI_E_INVALID_OBJECT, mem_ctx); /* Retrieve the rowData and expandedRowCount */ reply = &mapi_response->mapi_repl->u.mapi_ExpandRow; rowData->cRows = reply->RowCount; rowData->aRow = talloc_array((TALLOC_CTX *)table, struct SRow, reply->RowCount); emsmdb_get_SRowSet((TALLOC_CTX *)table, rowData, &table->proptags, &reply->RowData); *expandedRowCount = reply->ExpandedRowCount; talloc_free(mapi_response); talloc_free(mem_ctx); return MAPI_E_SUCCESS; } /** \details Collapse an expanded row in a table After a contents table has been sorted and categorized using SortTable, rows can be expanded and collapsed (using ExpandRow and CollapseRow repectively). \param obj_table the table we are collapsing the category in. \param categoryId the row identification for the heading row for the category being collapsed. \param rowCount (result) the number of rows that were removed from the table when the row was collapsed. You obtain the categoryId argument from the PR_INST_ID property of the heading row for the category that is being collapsed. If you pass rowCount as null, the number of rows will not be returned. \return MAPI_E_SUCCESS on success, otherwise MAPI error. \note Developers may also call GetLastError() to retrieve the last MAPI error code. Possible MAPI error codes are: - MAPI_E_NOT_INITIALIZED: MAPI subsystem has not been initialized - MAPI_E_INVALID_PARAMETER: obj_table is NULL - MAPI_E_CALL_FAILED: A network problem was encountered during the transaction \sa ExpandRow */ _PUBLIC_ enum MAPISTATUS CollapseRow(mapi_object_t *obj_table, uint64_t categoryId, uint32_t *rowCount) { struct mapi_request *mapi_request; struct mapi_response *mapi_response; struct EcDoRpc_MAPI_REQ *mapi_req; struct CollapseRow_req request; struct CollapseRow_repl *reply; struct mapi_session *session; NTSTATUS status; enum MAPISTATUS retval; uint32_t size; TALLOC_CTX *mem_ctx; uint8_t logon_id = 0; /* Sanity checks */ OPENCHANGE_RETVAL_IF(!obj_table, MAPI_E_INVALID_PARAMETER, NULL); session = mapi_object_get_session(obj_table); OPENCHANGE_RETVAL_IF(!session, MAPI_E_INVALID_PARAMETER, NULL); if ((retval = mapi_object_get_logon_id(obj_table, &logon_id)) != MAPI_E_SUCCESS) return retval; mem_ctx = talloc_named(session, 0, "CollapseRow"); size = 0; /* Fill the CollapseRow operation */ request.CategoryId = categoryId; size += sizeof (uint64_t); /* Fill the MAPI_REQ request */ mapi_req = talloc_zero(mem_ctx, struct EcDoRpc_MAPI_REQ); mapi_req->opnum = op_MAPI_CollapseRow; mapi_req->logon_id = logon_id; mapi_req->handle_idx = 0; mapi_req->u.mapi_CollapseRow = request; size += 5; /* Fill the mapi_request structure */ mapi_request = talloc_zero(mem_ctx, struct mapi_request); mapi_request->mapi_len = size + sizeof (uint32_t); mapi_request->length = size; mapi_request->mapi_req = mapi_req; mapi_request->handles = talloc_array(mem_ctx, uint32_t, 1); mapi_request->handles[0] = mapi_object_get_handle(obj_table); status = emsmdb_transaction_wrapper(session, mem_ctx, mapi_request, &mapi_response); OPENCHANGE_RETVAL_IF(!NT_STATUS_IS_OK(status), MAPI_E_CALL_FAILED, mem_ctx); OPENCHANGE_RETVAL_IF(!mapi_response->mapi_repl, MAPI_E_CALL_FAILED, mem_ctx); retval = mapi_response->mapi_repl->error_code; OPENCHANGE_RETVAL_IF(retval, retval, mem_ctx); OPENCHANGE_CHECK_NOTIFICATION(session, mapi_response); /* Retrieve the RowCount */ reply = &mapi_response->mapi_repl->u.mapi_CollapseRow; *rowCount = reply->CollapsedRowCount; talloc_free(mapi_response); talloc_free(mem_ctx); return MAPI_E_SUCCESS; } /** \details Get the Collapse State of a Table After a contents table has been sorted and categorized using SortTable, rows can be expanded and collapsed (using ExpandRow() and CollapseRow() repectively). You can save the state of the table using this function, and restore it using SetCollapseState. \param obj_table the table we are retrieving the state from \param rowId the row number for the cursor \param rowInstanceNumber the instance number for the cursor \param CollapseState (result) the returned table Collapse State You obtain the row number and row instance number arguments from the PR_INST_ID and PR_INST_NUM properties of the row you want to use as the cursor. \return MAPI_E_SUCCESS on success, otherwise MAPI error. \note Developers may also call GetLastError() to retrieve the last MAPI error code. Possible MAPI error codes are: - MAPI_E_NOT_INITIALIZED: MAPI subsystem has not been initialized - MAPI_E_INVALID_PARAMETER: obj_table or CollapseState are null - MAPI_E_CALL_FAILED: A network problem was encountered during the transaction \sa SetCollapseState */ _PUBLIC_ enum MAPISTATUS GetCollapseState(mapi_object_t *obj_table, uint64_t rowId, uint32_t rowInstanceNumber, struct SBinary_short *CollapseState) { struct mapi_request *mapi_request; struct mapi_response *mapi_response; struct EcDoRpc_MAPI_REQ *mapi_req; struct GetCollapseState_req request; struct GetCollapseState_repl *reply; struct mapi_session *session; NTSTATUS status; enum MAPISTATUS retval; uint32_t size; TALLOC_CTX *mem_ctx; uint8_t logon_id = 0; /* Sanity checks */ OPENCHANGE_RETVAL_IF(!obj_table, MAPI_E_INVALID_PARAMETER, NULL); session = mapi_object_get_session(obj_table); OPENCHANGE_RETVAL_IF(!session, MAPI_E_INVALID_PARAMETER, NULL); if ((retval = mapi_object_get_logon_id(obj_table, &logon_id)) != MAPI_E_SUCCESS) return retval; mem_ctx = talloc_named(session, 0, "GetCollapseState"); size = 0; /* Fill the GetCollapseState operation */ size = 0; request.RowId = rowId; size += sizeof (uint64_t); request.RowInstanceNumber = rowInstanceNumber; size += sizeof (uint32_t); /* Fill the MAPI_REQ request */ mapi_req = talloc_zero(mem_ctx, struct EcDoRpc_MAPI_REQ); mapi_req->opnum = op_MAPI_GetCollapseState; mapi_req->logon_id = logon_id; mapi_req->handle_idx = 0; mapi_req->u.mapi_GetCollapseState = request; size += 5; /* Fill the mapi_request structure */ mapi_request = talloc_zero(mem_ctx, struct mapi_request); mapi_request->mapi_len = size + sizeof (uint32_t); mapi_request->length = size; mapi_request->mapi_req = mapi_req; mapi_request->handles = talloc_array(mem_ctx, uint32_t, 1); mapi_request->handles[0] = mapi_object_get_handle(obj_table); status = emsmdb_transaction_wrapper(session, mem_ctx, mapi_request, &mapi_response); OPENCHANGE_RETVAL_IF(!NT_STATUS_IS_OK(status), MAPI_E_CALL_FAILED, mem_ctx); OPENCHANGE_RETVAL_IF(!mapi_response->mapi_repl, MAPI_E_CALL_FAILED, mem_ctx); retval = mapi_response->mapi_repl->error_code; OPENCHANGE_RETVAL_IF(retval, retval, mem_ctx); OPENCHANGE_CHECK_NOTIFICATION(session, mapi_response); /* Retrieve the CollapseState */ reply = &mapi_response->mapi_repl->u.mapi_GetCollapseState; CollapseState->cb = reply->CollapseState.cb; CollapseState->lpb = talloc_array((TALLOC_CTX *)session, uint8_t, reply->CollapseState.cb); memcpy(CollapseState->lpb, reply->CollapseState.lpb, reply->CollapseState.cb); talloc_free(mapi_response); talloc_free(mem_ctx); return MAPI_E_SUCCESS; } /** \details Set the Collapse State of a Table After a contents table has been sorted and categorized using SortTable, rows can be expanded and collapsed (using ExpandRow() and CollapseRow() repectively). You can save the state of the table using GetCollapseState, and restore it using this function. \param obj_table the table we are restoring the state for \param CollapseState the Collapse State to restore \return MAPI_E_SUCCESS on success, otherwise MAPI error. \note Developers may also call GetLastError() to retrieve the last MAPI error code. Possible MAPI error codes are: - MAPI_E_NOT_INITIALIZED: MAPI subsystem has not been initialized - MAPI_E_INVALID_PARAMETER: obj_table or CollapseState are null - MAPI_E_CALL_FAILED: A network problem was encountered during the transaction \sa GetCollapseState */ _PUBLIC_ enum MAPISTATUS SetCollapseState(mapi_object_t *obj_table, struct SBinary_short *CollapseState) { struct mapi_request *mapi_request; struct mapi_response *mapi_response; struct EcDoRpc_MAPI_REQ *mapi_req; struct SetCollapseState_req request; struct mapi_session *session; NTSTATUS status; enum MAPISTATUS retval; uint32_t size; TALLOC_CTX *mem_ctx; mapi_object_table_t *mapi_table; uint8_t logon_id = 0; /* Sanity checks */ OPENCHANGE_RETVAL_IF(!obj_table, MAPI_E_INVALID_PARAMETER, NULL); OPENCHANGE_RETVAL_IF(!CollapseState, MAPI_E_INVALID_PARAMETER, NULL); session = mapi_object_get_session(obj_table); OPENCHANGE_RETVAL_IF(!session, MAPI_E_INVALID_PARAMETER, NULL); if ((retval = mapi_object_get_logon_id(obj_table, &logon_id)) != MAPI_E_SUCCESS) return retval; mem_ctx = talloc_named(session, 0, "SetCollapseState"); size = 0; /* Fill the SetCollapseState operation */ size = 0; request.CollapseState.cb = CollapseState->cb; size += sizeof (uint16_t); request.CollapseState.lpb = CollapseState->lpb; size += CollapseState->cb; /* Fill the MAPI_REQ request */ mapi_req = talloc_zero(mem_ctx, struct EcDoRpc_MAPI_REQ); mapi_req->opnum = op_MAPI_SetCollapseState; mapi_req->logon_id = logon_id; mapi_req->handle_idx = 0; mapi_req->u.mapi_SetCollapseState = request; size += 5; /* Fill the mapi_request structure */ mapi_request = talloc_zero(mem_ctx, struct mapi_request); mapi_request->mapi_len = size + sizeof (uint32_t); mapi_request->length = size; mapi_request->mapi_req = mapi_req; mapi_request->handles = talloc_array(mem_ctx, uint32_t, 1); mapi_request->handles[0] = mapi_object_get_handle(obj_table); status = emsmdb_transaction_wrapper(session, mem_ctx, mapi_request, &mapi_response); OPENCHANGE_RETVAL_IF(!NT_STATUS_IS_OK(status), MAPI_E_CALL_FAILED, mem_ctx); OPENCHANGE_RETVAL_IF(!mapi_response->mapi_repl, MAPI_E_CALL_FAILED, mem_ctx); retval = mapi_response->mapi_repl->error_code; OPENCHANGE_RETVAL_IF(retval, retval, mem_ctx); OPENCHANGE_CHECK_NOTIFICATION(session, mapi_response); mapi_table = (mapi_object_table_t *)obj_table->private_data; OPENCHANGE_RETVAL_IF(!mapi_table, MAPI_E_INVALID_PARAMETER, mem_ctx); obj_table->private_data = mapi_table; talloc_free(mapi_response); talloc_free(mem_ctx); return MAPI_E_SUCCESS; } openchange-2.0/libmapi/IMSProvider.c000066400000000000000000000413711223057412600174160ustar00rootroot00000000000000/* OpenChange MAPI implementation. Copyright (C) Julien Kerihuel 2007-2011. This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see . */ #include "libmapi/libmapi.h" #include "libmapi/mapicode.h" #include "libmapi/libmapi_private.h" #include "gen_ndr/ndr_exchange.h" #include "gen_ndr/ndr_exchange_c.h" #include #include #define TEVENT_DEPRECATED 1 #include /** \file IMSProvider.c \brief Provider operations */ /* * Log MAPI to one instance of a message store provider */ #pragma GCC diagnostic ignored "-Wdeprecated-declarations" static NTSTATUS provider_rpc_connection(TALLOC_CTX *parent_ctx, struct dcerpc_pipe **p, const char *binding, struct cli_credentials *credentials, const struct ndr_interface_table *table, struct loadparm_context *lp_ctx) { NTSTATUS status; struct tevent_context *ev; if (!binding) { DEBUG(3, ("You must specify a ncacn binding string\n")); return NT_STATUS_INVALID_PARAMETER; } ev = tevent_context_init(parent_ctx); tevent_loop_allow_nesting(ev); status = dcerpc_pipe_connect(parent_ctx, p, binding, table, credentials, ev, lp_ctx); if (!NT_STATUS_IS_OK(status)) { DEBUG(3, ("Failed to connect to remote server: %s %s\n", binding, nt_errstr(status))); } /* dcerpc_pipe_connect set errno, we have to unset it */ errno = 0; return status; } #pragma GCC diagnostic warning "-Wdeprecated-declarations" /** \details Build the binding string and flags given profile and global options. \param mapi_ctx pointer to the MAPI context \param mem_ctx pointer to the memory allocation context \param server string representing the server FQDN or IP address \param profile pointer to the MAPI profile structure \return valid allocated string on success, otherwise NULL */ static char *build_binding_string(struct mapi_context *mapi_ctx, TALLOC_CTX *mem_ctx, const char *server, struct mapi_profile *profile) { char *binding; /* Sanity Checks */ if (!profile) return NULL; if (!server) return NULL; if (!mapi_ctx) return NULL; binding = talloc_asprintf(mem_ctx, "ncacn_ip_tcp:%s[", server); /* If dump-data option is enabled */ if (mapi_ctx->dumpdata == true) { binding = talloc_strdup_append(binding, "print,"); } /* If seal option is enabled in the profile */ if (profile->seal == true) { binding = talloc_strdup_append(binding, "seal,"); } /* If localaddress parameter is available in the profile */ if (profile->localaddr) { binding = talloc_asprintf_append(binding, "localaddress=%s,", profile->localaddr); } binding = talloc_strdup_append(binding, "]"); return binding; } /** \details Returns the name of an NSPI server \param mapi_ctx pointer to the MAPI context \param session pointer to the MAPI session context \param server the Exchange server address (IP or FQDN) \param userDN optional user mailbox DN \param dsa pointer to a new dsa (return value), containing a valid allocated string on success, otherwise NULL \return MAPI_E_SUCCESS on success, otherwise a MAPI error and serverFQDN content set to NULL. \note The string returned can either be RfrGetNewDSA one on success, or a copy of the server's argument one on failure. If no server string is provided, NULL is returned. It is up to the developer to free the returned string when not needed anymore. */ _PUBLIC_ enum MAPISTATUS RfrGetNewDSA(struct mapi_context *mapi_ctx, struct mapi_session *session, const char *server, const char *userDN, char **dsa) { NTSTATUS status; TALLOC_CTX *mem_ctx; struct mapi_profile *profile; struct RfrGetNewDSA r; struct dcerpc_pipe *pipe; char *binding; char *ppszServer = NULL; /* Sanity Checks */ if (!mapi_ctx) return MAPI_E_NOT_INITIALIZED; if (!mapi_ctx->session) return MAPI_E_NOT_INITIALIZED; mem_ctx = talloc_named(session, 0, "RfrGetNewDSA"); profile = session->profile; binding = build_binding_string(mapi_ctx, mem_ctx, server, profile); status = provider_rpc_connection(mem_ctx, &pipe, binding, profile->credentials, &ndr_table_exchange_ds_rfr, mapi_ctx->lp_ctx); talloc_free(binding); if (!NT_STATUS_IS_OK(status)) { talloc_free(mem_ctx); return MAPI_E_NETWORK_ERROR; } r.in.ulFlags = 0x0; r.in.pUserDN = userDN ? userDN : ""; r.in.ppszUnused = NULL; r.in.ppszServer = (const char **) &ppszServer; status = dcerpc_RfrGetNewDSA_r(pipe->binding_handle, mem_ctx, &r); if ((!NT_STATUS_IS_OK(status) || !r.out.ppszServer || !*r.out.ppszServer) && server) { ppszServer = talloc_strdup((TALLOC_CTX *)session, server); } else { ppszServer = (char *)talloc_steal((TALLOC_CTX *)session, *r.out.ppszServer); } talloc_free(mem_ctx); *dsa = ppszServer; return MAPI_E_SUCCESS; } /** \details Returns the FQDN of the NSPI server corresponding to a DN \param mapi_ctx pointer to the MAPI context \param session pointer to the MAPI session context \param serverFQDN pointer to the server FQDN string (return value) \return MAPI_E_SUCCESS on success, otherwise a MAPI error and serverFQDN content set to NULL. */ _PUBLIC_ enum MAPISTATUS RfrGetFQDNFromLegacyDN(struct mapi_context *mapi_ctx, struct mapi_session *session, const char **serverFQDN) { NTSTATUS status; TALLOC_CTX *mem_ctx; struct mapi_profile *profile; struct RfrGetFQDNFromLegacyDN r; struct dcerpc_pipe *pipe; char *binding; const char *ppszServerFQDN; /* Sanity Checks */ OPENCHANGE_RETVAL_IF(!mapi_ctx, MAPI_E_NOT_INITIALIZED, NULL); OPENCHANGE_RETVAL_IF(!session, MAPI_E_NOT_INITIALIZED, NULL); mem_ctx = (TALLOC_CTX *)session; profile = session->profile; *serverFQDN = NULL; binding = build_binding_string(mapi_ctx, mem_ctx, profile->server, profile); status = provider_rpc_connection(mem_ctx, &pipe, binding, profile->credentials, &ndr_table_exchange_ds_rfr, mapi_ctx->lp_ctx); talloc_free(binding); OPENCHANGE_RETVAL_IF(NT_STATUS_EQUAL(status, NT_STATUS_CONNECTION_REFUSED), MAPI_E_NETWORK_ERROR, NULL); OPENCHANGE_RETVAL_IF(NT_STATUS_EQUAL(status, NT_STATUS_HOST_UNREACHABLE), MAPI_E_NETWORK_ERROR, NULL); OPENCHANGE_RETVAL_IF(NT_STATUS_EQUAL(status, NT_STATUS_PORT_UNREACHABLE), MAPI_E_NETWORK_ERROR, NULL); OPENCHANGE_RETVAL_IF(NT_STATUS_EQUAL(status, NT_STATUS_IO_TIMEOUT), MAPI_E_NETWORK_ERROR, NULL); OPENCHANGE_RETVAL_IF(NT_STATUS_EQUAL(status, NT_STATUS_OBJECT_NAME_NOT_FOUND), MAPI_E_NETWORK_ERROR, NULL); OPENCHANGE_RETVAL_IF(!NT_STATUS_IS_OK(status), MAPI_E_CALL_FAILED, NULL); r.in.ulFlags = 0x0; r.in.cbMailboxServerDN = strlen(profile->homemdb) + 1; r.in.szMailboxServerDN = profile->homemdb; r.out.ppszServerFQDN = &ppszServerFQDN; status = dcerpc_RfrGetFQDNFromLegacyDN_r(pipe->binding_handle, mem_ctx, &r); OPENCHANGE_RETVAL_IF(!NT_STATUS_IS_OK(status), MAPI_E_CALL_FAILED, mem_ctx); if (ppszServerFQDN) { *serverFQDN = ppszServerFQDN; } else { *serverFQDN = NULL; } return MAPI_E_SUCCESS; } enum MAPISTATUS Logon(struct mapi_session *session, struct mapi_provider *provider, enum PROVIDER_ID provider_id) { struct mapi_context *mapi_ctx; NTSTATUS status; TALLOC_CTX *mem_ctx; struct dcerpc_pipe *pipe; struct mapi_profile *profile; char *binding; char *server; int retval = 0; enum MAPISTATUS mapistatus; /*Sanity checks */ OPENCHANGE_RETVAL_IF(!session, MAPI_E_NOT_INITIALIZED, NULL); mem_ctx = (TALLOC_CTX *)provider; profile = session->profile; mapi_ctx = session->mapi_ctx; switch(provider_id) { case PROVIDER_ID_EMSMDB: emsmdb_retry: binding = build_binding_string(mapi_ctx, mem_ctx, profile->server, profile); status = provider_rpc_connection(mem_ctx, &pipe, binding, profile->credentials, &ndr_table_exchange_emsmdb, mapi_ctx->lp_ctx); talloc_free(binding); OPENCHANGE_RETVAL_IF(NT_STATUS_EQUAL(status, NT_STATUS_CONNECTION_REFUSED), MAPI_E_NETWORK_ERROR, NULL); OPENCHANGE_RETVAL_IF(NT_STATUS_EQUAL(status, NT_STATUS_HOST_UNREACHABLE), MAPI_E_NETWORK_ERROR, NULL); OPENCHANGE_RETVAL_IF(NT_STATUS_EQUAL(status, NT_STATUS_PORT_UNREACHABLE), MAPI_E_NETWORK_ERROR, NULL); OPENCHANGE_RETVAL_IF(NT_STATUS_EQUAL(status, NT_STATUS_IO_TIMEOUT), MAPI_E_NETWORK_ERROR, NULL); OPENCHANGE_RETVAL_IF(NT_STATUS_EQUAL(status, NT_STATUS_OBJECT_NAME_NOT_FOUND), MAPI_E_NETWORK_ERROR, NULL); OPENCHANGE_RETVAL_IF(!NT_STATUS_IS_OK(status), MAPI_E_LOGON_FAILED, NULL); switch (profile->exchange_version) { case 0x0: provider->ctx = emsmdb_connect(mem_ctx, session, pipe, profile->credentials, &retval); break; case 0x1: case 0x2: provider->ctx = emsmdb_connect_ex(mem_ctx, session, pipe, profile->credentials, &retval); break; } if (retval == ecNotEncrypted) { profile->seal = true; retval = 0; goto emsmdb_retry; } OPENCHANGE_RETVAL_IF(!provider->ctx, MAPI_E_LOGON_FAILED, NULL); if (server_version_at_least((struct emsmdb_context *)provider->ctx, 8, 0, 835, 0)){ struct emsmdb_context *prov_ctx = (struct emsmdb_context *)provider->ctx; status = dcerpc_secondary_context(pipe, &(prov_ctx->async_rpc_connection), &ndr_table_exchange_async_emsmdb); OPENCHANGE_RETVAL_IF(NT_STATUS_EQUAL(status, NT_STATUS_CONNECTION_REFUSED), MAPI_E_NETWORK_ERROR, NULL); OPENCHANGE_RETVAL_IF(NT_STATUS_EQUAL(status, NT_STATUS_HOST_UNREACHABLE), MAPI_E_NETWORK_ERROR, NULL); OPENCHANGE_RETVAL_IF(NT_STATUS_EQUAL(status, NT_STATUS_PORT_UNREACHABLE), MAPI_E_NETWORK_ERROR, NULL); OPENCHANGE_RETVAL_IF(NT_STATUS_EQUAL(status, NT_STATUS_IO_TIMEOUT), MAPI_E_NETWORK_ERROR, NULL); OPENCHANGE_RETVAL_IF(NT_STATUS_EQUAL(status, NT_STATUS_OBJECT_NAME_NOT_FOUND), MAPI_E_NETWORK_ERROR, NULL); OPENCHANGE_RETVAL_IF(!NT_STATUS_IS_OK(status), MAPI_E_LOGON_FAILED, NULL); mapistatus = emsmdb_async_connect(prov_ctx); OPENCHANGE_RETVAL_IF(mapistatus, mapistatus, NULL); } break; case PROVIDER_ID_NSPI: /* Call RfrGetNewDSA prior any NSPI call */ mapistatus = RfrGetNewDSA(mapi_ctx, session, profile->server, profile->mailbox, &server); OPENCHANGE_RETVAL_IF(mapistatus != MAPI_E_SUCCESS, mapistatus, NULL); binding = build_binding_string(mapi_ctx, mem_ctx, server, profile); talloc_free(server); status = provider_rpc_connection(mem_ctx, &pipe, binding, profile->credentials, &ndr_table_exchange_nsp, mapi_ctx->lp_ctx); talloc_free(binding); OPENCHANGE_RETVAL_IF(NT_STATUS_EQUAL(status, NT_STATUS_CONNECTION_REFUSED), MAPI_E_NETWORK_ERROR, NULL); OPENCHANGE_RETVAL_IF(NT_STATUS_EQUAL(status, NT_STATUS_HOST_UNREACHABLE), MAPI_E_NETWORK_ERROR, NULL); OPENCHANGE_RETVAL_IF(NT_STATUS_EQUAL(status, NT_STATUS_PORT_UNREACHABLE), MAPI_E_NETWORK_ERROR, NULL); OPENCHANGE_RETVAL_IF(NT_STATUS_EQUAL(status, NT_STATUS_IO_TIMEOUT), MAPI_E_NETWORK_ERROR, NULL); OPENCHANGE_RETVAL_IF(NT_STATUS_EQUAL(status, NT_STATUS_OBJECT_NAME_NOT_FOUND), MAPI_E_NETWORK_ERROR, NULL); OPENCHANGE_RETVAL_IF(!NT_STATUS_IS_OK(status), MAPI_E_LOGON_FAILED, NULL); provider->ctx = (void *)nspi_bind(provider, pipe, profile->credentials, profile->codepage, profile->language, profile->method); OPENCHANGE_RETVAL_IF(!provider->ctx, MAPI_E_LOGON_FAILED, NULL); break; default: OPENCHANGE_RETVAL_ERR(MAPI_E_NOT_FOUND, NULL); break; } return MAPI_E_SUCCESS; } /** \details Logoff an Exchange store This function uninitializes the MAPI session associated to the object. \param obj_store pointer to the store object \return MAPI_E_SUCCESS on success, otherwise MAPI_E_NOT_FOUND */ _PUBLIC_ enum MAPISTATUS Logoff(mapi_object_t *obj_store) { struct mapi_context *mapi_ctx; struct mapi_session *session; struct mapi_session *el; bool found = false; /* Sanity checks */ session = mapi_object_get_session(obj_store); OPENCHANGE_RETVAL_IF(!session, MAPI_E_INVALID_PARAMETER, NULL); mapi_ctx = session->mapi_ctx; OPENCHANGE_RETVAL_IF(!mapi_ctx, MAPI_E_NOT_INITIALIZED, NULL); for (el = mapi_ctx->session; el; el = el->next) { if (session == el) { found = true; mapi_object_release(obj_store); DLIST_REMOVE(mapi_ctx->session, el); MAPIFreeBuffer(session); break; } } return (found == true) ? MAPI_E_SUCCESS : MAPI_E_NOT_FOUND; } /** \details Retrieve a free logon identifier within the session \param session pointer to the MAPI session context \param logon_id pointer to the logon identifier the function returns \return MAPI_E_SUCCESS on success, otherwise MAPI eorr */ enum MAPISTATUS GetNewLogonId(struct mapi_session *session, uint8_t *logon_id) { int i = 0; /* Sanity checks */ OPENCHANGE_RETVAL_IF(!session, MAPI_E_INVALID_PARAMETER, NULL); OPENCHANGE_RETVAL_IF(!logon_id, MAPI_E_INVALID_PARAMETER, NULL); for (i = 0; i < 255; i++) { if (!session->logon_ids[i]) { session->logon_ids[i] = 1; *logon_id = i; return MAPI_E_SUCCESS; } } return MAPI_E_NOT_FOUND; } /** \details Initialize the notification subsystem This function initializes the notification subsystem, binds a local UDP port to receive Exchange (server side) notifications and configures the server to send notifications on this port. \param session the session context to register for notifications on. \return MAPI_E_SUCCESS on success, otherwise MAPI error. \note Developers may also call GetLastError() to retrieve the last MAPI error code. Possible MAPI error codes are: - MAPI_E_NOT_INITIALIZED: MAPI subsystem has not been initialized - MAPI_E_CALL_FAILED: A network problem was encountered during the transaction \sa RegisterAsyncNotification, Subscribe, Unsubscribe, MonitorNotification, GetLastError */ _PUBLIC_ enum MAPISTATUS RegisterNotification(struct mapi_session *session) { NTSTATUS status; struct mapi_context *mapi_ctx; struct emsmdb_context *emsmdb; TALLOC_CTX *mem_ctx; struct NOTIFKEY *lpKey; static uint8_t rand = 0; static uint8_t attempt = 0; /* Sanity checks */ OPENCHANGE_RETVAL_IF(!session, MAPI_E_INVALID_PARAMETER, NULL); OPENCHANGE_RETVAL_IF(!session->emsmdb, MAPI_E_SESSION_LIMIT, NULL); emsmdb = (struct emsmdb_context *)session->emsmdb->ctx; OPENCHANGE_RETVAL_IF(!emsmdb, MAPI_E_SESSION_LIMIT, NULL); mapi_ctx = session->mapi_ctx; OPENCHANGE_RETVAL_IF(!mapi_ctx, MAPI_E_NOT_INITIALIZED, NULL); mem_ctx = emsmdb->mem_ctx; /* bind local udp port */ session->notify_ctx = emsmdb_bind_notification(mapi_ctx, mem_ctx); if (!session->notify_ctx) return MAPI_E_CANCEL; /* tell exchange where to send notifications */ lpKey = talloc_zero(mem_ctx, struct NOTIFKEY); lpKey->cb = 8; lpKey->ab = talloc_array((TALLOC_CTX *)lpKey, uint8_t, lpKey->cb); memcpy(lpKey->ab, "libmapi", 7); retry: lpKey->ab[7] = rand; status = emsmdb_register_notification(session, lpKey); if (!NT_STATUS_IS_OK(status)) { if (attempt < 5) { rand++; attempt++; errno = 0; goto retry; } else { talloc_free(lpKey); return MAPI_E_CALL_FAILED; } } attempt = 0; talloc_free(lpKey); return MAPI_E_SUCCESS; } /** \details Create an asynchronous notification This function initializes the notification subsystem and configures the server to send notifications. Note that this call will block. \param session the session context to register for notifications on. \param resultFlag the result of the operation (true if there was anything returned) \return MAPI_E_SUCCESS on success, otherwise MAPI error. \note Developers may also call GetLastError() to retrieve the last MAPI error code. Possible MAPI error codes are: - MAPI_E_NOT_INITIALIZED: MAPI subsystem has not been initialized - MAPI_E_CALL_FAILED: A network problem was encountered during the transaction \sa RegisterNotification */ _PUBLIC_ enum MAPISTATUS RegisterAsyncNotification(struct mapi_session *session, uint32_t *resultFlag) { enum MAPISTATUS mapistatus; struct emsmdb_context *emsmdb; /* Sanity checks */ OPENCHANGE_RETVAL_IF(!session, MAPI_E_INVALID_PARAMETER, NULL); OPENCHANGE_RETVAL_IF(!session->emsmdb, MAPI_E_SESSION_LIMIT, NULL); emsmdb = (struct emsmdb_context *)session->emsmdb->ctx; session->notify_ctx = talloc_zero(emsmdb->mem_ctx, struct mapi_notify_ctx); session->notify_ctx->notifications = talloc_zero((TALLOC_CTX *)session->notify_ctx, struct notifications); session->notify_ctx->notifications->prev = NULL; session->notify_ctx->notifications->next = NULL; mapistatus = emsmdb_async_waitex(emsmdb, 0, resultFlag); OPENCHANGE_RETVAL_IF(mapistatus, mapistatus, NULL); return MAPI_E_SUCCESS; } openchange-2.0/libmapi/IMessage.c000066400000000000000000001625761223057412600167630ustar00rootroot00000000000000/* OpenChange MAPI implementation. Copyright (C) Julien Kerihuel 2007-2008. Copyright (C) Fabien Le Mentec 2007. This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see . */ #include "libmapi/libmapi.h" #include "libmapi/libmapi_private.h" #include "gen_ndr/ndr_exchange.h" #include /** \file IMessage.c \brief Operations on messages */ /** \details Create a new attachment This function creates a new attachment to an existing message. \param obj_message the message to attach to \param obj_attach the attachment Both objects need to exist before you call this message. obj_message should be a valid message on the server. obj_attach needs to be initialised. \code enum MAPISTATUS retval; mapi_object_t obj_message; mapi_object_t obj_attach; ... open or create the obj_message ... mapi_object_init(&obj_attach); retval = CreateAttach(&obj_message, &obj_attach); ... check the return value ... ... use SetProps() to set the attachment up ... ... perhaps OpenStream() / WriteStream() / CommitStream() on obj_attach ... // Save the changes to the attachment and then the message retval = SaveChangesAttachment(&obj_message, &obj_attach, KeepOpenReadOnly); ... check the return value ... retval = SaveChangesMessage(&obj_folder, &obj_message, KeepOpenReadOnly); ... check the return value ... \endcode \return MAPI_E_SUCCESS on success, otherwise MAPI error. \note Developers may also call GetLastError() to retrieve the last MAPI error code. Possible MAPI error codes are: - MAPI_E_NOT_INITIALIZED: MAPI subsystem has not been initialized - MAPI_E_CALL_FAILED: A network problem was encountered during the transaction \sa CreateMessage, GetAttachmentTable, OpenAttach, GetLastError */ _PUBLIC_ enum MAPISTATUS CreateAttach(mapi_object_t *obj_message, mapi_object_t *obj_attach) { struct mapi_request *mapi_request; struct mapi_response *mapi_response; struct EcDoRpc_MAPI_REQ *mapi_req; struct CreateAttach_req request; struct mapi_session *session; NTSTATUS status; enum MAPISTATUS retval; uint32_t size = 0; TALLOC_CTX *mem_ctx; uint8_t logon_id; /* Sanity checks */ OPENCHANGE_RETVAL_IF(!obj_message, MAPI_E_INVALID_PARAMETER, NULL); session = mapi_object_get_session(obj_message); OPENCHANGE_RETVAL_IF(!session, MAPI_E_INVALID_PARAMETER, NULL); if ((retval = mapi_object_get_logon_id(obj_message, &logon_id)) != MAPI_E_SUCCESS) return retval; mem_ctx = talloc_named(session, 0, "CreateAttach"); size = 0; /* Fill the CreateAttach operation */ request.handle_idx = 0x1; size += sizeof (uint8_t); /* Fill the MAPI_REQ request */ mapi_req = talloc_zero(mem_ctx, struct EcDoRpc_MAPI_REQ); mapi_req->opnum = op_MAPI_CreateAttach; mapi_req->logon_id = logon_id; mapi_req->handle_idx = 0; mapi_req->u.mapi_CreateAttach = request; size += 5; /* Fill the mapi_request structure */ mapi_request = talloc_zero(mem_ctx, struct mapi_request); mapi_request->mapi_len = size + (sizeof (uint32_t) * 2); mapi_request->length = size; mapi_request->mapi_req = mapi_req; mapi_request->handles = talloc_array(mem_ctx, uint32_t, 2); mapi_request->handles[0] = mapi_object_get_handle(obj_message); mapi_request->handles[1] = 0xffffffff; status = emsmdb_transaction_wrapper(session, mem_ctx, mapi_request, &mapi_response); OPENCHANGE_RETVAL_IF(!NT_STATUS_IS_OK(status), MAPI_E_CALL_FAILED, mem_ctx); OPENCHANGE_RETVAL_IF(!mapi_response->mapi_repl, MAPI_E_CALL_FAILED, mem_ctx); retval = mapi_response->mapi_repl->error_code; OPENCHANGE_RETVAL_IF(retval, retval, mem_ctx); OPENCHANGE_CHECK_NOTIFICATION(session, mapi_response); /* Set object session and handle */ mapi_object_set_session(obj_attach, session); mapi_object_set_handle(obj_attach, mapi_response->handles[1]); mapi_object_set_logon_id(obj_attach, logon_id); talloc_free(mapi_response); talloc_free(mem_ctx); return MAPI_E_SUCCESS; } /** \details Delete an attachment from a message This function deletes one attachment from a message. The attachment to be deleted is specified by its PR_ATTACH_NUM \param obj_message the message to operate on \param AttachmentID the attachment number \return MAPI_E_SUCCESS on success, otherwise MAPI error. \note Developers may also call GetLastError() to retrieve the last MAPI error code. Possible MAPI error codes are: - MAPI_E_NOT_INITIALIZED: MAPI subsystem has not been initialized - MAPI_E_CALL_FAILED: A network problem was encountered during the transaction \sa CreateMessage, GetAttachmentTable, GetLastError */ _PUBLIC_ enum MAPISTATUS DeleteAttach(mapi_object_t *obj_message, uint32_t AttachmentID) { struct mapi_request *mapi_request; struct mapi_response *mapi_response; struct EcDoRpc_MAPI_REQ *mapi_req; struct DeleteAttach_req request; struct mapi_session *session; NTSTATUS status; enum MAPISTATUS retval; uint32_t size = 0; TALLOC_CTX *mem_ctx; uint8_t logon_id; /* Sanity checks */ OPENCHANGE_RETVAL_IF(!obj_message, MAPI_E_INVALID_PARAMETER, NULL); session = mapi_object_get_session(obj_message); OPENCHANGE_RETVAL_IF(!session, MAPI_E_INVALID_PARAMETER, NULL); if ((retval = mapi_object_get_logon_id(obj_message, &logon_id)) != MAPI_E_SUCCESS) return retval; mem_ctx = talloc_named(session, 0, "DeleteAttach"); size = 0; /* Fill the DeleteAttach operation */ request.AttachmentID = AttachmentID; size += sizeof (uint32_t); /* Fill the MAPI_REQ request */ mapi_req = talloc_zero(mem_ctx, struct EcDoRpc_MAPI_REQ); mapi_req->opnum = op_MAPI_DeleteAttach; mapi_req->logon_id = logon_id; mapi_req->handle_idx = 0; mapi_req->u.mapi_DeleteAttach = request; size += 5; /* Fill the mapi_request structure */ mapi_request = talloc_zero(mem_ctx, struct mapi_request); mapi_request->mapi_len = size + sizeof (uint32_t); mapi_request->length = size; mapi_request->mapi_req = mapi_req; mapi_request->handles = talloc_array(mem_ctx, uint32_t, 1); mapi_request->handles[0] = mapi_object_get_handle(obj_message); status = emsmdb_transaction_wrapper(session, mem_ctx, mapi_request, &mapi_response); OPENCHANGE_RETVAL_IF(!NT_STATUS_IS_OK(status), MAPI_E_CALL_FAILED, mem_ctx); OPENCHANGE_RETVAL_IF(!mapi_response->mapi_repl, MAPI_E_CALL_FAILED, mem_ctx); retval = mapi_response->mapi_repl->error_code; OPENCHANGE_RETVAL_IF(retval, retval, mem_ctx); OPENCHANGE_CHECK_NOTIFICATION(session, mapi_response); talloc_free(mapi_response); talloc_free(mem_ctx); return MAPI_E_SUCCESS; } /** \details Retrieve the attachment table for a message \param obj_message the message \param obj_table the attachment table for the message \return MAPI_E_SUCCESS on success, otherwise MAPI error. \note Developers may also call GetLastError() to retrieve the last MAPI error code. Possible MAPI error codes are: - MAPI_E_NOT_INITIALIZED: MAPI subsystem has not been initialized - MAPI_E_CALL_FAILED: A network problem was encountered during the transaction \sa CreateMessage, OpenMessage, CreateAttach, OpenAttach, GetLastError */ _PUBLIC_ enum MAPISTATUS GetAttachmentTable(mapi_object_t *obj_message, mapi_object_t *obj_table) { struct mapi_request *mapi_request; struct mapi_response *mapi_response; struct EcDoRpc_MAPI_REQ *mapi_req; struct GetAttachmentTable_req request; struct mapi_session *session; NTSTATUS status; enum MAPISTATUS retval; TALLOC_CTX *mem_ctx; uint32_t size = 0; uint8_t logon_id; /* Sanity checks */ OPENCHANGE_RETVAL_IF(!obj_message, MAPI_E_INVALID_PARAMETER, NULL); OPENCHANGE_RETVAL_IF(!obj_table, MAPI_E_INVALID_PARAMETER, NULL); session = mapi_object_get_session(obj_message); OPENCHANGE_RETVAL_IF(!session, MAPI_E_INVALID_PARAMETER, NULL); if ((retval = mapi_object_get_logon_id(obj_message, &logon_id)) != MAPI_E_SUCCESS) return retval; mem_ctx = talloc_named(session, 0, "GetAttachmentTable"); size = 0; /* Fill the GetAttachmentTable operation */ request.handle_idx = 1; size += sizeof (uint8_t); request.TableFlags = 0x0; size += sizeof (uint8_t); /* Fill the MAPI_REQ request */ mapi_req = talloc_zero(mem_ctx, struct EcDoRpc_MAPI_REQ); mapi_req->opnum = op_MAPI_GetAttachmentTable; mapi_req->logon_id = logon_id; mapi_req->handle_idx = 0; mapi_req->u.mapi_GetAttachmentTable = request; size += 5; /* Fill the mapi_request structure */ mapi_request = talloc_zero(mem_ctx, struct mapi_request); mapi_request->mapi_len = size + sizeof (uint32_t) * 2; mapi_request->length = size; mapi_request->mapi_req = mapi_req; mapi_request->handles = talloc_array(mem_ctx, uint32_t, 2); mapi_request->handles[0] = mapi_object_get_handle(obj_message); mapi_request->handles[1] = 0xffffffff; status = emsmdb_transaction_wrapper(session, mem_ctx, mapi_request, &mapi_response); OPENCHANGE_RETVAL_IF(!NT_STATUS_IS_OK(status), MAPI_E_CALL_FAILED, mem_ctx); OPENCHANGE_RETVAL_IF(!mapi_response->mapi_repl, MAPI_E_CALL_FAILED, mem_ctx); retval = mapi_response->mapi_repl->error_code; OPENCHANGE_RETVAL_IF(retval, retval, mem_ctx); OPENCHANGE_CHECK_NOTIFICATION(session, mapi_response); /* Set object session and handle */ mapi_object_set_session(obj_table, session); mapi_object_set_handle(obj_table, mapi_response->handles[mapi_response->mapi_repl->handle_idx]); mapi_object_set_logon_id(obj_table, logon_id); talloc_free(mapi_response); talloc_free(mem_ctx); return MAPI_E_SUCCESS; } /** \details Get the valid attachment IDs for a message This function returns the list of valid attachment IDs for a message. You can then use these IDs with the OpenAttach and DeleteAttach functions. \param obj_message the message to operate on \param NumAttachments the number of attachments for the message \param AttachmentIds array of attachment Ids The AttachmentIds array has NumAttachments elements. \return MAPI_E_SUCCESS on success, otherwise MAPI error. \note Developers may also call GetLastError() to retrieve the last MAPI error code. Possible MAPI error codes are: - MAPI_E_NOT_INITIALIZED: MAPI subsystem has not been initialized - MAPI_E_INVALID_PARAMETER: a parameter is incorrect (e.g. null pointer) - MAPI_E_CALL_FAILED: A network problem was encountered during the transaction \sa OpenAttach, DeleteAttach */ _PUBLIC_ enum MAPISTATUS GetValidAttach(mapi_object_t *obj_message, uint16_t *NumAttachments, uint32_t **AttachmentIds) { struct mapi_request *mapi_request; struct mapi_response *mapi_response; struct EcDoRpc_MAPI_REQ *mapi_req; struct GetValidAttachments_repl *reply; struct mapi_session *session; NTSTATUS status; enum MAPISTATUS retval; uint32_t size = 0; TALLOC_CTX *mem_ctx; uint8_t logon_id; /* Sanity checks */ OPENCHANGE_RETVAL_IF(!obj_message, MAPI_E_INVALID_PARAMETER, NULL); OPENCHANGE_RETVAL_IF(!NumAttachments, MAPI_E_INVALID_PARAMETER, NULL); OPENCHANGE_RETVAL_IF(!AttachmentIds, MAPI_E_INVALID_PARAMETER, NULL); session = mapi_object_get_session(obj_message); OPENCHANGE_RETVAL_IF(!session, MAPI_E_INVALID_PARAMETER, NULL); if ((retval = mapi_object_get_logon_id(obj_message, &logon_id)) != MAPI_E_SUCCESS) return retval; mem_ctx = talloc_named(session, 0, "GetValidAttach"); size = 0; /* Fill the MAPI_REQ request */ mapi_req = talloc_zero(mem_ctx, struct EcDoRpc_MAPI_REQ); mapi_req->opnum = op_MAPI_GetValidAttachments; mapi_req->logon_id = logon_id; mapi_req->handle_idx = 0; size += 5; /* Fill the mapi_request structure */ mapi_request = talloc_zero(mem_ctx, struct mapi_request); mapi_request->mapi_len = size + sizeof (uint32_t); mapi_request->length = size; mapi_request->mapi_req = mapi_req; mapi_request->handles = talloc_array(mem_ctx, uint32_t, 1); mapi_request->handles[0] = mapi_object_get_handle(obj_message); status = emsmdb_transaction_wrapper(session, mem_ctx, mapi_request, &mapi_response); OPENCHANGE_RETVAL_IF(!NT_STATUS_IS_OK(status), MAPI_E_CALL_FAILED, mem_ctx); OPENCHANGE_RETVAL_IF(!mapi_response->mapi_repl, MAPI_E_CALL_FAILED, mem_ctx); retval = mapi_response->mapi_repl->error_code; OPENCHANGE_RETVAL_IF(retval, retval, mem_ctx); OPENCHANGE_CHECK_NOTIFICATION(session, mapi_response); /* Retrieve the result */ reply = &(mapi_response->mapi_repl->u.mapi_GetValidAttachments); *NumAttachments = reply->AttachmentIdCount; *AttachmentIds = talloc_steal((TALLOC_CTX *)session, reply->AttachmentIdArray); talloc_free(mapi_response); talloc_free(mem_ctx); return MAPI_E_SUCCESS; } /** \details Open an attachment to a message This function opens one attachment from a message. The attachment to be opened is specified by its PR_ATTACH_NUM. \param obj_message the message to operate on \param AttachmentID the attachment number \param obj_attach the resulting attachment object \return MAPI_E_SUCCESS on success, otherwise MAPI error. \note Developers may also call GetLastError() to retrieve the last MAPI error code. Possible MAPI error codes are: - MAPI_E_NOT_INITIALIZED: MAPI subsystem has not been initialized - MAPI_E_CALL_FAILED: A network problem was encountered during the transaction \sa CreateMessage, CreateAttach, GetAttachmentTable, GetLastError */ _PUBLIC_ enum MAPISTATUS OpenAttach(mapi_object_t *obj_message, uint32_t AttachmentID, mapi_object_t *obj_attach) { struct mapi_request *mapi_request; struct mapi_response *mapi_response; struct EcDoRpc_MAPI_REQ *mapi_req; struct OpenAttach_req request; struct mapi_session *session; NTSTATUS status; enum MAPISTATUS retval; uint32_t size = 0; TALLOC_CTX *mem_ctx; uint8_t logon_id; /* Sanity checks */ OPENCHANGE_RETVAL_IF(!obj_message, MAPI_E_INVALID_PARAMETER, NULL); session = mapi_object_get_session(obj_message); OPENCHANGE_RETVAL_IF(!session, MAPI_E_INVALID_PARAMETER, NULL); if ((retval = mapi_object_get_logon_id(obj_message, &logon_id)) != MAPI_E_SUCCESS) return retval; mem_ctx = talloc_named(session, 0, "OpenAttach"); size = 0; /* Fill the OpenAttach operation */ request.handle_idx = 0x1; size += sizeof(uint8_t); request.OpenAttachmentFlags = OpenAttachmentFlags_ReadOnly; size += sizeof(uint8_t); request.AttachmentID = AttachmentID; size += sizeof(uint32_t); /* Fill the MAPI_REQ request */ mapi_req = talloc_zero(mem_ctx, struct EcDoRpc_MAPI_REQ); mapi_req->opnum = op_MAPI_OpenAttach; mapi_req->logon_id = logon_id; mapi_req->handle_idx = 0; mapi_req->u.mapi_OpenAttach = request; size += 5; /* Fill the mapi_request structure */ mapi_request = talloc_zero(mem_ctx, struct mapi_request); mapi_request->mapi_len = size + sizeof (uint32_t) * 2; mapi_request->length = size; mapi_request->mapi_req = mapi_req; mapi_request->handles = talloc_array(mem_ctx, uint32_t, 2); mapi_request->handles[0] = mapi_object_get_handle(obj_message); mapi_request->handles[1] = 0xffffffff; status = emsmdb_transaction_wrapper(session, mem_ctx, mapi_request, &mapi_response); OPENCHANGE_RETVAL_IF(!NT_STATUS_IS_OK(status), MAPI_E_CALL_FAILED, mem_ctx); OPENCHANGE_RETVAL_IF(!mapi_response->mapi_repl, MAPI_E_CALL_FAILED, mem_ctx); retval = mapi_response->mapi_repl->error_code; OPENCHANGE_RETVAL_IF(retval, retval, mem_ctx); OPENCHANGE_CHECK_NOTIFICATION(session, mapi_response); /* Set object session and handle */ mapi_object_set_session(obj_attach, session); mapi_object_set_handle(obj_attach, mapi_response->handles[1]); mapi_object_set_logon_id(obj_attach, logon_id); talloc_free(mapi_response); talloc_free(mem_ctx); return MAPI_E_SUCCESS; } /** \details Set the type of a recipient The function sets the recipient type (RecipClass) in the aRow parameter. ResolveNames should be used to fill the SRow structure. \param aRow the row to set \param RecipClass the type of recipient to set on the specified row \return MAPI_E_SUCCESS on success, otherwise MAPI error. \note Developers may also call GetLastError() to retrieve the last MAPI error code. Possible MAPI error codes are: - MAPI_E_INVALID_PARAMETER: The aRow parameter was not set properly. \sa ResolveNames, ModifyRecipients, GetLastError */ _PUBLIC_ enum MAPISTATUS SetRecipientType(struct SRow *aRow, enum ulRecipClass RecipClass) { enum MAPISTATUS retval; struct SPropValue lpProp; lpProp.ulPropTag = PR_RECIPIENT_TYPE; lpProp.value.l = RecipClass; retval = SRow_addprop(aRow, lpProp); OPENCHANGE_RETVAL_IF(retval, retval, NULL); return MAPI_E_SUCCESS; } /* * retrieve the organization length for Exchange recipients */ uint8_t mapi_recipients_get_org_length(struct mapi_profile *profile) { if (profile->mailbox && profile->username) return (strlen(profile->mailbox) - strlen(profile->username)); return 0; } /** \details RecipientFlags bitmask calculation for RecipientRows structure. \param aRow pointer to the SRow structures with the properties to pass to ModifyRecipients. According to MS-OXCDATA 2.9.3.1 RecipientFlags structure, the bitmask can be represented as the following: 0 3 4 5 6 7 8 9 10 11 15 16 +------+---+---+---+---+---+---+---+---+----------+---+ | Type | E | D | T | S | R | N | U | I | Reserved | O | +------+---+---+---+---+---+---+---+---+----------+---+ Type: (0x7 mask) 3-bit enumeration describing the Address Type (PR_ADDRTYPE) E: (0x8) Email address included (PR_SMTP_ADDRESS) D: (0x10) Display Name included (PR_DISPLAY_NAME) T: (0x20) Transmittable Display Name included (PR_TRANSMITTABLE_DISPLAY_NAME) S: (0x40) If Transmittable Display Name is the same than Display Name (D == T) R: (0x80) Different transport is responsible for delivery N: (0x100) Recipient does not support receiving Rich Text messages U: (0x200) If we are using Unicode properties I: (0x400) If Simple Display Name is included (PR_7BIT_DISPLAY_NAME) Reserved: Must be zero O: (0x8000) Non-standard address type is used The PidTag property to bitmask mapping was unclear for some fields. mapiproxy between Outlook 2003 and Exchange 2010 has been used for this purpose. For further information about PidTagAddressType, refer to [MS-OXCMAIL] section 2.1.1.9 \return uint16_t holding the RecipientFlags value. 0 is returned when an inconsistency or a failure occurs */ uint16_t mapi_recipients_RecipientFlags(struct SRow *aRow) { uint16_t bitmask; struct SPropValue *lpProp = NULL; bool unicode = false; const char *addrtype = NULL; const char *tmp = NULL; const char *display_name = NULL; const char *transmit_display_name = NULL; /* Sanity Checks */ if (!aRow) return 0; bitmask = 0; /* (Type) - 0x0 to 0x7: PR_ADDRTYPE */ lpProp = get_SPropValue_SRow(aRow, PR_ADDRTYPE); if (lpProp && lpProp->value.lpszA) { addrtype = lpProp->value.lpszA; } else { lpProp = get_SPropValue_SRow(aRow, PR_ADDRTYPE_UNICODE); if (lpProp && lpProp->value.lpszW) { unicode = true; addrtype = lpProp->value.lpszW; } } if (!addrtype) { return 0; } /* WARNING: This check is yet incomplete */ if (!strcmp("EX", addrtype)) { bitmask |= 0x1; } else if (!strcmp("SMTP", addrtype)) { bitmask |= 0x3; } /* (E) - 0x8: PR_SMTP_ADDRESS (If we have Exchange type, we don't need it) */ if (strcmp(addrtype, "EX")) { lpProp = get_SPropValue_SRow(aRow, (unicode == true) ? PR_SMTP_ADDRESS_UNICODE: PR_SMTP_ADDRESS); if (lpProp) { tmp = (unicode == true) ? lpProp->value.lpszW : lpProp->value.lpszA; if (tmp) { bitmask |= 0x8; } } } /* (D) - 0x10: PR_DISPLAY_NAME */ lpProp = get_SPropValue_SRow(aRow, (unicode == true) ? PR_DISPLAY_NAME_UNICODE : PR_DISPLAY_NAME); if (lpProp) { display_name = (unicode == true) ? lpProp->value.lpszW : lpProp->value.lpszA; if (display_name) { bitmask |= 0x10; } } /* (T) - 0x20: PR_TRANSMITTABLE_DISPLAY_NAME */ lpProp = get_SPropValue_SRow(aRow, (unicode == true) ? PR_TRANSMITTABLE_DISPLAY_NAME_UNICODE : PR_TRANSMITTABLE_DISPLAY_NAME); if (lpProp) { transmit_display_name = (unicode == true) ? lpProp->value.lpszW : lpProp->value.lpszA; if (transmit_display_name) { if (!display_name) { bitmask |= 0x20; } else if (display_name && strcmp(display_name, transmit_display_name)) { bitmask |= 0x20; } } } /* (S) - 0x40: Does D equals T? If so, we shouldn't include PR_TRANSMITTABLE_DISPLAY_NAME within RecipientRows */ if (display_name && transmit_display_name) { if (!strcmp(display_name, transmit_display_name)) { bitmask |= 0x40; } } /* (R) - 0x80: Different transport is responsible for delivery */ if (addrtype && strcmp(addrtype, "EX")) { bitmask |= 0x80; } /* (N) - 0x100: Recipient doesn't support rich-text messages */ lpProp = get_SPropValue_SRow(aRow, PR_SEND_RICH_INFO); if (lpProp && (lpProp->value.b == false)) { bitmask |= 0x100; } /* (U) - 0x200: Unicode properties */ if (unicode == true) { bitmask |= 0x200; } /* (I) - 0x400: PR_7BIT_DISPLAY_NAME */ lpProp = get_SPropValue_SRow(aRow, (unicode == true) ? PR_7BIT_DISPLAY_NAME_UNICODE : PR_7BIT_DISPLAY_NAME); if (lpProp) { tmp = (unicode == true) ? lpProp->value.lpszW : lpProp->value.lpszA; if (tmp) { bitmask |= 0x400; } } return bitmask; } /** \details Adds, deletes or modifies message recipients \param obj_message the message to change the recipients for \param SRowSet the recipients to add \return MAPI_E_SUCCESS on success, otherwise MAPI error. When using this function, take care to ensure that the properties that are present on the first row in the rowset are also present in all the following rows. If any are missing, this function will suffer NDR errors. This includes making sure that any string properties are present in the same encoding (e.g. if you use PR_SMTP_ADDRESS_UNICODE on the first row, don't provide PR_SMTP_ADDRESS on subsequent rows). \note Developers may also call GetLastError() to retrieve the last MAPI error code. Possible MAPI error codes are: - MAPI_E_NOT_INITIALIZED: MAPI subsystem has not been initialized - MAPI_E_CALL_FAILED: A network problem was encountered during the transaction \bug ModifyRecipients can only add recipients. \sa CreateMessage, ResolveNames, SetRecipientType, GetLastError */ _PUBLIC_ enum MAPISTATUS ModifyRecipients(mapi_object_t *obj_message, struct SRowSet *SRowSet) { struct mapi_request *mapi_request; struct mapi_response *mapi_response; struct EcDoRpc_MAPI_REQ *mapi_req; struct ModifyRecipients_req request; struct mapi_session *session; NTSTATUS status; enum MAPISTATUS retval; uint32_t size = 0; TALLOC_CTX *mem_ctx; unsigned long i_prop, j; unsigned long i_recip; uint32_t count; uint8_t logon_id; /* Sanity checks */ OPENCHANGE_RETVAL_IF(!obj_message, MAPI_E_INVALID_PARAMETER, NULL); OPENCHANGE_RETVAL_IF(!SRowSet, MAPI_E_NOT_INITIALIZED, NULL); OPENCHANGE_RETVAL_IF(!SRowSet->aRow, MAPI_E_NOT_INITIALIZED, NULL); session = mapi_object_get_session(obj_message); OPENCHANGE_RETVAL_IF(!session, MAPI_E_INVALID_PARAMETER, NULL); if ((retval = mapi_object_get_logon_id(obj_message, &logon_id)) != MAPI_E_SUCCESS) return retval; mem_ctx = talloc_named(session, 0, "ModifyRecipients"); size = 0; /* Fill the ModifyRecipients operation */ request.prop_count = SRowSet->aRow[0].cValues; size += sizeof(uint16_t); /* * append here property tags that can be fetched with * ResolveNames but shouldn't be included in ModifyRecipients rows */ request.properties = get_MAPITAGS_SRow(mem_ctx, &SRowSet->aRow[0], &count); request.prop_count = MAPITAGS_delete_entries(request.properties, count, 19, PR_ENTRYID, PR_DISPLAY_NAME, PR_DISPLAY_NAME_UNICODE, PR_DISPLAY_NAME_ERROR, PR_GIVEN_NAME, PR_GIVEN_NAME_UNICODE, PR_GIVEN_NAME_ERROR, PR_EMAIL_ADDRESS, PR_EMAIL_ADDRESS_UNICODE, PR_TRANSMITTABLE_DISPLAY_NAME, PR_TRANSMITTABLE_DISPLAY_NAME_UNICODE, PR_RECIPIENT_TYPE, PR_ADDRTYPE, PR_ADDRTYPE_UNICODE, PR_ADDRTYPE_ERROR, PR_SEND_INTERNET_ENCODING, PR_SEND_INTERNET_ENCODING_ERROR, PR_SEND_RICH_INFO, PR_SEND_RICH_INFO_ERROR); size += request.prop_count * sizeof(uint32_t); request.cValues = SRowSet->cRows; size += sizeof(uint16_t); request.RecipientRow = talloc_array(mem_ctx, struct ModifyRecipientRow, request.cValues); for (i_recip = 0; i_recip < request.cValues; i_recip++) { struct SRow *aRow; struct RecipientRow *RecipientRow; struct ndr_push *ndr; struct mapi_SPropValue mapi_sprop; const uint32_t *RecipClass = 0; ndr = talloc_zero(mem_ctx, struct ndr_push); aRow = &(SRowSet->aRow[i_recip]); RecipientRow = &(request.RecipientRow[i_recip].RecipientRow); request.RecipientRow[i_recip].idx = i_recip; size += sizeof(uint32_t); RecipClass = (const uint32_t *) find_SPropValue_data(aRow, PR_RECIPIENT_TYPE); OPENCHANGE_RETVAL_IF(!RecipClass, MAPI_E_INVALID_PARAMETER, mem_ctx); request.RecipientRow[i_recip].RecipClass = (enum ulRecipClass) *RecipClass; size += sizeof(uint8_t); RecipientRow->RecipientFlags = mapi_recipients_RecipientFlags(aRow); /* (Type) - 0x0 to 0x7: Recipient type (Exchange, SMTP or other?) */ switch (RecipientRow->RecipientFlags & 0x7) { case 0x1: // RecipientRow->type.EXCHANGE.organization_length = mapi_recipients_get_org_length(session->profile); RecipientRow->AddressPrefixUsed.prefix_size = 0; RecipientRow->DisplayType.display_type = SINGLE_RECIPIENT; switch (RecipientRow->RecipientFlags & 0x200) { case 0x0: RecipientRow->X500DN.recipient_x500name = (const char *) find_SPropValue_data(aRow, PR_EMAIL_ADDRESS); break; case 0x200: RecipientRow->X500DN.recipient_x500name = (const char *) find_SPropValue_data(aRow, PR_EMAIL_ADDRESS_UNICODE); break; } size += sizeof(uint32_t) + strlen(RecipientRow->X500DN.recipient_x500name) + 1; break; case 0x3: size += sizeof(uint16_t); break; } /* (E) - 0x8: PR_SMTP_ADDRESS */ switch (RecipientRow->RecipientFlags & 0x208) { case (0x8): RecipientRow->EmailAddress.lpszA = (const char *) find_SPropValue_data(aRow, PR_SMTP_ADDRESS); size += strlen(RecipientRow->EmailAddress.lpszA) + 1; break; case (0x208): RecipientRow->EmailAddress.lpszW = (const char *) find_SPropValue_data(aRow, PR_SMTP_ADDRESS_UNICODE); size += get_utf8_utf16_conv_length(RecipientRow->EmailAddress.lpszW); break; default: break; } /* (D) - 0x10: PR_DISPLAY_NAME */ switch (RecipientRow->RecipientFlags & 0x210) { case (0x10): RecipientRow->DisplayName.lpszA = (const char *) find_SPropValue_data(aRow, PR_DISPLAY_NAME); size += strlen(RecipientRow->DisplayName.lpszA) + 1; break; case (0x210): RecipientRow->DisplayName.lpszW = (const char *) find_SPropValue_data(aRow, PR_DISPLAY_NAME_UNICODE); size += get_utf8_utf16_conv_length(RecipientRow->DisplayName.lpszW); break; default: break; } /* (T) - 0x20: PR_TRANSMITTABLE_DISPLAY_NAME */ switch (RecipientRow->RecipientFlags & 0x260) { case (0x20): RecipientRow->TransmittableDisplayName.lpszA = (const char *) find_SPropValue_data(aRow, PR_TRANSMITTABLE_DISPLAY_NAME); size += strlen(RecipientRow->TransmittableDisplayName.lpszA) + 1; break; case (0x220): RecipientRow->TransmittableDisplayName.lpszW = (const char *) find_SPropValue_data(aRow, PR_TRANSMITTABLE_DISPLAY_NAME_UNICODE); size += get_utf8_utf16_conv_length(RecipientRow->TransmittableDisplayName.lpszW); break; default: break; } /* (I) - 0x400: PR_7BIT_DISPLAY_NAME */ switch(RecipientRow->RecipientFlags & 0x600) { case (0x400): RecipientRow->SimpleDisplayName.lpszA = (const char *) find_SPropValue_data(aRow, PR_7BIT_DISPLAY_NAME); size += strlen(RecipientRow->SimpleDisplayName.lpszA) + 1; break; case (0x600): RecipientRow->SimpleDisplayName.lpszW = (const char *) find_SPropValue_data(aRow, PR_7BIT_DISPLAY_NAME_UNICODE); size += get_utf8_utf16_conv_length(RecipientRow->SimpleDisplayName.lpszW); break; default: break; } RecipientRow->prop_count = request.prop_count; size += sizeof(uint16_t); RecipientRow->layout = 0; size += sizeof(uint8_t); /* for each property, we set the switch values and ndr_flags then call mapi_SPropValue_CTR */ ndr_set_flags(&ndr->flags, LIBNDR_FLAG_NOALIGN); for (i_prop = 0; i_prop < request.prop_count; i_prop++) { for (j = 0; j < aRow->cValues; j++) { if (aRow->lpProps[j].ulPropTag == request.properties[i_prop]) { enum ndr_err_code ndr_retval; ndr_retval = ndr_push_set_switch_value(ndr, &mapi_sprop.value, (aRow->lpProps[j].ulPropTag & 0xFFFF)); if (!NDR_ERR_CODE_IS_SUCCESS(ndr_retval)) return MAPI_E_CALL_FAILED; cast_mapi_SPropValue(mem_ctx, &mapi_sprop, &aRow->lpProps[j]); ndr_push_mapi_SPropValue_CTR(ndr, NDR_SCALARS, &mapi_sprop.value); } } } RecipientRow->prop_values.length = ndr->offset; RecipientRow->prop_values.data = ndr->data; /* add the blob size field */ size += sizeof(uint16_t); size += RecipientRow->prop_values.length; } /* Fill the MAPI_REQ request */ mapi_req = talloc_zero(mem_ctx, struct EcDoRpc_MAPI_REQ); mapi_req->opnum = op_MAPI_ModifyRecipients; mapi_req->logon_id = logon_id; mapi_req->handle_idx = 0; mapi_req->u.mapi_ModifyRecipients = request; size += 5; /* Fill the mapi_request structure */ mapi_request = talloc_zero(mem_ctx, struct mapi_request); mapi_request->mapi_len = size + sizeof(uint32_t); mapi_request->length = size; mapi_request->mapi_req = mapi_req; mapi_request->handles = talloc_array(mem_ctx, uint32_t, 1); mapi_request->handles[0] = mapi_object_get_handle(obj_message); status = emsmdb_transaction_wrapper(session, mem_ctx, mapi_request, &mapi_response); OPENCHANGE_RETVAL_IF(!NT_STATUS_IS_OK(status), MAPI_E_CALL_FAILED, mem_ctx); OPENCHANGE_RETVAL_IF(!mapi_response->mapi_repl, MAPI_E_CALL_FAILED, mem_ctx); retval = mapi_response->mapi_repl->error_code; OPENCHANGE_RETVAL_IF(retval, retval, mem_ctx); OPENCHANGE_CHECK_NOTIFICATION(session, mapi_response); talloc_free(mapi_response); talloc_free(mem_ctx); errno = 0; return MAPI_E_SUCCESS; } /** \details Read Recipients from a message \param obj_message the message we want to read recipients from \param RowId the row index we start reading recipients from \param RowCount pointer on the number of recipients \param RecipientRows pointer on the recipients array \return MAPI_E_SUCCESS on success, otherwise MAPI error. \note Developers may also call GetLastError() to retrieve the last MAPI error code. Possible MAPI error codes are: - MAPI_E_NOT_INITIALIZED: MAPI subsystem has not been initialized - MAPI_E_CALL_FAILED: A network problem was encountered during the transaction \sa ModifyRecipients, RemoveAllRecipients, GetRecipientTable, OpenMessage */ _PUBLIC_ enum MAPISTATUS ReadRecipients(mapi_object_t *obj_message, uint32_t RowId, uint8_t *RowCount, struct ReadRecipientRow **RecipientRows) { struct mapi_request *mapi_request; struct mapi_response *mapi_response; struct EcDoRpc_MAPI_REQ *mapi_req; struct ReadRecipients_req request; struct ReadRecipients_repl *reply; struct mapi_session *session; NTSTATUS status; enum MAPISTATUS retval; uint32_t size = 0; TALLOC_CTX *mem_ctx; uint8_t logon_id; /* Sanity checks */ OPENCHANGE_RETVAL_IF(!obj_message, MAPI_E_INVALID_PARAMETER, NULL); session = mapi_object_get_session(obj_message); OPENCHANGE_RETVAL_IF(!session, MAPI_E_INVALID_PARAMETER, NULL); if ((retval = mapi_object_get_logon_id(obj_message, &logon_id)) != MAPI_E_SUCCESS) return retval; mem_ctx = talloc_named(session, 0, "ReadRecipients"); size = 0; /* Fill the ReadRecipients operation */ request.RowId = RowId; size += sizeof (uint32_t); request.ulReserved = 0; size += sizeof (uint16_t); /* Fill the MAPI_REQ request */ mapi_req = talloc_zero(mem_ctx, struct EcDoRpc_MAPI_REQ); mapi_req->opnum = op_MAPI_ReadRecipients; mapi_req->logon_id = logon_id; mapi_req->handle_idx = 0; mapi_req->u.mapi_ReadRecipients = request; size += 5; /* Fill the mapi_request structure */ mapi_request = talloc_zero(mem_ctx, struct mapi_request); mapi_request->mapi_len = size + sizeof (uint32_t); mapi_request->length = size; mapi_request->mapi_req = mapi_req; mapi_request->handles = talloc_array(mem_ctx, uint32_t, 1); mapi_request->handles[0] = mapi_object_get_handle(obj_message); status = emsmdb_transaction_wrapper(session, mem_ctx, mapi_request, &mapi_response); OPENCHANGE_RETVAL_IF(!NT_STATUS_IS_OK(status), MAPI_E_CALL_FAILED, mem_ctx); OPENCHANGE_RETVAL_IF(!mapi_response->mapi_repl, MAPI_E_CALL_FAILED, mem_ctx); retval = mapi_response->mapi_repl->error_code; OPENCHANGE_RETVAL_IF(retval, retval, mem_ctx); OPENCHANGE_CHECK_NOTIFICATION(session, mapi_response); /* Retrieve the recipients */ reply = &mapi_response->mapi_repl->u.mapi_ReadRecipients; *RowCount = reply->RowCount; *RecipientRows = talloc_steal((TALLOC_CTX *)session, reply->RecipientRows); talloc_free(mapi_response); talloc_free(mem_ctx); return MAPI_E_SUCCESS; } /** \details Deletes all recipients from a message \param obj_message the message we want to remove all recipients from \return MAPI_E_SUCCESS on success, otherwise MAPI error. \note Developers may also call GetLastError() to retrieve the last MAPI error code. Possible MAPI error codes are: - MAPI_E_NOT_INITIALIZED: MAPI subsystem has not been initialized - MAPI_E_CALL_FAILED: A network problem was encountered during the transaction \sa ModifyRecipients, ReadRecipients */ _PUBLIC_ enum MAPISTATUS RemoveAllRecipients(mapi_object_t *obj_message) { struct mapi_request *mapi_request; struct mapi_response *mapi_response; struct EcDoRpc_MAPI_REQ *mapi_req; struct RemoveAllRecipients_req request; struct mapi_session *session; NTSTATUS status; enum MAPISTATUS retval; uint32_t size = 0; TALLOC_CTX *mem_ctx; uint8_t logon_id; /* Sanity checks */ OPENCHANGE_RETVAL_IF(!obj_message, MAPI_E_INVALID_PARAMETER, NULL); session = mapi_object_get_session(obj_message); OPENCHANGE_RETVAL_IF(!session, MAPI_E_INVALID_PARAMETER, NULL); if ((retval = mapi_object_get_logon_id(obj_message, &logon_id)) != MAPI_E_SUCCESS) return retval; mem_ctx = talloc_named(session, 0, "RemoveAllRecipients"); size = 0; /* Fill the RemoveAllRecipients operation */ request.ulReserved = 0; size += sizeof (uint32_t); /* Fill the MAPI_REQ request */ mapi_req = talloc_zero(mem_ctx, struct EcDoRpc_MAPI_REQ); mapi_req->opnum = op_MAPI_RemoveAllRecipients; mapi_req->logon_id = logon_id; mapi_req->handle_idx = 0; mapi_req->u.mapi_RemoveAllRecipients = request; size += 5; /* Fill the mapi_request structure */ mapi_request = talloc_zero(mem_ctx, struct mapi_request); mapi_request->mapi_len = size + sizeof (uint32_t); mapi_request->length = size; mapi_request->mapi_req = mapi_req; mapi_request->handles = talloc_array(mem_ctx, uint32_t, 1); mapi_request->handles[0] = mapi_object_get_handle(obj_message); status = emsmdb_transaction_wrapper(session, mem_ctx, mapi_request, &mapi_response); OPENCHANGE_RETVAL_IF(!NT_STATUS_IS_OK(status), MAPI_E_CALL_FAILED, mem_ctx); OPENCHANGE_RETVAL_IF(!mapi_response->mapi_repl, MAPI_E_CALL_FAILED, mem_ctx); retval = mapi_response->mapi_repl->error_code; OPENCHANGE_RETVAL_IF(retval, retval, mem_ctx); OPENCHANGE_CHECK_NOTIFICATION(session, mapi_response); talloc_free(mapi_response); talloc_free(mem_ctx); return MAPI_E_SUCCESS; } /** \details Saves all changes to the message and marks it as ready for sending. This function saves all changes made to a message and marks it ready to be sent. \param obj_message the message to mark complete \return MAPI_E_SUCCESS on success, otherwise MAPI error. \note Developers may also call GetLastError() to retrieve the last MAPI error code. Possible MAPI error codes are: - MAPI_E_NOT_INITIALIZED: MAPI subsystem has not been initialized - MAPI_E_CALL_FAILED: A network problem was encountered during the transaction \sa CreateMessage, SetProps, ModifyRecipients, SetRecipientType, GetLastError */ _PUBLIC_ enum MAPISTATUS SubmitMessage(mapi_object_t *obj_message) { struct mapi_request *mapi_request; struct mapi_response *mapi_response; struct EcDoRpc_MAPI_REQ *mapi_req; struct SubmitMessage_req request; struct mapi_session *session; NTSTATUS status; enum MAPISTATUS retval; uint32_t size = 0; TALLOC_CTX *mem_ctx; uint8_t logon_id; /* Sanity checks */ OPENCHANGE_RETVAL_IF(!obj_message, MAPI_E_INVALID_PARAMETER, NULL); session = mapi_object_get_session(obj_message); OPENCHANGE_RETVAL_IF(!session, MAPI_E_INVALID_PARAMETER, NULL); if ((retval = mapi_object_get_logon_id(obj_message, &logon_id)) != MAPI_E_SUCCESS) return retval; mem_ctx = talloc_named(session, 0, "SubmitMessage"); size = 0; /* Fill the SubmitMessage operation */ request.SubmitFlags = None; size += sizeof(uint8_t); /* Fill the MAPI_REQ request */ mapi_req = talloc_zero(mem_ctx, struct EcDoRpc_MAPI_REQ); mapi_req->opnum = op_MAPI_SubmitMessage; mapi_req->logon_id = logon_id; mapi_req->handle_idx = 0; mapi_req->u.mapi_SubmitMessage = request; size += 5; /* Fill the mapi_request structure */ mapi_request = talloc_zero(mem_ctx, struct mapi_request); mapi_request->mapi_len = size + sizeof (uint32_t); mapi_request->length = size; mapi_request->mapi_req = mapi_req; mapi_request->handles = talloc_array(mem_ctx, uint32_t, 1); mapi_request->handles[0] = mapi_object_get_handle(obj_message); status = emsmdb_transaction_wrapper(session, mem_ctx, mapi_request, &mapi_response); OPENCHANGE_RETVAL_IF(!NT_STATUS_IS_OK(status), MAPI_E_CALL_FAILED, mem_ctx); OPENCHANGE_RETVAL_IF(!mapi_response->mapi_repl, MAPI_E_CALL_FAILED, mem_ctx); retval = mapi_response->mapi_repl->error_code; OPENCHANGE_RETVAL_IF(retval, retval, mem_ctx); OPENCHANGE_CHECK_NOTIFICATION(session, mapi_response); talloc_free(mapi_response); talloc_free(mem_ctx); return MAPI_E_SUCCESS; } /** \details Aborts a previous message submission. \param obj_store the store object \param obj_folder the folder object where the message has been submitted \param obj_message the submitted message object \return MAPI_E_SUCCESS on success, otherwise MAPI error. \note Developers may also call GetLastError() to retrieve the last MAPI error code. Possible MAPI error codes are: - MAPI_E_NOT_INITIALIZED: MAPI subsystem has not been initialized - MAPI_E_CALL_FAILED: A network problem was encountered during the transaction - MAPI_E_UNABLE_TO_ABORT: The operation can not be aborted - MAPI_E_NOT_IN_QUEUE: The message is no longer in the message store's spooler queue - MAPI_E_NO_SUPPORT: the server object associated with the input handle index in the server object table is not of type Logon or the current logon session is a public logon. \sa SubmitMessage */ _PUBLIC_ enum MAPISTATUS AbortSubmit(mapi_object_t *obj_store, mapi_object_t *obj_folder, mapi_object_t *obj_message) { struct mapi_request *mapi_request; struct mapi_response *mapi_response; struct EcDoRpc_MAPI_REQ *mapi_req; struct AbortSubmit_req request; struct mapi_session *session[2]; NTSTATUS status; enum MAPISTATUS retval; uint32_t size = 0; TALLOC_CTX *mem_ctx; uint8_t logon_id; /* Sanity checks */ OPENCHANGE_RETVAL_IF(!obj_folder, MAPI_E_INVALID_PARAMETER, NULL); OPENCHANGE_RETVAL_IF(!obj_message, MAPI_E_INVALID_PARAMETER, NULL); session[0] = mapi_object_get_session(obj_store); session[1] = mapi_object_get_session(obj_message); OPENCHANGE_RETVAL_IF(!session[0], MAPI_E_INVALID_PARAMETER, NULL); OPENCHANGE_RETVAL_IF(!session[1], MAPI_E_INVALID_PARAMETER, NULL); OPENCHANGE_RETVAL_IF(session[0] != session[1], MAPI_E_INVALID_PARAMETER, NULL); if ((retval = mapi_object_get_logon_id(obj_store, &logon_id)) != MAPI_E_SUCCESS) return retval; mem_ctx = talloc_named(session[0], 0, "AbortSubmit"); size = 0; /* Fill the AbortSubmit operation */ request.FolderId = mapi_object_get_id(obj_folder); size += sizeof (uint64_t); request.MessageId = mapi_object_get_id(obj_message); size += sizeof (uint64_t); /* Fill the MAPI_REQ request */ mapi_req = talloc_zero(mem_ctx, struct EcDoRpc_MAPI_REQ); mapi_req->opnum = op_MAPI_AbortSubmit; mapi_req->logon_id = logon_id; mapi_req->handle_idx = 0; mapi_req->u.mapi_AbortSubmit = request; size += 5; /* Fill the mapi_request structure */ mapi_request = talloc_zero(mem_ctx, struct mapi_request); mapi_request->mapi_len = size + sizeof (uint32_t); mapi_request->length = size; mapi_request->mapi_req = mapi_req; mapi_request->handles = talloc_array(mem_ctx, uint32_t, 1); mapi_request->handles[0] = mapi_object_get_handle(obj_store); status = emsmdb_transaction_wrapper(session[0], mem_ctx, mapi_request, &mapi_response); OPENCHANGE_RETVAL_IF(!NT_STATUS_IS_OK(status), MAPI_E_CALL_FAILED, mem_ctx); OPENCHANGE_RETVAL_IF(!mapi_response->mapi_repl, MAPI_E_CALL_FAILED, mem_ctx); retval = mapi_response->mapi_repl->error_code; OPENCHANGE_RETVAL_IF(retval, retval, mem_ctx); OPENCHANGE_CHECK_NOTIFICATION(session[0], mapi_response); talloc_free(mapi_response); talloc_free(mem_ctx); return MAPI_E_SUCCESS; } /** \details Saves all changes to the message \param parent the parent object for the message \param obj_message the message to save \param SaveFlags specify how the save operation behaves Possible value for SaveFlags: -# KeepReadOnly Keep the Message object open with read-only access -# KeepOpenReadWrite Keep the Message object open with read-write access -# ForceSave Commit the changes and keep the message object open with read-write access \return MAPI_E_SUCCESS on success, otherwise MAPI error. \note Developers may also call GetLastError() to retrieve the last MAPI error code. Possible MAPI error codes are: - MAPI_E_NOT_INITIALIZED: MAPI subsystem has not been initialized - MAPI_E_CALL_FAILED: A network problem was encountered during the transaction \sa SetProps, ModifyRecipients, GetLastError */ _PUBLIC_ enum MAPISTATUS SaveChangesMessage(mapi_object_t *parent, mapi_object_t *obj_message, uint8_t SaveFlags) { struct mapi_request *mapi_request; struct mapi_response *mapi_response; struct EcDoRpc_MAPI_REQ *mapi_req; struct SaveChangesMessage_req request; struct mapi_session *session[2]; NTSTATUS status; enum MAPISTATUS retval; uint32_t size = 0; TALLOC_CTX *mem_ctx; uint8_t logon_id; /* Sanity checks */ OPENCHANGE_RETVAL_IF(!parent, MAPI_E_INVALID_PARAMETER, NULL); OPENCHANGE_RETVAL_IF(!obj_message, MAPI_E_INVALID_PARAMETER, NULL); OPENCHANGE_RETVAL_IF((SaveFlags != 0x9) && (SaveFlags != 0xA) && (SaveFlags != 0xC), MAPI_E_INVALID_PARAMETER, NULL); session[0] = mapi_object_get_session(parent); session[1] = mapi_object_get_session(obj_message); OPENCHANGE_RETVAL_IF(!session[0], MAPI_E_INVALID_PARAMETER, NULL); OPENCHANGE_RETVAL_IF(!session[1], MAPI_E_INVALID_PARAMETER, NULL); if ((retval = mapi_object_get_logon_id(parent, &logon_id)) != MAPI_E_SUCCESS) return retval; mem_ctx = talloc_named(session[0], 0, "SaveChangesMessage"); size = 0; /* Fill the SaveChangesMessage operation */ request.handle_idx = 0x1; size += sizeof (uint8_t); request.SaveFlags = SaveFlags; size += sizeof(uint8_t); /* Fill the MAPI_REQ request */ mapi_req = talloc_zero(mem_ctx, struct EcDoRpc_MAPI_REQ); mapi_req->opnum = op_MAPI_SaveChangesMessage; mapi_req->logon_id = logon_id; mapi_req->handle_idx = 0; mapi_req->u.mapi_SaveChangesMessage = request; size += 5; /* Fill the mapi_request structure */ mapi_request = talloc_zero(mem_ctx, struct mapi_request); mapi_request->mapi_len = size + (2 * sizeof (uint32_t)); mapi_request->length = size; mapi_request->mapi_req = mapi_req; mapi_request->handles = talloc_array(mem_ctx, uint32_t, 2); mapi_request->handles[0] = mapi_object_get_handle(parent); mapi_request->handles[1] = mapi_object_get_handle(obj_message); status = emsmdb_transaction_wrapper(session[0], mem_ctx, mapi_request, &mapi_response); OPENCHANGE_RETVAL_IF(!NT_STATUS_IS_OK(status), MAPI_E_CALL_FAILED, mem_ctx); OPENCHANGE_RETVAL_IF(!mapi_response->mapi_repl, MAPI_E_CALL_FAILED, mem_ctx); retval = mapi_response->mapi_repl->error_code; OPENCHANGE_RETVAL_IF(retval, retval, mem_ctx); OPENCHANGE_CHECK_NOTIFICATION(session[0], mapi_response); /* store the message_id */ mapi_object_set_id(obj_message, mapi_response->mapi_repl->u.mapi_SaveChangesMessage.MessageId); talloc_free(mapi_response); talloc_free(mem_ctx); return MAPI_E_SUCCESS; } /** \details Sends the specified Message object out for message delivery. */ _PUBLIC_ enum MAPISTATUS TransportSend(mapi_object_t *obj_message, struct mapi_SPropValue_array *lpProps) { struct mapi_request *mapi_request; struct mapi_response *mapi_response; struct EcDoRpc_MAPI_REQ *mapi_req; struct TransportSend_repl *reply; struct mapi_session *session; NTSTATUS status; enum MAPISTATUS retval; uint32_t size = 0; TALLOC_CTX *mem_ctx; uint8_t logon_id; /* Sanity checks */ OPENCHANGE_RETVAL_IF(!obj_message, MAPI_E_INVALID_PARAMETER, NULL); OPENCHANGE_RETVAL_IF(!lpProps, MAPI_E_INVALID_PARAMETER, NULL); session = mapi_object_get_session(obj_message); OPENCHANGE_RETVAL_IF(!session, MAPI_E_INVALID_PARAMETER, NULL); if ((retval = mapi_object_get_logon_id(obj_message, &logon_id)) != MAPI_E_SUCCESS) return retval; mem_ctx = talloc_named(session, 0, "TransportSend"); size = 0; /* Fill the MAPI_REQ request */ mapi_req = talloc_zero(mem_ctx, struct EcDoRpc_MAPI_REQ); mapi_req->opnum = op_MAPI_TransportSend; mapi_req->logon_id = logon_id; mapi_req->handle_idx = 0; size += 5; /* Fill the mapi_request structure */ mapi_request = talloc_zero(mem_ctx, struct mapi_request); mapi_request->mapi_len = size + sizeof (uint32_t); mapi_request->length = size; mapi_request->mapi_req = mapi_req; mapi_request->handles = talloc_array(mem_ctx, uint32_t, 1); mapi_request->handles[0] = mapi_object_get_handle(obj_message); status = emsmdb_transaction_wrapper(session, mem_ctx, mapi_request, &mapi_response); OPENCHANGE_RETVAL_IF(!NT_STATUS_IS_OK(status), MAPI_E_CALL_FAILED, mem_ctx); OPENCHANGE_RETVAL_IF(!mapi_response->mapi_repl, MAPI_E_CALL_FAILED, mem_ctx); retval = mapi_response->mapi_repl->error_code; OPENCHANGE_RETVAL_IF(retval, retval, mem_ctx); OPENCHANGE_CHECK_NOTIFICATION(session, mapi_response); /* Retrieve reply parameters */ reply = &mapi_response->mapi_repl->u.mapi_TransportSend; if (!reply->NoPropertiesReturned) { lpProps->cValues = reply->properties.lpProps.cValues; lpProps->lpProps = talloc_steal((TALLOC_CTX *)session, reply->properties.lpProps.lpProps); } else { lpProps->cValues = 0; lpProps->lpProps = NULL; } talloc_free(mapi_response); talloc_free(mem_ctx); return MAPI_E_SUCCESS; } /** \details Returns the message recipient table \param obj_message the message to receive recipients from \param SRowSet pointer to the recipient table \param SPropTagArray pointer to the array of properties listed in the recipient table \return MAPI_E_SUCCESS on success, otherwise MAPI error. \note Developers may also call GetLastError() to retrieve the last MAPI error code. Possible MAPI error codes are: - MAPI_E_NOT_INITIALIZED: MAPI subsystem has not been initialized \sa OpenMessage */ _PUBLIC_ enum MAPISTATUS GetRecipientTable(mapi_object_t *obj_message, struct SRowSet *SRowSet, struct SPropTagArray *SPropTagArray) { mapi_object_message_t *message; message = (mapi_object_message_t *)obj_message->private_data; OPENCHANGE_RETVAL_IF(!obj_message, MAPI_E_NOT_INITIALIZED, NULL); OPENCHANGE_RETVAL_IF(!message, MAPI_E_NOT_INITIALIZED, NULL); *SRowSet = message->SRowSet; *SPropTagArray = message->SPropTagArray; return MAPI_E_SUCCESS; } /** \details Clear or set the MSGFLAG_READ flag for a given message This function clears or sets the MSGFLAG_READ flag in the PR_MESSAGE_FLAGS property of a given message. \param obj_folder the folder to operate in \param obj_child the message to set flags on \param flags the new flags (MSGFLAG_READ) value \return MAPI_E_SUCCESS on success, otherwise MAPI error. \note Developers may also call GetLastError() to retrieve the last MAPI error code. Possible MAPI error codes are: - MAPI_E_NOT_INITIALIZED: MAPI subsystem has not been initialized - MAPI_E_CALL_FAILED: A network problem was encountered during the transaction \sa OpenMessage, GetLastError */ _PUBLIC_ enum MAPISTATUS SetMessageReadFlag(mapi_object_t *obj_folder, mapi_object_t *obj_child, uint8_t flags) { struct mapi_request *mapi_request; struct mapi_response *mapi_response; struct EcDoRpc_MAPI_REQ *mapi_req; struct SetMessageReadFlag_req request; struct mapi_session *session[2]; NTSTATUS status; enum MAPISTATUS retval; uint32_t size; TALLOC_CTX *mem_ctx; uint8_t logon_id; /* Sanity checks */ OPENCHANGE_RETVAL_IF(!obj_folder, MAPI_E_INVALID_PARAMETER, NULL); OPENCHANGE_RETVAL_IF(!obj_child, MAPI_E_INVALID_PARAMETER, NULL); session[0] = mapi_object_get_session(obj_folder); session[1] = mapi_object_get_session(obj_child); OPENCHANGE_RETVAL_IF(!session[0], MAPI_E_INVALID_PARAMETER, NULL); OPENCHANGE_RETVAL_IF(!session[1], MAPI_E_INVALID_PARAMETER, NULL); if ((retval = mapi_object_get_logon_id(obj_folder, &logon_id)) != MAPI_E_SUCCESS) return retval; mem_ctx = talloc_named(session[0], 0, "SetMessageReadFlags"); size = 0; /* Fill the SetMessageReadFlags operation */ request.handle_idx = 0x1; size += sizeof(uint8_t); request.flags = flags; size += sizeof(uint8_t); /* TEMP HACK, see exchange.idl: request.clientdata.length = 0; request.clientdata.data = NULL; */ /* Fill the MAPI_REQ request */ mapi_req = talloc_zero(mem_ctx, struct EcDoRpc_MAPI_REQ); mapi_req->opnum = op_MAPI_SetMessageReadFlag; mapi_req->logon_id = logon_id; mapi_req->handle_idx = 0; mapi_req->u.mapi_SetMessageReadFlag = request; size += 5; /* Fill the mapi_request structure */ mapi_request = talloc_zero(mem_ctx, struct mapi_request); mapi_request->mapi_len = size + sizeof (uint32_t) * 2; mapi_request->length = size; mapi_request->mapi_req = mapi_req; mapi_request->handles = talloc_array(mem_ctx, uint32_t, 2); mapi_request->handles[0] = mapi_object_get_handle(obj_folder); mapi_request->handles[1] = mapi_object_get_handle(obj_child); status = emsmdb_transaction_wrapper(session[0], mem_ctx, mapi_request, &mapi_response); OPENCHANGE_RETVAL_IF(!NT_STATUS_IS_OK(status), MAPI_E_CALL_FAILED, mem_ctx); OPENCHANGE_RETVAL_IF(!mapi_response->mapi_repl, MAPI_E_CALL_FAILED, mem_ctx); retval = mapi_response->mapi_repl->error_code; OPENCHANGE_RETVAL_IF(retval, retval, mem_ctx); OPENCHANGE_CHECK_NOTIFICATION(session[0], mapi_response); talloc_free(mapi_response); talloc_free(mem_ctx); return MAPI_E_SUCCESS; } /** \details Opens an embedded message object and retrieves a MAPI object that can be used to get or set properties on the embedded message. This function essentially takes an attachment and gives you back a message. \param obj_attach the attachment object \param obj_embeddedmsg the embedded message \param ulFlags access rights on the embedded message Possible ulFlags values: - 0x0: read only access - 0x1: Read / Write access - 0x2: Create \code ... assume we have a message - obj_message ... // Initialise the attachment object mapi_object_init(&obj_attach); // Create an attachment to the message retval = CreateAttach(&obj_message, &obj_attach); ... check the return value ... // use SetProps() to set the attachment up, noting the special PR_ATTACHM_METHOD property attach[0].ulPropTag = PR_ATTACH_METHOD; attach[0].value.l = ATTACH_EMBEDDED_MSG; attach[1].ulPropTag = PR_RENDERING_POSITION; attach[1].value.l = 0; retval = SetProps(&obj_attach, 0, attach, 2); ... check the return value ... // Initialise the embedded message object mapi_object_init(&obj_embeddedmsg); retval = OpenEmbeddedMessage(&obj_attach, &obj_embeddedmsg, MAPI_CREATE); ... check the return value ... // Fill in the embedded message properties, just like any other message (e.g. resulting from CreateMessage()) // Save the changes to the embedded message retval = SaveChangesMessage(&obj_message, &obj_embeddedmsg, KeepOpenReadOnly); ... check the return value ... // Save the changes to the attachment retval = SaveChangesAttachment(&obj_message, &obj_attach, KeepOpenReadOnly); ... check the return value ... // Save the changes to the original message retval = SaveChangesMessage(&obj_folder, &obj_message, KeepOpenReadOnly); ... check the return value ... \endcode \return MAPI_E_SUCCESS on success, otherwise MAPI error. Possible MAPI error codes are: - MAPI_E_NOT_INITIALIZED: MAPI subsystem has not been initialized - MAPI_E_INVALID_PARAMETER: obj_store is undefined - MAPI_E_CALL_FAILED: A network problem was encountered during the transaction \note Developers may also call GetLastError() to retrieve the last MAPI error code. \sa CreateAttach, OpenMessage, GetLastError */ _PUBLIC_ enum MAPISTATUS OpenEmbeddedMessage(mapi_object_t *obj_attach, mapi_object_t *obj_embeddedmsg, enum OpenEmbeddedMessage_OpenModeFlags ulFlags) { struct mapi_context *mapi_ctx; struct mapi_request *mapi_request; struct mapi_response *mapi_response; struct EcDoRpc_MAPI_REQ *mapi_req; struct OpenEmbeddedMessage_req request; struct OpenEmbeddedMessage_repl *reply; struct mapi_session *session; mapi_object_message_t *message; struct SPropValue lpProp; NTSTATUS status; enum MAPISTATUS retval; uint32_t size = 0; TALLOC_CTX *mem_ctx; uint32_t i = 0; uint8_t logon_id; /* Sanity checks */ OPENCHANGE_RETVAL_IF(!obj_attach, MAPI_E_INVALID_PARAMETER, NULL); session = mapi_object_get_session(obj_attach); OPENCHANGE_RETVAL_IF(!session, MAPI_E_INVALID_PARAMETER, NULL); OPENCHANGE_RETVAL_IF(!obj_embeddedmsg, MAPI_E_INVALID_PARAMETER, NULL); mapi_ctx = session->mapi_ctx; OPENCHANGE_RETVAL_IF(!mapi_ctx, MAPI_E_NOT_INITIALIZED, NULL); if ((retval = mapi_object_get_logon_id(obj_attach, &logon_id)) != MAPI_E_SUCCESS) return retval; mem_ctx = talloc_named(session, 0, "OpenEmbeddedMessage"); /* Fill the OpenEmbeddedMessage request */ request.handle_idx = 0x1; size += sizeof(uint8_t); request.CodePageId = 0xfff; size += sizeof(uint16_t); request.OpenModeFlags = ulFlags; size += sizeof(uint8_t); /* Fill the MAPI_REQ request */ mapi_req = talloc_zero(mem_ctx, struct EcDoRpc_MAPI_REQ); mapi_req->opnum = op_MAPI_OpenEmbeddedMessage; mapi_req->logon_id = logon_id; mapi_req->handle_idx = 0; mapi_req->u.mapi_OpenEmbeddedMessage = request; size += 5; /* Fill the mapi_request structure */ mapi_request = talloc_zero(mem_ctx, struct mapi_request); mapi_request->mapi_len = size + sizeof (uint32_t) * 2; mapi_request->length = size; mapi_request->mapi_req = mapi_req; mapi_request->handles = talloc_array(mem_ctx, uint32_t, 2); mapi_request->handles[0] = mapi_object_get_handle(obj_attach); mapi_request->handles[1] = mapi_object_get_handle(obj_embeddedmsg); status = emsmdb_transaction_wrapper(session, mem_ctx, mapi_request, &mapi_response); OPENCHANGE_RETVAL_IF(!NT_STATUS_IS_OK(status), MAPI_E_CALL_FAILED, mem_ctx); OPENCHANGE_RETVAL_IF(!mapi_response->mapi_repl, MAPI_E_CALL_FAILED, mem_ctx); retval = mapi_response->mapi_repl->error_code; OPENCHANGE_RETVAL_IF(retval, retval, mem_ctx); OPENCHANGE_CHECK_NOTIFICATION(session, mapi_response); /* Set object session and handle */ mapi_object_set_session(obj_embeddedmsg, session); mapi_object_set_handle(obj_embeddedmsg, mapi_response->handles[1]); mapi_object_set_logon_id(obj_embeddedmsg, logon_id); /* Store OpenEmbeddedMessage reply data */ reply = &mapi_response->mapi_repl->u.mapi_OpenEmbeddedMessage; message = talloc_zero((TALLOC_CTX *)session, mapi_object_message_t); message->cValues = reply->RecipientCount; message->SRowSet.cRows = reply->RowCount; message->SRowSet.aRow = talloc_array((TALLOC_CTX *)message, struct SRow, reply->RowCount + 1); message->SPropTagArray.cValues = reply->RecipientColumns.cValues; message->SPropTagArray.aulPropTag = talloc_steal(message, reply->RecipientColumns.aulPropTag); for (i = 0; i < reply->RowCount; i++) { emsmdb_get_SRow((TALLOC_CTX *)message, &(message->SRowSet.aRow[i]), &message->SPropTagArray, reply->RecipientRows[i].RecipientRow.prop_count, &reply->RecipientRows[i].RecipientRow.prop_values, reply->RecipientRows[i].RecipientRow.layout, 1); lpProp.ulPropTag = PR_RECIPIENT_TYPE; lpProp.value.l = reply->RecipientRows[i].RecipientType; SRow_addprop(&(message->SRowSet.aRow[i]), lpProp); lpProp.ulPropTag = PR_INTERNET_CPID; lpProp.value.l = reply->RecipientRows[i].CodePageId; SRow_addprop(&(message->SRowSet.aRow[i]), lpProp); } /* add SPropTagArray elements we automatically append to SRow */ SPropTagArray_add((TALLOC_CTX *)message, &message->SPropTagArray, PR_RECIPIENT_TYPE); SPropTagArray_add((TALLOC_CTX *)message, &message->SPropTagArray, PR_INTERNET_CPID); obj_embeddedmsg->private_data = (void *) message; talloc_free(mapi_response); talloc_free(mem_ctx); return MAPI_E_SUCCESS; } openchange-2.0/libmapi/IMsgStore.c000066400000000000000000001015271223057412600171270ustar00rootroot00000000000000/* OpenChange MAPI implementation. Copyright (C) Julien Kerihuel 2007-2008. This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see . */ #include "libmapi/libmapi.h" #include "libmapi/libmapi_private.h" /** \file IMsgStore.c \brief Folders related operations */ /** \details Open a folder from the store \param obj_store the store to open a folder in (i.e. the parent) \param id_folder the folder identifier \param obj_folder the resulting open folder \return MAPI_E_SUCCESS on success, otherwise MAPI error. \note Developers may also call GetLastError() to retrieve the last MAPI error code. Possible MAPI error codes are: - MAPI_E_NOT_INITIALIZED: MAPI subsystem has not been initialized - MAPI_E_CALL_FAILED: A network problem was encountered during the transaction \sa MAPIInitialize, OpenMsgStore, GetLastError */ _PUBLIC_ enum MAPISTATUS OpenFolder(mapi_object_t *obj_store, mapi_id_t id_folder, mapi_object_t *obj_folder) { struct mapi_request *mapi_request; struct mapi_response *mapi_response; struct EcDoRpc_MAPI_REQ *mapi_req; struct OpenFolder_req request; struct mapi_session *session; NTSTATUS status; enum MAPISTATUS retval; uint32_t size = 0; TALLOC_CTX *mem_ctx; uint8_t logon_id; /* Sanity checks */ OPENCHANGE_RETVAL_IF(!obj_store, MAPI_E_INVALID_PARAMETER, NULL); session = mapi_object_get_session(obj_store); OPENCHANGE_RETVAL_IF(!session, MAPI_E_INVALID_PARAMETER, NULL); if ((retval = mapi_object_get_logon_id(obj_store, &logon_id)) != MAPI_E_SUCCESS) return retval; mem_ctx = talloc_named(session, 0, "OpenFolder"); /* Fill the OpenFolder operation */ request.handle_idx = 0x1; request.folder_id = id_folder; request.OpenModeFlags = OpenModeFlags_Folder; size += sizeof (uint8_t) + sizeof(uint64_t) + sizeof(uint8_t); /* Fill the MAPI_REQ request */ mapi_req = talloc_zero(mem_ctx, struct EcDoRpc_MAPI_REQ); mapi_req->opnum = op_MAPI_OpenFolder; mapi_req->logon_id = logon_id; mapi_req->handle_idx = 0; mapi_req->u.mapi_OpenFolder = request; size += 5; /* Fill the mapi_request structure */ mapi_request = talloc_zero(mem_ctx, struct mapi_request); mapi_request->mapi_len = size + sizeof (uint32_t) * 2; mapi_request->length = size; mapi_request->mapi_req = mapi_req; mapi_request->handles = talloc_array(mem_ctx, uint32_t, 2); mapi_request->handles[0] = mapi_object_get_handle(obj_store); mapi_request->handles[1] = 0xffffffff; status = emsmdb_transaction_wrapper(session, mem_ctx, mapi_request, &mapi_response); OPENCHANGE_RETVAL_IF(!NT_STATUS_IS_OK(status), MAPI_E_CALL_FAILED, mem_ctx); OPENCHANGE_RETVAL_IF(!mapi_response->mapi_repl, MAPI_E_CALL_FAILED, mem_ctx); retval = mapi_response->mapi_repl->error_code; OPENCHANGE_RETVAL_IF(retval, retval, mem_ctx); OPENCHANGE_CHECK_NOTIFICATION(session, mapi_response); /* Set object session, id and handle */ mapi_object_set_session(obj_folder, session); mapi_object_set_id(obj_folder, id_folder); mapi_object_set_handle(obj_folder, mapi_response->handles[1]); mapi_object_set_logon_id(obj_folder, logon_id); talloc_free(mapi_response); talloc_free(mem_ctx); return MAPI_E_SUCCESS; } /** \details Determine if a public folder is ghosted. This function returns whether a public folder is ghosted or not. \param obj_store the store of the public folder \param obj_folder the folder we are querying for ghost \param IsGhosted pointer on the boolean value returned \return MAPI_E_SUCCESS on success, otherwise MAPI error. \note Developers may also call GetLastError() to retrieve the last MAPI error code. Possible MAPI error codes are: - MAPI_E_NOT_INITIALIZED: MAPI subsystem has not been initialized - MAPI_E_CALL_FAILED: A network problem was encountered during the transaction */ _PUBLIC_ enum MAPISTATUS PublicFolderIsGhosted(mapi_object_t *obj_store, mapi_object_t *obj_folder, bool *IsGhosted) { struct mapi_request *mapi_request; struct mapi_response *mapi_response; struct EcDoRpc_MAPI_REQ *mapi_req; struct PublicFolderIsGhosted_req request; struct mapi_session *session[2]; NTSTATUS status; enum MAPISTATUS retval; uint32_t size = 0; TALLOC_CTX *mem_ctx; mapi_id_t folderId; uint8_t logon_id; /* Sanity checks */ OPENCHANGE_RETVAL_IF(!obj_store, MAPI_E_INVALID_PARAMETER, NULL); OPENCHANGE_RETVAL_IF(!obj_folder, MAPI_E_INVALID_PARAMETER, NULL); session[0] = mapi_object_get_session(obj_store); session[1] = mapi_object_get_session(obj_folder); OPENCHANGE_RETVAL_IF(!session[0], MAPI_E_INVALID_PARAMETER, NULL); OPENCHANGE_RETVAL_IF(!session[1], MAPI_E_INVALID_PARAMETER, NULL); OPENCHANGE_RETVAL_IF(session[0] != session[1], MAPI_E_INVALID_PARAMETER, NULL); if ((retval = mapi_object_get_logon_id(obj_store, &logon_id)) != MAPI_E_SUCCESS) return retval; folderId = mapi_object_get_id(obj_folder); OPENCHANGE_RETVAL_IF(!folderId, MAPI_E_INVALID_PARAMETER, NULL); mem_ctx = talloc_named(session[0], 0, "PublicFolderIsGhosted"); size = 0; /* Fill the PublicFolderIsGhosted operation */ request.FolderId = folderId; size += sizeof (uint64_t); /* Fill the MAPI_REQ request */ mapi_req = talloc_zero(mem_ctx, struct EcDoRpc_MAPI_REQ); mapi_req->opnum = op_MAPI_PublicFolderIsGhosted; mapi_req->logon_id = logon_id; mapi_req->handle_idx = 0; mapi_req->u.mapi_PublicFolderIsGhosted = request; size += 5; /* Fill the mapi_request structure */ mapi_request = talloc_zero(mem_ctx, struct mapi_request); mapi_request->mapi_len = size + sizeof (uint32_t); mapi_request->length = size; mapi_request->mapi_req = mapi_req; mapi_request->handles = talloc_array(mem_ctx, uint32_t, 1); mapi_request->handles[0] = mapi_object_get_handle(obj_store); status = emsmdb_transaction_wrapper(session[0], mem_ctx, mapi_request, &mapi_response); OPENCHANGE_RETVAL_IF(!NT_STATUS_IS_OK(status), MAPI_E_CALL_FAILED, mem_ctx); OPENCHANGE_RETVAL_IF(!mapi_response->mapi_repl, MAPI_E_CALL_FAILED, mem_ctx); retval = mapi_response->mapi_repl->error_code; OPENCHANGE_RETVAL_IF(retval, retval, mem_ctx); OPENCHANGE_CHECK_NOTIFICATION(session[0], mapi_response); *IsGhosted = mapi_response->mapi_repl->u.mapi_PublicFolderIsGhosted.IsGhosted; talloc_free(mapi_response); talloc_free(mem_ctx); return MAPI_E_SUCCESS; } /** \details Open a NNTP Public Folder given its name \param obj_folder the parent folder \param obj_child the resulting open folder \param name the folder name \return MAPI_E_SUCCESS on success, otherwise MAPI error. \note Developers may also call GetLastError() to retrieve the last MAPI error code. Possible MAPI error codes are: - MAPI_E_NOT_INITIALIZED: MAPI subsystem has not been initialized - MAPI_E_CALL_FAILED: A network problem was encountered during the transaction \sa OpenPublicFolder */ _PUBLIC_ enum MAPISTATUS OpenPublicFolderByName(mapi_object_t *obj_folder, mapi_object_t *obj_child, const char *name) { struct mapi_request *mapi_request; struct mapi_response *mapi_response; struct EcDoRpc_MAPI_REQ *mapi_req; struct OpenPublicFolderByName_req request; struct mapi_session *session; NTSTATUS status; enum MAPISTATUS retval; uint32_t size = 0; TALLOC_CTX *mem_ctx; uint8_t logon_id; /* Sanity checks */ OPENCHANGE_RETVAL_IF(!obj_folder, MAPI_E_INVALID_PARAMETER, NULL); OPENCHANGE_RETVAL_IF(!obj_child, MAPI_E_INVALID_PARAMETER, NULL); OPENCHANGE_RETVAL_IF(!name, MAPI_E_INVALID_PARAMETER, NULL); session = mapi_object_get_session(obj_folder); OPENCHANGE_RETVAL_IF(!session, MAPI_E_INVALID_PARAMETER, NULL); if ((retval = mapi_object_get_logon_id(obj_folder, &logon_id)) != MAPI_E_SUCCESS) return retval; mem_ctx = talloc_named(session, 0, "OpenPublicFolderByName"); size = 0; /* Fill the OpenPublicFolderByName operation */ request.handle_idx = 0x1; size += sizeof (uint8_t); /* name is prefixed with 32 bit [size] */ request.name = name; size += strlen(name) + 1 + sizeof (uint32_t); /* Fill the MAPI_REQ request */ mapi_req = talloc_zero(mem_ctx, struct EcDoRpc_MAPI_REQ); mapi_req->opnum = op_MAPI_OpenPublicFolderByName; mapi_req->logon_id = logon_id; mapi_req->handle_idx = 0; mapi_req->u.mapi_OpenPublicFolderByName = request; size += 5; /* Fill the mapi_request structure */ mapi_request = talloc_zero(mem_ctx, struct mapi_request); mapi_request->mapi_len = size + sizeof (uint32_t) * 2; mapi_request->length = size; mapi_request->mapi_req = mapi_req; mapi_request->handles = talloc_array(mem_ctx, uint32_t, 2); mapi_request->handles[0] = mapi_object_get_handle(obj_folder); mapi_request->handles[1] = 0xffffffff; status = emsmdb_transaction_wrapper(session, mem_ctx, mapi_request, &mapi_response); OPENCHANGE_RETVAL_IF(!NT_STATUS_IS_OK(status), MAPI_E_CALL_FAILED, mem_ctx); OPENCHANGE_RETVAL_IF(!mapi_response->mapi_repl, MAPI_E_CALL_FAILED, mem_ctx); retval = mapi_response->mapi_repl->error_code; OPENCHANGE_RETVAL_IF(retval, retval, mem_ctx); OPENCHANGE_CHECK_NOTIFICATION(session, mapi_response); /* Set object session and handle */ mapi_object_set_session(obj_child, session); mapi_object_set_handle(obj_child, mapi_response->handles[1]); mapi_object_set_logon_id(obj_child, logon_id); talloc_free(mapi_response); talloc_free(mem_ctx); return MAPI_E_SUCCESS; } /** \details Sets a folder as the destination for incoming messages of a particular message class. \param obj_store the store to set the receive folder for \param obj_folder the destination folder \param lpszMessageClass the message class the folder will receive \return MAPI_E_SUCCESS on success, otherwise MAPI error. \note Developers may also call GetLastError() to retrieve the last MAPI error code. Possible MAPI error codes are: - MAPI_E_NOT_INITIALIZED: MAPI subsystem has not been initialized - MAPI_E_CALL_FAILED: A network problem was encountered during the transaction \sa GetReceiveFolder, GetReceiveFolderTable */ _PUBLIC_ enum MAPISTATUS SetReceiveFolder(mapi_object_t *obj_store, mapi_object_t *obj_folder, const char *lpszMessageClass) { struct mapi_request *mapi_request; struct mapi_response *mapi_response; struct EcDoRpc_MAPI_REQ *mapi_req; struct SetReceiveFolder_req request; struct mapi_session *session; NTSTATUS status; enum MAPISTATUS retval; uint32_t size; TALLOC_CTX *mem_ctx; uint8_t logon_id; /* Sanity checks */ OPENCHANGE_RETVAL_IF(!obj_store, MAPI_E_INVALID_PARAMETER, NULL); OPENCHANGE_RETVAL_IF(!obj_folder, MAPI_E_INVALID_PARAMETER, NULL); OPENCHANGE_RETVAL_IF(!lpszMessageClass, MAPI_E_INVALID_PARAMETER, NULL); session = mapi_object_get_session(obj_store); OPENCHANGE_RETVAL_IF(!session, MAPI_E_INVALID_PARAMETER, NULL); if ((retval = mapi_object_get_logon_id(obj_store, &logon_id)) != MAPI_E_SUCCESS) return retval; mem_ctx = talloc_named(session, 0, "SetReceiveFolder"); /* Fill the SetReceiveFolder operation */ size = 0; request.fid = mapi_object_get_id(obj_folder); size += sizeof (uint64_t); request.lpszMessageClass = lpszMessageClass; size += strlen(lpszMessageClass) + 1; /* Fill the MAPI_REQ request */ mapi_req = talloc_zero(mem_ctx, struct EcDoRpc_MAPI_REQ); mapi_req->opnum = op_MAPI_SetReceiveFolder; mapi_req->logon_id = logon_id; mapi_req->handle_idx = 0; mapi_req->u.mapi_SetReceiveFolder = request; size += 5; /* Fill the mapi_request structure */ mapi_request = talloc_zero(mem_ctx, struct mapi_request); mapi_request->mapi_len = size + sizeof (uint32_t); mapi_request->length = size; mapi_request->mapi_req = mapi_req; mapi_request->handles = talloc_array(mem_ctx, uint32_t, 1); mapi_request->handles[0] = mapi_object_get_handle(obj_store); status = emsmdb_transaction_wrapper(session, mem_ctx, mapi_request, &mapi_response); OPENCHANGE_RETVAL_IF(!NT_STATUS_IS_OK(status), MAPI_E_CALL_FAILED, mem_ctx); OPENCHANGE_RETVAL_IF(!mapi_response->mapi_repl, MAPI_E_CALL_FAILED, mem_ctx); retval = mapi_response->mapi_repl->error_code; OPENCHANGE_RETVAL_IF(retval, retval, mem_ctx); OPENCHANGE_CHECK_NOTIFICATION(session, mapi_response); talloc_free(mapi_response); talloc_free(mem_ctx); return MAPI_E_SUCCESS; } /** \details Gets the receive folder for incoming messages of a particular message class. This function obtains the folder that was established as the destination for incoming messages of a specified message class, or the default receive folder for the message store. \param obj_store the store to get the receiver folder for \param id_folder the resulting folder identification \param MessageClass which message class to find the receivefolder for \return MAPI_E_SUCCESS on success, otherwise MAPI error. \note Developers may also call GetLastError() to retrieve the last MAPI error code. Possible MAPI error codes are: - MAPI_E_NOT_INITIALIZED: MAPI subsystem has not been initialized - MAPI_E_CALL_FAILED: A network problem was encountered during the transaction \sa MAPIInitialize, OpenMsgStore, GetLastError, SetReceiveFolder, GetReceiveFolderTable */ _PUBLIC_ enum MAPISTATUS GetReceiveFolder(mapi_object_t *obj_store, mapi_id_t *id_folder, const char *MessageClass) { struct mapi_request *mapi_request; struct mapi_response *mapi_response; struct EcDoRpc_MAPI_REQ *mapi_req; struct GetReceiveFolder_req request; struct mapi_session *session; NTSTATUS status; enum MAPISTATUS retval; uint32_t size = 0; TALLOC_CTX *mem_ctx; uint8_t logon_id; /* Sanity checks */ OPENCHANGE_RETVAL_IF(!obj_store, MAPI_E_INVALID_PARAMETER, NULL); session = mapi_object_get_session(obj_store); OPENCHANGE_RETVAL_IF(!session, MAPI_E_INVALID_PARAMETER, NULL); if ((retval = mapi_object_get_logon_id(obj_store, &logon_id)) != MAPI_E_SUCCESS) return retval; mem_ctx = talloc_named(session, 0, "GetReceiveFolder"); *id_folder = 0; /* Fill the GetReceiveFolder operation */ if (!MessageClass) { request.MessageClass = ""; size += 1; } else { request.MessageClass = MessageClass; size += strlen (MessageClass) + 1; } /* Fill the MAPI_REQ request */ mapi_req = talloc_zero(mem_ctx, struct EcDoRpc_MAPI_REQ); mapi_req->opnum = op_MAPI_GetReceiveFolder; mapi_req->logon_id = logon_id; mapi_req->handle_idx = 0; mapi_req->u.mapi_GetReceiveFolder = request; size += 5; /* Fill the mapi_request structure */ mapi_request = talloc_zero(mem_ctx, struct mapi_request); mapi_request->mapi_len = size + sizeof (uint32_t); mapi_request->length = size; mapi_request->mapi_req = mapi_req; mapi_request->handles = talloc_array(mem_ctx, uint32_t, 1); mapi_request->handles[0] = mapi_object_get_handle(obj_store); status = emsmdb_transaction_wrapper(session, mem_ctx, mapi_request, &mapi_response); OPENCHANGE_RETVAL_IF(!NT_STATUS_IS_OK(status), MAPI_E_CALL_FAILED, mem_ctx); OPENCHANGE_RETVAL_IF(!mapi_response->mapi_repl, MAPI_E_CALL_FAILED, mem_ctx); retval = mapi_response->mapi_repl->error_code; OPENCHANGE_RETVAL_IF(retval, retval, mem_ctx); OPENCHANGE_CHECK_NOTIFICATION(session, mapi_response); *id_folder = mapi_response->mapi_repl->u.mapi_GetReceiveFolder.folder_id; talloc_free(mapi_response); talloc_free(mem_ctx); return MAPI_E_SUCCESS; } /** \details Retrieve the receive folder table which includes all the information about the receive folders for the message store \param obj_store the message store object \param SRowSet pointer on a SRowSet structure with GetReceiveFolderTable results. Developers are required to call MAPIFreeBuffer(SRowSet.aRow) when they don't need the folder table data anymore. \return MAPI_E_SUCCESS on success, otherwise MAPI error. \note Developers may also call GetLastError() to retrieve the last MAPI error code. Possible MAPI error codes are: - MAPI_E_NOT_INITIALIZED: MAPI subsystem has not been initialized - MAPI_E_CALL_FAILED: A network problem was encountered during the transaction \sa GetReceiveFolder, SetReceiveFolder */ _PUBLIC_ enum MAPISTATUS GetReceiveFolderTable(mapi_object_t *obj_store, struct SRowSet *SRowSet) { struct mapi_request *mapi_request; struct mapi_response *mapi_response; struct EcDoRpc_MAPI_REQ *mapi_req; struct GetReceiveFolderTable_repl *reply; struct mapi_session *session; NTSTATUS status; enum MAPISTATUS retval; uint32_t size = 0; TALLOC_CTX *mem_ctx; uint32_t i; uint8_t logon_id; /* Sanity checks */ OPENCHANGE_RETVAL_IF(!obj_store, MAPI_E_INVALID_PARAMETER, NULL); session = mapi_object_get_session(obj_store); OPENCHANGE_RETVAL_IF(!session, MAPI_E_INVALID_PARAMETER, NULL); if ((retval = mapi_object_get_logon_id(obj_store, &logon_id)) != MAPI_E_SUCCESS) return retval; mem_ctx = talloc_named(session, 0, "GetReceiveFolderTable"); size = 0; /* Fill the MAPI_REQ request */ mapi_req = talloc_zero(mem_ctx, struct EcDoRpc_MAPI_REQ); mapi_req->opnum = op_MAPI_GetReceiveFolderTable; mapi_req->logon_id = logon_id; mapi_req->handle_idx = 0; size += 5; /* Fill the mapi_request structure */ mapi_request = talloc_zero(mem_ctx, struct mapi_request); mapi_request->mapi_len = size + sizeof (uint32_t); mapi_request->length = size; mapi_request->mapi_req = mapi_req; mapi_request->handles = talloc_array(mem_ctx, uint32_t, 1); mapi_request->handles[0] = mapi_object_get_handle(obj_store); status = emsmdb_transaction_wrapper(session, mem_ctx, mapi_request, &mapi_response); OPENCHANGE_RETVAL_IF(!NT_STATUS_IS_OK(status), MAPI_E_CALL_FAILED, mem_ctx); OPENCHANGE_RETVAL_IF(!mapi_response->mapi_repl, MAPI_E_CALL_FAILED, mem_ctx); retval = mapi_response->mapi_repl->error_code; OPENCHANGE_RETVAL_IF(retval, retval, mem_ctx); OPENCHANGE_CHECK_NOTIFICATION(session, mapi_response); reply = &mapi_response->mapi_repl->u.mapi_GetReceiveFolderTable; /* Retrieve the ReceiveFolderTable entries */ SRowSet->cRows = reply->cValues; SRowSet->aRow = talloc_array((TALLOC_CTX *)session, struct SRow, reply->cValues); for (i = 0; i < reply->cValues; i++) { SRowSet->aRow[i].ulAdrEntryPad = 0; SRowSet->aRow[i].cValues = 3; SRowSet->aRow[i].lpProps = talloc_array((TALLOC_CTX *)SRowSet->aRow, struct SPropValue, SRowSet->aRow[i].cValues); SRowSet->aRow[i].lpProps[0].ulPropTag = PR_FID; SRowSet->aRow[i].lpProps[0].dwAlignPad = 0x0; SRowSet->aRow[i].lpProps[0].value.d = reply->entries[i].fid; if (reply->entries[i].lpszMessageClass && strlen(reply->entries[i].lpszMessageClass)) { SRowSet->aRow[i].lpProps[1].ulPropTag = PR_MESSAGE_CLASS; SRowSet->aRow[i].lpProps[1].dwAlignPad = 0x0; SRowSet->aRow[i].lpProps[1].value.lpszA = talloc_strdup((TALLOC_CTX *)SRowSet->aRow[i].lpProps, reply->entries[i].lpszMessageClass); } else { SRowSet->aRow[i].lpProps[1].ulPropTag = PR_MESSAGE_CLASS; SRowSet->aRow[i].lpProps[1].dwAlignPad = 0x0; SRowSet->aRow[i].lpProps[1].value.lpszA = ""; } SRowSet->aRow[i].lpProps[2].ulPropTag = PR_LAST_MODIFICATION_TIME; SRowSet->aRow[i].lpProps[2].dwAlignPad = 0x0; SRowSet->aRow[i].lpProps[2].value.ft.dwLowDateTime = reply->entries[i].modiftime.dwLowDateTime; SRowSet->aRow[i].lpProps[2].value.ft.dwHighDateTime = reply->entries[i].modiftime.dwHighDateTime; } talloc_free(mapi_response); talloc_free(mem_ctx); return MAPI_E_SUCCESS; } /** \details Retrieves the folder ID of the temporary transport folder. \param obj_store the server object \param FolderId pointer on the returning Folder identifier \return MAPI_E_SUCCESS on success, otherwise MAPI error. \note Developers may also call GetLastError() to retrieve the last MAPI error code. Possible MAPI error codes are: - MAPI_E_NOT_INITIALIZED: MAPI subsystem has not been initialized - MAPI_E_CALL_FAILED: A network problem was encountered during the transaction */ _PUBLIC_ enum MAPISTATUS GetTransportFolder(mapi_object_t *obj_store, mapi_id_t *FolderId) { struct mapi_request *mapi_request; struct mapi_response *mapi_response; struct EcDoRpc_MAPI_REQ *mapi_req; struct GetTransportFolder_repl *reply; struct mapi_session *session; NTSTATUS status; enum MAPISTATUS retval; uint32_t size = 0; TALLOC_CTX *mem_ctx; uint8_t logon_id; /* Sanity checks */ OPENCHANGE_RETVAL_IF(!obj_store, MAPI_E_INVALID_PARAMETER, NULL); OPENCHANGE_RETVAL_IF(!FolderId, MAPI_E_INVALID_PARAMETER, NULL); session = mapi_object_get_session(obj_store); OPENCHANGE_RETVAL_IF(!session, MAPI_E_INVALID_PARAMETER, NULL); if ((retval = mapi_object_get_logon_id(obj_store, &logon_id)) != MAPI_E_SUCCESS) return retval; mem_ctx = talloc_named(session, 0, "GetTransportFolder"); size = 0; /* Fill the MAPI_REQ request */ mapi_req = talloc_zero(mem_ctx, struct EcDoRpc_MAPI_REQ); mapi_req->opnum = op_MAPI_GetTransportFolder; mapi_req->logon_id = logon_id; mapi_req->handle_idx = 0; size += 5; /* Fill the mapi_request structure */ mapi_request = talloc_zero(mem_ctx, struct mapi_request); mapi_request->mapi_len = size + sizeof (uint32_t); mapi_request->length = size; mapi_request->mapi_req = mapi_req; mapi_request->handles = talloc_array(mem_ctx, uint32_t, 1); mapi_request->handles[0] = mapi_object_get_handle(obj_store); status = emsmdb_transaction_wrapper(session, mem_ctx, mapi_request, &mapi_response); OPENCHANGE_RETVAL_IF(!NT_STATUS_IS_OK(status), MAPI_E_CALL_FAILED, mem_ctx); OPENCHANGE_RETVAL_IF(!mapi_response->mapi_repl, MAPI_E_CALL_FAILED, mem_ctx); retval = mapi_response->mapi_repl->error_code; OPENCHANGE_RETVAL_IF(retval, retval, mem_ctx); OPENCHANGE_CHECK_NOTIFICATION(session, mapi_response); /* Retrieve the FolderId parameter */ reply = &mapi_response->mapi_repl->u.mapi_GetTransportFolder; *FolderId = reply->FolderId; talloc_free(mapi_response); talloc_free(mem_ctx); return MAPI_E_SUCCESS; } /** \details Get the list of servers that host replicas of a given public folder. \param obj_store the public folder store object \param obj_folder the folder object we search replica for \param OwningServersCount number of OwningServers \param CheapServersCount number of low-cost servers \param OwningServers pointer on the list of NULL terminated ASCII string representing replica servers \return MAPI_E_SUCCESS on success, otherwise MAPI error. \note ecNoReplicaAvailable (0x469) can be returned if no replica is available for the folder. Developers may also call GetLastError() to retrieve the last MAPI error code. Possible MAPI error codes are: - MAPI_E_NOT_INITIALIZED: MAPI subsystem has not been initialized - MAPI_E_CALL_FAILED: A network problem was encountered during the transaction */ _PUBLIC_ enum MAPISTATUS GetOwningServers(mapi_object_t *obj_store, mapi_object_t *obj_folder, uint16_t *OwningServersCount, uint16_t *CheapServersCount, char **OwningServers) { struct mapi_request *mapi_request; struct mapi_response *mapi_response; struct EcDoRpc_MAPI_REQ *mapi_req; struct GetOwningServers_req request; struct GetOwningServers_repl response; struct mapi_session *session; NTSTATUS status; enum MAPISTATUS retval; uint32_t size; TALLOC_CTX *mem_ctx; mapi_id_t FolderId; uint32_t i; uint8_t logon_id; /* Sanity checks */ OPENCHANGE_RETVAL_IF(!obj_store, MAPI_E_INVALID_PARAMETER, NULL); OPENCHANGE_RETVAL_IF(!obj_folder, MAPI_E_INVALID_PARAMETER, NULL); OPENCHANGE_RETVAL_IF(!OwningServersCount, MAPI_E_INVALID_PARAMETER, NULL); OPENCHANGE_RETVAL_IF(!CheapServersCount, MAPI_E_INVALID_PARAMETER, NULL); OPENCHANGE_RETVAL_IF(!OwningServers, MAPI_E_INVALID_PARAMETER, NULL); session = mapi_object_get_session(obj_store); OPENCHANGE_RETVAL_IF(!session, MAPI_E_INVALID_PARAMETER, NULL); if ((retval = mapi_object_get_logon_id(obj_store, &logon_id)) != MAPI_E_SUCCESS) return retval; FolderId = mapi_object_get_id(obj_folder); OPENCHANGE_RETVAL_IF(!FolderId, MAPI_E_INVALID_PARAMETER, NULL); mem_ctx = talloc_named(session, 0, "GetOwningServers"); size = 0; /* Fill the GetOwningServers operation */ request.FolderId = FolderId; size += sizeof (uint64_t); /* Fill the MAPI_REQ request */ mapi_req = talloc_zero(mem_ctx, struct EcDoRpc_MAPI_REQ); mapi_req->opnum = op_MAPI_GetOwningServers; mapi_req->logon_id = logon_id; mapi_req->handle_idx = 0; mapi_req->u.mapi_GetOwningServers = request; size += 5; /* Fill the mapi_request structure */ mapi_request = talloc_zero(mem_ctx, struct mapi_request); mapi_request->mapi_len = size + sizeof (uint32_t); mapi_request->length = size; mapi_request->mapi_req = mapi_req; mapi_request->handles = talloc_array(mem_ctx, uint32_t, 1); mapi_request->handles[0] = mapi_object_get_handle(obj_store); status = emsmdb_transaction_wrapper(session, mem_ctx, mapi_request, &mapi_response); OPENCHANGE_RETVAL_IF(!NT_STATUS_IS_OK(status), MAPI_E_CALL_FAILED, mem_ctx); OPENCHANGE_RETVAL_IF(!mapi_response->mapi_repl, MAPI_E_CALL_FAILED, mem_ctx); retval = mapi_response->mapi_repl->error_code; OPENCHANGE_RETVAL_IF(retval, retval, mem_ctx); OPENCHANGE_CHECK_NOTIFICATION(session, mapi_response); /* Retrieve GetOwningServers response */ response = mapi_response->mapi_repl->u.mapi_GetOwningServers; *OwningServersCount = response.OwningServersCount; *CheapServersCount = response.CheapServersCount; if (*OwningServersCount) { OwningServers = talloc_array((TALLOC_CTX *)session, char *, *OwningServersCount + 1); for (i = 0; i != *OwningServersCount; i++) { OwningServers[i] = talloc_strdup((TALLOC_CTX *)OwningServers, response.OwningServers[i]); } OwningServers[i] = NULL; } else { OwningServers = NULL; } talloc_free(mapi_response); talloc_free(mem_ctx); return MAPI_E_SUCCESS; } /** \details Gets the current store state for the logged in user This operation must be performed against a user store (not against a Public Folder store). The StoreState will have the STORE_HAS_SEARCHES flag set if there are any active search folders. There are (currently) no other flags in the StoreState. \param obj_store the store object \param StoreState pointer to the store state returned by the server \return MAPI_E_SUCCESS on success, otherwise MAPI error. \note Developers may also call GetLastError() to retrieve the last MAPI error code. Possible MAPI error codes are: - MAPI_E_NOT_INITIALIZED: MAPI subsystem has not been initialized - MAPI_E_INVALID_PARAMETER: obj_store or StoreState are not valid - MAPI_E_CALL_FAILED: A network problem was encountered during the transaction */ _PUBLIC_ enum MAPISTATUS GetStoreState(mapi_object_t *obj_store, uint32_t *StoreState) { struct mapi_request *mapi_request; struct mapi_response *mapi_response; struct EcDoRpc_MAPI_REQ *mapi_req; struct mapi_session *session; NTSTATUS status; enum MAPISTATUS retval; uint32_t size = 0; TALLOC_CTX *mem_ctx; uint8_t logon_id; /* Sanity Checks */ OPENCHANGE_RETVAL_IF(!obj_store, MAPI_E_INVALID_PARAMETER, NULL); OPENCHANGE_RETVAL_IF(!StoreState, MAPI_E_INVALID_PARAMETER, NULL); session = mapi_object_get_session(obj_store); OPENCHANGE_RETVAL_IF(!session, MAPI_E_INVALID_PARAMETER, NULL); if ((retval = mapi_object_get_logon_id(obj_store, &logon_id)) != MAPI_E_SUCCESS) return retval; mem_ctx = talloc_named(session, 0, "GetStoreState"); size = 0; /* Fill the MAPI_REQ request */ mapi_req = talloc_zero(mem_ctx, struct EcDoRpc_MAPI_REQ); mapi_req->opnum = op_MAPI_GetStoreState; mapi_req->logon_id = logon_id; mapi_req->handle_idx = 0; size += 5; /* Fill the mapi_request structure */ mapi_request = talloc_zero(mem_ctx, struct mapi_request); mapi_request->mapi_len = size + sizeof (uint32_t); mapi_request->length = size; mapi_request->mapi_req = mapi_req; mapi_request->handles = talloc_array(mem_ctx, uint32_t, 1); mapi_request->handles[0] = mapi_object_get_handle(obj_store); status = emsmdb_transaction_wrapper(session, mem_ctx, mapi_request, &mapi_response); OPENCHANGE_RETVAL_IF(!NT_STATUS_IS_OK(status), MAPI_E_CALL_FAILED, mem_ctx); OPENCHANGE_RETVAL_IF(!mapi_response->mapi_repl, MAPI_E_CALL_FAILED, mem_ctx); retval = mapi_response->mapi_repl->error_code; OPENCHANGE_RETVAL_IF(retval, retval, mem_ctx); OPENCHANGE_CHECK_NOTIFICATION(session, mapi_response); /* Retrieve the StoreState */ *StoreState = mapi_response->mapi_repl->u.mapi_GetStoreState.StoreState; talloc_free(mapi_response); talloc_free(mem_ctx); return MAPI_E_SUCCESS; } /** \details Retrieves the sending folder (OUTBOX) for a given store This function obtains the folder that was established as the destination for outgoing messages of a specified message class. This function does not result in any network traffic. \param obj_store the store to get the outbox folder for \param outbox_id the resulting folder identification \return MAPI_E_SUCCESS on success, otherwise MAPI error. \note Developers may also call GetLastError() to retrieve the last MAPI error code. Possible MAPI error codes are: - MAPI_E_NOT_INITIALIZED: MAPI subsystem has not been initialized - MAPI_E_CALL_FAILED: A network problem was encountered during the transaction \sa MAPIInitialize, OpenMsgStore, GetLastError, GetDefaultFolder */ _PUBLIC_ enum MAPISTATUS GetOutboxFolder(mapi_object_t *obj_store, mapi_id_t *outbox_id) { OPENCHANGE_RETVAL_IF(!obj_store, MAPI_E_INVALID_PARAMETER, NULL); *outbox_id = ((mapi_object_store_t *)obj_store->private_data)->fid_outbox; return MAPI_E_SUCCESS; } /** \details Notify the store of a new message to be processed \param obj_store the store that the message is in (logon object) \param obj_folder the folder that the message is in \param obj_msg the message to be processed \param MessageClass the message class of the message to be processed \param MessageFlags the message flags on the message \return MAPI_E_SUCCESS on success, otherwise MAPI error. \note Developers may also call GetLastError() to retrieve the last MAPI error code. Possible MAPI error codes are: - MAPI_E_NOT_INITIALIZED: MAPI subsystem has not been initialized - MAPI_E_INVALID_PARAMETER: one the parameters is invalid - MAPI_E_CALL_FAILED: A network problem was encountered during the transaction \sa GetReceiveFolder, GetReceiveFolderTable */ _PUBLIC_ enum MAPISTATUS TransportNewMail(mapi_object_t *obj_store, mapi_object_t *obj_folder, mapi_object_t *obj_msg, const char *MessageClass, uint32_t MessageFlags) { struct mapi_request *mapi_request; struct mapi_response *mapi_response; struct EcDoRpc_MAPI_REQ *mapi_req; struct TransportNewMail_req request; struct mapi_session *session; NTSTATUS status; enum MAPISTATUS retval; uint32_t size; TALLOC_CTX *mem_ctx; uint8_t logon_id; /* Sanity checks */ OPENCHANGE_RETVAL_IF(!obj_store, MAPI_E_INVALID_PARAMETER, NULL); OPENCHANGE_RETVAL_IF(!obj_store, MAPI_E_INVALID_PARAMETER, NULL); OPENCHANGE_RETVAL_IF(!obj_folder, MAPI_E_INVALID_PARAMETER, NULL); OPENCHANGE_RETVAL_IF(!obj_msg, MAPI_E_INVALID_PARAMETER, NULL); OPENCHANGE_RETVAL_IF(!MessageClass, MAPI_E_INVALID_PARAMETER, NULL); session = mapi_object_get_session(obj_folder); OPENCHANGE_RETVAL_IF(!session, MAPI_E_INVALID_PARAMETER, NULL); if ((retval = mapi_object_get_logon_id(obj_folder, &logon_id)) != MAPI_E_SUCCESS) return retval; mem_ctx = talloc_named(session, 0, "TransportNewMail"); /* Fill the TransportNewMail operation */ size = 0; request.MessageId = mapi_object_get_id(obj_msg); size += sizeof (uint64_t); request.FolderId = mapi_object_get_id(obj_folder); size += sizeof (uint64_t); request.MessageClass = MessageClass; size += strlen(MessageClass) + 1; request.MessageFlags = MessageFlags; size += sizeof(uint32_t); /* Fill the MAPI_REQ request */ mapi_req = talloc_zero(mem_ctx, struct EcDoRpc_MAPI_REQ); mapi_req->opnum = op_MAPI_TransportNewMail; mapi_req->logon_id = logon_id; mapi_req->handle_idx = 0; mapi_req->u.mapi_TransportNewMail = request; size += 5; /* Fill the mapi_request structure */ mapi_request = talloc_zero(mem_ctx, struct mapi_request); mapi_request->mapi_len = size + sizeof (uint32_t); mapi_request->length = size; mapi_request->mapi_req = mapi_req; mapi_request->handles = talloc_array(mem_ctx, uint32_t, 1); mapi_request->handles[0] = mapi_object_get_handle(obj_store); status = emsmdb_transaction_wrapper(session, mem_ctx, mapi_request, &mapi_response); OPENCHANGE_RETVAL_IF(!NT_STATUS_IS_OK(status), MAPI_E_CALL_FAILED, mem_ctx); OPENCHANGE_RETVAL_IF(!mapi_response->mapi_repl, MAPI_E_CALL_FAILED, mem_ctx); retval = mapi_response->mapi_repl->error_code; OPENCHANGE_RETVAL_IF(retval, retval, mem_ctx); talloc_free(mapi_response); talloc_free(mem_ctx); return MAPI_E_SUCCESS; } openchange-2.0/libmapi/IProfAdmin.c000066400000000000000000001644251223057412600172510ustar00rootroot00000000000000/* OpenChange MAPI implementation. Copyright (C) Julien Kerihuel 2007-2013. Copyright (C) Fabien Le Mentec 2007. This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see . */ #include "libmapi/libmapi.h" #include "libmapi/libmapi_private.h" #include #include #include /** \file IProfAdmin.c \brief MAPI Profiles interface */ /* * Private functions */ /** * Load a MAPI profile into a mapi_profile struct */ static enum MAPISTATUS ldb_load_profile(TALLOC_CTX *mem_ctx, struct ldb_context *ldb_ctx, struct mapi_profile *profile, const char *profname, const char *password) { int ret; enum ldb_scope scope = LDB_SCOPE_SUBTREE; struct ldb_result *res; struct ldb_message *msg; const char * const attrs[] = { "*", NULL }; memset(profile, 0, sizeof(struct mapi_profile)); /* fills in profile name */ profile->profname = talloc_strdup(mem_ctx, profname); if (!profile->profname) return MAPI_E_NOT_ENOUGH_RESOURCES; ret = ldb_search(ldb_ctx, mem_ctx, &res, ldb_get_default_basedn(ldb_ctx), scope, attrs, "(cn=%s)(cn=Profiles)", profile->profname); if (ret != LDB_SUCCESS) return MAPI_E_NOT_FOUND; /* profile not found */ if (!res->count) { talloc_free(res); return MAPI_E_NOT_FOUND; } /* more than one profile */ if (res->count > 1) { talloc_free(res); return MAPI_E_COLLISION; } /* fills in profile with query result */ msg = res->msgs[0]; profile->username = talloc_steal(profile, ldb_msg_find_attr_as_string(msg, "username", NULL)); profile->password = password ? password : talloc_steal(profile, ldb_msg_find_attr_as_string(msg, "password", NULL)); profile->workstation = talloc_steal(profile, ldb_msg_find_attr_as_string(msg, "workstation", NULL)); profile->realm = talloc_steal(profile, ldb_msg_find_attr_as_string(msg, "realm", NULL)); profile->domain = talloc_steal(profile, ldb_msg_find_attr_as_string(msg, "domain", NULL)); profile->mailbox = talloc_steal(profile, ldb_msg_find_attr_as_string(msg, "EmailAddress", NULL)); profile->homemdb = talloc_steal(profile, ldb_msg_find_attr_as_string(msg, "HomeMDB", NULL)); profile->localaddr = talloc_steal(profile, ldb_msg_find_attr_as_string(msg, "localaddress", NULL)); profile->server = talloc_steal(profile, ldb_msg_find_attr_as_string(msg, "binding", NULL)); profile->seal = ldb_msg_find_attr_as_bool(msg, "seal", false); profile->org = talloc_steal(profile, ldb_msg_find_attr_as_string(msg, "Organization", NULL)); profile->ou = talloc_steal(profile, ldb_msg_find_attr_as_string(msg, "OrganizationUnit", NULL)); profile->codepage = ldb_msg_find_attr_as_int(msg, "codepage", 0); profile->language = ldb_msg_find_attr_as_int(msg, "language", 0); profile->method = ldb_msg_find_attr_as_int(msg, "method", 0); profile->exchange_version = ldb_msg_find_attr_as_int(msg, "exchange_version", 0); profile->kerberos = talloc_steal(profile, ldb_msg_find_attr_as_string(msg, "kerberos", NULL)); talloc_free(res); return MAPI_E_SUCCESS; } /** * Remove the "default" attribute from whichever profile is currently the default profile */ static enum MAPISTATUS ldb_clear_default_profile(struct mapi_context *mapi_ctx, TALLOC_CTX *mem_ctx) { enum ldb_scope scope = LDB_SCOPE_SUBTREE; struct ldb_context *ldb_ctx; struct ldb_dn *basedn; struct ldb_message *msg; struct ldb_result *res; const char *attrs[] = { "PR_DEFAULT_PROFILE", NULL }; int ret; uint32_t i; ldb_ctx = mapi_ctx->ldb_ctx; basedn = ldb_dn_new(ldb_ctx, ldb_ctx, "CN=Profiles"); ret = ldb_search(ldb_ctx, mem_ctx, &res, basedn, scope, attrs, "(cn=*)"); if (ret != LDB_SUCCESS) return MAPI_E_NOT_FOUND; if (!res->count) return MAPI_E_NOT_FOUND; for (i = 0; i < res->count; i++) { struct ldb_message *message; msg = res->msgs[i]; if (msg->num_elements == 1) { message = talloc_steal(mem_ctx, msg); message->elements[0].flags = LDB_FLAG_MOD_DELETE; ret = ldb_modify(ldb_ctx, message); talloc_free(message); } } return MAPI_E_SUCCESS; } /** * Test if the password is correct */ static enum MAPISTATUS ldb_test_password(struct mapi_context *mapi_ctx, TALLOC_CTX *mem_ctx, const char *profile, const char *password) { enum ldb_scope scope = LDB_SCOPE_DEFAULT; struct ldb_context *ldb_ctx; struct ldb_message *msg; struct ldb_result *res; const char *attrs[] = {"cn", "password", NULL }; const char *ldb_password; int ret; ldb_ctx = mapi_ctx->ldb_ctx; ret = ldb_search(ldb_ctx, mem_ctx, &res, NULL, scope, attrs, "(cn=%s)(cn=Profiles)", profile); if (ret != LDB_SUCCESS) return MAPI_E_NO_SUPPORT; if (!res->count) return MAPI_E_NOT_FOUND; msg = res->msgs[0]; ldb_password = ldb_msg_find_attr_as_string(msg, "password", NULL); if (!ldb_password) return MAPI_E_NO_SUPPORT; if (strncmp(password, ldb_password, strlen(password))) return MAPI_E_LOGON_FAILED; return MAPI_E_SUCCESS; } /** * Add a profile to the database with default fields */ static enum MAPISTATUS ldb_create_profile(TALLOC_CTX *mem_ctx, struct ldb_context *ldb_ctx, const char *profname) { enum ldb_scope scope = LDB_SCOPE_SUBTREE; struct ldb_message msg; struct ldb_message_element el[2]; struct ldb_val vals[2][1]; struct ldb_result *res; struct ldb_dn *basedn; char *dn; int ret; const char * const attrs[] = { "*", NULL }; /* Sanity check */ if (profname == NULL) return MAPI_E_BAD_VALUE; /* Does the profile already exists? */ ret = ldb_search(ldb_ctx, mem_ctx, &res, ldb_get_default_basedn(ldb_ctx), scope, attrs, "(cn=%s)(cn=Profiles)", profname); if (ret == LDB_SUCCESS && res && res->msgs) return MAPI_E_NO_ACCESS; /* * We now prepare the entry for transaction */ dn = talloc_asprintf(mem_ctx, "CN=%s,CN=Profiles", profname); basedn = ldb_dn_new(ldb_ctx, ldb_ctx, dn); talloc_free(dn); if (!ldb_dn_validate(basedn)) return MAPI_E_BAD_VALUE; msg.dn = ldb_dn_copy(mem_ctx, basedn); msg.num_elements = 2; msg.elements = el; el[0].flags = 0; el[0].name = talloc_strdup(mem_ctx, "cn"); el[0].num_values = 1; el[0].values = vals[0]; vals[0][0].data = (uint8_t *)talloc_strdup(mem_ctx, profname); vals[0][0].length = strlen(profname); el[1].flags = 0; el[1].name = talloc_strdup(mem_ctx, "name"); el[1].num_values = 1; el[1].values = vals[1]; vals[1][0].data = (uint8_t *)talloc_strdup(mem_ctx, profname); vals[1][0].length = strlen(profname); ret = ldb_add(ldb_ctx, &msg); if (ret != LDB_SUCCESS) return MAPI_E_NO_SUPPORT; return MAPI_E_SUCCESS; } /* * delete the current profile */ static enum MAPISTATUS ldb_delete_profile(TALLOC_CTX *mem_ctx, struct ldb_context *ldb_ctx, const char *profname) { enum ldb_scope scope = LDB_SCOPE_SUBTREE; struct ldb_result *res; const char * const attrs[] = { "*", NULL }; int ret; ret = ldb_search(ldb_ctx, mem_ctx, &res, ldb_get_default_basedn(ldb_ctx), scope, attrs, "(cn=%s)(cn=Profiles)", profname); if (!res->msgs) return MAPI_E_NOT_FOUND; ret = ldb_delete(ldb_ctx, res->msgs[0]->dn); if (ret != LDB_SUCCESS) return MAPI_E_NOT_FOUND; return MAPI_E_SUCCESS; } /** \details Copy the MAPI profile \param mem_ctx pointer to the memory context \param ldb_ctx pointer to the LDB context \param profname_src pointer to the source profile name \param profname_dest pointer to the destination profile name */ static enum MAPISTATUS ldb_copy_profile(TALLOC_CTX *mem_ctx, struct ldb_context *ldb_ctx, const char *profname_src, const char *profname_dest) { int ret; enum ldb_scope scope = LDB_SCOPE_SUBTREE; struct ldb_result *res; struct ldb_result *res_dest; struct ldb_message *msg; const char * const attrs[] = { "*", NULL }; uint32_t i; char *dn; struct ldb_message_element *el; struct ldb_dn *basedn; /* Step 1. Load the source profile */ ret = ldb_search(ldb_ctx, mem_ctx, &res, ldb_get_default_basedn(ldb_ctx), scope, attrs, "(cn=%s)(cn=Profiles)", profname_src); /* profile not found */ if (ret != LDB_SUCCESS) return MAPI_E_NOT_FOUND; /* more than one profile */ if (res->count > 1) return MAPI_E_COLLISION; /* fills in profile with query result */ msg = res->msgs[0]; /* Step 2. Encure the desintation profile doesn't exist */ ret = ldb_search(ldb_ctx, mem_ctx, &res_dest, ldb_get_default_basedn(ldb_ctx), scope, attrs, "(cn=%s)(cn=Profiles)", profname_dest); /* If profile exists or there is more than one */ if (ret == LDB_SUCCESS && res_dest->count) return MAPI_E_COLLISION; /* Step 3. Customize destination profile */ dn = talloc_asprintf(mem_ctx, "CN=%s,CN=Profiles", profname_dest); basedn = ldb_dn_new(ldb_ctx, ldb_ctx, dn); talloc_free(dn); if (!ldb_dn_validate(basedn)) return MAPI_E_BAD_VALUE; msg->dn = ldb_dn_copy(mem_ctx, basedn); /* Change cn */ el = msg->elements; for (i = 0; i < msg->num_elements; i++) { if (el[i].name && !strcmp(el[i].name, "cn")) { el[i].values[0].data = (uint8_t *)talloc_strdup(mem_ctx, profname_dest); el[i].values[0].length = strlen(profname_dest); } } /* Step 4. Copy the profile */ ret = ldb_add(ldb_ctx, msg); /* talloc_free(basedn); */ if (ret != LDB_SUCCESS) return MAPI_E_NO_SUPPORT; return MAPI_E_SUCCESS; } /** \details Rename a profile \param mem_ctx pointer on the memory context \param old_profname the old profile name string \param new_profname the new profile name string \return MAPI_E_SUCCESS on success otherwise MAPI error. */ static enum MAPISTATUS ldb_rename_profile(struct mapi_context *mapi_ctx, TALLOC_CTX *mem_ctx, const char *old_profname, const char *new_profname) { int ret; struct ldb_context *ldb_ctx; struct ldb_dn *old_dn; struct ldb_dn *new_dn; char *dn; /* Sanity checks */ OPENCHANGE_RETVAL_IF(!old_profname, MAPI_E_INVALID_PARAMETER, NULL); OPENCHANGE_RETVAL_IF(!new_profname, MAPI_E_INVALID_PARAMETER, NULL); ldb_ctx = mapi_ctx->ldb_ctx; dn = talloc_asprintf(mem_ctx, "CN=%s,CN=Profiles", old_profname); old_dn = ldb_dn_new(mem_ctx, ldb_ctx, dn); talloc_free(dn); dn = talloc_asprintf(mem_ctx, "CN=%s,CN=Profiles", new_profname); new_dn = ldb_dn_new(mem_ctx, ldb_ctx, dn); talloc_free(dn); ret = ldb_rename(ldb_ctx, old_dn, new_dn); OPENCHANGE_RETVAL_IF(ret, MAPI_E_CORRUPT_STORE, NULL); return MAPI_E_SUCCESS; } /* * Public interface */ /** \details Add an attribute to the profile \param mapi_ctx pointer to the MAPI context \param profile pointer to the profile name \param attr the name of the atribute \param value the value of the attribute */ _PUBLIC_ enum MAPISTATUS mapi_profile_add_string_attr(struct mapi_context *mapi_ctx, const char *profile, const char *attr, const char *value) { TALLOC_CTX *mem_ctx; enum ldb_scope scope = LDB_SCOPE_SUBTREE; struct ldb_message msg; struct ldb_message_element el[1]; struct ldb_val vals[1][1]; struct ldb_result *res; struct ldb_context *ldb_ctx; struct ldb_dn *basedn; char *dn; int ret; const char * const attrs[] = { "*", NULL }; OPENCHANGE_RETVAL_IF(!mapi_ctx, MAPI_E_NOT_INITIALIZED, NULL); OPENCHANGE_RETVAL_IF(!mapi_ctx->ldb_ctx, MAPI_E_NOT_INITIALIZED, NULL); OPENCHANGE_RETVAL_IF(!profile, MAPI_E_BAD_VALUE, NULL); OPENCHANGE_RETVAL_IF(!value, MAPI_E_INVALID_PARAMETER, NULL); mem_ctx = talloc_named(mapi_ctx->mem_ctx, 0, "mapi_profile_add_string_attr"); ldb_ctx = mapi_ctx->ldb_ctx; /* Retrieve the profile from the database */ ret = ldb_search(ldb_ctx, mem_ctx, &res, ldb_get_default_basedn(ldb_ctx), scope, attrs, "(cn=%s)(cn=Profiles)", profile); OPENCHANGE_RETVAL_IF(ret != LDB_SUCCESS, MAPI_E_BAD_VALUE, mem_ctx); /* Preparing for the transaction */ dn = talloc_asprintf(mem_ctx, "CN=%s,CN=Profiles", profile); basedn = ldb_dn_new(ldb_ctx, ldb_ctx, dn); talloc_free(dn); OPENCHANGE_RETVAL_IF(!ldb_dn_validate(basedn), MAPI_E_BAD_VALUE, mem_ctx); msg.dn = ldb_dn_copy(mem_ctx, basedn); msg.num_elements = 1; msg.elements = el; el[0].flags = LDB_FLAG_MOD_ADD; el[0].name = talloc_strdup(mem_ctx, attr); el[0].num_values = 1; el[0].values = vals[0]; vals[0][0].data = (uint8_t *)talloc_strdup(mem_ctx, value); vals[0][0].length = strlen(value); ret = ldb_modify(ldb_ctx, &msg); OPENCHANGE_RETVAL_IF(ret != LDB_SUCCESS, MAPI_E_NO_SUPPORT, mem_ctx); talloc_free(mem_ctx); return MAPI_E_SUCCESS; } /** \details Modify an attribute \param mapi_ctx pointer to the MAPI context \param profname the name of the profile \param attr the name of the attribute \param value the value of the attribute */ _PUBLIC_ enum MAPISTATUS mapi_profile_modify_string_attr(struct mapi_context *mapi_ctx, const char *profname, const char *attr, const char *value) { TALLOC_CTX *mem_ctx; enum ldb_scope scope = LDB_SCOPE_SUBTREE; struct ldb_message msg; struct ldb_message_element el[1]; struct ldb_val vals[1][1]; struct ldb_result *res; struct ldb_context *ldb_ctx; struct ldb_dn *basedn; char *dn; int ret; const char * const attrs[] = { "*", NULL }; OPENCHANGE_RETVAL_IF(!mapi_ctx, MAPI_E_NOT_INITIALIZED, NULL); OPENCHANGE_RETVAL_IF(!profname, MAPI_E_BAD_VALUE, NULL); ldb_ctx = mapi_ctx->ldb_ctx; mem_ctx = talloc_named(mapi_ctx->mem_ctx, 0, "mapi_profile_modify_string_attr"); /* Retrieve the profile from the database */ ret = ldb_search(ldb_ctx, mem_ctx, &res, ldb_get_default_basedn(ldb_ctx), scope, attrs, "(cn=%s)(cn=Profiles)", profname); OPENCHANGE_RETVAL_IF(ret != LDB_SUCCESS, MAPI_E_BAD_VALUE, mem_ctx); /* Preparing for the transaction */ dn = talloc_asprintf(mem_ctx, "CN=%s,CN=Profiles", profname); basedn = ldb_dn_new(ldb_ctx, ldb_ctx, dn); talloc_free(dn); OPENCHANGE_RETVAL_IF(!ldb_dn_validate(basedn), MAPI_E_BAD_VALUE, mem_ctx); msg.dn = ldb_dn_copy(mem_ctx, basedn); msg.num_elements = 1; msg.elements = el; el[0].flags = LDB_FLAG_MOD_REPLACE; el[0].name = talloc_strdup(mem_ctx, attr); el[0].num_values = 1; el[0].values = vals[0]; vals[0][0].data = (uint8_t *)talloc_strdup(mem_ctx, value); vals[0][0].length = strlen(value); ret = ldb_modify(ldb_ctx, &msg); OPENCHANGE_RETVAL_IF(ret != LDB_SUCCESS, MAPI_E_NO_SUPPORT, mem_ctx); talloc_free(mem_ctx); return MAPI_E_SUCCESS; } /** \details Delete an attribute \param mapi_ctx pointer to the MAPI context \param profname the name of the profile \param attr the name of the attribute \param value the value of the attribute */ _PUBLIC_ enum MAPISTATUS mapi_profile_delete_string_attr(struct mapi_context *mapi_ctx, const char *profname, const char *attr, const char *value) { TALLOC_CTX *mem_ctx; enum ldb_scope scope = LDB_SCOPE_SUBTREE; struct ldb_message msg; struct ldb_message_element el[1]; struct ldb_val vals[1][1]; struct ldb_result *res; struct ldb_context *ldb_ctx; struct ldb_dn *basedn; char *dn; int ret; const char * const attrs[] = { "*", NULL }; /* Saniy checks */ OPENCHANGE_RETVAL_IF(!mapi_ctx, MAPI_E_NOT_INITIALIZED, NULL); OPENCHANGE_RETVAL_IF(!mapi_ctx->ldb_ctx, MAPI_E_NOT_INITIALIZED, NULL); OPENCHANGE_RETVAL_IF(!profname, MAPI_E_BAD_VALUE, NULL); ldb_ctx = mapi_ctx->ldb_ctx; mem_ctx = talloc_named(mapi_ctx->mem_ctx, 0, "mapi_profile_delete_string_attr"); /* Retrieve the profile from the database */ ret = ldb_search(ldb_ctx, mem_ctx, &res, ldb_get_default_basedn(ldb_ctx), scope, attrs, "(cn=%s)(cn=Profiles)", profname); OPENCHANGE_RETVAL_IF(ret != LDB_SUCCESS, MAPI_E_BAD_VALUE, mem_ctx); /* Preparing for the transaction */ dn = talloc_asprintf(mem_ctx, "CN=%s,CN=Profiles", profname); basedn = ldb_dn_new(ldb_ctx, ldb_ctx, dn); talloc_free(dn); OPENCHANGE_RETVAL_IF(!ldb_dn_validate(basedn), MAPI_E_BAD_VALUE, mem_ctx); msg.dn = ldb_dn_copy(mem_ctx, basedn); msg.num_elements = 1; msg.elements = el; el[0].flags = LDB_FLAG_MOD_DELETE; el[0].name = talloc_strdup(mem_ctx, attr); el[0].num_values = 1; el[0].values = vals[0]; vals[0][0].data = (uint8_t *)talloc_strdup(mem_ctx, value); vals[0][0].length = strlen(value); ret = ldb_modify(ldb_ctx, &msg); OPENCHANGE_RETVAL_IF(ret != LDB_SUCCESS, MAPI_E_NO_SUPPORT, mem_ctx); talloc_free(mem_ctx); return MAPI_E_SUCCESS; } /* * Private function which opens the profile store * Should only be called within MAPIInitialize */ enum MAPISTATUS OpenProfileStore(TALLOC_CTX *mem_ctx, struct ldb_context **ldb_ctx, const char *profiledb) { int ret; struct ldb_context *tmp_ctx; struct tevent_context *ev; *ldb_ctx = 0; /* store path */ if (!profiledb) return MAPI_E_NOT_FOUND; ev = tevent_context_init(mem_ctx); if (!ev) return MAPI_E_NOT_ENOUGH_RESOURCES; /* connect to the store */ tmp_ctx = ldb_init(mem_ctx, ev); if (!tmp_ctx) return MAPI_E_NOT_ENOUGH_RESOURCES; ret = ldb_connect(tmp_ctx, profiledb, 0, NULL); if (ret != LDB_SUCCESS) return MAPI_E_NOT_FOUND; *ldb_ctx = tmp_ctx; return MAPI_E_SUCCESS; } /** \details Get default ldif_path This function returns the path for the default LDIF files. \sa CreateProfileStore */ _PUBLIC_ const char *mapi_profile_get_ldif_path(void) { return DEFAULT_LDIF; } /** \details Create a profile database This function creates a new profile database, including doing an initial setup. \param profiledb the absolute path to the profile database intended to be created \param ldif_path the absolute path to the LDIF information to use for initial setup. \return MAPI_E_SUCCESS on success, otherwise MAPI error. \note Developers may also call GetLastError() to retrieve the last MAPI error code. Possible MAPI error codes are: - MAPI_E_CALL_FAILED: profiledb or ldif_path is not set - MAPI_E_NOT_ENOUGH_RESOURCES: ldb subsystem initialization failed - MAPI_E_NO_ACCESS: connection or ldif add failed \sa GetLastError, mapi_profile_get_ldif_path */ _PUBLIC_ enum MAPISTATUS CreateProfileStore(const char *profiledb, const char *ldif_path) { int ret; TALLOC_CTX *mem_ctx; struct ldb_context *ldb_ctx; struct ldb_ldif *ldif; char *url = NULL; char *filename = NULL; FILE *f; struct tevent_context *ev; OPENCHANGE_RETVAL_IF(!profiledb, MAPI_E_INVALID_PARAMETER, NULL); OPENCHANGE_RETVAL_IF(!ldif_path, MAPI_E_INVALID_PARAMETER, NULL); mem_ctx = talloc_named(NULL, 0, "CreateProfileStore"); ev = tevent_context_init(mem_ctx); OPENCHANGE_RETVAL_IF(!ev, MAPI_E_NOT_ENOUGH_RESOURCES, mem_ctx); ldb_ctx = ldb_init(mem_ctx, ev); OPENCHANGE_RETVAL_IF(!ldb_ctx, MAPI_E_NOT_ENOUGH_RESOURCES, mem_ctx); url = talloc_asprintf(mem_ctx, "tdb://%s", profiledb); ret = ldb_connect(ldb_ctx, url, 0, 0); talloc_free(url); OPENCHANGE_RETVAL_IF(ret != LDB_SUCCESS, MAPI_E_NO_ACCESS, mem_ctx); filename = talloc_asprintf(mem_ctx, "%s/oc_profiles_init.ldif", ldif_path); f = fopen(filename, "r"); OPENCHANGE_RETVAL_IF(!f, MAPI_E_NO_ACCESS, mem_ctx); talloc_free(filename); while ((ldif = ldb_ldif_read_file(ldb_ctx, f))) { struct ldb_message *normalized_msg; ret = ldb_msg_normalize(ldb_ctx, mem_ctx, ldif->msg, &normalized_msg); OPENCHANGE_RETVAL_IF(ret != LDB_SUCCESS, MAPI_E_NO_ACCESS, mem_ctx); ret = ldb_add(ldb_ctx, normalized_msg); if (ret != LDB_SUCCESS) { fclose(f); OPENCHANGE_RETVAL_ERR(MAPI_E_NO_ACCESS, mem_ctx); } ldb_ldif_read_free(ldb_ctx, ldif); talloc_free(normalized_msg); } fclose(f); filename = talloc_asprintf(mem_ctx, "%s/oc_profiles_schema.ldif", ldif_path); f = fopen(filename, "r"); OPENCHANGE_RETVAL_IF(!f, MAPI_E_NO_ACCESS, mem_ctx); talloc_free(filename); while ((ldif = ldb_ldif_read_file(ldb_ctx, f))) { struct ldb_message *normalized_msg; ret = ldb_msg_normalize(ldb_ctx, mem_ctx, ldif->msg, &normalized_msg); OPENCHANGE_RETVAL_IF(ret != LDB_SUCCESS, MAPI_E_NO_ACCESS, mem_ctx); ret = ldb_add(ldb_ctx, normalized_msg); if (ret != LDB_SUCCESS) { fclose(f); OPENCHANGE_RETVAL_ERR(MAPI_E_NO_ACCESS, mem_ctx); } ldb_ldif_read_free(ldb_ctx, ldif); talloc_free(normalized_msg); } fclose(f); talloc_free(mem_ctx); return MAPI_E_SUCCESS; } /** \details Load a profile from the database This function opens a named profile from the database, and fills the mapi_profile structure with common profile information. \param mapi_ctx pointer to the MAPI context \param profile the resulting profile \param profname the name of the profile to open \param password the password to use with the profile \return MAPI_E_SUCCESS on success, otherwise MAPI error. \note profile must be talloced because it used as talloc subcontext for data members. Developers may also call GetLastError() to retrieve the last MAPI error code. Possible MAPI error codes are: - MAPI_E_NOT_ENOUGH_RESOURCES: ldb subsystem initialization failed - MAPI_E_NOT_FOUND: the profile was not found in the profile database - MAPI_E_COLLISION: profname matched more than one entry \sa MAPIInitialize, GetLastError */ _PUBLIC_ enum MAPISTATUS OpenProfile(struct mapi_context *mapi_ctx, struct mapi_profile *profile, const char *profname, const char *password) { TALLOC_CTX *mem_ctx; enum MAPISTATUS retval; OPENCHANGE_RETVAL_IF(!mapi_ctx, MAPI_E_NOT_INITIALIZED, NULL); OPENCHANGE_RETVAL_IF(!mapi_ctx->ldb_ctx, MAPI_E_NOT_INITIALIZED, NULL); mem_ctx = (TALLOC_CTX *) mapi_ctx; /* find the profile in ldb store */ retval = ldb_load_profile(mem_ctx, mapi_ctx->ldb_ctx, profile, profname, password); OPENCHANGE_RETVAL_IF(retval, retval, NULL); profile->mapi_ctx = mapi_ctx; return MAPI_E_SUCCESS; } /** \details Load a MAPI Profile and sets its credentials This function loads a named MAPI profile and sets the MAPI session credentials. \param mapi_ctx pointer to the MAPI context \param profile pointer to the MAPI profile \return MAPI_E_SUCCESS on success, otherwise MAPI error. \note Developers may also call GetLastError() to retrieve the last MAPI error code. Possible MAPI error codes are: - MAPI_E_NOT_INITIALIZED: MAPI subsystem has not been initialized - MAPI_E_INVALID_PARAMETER: The profile parameter is not initialized - MAPI_E_NOT_ENOUGH_RESOURCES: MAPI subsystem failed to allocate the necessary resources to perform the operation \sa OpenProfile, GetLastError */ _PUBLIC_ enum MAPISTATUS LoadProfile(struct mapi_context *mapi_ctx, struct mapi_profile *profile) { enum credentials_use_kerberos use_krb = CRED_AUTO_USE_KERBEROS; /* Sanity checks */ OPENCHANGE_RETVAL_IF(!mapi_ctx, MAPI_E_NOT_INITIALIZED, NULL); OPENCHANGE_RETVAL_IF(!mapi_ctx->session, MAPI_E_NOT_INITIALIZED, NULL); OPENCHANGE_RETVAL_IF(!profile, MAPI_E_INVALID_PARAMETER, NULL); profile->credentials = cli_credentials_init(profile); OPENCHANGE_RETVAL_IF(!profile->credentials, MAPI_E_NOT_ENOUGH_RESOURCES, NULL); cli_credentials_guess(profile->credentials, mapi_ctx->lp_ctx); if (profile->workstation && *(profile->workstation)) { cli_credentials_set_workstation(profile->credentials, profile->workstation, CRED_SPECIFIED); } if (profile->realm && *(profile->realm)) { cli_credentials_set_realm(profile->credentials, profile->realm, CRED_SPECIFIED); } if (profile->domain && *(profile->domain)) { cli_credentials_set_domain(profile->credentials, profile->domain, CRED_SPECIFIED); } /* we keep the krb value literal as on/off and set the appropriate * flags at profile load time, to avoid embedding the bits of * another API in the profile */ if (profile->kerberos) { if (!strncmp(profile->kerberos, "yes", 3)) { use_krb = CRED_MUST_USE_KERBEROS; } else { use_krb = CRED_DONT_USE_KERBEROS; } } /* additionally, don't set the username in the ccache if kerberos * is forced, it causes the samba API to ignore existing kerberos * credentials. cli_credentials_guess probably gets the right * thing anyway in the situations where kerberos is in use */ if (profile->username && *(profile->username) && use_krb != CRED_MUST_USE_KERBEROS) { cli_credentials_set_username(profile->credentials, profile->username, CRED_SPECIFIED); } if (profile->password && *(profile->password)) { cli_credentials_set_password(profile->credentials, profile->password, CRED_SPECIFIED); } if (use_krb != CRED_AUTO_USE_KERBEROS) { cli_credentials_set_kerberos_state(profile->credentials, use_krb); } return MAPI_E_SUCCESS; } /** \details Release a profile This function releases the credentials associated with the profile. \param profile the profile to release. \return MAPI_E_SUCCESS on success, otherwise MAPI error. \note Developers may also call GetLastError() to retrieve the last MAPI error code. Possible MAPI error codes are: - MAPI_E_INVALID_PARAMETER: The profile parameter was not set or not valid */ _PUBLIC_ enum MAPISTATUS ShutDown(struct mapi_profile *profile) { OPENCHANGE_RETVAL_IF(!profile, MAPI_E_INVALID_PARAMETER, NULL); if (profile->credentials) talloc_free(profile->credentials); return MAPI_E_SUCCESS; } /** \details Create a profile in the MAPI profile database This function creates a profile named \a profile in the MAPI profile database and sets the specified username in that profile. This function may also set the password. If the flags include OC_PROFILE_NOPASSWORD then the password will not be set. Otherwise, the specified password argument will also be saved to the profile. \param mapi_ctx pointer to the MAPI context \param profile the name of the profile \param username the username of the profile \param password the password for the profile (if used) \param flag the union of the flags. \return MAPI_E_SUCCESS on success, otherwise MAPI error. \note Developers may also call GetLastError() to retrieve the last MAPI error code. Possible MAPI error codes are: - MAPI_E_NOT_INITIALIZED: MAPI subsystem has not been initialized. The MAPI subsystem must be initialized (using MAPIInitialize) prior to creating a profile. - MAPI_E_NOT_ENOUGH_RESOURCES: MAPI subsystem failed to allocate the necessary resources to operate properly - MAPI_E_NO_SUPPORT: An error was encountered while setting the MAPI profile attributes in the database. \note profile information (including the password, if saved to the profile) is stored unencrypted. \sa DeleteProfile, SetDefaultProfile, GetDefaultProfile, ChangeProfilePassword, GetProfileTable, ProcessNetworkProfile, GetLastError */ _PUBLIC_ enum MAPISTATUS CreateProfile(struct mapi_context *mapi_ctx, const char *profile, const char *username, const char *password, uint32_t flag) { enum MAPISTATUS retval; TALLOC_CTX *mem_ctx; OPENCHANGE_RETVAL_IF(!mapi_ctx, MAPI_E_NOT_INITIALIZED, NULL); OPENCHANGE_RETVAL_IF(!mapi_ctx->ldb_ctx, MAPI_E_NOT_INITIALIZED, NULL); mem_ctx = talloc_named(mapi_ctx->mem_ctx, 0, "CreateProfile"); retval = ldb_create_profile(mem_ctx, mapi_ctx->ldb_ctx, profile); OPENCHANGE_RETVAL_IF(retval, retval, mem_ctx); retval = mapi_profile_add_string_attr(mapi_ctx, profile, "username", username); if (flag != OC_PROFILE_NOPASSWORD) { retval = mapi_profile_add_string_attr(mapi_ctx, profile, "password", password); } talloc_free(mem_ctx); return retval; } /** \details Delete a profile from the MAPI profile database \param mapi_ctx pointer to the MAPI context \param profile the name of the profile to delete \return MAPI_E_SUCCESS on success, otherwise MAPI error. \note Developers may also call GetLastError() to retrieve the last MAPI error code. Possible MAPI error codes are: - MAPI_E_NOT_INITIALIZED: MAPI subsystem has not been initialized. The MAPI subsystem must be initialized (using MAPIInitialize) prior to creating a profile. - MAPI_E_NOT_FOUND: The profile was not found in the database. \sa CreateProfile, ChangeProfilePassword, GetProfileTable, GetProfileAttr, ProcessNetworkProfile, GetLastError */ _PUBLIC_ enum MAPISTATUS DeleteProfile(struct mapi_context *mapi_ctx, const char *profile) { TALLOC_CTX *mem_ctx; enum MAPISTATUS retval; /* Sanity checks */ OPENCHANGE_RETVAL_IF(!mapi_ctx, MAPI_E_NOT_INITIALIZED, NULL); OPENCHANGE_RETVAL_IF(!mapi_ctx->ldb_ctx, MAPI_E_NOT_INITIALIZED, NULL); mem_ctx = talloc_named(mapi_ctx->mem_ctx, 0, "DeleteProfile"); retval = ldb_delete_profile(mem_ctx, mapi_ctx->ldb_ctx, profile); OPENCHANGE_RETVAL_IF(retval, retval, mem_ctx); talloc_free(mem_ctx); return retval; } /** \details Change the profile password of an existing MAPI profile \param mapi_ctx pointer to the MAPI context \param profile the name of the profile to have its password changed \param old_password the old password \param password the new password \return MAPI_E_SUCCESS on success, otherwise MAPI error. \note Developers may also call GetLastError() to retrieve the last MAPI error code. Possible MAPI error codes are: - MAPI_E_INVALID_PARAMETER: One of the following argument was not set: profile, old_password, password - MAPI_E_NOT_FOUND: The profile was not found in the database \sa CreateProfile, GetProfileTable, GetProfileAttr, ProcessNetworkProfile, GetLastError */ _PUBLIC_ enum MAPISTATUS ChangeProfilePassword(struct mapi_context *mapi_ctx, const char *profile, const char *old_password, const char *password) { TALLOC_CTX *mem_ctx; enum MAPISTATUS retval; /* Sanity checks */ OPENCHANGE_RETVAL_IF(!mapi_ctx, MAPI_E_NOT_INITIALIZED, NULL); OPENCHANGE_RETVAL_IF(!profile || !old_password || !password, MAPI_E_INVALID_PARAMETER, NULL); mem_ctx = talloc_named(mapi_ctx->mem_ctx, 0, "ChangeProfilePassword"); retval = ldb_test_password(mapi_ctx, mem_ctx, profile, password); OPENCHANGE_RETVAL_IF(retval, retval, mem_ctx); retval = mapi_profile_modify_string_attr(mapi_ctx, profile, "password", password); talloc_free(mem_ctx); return retval; } /** \details Copy a profile \param mapi_ctx pointer to the MAPI context \param profile_src the source profile to copy from \param profile_dst the destination profile to copy to \return MAPI_E_SUCCESS on success, otherwise MAPI error. */ _PUBLIC_ enum MAPISTATUS CopyProfile(struct mapi_context *mapi_ctx, const char *profile_src, const char *profile_dst) { TALLOC_CTX *mem_ctx; enum MAPISTATUS retval; /* Sanity checks */ OPENCHANGE_RETVAL_IF(!mapi_ctx, MAPI_E_NOT_INITIALIZED, NULL); OPENCHANGE_RETVAL_IF(!mapi_ctx->ldb_ctx, MAPI_E_NOT_INITIALIZED, NULL); OPENCHANGE_RETVAL_IF(!profile_src, MAPI_E_INVALID_PARAMETER, NULL); OPENCHANGE_RETVAL_IF(!profile_dst, MAPI_E_INVALID_PARAMETER, NULL); mem_ctx = talloc_named(mapi_ctx->mem_ctx, 0, "CopyProfile"); retval = ldb_copy_profile(mem_ctx, mapi_ctx->ldb_ctx, profile_src, profile_dst); OPENCHANGE_RETVAL_IF(retval, retval, mem_ctx); talloc_free(mem_ctx); return retval; } static bool set_profile_attribute(struct mapi_context *mapi_ctx, const char *profname, struct PropertyRowSet_r rowset, uint32_t index, uint32_t property, const char *attr); /** \details Duplicate an existing profile. The username specified in parameter is used to customize the new profile. This function should only be used in environments where users are within the same administrative group, storage group, server etc. Otherwise this will create an invalid profile and may cause unpredictable results. \param mapi_ctx pointer to the MAPI context \param profile_src the source profile to duplicate from \param profile_dst the destination profile to duplicate to \param username the username to replace within the destination profile \return MAPI_E_SUCCESS on success, otherwise MAPI error */ _PUBLIC_ enum MAPISTATUS DuplicateProfile(struct mapi_context *mapi_ctx, const char *profile_src, const char *profile_dst, const char *username) { TALLOC_CTX *mem_ctx; enum MAPISTATUS retval; char *username_src = NULL; char *ProxyAddress = NULL; char *oldEmailAddress = NULL; struct mapi_profile *profile; char **attr_tmp = NULL; char *tmp = NULL; char *attr; uint32_t count = 0; /* Sanity checks */ OPENCHANGE_RETVAL_IF(!mapi_ctx, MAPI_E_NOT_INITIALIZED, NULL); OPENCHANGE_RETVAL_IF(!profile_src, MAPI_E_INVALID_PARAMETER, NULL); OPENCHANGE_RETVAL_IF(!profile_dst, MAPI_E_INVALID_PARAMETER, NULL); OPENCHANGE_RETVAL_IF(!username, MAPI_E_INVALID_PARAMETER, NULL); mem_ctx = talloc_named(mapi_ctx->mem_ctx, 0, "DuplicateProfile"); profile = talloc(mem_ctx, struct mapi_profile); /* Step 1. Copy the profile */ retval = CopyProfile(mapi_ctx, profile_src, profile_dst); OPENCHANGE_RETVAL_IF(retval, retval, NULL); /* retrieve username, EmailAddress and ProxyAddress */ retval = OpenProfile(mapi_ctx, profile, profile_src, NULL); OPENCHANGE_RETVAL_IF(retval, MAPI_E_NOT_FOUND, NULL); retval = GetProfileAttr(profile, "username", &count, &attr_tmp); OPENCHANGE_RETVAL_IF(retval || !count, MAPI_E_NOT_FOUND, mem_ctx); username_src = talloc_strdup(mem_ctx, attr_tmp[0]); talloc_free(attr_tmp[0]); retval = GetProfileAttr(profile, "EmailAddress", &count, &attr_tmp); OPENCHANGE_RETVAL_IF(retval, MAPI_E_NOT_FOUND, mem_ctx); oldEmailAddress = talloc_strdup(mem_ctx, attr_tmp[0]); talloc_free(attr_tmp[0]); retval = GetProfileAttr(profile, "ProxyAddress", &count, &attr_tmp); OPENCHANGE_RETVAL_IF(retval, MAPI_E_NOT_FOUND, mem_ctx); ProxyAddress = talloc_strdup(mem_ctx, attr_tmp[0]); talloc_free(attr_tmp[0]); /* Change EmailAddress */ { enum MAPISTATUS retval; struct nspi_context *nspi; struct SPropTagArray *SPropTagArray = NULL; struct PropertyRowSet_r *PropertyRowSet; struct Restriction_r Filter; struct PropertyValue_r *lpProp = NULL; struct PropertyTagArray_r *MIds = NULL; uint32_t index = 0; char *password; struct mapi_session *session = NULL; retval = GetProfileAttr(profile, "password", &count, &attr_tmp); OPENCHANGE_RETVAL_IF(retval || !count, MAPI_E_NOT_FOUND, mem_ctx); password = talloc_strdup(mem_ctx, attr_tmp[0]); talloc_free(attr_tmp[0]); retval = MapiLogonProvider(mapi_ctx, &session, profile_dst, password, PROVIDER_ID_NSPI); if (retval != MAPI_E_SUCCESS) { mapi_errstr("DuplicateProfile", GetLastError()); return retval; } mapi_ctx = session->mapi_ctx; OPENCHANGE_RETVAL_IF(!session, MAPI_E_NOT_INITIALIZED, NULL); OPENCHANGE_RETVAL_IF(!session->nspi->ctx, MAPI_E_END_OF_SESSION, NULL); OPENCHANGE_RETVAL_IF(!session->mapi_ctx, MAPI_E_NOT_INITIALIZED, NULL); mem_ctx = talloc_named(NULL, 0, "ProcessNetworkProfile"); nspi = (struct nspi_context *) session->nspi->ctx; index = 0; PropertyRowSet = talloc_zero(mem_ctx, struct PropertyRowSet_r); retval = nspi_GetSpecialTable(nspi, mem_ctx, 0x0, &PropertyRowSet); MAPIFreeBuffer(PropertyRowSet); OPENCHANGE_RETVAL_IF(retval, retval, mem_ctx); SPropTagArray = set_SPropTagArray(mem_ctx, 0x1, PR_EMAIL_ADDRESS ); /* Build the restriction we want for NspiGetMatches */ lpProp = talloc_zero(mem_ctx, struct PropertyValue_r); lpProp->ulPropTag = PR_ANR_UNICODE; lpProp->dwAlignPad = 0; lpProp->value.lpszW = username; Filter.rt = (enum RestrictionType_r)RES_PROPERTY; Filter.res.resProperty.relop = RES_PROPERTY; Filter.res.resProperty.ulPropTag = PR_ANR_UNICODE; Filter.res.resProperty.lpProp = lpProp; PropertyRowSet = talloc_zero(mem_ctx, struct PropertyRowSet_r); MIds = talloc_zero(mem_ctx, struct PropertyTagArray_r); retval = nspi_GetMatches(nspi, mem_ctx, SPropTagArray, &Filter, 5000, &PropertyRowSet, &MIds); MAPIFreeBuffer(SPropTagArray); MAPIFreeBuffer(lpProp); if (retval != MAPI_E_SUCCESS) { MAPIFreeBuffer(MIds); MAPIFreeBuffer(PropertyRowSet); talloc_free(mem_ctx); return retval; } /* if there's no match */ OPENCHANGE_RETVAL_IF(!PropertyRowSet, MAPI_E_NOT_FOUND, mem_ctx); OPENCHANGE_RETVAL_IF(!PropertyRowSet->cRows, MAPI_E_NOT_FOUND, mem_ctx); OPENCHANGE_RETVAL_IF(!MIds, MAPI_E_NOT_FOUND, mem_ctx); MAPIFreeBuffer(MIds); set_profile_attribute(mapi_ctx, profile_dst, *PropertyRowSet, index, PR_EMAIL_ADDRESS, "EmailAddress"); mapi_profile_delete_string_attr(mapi_ctx, profile_dst, "EmailAddress", oldEmailAddress); MAPIFreeBuffer(PropertyRowSet); DLIST_REMOVE(mapi_ctx->session, session); MAPIFreeBuffer(session); } /* Change ProxyAddress */ { tmp = strstr(ProxyAddress, username_src); attr = talloc_strndup(mem_ctx, ProxyAddress, strlen(ProxyAddress) - strlen(tmp)); tmp += strlen(username_src); attr = talloc_asprintf_append(attr, "%s%s", username, tmp); mapi_profile_modify_string_attr(mapi_ctx, profile_dst, "ProxyAddress", attr); talloc_free(attr); } /* Step 2. Change parameters but cn (already changed) */ mapi_profile_modify_string_attr(mapi_ctx, profile_dst, "name", profile_dst); mapi_profile_modify_string_attr(mapi_ctx, profile_dst, "username", username); mapi_profile_modify_string_attr(mapi_ctx, profile_dst, "DisplayName", username); mapi_profile_modify_string_attr(mapi_ctx, profile_dst, "Account", username); talloc_free(profile); talloc_free(mem_ctx); return MAPI_E_SUCCESS; } /** \details Rename a profile \param mapi_ctx pointer to the MAPI context \param old_profile old profile name \param profile new profile name \return MAPI_E_SUCCESS on success, otherwise MAPI error. */ _PUBLIC_ enum MAPISTATUS RenameProfile(struct mapi_context *mapi_ctx, const char *old_profile, const char *profile) { TALLOC_CTX *mem_ctx; enum MAPISTATUS retval; struct SRowSet proftable; struct SPropValue *lpProp; struct ldb_message *msg = NULL; bool found = false; char *dn = NULL; int ret; uint32_t i; /* Sanity checks */ OPENCHANGE_RETVAL_IF(!mapi_ctx, MAPI_E_NOT_INITIALIZED, NULL); OPENCHANGE_RETVAL_IF(!old_profile, MAPI_E_INVALID_PARAMETER, NULL); OPENCHANGE_RETVAL_IF(!profile, MAPI_E_INVALID_PARAMETER, NULL); mem_ctx = mapi_ctx->mem_ctx; retval = GetProfileTable(mapi_ctx, &proftable); OPENCHANGE_RETVAL_IF(retval, retval, NULL); /* Step 1. Check if old profile exists */ for (found = false, i = 0; i < proftable.cRows; i++) { lpProp = get_SPropValue_SRow(&(proftable.aRow[i]), PR_DISPLAY_NAME); if (lpProp && !strcmp(lpProp->value.lpszA, old_profile)) { found = true; } } OPENCHANGE_RETVAL_IF(found == false, MAPI_E_NOT_FOUND, proftable.aRow); /* Step 2. Check if new profile already exists */ for (found = false, i = 0; i < proftable.cRows; i++) { lpProp = get_SPropValue_SRow(&(proftable.aRow[i]), PR_DISPLAY_NAME); if (lpProp && !strcmp(lpProp->value.lpszA, profile)) { found = true; } } talloc_free(proftable.aRow); OPENCHANGE_RETVAL_IF(found == true, MAPI_E_INVALID_PARAMETER, NULL); /* Step 3. Rename the profile */ retval = ldb_rename_profile(mapi_ctx, mem_ctx, old_profile, profile); OPENCHANGE_RETVAL_IF(retval, retval, NULL); /* Step 4. Change name and cn */ msg = ldb_msg_new(mem_ctx); dn = talloc_asprintf(mem_ctx, "CN=%s,CN=Profiles", profile); msg->dn = ldb_dn_new(mem_ctx, mapi_ctx->ldb_ctx, dn); talloc_free(dn); ret = ldb_msg_add_string(msg, "cn", profile); ret = ldb_msg_add_string(msg, "name", profile); for (i = 0; i < msg->num_elements; i++) { msg->elements[i].flags = LDB_FLAG_MOD_REPLACE; } OPENCHANGE_RETVAL_IF(ret != LDB_SUCCESS, MAPI_E_CORRUPT_STORE, NULL); ret = ldb_modify(mapi_ctx->ldb_ctx, msg); OPENCHANGE_RETVAL_IF(ret != LDB_SUCCESS, MAPI_E_CORRUPT_STORE, NULL); return MAPI_E_SUCCESS; } /** \details Set a default profile for the database \param mapi_ctx pointer to the MAPI context \param profname the name of the profile to make the default profile \return MAPI_E_SUCCESS on success, otherwise MAPI error. \note Developers may also call GetLastError() to retrieve the last MAPI error code. Possible MAPI error codes are: - MAPI_E_NOT_INITIALIZED: MAPI subsystem has not been initialized - MAPI_E_INVALID_PARAMETER: The profile parameter was not set properly. - MAPI_E_NOT_FOUND: The profile was not found in the database \sa GetDefaultProfile, GetProfileTable, GetLastError */ _PUBLIC_ enum MAPISTATUS SetDefaultProfile(struct mapi_context *mapi_ctx, const char *profname) { TALLOC_CTX *mem_ctx; struct mapi_profile *profile; enum MAPISTATUS retval; /* Sanity checks */ OPENCHANGE_RETVAL_IF(!mapi_ctx, MAPI_E_NOT_INITIALIZED, NULL); OPENCHANGE_RETVAL_IF(!mapi_ctx->ldb_ctx, MAPI_E_NOT_INITIALIZED, NULL); OPENCHANGE_RETVAL_IF(!profname, MAPI_E_INVALID_PARAMETER, NULL); mem_ctx = talloc_named(mapi_ctx->mem_ctx, 0, "SetDefaultProfile"); /* open profile */ profile = talloc_zero(mem_ctx, struct mapi_profile); retval = ldb_load_profile(mem_ctx, mapi_ctx->ldb_ctx, profile, profname, NULL); OPENCHANGE_RETVAL_IF(retval && retval != MAPI_E_INVALID_PARAMETER, retval, mem_ctx); /* search any previous default profile and unset it */ retval = ldb_clear_default_profile(mapi_ctx, mem_ctx); /* set profname as the default profile */ retval = mapi_profile_modify_string_attr(mapi_ctx, profname, "PR_DEFAULT_PROFILE", "1"); talloc_free(mem_ctx); return retval; } /** \details Get the default profile from the database \param mapi_ctx pointer to the MAPI context \param profname the result of the function (name of the default profile) \return MAPI_E_SUCCESS on success, otherwise MAPI error. \note Developers may also call GetLastError() to retrieve the last MAPI error code. Possible MAPI error codes are: - MAPI_E_NOT_INITIALIZED: MAPI subsystem has not been initialized - MAPI_E_NOT_FOUND: The profile was not found in the database \note On success GetDefaultProfile profname string is allocated. It is up to the developer to free it when not needed anymore. \sa SetDefaultProfile, GetProfileTable, GetLastError */ _PUBLIC_ enum MAPISTATUS GetDefaultProfile(struct mapi_context *mapi_ctx, char **profname) { enum MAPISTATUS retval; struct SRowSet proftable; struct SPropValue *lpProp; uint32_t i; OPENCHANGE_RETVAL_IF(!mapi_ctx, MAPI_E_NOT_INITIALIZED, NULL); retval = GetProfileTable(mapi_ctx, &proftable); OPENCHANGE_RETVAL_IF(retval, retval, NULL); for (i = 0; i < proftable.cRows; i++) { lpProp = get_SPropValue_SRow(&(proftable.aRow[i]), PR_DEFAULT_PROFILE); if (lpProp && (lpProp->value.l == 1)) { lpProp = get_SPropValue_SRow(&(proftable.aRow[i]), PR_DISPLAY_NAME); if (lpProp) { *profname = talloc_strdup(mapi_ctx->mem_ctx, lpProp->value.lpszA); talloc_free(proftable.aRow); return MAPI_E_SUCCESS; } } } OPENCHANGE_RETVAL_ERR(MAPI_E_NOT_FOUND, proftable.aRow); } /** \details Retrieve the profile table This function retrieves the profile table. Two fields are returned: - PR_DISPLAY_NAME: The profile name stored as a UTF8 string - PR_DEFAULT_PROFILE: Whether the profile is the default one(1) or not(0), stored as an integer \param mapi_ctx pointer to the MAPI context \param proftable the result of the call \return MAPI_E_SUCCESS on success, otherwise MAPI error. \note Developers may also call GetLastError() to retrieve the last MAPI error code. Possible MAPI error codes are: - MAPI_E_NOT_INITIALIZED: MAPI subsystem has not been initialized - MAPI_E_NOT_FOUND: The profile was not found in the database \sa SetDefaultProfile, GetLastError */ _PUBLIC_ enum MAPISTATUS GetProfileTable(struct mapi_context *mapi_ctx, struct SRowSet *proftable) { TALLOC_CTX *mem_ctx; enum ldb_scope scope = LDB_SCOPE_SUBTREE; struct ldb_context *ldb_ctx; struct ldb_result *res; struct ldb_message *msg; struct ldb_dn *basedn; const char *attrs[] = {"cn", "PR_DEFAULT_PROFILE", NULL}; int ret; uint32_t count; OPENCHANGE_RETVAL_IF(!mapi_ctx, MAPI_E_NOT_INITIALIZED, NULL); ldb_ctx = mapi_ctx->ldb_ctx; mem_ctx = mapi_ctx->mem_ctx; basedn = ldb_dn_new(ldb_ctx, ldb_ctx, "CN=Profiles"); ret = ldb_search(ldb_ctx, mem_ctx, &res, basedn, scope, attrs, "(cn=*)"); talloc_free(basedn); OPENCHANGE_RETVAL_IF(ret != LDB_SUCCESS, MAPI_E_NOT_FOUND, NULL); /* Allocate Arow */ proftable->cRows = res->count; proftable->aRow = talloc_array(mapi_ctx->mem_ctx, struct SRow, res->count); /* Build Arow array */ for (count = 0; count < res->count; count++) { msg = res->msgs[count]; proftable->aRow[count].lpProps = talloc_array((TALLOC_CTX *)proftable->aRow, struct SPropValue, 2); proftable->aRow[count].cValues = 2; proftable->aRow[count].lpProps[0].ulPropTag = PR_DISPLAY_NAME; proftable->aRow[count].lpProps[0].value.lpszA = talloc_strdup((TALLOC_CTX *)proftable->aRow, ldb_msg_find_attr_as_string(msg, "cn", NULL)); proftable->aRow[count].lpProps[1].ulPropTag = PR_DEFAULT_PROFILE; proftable->aRow[count].lpProps[1].value.l = ldb_msg_find_attr_as_int(msg, "PR_DEFAULT_PROFILE", 0); } talloc_free(res); return MAPI_E_SUCCESS; } /** \details Retrieve attribute values from a profile This function retrieves all the attribute values from the given profile. The number of results is stored in \a count and values are stored in an allocated string array in the \a value parameter that needs to be free'd using MAPIFreeBuffer(). \param profile the name of the profile to retrieve attributes from \param attribute the attribute(s) to search for \param count the number of results \param value the resulting values \return MAPI_E_SUCCESS on success, otherwise MAPI error. \note Developers may also call GetLastError() to retrieve the last MAPI error code. Possible MAPI error codes are: - MAPI_E_NOT_INITIALIZED: MAPI subsystem has not been initialized - MAPI_E_INVALID_PARAMETER: Either profile or attribute was not set properly - MAPI_E_NOT_FOUND: The profile was not found in the database \sa SetDefaultProfile, GetDefaultProfile, MAPIFreeBuffer, GetProfileTable, GetLastError */ _PUBLIC_ enum MAPISTATUS GetProfileAttr(struct mapi_profile *profile, const char *attribute, unsigned int *count, char ***value) { TALLOC_CTX *mem_ctx; struct mapi_context *mapi_ctx; struct ldb_context *ldb_ctx; struct ldb_result *res; struct ldb_message *msg; struct ldb_message_element *ldb_element; struct ldb_dn *basedn; const char *attrs[] = {"*", NULL}; int ret; uint32_t i; /* Sanity checks */ OPENCHANGE_RETVAL_IF(!profile, MAPI_E_INVALID_PARAMETER, NULL); OPENCHANGE_RETVAL_IF(!attribute, MAPI_E_INVALID_PARAMETER, NULL); mapi_ctx = profile->mapi_ctx; OPENCHANGE_RETVAL_IF(!mapi_ctx, MAPI_E_NOT_INITIALIZED, NULL); OPENCHANGE_RETVAL_IF(!mapi_ctx->ldb_ctx, MAPI_E_NOT_INITIALIZED, NULL); mem_ctx = (TALLOC_CTX *)mapi_ctx->ldb_ctx; ldb_ctx = mapi_ctx->ldb_ctx; basedn = ldb_dn_new(ldb_ctx, ldb_ctx, "CN=Profiles"); ret = ldb_search(ldb_ctx, mem_ctx, &res, basedn, LDB_SCOPE_SUBTREE, attrs, "(cn=%s)", profile->profname); OPENCHANGE_RETVAL_IF(ret != LDB_SUCCESS, MAPI_E_NOT_FOUND, NULL); msg = res->msgs[0]; ldb_element = ldb_msg_find_element(msg, attribute); if (!ldb_element) { DEBUG(3, ("ldb_msg_find_element: NULL\n")); return MAPI_E_NOT_FOUND; } *count = ldb_element[0].num_values; value[0] = talloc_array(mem_ctx, char *, *count); if (*count == 1) { value[0][0] = talloc_strdup(value[0], ldb_msg_find_attr_as_string(msg, attribute, NULL)); } else { for (i = 0; i < *count; i++) { value[0][i] = talloc_strdup(mem_ctx, (char *)ldb_element->values[i].data); } } return MAPI_E_SUCCESS; } /** \details Search the value of an attribute within a given profile \param profile pointer to the MAPI profile \param attribute pointer to the attribute name \param value pointer to the attribute value \return MAPI_E_SUCCESS on success, otherwise MAPI error */ _PUBLIC_ enum MAPISTATUS FindProfileAttr(struct mapi_profile *profile, const char *attribute, const char *value) { TALLOC_CTX *mem_ctx; struct mapi_context *mapi_ctx; struct ldb_context *ldb_ctx; struct ldb_result *res; struct ldb_message *msg; struct ldb_message_element *ldb_element; struct ldb_val val; struct ldb_dn *basedn; const char *attrs[] = {"*", NULL}; int ret; OPENCHANGE_RETVAL_IF(!profile, MAPI_E_INVALID_PARAMETER, NULL); OPENCHANGE_RETVAL_IF(!attribute, MAPI_E_INVALID_PARAMETER, NULL); OPENCHANGE_RETVAL_IF(!value, MAPI_E_INVALID_PARAMETER, NULL); mapi_ctx = profile->mapi_ctx; OPENCHANGE_RETVAL_IF(!mapi_ctx, MAPI_E_NOT_INITIALIZED, NULL); OPENCHANGE_RETVAL_IF(!mapi_ctx->ldb_ctx, MAPI_E_NOT_INITIALIZED, NULL); mem_ctx = (TALLOC_CTX *)mapi_ctx->ldb_ctx; ldb_ctx = mapi_ctx->ldb_ctx; basedn = ldb_dn_new(ldb_ctx, ldb_ctx, "CN=Profiles"); ret = ldb_search(ldb_ctx, mem_ctx, &res, basedn, LDB_SCOPE_SUBTREE, attrs, "(CN=%s)", profile->profname); OPENCHANGE_RETVAL_IF(ret != LDB_SUCCESS, MAPI_E_NOT_FOUND, res); OPENCHANGE_RETVAL_IF(!res->count, MAPI_E_NOT_FOUND, res); msg = res->msgs[0]; ldb_element = ldb_msg_find_element(msg, attribute); OPENCHANGE_RETVAL_IF(!ldb_element, MAPI_E_NOT_FOUND, res); val.data = (uint8_t *)talloc_strdup(mem_ctx, value); val.length = strlen(value); OPENCHANGE_RETVAL_IF(!ldb_msg_find_val(ldb_element, &val), MAPI_E_NOT_FOUND, res); talloc_free(res); return MAPI_E_SUCCESS; } /** Create the profile */ static bool set_profile_attribute(struct mapi_context *mapi_ctx, const char *profname, struct PropertyRowSet_r rowset, uint32_t index, uint32_t property, const char *attr) { struct PropertyValue_r *lpProp; enum MAPISTATUS ret; lpProp = get_PropertyValue_PropertyRow(&(rowset.aRow[index]), property); if (!lpProp) { DEBUG(3, ("MAPI Property %s not set\n", attr)); return true; } ret = mapi_profile_add_string_attr(mapi_ctx, profname, attr, lpProp->value.lpszA); if (ret != MAPI_E_SUCCESS) { DEBUG(3, ("Problem adding attribute %s in profile %s\n", attr, profname)); return false; } return true; } static bool set_profile_mvstr_attribute(struct mapi_context *mapi_ctx, const char *profname, struct PropertyRowSet_r rowset, uint32_t index, uint32_t property, const char *attr) { struct PropertyValue_r *lpProp; enum MAPISTATUS ret; uint32_t i; lpProp = get_PropertyValue_PropertyRow(&(rowset.aRow[index]), property); if (!lpProp) { DEBUG(3, ("MAPI Property %s not set\n", attr)); return true; } for (i = 0; i < lpProp->value.MVszA.cValues; i++) { ret = mapi_profile_add_string_attr(mapi_ctx, profname, attr, lpProp->value.MVszA.lppszA[i]); if (ret != MAPI_E_SUCCESS) { DEBUG(3, ("Problem adding attribute %s in profile %s\n", attr, profname)); return false; } } return true; } /** \details Process a full and automated MAPI profile creation This function process a full and automated MAPI profile creation using the \a username pattern passed as a parameter. The functions takes a callback parameter which will be called when the username checked matches several usernames. Private data needed by the callback can be supplied using the private_data pointer. \code typedef int (*mapi_callback_t) callback(struct SRowSet *, void *private_data); \endcode The callback returns the SRow element index within the SRowSet structure. If the user cancels the operation the callback return value should be SRowSet->cRows or more. \param session the session context \param username the username for the network profile \param callback function pointer callback function \param private_data context data that will be provided to the callback \return MAPI_E_SUCCESS on success, otherwise MAPI error. \note Developers may also call GetLastError() to retrieve the last MAPI error code. Possible MAPI error codes are: - MAPI_E_NOT_INITIALIZED: MAPI subsystem has not been initialized. The MAPI subsystem must be initialized (using MAPIInitialize) prior to creating a profile. - MAPI_E_END_OF_SESSION: The NSPI session has not been initialized - MAPI_E_CANCEL_USER: The user has aborted the operation - MAPI_E_INVALID_PARAMETER: The profile parameter was not set properly. - MAPI_E_NOT_FOUND: One of the mandatory field was not found during the profile creation process. \sa OpenProfileStore, MAPILogonProvider, GetLastError */ _PUBLIC_ enum MAPISTATUS ProcessNetworkProfile(struct mapi_session *session, const char *username, mapi_profile_callback_t callback, const void *private_data) { TALLOC_CTX *mem_ctx; enum MAPISTATUS retval; struct mapi_context *mapi_ctx; struct nspi_context *nspi; struct SPropTagArray *SPropTagArray = NULL; struct Restriction_r Filter; struct PropertyRowSet_r *PropertyRowSet; struct PropertyValue_r *lpProp = NULL; struct PropertyTagArray_r *MIds = NULL; struct PropertyTagArray_r MIds2; struct PropertyTagArray_r *MId_server = NULL; struct StringsArray_r pNames; const char *profname; uint32_t instance_key = 0; uint32_t index = 0; OPENCHANGE_RETVAL_IF(!session, MAPI_E_NOT_INITIALIZED, NULL); OPENCHANGE_RETVAL_IF(!session->nspi->ctx, MAPI_E_END_OF_SESSION, NULL); OPENCHANGE_RETVAL_IF(!session->mapi_ctx, MAPI_E_NOT_INITIALIZED, NULL); mapi_ctx = session->mapi_ctx; mem_ctx = talloc_named(session, 0, "ProcessNetworkProfile"); nspi = (struct nspi_context *) session->nspi->ctx; profname = session->profile->profname; index = 0; PropertyRowSet = talloc_zero(mem_ctx, struct PropertyRowSet_r); retval = nspi_GetSpecialTable(nspi, mem_ctx, 0x0, &PropertyRowSet); MAPIFreeBuffer(PropertyRowSet); OPENCHANGE_RETVAL_IF(retval, retval, mem_ctx); SPropTagArray = set_SPropTagArray(mem_ctx, 0xc, PR_DISPLAY_NAME, PR_OFFICE_TELEPHONE_NUMBER, PR_OFFICE_LOCATION, PR_TITLE, PR_COMPANY_NAME, PR_ACCOUNT, PR_ADDRTYPE, PR_ENTRYID, PR_OBJECT_TYPE, PR_DISPLAY_TYPE, PR_INSTANCE_KEY, PR_EMAIL_ADDRESS ); /* Retrieve the username to match */ if (!username) { username = cli_credentials_get_username(nspi->cred); OPENCHANGE_RETVAL_IF(!username, MAPI_E_INVALID_PARAMETER, mem_ctx); } /* Build the restriction we want for NspiGetMatches */ lpProp = talloc_zero(mem_ctx, struct PropertyValue_r); lpProp->ulPropTag = PR_ANR_UNICODE; lpProp->dwAlignPad = 0; lpProp->value.lpszW = username; Filter.rt = (enum RestrictionType_r)RES_PROPERTY; Filter.res.resProperty.relop = RES_PROPERTY; Filter.res.resProperty.ulPropTag = PR_ANR_UNICODE; Filter.res.resProperty.lpProp = lpProp; PropertyRowSet = talloc_zero(mem_ctx, struct PropertyRowSet_r); MIds = talloc_zero(mem_ctx, struct PropertyTagArray_r); retval = nspi_GetMatches(nspi, mem_ctx, SPropTagArray, &Filter, 5000, &PropertyRowSet, &MIds); MAPIFreeBuffer(SPropTagArray); MAPIFreeBuffer(lpProp); if (retval != MAPI_E_SUCCESS) { MAPIFreeBuffer(MIds); MAPIFreeBuffer(PropertyRowSet); talloc_free(mem_ctx); return retval; } /* if there's no match */ OPENCHANGE_RETVAL_IF(!PropertyRowSet, MAPI_E_NOT_FOUND, mem_ctx); OPENCHANGE_RETVAL_IF(!PropertyRowSet->cRows, MAPI_E_NOT_FOUND, mem_ctx); OPENCHANGE_RETVAL_IF(!MIds, MAPI_E_NOT_FOUND, mem_ctx); /* if PropertyRowSet count is superior than 1 an callback is specified, call it */ if (PropertyRowSet->cRows > 1 && callback) { index = callback(PropertyRowSet, private_data); OPENCHANGE_RETVAL_IF((index >= PropertyRowSet->cRows), MAPI_E_USER_CANCEL, mem_ctx); instance_key = MIds->aulPropTag[index]; } else { instance_key = MIds->aulPropTag[0]; } MAPIFreeBuffer(MIds); MIds2.cValues = 0x1; MIds2.aulPropTag = &instance_key; set_profile_attribute(mapi_ctx, profname, *PropertyRowSet, index, PR_EMAIL_ADDRESS, "EmailAddress"); set_profile_attribute(mapi_ctx, profname, *PropertyRowSet, index, PR_DISPLAY_NAME, "DisplayName"); set_profile_attribute(mapi_ctx, profname, *PropertyRowSet, index, PR_ACCOUNT, "Account"); set_profile_attribute(mapi_ctx, profname, *PropertyRowSet, index, PR_ADDRTYPE, "AddrType"); SPropTagArray = set_SPropTagArray(mem_ctx, 0x7, PR_DISPLAY_NAME, PR_EMAIL_ADDRESS, PR_DISPLAY_TYPE, PR_EMS_AB_HOME_MDB, PR_ATTACH_NUM, PR_PROFILE_HOME_SERVER_ADDRS, PR_EMS_AB_PROXY_ADDRESSES ); nspi->pStat->CurrentRec = 0x0; nspi->pStat->Delta = 0x0; nspi->pStat->NumPos = 0x0; nspi->pStat->TotalRecs = 0x1; MAPIFreeBuffer(PropertyRowSet); PropertyRowSet = talloc(mem_ctx, struct PropertyRowSet_r); retval = nspi_QueryRows(nspi, mem_ctx, SPropTagArray, &MIds2, 1, &PropertyRowSet); MAPIFreeBuffer(SPropTagArray); OPENCHANGE_RETVAL_IF(retval, retval, mem_ctx); lpProp = get_PropertyValue_PropertyRowSet(PropertyRowSet, PR_EMS_AB_HOME_MDB); OPENCHANGE_RETVAL_IF(!lpProp, MAPI_E_NOT_FOUND, mem_ctx); nspi->org = x500_get_dn_element(mem_ctx, lpProp->value.lpszA, ORG); nspi->org_unit = x500_get_dn_element(mem_ctx, lpProp->value.lpszA, ORG_UNIT); OPENCHANGE_RETVAL_IF(!nspi->org_unit, MAPI_E_INVALID_PARAMETER, mem_ctx); OPENCHANGE_RETVAL_IF(!nspi->org, MAPI_E_INVALID_PARAMETER, mem_ctx); retval = mapi_profile_add_string_attr(mapi_ctx, profname, "Organization", nspi->org); retval = mapi_profile_add_string_attr(mapi_ctx, profname, "OrganizationUnit", nspi->org_unit); nspi->servername = x500_get_servername(lpProp->value.lpszA); mapi_profile_add_string_attr(mapi_ctx, profname, "ServerName", nspi->servername); set_profile_attribute(mapi_ctx, profname, *PropertyRowSet, 0, PR_EMS_AB_HOME_MDB, "HomeMDB"); set_profile_mvstr_attribute(mapi_ctx, profname, *PropertyRowSet, 0, PR_EMS_AB_PROXY_ADDRESSES, "ProxyAddress"); pNames.Count = 0x1; pNames.Strings = (const char **) talloc_array(mem_ctx, char *, 1); pNames.Strings[0] = (const char *) talloc_asprintf(mem_ctx, SERVER_DN, nspi->org, nspi->org_unit, nspi->servername); MId_server = talloc_zero(mem_ctx, struct PropertyTagArray_r); retval = nspi_DNToMId(nspi, mem_ctx, &pNames, &MId_server); MAPIFreeBuffer((char *)pNames.Strings[0]); MAPIFreeBuffer((char **)pNames.Strings); OPENCHANGE_RETVAL_IF(retval, retval, mem_ctx); MAPIFreeBuffer(PropertyRowSet); PropertyRowSet = talloc_zero(mem_ctx, struct PropertyRowSet_r); SPropTagArray = set_SPropTagArray(mem_ctx, 0x1, PR_EMS_AB_NETWORK_ADDRESS); retval = nspi_GetProps(nspi, mem_ctx, SPropTagArray, MId_server, &PropertyRowSet); MAPIFreeBuffer(SPropTagArray); MAPIFreeBuffer(MId_server); OPENCHANGE_RETVAL_IF(retval, retval, mem_ctx); set_profile_mvstr_attribute(mapi_ctx, profname, *PropertyRowSet, 0, PR_EMS_AB_NETWORK_ADDRESS, "NetworkAddress"); MAPIFreeBuffer(PropertyRowSet); talloc_free(mem_ctx); return MAPI_E_SUCCESS; } openchange-2.0/libmapi/IStoreFolder.c000066400000000000000000000247471223057412600176240ustar00rootroot00000000000000/* OpenChange MAPI implementation. Copyright (C) Julien Kerihuel 2007-2011. This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see . */ #include "libmapi/libmapi.h" #include "libmapi/libmapi_private.h" /** \file IStoreFolder.c \brief Open messages */ /** \details Opens a specific message and retrieves a MAPI object that can be used to get or set message properties. This function opens a specific message defined by a combination of object store, folder ID, and message ID and which read/write access is defined by ulFlags. \param obj_store the store to read from \param id_folder the folder ID \param id_message the message ID \param obj_message the resulting message object \param ulFlags Possible ulFlags values: - 0x0: read only access - 0x1: ReadWrite - 0x3: Create - 0x4: OpenSoftDeleted \return MAPI_E_SUCCESS on success, otherwise MAPI error. \note Developers may also call GetLastError() to retrieve the last MAPI error code. Possible MAPI error codes are: - MAPI_E_NOT_INITIALIZED: MAPI subsystem has not been initialized - MAPI_E_INVALID_PARAMETER: obj_store is undefined - MAPI_E_CALL_FAILED: A network problem was encountered during the transaction \sa MAPIInitialize, GetLastError */ _PUBLIC_ enum MAPISTATUS OpenMessage(mapi_object_t *obj_store, mapi_id_t id_folder, mapi_id_t id_message, mapi_object_t *obj_message, uint8_t ulFlags) { struct mapi_context *mapi_ctx; struct mapi_request *mapi_request; struct mapi_response *mapi_response; struct EcDoRpc_MAPI_REQ *mapi_req; struct OpenMessage_req request; struct OpenMessage_repl *reply; struct mapi_session *session; mapi_object_message_t *message; struct SPropValue lpProp; const char *tstring; NTSTATUS status; enum MAPISTATUS retval; uint32_t size = 0; TALLOC_CTX *mem_ctx; uint32_t i = 0; uint8_t logon_id; /* Sanity checks */ OPENCHANGE_RETVAL_IF(!obj_store, MAPI_E_INVALID_PARAMETER, NULL); session = mapi_object_get_session(obj_store); OPENCHANGE_RETVAL_IF(!session, MAPI_E_INVALID_PARAMETER, NULL); mapi_ctx = session->mapi_ctx; OPENCHANGE_RETVAL_IF(!mapi_ctx, MAPI_E_NOT_INITIALIZED, NULL); if ((retval = mapi_object_get_logon_id(obj_store, &logon_id)) != MAPI_E_SUCCESS) return retval; mem_ctx = talloc_named(session, 0, "OpenMessage"); /* Fill the OpenMessage operation */ request.handle_idx = 0x1; request.CodePageId = 0xfff; request.FolderId = id_folder; request.OpenModeFlags = (enum OpenMessage_OpenModeFlags)ulFlags; request.MessageId = id_message; size = sizeof (uint8_t) + sizeof(uint16_t) + sizeof(mapi_id_t) + sizeof(uint8_t) + sizeof(mapi_id_t); /* Fill the MAPI_REQ request */ mapi_req = talloc_zero(mem_ctx, struct EcDoRpc_MAPI_REQ); mapi_req->opnum = op_MAPI_OpenMessage; mapi_req->logon_id = logon_id; mapi_req->handle_idx = 0; mapi_req->u.mapi_OpenMessage = request; size += 5; /* Fill the mapi_request structure */ mapi_request = talloc_zero(mem_ctx, struct mapi_request); mapi_request->mapi_len = size + sizeof (uint32_t) * 2; mapi_request->length = size; mapi_request->mapi_req = mapi_req; mapi_request->handles = talloc_array(mem_ctx, uint32_t, 2); mapi_request->handles[0] = mapi_object_get_handle(obj_store); mapi_request->handles[1] = 0xffffffff; status = emsmdb_transaction_wrapper(session, mem_ctx, mapi_request, &mapi_response); OPENCHANGE_RETVAL_IF(!NT_STATUS_IS_OK(status), MAPI_E_CALL_FAILED, mem_ctx); OPENCHANGE_RETVAL_IF(!mapi_response->mapi_repl, MAPI_E_CALL_FAILED, mem_ctx); retval = mapi_response->mapi_repl->error_code; OPENCHANGE_RETVAL_IF(retval, retval, mem_ctx); OPENCHANGE_CHECK_NOTIFICATION(session, mapi_response); /* Set object session and handle */ mapi_object_set_session(obj_message, session); mapi_object_set_handle(obj_message, mapi_response->handles[1]); mapi_object_set_logon_id(obj_message, logon_id); /* Store OpenMessage reply data */ reply = &mapi_response->mapi_repl->u.mapi_OpenMessage; message = talloc_zero((TALLOC_CTX *)session, mapi_object_message_t); tstring = get_TypedString(&reply->SubjectPrefix); if (tstring) { message->SubjectPrefix = talloc_strdup((TALLOC_CTX *)message, tstring); } tstring = get_TypedString(&reply->NormalizedSubject); if (tstring) { message->NormalizedSubject = talloc_strdup((TALLOC_CTX *)message, tstring); } message->cValues = reply->RecipientColumns.cValues; message->SRowSet.cRows = reply->RowCount; message->SRowSet.aRow = talloc_array((TALLOC_CTX *)message, struct SRow, reply->RowCount + 1); message->SPropTagArray.cValues = reply->RecipientColumns.cValues; message->SPropTagArray.aulPropTag = talloc_steal(message, reply->RecipientColumns.aulPropTag); for (i = 0; i < reply->RowCount; i++) { emsmdb_get_SRow((TALLOC_CTX *)message, &(message->SRowSet.aRow[i]), &message->SPropTagArray, reply->RecipientRows[i].RecipientRow.prop_count, &reply->RecipientRows[i].RecipientRow.prop_values, reply->RecipientRows[i].RecipientRow.layout, 1); lpProp.ulPropTag = PR_RECIPIENT_TYPE; lpProp.value.l = reply->RecipientRows[i].RecipientType; SRow_addprop(&(message->SRowSet.aRow[i]), lpProp); lpProp.ulPropTag = PR_INTERNET_CPID; lpProp.value.l = reply->RecipientRows[i].CodePageId; SRow_addprop(&(message->SRowSet.aRow[i]), lpProp); } /* add SPropTagArray elements we automatically append to SRow */ SPropTagArray_add((TALLOC_CTX *)message, &message->SPropTagArray, PR_RECIPIENT_TYPE); SPropTagArray_add((TALLOC_CTX *)message, &message->SPropTagArray, PR_INTERNET_CPID); obj_message->private_data = (void *) message; talloc_free(mapi_response); talloc_free(mem_ctx); return MAPI_E_SUCCESS; } /** \details Retrieve the message properties for an already open message. This function is very similar to OpenMessage, but works on an already open message object. \param obj_message the message object to retrieve the properties for. \return MAPI_E_SUCCESS on success, otherwise MAPI error. \note Developers may also call GetLastError() to retrieve the last MAPI error code. Possible MAPI error codes are: - MAPI_E_NOT_INITIALIZED: MAPI subsystem has not been initialized - MAPI_E_INVALID_PARAMETER: obj_store is undefined - MAPI_E_CALL_FAILED: A network problem was encountered during the transaction \sa OpenMessage */ _PUBLIC_ enum MAPISTATUS ReloadCachedInformation(mapi_object_t *obj_message) { struct mapi_context *mapi_ctx; struct mapi_request *mapi_request; struct mapi_response *mapi_response; struct EcDoRpc_MAPI_REQ *mapi_req; struct ReloadCachedInformation_req request; struct ReloadCachedInformation_repl *reply; struct mapi_session *session; mapi_object_message_t *message; struct SPropValue lpProp; NTSTATUS status; enum MAPISTATUS retval; uint32_t size = 0; TALLOC_CTX *mem_ctx; uint32_t i = 0; uint8_t logon_id; /* Sanity checks */ OPENCHANGE_RETVAL_IF(!obj_message, MAPI_E_INVALID_PARAMETER, NULL); session = mapi_object_get_session(obj_message); OPENCHANGE_RETVAL_IF(!session, MAPI_E_INVALID_PARAMETER, NULL); mapi_ctx = session->mapi_ctx; OPENCHANGE_RETVAL_IF(!mapi_ctx, MAPI_E_NOT_INITIALIZED, NULL); if ((retval = mapi_object_get_logon_id(obj_message, &logon_id)) != MAPI_E_SUCCESS) return retval; mem_ctx = talloc_named(session, 0, "ReloadCachedInformation"); /* Fill the ReloadCachedInformation operation */ request.Reserved = 0x0000; size += sizeof (uint16_t); /* Fill the MAPI_REQ request */ mapi_req = talloc_zero(mem_ctx, struct EcDoRpc_MAPI_REQ); mapi_req->opnum = op_MAPI_ReloadCachedInformation; mapi_req->logon_id = logon_id; mapi_req->handle_idx = 0; mapi_req->u.mapi_ReloadCachedInformation = request; size += 5; /* Fill the mapi_request structure */ mapi_request = talloc_zero(mem_ctx, struct mapi_request); mapi_request->mapi_len = size + sizeof (uint32_t); mapi_request->length = size; mapi_request->mapi_req = mapi_req; mapi_request->handles = talloc_array(mem_ctx, uint32_t, 1); mapi_request->handles[0] = mapi_object_get_handle(obj_message); status = emsmdb_transaction_wrapper(session, mem_ctx, mapi_request, &mapi_response); OPENCHANGE_RETVAL_IF(!NT_STATUS_IS_OK(status), MAPI_E_CALL_FAILED, mem_ctx); OPENCHANGE_RETVAL_IF(!mapi_response->mapi_repl, MAPI_E_CALL_FAILED, mem_ctx); retval = mapi_response->mapi_repl->error_code; OPENCHANGE_RETVAL_IF(retval, retval, mem_ctx); OPENCHANGE_CHECK_NOTIFICATION(session, mapi_response); /* Store ReloadCachedInformation reply data */ reply = &mapi_response->mapi_repl->u.mapi_ReloadCachedInformation; message = talloc_zero((TALLOC_CTX *)session, mapi_object_message_t); message->cValues = reply->RecipientColumns.cValues; message->SRowSet.cRows = reply->RowCount; message->SRowSet.aRow = talloc_array((TALLOC_CTX *)message, struct SRow, reply->RowCount + 1); message->SPropTagArray.cValues = reply->RecipientColumns.cValues; message->SPropTagArray.aulPropTag = talloc_steal(message, reply->RecipientColumns.aulPropTag); for (i = 0; i < reply->RowCount; i++) { emsmdb_get_SRow((TALLOC_CTX *)message, &(message->SRowSet.aRow[i]), &message->SPropTagArray, reply->RecipientRows[i].RecipientRow.prop_count, &reply->RecipientRows[i].RecipientRow.prop_values, reply->RecipientRows[i].RecipientRow.layout, 1); lpProp.ulPropTag = PR_RECIPIENT_TYPE; lpProp.value.l = reply->RecipientRows[i].RecipientType; SRow_addprop(&(message->SRowSet.aRow[i]), lpProp); lpProp.ulPropTag = PR_INTERNET_CPID; lpProp.value.l = reply->RecipientRows[i].CodePageId; SRow_addprop(&(message->SRowSet.aRow[i]), lpProp); } /* add SPropTagArray elements we automatically append to SRow */ SPropTagArray_add((TALLOC_CTX *)message, &message->SPropTagArray, PR_RECIPIENT_TYPE); SPropTagArray_add((TALLOC_CTX *)message, &message->SPropTagArray, PR_INTERNET_CPID); talloc_free(obj_message->private_data); obj_message->private_data = (void *) message; talloc_free(mapi_response); talloc_free(mem_ctx); errno = 0; return MAPI_E_SUCCESS; } openchange-2.0/libmapi/IStream.c000066400000000000000000001075761223057412600166310ustar00rootroot00000000000000/* OpenChange MAPI implementation. Copyright (C) Julien Kerihuel 2007-2008. This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see . */ #include "libmapi/libmapi.h" #include "libmapi/libmapi_private.h" /** \file IStream.c \brief Functions for operating on Streams on MAPI objects */ /** \details Open a stream This function opens a stream on the property \a prop set in \a obj_related with access flags set to \a access_flags and returns an object \a obj_stream. \param obj_related the object to open. \param PropertyTag the property name for the object to create a stream for. \param OpenModeFlags sets the access mode for the stream and is one of the following values: * 0x0: ReadOnly * 0x1: ReadWrite * 0x2: Create * 0x3: BestAccess \param obj_stream the resulting stream object. \return MAPI_E_SUCCESS on success, otherwise MAPI error. Possible MAPI error codes are: - MAPI_E_NOT_INITIALIZED: MAPI subsystem has not been initialized - MAPI_E_INVALID_PARAMETER: A problem occurred obtaining the session context - MAPI_E_CALL_FAILED: A network problem was encountered during the transaction \note Developers may also call GetLastError() to retrieve the last MAPI error code. \sa ReadStream, WriteStream, GetLastError */ _PUBLIC_ enum MAPISTATUS OpenStream(mapi_object_t *obj_related, enum MAPITAGS PropertyTag, enum OpenStream_OpenModeFlags OpenModeFlags, mapi_object_t *obj_stream) { struct mapi_request *mapi_request; struct mapi_response *mapi_response; struct EcDoRpc_MAPI_REQ *mapi_req; struct OpenStream_req request; struct mapi_session *session; NTSTATUS status; enum MAPISTATUS retval; uint32_t size = 0; TALLOC_CTX *mem_ctx; uint8_t logon_id; /* Sanity checks */ session = mapi_object_get_session(obj_related); OPENCHANGE_RETVAL_IF(!session, MAPI_E_INVALID_PARAMETER, NULL); if ((retval = mapi_object_get_logon_id(obj_related, &logon_id)) != MAPI_E_SUCCESS) return retval; mem_ctx = talloc_named(session, 0, "OpenStream"); size = 0; /* Fill the OpenStream operation */ request.handle_idx = 0x1; request.PropertyTag = PropertyTag; /* STGM_XXX (obj_base.h windows header) */ request.OpenModeFlags = OpenModeFlags; size += sizeof(uint8_t) + sizeof(uint32_t) + sizeof(uint8_t); /* Fill the MAPI_REQ request */ mapi_req = talloc_zero(mem_ctx, struct EcDoRpc_MAPI_REQ); mapi_req->opnum = op_MAPI_OpenStream; mapi_req->logon_id = logon_id; mapi_req->handle_idx = 0; mapi_req->u.mapi_OpenStream = request; size += 5; /* Fill the mapi_request structure */ mapi_request = talloc_zero(mem_ctx, struct mapi_request); mapi_request->mapi_len = size + sizeof (uint32_t) * 2; mapi_request->length = size; mapi_request->mapi_req = mapi_req; mapi_request->handles = talloc_array(mem_ctx, uint32_t, 2); mapi_request->handles[0] = mapi_object_get_handle(obj_related); mapi_request->handles[1] = 0xffffffff; status = emsmdb_transaction_wrapper(session, mem_ctx, mapi_request, &mapi_response); OPENCHANGE_RETVAL_IF(!NT_STATUS_IS_OK(status), MAPI_E_CALL_FAILED, mem_ctx); OPENCHANGE_RETVAL_IF(!mapi_response->mapi_repl, MAPI_E_CALL_FAILED, mem_ctx); retval = mapi_response->mapi_repl->error_code; OPENCHANGE_RETVAL_IF(retval, retval, mem_ctx); OPENCHANGE_CHECK_NOTIFICATION(session, mapi_response); /* Set object session and handle */ mapi_object_set_session(obj_stream, session); mapi_object_set_handle(obj_stream, mapi_response->handles[1]); mapi_object_set_logon_id(obj_stream, logon_id); talloc_free(mapi_response); talloc_free(mem_ctx); return MAPI_E_SUCCESS; } /** \details Read buffer from a stream This function reads from an open data stream. It will read up to ByteCount bytes from the stream, and return the data in data_buf. ByteRead is set to the number of bytes actually read. \param obj_stream the opened stream object \param buf_data the buffer where data read from the stream will be stored \param ByteCount the number of bytes requested to be read from the stream \param ByteRead the number of bytes read from the stream \return MAPI_E_SUCCESS on success, otherwise MAPI error. Possible MAPI error codes are: - MAPI_E_NOT_INITIALIZED: MAPI subsystem has not been initialized - MAPI_E_INVALID_PARAMETER: A problem occurred obtaining the session context - MAPI_E_CALL_FAILED: A network problem was encountered during the transaction \note Developers may also call GetLastError() to retrieve the last MAPI error code. \note The data size intended to be read from the stream shouldn't extend a maximum size each time you call ReadStream. This size depends on Exchange server version. However 0x1000 is known to be a reliable read size value. \sa OpenStream, WriteStream, GetLastError */ _PUBLIC_ enum MAPISTATUS ReadStream(mapi_object_t *obj_stream, unsigned char *buf_data, uint16_t ByteCount, uint16_t *ByteRead) { struct mapi_request *mapi_request; struct mapi_response *mapi_response; struct EcDoRpc_MAPI_REQ *mapi_req; struct ReadStream_req request; struct mapi_session *session; NTSTATUS status; enum MAPISTATUS retval; uint32_t size = 0; TALLOC_CTX *mem_ctx; uint8_t logon_id = 0; /* Sanity checks */ session = mapi_object_get_session(obj_stream); OPENCHANGE_RETVAL_IF(!session, MAPI_E_INVALID_PARAMETER, NULL); if ((retval = mapi_object_get_logon_id(obj_stream, &logon_id)) != MAPI_E_SUCCESS) return retval; mem_ctx = talloc_named(session, 0, "ReadStream"); *ByteRead = 0; size = 0; /* Fill the ReadStream operation */ request.ByteCount = ByteCount; size += sizeof(uint16_t); /* Fill the MAPI_REQ request */ mapi_req = talloc_zero(mem_ctx, struct EcDoRpc_MAPI_REQ); mapi_req->opnum = op_MAPI_ReadStream; mapi_req->logon_id = logon_id; mapi_req->handle_idx = 0; mapi_req->u.mapi_ReadStream = request; size += 5; /* Fill the mapi_request structure */ mapi_request = talloc_zero(mem_ctx, struct mapi_request); mapi_request->mapi_len = size + sizeof (uint32_t) * 1; mapi_request->length = size; mapi_request->mapi_req = mapi_req; mapi_request->handles = talloc_array(mem_ctx, uint32_t, 1); mapi_request->handles[0] = mapi_object_get_handle(obj_stream); status = emsmdb_transaction_wrapper(session, mem_ctx, mapi_request, &mapi_response); OPENCHANGE_RETVAL_IF(!NT_STATUS_IS_OK(status), MAPI_E_CALL_FAILED, mem_ctx); OPENCHANGE_RETVAL_IF(!mapi_response->mapi_repl, MAPI_E_CALL_FAILED, mem_ctx); retval = mapi_response->mapi_repl->error_code; OPENCHANGE_RETVAL_IF(retval, retval, mem_ctx); OPENCHANGE_CHECK_NOTIFICATION(session, mapi_response); /* copy no more than sz_data into buffer */ *ByteRead = mapi_response->mapi_repl->u.mapi_ReadStream.data.length; if (*ByteRead > 0) { if (*ByteRead > ByteCount) { *ByteRead = ByteCount; } memcpy(buf_data, mapi_response->mapi_repl->u.mapi_ReadStream.data.data, *ByteRead); } talloc_free(mapi_response); talloc_free(mem_ctx); return MAPI_E_SUCCESS; } /** \details Write buffer to the stream This function writes the stream specified as a DATA_BLOB in data to the stream obj_stream. \param obj_stream the opened stream object \param blob the DATA_BLOB to write to the stream \param WrittenSize the actual number of bytes written to the stream \return MAPI_E_SUCCESS on success, otherwise MAPI error. \note Developers may also call GetLastError() to retrieve the last MAPI error code. Possible MAPI error codes are: - MAPI_E_NOT_INITIALIZED: MAPI subsystem has not been initialized - MAPI_E_INVALID_PARAMETER: A problem occurred obtaining the session context, or blob was null. - MAPI_E_CALL_FAILED: A network problem was encountered during the transaction - MAPI_E_TOO_BIG: the data blob was too large to process \note The data size intended to be written to the stream should not exceed a maximum size each time you call WriteStream. This size depends on Exchange server version. However 0x1000 is known to be a reliable write size value. \sa OpenStream, ReadStream, GetLastError */ _PUBLIC_ enum MAPISTATUS WriteStream(mapi_object_t *obj_stream, DATA_BLOB *blob, uint16_t *WrittenSize) { struct mapi_request *mapi_request; struct mapi_response *mapi_response; struct EcDoRpc_MAPI_REQ *mapi_req; struct WriteStream_req request; struct mapi_session *session; NTSTATUS status; enum MAPISTATUS retval; TALLOC_CTX *mem_ctx; uint32_t size; uint8_t logon_id = 0; /* Sanity Checks */ session = mapi_object_get_session(obj_stream); OPENCHANGE_RETVAL_IF(!session, MAPI_E_INVALID_PARAMETER, NULL); OPENCHANGE_RETVAL_IF(!blob, MAPI_E_INVALID_PARAMETER, NULL); OPENCHANGE_RETVAL_IF(blob->length > 0x7000, MAPI_E_TOO_BIG, NULL); if ((retval = mapi_object_get_logon_id(obj_stream, &logon_id)) != MAPI_E_SUCCESS) return retval; mem_ctx = talloc_named(session, 0, "WriteStream"); size = 0; /* Fill the WriteStream operation */ request.data = *blob; size += blob->length; /* size for subcontext(2) */ size += 2; /* Fill the MAPI_REQ request */ mapi_req = talloc_zero(mem_ctx, struct EcDoRpc_MAPI_REQ); mapi_req->opnum = op_MAPI_WriteStream; mapi_req->logon_id = logon_id; mapi_req->handle_idx = 0; mapi_req->u.mapi_WriteStream = request; size += 5; /* Fill the mapi_request structure */ mapi_request = talloc_zero(mem_ctx, struct mapi_request); mapi_request->mapi_len = size + sizeof (uint32_t); mapi_request->length = size; mapi_request->mapi_req = mapi_req; mapi_request->handles = talloc_array(mem_ctx, uint32_t, 1); mapi_request->handles[0] = mapi_object_get_handle(obj_stream); status = emsmdb_transaction_wrapper(session, mem_ctx, mapi_request, &mapi_response); OPENCHANGE_RETVAL_IF(!NT_STATUS_IS_OK(status), MAPI_E_CALL_FAILED, mem_ctx); OPENCHANGE_RETVAL_IF(!mapi_response->mapi_repl, MAPI_E_CALL_FAILED, mem_ctx); retval = mapi_response->mapi_repl->error_code; OPENCHANGE_RETVAL_IF(retval, retval, mem_ctx); OPENCHANGE_CHECK_NOTIFICATION(session, mapi_response); *WrittenSize = mapi_response->mapi_repl->u.mapi_WriteStream.WrittenSize; talloc_free(mapi_response); talloc_free(mem_ctx); errno = 0; return MAPI_E_SUCCESS; } /** \details Commits stream operations \param obj_stream the stream object to commit \return MAPI_E_SUCCESS on success, otherwise MAPI error. \note Developers may also call GetLastError() to retrieve the last MAPI error code. Possible MAPI error codes are: - MAPI_E_NOT_INITIALIZED: MAPI subsystem has not been initialized - MAPI_E_INVALID_PARAMETER: Either the network stream or session context are not valid. - MAPI_E_CALL_FAILED: A network problem was encountered during the transaction \sa OpenStream, ReadStream, WriteStream */ _PUBLIC_ enum MAPISTATUS CommitStream(mapi_object_t *obj_stream) { struct mapi_request *mapi_request; struct mapi_response *mapi_response; struct EcDoRpc_MAPI_REQ *mapi_req; struct mapi_session *session; NTSTATUS status; enum MAPISTATUS retval; uint32_t size; TALLOC_CTX *mem_ctx; uint8_t logon_id = 0; /* Sanity checks */ session = mapi_object_get_session(obj_stream); OPENCHANGE_RETVAL_IF(!obj_stream, MAPI_E_INVALID_PARAMETER, NULL); OPENCHANGE_RETVAL_IF(!session, MAPI_E_INVALID_PARAMETER, NULL); if ((retval = mapi_object_get_logon_id(obj_stream, &logon_id)) != MAPI_E_SUCCESS) return retval; mem_ctx = talloc_named(session, 0, "CommitStream"); size = 0; /* Fill the MAPI_REQ request */ mapi_req = talloc_zero(mem_ctx, struct EcDoRpc_MAPI_REQ); mapi_req->opnum = op_MAPI_CommitStream; mapi_req->logon_id = logon_id; mapi_req->handle_idx = 0; size += 5; /* Fill the mapi_request structure */ mapi_request = talloc_zero(mem_ctx, struct mapi_request); mapi_request->mapi_len = size + sizeof (uint32_t); mapi_request->length = size; mapi_request->mapi_req = mapi_req; mapi_request->handles = talloc_array(mem_ctx, uint32_t, 1); mapi_request->handles[0] = mapi_object_get_handle(obj_stream); status = emsmdb_transaction_wrapper(session, mem_ctx, mapi_request, &mapi_response); OPENCHANGE_RETVAL_IF(!NT_STATUS_IS_OK(status), MAPI_E_CALL_FAILED, mem_ctx); OPENCHANGE_RETVAL_IF(!mapi_response->mapi_repl, MAPI_E_CALL_FAILED, mem_ctx); retval = mapi_response->mapi_repl->error_code; OPENCHANGE_RETVAL_IF(retval, retval, mem_ctx); OPENCHANGE_CHECK_NOTIFICATION(session, mapi_response); talloc_free(mapi_response); talloc_free(mem_ctx); return MAPI_E_SUCCESS; } /** \details Gets the size of a stream \param obj_stream the stream object we retrieve size from \param StreamSize pointer on the stream size \return MAPI_E_SUCCESS on success, otherwise MAPI error. \note Developers may also call GetLastError() to retrieve the last MAPI error code. Possible MAPI error codes are: - MAPI_E_NOT_INITIALIZED: MAPI subsystem has not been initialized - MAPI_E_INVALID_PARAMETER: obj_stream is not initialized, or there was a problem obtaining the session context - MAPI_E_CALL_FAILED: A network problem was encountered during the transaction \sa OpenStream, ReadStream */ _PUBLIC_ enum MAPISTATUS GetStreamSize(mapi_object_t *obj_stream, uint32_t *StreamSize) { struct mapi_request *mapi_request; struct mapi_response *mapi_response; struct EcDoRpc_MAPI_REQ *mapi_req; struct mapi_session *session; NTSTATUS status; enum MAPISTATUS retval; uint32_t size; TALLOC_CTX *mem_ctx; uint8_t logon_id = 0; /* Sanity checks */ OPENCHANGE_RETVAL_IF(!obj_stream, MAPI_E_INVALID_PARAMETER, NULL); session = mapi_object_get_session(obj_stream); OPENCHANGE_RETVAL_IF(!session, MAPI_E_INVALID_PARAMETER, NULL); if ((retval = mapi_object_get_logon_id(obj_stream, &logon_id)) != MAPI_E_SUCCESS) return retval; mem_ctx = talloc_named(session, 0, "GetStreamSize"); size = 0; /* Fill the MAPI_REQ request */ mapi_req = talloc_zero(mem_ctx, struct EcDoRpc_MAPI_REQ); mapi_req->opnum = op_MAPI_GetStreamSize; mapi_req->logon_id = logon_id; mapi_req->handle_idx = 0; size += 5; /* Fill the mapi_request structure */ mapi_request = talloc_zero(mem_ctx, struct mapi_request); mapi_request->mapi_len = size + sizeof (uint32_t); mapi_request->length = size; mapi_request->mapi_req = mapi_req; mapi_request->handles = talloc_array(mem_ctx, uint32_t, 1); mapi_request->handles[0] = mapi_object_get_handle(obj_stream); status = emsmdb_transaction_wrapper(session, mem_ctx, mapi_request, &mapi_response); OPENCHANGE_RETVAL_IF(!NT_STATUS_IS_OK(status), MAPI_E_CALL_FAILED, mem_ctx); OPENCHANGE_RETVAL_IF(!mapi_response->mapi_repl, MAPI_E_CALL_FAILED, mem_ctx); retval = mapi_response->mapi_repl->error_code; OPENCHANGE_RETVAL_IF(retval, retval, mem_ctx); OPENCHANGE_CHECK_NOTIFICATION(session, mapi_response); *StreamSize = mapi_response->mapi_repl->u.mapi_GetStreamSize.StreamSize; talloc_free(mapi_response); talloc_free(mem_ctx); return MAPI_E_SUCCESS; } /** \details Seek a specific position within the stream \param obj_stream the stream object \param Origin origin location for the seek operation \param Offset the seek offset \param NewPosition pointer on the new position after the operation Origin can either take one of the following values: * 0x0 The new seek pointer is an offset relative to the beginning of the stream. * 0x1 The new seek pointer is an offset relative to the current seek pointer location. * 0x2 The new seek pointer is an offset relative to the end of the stream. \return MAPI_E_SUCCESS on success, otherwise MAPI error \note Developers may also call GetLastError() to retrieve the last MAPI error code. Possible MAPI error codes are: - MAPI_E_NOT_INITIALIZED: MAPI subsystem has not been initialized - MAPI_E_INVALID_PARAMETER: obj_stream is not valid, Origin is out of limits, or NewPosition is null. - MAPI_E_CALL_FAILED: A network problem was encountered during the transaction \sa OpenStream, ReadStream */ _PUBLIC_ enum MAPISTATUS SeekStream(mapi_object_t *obj_stream, uint8_t Origin, uint64_t Offset, uint64_t *NewPosition) { struct mapi_request *mapi_request; struct mapi_response *mapi_response; struct EcDoRpc_MAPI_REQ *mapi_req; struct SeekStream_req request; struct mapi_session *session; NTSTATUS status; enum MAPISTATUS retval; TALLOC_CTX *mem_ctx; uint32_t size; uint8_t logon_id = 0; /* Sanity checks */ OPENCHANGE_RETVAL_IF(!obj_stream, MAPI_E_INVALID_PARAMETER, NULL); session = mapi_object_get_session(obj_stream); OPENCHANGE_RETVAL_IF(!session, MAPI_E_INVALID_PARAMETER, NULL); OPENCHANGE_RETVAL_IF((Origin > 2), MAPI_E_INVALID_PARAMETER, NULL); OPENCHANGE_RETVAL_IF(!NewPosition, MAPI_E_INVALID_PARAMETER, NULL); if ((retval = mapi_object_get_logon_id(obj_stream, &logon_id)) != MAPI_E_SUCCESS) return retval; mem_ctx = talloc_named(session, 0, "SeekStream"); size = 0; /* Fill the SeekStream operation */ request.Origin = Origin; size += sizeof (uint8_t); request.Offset = Offset; size += sizeof (uint64_t); /* Fill the MAPI_REQ request */ mapi_req = talloc_zero(mem_ctx, struct EcDoRpc_MAPI_REQ); mapi_req->opnum = op_MAPI_SeekStream; mapi_req->logon_id = logon_id; mapi_req->handle_idx = 0; mapi_req->u.mapi_SeekStream = request; size += 5; /* Fill the mapi_request structure */ mapi_request = talloc_zero(mem_ctx, struct mapi_request); mapi_request->mapi_len = size + sizeof (uint32_t); mapi_request->length = size; mapi_request->mapi_req = mapi_req; mapi_request->handles = talloc_array(mem_ctx, uint32_t, 1); mapi_request->handles[0] = mapi_object_get_handle(obj_stream); status = emsmdb_transaction_wrapper(session, mem_ctx, mapi_request, &mapi_response); OPENCHANGE_RETVAL_IF(!NT_STATUS_IS_OK(status), MAPI_E_CALL_FAILED, mem_ctx); OPENCHANGE_RETVAL_IF(!mapi_response->mapi_repl, MAPI_E_CALL_FAILED, mem_ctx); retval = mapi_response->mapi_repl->error_code; OPENCHANGE_RETVAL_IF(retval, retval, mem_ctx); OPENCHANGE_CHECK_NOTIFICATION(session, mapi_response); *NewPosition = mapi_response->mapi_repl->u.mapi_SeekStream.NewPosition; talloc_free(mapi_response); talloc_free(mem_ctx); return MAPI_E_SUCCESS; } /** \details Set the stream size \param obj_stream the stream object \param SizeStream the size of the stream \return MAPI_E_SUCCESS on success, otherwise MAPI error \note Developers may also call GetLastError() to retrieve the last MAPI error code. Possible MAPI error codes are: - MAPI_E_NOT_INITIALIZED: MAPI subsystem has not been initialized - MAPI_E_INVALID_PARAMETER: obj_stream is not valid - MAPI_E_CALL_FAILED: A network problem was encountered during the transaction \sa OpenStream, GetStreamSize */ _PUBLIC_ enum MAPISTATUS SetStreamSize(mapi_object_t *obj_stream, uint64_t SizeStream) { struct mapi_request *mapi_request; struct mapi_response *mapi_response; struct EcDoRpc_MAPI_REQ *mapi_req; struct SetStreamSize_req request; struct mapi_session *session; NTSTATUS status; enum MAPISTATUS retval; TALLOC_CTX *mem_ctx; uint32_t size; uint8_t logon_id = 0; /* Sanity checks */ OPENCHANGE_RETVAL_IF(!obj_stream, MAPI_E_INVALID_PARAMETER, NULL); session = mapi_object_get_session(obj_stream); OPENCHANGE_RETVAL_IF(!session, MAPI_E_INVALID_PARAMETER, NULL); if ((retval = mapi_object_get_logon_id(obj_stream, &logon_id)) != MAPI_E_SUCCESS) return retval; mem_ctx = talloc_named(session, 0, "SetStreamSize"); size = 0; /* Fill the SetStreamSize operation */ request.SizeStream = SizeStream; size += sizeof (uint64_t); /* Fill the MAPI_REQ request */ mapi_req = talloc_zero(mem_ctx, struct EcDoRpc_MAPI_REQ); mapi_req->opnum = op_MAPI_SetStreamSize; mapi_req->logon_id = logon_id; mapi_req->handle_idx = 0; mapi_req->u.mapi_SetStreamSize = request; size += 5; /* Fill the mapi_request structure */ mapi_request = talloc_zero(mem_ctx, struct mapi_request); mapi_request->mapi_len = size + sizeof (uint32_t); mapi_request->length = size; mapi_request->mapi_req = mapi_req; mapi_request->handles = talloc_array(mem_ctx, uint32_t, 1); mapi_request->handles[0] = mapi_object_get_handle(obj_stream); status = emsmdb_transaction_wrapper(session, mem_ctx, mapi_request, &mapi_response); OPENCHANGE_RETVAL_IF(!NT_STATUS_IS_OK(status), MAPI_E_CALL_FAILED, mem_ctx); OPENCHANGE_RETVAL_IF(!mapi_response->mapi_repl, MAPI_E_CALL_FAILED, mem_ctx); retval = mapi_response->mapi_repl->error_code; OPENCHANGE_RETVAL_IF(retval, retval, mem_ctx); OPENCHANGE_CHECK_NOTIFICATION(session, mapi_response); talloc_free(mapi_response); talloc_free(mem_ctx); return MAPI_E_SUCCESS; } /** \details Copy a number of bytes from a source stream to another stream \param obj_src the source stream object \param obj_dst the destination stream object \param ByteCount the number of bytes to copy \param ReadByteCount pointer on the number of bytes read from the source object \param WrittenByteCount pointer on the number of bytes written to the destination object \return MAPI_E_SUCCESS on success, otherwise MAPI error. \note Developers may also call GetLastError() to retrieve the last MAPI error code. Possible MAPI error codes are: - MAPI_E_NOT_INITIALIZED: MAPI subsystem has not been initialized - MAPI_E_INVALID_BOOKMARK: the bookmark specified is invalid or beyond the last row requested. - MAPI_E_CALL_FAILED: A network problem was encountered during the transaction \sa OpenStream */ _PUBLIC_ enum MAPISTATUS CopyToStream(mapi_object_t *obj_src, mapi_object_t *obj_dst, uint64_t ByteCount, uint64_t *ReadByteCount, uint64_t *WrittenByteCount) { struct mapi_request *mapi_request; struct mapi_response *mapi_response; struct EcDoRpc_MAPI_REQ *mapi_req; struct CopyToStream_req request; struct mapi_session *session[2]; NTSTATUS status; enum MAPISTATUS retval; TALLOC_CTX *mem_ctx; uint32_t size; uint8_t logon_id = 0; /* Sanity Check */ OPENCHANGE_RETVAL_IF(!obj_src, MAPI_E_INVALID_PARAMETER, NULL); OPENCHANGE_RETVAL_IF(!obj_dst, MAPI_E_INVALID_PARAMETER, NULL); session[0] = mapi_object_get_session(obj_src); session[1] = mapi_object_get_session(obj_dst); OPENCHANGE_RETVAL_IF(!session[0], MAPI_E_INVALID_PARAMETER, NULL); OPENCHANGE_RETVAL_IF(!session[1], MAPI_E_INVALID_PARAMETER, NULL); OPENCHANGE_RETVAL_IF(session[0] != session[1], MAPI_E_INVALID_PARAMETER, NULL); OPENCHANGE_RETVAL_IF(!ByteCount, MAPI_E_INVALID_PARAMETER, NULL); OPENCHANGE_RETVAL_IF(!ReadByteCount, MAPI_E_INVALID_PARAMETER, NULL); OPENCHANGE_RETVAL_IF(!WrittenByteCount, MAPI_E_INVALID_PARAMETER, NULL); if ((retval = mapi_object_get_logon_id(obj_src, &logon_id)) != MAPI_E_SUCCESS) return retval; mem_ctx = talloc_named(session[0], 0, "CopyToStream"); size = 0; /* Fill the CopyToStream operation */ request.handle_idx = 0x1; size += sizeof (uint8_t); request.ByteCount = ByteCount; size += sizeof (uint64_t); /* Fill the MAPI_REQ request */ mapi_req = talloc_zero(mem_ctx, struct EcDoRpc_MAPI_REQ); mapi_req->opnum = op_MAPI_CopyToStream; mapi_req->logon_id = logon_id; mapi_req->handle_idx = 0; mapi_req->u.mapi_CopyToStream = request; size += 5; /* Fill the mapi_request structure */ mapi_request = talloc_zero(mem_ctx, struct mapi_request); mapi_request->mapi_len = size + sizeof (uint32_t) * 2; mapi_request->length = size; mapi_request->mapi_req = mapi_req; mapi_request->handles = talloc_array(mem_ctx, uint32_t, 2); mapi_request->handles[0] = mapi_object_get_handle(obj_src); mapi_request->handles[1] = mapi_object_get_handle(obj_dst); status = emsmdb_transaction_wrapper(session[0], mem_ctx, mapi_request, &mapi_response); OPENCHANGE_RETVAL_IF(!NT_STATUS_IS_OK(status), MAPI_E_CALL_FAILED, mem_ctx); OPENCHANGE_RETVAL_IF(!mapi_response->mapi_repl, MAPI_E_CALL_FAILED, mem_ctx); retval = mapi_response->mapi_repl->error_code; OPENCHANGE_RETVAL_IF(retval, retval, mem_ctx); OPENCHANGE_CHECK_NOTIFICATION(session[0], mapi_response); *ReadByteCount = mapi_response->mapi_repl->u.mapi_CopyToStream.ReadByteCount; *WrittenByteCount = mapi_response->mapi_repl->u.mapi_CopyToStream.WrittenByteCount; talloc_free(mapi_response); talloc_free(mem_ctx); return MAPI_E_SUCCESS; } /** \details Lock a range of bytes within the stream \param obj_stream the stream object \param RegionOffset starting point for the range \param RegionSize length of the range \param LockFlags type of locking to apply Setting LockFlags to 0x00000001 will provide a write lock (i.e. one writer, any number of readers). Setting LockFlags to any other value will provide a read-write lock (one reader/writer, no other readers or writers). \return MAPI_E_SUCCESS on success, otherwise MAPI error \note Developers may also call GetLastError() to retrieve the last MAPI error code. Possible MAPI error codes are: - MAPI_E_NOT_INITIALIZED: MAPI subsystem has not been initialized - MAPI_E_INVALID_PARAMETER: obj_stream is not valid - MAPI_E_CALL_FAILED: A network problem was encountered during the transaction \sa UnlockRegionStream */ _PUBLIC_ enum MAPISTATUS LockRegionStream(mapi_object_t *obj_stream, uint64_t RegionOffset, uint64_t RegionSize, uint32_t LockFlags) { struct mapi_request *mapi_request; struct mapi_response *mapi_response; struct EcDoRpc_MAPI_REQ *mapi_req; struct LockRegionStream_req request; struct mapi_session *session; NTSTATUS status; enum MAPISTATUS retval; TALLOC_CTX *mem_ctx; uint32_t size; uint8_t logon_id = 0; /* Sanity checks */ OPENCHANGE_RETVAL_IF(!obj_stream, MAPI_E_INVALID_PARAMETER, NULL); session = mapi_object_get_session(obj_stream); OPENCHANGE_RETVAL_IF(!session, MAPI_E_INVALID_PARAMETER, NULL); if ((retval = mapi_object_get_logon_id(obj_stream, &logon_id)) != MAPI_E_SUCCESS) return retval; mem_ctx = talloc_named(session, 0, "LockRegionStream"); size = 0; /* Fill the LockRegionStream operation */ request.RegionOffset = RegionOffset; size += sizeof (uint64_t); request.RegionSize = RegionSize; size += sizeof (uint64_t); request.LockFlags = LockFlags; size += sizeof (uint32_t); /* Fill the MAPI_REQ request */ mapi_req = talloc_zero(mem_ctx, struct EcDoRpc_MAPI_REQ); mapi_req->opnum = op_MAPI_LockRegionStream; mapi_req->logon_id = logon_id; mapi_req->handle_idx = 0; mapi_req->u.mapi_LockRegionStream = request; size += 5; /* Fill the mapi_request structure */ mapi_request = talloc_zero(mem_ctx, struct mapi_request); mapi_request->mapi_len = size + sizeof (uint32_t); mapi_request->length = size; mapi_request->mapi_req = mapi_req; mapi_request->handles = talloc_array(mem_ctx, uint32_t, 1); mapi_request->handles[0] = mapi_object_get_handle(obj_stream); status = emsmdb_transaction_wrapper(session, mem_ctx, mapi_request, &mapi_response); OPENCHANGE_RETVAL_IF(!NT_STATUS_IS_OK(status), MAPI_E_CALL_FAILED, mem_ctx); OPENCHANGE_RETVAL_IF(!mapi_response->mapi_repl, MAPI_E_CALL_FAILED, mem_ctx); retval = mapi_response->mapi_repl->error_code; OPENCHANGE_RETVAL_IF(retval, retval, mem_ctx); talloc_free(mapi_response); talloc_free(mem_ctx); return MAPI_E_SUCCESS; } /** \details Unlock a range of bytes within the stream \param obj_stream the stream object \param RegionOffset starting point for the range \param RegionSize length of the range \param LockFlags type of locking LockFlags used in unlocking must match the LockFlags used in locking. \return MAPI_E_SUCCESS on success, otherwise MAPI error \note Developers may also call GetLastError() to retrieve the last MAPI error code. Possible MAPI error codes are: - MAPI_E_NOT_INITIALIZED: MAPI subsystem has not been initialized - MAPI_E_INVALID_PARAMETER: obj_stream is not valid - MAPI_E_CALL_FAILED: A network problem was encountered during the transaction \sa UnlockRegionStream */ _PUBLIC_ enum MAPISTATUS UnlockRegionStream(mapi_object_t *obj_stream, uint64_t RegionOffset, uint64_t RegionSize, uint32_t LockFlags) { struct mapi_request *mapi_request; struct mapi_response *mapi_response; struct EcDoRpc_MAPI_REQ *mapi_req; struct UnlockRegionStream_req request; struct mapi_session *session; NTSTATUS status; enum MAPISTATUS retval; TALLOC_CTX *mem_ctx; uint32_t size; uint8_t logon_id = 0; /* Sanity checks */ OPENCHANGE_RETVAL_IF(!obj_stream, MAPI_E_INVALID_PARAMETER, NULL); session = mapi_object_get_session(obj_stream); OPENCHANGE_RETVAL_IF(!session, MAPI_E_INVALID_PARAMETER, NULL); if ((retval = mapi_object_get_logon_id(obj_stream, &logon_id)) != MAPI_E_SUCCESS) return retval; mem_ctx = talloc_named(session, 0, "UnlockRegionStream"); size = 0; /* Fill the LockRegionStream operation */ request.RegionOffset = RegionOffset; size += sizeof (uint64_t); request.RegionSize = RegionSize; size += sizeof (uint64_t); request.LockFlags = LockFlags; size += sizeof (uint32_t); /* Fill the MAPI_REQ request */ mapi_req = talloc_zero(mem_ctx, struct EcDoRpc_MAPI_REQ); mapi_req->opnum = op_MAPI_UnlockRegionStream; mapi_req->logon_id = logon_id; mapi_req->handle_idx = 0; mapi_req->u.mapi_UnlockRegionStream = request; size += 5; /* Fill the mapi_request structure */ mapi_request = talloc_zero(mem_ctx, struct mapi_request); mapi_request->mapi_len = size + sizeof (uint32_t); mapi_request->length = size; mapi_request->mapi_req = mapi_req; mapi_request->handles = talloc_array(mem_ctx, uint32_t, 1); mapi_request->handles[0] = mapi_object_get_handle(obj_stream); status = emsmdb_transaction_wrapper(session, mem_ctx, mapi_request, &mapi_response); OPENCHANGE_RETVAL_IF(!NT_STATUS_IS_OK(status), MAPI_E_CALL_FAILED, mem_ctx); OPENCHANGE_RETVAL_IF(!mapi_response->mapi_repl, MAPI_E_CALL_FAILED, mem_ctx); retval = mapi_response->mapi_repl->error_code; OPENCHANGE_RETVAL_IF(retval, retval, mem_ctx); talloc_free(mapi_response); talloc_free(mem_ctx); return MAPI_E_SUCCESS; } /** \details Clone a source stream to another stream \param obj_src the source stream object \param obj_dst the destination stream object \return MAPI_E_SUCCESS on success, otherwise MAPI error. \note Developers may also call GetLastError() to retrieve the last MAPI error code. Possible MAPI error codes are: - MAPI_E_NOT_INITIALIZED: MAPI subsystem has not been initialized - MAPI_E_INVALID_PARAMETER: source or destination streams are not valid. - MAPI_E_CALL_FAILED: A network problem was encountered during the transaction \sa OpenStream */ _PUBLIC_ enum MAPISTATUS CloneStream(mapi_object_t *obj_src, mapi_object_t *obj_dst) { struct mapi_request *mapi_request; struct mapi_response *mapi_response; struct EcDoRpc_MAPI_REQ *mapi_req; struct CloneStream_req request; struct mapi_session *session; NTSTATUS status; enum MAPISTATUS retval; TALLOC_CTX *mem_ctx; uint32_t size; uint8_t logon_id; /* Sanity Check */ OPENCHANGE_RETVAL_IF(!obj_src, MAPI_E_INVALID_PARAMETER, NULL); OPENCHANGE_RETVAL_IF(!obj_dst, MAPI_E_INVALID_PARAMETER, NULL); session = mapi_object_get_session(obj_src); OPENCHANGE_RETVAL_IF(!session, MAPI_E_INVALID_PARAMETER, NULL); if ((retval = mapi_object_get_logon_id(obj_src, &logon_id)) != MAPI_E_SUCCESS) return retval; mem_ctx = talloc_named(session, 0, "CloneStream"); size = 0; /* Fill the CloneStream operation */ request.handle_idx = 0x1; /* destionation */ size += sizeof (uint8_t); /* Fill the MAPI_REQ request */ mapi_req = talloc_zero(mem_ctx, struct EcDoRpc_MAPI_REQ); mapi_req->opnum = op_MAPI_CloneStream; mapi_req->logon_id = logon_id; mapi_req->handle_idx = 0; mapi_req->u.mapi_CloneStream = request; size += 5; /* Fill the mapi_request structure */ mapi_request = talloc_zero(mem_ctx, struct mapi_request); mapi_request->mapi_len = size + sizeof (uint32_t) * 2; mapi_request->length = size; mapi_request->mapi_req = mapi_req; mapi_request->handles = talloc_array(mem_ctx, uint32_t, 2); mapi_request->handles[0] = mapi_object_get_handle(obj_src); mapi_request->handles[1] = 0xFFFFFFFF; status = emsmdb_transaction_wrapper(session, mem_ctx, mapi_request, &mapi_response); OPENCHANGE_RETVAL_IF(!NT_STATUS_IS_OK(status), MAPI_E_CALL_FAILED, mem_ctx); OPENCHANGE_RETVAL_IF(!mapi_response->mapi_repl, MAPI_E_CALL_FAILED, mem_ctx); retval = mapi_response->mapi_repl->error_code; OPENCHANGE_RETVAL_IF(retval, retval, mem_ctx); mapi_object_set_handle(obj_dst, mapi_response->handles[1]); mapi_object_set_session(obj_dst, session); mapi_object_set_logon_id(obj_dst, logon_id); talloc_free(mapi_response); talloc_free(mem_ctx); return MAPI_E_SUCCESS; } /** \details Write and commit a buffer to the stream This function writes and commits the contents of a DATA_BLOB to the stream obj_stream. \param obj_stream the opened stream object \param blob the DATA_BLOB to write to the stream \param WrittenSize the actual number of bytes written to the stream \return MAPI_E_SUCCESS on success, otherwise MAPI error. \note Developers may also call GetLastError() to retrieve the last MAPI error code. Possible MAPI error codes are: - MAPI_E_NOT_INITIALIZED: MAPI subsystem has not been initialized - MAPI_E_INVALID_PARAMETER: A problem occurred obtaining the session context, or the stream or blob were null. - MAPI_E_CALL_FAILED: A network problem was encountered during the transaction - MAPI_E_TOO_BIG: the data blob was too large to process \note The data size intended to be written to the stream should not exceed a maximum size each time you call WriteStream. This size depends on Exchange server version. However 0x1000 is known to be a reliable write size value. \sa WriteStream, CommitStream */ _PUBLIC_ enum MAPISTATUS WriteAndCommitStream(mapi_object_t *obj_stream, DATA_BLOB *blob, uint16_t *WrittenSize) { struct mapi_request *mapi_request; struct mapi_response *mapi_response; struct EcDoRpc_MAPI_REQ *mapi_req; struct WriteAndCommitStream_req request; struct mapi_session *session; NTSTATUS status; enum MAPISTATUS retval; TALLOC_CTX *mem_ctx; uint32_t size; uint8_t logon_id = 0; /* Sanity Checks */ OPENCHANGE_RETVAL_IF(!obj_stream, MAPI_E_INVALID_PARAMETER, NULL); session = mapi_object_get_session(obj_stream); OPENCHANGE_RETVAL_IF(!session, MAPI_E_INVALID_PARAMETER, NULL); OPENCHANGE_RETVAL_IF(!blob, MAPI_E_INVALID_PARAMETER, NULL); OPENCHANGE_RETVAL_IF(blob->length > 0x7000, MAPI_E_TOO_BIG, NULL); if ((retval = mapi_object_get_logon_id(obj_stream, &logon_id)) != MAPI_E_SUCCESS) return retval; mem_ctx = talloc_named(session, 0, "WriteAndCommitStream"); size = 0; /* Fill the WriteStream operation */ request.data = *blob; size += blob->length; /* size for subcontext(2) */ size += 2; /* Fill the MAPI_REQ request */ mapi_req = talloc_zero(mem_ctx, struct EcDoRpc_MAPI_REQ); mapi_req->opnum = op_MAPI_WriteAndCommitStream; mapi_req->logon_id = logon_id; mapi_req->handle_idx = 0; mapi_req->u.mapi_WriteAndCommitStream = request; size += 5; /* Fill the mapi_request structure */ mapi_request = talloc_zero(mem_ctx, struct mapi_request); mapi_request->mapi_len = size + sizeof (uint32_t); mapi_request->length = size; mapi_request->mapi_req = mapi_req; mapi_request->handles = talloc_array(mem_ctx, uint32_t, 1); mapi_request->handles[0] = mapi_object_get_handle(obj_stream); status = emsmdb_transaction_wrapper(session, mem_ctx, mapi_request, &mapi_response); OPENCHANGE_RETVAL_IF(!NT_STATUS_IS_OK(status), MAPI_E_CALL_FAILED, mem_ctx); OPENCHANGE_RETVAL_IF(!mapi_response->mapi_repl, MAPI_E_CALL_FAILED, mem_ctx); retval = mapi_response->mapi_repl->error_code; OPENCHANGE_RETVAL_IF(retval, retval, mem_ctx); *WrittenSize = mapi_response->mapi_repl->u.mapi_WriteAndCommitStream.WrittenSize; talloc_free(mapi_response); talloc_free(mem_ctx); errno = 0; return MAPI_E_SUCCESS; } openchange-2.0/libmapi/IUnknown.c000066400000000000000000000250311223057412600170160ustar00rootroot00000000000000/* OpenChange MAPI implementation. Copyright (C) Julien Kerihuel 2007-2011. This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see . */ #include "libmapi/libmapi.h" #include "libmapi/libmapi_private.h" /** \file IUnknown.c \brief Various miscellaneous (ungrouped) functions */ /** \details Allocate memory using the MAPI memory context \param mapi_ctx pointer to the MAPI context \param size the number of bytes to allocate \param ptr pointer to the allocated byte region \return MAPI_E_SUCCESS on success, otherwise MAPI error. \note Developers may also call GetLastError() to retrieve the last MAPI error code. Possible MAPI error codes are: - MAPI_E_NOT_INITIALIZED: MAPI subsystem has not been initialized - MAPI_E_SESSION_LIMIT: No session has been opened on the provider - MAPI_E_NOT_ENOUGH_RESOURCES: MAPI subsystem failed to allocate the necessary resources to operate properly - MAPI_E_INVALID_PARAMER: size is not set properly. \sa MAPIFreeBuffer, GetLastError */ _PUBLIC_ enum MAPISTATUS MAPIAllocateBuffer(struct mapi_context *mapi_ctx, uint32_t size, void **ptr) { TALLOC_CTX *mem_ctx; /* Sanity checks */ OPENCHANGE_RETVAL_IF(!mapi_ctx, MAPI_E_NOT_INITIALIZED, NULL); OPENCHANGE_RETVAL_IF(!size, MAPI_E_INVALID_PARAMETER, NULL); mem_ctx = (TALLOC_CTX *) mapi_ctx->mem_ctx; *ptr = talloc_size(mem_ctx, size); OPENCHANGE_RETVAL_IF(!ptr, MAPI_E_NOT_ENOUGH_RESOURCES, NULL); return MAPI_E_SUCCESS; } /** \details Free allocated memory This function frees memory previously allocated with MAPIAllocateBuffer. \param ptr memory region to free \return MAPI_E_SUCCESS on success, otherwise MAPI error. \note Developers may also call GetLastError() to retrieve the last MAPI error code. Possible MAPI error codes are: - MAPI_E_INVALID_PARAMER: ptr is not set properly. \sa MAPIAllocateBuffer, GetLastError */ _PUBLIC_ enum MAPISTATUS MAPIFreeBuffer(void *ptr) { int ret; OPENCHANGE_RETVAL_IF(!ptr, MAPI_E_INVALID_PARAMETER, NULL); ret = talloc_free(ptr); OPENCHANGE_RETVAL_IF(ret == -1, MAPI_E_INVALID_PARAMETER, NULL); return MAPI_E_SUCCESS; } /** \details Release an object on the server The function releases the object \a obj on the server. \param obj the object to release \return MAPI_E_SUCCESS on success, otherwise MAPI error. \note Developers may also call GetLastError() to retrieve the last MAPI error code. Possible MAPI error codes are: - MAPI_E_NOT_INITIALIZED: MAPI subsystem has not been initialized - MAPI_E_CALL_FAILED: A network problem was encountered during the transaction \sa GetLastError */ _PUBLIC_ enum MAPISTATUS Release(mapi_object_t *obj) { struct mapi_request *mapi_request; struct mapi_response *mapi_response; struct EcDoRpc_MAPI_REQ *mapi_req; struct mapi_session *session; NTSTATUS status; TALLOC_CTX *mem_ctx; uint32_t size = 0; enum MAPISTATUS retval; uint8_t logon_id = 0; mapi_response = 0; /* Sanity checks */ session = mapi_object_get_session(obj); OPENCHANGE_RETVAL_IF(!session, MAPI_E_INVALID_PARAMETER, NULL); if ((retval = mapi_object_get_logon_id(obj, &logon_id)) != MAPI_E_SUCCESS) return retval; mem_ctx = talloc_named(session, 0, "Release"); /* Fill the MAPI_REQ request */ mapi_req = talloc_zero(mem_ctx, struct EcDoRpc_MAPI_REQ); mapi_req->opnum = op_MAPI_Release; mapi_req->logon_id = logon_id; mapi_req->handle_idx = 0; size += 5; /* Fill the mapi_request structure */ mapi_request = talloc_zero(mem_ctx, struct mapi_request); mapi_request->mapi_len = size + sizeof (uint32_t); mapi_request->length = (uint16_t)size; mapi_request->mapi_req = mapi_req; mapi_request->handles = talloc_array(mem_ctx, uint32_t, 1); mapi_request->handles[0] = mapi_object_get_handle(obj); status = emsmdb_transaction_wrapper(session, mem_ctx, mapi_request, &mapi_response); OPENCHANGE_RETVAL_IF(!NT_STATUS_IS_OK(status), MAPI_E_CALL_FAILED, mem_ctx); if (mapi_response->mapi_repl) { OPENCHANGE_CHECK_NOTIFICATION(session, mapi_response); } talloc_free(mapi_response); talloc_free(mem_ctx); errno = 0; return MAPI_E_SUCCESS; } /** \details Returns the latest error code. This function returns the error code set by a previous function call. \note Calls to this function may not work reliably in multi-threaded or multisession code. We suggest you capture the return value of the call, and check that instead. */ _PUBLIC_ enum MAPISTATUS GetLastError(void) { return (enum MAPISTATUS)errno; } /** \details Convert an ID to a Long Term Id The function looks up the Long Term Id for a specified ID value. \param obj the object to look up on \param id the id to look up \param long_term_id the long term ID returned from the server \return MAPI_E_SUCCESS on success, otherwise MAPI error. \note Developers may also call GetLastError() to retrieve the last MAPI error code. Possible MAPI error codes are: - MAPI_E_NOT_INITIALIZED: MAPI subsystem has not been initialized - MAPI_E_INVALID_PARAMETER: obj is null - MAPI_E_CALL_FAILED: A network problem was encountered during the transaction \sa GetIdFromLongTermId */ _PUBLIC_ enum MAPISTATUS GetLongTermIdFromId(mapi_object_t *obj, mapi_id_t id, struct LongTermId *long_term_id) { struct mapi_request *mapi_request; struct mapi_response *mapi_response; struct EcDoRpc_MAPI_REQ *mapi_req; struct LongTermIdFromId_req request; struct mapi_session *session; NTSTATUS status; TALLOC_CTX *mem_ctx; uint32_t size = 0; enum MAPISTATUS retval; int i; uint8_t logon_id = 0; /* Sanity checks */ OPENCHANGE_RETVAL_IF(!obj, MAPI_E_INVALID_PARAMETER, NULL); session = mapi_object_get_session(obj); OPENCHANGE_RETVAL_IF(!session, MAPI_E_INVALID_PARAMETER, NULL); if ((retval = mapi_object_get_logon_id(obj, &logon_id)) != MAPI_E_SUCCESS) return retval; mem_ctx = talloc_named(session, 0, "LongTermIdFromId"); /* Fill the LongTermIdFromId operation */ request.Id = id; size += sizeof(mapi_id_t); /* Fill the MAPI_REQ request */ mapi_req = talloc_zero(mem_ctx, struct EcDoRpc_MAPI_REQ); mapi_req->opnum = op_MAPI_LongTermIdFromId; mapi_req->logon_id = logon_id; mapi_req->handle_idx = 0; mapi_req->u.mapi_LongTermIdFromId = request; size += 5; /* Fill the mapi_request structure */ mapi_request = talloc_zero(mem_ctx, struct mapi_request); mapi_request->mapi_len = size + sizeof (uint32_t); mapi_request->length = (uint16_t)size; mapi_request->mapi_req = mapi_req; mapi_request->handles = talloc_array(mem_ctx, uint32_t, 1); mapi_request->handles[0] = mapi_object_get_handle(obj); status = emsmdb_transaction_wrapper(session, mem_ctx, mapi_request, &mapi_response); OPENCHANGE_RETVAL_IF(!NT_STATUS_IS_OK(status), MAPI_E_CALL_FAILED, mem_ctx); OPENCHANGE_RETVAL_IF(!mapi_response->mapi_repl, MAPI_E_CALL_FAILED, mem_ctx); retval = mapi_response->mapi_repl->error_code; OPENCHANGE_RETVAL_IF(retval, retval, mem_ctx); OPENCHANGE_CHECK_NOTIFICATION(session, mapi_response); long_term_id->DatabaseGuid = mapi_response->mapi_repl->u.mapi_LongTermIdFromId.LongTermId.DatabaseGuid; for (i = 0; i < 6; ++i) { long_term_id->GlobalCounter[i] = mapi_response->mapi_repl->u.mapi_LongTermIdFromId.LongTermId.GlobalCounter[i]; } long_term_id->padding = 0x0; talloc_free(mapi_response); talloc_free(mem_ctx); errno = 0; return MAPI_E_SUCCESS; } /** \details Convert an Long Term Id into an Id The function looks up the Id for a specified Long Term Id value. \param obj the object to look up on \param long_term_id the id to look up \param id the id returned by the server \return MAPI_E_SUCCESS on success, otherwise MAPI error. \note Developers may also call GetLastError() to retrieve the last MAPI error code. Possible MAPI error codes are: - MAPI_E_NOT_INITIALIZED: MAPI subsystem has not been initialized - MAPI_E_INVALID_PARAMETER: obj is null - MAPI_E_CALL_FAILED: A network problem was encountered during the transaction \sa GetLongTermIdFromId */ _PUBLIC_ enum MAPISTATUS GetIdFromLongTermId(mapi_object_t *obj, struct LongTermId long_term_id, mapi_id_t *id) { struct mapi_request *mapi_request; struct mapi_response *mapi_response; struct EcDoRpc_MAPI_REQ *mapi_req; struct IdFromLongTermId_req request; struct mapi_session *session; NTSTATUS status; TALLOC_CTX *mem_ctx; uint32_t size = 0; enum MAPISTATUS retval; uint8_t logon_id = 0; /* Sanity checks */ OPENCHANGE_RETVAL_IF(!obj, MAPI_E_INVALID_PARAMETER, NULL); session = mapi_object_get_session(obj); OPENCHANGE_RETVAL_IF(!session, MAPI_E_INVALID_PARAMETER, NULL); if ((retval = mapi_object_get_logon_id(obj, &logon_id)) != MAPI_E_SUCCESS) return retval; mem_ctx = talloc_named(session, 0, "IdFromLongTermId"); size = 0; /* Fill the IdFromLongTermId operation */ request.LongTermId = long_term_id; size += sizeof(struct LongTermId); /* Fill the MAPI_REQ request */ mapi_req = talloc_zero(mem_ctx, struct EcDoRpc_MAPI_REQ); mapi_req->opnum = op_MAPI_IdFromLongTermId; mapi_req->logon_id = logon_id; mapi_req->handle_idx = 0; mapi_req->u.mapi_IdFromLongTermId = request; size += 5; /* Fill the mapi_request structure */ mapi_request = talloc_zero(mem_ctx, struct mapi_request); mapi_request->mapi_len = size + sizeof (uint32_t); mapi_request->length = (uint16_t)size; mapi_request->mapi_req = mapi_req; mapi_request->handles = talloc_array(mem_ctx, uint32_t, 1); mapi_request->handles[0] = mapi_object_get_handle(obj); status = emsmdb_transaction_wrapper(session, mem_ctx, mapi_request, &mapi_response); OPENCHANGE_RETVAL_IF(!NT_STATUS_IS_OK(status), MAPI_E_CALL_FAILED, mem_ctx); OPENCHANGE_RETVAL_IF(!mapi_response->mapi_repl, MAPI_E_CALL_FAILED, mem_ctx); retval = mapi_response->mapi_repl->error_code; OPENCHANGE_RETVAL_IF(retval, retval, mem_ctx); OPENCHANGE_CHECK_NOTIFICATION(session, mapi_response); *id = mapi_response->mapi_repl->u.mapi_IdFromLongTermId.Id; talloc_free(mapi_response); talloc_free(mem_ctx); errno = 0; return MAPI_E_SUCCESS; } openchange-2.0/libmapi/IXPLogon.c000066400000000000000000000310331223057412600167040ustar00rootroot00000000000000/* OpenChange MAPI implementation. Copyright (C) Julien Kerihuel 2008. This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see . */ #include "libmapi/libmapi.h" #include "libmapi/libmapi_private.h" /** \file IXPLogon.c \brief Transport provider status information */ /** \details Returns the types of recipients that the transport provider handles. \param obj_store the object to get recipients types from \param lpcAdrType the count of recipients types returned \param lpAdrTypeArray pointer on pointer of returned transport provider types \return MAPI_E_SUCCESS on success, otherwise MAPI error. \note Developers may also call GetLastError() to retrieve the last MAPI error code. Possible MAPI error codes are: - MAPI_E_NOT_INITIALIZED: MAPI subsystem has not been initialized - MAPI_E_INVALID_PARAMETER: obj_store is not initialized - MAPI_E_CALL_FAILED: A network problem was encountered during the transaction */ _PUBLIC_ enum MAPISTATUS AddressTypes(mapi_object_t *obj_store, uint16_t *lpcAdrType, struct mapi_LPSTR **lpAdrTypeArray) { struct mapi_request *mapi_request; struct mapi_response *mapi_response; struct EcDoRpc_MAPI_REQ *mapi_req; struct AddressTypes_repl *response; struct mapi_session *session; NTSTATUS status; enum MAPISTATUS retval; uint32_t size; TALLOC_CTX *mem_ctx; uint8_t logon_id = 0; /* Sanity checks */ OPENCHANGE_RETVAL_IF(!obj_store, MAPI_E_INVALID_PARAMETER, NULL); session = mapi_object_get_session(obj_store); OPENCHANGE_RETVAL_IF(!session, MAPI_E_INVALID_PARAMETER, NULL); if ((retval = mapi_object_get_logon_id(obj_store, &logon_id)) != MAPI_E_SUCCESS) return retval; mem_ctx = talloc_named(session, 0, "AddressTypes"); size = 0; /* Fill the MAPI_REQ request */ mapi_req = talloc_zero(mem_ctx, struct EcDoRpc_MAPI_REQ); mapi_req->opnum = op_MAPI_AddressTypes; mapi_req->logon_id = logon_id; mapi_req->handle_idx = 0; size += 5; /* Fill the mapi_request structure */ mapi_request = talloc_zero(mem_ctx, struct mapi_request); mapi_request->mapi_len = size + sizeof (uint32_t); mapi_request->length = size; mapi_request->mapi_req = mapi_req; mapi_request->handles = talloc_array(mem_ctx, uint32_t, 1); mapi_request->handles[0] = mapi_object_get_handle(obj_store); status = emsmdb_transaction_wrapper(session, mem_ctx, mapi_request, &mapi_response); OPENCHANGE_RETVAL_IF(!NT_STATUS_IS_OK(status), MAPI_E_CALL_FAILED, mem_ctx); OPENCHANGE_RETVAL_IF(!mapi_response->mapi_repl, MAPI_E_CALL_FAILED, mem_ctx); retval = mapi_response->mapi_repl->error_code; OPENCHANGE_RETVAL_IF(retval, retval, mem_ctx); OPENCHANGE_CHECK_NOTIFICATION(session, mapi_response); /* Retrieve Address Types */ response = &mapi_response->mapi_repl->u.mapi_AddressTypes; *lpcAdrType = response->cValues; *lpAdrTypeArray = talloc_steal((TALLOC_CTX *)session, response->transport); talloc_free(mapi_response); talloc_free(mem_ctx); return MAPI_E_SUCCESS; } /** \details Informs the server that the client intends to act as a mail spooler. \param obj_store: the object server store object \return MAPI_E_SUCCESS on success, otherwise MAPI error. \note Developers may also call GetLastError() to retrieve the last MAPI error code. Possible MAPI error codes are: - MAPI_E_NOT_INITIALIZED: MAPI subsystem has not been initialized - MAPI_E_INVALID_PARAMETER: obj_store is not initialized - MAPI_E_CALL_FAILED: A network problem was encountered during the transaction \sa SpoolerLockMessage */ _PUBLIC_ enum MAPISTATUS SetSpooler(mapi_object_t *obj_store) { struct mapi_request *mapi_request; struct mapi_response *mapi_response; struct EcDoRpc_MAPI_REQ *mapi_req; struct mapi_session *session; NTSTATUS status; enum MAPISTATUS retval; uint32_t size = 0; TALLOC_CTX *mem_ctx; uint8_t logon_id = 0; /* Sanity checks */ OPENCHANGE_RETVAL_IF(!obj_store, MAPI_E_INVALID_PARAMETER, NULL); session = mapi_object_get_session(obj_store); OPENCHANGE_RETVAL_IF(!session, MAPI_E_INVALID_PARAMETER, NULL); if ((retval = mapi_object_get_logon_id(obj_store, &logon_id)) != MAPI_E_SUCCESS) return retval; mem_ctx = talloc_named(session, 0, "SetSpooler"); size = 0; /* Fill the MAPI_REQ request */ mapi_req = talloc_zero(mem_ctx, struct EcDoRpc_MAPI_REQ); mapi_req->opnum = op_MAPI_SetSpooler; mapi_req->logon_id = logon_id; mapi_req->handle_idx = 0; size += 5; /* Fill the mapi_request structure */ mapi_request = talloc_zero(mem_ctx, struct mapi_request); mapi_request->mapi_len = size + sizeof (uint32_t); mapi_request->length = size; mapi_request->mapi_req = mapi_req; mapi_request->handles = talloc_array(mem_ctx, uint32_t, 1); mapi_request->handles[0] = mapi_object_get_handle(obj_store); status = emsmdb_transaction_wrapper(session, mem_ctx, mapi_request, &mapi_response); OPENCHANGE_RETVAL_IF(!NT_STATUS_IS_OK(status), MAPI_E_CALL_FAILED, mem_ctx); OPENCHANGE_RETVAL_IF(!mapi_response->mapi_repl, MAPI_E_CALL_FAILED, mem_ctx); retval = mapi_response->mapi_repl->error_code; OPENCHANGE_RETVAL_IF(retval, retval, mem_ctx); OPENCHANGE_CHECK_NOTIFICATION(session, mapi_response); talloc_free(mapi_response); talloc_free(mem_ctx); return MAPI_E_SUCCESS; } /** \details Locks the specified message for spooling. \param obj_store the store object \param obj_message the message object we want to lock \param lockstate the lock state Possible values for the lock state: -# LockState_1stLock (0x0): Mark the message as locked -# LockState_1stUnlock (0x1): Mark the message as unlocked -# LockState_1stFinished (0x2): Mark the message as ready for processing by the server \return MAPI_E_SUCCESS on success, otherwise MAPI error. \note Developers may also call GetLastError() to retrieve the last MAPI error code. Possible MAPI error codes are: - MAPI_E_NOT_INITIALIZED: MAPI subsystem has not been initialized - MAPI_E_INVALID_PARAMETER: obj_store is not initialized - MAPI_E_CALL_FAILED: A network problem was encountered during the transaction \sa SetSPooler */ _PUBLIC_ enum MAPISTATUS SpoolerLockMessage(mapi_object_t *obj_store, mapi_object_t *obj_message, enum LockState lockstate) { struct mapi_request *mapi_request; struct mapi_response *mapi_response; struct EcDoRpc_MAPI_REQ *mapi_req; struct SpoolerLockMessage_req request; struct mapi_session *session; NTSTATUS status; enum MAPISTATUS retval; uint32_t size = 0; TALLOC_CTX *mem_ctx; uint8_t logon_id = 0; /* Sanity checks */ OPENCHANGE_RETVAL_IF(!obj_store, MAPI_E_INVALID_PARAMETER, NULL); OPENCHANGE_RETVAL_IF(!obj_message, MAPI_E_INVALID_PARAMETER, NULL); OPENCHANGE_RETVAL_IF(lockstate > 2, MAPI_E_INVALID_PARAMETER, NULL); session = mapi_object_get_session(obj_store); OPENCHANGE_RETVAL_IF(!session, MAPI_E_INVALID_PARAMETER, NULL); if ((retval = mapi_object_get_logon_id(obj_store, &logon_id)) != MAPI_E_SUCCESS) return retval; mem_ctx = talloc_named(session, 0, "SpoolerLockMessage"); size = 0; /* Fill the SpoolerLockMessage operation */ request.MessageId = mapi_object_get_id(obj_message); size += sizeof (uint64_t); request.LockState = lockstate; size += sizeof (uint8_t); /* Fill the MAPI_REQ request */ mapi_req = talloc_zero(mem_ctx, struct EcDoRpc_MAPI_REQ); mapi_req->opnum = op_MAPI_SpoolerLockMessage; mapi_req->logon_id = logon_id; mapi_req->handle_idx = 0; mapi_req->u.mapi_SpoolerLockMessage = request; size += 5; /* Fill the mapi_request structure */ mapi_request = talloc_zero(mem_ctx, struct mapi_request); mapi_request->mapi_len = size + sizeof (uint32_t); mapi_request->length = size; mapi_request->mapi_req = mapi_req; mapi_request->handles = talloc_array(mem_ctx, uint32_t, 1); mapi_request->handles[0] = mapi_object_get_handle(obj_store); status = emsmdb_transaction_wrapper(session, mem_ctx, mapi_request, &mapi_response); OPENCHANGE_RETVAL_IF(!NT_STATUS_IS_OK(status), MAPI_E_CALL_FAILED, mem_ctx); OPENCHANGE_RETVAL_IF(!mapi_response->mapi_repl, MAPI_E_CALL_FAILED, mem_ctx); retval = mapi_response->mapi_repl->error_code; OPENCHANGE_RETVAL_IF(retval, retval, mem_ctx); OPENCHANGE_CHECK_NOTIFICATION(session, mapi_response); talloc_free(mapi_response); talloc_free(mem_ctx); return MAPI_E_SUCCESS; } /** \details Returns options information for the types of recipients that the transport provider handles. \param [in] obj_store the object to get recipients types from \param [in] addrtype string name of the address type to get options for \param [out] OptionsData the options data for this addrtype \param [out] OptionsLength length of the OptionsData array \param [out] HelpFile the help file data for this addrtype (often empty) \param [out] HelpFileLength length of the HelpFile array \param [out] HelpFileName the name of the help file (often null) The caller is responsible for talloc_free()ing the OptionsData array. \return MAPI_E_SUCCESS on success, otherwise MAPI error. \note Developers may also call GetLastError() to retrieve the last MAPI error code. Possible MAPI error codes are: - MAPI_E_NOT_INITIALIZED: MAPI subsystem has not been initialized - MAPI_E_INVALID_PARAMETER: obj_store is not initialized - MAPI_E_CALL_FAILED: A network problem was encountered during the transaction */ _PUBLIC_ enum MAPISTATUS OptionsData(mapi_object_t *obj_store, const char *addrtype, uint8_t **OptionsData, uint16_t *OptionsLength, uint8_t **HelpFile, uint16_t *HelpFileLength, const char** HelpFileName) { struct mapi_session *session; TALLOC_CTX *mem_ctx; uint32_t size; struct OptionsData_req request; struct mapi_request *mapi_request; struct mapi_response *mapi_response; struct EcDoRpc_MAPI_REQ *mapi_req; struct OptionsData_repl *response; NTSTATUS status; enum MAPISTATUS retval; uint8_t logon_id = 0; /* Sanity checks */ OPENCHANGE_RETVAL_IF(!obj_store, MAPI_E_INVALID_PARAMETER, NULL); OPENCHANGE_RETVAL_IF(!addrtype, MAPI_E_INVALID_PARAMETER, NULL); session = mapi_object_get_session(obj_store); OPENCHANGE_RETVAL_IF(!session, MAPI_E_INVALID_PARAMETER, NULL); if ((retval = mapi_object_get_logon_id(obj_store, &logon_id)) != MAPI_E_SUCCESS) return retval; mem_ctx = talloc_named(session, 0, "RecipientOptions"); size = 0; /* Build the OptionsData request */ request.AddressType = addrtype; size += strlen(addrtype) + 1; request.WantWin32 = 0x1; size += sizeof (uint8_t); /* Fill the MAPI_REQ request */ mapi_req = talloc_zero(mem_ctx, struct EcDoRpc_MAPI_REQ); mapi_req->opnum = op_MAPI_OptionsData; mapi_req->logon_id = logon_id; mapi_req->handle_idx = 0; mapi_req->u.mapi_OptionsData = request; size += 5; /* Fill the mapi_request structure */ mapi_request = talloc_zero(mem_ctx, struct mapi_request); mapi_request->mapi_len = size + sizeof (uint32_t); mapi_request->length = size; mapi_request->mapi_req = mapi_req; mapi_request->handles = talloc_array(mem_ctx, uint32_t, 1); mapi_request->handles[0] = mapi_object_get_handle(obj_store); status = emsmdb_transaction_wrapper(session, mem_ctx, mapi_request, &mapi_response); OPENCHANGE_RETVAL_IF(!NT_STATUS_IS_OK(status), MAPI_E_CALL_FAILED, mem_ctx); OPENCHANGE_RETVAL_IF(!mapi_response->mapi_repl, MAPI_E_CALL_FAILED, mem_ctx); retval = mapi_response->mapi_repl->error_code; OPENCHANGE_RETVAL_IF(retval, retval, mem_ctx); /* Retrieve the Options Data */ response = &mapi_response->mapi_repl->u.mapi_OptionsData; *OptionsLength = response->OptionsInfo.cb; *OptionsData = talloc_steal((TALLOC_CTX *)session, response->OptionsInfo.lpb); *HelpFileLength = response->HelpFileSize; *HelpFile = talloc_steal((TALLOC_CTX *)session, response->HelpFile); if (*HelpFileLength != 0) { *HelpFileName = talloc_steal((TALLOC_CTX *)session, response->HelpFileName.HelpFileName); } else { *HelpFileName = 0; } talloc_free(mapi_response); talloc_free(mem_ctx); return MAPI_E_SUCCESS; } openchange-2.0/libmapi/async_emsmdb.c000066400000000000000000000050171223057412600177140ustar00rootroot00000000000000/* OpenChange MAPI implementation. Copyright (C) Brad Hards 2010. This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see . */ #include "libmapi/libmapi.h" #include "libmapi/libmapi_private.h" #include "gen_ndr/ndr_exchange.h" #include "gen_ndr/ndr_exchange_c.h" /** \file async_emsmdb.c \brief Async_EMSMDB stack functions */ /** \details Create an asynchronous wait call This basically "parks" a call on the AsyncEMSMDB interface to allow asynchronous notification to the client of changes on the server. This call (probably) won't return immediately, but will return when the server makes a change, or 300 seconds (5 minutes) elapses. This call will then need to be re-queued if further change notifications are wanted. \param emsmdb_ctx pointer to the EMSMDB context \param flagsIn input flags (currently must be 0x00000000) \param flagsOut output flags (zero for a call completion with no changes, non-zero if there are changes) \return MAPI_E_SUCCESS on success, otherwise MAPI error */ enum MAPISTATUS emsmdb_async_waitex(struct emsmdb_context *emsmdb_ctx, uint32_t flagsIn, uint32_t *flagsOut) { NTSTATUS status; enum MAPISTATUS retval; struct EcDoAsyncWaitEx r; /* Sanity Checks */ OPENCHANGE_RETVAL_IF(!emsmdb_ctx, MAPI_E_NOT_INITIALIZED, NULL); OPENCHANGE_RETVAL_IF(!(emsmdb_ctx->mem_ctx), MAPI_E_NOT_INITIALIZED, NULL); OPENCHANGE_RETVAL_IF(!(emsmdb_ctx->async_rpc_connection), MAPI_E_NOT_INITIALIZED, NULL); r.in.async_handle = &(emsmdb_ctx->async_handle); r.in.ulFlagsIn = flagsIn; r.out.pulFlagsOut = flagsOut; dcerpc_binding_handle_set_timeout(emsmdb_ctx->async_rpc_connection->binding_handle, 400); status = dcerpc_EcDoAsyncWaitEx_r(emsmdb_ctx->async_rpc_connection->binding_handle, emsmdb_ctx->mem_ctx, &r); retval = r.out.result; OPENCHANGE_RETVAL_IF(!NT_STATUS_IS_OK(status), retval, NULL); OPENCHANGE_RETVAL_IF(retval, retval, NULL); return MAPI_E_SUCCESS; } openchange-2.0/libmapi/cdo_mapi.c000066400000000000000000000252711223057412600170270ustar00rootroot00000000000000/* OpenChange MAPI implementation. Copyright (C) Julien Kerihuel 2007-2010. Copyright (C) Fabien Le Mentec 2007. This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see . */ #include "libmapi/libmapi.h" #include "libmapi/libmapi_private.h" #include #include /** \file cdo_mapi.c \brief MAPI subsystem related operations */ /** \details Create a full MAPI session Open providers stored in the profile and return a pointer on a IMAPISession object. \param mapi_ctx pointer to the MAPI context \param session pointer to a pointer to a MAPI session object \param profname profile name to use \param password password to use for the profile password should be set to NULL if the password has been stored in the profile. \return MAPI_E_SUCCESS on success otherwise MAPI error. \note Developers may also call GetLastError() to retrieve the last MAPI error code. Possible MAPI error codes are: - MAPI_E_NOT_INITIALIZED: MAPI subsystem has not been initialized - MAPI_E_NOT_ENOUGH_RESOURCES: MAPI subsystem failed to allocate the necessary resources to operate properly - MAPI_E_CALL_FAILED: A network problem was encountered during the transaction \sa MAPIInitialize, OpenProfile, MapiLogonProvider */ _PUBLIC_ enum MAPISTATUS MapiLogonEx(struct mapi_context *mapi_ctx, struct mapi_session **session, const char *profname, const char *password) { struct mapi_session *tmp_session = NULL; enum MAPISTATUS retval; retval = MapiLogonProvider(mapi_ctx, &tmp_session, profname, password, PROVIDER_ID_NSPI); if (retval != MAPI_E_SUCCESS) return retval; retval = MapiLogonProvider(mapi_ctx, &tmp_session, profname, password, PROVIDER_ID_EMSMDB); if (retval != MAPI_E_SUCCESS) return retval; *session = tmp_session; return MAPI_E_SUCCESS; } /** \details Initialize a session on the specified provider \param mapi_ctx pointer to the MAPI context \param session pointer to a pointer to a MAPI session object \param profname profile name \param password profile password \param provider provider we want to establish a connection on password should be set to NULL if the password has been stored in the profile. Supported providers are: - PROVIDER_ID_NSPI: Address Book provider - PROVIDER_ID_EMSMDB: MAPI Store provider \return MAPI_E_SUCCESS on success, otherwise MAPI error. \note Developers may also call GetLastError() to retrieve the last MAPI error code. Possible MAPI error codes are: - MAPI_E_NOT_INITIALIZED: MAPI subsystem has not been initialized - MAPI_E_NOT_ENOUGH_RESOURCES: MAPI subsystem failed to allocate the necessary resources to operate properly - MAPI_E_CALL_FAILED: A network problem was encountered during the transaction \sa MapiLogonEx, OpenProfile, LoadProfile */ _PUBLIC_ enum MAPISTATUS MapiLogonProvider(struct mapi_context *mapi_ctx, struct mapi_session **session, const char *profname, const char *password, enum PROVIDER_ID provider) { TALLOC_CTX *mem_ctx; enum MAPISTATUS retval; struct mapi_provider *provider_emsmdb; struct mapi_provider *provider_nspi; struct mapi_profile *profile; struct mapi_session *el; bool found = false; bool exist = false; /* Sanity checks */ OPENCHANGE_RETVAL_IF(!mapi_ctx, MAPI_E_NOT_INITIALIZED, NULL); OPENCHANGE_RETVAL_IF(!session, MAPI_E_NOT_INITIALIZED, NULL); /* If no MAPI session has already been created */ if (!mapi_ctx->session) { mapi_ctx->session = talloc_zero(mapi_ctx->mem_ctx, struct mapi_session); } /* If the session doesn't exist, create a new one */ if (!*session) { el = talloc_zero(mapi_ctx->mem_ctx, struct mapi_session); memset(el->logon_ids, 0, 255); el->mapi_ctx = mapi_ctx; OPENCHANGE_RETVAL_IF(!el, MAPI_E_NOT_ENOUGH_RESOURCES, NULL); } else { /* Lookup the session within the chained list */ for (el = mapi_ctx->session; el; el = el->next) { if (*session == el) { found = true; break; } } OPENCHANGE_RETVAL_IF(found == false, MAPI_E_NOT_FOUND, NULL); exist = true; } mem_ctx = (TALLOC_CTX *) el; /* Open the profile */ if (!el->profile) { profile = talloc_zero(mem_ctx, struct mapi_profile); OPENCHANGE_RETVAL_IF(!profile, MAPI_E_NOT_ENOUGH_RESOURCES, el); retval = OpenProfile(mapi_ctx, profile, profname, password); OPENCHANGE_RETVAL_IF(retval, retval, el); retval = LoadProfile(mapi_ctx, profile); OPENCHANGE_RETVAL_IF(retval, retval, el); el->profile = profile; } switch (provider) { case PROVIDER_ID_EMSMDB: provider_emsmdb = talloc_zero(mem_ctx, struct mapi_provider); OPENCHANGE_RETVAL_IF(!provider_emsmdb, MAPI_E_NOT_ENOUGH_RESOURCES, NULL); talloc_set_destructor((void *)provider_emsmdb, (int (*)(void *))emsmdb_disconnect_dtor); retval = Logon(el, provider_emsmdb, PROVIDER_ID_EMSMDB); if (retval) return retval; el->emsmdb = provider_emsmdb; break; case PROVIDER_ID_NSPI: provider_nspi = talloc_zero(mem_ctx, struct mapi_provider); OPENCHANGE_RETVAL_IF(!provider_nspi, MAPI_E_NOT_ENOUGH_RESOURCES, NULL); talloc_set_destructor((void *)provider_nspi, (int (*)(void *))nspi_disconnect_dtor); retval = Logon(el, provider_nspi, PROVIDER_ID_NSPI); if (retval) return retval; el->nspi = provider_nspi; break; default: OPENCHANGE_RETVAL_IF(1, MAPI_E_NO_SUPPORT, el); break; } /* Add the element to the session list */ if (exist == false) { DLIST_ADD(mapi_ctx->session, el); *session = el; } return MAPI_E_SUCCESS; } /** \details Initialize mapi context structure This function inititalizes the MAPI subsystem and open the profile database pointed by profiledb . \param _mapi_ctx pointer to the MAPI context \param profiledb profile database path \return MAPI_E_SUCCESS on success, otherwise MAPI error. \note Developers may also call GetLastError() to retrieve the last MAPI error code. Possible MAPI error codes are: - MAPI_E_NOT_INITIALIZED: MAPI subsystem has not been initialized - MAPI_E_NOT_ENOUGH_RESOURCES: MAPI subsystem failed to allocate the necessary resources to operate properly - MAPI_E_NOT_FOUND: No suitable profile database was found in the path pointed by profiledb - MAPI_E_CALL_FAILED: A network problem was encountered during the transaction \sa MAPIUninitialize */ _PUBLIC_ enum MAPISTATUS MAPIInitialize(struct mapi_context **_mapi_ctx, const char *profiledb) { enum MAPISTATUS retval; struct mapi_context *mapi_ctx; TALLOC_CTX *mem_ctx; /* Set the initial errno value for GetLastError */ errno = 0; OPENCHANGE_RETVAL_IF(!_mapi_ctx, MAPI_E_INVALID_PARAMETER, NULL); OPENCHANGE_RETVAL_IF(!profiledb, MAPI_E_INVALID_PARAMETER, NULL); mem_ctx = talloc_named(NULL, 0, "MAPIInitialize"); OPENCHANGE_RETVAL_IF(!mem_ctx, MAPI_E_NOT_ENOUGH_RESOURCES, NULL); mapi_ctx = talloc_zero(mem_ctx, struct mapi_context); OPENCHANGE_RETVAL_IF(!mapi_ctx, MAPI_E_NOT_ENOUGH_RESOURCES, mem_ctx); mapi_ctx->mem_ctx = mem_ctx; mapi_ctx->dumpdata = false; mapi_ctx->session = NULL; mapi_ctx->lp_ctx = loadparm_init_global(true); /* Enable logging on stdout */ setup_logging(NULL, DEBUG_STDOUT); /* profile store */ retval = OpenProfileStore(mapi_ctx, &mapi_ctx->ldb_ctx, profiledb); OPENCHANGE_RETVAL_IF(retval, retval, mem_ctx); /* Initialize dcerpc subsystem */ dcerpc_init(); errno = 0; *_mapi_ctx = mapi_ctx; return MAPI_E_SUCCESS; } /** \details Uninitialize MAPI subsystem \param mapi_ctx pointer to the MAPI context This function uninitializes the MAPI context and destroy recursively the whole mapi session and associated objects hierarchy \sa MAPIInitialize, GetLastError */ _PUBLIC_ void MAPIUninitialize(struct mapi_context *mapi_ctx) { TALLOC_CTX *mem_ctx; struct mapi_session *session; if (!mapi_ctx) return; session = mapi_ctx->session; if (session && session->notify_ctx && session->notify_ctx->fd != -1) { DEBUG(3, ("emsmdb_disconnect_dtor: unbind udp\n")); shutdown(session->notify_ctx->fd, SHUT_RDWR); close(session->notify_ctx->fd); } mem_ctx = mapi_ctx->mem_ctx; talloc_free(mem_ctx); mapi_ctx = NULL; } /** \details Enable MAPI network trace output \param mapi_ctx pointer to the MAPI context \param status the status possible status values/behavior: -# true: Network traces are displayed on stdout -# false: Network traces are not displayed on stdout \return MAPI_E_SUCCESS on success, otherwise MAPI_E_NOT_INITIALIZED */ _PUBLIC_ enum MAPISTATUS SetMAPIDumpData(struct mapi_context *mapi_ctx, bool status) { /* Sanity checks */ OPENCHANGE_RETVAL_IF(!mapi_ctx, MAPI_E_NOT_INITIALIZED, NULL); mapi_ctx->dumpdata = status; return MAPI_E_SUCCESS; } /** \details Set MAPI debug level \param mapi_ctx pointer to the MAPI context \param level the debug level to set \return MAPI_E_SUCCESS on success, otherwise MAPI error. \note Developers may also call GetLastError() to retrieve the last MAPI error code. Possible MAPI error codes are: - MAPI_E_NOT_INITIALIZED: MAPI subsystem has not been initialized - MAPI_E_INVALID_PARAMETER: the function parameter is invalid */ _PUBLIC_ enum MAPISTATUS SetMAPIDebugLevel(struct mapi_context *mapi_ctx, uint32_t level) { char *debuglevel; bool ret; /* Sanity checks */ OPENCHANGE_RETVAL_IF(!mapi_ctx, MAPI_E_NOT_INITIALIZED, NULL); debuglevel = talloc_asprintf(mapi_ctx->mem_ctx, "%u", level); ret = lpcfg_set_cmdline(mapi_ctx->lp_ctx, "log level", debuglevel); talloc_free(debuglevel); return (ret == true) ? MAPI_E_SUCCESS : MAPI_E_INVALID_PARAMETER; } /** \details Retrieve the MAPI loadparm context for specified MAPI context \param mapi_ctx pointer to the MAPI context \param lp_ctx pointer to a pointer to the loadparm context that the function returns \return MAPI_E_SUCCESS on success, otherwise MAPI_E_NOT_INITIALIZED or MAPI_E_INVALID_PARAMETER */ _PUBLIC_ enum MAPISTATUS GetLoadparmContext(struct mapi_context *mapi_ctx, struct loadparm_context **lp_ctx) { /* Sanity checks */ OPENCHANGE_RETVAL_IF(!mapi_ctx, MAPI_E_NOT_INITIALIZED, NULL); OPENCHANGE_RETVAL_IF(!lp_ctx, MAPI_E_INVALID_PARAMETER, NULL); *lp_ctx = mapi_ctx->lp_ctx; return MAPI_E_SUCCESS; } openchange-2.0/libmapi/codepage_lcid.c000066400000000000000000000570431223057412600200200ustar00rootroot00000000000000/* parser auto-generated by mparse */ #include "libmapi/libmapi.h" #include "libmapi/libmapi_private.h" #include #include /** \file codepage_lcid.c \brief Codepage and Locale ID operations */ #define CP_UNICODE_ONLY 0 #define CP_WESTERN_EUROPE_AND_US 1 #define CP_CENTRAL_EUROPE 2 #define CP_BALTIC 3 #define CP_GREEK 4 #define CP_CYRILLIC 5 #define CP_TURKIC 6 #define CP_JAPANESE 7 #define CP_KOREAN 8 #define CP_TRADITIONAL_CHINESE 9 #define CP_SIMPLIFIED_CHINESE 10 #define CP_THAI 11 #define CP_HEBREW 12 #define CP_ARABIC 13 #define CP_VIETNAMESE 14 #define CP_INDIC 15 #define CP_GEORGIAN 16 #define CP_ARMENIAN 17 struct cpid_lcid { const char *language; const char *locale; uint32_t lcid; uint32_t cpid; uint32_t language_group; }; static const struct cpid_lcid locales[] = { { "Afrikaans", "af_ZA", 0x0436, 1252, CP_WESTERN_EUROPE_AND_US }, { "Albanian", "sq_AL", 0x041c, 1250, CP_CENTRAL_EUROPE }, { "Amharic (Ethiopia)", "am_ET", 0x045e, 0 , CP_UNICODE_ONLY }, { "Arabic (Algeria)", "ar_DZ", 0x1401, 1256, CP_ARABIC }, { "Arabic (Bahrain)", "ar_BH", 0x3c01, 1256, CP_ARABIC }, { "Arabic (Egypt)", "ar_EG", 0x0c01, 1256, CP_ARABIC }, { "Arabic (Iraq)", "ar_SA", 0x0801, 1256, CP_ARABIC }, { "Arabic (Jordan)", "ar_JO", 0x2c01, 1256, CP_ARABIC }, { "Arabic (Kuwait)", "ar_KW", 0x3401, 1256, CP_ARABIC }, { "Arabic (Lebanon)", "ar_LB", 0x3001, 1256, CP_ARABIC }, { "Arabic (Libya)", "ar_LY", 0x1001, 1256, CP_ARABIC }, { "Arabic (Morocco)", "ar_MA", 0x1801, 1256, CP_ARABIC }, { "Arabic (Oman)", "ar_OM", 0x2001, 1256, CP_ARABIC }, { "Arabic (Qatar)", "ar_QA", 0x4001, 1256, CP_ARABIC }, { "Arabic (Saudi Arabia)", "ar_SA", 0x0401, 1256, CP_ARABIC }, { "Arabic (Syria)", "ar_SY", 0x2801, 1256, CP_ARABIC }, { "Arabic (Tunisia)", "ar_TN", 0x1c01, 1256, CP_ARABIC }, { "Arabic (U.A.E.)", "ar_AE", 0x3801, 1256, CP_ARABIC }, { "Arabic (Yemen)", "ar_YE", 0x2401, 1256, CP_ARABIC }, { "Armenian", "hy_AM", 0x042b, 0 , CP_ARMENIAN }, { "Assamese", "as_IN", 0x044d, 0 , CP_INDIC }, { "Azeri (Cyrillic)", "az_Cyrl_AZ", 0x082c, 1251, CP_CYRILLIC }, { "Azeri (Latin)", "az_Latn_AZ", 0x042c, 1254, CP_TURKIC }, { "Basque", "eu_ES", 0x042d, 1252, CP_WESTERN_EUROPE_AND_US }, { "Belarusian", "be_BY", 0x0423, 1251, CP_CYRILLIC }, { "Bengali (India)", "bn_IN", 0x0445, 0 , CP_INDIC }, { "Bosnian (Bosnia/Herzegovina)", "bs_Latn_BA", 0x141A, 1250, CP_CENTRAL_EUROPE }, { "Breton (France)", "br_FR", 0x047e, 1252, CP_WESTERN_EUROPE_AND_US }, { "Bulgarian", "bg_BG", 0x0402, 1251, CP_CYRILLIC }, { "Catalan", "ca_ES", 0x0403, 1252, CP_WESTERN_EUROPE_AND_US }, { "Chinese (Hong Kong S.A.R.)", "zh_HK", 0x0c04, 950 , CP_TRADITIONAL_CHINESE }, { "Chinese (Macau S.A.R.)", "zh_MO", 0x1404, 950 , CP_TRADITIONAL_CHINESE }, { "Chinese (PRC)", "zh_CN", 0x0804, 936 , CP_SIMPLIFIED_CHINESE }, { "Chinese (Singapore)", "zh_SG", 0x1004, 936 , CP_SIMPLIFIED_CHINESE }, { "Chinese (Taiwan)", "zh_TW", 0x0404, 950 , CP_TRADITIONAL_CHINESE }, { "Croatian", "hr_HR", 0x041a, 1250, CP_CENTRAL_EUROPE }, { "Croatian (Bosnia/Herzegovina)", "hr_BA", 0x101a, 1250, CP_CENTRAL_EUROPE }, { "Czech", "cz_CZ", 0x0405, 1250, CP_CENTRAL_EUROPE }, { "Danish", "da_DK", 0x0406, 1252, CP_WESTERN_EUROPE_AND_US }, { "Dari (Afghanistan)", "gbz_AF", 0x048c, 1256, CP_ARABIC }, { "Divehi", "dv_MV", 0x0465, 0 , CP_UNICODE_ONLY }, { "Dutch (Belgium)", "nl_BE", 0x0813, 1252, CP_WESTERN_EUROPE_AND_US }, { "Dutch (Netherlands)", "nl_NL", 0x0413, 1252, CP_WESTERN_EUROPE_AND_US }, { "English (Australia)", "en_AU", 0x0c09, 1252, CP_WESTERN_EUROPE_AND_US }, { "English (Belize)", "en_BZ", 0x2809, 1252, CP_WESTERN_EUROPE_AND_US }, { "English (Canada)", "en_CA", 0x1009, 1252, CP_WESTERN_EUROPE_AND_US }, { "English (Caribbean)", "en_CB", 0x2409, 1252, CP_WESTERN_EUROPE_AND_US }, { "English (India)", "en_IN", 0x4009, 1252, CP_WESTERN_EUROPE_AND_US }, { "English (Ireland)", "en_IE", 0x1809, 1252, CP_WESTERN_EUROPE_AND_US }, { "English (Jamaica)", "en_JM", 0x2009, 1252, CP_WESTERN_EUROPE_AND_US }, { "English (New Zealand)", "en_NZ", 0x1409, 1252, CP_WESTERN_EUROPE_AND_US }, { "English (Philippines)", "en_PH", 0x3409, 1252, CP_WESTERN_EUROPE_AND_US }, { "English (South Africa)", "en_ZA", 0x1c09, 1252, CP_WESTERN_EUROPE_AND_US }, { "English (Trinidad)", "en_TT", 0x2c09, 1252, CP_WESTERN_EUROPE_AND_US }, { "English (United Kingdom)", "en_GB", 0x0809, 1252, CP_WESTERN_EUROPE_AND_US }, { "English (United States)", "en_US", 0x0409, 1252, CP_WESTERN_EUROPE_AND_US }, { "English (Zimbabwe)", "en_ZW", 0x3009, 1252, CP_WESTERN_EUROPE_AND_US }, { "Estonian", "et_EE", 0x0425, 1257, CP_BALTIC }, { "Faroese", "fo_FO", 0x0438, 1252, CP_WESTERN_EUROPE_AND_US }, { "Farsi", "fa_IR", 0x0429, 1256, CP_ARABIC }, { "Filipino", "fil_PH", 0x0464, 1252, CP_WESTERN_EUROPE_AND_US }, { "Finnish", "fi_FI", 0x040b, 1252, CP_WESTERN_EUROPE_AND_US }, { "French (Belgium)", "fr_BE", 0x080c, 1252, CP_WESTERN_EUROPE_AND_US }, { "French (Cameroon)", "fr_CM", 0x2c0c, 1252, CP_WESTERN_EUROPE_AND_US }, { "French (Canada)", "fr_CA", 0x0c0c, 1252, CP_WESTERN_EUROPE_AND_US }, { "French (Congo,DRC)", "fr_CG", 0x240c, 1252, CP_WESTERN_EUROPE_AND_US }, { "French (Cote d'Ivoire)", "fr_CI", 0x300c, 1252, CP_WESTERN_EUROPE_AND_US }, { "French (France)", "fr_FR", 0x040c, 1252, CP_WESTERN_EUROPE_AND_US }, { "French (Luxembourg)", "fr_LU", 0x140c, 1252, CP_WESTERN_EUROPE_AND_US }, { "French (Mali)", "fr_ML", 0x340c, 1252, CP_WESTERN_EUROPE_AND_US }, { "French (Monaco)", "fr_MC", 0x180c, 1252, CP_WESTERN_EUROPE_AND_US }, { "French (Morocco)", "fr_MA", 0x380c, 1252, CP_WESTERN_EUROPE_AND_US }, { "French (Senegal)", "fr_SN", 0x280c, 1252, CP_WESTERN_EUROPE_AND_US }, { "French (Switzerland)", "fr_CH", 0x100c, 1252, CP_WESTERN_EUROPE_AND_US }, { "French (West Indies)", "fr_West_Indies", 0x1c0c, 1252, CP_WESTERN_EUROPE_AND_US }, { "Frisian (Netherlands)", "fy_NL", 0x0462, 1252, CP_WESTERN_EUROPE_AND_US }, { "FYRO Macedonian", "mk_MK", 0x042f, 1251, CP_CYRILLIC }, { "Gaelic Ireland", "ga_IE", 0x083c, 1252, CP_WESTERN_EUROPE_AND_US }, { "Galician (Spain)", "gl_ES", 0x0456, 1252, CP_WESTERN_EUROPE_AND_US }, { "Georgian", "ka_GE", 0x0437, 0 , CP_GEORGIAN }, { "German (Austria)", "de_AT", 0x0c07, 1252, CP_WESTERN_EUROPE_AND_US }, { "German (Germany)", "de_DE", 0x0407, 1252, CP_WESTERN_EUROPE_AND_US }, { "German (Liechtenstein)", "de_LI", 0x1407, 1252, CP_WESTERN_EUROPE_AND_US }, { "German (Luxembourg)", "de_LU", 0x1007, 1252, CP_WESTERN_EUROPE_AND_US }, { "German (Switzerland)", "de_CH", 0x0807, 1252, CP_WESTERN_EUROPE_AND_US }, { "Greek", "el_GR", 0x0408, 1253, CP_GREEK }, { "Gujarati", "gu_IN", 0x0447, 0 , CP_INDIC }, { "Hebrew", "he_IL", 0x040d, 1255, CP_HEBREW }, { "Hindi", "hi_IN", 0x0439, 0 , CP_INDIC }, { "Hungarian", "hu_HU", 0x040e, 1250, CP_CENTRAL_EUROPE }, { "Icelandic", "is_IS", 0x040f, 1252, CP_WESTERN_EUROPE_AND_US }, { "Igbo (Nigeria)", "ig_NG", 0x0470, 1252, CP_WESTERN_EUROPE_AND_US }, { "Indonesian", "id_ID", 0x0421, 1252, CP_WESTERN_EUROPE_AND_US }, { "Italian (Italy)", "it_IT", 0x0410, 1252, CP_WESTERN_EUROPE_AND_US }, { "Italian (Switzerland)", "it_CH", 0x0810, 1252, CP_WESTERN_EUROPE_AND_US }, { "Japanese", "ja_JP", 0x0411, 932 , CP_JAPANESE }, { "Kannada", "kn_IN", 0x044b, 0 , CP_UNICODE_ONLY }, { "Kazakh", "kk_KZ", 0x043f, 1251, CP_CYRILLIC }, { "Khmer", "km_KH", 0x0453, 0 , CP_UNICODE_ONLY }, { "Konkani", "kok_IN", 0x0457, 0 , CP_INDIC }, { "Korean", "ko_KR", 0x0412, 949 , CP_KOREAN }, { "Kyrgyz (Cyrillic)", "ky_KG", 0x0440, 1251, CP_CYRILLIC }, { "Lao", "lo_LA", 0x0454, 0 , CP_UNICODE_ONLY }, { "Latvian", "lv_LV", 0x0426, 1257, CP_BALTIC }, { "Lithuanian", "lt_LT", 0x0427, 1257, CP_BALTIC }, { "Macedonian", "mk_MK", 0x042f, 1251, CP_CYRILLIC }, { "Malay (Brunei Darussalam)", "ms_BN", 0x083e, 1252, CP_WESTERN_EUROPE_AND_US }, { "Malay (Malaysia)", "ms_MY", 0x043e, 1252, CP_WESTERN_EUROPE_AND_US }, { "Malayalam", "ml_IN", 0x044c, 0 , CP_UNICODE_ONLY }, { "Maltese", "mt_MT", 0x043a, 1252, CP_WESTERN_EUROPE_AND_US }, { "Maori (New Zealand)", "mi_NZ", 0x0481, 1252, CP_WESTERN_EUROPE_AND_US }, { "Marathi", "ms_IN", 0x044e, 0 , CP_INDIC }, { "Mongolian (Cyrillic)", "mn_MN", 0x0450, 1251, CP_CYRILLIC }, { "Mongolian (Mongolia)", "mn_Mong_CN", 0x0850, 0 , CP_UNICODE_ONLY }, { "Nepali", "ne_NP", 0x0461, 0 , CP_UNICODE_ONLY }, { "Norwegian (Bokmal)", "nb_NO", 0x0414, 1252, CP_WESTERN_EUROPE_AND_US }, { "Norwegian (Nynorsk)", "nn_NO", 0x0814, 1252, CP_WESTERN_EUROPE_AND_US }, { "Oriya", "or_IN", 0x0448, 0 , CP_INDIC }, { "Polish", "pl_PL", 0x0415, 1250, CP_CENTRAL_EUROPE }, { "Portuguese (Brazil)", "pt_BR", 0x0416, 1252, CP_WESTERN_EUROPE_AND_US }, { "Portuguese (Portugal)", "pt_PT", 0x0816, 1252, CP_WESTERN_EUROPE_AND_US }, { "Punjabi", "pa_IN", 0x0446, 0 , CP_INDIC }, { "Rhaeto-Romanic", "rm_CH", 0x0417, 1252, CP_WESTERN_EUROPE_AND_US }, { "Romanian", "ro_RM", 0x0418, 1250, CP_CENTRAL_EUROPE }, { "Romanian (Moldova)", "ro_MO", 0x0818, 819 , CP_CENTRAL_EUROPE }, { "Russian", "ru_RU", 0x0419, 1251, CP_CYRILLIC }, { "Sami Lappish", "se_NO", 0x043b, 1252, CP_WESTERN_EUROPE_AND_US }, { "Sanskrit", "sa_IN", 0x044f, 0 , CP_INDIC }, { "Serbian (Cyrillic)", "sr_Cyrl_CS", 0x0c1a, 1251, CP_CYRILLIC }, { "Serbian (Latin)", "sr_Latn_CS", 0x081a, 1250, CP_CENTRAL_EUROPE }, { "Sindhi", "sd_IN", 0x0459, 0 , CP_INDIC }, { "Sinhalese (Sri Lanka)", "si_LK", 0x045b, 0 , CP_UNICODE_ONLY }, { "Slovak", "sk_SK", 0x041b, 1250, CP_CENTRAL_EUROPE }, { "Slovenian", "sl_SI", 0x0424, 1250, CP_CENTRAL_EUROPE }, { "Spanish (Argentina)", "es_AR", 0x2c0a, 1252, CP_WESTERN_EUROPE_AND_US }, { "Spanish (Bolivia)", "es_BO", 0x400a, 1252, CP_WESTERN_EUROPE_AND_US }, { "Spanish (Chile)", "es_CL", 0x340a, 1252, CP_WESTERN_EUROPE_AND_US }, { "Spanish (Colombia)", "es_CO", 0x240a, 1252, CP_WESTERN_EUROPE_AND_US }, { "Spanish (Costa Rica)", "es_CR", 0x140a, 1252, CP_WESTERN_EUROPE_AND_US }, { "Spanish (Dominican Republic)", "es_DO", 0x1c0a, 1252, CP_WESTERN_EUROPE_AND_US }, { "Spanish (Ecuador)", "es_EC", 0x300a, 1252, CP_WESTERN_EUROPE_AND_US }, { "Spanish (El Salvador)", "es_SV", 0x440a, 1252, CP_WESTERN_EUROPE_AND_US }, { "Spanish (Guatemala)", "es_GT", 0x100a, 1252, CP_WESTERN_EUROPE_AND_US }, { "Spanish (Honduras)", "es_HN", 0x480a, 1252, CP_WESTERN_EUROPE_AND_US }, { "Spanish (International Sort)", "es_ES", 0x0c0a, 1252, CP_WESTERN_EUROPE_AND_US }, { "Spanish (Mexico)", "es_MX", 0x080a, 1252, CP_WESTERN_EUROPE_AND_US }, { "Spanish (Nicaragua)", "es_NI", 0x4c0a, 1252, CP_WESTERN_EUROPE_AND_US }, { "Spanish (Panama)", "es_PA", 0x180a, 1252, CP_WESTERN_EUROPE_AND_US }, { "Spanish (Paraguay)", "es_PY", 0x3c0a, 1252, CP_WESTERN_EUROPE_AND_US }, { "Spanish (Peru)", "es_PE", 0x280a, 1252, CP_WESTERN_EUROPE_AND_US }, { "Spanish (Puerto Rico)", "es_PR", 0x500a, 1252, CP_WESTERN_EUROPE_AND_US }, { "Spanish (Traditional Sort)", "es_ES_tradnl", 0x040a, 1252, CP_WESTERN_EUROPE_AND_US }, { "Spanish (Uruguay)", "es_UY", 0x380a, 1252, CP_WESTERN_EUROPE_AND_US }, { "Spanish (Venezuela)", "es_VE", 0x200a, 1252, CP_WESTERN_EUROPE_AND_US }, { "Swahili", "sw_KE", 0x0441, 1252, CP_WESTERN_EUROPE_AND_US }, { "Swedish", "sv_SE", 0x041d, 1252, CP_WESTERN_EUROPE_AND_US }, { "Swedish (Finland)", "sv_FI", 0x081d, 1252, CP_WESTERN_EUROPE_AND_US }, { "Tajik", "tg_Cyrl_TJ", 0x0428, 1251, CP_CYRILLIC }, { "Tamil", "ta_IN", 0x0449, 0 , CP_INDIC }, { "Tatar", "tt_RU", 0x0444, 1251, CP_CYRILLIC }, { "Telegu", "te_IN", 0x044a, 0 , CP_INDIC }, { "Thai", "th_TH", 0x041e, 874 , CP_THAI }, { "Tibetan", "bo_CN", 0x0451, 0 , CP_UNICODE_ONLY }, { "Tsonga", "ts_ZA", 0x0431, 1252, CP_WESTERN_EUROPE_AND_US }, { "Twana", "tn_ZA", 0x0432, 1252, CP_WESTERN_EUROPE_AND_US }, { "Turkish", "tr_TR", 0x041f, 1254, CP_TURKIC }, { "Turkmen", "tk_TM", 0x0442, 1251, CP_CYRILLIC }, { "Ukrainian", "uk_UA", 0x0422, 1251, CP_CYRILLIC }, { "Urdu", "ur_PK", 0x0420, 1256, CP_ARABIC }, { "Uzbek (Cyrillic)", "uz_Cyrl_UZ", 0x0843, 1251, CP_CYRILLIC }, { "Uzbek (Latin)", "uz_Latn_UZ", 0x0443, 1254, CP_TURKIC }, { "Venda", "ven_ZA", 0x0433, 1252, CP_WESTERN_EUROPE_AND_US }, { "Vietnamese", "vi_VN", 0x042a, 1258, CP_VIETNAMESE }, { "Welsh", "cy_GB", 0x0452, 1252, CP_WESTERN_EUROPE_AND_US }, { "Wolof (Senegal)", "wo_SN", 0x0488, 1252, CP_WESTERN_EUROPE_AND_US }, { "Xhosa", "xh_ZA", 0x0434, 1252, CP_WESTERN_EUROPE_AND_US }, { "Zulu", "zu_ZA", 0x0435, 1252, CP_WESTERN_EUROPE_AND_US }, { NULL, NULL, 0, 0, 0 } }; /** \details Returns current locale used by the system \return pointer to locale string on success, otherwise NULL */ _PUBLIC_ char *mapi_get_system_locale(void) { char *locale; locale = setlocale(LC_CTYPE, ""); return locale; } /** \details Verify if the specified codepage is valid \param cpid the codepage to lookup \return 0 on success, otherwise 1 */ _PUBLIC_ bool mapi_verify_cpid(uint32_t cpid) { uint32_t i; for (i = 0; locales[i].lcid; i++) { if (cpid == locales[i].cpid) { return true; } } return false; } /** \details Returns codepage for a given LCID (Locale ID) \param lcid the locale ID to lookup \return non-zero codepage on success, otherwise 0 if only unicode is supported for this language */ _PUBLIC_ uint32_t mapi_get_cpid_from_lcid(uint32_t lcid) { uint32_t i; for (i = 0; locales[i].lcid; i++) { if (lcid == locales[i].lcid) { return locales[i].cpid; } } return 0; } /** \details Return codepage associated to specified locale \param locale The locale string to lookup \return non-zero codepage on success, otherwise 0 */ _PUBLIC_ uint32_t mapi_get_cpid_from_locale(const char *locale) { uint32_t i; /* Sanity Checks */ if (!locale) return 0; for (i = 0; locales[i].locale; i++) { if (locales[i].locale && !strncmp(locales[i].locale, locale, strlen(locales[i].locale))) { return locales[i].cpid; } } return 0; } /** \details Return codepage associated to specified language \param language The language string to lookup \return non-zero codepage on success, otherwise 0 */ _PUBLIC_ uint32_t mapi_get_cpid_from_language(const char *language) { uint32_t i; /* Sanity Checks */ if (!language) return 0; for (i = 0; locales[i].language; i++) { if (locales[i].language && !strncmp(locales[i].language, language, strlen(locales[i].language))) { return locales[i].cpid; } } return 0; } /** \details Returns LCID (Locale ID) for a given locale \param locale the locale string to lookup \return non-zero LCID on success, otherwise 0 */ _PUBLIC_ uint32_t mapi_get_lcid_from_locale(const char *locale) { uint32_t i; /* Sanity Checks */ if (!locale) return 0; for (i = 0; locales[i].locale; i++) { if (locales[i].locale && !strncmp(locales[i].locale, locale, strlen(locales[i].locale))) { return locales[i].lcid; } } return 0; } /** \details Returns LCID (Locale ID) for a given language \param language the language string to lookup \return non-zero LCID on success, otherwise 0 */ _PUBLIC_ uint32_t mapi_get_lcid_from_language(const char *language) { uint32_t i; /* Sanity Checks */ if (!language) return 0; for (i = 0; locales[i].language; i++) { if (locales[i].language && !strncmp(locales[i].language, language, strlen(locales[i].language))) { return locales[i].lcid; } } return 0; } /** \details Returns Locale for a given Locale ID \param lcid the locale ID to lookup \return locale string on success, otherwise NULL */ _PUBLIC_ const char *mapi_get_locale_from_lcid(uint32_t lcid) { uint32_t i; for (i = 0; locales[i].lcid; i++) { if (locales[i].lcid == lcid) { return locales[i].locale; } } return NULL; } /** \details Returns Locale for a given language \param language the language string to lookup \return Locale string on success, otherwise NULL */ _PUBLIC_ const char *mapi_get_locale_from_language(const char *language) { uint32_t i; /* Sanity Checks */ if (!language) return NULL; for (i = 0; locales[i].language; i++) { if (locales[i].language && !strncmp(locales[i].language, language, strlen(locales[i].language))) { return locales[i].locale; } } return NULL; } /** \details Returns Language for a given Locale \param locale the language string to lookup \return Language string on success, otherwise NULL */ _PUBLIC_ const char *mapi_get_language_from_locale(const char *locale) { uint32_t i; /* Sanity Checks */ if (!locale) return NULL; for (i = 0; locales[i].locale; i++) { if (locales[i].locale && !strncmp(locales[i].locale, locale, strlen(locales[i].locale))) { return locales[i].language; } } return NULL; } /** \details Returns Language for a given Locale ID \param lcid the locale ID to lookup \return language string on success, otherwise NULL */ _PUBLIC_ const char *mapi_get_language_from_lcid(uint32_t lcid) { uint32_t i; for (i = 0; locales[i].lcid; i++) { if (locales[i].lcid == lcid) { return locales[i].language; } } return NULL; } /** \details Returns List of languages for a given Language Group \param mem_ctx pointer to the memory context \param group the locale group to lookup \return Array of languages string on success, otherwise NULL */ _PUBLIC_ char **mapi_get_language_from_group(TALLOC_CTX *mem_ctx, uint32_t group) { uint32_t i; uint32_t counter = 0; char **languages; /* Sanity Checks */ if (!mem_ctx) return NULL; languages = talloc_array(mem_ctx, char *, counter + 1); for (i = 0; locales[i].language; i++) { if (locales[i].language_group == group) { languages = talloc_realloc(mem_ctx, languages, char *, counter + 1); languages[counter] = talloc_strdup(languages, locales[i].language); counter += 1; } } if (!counter) { talloc_free(languages); return NULL; } return languages; } void mapi_get_language_list(void) { uint32_t i; for (i = 0; locales[i].language; i++) { printf("%s\n", locales[i].language); } } openchange-2.0/libmapi/conf/000077500000000000000000000000001223057412600160265ustar00rootroot00000000000000openchange-2.0/libmapi/conf/append-prop.py000077500000000000000000000114751223057412600206400ustar00rootroot00000000000000#!/usr/bin/python ################################################### # # script that produces stub entries for missing properties passed as parameter in the form oldguid:olid # example: # ./append-prop.py 00062008-0000-0000-c000-000000000046:858d outputs this: # PidLidUnknownProperty858d LID_UNKNOWN_PROPERTY_858d 0x858d NULL PT_NULL MNID_ID PSETID_Common 0x84f5 # # As the MAPI data type is unknown, it needs to be filled in as requests are performed by outlook on the mapped id. # Also, note that the output is performed on stdout. # # Copyright (C) Wolfgang Sourdeau 2010 # released under the GNU GPL v2 # import sys filename = "mapi-named-properties" def getLineID(line): idPos = line.rfind("0x") if idPos < len(line) - 8: lineID = -1 else: lineID = int(line[idPos:], 16) return lineID def getLastID(filename): propFile = open(filename) lines = propFile.readlines() propFile.close() lastID = -1 for line in lines: line = line.strip() if len(line) > 0 and line[0] != '#' and line[0] != '#' and line[0] != ' ': lineID = getLineID(line) if lineID > lastID: lastID = lineID return lastID guidArray = [("PS_MAPI", "00020328-0000-0000-c000-000000000046"), ("PS_PUBLIC_STRINGS", "00020329-0000-0000-c000-000000000046"), ("PS_INTERNET_HEADERS", "00020386-0000-0000-c000-000000000046"), ("PSETID_Appointment", "00062002-0000-0000-c000-000000000046"), ("PSETID_Task", "00062003-0000-0000-c000-000000000046"), ("PSETID_Address", "00062004-0000-0000-c000-000000000046"), ("PSETID_Common", "00062008-0000-0000-c000-000000000046"), ("PS_UNKNOWN_0006200b_0000_0000_c000_000000000046", "0006200b-0000-0000-c000-000000000046"), ("PSETID_Report", "00062013-0000-0000-c000-000000000046"), ("PSETID_Remote", "00062014-0000-0000-c000-000000000046"), ("PSETID_Sharing", "00062040-0000-0000-c000-000000000046"), ("PSETID_PostRss", "00062041-0000-0000-c000-000000000046"), ("PSETID_Log", "0006200a-0000-0000-c000-000000000046"), ("PSETID_Note", "0006200e-0000-0000-c000-000000000046"), ("PSETID_Meeting", "6ed8da90-450b-101b-98da-00aa003f1305"), ("PSETID_Messaging", "41f28f13-83f4-4114-a584-eedb5a6b0bff"), ("PSETID_UnifiedMessaging", "4442858e-a9e3-4e80-b900-317a210cc15b"), ("PSETID_AirSync", "71035549-0739-4dcb-9163-00f0580dbbdf")] guidMapping = {} for guidTpl in guidArray: guidMapping[guidTpl[1]] = guidTpl[0] def canonicalizeName(name): for sep in [ ":", "/" ]: sepIdx = name.rfind(sep) if sepIdx > -1: name = name[sepIdx+1:] nameArray = name.split("-") name = "".join([x.capitalize() for x in nameArray]) return name def genNewLine(olID, nextID): colIdx = olID.find(":") if colIdx == -1: raise Exception, "Property line must contain a namespace id and a property name/id" mappingKey = olID[0:colIdx] if guidMapping.has_key(mappingKey): domain = guidMapping[mappingKey] else: domain = "PS_UNKNOWN_%s" % mappingKey.replace("-", "_") olPropID = olID[colIdx+1:] try: int(olPropID, 16) isdigit = True except: isdigit = False if len(olPropID) == 4 and isdigit: propKind = "MNID_ID" propId = "0x%s" % olPropID.lower() propName = "NULL" OOM = "LID_UNKNOWN_PROPERTY_%s" % olPropID.lower() canonicalName = "PidLidUnknownProperty%s" % olPropID.lower() else: propKind = "MNID_STRING" propId = "0x0000" propName = olPropID OOM = "NULL" if olPropID[0:4] == "urn:": canonicalName = "NULL" else: canonicalName = "PidName%s" % canonicalizeName(olPropID) propType = "PT_NULL" return "%s\t%s\t%s\t%s\t%s\t%s\t%s\t0x%.4x" \ % (canonicalName, OOM, propId, propName, propType, propKind, domain, nextID) # PidLidServerProcessed ExchangeProcessed 0x85CC NULL PT_BOOLEAN MNID_ID PSETID_Common # PidNameCalendarAttendeeRole NULL 0x0000 CalendarAttendeeRole PT_LONG MNID_STRING PS_PUBLIC_STRINGS def main(): lastID = getLastID(filename) # print "lastID: %.4x" % lastID if lastID > -1: nextID = lastID + 1 # newLines = [] if len(sys.argv) > 1: print "### generated via append-prop.py" for i in xrange(1, len(sys.argv)): newLine = genNewLine(sys.argv[i], nextID) print newLine nextID = nextID + 1 if __name__ == "__main__": main() openchange-2.0/libmapi/conf/codepage-lcid000066400000000000000000000350331223057412600204350ustar00rootroot00000000000000 # OpenChange MAPI implementation. # # Copyright (C) Julien Kerihuel 2010. # # This program is free software; you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by # the Free Software Foundation; either version 3 of the License, or # (at your option) any later version. # # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program. If not, see . # # Lines starting with # are commented and not processed. # Locale using '_' underscore characters will automatically be # replaced by space once processed. # # Defines for Language group # DEFINE CP_UNICODE_ONLY 0 DEFINE CP_WESTERN_EUROPE_AND_US 1 DEFINE CP_CENTRAL_EUROPE 2 DEFINE CP_BALTIC 3 DEFINE CP_GREEK 4 DEFINE CP_CYRILLIC 5 DEFINE CP_TURKIC 6 DEFINE CP_JAPANESE 7 DEFINE CP_KOREAN 8 DEFINE CP_TRADITIONAL_CHINESE 9 DEFINE CP_SIMPLIFIED_CHINESE 10 DEFINE CP_THAI 11 DEFINE CP_HEBREW 12 DEFINE CP_ARABIC 13 DEFINE CP_VIETNAMESE 14 DEFINE CP_INDIC 15 DEFINE CP_GEORGIAN 16 DEFINE CP_ARMENIAN 17 #Language Locale Language Tag LCID (hex) CodePage (dec) Language Group Country Code Afrikaans NULL af_ZA 0x0436 1252 CP_WESTERN_EUROPE_AND_US ZAF Albanian NULL sq_AL 0x041c 1250 CP_CENTRAL_EUROPE ALB Amharic Ethiopia am_ET 0x045e 0 CP_UNICODE_ONLY ETH Arabic Algeria ar_DZ 0x1401 1256 CP_ARABIC DZA Arabic Bahrain ar_BH 0x3c01 1256 CP_ARABIC BHR Arabic Egypt ar_EG 0x0c01 1256 CP_ARABIC EGY Arabic Iraq ar_SA 0x0801 1256 CP_ARABIC IRQ Arabic Jordan ar_JO 0x2c01 1256 CP_ARABIC JOR Arabic Kuwait ar_KW 0x3401 1256 CP_ARABIC KWT Arabic Lebanon ar_LB 0x3001 1256 CP_ARABIC LBN Arabic Libya ar_LY 0x1001 1256 CP_ARABIC LBY Arabic Morocco ar_MA 0x1801 1256 CP_ARABIC MAR Arabic Oman ar_OM 0x2001 1256 CP_ARABIC OMN Arabic Qatar ar_QA 0x4001 1256 CP_ARABIC QAT Arabic Saudi_Arabia ar_SA 0x0401 1256 CP_ARABIC SAU Arabic Syria ar_SY 0x2801 1256 CP_ARABIC SYR Arabic Tunisia ar_TN 0x1c01 1256 CP_ARABIC TUN Arabic U.A.E. ar_AE 0x3801 1256 CP_ARABIC ARE Arabic Yemen ar_YE 0x2401 1256 CP_ARABIC YEM Armenian NULL hy_AM 0x042b 0 CP_ARMENIAN ARM Assamese NULL as_IN 0x044d 0 CP_INDIC NULL Azeri Cyrillic az_Cyrl_AZ 0x082c 1251 CP_CYRILLIC AZE Azeri Latin az_Latn_AZ 0x042c 1254 CP_TURKIC AZE Basque NULL eu_ES 0x042d 1252 CP_WESTERN_EUROPE_AND_US ESP Belarusian NULL be_BY 0x0423 1251 CP_CYRILLIC BLR Bengali India bn_IN 0x0445 0 CP_INDIC BGD Bosnian Bosnia/Herzegovina bs_Latn_BA 0x141A 1250 CP_CENTRAL_EUROPE BIH Breton France br_FR 0x047e 1252 CP_WESTERN_EUROPE_AND_US BRE Bulgarian NULL bg_BG 0x0402 1251 CP_CYRILLIC BGR Catalan NULL ca_ES 0x0403 1252 CP_WESTERN_EUROPE_AND_US ESP Chinese Hong_Kong_S.A.R. zh_HK 0x0c04 950 CP_TRADITIONAL_CHINESE HKG Chinese Macau_S.A.R. zh_MO 0x1404 950 CP_TRADITIONAL_CHINESE MCO Chinese PRC zh_CN 0x0804 936 CP_SIMPLIFIED_CHINESE CHN Chinese Singapore zh_SG 0x1004 936 CP_SIMPLIFIED_CHINESE SGP Chinese Taiwan zh_TW 0x0404 950 CP_TRADITIONAL_CHINESE TWN Croatian NULL hr_HR 0x041a 1250 CP_CENTRAL_EUROPE HRV Croatian Bosnia/Herzegovina hr_BA 0x101a 1250 CP_CENTRAL_EUROPE BIH Czech NULL cz_CZ 0x0405 1250 CP_CENTRAL_EUROPE CZE Danish NULL da_DK 0x0406 1252 CP_WESTERN_EUROPE_AND_US DNK Dari Afghanistan gbz_AF 0x048c 1256 CP_ARABIC AFG Divehi NULL dv_MV 0x0465 0 CP_UNICODE_ONLY MDV Dutch Belgium nl_BE 0x0813 1252 CP_WESTERN_EUROPE_AND_US BEL Dutch Netherlands nl_NL 0x0413 1252 CP_WESTERN_EUROPE_AND_US NLD English Australia en_AU 0x0c09 1252 CP_WESTERN_EUROPE_AND_US AUS English Belize en_BZ 0x2809 1252 CP_WESTERN_EUROPE_AND_US BLZ English Canada en_CA 0x1009 1252 CP_WESTERN_EUROPE_AND_US CAN English Caribbean en_CB 0x2409 1252 CP_WESTERN_EUROPE_AND_US CAR English India en_IN 0x4009 1252 CP_WESTERN_EUROPE_AND_US IND English Ireland en_IE 0x1809 1252 CP_WESTERN_EUROPE_AND_US IRL English Jamaica en_JM 0x2009 1252 CP_WESTERN_EUROPE_AND_US JAM English New_Zealand en_NZ 0x1409 1252 CP_WESTERN_EUROPE_AND_US NZL English Philippines en_PH 0x3409 1252 CP_WESTERN_EUROPE_AND_US PHL English South_Africa en_ZA 0x1c09 1252 CP_WESTERN_EUROPE_AND_US ZAF English Trinidad en_TT 0x2c09 1252 CP_WESTERN_EUROPE_AND_US TTO English United_Kingdom en_GB 0x0809 1252 CP_WESTERN_EUROPE_AND_US GBR English United_States en_US 0x0409 1252 CP_WESTERN_EUROPE_AND_US USA English Zimbabwe en_ZW 0x3009 1252 CP_WESTERN_EUROPE_AND_US ZWE Estonian NULL et_EE 0x0425 1257 CP_BALTIC EST Faroese NULL fo_FO 0x0438 1252 CP_WESTERN_EUROPE_AND_US FRO Farsi NULL fa_IR 0x0429 1256 CP_ARABIC IRN Filipino NULL fil_PH 0x0464 1252 CP_WESTERN_EUROPE_AND_US NULL Finnish NULL fi_FI 0x040b 1252 CP_WESTERN_EUROPE_AND_US FIN French Belgium fr_BE 0x080c 1252 CP_WESTERN_EUROPE_AND_US BEL French Cameroon fr_CM 0x2c0c 1252 CP_WESTERN_EUROPE_AND_US NULL French Canada fr_CA 0x0c0c 1252 CP_WESTERN_EUROPE_AND_US CAN French Congo,DRC fr_CG 0x240c 1252 CP_WESTERN_EUROPE_AND_US COD French Cote_d'Ivoire fr_CI 0x300c 1252 CP_WESTERN_EUROPE_AND_US CIV French France fr_FR 0x040c 1252 CP_WESTERN_EUROPE_AND_US FRA French Luxembourg fr_LU 0x140c 1252 CP_WESTERN_EUROPE_AND_US LUX French Mali fr_ML 0x340c 1252 CP_WESTERN_EUROPE_AND_US MLI French Monaco fr_MC 0x180c 1252 CP_WESTERN_EUROPE_AND_US MCO French Morocco fr_MA 0x380c 1252 CP_WESTERN_EUROPE_AND_US MAR French Senegal fr_SN 0x280c 1252 CP_WESTERN_EUROPE_AND_US SEN French Switzerland fr_CH 0x100c 1252 CP_WESTERN_EUROPE_AND_US CHE French West_Indies fr_West_Indies 0x1c0c 1252 CP_WESTERN_EUROPE_AND_US NULL Frisian Netherlands fy_NL 0x0462 1252 CP_WESTERN_EUROPE_AND_US NULL FYRO_Macedonian NULL mk_MK 0x042f 1251 CP_CYRILLIC MKD Gaelic_Ireland NULL ga_IE 0x083c 1252 CP_WESTERN_EUROPE_AND_US NULL Galician Spain gl_ES 0x0456 1252 CP_WESTERN_EUROPE_AND_US ESP Georgian NULL ka_GE 0x0437 0 CP_GEORGIAN GEO German Austria de_AT 0x0c07 1252 CP_WESTERN_EUROPE_AND_US AUT German Germany de_DE 0x0407 1252 CP_WESTERN_EUROPE_AND_US DEU German Liechtenstein de_LI 0x1407 1252 CP_WESTERN_EUROPE_AND_US LIE German Luxembourg de_LU 0x1007 1252 CP_WESTERN_EUROPE_AND_US LUX German Switzerland de_CH 0x0807 1252 CP_WESTERN_EUROPE_AND_US CHE Greek NULL el_GR 0x0408 1253 CP_GREEK GRC Gujarati NULL gu_IN 0x0447 0 CP_INDIC IND Hebrew NULL he_IL 0x040d 1255 CP_HEBREW ISR Hindi NULL hi_IN 0x0439 0 CP_INDIC IND Hungarian NULL hu_HU 0x040e 1250 CP_CENTRAL_EUROPE HUNG Icelandic NULL is_IS 0x040f 1252 CP_WESTERN_EUROPE_AND_US ISL Igbo Nigeria ig_NG 0x0470 1252 CP_WESTERN_EUROPE_AND_US NULL Indonesian NULL id_ID 0x0421 1252 CP_WESTERN_EUROPE_AND_US IDN Italian Italy it_IT 0x0410 1252 CP_WESTERN_EUROPE_AND_US ITA Italian Switzerland it_CH 0x0810 1252 CP_WESTERN_EUROPE_AND_US CHE Japanese NULL ja_JP 0x0411 932 CP_JAPANESE JPN Kannada NULL kn_IN 0x044b 0 CP_UNICODE_ONLY IDN Kazakh NULL kk_KZ 0x043f 1251 CP_CYRILLIC KAZ Khmer NULL km_KH 0x0453 0 CP_UNICODE_ONLY NULL Konkani NULL kok_IN 0x0457 0 CP_INDIC IND Korean NULL ko_KR 0x0412 949 CP_KOREAN KOR Kyrgyz Cyrillic ky_KG 0x0440 1251 CP_CYRILLIC KGZ Lao NULL lo_LA 0x0454 0 CP_UNICODE_ONLY NULL Latvian NULL lv_LV 0x0426 1257 CP_BALTIC LVA Lithuanian NULL lt_LT 0x0427 1257 CP_BALTIC LTU Macedonian NULL mk_MK 0x042f 1251 CP_CYRILLIC MKD Malay Brunei_Darussalam ms_BN 0x083e 1252 CP_WESTERN_EUROPE_AND_US BRN Malay Malaysia ms_MY 0x043e 1252 CP_WESTERN_EUROPE_AND_US MYS Malayalam NULL ml_IN 0x044c 0 CP_UNICODE_ONLY NULL Maltese NULL mt_MT 0x043a 1252 CP_WESTERN_EUROPE_AND_US MLT Maori New_Zealand mi_NZ 0x0481 1252 CP_WESTERN_EUROPE_AND_US NULL Marathi NULL ms_IN 0x044e 0 CP_INDIC IND Mongolian Cyrillic mn_MN 0x0450 1251 CP_CYRILLIC MNG Mongolian Mongolia mn_Mong_CN 0x0850 0 CP_UNICODE_ONLY MNG Nepali NULL ne_NP 0x0461 0 CP_UNICODE_ONLY NPL Norwegian Bokmal nb_NO 0x0414 1252 CP_WESTERN_EUROPE_AND_US NOR Norwegian Nynorsk nn_NO 0x0814 1252 CP_WESTERN_EUROPE_AND_US NOR Oriya NULL or_IN 0x0448 0 CP_INDIC NULL Polish NULL pl_PL 0x0415 1250 CP_CENTRAL_EUROPE POL Portuguese Brazil pt_BR 0x0416 1252 CP_WESTERN_EUROPE_AND_US BRA Portuguese Portugal pt_PT 0x0816 1252 CP_WESTERN_EUROPE_AND_US PLT Punjabi NULL pa_IN 0x0446 0 CP_INDIC IND Rhaeto-Romanic NULL rm_CH 0x0417 1252 CP_WESTERN_EUROPE_AND_US NULL Romanian NULL ro_RM 0x0418 1250 CP_CENTRAL_EUROPE ROM Romanian Moldova ro_MO 0x0818 819 CP_CENTRAL_EUROPE NULL Russian NULL ru_RU 0x0419 1251 CP_CYRILLIC RUS Sami_Lappish NULL se_NO 0x043b 1252 CP_WESTERN_EUROPE_AND_US NULL Sanskrit NULL sa_IN 0x044f 0 CP_INDIC IND Serbian Cyrillic sr_Cyrl_CS 0x0c1a 1251 CP_CYRILLIC SPB Serbian Latin sr_Latn_CS 0x081a 1250 CP_CENTRAL_EUROPE SPB Sindhi NULL sd_IN 0x0459 0 CP_INDIC NULL Sinhalese Sri_Lanka si_LK 0x045b 0 CP_UNICODE_ONLY NULL Slovak NULL sk_SK 0x041b 1250 CP_CENTRAL_EUROPE SVK Slovenian NULL sl_SI 0x0424 1250 CP_CENTRAL_EUROPE SVN Spanish Argentina es_AR 0x2c0a 1252 CP_WESTERN_EUROPE_AND_US ARG Spanish Bolivia es_BO 0x400a 1252 CP_WESTERN_EUROPE_AND_US BOL Spanish Chile es_CL 0x340a 1252 CP_WESTERN_EUROPE_AND_US CHL Spanish Colombia es_CO 0x240a 1252 CP_WESTERN_EUROPE_AND_US COL Spanish Costa_Rica es_CR 0x140a 1252 CP_WESTERN_EUROPE_AND_US CRI Spanish Dominican_Republic es_DO 0x1c0a 1252 CP_WESTERN_EUROPE_AND_US DOM Spanish Ecuador es_EC 0x300a 1252 CP_WESTERN_EUROPE_AND_US ECU Spanish El_Salvador es_SV 0x440a 1252 CP_WESTERN_EUROPE_AND_US SLV Spanish Guatemala es_GT 0x100a 1252 CP_WESTERN_EUROPE_AND_US GTM Spanish Honduras es_HN 0x480a 1252 CP_WESTERN_EUROPE_AND_US HND Spanish International_Sort es_ES 0x0c0a 1252 CP_WESTERN_EUROPE_AND_US ESP Spanish Mexico es_MX 0x080a 1252 CP_WESTERN_EUROPE_AND_US MEX Spanish Nicaragua es_NI 0x4c0a 1252 CP_WESTERN_EUROPE_AND_US NIC Spanish Panama es_PA 0x180a 1252 CP_WESTERN_EUROPE_AND_US PAN Spanish Paraguay es_PY 0x3c0a 1252 CP_WESTERN_EUROPE_AND_US PRY Spanish Peru es_PE 0x280a 1252 CP_WESTERN_EUROPE_AND_US PER Spanish Puerto_Rico es_PR 0x500a 1252 CP_WESTERN_EUROPE_AND_US PRI Spanish Traditional_Sort es_ES_tradnl 0x040a 1252 CP_WESTERN_EUROPE_AND_US ESP Spanish Uruguay es_UY 0x380a 1252 CP_WESTERN_EUROPE_AND_US URY Spanish Venezuela es_VE 0x200a 1252 CP_WESTERN_EUROPE_AND_US VEN Swahili NULL sw_KE 0x0441 1252 CP_WESTERN_EUROPE_AND_US KEN Swedish NULL sv_SE 0x041d 1252 CP_WESTERN_EUROPE_AND_US SWE Swedish Finland sv_FI 0x081d 1252 CP_WESTERN_EUROPE_AND_US FIN Tajik NULL tg_Cyrl_TJ 0x0428 1251 CP_CYRILLIC NULL Tamil NULL ta_IN 0x0449 0 CP_INDIC IND Tatar NULL tt_RU 0x0444 1251 CP_CYRILLIC RUS Telegu NULL te_IN 0x044a 0 CP_INDIC IND Thai NULL th_TH 0x041e 874 CP_THAI THA Tibetan NULL bo_CN 0x0451 0 CP_UNICODE_ONLY NULL Tsonga NULL ts_ZA 0x0431 1252 CP_WESTERN_EUROPE_AND_US NULL Twana NULL tn_ZA 0x0432 1252 CP_WESTERN_EUROPE_AND_US NULL Turkish NULL tr_TR 0x041f 1254 CP_TURKIC TUR Turkmen NULL tk_TM 0x0442 1251 CP_CYRILLIC NULL Ukrainian NULL uk_UA 0x0422 1251 CP_CYRILLIC UKR Urdu NULL ur_PK 0x0420 1256 CP_ARABIC PAK Uzbek Cyrillic uz_Cyrl_UZ 0x0843 1251 CP_CYRILLIC UZB Uzbek Latin uz_Latn_UZ 0x0443 1254 CP_TURKIC UZB Venda NULL ven_ZA 0x0433 1252 CP_WESTERN_EUROPE_AND_US NULL Vietnamese NULL vi_VN 0x042a 1258 CP_VIETNAMESE VNM Welsh NULL cy_GB 0x0452 1252 CP_WESTERN_EUROPE_AND_US NULL Wolof Senegal wo_SN 0x0488 1252 CP_WESTERN_EUROPE_AND_US NULL Xhosa NULL xh_ZA 0x0434 1252 CP_WESTERN_EUROPE_AND_US NULL Zulu NULL zu_ZA 0x0435 1252 CP_WESTERN_EUROPE_AND_US NULL openchange-2.0/libmapi/conf/mapi-codes000066400000000000000000000213411223057412600177730ustar00rootroot00000000000000# # OpenChange MAPI implementation. # MAPI error codes # # This program is free software; you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by # the Free Software Foundation; either version 3 of the License, or # (at your option) any later version. # # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program. If not, see . # 0x00000000 MAPI_E_SUCCESS 0x80004002 MAPI_E_INTERFACE_NO_SUPPORT 0x80004005 MAPI_E_CALL_FAILED 0x80040102 MAPI_E_NO_SUPPORT 0x80040103 MAPI_E_BAD_CHARWIDTH 0x80040105 MAPI_E_STRING_TOO_LONG 0x80040106 MAPI_E_UNKNOWN_FLAGS 0x80040107 MAPI_E_INVALID_ENTRYID 0x80040108 MAPI_E_INVALID_OBJECT 0x80040109 MAPI_E_OBJECT_CHANGED 0x8004010A MAPI_E_OBJECT_DELETED 0x8004010B MAPI_E_BUSY 0x8004010D MAPI_E_NOT_ENOUGH_DISK 0x8004010E MAPI_E_NOT_ENOUGH_RESOURCES 0x8004010F MAPI_E_NOT_FOUND 0x80040110 MAPI_E_VERSION 0x80040111 MAPI_E_LOGON_FAILED 0x80040112 MAPI_E_SESSION_LIMIT 0x80040113 MAPI_E_USER_CANCEL 0x80040114 MAPI_E_UNABLE_TO_ABORT 0x80040115 MAPI_E_NETWORK_ERROR 0x80040116 MAPI_E_DISK_ERROR 0x80040117 MAPI_E_TOO_COMPLEX 0x80040118 MAPI_E_BAD_COLUMN 0x80040119 MAPI_E_EXTENDED_ERROR 0x8004011A MAPI_E_COMPUTED 0x8004011B MAPI_E_CORRUPT_DATA 0x8004011C MAPI_E_UNCONFIGURED 0x8004011D MAPI_E_FAILONEPROVIDER 0x8004011E MAPI_E_UNKNOWN_CPID 0x8004011F MAPI_E_UNKNOWN_LCID 0x80040120 MAPI_E_PASSWORD_CHANGE_REQUIRED 0x80040121 MAPI_E_PASSWORD_EXPIRED 0x80040122 MAPI_E_INVALID_WORKSTATION_ACCOUNT 0x80040123 MAPI_E_INVALID_ACCESS_TIME 0x80040124 MAPI_E_ACCOUNT_DISABLED 0x80040200 MAPI_E_END_OF_SESSION 0x80040201 MAPI_E_UNKNOWN_ENTRYID 0x80040202 MAPI_E_MISSING_REQUIRED_COLUMN 0x00040203 MAPI_W_NO_SERVICE 0x80040301 MAPI_E_BAD_VALUE 0x80040302 MAPI_E_INVALID_TYPE 0x80040303 MAPI_E_TYPE_NO_SUPPORT 0x80040304 MAPI_E_UNEXPECTED_TYPE 0x80040305 MAPI_E_TOO_BIG 0x80040306 MAPI_E_DECLINE_COPY 0x80040307 MAPI_E_UNEXPECTED_ID 0x00040380 MAPI_W_ERRORS_RETURNED 0x80040400 MAPI_E_UNABLE_TO_COMPLETE 0x80040401 MAPI_E_TIMEOUT 0x80040402 MAPI_E_TABLE_EMPTY 0x80040403 MAPI_E_TABLE_TOO_BIG 0x80040405 MAPI_E_INVALID_BOOKMARK 0x00040481 MAPI_W_POSITION_CHANGED 0x00040482 MAPI_W_APPROX_COUNT 0x80040500 MAPI_E_WAIT 0x80040501 MAPI_E_CANCEL 0x80040502 MAPI_E_NOT_ME 0x00040580 MAPI_W_CANCEL_MESSAGE 0x80040600 MAPI_E_CORRUPT_STORE 0x80040601 MAPI_E_NOT_IN_QUEUE 0x80040602 MAPI_E_NO_SUPPRESS 0x80040604 MAPI_E_COLLISION 0x80040605 MAPI_E_NOT_INITIALIZED 0x80040606 MAPI_E_NON_STANDARD 0x80040607 MAPI_E_NO_RECIPIENTS 0x80040608 MAPI_E_SUBMITTED 0x80040609 MAPI_E_HAS_FOLDERS 0x8004060A MAPI_E_HAS_MESAGES 0x8004060B MAPI_E_FOLDER_CYCLE 0x8004060D MAPI_E_LOCKID_LIMIT 0x00040680 MAPI_W_PARTIAL_COMPLETION 0x80040700 MAPI_E_AMBIGUOUS_RECIP 0x80040800 SYNC_E_OBJECT_DELETED 0x80040801 SYNC_E_IGNORE 0x80040802 SYNC_E_CONFLICT 0x80040803 SYNC_E_NO_PARENT 0x80040804 SYNC_E_CYCLE_DETECTED 0x80040805 SYNC_E_UNSYNCHRONIZED 0x00040820 SYNC_W_PROGRESS 0x00040821 SYNC_W_CLIENT_CHANGE_NEWER 0x80040900 MAPI_E_NAMED_PROP_QUOTA_EXCEEDED 0x80040FFF MAPI_E_NOT_IMPLEMENTED 0x80070005 MAPI_E_NO_ACCESS 0x8007000E MAPI_E_NOT_ENOUGH_MEMORY 0x80070057 MAPI_E_INVALID_PARAMETER # # Additional Error Codes # 0x000003EA ecJetError 0x000003EB ecUnknownUser 0x000003ED ecExiting 0x000003EE ecBadConfig 0x000003EF ecUnknownCodePage 0x000003F0 ecMemory 0x000003F2 ecLoginPerm 0x000003F3 ecDatabaseRolledBack 0x000003F4 ecDatabaseCopiedError 0x000003F5 ecAuditNotAllowed 0x000003F6 ecZombieUser 0x000003F7 ecUnconvertableACL 0x0000044C ecNoFreeJses 0x0000044D ecDifferentJses 0x0000044F ecFileRemove 0x00000450 ecParameterOverflow 0x00000451 ecBadVersion 0x00000452 ecTooManyCols 0x00000453 ecHaveMore 0x00000454 ecDatabaseError 0x00000455 ecIndexNameTooBig 0x00000456 ecUnsupportedProp 0x00000457 ecMsgNotSaved 0x00000459 ecUnpubNotif 0x0000045B ecDifferentRoot 0x0000045C ecBadFolderName 0x0000045D ecAttachOpen 0x0000045E ecInvClpsState 0x0000045F ecSkipMyChildren 0x00000460 ecSearchFolder 0x00000461 ecNotSearchFolder 0x00000462 ecFolderSetReceive 0x00000463 ecNoReceiveFolder 0x00000465 ecNoDelSubmitMsg 0x00000467 ecInvalidRecips 0x00000468 ecNoReplicaHere 0x00000469 ecNoReplicaAvailable 0x0000046A ecPublicMDB 0x0000046B ecNotPublicMDB 0x0000046C ecRecordNotFound 0x0000046D ecReplConflict 0x00000470 ecFxBufferOverrun 0x00000471 ecFxBufferEmpty 0x00000472 ecFxPartialValue 0x00000473 ecFxNoRoom 0x00000474 ecMaxTimeExpired 0x00000475 ecDstError 0x00000476 ecMDBNotInit 0x00000478 ecWrongServer 0x0000047D ecBufferTooSmall 0x0000047E ecRequiresRefResolve 0x0000047F ecServerPaused 0x00000480 ecServerBusy 0x00000481 ecNoSuchLogon 0x00000482 ecLoadLibFailed 0x00000483 ecObjAlreadyConfig 0x00000484 ecObjNotConfig 0x00000485 ecDataLoss 0x00000488 ecMaxSendThreadExceeded 0x00000489 ecFxErrorMarker 0x0000048A ecNoFreeJtabs 0x0000048B ecNotPrivateMDB 0x0000048C ecIsintegMDB 0x0000048D ecRecoveryMDBMismatch 0x0000048E ecTableMayNotBeDeleted 0x000004B1 ecRpcRegisterIf 0x000004B2 ecRpcListen 0x000004B6 ecRpcFormat 0x000004B7 ecNoCopyTo 0x000004B9 ecNullObject 0x000004BC ecRpcAuthentication 0x000004BD ecRpcBadAuthenticationLevel 0x000004BE ecNullCommentRestriction 0x000004CC ecRulesLoadError 0x000004CD ecRulesDelivErr 0x000004CE ecRulesParsingErr 0x000004CF ecRulesCreateDaeErr 0x000004D0 ecRulesCreateDamErr 0x000004D1 ecRulesNoMoveCopyFolder 0x000004D2 ecRulesNoFolderRights 0x000004D4 ecMessageTooBig 0x000004D5 ecFormNotValid 0x000004D6 ecNotAuthorized 0x000004D7 ecDeleteMessage 0x000004D8 ecBounceMessage 0x000004D9 ecQuotaExceeded 0x000004DA ecMaxSubmissionExceeded 0x000004DB ecMaxAttachmentExceeded 0x000004DC ecSendAsDenied 0x000004DD ecShutoffQuotaExceeded 0x000004DE ecMaxObjsExceeded 0x000004DF ecClientVerDisallowed 0x000004E0 ecRpcHttpDisallowed 0x000004E1 ecCachedModeRequired 0x000004E3 ecFolderNotCleanedUp 0x000004ED ecFmtError 0x000004F7 ecNotExpanded 0x000004F8 ecNotCollapsed 0x000004F9 ecLeaf 0x000004FA ecUnregisteredNamedProp 0x000004FB ecFolderDisabled 0x000004FC ecDomainError 0x000004FF ecNoCreateRight 0x00000500 ecPublicRoot 0x00000501 ecNoReadRight 0x00000502 ecNoCreateSubfolderRight 0x00000503 ecDstNullObject 0x00000504 ecMsgCycle 0x00000505 ecTooManyRecips 0x0000050A ecVirusScanInProgress 0x0000050B ecVirusDetected 0x0000050C ecMailboxInTransit 0x0000050D ecBackupInProgress 0x0000050E ecVirusMessageDeleted 0x0000050F ecInvalidBackupSequence 0x00000510 ecInvalidBackupSize 0x00000511 ecTooManyBackupsInProgress 0x00000512 ecRestoreInProgress 0x00000579 ecDuplicateObject 0x0000057A ecObjectNotFound 0x0000057B ecFixupReplyRule 0x0000057C ecTemplateNotFound 0x0000057D ecRuleException 0x0000057E ecDSNoSuchObject 0x0000057F ecMessageAlreadyTombstoned 0x00000596 ecRequiresRWTransaction 0x0000060E ecPaused 0x00000648 ecWrongMailbox 0x0000064C ecChgPassword 0x0000064D ecPwdExpired 0x0000064E ecInvWkstn 0x0000064F ecInvLogonHrs 0x00000650 ecAcctDisabled 0x000006A4 ecRuleVersion 0x000006A5 ecRuleFormat 0x000006A6 ecRuleSendAsDenied 0x000006B9 ecNoServerSupport 0x000006BA ecLockTimedOut 0x000006BB ecObjectLocked 0x000006BD ecInvalidLockNamespace 0x000007D6 ecMessageDeleted 0x000007D8 ecProtocolDisabled 0x000007D9 ecClearTextLogonDisabled 0x000007EE ecRejected 0x0000089A ecAmbiguousAlias 0x0000089B ecUnknownMailbox 0x000008FC ecExpReserved 0x000008FD ecExpParseDepth 0x000008FE ecExpFuncArgType 0x000008FF ecExpSyntax 0x00000900 ecExpBadStrToken 0x00000901 ecExpBadColToken 0x00000902 ecExpTypeMismatch 0x00000903 ecExpOpNotSupported 0x00000904 ecExpDivByZero 0x00000905 ecExpUnaryArgType 0x00000960 ecNotLocked 0x00000961 ecClientEvent 0x00000965 ecCorruptEvent 0x00000966 ecCorruptWatermark 0x00000967 ecEventError 0x00000968 ecWatermarkError 0x00000969 ecNonCanonicalACL 0x0000096C ecMailboxDisabled 0x0000096D ecRulesFolderOverQuota 0x0000096E ecADUnavailable 0x0000096F ecADError 0x00000971 ecADNotFound 0x00000972 ecADPropertyError 0x00000970 ecNotEncrypted 0x00000973 ecRpcServerTooBusy 0x00000974 ecRpcOutOfMemory 0x00000975 ecRpcServerOutOfMemory 0x00000976 ecRpcOutOfResources 0x00000977 ecRpcServerUnavailable 0x0000097A ecSecureSubmitError 0x0000097C ecEventsDeleted 0x0000097D ecSubsystemStopping 0x0000097E ecSAUnavailable 0x00000A28 ecCIStopping 0x00000A29 ecFxInvalidState 0x00000A2A ecFxUnexpectedMarker 0x00000A2B ecDuplicateDelivery 0x00000A2C ecConditionViolation 0x00000A2E ecRpcInvalidHandle 0x00000A2F ecEventNotFound openchange-2.0/libmapi/conf/mapi-named-properties000066400000000000000000003304361223057412600221640ustar00rootroot00000000000000# # OpenChange MAPI implementation. # # Copyright (C) Julien Kerihuel 2007-2010. # # This program is free software; you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by # the Free Software Foundation; either version 3 of the License, or # (at your option) any later version. # # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program. If not, see . # # Mapped Property ID is used by mapistore only to generate a named # prop ldb database on purpose. Values are extracted from an existing # Exchange server we are using for development references / test # behavior. It means the value is really arbitrary and provided for # convenience purposes. ### Canonical name OOM propID propName propType Kind OLEGUID Mapped Property ID ### Meeting Properties PidLidAttendeeCriticalChange LID_ATTENDEE_CRITICAL_CHANGE 0x0001 NULL PT_SYSTIME MNID_ID PSETID_Meeting 0x9192 PidLidWhere LID_WHERE 0x0002 NULL PT_UNICODE MNID_ID PSETID_Meeting 0x9208 PidLidGlobalObjectId LID_GLOBAL_OBJID 0x0003 NULL PT_BINARY MNID_ID PSETID_Meeting 0x91ca PidLidIsSilent LID_IS_SILENT 0x0004 NULL PT_BOOLEAN MNID_ID PSETID_Meeting 0x91d0 PidLidIsRecurring LID_IS_RECURRING 0x0005 NULL PT_BOOLEAN MNID_ID PSETID_Meeting 0x91cf PidLidRequiredAttendees LID_REQUIRED_ATTENDEES 0x0006 NULL PT_UNICODE MNID_ID PSETID_Meeting 0x91f4 PidLidOptionalAttendees LID_OPTIONAL_ATTENDEES 0x0007 NULL PT_UNICODE MNID_ID PSETID_Meeting 0x91de PidLidResourceAttendees LID_RESOURCE_ATTENDEES 0x0008 NULL PT_UNICODE MNID_ID PSETID_Meeting 0x91f5 PidLidDelegateMail LID_DELEGATE_MAIL 0x0009 NULL PT_BOOLEAN MNID_ID PSETID_Meeting 0x91a4 PidLidIsException LID_IS_EXCEPTION 0x000A NULL PT_BOOLEAN MNID_ID PSETID_Meeting 0x91ce PidLidSingleInvite LID_SINGLE_INVITE 0x000B NULL PT_BOOLEAN MNID_ID PSETID_Meeting 0x91f9 PidLidTimeZone LID_TIME_ZONE 0x000C NULL PT_LONG MNID_ID PSETID_Meeting 0x9200 PidLidStartRecurrenceDate LID_START_RECUR_DATE 0x000D NULL PT_LONG MNID_ID PSETID_Meeting 0x91fc PidLidStartRecurrenceTime LID_START_RECUR_TIME 0x000E NULL PT_LONG MNID_ID PSETID_Meeting 0x91fd PidLidEndRecurrenceDate EndRecurrenceDate 0x000F NULL PT_LONG MNID_ID PSETID_Meeting 0x91be PidLidEndRecurrenceTime EndRecurrenceTime 0x0010 NULL PT_LONG MNID_ID PSETID_Meeting 0x91bf PidLidDayInterval LID_DAY_INTERVAL 0x0011 NULL PT_SHORT MNID_ID PSETID_Meeting 0x91a1 PidLidWeekInterval LID_WEEK_INTERVAL 0x0012 NULL PT_SHORT MNID_ID PSETID_Meeting 0x9206 PidLidMonthInterval LID_MONTH_INTERVAL 0x0013 NULL PT_SHORT MNID_ID PSETID_Meeting 0x91d4 PidLidYearInterval LID_YEAR_INTERVAL 0x0014 NULL PT_SHORT MNID_ID PSETID_Meeting 0x9209 PidLidMonthOfYearMask LID_MOY_MASK 0x0017 NULL PT_LONG MNID_ID PSETID_Meeting 0x91d6 PidLidOldRecurrenceType OldRecurrenceType 0x0018 NULL PT_SHORT MNID_ID PSETID_Meeting 0x91e4 PidLidOwnerCriticalChange LID_OWNER_CRITICAL_CHANGE 0x001A NULL PT_SYSTIME MNID_ID PSETID_Meeting 0x9102 PidLidUnknown001B NULL 0x001B NULL PT_NULL MNID_ID PSETID_Meeting 0x9103 PidLidCalendarType LID_CALENDAR_TYPE 0x001C NULL PT_LONG MNID_ID PSETID_Meeting 0x9194 PidLidAllAttendeesList LID_ALL_ATTENDEES_LIST 0x001D NULL PT_UNICODE MNID_ID PSETID_Meeting 0x9259 PidLidCleanGlobalObjectId CleanGlobalObjId 0x0023 NULL PT_BINARY MNID_ID PSETID_Meeting 0x9195 PidLidAppointmentMessageClass ApptMessageClass 0x0024 NULL PT_UNICODE MNID_ID PSETID_Meeting 0x9258 PidLidMeetingType MeetingType 0x0026 NULL PT_LONG MNID_ID PSETID_Meeting 0x9365 PidLidOldLocation OldLocation 0x0028 NULL PT_UNICODE MNID_ID PSETID_Meeting 0x9367 PidLidOldWhenStartWhole OldWhenStartWhole 0x0029 NULL PT_SYSTIME MNID_ID PSETID_Meeting 0x9450 PidLidOldWhenEndWhole OldWhenEndWhole 0x002A NULL PT_SYSTIME MNID_ID PSETID_Meeting 0x9451 ### Address Named Properties PidLidFileUnder FileUnder 0x8005 NULL PT_UNICODE MNID_ID PSETID_Address 0x91c2 PidLidFileUnderId FileUnderId 0x8006 NULL PT_LONG MNID_ID PSETID_Address 0x91c3 PidLidContactItemData ContactItemData 0x8007 NULL PT_MV_LONG MNID_ID PSETID_Address 0x9302 PidLidReferredBy ReferredBy 0x800E NULL PT_UNICODE MNID_ID PSETID_Address 0x90a2 PidLidDepartment Department 0x8010 NULL PT_UNICODE MNID_ID PSETID_Address 0x9301 PidLidHasPicture HasPicture 0x8015 NULL PT_BOOLEAN MNID_ID PSETID_Address 0x933c PidLidHomeAddress HomeAddress 0x801A NULL PT_UNICODE MNID_ID PSETID_Address 0x9095 PidLidWorkAddress WorkAddress 0x801B NULL PT_UNICODE MNID_ID PSETID_Address 0x90a7 PidLidOtherAddress OtherAddress 0x801C NULL PT_UNICODE MNID_ID PSETID_Address 0x909c PidLidPostalAddressId PostalAddressId 0x8022 NULL PT_LONG MNID_ID PSETID_Address 0x9098 PidLidContactCharacterSet ContactCharSet 0x8023 NULL PT_LONG MNID_ID PSETID_Address 0x930a PidLidAutoLog AutoLog 0x8025 NULL PT_BOOLEAN MNID_ID PSETID_Address 0x9304 PidLidFileUnderList FileUnderList 0x8026 NULL PT_MV_LONG MNID_ID PSETID_Address 0x92ff PidLidEmailList EmailList 0x8027 NULL PT_MV_LONG MNID_ID PSETID_Address 0x9300 PidLidAddressBookProviderEmailList ABPEmailList 0x8028 NULL PT_MV_LONG MNID_ID PSETID_Address 0x91bc PidLidAddressBookProviderArrayType ABPArrayType 0x8029 NULL PT_LONG MNID_ID PSETID_Address 0x91bd PidLidHtml HTML 0x802B NULL PT_UNICODE MNID_ID PSETID_Address 0x930d PidLidYomiFirstName YomiFirstName 0x802C NULL PT_UNICODE MNID_ID PSETID_Address 0x9151 PidLidYomiLastName YomiLastName 0x802D NULL PT_UNICODE MNID_ID PSETID_Address 0x9152 PidLidYomiCompanyName YomiCompanyName 0x802E NULL PT_UNICODE MNID_ID PSETID_Address 0x9153 PidLidBusinessCardDisplayDefinition BCDisplayDefinition 0x8040 NULL PT_BINARY MNID_ID PSETID_Address 0x933d PidLidBusinessCardCardPicture BCCardPicture 0x8041 NULL PT_BINARY MNID_ID PSETID_Address 0x933e PidLidWorkAddressStreet WorkAddressStreet 0x8045 NULL PT_UNICODE MNID_ID PSETID_Address 0x90a6 PidLidWorkAddressCity WorkAddressCity 0x8046 NULL PT_UNICODE MNID_ID PSETID_Address 0x9097 PidLidWorkAddressState WorkAddressState 0x8047 NULL PT_UNICODE MNID_ID PSETID_Address 0x90a5 PidLidWorkAddressPostalCode WorkAddressPostalCode 0x8048 NULL PT_UNICODE MNID_ID PSETID_Address 0x909e PidLidWorkAddressCountry WorkAddressCountry 0x8049 NULL PT_UNICODE MNID_ID PSETID_Address 0x908d PidLidWorkAddressPostOfficeBox WorkAddressPostOfficeBox 0x804A NULL PT_UNICODE MNID_ID PSETID_Address 0x909f PidLidDistributionListChecksum DLChecksum 0x804C NULL PT_LONG MNID_ID PSETID_Address 0x91a6 PidLidBirthdayEventEntryId BirthdayEventEID 0x804D NULL PT_BINARY MNID_ID PSETID_Address 0x9422 PidLidAnniversaryEventEntryId AnniversaryEventEID 0x804E NULL PT_BINARY MNID_ID PSETID_Address 0x9423 PidLidContactUserField1 ContactUserField1 0x804F NULL PT_UNICODE MNID_ID PSETID_Address 0x913c PidLidContactUserField2 ContactUserField2 0x8050 NULL PT_UNICODE MNID_ID PSETID_Address 0x913d PidLidContactUserField3 ContactUserField3 0x8051 NULL PT_UNICODE MNID_ID PSETID_Address 0x913e PidLidContactUserField4 ContactUserField4 0x8052 NULL PT_UNICODE MNID_ID PSETID_Address 0x913f PidLidDistributionListName DLName 0x8053 NULL PT_UNICODE MNID_ID PSETID_Address 0x91a8 PidLidDistributionListOneOffMembers DLOneOffMembers 0x8054 NULL PT_MV_BINARY MNID_ID PSETID_Address 0x91a9 PidLidDistributionListMembers DLMembers 0x8055 NULL PT_MV_BINARY MNID_ID PSETID_Address 0x91a7 PidLidInstantMessagingAddress InstMsg 0x8062 NULL PT_UNICODE MNID_ID PSETID_Address 0x92a6 PidLidDistributionListStream DLStream 0x8064 NULL PT_LONG MNID_ID PSETID_Address 0x9421 PidLidEmail1DisplayName Email1DisplayName 0x8080 NULL PT_UNICODE MNID_ID PSETID_Address 0x91af PidLidEmail1AddressType Email1AddrType 0x8082 NULL PT_UNICODE MNID_ID PSETID_Address 0x91ad PidLidEmail1EmailAddress Email1EmailAddress 0x8083 NULL PT_UNICODE MNID_ID PSETID_Address 0x91ae PidLidEmail1OriginalDisplayName Email1OriginalDisplayName 0x8084 NULL PT_UNICODE MNID_ID PSETID_Address 0x91b0 PidLidEmail1OriginalEntryId Email1OriginalEntryID 0x8085 NULL PT_BINARY MNID_ID PSETID_Address 0x91b1 PidLidEmail1RichTextFormat Email1RichTextFormat 0x8086 NULL PT_BOOLEAN MNID_ID PSETID_Address 0x929c PidLidEmail1EmailType Email1EmailType 0x8087 NULL PT_UNICODE MNID_ID PSETID_Address 0x9325 PidLidEmail2DisplayName Email2DisplayName 0x8090 NULL PT_UNICODE MNID_ID PSETID_Address 0x91b4 PidLidEmail2EntryId Email2EntryID 0x8091 NULL PT_BINARY MNID_ID PSETID_Address 0x9326 PidLidEmail2AddressType Email2AddrType 0x8092 NULL PT_UNICODE MNID_ID PSETID_Address 0x91b2 PidLidEmail2EmailAddress Email2EmailAddress 0x8093 NULL PT_UNICODE MNID_ID PSETID_Address 0x91b3 PidLidEmail2OriginalDisplayName Email2OriginalDisplayName 0x8094 NULL PT_UNICODE MNID_ID PSETID_Address 0x91b5 PidLidEmail2OriginalEntryId Email2OriginalEntryID 0x8095 NULL PT_BINARY MNID_ID PSETID_Address 0x91b6 PidLidEmail2RichTextFormat Email2RichTextFormat 0x8096 NULL PT_BOOLEAN MNID_ID PSETID_Address 0x929d PidLidEmail3DisplayName Email3DisplayName 0x80A0 NULL PT_UNICODE MNID_ID PSETID_Address 0x91b9 PidLidEmail3EntryId Email3EntryID 0x80A1 NULL PT_BINARY MNID_ID PSETID_Address 0x9328 PidLidEmail3AddressType Email3AddrType 0x80A2 NULL PT_UNICODE MNID_ID PSETID_Address 0x91b7 PidLidEmail3EmailAddress Email3EmailAddress 0x80A3 NULL PT_UNICODE MNID_ID PSETID_Address 0x91b8 PidLidEmail3OriginalDisplayName Email3OriginalDisplayName 0x80A4 NULL PT_UNICODE MNID_ID PSETID_Address 0x91ba PidLidEmail3OriginalEntryId Email3OriginalEntryID 0x80A5 NULL PT_BINARY MNID_ID PSETID_Address 0x91bb PidLidEmail3RichTextFormat Email3RichTextFormat 0x80A6 NULL PT_BOOLEAN MNID_ID PSETID_Address 0x929e PidLidFax1AddressType Fax1AddrType 0x80B2 NULL PT_UNICODE MNID_ID PSETID_Address 0x9295 PidLidFax1EmailAddress Fax1EmailAddress 0x80B3 NULL PT_UNICODE MNID_ID PSETID_Address 0x9292 PidLidFax1OriginalDisplayName Fax1OriginalDisplayName 0x80B4 NULL PT_UNICODE MNID_ID PSETID_Address 0x9298 PidLidFax1OriginalEntryId Fax1OriginalEntryID 0x80B5 NULL PT_BINARY MNID_ID PSETID_Address 0x929b PidLidFax2AddressType Fax2AddrType 0x80C2 NULL PT_UNICODE MNID_ID PSETID_Address 0x9293 PidLidFax2EmailAddress Fax2EmailAddress 0x80C3 NULL PT_UNICODE MNID_ID PSETID_Address 0x9290 PidLidFax2OriginalDisplayName Fax2OriginalDisplayName 0x80C4 NULL PT_UNICODE MNID_ID PSETID_Address 0x9296 PidLidFax2OriginalEntryId Fax2OriginalEntryID 0x80C5 NULL PT_BINARY MNID_ID PSETID_Address 0x9299 PidLidFax3AddressType Fax3AddrType 0x80D2 NULL PT_UNICODE MNID_ID PSETID_Address 0x9294 PidLidFax3EmailAddress Fax3EmailAddress 0x80D3 NULL PT_UNICODE MNID_ID PSETID_Address 0x9291 PidLidFax3OriginalDisplayName Fax3OriginalDisplayName 0x80D4 NULL PT_UNICODE MNID_ID PSETID_Address 0x9297 PidLidFax3OriginalEntryId Fax3OriginalEntryID 0x80D5 NULL PT_BINARY MNID_ID PSETID_Address 0x929a PidLidFreeBusyLocation FreeBusyLocation 0x80D8 NULL PT_UNICODE MNID_ID PSETID_Address 0x9106 PidLidHomeAddressCountryCode HomeAddressCountryCode 0x80DA NULL PT_UNICODE MNID_ID PSETID_Address 0x9307 PidLidWorkAddressCountryCode WorkAddressCountryCode 0x80DB NULL PT_UNICODE MNID_ID PSETID_Address 0x9306 PidLidOtherAddressCountryCode OtherAddressCountryCode 0x80DC NULL PT_UNICODE MNID_ID PSETID_Address 0x9308 PidLidBirthdayLocal BirthdayLocal 0x80DE NULL PT_SYSTIME MNID_ID PSETID_Address PidLidAddressCountryCode AddressCountryCode 0x80DD NULL PT_UNICODE MNID_ID PSETID_Address 0x9309 PidLidWeddingAnniversaryLocal ApptAnniversaryLocal 0x80DF NULL PT_SYSTIME MNID_ID PSETID_Address ### Task Named Properties PidLidTaskStatus TaskStatus 0x8101 NULL PT_LONG MNID_ID PSETID_Task 0x9120 PidLidPercentComplete PercentComplete 0x8102 NULL PT_DOUBLE MNID_ID PSETID_Task 0x9121 PidLidTeamTask TeamTask 0x8103 NULL PT_BOOLEAN MNID_ID PSETID_Task 0x9135 PidLidTaskStartDate TaskStartDate 0x8104 NULL PT_SYSTIME MNID_ID PSETID_Task 0x911e PidLidTaskDueDate TaskDueDate 0x8105 NULL PT_SYSTIME MNID_ID PSETID_Task 0x911f PidLidTaskResetReminder TaskResetReminder 0x8107 NULL PT_BOOLEAN MNID_ID PSETID_Task 0x9137 PidLidTaskAccepted TaskAccepted 0x8108 NULL PT_BOOLEAN MNID_ID PSETID_Task 0x9344 PidLidTaskDeadOccurrence TaskDeadOccur 0x8109 NULL PT_BOOLEAN MNID_ID PSETID_Task 0x9127 PidLidTaskDateCompleted TaskDateCompleted 0x810F NULL PT_SYSTIME MNID_ID PSETID_Task 0x9125 PidLidTaskActualEffort TaskActualEffort 0x8110 NULL PT_LONG MNID_ID PSETID_Task 0x9128 PidLidTaskEstimatedEffort TaskEstimatedEffort 0x8111 NULL PT_LONG MNID_ID PSETID_Task 0x9129 PidLidTaskVersion TaskVersion 0x8112 NULL PT_LONG MNID_ID PSETID_Task 0x9133 PidLidTaskState TaskState 0x8113 NULL PT_LONG MNID_ID PSETID_Task 0x9123 PidLidTaskLastUpdate TaskLastUpdate 0x8115 NULL PT_SYSTIME MNID_ID PSETID_Task 0x912e PidLidTaskRecurrence TaskRecur 0x8116 NULL PT_BINARY MNID_ID PSETID_Task 0x9136 PidLidTaskAssigners TaskMyDelegators 0x8117 NULL PT_BINARY MNID_ID PSETID_Task 0x934a PidLidTaskStatusOnComplete TaskSOC 0x8119 NULL PT_BOOLEAN MNID_ID PSETID_Task 0x9346 PidLidTaskHistory TaskHistory 0x811A NULL PT_LONG MNID_ID PSETID_Task 0x912b PidLidTaskUpdates TaskUpdates 0x811B NULL PT_BOOLEAN MNID_ID PSETID_Task 0x9345 PidLidTaskComplete TaskComplete 0x811C NULL PT_BOOLEAN MNID_ID PSETID_Task 0x9124 PidLidTaskFCreator TaskFCreator 0x811E NULL PT_BOOLEAN MNID_ID PSETID_Task 0x934c PidLidTaskOwner TaskOwner 0x811F NULL PT_UNICODE MNID_ID PSETID_Task 0x9122 PidLidTaskMultipleRecipients TaskMultRecips 0x8120 NULL PT_LONG MNID_ID PSETID_Task 0x912a PidLidTaskAssigner TaskDelegator 0x8121 NULL PT_UNICODE MNID_ID PSETID_Task 0x9134 PidLidTaskLastUser TaskLastUser 0x8122 NULL PT_UNICODE MNID_ID PSETID_Task 0x912d PidLidTaskOrdinal TaskOrdinal 0x8123 NULL PT_LONG MNID_ID PSETID_Task 0x9138 PidLidTaskNoCompute TaskNoCompute 0x8124 NULL PT_BOOLEAN MNID_ID PSETID_Task 0x9130 PidLidTaskLastDelegate TaskLastDelegate 0x8125 NULL PT_UNICODE MNID_ID PSETID_Task 0x9347 PidLidTaskFRecurring TaskFRecur 0x8126 NULL PT_BOOLEAN MNID_ID PSETID_Task 0x9126 PidLidTaskRole TaskRole 0x8127 NULL PT_UNICODE MNID_ID PSETID_Task 0x9132 PidLidTaskOwnership TaskOwnership 0x8129 NULL PT_LONG MNID_ID PSETID_Task 0x912f PidLidAcceptanceState TaskDelegValue 0x812A NULL PT_LONG MNID_ID PSETID_Task 0x912c PidLidTaskFFixOffline TaskFFixOffline 0x812C NULL PT_BOOLEAN MNID_ID PSETID_Task 0x9131 PidLidTaskCustomFlags TaskActualEffort 0x8139 NULL PT_LONG MNID_ID PSETID_Task 0x9428 PidLidTrustRecipientHighlights TrustRecipHighlights 0x823E NULL PT_BOOLEAN MNID_ID PSETID_Task ### Appointment Named Properties PidLidSendMeetingAsIcal SendMtgAsICAL 0x8200 NULL PT_BOOLEAN MNID_ID PSETID_Appointment 0x9252 PidLidAppointmentSequence ApptSequence 0x8201 NULL PT_LONG MNID_ID PSETID_Appointment 0x9253 PidLidAppointmentSequenceTime ApptSeqTime 0x8202 NULL PT_SYSTIME MNID_ID PSETID_Appointment 0x9254 PidLidAppointmentLastSequence ApptLastSequence 0x8203 NULL PT_LONG MNID_ID PSETID_Appointment 0x9256 PidLidChangeHighlight ChangeHighlight 0x8204 NULL PT_LONG MNID_ID PSETID_Appointment 0x9354 PidLidBusyStatus BusyStatus 0x8205 NULL PT_LONG MNID_ID PSETID_Appointment 0x9193 PidLidFExceptionalBody FExceptionalBody 0x8206 NULL PT_BOOLEAN MNID_ID PSETID_Appointment 0x924b PidLidAppointmentAuxiliaryFlags ApptAuxFlags 0x8207 NULL PT_LONG MNID_ID PSETID_Appointment 0x9245 PidLidLocation Location 0x8208 NULL PT_UNICODE MNID_ID PSETID_Appointment 0x910c PidLidMeetingWorkspaceUrl MWSURL 0x8209 NULL PT_UNICODE MNID_ID PSETID_Appointment 0x91d1 PidLidForwardInstance FwrdInstance 0x820A NULL PT_BOOLEAN MNID_ID PSETID_Appointment 0x9257 PidLidLinkedTaskItems LinkedTaskItems 0x820C NULL PT_MV_BINARY MNID_ID PSETID_Appointment 0x9430 PidLidAppointmentStartWhole ApptStartWhole 0x820D NULL PT_SYSTIME MNID_ID PSETID_Appointment 0x918f PidLidAppointmentEndWhole ApptEndWhole 0x820E NULL PT_SYSTIME MNID_ID PSETID_Appointment 0x918a PidLidAppointmentStartTime ApptStartTime 0x820F NULL PT_SYSTIME MNID_ID PSETID_Appointment 0x918e PidLidAppointmentEndTime ApptEndTime 0x8210 NULL PT_SYSTIME MNID_ID PSETID_Appointment 0x9189 PidLidAppointmentEndDate ApptEndDate 0x8211 NULL PT_SYSTIME MNID_ID PSETID_Appointment 0x9188 PidLidAppointmentStartDate ApptStartDate 0x8212 NULL PT_SYSTIME MNID_ID PSETID_Appointment 0x918d PidLidAppointmentDuration ApptDuration 0x8213 NULL PT_LONG MNID_ID PSETID_Appointment 0x9187 PidLidAppointmentColor ApptColor 0x8214 NULL PT_LONG MNID_ID PSETID_Appointment 0x9241 PidLidAppointmentSubType ApptSubType 0x8215 NULL PT_BOOLEAN MNID_ID PSETID_Appointment 0x90fa PidLidAppointmentRecur ApptRecur 0x8216 NULL PT_BINARY MNID_ID PSETID_Appointment 0x918b PidLidAppointmentStateFlags ApptStateFlags 0x8217 NULL PT_LONG MNID_ID PSETID_Appointment 0x9190 PidLidResponseStatus ResponseStatus 0x8218 NULL PT_LONG MNID_ID PSETID_Appointment 0x90fc PidLidAppointmentReplyTime ApptReplyTime 0x8220 NULL PT_SYSTIME MNID_ID PSETID_Appointment 0x9114 PidLidRecurring Recurring 0x8223 NULL PT_BOOLEAN MNID_ID PSETID_Appointment 0x91e7 PidLidIntendedBusyStatus IntendedBusyStatus 0x8224 NULL PT_LONG MNID_ID PSETID_Appointment 0x91cc PidLidUnknown8225 NULL 0x8225 NULL PT_NULL MNID_ID PSETID_Appointment 0x91cd PidLidAppointmentUpdateTime ApptUpdateTime 0x8226 NULL PT_SYSTIME MNID_ID PSETID_Appointment 0x9191 PidLidExceptionReplaceTime ExceptionReplaceTime 0x8228 NULL PT_SYSTIME MNID_ID PSETID_Appointment 0x9249 PidLidFInvited FInvited 0x8229 NULL PT_BOOLEAN MNID_ID PSETID_Appointment 0x91c4 PidLidFExceptionalAttendees FExceptionalAttendees 0x822B NULL PT_BOOLEAN MNID_ID PSETID_Appointment 0x924a PidLidUnknown822c NULL 0x822C NULL PT_NULL MNID_ID PSETID_Appointment 0x924c PidLidUnknown822d NULL 0x822D NULL PT_NULL MNID_ID PSETID_Appointment 0x924e PidLidOwnerName OwnerName 0x822E NULL PT_UNICODE MNID_ID PSETID_Appointment 0x91e0 PidLidFOthersAppointment FOthersAppt 0x822F NULL PT_BOOLEAN MNID_ID PSETID_Appointment 0x91c8 PidLidAppointmentReplyName ApptReplyName 0x8230 NULL PT_UNICODE MNID_ID PSETID_Appointment 0x918c PidLidRecurrenceType RecurType 0x8231 NULL PT_LONG MNID_ID PSETID_Appointment 0x91e8 PidLidRecurrencePattern RecurPattern 0x8232 NULL PT_UNICODE MNID_ID PSETID_Appointment 0x91e6 PidLidTimeZoneStruct TimeZoneStruct 0x8233 NULL PT_BINARY MNID_ID PSETID_Appointment 0x9202 PidLidTimeZoneDescription TimeZoneDesc 0x8234 NULL PT_UNICODE MNID_ID PSETID_Appointment 0x9201 PidLidClipStart ClipStart 0x8235 NULL PT_SYSTIME MNID_ID PSETID_Appointment 0x9197 PidLidClipEnd ClipEnd 0x8236 NULL PT_SYSTIME MNID_ID PSETID_Appointment 0x9196 PidLidOriginalStoreEntryId OrigStoreEid 0x8237 NULL PT_BINARY MNID_ID PSETID_Appointment 0x91df PidLidAllAttendeesString AllAttendeesString 0x8238 NULL PT_UNICODE MNID_ID PSETID_Appointment 0x9186 PidLidAutoFillLocation AutoFillLocation 0x823A NULL PT_BOOLEAN MNID_ID PSETID_Appointment 0x9255 PidLidToAttendeesString ToAttendeesString 0x823B NULL PT_UNICODE MNID_ID PSETID_Appointment 0x924c PidLidCcAttendeesString CcAttendeesString 0x823C NULL PT_UNICODE MNID_ID PSETID_Appointment 0x924d PidLidConferencingCheck ConfCheck 0x8240 NULL PT_BOOLEAN MNID_ID PSETID_Appointment 0x923a PidLidConferencingType ConfType 0x8241 NULL PT_LONG MNID_ID PSETID_Appointment 0x923b PidLidDirectory Directory 0x8242 NULL PT_UNICODE MNID_ID PSETID_Appointment 0x923d PidLidOrganizerAlias OrgAlias 0x8243 NULL PT_UNICODE MNID_ID PSETID_Appointment 0x923c PidLidAutoStartCheck AutoStartCheck 0x8244 NULL PT_BOOLEAN MNID_ID PSETID_Appointment 0x923e PidLidAutoStartWhen AutoStartWhen 0x8245 NULL PT_LONG MNID_ID PSETID_Appointment 0x924f PidLidAllowExternalCheck AllowExternCheck 0x8246 NULL PT_BOOLEAN MNID_ID PSETID_Appointment 0x9250 PidLidCollaborateDoc CollaborateDoc 0x8247 NULL PT_UNICODE MNID_ID PSETID_Appointment 0x923f PidLidNetShowUrl NetShowURL 0x8248 NULL PT_UNICODE MNID_ID PSETID_Appointment 0x9240 PidLidOnlinePassword OnlinePassword 0x8249 NULL PT_UNICODE MNID_ID PSETID_Appointment 0x9251 PidLidAppointmentProposedStartWhole ApptProposedStartWhole 0x8250 NULL PT_SYSTIME MNID_ID PSETID_Appointment 0x9242 PidLidAppointmentProposedEndWhole ApptProposedEndWhole 0x8251 NULL PT_SYSTIME MNID_ID PSETID_Appointment 0x9243 PidLidAppointmentProposedDuration ApptProposedDuration 0x8256 NULL PT_LONG MNID_ID PSETID_Appointment 0x9244 PidLidAppointmentCounterProposal ApptCounterProposal 0x8257 NULL PT_BOOLEAN MNID_ID PSETID_Appointment 0x9246 PidLidAppointmentProposalNumber ApptProposalNum 0x8259 NULL PT_LONG MNID_ID PSETID_Appointment 0x9247 PidLidAppointmentNotAllowPropose ApptNotAllowPropose 0x825A NULL PT_BOOLEAN MNID_ID PSETID_Appointment 0x9248 PidLidAppointmentUnsendableRecipients ApptUnsendableRecipients 0x825D NULL PT_BINARY MNID_ID PSETID_Appointment 0x942f PidLidAppointmentTimeZoneDefinitionStartDisplay ApptTZDefStartDisplay 0x825E NULL PT_BINARY MNID_ID PSETID_Appointment 0x942c PidLidAppointmentTimeZoneDefinitionEndDisplay ApptTZDefEndDisplay 0x825F NULL PT_BINARY MNID_ID PSETID_Appointment 0x942d PidLidAppointmentTimeZoneDefinitionRecur ApptTZDefRecur 0x8260 NULL PT_BINARY MNID_ID PSETID_Appointment 0x942e PidLidForwardNotificationRecipients ForwardNotificationRecipients 0x8261 NULL PT_BINARY MNID_ID PSETID_Appointment PidLidInboundICalStream InboundICalStream 0x827A NULL PT_BINARY MNID_ID PSETID_Appointment PidLidSingleBodyIcal IsSingleBodyIcal 0x827B NULL PT_BOOLEAN MNID_ID PSETID_Appointment ### Common Named properties PidLidDayOfMonth DayOfMonth 0x1000 NULL PT_LONG MNID_ID PSETID_Common 0x91a2 PidLidICalendarDayOfWeekMask ICalendarDayOfWeekMask 0x1001 NULL PT_LONG MNID_ID PSETID_Common 0x91a3 PidLidUnknown1003 NULL 0x1003 NULL PT_NULL MNID_ID PSETID_Common 0x91a5 PidLidUnknown1004 NULL 0x1004 NULL PT_NULL MNID_ID PSETID_Common 0x91a7 PidLidOccurrences Occurrences 0x1005 NULL PT_LONG MNID_ID PSETID_Common 0x91dd PidLidMonthOfYear MonthOfYear 0x1006 NULL PT_LONG MNID_ID PSETID_Common 0x91d5 PidLidUnknown100a NULL 0x100A NULL PT_LONG MNID_ID PSETID_Common 0x91aa PidLidNoEndDateFlag NoEndDateFlag 0x100B NULL PT_BOOLEAN MNID_ID PSETID_Common 0x91c5 PidLidRecurrenceDuration RecurrenceDuration 0x100D NULL PT_LONG MNID_ID PSETID_Common 0x91e5 PidLidUnknown100f NULL 0x100F NULL PT_NULL MNID_ID PSETID_Common 0x91f6 PidLidReminderDelta ReminderDelta 0x8501 NULL PT_LONG MNID_ID PSETID_Common 0x91e9 PidLidReminderTime ReminderTime 0x8502 NULL PT_SYSTIME MNID_ID PSETID_Common 0x91ef PidLidReminderSet ReminderSet 0x8503 NULL PT_BOOLEAN MNID_ID PSETID_Common 0x91ee PidLidReminderTimeTime ReminderTimeTime 0x8504 NULL PT_SYSTIME MNID_ID PSETID_Common 0x91f1 PidLidReminderTimeDate ReminderTimeDate 0x8505 NULL PT_SYSTIME MNID_ID PSETID_Common 0x91f0 PidLidPrivate Private 0x8506 NULL PT_BOOLEAN MNID_ID PSETID_Common 0x9224 PidLidAgingDontAgeMe AgingDontAgeMe 0x850E NULL PT_BOOLEAN MNID_ID PSETID_Common 0x9185 PidLidSideEffects SideEffects 0x8510 NULL PT_LONG MNID_ID PSETID_Common 0x91f8 PidLidRemoteStatus RemoteStatus 0x8511 NULL PT_LONG MNID_ID PSETID_Common 0x91f3 PidLidSmartNoAttach SmartNoAttach 0x8514 NULL PT_BOOLEAN MNID_ID PSETID_Common 0x91fa PidLidCommonStart CommonStart 0x8516 NULL PT_SYSTIME MNID_ID PSETID_Common 0x9199 PidLidCommonEnd CommonEnd 0x8517 NULL PT_SYSTIME MNID_ID PSETID_Common 0x9198 PidLidTaskMode TaskMode 0x8518 NULL PT_LONG MNID_ID PSETID_Common 0x91ff PidLidTaskGlobalId TaskGlobalObjId 0x8519 NULL PT_BINARY MNID_ID PSETID_Common 0x91fe PidLidAutoProcessState SniffState 0x851A NULL PT_LONG MNID_ID PSETID_Common 0x91fb PidLidReminderOverride ReminderOverride 0x851C NULL PT_BOOLEAN MNID_ID PSETID_Common 0x91ec PidLidReminderType ReminderType 0x851D NULL PT_LONG MNID_ID PSETID_Common 0x91f2 PidLidReminderPlaySound ReminderPlaySound 0x851E NULL PT_BOOLEAN MNID_ID PSETID_Common 0x91ed PidLidReminderFileParameter ReminderFileParam 0x851F NULL PT_UNICODE MNID_ID PSETID_Common 0x91ea PidLidVerbStream VerbStream 0x8520 NULL PT_BINARY MNID_ID PSETID_Common 0x9204 PidLidVerbResponse VerbResponse 0x8524 NULL PT_UNICODE MNID_ID PSETID_Common 0x9203 PidLidFlagRequest Request 0x8530 NULL PT_UNICODE MNID_ID PSETID_Common 0x9027 PidLidMileage MileAge 0x8534 NULL PT_UNICODE MNID_ID PSETID_Common 0x914a PidLidBillingInformation BillingInformation 0x8535 NULL PT_UNICODE MNID_ID PSETID_Common 0x908b PidLidNonSendtableTo NonSendableTo 0x8536 NULL PT_UNICODE MNID_ID PSETID_Common 0x91d9 PidLidNonSendableCc NonSendableCC 0x8537 NULL PT_UNICODE MNID_ID PSETID_Common 0x91d8 PidLidNonSendableBcc NonSendableBCC 0x8538 NULL PT_UNICODE MNID_ID PSETID_Common 0x91d7 PidLidCompanies Companies 0x8539 NULL PT_MV_STRING8 MNID_ID PSETID_Common 0x913a PidLidContacts Contacts 0x853A NULL PT_MV_STRING8 MNID_ID PSETID_Common 0x919b PidLidNonSendToTrackStatus NonSendToTrackStatus 0x8543 NULL PT_MV_LONG MNID_ID PSETID_Common 0x91dc PidLidNonSendCcTrackStatus NonSendCcTrackStatus 0x8544 NULL PT_MV_LONG MNID_ID PSETID_Common 0x91db PidLidNonSendBccTrackStatus NonSendBccTrackStatus 0x8545 NULL PT_MV_LONG MNID_ID PSETID_Common 0x91da PidLidCurrentVersion CurrentVersion 0x8552 NULL PT_LONG MNID_ID PSETID_Common 0x919d PidLidCurrentVersionName CurrentVersionName 0x8554 NULL PT_UNICODE MNID_ID PSETID_Common 0x919e PidLidReminderSignalTime ReminderNextTime 0x8560 NULL PT_SYSTIME MNID_ID PSETID_Common 0x91eb PidLidImapDeleted ImapDeleted 0x8570 NULL PT_LONG MNID_ID PSETID_Common 0x94e5 PidLidHeaderItem HeaderItem 0x8578 NULL PT_LONG MNID_ID PSETID_Common 0x94e6 PidLidInternetAccountName InetAcctName 0x8580 NULL PT_UNICODE MNID_ID PSETID_Common 0x9225 PidLidInternetAccountStamp InetAcctStamp 0x8581 NULL PT_UNICODE MNID_ID PSETID_Common 0x9226 PidLidUseTnef UseTNEF 0x8582 NULL PT_BOOLEAN MNID_ID PSETID_Common 0x9227 PidLidContactLinkSearchKey ContactLinkSearchKey 0x8584 NULL PT_BINARY MNID_ID PSETID_Common 0x922b PidLidContactLinkEntry ContactLinkEntry 0x8585 NULL PT_BINARY MNID_ID PSETID_Common 0x922a PidLidContactLinkName ContactLinkName 0x8586 NULL PT_UNICODE MNID_ID PSETID_Common 0x9229 PidLidSpamOriginalFolder SpamOriginalFolder 0x859C NULL PT_BINARY MNID_ID PSETID_Common 0x9237 PidLidToDoOrdinalDate ToDoOrdinalDate 0x85A0 NULL PT_SYSTIME MNID_ID PSETID_Common 0x935f PidLidToDoSubOrdinal ToDoSubOrdinal 0x85A1 NULL PT_UNICODE MNID_ID PSETID_Common 0x9360 PidLidToDoTitle ToDoTitle 0x85A4 NULL PT_UNICODE MNID_ID PSETID_Common 0x9361 PidLidInfoPathFormName InfoPathFormName 0x85B1 NULL PT_UNICODE MNID_ID PSETID_Common 0x9433 PidLidClassified Classified 0x85B5 NULL PT_BOOLEAN MNID_ID PSETID_Common 0x9439 PidLidClassification Classification 0x85B6 NULL PT_UNICODE MNID_ID PSETID_Common 0x943a PidLidClassificationDescription ClassDesc 0x85B7 NULL PT_UNICODE MNID_ID PSETID_Common 0x943b PidLidClassificationGuid ClassGuid 0x85B8 NULL PT_UNICODE MNID_ID PSETID_Common 0x943c PidLidClassificationKeep ClassKeep 0x85BA NULL PT_BOOLEAN MNID_ID PSETID_Common 0x943e PidLidReferenceEntryId ReferenceEID 0x85BD NULL PT_BINARY MNID_ID PSETID_Common 0x9440 PidLidValidFlagStringProof ValidFlagStringProof 0x85BF NULL PT_SYSTIME MNID_ID PSETID_Common 0x9442 PidLidFlagString FlagStringEnum 0x85C0 NULL PT_LONG MNID_ID PSETID_Common 0x9443 PidLidConversationActionMoveFolderEid ConversationActionMoveFolderEid 0x85C6 NULL PT_BINARY MNID_ID PSETID_Common PidLidConversationActionMoveStoreEid ConversationActionMoveStoreEid 0x85C7 NULL PT_BINARY MNID_ID PSETID_Common PidLidConversationActionMaxDeliveryTime ConversationActionMaxDeliveryTime 0x85C8 NULL PT_SYSTIME MNID_ID PSETID_Common PidLidConversationProcessed ConversationProcessed 0x85C9 NULL PT_LONG MNID_ID PSETID_Common PidLidConversationActionLastAppliedTime ConversationActionLastAppliedTime 0x85CA NULL PT_SYSTIME MNID_ID PSETID_Common PidLidConversationActionVersion ConversationActionVersion 0x85CB NULL PT_LONG MNID_ID PSETID_Common ### Log Named Properties PidLidLogType LogType 0x8700 NULL PT_UNICODE MNID_ID PSETID_Log 0x92b6 PidLidLogStart LogStart 0x8706 NULL PT_SYSTIME MNID_ID PSETID_Log 0x92b9 PidLidLogDuration LogDuration 0x8707 NULL PT_LONG MNID_ID PSETID_Log 0x92bb PidLidLogEnd LogEnd 0x8708 NULL PT_SYSTIME MNID_ID PSETID_Log 0x92ba PidLidLogFlags LogFlags 0x870C NULL PT_LONG MNID_ID PSETID_Log 0x92bc PidLidDocumentPrinted LogDocPrinted 0x870E NULL PT_BOOLEAN MNID_ID PSETID_Log 0x92be PidLidDocumentSaved LogDocSaved 0x870F NULL PT_BOOLEAN MNID_ID PSETID_Log 0x92bf PidLidDocumentRouted LogDocRouted 0x8710 NULL PT_BOOLEAN MNID_ID PSETID_Log 0x92c0 PidLidDocumentPosted LogDocPosted 0x8711 NULL PT_BOOLEAN MNID_ID PSETID_Log 0x92c1 PidLidLogTypeDesc LogTypeDesc 0x8712 NULL PT_UNICODE MNID_ID PSETID_Log 0x92b5 ### Post RSS Named Properties PidLidPostRssChannelLink PostRssChannelLink 0x8900 NULL PT_UNICODE MNID_ID PSETID_PostRss 0x92af PidLidPostRssItemLink PostRssItemLink 0x8901 NULL PT_UNICODE MNID_ID PSETID_PostRss 0x92b0 PidLidPostRssItemHash PostRssItemHash 0x8902 NULL PT_LONG MNID_ID PSETID_PostRss 0x92b1 PidLidPostRssItemGuid PostRssItemGuid 0x8903 NULL PT_UNICODE MNID_ID PSETID_PostRss 0x92b2 PidLidPostRssChannel PostRssChannel 0x8904 NULL PT_UNICODE MNID_ID PSETID_PostRss 0x92b3 PidLidPostRssItemXml PostRssItemXml 0x8905 NULL PT_UNICODE MNID_ID PSETID_PostRss 0x92b4 PidLidPostRssSubscription PostRssSubscription 0x8906 NULL PT_UNICODE MNID_ID PSETID_PostRss 0x9447 ### Sharing Named Properties PidLidSharingStatus SharingStatus 0x8A00 NULL PT_LONG MNID_ID PSETID_Sharing 0x92c4 PidLidSharingProviderGuid SharingProviderGuid 0x8A01 NULL PT_BINARY MNID_ID PSETID_Sharing 0x92c9 PidLidSharingProviderName SharingProviderName 0x8A02 NULL PT_UNICODE MNID_ID PSETID_Sharing 0x92ca PidLidSharingProviderUrl SharingProviderUrl 0x8A03 NULL PT_UNICODE MNID_ID PSETID_Sharing 0x92cb PidLidSharingRemotePath SharingRemotePath 0x8A04 NULL PT_UNICODE MNID_ID PSETID_Sharing 0x92cc PidLidSharingRemoteName SharingRemoteName 0x8A05 NULL PT_UNICODE MNID_ID PSETID_Sharing 0x92cd PidLidSharingRemoteUid SharingRemoteUid 0x8A06 NULL PT_UNICODE MNID_ID PSETID_Sharing 0x92ce PidLidSharingInitiatorName SharingInitiatorName 0x8A07 NULL PT_UNICODE MNID_ID PSETID_Sharing 0x92d0 PidLidSharingInitiatorSmtp SharingInitiatorSmtp 0x8A08 NULL PT_UNICODE MNID_ID PSETID_Sharing 0x92d1 PidLidSharingInitiatorEntryId SharingInitiatorEid 0x8A09 NULL PT_BINARY MNID_ID PSETID_Sharing 0x92d2 PidLidSharingFlags SharingFlags 0x8A0A NULL PT_LONG MNID_ID PSETID_Sharing 0x9214 PidLidSharingProviderExtension SharingProviderExtension 0x8A0B NULL PT_UNICODE MNID_ID PSETID_Sharing 0x944c PidLidSharingRemoteUser SharingRemoteUser 0x8A0C NULL PT_UNICODE MNID_ID PSETID_Sharing 0x94da PidLidSharingRemotePass SharingRemotePass 0x8A0D NULL PT_UNICODE MNID_ID PSETID_Sharing 0x92db PidLidSharingLocalPath SharingLocalPath 0x8A0E NULL PT_UNICODE MNID_ID PSETID_Sharing 0x92d6 PidLidSharingLocalName SharingLocalName 0x8A0F NULL PT_UNICODE MNID_ID PSETID_Sharing 0x92d7 PidLidSharingLocalUid SharingLocalUid 0x8A10 NULL PT_UNICODE MNID_ID PSETID_Sharing 0x92d8 PidLidSharingFilter SharingFilter 0x8A13 NULL PT_BINARY MNID_ID PSETID_Sharing 0x92d3 PidLidSharingLocalType SharingLocalType 0x8A14 NULL PT_UNICODE MNID_ID PSETID_Sharing 0x92d9 PidLidSharingFolderEntryId SharingFolderEid 0x8A15 NULL PT_BINARY MNID_ID PSETID_Sharing 0x92e0 PidLidSharingCapabilities SharingCaps 0x8A17 NULL PT_LONG MNID_ID PSETID_Sharing 0x92c2 PidLidSharingFlavor SharingFlavor 0x8A18 NULL PT_LONG MNID_ID PSETID_Sharing 0x92c3 PidLidSharingAnonymity SharingAnonymity 0x8A19 NULL PT_LONG MNID_ID PSETID_Sharing 0x92c5 PidLidSharingReciprocation SharingReciprocation 0x8A1A NULL PT_LONG MNID_ID PSETID_Sharing 0x92c6 PidLidSharingPermissions SharingPermissions 0x8A1B NULL PT_LONG MNID_ID PSETID_Sharing 0x92c7 PidLidSharingInstanceGuid SharingInstanceGuid 0x8A1C NULL PT_BINARY MNID_ID PSETID_Sharing 0x92c8 PidLidSharingRemoteType SharingRemoteType 0x8A1D NULL PT_UNICODE MNID_ID PSETID_Sharing 0x92cf PidLidSharingParticipants SharingParticipants 0x8A1E NULL PT_UNICODE MNID_ID PSETID_Sharing 0x92dc PidLidSharingLastSyncTime SharingLastSync 0x8A1F NULL PT_SYSTIME MNID_ID PSETID_Sharing 0x92dd PidLidSharingExtensionXml SharingExtXml 0x8A21 NULL PT_UNICODE MNID_ID PSETID_Sharing 0x92df PidLidSharingRemoteLastModificationTime SharingRemoteLastMod 0x8A22 NULL PT_SYSTIME MNID_ID PSETID_Sharing 0x92e3 PidLidSharingLocalLastModificationTime SharingLocalLastMod 0x8A23 NULL PT_SYSTIME MNID_ID PSETID_Sharing 0x92e2 PidLidSharingConfigurationUrl SharingConfigUrl 0x8A24 NULL PT_UNICODE MNID_ID PSETID_Sharing 0x92e4 PidLidSharingStart SharingStart 0x8A25 NULL PT_SYSTIME MNID_ID PSETID_Sharing 0x9401 PidLidSharingStop SharingStop 0x8A26 NULL PT_SYSTIME MNID_ID PSETID_Sharing 0x9402 PidLidSharingResponseType SharingResponseType 0x8A27 NULL PT_LONG MNID_ID PSETID_Sharing 0x9449 PidLidSharingResponseTime SharingResponseTime 0x8A28 NULL PT_SYSTIME MNID_ID PSETID_Sharing 0x944a PidLidSharingOriginalMessageEntryId SharingOriginalMessageEid 0x8A29 NULL PT_BINARY MNID_ID PSETID_Sharing 0x944b PidLidSharingSyncInterval SharingSyncInterval 0x8A2A NULL PT_LONG MNID_ID PSETID_Sharing 0x9448 PidLidSharingDetail SharingDetail 0x8A2B NULL PT_LONG MNID_ID PSETID_Sharing 0x93f9 PidLidSharingTimeToLive SharingTimeToLive 0x8A2C NULL PT_LONG MNID_ID PSETID_Sharing 0x9406 PidLidSharingBindingEntryId SharingBindingEid 0x8A2D NULL PT_BINARY MNID_ID PSETID_Sharing 0x9408 PidLidSharingIndexEntryId SharingIndexEid 0x8A2E NULL PT_BINARY MNID_ID PSETID_Sharing 0x9409 PidLidSharingRemoteComment SharingRemoteComment 0x8A2F NULL PT_UNICODE MNID_ID PSETID_Sharing 0x93fe PidLidSharingWorkingHoursStart SharingWorkingHoursStart 0x8A40 NULL PT_SYSTIME MNID_ID PSETID_Sharing 0x940a PidLidSharingWorkingHoursEnd SharingWorkingHoursEnd 0x8A41 NULL PT_SYSTIME MNID_ID PSETID_Sharing 0x940b PidLidSharingWorkingHoursDay SharingWorkingHoursDays 0x8A42 NULL PT_LONG MNID_ID PSETID_Sharing 0x940c PidLidSharingWorkingHoursTimeZone SharingWorkingHoursTZ 0x8A43 NULL PT_BINARY MNID_ID PSETID_Sharing 0x940d PidLidSharingDataRangeStart SharingDataRangeStart 0x8A44 NULL PT_SYSTIME MNID_ID PSETID_Sharing 0x940e PidLidSharingDataRangeEnd SharingDataRangeEnd 0x8A45 NULL PT_SYSTIME MNID_ID PSETID_Sharing 0x940f PidLidSharingRangeStart SharingRangeStart 0x8A46 NULL PT_LONG MNID_ID PSETID_Sharing 0x9410 PidLidSharingRangeEnd SharingRangeEnd 0x8A47 NULL PT_LONG MNID_ID PSETID_Sharing 0x9411 PidLidSharingRemoteStoreUid SharingRemoteStoreUid 0x8A48 NULL PT_UNICODE MNID_ID PSETID_Sharing 0x93fb PidLidSharingLocalStoreUid SharingLocalStoreUid 0x8A49 NULL PT_UNICODE MNID_ID PSETID_Sharing 0x9403 PidLidSharingRemoteByteSize SharingRemoteByteSize 0x8A4B NULL PT_LONG MNID_ID PSETID_Sharing 0x93ff PidLidSharingRemoteCrc SharingRemoteCrc 0x8A4C NULL PT_LONG MNID_ID PSETID_Sharing 0x93fd PidLidSharingLocalComment SharingLocalComment 0x8A4D NULL PT_UNICODE MNID_ID PSETID_Sharing 0x9404 PidLidSharingRoamLog SharingRoamLog 0x8A4E NULL PT_LONG MNID_ID PSETID_Sharing 0x9412 PidLidSharingRemoteMessageCount SharingRemoteMsgCount 0x8A4F NULL PT_LONG MNID_ID PSETID_Sharing 0x9400 PidLidSharingBrowseUrl SharingBrowseUrl 0x8A51 NULL PT_UNICODE MNID_ID PSETID_Sharing 0x93fa PidLidSharingLastAutoSyncTime SharingLastAutoSync 0x8A55 NULL PT_SYSTIME MNID_ID PSETID_Sharing 0x9405 PidLidSharingTimeToLiveAuto SharingTimeToLiveAuto 0x8A56 NULL PT_LONG MNID_ID PSETID_Sharing 0x9407 PidLidSharingRemoteVersion SharingRemoteVersion 0x8A5B NULL PT_UNICODE MNID_ID PSETID_Sharing 0x93fc PidLidSharingParentBindingEntryId SharingParentBindingEid 0x8A5C NULL PT_BINARY MNID_ID PSETID_Sharing 0x9313 PidLidSharingSyncFlags SharingSyncFlags 0x8A60 NULL PT_LONG MNID_ID PSETID_Sharing 0x941d ### Note Named Properties PidLidNoteColor NoteColor 0x8B00 NULL PT_LONG MNID_ID PSETID_Note 0x94a9 PidLidNoteWidth NoteWidth 0x8B02 NULL PT_LONG MNID_ID PSETID_Note 0x92ab PidLidNoteHeight NoteHeight 0x8B03 NULL PT_LONG MNID_ID PSETID_Note 0x92ac PidLidNoteX NoteX 0x8B04 NULL PT_LONG MNID_ID PSETID_Note 0x92ad PidLidNoteY NoteY 0x8B05 NULL PT_LONG MNID_ID PSETID_Note 0x92ae ### PS_PUBLIC_STRINGS PidLidCategories Categories 0x9000 NULL PT_MV_STRING8 MNID_ID PS_PUBLIC_STRINGS 0x93b7 PidNameApplicationName NULL 0x0000 AppName PT_UNICODE MNID_STRING PS_PUBLIC_STRINGS 0x90e8 PidNameAuthor NULL 0x0000 Author PT_UNICODE MNID_STRING PS_PUBLIC_STRINGS 0x90da PidNameByteCount NULL 0x0000 ByteCount PT_LONG MNID_STRING PS_PUBLIC_STRINGS 0x90ec PidNameCalendarAttendeeRole NULL 0x0000 CalendarAttendeeRole PT_LONG MNID_STRING PS_PUBLIC_STRINGS PidNameCalendarBusyStatus NULL 0x0000 CalendarBusyStatus PT_UNICODE MNID_STRING PS_PUBLIC_STRINGS PidNameCalendarContact NULL 0x0000 CalendarContact PT_UNICODE MNID_STRING PS_PUBLIC_STRINGS PidNameCalendarContactUrl NULL 0x0000 CalendarContactUrl PT_UNICODE MNID_STRING PS_PUBLIC_STRINGS PidNameCalendarCreated NULL 0x0000 CalendarCreated PT_SYSTIME MNID_STRING PS_PUBLIC_STRINGS PidNameCalendarDescriptionUrl NULL 0x0000 CalendarDescriptionUrl PT_UNICODE MNID_STRING PS_PUBLIC_STRINGS PidNameCalendarDuration NULL 0x0000 CalendarDuration PT_LONG MNID_STRING PS_PUBLIC_STRINGS PidNameCalendarExceptionDate NULL 0x0000 CalendarExdate PT_MV_SYSTIME MNID_STRING PS_PUBLIC_STRINGS PidNameCalendarExceptionRule NULL 0x0000 CalendarExrule PT_MV_UNICODE MNID_STRING PS_PUBLIC_STRINGS PidNameCategory NULL 0x0000 Category PT_UNICODE MNID_STRING PS_PUBLIC_STRINGS 0x90ea PidNameCharacterCount NULL 0x0000 CharCount PT_LONG MNID_STRING PS_PUBLIC_STRINGS 0x90e6 PidNameComments NULL 0x0000 Comments PT_UNICODE MNID_STRING PS_PUBLIC_STRINGS 0x90dc PidNameCompany NULL 0x0000 Company PT_UNICODE MNID_STRING PS_PUBLIC_STRINGS 0x90f7 PidNameCreateDateTimeReadOnly NULL 0x0000 CreateDtmRo PT_SYSTIME MNID_STRING PS_PUBLIC_STRINGS 0x90e2 PidNameRightsManagementLicense NULL 0x0000 DRMLicense PT_MV_BINARY MNID_STRING PS_PUBLIC_STRINGS 0x9370 PidNameEditTime NULL 0x0000 EditTime PT_UNICODE MNID_STRING PS_PUBLIC_STRINGS 0x90e0 ###PidNameJunkEmailMoveStamp NULL 0x0000 http://schemas.microsoft.com/exchange/junkemailmovestamp PT_LONG MNID_STRING PS_PUBLIC_STRINGS 0x917e PidNameHiddenCount NULL 0x0000 HiddenCount PT_LONG MNID_STRING PS_PUBLIC_STRINGS 0x90f1 PidNameKeywords NULL 0x0000 Keywords PT_MV_STRING8 MNID_STRING PS_PUBLIC_STRINGS 0x90db PidNameLastAuthor NULL 0x0000 LastAuthor PT_UNICODE MNID_STRING PS_PUBLIC_STRINGS 0x90de PidNameLastPrinted NULL 0x0000 LastPrinted PT_SYSTIME MNID_STRING PS_PUBLIC_STRINGS 0x90e1 PidNameLastSaveDateTime NULL 0x0000 LastSaveDtm PT_SYSTIME MNID_STRING PS_PUBLIC_STRINGS 0x90e3 PidNameLineCount NULL 0x0000 LineCount PT_LONG MNID_STRING PS_PUBLIC_STRINGS 0x90ed PidNameManager NULL 0x0000 Manager PT_UNICODE MNID_STRING PS_PUBLIC_STRINGS 0x90f6 PidNameMultimediaClipCount NULL 0x0000 MMClipCount PT_LONG MNID_STRING PS_PUBLIC_STRINGS 0x90f2 PidNameNoteCount NULL 0x0000 NoteCount PT_LONG MNID_STRING PS_PUBLIC_STRINGS 0x90f0 PidNameOMSAccountGuid NULL 0x0000 OMSAccountGuid PT_UNICODE MNID_STRING PS_PUBLIC_STRINGS PidNameOMSMobileModel NULL 0x0000 OMSMobileModel PT_UNICODE MNID_STRING PS_PUBLIC_STRINGS PidNameOMSGScheduleTime NULL 0x0000 OMSScheduleTime PT_SYSTIME MNID_STRING PS_PUBLIC_STRINGS PidNameOMSServiceType NULL 0x0000 OMSServiceType PT_LONG MNID_STRING PS_PUBLIC_STRINGS PidNameOMSSourceType NULL 0x0000 OMSSourceType PT_LONG MNID_STRING PS_PUBLIC_STRINGS PidNamePhishingStamp NULL 0x0000 http://schemas.microsoft.com/outlook/phishingstamp PT_LONG MNID_STRING PS_PUBLIC_STRINGS 0x936f PidNameSpoofingStamp NULL 0x0000 http://schemas.microsoft.com/outlook/spoofingstamp PT_LONG MNID_STRING PS_PUBLIC_STRINGS 0x9526 PidNamePageCount NULL 0x0000 PageCount PT_LONG MNID_STRING PS_PUBLIC_STRINGS 0x90e4 PidNameParagraphCount NULL 0x0000 ParCount PT_LONG MNID_STRING PS_PUBLIC_STRINGS 0x90ee PidNamePresentationFormat NULL 0x0000 PresFormat PT_UNICODE MNID_STRING PS_PUBLIC_STRINGS 0x90eb PidNameSecurity NULL 0x0000 Security PT_LONG MNID_STRING PS_PUBLIC_STRINGS 0x90e9 PidNameSlideCount NULL 0x0000 SlideCount PT_LONG MNID_STRING PS_PUBLIC_STRINGS 0x90ef PidNameSTSId NULL 0x0000 STS_Id PT_NULL MNID_STRING PS_PUBLIC_STRINGS 0x9521 PidNameSubject NULL 0x0000 Subject PT_UNICODE MNID_STRING PS_PUBLIC_STRINGS 0x90d9 PidNameTemplate NULL 0x0000 Template PT_UNICODE MNID_STRING PS_PUBLIC_STRINGS 0x90dd PidNameTitle NULL 0x0000 Title PT_UNICODE MNID_STRING PS_PUBLIC_STRINGS 0x90d8 PidNameWordCount NULL 0x0000 WordCount PT_LONG MNID_STRING PS_PUBLIC_STRINGS 0x90e5 NULL NULL 0x0000 urn:schemas:contacts:fileas PT_UNICODE MNID_STRING PS_PUBLIC_STRINGS NULL NULL 0x0000 urn:schemas:calendar:sequence PT_LONG MNID_STRING PS_PUBLIC_STRINGS NULL NULL 0x0000 urn:schemas:calendar:version PT_UNICODE MNID_STRING PS_PUBLIC_STRINGS NULL NULL 0x0000 urn:schemas-microsoft-com:office:outlook#storetypeprivate PT_BOOLEAN MNID_STRING PS_PUBLIC_STRINGS 0x90e7 NULL NULL 0x0000 urn:schemas-microsoft-com:office:outlook#noaclui PT_BOOLEAN MNID_STRING PS_PUBLIC_STRINGS 0x90e9 ### PS_INTERNET_HEADERS PidNameAcceptLanguage AcceptLanguage 0x0000 Accept-Language PT_UNICODE MNID_STRING PS_INTERNET_HEADERS PidNameApproved Approved 0x0000 Approved PT_UNICODE MNID_STRING PS_INTERNET_HEADERS 0x9056 PidNameApprovalAllowedDescisionMakers NULL 0x0000 X-MS-Exchange-Organization-Approval-Allowed-Decision-Makers PT_UNICODE MNID_STRING PS_INTERNET_HEADERS PidNameApprovalRequestor NULL 0x0000 X-MS-Exchange-Organization-Approval-Requestor PT_UNICODE MNID_STRING PS_INTERNET_HEADERS PidNameAuthenticatedAs NULL 0x0000 X-MS-Exchange-Organization-AuthAs PT_UNICODE MNID_STRING PS_INTERNET_HEADERS PidNameAuthenticatedDomain NULL 0x0000 X-MS-Exchange-Organization-AuthDomain PT_UNICODE MNID_STRING PS_INTERNET_HEADERS PidNameAuthenticatedMechanism NULL 0x0000 X-MS-Exchange-Organization-AuthMechanism PT_UNICODE MNID_STRING PS_INTERNET_HEADERS PidNameAuthenticatedSource NULL 0x0000 X-MS-Exchange-Organization-AuthSource PT_UNICODE MNID_STRING PS_INTERNET_HEADERS PidNameBcc NULL 0x0000 Bcc PT_UNICODE MNID_STRING PS_INTERNET_HEADERS 0x9057 PidNameCc NULL 0x0000 Cc PT_UNICODE MNID_STRING PS_INTERNET_HEADERS 0x9058 PidNameContentBase BodyContentBase 0x0000 Content-Base PT_UNICODE MNID_STRING PS_INTERNET_HEADERS PidNameContentClass NULL 0x0000 Content-Class PT_UNICODE MNID_STRING PS_INTERNET_HEADERS 0x9041 PidNameContentDisposition NULL 0x0000 Content-Disposition PT_UNICODE MNID_STRING PS_INTERNET_HEADERS 0x905b PidNameContentID NULL 0x0000 Content-ID PT_UNICODE MNID_STRING PS_INTERNET_HEADERS 0x905c PidNameContentLanguage NULL 0x0000 Content-Language PT_UNICODE MNID_STRING PS_INTERNET_HEADERS 0x905d PidNameContentLocation NULL 0x0000 Content-Location PT_UNICODE MNID_STRING PS_INTERNET_HEADERS 0x905e PidNameContentTransferEncoding NULL 0x0000 Content-Transfer-Encoding PT_UNICODE MNID_STRING PS_INTERNET_HEADERS 0x905f PidNameContentType NULL 0x0000 Content-Type PT_UNICODE MNID_STRING PS_INTERNET_HEADERS 0x905a PidNameCrossReference NULL 0x0000 Xref PT_UNICODE MNID_STRING PS_INTERNET_HEADERS 0x9089 PidNameXMSExchangeOrganizationAuthdomain NULL 0x0000 X-MS-Exchange-Organization-AuthDomain PT_UNICODE MNID_STRING PS_INTERNET_HEADERS 0x951a PidNameXSharingBrowseUrl NULL 0x0000 X-Sharing-Browse-Url PT_UNICODE MNID_STRING PS_INTERNET_HEADERS 0x9463 PidNameXSharingCapabilities NULL 0x0000 X-Sharing-Capabilities PT_UNICODE MNID_STRING PS_INTERNET_HEADERS 0x9457 PidNameXSharingConfigUrl NULL 0x0000 X-Sharing-Config-Url PT_UNICODE MNID_STRING PS_INTERNET_HEADERS 0x9462 PidNameXSharingExtendedCaps NULL 0x0000 X-Sharing-Extended-Caps PT_UNICODE MNID_STRING PS_INTERNET_HEADERS PidNameXSharingFlavor NULL 0x0000 X-Sharing-Flavor PT_UNICODE MNID_STRING PS_INTERNET_HEADERS 0x9458 PidNameXSharingInstanceGuid NULL 0x0000 X-Sharing-Instance-Guid PT_UNICODE MNID_STRING PS_INTERNET_HEADERS 0x9459 PidNameXSharingLocalType NULL 0x0000 X-Sharing-Local-Type PT_UNICODE MNID_STRING PS_INTERNET_HEADERS 0x9464 PidNameXSharingProviderGuid NULL 0x0000 X-Sharing-Provider-Guid PT_UNICODE MNID_STRING PS_INTERNET_HEADERS 0x945a PidNameXSharingProviderName NULL 0x0000 X-Sharing-Provider-Name PT_UNICODE MNID_STRING PS_INTERNET_HEADERS 0x945b PidNameXSharingProviderUrl NULL 0x0000 X-Sharing-Provider-Url PT_UNICODE MNID_STRING PS_INTERNET_HEADERS 0x945c PidNameXSharingRemoteName NULL 0x0000 X-Sharing-Remote-Name PT_UNICODE MNID_STRING PS_INTERNET_HEADERS 0x945e PidNameXSharingRemotePath NULL 0x0000 X-Sharing-Remote-Path PT_UNICODE MNID_STRING PS_INTERNET_HEADERS 0x945d PidNameXSharingRemoteStoreUid NULL 0x0000 X-Sharing-Remote-Store-Uid PT_UNICODE MNID_STRING PS_INTERNET_HEADERS 0x9460 PidNameXSharingRemoteType NULL 0x0000 X-Sharing-Remote-Type PT_UNICODE MNID_STRING PS_INTERNET_HEADERS 0x9461 PidNameXSharingRemoteUid NULL 0x0000 X-Sharing-Remote-Uid PT_UNICODE MNID_STRING PS_INTERNET_HEADERS 0x845f PidNameXSieve NULL 0x0000 X-Sieve PT_UNICODE MNID_STRING PS_INTERNET_HEADERS 0x9513 PidNameXVirusScanned NULL 0x0000 X-Virus-Scanned PT_UNICODE MNID_STRING PS_INTERNET_HEADERS 0x9514 ### PSETID_CalendarAssistant PidLidClientIntent ClientIntent 0x0015 ClientIntent PT_LONG MNID_ID PSETID_CalendarAssistant 0x95f4 PidLidServerProcessed ServerProcessed 0x85CC NULL PT_BOOLEAN MNID_ID PSETID_CalendarAssistant 0x95f5 PidLidServerProcessingActions ServerProcessingActions 0x85CD NULL PT_LONG MNID_ID PSETID_CalendarAssistant 0x95f6 ### PSETID_Attachment PidNameAttachmentMacContentType NULL 0x0000 AttachmentMacContentType PT_UNICODE MNID_STRING PSETID_Attachment PidNameAttachmentMacInfo NULL 0x0000 AttachmentMacInfo PT_BINARY MNID_STRING PSETID_Attachment ### PSETID_UnifiedMessaging PidNameAudioNotes UMAudioNotes 0x0000 UMAudioNotes PT_UNICODE MNID_STRING PSETID_UnifiedMessaging PidNameAutomaticSpeechRecognitionData NULL 0x0000 AsrData PT_BINARY MNID_STRING PSETID_UnifiedMessaging PidNameOutlookProtectionRuleTimestamp NULL 0x0000 X-MS-Exchange-Organization-Outlook-Protection-Rule-Config-Timestamp PT_UNICODE MNID_STRING PSETID_UnifiedMessaging PidNameXUnifiedMessagingPartnerAssignedId NULL 0x0000 X-MS-Exchange-UM-PartnerAssignedID PT_UNICODE MNID_STRING PSETID_UnifiedMessaging PidNameXUnifiedMessagingPartnerContent NULL 0x0000 X-MS-Exchange-UM-PartnerContent PT_UNICODE MNID_STRING PSETID_UnifiedMessaging PidNameXUnifiedMessagingPartnerContext NULL 0x0000 X-MS-Exchange-UM-PartnerContext PT_UNICODE MNID_STRING PSETID_UnifiedMessaging PidNameXUnifiedMessagingPartnerStatus NULL 0x0000 X-MS-Exchange-UM-PartnerStatus PT_UNICODE MNID_STRING PSETID_UnifiedMessaging ### PSETID_AirSync PidNameInstantMessagingAddress2 NULL 0x0000 IMAddress2 PT_UNICODE MNID_STRING PSETID_AirSync PidNameInstantMessagingAddress3 NULL 0x0000 IMAddress3 PT_UNICODE MNID_STRING PSETID_AirSync ### PSETID_Messaging PidNameOriginalSpamConfidenceLevel NULL 0x0000 OriginalScl PT_LONG MNID_STRING PSETID_Messaging ### PSETID_Remote PidLidRemoteTransferSize RemoteTransferSize 0x8f05 NULL PT_LONG MNID_ID PSETID_Remote 0x94f6 PidLidRemoteAttachment RemoteAttachment 0x8f07 NULL PT_BOOLEAN MNID_ID PSETID_Remote 0x94f7 ### generated via append-prop.py PidLidUnknownProperty8550 LID_UNKNOWN_PROPERTY_8550 0x8550 NULL PT_LONG MNID_ID PSETID_Common 0x94db PidLidUnknownProperty8551 LID_UNKNOWN_PROPERTY_8551 0x8551 NULL PT_LONG MNID_ID PSETID_Common 0x94dc PidLidUnknownProperty8515 LID_UNKNOWN_PROPERTY_8515 0x8515 NULL PT_BOOLEAN MNID_ID PSETID_Common 0x94dd PidLidUnknownProperty8542 LID_UNKNOWN_PROPERTY_8542 0x8542 NULL PT_LONG MNID_ID PSETID_Common 0x94de PidLidUnknownProperty851b LID_UNKNOWN_PROPERTY_851b 0x851b NULL PT_BINARY MNID_ID PSETID_Common 0x94e0 PidLidUnknownProperty8513 LID_UNKNOWN_PROPERTY_8513 0x8513 NULL PT_BINARY MNID_ID PSETID_Common 0x94e1 PidLidUnknownProperty8540 LID_UNKNOWN_PROPERTY_8540 0x8540 NULL PT_BINARY MNID_ID PSETID_Common 0x94e2 PidLidUnknownProperty8549 LID_UNKNOWN_PROPERTY_8549 0x8549 NULL PT_SYSTIME MNID_ID PSETID_Common 0x94e4 PidLidUnknownProperty8583 LID_UNKNOWN_PROPERTY_8583 0x8583 NULL PT_UNICODE MNID_ID PSETID_Common 0x94e7 PidLidUnknownProperty858c LID_UNKNOWN_PROPERTY_858c 0x858c NULL PT_BOOLEAN MNID_ID PSETID_Common 0x94e8 PidLidUnknownProperty858e LID_UNKNOWN_PROPERTY_858e 0x858e NULL PT_UNICODE MNID_ID PSETID_Common 0x94e9 PidLidUnknownProperty858f LID_UNKNOWN_PROPERTY_858f 0x858f NULL PT_UNICODE MNID_ID PSETID_Common 0x94ea PidLidUnknownProperty8593 LID_UNKNOWN_PROPERTY_8593 0x8593 NULL PT_LONG MNID_ID PSETID_Common 0x94eb PidLidUnknownProperty8590 LID_UNKNOWN_PROPERTY_8590 0x8590 NULL PT_BOOLEAN MNID_ID PSETID_Common 0x94ec PidLidUnknownProperty8595 LID_UNKNOWN_PROPERTY_8595 0x8595 NULL PT_MV_BINARY MNID_ID PSETID_Common 0x94ed PidLidUnknownProperty8597 LID_UNKNOWN_PROPERTY_8597 0x8597 NULL PT_LONG MNID_ID PSETID_Common 0x94ee PidLidUnknownProperty8591 LID_UNKNOWN_PROPERTY_8591 0x8591 NULL PT_UNICODE MNID_ID PSETID_Common 0x94ef PidLidUnknownProperty8596 LID_UNKNOWN_PROPERTY_8596 0x8596 NULL PT_UNICODE MNID_ID PSETID_Common 0x94f0 PidLidUnknownProperty859a LID_UNKNOWN_PROPERTY_859a 0x859a NULL PT_LONG MNID_ID PSETID_Common 0x94f1 PidLidUnknownProperty859b LID_UNKNOWN_PROPERTY_859b 0x859b NULL PT_BOOLEAN MNID_ID PSETID_Common 0x94f2 PidLidUnknownProperty859f LID_UNKNOWN_PROPERTY_859f 0x859f NULL PT_NULL MNID_ID PSETID_Common 0x9520 PidLidUnknownProperty85b2 LID_UNKNOWN_PROPERTY_85b2 0x85b2 NULL PT_NULL MNID_ID PSETID_Common 0x9522 PidLidUnknownProperty85b3 LID_UNKNOWN_PROPERTY_85b3 0x85b3 NULL PT_NULL MNID_ID PSETID_Common 0x9523 PidLidUnknownProperty85b9 LID_UNKNOWN_PROPERTY_85b9 0x85b9 NULL PT_NULL MNID_ID PSETID_Common 0x9524 PidLidUnknownProperty85bc LID_UNKNOWN_PROPERTY_85bc 0x85bc NULL PT_NULL MNID_ID PSETID_Common 0x9525 PidLidUnknownProperty85be LID_UNKNOWN_PROPERTY_85be 0x85be NULL PT_NULL MNID_ID PSETID_Common 0x9527 PidLidUnknownProperty85c1 LID_UNKNOWN_PROPERTY_85c1 0x85c1 NULL PT_NULL MNID_ID PSETID_Common 0x9528 PidLidUnknownProperty85c2 LID_UNKNOWN_PROPERTY_85c2 0x85c2 NULL PT_NULL MNID_ID PSETID_Common 0x9529 PidLidUnknownProperty85c3 LID_UNKNOWN_PROPERTY_85c3 0x85c3 NULL PT_NULL MNID_ID PSETID_Common 0x952a PidLidUnknownProperty858d LID_UNKNOWN_PROPERTY_858d 0x858d NULL PT_UNICODE MNID_ID PSETID_Common 0x94f5 PidLidUnknownProperty850f LID_UNKNOWN_PROPERTY_850f 0x850f NULL PT_NULL MNID_ID PSETID_Common 0x94df PidLidUnknownProperty8541 LID_UNKNOWN_PROPERTY_8541 0x8541 NULL PT_NULL MNID_ID PSETID_Common 0x94e3 PidLidUnknownProperty823d LID_UNKNOWN_PROPERTY_823d 0x823d NULL PT_NULL MNID_ID PSETID_Appointment 0x94f8 PidLidUnknownProperty0021 LID_UNKNOWN_PROPERTY_0021 0x0021 NULL PT_NULL MNID_ID PSETID_Meeting 0x94f9 PidLidUnknownProperty0015 LID_UNKNOWN_PROPERTY_0015 0x0015 NULL PT_NULL MNID_ID PSETID_Meeting 0x94fa PidLidUnknownProperty0016 LID_UNKNOWN_PROPERTY_0016 0x0016 NULL PT_NULL MNID_ID PSETID_Meeting 0x94fb PidLidUnknownProperty0019 LID_UNKNOWN_PROPERTY_0019 0x0019 NULL PT_NULL MNID_ID PSETID_Meeting 0x94fc PidLidUnknownProperty812b LID_UNKNOWN_PROPERTY_812b 0x812b NULL PT_NULL MNID_ID PSETID_Task 0x94fd PidLidUnknownProperty812f LID_UNKNOWN_PROPERTY_812f 0x812f NULL PT_NULL MNID_ID PSETID_Task 0x94fe PidLidUnknownProperty811d LID_UNKNOWN_PROPERTY_811d 0x811d NULL PT_NULL MNID_ID PSETID_Task 0x94ff PidLidUnknownProperty8137 LID_UNKNOWN_PROPERTY_8137 0x8137 NULL PT_NULL MNID_ID PSETID_Task 0x951c PidLidUnknownProperty8138 LID_UNKNOWN_PROPERTY_8138 0x8138 NULL PT_NULL MNID_ID PSETID_Task 0x951d PidLidUnknownProperty8132 LID_UNKNOWN_PROPERTY_8132 0x8132 NULL PT_NULL MNID_ID PSETID_Task 0x951e PidLidUnknownProperty8134 LID_UNKNOWN_PROPERTY_8134 0x8134 NULL PT_NULL MNID_ID PSETID_Task 0x951f PidLidUnknownProperty800b LID_UNKNOWN_PROPERTY_800b 0x800b NULL PT_NULL MNID_ID PSETID_Address 0x9500 PidLidUnknownProperty802a LID_UNKNOWN_PROPERTY_802a 0x802a NULL PT_NULL MNID_ID PSETID_Address 0x9501 PidLidUnknownProperty8016 LID_UNKNOWN_PROPERTY_8016 0x8016 NULL PT_NULL MNID_ID PSETID_Address 0x9502 PidLidUnknownProperty8043 LID_UNKNOWN_PROPERTY_8043 0x8043 NULL PT_NULL MNID_ID PSETID_Address 0x951b PidLidUnknownProperty8081 LID_UNKNOWN_PROPERTY_8081 0x8081 NULL PT_NULL MNID_ID PSETID_Address 0x9503 PidLidUnknownProperty80b0 LID_UNKNOWN_PROPERTY_80b0 0x80b0 NULL PT_NULL MNID_ID PSETID_Address 0x9504 PidLidUnknownProperty80b1 LID_UNKNOWN_PROPERTY_80b1 0x80b1 NULL PT_NULL MNID_ID PSETID_Address 0x9505 PidLidUnknownProperty80b6 LID_UNKNOWN_PROPERTY_80b6 0x80b6 NULL PT_NULL MNID_ID PSETID_Address 0x9506 PidLidUnknownProperty80c0 LID_UNKNOWN_PROPERTY_80c0 0x80c0 NULL PT_NULL MNID_ID PSETID_Address 0x9507 PidLidUnknownProperty80c1 LID_UNKNOWN_PROPERTY_80c1 0x80c1 NULL PT_NULL MNID_ID PSETID_Address 0x9508 PidLidUnknownProperty80c6 LID_UNKNOWN_PROPERTY_80c6 0x80c6 NULL PT_NULL MNID_ID PSETID_Address 0x9509 PidLidUnknownProperty80d0 LID_UNKNOWN_PROPERTY_80d0 0x80d0 NULL PT_NULL MNID_ID PSETID_Address 0x950a PidLidUnknownProperty80d1 LID_UNKNOWN_PROPERTY_80d1 0x80d1 NULL PT_NULL MNID_ID PSETID_Address 0x950b PidLidUnknownProperty80d6 LID_UNKNOWN_PROPERTY_80d6 0x80d6 NULL PT_NULL MNID_ID PSETID_Address 0x950c PidLidUnknownProperty8059 LID_UNKNOWN_PROPERTY_8059 0x8059 NULL PT_NULL MNID_ID PSETID_Address 0x950d PidLidUnknownProperty8056 LID_UNKNOWN_PROPERTY_8056 0x8056 NULL PT_NULL MNID_ID PSETID_Address 0x950e PidLidUnknownProperty8057 LID_UNKNOWN_PROPERTY_8057 0x8057 NULL PT_NULL MNID_ID PSETID_Address 0x950f PidLidUnknownProperty8058 LID_UNKNOWN_PROPERTY_8058 0x8058 NULL PT_NULL MNID_ID PSETID_Address 0x9510 PidLidUnknownProperty80d9 LID_UNKNOWN_PROPERTY_80d9 0x80d9 NULL PT_NULL MNID_ID PSETID_Address 0x9511 PidLidUnknownProperty804b LID_UNKNOWN_PROPERTY_804b 0x804b NULL PT_NULL MNID_ID PSETID_Address 0x9512 PidLidUnknownProperty8f01 LID_UNKNOWN_PROPERTY_8f01 0x8f01 NULL PT_NULL MNID_ID PSETID_Remote 0x9515 PidLidUnknownProperty8f06 LID_UNKNOWN_PROPERTY_8f06 0x8f06 NULL PT_NULL MNID_ID PSETID_Remote 0x9516 PidLidUnknownProperty8f03 LID_UNKNOWN_PROPERTY_8f03 0x8f03 NULL PT_NULL MNID_ID PSETID_Remote 0x9517 PidLidUnknownProperty8f04 LID_UNKNOWN_PROPERTY_8f04 0x8f04 NULL PT_NULL MNID_ID PSETID_Remote 0x9518 PidLidUnknownProperty85a8 LID_UNKNOWN_PROPERTY_85a8 0x85a8 NULL PT_NULL MNID_ID PSETID_Common 0x9519 PidLidUnknownProperty8808 LID_UNKNOWN_PROPERTY_8808 0x8808 NULL PT_BOOLEAN MNID_ID PS_UNKNOWN_0006200b_0000_0000_c000_000000000046 0x94f3 PidLidUnknownProperty8809 LID_UNKNOWN_PROPERTY_8809 0x8809 NULL PT_LONG MNID_ID PS_UNKNOWN_0006200b_0000_0000_c000_000000000046 0x94f4 PidLidUnknownProperty0001 LID_UNKNOWN_PROPERTY_0001 0x0001 NULL PT_NULL MNID_ID PSETID_CalendarAssistant 0x952b PidLidUnknownProperty0003 LID_UNKNOWN_PROPERTY_0003 0x0003 NULL PT_NULL MNID_ID PSETID_CalendarAssistant 0x952c PidLidUnknownProperty8a5e LID_UNKNOWN_PROPERTY_8a5e 0x8a5e NULL PT_NULL MNID_ID PSETID_Sharing 0x952d PidLidUnknownProperty8a30 LID_UNKNOWN_PROPERTY_8a30 0x8a30 NULL PT_NULL MNID_ID PSETID_Sharing 0x952e PidLidUnknownProperty8a31 LID_UNKNOWN_PROPERTY_8a31 0x8a31 NULL PT_NULL MNID_ID PSETID_Sharing 0x952f PidLidUnknownProperty8a33 LID_UNKNOWN_PROPERTY_8a33 0x8a33 NULL PT_NULL MNID_ID PSETID_Sharing 0x9530 PidLidUnknownProperty8a32 LID_UNKNOWN_PROPERTY_8a32 0x8a32 NULL PT_NULL MNID_ID PSETID_Sharing 0x9531 PidLidUnknownProperty8a57 LID_UNKNOWN_PROPERTY_8a57 0x8a57 NULL PT_NULL MNID_ID PSETID_Sharing 0x9532 PidLidUnknownProperty8a61 LID_UNKNOWN_PROPERTY_8a61 0x8a61 NULL PT_NULL MNID_ID PSETID_Sharing 0x9533 PidLidUnknownProperty8a62 LID_UNKNOWN_PROPERTY_8a62 0x8a62 NULL PT_NULL MNID_ID PSETID_Sharing 0x9534 PidLidUnknownProperty8a5a LID_UNKNOWN_PROPERTY_8a5a 0x8a5a NULL PT_NULL MNID_ID PSETID_Sharing 0x9535 PidLidUnknownProperty8a5d LID_UNKNOWN_PROPERTY_8a5d 0x8a5d NULL PT_NULL MNID_ID PSETID_Sharing 0x9536 PidLidUnknownProperty8a5f LID_UNKNOWN_PROPERTY_8a5f 0x8a5f NULL PT_NULL MNID_ID PSETID_Sharing 0x9537 PidLidUnknownProperty8a64 LID_UNKNOWN_PROPERTY_8a64 0x8a64 NULL PT_NULL MNID_ID PSETID_Sharing 0x9538 PidLidUnknownProperty8a20 LID_UNKNOWN_PROPERTY_8a20 0x8a20 NULL PT_NULL MNID_ID PSETID_Sharing 0x9539 ### generated via append-prop.py PidLidUnknownProperty800c LID_UNKNOWN_PROPERTY_800c 0x800c NULL PT_NULL MNID_ID PSETID_Address 0x953a PidLidUnknownProperty8017 LID_UNKNOWN_PROPERTY_8017 0x8017 NULL PT_NULL MNID_ID PSETID_Address 0x953b PidLidUnknownProperty8018 LID_UNKNOWN_PROPERTY_8018 0x8018 NULL PT_NULL MNID_ID PSETID_Address 0x953c PidLidUnknownProperty8019 LID_UNKNOWN_PROPERTY_8019 0x8019 NULL PT_NULL MNID_ID PSETID_Address 0x953d PidLidUnknownProperty8002 LID_UNKNOWN_PROPERTY_8002 0x8002 NULL PT_NULL MNID_ID PSETID_Address 0x953e PidLidUnknownProperty8068 LID_UNKNOWN_PROPERTY_8068 0x8068 NULL PT_NULL MNID_ID PSETID_Address 0x953f PidLidUnknownProperty8069 LID_UNKNOWN_PROPERTY_8069 0x8069 NULL PT_NULL MNID_ID PSETID_Address 0x9540 PidLidUnknownProperty8074 LID_UNKNOWN_PROPERTY_8074 0x8074 NULL PT_NULL MNID_ID PSETID_Address 0x9541 PidLidUnknownProperty8008 LID_UNKNOWN_PROPERTY_8008 0x8008 NULL PT_NULL MNID_ID PSETID_Address 0x9542 PidLidUnknownProperty8009 LID_UNKNOWN_PROPERTY_8009 0x8009 NULL PT_NULL MNID_ID PSETID_Address 0x9543 PidLidUnknownProperty800a LID_UNKNOWN_PROPERTY_800a 0x800a NULL PT_NULL MNID_ID PSETID_Address 0x9544 PidLidUnknownProperty806a LID_UNKNOWN_PROPERTY_806a 0x806a NULL PT_NULL MNID_ID PSETID_Address 0x9545 PidLidUnknownProperty8076 LID_UNKNOWN_PROPERTY_8076 0x8076 NULL PT_NULL MNID_ID PSETID_Address 0x9546 PidLidUnknownProperty806b LID_UNKNOWN_PROPERTY_806b 0x806b NULL PT_NULL MNID_ID PSETID_Address 0x9547 PidLidUnknownProperty8077 LID_UNKNOWN_PROPERTY_8077 0x8077 NULL PT_NULL MNID_ID PSETID_Address 0x9548 PidLidUnknownProperty806c LID_UNKNOWN_PROPERTY_806c 0x806c NULL PT_NULL MNID_ID PSETID_Address 0x9549 PidLidUnknownProperty8078 LID_UNKNOWN_PROPERTY_8078 0x8078 NULL PT_NULL MNID_ID PSETID_Address 0x954a PidLidUnknownProperty806d LID_UNKNOWN_PROPERTY_806d 0x806d NULL PT_NULL MNID_ID PSETID_Address 0x954b PidLidUnknownProperty8079 LID_UNKNOWN_PROPERTY_8079 0x8079 NULL PT_NULL MNID_ID PSETID_Address 0x954c PidLidUnknownProperty806e LID_UNKNOWN_PROPERTY_806e 0x806e NULL PT_NULL MNID_ID PSETID_Address 0x954d PidLidUnknownProperty807a LID_UNKNOWN_PROPERTY_807a 0x807a NULL PT_NULL MNID_ID PSETID_Address 0x954e PidLidUnknownProperty806f LID_UNKNOWN_PROPERTY_806f 0x806f NULL PT_NULL MNID_ID PSETID_Address 0x954f PidLidUnknownProperty807b LID_UNKNOWN_PROPERTY_807b 0x807b NULL PT_NULL MNID_ID PSETID_Address 0x9550 PidLidUnknownProperty8070 LID_UNKNOWN_PROPERTY_8070 0x8070 NULL PT_NULL MNID_ID PSETID_Address 0x9551 PidLidUnknownProperty807c LID_UNKNOWN_PROPERTY_807c 0x807c NULL PT_NULL MNID_ID PSETID_Address 0x9552 PidLidUnknownProperty8071 LID_UNKNOWN_PROPERTY_8071 0x8071 NULL PT_NULL MNID_ID PSETID_Address 0x9553 PidLidUnknownProperty807d LID_UNKNOWN_PROPERTY_807d 0x807d NULL PT_NULL MNID_ID PSETID_Address 0x9554 PidLidUnknownProperty8097 LID_UNKNOWN_PROPERTY_8097 0x8097 NULL PT_NULL MNID_ID PSETID_Address 0x9555 PidLidUnknownProperty80a7 LID_UNKNOWN_PROPERTY_80a7 0x80a7 NULL PT_NULL MNID_ID PSETID_Address 0x9556 PidLidUnknownProperty80b7 LID_UNKNOWN_PROPERTY_80b7 0x80b7 NULL PT_NULL MNID_ID PSETID_Address 0x9557 PidLidUnknownProperty80c7 LID_UNKNOWN_PROPERTY_80c7 0x80c7 NULL PT_NULL MNID_ID PSETID_Address 0x9558 PidLidUnknownProperty80d7 LID_UNKNOWN_PROPERTY_80d7 0x80d7 NULL PT_NULL MNID_ID PSETID_Address 0x9559 PidLidUnknownProperty8030 LID_UNKNOWN_PROPERTY_8030 0x8030 NULL PT_NULL MNID_ID PSETID_Address 0x955a PidLidUnknownProperty8031 LID_UNKNOWN_PROPERTY_8031 0x8031 NULL PT_NULL MNID_ID PSETID_Address 0x955b PidLidUnknownProperty8032 LID_UNKNOWN_PROPERTY_8032 0x8032 NULL PT_NULL MNID_ID PSETID_Address 0x955c PidLidUnknownProperty8033 LID_UNKNOWN_PROPERTY_8033 0x8033 NULL PT_NULL MNID_ID PSETID_Address 0x955d PidLidUnknownProperty8034 LID_UNKNOWN_PROPERTY_8034 0x8034 NULL PT_NULL MNID_ID PSETID_Address 0x955e PidLidUnknownProperty8035 LID_UNKNOWN_PROPERTY_8035 0x8035 NULL PT_NULL MNID_ID PSETID_Address 0x955f PidLidUnknownProperty8036 LID_UNKNOWN_PROPERTY_8036 0x8036 NULL PT_NULL MNID_ID PSETID_Address 0x9560 PidLidUnknownProperty8038 LID_UNKNOWN_PROPERTY_8038 0x8038 NULL PT_NULL MNID_ID PSETID_Address 0x9561 PidLidUnknownProperty8037 LID_UNKNOWN_PROPERTY_8037 0x8037 NULL PT_NULL MNID_ID PSETID_Address 0x9562 PidLidUnknownProperty805d LID_UNKNOWN_PROPERTY_805d 0x805d NULL PT_NULL MNID_ID PSETID_Address 0x9563 PidLidUnknownProperty805e LID_UNKNOWN_PROPERTY_805e 0x805e NULL PT_NULL MNID_ID PSETID_Address 0x9564 PidLidUnknownProperty805f LID_UNKNOWN_PROPERTY_805f 0x805f NULL PT_NULL MNID_ID PSETID_Address 0x9565 PidLidUnknownProperty8060 LID_UNKNOWN_PROPERTY_8060 0x8060 NULL PT_NULL MNID_ID PSETID_Address 0x9566 PidLidUnknownProperty8001 LID_UNKNOWN_PROPERTY_8001 0x8001 NULL PT_NULL MNID_ID PSETID_Address 0x9567 PidLidUnknownProperty805c LID_UNKNOWN_PROPERTY_805c 0x805c NULL PT_NULL MNID_ID PSETID_Address 0x9568 PidLidUnknownProperty805b LID_UNKNOWN_PROPERTY_805b 0x805b NULL PT_NULL MNID_ID PSETID_Address 0x9569 PidLidUnknownProperty8061 LID_UNKNOWN_PROPERTY_8061 0x8061 NULL PT_NULL MNID_ID PSETID_Address 0x956a PidLidUnknownProperty8252 LID_UNKNOWN_PROPERTY_8252 0x8252 NULL PT_NULL MNID_ID PSETID_Appointment 0x956b PidLidUnknownProperty8253 LID_UNKNOWN_PROPERTY_8253 0x8253 NULL PT_NULL MNID_ID PSETID_Appointment 0x956c PidLidUnknownProperty8254 LID_UNKNOWN_PROPERTY_8254 0x8254 NULL PT_NULL MNID_ID PSETID_Appointment 0x956d PidLidUnknownProperty8255 LID_UNKNOWN_PROPERTY_8255 0x8255 NULL PT_NULL MNID_ID PSETID_Appointment 0x956e PidLidUnknownProperty825b LID_UNKNOWN_PROPERTY_825b 0x825b NULL PT_NULL MNID_ID PSETID_Appointment 0x956f PidLidUnknownProperty8227 LID_UNKNOWN_PROPERTY_8227 0x8227 NULL PT_NULL MNID_ID PSETID_Appointment 0x9570 PidLidUnknownProperty823f LID_UNKNOWN_PROPERTY_823f 0x823f NULL PT_NULL MNID_ID PSETID_Appointment 0x9571 PidLidUnknownProperty822a LID_UNKNOWN_PROPERTY_822a 0x822a NULL PT_NULL MNID_ID PSETID_Appointment 0x9572 PidLidUnknownProperty853b LID_UNKNOWN_PROPERTY_853b 0x853b NULL PT_NULL MNID_ID PSETID_Common 0x9573 PidLidUnknownProperty853c LID_UNKNOWN_PROPERTY_853c 0x853c NULL PT_NULL MNID_ID PSETID_Common 0x9574 PidLidUnknownProperty8587 LID_UNKNOWN_PROPERTY_8587 0x8587 NULL PT_NULL MNID_ID PSETID_Common 0x9575 PidLidUnknownProperty853e LID_UNKNOWN_PROPERTY_853e 0x853e NULL PT_NULL MNID_ID PSETID_Common 0x9576 PidLidUnknownProperty8588 LID_UNKNOWN_PROPERTY_8588 0x8588 NULL PT_NULL MNID_ID PSETID_Common 0x9577 PidLidUnknownProperty8589 LID_UNKNOWN_PROPERTY_8589 0x8589 NULL PT_NULL MNID_ID PSETID_Common 0x9578 PidLidUnknownProperty858a LID_UNKNOWN_PROPERTY_858a 0x858a NULL PT_NULL MNID_ID PSETID_Common 0x9579 PidLidUnknownProperty8571 LID_UNKNOWN_PROPERTY_8571 0x8571 NULL PT_NULL MNID_ID PSETID_Common 0x957a PidLidUnknownProperty854a LID_UNKNOWN_PROPERTY_854a 0x854a NULL PT_NULL MNID_ID PSETID_Common 0x957b PidLidUnknownProperty859d LID_UNKNOWN_PROPERTY_859d 0x859d NULL PT_NULL MNID_ID PSETID_Common 0x957c PidNameArchivesourcesupportmask NULL 0x0000 ArchiveSourceSupportMask PT_NULL MNID_STRING PSETID_Common 0x957d PidNameCrawlsourcesupportmask NULL 0x0000 CrawlSourceSupportMask PT_NULL MNID_STRING PSETID_Common 0x957e PidLidUnknownProperty8704 LID_UNKNOWN_PROPERTY_8704 0x8704 NULL PT_NULL MNID_ID PSETID_Log 0x957f PidLidUnknownProperty8705 LID_UNKNOWN_PROPERTY_8705 0x8705 NULL PT_NULL MNID_ID PSETID_Log 0x9580 PidLidUnknownProperty870d LID_UNKNOWN_PROPERTY_870d 0x870d NULL PT_NULL MNID_ID PSETID_Log 0x9581 PidLidUnknownProperty8b01 LID_UNKNOWN_PROPERTY_8b01 0x8b01 NULL PT_NULL MNID_ID PSETID_Note 0x9582 PidLidUnknownProperty0022 LID_UNKNOWN_PROPERTY_0022 0x0022 NULL PT_NULL MNID_ID PSETID_Meeting 0x9583 PidLidUnknownProperty0025 LID_UNKNOWN_PROPERTY_0025 0x0025 NULL PT_NULL MNID_ID PSETID_Meeting 0x9584 PidLidUnknownProperty8d00 LID_UNKNOWN_PROPERTY_8d00 0x8d00 NULL PT_NULL MNID_ID PSETID_Report 0x9585 PidLidUnknownProperty8f02 LID_UNKNOWN_PROPERTY_8f02 0x8f02 NULL PT_NULL MNID_ID PSETID_Remote 0x9586 PidLidUnknownProperty9001 LID_UNKNOWN_PROPERTY_9001 0x9001 NULL PT_NULL MNID_ID PS_PUBLIC_STRINGS 0x9587 NULL NULL 0x0000 urn:schemas:httpmail:bcc PT_NULL MNID_STRING PS_PUBLIC_STRINGS 0x9588 NULL NULL 0x0000 urn:schemas:httpmail:calendar PT_NULL MNID_STRING PS_PUBLIC_STRINGS 0x9589 NULL NULL 0x0000 urn:schemas:httpmail:cc PT_NULL MNID_STRING PS_PUBLIC_STRINGS 0x958a NULL NULL 0x0000 urn:schemas:httpmail:contacts PT_NULL MNID_STRING PS_PUBLIC_STRINGS 0x958b NULL NULL 0x0000 urn:schemas:httpmail:content-disposition-type PT_NULL MNID_STRING PS_PUBLIC_STRINGS 0x958c NULL NULL 0x0000 urn:schemas:httpmail:content-media-type PT_NULL MNID_STRING PS_PUBLIC_STRINGS 0x958d NULL NULL 0x0000 urn:schemas:httpmail:deleteditems PT_NULL MNID_STRING PS_PUBLIC_STRINGS 0x958e NULL NULL 0x0000 urn:schemas:httpmail:drafts PT_NULL MNID_STRING PS_PUBLIC_STRINGS 0x958f NULL NULL 0x0000 urn:schemas:httpmail:from PT_NULL MNID_STRING PS_PUBLIC_STRINGS 0x9590 NULL NULL 0x0000 urn:schemas:httpmail:fromemail PT_NULL MNID_STRING PS_PUBLIC_STRINGS 0x9591 NULL NULL 0x0000 urn:schemas:httpmail:inbox PT_NULL MNID_STRING PS_PUBLIC_STRINGS 0x9592 NULL NULL 0x0000 urn:schemas:httpmail:journal PT_NULL MNID_STRING PS_PUBLIC_STRINGS 0x9593 NULL NULL 0x0000 urn:schemas:httpmail:msgfolderroot PT_NULL MNID_STRING PS_PUBLIC_STRINGS 0x9594 NULL NULL 0x0000 urn:schemas:httpmail:notes PT_NULL MNID_STRING PS_PUBLIC_STRINGS 0x9595 NULL NULL 0x0000 urn:schemas:httpmail:outbox PT_NULL MNID_STRING PS_PUBLIC_STRINGS 0x9596 NULL NULL 0x0000 urn:schemas:httpmail:sender PT_NULL MNID_STRING PS_PUBLIC_STRINGS 0x9597 NULL NULL 0x0000 urn:schemas:httpmail:senderemail PT_NULL MNID_STRING PS_PUBLIC_STRINGS 0x9598 NULL NULL 0x0000 urn:schemas:httpmail:sendmsg PT_NULL MNID_STRING PS_PUBLIC_STRINGS 0x9599 NULL NULL 0x0000 urn:schemas:httpmail:sentitems PT_NULL MNID_STRING PS_PUBLIC_STRINGS 0x959a NULL NULL 0x0000 urn:schemas:httpmail:special PT_NULL MNID_STRING PS_PUBLIC_STRINGS 0x959b NULL NULL 0x0000 urn:schemas:httpmail:tasks PT_NULL MNID_STRING PS_PUBLIC_STRINGS 0x959c NULL NULL 0x0000 urn:schemas:httpmail:reply-to PT_NULL MNID_STRING PS_PUBLIC_STRINGS 0x959d NULL NULL 0x0000 urn:schemas:httpmail:submitted PT_NULL MNID_STRING PS_PUBLIC_STRINGS 0x959e NULL NULL 0x0000 urn:schemas:httpmail:to PT_NULL MNID_STRING PS_PUBLIC_STRINGS 0x959f NULL NULL 0x0000 urn:schemas:httpmail:saveinsent PT_NULL MNID_STRING PS_PUBLIC_STRINGS 0x95a0 NULL NULL 0x0000 urn:schemas:httpmail:savedestination PT_NULL MNID_STRING PS_PUBLIC_STRINGS 0x95a1 NULL NULL 0x0000 urn:schemas:httpmail:junkemail PT_NULL MNID_STRING PS_PUBLIC_STRINGS 0x95a2 NULL NULL 0x0000 urn:schemas:httpmail:htmldescription PT_NULL MNID_STRING PS_PUBLIC_STRINGS 0x95a3 NULL NULL 0x0000 urn:schemas-microsoft-com:exch-data:schema-uri PT_NULL MNID_STRING PS_PUBLIC_STRINGS 0x95a4 NULL NULL 0x0000 urn:schemas-microsoft-com:exch-data:schema-collection-ref PT_NULL MNID_STRING PS_PUBLIC_STRINGS 0x95a5 NULL NULL 0x0000 urn:schemas-microsoft-com:exch-data:baseschema PT_NULL MNID_STRING PS_PUBLIC_STRINGS 0x95a6 NULL NULL 0x0000 urn:schemas-microsoft-com:exch-data:expected-content-class PT_NULL MNID_STRING PS_PUBLIC_STRINGS 0x95a7 NULL NULL 0x0000 urn:schemas-microsoft-com:exch-data:default PT_NULL MNID_STRING PS_PUBLIC_STRINGS 0x95a8 NULL NULL 0x0000 urn:schemas-microsoft-com:exch-data:dictionary PT_NULL MNID_STRING PS_PUBLIC_STRINGS 0x95a9 NULL NULL 0x0000 urn:schemas-microsoft-com:exch-data:iscontentindexed PT_NULL MNID_STRING PS_PUBLIC_STRINGS 0x95aa NULL NULL 0x0000 urn:schemas-microsoft-com:exch-data:isindexed PT_NULL MNID_STRING PS_PUBLIC_STRINGS 0x95ab NULL NULL 0x0000 urn:schemas-microsoft-com:exch-data:ismultivalued PT_NULL MNID_STRING PS_PUBLIC_STRINGS 0x95ac NULL NULL 0x0000 urn:schemas-microsoft-com:exch-data:isreadonly PT_NULL MNID_STRING PS_PUBLIC_STRINGS 0x95ad NULL NULL 0x0000 urn:schemas-microsoft-com:exch-data:isrequired PT_NULL MNID_STRING PS_PUBLIC_STRINGS 0x95ae NULL NULL 0x0000 urn:schemas-microsoft-com:exch-data:isvisible PT_NULL MNID_STRING PS_PUBLIC_STRINGS 0x95af NULL NULL 0x0000 urn:schemas-microsoft-com:exch-data:propertydef PT_NULL MNID_STRING PS_PUBLIC_STRINGS 0x95b0 NULL NULL 0x0000 urn:schemas-microsoft-com:exch-data:synchronize PT_NULL MNID_STRING PS_PUBLIC_STRINGS 0x95b1 NULL NULL 0x0000 urn:schemas-microsoft-com:exch-data:version PT_NULL MNID_STRING PS_PUBLIC_STRINGS 0x95b2 NULL NULL 0x0000 urn:schemas-microsoft-com:exch-data:closedexpectedcontentclasses PT_NULL MNID_STRING PS_PUBLIC_STRINGS 0x95b3 NULL NULL 0x0000 urn:schemas-microsoft-com:exch-data:codebase PT_NULL MNID_STRING PS_PUBLIC_STRINGS 0x95b4 NULL NULL 0x0000 urn:schemas-microsoft-com:exch-data:comclassid PT_NULL MNID_STRING PS_PUBLIC_STRINGS 0x95b5 NULL NULL 0x0000 urn:schemas-microsoft-com:exch-data:comprogid PT_NULL MNID_STRING PS_PUBLIC_STRINGS 0x95b6 NULL NULL 0x0000 urn:schemas-microsoft-com:exch-data:form PT_NULL MNID_STRING PS_PUBLIC_STRINGS 0x95b7 NULL NULL 0x0000 urn:schemas-microsoft-com:datatypes#type PT_NULL MNID_STRING PS_PUBLIC_STRINGS 0x95b8 NULL NULL 0x0000 urn:schemas-microsoft-com:xml-data#element PT_NULL MNID_STRING PS_PUBLIC_STRINGS 0x95b9 NULL NULL 0x0000 urn:schemas-microsoft-com:xml-data#extends PT_NULL MNID_STRING PS_PUBLIC_STRINGS 0x95ba NULL NULL 0x0000 urn:schemas-microsoft-com:xml-data#name PT_NULL MNID_STRING PS_PUBLIC_STRINGS 0x95bb NULL NULL 0x0000 urn:schemas-microsoft-com:office:outlook#fixupfbfolder PT_NULL MNID_STRING PS_PUBLIC_STRINGS 0x95bc NULL NULL 0x0000 urn:schemas-microsoft-com:publishing:BaseDoc PT_NULL MNID_STRING PS_PUBLIC_STRINGS 0x95bd NULL NULL 0x0000 urn:schemas-microsoft-com:publishing:WorkingCopy PT_NULL MNID_STRING PS_PUBLIC_STRINGS 0x95be NULL NULL 0x0000 urn:schemas-microsoft-com:publishing:LastUnapprovedVersion PT_NULL MNID_STRING PS_PUBLIC_STRINGS 0x95bf NULL NULL 0x0000 urn:schemas-microsoft-com:publishing:LastApprovedVersion PT_NULL MNID_STRING PS_PUBLIC_STRINGS 0x95c0 NULL NULL 0x0000 urn:schemas-microsoft-com:publishing:MainFolder PT_NULL MNID_STRING PS_PUBLIC_STRINGS 0x95c1 PidNameRunat NULL 0x0000 http://schemas.microsoft.com/exchange/runat PT_NULL MNID_STRING PS_PUBLIC_STRINGS 0x95c2 PidNameSchemaversion NULL 0x0000 http://schemas.microsoft.com/exchange/schemaversion PT_NULL MNID_STRING PS_PUBLIC_STRINGS 0x95c3 PidNameBaseitemuri NULL 0x0000 http://schemas.microsoft.com/exchange/baseitemuri PT_NULL MNID_STRING PS_PUBLIC_STRINGS 0x95c4 PidNameRootfid NULL 0x0000 http://schemas.microsoft.com/exchange/rootfid PT_NULL MNID_STRING PS_PUBLIC_STRINGS 0x95c5 PidNameSmallicon NULL 0x0000 http://schemas.microsoft.com/exchange/smallicon PT_NULL MNID_STRING PS_PUBLIC_STRINGS 0x95c6 PidNameOofState NULL 0x0000 http://schemas.microsoft.com/exchange/oof-state PT_NULL MNID_STRING PS_PUBLIC_STRINGS 0x95c7 PidNameMailboxOwnerName NULL 0x0000 http://schemas.microsoft.com/exchange/mailbox-owner-name PT_NULL MNID_STRING PS_PUBLIC_STRINGS 0x95c8 PidNameMailboxOwnerEntryid NULL 0x0000 http://schemas.microsoft.com/exchange/mailbox-owner-entryid PT_NULL MNID_STRING PS_PUBLIC_STRINGS 0x95c9 PidNameUserEntryid NULL 0x0000 http://schemas.microsoft.com/exchange/user-entryid PT_NULL MNID_STRING PS_PUBLIC_STRINGS 0x95ca PidNameOtherproxyaddresses NULL 0x0000 http://schemas.microsoft.com/exchange/otherproxyaddresses PT_NULL MNID_STRING PS_PUBLIC_STRINGS 0x95cb PidNameArchive NULL 0x0000 http://schemas.microsoft.com/exchange/archive PT_NULL MNID_STRING PS_PUBLIC_STRINGS 0x95cc PidNameDeliverandredirect NULL 0x0000 http://schemas.microsoft.com/exchange/deliverandredirect PT_NULL MNID_STRING PS_PUBLIC_STRINGS 0x95cd PidNameFboldbusystatus NULL 0x0000 http://schemas.microsoft.com/exchange/fboldbusystatus PT_NULL MNID_STRING PS_PUBLIC_STRINGS 0x95ce PidNameFboldend NULL 0x0000 http://schemas.microsoft.com/exchange/fboldend PT_NULL MNID_STRING PS_PUBLIC_STRINGS 0x95cf PidNameFboldstart NULL 0x0000 http://schemas.microsoft.com/exchange/fboldstart PT_NULL MNID_STRING PS_PUBLIC_STRINGS 0x95d0 PidNameFbqueryend NULL 0x0000 http://schemas.microsoft.com/exchange/fbqueryend PT_NULL MNID_STRING PS_PUBLIC_STRINGS 0x95d1 PidNameFbqueryinterval NULL 0x0000 http://schemas.microsoft.com/exchange/fbqueryinterval PT_NULL MNID_STRING PS_PUBLIC_STRINGS 0x95d2 PidNameFbquerystart NULL 0x0000 http://schemas.microsoft.com/exchange/fbquerystart PT_NULL MNID_STRING PS_PUBLIC_STRINGS 0x95d3 PidNameFbquerystring NULL 0x0000 http://schemas.microsoft.com/exchange/fbquerystring PT_NULL MNID_STRING PS_PUBLIC_STRINGS 0x95d4 PidNameFbrecurisdirty NULL 0x0000 http://schemas.microsoft.com/exchange/fbrecurisdirty PT_NULL MNID_STRING PS_PUBLIC_STRINGS 0x95d5 PidNameForwardingaddress NULL 0x0000 http://schemas.microsoft.com/exchange/forwardingaddress PT_NULL MNID_STRING PS_PUBLIC_STRINGS 0x95d6 PidNameIntendedbusystatus NULL 0x0000 http://schemas.microsoft.com/exchange/intendedbusystatus PT_NULL MNID_STRING PS_PUBLIC_STRINGS 0x95d7 PidNameModifyexceptionstruct NULL 0x0000 http://schemas.microsoft.com/exchange/modifyexceptionstruct PT_NULL MNID_STRING PS_PUBLIC_STRINGS 0x95d8 PidNameNomodifyexceptions NULL 0x0000 http://schemas.microsoft.com/exchange/nomodifyexceptions PT_NULL MNID_STRING PS_PUBLIC_STRINGS 0x95d9 PidNamePatternend NULL 0x0000 http://schemas.microsoft.com/exchange/patternend PT_NULL MNID_STRING PS_PUBLIC_STRINGS 0x95da PidNamePatternstart NULL 0x0000 http://schemas.microsoft.com/exchange/patternstart PT_NULL MNID_STRING PS_PUBLIC_STRINGS 0x95db PidNamePublicfolderemailaddress NULL 0x0000 http://schemas.microsoft.com/exchange/publicfolderemailaddress PT_NULL MNID_STRING PS_PUBLIC_STRINGS 0x95dc PidNameSearchfolder NULL 0x0000 http://schemas.microsoft.com/exchange/searchfolder PT_NULL MNID_STRING PS_PUBLIC_STRINGS 0x95dd PidNameTimezone NULL 0x0000 http://schemas.microsoft.com/exchange/timezone PT_NULL MNID_STRING PS_PUBLIC_STRINGS 0x95de PidNameTimeformat NULL 0x0000 http://schemas.microsoft.com/exchange/timeformat PT_NULL MNID_STRING PS_PUBLIC_STRINGS 0x95df PidNameLongdateformat NULL 0x0000 http://schemas.microsoft.com/exchange/longdateformat PT_NULL MNID_STRING PS_PUBLIC_STRINGS 0x95e0 PidNameShortdateformat NULL 0x0000 http://schemas.microsoft.com/exchange/shortdateformat PT_NULL MNID_STRING PS_PUBLIC_STRINGS 0x95e1 PidNameWeekstartday NULL 0x0000 http://schemas.microsoft.com/exchange/weekstartday PT_NULL MNID_STRING PS_PUBLIC_STRINGS 0x95e2 PidNameWorkdays NULL 0x0000 http://schemas.microsoft.com/exchange/workdays PT_NULL MNID_STRING PS_PUBLIC_STRINGS 0x95e3 PidNameWorkdaystarttime NULL 0x0000 http://schemas.microsoft.com/exchange/workdaystarttime PT_NULL MNID_STRING PS_PUBLIC_STRINGS 0x95e4 PidNameWorkdayendtime NULL 0x0000 http://schemas.microsoft.com/exchange/workdayendtime PT_NULL MNID_STRING PS_PUBLIC_STRINGS 0x95e5 PidNameAnrcontactsfirst NULL 0x0000 http://schemas.microsoft.com/exchange/anrcontactsfirst PT_NULL MNID_STRING PS_PUBLIC_STRINGS 0x95e6 PidNameWebclientlastusedview NULL 0x0000 http://schemas.microsoft.com/exchange/webclientlastusedview PT_NULL MNID_STRING PS_PUBLIC_STRINGS 0x95e7 PidNameWebclientshowhierarchy NULL 0x0000 http://schemas.microsoft.com/exchange/webclientshowhierarchy PT_NULL MNID_STRING PS_PUBLIC_STRINGS 0x95e8 PidNameQuicklinks NULL 0x0000 http://schemas.microsoft.com/exchange/quicklinks PT_NULL MNID_STRING PS_PUBLIC_STRINGS 0x95e9 PidNameAutoaddsignature NULL 0x0000 http://schemas.microsoft.com/exchange/autoaddsignature PT_NULL MNID_STRING PS_PUBLIC_STRINGS 0x95ea PidNameSignaturetext NULL 0x0000 http://schemas.microsoft.com/exchange/signaturetext PT_NULL MNID_STRING PS_PUBLIC_STRINGS 0x95eb PidNameSignaturehtml NULL 0x0000 http://schemas.microsoft.com/exchange/signaturehtml PT_NULL MNID_STRING PS_PUBLIC_STRINGS 0x95ec PidNameBlockexternalcontent NULL 0x0000 http://schemas.microsoft.com/exchange/blockexternalcontent PT_NULL MNID_STRING PS_PUBLIC_STRINGS 0x95ed PidNameWebclientnavbarwidth NULL 0x0000 http://schemas.microsoft.com/exchange/webclientnavbarwidth PT_NULL MNID_STRING PS_PUBLIC_STRINGS 0x95ee PidNameWcviewwidth NULL 0x0000 http://schemas.microsoft.com/exchange/wcviewwidth PT_NULL MNID_STRING PS_PUBLIC_STRINGS 0x95ef PidNameWcviewheight NULL 0x0000 http://schemas.microsoft.com/exchange/wcviewheight PT_NULL MNID_STRING PS_PUBLIC_STRINGS 0x95f0 PidNamePreview NULL 0x0000 http://schemas.microsoft.com/exchange/preview PT_NULL MNID_STRING PS_PUBLIC_STRINGS 0x95f1 PidNameWebclientlastusedsortcols NULL 0x0000 http://schemas.microsoft.com/exchange/webclientlastusedsortcols PT_NULL MNID_STRING PS_PUBLIC_STRINGS 0x95f2 PidLidUnknownProperty85d9 LID_UNKNOWN_PROPERTY_85d9 0x85d9 NULL PT_NULL MNID_ID PSETID_CalendarAssistant 0x95f3 PidNameTimeZone NULL 0x0000 TimeZone PT_NULL MNID_STRING PSETID_Appointment2 0x95f7 openchange-2.0/libmapi/conf/mapi-properties000066400000000000000000001644661223057412600211120ustar00rootroot00000000000000# # OpenChange MAPI implementation. # MAPI property tags # # This file was originally taken from the Gnome Evolution project. # evolution/evolution-exchange/docs/mapi-properties # # For the OpenChange project, UNICODE properties (1f) have been # replaced by PT_STRING8 ones (1e) # # This program is free software; you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by # the Free Software Foundation; either version 3 of the License, or # (at your option) any later version. # # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program. If not, see . # 0x00010003 PR_ACKNOWLEDGEMENT_MODE 0x0002000b PR_ALTERNATE_RECIPIENT_ALLOWED 0x00030102 PR_AUTHORIZING_USERS 0x0004001e PR_AUTO_FORWARD_COMMENT 0x0005000b PR_AUTO_FORWARDED 0x00060102 PR_CONTENT_CONFIDENTIALITY_ALGORITHM_ID 0x00070102 PR_CONTENT_CORRELATOR 0x0008001e PR_CONTENT_IDENTIFIER 0x00090003 PR_CONTENT_LENGTH 0x000a000b PR_CONTENT_RETURN_REQUESTED 0x000b0102 PR_CONVERSATION_KEY 0x000c0102 PR_CONVERSION_EITS 0x000d000b PR_CONVERSION_WITH_LOSS_PROHIBITED 0x000e0102 PR_CONVERTED_EITS 0x000f0040 PR_DEFERRED_DELIVERY_TIME 0x00100040 PR_DELIVER_TIME 0x00110003 PR_DISCARD_REASON 0x0012000b PR_DISCLOSURE_OF_RECIPIENTS 0x00130102 PR_DL_EXPANSION_HISTORY 0x0014000b PR_DL_EXPANSION_PROHIBITED 0x00150040 PR_EXPIRY_TIME 0x0016000b PR_IMPLICIT_CONVERSION_PROHIBITED 0x00170003 PR_IMPORTANCE PidTagImportance 0x00180102 PR_IPM_ID 0x00190040 PR_LATEST_DELIVERY_TIME 0x001a001e PR_MESSAGE_CLASS PidTagMessageClass 0x001b0102 PR_MESSAGE_DELIVERY_ID 0x001e0102 PR_MESSAGE_SECURITY_LABEL 0x001f0102 PR_OBSOLETED_IPMS 0x00200102 PR_ORIGINALLY_INTENDED_RECIPIENT_NAME 0x00210102 PR_ORIGINAL_EITS 0x00220102 PR_ORIGINATOR_CERTIFICATE 0x0023000b PR_ORIGINATOR_DELIVERY_REPORT_REQUESTED 0x00240102 PR_ORIGINATOR_RETURN_ADDRESS 0x00250102 PR_PARENT_KEY 0x00260003 PR_PRIORITY 0x00270102 PR_ORIGIN_CHECK 0x0028000b PR_PROOF_OF_SUBMISSION_REQUESTED 0x0029000b PR_READ_RECEIPT_REQUESTED 0x002a0040 PR_RECEIPT_TIME 0x002b000b PR_RECIPIENT_REASSIGNMENT_PROHIBITED 0x002c0102 PR_REDIRECTION_HISTORY 0x002d0102 PR_RELATED_IPMS 0x002e0003 PR_ORIGINAL_SENSITIVITY 0x002f001e PR_LANGUAGES 0x00300040 PR_REPLY_TIME 0x00310102 PR_REPORT_TAG 0x00320040 PR_REPORT_TIME 0x0033000b PR_RETURNED_IPM 0x00340003 PR_SECURITY 0x0035000b PR_INCOMPLETE_COPY 0x00360003 PR_SENSITIVITY PidTagSensitivity 0x0037001e PR_SUBJECT 0x00380102 PR_SUBJECT_IPM 0x00390040 PR_CLIENT_SUBMIT_TIME 0x003a001e PR_REPORT_NAME 0x003b0102 PR_SENT_REPRESENTING_SEARCH_KEY 0x003c0102 PR_X400_CONTENT_TYPE 0x003d001e PR_SUBJECT_PREFIX 0x003e0003 PR_NON_RECEIPT_REASON 0x003f0102 PR_RECEIVED_BY_ENTRYID 0x0040001e PR_RECEIVED_BY_NAME 0x00410102 PR_SENT_REPRESENTING_ENTRYID 0x0042001e PR_SENT_REPRESENTING_NAME 0x00430102 PR_RCVD_REPRESENTING_ENTRYID 0x0044001e PR_RCVD_REPRESENTING_NAME 0x00450102 PR_REPORT_ENTRYID 0x00460102 PR_READ_RECEIPT_ENTRYID 0x00470102 PR_MESSAGE_SUBMISSION_ID 0x00480040 PR_PROVIDER_SUBMIT_TIME 0x0049001e PR_ORIGINAL_SUBJECT 0x004a000b PR_DISC_VAL 0x004b001e PR_ORIG_MESSAGE_CLASS 0x004c0102 PR_ORIGINAL_AUTHOR_ENTRYID 0x004d001e PR_ORIGINAL_AUTHOR_NAME 0x004e0040 PR_ORIGINAL_SUBMIT_TIME 0x004f0102 PR_REPLY_RECIPIENT_ENTRIES 0x0050001e PR_REPLY_RECIPIENT_NAMES 0x00510102 PR_RECEIVED_BY_SEARCH_KEY 0x00520102 PR_RCVD_REPRESENTING_SEARCH_KEY 0x00530102 PR_READ_RECEIPT_SEARCH_KEY 0x00540102 PR_REPORT_SEARCH_KEY 0x00550040 PR_ORIGINAL_DELIVERY_TIME 0x00560102 PR_ORIGINAL_AUTHOR_SEARCH_KEY 0x0057000b PR_MESSAGE_TO_ME 0x0058000b PR_MESSAGE_CC_ME 0x0059000b PR_MESSAGE_RECIP_ME 0x005a001e PR_ORIGINAL_SENDER_NAME 0x005b0102 PR_ORIGINAL_SENDER_ENTRYID 0x005c0102 PR_ORIGINAL_SENDER_SEARCH_KEY 0x005d001e PR_ORIGINAL_SENT_REPRESENTING_NAME 0x005e0102 PR_ORIGINAL_SENT_REPRESENTING_ENTRYID 0x005f0102 PR_ORIGINAL_SENT_REPRESENTING_SEARCH_KEY 0x00600040 PR_START_DATE 0x00610040 PR_END_DATE 0x00620003 PR_OWNER_APPT_ID 0x0063000b PR_RESPONSE_REQUESTED 0x0064001e PR_SENT_REPRESENTING_ADDRTYPE 0x0065001e PR_SENT_REPRESENTING_EMAIL_ADDRESS 0x0066001e PR_ORIGINAL_SENDER_ADDRTYPE 0x0067001e PR_ORIGINAL_SENDER_EMAIL_ADDRESS 0x0068001e PR_ORIGINAL_SENT_REPRESENTING_ADDRTYPE 0x0069001e PR_ORIGINAL_SENT_REPRESENTING_EMAIL_ADDRESS 0x0070001e PR_CONVERSATION_TOPIC 0x00710102 PR_CONVERSATION_INDEX 0x0072001e PR_ORIGINAL_DISPLAY_BCC 0x0073001e PR_ORIGINAL_DISPLAY_CC 0x0074001e PR_ORIGINAL_DISPLAY_TO 0x0075001e PR_RECEIVED_BY_ADDRTYPE 0x0076001e PR_RECEIVED_BY_EMAIL_ADDRESS 0x0077001e PR_RCVD_REPRESENTING_ADDRTYPE 0x0078001e PR_RCVD_REPRESENTING_EMAIL_ADDRESS 0x0079001e PR_ORIGINAL_AUTHOR_ADDRTYPE 0x007a001e PR_ORIGINAL_AUTHOR_EMAIL_ADDRESS 0x007b001e PR_ORIGINALLY_INTENDED_RECIP_ADDRTYPE 0x007c001e PR_ORIGINALLY_INTENDED_RECIP_EMAIL_ADDRESS 0x007d001e PR_TRANSPORT_MESSAGE_HEADERS PidTagTransportMessageHeaders 0x007e0102 PR_DELEGATION 0x007f0102 PR_TNEF_CORRELATION_KEY 0x0c000102 PR_CONTENT_INTEGRITY_CHECK 0x0c010003 PR_EXPLICIT_CONVERSION 0x0c02000b PR_IPM_RETURN_REQUESTED 0x0c030102 PR_MESSAGE_TOKEN 0x0c040003 PR_NDR_REASON_CODE 0x0c050003 PR_NDR_DIAG_CODE 0x0c06000b PR_NON_RECEIPT_NOTIFICATION_REQUESTED 0x0c070003 PR_DELIVERY_POINT 0x0c08000b PR_ORIGINATOR_NON_DELIVERY_REPORT_REQUESTED 0x0c090102 PR_ORIGINATOR_REQUESTED_ALTERNATE_RECIPIENT 0x0c0a000b PR_PHYSICAL_DELIVERY_BUREAU_FAX_DELIVERY 0x0c0b0003 PR_PHYSICAL_DELIVERY_MODE 0x0c0c0003 PR_PHYSICAL_DELIVERY_REPORT_REQUEST 0x0c0d0102 PR_PHYSICAL_FORWARDING_ADDRESS 0x0c0e000b PR_PHYSICAL_FORWARDING_ADDRESS_REQUESTED 0x0c0f000b PR_PHYSICAL_FORWARDING_PROHIBITED 0x0c100102 PR_PHYSICAL_RENDITION_ATTRIBUTES 0x0c110102 PR_PROOF_OF_DELIVERY 0x0c12000b PR_PROOF_OF_DELIVERY_REQUESTED 0x0c130102 PR_RECIPIENT_CERTIFICATE 0x0c14001e PR_RECIPIENT_NUMBER_FOR_ADVICE 0x0c150003 PR_RECIPIENT_TYPE PidTagRecipientType 0x0c160003 PR_REGISTERED_MAIL_TYPE 0x0c17000b PR_REPLY_REQUESTED 0x0c180003 PR_REQUESTED_DELIVERY_METHOD 0x0c190102 PR_SENDER_ENTRYID 0x0c1a001e PR_SENDER_NAME 0x0c1b001e PR_SUPPLEMENTARY_INFO 0x0c1c0003 PR_TYPE_OF_MTS_USER 0x0c1d0102 PR_SENDER_SEARCH_KEY 0x0c1e001e PR_SENDER_ADDRTYPE 0x0c1f001e PR_SENDER_EMAIL_ADDRESS 0x0c200003 PR_NDR_STATUS_CODE 0x0e000014 PR_CURRENT_VERSION 0x0e01000b PR_DELETE_AFTER_SUBMIT 0x0e02001e PR_DISPLAY_BCC PidTagDisplayBcc 0x0e03001e PR_DISPLAY_CC PidTagDisplayCc 0x0e04001e PR_DISPLAY_TO PidTagDisplayTo 0x0e05001e PR_PARENT_DISPLAY 0x0e060040 PR_MESSAGE_DELIVERY_TIME 0x0e070003 PR_MESSAGE_FLAGS PidTagMessageFlags 0x0e080003 PR_MESSAGE_SIZE PidTagMessageSize 0x0e080014 PR_MESSAGE_SIZE_EXTENDED 0x0e090102 PR_PARENT_ENTRYID 0x0e0a0102 PR_SENTMAIL_ENTRYID 0x0e0c000b PR_CORRELATE 0x0e0d0102 PR_CORRELATE_MTSID 0x0e0e000b PR_DISCRETE_VALUES 0x0e0f000b PR_RESPONSIBILITY 0x0e100003 PR_SPOOLER_STATUS 0x0e110003 PR_TRANSPORT_STATUS 0x0e12000d PR_MESSAGE_RECIPIENTS 0x0e13000d PR_MESSAGE_ATTACHMENTS 0x0e140003 PR_SUBMIT_FLAGS 0x0e150003 PR_RECIPIENT_STATUS 0x0e160003 PR_TRANSPORT_KEY 0x0e170003 PR_MSG_STATUS 0x0e180003 PR_MESSAGE_DOWNLOAD_TIME 0x0e190014 PR_CREATION_VERSION 0x0e1a0014 PR_MODIFY_VERSION 0x0e1b000b PR_HASATTACH PidTagHasAttachments 0x0e1c0003 PR_BODY_CRC 0x0e1d001e PR_NORMALIZED_SUBJECT PidTagNormalizedSubject 0x0e1f000b PR_RTF_IN_SYNC 0x0e200003 PR_ATTACH_SIZE 0x0e210003 PR_ATTACH_NUM 0x0e22000b PR_PREPROCESS 0x0e230003 PR_INTERNET_ARTICLE_NUMBER 0x0e24001e PR_NEWSGROUP_NAME 0x0e250102 PR_ORIGINATING_MTA_CERTIFICATE 0x0e260102 PR_PROOF_OF_SUBMISSION 0x0e270102 PR_NT_SECURITY_DESCRIPTOR PidTagSecurityDescriptor 0x0e28001f PR_PRIMARY_SEND_ACCT 0x0e29001f PR_NEXT_SEND_ACCT 0x0e580102 PR_CREATOR_SID 0x0e590102 PR_LAST_MODIFIER_SID 0x0e5e0048 PR_MIME_HANDLER_CLASSIDS 0x0e610003 PR_URL_COMP_NAME_POSTFIX 0x0e62000b PR_URL_COMP_NAME_SET PidTagUrlCompNameSet 0x0e630003 PR_SUBFOLDER_CT 0x0e640003 PR_DELETED_SUBFOLDER_CT 0x0e660040 PR_DELETE_TIME 0x0e670102 PR_AGE_LIMIT 0x0e6a001f PR_NT_SECURITY_DESCRIPTOR_AS_XML 0x0e790003 PR_TRUST_SENDER PidTagTrustSender 0x0e960102 PR_ATTACH_VIRUS_SCAN_INFO 0x0e990102 PR_EXTENDED_RULE_MSG_ACTIONS 0x0e9a0102 PR_EXTENDED_RULE_MSG_CONDITION 0x0e9b0003 PR_EXTENDED_RULE_SIZE_LIMIT 0x0ff40003 PR_ACCESS PidTagAccess 0x0ff50003 PR_ROW_TYPE 0x0ff60102 PR_INSTANCE_KEY PidTagInstanceKey 0x0ff70003 PR_ACCESS_LEVEL PidTagAccessLevel 0x0ff80102 PR_MAPPING_SIGNATURE 0x0ff90102 PR_RECORD_KEY 0x0ffa0102 PR_STORE_RECORD_KEY 0x0ffb0102 PR_STORE_ENTRYID 0x0ffc0102 PR_MINI_ICON 0x0ffd0102 PR_ICON 0x0ffe0003 PR_OBJECT_TYPE 0x0fff0102 PR_ENTRYID PidTagEntryId 0x1000001e PR_BODY 0x1001001e PR_REPORT_TEXT 0x10020102 PR_ORIGINATOR_AND_DL_EXPANSION_HISTORY 0x10030102 PR_REPORTING_DL_NAME 0x10040102 PR_REPORTING_MTA_CERTIFICATE 0x10060003 PR_RTF_SYNC_BODY_CRC 0x10070003 PR_RTF_SYNC_BODY_COUNT 0x1008001e PR_RTF_SYNC_BODY_TAG 0x10090102 PR_RTF_COMPRESSED 0x10100003 PR_RTF_SYNC_PREFIX_COUNT 0x10110003 PR_RTF_SYNC_TRAILING_COUNT 0x10120102 PR_ORIGINALLY_INTENDED_RECIP_ENTRYID 0x1013001e PR_BODY_HTML 0x10130102 PR_HTML 0x10160003 PR_NATIVE_BODY_INFO 0x1030001e PR_INTERNET_APPROVED 0x1031001e PR_INTERNET_CONTROL 0x1032001e PR_INTERNET_DISTRIBUTION 0x1033001e PR_INTERNET_FOLLOWUP_TO 0x10340003 PR_INTERNET_LINES 0x1035001e PR_INTERNET_MESSAGE_ID 0x1036001e PR_INTERNET_NEWSGROUPS 0x1037001e PR_INTERNET_ORGANIZATION 0x1038001e PR_INTERNET_NNTP_PATH 0x1039001e PR_INTERNET_REFERENCES 0x103a001e PR_SUPERSEDES 0x103b0102 PR_POST_FOLDER_ENTRIES 0x103c001e PR_POST_FOLDER_NAMES 0x103d0102 PR_POST_REPLY_FOLDER_ENTRIES 0x103e001e PR_POST_REPLY_FOLDER_NAMES 0x103f0102 PR_POST_REPLY_DENIED 0x1040001e PR_NNTP_XREF 0x1041001e PR_INTERNET_PRECEDENCE 0x1042001e PR_IN_REPLY_TO_ID 0x1043001e PR_LIST_HELP 0x1044001e PR_LIST_SUBSCRIBE 0x1045001e PR_LIST_UNSUBSCRIBE 0x10800003 PR_ICON_INDEX 0x10810003 PR_ACTION_FLAG 0x10820040 PR_ACTION_DATE 0x10900003 PR_FLAG_STATUS 0x10910040 PR_FLAG_COMPLETE 0x10950003 PR_FOLLOWUP_ICON PidTagFollowupIcon 0x10970003 PR_ITEM_TEMPORARY_FLAGS PidTagItemTemporaryflags 0x10c00102 PR_SMTP_TEMP_TBL_DATA 0x10c10003 PR_SMTP_TEMP_TBL_DATA_2 0x10c20102 PR_SMTP_TEMP_TBL_DATA_3 0x10c30040 PR_CAL_START_TIME 0x10c40040 PR_CAL_END_TIME 0x10c50040 PR_CAL_RECURRING_ID 0x10c6001e PR_DAV_SUBMIT_DATA 0x10c70003 PR_CDO_EXPANSION_INDEX 0x10c80102 PR_IFS_INTERNAL_DATA 0x10ca0040 PR_CAL_REMINDER_NEXT_TIME 0x10f1001e PR_OWA_URL 0x10f2000b PR_DISABLE_FULL_FIDELITY 0x10f3001e PR_URL_COMP_NAME PidTagUrlCompName 0x10f4000b PR_ATTR_HIDDEN PidTagAttributeHidden 0x10f5000b PR_ATTR_SYSTEM PidTagAttributeSystem 0x10f6000b PR_ATTR_READONLY PidTagAttributeReadOnly 0x11000102 PR_P1_CONTENT 0x11010102 PR_P1_CONTENT_TYPE 0x30000003 PR_ROWID 0x3001001e PR_DISPLAY_NAME PidTagDisplayName 0x3002001e PR_ADDRTYPE PidTagAddressType 0x3003001e PR_EMAIL_ADDRESS PidTagEmailAddress 0x3004001e PR_COMMENT PidTagComment 0x30050003 PR_DEPTH PidTagDepth 0x3006001e PR_PROVIDER_DISPLAY 0x30070040 PR_CREATION_TIME PidTagCreationTime 0x30080040 PR_LAST_MODIFICATION_TIME PidTagLastModificationTime 0x30090003 PR_RESOURCE_FLAGS 0x300a001e PR_PROVIDER_DLL_NAME 0x300b0102 PR_SEARCH_KEY PidTagSearchKey 0x300c0102 PR_PROVIDER_UID 0x300d0003 PR_PROVIDER_ORDINAL 0x30100102 PR_TARGET_ENTRYID 0x30180102 PR_ARCHIVE_TAG 0x30190102 PR_POLICY_TAG 0x301A0003 PR_RETENTION_PERIOD 0x301D0003 PR_RETENTION_FLAGS 0x301E0003 PR_ARCHIVE_PERIOD 0x3301001e PR_FORM_VERSION 0x33020048 PR_FORM_CLSID 0x3303001e PR_FORM_CONTACT_NAME 0x3304001e PR_FORM_CATEGORY 0x3305001e PR_FORM_CATEGORY_SUB 0x33061003 PR_FORM_HOST_MAP 0x3307000b PR_FORM_HIDDEN 0x3308001e PR_FORM_DESIGNER_NAME 0x33090048 PR_FORM_DESIGNER_GUID 0x330a0003 PR_FORM_MESSAGE_BEHAVIOR 0x3400000b PR_DEFAULT_STORE 0x340d0003 PR_STORE_SUPPORT_MASK 0x340e0003 PR_STORE_STATE 0x34100102 PR_IPM_SUBTREE_SEARCH_KEY 0x34110102 PR_IPM_OUTBOX_SEARCH_KEY 0x34120102 PR_IPM_WASTEBASKET_SEARCH_KEY 0x34130102 PR_IPM_SENTMAIL_SEARCH_KEY 0x34140102 PR_MDB_PROVIDER 0x3415000d PR_RECEIVE_FOLDER_SETTINGS 0x35df0003 PR_VALID_FOLDER_MASK 0x35e00102 PR_IPM_SUBTREE_ENTRYID 0x35e20102 PR_IPM_OUTBOX_ENTRYID 0x35e30102 PR_IPM_WASTEBASKET_ENTRYID 0x35e40102 PR_IPM_SENTMAIL_ENTRYID 0x35e50102 PR_VIEWS_ENTRYID 0x35e60102 PR_COMMON_VIEWS_ENTRYID 0x35e70102 PR_FINDER_ENTRYID 0x36000003 PR_CONTAINER_FLAGS 0x36010003 PR_FOLDER_TYPE PidTagFolderType 0x36020003 PR_CONTENT_COUNT PidTagContentCount 0x36030003 PR_CONTENT_UNREAD PidTagContentUnreadCount 0x3604000d PR_CREATE_TEMPLATES 0x3605000d PR_DETAILS_TABLE 0x3607000d PR_SEARCH 0x3609000b PR_SELECTABLE 0x360a000b PR_SUBFOLDERS PidTagSubFolders 0x360b0003 PR_STATUS 0x360c001e PR_ANR 0x360d1003 PR_CONTENTS_SORT_ORDER 0x360e000d PR_CONTAINER_HIERARCHY 0x360f000d PR_CONTAINER_CONTENTS 0x3610000d PR_FOLDER_ASSOCIATED_CONTENTS 0x36110102 PR_DEF_CREATE_DL 0x36120102 PR_DEF_CREATE_MAILUSER 0x3613001e PR_CONTAINER_CLASS PidTagContainerClass 0x36140014 PR_CONTAINER_MODIFY_VERSION 0x36150102 PR_AB_PROVIDER_ID 0x36160102 PR_DEFAULT_VIEW_ENTRYID 0x36170003 PR_ASSOC_CONTENT_COUNT 0x361c0102 PR_PACKED_NAME_PROPS 0x36d00102 PR_IPM_APPOINTMENT_ENTRYID PidTagIpmAppointmentEntryId 0x36d10102 PR_IPM_CONTACT_ENTRYID PidTagIpmContactEntryId 0x36d20102 PR_IPM_JOURNAL_ENTRYID PidTagIpmJournalEntryId 0x36d30102 PR_IPM_NOTE_ENTRYID PidTagIpmNoteEntryId 0x36d40102 PR_IPM_TASK_ENTRYID PidTagIpmTaskEntryId 0x36d50102 PR_REMINDERS_ONLINE_ENTRYID PidTagRemindersOnlineEntryId 0x36d60102 PR_REMINDERS_OFFLINE_ENTRYID 0x36d70102 PR_IPM_DRAFTS_ENTRYID PidTagIpmDraftsEntryId 0x36d81102 PR_ADDITIONAL_REN_ENTRYIDS PidTagAdditionalRenEntryIds 0x36d90102 PR_ADDITIONAL_REN_ENTRYIDS_EX PidTagAdditionalRenEntryIdsEx 0x36da0102 PR_EXTENDED_FOLDER_FLAGS PidTagExtendedFolderFlags 0x36df0102 PR_FOLDER_WEBVIEWINFO 0x36e00102 PR_FOLDER_XVIEWINFO_E PidTagXViewInfoE 0x36e10003 PR_FOLDER_VIEWS_ONLY 0x36e41102 PR_FREEBUSY_ENTRYIDS PidTagFreeBusyEntryIds 0x36e5001e PR_DEF_POST_MSGCLASS PidTagDefaultPostMessageClass 0x36e6001e PR_DEF_FORM_NAME 0x36e9000b PR_GENERATE_EXCHANGE_VIEWS 0x36eb0102 PR_FOLDER_VIEWLIST 0x36ec0003 PR_AGING_PERIOD 0x36ee0003 PR_AGING_GRANULARITY 0x37000102 PR_ATTACHMENT_X400_PARAMETERS 0x3701000d PR_ATTACH_DATA_OBJ 0x37010102 PR_ATTACH_DATA_BIN 0x37020102 PR_ATTACH_ENCODING 0x3703001e PR_ATTACH_EXTENSION 0x3704001e PR_ATTACH_FILENAME 0x37050003 PR_ATTACH_METHOD 0x3707001e PR_ATTACH_LONG_FILENAME 0x3708001e PR_ATTACH_PATHNAME 0x37090102 PR_ATTACH_RENDERING 0x370a0102 PR_ATTACH_TAG 0x370b0003 PR_RENDERING_POSITION 0x370c001e PR_ATTACH_TRANSPORT_NAME 0x370d001e PR_ATTACH_LONG_PATHNAME 0x370e001e PR_ATTACH_MIME_TAG 0x370f0102 PR_ATTACH_ADDITIONAL_INFO 0x3711001f PR_ATTACH_CONTENT_BASE 0x3712001e PR_ATTACH_CONTENT_ID 0x3713001e PR_ATTACH_CONTENT_LOCATION 0x37140003 PR_ATTACH_FLAGS 0x3716001e PR_ATTACH_CONTENT_DISPOSITION 0x38800102 PR_SYNCEVENT_SUPPRESS_GUID 0x39000003 PR_DISPLAY_TYPE 0x39020102 PR_TEMPLATEID 0x39040102 PR_PRIMARY_CAPABILITY 0x39050003 PR_DISPLAY_TYPE_EX 0x39fe001e PR_SMTP_ADDRESS 0x39ff001e PR_7BIT_DISPLAY_NAME PidTagAddressBookDisplayNamePrintable 0x3a00001e PR_ACCOUNT 0x3a010102 PR_ALTERNATE_RECIPIENT 0x3a02001e PR_CALLBACK_TELEPHONE_NUMBER 0x3a03000b PR_CONVERSION_PROHIBITED 0x3a04000b PR_DISCLOSE_RECIPIENTS 0x3a05001e PR_GENERATION 0x3a06001e PR_GIVEN_NAME 0x3a07001e PR_GOVERNMENT_ID_NUMBER 0x3a08001e PR_OFFICE_TELEPHONE_NUMBER 0x3a09001e PR_HOME_TELEPHONE_NUMBER 0x3a0a001e PR_INITIALS 0x3a0b001e PR_KEYWORD 0x3a0c001e PR_LANGUAGE 0x3a0d001e PR_LOCATION 0x3a0e000b PR_MAIL_PERMISSION 0x3a0f001e PR_MHS_COMMON_NAME 0x3a10001e PR_ORGANIZATIONAL_ID_NUMBER 0x3a11001e PR_SURNAME 0x3a120102 PR_ORIGINAL_ENTRYID 0x3a13001e PR_ORIGINAL_DISPLAY_NAME 0x3a140102 PR_ORIGINAL_SEARCH_KEY 0x3a15001e PR_POSTAL_ADDRESS 0x3a16001e PR_COMPANY_NAME 0x3a17001e PR_TITLE 0x3a18001e PR_DEPARTMENT_NAME 0x3a19001e PR_OFFICE_LOCATION 0x3a1a001e PR_PRIMARY_TELEPHONE_NUMBER 0x3a1b001e PR_OFFICE2_TELEPHONE_NUMBER 0x3a1c001e PR_MOBILE_TELEPHONE_NUMBER 0x3a1d001e PR_RADIO_TELEPHONE_NUMBER 0x3a1e001e PR_CAR_TELEPHONE_NUMBER 0x3a1f001e PR_OTHER_TELEPHONE_NUMBER 0x3a20001e PR_TRANSMITTABLE_DISPLAY_NAME PidTagTransmittableDisplayName 0x3a21001e PR_PAGER_TELEPHONE_NUMBER 0x3a220102 PR_USER_CERTIFICATE 0x3a23001e PR_PRIMARY_FAX_NUMBER 0x3a24001e PR_BUSINESS_FAX_NUMBER 0x3a25001e PR_HOME_FAX_NUMBER 0x3a26001e PR_COUNTRY 0x3a27001e PR_LOCALITY 0x3a28001e PR_STATE_OR_PROVINCE 0x3a29001e PR_STREET_ADDRESS 0x3a2a001e PR_POSTAL_CODE 0x3a2b001e PR_POST_OFFICE_BOX 0x3a2c001e PR_TELEX_NUMBER 0x3a2d001e PR_ISDN_NUMBER 0x3a2e001e PR_ASSISTANT_TELEPHONE_NUMBER 0x3a2f001e PR_HOME2_TELEPHONE_NUMBER 0x3a30001e PR_ASSISTANT 0x3a40000b PR_SEND_RICH_INFO PidTagSendRichInfo 0x3a410040 PR_WEDDING_ANNIVERSARY 0x3a420040 PR_BIRTHDAY 0x3a43001e PR_HOBBIES 0x3a44001e PR_MIDDLE_NAME 0x3a45001e PR_DISPLAY_NAME_PREFIX 0x3a46001e PR_PROFESSION 0x3a47001e PR_PREFERRED_BY_NAME 0x3a48001e PR_SPOUSE_NAME 0x3a49001e PR_COMPUTER_NETWORK_NAME 0x3a4a001e PR_CUSTOMER_ID 0x3a4b001e PR_TTYTDD_PHONE_NUMBER 0x3a4c001e PR_FTP_SITE 0x3a4d0002 PR_GENDER 0x3a4e001e PR_MANAGER_NAME 0x3a4f001e PR_NICKNAME 0x3a50001e PR_PERSONAL_HOME_PAGE 0x3a51001e PR_BUSINESS_HOME_PAGE 0x3a520048 PR_CONTACT_VERSION 0x3a531102 PR_CONTACT_ENTRYIDS 0x3a54101e PR_CONTACT_ADDRTYPES 0x3a550003 PR_CONTACT_DEFAULT_ADDRESS_INDEX 0x3a56101e PR_CONTACT_EMAIL_ADDRESSES 0x3a57001e PR_COMPANY_MAIN_PHONE_NUMBER 0x3a58101e PR_CHILDRENS_NAMES 0x3a59001e PR_HOME_ADDRESS_CITY 0x3a5a001e PR_HOME_ADDRESS_COUNTRY 0x3a5b001e PR_HOME_ADDRESS_POSTAL_CODE 0x3a5c001e PR_HOME_ADDRESS_STATE_OR_PROVINCE 0x3a5d001e PR_HOME_ADDRESS_STREET 0x3a5e001e PR_HOME_ADDRESS_POST_OFFICE_BOX 0x3a5f001e PR_OTHER_ADDRESS_CITY 0x3a60001e PR_OTHER_ADDRESS_COUNTRY 0x3a61001e PR_OTHER_ADDRESS_POSTAL_CODE 0x3a62001e PR_OTHER_ADDRESS_STATE_OR_PROVINCE 0x3a63001e PR_OTHER_ADDRESS_STREET 0x3a64001e PR_OTHER_ADDRESS_POST_OFFICE_BOX 0x3a701102 PR_USER_X509_CERTIFICATE 0x3a710003 PR_SEND_INTERNET_ENCODING 0x3d000102 PR_STORE_PROVIDERS 0x3d010102 PR_AB_PROVIDERS 0x3d020102 PR_TRANSPORT_PROVIDERS 0x3d04000b PR_DEFAULT_PROFILE 0x3d051102 PR_AB_SEARCH_PATH 0x3d060102 PR_AB_DEFAULT_DIR 0x3d070102 PR_AB_DEFAULT_PAB 0x3d080102 PR_FILTERING_HOOKS 0x3d09001e PR_SERVICE_NAME 0x3d0a001e PR_SERVICE_DLL_NAME 0x3d0b001e PR_SERVICE_ENTRY_NAME 0x3d0c0102 PR_SERVICE_UID 0x3d0d0102 PR_SERVICE_EXTRA_UIDS 0x3d0e0102 PR_SERVICES 0x3d0f101e PR_SERVICE_SUPPORT_FILES 0x3d10101e PR_SERVICE_DELETE_FILES 0x3d110102 PR_AB_SEARCH_PATH_UPDATE 0x3d12001e PR_PROFILE_NAME 0x3d13001e PR_SERVICE_INSTALL_ID 0x3d210102 PR_ADMIN_SECURITY_DESCRIPTOR 0x3e00001e PR_IDENTITY_DISPLAY 0x3e010102 PR_IDENTITY_ENTRYID 0x3e020003 PR_RESOURCE_METHODS 0x3e030003 PR_RESOURCE_TYPE 0x3e040003 PR_STATUS_CODE 0x3e050102 PR_IDENTITY_SEARCH_KEY 0x3e060102 PR_OWN_STORE_ENTRYID 0x3e07001e PR_RESOURCE_PATH 0x3e08001e PR_STATUS_STRING 0x3e09000b PR_X400_DEFERRED_DELIVERY_CANCEL 0x3e0a0102 PR_HEADER_FOLDER_ENTRYID 0x3e0b0003 PR_REMOTE_PROGRESS 0x3e0c001e PR_REMOTE_PROGRESS_TEXT 0x3e0d000b PR_REMOTE_VALIDATE_OK 0x3f000003 PR_CONTROL_FLAGS 0x3f010102 PR_CONTROL_STRUCTURE 0x3f020003 PR_CONTROL_TYPE 0x3f030003 PR_DELTAX 0x3f040003 PR_DELTAY 0x3f050003 PR_XPOS 0x3f060003 PR_YPOS 0x3f070102 PR_CONTROL_ID 0x3f080003 PR_INITIAL_DETAILS_PANE 0x3f800014 PR_DID 0x3f810014 PR_SEQID 0x3f820014 PR_DRAFTID 0x3f830040 PR_CHECK_IN_TIME 0x3f84001e PR_CHECK_IN_COMMENT 0x3f850003 PR_VERSION_OP_CODE 0x3f860102 PR_VERSION_OP_DATA 0x3f870003 PR_VERSION_SEQUENCE_NUMBER 0x3f880014 PR_ATTACH_ID 0x3f8d001e PR_PKM_DOC_STATUS 0x3f8e101e PR_MV_PKM_OPERATION_REQ 0x3f8f001e PR_PKM_DOC_INTERNAL_STATE 0x3f900002 PR_VERSIONING_FLAGS 0x3f910102 PR_PKM_LAST_UNAPPROVED_VID 0x3f92101e PR_MV_PKM_VERSION_LABELS 0x3f93101e PR_MV_PKM_VERSION_STATUS 0x3f940102 PR_PKM_INTERNAL_DATA 0x3fc90102 PR_LAST_CONFLICT 0x3fca0102 PR_CONFLICT_MSG_KEY 0x3fd00102 PR_REPL_HEADER 0x3fd10102 PR_REPL_STATUS 0x3fd20102 PR_REPL_CHANGES 0x3fd30102 PR_REPL_RGM 0x3fd40102 PR_RMI 0x3fd50102 PR_INTERNAL_POST_REPLY 0x3fd60040 PR_NTSD_MODIFICATION_TIME PidTagNTSDModificationTime 0x3fd8001e PR_PREVIEW_UNREAD 0x3fd9001e PR_PREVIEW 0x3fda001e PR_ABSTRACT 0x3fdb0003 PR_DL_REPORT_FLAGS 0x3fdc0102 PR_BILATERAL_INFO 0x3fdd0003 PR_MSG_BODY_ID 0x3fde0003 PR_INTERNET_CPID PidTagInternetCodepage 0x3fdf0003 PR_AUTO_RESPONSE_SUPPRESS 0x3fe0000d PR_ACL_TABLE 0x3fe00102 PR_ACL_DATA 0x3fe1000d PR_RULES_TABLE 0x3fe10102 PR_RULES_DATA 0x3fe20003 PR_FOLDER_DESIGN_FLAGS 0x3fe3000b PR_DELEGATED_BY_RULE 0x3fe4000b PR_DESIGN_IN_PROGRESS 0x3fe5000b PR_SECURE_ORIGINATION 0x3fe6000b PR_PUBLISH_IN_ADDRESS_BOOK 0x3fe70003 PR_RESOLVE_METHOD 0x3fe8001e PR_ADDRESS_BOOK_DISPLAY_NAME 0x3fe90003 PR_EFORMS_LOCALE_ID 0x3fea000b PR_HAS_DAMS 0x3feb0003 PR_DEFERRED_SEND_NUMBER 0x3fec0003 PR_DEFERRED_SEND_UNITS 0x3fed0003 PR_EXPIRY_NUMBER 0x3fee0003 PR_EXPIRY_UNITS 0x3fef0040 PR_DEFERRED_SEND_TIME 0x3ff00102 PR_CONFLICT_ENTRYID 0x3ff10003 PR_MESSAGE_LOCALE_ID PidTagMessageLocalId 0x3ff20102 PR_RULE_TRIGGER_HISTORY 0x3ff30102 PR_MOVE_TO_STORE_ENTRYID 0x3ff40102 PR_MOVE_TO_FOLDER_ENTRYID 0x3ff50003 PR_STORAGE_QUOTA_LIMIT 0x3ff60003 PR_EXCESS_STORAGE_USED 0x3ff7001e PR_SVR_GENERATING_QUOTA_MSG 0x3ff8001e PR_CREATOR_NAME PidTagCreatorName 0x3ff90102 PR_CREATOR_ENTRYID PidTagCreatorEntryId 0x3ffa001e PR_LAST_MODIFIER_NAME 0x3ffb0102 PR_LAST_MODIFIER_ENTRYID 0x3ffc001e PR_REPLY_RECIPIENT_SMTP_PROXIES 0x3ffd0003 PR_MESSAGE_CODEPAGE PidTagMessageCodepage 0x3ffe0102 PR_EXTENDED_ACL_DATA 0x3fff000b PR_FROM_I_HAVE 0x40000003 PR_NEW_ATTACH 0x40010003 PR_START_EMBED 0x40020003 PR_END_EMBED 0x40030003 PR_START_RECIP 0x40040003 PR_END_RECIP 0x40050003 PR_END_CC_RECIP 0x40060003 PR_END_BCC_RECIP 0x40070003 PR_END_P1_RECIP 0x40090003 PR_START_TOP_FLD 0x400a0003 PR_START_SUB_FLD 0x400b0003 PR_END_FOLDER 0x400c0003 PR_START_MESSAGE 0x400d0003 PR_END_MESSAGE 0x400e0003 PR_END_ATTACH 0x400f0003 PR_EC_WARNING 0x40100003 PR_START_FAI_MSG 0x40110102 PR_NEW_FX_FOLDER 0x40120003 PR_INCR_SYNC_CHG 0x40130003 PR_INCR_SYNC_DEL 0x40140003 PR_INCR_SYNC_END 0x40150003 PR_INCR_SYNC_MSG 0x40160003 PR_FX_DEL_PROP 0x40170003 PR_IDSET_GIVEN 0x40190003 PR_SENDER_FLAGS 0x401a0003 PR_SENT_REPRESENTING_FLAGS 0x401b0003 PR_RCVD_BY_FLAGS 0x401c0003 PR_RCVD_REPRESENTING_FLAGS 0x401d0003 PR_ORIGINAL_SENDER_FLAGS 0x401e0003 PR_ORIGINAL_SENT_REPRESENTING_FLAGS 0x401f0003 PR_REPORT_FLAGS 0x40200003 PR_READ_RECEIPT_FLAGS 0x4021000b PR_SOFT_DELETES 0x402c0102 PR_MESSAGE_SUBMISSION_ID_FROM_CLIENT 0x402F0003 PR_INCR_SYNC_READ 0x4030001e PR_SENDER_SIMPLE_DISP_NAME 0x4031001e PR_SENT_REPRESENTING_SIMPLE_DISP_NAME 0x4038001e PR_CREATOR_SIMPLE_DISP_NAME 0x403a0003 PR_INCR_SYNC_STATE_BEGIN 0x403b0003 PR_INCR_SYNC_STATE_END 0x403d001e PR_ORG_ADDR_TYPE 0x403e001e PR_ORG_EMAIL_ADDR 0x40590003 PR_CREATOR_FLAGS 0x405a0003 PR_MODIFIER_FLAGS 0x405b0003 PR_ORIGINATOR_FLAGS 0x405c0003 PR_REPORT_DESTINATION_FLAGS 0x405d0003 PR_ORIGINAL_AUTHOR_FLAGS 0x40610102 PR_ORIGINATOR_SEARCH_KEY 0x40640102 PR_REPORT_DESTINATION_SEARCH_KEY 0x40650003 PR_ER_FLAG 0x40680102 PR_INTERNET_SUBJECT 0x40690102 PR_INTERNET_SENT_REPRESENTING_NAME 0x4074000B PR_INCR_SYNC_PROGRESS_MODE 0x4075000B PR_INCR_SYNC_PROGRESS_PER_MSG 0x40760003 PR_CONTENT_FILTER_SCL 0x407D0003 PR_INCR_SYNC_CHG_PARTIAL 0x59020003 PR_INET_MAIL_OVERRIDE_FORMAT 0x59090003 PR_MSG_EDITOR_FORMAT 0x5fde0003 PR_RECIPIENT_RESOURCESTATE 0x5fdf0003 PR_RECIPIENT_ORDER 0x5ff6001e PR_RECIPIENT_DISPLAY_NAME 0x5ff70102 PR_RECIPIENT_ENTRYID 0x5ffb0040 PR_RECIPIENT_TRACKSTATUS_ME 0x5ffd0003 PR_RECIPIENT_FLAGS 0x5fff0003 PR_RECIPIENT_TRACKSTATUS 0x60010003 PR_DOTSTUFF_STATE 0x61000003 PR_JUNK_INCLUDE_CONTACTS 0x61010003 PR_JUNK_THRESHOLD 0x61020003 PR_JUNK_PERMANENTLY_DELETE 0x61030003 PR_JUNK_ADD_RECIPS_TO_SSL 0x6107000B PR_JUNK_PHISHING_ENABLE_LINKS 0x65a00014 PR_RULE_SERVER_RULE_ID 0x65c20102 PR_REPLY_TEMPLATE_ID 0x65e00102 PR_SOURCE_KEY 0x65e10102 PR_PARENT_SOURCE_KEY 0x65e20102 PR_CHANGE_KEY 0x65e30102 PR_PREDECESSOR_CHANGE_LIST 0x65e40003 PR_SYNCHRONIZE_FLAGS 0x65e5000b PR_AUTO_ADD_NEW_SUBS 0x65e6000b PR_NEW_SUBS_GET_AUTO_ADD 0x65e7001e PR_MESSAGE_SITE_NAME 0x65e8000b PR_MESSAGE_PROCESSED 0x65e90003 PR_RULE_MSG_STATE 0x65ea0003 PR_RULE_MSG_USER_FLAGS 0x65eb001e PR_RULE_MSG_PROVIDER 0x65ec001e PR_RULE_MSG_NAME 0x65ed0003 PR_RULE_MSG_LEVEL 0x65ee0102 PR_RULE_MSG_PROVIDER_DATA 0x65ef0102 PR_RULE_MSG_ACTIONS 0x65f00102 PR_RULE_MSG_CONDITION 0x65f10003 PR_RULE_MSG_CONDITION_LCID 0x65f20002 PR_RULE_MSG_VERSION 0x65f30003 PR_RULE_MSG_SEQUENCE 0x65f4000b PR_PREVENT_MSG_CREATE 0x65f50040 PR_IMAP_INTERNAL_DATE 0x66000003 PR_PROFILE_VERSION 0x66010003 PR_PROFILE_CONFIG_FLAGS 0x6602001e PR_PROFILE_HOME_SERVER 0x6603001e PR_PROFILE_USER 0x66040003 PR_PROFILE_CONNECT_FLAGS 0x66050003 PR_PROFILE_TRANSPORT_FLAGS 0x66060003 PR_PROFILE_UI_STATE 0x6607001e PR_PROFILE_UNRESOLVED_NAME 0x6608001e PR_PROFILE_UNRESOLVED_SERVER 0x66090003 PR_PROFILE_OPEN_FLAGS 0x6609001e PR_PROFILE_BINDING_ORDER 0x660a0003 PR_PROFILE_TYPE 0x660b001e PR_PROFILE_MAILBOX 0x660c001e PR_PROFILE_SERVER 0x660d0003 PR_PROFILE_MAX_RESTRICT 0x660e001e PR_PROFILE_AB_FILES_PATH 0x660f001e PR_PROFILE_FAVFLD_DISPLAY_NAME 0x6610001e PR_PROFILE_OFFLINE_STORE_PATH 0x66110102 PR_PROFILE_OFFLINE_INFO 0x6612001e PR_PROFILE_HOME_SERVER_DN 0x6613101e PR_PROFILE_HOME_SERVER_ADDRS 0x6614001e PR_PROFILE_SERVER_DN 0x6615001e PR_PROFILE_FAVFLD_COMMENT 0x6616001e PR_PROFILE_ALLPUB_DISPLAY_NAME 0x6617001e PR_PROFILE_ALLPUB_COMMENT 0x66180003 PR_DISABLE_WINSOCK 0x6618000b PR_IN_TRANSIT 0x66190003 PR_PROFILE_AUTH_PACKAGE 0x66190102 PR_USER_ENTRYID 0x661a001e PR_USER_NAME 0x661b0102 PR_MAILBOX_OWNER_ENTRYID 0x661c001e PR_MAILBOX_OWNER_NAME 0x661d000b PR_OOF_STATE 0x661e0102 PR_SCHEDULE_FOLDER_ENTRYID 0x661f0102 PR_IPM_DAF_ENTRYID 0x66200102 PR_NON_IPM_SUBTREE_ENTRYID 0x66210102 PR_EFORMS_REGISTRY_ENTRYID 0x66220102 PR_SPLUS_FREE_BUSY_ENTRYID 0x6623001e PR_HIERARCHY_SERVER 0x66230102 PR_OFFLINE_ADDRBOOK_ENTRYID 0x66240102 PR_EFORMS_FOR_LOCALE_ENTRYID 0x66250102 PR_FREE_BUSY_FOR_LOCAL_SITE_ENTRYID 0x66260102 PR_ADDRBOOK_FOR_LOCAL_SITE_ENTRYID 0x66270102 PR_OFFLINE_MESSAGE_ENTRYID 0x66280102 PR_GW_MTSIN_ENTRYID 0x66290102 PR_GW_MTSOUT_ENTRYID 0x662a000b PR_TRANSFER_ENABLED 0x662b0102 PR_TEST_LINE_SPEED 0x662c000d PR_HIERARCHY_SYNCHRONIZER 0x662d000d PR_CONTENTS_SYNCHRONIZER 0x662e000d PR_COLLECTOR 0x662f000d PR_FAST_TRANSFER 0x66300102 PR_IPM_FAVORITES_ENTRYID 0x66310102 PR_IPM_PUBLIC_FOLDERS_ENTRYID 0x6632000b PR_STORE_OFFLINE 0x6634000d PR_CHANGE_ADVISOR 0x6635001e PR_FAVORITES_DEFAULT_NAME 0x66360102 PR_SYS_CONFIG_FOLDER_ENTRYID 0x66370048 PR_CHANGE_NOTIFICATION_GUID 0x66380003 PR_FOLDER_CHILD_COUNT PidTagFolderChildCount 0x66390003 PR_RIGHTS PidTagRights 0x663a000b PR_HAS_RULES 0x663b0102 PR_ADDRESS_BOOK_ENTRYID 0x663c0102 PR_PUBLIC_FOLDER_ENTRYID 0x663d0003 PR_OFFLINE_FLAGS 0x663e0003 PR_HIERARCHY_CHANGE_NUM 0x663f000b PR_HAS_MODERATOR_RULES 0x66400003 PR_DELETED_MSG_COUNT 0x66410003 PR_DELETED_FOLDER_COUNT 0x66420040 PR_OLDEST_DELETED_ON 0x66430003 PR_DELETED_ASSOC_MSG_COUNT 0x6644001e PR_REPLICA_SERVER 0x66450102 PR_CLIENT_ACTIONS 0x66460102 PR_DAM_ORIGINAL_ENTRYID 0x6647000b PR_DAM_BACK_PATCHED 0x66480003 PR_RULE_ERROR 0x66490003 PR_RULE_ACTION_TYPE 0x664a000b PR_HAS_NAMED_PROPERTIES PidTagHasNamedProperties 0x664b0014 PR_REPLICA_VERSION 0x66500003 PR_RULE_ACTION_NUMBER 0x66510102 PR_RULE_FOLDER_ENTRYID 0x66520102 PR_ACTIVE_USER_ENTRYID 0x66530003 PR_0X400_ENVELOPE_TYPE 0x66540040 PR_MSG_FOLD_TIME 0x66550102 PR_ICS_CHANGE_KEY 0x66580003 PR_GW_ADMIN_OPERATIONS 0x66590102 PR_INTERNET_CONTENT 0x665a000b PR_HAS_ATTACH_FROM_IMAIL 0x665b001e PR_ORIGINATOR_NAME 0x665c001e PR_ORIGINATOR_ADDR 0x665d001e PR_ORIGINATOR_ADDRTYPE 0x665e0102 PR_ORIGINATOR_ENTRYID 0x665f0040 PR_ARRIVAL_TIME 0x66600102 PR_TRACE_INFO 0x66610102 PR_SUBJECT_TRACE_INFO 0x66620003 PR_RECIPIENT_NUMBER 0x66630102 PR_MTS_SUBJECT_ID 0x6664001e PR_REPORT_DESTINATION_NAME 0x66650102 PR_REPORT_DESTINATION_ENTRYID 0x66660102 PR_CONTENT_SEARCH_KEY 0x66670102 PR_FOREIGN_ID 0x66680102 PR_FOREIGN_REPORT_ID 0x66690102 PR_FOREIGN_SUBJECT_ID 0x666a0003 PR_PROHIBIT_RECEIVE_QUOTA 0x666c000b PR_IN_CONFLICT 0x666d0003 PR_MAX_SUBMIT_MESSAGE_SIZE 0x666e0003 PR_PROHIBIT_SEND_QUOTA 0x66700102 PR_LONGTERM_ENTRYID_FROM_TABLE 0x66710014 PR_MEMBER_ID 0x6672001e PR_MEMBER_NAME 0x66720102 PR_SHORTTERM_ENTRYID_FROM_OBJECT 0x66730003 PR_MEMBER_RIGHTS 0x66740014 PR_RULE_ID 0x66750102 PR_RULE_IDS 0x66760003 PR_RULE_SEQUENCE 0x66770003 PR_RULE_STATE 0x66780003 PR_RULE_USER_FLAGS 0x667900fd PR_RULE_CONDITION 0x667b001e PR_PROFILE_MOAB 0x667c001e PR_PROFILE_MOAB_GUID 0x667d0003 PR_PROFILE_MOAB_SEQ 0x667f1102 PR_IMPLIED_RESTRICTIONS 0x668000fe PR_RULE_ACTIONS 0x6681001e PR_RULE_PROVIDER 0x6682001e PR_RULE_NAME 0x66830003 PR_RULE_LEVEL 0x66840102 PR_RULE_PROVIDER_DATA 0x66850040 PR_LAST_FULL_BACKUP 0x66870102 PR_PROFILE_ADDR_INFO 0x66890102 PR_PROFILE_OPTIONS_DATA 0x668a0102 PR_EVENTS_ROOT_FOLDER_ENTRYID 0x668d001e PR_INBOUND_NEWSFEED_DN 0x668e001e PR_OUTBOUND_NEWSFEED_DN 0x668f0040 PR_DELETED_ON 0x66900003 PR_REPLICATION_STYLE 0x66910102 PR_REPLICATION_SCHEDULE 0x66920003 PR_REPLICATION_MESSAGE_PRIORITY 0x66930003 PR_OVERALL_MSG_AGE_LIMIT 0x66940003 PR_REPLICATION_ALWAYS_INTERVAL 0x66950003 PR_REPLICATION_MSG_SIZE 0x6696000b PR_IS_NEWSGROUP_ANCHOR 0x6697000b PR_IS_NEWSGROUP 0x66980102 PR_REPLICA_LIST 0x66990003 PR_OVERALL_AGE_LIMIT 0x669a001e PR_INTERNET_CHARSET 0x669b0014 PR_DELETED_MESSAGE_SIZE_EXTENDED 0x669c0014 PR_DELETED_NORMAL_MESSAGE_SIZE_EXTENDED 0x669d0014 PR_DELETED_ASSOC_MESSAGE_SIZE_EXTENDED 0x669e000b PR_SECURE_IN_SITE 0x66a0001e PR_NT_USER_NAME 0x66a10003 PR_LOCALE_ID PidTagLocaleId 0x66a20040 PR_LAST_LOGON_TIME 0x66a30040 PR_LAST_LOGOFF_TIME 0x66a40003 PR_STORAGE_LIMIT_INFORMATION 0x66a5001e PR_NEWSGROUP_COMPONENT 0x66a60102 PR_NEWSFEED_INFO 0x66a7001e PR_INTERNET_NEWSGROUP_NAME 0x66a80003 PR_FOLDER_FLAGS 0x66a90040 PR_LAST_ACCESS_TIME 0x66aa0003 PR_RESTRICTION_COUNT 0x66ab0003 PR_CATEG_COUNT 0x66ac0003 PR_CACHED_COLUMN_COUNT 0x66ad0003 PR_NORMAL_MSG_W_ATTACH_COUNT 0x66ae0003 PR_ASSOC_MSG_W_ATTACH_COUNT 0x66af0003 PR_RECIPIENT_ON_NORMAL_MSG_COUNT 0x66b00003 PR_RECIPIENT_ON_ASSOC_MSG_COUNT 0x66b10003 PR_ATTACH_ON_NORMAL_MSG_COUNT 0x66b20003 PR_ATTACH_ON_ASSOC_MSG_COUNT 0x66b30003 PR_NORMAL_MESSAGE_SIZE 0x66b30014 PR_NORMAL_MESSAGE_SIZE_EXTENDED 0x66b40003 PR_ASSOC_MESSAGE_SIZE 0x66b40014 PR_ASSOC_MESSAGE_SIZE_EXTENDED 0x66b5001e PR_FOLDER_PATHNAME 0x66b60003 PR_OWNER_COUNT 0x66b70003 PR_CONTACT_COUNT 0x66c30003 PR_CODE_PAGE_ID 0x66c40003 PR_RETENTION_AGE_LIMIT 0x66c5000b PR_DISABLE_PERUSER_READ 0x66c60102 PR_INTERNET_PARSE_STATE 0x66c70102 PR_INTERNET_MESSAGE_INFO 0x6700001e PR_PST_PATH 0x6701000b PR_PST_REMEMBER_PW 0x67020003 PR_OST_ENCRYPTION 0x6703001e PR_PST_PW_SZ_OLD 0x6704001e PR_PST_PW_SZ_NEW 0x67050003 PR_SORT_LOCALE_ID 0x6707001e PR_URL_NAME 0x67090040 PR_LOCAL_COMMIT_TIME PidTagLocalCommitTime 0x670a0040 PR_LOCAL_COMMIT_TIME_MAX 0x670b0003 PR_DELETED_COUNT_TOTAL 0x670c0048 PR_AUTO_RESET 0x67100003 PR_URL_COMP_NAME_HASH 0x67110003 PR_MSG_FOLDER_TEMPLATE_RES_2 0x67120003 PR_RANK 0x6713000b PR_MSG_FOLDER_TEMPLATE_RES_4 0x6714000b PR_MSG_FOLDER_TEMPLATE_RES_5 0x6715000b PR_MSG_FOLDER_TEMPLATE_RES_6 0x67160102 PR_MSG_FOLDER_TEMPLATE_RES_7 0x67170102 PR_MSG_FOLDER_TEMPLATE_RES_8 0x67180102 PR_MSG_FOLDER_TEMPLATE_RES_9 0x6719001e PR_MSG_FOLDER_TEMPLATE_RES_10 0x671a001e PR_MSG_FOLDER_TEMPLATE_RES_11 0x671b001e PR_MSG_FOLDER_TEMPLATE_RES_12 0x671e000b PR_PF_PLATINUM_HOME_MDB 0x671f000b PR_PF_PROXY_REQUIRED 0x67200102 PR_INTERNET_FREE_DOC_INFO 0x67210003 PR_PF_OVER_HARD_QUOTA_LIMIT 0x67220003 PR_PF_MSG_SIZE_LIMIT 0x674000fb PR_SENT_MAILSVR_EID PidTagSentMailSvrEID 0x67430003 PR_CONNECTION_MODULUS 0x6744001e PR_DELIVER_TO_DN 0x67460003 PR_MIME_SIZE 0x67470014 PR_FILE_SIZE_EXTENDED 0x67480014 PR_FID PidTagFolderId 0x67490014 PR_PARENT_FID PidTagParentFolderId 0x674a0014 PR_MID PidTagMessageId 0x674b0014 PR_CATEG_ID 0x674c0014 PR_PARENT_CATEG_ID 0x674d0014 PR_INST_ID PidTagInstanceId 0x674e0003 PR_INSTANCE_NUM PidTagInstanceNum 0x674f0014 PR_ADDRBOOK_MID 0x67500003 PR_ICS_NOTIF 0x67510003 PR_ARTICLE_NUM_NEXT 0x67520003 PR_IMAP_LAST_ARTICLE_ID 0x6753000b PR_NOT_822_RENDERABLE 0x67580102 PR_LTID 0x67590102 PR_CN_EXPORT 0x675a0102 PR_PCL_EXPORT 0x675b1102 PR_CN_MV_EXPORT 0x67790003 PR_PF_QUOTA_STYLE 0x677b0003 PR_PF_STORAGE_QUOTA 0x67830003 PR_SEARCH_FLAGS 0x67a40014 PR_CHANGE_NUM PidTagChangeNumber 0x67aa000b PR_ASSOCIATED 0x67f00102 PR_PROFILE_SECURE_MAILBOX 0x6800001e PR_OAB_NAME 0x68010003 PR_OAB_SEQUENCE 0x6802001e PR_OAB_CONTAINER_GUID 0x68030003 PR_OAB_MESSAGE_CLASS 0x6804001e PR_OAB_DN 0x68051003 PR_OAB_TRUNCATED_PROPS 0x68060102 PR_OAB_SHA_HASH 0x68070003 PR_OAB_LANGID 0x68080003 PR_OAB_FILETYPE 0x68090003 PR_OAB_COMPRESSED_SIZE 0x680A0003 PR_OAB_FILE_SIZE 0x68340003 PR_VIEW_STYLE 0x683A0003 PR_VIEW_MAJORVERSION 0x68410003 PR_SCHDINFO_RESOURCE_TYPE PidTagScheduleInfoResourceType 0x6842000b PR_SCHDINFO_BOSS_WANTS_COPY PidTagScheduleInfoDelegatorWantsCopy 0x6843000b PR_SCHDINFO_DONT_MAIL_DELEGATES PidTagScheduleInfoDontMailDelegates 0x6844101e PR_DELEGATES_DISPLAY_NAMES PidTagScheduleInfoDelegateNames 0x68451102 PR_DELEGATES_ENTRYIDS PidTagScheduleInfoDelegateEntryIds 0x68470003 PR_FREEBUSY_PUBLISH_START PidTagFreeBusyPublishStart 0x68480003 PR_FREEBUSY_PUBLISH_END PidTagFreeBusyPublishEnd 0x6849001e PR_FREEBUSY_EMA PidTagFreeBusyMessageEmailAddress 0x684b000b PR_SCHDINFO_BOSS_WANTS_INFO PidTagScheduleInfoDelegatorWantsInfo 0x684f1003 PR_SCHDINFO_MONTHS_MERGED PidTagScheduleInfoMonthsMerged 0x68501102 PR_SCHDINFO_FREEBUSY_MERGED PidTagScheduleInfoFreeBusyMerged 0x68511003 PR_SCHDINFO_MONTHS_TENTATIVE PidTagScheduleInfoMonthsTentative 0x68521102 PR_SCHDINFO_FREEBUSY_TENTATIVE PidTagScheduleInfoFreeBusyTentative 0x68531003 PR_SCHDINFO_MONTHS_BUSY PidTagScheduleInfoMonthsBusy 0x68541102 PR_SCHDINFO_FREEBUSY_BUSY PidTagScheduleInfoFreeBusyBusy 0x68551003 PR_SCHDINFO_MONTHS_OOF PidTagScheduleInfoMonthsAway 0x68561102 PR_SCHDINFO_FREEBUSY_OOF PidTagScheduleInfoFreeBusyAway 0x68680040 PR_FREEBUSY_RANGE_TIMESTAMP PidTagFreeBusyRangeTimestamp 0x68690003 PR_FREEBUSY_COUNT_MONTHS PidTagFreeBusyCountMonths 0x686b1003 PR_DELEGATES_SEE_PRIVATE 0x686c0102 PR_PERSONAL_FREEBUSY 0x686d000b PR_PROCESS_MEETING_REQUESTS 0x686e000b PR_DECLINE_RECURRING_MEETING_REQUESTS 0x686f000b PR_DECLINE_CONFLICTING_MEETING_REQUESTS 0x70010102 PR_VD_BINARY 0x7002001e PR_VD_STRINGS 0x70030003 PR_VD_FLAGS 0x70040102 PR_VD_LINK_TO 0x70050102 PR_VD_VIEW_FOLDER 0x7006001e PR_VD_NAME 0x70070003 PR_VD_VERSION 0x7c00001e PR_FAV_DISPLAY_NAME_A 0x7c020102 PR_FAV_PUBLIC_SOURCE_KEY 0x7c040102 PR_OST_OSTID 0x7c0a000b PR_STORE_SLOWLINK 0x7d010003 PR_FAV_AUTOSUBFOLDERS 0x7d01000b PR_PROCESSED 0x7d020102 PR_FAV_PARENT_SOURCE_KEY 0x7d030003 PR_FAV_LEVEL_MASK 0x7d070003 PR_FAV_INHERIT_AUTO 0x7d080102 PR_FAV_DEL_SUBS 0x7ffa0003 PR_ATTACHMENT_LINKID 0x7ffb0040 PR_EXCEPTION_STARTTIME 0x7ffc0040 PR_EXCEPTION_ENDTIME 0x7ffd0003 PR_ATTACHMENT_FLAGS 0x7ffe000b PR_ATTACHMENT_HIDDEN 0x7fff000b PR_ATTACHMENT_CONTACTPHOTO 0x8001000b PR_EMS_AB_DISPLAY_NAME_OVERRIDE 0x80031102 PR_EMS_AB_CA_CERTIFICATE 0x8004001e PR_EMS_AB_FOLDER_PATHNAME 0x8005000d PR_EMS_AB_MANAGER 0x8005001e PR_EMS_AB_MANAGER_T 0x8006000d PR_EMS_AB_HOME_MDB_O 0x8006001e PR_EMS_AB_HOME_MDB 0x8007000d PR_EMS_AB_HOME_MTA_O 0x8007001e PR_EMS_AB_HOME_MTA 0x8008000d PR_EMS_AB_IS_MEMBER_OF_DL 0x8008001e PR_EMS_AB_IS_MEMBER_OF_DL_T 0x8009000d PR_EMS_AB_MEMBER 0x8009001e PR_EMS_AB_MEMBER_T 0x800a001e PR_EMS_AB_AUTOREPLY_MESSAGE 0x800b000b PR_EMS_AB_AUTOREPLY 0x800c000d PR_EMS_AB_OWNER_O 0x800c001e PR_EMS_AB_OWNER 0x800d000d PR_EMS_AB_KM_SERVER_O 0x800d001e PR_EMS_AB_KM_SERVER 0x800e000d PR_EMS_AB_REPORTS 0x800f101e PR_EMS_AB_PROXY_ADDRESSES 0x80100102 PR_EMS_AB_HELP_DATA32 0x8011001e PR_EMS_AB_TARGET_ADDRESS 0x8012101e PR_EMS_AB_TELEPHONE_NUMBER 0x80130102 PR_EMS_AB_NT_SECURITY_DESCRIPTOR 0x8014000d PR_EMS_AB_HOME_MDB_BL_O 0x8014101e PR_EMS_AB_HOME_MDB_BL 0x8015000d PR_EMS_AB_PUBLIC_DELEGATES 0x8015001e PR_EMS_AB_PUBLIC_DELEGATES_T 0x80160102 PR_EMS_AB_CERTIFICATE_REVOCATION_LIST 0x80170102 PR_EMS_AB_ADDRESS_ENTRY_DISPLAY_TABLE 0x80180102 PR_EMS_AB_ADDRESS_SYNTAX 0x80230102 PR_EMS_AB_BUSINESS_ROLES 0x8024000d PR_EMS_AB_OWNER_BL_O 0x8024101e PR_EMS_AB_OWNER_BL 0x80251102 PR_EMS_AB_CROSS_CERTIFICATE_PAIR 0x80261102 PR_EMS_AB_AUTHORITY_REVOCATION_LIST 0x80270102 PR_EMS_AB_ASSOC_NT_ACCOUNT 0x80280040 PR_EMS_AB_EXPIRATION_TIME 0x80290003 PR_EMS_AB_USN_CHANGED 0x802d001e PR_EMS_AB_EXTENSION_ATTRIBUTE_1 0x802e001e PR_EMS_AB_EXTENSION_ATTRIBUTE_2 0x802f001e PR_EMS_AB_EXTENSION_ATTRIBUTE_3 0x8030001e PR_EMS_AB_EXTENSION_ATTRIBUTE_4 0x8031001e PR_EMS_AB_EXTENSION_ATTRIBUTE_5 0x8032001e PR_EMS_AB_EXTENSION_ATTRIBUTE_6 0x8033001e PR_EMS_AB_EXTENSION_ATTRIBUTE_7 0x8034001e PR_EMS_AB_EXTENSION_ATTRIBUTE_8 0x8035001e PR_EMS_AB_EXTENSION_ATTRIBUTE_9 0x8036001e PR_EMS_AB_EXTENSION_ATTRIBUTE_10 0x80371102 PR_EMS_AB_SECURITY_PROTOCOL 0x8038000d PR_EMS_AB_PF_CONTACTS_O 0x8038101e PR_EMS_AB_PF_CONTACTS 0x803a0102 PR_EMS_AB_HELP_DATA16 0x803b001e PR_EMS_AB_HELP_FILE_NAME 0x803c000d PR_EMS_AB_OBJ_DIST_NAME_O 0x803c001e PR_EMS_AB_OBJ_DIST_NAME 0x803d001e PR_EMS_AB_ENCRYPT_ALG_SELECTED_OTHER 0x803e001e PR_EMS_AB_AUTOREPLY_SUBJECT 0x803f000d PR_EMS_AB_HOME_PUBLIC_SERVER_O 0x803f001e PR_EMS_AB_HOME_PUBLIC_SERVER 0x8040101e PR_EMS_AB_ENCRYPT_ALG_LIST_NA 0x8041101e PR_EMS_AB_ENCRYPT_ALG_LIST_OTHER 0x8042001e PR_EMS_AB_IMPORTED_FROM 0x8043001e PR_EMS_AB_ENCRYPT_ALG_SELECTED_NA 0x80440003 PR_EMS_AB_ACCESS_CATEGORY 0x80450102 PR_EMS_AB_ACTIVATION_SCHEDULE 0x80460003 PR_EMS_AB_ACTIVATION_STYLE 0x80470102 PR_EMS_AB_ADDRESS_ENTRY_DISPLAY_TABLE_MSDOS 0x8048001e PR_EMS_AB_ADDRESS_TYPE 0x8049001e PR_EMS_AB_ADMD 0x804a001e PR_EMS_AB_ADMIN_DESCRIPTION 0x804b001e PR_EMS_AB_ADMIN_DISPLAY_NAME 0x804c001e PR_EMS_AB_ADMIN_EXTENSION_DLL 0x804d000d PR_EMS_AB_ALIASED_OBJECT_NAME_O 0x804d001e PR_EMS_AB_ALIASED_OBJECT_NAME 0x804e000d PR_EMS_AB_ALT_RECIPIENT_O 0x804e001e PR_EMS_AB_ALT_RECIPIENT 0x804f000d PR_EMS_AB_ALT_RECIPIENT_BL_O 0x804f101e PR_EMS_AB_ALT_RECIPIENT_BL 0x80500102 PR_EMS_AB_ANCESTOR_ID 0x8051000d PR_EMS_AB_ASSOC_REMOTE_DXA_O 0x8051101e PR_EMS_AB_ASSOC_REMOTE_DXA 0x80520003 PR_EMS_AB_ASSOCIATION_LIFETIME 0x8053000d PR_EMS_AB_AUTH_ORIG_BL_O 0x8053101e PR_EMS_AB_AUTH_ORIG_BL 0x8054001e PR_EMS_AB_AUTHORIZED_DOMAIN 0x80550102 PR_EMS_AB_AUTHORIZED_PASSWORD 0x8056001e PR_EMS_AB_AUTHORIZED_USER 0x8057101e PR_EMS_AB_BUSINESS_CATEGORY 0x8058000d PR_EMS_AB_CAN_CREATE_PF_O 0x8058101e PR_EMS_AB_CAN_CREATE_PF 0x8059000d PR_EMS_AB_CAN_CREATE_PF_BL_O 0x8059101e PR_EMS_AB_CAN_CREATE_PF_BL 0x805a000d PR_EMS_AB_CAN_CREATE_PF_DL_O 0x805a101e PR_EMS_AB_CAN_CREATE_PF_DL 0x805b000d PR_EMS_AB_CAN_CREATE_PF_DL_BL_O 0x805b101e PR_EMS_AB_CAN_CREATE_PF_DL_BL 0x805c000d PR_EMS_AB_CAN_NOT_CREATE_PF_O 0x805c101e PR_EMS_AB_CAN_NOT_CREATE_PF 0x805d000d PR_EMS_AB_CAN_NOT_CREATE_PF_BL_O 0x805d101e PR_EMS_AB_CAN_NOT_CREATE_PF_BL 0x805e000d PR_EMS_AB_CAN_NOT_CREATE_PF_DL_O 0x805e101e PR_EMS_AB_CAN_NOT_CREATE_PF_DL 0x805f000d PR_EMS_AB_CAN_NOT_CREATE_PF_DL_BL_O 0x805f101e PR_EMS_AB_CAN_NOT_CREATE_PF_DL_BL 0x8060000b PR_EMS_AB_CAN_PRESERVE_DNS 0x80610003 PR_EMS_AB_CLOCK_ALERT_OFFSET 0x8062000b PR_EMS_AB_CLOCK_ALERT_REPAIR 0x80630003 PR_EMS_AB_CLOCK_WARNING_OFFSET 0x8064000b PR_EMS_AB_CLOCK_WARNING_REPAIR 0x8065001e PR_EMS_AB_COMPUTER_NAME 0x8066101e PR_EMS_AB_CONNECTED_DOMAINS 0x80670003 PR_EMS_AB_CONTAINER_INFO 0x80680003 PR_EMS_AB_COST 0x8069001e PR_EMS_AB_COUNTRY_NAME 0x806a0003 PR_EMS_AB_DELIV_CONT_LENGTH 0x806b1102 PR_EMS_AB_DELIV_EITS 0x806c1102 PR_EMS_AB_DELIV_EXT_CONT_TYPES 0x806d000b PR_EMS_AB_DELIVER_AND_REDIRECT 0x806e0003 PR_EMS_AB_DELIVERY_MECHANISM 0x806f101e PR_EMS_AB_DESCRIPTION 0x8070101e PR_EMS_AB_DESTINATION_INDICATOR 0x8071001e PR_EMS_AB_DIAGNOSTIC_REG_KEY 0x8072000d PR_EMS_AB_DL_MEM_REJECT_PERMS_BL_O 0x8072101e PR_EMS_AB_DL_MEM_REJECT_PERMS_BL 0x8073000d PR_EMS_AB_DL_MEM_SUBMIT_PERMS_BL_O 0x8073101e PR_EMS_AB_DL_MEM_SUBMIT_PERMS_BL 0x80741102 PR_EMS_AB_DL_MEMBER_RULE 0x8075000d PR_EMS_AB_DOMAIN_DEF_ALT_RECIP_O 0x8075001e PR_EMS_AB_DOMAIN_DEF_ALT_RECIP 0x8076001e PR_EMS_AB_DOMAIN_NAME 0x80770102 PR_EMS_AB_DSA_SIGNATURE 0x8078000b PR_EMS_AB_DXA_ADMIN_COPY 0x8079000b PR_EMS_AB_DXA_ADMIN_FORWARD 0x807a0003 PR_EMS_AB_DXA_ADMIN_UPDATE 0x807b000b PR_EMS_AB_DXA_APPEND_REQCN 0x807c000d PR_EMS_AB_DXA_CONF_CONTAINER_LIST_O 0x807c101e PR_EMS_AB_DXA_CONF_CONTAINER_LIST 0x807d0040 PR_EMS_AB_DXA_CONF_REQ_TIME 0x807e001e PR_EMS_AB_DXA_CONF_SEQ 0x807f0003 PR_EMS_AB_DXA_CONF_SEQ_USN 0x80800003 PR_EMS_AB_DXA_EXCHANGE_OPTIONS 0x8081000b PR_EMS_AB_DXA_EXPORT_NOW 0x80820003 PR_EMS_AB_DXA_FLAGS 0x8083001e PR_EMS_AB_DXA_IMP_SEQ 0x80840040 PR_EMS_AB_DXA_IMP_SEQ_TIME 0x80850003 PR_EMS_AB_DXA_IMP_SEQ_USN 0x8086000b PR_EMS_AB_DXA_IMPORT_NOW 0x8087101e PR_EMS_AB_DXA_IN_TEMPLATE_MAP 0x8088000d PR_EMS_AB_DXA_LOCAL_ADMIN_O 0x8088001e PR_EMS_AB_DXA_LOCAL_ADMIN 0x80890003 PR_EMS_AB_DXA_LOGGING_LEVEL 0x808a001e PR_EMS_AB_DXA_NATIVE_ADDRESS_TYPE 0x808b101e PR_EMS_AB_DXA_OUT_TEMPLATE_MAP 0x808c001e PR_EMS_AB_DXA_PASSWORD 0x808d0003 PR_EMS_AB_DXA_PREV_EXCHANGE_OPTIONS 0x808e000b PR_EMS_AB_DXA_PREV_EXPORT_NATIVE_ONLY 0x808f0003 PR_EMS_AB_DXA_PREV_IN_EXCHANGE_SENSITIVITY 0x8090000d PR_EMS_AB_DXA_PREV_REMOTE_ENTRIES_O 0x8090001e PR_EMS_AB_DXA_PREV_REMOTE_ENTRIES 0x80910003 PR_EMS_AB_DXA_PREV_REPLICATION_SENSITIVITY 0x80920003 PR_EMS_AB_DXA_PREV_TEMPLATE_OPTIONS 0x80930003 PR_EMS_AB_DXA_PREV_TYPES 0x8094001e PR_EMS_AB_DXA_RECIPIENT_CP 0x8095000d PR_EMS_AB_DXA_REMOTE_CLIENT_O 0x8095001e PR_EMS_AB_DXA_REMOTE_CLIENT 0x8096001e PR_EMS_AB_DXA_REQ_SEQ 0x80970040 PR_EMS_AB_DXA_REQ_SEQ_TIME 0x80980003 PR_EMS_AB_DXA_REQ_SEQ_USN 0x8099001e PR_EMS_AB_DXA_REQNAME 0x809a001e PR_EMS_AB_DXA_SVR_SEQ 0x809b0040 PR_EMS_AB_DXA_SVR_SEQ_TIME 0x809c0003 PR_EMS_AB_DXA_SVR_SEQ_USN 0x809d0003 PR_EMS_AB_DXA_TASK 0x809e0003 PR_EMS_AB_DXA_TEMPLATE_OPTIONS 0x809f0040 PR_EMS_AB_DXA_TEMPLATE_TIMESTAMP 0x80a00003 PR_EMS_AB_DXA_TYPES 0x80a1000d PR_EMS_AB_DXA_UNCONF_CONTAINER_LIST_O 0x80a1101e PR_EMS_AB_DXA_UNCONF_CONTAINER_LIST 0x80a20003 PR_EMS_AB_ENCAPSULATION_METHOD 0x80a3000b PR_EMS_AB_ENCRYPT 0x80a4000b PR_EMS_AB_EXPAND_DLS_LOCALLY 0x80a5000d PR_EMS_AB_EXPORT_CONTAINERS_O 0x80a5101e PR_EMS_AB_EXPORT_CONTAINERS 0x80a6000b PR_EMS_AB_EXPORT_CUSTOM_RECIPIENTS 0x80a7000b PR_EMS_AB_EXTENDED_CHARS_ALLOWED 0x80a81102 PR_EMS_AB_EXTENSION_DATA 0x80a9101e PR_EMS_AB_EXTENSION_NAME 0x80aa101e PR_EMS_AB_EXTENSION_NAME_INHERITED 0x80ab1102 PR_EMS_AB_FACSIMILE_TELEPHONE_NUMBER 0x80ac0102 PR_EMS_AB_FILE_VERSION 0x80ad000b PR_EMS_AB_FILTER_LOCAL_ADDRESSES 0x80ae000d PR_EMS_AB_FOLDERS_CONTAINER_O 0x80ae001e PR_EMS_AB_FOLDERS_CONTAINER 0x80af0003 PR_EMS_AB_GARBAGE_COLL_PERIOD 0x80b0001e PR_EMS_AB_GATEWAY_LOCAL_CRED 0x80b1001e PR_EMS_AB_GATEWAY_LOCAL_DESIG 0x80b2101e PR_EMS_AB_GATEWAY_PROXY 0x80b30102 PR_EMS_AB_GATEWAY_ROUTING_TREE 0x80b40040 PR_EMS_AB_GWART_LAST_MODIFIED 0x80b5000d PR_EMS_AB_HAS_FULL_REPLICA_NCS_O 0x80b5101e PR_EMS_AB_HAS_FULL_REPLICA_NCS 0x80b6000d PR_EMS_AB_HAS_MASTER_NCS_O 0x80b6101e PR_EMS_AB_HAS_MASTER_NCS 0x80b70003 PR_EMS_AB_HEURISTICS 0x80b8000b PR_EMS_AB_HIDE_DL_MEMBERSHIP 0x80b9000b PR_EMS_AB_HIDE_FROM_ADDRESS_BOOK 0x80ba000d PR_EMS_AB_IMPORT_CONTAINER_O 0x80ba001e PR_EMS_AB_IMPORT_CONTAINER 0x80bb0003 PR_EMS_AB_IMPORT_SENSITIVITY 0x80bc000d PR_EMS_AB_INBOUND_SITES_O 0x80bc101e PR_EMS_AB_INBOUND_SITES 0x80bd0003 PR_EMS_AB_INSTANCE_TYPE 0x80be101e PR_EMS_AB_INTERNATIONAL_ISDN_NUMBER 0x80bf0102 PR_EMS_AB_INVOCATION_ID 0x80c0000b PR_EMS_AB_IS_DELETED 0x80c1000b PR_EMS_AB_IS_SINGLE_VALUED 0x80c21102 PR_EMS_AB_KCC_STATUS 0x80c3101e PR_EMS_AB_KNOWLEDGE_INFORMATION 0x80c40003 PR_EMS_AB_LINE_WRAP 0x80c50003 PR_EMS_AB_LINK_ID 0x80c6001e PR_EMS_AB_LOCAL_BRIDGE_HEAD 0x80c7001e PR_EMS_AB_LOCAL_BRIDGE_HEAD_ADDRESS 0x80c8000b PR_EMS_AB_LOCAL_INITIAL_TURN 0x80c9000d PR_EMS_AB_LOCAL_SCOPE_O 0x80c9101e PR_EMS_AB_LOCAL_SCOPE 0x80ca001e PR_EMS_AB_LOG_FILENAME 0x80cb0003 PR_EMS_AB_LOG_ROLLOVER_INTERVAL 0x80cc000b PR_EMS_AB_MAINTAIN_AUTOREPLY_HISTORY 0x80cd0003 PR_EMS_AB_MAPI_DISPLAY_TYPE 0x80ce0003 PR_EMS_AB_MAPI_ID 0x80cf0003 PR_EMS_AB_MDB_BACKOFF_INTERVAL 0x80d00003 PR_EMS_AB_MDB_MSG_TIME_OUT_PERIOD 0x80d10003 PR_EMS_AB_MDB_OVER_QUOTA_LIMIT 0x80d20003 PR_EMS_AB_MDB_STORAGE_QUOTA 0x80d30003 PR_EMS_AB_MDB_UNREAD_LIMIT 0x80d4000b PR_EMS_AB_MDB_USE_DEFAULTS 0x80d5000b PR_EMS_AB_MESSAGE_TRACKING_ENABLED 0x80d6000b PR_EMS_AB_MONITOR_CLOCK 0x80d7000b PR_EMS_AB_MONITOR_SERVERS 0x80d8000b PR_EMS_AB_MONITOR_SERVICES 0x80d9000d PR_EMS_AB_MONITORED_CONFIGURATIONS_O 0x80d9101e PR_EMS_AB_MONITORED_CONFIGURATIONS 0x80da000d PR_EMS_AB_MONITORED_SERVERS_O 0x80da101e PR_EMS_AB_MONITORED_SERVERS 0x80db101e PR_EMS_AB_MONITORED_SERVICES 0x80dc0003 PR_EMS_AB_MONITORING_ALERT_DELAY 0x80dd0003 PR_EMS_AB_MONITORING_ALERT_UNITS 0x80de0003 PR_EMS_AB_MONITORING_AVAILABILITY_STYLE 0x80df0102 PR_EMS_AB_MONITORING_AVAILABILITY_WINDOW 0x80e0000d PR_EMS_AB_MONITORING_CACHED_VIA_MAIL_O 0x80e0101e PR_EMS_AB_MONITORING_CACHED_VIA_MAIL 0x80e1000d PR_EMS_AB_MONITORING_CACHED_VIA_RPC_O 0x80e1101e PR_EMS_AB_MONITORING_CACHED_VIA_RPC 0x80e21102 PR_EMS_AB_MONITORING_ESCALATION_PROCEDURE 0x80e30003 PR_EMS_AB_MONITORING_HOTSITE_POLL_INTERVAL 0x80e40003 PR_EMS_AB_MONITORING_HOTSITE_POLL_UNITS 0x80e50003 PR_EMS_AB_MONITORING_MAIL_UPDATE_INTERVAL 0x80e60003 PR_EMS_AB_MONITORING_MAIL_UPDATE_UNITS 0x80e70003 PR_EMS_AB_MONITORING_NORMAL_POLL_INTERVAL 0x80e80003 PR_EMS_AB_MONITORING_NORMAL_POLL_UNITS 0x80e9000d PR_EMS_AB_MONITORING_RECIPIENTS_O 0x80e9101e PR_EMS_AB_MONITORING_RECIPIENTS 0x80ea000d PR_EMS_AB_MONITORING_RECIPIENTS_NDR_O 0x80ea101e PR_EMS_AB_MONITORING_RECIPIENTS_NDR 0x80eb0003 PR_EMS_AB_MONITORING_RPC_UPDATE_INTERVAL 0x80ec0003 PR_EMS_AB_MONITORING_RPC_UPDATE_UNITS 0x80ed0003 PR_EMS_AB_MONITORING_WARNING_DELAY 0x80ee0003 PR_EMS_AB_MONITORING_WARNING_UNITS 0x80ef001e PR_EMS_AB_MTA_LOCAL_CRED 0x80f0001e PR_EMS_AB_MTA_LOCAL_DESIG 0x80f10102 PR_EMS_AB_N_ADDRESS 0x80f20003 PR_EMS_AB_N_ADDRESS_TYPE 0x80f3001e PR_EMS_AB_NT_MACHINE_NAME 0x80f40003 PR_EMS_AB_NUM_OF_OPEN_RETRIES 0x80f50003 PR_EMS_AB_NUM_OF_TRANSFER_RETRIES 0x80f60003 PR_EMS_AB_OBJECT_CLASS_CATEGORY 0x80f70003 PR_EMS_AB_OBJECT_VERSION 0x80f8000d PR_EMS_AB_OFF_LINE_AB_CONTAINERS_O 0x80f8101e PR_EMS_AB_OFF_LINE_AB_CONTAINERS 0x80f90102 PR_EMS_AB_OFF_LINE_AB_SCHEDULE 0x80fa000d PR_EMS_AB_OFF_LINE_AB_SERVER_O 0x80fa001e PR_EMS_AB_OFF_LINE_AB_SERVER 0x80fb0003 PR_EMS_AB_OFF_LINE_AB_STYLE 0x80fc0003 PR_EMS_AB_OID_TYPE 0x80fd0102 PR_EMS_AB_OM_OBJECT_CLASS 0x80fe0003 PR_EMS_AB_OM_SYNTAX 0x80ff000b PR_EMS_AB_OOF_REPLY_TO_ORIGINATOR 0x81000003 PR_EMS_AB_OPEN_RETRY_INTERVAL 0x8101101e PR_EMS_AB_ORGANIZATION_NAME 0x8102101e PR_EMS_AB_ORGANIZATIONAL_UNIT_NAME 0x81030102 PR_EMS_AB_ORIGINAL_DISPLAY_TABLE 0x81040102 PR_EMS_AB_ORIGINAL_DISPLAY_TABLE_MSDOS 0x8105000d PR_EMS_AB_OUTBOUND_SITES_O 0x8105101e PR_EMS_AB_OUTBOUND_SITES 0x81060102 PR_EMS_AB_P_SELECTOR 0x81070102 PR_EMS_AB_P_SELECTOR_INBOUND 0x81080102 PR_EMS_AB_PER_MSG_DIALOG_DISPLAY_TABLE 0x81090102 PR_EMS_AB_PER_RECIP_DIALOG_DISPLAY_TABLE 0x810a0102 PR_EMS_AB_PERIOD_REP_SYNC_TIMES 0x810b0003 PR_EMS_AB_PERIOD_REPL_STAGGER 0x810c1102 PR_EMS_AB_POSTAL_ADDRESS 0x810d1003 PR_EMS_AB_PREFERRED_DELIVERY_METHOD 0x810e001e PR_EMS_AB_PRMD 0x810f001e PR_EMS_AB_PROXY_GENERATOR_DLL 0x8110000d PR_EMS_AB_PUBLIC_DELEGATES_BL_O 0x8110101e PR_EMS_AB_PUBLIC_DELEGATES_BL 0x81110102 PR_EMS_AB_QUOTA_NOTIFICATION_SCHEDULE 0x81120003 PR_EMS_AB_QUOTA_NOTIFICATION_STYLE 0x81130003 PR_EMS_AB_RANGE_LOWER 0x81140003 PR_EMS_AB_RANGE_UPPER 0x8115001e PR_EMS_AB_RAS_CALLBACK_NUMBER 0x8116001e PR_EMS_AB_RAS_PHONE_NUMBER 0x8117001e PR_EMS_AB_RAS_PHONEBOOK_ENTRY_NAME 0x8118001e PR_EMS_AB_RAS_REMOTE_SRVR_NAME 0x81191102 PR_EMS_AB_REGISTERED_ADDRESS 0x811a001e PR_EMS_AB_REMOTE_BRIDGE_HEAD 0x811b001e PR_EMS_AB_REMOTE_BRIDGE_HEAD_ADDRESS 0x811c000d PR_EMS_AB_REMOTE_OUT_BH_SERVER_O 0x811c001e PR_EMS_AB_REMOTE_OUT_BH_SERVER 0x811d000d PR_EMS_AB_REMOTE_SITE_O 0x811d001e PR_EMS_AB_REMOTE_SITE 0x811e0003 PR_EMS_AB_REPLICATION_SENSITIVITY 0x811f0003 PR_EMS_AB_REPLICATION_STAGGER 0x8120000b PR_EMS_AB_REPORT_TO_ORIGINATOR 0x8121000b PR_EMS_AB_REPORT_TO_OWNER 0x81220003 PR_EMS_AB_REQ_SEQ 0x8123000d PR_EMS_AB_RESPONSIBLE_LOCAL_DXA_O 0x8123001e PR_EMS_AB_RESPONSIBLE_LOCAL_DXA 0x8124000d PR_EMS_AB_RID_SERVER_O 0x8124001e PR_EMS_AB_RID_SERVER 0x8125000d PR_EMS_AB_ROLE_OCCUPANT_O 0x8125101e PR_EMS_AB_ROLE_OCCUPANT 0x8126101e PR_EMS_AB_ROUTING_LIST 0x81270003 PR_EMS_AB_RTS_CHECKPOINT_SIZE 0x81280003 PR_EMS_AB_RTS_RECOVERY_TIMEOUT 0x81290003 PR_EMS_AB_RTS_WINDOW_SIZE 0x812a000d PR_EMS_AB_RUNS_ON_O 0x812a101e PR_EMS_AB_RUNS_ON 0x812b0102 PR_EMS_AB_S_SELECTOR 0x812c0102 PR_EMS_AB_S_SELECTOR_INBOUND 0x812d0003 PR_EMS_AB_SEARCH_FLAGS 0x812e1102 PR_EMS_AB_SEARCH_GUIDE 0x812f000d PR_EMS_AB_SEE_ALSO_O 0x812f101e PR_EMS_AB_SEE_ALSO 0x8130101e PR_EMS_AB_SERIAL_NUMBER 0x81310003 PR_EMS_AB_SERVICE_ACTION_FIRST 0x81320003 PR_EMS_AB_SERVICE_ACTION_OTHER 0x81330003 PR_EMS_AB_SERVICE_ACTION_SECOND 0x81340003 PR_EMS_AB_SERVICE_RESTART_DELAY 0x8135001e PR_EMS_AB_SERVICE_RESTART_MESSAGE 0x81360003 PR_EMS_AB_SESSION_DISCONNECT_TIMER 0x8137101e PR_EMS_AB_SITE_AFFINITY 0x8138101e PR_EMS_AB_SITE_PROXY_SPACE 0x81390040 PR_EMS_AB_SPACE_LAST_COMPUTED 0x813a001e PR_EMS_AB_STREET_ADDRESS 0x813b000d PR_EMS_AB_SUB_REFS_O 0x813b101e PR_EMS_AB_SUB_REFS 0x813c0003 PR_EMS_AB_SUBMISSION_CONT_LENGTH 0x813d1102 PR_EMS_AB_SUPPORTED_APPLICATION_CONTEXT 0x813e000d PR_EMS_AB_SUPPORTING_STACK_O 0x813e101e PR_EMS_AB_SUPPORTING_STACK 0x813f000d PR_EMS_AB_SUPPORTING_STACK_BL_O 0x813f101e PR_EMS_AB_SUPPORTING_STACK_BL 0x81400102 PR_EMS_AB_T_SELECTOR 0x81410102 PR_EMS_AB_T_SELECTOR_INBOUND 0x8142101e PR_EMS_AB_TARGET_MTAS 0x81431102 PR_EMS_AB_TELETEX_TERMINAL_IDENTIFIER 0x81440003 PR_EMS_AB_TEMP_ASSOC_THRESHOLD 0x81450003 PR_EMS_AB_TOMBSTONE_LIFETIME 0x8146001e PR_EMS_AB_TRACKING_LOG_PATH_NAME 0x81470003 PR_EMS_AB_TRANS_RETRY_MINS 0x81480003 PR_EMS_AB_TRANS_TIMEOUT_MINS 0x81490003 PR_EMS_AB_TRANSFER_RETRY_INTERVAL 0x814a0003 PR_EMS_AB_TRANSFER_TIMEOUT_NON_URGENT 0x814b0003 PR_EMS_AB_TRANSFER_TIMEOUT_NORMAL 0x814c0003 PR_EMS_AB_TRANSFER_TIMEOUT_URGENT 0x814d0003 PR_EMS_AB_TRANSLATION_TABLE_USED 0x814e000b PR_EMS_AB_TRANSPORT_EXPEDITED_DATA 0x814f0003 PR_EMS_AB_TRUST_LEVEL 0x81500003 PR_EMS_AB_TURN_REQUEST_THRESHOLD 0x8151000b PR_EMS_AB_TWO_WAY_ALTERNATE_FACILITY 0x8152000d PR_EMS_AB_UNAUTH_ORIG_BL_O 0x8152101e PR_EMS_AB_UNAUTH_ORIG_BL 0x81531102 PR_EMS_AB_USER_PASSWORD 0x81540003 PR_EMS_AB_USN_CREATED 0x81550003 PR_EMS_AB_USN_DSA_LAST_OBJ_REMOVED 0x81560003 PR_EMS_AB_USN_LAST_OBJ_REM 0x81570003 PR_EMS_AB_USN_SOURCE 0x8158101e PR_EMS_AB_X121_ADDRESS 0x81590102 PR_EMS_AB_X25_CALL_USER_DATA_INCOMING 0x815a0102 PR_EMS_AB_X25_CALL_USER_DATA_OUTGOING 0x815b0102 PR_EMS_AB_X25_FACILITIES_DATA_INCOMING 0x815c0102 PR_EMS_AB_X25_FACILITIES_DATA_OUTGOING 0x815d0102 PR_EMS_AB_X25_LEASED_LINE_PORT 0x815e000b PR_EMS_AB_X25_LEASED_OR_SWITCHED 0x815f001e PR_EMS_AB_X25_REMOTE_MTA_PHONE 0x81600102 PR_EMS_AB_X400_ATTACHMENT_TYPE 0x81610003 PR_EMS_AB_X400_SELECTOR_SYNTAX 0x81620102 PR_EMS_AB_X500_ACCESS_CONTROL_LIST 0x81630003 PR_EMS_AB_XMIT_TIMEOUT_NON_URGENT 0x81640003 PR_EMS_AB_XMIT_TIMEOUT_NORMAL 0x81650003 PR_EMS_AB_XMIT_TIMEOUT_URGENT 0x81660102 PR_EMS_AB_SITE_FOLDER_GUID 0x8167000d PR_EMS_AB_SITE_FOLDER_SERVER_O 0x8167001e PR_EMS_AB_SITE_FOLDER_SERVER 0x81680003 PR_EMS_AB_REPLICATION_MAIL_MSG_SIZE 0x81690102 PR_EMS_AB_MAXIMUM_OBJECT_ID 0x8170101e PR_EMS_AB_NETWORK_ADDRESS 0x8171101e PR_EMS_AB_LDAP_DISPLAY_NAME 0x81730003 PR_EMS_AB_SCHEMA_FLAGS 0x8174000d PR_EMS_AB_BRIDGEHEAD_SERVERS_O 0x8174101e PR_EMS_AB_BRIDGEHEAD_SERVERS 0x8175001e PR_EMS_AB_WWW_HOME_PAGE 0x8176001e PR_EMS_AB_NNTP_CONTENT_FORMAT 0x8177001e PR_EMS_AB_POP_CONTENT_FORMAT 0x81780003 PR_EMS_AB_LANGUAGE 0x8179001e PR_EMS_AB_POP_CHARACTER_SET 0x817a0003 PR_EMS_AB_USN_INTERSITE 0x817b001e PR_EMS_AB_SUB_SITE 0x817c1003 PR_EMS_AB_SCHEMA_VERSION 0x817d001e PR_EMS_AB_NNTP_CHARACTER_SET 0x817e000b PR_EMS_AB_USE_SERVER_VALUES 0x817f0003 PR_EMS_AB_ENABLED_PROTOCOLS 0x81800102 PR_EMS_AB_CONNECTION_LIST_FILTER 0x8181101e PR_EMS_AB_AVAILABLE_AUTHORIZATION_PACKAGES 0x8182101e PR_EMS_AB_CHARACTER_SET_LIST 0x8183000b PR_EMS_AB_USE_SITE_VALUES 0x8184101e PR_EMS_AB_ENABLED_AUTHORIZATION_PACKAGES 0x8185001e PR_EMS_AB_CHARACTER_SET 0x81860003 PR_EMS_AB_CONTENT_TYPE 0x8187000b PR_EMS_AB_ANONYMOUS_ACCESS 0x81880102 PR_EMS_AB_CONTROL_MSG_FOLDER_ID 0x8189001e PR_EMS_AB_USENET_SITE_NAME 0x818a0102 PR_EMS_AB_CONTROL_MSG_RULES 0x818b001e PR_EMS_AB_AVAILABLE_DISTRIBUTIONS 0x818d0102 PR_EMS_AB_OUTBOUND_HOST 0x818e101e PR_EMS_AB_INBOUND_HOST 0x818f0003 PR_EMS_AB_OUTGOING_MSG_SIZE_LIMIT 0x81900003 PR_EMS_AB_INCOMING_MSG_SIZE_LIMIT 0x8191000b PR_EMS_AB_SEND_TNEF 0x81920102 PR_EMS_AB_AUTHORIZED_PASSWORD_CONFIRM 0x8193001e PR_EMS_AB_INBOUND_NEWSFEED 0x81940003 PR_EMS_AB_NEWSFEED_TYPE 0x8195001e PR_EMS_AB_OUTBOUND_NEWSFEED 0x81960102 PR_EMS_AB_NEWSGROUP_LIST 0x8197101e PR_EMS_AB_NNTP_DISTRIBUTIONS 0x8198001e PR_EMS_AB_NEWSGROUP 0x8199001e PR_EMS_AB_MODERATOR 0x819a001e PR_EMS_AB_AUTHENTICATION_TO_USE 0x819b000b PR_EMS_AB_HTTP_PUB_GAL 0x819c0003 PR_EMS_AB_HTTP_PUB_GAL_LIMIT 0x819e1102 PR_EMS_AB_HTTP_PUB_PF 0x81a1001e PR_EMS_AB_X500_RDN 0x81a2001e PR_EMS_AB_X500_NC 0x81a3101e PR_EMS_AB_REFERRAL_LIST 0x81a4000b PR_EMS_AB_NNTP_DISTRIBUTIONS_FLAG 0x81a5000d PR_EMS_AB_ASSOC_PROTOCOL_CFG_NNTP_O 0x81a5001e PR_EMS_AB_ASSOC_PROTOCOL_CFG_NNTP 0x81a6000d PR_EMS_AB_NNTP_NEWSFEEDS_O 0x81a6101e PR_EMS_AB_NNTP_NEWSFEEDS 0x81a8000b PR_EMS_AB_ENABLED_PROTOCOL_CFG 0x81a9101e PR_EMS_AB_HTTP_PUB_AB_ATTRIBUTES 0x81ab101e PR_EMS_AB_HTTP_SERVERS 0x81ac000b PR_EMS_AB_MODERATED 0x81ad001e PR_EMS_AB_RAS_ACCOUNT 0x81ae0102 PR_EMS_AB_RAS_PASSWORD 0x81af0102 PR_EMS_AB_INCOMING_PASSWORD 0x81b0000b PR_EMS_AB_OUTBOUND_HOST_TYPE 0x81b1000b PR_EMS_AB_PROXY_GENERATION_ENABLED 0x81b20102 PR_EMS_AB_ROOT_NEWSGROUPS_FOLDER_ID 0x81b3000b PR_EMS_AB_CONNECTION_TYPE 0x81b40003 PR_EMS_AB_CONNECTION_LIST_FILTER_TYPE 0x81b50003 PR_EMS_AB_PORT_NUMBER 0x81b6101e PR_EMS_AB_PROTOCOL_SETTINGS 0x81b7001e PR_EMS_AB_GROUP_BY_ATTR_1 0x81b8001e PR_EMS_AB_GROUP_BY_ATTR_2 0x81b9001e PR_EMS_AB_GROUP_BY_ATTR_3 0x81ba001e PR_EMS_AB_GROUP_BY_ATTR_4 0x81be001e PR_EMS_AB_VIEW_SITE 0x81bf001e PR_EMS_AB_VIEW_CONTAINER_1 0x81c0001e PR_EMS_AB_VIEW_CONTAINER_2 0x81c1001e PR_EMS_AB_VIEW_CONTAINER_3 0x81c20040 PR_EMS_AB_PROMO_EXPIRATION 0x81c3101e PR_EMS_AB_DISABLED_GATEWAY_PROXY 0x81c40102 PR_EMS_AB_COMPROMISED_KEY_LIST 0x81c5000d PR_EMS_AB_INSADMIN_O 0x81c5001e PR_EMS_AB_INSADMIN 0x81c6000b PR_EMS_AB_OVERRIDE_NNTP_CONTENT_FORMAT 0x81c7000d PR_EMS_AB_OBJ_VIEW_CONTAINERS_O 0x81c7101e PR_EMS_AB_OBJ_VIEW_CONTAINERS 0x8c180003 PR_EMS_AB_VIEW_FLAGS 0x8c19001e PR_EMS_AB_GROUP_BY_ATTR_VALUE_STR 0x8c1a000d PR_EMS_AB_GROUP_BY_ATTR_VALUE_DN_O 0x8c1a001e PR_EMS_AB_GROUP_BY_ATTR_VALUE_DN 0x8c1b1102 PR_EMS_AB_VIEW_DEFINITION 0x8c1c0102 PR_EMS_AB_MIME_TYPES 0x8c1d0003 PR_EMS_AB_LDAP_SEARCH_CFG 0x8c1e000d PR_EMS_AB_INBOUND_DN_O 0x8c1e001e PR_EMS_AB_INBOUND_DN 0x8c1f000b PR_EMS_AB_INBOUND_NEWSFEED_TYPE 0x8c20000b PR_EMS_AB_INBOUND_ACCEPT_ALL 0x8c21000b PR_EMS_AB_ENABLED 0x8c22000b PR_EMS_AB_PRESERVE_INTERNET_CONTENT 0x8c23000b PR_EMS_AB_DISABLE_DEFERRED_COMMIT 0x8c24000b PR_EMS_AB_CLIENT_ACCESS_ENABLED 0x8c25000b PR_EMS_AB_REQUIRE_SSL 0x8c26001e PR_EMS_AB_ANONYMOUS_ACCOUNT 0x8c270102 PR_EMS_AB_CERTIFICATE_CHAIN_V3 0x8c280102 PR_EMS_AB_CERTIFICATE_REVOCATION_LIST_V3 0x8c290102 PR_EMS_AB_CERTIFICATE_REVOCATION_LIST_V1 0x8c301102 PR_EMS_AB_CROSS_CERTIFICATE_CRL 0x8c31000b PR_EMS_AB_SEND_EMAIL_MESSAGE 0x8c32000b PR_EMS_AB_ENABLE_COMPATIBILITY 0x8c33101e PR_EMS_AB_SMIME_ALG_LIST_NA 0x8c34101e PR_EMS_AB_SMIME_ALG_LIST_OTHER 0x8c35001e PR_EMS_AB_SMIME_ALG_SELECTED_NA 0x8c36001e PR_EMS_AB_SMIME_ALG_SELECTED_OTHER 0x8c37000b PR_EMS_AB_DEFAULT_MESSAGE_FORMAT 0x8c38001e PR_EMS_AB_TYPE 0x8c3a0003 PR_EMS_AB_DO_OAB_VERSION 0x8c3b0102 PR_EMS_AB_VOICE_MAIL_SYSTEM_GUID 0x8c3c001e PR_EMS_AB_VOICE_MAIL_USER_ID 0x8c3d001e PR_EMS_AB_VOICE_MAIL_PASSWORD 0x8c3e0102 PR_EMS_AB_VOICE_MAIL_RECORDED_NAME 0x8c3f101e PR_EMS_AB_VOICE_MAIL_GREETINGS 0x8c401102 PR_EMS_AB_VOICE_MAIL_FLAGS 0x8c410003 PR_EMS_AB_VOICE_MAIL_VOLUME 0x8c420003 PR_EMS_AB_VOICE_MAIL_SPEED 0x8c431003 PR_EMS_AB_VOICE_MAIL_RECORDING_LENGTH 0x8c44001e PR_EMS_AB_DISPLAY_NAME_SUFFIX 0x8c451102 PR_EMS_AB_ATTRIBUTE_CERTIFICATE 0x8c461102 PR_EMS_AB_DELTA_REVOCATION_LIST 0x8c471102 PR_EMS_AB_SECURITY_POLICY 0x8c48000b PR_EMS_AB_SUPPORT_SMIME_SIGNATURES 0x8c49000b PR_EMS_AB_DELEGATE_USER 0x8c50000b PR_EMS_AB_LIST_PUBLIC_FOLDERS 0x8c51001e PR_EMS_AB_LABELEDURI 0x8c52000b PR_EMS_AB_RETURN_EXACT_MSG_SIZE 0x8c53001e PR_EMS_AB_GENERATION_QUALIFIER 0x8c54001e PR_EMS_AB_HOUSE_IDENTIFIER 0x8c550102 PR_EMS_AB_SUPPORTED_ALGORITHMS 0x8c56001e PR_EMS_AB_DMD_NAME 0x8c57001e PR_EMS_AB_EXTENSION_ATTRIBUTE_11 0x8c58001e PR_EMS_AB_EXTENSION_ATTRIBUTE_12 0x8c59001e PR_EMS_AB_EXTENSION_ATTRIBUTE_13 0x8c60001e PR_EMS_AB_EXTENSION_ATTRIBUTE_14 0x8c61001e PR_EMS_AB_EXTENSION_ATTRIBUTE_15 0x8c620003 PR_EMS_AB_REPLICATED_OBJECT_VERSION 0x8c63001e PR_EMS_AB_MAIL_DROP 0x8c64001e PR_EMS_AB_FORWARDING_ADDRESS 0x8c650102 PR_EMS_AB_FORM_DATA 0x8c66001e PR_EMS_AB_OWA_SERVER 0x8c67001e PR_EMS_AB_EMPLOYEE_NUMBER 0x8c68001e PR_EMS_AB_TELEPHONE_PERSONAL_PAGER 0x8c69001e PR_EMS_AB_EMPLOYEE_TYPE 0x8c6a1102 PR_EMS_AB_TAGGED_X509_CERT 0x8c6b001e PR_EMS_AB_PERSONAL_TITLE 0x8c6c001e PR_EMS_AB_LANGUAGE_ISO639 0x8c6d0102 PR_EMS_AB_OBJECT_GUID 0x8c8e001e PR_EMS_AB_PHONETIC_GIVEN_NAME 0x8c8f001e PR_EMS_AB_PHONETIC_SURNAME 0x8c90001e PR_EMS_AB_PHONETIC_DEPARTMENT_NAME 0x8c91001e PR_EMS_AB_PHONETIC_COMPANY_NAME 0x8c92001e PR_EMS_AB_PHONETIC_DISPLAY_NAME 0x8c96001e PR_EMS_AB_ROOM_CONTAINERS 0xf000000d PR_EMS_AB_OTHER_RECIPS 0xfff8101e PR_EMS_AB_CHILD_RDNS 0xfff9001e PR_EMS_AB_HIERARCHY_PATH 0xfffa0102 PR_EMS_AB_OBJECT_OID 0xfffb000b PR_EMS_AB_IS_MASTER 0xfffc0102 PR_EMS_AB_PARENT_ENTRYID 0xfffd0003 PR_EMS_AB_CONTAINERID 0xfffe001e PR_EMS_AB_SERVER openchange-2.0/libmapi/conf/mparse.pl000077500000000000000000001107631223057412600176650ustar00rootroot00000000000000#!/usr/bin/perl -w ################################################### # package to parse the mapi-properties files and # generate code for libmapi in OpenChange # # Perl code based on pidl one from Andrew Tridgell and the Samba team # # Copyright (C) Julien Kerihuel 2005-2011 # released under the GNU GPL use strict; use Getopt::Long; my $ret = ""; my $tabs = ""; sub indent() { $tabs.="\t"; } sub deindent() { $tabs = substr($tabs, 1); } sub mparse($) { $ret .= $tabs.(shift)."\n"; } my($opt_outputdir) = '.'; my($opt_parser) = ''; my %prop_types = ( 0x0 => "PT_UNSPECIFIED", 0x1 => "PT_NULL", 0x2 => "PT_SHORT", 0x3 => "PT_LONG", 0x4 => "PT_FLOAT", 0x5 => "PT_DOUBLE", 0x6 => "PT_CURRENCY", 0x7 => "PT_APPTIME", 0xa => "PT_ERROR", 0xb => "PT_BOOLEAN", 0xd => "PT_OBJECT", 0x14 => "PT_I8", 0x1e => "PT_STRING8", 0x1f => "PT_UNICODE", 0x40 => "PT_SYSTIME", 0x48 => "PT_CLSID", 0xFB => "PT_SVREID", 0xFD => "PT_SRESTRICT", 0xFE => "PT_ACTIONS", 0x102 => "PT_BINARY", # Multi-valued property types 0x1002 => "PT_MV_SHORT", 0x1003 => "PT_MV_LONG", 0x1004 => "PT_MV_FLOAT", 0x1005 => "PT_MV_DOUBLE", 0x1006 => "PT_MV_CURRENCY", 0x1007 => "PT_MV_APPTIME", 0x1014 => "PT_MV_I8", 0x101e => "PT_MV_STRING8", 0x101f => "PT_MV_UNICODE", 0x1040 => "PT_MV_SYSTIME", 0x1048 => "PT_MV_CLSID", 0x1102 => "PT_MV_BINARY" ); my %prop_names = ( "PT_UNSPECIFIED" => 0x0, "PT_NULL" => 0x1, "PT_SHORT" => 0x2, "PT_LONG" => 0x3, "PT_FLOAT" => 0x4, "PT_DOUBLE" => 0x5, "PT_CURRENCY" => 0x6, "PT_APPTIME" => 0x7, "PT_ERROR" => 0xa, "PT_BOOLEAN" => 0xb, "PT_OBJECT" => 0xd, "PT_I8" => 0x14, "PT_STRING8" => 0x1e, "PT_UNICODE" => 0x1f, "PT_SYSTIME" => 0x40, "PT_CLSID" => 0x48, "PT_SVREID" => 0xfb, "PT_SRESTRICT" => 0xfd, "PT_ACTIONS" => 0xfe, "PT_BINARY" => 0x102, # Multi-valued property types "PT_MV_SHORT" => 0x1002, "PT_MV_LONG" => 0x1003, "PT_MV_FLOAT" => 0x1004, "PT_MV_DOUBLE" => 0x1005, "PT_MV_CURRENCY" => 0x1006, "PT_MV_APPTIME" => 0x1007, "PT_MV_I8" => 0x1014, "PT_MV_STRING8" => 0x101e, "PT_MV_UNICODE" => 0x101f, "PT_MV_SYSTIME" => 0x1040, "PT_MV_CLSID" => 0x1048, "PT_MV_BINARY" => 0x1102 ); my %oleguid = ( "PSETID_Appointment" => "00062002-0000-0000-c000-000000000046", "PSETID_Task" => "00062003-0000-0000-c000-000000000046", "PSETID_Address" => "00062004-0000-0000-c000-000000000046", "PSETID_Common" => "00062008-0000-0000-c000-000000000046", "PSETID_Note" => "0006200e-0000-0000-c000-000000000046", "PSETID_Log" => "0006200a-0000-0000-c000-000000000046", "PSETID_Sharing" => "00062040-0000-0000-c000-000000000046", "PSETID_PostRss" => "00062041-0000-0000-c000-000000000046", "PSETID_UnifiedMessaging" => "4442858e-a9e3-4e80-b900-317a210cc15b", "PSETID_Meeting" => "6ed8da90-450b-101b-98da-00aa003f1305", "PSETID_AirSync" => "71035549-0739-4dcb-9163-00f0580dbbdf", "PSETID_Messaging" => "41f28f13-83f4-4114-a584-eedb5a6b0bff", "PSETID_Attachment" => "96357f7f-59e1-47d0-99a7-46515c183b54", "PSETID_CalendarAssistant" => "11000e07-b51b-40d6-af21-caa85edab1d0", "PS_PUBLIC_STRINGS" => "00020329-0000-0000-c000-000000000046", "PS_INTERNET_HEADERS" => "00020386-0000-0000-c000-000000000046", "PS_MAPI" => "00020328-0000-0000-c000-000000000046", "PSETID_Report" => "00062013-0000-0000-c000-000000000046", "PSETID_Remote" => "00062014-0000-0000-c000-000000000046", "PS_UNKNOWN_0006200b_0000_0000_c000_000000000046" => "0006200b-0000-0000-c000-000000000046", "PSETID_Appointment2" => "02200600-0000-0000-c000-000000000046", "PSETID_GoodMessaging" => "ef9203ee-b9a5-101b-acc1-00aa00423326", "PS_UNKNOWN_2f733904_5c72_45d7_a476_c4dd9f3f4052" => "2f733904-5c72-45d7-a476-c4dd9f3f4052" ); # main program my $result = GetOptions ( 'outputdir=s' => \$opt_outputdir, 'parser=s' => \$opt_parser ); if (not $result) { exit(1); } ##################################################################### # read a file into a string sub FileLoad($) { my($filename) = shift; local(*INPUTFILE); open(INPUTFILE, $filename) || return undef; my($saved_delim) = $/; undef $/; my($data) = ; close(INPUTFILE); $/ = $saved_delim; return $data; } ##################################################################### # write a string into a file sub FileSave($$) { my($filename) = shift; my($v) = shift; local(*FILE); open(FILE, ">$filename") || die "can't open $filename"; print FILE $v; close(FILE); } ##################################################################### # generate mapitags.h file sub mapitags_header($) { my $contents = shift; my $line; my @lines; my @prop; my $prop_type; my $prop_value; mparse "/* parser auto-generated by mparse */"; mparse "#ifndef __MAPITAGS_H__"; mparse "#define __MAPITAGS_H__"; mparse ""; @lines = split(/\n/, $contents); foreach $line (@lines) { $line =~ s/^\#+.*$//; if ($line) { @prop = split(/\s+/, $line); # if (!defined($prop[6])) { # print "prop6 not defined for line: $line\n"; # } # elsif (!defined($oleguid{$prop[6]})) { # print "entry not defined for guid: $prop[6]\n"; # } $prop_type = hex $prop[0]; $prop_type &= 0xFFFF; $prop_value = hex $prop[0]; $prop_value = ($prop_value >> 16) & 0xFFFF; mparse sprintf "#define %-51s PROP_TAG(%-13s, 0x%.04x) /* %s */", $prop[1], $prop_types{$prop_type}, $prop_value, $prop[0] if ($prop_types{$prop_type}); if (($prop_type == 0x1e) || ($prop_type == 0x101e)){ $prop_type++; $prop[0] = sprintf "0x%.8x", ((hex $prop[0]) & 0xFFFF0000) + $prop_type; mparse sprintf "#define %-51s PROP_TAG(%-13s, 0x%.04x) /* %s */", "$prop[1]_UNICODE", $prop_types{$prop_type}, $prop_value, $prop[0] if ($prop_types{$prop_type}); } $prop_type = 0xa; $prop[0] = sprintf "0x%.8x", ((hex $prop[0]) & 0xFFFF0000) + $prop_type; mparse sprintf "#define %-51s PROP_TAG(%-13s, 0x%.04x) /* %s */", "$prop[1]_ERROR", $prop_types{$prop_type}, $prop_value, $prop[0] if ($prop_types{$prop_type}); } } mparse ""; mparse "#endif /* !__MAPITAGS_H__ */"; return $ret; } ##################################################################### # generate mapitags.c file sub mapitags_interface($) { my $contents = shift; my $line; my @lines; my @prop; my $prop_type; my $prop_value; mparse "/* parser auto-generated by mparse */"; mparse "#include \"libmapi/libmapi.h\""; mparse "#include \"libmapi/libmapi_private.h\""; mparse "#include \"gen_ndr/ndr_exchange.h\""; mparse "#include \"libmapi/mapitags.h\""; mparse ""; mparse "struct mapi_proptags"; mparse "{"; indent; mparse "uint32_t proptag;"; mparse "uint32_t proptype;"; mparse "const char *propname;"; deindent; mparse "};"; mparse ""; mparse "static struct mapi_proptags mapitags[] = {"; indent; @lines = split(/\n/, $contents); foreach $line (@lines) { $line =~ s/^\#+.*$//; if ($line) { @prop = split(/\s+/, $line); $prop_type = hex $prop[0]; $prop_type &= 0xFFFF; $prop_value = hex $prop[0]; $prop_value = ($prop_value >> 16) & 0xFFFF; if ($prop_types{$prop_type}) { mparse sprintf "{ %-51s, %-13s, \"%s\" },", $prop[1], $prop_types{$prop_type}, $prop[1]; if (($prop_type == 0x1e) || ($prop_type == 0x101e)) { $prop_type++; mparse sprintf "{ %-51s, %-13s, \"%s\" },", "$prop[1]_UNICODE", $prop_types{$prop_type}, "$prop[1]_UNICODE"; } $prop_type = 0xa; mparse sprintf "{ %-51s, %-13s, \"%s\" },", "$prop[1]_ERROR", $prop_types{$prop_type}, $prop[1]; } } } mparse sprintf "{ %-51s, %-13d, \"NULL\"}", 0, 0; deindent; mparse "};"; mparse ""; mparse "_PUBLIC_ const char *get_proptag_name(uint32_t proptag)"; mparse "{"; indent; mparse "uint32_t idx;"; mparse ""; mparse "for (idx = 0; mapitags[idx].proptag; idx++) {"; indent; mparse "if (mapitags[idx].proptag == proptag) { "; indent; mparse "return mapitags[idx].propname;"; deindent; mparse "}"; deindent; mparse "}"; mparse ""; mparse "return NULL;"; deindent; mparse "}"; mparse ""; mparse "_PUBLIC_ uint32_t get_proptag_value(const char *propname)"; mparse "{"; indent; mparse "uint32_t idx;"; mparse ""; mparse "for (idx = 0; mapitags[idx].proptag; idx++) {"; indent; mparse "if (!strcmp(mapitags[idx].propname, propname)) { "; indent; mparse "return mapitags[idx].proptag;"; deindent; mparse "}"; deindent; mparse "}"; mparse ""; mparse "return 0;"; deindent; mparse "}"; mparse ""; mparse "_PUBLIC_ uint16_t get_property_type(uint16_t untypedtag)"; mparse "{"; indent; mparse "uint32_t idx;"; mparse "uint16_t current_type;"; mparse ""; mparse "for (idx = 0; mapitags[idx].proptag; idx++) {"; indent; mparse "if ((mapitags[idx].proptag >> 16) == untypedtag) {"; indent; mparse "current_type = mapitags[idx].proptag & 0xffff;"; mparse "if (current_type != PT_ERROR && current_type != PT_STRING8) {"; indent; mparse "return current_type;"; deindent; mparse "}"; deindent; mparse "}"; deindent; mparse "}"; mparse ""; mparse "DEBUG(5, (\"%s: type for property '%x' could not be deduced\\n\", __FUNCTION__, untypedtag));"; mparse ""; mparse "return 0;"; deindent; mparse "}"; return $ret; } ##################################################################### # generate mapitags_enum.idl file sub mapitags_enum($) { my $contents = shift; my $line; my @lines; my @prop; my $prop_type; my %hash; mparse "/* parser auto-generated by mparse */"; mparse ""; mparse "typedef [v1_enum, flag(NDR_PAHEX)] enum {"; indent; @lines = split(/\n/, $contents); foreach $line (@lines) { $line =~ s/^\#+.*$//; if ($line) { @prop = split(/\s+/, $line); $prop_type = hex $prop[0]; $prop_type &= 0xFFFF; mparse sprintf "%-51s = %s,", $prop[1], $prop[0]; if (($prop_type == 0x1e) || ($prop_type == 0x101e)) { $prop_type = hex $prop[0]; $prop_type++; mparse sprintf "%-51s = 0x%.8x,", "$prop[1]_UNICODE", $prop_type; } if (!exists($hash{((hex $prop[0]) & 0xFFFF0000)})) { $prop_type = 0xa; $prop_type += ((hex $prop[0]) & 0xFFFF0000); mparse sprintf "%-51s = 0x%.8x,", "$prop[1]_ERROR", $prop_type; $hash{((hex $prop[0]) & 0xFFFF0000)} = 1; } } } mparse sprintf "%-51s = %s", "MAPI_PROP_RESERVED", "0xFFFFFFFF"; deindent; mparse "} MAPITAGS;"; mparse ""; return $ret; } ##################################################################### # generate mapi_nameid_private.h file sub mapi_nameid_private_header($) { my $contents = shift; my $line; my @lines; my @prop; my $prop_OOM; my $prop_ID; my $prop_Type; my $prop_name; my $prop_Kind; my $prop_OLEGUID; mparse "/* parser auto-generated by mparse */"; mparse "#ifndef __MAPI_NAMEID_PRIVATE_H__"; mparse "#define __MAPI_NAMEID_PRIVATE_H__"; mparse ""; mparse "static struct mapi_nameid_tags mapi_nameid_tags[] = {"; indent; @lines = split(/\n/, $contents); foreach $line (@lines) { $line =~ s/^\#+.*$//; if ($line) { @prop = split(/\s+/, $line); if ($prop[1] ne "NULL") { $prop[1] = sprintf "\"%s\"", $prop[1]; } if ($prop[3] ne "NULL") { $prop[3] = sprintf "\"%s\"", $prop[3] } if ($prop[0] eq "NULL") { $prop[0] = "0x00000000"; } mparse sprintf "{ %-51s, %-40s, %-15s, %-30s, %-30s, %-15s, %-20s, 0x0 },", $prop[0], $prop[1], $prop[2], $prop[3], $prop[4], $prop[5], $prop[6]; } } mparse sprintf "{ 0x00000000, NULL, 0x0, NULL, PT_UNSPECIFIED, 0x0, NULL, 0x0 }"; deindent; mparse "};"; mparse ""; mparse "#endif /* !MAPI_NAMEID_PRIVATE_H__ */"; return $ret; } ##################################################################### # generate mapi_nameid.h file sub mapi_nameid_header($) { my $contents = shift; my $line; my @lines; my @prop; my $propID; my $proptype; my $property; my $counter = 0; mparse "/* parser auto-generated by mparse */"; mparse "#ifndef __MAPI_NAMEID_H__"; mparse "#define __MAPI_NAMEID_H__"; mparse ""; mparse "/* NOTE TO DEVELOPERS: If this is a MNID_STRING named property,"; mparse " * then we use the arbitrary 0xa000-0afff property ID range for"; mparse " * internal mapping purpose only."; mparse " */"; mparse ""; mparse "struct mapi_nameid_tags {"; indent; mparse "uint32_t proptag;"; mparse "const char *OOM;"; mparse "uint16_t lid;"; mparse "const char *Name;"; mparse "uint32_t propType;"; mparse "uint8_t ulKind;"; mparse "const char *OLEGUID;"; mparse "uint32_t position;"; deindent; mparse "};"; mparse ""; mparse "struct mapi_nameid {"; indent; mparse "struct MAPINAMEID *nameid;"; mparse "uint16_t count;"; mparse "struct mapi_nameid_tags *entries;"; deindent; mparse "};"; mparse ""; @lines = split(/\n/, $contents); foreach $line (@lines) { $line =~ s/^\#+.*$//; if ($line) { @prop = split(/\s+/, $line); if ($prop[0] ne "NULL") { $proptype = $prop_names{$prop[4]}; $propID = hex $prop[2]; if ($propID == 0) { # 40960 == 0xa000 $propID = 40960 + $counter; $counter++; } $property = sprintf "0x%.8x", ($propID << 16) | $proptype; mparse sprintf "#define %-51s %s", $prop[0], $property; } } } mparse ""; mparse "#endif /* !MAPI_NAMEID_H__ */"; return $ret; } ##################################################################### # generate mapicode.c file sub mapicodes_interface($) { my $contents = shift; my $line; my @lines; my @errors; mparse "/* parser auto-generated by mparse */"; mparse "#include \"libmapi/libmapi.h\""; mparse "#include \"libmapi/libmapi_private.h\""; mparse "#include \"gen_ndr/ndr_exchange.h\""; mparse ""; mparse "void set_errno(enum MAPISTATUS status)"; mparse "{"; indent; mparse "errno = status;"; deindent; mparse "}"; mparse ""; mparse "struct mapi_retval {"; indent; mparse "enum MAPISTATUS err;"; mparse "const char *name;"; deindent; mparse "};"; mparse ""; mparse "static const struct mapi_retval mapi_retval[] = {"; indent; @lines = split(/\n/, $contents); foreach $line (@lines) { $line =~ s/^\#+.*$//; if ($line) { @errors = split(/\s+/, $line); mparse sprintf "{ %8s, \"%s\" },", $errors[1], $errors[1]; } } mparse " { MAPI_E_RESERVED, NULL }"; deindent; mparse "};"; mparse ""; mparse "_PUBLIC_ void mapi_errstr(const char *function, enum MAPISTATUS mapi_code)"; mparse "{"; indent; mparse "struct ndr_print ndr_print;"; mparse ""; mparse "ndr_print.depth = 1;"; mparse "ndr_print.print = ndr_print_debug_helper;"; mparse "ndr_print.no_newline = false;"; mparse "ndr_print_MAPISTATUS(&ndr_print, function, mapi_code);"; deindent; mparse "}"; mparse ""; mparse "_PUBLIC_ const char *mapi_get_errstr(enum MAPISTATUS mapi_code)"; mparse "{"; indent; mparse "uint32_t i;"; mparse ""; mparse "for (i = 0; mapi_retval[i].name; i++) {"; indent; mparse "if (mapi_retval[i].err == mapi_code) {"; indent; mparse "return mapi_retval[i].name;"; deindent; mparse "}"; deindent; mparse "}"; mparse ""; mparse "return NULL;"; deindent; mparse "}"; } ##################################################################### # generate mapicodes_enum.idl file sub mapicodes_enum($) { my $contents = shift; my $line; my @lines; my @prop; my $prop_type; mparse "/* parser auto-generated by mparse */"; mparse ""; mparse "typedef [public, v1_enum, flag(NDR_PAHEX)] enum {"; indent; @lines = split(/\n/, $contents); foreach $line (@lines) { $line =~ s/^\#+.*$//; if ($line) { @prop = split(/\s+/, $line); mparse sprintf "%-51s = %s,", $prop[1], $prop[0]; } } mparse sprintf "%-51s = %s", "MAPI_E_RESERVED", "0xFFFFFFFF"; deindent; mparse "} MAPISTATUS;"; mparse ""; return $ret; } ##################################################################### # generate openchangedb_property.c file sub openchangedb_property($) { my $contents = shift; my $line; my @lines; my @prop; my $prop_type; my $prop_value; my $pidtag; mparse "/* parser auto-generated by mparse */"; mparse "#include \"mapiproxy/dcesrv_mapiproxy.h\""; mparse "#include \"libmapiproxy.h\""; mparse "#include \"libmapi/libmapi.h\""; mparse "#include \"libmapi/libmapi_private.h\""; mparse ""; mparse "struct pidtags {"; mparse " uint32_t proptag;"; mparse " const char *pidtag;"; mparse "};"; mparse ""; mparse "static struct pidtags pidtags[] = {"; indent; @lines = split(/\n/, $contents); foreach $line (@lines) { $line =~ s/^\#+.*$//; if ($line) { @prop = split(/\s+/, $line); $prop_type = hex $prop[0]; $prop_type &= 0xFFFF; $prop_value = hex $prop[0]; $prop_value = ($prop_value >> 16) & 0xFFFF; if ($prop_types{$prop_type}) { if ($prop[2]) { mparse sprintf "{ %-51s, \"%s\"},", $prop[1], $prop[2]; } else { mparse sprintf "{ %-51s, \"0x%.8x\"},", $prop[1], hex $prop[0]; } if (($prop_type == 0x1e) || ($prop_type == 0x101e)) { if ($prop[2]) { mparse sprintf "{ %-51s, \"%s\"},", "$prop[1]_UNICODE", $prop[2]; } else { mparse sprintf "{ %-51s, \"0x%.8x\"},", "$prop[1]_UNICODE", hex $prop[0]; } } } } } mparse sprintf "{ %-51s, NULL }", 0; deindent; mparse "};"; mparse ""; mparse "_PUBLIC_ const char *openchangedb_property_get_attribute(uint32_t proptag)"; mparse "{"; indent; mparse "uint32_t i;"; mparse ""; mparse "for (i = 0; pidtags[i].pidtag; i++) {"; indent; mparse "if (pidtags[i].proptag == proptag) {"; indent; mparse "return pidtags[i].pidtag;"; deindent; mparse "}"; deindent; mparse "}"; mparse "DEBUG(0, (\"[%s:%d]: Unsupported property tag '0x%.8x'\\n\", __FUNCTION__, __LINE__, proptag));"; mparse ""; mparse "return NULL;"; deindent; mparse "}"; } ##################################################################### # generate codepage_lcid.c file sub codepage_lcid_interface($) { my $contents = shift; my $line; my @lines; my @params; my $locale; mparse "/* parser auto-generated by mparse */"; mparse "#include \"libmapi/libmapi.h\""; mparse "#include \"libmapi/libmapi_private.h\""; mparse "#include "; mparse "#include "; mparse ""; mparse "/**"; mparse " \\file codepage_lcid.c"; mparse ""; mparse " \\brief Codepage and Locale ID operations"; mparse " */"; mparse ""; # Step 1. Generate code for defines @lines = split(/\n/, $contents); foreach $line (@lines) { $line =~ s/^\#+.*$//; if ($line) { @params = split(/\s+/, $line); if ($params[0] eq "DEFINE") { mparse sprintf "#define %-30s %15d", $params[1], $params[2]; } } } ## We do not have yet convenient functions making use of this struct. This causes warning # mparse ""; # mparse "static const char *language_group[] ="; # mparse "{"; # indent; # foreach $line (@lines) { # $line =~ s/^\#+.*$//; # if ($line) { # @params = split(/\s+/, $line); # if ($params[0] eq "DEFINE") { # mparse sprintf "\"%s\",", $params[1]; # } # } # } # mparse "NULL"; # deindent; # mparse "};"; # mparse ""; # Step 2. Generate the locales array mparse "struct cpid_lcid {"; indent; mparse "const char *language;"; mparse "const char *locale;"; mparse "uint32_t lcid;"; mparse "uint32_t cpid;"; mparse "uint32_t language_group;"; deindent; mparse "};"; mparse ""; mparse "static const struct cpid_lcid locales[] ="; mparse "{"; indent; foreach $line (@lines) { $line =~ s/^\#+.*$//; if ($line) { @params = split(/\s+/, $line); if ($params[0] ne "DEFINE") { $params[0] = ($params[1] eq "NULL") ? (sprintf "\"%s\",", $params[0]) : (sprintf "\"%s (%s)\",", $params[0], $params[1]); $params[0] =~ s/_/ /g; $params[2] = sprintf "\"%s\",", $params[2]; mparse sprintf "{ %-32s %-18s %-6s, %-4s, %-24s },", $params[0], $params[2], $params[3], $params[4], $params[5]; } } } mparse "{ NULL, NULL, 0, 0, 0 }"; deindent; mparse "};"; mparse ""; # mapi_get_system_locale mparse "/**"; mparse " \\details Returns current locale used by the system"; mparse ""; mparse " \\return pointer to locale string on success, otherwise NULL"; mparse " */"; mparse "_PUBLIC_ char *mapi_get_system_locale(void)"; mparse "{"; indent; mparse "char *locale;"; mparse ""; mparse "locale = setlocale(LC_CTYPE, \"\");"; mparse "return locale;"; deindent; mparse "}"; mparse ""; # mapi_verify_cpid mparse "/**"; mparse " \\details Verify if the specified codepage is valid"; mparse ""; mparse " \\param cpid the codepage to lookup"; mparse ""; mparse " \\return 0 on success, otherwise 1"; mparse " */"; mparse "_PUBLIC_ bool mapi_verify_cpid(uint32_t cpid)"; mparse "{"; indent; mparse "uint32_t i;"; mparse ""; mparse "for (i = 0; locales[i].lcid; i++) {"; indent; mparse "if (cpid == locales[i].cpid) {"; indent; mparse "return true;"; deindent; mparse "}"; deindent; mparse "}"; mparse ""; mparse "return false;"; deindent; mparse "}"; mparse ""; # mapi_get_cpid_from_lcid mparse "/**"; mparse " \\details Returns codepage for a given LCID (Locale ID)"; mparse ""; mparse " \\param lcid the locale ID to lookup"; mparse ""; mparse " \\return non-zero codepage on success, otherwise 0 if"; mparse " only unicode is supported for this language"; mparse " */"; mparse "_PUBLIC_ uint32_t mapi_get_cpid_from_lcid(uint32_t lcid)"; mparse "{"; indent; mparse "uint32_t i;"; mparse ""; mparse "for (i = 0; locales[i].lcid; i++) {"; indent; mparse "if (lcid == locales[i].lcid) {"; indent; mparse "return locales[i].cpid;"; deindent; mparse "}"; deindent; mparse "}"; mparse ""; mparse "return 0;"; deindent; mparse "}"; mparse ""; # mapi_get_cpid_from_locale mparse "/**"; mparse " \\details Return codepage associated to specified locale"; mparse ""; mparse " \\param locale The locale string to lookup"; mparse ""; mparse " \\return non-zero codepage on success, otherwise 0"; mparse " */"; mparse "_PUBLIC_ uint32_t mapi_get_cpid_from_locale(const char *locale)"; mparse "{"; indent; mparse "uint32_t i;"; mparse ""; mparse "/* Sanity Checks */"; mparse "if (!locale) return 0;"; mparse ""; mparse "for (i = 0; locales[i].locale; i++) {"; indent; mparse "if (locales[i].locale && !strncmp(locales[i].locale, locale, strlen(locales[i].locale))) {"; indent; mparse "return locales[i].cpid;"; deindent; mparse "}"; deindent; mparse "}"; mparse ""; mparse "return 0;"; deindent; mparse "}"; mparse ""; # mapi_get_cpid_from_language mparse "/**"; mparse " \\details Return codepage associated to specified language"; mparse ""; mparse " \\param language The language string to lookup"; mparse ""; mparse " \\return non-zero codepage on success, otherwise 0"; mparse " */"; mparse "_PUBLIC_ uint32_t mapi_get_cpid_from_language(const char *language)"; mparse "{"; indent; mparse "uint32_t i;"; mparse ""; mparse "/* Sanity Checks */"; mparse "if (!language) return 0;"; mparse ""; mparse "for (i = 0; locales[i].language; i++) {"; indent; mparse "if (locales[i].language && !strncmp(locales[i].language, language, strlen(locales[i].language))) {"; indent; mparse "return locales[i].cpid;"; deindent; mparse "}"; deindent; mparse "}"; mparse ""; mparse "return 0;"; deindent; mparse "}"; mparse ""; # mapi_get_lcid_from_locale mparse "/**"; mparse " \\details Returns LCID (Locale ID) for a given locale"; mparse ""; mparse " \\param locale the locale string to lookup"; mparse ""; mparse " \\return non-zero LCID on success, otherwise 0"; mparse " */"; mparse "_PUBLIC_ uint32_t mapi_get_lcid_from_locale(const char *locale)"; mparse "{"; indent; mparse "uint32_t i;"; mparse ""; mparse "/* Sanity Checks */"; mparse "if (!locale) return 0;"; mparse ""; mparse "for (i = 0; locales[i].locale; i++) {"; indent; mparse "if (locales[i].locale && !strncmp(locales[i].locale, locale, strlen(locales[i].locale))) {"; indent; mparse "return locales[i].lcid;"; deindent; mparse "}"; deindent; mparse "}"; mparse ""; mparse "return 0;"; deindent; mparse "}"; mparse ""; # mapi_get_lcid_from_language mparse "/**"; mparse " \\details Returns LCID (Locale ID) for a given language"; mparse ""; mparse " \\param language the language string to lookup"; mparse ""; mparse " \\return non-zero LCID on success, otherwise 0"; mparse " */"; mparse "_PUBLIC_ uint32_t mapi_get_lcid_from_language(const char *language)"; mparse "{"; indent; mparse "uint32_t i;"; mparse ""; mparse "/* Sanity Checks */"; mparse "if (!language) return 0;"; mparse ""; mparse "for (i = 0; locales[i].language; i++) {"; indent; mparse "if (locales[i].language && !strncmp(locales[i].language, language, strlen(locales[i].language))) {"; indent; mparse "return locales[i].lcid;"; deindent; mparse "}"; deindent; mparse "}"; mparse ""; mparse "return 0;"; deindent; mparse "}"; mparse ""; # mapi_get_locale_from_lcid mparse "/**"; mparse " \\details Returns Locale for a given Locale ID"; mparse ""; mparse " \\param lcid the locale ID to lookup"; mparse ""; mparse " \\return locale string on success, otherwise NULL"; mparse " */"; mparse "_PUBLIC_ const char *mapi_get_locale_from_lcid(uint32_t lcid)"; mparse "{"; indent; mparse "uint32_t i;"; mparse ""; mparse "for (i = 0; locales[i].lcid; i++) {"; indent; mparse "if (locales[i].lcid == lcid) {"; indent; mparse "return locales[i].locale;"; deindent; mparse "}"; deindent; mparse "}"; mparse ""; mparse "return NULL;"; deindent; mparse "}"; mparse ""; # mapi_get_locale_from_language mparse "/**"; mparse " \\details Returns Locale for a given language"; mparse ""; mparse " \\param language the language string to lookup"; mparse ""; mparse " \\return Locale string on success, otherwise NULL"; mparse " */"; mparse "_PUBLIC_ const char *mapi_get_locale_from_language(const char *language)"; mparse "{"; indent; mparse "uint32_t i;"; mparse ""; mparse "/* Sanity Checks */"; mparse "if (!language) return NULL;"; mparse ""; mparse "for (i = 0; locales[i].language; i++) {"; indent; mparse "if (locales[i].language && !strncmp(locales[i].language, language, strlen(locales[i].language))) {"; indent; mparse "return locales[i].locale;"; deindent; mparse "}"; deindent; mparse "}"; mparse ""; mparse "return NULL;"; deindent; mparse "}"; mparse ""; # mapi_get_language_from_locale mparse "/**"; mparse " \\details Returns Language for a given Locale"; mparse ""; mparse " \\param locale the language string to lookup"; mparse ""; mparse " \\return Language string on success, otherwise NULL"; mparse " */"; mparse "_PUBLIC_ const char *mapi_get_language_from_locale(const char *locale)"; mparse "{"; indent; mparse "uint32_t i;"; mparse ""; mparse "/* Sanity Checks */"; mparse "if (!locale) return NULL;"; mparse ""; mparse "for (i = 0; locales[i].locale; i++) {"; indent; mparse "if (locales[i].locale && !strncmp(locales[i].locale, locale, strlen(locales[i].locale))) {"; indent; mparse "return locales[i].language;"; deindent; mparse "}"; deindent; mparse "}"; mparse ""; mparse "return NULL;"; deindent; mparse "}"; mparse ""; # mapi_get_language_from_lcid mparse "/**"; mparse " \\details Returns Language for a given Locale ID"; mparse ""; mparse " \\param lcid the locale ID to lookup"; mparse ""; mparse " \\return language string on success, otherwise NULL"; mparse " */"; mparse "_PUBLIC_ const char *mapi_get_language_from_lcid(uint32_t lcid)"; mparse "{"; indent; mparse "uint32_t i;"; mparse ""; mparse "for (i = 0; locales[i].lcid; i++) {"; indent; mparse "if (locales[i].lcid == lcid) {"; indent; mparse "return locales[i].language;"; deindent; mparse "}"; deindent; mparse "}"; mparse ""; mparse "return NULL;"; deindent; mparse "}"; mparse ""; # mapi_get_language_by_group mparse "/**"; mparse " \\details Returns List of languages for a given Language Group"; mparse ""; mparse " \\param mem_ctx pointer to the memory context"; mparse " \\param group the locale group to lookup"; mparse ""; mparse " \\return Array of languages string on success, otherwise NULL"; mparse " */"; mparse "_PUBLIC_ char **mapi_get_language_from_group(TALLOC_CTX *mem_ctx, uint32_t group)"; mparse "{"; indent; mparse "uint32_t i;"; mparse "uint32_t counter = 0;"; mparse "char **languages;"; mparse ""; mparse "/* Sanity Checks */"; mparse "if (!mem_ctx) return NULL;"; mparse ""; mparse "languages = talloc_array(mem_ctx, char *, counter + 1);"; mparse "for (i = 0; locales[i].language; i++) {"; indent; mparse "if (locales[i].language_group == group) {"; indent; mparse "languages = talloc_realloc(mem_ctx, languages, char *, counter + 1);"; mparse "languages[counter] = talloc_strdup(languages, locales[i].language);"; mparse "counter += 1;"; deindent; mparse "}"; deindent; mparse "}"; mparse ""; mparse "if (!counter) {"; indent; mparse "talloc_free(languages);"; mparse "return NULL;"; deindent; mparse "}"; mparse ""; mparse "return languages;"; deindent; mparse "}"; mparse ""; # assessor for mapidump_get_languages mparse "void mapi_get_language_list(void)"; mparse "{"; indent; mparse "uint32_t i;"; mparse ""; mparse "for (i = 0; locales[i].language; i++) {"; indent; mparse "printf(\"%s\\n\", locales[i].language);"; deindent; mparse "}"; deindent; mparse "}"; } ##################################################################### # generate mapistore_namedprops.ldif file sub mapistore_namedprops($) { my $contents = shift; my $line; my @lines; my @prop; mparse "# LDIF file auto-generated by mparse "; mparse ""; mparse sprintf "dn: CN=default"; mparse sprintf "objectClass: top"; mparse sprintf "cn: default"; mparse sprintf ""; mparse sprintf "dn: CN=custom"; mparse sprintf "objectClass: top"; mparse sprintf "cn: custom"; mparse sprintf ""; for my $key ( keys %oleguid ) { my $value = $oleguid{$key}; mparse sprintf "dn: CN=%s,CN=default", $value; mparse sprintf "cn: %s", $value; mparse sprintf "name: %s", $key; mparse sprintf "oleguid: %s", $value; mparse ""; } @lines = split(/\n/, $contents); foreach $line (@lines) { $line =~ s/^\#+.*$//; if ($line) { @prop = split(/\s+/, $line); if ($prop[5] eq "MNID_ID" && $prop[7]) { mparse sprintf "dn: CN=%s,CN=%s,CN=default", $prop[2], $oleguid{$prop[6]}; mparse sprintf "objectClass: %s", $prop[5]; mparse sprintf "cn: %s", $prop[2]; mparse sprintf "canonical: %s", $prop[0]; mparse sprintf "oleguid: %s", $oleguid{$prop[6]}; mparse sprintf "mappedId: %d", hex($prop[7]); mparse sprintf "propId: %d", hex($prop[2]); mparse sprintf "propType: %s", $prop_names{$prop[4]}; mparse sprintf "oom: %s", $prop[1]; mparse sprintf ""; } elsif ($prop[5] eq "MNID_STRING" && $prop[7]) { mparse sprintf "dn: CN=%s,CN=%s,CN=default", $prop[3], $oleguid{$prop[6]}; mparse sprintf "objectClass: %s", $prop[5]; mparse sprintf "cn: %s", $prop[3]; mparse sprintf "canonical: %s", $prop[0]; mparse sprintf "oleguid: %s", $oleguid{$prop[6]}; mparse sprintf "mappedId: %d", hex($prop[7]); mparse sprintf "propId: 0"; mparse sprintf "propType: %s", $prop[4]; mparse sprintf "propName: %s", $prop[3]; mparse sprintf ""; } } } return $ret; } ##################################################################### # generate mapistore_nameid.h file sub mapistore_nameid_header($) { my $contents = shift; my $line; my @lines; my @prop; my $propID; my $proptype; my $property; my $counter = 0; mparse "/* header auto-generated by mparse */"; mparse "#ifndef __MAPISTORE_NAMEID_H__"; mparse "#define __MAPISTORE_NAMEID_H__"; mparse ""; @lines = split(/\n/, $contents); foreach $line (@lines) { $line =~ s/^\#+.*$//; if ($line) { @prop = split(/\s+/, $line); if ($prop[0] ne "NULL" && $prop[0] !~ m/^PidLidUnknownProperty/ && defined($prop[7])) { $proptype = $prop_names{$prop[4]}; my $propID = hex $prop[7]; $property = sprintf "0x%.8x", ($propID << 16) | $proptype; mparse sprintf "#define %-51s %s", $prop[0], $property; } } } mparse ""; mparse "#endif /* !MAPISTORE_NAMEID_H__ */"; return $ret; } sub process_file($) { my $mapi_file = shift; my $outputdir = $opt_outputdir; print "Parsing $mapi_file\n"; my $contents = FileLoad($mapi_file); defined $contents || return undef; if ($opt_parser eq "mapitags") { print "Generating $outputdir" . "mapitags.h\n"; my $parser = ("$outputdir/mapitags.h"); FileSave($parser, mapitags_header($contents)); print "Generating $outputdir" . "mapitags.c\n"; $ret = ''; my $code_parser = ("$outputdir/mapitags.c"); FileSave($code_parser, mapitags_interface($contents)); print "Generating mapitags_enum.h\n"; $ret = ''; my $enum_parser = ("mapitags_enum.h"); FileSave($enum_parser, mapitags_enum($contents)); } if ($opt_parser eq "mapicodes") { print "Generating $outputdir" . "mapicode.c\n"; $ret = ''; my $code_parser = ("$outputdir/mapicode.c"); FileSave($code_parser, mapicodes_interface($contents)); print "Generating mapicodes_enum.h\n"; $ret = ''; my $enum_parser = ("mapicodes_enum.h"); FileSave($enum_parser, mapicodes_enum($contents)); } if ($opt_parser eq "mapi_nameid") { print "Generating $outputdir" . "mapi_nameid_private.h\n"; $ret = ''; my $parser = ("$outputdir/mapi_nameid_private.h"); FileSave($parser, mapi_nameid_private_header($contents)); print "Generating $outputdir" . "mapi_nameid.h\n"; $ret = ''; my $nameid_parser = ("$outputdir/mapi_nameid.h"); FileSave($nameid_parser, mapi_nameid_header($contents)); } if ($opt_parser eq "codepage_lcid") { print "Generating $outputdir" . "codepage_lcid.c\n"; $ret = ''; my $code_parser = ("$outputdir/codepage_lcid.c"); FileSave($code_parser, codepage_lcid_interface($contents)); } if ($opt_parser eq "openchangedb_property") { print "Generating $outputdir" . "openchangedb_property.c\n"; my $openchangedb_parser = ("$outputdir/openchangedb_property.c"); FileSave($openchangedb_parser, openchangedb_property($contents)); } if ($opt_parser eq "mapistore_namedprops") { print "Generating $outputdir" . "mapistore_namedprops.ldif\n"; my $mapistore_parser = ("$outputdir/mapistore_namedprops.ldif"); FileSave($mapistore_parser, mapistore_namedprops($contents)); } if ($opt_parser eq "mapistore_nameid") { print "Generating $outputdir" . "mapistore_nameid.h\n"; my $mapistore_parser = ("$outputdir/mapistore_nameid.h"); FileSave($mapistore_parser, mapistore_nameid_header($contents)); } } process_file($_) foreach (@ARGV); openchange-2.0/libmapi/emsmdb.c000066400000000000000000001077401223057412600165250ustar00rootroot00000000000000/* OpenChange MAPI implementation. Copyright (C) Julien Kerihuel 2005 - 2011. Copyright (C) Jelmer Vernooij 2005. This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see . */ #include #include #include "libmapi/libmapi.h" #include "libmapi/libmapi_private.h" #include "gen_ndr/ndr_exchange.h" #include "gen_ndr/ndr_exchange_c.h" #include #include /** \file emsmdb.c \brief EMSMDB stack functions */ /** \details Hash a string and returns a unsigned integer hash value \param str the string to hash \return a hash value greater than 0 on success, otherwise 0 \note This function is based on the hash algorithm from gdbm and from Samba4 TDB code. */ static unsigned int emsmdb_hash(const char *str) { uint32_t value; /* Used to compute the hash value. */ uint32_t i; /* Used to cycle through random values. */ uint32_t len; /* Sanity check */ if (!str) return 0; len = strlen(str); /* Set the initial value from the key size. */ for (value = 0x238F13AF * len, i = 0; i < len; i++) value = (value + (str[i] << (i * 5 % 24))); return (1103515243 * value + 12345); } /** \details Establishes a new Session Context with the server on the exchange_emsmdb pipe \param parent_mem_ctx pointer to the memory context \param session pointer to the MAPI session context \param p pointer to the DCERPC pipe \param cred pointer to the user credentials \param return_value pointer on EcDoConnect MAPI return value \return an allocated emsmdb_context on success, otherwise NULL */ struct emsmdb_context *emsmdb_connect(TALLOC_CTX *parent_mem_ctx, struct mapi_session *session, struct dcerpc_pipe *p, struct cli_credentials *cred, int *return_value) { TALLOC_CTX *mem_ctx; struct EcDoConnect r; struct emsmdb_context *ret; NTSTATUS status; enum MAPISTATUS retval; uint32_t pullTimeStamp = 0; /* Sanity Checks */ if (!session) return NULL; if (!p) return NULL; if (!cred) return NULL; if (!return_value) return NULL; if (!session->profile->mailbox) return NULL; mem_ctx = talloc_named(parent_mem_ctx, 0, "emsmdb_connect"); ret = talloc_zero(parent_mem_ctx, struct emsmdb_context); ret->rpc_connection = p; ret->mem_ctx = parent_mem_ctx; ret->cache_requests = talloc(parent_mem_ctx, struct EcDoRpc_MAPI_REQ *); ret->info.szDisplayName = NULL; ret->info.szDNPrefix = NULL; r.in.szUserDN = session->profile->mailbox; r.in.ulFlags = 0x00000000; r.in.ulConMod = emsmdb_hash(r.in.szUserDN); r.in.cbLimit = 0x00000000; r.in.ulCpid = session->profile->codepage; r.in.ulLcidString = session->profile->language; r.in.ulLcidSort = session->profile->method; r.in.ulIcxrLink = 0xFFFFFFFF; r.in.usFCanConvertCodePages = 0x1; r.in.rgwClientVersion[0] = 0x000c; r.in.rgwClientVersion[1] = 0x183e; r.in.rgwClientVersion[2] = 0x03e8; r.in.pullTimeStamp = &pullTimeStamp; r.out.szDNPrefix = (const char **)&ret->info.szDNPrefix; r.out.szDisplayName = (const char **)&ret->info.szDisplayName; r.out.handle = &ret->handle; r.out.pcmsPollsMax = &ret->info.pcmsPollsMax; r.out.pcRetry = &ret->info.pcRetry; r.out.pcmsRetryDelay = &ret->info.pcmsRetryDelay; r.out.picxr = &ret->info.picxr; r.out.pullTimeStamp = &pullTimeStamp; status = dcerpc_EcDoConnect_r(p->binding_handle, mem_ctx, &r); retval = r.out.result; if (!NT_STATUS_IS_OK(status) || retval) { *return_value = retval; mapi_errstr("EcDoConnect", retval); talloc_free(mem_ctx); return NULL; } ret->info.szDNPrefix = talloc_steal(parent_mem_ctx, ret->info.szDNPrefix); ret->info.szDisplayName = talloc_steal(parent_mem_ctx, ret->info.szDisplayName); ret->info.rgwServerVersion[0] = r.out.rgwServerVersion[0]; ret->info.rgwServerVersion[1] = r.out.rgwServerVersion[1]; ret->info.rgwServerVersion[2] = r.out.rgwServerVersion[2]; ret->cred = cred; ret->max_data = 0xFFF0; ret->setup = false; talloc_free(mem_ctx); return ret; } /** \details Establishes a new Session Context with the server on the exchange_emsmdb pipe using 0xA EcDoConnectEx opnum \param mem_ctx pointer to the memory context \param session pointer to the MAPI session context \param p pointer to the DCERPC pipe \param cred pointer to the user credentials \param return_value pointer on EcDoConnectEx MAPI return value \return an allocated emsmdb_context structure on success, otherwise NULL */ struct emsmdb_context *emsmdb_connect_ex(TALLOC_CTX *mem_ctx, struct mapi_session *session, struct dcerpc_pipe *p, struct cli_credentials *cred, int *return_value) { TALLOC_CTX *tmp_ctx; struct EcDoConnectEx r; struct emsmdb_context *ctx; NTSTATUS status; enum MAPISTATUS retval; uint32_t pulTimeStamp = 0; uint32_t pcbAuxOut = 0x00001008; struct mapi2k7_AuxInfo *rgbAuxOut; /* Sanity Checks */ if (!session) return NULL; if (!p) return NULL; if (!cred) return NULL; if (!return_value) return NULL; tmp_ctx = talloc_named(mem_ctx, 0, "emsmdb_connect_ex"); ctx = talloc_zero(mem_ctx, struct emsmdb_context); ctx->rpc_connection = p; ctx->mem_ctx = mem_ctx; ctx->info.szDisplayName = NULL; ctx->info.szDNPrefix = NULL; r.out.handle = &ctx->handle; r.in.szUserDN = session->profile->mailbox; r.in.ulFlags = 0x00000000; r.in.ulConMod = emsmdb_hash(r.in.szUserDN); r.in.cbLimit = 0x00000000; r.in.ulCpid = session->profile->codepage; r.in.ulLcidString = session->profile->language; r.in.ulLcidSort = session->profile->method; r.in.ulIcxrLink = 0xFFFFFFFF; r.in.usFCanConvertCodePages = 0x1; r.out.szDNPrefix = (const char **) &ctx->info.szDNPrefix; r.out.szDisplayName = (const char **) &ctx->info.szDisplayName; r.out.pcmsPollsMax = &ctx->info.pcmsPollsMax; r.out.pcRetry = &ctx->info.pcRetry; r.out.pcmsRetryDelay = &ctx->info.pcmsRetryDelay; r.out.picxr = &ctx->info.picxr; r.out.pulTimeStamp = &pulTimeStamp; r.in.rgwClientVersion[0] = 0x000c; r.in.rgwClientVersion[1] = 0x183e; r.in.rgwClientVersion[2] = 0x03e8; r.in.pulTimeStamp = &pulTimeStamp; r.in.rgbAuxIn = NULL; r.in.cbAuxIn = 0x00000000; rgbAuxOut = talloc_zero(ctx->mem_ctx, struct mapi2k7_AuxInfo); rgbAuxOut->AUX_HEADER = NULL; r.out.rgbAuxOut = rgbAuxOut; r.in.pcbAuxOut = &pcbAuxOut; r.out.pcbAuxOut = &pcbAuxOut; status = dcerpc_EcDoConnectEx_r(p->binding_handle, tmp_ctx, &r); retval = r.out.result; if (!NT_STATUS_IS_OK(status) || retval) { *return_value = retval; mapi_errstr("EcDoConnectEx", retval); talloc_free(tmp_ctx); return NULL; } ctx->info.szDisplayName = talloc_steal(mem_ctx, ctx->info.szDisplayName); ctx->info.szDNPrefix = talloc_steal(mem_ctx, ctx->info.szDNPrefix); ctx->info.rgwServerVersion[0] = r.out.rgwServerVersion[0]; ctx->info.rgwServerVersion[1] = r.out.rgwServerVersion[1]; ctx->info.rgwServerVersion[2] = r.out.rgwServerVersion[2]; ctx->cred = cred; ctx->max_data = 0xFFF0; ctx->setup = false; talloc_free(tmp_ctx); return ctx; } /** \details Destructor for the EMSMDB context. Call the EcDoDisconnect function. \param data generic pointer to data with mapi_provider information \return MAPI_E_SUCCESS on success, otherwise -1 */ int emsmdb_disconnect_dtor(void *data) { struct mapi_provider *provider = (struct mapi_provider *)data; struct emsmdb_context *emsmdb_ctx; emsmdb_ctx = (struct emsmdb_context *)provider->ctx; if (!emsmdb_ctx) { return MAPI_E_SUCCESS; } emsmdb_disconnect(emsmdb_ctx); talloc_free(emsmdb_ctx->cache_requests); if (emsmdb_ctx->info.szDisplayName) { talloc_free(emsmdb_ctx->info.szDisplayName); } if (emsmdb_ctx->info.szDNPrefix) { talloc_free(emsmdb_ctx->info.szDNPrefix); } return MAPI_E_SUCCESS; } /** \details Destroy the EMSMDB context handle \param emsmdb_ctx pointer to the EMSMDB context \return MAPI_E_SUCCESS on success, otherwise MAPI error */ enum MAPISTATUS emsmdb_disconnect(struct emsmdb_context *emsmdb_ctx) { NTSTATUS status; enum MAPISTATUS retval; struct EcDoDisconnect r; /* Sanity Checks */ OPENCHANGE_RETVAL_IF(!emsmdb_ctx, MAPI_E_NOT_INITIALIZED, NULL); r.in.handle = r.out.handle = &emsmdb_ctx->handle; status = dcerpc_EcDoDisconnect_r(emsmdb_ctx->rpc_connection->binding_handle, emsmdb_ctx, &r); retval = r.out.result; OPENCHANGE_RETVAL_IF(!NT_STATUS_IS_OK(status), retval, NULL); OPENCHANGE_RETVAL_IF(retval, retval, NULL); return MAPI_E_SUCCESS; } /** \details Send an empty MAPI packet - useful to keep connection up or force notifications. \param emsmdb_ctx pointer to the EMSMDB connection context \param res pointer on pointer to a MAPI response structure \return NT_STATUS_OK on success, otherwise NT status error */ _PUBLIC_ NTSTATUS emsmdb_transaction_null(struct emsmdb_context *emsmdb_ctx, struct mapi_response **res) { struct EcDoRpc r; struct mapi_request *mapi_request; struct mapi_response *mapi_response; NTSTATUS status; uint16_t *length; /* Sanity checks */ if(!emsmdb_ctx) return NT_STATUS_INVALID_PARAMETER; if (!res) return NT_STATUS_INVALID_PARAMETER; mapi_request = talloc_zero(emsmdb_ctx->mem_ctx, struct mapi_request); mapi_response = talloc_zero(emsmdb_ctx->mem_ctx, struct mapi_response); r.in.mapi_request = mapi_request; r.in.mapi_request->mapi_len = 2; r.in.mapi_request->length = 2; r.in.handle = r.out.handle = &emsmdb_ctx->handle; r.in.size = emsmdb_ctx->max_data; r.in.offset = 0x0; r.in.max_data = emsmdb_ctx->max_data; length = talloc_zero(emsmdb_ctx->mem_ctx, uint16_t); *length = r.in.mapi_request->mapi_len; r.in.length = r.out.length = length; r.out.mapi_response = mapi_response; status = dcerpc_EcDoRpc_r(emsmdb_ctx->rpc_connection->binding_handle, emsmdb_ctx->mem_ctx, &r); if (!MAPI_STATUS_IS_OK(NT_STATUS_V(status))) { return status; } *res = mapi_response; return status; } static int mapi_response_destructor(void *data) { struct mapi_response *mapi_response = (struct mapi_response *)data; if (!mapi_response) return 0; if (mapi_response->mapi_repl) { if (mapi_response->handles) { talloc_free(mapi_response->handles); } if (!mapi_response->mapi_repl->error_code) { talloc_free(mapi_response->mapi_repl); } } return 0; } /** \details Make a EMSMDB transaction. \param emsmdb_ctx pointer to the EMSMDB connection context \param mem_ctx pointer to the memory context \param req pointer to the MAPI request to send \param repl pointer on pointer to the MAPI reply returned by the server \return NT_STATUS_OK on success, otherwise NT status error */ _PUBLIC_ NTSTATUS emsmdb_transaction(struct emsmdb_context *emsmdb_ctx, TALLOC_CTX *mem_ctx, struct mapi_request *req, struct mapi_response **repl) { struct EcDoRpc r; struct mapi_response *mapi_response; uint16_t *length; NTSTATUS status; struct EcDoRpc_MAPI_REQ *multi_req; uint8_t i = 0; start: r.in.handle = r.out.handle = &emsmdb_ctx->handle; r.in.size = emsmdb_ctx->max_data; r.in.offset = 0x0; mapi_response = talloc_zero(emsmdb_ctx->mem_ctx, struct mapi_response); mapi_response->mapi_repl = NULL; mapi_response->handles = NULL; talloc_set_destructor((void *)mapi_response, (int (*)(void *))mapi_response_destructor); r.out.mapi_response = mapi_response; /* process cached data */ if (emsmdb_ctx->cache_count) { multi_req = talloc_array(mem_ctx, struct EcDoRpc_MAPI_REQ, emsmdb_ctx->cache_count + 2); for (i = 0; i < emsmdb_ctx->cache_count; i++) { multi_req[i] = *emsmdb_ctx->cache_requests[i]; } multi_req[i] = req->mapi_req[0]; req->mapi_req = multi_req; } req->mapi_req = talloc_realloc(mem_ctx, req->mapi_req, struct EcDoRpc_MAPI_REQ, emsmdb_ctx->cache_count + 2); req->mapi_req[i+1].opnum = 0; r.in.mapi_request = req; r.in.mapi_request->mapi_len += emsmdb_ctx->cache_size; r.in.mapi_request->length += emsmdb_ctx->cache_size; length = talloc_zero(mem_ctx, uint16_t); *length = r.in.mapi_request->mapi_len; r.in.length = r.out.length = length; r.in.max_data = (*length >= 0x4000) ? 0x7FFF : emsmdb_ctx->max_data; status = dcerpc_EcDoRpc_r(emsmdb_ctx->rpc_connection->binding_handle, mem_ctx, &r); if (!NT_STATUS_IS_OK(status)) { if (emsmdb_ctx->setup == false) { errno = 0; emsmdb_ctx->max_data = 0x7FFF; emsmdb_ctx->setup = true; talloc_free(mapi_response); goto start; } else { talloc_free(mapi_response); return status; } } else { emsmdb_ctx->setup = true; } emsmdb_ctx->cache_size = emsmdb_ctx->cache_count = 0; if (r.out.mapi_response->mapi_repl && r.out.mapi_response->mapi_repl->error_code) { talloc_set_destructor((void *)mapi_response, NULL); r.out.mapi_response->handles = NULL; } *repl = r.out.mapi_response; return status; } /** \details Make a EMSMDB EXT2 transaction. \param emsmdb_ctx pointer to the EMSMDB connection context \param mem_ctx pointer to the memory context \param req pointer to the MAPI request to send \param repl pointer on pointer to the MAPI reply returned by the server \return NT_STATUS_OK on success, otherwise NT status error */ _PUBLIC_ NTSTATUS emsmdb_transaction_ext2(struct emsmdb_context *emsmdb_ctx, TALLOC_CTX *mem_ctx, struct mapi_request *req, struct mapi_response **repl) { NTSTATUS status; struct EcDoRpcExt2 r; struct mapi2k7_response mapi2k7_response; struct ndr_push *ndr_uncomp_rgbIn; struct ndr_push *ndr_comp_rgbIn; struct ndr_push *ndr_rgbIn; struct ndr_pull *ndr_pull = NULL; uint32_t pulFlags = 0x0; uint32_t pcbOut = 0x8007; uint32_t pcbAuxOut = 0x1008; uint32_t pulTransTime = 0; DATA_BLOB rgbOut; struct RPC_HEADER_EXT RPC_HEADER_EXT; r.in.handle = r.out.handle = &emsmdb_ctx->handle; r.in.pulFlags = r.out.pulFlags = &pulFlags; /* Step 1. Push mapi_request in a data blob */ ndr_uncomp_rgbIn = ndr_push_init_ctx(mem_ctx); ndr_set_flags(&ndr_uncomp_rgbIn->flags, LIBNDR_FLAG_NOALIGN); ndr_push_mapi_request(ndr_uncomp_rgbIn, NDR_SCALARS|NDR_BUFFERS, req); /* Step 2. Compress the blob */ /* ndr_comp_rgbIn = ndr_push_init_ctx(mem_ctx); */ /* ndr_push_lzxpress_compress(ndr_comp_rgbIn, ndr_uncomp_rgbIn); */ /* If the compressed blob is larger than the uncompressed one, use obfuscation */ /* if (ndr_comp_rgbIn->offset > ndr_uncomp_rgbIn->offset) { */ /* talloc_free(ndr_comp_rgbIn); */ ndr_comp_rgbIn = ndr_uncomp_rgbIn; obfuscate_data(ndr_comp_rgbIn->data, ndr_comp_rgbIn->offset, 0xA5); RPC_HEADER_EXT.Version = 0x0000; RPC_HEADER_EXT.Flags = RHEF_XorMagic|RHEF_Last; RPC_HEADER_EXT.Size = ndr_comp_rgbIn->offset; RPC_HEADER_EXT.SizeActual = ndr_comp_rgbIn->offset; ndr_rgbIn = ndr_push_init_ctx(mem_ctx); ndr_set_flags(&ndr_rgbIn->flags, LIBNDR_FLAG_NOALIGN); ndr_push_RPC_HEADER_EXT(ndr_rgbIn, NDR_SCALARS|NDR_BUFFERS, &RPC_HEADER_EXT); ndr_push_bytes(ndr_rgbIn, ndr_comp_rgbIn->data, ndr_comp_rgbIn->offset); /* } else { */ /* RPC_HEADER_EXT.Version = 0x0000; */ /* RPC_HEADER_EXT.Flags = RHEF_Compressed|RHEF_Last; */ /* RPC_HEADER_EXT.Size = ndr_comp_rgbIn->offset; */ /* RPC_HEADER_EXT.SizeActual = ndr_uncomp_rgbIn->offset; */ /* ndr_rgbIn = ndr_push_init_ctx(mem_ctx); */ /* ndr_set_flags(&ndr_rgbIn->flags, LIBNDR_FLAG_NOALIGN); */ /* ndr_push_RPC_HEADER_EXT(ndr_rgbIn, NDR_SCALARS|NDR_BUFFERS, &RPC_HEADER_EXT); */ /* ndr_push_bytes(ndr_rgbIn, ndr_comp_rgbIn->data, ndr_comp_rgbIn->offset); */ /* } */ /* Plain request (no obfuscation or compression) */ /* ndr_comp_rgbIn = ndr_uncomp_rgbIn; */ /* RPC_HEADER_EXT.Version = 0x0000; */ /* RPC_HEADER_EXT.Flags = RHEF_Last; */ /* RPC_HEADER_EXT.Size = ndr_uncomp_rgbIn->offset; */ /* RPC_HEADER_EXT.SizeActual = ndr_uncomp_rgbIn->offset; */ /* Pull the complete rgbIn */ /* ndr_rgbIn = ndr_push_init_ctx(mem_ctx); */ /* ndr_set_flags(&ndr_rgbIn->flags, LIBNDR_FLAG_NOALIGN); */ /* ndr_push_RPC_HEADER_EXT(ndr_rgbIn, NDR_SCALARS|NDR_BUFFERS, &RPC_HEADER_EXT); */ /* ndr_push_bytes(ndr_rgbIn, ndr_comp_rgbIn->data, ndr_comp_rgbIn->offset); */ r.in.rgbIn = ndr_rgbIn->data; r.in.cbIn = ndr_rgbIn->offset; r.in.pcbOut = r.out.pcbOut = &pcbOut; r.in.rgbAuxIn = NULL; r.in.cbAuxIn = 0; r.in.pcbAuxOut = r.out.pcbAuxOut = &pcbAuxOut; r.out.pulTransTime = &pulTransTime; status = dcerpc_EcDoRpcExt2_r(emsmdb_ctx->rpc_connection->binding_handle, mem_ctx, &r); talloc_free(ndr_rgbIn); talloc_free(ndr_comp_rgbIn); if (!NT_STATUS_IS_OK(status)) { return status; } else if (r.out.result) { return NT_STATUS_UNSUCCESSFUL; } /* Pull MAPI response form rgbOut */ rgbOut.data = r.out.rgbOut; rgbOut.length = *r.out.pcbOut; ndr_pull = ndr_pull_init_blob(&rgbOut, mem_ctx); ndr_set_flags(&ndr_pull->flags, LIBNDR_FLAG_NOALIGN|LIBNDR_FLAG_REF_ALLOC); ndr_pull_mapi2k7_response(ndr_pull, NDR_SCALARS|NDR_BUFFERS, &mapi2k7_response); *repl = mapi2k7_response.mapi_response; return status; } _PUBLIC_ NTSTATUS emsmdb_transaction_wrapper(struct mapi_session *session, TALLOC_CTX *mem_ctx, struct mapi_request *req, struct mapi_response **repl) { switch (session->profile->exchange_version) { case 0x0: return emsmdb_transaction((struct emsmdb_context *)session->emsmdb->ctx, mem_ctx, req, repl); case 0x1: case 0x2: return emsmdb_transaction_ext2((struct emsmdb_context *)session->emsmdb->ctx, mem_ctx, req, repl); break; } return NT_STATUS_OK; } /** \details Initialize the notify context structure and bind a local UDP port to receive notifications from the server \param mapi_ctx pointer to the MAPI context \param mem_ctx pointer to the memory context \return an allocated mapi_notify_ctx structure on success, otherwise NULL */ struct mapi_notify_ctx *emsmdb_bind_notification(struct mapi_context *mapi_ctx, TALLOC_CTX *mem_ctx) { struct interface *ifaces; struct mapi_notify_ctx *notify_ctx = NULL; unsigned short port = DFLT_NOTIF_PORT; const char *ipaddr = NULL; uint32_t attempt = 0; /* Sanity Checks */ if (!mapi_ctx) return NULL; if (!mapi_ctx->session) return NULL; if (!mapi_ctx->session->profile) return NULL; notify_ctx = talloc_zero(mem_ctx, struct mapi_notify_ctx); notify_ctx->notifications = talloc_zero((TALLOC_CTX *)notify_ctx, struct notifications); notify_ctx->notifications->prev = NULL; notify_ctx->notifications->next = NULL; load_interfaces(mem_ctx, lpcfg_interfaces(mapi_ctx->lp_ctx), &ifaces); ipaddr = iface_best_ip(ifaces, mapi_ctx->session->profile->server); if (!ipaddr) { talloc_free(notify_ctx->notifications); talloc_free(notify_ctx); return NULL; } notify_ctx->addr = talloc_zero(mem_ctx, struct sockaddr); notify_ctx->addr->sa_family = AF_INET; ((struct sockaddr_in *)(notify_ctx->addr))->sin_addr.s_addr = inet_addr(ipaddr); retry: if (attempt) port++; ((struct sockaddr_in *)(notify_ctx->addr))->sin_port = htons(port); notify_ctx->fd = socket(PF_INET, SOCK_DGRAM, IPPROTO_UDP); if (notify_ctx->fd == -1) { talloc_free(notify_ctx->notifications); talloc_free(notify_ctx->addr); talloc_free(notify_ctx); return NULL; } fcntl(notify_ctx->fd, F_SETFL, O_NONBLOCK); if (bind(notify_ctx->fd, notify_ctx->addr, sizeof(struct sockaddr)) == -1) { shutdown(notify_ctx->fd, SHUT_RDWR); close(notify_ctx->fd); if (attempt < 3) { attempt++; errno = 0; goto retry; } talloc_free(notify_ctx->notifications); talloc_free(notify_ctx->addr); talloc_free(notify_ctx); return NULL; } return notify_ctx; } /** \details Register for notifications on the server \param session Pointer to the current MAPI session \param notifkey The opaque client-generated context data \return NTSTATUS_OK on success, otherwise NT status error */ NTSTATUS emsmdb_register_notification(struct mapi_session *session, struct NOTIFKEY *notifkey) { struct EcRRegisterPushNotification request; NTSTATUS status; enum MAPISTATUS retval; TALLOC_CTX *mem_ctx; struct emsmdb_context *emsmdb_ctx; struct mapi_notify_ctx *notify_ctx; struct policy_handle handle; uint32_t hNotification = 0; /* Sanity Checks*/ if (!notifkey) return NT_STATUS_INVALID_PARAMETER; emsmdb_ctx = (struct emsmdb_context *)session->emsmdb->ctx; notify_ctx = (struct mapi_notify_ctx *)session->notify_ctx; mem_ctx = talloc_named(session, 0, "emsmdb_register_notification"); request.in.handle = &emsmdb_ctx->handle; request.in.iRpc = 0x0; request.in.cbContext = notifkey->cb; request.in.rgbContext = talloc_array(mem_ctx, uint8_t, request.in.cbContext); memcpy(request.in.rgbContext, notifkey->ab, request.in.cbContext); request.in.grbitAdviseBits = 0xffffffff; request.in.rgbCallbackAddress = talloc_array(mem_ctx, uint8_t, sizeof (struct sockaddr)); /* cp address family and length */ request.in.rgbCallbackAddress[0] = (notify_ctx->addr->sa_family & 0xFF); request.in.rgbCallbackAddress[1] = (notify_ctx->addr->sa_family & 0xFF00) >> 8; memcpy(&request.in.rgbCallbackAddress[2], notify_ctx->addr->sa_data, 14); request.in.cbCallbackAddress = sizeof (struct sockaddr); request.out.handle = &handle; request.out.hNotification = &hNotification; status = dcerpc_EcRRegisterPushNotification_r(emsmdb_ctx->rpc_connection->binding_handle, emsmdb_ctx->mem_ctx, &request); retval = request.out.result; if (!NT_STATUS_IS_OK(status) || retval) { status = NT_STATUS_RPC_CALL_FAILED; } talloc_free(mem_ctx); return status; } /** \details Retrieves the EMSMDB context server information structure \param session pointer to the MAPI session context \return the server info structure on success, otherwise NULL */ _PUBLIC_ struct emsmdb_info *emsmdb_get_info(struct mapi_session *session) { if (!session->emsmdb->ctx) { return NULL; } return &((struct emsmdb_context *)session->emsmdb->ctx)->info; } /** \details Free property values retrieved with pull_emsmdb_property \param lpProp pointer to SPropValue structure \param data generic pointer to associated lpProp data */ void free_emsmdb_property(struct SPropValue *lpProp, void *data) { if (!data) return; if (!lpProp) return; switch (lpProp->ulPropTag & 0xFFFF) { case PT_I2: talloc_free((uint16_t *)data); break; case PT_ERROR: case PT_LONG: talloc_free((uint32_t *)data); break; case PT_I8: talloc_free((uint64_t *)data); break; case PT_BOOLEAN: talloc_free((uint8_t *)data); break; default: break; } } /** \details Retrieves a property value from a DATA blob \param mem_ctx pointer to the memory context \param offset pointer on pointer to the current offset \param tag the property tag which value is to be retrieved \param data pointer to the data \return pointer on constant generic data on success, otherwise NULL */ const void *pull_emsmdb_property(TALLOC_CTX *mem_ctx, uint32_t *offset, enum MAPITAGS tag, DATA_BLOB *data) { struct ndr_pull *ndr; const char *pt_string8 = NULL; const char *pt_unicode = NULL; uint16_t *pt_i2 = NULL; uint64_t *pt_i8 = NULL; uint32_t *pt_long = NULL; uint8_t *pt_boolean = NULL; double *pt_double = NULL; struct FILETIME *pt_filetime = NULL; struct GUID *pt_clsid = NULL; struct SBinary_short pt_binary; struct Binary_r *sbin = NULL; struct mapi_SLPSTRArray pt_slpstr; struct StringArray_r *slpstr = NULL; struct mapi_SLPSTRArrayW pt_slpstrw; struct StringArrayW_r *slpstrw = NULL; struct mapi_MV_LONG_STRUCT pt_MVl; struct LongArray_r *MVl = NULL; struct mapi_SBinaryArray pt_MVbin; struct BinaryArray_r *MVbin = NULL; uint32_t i; ndr = talloc_zero(mem_ctx, struct ndr_pull); ndr->offset = *offset; ndr->data = data->data; ndr->data_size = data->length; ndr_set_flags(&ndr->flags, LIBNDR_FLAG_NOALIGN); switch(tag & 0xFFFF) { case PT_I2: pt_i2 = talloc_zero(mem_ctx, uint16_t); ndr_pull_uint16(ndr, NDR_SCALARS, pt_i2); *offset = ndr->offset; talloc_free(ndr); return (const void *) pt_i2; case PT_ERROR: case PT_LONG: pt_long = talloc_zero(mem_ctx, uint32_t); ndr_pull_uint32(ndr, NDR_SCALARS, pt_long); *offset = ndr->offset; talloc_free(ndr); return (const void *) pt_long; case PT_BOOLEAN: pt_boolean = talloc_zero(mem_ctx, uint8_t); ndr_pull_uint8(ndr, NDR_SCALARS, pt_boolean); *offset = ndr->offset; talloc_free(ndr); return (const void *) pt_boolean; case PT_I8: pt_i8 = talloc_zero(mem_ctx, uint64_t); ndr_pull_hyper(ndr, NDR_SCALARS, pt_i8); *offset = ndr->offset; talloc_free(ndr); return (const void *) pt_i8; case PT_DOUBLE: pt_double = talloc_zero(mem_ctx, double); ndr_pull_double(ndr, NDR_SCALARS, pt_double); *offset = ndr->offset; talloc_free(ndr); return (const void *) pt_double; case PT_UNICODE: ndr_set_flags(&ndr->flags, LIBNDR_FLAG_STR_NULLTERM); ndr_pull_string(ndr, NDR_SCALARS, &pt_unicode); *offset = ndr->offset; talloc_free(ndr); return (const void *) pt_unicode; case PT_STRING8: ndr_set_flags(&ndr->flags, LIBNDR_FLAG_STR_RAW8|LIBNDR_FLAG_STR_NULLTERM); ndr_pull_string(ndr, NDR_SCALARS, &pt_string8); *offset = ndr->offset; talloc_free(ndr); return (const void *) pt_string8; case PT_SYSTIME: pt_filetime = talloc_zero(mem_ctx, struct FILETIME); ndr_pull_hyper(ndr, NDR_SCALARS, (uint64_t *) pt_filetime); *offset = ndr->offset; talloc_free(ndr); return (const void *) pt_filetime; case PT_CLSID: pt_clsid = talloc_zero(mem_ctx, struct GUID); ndr_pull_GUID(ndr, NDR_SCALARS, pt_clsid); *offset = ndr->offset; talloc_free(ndr); return (const void *) pt_clsid; case 0xFB: case PT_BINARY: ndr_pull_SBinary_short(ndr, NDR_SCALARS, &pt_binary); *offset = ndr->offset; sbin = talloc_zero(mem_ctx, struct Binary_r); sbin->cb = pt_binary.cb; sbin->lpb = (uint8_t *)talloc_memdup(sbin, pt_binary.lpb, pt_binary.cb); talloc_free(ndr); return (const void *) sbin; case PT_MV_LONG: ndr_pull_mapi_MV_LONG_STRUCT(ndr, NDR_SCALARS, &pt_MVl); *offset = ndr->offset; MVl = talloc_zero(mem_ctx, struct LongArray_r); MVl->cValues = pt_MVl.cValues; MVl->lpl = talloc_array(mem_ctx, uint32_t, pt_MVl.cValues); for (i = 0; i < MVl->cValues; i++) { MVl->lpl[i] = pt_MVl.lpl[i]; } talloc_free(ndr); return (const void *) MVl; case PT_MV_STRING8: ndr_pull_mapi_SLPSTRArray(ndr, NDR_SCALARS, &pt_slpstr); *offset = ndr->offset; slpstr = talloc_zero(mem_ctx, struct StringArray_r); slpstr->cValues = pt_slpstr.cValues; slpstr->lppszA = talloc_array(mem_ctx, const char *, pt_slpstr.cValues); for (i = 0; i < slpstr->cValues; i++) { slpstr->lppszA[i] = talloc_strdup(mem_ctx, pt_slpstr.strings[i].lppszA); } talloc_free(ndr); return (const void *) slpstr; case PT_MV_UNICODE: ndr_pull_mapi_SLPSTRArrayW(ndr, NDR_SCALARS, &pt_slpstrw); *offset = ndr->offset; slpstrw = talloc_zero(mem_ctx, struct StringArrayW_r); slpstrw->cValues = pt_slpstrw.cValues; slpstrw->lppszW = talloc_array(mem_ctx, const char *, pt_slpstrw.cValues); for (i = 0; i < slpstrw->cValues; i++) { slpstrw->lppszW[i] = talloc_strdup(mem_ctx, pt_slpstrw.strings[i].lppszW); } talloc_free(ndr); return (const void *) slpstrw; case PT_MV_BINARY: ndr_pull_mapi_SBinaryArray(ndr, NDR_SCALARS, &pt_MVbin); *offset = ndr->offset; MVbin = talloc_zero(mem_ctx, struct BinaryArray_r); MVbin->cValues = pt_MVbin.cValues; MVbin->lpbin = talloc_array(mem_ctx, struct Binary_r, pt_MVbin.cValues); for (i = 0; i < MVbin->cValues; i++) { MVbin->lpbin[i].cb = pt_MVbin.bin[i].cb; MVbin->lpbin[i].lpb = (uint8_t *)talloc_size(mem_ctx, MVbin->lpbin[i].cb); memcpy(MVbin->lpbin[i].lpb, pt_MVbin.bin[i].lpb, MVbin->lpbin[i].cb); } talloc_free(ndr); return (const void *) MVbin; default: fprintf (stderr, "unhandled type case in pull_emsmdb_property(): 0x%x\n", (tag & 0xFFFF)); return NULL; } } /** \details Get a SPropValue array from a DATA blob \param mem_ctx pointer to the memory context \param content pointer to the DATA blob content \param tags pointer to a list of property tags to lookup \param propvals pointer on pointer to the returned SPropValues \param cn_propvals pointer to the number of propvals \param flag describes the type data \return MAPI_E_SUCCESS on success */ enum MAPISTATUS emsmdb_get_SPropValue(TALLOC_CTX *mem_ctx, DATA_BLOB *content, struct SPropTagArray *tags, struct SPropValue **propvals, uint32_t *cn_propvals, uint8_t flag) { struct SPropValue *p_propval; uint32_t i_propval; uint32_t i_tag; int proptag; uint32_t cn_tags; uint32_t offset = 0; const void *data; i_propval = 0; cn_tags = tags->cValues; *cn_propvals = 0; *propvals = talloc_array(mem_ctx, struct SPropValue, cn_tags + 1); for (i_tag = 0; i_tag < cn_tags; i_tag++) { if (flag) { if (((uint8_t)(*(content->data + offset))) == PT_ERROR) { proptag = (int)tags->aulPropTag[i_tag]; proptag &= 0xFFFF0000; proptag |= PT_ERROR; tags->aulPropTag[i_tag] = (enum MAPITAGS) proptag; } offset += sizeof (uint8_t); } data = pull_emsmdb_property(mem_ctx, &offset, tags->aulPropTag[i_tag], content); if (data) { data = talloc_steal(*propvals, data); p_propval = &((*propvals)[i_propval]); p_propval->ulPropTag = tags->aulPropTag[i_tag]; p_propval->dwAlignPad = 0x0; set_SPropValue(p_propval, data); free_emsmdb_property(p_propval, (void *) data); i_propval++; } } (*propvals)[i_propval].ulPropTag = (enum MAPITAGS) 0x0; *cn_propvals = i_propval; return MAPI_E_SUCCESS; } /** \details Get a SRowSet from a DATA blob \param mem_ctx pointer on the memory context \param rowset pointer on the returned SRowSe \param proptags pointer on a list of property tags to lookup \param content pointer on the DATA blob content \return MAPI_E_SUCCESS on success \note TODO: this doesn't yet handle the TypedPropertyValue and FlaggedPropertyValueWithTypeSpecified variants */ _PUBLIC_ void emsmdb_get_SRowSet(TALLOC_CTX *mem_ctx, struct SRowSet *rowset, struct SPropTagArray *proptags, DATA_BLOB *content) { struct SRow *rows; struct SPropValue *lpProps; int proptag; uint32_t idx; uint32_t prop; uint32_t offset = 0; const void *data; uint32_t row_count; bool is_FlaggedPropertyRow = false; bool havePropertyValue; uint8_t flag; /* caller allocated */ rows = rowset->aRow; row_count = rowset->cRows; for (idx = 0; idx < row_count; idx++) { if (0x1 == *(content->data + offset)) { is_FlaggedPropertyRow = true; } else { is_FlaggedPropertyRow = false; } ++offset; lpProps = talloc_array(mem_ctx, struct SPropValue, proptags->cValues); for (prop = 0; prop < proptags->cValues; prop++) { havePropertyValue = true; lpProps[prop].ulPropTag = proptags->aulPropTag[prop]; if (is_FlaggedPropertyRow) { flag = (uint8_t)(*(content->data + offset)); ++offset; /* advance offset for the flag */ switch (flag) { case 0x0: /* Property Value is valid */ break; case 0x1: /* Property Value is not present */ havePropertyValue = false; break; case PT_ERROR: lpProps[prop].ulPropTag = proptags->aulPropTag[prop]; proptag = (int) lpProps[prop].ulPropTag; proptag &= 0xFFFF0000; proptag |= PT_ERROR; lpProps[prop].ulPropTag = (enum MAPITAGS) proptag; break; default: /* unknown FlaggedPropertyValue flag */ break; } } if (havePropertyValue) { lpProps[prop].dwAlignPad = 0x0; data = pull_emsmdb_property(mem_ctx, &offset, lpProps[prop].ulPropTag, content); talloc_steal(lpProps, data); set_SPropValue(&lpProps[prop], data); free_emsmdb_property(&lpProps[prop], (void *) data); } } rows[idx].ulAdrEntryPad = 0; rows[idx].cValues = proptags->cValues; rows[idx].lpProps = lpProps; } } /** \details Get a SRow from a DATA blob \param mem_ctx pointer on the memory context \param aRow pointer on the returned SRow \param proptags pointer on a list of property tags to lookup \param propcount number of SPropValue entries in aRow \param content pointer on the DATA blob content \param flag the type data \param align alignment pad \return MAPI_E_SUCCESS on success \note TODO: We shouldn't have any alignment pad here */ void emsmdb_get_SRow(TALLOC_CTX *mem_ctx, struct SRow *aRow, struct SPropTagArray *proptags, uint16_t propcount, DATA_BLOB *content, uint8_t flag, uint8_t align) { uint32_t i; uint32_t offset = 0; enum MAPITAGS aulPropTag = (enum MAPITAGS) 0; int proptag; const void *data; aRow->cValues = propcount; aRow->lpProps = talloc_array(mem_ctx, struct SPropValue, propcount); for (i = 0; i < propcount; i++) { aulPropTag = proptags->aulPropTag[i]; if (flag) { if (((uint8_t)(*(content->data + offset))) == PT_ERROR) { proptag = (int) aulPropTag; proptag &= 0xFFFF0000; proptag |= 0xA; aulPropTag = (enum MAPITAGS)proptag; } offset += align; } data = pull_emsmdb_property(mem_ctx, &offset, aulPropTag, content); talloc_steal(aRow->lpProps, data); aRow->lpProps[i].ulPropTag = aulPropTag; aRow->lpProps[i].dwAlignPad = 0x0; set_SPropValue(&(aRow->lpProps[i]), data); free_emsmdb_property(&aRow->lpProps[i], (void *) data); } if (align) { offset += align; } } /** \details Get an async notification context handle \param emsmdb_ctx pointer to the EMSMDB context \return MAPI_E_SUCCESS on success, otherwise MAPI error */ enum MAPISTATUS emsmdb_async_connect(struct emsmdb_context *emsmdb_ctx) { NTSTATUS status; enum MAPISTATUS retval; struct EcDoAsyncConnectEx r; /* Sanity Checks */ OPENCHANGE_RETVAL_IF(!emsmdb_ctx, MAPI_E_NOT_INITIALIZED, NULL); r.in.handle = &(emsmdb_ctx->handle); r.out.async_handle = &(emsmdb_ctx->async_handle); status = dcerpc_EcDoAsyncConnectEx_r(emsmdb_ctx->rpc_connection->binding_handle, emsmdb_ctx->mem_ctx, &r); retval = r.out.result; OPENCHANGE_RETVAL_IF(!NT_STATUS_IS_OK(status), retval, NULL); OPENCHANGE_RETVAL_IF(retval, retval, NULL); return MAPI_E_SUCCESS; } bool server_version_at_least(struct emsmdb_context *ctx, uint16_t major_ver, uint16_t minor_ver, uint16_t major_build, uint16_t minor_build) { /* See MS-OXCRPC Section 3.1.9 to understand this */ uint16_t normalisedword0; uint16_t normalisedword1; uint16_t normalisedword2; uint16_t normalisedword3; if (ctx->info.rgwServerVersion[1] & 0x8000) { /* new format */ normalisedword0 = (ctx->info.rgwServerVersion[0] & 0xFF00) >> 8; normalisedword1 = (ctx->info.rgwServerVersion[0] & 0x00FF); normalisedword2 = (ctx->info.rgwServerVersion[1] & 0x7FFF); normalisedword3 = ctx->info.rgwServerVersion[2]; } else { normalisedword0 = ctx->info.rgwServerVersion[0]; normalisedword1 = 0; normalisedword2 = ctx->info.rgwServerVersion[1]; normalisedword3 = ctx->info.rgwServerVersion[2]; } if (normalisedword0 < major_ver) { /* the server major version is less than the minimum we wanted */ return false; } if (normalisedword0 > major_ver) { /* the server major version is greater than we wanted */ return true; } /* the server major number matches the minimum we wanted, so proceed to check further */ if (normalisedword1 < minor_ver) { /* major numbers match, but minor version was too low */ return false; } if (normalisedword1 > minor_ver) { /* major numbers match, and minor number was greater, so thats enough */ return true; } /* both major and minor versions match, start testing build numbers */ if (normalisedword2 < major_build) { /* major and minor numbers match, build number less than required */ return false; } if (normalisedword2 > major_build) { /* major and minor numbers match, build number was greater */ return true; } /* major and minor versions and major build numbers match */ if (normalisedword3 < minor_build) { /* not quite high enough */ return false; } /* if we get here, then major and minor build numbers match, major build matches and minor build was greater than or equal to that required */ return true; } openchange-2.0/libmapi/emsmdb.h000066400000000000000000000031711223057412600165230ustar00rootroot00000000000000/* OpenChange MAPI implementation. Copyright (C) Jelmer Vernooij 2005. Copyright (C) Julien Kerihuel 2008. This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see . */ #ifndef __EMSMDB_H__ #define __EMSMDB_H__ struct emsmdb_info { char *szDisplayName; char *szDNPrefix; uint32_t pcmsPollsMax; uint32_t pcRetry; uint32_t pcmsRetryDelay; uint32_t picxr; uint16_t rgwServerVersion[3]; }; struct emsmdb_context { struct dcerpc_pipe *rpc_connection; struct policy_handle handle; struct nspi_context *nspi; struct cli_credentials *cred; TALLOC_CTX *mem_ctx; struct EcDoRpc_MAPI_REQ **cache_requests; uint32_t cache_size; uint8_t cache_count; uint16_t prop_count; enum MAPITAGS *properties; uint16_t max_data; bool setup; struct emsmdb_info info; struct policy_handle async_handle; ///< The handle to use for Async notification requests struct dcerpc_pipe *async_rpc_connection; }; #define MAILBOX_PATH "/o=%s/ou=%s/cn=Recipients/cn=%s" #endif /* __EMSMDB_H__ */ openchange-2.0/libmapi/freebusy.c000066400000000000000000000266471223057412600171100ustar00rootroot00000000000000/* OpenChange MAPI implementation. Copyright (C) Julien Kerihuel 2007-2011. This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see . */ #include "libmapi/libmapi.h" #include "libmapi/libmapi_private.h" #include #include /** \file freebusy.c \brief Convenient API to access FreeBusy */ /** \details Retrieve FreeBusy data associated with the specified recipient \param obj_store pointer to the public folder MAPI object \param recipient name of the recipient to fetch freebusy data \param pSRow pointer to the returned properties \note The function returns a SRow structure with the following property tags: -# PR_NORMALIZED_SUBJECT -# PR_FREEBUSY_RANGE_TIMESTAMP -# PR_FREEBUSY_PUBLISH_START -# PR_FREEBUSY_PUBLISH_END -# PR_SCHDINFO_MONTHS_MERGED -# PR_SCHDINFO_FREEBUSY_MERGED -# PR_SCHDINFO_MONTHS_TENTATIVE -# PR_SCHDINFO_FREEBUSY_TENTATIVE -# PR_SCHDINFO_MONTHS_BUSY -# PR_SCHDINFO_FREEBUSY_BUSY -# PR_SCHDINFO_MONTHS_OOF -# PR_SCHDINFO_FREEBUSY_OOF \return MAPI_E_SUCCESS on success, otherwise MAPI error */ _PUBLIC_ enum MAPISTATUS GetUserFreeBusyData(mapi_object_t *obj_store, const char *recipient, struct SRow *pSRow) { enum MAPISTATUS retval; TALLOC_CTX *mem_ctx; struct mapi_session *session; mapi_id_t id_freebusy; mapi_object_t obj_freebusy; mapi_object_t obj_exfreebusy; mapi_object_t obj_message; mapi_object_t obj_htable; mapi_object_t obj_ctable; struct PropertyRowSet_r *pRowSet; struct SRowSet SRowSet; struct SPropValue *lpProps; struct mapi_SRestriction res; struct SSortOrderSet criteria; struct SPropTagArray *SPropTagArray = NULL; char *message_name; char *folder_name; const char *email = NULL; char *o = NULL; char *ou = NULL; char *username; const uint64_t *fid; const uint64_t *mid; uint32_t i; uint32_t count; /* Sanity checks */ OPENCHANGE_RETVAL_IF(!obj_store, MAPI_E_INVALID_PARAMETER, NULL); OPENCHANGE_RETVAL_IF(!recipient, MAPI_E_INVALID_PARAMETER, NULL); OPENCHANGE_RETVAL_IF(!pSRow, MAPI_E_INVALID_PARAMETER, NULL); session = mapi_object_get_session(obj_store); OPENCHANGE_RETVAL_IF(!session, MAPI_E_SESSION_LIMIT, NULL); mem_ctx = (TALLOC_CTX *) session; /* Step 0. Retrieve the user Email Address and build FreeBusy strings */ pRowSet = talloc_zero(mem_ctx, struct PropertyRowSet_r); retval = GetABRecipientInfo(session, recipient, NULL, &pRowSet); OPENCHANGE_RETVAL_IF(retval, retval, pRowSet); email = (const char *) get_PropertyValue_PropertyRowSet_data(pRowSet, PR_EMAIL_ADDRESS_UNICODE); o = x500_get_dn_element(mem_ctx, email, ORG); ou = x500_get_dn_element(mem_ctx, email, ORG_UNIT); username = x500_get_dn_element(mem_ctx, email, "/cn=Recipients/cn="); if (!username) { MAPIFreeBuffer(o); MAPIFreeBuffer(ou); MAPIFreeBuffer(pRowSet); return MAPI_E_NOT_FOUND; } /* toupper username */ for (i = 0; username[i]; i++) { username[i] = toupper((unsigned char)username[i]); } message_name = talloc_asprintf(mem_ctx, FREEBUSY_USER, username); folder_name = talloc_asprintf(mem_ctx, FREEBUSY_FOLDER, o, ou); MAPIFreeBuffer(username); MAPIFreeBuffer(o); MAPIFreeBuffer(ou); MAPIFreeBuffer(pRowSet); /* Step 1. Open the FreeBusy root folder */ retval = GetDefaultPublicFolder(obj_store, &id_freebusy, olFolderPublicFreeBusyRoot); OPENCHANGE_RETVAL_IF(retval, retval, NULL); mapi_object_init(&obj_freebusy); retval = OpenFolder(obj_store, id_freebusy, &obj_freebusy); OPENCHANGE_RETVAL_IF(retval, retval, NULL); /* Step 2. Open the hierarchy table */ mapi_object_init(&obj_htable); retval = GetHierarchyTable(&obj_freebusy, &obj_htable, 0, NULL); OPENCHANGE_RETVAL_IF(retval, retval, NULL); /* Step 3. Customize Hierarchy Table view */ SPropTagArray = set_SPropTagArray(mem_ctx, 0x2, PR_FID, PR_DISPLAY_NAME); retval = SetColumns(&obj_htable, SPropTagArray); MAPIFreeBuffer(SPropTagArray); OPENCHANGE_RETVAL_IF(retval, retval, NULL); /* Step 4. Find FreeBusy folder row */ res.rt = RES_PROPERTY; res.res.resProperty.relop = RELOP_EQ; res.res.resProperty.ulPropTag = PR_DISPLAY_NAME; res.res.resProperty.lpProp.ulPropTag = PR_DISPLAY_NAME; res.res.resProperty.lpProp.value.lpszA = folder_name; retval = FindRow(&obj_htable, &res, BOOKMARK_BEGINNING, DIR_FORWARD, &SRowSet); MAPIFreeBuffer(folder_name); OPENCHANGE_RETVAL_IF(retval, retval, NULL); /* Step 5. Open the folder */ fid = (const uint64_t *) get_SPropValue_SRowSet_data(&SRowSet, PR_FID); if (!fid || *fid == MAPI_E_NOT_FOUND) return MAPI_E_NOT_FOUND; mapi_object_init(&obj_exfreebusy); retval = OpenFolder(&obj_freebusy, *fid, &obj_exfreebusy); OPENCHANGE_RETVAL_IF(retval, retval, NULL); /* Step 6. Open the contents table */ mapi_object_init(&obj_ctable); retval = GetContentsTable(&obj_exfreebusy, &obj_ctable, 0, NULL); OPENCHANGE_RETVAL_IF(retval, retval, NULL); /* Step 7. Customize Contents Table view */ SPropTagArray = set_SPropTagArray(mem_ctx, 0x5, PR_FID, PR_MID, PR_ADDRBOOK_MID, PR_INSTANCE_NUM, PR_NORMALIZED_SUBJECT); retval = SetColumns(&obj_ctable, SPropTagArray); MAPIFreeBuffer(SPropTagArray); OPENCHANGE_RETVAL_IF(retval, retval, NULL); /* Step 8. Sort the table */ memset(&criteria, 0x0, sizeof (struct SSortOrderSet)); criteria.cSorts = 1; criteria.aSort = talloc_array(mem_ctx, struct SSortOrder, criteria.cSorts); criteria.aSort[0].ulPropTag = PR_NORMALIZED_SUBJECT; criteria.aSort[0].ulOrder = TABLE_SORT_ASCEND; retval = SortTable(&obj_ctable, &criteria); MAPIFreeBuffer(criteria.aSort); OPENCHANGE_RETVAL_IF(retval, retval, NULL); /* Step 9. Find the user FreeBusy message row */ res.rt = RES_PROPERTY; res.res.resProperty.relop = RELOP_EQ; res.res.resProperty.ulPropTag = PR_NORMALIZED_SUBJECT; res.res.resProperty.lpProp.ulPropTag = PR_NORMALIZED_SUBJECT; res.res.resProperty.lpProp.value.lpszA = message_name; retval = FindRow(&obj_ctable, &res, BOOKMARK_BEGINNING, DIR_FORWARD, &SRowSet); MAPIFreeBuffer(message_name); OPENCHANGE_RETVAL_IF(retval, retval, NULL); /* Step 10. Open the message */ fid = (const uint64_t *)get_SPropValue_SRowSet_data(&SRowSet, PR_FID); mid = (const uint64_t *)get_SPropValue_SRowSet_data(&SRowSet, PR_MID); OPENCHANGE_RETVAL_IF(!fid || *fid == MAPI_E_NOT_FOUND, MAPI_E_NOT_FOUND, NULL); OPENCHANGE_RETVAL_IF(!mid || *mid == MAPI_E_NOT_FOUND, MAPI_E_NOT_FOUND, NULL); mapi_object_init(&obj_message); retval = OpenMessage(obj_store, *fid, *mid, &obj_message, 0x0); OPENCHANGE_RETVAL_IF(retval, retval, NULL); /* Step 11. Get FreeBusy properties */ SPropTagArray = set_SPropTagArray(mem_ctx, 0xc, PR_NORMALIZED_SUBJECT, PR_FREEBUSY_RANGE_TIMESTAMP, PR_FREEBUSY_PUBLISH_START, PR_FREEBUSY_PUBLISH_END, PR_SCHDINFO_MONTHS_MERGED, PR_SCHDINFO_FREEBUSY_MERGED, PR_SCHDINFO_MONTHS_TENTATIVE, PR_SCHDINFO_FREEBUSY_TENTATIVE, PR_SCHDINFO_MONTHS_BUSY, PR_SCHDINFO_FREEBUSY_BUSY, PR_SCHDINFO_MONTHS_OOF, PR_SCHDINFO_FREEBUSY_OOF); retval = GetProps(&obj_message, 0, SPropTagArray, &lpProps, &count); MAPIFreeBuffer(SPropTagArray); OPENCHANGE_RETVAL_IF(retval, retval, NULL); pSRow->cValues = count; pSRow->lpProps = lpProps; mapi_object_release(&obj_message); mapi_object_release(&obj_ctable); mapi_object_release(&obj_exfreebusy); mapi_object_release(&obj_htable); mapi_object_release(&obj_freebusy); return MAPI_E_SUCCESS; } /** \details Check if a date conflicts with existing FreeBusy Busy/Out Of Office events \param obj_store pointer to the public folder MAPI object \param date pointer to the date to check \param conflict pointer to the returned boolean value \return MAPI_E_SUCCESS on success, otherwise MAPI error */ _PUBLIC_ enum MAPISTATUS IsFreeBusyConflict(mapi_object_t *obj_store, struct FILETIME *date, bool *conflict) { enum MAPISTATUS retval; struct mapi_session *session; struct SRow aRow; const struct LongArray_r *all_months; const struct BinaryArray_r *all_events; struct Binary_r bin; const uint32_t *publish_start; NTTIME nttime; time_t time; struct tm *tm; uint32_t fbusytime; uint32_t fmonth; uint32_t month; int year; uint32_t idx; uint32_t i; bool found = false; uint32_t start; uint32_t end; /* Sanity checks */ OPENCHANGE_RETVAL_IF(!obj_store, MAPI_E_INVALID_PARAMETER, NULL); OPENCHANGE_RETVAL_IF(!date, MAPI_E_INVALID_PARAMETER, NULL); OPENCHANGE_RETVAL_IF(!conflict, MAPI_E_INVALID_PARAMETER, NULL); session = mapi_object_get_session(obj_store); OPENCHANGE_RETVAL_IF(!session, MAPI_E_SESSION_LIMIT, NULL); *conflict = false; /* Step 1. Retrieve the freebusy data for the user */ retval = GetUserFreeBusyData(obj_store, session->profile->username, &aRow); OPENCHANGE_RETVAL_IF(retval, retval, NULL); publish_start = (const uint32_t *) find_SPropValue_data(&aRow, PR_FREEBUSY_PUBLISH_START); all_months = (const struct LongArray_r *) find_SPropValue_data(&aRow, PR_SCHDINFO_MONTHS_MERGED); all_events = (const struct BinaryArray_r *) find_SPropValue_data(&aRow, PR_SCHDINFO_FREEBUSY_MERGED); if (!all_months || (*(const uint32_t *)all_months) == MAPI_E_NOT_FOUND || !all_events || (*(const uint32_t *)all_events) == MAPI_E_NOT_FOUND) { return MAPI_E_SUCCESS; } /* Step 2. Convert the input date to freebusy */ nttime = ((uint64_t) date->dwHighDateTime << 32); nttime |= (uint64_t) date->dwLowDateTime; time = nt_time_to_unix(nttime); tm = localtime(&time); fmonth = tm->tm_mon + 1; fbusytime = ((tm->tm_mday - 1) * 60 * 24) + (tm->tm_hour * 60); /* Step 3. Check if the years matches */ year = GetFreeBusyYear(publish_start); if (year != (tm->tm_year + 1900)) { return MAPI_E_SUCCESS; } /* Step 4. Check if we have already registered events for the month */ for (idx = 0; idx < all_months->cValues; idx++) { month = all_months->lpl[idx] - (year * 16); if (month == fmonth) { found = true; break; } } if (found == false) return MAPI_E_SUCCESS; /* Step 5. Check if one this months events conflicts with the date */ bin = all_events->lpbin[idx]; if (bin.cb % 4) { return MAPI_E_INVALID_PARAMETER; } for (i = 0; i < bin.cb; i += 4) { start = (bin.lpb[i + 1] << 8) | bin.lpb[i]; end = (bin.lpb[i + 3] << 8) | bin.lpb[i + 2]; if ((fbusytime >= start) && (fbusytime <= end)) { *conflict = true; return MAPI_E_SUCCESS; } } return MAPI_E_SUCCESS; } /** \details Return the year associated with the FreeBusy start range \param publish_start pointer to the publish start integer \return a valid year on success, otherwise 0 */ _PUBLIC_ int GetFreeBusyYear(const uint32_t *publish_start) { struct tm *tm; uint32_t year; time_t time; NTTIME nttime; if (!publish_start) return 0; nttime = *publish_start; nttime *= 60; nttime *= 10000000; time = nt_time_to_unix(nttime); tm = localtime(&time); year = (tm->tm_year + 1900); return year; } openchange-2.0/libmapi/fxparser.c000066400000000000000000000425501223057412600171050ustar00rootroot00000000000000/* OpenChange MAPI implementation. Copyright (C) Brad Hards 2010. This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see . */ #include "libmapi/libmapi.h" #include "libmapi/libmapi_private.h" #include "libmapi/fxparser.h" #ifdef ENABLE_ASSERTS #include #define OC_ASSERT(x) assert(x) #else #define OC_ASSERT(x) #endif /** \file fxparser.c \brief Fast Transfer stream parser */ static bool pull_uint8_t(struct fx_parser_context *parser, uint8_t *val) { if ((parser->idx) + 1 > parser->data.length) { *val = 0; return false; } *val = parser->data.data[parser->idx]; (parser->idx)++; return true; } static bool pull_uint16_t(struct fx_parser_context *parser, uint16_t *val) { if ((parser->idx) + 2 > parser->data.length) { *val = 0; return false; } *val = parser->data.data[parser->idx]; (parser->idx)++; *val += parser->data.data[parser->idx] << 8; (parser->idx)++; return true; } static bool pull_uint32_t(struct fx_parser_context *parser, uint32_t *val) { if ((parser->idx) + 4 > parser->data.length) { *val = 0; return false; } *val = parser->data.data[parser->idx]; (parser->idx)++; *val += parser->data.data[parser->idx] << 8; (parser->idx)++; *val += parser->data.data[parser->idx] << 16; (parser->idx)++; *val += parser->data.data[parser->idx] << 24; (parser->idx)++; return true; } static bool pull_tag(struct fx_parser_context *parser) { return pull_uint32_t(parser, &(parser->tag)); } static bool pull_uint8_data(struct fx_parser_context *parser, uint32_t read_len, uint8_t **data_read) { uint32_t i; for (i = 0; i < read_len; i++) { if (!pull_uint8_t(parser, (uint8_t*)&((*data_read)[i]))) { return false; } } return true; } static bool pull_int64_t(struct fx_parser_context *parser, int64_t *val) { int64_t tmp; if ((parser->idx) + 8 > parser->data.length) { *val = 0; return false; } *val = parser->data.data[parser->idx]; (parser->idx)++; tmp = parser->data.data[parser->idx]; *val += (tmp << 8); (parser->idx)++; tmp = parser->data.data[parser->idx]; *val += (tmp << 16); (parser->idx)++; tmp = parser->data.data[parser->idx]; *val += (tmp << 24); (parser->idx)++; tmp = parser->data.data[parser->idx]; *val += (tmp << 32); (parser->idx)++; tmp = parser->data.data[parser->idx]; *val += (tmp << 40); (parser->idx)++; tmp = parser->data.data[parser->idx]; *val += (tmp << 48); (parser->idx)++; tmp = parser->data.data[parser->idx]; *val += (tmp << 56); (parser->idx)++; return true; } static bool pull_double(struct fx_parser_context *parser, double *val) { return pull_int64_t(parser, (int64_t *)val); } static bool pull_guid(struct fx_parser_context *parser, struct GUID *guid) { int i; if ((parser->idx) + 16 > parser->data.length) { GUID_all_zero(guid); return false; } if (!pull_uint32_t(parser, &(guid->time_low))) return false; if (!pull_uint16_t(parser, &(guid->time_mid))) return false; if (!pull_uint16_t(parser, &(guid->time_hi_and_version))) return false; if (!pull_uint8_t(parser, &(guid->clock_seq[0]))) return false; if (!pull_uint8_t(parser, &(guid->clock_seq[1]))) return false; for (i = 0; i < 6; ++i) { if (!pull_uint8_t(parser, &(guid->node[i]))) return false; } return true; } static bool pull_systime(struct fx_parser_context *parser, struct FILETIME *ft) { struct FILETIME filetime = {0,0}; if (parser->idx + 8 > parser->data.length || !pull_uint32_t(parser, &(filetime.dwLowDateTime)) || !pull_uint32_t(parser, &(filetime.dwHighDateTime))) return false; *ft = filetime; return true; } static bool pull_clsid(struct fx_parser_context *parser, struct FlatUID_r **pclsid) { struct FlatUID_r *clsid; int i = 0; if (parser->idx + 16 > parser->data.length) return false; clsid = talloc_zero(parser->mem_ctx, struct FlatUID_r); for (i = 0; i < 16; ++i) { if (!pull_uint8_t(parser, &(clsid->ab[i]))) return false; } *pclsid = clsid; return true; } static bool pull_string8(struct fx_parser_context *parser, char **pstr) { char *str; uint32_t i, length; if (!pull_uint32_t(parser, &length) || parser->idx + length > parser->data.length) return false; str = talloc_array(parser->mem_ctx, char, length + 1); for (i = 0; i < length; i++) { if (!pull_uint8_t(parser, (uint8_t*)&(str[i]))) { return false; } } str[length] = '\0'; *pstr = str; return true; } static bool fetch_ucs2_data(struct fx_parser_context *parser, uint32_t numbytes, smb_ucs2_t **data_read) { if ((parser->idx) + numbytes > parser->data.length) { // printf("insufficient data in fetch_ucs2_data (%i requested, %zi available)\n", numbytes, (parser->data.length - parser->idx)); return false; } *data_read = talloc_zero_array(parser->mem_ctx, smb_ucs2_t, (numbytes/2) + 1); memcpy(*data_read, &(parser->data.data[parser->idx]), numbytes); parser->idx += numbytes; return true; } static bool fetch_ucs2_nullterminated(struct fx_parser_context *parser, smb_ucs2_t **data_read) { uint32_t idx_local = parser->idx; bool found = false; while (idx_local < parser->data.length -1) { smb_ucs2_t val = 0x0000; val += parser->data.data[idx_local]; idx_local++; val += parser->data.data[idx_local] << 8; idx_local++; if (val == 0x0000) { found = true; break; } } if (!found) return false; return fetch_ucs2_data(parser, idx_local-(parser->idx), data_read); } static bool pull_unicode(struct fx_parser_context *parser, char **pstr) { smb_ucs2_t *ucs2_data = NULL; char *utf8_data = NULL; size_t utf8_len; uint32_t length; if (!pull_uint32_t(parser, &length) || parser->idx + length > parser->data.length) return false; ucs2_data = talloc_zero_array(parser->mem_ctx, smb_ucs2_t, (length/2) + 1); if (!fetch_ucs2_data(parser, length, &ucs2_data)) { return false; } pull_ucs2_talloc(parser->mem_ctx, &utf8_data, ucs2_data, &utf8_len); *pstr = utf8_data; return true; } static bool pull_binary(struct fx_parser_context *parser, struct Binary_r *bin) { if (!pull_uint32_t(parser, &(bin->cb)) || parser->idx + bin->cb > parser->data.length) return false; bin->lpb = talloc_array(parser->mem_ctx, uint8_t, bin->cb + 1); return pull_uint8_data(parser, bin->cb, &(bin->lpb)); } /* pull a property value from the blob, starting at position idx */ static bool fetch_property_value(struct fx_parser_context *parser, DATA_BLOB *buf, struct SPropValue *prop) { switch(prop->ulPropTag & 0xFFFF) { case PT_NULL: { if (!pull_uint32_t(parser, &(prop->value.null))) return false; break; } case PT_SHORT: { if (!pull_uint16_t(parser, &(prop->value.i))) return false; break; } case PT_LONG: { if (!pull_uint32_t(parser, &(prop->value.l))) return false; break; } case PT_DOUBLE: { if (!pull_double(parser, (double *)&(prop->value.dbl))) return false; break; } case PT_BOOLEAN: { if (parser->idx + 2 > parser->data.length || !pull_uint8_t(parser, &(prop->value.b))) return false; /* special case for fast transfer, 2 bytes instead of one */ (parser->idx)++; break; } case PT_I8: { int64_t val; if (!pull_int64_t(parser, &(val))) return false; prop->value.d = val; break; } case PT_STRING8: { char *str = NULL; if (!pull_string8(parser, &str)) return false; prop->value.lpszA = str; break; } case PT_UNICODE: { char *str = NULL; if (!pull_unicode (parser, &str)) return false; prop->value.lpszW = str; break; } case PT_SYSTIME: { if (!pull_systime(parser, &prop->value.ft)) return false; break; } case PT_CLSID: { if (!pull_clsid(parser, &prop->value.lpguid)) return false; break; } case PT_SVREID: case PT_BINARY: { if (!pull_binary(parser, &prop->value.bin)) return false; break; } case PT_OBJECT: { /* the object itself is sent too, thus download it as a binary, not as a meaningless number, which is length of the object here */ if (!pull_binary(parser, &prop->value.bin)) return false; break; } case PT_ERROR: { uint32_t num; if (!pull_uint32_t(parser, &num)) return false; prop->value.err = num; break; } case PT_MV_BINARY: { uint32_t i; if (!pull_uint32_t(parser, &(prop->value.MVbin.cValues)) || parser->idx + prop->value.MVbin.cValues * 4 > parser->data.length) return false; prop->value.MVbin.lpbin = talloc_array(parser->mem_ctx, struct Binary_r, prop->value.MVbin.cValues); for (i = 0; i < prop->value.MVbin.cValues; i++) { if (!pull_binary(parser, &(prop->value.MVbin.lpbin[i]))) return false; } break; } case PT_MV_SHORT: { uint32_t i; if (!pull_uint32_t(parser, &(prop->value.MVi.cValues)) || parser->idx + prop->value.MVi.cValues * 2 > parser->data.length) return false; prop->value.MVi.lpi = talloc_array(parser->mem_ctx, uint16_t, prop->value.MVi.cValues); for (i = 0; i < prop->value.MVi.cValues; i++) { if (!pull_uint16_t(parser, &(prop->value.MVi.lpi[i]))) return false; } break; } case PT_MV_LONG: { uint32_t i; if (!pull_uint32_t(parser, &(prop->value.MVl.cValues)) || parser->idx + prop->value.MVl.cValues * 4 > parser->data.length) return false; prop->value.MVl.lpl = talloc_array(parser->mem_ctx, uint32_t, prop->value.MVl.cValues); for (i = 0; i < prop->value.MVl.cValues; i++) { if (!pull_uint32_t(parser, &(prop->value.MVl.lpl[i]))) return false; } break; } case PT_MV_STRING8: { uint32_t i; char *str; if (!pull_uint32_t(parser, &(prop->value.MVszA.cValues)) || parser->idx + prop->value.MVszA.cValues * 4 > parser->data.length) return false; prop->value.MVszA.lppszA = (const char **) talloc_array(parser->mem_ctx, char *, prop->value.MVszA.cValues); for (i = 0; i < prop->value.MVszA.cValues; i++) { str = NULL; if (!pull_string8(parser, &str)) return false; prop->value.MVszA.lppszA[i] = str; } break; } case PT_MV_CLSID: { uint32_t i; if (!pull_uint32_t(parser, &(prop->value.MVguid.cValues)) || parser->idx + prop->value.MVguid.cValues * 16 > parser->data.length) return false; prop->value.MVguid.lpguid = talloc_array(parser->mem_ctx, struct FlatUID_r *, prop->value.MVguid.cValues); for (i = 0; i < prop->value.MVguid.cValues; i++) { if (!pull_clsid(parser, &(prop->value.MVguid.lpguid[i]))) return false; } break; } case PT_MV_UNICODE: { uint32_t i; char *str; if (!pull_uint32_t(parser, &(prop->value.MVszW.cValues)) || parser->idx + prop->value.MVszW.cValues * 4 > parser->data.length) return false; prop->value.MVszW.lppszW = (const char **) talloc_array(parser->mem_ctx, char *, prop->value.MVszW.cValues); for (i = 0; i < prop->value.MVszW.cValues; i++) { str = NULL; if (!pull_unicode(parser, &str)) return false; prop->value.MVszW.lppszW[i] = str; } break; } case PT_MV_SYSTIME: { uint32_t i; if (!pull_uint32_t(parser, &(prop->value.MVft.cValues)) || parser->idx + prop->value.MVft.cValues * 8 > parser->data.length) return false; prop->value.MVft.lpft = talloc_array(parser->mem_ctx, struct FILETIME, prop->value.MVft.cValues); for (i = 0; i < prop->value.MVft.cValues; i++) { if (!pull_systime(parser, &(prop->value.MVft.lpft[i]))) return false; } break; } default: printf("unhandled conversion case in fetch_property_value(): 0x%x\n", prop->ulPropTag); OPENCHANGE_ASSERT(); } return true; } static bool pull_named_property(struct fx_parser_context *parser, enum MAPISTATUS *ms) { uint8_t type = 0; if (!pull_guid(parser, &(parser->namedprop.lpguid))) return false; /* printf("guid : %s\n", GUID_string(parser->mem_ctx, &(parser->namedprop.lpguid))); */ if (!pull_uint8_t(parser, &type)) return false; if (type == 0) { parser->namedprop.ulKind = MNID_ID; if (!pull_uint32_t(parser, &(parser->namedprop.kind.lid))) return false; /* printf("LID dispid: 0x%08x\n", parser->namedprop.kind.lid); */ } else if (type == 1) { smb_ucs2_t *ucs2_data = NULL; size_t utf8_len; parser->namedprop.ulKind = MNID_STRING; if (!fetch_ucs2_nullterminated(parser, &ucs2_data)) return false; pull_ucs2_talloc(parser->mem_ctx, (char**)&(parser->namedprop.kind.lpwstr.Name), ucs2_data, &(utf8_len)); parser->namedprop.kind.lpwstr.NameSize = utf8_len; /* printf("named: %s\n", parser->namedprop.kind.lpwstr.Name); */ } else { printf("unknown named property kind: 0x%02x\n", parser->namedprop.ulKind); OPENCHANGE_ASSERT(); } if (parser->op_namedprop) { *ms = parser->op_namedprop(parser->lpProp.ulPropTag, parser->namedprop, parser->priv); } return true; } /** \details set a callback function for marker output */ _PUBLIC_ void fxparser_set_marker_callback(struct fx_parser_context *parser, fxparser_marker_callback_t marker_callback) { parser->op_marker = marker_callback; } /** \details set a callback function for delete properties output */ _PUBLIC_ void fxparser_set_delprop_callback(struct fx_parser_context *parser, fxparser_delprop_callback_t delprop_callback) { parser->op_delprop = delprop_callback; } /** \details set a callback function for named properties output */ _PUBLIC_ void fxparser_set_namedprop_callback(struct fx_parser_context *parser, fxparser_namedprop_callback_t namedprop_callback) { parser->op_namedprop = namedprop_callback; } /** \details set a callback function for property output */ _PUBLIC_ void fxparser_set_property_callback(struct fx_parser_context *parser, fxparser_property_callback_t property_callback) { parser->op_property = property_callback; } /** \details initialise a fast transfer parser */ _PUBLIC_ struct fx_parser_context* fxparser_init(TALLOC_CTX *mem_ctx, void *priv) { struct fx_parser_context *parser = talloc_zero(mem_ctx, struct fx_parser_context); parser->mem_ctx = mem_ctx; parser->data = data_blob_talloc_named(parser->mem_ctx, NULL, 0, "fast transfer parser"); parser->state = ParserState_Entry; parser->idx = 0; parser->lpProp.ulPropTag = (enum MAPITAGS) 0; parser->lpProp.dwAlignPad = 0; parser->lpProp.value.l = 0; parser->priv = priv; return parser; } /** \details parse a fast transfer buffer */ _PUBLIC_ enum MAPISTATUS fxparser_parse(struct fx_parser_context *parser, DATA_BLOB *fxbuf) { enum MAPISTATUS ms = MAPI_E_SUCCESS; data_blob_append(parser->mem_ctx, &(parser->data), fxbuf->data, fxbuf->length); parser->enough_data = true; while(ms == MAPI_E_SUCCESS && (parser->idx < parser->data.length) && parser->enough_data) { uint32_t idx = parser->idx; switch(parser->state) { case ParserState_Entry: { if (pull_tag(parser)) { /* printf("tag: 0x%08x\n", parser->tag); */ parser->state = ParserState_HaveTag; } else { parser->enough_data = false; parser->idx = idx; } break; } case ParserState_HaveTag: { switch (parser->tag) { case PidTagStartTopFld: case PidTagStartSubFld: case PidTagEndFolder: case PidTagStartMessage: case PidTagStartFAIMsg: case PidTagEndMessage: case PidTagStartRecip: case PidTagEndToRecip: case PidTagNewAttach: case PidTagEndAttach: case PidTagStartEmbed: case PidTagEndEmbed: if (parser->op_marker) { ms = parser->op_marker(parser->tag, parser->priv); } parser->state = ParserState_Entry; break; case PidTagFXDelProp: { uint32_t tag; if (pull_uint32_t(parser, &tag)) { if (parser->op_delprop) { ms = parser->op_delprop(tag, parser->priv); } parser->state = ParserState_Entry; } else { parser->enough_data = false; parser->idx = idx; } break; } default: { /* standard property thing */ parser->lpProp.ulPropTag = (enum MAPITAGS) parser->tag; parser->lpProp.dwAlignPad = 0; if ((parser->lpProp.ulPropTag >> 16) & 0x8000) { /* this is a named property */ // printf("tag: 0x%08x\n", parser->tag); // TODO: this should probably be a separate parser state // TODO: this needs to return the named property if (pull_named_property(parser, &ms)) { parser->state = ParserState_HavePropTag; } else { parser->enough_data = false; parser->idx = idx; } } else { parser->state = ParserState_HavePropTag; } } } break; } case ParserState_HavePropTag: { if (fetch_property_value(parser, &(parser->data), &(parser->lpProp))) { // printf("position %i of %zi\n", parser->idx, parser->data.length); if (parser->op_property) { ms = parser->op_property(parser->lpProp, parser->priv); } parser->state = ParserState_Entry; } else { parser->enough_data = false; parser->idx = idx; } break; } } } { // Remove the part of the buffer that we've used uint32_t remainder_len = parser->data.length - parser->idx; DATA_BLOB remainder = data_blob_talloc_named(parser->mem_ctx, &(parser->data.data[parser->idx]), remainder_len, "fast transfer parser"); data_blob_free(&(parser->data)); parser->data = remainder; parser->idx = 0; } return ms; } openchange-2.0/libmapi/fxparser.h000066400000000000000000000032611223057412600171060ustar00rootroot00000000000000/* OpenChange MAPI implementation. Copyright (C) Brad Hards 2010 This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see . */ #ifndef __LIBMAPI_FXPARSER_H__ #define __LIBMAPI_FXPARSER_H__ /* This header is private to the parser. If you use this directly, you may suffer API or ABI breakage. We mean it. */ enum fx_parser_state { ParserState_Entry, ParserState_HaveTag, ParserState_HavePropTag }; struct fx_parser_context { TALLOC_CTX *mem_ctx; DATA_BLOB data; /* the data we have (so far) to parse */ uint32_t idx; /* where we are up to in the data blob */ enum fx_parser_state state; struct SPropValue lpProp; /* the current property tag and value we are parsing */ struct MAPINAMEID namedprop; /* the current named property we are parsing */ bool enough_data; uint32_t tag; void *priv; /* callbacks for parser actions */ enum MAPISTATUS (*op_marker)(uint32_t, void *); enum MAPISTATUS (*op_delprop)(uint32_t, void *); enum MAPISTATUS (*op_namedprop)(uint32_t, struct MAPINAMEID, void *); enum MAPISTATUS (*op_property)(struct SPropValue, void *); }; #endif openchange-2.0/libmapi/idset.c000066400000000000000000000731021223057412600163600ustar00rootroot00000000000000/* OpenChange MAPI implementation. Copyright (C) Wolfgang Sourdeau 2011 This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see . */ /** \file idset.c \brief Parsing of GLOBSET structures */ #include "libmapi/libmapi.h" #include "libmapi/libmapi_private.h" #include "gen_ndr/ndr_exchange.h" struct uint32_array { uint32_t *data; size_t length; }; struct GLOBSET_parser { DATA_BLOB buffer; size_t buffer_position; DATA_BLOB stack[6]; uint8_t next_stack_item; uint8_t total_stack_size; bool error; uint32_t range_count; struct globset_range *ranges; }; /** \details Inverts the bytes of a globcnt, such as for the ids returned by Exchange */ _PUBLIC_ uint64_t exchange_globcnt(uint64_t globcnt) { return ((globcnt & 0x00000000000000ffLL) << 40 | (globcnt & 0x000000000000ff00LL) << 24 | (globcnt & 0x0000000000ff0000LL) << 8 | (globcnt & 0x00000000ff000000LL) >> 8 | (globcnt & 0x000000ff00000000LL) >> 24 | (globcnt & 0x0000ff0000000000LL) >> 40); } static inline void GLOBSET_parser_do_push(struct GLOBSET_parser *parser, uint8_t count); static inline void GLOBSET_parser_do_bitmask(struct GLOBSET_parser *parser); static void GLOBSET_parser_do_pop(struct GLOBSET_parser *parser); static void GLOBSET_parser_do_range(struct GLOBSET_parser *parser); static inline void GLOBSET_parser_do_push(struct GLOBSET_parser *parser, uint8_t count) { DATA_BLOB *push_buffer; if (count == 0 || count > 6 || parser->next_stack_item > 5 || parser->total_stack_size > 6) { abort(); } push_buffer = parser->stack + parser->next_stack_item; push_buffer->data = parser->buffer.data + parser->buffer_position; push_buffer->length = count; parser->next_stack_item += 1; parser->buffer_position += count; parser->total_stack_size += count; if (parser->total_stack_size == 6) { GLOBSET_parser_do_range(parser); GLOBSET_parser_do_pop(parser); } } static void GLOBSET_parser_do_pop(struct GLOBSET_parser *parser) { DATA_BLOB *push_buffer; parser->next_stack_item -= 1; push_buffer = parser->stack + parser->next_stack_item; parser->total_stack_size -= push_buffer->length; } static DATA_BLOB *GLOBSET_parser_stack_combine(TALLOC_CTX *mem_ctx, struct GLOBSET_parser *parser, DATA_BLOB *additional) { DATA_BLOB *combined, *current; uint8_t i; uint8_t *current_ptr; combined = talloc_zero(mem_ctx, DATA_BLOB); if (additional != NULL) { combined->length = additional->length; } for (i = 0; i < parser->next_stack_item; i++) { current = parser->stack + i; combined->length += current->length; } combined->data = talloc_array(combined, uint8_t, combined->length); current_ptr = combined->data; for (i = 0; i < parser->next_stack_item; i++) { current = parser->stack + i; memcpy(current_ptr, current->data, current->length); current_ptr += current->length; } if (additional && additional->length > 0) { memcpy(current_ptr, additional->data, additional->length); } return combined; } static uint64_t GLOBSET_parser_range_value(DATA_BLOB *combined) { uint64_t value = 0, base = 1; uint8_t i; for (i = 0; i < combined->length; i++) { value += combined->data[i] * base; base = base * 256; } return value; } static void GLOBSET_parser_do_range(struct GLOBSET_parser *parser) { uint8_t count; struct globset_range *range; DATA_BLOB *combined, *additional; void *mem_ctx; mem_ctx = talloc_zero(NULL, void); range = talloc_zero(parser, struct globset_range); count = 6 - parser->total_stack_size; if (count > 0) { additional = talloc_zero(mem_ctx, DATA_BLOB); additional->length = count; additional->data = talloc_array(additional, uint8_t, count); memcpy(additional->data, parser->buffer.data + parser->buffer_position, count); } else { additional = NULL; } parser->buffer_position += count; combined = GLOBSET_parser_stack_combine(mem_ctx, parser, additional); range->low = GLOBSET_parser_range_value(combined); if (count == 0) { range->high = range->low; } else if (count > 0) { memcpy(additional->data, parser->buffer.data + parser->buffer_position, count); parser->buffer_position += count; combined = GLOBSET_parser_stack_combine(mem_ctx, parser, additional); range->high = GLOBSET_parser_range_value(combined); } DLIST_ADD_END(parser->ranges, range, void); /* DEBUG(5, (" added range: [%.16"PRIx64":%.16"PRIx64"] %p %p %p\n", range->low, range->high, range, range->prev, range->next)); */ parser->range_count++; if (!parser->ranges) { abort(); } talloc_free(mem_ctx); } static inline void GLOBSET_parser_do_bitmask(struct GLOBSET_parser *parser) { uint8_t mask, bit, i; DATA_BLOB *combined, additional; uint64_t baseValue, lowValue, highValue; struct globset_range *range; bool blank = false; mask = parser->buffer.data[parser->buffer_position+1]; parser->buffer_position += 2; additional.length = 1; additional.data = parser->buffer.data + parser->buffer_position; combined = GLOBSET_parser_stack_combine(NULL, parser, &additional); baseValue = GLOBSET_parser_range_value(combined); talloc_free(combined); lowValue = baseValue; highValue = baseValue; for (i = 0; i < 8; i++) { bit = 1 << i; if (blank) { if ((mask & bit)) { blank = false; lowValue = baseValue + ((uint64_t) (bit + 1) << 40); highValue = lowValue; } } else { if ((mask & bit) == 0) { range = talloc_zero(parser, struct globset_range); range->low = lowValue; range->high = highValue; DLIST_ADD_END(parser->ranges, range, void); parser->range_count++; blank = true; } else { highValue = baseValue + ((uint64_t) (bit + 1) << 40); } } } if (!blank) { range = talloc_zero(parser, struct globset_range); range->low = lowValue; range->high = highValue; DLIST_ADD_END(parser->ranges, range, void); parser->range_count++; } } /** \details deserialize a GLOBSET following the format described in [OXCFXICS - 2.2.2.5] */ _PUBLIC_ struct globset_range *GLOBSET_parse(TALLOC_CTX *mem_ctx, DATA_BLOB buffer, uint32_t *countP, uint32_t *byte_countP) { struct GLOBSET_parser *parser; struct globset_range *ranges, *range; bool end = false; uint8_t command; parser = talloc_zero(NULL, struct GLOBSET_parser); parser->buffer = buffer; while (!end && !parser->error) { if (parser->buffer_position >= parser->buffer.length) { DEBUG(4, ("%s: end of buffer reached unexpectedly at position %Ld\n", __FUNCTION__, (unsigned long long) parser->buffer_position)); parser->error = true; } else { command = parser->buffer.data[parser->buffer_position]; parser->buffer_position++; switch (command) { case 0x00: /* end */ end = true; break; case 0x01: /* push 1 */ case 0x02: /* push 2 */ case 0x03: /* push 3 */ case 0x04: /* push 4 */ case 0x05: /* push 5 */ case 0x06: /* push 6 */ GLOBSET_parser_do_push(parser, command); break; case 0x42: /* bitmask */ GLOBSET_parser_do_bitmask(parser); break; case 0x50: /* pop */ GLOBSET_parser_do_pop(parser); break; case 0x52: /* range */ GLOBSET_parser_do_range(parser); break; default: parser->error = true; DEBUG(4, ("%s: invalid command in blockset: %.2x\n", __FUNCTION__, command)); abort(); } } } if (parser->error) { ranges = NULL; /* abort(); */ } else { ranges = parser->ranges; if (countP) { *countP = parser->range_count; } if (byte_countP) { *byte_countP = parser->buffer_position; } if (ranges) { range = ranges; while (range) { (void) talloc_reference(mem_ctx, range); range = range->next; } } } talloc_free(parser); return ranges; } #if 0 /* IDSET debugging */ static void check_idset(const struct idset *idset) { uint32_t i; struct globset_range *range, *last_range; while (idset) { if (!idset->idbased && GUID_all_zero(&idset->repl.guid)) { DEBUG(5, ("idset: invalid guid\n")); abort(); } i = 0; if (idset->ranges) { range = idset->ranges; while (range) { /* DEBUG(5, ("range %d: [%.16Lx:%.16Lx] prev: %p; next: %p\n", i, range->low, range->high, range->prev, range->next)); */ if (range->prev == NULL) { DEBUG(5, ("range %d has a NULL prev\n", i)); abort(); } i++; last_range = range; range = range->next; } if (idset->ranges->prev != last_range) { DEBUG(5, ("idset: last element of linked list is not the expected one\n")); abort(); } } if (i != idset->range_count) { DEBUG(5, ("idset: elements count does not match the reported value (%d and %d)\n", i, idset->range_count)); abort(); } idset = idset->next; } } #else /* IDSET debugging */ #define check_idset(x) {} #endif /** \details deserialize an IDSET following the format described in [OXCFXICS - 2.2.2.4] */ _PUBLIC_ struct idset *IDSET_parse(TALLOC_CTX *mem_ctx, DATA_BLOB buffer, bool idbased) { struct idset *idset, *prev_idset = NULL; DATA_BLOB guid_blob, globset; uint32_t total_bytes, byte_count; if (buffer.length < 17) return NULL; total_bytes = 0; while (total_bytes < buffer.length) { idset = talloc_zero(mem_ctx, struct idset); if (prev_idset) { prev_idset->next = idset; } if (idbased) { idset->repl.id = (buffer.data[total_bytes] | (buffer.data[total_bytes+1] << 8)); total_bytes += 2; } else { guid_blob.data = buffer.data; guid_blob.length = 16; GUID_from_data_blob(&guid_blob, &idset->repl.guid); total_bytes += 16; } globset.length = buffer.length - 16; globset.data = (uint8_t *) buffer.data + 16; idset->ranges = GLOBSET_parse(idset, globset, &idset->range_count, &byte_count); total_bytes += byte_count; check_idset(idset); prev_idset = idset; } IDSET_dump(idset, "freshly parsed"); return idset; } static int IDSET_ID_compar(const void *vap, const void *vbp) { const struct idset *ap, *bp; int rc; ap = *(const struct idset **) vap; bp = *(const struct idset **) vbp; if (ap->repl.id == bp ->repl.id) { rc = 0; } else if (ap->repl.id < bp ->repl.id) { rc = 1; } else { rc = -1; } return rc; } static int IDSET_GUID_compar(const void *vap, const void *vbp) { const struct idset *ap, *bp; ap = *(const struct idset **) vap; bp = *(const struct idset **) vbp; return GUID_compare(&ap->repl.guid, &bp->repl.guid); } static int IDSET_globcnt_compar(const void *vap, const void *vbp) { int retval; uint64_t a, b; a = exchange_globcnt(*(uint64_t *) vap); b = exchange_globcnt(*(uint64_t *) vbp); if (a < b) { retval = -1; } else if (a == b) { retval = 0; } else { retval = 1; } return retval; } static int IDSET_range_compar(const void *vap, const void *vbp) { const struct globset_range *ap, *bp; ap = *(const struct globset_range **) vap; bp = *(const struct globset_range **) vbp; return IDSET_globcnt_compar(&ap->low, &bp->low); } static struct idset *IDSET_make(TALLOC_CTX *mem_ctx, bool idbased, uint16_t base_id, const struct GUID *base_guid, const uint64_t *array, uint32_t length, bool single) { struct idset *idset; struct globset_range *current_globset; uint64_t last_consequent; uint64_t *work_array; uint32_t i; if (!array) { return NULL; } idset = talloc_zero(mem_ctx, struct idset); idset->idbased = idbased; if (idbased) { idset->repl.id = base_id; } else { idset->repl.guid = *base_guid; } idset->single = single; current_globset = talloc_zero(idset, struct globset_range); DLIST_ADD_END(idset->ranges, current_globset, end); idset->range_count = 1; if (length == 0) { return idset; } work_array = talloc_memdup(NULL, array, sizeof(uint64_t) * length); qsort(work_array, length, sizeof(uint64_t), IDSET_globcnt_compar); if (length == 2) { DEBUG(5, ("work_array[0]: %.16Lx, %.16Lx\n", (unsigned long long) work_array[0], (unsigned long long) work_array[1])); if (work_array[0] != array[0]) { DEBUG(5, ("elements were reordered\n")); } } current_globset->low = work_array[0]; if (single || length < 3) { current_globset->high = work_array[length-1]; } else { last_consequent = exchange_globcnt(current_globset->low); for (i = 1; i < length; i++) { if ((exchange_globcnt(work_array[i]) != last_consequent) && (exchange_globcnt(work_array[i]) != (last_consequent + 1))) { current_globset->high = exchange_globcnt(last_consequent); current_globset = talloc_zero(idset, struct globset_range); DLIST_ADD_END(idset->ranges, current_globset, void); idset->range_count++; current_globset->low = work_array[i]; } last_consequent = exchange_globcnt(work_array[i]); } current_globset->high = exchange_globcnt(last_consequent); } talloc_free(work_array); check_idset(idset); return idset; } /* start: [0|1|2|3|4|5] -- count --> */ static void GLOBSET_ndr_push_shifted_id(struct ndr_push *ndr, uint64_t range_id, uint8_t start, uint8_t count) { uint8_t i, steps, byte; for (i = 0; i < count; i++) { steps = start + i; byte = (range_id >> (8 * steps)) & 0xff; ndr_push_uint8(ndr, NDR_SCALARS, byte); } } static void GLOBSET_ndr_push_globset_range(struct ndr_push *ndr, struct globset_range *range) { uint8_t i; uint64_t mask; bool done; if (range->low == range->high) { ndr_push_uint8(ndr, NDR_SCALARS, 0x06); /* push 6 */ GLOBSET_ndr_push_shifted_id(ndr, range->low, 0, 6); } else { i = 0; mask = 0xff; done = false; while (!done && i < 6) { if ((range->low & mask) == (range->high & mask)) { mask <<= 8; i++; } else { done = true; } } if (i > 0 && i < 6) { /* push i */ ndr_push_uint8(ndr, NDR_SCALARS, i); GLOBSET_ndr_push_shifted_id(ndr, range->low, 0, i); } ndr_push_uint8(ndr, NDR_SCALARS, 0x52); /* range */ GLOBSET_ndr_push_shifted_id(ndr, range->low, i, 6 - i); GLOBSET_ndr_push_shifted_id(ndr, range->high, i, 6 - i); if (i > 0 && i < 6) { /* pop */ ndr_push_uint8(ndr, NDR_SCALARS, 0x50); } } } static int IDSET_count(const struct idset *idset) { int max = 0; while (idset) { max++; idset = idset->next; } return max; } static void IDSET_reorder_idset(struct idset **idsetP) { int i, max = 0; struct idset **idsets; struct idset *idset, *current_idset, *last_idset; if (!idsetP) return; idset = *idsetP; if (!idset || !idset->next) return; check_idset(idset); max = IDSET_count(idset); idsets = talloc_array(NULL, struct idset *, max); current_idset = idset; for (i = 0; i < max; i++) { idsets[i] = current_idset; current_idset = current_idset->next; } qsort(idsets, max, sizeof(struct idset *), idsets[0]->idbased ? IDSET_ID_compar : IDSET_GUID_compar); current_idset = idsets[0]; for (i = 1; i < max; i++) { last_idset = current_idset; current_idset = idsets[i]; last_idset->next = current_idset; } current_idset->next = NULL; *idsetP = idsets[0]; talloc_free(idsets); } static void IDSET_reorder_ranges(struct idset *idset) { struct globset_range *range; struct globset_range **ranges; uint32_t i; if (!idset || idset->range_count < 2) return; ranges = talloc_array(NULL, struct globset_range *, idset->range_count); range = idset->ranges; for (i = 0; i < idset->range_count; i++) { ranges[i] = range; range = range->next; } qsort(ranges, idset->range_count, sizeof(struct globset_range *), IDSET_range_compar); idset->ranges = ranges[0]; ranges[0]->prev = ranges[idset->range_count-1]; for (i = 0; i < idset->range_count - 1; i++) { ranges[i]->next = ranges[i+1]; ranges[i+1]->prev = ranges[i]; } ranges[idset->range_count-1]->next = NULL; check_idset(idset); talloc_free(ranges); } static void IDSET_compact_ranges(struct idset *idset) { struct globset_range *range, *next_range, *prev_range; if (!idset || idset->range_count < 2) return; if (idset->single) { range = idset->ranges; next_range = range->next; while (next_range) { if (exchange_globcnt(next_range->low) < exchange_globcnt(range->low)) { range->low = next_range->low; } if (exchange_globcnt(next_range->high) > exchange_globcnt(range->high)) { range->high = next_range->high; } prev_range = next_range; next_range = next_range->next; talloc_free(prev_range); } range->next = NULL; range->prev = range; idset->range_count = 1; } else { range = idset->ranges; while (range) { next_range = range->next; while (next_range) { if (exchange_globcnt(next_range->low) >= exchange_globcnt(range->low) && exchange_globcnt(next_range->low) <= exchange_globcnt(range->high)) { /* A[ B[... ]A */ if (exchange_globcnt(next_range->high) > exchange_globcnt(range->high)) { /* A[ B[ ]A ]B -> A[ B[ ]AB */ range->high = next_range->high; } range->next = next_range->next; if (range->next) { range->next->prev = range; } if (idset->ranges->prev == next_range) { idset->ranges->prev = range; } idset->range_count--; talloc_free(next_range); next_range = range->next; } else { next_range = NULL; } } range = range->next; } } check_idset(idset); } /** \details returns an exact but totally distinct copy of an idset structure */ static struct idset *IDSET_clone(TALLOC_CTX *mem_ctx, const struct idset *source_idset) { struct globset_range *range, *clone; struct idset *idset = NULL, *head_idset = NULL, *tail_idset; if (!source_idset) return NULL; check_idset(source_idset); while (source_idset) { tail_idset = idset; idset = talloc_zero(mem_ctx, struct idset); idset->idbased = source_idset->idbased; if (idset->idbased) { idset->repl.id = source_idset->repl.id; } else { idset->repl.guid = source_idset->repl.guid; } idset->single = source_idset->single; idset->range_count = source_idset->range_count; range = source_idset->ranges; while (range) { clone = talloc_zero(idset, struct globset_range); clone->low = range->low; clone->high = range->high; DLIST_ADD_END(idset->ranges, clone, void); range = range->next; } if (!head_idset) { head_idset = idset; } if (tail_idset) { tail_idset->next = idset; } source_idset = source_idset->next; } check_idset(head_idset); return head_idset; } /** \details merge two idsets structures into a third one */ _PUBLIC_ struct idset *IDSET_merge_idsets(TALLOC_CTX *mem_ctx, const struct idset *left, const struct idset *right) { struct idset *merged_idset, *clone_right, *current, *next; uint16_t current_id = 0, next_id; struct GUID *current_guid = NULL, *next_guid; bool added_ranges = false, same_id, idbased; struct globset_range *range; if (!left || left->range_count == 0) return IDSET_clone(mem_ctx, right); if (!right || right->range_count == 0) return IDSET_clone(mem_ctx, left); merged_idset = IDSET_clone(mem_ctx, left); clone_right = IDSET_clone(mem_ctx, right); current = merged_idset; while (current->next) { current = current->next; } current->next = clone_right; IDSET_reorder_idset(&merged_idset); current = merged_idset; idbased = current->idbased; if (idbased) { current_id = current->repl.id; } else { current_guid = ¤t->repl.guid; } while (current->next) { next = current->next; if (idbased) { next_id = next->repl.id; same_id = (current_id == next_id); } else { next_guid = &next->repl.guid; same_id = GUID_equal(current_guid, next_guid); } if (same_id) { added_ranges = true; current->range_count += next->range_count; range = next->ranges; current->ranges->prev->next = range; while (range) { (void) talloc_reference(current, range); range = range->next; } current->next = next->next; talloc_free(next); } else { current = next; } } if (added_ranges) { current = merged_idset; while (current) { IDSET_reorder_ranges(current); IDSET_compact_ranges(current); current = current->next; } } return merged_idset; } /** \details serialize an idset structure in a struct SBinary_r */ _PUBLIC_ struct Binary_r *IDSET_serialize(TALLOC_CTX *mem_ctx, const struct idset *idset) { struct ndr_push *ndr; struct globset_range *current_range; struct Binary_r *data; check_idset(idset); ndr = ndr_push_init_ctx(NULL); ndr_set_flags(&ndr->flags, LIBNDR_FLAG_NOALIGN); ndr->offset = 0; while (idset) { if (idset->idbased) { ndr_push_uint16(ndr, NDR_SCALARS, idset->repl.id); } else { ndr_push_GUID(ndr, NDR_SCALARS, &idset->repl.guid); } current_range = idset->ranges; while (current_range) { GLOBSET_ndr_push_globset_range(ndr, current_range); current_range = current_range->next; } ndr_push_uint8(ndr, NDR_SCALARS, 0x00); /* end */ idset = idset->next; } data = talloc_zero(mem_ctx, struct Binary_r); data->cb = ndr->offset; data->lpb = ndr->data; (void) talloc_reference(data, data->lpb); talloc_free(ndr); return data; } /** \details tests the presence of a specific id in the ranges of a ReplID-based idset structure */ _PUBLIC_ bool IDSET_includes_eid(const struct idset *idset, uint64_t eid) { struct globset_range *range; uint16_t eid_id; uint64_t eid_globcnt; if (!idset || !idset->idbased) { return false; } eid_id = eid & 0xffff; eid_globcnt = eid >> 16; while (idset) { if (idset->repl.id == eid_id) { range = idset->ranges; while (range) { if (exchange_globcnt(range->low) <= exchange_globcnt(eid_globcnt) && exchange_globcnt(range->high) >= exchange_globcnt(eid_globcnt)) { return true; } range = range->next; } } idset = idset->next; } return false; } /** \details tests the presence of a specific id in the ranges of a ReplGUID-based idset structure */ _PUBLIC_ bool IDSET_includes_guid_glob(const struct idset *idset, struct GUID *replica_guid, uint64_t id) { struct globset_range *range; if (!idset || idset->idbased) { return false; } if (!replica_guid) { return false; } while (idset) { if (GUID_equal(&idset->repl.guid, replica_guid)) { range = idset->ranges; while (range) { if (exchange_globcnt(range->low) <= exchange_globcnt(id) && exchange_globcnt(range->high) >= exchange_globcnt(id)) { return true; } range = range->next; } } idset = idset->next; } return false; } static void IDSET_ranges_remove_globcnt(struct idset *idset, uint64_t eid) { struct globset_range *range, *new_range; bool done = false; uint64_t work_eid; work_eid = exchange_globcnt(eid); range = idset->ranges; while (!done && range) { if (range->low == eid) { if (range->high == eid) { DLIST_REMOVE(idset->ranges, range); idset->range_count--; if (range->next == NULL && idset->ranges != NULL) { idset->ranges->prev = range->prev; } talloc_free(range); } else { range->low = exchange_globcnt(work_eid + 1); } done = true; } else if (range->high == eid) { range->high = exchange_globcnt(work_eid + 1); done = true; } else if ((exchange_globcnt(range->low) < work_eid) && (exchange_globcnt(range->high) > work_eid)) { new_range = talloc_zero(idset, struct globset_range); new_range->low = exchange_globcnt(work_eid + 1); new_range->high = range->high; range->high = exchange_globcnt(work_eid - 1); new_range->next = range->next; range->next = new_range; if (new_range->next == NULL) { idset->ranges->prev = new_range; } idset->range_count++; done = true; } else { range = range->next; } } } _PUBLIC_ void IDSET_remove_rawidset(struct idset *idset, const struct rawidset *rawidset) { struct idset *current_idset; int i; if (!idset || !rawidset) { return; } if (idset->single) { return; } if (idset->idbased != rawidset->idbased) { return; } if (rawidset->next) { DEBUG(5, (__location__ ": warning, only first rawidset will be taken into account\n")); } current_idset = idset; if (idset->idbased) { while (current_idset && (current_idset->repl.id != rawidset->repl.id)) { current_idset = current_idset->next; } } else { while (current_idset && !GUID_equal(¤t_idset->repl.guid, &rawidset->repl.guid)) { current_idset = current_idset->next; } } if (current_idset) { for (i = 0; i < rawidset->count; i++) { IDSET_ranges_remove_globcnt(current_idset, rawidset->globcnts[i]); } } check_idset(idset); } /** \details dump an idset structure */ _PUBLIC_ void IDSET_dump(const struct idset *idset, const char *label) { struct globset_range *range; uint32_t i; char *guid_str; DEBUG(0, ("[%s] Dump of idset\n", label)); while (idset) { if (idset->idbased) { DEBUG(0, (" %.4x: %d elements\n", idset->repl.id, idset->range_count)); } else { guid_str = GUID_string(NULL, &idset->repl.guid); DEBUG(0, (" %s: %d elements\n", guid_str, idset->range_count)); talloc_free(guid_str); } range = idset->ranges; for (i = 0; i < idset->range_count; i++) { if (exchange_globcnt(range->low) > exchange_globcnt(range->high)) { abort(); } DEBUG(0, (" [0x%.12" PRIx64 ":0x%.12" PRIx64 "]\n", range->low, range->high)); range = range->next; } idset = idset->next; } } /** \details push an idset on an ndr stream */ _PUBLIC_ void ndr_push_idset(struct ndr_push *ndr, struct idset *idset) { struct Binary_r *bin_data; bin_data = IDSET_serialize(NULL, idset); ndr_push_Binary_r(ndr, NDR_BUFFERS, bin_data); talloc_free(bin_data); } _PUBLIC_ struct rawidset *RAWIDSET_make(TALLOC_CTX *mem_ctx, bool idbased, bool single) { struct rawidset *rawidset; rawidset = talloc_zero(mem_ctx, struct rawidset); rawidset->mem_ctx = mem_ctx; rawidset->idbased = idbased; rawidset->single = single; rawidset->globcnts = talloc_zero(rawidset, uint64_t); rawidset->count = 0; rawidset->max_count = 0; rawidset->next = NULL; return rawidset; } static struct rawidset *RAWIDSET_find_by_ID(struct rawidset *rawidset, uint16_t replid, struct rawidset **rawidset_last) { static struct rawidset *current; if (!rawidset->idbased) { return NULL; } current = rawidset; if (rawidset_last) *rawidset_last = current; while (current) { if (current->repl.id == replid) { return current; } else { current = current->next; if (rawidset_last && current) *rawidset_last = current; } } return NULL; } static struct rawidset *RAWIDSET_find_by_GUID(struct rawidset *rawidset, const struct GUID *guid, struct rawidset **rawidset_last) { static struct rawidset *current; if (rawidset->idbased) { return NULL; } current = rawidset; if (rawidset_last) *rawidset_last = current; while (current) { if (GUID_equal(¤t->repl.guid, guid)) { return current; } else { current = current->next; if (rawidset_last && current) *rawidset_last = current; } } return NULL; } _PUBLIC_ void RAWIDSET_push_eid(struct rawidset *rawidset, uint64_t eid) { struct rawidset *glob_idset, *last_glob_idset = NULL; uint16_t eid_id; uint64_t eid_globcnt; if (!rawidset) return; eid_id = eid & 0xffff; eid_globcnt = eid >> 16; glob_idset = RAWIDSET_find_by_ID(rawidset, eid_id, &last_glob_idset); if (!glob_idset) { if (last_glob_idset == rawidset && rawidset->repl.id == 0) { glob_idset = rawidset; } else { glob_idset = RAWIDSET_make(rawidset->mem_ctx, true, rawidset->single); last_glob_idset->next = glob_idset; } glob_idset->repl.id = eid_id; } if (glob_idset->count + 1 > glob_idset->max_count) { glob_idset->max_count += 256; glob_idset->globcnts = talloc_realloc(glob_idset, glob_idset->globcnts, uint64_t, glob_idset->max_count); } glob_idset->globcnts[glob_idset->count] = eid_globcnt; glob_idset->count++; } _PUBLIC_ void RAWIDSET_push_guid_glob(struct rawidset *rawidset, const struct GUID *guid, uint64_t globcnt) { struct rawidset *glob_idset, *last_glob_idset; static struct GUID *zero_guid = NULL; if (!rawidset) return; /* DEBUG(0, ("pushing %.16"PRIx64" into idset...\n", globcnt)); */ if (globcnt == 0) { DEBUG(0, ("attempting to push a null globcnt\n")); abort(); } if ((globcnt & 0xffff000000000000)) { DEBUG(0, ("attempting to push a globcnt that has not been shifted by 16 bits beforehand\n")); abort(); } glob_idset = RAWIDSET_find_by_GUID(rawidset, guid, &last_glob_idset); if (!glob_idset) { if (!zero_guid) { zero_guid = talloc_zero(NULL, struct GUID); } glob_idset = RAWIDSET_find_by_GUID(rawidset, zero_guid, NULL); if (!glob_idset) { glob_idset = RAWIDSET_make(rawidset->mem_ctx, false, rawidset->single); last_glob_idset->next = glob_idset; } glob_idset->repl.guid = *guid; } if (glob_idset->count + 1 > glob_idset->max_count) { glob_idset->max_count += 256; glob_idset->globcnts = talloc_realloc(glob_idset, glob_idset->globcnts, uint64_t, glob_idset->max_count); } glob_idset->globcnts[glob_idset->count] = globcnt; glob_idset->count++; } _PUBLIC_ struct idset *RAWIDSET_convert_to_idset(TALLOC_CTX *mem_ctx, const struct rawidset *rawidset) { struct idset *head_idset = NULL, *last_idset = NULL, *new_idset; const struct rawidset *current; bool valid_repl; current = rawidset; while (current) { if (current->idbased) { valid_repl = (current->repl.id != 0); } else { valid_repl = !GUID_all_zero(¤t->repl.guid); } if (current->count > 0 && valid_repl) { new_idset = IDSET_make(mem_ctx, current->idbased, current->repl.id, ¤t->repl.guid, current->globcnts, current->count, current->single); if (!head_idset) { head_idset = new_idset; } if (last_idset) { last_idset->next = new_idset; } last_idset = new_idset; } current = current->next; } check_idset(head_idset); return head_idset; } openchange-2.0/libmapi/idset.h000066400000000000000000000026461223057412600163720ustar00rootroot00000000000000/* OpenChange MAPI implementation. Copyright (C) Wolfgang Sourdeau 2011 This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see . */ #ifndef __LIBMAPI_IDSET_H_ #define __LIBMAPI_IDSET_H_ #include struct idset { bool idbased; /* replid-/replguid based */ union { uint16_t id; struct GUID guid; } repl; bool single; /* single range */ uint32_t range_count; struct globset_range *ranges; struct idset *next; }; struct globset_range { uint64_t low; uint64_t high; struct globset_range *prev; struct globset_range *next; }; struct rawidset { TALLOC_CTX *mem_ctx; bool idbased; /* replid-/replguid based */ union { uint16_t id; struct GUID guid; } repl; bool single; /* single range */ uint64_t *globcnts; int count; int max_count; struct rawidset *next; }; #endif /* __LIBMAPI_IDSET_H_ */ openchange-2.0/libmapi/libmapi.h000066400000000000000000001131261223057412600166730ustar00rootroot00000000000000/* OpenChange MAPI implementation. libmapi public header file Copyright (C) Julien Kerihuel 2007-2011. This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see . */ #ifndef __LIBMAPI_H__ #define __LIBMAPI_H__ #ifndef _GNU_SOURCE #define _GNU_SOURCE 1 #endif #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include /* Samba4 includes */ #include #include #include #include #include /* OpenChange includes */ #include #include #include "libmapi/version.h" #include "libmapi/nspi.h" #include "libmapi/emsmdb.h" #include "libmapi/mapi_context.h" #include "libmapi/mapi_provider.h" #include "libmapi/mapi_object.h" #include "libmapi/mapi_id_array.h" #include "libmapi/mapi_notification.h" #include "libmapi/mapi_profile.h" #include "libmapi/mapidefs.h" #include "libmapi/mapicode.h" #include "libmapi/socket/netif.h" #include "libmapi/idset.h" #include "libmapi/property_tags.h" #include "libmapi/property_altnames.h" #undef _PRINTF_ATTRIBUTE #define _PRINTF_ATTRIBUTE(a1, a2) PRINTF_ATTRIBUTE(a1, a2) #ifndef __BEGIN_DECLS #ifdef __cplusplus #define __BEGIN_DECLS extern "C" { #define __END_DECLS } #else #define __BEGIN_DECLS #define __END_DECLS #endif #endif #ifndef _PUBLIC_ #define _PUBLIC_ #endif __BEGIN_DECLS /* The following public definitions come from libmapi/nspi.c */ struct nspi_context *nspi_bind(TALLOC_CTX *, struct dcerpc_pipe *, struct cli_credentials *, uint32_t, uint32_t, uint32_t); enum MAPISTATUS nspi_unbind(struct nspi_context *); enum MAPISTATUS nspi_UpdateStat(struct nspi_context *, TALLOC_CTX *, uint32_t *); enum MAPISTATUS nspi_QueryRows(struct nspi_context *, TALLOC_CTX *, struct SPropTagArray *, struct PropertyTagArray_r *MIds, uint32_t, struct PropertyRowSet_r **); enum MAPISTATUS nspi_SeekEntries(struct nspi_context *, TALLOC_CTX *, enum TableSortOrders, struct PropertyValue_r *, struct SPropTagArray *, struct PropertyTagArray_r *pMIds, struct PropertyRowSet_r **); enum MAPISTATUS nspi_GetMatches(struct nspi_context *, TALLOC_CTX *, struct SPropTagArray *, struct Restriction_r *, uint32_t ulRequested, struct PropertyRowSet_r **, struct PropertyTagArray_r **ppOutMIds); enum MAPISTATUS nspi_ResortRestriction(struct nspi_context *, TALLOC_CTX *, enum TableSortOrders, struct PropertyTagArray_r *pInMIds, struct PropertyTagArray_r **ppMIds); enum MAPISTATUS nspi_DNToMId(struct nspi_context *, TALLOC_CTX *, struct StringsArray_r *, struct PropertyTagArray_r **ppMIds); enum MAPISTATUS nspi_GetPropList(struct nspi_context *, TALLOC_CTX *, bool, uint32_t, struct SPropTagArray **); enum MAPISTATUS nspi_GetProps(struct nspi_context *, TALLOC_CTX *, struct SPropTagArray *, struct PropertyTagArray_r *MId, struct PropertyRowSet_r **); enum MAPISTATUS nspi_CompareMIds(struct nspi_context *, TALLOC_CTX *, uint32_t, uint32_t, uint32_t *); enum MAPISTATUS nspi_ModProps(struct nspi_context *, TALLOC_CTX *, uint32_t, struct SPropTagArray *, struct PropertyRow_r *); enum MAPISTATUS nspi_GetSpecialTable(struct nspi_context *, TALLOC_CTX *, uint32_t, struct PropertyRowSet_r **); enum MAPISTATUS nspi_GetTemplateInfo(struct nspi_context *, TALLOC_CTX *, uint32_t, uint32_t, char *, struct PropertyRow_r **); enum MAPISTATUS nspi_ModLinkAtt(struct nspi_context *, bool, uint32_t, uint32_t, struct BinaryArray_r *); enum MAPISTATUS nspi_QueryColumns(struct nspi_context *, TALLOC_CTX *, bool, struct SPropTagArray **); enum MAPISTATUS nspi_GetNamesFromIDs(struct nspi_context *, TALLOC_CTX *, struct FlatUID_r *, struct SPropTagArray *, struct SPropTagArray **, struct PropertyNameSet_r **); enum MAPISTATUS nspi_GetIDsFromNames(struct nspi_context *, TALLOC_CTX *, bool, uint32_t, struct PropertyName_r *, struct SPropTagArray **); enum MAPISTATUS nspi_ResolveNames(struct nspi_context *, TALLOC_CTX *, const char **, struct SPropTagArray *, struct PropertyRowSet_r ***, struct PropertyTagArray_r ***); enum MAPISTATUS nspi_ResolveNamesW(struct nspi_context *, TALLOC_CTX *, const char **, struct SPropTagArray *, struct PropertyRowSet_r ***, struct PropertyTagArray_r ***); /* The following public definitions come from libmapi/emsmdb.c */ NTSTATUS emsmdb_transaction_null(struct emsmdb_context *, struct mapi_response **); NTSTATUS emsmdb_transaction(struct emsmdb_context *, TALLOC_CTX *, struct mapi_request *, struct mapi_response **); NTSTATUS emsmdb_transaction_ext2(struct emsmdb_context *, TALLOC_CTX *, struct mapi_request *, struct mapi_response **); NTSTATUS emsmdb_transaction_wrapper(struct mapi_session *, TALLOC_CTX *, struct mapi_request *, struct mapi_response **); struct emsmdb_info *emsmdb_get_info(struct mapi_session *); void emsmdb_get_SRowSet(TALLOC_CTX *, struct SRowSet *, struct SPropTagArray *, DATA_BLOB *); /* The following public definitions come from libmapi/cdo_mapi.c */ enum MAPISTATUS MapiLogonEx(struct mapi_context *, struct mapi_session **, const char *, const char *); enum MAPISTATUS MapiLogonProvider(struct mapi_context *, struct mapi_session **, const char *, const char *, enum PROVIDER_ID); enum MAPISTATUS MAPIInitialize(struct mapi_context **, const char *); void MAPIUninitialize(struct mapi_context *); enum MAPISTATUS SetMAPIDumpData(struct mapi_context *, bool); enum MAPISTATUS SetMAPIDebugLevel(struct mapi_context *, uint32_t); enum MAPISTATUS GetLoadparmContext(struct mapi_context *, struct loadparm_context **); /* The following public definitions come from libmapi/simple_mapi.c */ enum MAPISTATUS GetDefaultPublicFolder(mapi_object_t *, uint64_t *, const uint32_t); enum MAPISTATUS GetDefaultFolder(mapi_object_t *, uint64_t *, const uint32_t); bool IsMailboxFolder(mapi_object_t *, uint64_t, uint32_t *); enum MAPISTATUS GetFolderItemsCount(mapi_object_t *, uint32_t *, uint32_t *); enum MAPISTATUS AddUserPermission(mapi_object_t *, const char *, enum ACLRIGHTS); enum MAPISTATUS ModifyUserPermission(mapi_object_t *, const char *, enum ACLRIGHTS); enum MAPISTATUS RemoveUserPermission(mapi_object_t *, const char *); enum MAPISTATUS GetBestBody(mapi_object_t *, uint8_t *); /* The following public definitions come from auto-generated libmapi/mapitags.c */ const char *get_proptag_name(uint32_t); uint32_t get_proptag_value(const char *); uint16_t get_property_type(uint16_t untypedtag); /* The following public definitions come from auto-generated libmapi/mapicode.c */ void mapi_errstr(const char *, enum MAPISTATUS); const char *mapi_get_errstr(enum MAPISTATUS); /* The following public definitions come from libmapi/codepage_lcid.c */ char *mapi_get_system_locale(void); bool mapi_verify_cpid(uint32_t); uint32_t mapi_get_cpid_from_lcid(uint32_t); uint32_t mapi_get_cpid_from_locale(const char *); uint32_t mapi_get_cpid_from_language(const char *); uint32_t mapi_get_lcid_from_locale(const char *); uint32_t mapi_get_lcid_from_language(const char *); const char *mapi_get_locale_from_lcid(uint32_t); const char *mapi_get_locale_from_language(const char *); const char *mapi_get_language_from_locale(const char *); const char *mapi_get_language_from_lcid(uint32_t); char **mapi_get_language_from_group(TALLOC_CTX *, uint32_t); /* The following public definitions come from libmapi/mapidump.c */ void mapidump_SPropValue(struct SPropValue, const char *); void mapidump_SPropTagArray(struct SPropTagArray *); void mapidump_SRowSet(struct SRowSet *, const char *); void mapidump_SRow(struct SRow *, const char *); void mapidump_PAB_entry(struct PropertyRow_r *); void mapidump_Recipients(const char **, struct SRowSet *, struct PropertyTagArray_r *flaglist); void mapidump_date(struct mapi_SPropValue_array *, uint32_t, const char *); void mapidump_date_SPropValue(struct SPropValue, const char *, const char *); void mapidump_message_summary(mapi_object_t *); void mapidump_message(struct mapi_SPropValue_array *, const char *, mapi_object_t *); void mapidump_appointment(struct mapi_SPropValue_array *, const char *); void mapidump_contact(struct mapi_SPropValue_array *, const char *); const char *get_task_status(uint32_t); const char *get_importance(uint32_t); void mapidump_task(struct mapi_SPropValue_array *, const char *); void mapidump_note(struct mapi_SPropValue_array *, const char *); void mapidump_msgflags(uint32_t, const char *); void mapidump_newmail(struct NewMailNotification *, const char *); void mapidump_tags(enum MAPITAGS *, uint16_t, const char *); void mapidump_foldercreated(struct FolderCreatedNotification *, const char *); void mapidump_folderdeleted(struct FolderDeletedNotification *, const char *); void mapidump_foldermoved(struct FolderMoveCopyNotification *, const char *); void mapidump_foldercopied(struct FolderMoveCopyNotification *, const char *); void mapidump_messagedeleted(struct MessageDeletedNotification *, const char *); void mapidump_messagecreated(struct MessageCreatedNotification *, const char *); void mapidump_messagemodified(struct MessageModifiedNotification *, const char *); void mapidump_messagemoved(struct MessageMoveCopyNotification *, const char *); void mapidump_messagecopied(struct MessageMoveCopyNotification *, const char *); const char *mapidump_freebusy_month(uint32_t, uint32_t); uint32_t mapidump_freebusy_year(uint32_t, uint32_t); void mapidump_freebusy_date(uint32_t, const char *); void mapidump_freebusy_event(struct Binary_r *, uint32_t, uint32_t, const char *); void mapidump_languages_list(void); /* The following public definitions come from libmapi/mapi_object.c */ enum MAPISTATUS mapi_object_init(mapi_object_t *); void mapi_object_release(mapi_object_t *); enum MAPISTATUS mapi_object_copy(mapi_object_t *, mapi_object_t *); struct mapi_session *mapi_object_get_session(mapi_object_t *); void mapi_object_set_session(mapi_object_t *, struct mapi_session *); mapi_id_t mapi_object_get_id(mapi_object_t *); void mapi_object_set_logon_id(mapi_object_t *, uint8_t); enum MAPISTATUS mapi_object_get_logon_id(mapi_object_t *, uint8_t *); void mapi_object_set_logon_store(mapi_object_t *); void mapi_object_debug(mapi_object_t *); enum MAPISTATUS mapi_object_bookmark_get_count(mapi_object_t *, uint32_t *); enum MAPISTATUS mapi_object_bookmark_debug(mapi_object_t *); /* The following public definitions come from libmapi/mapi_id_array.c */ enum MAPISTATUS mapi_id_array_init(TALLOC_CTX *, mapi_id_array_t *); enum MAPISTATUS mapi_id_array_release(mapi_id_array_t *); enum MAPISTATUS mapi_id_array_get(TALLOC_CTX *, mapi_id_array_t *, mapi_id_t **); enum MAPISTATUS mapi_id_array_add_obj(mapi_id_array_t *, mapi_object_t *); enum MAPISTATUS mapi_id_array_add_id(mapi_id_array_t *, mapi_id_t); enum MAPISTATUS mapi_id_array_del_id(mapi_id_array_t *, mapi_id_t); enum MAPISTATUS mapi_id_array_del_obj(mapi_id_array_t *, mapi_object_t *); /* The following public definitions come from libmapi/mapi_nameid.c */ struct mapi_nameid *mapi_nameid_new(TALLOC_CTX *); enum MAPISTATUS mapi_nameid_OOM_add(struct mapi_nameid *, const char *, const char *); enum MAPISTATUS mapi_nameid_lid_add(struct mapi_nameid *, uint16_t, const char *); enum MAPISTATUS mapi_nameid_string_add(struct mapi_nameid *, const char *, const char *); enum MAPISTATUS mapi_nameid_custom_lid_add(struct mapi_nameid *, uint16_t, uint16_t, const char *); enum MAPISTATUS mapi_nameid_custom_string_add(struct mapi_nameid *, const char *, uint16_t, const char *); enum MAPISTATUS mapi_nameid_canonical_add(struct mapi_nameid *, uint32_t); enum MAPISTATUS mapi_nameid_property_lookup(uint32_t); enum MAPISTATUS mapi_nameid_OOM_lookup(const char *, const char *, uint16_t *); enum MAPISTATUS mapi_nameid_lid_lookup(uint16_t, const char *, uint16_t *); enum MAPISTATUS mapi_nameid_lid_lookup_canonical(uint16_t, const char *, uint32_t *); enum MAPISTATUS mapi_nameid_string_lookup(const char *, const char *, uint16_t *); enum MAPISTATUS mapi_nameid_string_lookup_canonical(const char *, const char *, uint32_t *); enum MAPISTATUS mapi_nameid_SPropTagArray(struct mapi_nameid *, struct SPropTagArray *); enum MAPISTATUS mapi_nameid_map_SPropTagArray(struct mapi_nameid *, struct SPropTagArray *, struct SPropTagArray *); enum MAPISTATUS mapi_nameid_unmap_SPropTagArray(struct mapi_nameid *, struct SPropTagArray *); enum MAPISTATUS mapi_nameid_map_SPropValue(struct mapi_nameid *, struct SPropValue *, uint32_t, struct SPropTagArray *); enum MAPISTATUS mapi_nameid_unmap_SPropValue(struct mapi_nameid *, struct SPropValue *, uint32_t); enum MAPISTATUS mapi_nameid_lookup_SPropTagArray(struct mapi_nameid *, struct SPropTagArray *); enum MAPISTATUS mapi_nameid_lookup_SPropValue(struct mapi_nameid *, struct SPropValue *, unsigned long); enum MAPISTATUS mapi_nameid_GetIDsFromNames(struct mapi_nameid *, mapi_object_t *, struct SPropTagArray *); const char * get_namedid_name(uint32_t proptag); uint32_t get_namedid_value(const char *propname); uint16_t get_namedid_type(uint16_t untypedtag); /* The following public definitions come from libmapi/property.c */ struct SPropTagArray *set_SPropTagArray(TALLOC_CTX *, uint32_t, ...); enum MAPISTATUS SPropTagArray_add(TALLOC_CTX *, struct SPropTagArray *, enum MAPITAGS); enum MAPISTATUS SPropTagArray_delete(TALLOC_CTX *, struct SPropTagArray *, uint32_t); enum MAPISTATUS SPropTagArray_find(struct SPropTagArray, enum MAPITAGS, uint32_t *); const void *get_SPropValue(struct SPropValue *, enum MAPITAGS); struct SPropValue *get_SPropValue_SRowSet(struct SRowSet *, uint32_t); const void *get_SPropValue_SRowSet_data(struct SRowSet *, uint32_t); enum MAPISTATUS set_default_error_SPropValue_SRow(struct SRow *, enum MAPITAGS, void *); struct SPropValue *get_SPropValue_SRow(struct SRow *, uint32_t); const void *get_SPropValue_SRow_data(struct SRow *, uint32_t); const void *find_SPropValue_data(struct SRow *, uint32_t); const void *find_mapi_SPropValue_data(struct mapi_SPropValue_array *, uint32_t); const void *get_mapi_SPropValue_data(struct mapi_SPropValue *); const void *get_SPropValue_data(struct SPropValue *); bool set_SPropValue_proptag(struct SPropValue *, enum MAPITAGS, const void *); struct SPropValue *add_SPropValue(TALLOC_CTX *, struct SPropValue *, uint32_t *, enum MAPITAGS, const void *); struct mapi_SPropValue *add_mapi_SPropValue(TALLOC_CTX *, struct mapi_SPropValue *, uint16_t *, uint32_t, const void *); bool set_SPropValue(struct SPropValue *, const void *); uint32_t get_mapi_property_size(struct mapi_SPropValue *); void mapi_copy_spropvalues(TALLOC_CTX *, struct SPropValue *, struct SPropValue *, uint32_t); uint32_t cast_mapi_SPropValue(TALLOC_CTX *, struct mapi_SPropValue *, struct SPropValue *); uint32_t cast_SPropValue(TALLOC_CTX *, struct mapi_SPropValue *, struct SPropValue *); enum MAPISTATUS SRow_addprop(struct SRow *, struct SPropValue); uint32_t SRowSet_propcpy(TALLOC_CTX *, struct SRowSet *, struct SPropValue); void mapi_SPropValue_array_named(mapi_object_t *, struct mapi_SPropValue_array *); enum MAPISTATUS get_mapi_SPropValue_array_date_timeval(struct timeval *, struct mapi_SPropValue_array *, uint32_t); enum MAPISTATUS get_mapi_SPropValue_date_timeval(struct timeval *t, struct SPropValue); bool set_SPropValue_proptag_date_timeval(struct SPropValue *, enum MAPITAGS, const struct timeval *); struct RecurrencePattern *get_RecurrencePattern(TALLOC_CTX *, struct Binary_r *); struct AppointmentRecurrencePattern *get_AppointmentRecurrencePattern(TALLOC_CTX *mem_ctx, struct Binary_r *); struct Binary_r *set_RecurrencePattern(TALLOC_CTX *, const struct RecurrencePattern *); struct Binary_r *set_AppointmentRecurrencePattern(TALLOC_CTX *mem_ctx, const struct AppointmentRecurrencePattern *); struct TimeZoneStruct *get_TimeZoneStruct(TALLOC_CTX *, struct Binary_r *); struct Binary_r *set_TimeZoneStruct(TALLOC_CTX *, const struct TimeZoneStruct *); struct Binary_r *set_TimeZoneDefinition(TALLOC_CTX *, const struct TimeZoneDefinition *); struct PtypServerId *get_PtypServerId(TALLOC_CTX *, struct Binary_r *); struct GlobalObjectId *get_GlobalObjectId(TALLOC_CTX *, struct Binary_r *); struct MessageEntryId *get_MessageEntryId(TALLOC_CTX *, struct Binary_r *); struct FolderEntryId *get_FolderEntryId(TALLOC_CTX *, struct Binary_r *); struct AddressBookEntryId *get_AddressBookEntryId(TALLOC_CTX *, struct Binary_r *); const char *get_TypedString(struct TypedString *); bool set_mapi_SPropValue(TALLOC_CTX *, struct mapi_SPropValue *, const void *); bool set_mapi_SPropValue_proptag(TALLOC_CTX *, struct mapi_SPropValue *, uint32_t, const void *); struct PropertyValue_r *get_PropertyValue_PropertyRow(struct PropertyRow_r *, enum MAPITAGS); struct PropertyValue_r *get_PropertyValue_PropertyRowSet(struct PropertyRowSet_r *, enum MAPITAGS); const void *get_PropertyValue_PropertyRowSet_data(struct PropertyRowSet_r *, uint32_t); bool set_PropertyValue(struct PropertyValue_r *, const void *); const void *get_PropertyValue(struct PropertyValue_r *, enum MAPITAGS); const void *get_PropertyValue_data(struct PropertyValue_r *); enum MAPISTATUS PropertyRow_addprop(struct PropertyRow_r *, struct PropertyValue_r); const void *find_PropertyValue_data(struct PropertyRow_r *, uint32_t); uint32_t PropertyRowSet_propcpy(TALLOC_CTX *, struct PropertyRowSet_r *, struct PropertyValue_r); void cast_PropertyValue_to_SPropValue(struct PropertyValue_r *, struct SPropValue *); void cast_PropertyRow_to_SRow(TALLOC_CTX *, struct PropertyRow_r *, struct SRow *); void cast_PropertyRowSet_to_SRowSet(TALLOC_CTX *, struct PropertyRowSet_r *, struct SRowSet *); /* The following public definitions come from libmapi/IABContainer.c */ enum MAPISTATUS ResolveNames(struct mapi_session *, const char **, struct SPropTagArray *, struct PropertyRowSet_r **, struct PropertyTagArray_r **, uint32_t); enum MAPISTATUS GetGALTable(struct mapi_session *, struct SPropTagArray *, struct PropertyRowSet_r **, uint32_t, uint8_t); enum MAPISTATUS GetGALTableCount(struct mapi_session *, uint32_t *); enum MAPISTATUS GetABRecipientInfo(struct mapi_session *, const char *, struct SPropTagArray *, struct PropertyRowSet_r **); /* The following public definitions come from libmapi/IProfAdmin.c */ enum MAPISTATUS mapi_profile_add_string_attr(struct mapi_context *, const char *, const char *, const char *); enum MAPISTATUS mapi_profile_modify_string_attr(struct mapi_context *, const char *, const char *, const char *); enum MAPISTATUS mapi_profile_delete_string_attr(struct mapi_context *, const char *, const char *, const char *); const char *mapi_profile_get_ldif_path(void); enum MAPISTATUS CreateProfileStore(const char *, const char *); enum MAPISTATUS OpenProfile(struct mapi_context *, struct mapi_profile *, const char *, const char *); enum MAPISTATUS LoadProfile(struct mapi_context *, struct mapi_profile *); enum MAPISTATUS ShutDown(struct mapi_profile *); enum MAPISTATUS CreateProfile(struct mapi_context *, const char *, const char *, const char *, uint32_t); enum MAPISTATUS DeleteProfile(struct mapi_context *, const char *); enum MAPISTATUS ChangeProfilePassword(struct mapi_context *, const char *, const char *, const char *); enum MAPISTATUS CopyProfile(struct mapi_context *, const char *, const char *); enum MAPISTATUS DuplicateProfile(struct mapi_context *, const char *, const char *, const char *); enum MAPISTATUS RenameProfile(struct mapi_context *, const char *, const char *); enum MAPISTATUS SetDefaultProfile(struct mapi_context *, const char *); enum MAPISTATUS GetDefaultProfile(struct mapi_context *, char **); enum MAPISTATUS GetProfileTable(struct mapi_context *, struct SRowSet *); enum MAPISTATUS GetProfileAttr(struct mapi_profile *, const char *, unsigned int *, char ***); enum MAPISTATUS FindProfileAttr(struct mapi_profile *, const char *, const char *); enum MAPISTATUS ProcessNetworkProfile(struct mapi_session *, const char *, mapi_profile_callback_t, const void *); /* The following public definitions come from libmapi/IMAPIContainer.c */ enum MAPISTATUS GetContentsTable(mapi_object_t *, mapi_object_t *, uint8_t, uint32_t *); enum MAPISTATUS GetHierarchyTable(mapi_object_t *, mapi_object_t *, uint8_t, uint32_t *); enum MAPISTATUS GetPermissionsTable(mapi_object_t *, uint8_t, mapi_object_t *); enum MAPISTATUS GetRulesTable(mapi_object_t *, mapi_object_t *, uint8_t); enum MAPISTATUS ModifyPermissions(mapi_object_t *, uint8_t, struct mapi_PermissionsData *); enum MAPISTATUS SetSearchCriteria(mapi_object_t *, struct mapi_SRestriction *, uint32_t, mapi_id_array_t *); enum MAPISTATUS GetSearchCriteria(mapi_object_t *, struct mapi_SRestriction *, uint32_t *, uint16_t *, uint64_t **); /* The following public definitions come from libmapi/IMAPIFolder.c */ enum MAPISTATUS CreateMessage(mapi_object_t *, mapi_object_t *); enum MAPISTATUS DeleteMessage(mapi_object_t *, mapi_id_t *, uint32_t); enum MAPISTATUS HardDeleteMessage(mapi_object_t *, mapi_id_t *, uint16_t); enum MAPISTATUS GetMessageStatus(mapi_object_t *, mapi_id_t, uint32_t *); enum MAPISTATUS SetMessageStatus(mapi_object_t *, mapi_id_t, uint32_t, uint32_t, uint32_t *); enum MAPISTATUS MoveCopyMessages(mapi_object_t *, mapi_object_t *, mapi_id_array_t *, bool); enum MAPISTATUS CreateFolder(mapi_object_t *, enum FOLDER_TYPE, const char *, const char *, uint32_t, mapi_object_t *); enum MAPISTATUS EmptyFolder(mapi_object_t *); enum MAPISTATUS DeleteFolder(mapi_object_t *, mapi_id_t, uint8_t, bool *); enum MAPISTATUS MoveFolder(mapi_object_t *, mapi_object_t *, mapi_object_t *, char *, bool); enum MAPISTATUS CopyFolder(mapi_object_t *, mapi_object_t *, mapi_object_t *, char *, bool, bool); enum MAPISTATUS SetReadFlags(mapi_object_t *, uint8_t, uint16_t, uint64_t *); enum MAPISTATUS HardDeleteMessagesAndSubfolders(mapi_object_t *); /* The following public definitions come from libmapi/IMAPIProp.c */ enum MAPISTATUS GetProps(mapi_object_t *, uint32_t, struct SPropTagArray *, struct SPropValue **, uint32_t *); enum MAPISTATUS SetProps(mapi_object_t *, uint32_t, struct SPropValue *, unsigned long); enum MAPISTATUS SaveChangesAttachment(mapi_object_t *, mapi_object_t *, enum SaveFlags); enum MAPISTATUS GetPropList(mapi_object_t *, struct SPropTagArray *); enum MAPISTATUS GetPropsAll(mapi_object_t *, uint32_t, struct mapi_SPropValue_array *); enum MAPISTATUS DeleteProps(mapi_object_t *, struct SPropTagArray *); enum MAPISTATUS SetPropertiesNoReplicate(mapi_object_t *, uint32_t, struct SPropValue *, unsigned long); enum MAPISTATUS DeletePropertiesNoReplicate(mapi_object_t *, struct SPropTagArray *); enum MAPISTATUS GetNamesFromIDs(mapi_object_t *, enum MAPITAGS, uint16_t *, struct MAPINAMEID **); enum MAPISTATUS GetIDsFromNames(mapi_object_t *, uint16_t, struct MAPINAMEID *, uint32_t, struct SPropTagArray **); enum MAPISTATUS QueryNamedProperties(mapi_object_t *, uint8_t, struct GUID *, uint16_t *, uint16_t **, struct MAPINAMEID **); enum MAPISTATUS CopyProps(mapi_object_t *, mapi_object_t *, struct SPropTagArray *, uint8_t, uint16_t *, struct PropertyProblem **); enum MAPISTATUS CopyTo(mapi_object_t *, mapi_object_t *, struct SPropTagArray *, uint8_t, uint16_t *, struct PropertyProblem **); /* The following public definitions come from libmapi/IMAPISession.c */ enum MAPISTATUS OpenPublicFolder(struct mapi_session *, mapi_object_t *); enum MAPISTATUS OpenMsgStore(struct mapi_session *, mapi_object_t *); enum MAPISTATUS OpenUserMailbox(struct mapi_session *, const char *, mapi_object_t *); /* The following public definitions come from libmapi/IMAPISupport.c */ enum MAPISTATUS Subscribe(mapi_object_t *, uint32_t *, uint16_t, bool, mapi_notify_callback_t, void *); enum MAPISTATUS Unsubscribe(struct mapi_session *, uint32_t); enum MAPISTATUS DispatchNotifications(struct mapi_session *); enum MAPISTATUS MonitorNotification(struct mapi_session *, void *, struct mapi_notify_continue_callback_data *); /* The following public definitions come from libmapi/IMAPITable.c */ enum MAPISTATUS SetColumns(mapi_object_t *, struct SPropTagArray *); enum MAPISTATUS QueryPosition(mapi_object_t *, uint32_t *, uint32_t *); enum MAPISTATUS QueryRows(mapi_object_t *, uint16_t, enum QueryRowsFlags, struct SRowSet *); enum MAPISTATUS QueryColumns(mapi_object_t *, struct SPropTagArray *); enum MAPISTATUS SeekRow(mapi_object_t *, enum BOOKMARK, int32_t, uint32_t *); enum MAPISTATUS SeekRowBookmark(mapi_object_t *, uint32_t, uint32_t, uint32_t *); enum MAPISTATUS SeekRowApprox(mapi_object_t *, uint32_t, uint32_t); enum MAPISTATUS CreateBookmark(mapi_object_t *, uint32_t *); enum MAPISTATUS FreeBookmark(mapi_object_t *, uint32_t); enum MAPISTATUS SortTable(mapi_object_t *, struct SSortOrderSet *); enum MAPISTATUS Reset(mapi_object_t *); enum MAPISTATUS Restrict(mapi_object_t *, struct mapi_SRestriction *, uint8_t *); enum MAPISTATUS FindRow(mapi_object_t *, struct mapi_SRestriction *, enum BOOKMARK, enum FindRow_ulFlags, struct SRowSet *); enum MAPISTATUS GetStatus(mapi_object_t *, uint8_t *); enum MAPISTATUS Abort(mapi_object_t *, uint8_t *); enum MAPISTATUS ExpandRow(mapi_object_t *, uint64_t, uint16_t, struct SRowSet *, uint32_t *); enum MAPISTATUS CollapseRow(mapi_object_t *, uint64_t, uint32_t *); enum MAPISTATUS GetCollapseState(mapi_object_t *, uint64_t, uint32_t, struct SBinary_short *); enum MAPISTATUS SetCollapseState(mapi_object_t *, struct SBinary_short *); /* The following public definitions come from libmapi/IMSProvider.c */ enum MAPISTATUS RfrGetNewDSA(struct mapi_context *, struct mapi_session *, const char *, const char *, char **); enum MAPISTATUS RfrGetFQDNFromLegacyDN(struct mapi_context *, struct mapi_session *, const char **); enum MAPISTATUS Logoff(mapi_object_t *); enum MAPISTATUS RegisterNotification(struct mapi_session *); enum MAPISTATUS RegisterAsyncNotification(struct mapi_session *, uint32_t *); /* The following public definitions come from libmapi/IMessage.c */ enum MAPISTATUS CreateAttach(mapi_object_t *, mapi_object_t *); enum MAPISTATUS DeleteAttach(mapi_object_t *, uint32_t); enum MAPISTATUS GetAttachmentTable(mapi_object_t *, mapi_object_t *); enum MAPISTATUS GetValidAttach(mapi_object_t *, uint16_t *, uint32_t **); enum MAPISTATUS OpenAttach(mapi_object_t *, uint32_t,mapi_object_t *); enum MAPISTATUS SetRecipientType(struct SRow *, enum ulRecipClass); enum MAPISTATUS ModifyRecipients(mapi_object_t *, struct SRowSet *); enum MAPISTATUS ReadRecipients(mapi_object_t *, uint32_t, uint8_t *, struct ReadRecipientRow **); enum MAPISTATUS RemoveAllRecipients(mapi_object_t *); enum MAPISTATUS SubmitMessage(mapi_object_t *); enum MAPISTATUS AbortSubmit(mapi_object_t *, mapi_object_t *, mapi_object_t *); enum MAPISTATUS SaveChangesMessage(mapi_object_t *, mapi_object_t *, uint8_t); enum MAPISTATUS TransportSend(mapi_object_t *, struct mapi_SPropValue_array *); enum MAPISTATUS GetRecipientTable(mapi_object_t *, struct SRowSet *, struct SPropTagArray *); enum MAPISTATUS SetMessageReadFlag(mapi_object_t *, mapi_object_t *, uint8_t); enum MAPISTATUS OpenEmbeddedMessage(mapi_object_t *, mapi_object_t *, enum OpenEmbeddedMessage_OpenModeFlags); /* The following public definitions come from libmapi/IMsgStore.c */ enum MAPISTATUS OpenFolder(mapi_object_t *, mapi_id_t,mapi_object_t *); enum MAPISTATUS PublicFolderIsGhosted(mapi_object_t *, mapi_object_t *, bool *); enum MAPISTATUS OpenPublicFolderByName(mapi_object_t *, mapi_object_t *, const char *); enum MAPISTATUS SetReceiveFolder(mapi_object_t *, mapi_object_t *, const char *); enum MAPISTATUS GetReceiveFolder(mapi_object_t *, mapi_id_t *, const char *); enum MAPISTATUS GetReceiveFolderTable(mapi_object_t *, struct SRowSet *); enum MAPISTATUS GetTransportFolder(mapi_object_t *, mapi_id_t *); enum MAPISTATUS GetOwningServers(mapi_object_t *, mapi_object_t *, uint16_t *, uint16_t *, char **); enum MAPISTATUS GetStoreState(mapi_object_t *, uint32_t *); enum MAPISTATUS GetOutboxFolder(mapi_object_t *, mapi_id_t *); enum MAPISTATUS TransportNewMail(mapi_object_t *, mapi_object_t *, mapi_object_t *,const char *, uint32_t); /* The following public definitions come from libmapi/IStoreFolder.c */ enum MAPISTATUS OpenMessage(mapi_object_t *, mapi_id_t, mapi_id_t, mapi_object_t *, uint8_t); enum MAPISTATUS ReloadCachedInformation(mapi_object_t *); /* The following public definitions come from libmapi/IUnknown.c */ enum MAPISTATUS MAPIAllocateBuffer(struct mapi_context *, uint32_t, void **); enum MAPISTATUS MAPIFreeBuffer(void *); enum MAPISTATUS Release(mapi_object_t *); enum MAPISTATUS GetLastError(void); enum MAPISTATUS GetLongTermIdFromId(mapi_object_t *, mapi_id_t, struct LongTermId *); enum MAPISTATUS GetIdFromLongTermId(mapi_object_t *, struct LongTermId, mapi_id_t *); /* The following public definitions come from libmapi/IStream.c */ enum MAPISTATUS OpenStream(mapi_object_t *, enum MAPITAGS, enum OpenStream_OpenModeFlags, mapi_object_t *); enum MAPISTATUS ReadStream(mapi_object_t *, unsigned char *, uint16_t, uint16_t *); enum MAPISTATUS WriteStream(mapi_object_t *, DATA_BLOB *, uint16_t *); enum MAPISTATUS CommitStream(mapi_object_t *); enum MAPISTATUS GetStreamSize(mapi_object_t *, uint32_t *); enum MAPISTATUS SeekStream(mapi_object_t *, uint8_t, uint64_t, uint64_t *); enum MAPISTATUS SetStreamSize(mapi_object_t *, uint64_t); enum MAPISTATUS CopyToStream(mapi_object_t *, mapi_object_t *, uint64_t, uint64_t *, uint64_t *); enum MAPISTATUS LockRegionStream(mapi_object_t *, uint64_t, uint64_t, uint32_t); enum MAPISTATUS UnlockRegionStream(mapi_object_t *, uint64_t, uint64_t, uint32_t); enum MAPISTATUS CloneStream(mapi_object_t *, mapi_object_t *); enum MAPISTATUS WriteAndCommitStream(mapi_object_t *, DATA_BLOB *, uint16_t *); /* The following public definitions come from libmapi/IXPLogon.c */ enum MAPISTATUS AddressTypes(mapi_object_t *, uint16_t *, struct mapi_LPSTR **); enum MAPISTATUS SetSpooler(mapi_object_t *); enum MAPISTATUS SpoolerLockMessage(mapi_object_t *, mapi_object_t *, enum LockState); enum MAPISTATUS OptionsData(mapi_object_t *, const char *, uint8_t **, uint16_t *, uint8_t **, uint16_t *, const char** ); /* The following public definitions come from libmapi/FXICS.c */ enum MAPISTATUS GetLocalReplicaIds(mapi_object_t *, uint32_t, struct GUID *, uint8_t [6]); enum MAPISTATUS TellVersion(mapi_object_t *, uint16_t version[3]); enum MAPISTATUS FXDestConfigure(mapi_object_t *, enum FastTransferDestConfig_SourceOperation, mapi_object_t *); enum MAPISTATUS FXCopyFolder(mapi_object_t *, uint8_t, uint8_t, mapi_object_t *); enum MAPISTATUS FXCopyMessages(mapi_object_t *, mapi_id_array_t *, uint8_t, uint8_t, mapi_object_t *); enum MAPISTATUS FXCopyTo(mapi_object_t *, uint8_t, uint32_t, uint8_t, struct SPropTagArray *, mapi_object_t *); enum MAPISTATUS FXCopyProperties(mapi_object_t *, uint8_t, uint32_t, uint8_t, struct SPropTagArray *, mapi_object_t *); enum MAPISTATUS FXGetBuffer(mapi_object_t *obj_source_context, uint16_t maxSize, enum TransferStatus *, uint16_t *, uint16_t *, DATA_BLOB *); enum MAPISTATUS FXPutBuffer(mapi_object_t *obj_dest_context, DATA_BLOB *blob, uint16_t *usedSize); enum MAPISTATUS ICSSyncConfigure(mapi_object_t *, enum SynchronizationType, uint8_t, uint16_t, uint32_t, DATA_BLOB, struct SPropTagArray*, mapi_object_t *); enum MAPISTATUS ICSSyncUploadStateBegin(mapi_object_t *, enum StateProperty, uint32_t); enum MAPISTATUS ICSSyncUploadStateContinue(mapi_object_t *, DATA_BLOB); enum MAPISTATUS ICSSyncUploadStateEnd(mapi_object_t *); enum MAPISTATUS SetLocalReplicaMidsetDeleted(mapi_object_t *, const struct GUID, const uint8_t GlobalCountLow[6], const uint8_t GlobalCountHigh[6]); enum MAPISTATUS ICSSyncOpenCollector(mapi_object_t *, bool, mapi_object_t *); enum MAPISTATUS ICSSyncGetTransferState(mapi_object_t *, mapi_object_t *); /* The following public definitions come from libmapi/freebusy.c */ enum MAPISTATUS GetUserFreeBusyData(mapi_object_t *, const char *, struct SRow *); enum MAPISTATUS IsFreeBusyConflict(mapi_object_t *, struct FILETIME *, bool *); int GetFreeBusyYear(const uint32_t *); /* The following public definitions come from libmapi/x500.c */ char *x500_get_dn_element(TALLOC_CTX *, const char *, const char *); char *x500_truncate_dn_last_elements(TALLOC_CTX *, const char *, uint32_t); char *x500_get_servername(const char *); /* The following public definitions come from libmapi/lzfu.c */ enum MAPISTATUS WrapCompressedRTFStream(mapi_object_t *, DATA_BLOB *); enum MAPISTATUS uncompress_rtf(TALLOC_CTX *, uint8_t *, uint32_t, DATA_BLOB *); uint32_t calculateCRC(uint8_t *, uint32_t, uint32_t); enum MAPISTATUS compress_rtf(TALLOC_CTX *, const char*, const size_t, uint8_t **, size_t *); /* The following public definitions come from libmapi/utils.c */ char *guid_delete_dash(TALLOC_CTX *, const char *); struct Binary_r *generate_recipient_entryid(TALLOC_CTX *, const char *); enum MAPISTATUS GetFIDFromEntryID(uint16_t, uint8_t *, uint64_t, uint64_t *); enum MAPISTATUS EntryIDFromSourceIDForMessage(TALLOC_CTX *, mapi_object_t *, mapi_object_t *, mapi_object_t *, struct SBinary_short *); /* The following public definitions come from libmapi/notif.c */ enum MAPISTATUS SyncOpenAdvisor(mapi_object_t *, mapi_object_t *); enum MAPISTATUS SetSyncNotificationGuid(mapi_object_t *, const struct GUID); /* The following public definitions come from libmapi/socket/netif.c */ int get_interfaces_oc(struct iface_struct *, int); /* The following public definitions come from libmapi/fxparser.c */ struct fx_parser_context; typedef enum MAPISTATUS (*fxparser_marker_callback_t)(uint32_t, void *); typedef enum MAPISTATUS (*fxparser_delprop_callback_t)(uint32_t, void *); typedef enum MAPISTATUS (*fxparser_namedprop_callback_t)(uint32_t, struct MAPINAMEID, void *); typedef enum MAPISTATUS (*fxparser_property_callback_t)(struct SPropValue, void *); struct fx_parser_context *fxparser_init(TALLOC_CTX *, void *); void fxparser_set_marker_callback(struct fx_parser_context *, fxparser_marker_callback_t); void fxparser_set_delprop_callback(struct fx_parser_context *, fxparser_delprop_callback_t); void fxparser_set_namedprop_callback(struct fx_parser_context *, fxparser_namedprop_callback_t); void fxparser_set_property_callback(struct fx_parser_context *, fxparser_property_callback_t); enum MAPISTATUS fxparser_parse(struct fx_parser_context *, DATA_BLOB *); /* The following public definitions come from libmapi/idset.c */ uint64_t exchange_globcnt(uint64_t); struct rawidset * RAWIDSET_make(TALLOC_CTX *, bool, bool); void RAWIDSET_push_eid(struct rawidset *, uint64_t); void RAWIDSET_push_guid_glob(struct rawidset *, const struct GUID *, uint64_t); struct idset * RAWIDSET_convert_to_idset(TALLOC_CTX *, const struct rawidset *); struct idset * IDSET_parse(TALLOC_CTX *, DATA_BLOB, bool); struct idset * IDSET_merge_idsets(TALLOC_CTX *mem_ctx, const struct idset *, const struct idset *); struct Binary_r * IDSET_serialize(TALLOC_CTX *, const struct idset *); bool IDSET_includes_guid_glob(const struct idset *, struct GUID *, uint64_t); bool IDSET_includes_eid(const struct idset *, uint64_t); void IDSET_remove_rawidset(struct idset *, const struct rawidset *); void IDSET_dump(const struct idset *, const char *); void ndr_push_idset(struct ndr_push *, struct idset *); struct globset_range * GLOBSET_parse(TALLOC_CTX *, DATA_BLOB, uint32_t *, uint32_t *); /* Size functions */ /** \details struct RecurrencePattern has fixed response size for: -# ReaderVersion: uint16_t -# WriterVersion: uint16_t -# RecurFrequency: uint16_t -# PatternType: uint16_t -# CalendarType: uint16_t -# FirstDateTime: uint32_t -# Period: uint32_t -# SlidingFlag: uint32_t -# EndType: uint32_t -# OccurrenceCount: uint32_t -# FirstDOW: uint32_t -# DeletedInstanceCount: uint32_t -# ModifiedInstanceCount: uint32_t -# StartDate: uint32_t -# EndDate: uint32_t */ #define SIZE_DFLT_RECURRENCEPATTERN 50 size_t set_RecurrencePattern_size(const struct RecurrencePattern *); /** \details struct AppointmentRecurrencePattern has fixed response size for: -# ReaderVersion2: uint32_t -# WriterVersion2: uint32_t -# StartTimeOffset: uint32_t -# EndTimeOffset: uint32_t -# ExceptionCount: uint16_t -# ReservedBlock1Size: uint32_t -# ReservedBlock2Size: uint32_t */ #define SIZE_DFLT_APPOINTMENTRECURRENCEPATTERN 26 size_t set_AppointmentRecurrencePattern_size(const struct AppointmentRecurrencePattern *); /** \details struct ExceptionInfo has fixed response size for: -# StartDateTime: uint32_t -# EndDateTime: uint32_t -# OriginalStartDate: uint32_t -# OverrideFlags: uint16_t -# AppointmentColor uint32_t -# ReservedBlock1Size uint32_t */ #define SIZE_DFLT_EXCEPTIONINFO 22 size_t set_ExceptionInfo_size(const struct ExceptionInfo *); /** \details struct ExceptionInfo has not fixed response size */ #define SIZE_DFLT_EXTENDEDEXCEPTION 0 size_t set_ExtendedException_size(uint32_t, enum OverrideFlags, const struct ExtendedException *); /** \details struct ExtendedException has fixed response size for: -# ReservedBlockEE1Size: uint32_t -# ReservedBlockEE2Size: uint32_t */ // #define SIZE_DFLT_EXTENDEDEXCEPTION 8 // size_t set_ExtendedException_size(const struct ExtendedException *); __END_DECLS #undef _PRINTF_ATTRIBUTE #define _PRINTF_ATTRIBUTE(a1, a2) #endif /* __LIBMAPI_H__ */ openchange-2.0/libmapi/libmapi_private.h000066400000000000000000000141261223057412600204250ustar00rootroot00000000000000/* OpenChange MAPI implementation. libmapi private header file Copyright (C) Julien Kerihuel 2010-2011. This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see . */ #ifndef __LIBMAPI_PRIVATE_H__ #define __LIBMAPI_PRIVATE_H__ #include "config.h" #define __STDC_FORMAT_MACROS 1 #include #if defined(HAVE_PTHREADS) #include #elif defined(HAVE_GTHREAD) #include #endif #undef _PRINTF_ATTRIBUTE #define _PRINTF_ATTRIBUTE(a1, a2) PRINTF_ATTRIBUTE(a1, a2) /* This provides a "we need to fix this problem" signal in development builds, but not in release builds */ #if SNAPSHOT == yes #include #define OPENCHANGE_ASSERT() assert(0) #else #define OPENCHANGE_ASSERT() #endif #ifndef __BEGIN_DECLS #ifdef __cplusplus #define __BEGIN_DECLS extern "C" { #define __END_DECLS } #else #define __BEGIN_DECLS #define __END_DECLS #endif #endif __BEGIN_DECLS /* The following private definitions come from ndr_mapi.c */ void obfuscate_data(uint8_t *, uint32_t, uint8_t); enum ndr_err_code ndr_pull_lzxpress_decompress(struct ndr_pull *, struct ndr_pull **, ssize_t); enum ndr_err_code ndr_push_lzxpress_compress(struct ndr_push *, struct ndr_push *); enum ndr_err_code ndr_push_ExtendedException(struct ndr_push *, int, uint16_t, const struct ExceptionInfo *, const struct ExtendedException *); enum ndr_err_code ndr_pull_ExtendedException(struct ndr_pull *, int, uint16_t, const struct ExceptionInfo *, struct ExtendedException *); enum ndr_err_code ndr_push_AppointmentRecurrencePattern(struct ndr_push *, int, const struct AppointmentRecurrencePattern *); enum ndr_err_code ndr_pull_AppointmentRecurrencePattern(struct ndr_pull *, int, struct AppointmentRecurrencePattern *); /* The following private definitions come from libmapi/nspi.c */ int nspi_disconnect_dtor(void *); /* The following private definitions come from libmapi/emsmdb.c */ struct emsmdb_context *emsmdb_connect(TALLOC_CTX *, struct mapi_session *, struct dcerpc_pipe *, struct cli_credentials *, int *); struct emsmdb_context *emsmdb_connect_ex(TALLOC_CTX *, struct mapi_session *, struct dcerpc_pipe *, struct cli_credentials *, int *); int emsmdb_disconnect_dtor(void *); enum MAPISTATUS emsmdb_disconnect(struct emsmdb_context *); struct mapi_notify_ctx *emsmdb_bind_notification(struct mapi_context *, TALLOC_CTX *); NTSTATUS emsmdb_register_notification(struct mapi_session *, struct NOTIFKEY *); void free_emsmdb_property(struct SPropValue *, void *); const void *pull_emsmdb_property(TALLOC_CTX *, uint32_t *, enum MAPITAGS, DATA_BLOB *); enum MAPISTATUS emsmdb_get_SPropValue(TALLOC_CTX *, DATA_BLOB *, struct SPropTagArray *, struct SPropValue **, uint32_t *, uint8_t); void emsmdb_get_SRow(TALLOC_CTX *, struct SRow *, struct SPropTagArray *, uint16_t, DATA_BLOB *, uint8_t, uint8_t); enum MAPISTATUS emsmdb_async_connect(struct emsmdb_context *); bool server_version_at_least(struct emsmdb_context *, uint16_t, uint16_t, uint16_t, uint16_t); /* The following private definition comes from libmapi/async_emsmdb.c */ enum MAPISTATUS emsmdb_async_waitex(struct emsmdb_context *, uint32_t, uint32_t *); /* The following private definitions come from auto-generated libmapi/mapicode.c */ void set_errno(enum MAPISTATUS); /* The following private definitions come from libmapi/codepage_lcid.c */ void mapi_get_language_list(void); /* The following private definitions come from libmapi/mapi_object.c */ int mapi_object_is_invalid(mapi_object_t *); void mapi_object_set_id(mapi_object_t *, mapi_id_t); mapi_handle_t mapi_object_get_handle(mapi_object_t *); void mapi_object_set_handle(mapi_object_t *, mapi_handle_t); void mapi_object_table_init(TALLOC_CTX *, mapi_object_t *); enum MAPISTATUS mapi_object_bookmark_find(mapi_object_t *, uint32_t,struct SBinary_short *); /* The following private definitions come from libmapi/property.c */ enum MAPITAGS *get_MAPITAGS_SRow(TALLOC_CTX *, struct SRow *, uint32_t *); uint32_t MAPITAGS_delete_entries(enum MAPITAGS *, uint32_t, uint32_t, ...); size_t get_utf8_utf16_conv_length(const char *); /* The following private definitions come from libmapi/IProfAdmin.c */ enum MAPISTATUS OpenProfileStore(TALLOC_CTX *, struct ldb_context **, const char *); /* The following private definitions come from libmapi/IMAPISupport.c */ enum MAPISTATUS ProcessNotification(struct mapi_notify_ctx *, struct mapi_response *); /* The following private definitions come from libmapi/IMAPITable.c */ uint32_t get_mapi_SRestriction_size(struct mapi_SRestriction *); /* The following private definitions come from libmapi/IMSProvider.c */ enum MAPISTATUS Logon(struct mapi_session *, struct mapi_provider *, enum PROVIDER_ID); enum MAPISTATUS GetNewLogonId(struct mapi_session *, uint8_t *); /* The following private definitions come from libmapi/IMessage.c */ uint8_t mapi_recipients_get_org_length(struct mapi_profile *); uint16_t mapi_recipients_RecipientFlags(struct SRow *); /* The following private definitions come from libmapi/socket/interface.c */ void load_interfaces(TALLOC_CTX *, const char **, struct interface **); int iface_count(struct interface *); const char *iface_n_ip(struct interface *, int); const char *iface_n_bcast(struct interface *, int); const char *iface_n_netmask(struct interface *, int); const char *iface_best_ip(struct interface *, const char *); bool iface_is_local(struct interface *, const char *); bool iface_same_net(const char *, const char *, const char *); __END_DECLS #undef _PRINTF_ATTRIBUTE #define _PRINTF_ATTRIBUTE(a1, a2) #endif /* !__LIBMAPI_PRIVATE_H__ */ openchange-2.0/libmapi/lzfu.c000066400000000000000000000446471223057412600162440ustar00rootroot00000000000000/* OpenChange MAPI implementation. This work is based on libpst-0.5.2, and the author(s) of that code will also hold appropriate copyrights. Copyright (C) Julien Kerihuel 2007-2011. This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see . */ #include "libmapi/libmapi.h" #include "libmapi/libmapi_private.h" #include /** \file lzfu.c \brief Compressed RTF related functions */ #if BYTE_ORDER == BIG_ENDIAN #define LE32_CPU(x) \ x = ((((x) & 0xff000000) >> 24) | \ (((x) & 0x00ff0000) >> 8 ) | \ (((x) & 0x0000ff00) << 8 ) | \ (((x) & 0x000000ff) << 24)); #define LE16_CPU(x) \ x = ((((x) & 0xff00) >> 8) | \ (((x) & 0x00ff) << 8)); #elif BYTE_ORDER == LITTLE_ENDIAN #define LE32_CPU(x) {} #define LE16_CPU(x) {} #else #error Byte order not supported #endif /* BYTE_ORDER */ #define LZFU_COMPRESSED 0x75465a4c #define LZFU_UNCOMPRESSED 0x414c454d /* Initial directory */ #define LZFU_INITDICT \ "{\\rtf1\\ansi\\mac\\deff0\\deftab720{\\fonttbl;}" \ "{\\f0\\fnil \\froman \\fswiss \\fmodern \\fscrip" \ "t \\fdecor MS Sans SerifSymbolArialTimes Ne" \ "w RomanCourier{\\colortbl\\red0\\green0\\blue0" \ "\r\n\\par \\pard\\plain\\f0\\fs20\\b\\i\\u\\tab" \ "\\tx" /* initial length of dictionary */ #define LZFU_INITLENGTH 207 #define LZFU_DICTLENGTH 0x1000 #define LZFU_HEADERLENGTH 0x10 /* header for compressed rtf */ typedef struct _lzfuheader { uint32_t cbSize; uint32_t cbRawSize; uint32_t dwMagic; uint32_t dwCRC; } lzfuheader; /** \details creates a DATA_BLOB in uncompressed Rich Text Format (RTF) from the compressed format used in the PR_RTF_COMPRESSED property opened in the stream. \param obj_stream stream object with RTF stream content \param rtf the output blob with uncompressed content \return MAPI_E_SUCCESS on success, otherwise MAPI error. Possible MAPI error codes are: - MAPI_E_NOT_INITIALIZED: MAPI subsystem has not been initialized - MAPI_E_INVALID_PARAMETER: obj_stream is not a valid pointer - MAPI_E_CORRUPT_DATA: a problem was encountered while decompressing the RTF compressed data - MAPI_E_CALL_FAILED: A network problem was encountered during the transaction \note Developers may also call GetLastError() to retrieve the last MAPI error code. \note rtf->data needs to be freed with MAPIFreeBuffer \sa OpenStream */ _PUBLIC_ enum MAPISTATUS WrapCompressedRTFStream(mapi_object_t *obj_stream, DATA_BLOB *rtf) { enum MAPISTATUS retval; struct mapi_context *mapi_ctx; struct mapi_session *session; TALLOC_CTX *mem_ctx; uint32_t in_size; uint8_t *rtfcomp; uint16_t read_size; unsigned char buf[0x1000]; /* sanity check and init */ OPENCHANGE_RETVAL_IF(!obj_stream, MAPI_E_INVALID_PARAMETER, NULL); session = mapi_object_get_session(obj_stream); OPENCHANGE_RETVAL_IF(!session, MAPI_E_NOT_INITIALIZED, NULL); mapi_ctx = session->mapi_ctx; OPENCHANGE_RETVAL_IF(!mapi_ctx, MAPI_E_NOT_INITIALIZED, NULL); mem_ctx = mapi_ctx->mem_ctx; /* Read the stream pointed by obj_stream */ read_size = 0; in_size = 0; rtfcomp = talloc_zero(mem_ctx, uint8_t); do { retval = ReadStream(obj_stream, buf, 0x1000, &read_size); OPENCHANGE_RETVAL_IF(retval, GetLastError(), rtf->data); if (read_size) { rtfcomp = talloc_realloc(mem_ctx, rtfcomp, uint8_t, in_size + read_size); memcpy(&(rtfcomp[in_size]), buf, read_size); in_size += read_size; } } while (read_size); return uncompress_rtf(mem_ctx, rtfcomp, in_size, rtf); } typedef struct _decompression_state { uint8_t* dict; uint32_t dict_writeoffset; uint8_t* compressed_data; uint32_t in_size; uint32_t in_pos; } decompression_state; /** Initialise the decompression_state \param mem_ctx the memory context to allocate the decompression state on \param dict the resulting decompression_state */ static void initialise_decompression_state(TALLOC_CTX *mem_ctx, uint8_t *compressed_data, uint32_t in_size, decompression_state *state) { state->dict = talloc_array(mem_ctx, uint8_t, LZFU_DICTLENGTH); memcpy(state->dict, LZFU_INITDICT, LZFU_INITLENGTH); state->dict_writeoffset = LZFU_INITLENGTH; state->compressed_data = compressed_data; state->in_size = in_size; state->in_pos = LZFU_HEADERLENGTH; } static void cleanup_decompression_state(decompression_state *state) { talloc_free(state->dict); } typedef struct _output_state { uint32_t out_size; uint32_t out_pos; DATA_BLOB *output_blob; } output_state; static void initialise_output_state(TALLOC_CTX *mem_ctx, output_state *state, uint32_t rawSize, DATA_BLOB *output_blob) { state->out_pos = 0; state->out_size = rawSize + LZFU_HEADERLENGTH + 4; output_blob->data = (uint8_t *) talloc_size(mem_ctx, state->out_size); output_blob->length = 0; state->output_blob = output_blob; } static void parse_header(uint8_t *header_data, lzfuheader *header) { memcpy(header, header_data, sizeof(*header)); LE32_CPU(header->cbSize); LE32_CPU(header->cbRawSize); LE32_CPU(header->dwMagic); LE32_CPU(header->dwCRC); /* DEBUG(2, ("COMPSIZE = 0x%x\n", header->cbSize)); DEBUG(2, ("RAWSIZE = 0x%x\n", header->cbRawSize)); DEBUG(2, ("COMPTYPE = 0x%08x\n", header->dwMagic)); // TODO: make this look like MS-OXRTFCP examples DEBUG(2, ("CRC = 0x%08x\n", header->dwCRC)); */ } static enum MAPISTATUS verify_header(uint8_t *header_data, uint32_t in_size, lzfuheader *header) { parse_header(header_data, header); if (header->cbSize != in_size - 4) { DEBUG(0, ("in_size mismatch:%u\n", in_size)); OPENCHANGE_RETVAL_ERR(MAPI_E_CORRUPT_DATA, NULL); } if ((header->dwMagic != LZFU_COMPRESSED) && (header->dwMagic != LZFU_UNCOMPRESSED)) { DEBUG(0, ("bad magic: 0x%x\n", header->dwMagic)); OPENCHANGE_RETVAL_ERR(MAPI_E_CORRUPT_DATA, NULL); } return MAPI_E_SUCCESS; } static uint8_t get_next_byte(decompression_state *state) { if (state->in_pos > state->in_size) { return 0; } uint8_t next_byte = state->compressed_data[state->in_pos]; state->in_pos += 1; return next_byte; } static uint8_t get_next_control(decompression_state *state) { uint8_t c = get_next_byte(state); /* DEBUG(3, ("control: 0x%02x\n", c)); */ return c; } static uint8_t get_next_literal(decompression_state *state) { uint8_t c = get_next_byte(state); /* if (isprint(c)) { DEBUG(3, ("literal %c\n", c)); } else { DEBUG(3, ("literal 0x%02x\n", c)); } */ return c; } typedef struct _dictionaryref { uint8_t length; uint16_t offset; } dictionaryref; static dictionaryref get_next_dictionary_reference(decompression_state *state) { dictionaryref reference; uint8_t highbyte = get_next_byte(state); uint8_t lowbyte = get_next_byte(state); reference.length = lowbyte & 0x0F; /* low 4 bits are length */ reference.length += 2; /* stored as two less than actual length */ reference.offset = ((highbyte << 8) + lowbyte); reference.offset &= 0xFFF0; /* high 12 bits are offset */ reference.offset >>= 4; /* shift the offset down */ return reference; } static void append_to_dictionary(decompression_state *state, char c) { state->dict[state->dict_writeoffset] = c; state->dict_writeoffset = (state->dict_writeoffset + 1) % LZFU_DICTLENGTH; } static void append_to_output(output_state *output, char c) { output->output_blob->data[output->out_pos] = c; output->out_pos += 1; output->output_blob->length += 1; } static char get_dictionary_entry(decompression_state *state, uint32_t index) { char c = state->dict[index % LZFU_DICTLENGTH]; /* if (isprint(c)) { DEBUG(3, ("dict entry %i: %c\n", index, c)); } else { DEBUG(3, ("dict entry 0x%04x: 0x%02x\n", index, c)); } */ return c; } static bool output_would_overflow(output_state *output) { bool would_overflow = (output->out_pos > output->out_size); if (would_overflow) { DEBUG(0, (" overrun on out_pos: %u > %u\n", output->out_pos, output->out_size)); DEBUG(0, (" overrun data: %s\n", output->output_blob->data)); } return would_overflow; } static bool input_would_overflow(decompression_state *state) { bool would_overflow = (state->in_pos > state->in_size); if (would_overflow) { DEBUG(0, ("input overrun at in_pos: %i (of %i)\n", state->in_pos, state->in_size)); } return would_overflow; } _PUBLIC_ enum MAPISTATUS uncompress_rtf(TALLOC_CTX *mem_ctx, uint8_t *rtfcomp, uint32_t in_size, DATA_BLOB *rtf) { lzfuheader lzfuhdr; decompression_state state; uint8_t bitmask_pos; output_state output; enum MAPISTATUS retval; if (in_size < sizeof(lzfuhdr)+1) { OPENCHANGE_RETVAL_ERR(MAPI_E_CORRUPT_DATA, NULL); } initialise_decompression_state(mem_ctx, rtfcomp, in_size, &state); retval = verify_header(rtfcomp, state.in_size, &lzfuhdr); if (retval != MAPI_E_SUCCESS) { cleanup_decompression_state(&state); return retval; } if (lzfuhdr.dwMagic == LZFU_UNCOMPRESSED) { // TODO: handle uncompressed case } initialise_output_state(mem_ctx, &output, lzfuhdr.cbRawSize, rtf); while ((state.in_pos + 1) < state.in_size) { uint8_t control = get_next_control(&state); for(bitmask_pos = 0; bitmask_pos < 8; ++bitmask_pos) { if (control & ( 1 << bitmask_pos)) { /* its a dictionary reference */ dictionaryref dictref; int i; dictref = get_next_dictionary_reference(&state); if (dictref.offset == state.dict_writeoffset) { DEBUG(4, ("matching offset - done\n")); append_to_output(&output, '\0'); cleanup_decompression_state(&state); return MAPI_E_SUCCESS; } for (i = 0; i < dictref.length; ++i) { if (output_would_overflow(&output)) { cleanup_decompression_state(&state); return MAPI_E_CORRUPT_DATA; } char c = get_dictionary_entry(&state, (dictref.offset + i)); append_to_output(&output, c); append_to_dictionary(&state, c); } } else { /* its a literal */ if ( output_would_overflow(&output) || input_would_overflow(&state) ) { cleanup_decompression_state(&state); talloc_free(rtf->data); return MAPI_E_CORRUPT_DATA; } char c = get_next_literal(&state); append_to_output(&output, c); append_to_dictionary(&state, c); } } } cleanup_decompression_state(&state); OPENCHANGE_RETVAL_ERR(MAPI_E_SUCCESS, NULL); } static uint32_t CRCTable[] = { 0x00000000, 0x77073096, 0xee0e612c, 0x990951ba, 0x076dc419, 0x706af48f, 0xe963a535, 0x9e6495a3, 0x0edb8832, 0x79dcb8a4, 0xe0d5e91e, 0x97d2d988, 0x09b64c2b, 0x7eb17cbd, 0xe7b82d07, 0x90bf1d91, 0x1db71064, 0x6ab020f2, 0xf3b97148, 0x84be41de, 0x1adad47d, 0x6ddde4eb, 0xf4d4b551, 0x83d385c7, 0x136c9856, 0x646ba8c0, 0xfd62f97a, 0x8a65c9ec, 0x14015c4f, 0x63066cd9, 0xfa0f3d63, 0x8d080df5, 0x3b6e20c8, 0x4c69105e, 0xd56041e4, 0xa2677172, 0x3c03e4d1, 0x4b04d447, 0xd20d85fd, 0xa50ab56b, 0x35b5a8fa, 0x42b2986c, 0xdbbbc9d6, 0xacbcf940, 0x32d86ce3, 0x45df5c75, 0xdcd60dcf, 0xabd13d59, 0x26d930ac, 0x51de003a, 0xc8d75180, 0xbfd06116, 0x21b4f4b5, 0x56b3c423, 0xcfba9599, 0xb8bda50f, 0x2802b89e, 0x5f058808, 0xc60cd9b2, 0xb10be924, 0x2f6f7c87, 0x58684c11, 0xc1611dab, 0xb6662d3d, 0x76dc4190, 0x01db7106, 0x98d220bc, 0xefd5102a, 0x71b18589, 0x06b6b51f, 0x9fbfe4a5, 0xe8b8d433, 0x7807c9a2, 0x0f00f934, 0x9609a88e, 0xe10e9818, 0x7f6a0dbb, 0x086d3d2d, 0x91646c97, 0xe6635c01, 0x6b6b51f4, 0x1c6c6162, 0x856530d8, 0xf262004e, 0x6c0695ed, 0x1b01a57b, 0x8208f4c1, 0xf50fc457, 0x65b0d9c6, 0x12b7e950, 0x8bbeb8ea, 0xfcb9887c, 0x62dd1ddf, 0x15da2d49, 0x8cd37cf3, 0xfbd44c65, 0x4db26158, 0x3ab551ce, 0xa3bc0074, 0xd4bb30e2, 0x4adfa541, 0x3dd895d7, 0xa4d1c46d, 0xd3d6f4fb, 0x4369e96a, 0x346ed9fc, 0xad678846, 0xda60b8d0, 0x44042d73, 0x33031de5, 0xaa0a4c5f, 0xdd0d7cc9, 0x5005713c, 0x270241aa, 0xbe0b1010, 0xc90c2086, 0x5768b525, 0x206f85b3, 0xb966d409, 0xce61e49f, 0x5edef90e, 0x29d9c998, 0xb0d09822, 0xc7d7a8b4, 0x59b33d17, 0x2eb40d81, 0xb7bd5c3b, 0xc0ba6cad, 0xedb88320, 0x9abfb3b6, 0x03b6e20c, 0x74b1d29a, 0xead54739, 0x9dd277af, 0x04db2615, 0x73dc1683, 0xe3630b12, 0x94643b84, 0x0d6d6a3e, 0x7a6a5aa8, 0xe40ecf0b, 0x9309ff9d, 0x0a00ae27, 0x7d079eb1, 0xf00f9344, 0x8708a3d2, 0x1e01f268, 0x6906c2fe, 0xf762575d, 0x806567cb, 0x196c3671, 0x6e6b06e7, 0xfed41b76, 0x89d32be0, 0x10da7a5a, 0x67dd4acc, 0xf9b9df6f, 0x8ebeeff9, 0x17b7be43, 0x60b08ed5, 0xd6d6a3e8, 0xa1d1937e, 0x38d8c2c4, 0x4fdff252, 0xd1bb67f1, 0xa6bc5767, 0x3fb506dd, 0x48b2364b, 0xd80d2bda, 0xaf0a1b4c, 0x36034af6, 0x41047a60, 0xdf60efc3, 0xa867df55, 0x316e8eef, 0x4669be79, 0xcb61b38c, 0xbc66831a, 0x256fd2a0, 0x5268e236, 0xcc0c7795, 0xbb0b4703, 0x220216b9, 0x5505262f, 0xc5ba3bbe, 0xb2bd0b28, 0x2bb45a92, 0x5cb36a04, 0xc2d7ffa7, 0xb5d0cf31, 0x2cd99e8b, 0x5bdeae1d, 0x9b64c2b0, 0xec63f226, 0x756aa39c, 0x026d930a, 0x9c0906a9, 0xeb0e363f, 0x72076785, 0x05005713, 0x95bf4a82, 0xe2b87a14, 0x7bb12bae, 0x0cb61b38, 0x92d28e9b, 0xe5d5be0d, 0x7cdcefb7, 0x0bdbdf21, 0x86d3d2d4, 0xf1d4e242, 0x68ddb3f8, 0x1fda836e, 0x81be16cd, 0xf6b9265b, 0x6fb077e1, 0x18b74777, 0x88085ae6, 0xff0f6a70, 0x66063bca, 0x11010b5c, 0x8f659eff, 0xf862ae69, 0x616bffd3, 0x166ccf45, 0xa00ae278, 0xd70dd2ee, 0x4e048354, 0x3903b3c2, 0xa7672661, 0xd06016f7, 0x4969474d, 0x3e6e77db, 0xaed16a4a, 0xd9d65adc, 0x40df0b66, 0x37d83bf0, 0xa9bcae53, 0xdebb9ec5, 0x47b2cf7f, 0x30b5ffe9, 0xbdbdf21c, 0xcabac28a, 0x53b39330, 0x24b4a3a6, 0xbad03605, 0xcdd70693, 0x54de5729, 0x23d967bf, 0xb3667a2e, 0xc4614ab8, 0x5d681b02, 0x2a6f2b94, 0xb40bbe37, 0xc30c8ea1, 0x5a05df1b, 0x2d02ef8d }; uint32_t calculateCRC(uint8_t *input, uint32_t offset, uint32_t length) { uint32_t crc = 0; uint32_t i; for (i = offset; i < offset+length; ++i) { DEBUG(5, ("input at %i: 0x%02x\n", i, input[i])); uint8_t table_position = (crc ^ input[i]) & 0xFF; DEBUG(5, ("table_position: 0x%02x\n", table_position)); uint32_t intermediateValue = crc >> 8; DEBUG(5, ("intermediateValue: 0x%08x\n", intermediateValue)); crc = CRCTable[table_position] ^ intermediateValue; DEBUG(5, ("tableValue: 0x%08x\n", CRCTable[table_position])); DEBUG(5, ("crc: 0x%08x\n", crc)); } return crc; } #define MIN(a,b) ((a) < (b) ? (a) : (b)) static size_t longest_match(const char *rtf, const size_t rtf_size, size_t input_idx, uint8_t *dict, size_t *dict_write_idx, size_t *dict_match_offset, size_t *dict_match_length) { size_t best_match_length = 0; size_t dict_iterator; for (dict_iterator = 0; dict_iterator < MIN(*dict_write_idx, LZFU_DICTLENGTH); ++dict_iterator) { size_t match_length_from_this_pos = 0; while ((rtf[input_idx + match_length_from_this_pos] == dict[dict_iterator + match_length_from_this_pos]) && ((dict_iterator + match_length_from_this_pos) < ((*dict_write_idx) % LZFU_DICTLENGTH)) && /* does this line need to have % LZFU_DICTLENGTH? */ ((input_idx + match_length_from_this_pos) < rtf_size) && (match_length_from_this_pos < 17)) { match_length_from_this_pos += 1; if (match_length_from_this_pos > best_match_length) { best_match_length = match_length_from_this_pos; dict[(*dict_write_idx) % LZFU_DICTLENGTH] = rtf[input_idx + match_length_from_this_pos - 1]; *dict_write_idx += 1; *dict_match_offset = dict_iterator; } } } *dict_match_length = best_match_length; return best_match_length; } _PUBLIC_ enum MAPISTATUS compress_rtf(TALLOC_CTX *mem_ctx, const char *rtf, const size_t rtf_size, uint8_t **rtfcomp, size_t *rtfcomp_size) { size_t input_idx = 0; lzfuheader header; uint8_t *dict; size_t output_idx = 0; size_t control_byte_idx = 0; uint8_t control_bit = 0x01; size_t dict_write_idx = 0; /* as an upper bound, assume that the output is no larger than 9/8 of the input size, plus the header size */ *rtfcomp = (uint8_t *) talloc_size(mem_ctx, 9 * rtf_size / 8 + sizeof(lzfuheader)); control_byte_idx = sizeof(lzfuheader); (*rtfcomp)[control_byte_idx] = 0x00; output_idx = control_byte_idx + 1; /* allocate and initialise the dictionary */ dict = talloc_zero_array(mem_ctx, uint8_t, LZFU_DICTLENGTH); memcpy(dict, LZFU_INITDICT, LZFU_INITLENGTH); dict_write_idx = LZFU_INITLENGTH; while (input_idx < rtf_size) { size_t dict_match_length = 0; size_t dict_match_offset = 0; DEBUG(4, ("compressing byte %zi of %zi\n", input_idx, rtf_size)); if (longest_match(rtf, rtf_size, input_idx, dict, &dict_write_idx, &dict_match_offset, &dict_match_length) > 1) { uint16_t dict_ref = dict_match_offset << 4; dict_ref += (dict_match_length - 2); input_idx += dict_match_length; (*rtfcomp)[control_byte_idx] |= control_bit; /* append dictionary reference to output */ (*rtfcomp)[output_idx] = (dict_ref & 0xFF00) >> 8; output_idx += 1; (*rtfcomp)[output_idx] = (dict_ref & 0xFF); output_idx += 1; } else { if (dict_match_length == 0) { /* we haven't written a literal to the dict yet */ dict[dict_write_idx % LZFU_DICTLENGTH] = rtf[input_idx]; dict_write_idx += 1; } /* append to output, and increment the output position */ (*rtfcomp)[output_idx] = rtf[input_idx]; output_idx += 1; DEBUG(5, ("new output_idx = 0x%08zx (for char value 0x%02x)\n", output_idx, rtf[input_idx])); /* increment the input position */ input_idx += 1; } if (control_bit == 0x80) { control_bit = 0x01; control_byte_idx = output_idx; (*rtfcomp)[control_byte_idx] = 0x00; output_idx = control_byte_idx + 1; DEBUG(5, ("new output_idx cb = 0x%08zx\n", output_idx)); } else { control_bit = control_bit << 1; } } { /* append final marker dictionary reference to output */ uint16_t dict_ref = (dict_write_idx % LZFU_DICTLENGTH) << 4; // printf("dict ref: 0x%04x at 0x%08zx\n", dict_ref, output_idx); (*rtfcomp)[control_byte_idx] |= control_bit; // printf("dict ref hi: 0x%02x\n", (dict_ref & 0xFF00) >> 8); (*rtfcomp)[output_idx] = (dict_ref & 0xFF00) >> 8; output_idx += 1; // printf("dict ref lo: 0x%02x\n", dict_ref & 0xFF); (*rtfcomp)[output_idx] = (dict_ref & 0xFF); output_idx += 1; } header.cbSize = output_idx - sizeof(lzfuheader) + 12; header.cbRawSize = rtf_size; header.dwMagic = LZFU_COMPRESSED; header.dwCRC = calculateCRC(*rtfcomp, sizeof(lzfuheader), output_idx - sizeof(lzfuheader)); memcpy(*rtfcomp, &header, sizeof(lzfuheader)); *rtfcomp_size = output_idx; *rtfcomp = (uint8_t *) talloc_realloc_size(mem_ctx, *rtfcomp, *rtfcomp_size); return MAPI_E_SUCCESS; } openchange-2.0/libmapi/mapi_context.h000066400000000000000000000021211223057412600177400ustar00rootroot00000000000000/* OpenChange MAPI implementation. MAPI Context. Copyright (C) Julien Kerihuel 2007-2010. Copyright (C) Fabien Le Mentec 2007. This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see . */ #ifndef _MAPI_CONTEXT_H #define _MAPI_CONTEXT_H #include struct ldb_context; struct mapi_session; struct mapi_context { TALLOC_CTX *mem_ctx; struct ldb_context *ldb_ctx; struct mapi_session *session; bool dumpdata; struct loadparm_context *lp_ctx; }; #endif /* ! _MAPI_CONTEXT_H */ openchange-2.0/libmapi/mapi_id_array.c000066400000000000000000000212221223057412600200440ustar00rootroot00000000000000/* OpenChange MAPI implementation. Copyright (C) Julien Kerihuel 2008-2010. This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see . */ #include "libmapi/libmapi.h" #include "libmapi/libmapi_private.h" /** \file mapi_id_array.c \brief mapi_id_array support functions */ /** \details Initialize a mapi_id_array structure \param mem_ctx pointer to the talloc context \param id pointer to a mapi_id_array structure \return MAPI_E_SUCCESS on success, otherwise MAPI error. \note Developers may also call GetLastError() to retrieve the last MAPI error code. Possible MAPI error codes are: - MAPI_E_NOT_INITIALIZED: MAPI subsystem has not been initialized - MAPI_E_INVALID_PARAMETER: The mapi_id_array_t is uninitialized - MAPI_E_CALL_FAILED: A network problem was encountered during the transaction \sa mapi_id_array_release */ _PUBLIC_ enum MAPISTATUS mapi_id_array_init(TALLOC_CTX *mem_ctx, mapi_id_array_t *id) { /* Sanity checks */ OPENCHANGE_RETVAL_IF(!mem_ctx, MAPI_E_NOT_INITIALIZED, NULL); OPENCHANGE_RETVAL_IF(!id, MAPI_E_INVALID_PARAMETER, NULL); id->count = 0; id->lpContainerList = talloc_zero(mem_ctx, mapi_container_list_t); return MAPI_E_SUCCESS; } /** \details Uninitialize a mapi_id_array structure \param id pointer to a mapi_id_array structure \return MAPI_E_SUCCESS on success, otherwise MAPI error. \note Developers may also call GetLastError() to retrieve the last MAPI error code. Possible MAPI error codes are: - MAPI_E_NOT_INITIALIZED: MAPI subsystem has not been initialized - MAPI_E_INVALID_PARAMETER: The mapi_id_array_t is uninitialized - MAPI_E_CALL_FAILED: A network problem was encountered during the transaction \sa mapi_id_array_init */ _PUBLIC_ enum MAPISTATUS mapi_id_array_release(mapi_id_array_t *id) { /* Sanity checks */ OPENCHANGE_RETVAL_IF(!id, MAPI_E_INVALID_PARAMETER, NULL); OPENCHANGE_RETVAL_IF(!id->lpContainerList, MAPI_E_INVALID_PARAMETER, NULL); id->count = 0; talloc_free(id->lpContainerList); return MAPI_E_SUCCESS; } /** \details Retrieve the ContainerList and store it within a uint64_t array. \param mem_ctx allocated talloc pointer \param id pointer to a mapi_id_array structure \param ContainerList pointer on a pointer of uint64_t values \return MAPI_E_SUCCESS on success, otherwise MAPI error. \note Developers may also call GetLastError() to retrieve the last MAPI error code. Possible MAPI error codes are: - MAPI_E_NOT_INITIALIZED: MAPI subsystem has not been initialized - MAPI_E_INVALID_PARAMETER: The mapi_id_array_t is uninitialized - MAPI_E_CALL_FAILED: A network problem was encountered during the transaction \sa GetSearchCriteria */ _PUBLIC_ enum MAPISTATUS mapi_id_array_get(TALLOC_CTX *mem_ctx, mapi_id_array_t *id, mapi_id_t **ContainerList) { mapi_container_list_t *element; uint32_t i = 0; /* Sanity checks */ OPENCHANGE_RETVAL_IF(!id, MAPI_E_INVALID_PARAMETER, NULL); OPENCHANGE_RETVAL_IF(!id->lpContainerList, MAPI_E_INVALID_PARAMETER, NULL); OPENCHANGE_RETVAL_IF(!ContainerList, MAPI_E_INVALID_PARAMETER, NULL); *ContainerList = talloc_array(mem_ctx, uint64_t, id->count + 1); element = id->lpContainerList; while (element) { ContainerList[0][i] = element->id; i++; element = element->next; } return MAPI_E_SUCCESS; } /** \details Add a container ID to the list given its mapi_object_t \param id pointer to a mapi_id_array structure \param obj pointer on the mapi object we retrieve the container ID from \return MAPI_E_SUCCESS on success, otherwise MAPI error. \note Developers may also call GetLastError() to retrieve the last MAPI error code. Possible MAPI error codes are: - MAPI_E_NOT_INITIALIZED: MAPI subsystem has not been initialized - MAPI_E_INVALID_PARAMETER: The mapi_id_array_t is uninitialized - MAPI_E_CALL_FAILED: A network problem was encountered during the transaction \sa mapi_id_array_add_id */ _PUBLIC_ enum MAPISTATUS mapi_id_array_add_obj(mapi_id_array_t *id, mapi_object_t *obj) { mapi_container_list_t *element; /* Sanity checks */ OPENCHANGE_RETVAL_IF(!id, MAPI_E_INVALID_PARAMETER, NULL); OPENCHANGE_RETVAL_IF(!id->lpContainerList, MAPI_E_INVALID_PARAMETER, NULL); OPENCHANGE_RETVAL_IF(!obj, MAPI_E_INVALID_PARAMETER, NULL); element = talloc_zero((TALLOC_CTX *)id->lpContainerList, mapi_container_list_t); element->id = mapi_object_get_id(obj); DLIST_ADD(id->lpContainerList, element); id->count++; return MAPI_E_SUCCESS; } /** \details Add a container ID to the list given its container ID \param id pointer to a mapi_id_array structure \param fid the container ID \return MAPI_E_SUCCESS on success, otherwise MAPI error. \note Developers may also call GetLastError() to retrieve the last MAPI error code. Possible MAPI error codes are: - MAPI_E_NOT_INITIALIZED: MAPI subsystem has not been initialized - MAPI_E_INVALID_PARAMETER: The mapi_id_array_t is uninitialized - MAPI_E_CALL_FAILED: A network problem was encountered during the transaction \sa mapi_id_array_add_obj */ _PUBLIC_ enum MAPISTATUS mapi_id_array_add_id(mapi_id_array_t *id, mapi_id_t fid) { mapi_container_list_t *element; /* Sanity checks */ OPENCHANGE_RETVAL_IF(!id, MAPI_E_INVALID_PARAMETER, NULL); OPENCHANGE_RETVAL_IF(!id->lpContainerList, MAPI_E_NOT_INITIALIZED, NULL); OPENCHANGE_RETVAL_IF(!fid, MAPI_E_INVALID_PARAMETER, NULL); element = talloc_zero((TALLOC_CTX *)id->lpContainerList, mapi_container_list_t); element->id = fid; DLIST_ADD(id->lpContainerList, element); id->count++; return MAPI_E_SUCCESS; } /** \details Delete a container ID from the list given its container ID \param id pointer to a mapi_id_array structure \param fid the container ID \return MAPI_E_SUCCESS on success, otherwise MAPI error. \note Developers may also call GetLastError() to retrieve the last MAPI error code. Possible MAPI error codes are: - MAPI_E_NOT_INITIALIZED: MAPI subsystem has not been initialized - MAPI_E_INVALID_PARAMETER: The mapi_id_array_t is uninitialized - MAPI_E_CALL_FAILED: A network problem was encountered during the transaction \sa mapi_id_array_add_id */ _PUBLIC_ enum MAPISTATUS mapi_id_array_del_id(mapi_id_array_t *id, mapi_id_t fid) { mapi_container_list_t *element; /* Sanity checks */ OPENCHANGE_RETVAL_IF(!id, MAPI_E_INVALID_PARAMETER, NULL); OPENCHANGE_RETVAL_IF(!id->count, MAPI_E_NOT_INITIALIZED, NULL); OPENCHANGE_RETVAL_IF(!id->lpContainerList, MAPI_E_NOT_INITIALIZED, NULL); element = id->lpContainerList; while (element) { if (element->id == fid) { DLIST_REMOVE(id->lpContainerList, element); return MAPI_E_SUCCESS; } element = element->next; } return MAPI_E_NOT_FOUND; } /** \details Delete a container ID from the list given its mapi_object_t \param id pointer to a mapi_id_array structure \param obj pointer on the mapi object we retrieve the container ID from \return MAPI_E_SUCCESS on success, otherwise MAPI error. \note Developers may also call GetLastError() to retrieve the last MAPI error code. Possible MAPI error codes are: - MAPI_E_NOT_INITIALIZED: MAPI subsystem has not been initialized - MAPI_E_INVALID_PARAMETER: The mapi_id_array_t is uninitialized - MAPI_E_CALL_FAILED: A network problem was encountered during the transaction \sa mapi_id_array_add_id */ _PUBLIC_ enum MAPISTATUS mapi_id_array_del_obj(mapi_id_array_t *id, mapi_object_t *obj) { mapi_container_list_t *element; mapi_id_t fid; /* Sanity checks */ OPENCHANGE_RETVAL_IF(!id, MAPI_E_INVALID_PARAMETER, NULL); OPENCHANGE_RETVAL_IF(!obj, MAPI_E_INVALID_PARAMETER, NULL); OPENCHANGE_RETVAL_IF(!id->count, MAPI_E_NOT_INITIALIZED, NULL); OPENCHANGE_RETVAL_IF(!id->lpContainerList, MAPI_E_NOT_INITIALIZED, NULL); fid = mapi_object_get_id(obj); OPENCHANGE_RETVAL_IF(!fid, MAPI_E_NOT_INITIALIZED, NULL); element = id->lpContainerList; while (element) { if (element->id == fid) { DLIST_REMOVE(id->lpContainerList, element); return MAPI_E_SUCCESS; } element = element->next; } return MAPI_E_NOT_FOUND; } openchange-2.0/libmapi/mapi_id_array.h000066400000000000000000000020731223057412600200540ustar00rootroot00000000000000/* OpenChange MAPI implementation. Copyright (C) Julien Kerihuel 2008. This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see . */ #ifndef __MAPI_ID_ARRAY_H #define __MAPI_ID_ARRAY_H typedef struct mapi_container_list { struct mapi_container_list *prev; struct mapi_container_list *next; mapi_id_t id; } mapi_container_list_t; typedef struct mapi_id_array { uint16_t count; mapi_container_list_t *lpContainerList; } mapi_id_array_t; #endif /* __MAPI_ID_ARRAY_H */ openchange-2.0/libmapi/mapi_nameid.c000066400000000000000000000775711223057412600175310ustar00rootroot00000000000000/* OpenChange MAPI implementation. Copyright (C) Julien Kerihuel 2007-2011. This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see . */ #include "libmapi/libmapi.h" #include "libmapi/mapi_nameid.h" #include "libmapi/mapi_nameid_private.h" #include "libmapi/libmapi_private.h" /** \file mapi_nameid.c \brief mapi_nameid convenience API */ /** \details Create a new mapi_nameid structure \param mem_ctx memory context to use for allocation \returns a pointer to an allocated mapi_nameid structure on success, otherwise NULL \sa GetIDsFromNames */ _PUBLIC_ struct mapi_nameid *mapi_nameid_new(TALLOC_CTX *mem_ctx) { struct mapi_nameid *mapi_nameid = NULL; /* Sanity check */ if (!mem_ctx) return NULL; mapi_nameid = talloc_zero(mem_ctx, struct mapi_nameid); if (!mapi_nameid) return NULL; mapi_nameid->nameid = NULL; mapi_nameid->entries = NULL; mapi_nameid->count = 0; return mapi_nameid; } /** \details Add a mapi_nameid entry given its OOM and OLEGUID (MNID_ID|MNID_STRING) \param mapi_nameid the structure where results are stored \param OOM the Outlook Object Model matching string \param OLEGUID the property set this entry belongs to \return MAPI_E_SUCCESS on success, otherwise MAPI error. \note Developers may also call GetLastError() to retrieve the last MAPI error code. Possible MAPI error codes are: - MAPI_E_NOT_INITIALIZED: MAPI subsystem has not been initialized - MAPI_E_INVALID_PARAMETER: one of the parameters was not set properly - MAPI_E_NOT_FOUND: the entry intended to be added was not found \sa mapi_nameid_new */ _PUBLIC_ enum MAPISTATUS mapi_nameid_OOM_add(struct mapi_nameid *mapi_nameid, const char *OOM, const char *OLEGUID) { uint32_t i; uint16_t count; /* Sanity check */ OPENCHANGE_RETVAL_IF(!mapi_nameid, MAPI_E_NOT_INITIALIZED, NULL); OPENCHANGE_RETVAL_IF(!OOM, MAPI_E_INVALID_PARAMETER, NULL); OPENCHANGE_RETVAL_IF(!OLEGUID, MAPI_E_INVALID_PARAMETER, NULL); for (i = 0; mapi_nameid_tags[i].OLEGUID; i++) { if (mapi_nameid_tags[i].OOM && !strcmp(OOM, mapi_nameid_tags[i].OOM) && !strcmp(OLEGUID, mapi_nameid_tags[i].OLEGUID)) { mapi_nameid->nameid = talloc_realloc(mapi_nameid, mapi_nameid->nameid, struct MAPINAMEID, mapi_nameid->count + 1); mapi_nameid->entries = talloc_realloc(mapi_nameid, mapi_nameid->entries, struct mapi_nameid_tags, mapi_nameid->count + 1); count = mapi_nameid->count; mapi_nameid->entries[count] = mapi_nameid_tags[i]; mapi_nameid->nameid[count].ulKind = (enum ulKind)mapi_nameid_tags[i].ulKind; GUID_from_string(mapi_nameid_tags[i].OLEGUID, &(mapi_nameid->nameid[count].lpguid)); switch (mapi_nameid_tags[i].ulKind) { case MNID_ID: mapi_nameid->nameid[count].kind.lid = mapi_nameid_tags[i].lid; break; case MNID_STRING: mapi_nameid->nameid[count].kind.lpwstr.Name = mapi_nameid_tags[i].Name; mapi_nameid->nameid[count].kind.lpwstr.NameSize = get_utf8_utf16_conv_length(mapi_nameid_tags[i].Name); break; } mapi_nameid->count++; return MAPI_E_SUCCESS; } } return MAPI_E_NOT_FOUND; } /** \details Add a mapi_nameid entry given its lid and OLEGUID (MNID_ID) \param mapi_nameid the structure where results are stored \param lid the light ID of the name property (used by MNID_ID named props only) \param OLEGUID the property set this entry belongs to \return MAPI_E_SUCCESS on success, otherwise MAPI error. \note Developers may also call GetLastError() to retrieve the last MAPI error code. Possible MAPI error codes are: - MAPI_E_NOT_INITIALIZED: MAPI subsystem has not been initialized - MAPI_E_INVALID_PARAMETER: one of the parameters was not set properly - MAPI_E_NOT_FOUND: the entry intended to be added was not found \sa mapi_nameid_new */ _PUBLIC_ enum MAPISTATUS mapi_nameid_lid_add(struct mapi_nameid *mapi_nameid, uint16_t lid, const char *OLEGUID) { uint32_t i; uint16_t count; /* Sanity check */ OPENCHANGE_RETVAL_IF(!mapi_nameid, MAPI_E_NOT_INITIALIZED, NULL); OPENCHANGE_RETVAL_IF(!lid, MAPI_E_INVALID_PARAMETER, NULL); OPENCHANGE_RETVAL_IF(!OLEGUID, MAPI_E_INVALID_PARAMETER, NULL); for (i = 0; mapi_nameid_tags[i].OLEGUID; i++) { if ((lid == mapi_nameid_tags[i].lid) && !strcmp(OLEGUID, mapi_nameid_tags[i].OLEGUID)) { mapi_nameid->nameid = talloc_realloc(mapi_nameid, mapi_nameid->nameid, struct MAPINAMEID, mapi_nameid->count + 1); mapi_nameid->entries = talloc_realloc(mapi_nameid, mapi_nameid->entries, struct mapi_nameid_tags, mapi_nameid->count + 1); count = mapi_nameid->count; mapi_nameid->entries[count] = mapi_nameid_tags[i]; mapi_nameid->nameid[count].ulKind = (enum ulKind) mapi_nameid_tags[i].ulKind; GUID_from_string(mapi_nameid_tags[i].OLEGUID, &(mapi_nameid->nameid[count].lpguid)); switch (mapi_nameid_tags[i].ulKind) { case MNID_ID: mapi_nameid->nameid[count].kind.lid = mapi_nameid_tags[i].lid; break; case MNID_STRING: mapi_nameid->nameid[count].kind.lpwstr.Name = mapi_nameid_tags[i].Name; mapi_nameid->nameid[count].kind.lpwstr.NameSize = get_utf8_utf16_conv_length(mapi_nameid_tags[i].Name); break; } mapi_nameid->count++; return MAPI_E_SUCCESS; } } return MAPI_E_NOT_FOUND; } /** \details Add a mapi_nameid entry given its Name and OLEGUID (MNID_STRING) \param mapi_nameid the structure where results are stored \param Name the property name (used by MNID_STRING named props only) \param OLEGUID the property set this entry belongs to \return MAPI_E_SUCCESS on success, otherwise MAPI error. \note Developers may also call GetLastError() to retrieve the last MAPI error code. Possible MAPI error codes are: - MAPI_E_NOT_INITIALIZED: MAPI subsystem has not been initialized - MAPI_E_INVALID_PARAMETER: one of the parameters was not set properly - MAPI_E_NOT_FOUND: the entry intended to be added was not found \sa mapi_nameid_new */ _PUBLIC_ enum MAPISTATUS mapi_nameid_string_add(struct mapi_nameid *mapi_nameid, const char *Name, const char *OLEGUID) { uint32_t i; uint16_t count; /* Sanity check */ OPENCHANGE_RETVAL_IF(!mapi_nameid, MAPI_E_NOT_INITIALIZED, NULL); OPENCHANGE_RETVAL_IF(!Name, MAPI_E_INVALID_PARAMETER, NULL); OPENCHANGE_RETVAL_IF(!OLEGUID, MAPI_E_INVALID_PARAMETER, NULL); for (i = 0; mapi_nameid_tags[i].OLEGUID; i++) { if (mapi_nameid_tags[i].Name && !strcmp(Name, mapi_nameid_tags[i].Name) && !strcmp(OLEGUID, mapi_nameid_tags[i].OLEGUID)) { mapi_nameid->nameid = talloc_realloc(mapi_nameid, mapi_nameid->nameid, struct MAPINAMEID, mapi_nameid->count + 1); mapi_nameid->entries = talloc_realloc(mapi_nameid, mapi_nameid->entries, struct mapi_nameid_tags, mapi_nameid->count + 1); count = mapi_nameid->count; mapi_nameid->entries[count] = mapi_nameid_tags[i]; mapi_nameid->nameid[count].ulKind = (enum ulKind) mapi_nameid_tags[i].ulKind; GUID_from_string(mapi_nameid_tags[i].OLEGUID, &(mapi_nameid->nameid[count].lpguid)); switch (mapi_nameid_tags[i].ulKind) { case MNID_ID: mapi_nameid->nameid[count].kind.lid = mapi_nameid_tags[i].lid; break; case MNID_STRING: mapi_nameid->nameid[count].kind.lpwstr.Name = mapi_nameid_tags[i].Name; mapi_nameid->nameid[count].kind.lpwstr.NameSize = get_utf8_utf16_conv_length(mapi_nameid_tags[i].Name); break; } mapi_nameid->count++; return MAPI_E_SUCCESS; } } return MAPI_E_NOT_FOUND; } /** \details Register and add a custom MNID_ID named property given its lid, proptype and OLEGUID. \param mapi_nameid the structure where results are stored \param lid the light ID of the name property (used by MNID_ID named props only) \param propType the named property type \param OLEGUID the property set this entry belongs to \return MAPI_E_SUCCESS on success, otherwise MAPI error. \note Developers may also call GetLastError() to retrieve the last MAPI error code. Possible MAPI error codes are: - MAPI_E_NOT_INITIALIZED: MAPI subsystem has not been initialized - MAPI_E_INVALID_PARAMETER: one of the parameter was no set properly \sa mapi_nameid_new, mapi_nameid_lid_add */ _PUBLIC_ enum MAPISTATUS mapi_nameid_custom_lid_add(struct mapi_nameid *mapi_nameid, uint16_t lid, uint16_t propType, const char *OLEGUID) { uint16_t count; /* Sanity check */ OPENCHANGE_RETVAL_IF(!mapi_nameid, MAPI_E_NOT_INITIALIZED, NULL); OPENCHANGE_RETVAL_IF(!lid, MAPI_E_INVALID_PARAMETER, NULL); OPENCHANGE_RETVAL_IF(!propType, MAPI_E_INVALID_PARAMETER, NULL); OPENCHANGE_RETVAL_IF(!OLEGUID, MAPI_E_INVALID_PARAMETER, NULL); mapi_nameid->nameid = talloc_realloc(mapi_nameid, mapi_nameid->nameid, struct MAPINAMEID, mapi_nameid->count + 1); mapi_nameid->entries = talloc_realloc(mapi_nameid, mapi_nameid->entries, struct mapi_nameid_tags, mapi_nameid->count + 1); count = mapi_nameid->count; mapi_nameid->entries[count].lid = lid; mapi_nameid->entries[count].propType = propType; mapi_nameid->entries[count].ulKind = MNID_ID; mapi_nameid->entries[count].OLEGUID = OLEGUID; mapi_nameid->nameid[count].ulKind = MNID_ID; GUID_from_string(OLEGUID, &(mapi_nameid->nameid[count].lpguid)); mapi_nameid->nameid[count].kind.lid = lid; mapi_nameid->count++; return MAPI_E_SUCCESS; } /** \details Register and add a custom MNID_STRING named property given its string, proptype and OLEGUID. \param mapi_nameid the structure where results are stored \param Name the property name (used by MNID_STRING named props only) \param propType the named property type \param OLEGUID the property set this entry belongs to \return MAPI_E_SUCCESS on success, otherwise MAPI error. \note Developers may also call GetLastError() to retrieve the last MAPI error code. Possible MAPI error codes are: - MAPI_E_NOT_INITIALIZED: MAPI subsystem has not been initialized - MAPI_E_INVALID_PARAMETER: one of the parameter was not set properly. \sa mapi_nameid_new, mapi_nameid_string_add */ _PUBLIC_ enum MAPISTATUS mapi_nameid_custom_string_add(struct mapi_nameid *mapi_nameid, const char *Name, uint16_t propType, const char *OLEGUID) { uint16_t count; /* Sanity check */ OPENCHANGE_RETVAL_IF(!mapi_nameid, MAPI_E_NOT_INITIALIZED, NULL); OPENCHANGE_RETVAL_IF(!Name, MAPI_E_INVALID_PARAMETER, NULL); OPENCHANGE_RETVAL_IF(!propType, MAPI_E_INVALID_PARAMETER, NULL); OPENCHANGE_RETVAL_IF(!OLEGUID, MAPI_E_INVALID_PARAMETER, NULL); mapi_nameid->nameid = talloc_realloc(mapi_nameid, mapi_nameid->nameid, struct MAPINAMEID, mapi_nameid->count + 1); mapi_nameid->entries = talloc_realloc(mapi_nameid, mapi_nameid->entries, struct mapi_nameid_tags, mapi_nameid->count + 1); count = mapi_nameid->count; mapi_nameid->entries[count].Name = Name; mapi_nameid->entries[count].propType = propType; mapi_nameid->entries[count].ulKind = MNID_STRING; mapi_nameid->entries[count].OLEGUID = OLEGUID; mapi_nameid->nameid[count].ulKind = MNID_STRING; GUID_from_string(OLEGUID, &(mapi_nameid->nameid[count].lpguid)); mapi_nameid->nameid[count].kind.lpwstr.Name = Name; mapi_nameid->nameid[count].kind.lpwstr.NameSize = get_utf8_utf16_conv_length(Name); mapi_nameid->count++; return MAPI_E_SUCCESS; } /** \details Add a mapi_nameid entry given its canonical property tag \param mapi_nameid the structure where results are stored \param proptag the canonical property tag we are searching \return MAPI_E_SUCCESS on success, otherwise MAPI error. \note Developers may also call GetLastError() to retrieve the last MAPI error code. Possible MAPI error codes are: - MAPI_E_NOT_INITIALIZE: MAPI subsystem has not been initialized - MAPI_E_INVALID_PARAMETER: one of the parameters was not set properly - MAPI_E_NOT_FOUND: the entry intended to be added was not found \sa mapi_nameid_new */ _PUBLIC_ enum MAPISTATUS mapi_nameid_canonical_add(struct mapi_nameid *mapi_nameid, uint32_t proptag) { uint32_t i; uint16_t count; /* Sanity checks */ OPENCHANGE_RETVAL_IF(!mapi_nameid, MAPI_E_NOT_INITIALIZED, NULL); OPENCHANGE_RETVAL_IF(!proptag, MAPI_E_INVALID_PARAMETER, NULL); for (i = 0; mapi_nameid_tags[i].OLEGUID; i++) { if (mapi_nameid_tags[i].proptag == proptag) { mapi_nameid->nameid = talloc_realloc(mapi_nameid, mapi_nameid->nameid, struct MAPINAMEID, mapi_nameid->count + 1); mapi_nameid->entries = talloc_realloc(mapi_nameid, mapi_nameid->entries, struct mapi_nameid_tags, mapi_nameid->count + 1); count = mapi_nameid->count; mapi_nameid->entries[count] = mapi_nameid_tags[i]; mapi_nameid->nameid[count].ulKind = (enum ulKind) mapi_nameid_tags[i].ulKind; GUID_from_string(mapi_nameid_tags[i].OLEGUID, &(mapi_nameid->nameid[count].lpguid)); switch (mapi_nameid_tags[i].ulKind) { case MNID_ID: mapi_nameid->nameid[count].kind.lid = mapi_nameid_tags[i].lid; break; case MNID_STRING: mapi_nameid->nameid[count].kind.lpwstr.Name = mapi_nameid_tags[i].Name; mapi_nameid->nameid[count].kind.lpwstr.NameSize = get_utf8_utf16_conv_length(mapi_nameid_tags[i].Name); break; } mapi_nameid->count++; return MAPI_E_SUCCESS; } } return MAPI_E_NOT_FOUND; } /** \details Search for a given referenced unmapped named property and return whether it was found or not. \param proptag the unmapped property tag to lookup \return MAPI_E_SUCCESS on success otherwise MAPI_E_NOT_FOUND */ _PUBLIC_ enum MAPISTATUS mapi_nameid_property_lookup(uint32_t proptag) { uint32_t i; for (i = 0; mapi_nameid_tags[i].proptag; i++) { if (mapi_nameid_tags[i].proptag == proptag) { return MAPI_E_SUCCESS; } } return MAPI_E_NOT_FOUND; } /** \details Search for a given OOM,OLEGUID couple and return the associated propType. \param OOM The Outlook Object Model \param OLEGUID the named property GUID for this entry \param propType pointer on returned named property type \return MAPI_E_SUCCESS on success, otherwise MAPI_E_NOT_FOUND. \note Developers may also call GetLastError() to retrieve the last MAPI error code. Possible MAPI error codes are: - MAPI_E_INVALID_PARAMETER: one of the parameter was not set properly. - MAPI_E_NOT_FOUND: no named property found */ _PUBLIC_ enum MAPISTATUS mapi_nameid_OOM_lookup(const char *OOM, const char *OLEGUID, uint16_t *propType) { uint32_t i; /* Sanity checks */ OPENCHANGE_RETVAL_IF(!OOM, MAPI_E_INVALID_PARAMETER, NULL); OPENCHANGE_RETVAL_IF(!OLEGUID, MAPI_E_INVALID_PARAMETER, NULL); for (i = 0; mapi_nameid_tags[i].OLEGUID; i++) { if (mapi_nameid_tags[i].OOM && !strcmp(mapi_nameid_tags[i].OOM, OOM) && !strcmp(mapi_nameid_tags[i].OLEGUID, OLEGUID)) { *propType = mapi_nameid_tags[i].propType; return MAPI_E_SUCCESS; } } OPENCHANGE_RETVAL_ERR(MAPI_E_NOT_FOUND, NULL); } /** \details Search for a given lid,OLEGUID couple and return the associated propType. \param lid the named property light ID \param OLEGUID the named property GUID for this entry \param propType pointer on returned named property type \return MAPI_E_SUCCESS on success, otherwise MAPI_E_NOT_FOUND. \note Developers may also call GetLastError() to retrieve the last MAPI error code. Possible MAPI error codes are: - MAPI_E_INVALID_PARAMETER: one of the parameter was not set properly. - MAPI_E_NOT_FOUND: no named property found */ _PUBLIC_ enum MAPISTATUS mapi_nameid_lid_lookup(uint16_t lid, const char *OLEGUID, uint16_t *propType) { uint32_t i; /* Sanity checks */ OPENCHANGE_RETVAL_IF(!lid, MAPI_E_INVALID_PARAMETER, NULL); OPENCHANGE_RETVAL_IF(!OLEGUID, MAPI_E_INVALID_PARAMETER, NULL); for (i = 0; mapi_nameid_tags[i].OLEGUID; i++) { if (mapi_nameid_tags[i].lid == lid && !strcmp(mapi_nameid_tags[i].OLEGUID, OLEGUID)) { *propType = mapi_nameid_tags[i].propType; return MAPI_E_SUCCESS; } } OPENCHANGE_RETVAL_ERR(MAPI_E_NOT_FOUND, NULL); } /** \details Search for a given lid,OLEGUID couple and return the associated canonical propTag. \param lid the named property light ID \param OLEGUID the named property GUID for this entry \param propTag pointer on returned named canonical property tag \return MAPI_E_SUCCESS on success, otherwise MAPI_E_NOT_FOUND. \note Developers may also call GetLastError() to retrieve the last MAPI error code. Possible MAPI error codes are: - MAPI_E_INVALID_PARAMETER: one of the parameter was not set properly. - MAPI_E_NOT_FOUND: no named property found */ _PUBLIC_ enum MAPISTATUS mapi_nameid_lid_lookup_canonical(uint16_t lid, const char *OLEGUID, uint32_t *propTag) { uint32_t i; /* Sanity checks */ OPENCHANGE_RETVAL_IF(!lid, MAPI_E_INVALID_PARAMETER, NULL); OPENCHANGE_RETVAL_IF(!OLEGUID, MAPI_E_INVALID_PARAMETER, NULL); OPENCHANGE_RETVAL_IF(!propTag, MAPI_E_INVALID_PARAMETER, NULL); for (i = 0; mapi_nameid_tags[i].OLEGUID; i++) { if (mapi_nameid_tags[i].lid == lid && !strcmp(mapi_nameid_tags[i].OLEGUID, OLEGUID)) { *propTag = mapi_nameid_tags[i].proptag; return MAPI_E_SUCCESS; } } OPENCHANGE_RETVAL_ERR(MAPI_E_NOT_FOUND, NULL); } /** \details Search for a given Name,OLEGUID couple and return the associated propType. \param Name the named property name \param OLEGUID the named property GUID for this entry \param propType pointer on returned named property type \return MAPI_E_SUCCESS on success, otherwise MAPI_E_NOT_FOUND. \note Developers may also call GetLastError() to retrieve the last MAPI error code. Possible MAPI error codes are: - MAPI_E_INVALID_PARAMETER: one of the parameter was not set properly. - MAPI_E_NOT_FOUND: no named property found */ _PUBLIC_ enum MAPISTATUS mapi_nameid_string_lookup(const char *Name, const char *OLEGUID, uint16_t *propType) { uint32_t i; /* Sanity checks */ OPENCHANGE_RETVAL_IF(!Name, MAPI_E_INVALID_PARAMETER, NULL); OPENCHANGE_RETVAL_IF(!OLEGUID, MAPI_E_INVALID_PARAMETER, NULL); for (i = 0; mapi_nameid_tags[i].OLEGUID; i++) { if (mapi_nameid_tags[i].Name && !strcmp(mapi_nameid_tags[i].Name, Name) && !strcmp(mapi_nameid_tags[i].OLEGUID, OLEGUID)) { *propType = mapi_nameid_tags[i].propType; return MAPI_E_SUCCESS; } } OPENCHANGE_RETVAL_ERR(MAPI_E_NOT_FOUND, NULL); } /** \details Search for a given Name,OLEGUID couple and return the associated canonical propTag. \param Name the named property name \param OLEGUID the named property GUID for this entry \param propTag pointer on returned named canonical property tag \return MAPI_E_SUCCESS on success, otherwise MAPI_E_NOT_FOUND. \note Developers may also call GetLastError() to retrieve the last MAPI error code. Possible MAPI error codes are: - MAPI_E_INVALID_PARAMETER: one of the parameter was not set properly. - MAPI_E_NOT_FOUND: no named property found */ _PUBLIC_ enum MAPISTATUS mapi_nameid_string_lookup_canonical(const char *Name, const char *OLEGUID, uint32_t *propTag) { uint32_t i; /* Sanity checks */ OPENCHANGE_RETVAL_IF(!Name, MAPI_E_INVALID_PARAMETER, NULL); OPENCHANGE_RETVAL_IF(!OLEGUID, MAPI_E_INVALID_PARAMETER, NULL); OPENCHANGE_RETVAL_IF(!propTag, MAPI_E_INVALID_PARAMETER, NULL); for (i = 0; mapi_nameid_tags[i].OLEGUID; i++) { if (mapi_nameid_tags[i].Name && !strcmp(mapi_nameid_tags[i].Name, Name) && !strcmp(mapi_nameid_tags[i].OLEGUID, OLEGUID)) { *propTag = mapi_nameid_tags[i].proptag; return MAPI_E_SUCCESS; } } OPENCHANGE_RETVAL_ERR(MAPI_E_NOT_FOUND, NULL); } /** \details set SPropTagArray ulPropTag property types from mapi_nameid returned by GetIDsFromNames() \param mapi_nameid the structure where results are stored \param SPropTagArray the array of property tags returned by previous call to GetIDsFromNames() \return MAPI_E_SUCCESS on success, otherwise MAPI error. \note Developers may also call GetLastError() to retrieve the last MAPI error code. Possible MAPI error codes are: - MAPI_E_INVALID_PARAMETER: one of the parameters was not set properly \sa GetIDsFromNames */ _PUBLIC_ enum MAPISTATUS mapi_nameid_SPropTagArray(struct mapi_nameid *mapi_nameid, struct SPropTagArray *SPropTagArray) { uint32_t i; /* sanity check */ OPENCHANGE_RETVAL_IF(!mapi_nameid, MAPI_E_INVALID_PARAMETER, NULL); OPENCHANGE_RETVAL_IF(!SPropTagArray, MAPI_E_INVALID_PARAMETER, NULL); for (i = 0; i < mapi_nameid->count; i++) { if (mapi_nameid->entries[i].propType) { SPropTagArray->aulPropTag[i] = (enum MAPITAGS)(((int)SPropTagArray->aulPropTag[i] & 0xFFFF0000) | mapi_nameid->entries[i].propType); } } return MAPI_E_SUCCESS; } /** \details Replace named property tags in SPropTagArray with the property ID Exchange expects and stored in SPropTagArray2. \param mapi_nameid the structure where results are stored \param SPropTagArray the array of property tags with original property tags \param SPropTagArray2 the array of named property tags resolved with GetIDsFromNames \return MAPI_E_SUCCESS on success, otherwise MAPI error. \note Developers may also call GetLastError() to retrieve the last MAPI error code. Possible MAPI error codes are: - MAPI_E_INVALID_PARAMETER: one of the parameters was not set properly \sa GetIDsFromNames */ _PUBLIC_ enum MAPISTATUS mapi_nameid_map_SPropTagArray(struct mapi_nameid *mapi_nameid, struct SPropTagArray *SPropTagArray, struct SPropTagArray *SPropTagArray2) { uint32_t i; uint32_t j; /* Sanity Checks */ OPENCHANGE_RETVAL_IF(!mapi_nameid, MAPI_E_INVALID_PARAMETER, NULL); OPENCHANGE_RETVAL_IF(!SPropTagArray, MAPI_E_INVALID_PARAMETER, NULL); OPENCHANGE_RETVAL_IF(!SPropTagArray2, MAPI_E_INVALID_PARAMETER, NULL); for (i = 0; i < SPropTagArray->cValues; i++) { for (j = 0; j < mapi_nameid->count; j++) { if ((enum MAPITAGS)mapi_nameid->entries[j].proptag == SPropTagArray->aulPropTag[i]) { SPropTagArray->aulPropTag[i] = (enum MAPITAGS)(((int)SPropTagArray2->aulPropTag[j] & 0xFFFF0000) | mapi_nameid->entries[j].propType); mapi_nameid->entries[j].position = i; } } } return MAPI_E_SUCCESS; } /** \details Restore the original SPropTagArray array with the property tags saved in the mapi_nameid structure. \param mapi_nameid the structure where results are stored \param SPropTagArray the array of property tags with original property tags \return MAPI_E_SUCCESS on success, otherwise MAPI error. \note Developers may also call GetLastError() to retrieve the last MAPI error code. Possible MAPI error codes are: - MAPI_E_INVALID_PARAMETER: one of the parameters was not set properly \sa GetIDsFromNames */ _PUBLIC_ enum MAPISTATUS mapi_nameid_unmap_SPropTagArray(struct mapi_nameid *mapi_nameid, struct SPropTagArray *SPropTagArray) { uint32_t i; /* Sanity Checks */ OPENCHANGE_RETVAL_IF(!mapi_nameid, MAPI_E_INVALID_PARAMETER, NULL); OPENCHANGE_RETVAL_IF(!SPropTagArray, MAPI_E_INVALID_PARAMETER, NULL); for (i = 0; i < mapi_nameid->count; i++) { if (mapi_nameid->entries[i].position <= SPropTagArray->cValues) { SPropTagArray->aulPropTag[mapi_nameid->entries[i].position] = (enum MAPITAGS) mapi_nameid->entries[i].proptag; } } return MAPI_E_SUCCESS; } /** \details Replace named property tags in the SPropValue array with the property ID Exchange expects and stored in SPropTagArray. \param mapi_nameid the structure where results are stored \param lpProps pointer on a SPropValue structure with property tags and values \param PropCount count of lpProps elements \param SPropTagArray the array of named property tags resolved with GetIDsFromNames \return MAPI_E_SUCCESS on success, otherwise MAPI error. \note Developers may also call GetLastError() to retrieve the last MAPI error code. Possible MAPI error codes are: - MAPI_E_INVALID_PARAMETER: one of the parameters was not set properly \sa GetIDsFromNames */ _PUBLIC_ enum MAPISTATUS mapi_nameid_map_SPropValue(struct mapi_nameid *mapi_nameid, struct SPropValue *lpProps, uint32_t PropCount, struct SPropTagArray *SPropTagArray) { uint32_t i; uint32_t j; /* Sanity Checks */ OPENCHANGE_RETVAL_IF(!mapi_nameid, MAPI_E_INVALID_PARAMETER, NULL); OPENCHANGE_RETVAL_IF(!lpProps, MAPI_E_INVALID_PARAMETER, NULL); OPENCHANGE_RETVAL_IF(!PropCount, MAPI_E_INVALID_PARAMETER, NULL); OPENCHANGE_RETVAL_IF(!SPropTagArray, MAPI_E_INVALID_PARAMETER, NULL); for (i = 0; i < PropCount; i++) { for (j = 0; j < mapi_nameid->count; j++) { if ((enum MAPITAGS)mapi_nameid->entries[j].proptag == lpProps[i].ulPropTag) { lpProps[i].ulPropTag = (enum MAPITAGS)(((int)SPropTagArray->aulPropTag[j] & 0xFFFF0000) | mapi_nameid->entries[j].propType); mapi_nameid->entries[j].position = i; } } } return MAPI_E_SUCCESS; } /** \details Restore the original SPropValue array with the property tags saved in the mapi_nameid structure. \param mapi_nameid the structure where results are stored \param lpProps the array of SPropValue structures with original property tags \param PropCount count of lpProps elements \return MAPI_E_SUCCESS on success, otherwise MAPI error. \note Developers may also call GetLastError() to retrieve the last MAPI error code. Possible MAPI error codes are: - MAPI_E_INVALID_PARAMETER: one of the parameters was not set properly \sa GetIDsFromNames */ _PUBLIC_ enum MAPISTATUS mapi_nameid_unmap_SPropValue(struct mapi_nameid *mapi_nameid, struct SPropValue *lpProps, uint32_t PropCount) { uint32_t i; /* Sanity Checks */ OPENCHANGE_RETVAL_IF(!mapi_nameid, MAPI_E_INVALID_PARAMETER, NULL); OPENCHANGE_RETVAL_IF(!lpProps, MAPI_E_INVALID_PARAMETER, NULL); OPENCHANGE_RETVAL_IF(!PropCount, MAPI_E_INVALID_PARAMETER, NULL); for (i = 0; i < mapi_nameid->count; i++) { if (mapi_nameid->entries[i].position <= PropCount) { lpProps[mapi_nameid->entries[i].position].ulPropTag = (enum MAPITAGS) mapi_nameid->entries[i].proptag; } } return MAPI_E_SUCCESS; } /** \details Loop over SPropTagArray and look for canonical named property tags we can add to the nameid structure. \param nameid the structure where results are stored \param SPropTagArray the array of property tags where to look for canonical named property tags. \return MAPI_E_SUCCESS on success, otherwise MAPI error. \note Developers may also call GetLastError() to retrieve the last MAPI error code. Possible MAPI error codes are: - MAPI_E_INVALID_PARAMETER: one of the parameters was not set properly - MAPI_E_NOT_FOUND: no named property found \sa GetIDsFromNames */ _PUBLIC_ enum MAPISTATUS mapi_nameid_lookup_SPropTagArray(struct mapi_nameid *nameid, struct SPropTagArray *SPropTagArray) { enum MAPISTATUS retval; uint32_t i; bool status = false; /* Sanity checks */ OPENCHANGE_RETVAL_IF(!nameid, MAPI_E_INVALID_PARAMETER, NULL); OPENCHANGE_RETVAL_IF(!SPropTagArray, MAPI_E_INVALID_PARAMETER, NULL); for (i = 0; i < SPropTagArray->cValues; i++) { if (mapi_nameid_property_lookup(SPropTagArray->aulPropTag[i]) == MAPI_E_SUCCESS) { retval = mapi_nameid_canonical_add(nameid, SPropTagArray->aulPropTag[i]); if (retval == MAPI_E_SUCCESS) { status = true; } } } return (status == true) ? MAPI_E_SUCCESS : MAPI_E_NOT_FOUND; } /** \details Loop over lpProps and look for canonical named property tags we can add to the nameid structure. \param mapi_nameid the structure where results are stored \param lpProps pointer on a SPropValue structure with the property tags where to look for canonical named property tags \param PropCount count of lpProps elemense \return MAPI_E_SUCCESS on success, otherwise MAPI error. \note Developers may also call GetLastError() to retrieve the last MAPI error code. Possible MAPI error codes are: - MAPI_E_INVALID_PARAMETER: one of the parameters was not set properly - MAPI_E_NOT_FOUND: no named property found \sa GetIDsFromNames */ _PUBLIC_ enum MAPISTATUS mapi_nameid_lookup_SPropValue(struct mapi_nameid *mapi_nameid, struct SPropValue *lpProps, unsigned long PropCount) { enum MAPISTATUS retval; uint32_t i; uint16_t proptype; bool status = false; /* Sanity checks */ OPENCHANGE_RETVAL_IF(!mapi_nameid, MAPI_E_INVALID_PARAMETER, NULL); OPENCHANGE_RETVAL_IF(!lpProps, MAPI_E_INVALID_PARAMETER, NULL); for (i = 0; i < PropCount; i++) { proptype = (lpProps[i].ulPropTag & 0xFFFF0000) >> 16; if (((proptype >= 0x8000) && (proptype <= 0x8FFF)) || ((proptype >= 0xa000) && (proptype <= 0xaFFF))) { retval = mapi_nameid_canonical_add(mapi_nameid, lpProps[i].ulPropTag); if (retval == MAPI_E_SUCCESS) { status = true; } } } return (status == true) ? MAPI_E_SUCCESS : MAPI_E_NOT_FOUND; } /** \details Lookup named properties (MNID_STRING) and return their mapped proptags This convenient function calls GetIDsFromNames() and returns property tags with their real property type. \return MAPI_E_SUCCESS on success, otherwise MAPI error. \note Developers may also call GetLastError() to retrieve the last MAPI error code. Possible MAPI error codes are: - MAPI_E_INVALID_PARAMETER: one of the parameters was not set properly \sa GetIDsFromNames, mapi_nameid_SPropTagArray */ _PUBLIC_ enum MAPISTATUS mapi_nameid_GetIDsFromNames(struct mapi_nameid *mapi_nameid, mapi_object_t *obj, struct SPropTagArray *SPropTagArray) { enum MAPISTATUS retval; uint32_t i; /* sanity check */ OPENCHANGE_RETVAL_IF(!mapi_nameid, MAPI_E_INVALID_PARAMETER, NULL); OPENCHANGE_RETVAL_IF(!SPropTagArray, MAPI_E_INVALID_PARAMETER, NULL); retval = GetIDsFromNames(obj, mapi_nameid->count, mapi_nameid->nameid, 0, &SPropTagArray); OPENCHANGE_RETVAL_IF(retval, GetLastError(), NULL); for (i = 0; i < SPropTagArray->cValues; i++) { SPropTagArray->aulPropTag[i] = (enum MAPITAGS)(((int)SPropTagArray->aulPropTag[i] & 0xFFFF0000) | mapi_nameid->entries[i].propType); } return MAPI_E_SUCCESS; } _PUBLIC_ const char *get_namedid_name(uint32_t proptag) { uint32_t idx; for (idx = 0; mapi_nameid_names[idx].proptag; idx++) { if (mapi_nameid_names[idx].proptag == proptag) { return mapi_nameid_names[idx].propname; } } if (((proptag & 0xFFFF) == PT_STRING8) || ((proptag & 0xFFFF) == PT_MV_STRING8)) { proptag += 1; /* try as _UNICODE variant */ } for (idx = 0; mapi_nameid_names[idx].proptag; idx++) { if (mapi_nameid_names[idx].proptag == proptag) { return mapi_nameid_names[idx].propname; } } return NULL; } _PUBLIC_ uint32_t get_namedid_value(const char *propname) { uint32_t idx; for (idx = 0; mapi_nameid_names[idx].proptag; idx++) { if (!strcmp(mapi_nameid_names[idx].propname, propname)) { return mapi_nameid_names[idx].proptag; } } return 0; } _PUBLIC_ uint16_t get_namedid_type(uint16_t untypedtag) { uint32_t idx; uint16_t current_type; for (idx = 0; mapi_nameid_names[idx].proptag; idx++) { if ((mapi_nameid_names[idx].proptag >> 16) == untypedtag) { current_type = mapi_nameid_names[idx].proptag & 0xFFFF; if (current_type != PT_ERROR && current_type != PT_STRING8) { return current_type; } } } DEBUG(5, ("%s: type for property '%x' could not be deduced\n", __FUNCTION__, untypedtag)); return 0; } openchange-2.0/libmapi/mapi_nameid.h000066400000000000000000001476461223057412600175370ustar00rootroot00000000000000 /* Automatically generated by script/makepropslist.py. Do not edit */ #ifndef __MAPI_NAMEID_H__ #define __MAPI_NAMEID_H__ /* NOTE TO DEVELOPERS: If this is a MNID_STRING named property, then * we use the arbitrary 0xa000-0xafff property ID range for internal * mapping purpose only. */ struct mapi_nameid_tags { uint32_t proptag; const char *OOM; uint16_t lid; const char *Name; uint32_t propType; uint8_t ulKind; const char *OLEGUID; uint32_t position; }; struct mapi_nameid_names { uint32_t proptag; const char *propname; }; struct mapi_nameid { struct MAPINAMEID *nameid; uint16_t count; struct mapi_nameid_tags *entries; }; /* MNID_ID named properties */ #define PidLidAddressBookProviderArrayType 0x80290003 #define PidLidAddressBookProviderEmailList 0x80281003 #define PidLidAddressCountryCode 0x80dd001f #define PidLidAnniversaryEventEntryId 0x804e0102 #define PidLidAutoLog 0x8025000b #define PidLidBirthdayEventEntryId 0x804d0102 #define PidLidBirthdayLocal 0x80de0040 #define PidLidBusinessCardCardPicture 0x80410102 #define PidLidBusinessCardDisplayDefinition 0x80400102 #define PidLidContactCharacterSet 0x80230003 #define PidLidContactItemData 0x80071003 #define PidLidContactUserField1 0x804f001f #define PidLidContactUserField2 0x8050001f #define PidLidContactUserField3 0x8051001f #define PidLidContactUserField4 0x8052001f #define PidLidDepartment 0x8010001f #define PidLidDistributionListChecksum 0x804c0003 #define PidLidDistributionListMembers 0x80551102 #define PidLidDistributionListName 0x8053001f #define PidLidDistributionListOneOffMembers 0x80541102 #define PidLidDistributionListStream 0x80640102 #define PidLidEmail1AddressType 0x8082001f #define PidLidEmail1DisplayName 0x8080001f #define PidLidEmail1EmailAddress 0x8083001f #define PidLidEmail1OriginalDisplayName 0x8084001f #define PidLidEmail1OriginalEntryId 0x80850102 #define PidLidEmail1RichTextFormat 0x8086000b #define PidLidEmail2AddressType 0x8092001f #define PidLidEmail2DisplayName 0x8090001f #define PidLidEmail2EmailAddress 0x8093001f #define PidLidEmail2OriginalDisplayName 0x8094001f #define PidLidEmail2OriginalEntryId 0x80950102 #define PidLidEmail2RichTextFormat 0x8096000b #define PidLidEmail3AddressType 0x80a2001f #define PidLidEmail3DisplayName 0x80a0001f #define PidLidEmail3EmailAddress 0x80a3001f #define PidLidEmail3OriginalDisplayName 0x80a4001f #define PidLidEmail3OriginalEntryId 0x80a50102 #define PidLidEmail3RichTextFormat 0x80a6000b #define PidLidEmailList 0x80271003 #define PidLidFax1AddressType 0x80b2001f #define PidLidFax1EmailAddress 0x80b3001f #define PidLidFax1OriginalDisplayName 0x80b4001f #define PidLidFax1OriginalEntryId 0x80b50102 #define PidLidFax2AddressType 0x80c2001f #define PidLidFax2EmailAddress 0x80c3001f #define PidLidFax2OriginalDisplayName 0x80c4001f #define PidLidFax2OriginalEntryId 0x80c50102 #define PidLidFax3AddressType 0x80d2001f #define PidLidFax3EmailAddress 0x80d3001f #define PidLidFax3OriginalDisplayName 0x80d4001f #define PidLidFax3OriginalEntryId 0x80d50102 #define PidLidFileUnder 0x8005001f #define PidLidFileUnderId 0x80060003 #define PidLidFileUnderList 0x80261003 #define PidLidFreeBusyLocation 0x80d8001f #define PidLidHasPicture 0x8015000b #define PidLidHomeAddress 0x801a001f #define PidLidHomeAddressCountryCode 0x80da001f #define PidLidHtml 0x802b001f #define PidLidInstantMessagingAddress 0x8062001f #define PidLidOtherAddress 0x801c001f #define PidLidOtherAddressCountryCode 0x80dc001f #define PidLidPostalAddressId 0x80220003 #define PidLidReferredBy 0x800e001f #define PidLidWeddingAnniversaryLocal 0x80df0040 #define PidLidWorkAddress 0x801b001f #define PidLidWorkAddressCity 0x8046001f #define PidLidWorkAddressCountry 0x8049001f #define PidLidWorkAddressCountryCode 0x80db001f #define PidLidWorkAddressPostalCode 0x8048001f #define PidLidWorkAddressPostOfficeBox 0x804a001f #define PidLidWorkAddressState 0x8047001f #define PidLidYomiCompanyName 0x802e001f #define PidLidYomiFirstName 0x802c001f #define PidLidYomiLastName 0x802d001f #define PidLidAllAttendeesString 0x8238001f #define PidLidAllowExternalCheck 0x8246000b #define PidLidAppointmentAuxiliaryFlags 0x82070003 #define PidLidAppointmentColor 0x82140003 #define PidLidAppointmentCounterProposal 0x8257000b #define PidLidAppointmentDuration 0x82130003 #define PidLidAppointmentEndDate 0x82110040 #define PidLidAppointmentEndTime 0x82100040 #define PidLidAppointmentEndWhole 0x820e0040 #define PidLidAppointmentLastSequence 0x82030003 #define PidLidAppointmentNotAllowPropose 0x825a000b #define PidLidAppointmentProposalNumber 0x82590003 #define PidLidAppointmentProposedDuration 0x82560003 #define PidLidAppointmentProposedEndWhole 0x82510040 #define PidLidAppointmentProposedStartWhole 0x82500040 #define PidLidAppointmentRecur 0x82160102 #define PidLidAppointmentReplyName 0x8230001f #define PidLidAppointmentReplyTime 0x82200040 #define PidLidAppointmentSequence 0x82010003 #define PidLidAppointmentSequenceTime 0x82020040 #define PidLidAppointmentStartDate 0x82120040 #define PidLidAppointmentStartTime 0x820f0040 #define PidLidAppointmentStartWhole 0x820d0040 #define PidLidAppointmentStateFlags 0x82170003 #define PidLidAppointmentSubType 0x8215000b #define PidLidAppointmentTimeZoneDefinitionEndDisplay 0x825f0102 #define PidLidAppointmentTimeZoneDefinitionRecur 0x82600102 #define PidLidAppointmentTimeZoneDefinitionStartDisplay 0x825e0102 #define PidLidAppointmentUnsendableRecipients 0x825d0102 #define PidLidAppointmentUpdateTime 0x82260040 #define PidLidAutoFillLocation 0x823a000b #define PidLidAutoStartCheck 0x8244000b #define PidLidBusyStatus 0x82050003 #define PidLidCcAttendeesString 0x823c001f #define PidLidChangeHighlight 0x82040003 #define PidLidClipEnd 0x82360040 #define PidLidClipStart 0x82350040 #define PidLidCollaborateDoc 0x8247001f #define PidLidConferencingCheck 0x8240000b #define PidLidConferencingType 0x82410003 #define PidLidDirectory 0x8242001f #define PidLidExceptionReplaceTime 0x82280040 #define PidLidFExceptionalAttendees 0x822b000b #define PidLidFExceptionalBody 0x8206000b #define PidLidFInvited 0x8229000b #define PidLidForwardInstance 0x820a000b #define PidLidForwardNotificationRecipients 0x82610102 #define PidLidFOthersAppointment 0x822f000b #define PidLidInboundICalStream 0x827a0102 #define PidLidIntendedBusyStatus 0x82240003 #define PidLidLinkedTaskItems 0x820c1102 #define PidLidLocation 0x8208001f #define PidLidMeetingWorkspaceUrl 0x8209001f #define PidLidNetShowUrl 0x8248001f #define PidLidOnlinePassword 0x8249001f #define PidLidOrganizerAlias 0x8243001f #define PidLidOriginalStoreEntryId 0x82370102 #define PidLidOwnerName 0x822e001f #define PidLidRecurrencePattern 0x8232001f #define PidLidRecurrenceType 0x82310003 #define PidLidRecurring 0x8223000b #define PidLidResponseStatus 0x82180003 #define PidLidSingleBodyICal 0x827b000b #define PidLidTimeZoneDescription 0x8234001f #define PidLidTimeZoneStruct 0x82330102 #define PidLidToAttendeesString 0x823b001f #define PidLidClientIntent 0x00150003 #define PidLidServerProcessed 0x85cc000b #define PidLidServerProcessingActions 0x85cd0003 #define PidLidAgingDontAgeMe 0x850e000b #define PidLidAutoProcessState 0x851a0003 #define PidLidBilling 0x8535001f #define PidLidClassification 0x85b6001f #define PidLidClassificationDescription 0x85b7001f #define PidLidClassificationGuid 0x85b8001f #define PidLidClassificationKeep 0x85ba000b #define PidLidClassified 0x85b5000b #define PidLidCommonEnd 0x85170040 #define PidLidCommonStart 0x85160040 #define PidLidCompanies 0x8539101f #define PidLidContactLinkEntry 0x85850102 #define PidLidContactLinkName 0x8586001f #define PidLidContactLinkSearchKey 0x85840102 #define PidLidContacts 0x853a101f #define PidLidConversationActionLastAppliedTime 0x85ca0040 #define PidLidConversationActionMaxDeliveryTime 0x85c80040 #define PidLidConversationActionMoveFolderEid 0x85c60102 #define PidLidConversationActionMoveStoreEid 0x85c70102 #define PidLidConversationActionVersion 0x85cb0003 #define PidLidConversationProcessed 0x85c90003 #define PidLidCurrentVersion 0x85520003 #define PidLidCurrentVersionName 0x8554001f #define PidLidDayOfMonth 0x10000003 #define PidLidFlagRequest 0x8530001f #define PidLidFlagString 0x85c00003 #define PidLidICalendarDayOfWeekMask 0x10010003 #define PidLidInfoPathFormName 0x85b1001f #define PidLidInternetAccountName 0x8580001f #define PidLidInternetAccountStamp 0x8581001f #define PidLidMonthOfYear 0x10060003 #define PidLidNoEndDateFlag 0x100b000b #define PidLidNonSendableBcc 0x8538001f #define PidLidNonSendableCc 0x8537001f #define PidLidNonSendableTo 0x8536001f #define PidLidNonSendBccTrackStatus 0x85451003 #define PidLidNonSendCcTrackStatus 0x85441003 #define PidLidNonSendToTrackStatus 0x85431003 #define PidLidOccurrences 0x10050003 #define PidLidPrivate 0x8506000b #define PidLidPromptSendUpdate 0x8045000b #define PidLidRecurrenceDuration 0x100d0003 #define PidLidReferenceEntryId 0x85bd0102 #define PidLidReminderDelta 0x85010003 #define PidLidReminderFileParameter 0x851f001f #define PidLidReminderOverride 0x851c000b #define PidLidReminderPlaySound 0x851e000b #define PidLidReminderSet 0x8503000b #define PidLidReminderSignalTime 0x85600040 #define PidLidReminderTime 0x85020040 #define PidLidReminderTimeDate 0x85050040 #define PidLidReminderTimeTime 0x85040040 #define PidLidReminderType 0x851d0003 #define PidLidRemoteStatus 0x85110003 #define PidLidSideEffects 0x85100003 #define PidLidSmartNoAttach 0x8514000b #define PidLidSpamOriginalFolder 0x859c0102 #define PidLidTaskGlobalId 0x85190102 #define PidLidTaskMode 0x85180003 #define PidLidToDoOrdinalDate 0x85a00040 #define PidLidToDoSubOrdinal 0x85a1001f #define PidLidToDoTitle 0x85a4001f #define PidLidUseTnef 0x8582000b #define PidLidValidFlagStringProof 0x85bf0040 #define PidLidVerbResponse 0x8524001f #define PidLidVerbStream 0x85200102 #define PidLidLogDocumentPosted 0x8711000b #define PidLidLogDocumentPrinted 0x870e000b #define PidLidLogDocumentRouted 0x8710000b #define PidLidLogDocumentSaved 0x870f000b #define PidLidLogDuration 0x87070003 #define PidLidLogEnd 0x87080040 #define PidLidLogFlags 0x870c0003 #define PidLidLogStart 0x87060040 #define PidLidLogType 0x8700001f #define PidLidLogTypeDesc 0x8712001f #define PidLidAppointmentMessageClass 0x0024001f #define PidLidAttendeeCriticalChange 0x00010040 #define PidLidCalendarType 0x001c0003 #define PidLidCleanGlobalObjectId 0x00230102 #define PidLidDayInterval 0x00110002 #define PidLidDelegateMail 0x0009000b #define PidLidEndRecurrenceDate 0x000f0003 #define PidLidEndRecurrenceTime 0x00100003 #define PidLidGlobalObjectId 0x00030102 #define PidLidIsException 0x000a000b #define PidLidIsRecurring 0x0005000b #define PidLidIsSilent 0x0004000b #define PidLidMeetingType 0x00260003 #define PidLidMonthInterval 0x00130002 #define PidLidMonthOfYearMask 0x00170003 #define PidLidOldLocation 0x0028001f #define PidLidOldRecurrenceType 0x00180002 #define PidLidOldWhenEndWhole 0x002a0040 #define PidLidOldWhenStartWhole 0x00290040 #define PidLidOptionalAttendees 0x0007001f #define PidLidOwnerCriticalChange 0x001a0040 #define PidLidRequiredAttendees 0x0006001f #define PidLidResourceAttendees 0x0008001f #define PidLidStartRecurrenceDate 0x000d0003 #define PidLidStartRecurrenceTime 0x000e0003 #define PidLidTimeZone 0x000c0003 #define PidLidWeekInterval 0x00120002 #define PidLidWhere 0x0002001f #define PidLidYearInterval 0x00140002 #define PidLidNoteColor 0x8b000003 #define PidLidNoteHeight 0x8b030003 #define PidLidNoteWidth 0x8b020003 #define PidLidNoteX 0x8b040003 #define PidLidNoteY 0x8b050003 #define PidLidPostRssChannel 0x8904001f #define PidLidPostRssChannelLink 0x8900001f #define PidLidPostRssItemGuid 0x8903001f #define PidLidPostRssItemHash 0x89020003 #define PidLidPostRssItemLink 0x8901001f #define PidLidPostRssItemXml 0x8905001f #define PidLidPostRssSubscription 0x8906001f #define PidLidSharingAnonymity 0x8a190003 #define PidLidSharingBindingEntryId 0x8a2d0102 #define PidLidSharingBrowseUrl 0x8a51001f #define PidLidSharingCapabilities 0x8a170003 #define PidLidSharingConfigurationUrl 0x8a24001f #define PidLidSharingDataRangeEnd 0x8a450040 #define PidLidSharingDataRangeStart 0x8a440040 #define PidLidSharingDetail 0x8a2b0003 #define PidLidSharingExtensionXml 0x8a21001f #define PidLidSharingFilter 0x8a130102 #define PidLidSharingFlags 0x8a0a0003 #define PidLidSharingFlavor 0x8a180003 #define PidLidSharingFolderEntryId 0x8a150102 #define PidLidSharingIndexEntryId 0x8a2e0102 #define PidLidSharingInitiatorEntryId 0x8a090102 #define PidLidSharingInitiatorName 0x8a07001f #define PidLidSharingInitiatorSmtp 0x8a08001f #define PidLidSharingInstanceGuid 0x8a1c0102 #define PidLidSharingLastAutoSyncTime 0x8a550040 #define PidLidSharingLastSyncTime 0x8a1f0040 #define PidLidSharingLocalComment 0x8a4d001f #define PidLidSharingLocalLastModificationTime 0x8a230040 #define PidLidSharingLocalName 0x8a0f001f #define PidLidSharingLocalPath 0x8a0e001f #define PidLidSharingLocalStoreUid 0x8a49001f #define PidLidSharingLocalType 0x8a14001f #define PidLidSharingLocalUid 0x8a10001f #define PidLidSharingOriginalMessageEntryId 0x8a290102 #define PidLidSharingParentBindingEntryId 0x8a5c0102 #define PidLidSharingParticipants 0x8a1e001f #define PidLidSharingPermissions 0x8a1b0003 #define PidLidSharingProviderExtension 0x8a0b001f #define PidLidSharingProviderGuid 0x8a010102 #define PidLidSharingProviderName 0x8a02001f #define PidLidSharingProviderUrl 0x8a03001f #define PidLidSharingRangeEnd 0x8a470003 #define PidLidSharingRangeStart 0x8a460003 #define PidLidSharingReciprocation 0x8a1a0003 #define PidLidSharingRemoteByteSize 0x8a4b0003 #define PidLidSharingRemoteComment 0x8a2f001f #define PidLidSharingRemoteCrc 0x8a4c0003 #define PidLidSharingRemoteLastModificationTime 0x8a220040 #define PidLidSharingRemoteMessageCount 0x8a4f0003 #define PidLidSharingRemoteName 0x8a05001f #define PidLidSharingRemotePass 0x8a0d001f #define PidLidSharingRemotePath 0x8a04001f #define PidLidSharingRemoteStoreUid 0x8a48001f #define PidLidSharingRemoteType 0x8a1d001f #define PidLidSharingRemoteUid 0x8a06001f #define PidLidSharingRemoteUser 0x8a0c001f #define PidLidSharingRemoteVersion 0x8a5b001f #define PidLidSharingResponseTime 0x8a280040 #define PidLidSharingResponseType 0x8a270003 #define PidLidSharingRoamLog 0x8a4e0003 #define PidLidSharingStart 0x8a250040 #define PidLidSharingStatus 0x8a000003 #define PidLidSharingStop 0x8a260040 #define PidLidSharingSyncFlags 0x8a600003 #define PidLidSharingSyncInterval 0x8a2a0003 #define PidLidSharingTimeToLive 0x8a2c0003 #define PidLidSharingTimeToLiveAuto 0x8a560003 #define PidLidSharingWorkingHoursDays 0x8a420003 #define PidLidSharingWorkingHoursEnd 0x8a410040 #define PidLidSharingWorkingHoursStart 0x8a400040 #define PidLidSharingWorkingHoursTimeZone 0x8a430102 #define PidLidPercentComplete 0x81020005 #define PidLidTaskAcceptanceState 0x812a0003 #define PidLidTaskAccepted 0x8108000b #define PidLidTaskActualEffort 0x81100003 #define PidLidTaskAssigner 0x8121001f #define PidLidTaskAssigners 0x81170102 #define PidLidTaskComplete 0x811c000b #define PidLidTaskCustomFlags 0x81390003 #define PidLidTaskDateCompleted 0x810f0040 #define PidLidTaskDeadOccurrence 0x8109000b #define PidLidTaskDueDate 0x81050040 #define PidLidTaskEstimatedEffort 0x81110003 #define PidLidTaskFCreator 0x811e000b #define PidLidTaskFFixOffline 0x812c000b #define PidLidTaskFRecurring 0x8126000b #define PidLidTaskHistory 0x811a0003 #define PidLidTaskLastDelegate 0x8125001f #define PidLidTaskLastUpdate 0x81150040 #define PidLidTaskLastUser 0x8122001f #define PidLidTaskMultipleRecipients 0x81200003 #define PidLidTaskNoCompute 0x8124000b #define PidLidTaskOrdinal 0x81230003 #define PidLidTaskOwner 0x811f001f #define PidLidTaskOwnership 0x81290003 #define PidLidTaskRecurrence 0x81160102 #define PidLidTaskResetReminder 0x8107000b #define PidLidTaskRole 0x8127001f #define PidLidTaskStartDate 0x81040040 #define PidLidTaskState 0x81130003 #define PidLidTaskStatus 0x81010003 #define PidLidTaskStatusOnComplete 0x8119000b #define PidLidTaskUpdates 0x811b000b #define PidLidTaskVersion 0x81120003 #define PidLidTeamTask 0x8103000b #define PidLidTrustRecipientHighlights 0x823e000b #define PidLidCategories 0x9000101f /* MNID_STRING named properties (internal mapping) */ #define PidNameInstantMessagingAddress2 0xa000001f #define PidNameInstantMessagingAddress3 0xa001001f #define PidNameAttachmentMacContentType 0xa002001f #define PidNameAttachmentMacInfo 0xa0030102 #define PidNameOriginalSpamConfidenceLevel 0xa0040003 #define PidNameAudioNotes 0xa005001f #define PidNameAutomaticSpeechRecognitionData 0xa0060102 #define PidNameOutlookProtectionRuleTimestamp 0xa007001f #define PidNameXUnifiedMessagingPartnerAssignedId 0xa008001f #define PidNameXUnifiedMessagingPartnerContent 0xa009001f #define PidNameXUnifiedMessagingPartnerContext 0xa00a001f #define PidNameXUnifiedMessagingPartnerStatus 0xa00b001f #define PidNameAcceptLanguage 0xa00c001f #define PidNameApprovalAllowedDecisionMakers 0xa00d001f #define PidNameApprovalRequestor 0xa00e001f #define PidNameApproved 0xa00f001f #define PidNameAuthenticatedAs 0xa010001f #define PidNameAuthenticatedDomain 0xa011001f #define PidNameAuthenticatedMechanism 0xa012001f #define PidNameAuthenticatedSource 0xa013001f #define PidNameBcc 0xa014001f #define PidNameCc 0xa015001f #define PidNameContentBase 0xa016001f #define PidNameContentClass 0xa017001f #define PidNameContentDisposition 0xa018001f #define PidNameContentID 0xa019001f #define PidNameContentLanguage 0xa01a001f #define PidNameContentLocation 0xa01b001f #define PidNameContentTransferEncoding 0xa01c001f #define PidNameContentType 0xa01d001f #define PidNameControl 0xa01e001f #define PidNameCrossReference 0xa01f001f #define PidNameDisposition 0xa020001f #define PidNameDispositionNotificationTo 0xa021001f #define PidNameDistribution 0xa022001f #define PidNameExpires 0xa023001f #define PidNameExpiryDate 0xa024001f #define PidNameFollowupTo 0xa025001f #define PidNameFrom 0xa026001f #define PidNameImportance 0xa027001f #define PidNameInReplyTo 0xa028001f #define PidNameInternetComment 0xa029001f #define PidNameInternetKeywords 0xa02a001f #define PidNameInternetSubject 0xa02b001f #define PidNameLines 0xa02c001f #define PidNameMessageId 0xa02d001f #define PidNameMimeVersion 0xa02e001f #define PidNameNewsgroups 0xa02f001f #define PidNameNntpPostingHost 0xa030001f #define PidNameOrganization 0xa031001f #define PidNameOriginalRecipient 0xa032001f #define PidNameOutlookProtectionRuleOverridden 0xa033001f #define PidNameOutlookProtectionRuleVersion 0xa034001f #define PidNamePath 0xa035001f #define PidNamePostingVersion 0xa036001f #define PidNamePriority 0xa037001f #define PidNameReceived 0xa038001f #define PidNameReferences 0xa039001f #define PidNameRelayVersion 0xa03a001f #define PidNameReplyBy 0xa03b001f #define PidNameReplyTo 0xa03c001f #define PidNameReturnPath 0xa03d001f #define PidNameReturnReceiptTo 0xa03e001f #define PidNameRightsProtectMessage 0xa03f001f #define PidNameSender 0xa040001f #define PidNameSensitivity 0xa041001f #define PidNameSummary 0xa042001f #define PidNameThreadIndex 0xa043001f #define PidNameThreadTopic 0xa044001f #define PidNameTo 0xa045001f #define PidNameXCallId 0xa046001f #define PidNameXFaxNumberOfPages 0xa0470002 #define PidNameXMailer 0xa048001f #define PidNameXMessageCompleted 0xa049001f #define PidNameXMessageFlag 0xa04a001f #define PidNameXRequireProtectedPlayOnPhone 0xa04b000b #define PidNameXSenderTelephoneNumber 0xa04c001f #define PidNameXSharingBrowseUrl 0xa04d001f #define PidNameXSharingCapabilities 0xa04e001f #define PidNameXSharingConfigUrl 0xa04f001f #define PidNameXSharingExendedCaps 0xa050001f #define PidNameXSharingFlavor 0xa051001f #define PidNameXSharingInstanceGuid 0xa052001f #define PidNameXSharingLocalType 0xa053001f #define PidNameXSharingProviderGuid 0xa054001f #define PidNameXSharingProviderName 0xa055001f #define PidNameXSharingProviderUrl 0xa056001f #define PidNameXSharingRemoteName 0xa057001f #define PidNameXSharingRemotePath 0xa058001f #define PidNameXSharingRemoteStoreUid 0xa059001f #define PidNameXSharingRemoteType 0xa05a001f #define PidNameXSharingRemoteUid 0xa05b001f #define PidNameXUnsent 0xa05c001f #define PidNameXVoiceMessageAttachmentOrder 0xa05d001f #define PidNameXVoiceMessageDuration 0xa05e0002 #define PidNameXVoiceMessageSenderName 0xa05f001f #define PidNameApplicationName 0xa060001f #define PidNameAuthor 0xa061001f #define PidNameByteCount 0xa0620003 #define PidNameCalendarAttendeeRole 0xa0630003 #define PidNameCalendarBusystatus 0xa064001f #define PidNameCalendarContact 0xa065001f #define PidNameCalendarContactUrl 0xa066001f #define PidNameCalendarCreated 0xa0670040 #define PidNameCalendarDescriptionUrl 0xa068001f #define PidNameCalendarDuration 0xa0690003 #define PidNameCalendarExceptionDate 0xa06a1040 #define PidNameCalendarExceptionRule 0xa06b101f #define PidNameCalendarGeoLatitude 0xa06c0005 #define PidNameCalendarGeoLongitude 0xa06d0005 #define PidNameCalendarInstanceType 0xa06e0003 #define PidNameCalendarIsOrganizer 0xa06f000b #define PidNameCalendarLastModified 0xa0700040 #define PidNameCalendarLocationUrl 0xa071001f #define PidNameCalendarMeetingStatus 0xa072001f #define PidNameCalendarMethod 0xa073001f #define PidNameCalendarProductId 0xa074001f #define PidNameCalendarRecurrenceIdRange 0xa075001f #define PidNameCalendarReminderOffset 0xa0760003 #define PidNameCalendarResources 0xa077001f #define PidNameCalendarRsvp 0xa078000b #define PidNameCalendarSequence 0xa0790003 #define PidNameCalendarTimeZone 0xa07a001f #define PidNameCalendarTimeZoneId 0xa07b0003 #define PidNameCalendarTransparent 0xa07c001f #define PidNameCalendarUid 0xa07d001f #define PidNameCalendarVersion 0xa07e001f #define PidNameCategory 0xa07f001f #define PidNameCharacterCount 0xa0800003 #define PidNameComments 0xa081001f #define PidNameCompany 0xa082001f #define PidNameContactsAlternateRecipient 0xa083001f #define PidNameContactsCountry 0xa084001f #define PidNameContactsEmail1 0xa085001f #define PidNameContactsEmail2 0xa086001f #define PidNameContactsEmail3 0xa087001f #define PidNameContactsFileAs 0xa088001f #define PidNameContactsFileasId 0xa0890003 #define PidNameContactsHomeLatitude 0xa08a0005 #define PidNameContactsHomeLongitude 0xa08b0005 #define PidNameContactsHomeTimeZone 0xa08c001f #define PidNameContactsMapUrl 0xa08d001f #define PidNameContactsOtherCountryCode 0xa08e001f #define PidNameContactsOtherPager 0xa08f001f #define PidNameContactsOtherTimeZone 0xa090001f #define PidNameContactsProxyAddresses 0xa091101f #define PidNameContactsSecretaryUrl 0xa092001f #define PidNameContactsSourceUrl 0xa093001f #define PidNameCreateDateTimeReadOnly 0xa0940040 #define PidNameDavGetContentType 0xa095001f #define PidNameDavId 0xa096001f #define PidNameDavIsCollection 0xa097000b #define PidNameDavIsStructuredDocument 0xa098000b #define PidNameDavParentName 0xa099001f #define PidNameDavResourceType 0xa09a001f #define PidNameDavSearchRequest 0xa09b001f #define PidNameDavSearchType 0xa09c001f #define PidNameDavUid 0xa09d001f #define PidNameDocumentParts 0xa09e101f #define PidNameEditTime 0xa09f001f #define PidNameExchangeIntendedBusyStatus 0xa0a0001f #define PidNameExchangeJunkEmailMoveStamp 0xa0a10003 #define PidNameExchangeModifyExceptionStructure 0xa0a20102 #define PidNameExchangeMsexchembdefaultmailfolder 0xa0a3001f #define PidNameExchangeMsexchembdefaultmailfoldertype 0xa0a4001f #define PidNameExchangeNoModifyExceptions 0xa0a5000b #define PidNameExchangePatternEnd 0xa0a60040 #define PidNameExchangePatternStart 0xa0a70040 #define PidNameExchangePublicFolderEmailAddress 0xa0a8001f #define PidNameExchangeReminderInterval 0xa0a90003 #define PidNameExchDatabaseSchema 0xa0aa101f #define PidNameExchDataExpectedContentClass 0xa0ab101f #define PidNameExchDataSchemaCollectionReference 0xa0ac001f #define PidNameHeadingPairs 0xa0ad0102 #define PidNameHiddenCount 0xa0ae0003 #define PidNameHttpmailCalendar 0xa0af001f #define PidNameHttpmailCc 0xa0b0001f #define PidNameHttpmailContacts 0xa0b1001f #define PidNameHttpmailContentMediaType 0xa0b2001f #define PidNameHttpmailFrom 0xa0b3001f #define PidNameHttpmailFromEmail 0xa0b4001f #define PidNameHttpmailHtmlDescription 0xa0b5001f #define PidNameHttpmailOutbox 0xa0b6001f #define PidNameHttpmailSendMessage 0xa0b7001f #define PidNameHttpmailSubmitted 0xa0b8000b #define PidNameHttpmailTo 0xa0b9001f #define PidNameICalendarRecurrenceDate 0xa0ba1040 #define PidNameICalendarRecurrenceRule 0xa0bb101f #define PidNameKeywords 0xa0bc101f #define PidNameLastAuthor 0xa0bd001f #define PidNameLastPrinted 0xa0be0040 #define PidNameLastSaveDateTime 0xa0bf0040 #define PidNameLineCount 0xa0c00003 #define PidNameLinksDirty 0xa0c1000b #define PidNameMailSubmissionUri 0xa0c2001f #define PidNameManager 0xa0c3001f #define PidNameMultimediaClipCount 0xa0c40003 #define PidNameNoteCount 0xa0c50003 #define PidNameOMSAccountGuid 0xa0c6001f #define PidNameOMSMobileModel 0xa0c7001f #define PidNameOMSScheduleTime 0xa0c80040 #define PidNameOMSServiceType 0xa0c90003 #define PidNameOMSSourceType 0xa0ca0003 #define PidNamePageCount 0xa0cb0003 #define PidNameParagraphCount 0xa0cc0003 #define PidNamePhishingStamp 0xa0cd0003 #define PidNamePresentationFormat 0xa0ce001f #define PidNameQuarantineOriginalSender 0xa0cf001f #define PidNameRevisionNumber 0xa0d0001f #define PidNameRightsManagementLicense 0xa0d11102 #define PidNameScale 0xa0d2000b #define PidNameSecurity 0xa0d30003 #define PidNameSlideCount 0xa0d40003 #define PidNameSubject 0xa0d5001f #define PidNameTemplate 0xa0d6001f #define PidNameThumbnail 0xa0d70102 #define PidNameTitle 0xa0d8001f #define PidNameWordCount 0xa0d90003 #define PidLidRemoteTransferSize 0x8f050003 #endif /* ! MAPI_NAMEID_H__ */openchange-2.0/libmapi/mapi_nameid_private.h000066400000000000000000005231041223057412600212540ustar00rootroot00000000000000 /* Automatically generated by script/makepropslist.py. Do not edit */ #ifndef __MAPI_NAMEID_PRIVATE_H__ #define __MAPI_NAMEID_PRIVATE_H__ static struct mapi_nameid_tags mapi_nameid_tags[] = { { PidLidAddressBookProviderArrayType , "ABPArrayType" , 0x8029, NULL, PT_LONG , MNID_ID, PSETID_Address, 0x0 }, { PidLidAddressBookProviderEmailList , "ABPEmailList" , 0x8028, NULL, PT_MV_LONG , MNID_ID, PSETID_Address, 0x0 }, { PidLidAddressCountryCode , "AddressCountryCode" , 0x80dd, NULL, PT_UNICODE , MNID_ID, PSETID_Address, 0x0 }, { PidLidAnniversaryEventEntryId , "AnniversaryEventEID" , 0x804e, NULL, PT_BINARY , MNID_ID, PSETID_Address, 0x0 }, { PidLidAutoLog , "AutoLog" , 0x8025, NULL, PT_BOOLEAN , MNID_ID, PSETID_Address, 0x0 }, { PidLidBirthdayEventEntryId , "BirthdayEventEID" , 0x804d, NULL, PT_BINARY , MNID_ID, PSETID_Address, 0x0 }, { PidLidBirthdayLocal , "ApptBirthdayLocal" , 0x80de, NULL, PT_SYSTIME , MNID_ID, PSETID_Address, 0x0 }, { PidLidBusinessCardCardPicture , "BCCardPicture" , 0x8041, NULL, PT_BINARY , MNID_ID, PSETID_Address, 0x0 }, { PidLidBusinessCardDisplayDefinition , "BCDisplayDefinition" , 0x8040, NULL, PT_BINARY , MNID_ID, PSETID_Address, 0x0 }, { PidLidContactCharacterSet , "ContactCharSet" , 0x8023, NULL, PT_LONG , MNID_ID, PSETID_Address, 0x0 }, { PidLidContactItemData , "ContactItemData" , 0x8007, NULL, PT_MV_LONG , MNID_ID, PSETID_Address, 0x0 }, { PidLidContactUserField1 , "ContactUserField1" , 0x804f, NULL, PT_UNICODE , MNID_ID, PSETID_Address, 0x0 }, { PidLidContactUserField2 , "ContactUserField2" , 0x8050, NULL, PT_UNICODE , MNID_ID, PSETID_Address, 0x0 }, { PidLidContactUserField3 , "ContactUserField3" , 0x8051, NULL, PT_UNICODE , MNID_ID, PSETID_Address, 0x0 }, { PidLidContactUserField4 , "ContactUserField4" , 0x8052, NULL, PT_UNICODE , MNID_ID, PSETID_Address, 0x0 }, { PidLidDepartment , "Department" , 0x8010, NULL, PT_UNICODE , MNID_ID, PSETID_Address, 0x0 }, { PidLidDistributionListChecksum , "DLChecksum" , 0x804c, NULL, PT_LONG , MNID_ID, PSETID_Address, 0x0 }, { PidLidDistributionListMembers , "DLMembers" , 0x8055, NULL, PT_MV_BINARY , MNID_ID, PSETID_Address, 0x0 }, { PidLidDistributionListName , "DLName" , 0x8053, NULL, PT_UNICODE , MNID_ID, PSETID_Address, 0x0 }, { PidLidDistributionListOneOffMembers , "DLOneOffMembers" , 0x8054, NULL, PT_MV_BINARY , MNID_ID, PSETID_Address, 0x0 }, { PidLidDistributionListStream , "DLStream" , 0x8064, NULL, PT_BINARY , MNID_ID, PSETID_Address, 0x0 }, { PidLidEmail1AddressType , "Email1AddrType" , 0x8082, NULL, PT_UNICODE , MNID_ID, PSETID_Address, 0x0 }, { PidLidEmail1DisplayName , "Email1DisplayName" , 0x8080, NULL, PT_UNICODE , MNID_ID, PSETID_Address, 0x0 }, { PidLidEmail1EmailAddress , "Email1EmailAddress" , 0x8083, NULL, PT_UNICODE , MNID_ID, PSETID_Address, 0x0 }, { PidLidEmail1OriginalDisplayName , "Email1OriginalDisplayName" , 0x8084, NULL, PT_UNICODE , MNID_ID, PSETID_Address, 0x0 }, { PidLidEmail1OriginalEntryId , "Email1OriginalEntryID" , 0x8085, NULL, PT_BINARY , MNID_ID, PSETID_Address, 0x0 }, { PidLidEmail1RichTextFormat , "Email1RTF" , 0x8086, NULL, PT_BOOLEAN , MNID_ID, PSETID_Address, 0x0 }, { PidLidEmail2AddressType , "Email2AddrType" , 0x8092, NULL, PT_UNICODE , MNID_ID, PSETID_Address, 0x0 }, { PidLidEmail2DisplayName , "Email2DisplayName" , 0x8090, NULL, PT_UNICODE , MNID_ID, PSETID_Address, 0x0 }, { PidLidEmail2EmailAddress , "Email2EmailAddress" , 0x8093, NULL, PT_UNICODE , MNID_ID, PSETID_Address, 0x0 }, { PidLidEmail2OriginalDisplayName , "Email2OriginalDisplayName" , 0x8094, NULL, PT_UNICODE , MNID_ID, PSETID_Address, 0x0 }, { PidLidEmail2OriginalEntryId , "Email2OriginalEntryID" , 0x8095, NULL, PT_BINARY , MNID_ID, PSETID_Address, 0x0 }, { PidLidEmail2RichTextFormat , "Email1RTF" , 0x8096, NULL, PT_BOOLEAN , MNID_ID, PSETID_Address, 0x0 }, { PidLidEmail3AddressType , "Email3AddrType" , 0x80a2, NULL, PT_UNICODE , MNID_ID, PSETID_Address, 0x0 }, { PidLidEmail3DisplayName , "Email3DisplayName" , 0x80a0, NULL, PT_UNICODE , MNID_ID, PSETID_Address, 0x0 }, { PidLidEmail3EmailAddress , "Email3EmailAddress" , 0x80a3, NULL, PT_UNICODE , MNID_ID, PSETID_Address, 0x0 }, { PidLidEmail3OriginalDisplayName , "Email3OriginalDisplayName" , 0x80a4, NULL, PT_UNICODE , MNID_ID, PSETID_Address, 0x0 }, { PidLidEmail3OriginalEntryId , "Email3OriginalEntryID" , 0x80a5, NULL, PT_BINARY , MNID_ID, PSETID_Address, 0x0 }, { PidLidEmail3RichTextFormat , "Email1RTF" , 0x80a6, NULL, PT_BOOLEAN , MNID_ID, PSETID_Address, 0x0 }, { PidLidEmailList , "EmailList" , 0x8027, NULL, PT_MV_LONG , MNID_ID, PSETID_Address, 0x0 }, { PidLidFax1AddressType , "Fax1AddrType" , 0x80b2, NULL, PT_UNICODE , MNID_ID, PSETID_Address, 0x0 }, { PidLidFax1EmailAddress , "Fax1EmailAddress" , 0x80b3, NULL, PT_UNICODE , MNID_ID, PSETID_Address, 0x0 }, { PidLidFax1OriginalDisplayName , "Fax1OriginalDisplayName" , 0x80b4, NULL, PT_UNICODE , MNID_ID, PSETID_Address, 0x0 }, { PidLidFax1OriginalEntryId , "Fax1OriginalEntryID" , 0x80b5, NULL, PT_BINARY , MNID_ID, PSETID_Address, 0x0 }, { PidLidFax2AddressType , "Fax2AddrType" , 0x80c2, NULL, PT_UNICODE , MNID_ID, PSETID_Address, 0x0 }, { PidLidFax2EmailAddress , "Fax2EmailAddress" , 0x80c3, NULL, PT_UNICODE , MNID_ID, PSETID_Address, 0x0 }, { PidLidFax2OriginalDisplayName , "Fax2OriginalDisplayName" , 0x80c4, NULL, PT_UNICODE , MNID_ID, PSETID_Address, 0x0 }, { PidLidFax2OriginalEntryId , "Fax2OriginalEntryID" , 0x80c5, NULL, PT_BINARY , MNID_ID, PSETID_Address, 0x0 }, { PidLidFax3AddressType , "Fax3AddrType" , 0x80d2, NULL, PT_UNICODE , MNID_ID, PSETID_Address, 0x0 }, { PidLidFax3EmailAddress , "Fax3EmailAddress" , 0x80d3, NULL, PT_UNICODE , MNID_ID, PSETID_Address, 0x0 }, { PidLidFax3OriginalDisplayName , "Fax3OriginalDisplayName" , 0x80d4, NULL, PT_UNICODE , MNID_ID, PSETID_Address, 0x0 }, { PidLidFax3OriginalEntryId , "Fax3OriginalEntryID" , 0x80d5, NULL, PT_BINARY , MNID_ID, PSETID_Address, 0x0 }, { PidLidFileUnder , "FileUnder" , 0x8005, NULL, PT_UNICODE , MNID_ID, PSETID_Address, 0x0 }, { PidLidFileUnderId , "FileUnderId" , 0x8006, NULL, PT_LONG , MNID_ID, PSETID_Address, 0x0 }, { PidLidFileUnderList , "FileUnderList" , 0x8026, NULL, PT_MV_LONG , MNID_ID, PSETID_Address, 0x0 }, { PidLidFreeBusyLocation , "FreeBusyLocation" , 0x80d8, NULL, PT_UNICODE , MNID_ID, PSETID_Address, 0x0 }, { PidLidHasPicture , "HasPicture" , 0x8015, NULL, PT_BOOLEAN , MNID_ID, PSETID_Address, 0x0 }, { PidLidHomeAddress , "HomeAddress" , 0x801a, NULL, PT_UNICODE , MNID_ID, PSETID_Address, 0x0 }, { PidLidHomeAddressCountryCode , "HomeAddressCountryCode" , 0x80da, NULL, PT_UNICODE , MNID_ID, PSETID_Address, 0x0 }, { PidLidHtml , "HTML" , 0x802b, NULL, PT_UNICODE , MNID_ID, PSETID_Address, 0x0 }, { PidLidInstantMessagingAddress , "InstMsg" , 0x8062, NULL, PT_UNICODE , MNID_ID, PSETID_Address, 0x0 }, { PidLidOtherAddress , "OtherAddress" , 0x801c, NULL, PT_UNICODE , MNID_ID, PSETID_Address, 0x0 }, { PidLidOtherAddressCountryCode , "OtherAddressCountryCode" , 0x80dc, NULL, PT_UNICODE , MNID_ID, PSETID_Address, 0x0 }, { PidLidPostalAddressId , "PostalAddressId" , 0x8022, NULL, PT_LONG , MNID_ID, PSETID_Address, 0x0 }, { PidLidReferredBy , "ReferredBy" , 0x800e, NULL, PT_UNICODE , MNID_ID, PSETID_Address, 0x0 }, { PidLidWeddingAnniversaryLocal , "ApptAnniversaryLocal" , 0x80df, NULL, PT_SYSTIME , MNID_ID, PSETID_Address, 0x0 }, { PidLidWorkAddress , "WorkAddress" , 0x801b, NULL, PT_UNICODE , MNID_ID, PSETID_Address, 0x0 }, { PidLidWorkAddressCity , "WorkAddressCity" , 0x8046, NULL, PT_UNICODE , MNID_ID, PSETID_Address, 0x0 }, { PidLidWorkAddressCountry , "WorkAddressCountry" , 0x8049, NULL, PT_UNICODE , MNID_ID, PSETID_Address, 0x0 }, { PidLidWorkAddressCountryCode , "WorkAddressCountryCode" , 0x80db, NULL, PT_UNICODE , MNID_ID, PSETID_Address, 0x0 }, { PidLidWorkAddressPostalCode , "WorkAddressPostalCode" , 0x8048, NULL, PT_UNICODE , MNID_ID, PSETID_Address, 0x0 }, { PidLidWorkAddressPostOfficeBox , "WorkAddressPostOfficeBox" , 0x804a, NULL, PT_UNICODE , MNID_ID, PSETID_Address, 0x0 }, { PidLidWorkAddressState , "WorkAddressState" , 0x8047, NULL, PT_UNICODE , MNID_ID, PSETID_Address, 0x0 }, { PidLidYomiCompanyName , "YomiCompanyName" , 0x802e, NULL, PT_UNICODE , MNID_ID, PSETID_Address, 0x0 }, { PidLidYomiFirstName , "YomiFirstName" , 0x802c, NULL, PT_UNICODE , MNID_ID, PSETID_Address, 0x0 }, { PidLidYomiLastName , "YomiLastName" , 0x802d, NULL, PT_UNICODE , MNID_ID, PSETID_Address, 0x0 }, { PidLidAllAttendeesString , "AllAttendeesString" , 0x8238, NULL, PT_UNICODE , MNID_ID, PSETID_Appointment, 0x0 }, { PidLidAllowExternalCheck , "AllowExternCheck" , 0x8246, NULL, PT_BOOLEAN , MNID_ID, PSETID_Appointment, 0x0 }, { PidLidAppointmentAuxiliaryFlags , "ApptAuxFlags" , 0x8207, NULL, PT_LONG , MNID_ID, PSETID_Appointment, 0x0 }, { PidLidAppointmentColor , "ApptColor" , 0x8214, NULL, PT_LONG , MNID_ID, PSETID_Appointment, 0x0 }, { PidLidAppointmentCounterProposal , "ApptCounterProposal" , 0x8257, NULL, PT_BOOLEAN , MNID_ID, PSETID_Appointment, 0x0 }, { PidLidAppointmentDuration , "ApptDuration" , 0x8213, NULL, PT_LONG , MNID_ID, PSETID_Appointment, 0x0 }, { PidLidAppointmentEndDate , "ApptEndDate" , 0x8211, NULL, PT_SYSTIME , MNID_ID, PSETID_Appointment, 0x0 }, { PidLidAppointmentEndTime , "ApptEndTime" , 0x8210, NULL, PT_SYSTIME , MNID_ID, PSETID_Appointment, 0x0 }, { PidLidAppointmentEndWhole , "ApptEndWhole" , 0x820e, NULL, PT_SYSTIME , MNID_ID, PSETID_Appointment, 0x0 }, { PidLidAppointmentLastSequence , "ApptLastSequence" , 0x8203, NULL, PT_LONG , MNID_ID, PSETID_Appointment, 0x0 }, { PidLidAppointmentNotAllowPropose , "ApptNotAllowPropose" , 0x825a, NULL, PT_BOOLEAN , MNID_ID, PSETID_Appointment, 0x0 }, { PidLidAppointmentProposalNumber , "ApptProposalNum" , 0x8259, NULL, PT_LONG , MNID_ID, PSETID_Appointment, 0x0 }, { PidLidAppointmentProposedDuration , "ApptProposedDuration" , 0x8256, NULL, PT_LONG , MNID_ID, PSETID_Appointment, 0x0 }, { PidLidAppointmentProposedEndWhole , "ApptProposedEndWhole" , 0x8251, NULL, PT_SYSTIME , MNID_ID, PSETID_Appointment, 0x0 }, { PidLidAppointmentProposedStartWhole , "ApptProposedStartWhole" , 0x8250, NULL, PT_SYSTIME , MNID_ID, PSETID_Appointment, 0x0 }, { PidLidAppointmentRecur , "ApptRecur" , 0x8216, NULL, PT_BINARY , MNID_ID, PSETID_Appointment, 0x0 }, { PidLidAppointmentReplyName , "ApptReplyName, http://schemas.microsoft.com/mapi/apptreplyname" , 0x8230, NULL, PT_UNICODE , MNID_ID, PSETID_Appointment, 0x0 }, { PidLidAppointmentReplyTime , "ApptReplyTime" , 0x8220, NULL, PT_SYSTIME , MNID_ID, PSETID_Appointment, 0x0 }, { PidLidAppointmentSequence , "ApptSequence" , 0x8201, NULL, PT_LONG , MNID_ID, PSETID_Appointment, 0x0 }, { PidLidAppointmentSequenceTime , "ApptSeqTime" , 0x8202, NULL, PT_SYSTIME , MNID_ID, PSETID_Appointment, 0x0 }, { PidLidAppointmentStartDate , "ApptStartDate" , 0x8212, NULL, PT_SYSTIME , MNID_ID, PSETID_Appointment, 0x0 }, { PidLidAppointmentStartTime , "ApptStartTime" , 0x820f, NULL, PT_SYSTIME , MNID_ID, PSETID_Appointment, 0x0 }, { PidLidAppointmentStartWhole , "ApptStartWhole" , 0x820d, NULL, PT_SYSTIME , MNID_ID, PSETID_Appointment, 0x0 }, { PidLidAppointmentStateFlags , "ApptStateFlags" , 0x8217, NULL, PT_LONG , MNID_ID, PSETID_Appointment, 0x0 }, { PidLidAppointmentSubType , "ApptSubType" , 0x8215, NULL, PT_BOOLEAN , MNID_ID, PSETID_Appointment, 0x0 }, { PidLidAppointmentTimeZoneDefinitionEndDisplay , "ApptTZDefEndDisplay" , 0x825f, NULL, PT_BINARY , MNID_ID, PSETID_Appointment, 0x0 }, { PidLidAppointmentTimeZoneDefinitionRecur , "ApptTZDefRecur" , 0x8260, NULL, PT_BINARY , MNID_ID, PSETID_Appointment, 0x0 }, { PidLidAppointmentTimeZoneDefinitionStartDisplay , "ApptTZDefStartDisplay" , 0x825e, NULL, PT_BINARY , MNID_ID, PSETID_Appointment, 0x0 }, { PidLidAppointmentUnsendableRecipients , "ApptUnsendableRecips" , 0x825d, NULL, PT_BINARY , MNID_ID, PSETID_Appointment, 0x0 }, { PidLidAppointmentUpdateTime , "ApptUpdateTime" , 0x8226, NULL, PT_SYSTIME , MNID_ID, PSETID_Appointment, 0x0 }, { PidLidAutoFillLocation , "AutoFillLocation" , 0x823a, NULL, PT_BOOLEAN , MNID_ID, PSETID_Appointment, 0x0 }, { PidLidAutoStartCheck , "AutoStartCheck" , 0x8244, NULL, PT_BOOLEAN , MNID_ID, PSETID_Appointment, 0x0 }, { PidLidBusyStatus , "BusyStatus" , 0x8205, NULL, PT_LONG , MNID_ID, PSETID_Appointment, 0x0 }, { PidLidCcAttendeesString , "CCAttendeesString" , 0x823c, NULL, PT_UNICODE , MNID_ID, PSETID_Appointment, 0x0 }, { PidLidChangeHighlight , "ChangeHighlight" , 0x8204, NULL, PT_LONG , MNID_ID, PSETID_Appointment, 0x0 }, { PidLidClipEnd , "ClipEnd" , 0x8236, NULL, PT_SYSTIME , MNID_ID, PSETID_Appointment, 0x0 }, { PidLidClipStart , "ClipStart" , 0x8235, NULL, PT_SYSTIME , MNID_ID, PSETID_Appointment, 0x0 }, { PidLidCollaborateDoc , "CollaborateDoc" , 0x8247, NULL, PT_UNICODE , MNID_ID, PSETID_Appointment, 0x0 }, { PidLidConferencingCheck , "ConfCheck" , 0x8240, NULL, PT_BOOLEAN , MNID_ID, PSETID_Appointment, 0x0 }, { PidLidConferencingType , "ConfType" , 0x8241, NULL, PT_LONG , MNID_ID, PSETID_Appointment, 0x0 }, { PidLidDirectory , "Directory" , 0x8242, NULL, PT_UNICODE , MNID_ID, PSETID_Appointment, 0x0 }, { PidLidExceptionReplaceTime , "ExceptionReplaceTime" , 0x8228, NULL, PT_SYSTIME , MNID_ID, PSETID_Appointment, 0x0 }, { PidLidFExceptionalAttendees , "FExceptionalAttendees" , 0x822b, NULL, PT_BOOLEAN , MNID_ID, PSETID_Appointment, 0x0 }, { PidLidFExceptionalBody , "FExceptionalBody" , 0x8206, NULL, PT_BOOLEAN , MNID_ID, PSETID_Appointment, 0x0 }, { PidLidFInvited , "FInvited" , 0x8229, NULL, PT_BOOLEAN , MNID_ID, PSETID_Appointment, 0x0 }, { PidLidForwardInstance , "FwrdInstance" , 0x820a, NULL, PT_BOOLEAN , MNID_ID, PSETID_Appointment, 0x0 }, { PidLidForwardNotificationRecipients , "ForwardNotificationRecipients" , 0x8261, NULL, PT_BINARY , MNID_ID, PSETID_Appointment, 0x0 }, { PidLidFOthersAppointment , "FOthersAppt, http://schemas.microsoft.com/mapi/fothersappt" , 0x822f, NULL, PT_BOOLEAN , MNID_ID, PSETID_Appointment, 0x0 }, { PidLidInboundICalStream , "InboundICalStream, dispidInboundICalStream" , 0x827a, NULL, PT_BINARY , MNID_ID, PSETID_Appointment, 0x0 }, { PidLidIntendedBusyStatus , "IntendedBusyStatus" , 0x8224, NULL, PT_LONG , MNID_ID, PSETID_Appointment, 0x0 }, { PidLidLinkedTaskItems , "LinkedTaskItems" , 0x820c, NULL, PT_MV_BINARY , MNID_ID, PSETID_Appointment, 0x0 }, { PidLidLocation , "Location" , 0x8208, NULL, PT_UNICODE , MNID_ID, PSETID_Appointment, 0x0 }, { PidLidMeetingWorkspaceUrl , "MWSURL" , 0x8209, NULL, PT_UNICODE , MNID_ID, PSETID_Appointment, 0x0 }, { PidLidNetShowUrl , "NetShowURL" , 0x8248, NULL, PT_UNICODE , MNID_ID, PSETID_Appointment, 0x0 }, { PidLidOnlinePassword , "OnlinePassword" , 0x8249, NULL, PT_UNICODE , MNID_ID, PSETID_Appointment, 0x0 }, { PidLidOrganizerAlias , "OrgAlias" , 0x8243, NULL, PT_UNICODE , MNID_ID, PSETID_Appointment, 0x0 }, { PidLidOriginalStoreEntryId , "OrigStoreEid, http://schemas.microsoft.com/mapi/origstoreeid" , 0x8237, NULL, PT_BINARY , MNID_ID, PSETID_Appointment, 0x0 }, { PidLidOwnerName , "OwnerName" , 0x822e, NULL, PT_UNICODE , MNID_ID, PSETID_Appointment, 0x0 }, { PidLidRecurrencePattern , "RecurPattern" , 0x8232, NULL, PT_UNICODE , MNID_ID, PSETID_Appointment, 0x0 }, { PidLidRecurrenceType , "RecurType" , 0x8231, NULL, PT_LONG , MNID_ID, PSETID_Appointment, 0x0 }, { PidLidRecurring , "Recurring" , 0x8223, NULL, PT_BOOLEAN , MNID_ID, PSETID_Appointment, 0x0 }, { PidLidResponseStatus , "ResponseStatus" , 0x8218, NULL, PT_LONG , MNID_ID, PSETID_Appointment, 0x0 }, { PidLidSingleBodyICal , "IsSingleBodyICal, dispidIsSingleBodyICal" , 0x827b, NULL, PT_BOOLEAN , MNID_ID, PSETID_Appointment, 0x0 }, { PidLidTimeZoneDescription , "TimeZoneDesc" , 0x8234, NULL, PT_UNICODE , MNID_ID, PSETID_Appointment, 0x0 }, { PidLidTimeZoneStruct , "TimeZoneStruct" , 0x8233, NULL, PT_BINARY , MNID_ID, PSETID_Appointment, 0x0 }, { PidLidToAttendeesString , "ToAttendeesString" , 0x823b, NULL, PT_UNICODE , MNID_ID, PSETID_Appointment, 0x0 }, { PidLidClientIntent , "ClientIntent" , 0x0015, NULL, PT_LONG , MNID_ID, PSETID_CalendarAssistant, 0x0 }, { PidLidServerProcessed , "ExchangeProcessed" , 0x85cc, NULL, PT_BOOLEAN , MNID_ID, PSETID_CalendarAssistant, 0x0 }, { PidLidServerProcessingActions , "ExchangeProcessingAction" , 0x85cd, NULL, PT_LONG , MNID_ID, PSETID_CalendarAssistant, 0x0 }, { PidLidAgingDontAgeMe , "AgingDontAgeMe" , 0x850e, NULL, PT_BOOLEAN , MNID_ID, PSETID_Common, 0x0 }, { PidLidAutoProcessState , "SniffState" , 0x851a, NULL, PT_LONG , MNID_ID, PSETID_Common, 0x0 }, { PidLidBilling , "Billing" , 0x8535, NULL, PT_UNICODE , MNID_ID, PSETID_Common, 0x0 }, { PidLidClassification , "Classification" , 0x85b6, NULL, PT_UNICODE , MNID_ID, PSETID_Common, 0x0 }, { PidLidClassificationDescription , "ClassDesc" , 0x85b7, NULL, PT_UNICODE , MNID_ID, PSETID_Common, 0x0 }, { PidLidClassificationGuid , "ClassGuid" , 0x85b8, NULL, PT_UNICODE , MNID_ID, PSETID_Common, 0x0 }, { PidLidClassificationKeep , "ClassKeep" , 0x85ba, NULL, PT_BOOLEAN , MNID_ID, PSETID_Common, 0x0 }, { PidLidClassified , "Classified" , 0x85b5, NULL, PT_BOOLEAN , MNID_ID, PSETID_Common, 0x0 }, { PidLidCommonEnd , "CommonEnd" , 0x8517, NULL, PT_SYSTIME , MNID_ID, PSETID_Common, 0x0 }, { PidLidCommonStart , "CommonStart" , 0x8516, NULL, PT_SYSTIME , MNID_ID, PSETID_Common, 0x0 }, { PidLidCompanies , "Companies, http://schemas.microsoft.com/exchange/companies" , 0x8539, NULL, PT_MV_UNICODE , MNID_ID, PSETID_Common, 0x0 }, { PidLidContactLinkEntry , "ContactLinkEntry" , 0x8585, NULL, PT_BINARY , MNID_ID, PSETID_Common, 0x0 }, { PidLidContactLinkName , "ContactLinkName" , 0x8586, NULL, PT_UNICODE , MNID_ID, PSETID_Common, 0x0 }, { PidLidContactLinkSearchKey , "ContactLinkSearchKey" , 0x8584, NULL, PT_BINARY , MNID_ID, PSETID_Common, 0x0 }, { PidLidContacts , "Contacts" , 0x853a, NULL, PT_MV_UNICODE , MNID_ID, PSETID_Common, 0x0 }, { PidLidConversationActionLastAppliedTime , "ConvActionLastAppliedTime" , 0x85ca, NULL, PT_SYSTIME , MNID_ID, PSETID_Common, 0x0 }, { PidLidConversationActionMaxDeliveryTime , "ConvActionMaxDeliveryTime" , 0x85c8, NULL, PT_SYSTIME , MNID_ID, PSETID_Common, 0x0 }, { PidLidConversationActionMoveFolderEid , "ConvActionMoveFolderEid" , 0x85c6, NULL, PT_BINARY , MNID_ID, PSETID_Common, 0x0 }, { PidLidConversationActionMoveStoreEid , "ConvActionMoveStoreEid" , 0x85c7, NULL, PT_BINARY , MNID_ID, PSETID_Common, 0x0 }, { PidLidConversationActionVersion , "ConvActionVersion" , 0x85cb, NULL, PT_LONG , MNID_ID, PSETID_Common, 0x0 }, { PidLidConversationProcessed , "ConvExLegacyProcessedRand" , 0x85c9, NULL, PT_LONG , MNID_ID, PSETID_Common, 0x0 }, { PidLidCurrentVersion , "CurrentVersion" , 0x8552, NULL, PT_LONG , MNID_ID, PSETID_Common, 0x0 }, { PidLidCurrentVersionName , "CurrentVersionName" , 0x8554, NULL, PT_UNICODE , MNID_ID, PSETID_Common, 0x0 }, { PidLidDayOfMonth , "NULL" , 0x1000, NULL, PT_LONG , MNID_ID, PSETID_Common, 0x0 }, { PidLidFlagRequest , "Request" , 0x8530, NULL, PT_UNICODE , MNID_ID, PSETID_Common, 0x0 }, { PidLidFlagString , "FlagStringEnum" , 0x85c0, NULL, PT_LONG , MNID_ID, PSETID_Common, 0x0 }, { PidLidICalendarDayOfWeekMask , "http://schemas.microsoft.com/mapi/dayofweekmask" , 0x1001, NULL, PT_LONG , MNID_ID, PSETID_Common, 0x0 }, { PidLidInfoPathFormName , "NULL" , 0x85b1, NULL, PT_UNICODE , MNID_ID, PSETID_Common, 0x0 }, { PidLidInternetAccountName , "InetAcctName" , 0x8580, NULL, PT_UNICODE , MNID_ID, PSETID_Common, 0x0 }, { PidLidInternetAccountStamp , "InetAcctStamp" , 0x8581, NULL, PT_UNICODE , MNID_ID, PSETID_Common, 0x0 }, { PidLidMonthOfYear , "NULL" , 0x1006, NULL, PT_LONG , MNID_ID, PSETID_Common, 0x0 }, { PidLidNoEndDateFlag , "http://schemas.microsoft.com/mapi/fnoenddate" , 0x100b, NULL, PT_BOOLEAN , MNID_ID, PSETID_Common, 0x0 }, { PidLidNonSendableBcc , "NonSendableBCC" , 0x8538, NULL, PT_UNICODE , MNID_ID, PSETID_Common, 0x0 }, { PidLidNonSendableCc , "NonSendableCC" , 0x8537, NULL, PT_UNICODE , MNID_ID, PSETID_Common, 0x0 }, { PidLidNonSendableTo , "NonSendableTo" , 0x8536, NULL, PT_UNICODE , MNID_ID, PSETID_Common, 0x0 }, { PidLidNonSendBccTrackStatus , "NonSendBccTrackStatus" , 0x8545, NULL, PT_MV_LONG , MNID_ID, PSETID_Common, 0x0 }, { PidLidNonSendCcTrackStatus , "NonSendCcTrackStatus" , 0x8544, NULL, PT_MV_LONG , MNID_ID, PSETID_Common, 0x0 }, { PidLidNonSendToTrackStatus , "NonSendToTrackStatus" , 0x8543, NULL, PT_MV_LONG , MNID_ID, PSETID_Common, 0x0 }, { PidLidOccurrences , "NULL" , 0x1005, NULL, PT_LONG , MNID_ID, PSETID_Common, 0x0 }, { PidLidPrivate , "Private" , 0x8506, NULL, PT_BOOLEAN , MNID_ID, PSETID_Common, 0x0 }, { PidLidPromptSendUpdate , "PromptSendUpdate" , 0x8045, NULL, PT_BOOLEAN , MNID_ID, PSETID_Common, 0x0 }, { PidLidRecurrenceDuration , "NULL" , 0x100d, NULL, PT_LONG , MNID_ID, PSETID_Common, 0x0 }, { PidLidReferenceEntryId , "ReferenceEID" , 0x85bd, NULL, PT_BINARY , MNID_ID, PSETID_Common, 0x0 }, { PidLidReminderDelta , "ReminderDelta, http://schemas.microsoft.com/mapi/reminderdelta" , 0x8501, NULL, PT_LONG , MNID_ID, PSETID_Common, 0x0 }, { PidLidReminderFileParameter , "ReminderFileParam" , 0x851f, NULL, PT_UNICODE , MNID_ID, PSETID_Common, 0x0 }, { PidLidReminderOverride , "ReminderOverride" , 0x851c, NULL, PT_BOOLEAN , MNID_ID, PSETID_Common, 0x0 }, { PidLidReminderPlaySound , "ReminderPlaySound" , 0x851e, NULL, PT_BOOLEAN , MNID_ID, PSETID_Common, 0x0 }, { PidLidReminderSet , "ReminderSet" , 0x8503, NULL, PT_BOOLEAN , MNID_ID, PSETID_Common, 0x0 }, { PidLidReminderSignalTime , "ReminderNextTime" , 0x8560, NULL, PT_SYSTIME , MNID_ID, PSETID_Common, 0x0 }, { PidLidReminderTime , "ReminderTime" , 0x8502, NULL, PT_SYSTIME , MNID_ID, PSETID_Common, 0x0 }, { PidLidReminderTimeDate , "ReminderTimeDate" , 0x8505, NULL, PT_SYSTIME , MNID_ID, PSETID_Common, 0x0 }, { PidLidReminderTimeTime , "ReminderTimeTime" , 0x8504, NULL, PT_SYSTIME , MNID_ID, PSETID_Common, 0x0 }, { PidLidReminderType , "ReminderType, http://schemas.microsoft.com/mapi/remindertype" , 0x851d, NULL, PT_LONG , MNID_ID, PSETID_Common, 0x0 }, { PidLidRemoteStatus , "RemoteStatus" , 0x8511, NULL, PT_LONG , MNID_ID, PSETID_Common, 0x0 }, { PidLidSideEffects , "SideEffects" , 0x8510, NULL, PT_LONG , MNID_ID, PSETID_Common, 0x0 }, { PidLidSmartNoAttach , "SmartNoAttach" , 0x8514, NULL, PT_BOOLEAN , MNID_ID, PSETID_Common, 0x0 }, { PidLidSpamOriginalFolder , "SpamOriginalFolder" , 0x859c, NULL, PT_BINARY , MNID_ID, PSETID_Common, 0x0 }, { PidLidTaskGlobalId , "TaskGlobalObjId" , 0x8519, NULL, PT_BINARY , MNID_ID, PSETID_Common, 0x0 }, { PidLidTaskMode , "TaskMode" , 0x8518, NULL, PT_LONG , MNID_ID, PSETID_Common, 0x0 }, { PidLidToDoOrdinalDate , "ToDoOrdinalDate" , 0x85a0, NULL, PT_SYSTIME , MNID_ID, PSETID_Common, 0x0 }, { PidLidToDoSubOrdinal , "ToDoSubOrdinal" , 0x85a1, NULL, PT_UNICODE , MNID_ID, PSETID_Common, 0x0 }, { PidLidToDoTitle , "ToDoTitle" , 0x85a4, NULL, PT_UNICODE , MNID_ID, PSETID_Common, 0x0 }, { PidLidUseTnef , "UseTNEF" , 0x8582, NULL, PT_BOOLEAN , MNID_ID, PSETID_Common, 0x0 }, { PidLidValidFlagStringProof , "ValidFlagStringProof" , 0x85bf, NULL, PT_SYSTIME , MNID_ID, PSETID_Common, 0x0 }, { PidLidVerbResponse , "VerbResponse" , 0x8524, NULL, PT_UNICODE , MNID_ID, PSETID_Common, 0x0 }, { PidLidVerbStream , "VerbStream" , 0x8520, NULL, PT_BINARY , MNID_ID, PSETID_Common, 0x0 }, { PidLidLogDocumentPosted , "LogDocPosted" , 0x8711, NULL, PT_BOOLEAN , MNID_ID, PSETID_Log, 0x0 }, { PidLidLogDocumentPrinted , "LogDocPrinted" , 0x870e, NULL, PT_BOOLEAN , MNID_ID, PSETID_Log, 0x0 }, { PidLidLogDocumentRouted , "LogDocRouted" , 0x8710, NULL, PT_BOOLEAN , MNID_ID, PSETID_Log, 0x0 }, { PidLidLogDocumentSaved , "LogDocSaved" , 0x870f, NULL, PT_BOOLEAN , MNID_ID, PSETID_Log, 0x0 }, { PidLidLogDuration , "LogDuration" , 0x8707, NULL, PT_LONG , MNID_ID, PSETID_Log, 0x0 }, { PidLidLogEnd , "LogEnd" , 0x8708, NULL, PT_SYSTIME , MNID_ID, PSETID_Log, 0x0 }, { PidLidLogFlags , "LogFlags" , 0x870c, NULL, PT_LONG , MNID_ID, PSETID_Log, 0x0 }, { PidLidLogStart , "LogStart" , 0x8706, NULL, PT_SYSTIME , MNID_ID, PSETID_Log, 0x0 }, { PidLidLogType , "LogType" , 0x8700, NULL, PT_UNICODE , MNID_ID, PSETID_Log, 0x0 }, { PidLidLogTypeDesc , "LogTypeDesc" , 0x8712, NULL, PT_UNICODE , MNID_ID, PSETID_Log, 0x0 }, { PidLidAppointmentMessageClass , "ApptMessageClass" , 0x0024, NULL, PT_UNICODE , MNID_ID, PSETID_Meeting, 0x0 }, { PidLidAttendeeCriticalChange , "LID_ATTENDEE_CRITICAL_CHANGE" , 0x0001, NULL, PT_SYSTIME , MNID_ID, PSETID_Meeting, 0x0 }, { PidLidCalendarType , "LID_CALENDAR_TYPE" , 0x001c, NULL, PT_LONG , MNID_ID, PSETID_Meeting, 0x0 }, { PidLidCleanGlobalObjectId , "CleanGlobalObjId" , 0x0023, NULL, PT_BINARY , MNID_ID, PSETID_Meeting, 0x0 }, { PidLidDayInterval , "LID_DAY_INTERVAL" , 0x0011, NULL, PT_SHORT , MNID_ID, PSETID_Meeting, 0x0 }, { PidLidDelegateMail , "LID_DELEGATE_MAIL" , 0x0009, NULL, PT_BOOLEAN , MNID_ID, PSETID_Meeting, 0x0 }, { PidLidEndRecurrenceDate , "LID_END_RECUR_DATE" , 0x000f, NULL, PT_LONG , MNID_ID, PSETID_Meeting, 0x0 }, { PidLidEndRecurrenceTime , "LID_END_RECUR_TIME" , 0x0010, NULL, PT_LONG , MNID_ID, PSETID_Meeting, 0x0 }, { PidLidGlobalObjectId , "LID_GLOBAL_OBJID" , 0x0003, NULL, PT_BINARY , MNID_ID, PSETID_Meeting, 0x0 }, { PidLidIsException , "LID_IS_EXCEPTION" , 0x000a, NULL, PT_BOOLEAN , MNID_ID, PSETID_Meeting, 0x0 }, { PidLidIsRecurring , "LID_IS_RECURRING" , 0x0005, NULL, PT_BOOLEAN , MNID_ID, PSETID_Meeting, 0x0 }, { PidLidIsSilent , "LID_IS_SILENT" , 0x0004, NULL, PT_BOOLEAN , MNID_ID, PSETID_Meeting, 0x0 }, { PidLidMeetingType , "MeetingType" , 0x0026, NULL, PT_LONG , MNID_ID, PSETID_Meeting, 0x0 }, { PidLidMonthInterval , "LID_MONTH_INTERVAL" , 0x0013, NULL, PT_SHORT , MNID_ID, PSETID_Meeting, 0x0 }, { PidLidMonthOfYearMask , "LID_MOY_MASK" , 0x0017, NULL, PT_LONG , MNID_ID, PSETID_Meeting, 0x0 }, { PidLidOldLocation , "OldLocation" , 0x0028, NULL, PT_UNICODE , MNID_ID, PSETID_Meeting, 0x0 }, { PidLidOldRecurrenceType , "LID_RECUR_TYPE" , 0x0018, NULL, PT_SHORT , MNID_ID, PSETID_Meeting, 0x0 }, { PidLidOldWhenEndWhole , "OldWhenEndWhole" , 0x002a, NULL, PT_SYSTIME , MNID_ID, PSETID_Meeting, 0x0 }, { PidLidOldWhenStartWhole , "OldWhenStartWhole" , 0x0029, NULL, PT_SYSTIME , MNID_ID, PSETID_Meeting, 0x0 }, { PidLidOptionalAttendees , "LID_OPTIONAL_ATTENDEES" , 0x0007, NULL, PT_UNICODE , MNID_ID, PSETID_Meeting, 0x0 }, { PidLidOwnerCriticalChange , "LID_OWNER_CRITICAL_CHANGE" , 0x001a, NULL, PT_SYSTIME , MNID_ID, PSETID_Meeting, 0x0 }, { PidLidRequiredAttendees , "LID_REQUIRED_ATTENDEES" , 0x0006, NULL, PT_UNICODE , MNID_ID, PSETID_Meeting, 0x0 }, { PidLidResourceAttendees , "LID_RESOURCE_ATTENDEES" , 0x0008, NULL, PT_UNICODE , MNID_ID, PSETID_Meeting, 0x0 }, { PidLidStartRecurrenceDate , "LID_START_RECUR_DATE" , 0x000d, NULL, PT_LONG , MNID_ID, PSETID_Meeting, 0x0 }, { PidLidStartRecurrenceTime , "LID_START_RECUR_TIME" , 0x000e, NULL, PT_LONG , MNID_ID, PSETID_Meeting, 0x0 }, { PidLidTimeZone , "LID_TIME_ZONE" , 0x000c, NULL, PT_LONG , MNID_ID, PSETID_Meeting, 0x0 }, { PidLidWeekInterval , "LID_WEEK_INTERVAL" , 0x0012, NULL, PT_SHORT , MNID_ID, PSETID_Meeting, 0x0 }, { PidLidWhere , "LID_WHERE" , 0x0002, NULL, PT_UNICODE , MNID_ID, PSETID_Meeting, 0x0 }, { PidLidYearInterval , "LID_YEAR_INTERVAL" , 0x0014, NULL, PT_SHORT , MNID_ID, PSETID_Meeting, 0x0 }, { PidLidNoteColor , "NoteColor" , 0x8b00, NULL, PT_LONG , MNID_ID, PSETID_Note, 0x0 }, { PidLidNoteHeight , "NoteHeight" , 0x8b03, NULL, PT_LONG , MNID_ID, PSETID_Note, 0x0 }, { PidLidNoteWidth , "NoteWidth" , 0x8b02, NULL, PT_LONG , MNID_ID, PSETID_Note, 0x0 }, { PidLidNoteX , "NoteX" , 0x8b04, NULL, PT_LONG , MNID_ID, PSETID_Note, 0x0 }, { PidLidNoteY , "NoteY" , 0x8b05, NULL, PT_LONG , MNID_ID, PSETID_Note, 0x0 }, { PidLidPostRssChannel , "PostRssChannel" , 0x8904, NULL, PT_UNICODE , MNID_ID, PSETID_PostRss, 0x0 }, { PidLidPostRssChannelLink , "PostRssChannelLink" , 0x8900, NULL, PT_UNICODE , MNID_ID, PSETID_PostRss, 0x0 }, { PidLidPostRssItemGuid , "PostRssItemGuid" , 0x8903, NULL, PT_UNICODE , MNID_ID, PSETID_PostRss, 0x0 }, { PidLidPostRssItemHash , "PostRssItemHash" , 0x8902, NULL, PT_LONG , MNID_ID, PSETID_PostRss, 0x0 }, { PidLidPostRssItemLink , "PostRssItemLink" , 0x8901, NULL, PT_UNICODE , MNID_ID, PSETID_PostRss, 0x0 }, { PidLidPostRssItemXml , "PostRssItemXml" , 0x8905, NULL, PT_UNICODE , MNID_ID, PSETID_PostRss, 0x0 }, { PidLidPostRssSubscription , "PostRssSubscription" , 0x8906, NULL, PT_UNICODE , MNID_ID, PSETID_PostRss, 0x0 }, { PidLidSharingAnonymity , "SharingAnonymity" , 0x8a19, NULL, PT_LONG , MNID_ID, PSETID_Sharing, 0x0 }, { PidLidSharingBindingEntryId , "SharingBindingEid" , 0x8a2d, NULL, PT_BINARY , MNID_ID, PSETID_Sharing, 0x0 }, { PidLidSharingBrowseUrl , "SharingBrowseUrl" , 0x8a51, NULL, PT_UNICODE , MNID_ID, PSETID_Sharing, 0x0 }, { PidLidSharingCapabilities , "SharingCaps" , 0x8a17, NULL, PT_LONG , MNID_ID, PSETID_Sharing, 0x0 }, { PidLidSharingConfigurationUrl , "SharingConfigUrl" , 0x8a24, NULL, PT_UNICODE , MNID_ID, PSETID_Sharing, 0x0 }, { PidLidSharingDataRangeEnd , "SharingDataRangeEnd" , 0x8a45, NULL, PT_SYSTIME , MNID_ID, PSETID_Sharing, 0x0 }, { PidLidSharingDataRangeStart , "SharingDataRangeStart" , 0x8a44, NULL, PT_SYSTIME , MNID_ID, PSETID_Sharing, 0x0 }, { PidLidSharingDetail , "SharingDetail" , 0x8a2b, NULL, PT_LONG , MNID_ID, PSETID_Sharing, 0x0 }, { PidLidSharingExtensionXml , "SharingExtXml" , 0x8a21, NULL, PT_UNICODE , MNID_ID, PSETID_Sharing, 0x0 }, { PidLidSharingFilter , "SharingFilter" , 0x8a13, NULL, PT_BINARY , MNID_ID, PSETID_Sharing, 0x0 }, { PidLidSharingFlags , "SharingFlags" , 0x8a0a, NULL, PT_LONG , MNID_ID, PSETID_Sharing, 0x0 }, { PidLidSharingFlavor , "SharingFlavor" , 0x8a18, NULL, PT_LONG , MNID_ID, PSETID_Sharing, 0x0 }, { PidLidSharingFolderEntryId , "SharingFolderEid" , 0x8a15, NULL, PT_BINARY , MNID_ID, PSETID_Sharing, 0x0 }, { PidLidSharingIndexEntryId , "SharingIndexEid" , 0x8a2e, NULL, PT_BINARY , MNID_ID, PSETID_Sharing, 0x0 }, { PidLidSharingInitiatorEntryId , "SharingInitiatorEid" , 0x8a09, NULL, PT_BINARY , MNID_ID, PSETID_Sharing, 0x0 }, { PidLidSharingInitiatorName , "SharingInitiatorName" , 0x8a07, NULL, PT_UNICODE , MNID_ID, PSETID_Sharing, 0x0 }, { PidLidSharingInitiatorSmtp , "SharingInitiatorSmtp" , 0x8a08, NULL, PT_UNICODE , MNID_ID, PSETID_Sharing, 0x0 }, { PidLidSharingInstanceGuid , "SharingInstanceGuid" , 0x8a1c, NULL, PT_BINARY , MNID_ID, PSETID_Sharing, 0x0 }, { PidLidSharingLastAutoSyncTime , "SharingLastAutoSync" , 0x8a55, NULL, PT_SYSTIME , MNID_ID, PSETID_Sharing, 0x0 }, { PidLidSharingLastSyncTime , "SharingLastSync" , 0x8a1f, NULL, PT_SYSTIME , MNID_ID, PSETID_Sharing, 0x0 }, { PidLidSharingLocalComment , "SharingLocalComment" , 0x8a4d, NULL, PT_UNICODE , MNID_ID, PSETID_Sharing, 0x0 }, { PidLidSharingLocalLastModificationTime , "SharingLocalLastMod" , 0x8a23, NULL, PT_SYSTIME , MNID_ID, PSETID_Sharing, 0x0 }, { PidLidSharingLocalName , "SharingLocalName" , 0x8a0f, NULL, PT_UNICODE , MNID_ID, PSETID_Sharing, 0x0 }, { PidLidSharingLocalPath , "SharingLocalPath" , 0x8a0e, NULL, PT_UNICODE , MNID_ID, PSETID_Sharing, 0x0 }, { PidLidSharingLocalStoreUid , "SharingLocalStoreUid" , 0x8a49, NULL, PT_UNICODE , MNID_ID, PSETID_Sharing, 0x0 }, { PidLidSharingLocalType , "SharingLocalType" , 0x8a14, NULL, PT_UNICODE , MNID_ID, PSETID_Sharing, 0x0 }, { PidLidSharingLocalUid , "SharingLocalUid" , 0x8a10, NULL, PT_UNICODE , MNID_ID, PSETID_Sharing, 0x0 }, { PidLidSharingOriginalMessageEntryId , "SharingOriginalMessageEid" , 0x8a29, NULL, PT_BINARY , MNID_ID, PSETID_Sharing, 0x0 }, { PidLidSharingParentBindingEntryId , "SharingParentBindingEid" , 0x8a5c, NULL, PT_BINARY , MNID_ID, PSETID_Sharing, 0x0 }, { PidLidSharingParticipants , "SharingParticipants" , 0x8a1e, NULL, PT_UNICODE , MNID_ID, PSETID_Sharing, 0x0 }, { PidLidSharingPermissions , "SharingPermissions" , 0x8a1b, NULL, PT_LONG , MNID_ID, PSETID_Sharing, 0x0 }, { PidLidSharingProviderExtension , "SharingProviderExtension" , 0x8a0b, NULL, PT_UNICODE , MNID_ID, PSETID_Sharing, 0x0 }, { PidLidSharingProviderGuid , "SharingProviderGuid" , 0x8a01, NULL, PT_BINARY , MNID_ID, PSETID_Sharing, 0x0 }, { PidLidSharingProviderName , "SharingProviderName" , 0x8a02, NULL, PT_UNICODE , MNID_ID, PSETID_Sharing, 0x0 }, { PidLidSharingProviderUrl , "SharingProviderUrl" , 0x8a03, NULL, PT_UNICODE , MNID_ID, PSETID_Sharing, 0x0 }, { PidLidSharingRangeEnd , "SharingRangeEnd" , 0x8a47, NULL, PT_LONG , MNID_ID, PSETID_Sharing, 0x0 }, { PidLidSharingRangeStart , "SharingRangeStart" , 0x8a46, NULL, PT_LONG , MNID_ID, PSETID_Sharing, 0x0 }, { PidLidSharingReciprocation , "SharingReciprocation" , 0x8a1a, NULL, PT_LONG , MNID_ID, PSETID_Sharing, 0x0 }, { PidLidSharingRemoteByteSize , "SharingRemoteByteSize" , 0x8a4b, NULL, PT_LONG , MNID_ID, PSETID_Sharing, 0x0 }, { PidLidSharingRemoteComment , "SharingRemoteComment" , 0x8a2f, NULL, PT_UNICODE , MNID_ID, PSETID_Sharing, 0x0 }, { PidLidSharingRemoteCrc , "SharingRemoteCrc" , 0x8a4c, NULL, PT_LONG , MNID_ID, PSETID_Sharing, 0x0 }, { PidLidSharingRemoteLastModificationTime , "SharingRemoteLastMod" , 0x8a22, NULL, PT_SYSTIME , MNID_ID, PSETID_Sharing, 0x0 }, { PidLidSharingRemoteMessageCount , "SharingRemoteMsgCount" , 0x8a4f, NULL, PT_LONG , MNID_ID, PSETID_Sharing, 0x0 }, { PidLidSharingRemoteName , "SharingRemoteName" , 0x8a05, NULL, PT_UNICODE , MNID_ID, PSETID_Sharing, 0x0 }, { PidLidSharingRemotePass , "SharingRemotePass" , 0x8a0d, NULL, PT_UNICODE , MNID_ID, PSETID_Sharing, 0x0 }, { PidLidSharingRemotePath , "SharingRemotePath" , 0x8a04, NULL, PT_UNICODE , MNID_ID, PSETID_Sharing, 0x0 }, { PidLidSharingRemoteStoreUid , "SharingRemoteStoreUid" , 0x8a48, NULL, PT_UNICODE , MNID_ID, PSETID_Sharing, 0x0 }, { PidLidSharingRemoteType , "SharingRemoteType" , 0x8a1d, NULL, PT_UNICODE , MNID_ID, PSETID_Sharing, 0x0 }, { PidLidSharingRemoteUid , "SharingRemoteUid" , 0x8a06, NULL, PT_UNICODE , MNID_ID, PSETID_Sharing, 0x0 }, { PidLidSharingRemoteUser , "SharingRemoteUser" , 0x8a0c, NULL, PT_UNICODE , MNID_ID, PSETID_Sharing, 0x0 }, { PidLidSharingRemoteVersion , "SharingRemoteVersion" , 0x8a5b, NULL, PT_UNICODE , MNID_ID, PSETID_Sharing, 0x0 }, { PidLidSharingResponseTime , "SharingResponseTime" , 0x8a28, NULL, PT_SYSTIME , MNID_ID, PSETID_Sharing, 0x0 }, { PidLidSharingResponseType , "SharingResponseType" , 0x8a27, NULL, PT_LONG , MNID_ID, PSETID_Sharing, 0x0 }, { PidLidSharingRoamLog , "SharingRoamLog" , 0x8a4e, NULL, PT_LONG , MNID_ID, PSETID_Sharing, 0x0 }, { PidLidSharingStart , "SharingStart" , 0x8a25, NULL, PT_SYSTIME , MNID_ID, PSETID_Sharing, 0x0 }, { PidLidSharingStatus , "SharingStatus" , 0x8a00, NULL, PT_LONG , MNID_ID, PSETID_Sharing, 0x0 }, { PidLidSharingStop , "SharingStop" , 0x8a26, NULL, PT_SYSTIME , MNID_ID, PSETID_Sharing, 0x0 }, { PidLidSharingSyncFlags , "SharingSyncFlags" , 0x8a60, NULL, PT_LONG , MNID_ID, PSETID_Sharing, 0x0 }, { PidLidSharingSyncInterval , "SharingSyncInterval" , 0x8a2a, NULL, PT_LONG , MNID_ID, PSETID_Sharing, 0x0 }, { PidLidSharingTimeToLive , "SharingTimeToLive" , 0x8a2c, NULL, PT_LONG , MNID_ID, PSETID_Sharing, 0x0 }, { PidLidSharingTimeToLiveAuto , "SharingTimeToLiveAuto" , 0x8a56, NULL, PT_LONG , MNID_ID, PSETID_Sharing, 0x0 }, { PidLidSharingWorkingHoursDays , "SharingWorkingHoursDays" , 0x8a42, NULL, PT_LONG , MNID_ID, PSETID_Sharing, 0x0 }, { PidLidSharingWorkingHoursEnd , "SharingWorkingHoursEnd" , 0x8a41, NULL, PT_SYSTIME , MNID_ID, PSETID_Sharing, 0x0 }, { PidLidSharingWorkingHoursStart , "SharingWorkingHoursStart" , 0x8a40, NULL, PT_SYSTIME , MNID_ID, PSETID_Sharing, 0x0 }, { PidLidSharingWorkingHoursTimeZone , "SharingWorkingHoursTZ" , 0x8a43, NULL, PT_BINARY , MNID_ID, PSETID_Sharing, 0x0 }, { PidLidPercentComplete , "PercentComplete" , 0x8102, NULL, PT_DOUBLE , MNID_ID, PSETID_Task, 0x0 }, { PidLidTaskAcceptanceState , "TaskDelegValue" , 0x812a, NULL, PT_LONG , MNID_ID, PSETID_Task, 0x0 }, { PidLidTaskAccepted , "TaskAccepted" , 0x8108, NULL, PT_BOOLEAN , MNID_ID, PSETID_Task, 0x0 }, { PidLidTaskActualEffort , "TaskActualEffort" , 0x8110, NULL, PT_LONG , MNID_ID, PSETID_Task, 0x0 }, { PidLidTaskAssigner , "TaskDelegator" , 0x8121, NULL, PT_UNICODE , MNID_ID, PSETID_Task, 0x0 }, { PidLidTaskAssigners , "TaskMyDelegators" , 0x8117, NULL, PT_BINARY , MNID_ID, PSETID_Task, 0x0 }, { PidLidTaskComplete , "TaskComplete" , 0x811c, NULL, PT_BOOLEAN , MNID_ID, PSETID_Task, 0x0 }, { PidLidTaskCustomFlags , "TaskActualEffort" , 0x8139, NULL, PT_LONG , MNID_ID, PSETID_Task, 0x0 }, { PidLidTaskDateCompleted , "TaskDateCompleted" , 0x810f, NULL, PT_SYSTIME , MNID_ID, PSETID_Task, 0x0 }, { PidLidTaskDeadOccurrence , "TaskDeadOccur" , 0x8109, NULL, PT_BOOLEAN , MNID_ID, PSETID_Task, 0x0 }, { PidLidTaskDueDate , "TaskDueDate" , 0x8105, NULL, PT_SYSTIME , MNID_ID, PSETID_Task, 0x0 }, { PidLidTaskEstimatedEffort , "TaskEstimatedEffort" , 0x8111, NULL, PT_LONG , MNID_ID, PSETID_Task, 0x0 }, { PidLidTaskFCreator , "TaskFCreator" , 0x811e, NULL, PT_BOOLEAN , MNID_ID, PSETID_Task, 0x0 }, { PidLidTaskFFixOffline , "TaskFFixOffline" , 0x812c, NULL, PT_BOOLEAN , MNID_ID, PSETID_Task, 0x0 }, { PidLidTaskFRecurring , "TaskFRecur" , 0x8126, NULL, PT_BOOLEAN , MNID_ID, PSETID_Task, 0x0 }, { PidLidTaskHistory , "TaskHistory" , 0x811a, NULL, PT_LONG , MNID_ID, PSETID_Task, 0x0 }, { PidLidTaskLastDelegate , "TaskLastDelegate" , 0x8125, NULL, PT_UNICODE , MNID_ID, PSETID_Task, 0x0 }, { PidLidTaskLastUpdate , "TaskLastUpdate" , 0x8115, NULL, PT_SYSTIME , MNID_ID, PSETID_Task, 0x0 }, { PidLidTaskLastUser , "TaskLastUser" , 0x8122, NULL, PT_UNICODE , MNID_ID, PSETID_Task, 0x0 }, { PidLidTaskMultipleRecipients , "TaskMultRecips" , 0x8120, NULL, PT_LONG , MNID_ID, PSETID_Task, 0x0 }, { PidLidTaskNoCompute , "TaskNoCompute" , 0x8124, NULL, PT_BOOLEAN , MNID_ID, PSETID_Task, 0x0 }, { PidLidTaskOrdinal , "TaskOrdinal" , 0x8123, NULL, PT_LONG , MNID_ID, PSETID_Task, 0x0 }, { PidLidTaskOwner , "TaskOwner" , 0x811f, NULL, PT_UNICODE , MNID_ID, PSETID_Task, 0x0 }, { PidLidTaskOwnership , "TaskOwnership" , 0x8129, NULL, PT_LONG , MNID_ID, PSETID_Task, 0x0 }, { PidLidTaskRecurrence , "TaskRecur" , 0x8116, NULL, PT_BINARY , MNID_ID, PSETID_Task, 0x0 }, { PidLidTaskResetReminder , "TaskResetReminder" , 0x8107, NULL, PT_BOOLEAN , MNID_ID, PSETID_Task, 0x0 }, { PidLidTaskRole , "TaskRole" , 0x8127, NULL, PT_UNICODE , MNID_ID, PSETID_Task, 0x0 }, { PidLidTaskStartDate , "TaskStartDate" , 0x8104, NULL, PT_SYSTIME , MNID_ID, PSETID_Task, 0x0 }, { PidLidTaskState , "TaskState" , 0x8113, NULL, PT_LONG , MNID_ID, PSETID_Task, 0x0 }, { PidLidTaskStatus , "TaskStatus" , 0x8101, NULL, PT_LONG , MNID_ID, PSETID_Task, 0x0 }, { PidLidTaskStatusOnComplete , "TaskSOC" , 0x8119, NULL, PT_BOOLEAN , MNID_ID, PSETID_Task, 0x0 }, { PidLidTaskUpdates , "TaskUpdates" , 0x811b, NULL, PT_BOOLEAN , MNID_ID, PSETID_Task, 0x0 }, { PidLidTaskVersion , "TaskVersion" , 0x8112, NULL, PT_LONG , MNID_ID, PSETID_Task, 0x0 }, { PidLidTeamTask , "TeamTask" , 0x8103, NULL, PT_BOOLEAN , MNID_ID, PSETID_Task, 0x0 }, { PidLidTrustRecipientHighlights , "TrustRecipHighlights" , 0x823e, NULL, PT_BOOLEAN , MNID_ID, PSETID_Task, 0x0 }, { PidLidCategories , "Categories" , 0x9000, NULL, PT_MV_UNICODE , MNID_ID, PS_PUBLIC_STRINGS, 0x0 }, { PidNameInstantMessagingAddress2 , NULL , 0x0000, "IMAddress2", PT_UNICODE , MNID_STRING, PSETID_AirSync, 0x0 }, { PidNameInstantMessagingAddress3 , NULL , 0x0000, "IMAddress3", PT_UNICODE , MNID_STRING, PSETID_AirSync, 0x0 }, { PidNameAttachmentMacContentType , NULL , 0x0000, "AttachmentMacContentType", PT_UNICODE , MNID_STRING, PSETID_Attachment, 0x0 }, { PidNameAttachmentMacInfo , NULL , 0x0000, "AttachmentMacInfo", PT_BINARY , MNID_STRING, PSETID_Attachment, 0x0 }, { PidNameOriginalSpamConfidenceLevel , NULL , 0x0000, "OriginalScl", PT_LONG , MNID_STRING, PSETID_Messaging, 0x0 }, { PidNameAudioNotes , NULL , 0x0000, "UMAudioNotes", PT_UNICODE , MNID_STRING, PSETID_UnifiedMessaging, 0x0 }, { PidNameAutomaticSpeechRecognitionData , NULL , 0x0000, "AsrData", PT_BINARY , MNID_STRING, PSETID_UnifiedMessaging, 0x0 }, { PidNameOutlookProtectionRuleTimestamp , NULL , 0x0000, "X-MS-Exchange-Organization-Outlook-Protection-Rule-Config-Timestamp", PT_UNICODE , MNID_STRING, PSETID_UnifiedMessaging, 0x0 }, { PidNameXUnifiedMessagingPartnerAssignedId , NULL , 0x0000, "X-MS-Exchange-UM-PartnerAssignedID", PT_UNICODE , MNID_STRING, PSETID_UnifiedMessaging, 0x0 }, { PidNameXUnifiedMessagingPartnerContent , NULL , 0x0000, "X-MS-Exchange-UM-PartnerContent", PT_UNICODE , MNID_STRING, PSETID_UnifiedMessaging, 0x0 }, { PidNameXUnifiedMessagingPartnerContext , NULL , 0x0000, "X-MS-Exchange-UM-PartnerContext", PT_UNICODE , MNID_STRING, PSETID_UnifiedMessaging, 0x0 }, { PidNameXUnifiedMessagingPartnerStatus , NULL , 0x0000, "X-MS-Exchange-UM-PartnerStatus", PT_UNICODE , MNID_STRING, PSETID_UnifiedMessaging, 0x0 }, { PidNameAcceptLanguage , NULL , 0x0000, "Accept-Language", PT_UNICODE , MNID_STRING, PS_INTERNET_HEADERS, 0x0 }, { PidNameApprovalAllowedDecisionMakers , NULL , 0x0000, "X-MS-Exchange-Organization-Approval-Allowed-Decision-Makers", PT_UNICODE , MNID_STRING, PS_INTERNET_HEADERS, 0x0 }, { PidNameApprovalRequestor , NULL , 0x0000, "X-MS-Exchange-Organization-Approval-Requestor", PT_UNICODE , MNID_STRING, PS_INTERNET_HEADERS, 0x0 }, { PidNameApproved , NULL , 0x0000, "Approved", PT_UNICODE , MNID_STRING, PS_INTERNET_HEADERS, 0x0 }, { PidNameAuthenticatedAs , NULL , 0x0000, "X-MS-Exchange-Organization-AuthAs", PT_UNICODE , MNID_STRING, PS_INTERNET_HEADERS, 0x0 }, { PidNameAuthenticatedDomain , NULL , 0x0000, "X-MS-Exchange-Organization-AuthDomain", PT_UNICODE , MNID_STRING, PS_INTERNET_HEADERS, 0x0 }, { PidNameAuthenticatedMechanism , NULL , 0x0000, "X-MS-Exchange-Organization-AuthMechanism", PT_UNICODE , MNID_STRING, PS_INTERNET_HEADERS, 0x0 }, { PidNameAuthenticatedSource , NULL , 0x0000, "X-MS-Exchange-Organization-AuthSource", PT_UNICODE , MNID_STRING, PS_INTERNET_HEADERS, 0x0 }, { PidNameBcc , NULL , 0x0000, "Bcc", PT_UNICODE , MNID_STRING, PS_INTERNET_HEADERS, 0x0 }, { PidNameCc , NULL , 0x0000, "Cc", PT_UNICODE , MNID_STRING, PS_INTERNET_HEADERS, 0x0 }, { PidNameContentBase , NULL , 0x0000, "Content-Base", PT_UNICODE , MNID_STRING, PS_INTERNET_HEADERS, 0x0 }, { PidNameContentClass , NULL , 0x0000, "Content-Class", PT_UNICODE , MNID_STRING, PS_INTERNET_HEADERS, 0x0 }, { PidNameContentDisposition , NULL , 0x0000, "Content-Disposition", PT_UNICODE , MNID_STRING, PS_INTERNET_HEADERS, 0x0 }, { PidNameContentID , NULL , 0x0000, "Content-ID", PT_UNICODE , MNID_STRING, PS_INTERNET_HEADERS, 0x0 }, { PidNameContentLanguage , NULL , 0x0000, "Content-Language", PT_UNICODE , MNID_STRING, PS_INTERNET_HEADERS, 0x0 }, { PidNameContentLocation , NULL , 0x0000, "Content-Location", PT_UNICODE , MNID_STRING, PS_INTERNET_HEADERS, 0x0 }, { PidNameContentTransferEncoding , NULL , 0x0000, "Content-Transfer-Encoding", PT_UNICODE , MNID_STRING, PS_INTERNET_HEADERS, 0x0 }, { PidNameContentType , NULL , 0x0000, "Content-Type", PT_UNICODE , MNID_STRING, PS_INTERNET_HEADERS, 0x0 }, { PidNameControl , NULL , 0x0000, "Control", PT_UNICODE , MNID_STRING, PS_INTERNET_HEADERS, 0x0 }, { PidNameCrossReference , NULL , 0x0000, "Xref", PT_UNICODE , MNID_STRING, PS_INTERNET_HEADERS, 0x0 }, { PidNameDisposition , NULL , 0x0000, "Disposition", PT_UNICODE , MNID_STRING, PS_INTERNET_HEADERS, 0x0 }, { PidNameDispositionNotificationTo , NULL , 0x0000, "Disposition-Notification-To", PT_UNICODE , MNID_STRING, PS_INTERNET_HEADERS, 0x0 }, { PidNameDistribution , NULL , 0x0000, "Distribution", PT_UNICODE , MNID_STRING, PS_INTERNET_HEADERS, 0x0 }, { PidNameExpires , NULL , 0x0000, "Expires", PT_UNICODE , MNID_STRING, PS_INTERNET_HEADERS, 0x0 }, { PidNameExpiryDate , NULL , 0x0000, "Expiry-Date", PT_UNICODE , MNID_STRING, PS_INTERNET_HEADERS, 0x0 }, { PidNameFollowupTo , NULL , 0x0000, "Followup-To", PT_UNICODE , MNID_STRING, PS_INTERNET_HEADERS, 0x0 }, { PidNameFrom , NULL , 0x0000, "From", PT_UNICODE , MNID_STRING, PS_INTERNET_HEADERS, 0x0 }, { PidNameImportance , NULL , 0x0000, "Importance", PT_UNICODE , MNID_STRING, PS_INTERNET_HEADERS, 0x0 }, { PidNameInReplyTo , NULL , 0x0000, "In-Reply-To", PT_UNICODE , MNID_STRING, PS_INTERNET_HEADERS, 0x0 }, { PidNameInternetComment , NULL , 0x0000, "Comment", PT_UNICODE , MNID_STRING, PS_INTERNET_HEADERS, 0x0 }, { PidNameInternetKeywords , NULL , 0x0000, "Keywords", PT_UNICODE , MNID_STRING, PS_INTERNET_HEADERS, 0x0 }, { PidNameInternetSubject , NULL , 0x0000, "Subject", PT_UNICODE , MNID_STRING, PS_INTERNET_HEADERS, 0x0 }, { PidNameLines , NULL , 0x0000, "Lines", PT_UNICODE , MNID_STRING, PS_INTERNET_HEADERS, 0x0 }, { PidNameMessageId , NULL , 0x0000, "Message-ID", PT_UNICODE , MNID_STRING, PS_INTERNET_HEADERS, 0x0 }, { PidNameMimeVersion , NULL , 0x0000, "Mime-Version", PT_UNICODE , MNID_STRING, PS_INTERNET_HEADERS, 0x0 }, { PidNameNewsgroups , NULL , 0x0000, "Newsgroups", PT_UNICODE , MNID_STRING, PS_INTERNET_HEADERS, 0x0 }, { PidNameNntpPostingHost , NULL , 0x0000, "NNTP-Posting-Host", PT_UNICODE , MNID_STRING, PS_INTERNET_HEADERS, 0x0 }, { PidNameOrganization , NULL , 0x0000, "Organization", PT_UNICODE , MNID_STRING, PS_INTERNET_HEADERS, 0x0 }, { PidNameOriginalRecipient , NULL , 0x0000, "Original-Recipient", PT_UNICODE , MNID_STRING, PS_INTERNET_HEADERS, 0x0 }, { PidNameOutlookProtectionRuleOverridden , NULL , 0x0000, "X-MS-Exchange-Organization-Outlook-Protection-Rule-Overridden", PT_UNICODE , MNID_STRING, PS_INTERNET_HEADERS, 0x0 }, { PidNameOutlookProtectionRuleVersion , NULL , 0x0000, "X-MS-Exchange-Organization-Outlook-Protection-Rule-Addin-Version", PT_UNICODE , MNID_STRING, PS_INTERNET_HEADERS, 0x0 }, { PidNamePath , NULL , 0x0000, "Path", PT_UNICODE , MNID_STRING, PS_INTERNET_HEADERS, 0x0 }, { PidNamePostingVersion , NULL , 0x0000, "Posting-Version", PT_UNICODE , MNID_STRING, PS_INTERNET_HEADERS, 0x0 }, { PidNamePriority , NULL , 0x0000, "Priority", PT_UNICODE , MNID_STRING, PS_INTERNET_HEADERS, 0x0 }, { PidNameReceived , NULL , 0x0000, "Received", PT_UNICODE , MNID_STRING, PS_INTERNET_HEADERS, 0x0 }, { PidNameReferences , NULL , 0x0000, "References", PT_UNICODE , MNID_STRING, PS_INTERNET_HEADERS, 0x0 }, { PidNameRelayVersion , NULL , 0x0000, "Relay-Version", PT_UNICODE , MNID_STRING, PS_INTERNET_HEADERS, 0x0 }, { PidNameReplyBy , NULL , 0x0000, "Reply-By", PT_UNICODE , MNID_STRING, PS_INTERNET_HEADERS, 0x0 }, { PidNameReplyTo , NULL , 0x0000, "Reply-To", PT_UNICODE , MNID_STRING, PS_INTERNET_HEADERS, 0x0 }, { PidNameReturnPath , NULL , 0x0000, "Return-Path", PT_UNICODE , MNID_STRING, PS_INTERNET_HEADERS, 0x0 }, { PidNameReturnReceiptTo , NULL , 0x0000, "Return-Receipt-To", PT_UNICODE , MNID_STRING, PS_INTERNET_HEADERS, 0x0 }, { PidNameRightsProtectMessage , NULL , 0x0000, "X-MS-Exchange-Organization-RightsProtectMessage", PT_UNICODE , MNID_STRING, PS_INTERNET_HEADERS, 0x0 }, { PidNameSender , NULL , 0x0000, "Sender", PT_UNICODE , MNID_STRING, PS_INTERNET_HEADERS, 0x0 }, { PidNameSensitivity , NULL , 0x0000, "Sensitivity", PT_UNICODE , MNID_STRING, PS_INTERNET_HEADERS, 0x0 }, { PidNameSummary , NULL , 0x0000, "Summary", PT_UNICODE , MNID_STRING, PS_INTERNET_HEADERS, 0x0 }, { PidNameThreadIndex , NULL , 0x0000, "Thread-Index", PT_UNICODE , MNID_STRING, PS_INTERNET_HEADERS, 0x0 }, { PidNameThreadTopic , NULL , 0x0000, "Thread-Topic", PT_UNICODE , MNID_STRING, PS_INTERNET_HEADERS, 0x0 }, { PidNameTo , NULL , 0x0000, "To", PT_UNICODE , MNID_STRING, PS_INTERNET_HEADERS, 0x0 }, { PidNameXCallId , NULL , 0x0000, "X-CallID", PT_UNICODE , MNID_STRING, PS_INTERNET_HEADERS, 0x0 }, { PidNameXFaxNumberOfPages , NULL , 0x0000, "X-FaxNumberOfPages", PT_SHORT , MNID_STRING, PS_INTERNET_HEADERS, 0x0 }, { PidNameXMailer , NULL , 0x0000, "X-Mailer", PT_UNICODE , MNID_STRING, PS_INTERNET_HEADERS, 0x0 }, { PidNameXMessageCompleted , NULL , 0x0000, "X-Message-Completed", PT_UNICODE , MNID_STRING, PS_INTERNET_HEADERS, 0x0 }, { PidNameXMessageFlag , NULL , 0x0000, "X-Message-Flag", PT_UNICODE , MNID_STRING, PS_INTERNET_HEADERS, 0x0 }, { PidNameXRequireProtectedPlayOnPhone , NULL , 0x0000, "X-RequireProtectedPlayOnPhone", PT_BOOLEAN , MNID_STRING, PS_INTERNET_HEADERS, 0x0 }, { PidNameXSenderTelephoneNumber , NULL , 0x0000, "X-CallingTelephoneNumber", PT_UNICODE , MNID_STRING, PS_INTERNET_HEADERS, 0x0 }, { PidNameXSharingBrowseUrl , NULL , 0x0000, "X-Sharing-Browse-Url", PT_UNICODE , MNID_STRING, PS_INTERNET_HEADERS, 0x0 }, { PidNameXSharingCapabilities , NULL , 0x0000, "X-Sharing-Capabilities", PT_UNICODE , MNID_STRING, PS_INTERNET_HEADERS, 0x0 }, { PidNameXSharingConfigUrl , NULL , 0x0000, "X-Sharing-Config-Url", PT_UNICODE , MNID_STRING, PS_INTERNET_HEADERS, 0x0 }, { PidNameXSharingExendedCaps , NULL , 0x0000, "X-Sharing-Exended-Caps", PT_UNICODE , MNID_STRING, PS_INTERNET_HEADERS, 0x0 }, { PidNameXSharingFlavor , NULL , 0x0000, "X-Sharing-Flavor", PT_UNICODE , MNID_STRING, PS_INTERNET_HEADERS, 0x0 }, { PidNameXSharingInstanceGuid , NULL , 0x0000, "X-Sharing-Instance-Guid", PT_UNICODE , MNID_STRING, PS_INTERNET_HEADERS, 0x0 }, { PidNameXSharingLocalType , NULL , 0x0000, "X-Sharing-Local-Type", PT_UNICODE , MNID_STRING, PS_INTERNET_HEADERS, 0x0 }, { PidNameXSharingProviderGuid , NULL , 0x0000, "X-Sharing-Provider-Guid", PT_UNICODE , MNID_STRING, PS_INTERNET_HEADERS, 0x0 }, { PidNameXSharingProviderName , NULL , 0x0000, "X-Sharing-Provider-Name", PT_UNICODE , MNID_STRING, PS_INTERNET_HEADERS, 0x0 }, { PidNameXSharingProviderUrl , NULL , 0x0000, "X-Sharing-Provider-Url", PT_UNICODE , MNID_STRING, PS_INTERNET_HEADERS, 0x0 }, { PidNameXSharingRemoteName , NULL , 0x0000, "X-Sharing-Remote-Name", PT_UNICODE , MNID_STRING, PS_INTERNET_HEADERS, 0x0 }, { PidNameXSharingRemotePath , NULL , 0x0000, "X-Sharing-Remote-Path", PT_UNICODE , MNID_STRING, PS_INTERNET_HEADERS, 0x0 }, { PidNameXSharingRemoteStoreUid , NULL , 0x0000, "X-Sharing-Remote-Store-Uid", PT_UNICODE , MNID_STRING, PS_INTERNET_HEADERS, 0x0 }, { PidNameXSharingRemoteType , NULL , 0x0000, "X-Sharing-Remote-Type", PT_UNICODE , MNID_STRING, PS_INTERNET_HEADERS, 0x0 }, { PidNameXSharingRemoteUid , NULL , 0x0000, "X-Sharing-Remote-Uid", PT_UNICODE , MNID_STRING, PS_INTERNET_HEADERS, 0x0 }, { PidNameXUnsent , NULL , 0x0000, "X-Unsent", PT_UNICODE , MNID_STRING, PS_INTERNET_HEADERS, 0x0 }, { PidNameXVoiceMessageAttachmentOrder , NULL , 0x0000, "X-AttachmentOrder", PT_UNICODE , MNID_STRING, PS_INTERNET_HEADERS, 0x0 }, { PidNameXVoiceMessageDuration , NULL , 0x0000, "X-VoiceMessageDuration", PT_SHORT , MNID_STRING, PS_INTERNET_HEADERS, 0x0 }, { PidNameXVoiceMessageSenderName , NULL , 0x0000, "X-VoiceMessageSenderName", PT_UNICODE , MNID_STRING, PS_INTERNET_HEADERS, 0x0 }, { PidNameApplicationName , NULL , 0x0000, "AppName", PT_UNICODE , MNID_STRING, PS_PUBLIC_STRINGS, 0x0 }, { PidNameAuthor , NULL , 0x0000, "Author", PT_UNICODE , MNID_STRING, PS_PUBLIC_STRINGS, 0x0 }, { PidNameByteCount , NULL , 0x0000, "ByteCount", PT_LONG , MNID_STRING, PS_PUBLIC_STRINGS, 0x0 }, { PidNameCalendarAttendeeRole , NULL , 0x0000, "urn:schemas:calendar:attendeerole", PT_LONG , MNID_STRING, PS_PUBLIC_STRINGS, 0x0 }, { PidNameCalendarBusystatus , NULL , 0x0000, "urn:schemas:calendar:busystatus", PT_UNICODE , MNID_STRING, PS_PUBLIC_STRINGS, 0x0 }, { PidNameCalendarContact , NULL , 0x0000, "urn:schemas:calendar:contact", PT_UNICODE , MNID_STRING, PS_PUBLIC_STRINGS, 0x0 }, { PidNameCalendarContactUrl , NULL , 0x0000, "urn:schemas:calendar:contacturl", PT_UNICODE , MNID_STRING, PS_PUBLIC_STRINGS, 0x0 }, { PidNameCalendarCreated , NULL , 0x0000, "urn:schemas:calendar:created", PT_SYSTIME , MNID_STRING, PS_PUBLIC_STRINGS, 0x0 }, { PidNameCalendarDescriptionUrl , NULL , 0x0000, "urn:schemas:calendar:descriptionurl", PT_UNICODE , MNID_STRING, PS_PUBLIC_STRINGS, 0x0 }, { PidNameCalendarDuration , NULL , 0x0000, "urn:schemas:calendar:duration", PT_LONG , MNID_STRING, PS_PUBLIC_STRINGS, 0x0 }, { PidNameCalendarExceptionDate , NULL , 0x0000, "urn:schemas:calendar:exdate", PT_MV_SYSTIME , MNID_STRING, PS_PUBLIC_STRINGS, 0x0 }, { PidNameCalendarExceptionRule , NULL , 0x0000, "urn:schemas:calendar:exrule", PT_MV_UNICODE , MNID_STRING, PS_PUBLIC_STRINGS, 0x0 }, { PidNameCalendarGeoLatitude , NULL , 0x0000, "urn:schemas:calendar:geolatitude", PT_DOUBLE , MNID_STRING, PS_PUBLIC_STRINGS, 0x0 }, { PidNameCalendarGeoLongitude , NULL , 0x0000, "urn:schemas:calendar:geolongitude", PT_DOUBLE , MNID_STRING, PS_PUBLIC_STRINGS, 0x0 }, { PidNameCalendarInstanceType , NULL , 0x0000, "urn:schemas:calendar:instancetype", PT_LONG , MNID_STRING, PS_PUBLIC_STRINGS, 0x0 }, { PidNameCalendarIsOrganizer , NULL , 0x0000, "urn:schemas:calendar:isorganizer", PT_BOOLEAN , MNID_STRING, PS_PUBLIC_STRINGS, 0x0 }, { PidNameCalendarLastModified , NULL , 0x0000, "urn:schemas:calendar:lastmodified", PT_SYSTIME , MNID_STRING, PS_PUBLIC_STRINGS, 0x0 }, { PidNameCalendarLocationUrl , NULL , 0x0000, "urn:schemas:calendar:locationurl", PT_UNICODE , MNID_STRING, PS_PUBLIC_STRINGS, 0x0 }, { PidNameCalendarMeetingStatus , NULL , 0x0000, "urn:schemas:calendar:meetingstatus", PT_UNICODE , MNID_STRING, PS_PUBLIC_STRINGS, 0x0 }, { PidNameCalendarMethod , NULL , 0x0000, "urn:schemas:calendar:method", PT_UNICODE , MNID_STRING, PS_PUBLIC_STRINGS, 0x0 }, { PidNameCalendarProductId , NULL , 0x0000, "urn:schemas:calendar:prodid", PT_UNICODE , MNID_STRING, PS_PUBLIC_STRINGS, 0x0 }, { PidNameCalendarRecurrenceIdRange , NULL , 0x0000, "urn:schemas:calendar:recurrenceidrange", PT_UNICODE , MNID_STRING, PS_PUBLIC_STRINGS, 0x0 }, { PidNameCalendarReminderOffset , NULL , 0x0000, "urn:schemas:calendar:reminderoffset", PT_LONG , MNID_STRING, PS_PUBLIC_STRINGS, 0x0 }, { PidNameCalendarResources , NULL , 0x0000, "urn:schemas:calendar:resources", PT_UNICODE , MNID_STRING, PS_PUBLIC_STRINGS, 0x0 }, { PidNameCalendarRsvp , NULL , 0x0000, "urn:schemas:calendar:rsvp", PT_BOOLEAN , MNID_STRING, PS_PUBLIC_STRINGS, 0x0 }, { PidNameCalendarSequence , NULL , 0x0000, "urn:schemas:calendar:sequence", PT_LONG , MNID_STRING, PS_PUBLIC_STRINGS, 0x0 }, { PidNameCalendarTimeZone , NULL , 0x0000, "urn:schemas:calendar:timezone", PT_UNICODE , MNID_STRING, PS_PUBLIC_STRINGS, 0x0 }, { PidNameCalendarTimeZoneId , NULL , 0x0000, "urn:schemas:calendar:timezoneid", PT_LONG , MNID_STRING, PS_PUBLIC_STRINGS, 0x0 }, { PidNameCalendarTransparent , NULL , 0x0000, "urn:schemas:calendar:transparent", PT_UNICODE , MNID_STRING, PS_PUBLIC_STRINGS, 0x0 }, { PidNameCalendarUid , NULL , 0x0000, "urn:schemas:calendar:uid", PT_UNICODE , MNID_STRING, PS_PUBLIC_STRINGS, 0x0 }, { PidNameCalendarVersion , NULL , 0x0000, "urn:schemas:calendar:version", PT_UNICODE , MNID_STRING, PS_PUBLIC_STRINGS, 0x0 }, { PidNameCategory , NULL , 0x0000, "Category", PT_UNICODE , MNID_STRING, PS_PUBLIC_STRINGS, 0x0 }, { PidNameCharacterCount , NULL , 0x0000, "CharCount", PT_LONG , MNID_STRING, PS_PUBLIC_STRINGS, 0x0 }, { PidNameComments , NULL , 0x0000, "Comments", PT_UNICODE , MNID_STRING, PS_PUBLIC_STRINGS, 0x0 }, { PidNameCompany , NULL , 0x0000, "Company", PT_UNICODE , MNID_STRING, PS_PUBLIC_STRINGS, 0x0 }, { PidNameContactsAlternateRecipient , NULL , 0x0000, "urn:schemas:contacts:alternaterecipient", PT_UNICODE , MNID_STRING, PS_PUBLIC_STRINGS, 0x0 }, { PidNameContactsCountry , NULL , 0x0000, "urn:schemas:contacts:c", PT_UNICODE , MNID_STRING, PS_PUBLIC_STRINGS, 0x0 }, { PidNameContactsEmail1 , NULL , 0x0000, "urn:schemas:contacts:email1", PT_UNICODE , MNID_STRING, PS_PUBLIC_STRINGS, 0x0 }, { PidNameContactsEmail2 , NULL , 0x0000, "urn:schemas:contacts:email2", PT_UNICODE , MNID_STRING, PS_PUBLIC_STRINGS, 0x0 }, { PidNameContactsEmail3 , NULL , 0x0000, "urn:schemas:contacts:email3", PT_UNICODE , MNID_STRING, PS_PUBLIC_STRINGS, 0x0 }, { PidNameContactsFileAs , NULL , 0x0000, "urn:schemas:contacts:fileas", PT_UNICODE , MNID_STRING, PS_PUBLIC_STRINGS, 0x0 }, { PidNameContactsFileasId , NULL , 0x0000, "urn:schemas:contacts:fileasid", PT_LONG , MNID_STRING, PS_PUBLIC_STRINGS, 0x0 }, { PidNameContactsHomeLatitude , NULL , 0x0000, "urn:schemas:contacts:homelatitude", PT_DOUBLE , MNID_STRING, PS_PUBLIC_STRINGS, 0x0 }, { PidNameContactsHomeLongitude , NULL , 0x0000, "urn:schemas:contacts:homelongitude", PT_DOUBLE , MNID_STRING, PS_PUBLIC_STRINGS, 0x0 }, { PidNameContactsHomeTimeZone , NULL , 0x0000, "urn:schemas:contacts:hometimezone", PT_UNICODE , MNID_STRING, PS_PUBLIC_STRINGS, 0x0 }, { PidNameContactsMapUrl , NULL , 0x0000, "urn:schemas:contacts:mapurl", PT_UNICODE , MNID_STRING, PS_PUBLIC_STRINGS, 0x0 }, { PidNameContactsOtherCountryCode , NULL , 0x0000, "urn:schemas:contacts:othercountrycode", PT_UNICODE , MNID_STRING, PS_PUBLIC_STRINGS, 0x0 }, { PidNameContactsOtherPager , NULL , 0x0000, "urn:schemas:contacts:otherpager", PT_UNICODE , MNID_STRING, PS_PUBLIC_STRINGS, 0x0 }, { PidNameContactsOtherTimeZone , NULL , 0x0000, "urn:schemas:contacts:othertimezone", PT_UNICODE , MNID_STRING, PS_PUBLIC_STRINGS, 0x0 }, { PidNameContactsProxyAddresses , NULL , 0x0000, "urn:schemas:contacts:proxyaddresses", PT_MV_UNICODE , MNID_STRING, PS_PUBLIC_STRINGS, 0x0 }, { PidNameContactsSecretaryUrl , NULL , 0x0000, "urn:schemas:contacts:secretaryurl", PT_UNICODE , MNID_STRING, PS_PUBLIC_STRINGS, 0x0 }, { PidNameContactsSourceUrl , NULL , 0x0000, "urn:schemas:contacts:sourceurl", PT_UNICODE , MNID_STRING, PS_PUBLIC_STRINGS, 0x0 }, { PidNameCreateDateTimeReadOnly , NULL , 0x0000, "CreateDtmRo", PT_SYSTIME , MNID_STRING, PS_PUBLIC_STRINGS, 0x0 }, { PidNameDavGetContentType , NULL , 0x0000, "DAV:getcontenttype", PT_UNICODE , MNID_STRING, PS_PUBLIC_STRINGS, 0x0 }, { PidNameDavId , NULL , 0x0000, "DAV:id", PT_UNICODE , MNID_STRING, PS_PUBLIC_STRINGS, 0x0 }, { PidNameDavIsCollection , NULL , 0x0000, "DAV:iscollection", PT_BOOLEAN , MNID_STRING, PS_PUBLIC_STRINGS, 0x0 }, { PidNameDavIsStructuredDocument , NULL , 0x0000, "DAV:isstructureddocument", PT_BOOLEAN , MNID_STRING, PS_PUBLIC_STRINGS, 0x0 }, { PidNameDavParentName , NULL , 0x0000, "DAV:parentname", PT_UNICODE , MNID_STRING, PS_PUBLIC_STRINGS, 0x0 }, { PidNameDavResourceType , NULL , 0x0000, "DAV:resourcetype", PT_UNICODE , MNID_STRING, PS_PUBLIC_STRINGS, 0x0 }, { PidNameDavSearchRequest , NULL , 0x0000, "DAV:searchrequest", PT_UNICODE , MNID_STRING, PS_PUBLIC_STRINGS, 0x0 }, { PidNameDavSearchType , NULL , 0x0000, "DAV:searchtype", PT_UNICODE , MNID_STRING, PS_PUBLIC_STRINGS, 0x0 }, { PidNameDavUid , NULL , 0x0000, "DAV:uid", PT_UNICODE , MNID_STRING, PS_PUBLIC_STRINGS, 0x0 }, { PidNameDocumentParts , NULL , 0x0000, "DocParts", PT_MV_UNICODE , MNID_STRING, PS_PUBLIC_STRINGS, 0x0 }, { PidNameEditTime , NULL , 0x0000, "EditTime", PT_UNICODE , MNID_STRING, PS_PUBLIC_STRINGS, 0x0 }, { PidNameExchangeIntendedBusyStatus , NULL , 0x0000, "http://schemas.microsoft.com/exchange/intendedbusystatus", PT_UNICODE , MNID_STRING, PS_PUBLIC_STRINGS, 0x0 }, { PidNameExchangeJunkEmailMoveStamp , NULL , 0x0000, "http://schemas.microsoft.com/exchange/junkemailmovestamp", PT_LONG , MNID_STRING, PS_PUBLIC_STRINGS, 0x0 }, { PidNameExchangeModifyExceptionStructure , NULL , 0x0000, "http://schemas.microsoft.com/exchange/modifyexceptionstruct", PT_BINARY , MNID_STRING, PS_PUBLIC_STRINGS, 0x0 }, { PidNameExchangeMsexchembdefaultmailfolder , NULL , 0x0000, "http://schemas.microsoft.com/exchange/msexchembdefaultmailfolder", PT_UNICODE , MNID_STRING, PS_PUBLIC_STRINGS, 0x0 }, { PidNameExchangeMsexchembdefaultmailfoldertype , NULL , 0x0000, "http://schemas.microsoft.com/exchange/msexchembdefaultmailfoldertype", PT_UNICODE , MNID_STRING, PS_PUBLIC_STRINGS, 0x0 }, { PidNameExchangeNoModifyExceptions , NULL , 0x0000, "http://schemas.microsoft.com/exchange/nomodifyexceptions", PT_BOOLEAN , MNID_STRING, PS_PUBLIC_STRINGS, 0x0 }, { PidNameExchangePatternEnd , NULL , 0x0000, "http://schemas.microsoft.com/exchange/patternend", PT_SYSTIME , MNID_STRING, PS_PUBLIC_STRINGS, 0x0 }, { PidNameExchangePatternStart , NULL , 0x0000, "http://schemas.microsoft.com/exchange/patternstart", PT_SYSTIME , MNID_STRING, PS_PUBLIC_STRINGS, 0x0 }, { PidNameExchangePublicFolderEmailAddress , NULL , 0x0000, "http://schemas.microsoft.com/exchange/publicfolderemailaddress", PT_UNICODE , MNID_STRING, PS_PUBLIC_STRINGS, 0x0 }, { PidNameExchangeReminderInterval , NULL , 0x0000, "http://schemas.microsoft.com/exchange/reminderinterval", PT_LONG , MNID_STRING, PS_PUBLIC_STRINGS, 0x0 }, { PidNameExchDatabaseSchema , NULL , 0x0000, "urn:schemas-microsoft-com:exch-data:baseschema", PT_MV_UNICODE , MNID_STRING, PS_PUBLIC_STRINGS, 0x0 }, { PidNameExchDataExpectedContentClass , NULL , 0x0000, "urn:schemas-microsoft-com:exch-data:expected-content-class", PT_MV_UNICODE , MNID_STRING, PS_PUBLIC_STRINGS, 0x0 }, { PidNameExchDataSchemaCollectionReference , NULL , 0x0000, "urn:schemas-microsoft-com:exch-data:schema-collection-ref", PT_UNICODE , MNID_STRING, PS_PUBLIC_STRINGS, 0x0 }, { PidNameHeadingPairs , NULL , 0x0000, "HeadingPairs", PT_BINARY , MNID_STRING, PS_PUBLIC_STRINGS, 0x0 }, { PidNameHiddenCount , NULL , 0x0000, "HiddenCount", PT_LONG , MNID_STRING, PS_PUBLIC_STRINGS, 0x0 }, { PidNameHttpmailCalendar , NULL , 0x0000, "urn:schemas:httpmail:calendar", PT_UNICODE , MNID_STRING, PS_PUBLIC_STRINGS, 0x0 }, { PidNameHttpmailCc , NULL , 0x0000, "urn:schemas:httpmail:cc", PT_UNICODE , MNID_STRING, PS_PUBLIC_STRINGS, 0x0 }, { PidNameHttpmailContacts , NULL , 0x0000, "urn:schemas:httpmail:contacts", PT_UNICODE , MNID_STRING, PS_PUBLIC_STRINGS, 0x0 }, { PidNameHttpmailContentMediaType , NULL , 0x0000, "urn:schemas:httpmail:content-media-type", PT_UNICODE , MNID_STRING, PS_PUBLIC_STRINGS, 0x0 }, { PidNameHttpmailFrom , NULL , 0x0000, "urn:schemas:httpmail:from", PT_UNICODE , MNID_STRING, PS_PUBLIC_STRINGS, 0x0 }, { PidNameHttpmailFromEmail , NULL , 0x0000, "urn:schemas:httpmail:fromemail", PT_UNICODE , MNID_STRING, PS_PUBLIC_STRINGS, 0x0 }, { PidNameHttpmailHtmlDescription , NULL , 0x0000, "urn:schemas:httpmail:htmldescription", PT_UNICODE , MNID_STRING, PS_PUBLIC_STRINGS, 0x0 }, { PidNameHttpmailOutbox , NULL , 0x0000, "urn:schemas:httpmail:outbox", PT_UNICODE , MNID_STRING, PS_PUBLIC_STRINGS, 0x0 }, { PidNameHttpmailSendMessage , NULL , 0x0000, "urn:schemas:httpmail:sendmsg", PT_UNICODE , MNID_STRING, PS_PUBLIC_STRINGS, 0x0 }, { PidNameHttpmailSubmitted , NULL , 0x0000, "urn:schemas:httpmail:submitted", PT_BOOLEAN , MNID_STRING, PS_PUBLIC_STRINGS, 0x0 }, { PidNameHttpmailTo , NULL , 0x0000, "urn:schemas:httpmail:to", PT_UNICODE , MNID_STRING, PS_PUBLIC_STRINGS, 0x0 }, { PidNameICalendarRecurrenceDate , NULL , 0x0000, "urn:schemas:calendar:rdate", PT_MV_SYSTIME , MNID_STRING, PS_PUBLIC_STRINGS, 0x0 }, { PidNameICalendarRecurrenceRule , NULL , 0x0000, "urn:schemas:calendar:rrule", PT_MV_UNICODE , MNID_STRING, PS_PUBLIC_STRINGS, 0x0 }, { PidNameKeywords , NULL , 0x0000, "Keywords", PT_MV_UNICODE , MNID_STRING, PS_PUBLIC_STRINGS, 0x0 }, { PidNameLastAuthor , NULL , 0x0000, "LastAuthor", PT_UNICODE , MNID_STRING, PS_PUBLIC_STRINGS, 0x0 }, { PidNameLastPrinted , NULL , 0x0000, "LastPrinted", PT_SYSTIME , MNID_STRING, PS_PUBLIC_STRINGS, 0x0 }, { PidNameLastSaveDateTime , NULL , 0x0000, "LastSaveDtm", PT_SYSTIME , MNID_STRING, PS_PUBLIC_STRINGS, 0x0 }, { PidNameLineCount , NULL , 0x0000, "LineCount", PT_LONG , MNID_STRING, PS_PUBLIC_STRINGS, 0x0 }, { PidNameLinksDirty , NULL , 0x0000, "LinksDirty", PT_BOOLEAN , MNID_STRING, PS_PUBLIC_STRINGS, 0x0 }, { PidNameMailSubmissionUri , NULL , 0x0000, "MAIL:submissionuri", PT_UNICODE , MNID_STRING, PS_PUBLIC_STRINGS, 0x0 }, { PidNameManager , NULL , 0x0000, "Manager", PT_UNICODE , MNID_STRING, PS_PUBLIC_STRINGS, 0x0 }, { PidNameMultimediaClipCount , NULL , 0x0000, "MMClipCount", PT_LONG , MNID_STRING, PS_PUBLIC_STRINGS, 0x0 }, { PidNameNoteCount , NULL , 0x0000, "NoteCount", PT_LONG , MNID_STRING, PS_PUBLIC_STRINGS, 0x0 }, { PidNameOMSAccountGuid , NULL , 0x0000, "OMSAccountGuid", PT_UNICODE , MNID_STRING, PS_PUBLIC_STRINGS, 0x0 }, { PidNameOMSMobileModel , NULL , 0x0000, "OMSMobileModel", PT_UNICODE , MNID_STRING, PS_PUBLIC_STRINGS, 0x0 }, { PidNameOMSScheduleTime , NULL , 0x0000, "OMSScheduleTime", PT_SYSTIME , MNID_STRING, PS_PUBLIC_STRINGS, 0x0 }, { PidNameOMSServiceType , NULL , 0x0000, "OMSServiceType", PT_LONG , MNID_STRING, PS_PUBLIC_STRINGS, 0x0 }, { PidNameOMSSourceType , NULL , 0x0000, "OMSSourceType", PT_LONG , MNID_STRING, PS_PUBLIC_STRINGS, 0x0 }, { PidNamePageCount , NULL , 0x0000, "PageCount", PT_LONG , MNID_STRING, PS_PUBLIC_STRINGS, 0x0 }, { PidNameParagraphCount , NULL , 0x0000, "ParCount", PT_LONG , MNID_STRING, PS_PUBLIC_STRINGS, 0x0 }, { PidNamePhishingStamp , NULL , 0x0000, "http://schemas.microsoft.com/outlook/phishingstamp", PT_LONG , MNID_STRING, PS_PUBLIC_STRINGS, 0x0 }, { PidNamePresentationFormat , NULL , 0x0000, "PresFormat", PT_UNICODE , MNID_STRING, PS_PUBLIC_STRINGS, 0x0 }, { PidNameQuarantineOriginalSender , NULL , 0x0000, "quarantine-original-sender", PT_UNICODE , MNID_STRING, PS_PUBLIC_STRINGS, 0x0 }, { PidNameRevisionNumber , NULL , 0x0000, "RevNumber", PT_UNICODE , MNID_STRING, PS_PUBLIC_STRINGS, 0x0 }, { PidNameRightsManagementLicense , NULL , 0x0000, "DRMLicense", PT_MV_BINARY , MNID_STRING, PS_PUBLIC_STRINGS, 0x0 }, { PidNameScale , NULL , 0x0000, "Scale", PT_BOOLEAN , MNID_STRING, PS_PUBLIC_STRINGS, 0x0 }, { PidNameSecurity , NULL , 0x0000, "Security", PT_LONG , MNID_STRING, PS_PUBLIC_STRINGS, 0x0 }, { PidNameSlideCount , NULL , 0x0000, "SlideCount", PT_LONG , MNID_STRING, PS_PUBLIC_STRINGS, 0x0 }, { PidNameSubject , NULL , 0x0000, "Subject", PT_UNICODE , MNID_STRING, PS_PUBLIC_STRINGS, 0x0 }, { PidNameTemplate , NULL , 0x0000, "Template", PT_UNICODE , MNID_STRING, PS_PUBLIC_STRINGS, 0x0 }, { PidNameThumbnail , NULL , 0x0000, "Thumbnail", PT_BINARY , MNID_STRING, PS_PUBLIC_STRINGS, 0x0 }, { PidNameTitle , NULL , 0x0000, "Title", PT_UNICODE , MNID_STRING, PS_PUBLIC_STRINGS, 0x0 }, { PidNameWordCount , NULL , 0x0000, "WordCount", PT_LONG , MNID_STRING, PS_PUBLIC_STRINGS, 0x0 }, { PidLidRemoteTransferSize , "RemoteTransferSize" , 0x8f05, NULL, PT_LONG , MNID_ID, PSETID_Remote, 0x0 }, { 0x00000000 , NULL , 0x0000, NULL, PT_UNSPECIFIED , 0x0, NULL, 0x0 } }; static struct mapi_nameid_names mapi_nameid_names[] = { { PidLidAddressBookProviderArrayType , "PidLidAddressBookProviderArrayType" }, { PidLidAddressBookProviderEmailList , "PidLidAddressBookProviderEmailList" }, { PidLidAddressCountryCode , "PidLidAddressCountryCode" }, { PidLidAnniversaryEventEntryId , "PidLidAnniversaryEventEntryId" }, { PidLidAutoLog , "PidLidAutoLog" }, { PidLidBirthdayEventEntryId , "PidLidBirthdayEventEntryId" }, { PidLidBirthdayLocal , "PidLidBirthdayLocal" }, { PidLidBusinessCardCardPicture , "PidLidBusinessCardCardPicture" }, { PidLidBusinessCardDisplayDefinition , "PidLidBusinessCardDisplayDefinition" }, { PidLidContactCharacterSet , "PidLidContactCharacterSet" }, { PidLidContactItemData , "PidLidContactItemData" }, { PidLidContactUserField1 , "PidLidContactUserField1" }, { PidLidContactUserField2 , "PidLidContactUserField2" }, { PidLidContactUserField3 , "PidLidContactUserField3" }, { PidLidContactUserField4 , "PidLidContactUserField4" }, { PidLidDepartment , "PidLidDepartment" }, { PidLidDistributionListChecksum , "PidLidDistributionListChecksum" }, { PidLidDistributionListMembers , "PidLidDistributionListMembers" }, { PidLidDistributionListName , "PidLidDistributionListName" }, { PidLidDistributionListOneOffMembers , "PidLidDistributionListOneOffMembers" }, { PidLidDistributionListStream , "PidLidDistributionListStream" }, { PidLidEmail1AddressType , "PidLidEmail1AddressType" }, { PidLidEmail1DisplayName , "PidLidEmail1DisplayName" }, { PidLidEmail1EmailAddress , "PidLidEmail1EmailAddress" }, { PidLidEmail1OriginalDisplayName , "PidLidEmail1OriginalDisplayName" }, { PidLidEmail1OriginalEntryId , "PidLidEmail1OriginalEntryId" }, { PidLidEmail1RichTextFormat , "PidLidEmail1RichTextFormat" }, { PidLidEmail2AddressType , "PidLidEmail2AddressType" }, { PidLidEmail2DisplayName , "PidLidEmail2DisplayName" }, { PidLidEmail2EmailAddress , "PidLidEmail2EmailAddress" }, { PidLidEmail2OriginalDisplayName , "PidLidEmail2OriginalDisplayName" }, { PidLidEmail2OriginalEntryId , "PidLidEmail2OriginalEntryId" }, { PidLidEmail2RichTextFormat , "PidLidEmail2RichTextFormat" }, { PidLidEmail3AddressType , "PidLidEmail3AddressType" }, { PidLidEmail3DisplayName , "PidLidEmail3DisplayName" }, { PidLidEmail3EmailAddress , "PidLidEmail3EmailAddress" }, { PidLidEmail3OriginalDisplayName , "PidLidEmail3OriginalDisplayName" }, { PidLidEmail3OriginalEntryId , "PidLidEmail3OriginalEntryId" }, { PidLidEmail3RichTextFormat , "PidLidEmail3RichTextFormat" }, { PidLidEmailList , "PidLidEmailList" }, { PidLidFax1AddressType , "PidLidFax1AddressType" }, { PidLidFax1EmailAddress , "PidLidFax1EmailAddress" }, { PidLidFax1OriginalDisplayName , "PidLidFax1OriginalDisplayName" }, { PidLidFax1OriginalEntryId , "PidLidFax1OriginalEntryId" }, { PidLidFax2AddressType , "PidLidFax2AddressType" }, { PidLidFax2EmailAddress , "PidLidFax2EmailAddress" }, { PidLidFax2OriginalDisplayName , "PidLidFax2OriginalDisplayName" }, { PidLidFax2OriginalEntryId , "PidLidFax2OriginalEntryId" }, { PidLidFax3AddressType , "PidLidFax3AddressType" }, { PidLidFax3EmailAddress , "PidLidFax3EmailAddress" }, { PidLidFax3OriginalDisplayName , "PidLidFax3OriginalDisplayName" }, { PidLidFax3OriginalEntryId , "PidLidFax3OriginalEntryId" }, { PidLidFileUnder , "PidLidFileUnder" }, { PidLidFileUnderId , "PidLidFileUnderId" }, { PidLidFileUnderList , "PidLidFileUnderList" }, { PidLidFreeBusyLocation , "PidLidFreeBusyLocation" }, { PidLidHasPicture , "PidLidHasPicture" }, { PidLidHomeAddress , "PidLidHomeAddress" }, { PidLidHomeAddressCountryCode , "PidLidHomeAddressCountryCode" }, { PidLidHtml , "PidLidHtml" }, { PidLidInstantMessagingAddress , "PidLidInstantMessagingAddress" }, { PidLidOtherAddress , "PidLidOtherAddress" }, { PidLidOtherAddressCountryCode , "PidLidOtherAddressCountryCode" }, { PidLidPostalAddressId , "PidLidPostalAddressId" }, { PidLidReferredBy , "PidLidReferredBy" }, { PidLidWeddingAnniversaryLocal , "PidLidWeddingAnniversaryLocal" }, { PidLidWorkAddress , "PidLidWorkAddress" }, { PidLidWorkAddressCity , "PidLidWorkAddressCity" }, { PidLidWorkAddressCountry , "PidLidWorkAddressCountry" }, { PidLidWorkAddressCountryCode , "PidLidWorkAddressCountryCode" }, { PidLidWorkAddressPostalCode , "PidLidWorkAddressPostalCode" }, { PidLidWorkAddressPostOfficeBox , "PidLidWorkAddressPostOfficeBox" }, { PidLidWorkAddressState , "PidLidWorkAddressState" }, { PidLidYomiCompanyName , "PidLidYomiCompanyName" }, { PidLidYomiFirstName , "PidLidYomiFirstName" }, { PidLidYomiLastName , "PidLidYomiLastName" }, { PidNameInstantMessagingAddress2 , "PidNameInstantMessagingAddress2" }, { PidNameInstantMessagingAddress3 , "PidNameInstantMessagingAddress3" }, { PidLidAllAttendeesString , "PidLidAllAttendeesString" }, { PidLidAllowExternalCheck , "PidLidAllowExternalCheck" }, { PidLidAppointmentAuxiliaryFlags , "PidLidAppointmentAuxiliaryFlags" }, { PidLidAppointmentColor , "PidLidAppointmentColor" }, { PidLidAppointmentCounterProposal , "PidLidAppointmentCounterProposal" }, { PidLidAppointmentDuration , "PidLidAppointmentDuration" }, { PidLidAppointmentEndDate , "PidLidAppointmentEndDate" }, { PidLidAppointmentEndTime , "PidLidAppointmentEndTime" }, { PidLidAppointmentEndWhole , "PidLidAppointmentEndWhole" }, { PidLidAppointmentLastSequence , "PidLidAppointmentLastSequence" }, { PidLidAppointmentNotAllowPropose , "PidLidAppointmentNotAllowPropose" }, { PidLidAppointmentProposalNumber , "PidLidAppointmentProposalNumber" }, { PidLidAppointmentProposedDuration , "PidLidAppointmentProposedDuration" }, { PidLidAppointmentProposedEndWhole , "PidLidAppointmentProposedEndWhole" }, { PidLidAppointmentProposedStartWhole , "PidLidAppointmentProposedStartWhole" }, { PidLidAppointmentRecur , "PidLidAppointmentRecur" }, { PidLidAppointmentReplyName , "PidLidAppointmentReplyName" }, { PidLidAppointmentReplyTime , "PidLidAppointmentReplyTime" }, { PidLidAppointmentSequence , "PidLidAppointmentSequence" }, { PidLidAppointmentSequenceTime , "PidLidAppointmentSequenceTime" }, { PidLidAppointmentStartDate , "PidLidAppointmentStartDate" }, { PidLidAppointmentStartTime , "PidLidAppointmentStartTime" }, { PidLidAppointmentStartWhole , "PidLidAppointmentStartWhole" }, { PidLidAppointmentStateFlags , "PidLidAppointmentStateFlags" }, { PidLidAppointmentSubType , "PidLidAppointmentSubType" }, { PidLidAppointmentTimeZoneDefinitionEndDisplay , "PidLidAppointmentTimeZoneDefinitionEndDisplay" }, { PidLidAppointmentTimeZoneDefinitionRecur , "PidLidAppointmentTimeZoneDefinitionRecur" }, { PidLidAppointmentTimeZoneDefinitionStartDisplay , "PidLidAppointmentTimeZoneDefinitionStartDisplay" }, { PidLidAppointmentUnsendableRecipients , "PidLidAppointmentUnsendableRecipients" }, { PidLidAppointmentUpdateTime , "PidLidAppointmentUpdateTime" }, { PidLidAutoFillLocation , "PidLidAutoFillLocation" }, { PidLidAutoStartCheck , "PidLidAutoStartCheck" }, { PidLidBusyStatus , "PidLidBusyStatus" }, { PidLidCcAttendeesString , "PidLidCcAttendeesString" }, { PidLidChangeHighlight , "PidLidChangeHighlight" }, { PidLidClipEnd , "PidLidClipEnd" }, { PidLidClipStart , "PidLidClipStart" }, { PidLidCollaborateDoc , "PidLidCollaborateDoc" }, { PidLidConferencingCheck , "PidLidConferencingCheck" }, { PidLidConferencingType , "PidLidConferencingType" }, { PidLidDirectory , "PidLidDirectory" }, { PidLidExceptionReplaceTime , "PidLidExceptionReplaceTime" }, { PidLidFExceptionalAttendees , "PidLidFExceptionalAttendees" }, { PidLidFExceptionalBody , "PidLidFExceptionalBody" }, { PidLidFInvited , "PidLidFInvited" }, { PidLidForwardInstance , "PidLidForwardInstance" }, { PidLidForwardNotificationRecipients , "PidLidForwardNotificationRecipients" }, { PidLidFOthersAppointment , "PidLidFOthersAppointment" }, { PidLidInboundICalStream , "PidLidInboundICalStream" }, { PidLidIntendedBusyStatus , "PidLidIntendedBusyStatus" }, { PidLidLinkedTaskItems , "PidLidLinkedTaskItems" }, { PidLidLocation , "PidLidLocation" }, { PidLidMeetingWorkspaceUrl , "PidLidMeetingWorkspaceUrl" }, { PidLidNetShowUrl , "PidLidNetShowUrl" }, { PidLidOnlinePassword , "PidLidOnlinePassword" }, { PidLidOrganizerAlias , "PidLidOrganizerAlias" }, { PidLidOriginalStoreEntryId , "PidLidOriginalStoreEntryId" }, { PidLidOwnerName , "PidLidOwnerName" }, { PidLidRecurrencePattern , "PidLidRecurrencePattern" }, { PidLidRecurrenceType , "PidLidRecurrenceType" }, { PidLidRecurring , "PidLidRecurring" }, { PidLidResponseStatus , "PidLidResponseStatus" }, { PidLidSingleBodyICal , "PidLidSingleBodyICal" }, { PidLidTimeZoneDescription , "PidLidTimeZoneDescription" }, { PidLidTimeZoneStruct , "PidLidTimeZoneStruct" }, { PidLidToAttendeesString , "PidLidToAttendeesString" }, { PidNameAttachmentMacContentType , "PidNameAttachmentMacContentType" }, { PidNameAttachmentMacInfo , "PidNameAttachmentMacInfo" }, { PidLidClientIntent , "PidLidClientIntent" }, { PidLidServerProcessed , "PidLidServerProcessed" }, { PidLidServerProcessingActions , "PidLidServerProcessingActions" }, { PidLidAgingDontAgeMe , "PidLidAgingDontAgeMe" }, { PidLidAutoProcessState , "PidLidAutoProcessState" }, { PidLidBilling , "PidLidBilling" }, { PidLidClassification , "PidLidClassification" }, { PidLidClassificationDescription , "PidLidClassificationDescription" }, { PidLidClassificationGuid , "PidLidClassificationGuid" }, { PidLidClassificationKeep , "PidLidClassificationKeep" }, { PidLidClassified , "PidLidClassified" }, { PidLidCommonEnd , "PidLidCommonEnd" }, { PidLidCommonStart , "PidLidCommonStart" }, { PidLidCompanies , "PidLidCompanies" }, { PidLidContactLinkEntry , "PidLidContactLinkEntry" }, { PidLidContactLinkName , "PidLidContactLinkName" }, { PidLidContactLinkSearchKey , "PidLidContactLinkSearchKey" }, { PidLidContacts , "PidLidContacts" }, { PidLidConversationActionLastAppliedTime , "PidLidConversationActionLastAppliedTime" }, { PidLidConversationActionMaxDeliveryTime , "PidLidConversationActionMaxDeliveryTime" }, { PidLidConversationActionMoveFolderEid , "PidLidConversationActionMoveFolderEid" }, { PidLidConversationActionMoveStoreEid , "PidLidConversationActionMoveStoreEid" }, { PidLidConversationActionVersion , "PidLidConversationActionVersion" }, { PidLidConversationProcessed , "PidLidConversationProcessed" }, { PidLidCurrentVersion , "PidLidCurrentVersion" }, { PidLidCurrentVersionName , "PidLidCurrentVersionName" }, { PidLidDayOfMonth , "PidLidDayOfMonth" }, { PidLidFlagRequest , "PidLidFlagRequest" }, { PidLidFlagString , "PidLidFlagString" }, { PidLidICalendarDayOfWeekMask , "PidLidICalendarDayOfWeekMask" }, { PidLidInfoPathFormName , "PidLidInfoPathFormName" }, { PidLidInternetAccountName , "PidLidInternetAccountName" }, { PidLidInternetAccountStamp , "PidLidInternetAccountStamp" }, { PidLidMonthOfYear , "PidLidMonthOfYear" }, { PidLidNoEndDateFlag , "PidLidNoEndDateFlag" }, { PidLidNonSendableBcc , "PidLidNonSendableBcc" }, { PidLidNonSendableCc , "PidLidNonSendableCc" }, { PidLidNonSendableTo , "PidLidNonSendableTo" }, { PidLidNonSendBccTrackStatus , "PidLidNonSendBccTrackStatus" }, { PidLidNonSendCcTrackStatus , "PidLidNonSendCcTrackStatus" }, { PidLidNonSendToTrackStatus , "PidLidNonSendToTrackStatus" }, { PidLidOccurrences , "PidLidOccurrences" }, { PidLidPrivate , "PidLidPrivate" }, { PidLidPromptSendUpdate , "PidLidPromptSendUpdate" }, { PidLidRecurrenceDuration , "PidLidRecurrenceDuration" }, { PidLidReferenceEntryId , "PidLidReferenceEntryId" }, { PidLidReminderDelta , "PidLidReminderDelta" }, { PidLidReminderFileParameter , "PidLidReminderFileParameter" }, { PidLidReminderOverride , "PidLidReminderOverride" }, { PidLidReminderPlaySound , "PidLidReminderPlaySound" }, { PidLidReminderSet , "PidLidReminderSet" }, { PidLidReminderSignalTime , "PidLidReminderSignalTime" }, { PidLidReminderTime , "PidLidReminderTime" }, { PidLidReminderTimeDate , "PidLidReminderTimeDate" }, { PidLidReminderTimeTime , "PidLidReminderTimeTime" }, { PidLidReminderType , "PidLidReminderType" }, { PidLidRemoteStatus , "PidLidRemoteStatus" }, { PidLidSideEffects , "PidLidSideEffects" }, { PidLidSmartNoAttach , "PidLidSmartNoAttach" }, { PidLidSpamOriginalFolder , "PidLidSpamOriginalFolder" }, { PidLidTaskGlobalId , "PidLidTaskGlobalId" }, { PidLidTaskMode , "PidLidTaskMode" }, { PidLidToDoOrdinalDate , "PidLidToDoOrdinalDate" }, { PidLidToDoSubOrdinal , "PidLidToDoSubOrdinal" }, { PidLidToDoTitle , "PidLidToDoTitle" }, { PidLidUseTnef , "PidLidUseTnef" }, { PidLidValidFlagStringProof , "PidLidValidFlagStringProof" }, { PidLidVerbResponse , "PidLidVerbResponse" }, { PidLidVerbStream , "PidLidVerbStream" }, { PidLidLogDocumentPosted , "PidLidLogDocumentPosted" }, { PidLidLogDocumentPrinted , "PidLidLogDocumentPrinted" }, { PidLidLogDocumentRouted , "PidLidLogDocumentRouted" }, { PidLidLogDocumentSaved , "PidLidLogDocumentSaved" }, { PidLidLogDuration , "PidLidLogDuration" }, { PidLidLogEnd , "PidLidLogEnd" }, { PidLidLogFlags , "PidLidLogFlags" }, { PidLidLogStart , "PidLidLogStart" }, { PidLidLogType , "PidLidLogType" }, { PidLidLogTypeDesc , "PidLidLogTypeDesc" }, { PidLidAppointmentMessageClass , "PidLidAppointmentMessageClass" }, { PidLidAttendeeCriticalChange , "PidLidAttendeeCriticalChange" }, { PidLidCalendarType , "PidLidCalendarType" }, { PidLidCleanGlobalObjectId , "PidLidCleanGlobalObjectId" }, { PidLidDayInterval , "PidLidDayInterval" }, { PidLidDelegateMail , "PidLidDelegateMail" }, { PidLidEndRecurrenceDate , "PidLidEndRecurrenceDate" }, { PidLidEndRecurrenceTime , "PidLidEndRecurrenceTime" }, { PidLidGlobalObjectId , "PidLidGlobalObjectId" }, { PidLidIsException , "PidLidIsException" }, { PidLidIsRecurring , "PidLidIsRecurring" }, { PidLidIsSilent , "PidLidIsSilent" }, { PidLidMeetingType , "PidLidMeetingType" }, { PidLidMonthInterval , "PidLidMonthInterval" }, { PidLidMonthOfYearMask , "PidLidMonthOfYearMask" }, { PidLidOldLocation , "PidLidOldLocation" }, { PidLidOldRecurrenceType , "PidLidOldRecurrenceType" }, { PidLidOldWhenEndWhole , "PidLidOldWhenEndWhole" }, { PidLidOldWhenStartWhole , "PidLidOldWhenStartWhole" }, { PidLidOptionalAttendees , "PidLidOptionalAttendees" }, { PidLidOwnerCriticalChange , "PidLidOwnerCriticalChange" }, { PidLidRequiredAttendees , "PidLidRequiredAttendees" }, { PidLidResourceAttendees , "PidLidResourceAttendees" }, { PidLidStartRecurrenceDate , "PidLidStartRecurrenceDate" }, { PidLidStartRecurrenceTime , "PidLidStartRecurrenceTime" }, { PidLidTimeZone , "PidLidTimeZone" }, { PidLidWeekInterval , "PidLidWeekInterval" }, { PidLidWhere , "PidLidWhere" }, { PidLidYearInterval , "PidLidYearInterval" }, { PidNameOriginalSpamConfidenceLevel , "PidNameOriginalSpamConfidenceLevel" }, { PidLidNoteColor , "PidLidNoteColor" }, { PidLidNoteHeight , "PidLidNoteHeight" }, { PidLidNoteWidth , "PidLidNoteWidth" }, { PidLidNoteX , "PidLidNoteX" }, { PidLidNoteY , "PidLidNoteY" }, { PidLidPostRssChannel , "PidLidPostRssChannel" }, { PidLidPostRssChannelLink , "PidLidPostRssChannelLink" }, { PidLidPostRssItemGuid , "PidLidPostRssItemGuid" }, { PidLidPostRssItemHash , "PidLidPostRssItemHash" }, { PidLidPostRssItemLink , "PidLidPostRssItemLink" }, { PidLidPostRssItemXml , "PidLidPostRssItemXml" }, { PidLidPostRssSubscription , "PidLidPostRssSubscription" }, { PidLidSharingAnonymity , "PidLidSharingAnonymity" }, { PidLidSharingBindingEntryId , "PidLidSharingBindingEntryId" }, { PidLidSharingBrowseUrl , "PidLidSharingBrowseUrl" }, { PidLidSharingCapabilities , "PidLidSharingCapabilities" }, { PidLidSharingConfigurationUrl , "PidLidSharingConfigurationUrl" }, { PidLidSharingDataRangeEnd , "PidLidSharingDataRangeEnd" }, { PidLidSharingDataRangeStart , "PidLidSharingDataRangeStart" }, { PidLidSharingDetail , "PidLidSharingDetail" }, { PidLidSharingExtensionXml , "PidLidSharingExtensionXml" }, { PidLidSharingFilter , "PidLidSharingFilter" }, { PidLidSharingFlags , "PidLidSharingFlags" }, { PidLidSharingFlavor , "PidLidSharingFlavor" }, { PidLidSharingFolderEntryId , "PidLidSharingFolderEntryId" }, { PidLidSharingIndexEntryId , "PidLidSharingIndexEntryId" }, { PidLidSharingInitiatorEntryId , "PidLidSharingInitiatorEntryId" }, { PidLidSharingInitiatorName , "PidLidSharingInitiatorName" }, { PidLidSharingInitiatorSmtp , "PidLidSharingInitiatorSmtp" }, { PidLidSharingInstanceGuid , "PidLidSharingInstanceGuid" }, { PidLidSharingLastAutoSyncTime , "PidLidSharingLastAutoSyncTime" }, { PidLidSharingLastSyncTime , "PidLidSharingLastSyncTime" }, { PidLidSharingLocalComment , "PidLidSharingLocalComment" }, { PidLidSharingLocalLastModificationTime , "PidLidSharingLocalLastModificationTime" }, { PidLidSharingLocalName , "PidLidSharingLocalName" }, { PidLidSharingLocalPath , "PidLidSharingLocalPath" }, { PidLidSharingLocalStoreUid , "PidLidSharingLocalStoreUid" }, { PidLidSharingLocalType , "PidLidSharingLocalType" }, { PidLidSharingLocalUid , "PidLidSharingLocalUid" }, { PidLidSharingOriginalMessageEntryId , "PidLidSharingOriginalMessageEntryId" }, { PidLidSharingParentBindingEntryId , "PidLidSharingParentBindingEntryId" }, { PidLidSharingParticipants , "PidLidSharingParticipants" }, { PidLidSharingPermissions , "PidLidSharingPermissions" }, { PidLidSharingProviderExtension , "PidLidSharingProviderExtension" }, { PidLidSharingProviderGuid , "PidLidSharingProviderGuid" }, { PidLidSharingProviderName , "PidLidSharingProviderName" }, { PidLidSharingProviderUrl , "PidLidSharingProviderUrl" }, { PidLidSharingRangeEnd , "PidLidSharingRangeEnd" }, { PidLidSharingRangeStart , "PidLidSharingRangeStart" }, { PidLidSharingReciprocation , "PidLidSharingReciprocation" }, { PidLidSharingRemoteByteSize , "PidLidSharingRemoteByteSize" }, { PidLidSharingRemoteComment , "PidLidSharingRemoteComment" }, { PidLidSharingRemoteCrc , "PidLidSharingRemoteCrc" }, { PidLidSharingRemoteLastModificationTime , "PidLidSharingRemoteLastModificationTime" }, { PidLidSharingRemoteMessageCount , "PidLidSharingRemoteMessageCount" }, { PidLidSharingRemoteName , "PidLidSharingRemoteName" }, { PidLidSharingRemotePass , "PidLidSharingRemotePass" }, { PidLidSharingRemotePath , "PidLidSharingRemotePath" }, { PidLidSharingRemoteStoreUid , "PidLidSharingRemoteStoreUid" }, { PidLidSharingRemoteType , "PidLidSharingRemoteType" }, { PidLidSharingRemoteUid , "PidLidSharingRemoteUid" }, { PidLidSharingRemoteUser , "PidLidSharingRemoteUser" }, { PidLidSharingRemoteVersion , "PidLidSharingRemoteVersion" }, { PidLidSharingResponseTime , "PidLidSharingResponseTime" }, { PidLidSharingResponseType , "PidLidSharingResponseType" }, { PidLidSharingRoamLog , "PidLidSharingRoamLog" }, { PidLidSharingStart , "PidLidSharingStart" }, { PidLidSharingStatus , "PidLidSharingStatus" }, { PidLidSharingStop , "PidLidSharingStop" }, { PidLidSharingSyncFlags , "PidLidSharingSyncFlags" }, { PidLidSharingSyncInterval , "PidLidSharingSyncInterval" }, { PidLidSharingTimeToLive , "PidLidSharingTimeToLive" }, { PidLidSharingTimeToLiveAuto , "PidLidSharingTimeToLiveAuto" }, { PidLidSharingWorkingHoursDays , "PidLidSharingWorkingHoursDays" }, { PidLidSharingWorkingHoursEnd , "PidLidSharingWorkingHoursEnd" }, { PidLidSharingWorkingHoursStart , "PidLidSharingWorkingHoursStart" }, { PidLidSharingWorkingHoursTimeZone , "PidLidSharingWorkingHoursTimeZone" }, { PidLidPercentComplete , "PidLidPercentComplete" }, { PidLidTaskAcceptanceState , "PidLidTaskAcceptanceState" }, { PidLidTaskAccepted , "PidLidTaskAccepted" }, { PidLidTaskActualEffort , "PidLidTaskActualEffort" }, { PidLidTaskAssigner , "PidLidTaskAssigner" }, { PidLidTaskAssigners , "PidLidTaskAssigners" }, { PidLidTaskComplete , "PidLidTaskComplete" }, { PidLidTaskCustomFlags , "PidLidTaskCustomFlags" }, { PidLidTaskDateCompleted , "PidLidTaskDateCompleted" }, { PidLidTaskDeadOccurrence , "PidLidTaskDeadOccurrence" }, { PidLidTaskDueDate , "PidLidTaskDueDate" }, { PidLidTaskEstimatedEffort , "PidLidTaskEstimatedEffort" }, { PidLidTaskFCreator , "PidLidTaskFCreator" }, { PidLidTaskFFixOffline , "PidLidTaskFFixOffline" }, { PidLidTaskFRecurring , "PidLidTaskFRecurring" }, { PidLidTaskHistory , "PidLidTaskHistory" }, { PidLidTaskLastDelegate , "PidLidTaskLastDelegate" }, { PidLidTaskLastUpdate , "PidLidTaskLastUpdate" }, { PidLidTaskLastUser , "PidLidTaskLastUser" }, { PidLidTaskMultipleRecipients , "PidLidTaskMultipleRecipients" }, { PidLidTaskNoCompute , "PidLidTaskNoCompute" }, { PidLidTaskOrdinal , "PidLidTaskOrdinal" }, { PidLidTaskOwner , "PidLidTaskOwner" }, { PidLidTaskOwnership , "PidLidTaskOwnership" }, { PidLidTaskRecurrence , "PidLidTaskRecurrence" }, { PidLidTaskResetReminder , "PidLidTaskResetReminder" }, { PidLidTaskRole , "PidLidTaskRole" }, { PidLidTaskStartDate , "PidLidTaskStartDate" }, { PidLidTaskState , "PidLidTaskState" }, { PidLidTaskStatus , "PidLidTaskStatus" }, { PidLidTaskStatusOnComplete , "PidLidTaskStatusOnComplete" }, { PidLidTaskUpdates , "PidLidTaskUpdates" }, { PidLidTaskVersion , "PidLidTaskVersion" }, { PidLidTeamTask , "PidLidTeamTask" }, { PidLidTrustRecipientHighlights , "PidLidTrustRecipientHighlights" }, { PidNameAudioNotes , "PidNameAudioNotes" }, { PidNameAutomaticSpeechRecognitionData , "PidNameAutomaticSpeechRecognitionData" }, { PidNameOutlookProtectionRuleTimestamp , "PidNameOutlookProtectionRuleTimestamp" }, { PidNameXUnifiedMessagingPartnerAssignedId , "PidNameXUnifiedMessagingPartnerAssignedId" }, { PidNameXUnifiedMessagingPartnerContent , "PidNameXUnifiedMessagingPartnerContent" }, { PidNameXUnifiedMessagingPartnerContext , "PidNameXUnifiedMessagingPartnerContext" }, { PidNameXUnifiedMessagingPartnerStatus , "PidNameXUnifiedMessagingPartnerStatus" }, { PidNameAcceptLanguage , "PidNameAcceptLanguage" }, { PidNameApprovalAllowedDecisionMakers , "PidNameApprovalAllowedDecisionMakers" }, { PidNameApprovalRequestor , "PidNameApprovalRequestor" }, { PidNameApproved , "PidNameApproved" }, { PidNameAuthenticatedAs , "PidNameAuthenticatedAs" }, { PidNameAuthenticatedDomain , "PidNameAuthenticatedDomain" }, { PidNameAuthenticatedMechanism , "PidNameAuthenticatedMechanism" }, { PidNameAuthenticatedSource , "PidNameAuthenticatedSource" }, { PidNameBcc , "PidNameBcc" }, { PidNameCc , "PidNameCc" }, { PidNameContentBase , "PidNameContentBase" }, { PidNameContentClass , "PidNameContentClass" }, { PidNameContentDisposition , "PidNameContentDisposition" }, { PidNameContentID , "PidNameContentID" }, { PidNameContentLanguage , "PidNameContentLanguage" }, { PidNameContentLocation , "PidNameContentLocation" }, { PidNameContentTransferEncoding , "PidNameContentTransferEncoding" }, { PidNameContentType , "PidNameContentType" }, { PidNameControl , "PidNameControl" }, { PidNameCrossReference , "PidNameCrossReference" }, { PidNameDisposition , "PidNameDisposition" }, { PidNameDispositionNotificationTo , "PidNameDispositionNotificationTo" }, { PidNameDistribution , "PidNameDistribution" }, { PidNameExpires , "PidNameExpires" }, { PidNameExpiryDate , "PidNameExpiryDate" }, { PidNameFollowupTo , "PidNameFollowupTo" }, { PidNameFrom , "PidNameFrom" }, { PidNameImportance , "PidNameImportance" }, { PidNameInReplyTo , "PidNameInReplyTo" }, { PidNameInternetComment , "PidNameInternetComment" }, { PidNameInternetKeywords , "PidNameInternetKeywords" }, { PidNameInternetSubject , "PidNameInternetSubject" }, { PidNameLines , "PidNameLines" }, { PidNameMessageId , "PidNameMessageId" }, { PidNameMimeVersion , "PidNameMimeVersion" }, { PidNameNewsgroups , "PidNameNewsgroups" }, { PidNameNntpPostingHost , "PidNameNntpPostingHost" }, { PidNameOrganization , "PidNameOrganization" }, { PidNameOriginalRecipient , "PidNameOriginalRecipient" }, { PidNameOutlookProtectionRuleOverridden , "PidNameOutlookProtectionRuleOverridden" }, { PidNameOutlookProtectionRuleVersion , "PidNameOutlookProtectionRuleVersion" }, { PidNamePath , "PidNamePath" }, { PidNamePostingVersion , "PidNamePostingVersion" }, { PidNamePriority , "PidNamePriority" }, { PidNameReceived , "PidNameReceived" }, { PidNameReferences , "PidNameReferences" }, { PidNameRelayVersion , "PidNameRelayVersion" }, { PidNameReplyBy , "PidNameReplyBy" }, { PidNameReplyTo , "PidNameReplyTo" }, { PidNameReturnPath , "PidNameReturnPath" }, { PidNameReturnReceiptTo , "PidNameReturnReceiptTo" }, { PidNameRightsProtectMessage , "PidNameRightsProtectMessage" }, { PidNameSender , "PidNameSender" }, { PidNameSensitivity , "PidNameSensitivity" }, { PidNameSummary , "PidNameSummary" }, { PidNameThreadIndex , "PidNameThreadIndex" }, { PidNameThreadTopic , "PidNameThreadTopic" }, { PidNameTo , "PidNameTo" }, { PidNameXCallId , "PidNameXCallId" }, { PidNameXFaxNumberOfPages , "PidNameXFaxNumberOfPages" }, { PidNameXMailer , "PidNameXMailer" }, { PidNameXMessageCompleted , "PidNameXMessageCompleted" }, { PidNameXMessageFlag , "PidNameXMessageFlag" }, { PidNameXRequireProtectedPlayOnPhone , "PidNameXRequireProtectedPlayOnPhone" }, { PidNameXSenderTelephoneNumber , "PidNameXSenderTelephoneNumber" }, { PidNameXSharingBrowseUrl , "PidNameXSharingBrowseUrl" }, { PidNameXSharingCapabilities , "PidNameXSharingCapabilities" }, { PidNameXSharingConfigUrl , "PidNameXSharingConfigUrl" }, { PidNameXSharingExendedCaps , "PidNameXSharingExendedCaps" }, { PidNameXSharingFlavor , "PidNameXSharingFlavor" }, { PidNameXSharingInstanceGuid , "PidNameXSharingInstanceGuid" }, { PidNameXSharingLocalType , "PidNameXSharingLocalType" }, { PidNameXSharingProviderGuid , "PidNameXSharingProviderGuid" }, { PidNameXSharingProviderName , "PidNameXSharingProviderName" }, { PidNameXSharingProviderUrl , "PidNameXSharingProviderUrl" }, { PidNameXSharingRemoteName , "PidNameXSharingRemoteName" }, { PidNameXSharingRemotePath , "PidNameXSharingRemotePath" }, { PidNameXSharingRemoteStoreUid , "PidNameXSharingRemoteStoreUid" }, { PidNameXSharingRemoteType , "PidNameXSharingRemoteType" }, { PidNameXSharingRemoteUid , "PidNameXSharingRemoteUid" }, { PidNameXUnsent , "PidNameXUnsent" }, { PidNameXVoiceMessageAttachmentOrder , "PidNameXVoiceMessageAttachmentOrder" }, { PidNameXVoiceMessageDuration , "PidNameXVoiceMessageDuration" }, { PidNameXVoiceMessageSenderName , "PidNameXVoiceMessageSenderName" }, { PidLidCategories , "PidLidCategories" }, { PidNameApplicationName , "PidNameApplicationName" }, { PidNameAuthor , "PidNameAuthor" }, { PidNameByteCount , "PidNameByteCount" }, { PidNameCalendarAttendeeRole , "PidNameCalendarAttendeeRole" }, { PidNameCalendarBusystatus , "PidNameCalendarBusystatus" }, { PidNameCalendarContact , "PidNameCalendarContact" }, { PidNameCalendarContactUrl , "PidNameCalendarContactUrl" }, { PidNameCalendarCreated , "PidNameCalendarCreated" }, { PidNameCalendarDescriptionUrl , "PidNameCalendarDescriptionUrl" }, { PidNameCalendarDuration , "PidNameCalendarDuration" }, { PidNameCalendarExceptionDate , "PidNameCalendarExceptionDate" }, { PidNameCalendarExceptionRule , "PidNameCalendarExceptionRule" }, { PidNameCalendarGeoLatitude , "PidNameCalendarGeoLatitude" }, { PidNameCalendarGeoLongitude , "PidNameCalendarGeoLongitude" }, { PidNameCalendarInstanceType , "PidNameCalendarInstanceType" }, { PidNameCalendarIsOrganizer , "PidNameCalendarIsOrganizer" }, { PidNameCalendarLastModified , "PidNameCalendarLastModified" }, { PidNameCalendarLocationUrl , "PidNameCalendarLocationUrl" }, { PidNameCalendarMeetingStatus , "PidNameCalendarMeetingStatus" }, { PidNameCalendarMethod , "PidNameCalendarMethod" }, { PidNameCalendarProductId , "PidNameCalendarProductId" }, { PidNameCalendarRecurrenceIdRange , "PidNameCalendarRecurrenceIdRange" }, { PidNameCalendarReminderOffset , "PidNameCalendarReminderOffset" }, { PidNameCalendarResources , "PidNameCalendarResources" }, { PidNameCalendarRsvp , "PidNameCalendarRsvp" }, { PidNameCalendarSequence , "PidNameCalendarSequence" }, { PidNameCalendarTimeZone , "PidNameCalendarTimeZone" }, { PidNameCalendarTimeZoneId , "PidNameCalendarTimeZoneId" }, { PidNameCalendarTransparent , "PidNameCalendarTransparent" }, { PidNameCalendarUid , "PidNameCalendarUid" }, { PidNameCalendarVersion , "PidNameCalendarVersion" }, { PidNameCategory , "PidNameCategory" }, { PidNameCharacterCount , "PidNameCharacterCount" }, { PidNameComments , "PidNameComments" }, { PidNameCompany , "PidNameCompany" }, { PidNameContactsAlternateRecipient , "PidNameContactsAlternateRecipient" }, { PidNameContactsCountry , "PidNameContactsCountry" }, { PidNameContactsEmail1 , "PidNameContactsEmail1" }, { PidNameContactsEmail2 , "PidNameContactsEmail2" }, { PidNameContactsEmail3 , "PidNameContactsEmail3" }, { PidNameContactsFileAs , "PidNameContactsFileAs" }, { PidNameContactsFileasId , "PidNameContactsFileasId" }, { PidNameContactsHomeLatitude , "PidNameContactsHomeLatitude" }, { PidNameContactsHomeLongitude , "PidNameContactsHomeLongitude" }, { PidNameContactsHomeTimeZone , "PidNameContactsHomeTimeZone" }, { PidNameContactsMapUrl , "PidNameContactsMapUrl" }, { PidNameContactsOtherCountryCode , "PidNameContactsOtherCountryCode" }, { PidNameContactsOtherPager , "PidNameContactsOtherPager" }, { PidNameContactsOtherTimeZone , "PidNameContactsOtherTimeZone" }, { PidNameContactsProxyAddresses , "PidNameContactsProxyAddresses" }, { PidNameContactsSecretaryUrl , "PidNameContactsSecretaryUrl" }, { PidNameContactsSourceUrl , "PidNameContactsSourceUrl" }, { PidNameCreateDateTimeReadOnly , "PidNameCreateDateTimeReadOnly" }, { PidNameDavGetContentType , "PidNameDavGetContentType" }, { PidNameDavId , "PidNameDavId" }, { PidNameDavIsCollection , "PidNameDavIsCollection" }, { PidNameDavIsStructuredDocument , "PidNameDavIsStructuredDocument" }, { PidNameDavParentName , "PidNameDavParentName" }, { PidNameDavResourceType , "PidNameDavResourceType" }, { PidNameDavSearchRequest , "PidNameDavSearchRequest" }, { PidNameDavSearchType , "PidNameDavSearchType" }, { PidNameDavUid , "PidNameDavUid" }, { PidNameDocumentParts , "PidNameDocumentParts" }, { PidNameEditTime , "PidNameEditTime" }, { PidNameExchangeIntendedBusyStatus , "PidNameExchangeIntendedBusyStatus" }, { PidNameExchangeJunkEmailMoveStamp , "PidNameExchangeJunkEmailMoveStamp" }, { PidNameExchangeModifyExceptionStructure , "PidNameExchangeModifyExceptionStructure" }, { PidNameExchangeMsexchembdefaultmailfolder , "PidNameExchangeMsexchembdefaultmailfolder" }, { PidNameExchangeMsexchembdefaultmailfoldertype , "PidNameExchangeMsexchembdefaultmailfoldertype" }, { PidNameExchangeNoModifyExceptions , "PidNameExchangeNoModifyExceptions" }, { PidNameExchangePatternEnd , "PidNameExchangePatternEnd" }, { PidNameExchangePatternStart , "PidNameExchangePatternStart" }, { PidNameExchangePublicFolderEmailAddress , "PidNameExchangePublicFolderEmailAddress" }, { PidNameExchangeReminderInterval , "PidNameExchangeReminderInterval" }, { PidNameExchDatabaseSchema , "PidNameExchDatabaseSchema" }, { PidNameExchDataExpectedContentClass , "PidNameExchDataExpectedContentClass" }, { PidNameExchDataSchemaCollectionReference , "PidNameExchDataSchemaCollectionReference" }, { PidNameHeadingPairs , "PidNameHeadingPairs" }, { PidNameHiddenCount , "PidNameHiddenCount" }, { PidNameHttpmailCalendar , "PidNameHttpmailCalendar" }, { PidNameHttpmailCc , "PidNameHttpmailCc" }, { PidNameHttpmailContacts , "PidNameHttpmailContacts" }, { PidNameHttpmailContentMediaType , "PidNameHttpmailContentMediaType" }, { PidNameHttpmailFrom , "PidNameHttpmailFrom" }, { PidNameHttpmailFromEmail , "PidNameHttpmailFromEmail" }, { PidNameHttpmailHtmlDescription , "PidNameHttpmailHtmlDescription" }, { PidNameHttpmailOutbox , "PidNameHttpmailOutbox" }, { PidNameHttpmailSendMessage , "PidNameHttpmailSendMessage" }, { PidNameHttpmailSubmitted , "PidNameHttpmailSubmitted" }, { PidNameHttpmailTo , "PidNameHttpmailTo" }, { PidNameICalendarRecurrenceDate , "PidNameICalendarRecurrenceDate" }, { PidNameICalendarRecurrenceRule , "PidNameICalendarRecurrenceRule" }, { PidNameKeywords , "PidNameKeywords" }, { PidNameLastAuthor , "PidNameLastAuthor" }, { PidNameLastPrinted , "PidNameLastPrinted" }, { PidNameLastSaveDateTime , "PidNameLastSaveDateTime" }, { PidNameLineCount , "PidNameLineCount" }, { PidNameLinksDirty , "PidNameLinksDirty" }, { PidNameMailSubmissionUri , "PidNameMailSubmissionUri" }, { PidNameManager , "PidNameManager" }, { PidNameMultimediaClipCount , "PidNameMultimediaClipCount" }, { PidNameNoteCount , "PidNameNoteCount" }, { PidNameOMSAccountGuid , "PidNameOMSAccountGuid" }, { PidNameOMSMobileModel , "PidNameOMSMobileModel" }, { PidNameOMSScheduleTime , "PidNameOMSScheduleTime" }, { PidNameOMSServiceType , "PidNameOMSServiceType" }, { PidNameOMSSourceType , "PidNameOMSSourceType" }, { PidNamePageCount , "PidNamePageCount" }, { PidNameParagraphCount , "PidNameParagraphCount" }, { PidNamePhishingStamp , "PidNamePhishingStamp" }, { PidNamePresentationFormat , "PidNamePresentationFormat" }, { PidNameQuarantineOriginalSender , "PidNameQuarantineOriginalSender" }, { PidNameRevisionNumber , "PidNameRevisionNumber" }, { PidNameRightsManagementLicense , "PidNameRightsManagementLicense" }, { PidNameScale , "PidNameScale" }, { PidNameSecurity , "PidNameSecurity" }, { PidNameSlideCount , "PidNameSlideCount" }, { PidNameSubject , "PidNameSubject" }, { PidNameTemplate , "PidNameTemplate" }, { PidNameThumbnail , "PidNameThumbnail" }, { PidNameTitle , "PidNameTitle" }, { PidNameWordCount , "PidNameWordCount" }, { 0x00000000 , "NULL" } }; #endif /* !MAPI_NAMEID_PRIVATE_H__ */ openchange-2.0/libmapi/mapi_notification.h000066400000000000000000000037751223057412600207620ustar00rootroot00000000000000/* OpenChange MAPI implementation. Copyright (C) Julien Kerihuel 2007. This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see . */ #ifndef __MAPI_NOTIFICATION_H__ #define __MAPI_NOTIFICATION_H__ /* notification which takes: * - ulEvenType = type of notification * - void * = notification data * - void * = private data pointer */ typedef int (*mapi_notify_callback_t)(uint16_t, void *, void *); typedef int (*mapi_notify_continue_callback_t)(void *); struct notifications { uint32_t ulConnection; /* connection number */ uint32_t NotificationFlags; /* events mask associated */ mapi_id_t parentID; /* parent EntryID == FID here */ mapi_notify_callback_t callback; /* callback to run when */ void *private_data; /* private data for the callback */ struct mapi_object obj_notif; /* notification object */ struct notifications *prev; struct notifications *next; }; struct mapi_notify_ctx { struct NOTIFKEY key; /* unique identifier */ int fd; /* UDP socket file descriptor */ struct sockaddr *addr; struct notifications *notifications; }; struct mapi_notify_continue_callback_data { mapi_notify_continue_callback_t callback; /* Consulted for continuing processing events*/ void *data; /* Data for callback */ struct timeval tv; /* Timeout for Select call */ }; #define DFLT_NOTIF_PORT 2500 #endif /*!__MAPI_NOTIFICATION_H__ */ openchange-2.0/libmapi/mapi_object.c000066400000000000000000000235421223057412600175270ustar00rootroot00000000000000/* OpenChange MAPI implementation. Copyright (C) Fabien Le Mentec 2007. Copyright (C) Julien Kerihuel 2007-2011. This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see . */ #include "libmapi/libmapi.h" #include "libmapi/libmapi_private.h" /** \file mapi_object.c \brief mapi_object_t support functions */ /* FIXME: mapi_object functions should return error codes */ /** keep intern to this file */ #define INVALID_HANDLE_VALUE 0xffffffff /** \details Reset a MAPI object structure \param obj pointer on the MAPI object to reset */ static void mapi_object_reset(mapi_object_t *obj) { obj->handle = INVALID_HANDLE_VALUE; obj->logon_id = 0; obj->store = false; obj->id = 0; obj->session = NULL; obj->private_data = NULL; } /** \details Initialize MAPI object This function is required to be called before any manipulation of this MAPI object. \param obj the object to initialize \return MAPI_E_SUCCESS on success, otherwise MAPI error. \note Developers may also call GetLastError() to retrieve the last MAPI error code. Possible MAPI error codes are: - MAPI_E_NOT_INITIALIZED: MAPI subsystem has not been initialized. \sa mapi_object_release */ _PUBLIC_ enum MAPISTATUS mapi_object_init(mapi_object_t *obj) { mapi_object_reset(obj); return MAPI_E_SUCCESS; } /** \details Release MAPI object This function is required to be called when this MAPI object is no longer required. \param obj pointer on the MAPI object to release \sa mapi_object_initialize, Release */ _PUBLIC_ void mapi_object_release(mapi_object_t *obj) { enum MAPISTATUS retval; if (!obj) return; if (obj->handle == INVALID_HANDLE_VALUE) return; retval = Release(obj); if (retval != MAPI_E_SUCCESS) { DEBUG(1, ("Release has failed")); } if (obj->private_data) { talloc_free(obj->private_data); } if (obj->store == true && obj->session) { obj->session->logon_ids[obj->logon_id] = 0; } mapi_object_reset(obj); } /** \details Check if the supplied object has a valid handle \param obj pointer on the MAPI object to test \return 0 on success, otherwise 1 */ int mapi_object_is_invalid(mapi_object_t *obj) { if (mapi_object_get_handle(obj) == INVALID_HANDLE_VALUE) { return 1; } return MAPI_E_SUCCESS; } /** \details Copy MAPI object This function copies mapi_object data from source to destination. \param dst pointer on the destination MAPI object \param src pointer on the source MAPI object \return MAPI_E_SUCCESS on success, otherwise MAPI_E_NOT_INITIALIZED */ _PUBLIC_ enum MAPISTATUS mapi_object_copy(mapi_object_t *dst, mapi_object_t *src) { mapi_object_reset(dst); OPENCHANGE_RETVAL_IF(!dst || !src, MAPI_E_NOT_INITIALIZED, NULL); dst->id = src->id; dst->handle = src->handle; dst->private_data = src->private_data; dst->logon_id = src->logon_id; dst->session = src->session; return MAPI_E_SUCCESS; } /** \details Retrieve the session associated to the MAPI object \param obj the object to get the session for \return pointer on a MAPI session on success, otherwise NULL */ _PUBLIC_ struct mapi_session *mapi_object_get_session(mapi_object_t *obj) { if (!obj) return NULL; if (!obj->session) return NULL; return obj->session; } /** \details Set the session for a given MAPI object \param obj pointer on the object to set the session for \param session pointer on the MAPI session to associate to the MAPI object */ _PUBLIC_ void mapi_object_set_session(mapi_object_t *obj, struct mapi_session *session) { if (obj) { obj->session = session; } } /** \details Retrieve an object ID for a given MAPI object \param obj pointer on the MAPI object to get the ID for \return the object ID, or 0xFFFFFFFFFFFFFFFF if the object does not exist */ _PUBLIC_ mapi_id_t mapi_object_get_id(mapi_object_t *obj) { return (!obj) ? -1 : obj->id; } /** \details Set the id for a given MAPI object \param obj pointer on the MAPI object to set the session for \param id Identifier to set to the object obj */ void mapi_object_set_id(mapi_object_t *obj, mapi_id_t id) { obj->id = id; } /** \details Set the logon id for a given MAPI object \param obj pointer to the object to set the logon id for \param logon_id the logon identifier to associate to the MAPI object */ _PUBLIC_ void mapi_object_set_logon_id(mapi_object_t *obj, uint8_t logon_id) { if (obj) { obj->logon_id = logon_id; } } /** \details Retrieve the logon id for a given MAPI object \param obj pointer to the object to retrieve the logon id from \param logon_id pointer to a variable to store the logon id \return MAPI_E_SUCCESS on success, otherwise MAPI error. */ _PUBLIC_ enum MAPISTATUS mapi_object_get_logon_id(mapi_object_t *obj, uint8_t *logon_id) { if (!obj || !logon_id) return MAPI_E_INVALID_PARAMETER; *logon_id = obj->logon_id; return MAPI_E_SUCCESS; } /** \details Mark a MAPI object as a store object \param obj pointer to the object to set the store boolean for */ _PUBLIC_ void mapi_object_set_logon_store(mapi_object_t *obj) { if (obj) { obj->store = true; } } /** \details Retrieve the handle associated to a MAPI object \param obj pointer on the MAPI object to retrieve the handle from \return a valid MAPI object handle on success, otherwise 0xFFFFFFFF. */ mapi_handle_t mapi_object_get_handle(mapi_object_t *obj) { return (!obj) ? 0xFFFFFFFF : obj->handle; } /** \details Associate a handle to a MAPI object \param obj pointer on the MAPI object on which handle has to be set \param handle the MAPI handle value */ void mapi_object_set_handle(mapi_object_t *obj, mapi_handle_t handle) { obj->handle = handle; } /** \details Dump a MAPI object (for debugging) \param obj pointer on the MAPI object to dump out */ _PUBLIC_ void mapi_object_debug(mapi_object_t *obj) { DEBUG(0, ("mapi_object {\n")); DEBUG(0, (" .handle == 0x%x\n", obj->handle)); DEBUG(0, (" .id == 0x%"PRIx64"\n", obj->id)); DEBUG(0, ("};\n")); } /** \details Initialize MAPI object private data to store a MAPI object table \param mem_ctx pointer on the memory context \param obj_table pointer on the MAPI object */ void mapi_object_table_init(TALLOC_CTX *mem_ctx, mapi_object_t *obj_table) { mapi_object_table_t *table = NULL; if (obj_table->private_data == NULL) { obj_table->private_data = talloc_zero((TALLOC_CTX *)mem_ctx, mapi_object_table_t); } table = (mapi_object_table_t *) obj_table->private_data; if (table->bookmark == NULL) { table->bookmark = talloc_zero((TALLOC_CTX *)table, mapi_object_bookmark_t); } table->proptags.aulPropTag = 0; table->proptags.cValues = 0; /* start bookmark index after BOOKMARK_END */ table->bk_last = 3; } /** \details Fetch a bookmark within a MAPI object table \param obj_table pointer on the MAPI object table \param bkPosition the bookmark position to find \param bin pointer on the Sbinary_short the function fills \return MAPI_E_SUCCESS on success, otherwise MAPI error. */ enum MAPISTATUS mapi_object_bookmark_find(mapi_object_t *obj_table, uint32_t bkPosition, struct SBinary_short *bin) { mapi_object_table_t *table; mapi_object_bookmark_t *bookmark; table = (mapi_object_table_t *)obj_table->private_data; bookmark = table->bookmark; /* Sanity checks */ OPENCHANGE_RETVAL_IF(!obj_table, MAPI_E_INVALID_PARAMETER, NULL); OPENCHANGE_RETVAL_IF(!table, MAPI_E_NOT_INITIALIZED, NULL); OPENCHANGE_RETVAL_IF(!bookmark, MAPI_E_NOT_INITIALIZED, NULL); OPENCHANGE_RETVAL_IF(bkPosition > table->bk_last, MAPI_E_INVALID_BOOKMARK, NULL); while (bookmark) { if (bookmark->index == bkPosition) { bin->cb = bookmark->bin.cb; bin->lpb = bookmark->bin.lpb; return MAPI_E_SUCCESS; } bookmark = bookmark->next; } return MAPI_E_INVALID_BOOKMARK; } /** \details Retrieve the number of bookmarks stored in a MAPI object table \param obj_table pointer to the MAPI object table \param count pointer to the number of bookmarks to return \return MAPI_E_SUCCESS on success, otherwise MAPI error. */ _PUBLIC_ enum MAPISTATUS mapi_object_bookmark_get_count(mapi_object_t *obj_table, uint32_t *count) { mapi_object_table_t *table; table = (mapi_object_table_t *)obj_table->private_data; /* Sanity checks */ OPENCHANGE_RETVAL_IF(!obj_table, MAPI_E_INVALID_PARAMETER, NULL); OPENCHANGE_RETVAL_IF(!table, MAPI_E_NOT_INITIALIZED, NULL); *count = table->bk_last - 3; return MAPI_E_SUCCESS; } /** \details Dump bookmarks associated to a MAPI object table \param obj_table pointer on the MAPI object table \return MAPI_E_SUCCESS on success, otherwise MAPI error. */ _PUBLIC_ enum MAPISTATUS mapi_object_bookmark_debug(mapi_object_t *obj_table) { mapi_object_table_t *table; mapi_object_bookmark_t *bookmark; table = (mapi_object_table_t *)obj_table->private_data; bookmark = table->bookmark; /* Sanity checks */ OPENCHANGE_RETVAL_IF(!obj_table, MAPI_E_INVALID_PARAMETER, NULL); OPENCHANGE_RETVAL_IF(!table, MAPI_E_NOT_INITIALIZED, NULL); OPENCHANGE_RETVAL_IF(!bookmark, MAPI_E_NOT_INITIALIZED, NULL); while (bookmark) { DEBUG(0, ("mapi_object_bookmark {\n")); DEBUG(0, (".index == %u\n", bookmark->index)); dump_data(0, bookmark->bin.lpb, bookmark->bin.cb); DEBUG(0, ("};\n")); bookmark = bookmark->next; } return MAPI_E_SUCCESS; } openchange-2.0/libmapi/mapi_object.h000066400000000000000000000061051223057412600175300ustar00rootroot00000000000000/* OpenChange MAPI implementation. Copyright (C) Julien Kerihuel 2007-2009. Copyright (C) Fabien Le Mentec 2007. This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see . */ #ifndef __MAPI_OBJECT_H #define __MAPI_OBJECT_H #include /* forward declarations */ struct mapi_session; /* generic mapi object definition */ typedef uint64_t mapi_id_t; typedef uint32_t mapi_handle_t; typedef struct mapi_object { bool store; uint64_t id; mapi_handle_t handle; uint8_t logon_id; struct mapi_session *session; void *private_data; } mapi_object_t; /* * Interface objects */ /** IMsgStore store type */ enum MsgStoreType { PrivateFolderWithoutCachedFids, /*!< Private folder store without the cached folder values filled in */ PrivateFolderWithCachedFids, /*!< Private folder store with the cached folder values filled in */ PublicFolder /*!< Public folder store */ }; /** * IMsgStore object */ typedef struct mapi_obj_store { enum MsgStoreType store_type; /* Mailbox */ uint64_t fid_mailbox_root; uint64_t fid_deferred_actions; uint64_t fid_spooler_queue; uint64_t fid_top_information_store; uint64_t fid_inbox; uint64_t fid_outbox; uint64_t fid_sent_items; uint64_t fid_deleted_items; uint64_t fid_common_views; uint64_t fid_schedule; uint64_t fid_search; uint64_t fid_views; uint64_t fid_shortcuts; /* Public Folders */ uint64_t fid_pf_public_root; uint64_t fid_pf_ipm_subtree; uint64_t fid_pf_non_ipm_subtree; uint64_t fid_pf_EFormsRegistryRoot; uint64_t fid_pf_FreeBusyRoot; uint64_t fid_pf_OfflineAB; uint64_t fid_pf_EFormsRegistry; uint64_t fid_pf_LocalSiteFreeBusy; uint64_t fid_pf_LocalSiteOfflineAB; uint64_t fid_pf_NNTPArticle; /* cached data */ uint64_t fid_calendar; uint64_t fid_contact; uint64_t fid_journal; uint64_t fid_note; uint64_t fid_task; uint64_t fid_drafts; /* GUID */ struct GUID guid; } mapi_object_store_t; /** * IMAPITable object */ typedef struct mapi_obj_bookmark { uint32_t index; struct SBinary_short bin; struct mapi_obj_bookmark *prev; struct mapi_obj_bookmark *next; } mapi_object_bookmark_t; typedef struct mapi_obj_table { uint32_t bk_last; mapi_object_bookmark_t *bookmark; struct SPropTagArray proptags; } mapi_object_table_t; typedef struct mapi_obj_message { uint32_t cValues; char *SubjectPrefix; char *NormalizedSubject; struct SPropTagArray SPropTagArray; struct SRowSet SRowSet; } mapi_object_message_t; #endif /*!__MAPI_OBJECT_H */ openchange-2.0/libmapi/mapi_profile.h000066400000000000000000000031141223057412600177170ustar00rootroot00000000000000/* OpenChange MAPI implementation. Copyright (C) Julien Kerihuel 2007-2009. Copyright (C) Fabien Le Mentec 2007. This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see . */ #ifndef __MAPI_PROFILE_H #define __MAPI_PROFILE_H #include /* forward decls */ struct cli_credentials; struct ldb_context; /* mapi profile */ struct mapi_profile { struct mapi_context *mapi_ctx; struct cli_credentials *credentials; char *profname; const char *org; const char *ou; const char *username; const char *password; const char *mailbox; const char *workstation; const char *homemdb; const char *domain; const char *realm; const char *server; const char *localaddr; bool seal; uint32_t codepage; uint32_t language; uint32_t method; uint32_t exchange_version; const char *kerberos; }; typedef int (*mapi_profile_callback_t)(struct PropertyRowSet_r *, const void *); #define OC_PROFILE_NOPASSWORD 1 #endif /* ! __MAPI_PROFILE_H__ */ openchange-2.0/libmapi/mapi_provider.h000066400000000000000000000027641223057412600201230ustar00rootroot00000000000000/* OpenChange MAPI implementation. Copyright (C) Julien Kerihuel 2007. Copyright (C) Fabien Le Mentec 2007. This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see . */ #ifndef __MAPI_PROVIDER_H #define __MAPI_PROVIDER_H /* forward decls */ struct mapi_object; struct mapi_profile; struct mapi_notify_ctx; enum PROVIDER_ID { PROVIDER_ID_EMSMDB = 0x1, PROVIDER_ID_NSPI = 0x2, PROVIDER_ID_UNKNOWN }; struct mapi_provider { enum PROVIDER_ID id; void *ctx; }; struct mapi_objects { struct mapi_object *object; struct mapi_objects *prev; struct mapi_objects *next; }; struct mapi_session { struct mapi_provider *emsmdb; struct mapi_provider *nspi; struct mapi_profile *profile; struct mapi_notify_ctx *notify_ctx; struct mapi_objects *objects; struct mapi_context *mapi_ctx; uint8_t logon_ids[255]; struct mapi_session *next; struct mapi_session *prev; }; #endif /* !__MAPI_PROVIDER_H */ openchange-2.0/libmapi/mapicode.c000066400000000000000000000315421223057412600170330ustar00rootroot00000000000000/* parser auto-generated by mparse */ #include "libmapi/libmapi.h" #include "libmapi/libmapi_private.h" #include "gen_ndr/ndr_exchange.h" void set_errno(enum MAPISTATUS status) { errno = status; } struct mapi_retval { enum MAPISTATUS err; const char *name; }; static const struct mapi_retval mapi_retval[] = { { MAPI_E_SUCCESS, "MAPI_E_SUCCESS" }, { MAPI_E_INTERFACE_NO_SUPPORT, "MAPI_E_INTERFACE_NO_SUPPORT" }, { MAPI_E_CALL_FAILED, "MAPI_E_CALL_FAILED" }, { MAPI_E_NO_SUPPORT, "MAPI_E_NO_SUPPORT" }, { MAPI_E_BAD_CHARWIDTH, "MAPI_E_BAD_CHARWIDTH" }, { MAPI_E_STRING_TOO_LONG, "MAPI_E_STRING_TOO_LONG" }, { MAPI_E_UNKNOWN_FLAGS, "MAPI_E_UNKNOWN_FLAGS" }, { MAPI_E_INVALID_ENTRYID, "MAPI_E_INVALID_ENTRYID" }, { MAPI_E_INVALID_OBJECT, "MAPI_E_INVALID_OBJECT" }, { MAPI_E_OBJECT_CHANGED, "MAPI_E_OBJECT_CHANGED" }, { MAPI_E_OBJECT_DELETED, "MAPI_E_OBJECT_DELETED" }, { MAPI_E_BUSY, "MAPI_E_BUSY" }, { MAPI_E_NOT_ENOUGH_DISK, "MAPI_E_NOT_ENOUGH_DISK" }, { MAPI_E_NOT_ENOUGH_RESOURCES, "MAPI_E_NOT_ENOUGH_RESOURCES" }, { MAPI_E_NOT_FOUND, "MAPI_E_NOT_FOUND" }, { MAPI_E_VERSION, "MAPI_E_VERSION" }, { MAPI_E_LOGON_FAILED, "MAPI_E_LOGON_FAILED" }, { MAPI_E_SESSION_LIMIT, "MAPI_E_SESSION_LIMIT" }, { MAPI_E_USER_CANCEL, "MAPI_E_USER_CANCEL" }, { MAPI_E_UNABLE_TO_ABORT, "MAPI_E_UNABLE_TO_ABORT" }, { MAPI_E_NETWORK_ERROR, "MAPI_E_NETWORK_ERROR" }, { MAPI_E_DISK_ERROR, "MAPI_E_DISK_ERROR" }, { MAPI_E_TOO_COMPLEX, "MAPI_E_TOO_COMPLEX" }, { MAPI_E_BAD_COLUMN, "MAPI_E_BAD_COLUMN" }, { MAPI_E_EXTENDED_ERROR, "MAPI_E_EXTENDED_ERROR" }, { MAPI_E_COMPUTED, "MAPI_E_COMPUTED" }, { MAPI_E_CORRUPT_DATA, "MAPI_E_CORRUPT_DATA" }, { MAPI_E_UNCONFIGURED, "MAPI_E_UNCONFIGURED" }, { MAPI_E_FAILONEPROVIDER, "MAPI_E_FAILONEPROVIDER" }, { MAPI_E_UNKNOWN_CPID, "MAPI_E_UNKNOWN_CPID" }, { MAPI_E_UNKNOWN_LCID, "MAPI_E_UNKNOWN_LCID" }, { MAPI_E_PASSWORD_CHANGE_REQUIRED, "MAPI_E_PASSWORD_CHANGE_REQUIRED" }, { MAPI_E_PASSWORD_EXPIRED, "MAPI_E_PASSWORD_EXPIRED" }, { MAPI_E_INVALID_WORKSTATION_ACCOUNT, "MAPI_E_INVALID_WORKSTATION_ACCOUNT" }, { MAPI_E_INVALID_ACCESS_TIME, "MAPI_E_INVALID_ACCESS_TIME" }, { MAPI_E_ACCOUNT_DISABLED, "MAPI_E_ACCOUNT_DISABLED" }, { MAPI_E_END_OF_SESSION, "MAPI_E_END_OF_SESSION" }, { MAPI_E_UNKNOWN_ENTRYID, "MAPI_E_UNKNOWN_ENTRYID" }, { MAPI_E_MISSING_REQUIRED_COLUMN, "MAPI_E_MISSING_REQUIRED_COLUMN" }, { MAPI_W_NO_SERVICE, "MAPI_W_NO_SERVICE" }, { MAPI_E_BAD_VALUE, "MAPI_E_BAD_VALUE" }, { MAPI_E_INVALID_TYPE, "MAPI_E_INVALID_TYPE" }, { MAPI_E_TYPE_NO_SUPPORT, "MAPI_E_TYPE_NO_SUPPORT" }, { MAPI_E_UNEXPECTED_TYPE, "MAPI_E_UNEXPECTED_TYPE" }, { MAPI_E_TOO_BIG, "MAPI_E_TOO_BIG" }, { MAPI_E_DECLINE_COPY, "MAPI_E_DECLINE_COPY" }, { MAPI_E_UNEXPECTED_ID, "MAPI_E_UNEXPECTED_ID" }, { MAPI_W_ERRORS_RETURNED, "MAPI_W_ERRORS_RETURNED" }, { MAPI_E_UNABLE_TO_COMPLETE, "MAPI_E_UNABLE_TO_COMPLETE" }, { MAPI_E_TIMEOUT, "MAPI_E_TIMEOUT" }, { MAPI_E_TABLE_EMPTY, "MAPI_E_TABLE_EMPTY" }, { MAPI_E_TABLE_TOO_BIG, "MAPI_E_TABLE_TOO_BIG" }, { MAPI_E_INVALID_BOOKMARK, "MAPI_E_INVALID_BOOKMARK" }, { MAPI_W_POSITION_CHANGED, "MAPI_W_POSITION_CHANGED" }, { MAPI_W_APPROX_COUNT, "MAPI_W_APPROX_COUNT" }, { MAPI_E_WAIT, "MAPI_E_WAIT" }, { MAPI_E_CANCEL, "MAPI_E_CANCEL" }, { MAPI_E_NOT_ME, "MAPI_E_NOT_ME" }, { MAPI_W_CANCEL_MESSAGE, "MAPI_W_CANCEL_MESSAGE" }, { MAPI_E_CORRUPT_STORE, "MAPI_E_CORRUPT_STORE" }, { MAPI_E_NOT_IN_QUEUE, "MAPI_E_NOT_IN_QUEUE" }, { MAPI_E_NO_SUPPRESS, "MAPI_E_NO_SUPPRESS" }, { MAPI_E_COLLISION, "MAPI_E_COLLISION" }, { MAPI_E_NOT_INITIALIZED, "MAPI_E_NOT_INITIALIZED" }, { MAPI_E_NON_STANDARD, "MAPI_E_NON_STANDARD" }, { MAPI_E_NO_RECIPIENTS, "MAPI_E_NO_RECIPIENTS" }, { MAPI_E_SUBMITTED, "MAPI_E_SUBMITTED" }, { MAPI_E_HAS_FOLDERS, "MAPI_E_HAS_FOLDERS" }, { MAPI_E_HAS_MESAGES, "MAPI_E_HAS_MESAGES" }, { MAPI_E_FOLDER_CYCLE, "MAPI_E_FOLDER_CYCLE" }, { MAPI_E_LOCKID_LIMIT, "MAPI_E_LOCKID_LIMIT" }, { MAPI_W_PARTIAL_COMPLETION, "MAPI_W_PARTIAL_COMPLETION" }, { MAPI_E_AMBIGUOUS_RECIP, "MAPI_E_AMBIGUOUS_RECIP" }, { SYNC_E_OBJECT_DELETED, "SYNC_E_OBJECT_DELETED" }, { SYNC_E_IGNORE, "SYNC_E_IGNORE" }, { SYNC_E_CONFLICT, "SYNC_E_CONFLICT" }, { SYNC_E_NO_PARENT, "SYNC_E_NO_PARENT" }, { SYNC_E_CYCLE_DETECTED, "SYNC_E_CYCLE_DETECTED" }, { SYNC_E_UNSYNCHRONIZED, "SYNC_E_UNSYNCHRONIZED" }, { SYNC_W_PROGRESS, "SYNC_W_PROGRESS" }, { SYNC_W_CLIENT_CHANGE_NEWER, "SYNC_W_CLIENT_CHANGE_NEWER" }, { MAPI_E_NAMED_PROP_QUOTA_EXCEEDED, "MAPI_E_NAMED_PROP_QUOTA_EXCEEDED" }, { MAPI_E_NOT_IMPLEMENTED, "MAPI_E_NOT_IMPLEMENTED" }, { MAPI_E_NO_ACCESS, "MAPI_E_NO_ACCESS" }, { MAPI_E_NOT_ENOUGH_MEMORY, "MAPI_E_NOT_ENOUGH_MEMORY" }, { MAPI_E_INVALID_PARAMETER, "MAPI_E_INVALID_PARAMETER" }, { ecJetError, "ecJetError" }, { ecUnknownUser, "ecUnknownUser" }, { ecExiting, "ecExiting" }, { ecBadConfig, "ecBadConfig" }, { ecUnknownCodePage, "ecUnknownCodePage" }, { ecMemory, "ecMemory" }, { ecLoginPerm, "ecLoginPerm" }, { ecDatabaseRolledBack, "ecDatabaseRolledBack" }, { ecDatabaseCopiedError, "ecDatabaseCopiedError" }, { ecAuditNotAllowed, "ecAuditNotAllowed" }, { ecZombieUser, "ecZombieUser" }, { ecUnconvertableACL, "ecUnconvertableACL" }, { ecNoFreeJses, "ecNoFreeJses" }, { ecDifferentJses, "ecDifferentJses" }, { ecFileRemove, "ecFileRemove" }, { ecParameterOverflow, "ecParameterOverflow" }, { ecBadVersion, "ecBadVersion" }, { ecTooManyCols, "ecTooManyCols" }, { ecHaveMore, "ecHaveMore" }, { ecDatabaseError, "ecDatabaseError" }, { ecIndexNameTooBig, "ecIndexNameTooBig" }, { ecUnsupportedProp, "ecUnsupportedProp" }, { ecMsgNotSaved, "ecMsgNotSaved" }, { ecUnpubNotif, "ecUnpubNotif" }, { ecDifferentRoot, "ecDifferentRoot" }, { ecBadFolderName, "ecBadFolderName" }, { ecAttachOpen, "ecAttachOpen" }, { ecInvClpsState, "ecInvClpsState" }, { ecSkipMyChildren, "ecSkipMyChildren" }, { ecSearchFolder, "ecSearchFolder" }, { ecNotSearchFolder, "ecNotSearchFolder" }, { ecFolderSetReceive, "ecFolderSetReceive" }, { ecNoReceiveFolder, "ecNoReceiveFolder" }, { ecNoDelSubmitMsg, "ecNoDelSubmitMsg" }, { ecInvalidRecips, "ecInvalidRecips" }, { ecNoReplicaHere, "ecNoReplicaHere" }, { ecNoReplicaAvailable, "ecNoReplicaAvailable" }, { ecPublicMDB, "ecPublicMDB" }, { ecNotPublicMDB, "ecNotPublicMDB" }, { ecRecordNotFound, "ecRecordNotFound" }, { ecReplConflict, "ecReplConflict" }, { ecFxBufferOverrun, "ecFxBufferOverrun" }, { ecFxBufferEmpty, "ecFxBufferEmpty" }, { ecFxPartialValue, "ecFxPartialValue" }, { ecFxNoRoom, "ecFxNoRoom" }, { ecMaxTimeExpired, "ecMaxTimeExpired" }, { ecDstError, "ecDstError" }, { ecMDBNotInit, "ecMDBNotInit" }, { ecWrongServer, "ecWrongServer" }, { ecBufferTooSmall, "ecBufferTooSmall" }, { ecRequiresRefResolve, "ecRequiresRefResolve" }, { ecServerPaused, "ecServerPaused" }, { ecServerBusy, "ecServerBusy" }, { ecNoSuchLogon, "ecNoSuchLogon" }, { ecLoadLibFailed, "ecLoadLibFailed" }, { ecObjAlreadyConfig, "ecObjAlreadyConfig" }, { ecObjNotConfig, "ecObjNotConfig" }, { ecDataLoss, "ecDataLoss" }, { ecMaxSendThreadExceeded, "ecMaxSendThreadExceeded" }, { ecFxErrorMarker, "ecFxErrorMarker" }, { ecNoFreeJtabs, "ecNoFreeJtabs" }, { ecNotPrivateMDB, "ecNotPrivateMDB" }, { ecIsintegMDB, "ecIsintegMDB" }, { ecRecoveryMDBMismatch, "ecRecoveryMDBMismatch" }, { ecTableMayNotBeDeleted, "ecTableMayNotBeDeleted" }, { ecRpcRegisterIf, "ecRpcRegisterIf" }, { ecRpcListen, "ecRpcListen" }, { ecRpcFormat, "ecRpcFormat" }, { ecNoCopyTo, "ecNoCopyTo" }, { ecNullObject, "ecNullObject" }, { ecRpcAuthentication, "ecRpcAuthentication" }, { ecRpcBadAuthenticationLevel, "ecRpcBadAuthenticationLevel" }, { ecNullCommentRestriction, "ecNullCommentRestriction" }, { ecRulesLoadError, "ecRulesLoadError" }, { ecRulesDelivErr, "ecRulesDelivErr" }, { ecRulesParsingErr, "ecRulesParsingErr" }, { ecRulesCreateDaeErr, "ecRulesCreateDaeErr" }, { ecRulesCreateDamErr, "ecRulesCreateDamErr" }, { ecRulesNoMoveCopyFolder, "ecRulesNoMoveCopyFolder" }, { ecRulesNoFolderRights, "ecRulesNoFolderRights" }, { ecMessageTooBig, "ecMessageTooBig" }, { ecFormNotValid, "ecFormNotValid" }, { ecNotAuthorized, "ecNotAuthorized" }, { ecDeleteMessage, "ecDeleteMessage" }, { ecBounceMessage, "ecBounceMessage" }, { ecQuotaExceeded, "ecQuotaExceeded" }, { ecMaxSubmissionExceeded, "ecMaxSubmissionExceeded" }, { ecMaxAttachmentExceeded, "ecMaxAttachmentExceeded" }, { ecSendAsDenied, "ecSendAsDenied" }, { ecShutoffQuotaExceeded, "ecShutoffQuotaExceeded" }, { ecMaxObjsExceeded, "ecMaxObjsExceeded" }, { ecClientVerDisallowed, "ecClientVerDisallowed" }, { ecRpcHttpDisallowed, "ecRpcHttpDisallowed" }, { ecCachedModeRequired, "ecCachedModeRequired" }, { ecFolderNotCleanedUp, "ecFolderNotCleanedUp" }, { ecFmtError, "ecFmtError" }, { ecNotExpanded, "ecNotExpanded" }, { ecNotCollapsed, "ecNotCollapsed" }, { ecLeaf, "ecLeaf" }, { ecUnregisteredNamedProp, "ecUnregisteredNamedProp" }, { ecFolderDisabled, "ecFolderDisabled" }, { ecDomainError, "ecDomainError" }, { ecNoCreateRight, "ecNoCreateRight" }, { ecPublicRoot, "ecPublicRoot" }, { ecNoReadRight, "ecNoReadRight" }, { ecNoCreateSubfolderRight, "ecNoCreateSubfolderRight" }, { ecDstNullObject, "ecDstNullObject" }, { ecMsgCycle, "ecMsgCycle" }, { ecTooManyRecips, "ecTooManyRecips" }, { ecVirusScanInProgress, "ecVirusScanInProgress" }, { ecVirusDetected, "ecVirusDetected" }, { ecMailboxInTransit, "ecMailboxInTransit" }, { ecBackupInProgress, "ecBackupInProgress" }, { ecVirusMessageDeleted, "ecVirusMessageDeleted" }, { ecInvalidBackupSequence, "ecInvalidBackupSequence" }, { ecInvalidBackupSize, "ecInvalidBackupSize" }, { ecTooManyBackupsInProgress, "ecTooManyBackupsInProgress" }, { ecRestoreInProgress, "ecRestoreInProgress" }, { ecDuplicateObject, "ecDuplicateObject" }, { ecObjectNotFound, "ecObjectNotFound" }, { ecFixupReplyRule, "ecFixupReplyRule" }, { ecTemplateNotFound, "ecTemplateNotFound" }, { ecRuleException, "ecRuleException" }, { ecDSNoSuchObject, "ecDSNoSuchObject" }, { ecMessageAlreadyTombstoned, "ecMessageAlreadyTombstoned" }, { ecRequiresRWTransaction, "ecRequiresRWTransaction" }, { ecPaused, "ecPaused" }, { ecWrongMailbox, "ecWrongMailbox" }, { ecChgPassword, "ecChgPassword" }, { ecPwdExpired, "ecPwdExpired" }, { ecInvWkstn, "ecInvWkstn" }, { ecInvLogonHrs, "ecInvLogonHrs" }, { ecAcctDisabled, "ecAcctDisabled" }, { ecRuleVersion, "ecRuleVersion" }, { ecRuleFormat, "ecRuleFormat" }, { ecRuleSendAsDenied, "ecRuleSendAsDenied" }, { ecNoServerSupport, "ecNoServerSupport" }, { ecLockTimedOut, "ecLockTimedOut" }, { ecObjectLocked, "ecObjectLocked" }, { ecInvalidLockNamespace, "ecInvalidLockNamespace" }, { ecMessageDeleted, "ecMessageDeleted" }, { ecProtocolDisabled, "ecProtocolDisabled" }, { ecClearTextLogonDisabled, "ecClearTextLogonDisabled" }, { ecRejected, "ecRejected" }, { ecAmbiguousAlias, "ecAmbiguousAlias" }, { ecUnknownMailbox, "ecUnknownMailbox" }, { ecExpReserved, "ecExpReserved" }, { ecExpParseDepth, "ecExpParseDepth" }, { ecExpFuncArgType, "ecExpFuncArgType" }, { ecExpSyntax, "ecExpSyntax" }, { ecExpBadStrToken, "ecExpBadStrToken" }, { ecExpBadColToken, "ecExpBadColToken" }, { ecExpTypeMismatch, "ecExpTypeMismatch" }, { ecExpOpNotSupported, "ecExpOpNotSupported" }, { ecExpDivByZero, "ecExpDivByZero" }, { ecExpUnaryArgType, "ecExpUnaryArgType" }, { ecNotLocked, "ecNotLocked" }, { ecClientEvent, "ecClientEvent" }, { ecCorruptEvent, "ecCorruptEvent" }, { ecCorruptWatermark, "ecCorruptWatermark" }, { ecEventError, "ecEventError" }, { ecWatermarkError, "ecWatermarkError" }, { ecNonCanonicalACL, "ecNonCanonicalACL" }, { ecMailboxDisabled, "ecMailboxDisabled" }, { ecRulesFolderOverQuota, "ecRulesFolderOverQuota" }, { ecADUnavailable, "ecADUnavailable" }, { ecADError, "ecADError" }, { ecADNotFound, "ecADNotFound" }, { ecADPropertyError, "ecADPropertyError" }, { ecNotEncrypted, "ecNotEncrypted" }, { ecRpcServerTooBusy, "ecRpcServerTooBusy" }, { ecRpcOutOfMemory, "ecRpcOutOfMemory" }, { ecRpcServerOutOfMemory, "ecRpcServerOutOfMemory" }, { ecRpcOutOfResources, "ecRpcOutOfResources" }, { ecRpcServerUnavailable, "ecRpcServerUnavailable" }, { ecSecureSubmitError, "ecSecureSubmitError" }, { ecEventsDeleted, "ecEventsDeleted" }, { ecSubsystemStopping, "ecSubsystemStopping" }, { ecSAUnavailable, "ecSAUnavailable" }, { ecCIStopping, "ecCIStopping" }, { ecFxInvalidState, "ecFxInvalidState" }, { ecFxUnexpectedMarker, "ecFxUnexpectedMarker" }, { ecDuplicateDelivery, "ecDuplicateDelivery" }, { ecConditionViolation, "ecConditionViolation" }, { ecRpcInvalidHandle, "ecRpcInvalidHandle" }, { ecEventNotFound, "ecEventNotFound" }, { MAPI_E_RESERVED, NULL } }; _PUBLIC_ void mapi_errstr(const char *function, enum MAPISTATUS mapi_code) { struct ndr_print ndr_print; ndr_print.depth = 1; ndr_print.print = ndr_print_debug_helper; ndr_print.no_newline = false; ndr_print_MAPISTATUS(&ndr_print, function, mapi_code); } _PUBLIC_ const char *mapi_get_errstr(enum MAPISTATUS mapi_code) { uint32_t i; for (i = 0; mapi_retval[i].name; i++) { if (mapi_retval[i].err == mapi_code) { return mapi_retval[i].name; } } return NULL; } openchange-2.0/libmapi/mapicode.h000066400000000000000000000052421223057412600170360ustar00rootroot00000000000000/* OpenChange MAPI implementation. libmapi macros header file Copyright (C) Julien Kerihuel 2010. This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see . */ #ifndef __MAPICODE_H__ #define __MAPICODE_H__ #define MAPI_RETVAL_IF(x,e,c) \ do { \ if (x) { \ errno = (e); \ if (c) { \ talloc_free(c); \ } \ return -1; \ } \ } while (0); #define OPENCHANGE_RETVAL_IF(x,e,c) \ do { \ if (x) { \ set_errno(e); \ if (c) { \ talloc_free(c); \ } \ return (e); \ } \ } while (0); #define OPENCHANGE_RETVAL_CALL_IF(x,e,r,c) \ do { \ if (x) { \ set_errno(e); \ if (r) { \ talloc_free(r); \ } \ if (c) { \ talloc_free(c); \ } \ return (e); \ } \ } while (0); #define OPENCHANGE_RETVAL_ERR(e,c) \ do { \ set_errno(e); \ if (c) { \ talloc_free(c); \ } \ return (e); \ } while (0); #define OPENCHANGE_CHECK_NOTIFICATION(s,r) \ do { \ if (s->notify_ctx) \ ProcessNotification(s->notify_ctx, r); \ } while (0); /* Status macros for MAPI */ typedef unsigned long SCODE; #define SEVERITY_ERROR 1 #define SEVERITY_WARN 0 #define FACILITY_ITF 4 #define MAKE_MAPI_CODE(sev, fac, code) \ (((SCODE)(sev)<<31)|((SCODE)(fac)<<16)|((SCODE)(code))) #define MAKE_MAPI_E(code) (MAKE_MAPI_CODE(SEVERITY_ERROR, FACILITY_ITF, code)) #define MAKE_MAPI_S(code) (MAKE_MAPI_CODE(SEVERITY_WARN, FACILITY_ITF, code)) #define MAPI_STATUS_V(x) ((SCODE)x) #define MAPI_STATUS_IS_OK(x) (MAPI_STATUS_V(x) == 0) #define MAPI_STATUS_IS_ERR(x) ((MAPI_STATUS_V(x) & 0xc0000000) == 0xc0000000) #define MAPI_STATUS_EQUAL(x,y) (MAPI_STATUS_V(x) == MAPI_STATUS_V(y)) #define MAPI_STATUS_IS_OK_RETURN(x) do { \ if (MAPI_STATUS_IS_OK(x)) {\ return x;\ }\ } while (0) #define MAPI_STATUS_NOT_OK_RETURN(x) do { \ if (!MAPI_STATUS_IS_OK(x)) {\ return x;\ }\ } while (0) #define MAPI_STATUS_IS_ERR_RETURN(x) do { \ if (MAPI_STATUS_IS_ERR(x)) {\ return x;\ }\ } while (0) #define MAPI_STATUS_NOT_ERR_RETURN(x) do { \ if (!MAPI_STATUS_IS_ERR(x)) {\ return x;\ }\ } while (0) #endif /* !__MAPICODE_H__ */ openchange-2.0/libmapi/mapidefs.h000066400000000000000000000203741223057412600170500ustar00rootroot00000000000000/* OpenChange MAPI implementation. MAPI definitions Copyright (C) Julien Kerihuel 2005 - 2007. This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see . */ #ifndef __MAPIDEFS_H__ #define __MAPIDEFS_H__ #define PROP_TAG(type, id) (((id << 16))| (type)) #define MV_FLAG 0x1000 /* UNICODE flags */ #define MAPI_UNICODE 0x80000000 /* Other GetProps/SetProps flags */ #define MAPI_PROPS_SKIP_NAMEDID_CHECK 0x00000001 /* Property types */ #define PT_UNSPECIFIED 0x0 #define PT_NULL 0x1 #define PT_I2 0x2 #define PT_SHORT 0x2 #define PT_LONG 0x3 #define PT_FLOAT 0x4 #define PT_DOUBLE 0x5 #define PT_CURRENCY 0x6 #define PT_APPTIME 0x7 #define PT_ERROR 0xa #define PT_BOOLEAN 0xb #define PT_OBJECT 0xd #define PT_I8 0x14 #define PT_STRING8 0x1e #define PT_UNICODE 0x1f #define PT_SYSTIME 0x40 #define PT_CLSID 0x48 #define PT_SVREID 0xFB #define PT_SRESTRICT 0xFD #define PT_ACTIONS 0xFE #define PT_BINARY 0x102 /* Multi valued property types */ #define PT_MV_SHORT (MV_FLAG | PT_SHORT) #define PT_MV_LONG (MV_FLAG | PT_LONG) #define PT_MV_FLOAT (MV_FLAG | PT_FLOAT) #define PT_MV_DOUBLE (MV_FLAG | PT_DOUBLE) #define PT_MV_CURRENCY (MV_FLAG | PT_CURRENCY) #define PT_MV_APPTIME (MV_FLAG | PT_APPTIME) #define PT_MV_I8 (MV_FLAG | PT_I8) #define PT_MV_STRING8 (MV_FLAG | PT_STRING8) #define PT_MV_UNICODE (MV_FLAG | PT_UNICODE) #define PT_MV_SYSTIME (MV_FLAG | PT_SYSTIME) #define PT_MV_CLSID (MV_FLAG | PT_CLSID) #define PT_MV_BINARY (MV_FLAG | PT_BINARY) /* Restriction types */ #define RES_AND 0 #define RES_OR 1 #define RES_NOT 2 #define RES_CONTENT 3 #define RES_PROPERTY 4 #define RES_COMPAREPROPS 5 #define RES_BITMASK 6 #define RES_SIZE 7 #define RES_EXIST 8 #define RES_SUBRESTRICTION 9 #define RES_COMMENT 10 /* Resolve types */ #define MAPI_UNRESOLVED 0x0 #define MAPI_AMBIGUOUS 0x1 #define MAPI_RESOLVED 0x2 /* Positioning Minimal Entry IDs */ #define MID_BEGINNING_OF_TABLE 0x0 #define MID_CURRENT 0x1 #define MID_END_OF_TABLE 0x2 /* Object Type */ #define MAPI_STORE 0x1 /* Message Store */ #define MAPI_ADDRBOOK 0x2 /* Address Book */ #define MAPI_FOLDER 0x3 /* Folder */ #define MAPI_ABCONT 0x4 /* Address Book Container */ #define MAPI_MESSAGE 0x5 /* Message */ #define MAPI_MAILUSER 0x6 /* Individual Recipient */ #define MAPI_ATTACH 0x7 /* Attachment */ #define MAPI_DISTLIST 0x8 /* Distribution List Recipient */ #define MAPI_PROFSECT 0x9 /* Profile Section */ #define MAPI_STATUS 0xA /* Status Object */ #define MAPI_SESSION 0xB /* Session */ #define MAPI_FORMINFO 0xC /* Form Information */ /* Display Type */ #define DT_MAILUSER 0x0 #define DT_DISTLIST 0x1 #define DT_FORUM 0x2 #define DT_AGENT 0x3 #define DT_ORGANIZATION 0x4 #define DT_PRIVATE_DISTLIST 0x5 #define DT_REMOTE_MAILUSER 0x6 #define DT_CONTAINER 0x100 #define DT_TEMPLATE 0x101 #define DT_ADDRESS_TEMPLATE 0x102 #define DT_SEARCH 0x200 /* Attachment method */ #define NO_ATTACHMENT 0 #define ATTACH_BY_VALUE 1 #define ATTACH_BY_REFERENCE 2 #define ATTACH_BY_REF_RESOLVE 3 #define ATTACH_BY_REF_ONLY 4 #define ATTACH_EMBEDDED_MSG 5 #define ATTACH_OLE 6 /* Creation flags */ #define MAPI_CREATE 0x2 /* SaveChanges flags */ #define KEEP_OPEN_READONLY 0x09 #define KEEP_OPEN_READWRITE 0x0A #define FORCE_SAVE 0x0C /* OpenMessage flags */ #define MAPI_MODIFY 0x1 /* see MAPI_CREATE above */ /* GetGALTable flags */ #define TABLE_START 0x0 #define TABLE_CUR 0x1 /* * ENTRYID flags */ /* definition for abFlags[0] */ #define MAPI_SHORTTERM 0x80 #define MAPI_NOTRECIP 0x40 #define MAPI_THISSESSION 0x20 #define MAPI_NOW 0x10 #define MAPI_NOTRESERVED 0x08 /* definition for abFlags[1] */ #define MAPI_COMPOUND 0x80 /* * Priority */ #define PRIORITY_LOW -1 #define PRIORITY_NORMAL 0 #define PRIORITY_HIGH 1 /* * Importance */ #define IMPORTANCE_LOW 0 #define IMPORTANCE_NORMAL 1 #define IMPORTANCE_HIGH 2 /* * Color */ #define olBlue 0 #define olGreen 1 #define olPink 2 #define olYellow 3 #define olWhite 4 /* * Appointment flags with PR_APPOINTMENT_BUSY_STATUS */ #define BUSY_STATUS_FREE 0 #define BUSY_STATUS_TENTATIVE 1 #define BUSY_STATUS_BUSY 2 #define BUSY_STATUS_OUTOFOFFICE 3 /* * Appointment meeting status */ #define MEETING_STATUS_NONMEETING 0 #define MEETING_STATUS_MEETING 1 /* * Task status */ #define olTaskNotStarted 0 #define olTaskInProgress 1 #define olTaskComplete 2 #define olTaskWaiting 3 #define olTaskDeferred 4 /* * Task OwnerShip */ #define olNewTask 0 #define olDelegatedTask 1 #define olOwnTask 2 /* * PR_MESSAGE_EDITOR_FORMAT type */ #define EDITOR_FORMAT_PLAINTEXT 1 #define EDITOR_FORMAT_HTML 2 #define EDITOR_FORMAT_RTF 3 #define olEditorText 1 #define olEditorHTML 2 #define olEditorRTF 3 #define olEditorWord 4 /* * Default folders */ #define olFolderMailboxRoot 0 #define olFolderTopInformationStore 1 #define olFolderDeletedItems 3 #define olFolderOutbox 4 #define olFolderSentMail 5 #define olFolderInbox 6 #define olFolderCommonView 8 #define olFolderCalendar 9 #define olFolderContacts 10 #define olFolderJournal 11 #define olFolderNotes 12 #define olFolderTasks 13 #define olFolderDrafts 16 #define olPublicFoldersAllPublicFolders 18 #define olFolderConflicts 19 #define olFolderSyncIssues 20 #define olFolderLocalFailures 21 #define olFolderServerFailures 22 #define olFolderJunk 23 #define olFolderFinder 24 #define olFolderPublicRoot 25 #define olFolderPublicIPMSubtree 26 #define olFolderPublicNonIPMSubtree 27 #define olFolderPublicEFormsRoot 28 #define olFolderPublicFreeBusyRoot 29 #define olFolderPublicOfflineAB 30 #define olFolderPublicEFormsRegistry 31 #define olFolderPublicLocalFreeBusy 32 #define olFolderPublicLocalOfflineAB 33 #define olFolderPublicNNTPArticle 34 /* * IPF container class */ #define IPF_APPOINTMENT "IPF.Appointment" #define IPF_CONTACT "IPF.Contact" #define IPF_JOURNAL "IPF.Journal" #define IPF_NOTE "IPF.Note" #define IPF_STICKYNOTE "IPF.StickyNote" #define IPF_TASK "IPF.Task" #define IPF_POST "IPF.Post" /* * Common OLEGUID - see MS-OXPROPS, Section 1.3.2 */ #define PSETID_Appointment "00062002-0000-0000-c000-000000000046" #define PSETID_Task "00062003-0000-0000-c000-000000000046" #define PSETID_Address "00062004-0000-0000-c000-000000000046" #define PSETID_Common "00062008-0000-0000-c000-000000000046" #define PSETID_Note "0006200e-0000-0000-c000-000000000046" #define PSETID_Log "0006200a-0000-0000-c000-000000000046" #define PSETID_Sharing "00062040-0000-0000-c000-000000000046" #define PSETID_PostRss "00062041-0000-0000-c000-000000000046" #define PSETID_UnifiedMessaging "4442858e-a9e3-4e80-b900-317a210cc15b" #define PSETID_Meeting "6ed8da90-450b-101b-98da-00aa003f1305" #define PSETID_AirSync "71035549-0739-4dcb-9163-00f0580dbbdf" #define PSETID_Messaging "41f28f13-83f4-4114-a584-eedb5a6b0bff" #define PSETID_Attachment "96357f7f-59e1-47d0-99a7-46515c183b54" #define PSETID_CalendarAssistant "11000e07-b51b-40d6-af21-caa85edab1d0" #define PS_PUBLIC_STRINGS "00020329-0000-0000-c000-000000000046" #define PS_INTERNET_HEADERS "00020386-0000-0000-c000-000000000046" #define PS_MAPI "00020328-0000-0000-c000-000000000046" #define PSETID_Report "00062013-0000-0000-c000-000000000046" #define PSETID_Remote "00062014-0000-0000-c000-000000000046" #define PS_UNKNOWN_0006200b_0000_0000_c000_000000000046 "0006200b-0000-0000-c000-000000000046" #define PSETID_Appointment2 "02200600-0000-0000-c000-000000000046" /* FreeBusy strings for Exchange 2003 and below */ #define FREEBUSY_FOLDER "EX:/o=%s/ou=%s" #define FREEBUSY_USER "USER-/CN=RECIPIENTS/CN=%s" #endif /*!__MAPIDEFS_H__ */ openchange-2.0/libmapi/mapidump.c000066400000000000000000000751441223057412600170740ustar00rootroot00000000000000/* OpenChange MAPI implementation. Copyright (C) Julien Kerihuel 2007-2011. This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see . */ #include "libmapi/libmapi.h" #include "libmapi/libmapi_private.h" #include "libmapi/mapi_nameid.h" #include "libmapi/mapidump.h" #include #ifdef ENABLE_ASSERTS #include #define OC_ASSERT(x) assert(x) #else #define OC_ASSERT(x) #endif /** \file mapidump.c \brief Functions for displaying various data structures, mainly for debugging */ /** Output one property tag and value \param lpProp the property to print \param sep a separator / spacer to insert in front of the label */ _PUBLIC_ void mapidump_SPropValue(struct SPropValue lpProp, const char *sep) { const char *proptag; const void *data; TALLOC_CTX *mem_ctx = NULL; const struct StringArray_r *StringArray_r = NULL; const struct StringArrayW_r *StringArrayW_r = NULL; const struct BinaryArray_r *BinaryArray_r = NULL; const struct LongArray_r *LongArray_r = NULL; uint32_t i; proptag = get_proptag_name(lpProp.ulPropTag); if (!proptag) { mem_ctx = talloc_named(NULL, 0, "mapidump_SPropValue"); proptag = talloc_asprintf(mem_ctx, "0x%.8x", lpProp.ulPropTag); } switch(lpProp.ulPropTag & 0xFFFF) { case PT_SHORT: data = get_SPropValue_data(&lpProp); printf("%s%s: 0x%x\n", sep?sep:"", proptag, (*(const uint16_t *)data)); break; case PT_LONG: case PT_OBJECT: data = get_SPropValue_data(&lpProp); printf("%s%s: %u\n", sep?sep:"", proptag, (*(const uint32_t *)data)); break; case PT_DOUBLE: data = get_SPropValue_data(&lpProp); printf("%s%s: %f\n", sep?sep:"", proptag, (*(const double *)data)); break; case PT_BOOLEAN: data = get_SPropValue_data(&lpProp); printf("%s%s: 0x%x\n", sep?sep:"", proptag, (*(const uint8_t *)data)); break; case PT_I8: data = get_SPropValue_data(&lpProp); printf("%s%s: %.16"PRIx64"\n", sep?sep:"", proptag, (*(const uint64_t *)data)); break; case PT_STRING8: case PT_UNICODE: data = get_SPropValue_data(&lpProp); printf("%s%s:", sep?sep:"", proptag); if (data && ((*(const uint16_t *)data) == 0x0000)) { /* its an empty string */ printf("\n"); } else if (data && ((*(enum MAPISTATUS *)data) != MAPI_E_NOT_FOUND)) { /* its a valid string */ printf(" %s\n", (const char *)data); } else { /* its a null or otherwise problematic string */ printf(" (NULL)\n"); } break; case PT_SYSTIME: mapidump_date_SPropValue(lpProp, proptag, sep); break; case PT_ERROR: data = get_SPropValue_data(&lpProp); printf("%s%s_ERROR: 0x%.8x\n", sep?sep:"", proptag, (*(const uint32_t *)data)); break; case PT_CLSID: { const uint8_t *ab = (const uint8_t *) get_SPropValue_data(&lpProp); printf("%s%s: ", sep?sep:"", proptag); for (i = 0; i < 15; ++i) { printf("%02x ", ab[i]); } printf("%x\n", ab[15]); break; } case PT_SVREID: case PT_BINARY: data = get_SPropValue_data(&lpProp); if (data) { printf("%s%s:\n", sep?sep:"", proptag); dump_data(0, ((const struct Binary_r *)data)->lpb, ((const struct Binary_r *)data)->cb); } else { printf("%s%s: (NULL)\n", sep?sep:"", proptag); } break; case PT_MV_LONG: LongArray_r = (const struct LongArray_r *) get_SPropValue_data(&lpProp); printf("%s%s ", sep?sep:"", proptag); for (i = 0; i < LongArray_r->cValues - 1; i++) { printf("0x%.8x, ", LongArray_r->lpl[i]); } printf("0x%.8x\n", LongArray_r->lpl[i]); break; case PT_MV_STRING8: StringArray_r = (const struct StringArray_r *) get_SPropValue_data(&lpProp); printf("%s%s: ", sep?sep:"", proptag); for (i = 0; i < StringArray_r->cValues - 1; i++) { printf("%s, ", StringArray_r->lppszA[i]); } printf("%s\n", StringArray_r->lppszA[i]); break; case PT_MV_UNICODE: StringArrayW_r = (const struct StringArrayW_r *) get_SPropValue_data(&lpProp); printf("%s%s: ", sep?sep:"", proptag); for (i = 0; i < StringArrayW_r->cValues - 1; i++) { printf("%s, ", StringArrayW_r->lppszW[i]); } printf("%s\n", StringArrayW_r->lppszW[i]); break; case PT_MV_BINARY: BinaryArray_r = (const struct BinaryArray_r *) get_SPropValue_data(&lpProp); printf("%s%s: ARRAY(%d)\n", sep?sep:"", proptag, BinaryArray_r->cValues); for (i = 0; i < BinaryArray_r->cValues; i++) { printf("\tPT_MV_BINARY [%d]:\n", i); dump_data(0, BinaryArray_r->lpbin[i].lpb, BinaryArray_r->lpbin[i].cb); } break; default: /* If you hit this assert, you'll need to implement whatever type is missing */ OC_ASSERT(0); break; } if (mem_ctx) { talloc_free(mem_ctx); } } _PUBLIC_ void mapidump_SPropTagArray(struct SPropTagArray *SPropTagArray) { uint32_t count; const char *proptag; if (!SPropTagArray) return; if (!SPropTagArray->cValues) return; for (count = 0; count != SPropTagArray->cValues; count++) { proptag = get_proptag_name(SPropTagArray->aulPropTag[count]); if (proptag) { printf("%s\n", proptag); } else { printf("0x%.8x\n", SPropTagArray->aulPropTag[count]); } } } _PUBLIC_ void mapidump_SRowSet(struct SRowSet *SRowSet, const char *sep) { uint32_t i; /* Sanity checks */ if (!SRowSet) return; if (!SRowSet->cRows) return; for (i = 0; i < SRowSet->cRows; i++) { mapidump_SRow(&(SRowSet->aRow[i]), sep); } } _PUBLIC_ void mapidump_SRow(struct SRow *aRow, const char *sep) { uint32_t i; for (i = 0; i < aRow->cValues; i++) { mapidump_SPropValue(aRow->lpProps[i], sep); } } /** Output a row of the public address book \param aRow one row of the public address book (Global Address List) This function is usually used with GetGALTable, which can obtain several rows at once - you'll need to iterate over the rows. The SRow is assumed to contain entries for PR_ADDRTYPE_UNICODE, PR_DISPLAY_NAME_UNICODE, PR_EMAIL_ADDRESS_UNICODE and PR_ACCOUNT_UNICODE. */ _PUBLIC_ void mapidump_PAB_entry(struct PropertyRow_r *aRow) { const char *addrtype; const char *name; const char *email; const char *account; addrtype = (const char *)find_PropertyValue_data(aRow, PR_ADDRTYPE_UNICODE); name = (const char *)find_PropertyValue_data(aRow, PR_DISPLAY_NAME_UNICODE); email = (const char *)find_PropertyValue_data(aRow, PR_EMAIL_ADDRESS_UNICODE); account = (const char *)find_PropertyValue_data(aRow, PR_ACCOUNT_UNICODE); printf("[%s] %s:\n\tName: %-25s\n\tEmail: %-25s\n", addrtype, account, name, email); fflush(0); } _PUBLIC_ void mapidump_Recipients(const char **usernames, struct SRowSet *rowset, struct PropertyTagArray_r *flaglist) { uint32_t i; uint32_t j; for (i = 0, j= 0; i < flaglist->cValues; i++) { switch ((int)flaglist->aulPropTag[i]) { case MAPI_UNRESOLVED: printf("\tUNRESOLVED (%s)\n", usernames[i]); break; case MAPI_AMBIGUOUS: printf("\tAMBIGUOUS (%s)\n", usernames[i]); break; case MAPI_RESOLVED: printf("\tRESOLVED (%s)\n", usernames[i]); mapidump_SRow(&rowset->aRow[j], "\t\t[+] "); j++; break; default: break; } } } _PUBLIC_ void mapidump_date(struct mapi_SPropValue_array *properties, uint32_t mapitag, const char *label) { TALLOC_CTX *mem_ctx; NTTIME time; const struct FILETIME *filetime; const char *date; mem_ctx = talloc_named(NULL, 0, "mapidump_date"); filetime = (const struct FILETIME *) find_mapi_SPropValue_data(properties, mapitag); if (filetime) { time = filetime->dwHighDateTime; time = time << 32; time |= filetime->dwLowDateTime; date = nt_time_string(mem_ctx, time); printf("\t%-15s: %s\n", label, date); fflush(0); } talloc_free(mem_ctx); } /** \details This function dumps a property containing a date / time to standard output If the property does not contain a PT_SYSTIME type value, then no output will occur. \param lpProp the property to dump \param label the label to display prior to the time (e.g. the property tag) \param sep a separator / spacer to insert in front of the label \note Prior to OpenChange 0.9, this function took 2 arguments, assuming a default separator of a tab. You can get the old behaviour by using "\t" for sep. */ _PUBLIC_ void mapidump_date_SPropValue(struct SPropValue lpProp, const char *label, const char *sep) { TALLOC_CTX *mem_ctx; NTTIME time; const struct FILETIME *filetime; const char *date; mem_ctx = talloc_named(NULL, 0, "mapidump_date_SPropValue"); filetime = (const struct FILETIME *) get_SPropValue_data(&lpProp); if (filetime) { time = filetime->dwHighDateTime; time = time << 32; time |= filetime->dwLowDateTime; date = nt_time_string(mem_ctx, time); printf("%s%s: %s\n", sep, label, date); fflush(0); } talloc_free(mem_ctx); } /** \details This function dumps message information retrieved from OpenMessage call. It provides a quick method to print message summaries with information such as subject and recipients. \param obj_message pointer to the MAPI message object to use */ _PUBLIC_ void mapidump_message_summary(mapi_object_t *obj_message) { mapi_object_message_t *msg; int *recipient_type; const char *recipient; uint32_t i; if (!obj_message) return; if (!obj_message->private_data) return; msg = (mapi_object_message_t *) obj_message->private_data; printf("Subject: "); if (msg->SubjectPrefix) { printf("[%s] ", msg->SubjectPrefix); } if (msg->NormalizedSubject) { printf("%s", msg->NormalizedSubject); } printf("\n"); if (!&(msg->SRowSet)) return; for (i = 0; i < msg->SRowSet.cRows; i++) { recipient_type = (int *) find_SPropValue_data(&(msg->SRowSet.aRow[i]), PR_RECIPIENT_TYPE); recipient = (const char *) find_SPropValue_data(&(msg->SRowSet.aRow[i]), PR_SMTP_ADDRESS_UNICODE); if (!recipient) { recipient = (const char *) find_SPropValue_data(&(msg->SRowSet.aRow[i]), PR_SMTP_ADDRESS); } if (recipient_type && recipient) { switch (*recipient_type) { case MAPI_ORIG: printf("From: %s\n", recipient); break; case MAPI_TO: printf("To: %s\n", recipient); break; case MAPI_CC: printf("Cc: %s\n", recipient); break; case MAPI_BCC: printf("Bcc: %s\n", recipient); break; } } } printf("\n"); } /** \details This function dumps the properties relating to an email message to standard output The expected way to obtain the properties array is to use OpenMessage() to obtain the message object, then to use GetPropsAll() to obtain all the properties. \param properties array of message properties \param id identification to display for the message (can be NULL) \param obj_msg pointer to the message MAPI object (can be NULL) \sa mapidump_appointment, mapidump_contact, mapidump_task, mapidump_note */ _PUBLIC_ void mapidump_message(struct mapi_SPropValue_array *properties, const char *id, mapi_object_t *obj_msg) { const char *msgid; const char *from; const char *to; const char *cc; const char *bcc; const char *subject; const char *body; const char *codepage; const struct SBinary_short *html = NULL; const uint8_t *has_attach; const uint32_t *cp; msgid = (const char *)find_mapi_SPropValue_data(properties, PR_INTERNET_MESSAGE_ID_UNICODE); if (!msgid) msgid = (const char *)find_mapi_SPropValue_data(properties, PR_INTERNET_MESSAGE_ID); subject = (const char *) find_mapi_SPropValue_data(properties, PR_CONVERSATION_TOPIC_UNICODE); if (!subject) subject = (const char *) find_mapi_SPropValue_data(properties, PR_CONVERSATION_TOPIC); body = (const char *) find_mapi_SPropValue_data(properties, PR_BODY_UNICODE); if (!body) { body = (const char *) find_mapi_SPropValue_data(properties, PR_BODY); if (!body) { html = (const struct SBinary_short *) find_mapi_SPropValue_data(properties, PR_HTML); } } from = (const char *) find_mapi_SPropValue_data(properties, PR_SENT_REPRESENTING_NAME_UNICODE); if (!from) from = (const char *) find_mapi_SPropValue_data(properties, PR_SENT_REPRESENTING_NAME); to = (const char *) find_mapi_SPropValue_data(properties, PR_DISPLAY_TO_UNICODE); if (!to) to = (const char *) find_mapi_SPropValue_data(properties, PR_DISPLAY_TO); cc = (const char *) find_mapi_SPropValue_data(properties, PR_DISPLAY_CC_UNICODE); if (!cc) cc = (const char *) find_mapi_SPropValue_data(properties, PR_DISPLAY_CC); bcc = (const char *) find_mapi_SPropValue_data(properties, PR_DISPLAY_BCC_UNICODE); if (!bcc) bcc = (const char *) find_mapi_SPropValue_data(properties, PR_DISPLAY_BCC); has_attach = (const uint8_t *)find_mapi_SPropValue_data(properties, PR_HASATTACH); cp = (const uint32_t *)find_mapi_SPropValue_data(properties, PR_MESSAGE_CODEPAGE); switch (cp ? *cp : 0) { case CP_USASCII: codepage = "CP_USASCII"; break; case CP_UNICODE: codepage = "CP_UNICODE"; break; case CP_JAUTODETECT: codepage = "CP_JAUTODETECT"; break; case CP_KAUTODETECT: codepage = "CP_KAUTODETECT"; break; case CP_ISO2022JPESC: codepage = "CP_ISO2022JPESC"; break; case CP_ISO2022JPSIO: codepage = "CP_ISO2022JPSIO"; break; default: codepage = ""; break; } printf("+-------------------------------------+\n"); printf("message id: %s %s\n", msgid ? msgid : "", id?id:""); if (obj_msg) { mapidump_message_summary(obj_msg); } else { printf("subject: %s\n", subject ? subject : ""); printf("From: %s\n", from ? from : ""); printf("To: %s\n", to ? to : ""); printf("Cc: %s\n", cc ? cc : ""); printf("Bcc: %s\n", bcc ? bcc : ""); } if (has_attach) { printf("Attachment: %s\n", *has_attach ? "True" : "False"); } printf("Codepage: %s\n", codepage); printf("Body:\n"); fflush(0); if (body) { printf("%s\n", body); } else if (html) { write(1, html->lpb, html->cb); write(1, "\n", 1); fflush(0); } } /** \details This function dumps the properties relating to an appointment to standard output The expected way to obtain the properties array is to use OpenMessage() to obtain the appointment object, then to use GetPropsAll() to obtain all the properties. \param properties array of appointment properties \param id identification to display for the appointment (can be NULL) \sa mapidump_message, mapidump_contact, mapidump_task, mapidump_note */ _PUBLIC_ void mapidump_appointment(struct mapi_SPropValue_array *properties, const char *id) { const struct mapi_SLPSTRArray *contacts = NULL; const char *subject = NULL; const char *location= NULL; const char *timezone = NULL; const uint32_t *status; const uint8_t *priv = NULL; uint32_t i; contacts = (const struct mapi_SLPSTRArray *)find_mapi_SPropValue_data(properties, PidLidContacts); subject = (const char *)find_mapi_SPropValue_data(properties, PR_CONVERSATION_TOPIC); timezone = (const char *)find_mapi_SPropValue_data(properties, PidLidTimeZoneDescription); location = (const char *)find_mapi_SPropValue_data(properties, PidLidLocation); status = (const uint32_t *)find_mapi_SPropValue_data(properties, PidLidBusyStatus); priv = (const uint8_t *)find_mapi_SPropValue_data(properties, PidLidPrivate); printf("|== %s ==| %s\n", subject?subject:"", id?id:""); fflush(0); if (location) { printf("\tLocation: %s\n", location); fflush(0); } mapidump_date(properties, PR_START_DATE, "Start time"); mapidump_date(properties, PR_END_DATE, "End time"); if (timezone) { printf("\tTimezone: %s\n", timezone); fflush(0); } printf("\tPrivate: %s\n", (priv && (*priv == true)) ? "True" : "False"); fflush(0); if (status) { printf("\tStatus: %s\n", get_task_status(*status)); fflush(0); } if (contacts) { printf("\tContacts:\n"); fflush(0); for (i = 0; i < contacts->cValues; i++) { printf("\t\tContact: %s\n", contacts->strings[i].lppszA); fflush(0); } } } /** \details This function dumps the properties relating to a contact (address book entry) to standard output The expected way to obtain the properties array is to use OpenMessage() to obtain the contact object, then to use GetPropsAll() to obtain all the properties. \param properties array of contact properties \param id identification to display for the contact (can be NULL) \sa mapidump_message, mapidump_appointment, mapidump_task, mapidump_note */ _PUBLIC_ void mapidump_contact(struct mapi_SPropValue_array *properties, const char *id) { const char *card_name =NULL; const char *topic =NULL; const char *full_name = NULL; const char *given_name = NULL; const char *surname = NULL; const char *company = NULL; const char *email = NULL; const char *title = NULL; const char *office_phone = NULL; const char *home_phone = NULL; const char *mobile_phone = NULL; const char *postal_address = NULL; const char *street_address = NULL; const char *locality = NULL; const char *state = NULL; const char *country = NULL; const char *department = NULL; const char *business_fax = NULL; const char *business_home_page = NULL; card_name = (const char *)find_mapi_SPropValue_data(properties, PidLidFileUnder); topic = (const char *)find_mapi_SPropValue_data(properties, PR_CONVERSATION_TOPIC); company = (const char *)find_mapi_SPropValue_data(properties, PR_COMPANY_NAME); title = (const char *)find_mapi_SPropValue_data(properties, PR_TITLE); full_name = (const char *)find_mapi_SPropValue_data(properties, PR_DISPLAY_NAME); given_name = (const char *)find_mapi_SPropValue_data(properties, PR_GIVEN_NAME); surname = (const char *)find_mapi_SPropValue_data(properties, PR_SURNAME); department = (const char *)find_mapi_SPropValue_data(properties, PR_DEPARTMENT_NAME); email = (const char *)find_mapi_SPropValue_data(properties, PidLidEmail1OriginalDisplayName); office_phone = (const char *)find_mapi_SPropValue_data(properties, PR_OFFICE_TELEPHONE_NUMBER); home_phone = (const char *)find_mapi_SPropValue_data(properties, PR_HOME_TELEPHONE_NUMBER); mobile_phone = (const char *)find_mapi_SPropValue_data(properties, PR_MOBILE_TELEPHONE_NUMBER); business_fax = (const char *)find_mapi_SPropValue_data(properties, PR_BUSINESS_FAX_NUMBER); business_home_page = (const char *)find_mapi_SPropValue_data(properties, PR_BUSINESS_HOME_PAGE); postal_address = (const char*)find_mapi_SPropValue_data(properties, PR_POSTAL_ADDRESS); street_address = (const char*)find_mapi_SPropValue_data(properties, PR_STREET_ADDRESS); locality = (const char*)find_mapi_SPropValue_data(properties, PR_LOCALITY); state = (const char*)find_mapi_SPropValue_data(properties, PR_STATE_OR_PROVINCE); country = (const char*)find_mapi_SPropValue_data(properties, PR_COUNTRY); if (card_name) printf("|== %s ==| %s\n", card_name, id?id:""); else if (topic) printf("|== %s ==| %s\n", topic, id?id:""); else printf("|== ==| %s\n", id?id:""); fflush(0); if (topic) printf("Topic: %s\n", topic); fflush(0); if (full_name) printf("Full Name: %s\n", full_name); else if (given_name && surname) printf("Full Name: %s %s\n", given_name, surname); // initials? l10n? fflush(0); if (title) printf("Job Title: %s\n", title); fflush(0); if (department) printf("Department: %s\n", department); fflush(0); if (company) printf("Company: %s\n", company); fflush(0); if (email) printf("E-mail: %s\n", email); fflush(0); if (office_phone) printf("Office phone number: %s\n", office_phone); fflush(0); if (home_phone) printf("Work phone number: %s\n", home_phone); fflush(0); if (mobile_phone) printf("Mobile phone number: %s\n", mobile_phone); fflush(0); if (business_fax) printf("Business fax number: %s\n", business_fax); fflush(0); if (business_home_page) printf("Business home page: %s\n", business_home_page); fflush(0); if (postal_address) printf("Postal address: %s\n", postal_address); fflush(0); if (street_address) printf("Street address: %s\n", street_address); fflush(0); if (locality) printf("Locality: %s\n", locality); fflush(0); if (state) printf("State / Province: %s\n", state); fflush(0); if (country) printf("Country: %s\n", country); fflush(0); printf("\n"); } _PUBLIC_ const char *get_task_status(uint32_t status) { switch (status) { case olTaskNotStarted: return ("Not Started"); case olTaskInProgress: return ("In Progress"); case olTaskComplete: return ("Completed"); case olTaskWaiting: return ("Waiting on someone else"); case olTaskDeferred: return ("Deferred"); } return NULL; } _PUBLIC_ const char *get_importance(uint32_t importance) { switch (importance) { case IMPORTANCE_LOW: return ("Low"); case IMPORTANCE_NORMAL: return ("Normal"); case IMPORTANCE_HIGH: return ("High"); } return NULL; } /** \details This function dumps the properties relating to a task (to-do list entry) to standard output The expected way to obtain the properties array is to use OpenMessage() to obtain the task object, then to use GetPropsAll() to obtain all the properties. \param properties array of task properties \param id identification to display for the task (can be NULL) \sa mapidump_message, mapidump_appointment, mapidump_contact, mapidump_note */ _PUBLIC_ void mapidump_task(struct mapi_SPropValue_array *properties, const char *id) { const struct mapi_SLPSTRArray *contacts = NULL; const char *subject = NULL; const char *body = NULL; const double *complete = 0; const uint32_t *status; const uint32_t *importance; const uint8_t *private_tag; uint32_t i; contacts = (const struct mapi_SLPSTRArray *)find_mapi_SPropValue_data(properties, PidLidContacts); subject = (const char *)find_mapi_SPropValue_data(properties, PR_CONVERSATION_TOPIC); body = (const char *)find_mapi_SPropValue_data(properties, PR_BODY); complete = (const double *)find_mapi_SPropValue_data(properties, PidLidPercentComplete); status = (const uint32_t *)find_mapi_SPropValue_data(properties, PidLidTaskStatus); importance = (const uint32_t *)find_mapi_SPropValue_data(properties, PR_IMPORTANCE); private_tag = (const uint8_t *)find_mapi_SPropValue_data(properties, PidLidPrivate); printf("|== %s ==| %s\n", subject?subject:"", id?id:""); fflush(0); printf("\tBody: %s\n", body?body:"none"); fflush(0); if (complete) { printf("\tComplete: %u %c\n", (uint32_t)(*complete * 100), '%'); fflush(0); } if (status) { printf("\tStatus: %s\n", get_task_status(*status)); fflush(0); if (*status == olTaskComplete) { mapidump_date(properties, PidLidTaskDateCompleted, "Date Completed"); } } if (importance) { printf("\tImportance: %s\n", get_importance(*importance)); fflush(0); } mapidump_date(properties, PidLidTaskDueDate,"Due Date"); mapidump_date(properties, PidLidTaskStartDate, "Start Date"); if (private_tag) { printf("\tPrivate: %s\n", (*private_tag == true)?"True":"False"); fflush(0); } else { printf("\tPrivate: false\n"); fflush(0); } if (contacts) { for (i = 0; i < contacts->cValues; i++) { printf("\tContact: %s\n", contacts->strings[i].lppszA); fflush(0); } } } /** \details This function dumps the properties relating to a note to standard output The expected way to obtain the properties array is to use OpenMessage() to obtain the note object, then to use GetPropsAll() to obtain all the properties. \param properties array of note properties \param id identification to display for the note (can be NULL) \sa mapidump_message, mapidump_appointment, mapidump_contact, mapidump_task */ _PUBLIC_ void mapidump_note(struct mapi_SPropValue_array *properties, const char *id) { const char *subject = NULL; const char *body = NULL; subject = (const char *)find_mapi_SPropValue_data(properties, PR_CONVERSATION_TOPIC); body = (const char *)find_mapi_SPropValue_data(properties, PR_BODY); printf("|== %s ==| %s\n", subject?subject:"", id?id:""); fflush(0); mapidump_date(properties, PR_CLIENT_SUBMIT_TIME, "Submit Time"); if (body) { printf("Content:\n"); printf("%s\n", body); fflush(0); } else { body = (const char *)find_mapi_SPropValue_data(properties, PR_BODY_HTML); if (body) { printf("Content HTML:\n"); printf("%s\n", body); fflush(0); } } } _PUBLIC_ void mapidump_msgflags(uint32_t MsgFlags, const char *sep) { uint32_t i; for (i = 0; mdump_msgflags[i].flag; i++) { if (MsgFlags & mdump_msgflags[i].flag) { printf("%s\t%s (0x%x)\n", sep?sep:"", mdump_msgflags[i].value, mdump_msgflags[i].flag); fflush(0); } } } _PUBLIC_ void mapidump_newmail(struct NewMailNotification *newmail, const char *sep) { printf("%sParent Entry ID: 0x%"PRIx64"\n", sep?sep:"", newmail->FID); fflush(0); printf("%sMessage Entry ID: 0x%"PRIx64"\n", sep?sep:"", newmail->MID); fflush(0); printf("%sMessage flags:\n", sep?sep:""); fflush(0); mapidump_msgflags(newmail->MessageFlags, sep); if (newmail->UnicodeFlag == 0x0) { printf("%sMessage Class: %s\n", sep?sep:"", newmail->MessageClass.lpszA); } else { printf("%sMessage Class: %s\n", sep?sep:"", newmail->MessageClass.lpszW); } fflush(0); } _PUBLIC_ void mapidump_tags(enum MAPITAGS *Tags, uint16_t TagCount, const char *sep) { uint32_t i; const char *proptag; for (i = 0; i < TagCount; i++) { proptag = get_proptag_name(Tags[i]); printf("%s Tag: %s\n", sep?sep:"", proptag); fflush(0); } } _PUBLIC_ void mapidump_foldercreated(struct FolderCreatedNotification *data, const char *sep) { if (!data) { return; } printf("%sParent Folder Entry ID: 0x%"PRIx64"\n", sep?sep:"", data->ParentFID); fflush(0); printf("%sFolder Entry ID: 0x%"PRIx64"\n", sep?sep:"", data->FID); fflush(0); mapidump_tags (data->NotificationTags.Tags, data->TagCount, sep); } _PUBLIC_ void mapidump_folderdeleted(struct FolderDeletedNotification *data, const char *sep) { if (!data) { return; } printf("%sParent Folder Entry ID: 0x%"PRIx64"\n", sep?sep:"", data->ParentFID); fflush(0); printf("%sFolder Entry ID: 0x%"PRIx64"\n", sep?sep:"", data->FID); fflush(0); } _PUBLIC_ void mapidump_foldermoved(struct FolderMoveCopyNotification *data, const char *sep) { if (!data) { return; } printf("%sParent Folder Entry ID: 0x%"PRIx64"\n", sep?sep:"", data->ParentFID); fflush(0); printf("%sFolder Entry ID: 0x%"PRIx64"\n", sep?sep:"", data->FID); fflush(0); printf("%sOld Parent Folder Entry ID: 0x%"PRIx64"\n", sep?sep:"", data->OldParentFID); fflush(0); printf("%sOld Folder Entry ID: 0x%"PRIx64"\n", sep?sep:"", data->OldFID); fflush(0); } _PUBLIC_ void mapidump_foldercopied(struct FolderMoveCopyNotification *data, const char *sep) { mapidump_foldermoved(data, sep); } _PUBLIC_ void mapidump_messagedeleted(struct MessageDeletedNotification *data, const char *sep) { if (!data) { return; } printf("%sFolder Entry ID: 0x%"PRIx64"\n", sep?sep:"", data->FID); fflush(0); printf("%sMessage Entry ID: 0x%"PRIx64"\n", sep?sep:"", data->MID); fflush(0); } _PUBLIC_ void mapidump_messagecreated(struct MessageCreatedNotification *data, const char *sep) { if (!data) { return; } printf("%sFolder Entry ID: 0x%"PRIx64"\n", sep?sep:"", data->FID); fflush(0); printf("%sMessage Entry ID: 0x%"PRIx64"\n", sep?sep:"", data->MID); fflush(0); if (data->TagCount != 0xffff) { mapidump_tags (data->NotificationTags.Tags, data->TagCount, sep); } } _PUBLIC_ void mapidump_messagemodified(struct MessageModifiedNotification *data, const char *sep) { mapidump_messagecreated((struct MessageCreatedNotification *)data, sep); } _PUBLIC_ void mapidump_messagemoved(struct MessageMoveCopyNotification *data, const char *sep) { if (!data) { return; } printf("%sFolder Entry ID: 0x%"PRIx64"\n", sep?sep:"", data->FID); fflush(0); printf("%sMessage Entry ID: 0x%"PRIx64"\n", sep?sep:"", data->MID); fflush(0); printf("%sOld Parent Folder Entry ID: 0x%"PRIx64"\n", sep?sep:"", data->OldFID); fflush(0); printf("%sOld Message Entry ID: 0x%"PRIx64"\n", sep?sep:"", data->OldMID); } _PUBLIC_ void mapidump_messagecopied(struct MessageMoveCopyNotification *data, const char *sep) { mapidump_messagemoved(data, sep); } _PUBLIC_ const char *mapidump_freebusy_month(uint32_t month, uint32_t year) { uint32_t realmonth; realmonth = month - (year * 16); switch (realmonth) { case 0x1: return "January"; case 0x2: return "February"; case 0x3: return "March"; case 0x4: return "April"; case 0x5: return "May"; case 0x6: return "June"; case 0x7: return "July"; case 0x8: return "August"; case 0x9: return "September"; case 0xa: return "October"; case 0xb: return "November"; case 0xc: return "December"; } return NULL; } _PUBLIC_ uint32_t mapidump_freebusy_year(uint32_t month, uint32_t year) { uint32_t realmonth; realmonth = month - (year * 16); while (realmonth > 0xc) { year++; realmonth = month - (year * 16); } return year; } _PUBLIC_ void mapidump_freebusy_date(uint32_t t, const char *sep) { TALLOC_CTX *mem_ctx; NTTIME time; const char *date; mem_ctx = talloc_named(NULL, 0, "mapidump_freebusy_date"); time = t; time *= 60; time *= 10000000; date = nt_time_string(mem_ctx, time); DEBUG(0, ("%s %-30s\n", sep, date)); talloc_free((char *)date); talloc_free(mem_ctx); } _PUBLIC_ void mapidump_freebusy_event(struct Binary_r *bin, uint32_t month, uint32_t year, const char *sep) { uint16_t event_start; uint16_t event_end; uint32_t i; uint32_t hour; uint32_t hours; uint32_t day; const char *month_name; uint32_t last; uint32_t minutes = 0; if (!bin) return; /* bin.cb must be a multiple of 4 */ if (bin->cb % 4) return; year = mapidump_freebusy_year(month, year); month_name = mapidump_freebusy_month(month, year); if (!month_name) return; for (i = 0; i < bin->cb; i+= 4) { event_start = (bin->lpb[i + 1] << 8) | bin->lpb[i]; event_end = (bin->lpb[i + 3] << 8) | bin->lpb[i + 2]; for (hour = 0; hour < 24; hour++) { if (!(((event_start - (60 * hour)) % 1440) && (((event_start - (60 * hour)) % 1440) - 30))) { day = ((event_start - (60 * hour)) / 1440) + 1; minutes = (event_start - (60 * hour)) % 1440; last = event_end - event_start; #if defined (__FreeBSD__) DEBUG(0, ("%s %u %s %u at %.2u%.2u hrs and lasts ", sep ? sep : "", day, month_name, year, hour, minutes)); #else DEBUG(0, ("%s %u %s %u at %.2u%.2u hrs and lasts ", sep ? sep : "", day, month_name, year, hour + daylight, minutes)); #endif if (last < 60) { DEBUG(0, ("%u mins\n", last)); } else { hours = last / 60; minutes = last - hours * 60; if (minutes > 0) { DEBUG(0, ("%u hrs %u mins\n", hours, minutes)); } else { DEBUG(0, ("%u hrs\n", hours)); } } } } } } /** \details print the list of languages OpenChange supports */ _PUBLIC_ void mapidump_languages_list(void) { mapi_get_language_list(); } openchange-2.0/libmapi/mapidump.h000066400000000000000000000022771223057412600170760ustar00rootroot00000000000000/* OpenChange MAPI implementation. Copyright (C) Julien Kerihuel 2007. This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see . */ #ifndef __MAPIDUMP_H__ #define __MAPIDUMP_H__ struct mdump_msgflags { uint16_t flag; const char *value; }; struct mdump_msgflags mdump_msgflags[] = { {0x1, "MSGFLAG_READ"}, {0x2, "MSGFLAG_UNMODIFIED"}, {0x4, "MSGFLAG_SUBMIT"}, {0x8, "MSGFLAG_UNSENT"}, {0x10, "MSGFLAG_HASATTACH"}, {0x20, "MSGFLAG_FROMME"}, {0x40, "MSGFLAG_ASSOCIATED"}, {0x80, "MSGFLAG_RESEND"}, {0x100, "MSGFLAG_RN_PENDING"}, {0x200, "MSGFLAG_NRN_PENDING"}, {0, NULL} }; #endif /* __MAPIDUMP_H__ */ openchange-2.0/libmapi/notif.c000066400000000000000000000152061223057412600163700ustar00rootroot00000000000000/* OpenChange MAPI implementation. Copyright (C) Brad Hards 2011. This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see . */ #include "libmapi/libmapi.h" #include "libmapi/libmapi_private.h" /** \file notif.c \brief Notification (MS-OXCNOTIF) operations */ /** \details Obtain an ICS notification object This function is used to obtain a server object handle for an ICS notification operation (RegisterSyncNotifications or SetSyncNotificationGuid). This operation is not supported on Exchange 2010. \param obj the logon object for which notifications are desired \param obj_notifier the notifier object for future ROPs. \return MAPI_E_SUCCESS on success, otherwise MAPI error. The caller should release the returned notifier object when it is no longer required, using the mapi_object_release function. \note Developers may also call GetLastError() to retrieve the last MAPI error code. Possible MAPI error codes are: - MAPI_E_NOT_INITIALIZED: MAPI subsystem has not been initialized - MAPI_E_INVALID_PARAMETER: one of the function parameters is invalid - MAPI_E_CALL_FAILED: A network problem was encountered during the transaction */ _PUBLIC_ enum MAPISTATUS SyncOpenAdvisor(mapi_object_t *obj, mapi_object_t *obj_notifier) { struct mapi_request *mapi_request; struct mapi_response *mapi_response; struct EcDoRpc_MAPI_REQ *mapi_req; struct SyncOpenAdvisor_req request; struct mapi_session *session; NTSTATUS status; enum MAPISTATUS retval; uint32_t size = 0; TALLOC_CTX *mem_ctx; uint8_t logon_id = 0; /* Sanity checks */ OPENCHANGE_RETVAL_IF(!obj, MAPI_E_INVALID_PARAMETER, NULL); session = mapi_object_get_session(obj); OPENCHANGE_RETVAL_IF(!session, MAPI_E_INVALID_PARAMETER, NULL); OPENCHANGE_RETVAL_IF(!obj_notifier, MAPI_E_INVALID_PARAMETER, NULL); if ((retval = mapi_object_get_logon_id(obj, &logon_id)) != MAPI_E_SUCCESS) return retval; mem_ctx = talloc_named(session, 0, __FUNCTION__); /* Fill the SyncOpenAdvisor operation */ request.handle_idx = 0x01; size += sizeof(uint8_t); /* Fill the MAPI_REQ structure */ mapi_req = talloc_zero(mem_ctx, struct EcDoRpc_MAPI_REQ); mapi_req->opnum = op_MAPI_SyncOpenAdvisor; mapi_req->logon_id = logon_id; mapi_req->handle_idx = 0; mapi_req->u.mapi_SyncOpenAdvisor = request; size += 5; /* Fill the mapi_request structure */ mapi_request = talloc_zero(mem_ctx, struct mapi_request); mapi_request->mapi_len = size + sizeof (uint32_t) * 2; mapi_request->length = (uint16_t)size; mapi_request->mapi_req = mapi_req; mapi_request->handles = talloc_array(mem_ctx, uint32_t, 2); mapi_request->handles[0] = mapi_object_get_handle(obj); mapi_request->handles[1] = 0xFFFFFFFF; status = emsmdb_transaction_wrapper(session, mem_ctx, mapi_request, &mapi_response); OPENCHANGE_RETVAL_IF(!NT_STATUS_IS_OK(status), MAPI_E_CALL_FAILED, mem_ctx); OPENCHANGE_RETVAL_IF(!mapi_response->mapi_repl, MAPI_E_CALL_FAILED, mem_ctx); retval = mapi_response->mapi_repl->error_code; OPENCHANGE_RETVAL_IF(retval, retval, mem_ctx); /* Set object session and handle */ mapi_object_set_session(obj_notifier, session); mapi_object_set_handle(obj_notifier, mapi_response->handles[1]); mapi_object_set_logon_id(obj_notifier, logon_id); talloc_free(mapi_response); talloc_free(mem_ctx); return MAPI_E_SUCCESS; } /** \details Assign a notification GUID to an ICS Advisor object This function allows the client to set a specific GUID to an ICS advistor object (as returned from SyncOpenAdvisor). This operation is not supported on Exchange 2010. \param obj_advisor pointer to the ICS Advisor object \param Guid the GUID for the notification \return MAPI_E_SUCCESS on success, otherwise MAPI error. \note Developers may also call GetLastError() to retrieve the last MAPI error code. Possible MAPI error codes are: - MAPI_E_NOT_INITIALIZED: MAPI subsystem has not been initialized - MAPI_E_INVALID_PARAMETER: one of the function parameters is invalid - MAPI_E_CALL_FAILED: A network problem was encountered during the transaction */ _PUBLIC_ enum MAPISTATUS SetSyncNotificationGuid(mapi_object_t *obj_advisor, const struct GUID Guid) { struct mapi_request *mapi_request; struct mapi_response *mapi_response; struct EcDoRpc_MAPI_REQ *mapi_req; struct SetSyncNotificationGuid_req request; struct mapi_session *session; NTSTATUS status; enum MAPISTATUS retval; uint32_t size = 0; TALLOC_CTX *mem_ctx; uint8_t logon_id = 0; /* Sanity checks */ OPENCHANGE_RETVAL_IF(!obj_advisor, MAPI_E_INVALID_PARAMETER, NULL); session = mapi_object_get_session(obj_advisor); OPENCHANGE_RETVAL_IF(!session, MAPI_E_INVALID_PARAMETER, NULL); if ((retval = mapi_object_get_logon_id(obj_advisor, &logon_id)) != MAPI_E_SUCCESS) { return retval; } mem_ctx = talloc_named(session, 0, __FUNCTION__); /* Fill the SetSyncNotificationGuid operation */ request.NotificationGuid = Guid; size += sizeof(struct GUID); /* Fill the MAPI_REQ structure */ mapi_req = talloc_zero(mem_ctx, struct EcDoRpc_MAPI_REQ); mapi_req->opnum = op_MAPI_SetSyncNotificationGuid; mapi_req->logon_id = logon_id; mapi_req->handle_idx = 0; mapi_req->u.mapi_SetSyncNotificationGuid = request; size += 5; /* Fill the mapi_request structure */ mapi_request = talloc_zero(mem_ctx, struct mapi_request); mapi_request->mapi_len = size + sizeof (uint32_t); mapi_request->length = (uint16_t)size; mapi_request->mapi_req = mapi_req; mapi_request->handles = talloc_array(mem_ctx, uint32_t, 1); mapi_request->handles[0] = mapi_object_get_handle(obj_advisor); status = emsmdb_transaction_wrapper(session, mem_ctx, mapi_request, &mapi_response); OPENCHANGE_RETVAL_IF(!NT_STATUS_IS_OK(status), MAPI_E_CALL_FAILED, mem_ctx); OPENCHANGE_RETVAL_IF(!mapi_response->mapi_repl, MAPI_E_CALL_FAILED, mem_ctx); retval = mapi_response->mapi_repl->error_code; OPENCHANGE_RETVAL_IF(retval, retval, mem_ctx); OPENCHANGE_CHECK_NOTIFICATION(session, mapi_response); talloc_free(mapi_response); talloc_free(mem_ctx); return MAPI_E_SUCCESS; } openchange-2.0/libmapi/nspi.c000066400000000000000000001113541223057412600162230ustar00rootroot00000000000000/* OpenChange NSPI implementation. Copyright (C) Julien Kerihuel 2005 - 2011. This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see . */ #include "libmapi/libmapi.h" #include "libmapi/libmapi_private.h" #include "gen_ndr/ndr_exchange_c.h" #include /** \file nspi.c \brief Name Service Provider (NSPI) stack functions */ /** \details Initialize the STAT structure and set common STAT parameters \param mem_ctx pointer to the memory context \param CodePage the CodePage value to set in the STAT structure \param TemplateLocale the Locale for the STAT TemplateLocale parameter \param SortLocale the Locale for the STAT SortLocal parameter */ static struct STAT *nspi_set_STAT(TALLOC_CTX *mem_ctx, uint32_t CodePage, uint32_t TemplateLocale, uint32_t SortLocale) { struct STAT *pStat; /* Sanity Checks */ if (!CodePage || !TemplateLocale || !SortLocale) { return NULL; } pStat = talloc_zero(mem_ctx, struct STAT); pStat->SortType = SortTypeDisplayName; pStat->CodePage = CodePage; pStat->TemplateLocale = TemplateLocale; pStat->SortLocale = SortLocale; return pStat; } /** \details Initiates a session between a client and the NSPI server. \param parent_ctx pointer to the memory context \param p pointer to the DCERPC pipe \param cred pointer to the user credentials \param codepage the code to set in the STAT structure \param language the language to set in the STAT structure \param method the method to set in the STAT structure \return Allocated pointer to a nspi_context structure on success, otherwise NULL */ _PUBLIC_ struct nspi_context *nspi_bind(TALLOC_CTX *parent_ctx, struct dcerpc_pipe *p, struct cli_credentials *cred, uint32_t codepage, uint32_t language, uint32_t method) { TALLOC_CTX *mem_ctx; struct NspiBind r; NTSTATUS status; enum MAPISTATUS retval; struct nspi_context *ret; struct GUID guid; /* Sanity checks */ if (!p) return NULL; if (!cred) return NULL; ret = talloc(parent_ctx, struct nspi_context); ret->rpc_connection = p; ret->mem_ctx = parent_ctx; ret->cred = cred; ret->version = 0; /* Sanity Checks */ if (!(ret->pStat = nspi_set_STAT((TALLOC_CTX *) ret, codepage, language, method))) { talloc_free(ret); return NULL; } mem_ctx = talloc_named(parent_ctx, 0, __FUNCTION__); r.in.dwFlags = 0; r.in.pStat = ret->pStat; r.in.pStat->ContainerID = 0x0; r.in.mapiuid = talloc(mem_ctx, struct GUID); memset(r.in.mapiuid, 0, sizeof(struct GUID)); r.out.mapiuid = &guid; r.in.mapiuid = talloc(mem_ctx, struct GUID); memset(r.in.mapiuid, 0, sizeof(struct GUID)); r.out.handle = &ret->handle; status = dcerpc_NspiBind_r(p->binding_handle, mem_ctx, &r); retval = r.out.result; if ((!NT_STATUS_IS_OK(status)) || (retval != MAPI_E_SUCCESS)) { talloc_free(ret); talloc_free(mem_ctx); return NULL; } talloc_free(mem_ctx); return ret; } /** \details Destructor for the NSPI context. Call the NspiUnbind function. \param data generic pointer to data with mapi_provider information \return MAPI_E_SUCCESS on success, otherwise MAPI error. */ int nspi_disconnect_dtor(void *data) { enum MAPISTATUS retval; struct mapi_provider *provider = (struct mapi_provider *) data; retval = nspi_unbind((struct nspi_context *)provider->ctx); return retval; } /** \details Destroys the context handle \param nspi_ctx pointer to the NSPI connection context \return return 1 on success or 2 if the input context is NULL */ _PUBLIC_ enum MAPISTATUS nspi_unbind(struct nspi_context *nspi_ctx) { struct NspiUnbind r; NTSTATUS status; enum MAPISTATUS retval; /* Sanity checks */ OPENCHANGE_RETVAL_IF(!nspi_ctx, MAPI_E_NOT_INITIALIZED, NULL); r.in.handle = r.out.handle = &nspi_ctx->handle; r.in.Reserved = 0; status = dcerpc_NspiUnbind_r(nspi_ctx->rpc_connection->binding_handle, nspi_ctx->mem_ctx, &r); retval = r.out.result; OPENCHANGE_RETVAL_IF((retval != 1) && !MAPI_STATUS_IS_OK(NT_STATUS_V(status)), retval, NULL); return MAPI_E_SUCCESS; } /** \details Updates the STAT block representing position in a table to reflect positioning changes requested by the client. \param nspi_ctx pointer to the NSPI connection context \param mem_ctx pointer to the memory context \param plDelta pointer to an unsigned long indicating movement within the address book container specified by the input parameter pStat. \return MAPI_E_SUCCESS on success, otherwise MAPI error */ _PUBLIC_ enum MAPISTATUS nspi_UpdateStat(struct nspi_context *nspi_ctx, TALLOC_CTX *mem_ctx, uint32_t *plDelta) { struct NspiUpdateStat r; NTSTATUS status; enum MAPISTATUS retval; /* Sanity checks */ OPENCHANGE_RETVAL_IF(!nspi_ctx, MAPI_E_NOT_INITIALIZED, NULL); OPENCHANGE_RETVAL_IF(!mem_ctx, MAPI_E_INVALID_PARAMETER, NULL); OPENCHANGE_RETVAL_IF(!plDelta, MAPI_E_INVALID_PARAMETER, NULL); r.in.handle = &nspi_ctx->handle; r.in.Reserved = 0x0; r.in.pStat = nspi_ctx->pStat; r.in.plDelta = plDelta; r.out.pStat = nspi_ctx->pStat; r.out.plDelta = r.in.plDelta; status = dcerpc_NspiUpdateStat_r(nspi_ctx->rpc_connection->binding_handle, mem_ctx, &r); retval = r.out.result; OPENCHANGE_RETVAL_IF(!NT_STATUS_IS_OK(status), retval, NULL); OPENCHANGE_RETVAL_IF(retval, retval, NULL); return MAPI_E_SUCCESS; } /** \details Returns a number of Rows from a specified table. \param nspi_ctx pointer to the NSPI connection context \param mem_ctx pointer to the memory context \param pPropTags pointer to the list of proptags that the client requires to be returned for each row. \param MIds pointer to a list of values representing an Explicit table \param count the number of rows requested \param ppRows pointer on pointer to the the rows returned by the server \return MAPI_E_SUCCESS on success, otherwise MAPI error */ _PUBLIC_ enum MAPISTATUS nspi_QueryRows(struct nspi_context *nspi_ctx, TALLOC_CTX *mem_ctx, struct SPropTagArray *pPropTags, struct PropertyTagArray_r *MIds, uint32_t count, struct PropertyRowSet_r **ppRows) { struct NspiQueryRows r; NTSTATUS status; enum MAPISTATUS retval; struct STAT *pStat; /* Sanity Checks */ OPENCHANGE_RETVAL_IF(!nspi_ctx, MAPI_E_NOT_INITIALIZED, NULL); OPENCHANGE_RETVAL_IF(!mem_ctx, MAPI_E_INVALID_PARAMETER, NULL); r.in.handle = &nspi_ctx->handle; r.in.dwFlags = 0x0; r.in.pStat = nspi_ctx->pStat; if (MIds && MIds->cValues) { r.in.dwETableCount = MIds->cValues; r.in.lpETable = (uint32_t *) MIds->aulPropTag; /* We set CurrentRec to the first entry */ r.in.pStat->CurrentRec = MIds->aulPropTag[0]; } else { r.in.dwETableCount = 0; r.in.lpETable = NULL; } r.in.Count = count; r.in.pPropTags = pPropTags; pStat = talloc(mem_ctx, struct STAT); r.out.pStat = pStat; r.out.ppRows = ppRows; status = dcerpc_NspiQueryRows_r(nspi_ctx->rpc_connection->binding_handle, mem_ctx, &r); retval = r.out.result; OPENCHANGE_RETVAL_IF(!NT_STATUS_IS_OK(status), retval, NULL); OPENCHANGE_RETVAL_IF(retval, retval, NULL); nspi_ctx->pStat->CurrentRec = r.out.pStat->CurrentRec; nspi_ctx->pStat->Delta = r.out.pStat->Delta; nspi_ctx->pStat->NumPos = r.out.pStat->NumPos; nspi_ctx->pStat->TotalRecs = r.out.pStat->TotalRecs; return MAPI_E_SUCCESS; } /** \details Searches for and sets the logical position in a specific table to the first entry greater than or equal to a specified value. Optionally, it might also return information about rows in the table. \param nspi_ctx pointer to the NSPI connection context \param mem_ctx pointer to the memory context \param SortType the table sort order to use \param pTarget PropertyValue_r struct holding the value being sought \param pPropTags pointer to an array of property tags of columns that the client wants to be returned for each row returned. \param pMIds pointer to a list of Mid that comprise a restricted address book container \param pRows pointer to pointer to a SRowSet structure holding the rows returned by the server SortType can take the following values: -# SortTypeDisplayName -# SortTypePhoneticDisplayName If pTarget property tag is not set accordingly to SortType, the function returns MAPI_E_INVALID_PARAMETER. Possible values are: -# SortType set to SortTypeDisplayName and pTarget property tag set to PR_DISPLAY_NAME or PR_DISPLAY_UNICODE -# SortType set to SortTypePhoneticDisplayName and pTarget property tag set to PR_EMS_AB_PHONETIC_DISPLAY_NAME or PR_EMS_AB_PHONETIC_DISPLAY_NAME_UNICODE \return MAPI_E_SUCCESS on success, otherwise MAPI error */ _PUBLIC_ enum MAPISTATUS nspi_SeekEntries(struct nspi_context *nspi_ctx, TALLOC_CTX *mem_ctx, enum TableSortOrders SortType, struct PropertyValue_r *pTarget, struct SPropTagArray *pPropTags, struct PropertyTagArray_r *pMIds, struct PropertyRowSet_r **pRows) { struct NspiSeekEntries r; NTSTATUS status; enum MAPISTATUS retval; struct STAT *pStat; /* Sanity Checks */ OPENCHANGE_RETVAL_IF(!nspi_ctx, MAPI_E_NOT_INITIALIZED, NULL); OPENCHANGE_RETVAL_IF(!mem_ctx, MAPI_E_INVALID_PARAMETER, NULL); OPENCHANGE_RETVAL_IF(!pTarget, MAPI_E_INVALID_PARAMETER, NULL); OPENCHANGE_RETVAL_IF(!pRows, MAPI_E_INVALID_PARAMETER, NULL); OPENCHANGE_RETVAL_IF(((SortType != SortTypeDisplayName) && (SortType != SortTypePhoneticDisplayName)), MAPI_E_INVALID_PARAMETER, NULL); /* Sanity Checks on SortType and pTarget combination */ OPENCHANGE_RETVAL_IF(((SortType == SortTypeDisplayName) && (pTarget->ulPropTag != PR_DISPLAY_NAME) && (pTarget->ulPropTag != PR_DISPLAY_NAME_UNICODE)), MAPI_E_INVALID_PARAMETER, NULL); OPENCHANGE_RETVAL_IF(((SortType == SortTypePhoneticDisplayName) && (pTarget->ulPropTag != PR_EMS_AB_PHONETIC_DISPLAY_NAME) && (pTarget->ulPropTag != PR_EMS_AB_PHONETIC_DISPLAY_NAME_UNICODE)), MAPI_E_INVALID_PARAMETER, NULL); r.in.handle = &nspi_ctx->handle; r.in.Reserved = 0x0; r.in.pStat = nspi_ctx->pStat; r.in.pStat->SortType = SortType; r.in.pTarget = pTarget; if (pMIds && pMIds->cValues) { r.in.lpETable = pMIds; } else { r.in.lpETable = NULL; } r.in.pPropTags = pPropTags; r.out.pRows = pRows; pStat = talloc(mem_ctx, struct STAT); r.out.pStat = pStat; status = dcerpc_NspiSeekEntries_r(nspi_ctx->rpc_connection->binding_handle, mem_ctx, &r); retval = r.out.result; OPENCHANGE_RETVAL_IF(!NT_STATUS_IS_OK(status), retval, pStat); OPENCHANGE_RETVAL_IF(retval, retval, pStat); nspi_ctx->pStat->CurrentRec = r.out.pStat->CurrentRec; nspi_ctx->pStat->Delta = r.out.pStat->Delta; nspi_ctx->pStat->NumPos = r.out.pStat->NumPos; nspi_ctx->pStat->TotalRecs = r.out.pStat->TotalRecs; return MAPI_E_SUCCESS; } /** \details Returns an explicit table. \param nspi_ctx pointer to the NSPI connection context \param mem_ctx pointer to the memory context \param pPropTags pointer to an array of property tags of columns \param Filter pointer to the Restriction to apply to the table \param ulRequested The upper limit for returned rows \param ppRows pointer to pointer to a SRowSet structure holding the rows returned by the server \param ppOutMIds pointer to pointer to a list of MId that comprise a restricted address book container \return MAPI_E_SUCCESS on success, otherwise MAPI error. If the resulting table rows count will be greater than ulRequested, then an error MAPI_E_TABLE_TOO_BIG is returned. Note, this error can be also returned when server limits for table size are exceeded. */ _PUBLIC_ enum MAPISTATUS nspi_GetMatches(struct nspi_context *nspi_ctx, TALLOC_CTX *mem_ctx, struct SPropTagArray *pPropTags, struct Restriction_r *Filter, uint32_t ulRequested, struct PropertyRowSet_r **ppRows, struct PropertyTagArray_r **ppOutMIds) { struct NspiGetMatches r; NTSTATUS status; enum MAPISTATUS retval; struct STAT *pStat; /* Sanity checks */ OPENCHANGE_RETVAL_IF(!nspi_ctx, MAPI_E_NOT_INITIALIZED, NULL); OPENCHANGE_RETVAL_IF(!mem_ctx, MAPI_E_INVALID_PARAMETER, NULL); OPENCHANGE_RETVAL_IF(!ppRows, MAPI_E_INVALID_PARAMETER, NULL); OPENCHANGE_RETVAL_IF(!ppOutMIds, MAPI_E_INVALID_PARAMETER, NULL); r.in.handle = &nspi_ctx->handle; r.in.Reserved = 0; r.in.pStat = nspi_ctx->pStat; r.in.pStat->ContainerID = 0x0; r.in.pStat->CurrentRec = 0x0; r.in.pStat->Delta = 0x0; r.in.pStat->NumPos = 0x0; r.in.pStat->TotalRecs = 0x0; r.in.pReserved = NULL; r.in.Reserved2 = 0; r.in.Filter = Filter; r.in.lpPropName = NULL; r.in.ulRequested = ulRequested; r.in.pPropTags = pPropTags; pStat = talloc(mem_ctx, struct STAT); r.out.pStat = pStat; r.out.ppOutMIds = ppOutMIds; r.out.ppRows = ppRows; status = dcerpc_NspiGetMatches_r(nspi_ctx->rpc_connection->binding_handle, mem_ctx, &r); retval = r.out.result; OPENCHANGE_RETVAL_IF(!NT_STATUS_IS_OK(status), MAPI_E_NOT_FOUND, NULL); OPENCHANGE_RETVAL_IF(retval, retval, NULL); return MAPI_E_SUCCESS; } /** \details Applies a sort order to the objects in a restricted address book container \param nspi_ctx pointer to the NSPI connection context \param mem_ctx pointer to the memory context \param SortType the table sort order to use \param pInMIds pointer on a list of MIds that comprise a restricted address book container \param ppMIds pointer on pointer to the returned list of MIds that comprise a restricted address book container. SortType can take the following values: -# SortTypeDisplayName -# SortTypePhoneticDisplayName \return MAPI_E_SUCCESS on success, otherwise MAPI error */ _PUBLIC_ enum MAPISTATUS nspi_ResortRestriction(struct nspi_context *nspi_ctx, TALLOC_CTX *mem_ctx, enum TableSortOrders SortType, struct PropertyTagArray_r *pInMIds, struct PropertyTagArray_r **ppMIds) { struct NspiResortRestriction r; enum MAPISTATUS retval; NTSTATUS status; struct PropertyTagArray_r *ppInMIds = NULL; struct STAT *pStat = NULL; /* Sanity checks */ OPENCHANGE_RETVAL_IF(!nspi_ctx, MAPI_E_NOT_INITIALIZED, NULL); OPENCHANGE_RETVAL_IF(!mem_ctx, MAPI_E_INVALID_PARAMETER, NULL); OPENCHANGE_RETVAL_IF(!pInMIds, MAPI_E_INVALID_PARAMETER, NULL); OPENCHANGE_RETVAL_IF(!ppMIds, MAPI_E_INVALID_PARAMETER, NULL); /* Sanity check on SortType */ OPENCHANGE_RETVAL_IF(((SortType != SortTypeDisplayName) && (SortType != SortTypePhoneticDisplayName)), MAPI_E_INVALID_PARAMETER, NULL); r.in.handle = &nspi_ctx->handle; r.in.Reserved = 0; r.in.pStat = nspi_ctx->pStat; r.in.pStat->SortType = SortType; r.in.pInMIds = pInMIds; r.in.ppMIds = &ppInMIds; pStat = talloc_zero(mem_ctx, struct STAT); r.out.pStat = pStat; r.out.ppMIds = ppMIds; status = dcerpc_NspiResortRestriction_r(nspi_ctx->rpc_connection->binding_handle, mem_ctx, &r); retval = r.out.result; OPENCHANGE_RETVAL_IF(!NT_STATUS_IS_OK(status), MAPI_E_CALL_FAILED, NULL); OPENCHANGE_RETVAL_IF(retval, retval, NULL); return MAPI_E_SUCCESS; } /** \details Maps a set of DN to a set of MId \param nspi_ctx pointer to the NSPI connection context \param mem_ctx pointer to the memory context \param pNames pointer to a StringsArray_r structure with the DN to map \param ppMIds pointer on pointer to the returned list of MIds \return MAPI_E_SUCCESS on success, otherwise MAPI error */ _PUBLIC_ enum MAPISTATUS nspi_DNToMId(struct nspi_context *nspi_ctx, TALLOC_CTX *mem_ctx, struct StringsArray_r *pNames, struct PropertyTagArray_r **ppMIds) { struct NspiDNToMId r; NTSTATUS status; enum MAPISTATUS retval; /* Sanity Checks */ OPENCHANGE_RETVAL_IF(!nspi_ctx, MAPI_E_NOT_INITIALIZED, NULL); OPENCHANGE_RETVAL_IF(!mem_ctx, MAPI_E_INVALID_PARAMETER, NULL); OPENCHANGE_RETVAL_IF(!pNames, MAPI_E_INVALID_PARAMETER, NULL); OPENCHANGE_RETVAL_IF(!pNames->Count, MAPI_E_INVALID_PARAMETER, NULL); OPENCHANGE_RETVAL_IF(!ppMIds, MAPI_E_INVALID_PARAMETER, NULL); r.in.handle = &nspi_ctx->handle; r.in.Reserved = 0; r.in.pNames = pNames; r.out.ppMIds = ppMIds; status = dcerpc_NspiDNToMId_r(nspi_ctx->rpc_connection->binding_handle, mem_ctx, &r); retval = r.out.result; OPENCHANGE_RETVAL_IF(!NT_STATUS_IS_OK(status), retval, NULL); OPENCHANGE_RETVAL_IF(retval, retval, NULL) return MAPI_E_SUCCESS; } /** \details Returns a list of all the properties that have values on the specified object \param nspi_ctx pointer to the NSPI connection context \param mem_ctx pointer to the memory context \param WantObject boolean value defining whether we want the server to include properties with the type set to PT_OBJECT \param dwMId the MId of the specified object \param ppPropTags pointer on pointer to the list of property tags associated to the object. \return MAPI_E_SUCCESS on success, otherwise MAPI error. */ _PUBLIC_ enum MAPISTATUS nspi_GetPropList(struct nspi_context *nspi_ctx, TALLOC_CTX *mem_ctx, bool WantObject, uint32_t dwMId, struct SPropTagArray **ppPropTags) { struct NspiGetPropList r; NTSTATUS status; enum MAPISTATUS retval; /* Sanity checks */ OPENCHANGE_RETVAL_IF(!nspi_ctx, MAPI_E_NOT_INITIALIZED, NULL); OPENCHANGE_RETVAL_IF(!mem_ctx, MAPI_E_INVALID_PARAMETER, NULL); OPENCHANGE_RETVAL_IF(!ppPropTags, MAPI_E_INVALID_PARAMETER, NULL); r.in.handle = &nspi_ctx->handle; r.in.dwFlags = (WantObject == true) ? 0x0 : fSkipObjects; r.in.dwMId = dwMId; r.in.CodePage = nspi_ctx->pStat->CodePage; r.out.ppPropTags = ppPropTags; status = dcerpc_NspiGetPropList_r(nspi_ctx->rpc_connection->binding_handle, mem_ctx, &r); retval = r.out.result; OPENCHANGE_RETVAL_IF(!NT_STATUS_IS_OK(status), retval, NULL); OPENCHANGE_RETVAL_IF(retval, retval, NULL); return MAPI_E_SUCCESS; } /** \details Returns an address book row containing a set of the properties and values that exists on an object \param nspi_ctx pointer to the NSPI connection context \param mem_ctx pointer to the memory context \param pPropTags pointer to the list of property tags that the client wants to be returned \param MId pointer to the MId of the record \param SRowSet pointer on pointer to the row returned by the server \return MAPI_E_SUCCESS on success, otherwise MAPI error */ _PUBLIC_ enum MAPISTATUS nspi_GetProps(struct nspi_context *nspi_ctx, TALLOC_CTX *mem_ctx, struct SPropTagArray *pPropTags, struct PropertyTagArray_r *MId, struct PropertyRowSet_r **SRowSet) { struct NspiGetProps r; NTSTATUS status; enum MAPISTATUS retval; struct PropertyRow_r *ppRows; /* Sanity checks */ OPENCHANGE_RETVAL_IF(!nspi_ctx, MAPI_E_NOT_INITIALIZED, NULL); OPENCHANGE_RETVAL_IF(!mem_ctx, MAPI_E_INVALID_PARAMETER, NULL); OPENCHANGE_RETVAL_IF(!MId, MAPI_E_INVALID_PARAMETER, NULL); OPENCHANGE_RETVAL_IF(!MId->cValues, MAPI_E_INVALID_PARAMETER, NULL); r.in.handle = &nspi_ctx->handle; r.in.dwFlags = 0; r.in.pStat = nspi_ctx->pStat; r.in.pStat->CurrentRec = MId->aulPropTag[0]; r.in.pStat->Delta = 0x0; r.in.pStat->NumPos = 0x0; r.in.pStat->TotalRecs = 0x0; r.in.pPropTags = pPropTags; ppRows = talloc(mem_ctx, struct PropertyRow_r); r.out.ppRows = &ppRows; status = dcerpc_NspiGetProps_r(nspi_ctx->rpc_connection->binding_handle, mem_ctx, &r); retval = r.out.result; OPENCHANGE_RETVAL_IF(!NT_STATUS_IS_OK(status), retval, NULL); OPENCHANGE_RETVAL_IF(retval, retval, NULL) SRowSet[0]->cRows = 1; SRowSet[0]->aRow = talloc(mem_ctx, struct PropertyRow_r); SRowSet[0]->aRow->Reserved = ppRows->Reserved; SRowSet[0]->aRow->cValues = ppRows->cValues; SRowSet[0]->aRow->lpProps = ppRows->lpProps; return MAPI_E_SUCCESS; } /** \details Compares the position in an address book container of two objects identified by MId and returns the value of the comparison \param nspi_ctx pointer to the NSPI connection context \param mem_ctx pointer to the memory context \param MId1 the first MId to compare \param MId2 the second MId to compare \param plResult pointer to the value of the comparison \return MAPI_E_SUCCESS on success, otherwise MAPI error. */ _PUBLIC_ enum MAPISTATUS nspi_CompareMIds(struct nspi_context *nspi_ctx, TALLOC_CTX *mem_ctx, uint32_t MId1, uint32_t MId2, uint32_t *plResult) { struct NspiCompareMIds r; NTSTATUS status; enum MAPISTATUS retval; /* Sanity Checks */ OPENCHANGE_RETVAL_IF(!nspi_ctx, MAPI_E_NOT_INITIALIZED, NULL); OPENCHANGE_RETVAL_IF(!mem_ctx, MAPI_E_INVALID_PARAMETER, NULL); OPENCHANGE_RETVAL_IF(!plResult, MAPI_E_INVALID_PARAMETER, NULL); r.in.handle = &nspi_ctx->handle; r.in.Reserved = 0x0; r.in.pStat = nspi_ctx->pStat; r.in.MId1 = MId1; r.in.MId2 = MId2; r.out.plResult = plResult; status = dcerpc_NspiCompareMIds_r(nspi_ctx->rpc_connection->binding_handle, mem_ctx, &r); retval = r.out.result; OPENCHANGE_RETVAL_IF(!NT_STATUS_IS_OK(status), retval, NULL); OPENCHANGE_RETVAL_IF(retval, retval, NULL); return MAPI_E_SUCCESS; } /** \details Modify the properties of an object in the address book \param nspi_ctx pointer to the NSPI connection context \param mem_ctx pointer to the memory context \param MId the MId of the address book object \param pPropTags pointer to the list of properties to be modified on the object \param pRow Contains an address book row \return MAPI_E_SUCCESS on success, otherwise MAPI error */ _PUBLIC_ enum MAPISTATUS nspi_ModProps(struct nspi_context *nspi_ctx, TALLOC_CTX *mem_ctx, uint32_t MId, struct SPropTagArray *pPropTags, struct PropertyRow_r *pRow) { struct NspiModProps r; NTSTATUS status; enum MAPISTATUS retval; /* Sanity Checks */ OPENCHANGE_RETVAL_IF(!nspi_ctx, MAPI_E_NOT_INITIALIZED, NULL); OPENCHANGE_RETVAL_IF(!mem_ctx, MAPI_E_INVALID_PARAMETER, NULL); OPENCHANGE_RETVAL_IF(!pPropTags, MAPI_E_INVALID_PARAMETER, NULL); OPENCHANGE_RETVAL_IF(!pRow, MAPI_E_INVALID_PARAMETER, NULL); r.in.handle = &nspi_ctx->handle; r.in.Reserved = 0x0; r.in.pStat = nspi_ctx->pStat; if (MId) { r.in.pStat->CurrentRec = MId; } r.in.pPropTags = pPropTags; r.in.pRow = pRow; status = dcerpc_NspiModProps_r(nspi_ctx->rpc_connection->binding_handle, mem_ctx, &r); retval = r.out.result; OPENCHANGE_RETVAL_IF(!NT_STATUS_IS_OK(status), retval, NULL); OPENCHANGE_RETVAL_IF(retval, retval, NULL); return MAPI_E_SUCCESS; } /** \details Returns the rows of a special table to the client. The special table can be a Hierarchy Table or an Address Creation Table \param nspi_ctx pointer to the NSPI connection context \param mem_ctx pointer to the memory context \param Type bitmap of flags defining the type of the special table \param ppRows pointer on pointer to the rows returned by the server Possible values for Type: -# NspiAddressCreationTemplates to access an Address Creation Table -# NspiUnicodeStrings for strings to be returned in Unicode If NspiAddressCreationTemplates is not set, then NspiGetSpecialTable will automatically fetch the Hierarchy Table. If NspiAddressCreationTemplates is set, then NspiUnicodeStrings is ignored. \return MAPI_E_SUCCESS on success, otherwise MAPI error. */ _PUBLIC_ enum MAPISTATUS nspi_GetSpecialTable(struct nspi_context *nspi_ctx, TALLOC_CTX *mem_ctx, uint32_t Type, struct PropertyRowSet_r **ppRows) { struct NspiGetSpecialTable r; NTSTATUS status; enum MAPISTATUS retval; /* Sanity Checks */ OPENCHANGE_RETVAL_IF(!nspi_ctx, MAPI_E_NOT_INITIALIZED, NULL); OPENCHANGE_RETVAL_IF(!mem_ctx, MAPI_E_INVALID_PARAMETER, NULL); OPENCHANGE_RETVAL_IF(((Type != 0x0) && (Type != 0x2) && (Type != 0x4)), MAPI_E_INVALID_PARAMETER, NULL); OPENCHANGE_RETVAL_IF(!ppRows, MAPI_E_INVALID_PARAMETER, NULL); r.in.handle = &nspi_ctx->handle; r.in.dwFlags = Type; r.in.pStat = nspi_ctx->pStat; r.in.lpVersion = &nspi_ctx->version; r.out.lpVersion = &nspi_ctx->version; r.out.ppRows = ppRows; status = dcerpc_NspiGetSpecialTable_r(nspi_ctx->rpc_connection->binding_handle, mem_ctx, &r); retval = r.out.result; OPENCHANGE_RETVAL_IF(!NT_STATUS_IS_OK(status), retval, NULL); OPENCHANGE_RETVAL_IF(retval, retval, NULL); return MAPI_E_SUCCESS; } /** \details Returns information about template objects in the address book. \param nspi_ctx pointer to the NSPI memory context \param mem_ctx pointer to the memory context \param dwFlags set of bit flags \param ulType specifies the display type of the template \param pDN the DN of the template requested \param ppData pointer on pointer to the data requested Possible values for dwFlags: -# TI_TEMPLATE to return the template -# TI_SCRIPT to return the script associated to the template -# TI_EMT to return the e-mail type associated to the template -# TI_HELPFILE_NAME to return the help file associated to the template -# TI_HELPFILE_CONTENTS to return the contents of the help file associated to the template \return MAPI_E_SUCCESS on success, otherwise MAPI error. */ _PUBLIC_ enum MAPISTATUS nspi_GetTemplateInfo(struct nspi_context *nspi_ctx, TALLOC_CTX *mem_ctx, uint32_t dwFlags, uint32_t ulType, char *pDN, struct PropertyRow_r **ppData) { struct NspiGetTemplateInfo r; NTSTATUS status; enum MAPISTATUS retval; /* Sanity checks */ OPENCHANGE_RETVAL_IF(!nspi_ctx, MAPI_E_NOT_INITIALIZED, NULL); OPENCHANGE_RETVAL_IF(!mem_ctx, MAPI_E_INVALID_PARAMETER, NULL); OPENCHANGE_RETVAL_IF(!ppData, MAPI_E_INVALID_PARAMETER, NULL); r.in.handle = &nspi_ctx->handle; r.in.dwFlags = dwFlags; r.in.ulType = ulType; r.in.pDN = pDN; r.in.dwCodePage = nspi_ctx->pStat->CodePage; r.in.dwLocaleID = nspi_ctx->pStat->TemplateLocale; r.out.ppData = ppData; status = dcerpc_NspiGetTemplateInfo_r(nspi_ctx->rpc_connection->binding_handle, mem_ctx, &r); retval = r.out.result; OPENCHANGE_RETVAL_IF(!NT_STATUS_IS_OK(status), retval, NULL); OPENCHANGE_RETVAL_IF(retval, retval, NULL); return MAPI_E_SUCCESS; } /** \details Modifies the values of a specific property of a specific row in the address book. This function only applies only to rows that support the PT_OBJECT Property Type. \param nspi_ctx pointer to the NSPI connection context \param Delete boolean value defining whether the server must remove all values specified by the input parameter lpEntryIDs from the property specified by ulPropTag \param ulPropTag property tag of the property the client wishes to modify \param MId the MId of the address book object \param lpEntryIds array of BinaryArray_r structures intended to be modified or deleted \return MAPI_E_SUCCESS on success, otherwise MAPI error */ _PUBLIC_ enum MAPISTATUS nspi_ModLinkAtt(struct nspi_context *nspi_ctx, bool Delete, uint32_t ulPropTag, uint32_t MId, struct BinaryArray_r *lpEntryIds) { struct NspiModLinkAtt r; NTSTATUS status; enum MAPISTATUS retval; /* Sanity Checks */ OPENCHANGE_RETVAL_IF(!nspi_ctx, MAPI_E_NOT_INITIALIZED, NULL); OPENCHANGE_RETVAL_IF(((ulPropTag & 0xFFFF) != PT_OBJECT), MAPI_E_INVALID_PARAMETER, NULL); OPENCHANGE_RETVAL_IF(!lpEntryIds, MAPI_E_INVALID_PARAMETER, NULL); OPENCHANGE_RETVAL_IF(!lpEntryIds->cValues, MAPI_E_INVALID_PARAMETER, NULL) r.in.handle = &nspi_ctx->handle; /* FIXME: need to find fDelete value first */ r.in.dwFlags = (Delete == true) ? 0x1 : 0x0; r.in.ulPropTag = ulPropTag; r.in.MId = MId; r.in.lpEntryIds = lpEntryIds; status = dcerpc_NspiModLinkAtt_r(nspi_ctx->rpc_connection->binding_handle, nspi_ctx->mem_ctx, &r); retval = r.out.result; OPENCHANGE_RETVAL_IF(!NT_STATUS_IS_OK(status), retval, NULL); OPENCHANGE_RETVAL_IF(retval, retval, NULL); return MAPI_E_SUCCESS; } /** \details Returns a list of all the properties the NSPI server is aware off. \param nspi_ctx pointer to the NSPI connection context \param mem_ctx pointer to the memory context \param WantUnicode whether we want UNICODE properties or not \param ppColumns pointer on pointer to a property tag array \return MAPI_E_SUCCESS on success, otherwise MAPI error. */ _PUBLIC_ enum MAPISTATUS nspi_QueryColumns(struct nspi_context *nspi_ctx, TALLOC_CTX *mem_ctx, bool WantUnicode, struct SPropTagArray **ppColumns) { struct NspiQueryColumns r; NTSTATUS status; enum MAPISTATUS retval; /* Sanity checks */ OPENCHANGE_RETVAL_IF(!nspi_ctx, MAPI_E_NOT_INITIALIZED, NULL); OPENCHANGE_RETVAL_IF(!mem_ctx, MAPI_E_INVALID_PARAMETER, NULL); OPENCHANGE_RETVAL_IF(!ppColumns, MAPI_E_INVALID_PARAMETER, NULL); r.in.handle = &nspi_ctx->handle; r.in.Reserved = 0x0; r.in.dwFlags = (WantUnicode != false) ? NspiUnicodeProptypes : 0x0; r.out.ppColumns = ppColumns; status = dcerpc_NspiQueryColumns_r(nspi_ctx->rpc_connection->binding_handle, mem_ctx, &r); retval = r.out.result; OPENCHANGE_RETVAL_IF(!NT_STATUS_IS_OK(status), MAPI_E_CALL_FAILED, NULL); OPENCHANGE_RETVAL_IF(retval, retval, NULL); return MAPI_E_SUCCESS; } /** \details Returns a list of property names for a set of proptags \param nspi_ctx pointer on the NSPI connection text \param mem_ctx pointer to the memory context \param lpGuid the property set about which the client is requesting information \param pPropTags pointer to the proptags list \param ppReturnedPropTags pointer on pointer to the list of all the proptags in the property set specified in lpGuid \param ppNames pointer on pointer to the list of property names returned by the server \return MAPI_E_SUCCESS on success, otherwise MAPI error */ _PUBLIC_ enum MAPISTATUS nspi_GetNamesFromIDs(struct nspi_context *nspi_ctx, TALLOC_CTX *mem_ctx, struct FlatUID_r *lpGuid, struct SPropTagArray *pPropTags, struct SPropTagArray **ppReturnedPropTags, struct PropertyNameSet_r **ppNames) { struct NspiGetNamesFromIDs r; NTSTATUS status; enum MAPISTATUS retval; /* Sanity Checks */ OPENCHANGE_RETVAL_IF(!nspi_ctx, MAPI_E_NOT_INITIALIZED, NULL); OPENCHANGE_RETVAL_IF(!mem_ctx, MAPI_E_INVALID_PARAMETER, NULL); OPENCHANGE_RETVAL_IF(!ppReturnedPropTags, MAPI_E_INVALID_PARAMETER, NULL); OPENCHANGE_RETVAL_IF(!ppNames, MAPI_E_INVALID_PARAMETER, NULL); r.in.handle = &nspi_ctx->handle; r.in.Reserved = 0x0; r.in.lpGuid = lpGuid; r.in.pPropTags = pPropTags; r.out.ppReturnedPropTags = ppReturnedPropTags; r.out.ppNames = ppNames; status = dcerpc_NspiGetNamesFromIDs_r(nspi_ctx->rpc_connection->binding_handle, mem_ctx, &r); retval = r.out.result; OPENCHANGE_RETVAL_IF(!NT_STATUS_IS_OK(status), retval, NULL); OPENCHANGE_RETVAL_IF(retval, retval, NULL); return MAPI_E_SUCCESS; } /** \details Retrieve the Property IDs associated with property names from the NSPI server. \param nspi_ctx pointer on the NSPI connection context \param mem_ctx pointer to the memoty context \param VerifyNames boolean value defining whether the NSPI server must verify that all client specified names are recognized by the server \param cNames count of PropertyName_r entries \param ppNames pointer to a PropertyName_r structure with the list of property tags supplied by the client \param ppPropTags pointer on pointer to the list of proptags returned by the server \return MAPI_E_SUCCESS on success, otherwise MAPI error */ _PUBLIC_ enum MAPISTATUS nspi_GetIDsFromNames(struct nspi_context *nspi_ctx, TALLOC_CTX *mem_ctx, bool VerifyNames, uint32_t cNames, struct PropertyName_r *ppNames, struct SPropTagArray **ppPropTags) { struct NspiGetIDsFromNames r; NTSTATUS status; enum MAPISTATUS retval; uint32_t i; /* Sanity Checks */ OPENCHANGE_RETVAL_IF(!nspi_ctx, MAPI_E_NOT_INITIALIZED, NULL); OPENCHANGE_RETVAL_IF(!mem_ctx, MAPI_E_INVALID_PARAMETER, NULL); OPENCHANGE_RETVAL_IF(!ppNames, MAPI_E_INVALID_PARAMETER, NULL); OPENCHANGE_RETVAL_IF(!ppPropTags, MAPI_E_INVALID_PARAMETER, NULL); r.in.handle = &nspi_ctx->handle; r.in.Reserved = 0; r.in.dwFlags = (VerifyNames == true) ? 0x2 : 0x0; r.in.cPropNames = cNames; r.in.ppNames = talloc_array(mem_ctx, struct PropertyName_r *, cNames); for (i = 0; i < cNames; i++) { r.in.ppNames[i] = &ppNames[i]; } r.out.ppPropTags = ppPropTags; status = dcerpc_NspiGetIDsFromNames_r(nspi_ctx->rpc_connection->binding_handle, mem_ctx, &r); retval = r.out.result; OPENCHANGE_RETVAL_IF(!NT_STATUS_IS_OK(status), retval, NULL); OPENCHANGE_RETVAL_IF(retval, retval, NULL); errno = retval; return MAPI_E_SUCCESS; } /** \details Takes a set of string values in an 8-bit character set and performs ANR on those strings \param nspi_ctx pointer on the NSPI connection context \param mem_ctx pointer to the memory context \param usernames pointer on pointer to the list of values we want to perform ANR on \param pPropTags pointer on the property tags list we want for each row returned \param pppRows pointer on pointer on pointer to the rows returned by the server \param pppMIds pointer on pointer on pointer to the MIds matching the array of strings \return MAPI_E_SUCCESS on success, otherwise MAPI error */ _PUBLIC_ enum MAPISTATUS nspi_ResolveNames(struct nspi_context *nspi_ctx, TALLOC_CTX *mem_ctx, const char **usernames, struct SPropTagArray *pPropTags, struct PropertyRowSet_r ***pppRows, struct PropertyTagArray_r ***pppMIds) { struct NspiResolveNames r; struct StringsArray_r *paStr; NTSTATUS status; enum MAPISTATUS retval; uint32_t count; /* Sanity checks */ OPENCHANGE_RETVAL_IF(!nspi_ctx, MAPI_E_NOT_INITIALIZED, NULL); OPENCHANGE_RETVAL_IF(!mem_ctx, MAPI_E_INVALID_PARAMETER, NULL); OPENCHANGE_RETVAL_IF(!usernames, MAPI_E_INVALID_PARAMETER, NULL); OPENCHANGE_RETVAL_IF(!pppRows, MAPI_E_INVALID_PARAMETER, NULL); OPENCHANGE_RETVAL_IF(!pppMIds, MAPI_E_INVALID_PARAMETER, NULL); for (count = 0; usernames[count]; count++); OPENCHANGE_RETVAL_IF(!count, MAPI_E_INVALID_PARAMETER, NULL); r.in.handle = &nspi_ctx->handle; r.in.pStat = nspi_ctx->pStat; r.in.Reserved = 0; r.in.pPropTags = pPropTags; paStr = talloc(mem_ctx, struct StringsArray_r); paStr->Count = count; paStr->Strings = usernames; r.in.paStr = paStr; r.out.ppMIds = *pppMIds; r.out.ppRows = *pppRows; status = dcerpc_NspiResolveNames_r(nspi_ctx->rpc_connection->binding_handle, mem_ctx, &r); retval = r.out.result; OPENCHANGE_RETVAL_IF(!NT_STATUS_IS_OK(status), retval, NULL); OPENCHANGE_RETVAL_IF(retval, retval, NULL); return MAPI_E_SUCCESS; } /** \details Takes a set of string values in the Unicode character set and performs ambiguous name resolution (ANR) on those strings \param nspi_ctx pointer on the NSPI connection context \param mem_ctx pointer to the memory context \param usernames pointer on pointer to the list of values we want to perform ANR on \param pPropTags pointer on the property tags list we want for each row returned \param pppRows pointer on pointer on pointer to the rows returned by the server \param pppMIds pointer on pointer on pointer to the MIds matching the array of strings \return MAPI_E_SUCCESS on success, otherwise MAPI error */ _PUBLIC_ enum MAPISTATUS nspi_ResolveNamesW(struct nspi_context *nspi_ctx, TALLOC_CTX *mem_ctx, const char **usernames, struct SPropTagArray *pPropTags, struct PropertyRowSet_r ***pppRows, struct PropertyTagArray_r ***pppMIds) { struct NspiResolveNamesW r; struct StringsArrayW_r *paWStr; NTSTATUS status; enum MAPISTATUS retval; uint32_t count; OPENCHANGE_RETVAL_IF(!nspi_ctx, MAPI_E_NOT_INITIALIZED, NULL); OPENCHANGE_RETVAL_IF(!mem_ctx, MAPI_E_INVALID_PARAMETER, NULL); OPENCHANGE_RETVAL_IF(!usernames, MAPI_E_INVALID_PARAMETER, NULL); OPENCHANGE_RETVAL_IF(!pppRows, MAPI_E_INVALID_PARAMETER, NULL); OPENCHANGE_RETVAL_IF(!pppMIds, MAPI_E_INVALID_PARAMETER, NULL); for (count = 0; usernames[count]; count++); OPENCHANGE_RETVAL_IF(!count, MAPI_E_INVALID_PARAMETER, NULL); r.in.handle = &nspi_ctx->handle; r.in.pStat = nspi_ctx->pStat; r.in.Reserved = 0; r.in.pPropTags = pPropTags; paWStr = talloc(mem_ctx, struct StringsArrayW_r); paWStr->Count = count; paWStr->Strings = usernames; r.in.paWStr = paWStr; r.out.ppMIds = *pppMIds; r.out.ppRows = *pppRows; status = dcerpc_NspiResolveNamesW_r(nspi_ctx->rpc_connection->binding_handle, mem_ctx, &r); retval = r.out.result; OPENCHANGE_RETVAL_IF(!NT_STATUS_IS_OK(status), retval, NULL); OPENCHANGE_RETVAL_IF(retval, retval, NULL); return MAPI_E_SUCCESS; } openchange-2.0/libmapi/nspi.h000066400000000000000000000024211223057412600162220ustar00rootroot00000000000000/* OpenChange NSPI implementation. Copyright (C) Julien Kerihuel 2005. This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see . */ #ifndef __NSPI_H__ #define __NSPI_H__ struct nspi_context { struct dcerpc_pipe *rpc_connection; struct policy_handle handle; TALLOC_CTX *mem_ctx; struct cli_credentials *cred; struct STAT *pStat; struct mapi_profile *profile; struct SRowSet *rowSet; char *org; char *org_unit; char *servername; uint32_t version; }; #define ORG "/o=" #define ORG_UNIT "/ou=" #define SERVER_DN "/o=%s/ou=%s/cn=Configuration/cn=Servers/cn=%s" #define SERVERNAME "/cn=Servers/cn=" #define RECIPIENT_DN "/o=%s/ou=%s/cn=Recipients/cn=%s" #endif /* __NSPI_H__ */ openchange-2.0/libmapi/property.c000066400000000000000000001766211223057412600171460ustar00rootroot00000000000000/* OpenChange MAPI implementation. Copyright (C) Julien Kerihuel 2005 - 2011. Copyright (C) Gregory Schiro 2006 This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see . */ #include "libmapi/libmapi.h" #include "libmapi/libmapi_private.h" #include #include /** \file property.c \brief Functions for manipulating MAPI properties */ /** \details Create a property tag array \param mem_ctx talloc memory context to use for allocation \param PropCount the number of properties in the array The varargs (the third and subsequent arguments) are the property tags to make up the array. So the normal way to use this to create an array of two tags is like: \code struct SPropTagArray *array array = set_SPropTagArray(mem_ctx, 2, PR_ENTRYID, PR_DISPLAY_NAME); \endcode */ _PUBLIC_ struct SPropTagArray *set_SPropTagArray(TALLOC_CTX *mem_ctx, uint32_t PropCount, ...) { struct SPropTagArray *SPropTagArray; va_list ap; uint32_t i; uint32_t *aulPropTag; aulPropTag = talloc_array(mem_ctx, uint32_t, PropCount); va_start(ap, PropCount); for (i = 0; i < PropCount; i++) { aulPropTag[i] = va_arg(ap, int); } va_end(ap); SPropTagArray = talloc(mem_ctx, struct SPropTagArray); SPropTagArray->aulPropTag = (enum MAPITAGS *) aulPropTag; SPropTagArray->cValues = PropCount; return SPropTagArray; } /** \details Add a property tag to an existing properties array \param mem_ctx talloc memory context to use for allocation \param SPropTagArray existing properties array to add to \param aulPropTag the property tag to add \return MAPI_E_SUCCESS on success, otherwise MAPI error. \note Possible MAPI error codes are: - MAPI_E_NOT_INITIALIZED: MAPI subsystem has not been initialized - MAPI_E_INVALID_PARAMETER: SPropTagArray parameter is not correctly set */ _PUBLIC_ enum MAPISTATUS SPropTagArray_add(TALLOC_CTX *mem_ctx, struct SPropTagArray *SPropTagArray, enum MAPITAGS aulPropTag) { /* Sanity checks */ OPENCHANGE_RETVAL_IF(!mem_ctx, MAPI_E_NOT_INITIALIZED, NULL); OPENCHANGE_RETVAL_IF(!SPropTagArray, MAPI_E_INVALID_PARAMETER, NULL); OPENCHANGE_RETVAL_IF(!SPropTagArray->aulPropTag, MAPI_E_INVALID_PARAMETER, NULL); SPropTagArray->cValues += 1; SPropTagArray->aulPropTag = (enum MAPITAGS *) talloc_realloc(mem_ctx, SPropTagArray->aulPropTag, uint32_t, SPropTagArray->cValues + 1); SPropTagArray->aulPropTag[SPropTagArray->cValues - 1] = aulPropTag; SPropTagArray->aulPropTag[SPropTagArray->cValues] = (enum MAPITAGS) 0; return MAPI_E_SUCCESS; } /** \details Delete a property tag from an existing properties array \param mem_ctx talloc memory context to use for allocation \param SPropTagArray existing properties array to remove from \param aulPropTag the property tag to remove \return MAPI_E_SUCCESS on success, otherwise MAPI error. \note Possible MAPI error codes are: - MAPI_E_NOT_INITIALIZED: MAPI subsystem has not been initialized - MAPI_E_INVALID_PARAMETER: SPropTagArray parameter is not correctly set */ _PUBLIC_ enum MAPISTATUS SPropTagArray_delete(TALLOC_CTX *mem_ctx, struct SPropTagArray *SPropTagArray, uint32_t aulPropTag) { uint32_t i, removed = 0; /* Sanity checks */ OPENCHANGE_RETVAL_IF(!mem_ctx, MAPI_E_NOT_INITIALIZED, NULL); OPENCHANGE_RETVAL_IF(!SPropTagArray, MAPI_E_INVALID_PARAMETER, NULL); OPENCHANGE_RETVAL_IF(!SPropTagArray->cValues, MAPI_E_INVALID_PARAMETER, NULL); for (i = 0; i < SPropTagArray->cValues; i++) { if (SPropTagArray->aulPropTag[i] == aulPropTag) { removed++; } else if (removed > 0) { SPropTagArray->aulPropTag[i-removed] = SPropTagArray->aulPropTag[i]; } } SPropTagArray->cValues -= removed; SPropTagArray->aulPropTag = (enum MAPITAGS *) talloc_realloc(mem_ctx, SPropTagArray->aulPropTag, uint32_t, SPropTagArray->cValues + 1); SPropTagArray->aulPropTag[SPropTagArray->cValues] = (enum MAPITAGS) 0; return MAPI_E_SUCCESS; } /** \details Return the index of a property tag in an existing properties array \param SPropTagArray existing properties array to remove from \param aulPropTag the property tag to find \param propIdx the index of the found property (undefined when MAPI_E_NOT_FOUND is returned) \return MAPI_E_SUCCESS on success, otherwise MAPI error. \note Possible MAPI error codes are: - MAPI_E_NOT_INITIALIZED: MAPI subsystem has not been initialized - MAPI_E_INVALID_PARAMETER: SPropTagArray parameter is not correctly set */ _PUBLIC_ enum MAPISTATUS SPropTagArray_find(struct SPropTagArray SPropTagArray, enum MAPITAGS aulPropTag, uint32_t *propIdx) { uint32_t i; /* Sanity checks */ OPENCHANGE_RETVAL_IF(!propIdx, MAPI_E_INVALID_PARAMETER, NULL); for (i = 0; i < SPropTagArray.cValues; i++) { if (SPropTagArray.aulPropTag[i] == aulPropTag) { *propIdx = i; return MAPI_E_SUCCESS; } } return MAPI_E_NOT_FOUND; } _PUBLIC_ const void *get_SPropValue(struct SPropValue *lpProps, enum MAPITAGS ulPropTag) { uint32_t i; /* Sanity checks */ if (!lpProps) return NULL; for (i = 0; lpProps[i].ulPropTag; i++) { if (ulPropTag == lpProps[i].ulPropTag) { return get_SPropValue_data(&lpProps[i]); } } return NULL; } _PUBLIC_ struct SPropValue *get_SPropValue_SRowSet(struct SRowSet *RowSet, uint32_t ulPropTag) { uint32_t i; uint32_t j; /* Sanity Checks */ if (!RowSet) return NULL; for (i = 0; i != RowSet->cRows; i++) { for (j = 0; j < RowSet->aRow[i].cValues; j++) { if (ulPropTag == RowSet->aRow[i].lpProps[j].ulPropTag) { return (&RowSet->aRow[i].lpProps[j]); } } } return NULL; } _PUBLIC_ const void *get_SPropValue_SRowSet_data(struct SRowSet *RowSet, uint32_t ulPropTag) { struct SPropValue *lpProp; lpProp = get_SPropValue_SRowSet(RowSet, ulPropTag); return get_SPropValue(lpProp, ulPropTag); } _PUBLIC_ enum MAPISTATUS set_default_error_SPropValue_SRow(struct SRow *aRow, enum MAPITAGS ulPropTag, void *data) { uint32_t i; for (i = 0; i < aRow->cValues; i++) { if ((ulPropTag & 0xFFFF0000) == (aRow->lpProps[i].ulPropTag & 0xFFFF0000) && (aRow->lpProps[i].ulPropTag & 0xFFFF) == 0xA) { set_SPropValue_proptag(&(aRow->lpProps[i]), ulPropTag, data); return MAPI_E_SUCCESS; } } return MAPI_E_NOT_FOUND; } _PUBLIC_ struct SPropValue *get_SPropValue_SRow(struct SRow *aRow, uint32_t ulPropTag) { uint32_t i; if ( ! aRow) { return NULL; } for (i = 0; i < aRow->cValues; i++) { if (ulPropTag == aRow->lpProps[i].ulPropTag) { return (&aRow->lpProps[i]); } } return NULL; } _PUBLIC_ const void *get_SPropValue_SRow_data(struct SRow *aRow, uint32_t ulPropTag) { struct SPropValue *lpProp; lpProp = get_SPropValue_SRow(aRow, ulPropTag); return get_SPropValue(lpProp, ulPropTag); } /* Create a MAPITAGS array from a SRow entry */ enum MAPITAGS *get_MAPITAGS_SRow(TALLOC_CTX *mem_ctx, struct SRow *aRow, uint32_t *actual_count) { enum MAPITAGS *mapitags; uint32_t count, idx; mapitags = talloc_array(mem_ctx, enum MAPITAGS, aRow->cValues + 1); for (count = 0, idx=0; count < aRow->cValues; count++) { if ((aRow->lpProps[count].ulPropTag & 0xFFFF) != PT_ERROR) { mapitags[idx] = aRow->lpProps[count].ulPropTag; idx++; } } mapitags[idx] = (enum MAPITAGS) 0; *actual_count = idx; return mapitags; } /* Remove MAPITAGS entries from a MAPITAGS array */ uint32_t MAPITAGS_delete_entries(enum MAPITAGS *mapitags, uint32_t final_count, uint32_t PropCount, ...) { va_list ap; uint32_t i,j; uint32_t aulPropTag; uint32_t count = 0; va_start(ap, PropCount); for (i = 0; i != PropCount; i++) { aulPropTag = va_arg(ap, uint32_t); for (count = 0; mapitags[count]; count++) { if (aulPropTag == (uint32_t)mapitags[count]) { final_count -= 1; for (j = count; mapitags[j]; j++) { mapitags[j] = (mapitags[j+1]) ? mapitags[j+1] : (enum MAPITAGS) 0; } } } } va_end(ap); return final_count; } _PUBLIC_ const void *find_SPropValue_data(struct SRow *aRow, uint32_t mapitag) { uint32_t i; if (!aRow) { return NULL; } for (i = 0; i < aRow->cValues; i++) { if (aRow->lpProps[i].ulPropTag == mapitag) { return get_SPropValue_data(&(aRow->lpProps[i])); } } return NULL; } _PUBLIC_ const void *find_mapi_SPropValue_data( struct mapi_SPropValue_array *properties, uint32_t mapitag) { uint32_t i; if ( ! properties) { return NULL; } for (i = 0; i < properties->cValues; i++) { if (properties->lpProps[i].ulPropTag == mapitag) { return get_mapi_SPropValue_data(&properties->lpProps[i]); } } return NULL; } _PUBLIC_ const void *get_mapi_SPropValue_data(struct mapi_SPropValue *lpProp) { if ( ! lpProp) { return NULL; } if (lpProp->ulPropTag == 0) { return NULL; } switch(lpProp->ulPropTag & 0xFFFF) { case PT_BOOLEAN: return (const void *)(uint8_t *)&lpProp->value.b; case PT_I2: /* Equivalent to PT_SHORT */ return (const void *)(uint16_t *)&lpProp->value.i; case PT_LONG: /* Equivalent to PT_I4 */ return (const void *)&lpProp->value.l; case PT_DOUBLE: return (const void *)&lpProp->value.dbl; case PT_I8: return (const void *)&lpProp->value.d; case PT_SYSTIME: return (const void *)(struct FILETIME *)&lpProp->value.ft; case PT_ERROR: return (const void *)&lpProp->value.err; case PT_STRING8: return (const void *)lpProp->value.lpszA; case PT_UNICODE: return (const void *)lpProp->value.lpszW; case PT_BINARY: return (const void *)(struct SBinary_short *)&lpProp->value.bin; case PT_MV_LONG: return (const void *)(struct mapi_MV_LONG_STRUCT *)&lpProp->value.MVl; case PT_MV_STRING8: return (const void *)(struct mapi_SLPSTRArray *)&lpProp->value.MVszA; case PT_MV_UNICODE: return (const void *)(struct mapi_SLPSTRArrayW *)&lpProp->value.MVszW; case PT_MV_BINARY: return (const void *)(struct mapi_SBinaryArray *)&lpProp->value.MVbin; default: return NULL; } } _PUBLIC_ const void *get_SPropValue_data(struct SPropValue *lpProps) { if (lpProps->ulPropTag == 0) { return NULL; } switch(lpProps->ulPropTag & 0xFFFF) { case PT_SHORT: return (const void *)&lpProps->value.i; case PT_BOOLEAN: return (const void *)&lpProps->value.b; case PT_I8: return (const void *)&lpProps->value.d; case PT_STRING8: return (const void *)lpProps->value.lpszA; case PT_UNICODE: return (const void *)lpProps->value.lpszW; case PT_SYSTIME: return (const void *)(struct FILETIME *)&lpProps->value.ft; case PT_ERROR: return (const void *)&lpProps->value.err; case PT_LONG: return (const void *)&lpProps->value.l; case PT_DOUBLE: return (const void *)&lpProps->value.dbl; case PT_CLSID: return (const void *)lpProps->value.lpguid; case PT_BINARY: case PT_SVREID: return (const void *)&lpProps->value.bin; case PT_OBJECT: return (const void *)&lpProps->value.object; case PT_MV_SHORT: return (const void *)(struct ShortArray_r *)&lpProps->value.MVi; case PT_MV_LONG: return (const void *)(struct LongArray_r *)&lpProps->value.MVl; case PT_MV_STRING8: return (const void *)(struct StringArray_r *)&lpProps->value.MVszA; case PT_MV_UNICODE: return (const void *)(struct StringArrayW_r *)&lpProps->value.MVszW; case PT_MV_BINARY: return (const void *)(struct BinaryArray_r *)&lpProps->value.MVbin; case PT_MV_SYSTIME: return (const void *)(struct DateTimeArray_r *)&lpProps->value.MVft; case PT_NULL: return (const void *)&lpProps->value.null; default: return NULL; } } _PUBLIC_ bool set_SPropValue_proptag(struct SPropValue *lpProps, enum MAPITAGS aulPropTag, const void *data) { lpProps->ulPropTag = aulPropTag; lpProps->dwAlignPad = 0x0; return (set_SPropValue(lpProps, data)); } _PUBLIC_ struct SPropValue *add_SPropValue(TALLOC_CTX *mem_ctx, struct SPropValue *lpProps, uint32_t *cValues, enum MAPITAGS aulPropTag, const void * data) { lpProps = talloc_realloc(mem_ctx, lpProps, struct SPropValue, *cValues + 2); set_SPropValue_proptag(&lpProps[*cValues], aulPropTag, data); *cValues = *cValues + 1; return lpProps; } _PUBLIC_ bool set_mapi_SPropValue(TALLOC_CTX *mem_ctx, struct mapi_SPropValue *lpProps, const void *data) { if (data == NULL) { lpProps->ulPropTag = (lpProps->ulPropTag & 0xffff0000) | PT_ERROR; lpProps->value.err = MAPI_E_NOT_FOUND; return false; } switch (lpProps->ulPropTag & 0xFFFF) { case PT_SHORT: lpProps->value.i = *((const uint16_t *)data); break; case PT_LONG: lpProps->value.l = *((const uint32_t *)data); break; case PT_DOUBLE: lpProps->value.dbl = *((const double *)data); break; case PT_I8: lpProps->value.d = *((const uint64_t *)data); break; case PT_BOOLEAN: lpProps->value.b = *((const uint8_t *)data); break; case PT_STRING8: lpProps->value.lpszA = (const char *) data; break; case PT_BINARY: { struct Binary_r *bin; bin = (struct Binary_r *)data; lpProps->value.bin.cb = (uint16_t)bin->cb; lpProps->value.bin.lpb = (void *)bin->lpb; } break; case PT_UNICODE: lpProps->value.lpszW = (const char *) data; break; case PT_CLSID: lpProps->value.lpguid = *((struct GUID *) data); break; case PT_SYSTIME: lpProps->value.ft = *((const struct FILETIME *) data); break; case PT_ERROR: lpProps->value.err = *((const uint32_t *)data); break; case PT_MV_LONG: lpProps->value.MVl = *((const struct mapi_MV_LONG_STRUCT *)data); break; case PT_MV_STRING8: lpProps->value.MVszA = *((const struct mapi_SLPSTRArray *)data); break; case PT_MV_BINARY: lpProps->value.MVbin = *((const struct mapi_SBinaryArray *)data); break; case PT_MV_CLSID: lpProps->value.MVguid = *((const struct mapi_SGuidArray *)data); break; case PT_MV_UNICODE: lpProps->value.MVszW = *((const struct mapi_SLPSTRArrayW *)data); break; default: lpProps->ulPropTag = (lpProps->ulPropTag & 0xffff0000) | PT_ERROR; lpProps->value.err = MAPI_E_NOT_FOUND; return false; } return true; } _PUBLIC_ bool set_mapi_SPropValue_proptag(TALLOC_CTX *mem_ctx, struct mapi_SPropValue *lpProps, uint32_t aulPropTag, const void *data) { lpProps->ulPropTag = aulPropTag; return (set_mapi_SPropValue(mem_ctx, lpProps, data)); } _PUBLIC_ struct mapi_SPropValue *add_mapi_SPropValue(TALLOC_CTX *mem_ctx, struct mapi_SPropValue *lpProps, uint16_t *cValues, uint32_t aulPropTag, const void *data) { lpProps = talloc_realloc(mem_ctx, lpProps, struct mapi_SPropValue, *cValues + 2); DEBUG(0, ("%d: setting value for 0x%.8x\n", *cValues, aulPropTag)); set_mapi_SPropValue_proptag(mem_ctx, &lpProps[*cValues], aulPropTag, data); *cValues = *cValues + 1; return lpProps; } _PUBLIC_ bool set_SPropValue(struct SPropValue *lpProps, const void *data) { if (data == NULL) { lpProps->ulPropTag = (lpProps->ulPropTag & 0xffff0000) | PT_ERROR; lpProps->value.err = MAPI_E_NOT_FOUND; return false; } switch (lpProps->ulPropTag & 0xFFFF) { case PT_SHORT: lpProps->value.i = *((const uint16_t *)data); break; case PT_LONG: lpProps->value.l = *((const uint32_t *)data); break; case PT_DOUBLE: lpProps->value.dbl = *((const double *)data); break; case PT_I8: lpProps->value.d = *((const uint64_t *)data); break; case PT_BOOLEAN: lpProps->value.b = *((const uint8_t *)data); break; case PT_STRING8: lpProps->value.lpszA = (const char *) data; break; case PT_BINARY: case PT_SVREID: lpProps->value.bin = *((const struct Binary_r *)data); break; case PT_UNICODE: lpProps->value.lpszW = (const char *) data; break; case PT_CLSID: lpProps->value.lpguid = (struct FlatUID_r *) data; break; case PT_SYSTIME: lpProps->value.ft = *((const struct FILETIME *) data); break; case PT_ERROR: lpProps->value.err = *((enum MAPISTATUS *)data); break; case PT_MV_SHORT: lpProps->value.MVi = *((const struct ShortArray_r *)data); break; case PT_MV_LONG: lpProps->value.MVl = *((const struct LongArray_r *)data); break; case PT_MV_STRING8: lpProps->value.MVszA = *((const struct StringArray_r *)data); break; case PT_MV_BINARY: lpProps->value.MVbin = *((const struct BinaryArray_r *)data); break; case PT_MV_CLSID: lpProps->value.MVguid = *((const struct FlatUIDArray_r *)data); break; case PT_MV_UNICODE: lpProps->value.MVszW = *((const struct StringArrayW_r *)data); break; case PT_MV_SYSTIME: lpProps->value.MVft = *((const struct DateTimeArray_r *)data); break; case PT_NULL: lpProps->value.null = *((const uint32_t *)data); break; case PT_OBJECT: lpProps->value.object = *((const uint32_t *)data); break; default: lpProps->ulPropTag = (lpProps->ulPropTag & 0xffff0000) | PT_ERROR; lpProps->value.err = MAPI_E_NOT_FOUND; return false; } return true; } _PUBLIC_ uint32_t get_mapi_property_size(struct mapi_SPropValue *lpProp) { switch(lpProp->ulPropTag & 0xFFFF) { case PT_BOOLEAN: return sizeof (uint8_t); case PT_I2: return sizeof (uint16_t); case PT_LONG: case PT_ERROR: return sizeof (uint32_t); case PT_DOUBLE: return sizeof (double); case PT_I8: return sizeof (uint64_t); case PT_STRING8: return strlen(lpProp->value.lpszA) + 1; case PT_UNICODE: return get_utf8_utf16_conv_length(lpProp->value.lpszW); case PT_SYSTIME: return sizeof (struct FILETIME); case PT_BINARY: return (lpProp->value.bin.cb + sizeof(uint16_t)); } return 0; } /** \details Convenience function to copy an array of struct SPropValue or a part thereof into another array, by duplicating and properly parenting pointer data. The destination array is considered to be preallocated. */ _PUBLIC_ void mapi_copy_spropvalues(TALLOC_CTX *mem_ctx, struct SPropValue *source_values, struct SPropValue *dest_values, uint32_t count) { uint32_t i; struct SPropValue *source_value, *dest_value; uint16_t prop_type; for (i = 0; i < count; i++) { source_value = source_values + i; dest_value = dest_values + i; *dest_value = *source_value; prop_type = (source_value->ulPropTag & 0xFFFF); if ((prop_type & MV_FLAG)) { DEBUG(5, ("multivalues not handled\n")); abort(); } else { switch(prop_type) { case PT_STRING8: dest_value->value.lpszA = talloc_strdup(mem_ctx, source_value->value.lpszA); break; case PT_UNICODE: dest_value->value.lpszW = talloc_strdup(mem_ctx, source_value->value.lpszW); break; case PT_BINARY: dest_value->value.bin.cb = source_value->value.bin.cb; dest_value->value.bin.lpb = talloc_memdup(mem_ctx, source_value->value.bin.lpb, sizeof(uint8_t) * source_value->value.bin.cb); break; default: *dest_value = *source_value; } } } } /** \details Convenience function to convert a SPropValue structure into a mapi_SPropValue structure and return the associated size. \param mem_ctx pointer to the memory context to use for allocation \param mapi_sprop pointer to the MAPI SPropValue structure to copy data to \param sprop pointer to the SPropValue structure to copy data from \return size of the converted data on success, otherwise 0 */ _PUBLIC_ uint32_t cast_mapi_SPropValue(TALLOC_CTX *mem_ctx, struct mapi_SPropValue *mapi_sprop, struct SPropValue *sprop) { mapi_sprop->ulPropTag = sprop->ulPropTag; switch(sprop->ulPropTag & 0xFFFF) { case PT_BOOLEAN: mapi_sprop->value.b = sprop->value.b; return sizeof(uint8_t); case PT_I2: mapi_sprop->value.i = sprop->value.i; return sizeof(uint16_t); case PT_LONG: mapi_sprop->value.l = sprop->value.l; return sizeof(uint32_t); case PT_DOUBLE: mapi_sprop->value.dbl = sprop->value.dbl; return sizeof(double); case PT_I8: mapi_sprop->value.d = sprop->value.d; return sizeof(uint64_t); case PT_STRING8: mapi_sprop->value.lpszA = sprop->value.lpszA; if (!mapi_sprop->value.lpszA) return 0; return (strlen(sprop->value.lpszA) + 1); case PT_UNICODE: mapi_sprop->value.lpszW = sprop->value.lpszW; if (!mapi_sprop->value.lpszW) return 0; return (get_utf8_utf16_conv_length(mapi_sprop->value.lpszW)); case PT_SYSTIME: mapi_sprop->value.ft.dwLowDateTime = sprop->value.ft.dwLowDateTime; mapi_sprop->value.ft.dwHighDateTime = sprop->value.ft.dwHighDateTime; return (sizeof (struct FILETIME)); case PT_BINARY: mapi_sprop->value.bin.cb = sprop->value.bin.cb; mapi_sprop->value.bin.lpb = sprop->value.bin.lpb; return (mapi_sprop->value.bin.cb + sizeof(uint16_t)); case PT_ERROR: mapi_sprop->value.err = sprop->value.err; return sizeof(uint32_t); case PT_CLSID: { DATA_BLOB b; b.data = sprop->value.lpguid->ab; b.length = 16; GUID_from_ndr_blob(&b, &mapi_sprop->value.lpguid); return sizeof(struct GUID); } case PT_SVREID: mapi_sprop->value.bin.cb = sprop->value.bin.cb; mapi_sprop->value.bin.lpb = sprop->value.bin.lpb; return (mapi_sprop->value.bin.cb + sizeof(uint16_t)); case PT_MV_STRING8: { uint32_t i; uint32_t size = 0; mapi_sprop->value.MVszA.cValues = sprop->value.MVszA.cValues; size += 4; mapi_sprop->value.MVszA.strings = talloc_array(mem_ctx, struct mapi_LPSTR, mapi_sprop->value.MVszA.cValues); for (i = 0; i < mapi_sprop->value.MVszA.cValues; i++) { mapi_sprop->value.MVszA.strings[i].lppszA = sprop->value.MVszA.lppszA[i]; size += strlen(mapi_sprop->value.MVszA.strings[i].lppszA) + 1; } return size; } case PT_MV_UNICODE: { uint32_t i; uint32_t size = 0; mapi_sprop->value.MVszW.cValues = sprop->value.MVszW.cValues; size += 4; mapi_sprop->value.MVszW.strings = talloc_array(mem_ctx, struct mapi_LPWSTR, mapi_sprop->value.MVszW.cValues); for (i = 0; i < mapi_sprop->value.MVszW.cValues; i++) { mapi_sprop->value.MVszW.strings[i].lppszW = sprop->value.MVszW.lppszW[i]; size += get_utf8_utf16_conv_length(mapi_sprop->value.MVszW.strings[i].lppszW); } return size; } case PT_MV_BINARY: { uint32_t i; uint32_t size = 0; mapi_sprop->value.MVbin.cValues = sprop->value.MVbin.cValues; size += 4; mapi_sprop->value.MVbin.bin = talloc_array(mem_ctx, struct SBinary_short, mapi_sprop->value.MVbin.cValues); for (i = 0; i < mapi_sprop->value.MVbin.cValues; i++) { mapi_sprop->value.MVbin.bin[i].cb = sprop->value.MVbin.lpbin[i].cb; mapi_sprop->value.MVbin.bin[i].lpb = sprop->value.MVbin.lpbin[i].lpb; size += sprop->value.MVbin.lpbin[i].cb + sizeof (uint16_t); } return size; } case PT_MV_LONG: { uint32_t i; mapi_sprop->value.MVl.cValues = sprop->value.MVl.cValues; mapi_sprop->value.MVl.lpl = talloc_array (mem_ctx, uint32_t, mapi_sprop->value.MVl.cValues); for (i = 0; i < mapi_sprop->value.MVl.cValues; i++) { mapi_sprop->value.MVl.lpl[i] = sprop->value.MVl.lpl[i]; } return sizeof(mapi_sprop->value.MVl.cValues) + (mapi_sprop->value.MVl.cValues * sizeof (uint32_t)); } case PT_MV_CLSID: { uint32_t i; DATA_BLOB b; mapi_sprop->value.MVguid.cValues = sprop->value.MVguid.cValues; mapi_sprop->value.MVguid.lpguid = talloc_array (mem_ctx, struct GUID, mapi_sprop->value.MVguid.cValues); for (i = 0; i < mapi_sprop->value.MVguid.cValues; i++) { b.data = sprop->value.MVguid.lpguid[i]->ab; b.length = 16; GUID_from_ndr_blob(&b, &(mapi_sprop->value.MVguid.lpguid[i])); } return sizeof(mapi_sprop->value.MVguid.cValues) + (mapi_sprop->value.MVguid.cValues * sizeof (struct GUID)); } default: printf("unhandled conversion case in cast_mapi_SPropValue(): 0x%x\n", (sprop->ulPropTag & 0xFFFF)); OPENCHANGE_ASSERT(); } return 0; } /** \details Convenience function to convert a mapi_SPropValue structure into a SPropValue structure and return the associated size \param mem_ctx pointer to the memory context to use for allocation \param mapi_sprop pointer to the MAPI SPropValue structure to copy data from \param sprop pointer to the SPropValue structure to copy data to \return size of the converted data on success, otherwise 0 */ _PUBLIC_ uint32_t cast_SPropValue(TALLOC_CTX *mem_ctx, struct mapi_SPropValue *mapi_sprop, struct SPropValue *sprop) { sprop->ulPropTag = mapi_sprop->ulPropTag; switch(sprop->ulPropTag & 0xFFFF) { case PT_BOOLEAN: sprop->value.b = mapi_sprop->value.b; return sizeof(uint8_t); case PT_I2: sprop->value.i = mapi_sprop->value.i; return sizeof(uint16_t); case PT_LONG: sprop->value.l = mapi_sprop->value.l; return sizeof(uint32_t); case PT_DOUBLE: sprop->value.dbl = mapi_sprop->value.dbl; return sizeof(double); case PT_I8: sprop->value.d = mapi_sprop->value.d; return sizeof(uint64_t); case PT_STRING8: sprop->value.lpszA = mapi_sprop->value.lpszA; if (!mapi_sprop->value.lpszA) return 0; return (strlen(sprop->value.lpszA) + 1); case PT_UNICODE: sprop->value.lpszW = mapi_sprop->value.lpszW; if (!sprop->value.lpszW) return 0; return (get_utf8_utf16_conv_length(mapi_sprop->value.lpszW)); case PT_SYSTIME: sprop->value.ft.dwLowDateTime = mapi_sprop->value.ft.dwLowDateTime; sprop->value.ft.dwHighDateTime = mapi_sprop->value.ft.dwHighDateTime; return (sizeof (struct FILETIME)); case PT_CLSID: { DATA_BLOB b; GUID_to_ndr_blob(&(mapi_sprop->value.lpguid), mem_ctx, &b); sprop->value.lpguid = talloc_zero(mem_ctx, struct FlatUID_r); sprop->value.lpguid = (struct FlatUID_r *)memcpy(sprop->value.lpguid->ab, b.data, 16); return (sizeof (struct FlatUID_r)); } case PT_SVREID: sprop->value.bin.cb = mapi_sprop->value.bin.cb; sprop->value.bin.lpb = mapi_sprop->value.bin.lpb; return (sprop->value.bin.cb + sizeof (uint16_t)); case PT_BINARY: sprop->value.bin.cb = mapi_sprop->value.bin.cb; sprop->value.bin.lpb = mapi_sprop->value.bin.lpb; return (sprop->value.bin.cb + sizeof(uint16_t)); case PT_ERROR: sprop->value.err = (enum MAPISTATUS)mapi_sprop->value.err; return sizeof(uint32_t); case PT_MV_LONG: { uint32_t i; uint32_t size = 0; sprop->value.MVl.cValues = mapi_sprop->value.MVl.cValues; size += 4; sprop->value.MVl.lpl = talloc_array(mem_ctx, uint32_t, sprop->value.MVl.cValues); for (i = 0; i < sprop->value.MVl.cValues; i++) { sprop->value.MVl.lpl[i] = mapi_sprop->value.MVl.lpl[i]; size += sizeof (uint32_t); } return size; } case PT_MV_STRING8: { uint32_t i; uint32_t size = 0; sprop->value.MVszA.cValues = mapi_sprop->value.MVszA.cValues; size += 4; sprop->value.MVszA.lppszA = talloc_array(mem_ctx, const char *, sprop->value.MVszA.cValues); for (i = 0; i < sprop->value.MVszA.cValues; i++) { sprop->value.MVszA.lppszA[i] = mapi_sprop->value.MVszA.strings[i].lppszA; size += strlen(sprop->value.MVszA.lppszA[i]) + 1; } return size; } case PT_MV_UNICODE: { uint32_t i; uint32_t size = 0; sprop->value.MVszW.cValues = mapi_sprop->value.MVszW.cValues; size += 4; sprop->value.MVszW.lppszW = talloc_array(mem_ctx, const char*, sprop->value.MVszW.cValues); for (i = 0; i < sprop->value.MVszW.cValues; i++) { sprop->value.MVszW.lppszW[i] = mapi_sprop->value.MVszW.strings[i].lppszW; size += get_utf8_utf16_conv_length(sprop->value.MVszW.lppszW[i]); } return size; } case PT_MV_CLSID: { uint32_t i; uint32_t size = 0; // conceptually we're copying mapi_SGuidArray over to FlatUIDArray_r // typedef struct { // uint32 cValues; // GUID lpguid[cValues]; // } mapi_SGuidArray; // typedef [flag(NDR_NOALIGN)] struct { // [range(0,100000)]uint32 cValues; // [size_is(cValues)] FlatUID_r **lpguid; // } FlatUIDArray_r; sprop->value.MVguid.cValues = mapi_sprop->value.MVguid.cValues; size += sizeof(uint32_t); sprop->value.MVguid.lpguid = talloc_array(mem_ctx, struct FlatUID_r*, sprop->value.MVguid.cValues); for (i = 0; i < sprop->value.MVguid.cValues; ++i) { DATA_BLOB b; sprop->value.MVguid.lpguid[i] = talloc_zero(mem_ctx, struct FlatUID_r); GUID_to_ndr_blob(&(mapi_sprop->value.MVguid.lpguid[i]), mem_ctx, &b); sprop->value.MVguid.lpguid[i] = (struct FlatUID_r *)memcpy(sprop->value.MVguid.lpguid[i]->ab, b.data, sizeof(struct FlatUID_r)); size += (sizeof (struct FlatUID_r)); } return size; } case PT_MV_BINARY: { uint32_t i; uint32_t size = 0; sprop->value.MVbin.cValues = mapi_sprop->value.MVbin.cValues; size += 4; sprop->value.MVbin.lpbin = talloc_array(mem_ctx, struct Binary_r, sprop->value.MVbin.cValues); for (i = 0; i < sprop->value.MVbin.cValues; i++) { sprop->value.MVbin.lpbin[i].cb = mapi_sprop->value.MVbin.bin[i].cb; if (sprop->value.MVbin.lpbin[i].cb) { sprop->value.MVbin.lpbin[i].lpb = (uint8_t *)talloc_memdup(sprop->value.MVbin.lpbin, mapi_sprop->value.MVbin.bin[i].lpb, mapi_sprop->value.MVbin.bin[i].cb); } else { sprop->value.MVbin.lpbin[i].lpb = NULL; } size += sizeof (uint32_t); size += sprop->value.MVbin.lpbin[i].cb; } return size; } default: printf("unhandled conversion case in cast_SPropValue(): 0x%x\n", (sprop->ulPropTag & 0xFFFF)); OPENCHANGE_ASSERT(); } return 0; } /** \details add a SPropValue structure to a SRow array \param aRow pointer to the SRow array where spropvalue should be appended \param spropvalue reference to the SPropValue structure to add to aRow \return MAPI_E_SUCCESS on success, otherwise MAPI_E_INVALID_PARAMETER. */ _PUBLIC_ enum MAPISTATUS SRow_addprop(struct SRow *aRow, struct SPropValue spropvalue) { TALLOC_CTX *mem_ctx; uint32_t cValues; struct SPropValue lpProp; uint32_t i; /* Sanity checks */ OPENCHANGE_RETVAL_IF(!aRow, MAPI_E_INVALID_PARAMETER, NULL); mem_ctx = (TALLOC_CTX *) aRow; /* If the property tag already exist, overwrite its value */ for (i = 0; i < aRow->cValues; i++) { if (aRow->lpProps[i].ulPropTag == spropvalue.ulPropTag) { aRow->lpProps[i] = spropvalue; return MAPI_E_SUCCESS; } } cValues = aRow->cValues + 1; aRow->lpProps = talloc_realloc(mem_ctx, aRow->lpProps, struct SPropValue, cValues); lpProp = aRow->lpProps[cValues-1]; lpProp.ulPropTag = spropvalue.ulPropTag; lpProp.dwAlignPad = 0; set_SPropValue(&(lpProp), get_SPropValue_data(&spropvalue)); aRow->cValues = cValues; aRow->lpProps[cValues - 1] = lpProp; return MAPI_E_SUCCESS; } /** \details Append a SPropValue structure to given SRowSet \param mem_ctx pointer to the memory context \param SRowSet pointer to the SRowSet array to update \param spropvalue the SPropValue to append within SRowSet \return 0 on success, otherwise 1 */ _PUBLIC_ uint32_t SRowSet_propcpy(TALLOC_CTX *mem_ctx, struct SRowSet *SRowSet, struct SPropValue spropvalue) { uint32_t rows; uint32_t cValues; struct SPropValue lpProp; /* Sanity checks */ if (!SRowSet) return 1; for (rows = 0; rows < SRowSet->cRows; rows++) { cValues = SRowSet->aRow[rows].cValues + 1; SRowSet->aRow[rows].lpProps = talloc_realloc(mem_ctx, SRowSet->aRow[rows].lpProps, struct SPropValue, cValues); lpProp = SRowSet->aRow[rows].lpProps[cValues-1]; lpProp.ulPropTag = spropvalue.ulPropTag; lpProp.dwAlignPad = 0; set_SPropValue(&(lpProp), (void *)&spropvalue.value); SRowSet->aRow[rows].cValues = cValues; SRowSet->aRow[rows].lpProps[cValues - 1] = lpProp; } return 0; } _PUBLIC_ void mapi_SPropValue_array_named(mapi_object_t *obj, struct mapi_SPropValue_array *props) { TALLOC_CTX *mem_ctx; enum MAPISTATUS retval; struct MAPINAMEID *nameid; uint32_t propID; uint16_t count; uint32_t i; mem_ctx = talloc_named(mapi_object_get_session(obj), 0, "mapi_SPropValue_array_named"); for (i = 0; i < props->cValues; i++) { if ((props->lpProps[i].ulPropTag & 0xFFFF0000) > 0x80000000) { propID = props->lpProps[i].ulPropTag; propID = (propID & 0xFFFF0000) | PT_NULL; nameid = talloc_zero(mem_ctx, struct MAPINAMEID); retval = GetNamesFromIDs(obj, (enum MAPITAGS)propID, &count, &nameid); if (retval != MAPI_E_SUCCESS) goto end; if (count) { /* Display property given its propID */ switch (nameid->ulKind) { case MNID_ID: props->lpProps[i].ulPropTag = (enum MAPITAGS)((nameid->kind.lid << 16) | ((int)props->lpProps[i].ulPropTag & 0x0000FFFF)); break; case MNID_STRING: /* MNID_STRING named properties don't have propIDs */ break; } } talloc_free(nameid); } } end: talloc_free(mem_ctx); } _PUBLIC_ enum MAPISTATUS get_mapi_SPropValue_array_date_timeval(struct timeval *t, struct mapi_SPropValue_array *properties, uint32_t mapitag) { const struct FILETIME *filetime; NTTIME time; filetime = (const struct FILETIME *) find_mapi_SPropValue_data(properties, mapitag); if (!filetime) { t = NULL; return MAPI_E_NOT_FOUND; } time = filetime->dwHighDateTime; time = time << 32; time |= filetime->dwLowDateTime; nttime_to_timeval(t, time); return MAPI_E_SUCCESS; } _PUBLIC_ enum MAPISTATUS get_mapi_SPropValue_date_timeval(struct timeval *t, struct SPropValue lpProp) { const struct FILETIME *filetime; NTTIME time; filetime = (const struct FILETIME *) get_SPropValue_data(&lpProp); if (!filetime) { t = NULL; return MAPI_E_NOT_FOUND; } time = filetime->dwHighDateTime; time = time << 32; time |= filetime->dwLowDateTime; nttime_to_timeval(t, time); return MAPI_E_SUCCESS; } _PUBLIC_ bool set_SPropValue_proptag_date_timeval(struct SPropValue *lpProps, enum MAPITAGS aulPropTag, const struct timeval *t) { struct FILETIME filetime; NTTIME time; time = timeval_to_nttime(t); filetime.dwLowDateTime = (time << 32) >> 32; filetime.dwHighDateTime = time >> 32; return set_SPropValue_proptag(lpProps, aulPropTag, &filetime); } /** \details Retrieve a RecurrencePattern structure from a binary blob \param mem_ctx pointer to the memory context \param bin pointer to the Binary_r structure with non-mapped reccurrence data \return Allocated RecurrencePattern structure on success, otherwise NULL \note Developers must free the allocated RecurrencePattern when finished. */ _PUBLIC_ struct RecurrencePattern *get_RecurrencePattern(TALLOC_CTX *mem_ctx, struct Binary_r *bin) { struct RecurrencePattern *RecurrencePattern = NULL; struct ndr_pull *ndr; enum ndr_err_code ndr_err_code; /* Sanity checks */ if (!bin) return NULL; if (!bin->cb) return NULL; if (!bin->lpb) return NULL; ndr = talloc_zero(mem_ctx, struct ndr_pull); ndr->offset = 0; ndr->data = bin->lpb; ndr->data_size = bin->cb; ndr_set_flags(&ndr->flags, LIBNDR_FLAG_NOALIGN); RecurrencePattern = talloc_zero(mem_ctx, struct RecurrencePattern); ndr_err_code = ndr_pull_RecurrencePattern(ndr, NDR_SCALARS, RecurrencePattern); talloc_free(ndr); if (ndr_err_code != NDR_ERR_SUCCESS) { talloc_free(RecurrencePattern); return NULL; } /*Copy DeletedInstanceDates and ModifiedInstanceDates into memory*/ RecurrencePattern->DeletedInstanceDates = (uint32_t *) talloc_memdup(mem_ctx, RecurrencePattern->DeletedInstanceDates, sizeof(uint32_t) * RecurrencePattern->DeletedInstanceCount); RecurrencePattern->ModifiedInstanceDates = (uint32_t *) talloc_memdup(mem_ctx, RecurrencePattern->ModifiedInstanceDates, sizeof(uint32_t) * RecurrencePattern->ModifiedInstanceCount); /*Set reference to parent so arrays get free with RecurrencePattern struct*/ RecurrencePattern->DeletedInstanceDates=talloc_reference(RecurrencePattern, RecurrencePattern->DeletedInstanceDates); RecurrencePattern->ModifiedInstanceDates=talloc_reference(RecurrencePattern, RecurrencePattern->ModifiedInstanceDates); return RecurrencePattern; } _PUBLIC_ size_t set_RecurrencePattern_size(const struct RecurrencePattern *rp) { size_t size = SIZE_DFLT_RECURRENCEPATTERN; switch (rp->PatternType) { case PatternType_MonthNth: case PatternType_HjMonthNth: size += sizeof(uint32_t); break; case PatternType_Week: case PatternType_Month: case PatternType_MonthEnd: case PatternType_HjMonth: case PatternType_HjMonthEnd: size += sizeof(uint32_t); break; case PatternType_Day: break; default: DEBUG(0, ("%s: unrecognized pattern type: %d", __PRETTY_FUNCTION__, rp->PatternType)); } size += rp->DeletedInstanceCount * sizeof(uint32_t); size += rp->ModifiedInstanceCount * sizeof(uint32_t); return size; } _PUBLIC_ struct Binary_r *set_RecurrencePattern(TALLOC_CTX *mem_ctx, const struct RecurrencePattern *rp) { struct Binary_r *bin = NULL; struct ndr_push *ndr; enum ndr_err_code ndr_err_code; size_t bin_size; /* SANITY CHECKS */ if (!rp) return NULL; bin_size = set_RecurrencePattern_size(rp); bin = talloc_zero(mem_ctx, struct Binary_r); bin->cb = bin_size; bin->lpb = talloc_array(bin, uint8_t, bin_size); ndr = talloc_zero(mem_ctx, struct ndr_push); ndr->offset = 0; ndr->data = bin->lpb; ndr_err_code = ndr_push_RecurrencePattern(ndr, NDR_SCALARS, rp); talloc_free(ndr); if (ndr_err_code != NDR_ERR_SUCCESS) { talloc_free(bin); return NULL; } return bin; } _PUBLIC_ struct AppointmentRecurrencePattern *get_AppointmentRecurrencePattern(TALLOC_CTX *mem_ctx, struct Binary_r *bin) { struct AppointmentRecurrencePattern *arp = NULL; struct ndr_pull *ndr; enum ndr_err_code ndr_err_code; /* Sanity checks */ if (!bin) return NULL; if (!bin->cb) return NULL; if (!bin->lpb) return NULL; ndr = talloc_zero(mem_ctx, struct ndr_pull); ndr->offset = 0; ndr->data = bin->lpb; ndr->data_size = bin->cb; ndr_set_flags(&ndr->flags, LIBNDR_FLAG_NOALIGN); arp = talloc_zero(mem_ctx, struct AppointmentRecurrencePattern); ndr_err_code = ndr_pull_AppointmentRecurrencePattern(ndr, NDR_SCALARS, arp); talloc_free(ndr); if (ndr_err_code != NDR_ERR_SUCCESS) { talloc_free(arp); return NULL; } /* Copy ExceptionInfo array into memory */ arp->ExceptionInfo = (struct ExceptionInfo *) talloc_memdup(mem_ctx,arp->ExceptionInfo, sizeof(struct ExceptionInfo) * arp->ExceptionCount); /* Copy DeletedInstanceDates and ModifiedInstanceDates into memory */ arp->RecurrencePattern.DeletedInstanceDates = (uint32_t *) talloc_memdup(mem_ctx, arp->RecurrencePattern.DeletedInstanceDates, sizeof(uint32_t) * arp->RecurrencePattern.DeletedInstanceCount); arp->RecurrencePattern.ModifiedInstanceDates = (uint32_t *) talloc_memdup(mem_ctx, arp->RecurrencePattern.ModifiedInstanceDates, sizeof(uint32_t) * arp->RecurrencePattern.ModifiedInstanceCount); /* Set reference to parent so arrays get free with rest */ arp->ExceptionInfo = talloc_reference(arp, arp->ExceptionInfo); arp->RecurrencePattern.DeletedInstanceDates = talloc_reference(arp,arp->RecurrencePattern.DeletedInstanceDates); arp->RecurrencePattern.ModifiedInstanceDates = talloc_reference(arp, arp->RecurrencePattern.ModifiedInstanceDates); return arp; } _PUBLIC_ size_t set_AppointmentRecurrencePattern_size(const struct AppointmentRecurrencePattern *arp) { size_t size = SIZE_DFLT_APPOINTMENTRECURRENCEPATTERN; uint16_t i; size += set_RecurrencePattern_size(&arp->RecurrencePattern); for (i = 0; i < arp->ExceptionCount; i++) { size += set_ExceptionInfo_size(arp->ExceptionInfo + i); size += set_ExtendedException_size(arp->WriterVersion2, (arp->ExceptionInfo + i)->OverrideFlags, arp->ExtendedException + i); } size += arp->ReservedBlock1Size * sizeof(uint32_t); size += arp->ReservedBlock2Size * sizeof(uint32_t); return size; } _PUBLIC_ struct Binary_r *set_AppointmentRecurrencePattern(TALLOC_CTX *mem_ctx, const struct AppointmentRecurrencePattern *arp) { struct Binary_r *bin = NULL; struct ndr_push *ndr; enum ndr_err_code ndr_err_code; TALLOC_CTX *local_mem_ctx; /* SANITY CHECKS */ if (!arp) return NULL; local_mem_ctx = talloc_zero(NULL, TALLOC_CTX); ndr = ndr_push_init_ctx(local_mem_ctx); ndr_set_flags(&ndr->flags, LIBNDR_FLAG_NOALIGN); ndr->offset = 0; ndr_err_code = ndr_push_AppointmentRecurrencePattern(ndr, NDR_SCALARS, arp); if (ndr_err_code != NDR_ERR_SUCCESS) { talloc_free(local_mem_ctx); return NULL; } bin = talloc_zero(mem_ctx, struct Binary_r); bin->cb = ndr->offset; bin->lpb = ndr->data; (void) talloc_reference(bin, bin->lpb); talloc_free(local_mem_ctx); return bin; } _PUBLIC_ size_t set_ExceptionInfo_size(const struct ExceptionInfo *exc_info) { size_t size = SIZE_DFLT_EXCEPTIONINFO; if ((exc_info->OverrideFlags & ARO_SUBJECT)) { size += 3 * sizeof(uint16_t); /* SubjectLength + SubjectLength2 + Subject */ size += exc_info->Subject.subjectMsg.msgLength2; } if ((exc_info->OverrideFlags & ARO_MEETINGTYPE)) { size += sizeof(uint32_t); } if ((exc_info->OverrideFlags & ARO_REMINDERDELTA)) { size += sizeof(uint32_t); } if ((exc_info->OverrideFlags & ARO_REMINDER)) { size += sizeof(uint32_t); } if ((exc_info->OverrideFlags & ARO_LOCATION)) { size += 2 * sizeof(uint16_t); /* LocationLength + LocationLength2 */ size += exc_info->Location.locationMsg.msgLength2; } if ((exc_info->OverrideFlags & ARO_BUSYSTATUS)) { size += sizeof(uint32_t); } if ((exc_info->OverrideFlags & ARO_ATTACHMENT)) { size += sizeof(uint32_t); } if ((exc_info->OverrideFlags & ARO_SUBTYPE)) { size += sizeof(uint32_t); } /* size += exc_info->ReservedBlock1Size; */ /* if ((exc_info->OverrideFlags & ARO_APPTCOLOR)) { */ /* size += sizeof(uint32_t); */ /* } */ return size; } size_t set_ExtendedException_size(uint32_t WriterVersion2, enum OverrideFlags flags, const struct ExtendedException *ext_exc) { size_t size = SIZE_DFLT_EXTENDEDEXCEPTION; bool subject_or_location; subject_or_location = (flags & (ARO_SUBJECT | ARO_LOCATION)); if (WriterVersion2 > 0x00003008) { size += ext_exc->ChangeHighlight.Size; } if (subject_or_location) { size += 3 * sizeof(uint32_t); // StartDateTime + EndDateTime + OriginalStartDate */ size += sizeof(uint32_t) + ext_exc->ReservedBlockEE2Size; } if ((flags & ARO_SUBJECT)) { size += sizeof(uint16_t) + strlen_m_ext(ext_exc->Subject, CH_UTF8, CH_UTF16LE) * 2; } if ((flags & ARO_LOCATION)) { size += sizeof(uint16_t) + strlen_m_ext(ext_exc->Location, CH_UTF8, CH_UTF16LE) * 2; } return size; } /* TODO: the get_XXX NDR wrapper should be normalized */ /** \details Retrieve a TimeZoneStruct structure from a binary blob \param mem_ctx pointer to the memory context \param bin pointer to the Binary_r structure with raw TimeZoneStruct data \return Allocated TimeZoneStruct structure on success, otherwise NULL \note Developers must free the allocated TimeZoneStruct when finished. */ _PUBLIC_ struct TimeZoneStruct *get_TimeZoneStruct(TALLOC_CTX *mem_ctx, struct Binary_r *bin) { struct TimeZoneStruct *TimeZoneStruct = NULL; struct ndr_pull *ndr; enum ndr_err_code ndr_err_code; /* Sanity checks */ if (!bin) return NULL; if (!bin->cb) return NULL; if (!bin->lpb) return NULL; ndr = talloc_zero(mem_ctx, struct ndr_pull); ndr->offset = 0; ndr->data = bin->lpb; ndr->data_size = bin->cb; ndr_set_flags(&ndr->flags, LIBNDR_FLAG_NOALIGN); TimeZoneStruct = talloc_zero(mem_ctx, struct TimeZoneStruct); ndr_err_code = ndr_pull_TimeZoneStruct(ndr, NDR_SCALARS, TimeZoneStruct); talloc_free(ndr); if (ndr_err_code != NDR_ERR_SUCCESS) { talloc_free(TimeZoneStruct); return NULL; } return TimeZoneStruct; } _PUBLIC_ struct Binary_r *set_TimeZoneStruct(TALLOC_CTX *mem_ctx, const struct TimeZoneStruct *TimeZoneStruct) { struct Binary_r *bin = NULL; struct ndr_push *ndr; enum ndr_err_code ndr_err_code; /* SANITY CHECKS */ if (!TimeZoneStruct) return NULL; ndr = talloc_zero(mem_ctx, struct ndr_push); ndr_err_code = ndr_push_TimeZoneStruct(ndr, NDR_SCALARS, TimeZoneStruct); if (ndr_err_code != NDR_ERR_SUCCESS) { goto end; } bin = talloc_zero(mem_ctx, struct Binary_r); bin->cb = ndr->offset; bin->lpb = ndr->data; (void) talloc_reference(bin, bin->lpb); end: talloc_free(ndr); return bin; } _PUBLIC_ struct Binary_r *set_TimeZoneDefinition(TALLOC_CTX *mem_ctx, const struct TimeZoneDefinition *TimeZoneDefinition) { struct Binary_r *bin = NULL; struct ndr_push *ndr; enum ndr_err_code ndr_err_code; /* SANITY CHECKS */ if (!TimeZoneDefinition) return NULL; ndr = talloc_zero(mem_ctx, struct ndr_push); ndr_err_code = ndr_push_TimeZoneDefinition(ndr, NDR_SCALARS, TimeZoneDefinition); if (ndr_err_code != NDR_ERR_SUCCESS) { goto end; } bin = talloc_zero(mem_ctx, struct Binary_r); bin->cb = ndr->offset; bin->lpb = ndr->data; (void) talloc_reference(bin, bin->lpb); end: talloc_free(ndr); return bin; } /** \details Retrieve a PtypServerId structure from a binary blob \param mem_ctx pointer to the memory context \param bin pointer to the Binary_r structure with raw PtypServerId data \return Allocated PtypServerId structure on success, otherwise NULL \note Developers must free the allocated PtypServerId when finished. */ _PUBLIC_ struct PtypServerId *get_PtypServerId(TALLOC_CTX *mem_ctx, struct Binary_r *bin) { struct PtypServerId *PtypServerId = NULL; struct ndr_pull *ndr; enum ndr_err_code ndr_err_code; /* Sanity checks */ if (!bin) return NULL; if (!bin->cb) return NULL; if (!bin->lpb) return NULL; ndr = talloc_zero(mem_ctx, struct ndr_pull); ndr->offset = 0; ndr->data = bin->lpb; ndr->data_size = bin->cb; ndr_set_flags(&ndr->flags, LIBNDR_FLAG_NOALIGN); PtypServerId = talloc_zero(mem_ctx, struct PtypServerId); ndr_err_code = ndr_pull_PtypServerId(ndr, NDR_SCALARS, PtypServerId); talloc_free(ndr); if (ndr_err_code != NDR_ERR_SUCCESS) { talloc_free(PtypServerId); return NULL; } return PtypServerId; } /** \details Retrieve a GlobalObjectId structure from a binary blob \param mem_ctx pointer to the memory context \param bin pointer to the Binary_r structure with raw GlobalObjectId data \return Allocated GlobalObjectId structure on success, otherwise NULL \note Developers must free the allocated GlobalObjectId when finished. */ _PUBLIC_ struct GlobalObjectId *get_GlobalObjectId(TALLOC_CTX *mem_ctx, struct Binary_r *bin) { struct GlobalObjectId *GlobalObjectId = NULL; struct ndr_pull *ndr; enum ndr_err_code ndr_err_code; /* Sanity checks */ if (!bin) return NULL; if (!bin->cb) return NULL; if (!bin->lpb) return NULL; ndr = talloc_zero(mem_ctx, struct ndr_pull); ndr->offset = 0; ndr->data = bin->lpb; ndr->data_size = bin->cb; ndr_set_flags(&ndr->flags, LIBNDR_FLAG_NOALIGN); GlobalObjectId = talloc_zero(mem_ctx, struct GlobalObjectId); ndr_err_code = ndr_pull_GlobalObjectId(ndr, NDR_SCALARS, GlobalObjectId); talloc_free(ndr); if (ndr_err_code != NDR_ERR_SUCCESS) { talloc_free(GlobalObjectId); return NULL; } return GlobalObjectId; } /** \details Retrieve a MessageEntryId structure from a binary blob \param mem_ctx pointer to the memory context \param bin pointer to the Binary_r structure with raw MessageEntryId data \return Allocated MessageEntryId structure on success, otherwise NULL \note Developers must free the allocated MessageEntryId when finished. */ _PUBLIC_ struct MessageEntryId *get_MessageEntryId(TALLOC_CTX *mem_ctx, struct Binary_r *bin) { struct MessageEntryId *MessageEntryId = NULL; struct ndr_pull *ndr; enum ndr_err_code ndr_err_code; /* Sanity checks */ if (!bin) return NULL; if (!bin->cb) return NULL; if (!bin->lpb) return NULL; ndr = talloc_zero(mem_ctx, struct ndr_pull); ndr->offset = 0; ndr->data = bin->lpb; ndr->data_size = bin->cb; ndr_set_flags(&ndr->flags, LIBNDR_FLAG_NOALIGN); MessageEntryId = talloc_zero(mem_ctx, struct MessageEntryId); ndr_err_code = ndr_pull_MessageEntryId(ndr, NDR_SCALARS, MessageEntryId); talloc_free(ndr); if (ndr_err_code != NDR_ERR_SUCCESS) { talloc_free(MessageEntryId); return NULL; } return MessageEntryId; } /** \details Retrieve a FolderEntryId structure from a binary blob \param mem_ctx pointer to the memory context \param bin pointer to the Binary_r structure with raw FolderEntryId data \return Allocated FolderEntryId structure on success, otherwise NULL \note Developers must free the allocated FolderEntryId when finished. */ _PUBLIC_ struct FolderEntryId *get_FolderEntryId(TALLOC_CTX *mem_ctx, struct Binary_r *bin) { struct FolderEntryId *FolderEntryId = NULL; struct ndr_pull *ndr; enum ndr_err_code ndr_err_code; /* Sanity checks */ if (!bin) return NULL; if (!bin->cb) return NULL; if (!bin->lpb) return NULL; ndr = talloc_zero(mem_ctx, struct ndr_pull); ndr->offset = 0; ndr->data = bin->lpb; ndr->data_size = bin->cb; ndr_set_flags(&ndr->flags, LIBNDR_FLAG_NOALIGN); FolderEntryId = talloc_zero(mem_ctx, struct FolderEntryId); ndr_err_code = ndr_pull_FolderEntryId(ndr, NDR_SCALARS, FolderEntryId); talloc_free(ndr); if (ndr_err_code != NDR_ERR_SUCCESS) { talloc_free(FolderEntryId); return NULL; } return FolderEntryId; } /** \details Retrieve a AddressBookEntryId structure from a binary blob \param mem_ctx pointer to the memory context \param bin pointer to the Binary_r structure with raw AddressBookEntryId data \return Allocated AddressBookEntryId structure on success, otherwise NULL \note Developers must free the allocated AddressBookEntryId when finished. */ _PUBLIC_ struct AddressBookEntryId *get_AddressBookEntryId(TALLOC_CTX *mem_ctx, struct Binary_r *bin) { struct AddressBookEntryId *AddressBookEntryId = NULL; struct ndr_pull *ndr; enum ndr_err_code ndr_err_code; /* Sanity checks */ if (!bin) return NULL; if (!bin->cb) return NULL; if (!bin->lpb) return NULL; ndr = talloc_zero(mem_ctx, struct ndr_pull); ndr->offset = 0; ndr->data = bin->lpb; ndr->data_size = bin->cb; ndr_set_flags(&ndr->flags, LIBNDR_FLAG_NOALIGN); AddressBookEntryId = talloc_zero(mem_ctx, struct AddressBookEntryId); ndr_err_code = ndr_pull_AddressBookEntryId(ndr, NDR_SCALARS, AddressBookEntryId); talloc_free(ndr); if (ndr_err_code != NDR_ERR_SUCCESS) { talloc_free(AddressBookEntryId); return NULL; } return AddressBookEntryId; } /** \details Return the effective value used in a TypedString structure. \param tstring pointer to TypedString structure \return pointer to a valid string on success, otherwise NULL */ _PUBLIC_ const char *get_TypedString(struct TypedString *tstring) { if (!tstring) return NULL; switch (tstring->StringType) { case StringType_STRING8: return tstring->String.lpszA; case StringType_UNICODE_REDUCED: return tstring->String.lpszW_reduced; case StringType_UNICODE: return tstring->String.lpszW; case StringType_NONE: case StringType_EMPTY: default: return NULL; } return NULL; } /** \details Return the expected size of the utf8 string after conversion to utf16 by iconv() function. \param inbuf pointer to the input string \return expected length of the converted string \note This routine is based upon utf8_pull() function from samba4/lib/util/charset/iconv.c */ size_t get_utf8_utf16_conv_length(const char *inbuf) { size_t in_left; size_t out_left; size_t max_out; const uint8_t *c = (const uint8_t *) inbuf; /* Sanity checks */ if (!inbuf) return 0; in_left = strlen(inbuf); out_left = in_left; out_left = ( out_left * 3); /* includes null-termination bytes */ max_out = out_left + 2; while (in_left >= 1 && out_left >= 2) { if ((c[0] & 0x80) == 0) { c += 1; in_left -= 1; out_left -= 2; continue; } if ((c[0] & 0xe0) == 0xc0) { if (in_left < 2 || (c[1] & 0xc0) != 0x80) { return -1; } c += 2; in_left -= 2; out_left -= 2; continue; } if ((c[0] & 0xf0) == 0xe0) { if (in_left < 3 || (c[1] & 0xc0) != 0x80 || (c[2] & 0xc0) != 0x80) { return -1; } c += 3; in_left -= 3; out_left -= 2; continue; } if ((c[0] & 0xf8) == 0xf0) { unsigned int codepoint; if (in_left < 4 || (c[1] & 0xc0) != 0x80 || (c[2] & 0xc0) != 0x80 || (c[3] & 0xc0) != 0x80) { return -1; } codepoint = (c[3]&0x3f) | ((c[2]&0x3f)<<6) | ((c[1]&0x3f)<<12) | ((c[0]&0x7)<<18); if (codepoint < 0x10000) { c += 4; in_left -= 4; out_left -= 2; continue; } codepoint -= 0x10000; if (out_left < 4) { return -1; } c += 4; in_left -= 4; out_left -= 4; continue; } /* we don't handle 5 byte sequences */ return -1; } if (in_left > 0) { return -1; } return (max_out - out_left); } struct PropertyValue_r* get_PropertyValue_PropertyRow(struct PropertyRow_r *aRow, enum MAPITAGS ulPropTag) { uint32_t i; if (!aRow) { return NULL; } for (i = 0; i < aRow->cValues; i++) { if (ulPropTag == aRow->lpProps[i].ulPropTag) { return (&aRow->lpProps[i]); } } return NULL; } _PUBLIC_ struct PropertyValue_r *get_PropertyValue_PropertyRowSet(struct PropertyRowSet_r *RowSet, enum MAPITAGS ulPropTag) { uint32_t i; uint32_t j; /* Sanity Checks */ if (!RowSet) return NULL; for (i = 0; i != RowSet->cRows; i++) { for (j = 0; j < RowSet->aRow[i].cValues; j++) { if (ulPropTag == RowSet->aRow[i].lpProps[j].ulPropTag) { return (&RowSet->aRow[i].lpProps[j]); } } } return NULL; } _PUBLIC_ const void *get_PropertyValue_PropertyRowSet_data(struct PropertyRowSet_r *RowSet, uint32_t ulPropTag) { struct PropertyValue_r *lpProp; lpProp = get_PropertyValue_PropertyRowSet(RowSet, ulPropTag); return get_PropertyValue(lpProp, ulPropTag); } _PUBLIC_ bool set_PropertyValue(struct PropertyValue_r *lpProp, const void *data) { if (data == NULL) { lpProp->ulPropTag = (lpProp->ulPropTag & 0xffff0000) | PT_ERROR; lpProp->value.err = MAPI_E_NOT_FOUND; return false; } switch (lpProp->ulPropTag & 0xFFFF) { case PT_SHORT: lpProp->value.i = *((const uint16_t *)data); break; case PT_BOOLEAN: lpProp->value.b = *((const uint8_t *)data); break; case PT_LONG: lpProp->value.l = *((const uint32_t *)data); break; case PT_STRING8: lpProp->value.lpszA = (const char *) data; break; case PT_BINARY: case PT_SVREID: lpProp->value.bin = *((const struct Binary_r *)data); break; case PT_UNICODE: lpProp->value.lpszW = (const char *) data; break; case PT_CLSID: lpProp->value.lpguid = (struct FlatUID_r *) data; break; case PT_SYSTIME: lpProp->value.ft = *((const struct FILETIME *) data); break; case PT_ERROR: lpProp->value.err = *((enum MAPISTATUS *)data); break; case PT_MV_SHORT: lpProp->value.MVi = *((const struct ShortArray_r *)data); break; case PT_MV_LONG: lpProp->value.MVl = *((const struct LongArray_r *)data); break; case PT_MV_STRING8: lpProp->value.MVszA = *((const struct StringArray_r *)data); break; case PT_MV_BINARY: lpProp->value.MVbin = *((const struct BinaryArray_r *)data); break; case PT_MV_CLSID: lpProp->value.MVguid = *((const struct FlatUIDArray_r *)data); break; case PT_MV_UNICODE: lpProp->value.MVszW = *((const struct StringArrayW_r *)data); break; case PT_MV_SYSTIME: lpProp->value.MVft = *((const struct DateTimeArray_r *)data); break; case PT_NULL: lpProp->value.null = *((const uint32_t *)data); break; default: lpProp->ulPropTag = (lpProp->ulPropTag & 0xffff0000) | PT_ERROR; lpProp->value.err = MAPI_E_NOT_FOUND; return false; } return true; } _PUBLIC_ const void *get_PropertyValue(struct PropertyValue_r *lpProps, enum MAPITAGS ulPropTag) { uint32_t i; /* Sanity checks */ if (!lpProps) return NULL; for (i = 0; lpProps[i].ulPropTag; i++) { if (ulPropTag == lpProps[i].ulPropTag) { return get_PropertyValue_data(&lpProps[i]); } } return NULL; } _PUBLIC_ const void *get_PropertyValue_data(struct PropertyValue_r *lpProps) { if (lpProps->ulPropTag == 0) { return NULL; } switch(lpProps->ulPropTag & 0xFFFF) { case PT_SHORT: return (const void *)&lpProps->value.i; case PT_BOOLEAN: return (const void *)&lpProps->value.b; case PT_STRING8: return (const void *)lpProps->value.lpszA; case PT_UNICODE: return (const void *)lpProps->value.lpszW; case PT_SYSTIME: return (const void *)(struct FILETIME *)&lpProps->value.ft; case PT_ERROR: return (const void *)&lpProps->value.err; case PT_LONG: return (const void *)&lpProps->value.l; case PT_CLSID: return (const void *)lpProps->value.lpguid; case PT_BINARY: case PT_SVREID: return (const void *)&lpProps->value.bin; case PT_MV_SHORT: return (const void *)(struct ShortArray_r *)&lpProps->value.MVi; case PT_MV_LONG: return (const void *)(struct LongArray_r *)&lpProps->value.MVl; case PT_MV_STRING8: return (const void *)(struct StringArray_r *)&lpProps->value.MVszA; case PT_MV_UNICODE: return (const void *)(struct StringArrayW_r *)&lpProps->value.MVszW; case PT_MV_BINARY: return (const void *)(struct BinaryArray_r *)&lpProps->value.MVbin; case PT_MV_SYSTIME: return (const void *)(struct DateTimeArray_r *)&lpProps->value.MVft; case PT_NULL: return (const void *)&lpProps->value.null; default: return NULL; } } /** \details add a PropertyValue_r structure to a PropertyRow_r array \param aRow pointer to the PropertyRow_r array where propValue should be appended \param propValue the PropertyValue_r structure to add to aRow \return MAPI_E_SUCCESS on success, otherwise MAPI_E_INVALID_PARAMETER. */ _PUBLIC_ enum MAPISTATUS PropertyRow_addprop(struct PropertyRow_r *aRow, struct PropertyValue_r propValue) { TALLOC_CTX *mem_ctx; uint32_t cValues; struct PropertyValue_r lpProp; uint32_t i; /* Sanity checks */ OPENCHANGE_RETVAL_IF(!aRow, MAPI_E_INVALID_PARAMETER, NULL); mem_ctx = (TALLOC_CTX *) aRow; /* If the property tag already exist, overwrite its value */ for (i = 0; i < aRow->cValues; i++) { if (aRow->lpProps[i].ulPropTag == propValue.ulPropTag) { aRow->lpProps[i] = propValue; return MAPI_E_SUCCESS; } } cValues = aRow->cValues + 1; aRow->lpProps = talloc_realloc(mem_ctx, aRow->lpProps, struct PropertyValue_r, cValues); lpProp = aRow->lpProps[cValues-1]; lpProp.ulPropTag = propValue.ulPropTag; lpProp.dwAlignPad = 0; set_PropertyValue(&(lpProp), get_PropertyValue_data(&propValue)); aRow->cValues = cValues; aRow->lpProps[cValues - 1] = lpProp; return MAPI_E_SUCCESS; } _PUBLIC_ const void *find_PropertyValue_data(struct PropertyRow_r *aRow, uint32_t mapitag) { uint32_t i; if (!aRow) { return NULL; } for (i = 0; i < aRow->cValues; i++) { if (aRow->lpProps[i].ulPropTag == mapitag) { return get_PropertyValue_data(&(aRow->lpProps[i])); } } return NULL; } /** \details Append a PropertyValue_r structure to given PropertyRowSet_r \param mem_ctx pointer to the memory context \param RowSet pointer to the PropertyRowSet_r array to update \param value the PropertyValue_r to append within SRowSet \return 0 on success, otherwise 1 */ _PUBLIC_ uint32_t PropertyRowSet_propcpy(TALLOC_CTX *mem_ctx, struct PropertyRowSet_r *RowSet, struct PropertyValue_r value) { uint32_t rows; uint32_t cValues; struct PropertyValue_r lpProp; /* Sanity checks */ if (!RowSet) return 1; for (rows = 0; rows < RowSet->cRows; rows++) { cValues = RowSet->aRow[rows].cValues + 1; RowSet->aRow[rows].lpProps = talloc_realloc(mem_ctx, RowSet->aRow[rows].lpProps, struct PropertyValue_r, cValues); lpProp = RowSet->aRow[rows].lpProps[cValues-1]; lpProp.ulPropTag = value.ulPropTag; lpProp.dwAlignPad = 0; set_PropertyValue(&(lpProp), (void *)&value.value); RowSet->aRow[rows].cValues = cValues; RowSet->aRow[rows].lpProps[cValues - 1] = lpProp; } return 0; } /** \details Convenience function to convert a PropertyValue_r structure into a SPropValue structure. \param propvalue pointer to the PropertyValue_r structure to copy data to \param spropvalue pointer to the SPropValue structure to copy data from */ _PUBLIC_ void cast_PropertyValue_to_SPropValue(struct PropertyValue_r *propvalue, struct SPropValue *spropvalue) { spropvalue->ulPropTag = propvalue->ulPropTag; switch (propvalue->ulPropTag & 0xFFFF) { case PT_BOOLEAN: spropvalue->value.b = propvalue->value.b; break; case PT_I2: spropvalue->value.i = propvalue->value.i; break; case PT_LONG: spropvalue->value.l = propvalue->value.l; break; case PT_STRING8: spropvalue->value.lpszA = propvalue->value.lpszA; break; case PT_UNICODE: spropvalue->value.lpszW = propvalue->value.lpszW; break; case PT_SYSTIME: spropvalue->value.ft = propvalue->value.ft; break; case PT_CLSID: spropvalue->value.lpguid = propvalue->value.lpguid; break; case PT_SVREID: case PT_BINARY: spropvalue->value.bin = propvalue->value.bin; break; case PT_ERROR: spropvalue->value.err = propvalue->value.err; break; case PT_MV_LONG: spropvalue->value.MVl = propvalue->value.MVl; break; case PT_MV_STRING8: spropvalue->value.MVszA = propvalue->value.MVszA; break; case PT_MV_UNICODE: spropvalue->value.MVszW = propvalue->value.MVszW; break; case PT_MV_CLSID: spropvalue->value.MVguid = propvalue->value.MVguid; break; case PT_MV_BINARY: spropvalue->value.MVbin = propvalue->value.MVbin; break; default: printf("unhandled conversion case in cast_PropvalueValue(): 0x%x\n", (propvalue->ulPropTag & 0xFFFF)); OPENCHANGE_ASSERT(); } } /** \details Convenience function to convert a PropertyRow_r structure into a SRow structure. \param mem_ctx pointer to the allocation context for structure members \param proprow pointer to the PropertyRow_r structure to copy data to \param srow pointer to the SRow structure to copy data from */ _PUBLIC_ void cast_PropertyRow_to_SRow(TALLOC_CTX *mem_ctx, struct PropertyRow_r *proprow, struct SRow *srow) { uint32_t i; srow->cValues = proprow->cValues; srow->lpProps = talloc_array(mem_ctx, struct SPropValue, srow->cValues); for (i = 0; i < srow->cValues; i++) { cast_PropertyValue_to_SPropValue(proprow->lpProps + i, srow->lpProps + i); } } /** \details Convenience function to convert a PropertyRowSet_r structure into a SRowSet structure. \param mem_ctx pointer to the allocation context for structure members \param prowset pointer to the PropertyRowSet_r structure to copy data to \param setrowset pointer to the SRowSet structure to copy data from */ _PUBLIC_ void cast_PropertyRowSet_to_SRowSet(TALLOC_CTX *mem_ctx, struct PropertyRowSet_r *prowset, struct SRowSet *srowset) { uint32_t i; /* Sanity checks */ if (!srowset || !prowset) return; srowset->cRows = prowset->cRows; srowset->aRow = talloc_array(mem_ctx, struct SRow, srowset->cRows); for (i = 0; i < srowset->cRows; i++) { cast_PropertyRow_to_SRow(mem_ctx, prowset->aRow + i, srowset->aRow + i); } } openchange-2.0/libmapi/property_altnames.h000066400000000000000000004516701223057412600210370ustar00rootroot00000000000000/* Automatically generated by script/makepropslist.py. Do not edit */ #define PR_7BIT_DISPLAY_NAME PROP_TAG(PT_STRING8 , 0x39FF) /* 0x39FF001E */ #define PR_7BIT_DISPLAY_NAME_ERROR PROP_TAG(PT_ERROR , 0x39FF) /* 0x39FF000A */ #define PR_7BIT_DISPLAY_NAME_UNICODE PROP_TAG(PT_UNICODE , 0x39FF) /* 0x39FF001F */ #define PR_ACCESS PidTagAccess #define PR_ACCESS_ERROR PROP_TAG(PT_ERROR , 0x0FF4) /* 0x0FF4000A */ #define PR_ACCESS_LEVEL PidTagAccessLevel #define PR_ACCESS_LEVEL_ERROR PROP_TAG(PT_ERROR , 0x0FF7) /* 0x0FF7000A */ #define PR_ACCOUNT PROP_TAG(PT_STRING8 , 0x3A00) /* 0x3A00001E */ #define PR_ACCOUNT_ERROR PROP_TAG(PT_ERROR , 0x3A00) /* 0x3A00000A */ #define PR_ACCOUNT_UNICODE PROP_TAG(PT_UNICODE , 0x3A00) /* 0x3A00001F */ #define PR_ADDITIONAL_REN_ENTRYIDS PidTagAdditionalRenEntryIds #define PR_ADDITIONAL_REN_ENTRYIDS_ERROR PROP_TAG(PT_ERROR , 0x36D8) /* 0x36D8000A */ #define PR_ADDITIONAL_REN_ENTRYIDS_EX PidTagAdditionalRenEntryIdsEx #define PR_ADDITIONAL_REN_ENTRYIDS_EX_ERROR PROP_TAG(PT_ERROR , 0x36D9) /* 0x36D9000A */ #define PR_ADDRBOOK_MID PidTagAddressBookMessageId #define PR_ADDRESS_BOOK_ENTRYID PidTagAddressBookEntryId #define PR_ADDRESS_BOOK_ENTRYID_ERROR PROP_TAG(PT_ERROR , 0x663B) /* 0x663B000A */ #define PR_ADDRTYPE PROP_TAG(PT_STRING8 , 0x3002) /* 0x3002001E */ #define PR_ADDRTYPE_ERROR PROP_TAG(PT_ERROR , 0x3002) /* 0x3002000A */ #define PR_ADDRTYPE_UNICODE PROP_TAG(PT_UNICODE , 0x3002) /* 0x3002001F */ #define PR_ALTERNATE_RECIPIENT_ALLOWED PidTagAlternateRecipientAllowed #define PR_ALTERNATE_RECIPIENT_ALLOWED_ERROR PROP_TAG(PT_ERROR , 0x0002) /* 0x0002000A */ #define PR_ANR PROP_TAG(PT_STRING8 , 0x360C) /* 0x360C001E */ #define PR_ANR_ERROR PROP_TAG(PT_ERROR , 0x360C) /* 0x360C000A */ #define PR_ANR_UNICODE PROP_TAG(PT_UNICODE , 0x360C) /* 0x360C001F */ #define PR_ARCHIVE_DATE PidTagArchiveDate #define PR_ARCHIVE_DATE_ERROR PROP_TAG(PT_ERROR , 0x301F) /* 0x301F000A */ #define PR_ARCHIVE_PERIOD PidTagArchivePeriod #define PR_ARCHIVE_PERIOD_ERROR PROP_TAG(PT_ERROR , 0x301E) /* 0x301E000A */ #define PR_ARCHIVE_TAG PidTagArchiveTag #define PR_ARCHIVE_TAG_ERROR PROP_TAG(PT_ERROR , 0x3018) /* 0x3018000A */ #define PR_ASSISTANT PROP_TAG(PT_STRING8 , 0x3A30) /* 0x3A30001E */ #define PR_ASSISTANT_ERROR PROP_TAG(PT_ERROR , 0x3A30) /* 0x3A30000A */ #define PR_ASSISTANT_TELEPHONE_NUMBER PROP_TAG(PT_STRING8 , 0x3A2E) /* 0x3A2E001E */ #define PR_ASSISTANT_TELEPHONE_NUMBER_ERROR PROP_TAG(PT_ERROR , 0x3A2E) /* 0x3A2E000A */ #define PR_ASSISTANT_TELEPHONE_NUMBER_UNICODE PROP_TAG(PT_UNICODE , 0x3A2E) /* 0x3A2E001F */ #define PR_ASSISTANT_UNICODE PROP_TAG(PT_UNICODE , 0x3A30) /* 0x3A30001F */ #define PR_ASSOCIATED PidTagAssociated #define PR_ASSOC_CONTENT_COUNT PidTagAssociatedContentCount #define PR_ATTACHMENT_CONTACTPHOTO PidTagAttachmentContactPhoto #define PR_ATTACHMENT_CONTACTPHOTO_ERROR PROP_TAG(PT_ERROR , 0x7FFF) /* 0x7FFF000A */ #define PR_ATTACHMENT_FLAGS PidTagAttachmentFlags #define PR_ATTACHMENT_FLAGS_ERROR PROP_TAG(PT_ERROR , 0x7FFD) /* 0x7FFD000A */ #define PR_ATTACHMENT_HIDDEN PidTagAttachmentHidden #define PR_ATTACHMENT_HIDDEN_ERROR PROP_TAG(PT_ERROR , 0x7FFE) /* 0x7FFE000A */ #define PR_ATTACHMENT_LINKID PidTagAttachmentLinkId #define PR_ATTACHMENT_LINKID_ERROR PROP_TAG(PT_ERROR , 0x7FFA) /* 0x7FFA000A */ #define PR_ATTACH_ADDITIONAL_INFO PidTagAttachAdditionalInformation #define PR_ATTACH_ADDITIONAL_INFO_ERROR PROP_TAG(PT_ERROR , 0x370F) /* 0x370F000A */ #define PR_ATTACH_CONTENT_BASE PROP_TAG(PT_STRING8 , 0x3711) /* 0x3711001E */ #define PR_ATTACH_CONTENT_BASE_ERROR PROP_TAG(PT_ERROR , 0x3711) /* 0x3711000A */ #define PR_ATTACH_CONTENT_BASE_UNICODE PROP_TAG(PT_UNICODE , 0x3711) /* 0x3711001F */ #define PR_ATTACH_CONTENT_ID PROP_TAG(PT_STRING8 , 0x3712) /* 0x3712001E */ #define PR_ATTACH_CONTENT_ID_ERROR PROP_TAG(PT_ERROR , 0x3712) /* 0x3712000A */ #define PR_ATTACH_CONTENT_ID_UNICODE PROP_TAG(PT_UNICODE , 0x3712) /* 0x3712001F */ #define PR_ATTACH_CONTENT_LOCATION PROP_TAG(PT_STRING8 , 0x3713) /* 0x3713001E */ #define PR_ATTACH_CONTENT_LOCATION_ERROR PROP_TAG(PT_ERROR , 0x3713) /* 0x3713000A */ #define PR_ATTACH_CONTENT_LOCATION_UNICODE PROP_TAG(PT_UNICODE , 0x3713) /* 0x3713001F */ #define PR_ATTACH_DATA_BIN PidTagAttachDataBinary #define PR_ATTACH_DATA_BIN_ERROR PROP_TAG(PT_ERROR , 0x3701) /* 0x3701000A */ #define PR_ATTACH_DATA_OBJ PidTagAttachDataObject #define PR_ATTACH_DATA_OBJ_ERROR PROP_TAG(PT_ERROR , 0x3701) /* 0x3701000A */ #define PR_ATTACH_ENCODING PidTagAttachEncoding #define PR_ATTACH_ENCODING_ERROR PROP_TAG(PT_ERROR , 0x3702) /* 0x3702000A */ #define PR_ATTACH_EXTENSION PROP_TAG(PT_STRING8 , 0x3703) /* 0x3703001E */ #define PR_ATTACH_EXTENSION_ERROR PROP_TAG(PT_ERROR , 0x3703) /* 0x3703000A */ #define PR_ATTACH_EXTENSION_UNICODE PROP_TAG(PT_UNICODE , 0x3703) /* 0x3703001F */ #define PR_ATTACH_FILENAME PROP_TAG(PT_STRING8 , 0x3704) /* 0x3704001E */ #define PR_ATTACH_FILENAME_ERROR PROP_TAG(PT_ERROR , 0x3704) /* 0x3704000A */ #define PR_ATTACH_FILENAME_UNICODE PROP_TAG(PT_UNICODE , 0x3704) /* 0x3704001F */ #define PR_ATTACH_FLAGS PidTagAttachFlags #define PR_ATTACH_FLAGS_ERROR PROP_TAG(PT_ERROR , 0x3714) /* 0x3714000A */ #define PR_ATTACH_LONG_FILENAME PROP_TAG(PT_STRING8 , 0x3707) /* 0x3707001E */ #define PR_ATTACH_LONG_FILENAME_ERROR PROP_TAG(PT_ERROR , 0x3707) /* 0x3707000A */ #define PR_ATTACH_LONG_FILENAME_UNICODE PROP_TAG(PT_UNICODE , 0x3707) /* 0x3707001F */ #define PR_ATTACH_LONG_PATHNAME PROP_TAG(PT_STRING8 , 0x370D) /* 0x370D001E */ #define PR_ATTACH_LONG_PATHNAME_ERROR PROP_TAG(PT_ERROR , 0x370D) /* 0x370D000A */ #define PR_ATTACH_LONG_PATHNAME_UNICODE PROP_TAG(PT_UNICODE , 0x370D) /* 0x370D001F */ #define PR_ATTACH_METHOD PidTagAttachMethod #define PR_ATTACH_METHOD_ERROR PROP_TAG(PT_ERROR , 0x3705) /* 0x3705000A */ #define PR_ATTACH_MIME_TAG PROP_TAG(PT_STRING8 , 0x370E) /* 0x370E001E */ #define PR_ATTACH_MIME_TAG_ERROR PROP_TAG(PT_ERROR , 0x370E) /* 0x370E000A */ #define PR_ATTACH_MIME_TAG_UNICODE PROP_TAG(PT_UNICODE , 0x370E) /* 0x370E001F */ #define PR_ATTACH_NUM PidTagAttachNumber #define PR_ATTACH_NUM_ERROR PROP_TAG(PT_ERROR , 0x0E21) /* 0x0E21000A */ #define PR_ATTACH_PATHNAME PROP_TAG(PT_STRING8 , 0x3708) /* 0x3708001E */ #define PR_ATTACH_PATHNAME_ERROR PROP_TAG(PT_ERROR , 0x3708) /* 0x3708000A */ #define PR_ATTACH_PATHNAME_UNICODE PROP_TAG(PT_UNICODE , 0x3708) /* 0x3708001F */ #define PR_ATTACH_PAYLOAD_CLASS PROP_TAG(PT_STRING8 , 0x371A) /* 0x371A001E */ #define PR_ATTACH_PAYLOAD_CLASS_ERROR PROP_TAG(PT_ERROR , 0x371A) /* 0x371A000A */ #define PR_ATTACH_PAYLOAD_CLASS_UNICODE PROP_TAG(PT_UNICODE , 0x371A) /* 0x371A001F */ #define PR_ATTACH_PAYLOAD_PROV_GUID_STR PROP_TAG(PT_STRING8 , 0x3719) /* 0x3719001E */ #define PR_ATTACH_PAYLOAD_PROV_GUID_STR_ERROR PROP_TAG(PT_ERROR , 0x3719) /* 0x3719000A */ #define PR_ATTACH_PAYLOAD_PROV_GUID_STR_UNICODE PROP_TAG(PT_UNICODE , 0x3719) /* 0x3719001F */ #define PR_ATTACH_RENDERING PidTagAttachRendering #define PR_ATTACH_RENDERING_ERROR PROP_TAG(PT_ERROR , 0x3709) /* 0x3709000A */ #define PR_ATTACH_SIZE PidTagAttachSize #define PR_ATTACH_SIZE_ERROR PROP_TAG(PT_ERROR , 0x0E20) /* 0x0E20000A */ #define PR_ATTACH_TAG PidTagAttachTag #define PR_ATTACH_TAG_ERROR PROP_TAG(PT_ERROR , 0x370A) /* 0x370A000A */ #define PR_ATTACH_TRANSPORT_NAME PROP_TAG(PT_STRING8 , 0x370C) /* 0x370C001E */ #define PR_ATTACH_TRANSPORT_NAME_ERROR PROP_TAG(PT_ERROR , 0x370C) /* 0x370C000A */ #define PR_ATTACH_TRANSPORT_NAME_UNICODE PROP_TAG(PT_UNICODE , 0x370C) /* 0x370C001F */ #define PR_ATTR_HIDDEN PidTagAttributeHidden #define PR_ATTR_HIDDEN_ERROR PROP_TAG(PT_ERROR , 0x10F4) /* 0x10F4000A */ #define PR_ATTR_READONLY PidTagAttributeReadOnly #define PR_ATTR_READONLY_ERROR PROP_TAG(PT_ERROR , 0x10F6) /* 0x10F6000A */ #define PR_ATTR_SYSTEM PidTagAttributeSystem #define PR_ATTR_SYSTEM_ERROR PROP_TAG(PT_ERROR , 0x10F5) /* 0x10F5000A */ #define PR_AUTO_FORWARDED PidTagAutoForwarded #define PR_AUTO_FORWARDED_ERROR PROP_TAG(PT_ERROR , 0x0005) /* 0x0005000A */ #define PR_AUTO_FORWARD_COMMENT PROP_TAG(PT_STRING8 , 0x0004) /* 0x0004001E */ #define PR_AUTO_FORWARD_COMMENT_ERROR PROP_TAG(PT_ERROR , 0x0004) /* 0x0004000A */ #define PR_AUTO_FORWARD_COMMENT_UNICODE PROP_TAG(PT_UNICODE , 0x0004) /* 0x0004001F */ #define PR_AUTO_RESPONSE_SUPPRESS PidTagAutoResponseSuppress #define PR_AUTO_RESPONSE_SUPPRESS_ERROR PROP_TAG(PT_ERROR , 0x3FDF) /* 0x3FDF000A */ #define PR_BIRTHDAY PidTagBirthday #define PR_BIRTHDAY_ERROR PROP_TAG(PT_ERROR , 0x3A42) /* 0x3A42000A */ #define PR_BLOCK_STATUS PidTagBlockStatus #define PR_BLOCK_STATUS_ERROR PROP_TAG(PT_ERROR , 0x1096) /* 0x1096000A */ #define PR_BODY PROP_TAG(PT_STRING8 , 0x1000) /* 0x1000001E */ #define PR_BODY_CONTENT_ID PROP_TAG(PT_STRING8 , 0x1015) /* 0x1015001E */ #define PR_BODY_CONTENT_ID_ERROR PROP_TAG(PT_ERROR , 0x1015) /* 0x1015000A */ #define PR_BODY_CONTENT_ID_UNICODE PROP_TAG(PT_UNICODE , 0x1015) /* 0x1015001F */ #define PR_BODY_CONTENT_LOCATION PROP_TAG(PT_STRING8 , 0x1014) /* 0x1014001E */ #define PR_BODY_CONTENT_LOCATION_ERROR PROP_TAG(PT_ERROR , 0x1014) /* 0x1014000A */ #define PR_BODY_CONTENT_LOCATION_UNICODE PROP_TAG(PT_UNICODE , 0x1014) /* 0x1014001F */ #define PR_BODY_ERROR PROP_TAG(PT_ERROR , 0x1000) /* 0x1000000A */ #define PR_BODY_HTML PROP_TAG(PT_STRING8 , 0x1013) /* 0x1013001E */ #define PR_BODY_HTML_ERROR PROP_TAG(PT_ERROR , 0x1013) /* 0x1013000A */ #define PR_BODY_HTML_UNICODE PROP_TAG(PT_UNICODE , 0x1013) /* 0x1013001F */ #define PR_BODY_UNICODE PROP_TAG(PT_UNICODE , 0x1000) /* 0x1000001F */ #define PR_BUSINESS2_TELEPHONE_NUMBER_A_MV PROP_TAG(PT_MV_STRING8, 0x3A1B) /* 0x3A1B101E */ #define PR_BUSINESS2_TELEPHONE_NUMBER_A_MV_ERROR PROP_TAG(PT_ERROR , 0x3A1B) /* 0x3A1B000A */ #define PR_BUSINESS2_TELEPHONE_NUMBER_A_MV_UNICODE PROP_TAG(PT_MV_UNICODE, 0x3A1B) /* 0x3A1B101F */ #define PR_BUSINESS_ADDRESS_COUNTRY PROP_TAG(PT_STRING8 , 0x3A26) /* 0x3A26001E */ #define PR_BUSINESS_ADDRESS_COUNTRY_ERROR PROP_TAG(PT_ERROR , 0x3A26) /* 0x3A26000A */ #define PR_BUSINESS_ADDRESS_COUNTRY_UNICODE PROP_TAG(PT_UNICODE , 0x3A26) /* 0x3A26001F */ #define PR_BUSINESS_ADDRESS_LOCALITY PROP_TAG(PT_STRING8 , 0x3A27) /* 0x3A27001E */ #define PR_BUSINESS_ADDRESS_LOCALITY_ERROR PROP_TAG(PT_ERROR , 0x3A27) /* 0x3A27000A */ #define PR_BUSINESS_ADDRESS_LOCALITY_UNICODE PROP_TAG(PT_UNICODE , 0x3A27) /* 0x3A27001F */ #define PR_BUSINESS_ADDRESS_POSTAL_CODE PROP_TAG(PT_STRING8 , 0x3A2A) /* 0x3A2A001E */ #define PR_BUSINESS_ADDRESS_POSTAL_CODE_ERROR PROP_TAG(PT_ERROR , 0x3A2A) /* 0x3A2A000A */ #define PR_BUSINESS_ADDRESS_POSTAL_CODE_UNICODE PROP_TAG(PT_UNICODE , 0x3A2A) /* 0x3A2A001F */ #define PR_BUSINESS_ADDRESS_POST_OFFICE_BOX PROP_TAG(PT_STRING8 , 0x3A2B) /* 0x3A2B001E */ #define PR_BUSINESS_ADDRESS_POST_OFFICE_BOX_ERROR PROP_TAG(PT_ERROR , 0x3A2B) /* 0x3A2B000A */ #define PR_BUSINESS_ADDRESS_POST_OFFICE_BOX_UNICODE PROP_TAG(PT_UNICODE , 0x3A2B) /* 0x3A2B001F */ #define PR_BUSINESS_ADDRESS_STATE_OR_PROVINCE PROP_TAG(PT_STRING8 , 0x3A28) /* 0x3A28001E */ #define PR_BUSINESS_ADDRESS_STATE_OR_PROVINCE_ERROR PROP_TAG(PT_ERROR , 0x3A28) /* 0x3A28000A */ #define PR_BUSINESS_ADDRESS_STATE_OR_PROVINCE_UNICODE PROP_TAG(PT_UNICODE , 0x3A28) /* 0x3A28001F */ #define PR_BUSINESS_ADDRESS_STREET PROP_TAG(PT_STRING8 , 0x3A29) /* 0x3A29001E */ #define PR_BUSINESS_ADDRESS_STREET_ERROR PROP_TAG(PT_ERROR , 0x3A29) /* 0x3A29000A */ #define PR_BUSINESS_ADDRESS_STREET_UNICODE PROP_TAG(PT_UNICODE , 0x3A29) /* 0x3A29001F */ #define PR_BUSINESS_FAX_NUMBER PROP_TAG(PT_STRING8 , 0x3A24) /* 0x3A24001E */ #define PR_BUSINESS_FAX_NUMBER_ERROR PROP_TAG(PT_ERROR , 0x3A24) /* 0x3A24000A */ #define PR_BUSINESS_FAX_NUMBER_UNICODE PROP_TAG(PT_UNICODE , 0x3A24) /* 0x3A24001F */ #define PR_BUSINESS_HOME_PAGE PROP_TAG(PT_STRING8 , 0x3A51) /* 0x3A51001E */ #define PR_BUSINESS_HOME_PAGE_ERROR PROP_TAG(PT_ERROR , 0x3A51) /* 0x3A51000A */ #define PR_BUSINESS_HOME_PAGE_UNICODE PROP_TAG(PT_UNICODE , 0x3A51) /* 0x3A51001F */ #define PR_BUSINESS_TELEPHONE_NUMBER PROP_TAG(PT_STRING8 , 0x3A08) /* 0x3A08001E */ #define PR_BUSINESS_TELEPHONE_NUMBER_ERROR PROP_TAG(PT_ERROR , 0x3A08) /* 0x3A08000A */ #define PR_BUSINESS_TELEPHONE_NUMBER_UNICODE PROP_TAG(PT_UNICODE , 0x3A08) /* 0x3A08001F */ #define PR_CALLBACK_TELEPHONE_NUMBER PROP_TAG(PT_STRING8 , 0x3A02) /* 0x3A02001E */ #define PR_CALLBACK_TELEPHONE_NUMBER_ERROR PROP_TAG(PT_ERROR , 0x3A02) /* 0x3A02000A */ #define PR_CALLBACK_TELEPHONE_NUMBER_UNICODE PROP_TAG(PT_UNICODE , 0x3A02) /* 0x3A02001F */ #define PR_CAR_TELEPHONE_NUMBER PROP_TAG(PT_STRING8 , 0x3A1E) /* 0x3A1E001E */ #define PR_CAR_TELEPHONE_NUMBER_ERROR PROP_TAG(PT_ERROR , 0x3A1E) /* 0x3A1E000A */ #define PR_CAR_TELEPHONE_NUMBER_UNICODE PROP_TAG(PT_UNICODE , 0x3A1E) /* 0x3A1E001F */ #define PR_CDO_RECURRENCEID PidTagCdoRecurrenceid #define PR_CDO_RECURRENCEID_ERROR PROP_TAG(PT_ERROR , 0x10C5) /* 0x10C5000A */ #define PR_CHANGE_KEY PidTagChangeKey #define PR_CHANGE_KEY_ERROR PROP_TAG(PT_ERROR , 0x65E2) /* 0x65E2000A */ #define PR_CHANGE_NOTIFICATION_GUID PidTagChangeNotificationGuid #define PR_CHANGE_NOTIFICATION_GUID_ERROR PROP_TAG(PT_ERROR , 0x6637) /* 0x6637000A */ #define PR_CHILDRENS_NAMES PROP_TAG(PT_MV_STRING8, 0x3A58) /* 0x3A58101E */ #define PR_CHILDRENS_NAMES_ERROR PROP_TAG(PT_ERROR , 0x3A58) /* 0x3A58000A */ #define PR_CHILDRENS_NAMES_UNICODE PROP_TAG(PT_MV_UNICODE, 0x3A58) /* 0x3A58101F */ #define PR_CLIENT_ACTIONS PidTagClientActions #define PR_CLIENT_ACTIONS_ERROR PROP_TAG(PT_ERROR , 0x6645) /* 0x6645000A */ #define PR_CLIENT_SUBMIT_TIME PidTagClientSubmitTime #define PR_CLIENT_SUBMIT_TIME_ERROR PROP_TAG(PT_ERROR , 0x0039) /* 0x0039000A */ #define PR_CODE_PAGE_ID PidTagCodePageId #define PR_CODE_PAGE_ID_ERROR PROP_TAG(PT_ERROR , 0x66C3) /* 0x66C3000A */ #define PR_COMMENT PROP_TAG(PT_STRING8 , 0x3004) /* 0x3004001E */ #define PR_COMMENT_ERROR PROP_TAG(PT_ERROR , 0x3004) /* 0x3004000A */ #define PR_COMMENT_UNICODE PROP_TAG(PT_UNICODE , 0x3004) /* 0x3004001F */ #define PR_COMPANY_MAIN_PHONE_NUMBER PROP_TAG(PT_STRING8 , 0x3A57) /* 0x3A57001E */ #define PR_COMPANY_MAIN_PHONE_NUMBER_ERROR PROP_TAG(PT_ERROR , 0x3A57) /* 0x3A57000A */ #define PR_COMPANY_MAIN_PHONE_NUMBER_UNICODE PROP_TAG(PT_UNICODE , 0x3A57) /* 0x3A57001F */ #define PR_COMPANY_NAME PROP_TAG(PT_STRING8 , 0x3A16) /* 0x3A16001E */ #define PR_COMPANY_NAME_ERROR PROP_TAG(PT_ERROR , 0x3A16) /* 0x3A16000A */ #define PR_COMPANY_NAME_UNICODE PROP_TAG(PT_UNICODE , 0x3A16) /* 0x3A16001F */ #define PR_COMPUTER_NETWORK_NAME PROP_TAG(PT_STRING8 , 0x3A49) /* 0x3A49001E */ #define PR_COMPUTER_NETWORK_NAME_ERROR PROP_TAG(PT_ERROR , 0x3A49) /* 0x3A49000A */ #define PR_COMPUTER_NETWORK_NAME_UNICODE PROP_TAG(PT_UNICODE , 0x3A49) /* 0x3A49001F */ #define PR_CONFLICT_ENTRYID PidTagConflictEntryId #define PR_CONFLICT_ENTRYID_ERROR PROP_TAG(PT_ERROR , 0x3FF0) /* 0x3FF0000A */ #define PR_CONFLICT_ITEMS PidTagConflictItems #define PR_CONFLICT_ITEMS_ERROR PROP_TAG(PT_ERROR , 0x1098) /* 0x1098000A */ #define PR_CONTAINER_CLASS PROP_TAG(PT_STRING8 , 0x3613) /* 0x3613001E */ #define PR_CONTAINER_CLASS_ERROR PROP_TAG(PT_ERROR , 0x3613) /* 0x3613000A */ #define PR_CONTAINER_CLASS_UNICODE PROP_TAG(PT_UNICODE , 0x3613) /* 0x3613001F */ #define PR_CONTAINER_CONTENTS PidTagContainerContents #define PR_CONTAINER_CONTENTS_ERROR PROP_TAG(PT_ERROR , 0x360F) /* 0x360F000A */ #define PR_CONTAINER_FLAGS PidTagContainerFlags #define PR_CONTAINER_FLAGS_ERROR PROP_TAG(PT_ERROR , 0x3600) /* 0x3600000A */ #define PR_CONTAINER_HIERARCHY PidTagContainerHierarchy #define PR_CONTAINER_HIERARCHY_ERROR PROP_TAG(PT_ERROR , 0x360E) /* 0x360E000A */ #define PR_CONTENT_COUNT PidTagContentCount #define PR_CONTENT_COUNT_ERROR PROP_TAG(PT_ERROR , 0x3602) /* 0x3602000A */ #define PR_CONTENT_FILTER_PCL PidTagContentFilterPhishingConfidenceLevel #define PR_CONTENT_FILTER_PCL_ERROR PROP_TAG(PT_ERROR , 0x4084) /* 0x4084000A */ #define PR_CONTENT_FILTER_SCL PidTagContentFilterSpamConfidenceLevel #define PR_CONTENT_FILTER_SCL_ERROR PROP_TAG(PT_ERROR , 0x4076) /* 0x4076000A */ #define PR_CONTENT_UNREAD PidTagContentUnreadCount #define PR_CONTENT_UNREAD_ERROR PROP_TAG(PT_ERROR , 0x3603) /* 0x3603000A */ #define PR_CONVERSATION_ID PidTagConversationId #define PR_CONVERSATION_ID_ERROR PROP_TAG(PT_ERROR , 0x3013) /* 0x3013000A */ #define PR_CONVERSATION_INDEX PidTagConversationIndex #define PR_CONVERSATION_INDEX_ERROR PROP_TAG(PT_ERROR , 0x0071) /* 0x0071000A */ #define PR_CONVERSATION_INDEX_TRACKING PidTagConversationIndexTracking #define PR_CONVERSATION_INDEX_TRACKING_ERROR PROP_TAG(PT_ERROR , 0x3016) /* 0x3016000A */ #define PR_CONVERSATION_KEY PidTagConversationKey #define PR_CONVERSATION_TOPIC PROP_TAG(PT_STRING8 , 0x0070) /* 0x0070001E */ #define PR_CONVERSATION_TOPIC_ERROR PROP_TAG(PT_ERROR , 0x0070) /* 0x0070000A */ #define PR_CONVERSATION_TOPIC_UNICODE PROP_TAG(PT_UNICODE , 0x0070) /* 0x0070001F */ #define PR_COUNTRY PROP_TAG(PT_STRING8 , 0x3A26) /* 0x3A26001E */ #define PR_COUNTRY_ERROR PROP_TAG(PT_ERROR , 0x3A26) /* 0x3A26000A */ #define PR_COUNTRY_UNICODE PROP_TAG(PT_UNICODE , 0x3A26) /* 0x3A26001F */ #define PR_CREATION_TIME PidTagCreationTime #define PR_CREATION_TIME_ERROR PROP_TAG(PT_ERROR , 0x3007) /* 0x3007000A */ #define PR_CREATOR_ENTRYID PidTagCreatorEntryId #define PR_CREATOR_ENTRYID_ERROR PROP_TAG(PT_ERROR , 0x3FF9) /* 0x3FF9000A */ #define PR_CREATOR_NAME PROP_TAG(PT_STRING8 , 0x3FF8) /* 0x3FF8001E */ #define PR_CREATOR_NAME_ERROR PROP_TAG(PT_ERROR , 0x3FF8) /* 0x3FF8000A */ #define PR_CREATOR_NAME_UNICODE PROP_TAG(PT_UNICODE , 0x3FF8) /* 0x3FF8001F */ #define PR_CREATOR_SID 0x0E580102 #define PR_CUSTOMER_ID PROP_TAG(PT_STRING8 , 0x3A4A) /* 0x3A4A001E */ #define PR_CUSTOMER_ID_ERROR PROP_TAG(PT_ERROR , 0x3A4A) /* 0x3A4A000A */ #define PR_CUSTOMER_ID_UNICODE PROP_TAG(PT_UNICODE , 0x3A4A) /* 0x3A4A001F */ #define PR_DAM_BACK_PATCHED PidTagDamBackPatched #define PR_DAM_BACK_PATCHED_ERROR PROP_TAG(PT_ERROR , 0x6647) /* 0x6647000A */ #define PR_DAM_ORIGINAL_ENTRYID PidTagDamOriginalEntryId #define PR_DAM_ORIGINAL_ENTRYID_ERROR PROP_TAG(PT_ERROR , 0x6646) /* 0x6646000A */ #define PR_DAM_ORIG_MSG_SVREID PidTagDeferredActionMessageOriginalEntryId #define PR_DAM_ORIG_MSG_SVREID_ERROR PROP_TAG(PT_ERROR , 0x6741) /* 0x6741000A */ #define PR_DEFAULT_PROFILE 0x00010102 #define PR_DEFERRED_DELIVERY_TIME PidTagDeferredDeliveryTime #define PR_DEFERRED_DELIVERY_TIME_ERROR PROP_TAG(PT_ERROR , 0x000F) /* 0x000F000A */ #define PR_DEFERRED_SEND_NUMBER PidTagDeferredSendNumber #define PR_DEFERRED_SEND_NUMBER_ERROR PROP_TAG(PT_ERROR , 0x3FEB) /* 0x3FEB000A */ #define PR_DEFERRED_SEND_TIME PidTagDeferredSendTime #define PR_DEFERRED_SEND_TIME_ERROR PROP_TAG(PT_ERROR , 0x3FEF) /* 0x3FEF000A */ #define PR_DEFERRED_SEND_UNITS PidTagDeferredSendUnits #define PR_DEFERRED_SEND_UNITS_ERROR PROP_TAG(PT_ERROR , 0x3FEC) /* 0x3FEC000A */ #define PR_DEF_POST_MSGCLASS PROP_TAG(PT_STRING8 , 0x36E5) /* 0x36E5001E */ #define PR_DEF_POST_MSGCLASS_ERROR PROP_TAG(PT_ERROR , 0x36E5) /* 0x36E5000A */ #define PR_DEF_POST_MSGCLASS_UNICODE PROP_TAG(PT_UNICODE , 0x36E5) /* 0x36E5001F */ #define PR_DELEGATED_BY_RULE PidTagDelegatedByRule #define PR_DELEGATED_BY_RULE_ERROR PROP_TAG(PT_ERROR , 0x3FE3) /* 0x3FE3000A */ #define PR_DELEGATE_FLAGS PidTagDelegateFlags #define PR_DELEGATE_FLAGS_ERROR PROP_TAG(PT_ERROR , 0x686B) /* 0x686B000A */ #define PR_DELETED_COUNT_TOTAL 0x670B0003 #define PR_DELETED_MSG_COUNT 0x66400003 #define PR_DELETED_ON PidTagDeletedOn #define PR_DELETED_ON_ERROR PROP_TAG(PT_ERROR , 0x668F) /* 0x668F000A */ #define PR_DELETE_AFTER_SUBMIT PidTagDeleteAfterSubmit #define PR_DELETE_AFTER_SUBMIT_ERROR PROP_TAG(PT_ERROR , 0x0E01) /* 0x0E01000A */ #define PR_DEPARTMENT_NAME PROP_TAG(PT_STRING8 , 0x3A18) /* 0x3A18001E */ #define PR_DEPARTMENT_NAME_ERROR PROP_TAG(PT_ERROR , 0x3A18) /* 0x3A18000A */ #define PR_DEPARTMENT_NAME_UNICODE PROP_TAG(PT_UNICODE , 0x3A18) /* 0x3A18001F */ #define PR_DEPTH PidTagDepth #define PR_DEPTH_ERROR PROP_TAG(PT_ERROR , 0x3005) /* 0x3005000A */ #define PR_DISPLAY_BCC PROP_TAG(PT_STRING8 , 0x0E02) /* 0x0E02001E */ #define PR_DISPLAY_BCC_ERROR PROP_TAG(PT_ERROR , 0x0E02) /* 0x0E02000A */ #define PR_DISPLAY_BCC_UNICODE PROP_TAG(PT_UNICODE , 0x0E02) /* 0x0E02001F */ #define PR_DISPLAY_CC PROP_TAG(PT_STRING8 , 0x0E03) /* 0x0E03001E */ #define PR_DISPLAY_CC_ERROR PROP_TAG(PT_ERROR , 0x0E03) /* 0x0E03000A */ #define PR_DISPLAY_CC_UNICODE PROP_TAG(PT_UNICODE , 0x0E03) /* 0x0E03001F */ #define PR_DISPLAY_NAME PROP_TAG(PT_STRING8 , 0x3001) /* 0x3001001E */ #define PR_DISPLAY_NAME_ERROR PROP_TAG(PT_ERROR , 0x3001) /* 0x3001000A */ #define PR_DISPLAY_NAME_PREFIX PROP_TAG(PT_STRING8 , 0x3A45) /* 0x3A45001E */ #define PR_DISPLAY_NAME_PREFIX_ERROR PROP_TAG(PT_ERROR , 0x3A45) /* 0x3A45000A */ #define PR_DISPLAY_NAME_PREFIX_UNICODE PROP_TAG(PT_UNICODE , 0x3A45) /* 0x3A45001F */ #define PR_DISPLAY_NAME_UNICODE PROP_TAG(PT_UNICODE , 0x3001) /* 0x3001001F */ #define PR_DISPLAY_TO PROP_TAG(PT_STRING8 , 0x0E04) /* 0x0E04001E */ #define PR_DISPLAY_TO_ERROR PROP_TAG(PT_ERROR , 0x0E04) /* 0x0E04000A */ #define PR_DISPLAY_TO_UNICODE PROP_TAG(PT_UNICODE , 0x0E04) /* 0x0E04001F */ #define PR_DISPLAY_TYPE PidTagDisplayType #define PR_DISPLAY_TYPE_ERROR PROP_TAG(PT_ERROR , 0x3900) /* 0x3900000A */ #define PR_DISPLAY_TYPE_EX PidTagDisplayTypeEx #define PR_DISPLAY_TYPE_EX_ERROR PROP_TAG(PT_ERROR , 0x3905) /* 0x3905000A */ #define PR_DSN_REMOTE_MTA PROP_TAG(PT_STRING8 , 0x0C21) /* 0x0C21001E */ #define PR_DSN_REMOTE_MTA_ERROR PROP_TAG(PT_ERROR , 0x0C21) /* 0x0C21000A */ #define PR_DSN_REMOTE_MTA_UNICODE PROP_TAG(PT_UNICODE , 0x0C21) /* 0x0C21001F */ #define PR_EMAIL_ADDRESS PROP_TAG(PT_STRING8 , 0x3003) /* 0x3003001E */ #define PR_EMAIL_ADDRESS_ERROR PROP_TAG(PT_ERROR , 0x3003) /* 0x3003000A */ #define PR_EMAIL_ADDRESS_UNICODE PROP_TAG(PT_UNICODE , 0x3003) /* 0x3003001F */ #define PR_EMS_AB_ASSOC_NT_ACCOUNT 0x80270102 #define PR_EMS_AB_AUTH_ORIG PidTagAddressBookAuthorizedSenders #define PR_EMS_AB_AUTH_ORIG_ERROR PROP_TAG(PT_ERROR , 0x8CD8) /* 0x8CD8000A */ #define PR_EMS_AB_CONTAINERID PidTagAddressBookContainerId #define PR_EMS_AB_CONTAINERID_ERROR PROP_TAG(PT_ERROR , 0xFFFD) /* 0xFFFD000A */ #define PR_EMS_AB_DELIV_CONT_LENGTH PidTagAddressBookDeliveryContentLength #define PR_EMS_AB_DELIV_CONT_LENGTH_ERROR PROP_TAG(PT_ERROR , 0x806A) /* 0x806A000A */ #define PR_EMS_AB_DISPLAY_NAME_PRINTABLE PROP_TAG(PT_STRING8 , 0x39FF) /* 0x39FF001E */ #define PR_EMS_AB_DISPLAY_NAME_PRINTABLE_ERROR PROP_TAG(PT_ERROR , 0x39FF) /* 0x39FF000A */ #define PR_EMS_AB_DISPLAY_NAME_PRINTABLE_UNICODE PROP_TAG(PT_UNICODE , 0x39FF) /* 0x39FF001F */ #define PR_EMS_AB_DISPLAY_TYPE_EX PidTagAddressBookDisplayTypeExtended #define PR_EMS_AB_DISPLAY_TYPE_EX_ERROR PROP_TAG(PT_ERROR , 0x8C93) /* 0x8C93000A */ #define PR_EMS_AB_DL_EXTERNAL_MEMBER_COUNT PidTagAddressBookDistributionListExternalMemberCount #define PR_EMS_AB_DL_EXTERNAL_MEMBER_COUNT_ERROR PROP_TAG(PT_ERROR , 0x8CE3) /* 0x8CE3000A */ #define PR_EMS_AB_DL_TOTAL_MEMBER_COUNT PidTagAddressBookDistributionListMemberCount #define PR_EMS_AB_DL_TOTAL_MEMBER_COUNT_ERROR PROP_TAG(PT_ERROR , 0x8CE2) /* 0x8CE2000A */ #define PR_EMS_AB_ENABLE_MODERATION PidTagAddressBookModerationEnabled #define PR_EMS_AB_ENABLE_MODERATION_ERROR PROP_TAG(PT_ERROR , 0x8CB5) /* 0x8CB5000A */ #define PR_EMS_AB_EXTENSION_ATTRIBUTE_1 PROP_TAG(PT_STRING8 , 0x802D) /* 0x802D001E */ #define PR_EMS_AB_EXTENSION_ATTRIBUTE_15 PROP_TAG(PT_STRING8 , 0x8C61) /* 0x8C61001E */ #define PR_EMS_AB_EXTENSION_ATTRIBUTE_15_ERROR PROP_TAG(PT_ERROR , 0x8C61) /* 0x8C61000A */ #define PR_EMS_AB_EXTENSION_ATTRIBUTE_15_UNICODE PROP_TAG(PT_UNICODE , 0x8C61) /* 0x8C61001F */ #define PR_EMS_AB_EXTENSION_ATTRIBUTE_1_ERROR PROP_TAG(PT_ERROR , 0x802D) /* 0x802D000A */ #define PR_EMS_AB_EXTENSION_ATTRIBUTE_1_UNICODE PROP_TAG(PT_UNICODE , 0x802D) /* 0x802D001F */ #define PR_EMS_AB_FOLDER_PATHNAME PROP_TAG(PT_STRING8 , 0x8004) /* 0x8004001E */ #define PR_EMS_AB_FOLDER_PATHNAME_ERROR PROP_TAG(PT_ERROR , 0x8004) /* 0x8004000A */ #define PR_EMS_AB_FOLDER_PATHNAME_UNICODE PROP_TAG(PT_UNICODE , 0x8004) /* 0x8004001F */ #define PR_EMS_AB_HAB_CHILD_DEPARTMENTS PidTagAddressBookHierarchicalChildDepartments #define PR_EMS_AB_HAB_CHILD_DEPARTMENTS_ERROR PROP_TAG(PT_ERROR , 0x8C9A) /* 0x8C9A000A */ #define PR_EMS_AB_HAB_DEPARTMENT_MEMBERS PidTagAddressBookHierarchicalDepartmentMembers #define PR_EMS_AB_HAB_DEPARTMENT_MEMBERS_ERROR PROP_TAG(PT_ERROR , 0x8C97) /* 0x8C97000A */ #define PR_EMS_AB_HAB_IS_HIERARCHICAL_GROUP PidTagAddressBookHierarchicalIsHierarchicalGroup #define PR_EMS_AB_HAB_IS_HIERARCHICAL_GROUP_ERROR PROP_TAG(PT_ERROR , 0x8CDD) /* 0x8CDD000A */ #define PR_EMS_AB_HAB_PARENT_DEPARTMENT PidTagAddressBookHierarchicalParentDepartment #define PR_EMS_AB_HAB_PARENT_DEPARTMENT_ERROR PROP_TAG(PT_ERROR , 0x8C99) /* 0x8C99000A */ #define PR_EMS_AB_HAB_ROOT_DEPARTMENT PidTagAddressBookHierarchicalRootDepartment #define PR_EMS_AB_HAB_ROOT_DEPARTMENT_ERROR PROP_TAG(PT_ERROR , 0x8C98) /* 0x8C98000A */ #define PR_EMS_AB_HAB_SENIORITY_INDEX PidTagAddressBookSeniorityIndex #define PR_EMS_AB_HAB_SENIORITY_INDEX_ERROR PROP_TAG(PT_ERROR , 0x8CA0) /* 0x8CA0000A */ #define PR_EMS_AB_HAB_SHOW_IN_DEPARTMENTS PidTagAddressBookHierarchicalShowInDepartments #define PR_EMS_AB_HAB_SHOW_IN_DEPARTMENTS_ERROR PROP_TAG(PT_ERROR , 0x8C94) /* 0x8C94000A */ #define PR_EMS_AB_HOME_MDB PidTagAddressBookHomeMessageDatabase #define PR_EMS_AB_HOME_MDB_ERROR PROP_TAG(PT_ERROR , 0x8006) /* 0x8006000A */ #define PR_EMS_AB_HOME_MTA 0x8007001F #define PR_EMS_AB_IS_MASTER PidTagAddressBookIsMaster #define PR_EMS_AB_IS_MASTER_ERROR PROP_TAG(PT_ERROR , 0xFFFB) /* 0xFFFB000A */ #define PR_EMS_AB_IS_MEMBER_OF_DL PidTagAddressBookIsMemberOfDistributionList #define PR_EMS_AB_IS_MEMBER_OF_DL_ERROR PROP_TAG(PT_ERROR , 0x8008) /* 0x8008000A */ #define PR_EMS_AB_IS_ORGANIZATIONAL PidTagAddressBookHierarchicalIsHierarchicalGroup #define PR_EMS_AB_IS_ORGANIZATIONAL_ERROR PROP_TAG(PT_ERROR , 0x8CDD) /* 0x8CDD000A */ #define PR_EMS_AB_MANAGER PidTagAddressBookManager #define PR_EMS_AB_MANAGER_ERROR PROP_TAG(PT_ERROR , 0x8005) /* 0x8005000A */ #define PR_EMS_AB_MANAGER_T PROP_TAG(PT_STRING8 , 0x8005) /* 0x8005001E */ #define PR_EMS_AB_MANAGER_T_ERROR PROP_TAG(PT_ERROR , 0x8005) /* 0x8005000A */ #define PR_EMS_AB_MANAGER_T_UNICODE PROP_TAG(PT_UNICODE , 0x8005) /* 0x8005001F */ #define PR_EMS_AB_MANAGE_DL PidTagAddressBookManageDistributionList #define PR_EMS_AB_MANAGE_DL_ERROR PROP_TAG(PT_ERROR , 0x6704) /* 0x6704000A */ #define PR_EMS_AB_MEMBER PidTagAddressBookMember #define PR_EMS_AB_MEMBER_ERROR PROP_TAG(PT_ERROR , 0x8009) /* 0x8009000A */ #define PR_EMS_AB_NETWORK_ADDRESS PROP_TAG(PT_MV_STRING8, 0x8170) /* 0x8170101E */ #define PR_EMS_AB_NETWORK_ADDRESS_ERROR PROP_TAG(PT_ERROR , 0x8170) /* 0x8170000A */ #define PR_EMS_AB_NETWORK_ADDRESS_UNICODE PROP_TAG(PT_MV_UNICODE, 0x8170) /* 0x8170101F */ #define PR_EMS_AB_OBJECT_GUID PidTagAddressBookObjectGuid #define PR_EMS_AB_OBJECT_GUID_ERROR PROP_TAG(PT_ERROR , 0x8C6D) /* 0x8C6D000A */ #define PR_EMS_AB_OBJ_DIST_NAME PROP_TAG(PT_STRING8 , 0x803C) /* 0x803C001E */ #define PR_EMS_AB_OBJ_DIST_NAME_ERROR PROP_TAG(PT_ERROR , 0x803C) /* 0x803C000A */ #define PR_EMS_AB_OBJ_DIST_NAME_UNICODE PROP_TAG(PT_UNICODE , 0x803C) /* 0x803C001F */ #define PR_EMS_AB_ORG_UNIT_ROOT_DN PROP_TAG(PT_STRING8 , 0x8CA8) /* 0x8CA8001E */ #define PR_EMS_AB_ORG_UNIT_ROOT_DN_ERROR PROP_TAG(PT_ERROR , 0x8CA8) /* 0x8CA8000A */ #define PR_EMS_AB_ORG_UNIT_ROOT_DN_UNICODE PROP_TAG(PT_UNICODE , 0x8CA8) /* 0x8CA8001F */ #define PR_EMS_AB_OWNER_BL_O PidTagAddressBookOwnerBackLink #define PR_EMS_AB_OWNER_BL_O_ERROR PROP_TAG(PT_ERROR , 0x8024) /* 0x8024000A */ #define PR_EMS_AB_OWNER_O PidTagAddressBookOwner #define PR_EMS_AB_OWNER_O_ERROR PROP_TAG(PT_ERROR , 0x800C) /* 0x800C000A */ #define PR_EMS_AB_PARENT_ENTRYID PidTagAddressBookParentEntryId #define PR_EMS_AB_PARENT_ENTRYID_ERROR PROP_TAG(PT_ERROR , 0xFFFC) /* 0xFFFC000A */ #define PR_EMS_AB_PHONETIC_COMPANY_NAME PROP_TAG(PT_STRING8 , 0x8C91) /* 0x8C91001E */ #define PR_EMS_AB_PHONETIC_COMPANY_NAME_ERROR PROP_TAG(PT_ERROR , 0x8C91) /* 0x8C91000A */ #define PR_EMS_AB_PHONETIC_COMPANY_NAME_UNICODE PROP_TAG(PT_UNICODE , 0x8C91) /* 0x8C91001F */ #define PR_EMS_AB_PHONETIC_DEPARTMENT_NAME PROP_TAG(PT_STRING8 , 0x8C90) /* 0x8C90001E */ #define PR_EMS_AB_PHONETIC_DEPARTMENT_NAME_ERROR PROP_TAG(PT_ERROR , 0x8C90) /* 0x8C90000A */ #define PR_EMS_AB_PHONETIC_DEPARTMENT_NAME_UNICODE PROP_TAG(PT_UNICODE , 0x8C90) /* 0x8C90001F */ #define PR_EMS_AB_PHONETIC_DISPLAY_NAME PROP_TAG(PT_STRING8 , 0x8C92) /* 0x8C92001E */ #define PR_EMS_AB_PHONETIC_DISPLAY_NAME_ERROR PROP_TAG(PT_ERROR , 0x8C92) /* 0x8C92000A */ #define PR_EMS_AB_PHONETIC_DISPLAY_NAME_UNICODE PROP_TAG(PT_UNICODE , 0x8C92) /* 0x8C92001F */ #define PR_EMS_AB_PHONETIC_GIVEN_NAME PROP_TAG(PT_STRING8 , 0x8C8E) /* 0x8C8E001E */ #define PR_EMS_AB_PHONETIC_GIVEN_NAME_ERROR PROP_TAG(PT_ERROR , 0x8C8E) /* 0x8C8E000A */ #define PR_EMS_AB_PHONETIC_GIVEN_NAME_UNICODE PROP_TAG(PT_UNICODE , 0x8C8E) /* 0x8C8E001F */ #define PR_EMS_AB_PHONETIC_SURNAME PROP_TAG(PT_STRING8 , 0x8C8F) /* 0x8C8F001E */ #define PR_EMS_AB_PHONETIC_SURNAME_ERROR PROP_TAG(PT_ERROR , 0x8C8F) /* 0x8C8F000A */ #define PR_EMS_AB_PHONETIC_SURNAME_UNICODE PROP_TAG(PT_UNICODE , 0x8C8F) /* 0x8C8F001F */ #define PR_EMS_AB_PROXY_ADDRESSES PROP_TAG(PT_MV_STRING8, 0x800F) /* 0x800F101E */ #define PR_EMS_AB_PROXY_ADDRESSES_ERROR PROP_TAG(PT_ERROR , 0x800F) /* 0x800F000A */ #define PR_EMS_AB_PROXY_ADDRESSES_UNICODE PROP_TAG(PT_MV_UNICODE, 0x800F) /* 0x800F101F */ #define PR_EMS_AB_PUBLIC_DELEGATES PidTagAddressBookPublicDelegates #define PR_EMS_AB_PUBLIC_DELEGATES_ERROR PROP_TAG(PT_ERROR , 0x8015) /* 0x8015000A */ #define PR_EMS_AB_REPORTS PidTagAddressBookReports #define PR_EMS_AB_REPORTS_ERROR PROP_TAG(PT_ERROR , 0x800E) /* 0x800E000A */ #define PR_EMS_AB_ROOM_CAPACITY PidTagAddressBookRoomCapacity #define PR_EMS_AB_ROOM_CAPACITY_ERROR PROP_TAG(PT_ERROR , 0x0807) /* 0x0807000A */ #define PR_EMS_AB_ROOM_CONTAINERS PROP_TAG(PT_MV_STRING8, 0x8C96) /* 0x8C96101E */ #define PR_EMS_AB_ROOM_CONTAINERS_ERROR PROP_TAG(PT_ERROR , 0x8C96) /* 0x8C96000A */ #define PR_EMS_AB_ROOM_CONTAINERS_UNICODE PROP_TAG(PT_MV_UNICODE, 0x8C96) /* 0x8C96101F */ #define PR_EMS_AB_ROOM_DESCRIPTION PROP_TAG(PT_STRING8 , 0x0809) /* 0x0809001E */ #define PR_EMS_AB_ROOM_DESCRIPTION_ERROR PROP_TAG(PT_ERROR , 0x0809) /* 0x0809000A */ #define PR_EMS_AB_ROOM_DESCRIPTION_UNICODE PROP_TAG(PT_UNICODE , 0x0809) /* 0x0809001F */ #define PR_EMS_AB_SENIORITY_INDEX PidTagAddressBookSeniorityIndex #define PR_EMS_AB_SENIORITY_INDEX_ERROR PROP_TAG(PT_ERROR , 0x8CA0) /* 0x8CA0000A */ #define PR_EMS_AB_TARGET_ADDRESS PROP_TAG(PT_STRING8 , 0x8011) /* 0x8011001E */ #define PR_EMS_AB_TARGET_ADDRESS_ERROR PROP_TAG(PT_ERROR , 0x8011) /* 0x8011000A */ #define PR_EMS_AB_TARGET_ADDRESS_UNICODE PROP_TAG(PT_UNICODE , 0x8011) /* 0x8011001F */ #define PR_EMS_AB_THUMBNAIL_PHOTO PidTagThumbnailPhoto #define PR_EMS_AB_THUMBNAIL_PHOTO_ERROR PROP_TAG(PT_ERROR , 0x8C9E) /* 0x8C9E000A */ #define PR_EMS_AB_UM_SPOKEN_NAME PidTagSpokenName #define PR_EMS_AB_UM_SPOKEN_NAME_ERROR PROP_TAG(PT_ERROR , 0x8CC2) /* 0x8CC2000A */ #define PR_EMS_AB_UNAUTH_ORIG PidTagAddressBookUnauthorizedSenders #define PR_EMS_AB_UNAUTH_ORIG_ERROR PROP_TAG(PT_ERROR , 0x8CD9) /* 0x8CD9000A */ #define PR_EMS_AB_X509_CERT PidTagAddressBookX509Certificate #define PR_EMS_AB_X509_CERT_ERROR PROP_TAG(PT_ERROR , 0x8C6A) /* 0x8C6A000A */ #define PR_EMS_SCRIPT_BLOB PidTagScriptData #define PR_EMS_SCRIPT_BLOB_ERROR PROP_TAG(PT_ERROR , 0x0004) /* 0x0004000A */ #define PR_EMS_TEMPLATE_BLOB PidTagTemplateData #define PR_EMS_TEMPLATE_BLOB_ERROR PROP_TAG(PT_ERROR , 0x0001) /* 0x0001000A */ #define PR_END_ATTACH PidTagEndAttach #define PR_END_DATE PidTagEndDate #define PR_END_DATE_ERROR PROP_TAG(PT_ERROR , 0x0061) /* 0x0061000A */ #define PR_END_RECIP PidTagEndToRecip #define PR_ENTRYID PidTagEntryId #define PR_ENTRYID_ERROR PROP_TAG(PT_ERROR , 0x0FFF) /* 0x0FFF000A */ #define PR_EXCEPTION_ENDTIME PidTagExceptionEndTime #define PR_EXCEPTION_ENDTIME_ERROR PROP_TAG(PT_ERROR , 0x7FFC) /* 0x7FFC000A */ #define PR_EXCEPTION_REPLACETIME PidTagExceptionReplaceTime #define PR_EXCEPTION_REPLACETIME_ERROR PROP_TAG(PT_ERROR , 0x7FF9) /* 0x7FF9000A */ #define PR_EXCEPTION_STARTTIME PidTagExceptionStartTime #define PR_EXCEPTION_STARTTIME_ERROR PROP_TAG(PT_ERROR , 0x7FFB) /* 0x7FFB000A */ #define PR_EXPIRY_NUMBER PidTagExpiryNumber #define PR_EXPIRY_NUMBER_ERROR PROP_TAG(PT_ERROR , 0x3FED) /* 0x3FED000A */ #define PR_EXPIRY_TIME PidTagExpiryTime #define PR_EXPIRY_TIME_ERROR PROP_TAG(PT_ERROR , 0x0015) /* 0x0015000A */ #define PR_EXPIRY_UNITS PidTagExpiryUnits #define PR_EXPIRY_UNITS_ERROR PROP_TAG(PT_ERROR , 0x3FEE) /* 0x3FEE000A */ #define PR_EXTENDED_ACL_DATA 0x3FFE0102 #define PR_EXTENDED_FOLDER_FLAGS PidTagExtendedFolderFlags #define PR_EXTENDED_FOLDER_FLAGS_ERROR PROP_TAG(PT_ERROR , 0x36DA) /* 0x36DA000A */ #define PR_EXTENDED_RULE_MSG_ACTIONS PidTagExtendedRuleMessageActions #define PR_EXTENDED_RULE_MSG_ACTIONS_ERROR PROP_TAG(PT_ERROR , 0x0E99) /* 0x0E99000A */ #define PR_EXTENDED_RULE_MSG_CONDITION PidTagExtendedRuleMessageCondition #define PR_EXTENDED_RULE_MSG_CONDITION_ERROR PROP_TAG(PT_ERROR , 0x0E9A) /* 0x0E9A000A */ #define PR_EXTENDED_RULE_SIZE_LIMIT PidTagExtendedRuleSizeLimit #define PR_EXTENDED_RULE_SIZE_LIMIT_ERROR PROP_TAG(PT_ERROR , 0x0E9B) /* 0x0E9B000A */ #define PR_FID PidTagFolderId #define PR_FLAG_COMPLETE_TIME PidTagFlagCompleteTime #define PR_FLAG_COMPLETE_TIME_ERROR PROP_TAG(PT_ERROR , 0x1091) /* 0x1091000A */ #define PR_FLAG_STATUS PidTagFlagStatus #define PR_FLAG_STATUS_ERROR PROP_TAG(PT_ERROR , 0x1090) /* 0x1090000A */ #define PR_FLAT_URL_NAME PROP_TAG(PT_STRING8 , 0x670E) /* 0x670E001E */ #define PR_FLAT_URL_NAME_ERROR PROP_TAG(PT_ERROR , 0x670E) /* 0x670E000A */ #define PR_FLAT_URL_NAME_UNICODE PROP_TAG(PT_UNICODE , 0x670E) /* 0x670E001F */ #define PR_FOLDER_ASSOCIATED_CONTENTS PidTagFolderAssociatedContents #define PR_FOLDER_ASSOCIATED_CONTENTS_ERROR PROP_TAG(PT_ERROR , 0x3610) /* 0x3610000A */ #define PR_FOLDER_CHILD_COUNT 0x66380003 #define PR_FOLDER_TYPE PidTagFolderType #define PR_FOLDER_TYPE_ERROR PROP_TAG(PT_ERROR , 0x3601) /* 0x3601000A */ #define PR_FOLDER_VIEWLIST 0x36EB0102 #define PR_FOLDER_XVIEWINFO_E 0x36E00102 #define PR_FOLLOWUP_ICON PidTagFollowupIcon #define PR_FOLLOWUP_ICON_ERROR PROP_TAG(PT_ERROR , 0x1095) /* 0x1095000A */ #define PR_FREEBUSY_ALL_EVENTS PidTagScheduleInfoFreeBusyMerged #define PR_FREEBUSY_ALL_MONTHS PidTagScheduleInfoMonthsMerged #define PR_FREEBUSY_BUSY_EVENTS PidTagScheduleInfoFreeBusyBusy #define PR_FREEBUSY_BUSY_MONTHS PidTagScheduleInfoMonthsBusy #define PR_FREEBUSY_COUNT_MONTHS PidTagFreeBusyCountMonths #define PR_FREEBUSY_COUNT_MONTHS_ERROR PROP_TAG(PT_ERROR , 0x6869) /* 0x6869000A */ #define PR_FREEBUSY_EMA PROP_TAG(PT_STRING8 , 0x6849) /* 0x6849001E */ #define PR_FREEBUSY_EMA_ERROR PROP_TAG(PT_ERROR , 0x6849) /* 0x6849000A */ #define PR_FREEBUSY_EMA_UNICODE PROP_TAG(PT_UNICODE , 0x6849) /* 0x6849001F */ #define PR_FREEBUSY_END_RANGE PidTagFreeBusyPublishEnd #define PR_FREEBUSY_ENTRYIDS PidTagFreeBusyEntryIds #define PR_FREEBUSY_ENTRYIDS_ERROR PROP_TAG(PT_ERROR , 0x36E4) /* 0x36E4000A */ #define PR_FREEBUSY_LAST_MODIFIED PidTagFreeBusyRangeTimestamp #define PR_FREEBUSY_OOF_EVENTS PidTagScheduleInfoFreeBusyAway #define PR_FREEBUSY_OOF_MONTHS PidTagScheduleInfoMonthsAway #define PR_FREEBUSY_PUBLISH_END PidTagFreeBusyPublishEnd #define PR_FREEBUSY_PUBLISH_END_ERROR PROP_TAG(PT_ERROR , 0x6848) /* 0x6848000A */ #define PR_FREEBUSY_PUBLISH_START PidTagFreeBusyPublishStart #define PR_FREEBUSY_PUBLISH_START_ERROR PROP_TAG(PT_ERROR , 0x6847) /* 0x6847000A */ #define PR_FREEBUSY_RANGE_TIMESTAMP PidTagFreeBusyRangeTimestamp #define PR_FREEBUSY_RANGE_TIMESTAMP_ERROR PROP_TAG(PT_ERROR , 0x6868) /* 0x6868000A */ #define PR_FREEBUSY_START_RANGE PidTagFreeBusyPublishStart #define PR_FREEBUSY_TENTATIVE_EVENTS PidTagScheduleInfoFreeBusyTentative #define PR_FREEBUSY_TENTATIVE_MONTHS PidTagScheduleInfoMonthsTentative #define PR_FTP_SITE PROP_TAG(PT_STRING8 , 0x3A4C) /* 0x3A4C001E */ #define PR_FTP_SITE_ERROR PROP_TAG(PT_ERROR , 0x3A4C) /* 0x3A4C000A */ #define PR_FTP_SITE_UNICODE PROP_TAG(PT_UNICODE , 0x3A4C) /* 0x3A4C001F */ #define PR_FX_DEL_PROP PidTagFXDelProp #define PR_GATEWAY_NEEDS_TO_REFRESH PidTagGatewayNeedsToRefresh #define PR_GATEWAY_NEEDS_TO_REFRESH_ERROR PROP_TAG(PT_ERROR , 0x6846) /* 0x6846000A */ #define PR_GENDER PidTagGender #define PR_GENDER_ERROR PROP_TAG(PT_ERROR , 0x3A4D) /* 0x3A4D000A */ #define PR_GENERATION PROP_TAG(PT_STRING8 , 0x3A05) /* 0x3A05001E */ #define PR_GENERATION_ERROR PROP_TAG(PT_ERROR , 0x3A05) /* 0x3A05000A */ #define PR_GENERATION_UNICODE PROP_TAG(PT_UNICODE , 0x3A05) /* 0x3A05001F */ #define PR_GIVEN_NAME PROP_TAG(PT_STRING8 , 0x3A06) /* 0x3A06001E */ #define PR_GIVEN_NAME_ERROR PROP_TAG(PT_ERROR , 0x3A06) /* 0x3A06000A */ #define PR_GIVEN_NAME_UNICODE PROP_TAG(PT_UNICODE , 0x3A06) /* 0x3A06001F */ #define PR_GOVERNMENT_ID_NUMBER PROP_TAG(PT_STRING8 , 0x3A07) /* 0x3A07001E */ #define PR_GOVERNMENT_ID_NUMBER_ERROR PROP_TAG(PT_ERROR , 0x3A07) /* 0x3A07000A */ #define PR_GOVERNMENT_ID_NUMBER_UNICODE PROP_TAG(PT_UNICODE , 0x3A07) /* 0x3A07001F */ #define PR_HASATTACH PidTagHasAttachments #define PR_HASATTACH_ERROR PROP_TAG(PT_ERROR , 0x0E1B) /* 0x0E1B000A */ #define PR_HAS_DAMS PidTagHasDeferredActionMessages #define PR_HAS_DAMS_ERROR PROP_TAG(PT_ERROR , 0x3FEA) /* 0x3FEA000A */ #define PR_HAS_NAMED_PROPERTIES PidTagHasNamedProperties #define PR_HAS_NAMED_PROPERTIES_ERROR PROP_TAG(PT_ERROR , 0x664A) /* 0x664A000A */ #define PR_HAS_RULES PidTagHasRules #define PR_HAS_RULES_ERROR PROP_TAG(PT_ERROR , 0x663A) /* 0x663A000A */ #define PR_HIERARCHY_CHANGE_NUM PidTagHierarchyChangeNumber #define PR_HIERARCHY_CHANGE_NUM_ERROR PROP_TAG(PT_ERROR , 0x663E) /* 0x663E000A */ #define PR_HOBBIES PROP_TAG(PT_STRING8 , 0x3A43) /* 0x3A43001E */ #define PR_HOBBIES_ERROR PROP_TAG(PT_ERROR , 0x3A43) /* 0x3A43000A */ #define PR_HOBBIES_UNICODE PROP_TAG(PT_UNICODE , 0x3A43) /* 0x3A43001F */ #define PR_HOME2_TELEPHONE_NUMBER PROP_TAG(PT_STRING8 , 0x3A2F) /* 0x3A2F001E */ #define PR_HOME2_TELEPHONE_NUMBER_A_MV PROP_TAG(PT_MV_STRING8, 0x3A2F) /* 0x3A2F101E */ #define PR_HOME2_TELEPHONE_NUMBER_A_MV_ERROR PROP_TAG(PT_ERROR , 0x3A2F) /* 0x3A2F000A */ #define PR_HOME2_TELEPHONE_NUMBER_A_MV_UNICODE PROP_TAG(PT_MV_UNICODE, 0x3A2F) /* 0x3A2F101F */ #define PR_HOME2_TELEPHONE_NUMBER_ERROR PROP_TAG(PT_ERROR , 0x3A2F) /* 0x3A2F000A */ #define PR_HOME2_TELEPHONE_NUMBER_UNICODE PROP_TAG(PT_UNICODE , 0x3A2F) /* 0x3A2F001F */ #define PR_HOME_ADDRESS_CITY PROP_TAG(PT_STRING8 , 0x3A59) /* 0x3A59001E */ #define PR_HOME_ADDRESS_CITY_ERROR PROP_TAG(PT_ERROR , 0x3A59) /* 0x3A59000A */ #define PR_HOME_ADDRESS_CITY_UNICODE PROP_TAG(PT_UNICODE , 0x3A59) /* 0x3A59001F */ #define PR_HOME_ADDRESS_COUNTRY PROP_TAG(PT_STRING8 , 0x3A5A) /* 0x3A5A001E */ #define PR_HOME_ADDRESS_COUNTRY_ERROR PROP_TAG(PT_ERROR , 0x3A5A) /* 0x3A5A000A */ #define PR_HOME_ADDRESS_COUNTRY_UNICODE PROP_TAG(PT_UNICODE , 0x3A5A) /* 0x3A5A001F */ #define PR_HOME_ADDRESS_POSTAL_CODE PROP_TAG(PT_STRING8 , 0x3A5B) /* 0x3A5B001E */ #define PR_HOME_ADDRESS_POSTAL_CODE_ERROR PROP_TAG(PT_ERROR , 0x3A5B) /* 0x3A5B000A */ #define PR_HOME_ADDRESS_POSTAL_CODE_UNICODE PROP_TAG(PT_UNICODE , 0x3A5B) /* 0x3A5B001F */ #define PR_HOME_ADDRESS_POST_OFFICE_BOX PROP_TAG(PT_STRING8 , 0x3A5E) /* 0x3A5E001E */ #define PR_HOME_ADDRESS_POST_OFFICE_BOX_ERROR PROP_TAG(PT_ERROR , 0x3A5E) /* 0x3A5E000A */ #define PR_HOME_ADDRESS_POST_OFFICE_BOX_UNICODE PROP_TAG(PT_UNICODE , 0x3A5E) /* 0x3A5E001F */ #define PR_HOME_ADDRESS_STATE_OR_PROVINCE PROP_TAG(PT_STRING8 , 0x3A5C) /* 0x3A5C001E */ #define PR_HOME_ADDRESS_STATE_OR_PROVINCE_ERROR PROP_TAG(PT_ERROR , 0x3A5C) /* 0x3A5C000A */ #define PR_HOME_ADDRESS_STATE_OR_PROVINCE_UNICODE PROP_TAG(PT_UNICODE , 0x3A5C) /* 0x3A5C001F */ #define PR_HOME_ADDRESS_STREET PROP_TAG(PT_STRING8 , 0x3A5D) /* 0x3A5D001E */ #define PR_HOME_ADDRESS_STREET_ERROR PROP_TAG(PT_ERROR , 0x3A5D) /* 0x3A5D000A */ #define PR_HOME_ADDRESS_STREET_UNICODE PROP_TAG(PT_UNICODE , 0x3A5D) /* 0x3A5D001F */ #define PR_HOME_FAX_NUMBER PROP_TAG(PT_STRING8 , 0x3A25) /* 0x3A25001E */ #define PR_HOME_FAX_NUMBER_ERROR PROP_TAG(PT_ERROR , 0x3A25) /* 0x3A25000A */ #define PR_HOME_FAX_NUMBER_UNICODE PROP_TAG(PT_UNICODE , 0x3A25) /* 0x3A25001F */ #define PR_HOME_TELEPHONE_NUMBER PROP_TAG(PT_STRING8 , 0x3A09) /* 0x3A09001E */ #define PR_HOME_TELEPHONE_NUMBER_ERROR PROP_TAG(PT_ERROR , 0x3A09) /* 0x3A09000A */ #define PR_HOME_TELEPHONE_NUMBER_UNICODE PROP_TAG(PT_UNICODE , 0x3A09) /* 0x3A09001F */ #define PR_HTML PidTagHtml #define PR_HTML_ERROR PROP_TAG(PT_ERROR , 0x1013) /* 0x1013000A */ #define PR_ICON_INDEX PidTagIconIndex #define PR_ICON_INDEX_ERROR PROP_TAG(PT_ERROR , 0x1080) /* 0x1080000A */ #define PR_IMPORTANCE PidTagImportance #define PR_IMPORTANCE_ERROR PROP_TAG(PT_ERROR , 0x0017) /* 0x0017000A */ #define PR_INCR_SYNC_CHG PidTagIncrSyncChg #define PR_INCR_SYNC_DEL PidTagIncrSyncDel #define PR_INCR_SYNC_END PidTagIncrSyncEnd #define PR_INCR_SYNC_MSG PidTagIncrSyncMessage #define PR_INCR_SYNC_STATE_BEGIN PidTagIncrSyncStateBegin #define PR_INCR_SYNC_STATE_END PidTagIncrSyncStateEnd #define PR_INETMAIL_OVERRIDE_FORMAT PidTagInternetMailOverrideFormat #define PR_INETMAIL_OVERRIDE_FORMAT_ERROR PROP_TAG(PT_ERROR , 0x5902) /* 0x5902000A */ #define PR_INITIALS PROP_TAG(PT_STRING8 , 0x3A0A) /* 0x3A0A001E */ #define PR_INITIALS_ERROR PROP_TAG(PT_ERROR , 0x3A0A) /* 0x3A0A000A */ #define PR_INITIALS_UNICODE PROP_TAG(PT_UNICODE , 0x3A0A) /* 0x3A0A001F */ #define PR_INITIAL_DETAILS_PANE PidTagInitialDetailsPane #define PR_INITIAL_DETAILS_PANE_ERROR PROP_TAG(PT_ERROR , 0x3F08) /* 0x3F08000A */ #define PR_INSTANCE_KEY PidTagInstanceKey #define PR_INSTANCE_KEY_ERROR PROP_TAG(PT_ERROR , 0x0FF6) /* 0x0FF6000A */ #define PR_INSTANCE_NUM PidTagInstanceNum #define PR_INST_ID 0x674d0014 #define PR_INTERNET_ARTICLE_NUMBER PidTagInternetArticleNumber #define PR_INTERNET_ARTICLE_NUMBER_ERROR PROP_TAG(PT_ERROR , 0x0E23) /* 0x0E23000A */ #define PR_INTERNET_CPID PidTagInternetCodepage #define PR_INTERNET_CPID_ERROR PROP_TAG(PT_ERROR , 0x3FDE) /* 0x3FDE000A */ #define PR_INTERNET_MESSAGE_ID PROP_TAG(PT_STRING8 , 0x1035) /* 0x1035001E */ #define PR_INTERNET_MESSAGE_ID_ERROR PROP_TAG(PT_ERROR , 0x1035) /* 0x1035000A */ #define PR_INTERNET_MESSAGE_ID_UNICODE PROP_TAG(PT_UNICODE , 0x1035) /* 0x1035001F */ #define PR_INTERNET_REFERENCES PROP_TAG(PT_STRING8 , 0x1039) /* 0x1039001E */ #define PR_INTERNET_REFERENCES_ERROR PROP_TAG(PT_ERROR , 0x1039) /* 0x1039000A */ #define PR_INTERNET_REFERENCES_UNICODE PROP_TAG(PT_UNICODE , 0x1039) /* 0x1039001F */ #define PR_IN_CONFLICT PidTagInConflict #define PR_IN_CONFLICT_ERROR PROP_TAG(PT_ERROR , 0x666C) /* 0x666C000A */ #define PR_IN_REPLY_TO_ID PROP_TAG(PT_STRING8 , 0x1042) /* 0x1042001E */ #define PR_IN_REPLY_TO_ID_ERROR PROP_TAG(PT_ERROR , 0x1042) /* 0x1042000A */ #define PR_IN_REPLY_TO_ID_UNICODE PROP_TAG(PT_UNICODE , 0x1042) /* 0x1042001F */ #define PR_IPM_APPOINTMENT_ENTRYID PidTagIpmAppointmentEntryId #define PR_IPM_APPOINTMENT_ENTRYID_ERROR PROP_TAG(PT_ERROR , 0x36D0) /* 0x36D0000A */ #define PR_IPM_CONTACT_ENTRYID PidTagIpmContactEntryId #define PR_IPM_CONTACT_ENTRYID_ERROR PROP_TAG(PT_ERROR , 0x36D1) /* 0x36D1000A */ #define PR_IPM_DRAFTS_ENTRYID PidTagIpmDraftsEntryId #define PR_IPM_DRAFTS_ENTRYID_ERROR PROP_TAG(PT_ERROR , 0x36D7) /* 0x36D7000A */ #define PR_IPM_JOURNAL_ENTRYID PidTagIpmJournalEntryId #define PR_IPM_JOURNAL_ENTRYID_ERROR PROP_TAG(PT_ERROR , 0x36D2) /* 0x36D2000A */ #define PR_IPM_NOTE_ENTRYID PidTagIpmNoteEntryId #define PR_IPM_NOTE_ENTRYID_ERROR PROP_TAG(PT_ERROR , 0x36D3) /* 0x36D3000A */ #define PR_IPM_PUBLIC_FOLDERS_ENTRYID PidTagIpmPublicFoldersEntryId #define PR_IPM_TASK_ENTRYID PidTagIpmTaskEntryId #define PR_IPM_TASK_ENTRYID_ERROR PROP_TAG(PT_ERROR , 0x36D4) /* 0x36D4000A */ #define PR_ISDN_NUMBER PROP_TAG(PT_STRING8 , 0x3A2D) /* 0x3A2D001E */ #define PR_ISDN_NUMBER_ERROR PROP_TAG(PT_ERROR , 0x3A2D) /* 0x3A2D000A */ #define PR_ISDN_NUMBER_UNICODE PROP_TAG(PT_UNICODE , 0x3A2D) /* 0x3A2D001F */ #define PR_JUNK_ADD_RECIPS_TO_SSL PidTagJunkAddRecipientsToSafeSendersList #define PR_JUNK_ADD_RECIPS_TO_SSL_ERROR PROP_TAG(PT_ERROR , 0x6103) /* 0x6103000A */ #define PR_JUNK_INCLUDE_CONTACTS PidTagJunkIncludeContacts #define PR_JUNK_INCLUDE_CONTACTS_ERROR PROP_TAG(PT_ERROR , 0x6100) /* 0x6100000A */ #define PR_JUNK_PERMANENTLY_DELETE PidTagJunkPermanentlyDelete #define PR_JUNK_PERMANENTLY_DELETE_ERROR PROP_TAG(PT_ERROR , 0x6102) /* 0x6102000A */ #define PR_JUNK_PHISHING_ENABLE_LINKS PidTagJunkPhishingEnableLinks #define PR_JUNK_PHISHING_ENABLE_LINKS_ERROR PROP_TAG(PT_ERROR , 0x6107) /* 0x6107000A */ #define PR_JUNK_THRESHOLD PidTagJunkThreshold #define PR_JUNK_THRESHOLD_ERROR PROP_TAG(PT_ERROR , 0x6101) /* 0x6101000A */ #define PR_KEYWORD PROP_TAG(PT_STRING8 , 0x3A0B) /* 0x3A0B001E */ #define PR_KEYWORD_ERROR PROP_TAG(PT_ERROR , 0x3A0B) /* 0x3A0B000A */ #define PR_KEYWORD_UNICODE PROP_TAG(PT_UNICODE , 0x3A0B) /* 0x3A0B001F */ #define PR_LANGUAGE PROP_TAG(PT_STRING8 , 0x3A0C) /* 0x3A0C001E */ #define PR_LANGUAGE_ERROR PROP_TAG(PT_ERROR , 0x3A0C) /* 0x3A0C000A */ #define PR_LANGUAGE_UNICODE PROP_TAG(PT_UNICODE , 0x3A0C) /* 0x3A0C001F */ #define PR_LAST_MODIFICATION_TIME PidTagLastModificationTime #define PR_LAST_MODIFICATION_TIME_ERROR PROP_TAG(PT_ERROR , 0x3008) /* 0x3008000A */ #define PR_LAST_MODIFIER_ENTRYID PidTagLastModifierEntryId #define PR_LAST_MODIFIER_ENTRYID_ERROR PROP_TAG(PT_ERROR , 0x3FFB) /* 0x3FFB000A */ #define PR_LAST_MODIFIER_NAME PROP_TAG(PT_STRING8 , 0x3FFA) /* 0x3FFA001E */ #define PR_LAST_MODIFIER_NAME_ERROR PROP_TAG(PT_ERROR , 0x3FFA) /* 0x3FFA000A */ #define PR_LAST_MODIFIER_NAME_UNICODE PROP_TAG(PT_UNICODE , 0x3FFA) /* 0x3FFA001F */ #define PR_LAST_MODIFIER_SID 0x0E590102 #define PR_LAST_VERB_EXECUTED PidTagLastVerbExecuted #define PR_LAST_VERB_EXECUTED_ERROR PROP_TAG(PT_ERROR , 0x1081) /* 0x1081000A */ #define PR_LAST_VERB_EXECUTION_TIME PidTagLastVerbExecutionTime #define PR_LAST_VERB_EXECUTION_TIME_ERROR PROP_TAG(PT_ERROR , 0x1082) /* 0x1082000A */ #define PR_LIST_HELP PROP_TAG(PT_STRING8 , 0x1043) /* 0x1043001E */ #define PR_LIST_HELP_ERROR PROP_TAG(PT_ERROR , 0x1043) /* 0x1043000A */ #define PR_LIST_HELP_UNICODE PROP_TAG(PT_UNICODE , 0x1043) /* 0x1043001F */ #define PR_LIST_SUBSCRIBE PROP_TAG(PT_STRING8 , 0x1044) /* 0x1044001E */ #define PR_LIST_SUBSCRIBE_ERROR PROP_TAG(PT_ERROR , 0x1044) /* 0x1044000A */ #define PR_LIST_SUBSCRIBE_UNICODE PROP_TAG(PT_UNICODE , 0x1044) /* 0x1044001F */ #define PR_LIST_UNSUBSCRIBE PROP_TAG(PT_STRING8 , 0x1045) /* 0x1045001E */ #define PR_LIST_UNSUBSCRIBE_ERROR PROP_TAG(PT_ERROR , 0x1045) /* 0x1045000A */ #define PR_LIST_UNSUBSCRIBE_UNICODE PROP_TAG(PT_UNICODE , 0x1045) /* 0x1045001F */ #define PR_LOCALE_ID PidTagLocaleId #define PR_LOCALE_ID_ERROR PROP_TAG(PT_ERROR , 0x66A1) /* 0x66A1000A */ #define PR_LOCALITY PROP_TAG(PT_STRING8 , 0x3A27) /* 0x3A27001E */ #define PR_LOCALITY_ERROR PROP_TAG(PT_ERROR , 0x3A27) /* 0x3A27000A */ #define PR_LOCALITY_UNICODE PROP_TAG(PT_UNICODE , 0x3A27) /* 0x3A27001F */ #define PR_LOCAL_COMMIT_TIME PidTagLocalCommitTime #define PR_LOCAL_COMMIT_TIME_ERROR PROP_TAG(PT_ERROR , 0x6709) /* 0x6709000A */ #define PR_LOCATION PROP_TAG(PT_STRING8 , 0x3A0D) /* 0x3A0D001E */ #define PR_LOCATION_ERROR PROP_TAG(PT_ERROR , 0x3A0D) /* 0x3A0D000A */ #define PR_LOCATION_UNICODE PROP_TAG(PT_UNICODE , 0x3A0D) /* 0x3A0D001F */ #define PR_MAILBOX_OWNER_ENTRYID PidTagMailboxOwnerEntryId #define PR_MAILBOX_OWNER_ENTRYID_ERROR PROP_TAG(PT_ERROR , 0x661B) /* 0x661B000A */ #define PR_MAILBOX_OWNER_NAME PROP_TAG(PT_STRING8 , 0x661C) /* 0x661C001E */ #define PR_MAILBOX_OWNER_NAME_ERROR PROP_TAG(PT_ERROR , 0x661C) /* 0x661C000A */ #define PR_MAILBOX_OWNER_NAME_UNICODE PROP_TAG(PT_UNICODE , 0x661C) /* 0x661C001F */ #define PR_MANAGER_NAME PROP_TAG(PT_STRING8 , 0x3A4E) /* 0x3A4E001E */ #define PR_MANAGER_NAME_ERROR PROP_TAG(PT_ERROR , 0x3A4E) /* 0x3A4E000A */ #define PR_MANAGER_NAME_UNICODE PROP_TAG(PT_UNICODE , 0x3A4E) /* 0x3A4E001F */ #define PR_MAPPING_SIGNATURE PidTagMappingSignature #define PR_MAPPING_SIGNATURE_ERROR PROP_TAG(PT_ERROR , 0x0FF8) /* 0x0FF8000A */ #define PR_MAX_SUBMIT_MESSAGE_SIZE PidTagMaximumSubmitMessageSize #define PR_MAX_SUBMIT_MESSAGE_SIZE_ERROR PROP_TAG(PT_ERROR , 0x666D) /* 0x666D000A */ #define PR_MEMBER_ID PidTagMemberId #define PR_MEMBER_ID_ERROR PROP_TAG(PT_ERROR , 0x6671) /* 0x6671000A */ #define PR_MEMBER_NAME PROP_TAG(PT_STRING8 , 0x6672) /* 0x6672001E */ #define PR_MEMBER_NAME_ERROR PROP_TAG(PT_ERROR , 0x6672) /* 0x6672000A */ #define PR_MEMBER_NAME_UNICODE PROP_TAG(PT_UNICODE , 0x6672) /* 0x6672001F */ #define PR_MEMBER_RIGHTS PidTagMemberRights #define PR_MEMBER_RIGHTS_ERROR PROP_TAG(PT_ERROR , 0x6673) /* 0x6673000A */ #define PR_MESSAGE_ATTACHMENTS PidTagMessageAttachments #define PR_MESSAGE_ATTACHMENTS_ERROR PROP_TAG(PT_ERROR , 0x0E13) /* 0x0E13000A */ #define PR_MESSAGE_CC_ME PidTagMessageCcMe #define PR_MESSAGE_CC_ME_ERROR PROP_TAG(PT_ERROR , 0x0058) /* 0x0058000A */ #define PR_MESSAGE_CLASS PROP_TAG(PT_STRING8 , 0x001A) /* 0x001A001E */ #define PR_MESSAGE_CLASS_ERROR PROP_TAG(PT_ERROR , 0x001A) /* 0x001A000A */ #define PR_MESSAGE_CLASS_UNICODE PROP_TAG(PT_UNICODE , 0x001A) /* 0x001A001F */ #define PR_MESSAGE_CODEPAGE PidTagMessageCodepage #define PR_MESSAGE_CODEPAGE_ERROR PROP_TAG(PT_ERROR , 0x3FFD) /* 0x3FFD000A */ #define PR_MESSAGE_DELIVERY_TIME PidTagMessageDeliveryTime #define PR_MESSAGE_DELIVERY_TIME_ERROR PROP_TAG(PT_ERROR , 0x0E06) /* 0x0E06000A */ #define PR_MESSAGE_FLAGS PidTagMessageFlags #define PR_MESSAGE_FLAGS_ERROR PROP_TAG(PT_ERROR , 0x0E07) /* 0x0E07000A */ #define PR_MESSAGE_LOCALE_ID PidTagMessageLocaleId #define PR_MESSAGE_LOCALE_ID_ERROR PROP_TAG(PT_ERROR , 0x3FF1) /* 0x3FF1000A */ #define PR_MESSAGE_RECIPIENTS PidTagMessageRecipients #define PR_MESSAGE_RECIPIENTS_ERROR PROP_TAG(PT_ERROR , 0x0E12) /* 0x0E12000A */ #define PR_MESSAGE_RECIP_ME PidTagMessageRecipientMe #define PR_MESSAGE_RECIP_ME_ERROR PROP_TAG(PT_ERROR , 0x0059) /* 0x0059000A */ #define PR_MESSAGE_SIZE PidTagMessageSize #define PR_MESSAGE_SIZE_ERROR PROP_TAG(PT_ERROR , 0x0E08) /* 0x0E08000A */ #define PR_MESSAGE_SIZE_EXTENDED PidTagMessageSizeExtended #define PR_MESSAGE_SIZE_EXTENDED_ERROR PROP_TAG(PT_ERROR , 0x0E08) /* 0x0E08000A */ #define PR_MESSAGE_SUBMISSION_ID PidTagMessageSubmissionId #define PR_MESSAGE_SUBMISSION_ID_ERROR PROP_TAG(PT_ERROR , 0x0047) /* 0x0047000A */ #define PR_MESSAGE_TO_ME PidTagMessageToMe #define PR_MESSAGE_TO_ME_ERROR PROP_TAG(PT_ERROR , 0x0057) /* 0x0057000A */ #define PR_MHS_COMMON_NAME PROP_TAG(PT_STRING8 , 0x3A0F) /* 0x3A0F001E */ #define PR_MHS_COMMON_NAME_ERROR PROP_TAG(PT_ERROR , 0x3A0F) /* 0x3A0F000A */ #define PR_MHS_COMMON_NAME_UNICODE PROP_TAG(PT_UNICODE , 0x3A0F) /* 0x3A0F001F */ #define PR_MID PidTagMid #define PR_MIDDLE_NAME PROP_TAG(PT_STRING8 , 0x3A44) /* 0x3A44001E */ #define PR_MIDDLE_NAME_ERROR PROP_TAG(PT_ERROR , 0x3A44) /* 0x3A44000A */ #define PR_MIDDLE_NAME_UNICODE PROP_TAG(PT_UNICODE , 0x3A44) /* 0x3A44001F */ #define PR_MOBILE_TELEPHONE_NUMBER PROP_TAG(PT_STRING8 , 0x3A1C) /* 0x3A1C001E */ #define PR_MOBILE_TELEPHONE_NUMBER_ERROR PROP_TAG(PT_ERROR , 0x3A1C) /* 0x3A1C000A */ #define PR_MOBILE_TELEPHONE_NUMBER_UNICODE PROP_TAG(PT_UNICODE , 0x3A1C) /* 0x3A1C001F */ #define PR_MSG_EDITOR_FORMAT PidTagMessageEditorFormat #define PR_MSG_EDITOR_FORMAT_ERROR PROP_TAG(PT_ERROR , 0x5909) /* 0x5909000A */ #define PR_MSG_STATUS PidTagMessageStatus #define PR_MSG_STATUS_ERROR PROP_TAG(PT_ERROR , 0x0E17) /* 0x0E17000A */ #define PR_NATIVE_BODY_INFO PidTagNativeBody #define PR_NATIVE_BODY_INFO_ERROR PROP_TAG(PT_ERROR , 0x1016) /* 0x1016000A */ #define PR_NEW_ATTACH PidTagNewAttach #define PR_NEXT_SEND_ACCT PROP_TAG(PT_STRING8 , 0x0E29) /* 0x0E29001E */ #define PR_NEXT_SEND_ACCT_ERROR PROP_TAG(PT_ERROR , 0x0E29) /* 0x0E29000A */ #define PR_NEXT_SEND_ACCT_UNICODE PROP_TAG(PT_UNICODE , 0x0E29) /* 0x0E29001F */ #define PR_NICKNAME PROP_TAG(PT_STRING8 , 0x3A4F) /* 0x3A4F001E */ #define PR_NICKNAME_ERROR PROP_TAG(PT_ERROR , 0x3A4F) /* 0x3A4F000A */ #define PR_NICKNAME_UNICODE PROP_TAG(PT_UNICODE , 0x3A4F) /* 0x3A4F001F */ #define PR_NORMALIZED_SUBJECT PROP_TAG(PT_STRING8 , 0x0E1D) /* 0x0E1D001E */ #define PR_NORMALIZED_SUBJECT_ERROR PROP_TAG(PT_ERROR , 0x0E1D) /* 0x0E1D000A */ #define PR_NORMALIZED_SUBJECT_UNICODE PROP_TAG(PT_UNICODE , 0x0E1D) /* 0x0E1D001F */ #define PR_NORMAL_MESSAGE_SIZE PidTagNormalMessageSize #define PR_NORMAL_MESSAGE_SIZE_ERROR PROP_TAG(PT_ERROR , 0x66B3) /* 0x66B3000A */ #define PR_NTSD_MODIFICATION_TIME 0x3FD60040 #define PR_NT_SECURITY_DESCRIPTOR PidTagSecurityDescriptor #define PR_NT_SECURITY_DESCRIPTOR_AS_XML PROP_TAG(PT_STRING8 , 0x0E6A) /* 0x0E6A001E */ #define PR_NT_SECURITY_DESCRIPTOR_AS_XML_ERROR PROP_TAG(PT_ERROR , 0x0E6A) /* 0x0E6A000A */ #define PR_NT_SECURITY_DESCRIPTOR_AS_XML_UNICODE PROP_TAG(PT_UNICODE , 0x0E6A) /* 0x0E6A001F */ #define PR_NT_SECURITY_DESCRIPTOR_ERROR PROP_TAG(PT_ERROR , 0x0E27) /* 0x0E27000A */ #define PR_OAB_COMPRESSED_SIZE PidTagOfflineAddressBookCompressedSize #define PR_OAB_COMPRESSED_SIZE_ERROR PROP_TAG(PT_ERROR , 0x6809) /* 0x6809000A */ #define PR_OAB_CONTAINER_GUID PidTagOfflineAddressBookContainerGuid #define PR_OAB_CONTAINER_GUID_ERROR PROP_TAG(PT_ERROR , 0x6802) /* 0x6802000A */ #define PR_OAB_DN PidTagOfflineAddressBookDistinguishedName #define PR_OAB_DN_ERROR PROP_TAG(PT_ERROR , 0x6804) /* 0x6804000A */ #define PR_OAB_FILETYPE PidTagOfflineAddressBookFileType #define PR_OAB_FILETYPE_ERROR PROP_TAG(PT_ERROR , 0x6808) /* 0x6808000A */ #define PR_OAB_FILE_SIZE PidTagOfflineAddressBookFileSize #define PR_OAB_FILE_SIZE_ERROR PROP_TAG(PT_ERROR , 0x680A) /* 0x680A000A */ #define PR_OAB_LANGID PidTagOfflineAddressBookLanguageId #define PR_OAB_LANGID_ERROR PROP_TAG(PT_ERROR , 0x6807) /* 0x6807000A */ #define PR_OAB_MESSAGE_CLASS PidTagOfflineAddressBookMessageClass #define PR_OAB_MESSAGE_CLASS_ERROR PROP_TAG(PT_ERROR , 0x6803) /* 0x6803000A */ #define PR_OAB_NAME PROP_TAG(PT_STRING8 , 0x6800) /* 0x6800001E */ #define PR_OAB_NAME_ERROR PROP_TAG(PT_ERROR , 0x6800) /* 0x6800000A */ #define PR_OAB_NAME_UNICODE PROP_TAG(PT_UNICODE , 0x6800) /* 0x6800001F */ #define PR_OAB_SEQUENCE PidTagOfflineAddressBookSequence #define PR_OAB_SEQUENCE_ERROR PROP_TAG(PT_ERROR , 0x6801) /* 0x6801000A */ #define PR_OAB_SHA_HASH PidTagOfflineAddressBookShaHash #define PR_OAB_SHA_HASH_ERROR PROP_TAG(PT_ERROR , 0x6806) /* 0x6806000A */ #define PR_OAB_TRUNCATED_PROPS PidTagOfflineAddressBookTruncatedProperties #define PR_OAB_TRUNCATED_PROPS_ERROR PROP_TAG(PT_ERROR , 0x6805) /* 0x6805000A */ #define PR_OBJECT_TYPE PidTagObjectType #define PR_OBJECT_TYPE_ERROR PROP_TAG(PT_ERROR , 0x0FFE) /* 0x0FFE000A */ #define PR_OFFICE2_TELEPHONE_NUMBER PROP_TAG(PT_STRING8 , 0x3A1B) /* 0x3A1B001E */ #define PR_OFFICE2_TELEPHONE_NUMBER_ERROR PROP_TAG(PT_ERROR , 0x3A1B) /* 0x3A1B000A */ #define PR_OFFICE2_TELEPHONE_NUMBER_UNICODE PROP_TAG(PT_UNICODE , 0x3A1B) /* 0x3A1B001F */ #define PR_OFFICE_LOCATION PROP_TAG(PT_STRING8 , 0x3A19) /* 0x3A19001E */ #define PR_OFFICE_LOCATION_ERROR PROP_TAG(PT_ERROR , 0x3A19) /* 0x3A19000A */ #define PR_OFFICE_LOCATION_UNICODE PROP_TAG(PT_UNICODE , 0x3A19) /* 0x3A19001F */ #define PR_OFFICE_TELEPHONE_NUMBER PROP_TAG(PT_STRING8 , 0x3A08) /* 0x3A08001E */ #define PR_OFFICE_TELEPHONE_NUMBER_ERROR PROP_TAG(PT_ERROR , 0x3A08) /* 0x3A08000A */ #define PR_OFFICE_TELEPHONE_NUMBER_UNICODE PROP_TAG(PT_UNICODE , 0x3A08) /* 0x3A08001F */ #define PR_OOF_STATE PidTagOutOfOfficeState #define PR_OOF_STATE_ERROR PROP_TAG(PT_ERROR , 0x661D) /* 0x661D000A */ #define PR_ORDINAL_MOST PidTagOrdinalMost #define PR_ORDINAL_MOST_ERROR PROP_TAG(PT_ERROR , 0x36E2) /* 0x36E2000A */ #define PR_ORGANIZATIONAL_ID_NUMBER PROP_TAG(PT_STRING8 , 0x3A10) /* 0x3A10001E */ #define PR_ORGANIZATIONAL_ID_NUMBER_ERROR PROP_TAG(PT_ERROR , 0x3A10) /* 0x3A10000A */ #define PR_ORGANIZATIONAL_ID_NUMBER_UNICODE PROP_TAG(PT_UNICODE , 0x3A10) /* 0x3A10001F */ #define PR_ORIGINAL_DELIVERY_TIME PidTagOriginalDeliveryTime #define PR_ORIGINAL_DELIVERY_TIME_ERROR PROP_TAG(PT_ERROR , 0x0055) /* 0x0055000A */ #define PR_ORIGINAL_DISPLAY_BCC PROP_TAG(PT_STRING8 , 0x0072) /* 0x0072001E */ #define PR_ORIGINAL_DISPLAY_BCC_ERROR PROP_TAG(PT_ERROR , 0x0072) /* 0x0072000A */ #define PR_ORIGINAL_DISPLAY_BCC_UNICODE PROP_TAG(PT_UNICODE , 0x0072) /* 0x0072001F */ #define PR_ORIGINAL_DISPLAY_CC PROP_TAG(PT_STRING8 , 0x0073) /* 0x0073001E */ #define PR_ORIGINAL_DISPLAY_CC_ERROR PROP_TAG(PT_ERROR , 0x0073) /* 0x0073000A */ #define PR_ORIGINAL_DISPLAY_CC_UNICODE PROP_TAG(PT_UNICODE , 0x0073) /* 0x0073001F */ #define PR_ORIGINAL_DISPLAY_NAME PROP_TAG(PT_STRING8 , 0x3A13) /* 0x3A13001E */ #define PR_ORIGINAL_DISPLAY_NAME_ERROR PROP_TAG(PT_ERROR , 0x3A13) /* 0x3A13000A */ #define PR_ORIGINAL_DISPLAY_NAME_UNICODE PROP_TAG(PT_UNICODE , 0x3A13) /* 0x3A13001F */ #define PR_ORIGINAL_DISPLAY_TO PROP_TAG(PT_STRING8 , 0x0074) /* 0x0074001E */ #define PR_ORIGINAL_DISPLAY_TO_ERROR PROP_TAG(PT_ERROR , 0x0074) /* 0x0074000A */ #define PR_ORIGINAL_DISPLAY_TO_UNICODE PROP_TAG(PT_UNICODE , 0x0074) /* 0x0074001F */ #define PR_ORIGINAL_ENTRYID PidTagOriginalEntryId #define PR_ORIGINAL_ENTRYID_ERROR PROP_TAG(PT_ERROR , 0x3A12) /* 0x3A12000A */ #define PR_ORIGINAL_SEARCH_KEY PidTagOriginalSearchKey #define PR_ORIGINAL_SEARCH_KEY_ERROR PROP_TAG(PT_ERROR , 0x3A14) /* 0x3A14000A */ #define PR_ORIGINAL_SENDER_ADDRTYPE PROP_TAG(PT_STRING8 , 0x0066) /* 0x0066001E */ #define PR_ORIGINAL_SENDER_ADDRTYPE_ERROR PROP_TAG(PT_ERROR , 0x0066) /* 0x0066000A */ #define PR_ORIGINAL_SENDER_ADDRTYPE_UNICODE PROP_TAG(PT_UNICODE , 0x0066) /* 0x0066001F */ #define PR_ORIGINAL_SENDER_EMAIL_ADDRESS PROP_TAG(PT_STRING8 , 0x0067) /* 0x0067001E */ #define PR_ORIGINAL_SENDER_EMAIL_ADDRESS_ERROR PROP_TAG(PT_ERROR , 0x0067) /* 0x0067000A */ #define PR_ORIGINAL_SENDER_EMAIL_ADDRESS_UNICODE PROP_TAG(PT_UNICODE , 0x0067) /* 0x0067001F */ #define PR_ORIGINAL_SENDER_ENTRYID PidTagOriginalSenderEntryId #define PR_ORIGINAL_SENDER_ENTRYID_ERROR PROP_TAG(PT_ERROR , 0x005B) /* 0x005B000A */ #define PR_ORIGINAL_SENDER_NAME PROP_TAG(PT_STRING8 , 0x005A) /* 0x005A001E */ #define PR_ORIGINAL_SENDER_NAME_ERROR PROP_TAG(PT_ERROR , 0x005A) /* 0x005A000A */ #define PR_ORIGINAL_SENDER_NAME_UNICODE PROP_TAG(PT_UNICODE , 0x005A) /* 0x005A001F */ #define PR_ORIGINAL_SENDER_SEARCH_KEY PidTagOriginalSenderSearchKey #define PR_ORIGINAL_SENDER_SEARCH_KEY_ERROR PROP_TAG(PT_ERROR , 0x005C) /* 0x005C000A */ #define PR_ORIGINAL_SENSITIVITY PidTagOriginalSensitivity #define PR_ORIGINAL_SENSITIVITY_ERROR PROP_TAG(PT_ERROR , 0x002E) /* 0x002E000A */ #define PR_ORIGINAL_SENT_REPRESENTING_ADDRTYPE PROP_TAG(PT_STRING8 , 0x0068) /* 0x0068001E */ #define PR_ORIGINAL_SENT_REPRESENTING_ADDRTYPE_ERROR PROP_TAG(PT_ERROR , 0x0068) /* 0x0068000A */ #define PR_ORIGINAL_SENT_REPRESENTING_ADDRTYPE_UNICODE PROP_TAG(PT_UNICODE , 0x0068) /* 0x0068001F */ #define PR_ORIGINAL_SENT_REPRESENTING_EMAIL_ADDRESS PROP_TAG(PT_STRING8 , 0x0069) /* 0x0069001E */ #define PR_ORIGINAL_SENT_REPRESENTING_EMAIL_ADDRESS_ERROR PROP_TAG(PT_ERROR , 0x0069) /* 0x0069000A */ #define PR_ORIGINAL_SENT_REPRESENTING_EMAIL_ADDRESS_UNICODE PROP_TAG(PT_UNICODE , 0x0069) /* 0x0069001F */ #define PR_ORIGINAL_SENT_REPRESENTING_ENTRYID PidTagOriginalSentRepresentingEntryId #define PR_ORIGINAL_SENT_REPRESENTING_ENTRYID_ERROR PROP_TAG(PT_ERROR , 0x005E) /* 0x005E000A */ #define PR_ORIGINAL_SENT_REPRESENTING_NAME PROP_TAG(PT_STRING8 , 0x005D) /* 0x005D001E */ #define PR_ORIGINAL_SENT_REPRESENTING_NAME_ERROR PROP_TAG(PT_ERROR , 0x005D) /* 0x005D000A */ #define PR_ORIGINAL_SENT_REPRESENTING_NAME_UNICODE PROP_TAG(PT_UNICODE , 0x005D) /* 0x005D001F */ #define PR_ORIGINAL_SENT_REPRESENTING_SEARCH_KEY PidTagOriginalSentRepresentingSearchKey #define PR_ORIGINAL_SENT_REPRESENTING_SEARCH_KEY_ERROR PROP_TAG(PT_ERROR , 0x005F) /* 0x005F000A */ #define PR_ORIGINAL_SUBJECT PROP_TAG(PT_STRING8 , 0x0049) /* 0x0049001E */ #define PR_ORIGINAL_SUBJECT_ERROR PROP_TAG(PT_ERROR , 0x0049) /* 0x0049000A */ #define PR_ORIGINAL_SUBJECT_UNICODE PROP_TAG(PT_UNICODE , 0x0049) /* 0x0049001F */ #define PR_ORIGINAL_SUBMIT_TIME PidTagOriginalSubmitTime #define PR_ORIGINAL_SUBMIT_TIME_ERROR PROP_TAG(PT_ERROR , 0x004E) /* 0x004E000A */ #define PR_ORIGINATOR_DELIVERY_REPORT_REQUESTED PidTagOriginatorDeliveryReportRequested #define PR_ORIGINATOR_DELIVERY_REPORT_REQUESTED_ERROR PROP_TAG(PT_ERROR , 0x0023) /* 0x0023000A */ #define PR_ORIGINATOR_NON_DELIVERY_REPORT_REQUESTED PidTagOriginatorNonDeliveryReportRequested #define PR_ORIGINATOR_NON_DELIVERY_REPORT_REQUESTED_ERROR PROP_TAG(PT_ERROR , 0x0C08) /* 0x0C08000A */ #define PR_ORIG_MESSAGE_CLASS PROP_TAG(PT_STRING8 , 0x004B) /* 0x004B001E */ #define PR_ORIG_MESSAGE_CLASS_ERROR PROP_TAG(PT_ERROR , 0x004B) /* 0x004B000A */ #define PR_ORIG_MESSAGE_CLASS_UNICODE PROP_TAG(PT_UNICODE , 0x004B) /* 0x004B001F */ #define PR_OTHER_ADDRESS_CITY PROP_TAG(PT_STRING8 , 0x3A5F) /* 0x3A5F001E */ #define PR_OTHER_ADDRESS_CITY_ERROR PROP_TAG(PT_ERROR , 0x3A5F) /* 0x3A5F000A */ #define PR_OTHER_ADDRESS_CITY_UNICODE PROP_TAG(PT_UNICODE , 0x3A5F) /* 0x3A5F001F */ #define PR_OTHER_ADDRESS_COUNTRY PROP_TAG(PT_STRING8 , 0x3A60) /* 0x3A60001E */ #define PR_OTHER_ADDRESS_COUNTRY_ERROR PROP_TAG(PT_ERROR , 0x3A60) /* 0x3A60000A */ #define PR_OTHER_ADDRESS_COUNTRY_UNICODE PROP_TAG(PT_UNICODE , 0x3A60) /* 0x3A60001F */ #define PR_OTHER_ADDRESS_POSTAL_CODE PROP_TAG(PT_STRING8 , 0x3A61) /* 0x3A61001E */ #define PR_OTHER_ADDRESS_POSTAL_CODE_ERROR PROP_TAG(PT_ERROR , 0x3A61) /* 0x3A61000A */ #define PR_OTHER_ADDRESS_POSTAL_CODE_UNICODE PROP_TAG(PT_UNICODE , 0x3A61) /* 0x3A61001F */ #define PR_OTHER_ADDRESS_POST_OFFICE_BOX PROP_TAG(PT_STRING8 , 0x3A64) /* 0x3A64001E */ #define PR_OTHER_ADDRESS_POST_OFFICE_BOX_ERROR PROP_TAG(PT_ERROR , 0x3A64) /* 0x3A64000A */ #define PR_OTHER_ADDRESS_POST_OFFICE_BOX_UNICODE PROP_TAG(PT_UNICODE , 0x3A64) /* 0x3A64001F */ #define PR_OTHER_ADDRESS_STATE_OR_PROVINCE PROP_TAG(PT_STRING8 , 0x3A62) /* 0x3A62001E */ #define PR_OTHER_ADDRESS_STATE_OR_PROVINCE_ERROR PROP_TAG(PT_ERROR , 0x3A62) /* 0x3A62000A */ #define PR_OTHER_ADDRESS_STATE_OR_PROVINCE_UNICODE PROP_TAG(PT_UNICODE , 0x3A62) /* 0x3A62001F */ #define PR_OTHER_ADDRESS_STREET PROP_TAG(PT_STRING8 , 0x3A63) /* 0x3A63001E */ #define PR_OTHER_ADDRESS_STREET_ERROR PROP_TAG(PT_ERROR , 0x3A63) /* 0x3A63000A */ #define PR_OTHER_ADDRESS_STREET_UNICODE PROP_TAG(PT_UNICODE , 0x3A63) /* 0x3A63001F */ #define PR_OTHER_TELEPHONE_NUMBER PROP_TAG(PT_STRING8 , 0x3A1F) /* 0x3A1F001E */ #define PR_OTHER_TELEPHONE_NUMBER_ERROR PROP_TAG(PT_ERROR , 0x3A1F) /* 0x3A1F000A */ #define PR_OTHER_TELEPHONE_NUMBER_UNICODE PROP_TAG(PT_UNICODE , 0x3A1F) /* 0x3A1F001F */ #define PR_OWNER_APPT_ID PidTagOwnerAppointmentId #define PR_OWNER_APPT_ID_ERROR PROP_TAG(PT_ERROR , 0x0062) /* 0x0062000A */ #define PR_PAGER_TELEPHONE_NUMBER PROP_TAG(PT_STRING8 , 0x3A21) /* 0x3A21001E */ #define PR_PAGER_TELEPHONE_NUMBER_ERROR PROP_TAG(PT_ERROR , 0x3A21) /* 0x3A21000A */ #define PR_PAGER_TELEPHONE_NUMBER_UNICODE PROP_TAG(PT_UNICODE , 0x3A21) /* 0x3A21001F */ #define PR_PARENT_ENTRYID PidTagParentEntryId #define PR_PARENT_ENTRYID_ERROR PROP_TAG(PT_ERROR , 0x0E09) /* 0x0E09000A */ #define PR_PARENT_FID PidTagParentFolderId #define PR_PARENT_KEY PidTagParentKey #define PR_PARENT_KEY_ERROR PROP_TAG(PT_ERROR , 0x0025) /* 0x0025000A */ #define PR_PARENT_SOURCE_KEY PidTagParentSourceKey #define PR_PARENT_SOURCE_KEY_ERROR PROP_TAG(PT_ERROR , 0x65E1) /* 0x65E1000A */ #define PR_PERSONAL_HOME_PAGE PROP_TAG(PT_STRING8 , 0x3A50) /* 0x3A50001E */ #define PR_PERSONAL_HOME_PAGE_ERROR PROP_TAG(PT_ERROR , 0x3A50) /* 0x3A50000A */ #define PR_PERSONAL_HOME_PAGE_UNICODE PROP_TAG(PT_UNICODE , 0x3A50) /* 0x3A50001F */ #define PR_POLICY_TAG PidTagPolicyTag #define PR_POLICY_TAG_ERROR PROP_TAG(PT_ERROR , 0x3019) /* 0x3019000A */ #define PR_POSTAL_ADDRESS PROP_TAG(PT_STRING8 , 0x3A15) /* 0x3A15001E */ #define PR_POSTAL_ADDRESS_ERROR PROP_TAG(PT_ERROR , 0x3A15) /* 0x3A15000A */ #define PR_POSTAL_ADDRESS_UNICODE PROP_TAG(PT_UNICODE , 0x3A15) /* 0x3A15001F */ #define PR_POSTAL_CODE PROP_TAG(PT_STRING8 , 0x3A2A) /* 0x3A2A001E */ #define PR_POSTAL_CODE_ERROR PROP_TAG(PT_ERROR , 0x3A2A) /* 0x3A2A000A */ #define PR_POSTAL_CODE_UNICODE PROP_TAG(PT_UNICODE , 0x3A2A) /* 0x3A2A001F */ #define PR_POST_OFFICE_BOX PROP_TAG(PT_STRING8 , 0x3A2B) /* 0x3A2B001E */ #define PR_POST_OFFICE_BOX_ERROR PROP_TAG(PT_ERROR , 0x3A2B) /* 0x3A2B000A */ #define PR_POST_OFFICE_BOX_UNICODE PROP_TAG(PT_UNICODE , 0x3A2B) /* 0x3A2B001F */ #define PR_PREDECESSOR_CHANGE_LIST PidTagPredecessorChangeList #define PR_PREDECESSOR_CHANGE_LIST_ERROR PROP_TAG(PT_ERROR , 0x65E3) /* 0x65E3000A */ #define PR_PRIMARY_FAX_NUMBER PROP_TAG(PT_STRING8 , 0x3A23) /* 0x3A23001E */ #define PR_PRIMARY_FAX_NUMBER_ERROR PROP_TAG(PT_ERROR , 0x3A23) /* 0x3A23000A */ #define PR_PRIMARY_FAX_NUMBER_UNICODE PROP_TAG(PT_UNICODE , 0x3A23) /* 0x3A23001F */ #define PR_PRIMARY_SEND_ACCT PROP_TAG(PT_STRING8 , 0x0E28) /* 0x0E28001E */ #define PR_PRIMARY_SEND_ACCT_ERROR PROP_TAG(PT_ERROR , 0x0E28) /* 0x0E28000A */ #define PR_PRIMARY_SEND_ACCT_UNICODE PROP_TAG(PT_UNICODE , 0x0E28) /* 0x0E28001F */ #define PR_PRIMARY_TELEPHONE_NUMBER PROP_TAG(PT_STRING8 , 0x3A1A) /* 0x3A1A001E */ #define PR_PRIMARY_TELEPHONE_NUMBER_ERROR PROP_TAG(PT_ERROR , 0x3A1A) /* 0x3A1A000A */ #define PR_PRIMARY_TELEPHONE_NUMBER_UNICODE PROP_TAG(PT_UNICODE , 0x3A1A) /* 0x3A1A001F */ #define PR_PRIORITY PidTagPriority #define PR_PRIORITY_ERROR PROP_TAG(PT_ERROR , 0x0026) /* 0x0026000A */ #define PR_PROCESSED PidTagProcessed #define PR_PROCESSED_ERROR PROP_TAG(PT_ERROR , 0x7D01) /* 0x7D01000A */ #define PR_PROFESSION PROP_TAG(PT_STRING8 , 0x3A46) /* 0x3A46001E */ #define PR_PROFESSION_ERROR PROP_TAG(PT_ERROR , 0x3A46) /* 0x3A46000A */ #define PR_PROFESSION_UNICODE PROP_TAG(PT_UNICODE , 0x3A46) /* 0x3A46001F */ #define PR_PROFILE_HOME_SERVER_ADDRS 0x6613101e #define PR_PROHIBIT_RECEIVE_QUOTA PidTagProhibitReceiveQuota #define PR_PROHIBIT_RECEIVE_QUOTA_ERROR PROP_TAG(PT_ERROR , 0x666A) /* 0x666A000A */ #define PR_PROHIBIT_SEND_QUOTA PidTagProhibitSendQuota #define PR_PROHIBIT_SEND_QUOTA_ERROR PROP_TAG(PT_ERROR , 0x666E) /* 0x666E000A */ #define PR_PROVIDER_SUBMIT_TIME PidTagProviderSubmitTime #define PR_PROVIDER_SUBMIT_TIME_ERROR PROP_TAG(PT_ERROR , 0x0048) /* 0x0048000A */ #define PR_PURPORTED_SENDER_DOMAIN PROP_TAG(PT_STRING8 , 0x4083) /* 0x4083001E */ #define PR_PURPORTED_SENDER_DOMAIN_ERROR PROP_TAG(PT_ERROR , 0x4083) /* 0x4083000A */ #define PR_PURPORTED_SENDER_DOMAIN_UNICODE PROP_TAG(PT_UNICODE , 0x4083) /* 0x4083001F */ #define PR_RADIO_TELEPHONE_NUMBER PROP_TAG(PT_STRING8 , 0x3A1D) /* 0x3A1D001E */ #define PR_RADIO_TELEPHONE_NUMBER_ERROR PROP_TAG(PT_ERROR , 0x3A1D) /* 0x3A1D000A */ #define PR_RADIO_TELEPHONE_NUMBER_UNICODE PROP_TAG(PT_UNICODE , 0x3A1D) /* 0x3A1D001F */ #define PR_RCVD_REPRESENTING_ADDRTYPE PROP_TAG(PT_STRING8 , 0x0077) /* 0x0077001E */ #define PR_RCVD_REPRESENTING_ADDRTYPE_ERROR PROP_TAG(PT_ERROR , 0x0077) /* 0x0077000A */ #define PR_RCVD_REPRESENTING_ADDRTYPE_UNICODE PROP_TAG(PT_UNICODE , 0x0077) /* 0x0077001F */ #define PR_RCVD_REPRESENTING_EMAIL_ADDRESS PROP_TAG(PT_STRING8 , 0x0078) /* 0x0078001E */ #define PR_RCVD_REPRESENTING_EMAIL_ADDRESS_ERROR PROP_TAG(PT_ERROR , 0x0078) /* 0x0078000A */ #define PR_RCVD_REPRESENTING_EMAIL_ADDRESS_UNICODE PROP_TAG(PT_UNICODE , 0x0078) /* 0x0078001F */ #define PR_RCVD_REPRESENTING_ENTRYID PidTagReceivedRepresentingEntryId #define PR_RCVD_REPRESENTING_ENTRYID_ERROR PROP_TAG(PT_ERROR , 0x0043) /* 0x0043000A */ #define PR_RCVD_REPRESENTING_NAME PROP_TAG(PT_STRING8 , 0x0044) /* 0x0044001E */ #define PR_RCVD_REPRESENTING_NAME_ERROR PROP_TAG(PT_ERROR , 0x0044) /* 0x0044000A */ #define PR_RCVD_REPRESENTING_NAME_UNICODE PROP_TAG(PT_UNICODE , 0x0044) /* 0x0044001F */ #define PR_RCVD_REPRESENTING_SEARCH_KEY PidTagReceivedRepresentingSearchKey #define PR_RCVD_REPRESENTING_SEARCH_KEY_ERROR PROP_TAG(PT_ERROR , 0x0052) /* 0x0052000A */ #define PR_READ PidTagRead #define PR_READ_ERROR PROP_TAG(PT_ERROR , 0x0E69) /* 0x0E69000A */ #define PR_READ_RECEIPT_ENTRYID PidTagReadReceiptEntryId #define PR_READ_RECEIPT_ENTRYID_ERROR PROP_TAG(PT_ERROR , 0x0046) /* 0x0046000A */ #define PR_READ_RECEIPT_REQUESTED PidTagReadReceiptRequested #define PR_READ_RECEIPT_REQUESTED_ERROR PROP_TAG(PT_ERROR , 0x0029) /* 0x0029000A */ #define PR_READ_RECEIPT_SEARCH_KEY PidTagReadReceiptSearchKey #define PR_READ_RECEIPT_SEARCH_KEY_ERROR PROP_TAG(PT_ERROR , 0x0053) /* 0x0053000A */ #define PR_RECEIVED_BY_ADDRTYPE PROP_TAG(PT_STRING8 , 0x0075) /* 0x0075001E */ #define PR_RECEIVED_BY_ADDRTYPE_ERROR PROP_TAG(PT_ERROR , 0x0075) /* 0x0075000A */ #define PR_RECEIVED_BY_ADDRTYPE_UNICODE PROP_TAG(PT_UNICODE , 0x0075) /* 0x0075001F */ #define PR_RECEIVED_BY_EMAIL_ADDRESS PROP_TAG(PT_STRING8 , 0x0076) /* 0x0076001E */ #define PR_RECEIVED_BY_EMAIL_ADDRESS_ERROR PROP_TAG(PT_ERROR , 0x0076) /* 0x0076000A */ #define PR_RECEIVED_BY_EMAIL_ADDRESS_UNICODE PROP_TAG(PT_UNICODE , 0x0076) /* 0x0076001F */ #define PR_RECEIVED_BY_ENTRYID PidTagReceivedByEntryId #define PR_RECEIVED_BY_ENTRYID_ERROR PROP_TAG(PT_ERROR , 0x003F) /* 0x003F000A */ #define PR_RECEIVED_BY_NAME PROP_TAG(PT_STRING8 , 0x0040) /* 0x0040001E */ #define PR_RECEIVED_BY_NAME_ERROR PROP_TAG(PT_ERROR , 0x0040) /* 0x0040000A */ #define PR_RECEIVED_BY_NAME_UNICODE PROP_TAG(PT_UNICODE , 0x0040) /* 0x0040001F */ #define PR_RECEIVED_BY_SEARCH_KEY PidTagReceivedBySearchKey #define PR_RECEIVED_BY_SEARCH_KEY_ERROR PROP_TAG(PT_ERROR , 0x0051) /* 0x0051000A */ #define PR_RECIPIENT_DISPLAY_NAME PROP_TAG(PT_STRING8 , 0x5FF6) /* 0x5FF6001E */ #define PR_RECIPIENT_DISPLAY_NAME_ERROR PROP_TAG(PT_ERROR , 0x5FF6) /* 0x5FF6000A */ #define PR_RECIPIENT_DISPLAY_NAME_UNICODE PROP_TAG(PT_UNICODE , 0x5FF6) /* 0x5FF6001F */ #define PR_RECIPIENT_ENTRYID PidTagRecipientEntryId #define PR_RECIPIENT_ENTRYID_ERROR PROP_TAG(PT_ERROR , 0x5FF7) /* 0x5FF7000A */ #define PR_RECIPIENT_FLAGS PidTagRecipientFlags #define PR_RECIPIENT_FLAGS_ERROR PROP_TAG(PT_ERROR , 0x5FFD) /* 0x5FFD000A */ #define PR_RECIPIENT_ON_NORMAL_MSG_COUNT 0x66af0003 #define PR_RECIPIENT_ORDER PidTagRecipientOrder #define PR_RECIPIENT_ORDER_ERROR PROP_TAG(PT_ERROR , 0x5FDF) /* 0x5FDF000A */ #define PR_RECIPIENT_PROPOSED PidTagRecipientProposed #define PR_RECIPIENT_PROPOSEDENDTIME PidTagRecipientProposedEndTime #define PR_RECIPIENT_PROPOSEDENDTIME_ERROR PROP_TAG(PT_ERROR , 0x5FE4) /* 0x5FE4000A */ #define PR_RECIPIENT_PROPOSEDSTARTTIME PidTagRecipientProposedStartTime #define PR_RECIPIENT_PROPOSEDSTARTTIME_ERROR PROP_TAG(PT_ERROR , 0x5FE3) /* 0x5FE3000A */ #define PR_RECIPIENT_PROPOSED_ERROR PROP_TAG(PT_ERROR , 0x5FE1) /* 0x5FE1000A */ #define PR_RECIPIENT_REASSIGNMENT_PROHIBITED PidTagRecipientReassignmentProhibited #define PR_RECIPIENT_REASSIGNMENT_PROHIBITED_ERROR PROP_TAG(PT_ERROR , 0x002B) /* 0x002B000A */ #define PR_RECIPIENT_RESOURCESTATE PidTagRecipientResourceState #define PR_RECIPIENT_RESOURCESTATE_ERROR PROP_TAG(PT_ERROR , 0x5FDE) /* 0x5FDE000A */ #define PR_RECIPIENT_TRACKSTATUS PidTagRecipientTrackStatus #define PR_RECIPIENT_TRACKSTATUS_ERROR PROP_TAG(PT_ERROR , 0x5FFF) /* 0x5FFF000A */ #define PR_RECIPIENT_TRACKSTATUS_TIME PidTagRecipientTrackStatusTime #define PR_RECIPIENT_TRACKSTATUS_TIME_ERROR PROP_TAG(PT_ERROR , 0x5FFB) /* 0x5FFB000A */ #define PR_RECIPIENT_TYPE PidTagRecipientType #define PR_RECIPIENT_TYPE_ERROR PROP_TAG(PT_ERROR , 0x0C15) /* 0x0C15000A */ #define PR_RECORD_KEY PidTagRecordKey #define PR_RECORD_KEY_ERROR PROP_TAG(PT_ERROR , 0x0FF9) /* 0x0FF9000A */ #define PR_REFERRED_BY_NAME PROP_TAG(PT_STRING8 , 0x3A47) /* 0x3A47001E */ #define PR_REFERRED_BY_NAME_ERROR PROP_TAG(PT_ERROR , 0x3A47) /* 0x3A47000A */ #define PR_REFERRED_BY_NAME_UNICODE PROP_TAG(PT_UNICODE , 0x3A47) /* 0x3A47001F */ #define PR_REMINDERS_ONLINE_ENTRYID 0x36d50102 #define PR_REMOTE_HEADER_LOC PROP_TAG(PT_STRING8 , 0x0078) /* 0x0078001E */ #define PR_REMOTE_HEADER_LOC_ERROR PROP_TAG(PT_ERROR , 0x0078) /* 0x0078000A */ #define PR_REMOTE_HEADER_LOC_UNICODE PROP_TAG(PT_UNICODE , 0x0078) /* 0x0078001F */ #define PR_REM_ONLINE_ENTRYID PidTagRemindersOnlineEntryId #define PR_REM_ONLINE_ENTRYID_ERROR PROP_TAG(PT_ERROR , 0x36D5) /* 0x36D5000A */ #define PR_RENDERING_POSITION PidTagRenderingPosition #define PR_RENDERING_POSITION_ERROR PROP_TAG(PT_ERROR , 0x370B) /* 0x370B000A */ #define PR_REPLY_RECIPIENT_ENTRIES PidTagReplyRecipientEntries #define PR_REPLY_RECIPIENT_ENTRIES_ERROR PROP_TAG(PT_ERROR , 0x004F) /* 0x004F000A */ #define PR_REPLY_RECIPIENT_NAMES PROP_TAG(PT_STRING8 , 0x0050) /* 0x0050001E */ #define PR_REPLY_RECIPIENT_NAMES_ERROR PROP_TAG(PT_ERROR , 0x0050) /* 0x0050000A */ #define PR_REPLY_RECIPIENT_NAMES_UNICODE PROP_TAG(PT_UNICODE , 0x0050) /* 0x0050001F */ #define PR_REPLY_REQUESTED PidTagReplyRequested #define PR_REPLY_REQUESTED_ERROR PROP_TAG(PT_ERROR , 0x0C17) /* 0x0C17000A */ #define PR_REPLY_TEMPLATE_ID PidTagReplyTemplateId #define PR_REPLY_TEMPLATE_ID_ERROR PROP_TAG(PT_ERROR , 0x65C2) /* 0x65C2000A */ #define PR_REPLY_TIME PidTagReplyTime #define PR_REPLY_TIME_ERROR PROP_TAG(PT_ERROR , 0x0030) /* 0x0030000A */ #define PR_REPORT_ENTRYID PidTagReportEntryId #define PR_REPORT_ENTRYID_ERROR PROP_TAG(PT_ERROR , 0x0045) /* 0x0045000A */ #define PR_REPORT_NAME PROP_TAG(PT_STRING8 , 0x003A) /* 0x003A001E */ #define PR_REPORT_NAME_ERROR PROP_TAG(PT_ERROR , 0x003A) /* 0x003A000A */ #define PR_REPORT_NAME_UNICODE PROP_TAG(PT_UNICODE , 0x003A) /* 0x003A001F */ #define PR_REPORT_SEARCH_KEY PidTagReportSearchKey #define PR_REPORT_SEARCH_KEY_ERROR PROP_TAG(PT_ERROR , 0x0054) /* 0x0054000A */ #define PR_REPORT_TAG PidTagReportTag #define PR_REPORT_TAG_ERROR PROP_TAG(PT_ERROR , 0x0031) /* 0x0031000A */ #define PR_REPORT_TEXT PROP_TAG(PT_STRING8 , 0x1001) /* 0x1001001E */ #define PR_REPORT_TEXT_ERROR PROP_TAG(PT_ERROR , 0x1001) /* 0x1001000A */ #define PR_REPORT_TEXT_UNICODE PROP_TAG(PT_UNICODE , 0x1001) /* 0x1001001F */ #define PR_REPORT_TIME PidTagReportTime #define PR_REPORT_TIME_ERROR PROP_TAG(PT_ERROR , 0x0032) /* 0x0032000A */ #define PR_RESOLVE_METHOD PidTagResolveMethod #define PR_RESOLVE_METHOD_ERROR PROP_TAG(PT_ERROR , 0x3FE7) /* 0x3FE7000A */ #define PR_RESPONSE_REQUESTED PidTagResponseRequested #define PR_RESPONSE_REQUESTED_ERROR PROP_TAG(PT_ERROR , 0x0063) /* 0x0063000A */ #define PR_RESPONSIBILITY PidTagResponsibility #define PR_RESPONSIBILITY_ERROR PROP_TAG(PT_ERROR , 0x0E0F) /* 0x0E0F000A */ #define PR_RETENTION_DATE PidTagRetentionDate #define PR_RETENTION_DATE_ERROR PROP_TAG(PT_ERROR , 0x301C) /* 0x301C000A */ #define PR_RETENTION_FLAGS PidTagRetentionFlags #define PR_RETENTION_FLAGS_ERROR PROP_TAG(PT_ERROR , 0x301D) /* 0x301D000A */ #define PR_RETENTION_PERIOD PidTagRetentionPeriod #define PR_RETENTION_PERIOD_ERROR PROP_TAG(PT_ERROR , 0x301A) /* 0x301A000A */ #define PR_RIGHTS PidTagRights #define PR_RIGHTS_ERROR PROP_TAG(PT_ERROR , 0x6639) /* 0x6639000A */ #define PR_ROAMING_DATATYPES PidTagRoamingDatatypes #define PR_ROAMING_DATATYPES_ERROR PROP_TAG(PT_ERROR , 0x7C06) /* 0x7C06000A */ #define PR_ROAMING_DICTIONARY PidTagRoamingDictionary #define PR_ROAMING_DICTIONARY_ERROR PROP_TAG(PT_ERROR , 0x7C07) /* 0x7C07000A */ #define PR_ROAMING_XMLSTREAM PidTagRoamingXmlStream #define PR_ROAMING_XMLSTREAM_ERROR PROP_TAG(PT_ERROR , 0x7C08) /* 0x7C08000A */ #define PR_ROWID PidTagRowid #define PR_ROWID_ERROR PROP_TAG(PT_ERROR , 0x3000) /* 0x3000000A */ #define PR_ROW_TYPE PidTagRowType #define PR_ROW_TYPE_ERROR PROP_TAG(PT_ERROR , 0x0FF5) /* 0x0FF5000A */ #define PR_RTF_COMPRESSED PidTagRtfCompressed #define PR_RTF_COMPRESSED_ERROR PROP_TAG(PT_ERROR , 0x1009) /* 0x1009000A */ #define PR_RTF_IN_SYNC PidTagRtfInSync #define PR_RTF_IN_SYNC_ERROR PROP_TAG(PT_ERROR , 0x0E1F) /* 0x0E1F000A */ #define PR_RTF_SYNC_BODY_COUNT PidTagRtfSyncBodyCount #define PR_RTF_SYNC_BODY_COUNT_ERROR PROP_TAG(PT_ERROR , 0x1007) /* 0x1007000A */ #define PR_RTF_SYNC_BODY_CRC PidTagRtfSyncBodyCrc #define PR_RTF_SYNC_BODY_CRC_ERROR PROP_TAG(PT_ERROR , 0x1006) /* 0x1006000A */ #define PR_RTF_SYNC_BODY_TAG PROP_TAG(PT_STRING8 , 0x1008) /* 0x1008001E */ #define PR_RTF_SYNC_BODY_TAG_ERROR PROP_TAG(PT_ERROR , 0x1008) /* 0x1008000A */ #define PR_RTF_SYNC_BODY_TAG_UNICODE PROP_TAG(PT_UNICODE , 0x1008) /* 0x1008001F */ #define PR_RTF_SYNC_PREFIX_COUNT PidTagRtfSyncPrefixCount #define PR_RTF_SYNC_PREFIX_COUNT_ERROR PROP_TAG(PT_ERROR , 0x1010) /* 0x1010000A */ #define PR_RTF_SYNC_TRAILING_COUNT PidTagRtfSyncTrailingCount #define PR_RTF_SYNC_TRAILING_COUNT_ERROR PROP_TAG(PT_ERROR , 0x1011) /* 0x1011000A */ #define PR_RULE_ACTIONS PidTagRuleActions #define PR_RULE_ACTIONS_ERROR PROP_TAG(PT_ERROR , 0x6680) /* 0x6680000A */ #define PR_RULE_ACTION_NUMBER PidTagRuleActionNumber #define PR_RULE_ACTION_NUMBER_ERROR PROP_TAG(PT_ERROR , 0x6650) /* 0x6650000A */ #define PR_RULE_ACTION_TYPE PidTagRuleActionType #define PR_RULE_ACTION_TYPE_ERROR PROP_TAG(PT_ERROR , 0x6649) /* 0x6649000A */ #define PR_RULE_CONDITION PidTagRuleCondition #define PR_RULE_CONDITION_ERROR PROP_TAG(PT_ERROR , 0x6679) /* 0x6679000A */ #define PR_RULE_ERROR PidTagRuleError #define PR_RULE_ERROR_ERROR PROP_TAG(PT_ERROR , 0x6648) /* 0x6648000A */ #define PR_RULE_FOLDER_ENTRYID PidTagRuleFolderEntryId #define PR_RULE_FOLDER_ENTRYID_ERROR PROP_TAG(PT_ERROR , 0x6651) /* 0x6651000A */ #define PR_RULE_ID PidTagRuleId #define PR_RULE_IDS PidTagRuleIds #define PR_RULE_IDS_ERROR PROP_TAG(PT_ERROR , 0x6675) /* 0x6675000A */ #define PR_RULE_ID_ERROR PROP_TAG(PT_ERROR , 0x6674) /* 0x6674000A */ #define PR_RULE_LEVEL PidTagRuleLevel #define PR_RULE_LEVEL_ERROR PROP_TAG(PT_ERROR , 0x6683) /* 0x6683000A */ #define PR_RULE_MSG_LEVEL PidTagRuleMessageLevel #define PR_RULE_MSG_LEVEL_ERROR PROP_TAG(PT_ERROR , 0x65ED) /* 0x65ED000A */ #define PR_RULE_MSG_NAME 0x65ec001e #define PR_RULE_MSG_PROVIDER 0x65eb001e #define PR_RULE_MSG_PROVIDER_DATA PidTagRuleMessageProviderData #define PR_RULE_MSG_PROVIDER_DATA_ERROR PROP_TAG(PT_ERROR , 0x65EE) /* 0x65EE000A */ #define PR_RULE_MSG_SEQUENCE PidTagRuleMessageSequence #define PR_RULE_MSG_SEQUENCE_ERROR PROP_TAG(PT_ERROR , 0x65F3) /* 0x65F3000A */ #define PR_RULE_MSG_STATE PidTagRuleMessageState #define PR_RULE_MSG_STATE_ERROR PROP_TAG(PT_ERROR , 0x65E9) /* 0x65E9000A */ #define PR_RULE_MSG_USER_FLAGS PidTagRuleMessageUserFlags #define PR_RULE_MSG_USER_FLAGS_ERROR PROP_TAG(PT_ERROR , 0x65EA) /* 0x65EA000A */ #define PR_RULE_NAME PROP_TAG(PT_STRING8 , 0x6682) /* 0x6682001E */ #define PR_RULE_NAME_ERROR PROP_TAG(PT_ERROR , 0x6682) /* 0x6682000A */ #define PR_RULE_NAME_UNICODE PROP_TAG(PT_UNICODE , 0x6682) /* 0x6682001F */ #define PR_RULE_PROVIDER PROP_TAG(PT_STRING8 , 0x6681) /* 0x6681001E */ #define PR_RULE_PROVIDER_DATA PidTagRuleProviderData #define PR_RULE_PROVIDER_DATA_ERROR PROP_TAG(PT_ERROR , 0x6684) /* 0x6684000A */ #define PR_RULE_PROVIDER_ERROR PROP_TAG(PT_ERROR , 0x6681) /* 0x6681000A */ #define PR_RULE_PROVIDER_UNICODE PROP_TAG(PT_UNICODE , 0x6681) /* 0x6681001F */ #define PR_RULE_SEQUENCE PidTagRuleSequence #define PR_RULE_SEQUENCE_ERROR PROP_TAG(PT_ERROR , 0x6676) /* 0x6676000A */ #define PR_RULE_STATE PidTagRuleState #define PR_RULE_STATE_ERROR PROP_TAG(PT_ERROR , 0x6677) /* 0x6677000A */ #define PR_RULE_USER_FLAGS PidTagRuleUserFlags #define PR_RULE_USER_FLAGS_ERROR PROP_TAG(PT_ERROR , 0x6678) /* 0x6678000A */ #define PR_RW_RULES_STREAM PidTagRwRulesStream #define PR_RW_RULES_STREAM_ERROR PROP_TAG(PT_ERROR , 0x6802) /* 0x6802000A */ #define PR_SCHDINFO_APPT_TOMBSTONE PidTagScheduleInfoAppointmentTombstone #define PR_SCHDINFO_APPT_TOMBSTONE_ERROR PROP_TAG(PT_ERROR , 0x686A) /* 0x686A000A */ #define PR_SCHDINFO_AUTO_ACCEPT_APPTS PidTagScheduleInfoAutoAcceptAppointments #define PR_SCHDINFO_AUTO_ACCEPT_APPTS_ERROR PROP_TAG(PT_ERROR , 0x686D) /* 0x686D000A */ #define PR_SCHDINFO_BOSS_WANTS_COPY PidTagScheduleInfoDelegatorWantsCopy #define PR_SCHDINFO_BOSS_WANTS_COPY_ERROR PROP_TAG(PT_ERROR , 0x6842) /* 0x6842000A */ #define PR_SCHDINFO_BOSS_WANTS_INFO PidTagScheduleInfoDelegatorWantsInfo #define PR_SCHDINFO_BOSS_WANTS_INFO_ERROR PROP_TAG(PT_ERROR , 0x684B) /* 0x684B000A */ #define PR_SCHDINFO_DELEGATE_ENTRYIDS PidTagScheduleInfoDelegateEntryIds #define PR_SCHDINFO_DELEGATE_ENTRYIDS_ERROR PROP_TAG(PT_ERROR , 0x6845) /* 0x6845000A */ #define PR_SCHDINFO_DELEGATE_NAMES PROP_TAG(PT_MV_STRING8, 0x6844) /* 0x6844101E */ #define PR_SCHDINFO_DELEGATE_NAMES_ERROR PROP_TAG(PT_ERROR , 0x6844) /* 0x6844000A */ #define PR_SCHDINFO_DELEGATE_NAMES_UNICODE PROP_TAG(PT_MV_UNICODE, 0x6844) /* 0x6844101F */ #define PR_SCHDINFO_DISALLOW_OVERLAPPING_APPTS PidTagScheduleInfoDisallowOverlappingAppts #define PR_SCHDINFO_DISALLOW_OVERLAPPING_APPTS_ERROR PROP_TAG(PT_ERROR , 0x686F) /* 0x686F000A */ #define PR_SCHDINFO_DISALLOW_RECURRING_APPTS PidTagScheduleInfoDisallowRecurringAppts #define PR_SCHDINFO_DISALLOW_RECURRING_APPTS_ERROR PROP_TAG(PT_ERROR , 0x686E) /* 0x686E000A */ #define PR_SCHDINFO_DONT_MAIL_DELEGATES PidTagScheduleInfoDontMailDelegates #define PR_SCHDINFO_DONT_MAIL_DELEGATES_ERROR PROP_TAG(PT_ERROR , 0x6843) /* 0x6843000A */ #define PR_SCHDINFO_FREEBUSY PidTagScheduleInfoFreeBusy #define PR_SCHDINFO_FREEBUSY_BUSY PidTagScheduleInfoFreeBusyBusy #define PR_SCHDINFO_FREEBUSY_BUSY_ERROR PROP_TAG(PT_ERROR , 0x6854) /* 0x6854000A */ #define PR_SCHDINFO_FREEBUSY_ERROR PROP_TAG(PT_ERROR , 0x686C) /* 0x686C000A */ #define PR_SCHDINFO_FREEBUSY_MERGED PidTagScheduleInfoFreeBusyMerged #define PR_SCHDINFO_FREEBUSY_MERGED_ERROR PROP_TAG(PT_ERROR , 0x6850) /* 0x6850000A */ #define PR_SCHDINFO_FREEBUSY_OOF PidTagScheduleInfoFreeBusyAway #define PR_SCHDINFO_FREEBUSY_OOF_ERROR PROP_TAG(PT_ERROR , 0x6856) /* 0x6856000A */ #define PR_SCHDINFO_FREEBUSY_TENTATIVE PidTagScheduleInfoFreeBusyTentative #define PR_SCHDINFO_FREEBUSY_TENTATIVE_ERROR PROP_TAG(PT_ERROR , 0x6852) /* 0x6852000A */ #define PR_SCHDINFO_MONTHS_BUSY PidTagScheduleInfoMonthsBusy #define PR_SCHDINFO_MONTHS_BUSY_ERROR PROP_TAG(PT_ERROR , 0x6853) /* 0x6853000A */ #define PR_SCHDINFO_MONTHS_MERGED PidTagScheduleInfoMonthsMerged #define PR_SCHDINFO_MONTHS_MERGED_ERROR PROP_TAG(PT_ERROR , 0x684F) /* 0x684F000A */ #define PR_SCHDINFO_MONTHS_OOF PidTagScheduleInfoMonthsAway #define PR_SCHDINFO_MONTHS_OOF_ERROR PROP_TAG(PT_ERROR , 0x6855) /* 0x6855000A */ #define PR_SCHDINFO_MONTHS_TENTATIVE PidTagScheduleInfoMonthsTentative #define PR_SCHDINFO_MONTHS_TENTATIVE_ERROR PROP_TAG(PT_ERROR , 0x6851) /* 0x6851000A */ #define PR_SCHDINFO_RESOURCE_TYPE PidTagScheduleInfoResourceType #define PR_SCHDINFO_RESOURCE_TYPE_ERROR PROP_TAG(PT_ERROR , 0x6841) /* 0x6841000A */ #define PR_SEARCH_KEY PidTagSearchKey #define PR_SEARCH_KEY_ERROR PROP_TAG(PT_ERROR , 0x300B) /* 0x300B000A */ #define PR_SECURE_SUBMIT_FLAGS PidTagSecureSubmitFlags #define PR_SECURE_SUBMIT_FLAGS_ERROR PROP_TAG(PT_ERROR , 0x65C6) /* 0x65C6000A */ #define PR_SELECTABLE PidTagSelectable #define PR_SELECTABLE_ERROR PROP_TAG(PT_ERROR , 0x3609) /* 0x3609000A */ #define PR_SENDER_ADDRTYPE PROP_TAG(PT_STRING8 , 0x0C1E) /* 0x0C1E001E */ #define PR_SENDER_ADDRTYPE_ERROR PROP_TAG(PT_ERROR , 0x0C1E) /* 0x0C1E000A */ #define PR_SENDER_ADDRTYPE_UNICODE PROP_TAG(PT_UNICODE , 0x0C1E) /* 0x0C1E001F */ #define PR_SENDER_EMAIL_ADDRESS PROP_TAG(PT_STRING8 , 0x0C1F) /* 0x0C1F001E */ #define PR_SENDER_EMAIL_ADDRESS_ERROR PROP_TAG(PT_ERROR , 0x0C1F) /* 0x0C1F000A */ #define PR_SENDER_EMAIL_ADDRESS_UNICODE PROP_TAG(PT_UNICODE , 0x0C1F) /* 0x0C1F001F */ #define PR_SENDER_ENTRYID PidTagSenderEntryId #define PR_SENDER_ENTRYID_ERROR PROP_TAG(PT_ERROR , 0x0C19) /* 0x0C19000A */ #define PR_SENDER_ID_STATUS PidTagSenderIdStatus #define PR_SENDER_ID_STATUS_ERROR PROP_TAG(PT_ERROR , 0x4079) /* 0x4079000A */ #define PR_SENDER_NAME PROP_TAG(PT_STRING8 , 0x0C1A) /* 0x0C1A001E */ #define PR_SENDER_NAME_ERROR PROP_TAG(PT_ERROR , 0x0C1A) /* 0x0C1A000A */ #define PR_SENDER_NAME_UNICODE PROP_TAG(PT_UNICODE , 0x0C1A) /* 0x0C1A001F */ #define PR_SENDER_SEARCH_KEY PidTagSenderSearchKey #define PR_SENDER_SEARCH_KEY_ERROR PROP_TAG(PT_ERROR , 0x0C1D) /* 0x0C1D000A */ #define PR_SEND_INTERNET_ENCODING PidTagSendInternetEncoding #define PR_SEND_INTERNET_ENCODING_ERROR PROP_TAG(PT_ERROR , 0x3A71) /* 0x3A71000A */ #define PR_SEND_RICH_INFO PidTagSendRichInfo #define PR_SEND_RICH_INFO_ERROR PROP_TAG(PT_ERROR , 0x3A40) /* 0x3A40000A */ #define PR_SENSITIVITY PidTagSensitivity #define PR_SENSITIVITY_ERROR PROP_TAG(PT_ERROR , 0x0036) /* 0x0036000A */ #define PR_SENT_REPRESENTING_ADDRTYPE PROP_TAG(PT_STRING8 , 0x0064) /* 0x0064001E */ #define PR_SENT_REPRESENTING_ADDRTYPE_ERROR PROP_TAG(PT_ERROR , 0x0064) /* 0x0064000A */ #define PR_SENT_REPRESENTING_ADDRTYPE_UNICODE PROP_TAG(PT_UNICODE , 0x0064) /* 0x0064001F */ #define PR_SENT_REPRESENTING_EMAIL_ADDRESS PROP_TAG(PT_STRING8 , 0x0065) /* 0x0065001E */ #define PR_SENT_REPRESENTING_EMAIL_ADDRESS_ERROR PROP_TAG(PT_ERROR , 0x0065) /* 0x0065000A */ #define PR_SENT_REPRESENTING_EMAIL_ADDRESS_UNICODE PROP_TAG(PT_UNICODE , 0x0065) /* 0x0065001F */ #define PR_SENT_REPRESENTING_ENTRYID PidTagSentRepresentingEntryId #define PR_SENT_REPRESENTING_ENTRYID_ERROR PROP_TAG(PT_ERROR , 0x0041) /* 0x0041000A */ #define PR_SENT_REPRESENTING_NAME PROP_TAG(PT_STRING8 , 0x0042) /* 0x0042001E */ #define PR_SENT_REPRESENTING_NAME_ERROR PROP_TAG(PT_ERROR , 0x0042) /* 0x0042000A */ #define PR_SENT_REPRESENTING_NAME_UNICODE PROP_TAG(PT_UNICODE , 0x0042) /* 0x0042001F */ #define PR_SENT_REPRESENTING_SEARCH_KEY PidTagSentRepresentingSearchKey #define PR_SENT_REPRESENTING_SEARCH_KEY_ERROR PROP_TAG(PT_ERROR , 0x003B) /* 0x003B000A */ #define PR_SMTP_ADDRESS PROP_TAG(PT_STRING8 , 0x39FE) /* 0x39FE001E */ #define PR_SMTP_ADDRESS_ERROR PROP_TAG(PT_ERROR , 0x39FE) /* 0x39FE000A */ #define PR_SMTP_ADDRESS_UNICODE PROP_TAG(PT_UNICODE , 0x39FE) /* 0x39FE001F */ #define PR_SORT_LOCALE_ID PidTagSortLocaleId #define PR_SORT_LOCALE_ID_ERROR PROP_TAG(PT_ERROR , 0x6705) /* 0x6705000A */ #define PR_SOURCE_KEY PidTagSourceKey #define PR_SOURCE_KEY_ERROR PROP_TAG(PT_ERROR , 0x65E0) /* 0x65E0000A */ #define PR_SPLUS_FREE_BUSY_ENTRYID PidTagSchedulePlusFreeBusyEntryId #define PR_SPLUS_FREE_BUSY_ENTRYID_ERROR PROP_TAG(PT_ERROR , 0x6622) /* 0x6622000A */ #define PR_SPOUSE_NAME PROP_TAG(PT_STRING8 , 0x3A48) /* 0x3A48001E */ #define PR_SPOUSE_NAME_ERROR PROP_TAG(PT_ERROR , 0x3A48) /* 0x3A48000A */ #define PR_SPOUSE_NAME_UNICODE PROP_TAG(PT_UNICODE , 0x3A48) /* 0x3A48001F */ #define PR_START_DATE PidTagStartDate #define PR_START_DATE_ERROR PROP_TAG(PT_ERROR , 0x0060) /* 0x0060000A */ #define PR_START_DATE_ETC PidTagStartDateEtc #define PR_START_DATE_ETC_ERROR PROP_TAG(PT_ERROR , 0x301B) /* 0x301B000A */ #define PR_START_RECIP PidTagStartRecip #define PR_STATE_OR_PROVINCE PROP_TAG(PT_STRING8 , 0x3A28) /* 0x3A28001E */ #define PR_STATE_OR_PROVINCE_ERROR PROP_TAG(PT_ERROR , 0x3A28) /* 0x3A28000A */ #define PR_STATE_OR_PROVINCE_UNICODE PROP_TAG(PT_UNICODE , 0x3A28) /* 0x3A28001F */ #define PR_STORE_ENTRYID PidTagStoreEntryId #define PR_STORE_ENTRYID_ERROR PROP_TAG(PT_ERROR , 0x0FFB) /* 0x0FFB000A */ #define PR_STORE_STATE PidTagStoreState #define PR_STORE_STATE_ERROR PROP_TAG(PT_ERROR , 0x340E) /* 0x340E000A */ #define PR_STORE_SUPPORT_MASK PidTagStoreSupportMask #define PR_STORE_SUPPORT_MASK_ERROR PROP_TAG(PT_ERROR , 0x340D) /* 0x340D000A */ #define PR_STREET_ADDRESS PROP_TAG(PT_STRING8 , 0x3A29) /* 0x3A29001E */ #define PR_STREET_ADDRESS_ERROR PROP_TAG(PT_ERROR , 0x3A29) /* 0x3A29000A */ #define PR_STREET_ADDRESS_UNICODE PROP_TAG(PT_UNICODE , 0x3A29) /* 0x3A29001F */ #define PR_SUBFOLDER PidTagSubfolder #define PR_SUBFOLDERS PidTagSubfolders #define PR_SUBFOLDERS_ERROR PROP_TAG(PT_ERROR , 0x360A) /* 0x360A000A */ #define PR_SUBFOLDER_ERROR PROP_TAG(PT_ERROR , 0x6708) /* 0x6708000A */ #define PR_SUBJECT PROP_TAG(PT_STRING8 , 0x0037) /* 0x0037001E */ #define PR_SUBJECT_ERROR PROP_TAG(PT_ERROR , 0x0037) /* 0x0037000A */ #define PR_SUBJECT_PREFIX PROP_TAG(PT_STRING8 , 0x003D) /* 0x003D001E */ #define PR_SUBJECT_PREFIX_ERROR PROP_TAG(PT_ERROR , 0x003D) /* 0x003D000A */ #define PR_SUBJECT_PREFIX_UNICODE PROP_TAG(PT_UNICODE , 0x003D) /* 0x003D001F */ #define PR_SUBJECT_UNICODE PROP_TAG(PT_UNICODE , 0x0037) /* 0x0037001F */ #define PR_SURNAME PROP_TAG(PT_STRING8 , 0x3A11) /* 0x3A11001E */ #define PR_SURNAME_ERROR PROP_TAG(PT_ERROR , 0x3A11) /* 0x3A11000A */ #define PR_SURNAME_UNICODE PROP_TAG(PT_UNICODE , 0x3A11) /* 0x3A11001F */ #define PR_SWAPPED_TODO_DATA PidTagSwappedToDoData #define PR_SWAPPED_TODO_DATA_ERROR PROP_TAG(PT_ERROR , 0x0E2D) /* 0x0E2D000A */ #define PR_SWAPPED_TODO_STORE PidTagSwappedToDoStore #define PR_SWAPPED_TODO_STORE_ERROR PROP_TAG(PT_ERROR , 0x0E2C) /* 0x0E2C000A */ #define PR_TARGET_ENTRYID PidTagTargetEntryId #define PR_TARGET_ENTRYID_ERROR PROP_TAG(PT_ERROR , 0x3010) /* 0x3010000A */ #define PR_TCV_CONST_LONG_ONE PidTagTcvConstLongOne #define PR_TCV_CONST_LONG_ONE_ERROR PROP_TAG(PT_ERROR , 0x8008) /* 0x8008000A */ #define PR_TELEX_NUMBER PROP_TAG(PT_STRING8 , 0x3A2C) /* 0x3A2C001E */ #define PR_TELEX_NUMBER_ERROR PROP_TAG(PT_ERROR , 0x3A2C) /* 0x3A2C000A */ #define PR_TELEX_NUMBER_UNICODE PROP_TAG(PT_UNICODE , 0x3A2C) /* 0x3A2C001F */ #define PR_TEMPLATEID PidTagTemplateid #define PR_TEMPLATEID_ERROR PROP_TAG(PT_ERROR , 0x3902) /* 0x3902000A */ #define PR_TITLE PROP_TAG(PT_STRING8 , 0x3A17) /* 0x3A17001E */ #define PR_TITLE_ERROR PROP_TAG(PT_ERROR , 0x3A17) /* 0x3A17000A */ #define PR_TITLE_UNICODE PROP_TAG(PT_UNICODE , 0x3A17) /* 0x3A17001F */ #define PR_TNEF_CORRELATION_KEY PidTagTnefCorrelationKey #define PR_TNEF_CORRELATION_KEY_ERROR PROP_TAG(PT_ERROR , 0x007F) /* 0x007F000A */ #define PR_TODO_ITEM_FLAGS PidTagToDoItemFlags #define PR_TODO_ITEM_FLAGS_ERROR PROP_TAG(PT_ERROR , 0x0E2B) /* 0x0E2B000A */ #define PR_TRANSMITABLE_DISPLAY_NAME PROP_TAG(PT_STRING8 , 0x3A20) /* 0x3A20001E */ #define PR_TRANSMITABLE_DISPLAY_NAME_ERROR PROP_TAG(PT_ERROR , 0x3A20) /* 0x3A20000A */ #define PR_TRANSMITABLE_DISPLAY_NAME_UNICODE PROP_TAG(PT_UNICODE , 0x3A20) /* 0x3A20001F */ #define PR_TRANSMITTABLE_DISPLAY_NAME 0x3a20001e #define PR_TRANSMITTABLE_DISPLAY_NAME_UNICODE PidTagTransmittableDisplayName #define PR_TRANSPORT_MESSAGE_HEADERS PROP_TAG(PT_STRING8 , 0x007D) /* 0x007D001E */ #define PR_TRANSPORT_MESSAGE_HEADERS_ERROR PROP_TAG(PT_ERROR , 0x007D) /* 0x007D000A */ #define PR_TRANSPORT_MESSAGE_HEADERS_UNICODE PROP_TAG(PT_UNICODE , 0x007D) /* 0x007D001F */ #define PR_TRUST_SENDER PidTagTrustSender #define PR_TRUST_SENDER_ERROR PROP_TAG(PT_ERROR , 0x0E79) /* 0x0E79000A */ #define PR_TTYTDD_PHONE_NUMBER PROP_TAG(PT_STRING8 , 0x3A4B) /* 0x3A4B001E */ #define PR_TTYTDD_PHONE_NUMBER PROP_TAG(PT_STRING8 , 0x3A4B) /* 0x3A4B001E */ #define PR_TTYTDD_PHONE_NUMBER_ERROR PROP_TAG(PT_ERROR , 0x3A4B) /* 0x3A4B000A */ #define PR_TTYTDD_PHONE_NUMBER_ERROR PROP_TAG(PT_ERROR , 0x3A4B) /* 0x3A4B000A */ #define PR_TTYTDD_PHONE_NUMBER_UNICODE PROP_TAG(PT_UNICODE , 0x3A4B) /* 0x3A4B001F */ #define PR_TTYTDD_PHONE_NUMBER_UNICODE PROP_TAG(PT_UNICODE , 0x3A4B) /* 0x3A4B001F */ #define PR_URL_COMP_NAME PROP_TAG(PT_STRING8 , 0x10F3) /* 0x10F3001E */ #define PR_URL_COMP_NAME_ERROR PROP_TAG(PT_ERROR , 0x10F3) /* 0x10F3000A */ #define PR_URL_COMP_NAME_SET PidTagUrlCompNameSet #define PR_URL_COMP_NAME_UNICODE PROP_TAG(PT_UNICODE , 0x10F3) /* 0x10F3001F */ #define PR_URL_NAME PROP_TAG(PT_STRING8 , 0x6707) /* 0x6707001E */ #define PR_URL_NAME_ERROR PROP_TAG(PT_ERROR , 0x6707) /* 0x6707000A */ #define PR_URL_NAME_UNICODE PROP_TAG(PT_UNICODE , 0x6707) /* 0x6707001F */ #define PR_USER_CERTIFICATE PidTagUserCertificate #define PR_USER_CERTIFICATE_ERROR PROP_TAG(PT_ERROR , 0x3A22) /* 0x3A22000A */ #define PR_USER_ENTRYID PidTagUserEntryId #define PR_USER_ENTRYID_ERROR PROP_TAG(PT_ERROR , 0x6619) /* 0x6619000A */ #define PR_USER_X509_CERTIFICATE PidTagUserX509Certificate #define PR_USER_X509_CERTIFICATE_ERROR PROP_TAG(PT_ERROR , 0x3A70) /* 0x3A70000A */ #define PR_VD_BINARY PidTagViewDescriptorBinary #define PR_VD_BINARY_ERROR PROP_TAG(PT_ERROR , 0x7001) /* 0x7001000A */ #define PR_VD_NAME PROP_TAG(PT_STRING8 , 0x7006) /* 0x7006001E */ #define PR_VD_NAME_ERROR PROP_TAG(PT_ERROR , 0x7006) /* 0x7006000A */ #define PR_VD_NAME_UNICODE PROP_TAG(PT_UNICODE , 0x7006) /* 0x7006001F */ #define PR_VD_STRINGS PROP_TAG(PT_STRING8 , 0x7002) /* 0x7002001E */ #define PR_VD_STRINGS_ERROR PROP_TAG(PT_ERROR , 0x7002) /* 0x7002000A */ #define PR_VD_STRINGS_UNICODE PROP_TAG(PT_UNICODE , 0x7002) /* 0x7002001F */ #define PR_VD_VERSION PidTagViewDescriptorVersion #define PR_VD_VERSION_ERROR PROP_TAG(PT_ERROR , 0x7007) /* 0x7007000A */ #define PR_WB_SF_DEFINITION PidTagSearchFolderDefinition #define PR_WB_SF_DEFINITION_ERROR PROP_TAG(PT_ERROR , 0x6845) /* 0x6845000A */ #define PR_WB_SF_EFP_FLAGS PidTagSearchFolderEfpFlags #define PR_WB_SF_EFP_FLAGS_ERROR PROP_TAG(PT_ERROR , 0x6848) /* 0x6848000A */ #define PR_WB_SF_EXPIRATION PidTagSearchFolderExpiration #define PR_WB_SF_EXPIRATION_ERROR PROP_TAG(PT_ERROR , 0x683A) /* 0x683A000A */ #define PR_WB_SF_LAST_USED PidTagSearchFolderLastUsed #define PR_WB_SF_LAST_USED_ERROR PROP_TAG(PT_ERROR , 0x6834) /* 0x6834000A */ #define PR_WB_SF_RECREATE_INFO PidTagSearchFolderRecreateInfo #define PR_WB_SF_RECREATE_INFO_ERROR PROP_TAG(PT_ERROR , 0x6844) /* 0x6844000A */ #define PR_WB_SF_STORAGE_TYPE PidTagSearchFolderStorageType #define PR_WB_SF_STORAGE_TYPE_ERROR PROP_TAG(PT_ERROR , 0x6846) /* 0x6846000A */ #define PR_WB_SF_TEMPLATE_ID PidTagSearchFolderTemplateId #define PR_WB_SF_TEMPLATE_ID_ERROR PROP_TAG(PT_ERROR , 0x6841) /* 0x6841000A */ #define PR_WEDDING_ANNIVERSARY PidTagWeddingAnniversary #define PR_WEDDING_ANNIVERSARY_ERROR PROP_TAG(PT_ERROR , 0x3A41) /* 0x3A41000A */ #define PidTagFolderChildCount PROP_TAG(PT_LONG , 0x6638) /* 0x66380003 */ openchange-2.0/libmapi/property_tags.c000066400000000000000000006037331223057412600201630ustar00rootroot00000000000000/* Automatically generated by script/makepropslist.py. Do not edit */ #include "libmapi/libmapi.h" #include "libmapi/libmapi_private.h" #include "gen_ndr/ndr_exchange.h" #include "libmapi/property_tags.h" struct mapi_proptags { uint32_t proptag; uint32_t proptype; const char *propname; }; static struct mapi_proptags canonical_property_tags[] = { { PidTag7BitDisplayName, PT_UNICODE, "PidTag7BitDisplayName" }, { PidTag7BitDisplayName_Error, PT_ERROR, "PidTag7BitDisplayName_Error" }, { PidTagAccess, PT_LONG, "PidTagAccess" }, { PidTagAccessLevel, PT_LONG, "PidTagAccessLevel" }, { PidTagAccessLevel_Error, PT_ERROR, "PidTagAccessLevel_Error" }, { PidTagAccess_Error, PT_ERROR, "PidTagAccess_Error" }, { PidTagAccount, PT_UNICODE, "PidTagAccount" }, { PidTagAccount_Error, PT_ERROR, "PidTagAccount_Error" }, { PidTagAdditionalRenEntryIds, PT_MV_BINARY, "PidTagAdditionalRenEntryIds" }, { PidTagAdditionalRenEntryIdsEx, PT_BINARY, "PidTagAdditionalRenEntryIdsEx" }, { PidTagAdditionalRenEntryIdsEx_Error, PT_ERROR, "PidTagAdditionalRenEntryIdsEx_Error" }, { PidTagAdditionalRenEntryIds_Error, PT_ERROR, "PidTagAdditionalRenEntryIds_Error" }, { PidTagAddressBookAuthorizedSenders, PT_OBJECT, "PidTagAddressBookAuthorizedSenders" }, { PidTagAddressBookAuthorizedSenders_Error, PT_ERROR, "PidTagAddressBookAuthorizedSenders_Error" }, { PidTagAddressBookContainerId, PT_LONG, "PidTagAddressBookContainerId" }, { PidTagAddressBookContainerId_Error, PT_ERROR, "PidTagAddressBookContainerId_Error" }, { PidTagAddressBookDeliveryContentLength, PT_LONG, "PidTagAddressBookDeliveryContentLength" }, { PidTagAddressBookDeliveryContentLength_Error, PT_ERROR, "PidTagAddressBookDeliveryContentLength_Error" }, { PidTagAddressBookDisplayNamePrintable, PT_UNICODE, "PidTagAddressBookDisplayNamePrintable" }, { PidTagAddressBookDisplayNamePrintable_Error, PT_ERROR, "PidTagAddressBookDisplayNamePrintable_Error" }, { PidTagAddressBookDisplayTypeExtended, PT_LONG, "PidTagAddressBookDisplayTypeExtended" }, { PidTagAddressBookDisplayTypeExtended_Error, PT_ERROR, "PidTagAddressBookDisplayTypeExtended_Error" }, { PidTagAddressBookDistributionListExternalMemberCount, PT_LONG, "PidTagAddressBookDistributionListExternalMemberCount" }, { PidTagAddressBookDistributionListExternalMemberCount_Error, PT_ERROR, "PidTagAddressBookDistributionListExternalMemberCount_Error" }, { PidTagAddressBookDistributionListMemberCount, PT_LONG, "PidTagAddressBookDistributionListMemberCount" }, { PidTagAddressBookDistributionListMemberCount_Error, PT_ERROR, "PidTagAddressBookDistributionListMemberCount_Error" }, { PidTagAddressBookDistributionListMemberSubmitAccepted, PT_OBJECT, "PidTagAddressBookDistributionListMemberSubmitAccepted" }, { PidTagAddressBookDistributionListMemberSubmitAccepted_Error, PT_ERROR, "PidTagAddressBookDistributionListMemberSubmitAccepted_Error" }, { PidTagAddressBookDistributionListMemberSubmitRejected, PT_OBJECT, "PidTagAddressBookDistributionListMemberSubmitRejected" }, { PidTagAddressBookDistributionListMemberSubmitRejected_Error, PT_ERROR, "PidTagAddressBookDistributionListMemberSubmitRejected_Error" }, { PidTagAddressBookDistributionListRejectMessagesFromDLMembers, PT_OBJECT, "PidTagAddressBookDistributionListRejectMessagesFromDLMembers" }, { PidTagAddressBookDistributionListRejectMessagesFromDLMembers_Error, PT_ERROR, "PidTagAddressBookDistributionListRejectMessagesFromDLMembers_Error"}, { PidTagAddressBookEntryId, PT_BINARY, "PidTagAddressBookEntryId" }, { PidTagAddressBookEntryId_Error, PT_ERROR, "PidTagAddressBookEntryId_Error" }, { PidTagAddressBookExtensionAttribute1, PT_UNICODE, "PidTagAddressBookExtensionAttribute1" }, { PidTagAddressBookExtensionAttribute15, PT_UNICODE, "PidTagAddressBookExtensionAttribute15" }, { PidTagAddressBookExtensionAttribute15_Error, PT_ERROR, "PidTagAddressBookExtensionAttribute15_Error" }, { PidTagAddressBookExtensionAttribute1_Error, PT_ERROR, "PidTagAddressBookExtensionAttribute1_Error" }, { PidTagAddressBookFolderPathname, PT_UNICODE, "PidTagAddressBookFolderPathname" }, { PidTagAddressBookFolderPathname_Error, PT_ERROR, "PidTagAddressBookFolderPathname_Error" }, { PidTagAddressBookHierarchicalChildDepartments, PT_OBJECT, "PidTagAddressBookHierarchicalChildDepartments" }, { PidTagAddressBookHierarchicalChildDepartments_Error, PT_ERROR, "PidTagAddressBookHierarchicalChildDepartments_Error" }, { PidTagAddressBookHierarchicalDepartmentMembers, PT_OBJECT, "PidTagAddressBookHierarchicalDepartmentMembers" }, { PidTagAddressBookHierarchicalDepartmentMembers_Error, PT_ERROR, "PidTagAddressBookHierarchicalDepartmentMembers_Error" }, { PidTagAddressBookHierarchicalIsHierarchicalGroup, PT_BOOLEAN, "PidTagAddressBookHierarchicalIsHierarchicalGroup" }, { PidTagAddressBookHierarchicalIsHierarchicalGroup_Error, PT_ERROR, "PidTagAddressBookHierarchicalIsHierarchicalGroup_Error" }, { PidTagAddressBookHierarchicalParentDepartment, PT_OBJECT, "PidTagAddressBookHierarchicalParentDepartment" }, { PidTagAddressBookHierarchicalParentDepartment_Error, PT_ERROR, "PidTagAddressBookHierarchicalParentDepartment_Error" }, { PidTagAddressBookHierarchicalRootDepartment, PT_STRING8, "PidTagAddressBookHierarchicalRootDepartment" }, { PidTagAddressBookHierarchicalRootDepartment_Error, PT_ERROR, "PidTagAddressBookHierarchicalRootDepartment_Error" }, { PidTagAddressBookHierarchicalShowInDepartments, PT_OBJECT, "PidTagAddressBookHierarchicalShowInDepartments" }, { PidTagAddressBookHierarchicalShowInDepartments_Error, PT_ERROR, "PidTagAddressBookHierarchicalShowInDepartments_Error" }, { PidTagAddressBookHomeMessageDatabase, PT_UNICODE, "PidTagAddressBookHomeMessageDatabase" }, { PidTagAddressBookHomeMessageDatabase_Error, PT_ERROR, "PidTagAddressBookHomeMessageDatabase_Error" }, { PidTagAddressBookIsMaster, PT_BOOLEAN, "PidTagAddressBookIsMaster" }, { PidTagAddressBookIsMaster_Error, PT_ERROR, "PidTagAddressBookIsMaster_Error" }, { PidTagAddressBookIsMemberOfDistributionList, PT_MV_STRING8,"PidTagAddressBookIsMemberOfDistributionList" }, { PidTagAddressBookIsMemberOfDistributionList_Error, PT_ERROR, "PidTagAddressBookIsMemberOfDistributionList_Error" }, { PidTagAddressBookManageDistributionList, PT_OBJECT, "PidTagAddressBookManageDistributionList" }, { PidTagAddressBookManageDistributionList_Error, PT_ERROR, "PidTagAddressBookManageDistributionList_Error" }, { PidTagAddressBookManager, PT_OBJECT, "PidTagAddressBookManager" }, { PidTagAddressBookManagerDistinguishedName, PT_UNICODE, "PidTagAddressBookManagerDistinguishedName" }, { PidTagAddressBookManagerDistinguishedName_Error, PT_ERROR, "PidTagAddressBookManagerDistinguishedName_Error" }, { PidTagAddressBookManager_Error, PT_ERROR, "PidTagAddressBookManager_Error" }, { PidTagAddressBookMember, PT_MV_STRING8,"PidTagAddressBookMember" }, { PidTagAddressBookMember_Error, PT_ERROR, "PidTagAddressBookMember_Error" }, { PidTagAddressBookMessageId, PT_I8, "PidTagAddressBookMessageId" }, { PidTagAddressBookMessageId_Error, PT_ERROR, "PidTagAddressBookMessageId_Error" }, { PidTagAddressBookModerationEnabled, PT_BOOLEAN, "PidTagAddressBookModerationEnabled" }, { PidTagAddressBookModerationEnabled_Error, PT_ERROR, "PidTagAddressBookModerationEnabled_Error" }, { PidTagAddressBookNetworkAddress, PT_MV_UNICODE,"PidTagAddressBookNetworkAddress" }, { PidTagAddressBookNetworkAddress_Error, PT_ERROR, "PidTagAddressBookNetworkAddress_Error" }, { PidTagAddressBookObjectDistinguishedName, PT_UNICODE, "PidTagAddressBookObjectDistinguishedName" }, { PidTagAddressBookObjectDistinguishedName_Error, PT_ERROR, "PidTagAddressBookObjectDistinguishedName_Error" }, { PidTagAddressBookObjectGuid, PT_BINARY, "PidTagAddressBookObjectGuid" }, { PidTagAddressBookObjectGuid_Error, PT_ERROR, "PidTagAddressBookObjectGuid_Error" }, { PidTagAddressBookOrganizationalUnitRootDistinguishedName, PT_UNICODE, "PidTagAddressBookOrganizationalUnitRootDistinguishedName" }, { PidTagAddressBookOrganizationalUnitRootDistinguishedName_Error, PT_ERROR, "PidTagAddressBookOrganizationalUnitRootDistinguishedName_Error" }, { PidTagAddressBookOwner, PT_OBJECT, "PidTagAddressBookOwner" }, { PidTagAddressBookOwnerBackLink, PT_OBJECT, "PidTagAddressBookOwnerBackLink" }, { PidTagAddressBookOwnerBackLink_Error, PT_ERROR, "PidTagAddressBookOwnerBackLink_Error" }, { PidTagAddressBookOwner_Error, PT_ERROR, "PidTagAddressBookOwner_Error" }, { PidTagAddressBookParentEntryId, PT_BINARY, "PidTagAddressBookParentEntryId" }, { PidTagAddressBookParentEntryId_Error, PT_ERROR, "PidTagAddressBookParentEntryId_Error" }, { PidTagAddressBookPhoneticCompanyName, PT_UNICODE, "PidTagAddressBookPhoneticCompanyName" }, { PidTagAddressBookPhoneticCompanyName_Error, PT_ERROR, "PidTagAddressBookPhoneticCompanyName_Error" }, { PidTagAddressBookPhoneticDepartmentName, PT_UNICODE, "PidTagAddressBookPhoneticDepartmentName" }, { PidTagAddressBookPhoneticDepartmentName_Error, PT_ERROR, "PidTagAddressBookPhoneticDepartmentName_Error" }, { PidTagAddressBookPhoneticDisplayName, PT_UNICODE, "PidTagAddressBookPhoneticDisplayName" }, { PidTagAddressBookPhoneticDisplayName_Error, PT_ERROR, "PidTagAddressBookPhoneticDisplayName_Error" }, { PidTagAddressBookPhoneticGivenName, PT_UNICODE, "PidTagAddressBookPhoneticGivenName" }, { PidTagAddressBookPhoneticGivenName_Error, PT_ERROR, "PidTagAddressBookPhoneticGivenName_Error" }, { PidTagAddressBookPhoneticSurname, PT_UNICODE, "PidTagAddressBookPhoneticSurname" }, { PidTagAddressBookPhoneticSurname_Error, PT_ERROR, "PidTagAddressBookPhoneticSurname_Error" }, { PidTagAddressBookProxyAddresses, PT_MV_UNICODE,"PidTagAddressBookProxyAddresses" }, { PidTagAddressBookProxyAddresses_Error, PT_ERROR, "PidTagAddressBookProxyAddresses_Error" }, { PidTagAddressBookPublicDelegates, PT_OBJECT, "PidTagAddressBookPublicDelegates" }, { PidTagAddressBookPublicDelegates_Error, PT_ERROR, "PidTagAddressBookPublicDelegates_Error" }, { PidTagAddressBookReports, PT_OBJECT, "PidTagAddressBookReports" }, { PidTagAddressBookReports_Error, PT_ERROR, "PidTagAddressBookReports_Error" }, { PidTagAddressBookRoomCapacity, PT_LONG, "PidTagAddressBookRoomCapacity" }, { PidTagAddressBookRoomCapacity_Error, PT_ERROR, "PidTagAddressBookRoomCapacity_Error" }, { PidTagAddressBookRoomContainers, PT_MV_UNICODE,"PidTagAddressBookRoomContainers" }, { PidTagAddressBookRoomContainers_Error, PT_ERROR, "PidTagAddressBookRoomContainers_Error" }, { PidTagAddressBookRoomDescription, PT_UNICODE, "PidTagAddressBookRoomDescription" }, { PidTagAddressBookRoomDescription_Error, PT_ERROR, "PidTagAddressBookRoomDescription_Error" }, { PidTagAddressBookSenderHintTranslations, PT_MV_UNICODE,"PidTagAddressBookSenderHintTranslations" }, { PidTagAddressBookSenderHintTranslations_Error, PT_ERROR, "PidTagAddressBookSenderHintTranslations_Error" }, { PidTagAddressBookSeniorityIndex, PT_LONG, "PidTagAddressBookSeniorityIndex" }, { PidTagAddressBookSeniorityIndex_Error, PT_ERROR, "PidTagAddressBookSeniorityIndex_Error" }, { PidTagAddressBookTargetAddress, PT_UNICODE, "PidTagAddressBookTargetAddress" }, { PidTagAddressBookTargetAddress_Error, PT_ERROR, "PidTagAddressBookTargetAddress_Error" }, { PidTagAddressBookUnauthorizedSenders, PT_OBJECT, "PidTagAddressBookUnauthorizedSenders" }, { PidTagAddressBookUnauthorizedSenders_Error, PT_ERROR, "PidTagAddressBookUnauthorizedSenders_Error" }, { PidTagAddressBookX509Certificate, PT_MV_BINARY, "PidTagAddressBookX509Certificate" }, { PidTagAddressBookX509Certificate_Error, PT_ERROR, "PidTagAddressBookX509Certificate_Error" }, { PidTagAddressType, PT_UNICODE, "PidTagAddressType" }, { PidTagAddressType_Error, PT_ERROR, "PidTagAddressType_Error" }, { PidTagAlternateRecipientAllowed, PT_BOOLEAN, "PidTagAlternateRecipientAllowed" }, { PidTagAlternateRecipientAllowed_Error, PT_ERROR, "PidTagAlternateRecipientAllowed_Error" }, { PidTagAnr, PT_UNICODE, "PidTagAnr" }, { PidTagAnr_Error, PT_ERROR, "PidTagAnr_Error" }, { PidTagArchiveDate, PT_SYSTIME, "PidTagArchiveDate" }, { PidTagArchiveDate_Error, PT_ERROR, "PidTagArchiveDate_Error" }, { PidTagArchivePeriod, PT_LONG, "PidTagArchivePeriod" }, { PidTagArchivePeriod_Error, PT_ERROR, "PidTagArchivePeriod_Error" }, { PidTagArchiveTag, PT_BINARY, "PidTagArchiveTag" }, { PidTagArchiveTag_Error, PT_ERROR, "PidTagArchiveTag_Error" }, { PidTagAssistant, PT_UNICODE, "PidTagAssistant" }, { PidTagAssistantTelephoneNumber, PT_UNICODE, "PidTagAssistantTelephoneNumber" }, { PidTagAssistantTelephoneNumber_Error, PT_ERROR, "PidTagAssistantTelephoneNumber_Error" }, { PidTagAssistant_Error, PT_ERROR, "PidTagAssistant_Error" }, { PidTagAssociated, PT_BOOLEAN, "PidTagAssociated" }, { PidTagAssociated_Error, PT_ERROR, "PidTagAssociated_Error" }, { PidTagAttachAdditionalInformation, PT_BINARY, "PidTagAttachAdditionalInformation" }, { PidTagAttachAdditionalInformation_Error, PT_ERROR, "PidTagAttachAdditionalInformation_Error" }, { PidTagAttachContentBase, PT_UNICODE, "PidTagAttachContentBase" }, { PidTagAttachContentBase_Error, PT_ERROR, "PidTagAttachContentBase_Error" }, { PidTagAttachContentId, PT_UNICODE, "PidTagAttachContentId" }, { PidTagAttachContentId_Error, PT_ERROR, "PidTagAttachContentId_Error" }, { PidTagAttachContentLocation, PT_UNICODE, "PidTagAttachContentLocation" }, { PidTagAttachContentLocation_Error, PT_ERROR, "PidTagAttachContentLocation_Error" }, { PidTagAttachDataBinary, PT_BINARY, "PidTagAttachDataBinary" }, { PidTagAttachDataBinary_Error, PT_ERROR, "PidTagAttachDataBinary_Error" }, { PidTagAttachDataObject, PT_OBJECT, "PidTagAttachDataObject" }, { PidTagAttachDataObject_Error, PT_ERROR, "PidTagAttachDataObject_Error" }, { PidTagAttachEncoding, PT_BINARY, "PidTagAttachEncoding" }, { PidTagAttachEncoding_Error, PT_ERROR, "PidTagAttachEncoding_Error" }, { PidTagAttachExtension, PT_UNICODE, "PidTagAttachExtension" }, { PidTagAttachExtension_Error, PT_ERROR, "PidTagAttachExtension_Error" }, { PidTagAttachFilename, PT_UNICODE, "PidTagAttachFilename" }, { PidTagAttachFilename_Error, PT_ERROR, "PidTagAttachFilename_Error" }, { PidTagAttachFlags, PT_LONG, "PidTagAttachFlags" }, { PidTagAttachFlags_Error, PT_ERROR, "PidTagAttachFlags_Error" }, { PidTagAttachLongFilename, PT_UNICODE, "PidTagAttachLongFilename" }, { PidTagAttachLongFilename_Error, PT_ERROR, "PidTagAttachLongFilename_Error" }, { PidTagAttachLongPathname, PT_UNICODE, "PidTagAttachLongPathname" }, { PidTagAttachLongPathname_Error, PT_ERROR, "PidTagAttachLongPathname_Error" }, { PidTagAttachMethod, PT_LONG, "PidTagAttachMethod" }, { PidTagAttachMethod_Error, PT_ERROR, "PidTagAttachMethod_Error" }, { PidTagAttachMimeTag, PT_UNICODE, "PidTagAttachMimeTag" }, { PidTagAttachMimeTag_Error, PT_ERROR, "PidTagAttachMimeTag_Error" }, { PidTagAttachNumber, PT_LONG, "PidTagAttachNumber" }, { PidTagAttachNumber_Error, PT_ERROR, "PidTagAttachNumber_Error" }, { PidTagAttachPathname, PT_UNICODE, "PidTagAttachPathname" }, { PidTagAttachPathname_Error, PT_ERROR, "PidTagAttachPathname_Error" }, { PidTagAttachPayloadClass, PT_UNICODE, "PidTagAttachPayloadClass" }, { PidTagAttachPayloadClass_Error, PT_ERROR, "PidTagAttachPayloadClass_Error" }, { PidTagAttachPayloadProviderGuidString, PT_UNICODE, "PidTagAttachPayloadProviderGuidString" }, { PidTagAttachPayloadProviderGuidString_Error, PT_ERROR, "PidTagAttachPayloadProviderGuidString_Error" }, { PidTagAttachRendering, PT_BINARY, "PidTagAttachRendering" }, { PidTagAttachRendering_Error, PT_ERROR, "PidTagAttachRendering_Error" }, { PidTagAttachSize, PT_LONG, "PidTagAttachSize" }, { PidTagAttachSize_Error, PT_ERROR, "PidTagAttachSize_Error" }, { PidTagAttachTag, PT_BINARY, "PidTagAttachTag" }, { PidTagAttachTag_Error, PT_ERROR, "PidTagAttachTag_Error" }, { PidTagAttachTransportName, PT_UNICODE, "PidTagAttachTransportName" }, { PidTagAttachTransportName_Error, PT_ERROR, "PidTagAttachTransportName_Error" }, { PidTagAttachmentContactPhoto, PT_BOOLEAN, "PidTagAttachmentContactPhoto" }, { PidTagAttachmentContactPhoto_Error, PT_ERROR, "PidTagAttachmentContactPhoto_Error" }, { PidTagAttachmentFlags, PT_LONG, "PidTagAttachmentFlags" }, { PidTagAttachmentFlags_Error, PT_ERROR, "PidTagAttachmentFlags_Error" }, { PidTagAttachmentHidden, PT_BOOLEAN, "PidTagAttachmentHidden" }, { PidTagAttachmentHidden_Error, PT_ERROR, "PidTagAttachmentHidden_Error" }, { PidTagAttachmentLinkId, PT_LONG, "PidTagAttachmentLinkId" }, { PidTagAttachmentLinkId_Error, PT_ERROR, "PidTagAttachmentLinkId_Error" }, { PidTagAttributeHidden, PT_BOOLEAN, "PidTagAttributeHidden" }, { PidTagAttributeHidden_Error, PT_ERROR, "PidTagAttributeHidden_Error" }, { PidTagAttributeReadOnly, PT_BOOLEAN, "PidTagAttributeReadOnly" }, { PidTagAttributeReadOnly_Error, PT_ERROR, "PidTagAttributeReadOnly_Error" }, { PidTagAttributeSystem, PT_BOOLEAN, "PidTagAttributeSystem" }, { PidTagAttributeSystem_Error, PT_ERROR, "PidTagAttributeSystem_Error" }, { PidTagAutoForwardComment, PT_UNICODE, "PidTagAutoForwardComment" }, { PidTagAutoForwardComment_Error, PT_ERROR, "PidTagAutoForwardComment_Error" }, { PidTagAutoForwarded, PT_BOOLEAN, "PidTagAutoForwarded" }, { PidTagAutoForwarded_Error, PT_ERROR, "PidTagAutoForwarded_Error" }, { PidTagAutoResponseSuppress, PT_LONG, "PidTagAutoResponseSuppress" }, { PidTagAutoResponseSuppress_Error, PT_ERROR, "PidTagAutoResponseSuppress_Error" }, { PidTagBirthday, PT_SYSTIME, "PidTagBirthday" }, { PidTagBirthday_Error, PT_ERROR, "PidTagBirthday_Error" }, { PidTagBlockStatus, PT_LONG, "PidTagBlockStatus" }, { PidTagBlockStatus_Error, PT_ERROR, "PidTagBlockStatus_Error" }, { PidTagBody, PT_UNICODE, "PidTagBody" }, { PidTagBodyContentId, PT_UNICODE, "PidTagBodyContentId" }, { PidTagBodyContentId_Error, PT_ERROR, "PidTagBodyContentId_Error" }, { PidTagBodyContentLocation, PT_UNICODE, "PidTagBodyContentLocation" }, { PidTagBodyContentLocation_Error, PT_ERROR, "PidTagBodyContentLocation_Error" }, { PidTagBodyHtml, PT_UNICODE, "PidTagBodyHtml" }, { PidTagBodyHtml_Error, PT_ERROR, "PidTagBodyHtml_Error" }, { PidTagBody_Error, PT_ERROR, "PidTagBody_Error" }, { PidTagBusiness2TelephoneNumber, PT_UNICODE, "PidTagBusiness2TelephoneNumber" }, { PidTagBusiness2TelephoneNumber_Error, PT_ERROR, "PidTagBusiness2TelephoneNumber_Error" }, { PidTagBusiness2TelephoneNumbers, PT_MV_UNICODE,"PidTagBusiness2TelephoneNumbers" }, { PidTagBusiness2TelephoneNumbers_Error, PT_ERROR, "PidTagBusiness2TelephoneNumbers_Error" }, { PidTagBusinessFaxNumber, PT_UNICODE, "PidTagBusinessFaxNumber" }, { PidTagBusinessFaxNumber_Error, PT_ERROR, "PidTagBusinessFaxNumber_Error" }, { PidTagBusinessHomePage, PT_UNICODE, "PidTagBusinessHomePage" }, { PidTagBusinessHomePage_Error, PT_ERROR, "PidTagBusinessHomePage_Error" }, { PidTagBusinessTelephoneNumber, PT_UNICODE, "PidTagBusinessTelephoneNumber" }, { PidTagBusinessTelephoneNumber_Error, PT_ERROR, "PidTagBusinessTelephoneNumber_Error" }, { PidTagCallId, PT_UNICODE, "PidTagCallId" }, { PidTagCallId_Error, PT_ERROR, "PidTagCallId_Error" }, { PidTagCallbackTelephoneNumber, PT_UNICODE, "PidTagCallbackTelephoneNumber" }, { PidTagCallbackTelephoneNumber_Error, PT_ERROR, "PidTagCallbackTelephoneNumber_Error" }, { PidTagCarTelephoneNumber, PT_UNICODE, "PidTagCarTelephoneNumber" }, { PidTagCarTelephoneNumber_Error, PT_ERROR, "PidTagCarTelephoneNumber_Error" }, { PidTagCdoRecurrenceid, PT_SYSTIME, "PidTagCdoRecurrenceid" }, { PidTagCdoRecurrenceid_Error, PT_ERROR, "PidTagCdoRecurrenceid_Error" }, { PidTagChangeKey, PT_BINARY, "PidTagChangeKey" }, { PidTagChangeKey_Error, PT_ERROR, "PidTagChangeKey_Error" }, { PidTagChangeNotificationGuid, PT_CLSID, "PidTagChangeNotificationGuid" }, { PidTagChangeNotificationGuid_Error, PT_ERROR, "PidTagChangeNotificationGuid_Error" }, { PidTagChangeNumber, PT_I8, "PidTagChangeNumber" }, { PidTagChangeNumber_Error, PT_ERROR, "PidTagChangeNumber_Error" }, { PidTagChildrensNames, PT_MV_UNICODE,"PidTagChildrensNames" }, { PidTagChildrensNames_Error, PT_ERROR, "PidTagChildrensNames_Error" }, { PidTagClientActions, PT_BINARY, "PidTagClientActions" }, { PidTagClientActions_Error, PT_ERROR, "PidTagClientActions_Error" }, { PidTagClientSubmitTime, PT_SYSTIME, "PidTagClientSubmitTime" }, { PidTagClientSubmitTime_Error, PT_ERROR, "PidTagClientSubmitTime_Error" }, { PidTagCnsetRead, PT_BINARY, "PidTagCnsetRead" }, { PidTagCnsetRead_Error, PT_ERROR, "PidTagCnsetRead_Error" }, { PidTagCnsetSeen, PT_BINARY, "PidTagCnsetSeen" }, { PidTagCnsetSeenFAI, PT_BINARY, "PidTagCnsetSeenFAI" }, { PidTagCnsetSeenFAI_Error, PT_ERROR, "PidTagCnsetSeenFAI_Error" }, { PidTagCnsetSeen_Error, PT_ERROR, "PidTagCnsetSeen_Error" }, { PidTagCodePageId, PT_LONG, "PidTagCodePageId" }, { PidTagCodePageId_Error, PT_ERROR, "PidTagCodePageId_Error" }, { PidTagComment, PT_UNICODE, "PidTagComment" }, { PidTagComment_Error, PT_ERROR, "PidTagComment_Error" }, { PidTagCompanyMainTelephoneNumber, PT_UNICODE, "PidTagCompanyMainTelephoneNumber" }, { PidTagCompanyMainTelephoneNumber_Error, PT_ERROR, "PidTagCompanyMainTelephoneNumber_Error" }, { PidTagCompanyName, PT_UNICODE, "PidTagCompanyName" }, { PidTagCompanyName_Error, PT_ERROR, "PidTagCompanyName_Error" }, { PidTagComputerNetworkName, PT_UNICODE, "PidTagComputerNetworkName" }, { PidTagComputerNetworkName_Error, PT_ERROR, "PidTagComputerNetworkName_Error" }, { PidTagConflictEntryId, PT_BINARY, "PidTagConflictEntryId" }, { PidTagConflictEntryId_Error, PT_ERROR, "PidTagConflictEntryId_Error" }, { PidTagConflictItems, PT_MV_BINARY, "PidTagConflictItems" }, { PidTagConflictItems_Error, PT_ERROR, "PidTagConflictItems_Error" }, { PidTagContainerClass, PT_UNICODE, "PidTagContainerClass" }, { PidTagContainerClass_Error, PT_ERROR, "PidTagContainerClass_Error" }, { PidTagContainerContents, PT_OBJECT, "PidTagContainerContents" }, { PidTagContainerContents_Error, PT_ERROR, "PidTagContainerContents_Error" }, { PidTagContainerFlags, PT_LONG, "PidTagContainerFlags" }, { PidTagContainerFlags_Error, PT_ERROR, "PidTagContainerFlags_Error" }, { PidTagContainerHierarchy, PT_OBJECT, "PidTagContainerHierarchy" }, { PidTagContainerHierarchy_Error, PT_ERROR, "PidTagContainerHierarchy_Error" }, { PidTagContentCount, PT_LONG, "PidTagContentCount" }, { PidTagContentCount_Error, PT_ERROR, "PidTagContentCount_Error" }, { PidTagContentFilterPhishingConfidenceLevel, PT_LONG, "PidTagContentFilterPhishingConfidenceLevel" }, { PidTagContentFilterPhishingConfidenceLevel_Error, PT_ERROR, "PidTagContentFilterPhishingConfidenceLevel_Error" }, { PidTagContentFilterSpamConfidenceLevel, PT_LONG, "PidTagContentFilterSpamConfidenceLevel" }, { PidTagContentFilterSpamConfidenceLevel_Error, PT_ERROR, "PidTagContentFilterSpamConfidenceLevel_Error" }, { PidTagContentUnreadCount, PT_LONG, "PidTagContentUnreadCount" }, { PidTagContentUnreadCount_Error, PT_ERROR, "PidTagContentUnreadCount_Error" }, { PidTagConversationId, PT_BINARY, "PidTagConversationId" }, { PidTagConversationId_Error, PT_ERROR, "PidTagConversationId_Error" }, { PidTagConversationIndex, PT_BINARY, "PidTagConversationIndex" }, { PidTagConversationIndexTracking, PT_BOOLEAN, "PidTagConversationIndexTracking" }, { PidTagConversationIndexTracking_Error, PT_ERROR, "PidTagConversationIndexTracking_Error" }, { PidTagConversationIndex_Error, PT_ERROR, "PidTagConversationIndex_Error" }, { PidTagConversationTopic, PT_UNICODE, "PidTagConversationTopic" }, { PidTagConversationTopic_Error, PT_ERROR, "PidTagConversationTopic_Error" }, { PidTagCountry, PT_UNICODE, "PidTagCountry" }, { PidTagCountry_Error, PT_ERROR, "PidTagCountry_Error" }, { PidTagCreationTime, PT_SYSTIME, "PidTagCreationTime" }, { PidTagCreationTime_Error, PT_ERROR, "PidTagCreationTime_Error" }, { PidTagCreatorEntryId, PT_BINARY, "PidTagCreatorEntryId" }, { PidTagCreatorEntryId_Error, PT_ERROR, "PidTagCreatorEntryId_Error" }, { PidTagCreatorName, PT_UNICODE, "PidTagCreatorName" }, { PidTagCreatorName_Error, PT_ERROR, "PidTagCreatorName_Error" }, { PidTagCreatorSimpleDisplayName, PT_UNICODE, "PidTagCreatorSimpleDisplayName" }, { PidTagCreatorSimpleDisplayName_Error, PT_ERROR, "PidTagCreatorSimpleDisplayName_Error" }, { PidTagCustomerId, PT_UNICODE, "PidTagCustomerId" }, { PidTagCustomerId_Error, PT_ERROR, "PidTagCustomerId_Error" }, { PidTagDamBackPatched, PT_BOOLEAN, "PidTagDamBackPatched" }, { PidTagDamBackPatched_Error, PT_ERROR, "PidTagDamBackPatched_Error" }, { PidTagDamOriginalEntryId, PT_BINARY, "PidTagDamOriginalEntryId" }, { PidTagDamOriginalEntryId_Error, PT_ERROR, "PidTagDamOriginalEntryId_Error" }, { PidTagDefaultPostMessageClass, PT_UNICODE, "PidTagDefaultPostMessageClass" }, { PidTagDefaultPostMessageClass_Error, PT_ERROR, "PidTagDefaultPostMessageClass_Error" }, { PidTagDeferredActionMessageOriginalEntryId, PT_SVREID, "PidTagDeferredActionMessageOriginalEntryId" }, { PidTagDeferredActionMessageOriginalEntryId_Error, PT_ERROR, "PidTagDeferredActionMessageOriginalEntryId_Error" }, { PidTagDeferredDeliveryTime, PT_SYSTIME, "PidTagDeferredDeliveryTime" }, { PidTagDeferredDeliveryTime_Error, PT_ERROR, "PidTagDeferredDeliveryTime_Error" }, { PidTagDeferredSendNumber, PT_LONG, "PidTagDeferredSendNumber" }, { PidTagDeferredSendNumber_Error, PT_ERROR, "PidTagDeferredSendNumber_Error" }, { PidTagDeferredSendTime, PT_SYSTIME, "PidTagDeferredSendTime" }, { PidTagDeferredSendTime_Error, PT_ERROR, "PidTagDeferredSendTime_Error" }, { PidTagDeferredSendUnits, PT_LONG, "PidTagDeferredSendUnits" }, { PidTagDeferredSendUnits_Error, PT_ERROR, "PidTagDeferredSendUnits_Error" }, { PidTagDelegateFlags, PT_MV_LONG, "PidTagDelegateFlags" }, { PidTagDelegateFlags_Error, PT_ERROR, "PidTagDelegateFlags_Error" }, { PidTagDelegatedByRule, PT_BOOLEAN, "PidTagDelegatedByRule" }, { PidTagDelegatedByRule_Error, PT_ERROR, "PidTagDelegatedByRule_Error" }, { PidTagDeleteAfterSubmit, PT_BOOLEAN, "PidTagDeleteAfterSubmit" }, { PidTagDeleteAfterSubmit_Error, PT_ERROR, "PidTagDeleteAfterSubmit_Error" }, { PidTagDeletedOn, PT_SYSTIME, "PidTagDeletedOn" }, { PidTagDeletedOn_Error, PT_ERROR, "PidTagDeletedOn_Error" }, { PidTagDepartmentName, PT_UNICODE, "PidTagDepartmentName" }, { PidTagDepartmentName_Error, PT_ERROR, "PidTagDepartmentName_Error" }, { PidTagDepth, PT_LONG, "PidTagDepth" }, { PidTagDepth_Error, PT_ERROR, "PidTagDepth_Error" }, { PidTagDisplayBcc, PT_UNICODE, "PidTagDisplayBcc" }, { PidTagDisplayBcc_Error, PT_ERROR, "PidTagDisplayBcc_Error" }, { PidTagDisplayCc, PT_UNICODE, "PidTagDisplayCc" }, { PidTagDisplayCc_Error, PT_ERROR, "PidTagDisplayCc_Error" }, { PidTagDisplayName, PT_UNICODE, "PidTagDisplayName" }, { PidTagDisplayNamePrefix, PT_UNICODE, "PidTagDisplayNamePrefix" }, { PidTagDisplayNamePrefix_Error, PT_ERROR, "PidTagDisplayNamePrefix_Error" }, { PidTagDisplayName_Error, PT_ERROR, "PidTagDisplayName_Error" }, { PidTagDisplayTo, PT_UNICODE, "PidTagDisplayTo" }, { PidTagDisplayTo_Error, PT_ERROR, "PidTagDisplayTo_Error" }, { PidTagDisplayType, PT_LONG, "PidTagDisplayType" }, { PidTagDisplayTypeEx, PT_LONG, "PidTagDisplayTypeEx" }, { PidTagDisplayTypeEx_Error, PT_ERROR, "PidTagDisplayTypeEx_Error" }, { PidTagDisplayType_Error, PT_ERROR, "PidTagDisplayType_Error" }, { PidTagEcWarning, PT_LONG, "PidTagEcWarning" }, { PidTagEcWarning_Error, PT_ERROR, "PidTagEcWarning_Error" }, { PidTagEmailAddress, PT_UNICODE, "PidTagEmailAddress" }, { PidTagEmailAddress_Error, PT_ERROR, "PidTagEmailAddress_Error" }, { PidTagEndAttach, PT_LONG, "PidTagEndAttach" }, { PidTagEndAttach_Error, PT_ERROR, "PidTagEndAttach_Error" }, { PidTagEndDate, PT_SYSTIME, "PidTagEndDate" }, { PidTagEndDate_Error, PT_ERROR, "PidTagEndDate_Error" }, { PidTagEndEmbed, PT_LONG, "PidTagEndEmbed" }, { PidTagEndEmbed_Error, PT_ERROR, "PidTagEndEmbed_Error" }, { PidTagEndFolder, PT_LONG, "PidTagEndFolder" }, { PidTagEndFolder_Error, PT_ERROR, "PidTagEndFolder_Error" }, { PidTagEndMessage, PT_LONG, "PidTagEndMessage" }, { PidTagEndMessage_Error, PT_ERROR, "PidTagEndMessage_Error" }, { PidTagEndToRecip, PT_LONG, "PidTagEndToRecip" }, { PidTagEndToRecip_Error, PT_ERROR, "PidTagEndToRecip_Error" }, { PidTagEntryId, PT_BINARY, "PidTagEntryId" }, { PidTagEntryId_Error, PT_ERROR, "PidTagEntryId_Error" }, { PidTagExceptionEndTime, PT_SYSTIME, "PidTagExceptionEndTime" }, { PidTagExceptionEndTime_Error, PT_ERROR, "PidTagExceptionEndTime_Error" }, { PidTagExceptionReplaceTime, PT_SYSTIME, "PidTagExceptionReplaceTime" }, { PidTagExceptionReplaceTime_Error, PT_ERROR, "PidTagExceptionReplaceTime_Error" }, { PidTagExceptionStartTime, PT_SYSTIME, "PidTagExceptionStartTime" }, { PidTagExceptionStartTime_Error, PT_ERROR, "PidTagExceptionStartTime_Error" }, { PidTagExchangeNTSecurityDescriptor, PT_BINARY, "PidTagExchangeNTSecurityDescriptor" }, { PidTagExchangeNTSecurityDescriptor_Error, PT_ERROR, "PidTagExchangeNTSecurityDescriptor_Error" }, { PidTagExpiryNumber, PT_LONG, "PidTagExpiryNumber" }, { PidTagExpiryNumber_Error, PT_ERROR, "PidTagExpiryNumber_Error" }, { PidTagExpiryTime, PT_SYSTIME, "PidTagExpiryTime" }, { PidTagExpiryTime_Error, PT_ERROR, "PidTagExpiryTime_Error" }, { PidTagExpiryUnits, PT_LONG, "PidTagExpiryUnits" }, { PidTagExpiryUnits_Error, PT_ERROR, "PidTagExpiryUnits_Error" }, { PidTagExtendedFolderFlags, PT_BINARY, "PidTagExtendedFolderFlags" }, { PidTagExtendedFolderFlags_Error, PT_ERROR, "PidTagExtendedFolderFlags_Error" }, { PidTagExtendedRuleMessageActions, PT_BINARY, "PidTagExtendedRuleMessageActions" }, { PidTagExtendedRuleMessageActions_Error, PT_ERROR, "PidTagExtendedRuleMessageActions_Error" }, { PidTagExtendedRuleMessageCondition, PT_BINARY, "PidTagExtendedRuleMessageCondition" }, { PidTagExtendedRuleMessageCondition_Error, PT_ERROR, "PidTagExtendedRuleMessageCondition_Error" }, { PidTagExtendedRuleSizeLimit, PT_LONG, "PidTagExtendedRuleSizeLimit" }, { PidTagExtendedRuleSizeLimit_Error, PT_ERROR, "PidTagExtendedRuleSizeLimit_Error" }, { PidTagFXDelProp, PT_LONG, "PidTagFXDelProp" }, { PidTagFXDelProp_Error, PT_ERROR, "PidTagFXDelProp_Error" }, { PidTagFXErrorInfo, PT_LONG, "PidTagFXErrorInfo" }, { PidTagFXErrorInfo_Error, PT_ERROR, "PidTagFXErrorInfo_Error" }, { PidTagFaxNumberOfPages, PT_LONG, "PidTagFaxNumberOfPages" }, { PidTagFaxNumberOfPages_Error, PT_ERROR, "PidTagFaxNumberOfPages_Error" }, { PidTagFlagCompleteTime, PT_SYSTIME, "PidTagFlagCompleteTime" }, { PidTagFlagCompleteTime_Error, PT_ERROR, "PidTagFlagCompleteTime_Error" }, { PidTagFlagStatus, PT_LONG, "PidTagFlagStatus" }, { PidTagFlagStatus_Error, PT_ERROR, "PidTagFlagStatus_Error" }, { PidTagFlatUrlName, PT_UNICODE, "PidTagFlatUrlName" }, { PidTagFlatUrlName_Error, PT_ERROR, "PidTagFlatUrlName_Error" }, { PidTagFolderAssociatedContents, PT_OBJECT, "PidTagFolderAssociatedContents" }, { PidTagFolderAssociatedContents_Error, PT_ERROR, "PidTagFolderAssociatedContents_Error" }, { PidTagFolderChildCount, PT_LONG, "PidTagFolderChildCount" }, { PidTagFolderId, PT_I8, "PidTagFolderId" }, { PidTagFolderId_Error, PT_ERROR, "PidTagFolderId_Error" }, { PidTagFolderType, PT_LONG, "PidTagFolderType" }, { PidTagFolderType_Error, PT_ERROR, "PidTagFolderType_Error" }, { PidTagFollowupIcon, PT_LONG, "PidTagFollowupIcon" }, { PidTagFollowupIcon_Error, PT_ERROR, "PidTagFollowupIcon_Error" }, { PidTagFreeBusyCountMonths, PT_LONG, "PidTagFreeBusyCountMonths" }, { PidTagFreeBusyCountMonths_Error, PT_ERROR, "PidTagFreeBusyCountMonths_Error" }, { PidTagFreeBusyEntryIds, PT_MV_BINARY, "PidTagFreeBusyEntryIds" }, { PidTagFreeBusyEntryIds_Error, PT_ERROR, "PidTagFreeBusyEntryIds_Error" }, { PidTagFreeBusyMessageEmailAddress, PT_UNICODE, "PidTagFreeBusyMessageEmailAddress" }, { PidTagFreeBusyMessageEmailAddress_Error, PT_ERROR, "PidTagFreeBusyMessageEmailAddress_Error" }, { PidTagFreeBusyPublishEnd, PT_LONG, "PidTagFreeBusyPublishEnd" }, { PidTagFreeBusyPublishEnd_Error, PT_ERROR, "PidTagFreeBusyPublishEnd_Error" }, { PidTagFreeBusyPublishStart, PT_LONG, "PidTagFreeBusyPublishStart" }, { PidTagFreeBusyPublishStart_Error, PT_ERROR, "PidTagFreeBusyPublishStart_Error" }, { PidTagFreeBusyRangeTimestamp, PT_SYSTIME, "PidTagFreeBusyRangeTimestamp" }, { PidTagFreeBusyRangeTimestamp_Error, PT_ERROR, "PidTagFreeBusyRangeTimestamp_Error" }, { PidTagFtpSite, PT_UNICODE, "PidTagFtpSite" }, { PidTagFtpSite_Error, PT_ERROR, "PidTagFtpSite_Error" }, { PidTagGatewayNeedsToRefresh, PT_BOOLEAN, "PidTagGatewayNeedsToRefresh" }, { PidTagGatewayNeedsToRefresh_Error, PT_ERROR, "PidTagGatewayNeedsToRefresh_Error" }, { PidTagGender, PT_SHORT, "PidTagGender" }, { PidTagGender_Error, PT_ERROR, "PidTagGender_Error" }, { PidTagGeneration, PT_UNICODE, "PidTagGeneration" }, { PidTagGeneration_Error, PT_ERROR, "PidTagGeneration_Error" }, { PidTagGivenName, PT_UNICODE, "PidTagGivenName" }, { PidTagGivenName_Error, PT_ERROR, "PidTagGivenName_Error" }, { PidTagGovernmentIdNumber, PT_UNICODE, "PidTagGovernmentIdNumber" }, { PidTagGovernmentIdNumber_Error, PT_ERROR, "PidTagGovernmentIdNumber_Error" }, { PidTagHasAttachments, PT_BOOLEAN, "PidTagHasAttachments" }, { PidTagHasAttachments_Error, PT_ERROR, "PidTagHasAttachments_Error" }, { PidTagHasDeferredActionMessages, PT_BOOLEAN, "PidTagHasDeferredActionMessages" }, { PidTagHasDeferredActionMessages_Error, PT_ERROR, "PidTagHasDeferredActionMessages_Error" }, { PidTagHasNamedProperties, PT_BOOLEAN, "PidTagHasNamedProperties" }, { PidTagHasNamedProperties_Error, PT_ERROR, "PidTagHasNamedProperties_Error" }, { PidTagHasRules, PT_BOOLEAN, "PidTagHasRules" }, { PidTagHasRules_Error, PT_ERROR, "PidTagHasRules_Error" }, { PidTagHierarchyChangeNumber, PT_LONG, "PidTagHierarchyChangeNumber" }, { PidTagHierarchyChangeNumber_Error, PT_ERROR, "PidTagHierarchyChangeNumber_Error" }, { PidTagHobbies, PT_UNICODE, "PidTagHobbies" }, { PidTagHobbies_Error, PT_ERROR, "PidTagHobbies_Error" }, { PidTagHome2TelephoneNumber, PT_UNICODE, "PidTagHome2TelephoneNumber" }, { PidTagHome2TelephoneNumber_Error, PT_ERROR, "PidTagHome2TelephoneNumber_Error" }, { PidTagHome2TelephoneNumbers, PT_MV_UNICODE,"PidTagHome2TelephoneNumbers" }, { PidTagHome2TelephoneNumbers_Error, PT_ERROR, "PidTagHome2TelephoneNumbers_Error" }, { PidTagHomeAddressCity, PT_UNICODE, "PidTagHomeAddressCity" }, { PidTagHomeAddressCity_Error, PT_ERROR, "PidTagHomeAddressCity_Error" }, { PidTagHomeAddressCountry, PT_UNICODE, "PidTagHomeAddressCountry" }, { PidTagHomeAddressCountry_Error, PT_ERROR, "PidTagHomeAddressCountry_Error" }, { PidTagHomeAddressPostOfficeBox, PT_UNICODE, "PidTagHomeAddressPostOfficeBox" }, { PidTagHomeAddressPostOfficeBox_Error, PT_ERROR, "PidTagHomeAddressPostOfficeBox_Error" }, { PidTagHomeAddressPostalCode, PT_UNICODE, "PidTagHomeAddressPostalCode" }, { PidTagHomeAddressPostalCode_Error, PT_ERROR, "PidTagHomeAddressPostalCode_Error" }, { PidTagHomeAddressStateOrProvince, PT_UNICODE, "PidTagHomeAddressStateOrProvince" }, { PidTagHomeAddressStateOrProvince_Error, PT_ERROR, "PidTagHomeAddressStateOrProvince_Error" }, { PidTagHomeAddressStreet, PT_UNICODE, "PidTagHomeAddressStreet" }, { PidTagHomeAddressStreet_Error, PT_ERROR, "PidTagHomeAddressStreet_Error" }, { PidTagHomeFaxNumber, PT_UNICODE, "PidTagHomeFaxNumber" }, { PidTagHomeFaxNumber_Error, PT_ERROR, "PidTagHomeFaxNumber_Error" }, { PidTagHomeTelephoneNumber, PT_UNICODE, "PidTagHomeTelephoneNumber" }, { PidTagHomeTelephoneNumber_Error, PT_ERROR, "PidTagHomeTelephoneNumber_Error" }, { PidTagHtml, PT_BINARY, "PidTagHtml" }, { PidTagHtml_Error, PT_ERROR, "PidTagHtml_Error" }, { PidTagICalendarEndTime, PT_SYSTIME, "PidTagICalendarEndTime" }, { PidTagICalendarEndTime_Error, PT_ERROR, "PidTagICalendarEndTime_Error" }, { PidTagICalendarReminderNextTime, PT_SYSTIME, "PidTagICalendarReminderNextTime" }, { PidTagICalendarReminderNextTime_Error, PT_ERROR, "PidTagICalendarReminderNextTime_Error" }, { PidTagICalendarStartTime, PT_SYSTIME, "PidTagICalendarStartTime" }, { PidTagICalendarStartTime_Error, PT_ERROR, "PidTagICalendarStartTime_Error" }, { PidTagIconIndex, PT_LONG, "PidTagIconIndex" }, { PidTagIconIndex_Error, PT_ERROR, "PidTagIconIndex_Error" }, { PidTagIdsetDeleted, PT_BINARY, "PidTagIdsetDeleted" }, { PidTagIdsetDeleted_Error, PT_ERROR, "PidTagIdsetDeleted_Error" }, { PidTagIdsetExpired, PT_BINARY, "PidTagIdsetExpired" }, { PidTagIdsetExpired_Error, PT_ERROR, "PidTagIdsetExpired_Error" }, { PidTagIdsetGiven, PT_LONG, "PidTagIdsetGiven" }, { PidTagIdsetGiven_Error, PT_ERROR, "PidTagIdsetGiven_Error" }, { PidTagIdsetNoLongerInScope, PT_BINARY, "PidTagIdsetNoLongerInScope" }, { PidTagIdsetNoLongerInScope_Error, PT_ERROR, "PidTagIdsetNoLongerInScope_Error" }, { PidTagIdsetRead, PT_BINARY, "PidTagIdsetRead" }, { PidTagIdsetRead_Error, PT_ERROR, "PidTagIdsetRead_Error" }, { PidTagIdsetUnread, PT_BINARY, "PidTagIdsetUnread" }, { PidTagIdsetUnread_Error, PT_ERROR, "PidTagIdsetUnread_Error" }, { PidTagImapCachedMsgsize, PT_BINARY, "PidTagImapCachedMsgsize" }, { PidTagImapCachedMsgsize_Error, PT_ERROR, "PidTagImapCachedMsgsize_Error" }, { PidTagImportance, PT_LONG, "PidTagImportance" }, { PidTagImportance_Error, PT_ERROR, "PidTagImportance_Error" }, { PidTagInConflict, PT_BOOLEAN, "PidTagInConflict" }, { PidTagInConflict_Error, PT_ERROR, "PidTagInConflict_Error" }, { PidTagInReplyToId, PT_UNICODE, "PidTagInReplyToId" }, { PidTagInReplyToId_Error, PT_ERROR, "PidTagInReplyToId_Error" }, { PidTagIncrSyncChg, PT_LONG, "PidTagIncrSyncChg" }, { PidTagIncrSyncChgPartial, PT_LONG, "PidTagIncrSyncChgPartial" }, { PidTagIncrSyncChgPartial_Error, PT_ERROR, "PidTagIncrSyncChgPartial_Error" }, { PidTagIncrSyncChg_Error, PT_ERROR, "PidTagIncrSyncChg_Error" }, { PidTagIncrSyncDel, PT_LONG, "PidTagIncrSyncDel" }, { PidTagIncrSyncDel_Error, PT_ERROR, "PidTagIncrSyncDel_Error" }, { PidTagIncrSyncEnd, PT_LONG, "PidTagIncrSyncEnd" }, { PidTagIncrSyncEnd_Error, PT_ERROR, "PidTagIncrSyncEnd_Error" }, { PidTagIncrSyncGroupId, PT_LONG, "PidTagIncrSyncGroupId" }, { PidTagIncrSyncGroupId_Error, PT_ERROR, "PidTagIncrSyncGroupId_Error" }, { PidTagIncrSyncGroupInfo, PT_BINARY, "PidTagIncrSyncGroupInfo" }, { PidTagIncrSyncGroupInfo_Error, PT_ERROR, "PidTagIncrSyncGroupInfo_Error" }, { PidTagIncrSyncMessage, PT_LONG, "PidTagIncrSyncMessage" }, { PidTagIncrSyncMessage_Error, PT_ERROR, "PidTagIncrSyncMessage_Error" }, { PidTagIncrSyncProgressMode, PT_BOOLEAN, "PidTagIncrSyncProgressMode" }, { PidTagIncrSyncProgressMode_Error, PT_ERROR, "PidTagIncrSyncProgressMode_Error" }, { PidTagIncrSyncProgressPerMsg, PT_BOOLEAN, "PidTagIncrSyncProgressPerMsg" }, { PidTagIncrSyncProgressPerMsg_Error, PT_ERROR, "PidTagIncrSyncProgressPerMsg_Error" }, { PidTagIncrSyncRead, PT_LONG, "PidTagIncrSyncRead" }, { PidTagIncrSyncRead_Error, PT_ERROR, "PidTagIncrSyncRead_Error" }, { PidTagIncrSyncStateBegin, PT_LONG, "PidTagIncrSyncStateBegin" }, { PidTagIncrSyncStateBegin_Error, PT_ERROR, "PidTagIncrSyncStateBegin_Error" }, { PidTagIncrSyncStateEnd, PT_LONG, "PidTagIncrSyncStateEnd" }, { PidTagIncrSyncStateEnd_Error, PT_ERROR, "PidTagIncrSyncStateEnd_Error" }, { PidTagIncrementalSyncMessagePartial, PT_LONG, "PidTagIncrementalSyncMessagePartial" }, { PidTagIncrementalSyncMessagePartial_Error, PT_ERROR, "PidTagIncrementalSyncMessagePartial_Error" }, { PidTagInitialDetailsPane, PT_LONG, "PidTagInitialDetailsPane" }, { PidTagInitialDetailsPane_Error, PT_ERROR, "PidTagInitialDetailsPane_Error" }, { PidTagInitials, PT_UNICODE, "PidTagInitials" }, { PidTagInitials_Error, PT_ERROR, "PidTagInitials_Error" }, { PidTagInstID, PT_I8, "PidTagInstID" }, { PidTagInstID_Error, PT_ERROR, "PidTagInstID_Error" }, { PidTagInstanceKey, PT_BINARY, "PidTagInstanceKey" }, { PidTagInstanceKey_Error, PT_ERROR, "PidTagInstanceKey_Error" }, { PidTagInstanceNum, PT_LONG, "PidTagInstanceNum" }, { PidTagInstanceNum_Error, PT_ERROR, "PidTagInstanceNum_Error" }, { PidTagInternetArticleNumber, PT_LONG, "PidTagInternetArticleNumber" }, { PidTagInternetArticleNumber_Error, PT_ERROR, "PidTagInternetArticleNumber_Error" }, { PidTagInternetCodepage, PT_LONG, "PidTagInternetCodepage" }, { PidTagInternetCodepage_Error, PT_ERROR, "PidTagInternetCodepage_Error" }, { PidTagInternetMailOverrideFormat, PT_LONG, "PidTagInternetMailOverrideFormat" }, { PidTagInternetMailOverrideFormat_Error, PT_ERROR, "PidTagInternetMailOverrideFormat_Error" }, { PidTagInternetMessageId, PT_UNICODE, "PidTagInternetMessageId" }, { PidTagInternetMessageId_Error, PT_ERROR, "PidTagInternetMessageId_Error" }, { PidTagInternetReferences, PT_UNICODE, "PidTagInternetReferences" }, { PidTagInternetReferences_Error, PT_ERROR, "PidTagInternetReferences_Error" }, { PidTagIpmAppointmentEntryId, PT_BINARY, "PidTagIpmAppointmentEntryId" }, { PidTagIpmAppointmentEntryId_Error, PT_ERROR, "PidTagIpmAppointmentEntryId_Error" }, { PidTagIpmContactEntryId, PT_BINARY, "PidTagIpmContactEntryId" }, { PidTagIpmContactEntryId_Error, PT_ERROR, "PidTagIpmContactEntryId_Error" }, { PidTagIpmDraftsEntryId, PT_BINARY, "PidTagIpmDraftsEntryId" }, { PidTagIpmDraftsEntryId_Error, PT_ERROR, "PidTagIpmDraftsEntryId_Error" }, { PidTagIpmJournalEntryId, PT_BINARY, "PidTagIpmJournalEntryId" }, { PidTagIpmJournalEntryId_Error, PT_ERROR, "PidTagIpmJournalEntryId_Error" }, { PidTagIpmNoteEntryId, PT_BINARY, "PidTagIpmNoteEntryId" }, { PidTagIpmNoteEntryId_Error, PT_ERROR, "PidTagIpmNoteEntryId_Error" }, { PidTagIpmTaskEntryId, PT_BINARY, "PidTagIpmTaskEntryId" }, { PidTagIpmTaskEntryId_Error, PT_ERROR, "PidTagIpmTaskEntryId_Error" }, { PidTagIsdnNumber, PT_UNICODE, "PidTagIsdnNumber" }, { PidTagIsdnNumber_Error, PT_ERROR, "PidTagIsdnNumber_Error" }, { PidTagJunkAddRecipientsToSafeSendersList, PT_LONG, "PidTagJunkAddRecipientsToSafeSendersList" }, { PidTagJunkAddRecipientsToSafeSendersList_Error, PT_ERROR, "PidTagJunkAddRecipientsToSafeSendersList_Error" }, { PidTagJunkIncludeContacts, PT_LONG, "PidTagJunkIncludeContacts" }, { PidTagJunkIncludeContacts_Error, PT_ERROR, "PidTagJunkIncludeContacts_Error" }, { PidTagJunkPermanentlyDelete, PT_LONG, "PidTagJunkPermanentlyDelete" }, { PidTagJunkPermanentlyDelete_Error, PT_ERROR, "PidTagJunkPermanentlyDelete_Error" }, { PidTagJunkPhishingEnableLinks, PT_BOOLEAN, "PidTagJunkPhishingEnableLinks" }, { PidTagJunkPhishingEnableLinks_Error, PT_ERROR, "PidTagJunkPhishingEnableLinks_Error" }, { PidTagJunkThreshold, PT_LONG, "PidTagJunkThreshold" }, { PidTagJunkThreshold_Error, PT_ERROR, "PidTagJunkThreshold_Error" }, { PidTagKeyword, PT_UNICODE, "PidTagKeyword" }, { PidTagKeyword_Error, PT_ERROR, "PidTagKeyword_Error" }, { PidTagLanguage, PT_UNICODE, "PidTagLanguage" }, { PidTagLanguage_Error, PT_ERROR, "PidTagLanguage_Error" }, { PidTagLastModificationTime, PT_SYSTIME, "PidTagLastModificationTime" }, { PidTagLastModificationTime_Error, PT_ERROR, "PidTagLastModificationTime_Error" }, { PidTagLastModifierEntryId, PT_BINARY, "PidTagLastModifierEntryId" }, { PidTagLastModifierEntryId_Error, PT_ERROR, "PidTagLastModifierEntryId_Error" }, { PidTagLastModifierName, PT_UNICODE, "PidTagLastModifierName" }, { PidTagLastModifierName_Error, PT_ERROR, "PidTagLastModifierName_Error" }, { PidTagLastModifierSimpleDisplayName, PT_UNICODE, "PidTagLastModifierSimpleDisplayName" }, { PidTagLastModifierSimpleDisplayName_Error, PT_ERROR, "PidTagLastModifierSimpleDisplayName_Error" }, { PidTagLastVerbExecuted, PT_LONG, "PidTagLastVerbExecuted" }, { PidTagLastVerbExecuted_Error, PT_ERROR, "PidTagLastVerbExecuted_Error" }, { PidTagLastVerbExecutionTime, PT_SYSTIME, "PidTagLastVerbExecutionTime" }, { PidTagLastVerbExecutionTime_Error, PT_ERROR, "PidTagLastVerbExecutionTime_Error" }, { PidTagListHelp, PT_UNICODE, "PidTagListHelp" }, { PidTagListHelp_Error, PT_ERROR, "PidTagListHelp_Error" }, { PidTagListSubscribe, PT_UNICODE, "PidTagListSubscribe" }, { PidTagListSubscribe_Error, PT_ERROR, "PidTagListSubscribe_Error" }, { PidTagListUnsubscribe, PT_UNICODE, "PidTagListUnsubscribe" }, { PidTagListUnsubscribe_Error, PT_ERROR, "PidTagListUnsubscribe_Error" }, { PidTagLocalCommitTime, PT_SYSTIME, "PidTagLocalCommitTime" }, { PidTagLocalCommitTime_Error, PT_ERROR, "PidTagLocalCommitTime_Error" }, { PidTagLocaleId, PT_LONG, "PidTagLocaleId" }, { PidTagLocaleId_Error, PT_ERROR, "PidTagLocaleId_Error" }, { PidTagLocality, PT_UNICODE, "PidTagLocality" }, { PidTagLocality_Error, PT_ERROR, "PidTagLocality_Error" }, { PidTagLocation, PT_UNICODE, "PidTagLocation" }, { PidTagLocation_Error, PT_ERROR, "PidTagLocation_Error" }, { PidTagMailboxOwnerEntryId, PT_BINARY, "PidTagMailboxOwnerEntryId" }, { PidTagMailboxOwnerEntryId_Error, PT_ERROR, "PidTagMailboxOwnerEntryId_Error" }, { PidTagMailboxOwnerName, PT_UNICODE, "PidTagMailboxOwnerName" }, { PidTagMailboxOwnerName_Error, PT_ERROR, "PidTagMailboxOwnerName_Error" }, { PidTagManagerName, PT_UNICODE, "PidTagManagerName" }, { PidTagManagerName_Error, PT_ERROR, "PidTagManagerName_Error" }, { PidTagMappingSignature, PT_BINARY, "PidTagMappingSignature" }, { PidTagMappingSignature_Error, PT_ERROR, "PidTagMappingSignature_Error" }, { PidTagMaximumSubmitMessageSize, PT_LONG, "PidTagMaximumSubmitMessageSize" }, { PidTagMaximumSubmitMessageSize_Error, PT_ERROR, "PidTagMaximumSubmitMessageSize_Error" }, { PidTagMemberId, PT_I8, "PidTagMemberId" }, { PidTagMemberId_Error, PT_ERROR, "PidTagMemberId_Error" }, { PidTagMemberName, PT_UNICODE, "PidTagMemberName" }, { PidTagMemberName_Error, PT_ERROR, "PidTagMemberName_Error" }, { PidTagMemberRights, PT_LONG, "PidTagMemberRights" }, { PidTagMemberRights_Error, PT_ERROR, "PidTagMemberRights_Error" }, { PidTagMessageAttachments, PT_OBJECT, "PidTagMessageAttachments" }, { PidTagMessageAttachments_Error, PT_ERROR, "PidTagMessageAttachments_Error" }, { PidTagMessageCcMe, PT_BOOLEAN, "PidTagMessageCcMe" }, { PidTagMessageCcMe_Error, PT_ERROR, "PidTagMessageCcMe_Error" }, { PidTagMessageClass, PT_UNICODE, "PidTagMessageClass" }, { PidTagMessageClass_Error, PT_ERROR, "PidTagMessageClass_Error" }, { PidTagMessageCodepage, PT_LONG, "PidTagMessageCodepage" }, { PidTagMessageCodepage_Error, PT_ERROR, "PidTagMessageCodepage_Error" }, { PidTagMessageDeliveryTime, PT_SYSTIME, "PidTagMessageDeliveryTime" }, { PidTagMessageDeliveryTime_Error, PT_ERROR, "PidTagMessageDeliveryTime_Error" }, { PidTagMessageEditorFormat, PT_LONG, "PidTagMessageEditorFormat" }, { PidTagMessageEditorFormat_Error, PT_ERROR, "PidTagMessageEditorFormat_Error" }, { PidTagMessageFlags, PT_LONG, "PidTagMessageFlags" }, { PidTagMessageFlags_Error, PT_ERROR, "PidTagMessageFlags_Error" }, { PidTagMessageHandlingSystemCommonName, PT_UNICODE, "PidTagMessageHandlingSystemCommonName" }, { PidTagMessageHandlingSystemCommonName_Error, PT_ERROR, "PidTagMessageHandlingSystemCommonName_Error" }, { PidTagMessageLocaleId, PT_LONG, "PidTagMessageLocaleId" }, { PidTagMessageLocaleId_Error, PT_ERROR, "PidTagMessageLocaleId_Error" }, { PidTagMessageRecipientMe, PT_BOOLEAN, "PidTagMessageRecipientMe" }, { PidTagMessageRecipientMe_Error, PT_ERROR, "PidTagMessageRecipientMe_Error" }, { PidTagMessageRecipients, PT_OBJECT, "PidTagMessageRecipients" }, { PidTagMessageRecipients_Error, PT_ERROR, "PidTagMessageRecipients_Error" }, { PidTagMessageSize, PT_LONG, "PidTagMessageSize" }, { PidTagMessageSizeExtended, PT_I8, "PidTagMessageSizeExtended" }, { PidTagMessageSizeExtended_Error, PT_ERROR, "PidTagMessageSizeExtended_Error" }, { PidTagMessageSize_Error, PT_ERROR, "PidTagMessageSize_Error" }, { PidTagMessageStatus, PT_LONG, "PidTagMessageStatus" }, { PidTagMessageStatus_Error, PT_ERROR, "PidTagMessageStatus_Error" }, { PidTagMessageSubmissionId, PT_BINARY, "PidTagMessageSubmissionId" }, { PidTagMessageSubmissionId_Error, PT_ERROR, "PidTagMessageSubmissionId_Error" }, { PidTagMessageToMe, PT_BOOLEAN, "PidTagMessageToMe" }, { PidTagMessageToMe_Error, PT_ERROR, "PidTagMessageToMe_Error" }, { PidTagMid, PT_I8, "PidTagMid" }, { PidTagMid_Error, PT_ERROR, "PidTagMid_Error" }, { PidTagMiddleName, PT_UNICODE, "PidTagMiddleName" }, { PidTagMiddleName_Error, PT_ERROR, "PidTagMiddleName_Error" }, { PidTagMimeSkeleton, PT_BINARY, "PidTagMimeSkeleton" }, { PidTagMimeSkeleton_Error, PT_ERROR, "PidTagMimeSkeleton_Error" }, { PidTagMobileTelephoneNumber, PT_UNICODE, "PidTagMobileTelephoneNumber" }, { PidTagMobileTelephoneNumber_Error, PT_ERROR, "PidTagMobileTelephoneNumber_Error" }, { PidTagNativeBody, PT_LONG, "PidTagNativeBody" }, { PidTagNativeBody_Error, PT_ERROR, "PidTagNativeBody_Error" }, { PidTagNewAttach, PT_LONG, "PidTagNewAttach" }, { PidTagNewAttach_Error, PT_ERROR, "PidTagNewAttach_Error" }, { PidTagNewFXFolder, PT_BINARY, "PidTagNewFXFolder" }, { PidTagNewFXFolder_Error, PT_ERROR, "PidTagNewFXFolder_Error" }, { PidTagNextSendAcct, PT_UNICODE, "PidTagNextSendAcct" }, { PidTagNextSendAcct_Error, PT_ERROR, "PidTagNextSendAcct_Error" }, { PidTagNickname, PT_UNICODE, "PidTagNickname" }, { PidTagNickname_Error, PT_ERROR, "PidTagNickname_Error" }, { PidTagNormalMessageSize, PT_LONG, "PidTagNormalMessageSize" }, { PidTagNormalMessageSize_Error, PT_ERROR, "PidTagNormalMessageSize_Error" }, { PidTagNormalizedSubject, PT_UNICODE, "PidTagNormalizedSubject" }, { PidTagNormalizedSubject_Error, PT_ERROR, "PidTagNormalizedSubject_Error" }, { PidTagObjectType, PT_LONG, "PidTagObjectType" }, { PidTagObjectType_Error, PT_ERROR, "PidTagObjectType_Error" }, { PidTagOfficeLocation, PT_UNICODE, "PidTagOfficeLocation" }, { PidTagOfficeLocation_Error, PT_ERROR, "PidTagOfficeLocation_Error" }, { PidTagOfflineAddressBookCompressedSize, PT_LONG, "PidTagOfflineAddressBookCompressedSize" }, { PidTagOfflineAddressBookCompressedSize_Error, PT_ERROR, "PidTagOfflineAddressBookCompressedSize_Error" }, { PidTagOfflineAddressBookContainerGuid, PT_STRING8, "PidTagOfflineAddressBookContainerGuid" }, { PidTagOfflineAddressBookContainerGuid_Error, PT_ERROR, "PidTagOfflineAddressBookContainerGuid_Error" }, { PidTagOfflineAddressBookDistinguishedName, PT_STRING8, "PidTagOfflineAddressBookDistinguishedName" }, { PidTagOfflineAddressBookDistinguishedName_Error, PT_ERROR, "PidTagOfflineAddressBookDistinguishedName_Error" }, { PidTagOfflineAddressBookFileSize, PT_LONG, "PidTagOfflineAddressBookFileSize" }, { PidTagOfflineAddressBookFileSize_Error, PT_ERROR, "PidTagOfflineAddressBookFileSize_Error" }, { PidTagOfflineAddressBookFileType, PT_LONG, "PidTagOfflineAddressBookFileType" }, { PidTagOfflineAddressBookFileType_Error, PT_ERROR, "PidTagOfflineAddressBookFileType_Error" }, { PidTagOfflineAddressBookLanguageId, PT_LONG, "PidTagOfflineAddressBookLanguageId" }, { PidTagOfflineAddressBookLanguageId_Error, PT_ERROR, "PidTagOfflineAddressBookLanguageId_Error" }, { PidTagOfflineAddressBookMessageClass, PT_LONG, "PidTagOfflineAddressBookMessageClass" }, { PidTagOfflineAddressBookMessageClass_Error, PT_ERROR, "PidTagOfflineAddressBookMessageClass_Error" }, { PidTagOfflineAddressBookName, PT_UNICODE, "PidTagOfflineAddressBookName" }, { PidTagOfflineAddressBookName_Error, PT_ERROR, "PidTagOfflineAddressBookName_Error" }, { PidTagOfflineAddressBookSequence, PT_LONG, "PidTagOfflineAddressBookSequence" }, { PidTagOfflineAddressBookSequence_Error, PT_ERROR, "PidTagOfflineAddressBookSequence_Error" }, { PidTagOfflineAddressBookShaHash, PT_BINARY, "PidTagOfflineAddressBookShaHash" }, { PidTagOfflineAddressBookShaHash_Error, PT_ERROR, "PidTagOfflineAddressBookShaHash_Error" }, { PidTagOfflineAddressBookTruncatedProperties, PT_MV_LONG, "PidTagOfflineAddressBookTruncatedProperties" }, { PidTagOfflineAddressBookTruncatedProperties_Error, PT_ERROR, "PidTagOfflineAddressBookTruncatedProperties_Error" }, { PidTagOrdinalMost, PT_LONG, "PidTagOrdinalMost" }, { PidTagOrdinalMost_Error, PT_ERROR, "PidTagOrdinalMost_Error" }, { PidTagOrganizationalIdNumber, PT_UNICODE, "PidTagOrganizationalIdNumber" }, { PidTagOrganizationalIdNumber_Error, PT_ERROR, "PidTagOrganizationalIdNumber_Error" }, { PidTagOriginalDeliveryTime, PT_SYSTIME, "PidTagOriginalDeliveryTime" }, { PidTagOriginalDeliveryTime_Error, PT_ERROR, "PidTagOriginalDeliveryTime_Error" }, { PidTagOriginalDisplayBcc, PT_UNICODE, "PidTagOriginalDisplayBcc" }, { PidTagOriginalDisplayBcc_Error, PT_ERROR, "PidTagOriginalDisplayBcc_Error" }, { PidTagOriginalDisplayCc, PT_UNICODE, "PidTagOriginalDisplayCc" }, { PidTagOriginalDisplayCc_Error, PT_ERROR, "PidTagOriginalDisplayCc_Error" }, { PidTagOriginalDisplayName, PT_UNICODE, "PidTagOriginalDisplayName" }, { PidTagOriginalDisplayName_Error, PT_ERROR, "PidTagOriginalDisplayName_Error" }, { PidTagOriginalDisplayTo, PT_UNICODE, "PidTagOriginalDisplayTo" }, { PidTagOriginalDisplayTo_Error, PT_ERROR, "PidTagOriginalDisplayTo_Error" }, { PidTagOriginalEntryId, PT_BINARY, "PidTagOriginalEntryId" }, { PidTagOriginalEntryId_Error, PT_ERROR, "PidTagOriginalEntryId_Error" }, { PidTagOriginalMessageClass, PT_UNICODE, "PidTagOriginalMessageClass" }, { PidTagOriginalMessageClass_Error, PT_ERROR, "PidTagOriginalMessageClass_Error" }, { PidTagOriginalMessageId, PT_UNICODE, "PidTagOriginalMessageId" }, { PidTagOriginalMessageId_Error, PT_ERROR, "PidTagOriginalMessageId_Error" }, { PidTagOriginalSearchKey, PT_BINARY, "PidTagOriginalSearchKey" }, { PidTagOriginalSearchKey_Error, PT_ERROR, "PidTagOriginalSearchKey_Error" }, { PidTagOriginalSenderAddressType, PT_UNICODE, "PidTagOriginalSenderAddressType" }, { PidTagOriginalSenderAddressType_Error, PT_ERROR, "PidTagOriginalSenderAddressType_Error" }, { PidTagOriginalSenderEmailAddress, PT_UNICODE, "PidTagOriginalSenderEmailAddress" }, { PidTagOriginalSenderEmailAddress_Error, PT_ERROR, "PidTagOriginalSenderEmailAddress_Error" }, { PidTagOriginalSenderEntryId, PT_BINARY, "PidTagOriginalSenderEntryId" }, { PidTagOriginalSenderEntryId_Error, PT_ERROR, "PidTagOriginalSenderEntryId_Error" }, { PidTagOriginalSenderName, PT_UNICODE, "PidTagOriginalSenderName" }, { PidTagOriginalSenderName_Error, PT_ERROR, "PidTagOriginalSenderName_Error" }, { PidTagOriginalSenderSearchKey, PT_BINARY, "PidTagOriginalSenderSearchKey" }, { PidTagOriginalSenderSearchKey_Error, PT_ERROR, "PidTagOriginalSenderSearchKey_Error" }, { PidTagOriginalSensitivity, PT_LONG, "PidTagOriginalSensitivity" }, { PidTagOriginalSensitivity_Error, PT_ERROR, "PidTagOriginalSensitivity_Error" }, { PidTagOriginalSentRepresentingAddressType, PT_UNICODE, "PidTagOriginalSentRepresentingAddressType" }, { PidTagOriginalSentRepresentingAddressType_Error, PT_ERROR, "PidTagOriginalSentRepresentingAddressType_Error" }, { PidTagOriginalSentRepresentingEmailAddress, PT_UNICODE, "PidTagOriginalSentRepresentingEmailAddress" }, { PidTagOriginalSentRepresentingEmailAddress_Error, PT_ERROR, "PidTagOriginalSentRepresentingEmailAddress_Error" }, { PidTagOriginalSentRepresentingEntryId, PT_BINARY, "PidTagOriginalSentRepresentingEntryId" }, { PidTagOriginalSentRepresentingEntryId_Error, PT_ERROR, "PidTagOriginalSentRepresentingEntryId_Error" }, { PidTagOriginalSentRepresentingName, PT_UNICODE, "PidTagOriginalSentRepresentingName" }, { PidTagOriginalSentRepresentingName_Error, PT_ERROR, "PidTagOriginalSentRepresentingName_Error" }, { PidTagOriginalSentRepresentingSearchKey, PT_BINARY, "PidTagOriginalSentRepresentingSearchKey" }, { PidTagOriginalSentRepresentingSearchKey_Error, PT_ERROR, "PidTagOriginalSentRepresentingSearchKey_Error" }, { PidTagOriginalSubject, PT_UNICODE, "PidTagOriginalSubject" }, { PidTagOriginalSubject_Error, PT_ERROR, "PidTagOriginalSubject_Error" }, { PidTagOriginalSubmitTime, PT_SYSTIME, "PidTagOriginalSubmitTime" }, { PidTagOriginalSubmitTime_Error, PT_ERROR, "PidTagOriginalSubmitTime_Error" }, { PidTagOriginatorDeliveryReportRequested, PT_BOOLEAN, "PidTagOriginatorDeliveryReportRequested" }, { PidTagOriginatorDeliveryReportRequested_Error, PT_ERROR, "PidTagOriginatorDeliveryReportRequested_Error" }, { PidTagOriginatorNonDeliveryReportRequested, PT_BOOLEAN, "PidTagOriginatorNonDeliveryReportRequested" }, { PidTagOriginatorNonDeliveryReportRequested_Error, PT_ERROR, "PidTagOriginatorNonDeliveryReportRequested_Error" }, { PidTagOtherAddressCity, PT_UNICODE, "PidTagOtherAddressCity" }, { PidTagOtherAddressCity_Error, PT_ERROR, "PidTagOtherAddressCity_Error" }, { PidTagOtherAddressCountry, PT_UNICODE, "PidTagOtherAddressCountry" }, { PidTagOtherAddressCountry_Error, PT_ERROR, "PidTagOtherAddressCountry_Error" }, { PidTagOtherAddressPostOfficeBox, PT_UNICODE, "PidTagOtherAddressPostOfficeBox" }, { PidTagOtherAddressPostOfficeBox_Error, PT_ERROR, "PidTagOtherAddressPostOfficeBox_Error" }, { PidTagOtherAddressPostalCode, PT_UNICODE, "PidTagOtherAddressPostalCode" }, { PidTagOtherAddressPostalCode_Error, PT_ERROR, "PidTagOtherAddressPostalCode_Error" }, { PidTagOtherAddressStateOrProvince, PT_UNICODE, "PidTagOtherAddressStateOrProvince" }, { PidTagOtherAddressStateOrProvince_Error, PT_ERROR, "PidTagOtherAddressStateOrProvince_Error" }, { PidTagOtherAddressStreet, PT_UNICODE, "PidTagOtherAddressStreet" }, { PidTagOtherAddressStreet_Error, PT_ERROR, "PidTagOtherAddressStreet_Error" }, { PidTagOtherTelephoneNumber, PT_UNICODE, "PidTagOtherTelephoneNumber" }, { PidTagOtherTelephoneNumber_Error, PT_ERROR, "PidTagOtherTelephoneNumber_Error" }, { PidTagOutOfOfficeState, PT_BOOLEAN, "PidTagOutOfOfficeState" }, { PidTagOutOfOfficeState_Error, PT_ERROR, "PidTagOutOfOfficeState_Error" }, { PidTagOwnerAppointmentId, PT_LONG, "PidTagOwnerAppointmentId" }, { PidTagOwnerAppointmentId_Error, PT_ERROR, "PidTagOwnerAppointmentId_Error" }, { PidTagPagerTelephoneNumber, PT_UNICODE, "PidTagPagerTelephoneNumber" }, { PidTagPagerTelephoneNumber_Error, PT_ERROR, "PidTagPagerTelephoneNumber_Error" }, { PidTagParentEntryId, PT_BINARY, "PidTagParentEntryId" }, { PidTagParentEntryId_Error, PT_ERROR, "PidTagParentEntryId_Error" }, { PidTagParentFolderId, PT_I8, "PidTagParentFolderId" }, { PidTagParentFolderId_Error, PT_ERROR, "PidTagParentFolderId_Error" }, { PidTagParentKey, PT_BINARY, "PidTagParentKey" }, { PidTagParentKey_Error, PT_ERROR, "PidTagParentKey_Error" }, { PidTagParentSourceKey, PT_BINARY, "PidTagParentSourceKey" }, { PidTagParentSourceKey_Error, PT_ERROR, "PidTagParentSourceKey_Error" }, { PidTagPersonalHomePage, PT_UNICODE, "PidTagPersonalHomePage" }, { PidTagPersonalHomePage_Error, PT_ERROR, "PidTagPersonalHomePage_Error" }, { PidTagPolicyTag, PT_BINARY, "PidTagPolicyTag" }, { PidTagPolicyTag_Error, PT_ERROR, "PidTagPolicyTag_Error" }, { PidTagPostOfficeBox, PT_UNICODE, "PidTagPostOfficeBox" }, { PidTagPostOfficeBox_Error, PT_ERROR, "PidTagPostOfficeBox_Error" }, { PidTagPostalAddress, PT_UNICODE, "PidTagPostalAddress" }, { PidTagPostalAddress_Error, PT_ERROR, "PidTagPostalAddress_Error" }, { PidTagPostalCode, PT_UNICODE, "PidTagPostalCode" }, { PidTagPostalCode_Error, PT_ERROR, "PidTagPostalCode_Error" }, { PidTagPredecessorChangeList, PT_BINARY, "PidTagPredecessorChangeList" }, { PidTagPredecessorChangeList_Error, PT_ERROR, "PidTagPredecessorChangeList_Error" }, { PidTagPrimaryFaxNumber, PT_UNICODE, "PidTagPrimaryFaxNumber" }, { PidTagPrimaryFaxNumber_Error, PT_ERROR, "PidTagPrimaryFaxNumber_Error" }, { PidTagPrimarySendAccount, PT_UNICODE, "PidTagPrimarySendAccount" }, { PidTagPrimarySendAccount_Error, PT_ERROR, "PidTagPrimarySendAccount_Error" }, { PidTagPrimarySmtpAddress, PT_UNICODE, "PidTagPrimarySmtpAddress" }, { PidTagPrimarySmtpAddress_Error, PT_ERROR, "PidTagPrimarySmtpAddress_Error" }, { PidTagPrimaryTelephoneNumber, PT_UNICODE, "PidTagPrimaryTelephoneNumber" }, { PidTagPrimaryTelephoneNumber_Error, PT_ERROR, "PidTagPrimaryTelephoneNumber_Error" }, { PidTagPriority, PT_LONG, "PidTagPriority" }, { PidTagPriority_Error, PT_ERROR, "PidTagPriority_Error" }, { PidTagProcessed, PT_BOOLEAN, "PidTagProcessed" }, { PidTagProcessed_Error, PT_ERROR, "PidTagProcessed_Error" }, { PidTagProfession, PT_UNICODE, "PidTagProfession" }, { PidTagProfession_Error, PT_ERROR, "PidTagProfession_Error" }, { PidTagProhibitReceiveQuota, PT_LONG, "PidTagProhibitReceiveQuota" }, { PidTagProhibitReceiveQuota_Error, PT_ERROR, "PidTagProhibitReceiveQuota_Error" }, { PidTagProhibitSendQuota, PT_LONG, "PidTagProhibitSendQuota" }, { PidTagProhibitSendQuota_Error, PT_ERROR, "PidTagProhibitSendQuota_Error" }, { PidTagProviderSubmitTime, PT_SYSTIME, "PidTagProviderSubmitTime" }, { PidTagProviderSubmitTime_Error, PT_ERROR, "PidTagProviderSubmitTime_Error" }, { PidTagPublicFolderAdministrativeDescription, PT_UNICODE, "PidTagPublicFolderAdministrativeDescription" }, { PidTagPublicFolderAdministrativeDescription_Error, PT_ERROR, "PidTagPublicFolderAdministrativeDescription_Error" }, { PidTagPublicFolderProxy, PT_BINARY, "PidTagPublicFolderProxy" }, { PidTagPublicFolderProxy_Error, PT_ERROR, "PidTagPublicFolderProxy_Error" }, { PidTagPurportedSenderDomain, PT_UNICODE, "PidTagPurportedSenderDomain" }, { PidTagPurportedSenderDomain_Error, PT_ERROR, "PidTagPurportedSenderDomain_Error" }, { PidTagRadioTelephoneNumber, PT_UNICODE, "PidTagRadioTelephoneNumber" }, { PidTagRadioTelephoneNumber_Error, PT_ERROR, "PidTagRadioTelephoneNumber_Error" }, { PidTagRead, PT_BOOLEAN, "PidTagRead" }, { PidTagReadReceiptAddressType, PT_UNICODE, "PidTagReadReceiptAddressType" }, { PidTagReadReceiptAddressType_Error, PT_ERROR, "PidTagReadReceiptAddressType_Error" }, { PidTagReadReceiptEmailAddress, PT_UNICODE, "PidTagReadReceiptEmailAddress" }, { PidTagReadReceiptEmailAddress_Error, PT_ERROR, "PidTagReadReceiptEmailAddress_Error" }, { PidTagReadReceiptEntryId, PT_BINARY, "PidTagReadReceiptEntryId" }, { PidTagReadReceiptEntryId_Error, PT_ERROR, "PidTagReadReceiptEntryId_Error" }, { PidTagReadReceiptName, PT_UNICODE, "PidTagReadReceiptName" }, { PidTagReadReceiptName_Error, PT_ERROR, "PidTagReadReceiptName_Error" }, { PidTagReadReceiptRequested, PT_BOOLEAN, "PidTagReadReceiptRequested" }, { PidTagReadReceiptRequested_Error, PT_ERROR, "PidTagReadReceiptRequested_Error" }, { PidTagReadReceiptSearchKey, PT_BINARY, "PidTagReadReceiptSearchKey" }, { PidTagReadReceiptSearchKey_Error, PT_ERROR, "PidTagReadReceiptSearchKey_Error" }, { PidTagRead_Error, PT_ERROR, "PidTagRead_Error" }, { PidTagReceivedByAddressType, PT_UNICODE, "PidTagReceivedByAddressType" }, { PidTagReceivedByAddressType_Error, PT_ERROR, "PidTagReceivedByAddressType_Error" }, { PidTagReceivedByEmailAddress, PT_UNICODE, "PidTagReceivedByEmailAddress" }, { PidTagReceivedByEmailAddress_Error, PT_ERROR, "PidTagReceivedByEmailAddress_Error" }, { PidTagReceivedByEntryId, PT_BINARY, "PidTagReceivedByEntryId" }, { PidTagReceivedByEntryId_Error, PT_ERROR, "PidTagReceivedByEntryId_Error" }, { PidTagReceivedByFlags, PT_LONG, "PidTagReceivedByFlags" }, { PidTagReceivedByFlags_Error, PT_ERROR, "PidTagReceivedByFlags_Error" }, { PidTagReceivedByName, PT_UNICODE, "PidTagReceivedByName" }, { PidTagReceivedByName_Error, PT_ERROR, "PidTagReceivedByName_Error" }, { PidTagReceivedBySearchKey, PT_BINARY, "PidTagReceivedBySearchKey" }, { PidTagReceivedBySearchKey_Error, PT_ERROR, "PidTagReceivedBySearchKey_Error" }, { PidTagReceivedRepresentingAddressType, PT_UNICODE, "PidTagReceivedRepresentingAddressType" }, { PidTagReceivedRepresentingAddressType_Error, PT_ERROR, "PidTagReceivedRepresentingAddressType_Error" }, { PidTagReceivedRepresentingEmailAddress, PT_UNICODE, "PidTagReceivedRepresentingEmailAddress" }, { PidTagReceivedRepresentingEmailAddress_Error, PT_ERROR, "PidTagReceivedRepresentingEmailAddress_Error" }, { PidTagReceivedRepresentingEntryId, PT_BINARY, "PidTagReceivedRepresentingEntryId" }, { PidTagReceivedRepresentingEntryId_Error, PT_ERROR, "PidTagReceivedRepresentingEntryId_Error" }, { PidTagReceivedRepresentingFlags, PT_LONG, "PidTagReceivedRepresentingFlags" }, { PidTagReceivedRepresentingFlags_Error, PT_ERROR, "PidTagReceivedRepresentingFlags_Error" }, { PidTagReceivedRepresentingName, PT_UNICODE, "PidTagReceivedRepresentingName" }, { PidTagReceivedRepresentingName_Error, PT_ERROR, "PidTagReceivedRepresentingName_Error" }, { PidTagReceivedRepresentingSearchKey, PT_BINARY, "PidTagReceivedRepresentingSearchKey" }, { PidTagReceivedRepresentingSearchKey_Error, PT_ERROR, "PidTagReceivedRepresentingSearchKey_Error" }, { PidTagReceivedRepresentingSimpleDisplayName, PT_UNICODE, "PidTagReceivedRepresentingSimpleDisplayName" }, { PidTagReceivedRepresentingSimpleDisplayName_Error, PT_ERROR, "PidTagReceivedRepresentingSimpleDisplayName_Error" }, { PidTagRecipientDisplayName, PT_UNICODE, "PidTagRecipientDisplayName" }, { PidTagRecipientDisplayName_Error, PT_ERROR, "PidTagRecipientDisplayName_Error" }, { PidTagRecipientEntryId, PT_BINARY, "PidTagRecipientEntryId" }, { PidTagRecipientEntryId_Error, PT_ERROR, "PidTagRecipientEntryId_Error" }, { PidTagRecipientFlags, PT_LONG, "PidTagRecipientFlags" }, { PidTagRecipientFlags_Error, PT_ERROR, "PidTagRecipientFlags_Error" }, { PidTagRecipientOrder, PT_LONG, "PidTagRecipientOrder" }, { PidTagRecipientOrder_Error, PT_ERROR, "PidTagRecipientOrder_Error" }, { PidTagRecipientProposed, PT_BOOLEAN, "PidTagRecipientProposed" }, { PidTagRecipientProposedEndTime, PT_SYSTIME, "PidTagRecipientProposedEndTime" }, { PidTagRecipientProposedEndTime_Error, PT_ERROR, "PidTagRecipientProposedEndTime_Error" }, { PidTagRecipientProposedStartTime, PT_SYSTIME, "PidTagRecipientProposedStartTime" }, { PidTagRecipientProposedStartTime_Error, PT_ERROR, "PidTagRecipientProposedStartTime_Error" }, { PidTagRecipientProposed_Error, PT_ERROR, "PidTagRecipientProposed_Error" }, { PidTagRecipientReassignmentProhibited, PT_BOOLEAN, "PidTagRecipientReassignmentProhibited" }, { PidTagRecipientReassignmentProhibited_Error, PT_ERROR, "PidTagRecipientReassignmentProhibited_Error" }, { PidTagRecipientResourceState, PT_LONG, "PidTagRecipientResourceState" }, { PidTagRecipientResourceState_Error, PT_ERROR, "PidTagRecipientResourceState_Error" }, { PidTagRecipientTrackStatus, PT_LONG, "PidTagRecipientTrackStatus" }, { PidTagRecipientTrackStatusTime, PT_SYSTIME, "PidTagRecipientTrackStatusTime" }, { PidTagRecipientTrackStatusTime_Error, PT_ERROR, "PidTagRecipientTrackStatusTime_Error" }, { PidTagRecipientTrackStatus_Error, PT_ERROR, "PidTagRecipientTrackStatus_Error" }, { PidTagRecipientType, PT_LONG, "PidTagRecipientType" }, { PidTagRecipientType_Error, PT_ERROR, "PidTagRecipientType_Error" }, { PidTagRecordKey, PT_BINARY, "PidTagRecordKey" }, { PidTagRecordKey_Error, PT_ERROR, "PidTagRecordKey_Error" }, { PidTagReferredByName, PT_UNICODE, "PidTagReferredByName" }, { PidTagReferredByName_Error, PT_ERROR, "PidTagReferredByName_Error" }, { PidTagRemindersOnlineEntryId, PT_BINARY, "PidTagRemindersOnlineEntryId" }, { PidTagRemindersOnlineEntryId_Error, PT_ERROR, "PidTagRemindersOnlineEntryId_Error" }, { PidTagRemoteHeaderLoc, PT_UNICODE, "PidTagRemoteHeaderLoc" }, { PidTagRemoteHeaderLoc_Error, PT_ERROR, "PidTagRemoteHeaderLoc_Error" }, { PidTagRemoteMessageTransferAgent, PT_UNICODE, "PidTagRemoteMessageTransferAgent" }, { PidTagRemoteMessageTransferAgent_Error, PT_ERROR, "PidTagRemoteMessageTransferAgent_Error" }, { PidTagRenderingPosition, PT_LONG, "PidTagRenderingPosition" }, { PidTagRenderingPosition_Error, PT_ERROR, "PidTagRenderingPosition_Error" }, { PidTagReplyRecipientEntries, PT_BINARY, "PidTagReplyRecipientEntries" }, { PidTagReplyRecipientEntries_Error, PT_ERROR, "PidTagReplyRecipientEntries_Error" }, { PidTagReplyRecipientNames, PT_UNICODE, "PidTagReplyRecipientNames" }, { PidTagReplyRecipientNames_Error, PT_ERROR, "PidTagReplyRecipientNames_Error" }, { PidTagReplyRequested, PT_BOOLEAN, "PidTagReplyRequested" }, { PidTagReplyRequested_Error, PT_ERROR, "PidTagReplyRequested_Error" }, { PidTagReplyTemplateId, PT_BINARY, "PidTagReplyTemplateId" }, { PidTagReplyTemplateId_Error, PT_ERROR, "PidTagReplyTemplateId_Error" }, { PidTagReplyTime, PT_SYSTIME, "PidTagReplyTime" }, { PidTagReplyTime_Error, PT_ERROR, "PidTagReplyTime_Error" }, { PidTagReportEntryId, PT_BINARY, "PidTagReportEntryId" }, { PidTagReportEntryId_Error, PT_ERROR, "PidTagReportEntryId_Error" }, { PidTagReportName, PT_UNICODE, "PidTagReportName" }, { PidTagReportName_Error, PT_ERROR, "PidTagReportName_Error" }, { PidTagReportSearchKey, PT_BINARY, "PidTagReportSearchKey" }, { PidTagReportSearchKey_Error, PT_ERROR, "PidTagReportSearchKey_Error" }, { PidTagReportTag, PT_BINARY, "PidTagReportTag" }, { PidTagReportTag_Error, PT_ERROR, "PidTagReportTag_Error" }, { PidTagReportText, PT_UNICODE, "PidTagReportText" }, { PidTagReportText_Error, PT_ERROR, "PidTagReportText_Error" }, { PidTagReportTime, PT_SYSTIME, "PidTagReportTime" }, { PidTagReportTime_Error, PT_ERROR, "PidTagReportTime_Error" }, { PidTagReportingMessageTransferAgent, PT_UNICODE, "PidTagReportingMessageTransferAgent" }, { PidTagReportingMessageTransferAgent_Error, PT_ERROR, "PidTagReportingMessageTransferAgent_Error" }, { PidTagResolveMethod, PT_LONG, "PidTagResolveMethod" }, { PidTagResolveMethod_Error, PT_ERROR, "PidTagResolveMethod_Error" }, { PidTagResponseRequested, PT_BOOLEAN, "PidTagResponseRequested" }, { PidTagResponseRequested_Error, PT_ERROR, "PidTagResponseRequested_Error" }, { PidTagResponsibility, PT_BOOLEAN, "PidTagResponsibility" }, { PidTagResponsibility_Error, PT_ERROR, "PidTagResponsibility_Error" }, { PidTagRetentionDate, PT_SYSTIME, "PidTagRetentionDate" }, { PidTagRetentionDate_Error, PT_ERROR, "PidTagRetentionDate_Error" }, { PidTagRetentionFlags, PT_LONG, "PidTagRetentionFlags" }, { PidTagRetentionFlags_Error, PT_ERROR, "PidTagRetentionFlags_Error" }, { PidTagRetentionPeriod, PT_LONG, "PidTagRetentionPeriod" }, { PidTagRetentionPeriod_Error, PT_ERROR, "PidTagRetentionPeriod_Error" }, { PidTagRights, PT_LONG, "PidTagRights" }, { PidTagRights_Error, PT_ERROR, "PidTagRights_Error" }, { PidTagRoamingDatatypes, PT_LONG, "PidTagRoamingDatatypes" }, { PidTagRoamingDatatypes_Error, PT_ERROR, "PidTagRoamingDatatypes_Error" }, { PidTagRoamingDictionary, PT_BINARY, "PidTagRoamingDictionary" }, { PidTagRoamingDictionary_Error, PT_ERROR, "PidTagRoamingDictionary_Error" }, { PidTagRoamingXmlStream, PT_BINARY, "PidTagRoamingXmlStream" }, { PidTagRoamingXmlStream_Error, PT_ERROR, "PidTagRoamingXmlStream_Error" }, { PidTagRowType, PT_LONG, "PidTagRowType" }, { PidTagRowType_Error, PT_ERROR, "PidTagRowType_Error" }, { PidTagRowid, PT_LONG, "PidTagRowid" }, { PidTagRowid_Error, PT_ERROR, "PidTagRowid_Error" }, { PidTagRtfCompressed, PT_BINARY, "PidTagRtfCompressed" }, { PidTagRtfCompressed_Error, PT_ERROR, "PidTagRtfCompressed_Error" }, { PidTagRtfInSync, PT_BOOLEAN, "PidTagRtfInSync" }, { PidTagRtfInSync_Error, PT_ERROR, "PidTagRtfInSync_Error" }, { PidTagRtfSyncBodyCount, PT_LONG, "PidTagRtfSyncBodyCount" }, { PidTagRtfSyncBodyCount_Error, PT_ERROR, "PidTagRtfSyncBodyCount_Error" }, { PidTagRtfSyncBodyCrc, PT_LONG, "PidTagRtfSyncBodyCrc" }, { PidTagRtfSyncBodyCrc_Error, PT_ERROR, "PidTagRtfSyncBodyCrc_Error" }, { PidTagRtfSyncBodyTag, PT_UNICODE, "PidTagRtfSyncBodyTag" }, { PidTagRtfSyncBodyTag_Error, PT_ERROR, "PidTagRtfSyncBodyTag_Error" }, { PidTagRtfSyncPrefixCount, PT_LONG, "PidTagRtfSyncPrefixCount" }, { PidTagRtfSyncPrefixCount_Error, PT_ERROR, "PidTagRtfSyncPrefixCount_Error" }, { PidTagRtfSyncTrailingCount, PT_LONG, "PidTagRtfSyncTrailingCount" }, { PidTagRtfSyncTrailingCount_Error, PT_ERROR, "PidTagRtfSyncTrailingCount_Error" }, { PidTagRuleActionNumber, PT_LONG, "PidTagRuleActionNumber" }, { PidTagRuleActionNumber_Error, PT_ERROR, "PidTagRuleActionNumber_Error" }, { PidTagRuleActionType, PT_LONG, "PidTagRuleActionType" }, { PidTagRuleActionType_Error, PT_ERROR, "PidTagRuleActionType_Error" }, { PidTagRuleActions, PT_ACTIONS, "PidTagRuleActions" }, { PidTagRuleActions_Error, PT_ERROR, "PidTagRuleActions_Error" }, { PidTagRuleCondition, PT_SRESTRICT, "PidTagRuleCondition" }, { PidTagRuleCondition_Error, PT_ERROR, "PidTagRuleCondition_Error" }, { PidTagRuleError, PT_LONG, "PidTagRuleError" }, { PidTagRuleError_Error, PT_ERROR, "PidTagRuleError_Error" }, { PidTagRuleFolderEntryId, PT_BINARY, "PidTagRuleFolderEntryId" }, { PidTagRuleFolderEntryId_Error, PT_ERROR, "PidTagRuleFolderEntryId_Error" }, { PidTagRuleId, PT_I8, "PidTagRuleId" }, { PidTagRuleId_Error, PT_ERROR, "PidTagRuleId_Error" }, { PidTagRuleIds, PT_BINARY, "PidTagRuleIds" }, { PidTagRuleIds_Error, PT_ERROR, "PidTagRuleIds_Error" }, { PidTagRuleLevel, PT_LONG, "PidTagRuleLevel" }, { PidTagRuleLevel_Error, PT_ERROR, "PidTagRuleLevel_Error" }, { PidTagRuleMessageLevel, PT_LONG, "PidTagRuleMessageLevel" }, { PidTagRuleMessageLevel_Error, PT_ERROR, "PidTagRuleMessageLevel_Error" }, { PidTagRuleMessageName, PT_UNICODE, "PidTagRuleMessageName" }, { PidTagRuleMessageName_Error, PT_ERROR, "PidTagRuleMessageName_Error" }, { PidTagRuleMessageProvider, PT_UNICODE, "PidTagRuleMessageProvider" }, { PidTagRuleMessageProviderData, PT_BINARY, "PidTagRuleMessageProviderData" }, { PidTagRuleMessageProviderData_Error, PT_ERROR, "PidTagRuleMessageProviderData_Error" }, { PidTagRuleMessageProvider_Error, PT_ERROR, "PidTagRuleMessageProvider_Error" }, { PidTagRuleMessageSequence, PT_LONG, "PidTagRuleMessageSequence" }, { PidTagRuleMessageSequence_Error, PT_ERROR, "PidTagRuleMessageSequence_Error" }, { PidTagRuleMessageState, PT_LONG, "PidTagRuleMessageState" }, { PidTagRuleMessageState_Error, PT_ERROR, "PidTagRuleMessageState_Error" }, { PidTagRuleMessageUserFlags, PT_LONG, "PidTagRuleMessageUserFlags" }, { PidTagRuleMessageUserFlags_Error, PT_ERROR, "PidTagRuleMessageUserFlags_Error" }, { PidTagRuleName, PT_UNICODE, "PidTagRuleName" }, { PidTagRuleName_Error, PT_ERROR, "PidTagRuleName_Error" }, { PidTagRuleProvider, PT_UNICODE, "PidTagRuleProvider" }, { PidTagRuleProviderData, PT_BINARY, "PidTagRuleProviderData" }, { PidTagRuleProviderData_Error, PT_ERROR, "PidTagRuleProviderData_Error" }, { PidTagRuleProvider_Error, PT_ERROR, "PidTagRuleProvider_Error" }, { PidTagRuleSequence, PT_LONG, "PidTagRuleSequence" }, { PidTagRuleSequence_Error, PT_ERROR, "PidTagRuleSequence_Error" }, { PidTagRuleState, PT_LONG, "PidTagRuleState" }, { PidTagRuleState_Error, PT_ERROR, "PidTagRuleState_Error" }, { PidTagRuleUserFlags, PT_LONG, "PidTagRuleUserFlags" }, { PidTagRuleUserFlags_Error, PT_ERROR, "PidTagRuleUserFlags_Error" }, { PidTagRwRulesStream, PT_BINARY, "PidTagRwRulesStream" }, { PidTagRwRulesStream_Error, PT_ERROR, "PidTagRwRulesStream_Error" }, { PidTagScheduleInfoAppointmentTombstone, PT_BINARY, "PidTagScheduleInfoAppointmentTombstone" }, { PidTagScheduleInfoAppointmentTombstone_Error, PT_ERROR, "PidTagScheduleInfoAppointmentTombstone_Error" }, { PidTagScheduleInfoAutoAcceptAppointments, PT_BOOLEAN, "PidTagScheduleInfoAutoAcceptAppointments" }, { PidTagScheduleInfoAutoAcceptAppointments_Error, PT_ERROR, "PidTagScheduleInfoAutoAcceptAppointments_Error" }, { PidTagScheduleInfoDelegateEntryIds, PT_MV_BINARY, "PidTagScheduleInfoDelegateEntryIds" }, { PidTagScheduleInfoDelegateEntryIds_Error, PT_ERROR, "PidTagScheduleInfoDelegateEntryIds_Error" }, { PidTagScheduleInfoDelegateNames, PT_MV_UNICODE,"PidTagScheduleInfoDelegateNames" }, { PidTagScheduleInfoDelegateNamesW, PT_MV_UNICODE,"PidTagScheduleInfoDelegateNamesW" }, { PidTagScheduleInfoDelegateNamesW_Error, PT_ERROR, "PidTagScheduleInfoDelegateNamesW_Error" }, { PidTagScheduleInfoDelegateNames_Error, PT_ERROR, "PidTagScheduleInfoDelegateNames_Error" }, { PidTagScheduleInfoDelegatorWantsCopy, PT_BOOLEAN, "PidTagScheduleInfoDelegatorWantsCopy" }, { PidTagScheduleInfoDelegatorWantsCopy_Error, PT_ERROR, "PidTagScheduleInfoDelegatorWantsCopy_Error" }, { PidTagScheduleInfoDelegatorWantsInfo, PT_BOOLEAN, "PidTagScheduleInfoDelegatorWantsInfo" }, { PidTagScheduleInfoDelegatorWantsInfo_Error, PT_ERROR, "PidTagScheduleInfoDelegatorWantsInfo_Error" }, { PidTagScheduleInfoDisallowOverlappingAppts, PT_BOOLEAN, "PidTagScheduleInfoDisallowOverlappingAppts" }, { PidTagScheduleInfoDisallowOverlappingAppts_Error, PT_ERROR, "PidTagScheduleInfoDisallowOverlappingAppts_Error" }, { PidTagScheduleInfoDisallowRecurringAppts, PT_BOOLEAN, "PidTagScheduleInfoDisallowRecurringAppts" }, { PidTagScheduleInfoDisallowRecurringAppts_Error, PT_ERROR, "PidTagScheduleInfoDisallowRecurringAppts_Error" }, { PidTagScheduleInfoDontMailDelegates, PT_BOOLEAN, "PidTagScheduleInfoDontMailDelegates" }, { PidTagScheduleInfoDontMailDelegates_Error, PT_ERROR, "PidTagScheduleInfoDontMailDelegates_Error" }, { PidTagScheduleInfoFreeBusy, PT_BINARY, "PidTagScheduleInfoFreeBusy" }, { PidTagScheduleInfoFreeBusyAway, PT_MV_BINARY, "PidTagScheduleInfoFreeBusyAway" }, { PidTagScheduleInfoFreeBusyAway_Error, PT_ERROR, "PidTagScheduleInfoFreeBusyAway_Error" }, { PidTagScheduleInfoFreeBusyBusy, PT_MV_BINARY, "PidTagScheduleInfoFreeBusyBusy" }, { PidTagScheduleInfoFreeBusyBusy_Error, PT_ERROR, "PidTagScheduleInfoFreeBusyBusy_Error" }, { PidTagScheduleInfoFreeBusyMerged, PT_MV_BINARY, "PidTagScheduleInfoFreeBusyMerged" }, { PidTagScheduleInfoFreeBusyMerged_Error, PT_ERROR, "PidTagScheduleInfoFreeBusyMerged_Error" }, { PidTagScheduleInfoFreeBusyTentative, PT_MV_BINARY, "PidTagScheduleInfoFreeBusyTentative" }, { PidTagScheduleInfoFreeBusyTentative_Error, PT_ERROR, "PidTagScheduleInfoFreeBusyTentative_Error" }, { PidTagScheduleInfoFreeBusy_Error, PT_ERROR, "PidTagScheduleInfoFreeBusy_Error" }, { PidTagScheduleInfoMonthsAway, PT_MV_LONG, "PidTagScheduleInfoMonthsAway" }, { PidTagScheduleInfoMonthsAway_Error, PT_ERROR, "PidTagScheduleInfoMonthsAway_Error" }, { PidTagScheduleInfoMonthsBusy, PT_MV_LONG, "PidTagScheduleInfoMonthsBusy" }, { PidTagScheduleInfoMonthsBusy_Error, PT_ERROR, "PidTagScheduleInfoMonthsBusy_Error" }, { PidTagScheduleInfoMonthsMerged, PT_MV_LONG, "PidTagScheduleInfoMonthsMerged" }, { PidTagScheduleInfoMonthsMerged_Error, PT_ERROR, "PidTagScheduleInfoMonthsMerged_Error" }, { PidTagScheduleInfoMonthsTentative, PT_MV_LONG, "PidTagScheduleInfoMonthsTentative" }, { PidTagScheduleInfoMonthsTentative_Error, PT_ERROR, "PidTagScheduleInfoMonthsTentative_Error" }, { PidTagScheduleInfoResourceType, PT_LONG, "PidTagScheduleInfoResourceType" }, { PidTagScheduleInfoResourceType_Error, PT_ERROR, "PidTagScheduleInfoResourceType_Error" }, { PidTagSchedulePlusFreeBusyEntryId, PT_BINARY, "PidTagSchedulePlusFreeBusyEntryId" }, { PidTagSchedulePlusFreeBusyEntryId_Error, PT_ERROR, "PidTagSchedulePlusFreeBusyEntryId_Error" }, { PidTagScriptData, PT_BINARY, "PidTagScriptData" }, { PidTagScriptData_Error, PT_ERROR, "PidTagScriptData_Error" }, { PidTagSearchFolderDefinition, PT_BINARY, "PidTagSearchFolderDefinition" }, { PidTagSearchFolderDefinition_Error, PT_ERROR, "PidTagSearchFolderDefinition_Error" }, { PidTagSearchFolderEfpFlags, PT_LONG, "PidTagSearchFolderEfpFlags" }, { PidTagSearchFolderEfpFlags_Error, PT_ERROR, "PidTagSearchFolderEfpFlags_Error" }, { PidTagSearchFolderExpiration, PT_LONG, "PidTagSearchFolderExpiration" }, { PidTagSearchFolderExpiration_Error, PT_ERROR, "PidTagSearchFolderExpiration_Error" }, { PidTagSearchFolderId, PT_BINARY, "PidTagSearchFolderId" }, { PidTagSearchFolderId_Error, PT_ERROR, "PidTagSearchFolderId_Error" }, { PidTagSearchFolderLastUsed, PT_LONG, "PidTagSearchFolderLastUsed" }, { PidTagSearchFolderLastUsed_Error, PT_ERROR, "PidTagSearchFolderLastUsed_Error" }, { PidTagSearchFolderRecreateInfo, PT_BINARY, "PidTagSearchFolderRecreateInfo" }, { PidTagSearchFolderRecreateInfo_Error, PT_ERROR, "PidTagSearchFolderRecreateInfo_Error" }, { PidTagSearchFolderStorageType, PT_LONG, "PidTagSearchFolderStorageType" }, { PidTagSearchFolderStorageType_Error, PT_ERROR, "PidTagSearchFolderStorageType_Error" }, { PidTagSearchFolderTag, PT_LONG, "PidTagSearchFolderTag" }, { PidTagSearchFolderTag_Error, PT_ERROR, "PidTagSearchFolderTag_Error" }, { PidTagSearchFolderTemplateId, PT_LONG, "PidTagSearchFolderTemplateId" }, { PidTagSearchFolderTemplateId_Error, PT_ERROR, "PidTagSearchFolderTemplateId_Error" }, { PidTagSearchKey, PT_BINARY, "PidTagSearchKey" }, { PidTagSearchKey_Error, PT_ERROR, "PidTagSearchKey_Error" }, { PidTagSecureSubmitFlags, PT_LONG, "PidTagSecureSubmitFlags" }, { PidTagSecureSubmitFlags_Error, PT_ERROR, "PidTagSecureSubmitFlags_Error" }, { PidTagSecurityDescriptor, PT_BINARY, "PidTagSecurityDescriptor" }, { PidTagSecurityDescriptorAsXml, PT_UNICODE, "PidTagSecurityDescriptorAsXml" }, { PidTagSecurityDescriptorAsXml_Error, PT_ERROR, "PidTagSecurityDescriptorAsXml_Error" }, { PidTagSecurityDescriptor_Error, PT_ERROR, "PidTagSecurityDescriptor_Error" }, { PidTagSelectable, PT_BOOLEAN, "PidTagSelectable" }, { PidTagSelectable_Error, PT_ERROR, "PidTagSelectable_Error" }, { PidTagSendInternetEncoding, PT_LONG, "PidTagSendInternetEncoding" }, { PidTagSendInternetEncoding_Error, PT_ERROR, "PidTagSendInternetEncoding_Error" }, { PidTagSendRichInfo, PT_BOOLEAN, "PidTagSendRichInfo" }, { PidTagSendRichInfo_Error, PT_ERROR, "PidTagSendRichInfo_Error" }, { PidTagSenderAddressType, PT_UNICODE, "PidTagSenderAddressType" }, { PidTagSenderAddressType_Error, PT_ERROR, "PidTagSenderAddressType_Error" }, { PidTagSenderEmailAddress, PT_UNICODE, "PidTagSenderEmailAddress" }, { PidTagSenderEmailAddress_Error, PT_ERROR, "PidTagSenderEmailAddress_Error" }, { PidTagSenderEntryId, PT_BINARY, "PidTagSenderEntryId" }, { PidTagSenderEntryId_Error, PT_ERROR, "PidTagSenderEntryId_Error" }, { PidTagSenderFlags, PT_LONG, "PidTagSenderFlags" }, { PidTagSenderFlags_Error, PT_ERROR, "PidTagSenderFlags_Error" }, { PidTagSenderIdStatus, PT_LONG, "PidTagSenderIdStatus" }, { PidTagSenderIdStatus_Error, PT_ERROR, "PidTagSenderIdStatus_Error" }, { PidTagSenderName, PT_UNICODE, "PidTagSenderName" }, { PidTagSenderName_Error, PT_ERROR, "PidTagSenderName_Error" }, { PidTagSenderSearchKey, PT_BINARY, "PidTagSenderSearchKey" }, { PidTagSenderSearchKey_Error, PT_ERROR, "PidTagSenderSearchKey_Error" }, { PidTagSenderSimpleDisplayName, PT_UNICODE, "PidTagSenderSimpleDisplayName" }, { PidTagSenderSimpleDisplayName_Error, PT_ERROR, "PidTagSenderSimpleDisplayName_Error" }, { PidTagSenderSmtpAddress, PT_UNICODE, "PidTagSenderSmtpAddress" }, { PidTagSenderSmtpAddress_Error, PT_ERROR, "PidTagSenderSmtpAddress_Error" }, { PidTagSenderTelephoneNumber, PT_UNICODE, "PidTagSenderTelephoneNumber" }, { PidTagSenderTelephoneNumber_Error, PT_ERROR, "PidTagSenderTelephoneNumber_Error" }, { PidTagSensitivity, PT_LONG, "PidTagSensitivity" }, { PidTagSensitivity_Error, PT_ERROR, "PidTagSensitivity_Error" }, { PidTagSentMailSvrEID, PT_SVREID, "PidTagSentMailSvrEID" }, { PidTagSentMailSvrEID_Error, PT_ERROR, "PidTagSentMailSvrEID_Error" }, { PidTagSentRepresentingAddressType, PT_UNICODE, "PidTagSentRepresentingAddressType" }, { PidTagSentRepresentingAddressType_Error, PT_ERROR, "PidTagSentRepresentingAddressType_Error" }, { PidTagSentRepresentingEmailAddress, PT_UNICODE, "PidTagSentRepresentingEmailAddress" }, { PidTagSentRepresentingEmailAddress_Error, PT_ERROR, "PidTagSentRepresentingEmailAddress_Error" }, { PidTagSentRepresentingEntryId, PT_BINARY, "PidTagSentRepresentingEntryId" }, { PidTagSentRepresentingEntryId_Error, PT_ERROR, "PidTagSentRepresentingEntryId_Error" }, { PidTagSentRepresentingFlags, PT_LONG, "PidTagSentRepresentingFlags" }, { PidTagSentRepresentingFlags_Error, PT_ERROR, "PidTagSentRepresentingFlags_Error" }, { PidTagSentRepresentingName, PT_UNICODE, "PidTagSentRepresentingName" }, { PidTagSentRepresentingName_Error, PT_ERROR, "PidTagSentRepresentingName_Error" }, { PidTagSentRepresentingSearchKey, PT_BINARY, "PidTagSentRepresentingSearchKey" }, { PidTagSentRepresentingSearchKey_Error, PT_ERROR, "PidTagSentRepresentingSearchKey_Error" }, { PidTagSentRepresentingSimpleDisplayName, PT_UNICODE, "PidTagSentRepresentingSimpleDisplayName" }, { PidTagSentRepresentingSimpleDisplayName_Error, PT_ERROR, "PidTagSentRepresentingSimpleDisplayName_Error" }, { PidTagSessionInitiationProtocolUri, PT_UNICODE, "PidTagSessionInitiationProtocolUri" }, { PidTagSessionInitiationProtocolUri_Error, PT_ERROR, "PidTagSessionInitiationProtocolUri_Error" }, { PidTagSmtpAddress, PT_UNICODE, "PidTagSmtpAddress" }, { PidTagSmtpAddress_Error, PT_ERROR, "PidTagSmtpAddress_Error" }, { PidTagSortLocaleId, PT_LONG, "PidTagSortLocaleId" }, { PidTagSortLocaleId_Error, PT_ERROR, "PidTagSortLocaleId_Error" }, { PidTagSourceKey, PT_BINARY, "PidTagSourceKey" }, { PidTagSourceKey_Error, PT_ERROR, "PidTagSourceKey_Error" }, { PidTagSpokenName, PT_BINARY, "PidTagSpokenName" }, { PidTagSpokenName_Error, PT_ERROR, "PidTagSpokenName_Error" }, { PidTagSpouseName, PT_UNICODE, "PidTagSpouseName" }, { PidTagSpouseName_Error, PT_ERROR, "PidTagSpouseName_Error" }, { PidTagStartDate, PT_SYSTIME, "PidTagStartDate" }, { PidTagStartDateEtc, PT_BINARY, "PidTagStartDateEtc" }, { PidTagStartDateEtc_Error, PT_ERROR, "PidTagStartDateEtc_Error" }, { PidTagStartDate_Error, PT_ERROR, "PidTagStartDate_Error" }, { PidTagStartEmbed, PT_LONG, "PidTagStartEmbed" }, { PidTagStartEmbed_Error, PT_ERROR, "PidTagStartEmbed_Error" }, { PidTagStartFAIMsg, PT_LONG, "PidTagStartFAIMsg" }, { PidTagStartFAIMsg_Error, PT_ERROR, "PidTagStartFAIMsg_Error" }, { PidTagStartMessage, PT_LONG, "PidTagStartMessage" }, { PidTagStartMessage_Error, PT_ERROR, "PidTagStartMessage_Error" }, { PidTagStartRecip, PT_LONG, "PidTagStartRecip" }, { PidTagStartRecip_Error, PT_ERROR, "PidTagStartRecip_Error" }, { PidTagStartSubFld, PT_LONG, "PidTagStartSubFld" }, { PidTagStartSubFld_Error, PT_ERROR, "PidTagStartSubFld_Error" }, { PidTagStartTopFld, PT_LONG, "PidTagStartTopFld" }, { PidTagStartTopFld_Error, PT_ERROR, "PidTagStartTopFld_Error" }, { PidTagStateOrProvince, PT_UNICODE, "PidTagStateOrProvince" }, { PidTagStateOrProvince_Error, PT_ERROR, "PidTagStateOrProvince_Error" }, { PidTagStoreEntryId, PT_BINARY, "PidTagStoreEntryId" }, { PidTagStoreEntryId_Error, PT_ERROR, "PidTagStoreEntryId_Error" }, { PidTagStoreState, PT_LONG, "PidTagStoreState" }, { PidTagStoreState_Error, PT_ERROR, "PidTagStoreState_Error" }, { PidTagStoreSupportMask, PT_LONG, "PidTagStoreSupportMask" }, { PidTagStoreSupportMask_Error, PT_ERROR, "PidTagStoreSupportMask_Error" }, { PidTagStreetAddress, PT_UNICODE, "PidTagStreetAddress" }, { PidTagStreetAddress_Error, PT_ERROR, "PidTagStreetAddress_Error" }, { PidTagSubfolder, PT_BOOLEAN, "PidTagSubfolder" }, { PidTagSubfolder_Error, PT_ERROR, "PidTagSubfolder_Error" }, { PidTagSubfolders, PT_BOOLEAN, "PidTagSubfolders" }, { PidTagSubfolders_Error, PT_ERROR, "PidTagSubfolders_Error" }, { PidTagSubject, PT_UNICODE, "PidTagSubject" }, { PidTagSubjectPrefix, PT_UNICODE, "PidTagSubjectPrefix" }, { PidTagSubjectPrefix_Error, PT_ERROR, "PidTagSubjectPrefix_Error" }, { PidTagSubject_Error, PT_ERROR, "PidTagSubject_Error" }, { PidTagSurname, PT_UNICODE, "PidTagSurname" }, { PidTagSurname_Error, PT_ERROR, "PidTagSurname_Error" }, { PidTagSwappedToDoData, PT_BINARY, "PidTagSwappedToDoData" }, { PidTagSwappedToDoData_Error, PT_ERROR, "PidTagSwappedToDoData_Error" }, { PidTagSwappedToDoStore, PT_BINARY, "PidTagSwappedToDoStore" }, { PidTagSwappedToDoStore_Error, PT_ERROR, "PidTagSwappedToDoStore_Error" }, { PidTagTargetEntryId, PT_BINARY, "PidTagTargetEntryId" }, { PidTagTargetEntryId_Error, PT_ERROR, "PidTagTargetEntryId_Error" }, { PidTagTcvConstLongOne, PT_LONG, "PidTagTcvConstLongOne" }, { PidTagTcvConstLongOne_Error, PT_ERROR, "PidTagTcvConstLongOne_Error" }, { PidTagTelecommunicationsDeviceForDeafTelephoneNumber, PT_UNICODE, "PidTagTelecommunicationsDeviceForDeafTelephoneNumber" }, { PidTagTelecommunicationsDeviceForDeafTelephoneNumber_Error, PT_ERROR, "PidTagTelecommunicationsDeviceForDeafTelephoneNumber_Error" }, { PidTagTelexNumber, PT_UNICODE, "PidTagTelexNumber" }, { PidTagTelexNumber_Error, PT_ERROR, "PidTagTelexNumber_Error" }, { PidTagTemplateData, PT_BINARY, "PidTagTemplateData" }, { PidTagTemplateData_Error, PT_ERROR, "PidTagTemplateData_Error" }, { PidTagTemplateid, PT_BINARY, "PidTagTemplateid" }, { PidTagTemplateid_Error, PT_ERROR, "PidTagTemplateid_Error" }, { PidTagTemporaryDefaultDocument, PT_UNICODE, "PidTagTemporaryDefaultDocument" }, { PidTagTemporaryDefaultDocument_Error, PT_ERROR, "PidTagTemporaryDefaultDocument_Error" }, { PidTagTextAttachmentCharset, PT_UNICODE, "PidTagTextAttachmentCharset" }, { PidTagTextAttachmentCharset_Error, PT_ERROR, "PidTagTextAttachmentCharset_Error" }, { PidTagThumbnailPhoto, PT_BINARY, "PidTagThumbnailPhoto" }, { PidTagThumbnailPhoto_Error, PT_ERROR, "PidTagThumbnailPhoto_Error" }, { PidTagTitle, PT_UNICODE, "PidTagTitle" }, { PidTagTitle_Error, PT_ERROR, "PidTagTitle_Error" }, { PidTagTnefCorrelationKey, PT_BINARY, "PidTagTnefCorrelationKey" }, { PidTagTnefCorrelationKey_Error, PT_ERROR, "PidTagTnefCorrelationKey_Error" }, { PidTagToDoItemFlags, PT_LONG, "PidTagToDoItemFlags" }, { PidTagToDoItemFlags_Error, PT_ERROR, "PidTagToDoItemFlags_Error" }, { PidTagTransmittableDisplayName, PT_UNICODE, "PidTagTransmittableDisplayName" }, { PidTagTransmittableDisplayName_Error, PT_ERROR, "PidTagTransmittableDisplayName_Error" }, { PidTagTransportMessageHeaders, PT_UNICODE, "PidTagTransportMessageHeaders" }, { PidTagTransportMessageHeaders_Error, PT_ERROR, "PidTagTransportMessageHeaders_Error" }, { PidTagTrustSender, PT_LONG, "PidTagTrustSender" }, { PidTagTrustSender_Error, PT_ERROR, "PidTagTrustSender_Error" }, { PidTagTtyTddPhoneNumber, PT_UNICODE, "PidTagTtyTddPhoneNumber" }, { PidTagTtyTddPhoneNumber_Error, PT_ERROR, "PidTagTtyTddPhoneNumber_Error" }, { PidTagUrlCompName, PT_UNICODE, "PidTagUrlCompName" }, { PidTagUrlCompNameSet, PT_BOOLEAN, "PidTagUrlCompNameSet" }, { PidTagUrlCompNameSet_Error, PT_ERROR, "PidTagUrlCompNameSet_Error" }, { PidTagUrlCompName_Error, PT_ERROR, "PidTagUrlCompName_Error" }, { PidTagUrlName, PT_UNICODE, "PidTagUrlName" }, { PidTagUrlName_Error, PT_ERROR, "PidTagUrlName_Error" }, { PidTagUserCertificate, PT_BINARY, "PidTagUserCertificate" }, { PidTagUserCertificate_Error, PT_ERROR, "PidTagUserCertificate_Error" }, { PidTagUserEntryId, PT_BINARY, "PidTagUserEntryId" }, { PidTagUserEntryId_Error, PT_ERROR, "PidTagUserEntryId_Error" }, { PidTagUserX509Certificate, PT_MV_BINARY, "PidTagUserX509Certificate" }, { PidTagUserX509Certificate_Error, PT_ERROR, "PidTagUserX509Certificate_Error" }, { PidTagViewDescriptorBinary, PT_BINARY, "PidTagViewDescriptorBinary" }, { PidTagViewDescriptorBinary_Error, PT_ERROR, "PidTagViewDescriptorBinary_Error" }, { PidTagViewDescriptorName, PT_UNICODE, "PidTagViewDescriptorName" }, { PidTagViewDescriptorName_Error, PT_ERROR, "PidTagViewDescriptorName_Error" }, { PidTagViewDescriptorStrings, PT_UNICODE, "PidTagViewDescriptorStrings" }, { PidTagViewDescriptorStrings_Error, PT_ERROR, "PidTagViewDescriptorStrings_Error" }, { PidTagViewDescriptorVersion, PT_LONG, "PidTagViewDescriptorVersion" }, { PidTagViewDescriptorVersion_Error, PT_ERROR, "PidTagViewDescriptorVersion_Error" }, { PidTagVoiceMessageAttachmentOrder, PT_UNICODE, "PidTagVoiceMessageAttachmentOrder" }, { PidTagVoiceMessageAttachmentOrder_Error, PT_ERROR, "PidTagVoiceMessageAttachmentOrder_Error" }, { PidTagVoiceMessageDuration, PT_LONG, "PidTagVoiceMessageDuration" }, { PidTagVoiceMessageDuration_Error, PT_ERROR, "PidTagVoiceMessageDuration_Error" }, { PidTagVoiceMessageSenderName, PT_UNICODE, "PidTagVoiceMessageSenderName" }, { PidTagVoiceMessageSenderName_Error, PT_ERROR, "PidTagVoiceMessageSenderName_Error" }, { PidTagWeddingAnniversary, PT_SYSTIME, "PidTagWeddingAnniversary" }, { PidTagWeddingAnniversary_Error, PT_ERROR, "PidTagWeddingAnniversary_Error" }, { PidTagWlinkAddressBookEID, PT_BINARY, "PidTagWlinkAddressBookEID" }, { PidTagWlinkAddressBookEID_Error, PT_ERROR, "PidTagWlinkAddressBookEID_Error" }, { PidTagWlinkAddressBookStoreEID, PT_BINARY, "PidTagWlinkAddressBookStoreEID" }, { PidTagWlinkAddressBookStoreEID_Error, PT_ERROR, "PidTagWlinkAddressBookStoreEID_Error" }, { PidTagWlinkCalendarColor, PT_LONG, "PidTagWlinkCalendarColor" }, { PidTagWlinkCalendarColor_Error, PT_ERROR, "PidTagWlinkCalendarColor_Error" }, { PidTagWlinkClientID, PT_CLSID, "PidTagWlinkClientID" }, { PidTagWlinkClientID_Error, PT_ERROR, "PidTagWlinkClientID_Error" }, { PidTagWlinkEntryId, PT_BINARY, "PidTagWlinkEntryId" }, { PidTagWlinkEntryId_Error, PT_ERROR, "PidTagWlinkEntryId_Error" }, { PidTagWlinkFlags, PT_LONG, "PidTagWlinkFlags" }, { PidTagWlinkFlags_Error, PT_ERROR, "PidTagWlinkFlags_Error" }, { PidTagWlinkFolderType, PT_CLSID, "PidTagWlinkFolderType" }, { PidTagWlinkFolderType_Error, PT_ERROR, "PidTagWlinkFolderType_Error" }, { PidTagWlinkGroupClsid, PT_CLSID, "PidTagWlinkGroupClsid" }, { PidTagWlinkGroupClsid_Error, PT_ERROR, "PidTagWlinkGroupClsid_Error" }, { PidTagWlinkGroupHeaderID, PT_CLSID, "PidTagWlinkGroupHeaderID" }, { PidTagWlinkGroupHeaderID_Error, PT_ERROR, "PidTagWlinkGroupHeaderID_Error" }, { PidTagWlinkGroupName, PT_UNICODE, "PidTagWlinkGroupName" }, { PidTagWlinkGroupName_Error, PT_ERROR, "PidTagWlinkGroupName_Error" }, { PidTagWlinkOrdinal, PT_BINARY, "PidTagWlinkOrdinal" }, { PidTagWlinkOrdinal_Error, PT_ERROR, "PidTagWlinkOrdinal_Error" }, { PidTagWlinkROGroupType, PT_LONG, "PidTagWlinkROGroupType" }, { PidTagWlinkROGroupType_Error, PT_ERROR, "PidTagWlinkROGroupType_Error" }, { PidTagWlinkRecordKey, PT_BINARY, "PidTagWlinkRecordKey" }, { PidTagWlinkRecordKey_Error, PT_ERROR, "PidTagWlinkRecordKey_Error" }, { PidTagWlinkSaveStamp, PT_LONG, "PidTagWlinkSaveStamp" }, { PidTagWlinkSaveStamp_Error, PT_ERROR, "PidTagWlinkSaveStamp_Error" }, { PidTagWlinkSection, PT_LONG, "PidTagWlinkSection" }, { PidTagWlinkSection_Error, PT_ERROR, "PidTagWlinkSection_Error" }, { PidTagWlinkStoreEntryId, PT_BINARY, "PidTagWlinkStoreEntryId" }, { PidTagWlinkStoreEntryId_Error, PT_ERROR, "PidTagWlinkStoreEntryId_Error" }, { PidTagWlinkType, PT_LONG, "PidTagWlinkType" }, { PidTagWlinkType_Error, PT_ERROR, "PidTagWlinkType_Error" }, { openchange_private_ROOT_FOLDER_FID, PT_I8, "openchange_private_ROOT_FOLDER_FID" }, { openchange_private_DEFERRED_ACTIONS_FID, PT_I8, "openchange_private_DEFERRED_ACTIONS_FID" }, { openchange_private_SPOOLER_QUEUE_FID, PT_I8, "openchange_private_SPOOLER_QUEUE_FID" }, { openchange_private_IPM_SUBTREE_FID, PT_I8, "openchange_private_IPM_SUBTREE_FID" }, { openchange_private_INBOX_FID, PT_I8, "openchange_private_INBOX_FID" }, { openchange_private_OUTBOX_FID, PT_I8, "openchange_private_OUTBOX_FID" }, { openchange_private_SENT_ITEMS_FID, PT_I8, "openchange_private_SENT_ITEMS_FID" }, { openchange_private_DELETED_ITEMS_FID, PT_I8, "openchange_private_DELETED_ITEMS_FID" }, { openchange_private_COMMON_VIEWS_FID, PT_I8, "openchange_private_COMMON_VIEWS_FID" }, { openchange_private_SCHEDULE_FID, PT_I8, "openchange_private_SCHEDULE_FID" }, { openchange_private_SEARCH_FID, PT_I8, "openchange_private_SEARCH_FID" }, { openchange_private_VIEWS_FID, PT_I8, "openchange_private_VIEWS_FID" }, { openchange_private_SHORTCUTS_FID, PT_I8, "openchange_private_SHORTCUTS_FID" }, { openchange_private_MailboxGUID, PT_CLSID, "openchange_private_MailboxGUID" }, { openchange_private_ReplicaID, PT_SHORT, "openchange_private_ReplicaID" }, { openchange_private_ReplicaGUID, PT_CLSID, "openchange_private_ReplicaGUID" }, { openchange_private_CONTACT_FID, PT_I8, "openchange_private_CONTACT_FID" }, { openchange_private_CALENDAR_FID, PT_I8, "openchange_private_CALENDAR_FID" }, { openchange_private_JOURNAL_FID, PT_I8, "openchange_private_JOURNAL_FID" }, { openchange_private_NOTE_FID, PT_I8, "openchange_private_NOTE_FID" }, { openchange_private_TASK_FID, PT_I8, "openchange_private_TASK_FID" }, { openchange_private_DRAFTS_FID, PT_I8, "openchange_private_DRAFTS_FID" }, { openchange_private_PF_ROOT, PT_I8, "openchange_private_PF_ROOT" }, { openchange_private_PF_IPM_SUBTREE, PT_I8, "openchange_private_PF_IPM_SUBTREE" }, { openchange_private_PF_NONIPM_SUBTREE, PT_I8, "openchange_private_PF_NONIPM_SUBTREE" }, { openchange_private_PF_EFORMS, PT_I8, "openchange_private_PF_EFORMS" }, { openchange_private_PF_FREEBUSY, PT_I8, "openchange_private_PF_FREEBUSY" }, { openchange_private_PF_OAB, PT_I8, "openchange_private_PF_OAB" }, { openchange_private_PF_LOCAL_EFORMS, PT_I8, "openchange_private_PF_LOCAL_EFORMS" }, { openchange_private_PF_LOCAL_FREEBUSY, PT_I8, "openchange_private_PF_LOCAL_FREEBUSY" }, { openchange_private_PF_LOCAL_OAB, PT_I8, "openchange_private_PF_LOCAL_OAB" }, { 0, 0, "NULL" } }; _PUBLIC_ const char *get_proptag_name(uint32_t proptag) { uint32_t idx; for (idx = 0; canonical_property_tags[idx].proptag; idx++) { if (canonical_property_tags[idx].proptag == proptag) { return canonical_property_tags[idx].propname; } } if (((proptag & 0xFFFF) == PT_STRING8) || ((proptag & 0xFFFF) == PT_MV_STRING8)) { proptag += 1; /* try as _UNICODE variant */ } for (idx = 0; canonical_property_tags[idx].proptag; idx++) { if (canonical_property_tags[idx].proptag == proptag) { return canonical_property_tags[idx].propname; } } return NULL; } _PUBLIC_ uint32_t get_proptag_value(const char *propname) { uint32_t idx; for (idx = 0; canonical_property_tags[idx].proptag; idx++) { if (!strcmp(canonical_property_tags[idx].propname, propname)) { return canonical_property_tags[idx].proptag; } } return 0; } _PUBLIC_ uint16_t get_property_type(uint16_t untypedtag) { uint32_t idx; uint16_t current_type; for (idx = 0; canonical_property_tags[idx].proptag; idx++) { if ((canonical_property_tags[idx].proptag >> 16) == untypedtag) { current_type = canonical_property_tags[idx].proptype; if (current_type != PT_ERROR && current_type != PT_STRING8) { return current_type; } } } DEBUG(5, ("%s: type for property '%x' could not be deduced\n", __FUNCTION__, untypedtag)); return 0; } openchange-2.0/libmapi/property_tags.h000066400000000000000000005024301223057412600201600ustar00rootroot00000000000000/* Automatically generated by script/makepropslist.py. Do not edit */ #define openchange_private_ROOT_FOLDER_FID PROP_TAG(PT_I8 , 0xd001) /* 0xd0010014 */ #define openchange_private_ROOT_FOLDER_FID_ERROR PROP_TAG(PT_ERROR , 0xd001) /* 0xd001000a */ #define openchange_private_DEFERRED_ACTIONS_FID PROP_TAG(PT_I8 , 0xd002) /* 0xd0020014 */ #define openchange_private_DEFERRED_ACTIONS_FID_ERROR PROP_TAG(PT_ERROR , 0xd002) /* 0xd002000a */ #define openchange_private_SPOOLER_QUEUE_FID PROP_TAG(PT_I8 , 0xd003) /* 0xd0030014 */ #define openchange_private_SPOOLER_QUEUE_FID_ERROR PROP_TAG(PT_ERROR , 0xd003) /* 0xd003000a */ #define openchange_private_IPM_SUBTREE_FID PROP_TAG(PT_I8 , 0xd004) /* 0xd0040014 */ #define openchange_private_IPM_SUBTREE_FID_ERROR PROP_TAG(PT_ERROR , 0xd004) /* 0xd004000a */ #define openchange_private_INBOX_FID PROP_TAG(PT_I8 , 0xd005) /* 0xd0050014 */ #define openchange_private_INBOX_FID_ERROR PROP_TAG(PT_ERROR , 0xd005) /* 0xd005000a */ #define openchange_private_OUTBOX_FID PROP_TAG(PT_I8 , 0xd006) /* 0xd0060014 */ #define openchange_private_OUTBOX_FID_ERROR PROP_TAG(PT_ERROR , 0xd006) /* 0xd006000a */ #define openchange_private_SENT_ITEMS_FID PROP_TAG(PT_I8 , 0xd007) /* 0xd0070014 */ #define openchange_private_SENT_ITEMS_FID_ERROR PROP_TAG(PT_ERROR , 0xd007) /* 0xd007000a */ #define openchange_private_DELETED_ITEMS_FID PROP_TAG(PT_I8 , 0xd008) /* 0xd0080014 */ #define openchange_private_DELETED_ITEMS_FID_ERROR PROP_TAG(PT_ERROR , 0xd008) /* 0xd008000a */ #define openchange_private_COMMON_VIEWS_FID PROP_TAG(PT_I8 , 0xd009) /* 0xd0090014 */ #define openchange_private_COMMON_VIEWS_FID_ERROR PROP_TAG(PT_ERROR , 0xd009) /* 0xd009000a */ #define openchange_private_SCHEDULE_FID PROP_TAG(PT_I8 , 0xd00a) /* 0xd00a0014 */ #define openchange_private_SCHEDULE_FID_ERROR PROP_TAG(PT_ERROR , 0xd00a) /* 0xd00a000a */ #define openchange_private_SEARCH_FID PROP_TAG(PT_I8 , 0xd00b) /* 0xd00b0014 */ #define openchange_private_SEARCH_FID_ERROR PROP_TAG(PT_ERROR , 0xd00b) /* 0xd00b000a */ #define openchange_private_VIEWS_FID PROP_TAG(PT_I8 , 0xd00c) /* 0xd00c0014 */ #define openchange_private_VIEWS_FID_ERROR PROP_TAG(PT_ERROR , 0xd00c) /* 0xd00c000a */ #define openchange_private_SHORTCUTS_FID PROP_TAG(PT_I8 , 0xd00d) /* 0xd00d0014 */ #define openchange_private_SHORTCUTS_FID_ERROR PROP_TAG(PT_ERROR , 0xd00d) /* 0xd00d000a */ #define openchange_private_MailboxGUID PROP_TAG(PT_CLSID , 0xd00e) /* 0xd00e0048 */ #define openchange_private_MailboxGUID_ERROR PROP_TAG(PT_ERROR , 0xd00e) /* 0xd00e000a */ #define openchange_private_ReplicaID PROP_TAG(PT_SHORT , 0xd00f) /* 0xd00f0002 */ #define openchange_private_ReplicaID_ERROR PROP_TAG(PT_ERROR , 0xd00f) /* 0xd00f000a */ #define openchange_private_ReplicaGUID PROP_TAG(PT_CLSID , 0xd010) /* 0xd0100048 */ #define openchange_private_ReplicaGUID_ERROR PROP_TAG(PT_ERROR , 0xd010) /* 0xd010000a */ #define openchange_private_CONTACT_FID PROP_TAG(PT_I8 , 0xd011) /* 0xd0110014 */ #define openchange_private_CONTACT_FID_ERROR PROP_TAG(PT_ERROR , 0xd011) /* 0xd011000a */ #define openchange_private_CALENDAR_FID PROP_TAG(PT_I8 , 0xd012) /* 0xd0120014 */ #define openchange_private_CALENDAR_FID_ERROR PROP_TAG(PT_ERROR , 0xd012) /* 0xd012000a */ #define openchange_private_JOURNAL_FID PROP_TAG(PT_I8 , 0xd013) /* 0xd0130014 */ #define openchange_private_JOURNAL_FID_ERROR PROP_TAG(PT_ERROR , 0xd013) /* 0xd013000a */ #define openchange_private_NOTE_FID PROP_TAG(PT_I8 , 0xd014) /* 0xd0140014 */ #define openchange_private_NOTE_FID_ERROR PROP_TAG(PT_ERROR , 0xd014) /* 0xd014000a */ #define openchange_private_TASK_FID PROP_TAG(PT_I8 , 0xd015) /* 0xd0150014 */ #define openchange_private_TASK_FID_ERROR PROP_TAG(PT_ERROR , 0xd015) /* 0xd015000a */ #define openchange_private_DRAFTS_FID PROP_TAG(PT_I8 , 0xd016) /* 0xd0160014 */ #define openchange_private_DRAFTS_FID_ERROR PROP_TAG(PT_ERROR , 0xd016) /* 0xd016000a */ #define openchange_private_PF_ROOT PROP_TAG(PT_I8 , 0xd017) /* 0xd0170014 */ #define openchange_private_PF_ROOT_ERROR PROP_TAG(PT_ERROR , 0xd017) /* 0xd017000a */ #define openchange_private_PF_IPM_SUBTREE PROP_TAG(PT_I8 , 0xd018) /* 0xd0180014 */ #define openchange_private_PF_IPM_SUBTREE_ERROR PROP_TAG(PT_ERROR , 0xd018) /* 0xd018000a */ #define openchange_private_PF_NONIPM_SUBTREE PROP_TAG(PT_I8 , 0xd019) /* 0xd0190014 */ #define openchange_private_PF_NONIPM_SUBTREE_ERROR PROP_TAG(PT_ERROR , 0xd019) /* 0xd019000a */ #define openchange_private_PF_EFORMS PROP_TAG(PT_I8 , 0xd01a) /* 0xd01a0014 */ #define openchange_private_PF_EFORMS_ERROR PROP_TAG(PT_ERROR , 0xd01a) /* 0xd01a000a */ #define openchange_private_PF_FREEBUSY PROP_TAG(PT_I8 , 0xd01b) /* 0xd01b0014 */ #define openchange_private_PF_FREEBUSY_ERROR PROP_TAG(PT_ERROR , 0xd01b) /* 0xd01b000a */ #define openchange_private_PF_OAB PROP_TAG(PT_I8 , 0xd01c) /* 0xd01c0014 */ #define openchange_private_PF_OAB_ERROR PROP_TAG(PT_ERROR , 0xd01c) /* 0xd01c000a */ #define openchange_private_PF_LOCAL_EFORMS PROP_TAG(PT_I8 , 0xd01d) /* 0xd01d0014 */ #define openchange_private_PF_LOCAL_EFORMS_ERROR PROP_TAG(PT_ERROR , 0xd01d) /* 0xd01d000a */ #define openchange_private_PF_LOCAL_FREEBUSY PROP_TAG(PT_I8 , 0xd01e) /* 0xd01e0014 */ #define openchange_private_PF_LOCAL_FREEBUSY_ERROR PROP_TAG(PT_ERROR , 0xd01e) /* 0xd01e000a */ #define openchange_private_PF_LOCAL_OAB PROP_TAG(PT_I8 , 0xd01f) /* 0xd01f0014 */ #define openchange_private_PF_LOCAL_OAB_ERROR PROP_TAG(PT_ERROR , 0xd01f) /* 0xd01f000a */ #define PidTag7BitDisplayName PROP_TAG(PT_UNICODE , 0x39FF) /* 0x39FF001F */ #define PidTag7BitDisplayName_Error PROP_TAG(PT_ERROR , 0x39FF) /* 0x39FF000A */ #define PidTagAccess PROP_TAG(PT_LONG , 0x0FF4) /* 0x0FF40003 */ #define PidTagAccessLevel PROP_TAG(PT_LONG , 0x0FF7) /* 0x0FF70003 */ #define PidTagAccessLevel_Error PROP_TAG(PT_ERROR , 0x0FF7) /* 0x0FF7000A */ #define PidTagAccess_Error PROP_TAG(PT_ERROR , 0x0FF4) /* 0x0FF4000A */ #define PidTagAccessControlListData PROP_TAG(PT_BINARY , 0x3FE0) #define PidTagAccount PROP_TAG(PT_UNICODE , 0x3A00) /* 0x3A00001F */ #define PidTagAccount_Error PROP_TAG(PT_ERROR , 0x3A00) /* 0x3A00000A */ #define PidTagAdditionalRenEntryIds PROP_TAG(PT_MV_BINARY , 0x36D8) /* 0x36D81102 */ #define PidTagAdditionalRenEntryIdsEx PROP_TAG(PT_BINARY , 0x36D9) /* 0x36D90102 */ #define PidTagAdditionalRenEntryIdsEx_Error PROP_TAG(PT_ERROR , 0x36D9) /* 0x36D9000A */ #define PidTagAdditionalRenEntryIds_Error PROP_TAG(PT_ERROR , 0x36D8) /* 0x36D8000A */ #define PidTagAddressBookAuthorizedSenders PROP_TAG(PT_OBJECT , 0x8CD8) /* 0x8CD8000D */ #define PidTagAddressBookAuthorizedSenders_Error PROP_TAG(PT_ERROR , 0x8CD8) /* 0x8CD8000A */ #define PidTagAddressBookContainerId PROP_TAG(PT_LONG , 0xFFFD) /* 0xFFFD0003 */ #define PidTagAddressBookContainerId_Error PROP_TAG(PT_ERROR , 0xFFFD) /* 0xFFFD000A */ #define PidTagAddressBookDeliveryContentLength PROP_TAG(PT_LONG , 0x806A) /* 0x806A0003 */ #define PidTagAddressBookDeliveryContentLength_Error PROP_TAG(PT_ERROR , 0x806A) /* 0x806A000A */ #define PidTagAddressBookDisplayNamePrintable PROP_TAG(PT_UNICODE , 0x39FF) /* 0x39FF001F */ #define PidTagAddressBookDisplayNamePrintable_Error PROP_TAG(PT_ERROR , 0x39FF) /* 0x39FF000A */ #define PidTagAddressBookDisplayTypeExtended PROP_TAG(PT_LONG , 0x8C93) /* 0x8C930003 */ #define PidTagAddressBookDisplayTypeExtended_Error PROP_TAG(PT_ERROR , 0x8C93) /* 0x8C93000A */ #define PidTagAddressBookDistributionListExternalMemberCount PROP_TAG(PT_LONG , 0x8CE3) /* 0x8CE30003 */ #define PidTagAddressBookDistributionListExternalMemberCount_Error PROP_TAG(PT_ERROR , 0x8CE3) /* 0x8CE3000A */ #define PidTagAddressBookDistributionListMemberCount PROP_TAG(PT_LONG , 0x8CE2) /* 0x8CE20003 */ #define PidTagAddressBookDistributionListMemberCount_Error PROP_TAG(PT_ERROR , 0x8CE2) /* 0x8CE2000A */ #define PidTagAddressBookDistributionListMemberSubmitAccepted PROP_TAG(PT_OBJECT , 0x8073) /* 0x8073000D */ #define PidTagAddressBookDistributionListMemberSubmitAccepted_Error PROP_TAG(PT_ERROR , 0x8073) /* 0x8073000A */ #define PidTagAddressBookDistributionListMemberSubmitRejected PROP_TAG(PT_OBJECT , 0x8CDA) /* 0x8CDA000D */ #define PidTagAddressBookDistributionListMemberSubmitRejected_Error PROP_TAG(PT_ERROR , 0x8CDA) /* 0x8CDA000A */ #define PidTagAddressBookDistributionListRejectMessagesFromDLMembers PROP_TAG(PT_OBJECT , 0x8CDB) /* 0x8CDB000D */ #define PidTagAddressBookDistributionListRejectMessagesFromDLMembers_Error PROP_TAG(PT_ERROR , 0x8CDB) /* 0x8CDB000A */ #define PidTagAddressBookEntryId PROP_TAG(PT_BINARY , 0x663B) /* 0x663B0102 */ #define PidTagAddressBookEntryId_Error PROP_TAG(PT_ERROR , 0x663B) /* 0x663B000A */ #define PidTagAddressBookExtensionAttribute1 PROP_TAG(PT_UNICODE , 0x802D) /* 0x802D001F */ #define PidTagAddressBookExtensionAttribute15 PROP_TAG(PT_UNICODE , 0x8C61) /* 0x8C61001F */ #define PidTagAddressBookExtensionAttribute15_Error PROP_TAG(PT_ERROR , 0x8C61) /* 0x8C61000A */ #define PidTagAddressBookExtensionAttribute1_Error PROP_TAG(PT_ERROR , 0x802D) /* 0x802D000A */ #define PidTagAddressBookFolderPathname PROP_TAG(PT_UNICODE , 0x8004) /* 0x8004001F */ #define PidTagAddressBookFolderPathname_Error PROP_TAG(PT_ERROR , 0x8004) /* 0x8004000A */ #define PidTagAddressBookHierarchicalChildDepartments PROP_TAG(PT_OBJECT , 0x8C9A) /* 0x8C9A000D */ #define PidTagAddressBookHierarchicalChildDepartments_Error PROP_TAG(PT_ERROR , 0x8C9A) /* 0x8C9A000A */ #define PidTagAddressBookHierarchicalDepartmentMembers PROP_TAG(PT_OBJECT , 0x8C97) /* 0x8C97000D */ #define PidTagAddressBookHierarchicalDepartmentMembers_Error PROP_TAG(PT_ERROR , 0x8C97) /* 0x8C97000A */ #define PidTagAddressBookHierarchicalIsHierarchicalGroup PROP_TAG(PT_BOOLEAN , 0x8CDD) /* 0x8CDD000B */ #define PidTagAddressBookHierarchicalIsHierarchicalGroup_Error PROP_TAG(PT_ERROR , 0x8CDD) /* 0x8CDD000A */ #define PidTagAddressBookHierarchicalParentDepartment PROP_TAG(PT_OBJECT , 0x8C99) /* 0x8C99000D */ #define PidTagAddressBookHierarchicalParentDepartment_Error PROP_TAG(PT_ERROR , 0x8C99) /* 0x8C99000A */ #define PidTagAddressBookHierarchicalRootDepartment PROP_TAG(PT_STRING8 , 0x8C98) /* 0x8C98001E */ #define PidTagAddressBookHierarchicalRootDepartment_Error PROP_TAG(PT_ERROR , 0x8C98) /* 0x8C98000A */ #define PidTagAddressBookHierarchicalShowInDepartments PROP_TAG(PT_OBJECT , 0x8C94) /* 0x8C94000D */ #define PidTagAddressBookHierarchicalShowInDepartments_Error PROP_TAG(PT_ERROR , 0x8C94) /* 0x8C94000A */ #define PidTagAddressBookHomeMessageDatabase PROP_TAG(PT_UNICODE , 0x8006) /* 0x8006001E */ #define PidTagAddressBookHomeMessageDatabase_Error PROP_TAG(PT_ERROR , 0x8006) /* 0x8006000A */ #define PidTagAddressBookIsMaster PROP_TAG(PT_BOOLEAN , 0xFFFB) /* 0xFFFB000B */ #define PidTagAddressBookIsMaster_Error PROP_TAG(PT_ERROR , 0xFFFB) /* 0xFFFB000A */ #define PidTagAddressBookIsMemberOfDistributionList PROP_TAG(PT_MV_STRING8, 0x8008) /* 0x8008101E */ #define PidTagAddressBookIsMemberOfDistributionList_Error PROP_TAG(PT_ERROR , 0x8008) /* 0x8008000A */ #define PidTagAddressBookManageDistributionList PROP_TAG(PT_OBJECT , 0x6704) /* 0x6704000D */ #define PidTagAddressBookManageDistributionList_Error PROP_TAG(PT_ERROR , 0x6704) /* 0x6704000A */ #define PidTagAddressBookManager PROP_TAG(PT_OBJECT , 0x8005) /* 0x8005000D */ #define PidTagAddressBookManagerDistinguishedName PROP_TAG(PT_UNICODE , 0x8005) /* 0x8005001F */ #define PidTagAddressBookManagerDistinguishedName_Error PROP_TAG(PT_ERROR , 0x8005) /* 0x8005000A */ #define PidTagAddressBookManager_Error PROP_TAG(PT_ERROR , 0x8005) /* 0x8005000A */ #define PidTagAddressBookMember PROP_TAG(PT_MV_STRING8, 0x8009) /* 0x8009101E */ #define PidTagAddressBookMember_Error PROP_TAG(PT_ERROR , 0x8009) /* 0x8009000A */ #define PidTagAddressBookMessageId PROP_TAG(PT_I8 , 0x674F) /* 0x674F0014 */ #define PidTagAddressBookMessageId_Error PROP_TAG(PT_ERROR , 0x674F) /* 0x674F000A */ #define PidTagAddressBookModerationEnabled PROP_TAG(PT_BOOLEAN , 0x8CB5) /* 0x8CB5000B */ #define PidTagAddressBookModerationEnabled_Error PROP_TAG(PT_ERROR , 0x8CB5) /* 0x8CB5000A */ #define PidTagAddressBookNetworkAddress PROP_TAG(PT_MV_UNICODE, 0x8170) /* 0x8170101F */ #define PidTagAddressBookNetworkAddress_string8 PROP_TAG(PT_MV_STRING8, 0x8170) /* 0x8170101E */ #define PidTagAddressBookNetworkAddress_Error PROP_TAG(PT_ERROR , 0x8170) /* 0x8170000A */ #define PidTagAddressBookObjectDistinguishedName PROP_TAG(PT_UNICODE , 0x803C) /* 0x803C001F */ #define PidTagAddressBookObjectDistinguishedName_Error PROP_TAG(PT_ERROR , 0x803C) /* 0x803C000A */ #define PidTagAddressBookObjectGuid PROP_TAG(PT_BINARY , 0x8C6D) /* 0x8C6D0102 */ #define PidTagAddressBookObjectGuid_Error PROP_TAG(PT_ERROR , 0x8C6D) /* 0x8C6D000A */ #define PidTagAddressBookOrganizationalUnitRootDistinguishedName PROP_TAG(PT_UNICODE , 0x8CA8) /* 0x8CA8001F */ #define PidTagAddressBookOrganizationalUnitRootDistinguishedName_Error PROP_TAG(PT_ERROR , 0x8CA8) /* 0x8CA8000A */ #define PidTagAddressBookOwner PROP_TAG(PT_OBJECT , 0x800C) /* 0x800C000D */ #define PidTagAddressBookOwnerBackLink PROP_TAG(PT_OBJECT , 0x8024) /* 0x8024000D */ #define PidTagAddressBookOwnerBackLink_Error PROP_TAG(PT_ERROR , 0x8024) /* 0x8024000A */ #define PidTagAddressBookOwner_Error PROP_TAG(PT_ERROR , 0x800C) /* 0x800C000A */ #define PidTagAddressBookParentEntryId PROP_TAG(PT_BINARY , 0xFFFC) /* 0xFFFC0102 */ #define PidTagAddressBookParentEntryId_Error PROP_TAG(PT_ERROR , 0xFFFC) /* 0xFFFC000A */ #define PidTagAddressBookPhoneticCompanyName PROP_TAG(PT_UNICODE , 0x8C91) /* 0x8C91001F */ #define PidTagAddressBookPhoneticCompanyName_Error PROP_TAG(PT_ERROR , 0x8C91) /* 0x8C91000A */ #define PidTagAddressBookPhoneticDepartmentName PROP_TAG(PT_UNICODE , 0x8C90) /* 0x8C90001F */ #define PidTagAddressBookPhoneticDepartmentName_Error PROP_TAG(PT_ERROR , 0x8C90) /* 0x8C90000A */ #define PidTagAddressBookPhoneticDisplayName PROP_TAG(PT_UNICODE , 0x8C92) /* 0x8C92001F */ #define PidTagAddressBookPhoneticDisplayName_Error PROP_TAG(PT_ERROR , 0x8C92) /* 0x8C92000A */ #define PidTagAddressBookPhoneticGivenName PROP_TAG(PT_UNICODE , 0x8C8E) /* 0x8C8E001F */ #define PidTagAddressBookPhoneticGivenName_Error PROP_TAG(PT_ERROR , 0x8C8E) /* 0x8C8E000A */ #define PidTagAddressBookPhoneticSurname PROP_TAG(PT_UNICODE , 0x8C8F) /* 0x8C8F001F */ #define PidTagAddressBookPhoneticSurname_Error PROP_TAG(PT_ERROR , 0x8C8F) /* 0x8C8F000A */ #define PidTagAddressBookProxyAddresses PROP_TAG(PT_MV_UNICODE, 0x800F) /* 0x800F101F */ #define PidTagAddressBookProxyAddresses_string8 PROP_TAG(PT_MV_STRING8, 0x800F) /* 0x800F101E */ #define PidTagAddressBookProxyAddresses_Error PROP_TAG(PT_ERROR , 0x800F) /* 0x800F000A */ #define PidTagAddressBookPublicDelegates PROP_TAG(PT_OBJECT , 0x8015) /* 0x8015000D */ #define PidTagAddressBookPublicDelegates_Error PROP_TAG(PT_ERROR , 0x8015) /* 0x8015000A */ #define PidTagAddressBookReports PROP_TAG(PT_OBJECT , 0x800E) /* 0x800E000D */ #define PidTagAddressBookReports_Error PROP_TAG(PT_ERROR , 0x800E) /* 0x800E000A */ #define PidTagAddressBookRoomCapacity PROP_TAG(PT_LONG , 0x0807) /* 0x08070003 */ #define PidTagAddressBookRoomCapacity_Error PROP_TAG(PT_ERROR , 0x0807) /* 0x0807000A */ #define PidTagAddressBookRoomContainers PROP_TAG(PT_MV_UNICODE, 0x8C96) /* 0x8C96101F */ #define PidTagAddressBookRoomContainers_Error PROP_TAG(PT_ERROR , 0x8C96) /* 0x8C96000A */ #define PidTagAddressBookRoomDescription PROP_TAG(PT_UNICODE , 0x0809) /* 0x0809001F */ #define PidTagAddressBookRoomDescription_Error PROP_TAG(PT_ERROR , 0x0809) /* 0x0809000A */ #define PidTagAddressBookSenderHintTranslations PROP_TAG(PT_MV_UNICODE, 0x8CAC) /* 0x8CAC101F */ #define PidTagAddressBookSenderHintTranslations_Error PROP_TAG(PT_ERROR , 0x8CAC) /* 0x8CAC000A */ #define PidTagAddressBookSeniorityIndex PROP_TAG(PT_LONG , 0x8CA0) /* 0x8CA00003 */ #define PidTagAddressBookSeniorityIndex_Error PROP_TAG(PT_ERROR , 0x8CA0) /* 0x8CA0000A */ #define PidTagAddressBookTargetAddress PROP_TAG(PT_UNICODE , 0x8011) /* 0x8011001F */ #define PidTagAddressBookTargetAddress_Error PROP_TAG(PT_ERROR , 0x8011) /* 0x8011000A */ #define PidTagAddressBookUnauthorizedSenders PROP_TAG(PT_OBJECT , 0x8CD9) /* 0x8CD9000D */ #define PidTagAddressBookUnauthorizedSenders_Error PROP_TAG(PT_ERROR , 0x8CD9) /* 0x8CD9000A */ #define PidTagAddressBookX509Certificate PROP_TAG(PT_MV_BINARY , 0x8C6A) /* 0x8C6A1102 */ #define PidTagAddressBookX509Certificate_Error PROP_TAG(PT_ERROR , 0x8C6A) /* 0x8C6A000A */ #define PidTagAddressType PROP_TAG(PT_UNICODE , 0x3002) /* 0x3002001F */ #define PidTagAddressType_Error PROP_TAG(PT_ERROR , 0x3002) /* 0x3002000A */ #define PidTagAlternateRecipientAllowed PROP_TAG(PT_BOOLEAN , 0x0002) /* 0x0002000B */ #define PidTagAlternateRecipientAllowed_Error PROP_TAG(PT_ERROR , 0x0002) /* 0x0002000A */ #define PidTagAnr PROP_TAG(PT_UNICODE , 0x360C) /* 0x360C001F */ #define PidTagAnr_Error PROP_TAG(PT_ERROR , 0x360C) /* 0x360C000A */ #define PidTagArchiveDate PROP_TAG(PT_SYSTIME , 0x301F) /* 0x301F0040 */ #define PidTagArchiveDate_Error PROP_TAG(PT_ERROR , 0x301F) /* 0x301F000A */ #define PidTagArchivePeriod PROP_TAG(PT_LONG , 0x301E) /* 0x301E0003 */ #define PidTagArchivePeriod_Error PROP_TAG(PT_ERROR , 0x301E) /* 0x301E000A */ #define PidTagArchiveTag PROP_TAG(PT_BINARY , 0x3018) /* 0x30180102 */ #define PidTagArchiveTag_Error PROP_TAG(PT_ERROR , 0x3018) /* 0x3018000A */ #define PidTagAssistant PROP_TAG(PT_UNICODE , 0x3A30) /* 0x3A30001F */ #define PidTagAssistantTelephoneNumber PROP_TAG(PT_UNICODE , 0x3A2E) /* 0x3A2E001F */ #define PidTagAssistantTelephoneNumber_Error PROP_TAG(PT_ERROR , 0x3A2E) /* 0x3A2E000A */ #define PidTagAssistant_Error PROP_TAG(PT_ERROR , 0x3A30) /* 0x3A30000A */ #define PidTagAssociated PROP_TAG(PT_BOOLEAN , 0x67AA) /* 0x67AA000B */ #define PidTagAssociated_Error PROP_TAG(PT_ERROR , 0x67AA) /* 0x67AA000A */ #define PidTagAttachAdditionalInformation PROP_TAG(PT_BINARY , 0x370F) /* 0x370F0102 */ #define PidTagAttachAdditionalInformation_Error PROP_TAG(PT_ERROR , 0x370F) /* 0x370F000A */ #define PidTagAttachContentBase PROP_TAG(PT_UNICODE , 0x3711) /* 0x3711001F */ #define PidTagAttachContentBase_Error PROP_TAG(PT_ERROR , 0x3711) /* 0x3711000A */ #define PidTagAttachContentId PROP_TAG(PT_UNICODE , 0x3712) /* 0x3712001F */ #define PidTagAttachContentId_Error PROP_TAG(PT_ERROR , 0x3712) /* 0x3712000A */ #define PidTagAttachContentLocation PROP_TAG(PT_UNICODE , 0x3713) /* 0x3713001F */ #define PidTagAttachContentLocation_Error PROP_TAG(PT_ERROR , 0x3713) /* 0x3713000A */ #define PidTagAttachDataBinary PROP_TAG(PT_BINARY , 0x3701) /* 0x37010102 */ #define PidTagAttachDataBinary_Error PROP_TAG(PT_ERROR , 0x3701) /* 0x3701000A */ #define PidTagAttachDataObject PROP_TAG(PT_OBJECT , 0x3701) /* 0x3701000D */ #define PidTagAttachDataObject_Error PROP_TAG(PT_ERROR , 0x3701) /* 0x3701000A */ #define PidTagAttachEncoding PROP_TAG(PT_BINARY , 0x3702) /* 0x37020102 */ #define PidTagAttachEncoding_Error PROP_TAG(PT_ERROR , 0x3702) /* 0x3702000A */ #define PidTagAttachExtension PROP_TAG(PT_UNICODE , 0x3703) /* 0x3703001F */ #define PidTagAttachExtension_Error PROP_TAG(PT_ERROR , 0x3703) /* 0x3703000A */ #define PidTagAttachFilename PROP_TAG(PT_UNICODE , 0x3704) /* 0x3704001F */ #define PidTagAttachFilename_Error PROP_TAG(PT_ERROR , 0x3704) /* 0x3704000A */ #define PidTagAttachFlags PROP_TAG(PT_LONG , 0x3714) /* 0x37140003 */ #define PidTagAttachFlags_Error PROP_TAG(PT_ERROR , 0x3714) /* 0x3714000A */ #define PidTagAttachLongFilename PROP_TAG(PT_UNICODE , 0x3707) /* 0x3707001F */ #define PidTagAttachLongFilename_Error PROP_TAG(PT_ERROR , 0x3707) /* 0x3707000A */ #define PidTagAttachLongPathname PROP_TAG(PT_UNICODE , 0x370D) /* 0x370D001F */ #define PidTagAttachLongPathname_Error PROP_TAG(PT_ERROR , 0x370D) /* 0x370D000A */ #define PidTagAttachMethod PROP_TAG(PT_LONG , 0x3705) /* 0x37050003 */ #define PidTagAttachMethod_Error PROP_TAG(PT_ERROR , 0x3705) /* 0x3705000A */ #define PidTagAttachMimeTag PROP_TAG(PT_UNICODE , 0x370E) /* 0x370E001F */ #define PidTagAttachMimeTag_Error PROP_TAG(PT_ERROR , 0x370E) /* 0x370E000A */ #define PidTagAttachNumber PROP_TAG(PT_LONG , 0x0E21) /* 0x0E210003 */ #define PidTagAttachNumber_Error PROP_TAG(PT_ERROR , 0x0E21) /* 0x0E21000A */ #define PidTagAttachPathname PROP_TAG(PT_UNICODE , 0x3708) /* 0x3708001F */ #define PidTagAttachPathname_Error PROP_TAG(PT_ERROR , 0x3708) /* 0x3708000A */ #define PidTagAttachPayloadClass PROP_TAG(PT_UNICODE , 0x371A) /* 0x371A001F */ #define PidTagAttachPayloadClass_Error PROP_TAG(PT_ERROR , 0x371A) /* 0x371A000A */ #define PidTagAttachPayloadProviderGuidString PROP_TAG(PT_UNICODE , 0x3719) /* 0x3719001F */ #define PidTagAttachPayloadProviderGuidString_Error PROP_TAG(PT_ERROR , 0x3719) /* 0x3719000A */ #define PidTagAttachRendering PROP_TAG(PT_BINARY , 0x3709) /* 0x37090102 */ #define PidTagAttachRendering_Error PROP_TAG(PT_ERROR , 0x3709) /* 0x3709000A */ #define PidTagAttachSize PROP_TAG(PT_LONG , 0x0E20) /* 0x0E200003 */ #define PidTagAttachSize_Error PROP_TAG(PT_ERROR , 0x0E20) /* 0x0E20000A */ #define PidTagAttachTag PROP_TAG(PT_BINARY , 0x370A) /* 0x370A0102 */ #define PidTagAttachTag_Error PROP_TAG(PT_ERROR , 0x370A) /* 0x370A000A */ #define PidTagAttachTransportName PROP_TAG(PT_UNICODE , 0x370C) /* 0x370C001F */ #define PidTagAttachTransportName_Error PROP_TAG(PT_ERROR , 0x370C) /* 0x370C000A */ #define PidTagAttachmentContactPhoto PROP_TAG(PT_BOOLEAN , 0x7FFF) /* 0x7FFF000B */ #define PidTagAttachmentContactPhoto_Error PROP_TAG(PT_ERROR , 0x7FFF) /* 0x7FFF000A */ #define PidTagAttachmentFlags PROP_TAG(PT_LONG , 0x7FFD) /* 0x7FFD0003 */ #define PidTagAttachmentFlags_Error PROP_TAG(PT_ERROR , 0x7FFD) /* 0x7FFD000A */ #define PidTagAttachmentHidden PROP_TAG(PT_BOOLEAN , 0x7FFE) /* 0x7FFE000B */ #define PidTagAttachmentHidden_Error PROP_TAG(PT_ERROR , 0x7FFE) /* 0x7FFE000A */ #define PidTagAttachmentLinkId PROP_TAG(PT_LONG , 0x7FFA) /* 0x7FFA0003 */ #define PidTagAttachmentLinkId_Error PROP_TAG(PT_ERROR , 0x7FFA) /* 0x7FFA000A */ #define PidTagAttributeHidden PROP_TAG(PT_BOOLEAN , 0x10F4) /* 0x10F4000B */ #define PidTagAttributeHidden_Error PROP_TAG(PT_ERROR , 0x10F4) /* 0x10F4000A */ #define PidTagAttributeReadOnly PROP_TAG(PT_BOOLEAN , 0x10F6) /* 0x10F6000B */ #define PidTagAttributeReadOnly_Error PROP_TAG(PT_ERROR , 0x10F6) /* 0x10F6000A */ #define PidTagAttributeSystem PROP_TAG(PT_BOOLEAN , 0x10F5) /* 0x10F5000B */ #define PidTagAttributeSystem_Error PROP_TAG(PT_ERROR , 0x10F5) /* 0x10F5000A */ #define PidTagAutoForwardComment PROP_TAG(PT_UNICODE , 0x0004) /* 0x0004001F */ #define PidTagAutoForwardComment_Error PROP_TAG(PT_ERROR , 0x0004) /* 0x0004000A */ #define PidTagAutoForwarded PROP_TAG(PT_BOOLEAN , 0x0005) /* 0x0005000B */ #define PidTagAutoForwarded_Error PROP_TAG(PT_ERROR , 0x0005) /* 0x0005000A */ #define PidTagAutoResponseSuppress PROP_TAG(PT_LONG , 0x3FDF) /* 0x3FDF0003 */ #define PidTagAutoResponseSuppress_Error PROP_TAG(PT_ERROR , 0x3FDF) /* 0x3FDF000A */ #define PidTagBirthday PROP_TAG(PT_SYSTIME , 0x3A42) /* 0x3A420040 */ #define PidTagBirthday_Error PROP_TAG(PT_ERROR , 0x3A42) /* 0x3A42000A */ #define PidTagBlockStatus PROP_TAG(PT_LONG , 0x1096) /* 0x10960003 */ #define PidTagBlockStatus_Error PROP_TAG(PT_ERROR , 0x1096) /* 0x1096000A */ #define PidTagBody PROP_TAG(PT_UNICODE , 0x1000) /* 0x1000001F */ #define PidTagBodyContentId PROP_TAG(PT_UNICODE , 0x1015) /* 0x1015001F */ #define PidTagBodyContentId_Error PROP_TAG(PT_ERROR , 0x1015) /* 0x1015000A */ #define PidTagBodyContentLocation PROP_TAG(PT_UNICODE , 0x1014) /* 0x1014001F */ #define PidTagBodyContentLocation_Error PROP_TAG(PT_ERROR , 0x1014) /* 0x1014000A */ #define PidTagBodyHtml PROP_TAG(PT_UNICODE , 0x1013) /* 0x1013001F */ #define PidTagBodyHtml_Error PROP_TAG(PT_ERROR , 0x1013) /* 0x1013000A */ #define PidTagBody_Error PROP_TAG(PT_ERROR , 0x1000) /* 0x1000000A */ #define PidTagBusiness2TelephoneNumber PROP_TAG(PT_UNICODE , 0x3A1B) /* 0x3A1B001F */ #define PidTagBusiness2TelephoneNumber_Error PROP_TAG(PT_ERROR , 0x3A1B) /* 0x3A1B000A */ #define PidTagBusiness2TelephoneNumbers PROP_TAG(PT_MV_UNICODE, 0x3A1B) /* 0x3A1B101F */ #define PidTagBusiness2TelephoneNumbers_Error PROP_TAG(PT_ERROR , 0x3A1B) /* 0x3A1B000A */ #define PidTagBusinessFaxNumber PROP_TAG(PT_UNICODE , 0x3A24) /* 0x3A24001F */ #define PidTagBusinessFaxNumber_Error PROP_TAG(PT_ERROR , 0x3A24) /* 0x3A24000A */ #define PidTagBusinessHomePage PROP_TAG(PT_UNICODE , 0x3A51) /* 0x3A51001F */ #define PidTagBusinessHomePage_Error PROP_TAG(PT_ERROR , 0x3A51) /* 0x3A51000A */ #define PidTagBusinessTelephoneNumber PROP_TAG(PT_UNICODE , 0x3A08) /* 0x3A08001F */ #define PidTagBusinessTelephoneNumber_Error PROP_TAG(PT_ERROR , 0x3A08) /* 0x3A08000A */ #define PidTagCallId PROP_TAG(PT_UNICODE , 0x6806) /* 0x6806001F */ #define PidTagCallId_Error PROP_TAG(PT_ERROR , 0x6806) /* 0x6806000A */ #define PidTagCallbackTelephoneNumber PROP_TAG(PT_UNICODE , 0x3A02) /* 0x3A02001F */ #define PidTagCallbackTelephoneNumber_Error PROP_TAG(PT_ERROR , 0x3A02) /* 0x3A02000A */ #define PidTagCarTelephoneNumber PROP_TAG(PT_UNICODE , 0x3A1E) /* 0x3A1E001F */ #define PidTagCarTelephoneNumber_Error PROP_TAG(PT_ERROR , 0x3A1E) /* 0x3A1E000A */ #define PidTagCdoRecurrenceid PROP_TAG(PT_SYSTIME , 0x10C5) /* 0x10C50040 */ #define PidTagCdoRecurrenceid_Error PROP_TAG(PT_ERROR , 0x10C5) /* 0x10C5000A */ #define PidTagChangeKey PROP_TAG(PT_BINARY , 0x65E2) /* 0x65E20102 */ #define PidTagChangeKey_Error PROP_TAG(PT_ERROR , 0x65E2) /* 0x65E2000A */ #define PidTagChangeNotificationGuid PROP_TAG(PT_CLSID , 0x6637) /* 0x66370048 */ #define PidTagChangeNotificationGuid_Error PROP_TAG(PT_ERROR , 0x6637) /* 0x6637000A */ #define PidTagChangeNumber PROP_TAG(PT_I8 , 0x67A4) /* 0x67A40014 */ #define PidTagChangeNumber_Error PROP_TAG(PT_ERROR , 0x67A4) /* 0x67A4000A */ #define PidTagChildrensNames PROP_TAG(PT_MV_UNICODE, 0x3A58) /* 0x3A58101F */ #define PidTagChildrensNames_Error PROP_TAG(PT_ERROR , 0x3A58) /* 0x3A58000A */ #define PidTagClientActions PROP_TAG(PT_BINARY , 0x6645) /* 0x66450102 */ #define PidTagClientActions_Error PROP_TAG(PT_ERROR , 0x6645) /* 0x6645000A */ #define PidTagClientSubmitTime PROP_TAG(PT_SYSTIME , 0x0039) /* 0x00390040 */ #define PidTagClientSubmitTime_Error PROP_TAG(PT_ERROR , 0x0039) /* 0x0039000A */ #define PidTagCnsetRead PROP_TAG(PT_BINARY , 0x67D2) /* 0x67D20102 */ #define PidTagCnsetRead_Error PROP_TAG(PT_ERROR , 0x67D2) /* 0x67D2000A */ #define PidTagCnsetSeen PROP_TAG(PT_BINARY , 0x6796) /* 0x67960102 */ #define PidTagCnsetSeenFAI PROP_TAG(PT_BINARY , 0x67DA) /* 0x67DA0102 */ #define PidTagCnsetSeenFAI_Error PROP_TAG(PT_ERROR , 0x67DA) /* 0x67DA000A */ #define PidTagCnsetSeen_Error PROP_TAG(PT_ERROR , 0x6796) /* 0x6796000A */ #define PidTagCodePageId PROP_TAG(PT_LONG , 0x66C3) /* 0x66C30003 */ #define PidTagCodePageId_Error PROP_TAG(PT_ERROR , 0x66C3) /* 0x66C3000A */ #define PidTagComment PROP_TAG(PT_UNICODE , 0x3004) /* 0x3004001F */ #define PidTagComment_Error PROP_TAG(PT_ERROR , 0x3004) /* 0x3004000A */ #define PidTagCompanyMainTelephoneNumber PROP_TAG(PT_UNICODE , 0x3A57) /* 0x3A57001F */ #define PidTagCompanyMainTelephoneNumber_Error PROP_TAG(PT_ERROR , 0x3A57) /* 0x3A57000A */ #define PidTagCompanyName PROP_TAG(PT_UNICODE , 0x3A16) /* 0x3A16001F */ #define PidTagCompanyName_Error PROP_TAG(PT_ERROR , 0x3A16) /* 0x3A16000A */ #define PidTagComputerNetworkName PROP_TAG(PT_UNICODE , 0x3A49) /* 0x3A49001F */ #define PidTagComputerNetworkName_Error PROP_TAG(PT_ERROR , 0x3A49) /* 0x3A49000A */ #define PidTagConflictEntryId PROP_TAG(PT_BINARY , 0x3FF0) /* 0x3FF00102 */ #define PidTagConflictEntryId_Error PROP_TAG(PT_ERROR , 0x3FF0) /* 0x3FF0000A */ #define PidTagConflictItems PROP_TAG(PT_MV_BINARY , 0x1098) /* 0x10981102 */ #define PidTagConflictItems_Error PROP_TAG(PT_ERROR , 0x1098) /* 0x1098000A */ #define PidTagContainerClass PROP_TAG(PT_UNICODE , 0x3613) /* 0x3613001F */ #define PidTagContainerClass_Error PROP_TAG(PT_ERROR , 0x3613) /* 0x3613000A */ #define PidTagContainerContents PROP_TAG(PT_OBJECT , 0x360F) /* 0x360F000D */ #define PidTagContainerContents_Error PROP_TAG(PT_ERROR , 0x360F) /* 0x360F000A */ #define PidTagContainerFlags PROP_TAG(PT_LONG , 0x3600) /* 0x36000003 */ #define PidTagContainerFlags_Error PROP_TAG(PT_ERROR , 0x3600) /* 0x3600000A */ #define PidTagContainerHierarchy PROP_TAG(PT_OBJECT , 0x360E) /* 0x360E000D */ #define PidTagContainerHierarchy_Error PROP_TAG(PT_ERROR , 0x360E) /* 0x360E000A */ #define PidTagContentCount PROP_TAG(PT_LONG , 0x3602) /* 0x36020003 */ #define PidTagContentCount_Error PROP_TAG(PT_ERROR , 0x3602) /* 0x3602000A */ #define PidTagContentFilterPhishingConfidenceLevel PROP_TAG(PT_LONG , 0x4084) /* 0x40840003 */ #define PidTagContentFilterPhishingConfidenceLevel_Error PROP_TAG(PT_ERROR , 0x4084) /* 0x4084000A */ #define PidTagContentFilterSpamConfidenceLevel PROP_TAG(PT_LONG , 0x4076) /* 0x40760003 */ #define PidTagContentFilterSpamConfidenceLevel_Error PROP_TAG(PT_ERROR , 0x4076) /* 0x4076000A */ #define PidTagContentUnreadCount PROP_TAG(PT_LONG , 0x3603) /* 0x36030003 */ #define PidTagContentUnreadCount_Error PROP_TAG(PT_ERROR , 0x3603) /* 0x3603000A */ #define PidTagConversationId PROP_TAG(PT_BINARY , 0x3013) /* 0x30130102 */ #define PidTagConversationId_Error PROP_TAG(PT_ERROR , 0x3013) /* 0x3013000A */ #define PidTagConversationIndex PROP_TAG(PT_BINARY , 0x0071) /* 0x00710102 */ #define PidTagConversationIndexTracking PROP_TAG(PT_BOOLEAN , 0x3016) /* 0x3016000B */ #define PidTagConversationIndexTracking_Error PROP_TAG(PT_ERROR , 0x3016) /* 0x3016000A */ #define PidTagConversationIndex_Error PROP_TAG(PT_ERROR , 0x0071) /* 0x0071000A */ #define PidTagConversationTopic PROP_TAG(PT_UNICODE , 0x0070) /* 0x0070001F */ #define PidTagConversationTopic_Error PROP_TAG(PT_ERROR , 0x0070) /* 0x0070000A */ #define PidTagCountry PROP_TAG(PT_UNICODE , 0x3A26) /* 0x3A26001F */ #define PidTagCountry_Error PROP_TAG(PT_ERROR , 0x3A26) /* 0x3A26000A */ #define PidTagCreationTime PROP_TAG(PT_SYSTIME , 0x3007) /* 0x30070040 */ #define PidTagCreationTime_Error PROP_TAG(PT_ERROR , 0x3007) /* 0x3007000A */ #define PidTagCreatorEntryId PROP_TAG(PT_BINARY , 0x3FF9) /* 0x3FF90102 */ #define PidTagCreatorEntryId_Error PROP_TAG(PT_ERROR , 0x3FF9) /* 0x3FF9000A */ #define PidTagCreatorName PROP_TAG(PT_UNICODE , 0x3FF8) /* 0x3FF8001F */ #define PidTagCreatorName_Error PROP_TAG(PT_ERROR , 0x3FF8) /* 0x3FF8000A */ #define PidTagCreatorSimpleDisplayName PROP_TAG(PT_UNICODE , 0x4038) /* 0x4038001F */ #define PidTagCreatorSimpleDisplayName_Error PROP_TAG(PT_ERROR , 0x4038) /* 0x4038000A */ #define PidTagCustomerId PROP_TAG(PT_UNICODE , 0x3A4A) /* 0x3A4A001F */ #define PidTagCustomerId_Error PROP_TAG(PT_ERROR , 0x3A4A) /* 0x3A4A000A */ #define PidTagDamBackPatched PROP_TAG(PT_BOOLEAN , 0x6647) /* 0x6647000B */ #define PidTagDamBackPatched_Error PROP_TAG(PT_ERROR , 0x6647) /* 0x6647000A */ #define PidTagDamOriginalEntryId PROP_TAG(PT_BINARY , 0x6646) /* 0x66460102 */ #define PidTagDamOriginalEntryId_Error PROP_TAG(PT_ERROR , 0x6646) /* 0x6646000A */ #define PidTagDefaultPostMessageClass PROP_TAG(PT_UNICODE , 0x36E5) /* 0x36E5001F */ #define PidTagDefaultPostMessageClass_Error PROP_TAG(PT_ERROR , 0x36E5) /* 0x36E5000A */ #define PidTagDeferredActionMessageOriginalEntryId PROP_TAG(PT_SVREID , 0x6741) /* 0x674100FB */ #define PidTagDeferredActionMessageOriginalEntryId_Error PROP_TAG(PT_ERROR , 0x6741) /* 0x6741000A */ #define PidTagDeferredDeliveryTime PROP_TAG(PT_SYSTIME , 0x000F) /* 0x000F0040 */ #define PidTagDeferredDeliveryTime_Error PROP_TAG(PT_ERROR , 0x000F) /* 0x000F000A */ #define PidTagDeferredSendNumber PROP_TAG(PT_LONG , 0x3FEB) /* 0x3FEB0003 */ #define PidTagDeferredSendNumber_Error PROP_TAG(PT_ERROR , 0x3FEB) /* 0x3FEB000A */ #define PidTagDeferredSendTime PROP_TAG(PT_SYSTIME , 0x3FEF) /* 0x3FEF0040 */ #define PidTagDeferredSendTime_Error PROP_TAG(PT_ERROR , 0x3FEF) /* 0x3FEF000A */ #define PidTagDeferredSendUnits PROP_TAG(PT_LONG , 0x3FEC) /* 0x3FEC0003 */ #define PidTagDeferredSendUnits_Error PROP_TAG(PT_ERROR , 0x3FEC) /* 0x3FEC000A */ #define PidTagDelegateFlags PROP_TAG(PT_MV_LONG , 0x686B) /* 0x686B1003 */ #define PidTagDelegateFlags_Error PROP_TAG(PT_ERROR , 0x686B) /* 0x686B000A */ #define PidTagDelegatedByRule PROP_TAG(PT_BOOLEAN , 0x3FE3) /* 0x3FE3000B */ #define PidTagDelegatedByRule_Error PROP_TAG(PT_ERROR , 0x3FE3) /* 0x3FE3000A */ #define PidTagDeleteAfterSubmit PROP_TAG(PT_BOOLEAN , 0x0E01) /* 0x0E01000B */ #define PidTagDeleteAfterSubmit_Error PROP_TAG(PT_ERROR , 0x0E01) /* 0x0E01000A */ #define PidTagDeletedOn PROP_TAG(PT_SYSTIME , 0x668F) /* 0x668F0040 */ #define PidTagDeletedOn_Error PROP_TAG(PT_ERROR , 0x668F) /* 0x668F000A */ #define PidTagDepartmentName PROP_TAG(PT_UNICODE , 0x3A18) /* 0x3A18001F */ #define PidTagDepartmentName_Error PROP_TAG(PT_ERROR , 0x3A18) /* 0x3A18000A */ #define PidTagDepth PROP_TAG(PT_LONG , 0x3005) /* 0x30050003 */ #define PidTagDepth_Error PROP_TAG(PT_ERROR , 0x3005) /* 0x3005000A */ #define PidTagDisplayBcc PROP_TAG(PT_UNICODE , 0x0E02) /* 0x0E02001F */ #define PidTagDisplayBcc_Error PROP_TAG(PT_ERROR , 0x0E02) /* 0x0E02000A */ #define PidTagDisplayCc PROP_TAG(PT_UNICODE , 0x0E03) /* 0x0E03001F */ #define PidTagDisplayCc_Error PROP_TAG(PT_ERROR , 0x0E03) /* 0x0E03000A */ #define PidTagDisplayName PROP_TAG(PT_UNICODE , 0x3001) /* 0x3001001F */ #define PidTagDisplayNamePrefix PROP_TAG(PT_UNICODE , 0x3A45) /* 0x3A45001F */ #define PidTagDisplayNamePrefix_Error PROP_TAG(PT_ERROR , 0x3A45) /* 0x3A45000A */ #define PidTagDisplayName_Error PROP_TAG(PT_ERROR , 0x3001) /* 0x3001000A */ #define PidTagDisplayTo PROP_TAG(PT_UNICODE , 0x0E04) /* 0x0E04001F */ #define PidTagDisplayTo_Error PROP_TAG(PT_ERROR , 0x0E04) /* 0x0E04000A */ #define PidTagDisplayType PROP_TAG(PT_LONG , 0x3900) /* 0x39000003 */ #define PidTagDisplayTypeEx PROP_TAG(PT_LONG , 0x3905) /* 0x39050003 */ #define PidTagDisplayTypeEx_Error PROP_TAG(PT_ERROR , 0x3905) /* 0x3905000A */ #define PidTagDisplayType_Error PROP_TAG(PT_ERROR , 0x3900) /* 0x3900000A */ #define PidTagEcWarning PROP_TAG(PT_LONG , 0x400F) /* 0x400F0003 */ #define PidTagEcWarning_Error PROP_TAG(PT_ERROR , 0x400F) /* 0x400F000A */ #define PidTagEmailAddress PROP_TAG(PT_UNICODE , 0x3003) /* 0x3003001F */ #define PidTagEmailAddress_Error PROP_TAG(PT_ERROR , 0x3003) /* 0x3003000A */ #define PidTagEndAttach PROP_TAG(PT_LONG , 0x400E) /* 0x400E0003 */ #define PidTagEndAttach_Error PROP_TAG(PT_ERROR , 0x400E) /* 0x400E000A */ #define PidTagEndDate PROP_TAG(PT_SYSTIME , 0x0061) /* 0x00610040 */ #define PidTagEndDate_Error PROP_TAG(PT_ERROR , 0x0061) /* 0x0061000A */ #define PidTagEndEmbed PROP_TAG(PT_LONG , 0x4002) /* 0x40020003 */ #define PidTagEndEmbed_Error PROP_TAG(PT_ERROR , 0x4002) /* 0x4002000A */ #define PidTagEndFolder PROP_TAG(PT_LONG , 0x400B) /* 0x400B0003 */ #define PidTagEndFolder_Error PROP_TAG(PT_ERROR , 0x400B) /* 0x400B000A */ #define PidTagEndMessage PROP_TAG(PT_LONG , 0x400D) /* 0x400D0003 */ #define PidTagEndMessage_Error PROP_TAG(PT_ERROR , 0x400D) /* 0x400D000A */ #define PidTagEndToRecip PROP_TAG(PT_LONG , 0x4004) /* 0x40040003 */ #define PidTagEndToRecip_Error PROP_TAG(PT_ERROR , 0x4004) /* 0x4004000A */ #define PidTagEntryId PROP_TAG(PT_BINARY , 0x0FFF) /* 0x0FFF0102 */ #define PidTagEntryId_Error PROP_TAG(PT_ERROR , 0x0FFF) /* 0x0FFF000A */ #define PidTagExceptionEndTime PROP_TAG(PT_SYSTIME , 0x7FFC) /* 0x7FFC0040 */ #define PidTagExceptionEndTime_Error PROP_TAG(PT_ERROR , 0x7FFC) /* 0x7FFC000A */ #define PidTagExceptionReplaceTime PROP_TAG(PT_SYSTIME , 0x7FF9) /* 0x7FF90040 */ #define PidTagExceptionReplaceTime_Error PROP_TAG(PT_ERROR , 0x7FF9) /* 0x7FF9000A */ #define PidTagExceptionStartTime PROP_TAG(PT_SYSTIME , 0x7FFB) /* 0x7FFB0040 */ #define PidTagExceptionStartTime_Error PROP_TAG(PT_ERROR , 0x7FFB) /* 0x7FFB000A */ #define PidTagExchangeNTSecurityDescriptor PROP_TAG(PT_BINARY , 0x0E84) /* 0x0E840102 */ #define PidTagExchangeNTSecurityDescriptor_Error PROP_TAG(PT_ERROR , 0x0E84) /* 0x0E84000A */ #define PidTagExpiryNumber PROP_TAG(PT_LONG , 0x3FED) /* 0x3FED0003 */ #define PidTagExpiryNumber_Error PROP_TAG(PT_ERROR , 0x3FED) /* 0x3FED000A */ #define PidTagExpiryTime PROP_TAG(PT_SYSTIME , 0x0015) /* 0x00150040 */ #define PidTagExpiryTime_Error PROP_TAG(PT_ERROR , 0x0015) /* 0x0015000A */ #define PidTagExpiryUnits PROP_TAG(PT_LONG , 0x3FEE) /* 0x3FEE0003 */ #define PidTagExpiryUnits_Error PROP_TAG(PT_ERROR , 0x3FEE) /* 0x3FEE000A */ #define PidTagExtendedFolderFlags PROP_TAG(PT_BINARY , 0x36DA) /* 0x36DA0102 */ #define PidTagExtendedFolderFlags_Error PROP_TAG(PT_ERROR , 0x36DA) /* 0x36DA000A */ #define PidTagExtendedRuleMessageActions PROP_TAG(PT_BINARY , 0x0E99) /* 0x0E990102 */ #define PidTagExtendedRuleMessageActions_Error PROP_TAG(PT_ERROR , 0x0E99) /* 0x0E99000A */ #define PidTagExtendedRuleMessageCondition PROP_TAG(PT_BINARY , 0x0E9A) /* 0x0E9A0102 */ #define PidTagExtendedRuleMessageCondition_Error PROP_TAG(PT_ERROR , 0x0E9A) /* 0x0E9A000A */ #define PidTagExtendedRuleSizeLimit PROP_TAG(PT_LONG , 0x0E9B) /* 0x0E9B0003 */ #define PidTagExtendedRuleSizeLimit_Error PROP_TAG(PT_ERROR , 0x0E9B) /* 0x0E9B000A */ #define PidTagFXDelProp PROP_TAG(PT_LONG , 0x4016) /* 0x40160003 */ #define PidTagFXDelProp_Error PROP_TAG(PT_ERROR , 0x4016) /* 0x4016000A */ #define PidTagFXErrorInfo PROP_TAG(PT_LONG , 0x4018) /* 0x40180003 */ #define PidTagFXErrorInfo_Error PROP_TAG(PT_ERROR , 0x4018) /* 0x4018000A */ #define PidTagFaxNumberOfPages PROP_TAG(PT_LONG , 0x6804) /* 0x68040003 */ #define PidTagFaxNumberOfPages_Error PROP_TAG(PT_ERROR , 0x6804) /* 0x6804000A */ #define PidTagFlagCompleteTime PROP_TAG(PT_SYSTIME , 0x1091) /* 0x10910040 */ #define PidTagFlagCompleteTime_Error PROP_TAG(PT_ERROR , 0x1091) /* 0x1091000A */ #define PidTagFlagStatus PROP_TAG(PT_LONG , 0x1090) /* 0x10900003 */ #define PidTagFlagStatus_Error PROP_TAG(PT_ERROR , 0x1090) /* 0x1090000A */ #define PidTagFlatUrlName PROP_TAG(PT_UNICODE , 0x670E) /* 0x670E001F */ #define PidTagFlatUrlName_Error PROP_TAG(PT_ERROR , 0x670E) /* 0x670E000A */ #define PidTagFolderAssociatedContents PROP_TAG(PT_OBJECT , 0x3610) /* 0x3610000D */ #define PidTagFolderAssociatedContents_Error PROP_TAG(PT_ERROR , 0x3610) /* 0x3610000A */ #define PidTagFolderId PROP_TAG(PT_I8 , 0x6748) /* 0x67480014 */ #define PidTagFolderId_Error PROP_TAG(PT_ERROR , 0x6748) /* 0x6748000A */ #define PidTagFolderType PROP_TAG(PT_LONG , 0x3601) /* 0x36010003 */ #define PidTagFolderType_Error PROP_TAG(PT_ERROR , 0x3601) /* 0x3601000A */ #define PidTagFollowupIcon PROP_TAG(PT_LONG , 0x1095) /* 0x10950003 */ #define PidTagFollowupIcon_Error PROP_TAG(PT_ERROR , 0x1095) /* 0x1095000A */ #define PidTagFreeBusyCountMonths PROP_TAG(PT_LONG , 0x6869) /* 0x68690003 */ #define PidTagFreeBusyCountMonths_Error PROP_TAG(PT_ERROR , 0x6869) /* 0x6869000A */ #define PidTagFreeBusyEntryIds PROP_TAG(PT_MV_BINARY , 0x36E4) /* 0x36E41102 */ #define PidTagFreeBusyEntryIds_Error PROP_TAG(PT_ERROR , 0x36E4) /* 0x36E4000A */ #define PidTagFreeBusyMessageEmailAddress PROP_TAG(PT_UNICODE , 0x6849) /* 0x6849001F */ #define PidTagFreeBusyMessageEmailAddress_Error PROP_TAG(PT_ERROR , 0x6849) /* 0x6849000A */ #define PidTagFreeBusyPublishEnd PROP_TAG(PT_LONG , 0x6848) /* 0x68480003 */ #define PidTagFreeBusyPublishEnd_Error PROP_TAG(PT_ERROR , 0x6848) /* 0x6848000A */ #define PidTagFreeBusyPublishStart PROP_TAG(PT_LONG , 0x6847) /* 0x68470003 */ #define PidTagFreeBusyPublishStart_Error PROP_TAG(PT_ERROR , 0x6847) /* 0x6847000A */ #define PidTagFreeBusyRangeTimestamp PROP_TAG(PT_SYSTIME , 0x6868) /* 0x68680040 */ #define PidTagFreeBusyRangeTimestamp_Error PROP_TAG(PT_ERROR , 0x6868) /* 0x6868000A */ #define PidTagFtpSite PROP_TAG(PT_UNICODE , 0x3A4C) /* 0x3A4C001F */ #define PidTagFtpSite_Error PROP_TAG(PT_ERROR , 0x3A4C) /* 0x3A4C000A */ #define PidTagGatewayNeedsToRefresh PROP_TAG(PT_BOOLEAN , 0x6846) /* 0x6846000B */ #define PidTagGatewayNeedsToRefresh_Error PROP_TAG(PT_ERROR , 0x6846) /* 0x6846000A */ #define PidTagGender PROP_TAG(PT_SHORT , 0x3A4D) /* 0x3A4D0002 */ #define PidTagGender_Error PROP_TAG(PT_ERROR , 0x3A4D) /* 0x3A4D000A */ #define PidTagGeneration PROP_TAG(PT_UNICODE , 0x3A05) /* 0x3A05001F */ #define PidTagGeneration_Error PROP_TAG(PT_ERROR , 0x3A05) /* 0x3A05000A */ #define PidTagGivenName PROP_TAG(PT_UNICODE , 0x3A06) /* 0x3A06001F */ #define PidTagGivenName_Error PROP_TAG(PT_ERROR , 0x3A06) /* 0x3A06000A */ #define PidTagGovernmentIdNumber PROP_TAG(PT_UNICODE , 0x3A07) /* 0x3A07001F */ #define PidTagGovernmentIdNumber_Error PROP_TAG(PT_ERROR , 0x3A07) /* 0x3A07000A */ #define PidTagHasAttachments PROP_TAG(PT_BOOLEAN , 0x0E1B) /* 0x0E1B000B */ #define PidTagHasAttachments_Error PROP_TAG(PT_ERROR , 0x0E1B) /* 0x0E1B000A */ #define PidTagHasDeferredActionMessages PROP_TAG(PT_BOOLEAN , 0x3FEA) /* 0x3FEA000B */ #define PidTagHasDeferredActionMessages_Error PROP_TAG(PT_ERROR , 0x3FEA) /* 0x3FEA000A */ #define PidTagHasNamedProperties PROP_TAG(PT_BOOLEAN , 0x664A) /* 0x664A000B */ #define PidTagHasNamedProperties_Error PROP_TAG(PT_ERROR , 0x664A) /* 0x664A000A */ #define PidTagHasRules PROP_TAG(PT_BOOLEAN , 0x663A) /* 0x663A000B */ #define PidTagHasRules_Error PROP_TAG(PT_ERROR , 0x663A) /* 0x663A000A */ #define PidTagHierarchyChangeNumber PROP_TAG(PT_LONG , 0x663E) /* 0x663E0003 */ #define PidTagHierarchyChangeNumber_Error PROP_TAG(PT_ERROR , 0x663E) /* 0x663E000A */ #define PidTagHobbies PROP_TAG(PT_UNICODE , 0x3A43) /* 0x3A43001F */ #define PidTagHobbies_Error PROP_TAG(PT_ERROR , 0x3A43) /* 0x3A43000A */ #define PidTagHome2TelephoneNumber PROP_TAG(PT_UNICODE , 0x3A2F) /* 0x3A2F001F */ #define PidTagHome2TelephoneNumber_Error PROP_TAG(PT_ERROR , 0x3A2F) /* 0x3A2F000A */ #define PidTagHome2TelephoneNumbers PROP_TAG(PT_MV_UNICODE, 0x3A2F) /* 0x3A2F101F */ #define PidTagHome2TelephoneNumbers_Error PROP_TAG(PT_ERROR , 0x3A2F) /* 0x3A2F000A */ #define PidTagHomeAddressCity PROP_TAG(PT_UNICODE , 0x3A59) /* 0x3A59001F */ #define PidTagHomeAddressCity_Error PROP_TAG(PT_ERROR , 0x3A59) /* 0x3A59000A */ #define PidTagHomeAddressCountry PROP_TAG(PT_UNICODE , 0x3A5A) /* 0x3A5A001F */ #define PidTagHomeAddressCountry_Error PROP_TAG(PT_ERROR , 0x3A5A) /* 0x3A5A000A */ #define PidTagHomeAddressPostOfficeBox PROP_TAG(PT_UNICODE , 0x3A5E) /* 0x3A5E001F */ #define PidTagHomeAddressPostOfficeBox_Error PROP_TAG(PT_ERROR , 0x3A5E) /* 0x3A5E000A */ #define PidTagHomeAddressPostalCode PROP_TAG(PT_UNICODE , 0x3A5B) /* 0x3A5B001F */ #define PidTagHomeAddressPostalCode_Error PROP_TAG(PT_ERROR , 0x3A5B) /* 0x3A5B000A */ #define PidTagHomeAddressStateOrProvince PROP_TAG(PT_UNICODE , 0x3A5C) /* 0x3A5C001F */ #define PidTagHomeAddressStateOrProvince_Error PROP_TAG(PT_ERROR , 0x3A5C) /* 0x3A5C000A */ #define PidTagHomeAddressStreet PROP_TAG(PT_UNICODE , 0x3A5D) /* 0x3A5D001F */ #define PidTagHomeAddressStreet_Error PROP_TAG(PT_ERROR , 0x3A5D) /* 0x3A5D000A */ #define PidTagHomeFaxNumber PROP_TAG(PT_UNICODE , 0x3A25) /* 0x3A25001F */ #define PidTagHomeFaxNumber_Error PROP_TAG(PT_ERROR , 0x3A25) /* 0x3A25000A */ #define PidTagHomeTelephoneNumber PROP_TAG(PT_UNICODE , 0x3A09) /* 0x3A09001F */ #define PidTagHomeTelephoneNumber_Error PROP_TAG(PT_ERROR , 0x3A09) /* 0x3A09000A */ #define PidTagHtml PROP_TAG(PT_BINARY , 0x1013) /* 0x10130102 */ #define PidTagHtml_Error PROP_TAG(PT_ERROR , 0x1013) /* 0x1013000A */ #define PidTagICalendarEndTime PROP_TAG(PT_SYSTIME , 0x10C4) /* 0x10C40040 */ #define PidTagICalendarEndTime_Error PROP_TAG(PT_ERROR , 0x10C4) /* 0x10C4000A */ #define PidTagICalendarReminderNextTime PROP_TAG(PT_SYSTIME , 0x10CA) /* 0x10CA0040 */ #define PidTagICalendarReminderNextTime_Error PROP_TAG(PT_ERROR , 0x10CA) /* 0x10CA000A */ #define PidTagICalendarStartTime PROP_TAG(PT_SYSTIME , 0x10C3) /* 0x10C30040 */ #define PidTagICalendarStartTime_Error PROP_TAG(PT_ERROR , 0x10C3) /* 0x10C3000A */ #define PidTagIconIndex PROP_TAG(PT_LONG , 0x1080) /* 0x10800003 */ #define PidTagIconIndex_Error PROP_TAG(PT_ERROR , 0x1080) /* 0x1080000A */ #define PidTagIdsetDeleted PROP_TAG(PT_BINARY , 0x67E5) /* 0x67E50102 */ #define PidTagIdsetDeleted_Error PROP_TAG(PT_ERROR , 0x67E5) /* 0x67E5000A */ #define PidTagIdsetExpired PROP_TAG(PT_BINARY , 0x6793) /* 0x67930102 */ #define PidTagIdsetExpired_Error PROP_TAG(PT_ERROR , 0x6793) /* 0x6793000A */ #define PidTagIdsetGiven PROP_TAG(PT_LONG , 0x4017) /* 0x40170003 */ #define PidTagIdsetGiven_Error PROP_TAG(PT_ERROR , 0x4017) /* 0x4017000A */ #define PidTagIdsetNoLongerInScope PROP_TAG(PT_BINARY , 0x4021) /* 0x40210102 */ #define PidTagIdsetNoLongerInScope_Error PROP_TAG(PT_ERROR , 0x4021) /* 0x4021000A */ #define PidTagIdsetRead PROP_TAG(PT_BINARY , 0x402D) /* 0x402D0102 */ #define PidTagIdsetRead_Error PROP_TAG(PT_ERROR , 0x402D) /* 0x402D000A */ #define PidTagIdsetUnread PROP_TAG(PT_BINARY , 0x402E) /* 0x402E0102 */ #define PidTagIdsetUnread_Error PROP_TAG(PT_ERROR , 0x402E) /* 0x402E000A */ #define PidTagImapCachedMsgsize PROP_TAG(PT_BINARY , 0x10F0) /* 0x10F00102 */ #define PidTagImapCachedMsgsize_Error PROP_TAG(PT_ERROR , 0x10F0) /* 0x10F0000A */ #define PidTagImportance PROP_TAG(PT_LONG , 0x0017) /* 0x00170003 */ #define PidTagImportance_Error PROP_TAG(PT_ERROR , 0x0017) /* 0x0017000A */ #define PidTagInConflict PROP_TAG(PT_BOOLEAN , 0x666C) /* 0x666C000B */ #define PidTagInConflict_Error PROP_TAG(PT_ERROR , 0x666C) /* 0x666C000A */ #define PidTagInReplyToId PROP_TAG(PT_UNICODE , 0x1042) /* 0x1042001F */ #define PidTagInReplyToId_Error PROP_TAG(PT_ERROR , 0x1042) /* 0x1042000A */ #define PidTagIncrSyncChg PROP_TAG(PT_LONG , 0x4012) /* 0x40120003 */ #define PidTagIncrSyncChgPartial PROP_TAG(PT_LONG , 0x407D) /* 0x407D0003 */ #define PidTagIncrSyncChgPartial_Error PROP_TAG(PT_ERROR , 0x407D) /* 0x407D000A */ #define PidTagIncrSyncChg_Error PROP_TAG(PT_ERROR , 0x4012) /* 0x4012000A */ #define PidTagIncrSyncDel PROP_TAG(PT_LONG , 0x4013) /* 0x40130003 */ #define PidTagIncrSyncDel_Error PROP_TAG(PT_ERROR , 0x4013) /* 0x4013000A */ #define PidTagIncrSyncEnd PROP_TAG(PT_LONG , 0x4014) /* 0x40140003 */ #define PidTagIncrSyncEnd_Error PROP_TAG(PT_ERROR , 0x4014) /* 0x4014000A */ #define PidTagIncrSyncGroupId PROP_TAG(PT_LONG , 0x407C) /* 0x407C0003 */ #define PidTagIncrSyncGroupId_Error PROP_TAG(PT_ERROR , 0x407C) /* 0x407C000A */ #define PidTagIncrSyncGroupInfo PROP_TAG(PT_BINARY , 0x407B) /* 0x407B0102 */ #define PidTagIncrSyncGroupInfo_Error PROP_TAG(PT_ERROR , 0x407B) /* 0x407B000A */ #define PidTagIncrSyncMessage PROP_TAG(PT_LONG , 0x4015) /* 0x40150003 */ #define PidTagIncrSyncMessage_Error PROP_TAG(PT_ERROR , 0x4015) /* 0x4015000A */ #define PidTagIncrSyncProgressMode PROP_TAG(PT_BOOLEAN , 0x4074) /* 0x4074000B */ #define PidTagIncrSyncProgressMode_Error PROP_TAG(PT_ERROR , 0x4074) /* 0x4074000A */ #define PidTagIncrSyncProgressPerMsg PROP_TAG(PT_BOOLEAN , 0x4075) /* 0x4075000B */ #define PidTagIncrSyncProgressPerMsg_Error PROP_TAG(PT_ERROR , 0x4075) /* 0x4075000A */ #define PidTagIncrSyncRead PROP_TAG(PT_LONG , 0x402F) /* 0x402F0003 */ #define PidTagIncrSyncRead_Error PROP_TAG(PT_ERROR , 0x402F) /* 0x402F000A */ #define PidTagIncrSyncStateBegin PROP_TAG(PT_LONG , 0x403A) /* 0x403A0003 */ #define PidTagIncrSyncStateBegin_Error PROP_TAG(PT_ERROR , 0x403A) /* 0x403A000A */ #define PidTagIncrSyncStateEnd PROP_TAG(PT_LONG , 0x403B) /* 0x403B0003 */ #define PidTagIncrSyncStateEnd_Error PROP_TAG(PT_ERROR , 0x403B) /* 0x403B000A */ #define PidTagIncrementalSyncMessagePartial PROP_TAG(PT_LONG , 0x407A) /* 0x407A0003 */ #define PidTagIncrementalSyncMessagePartial_Error PROP_TAG(PT_ERROR , 0x407A) /* 0x407A000A */ #define PidTagInitialDetailsPane PROP_TAG(PT_LONG , 0x3F08) /* 0x3F080003 */ #define PidTagInitialDetailsPane_Error PROP_TAG(PT_ERROR , 0x3F08) /* 0x3F08000A */ #define PidTagInitials PROP_TAG(PT_UNICODE , 0x3A0A) /* 0x3A0A001F */ #define PidTagInitials_Error PROP_TAG(PT_ERROR , 0x3A0A) /* 0x3A0A000A */ #define PidTagInstID PROP_TAG(PT_I8 , 0x674D) /* 0x674D0014 */ #define PidTagInstID_Error PROP_TAG(PT_ERROR , 0x674D) /* 0x674D000A */ #define PidTagInstanceKey PROP_TAG(PT_BINARY , 0x0FF6) /* 0x0FF60102 */ #define PidTagInstanceKey_Error PROP_TAG(PT_ERROR , 0x0FF6) /* 0x0FF6000A */ #define PidTagInstanceNum PROP_TAG(PT_LONG , 0x674E) /* 0x674E0003 */ #define PidTagInstanceNum_Error PROP_TAG(PT_ERROR , 0x674E) /* 0x674E000A */ #define PidTagInternetArticleNumber PROP_TAG(PT_LONG , 0x0E23) /* 0x0E230003 */ #define PidTagInternetArticleNumber_Error PROP_TAG(PT_ERROR , 0x0E23) /* 0x0E23000A */ #define PidTagInternetCodepage PROP_TAG(PT_LONG , 0x3FDE) /* 0x3FDE0003 */ #define PidTagInternetCodepage_Error PROP_TAG(PT_ERROR , 0x3FDE) /* 0x3FDE000A */ #define PidTagInternetMailOverrideFormat PROP_TAG(PT_LONG , 0x5902) /* 0x59020003 */ #define PidTagInternetMailOverrideFormat_Error PROP_TAG(PT_ERROR , 0x5902) /* 0x5902000A */ #define PidTagInternetMessageId PROP_TAG(PT_UNICODE , 0x1035) /* 0x1035001F */ #define PidTagInternetMessageId_Error PROP_TAG(PT_ERROR , 0x1035) /* 0x1035000A */ #define PidTagInternetReferences PROP_TAG(PT_UNICODE , 0x1039) /* 0x1039001F */ #define PidTagInternetReferences_Error PROP_TAG(PT_ERROR , 0x1039) /* 0x1039000A */ #define PidTagIpmAppointmentEntryId PROP_TAG(PT_BINARY , 0x36D0) /* 0x36D00102 */ #define PidTagIpmAppointmentEntryId_Error PROP_TAG(PT_ERROR , 0x36D0) /* 0x36D0000A */ #define PidTagIpmContactEntryId PROP_TAG(PT_BINARY , 0x36D1) /* 0x36D10102 */ #define PidTagIpmContactEntryId_Error PROP_TAG(PT_ERROR , 0x36D1) /* 0x36D1000A */ #define PidTagIpmDraftsEntryId PROP_TAG(PT_BINARY , 0x36D7) /* 0x36D70102 */ #define PidTagIpmDraftsEntryId_Error PROP_TAG(PT_ERROR , 0x36D7) /* 0x36D7000A */ #define PidTagIpmJournalEntryId PROP_TAG(PT_BINARY , 0x36D2) /* 0x36D20102 */ #define PidTagIpmJournalEntryId_Error PROP_TAG(PT_ERROR , 0x36D2) /* 0x36D2000A */ #define PidTagIpmNoteEntryId PROP_TAG(PT_BINARY , 0x36D3) /* 0x36D30102 */ #define PidTagIpmNoteEntryId_Error PROP_TAG(PT_ERROR , 0x36D3) /* 0x36D3000A */ #define PidTagIpmTaskEntryId PROP_TAG(PT_BINARY , 0x36D4) /* 0x36D40102 */ #define PidTagIpmTaskEntryId_Error PROP_TAG(PT_ERROR , 0x36D4) /* 0x36D4000A */ #define PidTagIsdnNumber PROP_TAG(PT_UNICODE , 0x3A2D) /* 0x3A2D001F */ #define PidTagIsdnNumber_Error PROP_TAG(PT_ERROR , 0x3A2D) /* 0x3A2D000A */ #define PidTagJunkAddRecipientsToSafeSendersList PROP_TAG(PT_LONG , 0x6103) /* 0x61030003 */ #define PidTagJunkAddRecipientsToSafeSendersList_Error PROP_TAG(PT_ERROR , 0x6103) /* 0x6103000A */ #define PidTagJunkIncludeContacts PROP_TAG(PT_LONG , 0x6100) /* 0x61000003 */ #define PidTagJunkIncludeContacts_Error PROP_TAG(PT_ERROR , 0x6100) /* 0x6100000A */ #define PidTagJunkPermanentlyDelete PROP_TAG(PT_LONG , 0x6102) /* 0x61020003 */ #define PidTagJunkPermanentlyDelete_Error PROP_TAG(PT_ERROR , 0x6102) /* 0x6102000A */ #define PidTagJunkPhishingEnableLinks PROP_TAG(PT_BOOLEAN , 0x6107) /* 0x6107000B */ #define PidTagJunkPhishingEnableLinks_Error PROP_TAG(PT_ERROR , 0x6107) /* 0x6107000A */ #define PidTagJunkThreshold PROP_TAG(PT_LONG , 0x6101) /* 0x61010003 */ #define PidTagJunkThreshold_Error PROP_TAG(PT_ERROR , 0x6101) /* 0x6101000A */ #define PidTagKeyword PROP_TAG(PT_UNICODE , 0x3A0B) /* 0x3A0B001F */ #define PidTagKeyword_Error PROP_TAG(PT_ERROR , 0x3A0B) /* 0x3A0B000A */ #define PidTagLanguage PROP_TAG(PT_UNICODE , 0x3A0C) /* 0x3A0C001F */ #define PidTagLanguage_Error PROP_TAG(PT_ERROR , 0x3A0C) /* 0x3A0C000A */ #define PidTagLastModificationTime PROP_TAG(PT_SYSTIME , 0x3008) /* 0x30080040 */ #define PidTagLastModificationTime_Error PROP_TAG(PT_ERROR , 0x3008) /* 0x3008000A */ #define PidTagLastModifierEntryId PROP_TAG(PT_BINARY , 0x3FFB) /* 0x3FFB0102 */ #define PidTagLastModifierEntryId_Error PROP_TAG(PT_ERROR , 0x3FFB) /* 0x3FFB000A */ #define PidTagLastModifierName PROP_TAG(PT_UNICODE , 0x3FFA) /* 0x3FFA001F */ #define PidTagLastModifierName_Error PROP_TAG(PT_ERROR , 0x3FFA) /* 0x3FFA000A */ #define PidTagLastModifierSimpleDisplayName PROP_TAG(PT_UNICODE , 0x4039) /* 0x4039001F */ #define PidTagLastModifierSimpleDisplayName_Error PROP_TAG(PT_ERROR , 0x4039) /* 0x4039000A */ #define PidTagLastVerbExecuted PROP_TAG(PT_LONG , 0x1081) /* 0x10810003 */ #define PidTagLastVerbExecuted_Error PROP_TAG(PT_ERROR , 0x1081) /* 0x1081000A */ #define PidTagLastVerbExecutionTime PROP_TAG(PT_SYSTIME , 0x1082) /* 0x10820040 */ #define PidTagLastVerbExecutionTime_Error PROP_TAG(PT_ERROR , 0x1082) /* 0x1082000A */ #define PidTagListHelp PROP_TAG(PT_UNICODE , 0x1043) /* 0x1043001F */ #define PidTagListHelp_Error PROP_TAG(PT_ERROR , 0x1043) /* 0x1043000A */ #define PidTagListSubscribe PROP_TAG(PT_UNICODE , 0x1044) /* 0x1044001F */ #define PidTagListSubscribe_Error PROP_TAG(PT_ERROR , 0x1044) /* 0x1044000A */ #define PidTagListUnsubscribe PROP_TAG(PT_UNICODE , 0x1045) /* 0x1045001F */ #define PidTagListUnsubscribe_Error PROP_TAG(PT_ERROR , 0x1045) /* 0x1045000A */ #define PidTagLocalCommitTime PROP_TAG(PT_SYSTIME , 0x6709) /* 0x67090040 */ #define PidTagLocalCommitTime_Error PROP_TAG(PT_ERROR , 0x6709) /* 0x6709000A */ #define PidTagLocaleId PROP_TAG(PT_LONG , 0x66A1) /* 0x66A10003 */ #define PidTagLocaleId_Error PROP_TAG(PT_ERROR , 0x66A1) /* 0x66A1000A */ #define PidTagLocality PROP_TAG(PT_UNICODE , 0x3A27) /* 0x3A27001F */ #define PidTagLocality_Error PROP_TAG(PT_ERROR , 0x3A27) /* 0x3A27000A */ #define PidTagLocation PROP_TAG(PT_UNICODE , 0x3A0D) /* 0x3A0D001F */ #define PidTagLocation_Error PROP_TAG(PT_ERROR , 0x3A0D) /* 0x3A0D000A */ #define PidTagMailboxOwnerEntryId PROP_TAG(PT_BINARY , 0x661B) /* 0x661B0102 */ #define PidTagMailboxOwnerEntryId_Error PROP_TAG(PT_ERROR , 0x661B) /* 0x661B000A */ #define PidTagMailboxOwnerName PROP_TAG(PT_UNICODE , 0x661C) /* 0x661C001F */ #define PidTagMailboxOwnerName_Error PROP_TAG(PT_ERROR , 0x661C) /* 0x661C000A */ #define PidTagManagerName PROP_TAG(PT_UNICODE , 0x3A4E) /* 0x3A4E001F */ #define PidTagManagerName_Error PROP_TAG(PT_ERROR , 0x3A4E) /* 0x3A4E000A */ #define PidTagMappingSignature PROP_TAG(PT_BINARY , 0x0FF8) /* 0x0FF80102 */ #define PidTagMappingSignature_Error PROP_TAG(PT_ERROR , 0x0FF8) /* 0x0FF8000A */ #define PidTagMaximumSubmitMessageSize PROP_TAG(PT_LONG , 0x666D) /* 0x666D0003 */ #define PidTagMaximumSubmitMessageSize_Error PROP_TAG(PT_ERROR , 0x666D) /* 0x666D000A */ #define PidTagMemberId PROP_TAG(PT_I8 , 0x6671) /* 0x66710014 */ #define PidTagMemberId_Error PROP_TAG(PT_ERROR , 0x6671) /* 0x6671000A */ #define PidTagMemberName PROP_TAG(PT_UNICODE , 0x6672) /* 0x6672001F */ #define PidTagMemberName_Error PROP_TAG(PT_ERROR , 0x6672) /* 0x6672000A */ #define PidTagMemberRights PROP_TAG(PT_LONG , 0x6673) /* 0x66730003 */ #define PidTagMemberRights_Error PROP_TAG(PT_ERROR , 0x6673) /* 0x6673000A */ #define PidTagMessageAttachments PROP_TAG(PT_OBJECT , 0x0E13) /* 0x0E13000D */ #define PidTagMessageAttachments_Error PROP_TAG(PT_ERROR , 0x0E13) /* 0x0E13000A */ #define PidTagMessageCcMe PROP_TAG(PT_BOOLEAN , 0x0058) /* 0x0058000B */ #define PidTagMessageCcMe_Error PROP_TAG(PT_ERROR , 0x0058) /* 0x0058000A */ #define PidTagMessageClass PROP_TAG(PT_UNICODE , 0x001A) /* 0x001A001F */ #define PidTagMessageClass_Error PROP_TAG(PT_ERROR , 0x001A) /* 0x001A000A */ #define PidTagMessageCodepage PROP_TAG(PT_LONG , 0x3FFD) /* 0x3FFD0003 */ #define PidTagMessageCodepage_Error PROP_TAG(PT_ERROR , 0x3FFD) /* 0x3FFD000A */ #define PidTagMessageDeliveryTime PROP_TAG(PT_SYSTIME , 0x0E06) /* 0x0E060040 */ #define PidTagMessageDeliveryTime_Error PROP_TAG(PT_ERROR , 0x0E06) /* 0x0E06000A */ #define PidTagMessageEditorFormat PROP_TAG(PT_LONG , 0x5909) /* 0x59090003 */ #define PidTagMessageEditorFormat_Error PROP_TAG(PT_ERROR , 0x5909) /* 0x5909000A */ #define PidTagMessageFlags PROP_TAG(PT_LONG , 0x0E07) /* 0x0E070003 */ #define PidTagMessageFlags_Error PROP_TAG(PT_ERROR , 0x0E07) /* 0x0E07000A */ #define PidTagMessageHandlingSystemCommonName PROP_TAG(PT_UNICODE , 0x3A0F) /* 0x3A0F001F */ #define PidTagMessageHandlingSystemCommonName_Error PROP_TAG(PT_ERROR , 0x3A0F) /* 0x3A0F000A */ #define PidTagMessageLocaleId PROP_TAG(PT_LONG , 0x3FF1) /* 0x3FF10003 */ #define PidTagMessageLocaleId_Error PROP_TAG(PT_ERROR , 0x3FF1) /* 0x3FF1000A */ #define PidTagMessageRecipientMe PROP_TAG(PT_BOOLEAN , 0x0059) /* 0x0059000B */ #define PidTagMessageRecipientMe_Error PROP_TAG(PT_ERROR , 0x0059) /* 0x0059000A */ #define PidTagMessageRecipients PROP_TAG(PT_OBJECT , 0x0E12) /* 0x0E12000D */ #define PidTagMessageRecipients_Error PROP_TAG(PT_ERROR , 0x0E12) /* 0x0E12000A */ #define PidTagMessageSize PROP_TAG(PT_LONG , 0x0E08) /* 0x0E080003 */ #define PidTagMessageSizeExtended PROP_TAG(PT_I8 , 0x0E08) /* 0x0E080014 */ #define PidTagMessageSizeExtended_Error PROP_TAG(PT_ERROR , 0x0E08) /* 0x0E08000A */ #define PidTagMessageSize_Error PROP_TAG(PT_ERROR , 0x0E08) /* 0x0E08000A */ #define PidTagMessageStatus PROP_TAG(PT_LONG , 0x0E17) /* 0x0E170003 */ #define PidTagMessageStatus_Error PROP_TAG(PT_ERROR , 0x0E17) /* 0x0E17000A */ #define PidTagMessageSubmissionId PROP_TAG(PT_BINARY , 0x0047) /* 0x00470102 */ #define PidTagMessageSubmissionId_Error PROP_TAG(PT_ERROR , 0x0047) /* 0x0047000A */ #define PidTagMessageToMe PROP_TAG(PT_BOOLEAN , 0x0057) /* 0x0057000B */ #define PidTagMessageToMe_Error PROP_TAG(PT_ERROR , 0x0057) /* 0x0057000A */ #define PidTagMid PROP_TAG(PT_I8 , 0x674A) /* 0x674A0014 */ #define PidTagMid_Error PROP_TAG(PT_ERROR , 0x674A) /* 0x674A000A */ #define PidTagMiddleName PROP_TAG(PT_UNICODE , 0x3A44) /* 0x3A44001F */ #define PidTagMiddleName_Error PROP_TAG(PT_ERROR , 0x3A44) /* 0x3A44000A */ #define PidTagMimeSkeleton PROP_TAG(PT_BINARY , 0x0470) /* 0x04700102 */ #define PidTagMimeSkeleton_Error PROP_TAG(PT_ERROR , 0x0470) /* 0x0470000A */ #define PidTagMobileTelephoneNumber PROP_TAG(PT_UNICODE , 0x3A1C) /* 0x3A1C001F */ #define PidTagMobileTelephoneNumber_Error PROP_TAG(PT_ERROR , 0x3A1C) /* 0x3A1C000A */ #define PidTagNativeBody PROP_TAG(PT_LONG , 0x1016) /* 0x10160003 */ #define PidTagNativeBody_Error PROP_TAG(PT_ERROR , 0x1016) /* 0x1016000A */ #define PidTagNewAttach PROP_TAG(PT_LONG , 0x4000) /* 0x40000003 */ #define PidTagNewAttach_Error PROP_TAG(PT_ERROR , 0x4000) /* 0x4000000A */ #define PidTagNewFXFolder PROP_TAG(PT_BINARY , 0x4011) /* 0x40110102 */ #define PidTagNewFXFolder_Error PROP_TAG(PT_ERROR , 0x4011) /* 0x4011000A */ #define PidTagNextSendAcct PROP_TAG(PT_UNICODE , 0x0E29) /* 0x0E29001F */ #define PidTagNextSendAcct_Error PROP_TAG(PT_ERROR , 0x0E29) /* 0x0E29000A */ #define PidTagNickname PROP_TAG(PT_UNICODE , 0x3A4F) /* 0x3A4F001F */ #define PidTagNickname_Error PROP_TAG(PT_ERROR , 0x3A4F) /* 0x3A4F000A */ #define PidTagNormalMessageSize PROP_TAG(PT_LONG , 0x66B3) /* 0x66B30003 */ #define PidTagNormalMessageSize_Error PROP_TAG(PT_ERROR , 0x66B3) /* 0x66B3000A */ #define PidTagNormalizedSubject PROP_TAG(PT_UNICODE , 0x0E1D) /* 0x0E1D001F */ #define PidTagNormalizedSubject_Error PROP_TAG(PT_ERROR , 0x0E1D) /* 0x0E1D000A */ #define PidTagObjectType PROP_TAG(PT_LONG , 0x0FFE) /* 0x0FFE0003 */ #define PidTagObjectType_Error PROP_TAG(PT_ERROR , 0x0FFE) /* 0x0FFE000A */ #define PidTagOfficeLocation PROP_TAG(PT_UNICODE , 0x3A19) /* 0x3A19001F */ #define PidTagOfficeLocation_Error PROP_TAG(PT_ERROR , 0x3A19) /* 0x3A19000A */ #define PidTagOfflineAddressBookCompressedSize PROP_TAG(PT_LONG , 0x6809) /* 0x68090003 */ #define PidTagOfflineAddressBookCompressedSize_Error PROP_TAG(PT_ERROR , 0x6809) /* 0x6809000A */ #define PidTagOfflineAddressBookContainerGuid PROP_TAG(PT_STRING8 , 0x6802) /* 0x6802001E */ #define PidTagOfflineAddressBookContainerGuid_Error PROP_TAG(PT_ERROR , 0x6802) /* 0x6802000A */ #define PidTagOfflineAddressBookDistinguishedName PROP_TAG(PT_STRING8 , 0x6804) /* 0x6804001E */ #define PidTagOfflineAddressBookDistinguishedName_Error PROP_TAG(PT_ERROR , 0x6804) /* 0x6804000A */ #define PidTagOfflineAddressBookFileSize PROP_TAG(PT_LONG , 0x680A) /* 0x680A0003 */ #define PidTagOfflineAddressBookFileSize_Error PROP_TAG(PT_ERROR , 0x680A) /* 0x680A000A */ #define PidTagOfflineAddressBookFileType PROP_TAG(PT_LONG , 0x6808) /* 0x68080003 */ #define PidTagOfflineAddressBookFileType_Error PROP_TAG(PT_ERROR , 0x6808) /* 0x6808000A */ #define PidTagOfflineAddressBookLanguageId PROP_TAG(PT_LONG , 0x6807) /* 0x68070003 */ #define PidTagOfflineAddressBookLanguageId_Error PROP_TAG(PT_ERROR , 0x6807) /* 0x6807000A */ #define PidTagOfflineAddressBookMessageClass PROP_TAG(PT_LONG , 0x6803) /* 0x68030003 */ #define PidTagOfflineAddressBookMessageClass_Error PROP_TAG(PT_ERROR , 0x6803) /* 0x6803000A */ #define PidTagOfflineAddressBookName PROP_TAG(PT_UNICODE , 0x6800) /* 0x6800001F */ #define PidTagOfflineAddressBookName_Error PROP_TAG(PT_ERROR , 0x6800) /* 0x6800000A */ #define PidTagOfflineAddressBookSequence PROP_TAG(PT_LONG , 0x6801) /* 0x68010003 */ #define PidTagOfflineAddressBookSequence_Error PROP_TAG(PT_ERROR , 0x6801) /* 0x6801000A */ #define PidTagOfflineAddressBookShaHash PROP_TAG(PT_BINARY , 0x6806) /* 0x68060102 */ #define PidTagOfflineAddressBookShaHash_Error PROP_TAG(PT_ERROR , 0x6806) /* 0x6806000A */ #define PidTagOfflineAddressBookTruncatedProperties PROP_TAG(PT_MV_LONG , 0x6805) /* 0x68051003 */ #define PidTagOfflineAddressBookTruncatedProperties_Error PROP_TAG(PT_ERROR , 0x6805) /* 0x6805000A */ #define PidTagOrdinalMost PROP_TAG(PT_LONG , 0x36E2) /* 0x36E20003 */ #define PidTagOrdinalMost_Error PROP_TAG(PT_ERROR , 0x36E2) /* 0x36E2000A */ #define PidTagOrganizationalIdNumber PROP_TAG(PT_UNICODE , 0x3A10) /* 0x3A10001F */ #define PidTagOrganizationalIdNumber_Error PROP_TAG(PT_ERROR , 0x3A10) /* 0x3A10000A */ #define PidTagOriginalDeliveryTime PROP_TAG(PT_SYSTIME , 0x0055) /* 0x00550040 */ #define PidTagOriginalDeliveryTime_Error PROP_TAG(PT_ERROR , 0x0055) /* 0x0055000A */ #define PidTagOriginalDisplayBcc PROP_TAG(PT_UNICODE , 0x0072) /* 0x0072001F */ #define PidTagOriginalDisplayBcc_Error PROP_TAG(PT_ERROR , 0x0072) /* 0x0072000A */ #define PidTagOriginalDisplayCc PROP_TAG(PT_UNICODE , 0x0073) /* 0x0073001F */ #define PidTagOriginalDisplayCc_Error PROP_TAG(PT_ERROR , 0x0073) /* 0x0073000A */ #define PidTagOriginalDisplayName PROP_TAG(PT_UNICODE , 0x3A13) /* 0x3A13001F */ #define PidTagOriginalDisplayName_Error PROP_TAG(PT_ERROR , 0x3A13) /* 0x3A13000A */ #define PidTagOriginalDisplayTo PROP_TAG(PT_UNICODE , 0x0074) /* 0x0074001F */ #define PidTagOriginalDisplayTo_Error PROP_TAG(PT_ERROR , 0x0074) /* 0x0074000A */ #define PidTagOriginalEntryId PROP_TAG(PT_BINARY , 0x3A12) /* 0x3A120102 */ #define PidTagOriginalEntryId_Error PROP_TAG(PT_ERROR , 0x3A12) /* 0x3A12000A */ #define PidTagOriginalMessageClass PROP_TAG(PT_UNICODE , 0x004B) /* 0x004B001F */ #define PidTagOriginalMessageClass_Error PROP_TAG(PT_ERROR , 0x004B) /* 0x004B000A */ #define PidTagOriginalMessageId PROP_TAG(PT_UNICODE , 0x1046) /* 0x1046001F */ #define PidTagOriginalMessageId_Error PROP_TAG(PT_ERROR , 0x1046) /* 0x1046000A */ #define PidTagOriginalSearchKey PROP_TAG(PT_BINARY , 0x3A14) /* 0x3A140102 */ #define PidTagOriginalSearchKey_Error PROP_TAG(PT_ERROR , 0x3A14) /* 0x3A14000A */ #define PidTagOriginalSenderAddressType PROP_TAG(PT_UNICODE , 0x0066) /* 0x0066001F */ #define PidTagOriginalSenderAddressType_Error PROP_TAG(PT_ERROR , 0x0066) /* 0x0066000A */ #define PidTagOriginalSenderEmailAddress PROP_TAG(PT_UNICODE , 0x0067) /* 0x0067001F */ #define PidTagOriginalSenderEmailAddress_Error PROP_TAG(PT_ERROR , 0x0067) /* 0x0067000A */ #define PidTagOriginalSenderEntryId PROP_TAG(PT_BINARY , 0x005B) /* 0x005B0102 */ #define PidTagOriginalSenderEntryId_Error PROP_TAG(PT_ERROR , 0x005B) /* 0x005B000A */ #define PidTagOriginalSenderName PROP_TAG(PT_UNICODE , 0x005A) /* 0x005A001F */ #define PidTagOriginalSenderName_Error PROP_TAG(PT_ERROR , 0x005A) /* 0x005A000A */ #define PidTagOriginalSenderSearchKey PROP_TAG(PT_BINARY , 0x005C) /* 0x005C0102 */ #define PidTagOriginalSenderSearchKey_Error PROP_TAG(PT_ERROR , 0x005C) /* 0x005C000A */ #define PidTagOriginalSensitivity PROP_TAG(PT_LONG , 0x002E) /* 0x002E0003 */ #define PidTagOriginalSensitivity_Error PROP_TAG(PT_ERROR , 0x002E) /* 0x002E000A */ #define PidTagOriginalSentRepresentingAddressType PROP_TAG(PT_UNICODE , 0x0068) /* 0x0068001F */ #define PidTagOriginalSentRepresentingAddressType_Error PROP_TAG(PT_ERROR , 0x0068) /* 0x0068000A */ #define PidTagOriginalSentRepresentingEmailAddress PROP_TAG(PT_UNICODE , 0x0069) /* 0x0069001F */ #define PidTagOriginalSentRepresentingEmailAddress_Error PROP_TAG(PT_ERROR , 0x0069) /* 0x0069000A */ #define PidTagOriginalSentRepresentingEntryId PROP_TAG(PT_BINARY , 0x005E) /* 0x005E0102 */ #define PidTagOriginalSentRepresentingEntryId_Error PROP_TAG(PT_ERROR , 0x005E) /* 0x005E000A */ #define PidTagOriginalSentRepresentingName PROP_TAG(PT_UNICODE , 0x005D) /* 0x005D001F */ #define PidTagOriginalSentRepresentingName_Error PROP_TAG(PT_ERROR , 0x005D) /* 0x005D000A */ #define PidTagOriginalSentRepresentingSearchKey PROP_TAG(PT_BINARY , 0x005F) /* 0x005F0102 */ #define PidTagOriginalSentRepresentingSearchKey_Error PROP_TAG(PT_ERROR , 0x005F) /* 0x005F000A */ #define PidTagOriginalSubject PROP_TAG(PT_UNICODE , 0x0049) /* 0x0049001F */ #define PidTagOriginalSubject_Error PROP_TAG(PT_ERROR , 0x0049) /* 0x0049000A */ #define PidTagOriginalSubmitTime PROP_TAG(PT_SYSTIME , 0x004E) /* 0x004E0040 */ #define PidTagOriginalSubmitTime_Error PROP_TAG(PT_ERROR , 0x004E) /* 0x004E000A */ #define PidTagOriginatorDeliveryReportRequested PROP_TAG(PT_BOOLEAN , 0x0023) /* 0x0023000B */ #define PidTagOriginatorDeliveryReportRequested_Error PROP_TAG(PT_ERROR , 0x0023) /* 0x0023000A */ #define PidTagOriginatorNonDeliveryReportRequested PROP_TAG(PT_BOOLEAN , 0x0C08) /* 0x0C08000B */ #define PidTagOriginatorNonDeliveryReportRequested_Error PROP_TAG(PT_ERROR , 0x0C08) /* 0x0C08000A */ #define PidTagOtherAddressCity PROP_TAG(PT_UNICODE , 0x3A5F) /* 0x3A5F001F */ #define PidTagOtherAddressCity_Error PROP_TAG(PT_ERROR , 0x3A5F) /* 0x3A5F000A */ #define PidTagOtherAddressCountry PROP_TAG(PT_UNICODE , 0x3A60) /* 0x3A60001F */ #define PidTagOtherAddressCountry_Error PROP_TAG(PT_ERROR , 0x3A60) /* 0x3A60000A */ #define PidTagOtherAddressPostOfficeBox PROP_TAG(PT_UNICODE , 0x3A64) /* 0x3A64001F */ #define PidTagOtherAddressPostOfficeBox_Error PROP_TAG(PT_ERROR , 0x3A64) /* 0x3A64000A */ #define PidTagOtherAddressPostalCode PROP_TAG(PT_UNICODE , 0x3A61) /* 0x3A61001F */ #define PidTagOtherAddressPostalCode_Error PROP_TAG(PT_ERROR , 0x3A61) /* 0x3A61000A */ #define PidTagOtherAddressStateOrProvince PROP_TAG(PT_UNICODE , 0x3A62) /* 0x3A62001F */ #define PidTagOtherAddressStateOrProvince_Error PROP_TAG(PT_ERROR , 0x3A62) /* 0x3A62000A */ #define PidTagOtherAddressStreet PROP_TAG(PT_UNICODE , 0x3A63) /* 0x3A63001F */ #define PidTagOtherAddressStreet_Error PROP_TAG(PT_ERROR , 0x3A63) /* 0x3A63000A */ #define PidTagOtherTelephoneNumber PROP_TAG(PT_UNICODE , 0x3A1F) /* 0x3A1F001F */ #define PidTagOtherTelephoneNumber_Error PROP_TAG(PT_ERROR , 0x3A1F) /* 0x3A1F000A */ #define PidTagOutOfOfficeState PROP_TAG(PT_BOOLEAN , 0x661D) /* 0x661D000B */ #define PidTagOutOfOfficeState_Error PROP_TAG(PT_ERROR , 0x661D) /* 0x661D000A */ #define PidTagOwnerAppointmentId PROP_TAG(PT_LONG , 0x0062) /* 0x00620003 */ #define PidTagOwnerAppointmentId_Error PROP_TAG(PT_ERROR , 0x0062) /* 0x0062000A */ #define PidTagPagerTelephoneNumber PROP_TAG(PT_UNICODE , 0x3A21) /* 0x3A21001F */ #define PidTagPagerTelephoneNumber_Error PROP_TAG(PT_ERROR , 0x3A21) /* 0x3A21000A */ #define PidTagParentEntryId PROP_TAG(PT_BINARY , 0x0E09) /* 0x0E090102 */ #define PidTagParentEntryId_Error PROP_TAG(PT_ERROR , 0x0E09) /* 0x0E09000A */ #define PidTagParentFolderId PROP_TAG(PT_I8 , 0x6749) /* 0x67490014 */ #define PidTagParentFolderId_Error PROP_TAG(PT_ERROR , 0x6749) /* 0x6749000A */ #define PidTagParentKey PROP_TAG(PT_BINARY , 0x0025) /* 0x00250102 */ #define PidTagParentKey_Error PROP_TAG(PT_ERROR , 0x0025) /* 0x0025000A */ #define PidTagParentSourceKey PROP_TAG(PT_BINARY , 0x65E1) /* 0x65E10102 */ #define PidTagParentSourceKey_Error PROP_TAG(PT_ERROR , 0x65E1) /* 0x65E1000A */ #define PidTagPersonalHomePage PROP_TAG(PT_UNICODE , 0x3A50) /* 0x3A50001F */ #define PidTagPersonalHomePage_Error PROP_TAG(PT_ERROR , 0x3A50) /* 0x3A50000A */ #define PidTagPolicyTag PROP_TAG(PT_BINARY , 0x3019) /* 0x30190102 */ #define PidTagPolicyTag_Error PROP_TAG(PT_ERROR , 0x3019) /* 0x3019000A */ #define PidTagPostOfficeBox PROP_TAG(PT_UNICODE , 0x3A2B) /* 0x3A2B001F */ #define PidTagPostOfficeBox_Error PROP_TAG(PT_ERROR , 0x3A2B) /* 0x3A2B000A */ #define PidTagPostalAddress PROP_TAG(PT_UNICODE , 0x3A15) /* 0x3A15001F */ #define PidTagPostalAddress_Error PROP_TAG(PT_ERROR , 0x3A15) /* 0x3A15000A */ #define PidTagPostalCode PROP_TAG(PT_UNICODE , 0x3A2A) /* 0x3A2A001F */ #define PidTagPostalCode_Error PROP_TAG(PT_ERROR , 0x3A2A) /* 0x3A2A000A */ #define PidTagPredecessorChangeList PROP_TAG(PT_BINARY , 0x65E3) /* 0x65E30102 */ #define PidTagPredecessorChangeList_Error PROP_TAG(PT_ERROR , 0x65E3) /* 0x65E3000A */ #define PidTagPrimaryFaxNumber PROP_TAG(PT_UNICODE , 0x3A23) /* 0x3A23001F */ #define PidTagPrimaryFaxNumber_Error PROP_TAG(PT_ERROR , 0x3A23) /* 0x3A23000A */ #define PidTagPrimarySendAccount PROP_TAG(PT_UNICODE , 0x0E28) /* 0x0E28001F */ #define PidTagPrimarySendAccount_Error PROP_TAG(PT_ERROR , 0x0E28) /* 0x0E28000A */ #define PidTagPrimarySmtpAddress PROP_TAG(PT_UNICODE , 0x39FE) /* 0x39FE001F */ #define PidTagPrimarySmtpAddress_Error PROP_TAG(PT_ERROR , 0x39FE) /* 0x39FE000A */ #define PidTagPrimaryTelephoneNumber PROP_TAG(PT_UNICODE , 0x3A1A) /* 0x3A1A001F */ #define PidTagPrimaryTelephoneNumber_Error PROP_TAG(PT_ERROR , 0x3A1A) /* 0x3A1A000A */ #define PidTagPriority PROP_TAG(PT_LONG , 0x0026) /* 0x00260003 */ #define PidTagPriority_Error PROP_TAG(PT_ERROR , 0x0026) /* 0x0026000A */ #define PidTagProcessed PROP_TAG(PT_BOOLEAN , 0x7D01) /* 0x7D01000B */ #define PidTagProcessed_Error PROP_TAG(PT_ERROR , 0x7D01) /* 0x7D01000A */ #define PidTagProfession PROP_TAG(PT_UNICODE , 0x3A46) /* 0x3A46001F */ #define PidTagProfession_Error PROP_TAG(PT_ERROR , 0x3A46) /* 0x3A46000A */ #define PidTagProhibitReceiveQuota PROP_TAG(PT_LONG , 0x666A) /* 0x666A0003 */ #define PidTagProhibitReceiveQuota_Error PROP_TAG(PT_ERROR , 0x666A) /* 0x666A000A */ #define PidTagProhibitSendQuota PROP_TAG(PT_LONG , 0x666E) /* 0x666E0003 */ #define PidTagProhibitSendQuota_Error PROP_TAG(PT_ERROR , 0x666E) /* 0x666E000A */ #define PidTagProviderSubmitTime PROP_TAG(PT_SYSTIME , 0x0048) /* 0x00480040 */ #define PidTagProviderSubmitTime_Error PROP_TAG(PT_ERROR , 0x0048) /* 0x0048000A */ #define PidTagPublicFolderAdministrativeDescription PROP_TAG(PT_UNICODE , 0x671C) /* 0x671C001F */ #define PidTagPublicFolderAdministrativeDescription_Error PROP_TAG(PT_ERROR , 0x671C) /* 0x671C000A */ #define PidTagPublicFolderProxy PROP_TAG(PT_BINARY , 0x671D) /* 0x671D0102 */ #define PidTagPublicFolderProxy_Error PROP_TAG(PT_ERROR , 0x671D) /* 0x671D000A */ #define PidTagPurportedSenderDomain PROP_TAG(PT_UNICODE , 0x4083) /* 0x4083001F */ #define PidTagPurportedSenderDomain_Error PROP_TAG(PT_ERROR , 0x4083) /* 0x4083000A */ #define PidTagRadioTelephoneNumber PROP_TAG(PT_UNICODE , 0x3A1D) /* 0x3A1D001F */ #define PidTagRadioTelephoneNumber_Error PROP_TAG(PT_ERROR , 0x3A1D) /* 0x3A1D000A */ #define PidTagRead PROP_TAG(PT_BOOLEAN , 0x0E69) /* 0x0E69000B */ #define PidTagReadReceiptAddressType PROP_TAG(PT_UNICODE , 0x4029) /* 0x4029001F */ #define PidTagReadReceiptAddressType_Error PROP_TAG(PT_ERROR , 0x4029) /* 0x4029000A */ #define PidTagReadReceiptEmailAddress PROP_TAG(PT_UNICODE , 0x402A) /* 0x402A001F */ #define PidTagReadReceiptEmailAddress_Error PROP_TAG(PT_ERROR , 0x402A) /* 0x402A000A */ #define PidTagReadReceiptEntryId PROP_TAG(PT_BINARY , 0x0046) /* 0x00460102 */ #define PidTagReadReceiptEntryId_Error PROP_TAG(PT_ERROR , 0x0046) /* 0x0046000A */ #define PidTagReadReceiptName PROP_TAG(PT_UNICODE , 0x402B) /* 0x402B001F */ #define PidTagReadReceiptName_Error PROP_TAG(PT_ERROR , 0x402B) /* 0x402B000A */ #define PidTagReadReceiptRequested PROP_TAG(PT_BOOLEAN , 0x0029) /* 0x0029000B */ #define PidTagReadReceiptRequested_Error PROP_TAG(PT_ERROR , 0x0029) /* 0x0029000A */ #define PidTagReadReceiptSearchKey PROP_TAG(PT_BINARY , 0x0053) /* 0x00530102 */ #define PidTagReadReceiptSearchKey_Error PROP_TAG(PT_ERROR , 0x0053) /* 0x0053000A */ #define PidTagRead_Error PROP_TAG(PT_ERROR , 0x0E69) /* 0x0E69000A */ #define PidTagReceivedByAddressType PROP_TAG(PT_UNICODE , 0x0075) /* 0x0075001F */ #define PidTagReceivedByAddressType_Error PROP_TAG(PT_ERROR , 0x0075) /* 0x0075000A */ #define PidTagReceivedByEmailAddress PROP_TAG(PT_UNICODE , 0x0076) /* 0x0076001F */ #define PidTagReceivedByEmailAddress_Error PROP_TAG(PT_ERROR , 0x0076) /* 0x0076000A */ #define PidTagReceivedByEntryId PROP_TAG(PT_BINARY , 0x003F) /* 0x003F0102 */ #define PidTagReceivedByEntryId_Error PROP_TAG(PT_ERROR , 0x003F) /* 0x003F000A */ #define PidTagReceivedByFlags PROP_TAG(PT_LONG , 0x401B) /* 0x401B0003 */ #define PidTagReceivedByFlags_Error PROP_TAG(PT_ERROR , 0x401B) /* 0x401B000A */ #define PidTagReceivedByName PROP_TAG(PT_UNICODE , 0x0040) /* 0x0040001F */ #define PidTagReceivedByName_Error PROP_TAG(PT_ERROR , 0x0040) /* 0x0040000A */ #define PidTagReceivedBySearchKey PROP_TAG(PT_BINARY , 0x0051) /* 0x00510102 */ #define PidTagReceivedBySearchKey_Error PROP_TAG(PT_ERROR , 0x0051) /* 0x0051000A */ #define PidTagReceivedRepresentingAddressType PROP_TAG(PT_UNICODE , 0x0077) /* 0x0077001F */ #define PidTagReceivedRepresentingAddressType_Error PROP_TAG(PT_ERROR , 0x0077) /* 0x0077000A */ #define PidTagReceivedRepresentingEmailAddress PROP_TAG(PT_UNICODE , 0x0078) /* 0x0078001F */ #define PidTagReceivedRepresentingEmailAddress_Error PROP_TAG(PT_ERROR , 0x0078) /* 0x0078000A */ #define PidTagReceivedRepresentingEntryId PROP_TAG(PT_BINARY , 0x0043) /* 0x00430102 */ #define PidTagReceivedRepresentingEntryId_Error PROP_TAG(PT_ERROR , 0x0043) /* 0x0043000A */ #define PidTagReceivedRepresentingFlags PROP_TAG(PT_LONG , 0x401C) /* 0x401C0003 */ #define PidTagReceivedRepresentingFlags_Error PROP_TAG(PT_ERROR , 0x401C) /* 0x401C000A */ #define PidTagReceivedRepresentingName PROP_TAG(PT_UNICODE , 0x0044) /* 0x0044001F */ #define PidTagReceivedRepresentingName_Error PROP_TAG(PT_ERROR , 0x0044) /* 0x0044000A */ #define PidTagReceivedRepresentingSearchKey PROP_TAG(PT_BINARY , 0x0052) /* 0x00520102 */ #define PidTagReceivedRepresentingSearchKey_Error PROP_TAG(PT_ERROR , 0x0052) /* 0x0052000A */ #define PidTagReceivedRepresentingSimpleDisplayName PROP_TAG(PT_UNICODE , 0x4035) /* 0x4035001F */ #define PidTagReceivedRepresentingSimpleDisplayName_Error PROP_TAG(PT_ERROR , 0x4035) /* 0x4035000A */ #define PidTagRecipientDisplayName PROP_TAG(PT_UNICODE , 0x5FF6) /* 0x5FF6001F */ #define PidTagRecipientDisplayName_Error PROP_TAG(PT_ERROR , 0x5FF6) /* 0x5FF6000A */ #define PidTagRecipientEntryId PROP_TAG(PT_BINARY , 0x5FF7) /* 0x5FF70102 */ #define PidTagRecipientEntryId_Error PROP_TAG(PT_ERROR , 0x5FF7) /* 0x5FF7000A */ #define PidTagRecipientFlags PROP_TAG(PT_LONG , 0x5FFD) /* 0x5FFD0003 */ #define PidTagRecipientFlags_Error PROP_TAG(PT_ERROR , 0x5FFD) /* 0x5FFD000A */ #define PidTagRecipientOrder PROP_TAG(PT_LONG , 0x5FDF) /* 0x5FDF0003 */ #define PidTagRecipientOrder_Error PROP_TAG(PT_ERROR , 0x5FDF) /* 0x5FDF000A */ #define PidTagRecipientProposed PROP_TAG(PT_BOOLEAN , 0x5FE1) /* 0x5FE1000B */ #define PidTagRecipientProposedEndTime PROP_TAG(PT_SYSTIME , 0x5FE4) /* 0x5FE40040 */ #define PidTagRecipientProposedEndTime_Error PROP_TAG(PT_ERROR , 0x5FE4) /* 0x5FE4000A */ #define PidTagRecipientProposedStartTime PROP_TAG(PT_SYSTIME , 0x5FE3) /* 0x5FE30040 */ #define PidTagRecipientProposedStartTime_Error PROP_TAG(PT_ERROR , 0x5FE3) /* 0x5FE3000A */ #define PidTagRecipientProposed_Error PROP_TAG(PT_ERROR , 0x5FE1) /* 0x5FE1000A */ #define PidTagRecipientReassignmentProhibited PROP_TAG(PT_BOOLEAN , 0x002B) /* 0x002B000B */ #define PidTagRecipientReassignmentProhibited_Error PROP_TAG(PT_ERROR , 0x002B) /* 0x002B000A */ #define PidTagRecipientResourceState PROP_TAG(PT_LONG , 0x5FDE) /* 0x5FDE0003 */ #define PidTagRecipientResourceState_Error PROP_TAG(PT_ERROR , 0x5FDE) /* 0x5FDE000A */ #define PidTagRecipientTrackStatus PROP_TAG(PT_LONG , 0x5FFF) /* 0x5FFF0003 */ #define PidTagRecipientTrackStatusTime PROP_TAG(PT_SYSTIME , 0x5FFB) /* 0x5FFB0040 */ #define PidTagRecipientTrackStatusTime_Error PROP_TAG(PT_ERROR , 0x5FFB) /* 0x5FFB000A */ #define PidTagRecipientTrackStatus_Error PROP_TAG(PT_ERROR , 0x5FFF) /* 0x5FFF000A */ #define PidTagRecipientType PROP_TAG(PT_LONG , 0x0C15) /* 0x0C150003 */ #define PidTagRecipientType_Error PROP_TAG(PT_ERROR , 0x0C15) /* 0x0C15000A */ #define PidTagRecordKey PROP_TAG(PT_BINARY , 0x0FF9) /* 0x0FF90102 */ #define PidTagRecordKey_Error PROP_TAG(PT_ERROR , 0x0FF9) /* 0x0FF9000A */ #define PidTagReferredByName PROP_TAG(PT_UNICODE , 0x3A47) /* 0x3A47001F */ #define PidTagReferredByName_Error PROP_TAG(PT_ERROR , 0x3A47) /* 0x3A47000A */ #define PidTagRemindersOnlineEntryId PROP_TAG(PT_BINARY , 0x36D5) /* 0x36D50102 */ #define PidTagRemindersOnlineEntryId_Error PROP_TAG(PT_ERROR , 0x36D5) /* 0x36D5000A */ #define PidTagRemoteHeaderLoc PROP_TAG(PT_UNICODE , 0x0078) /* 0x0078001F */ #define PidTagRemoteHeaderLoc_Error PROP_TAG(PT_ERROR , 0x0078) /* 0x0078000A */ #define PidTagRemoteMessageTransferAgent PROP_TAG(PT_UNICODE , 0x0C21) /* 0x0C21001F */ #define PidTagRemoteMessageTransferAgent_Error PROP_TAG(PT_ERROR , 0x0C21) /* 0x0C21000A */ #define PidTagRenderingPosition PROP_TAG(PT_LONG , 0x370B) /* 0x370B0003 */ #define PidTagRenderingPosition_Error PROP_TAG(PT_ERROR , 0x370B) /* 0x370B000A */ #define PidTagReplyRecipientEntries PROP_TAG(PT_BINARY , 0x004F) /* 0x004F0102 */ #define PidTagReplyRecipientEntries_Error PROP_TAG(PT_ERROR , 0x004F) /* 0x004F000A */ #define PidTagReplyRecipientNames PROP_TAG(PT_UNICODE , 0x0050) /* 0x0050001F */ #define PidTagReplyRecipientNames_Error PROP_TAG(PT_ERROR , 0x0050) /* 0x0050000A */ #define PidTagReplyRequested PROP_TAG(PT_BOOLEAN , 0x0C17) /* 0x0C17000B */ #define PidTagReplyRequested_Error PROP_TAG(PT_ERROR , 0x0C17) /* 0x0C17000A */ #define PidTagReplyTemplateId PROP_TAG(PT_BINARY , 0x65C2) /* 0x65C20102 */ #define PidTagReplyTemplateId_Error PROP_TAG(PT_ERROR , 0x65C2) /* 0x65C2000A */ #define PidTagReplyTime PROP_TAG(PT_SYSTIME , 0x0030) /* 0x00300040 */ #define PidTagReplyTime_Error PROP_TAG(PT_ERROR , 0x0030) /* 0x0030000A */ #define PidTagReportEntryId PROP_TAG(PT_BINARY , 0x0045) /* 0x00450102 */ #define PidTagReportEntryId_Error PROP_TAG(PT_ERROR , 0x0045) /* 0x0045000A */ #define PidTagReportName PROP_TAG(PT_UNICODE , 0x003A) /* 0x003A001F */ #define PidTagReportName_Error PROP_TAG(PT_ERROR , 0x003A) /* 0x003A000A */ #define PidTagReportSearchKey PROP_TAG(PT_BINARY , 0x0054) /* 0x00540102 */ #define PidTagReportSearchKey_Error PROP_TAG(PT_ERROR , 0x0054) /* 0x0054000A */ #define PidTagReportTag PROP_TAG(PT_BINARY , 0x0031) /* 0x00310102 */ #define PidTagReportTag_Error PROP_TAG(PT_ERROR , 0x0031) /* 0x0031000A */ #define PidTagReportText PROP_TAG(PT_UNICODE , 0x1001) /* 0x1001001F */ #define PidTagReportText_Error PROP_TAG(PT_ERROR , 0x1001) /* 0x1001000A */ #define PidTagReportTime PROP_TAG(PT_SYSTIME , 0x0032) /* 0x00320040 */ #define PidTagReportTime_Error PROP_TAG(PT_ERROR , 0x0032) /* 0x0032000A */ #define PidTagReportingMessageTransferAgent PROP_TAG(PT_UNICODE , 0x6820) /* 0x6820001F */ #define PidTagReportingMessageTransferAgent_Error PROP_TAG(PT_ERROR , 0x6820) /* 0x6820000A */ #define PidTagResolveMethod PROP_TAG(PT_LONG , 0x3FE7) /* 0x3FE70003 */ #define PidTagResolveMethod_Error PROP_TAG(PT_ERROR , 0x3FE7) /* 0x3FE7000A */ #define PidTagResponseRequested PROP_TAG(PT_BOOLEAN , 0x0063) /* 0x0063000B */ #define PidTagResponseRequested_Error PROP_TAG(PT_ERROR , 0x0063) /* 0x0063000A */ #define PidTagResponsibility PROP_TAG(PT_BOOLEAN , 0x0E0F) /* 0x0E0F000B */ #define PidTagResponsibility_Error PROP_TAG(PT_ERROR , 0x0E0F) /* 0x0E0F000A */ #define PidTagRetentionDate PROP_TAG(PT_SYSTIME , 0x301C) /* 0x301C0040 */ #define PidTagRetentionDate_Error PROP_TAG(PT_ERROR , 0x301C) /* 0x301C000A */ #define PidTagRetentionFlags PROP_TAG(PT_LONG , 0x301D) /* 0x301D0003 */ #define PidTagRetentionFlags_Error PROP_TAG(PT_ERROR , 0x301D) /* 0x301D000A */ #define PidTagRetentionPeriod PROP_TAG(PT_LONG , 0x301A) /* 0x301A0003 */ #define PidTagRetentionPeriod_Error PROP_TAG(PT_ERROR , 0x301A) /* 0x301A000A */ #define PidTagRights PROP_TAG(PT_LONG , 0x6639) /* 0x66390003 */ #define PidTagRights_Error PROP_TAG(PT_ERROR , 0x6639) /* 0x6639000A */ #define PidTagRoamingDatatypes PROP_TAG(PT_LONG , 0x7C06) /* 0x7C060003 */ #define PidTagRoamingDatatypes_Error PROP_TAG(PT_ERROR , 0x7C06) /* 0x7C06000A */ #define PidTagRoamingDictionary PROP_TAG(PT_BINARY , 0x7C07) /* 0x7C070102 */ #define PidTagRoamingDictionary_Error PROP_TAG(PT_ERROR , 0x7C07) /* 0x7C07000A */ #define PidTagRoamingXmlStream PROP_TAG(PT_BINARY , 0x7C08) /* 0x7C080102 */ #define PidTagRoamingXmlStream_Error PROP_TAG(PT_ERROR , 0x7C08) /* 0x7C08000A */ #define PidTagRowType PROP_TAG(PT_LONG , 0x0FF5) /* 0x0FF50003 */ #define PidTagRowType_Error PROP_TAG(PT_ERROR , 0x0FF5) /* 0x0FF5000A */ #define PidTagRowid PROP_TAG(PT_LONG , 0x3000) /* 0x30000003 */ #define PidTagRowid_Error PROP_TAG(PT_ERROR , 0x3000) /* 0x3000000A */ #define PidTagRtfCompressed PROP_TAG(PT_BINARY , 0x1009) /* 0x10090102 */ #define PidTagRtfCompressed_Error PROP_TAG(PT_ERROR , 0x1009) /* 0x1009000A */ #define PidTagRtfInSync PROP_TAG(PT_BOOLEAN , 0x0E1F) /* 0x0E1F000B */ #define PidTagRtfInSync_Error PROP_TAG(PT_ERROR , 0x0E1F) /* 0x0E1F000A */ #define PidTagRtfSyncBodyCount PROP_TAG(PT_LONG , 0x1007) /* 0x10070003 */ #define PidTagRtfSyncBodyCount_Error PROP_TAG(PT_ERROR , 0x1007) /* 0x1007000A */ #define PidTagRtfSyncBodyCrc PROP_TAG(PT_LONG , 0x1006) /* 0x10060003 */ #define PidTagRtfSyncBodyCrc_Error PROP_TAG(PT_ERROR , 0x1006) /* 0x1006000A */ #define PidTagRtfSyncBodyTag PROP_TAG(PT_UNICODE , 0x1008) /* 0x1008001F */ #define PidTagRtfSyncBodyTag_Error PROP_TAG(PT_ERROR , 0x1008) /* 0x1008000A */ #define PidTagRtfSyncPrefixCount PROP_TAG(PT_LONG , 0x1010) /* 0x10100003 */ #define PidTagRtfSyncPrefixCount_Error PROP_TAG(PT_ERROR , 0x1010) /* 0x1010000A */ #define PidTagRtfSyncTrailingCount PROP_TAG(PT_LONG , 0x1011) /* 0x10110003 */ #define PidTagRtfSyncTrailingCount_Error PROP_TAG(PT_ERROR , 0x1011) /* 0x1011000A */ #define PidTagRuleActionNumber PROP_TAG(PT_LONG , 0x6650) /* 0x66500003 */ #define PidTagRuleActionNumber_Error PROP_TAG(PT_ERROR , 0x6650) /* 0x6650000A */ #define PidTagRuleActionType PROP_TAG(PT_LONG , 0x6649) /* 0x66490003 */ #define PidTagRuleActionType_Error PROP_TAG(PT_ERROR , 0x6649) /* 0x6649000A */ #define PidTagRuleActions PROP_TAG(PT_ACTIONS , 0x6680) /* 0x668000FE */ #define PidTagRuleActions_Error PROP_TAG(PT_ERROR , 0x6680) /* 0x6680000A */ #define PidTagRuleCondition PROP_TAG(PT_SRESTRICT , 0x6679) /* 0x667900FD */ #define PidTagRuleCondition_Error PROP_TAG(PT_ERROR , 0x6679) /* 0x6679000A */ #define PidTagRuleError PROP_TAG(PT_LONG , 0x6648) /* 0x66480003 */ #define PidTagRuleError_Error PROP_TAG(PT_ERROR , 0x6648) /* 0x6648000A */ #define PidTagRuleFolderEntryId PROP_TAG(PT_BINARY , 0x6651) /* 0x66510102 */ #define PidTagRuleFolderEntryId_Error PROP_TAG(PT_ERROR , 0x6651) /* 0x6651000A */ #define PidTagRuleId PROP_TAG(PT_I8 , 0x6674) /* 0x66740014 */ #define PidTagRuleId_Error PROP_TAG(PT_ERROR , 0x6674) /* 0x6674000A */ #define PidTagRuleIds PROP_TAG(PT_BINARY , 0x6675) /* 0x66750102 */ #define PidTagRuleIds_Error PROP_TAG(PT_ERROR , 0x6675) /* 0x6675000A */ #define PidTagRuleLevel PROP_TAG(PT_LONG , 0x6683) /* 0x66830003 */ #define PidTagRuleLevel_Error PROP_TAG(PT_ERROR , 0x6683) /* 0x6683000A */ #define PidTagRuleMessageLevel PROP_TAG(PT_LONG , 0x65ED) /* 0x65ED0003 */ #define PidTagRuleMessageLevel_Error PROP_TAG(PT_ERROR , 0x65ED) /* 0x65ED000A */ #define PidTagRuleMessageName PROP_TAG(PT_UNICODE , 0x65EC) /* 0x65EC001F */ #define PidTagRuleMessageName_Error PROP_TAG(PT_ERROR , 0x65EC) /* 0x65EC000A */ #define PidTagRuleMessageProvider PROP_TAG(PT_UNICODE , 0x65EB) /* 0x65EB001F */ #define PidTagRuleMessageProviderData PROP_TAG(PT_BINARY , 0x65EE) /* 0x65EE0102 */ #define PidTagRuleMessageProviderData_Error PROP_TAG(PT_ERROR , 0x65EE) /* 0x65EE000A */ #define PidTagRuleMessageProvider_Error PROP_TAG(PT_ERROR , 0x65EB) /* 0x65EB000A */ #define PidTagRuleMessageSequence PROP_TAG(PT_LONG , 0x65F3) /* 0x65F30003 */ #define PidTagRuleMessageSequence_Error PROP_TAG(PT_ERROR , 0x65F3) /* 0x65F3000A */ #define PidTagRuleMessageState PROP_TAG(PT_LONG , 0x65E9) /* 0x65E90003 */ #define PidTagRuleMessageState_Error PROP_TAG(PT_ERROR , 0x65E9) /* 0x65E9000A */ #define PidTagRuleMessageUserFlags PROP_TAG(PT_LONG , 0x65EA) /* 0x65EA0003 */ #define PidTagRuleMessageUserFlags_Error PROP_TAG(PT_ERROR , 0x65EA) /* 0x65EA000A */ #define PidTagRuleName PROP_TAG(PT_UNICODE , 0x6682) /* 0x6682001F */ #define PidTagRuleName_Error PROP_TAG(PT_ERROR , 0x6682) /* 0x6682000A */ #define PidTagRuleProvider PROP_TAG(PT_UNICODE , 0x6681) /* 0x6681001F */ #define PidTagRuleProviderData PROP_TAG(PT_BINARY , 0x6684) /* 0x66840102 */ #define PidTagRuleProviderData_Error PROP_TAG(PT_ERROR , 0x6684) /* 0x6684000A */ #define PidTagRuleProvider_Error PROP_TAG(PT_ERROR , 0x6681) /* 0x6681000A */ #define PidTagRuleSequence PROP_TAG(PT_LONG , 0x6676) /* 0x66760003 */ #define PidTagRuleSequence_Error PROP_TAG(PT_ERROR , 0x6676) /* 0x6676000A */ #define PidTagRuleState PROP_TAG(PT_LONG , 0x6677) /* 0x66770003 */ #define PidTagRuleState_Error PROP_TAG(PT_ERROR , 0x6677) /* 0x6677000A */ #define PidTagRuleUserFlags PROP_TAG(PT_LONG , 0x6678) /* 0x66780003 */ #define PidTagRuleUserFlags_Error PROP_TAG(PT_ERROR , 0x6678) /* 0x6678000A */ #define PidTagRwRulesStream PROP_TAG(PT_BINARY , 0x6802) /* 0x68020102 */ #define PidTagRwRulesStream_Error PROP_TAG(PT_ERROR , 0x6802) /* 0x6802000A */ #define PidTagScheduleInfoAppointmentTombstone PROP_TAG(PT_BINARY , 0x686A) /* 0x686A0102 */ #define PidTagScheduleInfoAppointmentTombstone_Error PROP_TAG(PT_ERROR , 0x686A) /* 0x686A000A */ #define PidTagScheduleInfoAutoAcceptAppointments PROP_TAG(PT_BOOLEAN , 0x686D) /* 0x686D000B */ #define PidTagScheduleInfoAutoAcceptAppointments_Error PROP_TAG(PT_ERROR , 0x686D) /* 0x686D000A */ #define PidTagScheduleInfoDelegateEntryIds PROP_TAG(PT_MV_BINARY , 0x6845) /* 0x68451102 */ #define PidTagScheduleInfoDelegateEntryIds_Error PROP_TAG(PT_ERROR , 0x6845) /* 0x6845000A */ #define PidTagScheduleInfoDelegateNames PROP_TAG(PT_MV_UNICODE, 0x6844) /* 0x6844101F */ #define PidTagScheduleInfoDelegateNamesW PROP_TAG(PT_MV_UNICODE, 0x684A) /* 0x684A101F */ #define PidTagScheduleInfoDelegateNamesW_Error PROP_TAG(PT_ERROR , 0x684A) /* 0x684A000A */ #define PidTagScheduleInfoDelegateNames_Error PROP_TAG(PT_ERROR , 0x6844) /* 0x6844000A */ #define PidTagScheduleInfoDelegatorWantsCopy PROP_TAG(PT_BOOLEAN , 0x6842) /* 0x6842000B */ #define PidTagScheduleInfoDelegatorWantsCopy_Error PROP_TAG(PT_ERROR , 0x6842) /* 0x6842000A */ #define PidTagScheduleInfoDelegatorWantsInfo PROP_TAG(PT_BOOLEAN , 0x684B) /* 0x684B000B */ #define PidTagScheduleInfoDelegatorWantsInfo_Error PROP_TAG(PT_ERROR , 0x684B) /* 0x684B000A */ #define PidTagScheduleInfoDisallowOverlappingAppts PROP_TAG(PT_BOOLEAN , 0x686F) /* 0x686F000B */ #define PidTagScheduleInfoDisallowOverlappingAppts_Error PROP_TAG(PT_ERROR , 0x686F) /* 0x686F000A */ #define PidTagScheduleInfoDisallowRecurringAppts PROP_TAG(PT_BOOLEAN , 0x686E) /* 0x686E000B */ #define PidTagScheduleInfoDisallowRecurringAppts_Error PROP_TAG(PT_ERROR , 0x686E) /* 0x686E000A */ #define PidTagScheduleInfoDontMailDelegates PROP_TAG(PT_BOOLEAN , 0x6843) /* 0x6843000B */ #define PidTagScheduleInfoDontMailDelegates_Error PROP_TAG(PT_ERROR , 0x6843) /* 0x6843000A */ #define PidTagScheduleInfoFreeBusy PROP_TAG(PT_BINARY , 0x686C) /* 0x686C0102 */ #define PidTagScheduleInfoFreeBusyAway PROP_TAG(PT_MV_BINARY , 0x6856) /* 0x68561102 */ #define PidTagScheduleInfoFreeBusyAway_Error PROP_TAG(PT_ERROR , 0x6856) /* 0x6856000A */ #define PidTagScheduleInfoFreeBusyBusy PROP_TAG(PT_MV_BINARY , 0x6854) /* 0x68541102 */ #define PidTagScheduleInfoFreeBusyBusy_Error PROP_TAG(PT_ERROR , 0x6854) /* 0x6854000A */ #define PidTagScheduleInfoFreeBusyMerged PROP_TAG(PT_MV_BINARY , 0x6850) /* 0x68501102 */ #define PidTagScheduleInfoFreeBusyMerged_Error PROP_TAG(PT_ERROR , 0x6850) /* 0x6850000A */ #define PidTagScheduleInfoFreeBusyTentative PROP_TAG(PT_MV_BINARY , 0x6852) /* 0x68521102 */ #define PidTagScheduleInfoFreeBusyTentative_Error PROP_TAG(PT_ERROR , 0x6852) /* 0x6852000A */ #define PidTagScheduleInfoFreeBusy_Error PROP_TAG(PT_ERROR , 0x686C) /* 0x686C000A */ #define PidTagScheduleInfoMonthsAway PROP_TAG(PT_MV_LONG , 0x6855) /* 0x68551003 */ #define PidTagScheduleInfoMonthsAway_Error PROP_TAG(PT_ERROR , 0x6855) /* 0x6855000A */ #define PidTagScheduleInfoMonthsBusy PROP_TAG(PT_MV_LONG , 0x6853) /* 0x68531003 */ #define PidTagScheduleInfoMonthsBusy_Error PROP_TAG(PT_ERROR , 0x6853) /* 0x6853000A */ #define PidTagScheduleInfoMonthsMerged PROP_TAG(PT_MV_LONG , 0x684F) /* 0x684F1003 */ #define PidTagScheduleInfoMonthsMerged_Error PROP_TAG(PT_ERROR , 0x684F) /* 0x684F000A */ #define PidTagScheduleInfoMonthsTentative PROP_TAG(PT_MV_LONG , 0x6851) /* 0x68511003 */ #define PidTagScheduleInfoMonthsTentative_Error PROP_TAG(PT_ERROR , 0x6851) /* 0x6851000A */ #define PidTagScheduleInfoResourceType PROP_TAG(PT_LONG , 0x6841) /* 0x68410003 */ #define PidTagScheduleInfoResourceType_Error PROP_TAG(PT_ERROR , 0x6841) /* 0x6841000A */ #define PidTagSchedulePlusFreeBusyEntryId PROP_TAG(PT_BINARY , 0x6622) /* 0x66220102 */ #define PidTagSchedulePlusFreeBusyEntryId_Error PROP_TAG(PT_ERROR , 0x6622) /* 0x6622000A */ #define PidTagScriptData PROP_TAG(PT_BINARY , 0x0004) /* 0x00040102 */ #define PidTagScriptData_Error PROP_TAG(PT_ERROR , 0x0004) /* 0x0004000A */ #define PidTagSearchFolderDefinition PROP_TAG(PT_BINARY , 0x6845) /* 0x68450102 */ #define PidTagSearchFolderDefinition_Error PROP_TAG(PT_ERROR , 0x6845) /* 0x6845000A */ #define PidTagSearchFolderEfpFlags PROP_TAG(PT_LONG , 0x6848) /* 0x68480003 */ #define PidTagSearchFolderEfpFlags_Error PROP_TAG(PT_ERROR , 0x6848) /* 0x6848000A */ #define PidTagSearchFolderExpiration PROP_TAG(PT_LONG , 0x683A) /* 0x683A0003 */ #define PidTagSearchFolderExpiration_Error PROP_TAG(PT_ERROR , 0x683A) /* 0x683A000A */ #define PidTagSearchFolderId PROP_TAG(PT_BINARY , 0x6842) /* 0x68420102 */ #define PidTagSearchFolderId_Error PROP_TAG(PT_ERROR , 0x6842) /* 0x6842000A */ #define PidTagSearchFolderLastUsed PROP_TAG(PT_LONG , 0x6834) /* 0x68340003 */ #define PidTagSearchFolderLastUsed_Error PROP_TAG(PT_ERROR , 0x6834) /* 0x6834000A */ #define PidTagSearchFolderRecreateInfo PROP_TAG(PT_BINARY , 0x6844) /* 0x68440102 */ #define PidTagSearchFolderRecreateInfo_Error PROP_TAG(PT_ERROR , 0x6844) /* 0x6844000A */ #define PidTagSearchFolderStorageType PROP_TAG(PT_LONG , 0x6846) /* 0x68460003 */ #define PidTagSearchFolderStorageType_Error PROP_TAG(PT_ERROR , 0x6846) /* 0x6846000A */ #define PidTagSearchFolderTag PROP_TAG(PT_LONG , 0x6847) /* 0x68470003 */ #define PidTagSearchFolderTag_Error PROP_TAG(PT_ERROR , 0x6847) /* 0x6847000A */ #define PidTagSearchFolderTemplateId PROP_TAG(PT_LONG , 0x6841) /* 0x68410003 */ #define PidTagSearchFolderTemplateId_Error PROP_TAG(PT_ERROR , 0x6841) /* 0x6841000A */ #define PidTagSearchKey PROP_TAG(PT_BINARY , 0x300B) /* 0x300B0102 */ #define PidTagSearchKey_Error PROP_TAG(PT_ERROR , 0x300B) /* 0x300B000A */ #define PidTagSecureSubmitFlags PROP_TAG(PT_LONG , 0x65C6) /* 0x65C60003 */ #define PidTagSecureSubmitFlags_Error PROP_TAG(PT_ERROR , 0x65C6) /* 0x65C6000A */ #define PidTagSecurityDescriptor PROP_TAG(PT_BINARY , 0x0E27) /* 0x0E270102 */ #define PidTagSecurityDescriptorAsXml PROP_TAG(PT_UNICODE , 0x0E6A) /* 0x0E6A001F */ #define PidTagSecurityDescriptorAsXml_Error PROP_TAG(PT_ERROR , 0x0E6A) /* 0x0E6A000A */ #define PidTagSecurityDescriptor_Error PROP_TAG(PT_ERROR , 0x0E27) /* 0x0E27000A */ #define PidTagSelectable PROP_TAG(PT_BOOLEAN , 0x3609) /* 0x3609000B */ #define PidTagSelectable_Error PROP_TAG(PT_ERROR , 0x3609) /* 0x3609000A */ #define PidTagSendInternetEncoding PROP_TAG(PT_LONG , 0x3A71) /* 0x3A710003 */ #define PidTagSendInternetEncoding_Error PROP_TAG(PT_ERROR , 0x3A71) /* 0x3A71000A */ #define PidTagSendRichInfo PROP_TAG(PT_BOOLEAN , 0x3A40) /* 0x3A40000B */ #define PidTagSendRichInfo_Error PROP_TAG(PT_ERROR , 0x3A40) /* 0x3A40000A */ #define PidTagSenderAddressType PROP_TAG(PT_UNICODE , 0x0C1E) /* 0x0C1E001F */ #define PidTagSenderAddressType_Error PROP_TAG(PT_ERROR , 0x0C1E) /* 0x0C1E000A */ #define PidTagSenderEmailAddress PROP_TAG(PT_UNICODE , 0x0C1F) /* 0x0C1F001F */ #define PidTagSenderEmailAddress_Error PROP_TAG(PT_ERROR , 0x0C1F) /* 0x0C1F000A */ #define PidTagSenderEntryId PROP_TAG(PT_BINARY , 0x0C19) /* 0x0C190102 */ #define PidTagSenderEntryId_Error PROP_TAG(PT_ERROR , 0x0C19) /* 0x0C19000A */ #define PidTagSenderFlags PROP_TAG(PT_LONG , 0x4019) /* 0x40190003 */ #define PidTagSenderFlags_Error PROP_TAG(PT_ERROR , 0x4019) /* 0x4019000A */ #define PidTagSenderIdStatus PROP_TAG(PT_LONG , 0x4079) /* 0x40790003 */ #define PidTagSenderIdStatus_Error PROP_TAG(PT_ERROR , 0x4079) /* 0x4079000A */ #define PidTagSenderName PROP_TAG(PT_UNICODE , 0x0C1A) /* 0x0C1A001F */ #define PidTagSenderName_Error PROP_TAG(PT_ERROR , 0x0C1A) /* 0x0C1A000A */ #define PidTagSenderSearchKey PROP_TAG(PT_BINARY , 0x0C1D) /* 0x0C1D0102 */ #define PidTagSenderSearchKey_Error PROP_TAG(PT_ERROR , 0x0C1D) /* 0x0C1D000A */ #define PidTagSenderSimpleDisplayName PROP_TAG(PT_UNICODE , 0x4030) /* 0x4030001F */ #define PidTagSenderSimpleDisplayName_Error PROP_TAG(PT_ERROR , 0x4030) /* 0x4030000A */ #define PidTagSenderSmtpAddress PROP_TAG(PT_UNICODE , 0x5D01) /* 0x5D01001F */ #define PidTagSenderSmtpAddress_Error PROP_TAG(PT_ERROR , 0x5D01) /* 0x5D01000A */ #define PidTagSenderTelephoneNumber PROP_TAG(PT_UNICODE , 0x6802) /* 0x6802001F */ #define PidTagSenderTelephoneNumber_Error PROP_TAG(PT_ERROR , 0x6802) /* 0x6802000A */ #define PidTagSensitivity PROP_TAG(PT_LONG , 0x0036) /* 0x00360003 */ #define PidTagSensitivity_Error PROP_TAG(PT_ERROR , 0x0036) /* 0x0036000A */ #define PidTagSentMailSvrEID PROP_TAG(PT_SVREID , 0x6740) /* 0x674000FB */ #define PidTagSentMailSvrEID_Error PROP_TAG(PT_ERROR , 0x6740) /* 0x6740000A */ #define PidTagSentRepresentingAddressType PROP_TAG(PT_UNICODE , 0x0064) /* 0x0064001F */ #define PidTagSentRepresentingAddressType_Error PROP_TAG(PT_ERROR , 0x0064) /* 0x0064000A */ #define PidTagSentRepresentingEmailAddress PROP_TAG(PT_UNICODE , 0x0065) /* 0x0065001F */ #define PidTagSentRepresentingEmailAddress_Error PROP_TAG(PT_ERROR , 0x0065) /* 0x0065000A */ #define PidTagSentRepresentingEntryId PROP_TAG(PT_BINARY , 0x0041) /* 0x00410102 */ #define PidTagSentRepresentingEntryId_Error PROP_TAG(PT_ERROR , 0x0041) /* 0x0041000A */ #define PidTagSentRepresentingFlags PROP_TAG(PT_LONG , 0x401A) /* 0x401A0003 */ #define PidTagSentRepresentingFlags_Error PROP_TAG(PT_ERROR , 0x401A) /* 0x401A000A */ #define PidTagSentRepresentingName PROP_TAG(PT_UNICODE , 0x0042) /* 0x0042001F */ #define PidTagSentRepresentingName_Error PROP_TAG(PT_ERROR , 0x0042) /* 0x0042000A */ #define PidTagSentRepresentingSearchKey PROP_TAG(PT_BINARY , 0x003B) /* 0x003B0102 */ #define PidTagSentRepresentingSearchKey_Error PROP_TAG(PT_ERROR , 0x003B) /* 0x003B000A */ #define PidTagSentRepresentingSimpleDisplayName PROP_TAG(PT_UNICODE , 0x4031) /* 0x4031001F */ #define PidTagSentRepresentingSimpleDisplayName_Error PROP_TAG(PT_ERROR , 0x4031) /* 0x4031000A */ #define PidTagSessionInitiationProtocolUri PROP_TAG(PT_UNICODE , 0x5FE5) /* 0x5FE5001F */ #define PidTagSessionInitiationProtocolUri_Error PROP_TAG(PT_ERROR , 0x5FE5) /* 0x5FE5000A */ #define PidTagSmtpAddress PROP_TAG(PT_UNICODE , 0x39FE) /* 0x39FE001F */ #define PidTagSmtpAddress_Error PROP_TAG(PT_ERROR , 0x39FE) /* 0x39FE000A */ #define PidTagSortLocaleId PROP_TAG(PT_LONG , 0x6705) /* 0x67050003 */ #define PidTagSortLocaleId_Error PROP_TAG(PT_ERROR , 0x6705) /* 0x6705000A */ #define PidTagSourceKey PROP_TAG(PT_BINARY , 0x65E0) /* 0x65E00102 */ #define PidTagSourceKey_Error PROP_TAG(PT_ERROR , 0x65E0) /* 0x65E0000A */ #define PidTagSpokenName PROP_TAG(PT_BINARY , 0x8CC2) /* 0x8CC20102 */ #define PidTagSpokenName_Error PROP_TAG(PT_ERROR , 0x8CC2) /* 0x8CC2000A */ #define PidTagSpouseName PROP_TAG(PT_UNICODE , 0x3A48) /* 0x3A48001F */ #define PidTagSpouseName_Error PROP_TAG(PT_ERROR , 0x3A48) /* 0x3A48000A */ #define PidTagStartDate PROP_TAG(PT_SYSTIME , 0x0060) /* 0x00600040 */ #define PidTagStartDateEtc PROP_TAG(PT_BINARY , 0x301B) /* 0x301B0102 */ #define PidTagStartDateEtc_Error PROP_TAG(PT_ERROR , 0x301B) /* 0x301B000A */ #define PidTagStartDate_Error PROP_TAG(PT_ERROR , 0x0060) /* 0x0060000A */ #define PidTagStartEmbed PROP_TAG(PT_LONG , 0x4001) /* 0x40010003 */ #define PidTagStartEmbed_Error PROP_TAG(PT_ERROR , 0x4001) /* 0x4001000A */ #define PidTagStartFAIMsg PROP_TAG(PT_LONG , 0x4010) /* 0x40100003 */ #define PidTagStartFAIMsg_Error PROP_TAG(PT_ERROR , 0x4010) /* 0x4010000A */ #define PidTagStartMessage PROP_TAG(PT_LONG , 0x400C) /* 0x400C0003 */ #define PidTagStartMessage_Error PROP_TAG(PT_ERROR , 0x400C) /* 0x400C000A */ #define PidTagStartRecip PROP_TAG(PT_LONG , 0x4003) /* 0x40030003 */ #define PidTagStartRecip_Error PROP_TAG(PT_ERROR , 0x4003) /* 0x4003000A */ #define PidTagStartSubFld PROP_TAG(PT_LONG , 0x400A) /* 0x400A0003 */ #define PidTagStartSubFld_Error PROP_TAG(PT_ERROR , 0x400A) /* 0x400A000A */ #define PidTagStartTopFld PROP_TAG(PT_LONG , 0x4009) /* 0x40090003 */ #define PidTagStartTopFld_Error PROP_TAG(PT_ERROR , 0x4009) /* 0x4009000A */ #define PidTagStateOrProvince PROP_TAG(PT_UNICODE , 0x3A28) /* 0x3A28001F */ #define PidTagStateOrProvince_Error PROP_TAG(PT_ERROR , 0x3A28) /* 0x3A28000A */ #define PidTagStoreEntryId PROP_TAG(PT_BINARY , 0x0FFB) /* 0x0FFB0102 */ #define PidTagStoreEntryId_Error PROP_TAG(PT_ERROR , 0x0FFB) /* 0x0FFB000A */ #define PidTagStoreState PROP_TAG(PT_LONG , 0x340E) /* 0x340E0003 */ #define PidTagStoreState_Error PROP_TAG(PT_ERROR , 0x340E) /* 0x340E000A */ #define PidTagStoreSupportMask PROP_TAG(PT_LONG , 0x340D) /* 0x340D0003 */ #define PidTagStoreSupportMask_Error PROP_TAG(PT_ERROR , 0x340D) /* 0x340D000A */ #define PidTagStreetAddress PROP_TAG(PT_UNICODE , 0x3A29) /* 0x3A29001F */ #define PidTagStreetAddress_Error PROP_TAG(PT_ERROR , 0x3A29) /* 0x3A29000A */ #define PidTagSubfolder PROP_TAG(PT_BOOLEAN , 0x6708) /* 0x6708000B */ #define PidTagSubfolder_Error PROP_TAG(PT_ERROR , 0x6708) /* 0x6708000A */ #define PidTagSubfolders PROP_TAG(PT_BOOLEAN , 0x360A) /* 0x360A000B */ #define PidTagSubfolders_Error PROP_TAG(PT_ERROR , 0x360A) /* 0x360A000A */ #define PidTagSubject PROP_TAG(PT_UNICODE , 0x0037) /* 0x0037001F */ #define PidTagSubjectPrefix PROP_TAG(PT_UNICODE , 0x003D) /* 0x003D001F */ #define PidTagSubjectPrefix_Error PROP_TAG(PT_ERROR , 0x003D) /* 0x003D000A */ #define PidTagSubject_Error PROP_TAG(PT_ERROR , 0x0037) /* 0x0037000A */ #define PidTagSurname PROP_TAG(PT_UNICODE , 0x3A11) /* 0x3A11001F */ #define PidTagSurname_Error PROP_TAG(PT_ERROR , 0x3A11) /* 0x3A11000A */ #define PidTagSwappedToDoData PROP_TAG(PT_BINARY , 0x0E2D) /* 0x0E2D0102 */ #define PidTagSwappedToDoData_Error PROP_TAG(PT_ERROR , 0x0E2D) /* 0x0E2D000A */ #define PidTagSwappedToDoStore PROP_TAG(PT_BINARY , 0x0E2C) /* 0x0E2C0102 */ #define PidTagSwappedToDoStore_Error PROP_TAG(PT_ERROR , 0x0E2C) /* 0x0E2C000A */ #define PidTagTargetEntryId PROP_TAG(PT_BINARY , 0x3010) /* 0x30100102 */ #define PidTagTargetEntryId_Error PROP_TAG(PT_ERROR , 0x3010) /* 0x3010000A */ #define PidTagTcvConstLongOne PROP_TAG(PT_LONG , 0x8008) /* 0x80080003 */ #define PidTagTcvConstLongOne_Error PROP_TAG(PT_ERROR , 0x8008) /* 0x8008000A */ #define PidTagTelecommunicationsDeviceForDeafTelephoneNumber PROP_TAG(PT_UNICODE , 0x3A4B) /* 0x3A4B001F */ #define PidTagTelecommunicationsDeviceForDeafTelephoneNumber_Error PROP_TAG(PT_ERROR , 0x3A4B) /* 0x3A4B000A */ #define PidTagTelexNumber PROP_TAG(PT_UNICODE , 0x3A2C) /* 0x3A2C001F */ #define PidTagTelexNumber_Error PROP_TAG(PT_ERROR , 0x3A2C) /* 0x3A2C000A */ #define PidTagTemplateData PROP_TAG(PT_BINARY , 0x0001) /* 0x00010102 */ #define PidTagTemplateData_Error PROP_TAG(PT_ERROR , 0x0001) /* 0x0001000A */ #define PidTagTemplateid PROP_TAG(PT_BINARY , 0x3902) /* 0x39020102 */ #define PidTagTemplateid_Error PROP_TAG(PT_ERROR , 0x3902) /* 0x3902000A */ #define PidTagTemporaryDefaultDocument PROP_TAG(PT_UNICODE , 0x3F20) /* 0x3F20001F */ #define PidTagTemporaryDefaultDocument_Error PROP_TAG(PT_ERROR , 0x3F20) /* 0x3F20000A */ #define PidTagTextAttachmentCharset PROP_TAG(PT_UNICODE , 0x371B) /* 0x371B001F */ #define PidTagTextAttachmentCharset_Error PROP_TAG(PT_ERROR , 0x371B) /* 0x371B000A */ #define PidTagThumbnailPhoto PROP_TAG(PT_BINARY , 0x8C9E) /* 0x8C9E0102 */ #define PidTagThumbnailPhoto_Error PROP_TAG(PT_ERROR , 0x8C9E) /* 0x8C9E000A */ #define PidTagTitle PROP_TAG(PT_UNICODE , 0x3A17) /* 0x3A17001F */ #define PidTagTitle_Error PROP_TAG(PT_ERROR , 0x3A17) /* 0x3A17000A */ #define PidTagTnefCorrelationKey PROP_TAG(PT_BINARY , 0x007F) /* 0x007F0102 */ #define PidTagTnefCorrelationKey_Error PROP_TAG(PT_ERROR , 0x007F) /* 0x007F000A */ #define PidTagToDoItemFlags PROP_TAG(PT_LONG , 0x0E2B) /* 0x0E2B0003 */ #define PidTagToDoItemFlags_Error PROP_TAG(PT_ERROR , 0x0E2B) /* 0x0E2B000A */ #define PidTagTransmittableDisplayName PROP_TAG(PT_UNICODE , 0x3A20) /* 0x3A20001F */ #define PidTagTransmittableDisplayName_Error PROP_TAG(PT_ERROR , 0x3A20) /* 0x3A20000A */ #define PidTagTransportMessageHeaders PROP_TAG(PT_UNICODE , 0x007D) /* 0x007D001F */ #define PidTagTransportMessageHeaders_Error PROP_TAG(PT_ERROR , 0x007D) /* 0x007D000A */ #define PidTagTrustSender PROP_TAG(PT_LONG , 0x0E79) /* 0x0E790003 */ #define PidTagTrustSender_Error PROP_TAG(PT_ERROR , 0x0E79) /* 0x0E79000A */ #define PidTagTtyTddPhoneNumber PROP_TAG(PT_UNICODE , 0x3A4B) /* 0x3A4B001F */ #define PidTagTtyTddPhoneNumber_Error PROP_TAG(PT_ERROR , 0x3A4B) /* 0x3A4B000A */ #define PidTagUrlCompName PROP_TAG(PT_UNICODE , 0x10F3) /* 0x10F3001F */ #define PidTagUrlCompNameSet PROP_TAG(PT_BOOLEAN , 0x0E62) /* 0x0E62000B */ #define PidTagUrlCompNameSet_Error PROP_TAG(PT_ERROR , 0x0E62) /* 0x0E62000A */ #define PidTagUrlCompName_Error PROP_TAG(PT_ERROR , 0x10F3) /* 0x10F3000A */ #define PidTagUrlName PROP_TAG(PT_UNICODE , 0x6707) /* 0x6707001F */ #define PidTagUrlName_Error PROP_TAG(PT_ERROR , 0x6707) /* 0x6707000A */ #define PidTagUserCertificate PROP_TAG(PT_BINARY , 0x3A22) /* 0x3A220102 */ #define PidTagUserCertificate_Error PROP_TAG(PT_ERROR , 0x3A22) /* 0x3A22000A */ #define PidTagUserEntryId PROP_TAG(PT_BINARY , 0x6619) /* 0x66190102 */ #define PidTagUserEntryId_Error PROP_TAG(PT_ERROR , 0x6619) /* 0x6619000A */ #define PidTagUserX509Certificate PROP_TAG(PT_MV_BINARY , 0x3A70) /* 0x3A701102 */ #define PidTagUserX509Certificate_Error PROP_TAG(PT_ERROR , 0x3A70) /* 0x3A70000A */ #define PidTagViewDescriptorBinary PROP_TAG(PT_BINARY , 0x7001) /* 0x70010102 */ #define PidTagViewDescriptorBinary_Error PROP_TAG(PT_ERROR , 0x7001) /* 0x7001000A */ #define PidTagViewDescriptorName PROP_TAG(PT_UNICODE , 0x7006) /* 0x7006001F */ #define PidTagViewDescriptorName_Error PROP_TAG(PT_ERROR , 0x7006) /* 0x7006000A */ #define PidTagViewDescriptorStrings PROP_TAG(PT_UNICODE , 0x7002) /* 0x7002001F */ #define PidTagViewDescriptorStrings_Error PROP_TAG(PT_ERROR , 0x7002) /* 0x7002000A */ #define PidTagViewDescriptorVersion PROP_TAG(PT_LONG , 0x7007) /* 0x70070003 */ #define PidTagViewDescriptorVersion_Error PROP_TAG(PT_ERROR , 0x7007) /* 0x7007000A */ #define PidTagVoiceMessageAttachmentOrder PROP_TAG(PT_UNICODE , 0x6805) /* 0x6805001F */ #define PidTagVoiceMessageAttachmentOrder_Error PROP_TAG(PT_ERROR , 0x6805) /* 0x6805000A */ #define PidTagVoiceMessageDuration PROP_TAG(PT_LONG , 0x6801) /* 0x68010003 */ #define PidTagVoiceMessageDuration_Error PROP_TAG(PT_ERROR , 0x6801) /* 0x6801000A */ #define PidTagVoiceMessageSenderName PROP_TAG(PT_UNICODE , 0x6803) /* 0x6803001F */ #define PidTagVoiceMessageSenderName_Error PROP_TAG(PT_ERROR , 0x6803) /* 0x6803000A */ #define PidTagWeddingAnniversary PROP_TAG(PT_SYSTIME , 0x3A41) /* 0x3A410040 */ #define PidTagWeddingAnniversary_Error PROP_TAG(PT_ERROR , 0x3A41) /* 0x3A41000A */ #define PidTagWlinkAddressBookEID PROP_TAG(PT_BINARY , 0x6854) /* 0x68540102 */ #define PidTagWlinkAddressBookEID_Error PROP_TAG(PT_ERROR , 0x6854) /* 0x6854000A */ #define PidTagWlinkAddressBookStoreEID PROP_TAG(PT_BINARY , 0x6891) /* 0x68910102 */ #define PidTagWlinkAddressBookStoreEID_Error PROP_TAG(PT_ERROR , 0x6891) /* 0x6891000A */ #define PidTagWlinkCalendarColor PROP_TAG(PT_LONG , 0x6853) /* 0x68530003 */ #define PidTagWlinkCalendarColor_Error PROP_TAG(PT_ERROR , 0x6853) /* 0x6853000A */ #define PidTagWlinkClientID PROP_TAG(PT_CLSID , 0x6890) /* 0x68900048 */ #define PidTagWlinkClientID_Error PROP_TAG(PT_ERROR , 0x6890) /* 0x6890000A */ #define PidTagWlinkEntryId PROP_TAG(PT_BINARY , 0x684C) /* 0x684C0102 */ #define PidTagWlinkEntryId_Error PROP_TAG(PT_ERROR , 0x684C) /* 0x684C000A */ #define PidTagWlinkFlags PROP_TAG(PT_LONG , 0x684A) /* 0x684A0003 */ #define PidTagWlinkFlags_Error PROP_TAG(PT_ERROR , 0x684A) /* 0x684A000A */ #define PidTagWlinkFolderType PROP_TAG(PT_CLSID , 0x684F) /* 0x684F0048 */ #define PidTagWlinkFolderType_Error PROP_TAG(PT_ERROR , 0x684F) /* 0x684F000A */ #define PidTagWlinkGroupClsid PROP_TAG(PT_CLSID , 0x6850) /* 0x68500048 */ #define PidTagWlinkGroupClsid_Error PROP_TAG(PT_ERROR , 0x6850) /* 0x6850000A */ #define PidTagWlinkGroupHeaderID PROP_TAG(PT_CLSID , 0x6842) /* 0x68420048 */ #define PidTagWlinkGroupHeaderID_Error PROP_TAG(PT_ERROR , 0x6842) /* 0x6842000A */ #define PidTagWlinkGroupName PROP_TAG(PT_UNICODE , 0x6851) /* 0x6851001F */ #define PidTagWlinkGroupName_Error PROP_TAG(PT_ERROR , 0x6851) /* 0x6851000A */ #define PidTagWlinkOrdinal PROP_TAG(PT_BINARY , 0x684B) /* 0x684B0102 */ #define PidTagWlinkOrdinal_Error PROP_TAG(PT_ERROR , 0x684B) /* 0x684B000A */ #define PidTagWlinkROGroupType PROP_TAG(PT_LONG , 0x6892) /* 0x68920003 */ #define PidTagWlinkROGroupType_Error PROP_TAG(PT_ERROR , 0x6892) /* 0x6892000A */ #define PidTagWlinkRecordKey PROP_TAG(PT_BINARY , 0x684D) /* 0x684D0102 */ #define PidTagWlinkRecordKey_Error PROP_TAG(PT_ERROR , 0x684D) /* 0x684D000A */ #define PidTagWlinkSaveStamp PROP_TAG(PT_LONG , 0x6847) /* 0x68470003 */ #define PidTagWlinkSaveStamp_Error PROP_TAG(PT_ERROR , 0x6847) /* 0x6847000A */ #define PidTagWlinkSection PROP_TAG(PT_LONG , 0x6852) /* 0x68520003 */ #define PidTagWlinkSection_Error PROP_TAG(PT_ERROR , 0x6852) /* 0x6852000A */ #define PidTagWlinkStoreEntryId PROP_TAG(PT_BINARY , 0x684E) /* 0x684E0102 */ #define PidTagWlinkStoreEntryId_Error PROP_TAG(PT_ERROR , 0x684E) /* 0x684E000A */ #define PidTagWlinkType PROP_TAG(PT_LONG , 0x6849) /* 0x68490003 */ #define PidTagWlinkType_Error PROP_TAG(PT_ERROR , 0x6849) /* 0x6849000A */ openchange-2.0/libmapi/simple_mapi.c000066400000000000000000000731161223057412600175540ustar00rootroot00000000000000/* OpenChange MAPI implementation. Copyright (C) Julien Kerihuel 2007-2011. This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see . */ #include "libmapi/libmapi.h" #include "libmapi/libmapi_private.h" /** \file simple_mapi.c \brief Convenience functions. */ /** \details Retrieve the folder id for the specified default folder in a public folder store \param obj_store the store to search \param id the type of folder to search for \param folder the resulting folder reference The following types of folders are supported: - olFolderPublicRoot - the parent (directly or indirectly) for the folders below - olFolderPublicIPMSubtree - Interpersonal Messages (IPM) folders - olFolderPublicNonIPMSubtree - Non-interpersonal message folders - olFolderPublicEFormsRoot - EForms Registry Root Folder - olFolderPublicFreeBusyRoot - Free/busy root folder - olFolderPublicOfflineAB - Offline address book root folder - olFolderPublicEFormsRegistry - EForms Registry for the users locale - olFolderPublicLocalFreeBusy - Site local free/busy folders - olFolderPublicLocalOfflineAB - Site local Offline address book - olFolderPublicNNTPArticle - NNTP article index folder \return MAPI_E_SUCCESS on success, otherwise a failure code (MAPISTATUS) indicating the error. \note Developers may also call GetLastError() to retrieve the last MAPI error code. Possible MAPI error codes are: - MAPI_E_NOT_INITIALIZED: MAPI subsystem has not been initialized. - MAPI_E_INVALID_PARAMETER: obj_store is undefined - MAPI_E_NOT_FOUND: The specified folder could not be found or is not yet supported. \sa MAPIInitialize, OpenPublicFolder, GetLastError */ _PUBLIC_ enum MAPISTATUS GetDefaultPublicFolder(mapi_object_t *obj_store, uint64_t *folder, const uint32_t id) { OPENCHANGE_RETVAL_IF(!obj_store, MAPI_E_INVALID_PARAMETER, NULL); switch (id) { case olFolderPublicRoot: *folder = ((mapi_object_store_t *)obj_store->private_data)->fid_pf_public_root; break; case olFolderPublicIPMSubtree: *folder = ((mapi_object_store_t *)obj_store->private_data)->fid_pf_ipm_subtree; break; case olFolderPublicNonIPMSubtree: *folder = ((mapi_object_store_t *)obj_store->private_data)->fid_pf_non_ipm_subtree; break; case olFolderPublicEFormsRoot: *folder = ((mapi_object_store_t *)obj_store->private_data)->fid_pf_EFormsRegistryRoot; break; case olFolderPublicFreeBusyRoot: *folder = ((mapi_object_store_t *)obj_store->private_data)->fid_pf_FreeBusyRoot; break; case olFolderPublicOfflineAB: *folder = ((mapi_object_store_t *)obj_store->private_data)->fid_pf_OfflineAB; break; case olFolderPublicEFormsRegistry: *folder = ((mapi_object_store_t *)obj_store->private_data)->fid_pf_EFormsRegistry; break; case olFolderPublicLocalFreeBusy: *folder = ((mapi_object_store_t *)obj_store->private_data)->fid_pf_LocalSiteFreeBusy; break; case olFolderPublicLocalOfflineAB: *folder = ((mapi_object_store_t *)obj_store->private_data)->fid_pf_LocalSiteOfflineAB; break; case olFolderPublicNNTPArticle: *folder = ((mapi_object_store_t *)obj_store->private_data)->fid_pf_NNTPArticle; break; default: OPENCHANGE_RETVAL_ERR(MAPI_E_NOT_FOUND, NULL); } return MAPI_E_SUCCESS; } static enum MAPISTATUS CacheDefaultFolders(mapi_object_t *obj_store) { enum MAPISTATUS retval; TALLOC_CTX *mem_ctx; mapi_object_store_t *store; mapi_object_t obj_inbox; mapi_id_t id_inbox; struct SPropTagArray *SPropTagArray = NULL; struct SRow aRow; struct SPropValue *lpProps; uint32_t count; const struct Binary_r *entryid; /* Sanity checks */ OPENCHANGE_RETVAL_IF(!obj_store, MAPI_E_INVALID_PARAMETER, NULL); store = (mapi_object_store_t *)obj_store->private_data; OPENCHANGE_RETVAL_IF(!store, MAPI_E_NOT_INITIALIZED, NULL); mem_ctx = talloc_named(mapi_object_get_session(obj_store), 0, "CacheDefaultFolders"); mapi_object_init(&obj_inbox); retval = GetReceiveFolder(obj_store, &id_inbox, NULL); OPENCHANGE_RETVAL_IF(retval, retval, mem_ctx); retval = OpenFolder(obj_store, id_inbox, &obj_inbox); OPENCHANGE_RETVAL_IF(retval, retval, mem_ctx); SPropTagArray = set_SPropTagArray(mem_ctx, 0x6, PR_IPM_APPOINTMENT_ENTRYID, PR_IPM_CONTACT_ENTRYID, PR_IPM_JOURNAL_ENTRYID, PR_IPM_NOTE_ENTRYID, PR_IPM_TASK_ENTRYID, PR_IPM_DRAFTS_ENTRYID); retval = GetProps(&obj_inbox, 0, SPropTagArray, &lpProps, &count); MAPIFreeBuffer(SPropTagArray); OPENCHANGE_RETVAL_IF(retval, retval, mem_ctx); aRow.cValues = count; aRow.lpProps = lpProps; /* set cached calendar FID */ entryid = (const struct Binary_r *)find_SPropValue_data(&aRow, PR_IPM_APPOINTMENT_ENTRYID); OPENCHANGE_RETVAL_IF(!entryid, MAPI_E_NOT_FOUND, mem_ctx); retval = GetFIDFromEntryID(entryid->cb, entryid->lpb, id_inbox, &store->fid_calendar); OPENCHANGE_RETVAL_IF(retval, retval, mem_ctx); /* set cached contact FID */ entryid = (const struct Binary_r *)find_SPropValue_data(&aRow, PR_IPM_CONTACT_ENTRYID); OPENCHANGE_RETVAL_IF(!entryid, MAPI_E_NOT_FOUND, mem_ctx); retval = GetFIDFromEntryID(entryid->cb, entryid->lpb, id_inbox, &store->fid_contact); OPENCHANGE_RETVAL_IF(retval, retval, mem_ctx); /* set cached journal FID */ entryid = (const struct Binary_r *)find_SPropValue_data(&aRow, PR_IPM_JOURNAL_ENTRYID); OPENCHANGE_RETVAL_IF(!entryid, MAPI_E_NOT_FOUND, mem_ctx); retval = GetFIDFromEntryID(entryid->cb, entryid->lpb, id_inbox, &store->fid_journal); OPENCHANGE_RETVAL_IF(retval, retval, mem_ctx); /* set cached note FID */ entryid = (const struct Binary_r *)find_SPropValue_data(&aRow, PR_IPM_NOTE_ENTRYID); OPENCHANGE_RETVAL_IF(!entryid, MAPI_E_NOT_FOUND, mem_ctx); retval = GetFIDFromEntryID(entryid->cb, entryid->lpb, id_inbox, &store->fid_note); OPENCHANGE_RETVAL_IF(retval, retval, mem_ctx); /* set cached task FID */ entryid = (const struct Binary_r *)find_SPropValue_data(&aRow, PR_IPM_TASK_ENTRYID); OPENCHANGE_RETVAL_IF(!entryid, MAPI_E_NOT_FOUND, mem_ctx); retval = GetFIDFromEntryID(entryid->cb, entryid->lpb, id_inbox, &store->fid_task); OPENCHANGE_RETVAL_IF(retval, retval, mem_ctx); /* set cached drafts FID */ entryid = (const struct Binary_r *)find_SPropValue_data(&aRow, PR_IPM_DRAFTS_ENTRYID); OPENCHANGE_RETVAL_IF(!entryid, MAPI_E_NOT_FOUND, mem_ctx); retval = GetFIDFromEntryID(entryid->cb, entryid->lpb, id_inbox, &store->fid_drafts); OPENCHANGE_RETVAL_IF(retval, retval, mem_ctx); store->store_type = PrivateFolderWithCachedFids; mapi_object_release(&obj_inbox); talloc_free(mem_ctx); return MAPI_E_SUCCESS; } /** \details Retrieves the folder id for the specified default folder in a mailbox store \param obj_store the store to search \param id the type of folder to search for \param folder the resulting folder reference The following types of folders are supported: - olFolderTopInformationStore - olFolderDeletedItems - olFolderOutbox - olFolderSentMail - olFolderInbox - olFolderCommonView - olFolderCalendar - olFolderContacts - olFolderJournal - olFolderNotes - olFolderTasks - olFolderDrafts - olFolderReminders - olFolderFinder Note that this function will cache FID values for common accessed folders such as calendar, contact, journal, note, task and drafts until the store object got released. \return MAPI_E_SUCCESS on success, otherwise a failure code (MAPISTATUS) indicating the error. \note Developers may also call GetLastError() to retrieve the last MAPI error code. Possible MAPI error codes are: - MAPI_E_NOT_INITIALIZED: MAPI subsystem has not been initialized. - MAPI_E_INVALID_PARAMETER: obj_store is undefined - MAPI_E_NOT_FOUND: The specified folder could not be found or is not yet supported. \sa MAPIInitialize, OpenMsgStore, GetLastError */ _PUBLIC_ enum MAPISTATUS GetDefaultFolder(mapi_object_t *obj_store, uint64_t *folder, const uint32_t id) { enum MAPISTATUS retval; mapi_object_store_t *store; /* Sanity checks */ OPENCHANGE_RETVAL_IF(!obj_store, MAPI_E_INVALID_PARAMETER, NULL); OPENCHANGE_RETVAL_IF(!folder, MAPI_E_INVALID_PARAMETER, NULL); store = (mapi_object_store_t *)obj_store->private_data; OPENCHANGE_RETVAL_IF(!store, MAPI_E_NOT_INITIALIZED, NULL); if ((id > 6) && (store->store_type == PrivateFolderWithoutCachedFids)) { retval = CacheDefaultFolders(obj_store); OPENCHANGE_RETVAL_IF(retval, retval, NULL); } switch (id) { case olFolderMailboxRoot: *folder = store->fid_mailbox_root; return MAPI_E_SUCCESS; case olFolderTopInformationStore: *folder = store->fid_top_information_store; return MAPI_E_SUCCESS; case olFolderDeletedItems: *folder = store->fid_deleted_items; return MAPI_E_SUCCESS; case olFolderOutbox: *folder = store->fid_outbox; return MAPI_E_SUCCESS; case olFolderSentMail: *folder = store->fid_sent_items; return MAPI_E_SUCCESS; case olFolderInbox: *folder = store->fid_inbox; return MAPI_E_SUCCESS; case olFolderCommonView: *folder = store->fid_common_views; return MAPI_E_SUCCESS; case olFolderCalendar: *folder = store->fid_calendar; return MAPI_E_SUCCESS; case olFolderContacts: *folder = store->fid_contact; return MAPI_E_SUCCESS; case olFolderJournal: *folder = store->fid_journal; return MAPI_E_SUCCESS; case olFolderNotes: *folder = store->fid_note; return MAPI_E_SUCCESS; case olFolderTasks: *folder = store->fid_task; return MAPI_E_SUCCESS; case olFolderDrafts: *folder = store->fid_drafts; return MAPI_E_SUCCESS; case olFolderFinder: *folder = store->fid_search; return MAPI_E_SUCCESS; default: *folder = 0; OPENCHANGE_RETVAL_ERR(MAPI_E_NOT_FOUND, 0); } } /** \details Check if a given folder identifier matches with a system/default one and optionally returns the olFolder type \param obj_store pointer to the store object \param fid reference to the folder identifier to check \param olFolder pointer to the returned olFolder \return true on success, otherwise false */ _PUBLIC_ bool IsMailboxFolder(mapi_object_t *obj_store, uint64_t fid, uint32_t *olFolder) { enum MAPISTATUS retval; mapi_object_store_t *store; uint32_t olFolderNum = 0; bool ret = true; if (!obj_store) { return false; } store = (mapi_object_store_t *) obj_store->private_data; if (!store) { return false; } if (fid == 0x0) { return false; } if (store->store_type == PrivateFolderWithoutCachedFids) { retval = CacheDefaultFolders(obj_store); if (retval) { return false; } } if(fid == store->fid_top_information_store) { olFolderNum = olFolderTopInformationStore; } else if (fid == store->fid_deleted_items) { olFolderNum = olFolderDeletedItems; } else if (fid == store->fid_outbox) { olFolderNum = olFolderOutbox; } else if (fid == store->fid_sent_items) { olFolderNum = olFolderSentMail; } else if (fid == store->fid_inbox) { olFolderNum = olFolderInbox; } else if (fid == store->fid_common_views) { olFolderNum = olFolderCommonView; } else if (fid == store->fid_calendar) { olFolderNum = olFolderCalendar; } else if (fid == store->fid_contact) { olFolderNum = olFolderContacts; } else if (fid == store->fid_journal) { olFolderNum = olFolderJournal; } else if (fid == store->fid_note) { olFolderNum = olFolderNotes; } else if (fid == store->fid_task) { olFolderNum = olFolderTasks; } else if (fid == store->fid_drafts) { olFolderNum = olFolderDrafts; } else if (fid == store->fid_search) { olFolderNum = olFolderFinder; } else if (fid == store->fid_pf_OfflineAB) { olFolderNum = olFolderPublicOfflineAB; } else if (fid == store->fid_pf_FreeBusyRoot) { olFolderNum = olFolderPublicFreeBusyRoot; } else if (fid == store->fid_pf_EFormsRegistryRoot) { olFolderNum = olFolderPublicEFormsRoot; } else if (fid == store->fid_pf_EFormsRegistry) { olFolderNum = olFolderPublicEFormsRegistry; } else if (fid == store->fid_pf_public_root) { olFolderNum = olFolderPublicRoot; } else if (fid == store->fid_pf_ipm_subtree) { olFolderNum = olFolderPublicIPMSubtree; } else if (fid == store->fid_pf_non_ipm_subtree) { olFolderNum = olFolderPublicNonIPMSubtree; } else if (fid == store->fid_pf_LocalSiteFreeBusy) { olFolderNum = olFolderPublicLocalFreeBusy; } else if (fid == store->fid_pf_LocalSiteOfflineAB) { olFolderNum = olFolderPublicLocalOfflineAB; } else if (fid == store->fid_pf_NNTPArticle) { olFolderNum = olFolderPublicNNTPArticle; } else { olFolderNum = 0xFFFFFFFF; ret = false; } if (olFolder) *olFolder = olFolderNum; return ret; } /** \details Retrieves the total and unread number of items for a specified folder. \param obj_folder the folder to get item counts for \param unread the number of items in the folder (result) \param total the number of items in the folder, including unread items (result) \return MAPI_E_SUCCESS on success, otherwise a failure code (MAPISTATUS) indicating the error. \note Developers may also call GetLastError() to retrieve the last MAPI error code. Possible MAPI error codes are: - MAPI_E_NOT_INITIALIZED: MAPI subsystem has not been initialized. - MAPI_E_INVALID_PARAMETER: obj_folder is undefined - MAPI_E_NOT_FOUND: The specified folder could not be found or is not yet supported. \sa MAPIInitialize, OpenFolder, GetLastError */ _PUBLIC_ enum MAPISTATUS GetFolderItemsCount(mapi_object_t *obj_folder, uint32_t *unread, uint32_t *total) { enum MAPISTATUS retval; TALLOC_CTX *mem_ctx; struct SPropTagArray *SPropTagArray; struct SPropValue *lpProps; uint32_t count; OPENCHANGE_RETVAL_IF(!obj_folder, MAPI_E_INVALID_PARAMETER, NULL); OPENCHANGE_RETVAL_IF(!unread, MAPI_E_INVALID_PARAMETER, NULL); OPENCHANGE_RETVAL_IF(!total, MAPI_E_INVALID_PARAMETER, NULL); mem_ctx = talloc_named(mapi_object_get_session(obj_folder), 0, "GetFolderItemsCount"); SPropTagArray = set_SPropTagArray(mem_ctx, 0x2, PR_CONTENT_UNREAD, PR_CONTENT_COUNT); retval = GetProps(obj_folder, 0, SPropTagArray, &lpProps, &count); MAPIFreeBuffer(SPropTagArray); OPENCHANGE_RETVAL_IF(retval, retval, mem_ctx); *unread = lpProps[0].value.l; *total = lpProps[1].value.l; talloc_free(mem_ctx); return MAPI_E_SUCCESS; } /** \details Adds permissions for a user on a given folder \param obj_folder the folder we add permission for \param username the Exchange username we add permissions for \param role the permission mask value The following permissions and rights are supported: - RightsNone - RightsReadItems - RightsCreateItems - RightsEditOwn - RightsDeleteOwn - RightsEditAll - RightsDeleteAll - RightsCreateSubfolders - RightsFolderOwner - RightsFolderContact - RoleNone - RoleReviewer - RoleContributor - RoleNoneditingAuthor - RoleAuthor - RoleEditor - RolePublishAuthor - RolePublishEditor - RightsAll - RoleOwner \return MAPI_E_SUCCESS on success, otherwise a failure code (MAPISTATUS) indicating the error. \note Developers may also call GetLastError() to retrieve the last MAPI error code. Possible MAPI error codes are: - MAPI_E_NOT_INITIALIZED: MAPI subsystem has not been initialized. - MAPI_E_INVALID_PARAMETER: username is NULL \sa ResolveNames, ModifyPermissions */ _PUBLIC_ enum MAPISTATUS AddUserPermission(mapi_object_t *obj_folder, const char *username, enum ACLRIGHTS role) { enum MAPISTATUS retval; TALLOC_CTX *mem_ctx; struct SPropTagArray *SPropTagArray; const char *names[2]; struct PropertyRowSet_r *rows = NULL; struct PropertyTagArray_r *flaglist = NULL; struct mapi_PermissionsData rowList; /* Sanity checks */ OPENCHANGE_RETVAL_IF(!obj_folder, MAPI_E_INVALID_PARAMETER, NULL); OPENCHANGE_RETVAL_IF(!username, MAPI_E_INVALID_PARAMETER, NULL); rowList.ModifyFlags = 0; mem_ctx = talloc_named(mapi_object_get_session(obj_folder), 0, "AddUserPermission"); /* query Address book */ SPropTagArray = set_SPropTagArray(mem_ctx, 2, PR_ENTRYID, PR_DISPLAY_NAME); names[0] = username; names[1] = NULL; retval = ResolveNames(mapi_object_get_session(obj_folder), (const char **)names, SPropTagArray, &rows, &flaglist, 0); MAPIFreeBuffer(SPropTagArray); OPENCHANGE_RETVAL_IF(retval, retval, mem_ctx); /* Sanity checks */ OPENCHANGE_RETVAL_IF(!flaglist, MAPI_E_NOT_FOUND, mem_ctx); OPENCHANGE_RETVAL_IF(!rows, MAPI_E_NOT_FOUND, mem_ctx); /* Check if the username was found */ OPENCHANGE_RETVAL_IF((flaglist->aulPropTag[0] != MAPI_RESOLVED), MAPI_E_NOT_FOUND, mem_ctx); rowList.ModifyCount = 1; rowList.PermissionsData = talloc_array(mem_ctx, struct PermissionData, 1); rowList.PermissionsData[0].PermissionDataFlags = ROW_ADD; rowList.PermissionsData[0].lpProps.cValues = 2; rowList.PermissionsData[0].lpProps.lpProps = talloc_array(mem_ctx, struct mapi_SPropValue, 2); set_mapi_SPropValue(NULL, &rowList.PermissionsData[0].lpProps.lpProps[0], get_PropertyValue_data(&rows->aRow[0].lpProps[0])); rowList.PermissionsData[0].lpProps.lpProps[1].ulPropTag = PR_MEMBER_RIGHTS; rowList.PermissionsData[0].lpProps.lpProps[1].value.l = role; retval = ModifyPermissions(obj_folder, 0, &rowList); OPENCHANGE_RETVAL_IF(retval, retval, mem_ctx); talloc_free(mem_ctx); return MAPI_E_SUCCESS; } /** \details Modify permissions for a user on a given folder \param obj_folder the folder to modify permissions for \param username the Exchange username to modify permissions for \param role the permission mask value (see AddUserPermission) \return MAPI_E_SUCCESS on success, otherwise a failure code (MAPISTATUS) indicating the error. \note Developers may also call GetLastError() to retrieve the last MAPI error code. Possible MAPI error codes are: - MAPI_E_NOT_INITIALIZED: MAPI subsystem has not been initialized. - MAPI_E_INVALID_PARAMETER: username is NULL - MAPI_E_NOT_FOUND: couldn't find or change permissions for the given user \sa AddUserPermission, ResolveNames, GetPermissionsTable, ModifyPermissions */ _PUBLIC_ enum MAPISTATUS ModifyUserPermission(mapi_object_t *obj_folder, const char *username, enum ACLRIGHTS role) { enum MAPISTATUS retval; TALLOC_CTX *mem_ctx; struct SPropTagArray *SPropTagArray; const char *names[2]; const char *user = NULL; struct PropertyRowSet_r *rows = NULL; struct SRowSet rowset; struct PropertyTagArray_r *flaglist = NULL; struct mapi_PermissionsData rowList; struct SPropValue *lpProp; mapi_object_t obj_table; uint32_t Numerator; uint32_t Denominator; bool found = false; uint32_t i = 0; OPENCHANGE_RETVAL_IF(!obj_folder, MAPI_E_INVALID_PARAMETER, NULL); OPENCHANGE_RETVAL_IF(!username, MAPI_E_INVALID_PARAMETER, NULL); rowList.ModifyFlags = 0; mem_ctx = talloc_named(mapi_object_get_session(obj_folder), 0, "ModifyUserPermission"); SPropTagArray = set_SPropTagArray(mem_ctx, 2, PR_ENTRYID, PR_DISPLAY_NAME); names[0] = username; names[1] = NULL; retval = ResolveNames(mapi_object_get_session(obj_folder), (const char **)names, SPropTagArray, &rows, &flaglist, 0); MAPIFreeBuffer(SPropTagArray); OPENCHANGE_RETVAL_IF(retval, retval, mem_ctx); if (flaglist->aulPropTag[0] == MAPI_RESOLVED) { user = (const char *) find_PropertyValue_data(&(rows->aRow[0]), PR_DISPLAY_NAME); } else { /* Special case: Not a AD user account but Default or * Anonymous. Since names are language specific, we * can't use strcmp */ user = username; } mapi_object_init(&obj_table); retval = GetPermissionsTable(obj_folder, 0x00, &obj_table); OPENCHANGE_RETVAL_IF(retval, retval, mem_ctx); SPropTagArray = set_SPropTagArray(mem_ctx, 4, PR_ENTRYID, PR_MEMBER_RIGHTS, PR_MEMBER_ID, PR_MEMBER_NAME); retval = SetColumns(&obj_table, SPropTagArray); MAPIFreeBuffer(SPropTagArray); OPENCHANGE_RETVAL_IF(retval, retval, mem_ctx); retval = QueryPosition(&obj_table, &Numerator, &Denominator); OPENCHANGE_RETVAL_IF(retval, retval, mem_ctx); retval = QueryRows(&obj_table, Denominator, TBL_ADVANCE, &rowset); OPENCHANGE_RETVAL_IF(retval, retval, mem_ctx); for (i = 0; i < rowset.cRows; i++) { lpProp = get_SPropValue_SRow(&rowset.aRow[i], PR_MEMBER_NAME); if (lpProp && lpProp->value.lpszA) { if (!strcmp(lpProp->value.lpszA, user)) { rowList.ModifyCount = 1; rowList.PermissionsData = talloc_array(mem_ctx, struct PermissionData, 1); rowList.PermissionsData[0].PermissionDataFlags = ROW_MODIFY; rowList.PermissionsData[0].lpProps.cValues = 2; rowList.PermissionsData[0].lpProps.lpProps = talloc_array(mem_ctx, struct mapi_SPropValue, 2); lpProp = get_SPropValue_SRow(&(rowset.aRow[i]), PR_MEMBER_ID); if (!lpProp) { continue; } rowList.PermissionsData[0].lpProps.lpProps[0].ulPropTag = PR_MEMBER_ID; rowList.PermissionsData[0].lpProps.lpProps[0].value.d = lpProp->value.d; rowList.PermissionsData[0].lpProps.lpProps[1].ulPropTag = PR_MEMBER_RIGHTS; rowList.PermissionsData[0].lpProps.lpProps[1].value.l = role; retval = ModifyPermissions(obj_folder, 0, &rowList); OPENCHANGE_RETVAL_IF(retval, retval, mem_ctx); found = true; break; } } } mapi_object_release(&obj_table); talloc_free(mem_ctx); OPENCHANGE_RETVAL_IF((!found), MAPI_E_NOT_FOUND, 0); return MAPI_E_SUCCESS; } /** \details Remove permissions for a user on a given folder \param obj_folder the folder to remove permission from \param username the Exchange username to remove permissions for \return MAPI_E_SUCCESS on success, otherwise a failure code (MAPISTATUS) indicating the error. \note Developers may also call GetLastError() to retrieve the last MAPI error code. Possible MAPI error codes are: - MAPI_E_NOT_INITIALIZED: MAPI subsystem has not been initialized. - MAPI_E_INVALID_PARAMETER: username or obj_folder are NULL - MAPI_E_NOT_FOUND: couldn't find or remove permissions for the given user \sa ResolveNames, GetPermissionsTable, ModifyPermissions */ _PUBLIC_ enum MAPISTATUS RemoveUserPermission(mapi_object_t *obj_folder, const char *username) { enum MAPISTATUS retval; TALLOC_CTX *mem_ctx; struct SPropTagArray *SPropTagArray; const char *names[2]; const char *user = NULL; struct PropertyRowSet_r *rows = NULL; struct SRowSet rowset; struct PropertyTagArray_r *flaglist = NULL; struct mapi_PermissionsData rowList; struct SPropValue *lpProp; mapi_object_t obj_table; uint32_t Numerator; uint32_t Denominator; bool found = false; uint32_t i = 0; OPENCHANGE_RETVAL_IF(!obj_folder, MAPI_E_INVALID_PARAMETER, NULL); OPENCHANGE_RETVAL_IF(!username, MAPI_E_INVALID_PARAMETER, NULL); mem_ctx = talloc_named(mapi_object_get_session(obj_folder), 0, "RemoveUserPermission"); SPropTagArray = set_SPropTagArray(mem_ctx, 2, PR_ENTRYID, PR_DISPLAY_NAME); names[0] = username; names[1] = NULL; retval = ResolveNames(mapi_object_get_session(obj_folder), (const char **)names, SPropTagArray, &rows, &flaglist, 0); MAPIFreeBuffer(SPropTagArray); OPENCHANGE_RETVAL_IF(retval, retval, mem_ctx); /* Check if the username was found */ OPENCHANGE_RETVAL_IF((flaglist->aulPropTag[0] != MAPI_RESOLVED), MAPI_E_NOT_FOUND, mem_ctx); user = (const char *)find_PropertyValue_data(&(rows->aRow[0]), PR_DISPLAY_NAME); mapi_object_init(&obj_table); retval = GetPermissionsTable(obj_folder, 0x00, &obj_table); OPENCHANGE_RETVAL_IF(retval, retval, mem_ctx); SPropTagArray = set_SPropTagArray(mem_ctx, 4, PR_ENTRYID, PR_MEMBER_RIGHTS, PR_MEMBER_ID, PR_MEMBER_NAME); retval = SetColumns(&obj_table, SPropTagArray); MAPIFreeBuffer(SPropTagArray); OPENCHANGE_RETVAL_IF(retval, retval, mem_ctx); retval = QueryPosition(&obj_table, &Numerator, &Denominator); OPENCHANGE_RETVAL_IF(retval, retval, mem_ctx); retval = QueryRows(&obj_table, Denominator, TBL_ADVANCE, &rowset); OPENCHANGE_RETVAL_IF(retval, retval, mem_ctx); for (i = 0; i < rowset.cRows; i++) { lpProp = get_SPropValue_SRow(&rowset.aRow[i], PR_MEMBER_NAME); if (lpProp && lpProp->value.lpszA) { if (!strcmp(lpProp->value.lpszA, user)) { rowList.ModifyCount = 1; rowList.PermissionsData = talloc_array(mem_ctx, struct PermissionData, 1); rowList.PermissionsData[0].PermissionDataFlags = ROW_REMOVE; rowList.PermissionsData[0].lpProps.cValues = 1; rowList.PermissionsData[0].lpProps.lpProps = talloc_array(mem_ctx, struct mapi_SPropValue, 1); lpProp = get_SPropValue_SRow(&(rowset.aRow[i]), PR_MEMBER_ID); if (!lpProp) { continue; } rowList.PermissionsData[0].lpProps.lpProps[0].ulPropTag = PR_MEMBER_ID; rowList.PermissionsData[0].lpProps.lpProps[0].value.d = lpProp->value.d; retval = ModifyPermissions(obj_folder, 0, &rowList); OPENCHANGE_RETVAL_IF(retval, retval, mem_ctx); found = true; break; } } } mapi_object_release(&obj_table); talloc_free(mem_ctx); OPENCHANGE_RETVAL_IF((found != true), MAPI_E_NOT_FOUND, 0); return MAPI_E_SUCCESS; } /** \details Implement the BestBody algorithm and return the best body content type for a given message. \param obj_message the message we find the best body for \param format the format - see below. \return MAPI_E_SUCCESS on success, otherwise MAPI_E_NOT_FOUND. If MAPI_E_NOT_FOUND is returned then format is set to 0x0 (undefined). If MAPI_E_SUCCESS is returned, then format can have one of the following values: - olEditorText: format is plain text - olEditorHTML: format is HTML - olEditorRTF: format is RTF */ _PUBLIC_ enum MAPISTATUS GetBestBody(mapi_object_t *obj_message, uint8_t *format) { struct mapi_context *mapi_ctx; struct mapi_session *session; enum MAPISTATUS retval; struct SPropTagArray *SPropTagArray = NULL; struct SPropValue *lpProps; struct SRow aRow; uint32_t count; uint8_t RtfInSync; uint32_t PlainStatus; uint32_t RtfStatus; uint32_t HtmlStatus; const uint32_t *err_code; /* Sanity checks */ OPENCHANGE_RETVAL_IF(!obj_message, MAPI_E_INVALID_PARAMETER, NULL); OPENCHANGE_RETVAL_IF(!format, MAPI_E_INVALID_PARAMETER, NULL); session = mapi_object_get_session(obj_message); mapi_ctx = session->mapi_ctx; /* Step 1. Retrieve properties needed by the BestBody algorithm */ SPropTagArray = set_SPropTagArray(mapi_ctx->mem_ctx, 0x4, PR_BODY_UNICODE, PR_RTF_COMPRESSED, PR_HTML, PR_RTF_IN_SYNC); retval = GetProps(obj_message, 0, SPropTagArray, &lpProps, &count); MAPIFreeBuffer(SPropTagArray); if (retval != MAPI_E_SUCCESS) { *format = 0; OPENCHANGE_RETVAL_ERR(MAPI_E_NOT_FOUND, 0); } aRow.ulAdrEntryPad = 0; aRow.cValues = count; aRow.lpProps = lpProps; /* Step 2. Retrieve properties values and map errors */ err_code = (const uint32_t *)find_SPropValue_data(&aRow, PR_RTF_IN_SYNC); RtfInSync = (err_code) ? *err_code : 0; err_code = (const uint32_t *)find_SPropValue_data(&aRow, PR_BODY_ERROR); PlainStatus = (err_code) ? *err_code : 0; err_code = (const uint32_t *)find_SPropValue_data(&aRow, PR_RTF_COMPRESSED_ERROR); RtfStatus = (err_code) ? *err_code : 0; err_code = (const uint32_t *)find_SPropValue_data(&aRow, PR_BODY_HTML_ERROR); HtmlStatus = (err_code) ? *err_code : 0; /* Step 3. Determine the body format (9 possible cases) */ /* case 1 */ if ((PlainStatus == MAPI_E_NOT_FOUND) && (RtfStatus == MAPI_E_NOT_FOUND) && (HtmlStatus == MAPI_E_NOT_FOUND)) { *format = 0; OPENCHANGE_RETVAL_ERR(MAPI_E_NOT_FOUND, 0); } /* case 2 */ if (((PlainStatus == MAPI_E_NOT_ENOUGH_MEMORY) || (PlainStatus == 0)) && (RtfStatus == MAPI_E_NOT_FOUND) && (HtmlStatus == MAPI_E_NOT_FOUND)) { *format = olEditorText; return MAPI_E_SUCCESS; } /* case 3 */ if ((PlainStatus == MAPI_E_NOT_ENOUGH_MEMORY) && (RtfStatus == MAPI_E_NOT_ENOUGH_MEMORY) && (HtmlStatus == MAPI_E_NOT_FOUND)) { *format = olEditorRTF; return MAPI_E_SUCCESS; } /* case 4 */ if ((PlainStatus == MAPI_E_NOT_ENOUGH_MEMORY) && (RtfStatus == MAPI_E_NOT_ENOUGH_MEMORY) && (HtmlStatus == MAPI_E_NOT_ENOUGH_MEMORY) && (RtfInSync == 1)) { *format = olEditorRTF; return MAPI_E_SUCCESS; } /* case 5 */ if ((PlainStatus == MAPI_E_NOT_ENOUGH_MEMORY) && (RtfStatus == MAPI_E_NOT_ENOUGH_MEMORY) && (HtmlStatus == MAPI_E_NOT_ENOUGH_MEMORY) && (RtfInSync == 0)) { *format = olEditorHTML; return MAPI_E_SUCCESS; } /* case 6 */ if (((RtfStatus == 0) || (RtfStatus == MAPI_E_NOT_ENOUGH_MEMORY)) && ((HtmlStatus == 0) || (HtmlStatus == MAPI_E_NOT_ENOUGH_MEMORY)) && (RtfInSync == 1)) { *format = olEditorRTF; return MAPI_E_SUCCESS; } /* case 7 */ if (((RtfStatus == 0) || (RtfStatus == MAPI_E_NOT_ENOUGH_MEMORY)) && ((HtmlStatus == 0) || (HtmlStatus == MAPI_E_NOT_ENOUGH_MEMORY)) && (RtfInSync == 0)) { *format = olEditorHTML; return MAPI_E_SUCCESS; } /* case 8 */ if (((PlainStatus == 0) || (PlainStatus == MAPI_E_NOT_ENOUGH_MEMORY)) && ((RtfStatus == 0) || (RtfStatus == MAPI_E_NOT_ENOUGH_MEMORY)) && (RtfInSync == 1)) { *format = olEditorRTF; return MAPI_E_SUCCESS; } /* case 9 */ if (((PlainStatus == 0) || (PlainStatus == MAPI_E_NOT_ENOUGH_MEMORY)) && ((RtfStatus == 0) || (RtfStatus == MAPI_E_NOT_ENOUGH_MEMORY)) && (RtfInSync == 0)) { *format = olEditorText; return MAPI_E_SUCCESS; } OPENCHANGE_RETVAL_ERR(MAPI_E_NOT_FOUND, 0); } openchange-2.0/libmapi/socket/000077500000000000000000000000001223057412600163715ustar00rootroot00000000000000openchange-2.0/libmapi/socket/interface.c000066400000000000000000000175611223057412600205070ustar00rootroot00000000000000/* Unix SMB/CIFS implementation. multiple interface handling Copyright (C) Andrew Tridgell 1992-2005 This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see . */ #include "libmapi/libmapi.h" #include "libmapi/libmapi_private.h" #include #define ALLONES ((uint32_t)0xFFFFFFFF) /* address construction based on a patch from fred@datalync.com */ #define MKBCADDR(_IP, _NM) ((_IP & _NM) | (_NM ^ ALLONES)) #define MKNETADDR(_IP, _NM) (_IP & _NM) bool is_zero_ip_v4(struct in_addr ip); bool same_net_v4(struct in_addr ip1, struct in_addr ip2, struct in_addr mask); uint32_t interpret_addr(const char *str); struct in_addr interpret_addr2(const char *str); /**************************************************************************** Try and find an interface that matches an ip. If we cannot, return NULL **************************************************************************/ static struct interface *iface_find(struct interface *interfaces, struct in_addr ip, bool CheckMask) { struct interface *i; if (is_zero_ip_v4(ip)) return interfaces; for (i=interfaces;i;i=i->next) if (CheckMask) { if (same_net_v4(i->ip,ip,i->nmask)) return i; } else if (i->ip.s_addr == ip.s_addr) return i; return NULL; } /**************************************************************************** add an interface to the linked list of interfaces ****************************************************************************/ static void add_interface(TALLOC_CTX *mem_ctx, struct in_addr ip, struct in_addr nmask, struct interface **interfaces) { struct interface *iface; struct in_addr bcast; if (iface_find(*interfaces, ip, false)) { DEBUG(3,("not adding duplicate interface %s\n",inet_ntoa(ip))); return; } iface = talloc(*interfaces == NULL ? mem_ctx : *interfaces, struct interface); if (iface == NULL) return; ZERO_STRUCTPN(iface); iface->ip = ip; iface->nmask = nmask; bcast.s_addr = MKBCADDR(iface->ip.s_addr, iface->nmask.s_addr); /* keep string versions too, to avoid people tripping over the implied static in inet_ntoa() */ iface->ip_s = talloc_strdup(iface, inet_ntoa(iface->ip)); iface->nmask_s = talloc_strdup(iface, inet_ntoa(iface->nmask)); if (nmask.s_addr != ~(in_addr_t)0) { iface->bcast_s = talloc_strdup(iface, inet_ntoa(bcast)); } DLIST_ADD_END(*interfaces, iface, struct interface *); DEBUG(2,("added interface ip=%s nmask=%s\n", iface->ip_s, iface->nmask_s)); } /** interpret a single element from a interfaces= config line This handles the following different forms: 1) wildcard interface name 2) DNS name 3) IP/masklen 4) ip/mask 5) bcast/mask **/ static void interpret_interface(TALLOC_CTX *mem_ctx, const char *token, struct iface_struct *probed_ifaces, int total_probed, struct interface **local_interfaces) { struct in_addr ip, nmask; char *p; char *address; int i, added=0; ip.s_addr = 0; nmask.s_addr = 0; /* first check if it is an interface name */ for (i=0;i 2) { nmask.s_addr = interpret_addr2(p).s_addr; } else { nmask.s_addr = htonl(((ALLONES >> atoi(p)) ^ ALLONES)); } /* maybe the first component was a broadcast address */ if (ip.s_addr == MKBCADDR(ip.s_addr, nmask.s_addr) || ip.s_addr == MKNETADDR(ip.s_addr, nmask.s_addr)) { for (i=0;inext) ret++; return ret; } /** return IP of the Nth interface **/ const char *iface_n_ip(struct interface *ifaces, int n) { struct interface *i; for (i=ifaces;i && n;i=i->next) n--; if (i) { return i->ip_s; } return NULL; } /** return bcast of the Nth interface **/ const char *iface_n_bcast(struct interface *ifaces, int n) { struct interface *i; for (i=ifaces;i && n;i=i->next) n--; if (i) { return i->bcast_s; } return NULL; } /** return netmask of the Nth interface **/ const char *iface_n_netmask(struct interface *ifaces, int n) { struct interface *i; for (i=ifaces;i && n;i=i->next) n--; if (i) { return i->nmask_s; } return NULL; } /** return the local IP address that best matches a destination IP, or our first interface if none match */ const char *iface_best_ip(struct interface *ifaces, const char *dest) { struct interface *iface; struct in_addr ip; ip.s_addr = interpret_addr(dest); iface = iface_find(ifaces, ip, true); if (iface) { return iface->ip_s; } return iface_n_ip(ifaces, 0); } /** return true if an IP is one one of our local networks */ bool iface_is_local(struct interface *ifaces, const char *dest) { struct in_addr ip; ip.s_addr = interpret_addr(dest); if (iface_find(ifaces, ip, true)) { return true; } return false; } /** return true if a IP matches a IP/netmask pair */ bool iface_same_net(const char *ip1, const char *ip2, const char *netmask) { return same_net_v4(interpret_addr2(ip1), interpret_addr2(ip2), interpret_addr2(netmask)); } openchange-2.0/libmapi/socket/netif.c000066400000000000000000000077551223057412600176600ustar00rootroot00000000000000/* Unix SMB/CIFS implementation. return a list of network interfaces Copyright (C) Andrew Tridgell 1998 This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see . */ /* working out the interfaces for a OS is an incredibly non-portable thing. We have several possible implementations below, and autoconf tries each of them to see what works Note that this file does _not_ include includes.h. That is so this code can be called directly from the autoconf tests. That also means this code cannot use any of the normal Samba debug stuff or defines. This is standalone code. */ #include "libmapi/libmapi.h" #include "libmapi/libmapi_private.h" #ifdef HAVE_SYS_SOCKIO_H #include #endif #ifdef __COMPAR_FN_T #define QSORT_CAST (__compar_fn_t) #endif #ifndef QSORT_CAST #define QSORT_CAST (int (*)(const void *, const void *)) #endif /* this works for Linux 2.2, Solaris 2.5, SunOS4, HPUX 10.20, OSF1 V4.0, Ultrix 4.4, SCO Unix 3.2, IRIX 6.4 and FreeBSD 3.2. It probably also works on any BSD style system. */ /**************************************************************************** get the netmask address for a local interface ****************************************************************************/ static int _get_interfaces(struct iface_struct *ifaces, int max_interfaces) { struct ifconf ifc; struct ifreq *ifr=NULL; struct in_addr ipaddr; struct in_addr nmask; struct sockaddr *sockaddr; struct sockaddr_in *sockaddr_in; char *iname; char buff[8192]; int fd, i, n; int total = 0; if ((fd = socket(AF_INET, SOCK_DGRAM, 0)) == -1) { return -1; } ifc.ifc_len = sizeof(buff); ifc.ifc_buf = buff; if (ioctl(fd, SIOCGIFCONF, &ifc) != 0) { close(fd); return -1; } ifr = ifc.ifc_req; n = ifc.ifc_len / sizeof(struct ifreq); /* Loop through interfaces, looking for given IP address */ for (i=n-1;i>=0 && total < max_interfaces;i--) { if (ioctl(fd, SIOCGIFADDR, &ifr[i]) != 0) { continue; } iname = ifr[i].ifr_name; sockaddr = (struct sockaddr *) &ifr[i].ifr_addr; sockaddr_in = (struct sockaddr_in *) sockaddr; ipaddr = sockaddr_in->sin_addr; if (ioctl(fd, SIOCGIFFLAGS, &ifr[i]) != 0) { continue; } if (!(ifr[i].ifr_flags & IFF_UP)) { continue; } if (ioctl(fd, SIOCGIFNETMASK, &ifr[i]) != 0) { continue; } nmask = sockaddr_in->sin_addr; strncpy(ifaces[total].name, iname, sizeof(ifaces[total].name)-1); ifaces[total].name[sizeof(ifaces[total].name)-1] = 0; ifaces[total].ip = ipaddr; ifaces[total].netmask = nmask; total++; } close(fd); return total; } static int iface_comp(struct iface_struct *i1, struct iface_struct *i2) { int r; r = strcmp(i1->name, i2->name); if (r) return r; r = ntohl(i1->ip.s_addr) - ntohl(i2->ip.s_addr); if (r) return r; r = ntohl(i1->netmask.s_addr) - ntohl(i2->netmask.s_addr); return r; } /* this wrapper is used to remove duplicates from the interface list generated above */ _PUBLIC_ int get_interfaces_oc(struct iface_struct *ifaces, int max_interfaces) { int total, i, j; total = _get_interfaces(ifaces, max_interfaces); if (total <= 0) return total; /* now we need to remove duplicates */ qsort(ifaces, total, sizeof(ifaces[0]), QSORT_CAST iface_comp); for (i=1;i. */ /** used for network interfaces */ struct interface { struct interface *next, *prev; struct in_addr ip; struct in_addr nmask; const char *ip_s; const char *bcast_s; const char *nmask_s; }; struct iface_struct { char name[16]; struct in_addr ip; struct in_addr netmask; }; #define MAX_INTERFACES 128 openchange-2.0/libmapi/utils.c000066400000000000000000000151111223057412600164040ustar00rootroot00000000000000/* OpenChange MAPI implementation. Copyright (C) Julien Kerihuel 2005 - 2012. This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see . */ #include "libmapi/libmapi.h" #include "libmapi/libmapi_private.h" #include "gen_ndr/ndr_exchange.h" /** \file utils.c \brief General utility functions */ /* FIXME: nor 0x00 0x00 0x00 0x00 at the beginning neither 0x2f at the end should be listed */ static const uint8_t MAPI_LOCAL_UID[] = { 0xdc, 0xa7, 0x40, 0xc8, 0xc0, 0x42, 0x10, 0x1a, 0xb4, 0xb9, 0x08, 0x00, 0x2b, 0x2f, 0xe1, 0x82 }; static const uint8_t MAPI_LOCAL_UID_END[] = { 0x01, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x2f }; _PUBLIC_ char *guid_delete_dash(TALLOC_CTX *mem_ctx, const char *recipient_id) { char *guid; uint32_t count,i; if (!recipient_id) { return NULL; } for (count=0,i=0;i!=strlen(recipient_id);i++) { if (recipient_id[i] != '-') count++; } guid = (char *)talloc_zero_size(mem_ctx, count+1); for (count=0,i = 0;i!=strlen(recipient_id);i++) { if (recipient_id[i] != '-') { guid[count] = recipient_id[i]; count++; } } return guid; } /* Constructs a PR_ENTRYID value for recipients. */ _PUBLIC_ struct Binary_r *generate_recipient_entryid(TALLOC_CTX *mem_ctx, const char *recipient_id) { struct Binary_r *entryid; uint32_t off; char *guid = (char *) NULL; entryid = talloc(mem_ctx, struct Binary_r); entryid->cb = sizeof (uint32_t) + sizeof (MAPI_LOCAL_UID) + sizeof (MAPI_LOCAL_UID_END) + 1; if (recipient_id) { guid = guid_delete_dash(mem_ctx, recipient_id); entryid->cb += strlen(guid); } entryid->lpb = (uint8_t *)talloc_zero_size(mem_ctx, entryid->cb); off = 4; memcpy(entryid->lpb + off, MAPI_LOCAL_UID, sizeof (MAPI_LOCAL_UID)); off += sizeof (MAPI_LOCAL_UID); memcpy(entryid->lpb + off, MAPI_LOCAL_UID_END, sizeof (MAPI_LOCAL_UID_END)); off += sizeof (MAPI_LOCAL_UID_END); if (recipient_id) { strcpy((char *)entryid->lpb + off, guid); off += strlen(recipient_id); } return entryid; } /** \details Create a FID from an EntryID \param cb count of lpb bytes \param lpb pointer on an array of bytes \param parent_fid the parent folder identifier \param fid pointer to the returned fid \return MAPI_E_SUCCESS on success, otherwise MAPI_E_INVALID_PARAMETER */ _PUBLIC_ enum MAPISTATUS GetFIDFromEntryID(uint16_t cb, uint8_t *lpb, uint64_t parent_fid, uint64_t *fid) { /* Sanity checks */ OPENCHANGE_RETVAL_IF(!lpb, MAPI_E_INVALID_PARAMETER, NULL); OPENCHANGE_RETVAL_IF(!fid, MAPI_E_INVALID_PARAMETER, NULL); OPENCHANGE_RETVAL_IF(cb < 8, MAPI_E_INVALID_PARAMETER, NULL); *fid = 0; *fid += ((uint64_t)lpb[cb - 3] << 56); *fid += ((uint64_t)lpb[cb - 4] << 48); *fid += ((uint64_t)lpb[cb - 5] << 40); *fid += ((uint64_t)lpb[cb - 6] << 32); *fid += ((uint64_t)lpb[cb - 7] << 24); *fid += ((uint64_t)lpb[cb - 8] << 16); /* WARNING: for some unknown reason the latest byte of folder ID may change (0x1 or 0x4 values identified so far). However this byte sounds the same than the parent folder one */ *fid += (parent_fid & 0xFFFF); return MAPI_E_SUCCESS; } /** \details Build an EntryID for message from folder and message source ID */ _PUBLIC_ enum MAPISTATUS EntryIDFromSourceIDForMessage(TALLOC_CTX *mem_ctx, mapi_object_t *obj_store, mapi_object_t *obj_folder, mapi_object_t *obj_message, struct SBinary_short *entryID) { enum MAPISTATUS retval; struct ndr_push *ndr; mapi_object_store_t *store; const struct SBinary_short *FolderSourceKey; const struct SBinary_short *MessageSourceKey; struct SPropTagArray *SPropTagArray; struct SPropValue *lpPropsf; struct SPropValue *lpPropsm; uint32_t count; /* Sanity checks */ OPENCHANGE_RETVAL_IF(!obj_store, MAPI_E_INVALID_PARAMETER, NULL); OPENCHANGE_RETVAL_IF(!obj_folder, MAPI_E_INVALID_PARAMETER, NULL); OPENCHANGE_RETVAL_IF(!obj_message, MAPI_E_INVALID_PARAMETER, NULL); OPENCHANGE_RETVAL_IF(!entryID, MAPI_E_INVALID_PARAMETER, NULL); store = (mapi_object_store_t *)obj_store->private_data; /* Step 1. Retrieve folder Source Key */ SPropTagArray = set_SPropTagArray(mem_ctx, 0x1, PidTagSourceKey); retval = GetProps(obj_folder, 0, SPropTagArray, &lpPropsf, &count); MAPIFreeBuffer(SPropTagArray); if (retval != MAPI_E_SUCCESS) return MAPI_E_NOT_FOUND; FolderSourceKey = (const struct SBinary_short *)get_SPropValue(lpPropsf, PidTagSourceKey); if (FolderSourceKey == NULL) return MAPI_E_NOT_FOUND; /* Step 2. Retrieve message Source Key */ SPropTagArray = set_SPropTagArray(mem_ctx, 0x1, PidTagSourceKey); retval = GetProps(obj_message, 0, SPropTagArray, &lpPropsm, &count); MAPIFreeBuffer(SPropTagArray); if (retval != MAPI_E_SUCCESS) return MAPI_E_NOT_FOUND; MessageSourceKey = (const struct SBinary_short *)get_SPropValue(lpPropsm, PidTagSourceKey); if (MessageSourceKey == NULL) return MAPI_E_NOT_FOUND; /* Step 3. Fill PidTagEntryID */ /* PidTagEntryId size for message is 70 bytes */ /* Flags (4 bytes) + store guid (16 bytes) + object type (2 * bytes) + Folder SourceKey (22 bytes) + Pad (2 bytes) + * Message Source (22 bytes) + Pad (2 bytes) == 70 bytes */ ndr = ndr_push_init_ctx(NULL); ndr_set_flags(&ndr->flags, LIBNDR_FLAG_NOALIGN); ndr->offset = 0; ndr_push_uint32(ndr, NDR_SCALARS, 0x0); if (store->store_type == PublicFolder) { const uint8_t ProviderUID[16] = { 0x1A, 0x44, 0x73, 0x90, 0xAA, 0x66, 0x11, 0xCD, 0x9B, 0xC8, 0x00, 0xAA, 0x00, 0x2F, 0xC4, 0x5A }; ndr_push_array_uint8(ndr, NDR_SCALARS, ProviderUID, 16); ndr_push_uint16(ndr, NDR_SCALARS, 0x0009); } else { ndr_push_GUID(ndr, NDR_SCALARS, &store->guid); ndr_push_uint16(ndr, NDR_SCALARS, 0x0007); } ndr_push_array_uint8(ndr, NDR_SCALARS, FolderSourceKey->lpb, FolderSourceKey->cb); ndr_push_uint16(ndr, NDR_SCALARS, 0x0); ndr_push_array_uint8(ndr, NDR_SCALARS, MessageSourceKey->lpb, MessageSourceKey->cb); ndr_push_uint16(ndr, NDR_SCALARS, 0x0); entryID->cb = ndr->offset; entryID->lpb = talloc_steal(mem_ctx, ndr->data); talloc_free(ndr); return MAPI_E_SUCCESS; } openchange-2.0/libmapi/x500.c000066400000000000000000000060461223057412600157470ustar00rootroot00000000000000/* OpenChange NSPI implementation. Copyright (C) Julien Kerihuel 2005 - 2011. This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see . */ #include "libmapi/libmapi.h" #include "libmapi/libmapi_private.h" #ifndef HAVE_STRCASESTR static char *strcasestr(const char *haystack, const char *needle) { const char *s; size_t nlen = strlen(needle); for (s=haystack;*s;s++) { if (toupper(*needle) == toupper(*s) && strncasecmp(s, needle, nlen) == 0) { return (char *)((uintptr_t)s); } } return NULL; } #endif /** \details Extract a DN element from a given DN \param mem_ctx pointer to the memory context \param dn pointer to a valid DN \param element pointer to the substring where extraction should start \return pointer to an allocated substring on success, otherwise NULL */ _PUBLIC_ char *x500_get_dn_element(TALLOC_CTX *mem_ctx, const char *dn, const char *element) { char *pdn, *p, *str; char *tmp_dn; if ((dn == NULL) || (dn[0] == '\0') || !element) return NULL; tmp_dn = talloc_strdup(mem_ctx, dn); pdn = (char *) strcasestr((const char *)tmp_dn, element); if (pdn == NULL) { talloc_free(tmp_dn); return NULL; } pdn += strlen(element); p = pdn; if ((p = strchr(pdn, '/')) != NULL) { p[0] = '\0'; } str = talloc_strdup(mem_ctx, pdn); talloc_free(tmp_dn); return str; } /** \details Truncate a DN element \param mem_ctx pointer to the memory context \param dn pointer to a valid DN \param elcount the number of elements to remove from the end of the DN \return pointer to an allocated substring on success, otherwise NULL */ _PUBLIC_ char *x500_truncate_dn_last_elements(TALLOC_CTX *mem_ctx, const char *dn, uint32_t elcount) { char *tmp_dn; int i; if ((dn == NULL) || (dn[0] == '\0') || !elcount) return NULL; tmp_dn = talloc_strdup(mem_ctx, dn); for (i = strlen(tmp_dn); i > 0; i--) { if (tmp_dn[i] == '/') { elcount -= 1; if (elcount == 0) { tmp_dn[i] = '\0'; return tmp_dn; } } } return NULL; } /** * Retrieve the servername from a string * We should definitively find a better way to handle this */ _PUBLIC_ char *x500_get_servername(const char *dn) { char *pdn; char *servername; if (!dn) { return NULL; } pdn = (char *) strcasestr(dn, SERVERNAME); if (pdn == NULL) return NULL; pdn += strlen(SERVERNAME); servername = strsep(&pdn, "/"); return (servername); } openchange-2.0/libmapiadmin.pc.in000066400000000000000000000005321223057412600170430ustar00rootroot00000000000000prefix=@prefix@ exec_prefix=@exec_prefix@ libdir=@libdir@ includedir=@includedir@ datarootdir=@prefix@/share datadir=@datadir@ Name: MAPI admin library Description: Library supporting MAPI administration actions Version: @PACKAGE_VERSION@ Libs: -L${libdir} -lmapiadmin Libs.private: @LIBS@ Cflags: -I${includedir} Requires: libmapi dcerpc_samr openchange-2.0/libmapiadmin/000077500000000000000000000000001223057412600161125ustar00rootroot00000000000000openchange-2.0/libmapiadmin/Doxyfile.in000066400000000000000000001465771223057412600202510ustar00rootroot00000000000000# Doxyfile 1.5.2 # This file describes the settings to be used by the documentation system # doxygen (www.doxygen.org) for a project # # All text after a hash (#) is considered a comment and will be ignored # The format is: # TAG = value [value, ...] # For lists items can also be appended using: # TAG += value [value, ...] # Values that contain spaces should be placed between quotes (" ") #--------------------------------------------------------------------------- # Project related configuration options #--------------------------------------------------------------------------- # This tag specifies the encoding used for all characters in the config file that # follow. The default is UTF-8 which is also the encoding used for all text before # the first occurrence of this tag. Doxygen uses libiconv (or the iconv built into # libc) for the transcoding. See http://www.gnu.org/software/libiconv for the list of # possible encodings. DOXYFILE_ENCODING = UTF-8 # The PROJECT_NAME tag is a single word (or a sequence of words surrounded # by quotes) that should identify the project. PROJECT_NAME = libmapiadmin # The PROJECT_NUMBER tag can be used to enter a project or revision number. # This could be handy for archiving the generated documentation or # if some version control system is used. PROJECT_NUMBER = @PACKAGE_VERSION@ # The OUTPUT_DIRECTORY tag is used to specify the (relative or absolute) # base path where the generated documentation will be put. # If a relative path is entered, it will be relative to the location # where doxygen was started. If left blank the current directory will be used. OUTPUT_DIRECTORY = apidocs # If the CREATE_SUBDIRS tag is set to YES, then doxygen will create # 4096 sub-directories (in 2 levels) under the output directory of each output # format and will distribute the generated files over these directories. # Enabling this option can be useful when feeding doxygen a huge amount of # source files, where putting all generated files in the same directory would # otherwise cause performance problems for the file system. CREATE_SUBDIRS = NO # The OUTPUT_LANGUAGE tag is used to specify the language in which all # documentation generated by doxygen is written. Doxygen will use this # information to generate all constant output in the proper language. # The default language is English, other supported languages are: # Afrikaans, Arabic, Brazilian, Catalan, Chinese, Chinese-Traditional, # Croatian, Czech, Danish, Dutch, Finnish, French, German, Greek, Hungarian, # Italian, Japanese, Japanese-en (Japanese with English messages), Korean, # Korean-en, Lithuanian, Norwegian, Polish, Portuguese, Romanian, Russian, # Serbian, Slovak, Slovene, Spanish, Swedish, and Ukrainian. OUTPUT_LANGUAGE = English # If the BRIEF_MEMBER_DESC tag is set to YES (the default) Doxygen will # include brief member descriptions after the members that are listed in # the file and class documentation (similar to JavaDoc). # Set to NO to disable this. BRIEF_MEMBER_DESC = YES # If the REPEAT_BRIEF tag is set to YES (the default) Doxygen will prepend # the brief description of a member or function before the detailed description. # Note: if both HIDE_UNDOC_MEMBERS and BRIEF_MEMBER_DESC are set to NO, the # brief descriptions will be completely suppressed. REPEAT_BRIEF = YES # This tag implements a quasi-intelligent brief description abbreviator # that is used to form the text in various listings. Each string # in this list, if found as the leading text of the brief description, will be # stripped from the text and the result after processing the whole list, is # used as the annotated text. Otherwise, the brief description is used as-is. # If left blank, the following values are used ("$name" is automatically # replaced with the name of the entity): "The $name class" "The $name widget" # "The $name file" "is" "provides" "specifies" "contains" # "represents" "a" "an" "the" ABBREVIATE_BRIEF = # If the ALWAYS_DETAILED_SEC and REPEAT_BRIEF tags are both set to YES then # Doxygen will generate a detailed section even if there is only a brief # description. ALWAYS_DETAILED_SEC = NO # If the INLINE_INHERITED_MEMB tag is set to YES, doxygen will show all # inherited members of a class in the documentation of that class as if those # members were ordinary class members. Constructors, destructors and assignment # operators of the base classes will not be shown. INLINE_INHERITED_MEMB = NO # If the FULL_PATH_NAMES tag is set to YES then Doxygen will prepend the full # path before files name in the file list and in the header files. If set # to NO the shortest path that makes the file name unique will be used. FULL_PATH_NAMES = YES # If the FULL_PATH_NAMES tag is set to YES then the STRIP_FROM_PATH tag # can be used to strip a user-defined part of the path. Stripping is # only done if one of the specified strings matches the left-hand part of # the path. The tag can be used to show relative paths in the file list. # If left blank the directory from which doxygen is run is used as the # path to strip. STRIP_FROM_PATH = # The STRIP_FROM_INC_PATH tag can be used to strip a user-defined part of # the path mentioned in the documentation of a class, which tells # the reader which header file to include in order to use a class. # If left blank only the name of the header file containing the class # definition is used. Otherwise one should specify the include paths that # are normally passed to the compiler using the -I flag. STRIP_FROM_INC_PATH = # If the SHORT_NAMES tag is set to YES, doxygen will generate much shorter # (but less readable) file names. This can be useful is your file systems # doesn't support long names like on DOS, Mac, or CD-ROM. SHORT_NAMES = NO # If the JAVADOC_AUTOBRIEF tag is set to YES then Doxygen # will interpret the first line (until the first dot) of a JavaDoc-style # comment as the brief description. If set to NO, the JavaDoc # comments will behave just like the Qt-style comments (thus requiring an # explicit @brief command for a brief description. JAVADOC_AUTOBRIEF = YES # The MULTILINE_CPP_IS_BRIEF tag can be set to YES to make Doxygen # treat a multi-line C++ special comment block (i.e. a block of //! or /// # comments) as a brief description. This used to be the default behaviour. # The new default is to treat a multi-line C++ comment block as a detailed # description. Set this tag to YES if you prefer the old behaviour instead. MULTILINE_CPP_IS_BRIEF = NO # If the INHERIT_DOCS tag is set to YES (the default) then an undocumented # member inherits the documentation from any documented member that it # re-implements. INHERIT_DOCS = YES # If the SEPARATE_MEMBER_PAGES tag is set to YES, then doxygen will produce # a new page for each member. If set to NO, the documentation of a member will # be part of the file/class/namespace that contains it. SEPARATE_MEMBER_PAGES = NO # The TAB_SIZE tag can be used to set the number of spaces in a tab. # Doxygen uses this value to replace tabs by spaces in code fragments. TAB_SIZE = 8 # This tag can be used to specify a number of aliases that acts # as commands in the documentation. An alias has the form "name=value". # For example adding "sideeffect=\par Side Effects:\n" will allow you to # put the command \sideeffect (or @sideeffect) in the documentation, which # will result in a user-defined paragraph with heading "Side Effects:". # You can put \n's in the value part of an alias to insert newlines. ALIASES = # Set the OPTIMIZE_OUTPUT_FOR_C tag to YES if your project consists of C # sources only. Doxygen will then generate output that is more tailored for C. # For instance, some of the names that are used will be different. The list # of all members will be omitted, etc. OPTIMIZE_OUTPUT_FOR_C = YES # Set the OPTIMIZE_OUTPUT_JAVA tag to YES if your project consists of Java # sources only. Doxygen will then generate output that is more tailored for Java. # For instance, namespaces will be presented as packages, qualified scopes # will look different, etc. OPTIMIZE_OUTPUT_JAVA = NO # If you use STL classes (i.e. std::string, std::vector, etc.) but do not want to # include (a tag file for) the STL sources as input, then you should # set this tag to YES in order to let doxygen match functions declarations and # definitions whose arguments contain STL classes (e.g. func(std::string); v.s. # func(std::string) {}). This also make the inheritance and collaboration # diagrams that involve STL classes more complete and accurate. BUILTIN_STL_SUPPORT = NO # If you use Microsoft's C++/CLI language, you should set this option to YES to # enable parsing support. CPP_CLI_SUPPORT = NO # If member grouping is used in the documentation and the DISTRIBUTE_GROUP_DOC # tag is set to YES, then doxygen will reuse the documentation of the first # member in the group (if any) for the other members of the group. By default # all members of a group must be documented explicitly. DISTRIBUTE_GROUP_DOC = NO # Set the SUBGROUPING tag to YES (the default) to allow class member groups of # the same type (for instance a group of public functions) to be put as a # subgroup of that type (e.g. under the Public Functions section). Set it to # NO to prevent subgrouping. Alternatively, this can be done per class using # the \nosubgrouping command. SUBGROUPING = YES #--------------------------------------------------------------------------- # Build related configuration options #--------------------------------------------------------------------------- # If the EXTRACT_ALL tag is set to YES doxygen will assume all entities in # documentation are documented, even if no documentation was available. # Private class members and static file members will be hidden unless # the EXTRACT_PRIVATE and EXTRACT_STATIC tags are set to YES EXTRACT_ALL = NO # If the EXTRACT_PRIVATE tag is set to YES all private members of a class # will be included in the documentation. EXTRACT_PRIVATE = NO # If the EXTRACT_STATIC tag is set to YES all static members of a file # will be included in the documentation. EXTRACT_STATIC = NO # If the EXTRACT_LOCAL_CLASSES tag is set to YES classes (and structs) # defined locally in source files will be included in the documentation. # If set to NO only classes defined in header files are included. EXTRACT_LOCAL_CLASSES = NO # This flag is only useful for Objective-C code. When set to YES local # methods, which are defined in the implementation section but not in # the interface are included in the documentation. # If set to NO (the default) only methods in the interface are included. EXTRACT_LOCAL_METHODS = NO # If the HIDE_UNDOC_MEMBERS tag is set to YES, Doxygen will hide all # undocumented members of documented classes, files or namespaces. # If set to NO (the default) these members will be included in the # various overviews, but no documentation section is generated. # This option has no effect if EXTRACT_ALL is enabled. HIDE_UNDOC_MEMBERS = YES # If the HIDE_UNDOC_CLASSES tag is set to YES, Doxygen will hide all # undocumented classes that are normally visible in the class hierarchy. # If set to NO (the default) these classes will be included in the various # overviews. This option has no effect if EXTRACT_ALL is enabled. HIDE_UNDOC_CLASSES = YES # If the HIDE_FRIEND_COMPOUNDS tag is set to YES, Doxygen will hide all # friend (class|struct|union) declarations. # If set to NO (the default) these declarations will be included in the # documentation. HIDE_FRIEND_COMPOUNDS = YES # If the HIDE_IN_BODY_DOCS tag is set to YES, Doxygen will hide any # documentation blocks found inside the body of a function. # If set to NO (the default) these blocks will be appended to the # function's detailed documentation block. HIDE_IN_BODY_DOCS = NO # The INTERNAL_DOCS tag determines if documentation # that is typed after a \internal command is included. If the tag is set # to NO (the default) then the documentation will be excluded. # Set it to YES to include the internal documentation. INTERNAL_DOCS = NO # If the CASE_SENSE_NAMES tag is set to NO then Doxygen will only generate # file names in lower-case letters. If set to YES upper-case letters are also # allowed. This is useful if you have classes or files whose names only differ # in case and if your file system supports case sensitive file names. Windows # and Mac users are advised to set this option to NO. CASE_SENSE_NAMES = YES # If the HIDE_SCOPE_NAMES tag is set to NO (the default) then Doxygen # will show members with their full class and namespace scopes in the # documentation. If set to YES the scope will be hidden. HIDE_SCOPE_NAMES = NO # If the SHOW_INCLUDE_FILES tag is set to YES (the default) then Doxygen # will put a list of the files that are included by a file in the documentation # of that file. SHOW_INCLUDE_FILES = YES # If the INLINE_INFO tag is set to YES (the default) then a tag [inline] # is inserted in the documentation for inline members. INLINE_INFO = YES # If the SORT_MEMBER_DOCS tag is set to YES (the default) then doxygen # will sort the (detailed) documentation of file and class members # alphabetically by member name. If set to NO the members will appear in # declaration order. SORT_MEMBER_DOCS = YES # If the SORT_BRIEF_DOCS tag is set to YES then doxygen will sort the # brief documentation of file, namespace and class members alphabetically # by member name. If set to NO (the default) the members will appear in # declaration order. SORT_BRIEF_DOCS = YES # If the SORT_BY_SCOPE_NAME tag is set to YES, the class list will be # sorted by fully-qualified names, including namespaces. If set to # NO (the default), the class list will be sorted only by class name, # not including the namespace part. # Note: This option is not very useful if HIDE_SCOPE_NAMES is set to YES. # Note: This option applies only to the class list, not to the # alphabetical list. SORT_BY_SCOPE_NAME = NO # The GENERATE_TODOLIST tag can be used to enable (YES) or # disable (NO) the todo list. This list is created by putting \todo # commands in the documentation. GENERATE_TODOLIST = YES # The GENERATE_TESTLIST tag can be used to enable (YES) or # disable (NO) the test list. This list is created by putting \test # commands in the documentation. GENERATE_TESTLIST = YES # The GENERATE_BUGLIST tag can be used to enable (YES) or # disable (NO) the bug list. This list is created by putting \bug # commands in the documentation. GENERATE_BUGLIST = YES # The GENERATE_DEPRECATEDLIST tag can be used to enable (YES) or # disable (NO) the deprecated list. This list is created by putting # \deprecated commands in the documentation. GENERATE_DEPRECATEDLIST= YES # The ENABLED_SECTIONS tag can be used to enable conditional # documentation sections, marked by \if sectionname ... \endif. ENABLED_SECTIONS = # The MAX_INITIALIZER_LINES tag determines the maximum number of lines # the initial value of a variable or define consists of for it to appear in # the documentation. If the initializer consists of more lines than specified # here it will be hidden. Use a value of 0 to hide initializers completely. # The appearance of the initializer of individual variables and defines in the # documentation can be controlled using \showinitializer or \hideinitializer # command in the documentation regardless of this setting. MAX_INITIALIZER_LINES = 30 # Set the SHOW_USED_FILES tag to NO to disable the list of files generated # at the bottom of the documentation of classes and structs. If set to YES the # list will mention the files that were used to generate the documentation. SHOW_USED_FILES = YES # If the sources in your project are distributed over multiple directories # then setting the SHOW_DIRECTORIES tag to YES will show the directory hierarchy # in the documentation. The default is NO. SHOW_DIRECTORIES = NO # The FILE_VERSION_FILTER tag can be used to specify a program or script that # doxygen should invoke to get the current version for each file (typically from the # version control system). Doxygen will invoke the program by executing (via # popen()) the command , where is the value of # the FILE_VERSION_FILTER tag, and is the name of an input file # provided by doxygen. Whatever the program writes to standard output # is used as the file version. See the manual for examples. FILE_VERSION_FILTER = #--------------------------------------------------------------------------- # configuration options related to warning and progress messages #--------------------------------------------------------------------------- # The QUIET tag can be used to turn on/off the messages that are generated # by doxygen. Possible values are YES and NO. If left blank NO is used. QUIET = NO # The WARNINGS tag can be used to turn on/off the warning messages that are # generated by doxygen. Possible values are YES and NO. If left blank # NO is used. WARNINGS = YES # If WARN_IF_UNDOCUMENTED is set to YES, then doxygen will generate warnings # for undocumented members. If EXTRACT_ALL is set to YES then this flag will # automatically be disabled. WARN_IF_UNDOCUMENTED = YES # If WARN_IF_DOC_ERROR is set to YES, doxygen will generate warnings for # potential errors in the documentation, such as not documenting some # parameters in a documented function, or documenting parameters that # don't exist or using markup commands wrongly. WARN_IF_DOC_ERROR = YES # This WARN_NO_PARAMDOC option can be abled to get warnings for # functions that are documented, but have no documentation for their parameters # or return value. If set to NO (the default) doxygen will only warn about # wrong or incomplete parameter documentation, but not about the absence of # documentation. WARN_NO_PARAMDOC = NO # The WARN_FORMAT tag determines the format of the warning messages that # doxygen can produce. The string should contain the $file, $line, and $text # tags, which will be replaced by the file and line number from which the # warning originated and the warning text. Optionally the format may contain # $version, which will be replaced by the version of the file (if it could # be obtained via FILE_VERSION_FILTER) WARN_FORMAT = "$file:$line: $text" # The WARN_LOGFILE tag can be used to specify a file to which warning # and error messages should be written. If left blank the output is written # to stderr. WARN_LOGFILE = #--------------------------------------------------------------------------- # configuration options related to the input files #--------------------------------------------------------------------------- # The INPUT tag can be used to specify the files and/or directories that contain # documented source files. You may enter file names like "myfile.cpp" or # directories like "/usr/src/myproject". Separate the files or directories # with spaces. INPUT = libmapiadmin # This tag can be used to specify the character encoding of the source files that # doxygen parses. Internally doxygen uses the UTF-8 encoding, which is also the default # input encoding. Doxygen uses libiconv (or the iconv built into libc) for the transcoding. # See http://www.gnu.org/software/libiconv for the list of possible encodings. INPUT_ENCODING = UTF-8 # If the value of the INPUT tag contains directories, you can use the # FILE_PATTERNS tag to specify one or more wildcard pattern (like *.cpp # and *.h) to filter out the source-files in the directories. If left # blank the following patterns are tested: # *.c *.cc *.cxx *.cpp *.c++ *.java *.ii *.ixx *.ipp *.i++ *.inl *.h *.hh *.hxx # *.hpp *.h++ *.idl *.odl *.cs *.php *.php3 *.inc *.m *.mm *.py FILE_PATTERNS = *.h *.c *.doxy # The RECURSIVE tag can be used to turn specify whether or not subdirectories # should be searched for input files as well. Possible values are YES and NO. # If left blank NO is used. RECURSIVE = NO # The EXCLUDE tag can be used to specify files and/or directories that should # excluded from the INPUT source files. This way you can easily exclude a # subdirectory from a directory tree whose root is specified with the INPUT tag. EXCLUDE = *_private.h # The EXCLUDE_SYMLINKS tag can be used select whether or not files or # directories that are symbolic links (a Unix filesystem feature) are excluded # from the input. EXCLUDE_SYMLINKS = NO # If the value of the INPUT tag contains directories, you can use the # EXCLUDE_PATTERNS tag to specify one or more wildcard patterns to exclude # certain files from those directories. Note that the wildcards are matched # against the file with absolute path, so to exclude all test directories # for example use the pattern */test/* EXCLUDE_PATTERNS = *.yy.c *_private.h # The EXCLUDE_SYMBOLS tag can be used to specify one or more symbol names # (namespaces, classes, functions, etc.) that should be excluded from the output. # The symbol name can be a fully qualified name, a word, or if the wildcard * is used, # a substring. Examples: ANamespace, AClass, AClass::ANamespace, ANamespace::*Test EXCLUDE_SYMBOLS = # The EXAMPLE_PATH tag can be used to specify one or more files or # directories that contain example code fragments that are included (see # the \include command). EXAMPLE_PATH = # If the value of the EXAMPLE_PATH tag contains directories, you can use the # EXAMPLE_PATTERNS tag to specify one or more wildcard pattern (like *.cpp # and *.h) to filter out the source-files in the directories. If left # blank all files are included. EXAMPLE_PATTERNS = # If the EXAMPLE_RECURSIVE tag is set to YES then subdirectories will be # searched for input files to be used with the \include or \dontinclude # commands irrespective of the value of the RECURSIVE tag. # Possible values are YES and NO. If left blank NO is used. EXAMPLE_RECURSIVE = NO # The IMAGE_PATH tag can be used to specify one or more files or # directories that contain image that are included in the documentation (see # the \image command). IMAGE_PATH = doc/doxygen/pictures/ # The INPUT_FILTER tag can be used to specify a program that doxygen should # invoke to filter for each input file. Doxygen will invoke the filter program # by executing (via popen()) the command , where # is the value of the INPUT_FILTER tag, and is the name of an # input file. Doxygen will then use the output that the filter program writes # to standard output. If FILTER_PATTERNS is specified, this tag will be # ignored. INPUT_FILTER = "sed \ -e '20,50s/.*\//' \ -e '20,50s/.*\//' \ -e '20,50s/.*\//' \ -e '20,50s/.*\//' \ -e '20,50s/.*\//' \ -e '20,50s/.*\//' \ -e '20,50s/.*\//' \ -e '20,50s/.*\//' \ -e '20,50s/.*\//' \ -e '20,50s/.*\//' \ -e '20,50s/.*\//' \ -e '20,50s/.*\//' \ -e '20,50s/.*\//' \ -e '20,50s/.*\//' \ -e 's/_PUBLIC_//'" # The FILTER_PATTERNS tag can be used to specify filters on a per file pattern # basis. Doxygen will compare the file name with each pattern and apply the # filter if there is a match. The filters are a list of the form: # pattern=filter (like *.cpp=my_cpp_filter). See INPUT_FILTER for further # info on how filters are used. If FILTER_PATTERNS is empty, INPUT_FILTER # is applied to all files. FILTER_PATTERNS = # If the FILTER_SOURCE_FILES tag is set to YES, the input filter (if set using # INPUT_FILTER) will be used to filter the input files when producing source # files to browse (i.e. when SOURCE_BROWSER is set to YES). FILTER_SOURCE_FILES = NO #--------------------------------------------------------------------------- # configuration options related to source browsing #--------------------------------------------------------------------------- # If the SOURCE_BROWSER tag is set to YES then a list of source files will # be generated. Documented entities will be cross-referenced with these sources. # Note: To get rid of all source code in the generated output, make sure also # VERBATIM_HEADERS is set to NO. SOURCE_BROWSER = NO # Setting the INLINE_SOURCES tag to YES will include the body # of functions and classes directly in the documentation. INLINE_SOURCES = NO # Setting the STRIP_CODE_COMMENTS tag to YES (the default) will instruct # doxygen to hide any special comment blocks from generated source code # fragments. Normal C and C++ comments will always remain visible. STRIP_CODE_COMMENTS = YES # If the REFERENCED_BY_RELATION tag is set to YES (the default) # then for each documented function all documented # functions referencing it will be listed. REFERENCED_BY_RELATION = YES # If the REFERENCES_RELATION tag is set to YES (the default) # then for each documented function all documented entities # called/used by that function will be listed. REFERENCES_RELATION = YES # If the REFERENCES_LINK_SOURCE tag is set to YES (the default) # and SOURCE_BROWSER tag is set to YES, then the hyperlinks from # functions in REFERENCES_RELATION and REFERENCED_BY_RELATION lists will # link to the source code. Otherwise they will link to the documentstion. REFERENCES_LINK_SOURCE = YES # If the USE_HTAGS tag is set to YES then the references to source code # will point to the HTML generated by the htags(1) tool instead of doxygen # built-in source browser. The htags tool is part of GNU's global source # tagging system (see http://www.gnu.org/software/global/global.html). You # will need version 4.8.6 or higher. USE_HTAGS = NO # If the VERBATIM_HEADERS tag is set to YES (the default) then Doxygen # will generate a verbatim copy of the header file for each class for # which an include is specified. Set to NO to disable this. VERBATIM_HEADERS = NO #--------------------------------------------------------------------------- # configuration options related to the alphabetical class index #--------------------------------------------------------------------------- # If the ALPHABETICAL_INDEX tag is set to YES, an alphabetical index # of all compounds will be generated. Enable this if the project # contains a lot of classes, structs, unions or interfaces. ALPHABETICAL_INDEX = NO # If the alphabetical index is enabled (see ALPHABETICAL_INDEX) then # the COLS_IN_ALPHA_INDEX tag can be used to specify the number of columns # in which this list will be split (can be a number in the range [1..20]) COLS_IN_ALPHA_INDEX = 5 # In case all classes in a project start with a common prefix, all # classes will be put under the same header in the alphabetical index. # The IGNORE_PREFIX tag can be used to specify one or more prefixes that # should be ignored while generating the index headers. IGNORE_PREFIX = #--------------------------------------------------------------------------- # configuration options related to the HTML output #--------------------------------------------------------------------------- # If the GENERATE_HTML tag is set to YES (the default) Doxygen will # generate HTML output. GENERATE_HTML = YES # The HTML_OUTPUT tag is used to specify where the HTML docs will be put. # If a relative path is entered the value of OUTPUT_DIRECTORY will be # put in front of it. If left blank `html' will be used as the default path. HTML_OUTPUT = html/libmapiadmin # The HTML_FILE_EXTENSION tag can be used to specify the file extension for # each generated HTML page (for example: .htm,.php,.asp). If it is left blank # doxygen will generate files with .html extension. HTML_FILE_EXTENSION = .html # The HTML_HEADER tag can be used to specify a personal HTML header for # each generated HTML page. If it is left blank doxygen will generate a # standard header. HTML_HEADER = doc/doxygen/header.html # The HTML_FOOTER tag can be used to specify a personal HTML footer for # each generated HTML page. If it is left blank doxygen will generate a # standard footer. HTML_FOOTER = doc/doxygen/footer.html # The HTML_STYLESHEET tag can be used to specify a user-defined cascading # style sheet that is used by each HTML page. It can be used to # fine-tune the look of the HTML output. If the tag is left blank doxygen # will generate a default style sheet. Note that doxygen will try to copy # the style sheet file to the HTML output directory, so don't put your own # stylesheet in the HTML output directory as well, or it will be erased! HTML_STYLESHEET = doc/doxygen/apidocs.css # If the HTML_ALIGN_MEMBERS tag is set to YES, the members of classes, # files or namespaces will be aligned in HTML using tables. If set to # NO a bullet list will be used. HTML_ALIGN_MEMBERS = YES # If the GENERATE_HTMLHELP tag is set to YES, additional index files # will be generated that can be used as input for tools like the # Microsoft HTML help workshop to generate a compressed HTML help file (.chm) # of the generated HTML documentation. GENERATE_HTMLHELP = NO # If the GENERATE_HTMLHELP tag is set to YES, the CHM_FILE tag can # be used to specify the file name of the resulting .chm file. You # can add a path in front of the file if the result should not be # written to the html output directory. CHM_FILE = # If the GENERATE_HTMLHELP tag is set to YES, the HHC_LOCATION tag can # be used to specify the location (absolute path including file name) of # the HTML help compiler (hhc.exe). If non-empty doxygen will try to run # the HTML help compiler on the generated index.hhp. HHC_LOCATION = # If the GENERATE_HTMLHELP tag is set to YES, the GENERATE_CHI flag # controls if a separate .chi index file is generated (YES) or that # it should be included in the master .chm file (NO). GENERATE_CHI = NO # If the GENERATE_HTMLHELP tag is set to YES, the BINARY_TOC flag # controls whether a binary table of contents is generated (YES) or a # normal table of contents (NO) in the .chm file. BINARY_TOC = NO # The TOC_EXPAND flag can be set to YES to add extra items for group members # to the contents of the HTML help documentation and to the tree view. TOC_EXPAND = NO # The DISABLE_INDEX tag can be used to turn on/off the condensed index at # top of each HTML page. The value NO (the default) enables the index and # the value YES disables it. DISABLE_INDEX = NO # This tag can be used to set the number of enum values (range [1..20]) # that doxygen will group on one line in the generated HTML documentation. ENUM_VALUES_PER_LINE = 4 # If the GENERATE_TREEVIEW tag is set to YES, a side panel will be # generated containing a tree-like index structure (just like the one that # is generated for HTML Help). For this to work a browser that supports # JavaScript, DHTML, CSS and frames is required (for instance Mozilla 1.0+, # Netscape 6.0+, Internet explorer 5.0+, or Konqueror). Windows users are # probably better off using the HTML help feature. GENERATE_TREEVIEW = NO # If the treeview is enabled (see GENERATE_TREEVIEW) then this tag can be # used to set the initial width (in pixels) of the frame in which the tree # is shown. TREEVIEW_WIDTH = 250 #--------------------------------------------------------------------------- # configuration options related to the LaTeX output #--------------------------------------------------------------------------- # If the GENERATE_LATEX tag is set to YES (the default) Doxygen will # generate Latex output. GENERATE_LATEX = NO # The LATEX_OUTPUT tag is used to specify where the LaTeX docs will be put. # If a relative path is entered the value of OUTPUT_DIRECTORY will be # put in front of it. If left blank `latex' will be used as the default path. LATEX_OUTPUT = latex # The LATEX_CMD_NAME tag can be used to specify the LaTeX command name to be # invoked. If left blank `latex' will be used as the default command name. LATEX_CMD_NAME = latex # The MAKEINDEX_CMD_NAME tag can be used to specify the command name to # generate index for LaTeX. If left blank `makeindex' will be used as the # default command name. MAKEINDEX_CMD_NAME = makeindex # If the COMPACT_LATEX tag is set to YES Doxygen generates more compact # LaTeX documents. This may be useful for small projects and may help to # save some trees in general. COMPACT_LATEX = NO # The PAPER_TYPE tag can be used to set the paper type that is used # by the printer. Possible values are: a4, a4wide, letter, legal and # executive. If left blank a4wide will be used. PAPER_TYPE = letter # The EXTRA_PACKAGES tag can be to specify one or more names of LaTeX # packages that should be included in the LaTeX output. EXTRA_PACKAGES = # The LATEX_HEADER tag can be used to specify a personal LaTeX header for # the generated latex document. The header should contain everything until # the first chapter. If it is left blank doxygen will generate a # standard header. Notice: only use this tag if you know what you are doing! LATEX_HEADER = # If the PDF_HYPERLINKS tag is set to YES, the LaTeX that is generated # is prepared for conversion to pdf (using ps2pdf). The pdf file will # contain links (just like the HTML output) instead of page references # This makes the output suitable for online browsing using a pdf viewer. PDF_HYPERLINKS = YES # If the USE_PDFLATEX tag is set to YES, pdflatex will be used instead of # plain latex in the generated Makefile. Set this option to YES to get a # higher quality PDF documentation. USE_PDFLATEX = YES # If the LATEX_BATCHMODE tag is set to YES, doxygen will add the \\batchmode. # command to the generated LaTeX files. This will instruct LaTeX to keep # running if errors occur, instead of asking the user for help. # This option is also used when generating formulas in HTML. LATEX_BATCHMODE = NO # If LATEX_HIDE_INDICES is set to YES then doxygen will not # include the index chapters (such as File Index, Compound Index, etc.) # in the output. LATEX_HIDE_INDICES = NO #--------------------------------------------------------------------------- # configuration options related to the RTF output #--------------------------------------------------------------------------- # If the GENERATE_RTF tag is set to YES Doxygen will generate RTF output # The RTF output is optimized for Word 97 and may not look very pretty with # other RTF readers or editors. GENERATE_RTF = NO # The RTF_OUTPUT tag is used to specify where the RTF docs will be put. # If a relative path is entered the value of OUTPUT_DIRECTORY will be # put in front of it. If left blank `rtf' will be used as the default path. RTF_OUTPUT = rtf # If the COMPACT_RTF tag is set to YES Doxygen generates more compact # RTF documents. This may be useful for small projects and may help to # save some trees in general. COMPACT_RTF = NO # If the RTF_HYPERLINKS tag is set to YES, the RTF that is generated # will contain hyperlink fields. The RTF file will # contain links (just like the HTML output) instead of page references. # This makes the output suitable for online browsing using WORD or other # programs which support those fields. # Note: wordpad (write) and others do not support links. RTF_HYPERLINKS = NO # Load stylesheet definitions from file. Syntax is similar to doxygen's # config file, i.e. a series of assignments. You only have to provide # replacements, missing definitions are set to their default value. RTF_STYLESHEET_FILE = # Set optional variables used in the generation of an rtf document. # Syntax is similar to doxygen's config file. RTF_EXTENSIONS_FILE = #--------------------------------------------------------------------------- # configuration options related to the man page output #--------------------------------------------------------------------------- # If the GENERATE_MAN tag is set to YES (the default) Doxygen will # generate man pages GENERATE_MAN = YES # The MAN_OUTPUT tag is used to specify where the man pages will be put. # If a relative path is entered the value of OUTPUT_DIRECTORY will be # put in front of it. If left blank `man' will be used as the default path. MAN_OUTPUT = man # The MAN_EXTENSION tag determines the extension that is added to # the generated man pages (default is the subroutine's section .3) MAN_EXTENSION = .3 # If the MAN_LINKS tag is set to YES and Doxygen generates man output, # then it will generate one additional man file for each entity # documented in the real man page(s). These additional files # only source the real man page, but without them the man command # would be unable to find the correct page. The default is NO. MAN_LINKS = YES #--------------------------------------------------------------------------- # configuration options related to the XML output #--------------------------------------------------------------------------- # If the GENERATE_XML tag is set to YES Doxygen will # generate an XML file that captures the structure of # the code including all documentation. GENERATE_XML = NO # The XML_OUTPUT tag is used to specify where the XML pages will be put. # If a relative path is entered the value of OUTPUT_DIRECTORY will be # put in front of it. If left blank `xml' will be used as the default path. XML_OUTPUT = xml # The XML_SCHEMA tag can be used to specify an XML schema, # which can be used by a validating XML parser to check the # syntax of the XML files. XML_SCHEMA = # The XML_DTD tag can be used to specify an XML DTD, # which can be used by a validating XML parser to check the # syntax of the XML files. XML_DTD = # If the XML_PROGRAMLISTING tag is set to YES Doxygen will # dump the program listings (including syntax highlighting # and cross-referencing information) to the XML output. Note that # enabling this will significantly increase the size of the XML output. XML_PROGRAMLISTING = YES #--------------------------------------------------------------------------- # configuration options for the AutoGen Definitions output #--------------------------------------------------------------------------- # If the GENERATE_AUTOGEN_DEF tag is set to YES Doxygen will # generate an AutoGen Definitions (see autogen.sf.net) file # that captures the structure of the code including all # documentation. Note that this feature is still experimental # and incomplete at the moment. GENERATE_AUTOGEN_DEF = NO #--------------------------------------------------------------------------- # configuration options related to the Perl module output #--------------------------------------------------------------------------- # If the GENERATE_PERLMOD tag is set to YES Doxygen will # generate a Perl module file that captures the structure of # the code including all documentation. Note that this # feature is still experimental and incomplete at the # moment. GENERATE_PERLMOD = NO # If the PERLMOD_LATEX tag is set to YES Doxygen will generate # the necessary Makefile rules, Perl scripts and LaTeX code to be able # to generate PDF and DVI output from the Perl module output. PERLMOD_LATEX = NO # If the PERLMOD_PRETTY tag is set to YES the Perl module output will be # nicely formatted so it can be parsed by a human reader. This is useful # if you want to understand what is going on. On the other hand, if this # tag is set to NO the size of the Perl module output will be much smaller # and Perl will parse it just the same. PERLMOD_PRETTY = YES # The names of the make variables in the generated doxyrules.make file # are prefixed with the string contained in PERLMOD_MAKEVAR_PREFIX. # This is useful so different doxyrules.make files included by the same # Makefile don't overwrite each other's variables. PERLMOD_MAKEVAR_PREFIX = #--------------------------------------------------------------------------- # Configuration options related to the preprocessor #--------------------------------------------------------------------------- # If the ENABLE_PREPROCESSING tag is set to YES (the default) Doxygen will # evaluate all C-preprocessor directives found in the sources and include # files. ENABLE_PREPROCESSING = YES # If the MACRO_EXPANSION tag is set to YES Doxygen will expand all macro # names in the source code. If set to NO (the default) only conditional # compilation will be performed. Macro expansion can be done in a controlled # way by setting EXPAND_ONLY_PREDEF to YES. MACRO_EXPANSION = NO # If the EXPAND_ONLY_PREDEF and MACRO_EXPANSION tags are both set to YES # then the macro expansion is limited to the macros specified with the # PREDEFINED and EXPAND_AS_DEFINED tags. EXPAND_ONLY_PREDEF = NO # If the SEARCH_INCLUDES tag is set to YES (the default) the includes files # in the INCLUDE_PATH (see below) will be search if a #include is found. SEARCH_INCLUDES = YES # The INCLUDE_PATH tag can be used to specify one or more directories that # contain include files that are not input files but should be processed by # the preprocessor. INCLUDE_PATH = # You can use the INCLUDE_FILE_PATTERNS tag to specify one or more wildcard # patterns (like *.h and *.hpp) to filter out the header-files in the # directories. If left blank, the patterns specified with FILE_PATTERNS will # be used. INCLUDE_FILE_PATTERNS = # The PREDEFINED tag can be used to specify one or more macro names that # are defined before the preprocessor is started (similar to the -D option of # gcc). The argument of the tag is a list of macros of the form: name # or name=definition (no spaces). If the definition and the = are # omitted =1 is assumed. To prevent a macro definition from being # undefined via #undef or recursively expanded use the := operator # instead of the = operator. PREDEFINED = _PUBLIC_ # If the MACRO_EXPANSION and EXPAND_ONLY_PREDEF tags are set to YES then # this tag can be used to specify a list of macro names that should be expanded. # The macro definition that is found in the sources will be used. # Use the PREDEFINED tag if you want to use a different macro definition. EXPAND_AS_DEFINED = # If the SKIP_FUNCTION_MACROS tag is set to YES (the default) then # doxygen's preprocessor will remove all function-like macros that are alone # on a line, have an all uppercase name, and do not end with a semicolon. Such # function macros are typically used for boiler-plate code, and will confuse # the parser if not removed. SKIP_FUNCTION_MACROS = YES #--------------------------------------------------------------------------- # Configuration::additions related to external references #--------------------------------------------------------------------------- # The TAGFILES option can be used to specify one or more tagfiles. # Optionally an initial location of the external documentation # can be added for each tagfile. The format of a tag file without # this location is as follows: # TAGFILES = file1 file2 ... # Adding location for the tag files is done as follows: # TAGFILES = file1=loc1 "file2 = loc2" ... # where "loc1" and "loc2" can be relative or absolute paths or # URLs. If a location is present for each tag, the installdox tool # does not have to be run to correct the links. # Note that each tag file must have a unique name # (where the name does NOT include the path) # If a tag file is not located in the directory in which doxygen # is run, you must also specify the path to the tagfile here. TAGFILES = # When a file name is specified after GENERATE_TAGFILE, doxygen will create # a tag file that is based on the input files it reads. GENERATE_TAGFILE = # If the ALLEXTERNALS tag is set to YES all external classes will be listed # in the class index. If set to NO only the inherited external classes # will be listed. ALLEXTERNALS = NO # If the EXTERNAL_GROUPS tag is set to YES all external groups will be listed # in the modules index. If set to NO, only the current project's groups will # be listed. EXTERNAL_GROUPS = YES # The PERL_PATH should be the absolute path and name of the perl script # interpreter (i.e. the result of `which perl'). PERL_PATH = /usr/bin/perl #--------------------------------------------------------------------------- # Configuration options related to the dot tool #--------------------------------------------------------------------------- # If the CLASS_DIAGRAMS tag is set to YES (the default) Doxygen will # generate a inheritance diagram (in HTML, RTF and LaTeX) for classes with base # or super classes. Setting the tag to NO turns the diagrams off. Note that # this option is superseded by the HAVE_DOT option below. This is only a # fallback. It is recommended to install and use dot, since it yields more # powerful graphs. CLASS_DIAGRAMS = YES # You can define message sequence charts within doxygen comments using the \msc # command. Doxygen will then run the mscgen tool (see http://www.mcternan.me.uk/mscgen/) to # produce the chart and insert it in the documentation. The MSCGEN_PATH tag allows you to # specify the directory where the mscgen tool resides. If left empty the tool is assumed to # be found in the default search path. MSCGEN_PATH = # If set to YES, the inheritance and collaboration graphs will hide # inheritance and usage relations if the target is undocumented # or is not a class. HIDE_UNDOC_RELATIONS = YES # If you set the HAVE_DOT tag to YES then doxygen will assume the dot tool is # available from the path. This tool is part of Graphviz, a graph visualization # toolkit from AT&T and Lucent Bell Labs. The other options in this section # have no effect if this option is set to NO (the default) HAVE_DOT = NO # If the CLASS_GRAPH and HAVE_DOT tags are set to YES then doxygen # will generate a graph for each documented class showing the direct and # indirect inheritance relations. Setting this tag to YES will force the # the CLASS_DIAGRAMS tag to NO. CLASS_GRAPH = YES # If the COLLABORATION_GRAPH and HAVE_DOT tags are set to YES then doxygen # will generate a graph for each documented class showing the direct and # indirect implementation dependencies (inheritance, containment, and # class references variables) of the class with other documented classes. COLLABORATION_GRAPH = YES # If the GROUP_GRAPHS and HAVE_DOT tags are set to YES then doxygen # will generate a graph for groups, showing the direct groups dependencies GROUP_GRAPHS = YES # If the UML_LOOK tag is set to YES doxygen will generate inheritance and # collaboration diagrams in a style similar to the OMG's Unified Modeling # Language. UML_LOOK = NO # If set to YES, the inheritance and collaboration graphs will show the # relations between templates and their instances. TEMPLATE_RELATIONS = NO # If the ENABLE_PREPROCESSING, SEARCH_INCLUDES, INCLUDE_GRAPH, and HAVE_DOT # tags are set to YES then doxygen will generate a graph for each documented # file showing the direct and indirect include dependencies of the file with # other documented files. INCLUDE_GRAPH = YES # If the ENABLE_PREPROCESSING, SEARCH_INCLUDES, INCLUDED_BY_GRAPH, and # HAVE_DOT tags are set to YES then doxygen will generate a graph for each # documented header file showing the documented files that directly or # indirectly include this file. INCLUDED_BY_GRAPH = YES # If the CALL_GRAPH and HAVE_DOT tags are set to YES then doxygen will # generate a call dependency graph for every global function or class method. # Note that enabling this option will significantly increase the time of a run. # So in most cases it will be better to enable call graphs for selected # functions only using the \callgraph command. CALL_GRAPH = NO # If the CALLER_GRAPH and HAVE_DOT tags are set to YES then doxygen will # generate a caller dependency graph for every global function or class method. # Note that enabling this option will significantly increase the time of a run. # So in most cases it will be better to enable caller graphs for selected # functions only using the \callergraph command. CALLER_GRAPH = NO # If the GRAPHICAL_HIERARCHY and HAVE_DOT tags are set to YES then doxygen # will graphical hierarchy of all classes instead of a textual one. GRAPHICAL_HIERARCHY = YES # If the DIRECTORY_GRAPH, SHOW_DIRECTORIES and HAVE_DOT tags are set to YES # then doxygen will show the dependencies a directory has on other directories # in a graphical way. The dependency relations are determined by the #include # relations between the files in the directories. DIRECTORY_GRAPH = YES # The DOT_IMAGE_FORMAT tag can be used to set the image format of the images # generated by dot. Possible values are png, jpg, or gif # If left blank png will be used. DOT_IMAGE_FORMAT = png # The tag DOT_PATH can be used to specify the path where the dot tool can be # found. If left blank, it is assumed the dot tool can be found in the path. DOT_PATH = # The DOTFILE_DIRS tag can be used to specify one or more directories that # contain dot files that are included in the documentation (see the # \dotfile command). DOTFILE_DIRS = # The MAX_DOT_GRAPH_MAX_NODES tag can be used to set the maximum number of # nodes that will be shown in the graph. If the number of nodes in a graph # becomes larger than this value, doxygen will truncate the graph, which is # visualized by representing a node as a red box. Note that doxygen will always # show the root nodes and its direct children regardless of this setting. DOT_GRAPH_MAX_NODES = 50 # Set the DOT_TRANSPARENT tag to YES to generate images with a transparent # background. This is disabled by default, which results in a white background. # Warning: Depending on the platform used, enabling this option may lead to # badly anti-aliased labels on the edges of a graph (i.e. they become hard to # read). DOT_TRANSPARENT = NO # Set the DOT_MULTI_TARGETS tag to YES allow dot to generate multiple output # files in one run (i.e. multiple -o and -T options on the command line). This # makes dot run faster, but since only newer versions of dot (>1.8.10) # support this, this feature is disabled by default. DOT_MULTI_TARGETS = NO # If the GENERATE_LEGEND tag is set to YES (the default) Doxygen will # generate a legend page explaining the meaning of the various boxes and # arrows in the dot generated graphs. GENERATE_LEGEND = YES # If the DOT_CLEANUP tag is set to YES (the default) Doxygen will # remove the intermediate dot files that are used to generate # the various graphs. DOT_CLEANUP = YES #--------------------------------------------------------------------------- # Configuration::additions related to the search engine #--------------------------------------------------------------------------- # The SEARCHENGINE tag specifies whether or not a search engine should be # used. If set to NO the values of all tags below this one will be ignored. SEARCHENGINE = NO openchange-2.0/libmapiadmin/libmapiadmin-mainpage.doxy000066400000000000000000000003711223057412600232250ustar00rootroot00000000000000/** \mainpage libmapiadmin

Client library for OpenChange Administration

libmapiadmin provides administration client capabilities for OpenChange and Exchange servers. \note As of version 0.8, libmapiadmin is considered alpha quality. */ openchange-2.0/libmapiadmin/libmapiadmin.h000066400000000000000000000063361223057412600207210ustar00rootroot00000000000000/* OpenChange Exchange Administration library. Copyright (C) Julien Kerihuel 2007-2010. This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see . */ #ifndef __LIBMAPIADMIN_H__ #define __LIBMAPIADMIN_H__ #define _GNU_SOURCE 1 struct mapiadmin_ctx; #include #include #include #include #include #include #include /* Samba4 includes */ #include #include #include #include /* OpenChange includes */ #include "libmapi/libmapi.h" #undef _PRINTF_ATTRIBUTE #define _PRINTF_ATTRIBUTE(a1, a2) PRINTF_ATTRIBUTE(a1, a2) #ifndef __BEGIN_DECLS #ifdef __cplusplus #define __BEGIN_DECLS extern "C" { #define __END_DECLS } #else #define __BEGIN_DECLS #define __END_DECLS #endif #endif #ifndef MAX #define MAX(p,q) (((p) >= (q)) ? (p) : (q)) #endif /** \file Structures for MAPI admin functions */ struct test_join { struct dcerpc_pipe *p; struct policy_handle user_handle; struct libnet_JoinDomain *libnet_r; struct dom_sid *dom_sid; const char *dom_netbios_name; const char *dom_dns_name; struct dom_sid *user_sid; struct GUID user_guid; const char *netbios_name; }; /** MAPI admin function context */ struct mapiadmin_ctx { struct mapi_session *session; const char *username; const char *password; const char *fullname; const char *description; const char *comment; struct test_join *user_ctx; const char *binding; const char *dc_binding; struct policy_handle *handle; }; __BEGIN_DECLS /* The following definitions come from samba4 framework */ struct ldb_dn *samdb_search_dn(struct ldb_context *, TALLOC_CTX *, struct ldb_dn *, const char *, ...) _PRINTF_ATTRIBUTE(4,5); struct dom_sid *dom_sid_add_rid(TALLOC_CTX *, const struct dom_sid *, uint32_t); bool encode_pw_buffer(uint8_t buffer[516], const char *, int); void arcfour_crypt_blob(uint8_t *, int, const DATA_BLOB *); /* The following public definitions come from libmapiadmin/mapiadmin.c */ struct mapiadmin_ctx *mapiadmin_init(struct mapi_session *); enum MAPISTATUS mapiadmin_release(struct mapiadmin_ctx *); /* The following public definitions come from libmapiadmin/mapiadmin_user.c */ enum MAPISTATUS mapiadmin_user_extend(struct mapiadmin_ctx *); enum MAPISTATUS mapiadmin_user_add(struct mapiadmin_ctx *); enum MAPISTATUS mapiadmin_user_del(struct mapiadmin_ctx *); enum MAPISTATUS mapiadmin_user_mod(struct mapiadmin_ctx *); __END_DECLS #define DEFAULT_PROFDB_PATH "%s/.openchange/profiles.ldb" #define MAPIADMIN_DEBUG_STR "[%s:%d]: %s %s\n", __FUNCTION__, __LINE__ #undef _PRINTF_ATTRIBUTE #define _PRINTF_ATTRIBUTE(a1, a2) #endif /* __LIBMAPIADMIN_H__ */ openchange-2.0/libmapiadmin/mapiadmin.c000066400000000000000000000033411223057412600202160ustar00rootroot00000000000000/* OpenChange Exchange Administration library. Copyright (C) Julien Kerihuel 2007. This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see . */ #include "libmapiadmin/libmapiadmin.h" /** \file Housekeeping functions for mapiadmin */ /** Create and initialise a mapiadmin_ctx structure You should use mapiadmin_release to clean up the mapiadmin_ctx structure when done. */ _PUBLIC_ struct mapiadmin_ctx *mapiadmin_init(struct mapi_session *session) { struct mapiadmin_ctx *mapiadmin_ctx; if (!session) return NULL; if (!session->profile) return NULL; mapiadmin_ctx = talloc_zero((TALLOC_CTX *)session, struct mapiadmin_ctx); mapiadmin_ctx->binding = talloc_asprintf((TALLOC_CTX *)mapiadmin_ctx, "ncacn_np:%s", session->profile->server); mapiadmin_ctx->session = session; return mapiadmin_ctx; } /** Clean up a mapiadmin_ctx structure The structure is assumed to have been allocated using mapiadmin_init() or equivalent code. */ _PUBLIC_ enum MAPISTATUS mapiadmin_release(struct mapiadmin_ctx *mapiadmin_ctx) { MAPI_RETVAL_IF(!mapiadmin_ctx, MAPI_E_NOT_INITIALIZED, NULL); talloc_free(mapiadmin_ctx); return MAPI_E_SUCCESS; } openchange-2.0/libmapiadmin/mapiadmin_user.c000066400000000000000000000460061223057412600212610ustar00rootroot00000000000000/* OpenChange Exchange Administration library. Based on the work by Andrew Tridgell, 2004 Original source code available in SAMBA_4_0: source/torture/rpc/testjoin.c Copyright (C) Julien Kerihuel 2007-2010. SAMR related code This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see . */ #include "libmapiadmin/libmapiadmin.h" #include #include #include #include #include #include #include #include #include /** \file User management functions for mapiadmin */ /** * open connection so SAMR + Join Domain * common code needed when adding or removing users */ static enum MAPISTATUS mapiadmin_samr_connect(struct mapiadmin_ctx *mapiadmin_ctx, TALLOC_CTX *mem_ctx) { NTSTATUS status; struct tevent_context *ev; struct mapi_context *mapi_ctx; struct mapi_profile *profile; struct samr_Connect c; struct samr_OpenDomain o; struct samr_LookupDomain l; struct policy_handle handle; struct policy_handle domain_handle; struct lsa_String name; MAPI_RETVAL_IF(!mapiadmin_ctx, MAPI_E_NOT_INITIALIZED, NULL); MAPI_RETVAL_IF(!mapiadmin_ctx->session, MAPI_E_NOT_INITIALIZED, NULL); MAPI_RETVAL_IF(!mapiadmin_ctx->session->profile, MAPI_E_NOT_INITIALIZED, NULL); MAPI_RETVAL_IF(!mapiadmin_ctx->session->profile->credentials, MAPI_E_NOT_INITIALIZED, NULL); MAPI_RETVAL_IF(!mapiadmin_ctx->username, MAPI_E_NOT_INITIALIZED, NULL); mapi_ctx = mapiadmin_ctx->session->mapi_ctx; MAPI_RETVAL_IF(!mapi_ctx, MAPI_E_NOT_INITIALIZED, NULL); profile = mapiadmin_ctx->session->profile; mapiadmin_ctx->user_ctx = talloc_zero(mem_ctx, struct test_join); MAPI_RETVAL_IF(!mapiadmin_ctx->user_ctx, MAPI_E_NOT_ENOUGH_RESOURCES ,NULL); DEBUG(3, ("Connecting to SAMR\n")); ev = tevent_context_init(mem_ctx); status = dcerpc_pipe_connect(mapiadmin_ctx->user_ctx, &mapiadmin_ctx->user_ctx->p, mapiadmin_ctx->dc_binding ? mapiadmin_ctx->dc_binding : mapiadmin_ctx->binding, &ndr_table_samr, profile->credentials, ev, mapi_ctx->lp_ctx); MAPI_RETVAL_IF(!NT_STATUS_IS_OK(status), MAPI_E_CALL_FAILED, NULL); profile = mapiadmin_ctx->session->profile; c.in.system_name = NULL; c.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED; c.out.connect_handle = &handle; status = dcerpc_samr_Connect_r(mapiadmin_ctx->user_ctx->p->binding_handle, mapiadmin_ctx->user_ctx, &c); if (!NT_STATUS_IS_OK(status)) { const char *errstr = nt_errstr(status); if (NT_STATUS_EQUAL(status, NT_STATUS_NET_WRITE_FAULT)) { errstr = dcerpc_errstr(mapiadmin_ctx->user_ctx, mapiadmin_ctx->user_ctx->p->last_fault_code); } DEBUG(3, ("samr_Connect failed - %s\n", errstr)); return MAPI_E_CALL_FAILED; } DEBUG(3, ("Opening domain %s\n", profile->domain)); name.string = profile->domain; l.in.connect_handle = &handle; l.in.domain_name = &name; l.out.sid = talloc(mem_ctx, struct dom_sid2 *); talloc_steal(mapiadmin_ctx->user_ctx, l.out.sid); status = dcerpc_samr_LookupDomain_r(mapiadmin_ctx->user_ctx->p->binding_handle, mapiadmin_ctx->user_ctx, &l); if (!NT_STATUS_IS_OK(status)) { DEBUG(3, ("LookupDomain failed - %s\n", nt_errstr(status))); return MAPI_E_CALL_FAILED; } mapiadmin_ctx->user_ctx->dom_sid = *l.out.sid; mapiadmin_ctx->user_ctx->dom_netbios_name = talloc_strdup(mapiadmin_ctx->user_ctx, profile->domain); if (!mapiadmin_ctx->user_ctx->dom_netbios_name) return MAPI_E_CALL_FAILED; o.in.connect_handle = &handle; o.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED; o.in.sid = *l.out.sid; o.out.domain_handle = &domain_handle; status = dcerpc_samr_OpenDomain_r(mapiadmin_ctx->user_ctx->p->binding_handle, mapiadmin_ctx->user_ctx, &o); if (!NT_STATUS_IS_OK(status)) { DEBUG(3, ("OpenDomain failed - %s\n", nt_errstr(status))); return MAPI_E_CALL_FAILED; } mapiadmin_ctx->handle = talloc_memdup(mem_ctx, &domain_handle, sizeof (struct policy_handle)); errno = 0; return MAPI_E_SUCCESS; } struct tce_async_context { int found; }; static int tce_search_callback(struct ldb_request *req, struct ldb_reply *ares) { struct tce_async_context *actx = talloc_get_type(req->context, struct tce_async_context); switch (ares->type) { case LDB_REPLY_ENTRY: if (ldb_msg_find_element(ares->message, "msExchMailboxGuid") != NULL) { DEBUG(3, ("[%s:%d]: msExchMailboxGuid found!\n", __FUNCTION__, __LINE__)); actx->found = 1; talloc_free(ares); return ldb_request_done(req, LDB_SUCCESS); } break; case LDB_REPLY_DONE: break; default: DEBUG(3, ("[%s:%d]: unknown Reply Type ignore it\n", __FUNCTION__, __LINE__)); talloc_free(ares); return LDB_ERR_OTHER; } if (talloc_free(ares) == -1) { DEBUG(3, ("[%s:%d]: talloc_free failed\n", __FUNCTION__, __LINE__)); return LDB_ERR_OPERATIONS_ERROR; } return LDB_SUCCESS; } /** * Extend user attributes to be Exchange user */ _PUBLIC_ enum MAPISTATUS mapiadmin_user_extend(struct mapiadmin_ctx *mapiadmin_ctx) { TALLOC_CTX *mem_ctx; enum MAPISTATUS retval; struct tevent_context *ev = NULL; struct mapi_context *mapi_ctx; struct mapi_profile *profile; struct ldb_context *remote_ldb; struct ldb_request *req; struct ldb_message *msg; struct ldb_result *res; struct ldb_control **controls; const char *control_strings[2] = { "notification:0", NULL }; struct tce_async_context *tce_ctx; const struct dom_sid *dom_sid; char *remote_ldb_url; const char * const dom_attrs[] = { "*", NULL }; int ret; uint32_t count; char **values; const char *exch_attrs[7]; uint32_t i; char *realm = NULL; char *org = NULL; const char *UserAccountControl; struct ldb_dn *account_dn; /* Sanity checks */ MAPI_RETVAL_IF(!mapiadmin_ctx, MAPI_E_NOT_INITIALIZED, NULL); MAPI_RETVAL_IF(!mapiadmin_ctx->session, MAPI_E_NOT_INITIALIZED, NULL); MAPI_RETVAL_IF(!mapiadmin_ctx->session->profile, MAPI_E_NOT_INITIALIZED, NULL); MAPI_RETVAL_IF(!mapiadmin_ctx->session->profile->credentials, MAPI_E_NOT_INITIALIZED, NULL); MAPI_RETVAL_IF(!mapiadmin_ctx->user_ctx, MAPI_E_NOT_INITIALIZED, NULL); mapi_ctx = mapiadmin_ctx->session->mapi_ctx; MAPI_RETVAL_IF(!mapi_ctx, MAPI_E_NOT_INITIALIZED, NULL); profile = mapiadmin_ctx->session->profile; dom_sid = mapiadmin_ctx->user_ctx->user_sid; /* initialize memory context */ mem_ctx = talloc_named((TALLOC_CTX *)mapiadmin_ctx, 0, "mapiadmin_user_extend"); /* open LDAP connection */ ev = tevent_context_init(mem_ctx); remote_ldb_url = talloc_asprintf(mem_ctx, "ldap://%s", profile->server); MAPI_RETVAL_IF(!remote_ldb_url, MAPI_E_CORRUPT_DATA, mem_ctx); remote_ldb = ldb_wrap_connect(mem_ctx, ev, mapi_ctx->lp_ctx, remote_ldb_url, NULL, mapiadmin_ctx->session->profile->credentials, 0); MAPI_RETVAL_IF(!remote_ldb, MAPI_E_NETWORK_ERROR, mem_ctx); /* Search the user_dn */ account_dn = samdb_search_dn(remote_ldb, mem_ctx, NULL, "(&(objectSid=%s)(objectClass=user))", ldap_encode_ndr_dom_sid(mem_ctx, dom_sid)); ret = ldb_search(remote_ldb, mem_ctx, &res, account_dn, LDB_SCOPE_SUBTREE, dom_attrs, "(objectSid=%s)", ldap_encode_ndr_dom_sid(mem_ctx, dom_sid)); MAPI_RETVAL_IF(ret != LDB_SUCCESS, MAPI_E_NOT_FOUND, mem_ctx); MAPI_RETVAL_IF(res->count != 1, MAPI_E_NOT_FOUND, mem_ctx); /* Prepare a new message for modify */ msg = ldb_msg_new(mem_ctx); MAPI_RETVAL_IF(!msg, MAPI_E_NOT_ENOUGH_RESOURCES, mem_ctx); msg->dn = res->msgs[0]->dn; /* message: givenName */ exch_attrs[0] = talloc_strdup(mem_ctx, mapiadmin_ctx->username); ret = ldb_msg_add_string(msg, "givenName", exch_attrs[0]); MAPI_RETVAL_IF((ret == -1), MAPI_E_NOT_ENOUGH_RESOURCES, mem_ctx); /* message: userAccountControl */ exch_attrs[1] = talloc_asprintf(mem_ctx, "513"); ret = ldb_msg_add_string(msg, "userAccountControl", exch_attrs[1]); MAPI_RETVAL_IF((ret == -1), MAPI_E_NOT_ENOUGH_RESOURCES, mem_ctx); msg->elements[1].flags = LDB_FLAG_MOD_REPLACE; /* message: mail */ retval = GetProfileAttr(profile, "ProxyAddress", &count, &values); MAPI_RETVAL_IF(retval, retval, mem_ctx); for (i = 0; i < count; i++) { if (values[i] && !strncasecmp("smtp", values[i], 4)) { realm = strchr(values[i], '@'); realm += 1; } } MAPI_RETVAL_IF(!realm, MAPI_E_NOT_FOUND, mem_ctx); exch_attrs[2] = talloc_asprintf(mem_ctx, "%s@%s", mapiadmin_ctx->username, realm); ret = ldb_msg_add_string(msg, "mail", exch_attrs[2]); MAPI_RETVAL_IF((ret == -1), MAPI_E_NOT_ENOUGH_RESOURCES, mem_ctx); /* message: mailNickname */ exch_attrs[3] = talloc_strdup(mem_ctx, mapiadmin_ctx->username); ret = ldb_msg_add_string(msg, "mailNickname", exch_attrs[3]); MAPI_RETVAL_IF((ret == -1), MAPI_E_NOT_ENOUGH_RESOURCES, mem_ctx); /* message: mDBUseDefaults */ exch_attrs[4] = talloc_asprintf(mem_ctx, "TRUE"); ret = ldb_msg_add_string(msg, "mDBUseDefaults", exch_attrs[4]); MAPI_RETVAL_IF((ret == -1), MAPI_E_NOT_ENOUGH_RESOURCES, mem_ctx); /* message: legacyExchangeDN */ org = talloc_strndup(mem_ctx, profile->mailbox, strlen(profile->mailbox) - strlen(profile->username)); exch_attrs[5] = talloc_asprintf(mem_ctx, "%s%s", org, mapiadmin_ctx->username); talloc_free(org); ret = ldb_msg_add_string(msg, "legacyExchangeDN", exch_attrs[5]); MAPI_RETVAL_IF((ret == -1), MAPI_E_NOT_ENOUGH_RESOURCES, mem_ctx); /* message: msExchHomeServerName */ exch_attrs[6] = talloc_strdup(mem_ctx, profile->homemdb); ret = ldb_msg_add_string(msg, "msExchHomeServerName", exch_attrs[6]); MAPI_RETVAL_IF((ret == -1), MAPI_E_NOT_ENOUGH_RESOURCES, mem_ctx); /* Prior we call ldb_modify, set up async ldb request on * msExchMailboxGuid */ req = talloc_zero(mem_ctx, struct ldb_request); tce_ctx = talloc_zero(mem_ctx, struct tce_async_context); controls = ldb_parse_control_strings(remote_ldb, mem_ctx, control_strings); ret = ldb_build_search_req(&req, remote_ldb, mem_ctx, msg->dn, LDB_SCOPE_BASE, "(objectclass=*)", NULL, controls, (void *)tce_ctx, tce_search_callback, NULL); DEBUG(3, (MAPIADMIN_DEBUG_STR, "ldb_build_search_req", ldb_strerror(ret))); MAPI_RETVAL_IF((ret != LDB_SUCCESS), MAPI_E_CALL_FAILED, mem_ctx); ldb_set_timeout(mem_ctx, req, 60); ret = ldb_request(remote_ldb, req); DEBUG(3, (MAPIADMIN_DEBUG_STR, "ldb_request", ldb_strerror(ret))); MAPI_RETVAL_IF((ret != LDB_SUCCESS), MAPI_E_CALL_FAILED, mem_ctx); ret = ldb_modify(remote_ldb, msg); DEBUG(3, (MAPIADMIN_DEBUG_STR, "ldb_modify", ldb_strerror(ret))); MAPI_RETVAL_IF((ret != LDB_SUCCESS), MAPI_E_CORRUPT_DATA, mem_ctx); /* async search */ ret = ldb_wait(req->handle, LDB_WAIT_ALL); DEBUG(3, (MAPIADMIN_DEBUG_STR, "ldb_wait", ldb_strerror(ret))); MAPI_RETVAL_IF((ret != LDB_SUCCESS), MAPI_E_CALL_FAILED, mem_ctx); MAPI_RETVAL_IF(!tce_ctx->found, MAPI_E_CALL_FAILED, mem_ctx); /* When successful replace UserAccountControl attr in the user * record */ talloc_free(msg); msg = ldb_msg_new(mem_ctx); MAPI_RETVAL_IF(!msg, MAPI_E_NOT_ENOUGH_RESOURCES, mem_ctx); msg->dn = res->msgs[0]->dn; UserAccountControl = talloc_asprintf(mem_ctx, "66048"); ret = ldb_msg_add_string(msg, "UserAccountControl", UserAccountControl); MAPI_RETVAL_IF((ret == -1), MAPI_E_NOT_ENOUGH_RESOURCES, mem_ctx); msg->elements[0].flags = LDB_FLAG_MOD_REPLACE; ret = ldb_modify(remote_ldb, msg); DEBUG(3, (MAPIADMIN_DEBUG_STR, "ldb_modify", ldb_strerror(ret))); MAPI_RETVAL_IF((ret != LDB_SUCCESS), MAPI_E_CORRUPT_DATA, mem_ctx); /* reset errno before leaving */ errno = 0; talloc_free(mem_ctx); return MAPI_E_SUCCESS; } /** * Add a user to Active Directory */ _PUBLIC_ enum MAPISTATUS mapiadmin_user_add(struct mapiadmin_ctx *mapiadmin_ctx) { TALLOC_CTX *mem_ctx; NTSTATUS status; enum MAPISTATUS retval; struct mapi_context *mapi_ctx; struct samr_CreateUser2 r; struct samr_GetUserPwInfo pwp; struct samr_SetUserInfo s; union samr_UserInfo u; uint32_t access_granted; uint32_t rid; DATA_BLOB session_key; struct lsa_String name; int policy_min_pw_len = 0; mem_ctx = talloc_named(NULL, 0, "mapiadmin_user_add"); retval = mapiadmin_samr_connect(mapiadmin_ctx, mem_ctx); MAPI_RETVAL_IF(retval, retval, mem_ctx); DEBUG(3, ("Creating account %s\n", mapiadmin_ctx->username)); mapi_ctx = mapiadmin_ctx->session->mapi_ctx; MAPI_RETVAL_IF(!mapi_ctx, MAPI_E_NOT_INITIALIZED, mem_ctx); again: name.string = mapiadmin_ctx->username; r.in.domain_handle = mapiadmin_ctx->handle; r.in.account_name = &name; r.in.acct_flags = ACB_NORMAL; r.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED; r.out.user_handle = &mapiadmin_ctx->user_ctx->user_handle; r.out.access_granted = &access_granted; r.out.rid = &rid; status = dcerpc_samr_CreateUser2_r(mapiadmin_ctx->user_ctx->p->binding_handle, mapiadmin_ctx->user_ctx, &r); if (NT_STATUS_EQUAL(status, NT_STATUS_USER_EXISTS)) { mapiadmin_user_del(mapiadmin_ctx); if (NT_STATUS_IS_OK(status)) { goto again; } else { MAPI_RETVAL_IF(1,MAPI_E_CALL_FAILED,mem_ctx); } } if (!NT_STATUS_IS_OK(status)) { DEBUG(3, ("CreateUser2 failed - %s\n", nt_errstr(status))); MAPI_RETVAL_IF(1,MAPI_E_CALL_FAILED,mem_ctx); } mapiadmin_ctx->user_ctx->user_sid = dom_sid_add_rid(mapiadmin_ctx->user_ctx, mapiadmin_ctx->user_ctx->dom_sid, rid); pwp.in.user_handle = &mapiadmin_ctx->user_ctx->user_handle; pwp.out.info = talloc_zero(mem_ctx, struct samr_PwInfo); status = dcerpc_samr_GetUserPwInfo_r(mapiadmin_ctx->user_ctx->p->binding_handle, mapiadmin_ctx->user_ctx, &pwp); if (NT_STATUS_IS_OK(status)) { policy_min_pw_len = pwp.out.info->min_password_length; } else { DEBUG(3, ("GetUserPwInfo failed - %s\n", nt_errstr(status))); MAPI_RETVAL_IF(1,MAPI_E_CALL_FAILED,mem_ctx); } if (!mapiadmin_ctx->password) { mapiadmin_ctx->password = generate_random_str(mapiadmin_ctx->user_ctx, MAX(8, policy_min_pw_len)); } DEBUG(3, ("Setting account password '%s'\n", mapiadmin_ctx->password)); ZERO_STRUCT(u); s.in.user_handle = &mapiadmin_ctx->user_ctx->user_handle; s.in.info = &u; s.in.level = 24; encode_pw_buffer(u.info24.password.data, mapiadmin_ctx->password, STR_UNICODE); u.info24.password_expired = 0; status = dcerpc_fetch_session_key(mapiadmin_ctx->user_ctx->p, &session_key); if (!NT_STATUS_IS_OK(status)) { DEBUG(3, ("SetUserInfo level %d - no session key - %s\n", s.in.level, nt_errstr(status))); mapiadmin_user_del(mapiadmin_ctx); MAPI_RETVAL_IF(1,MAPI_E_CALL_FAILED,mem_ctx); } arcfour_crypt_blob(u.info24.password.data, 516, &session_key); status = dcerpc_samr_SetUserInfo_r(mapiadmin_ctx->user_ctx->p->binding_handle, mapiadmin_ctx->user_ctx, &s); if (!NT_STATUS_IS_OK(status)) { DEBUG(3, ("SetUserInfo failed - %s\n", nt_errstr(status))); if (NT_STATUS_EQUAL(status, NT_STATUS_PASSWORD_RESTRICTION)) { MAPI_RETVAL_IF(1, MAPI_E_BAD_VALUE, mem_ctx); } else { MAPI_RETVAL_IF(1, MAPI_E_CALL_FAILED, mem_ctx); } } ZERO_STRUCT(u); s.in.user_handle = &mapiadmin_ctx->user_ctx->user_handle; s.in.info = &u; s.in.level = 21; u.info21.acct_flags = ACB_NORMAL | ACB_PWNOEXP; u.info21.fields_present = SAMR_FIELD_ACCT_FLAGS | SAMR_FIELD_DESCRIPTION | SAMR_FIELD_COMMENT | SAMR_FIELD_FULL_NAME; u.info21.comment.string = talloc_asprintf(mapiadmin_ctx->user_ctx, mapiadmin_ctx->comment ? mapiadmin_ctx->comment : "Created by OpenChange: %s", timestring(mapiadmin_ctx->user_ctx, time(NULL))); u.info21.full_name.string = talloc_asprintf(mapiadmin_ctx->user_ctx, mapiadmin_ctx->fullname ? mapiadmin_ctx->fullname : "Account for OpenChange: %s", timestring(mapiadmin_ctx->user_ctx, time(NULL))); u.info21.description.string = talloc_asprintf(mapiadmin_ctx->user_ctx, mapiadmin_ctx->description ? mapiadmin_ctx->description : "OpenChange account created by host %s: %s", lpcfg_netbios_name(mapi_ctx->lp_ctx), timestring(mapiadmin_ctx->user_ctx, time(NULL))); DEBUG(3, ("Resetting ACB flags, force pw change time\n")); status = dcerpc_samr_SetUserInfo_r(mapiadmin_ctx->user_ctx->p->binding_handle, mapiadmin_ctx->user_ctx, &s); if (!NT_STATUS_IS_OK(status)) { DEBUG(3, ("SetUserInfo failed - %s\n", nt_errstr(status))); MAPI_RETVAL_IF(1, MAPI_E_CALL_FAILED, mem_ctx); } retval = mapiadmin_user_extend(mapiadmin_ctx); if (retval != MAPI_E_SUCCESS) { DEBUG(3, ("mapiadmin_user_extend: 0x%x\n", GetLastError())); mapiadmin_user_del(mapiadmin_ctx); MAPI_RETVAL_IF(1, MAPI_E_CALL_FAILED,mem_ctx); } talloc_free(mem_ctx); return MAPI_E_SUCCESS; } /** * Delete a user from Active Directory */ _PUBLIC_ enum MAPISTATUS mapiadmin_user_del(struct mapiadmin_ctx *mapiadmin_ctx) { TALLOC_CTX *mem_ctx; enum MAPISTATUS retval; NTSTATUS status; struct samr_DeleteUser d; struct policy_handle user_handle; uint32_t rid; struct samr_LookupNames n; struct lsa_String sname; struct samr_OpenUser r; MAPI_RETVAL_IF(!mapiadmin_ctx, MAPI_E_NOT_INITIALIZED, NULL); MAPI_RETVAL_IF(!mapiadmin_ctx->username, MAPI_E_NOT_INITIALIZED, NULL); mem_ctx = talloc_named(NULL, 0, "mapiadmin_user_del"); /* Initiate SAMR connection if not already done */ if (!mapiadmin_ctx->user_ctx) { retval = mapiadmin_samr_connect(mapiadmin_ctx, mem_ctx); MAPI_RETVAL_IF(retval, GetLastError(), mem_ctx); } sname.string = mapiadmin_ctx->username; n.in.domain_handle = mapiadmin_ctx->handle; n.in.num_names = 1; n.in.names = &sname; n.out.rids = talloc_zero(mem_ctx, struct samr_Ids); n.out.types = talloc_zero(mem_ctx, struct samr_Ids); status = dcerpc_samr_LookupNames_r(mapiadmin_ctx->user_ctx->p->binding_handle, mem_ctx, &n); if (NT_STATUS_IS_OK(status)) { rid = n.out.rids->ids[0]; } else { talloc_free(mem_ctx); return MAPI_E_NOT_FOUND; } r.in.domain_handle = mapiadmin_ctx->handle; r.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED; r.in.rid = rid; r.out.user_handle = &user_handle; status = dcerpc_samr_OpenUser_r(mapiadmin_ctx->user_ctx->p->binding_handle, mem_ctx, &r); if (!NT_STATUS_IS_OK(status)) { DEBUG(3, ("OpenUser(%s) failed - %s\n", mapiadmin_ctx->username, nt_errstr(status))); MAPI_RETVAL_IF(!NT_STATUS_IS_OK(status), MAPI_E_NOT_FOUND, mem_ctx); } d.in.user_handle = &user_handle; d.out.user_handle = &user_handle; status = dcerpc_samr_DeleteUser_r(mapiadmin_ctx->user_ctx->p->binding_handle, mem_ctx, &d); MAPI_RETVAL_IF(!NT_STATUS_IS_OK(status), MAPI_E_CALL_FAILED, mem_ctx); talloc_free(mem_ctx); return MAPI_E_SUCCESS; } _PUBLIC_ enum MAPISTATUS mapiadmin_user_mod(struct mapiadmin_ctx *mapiadmin) { return MAPI_E_NO_SUPPORT; } openchange-2.0/libocpf.pc.in000066400000000000000000000004431223057412600160340ustar00rootroot00000000000000prefix=@prefix@ exec_prefix=@exec_prefix@ libdir=@libdir@ includedir=@includedir@ datarootdir=@prefix@/share datadir=@datadir@ Name: OpenChange Property File Description: OCPF file format support Version: @PACKAGE_VERSION@ Libs: -L${libdir} -locpf Cflags: -I${includedir} Requires: libmapi openchange-2.0/libocpf/000077500000000000000000000000001223057412600151025ustar00rootroot00000000000000openchange-2.0/libocpf/Doxyfile.in000066400000000000000000001471761223057412600172350ustar00rootroot00000000000000# Doxyfile 1.5.2 # This file describes the settings to be used by the documentation system # doxygen (www.doxygen.org) for a project # # All text after a hash (#) is considered a comment and will be ignored # The format is: # TAG = value [value, ...] # For lists items can also be appended using: # TAG += value [value, ...] # Values that contain spaces should be placed between quotes (" ") #--------------------------------------------------------------------------- # Project related configuration options #--------------------------------------------------------------------------- # This tag specifies the encoding used for all characters in the config file that # follow. The default is UTF-8 which is also the encoding used for all text before # the first occurrence of this tag. Doxygen uses libiconv (or the iconv built into # libc) for the transcoding. See http://www.gnu.org/software/libiconv for the list of # possible encodings. DOXYFILE_ENCODING = UTF-8 # The PROJECT_NAME tag is a single word (or a sequence of words surrounded # by quotes) that should identify the project. PROJECT_NAME = "OpenChange Property Files" # The PROJECT_NUMBER tag can be used to enter a project or revision number. # This could be handy for archiving the generated documentation or # if some version control system is used. PROJECT_NUMBER = @PACKAGE_VERSION@ # The OUTPUT_DIRECTORY tag is used to specify the (relative or absolute) # base path where the generated documentation will be put. # If a relative path is entered, it will be relative to the location # where doxygen was started. If left blank the current directory will be used. OUTPUT_DIRECTORY = apidocs # If the CREATE_SUBDIRS tag is set to YES, then doxygen will create # 4096 sub-directories (in 2 levels) under the output directory of each output # format and will distribute the generated files over these directories. # Enabling this option can be useful when feeding doxygen a huge amount of # source files, where putting all generated files in the same directory would # otherwise cause performance problems for the file system. CREATE_SUBDIRS = NO # The OUTPUT_LANGUAGE tag is used to specify the language in which all # documentation generated by doxygen is written. Doxygen will use this # information to generate all constant output in the proper language. # The default language is English, other supported languages are: # Afrikaans, Arabic, Brazilian, Catalan, Chinese, Chinese-Traditional, # Croatian, Czech, Danish, Dutch, Finnish, French, German, Greek, Hungarian, # Italian, Japanese, Japanese-en (Japanese with English messages), Korean, # Korean-en, Lithuanian, Norwegian, Polish, Portuguese, Romanian, Russian, # Serbian, Slovak, Slovene, Spanish, Swedish, and Ukrainian. OUTPUT_LANGUAGE = English # If the BRIEF_MEMBER_DESC tag is set to YES (the default) Doxygen will # include brief member descriptions after the members that are listed in # the file and class documentation (similar to JavaDoc). # Set to NO to disable this. BRIEF_MEMBER_DESC = YES # If the REPEAT_BRIEF tag is set to YES (the default) Doxygen will prepend # the brief description of a member or function before the detailed description. # Note: if both HIDE_UNDOC_MEMBERS and BRIEF_MEMBER_DESC are set to NO, the # brief descriptions will be completely suppressed. REPEAT_BRIEF = YES # This tag implements a quasi-intelligent brief description abbreviator # that is used to form the text in various listings. Each string # in this list, if found as the leading text of the brief description, will be # stripped from the text and the result after processing the whole list, is # used as the annotated text. Otherwise, the brief description is used as-is. # If left blank, the following values are used ("$name" is automatically # replaced with the name of the entity): "The $name class" "The $name widget" # "The $name file" "is" "provides" "specifies" "contains" # "represents" "a" "an" "the" ABBREVIATE_BRIEF = # If the ALWAYS_DETAILED_SEC and REPEAT_BRIEF tags are both set to YES then # Doxygen will generate a detailed section even if there is only a brief # description. ALWAYS_DETAILED_SEC = NO # If the INLINE_INHERITED_MEMB tag is set to YES, doxygen will show all # inherited members of a class in the documentation of that class as if those # members were ordinary class members. Constructors, destructors and assignment # operators of the base classes will not be shown. INLINE_INHERITED_MEMB = NO # If the FULL_PATH_NAMES tag is set to YES then Doxygen will prepend the full # path before files name in the file list and in the header files. If set # to NO the shortest path that makes the file name unique will be used. FULL_PATH_NAMES = YES # If the FULL_PATH_NAMES tag is set to YES then the STRIP_FROM_PATH tag # can be used to strip a user-defined part of the path. Stripping is # only done if one of the specified strings matches the left-hand part of # the path. The tag can be used to show relative paths in the file list. # If left blank the directory from which doxygen is run is used as the # path to strip. STRIP_FROM_PATH = # The STRIP_FROM_INC_PATH tag can be used to strip a user-defined part of # the path mentioned in the documentation of a class, which tells # the reader which header file to include in order to use a class. # If left blank only the name of the header file containing the class # definition is used. Otherwise one should specify the include paths that # are normally passed to the compiler using the -I flag. STRIP_FROM_INC_PATH = # If the SHORT_NAMES tag is set to YES, doxygen will generate much shorter # (but less readable) file names. This can be useful is your file systems # doesn't support long names like on DOS, Mac, or CD-ROM. SHORT_NAMES = NO # If the JAVADOC_AUTOBRIEF tag is set to YES then Doxygen # will interpret the first line (until the first dot) of a JavaDoc-style # comment as the brief description. If set to NO, the JavaDoc # comments will behave just like the Qt-style comments (thus requiring an # explicit @brief command for a brief description. JAVADOC_AUTOBRIEF = YES # The MULTILINE_CPP_IS_BRIEF tag can be set to YES to make Doxygen # treat a multi-line C++ special comment block (i.e. a block of //! or /// # comments) as a brief description. This used to be the default behaviour. # The new default is to treat a multi-line C++ comment block as a detailed # description. Set this tag to YES if you prefer the old behaviour instead. MULTILINE_CPP_IS_BRIEF = NO # If the INHERIT_DOCS tag is set to YES (the default) then an undocumented # member inherits the documentation from any documented member that it # re-implements. INHERIT_DOCS = YES # If the SEPARATE_MEMBER_PAGES tag is set to YES, then doxygen will produce # a new page for each member. If set to NO, the documentation of a member will # be part of the file/class/namespace that contains it. SEPARATE_MEMBER_PAGES = NO # The TAB_SIZE tag can be used to set the number of spaces in a tab. # Doxygen uses this value to replace tabs by spaces in code fragments. TAB_SIZE = 8 # This tag can be used to specify a number of aliases that acts # as commands in the documentation. An alias has the form "name=value". # For example adding "sideeffect=\par Side Effects:\n" will allow you to # put the command \sideeffect (or @sideeffect) in the documentation, which # will result in a user-defined paragraph with heading "Side Effects:". # You can put \n's in the value part of an alias to insert newlines. ALIASES = # Set the OPTIMIZE_OUTPUT_FOR_C tag to YES if your project consists of C # sources only. Doxygen will then generate output that is more tailored for C. # For instance, some of the names that are used will be different. The list # of all members will be omitted, etc. OPTIMIZE_OUTPUT_FOR_C = YES # Set the OPTIMIZE_OUTPUT_JAVA tag to YES if your project consists of Java # sources only. Doxygen will then generate output that is more tailored for Java. # For instance, namespaces will be presented as packages, qualified scopes # will look different, etc. OPTIMIZE_OUTPUT_JAVA = NO # If you use STL classes (i.e. std::string, std::vector, etc.) but do not want to # include (a tag file for) the STL sources as input, then you should # set this tag to YES in order to let doxygen match functions declarations and # definitions whose arguments contain STL classes (e.g. func(std::string); v.s. # func(std::string) {}). This also make the inheritance and collaboration # diagrams that involve STL classes more complete and accurate. BUILTIN_STL_SUPPORT = NO # If you use Microsoft's C++/CLI language, you should set this option to YES to # enable parsing support. CPP_CLI_SUPPORT = NO # If member grouping is used in the documentation and the DISTRIBUTE_GROUP_DOC # tag is set to YES, then doxygen will reuse the documentation of the first # member in the group (if any) for the other members of the group. By default # all members of a group must be documented explicitly. DISTRIBUTE_GROUP_DOC = NO # Set the SUBGROUPING tag to YES (the default) to allow class member groups of # the same type (for instance a group of public functions) to be put as a # subgroup of that type (e.g. under the Public Functions section). Set it to # NO to prevent subgrouping. Alternatively, this can be done per class using # the \nosubgrouping command. SUBGROUPING = YES #--------------------------------------------------------------------------- # Build related configuration options #--------------------------------------------------------------------------- # If the EXTRACT_ALL tag is set to YES doxygen will assume all entities in # documentation are documented, even if no documentation was available. # Private class members and static file members will be hidden unless # the EXTRACT_PRIVATE and EXTRACT_STATIC tags are set to YES EXTRACT_ALL = NO # If the EXTRACT_PRIVATE tag is set to YES all private members of a class # will be included in the documentation. EXTRACT_PRIVATE = NO # If the EXTRACT_STATIC tag is set to YES all static members of a file # will be included in the documentation. EXTRACT_STATIC = NO # If the EXTRACT_LOCAL_CLASSES tag is set to YES classes (and structs) # defined locally in source files will be included in the documentation. # If set to NO only classes defined in header files are included. EXTRACT_LOCAL_CLASSES = NO # This flag is only useful for Objective-C code. When set to YES local # methods, which are defined in the implementation section but not in # the interface are included in the documentation. # If set to NO (the default) only methods in the interface are included. EXTRACT_LOCAL_METHODS = NO # If the HIDE_UNDOC_MEMBERS tag is set to YES, Doxygen will hide all # undocumented members of documented classes, files or namespaces. # If set to NO (the default) these members will be included in the # various overviews, but no documentation section is generated. # This option has no effect if EXTRACT_ALL is enabled. HIDE_UNDOC_MEMBERS = YES # If the HIDE_UNDOC_CLASSES tag is set to YES, Doxygen will hide all # undocumented classes that are normally visible in the class hierarchy. # If set to NO (the default) these classes will be included in the various # overviews. This option has no effect if EXTRACT_ALL is enabled. HIDE_UNDOC_CLASSES = YES # If the HIDE_FRIEND_COMPOUNDS tag is set to YES, Doxygen will hide all # friend (class|struct|union) declarations. # If set to NO (the default) these declarations will be included in the # documentation. HIDE_FRIEND_COMPOUNDS = YES # If the HIDE_IN_BODY_DOCS tag is set to YES, Doxygen will hide any # documentation blocks found inside the body of a function. # If set to NO (the default) these blocks will be appended to the # function's detailed documentation block. HIDE_IN_BODY_DOCS = NO # The INTERNAL_DOCS tag determines if documentation # that is typed after a \internal command is included. If the tag is set # to NO (the default) then the documentation will be excluded. # Set it to YES to include the internal documentation. INTERNAL_DOCS = NO # If the CASE_SENSE_NAMES tag is set to NO then Doxygen will only generate # file names in lower-case letters. If set to YES upper-case letters are also # allowed. This is useful if you have classes or files whose names only differ # in case and if your file system supports case sensitive file names. Windows # and Mac users are advised to set this option to NO. CASE_SENSE_NAMES = YES # If the HIDE_SCOPE_NAMES tag is set to NO (the default) then Doxygen # will show members with their full class and namespace scopes in the # documentation. If set to YES the scope will be hidden. HIDE_SCOPE_NAMES = NO # If the SHOW_INCLUDE_FILES tag is set to YES (the default) then Doxygen # will put a list of the files that are included by a file in the documentation # of that file. SHOW_INCLUDE_FILES = YES # If the INLINE_INFO tag is set to YES (the default) then a tag [inline] # is inserted in the documentation for inline members. INLINE_INFO = YES # If the SORT_MEMBER_DOCS tag is set to YES (the default) then doxygen # will sort the (detailed) documentation of file and class members # alphabetically by member name. If set to NO the members will appear in # declaration order. SORT_MEMBER_DOCS = YES # If the SORT_BRIEF_DOCS tag is set to YES then doxygen will sort the # brief documentation of file, namespace and class members alphabetically # by member name. If set to NO (the default) the members will appear in # declaration order. SORT_BRIEF_DOCS = YES # If the SORT_BY_SCOPE_NAME tag is set to YES, the class list will be # sorted by fully-qualified names, including namespaces. If set to # NO (the default), the class list will be sorted only by class name, # not including the namespace part. # Note: This option is not very useful if HIDE_SCOPE_NAMES is set to YES. # Note: This option applies only to the class list, not to the # alphabetical list. SORT_BY_SCOPE_NAME = NO # The GENERATE_TODOLIST tag can be used to enable (YES) or # disable (NO) the todo list. This list is created by putting \todo # commands in the documentation. GENERATE_TODOLIST = YES # The GENERATE_TESTLIST tag can be used to enable (YES) or # disable (NO) the test list. This list is created by putting \test # commands in the documentation. GENERATE_TESTLIST = YES # The GENERATE_BUGLIST tag can be used to enable (YES) or # disable (NO) the bug list. This list is created by putting \bug # commands in the documentation. GENERATE_BUGLIST = YES # The GENERATE_DEPRECATEDLIST tag can be used to enable (YES) or # disable (NO) the deprecated list. This list is created by putting # \deprecated commands in the documentation. GENERATE_DEPRECATEDLIST= YES # The ENABLED_SECTIONS tag can be used to enable conditional # documentation sections, marked by \if sectionname ... \endif. ENABLED_SECTIONS = # The MAX_INITIALIZER_LINES tag determines the maximum number of lines # the initial value of a variable or define consists of for it to appear in # the documentation. If the initializer consists of more lines than specified # here it will be hidden. Use a value of 0 to hide initializers completely. # The appearance of the initializer of individual variables and defines in the # documentation can be controlled using \showinitializer or \hideinitializer # command in the documentation regardless of this setting. MAX_INITIALIZER_LINES = 30 # Set the SHOW_USED_FILES tag to NO to disable the list of files generated # at the bottom of the documentation of classes and structs. If set to YES the # list will mention the files that were used to generate the documentation. SHOW_USED_FILES = YES # If the sources in your project are distributed over multiple directories # then setting the SHOW_DIRECTORIES tag to YES will show the directory hierarchy # in the documentation. The default is NO. SHOW_DIRECTORIES = NO # The FILE_VERSION_FILTER tag can be used to specify a program or script that # doxygen should invoke to get the current version for each file (typically from the # version control system). Doxygen will invoke the program by executing (via # popen()) the command , where is the value of # the FILE_VERSION_FILTER tag, and is the name of an input file # provided by doxygen. Whatever the program writes to standard output # is used as the file version. See the manual for examples. FILE_VERSION_FILTER = #--------------------------------------------------------------------------- # configuration options related to warning and progress messages #--------------------------------------------------------------------------- # The QUIET tag can be used to turn on/off the messages that are generated # by doxygen. Possible values are YES and NO. If left blank NO is used. QUIET = NO # The WARNINGS tag can be used to turn on/off the warning messages that are # generated by doxygen. Possible values are YES and NO. If left blank # NO is used. WARNINGS = YES # If WARN_IF_UNDOCUMENTED is set to YES, then doxygen will generate warnings # for undocumented members. If EXTRACT_ALL is set to YES then this flag will # automatically be disabled. WARN_IF_UNDOCUMENTED = YES # If WARN_IF_DOC_ERROR is set to YES, doxygen will generate warnings for # potential errors in the documentation, such as not documenting some # parameters in a documented function, or documenting parameters that # don't exist or using markup commands wrongly. WARN_IF_DOC_ERROR = YES # This WARN_NO_PARAMDOC option can be abled to get warnings for # functions that are documented, but have no documentation for their parameters # or return value. If set to NO (the default) doxygen will only warn about # wrong or incomplete parameter documentation, but not about the absence of # documentation. WARN_NO_PARAMDOC = NO # The WARN_FORMAT tag determines the format of the warning messages that # doxygen can produce. The string should contain the $file, $line, and $text # tags, which will be replaced by the file and line number from which the # warning originated and the warning text. Optionally the format may contain # $version, which will be replaced by the version of the file (if it could # be obtained via FILE_VERSION_FILTER) WARN_FORMAT = "$file:$line: $text" # The WARN_LOGFILE tag can be used to specify a file to which warning # and error messages should be written. If left blank the output is written # to stderr. WARN_LOGFILE = #--------------------------------------------------------------------------- # configuration options related to the input files #--------------------------------------------------------------------------- # The INPUT tag can be used to specify the files and/or directories that contain # documented source files. You may enter file names like "myfile.cpp" or # directories like "/usr/src/myproject". Separate the files or directories # with spaces. INPUT = libocpf # This tag can be used to specify the character encoding of the source files that # doxygen parses. Internally doxygen uses the UTF-8 encoding, which is also the default # input encoding. Doxygen uses libiconv (or the iconv built into libc) for the transcoding. # See http://www.gnu.org/software/libiconv for the list of possible encodings. INPUT_ENCODING = UTF-8 # If the value of the INPUT tag contains directories, you can use the # FILE_PATTERNS tag to specify one or more wildcard pattern (like *.cpp # and *.h) to filter out the source-files in the directories. If left # blank the following patterns are tested: # *.c *.cc *.cxx *.cpp *.c++ *.java *.ii *.ixx *.ipp *.i++ *.inl *.h *.hh *.hxx # *.hpp *.h++ *.idl *.odl *.cs *.php *.php3 *.inc *.m *.mm *.py FILE_PATTERNS = *.h *.c *.doxy # The RECURSIVE tag can be used to turn specify whether or not subdirectories # should be searched for input files as well. Possible values are YES and NO. # If left blank NO is used. RECURSIVE = NO # The EXCLUDE tag can be used to specify files and/or directories that should # excluded from the INPUT source files. This way you can easily exclude a # subdirectory from a directory tree whose root is specified with the INPUT tag. EXCLUDE = *_private.h # The EXCLUDE_SYMLINKS tag can be used select whether or not files or # directories that are symbolic links (a Unix filesystem feature) are excluded # from the input. EXCLUDE_SYMLINKS = NO # If the value of the INPUT tag contains directories, you can use the # EXCLUDE_PATTERNS tag to specify one or more wildcard patterns to exclude # certain files from those directories. Note that the wildcards are matched # against the file with absolute path, so to exclude all test directories # for example use the pattern */test/* EXCLUDE_PATTERNS = *.yy.c *_private.h ocpf_api.* # The EXCLUDE_SYMBOLS tag can be used to specify one or more symbol names # (namespaces, classes, functions, etc.) that should be excluded from the output. # The symbol name can be a fully qualified name, a word, or if the wildcard * is used, # a substring. Examples: ANamespace, AClass, AClass::ANamespace, ANamespace::*Test EXCLUDE_SYMBOLS = # The EXAMPLE_PATH tag can be used to specify one or more files or # directories that contain example code fragments that are included (see # the \include command). EXAMPLE_PATH = libocpf/examples # If the value of the EXAMPLE_PATH tag contains directories, you can use the # EXAMPLE_PATTERNS tag to specify one or more wildcard pattern (like *.cpp # and *.h) to filter out the source-files in the directories. If left # blank all files are included. EXAMPLE_PATTERNS = # If the EXAMPLE_RECURSIVE tag is set to YES then subdirectories will be # searched for input files to be used with the \include or \dontinclude # commands irrespective of the value of the RECURSIVE tag. # Possible values are YES and NO. If left blank NO is used. EXAMPLE_RECURSIVE = NO # The IMAGE_PATH tag can be used to specify one or more files or # directories that contain image that are included in the documentation (see # the \image command). IMAGE_PATH = doc/doxygen/pictures/ # The INPUT_FILTER tag can be used to specify a program that doxygen should # invoke to filter for each input file. Doxygen will invoke the filter program # by executing (via popen()) the command , where # is the value of the INPUT_FILTER tag, and is the name of an # input file. Doxygen will then use the output that the filter program writes # to standard output. If FILTER_PATTERNS is specified, this tag will be # ignored. INPUT_FILTER = "sed \ -e '20,40s/.*\//' \ -e '20,40s/.*\//' \ -e '20,40s/.*\//' \ -e '20,40s/.*\//' \ -e '20,40s/.*\//' \ -e '20,40s/.*\//' \ -e '20,40s/.*\//' \ -e '20,40s/.*\//' \ -e '20,40s/.*\//' \ -e '20,40s/.*\//' \ -e '20,40s/.*\//' \ -e '20,40s/.*\//' \ -e '20,40s/.*\//' \ -e '20,40s/.*\//' \ -e '20,40s/.*\//' \ -e '20,40s/.*\//' \ -e '20,40s/.*\//' \ -e '20,40s/.*\//' \ -e '20,40s/_PUBLIC_//'" # The FILTER_PATTERNS tag can be used to specify filters on a per file pattern # basis. Doxygen will compare the file name with each pattern and apply the # filter if there is a match. The filters are a list of the form: # pattern=filter (like *.cpp=my_cpp_filter). See INPUT_FILTER for further # info on how filters are used. If FILTER_PATTERNS is empty, INPUT_FILTER # is applied to all files. FILTER_PATTERNS = # If the FILTER_SOURCE_FILES tag is set to YES, the input filter (if set using # INPUT_FILTER) will be used to filter the input files when producing source # files to browse (i.e. when SOURCE_BROWSER is set to YES). FILTER_SOURCE_FILES = NO #--------------------------------------------------------------------------- # configuration options related to source browsing #--------------------------------------------------------------------------- # If the SOURCE_BROWSER tag is set to YES then a list of source files will # be generated. Documented entities will be cross-referenced with these sources. # Note: To get rid of all source code in the generated output, make sure also # VERBATIM_HEADERS is set to NO. SOURCE_BROWSER = NO # Setting the INLINE_SOURCES tag to YES will include the body # of functions and classes directly in the documentation. INLINE_SOURCES = NO # Setting the STRIP_CODE_COMMENTS tag to YES (the default) will instruct # doxygen to hide any special comment blocks from generated source code # fragments. Normal C and C++ comments will always remain visible. STRIP_CODE_COMMENTS = YES # If the REFERENCED_BY_RELATION tag is set to YES (the default) # then for each documented function all documented # functions referencing it will be listed. REFERENCED_BY_RELATION = YES # If the REFERENCES_RELATION tag is set to YES (the default) # then for each documented function all documented entities # called/used by that function will be listed. REFERENCES_RELATION = YES # If the REFERENCES_LINK_SOURCE tag is set to YES (the default) # and SOURCE_BROWSER tag is set to YES, then the hyperlinks from # functions in REFERENCES_RELATION and REFERENCED_BY_RELATION lists will # link to the source code. Otherwise they will link to the documentstion. REFERENCES_LINK_SOURCE = YES # If the USE_HTAGS tag is set to YES then the references to source code # will point to the HTML generated by the htags(1) tool instead of doxygen # built-in source browser. The htags tool is part of GNU's global source # tagging system (see http://www.gnu.org/software/global/global.html). You # will need version 4.8.6 or higher. USE_HTAGS = NO # If the VERBATIM_HEADERS tag is set to YES (the default) then Doxygen # will generate a verbatim copy of the header file for each class for # which an include is specified. Set to NO to disable this. VERBATIM_HEADERS = NO #--------------------------------------------------------------------------- # configuration options related to the alphabetical class index #--------------------------------------------------------------------------- # If the ALPHABETICAL_INDEX tag is set to YES, an alphabetical index # of all compounds will be generated. Enable this if the project # contains a lot of classes, structs, unions or interfaces. ALPHABETICAL_INDEX = NO # If the alphabetical index is enabled (see ALPHABETICAL_INDEX) then # the COLS_IN_ALPHA_INDEX tag can be used to specify the number of columns # in which this list will be split (can be a number in the range [1..20]) COLS_IN_ALPHA_INDEX = 5 # In case all classes in a project start with a common prefix, all # classes will be put under the same header in the alphabetical index. # The IGNORE_PREFIX tag can be used to specify one or more prefixes that # should be ignored while generating the index headers. IGNORE_PREFIX = #--------------------------------------------------------------------------- # configuration options related to the HTML output #--------------------------------------------------------------------------- # If the GENERATE_HTML tag is set to YES (the default) Doxygen will # generate HTML output. GENERATE_HTML = YES # The HTML_OUTPUT tag is used to specify where the HTML docs will be put. # If a relative path is entered the value of OUTPUT_DIRECTORY will be # put in front of it. If left blank `html' will be used as the default path. HTML_OUTPUT = html/libocpf # The HTML_FILE_EXTENSION tag can be used to specify the file extension for # each generated HTML page (for example: .htm,.php,.asp). If it is left blank # doxygen will generate files with .html extension. HTML_FILE_EXTENSION = .html # The HTML_HEADER tag can be used to specify a personal HTML header for # each generated HTML page. If it is left blank doxygen will generate a # standard header. HTML_HEADER = doc/doxygen/header.html # The HTML_FOOTER tag can be used to specify a personal HTML footer for # each generated HTML page. If it is left blank doxygen will generate a # standard footer. HTML_FOOTER = doc/doxygen/footer.html # The HTML_STYLESHEET tag can be used to specify a user-defined cascading # style sheet that is used by each HTML page. It can be used to # fine-tune the look of the HTML output. If the tag is left blank doxygen # will generate a default style sheet. Note that doxygen will try to copy # the style sheet file to the HTML output directory, so don't put your own # stylesheet in the HTML output directory as well, or it will be erased! HTML_STYLESHEET = doc/doxygen/apidocs.css # If the HTML_ALIGN_MEMBERS tag is set to YES, the members of classes, # files or namespaces will be aligned in HTML using tables. If set to # NO a bullet list will be used. HTML_ALIGN_MEMBERS = YES # If the GENERATE_HTMLHELP tag is set to YES, additional index files # will be generated that can be used as input for tools like the # Microsoft HTML help workshop to generate a compressed HTML help file (.chm) # of the generated HTML documentation. GENERATE_HTMLHELP = NO # If the GENERATE_HTMLHELP tag is set to YES, the CHM_FILE tag can # be used to specify the file name of the resulting .chm file. You # can add a path in front of the file if the result should not be # written to the html output directory. CHM_FILE = # If the GENERATE_HTMLHELP tag is set to YES, the HHC_LOCATION tag can # be used to specify the location (absolute path including file name) of # the HTML help compiler (hhc.exe). If non-empty doxygen will try to run # the HTML help compiler on the generated index.hhp. HHC_LOCATION = # If the GENERATE_HTMLHELP tag is set to YES, the GENERATE_CHI flag # controls if a separate .chi index file is generated (YES) or that # it should be included in the master .chm file (NO). GENERATE_CHI = NO # If the GENERATE_HTMLHELP tag is set to YES, the BINARY_TOC flag # controls whether a binary table of contents is generated (YES) or a # normal table of contents (NO) in the .chm file. BINARY_TOC = NO # The TOC_EXPAND flag can be set to YES to add extra items for group members # to the contents of the HTML help documentation and to the tree view. TOC_EXPAND = NO # The DISABLE_INDEX tag can be used to turn on/off the condensed index at # top of each HTML page. The value NO (the default) enables the index and # the value YES disables it. DISABLE_INDEX = NO # This tag can be used to set the number of enum values (range [1..20]) # that doxygen will group on one line in the generated HTML documentation. ENUM_VALUES_PER_LINE = 4 # If the GENERATE_TREEVIEW tag is set to YES, a side panel will be # generated containing a tree-like index structure (just like the one that # is generated for HTML Help). For this to work a browser that supports # JavaScript, DHTML, CSS and frames is required (for instance Mozilla 1.0+, # Netscape 6.0+, Internet explorer 5.0+, or Konqueror). Windows users are # probably better off using the HTML help feature. GENERATE_TREEVIEW = NO # If the treeview is enabled (see GENERATE_TREEVIEW) then this tag can be # used to set the initial width (in pixels) of the frame in which the tree # is shown. TREEVIEW_WIDTH = 250 #--------------------------------------------------------------------------- # configuration options related to the LaTeX output #--------------------------------------------------------------------------- # If the GENERATE_LATEX tag is set to YES (the default) Doxygen will # generate Latex output. GENERATE_LATEX = NO # The LATEX_OUTPUT tag is used to specify where the LaTeX docs will be put. # If a relative path is entered the value of OUTPUT_DIRECTORY will be # put in front of it. If left blank `latex' will be used as the default path. LATEX_OUTPUT = latex # The LATEX_CMD_NAME tag can be used to specify the LaTeX command name to be # invoked. If left blank `latex' will be used as the default command name. LATEX_CMD_NAME = latex # The MAKEINDEX_CMD_NAME tag can be used to specify the command name to # generate index for LaTeX. If left blank `makeindex' will be used as the # default command name. MAKEINDEX_CMD_NAME = makeindex # If the COMPACT_LATEX tag is set to YES Doxygen generates more compact # LaTeX documents. This may be useful for small projects and may help to # save some trees in general. COMPACT_LATEX = NO # The PAPER_TYPE tag can be used to set the paper type that is used # by the printer. Possible values are: a4, a4wide, letter, legal and # executive. If left blank a4wide will be used. PAPER_TYPE = letter # The EXTRA_PACKAGES tag can be to specify one or more names of LaTeX # packages that should be included in the LaTeX output. EXTRA_PACKAGES = # The LATEX_HEADER tag can be used to specify a personal LaTeX header for # the generated latex document. The header should contain everything until # the first chapter. If it is left blank doxygen will generate a # standard header. Notice: only use this tag if you know what you are doing! LATEX_HEADER = # If the PDF_HYPERLINKS tag is set to YES, the LaTeX that is generated # is prepared for conversion to pdf (using ps2pdf). The pdf file will # contain links (just like the HTML output) instead of page references # This makes the output suitable for online browsing using a pdf viewer. PDF_HYPERLINKS = YES # If the USE_PDFLATEX tag is set to YES, pdflatex will be used instead of # plain latex in the generated Makefile. Set this option to YES to get a # higher quality PDF documentation. USE_PDFLATEX = YES # If the LATEX_BATCHMODE tag is set to YES, doxygen will add the \\batchmode. # command to the generated LaTeX files. This will instruct LaTeX to keep # running if errors occur, instead of asking the user for help. # This option is also used when generating formulas in HTML. LATEX_BATCHMODE = NO # If LATEX_HIDE_INDICES is set to YES then doxygen will not # include the index chapters (such as File Index, Compound Index, etc.) # in the output. LATEX_HIDE_INDICES = NO #--------------------------------------------------------------------------- # configuration options related to the RTF output #--------------------------------------------------------------------------- # If the GENERATE_RTF tag is set to YES Doxygen will generate RTF output # The RTF output is optimized for Word 97 and may not look very pretty with # other RTF readers or editors. GENERATE_RTF = NO # The RTF_OUTPUT tag is used to specify where the RTF docs will be put. # If a relative path is entered the value of OUTPUT_DIRECTORY will be # put in front of it. If left blank `rtf' will be used as the default path. RTF_OUTPUT = rtf # If the COMPACT_RTF tag is set to YES Doxygen generates more compact # RTF documents. This may be useful for small projects and may help to # save some trees in general. COMPACT_RTF = NO # If the RTF_HYPERLINKS tag is set to YES, the RTF that is generated # will contain hyperlink fields. The RTF file will # contain links (just like the HTML output) instead of page references. # This makes the output suitable for online browsing using WORD or other # programs which support those fields. # Note: wordpad (write) and others do not support links. RTF_HYPERLINKS = NO # Load stylesheet definitions from file. Syntax is similar to doxygen's # config file, i.e. a series of assignments. You only have to provide # replacements, missing definitions are set to their default value. RTF_STYLESHEET_FILE = # Set optional variables used in the generation of an rtf document. # Syntax is similar to doxygen's config file. RTF_EXTENSIONS_FILE = #--------------------------------------------------------------------------- # configuration options related to the man page output #--------------------------------------------------------------------------- # If the GENERATE_MAN tag is set to YES (the default) Doxygen will # generate man pages GENERATE_MAN = YES # The MAN_OUTPUT tag is used to specify where the man pages will be put. # If a relative path is entered the value of OUTPUT_DIRECTORY will be # put in front of it. If left blank `man' will be used as the default path. MAN_OUTPUT = man # The MAN_EXTENSION tag determines the extension that is added to # the generated man pages (default is the subroutine's section .3) MAN_EXTENSION = .3 # If the MAN_LINKS tag is set to YES and Doxygen generates man output, # then it will generate one additional man file for each entity # documented in the real man page(s). These additional files # only source the real man page, but without them the man command # would be unable to find the correct page. The default is NO. MAN_LINKS = YES #--------------------------------------------------------------------------- # configuration options related to the XML output #--------------------------------------------------------------------------- # If the GENERATE_XML tag is set to YES Doxygen will # generate an XML file that captures the structure of # the code including all documentation. GENERATE_XML = NO # The XML_OUTPUT tag is used to specify where the XML pages will be put. # If a relative path is entered the value of OUTPUT_DIRECTORY will be # put in front of it. If left blank `xml' will be used as the default path. XML_OUTPUT = xml # The XML_SCHEMA tag can be used to specify an XML schema, # which can be used by a validating XML parser to check the # syntax of the XML files. XML_SCHEMA = # The XML_DTD tag can be used to specify an XML DTD, # which can be used by a validating XML parser to check the # syntax of the XML files. XML_DTD = # If the XML_PROGRAMLISTING tag is set to YES Doxygen will # dump the program listings (including syntax highlighting # and cross-referencing information) to the XML output. Note that # enabling this will significantly increase the size of the XML output. XML_PROGRAMLISTING = YES #--------------------------------------------------------------------------- # configuration options for the AutoGen Definitions output #--------------------------------------------------------------------------- # If the GENERATE_AUTOGEN_DEF tag is set to YES Doxygen will # generate an AutoGen Definitions (see autogen.sf.net) file # that captures the structure of the code including all # documentation. Note that this feature is still experimental # and incomplete at the moment. GENERATE_AUTOGEN_DEF = NO #--------------------------------------------------------------------------- # configuration options related to the Perl module output #--------------------------------------------------------------------------- # If the GENERATE_PERLMOD tag is set to YES Doxygen will # generate a Perl module file that captures the structure of # the code including all documentation. Note that this # feature is still experimental and incomplete at the # moment. GENERATE_PERLMOD = NO # If the PERLMOD_LATEX tag is set to YES Doxygen will generate # the necessary Makefile rules, Perl scripts and LaTeX code to be able # to generate PDF and DVI output from the Perl module output. PERLMOD_LATEX = NO # If the PERLMOD_PRETTY tag is set to YES the Perl module output will be # nicely formatted so it can be parsed by a human reader. This is useful # if you want to understand what is going on. On the other hand, if this # tag is set to NO the size of the Perl module output will be much smaller # and Perl will parse it just the same. PERLMOD_PRETTY = YES # The names of the make variables in the generated doxyrules.make file # are prefixed with the string contained in PERLMOD_MAKEVAR_PREFIX. # This is useful so different doxyrules.make files included by the same # Makefile don't overwrite each other's variables. PERLMOD_MAKEVAR_PREFIX = #--------------------------------------------------------------------------- # Configuration options related to the preprocessor #--------------------------------------------------------------------------- # If the ENABLE_PREPROCESSING tag is set to YES (the default) Doxygen will # evaluate all C-preprocessor directives found in the sources and include # files. ENABLE_PREPROCESSING = YES # If the MACRO_EXPANSION tag is set to YES Doxygen will expand all macro # names in the source code. If set to NO (the default) only conditional # compilation will be performed. Macro expansion can be done in a controlled # way by setting EXPAND_ONLY_PREDEF to YES. MACRO_EXPANSION = NO # If the EXPAND_ONLY_PREDEF and MACRO_EXPANSION tags are both set to YES # then the macro expansion is limited to the macros specified with the # PREDEFINED and EXPAND_AS_DEFINED tags. EXPAND_ONLY_PREDEF = NO # If the SEARCH_INCLUDES tag is set to YES (the default) the includes files # in the INCLUDE_PATH (see below) will be search if a #include is found. SEARCH_INCLUDES = YES # The INCLUDE_PATH tag can be used to specify one or more directories that # contain include files that are not input files but should be processed by # the preprocessor. INCLUDE_PATH = # You can use the INCLUDE_FILE_PATTERNS tag to specify one or more wildcard # patterns (like *.h and *.hpp) to filter out the header-files in the # directories. If left blank, the patterns specified with FILE_PATTERNS will # be used. INCLUDE_FILE_PATTERNS = # The PREDEFINED tag can be used to specify one or more macro names that # are defined before the preprocessor is started (similar to the -D option of # gcc). The argument of the tag is a list of macros of the form: name # or name=definition (no spaces). If the definition and the = are # omitted =1 is assumed. To prevent a macro definition from being # undefined via #undef or recursively expanded use the := operator # instead of the = operator. PREDEFINED = _PUBLIC_ # If the MACRO_EXPANSION and EXPAND_ONLY_PREDEF tags are set to YES then # this tag can be used to specify a list of macro names that should be expanded. # The macro definition that is found in the sources will be used. # Use the PREDEFINED tag if you want to use a different macro definition. EXPAND_AS_DEFINED = # If the SKIP_FUNCTION_MACROS tag is set to YES (the default) then # doxygen's preprocessor will remove all function-like macros that are alone # on a line, have an all uppercase name, and do not end with a semicolon. Such # function macros are typically used for boiler-plate code, and will confuse # the parser if not removed. SKIP_FUNCTION_MACROS = YES #--------------------------------------------------------------------------- # Configuration::additions related to external references #--------------------------------------------------------------------------- # The TAGFILES option can be used to specify one or more tagfiles. # Optionally an initial location of the external documentation # can be added for each tagfile. The format of a tag file without # this location is as follows: # TAGFILES = file1 file2 ... # Adding location for the tag files is done as follows: # TAGFILES = file1=loc1 "file2 = loc2" ... # where "loc1" and "loc2" can be relative or absolute paths or # URLs. If a location is present for each tag, the installdox tool # does not have to be run to correct the links. # Note that each tag file must have a unique name # (where the name does NOT include the path) # If a tag file is not located in the directory in which doxygen # is run, you must also specify the path to the tagfile here. TAGFILES = # When a file name is specified after GENERATE_TAGFILE, doxygen will create # a tag file that is based on the input files it reads. GENERATE_TAGFILE = # If the ALLEXTERNALS tag is set to YES all external classes will be listed # in the class index. If set to NO only the inherited external classes # will be listed. ALLEXTERNALS = NO # If the EXTERNAL_GROUPS tag is set to YES all external groups will be listed # in the modules index. If set to NO, only the current project's groups will # be listed. EXTERNAL_GROUPS = YES # The PERL_PATH should be the absolute path and name of the perl script # interpreter (i.e. the result of `which perl'). PERL_PATH = /usr/bin/perl #--------------------------------------------------------------------------- # Configuration options related to the dot tool #--------------------------------------------------------------------------- # If the CLASS_DIAGRAMS tag is set to YES (the default) Doxygen will # generate a inheritance diagram (in HTML, RTF and LaTeX) for classes with base # or super classes. Setting the tag to NO turns the diagrams off. Note that # this option is superseded by the HAVE_DOT option below. This is only a # fallback. It is recommended to install and use dot, since it yields more # powerful graphs. CLASS_DIAGRAMS = YES # You can define message sequence charts within doxygen comments using the \msc # command. Doxygen will then run the mscgen tool (see http://www.mcternan.me.uk/mscgen/) to # produce the chart and insert it in the documentation. The MSCGEN_PATH tag allows you to # specify the directory where the mscgen tool resides. If left empty the tool is assumed to # be found in the default search path. MSCGEN_PATH = # If set to YES, the inheritance and collaboration graphs will hide # inheritance and usage relations if the target is undocumented # or is not a class. HIDE_UNDOC_RELATIONS = YES # If you set the HAVE_DOT tag to YES then doxygen will assume the dot tool is # available from the path. This tool is part of Graphviz, a graph visualization # toolkit from AT&T and Lucent Bell Labs. The other options in this section # have no effect if this option is set to NO (the default) HAVE_DOT = NO # If the CLASS_GRAPH and HAVE_DOT tags are set to YES then doxygen # will generate a graph for each documented class showing the direct and # indirect inheritance relations. Setting this tag to YES will force the # the CLASS_DIAGRAMS tag to NO. CLASS_GRAPH = YES # If the COLLABORATION_GRAPH and HAVE_DOT tags are set to YES then doxygen # will generate a graph for each documented class showing the direct and # indirect implementation dependencies (inheritance, containment, and # class references variables) of the class with other documented classes. COLLABORATION_GRAPH = YES # If the GROUP_GRAPHS and HAVE_DOT tags are set to YES then doxygen # will generate a graph for groups, showing the direct groups dependencies GROUP_GRAPHS = YES # If the UML_LOOK tag is set to YES doxygen will generate inheritance and # collaboration diagrams in a style similar to the OMG's Unified Modeling # Language. UML_LOOK = NO # If set to YES, the inheritance and collaboration graphs will show the # relations between templates and their instances. TEMPLATE_RELATIONS = NO # If the ENABLE_PREPROCESSING, SEARCH_INCLUDES, INCLUDE_GRAPH, and HAVE_DOT # tags are set to YES then doxygen will generate a graph for each documented # file showing the direct and indirect include dependencies of the file with # other documented files. INCLUDE_GRAPH = YES # If the ENABLE_PREPROCESSING, SEARCH_INCLUDES, INCLUDED_BY_GRAPH, and # HAVE_DOT tags are set to YES then doxygen will generate a graph for each # documented header file showing the documented files that directly or # indirectly include this file. INCLUDED_BY_GRAPH = YES # If the CALL_GRAPH and HAVE_DOT tags are set to YES then doxygen will # generate a call dependency graph for every global function or class method. # Note that enabling this option will significantly increase the time of a run. # So in most cases it will be better to enable call graphs for selected # functions only using the \callgraph command. CALL_GRAPH = NO # If the CALLER_GRAPH and HAVE_DOT tags are set to YES then doxygen will # generate a caller dependency graph for every global function or class method. # Note that enabling this option will significantly increase the time of a run. # So in most cases it will be better to enable caller graphs for selected # functions only using the \callergraph command. CALLER_GRAPH = NO # If the GRAPHICAL_HIERARCHY and HAVE_DOT tags are set to YES then doxygen # will graphical hierarchy of all classes instead of a textual one. GRAPHICAL_HIERARCHY = YES # If the DIRECTORY_GRAPH, SHOW_DIRECTORIES and HAVE_DOT tags are set to YES # then doxygen will show the dependencies a directory has on other directories # in a graphical way. The dependency relations are determined by the #include # relations between the files in the directories. DIRECTORY_GRAPH = YES # The DOT_IMAGE_FORMAT tag can be used to set the image format of the images # generated by dot. Possible values are png, jpg, or gif # If left blank png will be used. DOT_IMAGE_FORMAT = png # The tag DOT_PATH can be used to specify the path where the dot tool can be # found. If left blank, it is assumed the dot tool can be found in the path. DOT_PATH = # The DOTFILE_DIRS tag can be used to specify one or more directories that # contain dot files that are included in the documentation (see the # \dotfile command). DOTFILE_DIRS = # The MAX_DOT_GRAPH_MAX_NODES tag can be used to set the maximum number of # nodes that will be shown in the graph. If the number of nodes in a graph # becomes larger than this value, doxygen will truncate the graph, which is # visualized by representing a node as a red box. Note that doxygen will always # show the root nodes and its direct children regardless of this setting. DOT_GRAPH_MAX_NODES = 50 # Set the DOT_TRANSPARENT tag to YES to generate images with a transparent # background. This is disabled by default, which results in a white background. # Warning: Depending on the platform used, enabling this option may lead to # badly anti-aliased labels on the edges of a graph (i.e. they become hard to # read). DOT_TRANSPARENT = NO # Set the DOT_MULTI_TARGETS tag to YES allow dot to generate multiple output # files in one run (i.e. multiple -o and -T options on the command line). This # makes dot run faster, but since only newer versions of dot (>1.8.10) # support this, this feature is disabled by default. DOT_MULTI_TARGETS = NO # If the GENERATE_LEGEND tag is set to YES (the default) Doxygen will # generate a legend page explaining the meaning of the various boxes and # arrows in the dot generated graphs. GENERATE_LEGEND = YES # If the DOT_CLEANUP tag is set to YES (the default) Doxygen will # remove the intermediate dot files that are used to generate # the various graphs. DOT_CLEANUP = YES #--------------------------------------------------------------------------- # Configuration::additions related to the search engine #--------------------------------------------------------------------------- # The SEARCHENGINE tag specifies whether or not a search engine should be # used. If set to NO the values of all tags below this one will be ignored. SEARCHENGINE = NO openchange-2.0/libocpf/examples/000077500000000000000000000000001223057412600167205ustar00rootroot00000000000000openchange-2.0/libocpf/examples/common_OLEGUID.ocpf000066400000000000000000000024771223057412600222430ustar00rootroot00000000000000/* * OpenChange Property File * * Copyright (C) Julien Kerihuel 2008. * * Registers common OLEGUID * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 3 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see */ OLEGUID PSETID_Appointment "00062002-0000-0000-c000-000000000046" OLEGUID PSETID_Task "00062003-0000-0000-c000-000000000046" OLEGUID PSETID_Address "00062004-0000-0000-c000-000000000046" OLEGUID PSETID_Common "00062008-0000-0000-c000-000000000046" OLEGUID PSETID_Note "0006200e-0000-0000-c000-000000000046" OLEGUID PSETID_Log "0006200a-0000-0000-c000-000000000046" OLEGUID PS_PUBLIC_STRINGS "00020329-0000-0000-c000-000000000046" OLEGUID PS_INTERNET_HEADERS "00020386-0000-0000-c000-000000000046" openchange-2.0/libocpf/examples/sample_appointment.ocpf000066400000000000000000000040021223057412600234640ustar00rootroot00000000000000/* * OpenChange Property File * * Copyright (C) Julien Kerihuel 2008. * * Sample appointment * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 3 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see */ TYPE "IPM.Appointment" FOLDER "olFolderCalendar" OLEGUID PSETID_Appointment "00062002-0000-0000-c000-000000000046" OLEGUID PSETID_Common "00062008-0000-0000-c000-000000000046" OLEGUID PS_PUBLIC_STRINGS "00020329-0000-0000-c000-000000000046" SET $subject = "[OCPF] Julien Kerihuel Birthday" SET $start_date = T2008-03-06 22:00:00 SET $end_date = T2008-03-06 23:45:00 SET $reminder = 45 SET $keywords = { "candles", "friends", "family" } SET $private = B"true" SET $wrong = 0 PROPERTY { PR_CONVERSATION_TOPIC = $subject PR_NORMALIZED_SUBJECT = $subject PR_BODY = "Another year, another pleasure" PR_START_DATE = $start_date PR_END_DATE = $end_date PR_SENSITIVITY = 2 }; NPROPERTY { OOM:BusyStatus:PSETID_Appointment = 9 OOM:ApptStartDate:PSETID_Appointment = $start_date OOM:CommonStart:PSETID_Common = $start_date OOM:ApptEndDate:PSETID_Appointment = $end_date OOM:CommonEnd:PSETID_Common = $end_date OOM:Location:PSETID_Appointment = W"Home Sweet Home" /* MeetingStatus */ MNID_ID:0x8217:PSETID_Appointment = $wrong OOM:Private:PSETID_Common = $private /* Set a reminder */ MNID_ID:0x8501:PT_LONG:PSETID_Common = $reminder /* Add categories */ MNID_STRING:"Keywords":PS_PUBLIC_STRINGS = $keywords };openchange-2.0/libocpf/examples/sample_task.ocpf000066400000000000000000000033321223057412600220750ustar00rootroot00000000000000/* * OpenChange Property File * * Copyright (C) Julien Kerihuel 2008. * * Sample task * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 3 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see */ TYPE "IPM.Task" FOLDER "olFolderTasks" OLEGUID PSETID_Task "00062003-0000-0000-c000-000000000046" OLEGUID PSETID_Common "00062008-0000-0000-c000-000000000046" OLEGUID PS_PUBLIC_STRINGS "00020329-0000-0000-c000-000000000046" SET $subject = "[OCPF] Sample Task" SET $body = "This is the sample task body" SET $start_date = T2008-03-06 20:00:00 SET $end_date = T2008-03-06 23:00:00 SET $importance = 2 /* IMPORTANCE_HIGH */ SET $task_status = 3 /* Waiting */ PROPERTY { PR_CONVERSATION_TOPIC = $subject PR_NORMALIZED_SUBJECT = $subject PR_BODY = $body PR_IMPORTANCE = $importance PR_SENSITIVITY = 2 /* needed to have private box ticked */ }; NPROPERTY { OOM:Companies:PSETID_Common = {"OpenChange Project", "Samba Project" } OOM:StartDate:PSETID_Task = $start_date OOM:DueDate:PSETID_Task = $end_date OOM:Status:PSETID_Task = $task_status OOM:Private:PSETID_Common = B"true" MNID_STRING:"Keywords":PS_PUBLIC_STRINGS = { "Category1", "Category2" } };openchange-2.0/libocpf/lex.h000066400000000000000000000017261223057412600160510ustar00rootroot00000000000000/* OpenChange OCPF (OpenChange Property File) implementation. Copyright (C) Julien Kerihuel 2008. This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see . */ #ifndef __LEX_H_ #define __LEX_H_ void ocpf_error_message (struct ocpf_context *, const char *, ...) __attribute__ ((format (printf, 2, 3))); extern int error_flag; /* int ocpf_yylex(YYSTYPE *); */ #endif /* __LEX_H_ */ openchange-2.0/libocpf/lex.l000066400000000000000000000203371223057412600160540ustar00rootroot00000000000000/* OpenChange OCPF (OpenChange Property File) implementation. Copyright (C) Julien Kerihuel 2008-2010 This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see . */ %{ #include #include #include "libocpf/ocpf.h" #include "libocpf/ocpf_api.h" #include "libocpf/ocpf.tab.h" #include "libocpf/lex.h" #define YY_EXTRA_TYPE struct ocpf_context * #define YY_NO_UNPUT /* * Prototypes */ int yylex(YYSTYPE *, void *); int yyget_lineno(void *); FILE *yyget_in(void *); FILE *yyget_out(void *); int yyget_leng(void *); char *yyget_text(void *); void yyset_lineno(int, void *); void yyset_extra(YY_EXTRA_TYPE, void *); void yyset_in (FILE *, void *); void yyset_out (FILE *, void *); int yyget_debug(void *); void yyset_debug(int, void *); int yylex_destroy(void *); void yyset_column(int, void *); int yyget_column(void *); static void unterminated(struct ocpf_context *, const char *, unsigned int); %} %option reentrant %option bison-bridge %option prefix="ocpf_yy" %option noyywrap %% TYPE { return kw_TYPE; } FOLDER { return kw_FOLDER; } OLEGUID { return kw_OLEGUID; } SET { return kw_SET; } PROPERTY { return kw_PROPERTY; } NPROPERTY { return kw_NPROPERTY; } TO { return kw_TO; } CC { return kw_CC; } BCC { return kw_BCC; } RECIPIENT { return kw_RECIPIENT; } OOM { return kw_OOM; } MNID_ID { return kw_MNID_ID; } MNID_STRING { return kw_MNID_STRING; } PT_STRING8 { return kw_PT_STRING8; } PT_UNICODE { return kw_PT_UNICODE; } PT_SHORT { return kw_PT_SHORT; } PT_LONG { return kw_PT_LONG; } PT_DOUBLE { return kw_PT_DOUBLE; } PT_I8 { return kw_PT_I8; } PT_SYSTIME { return kw_PT_SYSTIME; } PT_BOOLEAN { return kw_PT_BOOLEAN; } PT_MV_LONG { return kw_PT_LONG; } PT_MV_STRING8 { return kw_PT_MV_STRING8; } PT_MV_UNICODE { return kw_PT_MV_UNICODE; } PT_BINARY { return kw_PT_BINARY; } PT_MV_BINARY { return kw_PT_MV_BINARY; } \{ { return OBRACE; } \} { return EBRACE; } , { return COMMA; } ; { return SEMICOLON; } : { return COLON; } \< { return LOWER; } \> { return GREATER; } = { return EQUAL;} \/\* { struct ocpf_context *ctx = yyextra; int c, start_lineno = ctx->lineno; int level = 1; int seen_star = 0; int seen_slash = 0; while((c = input(yyscanner)) != EOF) { if(c == '/') { if(seen_star) { if(--level == 0) break; seen_star = 0; continue; } seen_slash = 1; continue; } if(seen_star && c == '/') { if(--level == 0) break; seen_star = 0; continue; } if(c == '*') { if(seen_slash) { level++; seen_star = seen_slash = 0; continue; } seen_star = 1; continue; } seen_star = seen_slash = 0; if(c == '\n') { ctx->lineno++; continue; } } if(c == EOF) unterminated(ctx, "comment", start_lineno); } "\"" { struct ocpf_context *ctx = yyextra; int start_lineno = ctx->lineno; int c, c2; char buf[0x4000]; char *p = buf; int f = 0; int skip_ws = 0; while((c = input(yyscanner)) != EOF) { if(isspace(c) && skip_ws) { if(c == '\n') ctx->lineno++; continue; } skip_ws = 0; if (c == '\\') { c2 = c; c = input(yyscanner); if (c == '"') { *p++ = c; c = input(yyscanner); } else { *p++ = c2; } } if(c == '"') { if(f) { *p++ = '"'; f = 0; } else { f = 1; } continue; } if(f == 1) { unput(c); break; } if(c == '\n') { ctx->lineno++; while(p > buf && isspace((unsigned char)p[-1])) p--; skip_ws = 1; continue; } *p++ = c; } if(c == EOF) unterminated(ctx, "string", start_lineno); *p++ = '\0'; yylval->name = buf; return STRING; } W"\"" { struct ocpf_context *ctx = yyextra; int start_lineno = ctx->lineno; int c, c2; char buf[0x4000]; char *p = buf; int f = 0; int skip_ws = 0; while((c = input(yyscanner)) != EOF) { if(isspace(c) && skip_ws) { if(c == '\n') ctx->lineno++; continue; } skip_ws = 0; if (c == '\\') { c2 = c; c = input(yyscanner); if (c == '"') { *p++ = c; c = input(yyscanner); } else { *p++ = c2; } } if(c == '"') { if(f) { *p++ = '"'; f = 0; } else { f = 1; } continue; } if(f == 1) { unput(c); break; } if(c == '\n') { ctx->lineno++; while(p > buf && isspace((unsigned char)p[-1])) p--; skip_ws = 1; continue; } *p++ = c; } if(c == EOF) unterminated(ctx, "string", start_lineno); *p++ = '\0'; yylval->name = buf; return UNICODE; } \$[-A-Za-z0-9_]+ { char *y = yytext + 1; yylval->var = strdup((const char *)y); return VAR; } B\"true\"|-?B\"false\" { char *y = yytext + 1; if (y && !strcmp(y, "\"true\"")) { yylval->b = true; } else { yylval->b = false; } return BOOLEAN; } F-?[0-9]"."[0-9]+e[-+]?[0-9]+ { struct ocpf_context *ctx = yyextra; char *y = yytext + 1; char *e; yylval->dbl = strtod((const char *)y, &e); if (e == y) { ocpf_error_message(ctx, "malformed constant (%s)", yytext); } else { return DOUBLE; } } T[0-9]{4}-[0-9]{2}-[0-9]{2}[ ][0-9]{2}\:[0-9]{2}\:[0-9]{2} { yylval->date = strdup((const char *)yytext + 1); return SYSTIME; } 0x[0-9A-Fa-f]{2} { struct ocpf_context *ctx = yyextra; char *e, *y = yytext; yylval->i = strtoul((const char *)y, &e, 0); if (e == y) ocpf_error_message(ctx, "malformed constant (%s)", yytext); else return UINT8; } 0x[0-9A-Fa-f]+ { struct ocpf_context *ctx = yyextra; char *e, *y = yytext; yylval->l = strtoul((const char *)y, &e, 0); if (e == y) ocpf_error_message(ctx, "malformed constant (%s)", yytext); else return INTEGER; } S0x[0-9A-Fa-f]+|-S[0-9]+ { struct ocpf_context *ctx = yyextra; char *e, *y; y = (yytext[0] == 'S') ? yytext + 1 : yytext; yylval->s = strtoul((const char *)y, &e, 0); if (e == y) ocpf_error_message(ctx, "malformed constant (%s)", yytext); else return SHORT; } L0x[0-9A-Fa-f]+|-?[0-9]+ { struct ocpf_context *ctx = yyextra; char *e, *y; y = (yytext[0] == 'L') ? yytext + 1 : yytext; yylval->l = strtoul((const char *)y, &e, 0); if(e == y) ocpf_error_message(ctx, "malformed constant (%s)", yytext); else return INTEGER; } D0x[0-9A-Fa-f]+ { struct ocpf_context *ctx = yyextra; char *e, *y = yytext + 1; yylval->d = strtoull((const char *)y, &e, 0); if(e == y) ocpf_error_message(ctx, "malformed constant (%s)", yytext); else return I8; } [A-Za-z][-A-Za-z0-9_]* { yylval->name = strdup((const char *)yytext); return IDENTIFIER; } [ \t]+ ; \n { struct ocpf_context *ctx = yyextra; ++ctx->lineno; } . { struct ocpf_context *ctx = yyextra; ocpf_error_message(ctx, "Ignoring char(%c)\n", *yytext); } %% void ocpf_error_message(struct ocpf_context *ctx, const char *format, ...) { va_list args; va_start(args, format); fprintf(stderr, "ERROR: %s:%d: ", ctx->filename, ctx->lineno); vfprintf(stderr, format, args); va_end(args); error_flag++; fflush(0); } static void unterminated(struct ocpf_context *ctx, const char *type, unsigned int start_lineno) { ocpf_error_message(ctx, "unterminated %s, possibly started on line %d\n", type, start_lineno); fflush(0); }openchange-2.0/libocpf/lex.yy.c000066400000000000000000002222141223057412600165010ustar00rootroot00000000000000 #line 3 "" #define YY_INT_ALIGNED short int /* A lexical scanner generated by flex */ #define FLEX_SCANNER #define YY_FLEX_MAJOR_VERSION 2 #define YY_FLEX_MINOR_VERSION 5 #define YY_FLEX_SUBMINOR_VERSION 35 #if YY_FLEX_SUBMINOR_VERSION > 0 #define FLEX_BETA #endif /* First, we deal with platform-specific or compiler-specific issues. */ /* begin standard C headers. */ #include #include #include #include /* end standard C headers. */ /* flex integer type definitions */ #ifndef FLEXINT_H #define FLEXINT_H /* C99 systems have . Non-C99 systems may or may not. */ #if defined (__STDC_VERSION__) && __STDC_VERSION__ >= 199901L /* C99 says to define __STDC_LIMIT_MACROS before including stdint.h, * if you want the limit (max/min) macros for int types. */ #ifndef __STDC_LIMIT_MACROS #define __STDC_LIMIT_MACROS 1 #endif #include typedef int8_t flex_int8_t; typedef uint8_t flex_uint8_t; typedef int16_t flex_int16_t; typedef uint16_t flex_uint16_t; typedef int32_t flex_int32_t; typedef uint32_t flex_uint32_t; #else typedef signed char flex_int8_t; typedef short int flex_int16_t; typedef int flex_int32_t; typedef unsigned char flex_uint8_t; typedef unsigned short int flex_uint16_t; typedef unsigned int flex_uint32_t; /* Limits of integral types. */ #ifndef INT8_MIN #define INT8_MIN (-128) #endif #ifndef INT16_MIN #define INT16_MIN (-32767-1) #endif #ifndef INT32_MIN #define INT32_MIN (-2147483647-1) #endif #ifndef INT8_MAX #define INT8_MAX (127) #endif #ifndef INT16_MAX #define INT16_MAX (32767) #endif #ifndef INT32_MAX #define INT32_MAX (2147483647) #endif #ifndef UINT8_MAX #define UINT8_MAX (255U) #endif #ifndef UINT16_MAX #define UINT16_MAX (65535U) #endif #ifndef UINT32_MAX #define UINT32_MAX (4294967295U) #endif #endif /* ! C99 */ #endif /* ! FLEXINT_H */ #ifdef __cplusplus /* The "const" storage-class-modifier is valid. */ #define YY_USE_CONST #else /* ! __cplusplus */ /* C99 requires __STDC__ to be defined as 1. */ #if defined (__STDC__) #define YY_USE_CONST #endif /* defined (__STDC__) */ #endif /* ! __cplusplus */ #ifdef YY_USE_CONST #define yyconst const #else #define yyconst #endif /* Returned upon end-of-file. */ #define YY_NULL 0 /* Promotes a possibly negative, possibly signed char to an unsigned * integer for use as an array index. If the signed char is negative, * we want to instead treat it as an 8-bit unsigned char, hence the * double cast. */ #define YY_SC_TO_UI(c) ((unsigned int) (unsigned char) c) /* An opaque pointer. */ #ifndef YY_TYPEDEF_YY_SCANNER_T #define YY_TYPEDEF_YY_SCANNER_T typedef void* yyscan_t; #endif /* For convenience, these vars (plus the bison vars far below) are macros in the reentrant scanner. */ #define yyin yyg->yyin_r #define yyout yyg->yyout_r #define yyextra yyg->yyextra_r #define yyleng yyg->yyleng_r #define yytext yyg->yytext_r #define yylineno (YY_CURRENT_BUFFER_LVALUE->yy_bs_lineno) #define yycolumn (YY_CURRENT_BUFFER_LVALUE->yy_bs_column) #define yy_flex_debug yyg->yy_flex_debug_r /* Enter a start condition. This macro really ought to take a parameter, * but we do it the disgusting crufty way forced on us by the ()-less * definition of BEGIN. */ #define BEGIN yyg->yy_start = 1 + 2 * /* Translate the current start state into a value that can be later handed * to BEGIN to return to the state. The YYSTATE alias is for lex * compatibility. */ #define YY_START ((yyg->yy_start - 1) / 2) #define YYSTATE YY_START /* Action number for EOF rule of a given start state. */ #define YY_STATE_EOF(state) (YY_END_OF_BUFFER + state + 1) /* Special action meaning "start processing a new file". */ #define YY_NEW_FILE ocpf_yyrestart(yyin ,yyscanner ) #define YY_END_OF_BUFFER_CHAR 0 /* Size of default input buffer. */ #ifndef YY_BUF_SIZE #ifdef __ia64__ /* On IA-64, the buffer size is 16k, not 8k. * Moreover, YY_BUF_SIZE is 2*YY_READ_BUF_SIZE in the general case. * Ditto for the __ia64__ case accordingly. */ #define YY_BUF_SIZE 32768 #else #define YY_BUF_SIZE 16384 #endif /* __ia64__ */ #endif /* The state buf must be large enough to hold one state per character in the main buffer. */ #define YY_STATE_BUF_SIZE ((YY_BUF_SIZE + 2) * sizeof(yy_state_type)) #ifndef YY_TYPEDEF_YY_BUFFER_STATE #define YY_TYPEDEF_YY_BUFFER_STATE typedef struct yy_buffer_state *YY_BUFFER_STATE; #endif #define EOB_ACT_CONTINUE_SCAN 0 #define EOB_ACT_END_OF_FILE 1 #define EOB_ACT_LAST_MATCH 2 #define YY_LESS_LINENO(n) /* Return all but the first "n" matched characters back to the input stream. */ #define yyless(n) \ do \ { \ /* Undo effects of setting up yytext. */ \ int yyless_macro_arg = (n); \ YY_LESS_LINENO(yyless_macro_arg);\ *yy_cp = yyg->yy_hold_char; \ YY_RESTORE_YY_MORE_OFFSET \ yyg->yy_c_buf_p = yy_cp = yy_bp + yyless_macro_arg - YY_MORE_ADJ; \ YY_DO_BEFORE_ACTION; /* set up yytext again */ \ } \ while ( 0 ) #define unput(c) yyunput( c, yyg->yytext_ptr , yyscanner ) #ifndef YY_TYPEDEF_YY_SIZE_T #define YY_TYPEDEF_YY_SIZE_T typedef size_t yy_size_t; #endif #ifndef YY_STRUCT_YY_BUFFER_STATE #define YY_STRUCT_YY_BUFFER_STATE struct yy_buffer_state { FILE *yy_input_file; char *yy_ch_buf; /* input buffer */ char *yy_buf_pos; /* current position in input buffer */ /* Size of input buffer in bytes, not including room for EOB * characters. */ yy_size_t yy_buf_size; /* Number of characters read into yy_ch_buf, not including EOB * characters. */ int yy_n_chars; /* Whether we "own" the buffer - i.e., we know we created it, * and can realloc() it to grow it, and should free() it to * delete it. */ int yy_is_our_buffer; /* Whether this is an "interactive" input source; if so, and * if we're using stdio for input, then we want to use getc() * instead of fread(), to make sure we stop fetching input after * each newline. */ int yy_is_interactive; /* Whether we're considered to be at the beginning of a line. * If so, '^' rules will be active on the next match, otherwise * not. */ int yy_at_bol; int yy_bs_lineno; /**< The line count. */ int yy_bs_column; /**< The column count. */ /* Whether to try to fill the input buffer when we reach the * end of it. */ int yy_fill_buffer; int yy_buffer_status; #define YY_BUFFER_NEW 0 #define YY_BUFFER_NORMAL 1 /* When an EOF's been seen but there's still some text to process * then we mark the buffer as YY_EOF_PENDING, to indicate that we * shouldn't try reading from the input source any more. We might * still have a bunch of tokens to match, though, because of * possible backing-up. * * When we actually see the EOF, we change the status to "new" * (via ocpf_yyrestart()), so that the user can continue scanning by * just pointing yyin at a new input file. */ #define YY_BUFFER_EOF_PENDING 2 }; #endif /* !YY_STRUCT_YY_BUFFER_STATE */ /* We provide macros for accessing buffer states in case in the * future we want to put the buffer states in a more general * "scanner state". * * Returns the top of the stack, or NULL. */ #define YY_CURRENT_BUFFER ( yyg->yy_buffer_stack \ ? yyg->yy_buffer_stack[yyg->yy_buffer_stack_top] \ : NULL) /* Same as previous macro, but useful when we know that the buffer stack is not * NULL or when we need an lvalue. For internal use only. */ #define YY_CURRENT_BUFFER_LVALUE yyg->yy_buffer_stack[yyg->yy_buffer_stack_top] void ocpf_yyrestart (FILE *input_file ,yyscan_t yyscanner ); void ocpf_yy_switch_to_buffer (YY_BUFFER_STATE new_buffer ,yyscan_t yyscanner ); YY_BUFFER_STATE ocpf_yy_create_buffer (FILE *file,int size ,yyscan_t yyscanner ); void ocpf_yy_delete_buffer (YY_BUFFER_STATE b ,yyscan_t yyscanner ); void ocpf_yy_flush_buffer (YY_BUFFER_STATE b ,yyscan_t yyscanner ); void ocpf_yypush_buffer_state (YY_BUFFER_STATE new_buffer ,yyscan_t yyscanner ); void ocpf_yypop_buffer_state (yyscan_t yyscanner ); static void ocpf_yyensure_buffer_stack (yyscan_t yyscanner ); static void ocpf_yy_load_buffer_state (yyscan_t yyscanner ); static void ocpf_yy_init_buffer (YY_BUFFER_STATE b,FILE *file ,yyscan_t yyscanner ); #define YY_FLUSH_BUFFER ocpf_yy_flush_buffer(YY_CURRENT_BUFFER ,yyscanner) YY_BUFFER_STATE ocpf_yy_scan_buffer (char *base,yy_size_t size ,yyscan_t yyscanner ); YY_BUFFER_STATE ocpf_yy_scan_string (yyconst char *yy_str ,yyscan_t yyscanner ); YY_BUFFER_STATE ocpf_yy_scan_bytes (yyconst char *bytes,int len ,yyscan_t yyscanner ); void *ocpf_yyalloc (yy_size_t ,yyscan_t yyscanner ); void *ocpf_yyrealloc (void *,yy_size_t ,yyscan_t yyscanner ); void ocpf_yyfree (void * ,yyscan_t yyscanner ); #define yy_new_buffer ocpf_yy_create_buffer #define yy_set_interactive(is_interactive) \ { \ if ( ! YY_CURRENT_BUFFER ){ \ ocpf_yyensure_buffer_stack (yyscanner); \ YY_CURRENT_BUFFER_LVALUE = \ ocpf_yy_create_buffer(yyin,YY_BUF_SIZE ,yyscanner); \ } \ YY_CURRENT_BUFFER_LVALUE->yy_is_interactive = is_interactive; \ } #define yy_set_bol(at_bol) \ { \ if ( ! YY_CURRENT_BUFFER ){\ ocpf_yyensure_buffer_stack (yyscanner); \ YY_CURRENT_BUFFER_LVALUE = \ ocpf_yy_create_buffer(yyin,YY_BUF_SIZE ,yyscanner); \ } \ YY_CURRENT_BUFFER_LVALUE->yy_at_bol = at_bol; \ } #define YY_AT_BOL() (YY_CURRENT_BUFFER_LVALUE->yy_at_bol) /* Begin user sect3 */ #define ocpf_yywrap(n) 1 #define YY_SKIP_YYWRAP typedef unsigned char YY_CHAR; typedef int yy_state_type; #define yytext_ptr yytext_r static yy_state_type yy_get_previous_state (yyscan_t yyscanner ); static yy_state_type yy_try_NUL_trans (yy_state_type current_state ,yyscan_t yyscanner); static int yy_get_next_buffer (yyscan_t yyscanner ); static void yy_fatal_error (yyconst char msg[] ,yyscan_t yyscanner ); /* Done after the current pattern has been matched and before the * corresponding action - sets up yytext. */ #define YY_DO_BEFORE_ACTION \ yyg->yytext_ptr = yy_bp; \ yyleng = (size_t) (yy_cp - yy_bp); \ yyg->yy_hold_char = *yy_cp; \ *yy_cp = '\0'; \ yyg->yy_c_buf_p = yy_cp; #define YY_NUM_RULES 51 #define YY_END_OF_BUFFER 52 /* This struct is not used in this scanner, but its presence is necessary. */ struct yy_trans_info { flex_int32_t yy_verify; flex_int32_t yy_nxt; }; static yyconst flex_int16_t yy_accept[230] = { 0, 0, 0, 52, 50, 48, 49, 36, 50, 29, 50, 50, 45, 45, 31, 30, 32, 34, 33, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 27, 28, 48, 38, 45, 0, 0, 35, 0, 47, 0, 47, 8, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 7, 47, 37, 0, 44, 43, 0, 0, 9, 47, 0, 47, 47, 47, 47, 47, 11, 47, 47, 47, 47, 4, 47, 47, 42, 0, 0, 46, 0, 47, 45, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 44, 47, 1, 43, 0, 0, 0, 47, 47, 47, 47, 47, 47, 47, 47, 19, 47, 47, 47, 47, 47, 47, 47, 47, 0, 0, 0, 40, 2, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 0, 39, 12, 47, 47, 3, 47, 47, 47, 47, 17, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 5, 47, 47, 47, 47, 47, 47, 47, 16, 47, 47, 47, 47, 47, 47, 6, 25, 47, 18, 47, 47, 47, 47, 47, 47, 47, 10, 47, 47, 21, 47, 22, 47, 47, 14, 20, 15, 47, 13, 47, 47, 47, 47, 26, 47, 47, 0, 23, 24, 0, 0, 0, 0, 0, 0, 0, 41, 0 } ; static yyconst flex_int32_t yy_ec[256] = { 0, 1, 1, 1, 1, 1, 1, 1, 1, 2, 3, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 4, 1, 5, 1, 6, 1, 1, 1, 1, 1, 7, 8, 9, 10, 11, 12, 13, 14, 14, 14, 14, 14, 14, 14, 15, 14, 16, 17, 18, 19, 20, 1, 1, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 30, 31, 32, 33, 34, 35, 30, 36, 37, 38, 39, 40, 41, 30, 42, 30, 1, 1, 1, 1, 43, 1, 44, 45, 45, 45, 46, 47, 30, 30, 30, 30, 30, 48, 30, 30, 30, 30, 30, 49, 50, 51, 52, 30, 30, 53, 30, 30, 54, 1, 55, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1 } ; static yyconst flex_int32_t yy_meta[56] = { 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 2, 1, 1, 3, 3, 3, 1, 1, 1, 1, 1, 3, 3, 3, 3, 3, 3, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 3, 3, 3, 3, 2, 2, 2, 2, 2, 2, 1, 1 } ; static yyconst flex_int16_t yy_base[235] = { 0, 0, 0, 356, 357, 54, 357, 357, 0, 357, 46, 348, 49, 52, 357, 357, 357, 357, 357, 0, 52, 331, 340, 59, 339, 318, 315, 45, 42, 324, 57, 71, 343, 357, 357, 85, 0, 77, 342, 81, 357, 0, 0, 30, 323, 0, 292, 84, 333, 312, 289, 312, 304, 314, 306, 303, 293, 312, 281, 295, 93, 0, 297, 357, 284, 96, 0, 286, 280, 0, 101, 104, 304, 136, 303, 292, 298, 0, 289, 147, 294, 174, 0, 115, 297, 0, 273, 268, 0, 118, 294, 0, 275, 282, 277, 290, 105, 280, 298, 278, 271, 114, 277, 274, 0, 122, 0, 0, 258, 261, 160, 270, 75, 280, 275, 267, 269, 267, 261, 0, 266, 255, 263, 260, 258, 265, 264, 282, 245, 285, 140, 152, 0, 265, 250, 251, 262, 247, 263, 252, 260, 254, 170, 244, 250, 240, 254, 251, 189, 270, 357, 0, 238, 235, 0, 230, 235, 245, 238, 0, 239, 233, 228, 232, 226, 230, 233, 227, 227, 197, 230, 216, 0, 215, 235, 230, 221, 220, 216, 222, 0, 223, 217, 224, 209, 207, 183, 0, 0, 175, 0, 185, 178, 165, 170, 176, 165, 160, 0, 200, 150, 0, 136, 0, 130, 110, 0, 0, 0, 209, 0, 101, 114, 116, 134, 0, 106, 95, 212, 0, 0, 215, 87, 218, 221, 85, 224, 227, 357, 357, 241, 243, 97, 85, 68 } ; static yyconst flex_int16_t yy_def[235] = { 0, 229, 1, 229, 229, 229, 229, 229, 230, 229, 229, 229, 229, 229, 229, 229, 229, 229, 229, 231, 231, 231, 231, 231, 231, 231, 231, 231, 231, 231, 231, 231, 231, 229, 229, 229, 230, 229, 229, 229, 229, 232, 231, 229, 231, 231, 231, 231, 231, 231, 231, 231, 231, 231, 231, 231, 231, 231, 231, 231, 231, 231, 231, 229, 229, 229, 233, 229, 229, 231, 231, 229, 231, 231, 231, 231, 231, 231, 231, 231, 231, 231, 231, 231, 231, 234, 229, 229, 70, 229, 231, 73, 231, 231, 231, 231, 231, 231, 231, 231, 231, 231, 231, 231, 81, 231, 231, 234, 229, 229, 229, 231, 231, 231, 231, 231, 231, 231, 231, 231, 231, 231, 231, 231, 231, 231, 231, 231, 229, 229, 229, 229, 231, 231, 231, 231, 231, 231, 231, 231, 231, 231, 231, 231, 231, 231, 231, 231, 231, 229, 229, 231, 231, 231, 231, 231, 231, 231, 231, 231, 231, 231, 231, 231, 231, 231, 231, 231, 231, 231, 231, 231, 231, 231, 231, 231, 231, 231, 231, 231, 231, 231, 231, 231, 231, 231, 231, 231, 231, 231, 231, 231, 231, 231, 231, 231, 231, 231, 231, 231, 231, 231, 231, 231, 231, 231, 231, 231, 231, 231, 231, 231, 231, 231, 231, 231, 231, 231, 229, 231, 231, 229, 229, 229, 229, 229, 229, 229, 229, 0, 229, 229, 229, 229, 229 } ; static yyconst flex_int16_t yy_nxt[413] = { 0, 4, 5, 6, 5, 7, 8, 4, 4, 9, 10, 4, 11, 12, 13, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 19, 23, 19, 19, 19, 19, 24, 25, 26, 27, 28, 29, 30, 31, 19, 19, 32, 19, 4, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 33, 34, 35, 43, 35, 37, 37, 37, 37, 37, 37, 37, 37, 37, 38, 47, 58, 107, 48, 48, 48, 44, 53, 67, 55, 54, 56, 68, 59, 39, 60, 60, 60, 35, 85, 35, 37, 37, 37, 49, 65, 65, 65, 48, 48, 48, 66, 226, 41, 223, 133, 61, 83, 83, 83, 65, 65, 65, 134, 62, 88, 88, 88, 89, 89, 89, 220, 219, 88, 88, 88, 88, 88, 88, 105, 105, 105, 89, 89, 89, 116, 127, 127, 127, 218, 117, 217, 216, 122, 215, 213, 88, 88, 88, 88, 91, 91, 91, 123, 131, 131, 131, 124, 91, 91, 91, 91, 91, 91, 212, 110, 131, 131, 131, 130, 96, 130, 97, 211, 131, 131, 131, 98, 210, 99, 100, 91, 91, 91, 91, 101, 208, 102, 104, 104, 104, 207, 206, 160, 205, 204, 104, 104, 104, 104, 104, 104, 161, 169, 169, 169, 203, 202, 162, 201, 163, 185, 185, 185, 209, 209, 209, 200, 199, 104, 104, 104, 104, 214, 214, 214, 221, 221, 221, 222, 222, 222, 224, 224, 224, 225, 225, 225, 227, 227, 227, 228, 228, 228, 36, 36, 42, 42, 198, 197, 196, 195, 194, 193, 192, 191, 190, 189, 188, 187, 186, 184, 183, 182, 181, 180, 179, 178, 177, 176, 175, 174, 173, 172, 171, 170, 150, 168, 167, 166, 165, 164, 159, 158, 157, 156, 155, 154, 153, 152, 151, 150, 149, 148, 147, 146, 145, 144, 143, 142, 141, 140, 139, 138, 137, 136, 135, 132, 129, 128, 126, 125, 121, 120, 119, 118, 115, 114, 113, 112, 111, 109, 108, 106, 103, 95, 94, 93, 92, 90, 87, 86, 67, 84, 82, 81, 80, 79, 78, 77, 76, 75, 74, 73, 72, 71, 70, 69, 64, 63, 57, 52, 51, 50, 46, 45, 40, 229, 3, 229, 229, 229, 229, 229, 229, 229, 229, 229, 229, 229, 229, 229, 229, 229, 229, 229, 229, 229, 229, 229, 229, 229, 229, 229, 229, 229, 229, 229, 229, 229, 229, 229, 229, 229, 229, 229, 229, 229, 229, 229, 229, 229, 229, 229, 229, 229, 229, 229, 229, 229, 229, 229, 229, 229 } ; static yyconst flex_int16_t yy_chk[413] = { 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 5, 20, 5, 10, 10, 10, 12, 12, 12, 13, 13, 13, 10, 23, 30, 234, 23, 23, 23, 20, 27, 43, 28, 27, 28, 43, 30, 10, 31, 31, 31, 35, 233, 35, 37, 37, 37, 23, 39, 39, 39, 47, 47, 47, 232, 225, 12, 222, 112, 31, 60, 60, 60, 65, 65, 65, 112, 31, 70, 70, 70, 71, 71, 71, 217, 216, 70, 70, 70, 70, 70, 70, 83, 83, 83, 89, 89, 89, 96, 105, 105, 105, 214, 96, 213, 212, 101, 211, 205, 70, 70, 70, 70, 73, 73, 73, 101, 130, 130, 130, 101, 73, 73, 73, 73, 73, 73, 204, 89, 131, 131, 131, 110, 79, 110, 79, 202, 110, 110, 110, 79, 200, 79, 79, 73, 73, 73, 73, 79, 197, 79, 81, 81, 81, 196, 195, 142, 194, 193, 81, 81, 81, 81, 81, 81, 142, 148, 148, 148, 192, 191, 142, 189, 142, 169, 169, 169, 199, 199, 199, 186, 185, 81, 81, 81, 81, 209, 209, 209, 218, 218, 218, 221, 221, 221, 223, 223, 223, 224, 224, 224, 226, 226, 226, 227, 227, 227, 230, 230, 231, 231, 184, 183, 182, 181, 179, 178, 177, 176, 175, 174, 173, 171, 170, 168, 167, 166, 165, 164, 163, 162, 161, 160, 158, 157, 156, 155, 153, 152, 149, 147, 146, 145, 144, 143, 141, 140, 139, 138, 137, 136, 135, 134, 133, 129, 128, 127, 126, 125, 124, 123, 122, 121, 120, 118, 117, 116, 115, 114, 113, 111, 109, 108, 103, 102, 100, 99, 98, 97, 95, 94, 93, 92, 90, 87, 86, 84, 80, 78, 76, 75, 74, 72, 68, 67, 64, 62, 59, 58, 57, 56, 55, 54, 53, 52, 51, 50, 49, 48, 46, 44, 38, 32, 29, 26, 25, 24, 22, 21, 11, 3, 229, 229, 229, 229, 229, 229, 229, 229, 229, 229, 229, 229, 229, 229, 229, 229, 229, 229, 229, 229, 229, 229, 229, 229, 229, 229, 229, 229, 229, 229, 229, 229, 229, 229, 229, 229, 229, 229, 229, 229, 229, 229, 229, 229, 229, 229, 229, 229, 229, 229, 229, 229, 229, 229, 229, 229 } ; /* The intent behind this definition is that it'll catch * any uses of REJECT which flex missed. */ #define REJECT reject_used_but_not_detected #define yymore() yymore_used_but_not_detected #define YY_MORE_ADJ 0 #define YY_RESTORE_YY_MORE_OFFSET #line 1 "libocpf/lex.l" /* OpenChange OCPF (OpenChange Property File) implementation. Copyright (C) Julien Kerihuel 2008-2010 This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see . */ #line 22 "libocpf/lex.l" #include #include #include "libocpf/ocpf.h" #include "libocpf/ocpf_api.h" #include "libocpf/ocpf.tab.h" #include "libocpf/lex.h" #define YY_EXTRA_TYPE struct ocpf_context * #define YY_NO_UNPUT /* * Prototypes */ int ocpf_yylex(YYSTYPE *,void *); int ocpf_yyget_lineno(void *); FILE *ocpf_yyget_in(void *); FILE *ocpf_yyget_out(void *); int ocpf_yyget_leng(void *); char *ocpf_yyget_text(void *); void ocpf_yyset_lineno(int,void *); void ocpf_yyset_extra(YY_EXTRA_TYPE,void *); void ocpf_yyset_in (FILE *, void *); void ocpf_yyset_out (FILE *, void *); int ocpf_yyget_debug(void *); void ocpf_yyset_debug(int,void *); int ocpf_yylex_destroy(void *); void ocpf_yyset_column(int,void *); int ocpf_yyget_column(void *); static void unterminated(struct ocpf_context *, const char *, unsigned int); #line 663 "" #define INITIAL 0 #ifndef YY_NO_UNISTD_H /* Special case for "unistd.h", since it is non-ANSI. We include it way * down here because we want the user's section 1 to have been scanned first. * The user has a chance to override it with an option. */ #include #endif #ifndef YY_EXTRA_TYPE #define YY_EXTRA_TYPE void * #endif /* Holds the entire state of the reentrant scanner. */ struct yyguts_t { /* User-defined. Not touched by flex. */ YY_EXTRA_TYPE yyextra_r; /* The rest are the same as the globals declared in the non-reentrant scanner. */ FILE *yyin_r, *yyout_r; size_t yy_buffer_stack_top; /**< index of top of stack. */ size_t yy_buffer_stack_max; /**< capacity of stack. */ YY_BUFFER_STATE * yy_buffer_stack; /**< Stack as an array. */ char yy_hold_char; int yy_n_chars; int yyleng_r; char *yy_c_buf_p; int yy_init; int yy_start; int yy_did_buffer_switch_on_eof; int yy_start_stack_ptr; int yy_start_stack_depth; int *yy_start_stack; yy_state_type yy_last_accepting_state; char* yy_last_accepting_cpos; int yylineno_r; int yy_flex_debug_r; char *yytext_r; int yy_more_flag; int yy_more_len; YYSTYPE * yylval_r; }; /* end struct yyguts_t */ static int yy_init_globals (yyscan_t yyscanner ); /* This must go here because YYSTYPE and YYLTYPE are included * from bison output in section 1.*/ # define yylval yyg->yylval_r int ocpf_yylex_init (yyscan_t* scanner); int ocpf_yylex_init_extra (YY_EXTRA_TYPE user_defined,yyscan_t* scanner); /* Accessor methods to globals. These are made visible to non-reentrant scanners for convenience. */ int ocpf_yylex_destroy (yyscan_t yyscanner ); int ocpf_yyget_debug (yyscan_t yyscanner ); void ocpf_yyset_debug (int debug_flag ,yyscan_t yyscanner ); YY_EXTRA_TYPE ocpf_yyget_extra (yyscan_t yyscanner ); void ocpf_yyset_extra (YY_EXTRA_TYPE user_defined ,yyscan_t yyscanner ); FILE *ocpf_yyget_in (yyscan_t yyscanner ); void ocpf_yyset_in (FILE * in_str ,yyscan_t yyscanner ); FILE *ocpf_yyget_out (yyscan_t yyscanner ); void ocpf_yyset_out (FILE * out_str ,yyscan_t yyscanner ); int ocpf_yyget_leng (yyscan_t yyscanner ); char *ocpf_yyget_text (yyscan_t yyscanner ); int ocpf_yyget_lineno (yyscan_t yyscanner ); void ocpf_yyset_lineno (int line_number ,yyscan_t yyscanner ); YYSTYPE * ocpf_yyget_lval (yyscan_t yyscanner ); void ocpf_yyset_lval (YYSTYPE * yylval_param ,yyscan_t yyscanner ); /* Macros after this point can all be overridden by user definitions in * section 1. */ #ifndef YY_SKIP_YYWRAP #ifdef __cplusplus extern "C" int ocpf_yywrap (yyscan_t yyscanner ); #else extern int ocpf_yywrap (yyscan_t yyscanner ); #endif #endif static void yyunput (int c,char *buf_ptr ,yyscan_t yyscanner); #ifndef yytext_ptr static void yy_flex_strncpy (char *,yyconst char *,int ,yyscan_t yyscanner); #endif #ifdef YY_NEED_STRLEN static int yy_flex_strlen (yyconst char * ,yyscan_t yyscanner); #endif #ifndef YY_NO_INPUT #ifdef __cplusplus static int yyinput (yyscan_t yyscanner ); #else static int input (yyscan_t yyscanner ); #endif #endif /* Amount of stuff to slurp up with each read. */ #ifndef YY_READ_BUF_SIZE #ifdef __ia64__ /* On IA-64, the buffer size is 16k, not 8k */ #define YY_READ_BUF_SIZE 16384 #else #define YY_READ_BUF_SIZE 8192 #endif /* __ia64__ */ #endif /* Copy whatever the last rule matched to the standard output. */ #ifndef ECHO /* This used to be an fputs(), but since the string might contain NUL's, * we now use fwrite(). */ #define ECHO do { if (fwrite( yytext, yyleng, 1, yyout )) {} } while (0) #endif /* Gets input and stuffs it into "buf". number of characters read, or YY_NULL, * is returned in "result". */ #ifndef YY_INPUT #define YY_INPUT(buf,result,max_size) \ if ( YY_CURRENT_BUFFER_LVALUE->yy_is_interactive ) \ { \ int c = '*'; \ size_t n; \ for ( n = 0; n < max_size && \ (c = getc( yyin )) != EOF && c != '\n'; ++n ) \ buf[n] = (char) c; \ if ( c == '\n' ) \ buf[n++] = (char) c; \ if ( c == EOF && ferror( yyin ) ) \ YY_FATAL_ERROR( "input in flex scanner failed" ); \ result = n; \ } \ else \ { \ errno=0; \ while ( (result = fread(buf, 1, max_size, yyin))==0 && ferror(yyin)) \ { \ if( errno != EINTR) \ { \ YY_FATAL_ERROR( "input in flex scanner failed" ); \ break; \ } \ errno=0; \ clearerr(yyin); \ } \ }\ \ #endif /* No semi-colon after return; correct usage is to write "yyterminate();" - * we don't want an extra ';' after the "return" because that will cause * some compilers to complain about unreachable statements. */ #ifndef yyterminate #define yyterminate() return YY_NULL #endif /* Number of entries by which start-condition stack grows. */ #ifndef YY_START_STACK_INCR #define YY_START_STACK_INCR 25 #endif /* Report a fatal error. */ #ifndef YY_FATAL_ERROR #define YY_FATAL_ERROR(msg) yy_fatal_error( msg , yyscanner) #endif /* end tables serialization structures and prototypes */ /* Default declaration of generated scanner - a define so the user can * easily add parameters. */ #ifndef YY_DECL #define YY_DECL_IS_OURS 1 extern int ocpf_yylex \ (YYSTYPE * yylval_param ,yyscan_t yyscanner); #define YY_DECL int ocpf_yylex \ (YYSTYPE * yylval_param , yyscan_t yyscanner) #endif /* !YY_DECL */ /* Code executed at the beginning of each rule, after yytext and yyleng * have been set up. */ #ifndef YY_USER_ACTION #define YY_USER_ACTION #endif /* Code executed at the end of each rule. */ #ifndef YY_BREAK #define YY_BREAK break; #endif #define YY_RULE_SETUP \ YY_USER_ACTION /** The main scanner function which does all the work. */ YY_DECL { register yy_state_type yy_current_state; register char *yy_cp, *yy_bp; register int yy_act; struct yyguts_t * yyg = (struct yyguts_t*)yyscanner; #line 64 "libocpf/lex.l" #line 903 "" yylval = yylval_param; if ( !yyg->yy_init ) { yyg->yy_init = 1; #ifdef YY_USER_INIT YY_USER_INIT; #endif if ( ! yyg->yy_start ) yyg->yy_start = 1; /* first start state */ if ( ! yyin ) yyin = stdin; if ( ! yyout ) yyout = stdout; if ( ! YY_CURRENT_BUFFER ) { ocpf_yyensure_buffer_stack (yyscanner); YY_CURRENT_BUFFER_LVALUE = ocpf_yy_create_buffer(yyin,YY_BUF_SIZE ,yyscanner); } ocpf_yy_load_buffer_state(yyscanner ); } while ( 1 ) /* loops until end-of-file is reached */ { yy_cp = yyg->yy_c_buf_p; /* Support of yytext. */ *yy_cp = yyg->yy_hold_char; /* yy_bp points to the position in yy_ch_buf of the start of * the current run. */ yy_bp = yy_cp; yy_current_state = yyg->yy_start; yy_match: do { register YY_CHAR yy_c = yy_ec[YY_SC_TO_UI(*yy_cp)]; if ( yy_accept[yy_current_state] ) { yyg->yy_last_accepting_state = yy_current_state; yyg->yy_last_accepting_cpos = yy_cp; } while ( yy_chk[yy_base[yy_current_state] + yy_c] != yy_current_state ) { yy_current_state = (int) yy_def[yy_current_state]; if ( yy_current_state >= 230 ) yy_c = yy_meta[(unsigned int) yy_c]; } yy_current_state = yy_nxt[yy_base[yy_current_state] + (unsigned int) yy_c]; ++yy_cp; } while ( yy_base[yy_current_state] != 357 ); yy_find_action: yy_act = yy_accept[yy_current_state]; if ( yy_act == 0 ) { /* have to back up */ yy_cp = yyg->yy_last_accepting_cpos; yy_current_state = yyg->yy_last_accepting_state; yy_act = yy_accept[yy_current_state]; } YY_DO_BEFORE_ACTION; do_action: /* This label is used only to access EOF actions. */ switch ( yy_act ) { /* beginning of action switch */ case 0: /* must back up */ /* undo the effects of YY_DO_BEFORE_ACTION */ *yy_cp = yyg->yy_hold_char; yy_cp = yyg->yy_last_accepting_cpos; yy_current_state = yyg->yy_last_accepting_state; goto yy_find_action; case 1: YY_RULE_SETUP #line 65 "libocpf/lex.l" { return kw_TYPE; } YY_BREAK case 2: YY_RULE_SETUP #line 66 "libocpf/lex.l" { return kw_FOLDER; } YY_BREAK case 3: YY_RULE_SETUP #line 67 "libocpf/lex.l" { return kw_OLEGUID; } YY_BREAK case 4: YY_RULE_SETUP #line 68 "libocpf/lex.l" { return kw_SET; } YY_BREAK case 5: YY_RULE_SETUP #line 69 "libocpf/lex.l" { return kw_PROPERTY; } YY_BREAK case 6: YY_RULE_SETUP #line 70 "libocpf/lex.l" { return kw_NPROPERTY; } YY_BREAK case 7: YY_RULE_SETUP #line 71 "libocpf/lex.l" { return kw_TO; } YY_BREAK case 8: YY_RULE_SETUP #line 72 "libocpf/lex.l" { return kw_CC; } YY_BREAK case 9: YY_RULE_SETUP #line 73 "libocpf/lex.l" { return kw_BCC; } YY_BREAK case 10: YY_RULE_SETUP #line 74 "libocpf/lex.l" { return kw_RECIPIENT; } YY_BREAK case 11: YY_RULE_SETUP #line 75 "libocpf/lex.l" { return kw_OOM; } YY_BREAK case 12: YY_RULE_SETUP #line 76 "libocpf/lex.l" { return kw_MNID_ID; } YY_BREAK case 13: YY_RULE_SETUP #line 77 "libocpf/lex.l" { return kw_MNID_STRING; } YY_BREAK case 14: YY_RULE_SETUP #line 78 "libocpf/lex.l" { return kw_PT_STRING8; } YY_BREAK case 15: YY_RULE_SETUP #line 79 "libocpf/lex.l" { return kw_PT_UNICODE; } YY_BREAK case 16: YY_RULE_SETUP #line 80 "libocpf/lex.l" { return kw_PT_SHORT; } YY_BREAK case 17: YY_RULE_SETUP #line 81 "libocpf/lex.l" { return kw_PT_LONG; } YY_BREAK case 18: YY_RULE_SETUP #line 82 "libocpf/lex.l" { return kw_PT_DOUBLE; } YY_BREAK case 19: YY_RULE_SETUP #line 83 "libocpf/lex.l" { return kw_PT_I8; } YY_BREAK case 20: YY_RULE_SETUP #line 84 "libocpf/lex.l" { return kw_PT_SYSTIME; } YY_BREAK case 21: YY_RULE_SETUP #line 85 "libocpf/lex.l" { return kw_PT_BOOLEAN; } YY_BREAK case 22: YY_RULE_SETUP #line 86 "libocpf/lex.l" { return kw_PT_LONG; } YY_BREAK case 23: YY_RULE_SETUP #line 87 "libocpf/lex.l" { return kw_PT_MV_STRING8; } YY_BREAK case 24: YY_RULE_SETUP #line 88 "libocpf/lex.l" { return kw_PT_MV_UNICODE; } YY_BREAK case 25: YY_RULE_SETUP #line 89 "libocpf/lex.l" { return kw_PT_BINARY; } YY_BREAK case 26: YY_RULE_SETUP #line 90 "libocpf/lex.l" { return kw_PT_MV_BINARY; } YY_BREAK case 27: YY_RULE_SETUP #line 91 "libocpf/lex.l" { return OBRACE; } YY_BREAK case 28: YY_RULE_SETUP #line 92 "libocpf/lex.l" { return EBRACE; } YY_BREAK case 29: YY_RULE_SETUP #line 93 "libocpf/lex.l" { return COMMA; } YY_BREAK case 30: YY_RULE_SETUP #line 94 "libocpf/lex.l" { return SEMICOLON; } YY_BREAK case 31: YY_RULE_SETUP #line 95 "libocpf/lex.l" { return COLON; } YY_BREAK case 32: YY_RULE_SETUP #line 96 "libocpf/lex.l" { return LOWER; } YY_BREAK case 33: YY_RULE_SETUP #line 97 "libocpf/lex.l" { return GREATER; } YY_BREAK case 34: YY_RULE_SETUP #line 98 "libocpf/lex.l" { return EQUAL;} YY_BREAK case 35: YY_RULE_SETUP #line 99 "libocpf/lex.l" { struct ocpf_context *ctx = yyextra; int c, start_lineno = ctx->lineno; int level = 1; int seen_star = 0; int seen_slash = 0; while((c = input(yyscanner)) != EOF) { if(c == '/') { if(seen_star) { if(--level == 0) break; seen_star = 0; continue; } seen_slash = 1; continue; } if(seen_star && c == '/') { if(--level == 0) break; seen_star = 0; continue; } if(c == '*') { if(seen_slash) { level++; seen_star = seen_slash = 0; continue; } seen_star = 1; continue; } seen_star = seen_slash = 0; if(c == '\n') { ctx->lineno++; continue; } } if(c == EOF) unterminated(ctx, "comment", start_lineno); } YY_BREAK case 36: YY_RULE_SETUP #line 140 "libocpf/lex.l" { struct ocpf_context *ctx = yyextra; int start_lineno = ctx->lineno; int c, c2; char buf[0x4000]; char *p = buf; int f = 0; int skip_ws = 0; while((c = input(yyscanner)) != EOF) { if(isspace(c) && skip_ws) { if(c == '\n') ctx->lineno++; continue; } skip_ws = 0; if (c == '\\') { c2 = c; c = input(yyscanner); if (c == '"') { *p++ = c; c = input(yyscanner); } else { *p++ = c2; } } if(c == '"') { if(f) { *p++ = '"'; f = 0; } else { f = 1; } continue; } if(f == 1) { unput(c); break; } if(c == '\n') { ctx->lineno++; while(p > buf && isspace((unsigned char)p[-1])) p--; skip_ws = 1; continue; } *p++ = c; } if(c == EOF) unterminated(ctx, "string", start_lineno); *p++ = '\0'; yylval->name = buf; return STRING; } YY_BREAK case 37: YY_RULE_SETUP #line 196 "libocpf/lex.l" { struct ocpf_context *ctx = yyextra; int start_lineno = ctx->lineno; int c, c2; char buf[0x4000]; char *p = buf; int f = 0; int skip_ws = 0; while((c = input(yyscanner)) != EOF) { if(isspace(c) && skip_ws) { if(c == '\n') ctx->lineno++; continue; } skip_ws = 0; if (c == '\\') { c2 = c; c = input(yyscanner); if (c == '"') { *p++ = c; c = input(yyscanner); } else { *p++ = c2; } } if(c == '"') { if(f) { *p++ = '"'; f = 0; } else { f = 1; } continue; } if(f == 1) { unput(c); break; } if(c == '\n') { ctx->lineno++; while(p > buf && isspace((unsigned char)p[-1])) p--; skip_ws = 1; continue; } *p++ = c; } if(c == EOF) unterminated(ctx, "string", start_lineno); *p++ = '\0'; yylval->name = buf; return UNICODE; } YY_BREAK case 38: YY_RULE_SETUP #line 252 "libocpf/lex.l" { char *y = yytext + 1; yylval->var = strdup((const char *)y); return VAR; } YY_BREAK case 39: YY_RULE_SETUP #line 256 "libocpf/lex.l" { char *y = yytext + 1; if (y && !strcmp(y, "\"true\"")) { yylval->b = true; } else { yylval->b = false; } return BOOLEAN; } YY_BREAK case 40: YY_RULE_SETUP #line 264 "libocpf/lex.l" { struct ocpf_context *ctx = yyextra; char *y = yytext + 1; char *e; yylval->dbl = strtod((const char *)y, &e); if (e == y) { ocpf_error_message(ctx, "malformed constant (%s)", yytext); } else { return DOUBLE; } } YY_BREAK case 41: YY_RULE_SETUP #line 275 "libocpf/lex.l" { yylval->date = strdup((const char *)yytext + 1); return SYSTIME; } YY_BREAK case 42: YY_RULE_SETUP #line 279 "libocpf/lex.l" { struct ocpf_context *ctx = yyextra; char *e, *y = yytext; yylval->i = strtoul((const char *)y, &e, 0); if (e == y) ocpf_error_message(ctx, "malformed constant (%s)", yytext); else return UINT8; } YY_BREAK case 43: YY_RULE_SETUP #line 288 "libocpf/lex.l" { struct ocpf_context *ctx = yyextra; char *e, *y = yytext; yylval->l = strtoul((const char *)y, &e, 0); if (e == y) ocpf_error_message(ctx, "malformed constant (%s)", yytext); else return INTEGER; } YY_BREAK case 44: YY_RULE_SETUP #line 298 "libocpf/lex.l" { struct ocpf_context *ctx = yyextra; char *e, *y; y = (yytext[0] == 'S') ? yytext + 1 : yytext; yylval->s = strtoul((const char *)y, &e, 0); if (e == y) ocpf_error_message(ctx, "malformed constant (%s)", yytext); else return SHORT; } YY_BREAK case 45: YY_RULE_SETUP #line 309 "libocpf/lex.l" { struct ocpf_context *ctx = yyextra; char *e, *y; y = (yytext[0] == 'L') ? yytext + 1 : yytext; yylval->l = strtoul((const char *)y, &e, 0); if(e == y) ocpf_error_message(ctx, "malformed constant (%s)", yytext); else return INTEGER; } YY_BREAK case 46: YY_RULE_SETUP #line 319 "libocpf/lex.l" { struct ocpf_context *ctx = yyextra; char *e, *y = yytext + 1; yylval->d = strtoull((const char *)y, &e, 0); if(e == y) ocpf_error_message(ctx, "malformed constant (%s)", yytext); else return I8; } YY_BREAK case 47: YY_RULE_SETUP #line 329 "libocpf/lex.l" { yylval->name = strdup((const char *)yytext); return IDENTIFIER; } YY_BREAK case 48: YY_RULE_SETUP #line 333 "libocpf/lex.l" ; YY_BREAK case 49: /* rule 49 can match eol */ YY_RULE_SETUP #line 334 "libocpf/lex.l" { struct ocpf_context *ctx = yyextra; ++ctx->lineno; } YY_BREAK case 50: YY_RULE_SETUP #line 338 "libocpf/lex.l" { struct ocpf_context *ctx = yyextra; ocpf_error_message(ctx, "Ignoring char(%c)\n", *yytext); } YY_BREAK case 51: YY_RULE_SETUP #line 342 "libocpf/lex.l" ECHO; YY_BREAK #line 1470 "" case YY_STATE_EOF(INITIAL): yyterminate(); case YY_END_OF_BUFFER: { /* Amount of text matched not including the EOB char. */ int yy_amount_of_matched_text = (int) (yy_cp - yyg->yytext_ptr) - 1; /* Undo the effects of YY_DO_BEFORE_ACTION. */ *yy_cp = yyg->yy_hold_char; YY_RESTORE_YY_MORE_OFFSET if ( YY_CURRENT_BUFFER_LVALUE->yy_buffer_status == YY_BUFFER_NEW ) { /* We're scanning a new file or input source. It's * possible that this happened because the user * just pointed yyin at a new source and called * ocpf_yylex(). If so, then we have to assure * consistency between YY_CURRENT_BUFFER and our * globals. Here is the right place to do so, because * this is the first action (other than possibly a * back-up) that will match for the new input source. */ yyg->yy_n_chars = YY_CURRENT_BUFFER_LVALUE->yy_n_chars; YY_CURRENT_BUFFER_LVALUE->yy_input_file = yyin; YY_CURRENT_BUFFER_LVALUE->yy_buffer_status = YY_BUFFER_NORMAL; } /* Note that here we test for yy_c_buf_p "<=" to the position * of the first EOB in the buffer, since yy_c_buf_p will * already have been incremented past the NUL character * (since all states make transitions on EOB to the * end-of-buffer state). Contrast this with the test * in input(). */ if ( yyg->yy_c_buf_p <= &YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[yyg->yy_n_chars] ) { /* This was really a NUL. */ yy_state_type yy_next_state; yyg->yy_c_buf_p = yyg->yytext_ptr + yy_amount_of_matched_text; yy_current_state = yy_get_previous_state( yyscanner ); /* Okay, we're now positioned to make the NUL * transition. We couldn't have * yy_get_previous_state() go ahead and do it * for us because it doesn't know how to deal * with the possibility of jamming (and we don't * want to build jamming into it because then it * will run more slowly). */ yy_next_state = yy_try_NUL_trans( yy_current_state , yyscanner); yy_bp = yyg->yytext_ptr + YY_MORE_ADJ; if ( yy_next_state ) { /* Consume the NUL. */ yy_cp = ++yyg->yy_c_buf_p; yy_current_state = yy_next_state; goto yy_match; } else { yy_cp = yyg->yy_c_buf_p; goto yy_find_action; } } else switch ( yy_get_next_buffer( yyscanner ) ) { case EOB_ACT_END_OF_FILE: { yyg->yy_did_buffer_switch_on_eof = 0; if ( ocpf_yywrap(yyscanner ) ) { /* Note: because we've taken care in * yy_get_next_buffer() to have set up * yytext, we can now set up * yy_c_buf_p so that if some total * hoser (like flex itself) wants to * call the scanner after we return the * YY_NULL, it'll still work - another * YY_NULL will get returned. */ yyg->yy_c_buf_p = yyg->yytext_ptr + YY_MORE_ADJ; yy_act = YY_STATE_EOF(YY_START); goto do_action; } else { if ( ! yyg->yy_did_buffer_switch_on_eof ) YY_NEW_FILE; } break; } case EOB_ACT_CONTINUE_SCAN: yyg->yy_c_buf_p = yyg->yytext_ptr + yy_amount_of_matched_text; yy_current_state = yy_get_previous_state( yyscanner ); yy_cp = yyg->yy_c_buf_p; yy_bp = yyg->yytext_ptr + YY_MORE_ADJ; goto yy_match; case EOB_ACT_LAST_MATCH: yyg->yy_c_buf_p = &YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[yyg->yy_n_chars]; yy_current_state = yy_get_previous_state( yyscanner ); yy_cp = yyg->yy_c_buf_p; yy_bp = yyg->yytext_ptr + YY_MORE_ADJ; goto yy_find_action; } break; } default: YY_FATAL_ERROR( "fatal flex scanner internal error--no action found" ); } /* end of action switch */ } /* end of scanning one token */ } /* end of ocpf_yylex */ /* yy_get_next_buffer - try to read in a new buffer * * Returns a code representing an action: * EOB_ACT_LAST_MATCH - * EOB_ACT_CONTINUE_SCAN - continue scanning from current position * EOB_ACT_END_OF_FILE - end of file */ static int yy_get_next_buffer (yyscan_t yyscanner) { struct yyguts_t * yyg = (struct yyguts_t*)yyscanner; register char *dest = YY_CURRENT_BUFFER_LVALUE->yy_ch_buf; register char *source = yyg->yytext_ptr; register int number_to_move, i; int ret_val; if ( yyg->yy_c_buf_p > &YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[yyg->yy_n_chars + 1] ) YY_FATAL_ERROR( "fatal flex scanner internal error--end of buffer missed" ); if ( YY_CURRENT_BUFFER_LVALUE->yy_fill_buffer == 0 ) { /* Don't try to fill the buffer, so this is an EOF. */ if ( yyg->yy_c_buf_p - yyg->yytext_ptr - YY_MORE_ADJ == 1 ) { /* We matched a single character, the EOB, so * treat this as a final EOF. */ return EOB_ACT_END_OF_FILE; } else { /* We matched some text prior to the EOB, first * process it. */ return EOB_ACT_LAST_MATCH; } } /* Try to read more data. */ /* First move last chars to start of buffer. */ number_to_move = (int) (yyg->yy_c_buf_p - yyg->yytext_ptr) - 1; for ( i = 0; i < number_to_move; ++i ) *(dest++) = *(source++); if ( YY_CURRENT_BUFFER_LVALUE->yy_buffer_status == YY_BUFFER_EOF_PENDING ) /* don't do the read, it's not guaranteed to return an EOF, * just force an EOF */ YY_CURRENT_BUFFER_LVALUE->yy_n_chars = yyg->yy_n_chars = 0; else { int num_to_read = YY_CURRENT_BUFFER_LVALUE->yy_buf_size - number_to_move - 1; while ( num_to_read <= 0 ) { /* Not enough room in the buffer - grow it. */ /* just a shorter name for the current buffer */ YY_BUFFER_STATE b = YY_CURRENT_BUFFER; int yy_c_buf_p_offset = (int) (yyg->yy_c_buf_p - b->yy_ch_buf); if ( b->yy_is_our_buffer ) { int new_size = b->yy_buf_size * 2; if ( new_size <= 0 ) b->yy_buf_size += b->yy_buf_size / 8; else b->yy_buf_size *= 2; b->yy_ch_buf = (char *) /* Include room in for 2 EOB chars. */ ocpf_yyrealloc((void *) b->yy_ch_buf,b->yy_buf_size + 2 ,yyscanner ); } else /* Can't grow it, we don't own it. */ b->yy_ch_buf = 0; if ( ! b->yy_ch_buf ) YY_FATAL_ERROR( "fatal error - scanner input buffer overflow" ); yyg->yy_c_buf_p = &b->yy_ch_buf[yy_c_buf_p_offset]; num_to_read = YY_CURRENT_BUFFER_LVALUE->yy_buf_size - number_to_move - 1; } if ( num_to_read > YY_READ_BUF_SIZE ) num_to_read = YY_READ_BUF_SIZE; /* Read in more data. */ YY_INPUT( (&YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[number_to_move]), yyg->yy_n_chars, (size_t) num_to_read ); YY_CURRENT_BUFFER_LVALUE->yy_n_chars = yyg->yy_n_chars; } if ( yyg->yy_n_chars == 0 ) { if ( number_to_move == YY_MORE_ADJ ) { ret_val = EOB_ACT_END_OF_FILE; ocpf_yyrestart(yyin ,yyscanner); } else { ret_val = EOB_ACT_LAST_MATCH; YY_CURRENT_BUFFER_LVALUE->yy_buffer_status = YY_BUFFER_EOF_PENDING; } } else ret_val = EOB_ACT_CONTINUE_SCAN; if ((yy_size_t) (yyg->yy_n_chars + number_to_move) > YY_CURRENT_BUFFER_LVALUE->yy_buf_size) { /* Extend the array by 50%, plus the number we really need. */ yy_size_t new_size = yyg->yy_n_chars + number_to_move + (yyg->yy_n_chars >> 1); YY_CURRENT_BUFFER_LVALUE->yy_ch_buf = (char *) ocpf_yyrealloc((void *) YY_CURRENT_BUFFER_LVALUE->yy_ch_buf,new_size ,yyscanner ); if ( ! YY_CURRENT_BUFFER_LVALUE->yy_ch_buf ) YY_FATAL_ERROR( "out of dynamic memory in yy_get_next_buffer()" ); } yyg->yy_n_chars += number_to_move; YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[yyg->yy_n_chars] = YY_END_OF_BUFFER_CHAR; YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[yyg->yy_n_chars + 1] = YY_END_OF_BUFFER_CHAR; yyg->yytext_ptr = &YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[0]; return ret_val; } /* yy_get_previous_state - get the state just before the EOB char was reached */ static yy_state_type yy_get_previous_state (yyscan_t yyscanner) { register yy_state_type yy_current_state; register char *yy_cp; struct yyguts_t * yyg = (struct yyguts_t*)yyscanner; yy_current_state = yyg->yy_start; for ( yy_cp = yyg->yytext_ptr + YY_MORE_ADJ; yy_cp < yyg->yy_c_buf_p; ++yy_cp ) { register YY_CHAR yy_c = (*yy_cp ? yy_ec[YY_SC_TO_UI(*yy_cp)] : 1); if ( yy_accept[yy_current_state] ) { yyg->yy_last_accepting_state = yy_current_state; yyg->yy_last_accepting_cpos = yy_cp; } while ( yy_chk[yy_base[yy_current_state] + yy_c] != yy_current_state ) { yy_current_state = (int) yy_def[yy_current_state]; if ( yy_current_state >= 230 ) yy_c = yy_meta[(unsigned int) yy_c]; } yy_current_state = yy_nxt[yy_base[yy_current_state] + (unsigned int) yy_c]; } return yy_current_state; } /* yy_try_NUL_trans - try to make a transition on the NUL character * * synopsis * next_state = yy_try_NUL_trans( current_state ); */ static yy_state_type yy_try_NUL_trans (yy_state_type yy_current_state , yyscan_t yyscanner) { register int yy_is_jam; struct yyguts_t * yyg = (struct yyguts_t*)yyscanner; /* This var may be unused depending upon options. */ register char *yy_cp = yyg->yy_c_buf_p; register YY_CHAR yy_c = 1; if ( yy_accept[yy_current_state] ) { yyg->yy_last_accepting_state = yy_current_state; yyg->yy_last_accepting_cpos = yy_cp; } while ( yy_chk[yy_base[yy_current_state] + yy_c] != yy_current_state ) { yy_current_state = (int) yy_def[yy_current_state]; if ( yy_current_state >= 230 ) yy_c = yy_meta[(unsigned int) yy_c]; } yy_current_state = yy_nxt[yy_base[yy_current_state] + (unsigned int) yy_c]; yy_is_jam = (yy_current_state == 229); return yy_is_jam ? 0 : yy_current_state; } static void yyunput (int c, register char * yy_bp , yyscan_t yyscanner) { register char *yy_cp; struct yyguts_t * yyg = (struct yyguts_t*)yyscanner; yy_cp = yyg->yy_c_buf_p; /* undo effects of setting up yytext */ *yy_cp = yyg->yy_hold_char; if ( yy_cp < YY_CURRENT_BUFFER_LVALUE->yy_ch_buf + 2 ) { /* need to shift things up to make room */ /* +2 for EOB chars. */ register int number_to_move = yyg->yy_n_chars + 2; register char *dest = &YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[ YY_CURRENT_BUFFER_LVALUE->yy_buf_size + 2]; register char *source = &YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[number_to_move]; while ( source > YY_CURRENT_BUFFER_LVALUE->yy_ch_buf ) *--dest = *--source; yy_cp += (int) (dest - source); yy_bp += (int) (dest - source); YY_CURRENT_BUFFER_LVALUE->yy_n_chars = yyg->yy_n_chars = YY_CURRENT_BUFFER_LVALUE->yy_buf_size; if ( yy_cp < YY_CURRENT_BUFFER_LVALUE->yy_ch_buf + 2 ) YY_FATAL_ERROR( "flex scanner push-back overflow" ); } *--yy_cp = (char) c; yyg->yytext_ptr = yy_bp; yyg->yy_hold_char = *yy_cp; yyg->yy_c_buf_p = yy_cp; } #ifndef YY_NO_INPUT #ifdef __cplusplus static int yyinput (yyscan_t yyscanner) #else static int input (yyscan_t yyscanner) #endif { int c; struct yyguts_t * yyg = (struct yyguts_t*)yyscanner; *yyg->yy_c_buf_p = yyg->yy_hold_char; if ( *yyg->yy_c_buf_p == YY_END_OF_BUFFER_CHAR ) { /* yy_c_buf_p now points to the character we want to return. * If this occurs *before* the EOB characters, then it's a * valid NUL; if not, then we've hit the end of the buffer. */ if ( yyg->yy_c_buf_p < &YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[yyg->yy_n_chars] ) /* This was really a NUL. */ *yyg->yy_c_buf_p = '\0'; else { /* need more input */ int offset = yyg->yy_c_buf_p - yyg->yytext_ptr; ++yyg->yy_c_buf_p; switch ( yy_get_next_buffer( yyscanner ) ) { case EOB_ACT_LAST_MATCH: /* This happens because yy_g_n_b() * sees that we've accumulated a * token and flags that we need to * try matching the token before * proceeding. But for input(), * there's no matching to consider. * So convert the EOB_ACT_LAST_MATCH * to EOB_ACT_END_OF_FILE. */ /* Reset buffer status. */ ocpf_yyrestart(yyin ,yyscanner); /*FALLTHROUGH*/ case EOB_ACT_END_OF_FILE: { if ( ocpf_yywrap(yyscanner ) ) return EOF; if ( ! yyg->yy_did_buffer_switch_on_eof ) YY_NEW_FILE; #ifdef __cplusplus return yyinput(yyscanner); #else return input(yyscanner); #endif } case EOB_ACT_CONTINUE_SCAN: yyg->yy_c_buf_p = yyg->yytext_ptr + offset; break; } } } c = *(unsigned char *) yyg->yy_c_buf_p; /* cast for 8-bit char's */ *yyg->yy_c_buf_p = '\0'; /* preserve yytext */ yyg->yy_hold_char = *++yyg->yy_c_buf_p; return c; } #endif /* ifndef YY_NO_INPUT */ /** Immediately switch to a different input stream. * @param input_file A readable stream. * @param yyscanner The scanner object. * @note This function does not reset the start condition to @c INITIAL . */ void ocpf_yyrestart (FILE * input_file , yyscan_t yyscanner) { struct yyguts_t * yyg = (struct yyguts_t*)yyscanner; if ( ! YY_CURRENT_BUFFER ){ ocpf_yyensure_buffer_stack (yyscanner); YY_CURRENT_BUFFER_LVALUE = ocpf_yy_create_buffer(yyin,YY_BUF_SIZE ,yyscanner); } ocpf_yy_init_buffer(YY_CURRENT_BUFFER,input_file ,yyscanner); ocpf_yy_load_buffer_state(yyscanner ); } /** Switch to a different input buffer. * @param new_buffer The new input buffer. * @param yyscanner The scanner object. */ void ocpf_yy_switch_to_buffer (YY_BUFFER_STATE new_buffer , yyscan_t yyscanner) { struct yyguts_t * yyg = (struct yyguts_t*)yyscanner; /* TODO. We should be able to replace this entire function body * with * ocpf_yypop_buffer_state(); * ocpf_yypush_buffer_state(new_buffer); */ ocpf_yyensure_buffer_stack (yyscanner); if ( YY_CURRENT_BUFFER == new_buffer ) return; if ( YY_CURRENT_BUFFER ) { /* Flush out information for old buffer. */ *yyg->yy_c_buf_p = yyg->yy_hold_char; YY_CURRENT_BUFFER_LVALUE->yy_buf_pos = yyg->yy_c_buf_p; YY_CURRENT_BUFFER_LVALUE->yy_n_chars = yyg->yy_n_chars; } YY_CURRENT_BUFFER_LVALUE = new_buffer; ocpf_yy_load_buffer_state(yyscanner ); /* We don't actually know whether we did this switch during * EOF (ocpf_yywrap()) processing, but the only time this flag * is looked at is after ocpf_yywrap() is called, so it's safe * to go ahead and always set it. */ yyg->yy_did_buffer_switch_on_eof = 1; } static void ocpf_yy_load_buffer_state (yyscan_t yyscanner) { struct yyguts_t * yyg = (struct yyguts_t*)yyscanner; yyg->yy_n_chars = YY_CURRENT_BUFFER_LVALUE->yy_n_chars; yyg->yytext_ptr = yyg->yy_c_buf_p = YY_CURRENT_BUFFER_LVALUE->yy_buf_pos; yyin = YY_CURRENT_BUFFER_LVALUE->yy_input_file; yyg->yy_hold_char = *yyg->yy_c_buf_p; } /** Allocate and initialize an input buffer state. * @param file A readable stream. * @param size The character buffer size in bytes. When in doubt, use @c YY_BUF_SIZE. * @param yyscanner The scanner object. * @return the allocated buffer state. */ YY_BUFFER_STATE ocpf_yy_create_buffer (FILE * file, int size , yyscan_t yyscanner) { YY_BUFFER_STATE b; b = (YY_BUFFER_STATE) ocpf_yyalloc(sizeof( struct yy_buffer_state ) ,yyscanner ); if ( ! b ) YY_FATAL_ERROR( "out of dynamic memory in ocpf_yy_create_buffer()" ); b->yy_buf_size = size; /* yy_ch_buf has to be 2 characters longer than the size given because * we need to put in 2 end-of-buffer characters. */ b->yy_ch_buf = (char *) ocpf_yyalloc(b->yy_buf_size + 2 ,yyscanner ); if ( ! b->yy_ch_buf ) YY_FATAL_ERROR( "out of dynamic memory in ocpf_yy_create_buffer()" ); b->yy_is_our_buffer = 1; ocpf_yy_init_buffer(b,file ,yyscanner); return b; } /** Destroy the buffer. * @param b a buffer created with ocpf_yy_create_buffer() * @param yyscanner The scanner object. */ void ocpf_yy_delete_buffer (YY_BUFFER_STATE b , yyscan_t yyscanner) { struct yyguts_t * yyg = (struct yyguts_t*)yyscanner; if ( ! b ) return; if ( b == YY_CURRENT_BUFFER ) /* Not sure if we should pop here. */ YY_CURRENT_BUFFER_LVALUE = (YY_BUFFER_STATE) 0; if ( b->yy_is_our_buffer ) ocpf_yyfree((void *) b->yy_ch_buf ,yyscanner ); ocpf_yyfree((void *) b ,yyscanner ); } #ifndef __cplusplus extern int isatty (int ); #endif /* __cplusplus */ /* Initializes or reinitializes a buffer. * This function is sometimes called more than once on the same buffer, * such as during a ocpf_yyrestart() or at EOF. */ static void ocpf_yy_init_buffer (YY_BUFFER_STATE b, FILE * file , yyscan_t yyscanner) { int oerrno = errno; struct yyguts_t * yyg = (struct yyguts_t*)yyscanner; ocpf_yy_flush_buffer(b ,yyscanner); b->yy_input_file = file; b->yy_fill_buffer = 1; /* If b is the current buffer, then ocpf_yy_init_buffer was _probably_ * called from ocpf_yyrestart() or through yy_get_next_buffer. * In that case, we don't want to reset the lineno or column. */ if (b != YY_CURRENT_BUFFER){ b->yy_bs_lineno = 1; b->yy_bs_column = 0; } b->yy_is_interactive = file ? (isatty( fileno(file) ) > 0) : 0; errno = oerrno; } /** Discard all buffered characters. On the next scan, YY_INPUT will be called. * @param b the buffer state to be flushed, usually @c YY_CURRENT_BUFFER. * @param yyscanner The scanner object. */ void ocpf_yy_flush_buffer (YY_BUFFER_STATE b , yyscan_t yyscanner) { struct yyguts_t * yyg = (struct yyguts_t*)yyscanner; if ( ! b ) return; b->yy_n_chars = 0; /* We always need two end-of-buffer characters. The first causes * a transition to the end-of-buffer state. The second causes * a jam in that state. */ b->yy_ch_buf[0] = YY_END_OF_BUFFER_CHAR; b->yy_ch_buf[1] = YY_END_OF_BUFFER_CHAR; b->yy_buf_pos = &b->yy_ch_buf[0]; b->yy_at_bol = 1; b->yy_buffer_status = YY_BUFFER_NEW; if ( b == YY_CURRENT_BUFFER ) ocpf_yy_load_buffer_state(yyscanner ); } /** Pushes the new state onto the stack. The new state becomes * the current state. This function will allocate the stack * if necessary. * @param new_buffer The new state. * @param yyscanner The scanner object. */ void ocpf_yypush_buffer_state (YY_BUFFER_STATE new_buffer , yyscan_t yyscanner) { struct yyguts_t * yyg = (struct yyguts_t*)yyscanner; if (new_buffer == NULL) return; ocpf_yyensure_buffer_stack(yyscanner); /* This block is copied from ocpf_yy_switch_to_buffer. */ if ( YY_CURRENT_BUFFER ) { /* Flush out information for old buffer. */ *yyg->yy_c_buf_p = yyg->yy_hold_char; YY_CURRENT_BUFFER_LVALUE->yy_buf_pos = yyg->yy_c_buf_p; YY_CURRENT_BUFFER_LVALUE->yy_n_chars = yyg->yy_n_chars; } /* Only push if top exists. Otherwise, replace top. */ if (YY_CURRENT_BUFFER) yyg->yy_buffer_stack_top++; YY_CURRENT_BUFFER_LVALUE = new_buffer; /* copied from ocpf_yy_switch_to_buffer. */ ocpf_yy_load_buffer_state(yyscanner ); yyg->yy_did_buffer_switch_on_eof = 1; } /** Removes and deletes the top of the stack, if present. * The next element becomes the new top. * @param yyscanner The scanner object. */ void ocpf_yypop_buffer_state (yyscan_t yyscanner) { struct yyguts_t * yyg = (struct yyguts_t*)yyscanner; if (!YY_CURRENT_BUFFER) return; ocpf_yy_delete_buffer(YY_CURRENT_BUFFER ,yyscanner); YY_CURRENT_BUFFER_LVALUE = NULL; if (yyg->yy_buffer_stack_top > 0) --yyg->yy_buffer_stack_top; if (YY_CURRENT_BUFFER) { ocpf_yy_load_buffer_state(yyscanner ); yyg->yy_did_buffer_switch_on_eof = 1; } } /* Allocates the stack if it does not exist. * Guarantees space for at least one push. */ static void ocpf_yyensure_buffer_stack (yyscan_t yyscanner) { int num_to_alloc; struct yyguts_t * yyg = (struct yyguts_t*)yyscanner; if (!yyg->yy_buffer_stack) { /* First allocation is just for 2 elements, since we don't know if this * scanner will even need a stack. We use 2 instead of 1 to avoid an * immediate realloc on the next call. */ num_to_alloc = 1; yyg->yy_buffer_stack = (struct yy_buffer_state**)ocpf_yyalloc (num_to_alloc * sizeof(struct yy_buffer_state*) , yyscanner); if ( ! yyg->yy_buffer_stack ) YY_FATAL_ERROR( "out of dynamic memory in ocpf_yyensure_buffer_stack()" ); memset(yyg->yy_buffer_stack, 0, num_to_alloc * sizeof(struct yy_buffer_state*)); yyg->yy_buffer_stack_max = num_to_alloc; yyg->yy_buffer_stack_top = 0; return; } if (yyg->yy_buffer_stack_top >= (yyg->yy_buffer_stack_max) - 1){ /* Increase the buffer to prepare for a possible push. */ int grow_size = 8 /* arbitrary grow size */; num_to_alloc = yyg->yy_buffer_stack_max + grow_size; yyg->yy_buffer_stack = (struct yy_buffer_state**)ocpf_yyrealloc (yyg->yy_buffer_stack, num_to_alloc * sizeof(struct yy_buffer_state*) , yyscanner); if ( ! yyg->yy_buffer_stack ) YY_FATAL_ERROR( "out of dynamic memory in ocpf_yyensure_buffer_stack()" ); /* zero only the new slots.*/ memset(yyg->yy_buffer_stack + yyg->yy_buffer_stack_max, 0, grow_size * sizeof(struct yy_buffer_state*)); yyg->yy_buffer_stack_max = num_to_alloc; } } /** Setup the input buffer state to scan directly from a user-specified character buffer. * @param base the character buffer * @param size the size in bytes of the character buffer * @param yyscanner The scanner object. * @return the newly allocated buffer state object. */ YY_BUFFER_STATE ocpf_yy_scan_buffer (char * base, yy_size_t size , yyscan_t yyscanner) { YY_BUFFER_STATE b; if ( size < 2 || base[size-2] != YY_END_OF_BUFFER_CHAR || base[size-1] != YY_END_OF_BUFFER_CHAR ) /* They forgot to leave room for the EOB's. */ return 0; b = (YY_BUFFER_STATE) ocpf_yyalloc(sizeof( struct yy_buffer_state ) ,yyscanner ); if ( ! b ) YY_FATAL_ERROR( "out of dynamic memory in ocpf_yy_scan_buffer()" ); b->yy_buf_size = size - 2; /* "- 2" to take care of EOB's */ b->yy_buf_pos = b->yy_ch_buf = base; b->yy_is_our_buffer = 0; b->yy_input_file = 0; b->yy_n_chars = b->yy_buf_size; b->yy_is_interactive = 0; b->yy_at_bol = 1; b->yy_fill_buffer = 0; b->yy_buffer_status = YY_BUFFER_NEW; ocpf_yy_switch_to_buffer(b ,yyscanner ); return b; } /** Setup the input buffer state to scan a string. The next call to ocpf_yylex() will * scan from a @e copy of @a str. * @param yystr a NUL-terminated string to scan * @param yyscanner The scanner object. * @return the newly allocated buffer state object. * @note If you want to scan bytes that may contain NUL values, then use * ocpf_yy_scan_bytes() instead. */ YY_BUFFER_STATE ocpf_yy_scan_string (yyconst char * yystr , yyscan_t yyscanner) { return ocpf_yy_scan_bytes(yystr,strlen(yystr) ,yyscanner); } /** Setup the input buffer state to scan the given bytes. The next call to ocpf_yylex() will * scan from a @e copy of @a bytes. * @param yybytes the byte buffer to scan * @param _yybytes_len the number of bytes in the buffer pointed to by @a bytes. * @param yyscanner The scanner object. * @return the newly allocated buffer state object. */ YY_BUFFER_STATE ocpf_yy_scan_bytes (yyconst char * yybytes, int _yybytes_len , yyscan_t yyscanner) { YY_BUFFER_STATE b; char *buf; yy_size_t n; int i; /* Get memory for full buffer, including space for trailing EOB's. */ n = _yybytes_len + 2; buf = (char *) ocpf_yyalloc(n ,yyscanner ); if ( ! buf ) YY_FATAL_ERROR( "out of dynamic memory in ocpf_yy_scan_bytes()" ); for ( i = 0; i < _yybytes_len; ++i ) buf[i] = yybytes[i]; buf[_yybytes_len] = buf[_yybytes_len+1] = YY_END_OF_BUFFER_CHAR; b = ocpf_yy_scan_buffer(buf,n ,yyscanner); if ( ! b ) YY_FATAL_ERROR( "bad buffer in ocpf_yy_scan_bytes()" ); /* It's okay to grow etc. this buffer, and we should throw it * away when we're done. */ b->yy_is_our_buffer = 1; return b; } #ifndef YY_EXIT_FAILURE #define YY_EXIT_FAILURE 2 #endif static void yy_fatal_error (yyconst char* msg , yyscan_t yyscanner) { (void) fprintf( stderr, "%s\n", msg ); exit( YY_EXIT_FAILURE ); } /* Redefine yyless() so it works in section 3 code. */ #undef yyless #define yyless(n) \ do \ { \ /* Undo effects of setting up yytext. */ \ int yyless_macro_arg = (n); \ YY_LESS_LINENO(yyless_macro_arg);\ yytext[yyleng] = yyg->yy_hold_char; \ yyg->yy_c_buf_p = yytext + yyless_macro_arg; \ yyg->yy_hold_char = *yyg->yy_c_buf_p; \ *yyg->yy_c_buf_p = '\0'; \ yyleng = yyless_macro_arg; \ } \ while ( 0 ) /* Accessor methods (get/set functions) to struct members. */ /** Get the user-defined data for this scanner. * @param yyscanner The scanner object. */ YY_EXTRA_TYPE ocpf_yyget_extra (yyscan_t yyscanner) { struct yyguts_t * yyg = (struct yyguts_t*)yyscanner; return yyextra; } /** Get the current line number. * @param yyscanner The scanner object. */ int ocpf_yyget_lineno (yyscan_t yyscanner) { struct yyguts_t * yyg = (struct yyguts_t*)yyscanner; if (! YY_CURRENT_BUFFER) return 0; return yylineno; } /** Get the current column number. * @param yyscanner The scanner object. */ int ocpf_yyget_column (yyscan_t yyscanner) { struct yyguts_t * yyg = (struct yyguts_t*)yyscanner; if (! YY_CURRENT_BUFFER) return 0; return yycolumn; } /** Get the input stream. * @param yyscanner The scanner object. */ FILE *ocpf_yyget_in (yyscan_t yyscanner) { struct yyguts_t * yyg = (struct yyguts_t*)yyscanner; return yyin; } /** Get the output stream. * @param yyscanner The scanner object. */ FILE *ocpf_yyget_out (yyscan_t yyscanner) { struct yyguts_t * yyg = (struct yyguts_t*)yyscanner; return yyout; } /** Get the length of the current token. * @param yyscanner The scanner object. */ int ocpf_yyget_leng (yyscan_t yyscanner) { struct yyguts_t * yyg = (struct yyguts_t*)yyscanner; return yyleng; } /** Get the current token. * @param yyscanner The scanner object. */ char *ocpf_yyget_text (yyscan_t yyscanner) { struct yyguts_t * yyg = (struct yyguts_t*)yyscanner; return yytext; } /** Set the user-defined data. This data is never touched by the scanner. * @param user_defined The data to be associated with this scanner. * @param yyscanner The scanner object. */ void ocpf_yyset_extra (YY_EXTRA_TYPE user_defined , yyscan_t yyscanner) { struct yyguts_t * yyg = (struct yyguts_t*)yyscanner; yyextra = user_defined ; } /** Set the current line number. * @param line_number * @param yyscanner The scanner object. */ void ocpf_yyset_lineno (int line_number , yyscan_t yyscanner) { struct yyguts_t * yyg = (struct yyguts_t*)yyscanner; /* lineno is only valid if an input buffer exists. */ if (! YY_CURRENT_BUFFER ) yy_fatal_error( "ocpf_yyset_lineno called with no buffer" , yyscanner); yylineno = line_number; } /** Set the current column. * @param line_number * @param yyscanner The scanner object. */ void ocpf_yyset_column (int column_no , yyscan_t yyscanner) { struct yyguts_t * yyg = (struct yyguts_t*)yyscanner; /* column is only valid if an input buffer exists. */ if (! YY_CURRENT_BUFFER ) yy_fatal_error( "ocpf_yyset_column called with no buffer" , yyscanner); yycolumn = column_no; } /** Set the input stream. This does not discard the current * input buffer. * @param in_str A readable stream. * @param yyscanner The scanner object. * @see ocpf_yy_switch_to_buffer */ void ocpf_yyset_in (FILE * in_str , yyscan_t yyscanner) { struct yyguts_t * yyg = (struct yyguts_t*)yyscanner; yyin = in_str ; } void ocpf_yyset_out (FILE * out_str , yyscan_t yyscanner) { struct yyguts_t * yyg = (struct yyguts_t*)yyscanner; yyout = out_str ; } int ocpf_yyget_debug (yyscan_t yyscanner) { struct yyguts_t * yyg = (struct yyguts_t*)yyscanner; return yy_flex_debug; } void ocpf_yyset_debug (int bdebug , yyscan_t yyscanner) { struct yyguts_t * yyg = (struct yyguts_t*)yyscanner; yy_flex_debug = bdebug ; } /* Accessor methods for yylval and yylloc */ YYSTYPE * ocpf_yyget_lval (yyscan_t yyscanner) { struct yyguts_t * yyg = (struct yyguts_t*)yyscanner; return yylval; } void ocpf_yyset_lval (YYSTYPE * yylval_param , yyscan_t yyscanner) { struct yyguts_t * yyg = (struct yyguts_t*)yyscanner; yylval = yylval_param; } /* User-visible API */ /* ocpf_yylex_init is special because it creates the scanner itself, so it is * the ONLY reentrant function that doesn't take the scanner as the last argument. * That's why we explicitly handle the declaration, instead of using our macros. */ int ocpf_yylex_init(yyscan_t* ptr_yy_globals) { if (ptr_yy_globals == NULL){ errno = EINVAL; return 1; } *ptr_yy_globals = (yyscan_t) ocpf_yyalloc ( sizeof( struct yyguts_t ), NULL ); if (*ptr_yy_globals == NULL){ errno = ENOMEM; return 1; } /* By setting to 0xAA, we expose bugs in yy_init_globals. Leave at 0x00 for releases. */ memset(*ptr_yy_globals,0x00,sizeof(struct yyguts_t)); return yy_init_globals ( *ptr_yy_globals ); } /* ocpf_yylex_init_extra has the same functionality as ocpf_yylex_init, but follows the * convention of taking the scanner as the last argument. Note however, that * this is a *pointer* to a scanner, as it will be allocated by this call (and * is the reason, too, why this function also must handle its own declaration). * The user defined value in the first argument will be available to ocpf_yyalloc in * the yyextra field. */ int ocpf_yylex_init_extra(YY_EXTRA_TYPE yy_user_defined,yyscan_t* ptr_yy_globals ) { struct yyguts_t dummy_yyguts; ocpf_yyset_extra (yy_user_defined, &dummy_yyguts); if (ptr_yy_globals == NULL){ errno = EINVAL; return 1; } *ptr_yy_globals = (yyscan_t) ocpf_yyalloc ( sizeof( struct yyguts_t ), &dummy_yyguts ); if (*ptr_yy_globals == NULL){ errno = ENOMEM; return 1; } /* By setting to 0xAA, we expose bugs in yy_init_globals. Leave at 0x00 for releases. */ memset(*ptr_yy_globals,0x00,sizeof(struct yyguts_t)); ocpf_yyset_extra (yy_user_defined, *ptr_yy_globals); return yy_init_globals ( *ptr_yy_globals ); } static int yy_init_globals (yyscan_t yyscanner) { struct yyguts_t * yyg = (struct yyguts_t*)yyscanner; /* Initialization is the same as for the non-reentrant scanner. * This function is called from ocpf_yylex_destroy(), so don't allocate here. */ yyg->yy_buffer_stack = 0; yyg->yy_buffer_stack_top = 0; yyg->yy_buffer_stack_max = 0; yyg->yy_c_buf_p = (char *) 0; yyg->yy_init = 0; yyg->yy_start = 0; yyg->yy_start_stack_ptr = 0; yyg->yy_start_stack_depth = 0; yyg->yy_start_stack = NULL; /* Defined in main.c */ #ifdef YY_STDINIT yyin = stdin; yyout = stdout; #else yyin = (FILE *) 0; yyout = (FILE *) 0; #endif /* For future reference: Set errno on error, since we are called by * ocpf_yylex_init() */ return 0; } /* ocpf_yylex_destroy is for both reentrant and non-reentrant scanners. */ int ocpf_yylex_destroy (yyscan_t yyscanner) { struct yyguts_t * yyg = (struct yyguts_t*)yyscanner; /* Pop the buffer stack, destroying each element. */ while(YY_CURRENT_BUFFER){ ocpf_yy_delete_buffer(YY_CURRENT_BUFFER ,yyscanner ); YY_CURRENT_BUFFER_LVALUE = NULL; ocpf_yypop_buffer_state(yyscanner); } /* Destroy the stack itself. */ ocpf_yyfree(yyg->yy_buffer_stack ,yyscanner); yyg->yy_buffer_stack = NULL; /* Destroy the start condition stack. */ ocpf_yyfree(yyg->yy_start_stack ,yyscanner ); yyg->yy_start_stack = NULL; /* Reset the globals. This is important in a non-reentrant scanner so the next time * ocpf_yylex() is called, initialization will occur. */ yy_init_globals( yyscanner); /* Destroy the main struct (reentrant only). */ ocpf_yyfree ( yyscanner , yyscanner ); yyscanner = NULL; return 0; } /* * Internal utility routines. */ #ifndef yytext_ptr static void yy_flex_strncpy (char* s1, yyconst char * s2, int n , yyscan_t yyscanner) { register int i; for ( i = 0; i < n; ++i ) s1[i] = s2[i]; } #endif #ifdef YY_NEED_STRLEN static int yy_flex_strlen (yyconst char * s , yyscan_t yyscanner) { register int n; for ( n = 0; s[n]; ++n ) ; return n; } #endif void *ocpf_yyalloc (yy_size_t size , yyscan_t yyscanner) { return (void *) malloc( size ); } void *ocpf_yyrealloc (void * ptr, yy_size_t size , yyscan_t yyscanner) { /* The cast to (char *) in the following accommodates both * implementations that use char* generic pointers, and those * that use void* generic pointers. It works with the latter * because both ANSI C and C++ allow castless assignment from * any pointer type to void*, and deal with argument conversions * as though doing an assignment. */ return (void *) realloc( (char *) ptr, size ); } void ocpf_yyfree (void * ptr , yyscan_t yyscanner) { free( (char *) ptr ); /* see ocpf_yyrealloc() for (char *) cast */ } #define YYTABLES_NAME "yytables" #line 342 "libocpf/lex.l" void ocpf_error_message(struct ocpf_context *ctx, const char *format, ...) { va_list args; va_start(args, format); fprintf(stderr, "ERROR: %s:%d: ", ctx->filename, ctx->lineno); vfprintf(stderr, format, args); va_end(args); error_flag++; fflush(0); } static void unterminated(struct ocpf_context *ctx, const char *type, unsigned int start_lineno) { ocpf_error_message(ctx, "unterminated %s, possibly started on line %d\n", type, start_lineno); fflush(0); } openchange-2.0/libocpf/ocpf-documentation.doxy000066400000000000000000000711711223057412600216140ustar00rootroot00000000000000/** \mainpage OpenChange Property File (OCPF) \section ocpf OpenChange Property File (OCPF) \section Contents

Revision History

Date Revision Number Author Revision Content
27/11/10 0.7 Brad Hards Add PT_DOUBLE support. Update PT_I8 description.
27/11/10 0.6.1 Brad Hards Update bug tracker link, minor rewording
25/06/10 0.6 Julien Kerihuel Add PT_MV_BINARY, PT_MV_LONG and PT_MV_UNICODE support. Update PT_BINARY description.
01/04/08 0.5 Julien Kerihuel Add RECIPIENT support
29/03/08 0.4 Julien Kerihuel Add PT_UNICODE support and ocpf_dump option
06/03/08 0.3 Julien Kerihuel Add PT_BINARY and Streams support
05/03/08 0.2 Julien Kerihuel Improve PT_MV_STRING8 support
03/03/08 0.1 Julien Kerihuel Initial Revision

1. Introduction

OCPF stands for OpenChange Property Files. This is a tiny file format designed for scripting and which facilitates third-party applications interaction and developers work using OpenChange. The main objective of OCPF is to offer the possibility to go beyond OpenChange tools default properties and create a custom message with user-defined fields.

2. Purpose and Scope

OCPF is designed to be used in various kind of applications and for different purposes:
  • Research on properties: OpenChange developers have often requested for an easy way to test properties and properties values. Prior to OCPF, developers had to write an application linked with libmapi and compile it so that they could test properties. Moreover, adding new named properties in trunk required commit permission to OpenChange source repository. OCPF solves this issue and allow developers to write OCPF files with custom properties that they can send using OpenChange tools. Furthermore OCPF will provide the community a convenient way to agree on a particular property.
  • Web Applications: OCPF offers a scripted language with substitution variables which makes it possible to use OCPF templates and use OCPF in conjunction with Web Forms. Since OCPF API supports the parsing of multiple files, developers can plan to have a file with variable declarations and a separate OCPF template that just specifies variables.
  • Backup/Restore: OCPF format may offer an easy way for a restore/backup application to dump to the local filesystem and restore messages on Exchange server. Furthermore, substitution of variables can possibly be used to maintain the new hierarchy, such as changing folders ID across Exchange servers and help migrating database from a server to another.

3. Limitations and Bugs

OCPF is a pretty new library and it currently has a some limitations:
  • It only supports a very limited set of property types
  • It doesn't support attachment yet
These limitations will be removed in later versions of OCPF. If you find bugs, limitations or encounter issues while using the OCPF library, please consider reporting them on http://tracker.openchange.org. (Note: registration is required to create new tickets). For questions about its usage or about libocpf development, please post on the OpenChange devel mailing-list.

4. Syntax

The general OCPF syntax is pretty basic. It mostly consists of top-level keywords, sections and properties types.

5. Top Level Keywords

5.1 TYPE

  • Format: \code TYPE STRING \endcode
  • Description: This keyword specifies the message class of the message. Users can either specify their custom type or use on of the following standard values:
    • "IPM.Appointment"
    • "IPM.Contact"
    • "IPM.Journal"
    • "IPM.Note"
    • "IPM.StickyNote"
    • "IPM.Task"
    • "IPM.Post"
  • Note: TYPE can only be defined once and takes a string value as parameter. String values must be quoted otherwise a syntax error will be displayed on output.
  • Example: \code TYPE "IPM.Appointment" \endcode

5.2 FOLDER

  • Format: \code FOLDER STRING FOLDER PT_I8 FOLDER VAR \endcode
  • Description: This keyword defines the destination folder of the message. Users can either specify a default folder using the string value or a custom folder ID using its PR_FID value. It is also possible to substitute the value with a variable, but it is limited to PT_I8 values. When FOLDER is set with a PT_I8 custom value and the ocpf_OpenFolder public function used, it can be set to any folder identifier within the message store. The function will loop over mailbox folders until it finds the folder with the given folder ID and opens it. Possible STRING values:
    • olFolderTopInformationStore
    • olFolderDeletedItems
    • olFolderOutbox
    • olFolderSentMail
    • olFolderInbox
    • olFolderCommonView
    • olFolderCalendar
    • olFolderContacts
    • olFolderJournal
    • olFolderNotes
    • olFolderTasks
  • Note: FOLDER can only be defined once.
  • Examples: \code FOLDER "olFolderCalendar" \endcode or \code FOLDER D0x9504000000000001 \endcode or \code SET $folder_id = D0x9504000000000001 FOLDER $folder_id \endcode

5.3. SET

  • Format: \code SET VAR = PROPVALUE \endcode
  • Description: This keyword registers a variable named VAR and sets its value to PROPVALUE. Variables must be prefixed with a dollar sign ($) and their value can be set to any supported property type. See section on property values for further information.
  • Note: SET can be used as many times as needed by the user, however VAR name must remain unique. When a variable name is registered for the second time, the OCPF parser displays a warning on the standard output and skips the assignment.
  • Example: \code SET $var1 = 0xdeadbeef SET $var2 = "Hello World" SET $var3 = T2008-03-06 23:30:00 \endcode

5.4. OLEGUID

  • Format: \code OLEGUID IDENTIFIER STRING \endcode
  • Description: This keyword registers an OLEGUID couple (IDENTIFIER and STRING value) that can then be used when declaring named properties (see NPROPERTY). OLEGUID keyword takes two parameters: first the name, used with named properties (PSETID_Appointment, PS_PUBLIC_STRINGS etc.) and secondly a string representing a GUID value.
  • Note: OLEGUID are identified by their IDENTIFIER and STRING. Users can't register the same OLEGUID IDENTIFIER or STRING twice. If such case occurs, a warning message will be displayed on stdout.
  • Example: \code OLEGUID PSETID_Appointment "00062002-0000-0000-c000-000000000046" [...] NPROPERTY { OOM:Label:PSETID_Appointment = T2008-03-06 23:30:00 [...] \endcode

5.5. RECIPIENT

  • Format: \code RECIPIENT TO STRING;STRING;STRING RECIPIENT CC STRING;STRING RECIPIENT BCC STRING \endcode
  • Description: This keyword declares recipients. RECIPIENT is followed by a recipient type (TO, CC or BCC) and a set of STRING (recipients) separated with semicolon.
  • Example: \code RECIPIENT TO "recipient1";"recipient2";"recipient3" RECIPIENT CC "recipient4" RECIPIENT BCC "recipient5@remote.corp";"recipient6" \endcode

5.6. PROPERTY section

  • Format: \code PROPERTY { [...] }; \endcode
  • Description: This keyword declares a known property section. PROPERTY is followed by an opening brace, a set of property declarations and is ended with a closing brace and semicolon. This section only recognizes properties as described in 6. Known properties.
  • Note: While we suggest keeping a single PROPERTY section, nothing prevents the user from declaring as many PROPERTY sections as needed.
  • Example: \code PROPERTY { PR_SUBJECT = "Hello World" 0x1000001e = "Sample body content" }; \endcode

5.7. NPROPERTY section

  • Format: \code NPROPERTY { [...] }; \endcode
  • Description: This keyword declares a named property section. NPROPERTY is followed by an opening brace, a set of named properties declarations and is ended with a closing brace and semicolon. This section only recognizes named properties as described in 7. Named Properties.
  • Note: While we suggest keeping a single NPROPERTY section, nothing prevents the user from declaring as many NPROPERTY sections as needed.
  • Example: \code NPROPERTY { OOM:Start:PSETID_Appointment = T2008-03-06 22:00:00 OOM:Location:PSETID_Appointment = "Home Sweet Home" /* Meeting Status */ MNID_ID:0x8217:PSETID_Appointment = 0; }; \endcode


6. Known Properties

A known properties is any property where the value doesn't change across Exchange servers and versions. Known properties can only be registered within a PROPERTY section (See 5.6 PROPERTY section). Known properties have the same general syntax: \code IDENTIFIER = [PROPVALUE | VAR] INTEGER = [PROPVALUE | VAR] \endcode OCPF lets the user define known properties using two different methods: property names or property tags. Please note that OCPF doesn't check whether the value associated with the property matches the property type. For the moment it is the developer's responsibility to ensure that the property type matches its value.

6.1. Property Names

Property Names are defined with an IDENTIFIER which must match one already registered in libmapi/conf/mapi-properties. For example: \code PR_SUBJECT = "Hello World" PR_START_DATE = T2008-03-06 22:00:00 PR_PRIORITY = 2 \endcode

6.2. Property Tags

Property Tags are the other way to set a property. This is an integer value represented using hexadecimal notation and which has two parts: the upper 16 bits are the property ID and the lower 16 bits are the property type. While users may prefer to use the property name notation for declaration, libmapi/conf/mapi-properties remains incomplete and there may be cases where you need to use the property tag notation. The example below sets properties described in previous example using their property tag notation. \code 0x0037001e = "Hello World" 0x00600040 = T2008-03-06 22:00:00 0x00260003 = 2 \endcode.

7. Named Properties

The OCPF syntax for different kind of named properties is quite generic. It supports each of the three kinds of property (OOM, MNID_ID, MNID_STRING) and can set known named properties (those listed in libmapi/conf/mapi-named-properties) or register new named properties (except OOM properties). The types of properties, and how they can be used, are described below.

7.1. OOM

OOM stands for Outlook Object Model and is a friendly name associated to a named property. It has no meaning to Exchange, but it can be useful for OpenChange or MAPI developers. OOM are human readable shortcuts for most named properties and OOM values are are considered reliable. This is the reason why OOM can only be used if it exists in libmapi/conf/mapi-named-properties. This method - in our opinion - is the best method to guarantee developers a common and validated mapi-named-properties file. Theorically, property names can have the same OOM, property ID (MNID_ID) or name (MNID_STRING). The only way to guarantee named property uniqueness is to associate its value with a OLEGUID. OLEGUID needs to be registered before they can be used with named properties. See 5.4 OLEGUID for more information on how to register a OLEGUID. OOM named properties have the following syntax: \code OOM:IDENTIFIER:IDENTIFIER = [PROPVALUE | VAR] \endcode The first IDENTIFIER represents the OOM value while the second one represents the OLEGUID. Note that identifiers are not enclosed with quotes. Below are some OOM assignments examples: \code OOM:Label:PSETID_Appointment = 9 OOM:End:PSETID_Appointment = $end_date OOM:Private:PSETID_Common = B"true" \endcode

7.2. MNID_ID

Named properties that Exchange converts using their property ID (16 bits) are known as MNID_ID named property kind. OCPF provides two different ways to define MNID_ID. It can either be a new named property or an existing one which wouldn't have any associated OOM. MNID_ID named property kind has the following syntax: \code MNID_ID:INTEGER:PROPTYPE:IDENTIFIER = [PROPVALUE | VAR] MNID_ID:INTEGER:IDENTIFIER = [PROPVALUE | VAR] \endcode If the MNID_ID named property doesn't exist within libmapi/conf/mapi-named-property then you must specify its property type. As described in the example below, the main difference between known and custom MNID_ID named properties is whether or not we specify its property type. If your MNID_ID property has not been referenced within libmapi/conf/mapi-named-property, then you must supply its property type, otherwise you can skip it. Note: PROPTYPE can be any of the values described in 8. Supported Property Types . \code MNID_ID:0x8501:PT_LONG:PSETID_Common = $reminder /* Reminder */ MNID_ID:0x8217:PSETID_Appointment = 0 /* MeetingStatus */ \endcode

7.3. MNID_STRING

Exchange also supports named properties which do not have a property ID but are described using property names. These named properties are known as MNID_STRING named property kind and Exchange maps these names to a temporary property type. MNID_STRING named property kind has the following syntax: \code MNID_STRING:STRING:IDENTIFIER = [PROPVALUE | VAR] MNID_STRING:STRING:PROPTYPE:IDENTIFIER = [PROPVALUE | VAR] \endcode MNID_STRING difference between known and custom is the same as MNID_ID one. If the MNID_STRING property doesn't exist in libmapi/conf/mapi-named-properties, then users have to supply its PROPTYPE. NOTE: PROPTYPE can be any of the value described in 8. Supported Property Types . Considering the behavior described above, we could set the "Keywords" MNID_STRING named property using any of the following example: \code MNID_STRING:"Keywords":PS_PUBLIC_STRINGS = {"one", "two" , "three" } MNID_STRING:"Keywords":PT_MV_STRING8:PS_PUBLIC_STRINGS = {"one", "two" , "three" } \endcode

8. Supported Property Types

8.1. PT_BOOLEAN

OCPF uses the following format for BOOLEAN values: \code B"true" B"false" \endcode

8.2. PT_SHORT

OCPF can use any of the following formats for SHORT values: \code S0x1234 S32 \endcode The short integer can either be in hexadecimal of decimal notation but must be prefixed with a "S" to specify this is a short integer value. If you omit to specify the "S", mismatch property type/value errors will occur while sending the message.

8.3. PT_LONG

OCPF can use any of the following formats for PT_LONG values: \code 0xdeadbeef L0xdeadbeef 32 \endcode The integer can either be in hexadecimal or decimal notation or prefixed with a "L" to specify this is long value. If you use the hexadecimal notation consider using the 'L' prefixed form since other form may disappear in further versions.

8.4. PT_I8

OCPF uses the following format for PT_I8 (uint64_t) values: \code D0x9504000000000001 \endcode

8.5. PT_DOUBLE

OCPF uses an exponent format for floating point (double) number, as shown in this example: \code F3.1415e+03 \endcode

8.6. PT_STRING8

OCPF defines a string as a set of characters (A-Za-z0-9_) enclosed with double quotes: \code "I am a STRING" \endcode

8.7. PT_UNICODE

OCPF defines a unicode string as a set of characters enclosed with double quotes and prefixed with W: \code W"I am a UNICODE string" \endcode

8.8. PT_SYSTIME

OCPF defines date using the following format string: \code TYYYY-MM-DD HH:MM:SS \endcode Dates are prefixed with a 'T' character and its content is represented with the syntax below:
  • YYYY: year
  • MM: month
  • DD: day
  • HH: hours
  • MM: minutes
  • SS: seconds
\code T2008-03-06 22:30:00 /* 2008, 6th of March 10:30:00PM */ \endcode

8.9. PT_MV_STRING8

PT_MV_STRING8 are arrays ("multiple values") of strings. OCPF defines PT_MV_STRING8 property values as STRING property values separated by commas and enclosed within braces. \code { STRING, STRING, ..., STRING } \endcode At least one STRING property value is required to create a valid PT_MV_STRING8 property. If two or more STRING property values are set, then they must be separated with comma. \code { "single multi-string value" } { "one" , "two", "three", "owned" } \endcode

8.10. PT_MV_UNICODE

PT_MV_UNICODE are arrays ("multiple values") of unicode strings. OCPF defines PT_MV_UNICODE property values as UNICODE property values separated by commas and enclosed within braces. \code { UNICODE, UNICODE, ..., UNICODE } \endcode At least one UNICODE property value is required to create a valid PT_MV_UNICODE property. If two or more UNICODE property values are set, then they must be separated with comma. \code { W"single multi-unicode value" } { W"four", W"five", W"six" } \endcode

8.11. PT_BINARY

PT_BINARY are blobs of data. OCPF defines PT_BINARY property values using two different methods. This can either be raw/inline blob of data or filename/external. If users wish to add raw data blob for a given property, they need to enclose UINT8 (from 0x00 to 0xFF) values within braces. However many cases occur where the data blob is large (such as HTML content; PR_HTML has PT_BINARY property type). In such cases, users may rather prefer to write an external file and specify a filename. \code { UINT8 UINT8 [...] UINT8 } < STRING > \endcode Note that if the blob of data (raw or pointed by filename) is too large to fit in the property values array, then OCPF will automatically open a stream for the property and write its data in the stream. \code PR_HTML = { 0x48 0x65 0x6c 0x6c 0x6f } /* Hello */ PR_HTML = <"/tmp/sample.html"> \endcode

8.12. PT_MV_BINARY

PT_MV_BINARY are arrays ("multiple values") of PT_BINARY blobs. OCPF defines PT_MV_BINARY propery values as PT_BINARY property values separated by commas and encloses within braces. \code { PT_BINARY, PT_BINARY, PT_BINARY } \endcode At least one PT_BINARY property value is required to create a valid PT_MV_BINARY property. If two or more PT_BINARY are set, then they must be separated with comma. \code { {0x48 0x65 0x6c 0x6c 0x6f}, {0x77 0x6f 0x72 0x6c 0x64}, { 0x21 } } /* Hello world ! */ \endcode Note that current implementation does not support the following PT_BINARY format: \code < STRING > \endcode

8.13. PT_MV_LONG

PT_MV_LONG are arrays ("multiple values") of integers. OCPF defines PT_MV_LONG property values as INTEGER property values separated by commas and enclosed within braces. \code { INTEGER, INTEGER, INTEGER } \endcode At least one INTEGER property value is required to create a valid PT_MV_LONG property. If two or more INTEGER property values are set, then they must be separated with comma. Also note that PT_MV_LONG are very similar to PT_BINARY in their syntax. The main difference lies in the representation of UINT8 and INTEGER values. \code { 1, 2, 3 } { L0x1, 0x123456, 42 } \endcode

9. Comments

OCPF files can contain comments embedded in normal C-style comment markers. That is, a comment starts with a combination of / followed by *, and ends with combination of * followed by /. Anything contained with in comment markers is ignored by the OCPF tools, and is only for the convenience of human readers. \code /* This is a comment */ \endcode

10. OCPF and openchangeclient

OCPF support has been added to the openchangeclient utility. It now has the ability to parse and process OCPF files. Two different options are supported; you can either check an OCPF files' syntax (--ocpf_syntax) or process the files (--ocpf_sender). Users can set OCPF files using --ocpf-file=filename. Note that you can specify --ocpf-file multiple times if you have split the OCPF contents into different files. However the whole OCPF files you specify must only represent a single message. Sample OCPF files are provided in the distribution (libocpf/examples), and can also be browsed from the Examples section of this documentation:

10.1 ocpf_syntax

Process specified OCPF files, display syntax errors if detected and dump OCPF context content on standard output. \code openchangeclient --ocpf-syntax \ --ocpf-file=libocpf/examples/sample_appointment.ocpf \endcode

10.2. ocpf_sender

Process specified OCPF files and create/send a message using OCPF context contents. \code openchangeclient --ocpf_sender \ --ocpf-file=libocpf/examples/sample_appointment.ocpf \endcode

10.3 ocpf_dump

Process specified MAPI message and generates the corresponding OCPF file on the filesystem. \code openchangeclient --fetch-items=Appointment MAILBOX (1 messages) |== test ==| : AA13000000000001/20C140000000003 Location: paris Start time : Sat Mar 29 09:00:00 2008 CET End time : Sat Mar 29 09:30:00 2008 CET Timezone: (GMT+01:00) Brussels, Copenhagen, Madrid, Paris Private: False Status: Completed fetchitems : MAPI_E_SUCCESS (0x0) openchangeclient --ocpf-dump=AA13000000000001/20C140000000003 OCPF output file: 20c140000000003.ocpf OCPF Dump : MAPI_E_SUCCESS (0x0) \endcode */ /** \example sample_appointment.ocpf This example shows a sample OCPF file designed to create a calendar with the following details: - Event starting the 6th of March at 10:00PM and ending at 11:45PM - Reminder set 45 minutes before the beginning of event - Label set to Anniversary - Subject, Body, Location and Private flag set */ /** \example sample_task.ocpf This example shows a sample OCPF file designed to create a task with the following details: - Task starting the 6th of March at 8:00PM and ending at 11:00PM - Importance set to High - Waiting for someone else - Subject, Body and Private flag set */ openchange-2.0/libocpf/ocpf.h000066400000000000000000000057741223057412600162170ustar00rootroot00000000000000/* OpenChange OCPF (OpenChange Property File) implementation. Copyright (C) Julien Kerihuel 2008-2010. This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see . */ #ifndef __OCPF_H_ #define __OCPF_H_ #include "libmapi/libmapi.h" #include "libmapi/mapi_nameid.h" #define OCPF_SUCCESS 0x0 #define OCPF_ERROR 0x1 #define OCPF_E_EXIST 0x2 #define OCPF_FLAGS_RDWR 0 #define OCPF_FLAGS_READ 1 #define OCPF_FLAGS_WRITE 2 #define OCPF_FLAGS_CREATE 3 enum ocpf_recipClass { OCPF_MAPI_TO = 0x1, OCPF_MAPI_CC, OCPF_MAPI_BCC }; extern struct ocpf *ocpf; #undef _PRINTF_ATTRIBUTE #define _PRINTF_ATTRIBUTE(a1, a2) PRINTF_ATTRIBUTE(a1, a2) #ifndef __BEGIN_DECLS #ifdef __cplusplus #define __BEGIN_DECLS extern "C" { #define __END_DECLS } #else #define __BEGIN_DECLS #define __END_DECLS #endif #endif #ifndef _PUBLIC_ #define _PUBLIC_ #endif __BEGIN_DECLS /* The following public definitions come from libocpf/ocpf_public.c */ int ocpf_init(void); int ocpf_release(void); int ocpf_new_context(const char *, uint32_t *, uint8_t); int ocpf_del_context(uint32_t); int ocpf_parse(uint32_t); enum MAPISTATUS ocpf_get_recipients(TALLOC_CTX *, uint32_t, struct SRowSet **); enum MAPISTATUS ocpf_set_SPropValue(TALLOC_CTX *, uint32_t, mapi_object_t *, mapi_object_t *); struct SPropValue *ocpf_get_SPropValue(uint32_t, uint32_t *); enum MAPISTATUS ocpf_OpenFolder(uint32_t, mapi_object_t *, mapi_object_t *); enum MAPISTATUS ocpf_set_Recipients(TALLOC_CTX *, uint32_t, mapi_object_t *); enum MAPISTATUS ocpf_clear_props (uint32_t context_id); /* The following public definitions come from libocpf/ocpf_server.c */ enum MAPISTATUS ocpf_server_set_type(uint32_t, const char *); enum MAPISTATUS ocpf_server_set_SPropValue(TALLOC_CTX *, uint32_t); enum MAPISTATUS ocpf_server_add_SPropValue(uint32_t, struct SPropValue *); enum MAPISTATUS ocpf_server_sync(uint32_t); /* The following public definitions come from libocpf/ocpf_dump.c */ void ocpf_dump_type(uint32_t); void ocpf_dump_folder(uint32_t); void ocpf_dump_recipients(uint32_t); void ocpf_dump_oleguid(uint32_t); void ocpf_dump_variable(uint32_t); void ocpf_dump_property(uint32_t); void ocpf_dump_named_property(uint32_t); void ocpf_dump(uint32_t); /* The following public definitions come from libocpf/ocpf_write.c */ int ocpf_write_init(uint32_t, mapi_id_t); int ocpf_write_auto(uint32_t, mapi_object_t *, struct mapi_SPropValue_array *); int ocpf_write_commit(uint32_t); __END_DECLS #endif /* ! __OCPF_H_ */ openchange-2.0/libocpf/ocpf.tab.c000066400000000000000000002230261223057412600167470ustar00rootroot00000000000000/* A Bison parser, made by GNU Bison 2.5. */ /* Bison implementation for Yacc-like parsers in C Copyright (C) 1984, 1989-1990, 2000-2011 Free Software Foundation, Inc. This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see . */ /* As a special exception, you may create a larger work that contains part or all of the Bison parser skeleton and distribute that work under terms of your choice, so long as that work isn't itself a parser generator using the skeleton or a modified version thereof as a parser skeleton. Alternatively, if you modify or redistribute the parser skeleton itself, you may (at your option) remove this special exception, which will cause the skeleton and the resulting Bison output files to be licensed under the GNU General Public License without this special exception. This special exception was added by the Free Software Foundation in version 2.2 of Bison. */ /* C LALR(1) parser skeleton written by Richard Stallman, by simplifying the original so-called "semantic" parser. */ /* All symbols defined below should begin with yy or YY, to avoid infringing on user name space. This should be done even for local variables, as they might otherwise be expanded by user macros. There are some unavoidable exceptions within include files to define necessary library symbols; they are noted "INFRINGES ON USER NAME SPACE" below. */ /* Identify Bison output. */ #define YYBISON 1 /* Bison version. */ #define YYBISON_VERSION "2.5" /* Skeleton name. */ #define YYSKELETON_NAME "yacc.c" /* Pure parsers. */ #define YYPURE 1 /* Push parsers. */ #define YYPUSH 0 /* Pull parsers. */ #define YYPULL 1 /* Using locations. */ #define YYLSP_NEEDED 0 /* Substitute the variable and function names. */ #define yyparse ocpf_yyparse #define yylex ocpf_yylex #define yyerror ocpf_yyerror #define yylval ocpf_yylval #define yychar ocpf_yychar #define yydebug ocpf_yydebug #define yynerrs ocpf_yynerrs /* Copy the first part of user declarations. */ /* Line 268 of yacc.c */ #line 20 "libocpf/ocpf.y" #include "libocpf/ocpf.h" #include "libocpf/ocpf_api.h" #include "libocpf/lex.h" int ocpf_yylex(void *, void *); void yyerror(struct ocpf_context *, void *, char *); /* Line 268 of yacc.c */ #line 91 "libocpf/ocpf.tab.c" /* Enabling traces. */ #ifndef YYDEBUG # define YYDEBUG 0 #endif /* Enabling verbose error messages. */ #ifdef YYERROR_VERBOSE # undef YYERROR_VERBOSE # define YYERROR_VERBOSE 1 #else # define YYERROR_VERBOSE 0 #endif /* Enabling the token table. */ #ifndef YYTOKEN_TABLE # define YYTOKEN_TABLE 0 #endif /* Tokens. */ #ifndef YYTOKENTYPE # define YYTOKENTYPE /* Put the tokens into the symbol table, so that GDB and other debuggers know about them. */ enum yytokentype { UINT8 = 258, BOOLEAN = 259, SHORT = 260, INTEGER = 261, I8 = 262, DOUBLE = 263, IDENTIFIER = 264, STRING = 265, UNICODE = 266, SYSTIME = 267, VAR = 268, kw_TYPE = 269, kw_FOLDER = 270, kw_OLEGUID = 271, kw_SET = 272, kw_PROPERTY = 273, kw_NPROPERTY = 274, kw_RECIPIENT = 275, kw_TO = 276, kw_CC = 277, kw_BCC = 278, kw_OOM = 279, kw_MNID_ID = 280, kw_MNID_STRING = 281, kw_PT_BOOLEAN = 282, kw_PT_STRING8 = 283, kw_PT_UNICODE = 284, kw_PT_SHORT = 285, kw_PT_LONG = 286, kw_PT_I8 = 287, kw_PT_DOUBLE = 288, kw_PT_SYSTIME = 289, kw_PT_MV_LONG = 290, kw_PT_MV_BINARY = 291, kw_PT_MV_STRING8 = 292, kw_PT_MV_UNICODE = 293, kw_PT_BINARY = 294, OBRACE = 295, EBRACE = 296, COMMA = 297, SEMICOLON = 298, COLON = 299, LOWER = 300, GREATER = 301, EQUAL = 302 }; #endif #if ! defined YYSTYPE && ! defined YYSTYPE_IS_DECLARED typedef union YYSTYPE { /* Line 293 of yacc.c */ #line 37 "libocpf/ocpf.y" uint8_t i; uint8_t b; uint16_t s; uint32_t l; uint64_t d; double dbl; char *name; char *nameW; char *date; char *var; struct LongArray_r MVl; struct StringArray_r MVszA; struct StringArrayW_r MVszW; struct BinaryArray_r MVbin; /* Line 293 of yacc.c */ #line 193 "libocpf/ocpf.tab.c" } YYSTYPE; # define YYSTYPE_IS_TRIVIAL 1 # define yystype YYSTYPE /* obsolescent; will be withdrawn */ # define YYSTYPE_IS_DECLARED 1 #endif /* Copy the second part of user declarations. */ /* Line 343 of yacc.c */ #line 205 "libocpf/ocpf.tab.c" #ifdef short # undef short #endif #ifdef YYTYPE_UINT8 typedef YYTYPE_UINT8 yytype_uint8; #else typedef unsigned char yytype_uint8; #endif #ifdef YYTYPE_INT8 typedef YYTYPE_INT8 yytype_int8; #elif (defined __STDC__ || defined __C99__FUNC__ \ || defined __cplusplus || defined _MSC_VER) typedef signed char yytype_int8; #else typedef short int yytype_int8; #endif #ifdef YYTYPE_UINT16 typedef YYTYPE_UINT16 yytype_uint16; #else typedef unsigned short int yytype_uint16; #endif #ifdef YYTYPE_INT16 typedef YYTYPE_INT16 yytype_int16; #else typedef short int yytype_int16; #endif #ifndef YYSIZE_T # ifdef __SIZE_TYPE__ # define YYSIZE_T __SIZE_TYPE__ # elif defined size_t # define YYSIZE_T size_t # elif ! defined YYSIZE_T && (defined __STDC__ || defined __C99__FUNC__ \ || defined __cplusplus || defined _MSC_VER) # include /* INFRINGES ON USER NAME SPACE */ # define YYSIZE_T size_t # else # define YYSIZE_T unsigned int # endif #endif #define YYSIZE_MAXIMUM ((YYSIZE_T) -1) #ifndef YY_ # if defined YYENABLE_NLS && YYENABLE_NLS # if ENABLE_NLS # include /* INFRINGES ON USER NAME SPACE */ # define YY_(msgid) dgettext ("bison-runtime", msgid) # endif # endif # ifndef YY_ # define YY_(msgid) msgid # endif #endif /* Suppress unused-variable warnings by "using" E. */ #if ! defined lint || defined __GNUC__ # define YYUSE(e) ((void) (e)) #else # define YYUSE(e) /* empty */ #endif /* Identity function, used to suppress warnings about constant conditions. */ #ifndef lint # define YYID(n) (n) #else #if (defined __STDC__ || defined __C99__FUNC__ \ || defined __cplusplus || defined _MSC_VER) static int YYID (int yyi) #else static int YYID (yyi) int yyi; #endif { return yyi; } #endif #if ! defined yyoverflow || YYERROR_VERBOSE /* The parser invokes alloca or malloc; define the necessary symbols. */ # ifdef YYSTACK_USE_ALLOCA # if YYSTACK_USE_ALLOCA # ifdef __GNUC__ # define YYSTACK_ALLOC __builtin_alloca # elif defined __BUILTIN_VA_ARG_INCR # include /* INFRINGES ON USER NAME SPACE */ # elif defined _AIX # define YYSTACK_ALLOC __alloca # elif defined _MSC_VER # include /* INFRINGES ON USER NAME SPACE */ # define alloca _alloca # else # define YYSTACK_ALLOC alloca # if ! defined _ALLOCA_H && ! defined EXIT_SUCCESS && (defined __STDC__ || defined __C99__FUNC__ \ || defined __cplusplus || defined _MSC_VER) # include /* INFRINGES ON USER NAME SPACE */ # ifndef EXIT_SUCCESS # define EXIT_SUCCESS 0 # endif # endif # endif # endif # endif # ifdef YYSTACK_ALLOC /* Pacify GCC's `empty if-body' warning. */ # define YYSTACK_FREE(Ptr) do { /* empty */; } while (YYID (0)) # ifndef YYSTACK_ALLOC_MAXIMUM /* The OS might guarantee only one guard page at the bottom of the stack, and a page size can be as small as 4096 bytes. So we cannot safely invoke alloca (N) if N exceeds 4096. Use a slightly smaller number to allow for a few compiler-allocated temporary stack slots. */ # define YYSTACK_ALLOC_MAXIMUM 4032 /* reasonable circa 2006 */ # endif # else # define YYSTACK_ALLOC YYMALLOC # define YYSTACK_FREE YYFREE # ifndef YYSTACK_ALLOC_MAXIMUM # define YYSTACK_ALLOC_MAXIMUM YYSIZE_MAXIMUM # endif # if (defined __cplusplus && ! defined EXIT_SUCCESS \ && ! ((defined YYMALLOC || defined malloc) \ && (defined YYFREE || defined free))) # include /* INFRINGES ON USER NAME SPACE */ # ifndef EXIT_SUCCESS # define EXIT_SUCCESS 0 # endif # endif # ifndef YYMALLOC # define YYMALLOC malloc # if ! defined malloc && ! defined EXIT_SUCCESS && (defined __STDC__ || defined __C99__FUNC__ \ || defined __cplusplus || defined _MSC_VER) void *malloc (YYSIZE_T); /* INFRINGES ON USER NAME SPACE */ # endif # endif # ifndef YYFREE # define YYFREE free # if ! defined free && ! defined EXIT_SUCCESS && (defined __STDC__ || defined __C99__FUNC__ \ || defined __cplusplus || defined _MSC_VER) void free (void *); /* INFRINGES ON USER NAME SPACE */ # endif # endif # endif #endif /* ! defined yyoverflow || YYERROR_VERBOSE */ #if (! defined yyoverflow \ && (! defined __cplusplus \ || (defined YYSTYPE_IS_TRIVIAL && YYSTYPE_IS_TRIVIAL))) /* A type that is properly aligned for any stack member. */ union yyalloc { yytype_int16 yyss_alloc; YYSTYPE yyvs_alloc; }; /* The size of the maximum gap between one aligned stack and the next. */ # define YYSTACK_GAP_MAXIMUM (sizeof (union yyalloc) - 1) /* The size of an array large to enough to hold all stacks, each with N elements. */ # define YYSTACK_BYTES(N) \ ((N) * (sizeof (yytype_int16) + sizeof (YYSTYPE)) \ + YYSTACK_GAP_MAXIMUM) # define YYCOPY_NEEDED 1 /* Relocate STACK from its old location to the new one. The local variables YYSIZE and YYSTACKSIZE give the old and new number of elements in the stack, and YYPTR gives the new location of the stack. Advance YYPTR to a properly aligned location for the next stack. */ # define YYSTACK_RELOCATE(Stack_alloc, Stack) \ do \ { \ YYSIZE_T yynewbytes; \ YYCOPY (&yyptr->Stack_alloc, Stack, yysize); \ Stack = &yyptr->Stack_alloc; \ yynewbytes = yystacksize * sizeof (*Stack) + YYSTACK_GAP_MAXIMUM; \ yyptr += yynewbytes / sizeof (*yyptr); \ } \ while (YYID (0)) #endif #if defined YYCOPY_NEEDED && YYCOPY_NEEDED /* Copy COUNT objects from FROM to TO. The source and destination do not overlap. */ # ifndef YYCOPY # if defined __GNUC__ && 1 < __GNUC__ # define YYCOPY(To, From, Count) \ __builtin_memcpy (To, From, (Count) * sizeof (*(From))) # else # define YYCOPY(To, From, Count) \ do \ { \ YYSIZE_T yyi; \ for (yyi = 0; yyi < (Count); yyi++) \ (To)[yyi] = (From)[yyi]; \ } \ while (YYID (0)) # endif # endif #endif /* !YYCOPY_NEEDED */ /* YYFINAL -- State number of the termination state. */ #define YYFINAL 2 /* YYLAST -- Last index in YYTABLE. */ #define YYLAST 203 /* YYNTOKENS -- Number of terminals. */ #define YYNTOKENS 48 /* YYNNTS -- Number of nonterminals. */ #define YYNNTS 32 /* YYNRULES -- Number of rules. */ #define YYNRULES 89 /* YYNRULES -- Number of states. */ #define YYNSTATES 154 /* YYTRANSLATE(YYLEX) -- Bison symbol number corresponding to YYLEX. */ #define YYUNDEFTOK 2 #define YYMAXUTOK 302 #define YYTRANSLATE(YYX) \ ((unsigned int) (YYX) <= YYMAXUTOK ? yytranslate[YYX] : YYUNDEFTOK) /* YYTRANSLATE[YYLEX] -- Bison symbol number corresponding to YYLEX. */ static const yytype_uint8 yytranslate[] = { 0, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47 }; #if YYDEBUG /* YYPRHS[YYN] -- Index of the first RHS symbol of rule number YYN in YYRHS. */ static const yytype_uint16 yyprhs[] = { 0, 0, 3, 4, 7, 9, 11, 13, 15, 17, 19, 21, 24, 27, 30, 33, 37, 42, 48, 49, 52, 58, 64, 70, 71, 74, 78, 82, 86, 90, 96, 97, 100, 104, 108, 112, 116, 118, 120, 122, 124, 126, 128, 130, 132, 137, 142, 147, 151, 158, 162, 163, 166, 169, 170, 173, 176, 177, 180, 183, 184, 187, 189, 190, 193, 198, 204, 205, 208, 212, 216, 220, 224, 230, 238, 246, 248, 250, 252, 254, 256, 258, 260, 262, 264, 266, 268, 270, 272, 278 }; /* YYRHS -- A `-1'-separated list of the rules' RHS. */ static const yytype_int8 yyrhs[] = { 49, 0, -1, -1, 49, 50, -1, 51, -1, 52, -1, 53, -1, 54, -1, 60, -1, 74, -1, 55, -1, 14, 10, -1, 15, 10, -1, 15, 7, -1, 15, 13, -1, 16, 9, 10, -1, 17, 13, 47, 63, -1, 20, 40, 56, 41, 43, -1, -1, 56, 57, -1, 21, 40, 58, 41, 43, -1, 22, 40, 58, 41, 43, -1, 23, 40, 58, 41, 43, -1, -1, 58, 59, -1, 9, 47, 63, -1, 6, 47, 63, -1, 9, 47, 13, -1, 6, 47, 13, -1, 18, 40, 61, 41, 43, -1, -1, 61, 62, -1, 9, 47, 63, -1, 6, 47, 63, -1, 9, 47, 13, -1, 6, 47, 13, -1, 10, -1, 11, -1, 5, -1, 6, -1, 4, -1, 7, -1, 8, -1, 12, -1, 40, 64, 6, 41, -1, 40, 66, 10, 41, -1, 40, 68, 11, 41, -1, 40, 70, 41, -1, 40, 72, 40, 70, 41, 41, -1, 45, 10, 46, -1, -1, 64, 65, -1, 6, 42, -1, -1, 66, 67, -1, 10, 42, -1, -1, 68, 69, -1, 11, 42, -1, -1, 70, 71, -1, 3, -1, -1, 72, 73, -1, 40, 70, 41, 42, -1, 19, 40, 75, 41, 43, -1, -1, 75, 76, -1, 77, 47, 63, -1, 79, 47, 63, -1, 77, 47, 13, -1, 79, 47, 13, -1, 24, 44, 9, 44, 9, -1, 25, 44, 6, 44, 78, 44, 9, -1, 26, 44, 10, 44, 78, 44, 9, -1, 28, -1, 29, -1, 30, -1, 31, -1, 33, -1, 32, -1, 27, -1, 34, -1, 35, -1, 37, -1, 38, -1, 39, -1, 36, -1, 25, 44, 6, 44, 9, -1, 26, 44, 10, 44, 9, -1 }; /* YYRLINE[YYN] -- source line where rule number YYN was defined. */ static const yytype_uint16 yyrline[] = { 0, 107, 107, 107, 113, 114, 115, 116, 117, 118, 119, 123, 136, 145, 154, 166, 179, 187, 191, 191, 194, 199, 204, 211, 211, 217, 222, 227, 231, 237, 241, 241, 248, 253, 258, 262, 268, 273, 278, 279, 280, 281, 282, 283, 288, 303, 321, 339, 349, 372, 381, 381, 383, 398, 398, 401, 419, 419, 421, 439, 439, 441, 459, 459, 461, 485, 489, 489, 495, 499, 503, 507, 513, 519, 525, 533, 538, 543, 548, 553, 558, 563, 568, 573, 578, 583, 588, 593, 600, 607 }; #endif #if YYDEBUG || YYERROR_VERBOSE || YYTOKEN_TABLE /* YYTNAME[SYMBOL-NUM] -- String name of the symbol SYMBOL-NUM. First, the terminals, then, starting at YYNTOKENS, nonterminals. */ static const char *const yytname[] = { "$end", "error", "$undefined", "UINT8", "BOOLEAN", "SHORT", "INTEGER", "I8", "DOUBLE", "IDENTIFIER", "STRING", "UNICODE", "SYSTIME", "VAR", "kw_TYPE", "kw_FOLDER", "kw_OLEGUID", "kw_SET", "kw_PROPERTY", "kw_NPROPERTY", "kw_RECIPIENT", "kw_TO", "kw_CC", "kw_BCC", "kw_OOM", "kw_MNID_ID", "kw_MNID_STRING", "kw_PT_BOOLEAN", "kw_PT_STRING8", "kw_PT_UNICODE", "kw_PT_SHORT", "kw_PT_LONG", "kw_PT_I8", "kw_PT_DOUBLE", "kw_PT_SYSTIME", "kw_PT_MV_LONG", "kw_PT_MV_BINARY", "kw_PT_MV_STRING8", "kw_PT_MV_UNICODE", "kw_PT_BINARY", "OBRACE", "EBRACE", "COMMA", "SEMICOLON", "COLON", "LOWER", "GREATER", "EQUAL", "$accept", "keywords", "kvalues", "Type", "Folder", "OLEGUID", "Set", "Recipient", "recipients", "recipient", "rpcontent", "rcontent", "Property", "pcontent", "content", "propvalue", "mvlong_contents", "mvlong_content", "mvstring_contents", "mvstring_content", "mvunicode_contents", "mvunicode_content", "binary_contents", "binary_content", "mvbin_contents", "mvbin_content", "NProperty", "npcontent", "ncontent", "kind", "proptype", "known_kind", 0 }; #endif # ifdef YYPRINT /* YYTOKNUM[YYLEX-NUM] -- Internal token number corresponding to token YYLEX-NUM. */ static const yytype_uint16 yytoknum[] = { 0, 256, 257, 258, 259, 260, 261, 262, 263, 264, 265, 266, 267, 268, 269, 270, 271, 272, 273, 274, 275, 276, 277, 278, 279, 280, 281, 282, 283, 284, 285, 286, 287, 288, 289, 290, 291, 292, 293, 294, 295, 296, 297, 298, 299, 300, 301, 302 }; # endif /* YYR1[YYN] -- Symbol number of symbol that rule YYN derives. */ static const yytype_uint8 yyr1[] = { 0, 48, 49, 49, 50, 50, 50, 50, 50, 50, 50, 51, 52, 52, 52, 53, 54, 55, 56, 56, 57, 57, 57, 58, 58, 59, 59, 59, 59, 60, 61, 61, 62, 62, 62, 62, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 64, 64, 65, 66, 66, 67, 68, 68, 69, 70, 70, 71, 72, 72, 73, 74, 75, 75, 76, 76, 76, 76, 77, 77, 77, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 79, 79 }; /* YYR2[YYN] -- Number of symbols composing right hand side of rule YYN. */ static const yytype_uint8 yyr2[] = { 0, 2, 0, 2, 1, 1, 1, 1, 1, 1, 1, 2, 2, 2, 2, 3, 4, 5, 0, 2, 5, 5, 5, 0, 2, 3, 3, 3, 3, 5, 0, 2, 3, 3, 3, 3, 1, 1, 1, 1, 1, 1, 1, 1, 4, 4, 4, 3, 6, 3, 0, 2, 2, 0, 2, 2, 0, 2, 2, 0, 2, 1, 0, 2, 4, 5, 0, 2, 3, 3, 3, 3, 5, 7, 7, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 5, 5 }; /* YYDEFACT[STATE-NAME] -- Default reduction number in state STATE-NUM. Performed when YYTABLE doesn't specify something else to do. Zero means the default is an error. */ static const yytype_uint8 yydefact[] = { 2, 0, 1, 0, 0, 0, 0, 0, 0, 0, 3, 4, 5, 6, 7, 10, 8, 9, 11, 13, 12, 14, 0, 0, 30, 66, 18, 15, 0, 0, 0, 0, 40, 38, 39, 41, 42, 36, 37, 43, 59, 0, 16, 0, 0, 0, 31, 0, 0, 0, 0, 67, 0, 0, 0, 0, 0, 0, 19, 0, 0, 0, 0, 0, 0, 0, 0, 29, 0, 0, 0, 65, 0, 0, 23, 23, 23, 17, 0, 51, 0, 54, 0, 57, 61, 47, 60, 59, 63, 49, 35, 33, 34, 32, 0, 0, 0, 70, 68, 71, 69, 0, 0, 0, 44, 52, 45, 55, 46, 58, 0, 0, 0, 0, 0, 0, 0, 24, 0, 0, 0, 72, 88, 81, 75, 76, 77, 78, 80, 79, 82, 83, 87, 84, 85, 86, 0, 89, 0, 0, 0, 20, 21, 22, 48, 64, 0, 0, 28, 26, 27, 25, 73, 74 }; /* YYDEFGOTO[NTERM-NUM]. */ static const yytype_int16 yydefgoto[] = { -1, 1, 10, 11, 12, 13, 14, 15, 31, 58, 101, 117, 16, 29, 46, 42, 59, 79, 60, 81, 61, 83, 62, 86, 63, 88, 17, 30, 51, 52, 136, 53 }; /* YYPACT[STATE-NUM] -- Index in YYTABLE of the portion describing STATE-NUM. */ #define YYPACT_NINF -66 static const yytype_int16 yypact[] = { -66, 166, -66, -4, 54, 42, 26, -6, 14, 16, -66, -66, -66, -66, -66, -66, -66, -66, -66, -66, -66, -66, 49, 19, -66, -66, -66, -66, 98, 71, 106, 103, -66, -66, -66, -66, -66, -66, -66, -66, 47, 53, -66, 50, 60, 72, -66, 29, 75, 77, 79, -66, 80, 82, 94, 96, 97, 99, -66, 133, 130, 134, 11, 101, 104, 5, 15, -66, 142, 181, 178, -66, 25, 36, -66, -66, -66, -66, -39, -66, -37, -66, 27, -66, -66, -66, -66, -66, -66, -66, -66, -66, -66, -66, 145, 146, 147, -66, -66, -66, -66, 105, 107, 111, -66, -66, -66, -66, -66, -66, 21, 183, 126, 140, 148, 149, 150, -66, 151, 154, 30, -66, -66, -66, -66, -66, -66, -66, -66, -66, -66, -66, -66, -66, -66, -66, 155, -66, 156, 78, 88, -66, -66, -66, -66, -66, 189, 192, -66, -66, -66, -66, -66, -66 }; /* YYPGOTO[NTERM-NUM]. */ static const yytype_int8 yypgoto[] = { -66, -66, -66, -66, -66, -66, -66, -66, -66, -66, 3, -66, -66, -66, -66, -65, -66, -66, -66, -66, -66, -66, 115, -66, -66, -66, -66, -66, -66, -66, 90, -66 }; /* YYTABLE[YYPACT[STATE-NUM]]. What to do in state STATE-NUM. If positive, shift that token. If negative, reduce the rule which number is the opposite. If YYTABLE_NINF, syntax error. */ #define YYTABLE_NINF -63 static const yytype_int16 yytable[] = { 91, 93, 104, 105, 106, 107, 18, 98, 100, 32, 33, 34, 35, 36, 84, 37, 38, 39, 90, 32, 33, 34, 35, 36, 84, 37, 38, 39, 92, 32, 33, 34, 35, 36, 24, 37, 38, 39, 97, 23, 32, 33, 34, 35, 36, 40, 37, 38, 39, 99, 41, 22, 85, -50, 25, 40, 26, -53, -56, 27, 41, 19, 120, 64, 20, 40, 28, 21, 108, 109, 41, 144, 145, 68, 149, 151, 40, 43, 102, 103, 44, 41, 32, 33, 34, 35, 36, -62, 37, 38, 39, 148, 32, 33, 34, 35, 36, 65, 37, 38, 39, 150, 32, 33, 34, 35, 36, 66, 37, 38, 39, 114, 45, 114, 115, 67, 115, 114, 40, 69, 115, 70, 71, 41, 54, 55, 56, 72, 40, 73, 47, 48, 49, 41, 74, 122, 75, 76, 40, 78, 80, 87, 77, 41, 57, 82, 116, 50, 118, 137, 89, 94, 119, 123, 124, 125, 126, 127, 128, 129, 130, 131, 132, 133, 134, 135, 2, 123, 124, 125, 126, 127, 128, 129, 130, 131, 132, 133, 134, 135, 3, 4, 5, 6, 7, 8, 9, 95, 96, 111, 112, 113, 121, 141, 142, 139, 140, 143, 152, 146, 147, 153, 110, 138 }; #define yypact_value_is_default(yystate) \ ((yystate) == (-66)) #define yytable_value_is_error(yytable_value) \ YYID (0) static const yytype_uint8 yycheck[] = { 65, 66, 41, 42, 41, 42, 10, 72, 73, 4, 5, 6, 7, 8, 3, 10, 11, 12, 13, 4, 5, 6, 7, 8, 3, 10, 11, 12, 13, 4, 5, 6, 7, 8, 40, 10, 11, 12, 13, 13, 4, 5, 6, 7, 8, 40, 10, 11, 12, 13, 45, 9, 41, 6, 40, 40, 40, 10, 11, 10, 45, 7, 41, 10, 10, 40, 47, 13, 41, 42, 45, 41, 42, 44, 139, 140, 40, 6, 75, 76, 9, 45, 4, 5, 6, 7, 8, 40, 10, 11, 12, 13, 4, 5, 6, 7, 8, 47, 10, 11, 12, 13, 4, 5, 6, 7, 8, 47, 10, 11, 12, 6, 41, 6, 9, 43, 9, 6, 40, 44, 9, 44, 43, 45, 21, 22, 23, 47, 40, 47, 24, 25, 26, 45, 40, 9, 40, 40, 40, 6, 10, 40, 43, 45, 41, 11, 41, 41, 41, 9, 46, 9, 41, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 0, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 14, 15, 16, 17, 18, 19, 20, 6, 10, 44, 44, 44, 9, 43, 43, 47, 47, 43, 9, 44, 44, 9, 87, 113 }; /* YYSTOS[STATE-NUM] -- The (internal number of the) accessing symbol of state STATE-NUM. */ static const yytype_uint8 yystos[] = { 0, 49, 0, 14, 15, 16, 17, 18, 19, 20, 50, 51, 52, 53, 54, 55, 60, 74, 10, 7, 10, 13, 9, 13, 40, 40, 40, 10, 47, 61, 75, 56, 4, 5, 6, 7, 8, 10, 11, 12, 40, 45, 63, 6, 9, 41, 62, 24, 25, 26, 41, 76, 77, 79, 21, 22, 23, 41, 57, 64, 66, 68, 70, 72, 10, 47, 47, 43, 44, 44, 44, 43, 47, 47, 40, 40, 40, 43, 6, 65, 10, 67, 11, 69, 3, 41, 71, 40, 73, 46, 13, 63, 13, 63, 9, 6, 10, 13, 63, 13, 63, 58, 58, 58, 41, 42, 41, 42, 41, 42, 70, 44, 44, 44, 6, 9, 41, 59, 41, 41, 41, 9, 9, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 78, 9, 78, 47, 47, 43, 43, 43, 41, 42, 44, 44, 13, 63, 13, 63, 9, 9 }; #define yyerrok (yyerrstatus = 0) #define yyclearin (yychar = YYEMPTY) #define YYEMPTY (-2) #define YYEOF 0 #define YYACCEPT goto yyacceptlab #define YYABORT goto yyabortlab #define YYERROR goto yyerrorlab /* Like YYERROR except do call yyerror. This remains here temporarily to ease the transition to the new meaning of YYERROR, for GCC. Once GCC version 2 has supplanted version 1, this can go. However, YYFAIL appears to be in use. Nevertheless, it is formally deprecated in Bison 2.4.2's NEWS entry, where a plan to phase it out is discussed. */ #define YYFAIL goto yyerrlab #if defined YYFAIL /* This is here to suppress warnings from the GCC cpp's -Wunused-macros. Normally we don't worry about that warning, but some users do, and we want to make it easy for users to remove YYFAIL uses, which will produce warnings from Bison 2.5. */ #endif #define YYRECOVERING() (!!yyerrstatus) #define YYBACKUP(Token, Value) \ do \ if (yychar == YYEMPTY && yylen == 1) \ { \ yychar = (Token); \ yylval = (Value); \ YYPOPSTACK (1); \ goto yybackup; \ } \ else \ { \ yyerror (ctx, scanner, YY_("syntax error: cannot back up")); \ YYERROR; \ } \ while (YYID (0)) #define YYTERROR 1 #define YYERRCODE 256 /* YYLLOC_DEFAULT -- Set CURRENT to span from RHS[1] to RHS[N]. If N is 0, then set CURRENT to the empty location which ends the previous symbol: RHS[0] (always defined). */ #define YYRHSLOC(Rhs, K) ((Rhs)[K]) #ifndef YYLLOC_DEFAULT # define YYLLOC_DEFAULT(Current, Rhs, N) \ do \ if (YYID (N)) \ { \ (Current).first_line = YYRHSLOC (Rhs, 1).first_line; \ (Current).first_column = YYRHSLOC (Rhs, 1).first_column; \ (Current).last_line = YYRHSLOC (Rhs, N).last_line; \ (Current).last_column = YYRHSLOC (Rhs, N).last_column; \ } \ else \ { \ (Current).first_line = (Current).last_line = \ YYRHSLOC (Rhs, 0).last_line; \ (Current).first_column = (Current).last_column = \ YYRHSLOC (Rhs, 0).last_column; \ } \ while (YYID (0)) #endif /* This macro is provided for backward compatibility. */ #ifndef YY_LOCATION_PRINT # define YY_LOCATION_PRINT(File, Loc) ((void) 0) #endif /* YYLEX -- calling `yylex' with the right arguments. */ #ifdef YYLEX_PARAM # define YYLEX yylex (&yylval, YYLEX_PARAM) #else # define YYLEX yylex (&yylval, scanner) #endif /* Enable debugging if requested. */ #if YYDEBUG # ifndef YYFPRINTF # include /* INFRINGES ON USER NAME SPACE */ # define YYFPRINTF fprintf # endif # define YYDPRINTF(Args) \ do { \ if (yydebug) \ YYFPRINTF Args; \ } while (YYID (0)) # define YY_SYMBOL_PRINT(Title, Type, Value, Location) \ do { \ if (yydebug) \ { \ YYFPRINTF (stderr, "%s ", Title); \ yy_symbol_print (stderr, \ Type, Value, ctx, scanner); \ YYFPRINTF (stderr, "\n"); \ } \ } while (YYID (0)) /*--------------------------------. | Print this symbol on YYOUTPUT. | `--------------------------------*/ /*ARGSUSED*/ #if (defined __STDC__ || defined __C99__FUNC__ \ || defined __cplusplus || defined _MSC_VER) static void yy_symbol_value_print (FILE *yyoutput, int yytype, YYSTYPE const * const yyvaluep, struct ocpf_context *ctx, void *scanner) #else static void yy_symbol_value_print (yyoutput, yytype, yyvaluep, ctx, scanner) FILE *yyoutput; int yytype; YYSTYPE const * const yyvaluep; struct ocpf_context *ctx; void *scanner; #endif { if (!yyvaluep) return; YYUSE (ctx); YYUSE (scanner); # ifdef YYPRINT if (yytype < YYNTOKENS) YYPRINT (yyoutput, yytoknum[yytype], *yyvaluep); # else YYUSE (yyoutput); # endif switch (yytype) { default: break; } } /*--------------------------------. | Print this symbol on YYOUTPUT. | `--------------------------------*/ #if (defined __STDC__ || defined __C99__FUNC__ \ || defined __cplusplus || defined _MSC_VER) static void yy_symbol_print (FILE *yyoutput, int yytype, YYSTYPE const * const yyvaluep, struct ocpf_context *ctx, void *scanner) #else static void yy_symbol_print (yyoutput, yytype, yyvaluep, ctx, scanner) FILE *yyoutput; int yytype; YYSTYPE const * const yyvaluep; struct ocpf_context *ctx; void *scanner; #endif { if (yytype < YYNTOKENS) YYFPRINTF (yyoutput, "token %s (", yytname[yytype]); else YYFPRINTF (yyoutput, "nterm %s (", yytname[yytype]); yy_symbol_value_print (yyoutput, yytype, yyvaluep, ctx, scanner); YYFPRINTF (yyoutput, ")"); } /*------------------------------------------------------------------. | yy_stack_print -- Print the state stack from its BOTTOM up to its | | TOP (included). | `------------------------------------------------------------------*/ #if (defined __STDC__ || defined __C99__FUNC__ \ || defined __cplusplus || defined _MSC_VER) static void yy_stack_print (yytype_int16 *yybottom, yytype_int16 *yytop) #else static void yy_stack_print (yybottom, yytop) yytype_int16 *yybottom; yytype_int16 *yytop; #endif { YYFPRINTF (stderr, "Stack now"); for (; yybottom <= yytop; yybottom++) { int yybot = *yybottom; YYFPRINTF (stderr, " %d", yybot); } YYFPRINTF (stderr, "\n"); } # define YY_STACK_PRINT(Bottom, Top) \ do { \ if (yydebug) \ yy_stack_print ((Bottom), (Top)); \ } while (YYID (0)) /*------------------------------------------------. | Report that the YYRULE is going to be reduced. | `------------------------------------------------*/ #if (defined __STDC__ || defined __C99__FUNC__ \ || defined __cplusplus || defined _MSC_VER) static void yy_reduce_print (YYSTYPE *yyvsp, int yyrule, struct ocpf_context *ctx, void *scanner) #else static void yy_reduce_print (yyvsp, yyrule, ctx, scanner) YYSTYPE *yyvsp; int yyrule; struct ocpf_context *ctx; void *scanner; #endif { int yynrhs = yyr2[yyrule]; int yyi; unsigned long int yylno = yyrline[yyrule]; YYFPRINTF (stderr, "Reducing stack by rule %d (line %lu):\n", yyrule - 1, yylno); /* The symbols being reduced. */ for (yyi = 0; yyi < yynrhs; yyi++) { YYFPRINTF (stderr, " $%d = ", yyi + 1); yy_symbol_print (stderr, yyrhs[yyprhs[yyrule] + yyi], &(yyvsp[(yyi + 1) - (yynrhs)]) , ctx, scanner); YYFPRINTF (stderr, "\n"); } } # define YY_REDUCE_PRINT(Rule) \ do { \ if (yydebug) \ yy_reduce_print (yyvsp, Rule, ctx, scanner); \ } while (YYID (0)) /* Nonzero means print parse trace. It is left uninitialized so that multiple parsers can coexist. */ int yydebug; #else /* !YYDEBUG */ # define YYDPRINTF(Args) # define YY_SYMBOL_PRINT(Title, Type, Value, Location) # define YY_STACK_PRINT(Bottom, Top) # define YY_REDUCE_PRINT(Rule) #endif /* !YYDEBUG */ /* YYINITDEPTH -- initial size of the parser's stacks. */ #ifndef YYINITDEPTH # define YYINITDEPTH 200 #endif /* YYMAXDEPTH -- maximum size the stacks can grow to (effective only if the built-in stack extension method is used). Do not make this value too large; the results are undefined if YYSTACK_ALLOC_MAXIMUM < YYSTACK_BYTES (YYMAXDEPTH) evaluated with infinite-precision integer arithmetic. */ #ifndef YYMAXDEPTH # define YYMAXDEPTH 10000 #endif #if YYERROR_VERBOSE # ifndef yystrlen # if defined __GLIBC__ && defined _STRING_H # define yystrlen strlen # else /* Return the length of YYSTR. */ #if (defined __STDC__ || defined __C99__FUNC__ \ || defined __cplusplus || defined _MSC_VER) static YYSIZE_T yystrlen (const char *yystr) #else static YYSIZE_T yystrlen (yystr) const char *yystr; #endif { YYSIZE_T yylen; for (yylen = 0; yystr[yylen]; yylen++) continue; return yylen; } # endif # endif # ifndef yystpcpy # if defined __GLIBC__ && defined _STRING_H && defined _GNU_SOURCE # define yystpcpy stpcpy # else /* Copy YYSRC to YYDEST, returning the address of the terminating '\0' in YYDEST. */ #if (defined __STDC__ || defined __C99__FUNC__ \ || defined __cplusplus || defined _MSC_VER) static char * yystpcpy (char *yydest, const char *yysrc) #else static char * yystpcpy (yydest, yysrc) char *yydest; const char *yysrc; #endif { char *yyd = yydest; const char *yys = yysrc; while ((*yyd++ = *yys++) != '\0') continue; return yyd - 1; } # endif # endif # ifndef yytnamerr /* Copy to YYRES the contents of YYSTR after stripping away unnecessary quotes and backslashes, so that it's suitable for yyerror. The heuristic is that double-quoting is unnecessary unless the string contains an apostrophe, a comma, or backslash (other than backslash-backslash). YYSTR is taken from yytname. If YYRES is null, do not copy; instead, return the length of what the result would have been. */ static YYSIZE_T yytnamerr (char *yyres, const char *yystr) { if (*yystr == '"') { YYSIZE_T yyn = 0; char const *yyp = yystr; for (;;) switch (*++yyp) { case '\'': case ',': goto do_not_strip_quotes; case '\\': if (*++yyp != '\\') goto do_not_strip_quotes; /* Fall through. */ default: if (yyres) yyres[yyn] = *yyp; yyn++; break; case '"': if (yyres) yyres[yyn] = '\0'; return yyn; } do_not_strip_quotes: ; } if (! yyres) return yystrlen (yystr); return yystpcpy (yyres, yystr) - yyres; } # endif /* Copy into *YYMSG, which is of size *YYMSG_ALLOC, an error message about the unexpected token YYTOKEN for the state stack whose top is YYSSP. Return 0 if *YYMSG was successfully written. Return 1 if *YYMSG is not large enough to hold the message. In that case, also set *YYMSG_ALLOC to the required number of bytes. Return 2 if the required number of bytes is too large to store. */ static int yysyntax_error (YYSIZE_T *yymsg_alloc, char **yymsg, yytype_int16 *yyssp, int yytoken) { YYSIZE_T yysize0 = yytnamerr (0, yytname[yytoken]); YYSIZE_T yysize = yysize0; YYSIZE_T yysize1; enum { YYERROR_VERBOSE_ARGS_MAXIMUM = 5 }; /* Internationalized format string. */ const char *yyformat = 0; /* Arguments of yyformat. */ char const *yyarg[YYERROR_VERBOSE_ARGS_MAXIMUM]; /* Number of reported tokens (one for the "unexpected", one per "expected"). */ int yycount = 0; /* There are many possibilities here to consider: - Assume YYFAIL is not used. It's too flawed to consider. See for details. YYERROR is fine as it does not invoke this function. - If this state is a consistent state with a default action, then the only way this function was invoked is if the default action is an error action. In that case, don't check for expected tokens because there are none. - The only way there can be no lookahead present (in yychar) is if this state is a consistent state with a default action. Thus, detecting the absence of a lookahead is sufficient to determine that there is no unexpected or expected token to report. In that case, just report a simple "syntax error". - Don't assume there isn't a lookahead just because this state is a consistent state with a default action. There might have been a previous inconsistent state, consistent state with a non-default action, or user semantic action that manipulated yychar. - Of course, the expected token list depends on states to have correct lookahead information, and it depends on the parser not to perform extra reductions after fetching a lookahead from the scanner and before detecting a syntax error. Thus, state merging (from LALR or IELR) and default reductions corrupt the expected token list. However, the list is correct for canonical LR with one exception: it will still contain any token that will not be accepted due to an error action in a later state. */ if (yytoken != YYEMPTY) { int yyn = yypact[*yyssp]; yyarg[yycount++] = yytname[yytoken]; if (!yypact_value_is_default (yyn)) { /* Start YYX at -YYN if negative to avoid negative indexes in YYCHECK. In other words, skip the first -YYN actions for this state because they are default actions. */ int yyxbegin = yyn < 0 ? -yyn : 0; /* Stay within bounds of both yycheck and yytname. */ int yychecklim = YYLAST - yyn + 1; int yyxend = yychecklim < YYNTOKENS ? yychecklim : YYNTOKENS; int yyx; for (yyx = yyxbegin; yyx < yyxend; ++yyx) if (yycheck[yyx + yyn] == yyx && yyx != YYTERROR && !yytable_value_is_error (yytable[yyx + yyn])) { if (yycount == YYERROR_VERBOSE_ARGS_MAXIMUM) { yycount = 1; yysize = yysize0; break; } yyarg[yycount++] = yytname[yyx]; yysize1 = yysize + yytnamerr (0, yytname[yyx]); if (! (yysize <= yysize1 && yysize1 <= YYSTACK_ALLOC_MAXIMUM)) return 2; yysize = yysize1; } } } switch (yycount) { # define YYCASE_(N, S) \ case N: \ yyformat = S; \ break YYCASE_(0, YY_("syntax error")); YYCASE_(1, YY_("syntax error, unexpected %s")); YYCASE_(2, YY_("syntax error, unexpected %s, expecting %s")); YYCASE_(3, YY_("syntax error, unexpected %s, expecting %s or %s")); YYCASE_(4, YY_("syntax error, unexpected %s, expecting %s or %s or %s")); YYCASE_(5, YY_("syntax error, unexpected %s, expecting %s or %s or %s or %s")); # undef YYCASE_ } yysize1 = yysize + yystrlen (yyformat); if (! (yysize <= yysize1 && yysize1 <= YYSTACK_ALLOC_MAXIMUM)) return 2; yysize = yysize1; if (*yymsg_alloc < yysize) { *yymsg_alloc = 2 * yysize; if (! (yysize <= *yymsg_alloc && *yymsg_alloc <= YYSTACK_ALLOC_MAXIMUM)) *yymsg_alloc = YYSTACK_ALLOC_MAXIMUM; return 1; } /* Avoid sprintf, as that infringes on the user's name space. Don't have undefined behavior even if the translation produced a string with the wrong number of "%s"s. */ { char *yyp = *yymsg; int yyi = 0; while ((*yyp = *yyformat) != '\0') if (*yyp == '%' && yyformat[1] == 's' && yyi < yycount) { yyp += yytnamerr (yyp, yyarg[yyi++]); yyformat += 2; } else { yyp++; yyformat++; } } return 0; } #endif /* YYERROR_VERBOSE */ /*-----------------------------------------------. | Release the memory associated to this symbol. | `-----------------------------------------------*/ /*ARGSUSED*/ #if (defined __STDC__ || defined __C99__FUNC__ \ || defined __cplusplus || defined _MSC_VER) static void yydestruct (const char *yymsg, int yytype, YYSTYPE *yyvaluep, struct ocpf_context *ctx, void *scanner) #else static void yydestruct (yymsg, yytype, yyvaluep, ctx, scanner) const char *yymsg; int yytype; YYSTYPE *yyvaluep; struct ocpf_context *ctx; void *scanner; #endif { YYUSE (yyvaluep); YYUSE (ctx); YYUSE (scanner); if (!yymsg) yymsg = "Deleting"; YY_SYMBOL_PRINT (yymsg, yytype, yyvaluep, yylocationp); switch (yytype) { default: break; } } /* Prevent warnings from -Wmissing-prototypes. */ #ifdef YYPARSE_PARAM #if defined __STDC__ || defined __cplusplus int yyparse (void *YYPARSE_PARAM); #else int yyparse (); #endif #else /* ! YYPARSE_PARAM */ #if defined __STDC__ || defined __cplusplus int yyparse (struct ocpf_context *ctx, void *scanner); #else int yyparse (); #endif #endif /* ! YYPARSE_PARAM */ /*----------. | yyparse. | `----------*/ #ifdef YYPARSE_PARAM #if (defined __STDC__ || defined __C99__FUNC__ \ || defined __cplusplus || defined _MSC_VER) int yyparse (void *YYPARSE_PARAM) #else int yyparse (YYPARSE_PARAM) void *YYPARSE_PARAM; #endif #else /* ! YYPARSE_PARAM */ #if (defined __STDC__ || defined __C99__FUNC__ \ || defined __cplusplus || defined _MSC_VER) int yyparse (struct ocpf_context *ctx, void *scanner) #else int yyparse (ctx, scanner) struct ocpf_context *ctx; void *scanner; #endif #endif { /* The lookahead symbol. */ int yychar; /* The semantic value of the lookahead symbol. */ YYSTYPE yylval; /* Number of syntax errors so far. */ int yynerrs; int yystate; /* Number of tokens to shift before error messages enabled. */ int yyerrstatus; /* The stacks and their tools: `yyss': related to states. `yyvs': related to semantic values. Refer to the stacks thru separate pointers, to allow yyoverflow to reallocate them elsewhere. */ /* The state stack. */ yytype_int16 yyssa[YYINITDEPTH]; yytype_int16 *yyss; yytype_int16 *yyssp; /* The semantic value stack. */ YYSTYPE yyvsa[YYINITDEPTH]; YYSTYPE *yyvs; YYSTYPE *yyvsp; YYSIZE_T yystacksize; int yyn; int yyresult; /* Lookahead token as an internal (translated) token number. */ int yytoken; /* The variables used to return semantic value and location from the action routines. */ YYSTYPE yyval; #if YYERROR_VERBOSE /* Buffer for error messages, and its allocated size. */ char yymsgbuf[128]; char *yymsg = yymsgbuf; YYSIZE_T yymsg_alloc = sizeof yymsgbuf; #endif #define YYPOPSTACK(N) (yyvsp -= (N), yyssp -= (N)) /* The number of symbols on the RHS of the reduced rule. Keep to zero when no symbol should be popped. */ int yylen = 0; yytoken = 0; yyss = yyssa; yyvs = yyvsa; yystacksize = YYINITDEPTH; YYDPRINTF ((stderr, "Starting parse\n")); yystate = 0; yyerrstatus = 0; yynerrs = 0; yychar = YYEMPTY; /* Cause a token to be read. */ /* Initialize stack pointers. Waste one element of value and location stack so that they stay on the same level as the state stack. The wasted elements are never initialized. */ yyssp = yyss; yyvsp = yyvs; goto yysetstate; /*------------------------------------------------------------. | yynewstate -- Push a new state, which is found in yystate. | `------------------------------------------------------------*/ yynewstate: /* In all cases, when you get here, the value and location stacks have just been pushed. So pushing a state here evens the stacks. */ yyssp++; yysetstate: *yyssp = yystate; if (yyss + yystacksize - 1 <= yyssp) { /* Get the current used size of the three stacks, in elements. */ YYSIZE_T yysize = yyssp - yyss + 1; #ifdef yyoverflow { /* Give user a chance to reallocate the stack. Use copies of these so that the &'s don't force the real ones into memory. */ YYSTYPE *yyvs1 = yyvs; yytype_int16 *yyss1 = yyss; /* Each stack pointer address is followed by the size of the data in use in that stack, in bytes. This used to be a conditional around just the two extra args, but that might be undefined if yyoverflow is a macro. */ yyoverflow (YY_("memory exhausted"), &yyss1, yysize * sizeof (*yyssp), &yyvs1, yysize * sizeof (*yyvsp), &yystacksize); yyss = yyss1; yyvs = yyvs1; } #else /* no yyoverflow */ # ifndef YYSTACK_RELOCATE goto yyexhaustedlab; # else /* Extend the stack our own way. */ if (YYMAXDEPTH <= yystacksize) goto yyexhaustedlab; yystacksize *= 2; if (YYMAXDEPTH < yystacksize) yystacksize = YYMAXDEPTH; { yytype_int16 *yyss1 = yyss; union yyalloc *yyptr = (union yyalloc *) YYSTACK_ALLOC (YYSTACK_BYTES (yystacksize)); if (! yyptr) goto yyexhaustedlab; YYSTACK_RELOCATE (yyss_alloc, yyss); YYSTACK_RELOCATE (yyvs_alloc, yyvs); # undef YYSTACK_RELOCATE if (yyss1 != yyssa) YYSTACK_FREE (yyss1); } # endif #endif /* no yyoverflow */ yyssp = yyss + yysize - 1; yyvsp = yyvs + yysize - 1; YYDPRINTF ((stderr, "Stack size increased to %lu\n", (unsigned long int) yystacksize)); if (yyss + yystacksize - 1 <= yyssp) YYABORT; } YYDPRINTF ((stderr, "Entering state %d\n", yystate)); if (yystate == YYFINAL) YYACCEPT; goto yybackup; /*-----------. | yybackup. | `-----------*/ yybackup: /* Do appropriate processing given the current state. Read a lookahead token if we need one and don't already have one. */ /* First try to decide what to do without reference to lookahead token. */ yyn = yypact[yystate]; if (yypact_value_is_default (yyn)) goto yydefault; /* Not known => get a lookahead token if don't already have one. */ /* YYCHAR is either YYEMPTY or YYEOF or a valid lookahead symbol. */ if (yychar == YYEMPTY) { YYDPRINTF ((stderr, "Reading a token: ")); yychar = YYLEX; } if (yychar <= YYEOF) { yychar = yytoken = YYEOF; YYDPRINTF ((stderr, "Now at end of input.\n")); } else { yytoken = YYTRANSLATE (yychar); YY_SYMBOL_PRINT ("Next token is", yytoken, &yylval, &yylloc); } /* If the proper action on seeing token YYTOKEN is to reduce or to detect an error, take that action. */ yyn += yytoken; if (yyn < 0 || YYLAST < yyn || yycheck[yyn] != yytoken) goto yydefault; yyn = yytable[yyn]; if (yyn <= 0) { if (yytable_value_is_error (yyn)) goto yyerrlab; yyn = -yyn; goto yyreduce; } /* Count tokens shifted since error; after three, turn off error status. */ if (yyerrstatus) yyerrstatus--; /* Shift the lookahead token. */ YY_SYMBOL_PRINT ("Shifting", yytoken, &yylval, &yylloc); /* Discard the shifted token. */ yychar = YYEMPTY; yystate = yyn; *++yyvsp = yylval; goto yynewstate; /*-----------------------------------------------------------. | yydefault -- do the default action for the current state. | `-----------------------------------------------------------*/ yydefault: yyn = yydefact[yystate]; if (yyn == 0) goto yyerrlab; goto yyreduce; /*-----------------------------. | yyreduce -- Do a reduction. | `-----------------------------*/ yyreduce: /* yyn is the number of a rule to reduce with. */ yylen = yyr2[yyn]; /* If YYLEN is nonzero, implement the default value of the action: `$$ = $1'. Otherwise, the following line sets YYVAL to garbage. This behavior is undocumented and Bison users should not rely upon it. Assigning to YYVAL unconditionally makes the parser a bit smaller, and it avoids a GCC warning that YYVAL may be used uninitialized. */ yyval = yyvsp[1-yylen]; YY_REDUCE_PRINT (yyn); switch (yyn) { case 3: /* Line 1806 of yacc.c */ #line 108 "libocpf/ocpf.y" { memset(&ctx->lpProp, 0, sizeof (union SPropValue_CTR)); } break; case 11: /* Line 1806 of yacc.c */ #line 124 "libocpf/ocpf.y" { if (!ctx->typeset) { ocpf_type_add(ctx,(yyvsp[(2) - (2)].name)); ctx->typeset++; } else { ocpf_error_message(ctx, "%s", "duplicated TYPE\n"); return -1; } } break; case 12: /* Line 1806 of yacc.c */ #line 137 "libocpf/ocpf.y" { if (ctx->folderset == false) { ocpf_folder_add(ctx, (yyvsp[(2) - (2)].name), 0, NULL); ctx->folderset = true; } else { ocpf_error_message(ctx, "%s", "duplicated FOLDER\n"); } } break; case 13: /* Line 1806 of yacc.c */ #line 146 "libocpf/ocpf.y" { if (ctx->folderset == false) { ocpf_folder_add(ctx, NULL, (yyvsp[(2) - (2)].d), NULL); ctx->folderset = true; } else { ocpf_error_message(ctx,"%s", "duplicated FOLDER\n"); } } break; case 14: /* Line 1806 of yacc.c */ #line 155 "libocpf/ocpf.y" { if (ctx->folderset == false) { ocpf_folder_add(ctx, NULL, 0, (yyvsp[(2) - (2)].var)); ctx->folderset = true; } else { ocpf_error_message(ctx,"%s", "duplicated FOLDER\n"); } } break; case 15: /* Line 1806 of yacc.c */ #line 167 "libocpf/ocpf.y" { char *name; char *guid; name = talloc_strdup(ctx, (yyvsp[(2) - (3)].name)); guid = talloc_strdup(ctx, (yyvsp[(3) - (3)].name)); ocpf_oleguid_add(ctx, name, guid); } break; case 16: /* Line 1806 of yacc.c */ #line 180 "libocpf/ocpf.y" { ocpf_variable_add(ctx, (yyvsp[(2) - (4)].var), ctx->lpProp, ctx->ltype, true); memset(&ctx->lpProp, 0, sizeof (union SPropValue_CTR)); } break; case 17: /* Line 1806 of yacc.c */ #line 188 "libocpf/ocpf.y" { } break; case 20: /* Line 1806 of yacc.c */ #line 195 "libocpf/ocpf.y" { ocpf_recipient_set_class(ctx, MAPI_TO); ocpf_new_recipient(ctx); } break; case 21: /* Line 1806 of yacc.c */ #line 200 "libocpf/ocpf.y" { ocpf_recipient_set_class(ctx, MAPI_CC); ocpf_new_recipient(ctx); } break; case 22: /* Line 1806 of yacc.c */ #line 205 "libocpf/ocpf.y" { ocpf_recipient_set_class(ctx, MAPI_BCC); ocpf_new_recipient(ctx); } break; case 24: /* Line 1806 of yacc.c */ #line 212 "libocpf/ocpf.y" { memset(&ctx->lpProp, 0, sizeof (union SPropValue_CTR)); } break; case 25: /* Line 1806 of yacc.c */ #line 218 "libocpf/ocpf.y" { ocpf_propvalue_s(ctx, (yyvsp[(1) - (3)].name), ctx->lpProp, ctx->ltype, true, kw_RECIPIENT); ocpf_propvalue_free(ctx->lpProp, ctx->ltype); } break; case 26: /* Line 1806 of yacc.c */ #line 223 "libocpf/ocpf.y" { ocpf_propvalue(ctx, (yyvsp[(1) - (3)].l), ctx->lpProp, ctx->ltype, true, kw_RECIPIENT); ocpf_propvalue_free(ctx->lpProp, ctx->ltype); } break; case 27: /* Line 1806 of yacc.c */ #line 228 "libocpf/ocpf.y" { ocpf_propvalue_var(ctx, (yyvsp[(1) - (3)].name), 0x0, (yyvsp[(3) - (3)].var), true, kw_RECIPIENT); } break; case 28: /* Line 1806 of yacc.c */ #line 232 "libocpf/ocpf.y" { ocpf_propvalue_var(ctx, NULL, (yyvsp[(1) - (3)].l), (yyvsp[(3) - (3)].var), true, kw_RECIPIENT); } break; case 29: /* Line 1806 of yacc.c */ #line 238 "libocpf/ocpf.y" { } break; case 31: /* Line 1806 of yacc.c */ #line 242 "libocpf/ocpf.y" { memset(&ctx->lpProp, 0, sizeof (union SPropValue_CTR)); } break; case 32: /* Line 1806 of yacc.c */ #line 249 "libocpf/ocpf.y" { ocpf_propvalue_s(ctx, (yyvsp[(1) - (3)].name), ctx->lpProp, ctx->ltype, true, kw_PROPERTY); ocpf_propvalue_free(ctx->lpProp, ctx->ltype); } break; case 33: /* Line 1806 of yacc.c */ #line 254 "libocpf/ocpf.y" { ocpf_propvalue(ctx, (yyvsp[(1) - (3)].l), ctx->lpProp, ctx->ltype, true, kw_PROPERTY); ocpf_propvalue_free(ctx->lpProp, ctx->ltype); } break; case 34: /* Line 1806 of yacc.c */ #line 259 "libocpf/ocpf.y" { ocpf_propvalue_var(ctx, (yyvsp[(1) - (3)].name), 0x0, (yyvsp[(3) - (3)].var), true, kw_PROPERTY); } break; case 35: /* Line 1806 of yacc.c */ #line 263 "libocpf/ocpf.y" { ocpf_propvalue_var(ctx, NULL, (yyvsp[(1) - (3)].l), (yyvsp[(3) - (3)].var), true, kw_PROPERTY); } break; case 36: /* Line 1806 of yacc.c */ #line 269 "libocpf/ocpf.y" { ctx->lpProp.lpszA = talloc_strdup(ctx, (yyvsp[(1) - (1)].name)); ctx->ltype = PT_STRING8; } break; case 37: /* Line 1806 of yacc.c */ #line 274 "libocpf/ocpf.y" { ctx->lpProp.lpszW = talloc_strdup(ctx, (yyvsp[(1) - (1)].nameW)); ctx->ltype = PT_UNICODE; } break; case 38: /* Line 1806 of yacc.c */ #line 278 "libocpf/ocpf.y" { ctx->lpProp.i = (yyvsp[(1) - (1)].s); ctx->ltype = PT_SHORT; } break; case 39: /* Line 1806 of yacc.c */ #line 279 "libocpf/ocpf.y" { ctx->lpProp.l = (yyvsp[(1) - (1)].l); ctx->ltype = PT_LONG; } break; case 40: /* Line 1806 of yacc.c */ #line 280 "libocpf/ocpf.y" { ctx->lpProp.b = (yyvsp[(1) - (1)].b); ctx->ltype = PT_BOOLEAN; } break; case 41: /* Line 1806 of yacc.c */ #line 281 "libocpf/ocpf.y" { ctx->lpProp.d = (yyvsp[(1) - (1)].d); ctx->ltype = PT_I8; } break; case 42: /* Line 1806 of yacc.c */ #line 282 "libocpf/ocpf.y" { ctx->lpProp.dbl = (yyvsp[(1) - (1)].dbl), ctx->ltype = PT_DOUBLE; } break; case 43: /* Line 1806 of yacc.c */ #line 284 "libocpf/ocpf.y" { ocpf_add_filetime((yyvsp[(1) - (1)].date), &ctx->lpProp.ft); ctx->ltype = PT_SYSTIME; } break; case 44: /* Line 1806 of yacc.c */ #line 289 "libocpf/ocpf.y" { if (!ctx->lpProp.MVl.cValues) { ctx->lpProp.MVl.cValues = 0; ctx->lpProp.MVl.lpl = talloc_array(ctx, uint32_t, 2); } else { ctx->lpProp.MVl.lpl = talloc_realloc(NULL, ctx->lpProp.MVl.lpl, uint32_t, ctx->lpProp.MVl.cValues + 2); } ctx->lpProp.MVl.lpl[ctx->lpProp.MVl.cValues] = (yyvsp[(3) - (4)].l); ctx->lpProp.MVl.cValues += 1; ctx->ltype = PT_MV_LONG; } break; case 45: /* Line 1806 of yacc.c */ #line 304 "libocpf/ocpf.y" { TALLOC_CTX *mem_ctx; if (!ctx->lpProp.MVszA.cValues) { ctx->lpProp.MVszA.cValues = 0; ctx->lpProp.MVszA.lppszA = talloc_array(ctx, const char *, 2); } else { ctx->lpProp.MVszA.lppszA = talloc_realloc(NULL, ctx->lpProp.MVszA.lppszA, const char *, ctx->lpProp.MVszA.cValues + 2); } mem_ctx = (TALLOC_CTX *) ctx->lpProp.MVszA.lppszA; ctx->lpProp.MVszA.lppszA[ctx->lpProp.MVszA.cValues] = talloc_strdup(mem_ctx, (yyvsp[(3) - (4)].name)); ctx->lpProp.MVszA.cValues += 1; ctx->ltype = PT_MV_STRING8; } break; case 46: /* Line 1806 of yacc.c */ #line 322 "libocpf/ocpf.y" { TALLOC_CTX *mem_ctx; if (!ctx->lpProp.MVszW.cValues) { ctx->lpProp.MVszW.cValues = 0; ctx->lpProp.MVszW.lppszW = talloc_array(ctx, const char *, 2); } else { ctx->lpProp.MVszW.lppszW = talloc_realloc(NULL, ctx->lpProp.MVszW.lppszW, const char *, ctx->lpProp.MVszW.cValues + 2); } mem_ctx = (TALLOC_CTX *) ctx->lpProp.MVszW.lppszW; ctx->lpProp.MVszW.lppszW[ctx->lpProp.MVszW.cValues] = talloc_strdup(mem_ctx, (yyvsp[(3) - (4)].nameW)); ctx->lpProp.MVszW.cValues += 1; ctx->ltype = PT_MV_UNICODE; } break; case 47: /* Line 1806 of yacc.c */ #line 340 "libocpf/ocpf.y" { ctx->lpProp.bin.cb = ctx->bin.cb; ctx->lpProp.bin.lpb = talloc_memdup(ctx, ctx->bin.lpb, ctx->bin.cb); talloc_free(ctx->bin.lpb); ctx->bin.cb = 0; ctx->ltype = PT_BINARY; } break; case 48: /* Line 1806 of yacc.c */ #line 350 "libocpf/ocpf.y" { TALLOC_CTX *mem_ctx; if (!ctx->lpProp.MVbin.cValues) { ctx->lpProp.MVbin.cValues = 0; ctx->lpProp.MVbin.lpbin = talloc_array(ctx, struct Binary_r, 2); } else { ctx->lpProp.MVbin.lpbin = talloc_realloc(NULL, ctx->lpProp.MVbin.lpbin, struct Binary_r, ctx->lpProp.MVbin.cValues + 2); } mem_ctx = (TALLOC_CTX *) ctx->lpProp.MVbin.lpbin; ctx->lpProp.MVbin.lpbin[ctx->lpProp.MVbin.cValues].cb = ctx->bin.cb; ctx->lpProp.MVbin.lpbin[ctx->lpProp.MVbin.cValues].lpb = talloc_memdup(mem_ctx, ctx->bin.lpb, ctx->bin.cb); ctx->lpProp.MVbin.cValues += 1; talloc_free(ctx->bin.lpb); ctx->bin.cb = 0; ctx->ltype = PT_MV_BINARY; } break; case 49: /* Line 1806 of yacc.c */ #line 373 "libocpf/ocpf.y" { int ret; ret = ocpf_binary_add(ctx, (yyvsp[(2) - (3)].name), &ctx->lpProp.bin); ctx->ltype = (ret == OCPF_SUCCESS) ? PT_BINARY : PT_ERROR; } break; case 52: /* Line 1806 of yacc.c */ #line 384 "libocpf/ocpf.y" { if (!ctx->lpProp.MVl.cValues) { ctx->lpProp.MVl.cValues = 0; ctx->lpProp.MVl.lpl = talloc_array(ctx, uint32_t, 2); } else { ctx->lpProp.MVl.lpl = talloc_realloc(NULL, ctx->lpProp.MVl.lpl, uint32_t, ctx->lpProp.MVl.cValues + 2); } ctx->lpProp.MVl.lpl[ctx->lpProp.MVl.cValues] = (yyvsp[(1) - (2)].l); ctx->lpProp.MVl.cValues += 1; } break; case 55: /* Line 1806 of yacc.c */ #line 402 "libocpf/ocpf.y" { TALLOC_CTX *mem_ctx; if (!ctx->lpProp.MVszA.cValues) { ctx->lpProp.MVszA.cValues = 0; ctx->lpProp.MVszA.lppszA = talloc_array(ctx, const char *, 2); } else { ctx->lpProp.MVszA.lppszA = talloc_realloc(NULL, ctx->lpProp.MVszA.lppszA, const char *, ctx->lpProp.MVszA.cValues + 2); } mem_ctx = (TALLOC_CTX *) ctx->lpProp.MVszA.lppszA; ctx->lpProp.MVszA.lppszA[ctx->lpProp.MVszA.cValues] = talloc_strdup(mem_ctx, (yyvsp[(1) - (2)].name)); ctx->lpProp.MVszA.cValues += 1; } break; case 58: /* Line 1806 of yacc.c */ #line 422 "libocpf/ocpf.y" { TALLOC_CTX *mem_ctx; if (!ctx->lpProp.MVszW.cValues) { ctx->lpProp.MVszW.cValues = 0; ctx->lpProp.MVszW.lppszW = talloc_array(ctx, const char *, 2); } else { ctx->lpProp.MVszW.lppszW = talloc_realloc(NULL, ctx->lpProp.MVszW.lppszW, const char *, ctx->lpProp.MVszW.cValues + 2); } mem_ctx = (TALLOC_CTX *) ctx->lpProp.MVszW.lppszW; ctx->lpProp.MVszW.lppszW[ctx->lpProp.MVszW.cValues] = talloc_strdup(mem_ctx, (yyvsp[(1) - (2)].nameW)); ctx->lpProp.MVszW.cValues += 1; } break; case 61: /* Line 1806 of yacc.c */ #line 442 "libocpf/ocpf.y" { if ((yyvsp[(1) - (1)].i) > 0xFF) { ocpf_error_message(ctx,"Invalid Binary constant: 0x%x > 0xFF\n", (yyvsp[(1) - (1)].i)); } if (!ctx->bin.cb) { ctx->bin.cb = 0; ctx->bin.lpb = talloc_array(ctx, uint8_t, 2); } else { ctx->bin.lpb = talloc_realloc(NULL, ctx->bin.lpb, uint8_t, ctx->bin.cb + 2); } ctx->bin.lpb[ctx->bin.cb] = (yyvsp[(1) - (1)].i); ctx->bin.cb += 1; } break; case 64: /* Line 1806 of yacc.c */ #line 462 "libocpf/ocpf.y" { TALLOC_CTX *mem_ctx; if (!ctx->lpProp.MVbin.cValues) { ctx->lpProp.MVbin.cValues = 0; ctx->lpProp.MVbin.lpbin = talloc_array(ctx, struct Binary_r, 2); } else { ctx->lpProp.MVbin.lpbin = talloc_realloc(NULL, ctx->lpProp.MVbin.lpbin, struct Binary_r, ctx->lpProp.MVbin.cValues + 2); } mem_ctx = (TALLOC_CTX *) ctx->lpProp.MVbin.lpbin; ctx->lpProp.MVbin.lpbin[ctx->lpProp.MVbin.cValues].cb = ctx->bin.cb; ctx->lpProp.MVbin.lpbin[ctx->lpProp.MVbin.cValues].lpb = talloc_memdup(mem_ctx, ctx->bin.lpb, ctx->bin.cb); ctx->lpProp.MVbin.cValues += 1; ctx->bin.cb = 0; } break; case 65: /* Line 1806 of yacc.c */ #line 486 "libocpf/ocpf.y" { } break; case 67: /* Line 1806 of yacc.c */ #line 490 "libocpf/ocpf.y" { memset(&ctx->lpProp, 0, sizeof (union SPropValue_CTR)); } break; case 68: /* Line 1806 of yacc.c */ #line 496 "libocpf/ocpf.y" { ocpf_nproperty_add(ctx, &ctx->nprop, ctx->lpProp, NULL, ctx->ltype, true); } break; case 69: /* Line 1806 of yacc.c */ #line 500 "libocpf/ocpf.y" { ocpf_nproperty_add(ctx, &ctx->nprop, ctx->lpProp, NULL, ctx->ltype, true); } break; case 70: /* Line 1806 of yacc.c */ #line 504 "libocpf/ocpf.y" { ocpf_nproperty_add(ctx, &ctx->nprop, ctx->lpProp, (yyvsp[(3) - (3)].var), ctx->ltype, true); } break; case 71: /* Line 1806 of yacc.c */ #line 508 "libocpf/ocpf.y" { ocpf_nproperty_add(ctx, &ctx->nprop, ctx->lpProp, (yyvsp[(3) - (3)].var), ctx->ltype, true); } break; case 72: /* Line 1806 of yacc.c */ #line 514 "libocpf/ocpf.y" { memset(&ctx->nprop, 0, sizeof (struct ocpf_nprop)); ctx->nprop.OOM = talloc_strdup(ctx, (yyvsp[(3) - (5)].name)); ctx->nprop.guid = (yyvsp[(5) - (5)].name); } break; case 73: /* Line 1806 of yacc.c */ #line 520 "libocpf/ocpf.y" { ctx->nprop.registered = false; ctx->nprop.mnid_id = (yyvsp[(3) - (7)].l); ctx->nprop.guid = (yyvsp[(7) - (7)].name); } break; case 74: /* Line 1806 of yacc.c */ #line 526 "libocpf/ocpf.y" { ctx->nprop.registered = false; ctx->nprop.mnid_string = talloc_strdup(ctx, (yyvsp[(3) - (7)].name)); ctx->nprop.guid = (yyvsp[(7) - (7)].name); } break; case 75: /* Line 1806 of yacc.c */ #line 534 "libocpf/ocpf.y" { memset(&ctx->nprop, 0, sizeof (struct ocpf_nprop)); ctx->nprop.propType = PT_STRING8; } break; case 76: /* Line 1806 of yacc.c */ #line 539 "libocpf/ocpf.y" { memset(&ctx->nprop, 0, sizeof (struct ocpf_nprop)); ctx->nprop.propType = PT_UNICODE; } break; case 77: /* Line 1806 of yacc.c */ #line 544 "libocpf/ocpf.y" { memset(&ctx->nprop, 0, sizeof (struct ocpf_nprop)); ctx->nprop.propType = PT_SHORT; } break; case 78: /* Line 1806 of yacc.c */ #line 549 "libocpf/ocpf.y" { memset(&ctx->nprop, 0, sizeof (struct ocpf_nprop)); ctx->nprop.propType = PT_LONG; } break; case 79: /* Line 1806 of yacc.c */ #line 554 "libocpf/ocpf.y" { memset(&ctx->nprop, 0, sizeof (struct ocpf_nprop)); ctx->nprop.propType = PT_DOUBLE; } break; case 80: /* Line 1806 of yacc.c */ #line 559 "libocpf/ocpf.y" { memset(&ctx->nprop, 0, sizeof (struct ocpf_nprop)); ctx->nprop.propType = PT_I8; } break; case 81: /* Line 1806 of yacc.c */ #line 564 "libocpf/ocpf.y" { memset(&ctx->nprop, 0, sizeof (struct ocpf_nprop)); ctx->nprop.propType = PT_BOOLEAN; } break; case 82: /* Line 1806 of yacc.c */ #line 569 "libocpf/ocpf.y" { memset(&ctx->nprop, 0, sizeof (struct ocpf_nprop)); ctx->nprop.propType = PT_SYSTIME; } break; case 83: /* Line 1806 of yacc.c */ #line 574 "libocpf/ocpf.y" { memset(&ctx->nprop, 0, sizeof (struct ocpf_nprop)); ctx->nprop.propType = PT_MV_LONG; } break; case 84: /* Line 1806 of yacc.c */ #line 579 "libocpf/ocpf.y" { memset(&ctx->nprop, 0, sizeof (struct ocpf_nprop)); ctx->nprop.propType = PT_MV_STRING8; } break; case 85: /* Line 1806 of yacc.c */ #line 584 "libocpf/ocpf.y" { memset(&ctx->nprop, 0, sizeof (struct ocpf_nprop)); ctx->nprop.propType = PT_MV_UNICODE; } break; case 86: /* Line 1806 of yacc.c */ #line 589 "libocpf/ocpf.y" { memset(&ctx->nprop, 0, sizeof (struct ocpf_nprop)); ctx->nprop.propType = PT_BINARY; } break; case 87: /* Line 1806 of yacc.c */ #line 594 "libocpf/ocpf.y" { memset(&ctx->nprop, 0, sizeof (struct ocpf_nprop)); ctx->nprop.propType = PT_MV_BINARY; } break; case 88: /* Line 1806 of yacc.c */ #line 601 "libocpf/ocpf.y" { memset(&ctx->nprop, 0, sizeof (struct ocpf_nprop)); ctx->nprop.registered = true; ctx->nprop.mnid_id = (yyvsp[(3) - (5)].l); ctx->nprop.guid = (yyvsp[(5) - (5)].name); } break; case 89: /* Line 1806 of yacc.c */ #line 608 "libocpf/ocpf.y" { memset(&ctx->nprop, 0, sizeof (struct ocpf_nprop)); ctx->nprop.registered = true; ctx->nprop.mnid_string = talloc_strdup(ctx, (yyvsp[(3) - (5)].name)); ctx->nprop.guid = (yyvsp[(5) - (5)].name); } break; /* Line 1806 of yacc.c */ #line 2362 "libocpf/ocpf.tab.c" default: break; } /* User semantic actions sometimes alter yychar, and that requires that yytoken be updated with the new translation. We take the approach of translating immediately before every use of yytoken. One alternative is translating here after every semantic action, but that translation would be missed if the semantic action invokes YYABORT, YYACCEPT, or YYERROR immediately after altering yychar or if it invokes YYBACKUP. In the case of YYABORT or YYACCEPT, an incorrect destructor might then be invoked immediately. In the case of YYERROR or YYBACKUP, subsequent parser actions might lead to an incorrect destructor call or verbose syntax error message before the lookahead is translated. */ YY_SYMBOL_PRINT ("-> $$ =", yyr1[yyn], &yyval, &yyloc); YYPOPSTACK (yylen); yylen = 0; YY_STACK_PRINT (yyss, yyssp); *++yyvsp = yyval; /* Now `shift' the result of the reduction. Determine what state that goes to, based on the state we popped back to and the rule number reduced by. */ yyn = yyr1[yyn]; yystate = yypgoto[yyn - YYNTOKENS] + *yyssp; if (0 <= yystate && yystate <= YYLAST && yycheck[yystate] == *yyssp) yystate = yytable[yystate]; else yystate = yydefgoto[yyn - YYNTOKENS]; goto yynewstate; /*------------------------------------. | yyerrlab -- here on detecting error | `------------------------------------*/ yyerrlab: /* Make sure we have latest lookahead translation. See comments at user semantic actions for why this is necessary. */ yytoken = yychar == YYEMPTY ? YYEMPTY : YYTRANSLATE (yychar); /* If not already recovering from an error, report this error. */ if (!yyerrstatus) { ++yynerrs; #if ! YYERROR_VERBOSE yyerror (ctx, scanner, YY_("syntax error")); #else # define YYSYNTAX_ERROR yysyntax_error (&yymsg_alloc, &yymsg, \ yyssp, yytoken) { char const *yymsgp = YY_("syntax error"); int yysyntax_error_status; yysyntax_error_status = YYSYNTAX_ERROR; if (yysyntax_error_status == 0) yymsgp = yymsg; else if (yysyntax_error_status == 1) { if (yymsg != yymsgbuf) YYSTACK_FREE (yymsg); yymsg = (char *) YYSTACK_ALLOC (yymsg_alloc); if (!yymsg) { yymsg = yymsgbuf; yymsg_alloc = sizeof yymsgbuf; yysyntax_error_status = 2; } else { yysyntax_error_status = YYSYNTAX_ERROR; yymsgp = yymsg; } } yyerror (ctx, scanner, yymsgp); if (yysyntax_error_status == 2) goto yyexhaustedlab; } # undef YYSYNTAX_ERROR #endif } if (yyerrstatus == 3) { /* If just tried and failed to reuse lookahead token after an error, discard it. */ if (yychar <= YYEOF) { /* Return failure if at end of input. */ if (yychar == YYEOF) YYABORT; } else { yydestruct ("Error: discarding", yytoken, &yylval, ctx, scanner); yychar = YYEMPTY; } } /* Else will try to reuse lookahead token after shifting the error token. */ goto yyerrlab1; /*---------------------------------------------------. | yyerrorlab -- error raised explicitly by YYERROR. | `---------------------------------------------------*/ yyerrorlab: /* Pacify compilers like GCC when the user code never invokes YYERROR and the label yyerrorlab therefore never appears in user code. */ if (/*CONSTCOND*/ 0) goto yyerrorlab; /* Do not reclaim the symbols of the rule which action triggered this YYERROR. */ YYPOPSTACK (yylen); yylen = 0; YY_STACK_PRINT (yyss, yyssp); yystate = *yyssp; goto yyerrlab1; /*-------------------------------------------------------------. | yyerrlab1 -- common code for both syntax error and YYERROR. | `-------------------------------------------------------------*/ yyerrlab1: yyerrstatus = 3; /* Each real token shifted decrements this. */ for (;;) { yyn = yypact[yystate]; if (!yypact_value_is_default (yyn)) { yyn += YYTERROR; if (0 <= yyn && yyn <= YYLAST && yycheck[yyn] == YYTERROR) { yyn = yytable[yyn]; if (0 < yyn) break; } } /* Pop the current state because it cannot handle the error token. */ if (yyssp == yyss) YYABORT; yydestruct ("Error: popping", yystos[yystate], yyvsp, ctx, scanner); YYPOPSTACK (1); yystate = *yyssp; YY_STACK_PRINT (yyss, yyssp); } *++yyvsp = yylval; /* Shift the error token. */ YY_SYMBOL_PRINT ("Shifting", yystos[yyn], yyvsp, yylsp); yystate = yyn; goto yynewstate; /*-------------------------------------. | yyacceptlab -- YYACCEPT comes here. | `-------------------------------------*/ yyacceptlab: yyresult = 0; goto yyreturn; /*-----------------------------------. | yyabortlab -- YYABORT comes here. | `-----------------------------------*/ yyabortlab: yyresult = 1; goto yyreturn; #if !defined(yyoverflow) || YYERROR_VERBOSE /*-------------------------------------------------. | yyexhaustedlab -- memory exhaustion comes here. | `-------------------------------------------------*/ yyexhaustedlab: yyerror (ctx, scanner, YY_("memory exhausted")); yyresult = 2; /* Fall through. */ #endif yyreturn: if (yychar != YYEMPTY) { /* Make sure we have latest lookahead translation. See comments at user semantic actions for why this is necessary. */ yytoken = YYTRANSLATE (yychar); yydestruct ("Cleanup: discarding lookahead", yytoken, &yylval, ctx, scanner); } /* Do not reclaim the symbols of the rule which action triggered this YYABORT or YYACCEPT. */ YYPOPSTACK (yylen); YY_STACK_PRINT (yyss, yyssp); while (yyssp != yyss) { yydestruct ("Cleanup: popping", yystos[*yyssp], yyvsp, ctx, scanner); YYPOPSTACK (1); } #ifndef yyoverflow if (yyss != yyssa) YYSTACK_FREE (yyss); #endif #if YYERROR_VERBOSE if (yymsg != yymsgbuf) YYSTACK_FREE (yymsg); #endif /* Make sure YYID is used. */ return YYID (yyresult); } /* Line 2067 of yacc.c */ #line 616 "libocpf/ocpf.y" void yyerror(struct ocpf_context *ctx, void *scanner, char *s) { printf("%s: %d\n", s, ctx->lineno); fflush(0); } openchange-2.0/libocpf/ocpf.tab.h000066400000000000000000000063631223057412600167570ustar00rootroot00000000000000/* A Bison parser, made by GNU Bison 2.5. */ /* Bison interface for Yacc-like parsers in C Copyright (C) 1984, 1989-1990, 2000-2011 Free Software Foundation, Inc. This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see . */ /* As a special exception, you may create a larger work that contains part or all of the Bison parser skeleton and distribute that work under terms of your choice, so long as that work isn't itself a parser generator using the skeleton or a modified version thereof as a parser skeleton. Alternatively, if you modify or redistribute the parser skeleton itself, you may (at your option) remove this special exception, which will cause the skeleton and the resulting Bison output files to be licensed under the GNU General Public License without this special exception. This special exception was added by the Free Software Foundation in version 2.2 of Bison. */ /* Tokens. */ #ifndef YYTOKENTYPE # define YYTOKENTYPE /* Put the tokens into the symbol table, so that GDB and other debuggers know about them. */ enum yytokentype { UINT8 = 258, BOOLEAN = 259, SHORT = 260, INTEGER = 261, I8 = 262, DOUBLE = 263, IDENTIFIER = 264, STRING = 265, UNICODE = 266, SYSTIME = 267, VAR = 268, kw_TYPE = 269, kw_FOLDER = 270, kw_OLEGUID = 271, kw_SET = 272, kw_PROPERTY = 273, kw_NPROPERTY = 274, kw_RECIPIENT = 275, kw_TO = 276, kw_CC = 277, kw_BCC = 278, kw_OOM = 279, kw_MNID_ID = 280, kw_MNID_STRING = 281, kw_PT_BOOLEAN = 282, kw_PT_STRING8 = 283, kw_PT_UNICODE = 284, kw_PT_SHORT = 285, kw_PT_LONG = 286, kw_PT_I8 = 287, kw_PT_DOUBLE = 288, kw_PT_SYSTIME = 289, kw_PT_MV_LONG = 290, kw_PT_MV_BINARY = 291, kw_PT_MV_STRING8 = 292, kw_PT_MV_UNICODE = 293, kw_PT_BINARY = 294, OBRACE = 295, EBRACE = 296, COMMA = 297, SEMICOLON = 298, COLON = 299, LOWER = 300, GREATER = 301, EQUAL = 302 }; #endif #if ! defined YYSTYPE && ! defined YYSTYPE_IS_DECLARED typedef union YYSTYPE { /* Line 2068 of yacc.c */ #line 37 "libocpf/ocpf.y" uint8_t i; uint8_t b; uint16_t s; uint32_t l; uint64_t d; double dbl; char *name; char *nameW; char *date; char *var; struct LongArray_r MVl; struct StringArray_r MVszA; struct StringArrayW_r MVszW; struct BinaryArray_r MVbin; /* Line 2068 of yacc.c */ #line 116 "libocpf/ocpf.tab.h" } YYSTYPE; # define YYSTYPE_IS_TRIVIAL 1 # define yystype YYSTYPE /* obsolescent; will be withdrawn */ # define YYSTYPE_IS_DECLARED 1 #endif openchange-2.0/libocpf/ocpf.y000066400000000000000000000350631223057412600162320ustar00rootroot00000000000000/* OpenChange OCPF (OpenChange Property File) implementation. Copyright (C) Julien Kerihuel 2008-2011. This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see . */ %{ #include "libocpf/ocpf.h" #include "libocpf/ocpf_api.h" #include "libocpf/lex.h" int ocpf_yylex(void *, void *); void yyerror(struct ocpf_context *, void *, char *); %} %pure_parser %parse-param {struct ocpf_context *ctx} %parse-param {void *scanner} %lex-param {yyscan_t *scanner} %name-prefix="ocpf_yy" %union { uint8_t i; uint8_t b; uint16_t s; uint32_t l; uint64_t d; double dbl; char *name; char *nameW; char *date; char *var; struct LongArray_r MVl; struct StringArray_r MVszA; struct StringArrayW_r MVszW; struct BinaryArray_r MVbin; } %token UINT8 %token BOOLEAN %token SHORT %token INTEGER %token I8 %token DOUBLE %token IDENTIFIER %token STRING %token UNICODE %token SYSTIME %token VAR %token kw_TYPE %token kw_FOLDER %token kw_OLEGUID %token kw_SET %token kw_PROPERTY %token kw_NPROPERTY %token kw_RECIPIENT %token kw_TO %token kw_CC %token kw_BCC %token kw_OOM %token kw_MNID_ID %token kw_MNID_STRING %token kw_PT_BOOLEAN %token kw_PT_STRING8 %token kw_PT_UNICODE %token kw_PT_SHORT %token kw_PT_LONG %token kw_PT_I8 %token kw_PT_DOUBLE %token kw_PT_SYSTIME %token kw_PT_MV_LONG %token kw_PT_MV_BINARY %token kw_PT_MV_STRING8 %token kw_PT_MV_UNICODE %token kw_PT_BINARY %token OBRACE %token EBRACE %token COMMA %token SEMICOLON %token COLON %token LOWER %token GREATER %token EQUAL %start keywords %% keywords : | keywords kvalues { memset(&ctx->lpProp, 0, sizeof (union SPropValue_CTR)); } ; kvalues : Type | Folder | OLEGUID | Set | Property | NProperty | Recipient ; Type : kw_TYPE STRING { if (!ctx->typeset) { ocpf_type_add(ctx,$2); ctx->typeset++; } else { ocpf_error_message(ctx, "%s", "duplicated TYPE\n"); return -1; } } ; Folder : kw_FOLDER STRING { if (ctx->folderset == false) { ocpf_folder_add(ctx, $2, 0, NULL); ctx->folderset = true; } else { ocpf_error_message(ctx, "%s", "duplicated FOLDER\n"); } } | kw_FOLDER I8 { if (ctx->folderset == false) { ocpf_folder_add(ctx, NULL, $2, NULL); ctx->folderset = true; } else { ocpf_error_message(ctx,"%s", "duplicated FOLDER\n"); } } | kw_FOLDER VAR { if (ctx->folderset == false) { ocpf_folder_add(ctx, NULL, 0, $2); ctx->folderset = true; } else { ocpf_error_message(ctx,"%s", "duplicated FOLDER\n"); } } ; OLEGUID : kw_OLEGUID IDENTIFIER STRING { char *name; char *guid; name = talloc_strdup(ctx, $2); guid = talloc_strdup(ctx, $3); ocpf_oleguid_add(ctx, name, guid); } ; Set : kw_SET VAR EQUAL propvalue { ocpf_variable_add(ctx, $2, ctx->lpProp, ctx->ltype, true); memset(&ctx->lpProp, 0, sizeof (union SPropValue_CTR)); } ; Recipient : kw_RECIPIENT OBRACE recipients EBRACE SEMICOLON { } recipients : | recipients recipient recipient : kw_TO OBRACE rpcontent EBRACE SEMICOLON { ocpf_recipient_set_class(ctx, MAPI_TO); ocpf_new_recipient(ctx); } | kw_CC OBRACE rpcontent EBRACE SEMICOLON { ocpf_recipient_set_class(ctx, MAPI_CC); ocpf_new_recipient(ctx); } | kw_BCC OBRACE rpcontent EBRACE SEMICOLON { ocpf_recipient_set_class(ctx, MAPI_BCC); ocpf_new_recipient(ctx); } ; rpcontent : | rpcontent rcontent { memset(&ctx->lpProp, 0, sizeof (union SPropValue_CTR)); } rcontent : IDENTIFIER EQUAL propvalue { ocpf_propvalue_s(ctx, $1, ctx->lpProp, ctx->ltype, true, kw_RECIPIENT); ocpf_propvalue_free(ctx->lpProp, ctx->ltype); } | INTEGER EQUAL propvalue { ocpf_propvalue(ctx, $1, ctx->lpProp, ctx->ltype, true, kw_RECIPIENT); ocpf_propvalue_free(ctx->lpProp, ctx->ltype); } | IDENTIFIER EQUAL VAR { ocpf_propvalue_var(ctx, $1, 0x0, $3, true, kw_RECIPIENT); } | INTEGER EQUAL VAR { ocpf_propvalue_var(ctx, NULL, $1, $3, true, kw_RECIPIENT); }; Property : kw_PROPERTY OBRACE pcontent EBRACE SEMICOLON { } pcontent : | pcontent content { memset(&ctx->lpProp, 0, sizeof (union SPropValue_CTR)); } ; content : IDENTIFIER EQUAL propvalue { ocpf_propvalue_s(ctx, $1, ctx->lpProp, ctx->ltype, true, kw_PROPERTY); ocpf_propvalue_free(ctx->lpProp, ctx->ltype); } | INTEGER EQUAL propvalue { ocpf_propvalue(ctx, $1, ctx->lpProp, ctx->ltype, true, kw_PROPERTY); ocpf_propvalue_free(ctx->lpProp, ctx->ltype); } | IDENTIFIER EQUAL VAR { ocpf_propvalue_var(ctx, $1, 0x0, $3, true, kw_PROPERTY); } | INTEGER EQUAL VAR { ocpf_propvalue_var(ctx, NULL, $1, $3, true, kw_PROPERTY); } ; propvalue : STRING { ctx->lpProp.lpszA = talloc_strdup(ctx, $1); ctx->ltype = PT_STRING8; } | UNICODE { ctx->lpProp.lpszW = talloc_strdup(ctx, $1); ctx->ltype = PT_UNICODE; } | SHORT { ctx->lpProp.i = $1; ctx->ltype = PT_SHORT; } | INTEGER { ctx->lpProp.l = $1; ctx->ltype = PT_LONG; } | BOOLEAN { ctx->lpProp.b = $1; ctx->ltype = PT_BOOLEAN; } | I8 { ctx->lpProp.d = $1; ctx->ltype = PT_I8; } | DOUBLE { ctx->lpProp.dbl = $1, ctx->ltype = PT_DOUBLE; } | SYSTIME { ocpf_add_filetime($1, &ctx->lpProp.ft); ctx->ltype = PT_SYSTIME; } | OBRACE mvlong_contents INTEGER EBRACE { if (!ctx->lpProp.MVl.cValues) { ctx->lpProp.MVl.cValues = 0; ctx->lpProp.MVl.lpl = talloc_array(ctx, uint32_t, 2); } else { ctx->lpProp.MVl.lpl = talloc_realloc(NULL, ctx->lpProp.MVl.lpl, uint32_t, ctx->lpProp.MVl.cValues + 2); } ctx->lpProp.MVl.lpl[ctx->lpProp.MVl.cValues] = $3; ctx->lpProp.MVl.cValues += 1; ctx->ltype = PT_MV_LONG; } | OBRACE mvstring_contents STRING EBRACE { TALLOC_CTX *mem_ctx; if (!ctx->lpProp.MVszA.cValues) { ctx->lpProp.MVszA.cValues = 0; ctx->lpProp.MVszA.lppszA = talloc_array(ctx, const char *, 2); } else { ctx->lpProp.MVszA.lppszA = talloc_realloc(NULL, ctx->lpProp.MVszA.lppszA, const char *, ctx->lpProp.MVszA.cValues + 2); } mem_ctx = (TALLOC_CTX *) ctx->lpProp.MVszA.lppszA; ctx->lpProp.MVszA.lppszA[ctx->lpProp.MVszA.cValues] = talloc_strdup(mem_ctx, $3); ctx->lpProp.MVszA.cValues += 1; ctx->ltype = PT_MV_STRING8; } | OBRACE mvunicode_contents UNICODE EBRACE { TALLOC_CTX *mem_ctx; if (!ctx->lpProp.MVszW.cValues) { ctx->lpProp.MVszW.cValues = 0; ctx->lpProp.MVszW.lppszW = talloc_array(ctx, const char *, 2); } else { ctx->lpProp.MVszW.lppszW = talloc_realloc(NULL, ctx->lpProp.MVszW.lppszW, const char *, ctx->lpProp.MVszW.cValues + 2); } mem_ctx = (TALLOC_CTX *) ctx->lpProp.MVszW.lppszW; ctx->lpProp.MVszW.lppszW[ctx->lpProp.MVszW.cValues] = talloc_strdup(mem_ctx, $3); ctx->lpProp.MVszW.cValues += 1; ctx->ltype = PT_MV_UNICODE; } | OBRACE binary_contents EBRACE { ctx->lpProp.bin.cb = ctx->bin.cb; ctx->lpProp.bin.lpb = talloc_memdup(ctx, ctx->bin.lpb, ctx->bin.cb); talloc_free(ctx->bin.lpb); ctx->bin.cb = 0; ctx->ltype = PT_BINARY; } | OBRACE mvbin_contents OBRACE binary_contents EBRACE EBRACE { TALLOC_CTX *mem_ctx; if (!ctx->lpProp.MVbin.cValues) { ctx->lpProp.MVbin.cValues = 0; ctx->lpProp.MVbin.lpbin = talloc_array(ctx, struct Binary_r, 2); } else { ctx->lpProp.MVbin.lpbin = talloc_realloc(NULL, ctx->lpProp.MVbin.lpbin, struct Binary_r, ctx->lpProp.MVbin.cValues + 2); } mem_ctx = (TALLOC_CTX *) ctx->lpProp.MVbin.lpbin; ctx->lpProp.MVbin.lpbin[ctx->lpProp.MVbin.cValues].cb = ctx->bin.cb; ctx->lpProp.MVbin.lpbin[ctx->lpProp.MVbin.cValues].lpb = talloc_memdup(mem_ctx, ctx->bin.lpb, ctx->bin.cb); ctx->lpProp.MVbin.cValues += 1; talloc_free(ctx->bin.lpb); ctx->bin.cb = 0; ctx->ltype = PT_MV_BINARY; } | LOWER STRING GREATER { int ret; ret = ocpf_binary_add(ctx, $2, &ctx->lpProp.bin); ctx->ltype = (ret == OCPF_SUCCESS) ? PT_BINARY : PT_ERROR; } ; mvlong_contents: | mvlong_contents mvlong_content mvlong_content : INTEGER COMMA { if (!ctx->lpProp.MVl.cValues) { ctx->lpProp.MVl.cValues = 0; ctx->lpProp.MVl.lpl = talloc_array(ctx, uint32_t, 2); } else { ctx->lpProp.MVl.lpl = talloc_realloc(NULL, ctx->lpProp.MVl.lpl, uint32_t, ctx->lpProp.MVl.cValues + 2); } ctx->lpProp.MVl.lpl[ctx->lpProp.MVl.cValues] = $1; ctx->lpProp.MVl.cValues += 1; } ; mvstring_contents: | mvstring_contents mvstring_content mvstring_content : STRING COMMA { TALLOC_CTX *mem_ctx; if (!ctx->lpProp.MVszA.cValues) { ctx->lpProp.MVszA.cValues = 0; ctx->lpProp.MVszA.lppszA = talloc_array(ctx, const char *, 2); } else { ctx->lpProp.MVszA.lppszA = talloc_realloc(NULL, ctx->lpProp.MVszA.lppszA, const char *, ctx->lpProp.MVszA.cValues + 2); } mem_ctx = (TALLOC_CTX *) ctx->lpProp.MVszA.lppszA; ctx->lpProp.MVszA.lppszA[ctx->lpProp.MVszA.cValues] = talloc_strdup(mem_ctx, $1); ctx->lpProp.MVszA.cValues += 1; } ; mvunicode_contents: | mvunicode_contents mvunicode_content mvunicode_content: UNICODE COMMA { TALLOC_CTX *mem_ctx; if (!ctx->lpProp.MVszW.cValues) { ctx->lpProp.MVszW.cValues = 0; ctx->lpProp.MVszW.lppszW = talloc_array(ctx, const char *, 2); } else { ctx->lpProp.MVszW.lppszW = talloc_realloc(NULL, ctx->lpProp.MVszW.lppszW, const char *, ctx->lpProp.MVszW.cValues + 2); } mem_ctx = (TALLOC_CTX *) ctx->lpProp.MVszW.lppszW; ctx->lpProp.MVszW.lppszW[ctx->lpProp.MVszW.cValues] = talloc_strdup(mem_ctx, $1); ctx->lpProp.MVszW.cValues += 1; } ; binary_contents: | binary_contents binary_content binary_content : UINT8 { if ($1 > 0xFF) { ocpf_error_message(ctx,"Invalid Binary constant: 0x%x > 0xFF\n", $1); } if (!ctx->bin.cb) { ctx->bin.cb = 0; ctx->bin.lpb = talloc_array(ctx, uint8_t, 2); } else { ctx->bin.lpb = talloc_realloc(NULL, ctx->bin.lpb, uint8_t, ctx->bin.cb + 2); } ctx->bin.lpb[ctx->bin.cb] = $1; ctx->bin.cb += 1; } ; mvbin_contents: | mvbin_contents mvbin_content mvbin_content : OBRACE binary_contents EBRACE COMMA { TALLOC_CTX *mem_ctx; if (!ctx->lpProp.MVbin.cValues) { ctx->lpProp.MVbin.cValues = 0; ctx->lpProp.MVbin.lpbin = talloc_array(ctx, struct Binary_r, 2); } else { ctx->lpProp.MVbin.lpbin = talloc_realloc(NULL, ctx->lpProp.MVbin.lpbin, struct Binary_r, ctx->lpProp.MVbin.cValues + 2); } mem_ctx = (TALLOC_CTX *) ctx->lpProp.MVbin.lpbin; ctx->lpProp.MVbin.lpbin[ctx->lpProp.MVbin.cValues].cb = ctx->bin.cb; ctx->lpProp.MVbin.lpbin[ctx->lpProp.MVbin.cValues].lpb = talloc_memdup(mem_ctx, ctx->bin.lpb, ctx->bin.cb); ctx->lpProp.MVbin.cValues += 1; ctx->bin.cb = 0; } ; NProperty : kw_NPROPERTY OBRACE npcontent EBRACE SEMICOLON { } npcontent : | npcontent ncontent { memset(&ctx->lpProp, 0, sizeof (union SPropValue_CTR)); } ; ncontent : kind EQUAL propvalue { ocpf_nproperty_add(ctx, &ctx->nprop, ctx->lpProp, NULL, ctx->ltype, true); } | known_kind EQUAL propvalue { ocpf_nproperty_add(ctx, &ctx->nprop, ctx->lpProp, NULL, ctx->ltype, true); } | kind EQUAL VAR { ocpf_nproperty_add(ctx, &ctx->nprop, ctx->lpProp, $3, ctx->ltype, true); } | known_kind EQUAL VAR { ocpf_nproperty_add(ctx, &ctx->nprop, ctx->lpProp, $3, ctx->ltype, true); } ; kind : kw_OOM COLON IDENTIFIER COLON IDENTIFIER { memset(&ctx->nprop, 0, sizeof (struct ocpf_nprop)); ctx->nprop.OOM = talloc_strdup(ctx, $3); ctx->nprop.guid = $5; } | kw_MNID_ID COLON INTEGER COLON proptype COLON IDENTIFIER { ctx->nprop.registered = false; ctx->nprop.mnid_id = $3; ctx->nprop.guid = $7; } | kw_MNID_STRING COLON STRING COLON proptype COLON IDENTIFIER { ctx->nprop.registered = false; ctx->nprop.mnid_string = talloc_strdup(ctx, $3); ctx->nprop.guid = $7; } ; proptype : kw_PT_STRING8 { memset(&ctx->nprop, 0, sizeof (struct ocpf_nprop)); ctx->nprop.propType = PT_STRING8; } | kw_PT_UNICODE { memset(&ctx->nprop, 0, sizeof (struct ocpf_nprop)); ctx->nprop.propType = PT_UNICODE; } | kw_PT_SHORT { memset(&ctx->nprop, 0, sizeof (struct ocpf_nprop)); ctx->nprop.propType = PT_SHORT; } | kw_PT_LONG { memset(&ctx->nprop, 0, sizeof (struct ocpf_nprop)); ctx->nprop.propType = PT_LONG; } | kw_PT_DOUBLE { memset(&ctx->nprop, 0, sizeof (struct ocpf_nprop)); ctx->nprop.propType = PT_DOUBLE; } | kw_PT_I8 { memset(&ctx->nprop, 0, sizeof (struct ocpf_nprop)); ctx->nprop.propType = PT_I8; } | kw_PT_BOOLEAN { memset(&ctx->nprop, 0, sizeof (struct ocpf_nprop)); ctx->nprop.propType = PT_BOOLEAN; } | kw_PT_SYSTIME { memset(&ctx->nprop, 0, sizeof (struct ocpf_nprop)); ctx->nprop.propType = PT_SYSTIME; } | kw_PT_MV_LONG { memset(&ctx->nprop, 0, sizeof (struct ocpf_nprop)); ctx->nprop.propType = PT_MV_LONG; } | kw_PT_MV_STRING8 { memset(&ctx->nprop, 0, sizeof (struct ocpf_nprop)); ctx->nprop.propType = PT_MV_STRING8; } | kw_PT_MV_UNICODE { memset(&ctx->nprop, 0, sizeof (struct ocpf_nprop)); ctx->nprop.propType = PT_MV_UNICODE; } | kw_PT_BINARY { memset(&ctx->nprop, 0, sizeof (struct ocpf_nprop)); ctx->nprop.propType = PT_BINARY; } | kw_PT_MV_BINARY { memset(&ctx->nprop, 0, sizeof (struct ocpf_nprop)); ctx->nprop.propType = PT_MV_BINARY; } ; known_kind : kw_MNID_ID COLON INTEGER COLON IDENTIFIER { memset(&ctx->nprop, 0, sizeof (struct ocpf_nprop)); ctx->nprop.registered = true; ctx->nprop.mnid_id = $3; ctx->nprop.guid = $5; } | kw_MNID_STRING COLON STRING COLON IDENTIFIER { memset(&ctx->nprop, 0, sizeof (struct ocpf_nprop)); ctx->nprop.registered = true; ctx->nprop.mnid_string = talloc_strdup(ctx, $3); ctx->nprop.guid = $5; } ; %% void yyerror(struct ocpf_context *ctx, void *scanner, char *s) { printf("%s: %d\n", s, ctx->lineno); fflush(0); } openchange-2.0/libocpf/ocpf_api.c000066400000000000000000000552141223057412600170350ustar00rootroot00000000000000/* OpenChange OCPF (OpenChange Property File) implementation. Copyright (C) Julien Kerihuel 2008-2013. This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see . */ #include #include #include #include "libocpf/ocpf.h" #include "libocpf/ocpf_api.h" #include "libocpf/ocpf_private.h" /** \file ocpf_api.c \brief ocpf Private API */ void ocpf_do_debug(struct ocpf_context *ctx, const char *format, ...) { va_list ap; char *s = NULL; int ret; va_start(ap, format); ret = vasprintf(&s, format, ap); va_end(ap); if (ret == -1) { printf("%s:%d: [Debug dump failure]\n", ctx->filename, ctx->lineno); fflush(0); return; } if (ctx) { printf("%s:%d: %s\n", ctx->filename, ctx->lineno, s); fflush(0); } else { printf("%s\n", s); fflush(0); } free(s); } int ocpf_propvalue_var(struct ocpf_context *ctx, const char *propname, uint32_t proptag, const char *variable, bool unescape, int scope) { struct ocpf_var *vel; struct ocpf_property *element; uint32_t aulPropTag; uint32_t cRows; struct SRow aRow; struct SPropValue lpProps; void *value; int i; if (!ocpf || !ocpf->mem_ctx) return -1; if (!propname && !proptag) return -1; if (propname && proptag) return -1; /* Sanity check: do not insert the same property twice */ if (proptag) { aulPropTag = proptag; } else { aulPropTag = get_proptag_value(propname); } switch (scope) { case kw_PROPERTY: for (element = ctx->props; element->next; element = element->next) { OCPF_RETVAL_IF(element->aulPropTag == aulPropTag, ctx, OCPF_WARN_PROP_REGISTERED, NULL); } for (vel = ctx->vars; vel->next; vel = vel->next) { if (vel->name && !strcmp(vel->name, variable)) { OCPF_RETVAL_IF(vel->propType != (aulPropTag & 0xFFFF), ctx, OCPF_WARN_PROPVALUE_MISMATCH, NULL); element = NULL; element = talloc_zero(ctx->vars, struct ocpf_property); element->aulPropTag = aulPropTag; if (unescape && (((aulPropTag & 0xFFFF) == PT_STRING8) || ((aulPropTag & 0xFFFF) == PT_UNICODE))) { element->value = ocpf_write_unescape_string(ctx, vel->value); } else { element->value = vel->value; } DLIST_ADD(ctx->props, element); return OCPF_SUCCESS; } } break; case kw_RECIPIENT: cRows = ctx->recipients->cRows; aRow = ctx->recipients->aRow[cRows]; for (i = 0; i < aRow.cValues; i++) { OCPF_RETVAL_IF(aRow.lpProps[i].ulPropTag == aulPropTag, ctx, OCPF_WARN_PROP_REGISTERED, NULL); } for (vel = ctx->vars; vel->next; vel = vel->next) { if (vel->name && !strcmp(vel->name, variable)) { OCPF_RETVAL_IF(vel->propType != (aulPropTag & 0xFFFF), ctx, OCPF_WARN_PROPVALUE_MISMATCH, NULL); lpProps.ulPropTag = aulPropTag; lpProps.dwAlignPad = 0; if (unescape && (((aulPropTag & 0xFFFF) == PT_STRING8) || ((aulPropTag & 0xFFFF) == PT_UNICODE))) { value = ocpf_write_unescape_string(ctx, vel->value); } else { value = (void *)vel->value; } set_SPropValue(&lpProps, value); if (!aRow.cValues) { aRow.lpProps = talloc_array((TALLOC_CTX *)ctx->recipients->aRow, struct SPropValue, 2); } else { aRow.lpProps = talloc_realloc(aRow.lpProps, aRow.lpProps, struct SPropValue, aRow.cValues + 2); } aRow.lpProps[aRow.cValues] = lpProps; aRow.cValues += 1; ctx->recipients->aRow[cRows] = aRow; return OCPF_SUCCESS; } } break; default: break; } OCPF_RETVAL_IF(1, ctx, OCPF_WARN_VAR_NOT_REGISTERED, NULL); } int ocpf_set_propvalue(TALLOC_CTX *mem_ctx, struct ocpf_context *ctx, const void **value, uint16_t proptype, uint16_t sproptype, union SPropValue_CTR lpProp, bool unescape) { char *str = NULL; OCPF_RETVAL_IF(proptype != sproptype, ctx, OCPF_WARN_PROPVALUE_MISMATCH, NULL); switch (proptype) { case PT_STRING8: if (unescape) { str = ocpf_write_unescape_string(ctx, lpProp.lpszA); } else { str = talloc_strdup(ctx, lpProp.lpszA); } *value = talloc_memdup(ctx, str, strlen(str) + 1); talloc_free(str); return OCPF_SUCCESS; case PT_UNICODE: if (unescape) { str = ocpf_write_unescape_string(ctx, lpProp.lpszW); } else { str = talloc_strdup(ctx, lpProp.lpszW); } *value = talloc_memdup(ctx, str, strlen(str) + 1); talloc_free(str); return OCPF_SUCCESS; case PT_SHORT: *value = talloc_memdup(ctx, (const void *)&lpProp.i, sizeof (uint16_t)); return OCPF_SUCCESS; case PT_LONG: *value = talloc_memdup(ctx, (const void *)&lpProp.l, sizeof (uint32_t)); return OCPF_SUCCESS; case PT_DOUBLE: *value = talloc_memdup(ctx, (const void *)&lpProp.dbl, sizeof (uint64_t)); return OCPF_SUCCESS; case PT_BOOLEAN: *value = talloc_memdup(ctx, (const void *)&lpProp.b, sizeof (uint8_t)); return OCPF_SUCCESS; case PT_ERROR: *value = talloc_memdup(ctx, (const void *)&lpProp.err, sizeof (uint32_t)); return OCPF_SUCCESS; case PT_I8: *value = talloc_memdup(ctx, (const void *)&lpProp.d, sizeof (uint64_t)); return OCPF_SUCCESS; case PT_SYSTIME: *value = talloc_memdup(ctx, (const void *)&lpProp.ft, sizeof (struct FILETIME)); return OCPF_SUCCESS; case PT_BINARY: *value = (const void *)talloc_zero(ctx, struct Binary_r); ((struct Binary_r *)*value)->cb = lpProp.bin.cb; ((struct Binary_r *)*value)->lpb = talloc_memdup(ctx, (const void *)lpProp.bin.lpb, lpProp.bin.cb); return OCPF_SUCCESS; case PT_MV_LONG: *value = (const void *)talloc_zero(ctx, struct LongArray_r); ((struct LongArray_r *)*value)->cValues = lpProp.MVl.cValues; ((struct LongArray_r *)*value)->lpl = talloc_array(ctx, uint32_t, lpProp.MVl.cValues); { uint32_t i; for (i = 0; i < lpProp.MVl.cValues; i++) { ((struct LongArray_r *)*value)->lpl[i] = lpProp.MVl.lpl[i]; } return OCPF_SUCCESS; } case PT_MV_STRING8: *value = (const void *)talloc_zero(ctx, struct StringArray_r); ((struct StringArray_r *)*value)->cValues = lpProp.MVszA.cValues; ((struct StringArray_r *)*value)->lppszA = talloc_array(ctx, const char *, lpProp.MVszA.cValues); { uint32_t i; for (i = 0; i < lpProp.MVszA.cValues; i++) { if (unescape) { str = ocpf_write_unescape_string(ctx, lpProp.MVszA.lppszA[i]); } else { str = (char *)lpProp.MVszA.lppszA[i]; } ((struct StringArray_r *)*value)->lppszA[i] = talloc_strdup(ctx, str); talloc_free(str); } } return OCPF_SUCCESS; case PT_MV_UNICODE: *value = (const void *)talloc_zero(ctx, struct StringArrayW_r); ((struct StringArrayW_r *)*value)->cValues = lpProp.MVszW.cValues; ((struct StringArrayW_r *)*value)->lppszW = talloc_array(ctx, const char *, lpProp.MVszW.cValues); { uint32_t i; for (i = 0; i < lpProp.MVszW.cValues; i++) { if (unescape) { str = ocpf_write_unescape_string(ctx, lpProp.MVszW.lppszW[i]); } else { str = (char *)lpProp.MVszW.lppszW[i]; } ((struct StringArrayW_r *)*value)->lppszW[i] = talloc_strdup(ctx, str); talloc_free(str); } } return OCPF_SUCCESS; case PT_MV_BINARY: *value = (const void *)talloc_zero(ctx, struct BinaryArray_r); ((struct BinaryArray_r *)*value)->cValues = lpProp.MVbin.cValues; ((struct BinaryArray_r *)*value)->lpbin = talloc_array(ctx, struct Binary_r, lpProp.MVbin.cValues); { uint32_t i; for (i = 0; i < lpProp.MVbin.cValues; i++) { ((struct BinaryArray_r *)*value)->lpbin[i].cb = lpProp.MVbin.lpbin[i].cb; ((struct BinaryArray_r *)*value)->lpbin[i].lpb = talloc_memdup(((struct BinaryArray_r *)*value)->lpbin, lpProp.MVbin.lpbin[i].lpb, lpProp.MVbin.lpbin[i].cb); } } return OCPF_SUCCESS; default: ocpf_do_debug(ctx, "%s (0x%.4x)", OCPF_WARN_PROP_TYPE, proptype); return OCPF_ERROR; } } int ocpf_propvalue_free(union SPropValue_CTR lpProp, uint16_t proptype) { switch (proptype) { case PT_STRING8: talloc_free((char *)lpProp.lpszA); break; case PT_UNICODE: talloc_free((char *)lpProp.lpszW); break; case PT_MV_LONG: talloc_free(lpProp.MVl.lpl); break; case PT_MV_STRING8: talloc_free(lpProp.MVszA.lppszA); break; case PT_MV_UNICODE: talloc_free(lpProp.MVszW.lppszW); break; case PT_MV_BINARY: talloc_free(lpProp.MVbin.lpbin); break; } return OCPF_SUCCESS; } int ocpf_propvalue(struct ocpf_context *ctx, uint32_t aulPropTag, union SPropValue_CTR lpProp, uint16_t proptype, bool unescape, int scope) { struct ocpf_property *element; int ret; uint32_t cRows; struct SRow aRow; struct SPropValue lpProps; void *value; int i; if (!ocpf || !ocpf->mem_ctx) return OCPF_ERROR; if (!ctx) return OCPF_ERROR; switch (scope) { case kw_PROPERTY: /* Sanity check: do not insert the same property twice */ for (element = ctx->props; element->next; element = element->next) { OCPF_RETVAL_IF(element->aulPropTag == aulPropTag, ctx, OCPF_WARN_PROP_REGISTERED, NULL); } element = NULL; element = talloc_zero(ctx->props, struct ocpf_property); if ((aulPropTag & 0xFFFF) == PT_STRING8) { element->aulPropTag = (aulPropTag & 0xFFFF0000) + PT_UNICODE; } else { element->aulPropTag = aulPropTag; } ret = ocpf_set_propvalue((TALLOC_CTX *)element, ctx, &element->value, (uint16_t)aulPropTag & 0xFFFF, proptype, lpProp, unescape); if (ret == -1) { talloc_free(element); return OCPF_ERROR; } DLIST_ADD(ctx->props, element); break; case kw_RECIPIENT: cRows = ctx->recipients->cRows; aRow = ctx->recipients->aRow[cRows]; for (i = 0; i < aRow.cValues; i++) { OCPF_RETVAL_IF(aRow.lpProps[i].ulPropTag == aulPropTag, ctx, OCPF_WARN_PROP_REGISTERED, NULL); } lpProps.ulPropTag = aulPropTag; ret = ocpf_set_propvalue((TALLOC_CTX *)ctx->recipients->aRow, ctx, (const void **)&value, (uint16_t)aulPropTag & 0xFFFF, proptype, lpProp, unescape); if (ret == -1) { return OCPF_ERROR; } set_SPropValue(&lpProps, value); if (!aRow.cValues) { aRow.lpProps = talloc_array((TALLOC_CTX *)ctx->recipients->aRow, struct SPropValue, 2); } else { aRow.lpProps = talloc_realloc(aRow.lpProps, aRow.lpProps, struct SPropValue, aRow.cValues + 2); } aRow.lpProps[aRow.cValues] = lpProps; aRow.cValues += 1; ctx->recipients->aRow[cRows] = aRow; break; default: break; } return OCPF_SUCCESS; } int ocpf_new_recipient(struct ocpf_context *ctx) { uint32_t cRows; if (!ocpf || !ocpf->mem_ctx) return OCPF_ERROR; if (!ctx->recipients || !ctx->recipients->aRow) return OCPF_ERROR; ctx->recipients->cRows += 1; cRows = ctx->recipients->cRows; ctx->recipients->aRow = talloc_realloc(ctx->recipients->aRow, ctx->recipients->aRow, struct SRow, cRows + 2); ctx->recipients->aRow[cRows].ulAdrEntryPad = 0; ctx->recipients->aRow[cRows].lpProps = NULL; ctx->recipients->aRow[cRows].cValues = 0; return OCPF_SUCCESS; } int ocpf_recipient_set_class(struct ocpf_context *ctx, enum ulRecipClass class) { struct SPropValue lpProps; uint32_t cRows; struct SRow aRow; int i; if (!ocpf || !ocpf->mem_ctx) return OCPF_ERROR; if (!ctx->recipients || !ctx->recipients->aRow) return OCPF_ERROR; cRows = ctx->recipients->cRows; aRow = ctx->recipients->aRow[cRows]; /* Check if PidTagRecipientType has not been declared as a block property */ for (i = 0; i < aRow.cValues; i++) { if (aRow.lpProps[i].ulPropTag == PidTagRecipientType) { if (aRow.lpProps[i].value.l == class) { return OCPF_SUCCESS; } else { OCPF_RETVAL_IF(1, ctx, OCPF_WARN_PROP_REGISTERED, NULL); } } } lpProps.ulPropTag = PidTagRecipientType; lpProps.dwAlignPad = 0; set_SPropValue(&lpProps, (void *)&class); if (!aRow.cValues) { aRow.lpProps = talloc_array((TALLOC_CTX *)ctx->recipients->aRow, struct SPropValue, 2); } else { aRow.lpProps = talloc_realloc(aRow.lpProps, aRow.lpProps, struct SPropValue, aRow.cValues + 2); } aRow.lpProps[aRow.cValues] = lpProps; aRow.cValues += 1; ctx->recipients->aRow[cRows] = aRow; return OCPF_SUCCESS; } void ocpf_propvalue_s(struct ocpf_context *ctx, const char *propname, union SPropValue_CTR lpProp, uint16_t proptype, bool unescape, int scope) { uint32_t aulPropTag; aulPropTag = get_proptag_value(propname); ocpf_propvalue(ctx, aulPropTag, lpProp, proptype, unescape, scope); } /** \details Add a named property This function adds either a custom or a known named property and supplies either the lpProp value or substitute with registered variable. \param nprop pointer on a ocpf named property entry \param lpProp named property value \param var_name variable name \param proptype variable property type \param unescape whether the property value should be escaped \return OCPF_SUCCESS on success, otherwise OCPF_ERROR. */ int ocpf_nproperty_add(struct ocpf_context *ctx, struct ocpf_nprop *nprop, union SPropValue_CTR lpProp, const char *var_name, uint16_t proptype, bool unescape) { enum MAPISTATUS retval; int ret = 0; struct ocpf_nproperty *element; struct ocpf_nproperty *el; struct ocpf_var *vel; if (!ocpf || !ocpf->mem_ctx) return -1; element = talloc_zero(ctx, struct ocpf_nproperty); if (nprop->guid) { ret = ocpf_oleguid_check(ctx, nprop->guid, &element->oleguid); OCPF_RETVAL_IF(ret == -1, ctx, OCPF_WARN_OLEGUID_UNREGISTERED, element); } if (nprop->OOM) { /* * Sanity check: do not insert twice the same * (OOM,oleguid) couple */ for (el = ctx->nprops; el->next; el = el->next) { OCPF_RETVAL_IF((el->OOM && !strcmp(el->OOM, nprop->OOM)) && (el->oleguid && nprop->guid && !strcmp(el->oleguid, nprop->guid)), ctx, OCPF_WARN_OOM_REGISTERED, element); } element->kind = OCPF_OOM; element->OOM = nprop->OOM; retval = mapi_nameid_OOM_lookup(element->OOM, element->oleguid, &element->propType); OCPF_RETVAL_IF(retval != MAPI_E_SUCCESS, ctx, OCPF_WARN_OOM_UNKNOWN, element); } else if (nprop->mnid_string) { /* * Sanity check: do not insert twice the same * (mnid_string,oleguid) couple */ for (el = ctx->nprops; el->next; el = el->next) { OCPF_RETVAL_IF((el->mnid_string && !strcmp(el->mnid_string, nprop->mnid_string)) && (el->oleguid && nprop->guid && !strcmp(el->oleguid, nprop->guid)), ctx, OCPF_WARN_STRING_REGISTERED, element); } element->kind = OCPF_MNID_STRING; element->mnid_string = nprop->mnid_string; if (nprop->registered == true) { retval = mapi_nameid_string_lookup(element->mnid_string, element->oleguid, &element->propType); OCPF_RETVAL_IF(retval != MAPI_E_SUCCESS, ctx, OCPF_WARN_STRING_UNKNOWN, element); } else { element->propType = nprop->propType; } } else if (nprop->mnid_id) { /* * Sanity check: do not insert twice the same * (mnid_id-oleguid) couple */ for (el = ctx->nprops; el->next; el = el->next) { OCPF_RETVAL_IF((el->mnid_id == nprop->mnid_id) && (el->oleguid && nprop->guid && !strcmp(el->oleguid, nprop->guid)), ctx, OCPF_WARN_LID_REGISTERED, element); } element->kind = OCPF_MNID_ID; element->mnid_id = nprop->mnid_id; if (nprop->registered == true) { retval = mapi_nameid_lid_lookup(element->mnid_id, element->oleguid, &element->propType); OCPF_RETVAL_IF(retval != MAPI_E_SUCCESS, ctx, OCPF_WARN_LID_UNKNOWN, element); } else { element->propType = nprop->propType; } } if (var_name) { for (vel = ctx->vars; vel->next; vel = vel->next) { if (vel->name && !strcmp(vel->name, var_name)) { OCPF_RETVAL_IF(element->propType != vel->propType, ctx, OCPF_WARN_PROPVALUE_MISMATCH, element); element->value = vel->value; } } OCPF_RETVAL_IF(!element->value, ctx, OCPF_WARN_VAR_NOT_REGISTERED, element); } else { ret = ocpf_set_propvalue((TALLOC_CTX *)element, ctx, &element->value, element->propType, proptype, lpProp, unescape); if (ret == -1) { talloc_free(element); return OCPF_ERROR; } } DLIST_ADD(ctx->nprops, element); return OCPF_SUCCESS; } /** \details Register OCPF message type Register OCPF message type \param type message type to register \return OCPF_SUCCESS on success, otherwise OCPF_ERROR */ int ocpf_type_add(struct ocpf_context *ctx, const char *type) { if (!ocpf || !ocpf->mem_ctx || !type) return OCPF_ERROR; if (ctx->type) { talloc_free((void *)ctx->type); ctx->type = NULL; } ctx->type = talloc_strdup(ctx, type); return OCPF_SUCCESS; } /* WARNING: This array doesn't hold all possible values */ static struct ocpf_olfolder olfolders[] = { { olFolderTopInformationStore, "olFolderTopInformationStore" }, { olFolderDeletedItems, "olFolderDeletedItems" }, { olFolderOutbox, "olFolderOutbox" }, { olFolderSentMail, "olFolderSentMail" }, { olFolderInbox, "olFolderInbox" }, { olFolderCommonView, "olFolderCommonView" }, { olFolderCalendar, "olFolderCalendar" }, { olFolderContacts, "olFolderContacts" }, { olFolderJournal, "olFolderJournal" }, { olFolderNotes, "olFolderNotes" }, { olFolderTasks, "olFolderTasks" }, { 0, NULL } }; static int ocpf_folder_name_to_id(const char *name, uint64_t *id) { uint32_t i; if (!name) return OCPF_ERROR; for (i = 0; olfolders[i].name; i++) { if (olfolders[i].name && !strcmp(olfolders[i].name, name)) { *id = olfolders[i].id; return OCPF_SUCCESS; } } /* not found */ return OCPF_ERROR; } /** \details Register OCPF folder Register the folder where the OCPF message needs to be saved \param name the name of the default folder if specified \param id the folder id of the message if specified \param var_name the substitution variable to use for folder ID if specified \return OCPF_SUCCESS on success, otherwise OCPF_ERROR */ int ocpf_folder_add(struct ocpf_context *ctx, const char *name, uint64_t id, const char *var_name) { struct ocpf_var *element; /* Sanity check */ if ((name && id) || (name && var_name) || (id && var_name)) return OCPF_ERROR; if (!name && !id && !var_name) return OCPF_ERROR; if (name) { int res = ocpf_folder_name_to_id(name, &(ctx->folder)); OCPF_RETVAL_IF(res == OCPF_ERROR, ctx, OCPF_WARN_FOLDER_ID_UNKNOWN, NULL); } else if (id) { ctx->folder = id; } else if (var_name) { for (element = ctx->vars; element->next; element = element->next) { if (element->name && !strcmp(element->name, var_name)) { /* WARNING: we assume var data is double */ ctx->folder = *((uint64_t *)element->value); } } } return OCPF_SUCCESS; } /** \details Register new OLEGUID in ocpf context This function registers a OLEGUID couple name, value in ocpf. \param name the OLEGUID name \param oleguid the guid string value \return OCPF_SUCCESS on success, otherwise OCPF_ERROR */ int ocpf_oleguid_add(struct ocpf_context *ctx, const char *name, const char *oleguid) { NTSTATUS status; struct ocpf_oleguid *element; struct GUID guid; /* Sanity checks */ if (!ocpf || !ocpf->mem_ctx) return OCPF_ERROR; if (!name) return OCPF_ERROR; /* Sanity check: Do not insert twice the same name or guid */ for (element = ctx->oleguid; element->next; element = element->next) { OCPF_RETVAL_IF(element->name && !strcmp(element->name, name), ctx, OCPF_WARN_OLEGUID_N_REGISTERED, NULL); OCPF_RETVAL_IF(element->guid && !strcmp(element->guid, oleguid), ctx, OCPF_WARN_OLEGUID_G_REGISTERED, NULL); } element = talloc_zero(ctx->oleguid, struct ocpf_oleguid); status = GUID_from_string(oleguid, &guid); OCPF_RETVAL_IF(!NT_STATUS_IS_OK(status), ctx, OCPF_WARN_OLEGUID_INVALID, element); element->name = talloc_strdup(element, name); element->guid = talloc_strdup(element, oleguid); DLIST_ADD(ctx->oleguid, element); return OCPF_SUCCESS; } /** \details Check if the given OLEGUID has been registered \param name the OLEGUID to check \param guid pointer on pointer to the guid result \result OCPF_SUCCESS on success, otherwise OCPF_ERROR; */ int ocpf_oleguid_check(struct ocpf_context *ctx, const char *name, const char **guid) { struct ocpf_oleguid *element; for (element = ctx->oleguid; element->next; element = element->next) { if (element->name && !strcmp(element->name, name)) { *guid = element->guid; return OCPF_SUCCESS; } } return OCPF_ERROR; } /** \details convert a string to FILETIME structure This function converts a string - representing a date under the following format "Tyyy-mm-dd hh:mm:ss" - into a FILETIME structure. \param date the date to convert \param ft pointer on the converted date \return OCPF_SUCCESS on success, otherwise OCPF_ERROR */ int ocpf_add_filetime(const char *date, struct FILETIME *ft) { NTTIME nt; struct tm tm; memset(&tm, 0, sizeof(struct tm)); if (!strptime(date, DATE_FORMAT, &tm)) { printf("Invalid data format: Tyyy-mm-dd hh:mm:ss (e.g.: T2008-03-06 23:30:00"); return OCPF_ERROR; } unix_to_nt_time(&nt, mktime(&tm)); ft->dwLowDateTime = (nt << 32) >> 32; ft->dwHighDateTime = (nt >> 32); return OCPF_SUCCESS; } int ocpf_variable_add(struct ocpf_context *ctx, const char *name, union SPropValue_CTR lpProp, uint16_t propType, bool unescape) { struct ocpf_var *element; int ret; if (!ocpf || !ocpf->mem_ctx) return OCPF_ERROR; if (!name) return OCPF_ERROR; /* Sanity check: Do not insert twice the same variable */ for (element = ctx->vars; element->next; element = element->next) { OCPF_RETVAL_IF(element->name && !strcmp(element->name, name), ctx, OCPF_WARN_VAR_REGISTERED, NULL); } element = talloc_zero(ctx->vars, struct ocpf_var); element->name = talloc_strdup((TALLOC_CTX *)element, name); element->propType = propType; ret = ocpf_set_propvalue((TALLOC_CTX *)element, ctx, &element->value, propType, propType, lpProp, unescape); OCPF_RETVAL_IF(ret == -1, ctx, OCPF_WARN_VAR_TYPE, element); DLIST_ADD(ctx->vars, element); return OCPF_SUCCESS; } int ocpf_binary_add(struct ocpf_context *ctx, const char *filename, struct Binary_r *bin) { int fd; int ret; struct stat sb; fd = open(filename, O_RDONLY); OCPF_RETVAL_IF(fd == -1, ctx, OCPF_WARN_FILENAME_INVALID, NULL); ret = fstat(fd, &sb); if (ret == -1) { ocpf_do_debug(ctx, "%s", OCPF_WARN_FILENAME_STAT); close(fd); return OCPF_ERROR; } bin->lpb = talloc_size(ctx, sb.st_size); bin->cb = read(fd, bin->lpb, sb.st_size); close(fd); return OCPF_SUCCESS; } openchange-2.0/libocpf/ocpf_api.h000066400000000000000000000123351223057412600170370ustar00rootroot00000000000000/* OpenChange OCPF (OpenChange Property File) implementation. Copyright (C) Julien Kerihuel 2008-2010. This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see . */ #ifndef __OCPF_API_H_ #define __OCPF_API_H_ #include "libmapi/libmapi.h" struct ocpf_var { struct ocpf_var *prev; struct ocpf_var *next; const char *name; const void *value; uint16_t propType; }; struct ocpf_oleguid { struct ocpf_oleguid *prev; struct ocpf_oleguid *next; const char *name; const char *guid; }; struct ocpf_property { struct ocpf_property *prev; struct ocpf_property *next; uint32_t aulPropTag; const void *value; }; struct ocpf_nprop { const char *OOM; const char *mnid_string; uint16_t mnid_id; uint16_t propType; const char *guid; bool registered; }; enum ocpf_ntype { OCPF_OOM = 0x1, OCPF_MNID_ID, OCPF_MNID_STRING }; struct ocpf_nproperty { struct ocpf_nproperty *prev; struct ocpf_nproperty *next; enum ocpf_ntype kind; const char *OOM; const char *mnid_string; uint16_t mnid_id; uint16_t propType; const char *oleguid; const void *value; }; struct ocpf_olfolder { int id; const char *name; }; struct ocpf_context { /* lexer internal data */ int typeset; bool folderset; uint8_t recip_type; uint16_t ltype; union SPropValue_CTR lpProp; struct Binary_r bin; struct ocpf_nprop nprop; unsigned int lineno; int result; /* ocpf */ const char *type; struct ocpf_var *vars; struct ocpf_oleguid *oleguid; struct ocpf_property *props; struct ocpf_nproperty *nprops; struct SRowSet *recipients; struct SPropValue *lpProps; uint32_t cValues; uint64_t folder; /* context */ FILE *fp; const char *filename; uint32_t ref_count; uint32_t context_id; uint8_t flags; struct ocpf_context *prev; struct ocpf_context *next; }; struct ocpf_freeid { uint32_t context_id; struct ocpf_freeid *prev; struct ocpf_freeid *next; }; struct ocpf { TALLOC_CTX *mem_ctx; struct ocpf_context *context; struct ocpf_freeid *free_id; uint32_t last_id; }; #include "libocpf/ocpf_private.h" /** * Defines */ #define OCPF_WARN(c,x) (ocpf_do_debug(c, x)) #define OCPF_RETVAL_IF(x, c, msg, mem_ctx) \ do { \ if (x) { \ ocpf_do_debug(c, "%s", msg); \ if (mem_ctx) { \ talloc_free(mem_ctx); \ } \ return OCPF_ERROR; \ } \ } while (0); #define OCPF_RETVAL_TYPE(x, c, msg, t, mem_ctx) \ do { \ if (x) { \ ocpf_do_debug(c, "%s", msg); \ if (mem_ctx) { \ talloc_free(mem_ctx); \ } \ return t; \ } \ } while (0); #define OCPF_INITIALIZED "OCPF context has already been initialized" #define OCPF_NOT_INITIALIZED "OCPF context has not been initialized" #define OCPF_INVALID_CONTEXT "Invalid OCPF context" #define OCPF_WRITE_NOT_INITIALIZED "OCPF write context has not been initialized" #define OCPF_FATAL_ERROR "Fatal error encountered" #define OCPF_WARN_FILENAME_INVALID "Invalid filename" #define OCPF_WARN_FILENAME_EXIST "filename already exists" #define OCPF_WARN_FILENAME_STAT "Unable to stat file" #define OCPF_WARN_PROP_REGISTERED "Property already registered" #define OCPF_WARN_PROP_TYPE "Property type not supported" #define OCPF_WARN_PROP_UNKNOWN "Property Unknown" #define OCPF_WARN_OOM_UNKNOWN "Unknown OOM" #define OCPF_WARN_OOM_REGISTERED "OOM already registered" #define OCPF_WARN_LID_UNKNOWN "Unknown MNID_ID" #define OCPF_WARN_LID_REGISTERED "MNID_ID already registered" #define OCPF_WARN_STRING_UNKNOWN "Unknown MNID_STRING" #define OCPF_WARN_STRING_REGISTERED "MNID_STRING already registered" #define OCPF_WARN_OLEGUID_N_REGISTERED "OLEGUID name already registered" #define OCPF_WARN_OLEGUID_G_REGISTERED "OLEGUID GUID already registered" #define OCPF_WARN_OLEGUID_UNREGISTERED "OLEGUID unregistered" #define OCPF_WARN_OLEGUID_INVALID "OLEGUID invalid" #define OCPF_WARN_VAR_REGISTERED "Variable already registered" #define OCPF_WARN_VAR_NOT_REGISTERED "Unknown variable" #define OCPF_WARN_VAR_TYPE "Variable property type not supported" #define OCPF_WARN_FOLDER_ID_UNKNOWN "Unknown Folder" #define OCPF_WARN_PROPVALUE_MISMATCH "Property type and value mismatch" #define OCPF_INVALID_PROPARRAY "Invalid property array" #define OCPF_INVALID_FILEHANDLE "Invalid file handle" #define OCPF_INVALID_RECIPIENTS "Invalid recipients" #define OCPF_PROPERTY_BEGIN "PROPERTY {\n" #define OCPF_NPROPERTY_BEGIN "NPROPERTY {\n" #define OCPF_END "};\n" #define OCPF_NEWLINE "\n" #define OCPF_RECIPIENT_BEGIN "RECIPIENT {\n" #define OCPF_RECIPIENT_TO "TO {\n" #define OCPF_RECIPIENT_CC "CC {\n" #define OCPF_RECIPIENT_BCC "BCC {\n" #define DATE_FORMAT "%Y-%m-%d %H:%M:%S" #endif /* __OCPF_API_H_ */ openchange-2.0/libocpf/ocpf_bison.supp000066400000000000000000000003661223057412600201410ustar00rootroot00000000000000{ ocpf_bison1 Memcheck:Addr1 fun:__GI_strlen fun:talloc_strdup ... fun:ocpf_yyparse fun:ocpf_parse } { ocpf_bison2 Memcheck:Addr1 fun:memcpy fun:__talloc_strlendup ... fun:ocpf_yyparse fun:ocpf_parse } openchange-2.0/libocpf/ocpf_context.c000066400000000000000000000161111223057412600177410ustar00rootroot00000000000000/* OpenChange OCPF (OpenChange Property File) implementation. Copyright (C) Julien Kerihuel 2010. This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see . */ /** \file ocpf_context.c \brief OCPF context API */ #include #include "libocpf/ocpf.h" #include "libocpf/ocpf_api.h" #include /** \details Initialize a new OCPF context \param mem_ctx pointer to the memory context \param filename the OCPF filename used for this context \param flags Flags controlling how the OCPF should be opened \param context_id the identifier representing the context \param context_id the context identifier to use for this context \return new allocated OCPF context on success, otherwise NULL */ struct ocpf_context *ocpf_context_init(TALLOC_CTX *mem_ctx, const char *filename, uint8_t flags, uint32_t context_id) { struct ocpf_context *ctx; struct stat sb; OCPF_RETVAL_TYPE(!mem_ctx, NULL, OCPF_NOT_INITIALIZED, NULL, NULL); OCPF_RETVAL_TYPE(!context_id, NULL, OCPF_INVALID_CONTEXT, NULL, NULL); OCPF_RETVAL_TYPE(!filename, NULL, OCPF_WARN_FILENAME_INVALID, NULL, NULL); switch (flags) { case OCPF_FLAGS_RDWR: case OCPF_FLAGS_READ: case OCPF_FLAGS_WRITE: OCPF_RETVAL_TYPE((stat(filename, &sb) == -1), NULL, OCPF_WARN_FILENAME_INVALID, NULL, NULL) break; case OCPF_FLAGS_CREATE: OCPF_RETVAL_TYPE(!(stat(filename, &sb)), NULL, OCPF_WARN_FILENAME_EXIST, NULL, NULL); break; } /* Initialize the context */ ctx = talloc_zero(mem_ctx, struct ocpf_context); /* Initialize ocpf context parameters */ ctx->vars = talloc_zero(ctx, struct ocpf_var); ctx->oleguid = talloc_zero(ctx, struct ocpf_oleguid); ctx->props = talloc_zero(ctx, struct ocpf_property); ctx->nprops = talloc_zero(ctx, struct ocpf_nproperty); ctx->recipients = talloc_zero(ctx, struct SRowSet); ctx->recipients->aRow = talloc_array(ctx->recipients, struct SRow, 2); ctx->recipients->aRow[0].lpProps = talloc_array(ctx->recipients->aRow, struct SPropValue, 2); ctx->recipients->cRows = 0; ctx->lpProps = NULL; ctx->cValues = 0; ctx->folder = 0; /* Initialize ocpf internal context parameters */ ctx->flags = flags; ctx->filename = talloc_strdup(ctx, filename); ctx->ref_count = 0; ctx->context_id = context_id; /* Initialize lexer parameters */ ctx->lineno = 1; ctx->typeset = 0; ctx->folderset = false; ctx->recip_type = 0; ctx->type = NULL; switch (flags) { case OCPF_FLAGS_RDWR: ctx->fp = fopen(filename, "r+"); break; case OCPF_FLAGS_READ: ctx->fp = fopen(filename, "r"); break; case OCPF_FLAGS_WRITE: ctx->fp = fopen(filename, "w"); break; case OCPF_FLAGS_CREATE: /* defer fopen to ocpf_write_commit */ ctx->fp = NULL; break; } OCPF_RETVAL_TYPE(!ctx->fp && flags != OCPF_FLAGS_CREATE, NULL, OCPF_WARN_FILENAME_INVALID, NULL, ctx); return ctx; } /** \details Add an OCPF context to the list \param ocpf_ctx pointer to the global ocpf context \param filename pointer to the \param context_id pointer to the context_id the function returns \param flags Flags controlling how the OCPF should be opened \param existing boolean returned by the function to specify if the context was already existing or not \return valid ocpf context pointer on success, otherwise NULL */ struct ocpf_context *ocpf_context_add(struct ocpf *ocpf_ctx, const char *filename, uint32_t *context_id, uint8_t flags, bool *existing) { struct ocpf_context *el; struct ocpf_freeid *elf; bool found = false; /* Sanity checks */ if (!ocpf_ctx) return NULL; if (!filename) return NULL; if (!context_id) return NULL; /* Search for an existing context */ for (el = ocpf_ctx->context; el; el = el->next) { if (el->filename && !strcmp(el->filename, filename)) { *context_id = el->context_id; el->ref_count += 1; *existing = true; return el; } } /* Search for an available free context_id, otherwise generate one */ for (elf = ocpf_ctx->free_id; elf; elf = elf->next) { if (elf && elf->context_id) { found = true; break; } } if (found == true) { *context_id = elf->context_id; DLIST_REMOVE(ocpf_ctx->free_id, elf); talloc_free(elf); } else { *context_id = ocpf_ctx->last_id; ocpf_ctx->last_id += 1; } /* Initialize the new context */ *existing = false; el = ocpf_context_init(ocpf_ctx->mem_ctx, filename, flags, *context_id); /* handle the case where file couldn't be opened */ return el; } /** \details Delete an OCPF context \param ocpf_ctx pointer to the global ocpf context \param ctx pointer to the OCPF context to delete \return 0 on success, 1 if there were still a ref_count, otherwise -1 on errors. */ int ocpf_context_delete(struct ocpf *ocpf_ctx, struct ocpf_context *ctx) { struct ocpf_freeid *el; uint32_t context_id; /* Sanity checks */ if (!ocpf_ctx) return -1; if (!ctx) return -1; /* If we still have a reference counter, do nothing */ if (ctx->ref_count) { ctx->ref_count -= 1; return 1; } /* Close the file */ if (ctx->fp) { fclose(ctx->fp); } /* Remove the context from the list and free it */ context_id = ctx->context_id; DLIST_REMOVE(ocpf_ctx->context, ctx); talloc_free(ctx); /* Add the context identifier to the free list */ el = talloc_zero(ocpf_ctx->mem_ctx, struct ocpf_freeid); el->context_id = context_id; DLIST_ADD_END(ocpf_ctx->free_id, el, struct ocpf_freeid *); return 0; } /** \details Search a context given its filename \param ctx pointer to the ocpf context list \param filename the filename to use for search \return pointer to valid ocpf context on success, otherwise NULL */ struct ocpf_context *ocpf_context_search_by_filename(struct ocpf_context *ctx, const char *filename) { struct ocpf_context *el; /* Sanity checks */ if (!ctx) return NULL; if (!filename) return NULL; for (el = ctx; el; el = el->next) { if (el->filename && !strcmp(el->filename, filename)) { return el; } } return NULL; } /** \details Search a context given its context identifier \param ctx pointer to the ocpf context list \param context_id the context identifier to use for search \return pointer to valid ocpf context on success, otherwise NULL */ struct ocpf_context *ocpf_context_search_by_context_id(struct ocpf_context *ctx, uint32_t context_id) { struct ocpf_context *el; /* Sanity checks */ if (!ctx) return NULL; if (!context_id) return NULL; for (el = ctx; el; el = el->next) { if (el->context_id == context_id) { return el; } } return NULL; } openchange-2.0/libocpf/ocpf_dump.c000066400000000000000000000132321223057412600172230ustar00rootroot00000000000000/* OpenChange OCPF (OpenChange Property File) implementation. Copyright (C) Julien Kerihuel 2008-2011. This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see . */ #include "libocpf/ocpf.h" #include "libocpf/ocpf_api.h" #include "libocpf/ocpf_dump.h" /** \file ocpf_dump.c \brief ocpf Dump API */ static void ocpf_do_dump(const char *format, ...) { va_list ap; char *s = NULL; int ret; va_start(ap, format); ret = vasprintf(&s, format, ap); va_end(ap); if (ret == -1) { printf("[Dump failure]\n"); } else { printf("%s\n", s); } free(s); } /** \details Dump OCPF Type Dump OCPF Registered Type */ _PUBLIC_ void ocpf_dump_type(uint32_t context_id) { struct ocpf_context *ctx; ctx = ocpf_context_search_by_context_id(ocpf->context, context_id); if (!ctx) return; OCPF_DUMP_TITLE(indent, "TYPE", OCPF_DUMP_TOPLEVEL); indent++; INDENT(); OCPF_DUMP(("* %s", ctx->type ? ctx->type : "Undefined")); indent--; } /** \details Dump OCPF Destination Folder Dump OCPF Registered Destination Folder */ _PUBLIC_ void ocpf_dump_folder(uint32_t context_id) { struct ocpf_context *ctx; ctx = ocpf_context_search_by_context_id(ocpf->context, context_id); if (!ctx) return; OCPF_DUMP_TITLE(indent, "FOLDER", OCPF_DUMP_TOPLEVEL); indent++; INDENT(); OCPF_DUMP(("* 0x%llx", ctx->folder ? ctx->folder : 0xFFFFFFFF)); indent--; } /** \details Dump OCPF Recipients Dump OCPF Recipients */ _PUBLIC_ void ocpf_dump_recipients(uint32_t context_id) { struct ocpf_context *ctx; uint32_t i; struct SPropValue *lpProps; uint32_t *RecipClass; ctx = ocpf_context_search_by_context_id(ocpf->context, context_id); if (!ctx) return; OCPF_DUMP_TITLE(indent, "RECIPIENTS", OCPF_DUMP_TOPLEVEL); indent++; for (i = 0; i < ctx->recipients->cRows; i++) { lpProps = get_SPropValue_SRow(&(ctx->recipients->aRow[i]), PidTagRecipientType); if (lpProps) { RecipClass = (uint32_t *)get_SPropValue_data(lpProps); if (RecipClass) { switch (*RecipClass) { case MAPI_TO: OCPF_DUMP_TITLE(indent, "TO", OCPF_DUMP_SUBLEVEL); break; case MAPI_CC: OCPF_DUMP_TITLE(indent, "CC", OCPF_DUMP_SUBLEVEL); break; case MAPI_BCC: OCPF_DUMP_TITLE(indent, "BCC", OCPF_DUMP_SUBLEVEL); break; } mapidump_SRow(&ctx->recipients->aRow[i], "\t * "); } } } indent--; printf("\n"); } /** \details Dump OCPF OLEGUID Dump OCPF Registered OLEGUID */ _PUBLIC_ void ocpf_dump_oleguid(uint32_t context_id) { struct ocpf_context *ctx; struct ocpf_oleguid *element; ctx = ocpf_context_search_by_context_id(ocpf->context, context_id); if (!ctx) return; OCPF_DUMP_TITLE(indent, "OLEGUID", OCPF_DUMP_TOPLEVEL); indent++; for (element = ctx->oleguid; element->next; element = element->next) { INDENT(); printf("%-25s: %s\n", element->name, element->guid); } indent--; } _PUBLIC_ void ocpf_dump_variable(uint32_t context_id) { struct ocpf_context *ctx; struct ocpf_var *element; ctx = ocpf_context_search_by_context_id(ocpf->context, context_id); if (!ctx) return; OCPF_DUMP_TITLE(indent, "VARIABLE", OCPF_DUMP_TOPLEVEL); indent++; for (element = ctx->vars; element->next; element = element->next) { INDENT(); printf("%s\n", element->name); } indent--; } _PUBLIC_ void ocpf_dump_property(uint32_t context_id) { struct ocpf_context *ctx; struct ocpf_property *element; const char *proptag; ctx = ocpf_context_search_by_context_id(ocpf->context, context_id); if (!ctx) return; OCPF_DUMP_TITLE(indent, "PROPERTIES", OCPF_DUMP_TOPLEVEL); indent++; for (element = ctx->props; element->next; element = element->next) { INDENT(); proptag = (const char *)get_proptag_name(element->aulPropTag); printf("0x%.8x = %s\n", element->aulPropTag, (char *)(proptag ? proptag : "UNKNOWN")); } indent--; } _PUBLIC_ void ocpf_dump_named_property(uint32_t context_id) { struct ocpf_context *ctx; struct ocpf_nproperty *element; ctx = ocpf_context_search_by_context_id(ocpf->context, context_id); if (!ctx) return; OCPF_DUMP_TITLE(indent, "NAMED PROPERTIES", OCPF_DUMP_TOPLEVEL); indent++; OCPF_DUMP_TITLE(indent, "OOM", OCPF_DUMP_SUBLEVEL); indent++; for (element = ctx->nprops; element->next; element = element->next) { if (element->kind == OCPF_OOM) { INDENT(); printf("* %s\n", element->OOM); } } indent--; OCPF_DUMP_TITLE(indent, "MNID_ID", OCPF_DUMP_SUBLEVEL); indent++; for (element = ctx->nprops; element->next; element = element->next) { if (element->kind == OCPF_MNID_ID) { INDENT(); printf("* 0x%.4x\n", element->mnid_id); } } indent--; OCPF_DUMP_TITLE(indent, "MNID_STRING", OCPF_DUMP_SUBLEVEL); indent++; for (element = ctx->nprops; element->next; element = element->next) { if (element->kind == OCPF_MNID_STRING) { INDENT(); printf("* %s\n", element->mnid_string); } } indent--; indent--; } _PUBLIC_ void ocpf_dump(uint32_t context_id) { indent = 0; ocpf_dump_type(context_id); ocpf_dump_folder(context_id); ocpf_dump_oleguid(context_id); ocpf_dump_recipients(context_id); ocpf_dump_variable(context_id); ocpf_dump_property(context_id); ocpf_dump_named_property(context_id); } openchange-2.0/libocpf/ocpf_dump.h000066400000000000000000000026631223057412600172360ustar00rootroot00000000000000/* OpenChange OCPF (OpenChange Property File) implementation. Copyright (C) Julien Kerihuel 2008. This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see . */ #ifndef __OCPF_DUMP_H_ #define __OCPF_DUMP_H_ #define INDENT() \ do { \ uint32_t i; \ \ for (i = 0; i < indent; i++) { \ printf("\t"); \ } \ } while (0); #define OCPF_DUMP(x) (ocpf_do_dump x) #define OCPF_DUMP_TITLE(indent, txt, type) \ do { \ size_t odt_i; \ size_t txt_len; \ \ printf("\n"); \ INDENT(); \ printf("%s:\n", txt); \ \ INDENT(); \ txt_len = strlen(txt) + 1; \ for (odt_i = 0; odt_i < txt_len; odt_i++) { \ printf("%c", type ? '-' : '='); \ } \ printf("\n"); \ } while (0); #define OCPF_DUMP_TOPLEVEL 0 #define OCPF_DUMP_SUBLEVEL 1 unsigned int indent; #endif /* ! __OCPF_DUMP_H_ */ openchange-2.0/libocpf/ocpf_private.h000066400000000000000000000065771223057412600177530ustar00rootroot00000000000000/* OpenChange OCPF (OpenChange Property File) implementation. Copyright (C) Julien Kerihuel 2009. This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see . */ #ifndef __OCPF_PRIVATE_H_ #define __OCPF_PRIVATE_H_ #include "config.h" #include #include #ifndef HAVE_COMPARISON_FN_T #define HAVE_COMPARISON_FN_T typedef int (*comparison_fn_t)(const void *, const void *); #else # ifndef comparison_fn_t typedef __compar_fn_t comparison_fn_t; # endif #endif #undef _PRINTF_ATTRIBUTE #define _PRINTF_ATTRIBUTE(a1, a2) PRINTF_ATTRIBUTE(a1, a2) #ifndef __BEGIN_DECLS #ifdef __cplusplus #define __BEGIN_DECLS extern "C" { #define __END_DECLS } #else #define __BEGIN_DECLS #define __END_DECLS #endif #endif __BEGIN_DECLS /* The following private definitions from from libocpf/ocpf_api.c */ void ocpf_do_debug(struct ocpf_context *, const char *, ...); int ocpf_propvalue_var(struct ocpf_context *, const char *, uint32_t, const char *, bool, int); int ocpf_set_propvalue(TALLOC_CTX *, struct ocpf_context *, const void **, uint16_t, uint16_t, union SPropValue_CTR, bool); int ocpf_propvalue_free(union SPropValue_CTR, uint16_t); int ocpf_propvalue(struct ocpf_context *, uint32_t, union SPropValue_CTR, uint16_t, bool, int); void ocpf_propvalue_s(struct ocpf_context *, const char *, union SPropValue_CTR, uint16_t, bool, int); int ocpf_new_recipient(struct ocpf_context *); int ocpf_recipient_set_class(struct ocpf_context *, enum ulRecipClass); int ocpf_nproperty_add(struct ocpf_context *, struct ocpf_nprop *, union SPropValue_CTR, const char *, uint16_t, bool); int ocpf_type_add(struct ocpf_context *, const char *); int ocpf_folder_add(struct ocpf_context *, const char *, uint64_t, const char *); int ocpf_oleguid_add(struct ocpf_context *, const char *, const char *); int ocpf_oleguid_check(struct ocpf_context *, const char *, const char **); int ocpf_add_filetime(const char *, struct FILETIME *); int ocpf_variable_add(struct ocpf_context *, const char *, union SPropValue_CTR, uint16_t, bool); int ocpf_binary_add(struct ocpf_context *, const char *, struct Binary_r *); /* The following private definitions come from libocpf/ocpf_write.c */ char *ocpf_write_unescape_string(TALLOC_CTX *, const char *); /* The following private definitions come from libocpf/ocpf_context.c */ struct ocpf_context *ocpf_context_init(TALLOC_CTX *, const char *, uint8_t, uint32_t); struct ocpf_context *ocpf_context_add(struct ocpf *, const char *, uint32_t *, uint8_t, bool *); int ocpf_context_delete(struct ocpf *, struct ocpf_context *); struct ocpf_context *ocpf_context_search_by_filename(struct ocpf_context *, const char *); struct ocpf_context *ocpf_context_search_by_context_id(struct ocpf_context *, uint32_t); __END_DECLS #undef _PRINTF_ATTRIBUTE #define _PRINTF_ATTRIBUTE(a1, a2) #endif /* ! __OCPF_PRIVATE_H_ */ openchange-2.0/libocpf/ocpf_public.c000066400000000000000000000503271223057412600175420ustar00rootroot00000000000000/* OpenChange OCPF (OpenChange Property File) implementation. Copyright (C) Julien Kerihuel 2008-2011. This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see . */ /** \file ocpf_public.c \brief public OCPF API */ #include #include "libocpf/ocpf.h" #include "libocpf/ocpf_api.h" int ocpf_yylex_init(void *); int ocpf_yylex_init_extra(struct ocpf_context *, void *); void ocpf_yyset_in(FILE *, void *); int ocpf_yylex_destroy(void *); int ocpf_yyparse(struct ocpf_context *, void *); struct ocpf *ocpf; int error_flag; /** \details Initialize OCPF context Initialize ocpf context and allocate memory for internal structures \return OCPF_SUCCESS on success, otherwise OCPF_ERROR \sa ocpf_release, ocpf_parse */ _PUBLIC_ int ocpf_init(void) { TALLOC_CTX *mem_ctx; OCPF_RETVAL_IF(ocpf, NULL, OCPF_INITIALIZED, NULL); mem_ctx = talloc_named(NULL, 0, "ocpf"); ocpf = talloc_zero(mem_ctx, struct ocpf); ocpf->mem_ctx = mem_ctx; ocpf->context = talloc_zero(mem_ctx, struct ocpf_context); ocpf->free_id = talloc_zero(mem_ctx, struct ocpf_freeid); ocpf->last_id = 1; return OCPF_SUCCESS; } /** \details Uninitialize OCPF context Uninitialize the global OCPF context and release memory. \return OCPF_SUCCESS on success, otherwise OCPF_ERROR \sa ocpf_init */ _PUBLIC_ int ocpf_release(void) { OCPF_RETVAL_IF(!ocpf || !ocpf->mem_ctx, NULL, OCPF_NOT_INITIALIZED, NULL); talloc_free(ocpf->mem_ctx); ocpf = NULL; return OCPF_SUCCESS; } /** \details Create a new OCPF context \param filename the filename to process \param context_id pointer to the context identifier the function \param flags Flags controlling how the OCPF should be opened \return OCPF_SUCCESS on success, otherwise OCPF_ERROR */ _PUBLIC_ int ocpf_new_context(const char *filename, uint32_t *context_id, uint8_t flags) { struct ocpf_context *ctx; bool existing = false; OCPF_RETVAL_IF(!ocpf || !ocpf->mem_ctx, NULL, OCPF_NOT_INITIALIZED, NULL); ctx = ocpf_context_add(ocpf, filename, context_id, flags, &existing); if (!ctx) { return OCPF_ERROR; } if (existing == false) { DLIST_ADD_END(ocpf->context, ctx, struct ocpf_context *); return OCPF_SUCCESS; } return OCPF_E_EXIST; } /** \details Delete an OCPF context \param context_id context identifier referencing the context to delete \return OCPF_SUCCESS on success, otherwise OCPF_ERROR */ _PUBLIC_ int ocpf_del_context(uint32_t context_id) { int ret; struct ocpf_context *ctx; /* Sanity checks */ OCPF_RETVAL_IF(!ocpf || !ocpf->mem_ctx, NULL, OCPF_NOT_INITIALIZED, NULL); /* Search the context */ ctx = ocpf_context_search_by_context_id(ocpf->context, context_id); OCPF_RETVAL_IF(!ctx, NULL, OCPF_INVALID_CONTEXT, NULL); ret = ocpf_context_delete(ocpf, ctx); if (ret == -1) return OCPF_ERROR; return OCPF_SUCCESS; } /** \details Parse OCPF file Parse and process the given ocpf file. \param context_id the identifier of the context holding the file to be parsed \return OCPF_SUCCESS on success, otherwise OCPF_ERROR \sa ocpf_init */ _PUBLIC_ int ocpf_parse(uint32_t context_id) { int ret; struct ocpf_context *ctx; void *scanner; /* Sanity checks */ OCPF_RETVAL_IF(!ocpf || !ocpf->mem_ctx, NULL, OCPF_NOT_INITIALIZED, NULL); /* Step 1. Search the context */ ctx = ocpf_context_search_by_context_id(ocpf->context, context_id); OCPF_RETVAL_IF(!ctx, NULL, OCPF_INVALID_CONTEXT, NULL); ret = ocpf_yylex_init(&scanner); ret = ocpf_yylex_init_extra(ctx, &scanner); ocpf_yyset_in(ctx->fp, scanner); ret = ocpf_yyparse(ctx, scanner); ocpf_yylex_destroy(scanner); return ret; } #define MAX_READ_SIZE 0x1000 static enum MAPISTATUS ocpf_stream(TALLOC_CTX *mem_ctx, mapi_object_t *obj_parent, uint32_t aulPropTag, struct Binary_r *bin) { enum MAPISTATUS retval; mapi_object_t obj_stream; DATA_BLOB stream; uint32_t access_flags = 2; /* MAPI_MODIFY by default */ uint32_t size; uint32_t offset; uint16_t read_size; mapi_object_init(&obj_stream); /* Step1. Open the Stream */ retval = OpenStream(obj_parent, aulPropTag, access_flags, &obj_stream); MAPI_RETVAL_IF(retval, retval, NULL); /* Step2. Write the Stream */ size = MAX_READ_SIZE; offset = 0; while (offset <= bin->cb) { stream.length = size; stream.data = talloc_size(mem_ctx, size); memcpy(stream.data, bin->lpb + offset, size); retval = WriteStream(&obj_stream, &stream, &read_size); talloc_free(stream.data); MAPI_RETVAL_IF(retval, retval, NULL); /* Exit when there is nothing left to write */ if (!read_size) return MAPI_E_SUCCESS; offset += read_size; if ((offset + size) > bin->cb) { size = bin->cb - offset; } } mapi_object_release(&obj_stream); return MAPI_E_SUCCESS; } /** \details Build a SPropValue array from ocpf context This function builds a SPropValue array from the ocpf context and information stored. \param mem_ctx the memory context to use for memory allocation \param context_id identifier of the context to build a SPropValue array for \param obj_folder pointer the folder object we use for internal MAPI operations \param obj_message pointer to the message object we use for internal MAPI operations \return MAPI_E_SUCCESS on success, otherwise -1. \note Developers should call GetLastError() to retrieve the last MAPI error code. Possible MAPI error codes are: - MAPI_E_NOT_INITIALIZED: MAPI subsystem has not been initialized \sa ocpf_get_SPropValue */ _PUBLIC_ enum MAPISTATUS ocpf_set_SPropValue(TALLOC_CTX *mem_ctx, uint32_t context_id, mapi_object_t *obj_folder, mapi_object_t *obj_message) { enum MAPISTATUS retval; struct mapi_nameid *nameid; struct SPropTagArray *SPropTagArray; struct ocpf_property *pel; struct ocpf_nproperty *nel; struct ocpf_context *ctx; uint32_t i; /* sanity checks */ MAPI_RETVAL_IF(!ocpf, MAPI_E_NOT_INITIALIZED, NULL); MAPI_RETVAL_IF(!obj_folder, MAPI_E_INVALID_PARAMETER, NULL); /* Step 0. Search for the context */ ctx = ocpf_context_search_by_context_id(ocpf->context, context_id); OCPF_RETVAL_IF(!ctx, NULL, OCPF_INVALID_CONTEXT, NULL); if (!mem_ctx) { mem_ctx = (TALLOC_CTX *) ctx; } /* Step 1. Allocate SPropValue */ ctx->cValues = 0; ctx->lpProps = talloc_array(mem_ctx, struct SPropValue, 2); /* Step2. build the list of named properties we want to set */ if (ctx->nprops && ctx->nprops->next) { nameid = mapi_nameid_new(mem_ctx); for (nel = ctx->nprops; nel->next; nel = nel->next) { if (nel->OOM) { mapi_nameid_OOM_add(nameid, nel->OOM, nel->oleguid); } else if (nel->mnid_id) { mapi_nameid_custom_lid_add(nameid, nel->mnid_id, nel->propType, nel->oleguid); } else if (nel->mnid_string) { mapi_nameid_custom_string_add(nameid, nel->mnid_string, nel->propType, nel->oleguid); } } /* Step3. GetIDsFromNames and map property types */ SPropTagArray = talloc_zero(mem_ctx, struct SPropTagArray); retval = GetIDsFromNames(obj_folder, nameid->count, nameid->nameid, 0, &SPropTagArray); if (retval != MAPI_E_SUCCESS) { MAPIFreeBuffer(SPropTagArray); MAPIFreeBuffer(nameid); return retval; } mapi_nameid_SPropTagArray(nameid, SPropTagArray); MAPIFreeBuffer(nameid); /* Step4. Add named properties */ for (nel = ctx->nprops, i = 0; SPropTagArray->aulPropTag[i] && nel->next; nel = nel->next, i++) { if (SPropTagArray->aulPropTag[i]) { if (((SPropTagArray->aulPropTag[i] & 0xFFFF) == PT_BINARY) && (((struct Binary_r *)nel->value)->cb > MAX_READ_SIZE)) { retval = ocpf_stream(mem_ctx, obj_message, SPropTagArray->aulPropTag[i], (struct Binary_r *)nel->value); MAPI_RETVAL_IF(retval, retval, NULL); } else { ctx->lpProps = add_SPropValue(mem_ctx, ctx->lpProps, &ctx->cValues, SPropTagArray->aulPropTag[i], nel->value); } } } MAPIFreeBuffer(SPropTagArray); } /* Step5. Add Known properties */ if (ctx->props && ctx->props->next) { for (pel = ctx->props; pel->next; pel = pel->next) { if (((pel->aulPropTag & 0xFFFF) == PT_BINARY) && (((struct Binary_r *)pel->value)->cb > MAX_READ_SIZE)) { retval = ocpf_stream(mem_ctx, obj_message, pel->aulPropTag, (struct Binary_r *)pel->value); MAPI_RETVAL_IF(retval, retval, NULL); } else { if ((pel->aulPropTag & 0xFFFF) == PT_STRING8) { pel->aulPropTag = (pel->aulPropTag & 0xFFFF) + PT_UNICODE; } ctx->lpProps = add_SPropValue(mem_ctx, ctx->lpProps, &ctx->cValues, pel->aulPropTag, pel->value); } } } /* Step 6. Add message class */ if (ctx->type) { ctx->lpProps = add_SPropValue(mem_ctx, ctx->lpProps, &ctx->cValues, PidTagMessageClass, (const void *)ctx->type); } return MAPI_E_SUCCESS; } /** \details Clear the known properties from the OCPF entity \param context_id identifier of the context to clear properties from \return MAPI_E_SUCCESS on success, otherwise a non-zero error code */ enum MAPISTATUS ocpf_clear_props (uint32_t context_id) { struct ocpf_context *ctx; MAPI_RETVAL_IF(!ocpf, MAPI_E_NOT_INITIALIZED, NULL); MAPI_RETVAL_IF(!ocpf->mem_ctx, MAPI_E_NOT_INITIALIZED, NULL); /* Search the context */ ctx = ocpf_context_search_by_context_id(ocpf->context, context_id); MAPI_RETVAL_IF(!ctx, MAPI_E_NOT_FOUND, NULL); if (ctx->props) { talloc_free(ctx->props); } ctx->props = talloc_zero(ctx, struct ocpf_property); return MAPI_E_SUCCESS; } /** \details Get the OCPF SPropValue array This function is an accessor designed to return the SPropValue structure created with ocpf_set_SPropValue. \param context_id identifier of the context to retrieve SPropValue from \param cValues pointer on the number of SPropValue entries \return NULL on error, otherwise returns an allocated lpProps pointer \sa ocpf_set_SPropValue */ /* TODO: this should return a success/error code, with lpProps as a return parameter */ _PUBLIC_ struct SPropValue *ocpf_get_SPropValue(uint32_t context_id, uint32_t *cValues) { struct ocpf_context *ctx; OCPF_RETVAL_TYPE(!ocpf || !ocpf->mem_ctx, NULL, OCPF_NOT_INITIALIZED, NULL, NULL); /* Search the context */ ctx = ocpf_context_search_by_context_id(ocpf->context, context_id); OCPF_RETVAL_TYPE(!ctx, NULL, OCPF_INVALID_CONTEXT, NULL, NULL); OCPF_RETVAL_TYPE(!ctx->lpProps || !ctx->cValues, ctx, OCPF_INVALID_PROPARRAY, NULL, NULL); *cValues = ctx->cValues; return ctx->lpProps; } static enum MAPISTATUS ocpf_folder_lookup(TALLOC_CTX *mem_ctx, uint64_t sfid, mapi_object_t *obj_parent, mapi_id_t folder_id, mapi_object_t *obj_ret) { enum MAPISTATUS retval; mapi_object_t obj_folder; mapi_object_t obj_htable; struct SPropTagArray *SPropTagArray; struct SRowSet SRowSet; uint32_t i; const uint64_t *fid; mapi_object_init(&obj_folder); retval = OpenFolder(obj_parent, folder_id, &obj_folder); if (retval != MAPI_E_SUCCESS) return false; mapi_object_init(&obj_htable); retval = GetHierarchyTable(&obj_folder, &obj_htable, 0, NULL); if (retval != MAPI_E_SUCCESS) return false; SPropTagArray = set_SPropTagArray(mem_ctx, 0x1, PR_FID); retval = SetColumns(&obj_htable, SPropTagArray); MAPIFreeBuffer(SPropTagArray); if (retval != MAPI_E_SUCCESS) return false; while (((retval = QueryRows(&obj_htable, 0x32, TBL_ADVANCE, &SRowSet)) != MAPI_E_NOT_FOUND && SRowSet.cRows)) { for (i = 0; i < SRowSet.cRows; i++) { fid = (const uint64_t *)find_SPropValue_data(&SRowSet.aRow[i], PR_FID); if (fid && *fid == sfid) { retval = OpenFolder(&obj_folder, *fid, obj_ret); mapi_object_release(&obj_htable); mapi_object_release(&obj_folder); return MAPI_E_SUCCESS; } else if (fid) { retval = ocpf_folder_lookup(mem_ctx, sfid, &obj_folder, *fid, obj_ret); if (retval == MAPI_E_SUCCESS) { mapi_object_release(&obj_htable); mapi_object_release(&obj_folder); return MAPI_E_SUCCESS; } } } } mapi_object_release(&obj_htable); mapi_object_release(&obj_folder); errno = MAPI_E_NOT_FOUND; return MAPI_E_NOT_FOUND; } /** \details Open OCPF folder This function opens the folder associated with the ocpf folder global context value. \param context_id identifier of the context to open the folder for \param obj_store the store object \param obj_folder the folder to open \return MAPI_E_SUCCESS on success, otherwise MAPI_E_NOT_FOUND. \note Developers should call GetLastError() to retrieve the last MAPI error code. Possible MAPI error codes are: - MAPI_E_NOT_INITIALIZED: MAPI subsystem has not been initialized. - MAPI_E_INVALID_PARAMETER: obj_store is undefined - MAPI_E_NOT_FOUND: The specified folder could not be found or is not yet supported. \sa ocpf_init, ocpf_parse */ _PUBLIC_ enum MAPISTATUS ocpf_OpenFolder(uint32_t context_id, mapi_object_t *obj_store, mapi_object_t *obj_folder) { enum MAPISTATUS retval; struct ocpf_context *ctx; mapi_id_t id_folder; mapi_id_t id_tis; /* Sanity checks */ MAPI_RETVAL_IF(!ocpf, MAPI_E_NOT_INITIALIZED, NULL); MAPI_RETVAL_IF(!obj_store, MAPI_E_INVALID_PARAMETER, NULL); /* Step 1. Search for the context */ ctx = ocpf_context_search_by_context_id(ocpf->context, context_id); MAPI_RETVAL_IF(!ctx, MAPI_E_INVALID_PARAMETER, NULL); MAPI_RETVAL_IF(!ctx->folder, MAPI_E_NOT_FOUND, NULL); mapi_object_init(obj_folder); if (ctx->folder >= 1 && ctx->folder <= 26) { retval = GetDefaultFolder(obj_store, &id_folder, ctx->folder); MAPI_RETVAL_IF(retval, retval, NULL); retval = OpenFolder(obj_store, id_folder, obj_folder); MAPI_RETVAL_IF(retval, retval, NULL); } else { retval = GetDefaultFolder(obj_store, &id_tis, olFolderTopInformationStore); MAPI_RETVAL_IF(retval, retval, NULL); retval = ocpf_folder_lookup((TALLOC_CTX *)ctx, ctx->folder, obj_store, id_tis, obj_folder); MAPI_RETVAL_IF(retval, retval, NULL); } return MAPI_E_SUCCESS; } /** * We set external recipients at the end of aRow */ static bool set_external_recipients(TALLOC_CTX *mem_ctx, struct SRowSet *SRowSet, const char *username, enum ulRecipClass RecipClass) { uint32_t last; struct SPropValue SPropValue; SRowSet->aRow = talloc_realloc(mem_ctx, SRowSet->aRow, struct SRow, SRowSet->cRows + 2); last = SRowSet->cRows; SRowSet->aRow[last].cValues = 0; SRowSet->aRow[last].lpProps = talloc_zero(mem_ctx, struct SPropValue); /* PR_OBJECT_TYPE */ SPropValue.ulPropTag = PidTagObjectType; SPropValue.value.l = MAPI_MAILUSER; SRow_addprop(&(SRowSet->aRow[last]), SPropValue); /* PR_DISPLAY_TYPE */ SPropValue.ulPropTag = PidTagDisplayType; SPropValue.value.l = 0; SRow_addprop(&(SRowSet->aRow[last]), SPropValue); /* PR_GIVEN_NAME */ SPropValue.ulPropTag = PidTagGivenName; SPropValue.value.lpszW = username; SRow_addprop(&(SRowSet->aRow[last]), SPropValue); /* PR_DISPLAY_NAME */ SPropValue.ulPropTag = PidTagDisplayName; SPropValue.value.lpszW = username; SRow_addprop(&(SRowSet->aRow[last]), SPropValue); /* PR_7BIT_DISPLAY_NAME */ SPropValue.ulPropTag = PidTag7BitDisplayName; SPropValue.value.lpszW = username; SRow_addprop(&(SRowSet->aRow[last]), SPropValue); /* PR_SMTP_ADDRESS */ SPropValue.ulPropTag = PidTagPrimarySmtpAddress; SPropValue.value.lpszW = username; SRow_addprop(&(SRowSet->aRow[last]), SPropValue); /* PR_ADDRTYPE */ SPropValue.ulPropTag = PidTagAddressType; SPropValue.value.lpszW = "SMTP"; SRow_addprop(&(SRowSet->aRow[last]), SPropValue); SetRecipientType(&(SRowSet->aRow[last]), RecipClass); SRowSet->cRows += 1; return true; } /** \details Set the message recipients from ocpf context This function sets the recipient (To, Cc, Bcc) from the ocpf context and information stored. \param mem_ctx the memory context to use for memory allocation \param context_id identifier to the context to set recipients for \param obj_message pointer to the message object we use for internal MAPI operations \return OCPF_SUCCESS on success, otherwise OCPF_ERROR. \sa ocpf */ _PUBLIC_ enum MAPISTATUS ocpf_set_Recipients(TALLOC_CTX *mem_ctx, uint32_t context_id, mapi_object_t *obj_message) { enum MAPISTATUS retval; struct ocpf_context *ctx; struct SPropTagArray *SPropTagArray; struct SPropValue SPropValue; struct SPropValue *lpProps; struct SRowSet *SRowSet; struct PropertyRowSet_r *RowSet; struct PropertyTagArray_r *flaglist = NULL; char **usernames = NULL; int *recipClass = NULL; uint32_t counter; uint32_t i; const void *propdata; MAPI_RETVAL_IF(!ocpf, MAPI_E_NOT_INITIALIZED, NULL); MAPI_RETVAL_IF(!obj_message, MAPI_E_INVALID_PARAMETER, NULL); /* Step 1. Search for the context */ ctx = ocpf_context_search_by_context_id(ocpf->context, context_id); MAPI_RETVAL_IF(!ctx, MAPI_E_INVALID_PARAMETER, NULL); MAPI_RETVAL_IF(!ctx->recipients->cRows, MAPI_E_NOT_FOUND, NULL); SPropTagArray = set_SPropTagArray(mem_ctx, 0x8, PidTagObjectType, PidTagDisplayName, PidTag7BitDisplayName, PidTagDisplayName, PidTagPrimarySmtpAddress, PidTagGivenName, PidTagEmailAddress, PidTagAddressType); /* Step 1. Group recipients and run ResolveNames */ usernames = talloc_array(mem_ctx, char *, ctx->recipients->cRows + 1); recipClass = talloc_array(mem_ctx, int, ctx->recipients->cRows + 1); for (i = 0; i < ctx->recipients->cRows; i++) { lpProps = get_SPropValue_SRow(&(ctx->recipients->aRow[i]), PidTag7BitDisplayName); propdata = get_SPropValue(lpProps, PidTag7BitDisplayName); usernames[i] = talloc_strdup((TALLOC_CTX *)usernames, (const char *) propdata); lpProps = get_SPropValue_SRow(&(ctx->recipients->aRow[i]), PidTagRecipientType); propdata = get_SPropValue(lpProps, PidTagRecipientType); recipClass[i] = *((uint32_t *)propdata); } usernames[i] = NULL; retval = ResolveNames(mapi_object_get_session(obj_message), (const char **)usernames, SPropTagArray, &RowSet, &flaglist, 0); MAPIFreeBuffer(SPropTagArray); MAPI_RETVAL_IF(retval, retval, usernames); /* Step2. Associate resolved recipients to their respective recipClass */ SRowSet = talloc_zero(mem_ctx, struct SRowSet); if (RowSet) { cast_PropertyRowSet_to_SRowSet(mem_ctx, RowSet, SRowSet); } counter = 0; for (i = 0; usernames[i]; i++) { if (flaglist->aulPropTag[i] == MAPI_UNRESOLVED) { set_external_recipients(mem_ctx, SRowSet, usernames[i], recipClass[i]); } if (flaglist->aulPropTag[i] == MAPI_RESOLVED) { SetRecipientType(&(SRowSet->aRow[counter]), recipClass[i]); counter++; } } /* Step3. Finish to build the ModifyRecipients SRowSet */ SPropValue.ulPropTag = PR_SEND_INTERNET_ENCODING; SPropValue.value.l = 0; SRowSet_propcpy(mem_ctx, SRowSet, SPropValue); /* Step4. Call ModifyRecipients */ retval = ModifyRecipients(obj_message, SRowSet); MAPI_RETVAL_IF(retval, retval, NULL); return MAPI_E_SUCCESS; } /** \details Get the message recipients from ocpf context This function gets the recipient (To, Cc, Bcc) from the ocpf context and information stored. \param mem_ctx the memory context to use for memory allocation \param context_id identifier to the context to set recipients for \param SRowSet pointer on pointer to the set of recipients to return \return MAPI_E_SUCCESS on success, otherwise NULL \sa ocpf */ _PUBLIC_ enum MAPISTATUS ocpf_get_recipients(TALLOC_CTX *mem_ctx, uint32_t context_id, struct SRowSet **SRowSet) { struct ocpf_context *ctx; /* Sanity checks */ MAPI_RETVAL_IF(!ocpf, MAPI_E_NOT_INITIALIZED, NULL); MAPI_RETVAL_IF(!SRowSet, MAPI_E_INVALID_PARAMETER, NULL); /* Step 1. Search for the context */ ctx = ocpf_context_search_by_context_id(ocpf->context, context_id); MAPI_RETVAL_IF(!ctx, MAPI_E_INVALID_PARAMETER, NULL); MAPI_RETVAL_IF(!ctx->recipients->cRows, MAPI_E_NOT_FOUND, NULL); *SRowSet = ctx->recipients; return MAPI_E_SUCCESS; } openchange-2.0/libocpf/ocpf_server.c000066400000000000000000000145621223057412600175730ustar00rootroot00000000000000/* OpenChange OCPF (OpenChange Property File) implementation. Copyright (C) Julien Kerihuel 2010. This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see . */ #include "libocpf/ocpf.h" #include "libocpf/ocpf_api.h" /** \file ocpf_server.c \brief ocpf public API for server side. Do not perform any libmapi calls and trust incoming data. Most of these functions have equivalent in ocpf_public.c or ocpf_api.c */ /** \details Set the message class (type) associated to an OCPF file. \param context_id identifier of the context to set type for \param type pointer to the type's string to set \return MAPI_E_SUCCESS on success, otherwise MAPI/OCPF error */ _PUBLIC_ enum MAPISTATUS ocpf_server_set_type(uint32_t context_id, const char *type) { struct ocpf_context *ctx; /* Sanity checks */ MAPI_RETVAL_IF(!ocpf, MAPI_E_NOT_INITIALIZED, NULL); /* Step 1. Search for the context */ ctx = ocpf_context_search_by_context_id(ocpf->context, context_id); OCPF_RETVAL_IF(!ctx, NULL, OCPF_INVALID_CONTEXT, NULL); return ocpf_type_add(ctx, type); } /** \details Build a SPropValue array from ocpf context This function builds a SPropValue array from the ocpf context and information stored. \param mem_ctx pointer to the memory context to use for memory allocation \param context_id identifier of the context to build a SPropValue array for \note This function is a server-side convenient function only. It doesn't handle named properties and its scope is much more limited than ocpf_set_SpropValue. Developers working on a client-side software/library must use ocpf_set_SPropValue instead. \return MAPI_E_SUCCESS on success, otherwise MAPI/OCPF error \sa ocpf_get_SPropValue */ _PUBLIC_ enum MAPISTATUS ocpf_server_set_SPropValue(TALLOC_CTX *mem_ctx, uint32_t context_id) { struct ocpf_property *pel; struct ocpf_context *ctx; /* sanity checks */ MAPI_RETVAL_IF(!ocpf, MAPI_E_NOT_INITIALIZED, NULL); /* Step 1. Search for the context */ ctx = ocpf_context_search_by_context_id(ocpf->context, context_id); OCPF_RETVAL_IF(!ctx, NULL, OCPF_INVALID_CONTEXT, NULL); /* Step 2. Allocate SPropValue */ ctx->cValues = 0; ctx->lpProps = talloc_array(ctx, struct SPropValue, 2); /* Step 3. Add Known properties */ if (ctx->props && ctx->props->next) { for (pel = ctx->props; pel->next; pel = pel->next) { switch (pel->aulPropTag) { case PidTagMessageClass: ocpf_server_set_type(context_id, (const char *)pel->value); ctx->lpProps = add_SPropValue(ctx, ctx->lpProps, &ctx->cValues, pel->aulPropTag, pel->value); break; default: ctx->lpProps = add_SPropValue(ctx, ctx->lpProps, &ctx->cValues, pel->aulPropTag, pel->value); } } } /* Step 4. Add message class */ if (ctx->type) { ctx->lpProps = add_SPropValue(ctx, ctx->lpProps, &ctx->cValues, PidTagMessageClass, (const void *)ctx->type); } return MAPI_E_SUCCESS; } /** \details Add a SPropValue structure to the context This functions adds a SPropValue to the ocpf context. This property must be part of the known property namespace. If the property already exists in the list, it is automatically replaced with the new one. \param context_id identifier of the ocpf context \param lpProps pointer to the SPropValue structure to add to the context \return MAPI_E_SUCCESS on success, otheriwse MAPI/OCPF error \sa ocpf_server_add_named_SPropValue */ _PUBLIC_ enum MAPISTATUS ocpf_server_add_SPropValue(uint32_t context_id, struct SPropValue *lpProps) { int ret; struct ocpf_context *ctx; struct ocpf_property *pel; struct ocpf_property *element; bool found = false; /* Sanity checks */ MAPI_RETVAL_IF(!ocpf, MAPI_E_NOT_INITIALIZED, NULL); MAPI_RETVAL_IF(!lpProps, MAPI_E_INVALID_PARAMETER, NULL); /* Step 1. Search the context */ ctx = ocpf_context_search_by_context_id(ocpf->context, context_id); OCPF_RETVAL_IF(!ctx, NULL, OCPF_INVALID_CONTEXT, NULL); if (ctx->props && ctx->props->next) { for (pel = ctx->props; pel->next; pel = pel->next) { if (pel->aulPropTag == lpProps->ulPropTag) { talloc_free((void *)pel->value); ret = ocpf_set_propvalue((TALLOC_CTX *)pel, ctx, &pel->value, (uint16_t)(pel->aulPropTag & 0xFFFF), (uint16_t)(pel->aulPropTag & 0xFFFF), lpProps->value, true); if (ret == -1) { return OCPF_ERROR; } found = true; break; } } } /* Add the element if not found */ if (found == false) { element = NULL; element = talloc_zero(ctx->props, struct ocpf_property); element->aulPropTag = lpProps->ulPropTag; ret = ocpf_set_propvalue((TALLOC_CTX *)element, ctx, &element->value, (uint16_t)(lpProps->ulPropTag & 0xFFFF), (uint16_t)(lpProps->ulPropTag & 0xFFFF), lpProps->value, true); if (ret == -1) { talloc_free(element); return OCPF_ERROR; } DLIST_ADD(ctx->props, element); } return MAPI_E_SUCCESS; } /** \details Synchronize data on filesystem \param context_id identifier of the ocpf context \return MAPI_E_SUCCESS on success, otherwise otheriwse MAPI/OCPF error */ _PUBLIC_ enum MAPISTATUS ocpf_server_sync(uint32_t context_id) { struct ocpf_context *ctx; /* Sanity checks */ MAPI_RETVAL_IF(!ocpf, MAPI_E_NOT_INITIALIZED, NULL); /* Step 1. Search the context */ ctx = ocpf_context_search_by_context_id(ocpf->context, context_id); OCPF_RETVAL_IF(!ctx, NULL, OCPF_INVALID_CONTEXT, NULL); if (ctx->flags == OCPF_FLAGS_CREATE) { ctx->flags = OCPF_FLAGS_RDWR; } if (ctx->fp) { fclose(ctx->fp); } switch (ctx->flags) { case OCPF_FLAGS_RDWR: ctx->fp = fopen(ctx->filename, "r+"); break; case OCPF_FLAGS_READ: ctx->fp = fopen(ctx->filename, "r"); break; case OCPF_FLAGS_WRITE: ctx->fp = fopen(ctx->filename, "w"); break; } return MAPI_E_SUCCESS; } openchange-2.0/libocpf/ocpf_write.c000066400000000000000000000464621223057412600174230ustar00rootroot00000000000000/* OpenChange OCPF (OpenChange Property File) implementation. Copyright (C) Julien Kerihuel 2008-2011. This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see . */ /** \file ocpf_write.c \brief public OCPF write API */ #include #include "libocpf/ocpf.h" #include "libocpf/ocpf_api.h" #include "libmapi/libmapi_private.h" #include "libmapi/mapidefs.h" struct ocpf_guid { char *name; const char *oleguid; }; static const struct ocpf_guid ocpf_guid[] = { { "PSETID_Appointment", PSETID_Appointment }, { "PSETID_Task", PSETID_Task }, { "PSETID_Address", PSETID_Address }, { "PSETID_Common", PSETID_Common }, { "PSETID_Note", PSETID_Note }, { "PSETID_Log", PSETID_Log }, { "PSETID_Sharing", PSETID_Sharing }, { "PSETID_PostRss", PSETID_PostRss }, { "PSETID_UnifiedMessaging", PSETID_UnifiedMessaging }, { "PSETID_Meeting", PSETID_Meeting }, { "PSETID_Airsync", PSETID_AirSync }, { "PSETID_Messaging", PSETID_Messaging }, { "PSETID_Attachment", PSETID_Attachment }, { "PSETID_CalendarAssistant", PSETID_CalendarAssistant }, { "PS_PUBLIC_STRINGS", PS_PUBLIC_STRINGS }, { "PS_INTERNET_HEADERS", PS_INTERNET_HEADERS }, { "PS_MAPI", PS_MAPI }, { NULL, NULL } }; static char *ocpf_write_get_guid_name(struct ocpf_context *ctx, const char *oleguid) { uint32_t i; static int idx = 0; static struct ocpf_oleguid *guid = NULL; struct ocpf_oleguid *element; char *name; if (!oleguid) return NULL; if (!guid) { guid = talloc_zero(ctx, struct ocpf_oleguid); } for (i = 0; ocpf_guid[i].oleguid; i++) { if (!strcmp(oleguid, ocpf_guid[i].oleguid)) { return ocpf_guid[i].name; } } for (element = guid; element->next; element = element->next) { if (!strcmp(oleguid, element->guid)) { return (char *)element->name; } } element->name = talloc_asprintf(ctx, "PSETID_Custom_%d", idx); element->guid = talloc_strdup(ctx, oleguid); DLIST_ADD(guid, element); name = talloc_strdup(ctx, element->name); idx++; return name; } struct ocpf_proptype { uint16_t type; const char *name; }; static const struct ocpf_proptype ocpf_proptype[] = { { 0x2, "PT_SHORT" }, { 0x3, "PT_LONG" }, { 0x4, "PT_FLOAT" }, { 0x5, "PT_DOUBLE" }, { 0x6, "PT_CURRENCY" }, { 0x7, "PT_APPTIME" }, { 0xa, "PT_ERROR" }, { 0xb, "PT_BOOLEAN" }, { 0xd, "PT_OBJECT" }, { 0x14, "PT_I8" }, { 0x1e, "PT_STRING8" }, { 0x1f, "PT_UNICODE" }, { 0x40, "PT_SYSTIME" }, { 0x48, "PT_CLSID" }, { 0x102, "PT_BINARY" }, { 0x1002, "PT_MV_SHORT" }, { 0x1003, "PT_MV_LONG" }, { 0x101e, "PT_MV_STRING8" }, { 0x101f, "PT_MV_UNICODE" }, { 0, NULL} }; static const char *ocpf_write_get_proptype_name(uint16_t type) { uint32_t i; for (i = 0; ocpf_proptype[i].name; i++) { if (type == ocpf_proptype[i].type) { return ocpf_proptype[i].name; } } return NULL; } static void ocpf_write_propname(struct ocpf_context *ctx, FILE *fp, uint32_t ulPropTag) { const char *propname; char *line; propname = get_proptag_name(ulPropTag); if (propname) { line = talloc_asprintf(ctx, "\t%s = ", propname); } else { line = talloc_asprintf(ctx, "\t0x%x = ", ulPropTag); } fwrite(line, strlen(line), 1, fp); talloc_free(line); } static char *ocpf_write_systime(struct ocpf_context *ctx, const struct FILETIME *ft) { char *line; char tempTime[60]; NTTIME nt; time_t t; struct tm *tm; nt = ft->dwHighDateTime; nt = (nt << 32) | ft->dwLowDateTime; t = nt_time_to_unix(nt); tm = localtime(&t); strftime(tempTime, sizeof(tempTime)-1, "T%Y-%m-%d %H:%M:%S\n", tm); line = talloc_strdup(ctx, tempTime); return line; } static char *ocpf_write_binary(struct ocpf_context *ctx, const struct Binary_r *bin) { uint32_t i; char *line; line = talloc_asprintf(ctx, "{"); for (i = 0; i < bin->cb; i++) { line = talloc_asprintf_append(line, " 0x%.2x", bin->lpb[i]); } line = talloc_asprintf_append(line, " }\n"); return line; } static char *ocpf_write_mv_binary(struct ocpf_context *ctx, const struct BinaryArray_r *value) { uint32_t i; uint32_t j; char *line; line = talloc_asprintf(ctx, "{"); for (i = 0; i < value->cValues; i++) { line = talloc_asprintf_append(line, " {"); for (j = 0; j < value->lpbin[i].cb; j++) { line = talloc_asprintf_append(line, " 0x%.2x", value->lpbin[i].lpb[j]); } if (i != value->cValues - 1) { line = talloc_asprintf_append(line, " },"); } else { line = talloc_asprintf_append(line, " }"); } } line = talloc_asprintf_append(line, " }\n"); return line; } static char *ocpf_write_mv_long(struct ocpf_context *ctx, const struct LongArray_r *value) { char *str = NULL; uint32_t i; str = talloc_asprintf(ctx, "{ "); for (i = 0; i < value->cValues; i++) { if (i != value->cValues - 1) { str = talloc_asprintf_append_buffer(str, "%d, ", value->lpl[i]); } else { str = talloc_asprintf_append_buffer(str, "%d }", value->lpl[i]); } } return str; } static char *ocpf_write_escape_string(struct ocpf_context *ctx, const char *value) { char *str = NULL; char *stmp = NULL; int value_len; int len = 0; int tmp = 0; value_len = strlen(value); tmp = strcspn(value, "\\\""); if (tmp == value_len) { str = talloc_strdup(ctx, value); return str; } else { str = talloc_strndup(ctx, value, tmp); str = talloc_asprintf_append_buffer(str, "\\%c", value[tmp]); } len += tmp + 1; while (len < value_len) { tmp = strcspn(value + len, "\\\""); if ((tmp + len) == value_len) { str = talloc_asprintf_append_buffer(str, "%s", value + len); break; } else { stmp = talloc_strndup(ctx, value + len, tmp); str = talloc_asprintf_append_buffer(str, "%s\\%c", stmp, value[len + tmp]); talloc_free(stmp); len += tmp + 1; } } return str; } char *ocpf_write_unescape_string(TALLOC_CTX *mem_ctx, const char *value) { char *str = NULL; char *stmp = NULL; int value_len; int len = 0; int tmp = 0; value_len = strlen(value); tmp = strcspn(value, "\\"); if (tmp == value_len) { str = talloc_strdup(mem_ctx, value); return str; } str = talloc_strndup(mem_ctx, value, tmp + 1); if (value[tmp + 1] && value[tmp + 1] == '\\') { len += tmp + 2; } else { len += tmp + 1; } while (len < value_len) { tmp = strcspn(value + len, "\\"); if ((tmp + len) == value_len) { str = talloc_asprintf_append(str, "%s", value + len); break; } stmp = talloc_strndup(mem_ctx, value + len, tmp + 1); str = talloc_asprintf_append(str, "%s", stmp); if (value[len + tmp + 1] && (value[len + tmp + 1] == '\\' || value[len + tmp + 1] == '"')) { len += tmp + 2; } else { len += tmp + 1; } talloc_free(stmp); } return str; } static char *ocpf_write_mv_string8(struct ocpf_context *ctx, const struct StringArray_r *value) { char *str = NULL; char *tmp = NULL; uint32_t i; str = talloc_asprintf(ctx, "{ "); for (i = 0; i < value->cValues; i++) { tmp = ocpf_write_escape_string(ctx, (const char *)value->lppszA[i]); if (i != value->cValues - 1) { str = talloc_asprintf_append_buffer(str, "\"%s\", ", tmp); } else { str = talloc_asprintf_append_buffer(str, "\"%s\" }", tmp); } talloc_free(tmp); } return str; } static char *ocpf_write_mv_unicode(struct ocpf_context *ctx, const struct StringArrayW_r *value) { char *str = NULL; char *tmp = NULL; uint32_t i; str = talloc_asprintf(ctx, "{ "); for (i = 0; i < value->cValues; i++) { tmp = ocpf_write_escape_string(ctx, (const char *)value->lppszW[i]); if (i != value->cValues - 1) { str = talloc_asprintf_append_buffer(str, "\"%s\", ", tmp); } else { str = talloc_asprintf_append_buffer(str, "\"%s\" }", tmp); } talloc_free(tmp); } return str; } static char *ocpf_write_property(struct ocpf_context *ctx, bool *found, uint32_t ulPropTag, const void *value) { char *line = NULL; char *str = NULL; switch (ulPropTag & 0xFFFF) { case PT_STRING8: str = ocpf_write_escape_string(ctx, (const char *)value); line = talloc_asprintf(ctx, "\"%s\"\n", str); talloc_free(str); *found = true; break; case PT_UNICODE: str = ocpf_write_escape_string(ctx, (const char *)value); line = talloc_asprintf(ctx, "W\"%s\"\n", str); talloc_free(str); *found = true; break; case PT_SHORT: line = talloc_asprintf(ctx, "S%d\n", *((const uint16_t *)value)); *found = true; break; case PT_LONG: line = talloc_asprintf(ctx, "%d\n", *((const uint32_t *)value)); *found = true; break; case PT_DOUBLE: line = talloc_asprintf(ctx, "F%e\n", *((const double *)value)); *found = true; break; case PT_BOOLEAN: line = talloc_asprintf(ctx, "B\"%s\"\n", (*((const uint8_t *)value) == true) ? "true" : "false"); *found = true; break; case PT_I8: line = talloc_asprintf(ctx, "D0x%.16"PRIx64"\n", *(const uint64_t *)value); *found = true; break; case PT_SYSTIME: line = ocpf_write_systime(ctx, (const struct FILETIME *)value); *found = true; break; case PT_BINARY: line = ocpf_write_binary(ctx, (const struct Binary_r *)value); *found = true; break; case PT_MV_LONG: line = ocpf_write_mv_long(ctx, (const struct LongArray_r *)value); *found = true; break; case PT_MV_STRING8: line = ocpf_write_mv_string8(ctx, (const struct StringArray_r *)value); *found = true; break; case PT_MV_UNICODE: line = ocpf_write_mv_unicode(ctx, (const struct StringArrayW_r *)value); *found = true; break; case PT_MV_BINARY: line = ocpf_write_mv_binary(ctx, (const struct BinaryArray_r *)value); *found = true; break; } return line; } static int ocpf_write_recipients(struct ocpf_context *ctx, FILE *fp, enum ulRecipClass recipClass) { int i; int j; char *line = NULL; const void *value_data; bool found = false; uint32_t *RecipClass; enum MAPITAGS ulPropTag; struct SPropValue *lpProps; for (i = 0; i < ctx->recipients->cRows; i++) { lpProps = get_SPropValue_SRow(&(ctx->recipients->aRow[i]), PidTagRecipientType); if (lpProps) { RecipClass = (uint32_t *)get_SPropValue_data(lpProps); if (RecipClass && *RecipClass == recipClass) { switch (recipClass) { case MAPI_TO: fwrite(OCPF_RECIPIENT_TO, strlen(OCPF_RECIPIENT_TO), 1, fp); break; case MAPI_CC: fwrite(OCPF_RECIPIENT_CC, strlen(OCPF_RECIPIENT_CC), 1, fp); break; case MAPI_BCC: fwrite(OCPF_RECIPIENT_BCC, strlen(OCPF_RECIPIENT_BCC), 1, fp); break; default: break; } for (j = 0; j < ctx->recipients->aRow[i].cValues; j++) { ulPropTag = ctx->recipients->aRow[i].lpProps[j].ulPropTag; value_data = get_SPropValue_data(&(ctx->recipients->aRow[i].lpProps[j])); if (value_data) { line = ocpf_write_property(ctx, &found, ulPropTag, (void *)value_data); if (found == true) { ocpf_write_propname(ctx, fp, ulPropTag); fwrite(line, strlen(line), 1, fp); talloc_free(line); found = false; } } } fwrite(OCPF_END, strlen(OCPF_END), 1, fp); fwrite(OCPF_NEWLINE, strlen(OCPF_NEWLINE), 1, fp); } } } return OCPF_SUCCESS; } static bool ocpf_write_exclude_property(uint32_t ulPropTag) { uint32_t i; uint32_t propArray[] = { PR_DISPLAY_TO, PR_DISPLAY_CC, PR_DISPLAY_BCC, 0}; for (i = 0; propArray[i]; i++) { if (propArray[i] == ulPropTag) { return true; } } return false; } /** \details Specify the OCPF file name to write Specify the ocpf file to create \param context_id the identifier representing the context \param folder_id the folder \return OCPF_SUCCESS on success, otherwise OCPF_ERROR \sa ocpf_init */ _PUBLIC_ int ocpf_write_init(uint32_t context_id, mapi_id_t folder_id) { struct ocpf_context *ctx; /* Sanity checks */ OCPF_RETVAL_IF(!ocpf || !ocpf->mem_ctx, NULL, OCPF_NOT_INITIALIZED, NULL); /* Search the context */ ctx = ocpf_context_search_by_context_id(ocpf->context, context_id); OCPF_RETVAL_IF(!ctx, NULL, OCPF_INVALID_CONTEXT, NULL); ctx->folder = folder_id; return OCPF_SUCCESS; } /** \details Create the OCPF structure required for the commit operation This function process properties and named properties from the specified mapi_SPropValue_array and generates an OCPF structure with all the attributes required to create an OCPF file in the commit operation. \param context_id the identifier representing the context \param obj_message the message object \param mapi_lpProps the array of mapi properties returned by GetPropsAll \return OCPF_SUCCESS on success, otherwise OCPF_ERROR \sa GetPropsAll, ocpf_write_commit */ _PUBLIC_ int ocpf_write_auto(uint32_t context_id, mapi_object_t *obj_message, struct mapi_SPropValue_array *mapi_lpProps) { enum MAPISTATUS retval; int ret; struct ocpf_context *ctx; uint32_t i; uint16_t propID; struct SPropValue lpProps; struct SPropTagArray SPropTagArray; const char *type; char *tmp_guid; const char *guid; struct MAPINAMEID *nameid; uint16_t count; struct ocpf_nprop nprop; OCPF_RETVAL_IF(!ocpf || !ocpf->mem_ctx, NULL, OCPF_NOT_INITIALIZED, NULL); OCPF_RETVAL_IF(!mapi_lpProps, NULL, OCPF_INVALID_PROPARRAY, NULL); /* Find the context */ ctx = ocpf_context_search_by_context_id(ocpf->context, context_id); OCPF_RETVAL_IF(!ctx, NULL, OCPF_INVALID_CONTEXT, NULL); OCPF_RETVAL_IF(!ctx->filename, ctx, OCPF_WRITE_NOT_INITIALIZED, NULL); /* store message type */ type = (const char *) find_mapi_SPropValue_data(mapi_lpProps, PidTagMessageClass); if (type) { ret = ocpf_type_add(ctx, type); if (ret) return ret; } /* store recipients */ if (obj_message) { retval = GetRecipientTable(obj_message, ctx->recipients, &SPropTagArray); OCPF_RETVAL_IF(retval, ctx, OCPF_INVALID_RECIPIENTS, NULL); } /* store properties and OLEGUID in OCPF context */ for (i = 0; i < mapi_lpProps->cValues; i++) { propID = mapi_lpProps->lpProps[i].ulPropTag >> 16; cast_SPropValue(ctx, &mapi_lpProps->lpProps[i], &lpProps); if (propID < 0x8000) { if (ocpf_write_exclude_property(lpProps.ulPropTag) == false) { /* HACK: replace PR_CONVERSATION_TOPIC with PR_SUBJECT */ if (lpProps.ulPropTag == PR_CONVERSATION_TOPIC) { lpProps.ulPropTag = PR_SUBJECT; ocpf_propvalue(ctx, lpProps.ulPropTag, lpProps.value, lpProps.ulPropTag & 0xFFFF, false, kw_PROPERTY); cast_SPropValue(ctx, &mapi_lpProps->lpProps[i], &lpProps); } ocpf_propvalue(ctx, mapi_lpProps->lpProps[i].ulPropTag, lpProps.value, mapi_lpProps->lpProps[i].ulPropTag & 0xFFFF, false, kw_PROPERTY); } } else { nameid = talloc_zero(ctx, struct MAPINAMEID); retval = GetNamesFromIDs(obj_message, ((lpProps.ulPropTag & 0xFFFF0000) | PT_NULL), &count, &nameid); memset(&nprop, 0, sizeof (struct ocpf_nprop)); switch (nameid->ulKind) { case MNID_ID: nprop.mnid_id = nameid->kind.lid; break; case MNID_STRING: nprop.mnid_string = talloc_strdup(ctx, nameid->kind.lpwstr.Name); break; } nprop.propType = lpProps.ulPropTag & 0xFFFF; tmp_guid = GUID_string(ctx, &nameid->lpguid); nprop.guid = ocpf_write_get_guid_name(ctx, tmp_guid); /* OLEGUID has to be inserted prior named properties */ if (ocpf_oleguid_check(ctx, nprop.guid, &guid) != OCPF_SUCCESS) ocpf_oleguid_add(ctx, nprop.guid, tmp_guid); nprop.registered = false; ocpf_nproperty_add(ctx, &nprop, lpProps.value, NULL, nprop.propType, false); talloc_free(nameid); } } return OCPF_SUCCESS; } /** \details Write OCPF structure to OCPF file This function dumps the OCPF structure content into the OCPF file defined in ocpf_write_init. \param context_id the identifier representing the context \return OCPF_SUCCESS on success, otherwise OCPF_ERROR \sa ocpf_write_init, ocpf_write_auto */ _PUBLIC_ int ocpf_write_commit(uint32_t context_id) { FILE *fp; struct ocpf_context *ctx; struct ocpf_property *element; struct ocpf_nproperty *nelement; struct ocpf_oleguid *nguid; char *line; bool found = false; char *definition = NULL; /* Find the context */ ctx = ocpf_context_search_by_context_id(ocpf->context, context_id); OCPF_RETVAL_IF(!ctx, NULL, OCPF_INVALID_CONTEXT, NULL); OCPF_RETVAL_IF(!ctx->filename, ctx, OCPF_WRITE_NOT_INITIALIZED, NULL); OCPF_RETVAL_IF(ctx->flags == OCPF_FLAGS_READ, ctx, OCPF_WRITE_NOT_INITIALIZED, NULL); if (ctx->flags == OCPF_FLAGS_CREATE) { ctx->fp = fopen(ctx->filename, "w+"); } /* Position the file at the beginning of the stream */ fseek(ctx->fp, 0, SEEK_SET); fp = ctx->fp; OCPF_RETVAL_IF(!fp, ctx, OCPF_INVALID_FILEHANDLE, NULL); /* message type */ if (ctx->type) { line = talloc_asprintf(ctx, "TYPE \"%s\"\n\n", ctx->type); fwrite(line, strlen(line), 1, fp); talloc_free(line); } /* folder id */ if (ctx->folder) { line = talloc_asprintf(ctx, "FOLDER D0x%.16"PRIx64"\n\n", ctx->folder); fwrite(line, strlen(line), 1, fp); talloc_free(line); } /* OLEGUID */ for (nguid = ctx->oleguid; nguid->next; nguid = nguid->next) { line = talloc_asprintf(ctx, "OLEGUID %-25s \"%s\"\n", nguid->name, nguid->guid); fwrite(line, strlen(line), 1, fp); talloc_free(line); } fwrite(OCPF_NEWLINE, strlen(OCPF_NEWLINE), 1, fp); /* RECIPIENT */ if (ctx->recipients && ctx->recipients->cRows) { fwrite(OCPF_RECIPIENT_BEGIN, strlen(OCPF_RECIPIENT_BEGIN), 1, fp); ocpf_write_recipients(ctx, fp, MAPI_TO); ocpf_write_recipients(ctx, fp, MAPI_CC); ocpf_write_recipients(ctx, fp, MAPI_BCC); fwrite(OCPF_END, strlen(OCPF_END), 1, fp); fwrite(OCPF_NEWLINE, strlen(OCPF_NEWLINE), 1, fp); } /* known properties */ fwrite(OCPF_PROPERTY_BEGIN, strlen(OCPF_PROPERTY_BEGIN), 1, fp); for (element = ctx->props; element->next; element = element->next) { line = ocpf_write_property(ctx, &found, element->aulPropTag, element->value); if (found == true) { ocpf_write_propname(ctx, fp, element->aulPropTag); fwrite(line, strlen(line), 1, fp); talloc_free(line); found = false; } } fwrite(OCPF_END, strlen(OCPF_END), 1, fp); fwrite(OCPF_NEWLINE, strlen(OCPF_NEWLINE), 1, fp); /* named properties */ fwrite(OCPF_NPROPERTY_BEGIN, strlen(OCPF_NPROPERTY_BEGIN), 1, fp); for (nelement = ctx->nprops; nelement->next; nelement = nelement->next) { line = ocpf_write_property(ctx, &found, nelement->propType, nelement->value); if (found == true) { if (nelement->mnid_id) { definition = talloc_asprintf(ctx, "\tMNID_ID:0x%.4x:%s:%s = ", nelement->mnid_id, ocpf_write_get_proptype_name(nelement->propType), ocpf_write_get_guid_name(ctx, nelement->oleguid)); } else if (nelement->mnid_string) { definition = talloc_asprintf(ctx, "\tMNID_STRING:\"%s\":%s:%s = ", nelement->mnid_string, ocpf_write_get_proptype_name(nelement->propType), ocpf_write_get_guid_name(ctx, nelement->oleguid)); } if (definition) { fwrite(definition, strlen(definition), 1, fp); talloc_free(definition); } fwrite(line, strlen(line), 1, fp); talloc_free(line); found = false; } } fwrite(OCPF_END, strlen(OCPF_END), 1, fp); return OCPF_SUCCESS; } openchange-2.0/mapicodes_enum.h000066400000000000000000000437321223057412600166360ustar00rootroot00000000000000/* parser auto-generated by mparse */ typedef [public, v1_enum, flag(NDR_PAHEX)] enum { MAPI_E_SUCCESS = 0x00000000, MAPI_E_INTERFACE_NO_SUPPORT = 0x80004002, MAPI_E_CALL_FAILED = 0x80004005, MAPI_E_NO_SUPPORT = 0x80040102, MAPI_E_BAD_CHARWIDTH = 0x80040103, MAPI_E_STRING_TOO_LONG = 0x80040105, MAPI_E_UNKNOWN_FLAGS = 0x80040106, MAPI_E_INVALID_ENTRYID = 0x80040107, MAPI_E_INVALID_OBJECT = 0x80040108, MAPI_E_OBJECT_CHANGED = 0x80040109, MAPI_E_OBJECT_DELETED = 0x8004010A, MAPI_E_BUSY = 0x8004010B, MAPI_E_NOT_ENOUGH_DISK = 0x8004010D, MAPI_E_NOT_ENOUGH_RESOURCES = 0x8004010E, MAPI_E_NOT_FOUND = 0x8004010F, MAPI_E_VERSION = 0x80040110, MAPI_E_LOGON_FAILED = 0x80040111, MAPI_E_SESSION_LIMIT = 0x80040112, MAPI_E_USER_CANCEL = 0x80040113, MAPI_E_UNABLE_TO_ABORT = 0x80040114, MAPI_E_NETWORK_ERROR = 0x80040115, MAPI_E_DISK_ERROR = 0x80040116, MAPI_E_TOO_COMPLEX = 0x80040117, MAPI_E_BAD_COLUMN = 0x80040118, MAPI_E_EXTENDED_ERROR = 0x80040119, MAPI_E_COMPUTED = 0x8004011A, MAPI_E_CORRUPT_DATA = 0x8004011B, MAPI_E_UNCONFIGURED = 0x8004011C, MAPI_E_FAILONEPROVIDER = 0x8004011D, MAPI_E_UNKNOWN_CPID = 0x8004011E, MAPI_E_UNKNOWN_LCID = 0x8004011F, MAPI_E_PASSWORD_CHANGE_REQUIRED = 0x80040120, MAPI_E_PASSWORD_EXPIRED = 0x80040121, MAPI_E_INVALID_WORKSTATION_ACCOUNT = 0x80040122, MAPI_E_INVALID_ACCESS_TIME = 0x80040123, MAPI_E_ACCOUNT_DISABLED = 0x80040124, MAPI_E_END_OF_SESSION = 0x80040200, MAPI_E_UNKNOWN_ENTRYID = 0x80040201, MAPI_E_MISSING_REQUIRED_COLUMN = 0x80040202, MAPI_W_NO_SERVICE = 0x00040203, MAPI_E_BAD_VALUE = 0x80040301, MAPI_E_INVALID_TYPE = 0x80040302, MAPI_E_TYPE_NO_SUPPORT = 0x80040303, MAPI_E_UNEXPECTED_TYPE = 0x80040304, MAPI_E_TOO_BIG = 0x80040305, MAPI_E_DECLINE_COPY = 0x80040306, MAPI_E_UNEXPECTED_ID = 0x80040307, MAPI_W_ERRORS_RETURNED = 0x00040380, MAPI_E_UNABLE_TO_COMPLETE = 0x80040400, MAPI_E_TIMEOUT = 0x80040401, MAPI_E_TABLE_EMPTY = 0x80040402, MAPI_E_TABLE_TOO_BIG = 0x80040403, MAPI_E_INVALID_BOOKMARK = 0x80040405, MAPI_W_POSITION_CHANGED = 0x00040481, MAPI_W_APPROX_COUNT = 0x00040482, MAPI_E_WAIT = 0x80040500, MAPI_E_CANCEL = 0x80040501, MAPI_E_NOT_ME = 0x80040502, MAPI_W_CANCEL_MESSAGE = 0x00040580, MAPI_E_CORRUPT_STORE = 0x80040600, MAPI_E_NOT_IN_QUEUE = 0x80040601, MAPI_E_NO_SUPPRESS = 0x80040602, MAPI_E_COLLISION = 0x80040604, MAPI_E_NOT_INITIALIZED = 0x80040605, MAPI_E_NON_STANDARD = 0x80040606, MAPI_E_NO_RECIPIENTS = 0x80040607, MAPI_E_SUBMITTED = 0x80040608, MAPI_E_HAS_FOLDERS = 0x80040609, MAPI_E_HAS_MESAGES = 0x8004060A, MAPI_E_FOLDER_CYCLE = 0x8004060B, MAPI_E_LOCKID_LIMIT = 0x8004060D, MAPI_W_PARTIAL_COMPLETION = 0x00040680, MAPI_E_AMBIGUOUS_RECIP = 0x80040700, SYNC_E_OBJECT_DELETED = 0x80040800, SYNC_E_IGNORE = 0x80040801, SYNC_E_CONFLICT = 0x80040802, SYNC_E_NO_PARENT = 0x80040803, SYNC_E_CYCLE_DETECTED = 0x80040804, SYNC_E_UNSYNCHRONIZED = 0x80040805, SYNC_W_PROGRESS = 0x00040820, SYNC_W_CLIENT_CHANGE_NEWER = 0x00040821, MAPI_E_NAMED_PROP_QUOTA_EXCEEDED = 0x80040900, MAPI_E_NOT_IMPLEMENTED = 0x80040FFF, MAPI_E_NO_ACCESS = 0x80070005, MAPI_E_NOT_ENOUGH_MEMORY = 0x8007000E, MAPI_E_INVALID_PARAMETER = 0x80070057, ecJetError = 0x000003EA, ecUnknownUser = 0x000003EB, ecExiting = 0x000003ED, ecBadConfig = 0x000003EE, ecUnknownCodePage = 0x000003EF, ecMemory = 0x000003F0, ecLoginPerm = 0x000003F2, ecDatabaseRolledBack = 0x000003F3, ecDatabaseCopiedError = 0x000003F4, ecAuditNotAllowed = 0x000003F5, ecZombieUser = 0x000003F6, ecUnconvertableACL = 0x000003F7, ecNoFreeJses = 0x0000044C, ecDifferentJses = 0x0000044D, ecFileRemove = 0x0000044F, ecParameterOverflow = 0x00000450, ecBadVersion = 0x00000451, ecTooManyCols = 0x00000452, ecHaveMore = 0x00000453, ecDatabaseError = 0x00000454, ecIndexNameTooBig = 0x00000455, ecUnsupportedProp = 0x00000456, ecMsgNotSaved = 0x00000457, ecUnpubNotif = 0x00000459, ecDifferentRoot = 0x0000045B, ecBadFolderName = 0x0000045C, ecAttachOpen = 0x0000045D, ecInvClpsState = 0x0000045E, ecSkipMyChildren = 0x0000045F, ecSearchFolder = 0x00000460, ecNotSearchFolder = 0x00000461, ecFolderSetReceive = 0x00000462, ecNoReceiveFolder = 0x00000463, ecNoDelSubmitMsg = 0x00000465, ecInvalidRecips = 0x00000467, ecNoReplicaHere = 0x00000468, ecNoReplicaAvailable = 0x00000469, ecPublicMDB = 0x0000046A, ecNotPublicMDB = 0x0000046B, ecRecordNotFound = 0x0000046C, ecReplConflict = 0x0000046D, ecFxBufferOverrun = 0x00000470, ecFxBufferEmpty = 0x00000471, ecFxPartialValue = 0x00000472, ecFxNoRoom = 0x00000473, ecMaxTimeExpired = 0x00000474, ecDstError = 0x00000475, ecMDBNotInit = 0x00000476, ecWrongServer = 0x00000478, ecBufferTooSmall = 0x0000047D, ecRequiresRefResolve = 0x0000047E, ecServerPaused = 0x0000047F, ecServerBusy = 0x00000480, ecNoSuchLogon = 0x00000481, ecLoadLibFailed = 0x00000482, ecObjAlreadyConfig = 0x00000483, ecObjNotConfig = 0x00000484, ecDataLoss = 0x00000485, ecMaxSendThreadExceeded = 0x00000488, ecFxErrorMarker = 0x00000489, ecNoFreeJtabs = 0x0000048A, ecNotPrivateMDB = 0x0000048B, ecIsintegMDB = 0x0000048C, ecRecoveryMDBMismatch = 0x0000048D, ecTableMayNotBeDeleted = 0x0000048E, ecRpcRegisterIf = 0x000004B1, ecRpcListen = 0x000004B2, ecRpcFormat = 0x000004B6, ecNoCopyTo = 0x000004B7, ecNullObject = 0x000004B9, ecRpcAuthentication = 0x000004BC, ecRpcBadAuthenticationLevel = 0x000004BD, ecNullCommentRestriction = 0x000004BE, ecRulesLoadError = 0x000004CC, ecRulesDelivErr = 0x000004CD, ecRulesParsingErr = 0x000004CE, ecRulesCreateDaeErr = 0x000004CF, ecRulesCreateDamErr = 0x000004D0, ecRulesNoMoveCopyFolder = 0x000004D1, ecRulesNoFolderRights = 0x000004D2, ecMessageTooBig = 0x000004D4, ecFormNotValid = 0x000004D5, ecNotAuthorized = 0x000004D6, ecDeleteMessage = 0x000004D7, ecBounceMessage = 0x000004D8, ecQuotaExceeded = 0x000004D9, ecMaxSubmissionExceeded = 0x000004DA, ecMaxAttachmentExceeded = 0x000004DB, ecSendAsDenied = 0x000004DC, ecShutoffQuotaExceeded = 0x000004DD, ecMaxObjsExceeded = 0x000004DE, ecClientVerDisallowed = 0x000004DF, ecRpcHttpDisallowed = 0x000004E0, ecCachedModeRequired = 0x000004E1, ecFolderNotCleanedUp = 0x000004E3, ecFmtError = 0x000004ED, ecNotExpanded = 0x000004F7, ecNotCollapsed = 0x000004F8, ecLeaf = 0x000004F9, ecUnregisteredNamedProp = 0x000004FA, ecFolderDisabled = 0x000004FB, ecDomainError = 0x000004FC, ecNoCreateRight = 0x000004FF, ecPublicRoot = 0x00000500, ecNoReadRight = 0x00000501, ecNoCreateSubfolderRight = 0x00000502, ecDstNullObject = 0x00000503, ecMsgCycle = 0x00000504, ecTooManyRecips = 0x00000505, ecVirusScanInProgress = 0x0000050A, ecVirusDetected = 0x0000050B, ecMailboxInTransit = 0x0000050C, ecBackupInProgress = 0x0000050D, ecVirusMessageDeleted = 0x0000050E, ecInvalidBackupSequence = 0x0000050F, ecInvalidBackupSize = 0x00000510, ecTooManyBackupsInProgress = 0x00000511, ecRestoreInProgress = 0x00000512, ecDuplicateObject = 0x00000579, ecObjectNotFound = 0x0000057A, ecFixupReplyRule = 0x0000057B, ecTemplateNotFound = 0x0000057C, ecRuleException = 0x0000057D, ecDSNoSuchObject = 0x0000057E, ecMessageAlreadyTombstoned = 0x0000057F, ecRequiresRWTransaction = 0x00000596, ecPaused = 0x0000060E, ecWrongMailbox = 0x00000648, ecChgPassword = 0x0000064C, ecPwdExpired = 0x0000064D, ecInvWkstn = 0x0000064E, ecInvLogonHrs = 0x0000064F, ecAcctDisabled = 0x00000650, ecRuleVersion = 0x000006A4, ecRuleFormat = 0x000006A5, ecRuleSendAsDenied = 0x000006A6, ecNoServerSupport = 0x000006B9, ecLockTimedOut = 0x000006BA, ecObjectLocked = 0x000006BB, ecInvalidLockNamespace = 0x000006BD, ecMessageDeleted = 0x000007D6, ecProtocolDisabled = 0x000007D8, ecClearTextLogonDisabled = 0x000007D9, ecRejected = 0x000007EE, ecAmbiguousAlias = 0x0000089A, ecUnknownMailbox = 0x0000089B, ecExpReserved = 0x000008FC, ecExpParseDepth = 0x000008FD, ecExpFuncArgType = 0x000008FE, ecExpSyntax = 0x000008FF, ecExpBadStrToken = 0x00000900, ecExpBadColToken = 0x00000901, ecExpTypeMismatch = 0x00000902, ecExpOpNotSupported = 0x00000903, ecExpDivByZero = 0x00000904, ecExpUnaryArgType = 0x00000905, ecNotLocked = 0x00000960, ecClientEvent = 0x00000961, ecCorruptEvent = 0x00000965, ecCorruptWatermark = 0x00000966, ecEventError = 0x00000967, ecWatermarkError = 0x00000968, ecNonCanonicalACL = 0x00000969, ecMailboxDisabled = 0x0000096C, ecRulesFolderOverQuota = 0x0000096D, ecADUnavailable = 0x0000096E, ecADError = 0x0000096F, ecADNotFound = 0x00000971, ecADPropertyError = 0x00000972, ecNotEncrypted = 0x00000970, ecRpcServerTooBusy = 0x00000973, ecRpcOutOfMemory = 0x00000974, ecRpcServerOutOfMemory = 0x00000975, ecRpcOutOfResources = 0x00000976, ecRpcServerUnavailable = 0x00000977, ecSecureSubmitError = 0x0000097A, ecEventsDeleted = 0x0000097C, ecSubsystemStopping = 0x0000097D, ecSAUnavailable = 0x0000097E, ecCIStopping = 0x00000A28, ecFxInvalidState = 0x00000A29, ecFxUnexpectedMarker = 0x00000A2A, ecDuplicateDelivery = 0x00000A2B, ecConditionViolation = 0x00000A2C, ecRpcInvalidHandle = 0x00000A2E, ecEventNotFound = 0x00000A2F, MAPI_E_RESERVED = 0xFFFFFFFF } MAPISTATUS; openchange-2.0/mapiproxy/000077500000000000000000000000001223057412600155145ustar00rootroot00000000000000openchange-2.0/mapiproxy/Doxyfile.in000066400000000000000000001743021223057412600176360ustar00rootroot00000000000000# Doxyfile 1.5.7.1 # This file describes the settings to be used by the documentation system # doxygen (www.doxygen.org) for a project # # All text after a hash (#) is considered a comment and will be ignored # The format is: # TAG = value [value, ...] # For lists items can also be appended using: # TAG += value [value, ...] # Values that contain spaces should be placed between quotes (" ") #--------------------------------------------------------------------------- # Project related configuration options #--------------------------------------------------------------------------- # This tag specifies the encoding used for all characters in the config file # that follow. The default is UTF-8 which is also the encoding used for all # text before the first occurrence of this tag. Doxygen uses libiconv (or the # iconv built into libc) for the transcoding. See # http://www.gnu.org/software/libiconv for the list of possible encodings. DOXYFILE_ENCODING = UTF-8 # The PROJECT_NAME tag is a single word (or a sequence of words surrounded # by quotes) that should identify the project. PROJECT_NAME = MAPIProxy # The PROJECT_NUMBER tag can be used to enter a project or revision number. # This could be handy for archiving the generated documentation or # if some version control system is used. PROJECT_NUMBER = @PACKAGE_VERSION@ # The OUTPUT_DIRECTORY tag is used to specify the (relative or absolute) # base path where the generated documentation will be put. # If a relative path is entered, it will be relative to the location # where doxygen was started. If left blank the current directory will be used. OUTPUT_DIRECTORY = apidocs # If the CREATE_SUBDIRS tag is set to YES, then doxygen will create # 4096 sub-directories (in 2 levels) under the output directory of each output # format and will distribute the generated files over these directories. # Enabling this option can be useful when feeding doxygen a huge amount of # source files, where putting all generated files in the same directory would # otherwise cause performance problems for the file system. CREATE_SUBDIRS = NO # The OUTPUT_LANGUAGE tag is used to specify the language in which all # documentation generated by doxygen is written. Doxygen will use this # information to generate all constant output in the proper language. # The default language is English, other supported languages are: # Afrikaans, Arabic, Brazilian, Catalan, Chinese, Chinese-Traditional, # Croatian, Czech, Danish, Dutch, Farsi, Finnish, French, German, Greek, # Hungarian, Italian, Japanese, Japanese-en (Japanese with English messages), # Korean, Korean-en, Lithuanian, Norwegian, Macedonian, Persian, Polish, # Portuguese, Romanian, Russian, Serbian, Serbian-Cyrilic, Slovak, Slovene, # Spanish, Swedish, and Ukrainian. OUTPUT_LANGUAGE = English # If the BRIEF_MEMBER_DESC tag is set to YES (the default) Doxygen will # include brief member descriptions after the members that are listed in # the file and class documentation (similar to JavaDoc). # Set to NO to disable this. BRIEF_MEMBER_DESC = YES # If the REPEAT_BRIEF tag is set to YES (the default) Doxygen will prepend # the brief description of a member or function before the detailed description. # Note: if both HIDE_UNDOC_MEMBERS and BRIEF_MEMBER_DESC are set to NO, the # brief descriptions will be completely suppressed. REPEAT_BRIEF = YES # This tag implements a quasi-intelligent brief description abbreviator # that is used to form the text in various listings. Each string # in this list, if found as the leading text of the brief description, will be # stripped from the text and the result after processing the whole list, is # used as the annotated text. Otherwise, the brief description is used as-is. # If left blank, the following values are used ("$name" is automatically # replaced with the name of the entity): "The $name class" "The $name widget" # "The $name file" "is" "provides" "specifies" "contains" # "represents" "a" "an" "the" ABBREVIATE_BRIEF = # If the ALWAYS_DETAILED_SEC and REPEAT_BRIEF tags are both set to YES then # Doxygen will generate a detailed section even if there is only a brief # description. ALWAYS_DETAILED_SEC = NO # If the INLINE_INHERITED_MEMB tag is set to YES, doxygen will show all # inherited members of a class in the documentation of that class as if those # members were ordinary class members. Constructors, destructors and assignment # operators of the base classes will not be shown. INLINE_INHERITED_MEMB = NO # If the FULL_PATH_NAMES tag is set to YES then Doxygen will prepend the full # path before files name in the file list and in the header files. If set # to NO the shortest path that makes the file name unique will be used. FULL_PATH_NAMES = YES # If the FULL_PATH_NAMES tag is set to YES then the STRIP_FROM_PATH tag # can be used to strip a user-defined part of the path. Stripping is # only done if one of the specified strings matches the left-hand part of # the path. The tag can be used to show relative paths in the file list. # If left blank the directory from which doxygen is run is used as the # path to strip. STRIP_FROM_PATH = # The STRIP_FROM_INC_PATH tag can be used to strip a user-defined part of # the path mentioned in the documentation of a class, which tells # the reader which header file to include in order to use a class. # If left blank only the name of the header file containing the class # definition is used. Otherwise one should specify the include paths that # are normally passed to the compiler using the -I flag. STRIP_FROM_INC_PATH = # If the SHORT_NAMES tag is set to YES, doxygen will generate much shorter # (but less readable) file names. This can be useful is your file systems # doesn't support long names like on DOS, Mac, or CD-ROM. SHORT_NAMES = NO # If the JAVADOC_AUTOBRIEF tag is set to YES then Doxygen # will interpret the first line (until the first dot) of a JavaDoc-style # comment as the brief description. If set to NO, the JavaDoc # comments will behave just like regular Qt-style comments # (thus requiring an explicit @brief command for a brief description.) JAVADOC_AUTOBRIEF = YES # If the QT_AUTOBRIEF tag is set to YES then Doxygen will # interpret the first line (until the first dot) of a Qt-style # comment as the brief description. If set to NO, the comments # will behave just like regular Qt-style comments (thus requiring # an explicit \brief command for a brief description.) QT_AUTOBRIEF = NO # The MULTILINE_CPP_IS_BRIEF tag can be set to YES to make Doxygen # treat a multi-line C++ special comment block (i.e. a block of //! or /// # comments) as a brief description. This used to be the default behaviour. # The new default is to treat a multi-line C++ comment block as a detailed # description. Set this tag to YES if you prefer the old behaviour instead. MULTILINE_CPP_IS_BRIEF = NO # If the INHERIT_DOCS tag is set to YES (the default) then an undocumented # member inherits the documentation from any documented member that it # re-implements. INHERIT_DOCS = YES # If the SEPARATE_MEMBER_PAGES tag is set to YES, then doxygen will produce # a new page for each member. If set to NO, the documentation of a member will # be part of the file/class/namespace that contains it. SEPARATE_MEMBER_PAGES = NO # The TAB_SIZE tag can be used to set the number of spaces in a tab. # Doxygen uses this value to replace tabs by spaces in code fragments. TAB_SIZE = 8 # This tag can be used to specify a number of aliases that acts # as commands in the documentation. An alias has the form "name=value". # For example adding "sideeffect=\par Side Effects:\n" will allow you to # put the command \sideeffect (or @sideeffect) in the documentation, which # will result in a user-defined paragraph with heading "Side Effects:". # You can put \n's in the value part of an alias to insert newlines. ALIASES = # Set the OPTIMIZE_OUTPUT_FOR_C tag to YES if your project consists of C # sources only. Doxygen will then generate output that is more tailored for C. # For instance, some of the names that are used will be different. The list # of all members will be omitted, etc. OPTIMIZE_OUTPUT_FOR_C = YES # Set the OPTIMIZE_OUTPUT_JAVA tag to YES if your project consists of Java # sources only. Doxygen will then generate output that is more tailored for # Java. For instance, namespaces will be presented as packages, qualified # scopes will look different, etc. OPTIMIZE_OUTPUT_JAVA = NO # Set the OPTIMIZE_FOR_FORTRAN tag to YES if your project consists of Fortran # sources only. Doxygen will then generate output that is more tailored for # Fortran. OPTIMIZE_FOR_FORTRAN = NO # Set the OPTIMIZE_OUTPUT_VHDL tag to YES if your project consists of VHDL # sources. Doxygen will then generate output that is tailored for # VHDL. OPTIMIZE_OUTPUT_VHDL = NO # If you use STL classes (i.e. std::string, std::vector, etc.) but do not want # to include (a tag file for) the STL sources as input, then you should # set this tag to YES in order to let doxygen match functions declarations and # definitions whose arguments contain STL classes (e.g. func(std::string); v.s. # func(std::string) {}). This also make the inheritance and collaboration # diagrams that involve STL classes more complete and accurate. BUILTIN_STL_SUPPORT = NO # If you use Microsoft's C++/CLI language, you should set this option to YES to # enable parsing support. CPP_CLI_SUPPORT = NO # Set the SIP_SUPPORT tag to YES if your project consists of sip sources only. # Doxygen will parse them like normal C++ but will assume all classes use public # instead of private inheritance when no explicit protection keyword is present. SIP_SUPPORT = NO # For Microsoft's IDL there are propget and propput attributes to indicate getter # and setter methods for a property. Setting this option to YES (the default) # will make doxygen to replace the get and set methods by a property in the # documentation. This will only work if the methods are indeed getting or # setting a simple type. If this is not the case, or you want to show the # methods anyway, you should set this option to NO. IDL_PROPERTY_SUPPORT = YES # If member grouping is used in the documentation and the DISTRIBUTE_GROUP_DOC # tag is set to YES, then doxygen will reuse the documentation of the first # member in the group (if any) for the other members of the group. By default # all members of a group must be documented explicitly. DISTRIBUTE_GROUP_DOC = NO # Set the SUBGROUPING tag to YES (the default) to allow class member groups of # the same type (for instance a group of public functions) to be put as a # subgroup of that type (e.g. under the Public Functions section). Set it to # NO to prevent subgrouping. Alternatively, this can be done per class using # the \nosubgrouping command. SUBGROUPING = YES # When TYPEDEF_HIDES_STRUCT is enabled, a typedef of a struct, union, or enum # is documented as struct, union, or enum with the name of the typedef. So # typedef struct TypeS {} TypeT, will appear in the documentation as a struct # with name TypeT. When disabled the typedef will appear as a member of a file, # namespace, or class. And the struct will be named TypeS. This can typically # be useful for C code in case the coding convention dictates that all compound # types are typedef'ed and only the typedef is referenced, never the tag name. TYPEDEF_HIDES_STRUCT = NO # The SYMBOL_CACHE_SIZE determines the size of the internal cache use to # determine which symbols to keep in memory and which to flush to disk. # When the cache is full, less often used symbols will be written to disk. # For small to medium size projects (<1000 input files) the default value is # probably good enough. For larger projects a too small cache size can cause # doxygen to be busy swapping symbols to and from disk most of the time # causing a significant performance penality. # If the system has enough physical memory increasing the cache will improve the # performance by keeping more symbols in memory. Note that the value works on # a logarithmic scale so increasing the size by one will rougly double the # memory usage. The cache size is given by this formula: # 2^(16+SYMBOL_CACHE_SIZE). The valid range is 0..9, the default is 0, # corresponding to a cache size of 2^16 = 65536 symbols SYMBOL_CACHE_SIZE = 0 #--------------------------------------------------------------------------- # Build related configuration options #--------------------------------------------------------------------------- # If the EXTRACT_ALL tag is set to YES doxygen will assume all entities in # documentation are documented, even if no documentation was available. # Private class members and static file members will be hidden unless # the EXTRACT_PRIVATE and EXTRACT_STATIC tags are set to YES EXTRACT_ALL = NO # If the EXTRACT_PRIVATE tag is set to YES all private members of a class # will be included in the documentation. EXTRACT_PRIVATE = NO # If the EXTRACT_STATIC tag is set to YES all static members of a file # will be included in the documentation. EXTRACT_STATIC = YES # If the EXTRACT_LOCAL_CLASSES tag is set to YES classes (and structs) # defined locally in source files will be included in the documentation. # If set to NO only classes defined in header files are included. EXTRACT_LOCAL_CLASSES = NO # This flag is only useful for Objective-C code. When set to YES local # methods, which are defined in the implementation section but not in # the interface are included in the documentation. # If set to NO (the default) only methods in the interface are included. EXTRACT_LOCAL_METHODS = NO # If this flag is set to YES, the members of anonymous namespaces will be # extracted and appear in the documentation as a namespace called # 'anonymous_namespace{file}', where file will be replaced with the base # name of the file that contains the anonymous namespace. By default # anonymous namespace are hidden. EXTRACT_ANON_NSPACES = NO # If the HIDE_UNDOC_MEMBERS tag is set to YES, Doxygen will hide all # undocumented members of documented classes, files or namespaces. # If set to NO (the default) these members will be included in the # various overviews, but no documentation section is generated. # This option has no effect if EXTRACT_ALL is enabled. HIDE_UNDOC_MEMBERS = YES # If the HIDE_UNDOC_CLASSES tag is set to YES, Doxygen will hide all # undocumented classes that are normally visible in the class hierarchy. # If set to NO (the default) these classes will be included in the various # overviews. This option has no effect if EXTRACT_ALL is enabled. HIDE_UNDOC_CLASSES = YES # If the HIDE_FRIEND_COMPOUNDS tag is set to YES, Doxygen will hide all # friend (class|struct|union) declarations. # If set to NO (the default) these declarations will be included in the # documentation. HIDE_FRIEND_COMPOUNDS = YES # If the HIDE_IN_BODY_DOCS tag is set to YES, Doxygen will hide any # documentation blocks found inside the body of a function. # If set to NO (the default) these blocks will be appended to the # function's detailed documentation block. HIDE_IN_BODY_DOCS = NO # The INTERNAL_DOCS tag determines if documentation # that is typed after a \internal command is included. If the tag is set # to NO (the default) then the documentation will be excluded. # Set it to YES to include the internal documentation. INTERNAL_DOCS = NO # If the CASE_SENSE_NAMES tag is set to NO then Doxygen will only generate # file names in lower-case letters. If set to YES upper-case letters are also # allowed. This is useful if you have classes or files whose names only differ # in case and if your file system supports case sensitive file names. Windows # and Mac users are advised to set this option to NO. CASE_SENSE_NAMES = YES # If the HIDE_SCOPE_NAMES tag is set to NO (the default) then Doxygen # will show members with their full class and namespace scopes in the # documentation. If set to YES the scope will be hidden. HIDE_SCOPE_NAMES = NO # If the SHOW_INCLUDE_FILES tag is set to YES (the default) then Doxygen # will put a list of the files that are included by a file in the documentation # of that file. SHOW_INCLUDE_FILES = YES # If the INLINE_INFO tag is set to YES (the default) then a tag [inline] # is inserted in the documentation for inline members. INLINE_INFO = YES # If the SORT_MEMBER_DOCS tag is set to YES (the default) then doxygen # will sort the (detailed) documentation of file and class members # alphabetically by member name. If set to NO the members will appear in # declaration order. SORT_MEMBER_DOCS = YES # If the SORT_BRIEF_DOCS tag is set to YES then doxygen will sort the # brief documentation of file, namespace and class members alphabetically # by member name. If set to NO (the default) the members will appear in # declaration order. SORT_BRIEF_DOCS = YES # If the SORT_GROUP_NAMES tag is set to YES then doxygen will sort the # hierarchy of group names into alphabetical order. If set to NO (the default) # the group names will appear in their defined order. SORT_GROUP_NAMES = NO # If the SORT_BY_SCOPE_NAME tag is set to YES, the class list will be # sorted by fully-qualified names, including namespaces. If set to # NO (the default), the class list will be sorted only by class name, # not including the namespace part. # Note: This option is not very useful if HIDE_SCOPE_NAMES is set to YES. # Note: This option applies only to the class list, not to the # alphabetical list. SORT_BY_SCOPE_NAME = NO # The GENERATE_TODOLIST tag can be used to enable (YES) or # disable (NO) the todo list. This list is created by putting \todo # commands in the documentation. GENERATE_TODOLIST = YES # The GENERATE_TESTLIST tag can be used to enable (YES) or # disable (NO) the test list. This list is created by putting \test # commands in the documentation. GENERATE_TESTLIST = YES # The GENERATE_BUGLIST tag can be used to enable (YES) or # disable (NO) the bug list. This list is created by putting \bug # commands in the documentation. GENERATE_BUGLIST = YES # The GENERATE_DEPRECATEDLIST tag can be used to enable (YES) or # disable (NO) the deprecated list. This list is created by putting # \deprecated commands in the documentation. GENERATE_DEPRECATEDLIST= YES # The ENABLED_SECTIONS tag can be used to enable conditional # documentation sections, marked by \if sectionname ... \endif. ENABLED_SECTIONS = # The MAX_INITIALIZER_LINES tag determines the maximum number of lines # the initial value of a variable or define consists of for it to appear in # the documentation. If the initializer consists of more lines than specified # here it will be hidden. Use a value of 0 to hide initializers completely. # The appearance of the initializer of individual variables and defines in the # documentation can be controlled using \showinitializer or \hideinitializer # command in the documentation regardless of this setting. MAX_INITIALIZER_LINES = 30 # Set the SHOW_USED_FILES tag to NO to disable the list of files generated # at the bottom of the documentation of classes and structs. If set to YES the # list will mention the files that were used to generate the documentation. SHOW_USED_FILES = YES # If the sources in your project are distributed over multiple directories # then setting the SHOW_DIRECTORIES tag to YES will show the directory hierarchy # in the documentation. The default is NO. SHOW_DIRECTORIES = NO # Set the SHOW_FILES tag to NO to disable the generation of the Files page. # This will remove the Files entry from the Quick Index and from the # Folder Tree View (if specified). The default is YES. SHOW_FILES = YES # Set the SHOW_NAMESPACES tag to NO to disable the generation of the # Namespaces page. This will remove the Namespaces entry from the Quick Index # and from the Folder Tree View (if specified). The default is YES. SHOW_NAMESPACES = YES # The FILE_VERSION_FILTER tag can be used to specify a program or script that # doxygen should invoke to get the current version for each file (typically from # the version control system). Doxygen will invoke the program by executing (via # popen()) the command , where is the value of # the FILE_VERSION_FILTER tag, and is the name of an input file # provided by doxygen. Whatever the program writes to standard output # is used as the file version. See the manual for examples. FILE_VERSION_FILTER = # The LAYOUT_FILE tag can be used to specify a layout file which will be parsed by # doxygen. The layout file controls the global structure of the generated output files # in an output format independent way. The create the layout file that represents # doxygen's defaults, run doxygen with the -l option. You can optionally specify a # file name after the option, if omitted DoxygenLayout.xml will be used as the name # of the layout file. LAYOUT_FILE = #--------------------------------------------------------------------------- # configuration options related to warning and progress messages #--------------------------------------------------------------------------- # The QUIET tag can be used to turn on/off the messages that are generated # by doxygen. Possible values are YES and NO. If left blank NO is used. QUIET = NO # The WARNINGS tag can be used to turn on/off the warning messages that are # generated by doxygen. Possible values are YES and NO. If left blank # NO is used. WARNINGS = YES # If WARN_IF_UNDOCUMENTED is set to YES, then doxygen will generate warnings # for undocumented members. If EXTRACT_ALL is set to YES then this flag will # automatically be disabled. WARN_IF_UNDOCUMENTED = YES # If WARN_IF_DOC_ERROR is set to YES, doxygen will generate warnings for # potential errors in the documentation, such as not documenting some # parameters in a documented function, or documenting parameters that # don't exist or using markup commands wrongly. WARN_IF_DOC_ERROR = YES # This WARN_NO_PARAMDOC option can be abled to get warnings for # functions that are documented, but have no documentation for their parameters # or return value. If set to NO (the default) doxygen will only warn about # wrong or incomplete parameter documentation, but not about the absence of # documentation. WARN_NO_PARAMDOC = NO # The WARN_FORMAT tag determines the format of the warning messages that # doxygen can produce. The string should contain the $file, $line, and $text # tags, which will be replaced by the file and line number from which the # warning originated and the warning text. Optionally the format may contain # $version, which will be replaced by the version of the file (if it could # be obtained via FILE_VERSION_FILTER) WARN_FORMAT = "$file:$line: $text" # The WARN_LOGFILE tag can be used to specify a file to which warning # and error messages should be written. If left blank the output is written # to stderr. WARN_LOGFILE = #--------------------------------------------------------------------------- # configuration options related to the input files #--------------------------------------------------------------------------- # The INPUT tag can be used to specify the files and/or directories that contain # documented source files. You may enter file names like "myfile.cpp" or # directories like "/usr/src/myproject". Separate the files or directories # with spaces. INPUT = mapiproxy \ mapiproxy/documentation \ mapiproxy/modules \ mapiproxy/libmapiproxy \ mapiproxy/libmapiserver \ mapiproxy/servers/default/emsmdb \ mapiproxy/servers/default/nspi \ mapiproxy/servers/default/rfr # This tag can be used to specify the character encoding of the source files # that doxygen parses. Internally doxygen uses the UTF-8 encoding, which is # also the default input encoding. Doxygen uses libiconv (or the iconv built # into libc) for the transcoding. See http://www.gnu.org/software/libiconv for # the list of possible encodings. INPUT_ENCODING = UTF-8 # If the value of the INPUT tag contains directories, you can use the # FILE_PATTERNS tag to specify one or more wildcard pattern (like *.cpp # and *.h) to filter out the source-files in the directories. If left # blank the following patterns are tested: # *.c *.cc *.cxx *.cpp *.c++ *.java *.ii *.ixx *.ipp *.i++ *.inl *.h *.hh *.hxx # *.hpp *.h++ *.idl *.odl *.cs *.php *.php3 *.inc *.m *.mm *.py *.f90 FILE_PATTERNS = *.h \ *.c \ *.doxy # The RECURSIVE tag can be used to turn specify whether or not subdirectories # should be searched for input files as well. Possible values are YES and NO. # If left blank NO is used. RECURSIVE = NO # The EXCLUDE tag can be used to specify files and/or directories that should # excluded from the INPUT source files. This way you can easily exclude a # subdirectory from a directory tree whose root is specified with the INPUT tag. EXCLUDE = *_private.h # The EXCLUDE_SYMLINKS tag can be used select whether or not files or # directories that are symbolic links (a Unix filesystem feature) are excluded # from the input. EXCLUDE_SYMLINKS = NO # If the value of the INPUT tag contains directories, you can use the # EXCLUDE_PATTERNS tag to specify one or more wildcard patterns to exclude # certain files from those directories. Note that the wildcards are matched # against the file with absolute path, so to exclude all test directories # for example use the pattern */test/* EXCLUDE_PATTERNS = *.yy.c \ *_private.h \ ocpf_api.* # The EXCLUDE_SYMBOLS tag can be used to specify one or more symbol names # (namespaces, classes, functions, etc.) that should be excluded from the # output. The symbol name can be a fully qualified name, a word, or if the # wildcard * is used, a substring. Examples: ANamespace, AClass, # AClass::ANamespace, ANamespace::*Test EXCLUDE_SYMBOLS = # The EXAMPLE_PATH tag can be used to specify one or more files or # directories that contain example code fragments that are included (see # the \include command). EXAMPLE_PATH = # If the value of the EXAMPLE_PATH tag contains directories, you can use the # EXAMPLE_PATTERNS tag to specify one or more wildcard pattern (like *.cpp # and *.h) to filter out the source-files in the directories. If left # blank all files are included. EXAMPLE_PATTERNS = # If the EXAMPLE_RECURSIVE tag is set to YES then subdirectories will be # searched for input files to be used with the \include or \dontinclude # commands irrespective of the value of the RECURSIVE tag. # Possible values are YES and NO. If left blank NO is used. EXAMPLE_RECURSIVE = NO # The IMAGE_PATH tag can be used to specify one or more files or # directories that contain image that are included in the documentation (see # the \image command). IMAGE_PATH = doc/doxygen/pictures/ mapiproxy/documentation/pictures # The INPUT_FILTER tag can be used to specify a program that doxygen should # invoke to filter for each input file. Doxygen will invoke the filter program # by executing (via popen()) the command , where # is the value of the INPUT_FILTER tag, and is the name of an # input file. Doxygen will then use the output that the filter program writes # to standard output. If FILTER_PATTERNS is specified, this tag will be # ignored. INPUT_FILTER = "sed \ -e '20,40s/.*\//' \ -e '20,40s/.*\//' \ -e '20,40s/.*\//' \ -e '20,40s/.*\//' \ -e '20,40s/.*\//' \ -e '20,40s/.*\//' \ -e '20,40s/.*\//' \ -e '20,40s/.*\//' \ -e '20,40s/.*\//' \ -e '20,40s/.*\//' \ -e '20,40s/.*\//' \ -e '20,40s/.*\//' \ -e '20,40s/.*\//' \ -e '20,40s/.*\//' \ -e '20,40s/.*\//' \ -e '20,40s/.*\//' \ -e '20,40s/.*\//' \ -e '20,40s/.*\//' \ -e '20,40s/_PUBLIC_//'" # The FILTER_PATTERNS tag can be used to specify filters on a per file pattern # basis. Doxygen will compare the file name with each pattern and apply the # filter if there is a match. The filters are a list of the form: # pattern=filter (like *.cpp=my_cpp_filter). See INPUT_FILTER for further # info on how filters are used. If FILTER_PATTERNS is empty, INPUT_FILTER # is applied to all files. FILTER_PATTERNS = # If the FILTER_SOURCE_FILES tag is set to YES, the input filter (if set using # INPUT_FILTER) will be used to filter the input files when producing source # files to browse (i.e. when SOURCE_BROWSER is set to YES). FILTER_SOURCE_FILES = NO #--------------------------------------------------------------------------- # configuration options related to source browsing #--------------------------------------------------------------------------- # If the SOURCE_BROWSER tag is set to YES then a list of source files will # be generated. Documented entities will be cross-referenced with these sources. # Note: To get rid of all source code in the generated output, make sure also # VERBATIM_HEADERS is set to NO. SOURCE_BROWSER = NO # Setting the INLINE_SOURCES tag to YES will include the body # of functions and classes directly in the documentation. INLINE_SOURCES = NO # Setting the STRIP_CODE_COMMENTS tag to YES (the default) will instruct # doxygen to hide any special comment blocks from generated source code # fragments. Normal C and C++ comments will always remain visible. STRIP_CODE_COMMENTS = YES # If the REFERENCED_BY_RELATION tag is set to YES # then for each documented function all documented # functions referencing it will be listed. REFERENCED_BY_RELATION = YES # If the REFERENCES_RELATION tag is set to YES # then for each documented function all documented entities # called/used by that function will be listed. REFERENCES_RELATION = YES # If the REFERENCES_LINK_SOURCE tag is set to YES (the default) # and SOURCE_BROWSER tag is set to YES, then the hyperlinks from # functions in REFERENCES_RELATION and REFERENCED_BY_RELATION lists will # link to the source code. Otherwise they will link to the documentstion. REFERENCES_LINK_SOURCE = YES # If the USE_HTAGS tag is set to YES then the references to source code # will point to the HTML generated by the htags(1) tool instead of doxygen # built-in source browser. The htags tool is part of GNU's global source # tagging system (see http://www.gnu.org/software/global/global.html). You # will need version 4.8.6 or higher. USE_HTAGS = NO # If the VERBATIM_HEADERS tag is set to YES (the default) then Doxygen # will generate a verbatim copy of the header file for each class for # which an include is specified. Set to NO to disable this. VERBATIM_HEADERS = NO #--------------------------------------------------------------------------- # configuration options related to the alphabetical class index #--------------------------------------------------------------------------- # If the ALPHABETICAL_INDEX tag is set to YES, an alphabetical index # of all compounds will be generated. Enable this if the project # contains a lot of classes, structs, unions or interfaces. ALPHABETICAL_INDEX = NO # If the alphabetical index is enabled (see ALPHABETICAL_INDEX) then # the COLS_IN_ALPHA_INDEX tag can be used to specify the number of columns # in which this list will be split (can be a number in the range [1..20]) COLS_IN_ALPHA_INDEX = 5 # In case all classes in a project start with a common prefix, all # classes will be put under the same header in the alphabetical index. # The IGNORE_PREFIX tag can be used to specify one or more prefixes that # should be ignored while generating the index headers. IGNORE_PREFIX = #--------------------------------------------------------------------------- # configuration options related to the HTML output #--------------------------------------------------------------------------- # If the GENERATE_HTML tag is set to YES (the default) Doxygen will # generate HTML output. GENERATE_HTML = YES # The HTML_OUTPUT tag is used to specify where the HTML docs will be put. # If a relative path is entered the value of OUTPUT_DIRECTORY will be # put in front of it. If left blank `html' will be used as the default path. HTML_OUTPUT = html/mapiproxy # The HTML_FILE_EXTENSION tag can be used to specify the file extension for # each generated HTML page (for example: .htm,.php,.asp). If it is left blank # doxygen will generate files with .html extension. HTML_FILE_EXTENSION = .html # The HTML_HEADER tag can be used to specify a personal HTML header for # each generated HTML page. If it is left blank doxygen will generate a # standard header. HTML_HEADER = doc/doxygen/header.html # The HTML_FOOTER tag can be used to specify a personal HTML footer for # each generated HTML page. If it is left blank doxygen will generate a # standard footer. HTML_FOOTER = doc/doxygen/footer.html # The HTML_STYLESHEET tag can be used to specify a user-defined cascading # style sheet that is used by each HTML page. It can be used to # fine-tune the look of the HTML output. If the tag is left blank doxygen # will generate a default style sheet. Note that doxygen will try to copy # the style sheet file to the HTML output directory, so don't put your own # stylesheet in the HTML output directory as well, or it will be erased! HTML_STYLESHEET = doc/doxygen/apidocs.css # If the HTML_ALIGN_MEMBERS tag is set to YES, the members of classes, # files or namespaces will be aligned in HTML using tables. If set to # NO a bullet list will be used. HTML_ALIGN_MEMBERS = YES # If the HTML_DYNAMIC_SECTIONS tag is set to YES then the generated HTML # documentation will contain sections that can be hidden and shown after the # page has loaded. For this to work a browser that supports # JavaScript and DHTML is required (for instance Mozilla 1.0+, Firefox # Netscape 6.0+, Internet explorer 5.0+, Konqueror, or Safari). HTML_DYNAMIC_SECTIONS = NO # If the GENERATE_DOCSET tag is set to YES, additional index files # will be generated that can be used as input for Apple's Xcode 3 # integrated development environment, introduced with OSX 10.5 (Leopard). # To create a documentation set, doxygen will generate a Makefile in the # HTML output directory. Running make will produce the docset in that # directory and running "make install" will install the docset in # ~/Library/Developer/Shared/Documentation/DocSets so that Xcode will find # it at startup. # See http://developer.apple.com/tools/creatingdocsetswithdoxygen.html for more information. GENERATE_DOCSET = NO # When GENERATE_DOCSET tag is set to YES, this tag determines the name of the # feed. A documentation feed provides an umbrella under which multiple # documentation sets from a single provider (such as a company or product suite) # can be grouped. DOCSET_FEEDNAME = "Doxygen generated docs" # When GENERATE_DOCSET tag is set to YES, this tag specifies a string that # should uniquely identify the documentation set bundle. This should be a # reverse domain-name style string, e.g. com.mycompany.MyDocSet. Doxygen # will append .docset to the name. DOCSET_BUNDLE_ID = org.doxygen.Project # If the GENERATE_HTMLHELP tag is set to YES, additional index files # will be generated that can be used as input for tools like the # Microsoft HTML help workshop to generate a compiled HTML help file (.chm) # of the generated HTML documentation. GENERATE_HTMLHELP = NO # If the GENERATE_HTMLHELP tag is set to YES, the CHM_FILE tag can # be used to specify the file name of the resulting .chm file. You # can add a path in front of the file if the result should not be # written to the html output directory. CHM_FILE = # If the GENERATE_HTMLHELP tag is set to YES, the HHC_LOCATION tag can # be used to specify the location (absolute path including file name) of # the HTML help compiler (hhc.exe). If non-empty doxygen will try to run # the HTML help compiler on the generated index.hhp. HHC_LOCATION = # If the GENERATE_HTMLHELP tag is set to YES, the GENERATE_CHI flag # controls if a separate .chi index file is generated (YES) or that # it should be included in the master .chm file (NO). GENERATE_CHI = NO # If the GENERATE_HTMLHELP tag is set to YES, the CHM_INDEX_ENCODING # is used to encode HtmlHelp index (hhk), content (hhc) and project file # content. CHM_INDEX_ENCODING = # If the GENERATE_HTMLHELP tag is set to YES, the BINARY_TOC flag # controls whether a binary table of contents is generated (YES) or a # normal table of contents (NO) in the .chm file. BINARY_TOC = NO # The TOC_EXPAND flag can be set to YES to add extra items for group members # to the contents of the HTML help documentation and to the tree view. TOC_EXPAND = NO # If the GENERATE_QHP tag is set to YES and both QHP_NAMESPACE and QHP_VIRTUAL_FOLDER # are set, an additional index file will be generated that can be used as input for # Qt's qhelpgenerator to generate a Qt Compressed Help (.qch) of the generated # HTML documentation. GENERATE_QHP = NO # If the QHG_LOCATION tag is specified, the QCH_FILE tag can # be used to specify the file name of the resulting .qch file. # The path specified is relative to the HTML output folder. QCH_FILE = # The QHP_NAMESPACE tag specifies the namespace to use when generating # Qt Help Project output. For more information please see # Qt Help Project / Namespace. QHP_NAMESPACE = org.doxygen.Project # The QHP_VIRTUAL_FOLDER tag specifies the namespace to use when generating # Qt Help Project output. For more information please see # Qt Help Project / Virtual Folders. QHP_VIRTUAL_FOLDER = doc # If the GENERATE_QHP tag is set to YES, the QHG_LOCATION tag can # be used to specify the location of Qt's qhelpgenerator. # If non-empty doxygen will try to run qhelpgenerator on the generated # .qhp file . QHG_LOCATION = # The DISABLE_INDEX tag can be used to turn on/off the condensed index at # top of each HTML page. The value NO (the default) enables the index and # the value YES disables it. DISABLE_INDEX = NO # This tag can be used to set the number of enum values (range [1..20]) # that doxygen will group on one line in the generated HTML documentation. ENUM_VALUES_PER_LINE = 4 # The GENERATE_TREEVIEW tag is used to specify whether a tree-like index # structure should be generated to display hierarchical information. # If the tag value is set to FRAME, a side panel will be generated # containing a tree-like index structure (just like the one that # is generated for HTML Help). For this to work a browser that supports # JavaScript, DHTML, CSS and frames is required (for instance Mozilla 1.0+, # Netscape 6.0+, Internet explorer 5.0+, or Konqueror). Windows users are # probably better off using the HTML help feature. Other possible values # for this tag are: HIERARCHIES, which will generate the Groups, Directories, # and Class Hierarchy pages using a tree view instead of an ordered list; # ALL, which combines the behavior of FRAME and HIERARCHIES; and NONE, which # disables this behavior completely. For backwards compatibility with previous # releases of Doxygen, the values YES and NO are equivalent to FRAME and NONE # respectively. GENERATE_TREEVIEW = NO # If the treeview is enabled (see GENERATE_TREEVIEW) then this tag can be # used to set the initial width (in pixels) of the frame in which the tree # is shown. TREEVIEW_WIDTH = 250 # Use this tag to change the font size of Latex formulas included # as images in the HTML documentation. The default is 10. Note that # when you change the font size after a successful doxygen run you need # to manually remove any form_*.png images from the HTML output directory # to force them to be regenerated. FORMULA_FONTSIZE = 10 #--------------------------------------------------------------------------- # configuration options related to the LaTeX output #--------------------------------------------------------------------------- # If the GENERATE_LATEX tag is set to YES (the default) Doxygen will # generate Latex output. GENERATE_LATEX = NO # The LATEX_OUTPUT tag is used to specify where the LaTeX docs will be put. # If a relative path is entered the value of OUTPUT_DIRECTORY will be # put in front of it. If left blank `latex' will be used as the default path. LATEX_OUTPUT = latex # The LATEX_CMD_NAME tag can be used to specify the LaTeX command name to be # invoked. If left blank `latex' will be used as the default command name. LATEX_CMD_NAME = latex # The MAKEINDEX_CMD_NAME tag can be used to specify the command name to # generate index for LaTeX. If left blank `makeindex' will be used as the # default command name. MAKEINDEX_CMD_NAME = makeindex # If the COMPACT_LATEX tag is set to YES Doxygen generates more compact # LaTeX documents. This may be useful for small projects and may help to # save some trees in general. COMPACT_LATEX = NO # The PAPER_TYPE tag can be used to set the paper type that is used # by the printer. Possible values are: a4, a4wide, letter, legal and # executive. If left blank a4wide will be used. PAPER_TYPE = letter # The EXTRA_PACKAGES tag can be to specify one or more names of LaTeX # packages that should be included in the LaTeX output. EXTRA_PACKAGES = # The LATEX_HEADER tag can be used to specify a personal LaTeX header for # the generated latex document. The header should contain everything until # the first chapter. If it is left blank doxygen will generate a # standard header. Notice: only use this tag if you know what you are doing! LATEX_HEADER = # If the PDF_HYPERLINKS tag is set to YES, the LaTeX that is generated # is prepared for conversion to pdf (using ps2pdf). The pdf file will # contain links (just like the HTML output) instead of page references # This makes the output suitable for online browsing using a pdf viewer. PDF_HYPERLINKS = YES # If the USE_PDFLATEX tag is set to YES, pdflatex will be used instead of # plain latex in the generated Makefile. Set this option to YES to get a # higher quality PDF documentation. USE_PDFLATEX = YES # If the LATEX_BATCHMODE tag is set to YES, doxygen will add the \\batchmode. # command to the generated LaTeX files. This will instruct LaTeX to keep # running if errors occur, instead of asking the user for help. # This option is also used when generating formulas in HTML. LATEX_BATCHMODE = NO # If LATEX_HIDE_INDICES is set to YES then doxygen will not # include the index chapters (such as File Index, Compound Index, etc.) # in the output. LATEX_HIDE_INDICES = NO #--------------------------------------------------------------------------- # configuration options related to the RTF output #--------------------------------------------------------------------------- # If the GENERATE_RTF tag is set to YES Doxygen will generate RTF output # The RTF output is optimized for Word 97 and may not look very pretty with # other RTF readers or editors. GENERATE_RTF = NO # The RTF_OUTPUT tag is used to specify where the RTF docs will be put. # If a relative path is entered the value of OUTPUT_DIRECTORY will be # put in front of it. If left blank `rtf' will be used as the default path. RTF_OUTPUT = rtf # If the COMPACT_RTF tag is set to YES Doxygen generates more compact # RTF documents. This may be useful for small projects and may help to # save some trees in general. COMPACT_RTF = NO # If the RTF_HYPERLINKS tag is set to YES, the RTF that is generated # will contain hyperlink fields. The RTF file will # contain links (just like the HTML output) instead of page references. # This makes the output suitable for online browsing using WORD or other # programs which support those fields. # Note: wordpad (write) and others do not support links. RTF_HYPERLINKS = NO # Load stylesheet definitions from file. Syntax is similar to doxygen's # config file, i.e. a series of assignments. You only have to provide # replacements, missing definitions are set to their default value. RTF_STYLESHEET_FILE = # Set optional variables used in the generation of an rtf document. # Syntax is similar to doxygen's config file. RTF_EXTENSIONS_FILE = #--------------------------------------------------------------------------- # configuration options related to the man page output #--------------------------------------------------------------------------- # If the GENERATE_MAN tag is set to YES (the default) Doxygen will # generate man pages GENERATE_MAN = YES # The MAN_OUTPUT tag is used to specify where the man pages will be put. # If a relative path is entered the value of OUTPUT_DIRECTORY will be # put in front of it. If left blank `man' will be used as the default path. MAN_OUTPUT = man # The MAN_EXTENSION tag determines the extension that is added to # the generated man pages (default is the subroutine's section .3) MAN_EXTENSION = .3 # If the MAN_LINKS tag is set to YES and Doxygen generates man output, # then it will generate one additional man file for each entity # documented in the real man page(s). These additional files # only source the real man page, but without them the man command # would be unable to find the correct page. The default is NO. MAN_LINKS = YES #--------------------------------------------------------------------------- # configuration options related to the XML output #--------------------------------------------------------------------------- # If the GENERATE_XML tag is set to YES Doxygen will # generate an XML file that captures the structure of # the code including all documentation. GENERATE_XML = NO # The XML_OUTPUT tag is used to specify where the XML pages will be put. # If a relative path is entered the value of OUTPUT_DIRECTORY will be # put in front of it. If left blank `xml' will be used as the default path. XML_OUTPUT = xml # The XML_SCHEMA tag can be used to specify an XML schema, # which can be used by a validating XML parser to check the # syntax of the XML files. XML_SCHEMA = # The XML_DTD tag can be used to specify an XML DTD, # which can be used by a validating XML parser to check the # syntax of the XML files. XML_DTD = # If the XML_PROGRAMLISTING tag is set to YES Doxygen will # dump the program listings (including syntax highlighting # and cross-referencing information) to the XML output. Note that # enabling this will significantly increase the size of the XML output. XML_PROGRAMLISTING = YES #--------------------------------------------------------------------------- # configuration options for the AutoGen Definitions output #--------------------------------------------------------------------------- # If the GENERATE_AUTOGEN_DEF tag is set to YES Doxygen will # generate an AutoGen Definitions (see autogen.sf.net) file # that captures the structure of the code including all # documentation. Note that this feature is still experimental # and incomplete at the moment. GENERATE_AUTOGEN_DEF = NO #--------------------------------------------------------------------------- # configuration options related to the Perl module output #--------------------------------------------------------------------------- # If the GENERATE_PERLMOD tag is set to YES Doxygen will # generate a Perl module file that captures the structure of # the code including all documentation. Note that this # feature is still experimental and incomplete at the # moment. GENERATE_PERLMOD = NO # If the PERLMOD_LATEX tag is set to YES Doxygen will generate # the necessary Makefile rules, Perl scripts and LaTeX code to be able # to generate PDF and DVI output from the Perl module output. PERLMOD_LATEX = NO # If the PERLMOD_PRETTY tag is set to YES the Perl module output will be # nicely formatted so it can be parsed by a human reader. This is useful # if you want to understand what is going on. On the other hand, if this # tag is set to NO the size of the Perl module output will be much smaller # and Perl will parse it just the same. PERLMOD_PRETTY = YES # The names of the make variables in the generated doxyrules.make file # are prefixed with the string contained in PERLMOD_MAKEVAR_PREFIX. # This is useful so different doxyrules.make files included by the same # Makefile don't overwrite each other's variables. PERLMOD_MAKEVAR_PREFIX = #--------------------------------------------------------------------------- # Configuration options related to the preprocessor #--------------------------------------------------------------------------- # If the ENABLE_PREPROCESSING tag is set to YES (the default) Doxygen will # evaluate all C-preprocessor directives found in the sources and include # files. ENABLE_PREPROCESSING = YES # If the MACRO_EXPANSION tag is set to YES Doxygen will expand all macro # names in the source code. If set to NO (the default) only conditional # compilation will be performed. Macro expansion can be done in a controlled # way by setting EXPAND_ONLY_PREDEF to YES. MACRO_EXPANSION = NO # If the EXPAND_ONLY_PREDEF and MACRO_EXPANSION tags are both set to YES # then the macro expansion is limited to the macros specified with the # PREDEFINED and EXPAND_AS_DEFINED tags. EXPAND_ONLY_PREDEF = NO # If the SEARCH_INCLUDES tag is set to YES (the default) the includes files # in the INCLUDE_PATH (see below) will be search if a #include is found. SEARCH_INCLUDES = YES # The INCLUDE_PATH tag can be used to specify one or more directories that # contain include files that are not input files but should be processed by # the preprocessor. INCLUDE_PATH = # You can use the INCLUDE_FILE_PATTERNS tag to specify one or more wildcard # patterns (like *.h and *.hpp) to filter out the header-files in the # directories. If left blank, the patterns specified with FILE_PATTERNS will # be used. INCLUDE_FILE_PATTERNS = # The PREDEFINED tag can be used to specify one or more macro names that # are defined before the preprocessor is started (similar to the -D option of # gcc). The argument of the tag is a list of macros of the form: name # or name=definition (no spaces). If the definition and the = are # omitted =1 is assumed. To prevent a macro definition from being # undefined via #undef or recursively expanded use the := operator # instead of the = operator. PREDEFINED = _PUBLIC_ # If the MACRO_EXPANSION and EXPAND_ONLY_PREDEF tags are set to YES then # this tag can be used to specify a list of macro names that should be expanded. # The macro definition that is found in the sources will be used. # Use the PREDEFINED tag if you want to use a different macro definition. EXPAND_AS_DEFINED = # If the SKIP_FUNCTION_MACROS tag is set to YES (the default) then # doxygen's preprocessor will remove all function-like macros that are alone # on a line, have an all uppercase name, and do not end with a semicolon. Such # function macros are typically used for boiler-plate code, and will confuse # the parser if not removed. SKIP_FUNCTION_MACROS = YES #--------------------------------------------------------------------------- # Configuration::additions related to external references #--------------------------------------------------------------------------- # The TAGFILES option can be used to specify one or more tagfiles. # Optionally an initial location of the external documentation # can be added for each tagfile. The format of a tag file without # this location is as follows: # TAGFILES = file1 file2 ... # Adding location for the tag files is done as follows: # TAGFILES = file1=loc1 "file2 = loc2" ... # where "loc1" and "loc2" can be relative or absolute paths or # URLs. If a location is present for each tag, the installdox tool # does not have to be run to correct the links. # Note that each tag file must have a unique name # (where the name does NOT include the path) # If a tag file is not located in the directory in which doxygen # is run, you must also specify the path to the tagfile here. TAGFILES = # When a file name is specified after GENERATE_TAGFILE, doxygen will create # a tag file that is based on the input files it reads. GENERATE_TAGFILE = # If the ALLEXTERNALS tag is set to YES all external classes will be listed # in the class index. If set to NO only the inherited external classes # will be listed. ALLEXTERNALS = NO # If the EXTERNAL_GROUPS tag is set to YES all external groups will be listed # in the modules index. If set to NO, only the current project's groups will # be listed. EXTERNAL_GROUPS = YES # The PERL_PATH should be the absolute path and name of the perl script # interpreter (i.e. the result of `which perl'). PERL_PATH = /usr/bin/perl #--------------------------------------------------------------------------- # Configuration options related to the dot tool #--------------------------------------------------------------------------- # If the CLASS_DIAGRAMS tag is set to YES (the default) Doxygen will # generate a inheritance diagram (in HTML, RTF and LaTeX) for classes with base # or super classes. Setting the tag to NO turns the diagrams off. Note that # this option is superseded by the HAVE_DOT option below. This is only a # fallback. It is recommended to install and use dot, since it yields more # powerful graphs. CLASS_DIAGRAMS = YES # You can define message sequence charts within doxygen comments using the \msc # command. Doxygen will then run the mscgen tool (see # http://www.mcternan.me.uk/mscgen/) to produce the chart and insert it in the # documentation. The MSCGEN_PATH tag allows you to specify the directory where # the mscgen tool resides. If left empty the tool is assumed to be found in the # default search path. MSCGEN_PATH = # If set to YES, the inheritance and collaboration graphs will hide # inheritance and usage relations if the target is undocumented # or is not a class. HIDE_UNDOC_RELATIONS = YES # If you set the HAVE_DOT tag to YES then doxygen will assume the dot tool is # available from the path. This tool is part of Graphviz, a graph visualization # toolkit from AT&T and Lucent Bell Labs. The other options in this section # have no effect if this option is set to NO (the default) HAVE_DOT = NO # By default doxygen will write a font called FreeSans.ttf to the output # directory and reference it in all dot files that doxygen generates. This # font does not include all possible unicode characters however, so when you need # these (or just want a differently looking font) you can specify the font name # using DOT_FONTNAME. You need need to make sure dot is able to find the font, # which can be done by putting it in a standard location or by setting the # DOTFONTPATH environment variable or by setting DOT_FONTPATH to the directory # containing the font. DOT_FONTNAME = FreeSans # The DOT_FONTSIZE tag can be used to set the size of the font of dot graphs. # The default size is 10pt. DOT_FONTSIZE = 10 # By default doxygen will tell dot to use the output directory to look for the # FreeSans.ttf font (which doxygen will put there itself). If you specify a # different font using DOT_FONTNAME you can set the path where dot # can find it using this tag. DOT_FONTPATH = # If the CLASS_GRAPH and HAVE_DOT tags are set to YES then doxygen # will generate a graph for each documented class showing the direct and # indirect inheritance relations. Setting this tag to YES will force the # the CLASS_DIAGRAMS tag to NO. CLASS_GRAPH = YES # If the COLLABORATION_GRAPH and HAVE_DOT tags are set to YES then doxygen # will generate a graph for each documented class showing the direct and # indirect implementation dependencies (inheritance, containment, and # class references variables) of the class with other documented classes. COLLABORATION_GRAPH = YES # If the GROUP_GRAPHS and HAVE_DOT tags are set to YES then doxygen # will generate a graph for groups, showing the direct groups dependencies GROUP_GRAPHS = YES # If the UML_LOOK tag is set to YES doxygen will generate inheritance and # collaboration diagrams in a style similar to the OMG's Unified Modeling # Language. UML_LOOK = NO # If set to YES, the inheritance and collaboration graphs will show the # relations between templates and their instances. TEMPLATE_RELATIONS = NO # If the ENABLE_PREPROCESSING, SEARCH_INCLUDES, INCLUDE_GRAPH, and HAVE_DOT # tags are set to YES then doxygen will generate a graph for each documented # file showing the direct and indirect include dependencies of the file with # other documented files. INCLUDE_GRAPH = YES # If the ENABLE_PREPROCESSING, SEARCH_INCLUDES, INCLUDED_BY_GRAPH, and # HAVE_DOT tags are set to YES then doxygen will generate a graph for each # documented header file showing the documented files that directly or # indirectly include this file. INCLUDED_BY_GRAPH = YES # If the CALL_GRAPH and HAVE_DOT options are set to YES then # doxygen will generate a call dependency graph for every global function # or class method. Note that enabling this option will significantly increase # the time of a run. So in most cases it will be better to enable call graphs # for selected functions only using the \callgraph command. CALL_GRAPH = NO # If the CALLER_GRAPH and HAVE_DOT tags are set to YES then # doxygen will generate a caller dependency graph for every global function # or class method. Note that enabling this option will significantly increase # the time of a run. So in most cases it will be better to enable caller # graphs for selected functions only using the \callergraph command. CALLER_GRAPH = NO # If the GRAPHICAL_HIERARCHY and HAVE_DOT tags are set to YES then doxygen # will graphical hierarchy of all classes instead of a textual one. GRAPHICAL_HIERARCHY = YES # If the DIRECTORY_GRAPH, SHOW_DIRECTORIES and HAVE_DOT tags are set to YES # then doxygen will show the dependencies a directory has on other directories # in a graphical way. The dependency relations are determined by the #include # relations between the files in the directories. DIRECTORY_GRAPH = YES # The DOT_IMAGE_FORMAT tag can be used to set the image format of the images # generated by dot. Possible values are png, jpg, or gif # If left blank png will be used. DOT_IMAGE_FORMAT = png # The tag DOT_PATH can be used to specify the path where the dot tool can be # found. If left blank, it is assumed the dot tool can be found in the path. DOT_PATH = # The DOTFILE_DIRS tag can be used to specify one or more directories that # contain dot files that are included in the documentation (see the # \dotfile command). DOTFILE_DIRS = # The DOT_GRAPH_MAX_NODES tag can be used to set the maximum number of # nodes that will be shown in the graph. If the number of nodes in a graph # becomes larger than this value, doxygen will truncate the graph, which is # visualized by representing a node as a red box. Note that doxygen if the # number of direct children of the root node in a graph is already larger than # DOT_GRAPH_MAX_NODES then the graph will not be shown at all. Also note # that the size of a graph can be further restricted by MAX_DOT_GRAPH_DEPTH. DOT_GRAPH_MAX_NODES = 50 # The MAX_DOT_GRAPH_DEPTH tag can be used to set the maximum depth of the # graphs generated by dot. A depth value of 3 means that only nodes reachable # from the root by following a path via at most 3 edges will be shown. Nodes # that lay further from the root node will be omitted. Note that setting this # option to 1 or 2 may greatly reduce the computation time needed for large # code bases. Also note that the size of a graph can be further restricted by # DOT_GRAPH_MAX_NODES. Using a depth of 0 means no depth restriction. MAX_DOT_GRAPH_DEPTH = 0 # Set the DOT_TRANSPARENT tag to YES to generate images with a transparent # background. This is disabled by default, because dot on Windows does not # seem to support this out of the box. Warning: Depending on the platform used, # enabling this option may lead to badly anti-aliased labels on the edges of # a graph (i.e. they become hard to read). DOT_TRANSPARENT = NO # Set the DOT_MULTI_TARGETS tag to YES allow dot to generate multiple output # files in one run (i.e. multiple -o and -T options on the command line). This # makes dot run faster, but since only newer versions of dot (>1.8.10) # support this, this feature is disabled by default. DOT_MULTI_TARGETS = NO # If the GENERATE_LEGEND tag is set to YES (the default) Doxygen will # generate a legend page explaining the meaning of the various boxes and # arrows in the dot generated graphs. GENERATE_LEGEND = YES # If the DOT_CLEANUP tag is set to YES (the default) Doxygen will # remove the intermediate dot files that are used to generate # the various graphs. DOT_CLEANUP = YES #--------------------------------------------------------------------------- # Configuration::additions related to the search engine #--------------------------------------------------------------------------- # The SEARCHENGINE tag specifies whether or not a search engine should be # used. If set to NO the values of all tags below this one will be ignored. SEARCHENGINE = NO openchange-2.0/mapiproxy/dcesrv_mapiproxy.c000066400000000000000000000551361223057412600212700ustar00rootroot00000000000000/* MAPI Proxy This proxy is based on dcesrv_remote.c code from Stefan Metzemacher OpenChange Project Copyright (C) Julien Kerihuel 2008-2010 This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see . */ #include "mapiproxy/dcesrv_mapiproxy.h" #include "mapiproxy/dcesrv_mapiproxy_proto.h" #include #include "libmapi/libmapi.h" #include "libmapi/libmapi_private.h" #include static int dispatch_nbr = 0; /** \file dcesrv_mapiproxy.c \brief mapiproxy main file */ static NTSTATUS mapiproxy_op_reply(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx, void *r) { DEBUG(5, ("mapiproxy::mapiproxy_op_reply\n")); return NT_STATUS_OK; } static NTSTATUS mapiproxy_op_connect(struct dcesrv_call_state *dce_call, const struct ndr_interface_table *table, const char *binding) { NTSTATUS status; struct dcesrv_mapiproxy_private *private; const char *user; const char *pass; const char *domain; struct cli_credentials *credentials; bool acquired_creds = false; bool machine_account; DEBUG(5, ("mapiproxy::mapiproxy_op_connect\n")); /* Retrieve the binding string from parametric options if undefined */ if (!binding) { binding = lpcfg_parm_string(dce_call->conn->dce_ctx->lp_ctx, NULL, "dcerpc_mapiproxy", "binding"); if (!binding) { DEBUG(0, ("You must specify a DCE/RPC binding string\n")); return NT_STATUS_INVALID_PARAMETER; } } /* Retrieve parametric options */ machine_account = lpcfg_parm_bool(dce_call->conn->dce_ctx->lp_ctx, NULL, "dcerpc_mapiproxy", "use_machine_account", false); user = lpcfg_parm_string(dce_call->conn->dce_ctx->lp_ctx, NULL, "dcerpc_mapiproxy", "username"); pass = lpcfg_parm_string(dce_call->conn->dce_ctx->lp_ctx, NULL, "dcerpc_mapiproxy", "password"); domain = lpcfg_parm_string(dce_call->conn->dce_ctx->lp_ctx, NULL, "dcerpc_mapiproxy", "domain"); /* Retrieve private mapiproxy data */ private = dce_call->context->private_data; if (user && pass) { DEBUG(5, ("dcerpc_mapiproxy: RPC proxy: Using specified account\n")); credentials = cli_credentials_init(private); if (!credentials) { return NT_STATUS_NO_MEMORY; } cli_credentials_set_conf(credentials, dce_call->conn->dce_ctx->lp_ctx); cli_credentials_set_username(credentials, user, CRED_SPECIFIED); if (domain) { cli_credentials_set_domain(credentials, domain, CRED_SPECIFIED); } cli_credentials_set_password(credentials, pass, CRED_SPECIFIED); } else if (machine_account) { DEBUG(5, ("dcerpc_mapiproxy: RPC proxy: Using machine account\n")); credentials = cli_credentials_init(private); if (!credentials) { return NT_STATUS_NO_MEMORY; } cli_credentials_set_conf(credentials, dce_call->conn->dce_ctx->lp_ctx); if (domain) { cli_credentials_set_domain(credentials, domain, CRED_SPECIFIED); } status = cli_credentials_set_machine_account(credentials, dce_call->conn->dce_ctx->lp_ctx); if (!NT_STATUS_IS_OK(status)) { return status; } } else if (dcesrv_call_credentials(dce_call)) { DEBUG(5, ("dcerpc_mapiproxy: RPC proxy: Using delegated credentials\n")); credentials = dcesrv_call_credentials(dce_call); acquired_creds = true; } else if (private->credentials) { DEBUG(5, ("dcerpc_mapiproxy: RPC proxy: Using acquired deletegated credentials\n")); credentials = private->credentials; acquired_creds = true; } else { DEBUG(1, ("dcerpc_mapiproxy: RPC proxy: You must supply binding, user and password or have delegated credentials\n")); return NT_STATUS_INVALID_PARAMETER; } if (((dce_call->pkt.ptype == DCERPC_PKT_BIND) && dce_call->pkt.u.bind.assoc_group_id) || ((dce_call->pkt.ptype == DCERPC_PKT_ALTER) && dce_call->pkt.u.alter.assoc_group_id)) { struct dcerpc_binding *b; struct composite_context *pipe_conn_req; /* parse binding string to the structure */ status = dcerpc_parse_binding(dce_call->context, binding, &b); if (!NT_STATUS_IS_OK(status)) { DEBUG(0, ("Failed to parse dcerpc binding '%s'\n", binding)); return status; } DEBUG(3, ("Using binding %s\n", dcerpc_binding_string(dce_call->context, b))); switch (dce_call->pkt.ptype) { case DCERPC_PKT_BIND: b->assoc_group_id = dce_call->pkt.u.bind.assoc_group_id; break; case DCERPC_PKT_ALTER: b->assoc_group_id = dce_call->pkt.u.alter.assoc_group_id; break; default: break; } pipe_conn_req = dcerpc_pipe_connect_b_send(dce_call->context, b, table, credentials, dce_call->event_ctx, dce_call->conn->dce_ctx->lp_ctx); status = dcerpc_pipe_connect_b_recv(pipe_conn_req, dce_call->context, &(private->c_pipe)); if (acquired_creds == false) { talloc_free(credentials); } if (!NT_STATUS_IS_OK(status)) { return status; } dce_call->context->assoc_group->id = private->c_pipe->assoc_group_id; } else { status = dcerpc_pipe_connect(dce_call->context, &(private->c_pipe), binding, table, credentials, dce_call->event_ctx, dce_call->conn->dce_ctx->lp_ctx); if (acquired_creds == false) { talloc_free(credentials); } if (!NT_STATUS_IS_OK(status)) { return status; } dce_call->context->assoc_group->id = private->c_pipe->assoc_group_id; } private->connected = true; DEBUG(5, ("dcerpc_mapiproxy: RPC proxy: CONNECTED\n")); return NT_STATUS_OK; } static NTSTATUS mapiproxy_op_bind_proxy(struct dcesrv_call_state *dce_call, const struct dcesrv_interface *iface, uint32_t if_version) { NTSTATUS status = NT_STATUS_OK; const struct ndr_interface_table *table; struct dcesrv_mapiproxy_private *private; bool delegated; /* Retrieve private mapiproxy data */ private = dce_call->context->private_data; table = ndr_table_by_uuid(&iface->syntax_id.uuid); if (!table) { dce_call->fault_code = DCERPC_FAULT_UNK_IF; return NT_STATUS_NET_WRITE_FAULT; } if (dcesrv_call_credentials(dce_call)) { private->credentials = dcesrv_call_credentials(dce_call); DEBUG(5, ("dcerpc_mapiproxy: Delegated credentials acquired\n")); } delegated = lpcfg_parm_bool(dce_call->conn->dce_ctx->lp_ctx, NULL, "dcerpc_mapiproxy", "delegated_auth", false); if (delegated == false) { status = mapiproxy_op_connect(dce_call, table, NULL); } return status; } /** \details This function is called when the client binds to one of the interfaces mapiproxy handles. \param dce_call pointer to the session context \param iface pointer to the dcesrv interface structure with function hooks \param if_version the version of the pipe \return NT_STATUS_OK on success, otherwise NTSTATUS error */ static NTSTATUS mapiproxy_op_bind(struct dcesrv_call_state *dce_call, const struct dcesrv_interface *iface, uint32_t if_version) { struct dcesrv_mapiproxy_private *private; bool server_mode; char *server_id_printable = NULL; server_id_printable = server_id_str(NULL, &(dce_call->conn->server_id)); DEBUG(5, ("mapiproxy::%s: [session = 0x%x] [session server id = %s]\n", __FUNCTION__, dce_call->context->context_id, server_id_printable)); talloc_free(server_id_printable); DEBUG(5, ("mapiproxy::mapiproxy_op_bind: [session = 0x%x] [session server id = 0x%"PRIx64" 0x%x 0x%x]\n", dce_call->context->context_id, dce_call->conn->server_id.pid, dce_call->conn->server_id.task_id, dce_call->conn->server_id.vnn)); /* Retrieve server mode parametric option */ server_mode = lpcfg_parm_bool(dce_call->conn->dce_ctx->lp_ctx, NULL, "dcerpc_mapiproxy", "server", false); /* Initialize private structure */ private = talloc(dce_call->context, struct dcesrv_mapiproxy_private); if (!private) { return NT_STATUS_NO_MEMORY; } private->c_pipe = NULL; private->exchname = NULL; private->server_mode = server_mode; private->connected = false; dce_call->context->private_data = private; if (server_mode == false) { return mapiproxy_op_bind_proxy(dce_call, iface, if_version); } return NT_STATUS_OK; } /** \details Called when the client disconnects from one of the endpoints managed by mapiproxy. \param context pointer to the connection context \param iface pointer to the dcesrv interface structure with function hooks */ static void mapiproxy_op_unbind(struct dcesrv_connection_context *context, const struct dcesrv_interface *iface) { struct dcesrv_mapiproxy_private *private = (struct dcesrv_mapiproxy_private *) context->private_data; DEBUG(5, ("mapiproxy::mapiproxy_op_unbind\n")); mapiproxy_module_unbind(context->conn->server_id, context->context_id); mapiproxy_server_unbind(context->conn->server_id, context->context_id); if (private) { talloc_free(private->c_pipe); talloc_free(private); } talloc_free(context); return; } /** \details This is the function called when mapiproxy receives a request. The request has already been extracted and its information filled into structures \param dce_call pointer to the session context \param mem_ctx pointer to the memory context \param pull pointer on pointer to the ndr_pull structure \param r generic pointer on pointer to the pulled ndr content \return NT_STATUS_OK on success, other NTSTATUS error */ static NTSTATUS mapiproxy_op_ndr_pull(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx, struct ndr_pull *pull, void **r) { NTSTATUS status; enum ndr_err_code ndr_err; const struct ndr_interface_table *table; uint16_t opnum; struct dcesrv_mapiproxy_private *private; DEBUG(5, ("mapiproxy::mapiproxy_op_ndr_pull\n")); private = dce_call->context->private_data; table = (const struct ndr_interface_table *)dce_call->context->iface->private_data; opnum = dce_call->pkt.u.request.opnum; dce_call->fault_code = 0; if (!dcesrv_call_authenticated(dce_call)) { DEBUG(0, ("User is not authenticated, cannot process\n")); dce_call->fault_code = DCERPC_FAULT_OP_RNG_ERROR; return NT_STATUS_NET_WRITE_FAULT; } /* If remote connection bind/auth has been delayed */ if (private->connected == false && private->server_mode == false) { status = mapiproxy_op_connect(dce_call, table, NULL); if (!NT_STATUS_IS_OK(status)) { dce_call->fault_code = DCERPC_FAULT_OP_RNG_ERROR; return NT_STATUS_NET_WRITE_FAULT; } } if (opnum >= table->num_calls) { dce_call->fault_code = DCERPC_FAULT_OP_RNG_ERROR; return NT_STATUS_NET_WRITE_FAULT; } *r = talloc_size(mem_ctx, table->calls[opnum].struct_size); if (!*r) { return NT_STATUS_NO_MEMORY; } /* directly alter the pull struct before it got pulled from ndr */ mapiproxy_module_ndr_pull(dce_call, mem_ctx, pull); ndr_err = table->calls[opnum].ndr_pull(pull, NDR_IN, *r); mapiproxy_module_pull(dce_call, mem_ctx, *r); if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) { DEBUG(0, ("mapiproxy: mapiproxy_ndr_pull: ERROR\n")); dcerpc_log_packet(dce_call->conn->packet_log_dir, table, opnum, NDR_IN, &dce_call->pkt.u.request.stub_and_verifier); dce_call->fault_code = DCERPC_FAULT_NDR; return NT_STATUS_NET_WRITE_FAULT; } return NT_STATUS_OK; } /** \details This is the function called when mapiproxy receive a response. The response has already been extracted and its information filled into structures \param dce_call pointer to the session context \param mem_ctx pointer to the memory context \param push pointer to the ndr_push structure \param r generic pointer to the data pushed \return NT_STATUS_OK on success, otherwise a NTSTATUS error */ static NTSTATUS mapiproxy_op_ndr_push(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx, struct ndr_push *push, const void *r) { struct dcesrv_mapiproxy_private *private; enum ndr_err_code ndr_err; const struct ndr_interface_table *table; /* const struct ndr_interface_call *call; */ uint16_t opnum; /* const char *name; */ DEBUG(5, ("mapiproxy::mapiproxy_op_ndr_push\n")); private = dce_call->context->private_data; table = (const struct ndr_interface_table *)dce_call->context->iface->private_data; opnum = dce_call->pkt.u.request.opnum; /* name = table->calls[opnum].name; */ /* call = &table->calls[opnum]; */ dce_call->fault_code = 0; if (private->server_mode == false) { /* NspiGetProps binding strings replacement */ if ((mapiproxy_server_loaded(NDR_EXCHANGE_NSP_NAME) == false) && table->name && !strcmp(table->name, NDR_EXCHANGE_NSP_NAME)) { switch (opnum) { case NDR_NSPIGETPROPS: mapiproxy_NspiGetProps(dce_call, (struct NspiGetProps *)r); break; case NDR_NSPIQUERYROWS: mapiproxy_NspiQueryRows(dce_call, (struct NspiQueryRows *)r); break; default: break; } } /* RfrGetNewDSA FQDN replacement */ if ((mapiproxy_server_loaded(NDR_EXCHANGE_DS_RFR_NAME) == false) && table->name && !strcmp(table->name, NDR_EXCHANGE_DS_RFR_NAME)) { switch (opnum) { case NDR_RFRGETNEWDSA: mapiproxy_RfrGetNewDSA(dce_call, (struct RfrGetNewDSA *)r); break; default: DEBUG(0, ("exchange_ds_rfr: OTHER DS-RFR CALL DETECTED!\n")); break; } } } mapiproxy_module_push(dce_call, mem_ctx, (void *)r); ndr_err = table->calls[opnum].ndr_push(push, NDR_OUT, r); if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) { DEBUG(0, ("mapiproxy: mapiproxy_ndr_push: ERROR\n")); dce_call->fault_code = DCERPC_FAULT_NDR; return NT_STATUS_NET_WRITE_FAULT; } return NT_STATUS_OK; } /** \details This function is called after the pull but before the push. Moreover it is called before the request is forward to the remote endpoint. \param dce_call pointer to the session context \param mem_ctx pointer to the memory context \param r generic pointer to the call mapped data \return NT_STATUS_OK on success, otherwise NTSTATUS error */ static NTSTATUS mapiproxy_op_dispatch(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx, void *r) { struct dcesrv_mapiproxy_private *private; struct ndr_push *push; enum ndr_err_code ndr_err; struct mapiproxy mapiproxy; const struct ndr_interface_table *table; const struct ndr_interface_call *call; uint16_t opnum; const char *name; NTSTATUS status; int this_dispatch; struct timeval tv; this_dispatch = dispatch_nbr; dispatch_nbr++; gettimeofday(&tv, NULL); DEBUG(5, ("mapiproxy::mapiproxy_op_dispatch: [tv=%lu.%.6lu] [#%d start]\n", tv.tv_sec, tv.tv_usec, this_dispatch)); private = dce_call->context->private_data; table = dce_call->context->iface->private_data; opnum = dce_call->pkt.u.request.opnum; name = table->calls[opnum].name; call = &table->calls[opnum]; mapiproxy.norelay = false; mapiproxy.ahead = false; if (!private) { dce_call->fault_code = DCERPC_FAULT_ACCESS_DENIED; return NT_STATUS_NET_WRITE_FAULT; } DEBUG(5, ("mapiproxy::mapiproxy_op_dispatch: %s(0x%x): %zd bytes\n", table->calls[opnum].name, opnum, table->calls[opnum].struct_size)); if (private->server_mode == false) { if (private->c_pipe->conn->flags & DCERPC_DEBUG_PRINT_IN) { ndr_print_function_debug(call->ndr_print, name, NDR_IN | NDR_SET_VALUES, r); } private->c_pipe->conn->flags |= DCERPC_NDR_REF_ALLOC; } if ((private->server_mode == true) || (mapiproxy_server_loaded(NDR_EXCHANGE_NSP_NAME) == true)) { ndr_print_function_debug(call->ndr_print, name, NDR_IN | NDR_SET_VALUES, r); status = mapiproxy_server_dispatch(dce_call, mem_ctx, r, &mapiproxy); ndr_print_function_debug(call->ndr_print, name, NDR_OUT | NDR_SET_VALUES, r); if (!NT_STATUS_IS_OK(status)) { return NT_STATUS_NET_WRITE_FAULT; } } else { if (table->name && !strcmp(table->name, NDR_EXCHANGE_NSP_NAME)) { if (opnum == NDR_NSPIDNTOMID) { mapiproxy_NspiDNToMId(dce_call, (struct NspiDNToMId *)r); } } } if (private->server_mode == false) { ahead: if (mapiproxy.ahead == true) { push = ndr_push_init_ctx(dce_call); NT_STATUS_HAVE_NO_MEMORY(push); ndr_err = call->ndr_push(push, NDR_OUT, r); if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) { DEBUG(0, ("mapiproxy: mapiproxy_op_dispatch:push: ERROR\n")); dce_call->fault_code = DCERPC_FAULT_NDR; return NT_STATUS_NET_WRITE_FAULT; } } status = mapiproxy_module_dispatch(dce_call, mem_ctx, r, &mapiproxy); if (!NT_STATUS_IS_OK(status)) { private->c_pipe->last_fault_code = dce_call->fault_code; return NT_STATUS_NET_WRITE_FAULT; } private->c_pipe->last_fault_code = 0; if (mapiproxy.norelay == false) { status = dcerpc_binding_handle_call(private->c_pipe->binding_handle, NULL, table, opnum, mem_ctx, r); } dce_call->fault_code = private->c_pipe->last_fault_code; if (dce_call->fault_code != 0 || !NT_STATUS_IS_OK(status)) { DEBUG(0, ("mapiproxy: call[%s] failed with %s! (status = %s)\n", name, dcerpc_errstr(mem_ctx, dce_call->fault_code), nt_errstr(status))); return NT_STATUS_NET_WRITE_FAULT; } if ((dce_call->fault_code == 0) && (private->c_pipe->conn->flags & DCERPC_DEBUG_PRINT_OUT) && mapiproxy.norelay == false) { ndr_print_function_debug(call->ndr_print, name, NDR_OUT | NDR_SET_VALUES, r); } if (mapiproxy.ahead == true) goto ahead; } gettimeofday(&tv, NULL); DEBUG(5, ("mapiproxy::mapiproxy_op_dispatch: [tv=%lu.%.6lu] [#%d end]\n", tv.tv_sec, tv.tv_usec, this_dispatch)); return NT_STATUS_OK; } /** \details Register an endpoint \param dce_ctx pointer to the dcerpc context \param iface pointer to the dcesrv interface with function hooks \return NT_STATUS_OK on success, otherwise NTSTATUS error */ static NTSTATUS mapiproxy_register_one_iface(struct dcesrv_context *dce_ctx, const struct dcesrv_interface *iface) { const struct ndr_interface_table *table = iface->private_data; int i; for (i = 0; i < table->endpoints->count; i++) { NTSTATUS ret; const char *name = table->endpoints->names[i]; ret = dcesrv_interface_register(dce_ctx, name, iface, NULL); if (!NT_STATUS_IS_OK(ret)) { DEBUG(1,("mapiproxy_op_init_server: failed to register endpoint '%s'\n", name)); return ret; } } return NT_STATUS_OK; } /** \details Initializes the server and register emsmdb,nspi and rfr interfaces \param dce_ctx pointer to the dcesrv context \param ep_server pointer to the endpoint server list \return NT_STATUS_OK on success, otherwise NTSTATUS error */ static NTSTATUS mapiproxy_op_init_server(struct dcesrv_context *dce_ctx, const struct dcesrv_endpoint_server *ep_server) { NTSTATUS ret; struct dcesrv_interface iface; char **ifaces; uint32_t i; static bool initialized = false; if (initialized == true) return NT_STATUS_OK; /* Register mapiproxy modules */ ret = mapiproxy_module_init(dce_ctx); NT_STATUS_NOT_OK_RETURN(ret); /* Register mapiproxy servers */ ret = mapiproxy_server_init(dce_ctx); NT_STATUS_NOT_OK_RETURN(ret); ifaces = str_list_make(dce_ctx, lpcfg_parm_string(dce_ctx->lp_ctx, NULL, "dcerpc_mapiproxy", "interfaces"), NULL); for (i = 0; ifaces[i]; i++) { /* Register the interface */ if (!ep_server->interface_by_name(&iface, ifaces[i])) { DEBUG(0, ("mapiproxy_op_init_server: failed to find interface '%s'\n", ifaces[i])); return NT_STATUS_UNSUCCESSFUL; } ret = mapiproxy_register_one_iface(dce_ctx, &iface); if (!NT_STATUS_IS_OK(ret)) { DEBUG(0, ("mapiproxy_op_init_server: failed to register interface '%s'\n", ifaces[i])); return ret; } } initialized = true; return NT_STATUS_OK; } static bool mapiproxy_fill_interface(struct dcesrv_interface *iface, const struct ndr_interface_table *tbl) { iface->name = tbl->name; iface->syntax_id = tbl->syntax_id; iface->bind = mapiproxy_op_bind; iface->unbind = mapiproxy_op_unbind; iface->ndr_pull = mapiproxy_op_ndr_pull; iface->dispatch = mapiproxy_op_dispatch; iface->reply = mapiproxy_op_reply; iface->ndr_push = mapiproxy_op_ndr_push; iface->private_data = tbl; return true; } static bool mapiproxy_op_interface_by_uuid(struct dcesrv_interface *iface, const struct GUID *uuid, uint32_t if_version) { const struct ndr_interface_list *l; for (l = ndr_table_list(); l; l = l->next) { if (l->table->syntax_id.if_version == if_version && GUID_equal(&l->table->syntax_id.uuid, uuid) == 0) { return mapiproxy_fill_interface(iface, l->table); } } return false; } static bool mapiproxy_op_interface_by_name(struct dcesrv_interface *iface, const char *name) { const struct ndr_interface_table *tbl; tbl = ndr_table_by_name(name); if (tbl) { return mapiproxy_fill_interface(iface, tbl); } return false; } /** \details register the mapiproxy endpoint server. \return NT_STATUS_OK on success, otherwise NTSTATUS error */ NTSTATUS dcerpc_server_mapiproxy_init(void) { NTSTATUS ret; struct dcesrv_endpoint_server ep_server; ZERO_STRUCT(ep_server); /* Fill in our name */ ep_server.name = "mapiproxy"; /* Fill in all the operations */ ep_server.init_server = mapiproxy_op_init_server; ep_server.interface_by_uuid = mapiproxy_op_interface_by_uuid; ep_server.interface_by_name = mapiproxy_op_interface_by_name; /* Register ourselves with the DCE/RPC subsystem */ ret = dcerpc_register_ep_server(&ep_server); if (!NT_STATUS_IS_OK(ret)) { DEBUG(0, ("Failed to register 'mapiproxy' endpoint server!")); return ret; } /* Full DCE/RPC interface table needed */ ndr_table_init(); return ret; } /** \details Register mapiproxy dynamic shared object modules This function registers mapiproxy modules located */ /** \details Entry point of mapiproxy dynamic shared object. This function first registers exchange endpoints and ndr tables, then attempts to register the mapiproxy interface. \return NT_STATUS_OK on success, otherwise NT_STATUS_UNSUCCESSFUL; */ NTSTATUS samba_init_module(void) { NTSTATUS status; /* Step1. Register Exchange endpoints */ status = dcerpc_server_exchange_emsmdb_init(); NT_STATUS_NOT_OK_RETURN(status); status = dcerpc_server_exchange_nsp_init(); NT_STATUS_NOT_OK_RETURN(status); status = dcerpc_server_exchange_ds_rfr_init(); NT_STATUS_NOT_OK_RETURN(status); /* Step2. Register Exchange ndr tables */ status = ndr_table_register(&ndr_table_exchange_emsmdb); NT_STATUS_NOT_OK_RETURN(status); status = ndr_table_register(&ndr_table_exchange_nsp); NT_STATUS_NOT_OK_RETURN(status); status = ndr_table_register(&ndr_table_exchange_ds_rfr); NT_STATUS_NOT_OK_RETURN(status); /* Step3. Finally register mapiproxy endpoint */ status = dcerpc_server_mapiproxy_init(); NT_STATUS_NOT_OK_RETURN(status); return NT_STATUS_OK; } /* include server boiler template */ #include "gen_ndr/ndr_exchange_s.c" openchange-2.0/mapiproxy/dcesrv_mapiproxy.h000066400000000000000000000032461223057412600212700ustar00rootroot00000000000000/* MAPI Proxy OpenChange Project Copyright (C) Julien Kerihuel 2008 This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see . */ #ifndef __DCESRV_MAPIPROXY_H__ #define __DCESRV_MAPIPROXY_H__ #ifndef _GNU_SOURCE #define _GNU_SOURCE 1 #endif #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include "gen_ndr/exchange.h" #include "gen_ndr/ndr_exchange.h" #include "mapiproxy/libmapiproxy/libmapiproxy.h" struct dcesrv_mapiproxy_private { struct dcerpc_pipe *c_pipe; char *exchname; bool server_mode; bool connected; struct cli_credentials *credentials; }; enum exchange_handle { EXCHANGE_HANDLE_NSP, EXCHANGE_HANDLE_EMSMDB, EXCHANGE_HANDLE_DS_RFR }; /* Forward declarations */ struct composite_context; #define MAXHOSTNAMELEN 255 #define SERVERNAME "/cn=Servers/cn=" #endif /* !__DCESRV_MAPIPROXY_H__ */ openchange-2.0/mapiproxy/dcesrv_mapiproxy_nspi.c000066400000000000000000000135441223057412600223160ustar00rootroot00000000000000/* MAPI Proxy - NSPI OpenChange Project Copyright (C) Julien Kerihuel 2008 This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see . */ #include "mapiproxy/dcesrv_mapiproxy.h" #include "mapiproxy/dcesrv_mapiproxy_proto.h" #include "libmapi/mapidefs.h" #include "libmapi/property_altnames.h" /** \file dcesrv_mapiproxy_nspi.c \brief NSPI hook functions */ /** \details Retrieve the servername from a DN string \param dn the DN string \return a talloc'd server name */ static char *x500_get_servername(const char *dn) { char *pdn; char *servername; if (!dn) { return NULL; } pdn = strcasestr(dn, SERVERNAME); if (pdn == NULL) return NULL; pdn += strlen(SERVERNAME); servername = strsep(&pdn, "/"); return (talloc_strdup(NULL, servername)); } /** \details This function replaces network address from the binding strings returned by Exchange for the PR_EMS_AB_NETWORK_ADDRESS property and limit the binding strings scope to ncacn_ip_tcp. \param dce_call pointer to the session context \param r pointer to the NspiGetProps structure \return true on success, otherwise false */ bool mapiproxy_NspiGetProps(struct dcesrv_call_state *dce_call, struct NspiGetProps *r) { uint32_t i; uint32_t propID = -1; struct SPropTagArray *SPropTagArray = NULL; struct PropertyRow_r *Row; struct StringArray_r *slpstr; struct PropertyValue_r *lpProp; /* Sanity checks */ if (!r->out.ppRows) return false; if (!(*r->out.ppRows)->cValues) return false; /* Step 1. Find PR_EMS_AB_NETWORK_ADDRESS index */ propID = -1; SPropTagArray = r->in.pPropTags; for (i = 0; i < SPropTagArray->cValues; i++) { if (SPropTagArray->aulPropTag[i] == PR_EMS_AB_NETWORK_ADDRESS) { propID = i; break; } } if (propID == -1) return false; /* Step 2. Retrieve the SLPSTRArray */ Row = *r->out.ppRows; lpProp = &Row->lpProps[propID]; if (!lpProp) return false; if (lpProp->ulPropTag != PR_EMS_AB_NETWORK_ADDRESS) return false; slpstr = &(lpProp->value.MVszA); /* Step 3. Modify Exchange binding strings and only return ncacn_ip_tcp */ slpstr->cValues = 1; slpstr->lppszA[0] = talloc_asprintf(dce_call, "ncacn_ip_tcp:%s.%s", lpcfg_netbios_name(dce_call->conn->dce_ctx->lp_ctx), lpcfg_realm(dce_call->conn->dce_ctx->lp_ctx)); slpstr->lppszA[0] = strlower_talloc(dce_call, slpstr->lppszA[0]); return true; } /** \details This function replaces the Exchange server name with mapiproxy netbios name for the PR_EMS_AB_HOME_MDB property and saves the original name in a global variable for further usage - such as mapiproxy_NspiDNToMId. \param dce_call pointer to the session context \param r pointer to the NspiQueryRows structure \sa mapiproxy_NspiDNToMId */ bool mapiproxy_NspiQueryRows(struct dcesrv_call_state *dce_call, struct NspiQueryRows *r) { struct dcesrv_mapiproxy_private *private; uint32_t i; uint32_t propID = -1; struct SPropTagArray *SPropTagArray = NULL; struct PropertyRowSet_r *RowSet; struct PropertyValue_r *lpProp; char *lpszA; char *exchname; private = dce_call->context->private_data; /* Sanity checks */ if (!r->out.ppRows) return false; if (!(*r->out.ppRows)->cRows) return false; if (!r->in.pPropTags) return false; /* Step 1. Find PR_EMS_AB_HOME_MDB index */ propID = -1; SPropTagArray = r->in.pPropTags; for (i = 0; i < SPropTagArray->cValues; i++) { if (SPropTagArray->aulPropTag[i] == PR_EMS_AB_HOME_MDB) { propID = i; break; } } if (propID == -1) return false; /* Retrieve the lpszA */ RowSet = *r->out.ppRows; lpProp = &(RowSet->aRow->lpProps[propID]); if (!lpProp) return false; if (lpProp->ulPropTag != PR_EMS_AB_HOME_MDB) return false; if (private->exchname) { if (strstr(lpProp->value.lpszA, private->exchname)) { lpProp->value.lpszA = string_sub_talloc((TALLOC_CTX *) dce_call, lpProp->value.lpszA, private->exchname, lpcfg_netbios_name(dce_call->conn->dce_ctx->lp_ctx)); } } else { lpszA = talloc_strdup(dce_call, lpProp->value.lpszA); if ((exchname = x500_get_servername(lpszA))) { private->exchname = talloc_strdup(NULL, exchname); lpProp->value.lpszA = string_sub_talloc((TALLOC_CTX *) dce_call, lpProp->value.lpszA, exchname, lpcfg_netbios_name(dce_call->conn->dce_ctx->lp_ctx)); talloc_free(exchname); } talloc_free(lpszA); } return true; } /** \details This function looks if the server DN string in the request holds the mapiproxy netbios name and replaces it with the original Exchange server one fetched from NspiQueryRows or NspiGetProps. \param dce_call pointer to the session context \param r pointer to the NspiDNToMId structure \return true on success or false if no occurrence of the mapiproxy netbios name was found. */ bool mapiproxy_NspiDNToMId(struct dcesrv_call_state *dce_call, struct NspiDNToMId *r) { struct dcesrv_mapiproxy_private *private; const char *proxyname; uint32_t i; private = dce_call->context->private_data; proxyname = lpcfg_netbios_name(dce_call->conn->dce_ctx->lp_ctx); if (!private->exchname) return false; for (i = 0; i < r->in.pNames->Count; i++) { if (strstr(r->in.pNames->Strings[i], proxyname)) { r->in.pNames->Strings[i] = string_sub_talloc((TALLOC_CTX *) dce_call, r->in.pNames->Strings[i], proxyname, private->exchname); return true; } } return false; } openchange-2.0/mapiproxy/dcesrv_mapiproxy_proto.h000066400000000000000000000242701223057412600225130ustar00rootroot00000000000000/* MAPI Proxy OpenChange Project Copyright (C) Julien Kerihuel 2008 This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see . */ #ifndef __DCESRV_MAPIPROXY_PROTO_H__ #define __DCESRV_MAPIPROXY_PROTO_H__ #ifndef __BEGIN_DECLS #ifdef __cplusplus #define __BEGIN_DECLS extern "C" { #define __END_DECLS } #else #define __BEGIN_DECLS #define __END_DECLS #endif #endif __BEGIN_DECLS /* definitions from dcesrv_mapiproxy.c */ NTSTATUS dcerpc_server_mapiproxy_init(void); NTSTATUS samba_init_module(void); NTSTATUS dcerpc_server_exchange_nsp_init(void); NTSTATUS dcerpc_server_exchange_emsmdb_init(void); /* definitions from dcesrv_mapiproxy_nspi.c */ bool mapiproxy_NspiGetProps(struct dcesrv_call_state *, struct NspiGetProps *); bool mapiproxy_NspiQueryRows(struct dcesrv_call_state *, struct NspiQueryRows *); bool mapiproxy_NspiDNToMId(struct dcesrv_call_state *, struct NspiDNToMId *); /* definitions from dcesrv_mapiproxy_rfr.c */ bool mapiproxy_RfrGetNewDSA(struct dcesrv_call_state *, struct RfrGetNewDSA *); /* init functions definitions from gen_ndr/ndr_exchange_s.c */ NTSTATUS dcerpc_server_exchange_store_admin3_init(void); NTSTATUS dcerpc_server_exchange_store_admin2_init(void); NTSTATUS dcerpc_server_exchange_store_admin1_init(void); NTSTATUS dcerpc_server_exchange_ds_rfr_init(void); NTSTATUS dcerpc_server_exchange_sysatt_cluster_init(void); NTSTATUS dcerpc_server_exchange_system_attendant_init(void); NTSTATUS dcerpc_server_exchange_mta_init(void); NTSTATUS dcerpc_server_exchange_drs_init(void); NTSTATUS dcerpc_server_exchange_xds_init(void); NTSTATUS dcerpc_server_exchange_mta_qadmin_init(void); NTSTATUS dcerpc_server_exchange_store_information_init(void); NTSTATUS dcerpc_server_exchange_nsp_init(void); NTSTATUS dcerpc_server_exchange_emsmdb_init(void); NTSTATUS dcerpc_server_exchange_async_emsmdb_init(void); NTSTATUS dcerpc_server_exchange_unknown_init(void); /* definitions from samba4: librpc/ndr/ndr_table.c */ NTSTATUS ndr_table_init(void); NTSTATUS ndr_table_register(const struct ndr_interface_table *); const struct ndr_interface_table *ndr_table_by_uuid(const struct GUID *); const struct ndr_interface_list *ndr_table_list(void); const struct ndr_interface_table *ndr_table_by_name(const char *); /* The following definitions come from dcesrv_mapiproxy_unused.c */ void dcesrv_ec_store_admin3_dummy(struct dcesrv_call_state *, TALLOC_CTX *,struct ec_store_admin3_dummy *); void dcesrv_ec_store_admin2_dummy(struct dcesrv_call_state *, TALLOC_CTX *,struct ec_store_admin2_dummy *); void dcesrv_ec_store_admin1_dummy(struct dcesrv_call_state *, TALLOC_CTX *,struct ec_store_admin1_dummy *); enum MAPISTATUS dcesrv_RfrGetNewDSA(struct dcesrv_call_state *, TALLOC_CTX *,struct RfrGetNewDSA *); enum MAPISTATUS dcesrv_RfrGetFQDNFromLegacyDN(struct dcesrv_call_state *, TALLOC_CTX *,struct RfrGetFQDNFromLegacyDN *); void dcesrv_sysatt_cluster_dummy(struct dcesrv_call_state *, TALLOC_CTX *,struct sysatt_cluster_dummy *); void dcesrv_sysatt_dummy(struct dcesrv_call_state *, TALLOC_CTX *,struct sysatt_dummy *); void dcesrv_MtaBind(struct dcesrv_call_state *, TALLOC_CTX *,struct MtaBind *); void dcesrv_MtaBindAck(struct dcesrv_call_state *, TALLOC_CTX *,struct MtaBindAck *); void dcesrv_ds_abandon(struct dcesrv_call_state *, TALLOC_CTX *,struct ds_abandon *); void dcesrv_ds_add_entry(struct dcesrv_call_state *, TALLOC_CTX *,struct ds_add_entry *); void dcesrv_ds_bind(struct dcesrv_call_state *, TALLOC_CTX *,struct ds_bind *); void dcesrv_ds_compare(struct dcesrv_call_state *, TALLOC_CTX *,struct ds_compare *); void dcesrv_ds_list(struct dcesrv_call_state *, TALLOC_CTX *,struct ds_list *); void dcesrv_ds_modify_entry(struct dcesrv_call_state *, TALLOC_CTX *,struct ds_modify_entry *); void dcesrv_ds_modify_rdn(struct dcesrv_call_state *, TALLOC_CTX *,struct ds_modify_rdn *); void dcesrv_ds_read(struct dcesrv_call_state *, TALLOC_CTX *,struct ds_read *); void dcesrv_ds_receive_result(struct dcesrv_call_state *, TALLOC_CTX *,struct ds_receive_result *); void dcesrv_ds_remove_entry(struct dcesrv_call_state *, TALLOC_CTX *,struct ds_remove_entry *); void dcesrv_ds_search(struct dcesrv_call_state *, TALLOC_CTX *,struct ds_search *); void dcesrv_ds_unbind(struct dcesrv_call_state *, TALLOC_CTX *,struct ds_unbind *); void dcesrv_ds_wait(struct dcesrv_call_state *, TALLOC_CTX *,struct ds_wait *); void dcesrv_dra_replica_add(struct dcesrv_call_state *, TALLOC_CTX *,struct dra_replica_add *); void dcesrv_dra_replica_delete(struct dcesrv_call_state *, TALLOC_CTX *,struct dra_replica_delete *); void dcesrv_dra_replica_synchronize(struct dcesrv_call_state *, TALLOC_CTX *,struct dra_replica_synchronize *); void dcesrv_dra_reference_update(struct dcesrv_call_state *, TALLOC_CTX *,struct dra_reference_update *); void dcesrv_dra_authorize_replica(struct dcesrv_call_state *, TALLOC_CTX *,struct dra_authorize_replica *); void dcesrv_dra_unauthorize_replica(struct dcesrv_call_state *, TALLOC_CTX *,struct dra_unauthorize_replica *); void dcesrv_dra_adopt(struct dcesrv_call_state *, TALLOC_CTX *,struct dra_adopt *); void dcesrv_dra_set_status(struct dcesrv_call_state *, TALLOC_CTX *,struct dra_set_status *); void dcesrv_dra_modify_entry(struct dcesrv_call_state *, TALLOC_CTX *,struct dra_modify_entry *); void dcesrv_dra_delete_subref(struct dcesrv_call_state *, TALLOC_CTX *,struct dra_delete_subref *); void dcesrv_xds_dummy(struct dcesrv_call_state *, TALLOC_CTX *,struct xds_dummy *); void dcesrv_exchange_mta_qadmin(struct dcesrv_call_state *, TALLOC_CTX *,struct exchange_mta_qadmin *); void dcesrv_exchange_store_information_dummy(struct dcesrv_call_state *, TALLOC_CTX *,struct exchange_store_information_dummy *); /* NSPI protocol functions */ enum MAPISTATUS dcesrv_NspiBind(struct dcesrv_call_state *, TALLOC_CTX *,struct NspiBind *); enum MAPISTATUS dcesrv_NspiUnbind(struct dcesrv_call_state *, TALLOC_CTX *,struct NspiUnbind *); enum MAPISTATUS dcesrv_NspiUpdateStat(struct dcesrv_call_state *, TALLOC_CTX *,struct NspiUpdateStat *); enum MAPISTATUS dcesrv_NspiQueryRows(struct dcesrv_call_state *, TALLOC_CTX *,struct NspiQueryRows *); enum MAPISTATUS dcesrv_NspiSeekEntries(struct dcesrv_call_state *, TALLOC_CTX *,struct NspiSeekEntries *); enum MAPISTATUS dcesrv_NspiGetMatches(struct dcesrv_call_state *, TALLOC_CTX *,struct NspiGetMatches *); enum MAPISTATUS dcesrv_NspiResortRestriction(struct dcesrv_call_state *, TALLOC_CTX *,struct NspiResortRestriction *); enum MAPISTATUS dcesrv_NspiDNToMId(struct dcesrv_call_state *, TALLOC_CTX *,struct NspiDNToMId *); enum MAPISTATUS dcesrv_NspiGetPropList(struct dcesrv_call_state *, TALLOC_CTX *,struct NspiGetPropList *); enum MAPISTATUS dcesrv_NspiGetProps(struct dcesrv_call_state *, TALLOC_CTX *,struct NspiGetProps *); enum MAPISTATUS dcesrv_NspiCompareMIds(struct dcesrv_call_state *, TALLOC_CTX *,struct NspiCompareMIds *); enum MAPISTATUS dcesrv_NspiModProps(struct dcesrv_call_state *, TALLOC_CTX *,struct NspiModProps *); enum MAPISTATUS dcesrv_NspiGetSpecialTable(struct dcesrv_call_state *, TALLOC_CTX *,struct NspiGetSpecialTable *); enum MAPISTATUS dcesrv_NspiGetTemplateInfo(struct dcesrv_call_state *, TALLOC_CTX *,struct NspiGetTemplateInfo *); enum MAPISTATUS dcesrv_NspiModLinkAtt(struct dcesrv_call_state *, TALLOC_CTX *,struct NspiModLinkAtt *); enum MAPISTATUS dcesrv_NspiDeleteEntries(struct dcesrv_call_state *, TALLOC_CTX *,struct NspiDeleteEntries *); enum MAPISTATUS dcesrv_NspiQueryColumns(struct dcesrv_call_state *, TALLOC_CTX *,struct NspiQueryColumns *); enum MAPISTATUS dcesrv_NspiGetNamesFromIDs(struct dcesrv_call_state *, TALLOC_CTX *,struct NspiGetNamesFromIDs *); enum MAPISTATUS dcesrv_NspiGetIDsFromNames(struct dcesrv_call_state *, TALLOC_CTX *,struct NspiGetIDsFromNames *); enum MAPISTATUS dcesrv_NspiResolveNames(struct dcesrv_call_state *, TALLOC_CTX *,struct NspiResolveNames *); enum MAPISTATUS dcesrv_NspiResolveNamesW(struct dcesrv_call_state *, TALLOC_CTX *,struct NspiResolveNamesW *); /* EMSMDB protocol functions */ enum MAPISTATUS dcesrv_EcDoConnect(struct dcesrv_call_state *, TALLOC_CTX *,struct EcDoConnect *); enum MAPISTATUS dcesrv_EcDoDisconnect(struct dcesrv_call_state *, TALLOC_CTX *,struct EcDoDisconnect *); enum MAPISTATUS dcesrv_EcDoRpc(struct dcesrv_call_state *, TALLOC_CTX *,struct EcDoRpc *); void dcesrv_EcGetMoreRpc(struct dcesrv_call_state *, TALLOC_CTX *,struct EcGetMoreRpc *); enum MAPISTATUS dcesrv_EcRRegisterPushNotification(struct dcesrv_call_state *, TALLOC_CTX *,struct EcRRegisterPushNotification *); enum MAPISTATUS dcesrv_EcRUnregisterPushNotification(struct dcesrv_call_state *, TALLOC_CTX *,struct EcRUnregisterPushNotification *); void dcesrv_EcDummyRpc(struct dcesrv_call_state *, TALLOC_CTX *,struct EcDummyRpc *); void dcesrv_EcRGetDCName(struct dcesrv_call_state *, TALLOC_CTX *,struct EcRGetDCName *); void dcesrv_EcRNetGetDCName(struct dcesrv_call_state *, TALLOC_CTX *,struct EcRNetGetDCName *); enum MAPISTATUS dcesrv_EcDoRpcExt(struct dcesrv_call_state *, TALLOC_CTX *,struct EcDoRpcExt *); enum MAPISTATUS dcesrv_EcDoConnectEx(struct dcesrv_call_state *, TALLOC_CTX *, struct EcDoConnectEx *); enum MAPISTATUS dcesrv_EcDoRpcExt2(struct dcesrv_call_state *, TALLOC_CTX *, struct EcDoRpcExt2 *); void dcesrv_EcUnknown0xC(struct dcesrv_call_state *, TALLOC_CTX *, struct EcUnknown0xC *); void dcesrv_EcUnknown0xD(struct dcesrv_call_state *, TALLOC_CTX *, struct EcUnknown0xD *); enum MAPISTATUS dcesrv_EcDoAsyncConnectEx(struct dcesrv_call_state *, TALLOC_CTX *, struct EcDoAsyncConnectEx *); void dcesrv_unknown_dummy(struct dcesrv_call_state *, TALLOC_CTX *,struct unknown_dummy *); /* AsyncEMSMDB protocol function */ enum MAPISTATUS dcesrv_EcDoAsyncWaitEx(struct dcesrv_call_state *, TALLOC_CTX *, struct EcDoAsyncWaitEx *); __END_DECLS #endif /* ! __DCESRV_MAPIPROXY_PROTO_H__ */ openchange-2.0/mapiproxy/dcesrv_mapiproxy_rfr.c000066400000000000000000000026641223057412600221370ustar00rootroot00000000000000/* MAPI Proxy - RFR OpenChange Project Copyright (C) Julien Kerihuel 2008 This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see . */ #include "mapiproxy/dcesrv_mapiproxy.h" #include "mapiproxy/dcesrv_mapiproxy_proto.h" /** \file dcesrv_mapiproxy_rfr.c \brief NSPI Referral hook functions */ /** \details This function replaces the Exchange server FQDN with mapiproxy one. \return true on success, otherwise false */ bool mapiproxy_RfrGetNewDSA(struct dcesrv_call_state *dce_call, struct RfrGetNewDSA *r) { /* Sanity checks */ if (!r->out.ppszServer) return false; *r->out.ppszServer = talloc_asprintf(dce_call, "%s.%s", lpcfg_netbios_name(dce_call->conn->dce_ctx->lp_ctx), lpcfg_realm(dce_call->conn->dce_ctx->lp_ctx)); *r->out.ppszServer = strlower_talloc(dce_call, *r->out.ppszServer); return true; } openchange-2.0/mapiproxy/dcesrv_mapiproxy_unused.c000066400000000000000000000405671223057412600226550ustar00rootroot00000000000000/* MAPI Proxy OpenChange Project Copyright (C) Julien Kerihuel 2008 This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see . */ #define _GNU_SOURCE 1 #include "config.h" #include #include #include #include #include #include #include #include #include #include "gen_ndr/exchange.h" #include #include #include #include "gen_ndr/ndr_exchange.h" #include "mapiproxy/dcesrv_mapiproxy.h" #include "mapiproxy/dcesrv_mapiproxy_proto.h" #include #ifdef HAVE_SYS_CDEFS_H #include #endif /* endpoint server for the exchange_store_admin3 pipe */ /* ec_store_admin3_dummy */ void dcesrv_ec_store_admin3_dummy(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx, struct ec_store_admin3_dummy *r) { DCESRV_FAULT_VOID(DCERPC_FAULT_OP_RNG_ERROR); } /* endpoint server for the exchange_store_admin2 pipe */ /* ec_store_admin2_dummy */ void dcesrv_ec_store_admin2_dummy(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx, struct ec_store_admin2_dummy *r) { DCESRV_FAULT_VOID(DCERPC_FAULT_OP_RNG_ERROR); } /* endpoint server for the exchange_store_admin1 pipe */ /* ec_store_admin1_dummy */ void dcesrv_ec_store_admin1_dummy(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx, struct ec_store_admin1_dummy *r) { DCESRV_FAULT_VOID(DCERPC_FAULT_OP_RNG_ERROR); } /* endpoint server for the exchange_ds_rfr pipe */ /* RfrGetNewDSA */ enum MAPISTATUS dcesrv_RfrGetNewDSA(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx, struct RfrGetNewDSA *r) { DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR); } /* RfrGetFQDNFromLegacyDN */ enum MAPISTATUS dcesrv_RfrGetFQDNFromLegacyDN(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx, struct RfrGetFQDNFromLegacyDN *r) { DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR); } /* endpoint server for the exchange_sysatt_cluster pipe */ /* sysatt_cluster_dummy */ void dcesrv_sysatt_cluster_dummy(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx, struct sysatt_cluster_dummy *r) { DCESRV_FAULT_VOID(DCERPC_FAULT_OP_RNG_ERROR); } /* endpoint server for the exchange_system_attendant pipe */ /* sysatt_dummy */ void dcesrv_sysatt_dummy(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx, struct sysatt_dummy *r) { DCESRV_FAULT_VOID(DCERPC_FAULT_OP_RNG_ERROR); } /* endpoint server for the exchange_mta pipe */ /* MtaBind */ void dcesrv_MtaBind(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx, struct MtaBind *r) { DCESRV_FAULT_VOID(DCERPC_FAULT_OP_RNG_ERROR); } /* MtaBindAck */ void dcesrv_MtaBindAck(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx, struct MtaBindAck *r) { DCESRV_FAULT_VOID(DCERPC_FAULT_OP_RNG_ERROR); } /* endpoint server for the exchange_drs pipe */ /* ds_abandon */ void dcesrv_ds_abandon(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx, struct ds_abandon *r) { DCESRV_FAULT_VOID(DCERPC_FAULT_OP_RNG_ERROR); } /* ds_add_entry */ void dcesrv_ds_add_entry(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx, struct ds_add_entry *r) { DCESRV_FAULT_VOID(DCERPC_FAULT_OP_RNG_ERROR); } /* ds_bind */ void dcesrv_ds_bind(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx, struct ds_bind *r) { DCESRV_FAULT_VOID(DCERPC_FAULT_OP_RNG_ERROR); } /* ds_compare */ void dcesrv_ds_compare(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx, struct ds_compare *r) { DCESRV_FAULT_VOID(DCERPC_FAULT_OP_RNG_ERROR); } /* ds_list */ void dcesrv_ds_list(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx, struct ds_list *r) { DCESRV_FAULT_VOID(DCERPC_FAULT_OP_RNG_ERROR); } /* ds_modify_entry */ void dcesrv_ds_modify_entry(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx, struct ds_modify_entry *r) { DCESRV_FAULT_VOID(DCERPC_FAULT_OP_RNG_ERROR); } /* ds_modify_rdn */ void dcesrv_ds_modify_rdn(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx, struct ds_modify_rdn *r) { DCESRV_FAULT_VOID(DCERPC_FAULT_OP_RNG_ERROR); } /* ds_read */ void dcesrv_ds_read(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx, struct ds_read *r) { DCESRV_FAULT_VOID(DCERPC_FAULT_OP_RNG_ERROR); } /* ds_receive_result */ void dcesrv_ds_receive_result(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx, struct ds_receive_result *r) { DCESRV_FAULT_VOID(DCERPC_FAULT_OP_RNG_ERROR); } /* ds_remove_entry */ void dcesrv_ds_remove_entry(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx, struct ds_remove_entry *r) { DCESRV_FAULT_VOID(DCERPC_FAULT_OP_RNG_ERROR); } /* ds_search */ void dcesrv_ds_search(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx, struct ds_search *r) { DCESRV_FAULT_VOID(DCERPC_FAULT_OP_RNG_ERROR); } /* ds_unbind */ void dcesrv_ds_unbind(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx, struct ds_unbind *r) { DCESRV_FAULT_VOID(DCERPC_FAULT_OP_RNG_ERROR); } /* ds_wait */ void dcesrv_ds_wait(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx, struct ds_wait *r) { DCESRV_FAULT_VOID(DCERPC_FAULT_OP_RNG_ERROR); } /* dra_replica_add */ void dcesrv_dra_replica_add(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx, struct dra_replica_add *r) { DCESRV_FAULT_VOID(DCERPC_FAULT_OP_RNG_ERROR); } /* dra_replica_delete */ void dcesrv_dra_replica_delete(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx, struct dra_replica_delete *r) { DCESRV_FAULT_VOID(DCERPC_FAULT_OP_RNG_ERROR); } /* dra_replica_synchronize */ void dcesrv_dra_replica_synchronize(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx, struct dra_replica_synchronize *r) { DCESRV_FAULT_VOID(DCERPC_FAULT_OP_RNG_ERROR); } /* dra_reference_update */ void dcesrv_dra_reference_update(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx, struct dra_reference_update *r) { DCESRV_FAULT_VOID(DCERPC_FAULT_OP_RNG_ERROR); } /* dra_authorize_replica */ void dcesrv_dra_authorize_replica(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx, struct dra_authorize_replica *r) { DCESRV_FAULT_VOID(DCERPC_FAULT_OP_RNG_ERROR); } /* dra_unauthorize_replica */ void dcesrv_dra_unauthorize_replica(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx, struct dra_unauthorize_replica *r) { DCESRV_FAULT_VOID(DCERPC_FAULT_OP_RNG_ERROR); } /* dra_adopt */ void dcesrv_dra_adopt(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx, struct dra_adopt *r) { DCESRV_FAULT_VOID(DCERPC_FAULT_OP_RNG_ERROR); } /* dra_set_status */ void dcesrv_dra_set_status(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx, struct dra_set_status *r) { DCESRV_FAULT_VOID(DCERPC_FAULT_OP_RNG_ERROR); } /* dra_modify_entry */ void dcesrv_dra_modify_entry(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx, struct dra_modify_entry *r) { DCESRV_FAULT_VOID(DCERPC_FAULT_OP_RNG_ERROR); } /* dra_delete_subref */ void dcesrv_dra_delete_subref(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx, struct dra_delete_subref *r) { DCESRV_FAULT_VOID(DCERPC_FAULT_OP_RNG_ERROR); } /* endpoint server for the exchange_xds pipe */ /* xds_dummy */ void dcesrv_xds_dummy(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx, struct xds_dummy *r) { DCESRV_FAULT_VOID(DCERPC_FAULT_OP_RNG_ERROR); } /* endpoint server for the exchange_mta_qadmin pipe */ /* exchange_mta_qadmin */ void dcesrv_exchange_mta_qadmin(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx, struct exchange_mta_qadmin *r) { DCESRV_FAULT_VOID(DCERPC_FAULT_OP_RNG_ERROR); } /* endpoint server for the exchange_store_information pipe */ /* exchange_store_information_dummy */ void dcesrv_exchange_store_information_dummy(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx, struct exchange_store_information_dummy *r) { DCESRV_FAULT_VOID(DCERPC_FAULT_OP_RNG_ERROR); } /* endpoint server for the exchange_nsp pipe */ /* NspiBind */ enum MAPISTATUS dcesrv_NspiBind(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx, struct NspiBind *r) { DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR); } /* NspiUnbind */ enum MAPISTATUS dcesrv_NspiUnbind(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx, struct NspiUnbind *r) { DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR); } /* NspiUpdateStat */ enum MAPISTATUS dcesrv_NspiUpdateStat(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx, struct NspiUpdateStat *r) { DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR); } /* NspiQueryRows */ enum MAPISTATUS dcesrv_NspiQueryRows(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx, struct NspiQueryRows *r) { DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR); } /* NspiSeekEntries */ enum MAPISTATUS dcesrv_NspiSeekEntries(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx, struct NspiSeekEntries *r) { DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR); } /* NspiGetMatches */ enum MAPISTATUS dcesrv_NspiGetMatches(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx, struct NspiGetMatches *r) { DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR); } /* NspiResortRestriction */ enum MAPISTATUS dcesrv_NspiResortRestriction(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx, struct NspiResortRestriction *r) { DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR); } /* NspiDNToMId */ enum MAPISTATUS dcesrv_NspiDNToMId(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx, struct NspiDNToMId *r) { DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR); } /* NspiGetPropList */ enum MAPISTATUS dcesrv_NspiGetPropList(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx, struct NspiGetPropList *r) { DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR); } /* NspiGetProps */ enum MAPISTATUS dcesrv_NspiGetProps(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx, struct NspiGetProps *r) { DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR); } /* NspiCompareMIds */ enum MAPISTATUS dcesrv_NspiCompareMIds(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx, struct NspiCompareMIds *r) { DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR); } /* NspiModProps */ enum MAPISTATUS dcesrv_NspiModProps(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx, struct NspiModProps *r) { DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR); } /* NspiGetSpecialTable */ enum MAPISTATUS dcesrv_NspiGetSpecialTable(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx, struct NspiGetSpecialTable *r) { DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR); } /* NspiGetTemplateInfo */ enum MAPISTATUS dcesrv_NspiGetTemplateInfo(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx, struct NspiGetTemplateInfo *r) { DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR); } /* NspiModLInkAtt */ enum MAPISTATUS dcesrv_NspiModLinkAtt(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx, struct NspiModLinkAtt *r) { DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR); } /* NspiDeleteEntries */ enum MAPISTATUS dcesrv_NspiDeleteEntries(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx, struct NspiDeleteEntries *r) { DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR); } /* NspiQueryColumns */ enum MAPISTATUS dcesrv_NspiQueryColumns(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx, struct NspiQueryColumns *r) { DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR); } /* NspiGetNamesFromIDs */ enum MAPISTATUS dcesrv_NspiGetNamesFromIDs(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx, struct NspiGetNamesFromIDs *r) { DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR); } /* NspiGetIDsFromNames */ enum MAPISTATUS dcesrv_NspiGetIDsFromNames(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx, struct NspiGetIDsFromNames *r) { DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR); } /* NspiResolveNames */ enum MAPISTATUS dcesrv_NspiResolveNames(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx, struct NspiResolveNames *r) { DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR); } /* NspiResolveNamesW */ enum MAPISTATUS dcesrv_NspiResolveNamesW(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx, struct NspiResolveNamesW *r) { DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR); } /* endpoint server for the exchange_emsmdb pipe */ /* EcDoConnect */ enum MAPISTATUS dcesrv_EcDoConnect(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx, struct EcDoConnect *r) { DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR); } /* EcDoDisconnect */ enum MAPISTATUS dcesrv_EcDoDisconnect(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx, struct EcDoDisconnect *r) { DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR); } /* EcDoRpc */ enum MAPISTATUS dcesrv_EcDoRpc(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx, struct EcDoRpc *r) { DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR); } /* EcGetMoreRpc */ void dcesrv_EcGetMoreRpc(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx, struct EcGetMoreRpc *r) { DCESRV_FAULT_VOID(DCERPC_FAULT_OP_RNG_ERROR); } /* EcRRegisterPushNotification */ enum MAPISTATUS dcesrv_EcRRegisterPushNotification(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx, struct EcRRegisterPushNotification *r) { DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR); } /* EcRUnregisterPushNotification */ enum MAPISTATUS dcesrv_EcRUnregisterPushNotification(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx, struct EcRUnregisterPushNotification *r) { DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR); } /* EcDummyRpc */ void dcesrv_EcDummyRpc(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx, struct EcDummyRpc *r) { DCESRV_FAULT_VOID(DCERPC_FAULT_OP_RNG_ERROR); } /* EcRGetDCName */ void dcesrv_EcRGetDCName(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx, struct EcRGetDCName *r) { DCESRV_FAULT_VOID(DCERPC_FAULT_OP_RNG_ERROR); } /* EcRNetGetDCName */ void dcesrv_EcRNetGetDCName(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx, struct EcRNetGetDCName *r) { DCESRV_FAULT_VOID(DCERPC_FAULT_OP_RNG_ERROR); } /* EcDoRpcExt */ enum MAPISTATUS dcesrv_EcDoRpcExt(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx, struct EcDoRpcExt *r) { DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR); } /* EcDoConnect Ex */ enum MAPISTATUS dcesrv_EcDoConnectEx(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx, struct EcDoConnectEx *r) { DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR); } /* EcDoRpcExt2 */ enum MAPISTATUS dcesrv_EcDoRpcExt2(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx, struct EcDoRpcExt2 *r) { DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR); } /* EcDoUnknown0xc */ void dcesrv_EcUnknown0xC(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx, struct EcUnknown0xC *r) { DCESRV_FAULT_VOID(DCERPC_FAULT_OP_RNG_ERROR); } /* EcDoAsyncConnectEx */ void dcesrv_EcUnknown0xD(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx, struct EcUnknown0xD *r) { DCESRV_FAULT_VOID(DCERPC_FAULT_OP_RNG_ERROR); } /* EcDoAsyncConnectEx */ enum MAPISTATUS dcesrv_EcDoAsyncConnectEx(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx, struct EcDoAsyncConnectEx *r) { DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR); } /* endpoint server for the exchange_async_emsmdb pipe */ enum MAPISTATUS dcesrv_EcDoAsyncWaitEx(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx, struct EcDoAsyncWaitEx *r) { DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR); } /* endpoint server for the exchange_unknown pipe */ /* unknown_dummy */ void dcesrv_unknown_dummy(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx, struct unknown_dummy *r) { DCESRV_FAULT_VOID(DCERPC_FAULT_OP_RNG_ERROR); } openchange-2.0/mapiproxy/documentation/000077500000000000000000000000001223057412600203655ustar00rootroot00000000000000openchange-2.0/mapiproxy/documentation/Mainpage.doxy000066400000000000000000000056001223057412600230140ustar00rootroot00000000000000/** @mainpage The OpenChange Server Reference

Introduction

This is the online reference for configuring mapiproxy and developing with the OpenChange server code: - Users will find documentation on how to setup mapiproxy, mapiproxy modules, openchange server, how to provision samba4 and openchange. User's documentation is tagged with the user icon. - Developers will find documentation on OpenChange server internals, design, architecture, implementation and API references. Developer's documentation is tagged with the box icon.

MAPIProxy documentation

MAPIProxy is an endpoint server for Samba4 which proxies ExchangeRPC traffic from MAPI clients (Outlook, openchangeclient, etc.) to Microsoft Exchange Server (and back). It can either act as a transparent proxy, for hacking, monitoring or debugging purposes or modify traffic on the fly and so provide new features. It is primarily developed for - but not limited to - third-party implementors looking for a development framework they can use for MAPI acceleration purposes.
Link to MAPIProxy documentation:

MAPIStore documentation

MAPIStore is the SAL component of OpenChange server. SAL stands for Storage Abstraction Layer. It is the component used by OpenChange Server to push/get information (messages, folders) to/from storage backends. The following document intends to describe the overall/theoretical SAL behavior and contraints we need to consider when dealing with MAPI/EMSMDB. It also describes the semantics and inner working of its storage backends.
Link to MAPIStore documentation:
*/openchange-2.0/mapiproxy/documentation/mapiproxy-documentation.doxy000066400000000000000000001607131223057412600262010ustar00rootroot00000000000000/** \page mapiproxy-documentation
\section Contents

Revision History

Date Revision Number Author Revision Content
27/11/2010 0.6.3 Brad Hards Fix tracker link and a couple of typos.
03/03/09 0.6.2 Julien Kerihuel Add configuration info for server mode.
01/02/09 0.6.1 Julien Kerihuel Add configuration info for server mode.
04/01/09 0.6 Julien Kerihuel server mode documented, update mapiproxy naming to MAPIProxy.
29/12/08 0.5.5 Julien Kerihuel Add 3 new questions to FAQ section
09/12/08 0.5.4 Julien Kerihuel Add dcesrv:assoc group checking to smb.conf configuration requirements
10/07/08 0.5.3 Julien Kerihuel Rename smbd process to samba session API and update documentation
08/26/08 0.5.2 Julien Kerihuel documentation update on NSPI replacement and new FAQ question added
08/26/08 0.5.1 Julien Kerihuel documentation on NSPI referral added
08/11/08 0.5 Julien Kerihuel unbind hook added, cache module documentation and scenario added
07/23/08 0.4 Julien Kerihuel MAPIProxy API hooks, IDL update, mapiproxy structure description and documentation added for the cache module
06/25/08 0.3.2 Julien Kerihuel Minor installation update
06/04/08 0.3.1 Brad Hards Minor edits
05/27/08 0.3 Julien Kerihuel Available modules section added
05/24/08 0.2 Julien Kerihuel EMSMDB protocol version subsection updated, modules system section added, 5-minute configuration updated
05/15/08 0.1 Julien Kerihuel Initial Revision

1. Introduction

1.1. Purpose and Scope

MAPIProxy is an endpoint server for Samba4 which proxies ExchangeRPC traffic from MAPI clients (Outlook, openchangeclient, etc.) to Microsoft Exchange Server (and back). It can either act as a transparent proxy, for hacking, monitoring or debugging purposes or modify traffic on the fly and so provide new features. It is primarily developed for - but not limited to - third-party implementors looking for a development framework they can use for MAPI acceleration purposes. This project is originally based on dcerpc_remote.c code from Stefan Metzemacher (Samba4 trunk) and is released under GPLv3 or later. It creates a dynamic shared object file which is loaded into samba and uses the Samba configuration file (smb.conf) to set common options.

1.2. General overview

Figure 1. General MAPIProxy network overview
The MAPIProxy traffic can be divided into 3 different parts as described in the figure above:
  • [1] clients to MAPIProxy:
    The origin of a client connect does not have much importance: it can either be an incoming connection from a real MAPI client, a connection relayed from another third-party proxy or another MAPIProxy instance. MAPIProxy runs as an endpoint server registered when samba starts. When the Samba4 endpoint mapper receives an incoming connection asking for one of the ExchangeRPC endpoints: NSPI (Name Service Provider Interface - Address Book) or EMSMDB (Exchange Message Store), the endpoint mapper redirects ExchangeRPC traffic to MAPIProxy which will pull, push and dispatch MAPI operations.
  • [2] MAPIProxy to MAPIProxy:
    The main objective of MAPIProxy is not to directly connect to the remote message server, but rather to relay some kind of modified MAPI traffic to the next MAPIProxy hop. This configuration can be used to add a compression layer between MAPIProxy instances, or to send specific third-party vendor information. However, a proxied connection directly from a MAPI client to an Exchange server (i.e. client-MAPIProxy-server is possible and such a configuration could be used for many other purposes.
  • [3] MAPIProxy to server:
    This last node is responsible for restoring MAPI contents and pushing it to the real Exchange server.

1.3. Bugs and Limitations

If you find bugs, limitations or have features you would like to see included in MAPIProxy, please register on the OpenChange Tracker System and create new tickets.

2. Installation

2.1. Download MAPIProxy

MAPIProxy is only available through SVN at the moment. A tarball release will only be made when we have a stabilized API with a preliminary set of useful features. You will need a SVN client to download openchange (including MAPIProxy). \code $ svn co https://svn.openchange.org/openchange/trunk openchange \endcode

2.2. Samba4 installation

The MAPIProxy implementation requires a very recent Samba4 version in order to run properly. If Samba4 is planned to be installed from scratch for MAPIProxy only, please use the make samba-git compilation rule provided in the build system. This command will automate most part of the samba4 installation process. The only requirement for this step is to have an up to date GIT version installed on the system. \code # make samba-git \endcode When the installation process is finished, a running samba4 installation will be located in /usr/local/samba/. You will possibly be required to run ldconfig before you move to next steps. Please refer to doc/howto.txt for further information on openchange compilation.

2.3. MAPIProxy installation

If you have existing OpenChange DSO in the /usr/local/samba/modules/dcerpc_server/ folder, such as dcesrv_exchange.so, please remove them prior loading samba with MAPIProxy. \code $ ./autogen.sh $ ./configure --prefix=/usr/local/samba $ make # make install # rm -rf /usr/local/samba/modules/dcerpc_server/dcesrv_exchange.so \endcode

3. Configuration

3.1. 5-Minute Configuration

This 5-Minute configuration will help you set up a minimal MAPIProxy using specified credentials and relaying traffic from Outlook clients to a remote Exchange server. This configuration will be performed in three steps:
  • [1] Provision Samba:
    From samba4/source4 directory, run under the root account: \code # ./setup/provision --realm=OPENCHANGE.LOCAL --domain=OPENCHANGE \ --adminpass=openchange --server-role='domain controller' \endcode If you don't have DNS resolution and your realm can't be resolved, samba will be unable to authenticate the user in its user database. You must specify a realm which MAPI clients and MAPIProxy can resolve. If everything works fine, the provisioning script will have created all the databases, populated the AD (Active Directory) and generated a valid smb.conf file.
  • [2] Add a user account:
    In this configuration, we'll set the same credentials both for the user in the windows domain and on the Samba4 server. Let say there is already a user named testuser with its password set to openchange on the Exchange server: \code # ./setup/newuser testuser New Password: openchange \endcode
  • [3] Configure MAPIProxy options:
    In this final step, we only need to customize a small set of parameters:
    • dcerpc endpoint servers:
      MUST include epmapper and mapiproxy separated with comma.
    • dcerpc_mapiproxy:binding:
      This is the binding string used to connect to the remote Exchange server. The format of this string is: transport:address[flags]. In the example below, we'll be using the TCP over IP transport, connect on 192.168.1.1 and add the print flag so MAPI packets get dissected on samba stdout (or logfile).
    • dcerpc_mapiproxy:username and dcerpc_mapiproxy:password:
      The specified credentials we will be using to connect to the remote Exchange server.
    • dcerpc_mapiproxy:domain:
      The Windows domain the remote Exchange server belongs to.
    • dcerpc_mapiproxy:interfaces:
      In our case, we want to relay the whole ExchangeRPC traffic, so we need to load both the EMSMDB and NSP interface. In the meantime, people interested in NSPI proxy only would only have to load the exchange_nsp interface.
    • dcerpc_mapiproxy:modules:
      MAPIProxy provides a stackable modular system which primary objective is to provide developers an API for modules development. In our case we want to activate the downgrade module responsible for the EcDoConnect/EcDoRpc EMSMDB RPC functions negotiation.
    \code [globals] netbios name = MAPIPROXY workgroup = OPENCHANGE realm = OPENCHANGE.LOCAL server role = domain controller ### Configuration required by mapiproxy ### dcesrv:assoc group checking = false dcerpc endpoint servers = epmapper, mapiproxy dcerpc_mapiproxy:binding = ncacn_ip_tcp:192.168.1.1[print] dcerpc_mapiproxy:username = testuser dcerpc_mapiproxy:password = openchange dcerpc_mapiproxy:domain = EXCHANGE dcerpc_mapiproxy:interfaces = exchange_emsmdb, exchange_nsp, exchange_ds_rfr dcerpc_mapiproxy:modules = downgrade ### Configuration required by mapiproxy ### [netlogon] path = /usr/local/samba/var/locks/sysvol/openchange.local/scripts read only = no [sysvol] path = /usr/local/samba/var/locks/sysvol read only = no \endcode
We are now ready to run samba: \code # samba -d5 -i -M single \endcode If everything works properly, the following lines should be displayed in samba output: \code DCERPC endpoint server 'exchange_emsmdb' registered DCERPC endpoint server 'exchange_nsp' registered DCERPC endpoint server 'exchange_ds_rfr' registered DCERPC endpoint server 'mapiproxy' registered dcesrv_interface_register: interface 'epmapper' registered on endpoint 'ncacn_np:[\pipe\epmapper]' dcesrv_interface_register: interface 'epmapper' registered on endpoint 'ncacn_ip_tcp:[135]' dcesrv_interface_register: interface 'epmapper' registered on endpoint 'ncalrpc:[EPMAPPER]' MAPIPROXY module 'downgrade' registered MAPIPROXY module 'downgrade' loaded mapiproxy_module_load 'downgrade' (Downgrade EMSMDB protocol version EcDoConnect/EcDoRpc) dcesrv_interface_register: interface 'exchange_emsmdb' registered on endpoint 'ncacn_np:[\pipe\lsass]' dcesrv_interface_register: interface 'exchange_emsmdb' registered on endpoint 'ncacn_np:[\pipe\protected_storage]' dcesrv_interface_register: interface 'exchange_emsmdb' registered on endpoint 'ncacn_ip_tcp:' dcesrv_interface_register: interface 'exchange_nsp' registered on endpoint 'ncacn_np:[\pipe\lsass]' dcesrv_interface_register: interface 'exchange_nsp' registered on endpoint 'ncacn_np:[\pipe\protected_storage]' dcesrv_interface_register: interface 'exchange_nsp' registered on endpoint 'ncacn_ip_tcp:[]' dcesrv_interface_register: interface 'exchange_ds_rfr' registered on endpoint 'ncacn_np:[\pipe\lsass]' dcesrv_interface_register: interface 'exchange_ds_rfr' registered on endpoint 'ncacn_np:[\pipe\protected_storage]' dcesrv_interface_register: interface 'exchange_ds_rfr' registered on endpoint 'ncacn_ip_tcp:[]' \endcode
You should now be able to configure Outlook to use an Exchange account with the proxy IP address and run Outlook seamlessly (both online or cached exchange mode).

4. Technical Concepts

4.1. NSPI Bindings Replacement

When Outlook sets up an Exchange account using either the mail applet from the configuration panel or the account editor within Outlook, it uses the NSPI protocol (Name Service Provider Interface, effectively the address book provider). In this case, NSPI is used to resolve the Exchange username and fetch from Exchange server all information needed by Outlook to initiate direct connection to the EMSMDB pipe (effectively the message store) the next time it connects to the server.
At some point of the profile's creation process, Outlook queries Exchange for some specific connection information using the NspiGetProps (0x9) RPC operation . More specifically, when Outlook requests for the PR_EMS_AB_NETWORK_ADDRESS MAPI property, Exchange returns a list binding strings. Outlook next stores these binding strings at some location - associated to the Outlook profile - in the windows registry and uses them for future connections.
Outlook can also rely on other information returned by NSPI functions and connect to the real Exchange server rather than MAPIProxy. Such case occurs when Outlook is able to resolve the exchange server using its hostname. This reference to the original Exchange server can be found when Outlook requests for the PR_EMS_AB_HOME_MDB MAPI property during the NspiQueryRows (0x3) RPC operation. MAPIProxy replaces the Exchange server name with its own netbios name and forward the reply to the client.
In the meantime, this information is next used by Outlook to query a minimal entry ID for a distinguished name using this server name. MAPIProxy needs to substitute the server name in the inbound request string with the original exchange one.
MAPIProxy needs to avoid Outlook clients being aware of this remote server address and trying to communicate directly with the remote server instead of using the proxy. In order to do this, MAPIProxy alters the Outlook-Exchange MAPI traffic and replaces these binding strings with the MAPIProxy FQDN and netbios name.

4.2. NSPI Referral Replacement

The Address Book Name Service Provider Interface (NSPI) Referral Service is a service used by Outlook to retrieve the name of an NSPI server. No NSPI connection should be initiated without first querying for the correct NSPI server. In this case, RFR returns the fully qualified domain name of the real Exchange server and starts using it if available.
MAPIProxy needs to avoid Outlook clients being aware of this server address and trying to communicate directly with the remote server instead of using the proxy. In order to do this, MAPIProxy alters the Outlook-Exchange MAPI traffic and replaces the server DN returned by RfrGetNewDSA (0x0) RPC operation with the MAPIProxy realm as specified in smb.conf.

4.3. Force EMSMDB Protocol Version

When Outlook starts and presumably calls MapiLogonEx, it first opens a connection to the Exchange server on the NSPI pipe, then on the EMSMDB pipe. Under Outlook 2003, the very first EMSMDB RPC call Outlook makes can be considered as a kind of protocol version negotiation. Depending on which version of Outlook is used, and how the Exchange server replies to the EMSMDB connect request, Outlook will either keep using the same pool of RPC calls or downgrade. For example Outlook 2003 (default behavior) tests if the remote server supports the 2 new EMSMDB calls (EcDoConnectEx/EcDoRpcExt2) introduced in Exchange 2003. If Exchange replies to the EcDoConnectEx request with a dcerpc_fault, it means the server does not support the RPC operation, presumably has a version before 2003, and Outlook needs to downgrade its version in order to communicate with the server:
  • EcDoConnectEx (0xa) call
    • On success, Outlook will use EcDoRpcExt2 (0xb) to handle MAPI traffic
    • On failure (dcerpc_fault: nca_op_rng_error), Outlook calls EcDoConnect (0x0) and use EcDoRpc (0x2) to handle MAPI traffic
If MAPIProxy runs in an environment with Outlook clients and Exchange servers using a version above 2003, a last step is required to successfully use Outlook. The EcDoConnect RPC reply returns the Exchange server version (as an array of 3 short integers). When Outlook detects this particular server version, it automatically closes the connection and keep requesting indefinitely for EcDoConnectEx. To deal with this, MAPIProxy modifies the EcDoConnect reply sent by Exchange and replaces the server version with a one equal to that sent by Exchange 2000. In the meantime, if we reproduce this test with Outlook 2000 which doesn't support these 2 new RPC calls, Outlook will directly call EcDoConnect. The main difference between the EcDoConnectEx/EcDoRpcExt2 operations and the EcDoConnect/EcDoRpc operations is that the former use both XOR 0xA5 obfuscation and LZ77 compression/Direct2 encoding; while the latter only use the XOR obfuscation to handle MAPI content. If MAPIProxy wants to act as an intelligent proxy (for example, to be able to analyze MAPI content on the fly, compress MAPI data etc), receiving non compressed MAPI traffic would probably improve the overall process. Below is a list of Exchange/Outlook pairs and the EMSMDB connect function they will use by default:
Exchange version Outlook version EMSMDB connect function
5.5/2000 any EcDoConnect (0x0)
2003 2000 EcDoConnect (0x0)
2007 2000 EcDoConnect (0x0)
Microsoft officially says it is unsupported
2003 2003-2007 EcDoConnectEx (0xa)
2007 2003 EcDoConnectEx (0xa)
2007 2007 EcDoConnectEx (0xa)
MAPIProxy reproduces the Exchange 2000 behavior and prevents Outlook from communicating with the Exchange server using the EcDoConnectEx/EcDoRpcExt2 as described in Figure 2 below. When Outlook sends an EcDoConnectEx request, MAPIProxy does not relay the request to the remote Exchange server and immediately returns a dcerpc_fault to Outlook. Outlook, assuming the server doesn't support this call uses EcDoConnect instead. From this call, MAPIProxy relay the information to Exchange.
Figure 2. MAPIProxy behavior on Outlook EMSMDB connection
From the Exchange side, the server will analyze this EcDoConnect request as a call sent by Outlook 2000 or below version. Exchange works fine using this protocol version unless Exchange 2007 SP1 which appears to introduce client version restrictions by default. In the meantime, existing tests demonstrate similar restrictions would apply to Outlook 2003 connection (without MAPIProxy) and prevent Outlook version before 2007 connecting to Exchange 2007. Further information and solution is available at the following addresses:

4.4. OpenChange IDL File

IDL stands for Interface Definition Language and OpenChange uses this format to describe ExchangeRPC communications. This file is processed by pidl (Perl IDL compiler provided by Samba4) which turns this protocol description into C-code dealing with the push, pull and print operations. OpenChange development policy in trunk used to push a new MAPI call in the IDL only when the associated libmapi implementation and mapitest unit is developed, but this was preventing from distributing MAPIProxy with further openchange releases. Furthermore, the OpenChange IDL is now almost complete and merging back to the trunk helps improving libmapi reliability.

5. Stackable Modules

5.1. General Overview

The MAPIProxy stackable modules system provides implementers a development framework to add new features. This stackable mechanism allows developers to write modules with a very specific scope of which modifications will transparently be relayed to the next module until it is finally pushed by MAPIProxy to the next hop (Figure 3.).
Figure 3. MAPIProxy module stack and EcDoRpc interaction
With this system, developers can focus their effort on ExchangeRPC traffic - or any other protocol samba supports - interception, modification, analysis and avoid spending time on implementing a new endpoint server. Furthermore it provides an easier way for implementers to divide the work in smaller units and develop each of them in a separated module.
MAPIProxy modules are dynamic shared objects with an entry point and a limited set of hooks. These modules have to be installed in the dcerpc_mapiproxy folder within the samba4 modules directory (e.g. /usr/local/samba/modules). MAPIProxy modules specified in the Samba configuration file (smb.conf) will be loaded into MAPIProxy at runtime and interact with each other in the same order they were defined: \code dcerpc_mapiproxy:modules = downgrade,dummy \endcode All MAPIProxy modules will be registered but only those specified on the dcerpc_mapiproxy:modules parametric option line will be added to the chained list of effective modules.

5.2. Module entry point

MAPIProxy modules must have an entry point function named samba_init_module. This function needs to set general information about the module, specify the module's hooks and finally call the mapiproxy_module_register function to register itself in the MAPIProxy module subsystem. \code NTSTATUS samba_init_module(void) { struct mapiproxy_module module; NTSTATUS ret; /* Fill in our name */ module.name = "sample"; module.description = "A sample module"; module.endpoint = "any"; /* Fill in all the operations */ module.init = sample_init; module.push = sample_push; module.ndr_pull = sample_ndr_pull; module.pull = sample_pull; module.dispatch = NULL; module.unbind = NULL; /* Register ourselves with the MAPIPROXY subsytem */ ret = mapiproxy_module_register(&module); if (!NT_STATUS_IS_OK(ret)) { DEBUG(0, ("Failed to register 'sample' mapiproxy module!\n")); return ret; } return ret; } \endcode
  • module.name:
    This is the module name. This name will be used by dcerpc_mapiproxy:modules in smb.conf to load the module
  • module.description:
    This field lets developers specify a brief module description for information purpose only.
  • module.endpoint:
    This field defines the interface which this module is designed to work with. The primary objective is to avoid calling the module hooks if the module doesn't have any impact on the requests or replies. For example, a module only interacting with the EcDoRpc function should define exchange_emsmdb. In the meantime, it can happen that a module requires to interact with more than a single interface. In such case, use the 'any' keyword which will call the modules functions with any endpoints proxied by MAPIProxy.

5.3. Module Hooks

MAPIProxy offers a set of hooks which modules can implement to modify/change/alter client to server MAPI traffic. The figure below shows how and when hooks are called during a request/response lifetime.
Figure 4. Usage of MAPIProxy Hooks during a request/response life time
  • init: This is the initialization function for the module which is only called once - when the module is loaded. It is generally used to retrieve smb.conf parametric options for the module and initialize some global structures
  • pull: This is the function called when MAPIProxy receives a MAPI request. The request has already been extracted and its information filled into MAPI structures
  • push: This is the function called when MAPIProxy receive a MAPI response. The response has already been extracted and its information filled into MAPI structures
  • dispatch: Similarly to the MAPIProxy top-level dispatch function, it is used to dispatch the information. This function is called after the pull but before the push. Moreover it is called before the request is forward to the remote endpoint.
  • ndr_pull: This is the function called before data from a request is extracted from the NDR blob.
  • ndr_push: This is the function called before data from a response is extracted from the NDR blob.
  • unbind: This is the function called when the connection closes. It can be used to free data associated to a given session and stored within a module global list.
Please note that the module API is still under development and is likely to change in further revisions.

5.4. mapiproxy structure

MAPIProxy uses a structure modules can modify in their dispatch routine and which impact on the general MAPIProxy behavior.
Figure 5. overview of mapiproxy structure variables scope
  • norelay: This boolean variable can be used by modules to tell MAPIProxy not to relay the incoming request to the remote server through dcerpc_ndr_request() but directly jump to the push (response) MAPIProxy code. This variable is for example in use within the cache module when we read stream from the local filesystem and play it back to MAPI clients.
  • ahead: This boolean variable can be used by modules to tell MAPIProxy not to relay the incoming response to the client through the push and dcerpc_ndr_request routine but loop over the dispatch routine. This variable is for example in use within the cache module when we want to read a stream ahead from Exchange server to the remote MAPIProxy instance.

6. Available Modules

6.1. Downgrade Module

The downgrade module implements the EcDoConnect/EcDoRpc negotiation as described in section 4.2. It ensures Outlook will not send compressed information or use functions other than EcDoRpc for EMSMDB transport. In order to use the downgrade module, edit smb.conf and add downgrade to dcerpc_mapiproxy:modules. \code dcerpc_mapiproxy:modules = downgrade \endcode

6.2. Pack Module

Note that this module only works with an infrastructure using two or more instances of MAPIProxy as described in Figure 1
The pack module implements routines designed to manipulate and factorize MAPI content between different MAPIProxy instances. It also offers a developer overview on how to manipulate mapi requests. Last but not least, it provides data which can next be used by subsequent MAPIProxy modules for example to compress or encrypt this proxypack blob.
  • First, MAPIProxy extracts and removes specific MAPI calls from the request, pack them within the proxypack MAPI call data blob, prefix them with their real offset in the array of mapi requests and finally append this custom call at the end of the mapi requests array (Figure 4).
  • Figure 6. Pack process
  • Final MAPIProxy hop will seek the mapi requests array looking for the proxypack call. If found, it unpacks MAPI data and restore these calls at their initial location within the mapi requests array (Figure 6).
  • Figure 7. Unpack process
This module has two configuration options:
  • mpm_pack:opnums
    This option takes a list of MAPI calls to pack into the proxypack data blob. It can take one or more MAPI opnums, each of them separated with a comma.
  • mpm_pack:lasthop
    This options takes either true or false.the lasthop option defines whether this is a MAPIProxy directly connected to Outlook/Exchange or yet another proxy inserted within the MAPIProxy chain of hops. If this MAPIProxy instance is not a last hop, then it will skip the pack/unpack operations and forward the request to the next one.
\code mpm_pack:opnums = 0x70,0x75,0x76,0x77,0xa mpm_pack:lasthop = true \endcode In order to use the pack module, edit smb.conf and add pack to dcerpc_mapiproxy:modules. \code dcerpc_mapiproxy:modules = downgrade,pack \endcode

6.3. Cache Module

The cache module implements a cache mechanism for streams related to messages or attachments. This module reduces communication latency between MAPI clients (using online mode) and Exchange. When configured with online mode, MAPI clients retrieve data from Exchange each time they access a message and don't have any offline storage mechanisms enabled - data are downloaded and stored within a temporary files folder. This module also offers a preliminary synchronization mechanism which can be used to transfer files between different MAPIProxy instances and use different protocols than MAPI for data transfer (such as rsync or wget). The cache module is designed to cover different cases:

Scenario 1: Replay attachments

This scenario only requires a single MAPIProxy instance and requires a single configuration option: \code mpm_cache:path = /tmp/cache \endcode
Figure 8. Replay stream scenario
  • 1. Outlook reads a stream for the first time:
    MAPIProxy monitors the Outlook-Exchange traffic and store the attachment on the local filesystem.
  • 2. Outlook requests this stream again:
    MAPIProxy looks over its cache, find the requested stream and directly communicate with Outlook without forwarding requests to the remote server.

Scenario 2: Read stream ahead

This scenario requires two MAPIProxy instances and requires different configuration options for local and remote MAPIProxy:
  • local MAPIProxy smb.conf sample:
    \code mpm_cache:path = /tmp/cache mpm_cache:ahead = false mpm_cache:sync = true mpm_cache:sync_cmd = /usr/bin/rsync -z mapiproxy@192.168.102.2:__FILE__ __FILE__ \endcode
  • remote MAPIProxy smb.conf sample:
    \code mpm_cache:path = /tmp/cache mpm_cache:ahead = true mpm_cache:sync = false \endcode
Figure 9. Read ahead scenario with synchronization mechanism
  • This scenario uses 2 MAPIProxy instances. We call remote MAPIProxy, the MAPIProxy instance connected to the Exchange server network and local MAPIProxy the instance connected to the MAPI clients network.
  • 1. Outlook wants to read an attachment for the first time:
    The remote MAPIProxy monitors the first ReadStream request and read the full stream ahead on its own and stores it on its local filesystem.
  • 2. remote MAPIProxy replies to local MAPIProxy and local MAPIProxy runs the synchronization mechanism. The current implementation provides a fork/execve/waitpid process which allows to run any command with parameters. When local MAPIProxy finishes to store the file locally through the synchronization mechanism, it marks the stream as being cached.
  • 3. local MAPIProxy plays the attachment back to the client from cache.
The module monitors OpenMessage, OpenAttach, OpenStream, ReadStream and Release MAPI calls and stores streams on the local filesystem with indexation in a TDB database. Note that the module doesn't yet provide semantics needed to remove entries from the TDB database. This module has different configuration options and modes:
  • mpm_cache:path
    This option takes the full path to an existing folder on the filesystem. This folder will be the storage root path for the cache module and will hold the TDB store, a folder hierarchy and stream files. \code mpm_cache:path = /tmp/cache \endcode
  • mpm_cache:ahead
    This option takes a boolean value (true or false) and defines whether the ahead mechanism should be enabled or not. This mode should only be enabled on the remote MAPIProxy instance. It can be enabled on local MAPIProxy instance, however there won't be any benefit but Outlook unexpectedly falling in some time out mode and close the connection. \code mpm_cache:ahead = true \endcode
  • mpm_cache:sync
    This option takes a boolean value (true or false) and defines whether the synchronization mechanism should be enabled or not. This mode only makes sense on the local MAPIProxy instance and mpm_cache:sync_cmd must also be configured. \code mpm_cache:sync = true \endcode
  • mpm_cache:sync_cmd
    This option takes the command line to execute for the synchronization process. A preliminary substitution variable mechanism is available but should be improved over time. For the moment, the cache module only provides __FILE__ which will be substituted by the full path to the cached file. The synchronization process currently assumes local and remote MAPIProxy instances have the same storage path (mpm_cache:path). \code mpm_cache:sync_cmd = /usr/bin/rsync -z mapiproxy@192.168.102.2:__FILE__ __FILE__ \endcode
In order to use the cache module, edit smb.conf and add cache to dcerpc_mapiproxy:modules. \code dcerpc_mapiproxy:modules = downgrade,cache \endcode

Notes

  • While the cache module implements a preliminary session mechanism (multiple clients support), this mode is currently only implemented up to 50%. Multiple clients will work for files already cached, but will cause unexpected behaviors while synchronizing a remote file at the same moment from different session. This bug should be fixed when the streaming and lock mechanism will be implemented.
  • The synchronization mechanism is yet experimental and we have deliberately changed the storage path permissions from 0700 to 0777 for trivial setup. File permissions will become parametric smb.conf options in the future.

7. Server Mode

7.1. 5-Minute Configuration

This 5-Minute configuration will help you set up a preliminary OpenChange server. This configuration will be performed in three steps. Before running these commands, make sure you have followed step 1 (Provision Samba) and step 2 (Add a user account) in MAPIProxy 5-Minute configuration section.
  • [1] Provision OpenChange:
    From openchange root directory, run under the root account: \code # ./setup/openchange_provision \endcode This script will extends Samba4 Active Directory with Exchange classes and attributes needed to run OpenChange server. Note that this operation may require several minutes to complete.
  • [2] Create the Exchange user account:
    OpenChange does not create the user account the way Samba does. It only extends existing users from the SAM database and add attributes required to access OpenChange server. The underlying concept is that system administrators may want to give access to Samba shares to a specific user but do not want him to access OpenChange server.The user must have been created using the Samba4 samba-tool newuser script before you run this command. Run under the root account: \code # ./setup/openchange_newuser --create \endcode where username is the user account you want to give access to OpenChange server
  • [3] Create the OpenChange Dispatcher database:
    OpenChange uses a dispatcher database designed to store generic and top-level information about user mailbox. The following command will create a blank openchangedb ldb database: \code # ./setup/openchange_provision --openchangedb \endcode
  • [4] Create a mailbox for the user in the OpenChange Dispatcher database:
    Run under the root account: \code # ./setup/openchange_newuser --mailbox \endcode
  • [5] Configure OpenChange server options:
    OpenChange server only requires a very limited set of options to be added to smb.conf in order to run. Note that the following configuration also works with existing MAPIProxy configuration. This configuration will turn MAPIProxy into OpenChange server only and no remote connection to Exchange server will be made: \code [globals] netbios name = MAPIPROXY workgroup = OPENCHANGE realm = OPENCHANGE.LOCAL server role = domain controller ### Configuration required by OpenChange server ### dcerpc endpoint servers = epmapper, mapiproxy dcerpc_mapiproxy:server = true dcerpc_mapiproxy:interfaces = exchange_emsmdb, exchange_nsp, exchange_ds_rfr ### Configuration required by OpenChange server ### [netlogon] path = /usr/local/samba/var/locks/sysvol/openchange.local/scripts read only = no [sysvol] path = /usr/local/samba/var/locks/sysvol read only = no \endcode


7.2. General Overview

Although section 1.1 only describes MAPIProxy as a proxy, recent work makes it possible to turn MAPIProxy either into a complete and real stand-alone server or server/proxy hybrid. MAPIProxy behaviour is controlled through the dcerpc_mapiproxy:server parametric option. To use MAPIProxy as an independent server, set \code dcerpc_mapiproxy:server = true \endcode
  • dcerpc_mapiproxy:server = true
    When this parametric option is set to true, MAPIProxy will not initiate connections to a remote server, but instead will direct client connections to its own default NSPI, RFR and EMSMDB servers and work as a stand-alone server.
  • dcerpc_mapiproxy:server = false
    If this option is unset or set to false (default behavior), MAPIProxy will work in proxy mode only and initiates a connection to a remote server using the binding/credentials configuration as specified in section 3.1 (5-Minute Configuration).

In addition to the server mode described above, MAPIProxy provides an additional set of configuration options which makes possible to override and customize MAPIProxy behavior. The server mode has been designed to supply a modular mechanism somewhat similar to the modules one described in section 5. While MAPIProxy modules are stackable and can be chained, server modules only support a single module for a given endpoint:
  • When dcerpc_mapiproxy:server is set to true, MAPIProxy registers dynamic shared object stored at a specific location (modules/dcerpc_mapiproxy_servers) and load server modules tagged with the MAPIPROXY_DEFAULT status. For each of the endpoints MAPIProxy can handle (exchange_nsp, exchange_emsmdb, exchange_ds_rfr), the associated default server will be loaded. These default servers are located within mapiproxy/servers/modules. (Figure 10.)
    Figure 10. Server mode enabled
  • When dcerpc_mapiproxy:server is set to false, MAPIProxy still registers server dynamic shared objects but does not load any of them, which means that ExchangeRPC traffic will be relayed to remote server.
However there may be some cases where developers would like to run a custom server they have developed, or handle a limited set of ExchangeRPC traffic on their own for a given endpoint. This configuration is made possible through 3 parametric options: \code dcerpc_mapiproxy:nspi_server = nspi_server dcerpc_mapiproxy:emsmdb_server = emsmdb_server dcerpc_mapiproxy:rfr_server = exchange_ds_rfr \endcode Each of these options specifies the server module name to be loaded for a given endpoint. Note that these options override the dcerpc_mapiproxy:server state:
  • If dcerpc_mapiproxy:server is set to true, specifying one or all of these options will override default servers with your own custom servers. For example Figure 11 shows a mapiproxy configuration where server mode is enabled but where the NSPI server has been replaced with a custom one.
    Figure 11. Server mode enabled but custom NSPI server loaded
  • If dcerpc_mapiproxy:server is set to false, specifying one or all of these options will force MAPIProxy to relay the associated traffic to default or custom server. For example, Figure 12 shows a mapiproxy configuration where NSPI traffic is handled by OpenChange NSPI server while EMSMDB and RFR traffic is relayed to the remote server.
    Figure 12. Server mode disabled but NSPI server loaded

8. Frequently Asked Questions

8.1. The action could not be completed

Figure 13. Outlook error: The action could not be completed
If you have followed the 5-Minute Configuration instructions and the above error message box (Figure 13) is displayed each time you click the Check Name button, then you need to:
  • Click on More Settings
  • Open the security Tab
  • Tick the Always prompt for username and password checkbox in the User Configuration section (Figure 14)
Figure 14. Resolution: Always prompt for username and password
Next time you click on Check Name, Outlook will prompt for username and password. A similar credentials dialog will be displayed each time Outlook is launched.

8.2. Profile creation goes fine, but Outlook can't open your default e-mail folders

The profile was properly created using the mail applet from the configuration panel (or using Outlook wizard). However when I launch Outlook, I keep having the following error message:
Figure 15. Outlook error: Unable to Open your default e-mail folders
This probably means Outlook is unable to lookup the resolved name of your MAPIProxy/samba4 server. You can either:
  • 1. Make your Windows workstation points to a domain name server able to resolve MAPIProxy fully qualified name.
  • 2. Open \code C:\WINDOWS\system32\etc\drivers\hosts \endcode file and add an entry for mapiproxy. For example if I have mapiproxy.openchange.local pointing at 192.168.102.2, then hosts file should hold the following line: \code 192.168.102.2 mapiproxy.openchange.local mapiproxy \endcode

8.3. Does MAPIProxy need to be domain controller?

No it doesn't. MAPIProxy works fine as a member server of a Windows domain. However, since delegated credentials and forwarded kerberos credentials don't yet work, you'll need to force samba to rely on the local SAM database. To force this behavior, add to smb.conf within the global section: \code server role = member server aux_methods:member server = sam \endcode

8.4. Generating Samba's private keys takes infinite time

For some configuration, the private keys generation process at Samba startup can be very long. In case private keys are not generated within a couple of minutes, it is suggested to recompile Samba with gnutls disabled as in the example below: \code $ ./configure.developer --enable-debug --disable-gnutls $ gmake idl_full $ gmake $ sudo gmake install \endcode

8.5. On Ubuntu make samba-git exits with gmake: not found

On Ubuntu, I have the following output while trying to install samba4 from OpenChange sources: \code To build Samba, run /usr/bin/make Step2: Compile Samba4 (IDL) ./script/installsamba4.sh: 332: gmake: not found Step3: Compile Samba4 (Source) ./script/installsamba4.sh: 332: gmake: not found Error in Step3 (error code 127) \endcode gmake is make on Ubuntu. Creating the following symbolic link will fix the issue: \code $ sudo ln -s /usr/bin/make /usr/bin/gmake \endcode */ openchange-2.0/mapiproxy/documentation/mapistore-documentation.doxy000066400000000000000000000462411223057412600261530ustar00rootroot00000000000000/** \page mapistore-documentation
\section Contents

Revision History

Date Revision Number Author Revision Content
21/05/10 0.3 Julien Kerihuel Add API documentation for initialization, backend connection contexts and add programming samples
21/05/10 0.2 Julien Kerihuel Merge initial Wiki document and add FSOCPF section
20/05/10 0.1 Julien Kerihuel Draft document.

1. Introduction

1.1. Purpose and Scope

MAPIStore is the SAL component of OpenChange server. SAL stands for Storage Abstraction Layer. It is the component used by OpenChange Server to push/get information (messages, folders) to/from storage backends. The following document intends to describe the overall/theoretical SAL behavior and constraints we need to consider when dealing with MAPI/EMSMDB. It also describes the semantics and inner working of its storage backends.

1.2. General overview

The main objective of mapistore is to provide an interface layer with a common set of atomic functions (operations) used to trigger and dispatch data and commands to the appropriate backend. MAPIStore relies on a backend mechanism specifically designed to transparently handle some of the MAPI semantics required by any Exchange compatible server. The initial idea was to provide to OpenChange a highly customizable storage backend mechanism which would fit in any situation and any environments. One of the greatest limitation we have found with existing groupware is the storage layer which is generally limited to a single solution, service or format and is neither scalable nor modifiable when user requirements evolve upon time. MAPIStore solves this problem and go beyond classical limitations. It is not a revolutionary concept, but the way openchange uses it makes the whole difference and offer administrators an innovative way to customize storage. MAPIStore allows you to: - use a different backend for any top-folder - transparently move/copy data across backends - develop new backends quickly - access all the different backends through an unique API For example (assuming all associated backends were developed) a user could have the following storage organization for his mailbox: - Mails stored using an IMAP backend (Cyrus-IMAP or dovecot) - Calendar items stored in CalDAV or pushed in Google calendar - Sent emails and archives/backup stored in a compression backend - Tasks stored in a MySQL database - Notes stored on the filesystem If the user is not satisfied with one of the backend's performance, they would just have to use an administration tool, change the backend, wait for the replication, synchronization to finish and there data will be available from the new backend. Information can be completely decentralized, stored on one of several servers and still be accessible transparently from OpenChange server.

2. Technical / MAPI Considerations

2.1. MAPI objects

An object is a physical (message, folder) or temporary (table) but generic entity which can be represented as a 2 columns fixed array with n rows, where each row contains a property of that entity. One column repesents the property tags (names), and the other represents the property value (or values). From a MAPI perspective (network layer), opening an object means: - opening either a private mailbox or public folder store. These are referenced by EssDN and not IDs - opening a message given its PR_MID (Message identifier) - opening a folder/container given its PR_FID (Folder identifier)

2.2. MAPI tables

Another category of MAPI objects are tables (also known as views) created with MAPI ROPs such as GetContentsTable, GetHierarchyTable, GetAttachmentTable or GetRulesTable. Views are temporary representation of the elements that a container holds at a specific moment. It can be represented as a list of n rows (elements) with n columns (property values): - GetContentsTables creates a view listing all messages available within a container - GetHierarchyTable creates a view listing all containers within a container - GetAttachmentTable creates a view listing all the attachment of a message - GetRulesTable creates a view listing all permissions associated to a container Tables are customized through the SetColumns MAPI ROP which will define the property identifiers to be retrieved. The QueryRows MAPI ROP can then be called to sequentially retrieve rows and associated property values. A table is similar to a MAPI object except it is virtual, created on demand to represent a list of objects rather than a unique object.

2.3. MAPI properties and mapping

There is a large set of fixed and known MAPI properties available. If appropriate backends are developed, there can be a 1-1 mapping between MAPI properties and backend properties for some of them. This mapping may even be enough for common purposes. However there will still be a set of MAPI properties which won't fit in this process. There are different way to workaround this issue. For example, Kolab is using a Cyrus/IMAP backend and associate/store MAPI properties to the message using ANNOTATE-MORE within a XML file format. OpenChange provides similar mechanism with its OCPF file format.

2.4. Named properties vs known properties

OpenChange server needs to support named properties. An initial set of named properties can be defined at provisioning time, but this list must not be static. Users must be able to add, delete, change new entries and create their own set of custom named properties as required.

3. MAPIStore Architecture

Given that objects representation are similar to SQL database records, an architecture like the sqlite one makes sense for our purpose:
Component Brief description
INTERFACE convenient top-level functions (Public API) accessed through EMSMDB providers
PROCESSING set of atomic operations (open, read, write, close, mkdir, rmdir etc.)
BACKENDS The code which does things in the specified storage system (mysql, fsocpf, imap etc.)

3.1. INTERFACE layer

The interface layer doesn't have any knowledge about mapistore internals, how or where objects are stored. The interface uses MAPI data structure, supplies PR_FID and PR_MID values and assumes the interface layer will return a pack of data it can directly use without further or significant modifications. The interface layer functions should also have (as a parameter) a pointer to a mapistore context with private/opaque set of information (void *) about the object.

3.2. PROCESSING layer

The processing layer is responsible for: - mapping OpenChange objects identifiers (PR_FID, PR_MID) to unique backends object identifiers (on purpose, depending on the kind of backend). - format input/output data: glue between INTERFACE and BACKENDS - relay input requests to the correct backend through atomic operations - maintain mapistore's integrity

3.3. BACKENDS layer

The backends layer has a list of modules identified at mapistore initialization and available across user sessions, which means unique initialization at server start-up. Each module is a backend (fsocpf, sqlite, imap, etc.) and similarly to many other openchange components is loaded as a DSO object (dynamic shared object)

3.4. Relationship to OpenChange Dispatcher database

MAPIStore and the openchange "dispatcher" database (openchange.ldb) are completely unrelated. MAPIStore is a standalone API and developers can use it independently from OpenChange server. However, the mapistore API has initially been designed to be used by OpenChange server, and OpenChange server is using a tiny indexing database which describes user mailboxes top level containers. In openchange.ldb the mapistore_uri attribute is attached to top level containers and its value points to a valid mapistore URI (namespace + path). Note that a single user can have several different types of mapistore databases in use (one for each of the top level containers). The is the only relationship between the database and the store: The database points to store locations.

3.5. Object mapping

MAPIStore needs to maintain a hash database linking unique OpenChange identifiers to unique backend identifiers. This hash table can be stored within a TDB database. MAPIStore is responsible for managing IDs mapping between OpenChange objects and backend specific objects. It maintains a list of free identifiers which it reallocates on demand whenever a backend needs (mapistore_register_id()) one or where it wants to release one (mapistore_unregister_id()).

4. MAPIStore API

MAPIStore relies on the talloc library for memory allocation.

4.1. Initialization

If there was a "hello mapistore" program, it would only require to make 2 calls: - mapistore_init:
The initialization routine initializes the mapistore general context used along all mapistore calls, the mapping context databases (described below) and finally load all the backends available (DSO). When this operation is successful, developers are ready to make mapistore calls. - mapistore_release:
The release operation uninitializes the mapistore general context, closes connections to database and frees the remaining allocated memory. mapistore_sample1.c \code #include int main(int ac, const char *av[]) { TALLOC_CTX *mem_ctx; struct mapistore_context *mstore_ctx; int retval; /* Step 1. Create the talloc memory context */ mem_ctx = talloc_named(NULL, 0, "mapistore_sample1"); /* Step 2. Initialize mapistore system */ mstore_ctx = mapistore_init(mem_ctx, NULL); if (!mstore_ctx) { exit (1); } /* Step 3. Uninitialize mapistore system */ retval = mapistore_release(mstore_ctx); if (retval != MAPISTORE_SUCCESS) { exit (1); } return 0; } \endcode \code $ export PKG_CONFIG_PATH=/usr/local/samba/lib/pkgconfig $ gcc mapistore_sample1.c -o mapistore_sample1 `pkg-config --cflags --libs libmapistore` $ ./mapistore_sample1 $ \endcode

4.2. Backend contexts

MAPIStore registers and loads its backends upon initialization. It means they are only instantiated/initialized one time during the whole server lifetime and the same code is used for all users and all mapistore folders. These backend contexts (or connection contexts) are identified by a context id, which is an unsigned 32 bit integer which references the context during its lifetime. If OpenChange is used in a very large environment with many top folders (which implies the same number of mapistore contexts), or if OpenChange server has an incredibly long uptime, it would be possible to run out of available context identifiers. In order to prevent this situation from happening, mapistore implements context databases where it stores available/free/used context identifiers: - mapistore_id_mapping_used.tdb: TDB database with used IDs - mapistore_id_mapping_free.tdb: TDB database with available pool of IDs MAPIStore provides a convenient set of functions to manage backend contexts: - mapistore_set_mapping_path: Defines the path where context databases are stored. Call to this function is optional and default path would be used instead. However if a call to this function has to be made, it must be done before any call to mapistore (even mapistore_init). - mapistore_add_context: Add a new connection context to mapistore - mapistore_del_context: Delete a connection context from mapistore mapistore_sample2.c: \code #include int main(int ac, const char *av[]) { TALLOC_CTX *mem_ctx; struct mapistore_context *mstore_ctx; int retval; uint32_t context_id = 0; uint32_t context_id2 = 0; /* Step 1. Create the talloc memory context */ mem_ctx = talloc_named(NULL, 0, "mapistore_sample1"); /* Step 2. Set the mapping path to /tmp */ retval = mapistore_set_mapping_path("/tmp"); if (retval != MAPISTORE_SUCCESS) { exit (1); } /* Step 3. Initialize mapistore system */ mstore_ctx = mapistore_init(mem_ctx, NULL); if (!mstore_ctx) { exit (1); } /* Step 4. Add connection contexts */ retval = mapistore_add_context(mstore_ctx, "fsocpf:///tmp/Inbox", &context_id); if (retval != MAPISTORE_SUCCESS) { exit (1); } retval = mapistore_add_context(mstore_ctx, "fsocpf:///tmp/Sent Items", &context_id2); if (retval != MAPISTORE_SUCCESS) { exit (1); } /* Step 5. Release connection contexts */ retval = mapistore_del_context(mstore_ctx, context_id); retval = mapistore_del_context(mstore_ctx, context_id2); /* Step 6. Uninitialize mapistore system */ retval = mapistore_release(mstore_ctx); if (retval != MAPISTORE_SUCCESS) { exit (1); } return 0; } \endcode \code $ ./mapistore_sample2 sqlite3 backend initialized fsocpf backend initialized namespace is fsocpf:// and backend_uri is '/tmp/Inbox' [fsocpf_create_context:49] namespace is fsocpf:// and backend_uri is '/tmp/Sent Items' [fsocpf_create_context:49] $ \endcode

5. FSOCPF Backend

5.1. Definition

FSOCPF stands for FileSystem and OpenChange Property Files. It is a backend designed to help developers testing OpenChange server code easily. The main idea is to have a backend we can manipulate, analyze and modify from the Linux console without having to develop a specific tool. This backend uses the UNIX filesystem for folder semantics and the OCPF file format as a way to store MAPI objects easily.

5.2. Namespace and Attributes

The namespace for this backend is: \code fsocpf:// \endcode The mapistore_uri attribute for the folder definition in openchange.ldb must be a valid path where the last part of the URI is the FSOCPF container folder to create on the filesystem.

5.3. Overview

\code [+] Private user storage space | +-[+] Top-MAPIStore folder (Inbox) | +-[+] 0xf1000001 (mapistore folder1) | | | +-[+] .properties (OCPF) | | | +-[+] 0xe10000001.ocpf (message - OCPF) | | | +-[+] 0xe10000001 (attachment folder) | | | +-[+] 1.ocpf (PR_ATTACH_NUM) | | | +-[+] 1.data (attachment / stream data) | +-[+] 0xf2000001 (mapistore folder2) | +-[+] .properties (OCPF) \endcode The figure above exposes the storage architecture of the FSOCPF backend using a real-world example. In this use case, we have decided to associate the FSOCPF backend to the Inbox folder. It means that any folder created under Inbox or any message stored within Inbox at any level of depth is stored and retrieved from the path defined in openchange.ldb. In openchange.ldb, the mapistore_uri attribute of the Inbox record points to: \code fsocpf://Private user storage space/Inbox \endcode where Private user storage space can for example be \code /usr/local/samba/private/mapistore/$username \endcode Under Inbox, we have created 2 folders: - 0xf1000001 folder1 - 0xf2000001 folder2 These folders are identified/named using their FID. Since they are classical filesystem folders, we can't associate attributes to them such as a folder comment, or the container class. All these attributes with the displayable name are stored into the .properties file within the folder. Inside 0xf1000001 folder, we have 1 message named 0xe10000001.ocpf stored in the OCPF file format (property/value pair). Any properties associated to the message (subject, recipient, body) are stored within this file. This message also has attachments. Attachments are stored within a directory at the same level named 0xe10000001 (message name without OCPF extension). Within this directory, we find the attachments named using the PR_ATTACH_NUM property value and the OCPF file extension. The content of the attachment is stored in \$PR_ATTACH_NUM.data - in this case 1.data.

5.4. Documentation and References

- OpenChange Property File format (OCPF) documentation */openchange-2.0/mapiproxy/documentation/pictures/000077500000000000000000000000001223057412600222235ustar00rootroot00000000000000openchange-2.0/mapiproxy/documentation/pictures/dcerpc_mapiproxy_server_false_nspi.png000066400000000000000000000436131223057412600321010ustar00rootroot00000000000000‰PNG  IHDRXÙíügsBITÛáOà pHYsêe¤ IDATxœíÝw\S×ûð'–!ˆ²Ä­àÖ¨¨¸q (â®ý"ŠÅªTk­£íÐV­«Ö…q!Š *â¸Ø(È’=d¯@BB ÷÷Çý~ó£€€zŸ÷¾âåäÜ— OÎIî¹,Š¢!„b*9ÒB!’°~™X,Ö‚ H§h‘Ï(ê'·yóf‹•žž^ïKL>,µ16騽¨­­•——oûýfee©¨¨4Û¬íã½ï? áFŽyæÌ}}ý÷L‡údpDøåïÕ«—ŠŠÊªU«d“’’Ư¤¤¤¥¥åëë›””dmm­¤¤¤§§·oß>`±XÆ ³°°°¶¶¦ÿ;|øðAƒ)**Î;·ªªª^õv*{ºššÚŽ;fÏž­¨¨hccSSSû÷ï×ÕÕe³Ù&&&ÞÞÞößµkW—F¿T/^bbâ¸qã”””´µµW¯^-‘HNœ8!''túôi999“:Š¢ŒçÍ›ÿZmÞ¼YSS“ÃátïÞ===½áѨ»G6›­¯¯/•JE"‘††ÆÊ•+éãÙôl9‹%‰‚‚‚ŒŒŒ:Tï@É´$3Bè£PèKaiiÙ¹sçððð#GŽÀüùó)Š2dˆ––Öƒ^½zõúõë!C†DFFîÚµ }úôÑ£G;vd±X–––¹¹¹ìСC||üرc·mÛÆápêöF÷Y¯‡¾}ûÖÛ/ý·›&{“Œ¢(ضm[ß¾}:´eË–˜˜˜Fûob×ôFYéJŒ>™ÐÐÐ=z())9::ÂÿÆqqqcÆŒQTTìСÕ+Wèw˜”••醬% FŒ1dȇcgg' ëõPo§²§Ó#BŠ¢èáÅ‹)ŠÚ´i“ŠŠJŸ>}Æÿ«Žõú‡:#Âz_ªÛ?ý½XYYq8MMMggg±X¼cÇ…ðððëׯÀÙ³gkjjŒ ))©^BŠ¢&Ož¬ªªÊf³‡šœœÜðhÔkŸ••%''§¨¨(›\möʼ׈°ÑE©%™BƒEáõ¨‹5þüK—.µ}ÿŸd×b±xæÌ™"‘èñãÇÓBˆ9ðS£èý(Õ±qãFÒqêSRRJHHÍd"„P³ð=Bô/ÍÎÄÆÆÊkjj~Âþ?ÉäÎp „ÞN"„b4œE!ÄhXB1Â/Óg´dsûÚþ~˜/õûBè}á‡eÐá¢ÛïÒ„Mkƒ%¼BG„_\t»ÙE·Y,ÖСC---UTTd+V×[Õº‰„õÔ{"4¹$wk/á]¯«zGæÖ­[ OHKK0`@Ý£Ñè¬áA“l...ônv5ð†ý4<€žµ:‚ó£O ÝnvÑmz‘‘‘ƒ ÒÖÖ¦7Ö[Õº‰„õÔ{"Õä’Ü­½„wîêY›º?ÊFÆ»~dõšYXXèéé………>|˜>>ͮްŸ†°Ñs¡Ö†…ðË‹nSÍ-º-Këàà {XoUë&ÖSï‰MÞÖ^»aWõŽLÓ¡Ñ£Ñè¬a³†'[³«7ì§álô@¨µá{„_\t»ÙE·eiY,–l§õVµn:a]õžøÃ?4qx[{ ïz]YYYÕ;2Ðàdhôh4ú#kجáÉÖ’ÕÀëõÓð¶üà#ô)‘®Äè“ÁE·›]t»aZªÁªÖM$¬§Þ©æ–änÕ%¼ëuµdÉ’zG¦áÉÐèÑhbùïºÍè“MYYyùòå°hÑ¢fWoØOÃØè9€PkÃBˆþå]ˆÛ ÿO²k‘H4iÒ$++«À—!66666¶¬¬Œ~3oÏž=Ÿ¤[<øˆüÔ(z?L^t»ïm)55uܸqÚÚÚ;wîtuu]»vm½x¬Ðg×E<¤ijjêèè ÓÆ˜ü½¿/>þÕ«W\.7((¨  €ËåzzzÀ¨Q£öíÛööö7n€o¿ývÉ’%ðÛo¿M˜0x<—Ëåóù·nÝâr¹IIIQQQ\.÷Ñ£G¹¹¹\.×ËË ¸\îÀÎÎnÓ¦Màââ²lÙ2عsçäÉ“àäÉ“\.W ܸqƒËå&''‡‡‡s¹Ü'Ožäääp¹\ooïÚÚZ.—{øða°µµÝ²e 8;;;::€››› ;vŒËåŠD¢ëׯs¹Ü´´´.—ûüùóÌÌL.—ëëë+‘H¸\î‘#G`ÆŒ?ýô899999ÀO?ý4cÆ 8rä—Ë•H$¾¾¾\.733óùóç\.7$$$--Ëå^¿~]$q¹ÜcÇŽ€››8:::;;À–-[lmmàðáÃ\.·¶¶ÖÛÛ›Ëåæää+3ƒ/F%$+)+óÂ×)érêÚ²®Ê+tªÂÒ²*‰482&;¿°¨´<82&ým^…@“˜žÅ_¼ŠOOMç „‘ñoØl6}VH•Ôÿ¿« Aú[º«ò–|pdLN~QaiypdLZN*)#›/¾x—”œFw|0&9M,¯È“2²é³"-'î ØŠÁ‘1o ‹Kÿ›*¿¼âÿO°ç/ãâ’Óù!ž«­w®~»~ã‘ý{³²² ÿmB¤±(Š"¡¹¬ûnìø‰‘΂",*<ìÉ£'ŽÖÔÔ$Æ BÁ‘1¤# „Ú«AýIG@ä1è=ÂŒŒŒy3¦Üñ÷#!DÞ«WæÍ˜’››K:"A…PQQ±G¯ÞšZZ¤ƒ „ÈÓÒÖîÑ«7‡Ã!‘‡S£!æÂ©QŒ¾}ûví ÇÇA¤ƒ „È ºwwí ÇÂÂBÒAy *„R©T ¨¬©©!!D^MD ¨”J¥¤ƒ òpj!Ä\85Š€Q#‚‚‚ß~Þú‚t„y!ÏžüöóÖ’’ÒAy *„B¡ðyðãÜœÒABä½ÍÎ~üX$‘‚ÈéQ„sáÔ(FKJJN=‹µ!1/£O=ÂçóIAä1¨–––žu?žK:Bˆ¼¸˜WgÝc!DÀ¨©Q©Tzïi(‡ÃQPP !D˜D"©®®ž2z8‹Å"Æ ¡@ xx?'+‹t„yÙ™ï …BÒAy *„»wüB:Bˆ¼ÐçÏvïø¹´´”tDƒ¦F«««/^ó×ÑÕí ·CˆéÊËÊŠ‹ ÙÍÄ÷JƒF„µµµ¥%%b±˜t„y"QUiI .±†€Q…ðíÛ·ß}³"øaé !òÜÿè66ém§K—.»÷63ïN:Bˆ¼Ñ㬻ëèè‚ÈcЈPAAÁØÌL½CÒABäihh›™±Ù   waP!ÌÌÌ\8kúÝ[7HA‘wóúÕ…³¦çåå‘‚È“wss#¡ÈËË‹(–åÀÁÚ;’΂"LQQÑÌÜ|ÚäI‡tDƒ.Ÿ (êQøK‹%'Ç q0B¨QR©”¢¨qC‚ÈcPIHMMµ6ðšé !ò¼==¬‡ ÌÎÎ&‘Ç B¨©©¹`é²î={“‚"¯gŸ> –.SWW'‘Ç ©QÀû"„þ ïGˆ€Q#ÂŒŒŒ¹6“nù]#!DžŸ¯Ï\›I¹¹¹¤ƒ òT•””úö·èˆ×Ï"„tttûö·ÀŒ"À©Q„“áÔ(Fœœ›é3–|5vüDÒYÚ£Ÿ6®/)."}iŒLL7ý¼ƒtŠFÞ½íëu1ðþ=]]]ÒYa Z^ˆ¢(‰D"­­%¤JOyÃçóÍÍÍIA_ŽøøxE…vúGF*•J$æŒP4"œmÒÒ93xõêUÒAЗcôèÑb±ø¯ã<ÒAÞ §F0êÃ2ùùù;·þöâ9é !ò^< Þ¹õÇ’’ÒAyítÖ¢5TUU…‡<„¢¢b·n݆ ³i¶%ƒ ¡‰‰‰_À#Ò)BíÂìyógÏ›¯¯¯O:H»væÌ¾ššš.]ºòÞ¤R©··×¢E [Ò˜A…°¤¤äÄ‘C£¬Æöµ°$!DXLtÔó§ÁíÕÐÐ ¥:{ö¯êêê>¿uÉ¥RéÉ“Çõô:ôì9´%íôaii©Ï=1!Žt„yq±1<÷ŠŠ ÒAÚ©³gÿ‹ÅŸoÔÖVæpZ:ÒcЈÐÌÌìÞÓPÒABäÍ]°h–½ƒé íÑÙ³‰D¢’òÞ>  £F„÷oùgf¤“‚"/#-õþ-¡PH:H»sîÜþÏ· º»ŸÐÒRz¯*Œ*„………{~ÛJ:E555¤S Ô^„‡¼ØóÛÎÒÒRÒAÚ—sçö …ÂÏ· jj***¾÷´ƒ¦F»vízÎûš¶NGÒAÈP×ÐpZ<Êô³íç+«¨Žƒa63m‡­§§G:H;rþü¡P8hÐ ÒAÞÛÇTA`Ôˆ°¦¦¦° ¿Š©3!ŠŠŠÓgÙ=¸ßaæÔ‹çNÀqÐÑÑÙ¾};ý¸W¯^ôƒÀÀÀ#FŒ3fèСÿüótîÜyܸq ¸ÿ>´ñšmÕÕÕ3f̨ý …ôÚÛòrR©ÔÖÖ¶ººšt/“P ,,Èÿ°Så‹tþü@ð9WA¥«‚À¨annî†Õή›6ÏqhÑ•%_Û¹óÎóÜËJKŽÜá oñ׎ï5:TWW÷÷÷ÿþûïëÞÔ{Íš5< _VÓ³Ljjj>LOOŸ7oÞ¤I“>,ªT*•“ké«´º/^¼8sæLyyùÛo»"''7cÆ GGGÒY¾@‚Žìßë`;ÍÐÐtòJJŠâââ´´´>|H:Ë{ËÌÌÐÐPTTüðrÆ BØ¥K—=‡ÿ11íF:1ŠŠŠKïû*øü÷-‡òòòNNNGýá‡d555ïÝ»7kÖ¬:hiiɶ›˜˜”••5ìä÷ß÷ññÑÐа²²úú믫ªª(Š:~üx¿~ýÀÌÌlòäɯ^½:tè˜1cæÎ+‘H àëëûí·ß¾«ñ£GèÏ_¾|ùøñãššZ·óŠŠŠŸþùîÝ»>>>7oÞ<{ölRR’“““T*åp8rrrE¹¸¸<~üxÅŠêêêçÏŸÏÏÏwssspp ÃwëÖmÊ”)tƒuëÖÅÄÄ8::*))õïß? ))©ÞNéuÕíA ÈÅÎ;é¯ÚØØ¼|ù²ººúÌ™3½{÷ž>}úòå˱¶†1ã'˜˜™éà J@"‘véÖ͘t‘‘‘ö1Uµè¶D"¹ìG[»£ZMÛ(/+ó<Û.Ö®­­õ»â-‹éŸ;‹Å¢(ªƒ†Æâ¯o^½2hР&Ý677ýúõˆ#ž?>`À€„„HOOßµkWpp°ššÚßÿ=lØ0ssóäääèèè5kÖÓÿ•ubffª££#•J§M›¶{÷¥-_¾<((tuuƒ‚‚ú÷ï»eË?????¿   „„„&ËúïÙ³gbb"L:µ^û?ÿü399ùåË—AAAªªª&Lpss³²²’ (uuu#""´µµ‡ ¥¬¬\TT4~üøW¯^Ñ×m`mm½{÷îáLJ††NŸ>½°°°áNëú=TWWË@GGÇßßĈ!!![¶l €=z$%%}’Ÿ~ÛkÏ‹nóùåe¥¥ógÚ°Ù ¼K~~®Ï±Ï´Þ¸qGCƒÍb±~ÉÉi›©iïf{`Й™¹dŽ-‘©Ñ >ÿâ¹3m¼Ó&ÈκòËË/œá)¶àVÝŠŠŠK–,qww—m111¡G`‘‘‘ŽŽŽÑÑÑ•••ãÆ“J¥û÷ïoØÃéÓ§7nÜ(‹—.]ëêêJo—}Š]MM.lýúõ+,,,((8wîܶmÛf̘ÑDã†vîââb``ð×_©ªª@JJŠ••ȦU;tè`ddD?¾råÊñãÇåå勊þÿu@ZZÚðáÃ`ذa***î´žº=Ô=666 ¤¤4bÄ>|xFFF£ßúTnû]?²ïج,œE *„ººº¶üd1€ØÇ‚×ý°yÖÜy¤öNKŒsùÏÒºÃAM-í¥ŽN¶sç9-´oI«V­²²²’]‰‘””Ô£GèÒ¥ ý¹ú=Âw=}ذacÇŽ½{÷>tèPïÞ½@"‘Ð ê¾½·xñâ#GŽdgg0 ÙÆ4ssóììlCCÆí×®]»{÷î£GÚÚÚêêêvëÖíéÓ§£F’ È꾢ܾ}ûË—/E"QÝB[ï%§±±qXXØÐ¡CÃÃÃé²×hȺêöP÷P¤¤¤€H$ 6lXxx8]/srrLMMßu0ÑÇmæ,yrÓ r,ñI˜sî'(Š¢K †¦][ÞƒªªªÝÁƒéÿþþûï G"‘8p Ù§Ï;W(ŠÅâÕ«WÏž=ÛÅÅE(ÊËË;ÖÍÍ­^ãE‹uíÚõ·ß~€ãÇ7ݘ6oÞ¼›7o:;;×konnÎáp¾ùæ›^½z}ýõ×þþþGŽqrrEEÅû÷ï×ûl޽½ý¸q㬦¦ö®ïåСCË—/WVVîÓ§½^e C6<ô 3gÎlذA,Ÿ>}nÞ¼){‡}ZfæÝMLUðR"Ĩ÷SRRÌÍ͉Lfgf.²›ñݦ-v Úx×u%ƽ^ùÕ¢º£Àº%ð˸1ouuõœ9süüüZþ¡Ó&‘HèOè„……mذáñãÇÙa½÷S¥RéìÙ³½½½ßë•J»Òžß#ôò8wdÿÞ,œ€¿G¨¢¢Íbq(Jú û¯ª¦¥%˜˜´Ê¡Æ÷߃¦¦æ¢eŽ=z5P¾T§OÕÒÖ^üõò÷~F8Ž¿¿Ûì+$$äǤ(J"‘=z´ÞWKJJæÌ™#ûï¤I“¶nÝú^ýËÉÉùùù}‚ ¨1½ûö[´ÌQ½Í?:×þÕÖR,–XEEéö©¤¤ž’ò)+ë§Å BرcÇUk]I§ ¦¨ `ð°;ÿÜÇá|™%°í=úÉ“'ïúª¶¶öû^’Uw8ˆZ›ÅÀAá=˜0je™ôôôÙ“Çßò»F:::Í[´« B´ëW¼gOŸ››K:"A…PYYyàà!:ºHA‘§ÛIoàà!_ê{è½0hjTOOoû®?I§@µ #­ÆŒ´£­­M:"A#œœœU_/ypt„ywn­úzIAAé ˆ<ÿ«±Ø"„jH^ž­¡¡ûaÏ•JkËÊ>× *„ÇÎxNj&N6qê´NðCM©­­))ùò?OÄ ©Ñüü|·ÍCŸ?#!DÞ³àÇn›7–””‚ÈcP!¬ªªzYTøy ÕB­ª° ÿed¤X,&‘Ç ©Q“«wI§h×rss?÷%ÖP»RRRBß룚5wÞ¬¹óºtéB:"A…°¸¸øèÁýVÖÖý,ÎÒN…„„Ô] ¡7dÈÒ÷22âYðc‹CûqqÄ BXVVvñÜi½.±6jóÎß««qš}b**ítD˜÷úâ¹Óþ¶ a=µµ >åZ£íƒ ¡™™Yàóp‚·ajçúôkü·}‘æ-Z2Çaé íŽX\õæM"§wê~/55Ü¡³`PU¨¨¨¸éwÍbÀ@3ó „KM~ûêå°~=›¸å$3ÉË×öêeN:E›bЧF ÿÚõktd8é !ò"BCþÚõkYYé ˆ<ŒŒ.\½¡¥…K "„`šíì‘cÆvîÜ™tDƒF„‰$'+SPYI:Bˆ¼ÊÊŠœ¬ÌššÒAy *„¹¹¹?¬]ý4ø!é !òþ°vuQQé ˆ<MvéÒeß‘ãF&&¤ƒ „È7a’™ywÒAy ²ÙlÝNzÊ**¤ƒ „ÈSVQÖí¤'//O:"A…0++ë«y³îÜ"!DÞí~_Í›ŸŸO:"AS£ººº·mïg‰ËÊ „`Èð·m×ÒÒ"‘Ǥ3|ÊÊÊrrM pÕÕÕ'MÆVPh³H¡vËØÔÌÀ°« ¾W‚Ø_̪ ‰‰‰=zôh¢AjjêäÑÃ]7mžã°°ÍR!„Ú§+—<ìß›••ehhH: "Œ Æ ›4ié$.""âÎ;Í6ÓÒÒZ긢Wï¾m !ÔÎõéשã uuuÒAyl9r䯿þJ:ɇ;zôhK ¡¶¶öŠÕkÚ B¨ýë?``ÿñÖõ©ÑôôtÛ‰cý¯ù’‚"ïš·—íıoß¾%‘Ç B¨¢¢2tÄH½ÎxCj„tÖ×:b¤’ƒîº‡Þ…A—OtêÔé§_w‘NjFŒ²1ÊJ[WáGL*„ÙÙÙ+–.\ôÕ×Ö“¦ÎҮ͞dmdjJ?výa³™y÷™ÆLž6c͆àøáþ×|o>€ˆÐ“G±ªÅbÛÙ¼cGmFwÈVMM͘ñ/e±XôFŠ¢„ÁV~3zœµ,€Ï¥ ö 7›óä‘CQá –.‹ñÄ›q IDATŽ[¸ì?Á‚¶îü­5Ž úòÜ»uÓû¢ÇãA:u"Æ BÈb±8Ž®¨Ôe•C'xu·¨©©§¥$SÅb±ãã444éíþÜuèÄ)-íŽPÁç_ö8×h3Y‡‰ä¯]¿^¾pnþ’e²e¥¥ß._V·^¹èY¯J¥Ò†‰>¸çyÕN9|Þ猱žðIú’ɳå9‹Å"‘Ç Bh``päÔYÒ)>Wý,ľЖcÉõé׿ /Þ¨¦®úüÙèqÖªªjê:¼«™Œ‚‚‚‹ë×UNó—,“m*Uë\ÌzóšoaAÁÚ•ŽÃGŽZüõòù¶6CGŒLy“d3Ã6ðî’’bGço¬'M9~ø`A^þÚ•Ž÷6‡~™ž~í^PVFÆ¿l§¤[AaÿÑM/³€kÂä©&OÕÕÕ%‘Ç B˜ŸŸÿÓÆõ3ìæ 9št–v­J(¤ë üºw‡0aÊÔë>Þ0sÎ܇÷é¯nÿíÓî§O)«¨|·iË»šÕ¥Þ¡ƒX$’íE"‘¤&¿qÛõ§¬ÁôÙsDYY騱}>¦Ââââ#û÷Ž?±?Þ€¢Iu§F\ÖX H?ž8Õ¦^Ë󼓙éil…ÚššµßoÚûÛÎF›Ñ²Xr5ɘñã/•m¤(JTUõ놺í‡õÃZîè1v dÇMœ´v¥cÏÞ}š½£äú·þ±Ó 8 ýƒï¢ÆEG†?}ôÐâïC¸¸ Ë(‘ÔNñ!ÂÂ"?²¸ººîß¿ÿãÓ°X¬ùóç_ºt©Þã–pssëׯŸ½½ýì÷èÑ£...Í.º’’bnnNdÑíìÌÌEv3¾Û´¥î_v„A^瘰èvxxxppðªU«”••›h–ŸŸëãs¬[7ã6 ö ݸqGCƒÝ耜¶™šön¶‡Öz±œ••õÏ?ÿ´¼ýŽ;|||Z) ­[·nâíæa)BÃâ¥â¿ì*C† ¹xñ¢©©éþýû…B!é8íÔG¤¤¤ñãÇ+))iiiùúþk Ï®]»º¸¸Ðm¬­­•””ôôôöíÛ,kèС–––***²-àååÕª×ô”——_õöJM~Óz»@}.’“¯z{UVV’Òê¶oßžŸŸ¿~ýz,‡ú¨B¸xñâèèè;wî<~ü¸W¯^ïjóæÍ›çÏŸ÷ÝwßÿýÇ ;;ûÌ™3½{÷þý÷ß ++ lmmé­¤¨¨èàŸ»^FE´Þ.BŸ‹È°Ðƒî*kîCÈ_€éÓ§<ŠŠŠ°6ê£>,mcc3nܸ¦ÛPeee%•JàéÓ§0jÔ¨š››GFF=;¡¬¬ÜªÓFFF¯ßÔÔÔj½]¼‹ìʹ²ÒÒ¶ß;B¨¡Ñc­-’——/,,$¥Õ­_¿~ñâÅô籋‹‹×¯_¿k׮͛7;;;«4÷é3&ø¨BhiiùôéÓGuìØñ]³š–––¹¹¹ìСC||üرc·mÛÆf³á3¢4…ÂÂÂÜÜÜþ4sÿþý›Y­­­e±XÐæ‹*ÕÖÔÀ±ÃŽ>ÐÆ»F5Á™t€¶Äb±(Š¢Ç$………ëׯÿå—_|}}›Ì0ÁGÂóçϯZµjÊ”)ŠŠŠ§OŸn´Í… ¾ù曥K—²X, ‹iÓ¦5Ú쫯¾:sæÌСC³³³?,ŒD"i¶Í/P#´º šºú¢¯þCdסz^EG½x¼iÓ¦:ÎÒêÊÊÊöíÛG—@“““J¥½{÷vss3¦ñµ,å£ aïÞ½=z$ûoÝë e{öìT÷Y²/]ºtIv}…»»»»»ûÇ„IHHhúò‰ªªªç<»ëvÒû˜}˜µ+‚Ê%ŽNm¿k„PCùy¹9YY«¾^¢¨¨H:K«[µj]éسgO777{{{¼Ê–Æ  êååå545™pÒ#„𥍍¤¡©É„J™™ÉãýwÑD,bбÈÊÊúÏû€»·IA‘w÷æÿ,°ÏÏÏ'¤ÕýþûOŸ>^^^±±±XëaЈ°S§N?nßÙ·¿é !ò†qGªwØ©¥Eàcäm)33344ÔËË GM`P!TUU;a‡Ã!!Dž¡‘q§Î]š^xì •J#""ðþÃMcÐ „´´4›1ÜW[w!7„ÐgÁ×ë¢ÍîÛ·oIi]&&&X›Å B¨¥¥µl…s¯>ýHA‘××ÂbÙ g&\;šÅ ©Qmmíå«V“NjúY èg1 !FÓÒÒ¦[¾qõ é !ò|/_œn=ú‹ŸE-Á B¨ªª:j̸.¤ƒ „È3045fœ’’é ˆ<MvêÔiËŽ_I§@µ ÃGŽ>r”¶¶6é ˆ<³³³—/r¼w‡t„y÷nù/_äÀ„ êQ³TåääTUÕ8 x!BØlUU5¼Æ£¦Fõõõä‘NjÆOž2~ò]]]ÒAy z5”——·uƒë‹§Á¤ƒ „È{òèÁÖ ®ÅÅŤƒ òTÅbñ›¤¼G¦è‹Ç€ÄÄDÙ}?G-ifll|ù~R!0ÓnîL»¹;w&‘Ç€Û·oß¾ýåßœ¨¨¨èÐÞ?ÆM˜d1pé,!¢ÂÂõÿçoMMMÒYaìçÏŸ“Îði5Ý ¼¼ÜçâC##,„¡¤„xŸ‹öÿ¹ !b1‚t†6Ò­[·Ç¯H§@µ ó—|5ÉW†††¤ƒ òôa™òòroOä¤DÒABä%ÆÇy{zTVV’‚ÈcP!,**:¼ïÏWÑ‘¤ƒ „È‹Ž?¼ïϲ²2ÒAy º ÞØØØÛÿ®ºÞu!3ìæŽ›0©K—.¤ƒ ò4"‹ÅI ñx!BÊJŠ“â«««IAä1¨æååmýW–A®²†Âû¢ÿÇ ©ÑN:mÝù[ï¾ýHA‘7|ähM--¼C=FBUUU®Õ%%%ÒABäéhëtÄ?55š––6ÃÚÊÿš/é !ò®^öšamõöí[ÒAy *„ÚÚÚË¿YݧŸé !òúYX.ÿfu‡¸ÂbÒÔ¨––Ö2'gÒ)BíB_ ˾–X0jD˜––f3†ëçëC:Bˆ¼+^mÆpqj£ ¡ššÚØ “ »’‚"¯«‘ñØ “”••IAä1hjTWW÷Çí;I§@µ ø#‡qGjii‘‚ÈcP!ÌÊÊúzþÜ¥ŽN¦ØÎÒ~ÍždmdjZYQ1oÑ›™³d[@¯s—­;k´ŒÏ¥ ö 7»—“GEE„/Xº,>66:"lá²ÿ?¢;G¨mÜñ÷»tþì³'Ázzz¤³ ÂTåååµ´µ9ŠŠ¤ƒ´kÊ**‡Nð„BÁÊ% é"GoiºÌ•‹žu ¡T*mt «÷<¯úÀÉ#‡Ïû\€1ÖZãÛAè]”””´´µq‰5Œ*„úúúûž$âó •š{ï¤a››×| Ö®t>r”Ÿ¯ÏÐ#SÞ$Ṵ̀ ¼{§¤¤ØÑùëISàøáƒyùkW:@ÞÛúAfzúµ{AYü²’Rl…ýGOà)ÔzÆMœ^:vŽÃ3óîb±Øvî¼ò²²uÎËéBè¼fÝÀ{t³%sle`ß®_V®^k1pл†’}*Á‚nú]½~ÅGGG‡tDƒ auuuFjjeŸtvMYEåðÉÓ1/£<Ïð†qGÂ;¦Fëµi´3óîð(ð¾ßo9yùò²²f÷þ6;Ûbà À*ˆZŸ_ž‘šZSSC:"A…ÐÈÈèâõ›¤S|ú[ «ÒSSL̺½WŠ¢èòròôÞ±N_ò©®®^æ0§ÙýêƼŒêo9G„¨µMŸe7}–]çÎIAä1èoMQQÑ?v½ŒŒ äó0Ónޝ×Å÷m3|ä¨Öº\½|I¶eÜÄIkW:ž}z½7ÕÒÒ2ŠŠ I%ü@CC£ÞFŠ¢D"¶‘Q÷–ôÀ B(‰^ǼêÞ£§Šé,!ÂŠŠ SÞ$ٌńPL™2eøðá¡¡¡EEGG7Z»w79r,Ùœ&$$45õ_—P%‘(nذ³…Wa1¨æççÿüÃ×M›çt%S‹ ŽìßÛ|;„PëKŒ‹ŽÏNNTWgÄ,‘¡¡aHHÐ&Õ+‡PS#ÉÉyC8削 ÑÐøÿZFWAW×-½éƒ ¡ÁÞ9}RJKJ¼<ΑÚ;B¨¡'NŽ@]###·mÛÖ»wo5µæ/óý,PTWs\]·¼Ç€‡A…Åb)((ÈýoÅ“6và¸;‘ý"„UR\TŸÿÕ<;‡C:K[ظqãþýûéÇrrrR©tôèÑnnn&L€üü\¢é> Š‚êj…uëÜ MÞë‰ *„ÙÙÙ+—.tÝ´yŽÃ¶ß;.†P»x÷Αý{§ÏbÂ¥„ùùùG‹EQÔÈ‘#e%ð‹AWÁµkݺv5yßç2¨êééýüÛîž}ú’‚"oĨÑut´µµIi {öì‰D0jÔ¨/¯EDÂ^»v»‘‘Éüƒ Zt»´´ôǟ܆Žàâì(B(.6&24dï®_rùjƒ !GÆŽ€jG¬õ'‘Ç 2¦¦¦N5ìúoÒABäù\¼0yÔ°œœÒAy *„êêꓦÍ026!!Dž‰™Ù¤i3TðÓs§FBL†S£5"ÌÊÊújÞìû·o’‚"ïöë_Í›ŸŸO:"A…ÍfëvÒSQU%!Dž²ŠŠn'=yy2k.¢v§FBÌ…S£5"ÌÍÍݸÆåÙãG¤ƒ „È{¸qKQQé ˆ<B‰D’›“]YYI:Bˆ¼Êʊܜ욚ÒAy85Šb.œEÀ¨aaaá¾ß‰Ž'!D^xè‹}¿ÿRVVF:"A…°¢¢âÖëéi©¤ƒ „ÈKKN¾uãº@ ‘‡S£!æÂ©QŒ–••yžå%ÆÇ‘‚"/þu¬çY^EEé ˆ<Ââââc‡¼ŽyI:Bˆ¼WQ‘Ç(//'‘Ç ©ÑÚÚZÿ Ç*ªjL¸'5B¨i¢ª*¡P0cü\\1hDXUU^TP@:Bˆ¼‚ü¼¨ˆp±XL:"A…0??ÇæB_<%!DÞó'Á;6ÿPRRB:"AS£"‘è¬×•ÎúúÚuHgAV\T˜Ÿ›ûŸ…ó8é,ˆ0B¡†TsrrV}½äaà}ÒABäܹ½êë%ø¡À& íèéé¹íÚÓ£WoÒABäq­ÆèvÒÓÖÖ&‘Ç B¨¬¬l9hªªé !ò:uÒSUUUTT$‘Ç ©Ñôôt»)nݸF:Bˆ¼ëW¼í¦LÈÍÍ%‘'ïææF:C‘““㋪ ÒQG—t„aòòò]ŒfØLÅA!bÐ個n#„þ ÝFÀ¨©ÑÔÔÔ Ü!×|.“‚"ÏÛÓcwHNNé ˆ<Buuõé¶³MLÍHA‘gjn>Ýv¶ªª*é ˆ<œE1N"`Ôˆ033s±ÝÌ{·n’‚"ï–ßµÅv3óòòHAä1¨*((t5RSÃëB ¦¦nÐÕˆÍfеÔè]pj!Ä\85Š€Q#ÂÜÜÜ «ŸßóÜiíŽ9Ι“Ç8Ž^ç.îÿü-ªªêjlâåqîmvV·î=nù]{Õ§_ÿÇAî<$2,ôƵ+ý,¤¥$_ñò465+//»xîLG]6›}Æý¸¢’b'½Î'Žª®w52¾xîLÞÛœnÝ{ø_ó}Ý»oÿ‡÷?´48"4Äÿš¯Å€ÉI‰¾—/švëVRR|éüYÝNXrrgÝO())éèv:ùÏᚉaW#ϳ¼‚ü<3óî7|}âcczõí÷àþݧZ òÜÿúUËAƒ“â}/_23ï^RTxÉãl§Î‚s§N(«¨hwÔq?úwmm­A×®Îð òͺ™_¿â׫OßÀ{wž?¶00ôù³›~W ’÷úª·—yž…ù^ç:wéR[[{žwRUMMSKÛýèß%Õ7ìêÁs/.*4íf~ÍÛëMbBÏÞ}ïÞ~ñ4¸ÿ€!ÏžÜò»6pÈи˜W×|.wïÕ+?7×ëÂùÎúú5ÉùÓîjêê§Ž}Ãs§N”––˜˜uó½|1åÍ›½zß¿}3ôù³þ–ž?y|ûÆõÁÃ†Ç¾Š¾æs¹gï>osr.{ž×74‹ÄgNuÐÐPSWçÿ‡Åbu108{ò8¿¼ÜØÔìŠ×ÅôÔ”î={Ý»åò¢Ÿ…å³ÇîÞô4tXLtÔõ+Þ½úôÍÉÊô¾èaØÕHTUåq攆¦¦ŠŠ*ïÄQyyùÎúú¼ãÿTVV›˜ú\¼ž–Ú½g¯;þ~‘á¡}û[>}üðþ훃† {áçëÓ»_¿ÌôtŸKº •Îò4µ´””•NŸ8Æf³;wÑ?uìH•PhdlrÙó|VF†yž·ü®½ŒŒèÓß"øaPàÝÛ‡ Ž÷»êÓ·¿EzZªÏ%O÷nù@Ðý»×¼½ ôù3ÓîãÁs éi<÷‚‚üâ¢Bž{ZJ²H$òà¹Ç¾Œ€Kçμx ~¾Þwo@àÝ;×½/@ÈÓ'žgOÀ똗}º¡¡!ǀݻw/Y²díÚµ“&Mzúô)¤¥¥ 2„Åb>}ºnK 4h££ãÚµkY,Öš5k **jöìÙk×®1cF\\\Ýb±¸¶¶633“þ¯ÝÖ­[éÇ Ÿ%Ûïßÿ=zôh‹¥££sìØ1عsg=‚ƒƒ›}â¸qãþ»o ¡¶EW&ccã‡Ò[ª««G]ïl …ôù_﹉„¢(×·o߆ÛßÕ¦U¿zw­Ñ¡CŸióçÏŸ2eŠì÷ë—_~5 ¶)IDAT±±±yóæÍwß}Go‘J¥=zô¸}û6EQb±ØÖÖVöt???Š¢.^¼¨§§GQÔùóçkkk)Šº{÷n÷îÝëîˆnyáºeMM¾¾~@@EQ‡¢÷.•J»uëFQÔ•+WFŽY/ó¦M›8ΤI“þúë¯äädY¼FŸEï÷æÍ›ô.455³²²(Šòóó;{öl ŸHÃBˆÚ}8p`Ú´iô–³gÏ|xìØ± ÈÈÈpppX³fͪU«V®\YQQ±eË6›½~ýúäää¾}ûšššš™™ ><222''gìØ±Ó¦M‰D~;‰D¶ 7mÚ4ƒS§NQµuëV{{{WW×™3gîÝ»×ÞÞV®\yéÒ%º‡]»v-^¼xÍš5'N|òäIÝ´õºŠµµµ]·nÝܹs·mÛFQTddä¬Y³Ö¬Y3}úôׯ_êŸúŒÕýEHII™2e ½½¦¦fôèÑC† ©¬¬¤·¼yódÿ­ûtzcDDýëy÷îÝyóæ999ÙÛÛ³X¬º-+**ê¶LJJ’==$$„ÞHïèÛo¿]·n“““••UÃØoß¾=yòäœ9s8ί¿þÚijê&¤(ÊÙÙyûöíE-]º´ªªªåO¤°¢¶GŸ…åå庺º±±±E999Ñë6›9s¦X,¾xñbÇŽeå§îïöÎ;ÇŽÛp{Ómè—<ÏÒÒòòåËô—~þùçeË–Q ^,{{{Ë^E.[¶¬Þ_ŠwíºîKcúW1??Ÿ¢¨œœœ½{÷6¶ðUv×í;¾FLÖÄ܃«««žžÞ«W¯èÿ6QëžØ'**J¶å]-©ÿB@@5(„åååôù|~Ý=òùüÛ·oÓ¿ Eyzzª¨¨4ñ¬zß`dd¤AZZÚúõëë~_Í>‘¢(|‘¡¢¢âââ²gÏžÛ·oO:µÞWcbbºwïÎápìììàÊ•+u¿ºzõêeË–¥¤¤xzz¾«ÿwµ;v,ýïË—/eû2eН¯/lÞ¼¹¢¢báÂ…¿üò ØÙÙegg‡……¥¥¥uêÔIUUµ%ßšµµ5ôêÕ+??ßÈÈhܸq#FŒøñÇ“““7lØÐ°}§N,X°bÅŠ“'O&''¿««”””¤¤$+++àp8ׯ_OIIIII9{ö¬««ëíÛ·ååå[1–¦¦&\¿~½ÿþû÷ï_´h}ânݺõèу~ÏO$Í›7¯Ñ§ ‚êêjmmmÈÈÈhz_fffúúú/^¼€ððpzc·nݺuëF¿{—••µxñâºOIII±±±¡Ç”Àf³õõõ›}–ÌÀõõõ,X°|ùò–ìî_Zúê¡ODör¬°°PCCÃÁÁ¡¶¶¶ÞˆðÛo¿upppvvvvvîß¿£#¿Fûla›””½B|ö왺º:ý¸Þ‹å?þøcñâÅßÿ}jjjÓßN£é6111»wï633³··¯¯å¯²¾loúõ5b²¤¤¤ùó瀋‹Ëêÿ€˜˜˜Ü¼y3 @KKkâĉqqqÔÿfÝ]]]—.]úäÉ“ÒÒRúéß}÷ìñæÍ›·mÛ6xðà5kÖÐEeóæÍïjIQT@@À Aƒœ·nÝ*''G‹ŠŠš>>ýû÷'§)XQ›’½P]»v­lcaa!½qõêÕÅÅųfÍ5jTBBýÕ'NhhhXYY]ºtIöR.//¯aŸ...QQQ¶iø20==]öa'''>Ÿÿ®ËK–, júÛqqqÉÎÎnøÒxÙ²e'Nttttuu6mš———X,:tèòåË·¢O/O§ÓCBBzX¾¡„õãºuë–ªªªŽŽNAA¶¤¤¤ÄÁÁAJJJSS“Á`ÙØØHIIÑh´²²2 Æ ÓÒÒÚ²e @pqqÑÒÒRSSKNNî¾¹p]؆úúúûöíëß¿¿¾¾þëׯ`Ë–-d2YJJjĈ Xá.{ÖÒÒÚºuë{W ‡”ŸŸO¡P$%%---óóó÷íÛ'''÷üùó¹sçêéé±X¬U«V©ªªr8œêêj"‘xòäIá¶ÛÊ•+åääÈdò²eË Ëá W4aÂ'''HKK#ÿ®>ñ7²gÏlCŒðW)øÐ½ºùQ™˜˜P©ÔP(ìL°²²200ÈÏÏOOOojj²²²²··/++suuuttäóù ¯¯_TTTYY ‚ÍMLLºo.\Ðh´¬¬,áÛ¶mãóùiii>ÌÌÌ$‘HXá.{€•+W~h• $ …‚­µ°°àñx®®®FFFD"1--Ïç?~ü®^½)++ÛÔÔTQQÑÐЀ)''óàÁƒ””ìp„_¸¢óçÏ„ׯ_/Z´HWW—Çã}ü»|òÿÖå7²`Á¨¨¨¨¨¨èòU ûнºJX?. ‰   >Ÿ¿xñb,a‘H¤E‹ H$IIIyyyIII‰Äçó`É’%ØZlŽ­í²¹0X¶lY—ÁÁÁ|>Ë–- °yóæ÷îYø/¶û*AH$©ËÚ¿ÿþœ‘¸¸¸L›6môèÑÓ§Oïä¶mÛ ¤¬¬¼víÚî‡/\Q[[›’’ÒîÝ»UUU7nÜøŸß•ÀÓë²våÊ•‚6D—¯zåÊ•Gð=t¯îAúÆ 8äûehh˜™™YZZš‘‘-177§Óé÷ïßoii¡P(fff[·níèè(//ÇÊHJJ ö ØÜÐаûæd2Y¸: ‰.ø|>lß¾}êÔ©îîîóæÍãÿÿ=ë.{Ö}• ¤Áƒ§§§ckMLL:::~ûí7[[Û;wî\ºtiÒ¤IàïïÏãñ.\¸oÞ¼!“ÉŠŠŠ`bb’œœ|ãÆàààmÛ¶u9üåË— *’––ž6mÚöíÛëëë}||à?¿+Á7,üc[[›ðRRRP\\¬ªª*¼¹¢¢byyyRR’ ä{«û kX?®ƒVVVŽ3FII [«¬¬lgg7mÚ´¶¶¶'N‰Ä &TWWw߃’’ÒØ±c«««8Ð}óO cþüùçÏŸOLL”““ûО?R©°cÇŽq¹\+++.—ûÇlܸ±¢¢âÊ•+Ë–-[°`Amm-LžlèçÏû P·¥RÞ56·ñ%†8ÚuH5Œ®Ãd•úå•Œí¡¦cp~s’×x#Šõ‰¸SÞÓ§Ù ±;,,pÑ"ë¡Ã׬^²%ÄÜÎ)páÂ#‘Q†–4Ÿ™3/$^Ö66?nlFvî€Az.ÎNO^¾’S`G³b6·6wr‡:9p$¤^¾©9ÜU¡¯jN~ç˜ÑõŒ®^OšÙ ,¨q§ãgLŸJâ¶7<ü—ùóm\F¬_·®ËÉ6gö¬ó/i›yyz¦ff©ê¸ òðé ÁÉÖÊ#q´ï$H¾®®áæ"«Ü/¿ðŸ“í¯ôI^Œ(Ö±'ã¼gL³u¹{÷nÁɶeës[§E¿üu4ÚÀ’6ÛÛûÒå?µŒL;&ãŽàd{-«ÜßÎÚª¾¥­¹ƒ;ÔÉK’~ù¦êŸ“-¯Àsìh }ã+]Ÿ<ÑË„f,&Fp²-[º„6ÄuÕ¯«vlßajãðËüù‹Ñïr²åå÷×Òâ`÷òMUK'¿¬´¢¢"žV||ü¾½{FyþdemÓÀdªkh›˜2ëÞ ÒÕÓ74b¼}k4ØD[G·¶¦ÚÜÒJ]}`Ý»w–Tš²ŠJSc#ÕÚVN^®•ͦÙÚIJJvvvÚ88ò¸<°stje·JIIÙ:8²XMd²•µMcC}ßþýÍ,(õõÌšÆ&¦uïÞéêëë¾}[k<ØTkÎÛš UU]YWG¡Z+*)³šš¨6¶²rrm­­ÖvöÇÖÞ‘Ãá{'g6»EJJÚÆÞÕÔÔG±…fÝØÐÐÀS Ëzf†–¶Ñ`“ºw ]}]}Fm±©™–ö ·µ5VV¨Õ3™V4E%¥f‹jc++#ÛÖÖfmç@$¸\®­ƒV‘£sKK‹ŒŒ´µ«©QQIÙ’Jk¨¯ ªfjnÁdÖiji®{ÇÐ70ÔÑÓ[[kbn®¡¥Íx[K¡ÒúöïßP_oemCîÓ§¥¹™fc+--ÓÞÞfcgO y\®­ƒSgG‘H´wÂb5ÉÊÊÑlíš””•-¬¨ ªªj&fæõÌ:­Aƒ ŒŒë }##]½·µ5&æ55Þ1–Tjß~ýê­h6drŸ––fš­´´tG{»ðx<[§ööv‘dçäÌjj’•—£ÙØ555*«ôµ X5Ô׫©ljƬ«¤««ohÄx[kh4x®îÛê3 EM}`Ý;…JSéÛ¯©±jm#¯ Àni¡ÙØIJJvvtØØ;ðù<>ŸoçèÔÚÚ*))iëàÄb5)`ç@cCß~ýÌ-)ÿ:Ùt°ŠÞŒlªªš:³î…flVÖ¶òòòÿ:Ùìø<Ø;9·²[$¥¤mYMMä>}¬hÂ'[½º††±‰i]Ý;]=}=CìÐÔÖ~[[ciE ¦V_WG¡Ò•UXMMTká“ôÿ'['@°wÒÒÜ,--8Ù)TëÆÆ†~ý±“©¡¥…lzú†ºúokjLÌÌ4µ´µµjÿªõL&…fý¿“MV¶­­fkO$¹\®­£cgG'v´°XÒ²2Övö¬¦Æ>JJ–TZCC}ÿ.'ƒ¡oh¤£§ÿ¶¶ÆÄÌâ`خܜ;3fÌÀóÉ ‰Wlœ°IåSŠ mÍMlllð| KRRRVhæ(AÄ”´´ŒŒŒ àû¢ûõë×—ø²[šE‚ =²o×ö 6¾gÍa0—o$L5Œ ˆ8zõò…½¥©¡¡!ž[XÍÍÍ5U•<OÔ Ò#̺:ƒøîÞ¾}{ãoÁ­ìQ‚ HüqøàîÝ»ß]Âæææ¿S³¨©‰xÎË‚{̺w޳àù/¹¢¢"'+ƒÃéu ‚ôȃ¢¢üü|Àw—ðÎ;{wnkkmu ‚ôÈÙS'Ž= øîr8œÛwïKKKQÇ‚ È—ëèhBµ––Æs «¤¤$þDLGG‡¨A¤Gnþ}=11ðÝ%,))9w¢½½MÔ Ò#·’®_¾|ðÝ%€Œ‚Q‡€ ÈW0”fønaeggïÝñ;ºèŽ âîì©“QQQ€ï„UYY™›ÅápD‚ =RZ\TPP¨Kˆ ˆXÀ—0%%e㪕­l¶¨A¤G¢#†††¾VKKKmM5zùAÄ]C=óÝ»w€º„‚ˆüw ¯_¿0¯¥Ö€ â-|×öuëÖ¾–¤¤¤¼¼ŽÑÈ·ð]ýáðx¼¡4 "‘ˆçÖñãÇýüü®¥¤÷QTu,"v&.öÈþpQGˆ CCÃcg.Š:Šÿ òŸ«¯«“˜˜ˆç„egg·xE°Œ¬¬¨ù.„°°0QGˆóçÏ×ÕÕ‰:Š™4c&ÕÄð} K__äè±$’¤¨ù^¬X±BÔ! bàÑ£G©©©¢Žâ_l­Ìßw ¼<†7³Ð]Bok–Í›7ðÝÂ6lØú­ÛeeåD‚ =òsÀ/ÖfÆ€ï–ŠŠŠ‘±zÒAÄœ†––®®.à;a]¾|yîôɨKˆ ânûÆuË–-|w Gv(RN^AÔ Ò#+~µ³0|·°‚„„„¨£@¤§$ˆDìoÏ +))iùÂvK³¨é -ÍÍhôz¯„íÚ´ià;aM˜0áÓgåÈ¢¤7ÈÊÉ-™ï{öÔɶ¶¶/Ø\MMmûöíØg++«””GGÇaÆ9889r[®­­íêêJ¥R“““±b_+økmmõööþÜ­z-¼ÿäííýe¿D`õæ­{öì|'¬ÆÆÆŠWå?H»ƒH$ŽŸ45"ŸO Æ¿sçNSSÓW¯^ÐéôfddÔÖÖÆÇÇ:thåÊ•žžžááá]ŠVR___F+((è¾ÏeË–q8œæææØØXww÷Ý»w[YYñx<ì×­©©™››«¨¨èää”››+++Ëd2=<<òòòº¬-..vss‹‹‹ãñxUUUÝëêòu o¾jÕ*ác×ÐÐÈÍÍåñxóæÍÃú΂CøŠ¿èojþüù©©©ßÕËÏõL¦3Õ¼oß¾x~¬áÕ«Wé)É?Mš,%%Ý;52ëÞý¶,¨wêú¾¤¤$‡ÃÁþjjlŒ‹‹‰6·¤üç–²²²³gÏŽŽŽ¬µUTTäçç‡ý‘3™LWWW>ŸÞuà//¯-[¶DDDÌš5ËÃã´´tÑ¢EØªŽŽèׯŸ¾¾¾¾¾þòåË;;;333wïÞíïïߥ˜ d÷ðºï3((ÈÀÀ ¬¬ ª««±‹V‚œúöí«¡¡-ILLŒŠŠ" £ûZhhhÐÔÔ%%¥÷ÖÕ…ðæ]Ž]QQÛ“ÉüÏïùDEyÄ6–§§'žVNNÎþÝ;ÝÇŒíµ„ÕÙÙùøa©™%e€ªZïÔØÇ{ùì™àG¬Õ¯ÿ€O`gáÂ…C† éìì|üø±±±1¨©© ÚàØ5¬÷nH"‘BCCÛÛÛíìì<<^LØ„ nÞ¼Ù¥°ººº­­­¿¿MMMTTTxxx@@€””FÛ·o_—=xyy¹¸¸XZZ’Éï¿e¼fÍš‘#GR©T¬…õ‰½÷ØUTTV­ZuÿþýƒbètºXß4øì?3„jø¾†•ŸŸ¿ÿp”_€ŒŒLïÔX[S=uܨ»E’°::Ú§ŽUÏd€ž!–ª°¶@ÂÉ㿆õ=c³Ù~~~ ß® .—+!!ñúõë3fdgg÷dW—ö0ÞÞÞ111²â3.Ûwx ëjâEÊ`ÃY³fá¹…UVVvé\ ŸŸ{-a‰ÖÕKë™L}C#ß_ RÈÉÉ}Ól›6mb0ØÃ>Â'L˜ ø1$$ÄÅÅå³vþ­ƒÿ¤Þ¢W¾xŠó„5{öìA¦ÿ}±::Ús³³¶íÙ‡§TÕk\]]ÓÒÒÞ»JQQñ³F³ëÒ¼B¾Š=QøŸæ+++k÷¶-m­­¢¤7ð¸¼ÐC]‡£l…àOÂÉãØsxnaUWWßÏ»ËápDHo@C×#8ö¸ì!t´¾Ö”)STõŒE‚ =µyÇnüw “““×­\Æþa^ÍA¼Š:¸oç΀ï„ÕÚÚZÏdâ÷± ùQ°šš°gzñÜ%ôôôT8HÔQ ÒSÁë6â¿KxíÚµ@ß9‚!SS{¶o]³f à;aÉÊÊ*)« »ü"îÈä>}ú¾»„#FŒR ê(¾#¢YYY¢¡«A˰.!žÖ… –¯\yôd‚Â^yýqÈ+ týúuQ‚ˆlÀïÇæ5¿ëë>|Ï K]]jmKB©ŒŸ4eü¤)¢ŽA¾±‰©¹‘à»…åììü«lQG HOyÏ™‡ÿ»„§NãâÄjB3?#ˆx ^üˬY³ß-,“IÓ¼{?A¾.—á#)&F€ï„E¥RçÎÿERRRÔ Ò#cÆ{á¿K;ÂÁº©±AÔ Ò#KçûN:ðݲ··_üwAÄÝÔ™³©¦Æ€ï„¥££ã2b$‰„º„"Þ¬¬m­Ìß]³gÏNãÞÌBw D¼­[¹ÔßßðÝÂruuÝ´}—¬œ¼¨A¤Gæ-Xhcn¤þýû‹:˜/4nÜ¸ØØØPTTÔÖÑýqæ©G¼RUˆMFKz÷î«««¨Cú<§OŸnú¯'BÿüóO??¿k)éŸ8ï1‚ ß§›7èëê$&&’`ìØ±¿þú«¨Cú<ÿYfôèÑ{•“Wè…x¾slvKa~¾¨£@ĉúÀºú¢ŽâK‚³³4|_Ãâóù<®XÎuüÕÕVW¯^¶XÔQ âÄkêô«×‰:Šðø|.— øNX7nÜ^ü ê DEE :TÔQ bÀÝÝ]Ô!üË¡=¡ÿëâ•——Q^QŒlø‡–––‰‰‰¨£@ÄÀ÷öBÛÚ-Û,MßÏa1™ÌçOŸrŒ‰TÇ*+*ÊËËß +==ý÷ kZ[Ù¢A9¹ÿ~À÷5,ooï¾Zº¨Kˆ ânGø'+sÀw ëùóç·’®s8¢A¹—›ƒ=É„ç„u÷îÝC{ÃÚZ[E‚ =réLüñãÇá+&,,üáSÐéôÍ›7­º˜7o^ê½BôL‚ˆ»ƒÄ^¼x¾E «¢¢bÆ ŸX˜N§‡„„|õ0ùùùÑÚÚÚ¾Ñþ¿7I×®ðxèAY‡®&^<}ú4ô$a•””888HIIijj2 Ár--­­[·@QQ‘””F+++0tèP---mmmì&åž={°å=;œ÷{üøñÕÄKßbçß¡–––™^ž×¯\æ '9|ÉL½M§Ó¡' kΜ9uuu999 222Ý Ì;—D"+**úùùa ›››***âãã`Á‚PQQñÅa|ĬY³®¥¤“ûü(w š8©­½mgÈFï ã>7mikk»ºººººŽ1ÔÕÕW¯^­Z½zµºº:¤¤¤8::6ÌÁÁáÈ‘#*¦­­íææ6lذŋ··· ï߯Æûw²´¶¶z{{îVVVVß"˜oG8à.Á{{{ã¦{±ûàḸ8èIÂzðà‡‡F:t(ù}S+?xð   ÀÆÆ&++ëÞ½{ØBWWWggg¨¯¯ÐÔÔüâ0>"33sgÈÆ碻””´o¼­­ùÜ´¥¢¢’ššššššœœ ªªªwïÞÅVݽ{WUU‚ƒƒ¯]»–žžž““3cÆŒSQQ¹}ûvzzºŽŽÎ¶mÛ„÷Ÿ‘‘ö¹Çõéý\á’qqq^^^Ÿ[žxzzbÍ8uüØ¡C‡ 'Ïa™››Óéôû÷ï·´´P(”îÌÌÌ$$$¶nÝÚÑÑu@BBëòù|’’€ââbKKË/ŽäCjkkõfÿ¨½­ Zš›ë™Ì^«TØ·ÑQ õÀx[»3dãñ¨#ó,4üÙoäØÛÛçääðù|lŽ{2™œ’’2zôh2™¬¬¬ü¡bAAAC† Ù²e‹` ›Í–—ÿ×xŠååå¾¾¾<oäÈ‘³gÏ^°`›Íæñx‘‘‘ÖÖÖ­­­ ˜>}ú!Còòò¢¢¢Ö­[÷¡’gÏžÅö|ùòåS§N•—— —d0Ç‹‹[¼x±›››‰‰I@@€„„FÛ·op¹\ÿœœœÀÀ@‰Ï`0BBB&OžŒíÖÂÂ;äÀÀ@}}ýeË–Y[[–””t©Ë¢ˑvÙÞÞþÞ½{YYYK—.9r¤à Y¿~½ Æ.Åôôô‚‚‚¨T*öJ0†Ëåúøø:tÈÍÍÍÃÃÃ×××××÷sõߡϞJòÿÿ944”ÿù mmmI$’ººúÛ·o`åÊ•XÂ>ÚØØH¤~ýú­ZµJx•àC^^ž––|níÖÖÖøùFãz®¢"\¿~ýCß§–––‹‹‹‹‹ËÌ™3ù|>…B),,\ºté’%KŠŠŠ( ŸÏùòå‚ LLLìììîÞ½û¡bØÿ1VVVÂû711Y·n]{{» @\\\nn.ŸÏçñx?ýôSii)ŸÏ///wwwçóùêêêÏž=ãóùYYY|>ÅŠ)))))@¥Rù|~÷’K—. üùçŸù|þÈ‘#ïß¿Ïçó¹\.¶•††Æ›7oX,–……›ÍæóùuuuÖÖÖ‚Ý puu­¨¨xõꕺºú{ëÖ}-¶«––ìFþB„?Ée IDATkìRÌÍÍíÕ«W‚ª1Äâ>|¸ð—ðttt¼¦NOÏ/þ~þÃûò…Btàÿ[LÂ(Š 'ø¡2ÖÖÖ¯_¿þ²ˆD¢´´ôG p¹ÜÎÎNII)èÅ4ÒÙÑ1PSkŽ_@ïUùoÇFÖVWa# 7lø1ãÖ/ÿÈVX—Mx …Byðà¿:::‘‘‘PTTäçç———÷Þbííí$©ËþŸ?îííÝ¢//¯-[¶DDDÌš5«´´tÑ¢EØòŽŽèׯŸ¾¾>899-_¾¼³³333s÷îÝþþþ*ÙE÷}`wª««±ë>Äÿ–¶oß¾ØÈ–D"1111**Š@ ßS.ÐÐЀ]ÍPRRzo]D°+===ì—ËþB<<<>T¬¾¾^[[[P5FQQ‹‡)¢þ·sdxº‘þºuëÄõÕ))©ñãÇ_ºté#e®_¿¾vÃÆûué†|SAóäååG{Žïµ…åfgUW¾"‘Èç󇸺͛¿PÏÀðåóg_°·¹sç ÿøøñccccPSSü“Ó½˜ÀáÇnjÓe¡²²òÓ§O?’H¤ÐÐÐööv;;;SSÓýû÷ëéé@gg'å>|xHHˆ³³3‘HüxIŒšš“Éì^rÅŠÑÑÑ«W¯¾|ù²ššv9‚Çãa{n#oÛ¶-//ÍfÓh4ÁBáJJJUUU<¯±±º×%¬ûZÁ®„÷)ü…` ë½Å”••±[UXÕ˜ÆÆÆÊÊJ‡uØ –àp µ•Íf³ßïŽ;–¬¦%ê(zÕ±ÈÀqŽ¥ªOÜÉdºººbŸ¯]»†}˜={¶p™ÐÐÐ’’‡#|í¼K1&“éææÆår-,,öîÝ+¼>ŸßÚÚºcÇAák×®|¸¤’¸NböfÏóu?WW×´´´­UTTìrùbAX—Ï£5œ?~úOcšY,Q‚ Hl\µ{+Ï-, {'gÁuAÄ”™%ÅÂØð°œœœVȼÿþ‚ bdúì9øïž}ú÷ÕËݧ´DD¼ÜÉLONN|'¬{÷îEØ×Žžl@1wùüÙ“'O¾»„¾¾¾†V¶¢Žâ{±~ù⪪*QGˆ!ÃGú.X$ê(þsÓÏ ëîÝ»‡öý%PF’ åååd2ÙÙÙYÔ b !!¡¡¾^ÔQüOâ¹3Ï‹óç΋ç„õüùó]õñ @ ãææ†ÝjA£Óé¢á_r³3™5•8OXÞÞÞšÆæ¢ŽAžÚ¹ïþ§ùJOOß¶q]+=‡… âíä±£û÷ï|_ê««{ò¨ŒÇã‰:Azäuy¹‰øNX'Nì7è?ùCäû·~ëvüw étú¯A‹ØìQ‚ HD„‡mݺð°¸\nggŸ/ê8éNg'öÊ ž»„cÆŒQPÕu½§³£CMsàÑÒUkðß%¼råJÀì-Í?Ê~Yi{¶o­­©u ò•í Ù øNXd2YCKëÇ™5g˜ÛˆûùyÞÆ¡´…àLUUlZ?<ÿ1»¹¹mÞ±[ö‡™œH$Î XÀápþ¼xþsÓ–¶¶¶««+•J‹‹^âêêºsçÎ÷€””GGÇaÆ9889rä«Qkk«··÷çneeeõÕ#éIëׯ2dHRR’ðBooï¶¶¶¯nùýˆµ°ð| ëìÙ³K—-?~æ‚™,êXzÉpÑ1‘‡+ßTp8œ«‰ÿú3qÜ„‰³}ýUÕÔ?¾¡ŠŠJjjjKK‹“““`ÉG @ppðÍ›7ûöí õ}õŒÇã}bSW¸d\\œ——×§lõÝâñxýõ×ýû÷…—‰DOOÏøøx___Æ&FÖÿºÜHO7::Ï kРAC\\I¤Þ>Æ'm]¿¦—+PVéû¦â5ðx<'H[œO*šÅb}ü½Ë.ÈdrJJÊèÑ£Éd²²²2”——/X°€Ífóx¼ÈÈH kkëÖÖÖLŸ>}È!yyyQQQëÖ­ûPɳgÏbû¿|ùò©S§ºì“Á`?~<..nñâÅnnn&&&4mß¾}ÀårýýýsrrI$R||<ƒÁ ™‘%•fil>®oûg”ôr;C6>yTÖË• c³[ªÞ¼üH$y<ž‰¹“ñvêÔ©zùY[[[WW·¨¨(!!a̘1Ø===X·n»»{÷P^^¾sçÎôôt2™|èÐ![[ÛñãÇïܹÓÔÔôÕ«Wt:}àÀúúúÙÙÙñññ‡Z¹r¥§§gxxø‡J ¢¢ÑhÝ÷¹lÙ2‡ÓÜÜëîî¾{÷n+++AÓLSS377WQQÑÉÉ)77WVV–ÉdzxxäååuY[\\ìææÇãñªªªº×%ü- ><66°Â§N222²³³ãóù¡ËW*8++«ÂÂBá%ÂG׃_õ7¤««kek¿bõ:Qò?ø^æÄ‰óç/¸tãVŸ>нVéêM[z­®÷Z8wvMUÇ“àr¹f–¿_i¶v³'z~d+•´´´¬¬¬={ö`ù¨{—°KÐÑщŒŒ€¢¢"??¿¼¼¼ÒÒÒE‹þD©££úõë‡ý‰:99-_¾¼³³333s÷îÝþþþ*ÙE÷}”••@uu5vEIБìÛ·¯††¶$111**Š@ 0Œîk ¡¡ASS”””Þ[—°úúzmmmAa//¯-[¶DDDÌš5ËÃãKáî‡ó¡DþÓÒ~º:çÎÃs¢P(>~þÒÒ?ÐØ2y¹wJKŠ±Ï¦–XªúôÍ7nÜøâÅ ¬mõŸ?~lll jjjXSÝÔÔtÿþýØZìI?áKWÇ qvv&‰/‰QSSc2™ÝK®X±"::zõêÕ—/_VSS+..¶´´´°„;Û¶mËËËc³Ù4 [Ò¥)¤¤¤TUUÅãñß¿0ee劊 À “H¤ÐÐÐööv;;»î «ûá/a0XÞD>ÅhÏñV&F€ï–™™ÙïÙR?Ò³”1QGÀÒŠêû™©JÀÏÏïèÑ£ØÁÿ,ZRR"##ÃápÂÂÂàÀÍÍÍD"ÑÅÅ%$$DxÛ™3gR©Ôœœœÿ,‰™0aÂÍ›7»”TWW·µµõ÷÷¯©©‰ŠŠ ’’\ÃæåååââbiiIþÀ—5kÖŒ9’J¥b¦GµvíÚQ£FYYY©¨¨Àµk×<ØÖÖ&¸ ñéètº¸ßOèMnPÍß×°bbbüüü®¥¤÷QTu,½!/÷Ή?ŽÎ›¿ð½©jöDÏñãÇ‹×~l6ÛÏÏ/!!áÛUÁår%$$^¿~=cÆŒìììoWQÞÞÞ111²²²½VãgùÞ®aúÎÑ×ÕILLÄs ËÉÉ)xÝF™ïõœøêTúö;}\ÔQ|Mrrrß4[@FFƦM› Æž={º¬jllœ0a‚àÇ—íç³ À·>.œñþyÍÔðÝ%8p µ=‰$)ê@z‰ž¡¨C?®®®iiiï]¥¨¨(|Ûáã>«0ò¹›˜Qp?Uý… ¼'Œkf5‰:AzdÓêà… ¾[X#FŒø}w¸¬œ¼¨A¤G/±57|·°deeûöë÷ã¼üŒ x¥¨¨„½Jç?æk×®-œçÓÒÌu ‚ôHض-«W¯|w Çq센Âòæ3‚àÕŠ5ëí-Mß-¬ööö¦¦F4k‚ˆ;vK ‹Å|·°nݺµfù’k)é’?ƃ£ÿ©¨¨èÀ¢ŽMMß×½õÈáøptòäÉÒÊýÈ}DÈ÷"#####CÔQ ÈgÛ¸}—#Å ðݪ­­-¾_ ®>ø#½Nø!ÇÏ%~_ÃB¾:¢„„¨CøŸçOž(J444ðœ°233C·næ6Í%’’?ÊÿþœŽ=–£«ãîîŽç—ŸÛÛÛ“ïä)ÉÝWCDŒ°Ù-ÎVæ x¾KøèÑ£?/žï> ‚ â%3õö7ß5Ü¿?&2¢½ÍM‚ âíjâEl| =Îm u DÌýºx¡H`¯â’¼¼¼¼JÿÁ&fßÓ”‚|.ee• žcõôôðÜÂRUUµ°¢Jð|A~úFF&&&€ï»„/^œ=i|3 =8Š âmËÚß/^ ø¾èþúõëøKÚ9:£YÚD¬•Þ·1lgg‡ç–´´tŸ>Šèågwròò €ï.á_ýè÷sK3KÔ Ò#{wü¾nÝ:Àw—ðíÛ·‰ß46Ew D¼½|ñÜÞÂÄØØÏ-,6›ýŽÁ@³æ ˆ¸kl¨¯¯¯|w SRRÖÿº¼•&¡@ñ}èÀ®]»ß]B‹õ×í õèº;‚ˆµwoß:Z™©©©áù/¹²²2ÿn.‡Ó)ê@鑲‡ŠŠŠß]Âììì°m[ÚZ[E‚ =rædldd$à»KØÙÙ™’›/++‡Fk@±ÖÖÖ6„j.++‹çViiéùøS¢A¹}óÆÕ«Wß]¢¢¢¸c´··‰:Az$éÚ• .¾»„€ÆtG¼Àÿ˜î999ûví@ÝDÜ‹‹ŽŽ|'¬W¯^e¥§r8Q‚ Hß/¸{÷. .!‚ bÿ]ÂÛ·oo^ók+›-ê@é‘c‘aaa€ïi¾X,VeEzùAÄ£¶¶¦ .!‚ bÿ]¿ÿþ{é¿–4Z‚ˆ·ý¡;6lØøNXRRÒèµw$II)))À÷¼„úúú¯ªk‹ï˜YR._8÷ôQ™±‰iÂÉØÚê*=Ãc‘­l¶ö C{ÃH$’²ŠJä}dEEIâØáˆjê--Í'£ÒÓ«©ªŠ=>ØÜüÉ£GçOÇQmíòïæ^M¼hcï–r+=å…ftíÊý¼{f–‰çÎ<úÄh°Iü‰˜·okõô þ8|¨­­MS[;bo˜”´t%Ũû•”BÌ‘Ãj²šX'ÿ8ªk`PõæM‰ã¦––ž?emïp/'ûúŸ‰Öv©·è™©·-©´ëW.ß/05·¸x6¡üÅsCãÁ§Ž«{ÇÐÕ78q ³³c ¦VÄÞ0i2¹Ïуû•TTø<~LäauMÍÆ††¸cÑz†F¯_9kF±zø øBüiÇœ¬Œ¤«W¬íìSè7²3Ò-­¨ý™ø ¸ÐÄÌâBÂéWå/ ÇÅD×3™:zú‘öq¹\5õ‡Ã÷ÈÊÉÉÉÉG: Ò¯‡Ã9uDCK«žYw*æcãWå/ÏœE³³¿—sçZâ%{‡Ô䛩)ªõßWÿ,*È7µ°¼t.áųgFƒMNÇÆ¼{ûVWß :â`GG»†¦VÄÞ0)irÅ£÷+*+@Läa5 ¦¦Æ¸?¢õ ßT¼N8kfI){P‚¹Ù™×¯þimgûæ¬ô´N¶Âû¦æÏÄÿs²ÅüÁ¬{§£§ôÐ~‡£>PãpøYYy…£‡(÷íËãqG¨©ÕPÏŒ;ö‡¾‘QEyù™“'Ì­¬J‹‹/$œ¶utº“™q㯫4[»dzRNfº…õÚåK¥ÅE&fæçãOU¼*702>yìhCC½Ž®^ä}<oâÔé>3¦¾[XPRxÿîl(¸w÷~~äfg––@fêíg@Êͤ×å/;:;’éIÕ••-Í-Éô¤wïÞ60™Éô$VSÓÛÚÚdzR[kë›×¯’éI<ïåógiÉ7àQéƒìô4¬¢{9w ÿ^nQA>ÜÉÌ(+)€ŒÛÉ/ž>áóùÉô¤×¯Ê;Ú;’éIÕÕUÍ,V2=‰YWWϬÃ*ª©®J¦'µ··UüE/ž=MOI€²ÒÙéP|¿ /7òrîß/€;ie¥ =ùÖ‹gOy<^2=©âõ«¶¶ÖdzRmM5‹Õ”LOª¯«c¾{—LOjifau´·W”—'Ó“àù“'©ÉððAINVæçåßÍ€{9wJ ï@VzÚ㇥–rëåóg\.7™žô¦â5VÑÛšš¦ÆÆdzR}=óƒ‘LOjii©®|“LOêììxõòEÊÍ$xúäQFj ”–çde@aA~Á½»XEŠ  3=õqÙCH½u³üÅs‡“LOªzó¦•ÝšLOb¼­mh¨O¦'564`±Ù-U•o’éI\çÕË—·oÒàÉ£²¬´T(-)º›…y÷ óîÀÝì¬Ò’"ÈJK}ò¨ nߤ¿zù’‹UTù†ÍnI¦'½c0’éI õŒ·µÉô¤VvkÕ›7Éô$‡Sþâyê­›ð¸ìafz*<(*Ä΂{w ò '럓-#5åé“GØÉöêå‹ÎN¶7--ÿTT_ÏL¦'556¾­©I¦'µµµ¾©xLOâr¹/Ÿ?KK¹–fu9Ùîææç@NVÆÃ%‘šüüÉH¦'U”—w´·'Ó“jª«ZšYÉô$æ»wõuuÉô$«©¶¦«è_'[ò-ìd»“‘öÏÉ–sòrs°“-;#ýŸ“-%YødkooÃ*b55%Ó“ê™u̺ºdzR3‹UýÏÉÖñúUy2=‰Ïç¿xú$ãv2”•”ÜÉÌ€¢‚üü{ÿ:Ù²ÓÓ•>€´ä›/Ÿ?üEãü¢;‚ x‚ó‚ x‚‚ b%,AÄJX‚ˆ ”°(a!"6PÂBDl „… ˆØ@ A±‚ b%,ä먬¬ôññ!C‡^)%%µtéRÁ*•ºÿ~ÁL&ÓÇLJD"-^¼8 ÀÕÕµ¨¨H°påÊ•ï-ðÕã®ñSÊ?{öLFF櫇ü>‚|%OŸ>•””ÔÐÐÈÎÎÆ–p8wwwyyyA™¢¢"SSS*•ÚeCiiiìó¹sçlmm»,|oo¿ –¯[ùZP ùšˆDâòåËwíÚ…ýxáÂ///áqqqgΜ)+++)yÿ`°&&&Ïž={ï*A’’{{{™ýû÷»¹¹@QQÑĉ—/_>cÆ ƒ«W¯–ˆ½~ýº±±qPP¡¡¡»»{mmmjjª±±ñ©S§ºï¿µµÛùž={ôôôvïÞ-XµtéÒ¹sçNŸ>ýÈ‘#Û·oçp8‹/ŽÇÖîܹóçŸ^ºté¸qã222>´“/^LŸ>}ùòåS¦L €L™2eÉ’%'N|òäÉ'|Í?0QgL?°FGSS“ŠŠJYYŸÏ÷õõ}úô© …ÕÙÙ9cÆ >Ÿ?}úô+VtÙû¼gÏž±cÇò?Ü <}ú”@ ܾ}›ÏçGGGóù|“{÷îñùüãÇÏš5 +¼páÂààุ¸¿ÿþ›ÏçÇÄÄ`455ýòË/ïû@ JKKSSSµ´´°µ•••¡­­­±±1,,¬{ +!!û™™I¥Rß»>ŸO£ÑÒÒÒ°oc̘1|>ßÜܼ´´”Ïçÿý÷ßîîî_òÕÿ0ð< "d2yáÂ…¡¡¡3fÌððð^uãÆ wwwðñññóóÛµk‰ôÏÈáp~ùå—¶¶6 ‰˜˜˜î»íR€Åb‰Dìz™¿¿MMÍ“'Oh4ØÚÚ®^½Ûj×®] ¥¥¥åðáÃ0}úôÕ«W3ŒK—.Íœ9ó#GA$MMMŸ>}Z__-0`…B6lX```PPÐëׯ»l¢ªªêííM&“›››±Fb÷ÔÖÖ:;;‰Dº~ýzMMÍÇ= mmmD"êô| JXÈ×·dÉ##£æææ„„„—/_ –'$$H¤»wïr¹Üæææ¤¤$OOOl‰DŠŒŒüÈ>»`±X$IBBû‘ÿaݬ­­SSSÛÛÛ¥¥¥åää¦OŸ[\\¼`Á‚WÂÿŒ#‘HyyyW®\Ù¾}ûùóçÃÃÅ˳X¬qãÆ={öìÊ•+ïÝ öÐmÜî°°0¬pssóG¢BP:G¾¾,Y²ÄÓÓSP ¡¡AVV6666222::záÂ…'NœøZ5ª««@^^Þˆ#°åGŽY¾|ùСC7mÚ„-Y°`ÁŽ;lmm?·Š7oÞlÛ¶mâĉÑÑÑ÷îÝ“””Äf;wî´µµµ··÷íÛ„stjjj %;;:::¦L™¢¦¦fbb’‘‘UUUO£º†…|uuu³gÏ–øí·ß ›ššfÏž-))¹xñâqãÆyxxÔ××óùüööv///iié°°0Á†Õb€(IDAT £ËÞV¬XñÞ‚%MMMØ’ÂÂB//¯eË–M›6­¶¶–ÏçïÝ»×ØØøþýûaaa6lÀJ:;;ca¼7þ+V`Μ9³iÓ&IIÉÐÐP>ŸÿîÝ;77·ÀÀÀI“&ÅÆÆr¹Ü¡C‡ÎŸ?ǎضoßîàà4wî\IIIè¾>ŸÿôéÓiÓ¦-_¾|Μ9Ø5¸’’’±cÇ.]ºtΜ9oÞ¼ùê¿·£Ooìââ"bw”‡ë;õèÑ#%%%uuõøøxb ›Í:t¨„„D¿~ýJKK“’’,!!annž––4mÔ¨Qªªª»ví¢Ñh£GVUUUVV~üøqÛ— ÷E¼PEEESSóèÑ£½zõÒÔÔÌËË€]»vÉÊÊJHHŒ7®²²’hÜjͪªª»wï~ïS‘âââLMMÅÅÅMLLâââŽ=*--ýêÕ«E‹ 0 ¦¦fÆ JJJ§¸¸˜N§_ºtI0v[¿~½´´´¬¬¬““‘¹Õæ wdkk;|øp ¥Ñhaaaíï«O|G:D¼ ¼«‰‚m»ûŽðÑwI__àÀ)))¦¦¦Ä¯™™™––V\\ܳgϪ««ÍÌÌ,--ÓÒÒ¬­­‡ Æçó@SS3))©°°/×××oûrá¾ÀÜÜ<""BøÁž={ø|~hhè‹/ÂÃà †››Ѹ՚`ýúõzJÉØØØÔÔ”xÖØØ˜ÇãY[[ëèèÐéôÐÐP>ŸŸžžwïÞ=uê”””Tuuu~~~ee%ŸÏ—––>wî\JJJHH‘¹Õæ wtãÆ –——·råJ ×þ¾ì‡îÿ¯Õ;²lÙ2ÈÏÏÏÏÏoµ«›O}:888ØÛÛóx<___(((•••““Ó××üøñƒœ÷ìÙ­6íÚµ‚Žºuë6kÖ¬¿þú«¢¢bÁ‚m·ÝW‚=,üccc£ðœœ¬¤¤$ür99¹œœœ   AË÷v÷ÀcXß©'NþøãòòòÄ’ .((( 2dÖ¬Y/^¤Óé¶¶¶ÅÅÅm× //?yòäâââãÇ·}ù'ÆXºté7nݺ%--ý¡5·Ó©°³gÏr¹\333.—ëéé¹}ûöüü|''§eË–½yóf̘!%%%++;iÒ$::vìØ1CCÃM›6 Žaµ¿ùL&³¢¢bذaZZZm,òÿZ=;cÆ UUUSSÓqãÆ /_³fM@@ÀÙ³gK>±;j"{ˆ‡º$øwzÒ‘k½Óúúzssó+Vˆ²D"a¡¯ORȳgÏÈŽó?ÒÒÒµµµ7n$;úB4>~Ó!ÔEà !Ôe`ÁBuX°¾wx.áë´Á:LÇïüúl\.WðuªŸŸßê[]mup$§kÇge&e?ª#÷GXß)<—Pø\B6räHUUU555ÁW1[`ØN0a­^ÕÎnd0ßâœÄíí¶›ßö…­vBÇïöÛà÷°¾Wx.¡ð¹„`ffFüÁÁømN0l'˜°V¯jg7;vì[œ“ø¡½ÝvóÛ¾°ÕNèø=Ð~{>žKøÝÂs Û&äñx‚`ü6'¶LX«Wµ³¿Ñ9‰íìímþ‡vBÇïî<†õÂs Aè\B"ñრFÛ Û &ÐêUíìÆotNb;{»Õæ·Õj'tüøèNÀcXß)<—>pF í †íôþ¡Wuü9‰íhµùÕñ{à£íqJˆ¾|ç~»Mî0"žJÙöްÐ×÷]KØi7¶­V›ÿµ’wäÀs B]ްB],„P— !Ôe`ÁBuX°B],„P— !Ôe`ÁBuX°B],„P— !Ôe`ÁBuX°B],„P— !Ôe`ÁBuX°B],„P— !ÔeP¼`íÛ·ïàÁƒ°eË–Ó§OÀªU«®]»Æçó™Lf```UU“ÉŒˆˆÈÏÏg2™l6;%%…ÉdæååEFF2™ÌÊÊÊ   &“Éãñ®_¿¾råJ8sæÌæÍ›àСC{÷î€;v¸¹¹ÀÚµk½¼¼`É’%þþþõõõL&óéÓ§%%%L&3>>>##ƒÉdfeeÅÄÄ0™ÌÒÒÒÇ3™Ì¦¦¦[·n988ÀÅ‹ׯ_Ç'îQþçŸ=z6lØpîÜ9X¾|¹¯¯/‡Ãa2™>,++c2™QQQ¯_¿f2™iiiIIIL&³°°0,,ŒÉdÖÖÖ,Z´¼½½ûí78uêÔÖ­[ÀÕÕÕÕÕþøãpttôññ€… Þ»w¯¦¦†Éd†……0™Ìäää/^0™Ìœœ‹Åd2ËË˃ƒƒ™L&‡Ã¹qãÆŠ+àìÙ³Ä-Ž9BÜØÎÅÅåĉ°nÝ:ânéööö·oßnlld2™!!!oß¾e2™±±±™™™L&3333..ŽÉd¾yóæÉ“'L&³¡¡áÎ;vvvàååµnÝ:8yòäÎ;௿þ:|ø0lÚ´ÉÓÓV®\yãÆ .—Ëd2d2™---~~~Ë–-€óçÏÿþûïpìØ1âÎc»ví"n¥åìì|áÂXºtéÍ›7›››™Læ£GÞ½{Çd2cbb^½zÅd2ÓÓÓ˜Lfqqqhh(“ɬ««»{÷î’%KàòåËÄM·þþûïíÛ·w¹? Á_4•o¤zâÄ —]“~žjÏgE¾-ÓÌŽdEÓ¥º÷ÑÒdE©iëq»ÉD²¢ Yª–VD²¢"â’h4Z$+*,.©0?/’—›ÉŠ ‹g‡GÇEFE‡Å³#¢ã²³2ÃâÙѱÍMMañìVtoee“aìVTÔ Í"£¢{ª¨uSìÉŠÒ1ø®®9’e—Ô]F&’—TQQNt”’”øÏúcâ‰1qÉ DG•eañ숨˜î22ƒâÙQÑå5õÚfÏ£¤äUD²¢4ô ëÉŠ2µ´ê¥¤D¬¿¹©)’Ÿœ•IlHDlBÄsVX<;"&žEôSXP@< „ų#£bòJÞX `EñÅ%ûéE²¢újhѺËG²¢ Ì- Ë«#YQ᱉ qq¢£’âb¢£XAþØ„ˆöXlæË—DþúúzâbfñìȨèºf®†ÑÀHV”‚²J÷Þ*‘¬(m#ÓŠ&n$+Ê|x¢œ¼<±þêª*bG¥¥¦D²¢ÂãÙÿv—C¼¥oßë—””²ˆgG°¢KÊ+uÍ-#XQ2r½5t"YQýu šÄ$#YQÆCûª”ëçr¹‘¬¨°Ø¤¼œ×‘¬¨°øäÈßñˆ˜¸HVtX<;<*6/ç5±~G<èÓWÅÈ’ÉŠn¡1ÔôM"ž³”Ô4ÄåzF²¢ôÌ•T×G²¢†Ä&JJJ½+-%vTb\Â?ïHL|Ä¿¥¥°‰7¢¦ºšX¿œ¼üÀxvdTLUC“¦É V”lÞr}Õ"YQš&5\z$+jà°Š=zF²¢Âbê#YQáqÉ/Ó¿QÄ;ó))"ÖÏïžW®mß°>(ð¾……•ïšâyÑkÅšudA}¹’¢"¿kÞûv»¨««S¹`@X<›ì¡¯`¤¹1PûÖþýûÇZš“!$’”äÄуM###@Œ8TIIâââ iY#S3²ƒ „¾FWìÑóçÉ?þðÃTžÖ××?~+¯ @v„Зãp8µ55“F §ò”ðøñã¿LKv „H^¾H™:~tLL Pûk ?ýôSm ì!‘¨ôSÛâò§––Pû »²²²Ž¾Ù)B"‘’–ÖÕ7‘‘j¬³gÏ.™ý+Ù)B"ÉÊx¹pÖôÄÄD ö”pÖ¬Y y²S „DÒ_}ÀëëëµGXbbbd§@‰„N§‹‹KÐét vÁòññY·r)Ù)B"yå´Ü>55¨ü=¬’’’{!ÏtôôÉ‚úr y¹9³mêÞ½;•GXåååyyd§@‰¤©©)?/·¡¡¨=%ô÷÷ß½uÙ)B"ÉÏËqÙ¼!##¨=%¬©©yݳwo²ƒ „¾\KKKeEù”±£$$$¨<ÂJOO}ò˜ì!‘TWU†>~TVVÔž>zôèä!W²S „DR\Txüàþׯ_µ§„\.÷Y\2ƒAå/Ç"Dy|>ŸËåZ[˜Ñh4*°ÂÃÃ/œ>Ev „HÞ¾)9çñw~~>P{J˜pÇï:Ù)B")/+»ã{½¤¤¨=%¼¦;BTAýkºøÓ…ì!‘æçíßµ#++ ¨]° ØI d§@‰¤¾¾ž˜PSS8%Du ÔŸúúúnY·†ì!‘ä¾ÎÞ´Ö1-- ¨]°šššêêjÉN Ç««­år¹€SB„P—@L ©ü-ðK—.¹:ì~Þ‹ì äóüûäKv"Ù)P—1ÉvúøI“ÉNñW™®»w^õ¾bbbBå‚õÃ?()+“¢S(,ÈÏÈÈ?~<ÙAPàëëka5Šìÿ#.!¡¤Ü§[·n@íÖ´iÓz¨i’¢³0`À7ÈN:;>ŸO\=½óP믾Ëõ®®.Pû »»»ûÛŸÈNIzÚ‹Y?OŠ‹‹j,MMÍ¡V#ÈN‰ì? 1JAA¨=%´±±‘êÙ‡ì!‘ôUé·vã–µGX‡š4rÙ)B"yÁN¶±Âb±€ÚkèСs-&;BH$={÷ž·ÈNEE¨=%´°°¨å‹‘!$’ž½zÏœ7¿oß¾@íÖáDzþ^ºóx<²# ôM¼HIž4rXTTP»`Mœ8qݦ?ÈNÑAŠ þܶ9÷uö7í…F£IKK÷/¡ÑhÎÎÎàïﯡ¡Á`0úôésäÈâ)F§Óõõõ‰C‚Ƭ¾¾^UUõܹsÜoGn/ŸÏ744Ü»woÇt×ñúªôsþc;õº«««›±$;E駦ÆçÃÂYÓ]¶lü¦e«¡¡ÁÍÍMxɲeËtuuÓÓÓ¯]»¦­­-XøòåK:¾téR{$Îzý²öžžžsæÌ1ÃçÊÏÏß¶mÛ¿ü³6™ÇãÙÙÙíß¿¿®®î‹{ìÌdde ±”——j,ùÓ§’¢ã,´_ .œ5ÝeˆoT¶´µµOž<ÙØØ(XR[[›––v÷î]yyù)S¦ eddtttÆŽK\ä½Ö¯_/---++ëääIIIƒ–077OKK£Ñh£FRUUݵk—­­íðáà 44”F£………µj Âí]x{{1BJJJÐ@EEESSóèÑ£½zõÒÔÔÌËËÛ°aƒ’’‡Ã)..¦Óé—.]j•“F£9RUUUMM-''§mr6zôhUUUeeåÇ€ªªêîÝ»?k{…7Á`´ÚÞö÷MUUUPPЗ¼£^ÆË´9¶?ÅÇǵ ÖôéÓw¹";EÇQS×k3‰F£ñx¼'ƒ¿QÙš2eм¼ü… Kœóóó×®]kjj*<âp8 jjjZÕ©S§ÜÜÜX,–­­-,Z´ˆÁ`$''ËÉÉÙÙÙ@QQѽ{÷–-[¶`Á‹•ŸŸýúu #F´m,Ü^ЛÍÖÒÒüXWWwãÆììl//¯;wîdgg_¾|ÙÞÞþíÛ·AAAþþþ’’’¿üòKÛ¨µµµ>>>ùùùÞÞÞm“@MMMPP²²²££ão¯`Ž;Öj{Ûß?Ä6&''¨ë.MM]cÏÁ£zzz@íO »wﮨأ#{,ÈË»~¥õÿçõïÅ‚ˆcðO=|ò0xÌ›¯8Y ÓéëÖ­;|ø°`ÉŽ;‚‚‚~ÿý÷S§Nº½‚MÐÕÕݱc‡ðö@;ûGxÀK= C¡‡¢¸¸8P»`yyymݺõItÇ]ÖýÝ»··}¯÷ìÝ[B\¢Ã:Æçÿßg…|ÏçÇEG))÷é.%ùµzY¸páöíÛ?®Y³†Éd6LQQ±©©‰XÈd2·lÙÒ·o_IÉö«¯¯ÿøñã8;;ïÙ³ÇÐÐPLLl÷îÝÍÍÍ999k×®%~G [·n³fÍú믿***,X­Í팉›ÄÄÄZ= þòìííy<ž¯¯ï{£Š‰‰Uƒhß*9„‡‡§¦¦†…… Žâ}îö oBÛím»ÉÂû‡ØÆö‹uו•¹r1ÓT'bøðáT.XóçÏ—SVéø~ÿ:tLÏÀ°ãû€³§Ü.yžÆçóØ-ýù—é{wn¯(}óµz‘’’Z½zõŽ;ˆÓÓÓmll*++544ÜÝ݉…òòòÄÇ:í &>Ä1‹/ÚÛÛÛÚÚÊËË/Y²¤Uc&“yúôéaÆÓŸö Ì;wË–- Äa¬™1c†££#NŸ4iÒǶþ=ɉí88X^^þÃw9´´ÝÎ]266j_q4##Ãï^ЈÑc:¬ÇÄøØß–œöò!¥`ÕTWÿú“MC}=(öèA”* ‰nà²ecEéâ|÷ïJCCƒ®®îÎ;Û)jD³#FXZZþý÷ß_Ð F[¿~=1îx|>ßÈÈhþüù›7oþ*k£Óé«Ö:ÿg>Sôµ}ÕÕUIñqË-PTT¤òëæÍ›Û:vJH®ëÞ^ õõŠ=z.°s”ªïœ””T^^ÞG›IKKëèèlܸ„ç°ÁÁÁ£F}ù¥ì¾âªÚA£ÑRSS¿Åš;‰¼œ×¬w²jAñ)á²eËÔõÉNÑAjª«C?\³a3–ª/ <Ïø‚Øš¦PûXx‡ÑÑÓ÷¹`nnÔ>èž››£¢úÁÕ©¤®¶öµ›íZ‘‰®®¶6.&zÌÐÁ’’’Tþý :¼÷O²Stå¾}±Z!J*,È?¸g׫W¯€Ú#¬uëÖ™YY“!$#“ÀgÏ---€Úßt‰‰¹yÍ›ì!‘”½+õõ¹\\\ Ô.XÏŸ?¿|þ,Ù)B")}óæò9Ï‚‚ ö”ÐÙÙÙrìD²S „Db`lò02f¨¹1P{„õðáÃcö‘!$’¢Â‚£û÷fggµ VVVÖó°gd§@‰¤¦º:"ì)qÚ9•§„+V¬0²ü^.‘üQïÞ½óôô$;êì:á¹zºú7 27j¬Û·oŸt÷رוì B^^žƒƒÙ)úly¹9žŸzÏËÎ&44ô£™]]];øÎÏ¡¯.•´r13"âß;?ÛÙÙµ?Té„ôôô>Úfܸq%åU¦óklh¨¬¨ ;êJzôê%..Nv å>*Žë7¨««µ?%ÔÓÓ=nÙ):…gOBþÜön Œ¾ç¯újjë@N^~Ìx›ž={µ –››N …>}Z^^žì¨³KJJÚ³gÙ)þ'=-õÿ¦„T5uêÔF#;E'2eÊ”>}úuv?üðÙþªšúŽ¿öëè赿ÖУGµþêd§@‰¤[·njêRRR@í‚uþüù¥ æ!$’¬Ìt»¹³’’’€ÚǰæÌ™#¥Ð‹ì!‘h Ð:â~ÆÐШ=Ââr¹‡ì!‘ðù|‡C܃Êëúõë׬";BH$9¯_ýî¸âÅ‹ð F#¾}*xð)‚ƒƒwîÜùµ2´bggwÎçÆ7Z9B¨chéè]¸ægffßb„•ŸŸ¿mÛ¶OlìââòÕ3Þ¼y“™þò­¼³áñx5ÕÕd§@èëklhÈLYWW¢,6›=tèP ‰~ýú•–– –«ªªîÞ½’’’,!!annž––4mäÈ‘ªªªjjj999pèÐ!b¹h[ô~{w~jéìêètú?]þܶ%?/—ì,}Mù¹{¶ÿ‘™™ ¢,&“YVVÆb±|||$ßw ©E‹1Œääd999;»î^S[[ëã㓟Ÿïíí Ë–-€üüü/ŽÑŽß~ûífÐão±æÎ‰i¿ôaà½3l¿ l©©©Y[[[[[7úôé³iÓ&â©M›6_7 6lبQ£†êîîþ¡fjjjcÆŒ5jÔêÕ«‰{É Ö?xðà+W®|¥Íýˆ†††9s>ûK-ļ£ n›|Μ9žèëÓ30ºóð©……ˆòµ†”””¥K—š›ðÆ)))4mðàÁÍÍÍ‚û_[[[[YY@EEÈÈÈ@¿~ý¾8F;Ølvðý€ÿÌg~‹•wBZ:ºV£­ÃŸ>yxïQÐýñ“&/tX¦ªÖÿS^«¨¨øôéSÁJJJÄõÒ ::š¸‘³³óÇ{ôèÿ¾}ïm¦¨¨øäÉ8xðàž={víÚ%XCCÃðáÃçÍ›÷YÛÅãñèôOúÏ*ÜÒËËkÚ´iŸÕÅL™2ÅÛÛ{É’%dUeyùàûƒôµTTT¾|„eddœ^SSÓ¶¡¡¡±±ñõëׯ_¿~àÀb¡˜˜1$J˜„„$''qŒvÔ,$$ÄÐÐpþüù\.W|Á‚†††Ä °±±¹uëÖ'¾ÝYII‘û±Ã¹¹¹ ÊëÂ… C† éÕ«ñ%ÔV.^¼hoookk+//ÿ¡2?cƌ˗/›šš †`Ÿ¨±±ñÒ¥K×®]k¿™D·nG¶þCúvZš›ÀÑ~1‰wúfˆ‰q¹\>ŸÏãr ø~À£ û½Gyy¹µµ5¨¨¨³¶Ù³gŸ?žÏçÛÙÙÝ¿.^¼¸oß¾;vÈÊÊž>>sçÎm§¥ ÷’’EEÅE‹H™­å IDATµjéïï¿zõêÚÚÚ3fL˜0ÁÍÍÍÌÌŒÇ㯪¨¨pqq‘““>|xTT”ƒƒCyy¹ÍŒ3Ú6èÑ£Gpp0Ç#ŠuÛTÂ{£í³Äª”””^¾|©  0räHIIIá}"è±U3999âŸàÿDyyùÞ½{y<Þâŋnj½zõ*,,üœßNÊÈÄìY\òpsc¥`™šš ¦ðïˆIø©©iLLŒðKÚ¶4hP^^ÞôÎãñ8Nçü^h«Qä\KžÇãùûùÖ××ð@LLŒËåš ll:ØÞU+ZM ÀÔÔ”¸×®‰‰ ±D]]ýÔ©S””dggûÞfMMM £Õú_½z5gÎbÌ2mÚ´]»v¹¹¹Í›7ÏÆÆ&55uåÊ•DûææfèÙ³'Qƒ†¾víÚ–––ðððØÛÛ¨e+m×éè訥¥E| T\\üχåÿN${ôè¡¢¢B,¹uë–‡‡FþLI¸Aee%q4ƒ¸FÛ¾ÚO"XÕ€ˆ\.·Õ>ùP³ŠŠ â œ‚ËoÈÉÉaÊËËÛî‡.­¤¨èæuÕ];ÕÕÕ»ê©9ÒÒÒK–,ñôôl§Í‰'víÞÝÁÇÝl3ÈbÈ2G§ŽìTà¾ÿíººZ Óé<ÏÔ|ÝòUÆfƒïßû‚µ-Z´HøÇôôt]]]PVV·j&ð÷ßÿøã­*((÷ƒÁpuumjj2dˆÁ±cLj ɶ´´€P€±cǺ¸¸XYYÑéôö[”••ËËËÛ¶\·nÝ™3g6mÚtûömeeåäädÁÁ/á¬÷ìÙ[__/| V¸¼¼|QQÇ«ªª€¶} kû¬`UÂëlµO>ÔLAAø¨ŠèšxPXXÈãñ³õÒÒR¢Àuu••î¬s\Õ… Ö§ptt4³²&;EÇáp8ç=܉Çfƒ¥ê_+˜@@@ñ`þüùÂm\]]Ùl¶¤¤$‡Ã9xð `y«fåååcÆŒár¹ÆÆÆ‡^?ŸÏohhØ»w¯ £'N466Ç•Ž?¾jÕªÚÚZ:>zôèV_Л;wîÀY,ÖG[lmm>|تeŸ>},,,ìííKJJ<<<Ž9âàà@|óæèÑ£­Ö0mÚ´Ñ£G›˜˜wÄkkóæÍãÇ8p 1Ìi?Õ§dn»O>dË–-'N433STT$–(**nذ!!!áĉÄ’àà`j|ì g`xçá sc Àºâ%’GŒÑþ+ àïÓž›wîî°Tðëd›‘ÖcÖl áòž÷ýoïsÙ>hˆå’e+[•ªàû÷þܶ¹¨¨èû¹V}}½Ï·ë‚Ë劉‰åååÍž=;22òÛuôeæÌ™sîÜ9âª,ŸåÁƒ“&Mꪢ6iiéoZ­ ,,lÇŽ¥¥¥Ä÷Ÿ[©ªª²µµüèââ2zt‡ÙüÖ›ßaÿ÷Mw*,;;;CÈNÑAÄÄÄ~ÿc;Ù)¾/ÖÖÖ¡¡¡zVNN®ÕçèËhéè^¸ægff ”¿ZÆ߾—«5|£Ó›"]Nv¶óêå_ùj Çãr;ã÷BŸŽ|â«…@í)áìÙ³Ut ÉN‰ÆÍï⊣çÏŸwÀkº#ÔÅeeüïšîT.X=zô诮Nv „HºIJö×@|?ƒÊS©S§*ôÓ ;BH$ªjý·ïÙGýûº¹¹Íüi"Ù)B"I‘:}Ò8âÜU*°ôôôF›@vŠNdöìÙÄejGYYÙþÏòòc&L$.ÄFå‚5nÜ8 …Þd§èzöêe1tXCsKCsë“rj…ÑMÒbè0i¡+—‘«O_Çõ444€ÚËÕÕuë¶mŸÇ’„|æCÌ-¾—/ý#ŠIMNZm¿(,,lذa ¸ÿ~g~Ô»wï>ÚfäÈ‘vËWv@„з£¤ÜÇ~¥#qý/†¢¢bRRÒ{/ÚÉ׃o‡™™Yy·c „¾…=~ž>ƒ¸c£Ë­>ݱcǶnÝú$º½+m"„:¹´TöÊÅ̈ˆˆáÇSùÖäÉ“«ñ3B]›J?µM;viiiµ¿‡¥¢¢bô±›/ „:9éîÝ ÿ¹î+• Ö™3gΚNv „H2ÓÓü:-!!¨ýµ†™3gŠuÿì!‘ôW°ÿØI}}} öK\\\JJšì!‘ÐÅĤ¤¥ÅÄÄ€ÚËÛÛÛi¹=Ù)B"yý*ó7‡%Äí/©<%\¸paÏ~êd§@‰DSKç´—q§^*°ªªªŠ‹¨p«n„¾gÍÍÍÅ…@í‚uûöm—-ÉNI~^ÎŽM¿gddµ§„+W®Ô21ÿx»ï@}}ÝA—md§@]‰Ãšõ}úvŠ;ÝëêÜx0hÐ  vÁÊÌÌŒ|úˬÙd!‡Ãyôè‘¡¡a¿~ýÈ΂:»wïÞÅÅÅͳ_NvTWWE„=µ27îÓ§• ÖÇÜK`íÚµvvvd§@q«z²SüOqQáÑý{gNBñ‚åììla=žì!‘™ŸO£ÑÈNÐW¦£§ï}+ÀœòS›7oný}-Ù):ÎU¯‹÷îÜâp8dAèkÊËyýÇz§—/_µ V}}}Ue%Ù):艓ïýsî´)X¶•p8œÊŠò–– vÁš?þ‰3çÉNÑqz+)ÿdûKIqÑþ];fÛNþ¬²¥¦¦fmm=pà@///á%ÖÖÖûöí{o 6lبQ£†êîîþÕ·¨¡¡aΜ9Ÿû*33³¯žD”.¶nÝ:bĈ   á…sæÌ!.?€>j€–¶Û¹KÆÆTŸzyy­²[HvŠ5‰=ƒÁ€woß~VÙRTT|úôixxøÁƒ…—<}útÓ¦MïmÎÎÎÏž=c±X³g·w ÇûÄMnéåå5mÚ´O|açÄãñîÝ».8Ù…ØÀ)S¦x{{“­ËÈÎÊ\±x›ÍjtïÞ½{=;¾_vR¢û±#ß/ACS++#ø« ÊÖùÓî³,ú”×ÖÔÔHJJ~zYYÙI“&ÉÊÊ*((@NNβeËêëëy<Þ©S§Œ tñâ۰°#FÄÆÆzxxœ9sæC-®]»F¬ÿöíÛ—/_nÕ²´´ôüùó^^^«W¯3fŒ¾¾¾ƒƒƒ˜˜˜¹¹ùÑ£G€ËåÚÛÛ³X¬U«V1 ooïÒÒR—3f€±±±¥¥%ñìŠ+‚ƒƒœœ ”˜˜Èf³Û¦ÞüGGÇr¹\bc—,YÂãñÆ¿uëÖVûJ°áÝ»w·¶¶>þüÔ©Shcc³dÉ’%K–|Êûòc0Š=zˆ‹‹Ïç“ç ‹gwpKæÌ|Wú¶ƒ;ÖÔÔÔP_/ø‘F£ñùüZÚÙY™žžž:ùYMMMCC#))ÉÇÇçÇ$– 0þøã &´m999ûöí{ö왬¬ìÉ“'-,,¦Nºoß>ƒÜÜ\‡ààà¾}û†……½yóÆÛÛûäÉ“ëׯŸ2eʘ1c>ÔRSSSÊÜÜ<>>¾mK'''‡S[[{áÂ… &8pÀÌÌŒÇãÑétèׯ_TT”œœÜðá㢢¤¤¤ÊËËmllbcc[=›œœ}šødð£ \]]Ùl¶¤¤$‡Ã!Æ?~|ÕªUµµµt:}ôèÑ...‚Î;wàÀ,‹ø±–¶¶¶>lÕ²OŸ>ööö%%%GŽqppÃ6mÚ´Ñ£G›˜üsßà¶6oÞ<~üøí§Ú²eËĉÍÌÌ àĉ ,ø„]û‚ƒƒ»úç ¦¯J¿õ[¶ÿE¨| ëðáÃ;vî¼ÿ4‚ì äî-¿ »w/[ѶTUWWM3²cXS}}½Ï·ë‚Ë劉‰åååÍž=;22òÛuÔÊœ9sÎ;'%%Õa=~ºÎv ëE {í ‡'!!–––Ta 2dÖÜÏþ××uõUéçvîÙ)¾&iiéoZ­ ,,lÇŽ¥¥¥‡jõTUU•­­­àG—Ñ£G¿w%ŸÞRà[o•ôìÕkÖ¼}ûöjO ---èÝÈNÑq ±$;B×cmmúÞ§äää„?vhǧ·D_ g¯ÞóÙýóQ Ùa¾¡C‡ý8êKŽã „:)É6VCˆ£ŸTaÙØØ”Vב!$’¾*ýÖmúƒ8èNå–¦¦æÐá#ÈN‰¬ìC­F§RP¹`¹»»Ï™öÙ)B"IùbÖÏ“âââ€ÚSÂ_~ù…ÃøŽº#DIjýÕw¹"¾¢Lå–¬¬lo%e²S „DÂï­¤,!!Ôa]ºtiëÖ­O¢ÈÒYÄÄÄÈÈÈuvIIIdGø?ÙY™+3µ"†Nå‚5oÞ<Ù^}ÈNщxxxxxx¡Ï£¡©}Òó‚‘‘P{„ÕÔÔT[[KvŠNAFFÖ÷~ðÇÛ!ô/E2®%÷^\.§¶¦†¸%• –¯¯/N t:ç¡.*/çõ¦µŽ#‡˜>œÊ'?———=‹TUëOv„ЗkjjzSR<}Òx)))*J˜ŸŸÏNÄáB][}]mrB|uu5Pûk þ|ÏU–B]HaA¾ëîÄ­ê©<%lll|/ó+·!„º.—[_Wg3Â’Á`Py„•pÇÌ+¬#„DW^öîŽïõ’’ ö”0<<üÂé¯wO„PGz[Rrþ´;q5}*O ŒÛ|!„¾â6_Ta=zôèÄ!W²S „DR\TxìÀ¾×¯_µ Vzzú³'ÉNIueå³Çeee€SB„P—@ý)¡¿¿ÿ®?6‘!$’ü¼\—Í222€Ú«¼¼¼ /—ì!‘456äç544N B]õ§„>>>ëV,%;BH$¯³_9-·OMMj,ƒ!ÑM‚ì!‘Ði4qq :8%Du ÔŸž={vñì_ÉNIVFú™¿$&&µ –²²²®¾Ù)B"‘’’Ò50$SB„P@ý)áñãǧٌ%;BH$/_¤N?:&&¨]°LLL~üy*Ù)B"QPPüñçi½{÷jO ù|þ³¸dâÓP„P×ÅãñF6j°öïß?nè ²S „D’’œhma b;wî$;Ï·"!!!!+ghlJv„З£ÓÅzöêýóäeee©<%¬««{Ýyn`‹ú§ºªr²õqqq*O Oœ81ãÇ d§@‰äå‹”i6c‰O ©|«úŸþ¹žKv„hú©öߺ{¯¶¶6Pû {¯^½hi“!$IIIMmmiii vÁ:wîœý¼ÿ!$’¬ÌôųMJJjO ÿóŸÿt“S$;BH$ꚇÜ< €Ú#,4Ù)B¢üS¹`]½zõ÷Õ+ÈNIÎëWëV.{ñâPûÔœ·oßÞ y¦¥£Kv„Зklh(ÈÏ›õóÝ»w§ò«´´4'ûÙ)B"ill|ý*«¾¾¨=%¼{÷îží!$’‚üÜÝ[7gffµ§„µµµ"£{ôìEv„Зkii!NÍ‘ ò+---$øÙ)B"©ª¬|ü ðÝ»w@í)áãÇÿ>zˆì!‘”ž<|0''¨=%Ä ø!D|>ŸÏçdB£Ñ¨üÇêù÷ ²S „Dò¶¤äôÉãyyy@í)arrò½;·ÉNIyyÙ½;7ß¼yÔžÞæ !ª þm¾îß¿¿×²S „DR˜Ÿ·w綬¬, vÁ***JKM!;BH$õõõi©ìššÀ)!B¨K þ”ðÆ›Ö:’!$’Ü×Ù~[•––Ô.X§©±‘ì!‘ðøü¦¦FÔ¾/¡±±qvAÑ«Ì m]=_Ÿ+oß¾Q éuîLcC£J?Õ3nÇ%$ºÉþðÃy÷ääi4ð:wFI¹oMuÕU¯ ê4‹ |}®è¿LM½ã{ÝÜÂ2†õüqp ©ù ÐG1Ï# M‚ü_¾HÕÑÓ¿uýjQaÁM-ï‹çjª«Uû«Ÿuw£Ñh=zö<ëîÖ]FV\\â’§GÏ^½¼/žSí¯þöí›W¼´õô_efÞº~Õdà Ä¸Ø ÿƒ-ÂCŸD†=325{x”¨g`x÷¦oîëlMmëW.•—•õ×иxƃÃiQêÓ×óï’’RÝ»Ë\8í.¯ Èãr/Ÿ÷ì£Ò¯¢¢üÚå‹´tòr^ß¼æmhb–’œèÓwÐKVDØÓÇLš?yø >6ÆÀÈø¾ÿíÌô—Úºz~W½ß–«м|γ¾¾®ŸZÿÓnÇ †¼¼Â9¿e£Óé^gÏôVîS[SsõÒ…þꊋ }}.ëe¼|qûƵƒ‡ÄF±Ý73ü,äqÔóCcÓ÷°uõ nû^/ÈË ¥íséBuU¥Zõ³§Ü€={õ:ë~Rº»L7ÉnÏx(öìÕÜÔä}á\?ÕþïJK¯_¹¤­«—ý*ëÖu3ó¤ø¸ûþ·Í-†D> }bl:ðñƒÀä„x=C£»·ür²_iéè^÷ö*+}×_cÀ¥³§›ššú¨¨œq;.ÑMRFVöÂiw9yù¼§r_•ªÊÊk^54µ òóü®^102IKaßñ»>hÈШÈð§ƒMš?}e`dx÷NÆË4=ý›×}Š ‹44µ®\8WW[£ªÖÿŒÛ 1†˜¼‚â¹Sn22² †ø¥³§{õVª¯¯÷¹x^M]ãMqñ ï˺ú†™é/o߸f6È">6:ø^€Ù ÁaOCXáaF&¦Á÷沈“uõ îøÝÈÏÍÑÔÖ¹êu±¢¢¼¿ºÆ…Ó§8\No%eÏ¿OHIIKJI]JŒ‹Ñ74¾wçVWùÓ=vüO¶¿ 65j° "ô)+"B‚ÄÇD@àÝ;©ì$ð÷óÍÊHojlò÷ó-ÈË­ªªò÷ó-}û¦ôí[?ßꪪ‚¼\?ß¦ÆÆW™þ~¾|>?-…x×bbB>VDXDèS yËzÁ÷ï%'&ÀÝ[~/ÓZZ8þ~¾¹¯³kkküý|KŠ‹ÊËÞùûùV”•øûù6ÔÕçd¿ò÷óår¹éi©÷n߀䄸‡÷ †õ<ìÉc{ú$*2&ÆÇÀ=ÿ[i©)<.×ßÏ7;+³¡¾ÞßÏ·¨  ²²ÂßÏ·¬´ômI±¿ŸoMMu~nŽ¿ŸossSVzúÝ›¾ÀNL|pï.ÄFG=} ‘a¡ÏÞÀ“GÁqÑQtïnjròÿvTS“¿Ÿo~nNMuµ¿Ÿï›’â²ÒR?ßÊÊŠÂü|?߆††ì¬,?_—–ʾç6$ÄÅ< VDxxèSxò8†õÞKNˆ€{wn¥§½àp8þ~¾9Ù¯êjkýý|‹ +ÊËýý|ËÊÞ•úûùÖÖÖæ¾Îö÷ómá´d¼L»wç&$%ÄßÿgG…†<€ˆÐ'¬ð0âOˆ€@ÿ;i©l>ŸOì¨Æ†z?ß‚üªÊŠÞñ7oüý|««ªóssýý|›šš²2Óýý| %9)(Àâc¢C‚ƒàyسÈg¡ðôáøhß»ËNJ€€Û~™/_¶47ûûùæåæÔÔ;ªä]i©¿ŸoEyyaA¾¿Ÿo}}ÝëÞqÎËÔÔ{þ· ).îу@ˆ~þÏ;þäñ¿ïøý¤øx¸}3ýÅ .—ëïçû:ûU}}¿ŸoQaÁ?;ê]iIq±¿ŸomMMnÎk?ß–ææŒô´»·ü %)áÁ½ˆ‹b…>~Ôåþ4Ñ?莢аBT‚ !Ôe`ÁBuX°B],„P— !Ôe`ÁBuX°B],„P— !Ôe`ÁB_AQQÑܹsi4ÚÈ‘#…—Ÿ:uJ\\|ÕªU‚%fffÇŽüXVV6wî\ƒ±|ùòÅ‹[[[³ÙlÁB''§÷6øêù…{ü”öYYY’’’_=ú8>B_Cff¦¸¸xß¾}###‰%gܸqÝ»w´ILLÔ××777oõÂnݺ¯_¿niiÙjá{|‹ü‚^¾ncôá }5t:ÝÉÉiÿþýľ¾¾Ó¦MnpéÒ%Ÿ/^¤¤¼ÿÒÕúúúít¡¯¯Ÿ””dii)))yìØ±1cÆhkk@RRÒ/¿ü²víÚÙ³g—––þþûït:ýܹs:::Ë—/×ÔÔ7nÜ›7o=z¤««{ñâÅ÷®¿¡¡XùáÇ5448 xjõêÕL&sÖ¬Yîîî»wïæp8Ë—/¿|ù2ñìÞ½{™Læš5k&Ožú¡•deeÍœ9ÓÉÉiÚ´iëÖ­€”””_ýõ·ß~›6mZûÛŽp„…¾bÐQ]]­¨¨˜––Æçó—,Y’™™)aµ´´Ìœ9“ÏçÏš5ËÙÙ¹Õ ‰ÇGýé§Ÿøa 233i4Ú“'Oø|¾§§'ŸÏ××׉‰áóùgÏž7oŸÏ_¾|ùƽ½½ïß¿O,Ÿ;w.ŸÏ¯©©YµjÕ‡òh4ZZZÚ“'OTUU‰g h4ZccceeåÁƒÛް®]»F< 333{ïJø|¾™™Yhh(±7&MšÄçó _¼xÁçó'L˜ð%»þ{ »`"J‘••]¾|¹««ëìÙ³'L˜ üT``àĉ`Á‚K—.Ý·oŸ˜˜ñ‡Ãqrrjll€óçÏ·]m«UUUt:8^fggWRR’‘‘ann–––[¶lWWW33³ººº'NÀìÙ³7oÞ\VVvóæÍ9sæ´¿t:]OOOLL¬¢¢‚X¢¤¤dff6bĈU«V9::7õÖ§OŸ… ÊÉÉÕÔÔ¼zõê½+)))INN¶²²ƒXRR’––æááx—ò‚…¾²5kÖhkk×ÖÖúøø¼~ýZ°üêÕ«222l6›ÃáTWWÿøãÄS ãèÑ£í¬³Uƒªª*ƒ!¨wü÷]ÓMFFÆÜÜ<44´¹¹YBBBZZzÖ¬YçÏŸg³ÙíoƒÁíW‹c0111ýõ—ŸŸß‘#G„Û×ÔÔLš4)11Q[[;++ëÆï] F£µêîàÁƒDãÚÚÚöƒ!¬èè+ëÝ»÷š5k¦L™"((P^^.##ãááqôèÑ“'O.[¶ìCG‘¾@Ÿ>}´µµ ::zܸqàîî¾víÚaƹ¸¸Í–/_¾wïÞAƒ}A{öì±µµõððˆ‰‰'.1NÔ¦ÆÆÆÆÆF®Ñ­(++›ššFFF@SSÓÌ™3•••õõõਨhéÒ¥_íûBò”QBYYÙüùóÅÄÄ6nÜ(XX]Ø0öÁ$IDAT]=þ|qqñÕ«WOž<ÙÆÆ¦¢¢‚Ïç755M:•8&-xáªU«JKK[­mݺuïm XR]]M,‰·µµurrš9sæ›7o>¬««›@ ^¶mÛF4³²²"2|(ÿºuëˆW¯^ݱc‡¸¸¸««+ŸÏ÷îݘ1cV­Z5}úô .p¹Ü‘#G.]ºtïÞ½ÄvïÞmiiI˜€¶+áóù3gÎ\»víüùóŸ>}ÊçóÙlöäɓ׬Y3þü¼¼¼¯ýÎP ^"}rrr·lÙròäI²³ /‡Ç°ÐwaÆŒ øóÏ?É‚D‚#,„P—ÝB],„P— !Ôe`ÁBuX°B]Æ‹ëNÔW$ÞÏIEND®B`‚openchange-2.0/mapiproxy/documentation/pictures/devdoc.png000066400000000000000000000022571223057412600242030ustar00rootroot00000000000000‰PNG  IHDRàw=øvIDATH‰í•ÛoUE‡¿™};§íé…ÚÒSO¡§biCU"cÄG_LÓ‰ù#ôÍ¿Æ5F4ñA‰ÑŒ/n (¥Ð––ôôr.û왵|ا¶$†à“/®d’Ù“™ùÖoýffÃÿñ_‡y”Ic#}?\åðä(a`P`ayoÏßäÒõ%œ“(yñÙ*Ï?½ŸòP/1ÓÀÉBÌf^Ήè;"úýÆVKÏ\¼Åé_nrweãသbÌუ;4ÆÌ‚ Ø új’Ä'K]…£µõu³¸´ª•±aÓßßÃæFëZ£Ù~xÏ{¹;7ŸŸ¯Üæ§Kól5Û;€ñò/?ÈÓO–I’¸ÛÀ‰0 Oö÷õ½ä¼Fwî,3wã­´ IšB!fbb”òp?ˆdµÍôKçäUý¼ÙvísWïðá©_ F‡{92]9b-o ì9aÃBiõþ:g/Ü Ùl"âÀZ‹ªb ˆ(‹K5jm Å$(ÎöuG³Í–[VÌûÏÍì{û³ÓW¼…|²ó2»otèžîBiaþ6×çþ Ñhb­% #’$!Žc¢0$Žcâ$Ɔ!‚¡™:–×RÚ¶‡'&îíïï{óúÂj±ÑÊrªš7qmphr„gföSÛlqwé>Ë÷Öhµ-Q"â)$6£˜½Ãƒì«”ylO>kã²6.sæÓo.—2ç·`,A” @»Õ¢z¦&F˜™gm£Îââ*+«5ºº T*e*•2Q`piJ–¶16À1¢J£™YUrÛn“*„ظ€µ!âi½AÁz¦Txê©I’¤‹v« ÎAÐMÜÝ:‡÷mT<" (Гl`¬ÙQ„Æâb €,­“5·°béêÁ‹ø,ß…Î! ‚<Ù¿Å!Æt†TQT1†¸X¡ ㄨ ª" ä‰yQ‚À€ÙU"Uƒ±;›« ¨GÔ`Ä Æ`ŒÁZ‹Á Þ¡²Ýò$T$OL•íuLþûTPÑmSPÄÔ{T‡z‡xŸ÷;jt[ydž] rˆJG6Šú|\D‡A|J±Ø‹¸¬“µëëQñ Òì2YUɼ&½¤õ.s¹óÆí$àœÇ«cÀ;ðÛ€ˆª *ˆt ìRPÛlþpêë3¿M¨N öõ)Y³*y]½0 âwš×_¼gm}ƒ?o/¥g.Üøb}«•ªjþØMW‡806ÈO—o—öôv?ȯž|ý[ǹDÖÅÿ9Úêð/l/é_㣹?x 耀 ‘x k,R'0)¼U¢™nŽ^p$h9‰ 9¢WÞè_àaÎ'ñ AŸ} ú·¢Ýà€9Ii8£íìáà2Äœ.,Fþ `‘€Ù¸B¶5ŒÕ¤XÉ´$ë˜&Š4D£µs%)âˆ5ì Ì«)R1¥éŸHïš ³ƒj®-Ü 5Ç’Å!øpA 0ò±àlX°Q†„XX&$s‚uR–J–pÔ°b°†¾"èED¯O‡)èÅôqÿÔáËš!©™¹¢äŠ®!$Õƒp8oùÂè(g¹aë#V’ÐEžÕL*Öj1!X*X2áYôY~OÄ×Ç+¶¾ÿAQá³÷üÁ—çÙ¹‚–¦ù@;ÖŽBL# àüC`äï`7`[Åã‚­ YVº¼æ ‹ûZ)“’E1‹PÊ.ÜÇ"4q¼EO Õþ\r -ªv>´,·¬¬˜©X'b1g­(,œ7Œ|6*ƒºxyÓ K _žÕ,‰ítÄJ åª9N¥,ÖHÁšdrº= ý3ÿ¢f•ÃH7¨zÍY[£dš¶7#ŸFQ±¼pëïYQ³š³¼tqÄ« iZk&4ëôðü€RæWÕ”Äxq÷û1²²?Oôg´$Ø-nÖŒ—8–ÀÈÑÑ8Š^ضŒŒÈ kj×/Åê/‡,+Jü´¦<3`4ÇqM/j!É&)&¢¡LŽp}OÐ:žšÄ‘ý3æT0 õªsS"鎻ŠYÉò/ ›àlC¼¢Ù/­ 3¶1r›#6*8–cH¦•ë8÷æ(pl,†/jÚy¶Çæ`»£,cKI‰Xÿú45>޶d%ÿ„×ö£÷~¬ãH¯èÚàjÇfïi‰qŒÖvˆ³lÁ+š‘³j}äÆ%_°šréGgÙÌ,››g²Õ\³Í1ËkäèùîÓJØE]¤Ý•šu$›“H|5kþÅüÊ™kùL5G|Í‘šÏ•<¥\j–;LÉªÏ Ôø-ÁZqˆcl¼Ù:f­fn±~ÎW6ë,¯-WI,AcBfJqп\:ñ4b =x±f!P5½­öqãLŒ²º¥1(Q‘4VÚÌåŽkÞUMììè_Ýìð“ÉçïÎß·ÌäékC2¹¢ñY¸dSŽÍvPæËÊ8×x%22ˆÄ̰¥5·¶Q¯@õrø±†ƒò­¬ˆ"ôšH#Ç•5N$ ¯k GÄž ÉËq¶Øc°[‰1Ùn‹ ªlö„[Mòá<ùÚIp™Oþu“Ÿ’þÕ?mdÃã'ªýkªþ.]ÂÐ2ËÙÉ1ÞÅL‹EœE*è倀s‰W#2·1`K›,«\åX`@R¶{{:nœ4~ªüe7Iÿ0žš+̶Fÿe‰—º9Äp9ˆåHsŒ€€Ÿ.XF¶0 ¯Ýư^ºQîÆ¥àRÖµ+òÂÕ¥’@»ÒúÙºuUe0!ŸlÍ¥P3³ªÝEÁ«5æZCùznuDÊð¾#E£…¹×û·œŸaHzv3cã D(|Ì>ŽðU‰gQ’xY¢jî(LáðŠØ«ãÒa‚³œHæœ5úšo‰‡ü¤†ËÓ_¼o.U‘§š>K\ÌÔ”ä7*XQàrˆå@Ê߸`ÙÔleÓ®öëþÈÖÎéH[Œlm]¯q.*c ¨¶Y*áB´Zq·'cÍ´躩Fíh4,$Q3èY¥±ÖO ÎH¬ut£D‚槃Ì%[ÖFlcÀò‚u;øǬ§°\pPàa;)Šî²FFƈ²E ­ÝŒä-7ei0@•Íh< œðæDv2ü j>½}‹¢v[¶ÃaËf8Z`¢ˆÁø <ÉÁ z.¥q( àï &#r{b9;µš2é¨ÓkëDÕTßak;ÊÊñ¸*Ê ¾è¨)ŽÛ˜z!€Œ@IWlã «ÒEZè˜{æÕ §ú l•rI‚,)¡(ÖQXwJsþá5[^býzÞÃ>À«‘æi-=gRü”Ñέ”"-9.$–…s]²™6ërÂN{¥ã:’É…c%gUΓ&1ƒMòê Lì–07›¼þÚ„šÉò \ȸ¦€µô•2HÐ-z ã£à³a¹/ àï#ÃÝ Ævy=?¶4çH4‰“^/ívpqV¡ý<ˆÖ<³uU;”Ìô8—ÂI)u$êÚ•e]׸)R¥±rRq`IëàqYk,Îè#Äh ð5Æ¡ggôÌ–öasRL±p"j'•kŸ\ªWWètŠ1cdI\"AÃ…µZ¸x˜j6b.ð~e±hx°°ÒbÄ$ùlÌÚêtö…!j^ÎYW¹®â_þÄÌ^mi¥*¦mv¶Šgäáéc p^l’¢uû pk4*‚§×Ö¬—œë_s@ÀŠ Š‘ueåÖúfe3;¹Üïë´ÕÞ¹ÐY\Œ»m¡%¦²U¼à'ƒR†¹;hኢ+pcÈ cÎu±æJ:T͌ז™Êš Y[J#7Û$­T ú¼ÒÚµÚºÓæ^&ÛŠ2.¢¦:¨öøI7èÃ÷éèš{?ϺÂS ª—ÕÜNÑ H¦1ˆc¤?E«‹5IWF%*ÖX²®Fvö¨[)˜Œ°§‰`g¸gð-jÝMRëÜŽžæGWô)¼¦ùPxU7­²á§£qhä8rÌ¥çú—p!â‚bäµÍj­_åÖ‹Á Óhv®=×Ó­»i(æ0*8ÈÏA†tƒùLö繎 (Ø$Æl¡˜ÅÀnmËduÉÈÈÜÖ!¶µJít$v¡i>£l9àqNügK”Í\ñ•A=Øtã1¶| Œ,0¢ä‹ŒY[!††cVKŒ`€Èžëa ZÍ™)@׳4ņÍЦš£cqJKbaA5xõ™5Óx…š0¯ÚR$Â'oˉ®vVx–)q[Ö„•­a=òÀ[¢ºR=ý~¶¸@èr”׫ýx×ñ”L"YTn’’³ù٨זsmÞÒg| î|3gý1jg´ß!1 , tì¨ßsQb똰ƒ˜Í3g0Ä!`;Ǥ’<ŽD ©8­²,s”}ú7"W{FUÔð´ ŒVlP¹±Ñ°ÊÆNèXc𣖒ƒLW†:]%@žÕk†ËÃkÀÛD*Œ5Šb«–R;P¼(±w¤d\ç\5 8OãvKɉEÊÆPÓOÅ$ûùæ­tï‘lï—ö†1þM‰ï7†HÓs­VøYâaäS«Åñ¥lm`„ÒíT“‘<—J ³z˜Y.t§wÛ˜PÜk±DRáÆ¸Iá\U;cxe±u“& “(f©ÿ^YYºSu9ðu’bx—ÂHnWÄ.ÝÚÓó}©pNÁ]¬â«1•„òêHf^U.‰¬%W#Aý­»)ñ#IxSãÀE(1™ˆÓç;—†Â¾Úù¼æ˜íûJk»%4Qû¸°jŸ·Ê䌼‡|mKm1¸ÃVTR7Y}…!O%Œ­³þ÷ìD.Ñ!-. àgƒóž‘áòGY½²Qm ðb«¥ãHÙÚ˜ªê¶EšFC·¶Y`ˆ EáS)LögÛ(÷¶ZY25Î rNáÒ¨'¾ñ6"Õ…¹‹ú¸?»òÉ–¬…j*¡Äd;É)+1s[•µR¢×“ð] XSa†ŒW¨|±(Cá8¡|â3‰ÖŠòÛà ŠûQ‹5Hûˆpe–±qîlÞu*EÊžm±žhDnîš{t“ò<¸Áª t=ߘJ`‘·Èý‚uâÓ}µaçÕ1›OQŒ{»gí0>@©®ØæÐÁ#m¡lÿÙøë¼Âq~32\û8skýêäÊ8+ÌÜ\k׎d&1¥oŽÊqn€‚W˦?BÝk [¢H&1¹È#{b µªjÊUp!$VBS´ùh,½ŠÕ½‡‹5Ò¨ .–½¤Úš\í•jVÍ`7 ÜÑØg¬ai Ö*m#{ _TR#)ƒdV“´âémò"!+†¼Œ‰qTP—¶”‘Ó%¾ 1² êî¨3ƒ‰Ö !F—–þà­š„ ü1Ç’2^¹¢E‰.ÉH»µpBÁh"†yðb³ÆI*NÎvðÌÞl¢ð±À©%ÏSH9 àïŠó; ˜åfy-[^+Vû•A×¶øS‡f/Ì´"Ë£á¦à‹Ýî|¯½14£ÌäyeJ`j^W’cÎ1÷kWJr±ðJ’妟»‰¯¦¯²S>Ç€3|ì¶gÚ_‡EiZDT1h‘"£z<áƒb4·;q«­ðyÁ9b®™É˜Ó”SÁš’?Åš‡}£( B2£X5F¶…ã'´"(µ×Á׃ »hƒÀŸŸCƒ¢Â°•œu#u˜mÂÞS?%íŸðÔpýºEzœ‚æÖ6õį.UÈËpI±¯Lá¬ߥ„e˜´à»†ƒHw•#üpkd`„—O O­ŒV7²¢²2Jâ8I½s>Þµ ZÌÊ›T€á¨X]ÔVè$­—Xí¬µ–^ó&R ,ESÝ4it.e,ÓöŠ4)ê ∼š ¾Ô¹‘¦öÕ"ø¹kŠ>67Ë|\eÅ8ŠôŽÅ^«%¼!cM„u6o1CƒSìBŸ9`Ž ®æe îÆ<8Ƈà/6æÔvš±¹–´¨ãµ”®©öÙʹŠTl¸‰›’×X>·üI4Ù`¿‹¢tBóˆc>† $MFQ“:|„+–X˜ê@Ê'œÇye-_ÝÈóÒZ.¡¸3‚U‘VUÍ–6ÜL[Ì÷χN;Žb½1•e«¤•F–Šø¦šúø° <^N/8Ñ´±xŠSåY̲à˜D\’¡DŒ‹i¦¤}®1èÁ$ ‡™¹q´7n‰"Öé견E©ªÒ ¹R-¹t@ïÄj IÍŒàÿÕéŠ;æÓ×dËð&spRÌRRá5-b÷?*æ.k¶9Âoár¢$ËfÞ˜è3Þ¸Í)ƒœ—sl0ÀxH%™(|ª.IÙkd©yY0ã–19xø€;æÛ¼Z â"籦¾$%Kj3º€€W<ÎK D6›—Ž–Vû WQÅ‘ÒZ(Ák=ÛKg{ª­›Lƒªtëýl0*@¥ÎÎu@ÆzÉYV–y‡ 4¢X(ò(ÅI2;Ò¹Œxг!RöÔT3b*Fi ¤<$PúlšÜ<_ªÐ-™g˜C§”LSL\ ØõÙ^\ûPP\V¹¼ªk¦`Ø)ðu,é†ñ@S†0¦©ð»>ií4) ÑIÐëî%K€ŠmÓ@ìíêFá§ê]ÇÒ¤¹†4Æ=wPÄńn8NFàeÔÈtÀ6QðpèÒ”çî–èŸü—p>2²µnœ×'WFƒQ%„†uiÌh\€œU¢™šGÀÎRs·­Ó–L"äU`äš›æy>ÄççÚq¬Jãò’ùV§È¹ÖÁ)üSÜó¯/Ó#áL¯ýGŒòá`øçBÒT¿.(4àá¼ ÖÔ+¤j24|°¸ {eM!ùÌ‘RÖ zÿeŒ–‘÷úYZ*67r¸rà寀©€ŽÈö“Œ…@Ø{úºgéW éWŠtLǸx©¼á=…†yã’1#§1ZdF˜6F,Øøµ*) OáµqjÈOʦõK…ýÓÃm‰ÐíæÎO5†c³Ø•J¥ðà|bäÚº¢¬_>Ñ?qjssXê(êv;³½´ÛÝTöº±&QªmsTÆuåɈ!ñùÌb¯¹T Ÿ¦S®EU™Ñ +²¢ÓiÍÏ·€ Ê=‡&;–$3§H•oP„¹ »‰LöEÆl‹ß0%g4Iruݔ͑­ëyšRßÈሂ’ùôf‘7¡’qfWWê"7^ d팤ôÌîd„Ú\”Èã(ÀUc®O+“MÚ²ðCAE±aäkŲ3."…¦EpF yǮΠ‡ÀõNSÀZR,ÛÕg8/gDÊ@Äp¢ˆ£½½ôg1(óÇ#³cV‰ÀÉ?6Î'FÝ»¼–­ ªþØP×M$âH+ÑNÕ Æ„%NÒ1{Ìå• v-eM`K=LnC(9! Gà”Øt6e›ëÃV ³ÓÒ–Ê2;.áÈ圲&à‹4­çhßr„–áš48Þ±³F¦´6G¦§#Ëc×ÈmŸgêºîv£nÙßçuøÝ[‰^¶±aÑÖH¹8æ~cMeÙÀÂ(•jÿ,e@û6Ø’â•9í9„Ñd‹ÎpI’h:+ÑG^Ϥ˜z\:Ô¼@Öãœm¬»;Ãb¨šiŒ>÷Ò-mýhP“ímtØ08˜U–|î +K'…›m;¢€€ç#oôócKã'ûãÜÎ#˜ÅǑж1Õ<Ò<VFéKêPÉ m5¶A¹(U¤lÃ3ØÎ)ј +¸Ž¸©ìÚÊf™—33­……|ZÔ®¨\Mb‹Iˆw-‘®@vl„'›:;/K_l¸ŸÖú(Âë¨{—²¡r©¦¤l76úv47—ú|g)¦qj.ExCÖï£Yб’» RÓN"eÄi…ÕwŒVá@Ôƒò5dd'é"†\…’¸)Ea”q‘çxýè}ÓÛ’•ÖrVfNcá WÔ€ªá[)ÖPÇ©’ªKà óš•Æ%hœÁ‹¾îºi 倀 ç #ç¥]ßÌ_8:è 40ü™¤*Ž‘–ˆé˜"GcId¤•TŠD-ú;…ÚÄ3öÄ­B6^ÁX9Ý,ÕÕµ©Gì*«ÞLÒ›iëH 7E…ûP{sdôòÄÊëÚ«dG4ÝD9|F³g[Ÿ¼áSã˜I;tÁ¤Ö}©l«*¥ƒÊ”;gÛm¸¿¦•ªM¨î”ìÔ)LzV‘„QD;“TG©¯(¥:gÞä­¦Ø4ÈXï:„YÉ>NbɵC¢XÆšoùp¢¶sQ‘M]f ©ãaßIé`ó‘^—ø¶RìÈ¢oúŽ­V¼0<а.O×sm¡U^ühœ7Œ<ÊÊ—O –׳h2—ÄqšD\r¿œF›™ÆZD”J¡”N^¤ ƒ¤–¦k`T `€ÔœÄhN)h¸ ØJ”¥9yb¹6fÏÞ…ÙÙVK£Õ½³“xwÜÇ“-ÿùX)rJ ®jò¾¤Ž–™€\5$ój›M21X³xˆDYè—Üí(¥˜duÈ kÊôèñ¼?0:Ž’³/š"å¬Öh„¥Ø#‚ºf9ŠeŒ;3,ëP”B‡‘k…{Š\˜K†9ÒØN ï)ÁõZP¿ã¾Òû{p¿vcïQSÁHÌ1‘®ÌUVh1»n‡FØ-°ªÜ|G„€r@ÀÄùÁÈ 1O,-ú™h}­¶¨ù$†$’"E$¢XµSE ¬ÆRÑ÷hÈÏ6"yCÃ@™BR@Ã%¨¡(>Ì–ƒý²¬ô‡ gççÚs3 PÏf¿fµÄ€6aVmÎ3Iu€×¦BñŒÚ’7åR7áfKöo5iUŸ\ÑðzÞ[clÚR­´éλ¡á²:]®­©Sõ‰5³´T€PO•&\+¡4oÊXR ûÂOD‰t‚ŒŠ Ï‹åZ$-j횬Žèva£ŽDr¸ÆÂ¶ÐØd2ïˆFìLýòšT ô ¢µ8øJNJNS½°Ð²–/¯³Ò&‰îÄÄfY¹qf)BŽõô: JAÏ¡x–Z_ ïHGÄäK6„lBÉ”ÅWb °¦í´ÑWሌ·¬6µËȰ}D|œ•µÅØ·1µÁjq&|ÏU‡AdCu(xZºƒ]\1òjtOfØ× _§ñ#ª‘Q|<¶¥åí–hK—;'N—jbUJwQ“#³’~åÐÁoÆQúv¬0—Ž&"hYWaF ä€€ˆó€‘Ãr”×@80én§Ñ\/%HÁ   ž’ÐwØç\ù¸Ese³†’¥±ðíôpÍ÷¢CæõéÃ0¿GCùšÖý¨ ˆkÈ\SßhKñÜ(ÖišŽÇåÚúdu'•í&%µ_¢ÐoŠûˆÞ½öŽET:(š¬ "YIÁ G‘VG%v†2ä(qn°FZí‘#{9—Š:ø9Ÿ}L9|E^ŽF#Î5V…PÜ3§QvSÔºØ%ÏgCóÆ2 `š ]=:Üû–°‚gYeÖ¢kð8á2My7BM]Ô®áê)×n²§'E4ZòÜ )3\QÄC…‹ð$aô’Ò…B¾€€„óÀSJYPÞ0 èµÍq­¥ÁD©…Òµõk˲ö6AU]+¦qÍòÞ¨–½ÖuñéÉŽt'mÀ%@l,M¶ OiþíM“‘úï0á[P®±3s½lœ/¯gƒQ¹s>íÆ2Õ|#Ã0+Fx)Š §®ˆ£á @ÉÒÂѸ*éÈB¨ _7 L1 ¹Š"Œ (ZÊ3”5…s¢‰Vc‚©Q"_V”(âwïì…Ùö…j[+°¨ÛšÅX‡ÇesZ¾“R8\XiÐO¹—°Ù„­ßþǼq6¶Ûh¡„Œ 7<Mëù.Û=ÃŽ¯ã`$ ¶“¾[á¥a”^.JÊî€',p”Á. àb»Ç‘‹²fÕ‰åñ樮¨/Òb¦«g» º U.+Ab±%.Þž i}‰†£XBršè¯0yå^–×ee±·ˆ©…_¥‡±` !»Æ¼{;yÖLØ«²^]Ù6ܳk¦“ ÝÄаþ|&ä9ߊzsP4üyV5Æ îKþ¸kÖ©S ÕŒHÚßw³6%ƦáJblîGm™¨4öàÖ­”º(*­e¯%ß\YßÔº‹‹ŽF‘VðÄpUN†}ýX¤¬PµÄ:r´Sê´Ñ•b\³•uŠÛNDžç*Ž“„¯o[©«`D‹[r®åZ±8±îÒ~·¢$ÉÿåT£™=&„àíéÃ<“^xAÄ]–0ðØkF‚ Q@À÷Áv×Èð3¶­­)Ï™€ùuU«¬°-Wá•3Ðq9C³Úp© ¶õb5‡O5å#5IYƒvÅ5.r°V¢÷Æbäf­*±YÀøèq³~TÙON9¿8W•åÑcÝn¼wW§­X2Ëe<¢x:“yãÄæ'øÀ‡¸phj̾£…AɯKÊ¿£1 d¾Ÿlt=æŸÁUTT <ÊÊÊk´ë ±‹€€ïÁyGçeT ²Â“ há,/22xóæÅÂ6‘ßúCú…;œ"c”²¸LG¯9úvbúÈ¡.®hI ”a„íPÑó¾©èÃj`SáB™›h]?£À°rqŸ(›5ˆÐ8ª+;UpìT‹½ß0ÜÁ)ÙI{Ë!ŒQ o…Aˆð.ƒ7¡àÆò¹Ón>>MwƒÃKYaw¨åµÁæ` ×=‚GSÁe8R·Û³A~ñÞÅå`°!¸â\Ñ9)™D*:8Œ@kóð¬k%Ô»¦zkÅ2x7eÖMðö(«ï ;Ph¼Ÿ×Xôà\0,eSàHcW~¿H —šh̸0Ô+ ÆB> Ë`²8ãp åsý—°í°½™ò€éÐi3CÛ ë€0¦ 4ÿÍgÆy⣠3[a¢V7ƒ’Ä”6Z¾ÃðÍàe“zÐpXL0ð¶Æøã‰ÙYŸÉ@îš^S  TD |ï¨Û¤’+èáš1Ë|‰õ°)´ÀýB"öV¦FAZcð¦BÖç:¬c’ÿä¸Va¦Ûí£³rÇ\81ËGp2S;FØUbs‡æ˜X"Œá3-«€TØÃx£ÙÞó$Q åÆã"Ib¥¸àà|D `ê…®ÒÝ0yŠR”Ÿ 9µ’☘ADŒÉ•ÅL8 ‚×8VÁÕÂU™p¶7#—å¥e ê]ã©F‰Y% L.OP(¢(E7³ušõ†a¥V çïÆàÚF¬ŸŠûÜdl‚⦔Z`á\…,! R©”ÖŒ©k¨wmcäs5µ/ªI+([ËNƒ™yM$rã#ÒùþO¢1Âg¬Ñ•ž”«²d$|É·OiJ´ip™~PÆ;Ùq¼qN«Ž8(à2Ÿ±ívTVV³Ý\' 4°+Ü Àx–c G–ä:†ýK å678íÀ²“HÁkQS ¾²uV˜™vJÆÿ¬¦ð­Uм°ÀæÈ¼5Õ¶X³lsÁ°¥25É‘§³ÊEd6Ô¬hžŸÆZÈP1°Û‘¹ä ÇåpTyMUÌ«[ ïÊšª*|q¥Áù”2ŠË6 ñ¼Æ¤?¤Ù¦!ˆwŬiy$¶OuÀpÎê‘U½[zQJJIöôÃkcïÚCÂ~QŽ1$8Îj˜æwRì/U–¨)ìÍóz1ñ§§lGúÒ”(hïRâ&޲Éôˆ"™eõ`8¬A¯Ò #èbWS@„B 8à›¦)Ðu^˜v¢±…㽃þÐæ>‚‚™$­®6L>X;%5Ïö§ƒ¦6F©ÍaÖiDZ–Y * •¦À!ãHaâ²u½{Mz†ºpáJ S4ÍVp£@wS¸æ8y2™™°Û‘‰@#•ÍK”µ˜ËIŒóR$B`Ì–û6΋FÌkpHL¶ö*˜"­UY6z™\ŠüJUéhŸãxm}½\cåCÕÙ΀„¬LI vÞR?r¼š2t…÷ŒÉ|O&TÖpxiëzœÁ8ÀÚ-‰sö¦~›ûæ ‚HŠb!ÜÇ[ɈûØ6ò¨mVùÐ\Tcð-{D”gf<.ðøNLRýšòDc(-$c‹Ñ —Ä^p£¿¿W¾¾É*Œ9ð­V¤º=ô…0¢ƒF8€Á[?áÈ«b8*çÓ ¢…&'|\ÏÄ0:Œ­BKeÌrÃᆞ ÒÉ 9R"/ëHã¯~G…ñaq̃†Çk*|àØ”6¨ä€€ ¶uöÛ¤>MÀ„7f±£ü ©(¸¢D%aˆ4xèÊFÚ;¸S2f$cHU’ÿ Ìñ q¹ ÿ–×c®‰û(Ÿc«^ý’¨Æ´3Î)§C#@ÍÑJS^1®Øù:fänæëú¸ï–$p¨ÀˆsÛª`Ü.Îi“ýœ:zLìí½è6T0"ÉGÎrÌCð6IÞ›L—ôÈÛûÌl¤ý(+€h·=”rb ŽW\æYÔØî¤µå ׬۸8i‡£cÐNá`aêO~îo‡£<Žùî½_|ËíÖ*©VP겨¥Ð­8Ú žìXlsÔåžÂBG¿­–:µVÆ»¢™]ß@*£«§ÁÐ˙찭9nØJÅòX²\p43ÒÂÚzœ›nk[ÿü<±­5² x6˜­÷GEFÈdW/‘£“D¶Z83/« QStÕ{>DØZ 8¡•ÆÀ¤Ô.Ìä1ì rÈ òŠ÷ ¾žoà°ÞÁˆØ pæ¾?)U'×uÓp ­ˆ1›‹­}}Ñ@93éˆJW®”˼âíX´INúÆ£t‡ë1ßÛÚã˜P»ÆÔ;Q>ƒó"˜†.HcqS£QЉ×UMÁ Q˜I&¸*á‘iÌíSãï ¶Öuõ‘O>øè“/<ûÂ)àå·Ý}¤,e6I¼“ Ü…‡Œõ2F»ªÀ$AÛëh_h(Uc[á×4ÇY ·–hV¸¦|Æûu nðé¦1Ø#ʱæ^0´ã°ùV;–!é" Àã<ˆâµÂÜ6f”Æä5®ú[^a S˜„²I#Ùk§i„öÀhÅ¿6/*US0tceHçÌU¦ÊË" ªíu¦^Ø×öŒwd#:¥LKéUMùÒ1?hèS9ø²¡P4|¡¢e=xh;y:Üì“í8kw[ÃQv|)++6ßBëaN^?µ7|ð6Èί¼aL]8ÑI£öQFùvbj‘¤,…±Hböˆäš3¿—0ðPž6ƒ!j<Êa~€¹:®+EºÛ‰}ò6–BOà‡¸ƒáЮmdKë¥ê¥ZmÒ4œx8Æç $>/G®Ê–ªZTÄ+ËWû8ùèø–¬Þ¶_ ´¯°‡l3ú>ÖXàHѲFy}®ÿĶ ΃ #(ÐHËVª;íˆZÜ£¤UI,ç4Å&à¿ì(®‘ƒ²hN‚B–‘©ª¢ÈqÁ óvõ ÑŒ)-Ö¡åÁ\aâö!Ó5ã}¤ðut‚<%0W©–®"c¶HkàPÙUsÛØ9Eç+‚AÁnMãÎLgcmóÅ—ËýÍv¤êE0•fø?j¥Ð‡ ¦÷è^Îp0àñHc(Ù›ZÀm´;:Ë¢µ.1€ zLa²·«¦™ –qÞ£BiAn>ÎÔds üŽO5 –ªª2eeÇ9Ý£¥’aü¬(²VmÓVû‡Ýž±(Ž L†F‘K†4U¯A Ñ•˜™ŸÙ\Û|þ…åƒw´ŒEôGÄ\h²á[hS Gcb¸ZÉ0©ObsÓs­ë%‹c>7ßKÛÜÌ…ÃÆÔŽ_¼2D0£¤¨* õ²víVŒ©&¥™›I8¦cg×_qÙ=‹ Ww/.84‡Ãˆ `ãÃA=‹ár¯xœF®|¢»t^¢32rjæË¸ØGA ð¬pã˜Í$ìTó‘)ÜÄáöå–i  êaˆD÷d hJÌ(+?˜œ'ŒÌH‡&‰n·¢¼,6û.ÓÇ ¤¶£F? ¼äincZy9V¡ }­È°¤›Áü ‹J­ 0Æ&‰tš(\6dµ/øÃFt è»6UŒL©¿¢öΜ˜zçó4€Ó ,ì¶ØSk¯-Q'¨cU˜’3Ö”ZÀɇø.Ò¢7ÛÝX>ýÌ©«¯ØÕŽ‘µW6°<ûöP“rm˜à—%P¹…Ñ”>#<Ì©»ÑHòvKîÙÝúŽJæ4%VS­!>­û᪠j Ïb_éÂÓ榨”]íÞ}÷«Ñ_4qíN&Ù›T ^ÇIŒáQ²d›‹ñ¸–àÆBD´?®Ñ^¯²”6BÖtpËý‘K4‡ûg0&qTáÓ,*ǨÌ[Fi*³¶¼ñëàè(‡™é¦çÍŸb@Àß¶õÊÞÙ×*…–Ò[!£‘Ö,‹Ùk1c¢F'"º¶ðžëd”ÜZ‘þŰEM± ‹Å× 5uUã‘1ÆÚŽÓTÃ$ÝY…fë ²5íðšQŠ—/D¯"*šÆä\¥#o¦FiЖ:`;ÌžX%ã4¿¶ —×d6®Ö7F;çZŽùÆF{jÊÌõÉX(É-É2¸g ¹R±ø4ÂMá‹8­VÂÈ* n³é"å;¸R{l,MôK‚äh‘¶`´Ù¨Œ'QžUðÜbt|Æ~Þ g‹²Œ4ë´“Ùd>ÖB(<¯öGÅ VS‰‡TØ‚£óÝMò½ÏÊF¦3,¼Æ»×rÊÈ>Sùçc©ä¯0a}/ ±ÝÝ8Ïüg¼´š¯ndƒjWR¨Va»OwäIàBÕH-‹¢´ÆbݦSøÒ2Á¤T‹•'H6 ¶h÷B¼0£4öˆs@.ÃZcúA[P.SÁ´{è‘§^:v ¸)Ž¢7ßy£µæùOŠleµ'ß·{~×ÎÙk®8Ði¥ÀË'VÖáÓ—-oôÇI¬/½xçÕ—_´saf°9è¶ôÁý=¸©AÅN,eÀûi ã+Ãï>wbiuó¥——¨¸¥óE»ço>rhÿ¾IL.ôÃÊqÄVÖûø'†p—fÿÞÅk¯ºô؉ՕÕÍã§Öà÷ì\€s]²WcK) ïÙÙv™•0wètÕú³/?µCË®3¿pÏ­Eኼì´ÔÂBú•û¿ôío>™åUš¦ï~ß;aà{æéN]>yâäž}»wïÛqùáK/¾h'(ä±qŠR§aô1…ûÒçîá™gà1å…»çÞ;/»âàñ£ÇN?¹¾¼|äúǯ>”è&Š1Æ€{yieyùر¥þêJ‘á÷íܳgÇî=‹gµI}ù¥“úà_WUÿ¾õ¶ëÞø¦[ýkøÕüé‡>õÒ‹'ýÛ+¯ºôÞ·½îÏÿì3Ó-oºûÖWßzÝYGƒ¯`Æ$cívú_çÜ\ï\ÿuœ?Q‹)ºm˜'èãë0`m=SJµ;iÚJ9QÀfãÌdp6NÖÂLEÀv#Rë$A½Ô“e@²¢• ÇFcû\V Gnל줂E<Š„©U‘ÛÍaIYd jÜs/žxèÛO1¬ŸÆõw¾ûò‰S«[Ç5`’#×\ú?p÷wž>öá=xrycëõ/Ìuï¾óºwßóªaV]Î.Ú‘v53‹É©å|e5ÿ«Ï~ý+}çÔÊf]Û³nü¯>÷õ÷¾ëu0`×*æªÒecsìXÿ³÷? ÏÁùË_{biµ_ùœgB¤ÕÕW\|ïoÙ¹87ÎrxVÝNT ŠÁ°|èѧŸ{q ö9°oÇ=w^ç°:QÀóÿöÃO~þ30r}ùÅcËK+ë›ÓÁ×ÎÝ;ÞóÞõÖ{o·•4º*’yâñï~é _ö»]rÙ/ßÿµ/}á+Cx¬Îý³ÿå7¯ºör;ÉïÆüãOÂYú›ƒÒ»åû Žôì\÷ž{îø•ø¶n·=ݾcçü`0þÂç¿êß~ëá'/¹dïe÷Ãë/Ýÿÿï?~4§‡_þM’h8ò¯î÷;ÃÜ|ËÕÞjÊã=þÑ|Á¿¾ñ¦«Ò49×׈ó)jÁˆ "-;mí[Lc@UG)~‰¢¤ /Vv8ªNΩ¢äUá4—í$êvâ4â¦Ìóñ¤G†ó.o”l+`¹þÈ GUmòT۪Ĕ»¹9Ñ‚1€J³«mæûÎó@Á »}þÅ“ƒaö½×yriã+ßxú¯=ÙÿžO=ŸzöøÎ³—_ºD(—²…‰}l\™ÿðÇŸûÔ}ß„¯Àű^˜ëÍδ±úÓžñ‹O>}ô²‹wïZœ«©¼Û»´´þÅ¿ýŽ1Íp1ÖžAå ²O.­?ûü‰Ý;çf»¶6Z `·û¿öÄÆæöéuÓÛn8¨Ñ?êuR©Üƒ÷íÅç2zF«+ky–Ÿu£á葇ÛÜ\䪜B7uiafòͯ~óÅç_òûœ8zò‘‡/ŠÂ¿}í7:| •ö±“'WþÅïþÁg?õåÑh|ÖØƒÅ/£ì±GŸyö™—¯;r¸ÓiùíJÉC‡<üð“ëë}x;ŒúýÑkn¿aiiõÿü—´¼¼îÿ<~é}o~×»_/z½ö}_øšçú²2w¿ù6áñ7õgþ̳Ͼìß¾ç=wßxÓ•çúO; qþidFÿEÍÏÆ ™.6Fõú¯Ñ˜ 8&ŸI+ :M^Ô΢²Ì†eYTT5!¹u’úÖ¡£¹Q8[s›÷G<«¢±]˜©óÒ€œŸQ3{¢Sëð5¾ÙÏ…<#‰;Žô‡öî\œ*yüÉ—–V7ýöµõ£Ô½Ë.ÞuÉþðú‘'^ZZÁO@?uß÷ÝtE¤":b31îÙ£÷õ;”âÌnºîà{ßuÇÜlW+½¾1|ü;/~èã÷gy1矾ï¡ë¯¹D0a,z Òq§ùÙΞ]óíV²¶1<¹´6!™žXZûÔºhï½v< gg» =1ìôyVUÙJTBÏe^sFŽpG¸hÏE{‹²8úÂÑS'NaÖFQ~ê÷]qåÁë^uc¹lŸÌ–PÃÒ©åï÷ËÃ(û‡?ôé¯~åÛÓƒ¸dßž}»adzñÅÏ?w4Ç’yû•¯|û?ÿ§¿üŸþçhÝü•î?°û×ÿÛwýîïü/‡A_ä0<·ç&ÜzÍ5ßÿþ·úììï½âÊKúúãt%k?öìwÝìw*ú»/ú× ©A>Ÿë¿è€€ç%#ûc©ó\‰\85¢j´ÊrWÚpJ­eœè¹Vf÷ãQ5dRq-•jÇuã€lulæûÕ9Œ+GTȌьÕ~9ÈënK 2S˜jÇl¼o^ÍtÔ‰¬œ^ \ïýòëßtç‘$Žáˆ_þÛÇÿïßÿË)ýÕ÷¼ö­o¼a¦Û&úâƒÿËÛ|züäÚòÚæ¥íγjc³sò»Ïùïý:î¾ó†Cï‚k¬,Û»{nq~æ>óèwž‡/;±6ænJNôV µ5sìʃûÞûöÛfgº\j8ѳ/øðÇ¿œ=÷Ò‰¯~ãÉ×ß~í¨*€É£$šF!(±Ïg:ã*hã·<Ìèã·ÞÿªÛ_£ã´?¯.­~꣟~à‹_&gógú«+®¾Ü(ôqsöûü¦öíßsåÕ‡¾øÚëûƒ>òí§þú“Md#m%ø÷¾þM· ¥ºÚšò3Ÿzàÿù7â9÷3Ÿ~àšk¾ííwNøº;oþÆCO|üc÷1 ÿþ¿ÿó¢(ýGIýƒ_½w~afúöî7¿v¦¶2õ׿þØ”‘[:E³À¡ËwŸë¿è€€ç%#{ø¾yó³I¤ÅòzÁW.Ëm¤1ãMÀÜÛ 2Z«`®\•ÜiÅŒI zbq­‘¹Z%£1¹®cDX:}\˜vK–VԌ:‘¸h§nm)gxõ‡ï}ãMi¢5¾{Õ /¾hdz/4 J·Þxù/Ü{kDy0ˆÜrãAËÏ<ŸfYyjyõÊÃ{óq¹Ñoyã‘7¾æŠŽo.­7\}‰à&ï/ŸZ}æùß}æØó/5Ç\Ûns³­ª°Y–×[Ø0¼çm·íÝ5Í'`šéÞ;^}õ_}æk¾þð›>}ÛM‡qér8nuZœ7C Lbê­‚žšuYäÕV–ë;ïzû»ß0ÄÃXãÒNëî·¿å™§ž9yü|úÒ GŸyòé+o8RQúß™z½æu·üÒ¯¾÷ðá=¦r³]¬b þô§ F~‡{ßq×›ßúºHëÍ©íL'yû;ïúÖ·žüüç0^ ¼üÑ|áõoxõ4àzù~àí=öŒ×ÅÃáxz®·ÜsÇíwܸõìGn¸baaveO<þ,œÔ¦Ÿzòùñ¸‰Ã€¬î>×Ë ΃*êvõ‚·[z¶—ìÛÕ^œfRÙ‰¥­pGQ€Ø³X;Ââ(Ju,tD~jÖRSQ,=Ʋ:ƒk_ó3­¹n¬¥e6®Ü(é$Ç.Ôý~Õï×//U/­Ú«“¥jØ ýê›.WZUè½NŒ<ýôæ#‡Ð/Ôb®.Q¯›\z`Çôâ±ÀÕIÊ¢VT.M{ûì¼ý†s=ý'ý›ÿý÷>ôÏÿÿò»ÿêÃô¡/üí7žŽšx4)SlcÕjaô|4>áݵػþê‹0­k-ù¼¹ë¯¾xn¶ãwXYë÷#4€¦XíÖÇØëµ%¦3SW`oþ0â$¾ëM·¢›ºEÍ¥fæænºõ–éõ<úè3­X#»3‚Ø ‹s¿ù›ïÞ½{èÞ7J\ß=ñØ3~‡$‰ßx÷­Ôj ûÒæÎ€sßþŽ»¢¨iX zÖLj§Ø»wç?ù~yë¢ಃû©§ñ ={o¸± ¿ôâñgžÆ·×Ë“ ˆÎÊÁ8·85òq,•âÀ ´ZÙ(‡Y=,ÊÚ‹¦À¹B‘'N¦e)ï—ŽÖmÎEJ-Ä šÛk¬3EVæ(ëVÚmu!Ù¸¨–ÖÐ@ÃNB¬I]´wS†ÜYãP1±˜ÀO\´ó‹Éê+ªíéO=8u;ò)k1ºo?ñü‡?þà#ß9Z™lõàÜ(ËŠ¼Œ’h~®½²Þš~²o÷üâ| dìh8ÆëQÁoó o|õ}_ø°0Èí¯}õÑoºjccðôÓÍÚã‹÷ºüÀ¹þû 8 ‘Í»qù.ÂÔ®µÍjch6FÈÅ@Ö\’õ¦o§‡…ͨ‹Ñ}\ݰˆåXëǰxL>£ñšåºÆÂëj}ÜçK«e1î´£;DÚÞºx…v?ª1B²µgT«‰cØvÄÕl«„ô½é¨BÙˆÝÿÀ“ÿî?éâ¦75Ókïß»pÅå{ûÎËO<…ót H¥´¥DEªÝVÓSÎôR8a·onoý¦—D¿¾9ÄA’ôäjàu+áðÇY5.²zbiD—îF£w Oô>ˆlªF9}#+Ëkýa®"é+§Û/½ü²i·uÙÇjr,B‰ØÑc'§ƒV;‰¢Ä Ÿ§Ò´®†ßhç4‰ý>0Š,-­õëÞX€æ=ý$­}êɪ·™³42àÚk8°ûùçÁëÇxùÅޝ®4ùˆ7ßrõYZ; àÜâadFSo&xG‰NKÇk¹sÙÆ°2’%Øv‰¸ ¹9'|wQlôTS©1º|–ŽBËÞ;3ã`:F)(i׿sŒÛ’©¬rΞ&)›z$#,L9àÁ÷þ`“¥Hï¦qúSÎ0níðzF£áŸÿõS:Þ¹Ð}Õ‘ƒ·9tèÒ]½nG§ê_ý¿Ÿ˜02[˜‹{³±3¾Rîô O­ôÑZÇ!‡(±òÏN¯)ŠÔŽ…N 6ìt~1š’Æ1ŒFØÏÉÛÏ{¡]5Î]·ÍãFµhœ§Ë«ƒ­bxÇs‚¹3îu÷òfu <éŠÂÆš5ïÝ»«ÕJ<)on ûýAonëK¨*°B§P¾²²±ºÚf’ÆûìÞú‹þýЇ>ôºuãç?÷·w½þ–ï AÌ/ÌÜvûÏÈÏ<ýðøO<çSâ’$zÍkŽœë?Û€€3pá0òVìšO"ÁºI±60ùÔ°ÐxJ56éÔÆ@¬7ãäV”fåè»ÆmUb‘ü›sM=R ³ê¹$R‚Ÿ6a§Xq+—!ç+[ä:‡¦‹=oa,¯Ž}3¨£'WŽhæò‹óÝßù§ï¹öò‹6‡ÔET£»PQœ®¡P’µZ ÙTÓ6&ˆ§66ãV”€6×XÞœ«66GÓtGóÝ9m0å7¾ ¯'ÌÓt OàØË'_q2–“Glq1³c/^ÏÂŽ…Q^w"_ksú`ÍzÍò¼.ŽJÕrמ»v-xŠì÷‡pð™ùExæq$Íò²N´xú»/ 'yÜvk~ît„ðÐ×ÿË}ñ¬ZÓÑ(ûÃ?øÈ¡C¦¹S¼öµ7}ü£÷ÁƒÁè‘G¾ûØ£Oûí!d° q~¯ìýÌôâý{:—ìiϦBÔÕpPÀ컬P Sj™„ሒYCýª§ÝIrv§JB œåÜÐôÙãüÔÊf9)´»ôÀíKë¶ðheÁN.m>ý܉é·ê’™‚Z\“½Üi¼¼ñÙû‹bÕ›i-,Ìt:IUå÷=øÈ´JeÏÎÙùÙV„9€ªÝNO×°q´…‡ã ôÅÄ>Ž‘ ½ïÓ_ü§Ÿ¾áÆ+¯½öÐÖ«ðщ‡¿ùF9p[7žë?Ò€€³qÁ2ò Ûi{~6:¹R,oTƒÜÔµÄ,e-“X¡Ó5d¢fD¨Xm=¡9’„‘D m09Að-ó ßCD І8jñ7夦];½ vfPƒ{ê§aààÅ;wí˜9~iwu}ð;¿÷ç—î_Ü¿{&+ª‡yempÆ-Q“냯geŒ³ò?~ð‹þÄWgºéêúÞN?ºåúËn»åJ)Ðà_ǃ瓋‘`u}¬uœJÌòN0Xr†Ò|òñ§þÅÿö{ó‹³@|›ëý©€mµZoº÷-IšRWçÓצ°¾¬ðg:b0.êÚIÅ.:°ïß÷æû¯ÿ„zƒÛ‡¾þèÃß||v®§µ^]ݨ&Bˆ÷¿ÿ­Óô5F*8׫`ß÷Ë÷\sÍÁC‡|í«ýÍ¿ÎHAð¿þõÿúÏë¬ãÛn?òÁþõÚ¤œ’abÜ­pÁF-¦ t¼ÛŽöïJî‰÷ÌŠNÌÑÊ͆Š#Ç”2!˜Ž0D+)à+È?èCQk;¿FDd,Û²°GɾgÍöí™3æF1úöN”•¼uò¦h–w,ÌüÚûîh¥ ll~ì…îÛŸýÒ@Çœ¬„ýG8¯Çкßrº0 0ýAöòñµ)Ãtᵯ¾òýÊ›v-η[-Rßšœzú¨34U2â€+ß:eòôZmœÚWUuêÄòÚÊú”ŽçæçÞõþ_ºôòƒ¬i*h ëÎx8®YK­Ð-škű?VÁŸ{Þ~ׯn1Â!aeãä‰å)ÃG°Ã/¼çMÓÉ`0úÃ?øÈ”U‹ßö¶×qtÍ>£TïÁþ̧8ëoàÀÝg çk®=Ôë…EÀ¶Ã…¯‘§H4~›M—ÖŠ«Å¸Ä©?¶75i^nÈ{|’YŒzÙÒJóo=Ýl‰kÒÎ@˰)©KéÖl Z»£d:ê*uæõðI¦…’Ùݯ»>Nâ~ò¡'Ÿ9>]Çk§Ñå—îzÝmW=òäÑ¿yð F¦9OLæÃú™[^uÍÖôdŸ˜üÀ—¿å‡xûšÛoàÁ9`ûáÄÈ‘ûv&–ZÚ¨6ÇØ¯žc¬µúÝKE ©}~1)eFò–Ê ý’»ûõG®½r?Ð(ðø®]=Üê°9“ŠðÅ=ðéUûiÙMÎÏ÷¦} € à€÷¼áÈuWî÷<ƒAÂjxhý®[¯¼ùºKŸzöä±@P­„_whñàE "‰¯¿îÒ¯»Ì‹ó]W:Gm9¶I½áŽknºþâ'Ÿ>±´´¹Ñ]uhï%vìÝ3‹=–j†½­ð+ØzJûŽ7ÝÜp©Vš&º*mÒÇN(uú¸‹»w¾ûÚ÷Ýzçk–Ž__]]\\¸ñ–C»÷î]^+à8M3mß³•‰[_{ûõG.‡wYi/;|še»ºve…¦}£¬® Î%*!b)€y/»êÐÒ‰Õ^8YŽ7©'atËwíšßêœÉhñ’K÷ýÓöþm§Ó¾ñ¦«¦Ÿ·¾ówíÜ9oÎÎÀUW„_‡/ÿÛ³gñškžë¿Ä€€ïƒW#ûŽs=ÝIÕÊf±¼YfØÌÝâ„ÃÌiÊ®Y¦óYƘن>k ú_¶ÿš+öûõ:N?¾ IY0 cøÔ tXL±€£ ŸÄ`ÙµWì¿úðþ©èÆÆ"»ç ÊÇ€÷Ýn|ãu_}øâŸí¾y™H\f±|j½ÜYS•¨ã”haÏga¨þBÐ:.åùŽ÷¶)•f¤ ·æ¹5‚š7òÜ$FŒÕq5²§ $”}ŒŸÂI|Ïfÿm$Pò‚ZGÎcl:ÛAΣªöX²—iýxû=ŸyG>úÑð/½Àkž¬ø Ò>aÆF› x`\D,†?ÊÂ¥Ib/ßR!b­¡ÓâÃsÊÆu„M˜ÐŠšÔÕþ1aJ,=áiŒ½hAG~V–®“âXˆ­·¬•Ø ‘“¨£4naêšÚŠÿŒËüGù‡/+³tjÍ×(¶Ûé=o½#„,¶'.ü•½ÐbÝ–ºxWº£DRÕØ~GÆUu;f¸\Oú´*0F\SLÙÇmáuYùPFs(GUÑÞQ#4ÒYʲð,C¤‡¯}'=OÇŽ ŠÈ\÷¬=‡Ò1AƒƒÆ,ªfí‰doR¢q ì,ÿK?øø°/#ôëŠM>×|”Ä<¦@tˆ¶XGSJÙË™§¥†þΈ¼ð=ò.u  ‹ª¤ª?*TôE7äïÁ'L§Ó•.ì'J(^¢½§k·€¦9Y}r”§¶UØa@Q˜K(­c?;`Ùô‹'N_ž.H¾éîÛ®9s•/ `ûà•«‘§ÐŠ_¼»•ÆåòFµÚ/° ˜)˜bÏwõHñqÁœlfýH‚Ô útΑQàÊ&ÄáóÒÚd Ö¢ç_ÆÉÅÂùÂeVÉrjÏÜ@|%²k¨²²Ø6Ta¿Q,Òct¢ÓIxgä6œfRNÄMµÛÍÒ"§K…K0Ôl4í*FJa)"®¿II[0Â`­ò>¬³íXãiì“m,ZYrú'yl±ó•kF&ŒD+Ç ,ÎŽx…#/í$"+°¢/¤T |FJ  µÀÚöï YüÌ~ÑZÝrË5øõw~¯ýE@À6AøÓl°s.ê¶µpý“«ùòXŽÇIåd§-"ÍA¨ZÏ­´‚ç¦òV`ð¡¡Z¢9 žºnòç`‹òμ #4äX“nµøué#Ô¤|½‡3‘A¥9KV”,7,¥Ž8·ȞžÇé ‹½ÿñ7ïµäG·o÷¼j{Zç“D;±ÿ!7¢NÁÒ4jµÓŽN ÓQk¸U.p¼©ÝwÝqýW¥Ýì3³3˜4AAÔÈ\ÃÇYQ™Jˆˆz^c6!Ö'rßH+!ËÒ`ŸY'm“¢g³\Ì´°5ÈàÊØX ʩх î×X‰$"ÛûŸÝÌííï¸óÈ ‡ýëÙÙÞ‘®h·Ósý·ðqžõ¢þû<‹Žg'W²²fi»½{1^œeñf\k§$Y?L‚¿ eþÛ0mñäë³)š¸rŠfzœî¨–¤‘̲‰<àRaíyw] ü ƒA±…6Ó°…±Í¬±Ñ€ñ5²¢ÚÂi±IÝdRO¥>ÙÙº&üÝ XJ‡ijeaÃjcsêµÝé)×ÖE ˆ^— Çós1ÝgŸ[E&<[˜Nà øÿÛûh;®ëºÛ¦¼ú+ðÑ  E‘¢HФz¨bY¢dɶâ(¶g%˱³R;Yò²Ó#kʼn‹r‰mQ–-«KT£H±ˆ;E€½ Ú¯¯L¹-çÜ;óðMI Ày·@èýWæÍ›‡¿gϹçìm#Á K `g ^Â4ËC ŽÈXiµn$I3…=¡ÒÈ|–÷1¸d²]&×­FÔmã©g0” §Û1êlàèÃsÃ鉿ó¦’V:‚Fþ;*Ø8“6R¾÷©lØÏZ+X²j˜…Ìö¨tknÄ-‘ÇŒ@‚Â/S·ôGLm<„íoU™øT¯¬uE‘£U8©+= ›Š\ë® 68ƒÖV(–.¬¯Zc¹6"<Â}0®Á\c²ñEd_aÕ<·ÖU‹´ nÅw÷nÖ‘r#bŒ%J[`gûš•¥u…¹f¬E© o`J\3'| FJµ:‰3T†=ÁHØwwb€Çq°”ª“¤IÄËBE‰Ÿ8¡¤ž·sÙ¸G ÌKiâˆçn`ņ·€7#? „WO`Ö®}ýÙÙÅ¢Hó¢±y&N27Àñ³H$uú؈‡sÃw5âº%Íu'TC%ÖT…câzæ8ŽÞᓯªÒž@©£Kß,ቕº™‹B‘§¾¹”•òõWöÊÓ®óÖð%lR.ª:2©÷ÐIõª·Ú·ßtàï& ‚÷‡…)Ñ Ù Ah]iáD’¦b8,}ºbUæ4˜évdžƒ<+Jê½ÑÄÔø Ål(ÆÌ9R3œAÏ™ëêÀcÏ„›R,”ks¼PÓØƒa6’^ÌŒü„8Ù/=½ûØ“ƒƒG ©ÑÙbÃéϙϑ ­ÍŽ]õ@¸‘ko[ÁF]ŽRëþªÅÂs®õåæz=кuÄêYÕM"ûÿ‚mÄd¬Ïof®ÑØo”º­£x¿`Hü9ÀÕ»}0t»‘:[ým\w©íÝ\ÕwÞhv^ö0¶Ž&ð~Z§q”ñÑùòð¡å ˽(6òBq ¤<½¾ÄAtC#|„9j†G3f©7h¤1ÅÉC²ÐWYa;¢_¨¼´iÇ\E¨ŸÊ’ˆ • ºÐ“Ù`x_YÀ‹§Ÿ¶êÇßÈ A`ä Îéx‹o^Ó Vï=Ø 7¥îN§d>CeJ]¯w\ìkÚ5 ûú€¯øU¾‘µu/š+JÇÂXÛÕN´²§9}VÕ Ÿ%]c%äïÆBÕºØ8ÁÎ|pÔ1jæ´Ú kMs' ÿ2× /-'qUÈ. Y–%o¤#ƸqÝx¦ïU cûðu®™ûäLGèVQ©; ¶Ënϙ𖞘ä|ަÜ7äYTÐ@ðF)c[²`´Ä˜ÚSýÅœRF~&LEÆ6›fÍû üÖN°„»A»ZábqÖu\Ä‘sup¼‰åZOCk7o×I«yãíR[1»ðf“nÐÙ¯øéÚÈ·ˆ·‚^NcWª®9ËÖäÎØ1o9ëGH8¶âÙÑÀž­Çû”3<‚݃·“%Ò¥›Ô€±¿˜QaŒeî±J.8¶¦Yç\ᙹîq†-&1w½z¶öÃC³il¡sîEB×Áì?/ºùãƒ%­A¾mb8¦ørtz$¬é¼ÈùG`ÕxⶆKCËÄ8oÄ/ÙLKCæÖÍ4PO‚q‚Äê¦Ô*á<§¾GíØ}˜cLFª ²¶•Üksb[uMÀFà%yÏl%d²‰~=½ eª§uãÎ 8hªÓ€ï;FYm«¶e.ŽQ¶ël#EÂT§M\Š2ÔÄZgy¹f•‘¦ƒ¦I"ŠcÚˆÄÔT ÄšF,—è¡lÑ,)LXL”*7¬í6š § ÝnâÒe1HгbAqÊ„m^ߪ„Ò„w˜ré&Ô, ,<¥Ó䱨v5B¥oæ$ìèš©ôTç§ /꙽g‰©±xËÚ´—V•s‹æ‘ý (xUvDŽò´o+&®¡a'2gÕPŠDJýŠœ¯Bø.wdUúÔ¯z9Í+F+zõ ÅÆÇGaÇç~D®.7׫‚þµ¶ÖÎ~¢Ñ¿cÊì|6LY”b'°¦Tªßë=rtavA+Åy[‹­ðb´56FÃÜ~§ý‹Ò8¼Wp®­‘a³ÌŸ*:­H•%ZQæÚB0+ HÛ%RÞÆhŽ‘ZÆÿœ—J5’=Fð…ÀÈÏ «'Ó «ÛFå³GææPã?¦;øo.vÊ$娔Ý5¾Ó´*;`A¸N亀€Ã&²bp_årä> Ú{(x¡‘È‘®Ý‚ך·î© ¦²Ë öX“pu>°U;‡Rdqa)ϳ$ÒË,@ÁE‘+%¤ÓisW¥v.@ŒQŽœXa ‡e‡jLÐÙS˜Þ ›]"¸2Ǽés#Ø+/dr\ÌÍp±Z·Ä)ìefØuáNÆû ÁÊõrÒ6âð2àEPµx¶Ø0òd÷áá#óQ4шâIA¦d>¯XÒ³0ñÁ"g: WÆégíZ2Ü܇àÕJ ­GŒ÷Z¯‰ÕÔ"W+« ˆq¥óÊ—S_‘@Zd®×ÂÏàyáì'°}S¥ÇN¸ÕÒœ!y†“BàR"ì@«™XÕŽãt||¼T¤˜]”¦šú6Ø2 4ªg‘ÑnÀÚÉ_Ê0ÊÚØÁ0'ØCÝUF¹^ŒO5®åxª›–Y)]ù«ÏÞ¼~ýÌùçn…Å‚¢×3>¥¶ ÎX)sfÊBœxFÖÚ\{ÓC_þÖ8±½ë-/{ÿ».8Õÿ”NòB~ì²oïÿûþÎõkÆü <ß’äÙ‚3ºe]{ºi©²~fJWðí$U 5 ÑJ,#|ÂV…c¯[ã¨먚ÏL5¾Aë„l²,¬UFrØlf]£!•«'q™Ï>ÍÚKf6z_RyÔYrÌÃ4d|¢=>ÞÆê­»³Ó““ññ±8Þ×¾I®VíHœZa\)–‘£­k“@±‹mÚ&qÇ _'ý¯[؈ÓNÊççûŠ0סL€›­ÿÎ(Yaw‰’‘`ŸŒÂZJ_ßpä?—îæ›ï|ì¹~q@Ç¿öÿf©—ŸêA§Réo^sßÜÂàTïHÀ³BÐÈÏ„mÙÐégja®ÿ¤àͨÑmrЮiŒkn„T>m£‰ ®¬ÁöKhgAiGÞl¤Já³8]m]Zkíy\Me¸BcQT3·­Úé܈#b„Zidr¬j Ï|lÏáÛïÚõÐ#¶nYýºWqæ¶µ«¦[.­ú—cØÏ»«™³{î{⊫î|ÙÙ[V¯ÛyÏcï}×…/ݶE­²ñ×ß™_ìÿÂϾ%ËŠk¿{÷ôTó½ï¼ØpœéX¯ºvç£=Å#þ¶·^ðæ×l“E™+³ã¡ýß¹n'ºsꎻ¹øužQH,]äòÿ}í¶÷ïe”žÎÆŸy÷…¥’i‚ÿ{ƒüÓ_¼õÞ÷¿ê‚-眵þö»ÿé‡ß§ ã}âªÕÓm[0ä—½èG¸Îß÷ðË>yÝC»Â)!q_êU±Ü°µ›î| 621Öüìw̬êþÒϾ֧j¦¾âª»¯¾[.yãÙï}ûyœ38|òs7¿ú§Ãó‹RýÌO]ðïÜ;?óS¯eqý@ÀÖþö«w|÷ÖGà#Œ¶÷û ¾î¢­ðÖ×lèCï»øÂsO½Äïˆú ^¶ñÃxu§…«û.üÞeWNO´_}áé ù7¬›ø•½^î_µ{ïÑË.¿^)óö7 ÿ»Ÿ4‰~㟿ãÆÛwõúù'>uýãOý¥Ÿ{íË^²Î¿d©ŸßxÛ£´ÿŠoß}÷ýOþü¥%±Æ¹î¦‡[Ídróñ€Ç7®›|æ/ ®ÙwÜ·ï©C‹RêÓ6LÁ=›ÖM áÆÝ÷ïûìWï¼ÿ‘×ßüðõÁ#K/Ùºfµ[€óÁwoyäÌ­33ÓÈ•ð-}æº}æ¿ðõïwä¥üÒ7îº}çž÷ïûÒ7w óò ¯<ãö(㎻÷œ±·ì³~í„ß¿ÁÇž8rèhoq)»ñÖG/yÓ9 þc"_ýöN؇4ŦÈ]îŠ _Žd ¬úõ«ïùü׿Wbð6¹ùŽÇ€¹~ú’— ÁYúW¿óYàÄV3†û?{Ågm]sžû¤ðä¿úü­pôö?µoúé/ÜòŽ7Ÿ3ÞmÂC{öýôo;2ׇSË—¿¹cnqà?‹?87ݱ a®þì¯o<û̵[ÝìØÇ?y]·.ö2xáç¿ö½N;}Û0Ïå?þÏ/Ï/RA•Ã>À zæ/hù¡¾þ–G¦'ÛË|º[¾÷8|´¹ùA£ŸãN$wìÜó›ÿýKpÉ5ÌÊAVÀé¡ÝÂèþ¨÷úIAÐÈÏ À_«&âù©ôÀ‘¬ßÏgbm—Ê Ý⋳šÔÓØˆŒü(k“ûQ±á‘¥Àvôº<„T‹~Ä=d&àùnb×ÁÆ¢j2Å7xŒ|3ˆ÷¨sñ8©Õé4à×~ÇÝ{_ºm­ï¾ð{‚ÝÒè½iµVœñ‹.8ã§Þ~ñç¾|ã¿ÿ—Üvúšßþ¯ŸÚ~ۃ眹¦)â¿ÿ×Þ¾c×ê鱟ß»fVi¼(0 w{ƒb÷Þÿñë—vÇZq]sí-ŸþüMÿæW/å1{ÓÎyë΋òLÿ‡ÿúßÑìÓF¶ßþçU'œg>÷µ;/¼ðÌÍ3]{Á/ó_ýß_ߨíG;tøèR»™À'¥ö­ëî{ýÅÛ~ñg_ó,¿¬Më'?öÛüÔçoÙ~Ç®?ý½¸ü!Š í}ô#8cËê‘ßp ü’ÿ·ßz?ˆSøúù?ßx×[ν ‚ú+Wîüøÿ…?ù«®úîsÙ?ùägo†ÓÆ3ì€ßì0üŒó7_¾ýõ¯ÜÙo>øúwï™oý³ßü4pÓ{.y9|êÏíNá~ Œ1 ×Ÿ}ÏE ÍA‚à}ðѧ~çß¼gÃÚ , A ?ÂW^wßôTûSøAäU™nÙ4½|OÞ÷Î .}ÇyGçúïÿÇ—4öw a—ž:¼ú7°öòƒ³~fü#ÿêÝøã¿üK8«ÁÁ°„ó{ùÀ^u|„í·ïúÄå×Ã.ÁŽÝpë#·~ïqï~ î>g/ØÎ<8Ë5|Òåç÷ÿôê_ûå7Ã{wUç~ì_üíM¿øÁWÿòÏ¿ööêÓ_¸ÍïÀÉùõ? uä猱ŸC_YÊCs¥4¤R7-\gG­Ä߈gÆîZY¼â'ø«WY[ d22¦¨9ÚÛÞ[gdá¤5_{*yÒû;¸ï‹WÜñŸ?úÅÝOà¯Þ<—'èMF_;ÅiÐAÖ õùap2³z˜ˆsë–5Oì=Gœ1ψcñ®K.šžî:qUfÂü^-. à9X¶ùÖS{÷σŠÇÄkgM¯•AfÜ1Ì3TØÍúƒ|¬ÛðŠ¾ÕˆÏܺ¦,°äjœ¯UáWˆìͯ}Éóç>æg¸ˆ,‡ðKžrDg ÍúCŒØö?ëÅ‘ë4ÖÎŒuZ)ÜxæíÃÖ@D.·7o˜zò©ùa&GO€‡¦&ÚðÖ°@IpœDç—†^à ™Ï}éú¬Ž'˜1˜â¡#èèÈ|ï޽眹Î×àïKÞxö¶ÍÇ‚_á»Øºy•Ë펢¸a^V_»ý!­ œàǧí<øRá샿ޏ|ñï»mó*8—T[;Úë´“Ñ2À¹/Ý ~TÌ÷jàñåç•lyã«Ïô_â…ïb÷¾£œ»ÉÿØn'qòBÓ”/´Ïsr0ÙM§'doLG–r;Õ¤‰[+cuùØ·9xêÓ#‹NŠz¹*×õbÁªLUüÏÕ¡YíIojR®C<£Ñ;3’Ôõ-Z;|z¾óÞ'.yËËë_¿·ÕŠwï>ôäþ9oñì»8ü»3‹“rYdmqe Ûª 0ìS‡æ›ðª'½þâ3Ae[ih-ÃÑQÈyØSŽº}ÍÌäx·õä¹3¶ÎhÙ¿uÇÞ—žuZ»™:7; Ÿ"޹+×`o²2jÕTã§/9oÓ†é‹^¾y|¼!(=ºû4'KõÈã‡Î;uhd¡ï{çùIÍ#œX;ppáËWî¸ø¼ÍðK{b¿YŠSã­ënzèÝo;.2xä)ŠÑñ†MÁÖVOuvÞ·÷õ¯:£,Õ5Û:ÿœ­æ±º3\¸Àå#à#¿÷í$¾÷íçmÙ8ýÊó·LŒ7ŸåÙ„$\æÿÂû_ üçÈk¶?ø’­kÎ=ký3¼´öìüàïÃgŸ±´óÇ>ñí…¥ì™ßŽÒ°åRªïÞúèáÙžèçnþÁŸ¾ä*Hïïí÷î}â[×Þ÷«¿ø&ØÃv¨áÛ\~p¾pµðš:ÿl ÞµûÈâÒ Í%Ô‘pŠ.J;ßË@€rl7jœ´*8°ºjá,+ˆõI{U×pM©Ü%wàd¶Ëôóôí¹Ø;ÌÁ3ÓˆÄn6dXV^ ¤N ¡u1šVŒYÍ´šÉ§þö†í·>|ý:¼xèÈâ]÷ìÙºefㆪüê-&{ªßÏ]Ê(aúðcOÎÍõ^øì—nêýùK_½vMg0,þàÏ®ºëžÝûÌÞq×£wܵëô-3ívKpÞŒEQÊ?¹üª[nàÊë<:7üGÿà’ɉv) miˆ3ÐÈW^³sýšIø½ÅÈì̪±?øÓ«/ûËkoºýÑ«¿{ÿ]÷í{åù›Æ;•úûèÇ¿ýÍkñ·/“{K½üO?}Ãm;vü“×l¼ôçûçÿ0™íýï?ûΗ¿µã¡]w>°ïkWß37?ðuäË?wóg¿z磻Ãå9Ü4á«Ò@ý ?úñ+¿~õ½Ÿú­wìÜ Wî§m˜ºùÎÇà"¶”, —ÛþÆÞsï¹ä¼¶°µ5«º¿ûû_ûÆÕ÷ÀÖv=qä·~ý«¦:þÑ»xØ Î1ÿçϾ_å¯ý£·øÏÌt÷ýñUðç×ÜxÛ£W^?<íl§÷\øÏ¿ÿõ»îÝ;ÌÊë'ÿÇ~Ëß~ÍE[Abï¼ïþùµ×ßüðe—_¿ïÀÜß}a»•ä…üè] BÎa µ?qùõþ6pßæÓ7ÜòÈ埻^róK©·ß¾ >ŸÑÁ9ãôxþè6èY88p®»ùáÏ]q'\qû¿ûï ;<1Ö|äñÃùè—¿råÎn{ôÛ×?à…ÿèPÀ÷¿þøê·¾î,xßÑÁY~¨ïº÷‰ûÏ.ñgt´Ÿö­Á6Ï<}擟»ùkWÝóÅoÞÕä{÷Ïù8Õ”pÂë‡f‹ÍQ&6l˜Ú<Ãb^õÿÖ9FŽëé OÍ^DuÍ@{{ 7¼gle)E•¸ö=J¡ Ï ™h‘É””šÌ±”\ÍFûê³wïU÷…gj*bw=~ðÞû÷ž¶iúÂóO»ëî'vï9üªWlÝrÚjRÜàž'ÃaAg,†M\ñ­ÛvÜûø¯þÊ»ïØùð眶nºsÖ¶ñóÙg¾r[?£îÓ(ÁØÅž9>ÖáÛ×ã;ï~ñÖÓ×­Ÿ™‚ëÜ~Ög€7ï{hÿ÷_àþ/¿q)ˆÇ·¾þ¬Më-TÓÁ' xÕ/ÛôÒ3ÖÀÁ;áÔ91Þzõ+¶|çÆýíw½õe P´Þòˆ?8¯å~¥KiŸ_DÛ^zë]»ýíw¾åeÀ¡p|¶ßþè`X¾ñUg»ù;9:8pXàŽnûCçkWÝ}ÖkAÿÖûâ§ÿèŸlÞ8µü‹#®¼3Ú NxáÛßtöÓ¾µï?ÔËöÓ¾µÑ¦€÷ÍÏÚ¶æ_|ä3òÑÃÁIýå>ù81ÈÌ=..ͪéöæµb¢U]Øæ5󊚈G«nšTN@ÒñµvþAÖÙcRgoo)ñ86mª éþ_8Œœ~Iú…k¡‹œ{œq–ž®8ÂjGPe2rþ¬œÛF…SM Û_X4‡Ì+eq`ƒ'wß¿ç²?ÿúì|ï—>ô÷>ðþ×e½A*è¶-Ýý{‡ç2Â@¿HØ5Ú÷•p ¦ÖäÝv2=5þÄ%ø$I$¤* £Ûoypû-D‚ë úÙúÍŸ{ŹëqüÏXƒ½Û,—*¤?…4V·NõWzR4ô‘~øî7~õíϼ¶¢tñ¥oíøöõ÷Ã5ÊÜÂðC—^üá¼ê$Ç ÜyÏñ™íE©öì›}ókÎüÍ_gü N|á|’“Œ8¢­?ZzÒŠÁ ©Œ=½«‘ñu;R<#ƒ!Ù`^*­4¥ØL‡Õ‡ª›ÙZ‘ÎiÑÏ';ñÄXrx¾—xš›47G“7PÙBpš$tr¬9·8è t·Û1J8ë‚ç‚4bÔ±ñö­Ìe»)œ1Ãñ¼+ÎêžhéßÛÅ©Jx#5ì§R4Nh‰ÁQ îE,ØÑùl²?ë#ð¢@`äãG)ᜦ‰ËvD«\Q¸Î!­*·#Nôðí¤–Æ®i ©™/++øö ‘´ÈÊiV`9Á+u¬t]vnpžmí¨ŽÌªˆwLö9~ð|‰äHâDÄIª8œN,ŒÀgÑJbsÅ‘D±*d«û D‘¥ÖäÙpÃÚé2,õ†­îÄp0( 7ˆaz–¹dŒÎãÌG W‹ëXÓp]"@Ъ?,;­$>^¿ˆ€€*#? ©³ÂD‚¶›è0©\a!r]À®¹‚æn@.ª-/FhuOı„¶¸G—‘}•ÃÕ†]#sD¢ˆÆiF¤•ZP±Ž ÅãÈF0yY`þS»aEºn¤bóÆUK s‹ƒ¤ÝÍ‹"Ï>™qȾ|¬‹A¨F»b±‘žº‘ˆ¼´ £mGs‹jÍT¨ <¡Ž|œÐÚr“&ü´u©ŸøÈ]>ˆŠSÎÝ‚:Þ4N;ûõ9ƒyÌtùhµYvVôU `d à8%“hWI2…C"h½ìÝ|c†ŸþðÚÛ'øÙQ¶­ì2|.!º.c]‡’ø¢ò/·ÞÜÞº)BmÂ4VÃá ìY¶8²¸˜VO­šhíÝw¸´N+4¡“ÀÈ UíRŸÈÒ—º\³j‚™Õt<ªW‘Ëš1ª^¿ìfH3!ciån‘a_DeLá+Ê­Ñù,O¾Þà· «>BªfäÊþMTOóš»Û±ÀÙ$ý[†ëÁiëÜŽ°§8‰ne’RYÊù¥‚§,:.”ÄÞeK½àWU^ óU²LSr»Õj”¥ÆENŠýª4q$£Zá,uš„½€€ŒÀÈǃRšBš±NìK¹´hFÝL›>6*MFmgËþZq´p>Od™å0²`d¬YõÉ ÜŸñ¡|~ÑÏ 5lŒc¼Ê«Öµ»vËñÊ:™±ê$ IÝ€a«ÞdâHÙ/º¾4\.d Y˜ã½¦Ì‡Ìä­”uÿ÷JADËXÛ_*Ê'[ÐgËÅ臵 쬀“è|¬;ívY*Ñ8Žòb` UÚ¤)[\,zY¹au0 ø¡U‹ãUÐÅÝv"*Þ,§Ãœ¬ž¦@ £ª±Ï¥6µ¶#׋eËz¾ê`œU›,QÉ6blg ½³è¬7|í[&ledQÏL“ÊÃG:Q±jGšÜq: âÊÇÌ/ŹõFEd”ʤx& Õ¼,‡ÜèUS“"Ž»Dýa®¤y+µ¡Nxã_næZðØR­1*Pr”É6‰ã,Ë8§i­à¹Àâ4d&ÍÆP¯xF|çq)µ2¾N¢™ذmM ¼6À¨ÅÜjÇ”ËáÐ4[Q§-õúenX$'ÆŽd­„MS¡€€ÀÈǃ¼4T`ß× ·Ã‚*%Ñ4˜såRJ¥;¨£êÄÈìÍå9»ò±Ÿ¢¶D¹¤; »©.éÄÕj^¡pØ9Ô`—1ñNó8ðF¹¯{ªMú$'[;<@íR__®£Füƒ°ŸXAÆ’·L ðþ\ôeY”Rš4à%‹óÃ(އ…sªÀ¦8ƒ&ÌnZN,.XV¨áínT–K¶h$ ïÆÆÚ……¼ÙNZÍdn!˜Ý8Ó<Õ_Z@ÀO#?g(mµ±iŒ®•‹ÉrÛmGq‚Gè±dS{oÒeEdïú¦\W²rä‹& ™=M•-4µµq=®àÕ¦žÕ}´*YÚI™²jlšø·ãÕø¶’hEœDØî ü þmq´ÏRm|Å“ÊÛ…á”bŒ-€‘K31žtÊETö–Uµi¼(p•íqviË–²gLCDl¬K©çæ†ÍV,8ÍŠRk³ymû$G±ü„"0òs Ð`ÌÑ¥¾(ÑóW+ Ùº•7Ìsb#‘z,god*t, ) ¶0ƒ2MiEX,Ž”èxdžiHÕ‰lm­vYU2™Ð»ä:á\ù]xC ÌìˆàÛ¥1¶F —¥umÇØPQù/›÷M)•ˆDÌh>ö—úR±N7ÕJFÆ¡ý³ÏÌ'lkªÑ¼BFâ"¤šmçV¡S8Íf\*5ä"†·ÓTô‡jãêV$ÂrE@À³B`äç ¥|3:QŽ‘t9‰£ÚxÞh=ý¡—Jg$(k|B§IZ¸dNÒMK»„'ålÌ+¦¦ušx»úÚÞ¨P–8½ŒÎóÌg'¡=`ÂèÈyN"¡c¿Zœpxœ ÊÒhC¥2%jX¬_(c†Ã¡¶œÇ(â­æ­ÉÖ‘Ù%YJ wQ´}Óp6†}ìU»c‹Œ3,O[ͤÑ`ƒA¡”2š®™n- ËuSͰšðìù9C¤¿8ây©}‰‚qG•’%Ž…#_ãk¾ä˜=q-hÆ…O'i¸¹>ié8ZÖgãú…]£…®Ãô˜ m*õ±‘âzŠYoŠóøÇÒÊéÍœUݾآØÐBZ4ª—¹¸T²,ö«%"æül¹&FØ’>9ÙÉòr°4<é¯á$¡ËÈ þ¤üDt·eKÌB°4aŰȲ¢,Ùª©d®—¯j¶šáX@Às@ø…9DJÓ6\Ô½ÕXD¦> ÄÔEdã;ZµWbxòc»M:>87wT‹¨é›ø°>RYÑe&ô¬.<-1Kª2M‘*ÑæX/ë“Ã4Ò‹ºh.šÙ ‘F’!' öó×)“ÆèÉ©1xËÁâ¢%¼ÀõD4M,âØVÕ‹4æ­V{i11jrÎx§X­–úyV°±n4ÌÕÌDc¼ìž#Aò\»RWX)À54Î*ÛM_8ƦãeqJÚ¹¸•›—£û޹»³§qIÐ[{§Má–æ¼õ„o_³®MñcsÆY[¸Ó€ODÅ (œøů,%fB»¾7äbìP.U 6A½åœ*â(Iàèa–++Ì™2ÓÓãÖò¥ù>å¢4 Ð`>VÆÜRJÇÛ-¥Š……ˆ|,µm·0fzaiDÜj¦ æW§“c!a: à9#0òñ ‘™[)mY€¨¤ó¹JãxjÂ%çq×êKÐY/›ÖS¶²­HbÒŽIìÔq/Gd!p®„»=^Þq«ò±5u‹…Ï ñÔﯕ®Ì‘%2²V ØØxß Ì©¦Hœï…UŽú1éŽG4m$–ÙA¿”®¡Û(Nq Úhl\Ûw`V*“¦ ¨fæ¬+àÍ';­,HÃxÌ#.Œ-»cífLææ³Ky»Ý`ÜL¶Ò©@ÇÇ…°~´‰±jèÛºaFŒšÚ—5Š’f9¶|ÀÉ@JƒA¬3¤á© ãí¬3ŸÀ 3è»E>z¶ÛN›ic8ÀìRt«°§’¥éÎÌÌÍ/ "þd…dc«ÚÃ^ovn`8XÌŒæ ‘ÍòƒGãc(ŠN[Ýh¤á_T@Àñ#üþ'bÁr©:MÒhÐy^,.#7HÝq!}»…¦XLpä›DÕ˜56ÀY¬ZR™Ð‹¨rqƒ‡+_c×D¬ÜŠŸÏþ€ûŽ]ßvà)I=Ì0/†ŸZgÿéÝ4Æ [?ÌG]0r‰ÊTðȲA¿f œÑÖFd%lb¼Ûïeífs¡7_j2Ñj%†ÊÞb_ëÈr è>RÔàí–hÄâБþüâpõtÎ[×µY–øñù8‘&¼T¤Ý$qT*mÓ4^\Rûæ§oH YÕ†™s£—X²HX#掩—†¸ÅÎ÷ÇYhú•@o¡é;+Œ©Æó0:Ïå0I7ýœFN€уè¶ñ¸u]vØE¡ ªdüçÅÒe³¦Ì*ÆtšÄfGj²8XÂÓ…Õ%·Ip D€Vžœ?<;zToÜL—úÒZ†Qz1ÎrjâF<Ñåi=uxinnizº zÚš@Ç'‘ÝgœõÆâC³ Š’O@Å›6$ÊÕ…•AÍÓ’ 1,bh3T”¶ÈÕpÈ’„sgŸÄN#›c¦ntÔ³Áª† oÔ»GV’"'ƒLç¥*•½l´o„s©I#ãæ´ÖÜY»ˆMâf«Ù„óGoÐgV»i@fqÀDh#Û‘˜oõû‹¦H˜9²¨æ3.âˆ1c$œ¢$Ic19†›Ü½ïˆRjfÍÄT; B' ‘,ÄÜ®N¥öKkrñó’óh¬ËüÄs^¢ñE#±Ígó2¡R1m)HinAAÛùÙhØN+ŽÚM€fý+]«\Õƒì½ß(vÎÁCEa‡…b‡›£c1‚‹s×[áKÎ$-ó#ÕJ›f#i6pfd™’Ò•8°ÏÓºŒ91j˜—ÑX§qôÈÒ|_eZ¥q×û´d N¼ t<³òБÅN«!ZÓ×¶1 * à!0ò@v3cñMeQ¦†ÝÍ-Œ7 T»E¡Ëܶò¶ívß\å³YQŽH²·˜ãT´´Iq š&QÌ#Å1:†?¾î,Ñ,ß9T¸å>kjÿeK…K-E‰¬ñ¸Jˆ¥¬2·i«U÷³2ËJŽõWA&JkŨ™šŸžìY¿§z¹Q”Æ áà!Æ¢4æãcIšòáPï?0;99ÖJÅÆ™V° 8±Œü㢙 ²~ß.”Üh§¸ö••ŠqáêZ*;’~ä M{åb[5vBà<µ VíÅ]\¾‹"Ak7REL;7"Y癕'¥.K×Ua*ã!üËÀöª»,Nß¹'ƒFÍ­fÚî¤ZÛÅŬ,K7È¢ U@§­V«Ûn•E~tn‘;1Ö–Z)e0” ÑH pq‹#G{<¢cV7;ÞZ? à„"0ò @»!6Ì$–³sRTÜL4´%*ÔYÚ`$i'$oòA¦¥–”pt&J1!%-e ¬×hD ‹Ñ„“U .Ž8¹ÍŽ_ç™URãTž2þHí#SVÅ©èj"Å;d`(KÓÔ1HïÅ…Q’3“Ä*7gÇ82¢#ž$,IAõRÁ0Ï)/,0к›ÓÃf ¥ÛØbàS9”«iàì5uîùŒÁkÑ÷;8ˆ4ÞS¿nãšêÆÇ; Ï­ÑÓãÉD7baÞ# àT#0òIƒ•Ê™/æ{r~I2fµ1͘u[ siàQ °³†p´f”¡?2ÇÅ>dam² ¨€±ËQÃße)ó"£nfÕµÆdw œ"عìà˜Kç¤Iƒ>تñtõdB¬F>Ù0¦¢æ…^1;ŸbšiÜHãV ‡¦ó\»H¬7ÀŸH`XFùá`4ð²¢®| I)ËBEé--.áQøÛÅŽ å±ÁlÓ$)Ýj5Az f'»Q§óàG°òù”Áù“aìœÏ-½òm5£F­ ·4‡&öuaƒø(Uÿ'¶ º£ë¦q©ªF!‰£·¶¸%ö:cj)¥–kFãÝ8ÔˆV8#¯ Í¶Kµ°T²}ˆ@™u¥aZ}S.÷ɺDS¼ß8à '¨ñÿ(ç,â´‘°±N B8Ìb"øÉ@`ä çRd±²ì¨Wâ¢zn¢=¦ÅÙ<΀|‘pǹ°.ð@`䀀€€•‚`°R9 `¥ 0r@@@ÀJA`䀀€€•‚ÀÈ+‘V #¬FX)Œ°R9 `¥ 0r@@@ÀJA`䀀€€•‚ÀÈ+‘V #¬FX)Œ°R9 `¥ 0r@@@ÀJA`䀀€€•‚ÀÈ+‘V #¬FX)Œ°R9 `¥ 0r@@@ÀJA`䀀€€•‚ÀÈ+‘V #¬FX)Œ°Rðÿãz߉Âʼn=IEND®B`‚openchange-2.0/mapiproxy/documentation/pictures/mapiproxy_emsmdb_graph.png000066400000000000000000001170411223057412600274750ustar00rootroot00000000000000‰PNG  IHDRÏ6ù"òsBIT|dˆ pHYs × ×B(›xtEXtSoftwarewww.inkscape.org›î< IDATxœìw˜UõÇ?ß¡w²PzPŠ`AAP ÒDAP°ó£ XD@PD@ª(]:H—zMBhi$”ÐB(9¿?Ι¼³³ï»»Iv“Ýä|žgž÷{ïܹ3o¹gN»23$ílô.6³Oh'’––Þ0³—Kå‹[›Ùóíí¯•ól œ §ð< ¨¥ÔÿõÔÔò»E}1O~õ/Åù¬t Åïè‘øÁM[¶óÝÇÿ6öˆýJm.‹²Óq¿…âw[);Qšß¢là7ÀyqO‡?ÞÝê ä3qq½KþH©~º€ûmú ›R³ß÷ú}£l8.¾ûŸ+})¦OàÔ„ÂÞr3!9µqc¥öçó×RùàRÿ+DÙî±?6ö‹ýÃb¿Wéƒß²Ô×w€“ãæîH9Çx¹uÝš€pSìÿ0ö'ÇïaPì¿_:f]|âÿðßÒ÷wñ¨/„b¿ÐšMÅ'åFÂÇÀ¢QVü¡ÞûÅÛ¥q,Q:÷ÚQ¶[ì/µû"þ§Y\×Ê¥ºŸGùIñûþÿ#î1§?›Üfûo¡‘Âþ¥6Åsñ}Ú½TW<|~¯TÖ#^‹ïóˆø]-ûï½£p¡w_|>+þã—úB@øuìûçÆþ¿cÿìØ_¦t _¤ùd½'ð9jðKÛqŠk¸ÚüYÌ»•Ú^ô‰›ŠsÄBë0šÖaIj½†Ïïôž>EK>…?µ7 \X(¼!W­sL[QÂÿ¨ÀÕüE]1èryÙ?¡U1 ¿ Ï†‘´po´; øI©ú¥Ò9ÆëÊñúB嵨_¡4þ¢3;ßÌÂmDë…÷l’´ÅSñúz¼Ž4÷4.¢`æ´4!s"þ»|²ÔÇ•>ÇÄëøxí]§M™wñ§‡ò1‹VÚÜQz_ö [9n‘RÝ(\ðšPª;wžú°þç}žÕñ²Næ†âß÷b;»Tw!@âÿÝ—HZ’Úwõ΢qïÑ]Qöfì/ô §€gpÀWKÇ,^é£è¿ècéxí¯#âÜðä‚¥÷ÿÄKÄþ  ©·¤ ÃqÝföAT¿R97¸ÓbQ÷*>¯–Ûõã,"Íl’™õÅç¶Ë¿ôÀÿhö—´zi@M¸â÷Qô>9¯&é+Q^u¯HÚFR½ ~˜ˆÿQýFÒf¸´nS1j7ÿI›GÆþk¾1Ø ®nä)©?þ‡º&®Vz!®÷I‹Å¾,š.i;àÛ±aåuICpµ.øÓÔ«’6–tp¼nDÍIj_¢$ijHq£ r7üOó3û6î˜Ôˆo†ÃcáŒô¢™½ÓJûE€í%-leOVÚL)½«yöŒsíûOƒ;%âOV ÷㧘ÙëQ¿5sɹ­Œ1™û13û ´•¿Å'¸7ñ ÷Ø8`5ázÛ¢±¤^•¾‹ï¯UÊ¿Ž;ë?bfýqÿ†Ô§Q#ãõ ጻÍ…‹Ñ¥ã>ϡŶu´(îûð-ÜOi3{·Ôä¡x].…ûP x0æ·âácÝxÝ ¨s,Ytff¯àÀÚ…Jâpüæþ W%¾† *©-.§¹}}4ÍM âÚˆ¢ÍYQ^uRÜ––NV÷aÀŠÔì˜Åö ¶A%ÌWÕLÃ7«£–Ù¨ÒWy[+Ú ž¨Ô]FsÕÓß*õ£KǵNß¿šÓj»ÜºöFÍÄpBì*úb`ñŠýUpaâcÜité;7 Ú&†Whî¼Ô721¼›ŠcÞÖŒ6…‰á°Êø¿CMûW„O¶Šú¨©;{Q³ý~§ÔÇú¥1Þ1§?“ÜæØo¡01LõÃÅöߨß:êFM¸À4Â_÷º/Ž¿Ÿ³þuÍÂñ(´â;·þi¸íOøT|¯×‹c C1æñëc=jNÁããwTü „3bðGà/¸Öâw îIáWaø¼<>¶²¹¿˜›'Q›ƒ‡S3ìRº/Äû€OGýi¸cåx¸dÊnO3;AÒ¿p§„žÀ1f6Šf¶s¨ËઑÕðÐÀ§¢þ]`P„.GMåø5üá¥hw“¤Uq„%ãC~Àb¤fö¢¤õñ?­¸Ä½fV¨( SÁÛÑþ"IÃð§ŸBíRf$M££—B[ñi"Q’™=Rºv~ 鯸ö. ’Ü ¸T¶:®²šˆÛ„Æ“$­s>)š€§ñ'é"YÉ[Ô4V˜Ù(Iã¶ØpGÝB W˜ ¾Žû­€ÿÉ^åOFŸ/TÚ¿ÇìƒÿfÏ5³aQ÷ü÷roù3;_Ò“ÀÎøïþ%à3aïãÎO6³$}ZJR3›ffKŠÿþÎiã~%s//á*ô*ÃB°/î û 3#iO\›½¯¤;ÌìIãqgÙñ§÷BõBôý\ìO+ë#3&éûøwÿ3øÄü=üÁ·øŸ¿7'¿³qÑÇ“föDh²ýŸG1€OÞàæíáøï¥ˆè{ ¸¦Á=y¹Á=y­ô~Üx\»øàçV3\šï+áÑÇ›Y¡)¸מ¬? ?Œ;yþ¹ðÎL’d.AÒ{¸ ºŠ™U…€zí7Ç”Qf63¾E3M˜"7ߤÆëX;š$Ý I‡á“ý|À~¸Vc<0ÐÜŸ¯[ѳí&I’$Æ>¸‰ó9`¿’nÎqÔ|÷À5{wGájñI’$³0Côµù㓤;!_Ï`=\Õÿ2ð”™}ÜúQ]—’$I’$iA£0Ž$I’$IæaR@H’$I’¤) $I’$IÒ‚’$I’$iA I’$I’´ „$I’$IZB’$I’$-貂¤ë%1§Ç‘$I’$ó"]9ÕòøBI’$I’Ìfº¬!I’Ù‡¤…%}FÒÂsz,I27#i=IÏéq´‡’$_êýþxM’¤óXØmN¢=¤€$I’$³¤9=¶H!I’$I’¤€$I’$³b å.¯AèÊQ ³ I€c€Wc¼f¹v’$IÒñty!5ΚÀuïÿž¶kë@I};whI’$É\D·yèL ‚ÓVÅ5Ã?HºJR~©‘H’$Iº) 8MÀç%= é I–´WQ)é4`$p,ðoIçFÕ`¬™½mfO™ÙÀ§¨™*ÚDR/I¿’ô:ð"0VÒm’6é¸ËK’$IºÝFƒ&gpp1.,4ŸHÚø.°’™²åKÇ)wdfïI:ü5Úï ìÌ\œbfÓâ?_¶4³g$õvN¶è”«M’$I’6HÁi.7³GG+u_þUföJé¸z¦‰w€…$ NŽFú‡HZ ø °®™=}O.•tc¹Ã0Y|\,’$I’îG·Ñ ¤‰ÁiÍa`R+Ç©S¾"0.Þÿ8ÇÌÎ6³Û€C©™>¼`fOU;0³w$ –ô ð&0FÒEIËIúŠ¤Þ’Ö‘´`k™$I’tº¼€0ÏkB¥¿$p”¤oâþà!3{ w<ܲÁáMÀã•þúâᑎ¢u€ß”š<,$i~<'÷è6†x)pðE`uàJIÏ™ÙåÀ¦ÀIÀëÀ`eI?6³«c,?Žë[¸ I{Hú¡¤Q7è-iYIËÄÄy9ð>pN´yŸœ 6&šÙÜѯÑÀ$­ ¬gfï˜ÙCÀ-À×£I° °½™mŒk, vÃ}+vÖ†KZ¹Ôÿ§%]*éNI'JZ¤ÎTΫýÝô*5Ûø@ÒIHºFÒé’5º¶$I’yœÔ Ì*’v¾¼\Ù^ƘÙdzÒØô§¢ (ÕO”ôi`gà3ÀÛÀ䨊OÖûÅþàZ`?3{7Ê®ö‘t Ð÷9¸4ênN”´¢™½Xçô+àQãJec5â}àßf61öŸÆŠ‚&àl3;@ÒÒ¸ÖáIë·â¾?Œñlm·Ns½%é3ûi´Ÿ|ZÒ+xäÅ`ð¥8ç€Ø>¨sMI’$ó2ÝFƒÐå\%'>Y~Ø5Þ/L“4––ÂC!@¼lfoÍêÌl2ž]±Zþív~8þÿLŒùŠ(ÃÌFFå-’~‚ ‹ßÄ5€’ú™Ù{ÑßWÿÄû&à‰Ò¹Æó2+…-\Pª¬ïÂ#*þafS$=L–´:ðFœã÷ÀY¸@°¤ùpÍÁdà[¸fd·Ç+!ÈŒÃÍÄ8–z—<“$Iæaº“b—¯…_8ä­ Œ×bûL¼zJz‡ÂCl³¬…hcüïß–Ô ø¤…`fJz8Øxø/0ÞÌž—ô0p¡¤pmÅJÀyqxPÎÚØ×0,…‡U–(—ž÷ãÂÄýá71ÿâ.Šk&'•Æ{€¤ÇµÌì{E§±–E?IÛÄùƘٛQÝ xRÒæ!- œmfÃÛu“$Iæ>R@è,B…?,¶Hê?A× ÊZˆO$£±ÑQZˆZ©»¸°Aõ6À¯puÿxà föRÔUÃ,›¨ MÀ¸Â‘°Nýà 3;γ*°wÔŸ,ˆéÿ$IW&5]™ù{&¶„¢?-ˆMqÛû@\%_ÖBT…‡ÓBÔÿ³•ýkKïon¯r5Ëix2§k%MÆMwâù?#%ý8˜†'izŸ¤«Oð-FU–ÉN–Çó@4¢)Ú}7L3HЇgûÇǘv‘´ ð.½¯K{wK: øŸ™ý3Ž|ÚÌ®(ŸTRö& Š,š_6³>)I’$í 5s1i¼ÛŒj!6‹×&šk!ê t²/D\Ï¿Kï Ÿh膩ጉ™½!›Gâãá“/ã÷á/’–Šºûð|‹IjÂ}'¦ aº¸_Ëb,ŠùÛCln, ýñÓç$…k.ÞÖöGÿ5³=£ýhÜ™´VÖÀMÅuþ{àá­‹Jz8ÐÌnº>À`\YÆ>…G­´* DôÍ^föRÙbq#:û³N’¤Ë“„¹YÐBl†G+¬@M Ñ("£Ó´q ¯Õ){h±üµ™]#én`[<Œ±î(ù3àD`Iùò×Âד¸w€Ü× <,é‚’E™&\€*XÏSqA¼ï,NÍ1ssàç¥öÏàÒyaFi*½‡’‰EÒFx„ƶÀ½ñúIÍì àz\Sò"p´¤ópÌQÀÂ’ž5³+«BãÉÀö¥²}€¿áQ Jbf÷Ö¹I’Ìݤ!qfA 1–Zˆ·iE€`6h!`º_Ä¿KECJ×Ò×(|Bm2¿"Æ5ZÒïñ'ÿÂ~åIóe\¸˜VÖ~”è Ì_Ú_˜ëY€;]–ý%Êû{áÑ1‹ëᦊ-%=…k/Lñ}ˆ†ýqgΥ댉¸¾[ÌlX»p:°£™Ý(é—ÀExJîv¦Ÿài»G”ÊkšÙÍ N’¤+‘aŽIûi‡b>|r+ 3ª…(òBLnq‚޽–iîpQ¥þÄVx¬Ôv²¤C€ËŸ`(>9?hfCñO_’T$žÚ¯rîpÿ‰‚ñR€AøŸ>û㉬ ÷g •t žŒªX£/pŸ™CcvÆÃV öF™Y±×™Ào%­…çùØ ¸¤4Ø¿vǯ#JåogKZ9ÍIÒ­H!™u¦?#Zˆrhg{µ…oÄØ95Ñ+eGÅ!x¦Æ ÔÌ¿ÂÕþCqé5šk žv”ô7\Ý¿ µØãÌìàzc‘´>Ñ ,éó!\5·5ºy*ë•€»KÅ›à)² Š ™ÙÔ8ךÀA’–À3\žjfçEŸ+á‚àÏðŒ—Ó3{7’\mƒ›E’$éÚ¤‰!™½Ì ¢*@´G 1ݹ²³µU̬n*ìH$µ*nìIóu/ÄóGü ¸ŒHÏu'wH:÷EøXÕÌî’´¤™MŠc.“ôðYÜ\²,Íýª¬Šg•,kPÓ\€ÿA|Œ›OÀý(†Iº,Æ{G!¿ÎñüMÒb¥DTÿ¾A IÒH BÒ5˜-D5±T{´ÕȌ٦…0_Aò¾³å·Íì`‹b?¢"^º§$}×܈›"®ÇWÎÀ1þë*9$~‡j~ɧn¶¦¹€0w¶L’¤û„dî!´¯ÄV7D/ž¼ëå…Ø×Nô§¥¢^nˆ13šRÙÌ~<ãWU·ŸOð¤QwÖ©»XÒ%ÀʸC•gñE¯Ê+tž\)é|"ÿî˜X]ÿÆ‹¯gIºÁÌÞ—/œµ+n6z ¾¦â¾ešð¶’$éúdC2obfo3óZˆ=âý"Ô´KÍv_ˆ‚xÂÕ¨NÒE¸Så)Qv£¤½ïâû™Y‘ËáïxFËíÍìCIâNˆ¿Âs.\bfßé!¤ᑯ¡Èñ9<u’$]Ÿ41$I=fQ ±E¼–µ fB ÑAœ ìR.0³K€Kê´ý09|)À×Ýø¥¤ñü ;•úø%_áskà’æÇ}~ØÁ×$Iç’„$™QfR 1šQÖBŒ¡±ñRœ«£Çÿ<žÆº=m'Tö_öÝ5ö;j~ãyêj4’$ér¤!I:‹™ÔBÑ…ÑÌ U5 ðˆŒ.µ¼´™]Ó£2ö¶›³#J’d&H B’Ì fB Q Ú£…(²Sv¸¢|„GDü]Ò›À_€›+QI’t-ºÍï3„dždµÕÜíÑB”}#:E af‰’vÁ£¶^•t2png-î•$I‡„$é®Ì€¢žQȨj!š9WΊÂÌÆJÚOæ4÷Q8AÒ¿ð-²P&I2ÇÈ0Ç$™Û©h!êZˆzÙ)ÛÒBÔËNÙP af÷H:ø5Æ=€oKzø#py)Z"I’¤UR@H’N$4OÅÖ‚ÐB4ÑR€ø,5óÆÂÀÇ¥ì”uC;Íì/’6vÄÓ=÷ŽÓlü8]ÒiÀ-‘$Éì'5I’´MhŠI¾.’¡¥1"Šì”…â|á©iøzàD}c;8\ÒÀŸÌ¬áÊ”I’t 餘$IÇ#Û«…ØÏŸÐèé¤XHj;à+’ÞþIóÕ&“$é|Rƒ$IçbfŸHz Oδ35ÍAÃCðå¦çÑú¾bg’$Oš’$™=DZæëñ¤z—ª¦á+=öú“ñÕ.Á#3†ÃÌlœ¤ÏáË['I’) $I·FÒ—ð¥ŸÂ}^Ç—˜~Vlföúd’$eRƒ$Iç"iWà[À„6>3;&I2‘B’tSÌìRàÒ9=Ž$Ifˆn£AhË™)I’$I’Ž£Û„9¦€$I’$³ŸÔ $I’$I241$I2g4_d_L’$™iR@H’¹IËJ:HÒ<×Á‘szLI’Ô¥Ûh2Š!Iº8’,ffoHüXx8ÖÌÆà¿åã€{€/™Ù¨95Þ$IæRƒ$]IóK¯¿‘´ð p𤅀»ÀéÀRÀÍ’0³W€«S8H’.Mj’$i?’Nž~ ܇§=>ø2ð-3{TÒÙqÌøêÛ—ãÙ_›ÃO’¤ýd˜c’$Í‘ÔSÒÉ’^•ô±¤+%õ‹êÅ€“qóÀ.±‚ã³ÀP3{´ÔflÑŸ™½‹¯Á°q Vš-“$ɬÒå5) $Éìãx`°°¾€ÒIQ7kfÃJí‡Ó\#ð0XÒü¥²E¨ýÑ Ç—zN’¤ëÒmL ) $ÉL iuI“tž¤Ý%MgÂÖØø#î+°.>¡SRxÿ^¥}U#p¾ ÓÁ’zKú4ðiàÆRûUf庒$I R@H’:Hêùv”t¸¤-KuKÿß®v–Æ[cAàïÀðE–^öˆ~†ƒBX(h¦0³€ïâš…k€ã̬X¦ù3Û|&/9I’ÙC·Ñ ¤“b2Ï#i0wÜØxŸÈ—Ä—M¾LÒ3»ø:ðš™ÇÅÕÿkàNƒx¸ÉÌ~S:·ð?ŠãuEà…¨¬\îÀÌî‘´îð¶™}Xª›6ãWŸ$IRŸ’þøþT¾ð:>I0³m$} |èŒ+6³ ’îÁ„›[9ÏñÀE’^ÁCâ9 ö7³§%],Tjÿu´fö 0iæ.µ%’æúwTI’´Jj’dv#©°9>¹¬üO&ôQ+‡Ç5ó›ÙÔèk8Í'ák€#Jí”Ô§h;®ÑÚøÌìjI»àBÁw€‘ÀN²Ø, IDAT¯Ììé¨ÿv¥½Ñ!Q‘Ga0~_V/½_ w˜L’dö‘B’t4¡–ß Ø˜ü+&Ꞹ#ßýÀùÀÕx^¾ÀÏ[ér8n2˜Z)\Úè'iYàNÜ¡ðW’NvÀý Êíëbf7Rs*ìpâÞ  &”…¦hö nÒ PæNí¬q%I2n“!„¤;r°=p!°'ð}I[™ÙI/O›ÙY’Þ.—ôëŠPf8°˜¤žföq©lÇ¢™},éy` 3»#Ö<8 ø1nV8øIÇ_j}"ÔqÍ5«GY‘[á\K1¸=^GÏUï…¤ÏÍ–'I’&†$i/’âiƒ‡›Y5Ô¯Úv Ü‹3›(éhÜ1pà<|b_´7³ÿFdÀ`àÉz}šÙ«’¦«â“(ÑÏê’ª~€[pmfö$bXŒëXàåÒ¾€ð(„b»ÂÌnhó†4¿ÞeiiX=úîÿÙ¼ã¾8;Þ0³±õúL’$i) $³ IâÎpÏšÙ³±.ð1þ]\NÒ—ÍìñVºY˜hfÌì=IŸ§& ”'î¾À@[þ#ñI¼F'½ñÌìg•ë9xØØøb”ÿ÷…x)Æ3 ×6<Ýà¾ôŠëª'Ë6OÁ3+Ž.ˆqŽÀïe«BU’$]ŠÔ $ó&’æ /ûrÙ@àZ þ”;_Žx*°«™Œv‡ãžþ_iå¯}b¢÷£l5µúpà IÛáªÿCð‰ú™6†¾0¦Ø §Æß¶qÌ+xXâ?½"=2À«÷@Òâ±øRÕ7`ej¿ÅñøÄÿp15A॒&#I’¤ÓI!AÒnxšß»# Ч™®½ÇoƒOÒ»;IšifWE“³ñU,G˜Ù3E2"`ü ~yI½Z‰:Šg"Ü8=4Ssü¼ýý_»`§¶&W3{¢½×[:æâjY„ ®$©ê°:žSÿóøÄ5߀%!#I’¹“Ô $ÝŠÏàOówã¶í3å«$õhŒgc‘ô=<ŸÀ®ø¤û6ð×h2XøNIÃP½ŽEiîð‘™µåP¯…¨oX•ZÈàëÔœ¯¡¦ ]r†L’dÞ$„¤[0 øZ¼ ˆ¤=«?3³»$Ãc÷ë%Žç89&ðËñEˆ6Ç—.ž†OâÍ´°ðY33IëGÕš4ÌìªÈ~ø<¹Ñ=…†ÀÌÞ Æ  ™/ƒ¤íq¿‚7©ùÜLcßá‚RÕ$°:µÄBŸ£qAà&jBÀ3ë°dFI’Ì5tSa ÝI_ÂãûŸ/ÒþÎÀ±Ÿú™ÙíøDyXTõÅ'Ý«Ë#ÿ?x¬ü˜9Ã÷‹Ð¹˜ìÖŽÔÀwã†}Jç+‡â!éUàpàÚH8烫çëq1îïPå&3»¾Z(i~IëÑRŒ;8‚ 8ÕÁxÈà‡Õ>“$I&†¤s‘Ô_+àsøZmµ?8ÑÌ g½MqoÿB@XYR_3»XÒÞ@’p€™ßJ÷Ï}%õ/…Ö §6Ñܱûâ&‰gÍì¨ðØ×\ì…Ûæ§4¸†^¸ùaDkë˜Ùÿ5¨ZºoÀ øÕpÇø¹å,j¾2˜$É>‰n\'év3›@ó'zpap),q>?m·¯œsaà ¥È„*Õ•oÆ'aÌìE|}„ö2-ú{ ¸7£Lwì“´õ}Væ‹fãp À£À¿¨ /gÈ`’$s˜’ö!{_ÇUðï¿­OofïJZ N4³û¢üàȸ=ž8hJ¼?ŸÀ¿Xêf"îm¿rôSà÷ÇIÚÿŽ<Š«áÿ#iI3{½Îðw.5„’ 3u#˜žÚø`%|âÿª¤²0P„ ~H-dðrš; ¶pŒL’$™Ãt›‡“æ’ÖÆ½àï)TÚ’õþ‚/žÓ:Þÿf6-V\(OÇïÇÍëÅ!÷G‡ŸÁ¸-Ÿ8¾>}“ôsàøwäHüI|=à­ãi!È´—ÐNÔó XÏd2XLþWQs|aVÎ$I2‡H ¼JØÂì†GÜ ‹G|Xè-is3{8÷êÿü LxÃñ0Á‚= ÌìÔC‘|3{RÒ£Ày’îöÅÍkà ·Çù‰ögã ŽÊÔ]Ë =”Ö&¨ú¬,ÍŠÁÀ Ô‚‘2˜$É\Bjº+’¾,bf§µ³}_`#à=3{,Ê–Àй .ÀŸ¼w.6Š|'ã^üëÍàÓðp\)è¬#ià›¸câR¥ú}qÆ@`wÜc €™“ñ,!iÜÙ±ê0ˆæ!ƒEöÀ[© ÏgÈ`’$s9館™øÐL@ˆÄ<ƒð”ÄFÙܾÿ °¶¤ûÝÌìõXfxš™íZêãMà®’p2p—¤žÀd\«0#T5GáK ?‰G >UTšÙ«¸ b–‘´-Mƒi2ø2>ñß…gg,|ÆuÄ’$I’Î#„–< Zì„}üRÜþ~=~ÏöŽt½[˜Ùc‘—`$°+ÍÙ)3œæê¥‰øSu?Ü1ðJIÇ„Ç?’ µ2Ö?K›Ùx\¸)óR»¯¼B%d°*,ÍÞ§2x.5߀ L’$iIjº’¾Š¯ÐÑ_YRŸÈ x þ®xÅo…{é÷‘ô]ÜÖÿ!°. §e6¿áøªgÄþ*¸ð®™]'é4`˜¤‡ðP½q…º˜Ù;Àgöº $-I}߀•h28x_½°0dÈ`’$ÉŒ“BWGÒ2¸&à`\88Ÿãªú/m2ׄOøÃñÁ§/FÝpÜ7¡Ìpà›’®Á'Úƒ€£ “ƒ™ýŸ¤3ð‰y ×è‰ £Ûk³UW¦þCKD³ñˆ†‘¸Ö¤ì$˜!ƒI’$³N·y šç`k`\xí#éwÀ÷pïþ'i°ÐžŠWÀ•fvCQ(i%Ü8¾¸Q™á¸q2°!0ÄÌî,7“Ât³BxÿïB-£àjø ‰£€ŸPY!«š€Á4œDóÁò*ƒ2˜$IÒù¤¡ÐŸ00³%=H-iÐøBCÿ,ÚHêefoHúpV¬^X„/Îlƒ¯p^å\Ãñ þ®ª`ЈXøheñ_OÍ7`DƒDGI’$Iç“„nÄãÀÆ’– '?ðIö£xð€¤qaa °(°‡™$é^Üï ðÜÔPd<¹r®—ñ‰{ ®eh•ŒkÖÂÃ$‹Áù£Ùdj“ÿÍÔ|2d0I’¤ë’„®DD,‰‰0³'Â)ðTI'â õ£–`èÕXhè»ÀâÀCø“|qü}D&ömÀÔ4*ÆÕŸú¾ËS | ŸøïÄ mÀx’$I’îBF1t%$ À7«윂/ès7®X¥¨ •üI³8†>¸À*Àö±®@! ùÞ§¦ 8‡æ« Ö]9I’$éV¤‰¡+ †§ þØ žÚ=÷ìV)~¥Ú®ç\Šúë ¬H-dp,>ñ?D-dpðJ† &I’̤aN é³ÀÀ¶Ô>„™ÙsÔOîŒXe9ü~7$­,Ü|xÅÌî-5yX-Þ¯›-ê"iEà6àQà@`uà¿¥&ÿN”ô°¤±’Ž”Ô'Ží#iOI=$ ’´t£óÌ™/"I’¤©A˜‹yx¸-é}IÏIdfN‘4$žØ?Ç5þ’â“öef6ÿÂ,P9ßRÀ;ñþ=ZÿÌö†™Ù1f67Ul"iýÒ6v6ÂC.·Žº€³q?ˆs€'$ý¬Ü¹¤ $!éI«´qŸ ~$éœv¶M’$Iº]ÞAÒÅÀkø“÷ØÒëX3{{vÇÌ®®+¯>ñ¾õ‡Kzø î€x#0MÒ8`0?°4p)PLÄ‹JÚÐ̧ø¯;GýÃÀVÀ¿ o]JNfövø7,EM¸Äèû=¥cš€¾À1f6TÒÀÀ©Ñv/àDàßÀ4àIC m‡¤%qdI\ëq5nnÙhfI’$™‡é6„®. ¸Ÿ¼úãªûþ±5IšFEh ¥ 1Î̦vÖÍì=àÙJÙéÀ镲~a–XøxÓ̦”ÚŒ—tp¯¤ÛÏÿ ¡ÖNt ðjÔ¯mî3³¯I¢$= œmf—4ðGÜ%é,Üäq·™};|3¶ÇµW™Ù³uŽM’$énXÛMº]]@h3› L†5j#©nÇ/ˆâu£JÙ¢ñTܪ afouÖõ˜ÙDà¦uCÃü°®!y+ê.“´nÖXwhÜ-m¢eE¹¬ Ÿø úï™ÙäxÊŸ lýöÇ.‹ïÏVÀ•qÂÖôsD¤G•¦¸Ž ¸¹£‡¤]p!èb<óä½’v3³Û$í üx 8Tî ÌrÀd3{¿ÞýK’$™Ã¤‰¡«Õ„ØkÔNRo|Ò« k”Ë"×AUx¨'H|P=GGbf¯á¾Õòã"—Â|•5Æ¿¨4ÿ£¿Æ² Õ„_¸ ñ6°“™OKAC¸Ù¤õ“jý(àÔ0™ø3ð33»@Ò+1öÛ%mƒ›;Çý>þ€F_ÆãŽ–WgƱë;›Ù/§VZ7Å<ÂX«HÚØÏÌ~ÔF»ÞÀÚföh[}&I’tuæz¡½DÂK±5DÒB47iôÇ“mZ*[NÒ{Ôq¬¬”M0³Oªçè€k™†«æËe¯PвMK»ÑÜ™p2pQ´{?žÚ/‘ô=\ÐZ8ÅÌî$ü$]÷±Lo\¸hDp[I»°:îTy”¤ýq­F¯8xÖÉóÌìlI‹ãš†BûÑŸæÉš¸¹†hÿw`'ÜgbsIǛ٠Q·:° ®‘\&¡5Á­\CÁÏñ„WÓIÛáþw•’g%I2ï’„¹3{[]â)xIZ ë_)•-.imföFg]OAåýÇ(i\Ìì6IðôÒK〢ú0<b¤¤ëf6$êFGHº¸§ŽQ5môÄ87Ã( sÆQ¿¾ÈUÁ(\RhªÂôý0]|XÉÌÞ sÄ ’.ÅïõuxØé#ÀÆÀ®’þô–tð¨™Y½¡•ØX§Tö<å?ÀÉ’~lfgVM’$銤€Ð ÄÓðÄØ®Ò¶ý¬Q$ÊN–M©0–Æ–… Ñ©v÷0›ÜV§|Œ¤ ñÆ•€KÕ[{ßÇÃ4ë •öŸÅMß4³¿Q3s|HM›>‘ óÄ|¸ðR>¦,0 ÁD-iL”¿Šû>î q–™M¢J*éŸñötÜ£Gg„ÆI›ßÂ…¥‰’®.tŽ™}Ü éHú ®Õéœkf¿)Õýø‹™o«Ÿ$Iºñ_©AHZ#&Šªÿ*’ e´F|r,ÊúKšJë‘EØg›ÔL\Ë4üÉû‘Jù$ÜgàÔ‡žK);d¬M±p¹¤ïàÂCp¦™ÝÜ|'žæûáΑ…ä'¡‘Yx-49Û§D÷KwàY+ûã n݉ߓÑñÄÿ|D‘mf… Ñ„k?^¨wá»måwÄ#; ÍÆP) $³Nhž‹­!a¯ k_*•-%é Ú$&5ˆ:èPÌìª:e÷Ä„¹Æ9žš9ãHà<<$sR”÷)þ(®!8øž¦ºÐ Ö2³kŒåI§âI®ž‘´V m9ZnŒÿ–ÊÂÑFøÊ›Ehk3›"éE\ ØAÒÆxäÉn¸éæP<ÿÅ¥’NÁ+„«ðl—) $IÒi¤€0¾ oÐúz óáN€ÕhÍ*e FÖÇV‰ðÉèŒkùº¯–¿ì"I¡ªûž²`W<Âá àBÜìQhh~üOÒÿ€³pGÎ¥ÍìI[†/Æa’¾ŠkÆâއ-"FJ,ŠçÑ(;œ.ŽóÇùŠûõàiIã>û‡ŸG/\¸8¦tì›47«<¬'i©öDa$IÒ%I BÒµˆI¬˜ðnÔNR_Zš4šð¤Iå°Ï¢¿¶²YV}fõ: íF9Ùæé·ËN„—•ê&ÄÓúÎxÔÉ'Ô„m€‹Ã)qéw¡xØRÒ£ ÂW'SËHY¦ì¯°5žÓáùËTI¿Ç•̬pÂ\׈”ý2&ÓCVC0šŠ§ïN!IºÝ"YR I]b"|!¶†È—“® ƒð4ÑEÙ2’Þ¢mAbâLd³|˜RXa[„ÆãÜØÊå¿t,° ¾¢æäRõQ¸?À³‘°©ºœ÷xÜï¡Ì4üžjzL_¨ë(\`X¸Ô®w¼ÎOÍ,±>Í?ÁW-L’$Ý#5ÉÜNdq|‹¶³Y.MKAb“JÙ"’ÆÓvªé“·™ýµ¯e ¾ÐTµü1|¥ÌFǽ(i´¤õÍìñ(þ3p_D ,/å½)@dÁ¼8½_ÒEáï0 ÿóX˜Z4ÆWpâø¸ƒæ¨™¿Ú®I8Ÿ~ˆG—Q&e‰d.$„$‰§æñ±5|ÚL„ýi)H¬U. £­$Tã:;›e… ñÈ…ÇÌìiùRß;ãþþ!HôÀó8üËÌþ élÜ'a0ƒÜ-éûøú«;”εðPR9·þ1[ã¹0_ijt¶* HÚ,^´æë$IW$M I2#„ŸÂ‹´T§7#²YV£5VÄ“8eËIz—¶‰ªsáÌr>°Eåzžޝ”MÃC˃;^.+{âËjOÀw¯$²ú:µÄQsËóá3:ÉÿwVí1æ÷¿5³g:vˆIÒa¤!I:šð#[]JÙ,«‚Äúø*‘EÙâ’&Òv6ËVŸÖcB»z&¯ç=xXi‘0ë5<µuOà’n(çôÔ·j~ òÀ¾x"­€ó$݈G™”×)I’Ž 5IÒ•‰I¸=Ù,ûÑÒ7b5GËb‘®h[? Où_h”À*ÂÁíõG†/Àk»‰Va0Ô̶TmuÕ&3û@Òºx¯AfV8gÞ iÅØ¯&³ºÏ}± ðޤoáþ}"QÕÌìÞh{ž¨j]3{9úí…'£ZŒæ ™%ɬ’„$™[3@{²Y.AKAbmàË¥²%%½N‚D¤©®Ž£Õ?óE¨¾„ç†Ø ÷øDÒYÀßÌlt{¯y0}á.k¹ºêx4C½ÈÀ[u´7…oÉ’VÂâÜŒ¯ zƒ¤þñÙ Z1†€Ÿû!´lŠÿ¹ßß@Ó$í!Ód^#|^§íl–…Y£,HlAóhðÔËm ÍžnÍìyIß®Ä#Àó8üDÒ£øSñ5]P«0€æ+{–y_6»ÕA ÖÁÃF_~ÜkfE¸èŸ%|NÒóxvÑ; L¾òçÿp'ʉÀIÛšÙÓQÿ7à8< ã}àÒÙ‘ª<éÖ¤€$Is"j¢XM²!’Šå®«‚Ć4$>¢~„Æðõ(æ§–€i3|âœ&éLº–VaàÀX¬«¸?#Ì—×¾ w8 8ÅÌ>”Ô;4 ¨ÜË'=ONe‘˜ªÙBb¸ðÕÚZ­-«~ž#c§Ø?7W|)ÌOkâÚŽŸâQ5ÄõlŠ/}¾5îÌz~5)X‘>¼{Tn¿𤙠oï1I—¡[) $I%7¢„H‘Ͳ­1XæëTZ…ƒð ypk {¦1³KN£MøÄ?Ô½#ikàL|ÌïãËoŸí–’¯þùî3°'¾ôøÑý<:IƒUqMÏÛQ¼ ÐHXÚøN1GB§ïG]á\y˜™=õï”ÖÊX w~ü-ðW|iðñLšHú,p°R˜žŽ5³³Kcí‹Gßô-™Rþ×Z¤€Ð=I B’$K)›åô˜I?ö¡í?!Ã1­ûKtÆÛKkN£föð©xbïYʨy5®ößè…‡@þ¸¸d~¹¸GÒ¡ø:¿n)ž¾%ÝŠO¸Ó}¢¼G<é/„›Ž >¤öØŒ,„ƒ`.LŒúÌìøès "LUÒR¸¦çÐó:¸oÄ“fö ¤M¢ÞðÏw I_Ä µ"4ó¿ ü3’®Ij’$™½Äø™À.¸Ê<¯À»¸°Ðwü{ O&ôTlkâ6ø%mAÍ¿aêl½€vN…åý[iCbfÃ$}ך숛Ž.5ù1p½¤eñå´ 7ÇŒNÁS׆Fû=ðû.¼X9åRÔLMÀ奺wñ ð¤WSqo}ü¾ßlc¼¸ÀÌŽ´‚ùwà—øbc SÓ MGÒ—ãÜÃð%Éoû° ®aɼ’9Cj’$™=ÄÓèµøºÓð§Ø§ñ‰ìË„T IDATq<üqT½±$ê÷&àçÔ²Q¾CãŵŠ× 3±ÈÖlÇ̆⡌õêFFjìðµ/zàBÔ?£ÉQÀùR¹< ±uÔ5s’”´ Í×Ò¨:QöÇÓŽƒ/l6ÿÌv¤f&zRÒj¸™äÏ¥q¾çXbZø2”Ø Oõ‘ÔK;Ý×´&˜õÇW&ýbô·"¾HØföHø6Üì \$iK\À,-éb`3ÇŸbfoÄ~àý0qÍ~:Õ|¡²ÖÚÍg7 [\K I2'wpŸ3š²œ‰²?ð…ò~´kO6Ê)y…™=ç—¨–ÿºR4wJ,„¬;i®Ah¢uqpˆ¤3pSƸÂí¸Ãä4\ Js–£&d4¢ σQ°‚ùðc¼Œ›6.þ†;Hž~wÄù‹4×ûÐÜGã7¸`tB´ùð]Ü1ö¿ÀÉVZç$Â{ûTןÇ8~ÛÆµœ/éV3» ÔßòÑßómÛUI B’$s73˜²*D¬|¦T¶\D(´µÈÖë˜E¶:œx¾$ÞîRæ0Ü„™MÓÆ/€‹ñpÔgÌì6àuIG7K:_{Dfv1®yX¨'ë&àÙÒþ¸£ãõøý^\žŒÉv5bM3{/2q®ÇöÞ®äÜXŽZ6ËÝpçPÜã` ðãÐTÜ‚G‰ô–ôðµ8ßfÀ’ÖF—´.Ó‘ôy\ˆÙ'ö{â‚Ï.Àk’^ÆÓqO®Û…I B’$IA8>KóI«’–¤åÚëâŽ{EÙò5'Zõ(Ôá]‰ªJÞÌÆãf¡zmOtf¹9ž>\XŒ’t“™ý°ÎáU߇gp'ÍÛªI²"•µÑ<ćÔ4e­GAÿRÙÀ©À%fö‘¤ƒûpçÏýðUS?çZwÔ|I€;\ÞŠ;_V9 7má¾x.Á1Þ+qäguŽm¤½ñïÒà43{!Êû˘ÙK­Þ‘¤!I’dFˆÓ“p§ÊºÄSdÙ¬Q[•ÊšT[d«­l”¶ÈVGcf÷àN†å²)ÀΡú_²zLLvÓ|Rÿþ>LÒ©x†Éµñ\ ¯âÖêÀ3‘hê›xx(xôË;¥þ{á”cä)¨×ú=£n Ð7îÿóÀ/$í\dfE–ÑÃìpT‘‘²Îu¬…k™n)ï\Q$ø’t)¾–ÆÏ$­¬nfÿiÐß!Ñö„ÿgï<Ãí(«6|? ½HBH€Ð{"M¥(Ò» "¨ ¢¢¢"ˆ4é MéUŠ ½HM¡$@HBB’õýXk²çì³÷i95Y÷uí뜙ygæM8ï3«[áÖ‹ CHÎ’´ºU5óêÒ‚$IÒÄðÛÔ/Í ÌŠö¯éü&[B˜ä™åc[ºjŸIÚO­Üw¼©¬ŸJ:¸7Ä×ñX‚âû}¬J'Ìñ·ÿÑxÚå <~án¨Tkß%iw<ädI?4³kBäõ§éŠ¢_ÁKdYóãbäÇ¥1ïSIó| ¸[ÒûföŸpO\Ï3·Tlf7Ås>ƒg\Õ9ÅÝ×71§ö"-I’$]EXZÒd«ã#Š&[ÅvÑd«^\Ä`´y?ŽnIÄ+ÜŸj~ˆ÷›X _ÌO¥…ö›Q=rx¸vÞ¡“ érà‡’^1³‘f6UR‘ʉ™= |%ì%]‹[€>m&»eUJÀˆ8þ÷œ†×’(b'~œ)×û˜ÙëòŠ•Eðe!˜Æë—®uÞF¼£B¦9&I’ôÂÄü>-o²U_ a¶FÑd«nÊ'.$>®¾GWâá¦øß.?HÒ¸µà]\<‰÷¦xZÒ`qà Igàe±‡â©Ã✩T:nÖc ‹@kV¹ÎÄÖxjf1Ïë% ýͬpO¬×w(3¾_5‡÷ðÜ )’$IZ„5l²õT½qª4Ùª¶HlTú}Yy“­&EîÖèô¶Ò‘žYBÀ̆•6¯+íŸ .éHܵ1¹@’NÁëf쌨õ&H!é6àQ3;µÆT&ýJÛoãŽ}Jû¾Š§is_·‚|„§˜,L¤m–DI\à¢eñóhoÒ‚$I2·a-o²µ$ã#ÖÄ+4Û}#-°©”Ï1À{íYH(Ìï+㮄֜7J•Èbß]x7ÎZã×—´%Y‹{ñ`Ébü4IWW†Ù/k}.€¤åñ ?ÅëGü84No°øKZÏ ù}é~µDDGAŠI’$ImÂ÷>/‡]“pkô§qËï-ª¶ zsÕ,'Wߣ‰ùuJ©e3{wCÔ:ö¬¤ù$ 6³7b÷€ñÔÊ1ÀQO¢/pp¦™]"é_À0I›˜ÙSÀ}À©’>gÞøëÛ¸˜ùOé–[1 @Z’$I’¶nÂjP—Hk¬ñCe·Fq½¦\cÍlZGNÒ_ð/™Ù,ФÍðÔÍ›ÚcÞs)’$I梊ã4 Ìk@IêGã ËM«ö-©ŒÍU³lT§¡+‰K#Ëû"(óLàëœçiAH’$Iz‘a0.>ÏÔE‹–¥±kc]¦}Í· ÛI s=úI!I’$i5± 7z¯FÒâ4«àõ Šíe$M¢ùj–ïXÓ-®Ûú,ã [{^¤Tnü£•u-Ò‚$I’ÌÝDa¢Ix¡¤š„‰¿ã#6¦a*è’ÆÓ|5ËNéìhfC%„w•¼8ÛÌêö)ŸÚÁSkR $I’$]J;ŽÏÿê‹ÆPh±Vy_ÄQ4)"p·F{4e:·"ì#é àt¼³eSMÀÒ‚$I’$íA¤8¾ŸºD¤j1/ŒTì[FÒG4_Ír|Sn 3›M°^¢"VÎΑt5nU¨®u‘.†$I’$él¢ Ô0*}n¾4ŽØ/ ]l/)隯f¹ð$^±èq0Þûuܪp}TÚì¤@H’$Iæ:­ñN|ž«7NÒ¼¸[£:>â‹4Œ˜ïÿ° Ð+NŸ7>ë⠫ΓteO B’$I’ôT¢Ó[ñ©‹¤hºMôÂñóðøyš¤éÀuݬrå,z5?$I’$I’zHú>ðO¼ uy] LŽÏ4¼×mÀà_ÀýÝU@Z’$I’¤M„ûáBà \|ˆ»&áÕ*ų2^^ÞDªæfÖd®&B’$I’´Iý€¿Ë—OáBàÅ”—Î:I’$I2‡2ع «2Í1I’$IæDÌ죮žCG“AŠI’$IÒ¹ô B „$I’$I‘!I’$™#‘4¯¤ë$-ÕÕs©"-I’$IÒÑHšOÒ¡’.—ô+I ì"Gÿ.êÚÖ$B’$I’t0ç¿ÄS wîŽ^ ç¢-sw¡G¤9¦@H’$Iº’ô-IûKZ¼…ç,Œ·ZÞÁÌζ6¾ Þm GtдÛBº’$I’¤’V’ôçÒv_¼ûâ!’–¯sîIWJZXè7]ÂÌ>nv-r+°¡¤:äaæPR $I’$]Á7€JÛǯÛk§HÚQÒÛ’Ö‹±¿&F-‚¢ÁŒÒµn¶(6Ìì}¼Êáfíÿm"-I’$Éœ‹¤$ jãé»”¶7ž6³iQð `7I ™Ù]ÀO{%}Ø85΋‹ƒ²u` °DÕý¦Ò½Ö¼I’$ÉËπݚ ©Þ:³10ª´=ƒ†V€»ñH[˜Ù•À÷ë€kÍllìŸ <ìY:·7ðYÕýfÐ}‚»Ë<š$B’$IÒV†k‚ÇHZ²|PÒ]¸¥ ½ð…¼à`V`b´A~è_óFìû¦¤­Jû¯ö’Ô'ÉŽÀcU÷<ײÇj?$-"és’ö“ôkI×Ç\Öìì¹´–ìÅ$I’´I šÙÔÒ®!Àáñûp«ÀWcì¼ÀÖx+äZ0_iûàIG— õæ-ù p0ø§¤=ÌìAëŒÄc'º5)’$Iæ$Í,ffïµpüRf6!~?ØX¸ÄÌ®Ža{áßüãë%­†/„KIêcfïK:8_ÒÝxÆ@µ™¿Ìõx&Ãùfö–¤?wJº·D< ü/ƯZ,üföŸP`fOÖº‘™Ý†g6´Iý©m Xwn­†[>þ¿3³Ñ-½Ow'B’$ÉœÃ÷ðô¾½ê !0 8X_ÒÊÀOpýÏ€%³%M5³áV™Ùqþð`Á­Íì>I#p+ÂÍì.IOÅuVÆøz\üRÒjfö €™çoüF´8v~[¾&¾‡yc޵„@‘1xÿ¾®ˆŸÃáQo¡­ôˆ4ÇI’$scM$‹ÁýÄÌ&Vù:ž"øs3ÛQÒ‚¸…`k3{NÒüx,Á‘@!'›ÙTI/á‹ë}xÂZÀcÈ1T‚O¯7Q3{GÒ€‹$mS··´ù¨"' 7@Y¬Le ‡/üÏ×Rq ¼•;‚I’$Iû ûÎxý€S€½ñ¿+¨*3ØÈÌ.‰íÅE“%­„Ó½ Ü_ÿ«²; “â÷Y™ f6FÒ©x@á M=ƒ™ý#b ¾ˆ‹6™ ƒ©m èÃ>^ÃþQÃÌlKHsL$IÒM‘4÷Ó÷î0³§b* êÙÀBÀÂföMI“€»Ììµ:—J”%>ÀÆMÀf6£jü`A௒Îù,Š‚ÇlTuÎXà‘×j„™}¿¹1¥ÒÊÕB`UÃë \L7³™’†#Íì›-xÔ“€€45(bê¥ .Ãê¥ ¾V¤ ö`Ò‚$IÒ“ ÿö¸|ѺÔÌÎnæ¼ÞÀ/ñ΂%=ìņŠãû™ÙµñÖ3û‡x¾-îN“´€™}R>hfS"`Bìûø®¤Ã¥BECñÅû®&¿,¿V¹ä1’úQ;Hp0•”ÁQøÂÿ( SÇ4w¿Jf1$I’ôdB\Ž/h¿Â£óû_)Y¯"ø‹7ÂÏ_,ÔKPùã?·&s2IEâ<­°ÜTè±xÖòs”Ý­&:Ör ŠyÎÀ» )ƒçP lQO‡¤Õ¤!I’¤XxOï{¸_x_)„àhüͽ7p\ˆ‚¢ÊßíÅØ·»áaKàß%7ÂÀQár¸o+¼„™}Pž”¤~Q5ð!¼§Àÿá…]q¾Ð._•âx$.0³3Ê׌ ÁVó‰”ÁU©2¸h ûÆ)ƒÃqËÄ4’Î&-I’$³ÉàSàfÖ¨;`øÌÿ:xÊ[y¹q™—©øú?ÁËðŒÁßðúáÅž®’t™½½ñÂB›ã ßÅáë?˜Ù›!.f™ãÍìñV>ùYûR?e°7M§ vûöÂs™æ˜$I2»Dºà+¸%à±°¬ÌV‚íuñRÃÕ¦Û!À>5.;•?ЇH:-Έÿm÷þ^ð IãðÞÏá©‹Dšá¦ùIuÊ^k}õ‘2¸µ…@Ÿ6·  Ç-*ElÀ+saÊ`O$] I’$íÄÜŒ2nÆŽ›ÿÿ ,‹WÖ«õG·œE49ÚÏí/bô=àIw?þ^FµÁ=ãí}a`b­H}3{¿z_SHZœÚ"`*)ƒc©¤ ^GÃ.ƒ=b‘Iê’„$I’v`(nFßx»jq –Ô§Æ"=X,õ>‹ý.¼\HÚ8_ n¬ž@ÔøoUÿè³°µ…À21l» }>lÍý’Cw)’$é ¬Nó ÂîßHú%^wàÀCQp2þ>)8¸¦,2Ìl<^)±MHZˆú)ƒ ư"ep SGfÊà\IZ’$IÚ!¸•`è>Ø÷ÓÏcfC%í„×:xR|x8Îý"0*DÀl!iYj[–£’28·ÜKÔÁ µ®™Ì•db’$I;ñ*0ˆ×&÷,øMô Ø<Òý¦We ´ªŽ@d)¬Jc!°:•IR±ü§ôûk™2˜Ì)¤@H’¤Ã4_{,˜f6MÒqxÿ!xIßFí~[ÓXÒÒÔ¶¬H%eð-¦ ±™2˜ÌiAH’dîDÒ€ÃðÆDoµÇ5ÍìÏm˜Gከ%–ŠaEÊà0§ Öí`˜$³A)&I2÷û»âMŠ6ö0³v-¸÷bÔOœ/†Á-/Ð0epT¦ &]@Z’$©¤-G{úâ>ûpa°Rì¾ÐÌnhçûïÊXK ˆaÓðx…ax¦r—ÁLLº =âÿùIÒÁÄÂ6øÀÌ&–ýð9à쮘×ì…~~ŒWøþ‡ï5¼/B[¯»žX-VŠaïÑ0e°è1)ƒIO!-I27#im¼øÍ’À¢’Ž7³BüøŸ¤ûÍì¥.›d+‰T¿c€ïóã}Ÿ»·Äw/iµ­Ëã<§Sé2XNž)ƒI'ƒ“$áb¼Öÿ÷ð|üÛ$=dfÏEãŸ?§;uá[„¤5ãpw‚Q)\æ3{±tÎ|x@-!P¤ N¢R=°œ2øz¦ &Iב!Ij é ѨØÞ_—®N6³Ïꜻ^°g¬wX˜½ï•ô0n–?<†ßü¡N™àn¤-€ŸáݧSûïÆt¼%ó§’N£"V¢’2ø&¾ð?\B¥€Ð¸Ž~†$éf¤!Iz"’>œ|9¶7Çsà&¿>N —€óÌlzŒ½k^è… …‚kñÅ3%éàëÀåüh-&â&vÆ?»Dm«øß’- h˜2XÄdÊ`’ô0R $IcvÁkö|¸ÑÌ®€Y)uçHú#^Vw'`[I{¿N5³©’¦ão eýKxÉ`•²FKw赜y$}1ËáÕ ¡¾0(˜| ÜÞÙ I2Ò#,½ºzIÒHú©¤o·ñôpsyÁ <}®àf``Ëx+Þã–ƒ Âñ"a‰zã*íëQ÷Å|þ üÐò¿óÄ5®—ô×h©œ$ImR $I2°Y½ƒ’¶—´uÃ}p“zÁTÞ¤1³IÀsÀú±ý)Þ†xE`, -s÷{•¶Æ™ÙÇ¥}½ñ@½®¤WáE„nžÁÓ Ë9Û3q±4“Æð¾<+i­Ž™j’$Aº’9•¡ÀŽ’ö–4³óJÇ ü®‰óËnáÀ!UÇ X´´½Þ#`$p‡¤¯…88TÒ¹À­À¸o¾ÌÆÀ±-y¨Ù!ÕkBT<˵fö`ó–Çk9”?«ÅÏ¥¨ˆƒñûx ç‘fva‡1¬X؇ᩙE­áf6¹êzÛ¶v-óá1I’8iAH’I[›ÙŸš7/°pþV¾(p'î÷îô‘´™½‰gì,cfŸHºxCÒ¦fö¤¤WãZãñ·ö$튿ÝÖ³\/i!3›û¾‹¿iÄ[af¯Ä±›ñ4H";á¶|-˜Ù(`TßÇâÔ«PÉ,x_ü_n¤"FšY­XN%ŠeÁ£$éa¤@H:‹…ñ:’Ô˜T² éR*.ƒ³ñ.|ç·˜Ù/b̹À¸•`(0ÚÌ>0³1’n¶žÄÝ k˜Ù4IGà• Ÿîª7Q3&éj\ ûÞ¶‰7w+×û7³ñ³ñ½®’¨-–‰aÓqÊp<–¡¨68¬ª¿C’$ÝŸ´ $s7Ñtç³H÷ÛX5ÞêÇà‘î¯Uò:p ЧXô$}¸LÒ·ðÅ~U` I½qÐGÒ¼¥ª†½©¤ì ¥‡€™Ý/é`?à—ÍLÿXàiI×›ÙS¥kLoÕ—P"¾êàÀ¢ Q‘ø•Åÿn–®Y¹1I’G „dîDÒŽÀoñ·_‹ µ¿ãnƒ]ÌlhS‡ãk¼<Š/ø7ãUùfH÷ظ",ëà™àâ°ªký¯[Ðds$3›îˆæ 5"šÕ²,‡ÿQ˜I¥ìðýxÝá¸5`¶¬I’$íE „¤MHú)Þ®xY¼@Ð>aâ_ˆû!p©™™¤^f63ô5ñ…¾Ci¼ ß»N*Ý{I¼ |ÕÿVÄ#ÝCï©q¯-Û[â›7³šAw1‡ù¨¤ V "eðc*¥†/¢b xµp‹$I2W’„¤girñ¬ãðb9W˜Ù¿ãøáÀ7ðt¹3ðæ;_öž1³KŠë•ã&ÿ¼,.i™RŸŸ–\ +áõ ¶6³7% ÃË¿|jf³ÜÑühV¤h"´/°g+¾‹¥©-V¤’2ø6.žÄ‹Ø€vK]L’$élR ÌHZXOk{ÐÌ&´àœyp»#ž&ø„™i{Ûá±cñüý5K%­éóÖÃc ÿB¸ù¼/[Õ›SŽÀc ÆÅ¾ç¢"ßx ãƒÀñ¥œú¡ÀêfvssÏŒ[6~[â£^ÊàR1ì*)ƒÿ b nfµàÞI’$iAH:I«âµó{ãi{Kâ>öUJcæÁÀ§fVö»¿Š›ï—Ëû\*éP3» _øVÇÛ?„¿ÁCš¤Û IDAT„g\ç÷ÿ4†/Ò»á&õç€ßW¥\œ(é'qÓkÏ9•f6ï X‹!¸›£%¼¬!©Z¬‚gL€·i.§ .‚7ºCÊ`’$s )’ŽAÒ¢ÀCÀifvfißÒïÛà­‡ßÖ”ô°[Dÿ¬ef›ÇØwñ”¾»pSÿÌ8¯à!¼$ðÕxšàL3; jN½áâáo’®¦â4³ ø·.^­°\ã3»´5߃™5‘2¸<µ­bX‘28Œ†)ƒÃ3e0I’N Ñß¾îH „.DÒ2¸/{üÌ[¼¶/0±,Ììݸv/üýd3;/Rì^ŽÆû £aGÁ[s%ÍE‡Fâ¹ùoÄñ¡T|÷gÿ‘ôîw_›ÙÍ‘µpîžx¸¶4¿GñŒ„Ù"žg5j§ Ï5‘Š :e°ÍéŠI’$³Iº’ÚHZl›Š/XàézkK:ÆÌþ^»1žæ7_XOÓýZ¸9¿Ëã†7ì´½sñ¿ÓñVb3+i nn/Ükáî(šÙÓ’¾ˆˆKð€˜Ù[¸ûa¶‘4€Úր婤 ¾s~/¬T ¾ÓsH’$™IÐNDÚÕðEôÅ&rý1³$M/×IÚ¸QÒP3{LÒ†x½ÿÓñÅï|‘ÜoG¼Pã«Ï¢°D”KÜŽúÅïCqkB™¡øâ[Cp÷Bñ Oà™ ³M¤ ®Bm!°X ûˆ†)ƒÅï™2˜$IO#-s:’Ãú¬‰û½‰/¬¦”ý¶Ä«å=n€¢ ð,`f·Jº8:ü^fø×qW'$‡wá;¨¨1P=73'ix\£hk¼"•ºÿC•$Í_*y|?•:çQú÷af'´úK*!i)* Y¬„Z•.ƒå”Áá™2˜$IÒ¹¤@˜=&ÛG×D `$퀿y¿€›Â—Œíê7ô‚»ð®„ÄØY c4 ‰ Þ/ª‡ã•øŠûõ~bf¿NăûSp Ä.q­±’NÆ£÷?}?/Ý«^ªb“D âŠÔ¶,Ã>Áã!†Ó8eðã¶Ü7I’¤‘„9¨8 X Ž8Xï ø=3»ºêðjûé'Qiû°IÕñ%™ÙÇ’ön’´Ÿ°n}ó»^Ò8<=±7°Y9ÕÑÌ~Óšç­z¶Å¨ÝW`U*)ƒãñ…žŽY73e0I’¹œsC€í"¦`-¼`ÑgföM`3Ü­pmó†â9ùŠöÀë •ÅÿžÒï#2e0I’d® -]¤M€Ÿß òáЦ(µáý©Ÿ2Ø $oаËàp2e0I’dn'-¤ñ†B[áæzá õÍfvQ®7/°2µ…À1¬HFÔÁ×2e0I’$©A¦9v’æö~†—:.Lôóââ`<µ{”¯±$µEÀÊTRGá ÿS4LÓ¾O”$I’̤@è(¢Òwãx@høLö0³¢Ëá`j ~1~*Þe°H,,ÃÍlJG>O’$I2×.†Ž ZýõÂ…@瑱<+é¯xà`9e°Üe°oÎN)ã$I’$i!iAh/$­„g$|ÍÍ]x‰4Lž)ƒI’$IÒ#^D»½@´ð+àóø—Ú«…§^_à}à7é"H’$IºÝÞ‚ÐÒŶ+XØo-¼•/³¥Ê«ðœ¤uÛwzI’$IÒ&2‹a6™ <Œg' Æ­ƒã³*Þ”h*±3ñ †Þ4ŒG˜ÏFxZÒ1fv~ÇO=I’$Iê’.†vÀÌl0¢ÖÁÈL( ‡âS- zó‘ô%à»f6±c§ž$I’$uI BGMŠFÅçáêãMˆ3$lfouÒT“$I’¤ -]Ms"I’$IºˆnoAèÎAŠI’$I2'Ò#,)’$I’¤óI B’$I’$ èiŽ)’$I’$iD „$I’$é\Ò‚$I’$I#2H1I’$I’š¤!I’$I’¤‹!I’$I’žI „$I’$é\Ò‚$I’$IÏ$B’$I’t.iAH’$I’¤™æ˜$I’$IMÒ‚$I’$IÒÅ$I’$IÏ$B’$I’t.=‚0OWO '"©/p+ð60ºôó¿föVWÎ-I’$IÚƒ´ ´å k7€þÀ.ÀZÍ(iIëJZ´Cg˜$I’tWÒ‚03cf×·æ$Iów/}%Mþœdfï´ÿ4“$I’nHiAh÷$-\ë ¤å%'é~I7JÚµtž€-Ílðuà3à%I«¶äÆaø¥¤ïHZ¿ž%I’$I‘¡m VÞ–4QÒË’.´ð °8pð7àóqÞ@àC3› `f#Ìì1þäò äÌ_ãÞ_ÃÝWJzBÒ&íûxI’$I’„9˜ÀÅf¶dü¾pvÛXø¶™Ýnfw›Ù qlÌXÍ­ø‚€¤_S€qa…X¡4vp‡™}ÏÌÖ†ÿ׎ϖ$I’$)ÚÈ Α4 Oüpž™Í4ãã>Hºø>pRœ?[šÎGÀ̰>l»/¦–æ:³Î#ž0³ý`–P»Ø¸ ظ]Ò³föº¤=KÇ€5$]lbf_ŠïáLïò¢þw\PœŒ‹Žeh±7ðT ‹´púß•¶÷Fáÿ°7^ž¾,émà|à`3»NÒR¸ÕaXœ»°s!‚ qAq €¤Õñl·šÙË4ÏŸ«Ë›$éàn3{¤×L’$éhÒÅÐÞ˜Ù | 3³Q’¦IZ¿Ú"“$IRE)ÎM˜Ù§xëç7šo×Õ±«àže$M¢ùøˆwÊn 3{Ò‚ØÞ˜Ùê—uÞØ_dÀߦ ³ø|‡DÜÇèÒ±·ð€ÇýÍì¸{¶tÏqë©Ào€«p1Q¯*e™M€ûKÛ«ãîçJû&Å>ÌìII·¿–tÞyóø:Y1£€>xPè¨ØwnH$Is¤!iH,xR‰ðoDdô¥±Ø;/ö-õš£ãžJX<®Šù÷Â΢õGÀ×åÝ''âı’öþ%ioÜ*± žÝðpð73{OÒcTÞâ§Äušb ÿ'œ˜ÿw_¸O6 ¡¨;ïoñ <>ãÊê‹ÆóÜnf£J‡ÞÃ…^’$IS¤!iax'>ÏÕe“‹l‚²X«¼/ÒC› ²Vö``zu}‚*ÓûèÒþ§".bó˜÷»x=…yâù Ñ48¢™ KÜ­Q¯¸RÁ8ÜmÒÚgy¨Æ¡£êŒÿ8Š7}7õ×âJqf6DÒ+À©’޾‡gru6ú÷àµ%v—´GU¥ÈxüÅ«ÀvQ,«ÌÂô7ƒ$I’æH0•_‰O]"ˆ¯:Èràk¥}}$½KÓñ£#°C‰€Ç{›r-p‚¤^%Qó-Ü𞺻™M ËÀíÀ=fv²¤ÿàý6î1²^›â|3ûMûm…×iH’$iŠ´ $=‹p L^¨7&²úÓXHlKÃlùi>ÈrL·ðvÃÌÞ—ôžîøxì{ØPÒ¼UiœýñrÐ×Ǹ$Ý\þ/3=?°–¤?Æs<8û³l=Ñ¿ãMFÒx?m·"æ¢/0xHÒ8üïÚ²xÀæÎf65*vŽÄÀ…!²Á…¸@x«(ˆ%i p›¤«ÌlrŸ‰»m Þ¤Ò”lgà¸">!b=ÆV?C©újx|Ã$IËOãÂ^þ.ér3++7NÅ],—àA”ŸDÔÅyšs;%Ý’´ $IÒ¹Äâw>îbX°êð <‚¿7.FÏÓé–„º˜Ù(¼gFyßh`ñèZºþŒ™Ù¤Ò“tpc+®wåüC HIp™Ù#’^öþÇ{ƒ©Ôiø*•ºMÅG”é÷¿,²K$…Û7/J:o?~/žÅqpð‹˜ÓSø³mñ¬ âük€C‹"Qá¶Zwk´¨^‡¤Ûý›«N*iC`H;¶ŠŸ[È:I’t.ѲúvÜ0³^Yx¯ððB¹6€¤mñÅfŠ¤ë¨˜ìke^ŒíŽ B¸>nâø¿%-‹§ª~ <™àB©úÜ˃ñŸH£ÜírPìÿSÜûÜ2òcàÿ€ÿâÿ†î`Ñcª]a¥ºøq!$íßÙMxÜÈc’ö(‰°¤!iAH’¤ÓxÓÌ6ŸÝ‹„TScÂ÷]]Öz<+ ÜdkÍ 3û`vçÜ„˜¸ @Ò Ürr)pi±JÚ#ß–úE¸j „㮌ÛÍì%<¸ï4*ÙHZ‰†©›hhµ([¾Œ»Žö”´%•¸• âø–À±fv; ùžº/ÞÁtrçØwãÜóZwý`f×E¦Æ‹¸•åÑ:ßEñLÛàÂv0×q.pQ)@t?\ô4géIôÑ”!Iæ"˜®³î5 ˜DóÕ(ûÑPD ¾@Ã"R Q©FYOHtD“­Ö0/¾xÕÅÌ^ÃÖ¦xŒÆ};ŽÃk8Œt3^ca¤™ý ·\,icµÎÛ[Ò×ð¬‹5ðì‚qÿ’Fà—«ãYà_•Ô×¼Ýv£¹H*²cÊ,Vü1*›â.‘‚_oàî”ïך¯¤Ÿà›TšŠ —9…´ $I’t&±`M¶ž«7N•&[ÕñëÑЭa4Ÿ­1Î:¯ÓXàÆÖœAˆÕˆ·…{aU`rÄÜ€IºÒÌ~KcÆÓ0öáqà›’2ï\º#ðQX*¾ï p²xuvKdEœ ™-#P¶Ì4¼ÖÄœB)&I’tG¬íM¶âtÛP±R,#o²ÕœxovSþÌìAÚ©Òe,ÒÃkì`üy§ÿ7ùwÄøG¢ÏÇ!À÷ÍlJXu.à X­<é×Ã¬Ú ×ÅñÍÊ®J¬Eì‘NZ’$Iz*Ö‚&[±.Eãøˆ«ö-.i<ͧ}vZ6Êlpžmð{€(g½=°'n™ÙÑÌþcÿYØ=Æý¸4ª5.„dŽÆ,§Tß(Š[ ÆçÒ‚$I2§V¢ÉÖóõÆ…½Ú­±,þv\ŽèMóÙc"¸³K0³!’ΗԻȉ²ÌÔûW௥íû%‰JNÃ31â…¢úKz8ÄÌîŒSvî5³™³H B’$I2«ÉVKŠP-Lã ËÁx­b{€¤h^HtX5K3»l6ν¥´ù­â—R3«É±½^¥rǶޫ›’AŠI’$IëˆÌ‰WãS—è™P±^Ĩ}$½KóÙÝ¢šeˆ™rÀäËͬQ¬DÒñ¤@H’$éD-‡ 4Ñ3Üýi±%+E«ªXY-$ZÓÓc¶1³S"ÆcN#-I’$I×n¢Cd]$-Hc1¯PnÒ5•æ³5Æ·g5ËlöÔu¤@H’$™Ë‰R̯ŧ.‘’Xd¹.^ݱܤë=šÏÖx¿C¦g„$I’dÎ!õ÷)uœ¬&²0úÓ8>b«òvX-ÆÐ¼h”úØ]÷Ç`3Ùìà†¤@H’$Iæ.½P,ðO×'i‹ˆeÏZ”Ä´nIDATÑ0>bÍgkŒ wJ§e§·“t9ðàŸföigÏ££H$I’t:ð8">u‘´EÄšÀö¥}}[Ò¤‹v¨fYã9þ.i3àjàcI—g7“y‘„$I’$™"ó¼}uM¢~Bµ[cY`óª}‹HjI“®ÖV³<ïã±pp°¤áx÷Ê{ªU!B’$IÒ£‰ú cãóL½q’æ§±ˆˆ÷ˆ(7é*ê14%$ÆÕ,Ílº¤¯ã±ýðÒâ$/«Â¹fVt"M B’$I’tâM~d|êíª«ã#VÅT•›t}@CqÞSbþ¸Ô¢ñó0àI¯z·×3u$)’$I’¤Dt”œ ­7&Ü}i("6zÕ>o|6.Á‡’Ö6³º®“®¦Öƒ$I’$IÒf6ÓÌÆ›Ù³fv¾èï‰ ZÌÀ»U¾ö. +iÃN™pH B’$I’´Ióûóáàc\, ¼‹—Ã~ïöù"p8°±™}·+æÜRR $I’$IÔø'°%ð!.žžÅ…ÀËQ¥²ú¼™db’$I’ÌyDÅ­€“€Íì.žR»“!I’$IZI\º±­§Ó,¤˜$I’$O „$I’$IÐ#ZX§@H’$I’Î%] I’$I’ôLR $I’$Iç’„$I’$Iz&)’$I’NGRhXÔA¤!I’$Iª‘´2ð‚¤Eºz.]H „$I’dîCR?I¿“ô„¤Û%ý>: bf¯7gwí,»ŒLsL’$IæZ®ÆÛ!œ|8ºtüT`;I_삹uº½!K-'I’$ 4Ÿ™M+m_à?þhf£Zp™}ÌìÝÒ5NNÎ0³O%]Üßžóï®HZX XXº‹§Ó,)’$I’YHúÞ¦øw±}0p>¾¸o <+iM3{OÒŠÀL3{3Æ~ØÅÌv-‹ƒ``hÕ¾wIš×Ì>ë¨gêl$-¬QõYXŠå࣮™]ËI$I’”ùð³ÒöQÀQfvpº¤Gãø€-€?IÚ œìQ}Áh‹ü`§ªCÏKஈ1íüФyqÑSK,æ¯Ã€Ëâçp`/`ûNžr«I$I2‡æü3Ílb+Ï[Øxº´{m`|iû:àHàGfv•¤O»€Û€çÍìÑ—¾¸Ì̯Ú?£5óë $õ¡¶X‰Ê:_øŸÅc/†Åç­èúX}ÍotüÌgŸI’$s{ÿªuPÒzÀH3›\uhyàS3›^Ú÷ ò[3%õ7³ñfvCøÖ/­q¯ƒp¿û>ÕÇÌÌ$ХÉ0˜ÚB o ›¼†/ü7RÃÍlR[n;{³îxR $I’Ìy Áá’tp¯™´(n!èSçÜêFoã¾ó‚)ñsq*–…õû€ßIif÷ŽVÎv–“´6°¤™]Ç׆ՈWèâÙW§±X˜?†M ²øßŒ[†#̬½,="Í1B’$IFÒJøú“fö~쬿ø °lo 1³ZArÓ€…ª‚öÄ¡" ¦Çý߯]«×KÚßÌî~,<ˆ›á‡O–î·pK».’ ¢¶5`` ›ŒÄþ»€?BÀÌÞkÏù45ÕNºO›I$IÒôð/Üܾ°”´ƒ™=ƒ „ƒcøÏ¡’¶6³‡€ÍÇê\zðž­poì» 8RÒ:föh8ÞÌFÄñ_—˜ÙX`¬¤Ý€%Ýü _|_1³OkÜïcàÒ6|HZFÕB`5< àC*€û¨X^+§qviAH’$IZ‡¤þÀ:fvŸ¤U€óp+€€Íìl`n ØÈ̦Hú  ¸1þ¦¾&€™M’ô#à°+î¿ÞÌž*7÷åïë™ÙI_Àû Æç—}ñ7å¡44U¿ƒ/:}ÍlŒ¤7q+B‘Zxð0ÍÌ^«7W3{]Ò‰¸5âk¥ýÃñE¹ÍDe-°2 S‡Ñ0ep8uR{(=â9R $I’ÔAÒçðžkàQûïÿ5³Kczá¦î­ð`ÀWK‹ˆ÷0Gó¿,ZçvC f6!¶‰{>‡›Ð‡Q©Q08JÒ/ß^de‹L†ÇÌìUIãÅ}šÄÌ.–Ô_Ò€ÖšéãûLm!Ð/†5•2øakî׃I B’$If°°²™ˆŒg$íif…ÿA|_/|,^%o_IKãcs3{¶™{ ¥\ðþ7z3›åËœ}p°8p‡¤p Áù¥L†¿áV…2ý)Å 4…™ÚÔñhÕ\2¸ Sߣb¸…ŠÙŽ)ƒ=‘´ $I’t%‘‚·.¾-‰/À/·´°¸Íp`&°@ˆ„‡ðÃ…@xø:0(]¼.é4Ü àùÿoïÌ£íªŠ4þû!F‚@À Ì ¢ˆ È`K«8` Š´¨iµ‘F#vÛ-¢ ¤é…‚‚B+¨Œ¢ ÈŒ"‘QÆ÷’D†hˆ„ê?jŸÜ!çMäM7ù~kÝ•—s÷ÙgŸ›—»ëTÕWÕkuÓ"V׺8SÒ‰d=‚=wo-ã—G{Ÿ.o:™|°èÿ ë4wTìI=I7-C^î%7þ+HÕB•$øørš {Œ1f9Ž”ì]DƶÿLôÙ­©ÉÐx²WÀndᄈ¸3"IºŸ¬)p›¤=]€Ó›®Ñ ìXÉø"â/’®*×½ŽÜ@×! ðôF7Ú‡G–×"2\P…7æ9 DÄÉ}̽”4&vªÛ´‹dpKê%ƒ/-ò¼dp&#/ìD¬b0ƘÁ¦<Ñn Œ‹ˆ‹ûÞLŽˆiMçŸLƽ@£aίÈ/ìãÉ'ô$í”9Ž—t°ðgÒ QÑ L4¶Ém>¦¬ïIÓ( J¢Þj5Õg3š[-£ãåÕBD,‘4‹ÜÈ{mtÏ_—ô I{°¼!ÐÉà#½]à ‡Œ1f04¬æ· ù$ÝMö¸¸mÜ6dÞƒq[7­yLQ OJ'Iý¸"—»\ÒîduÀcÊãÉ.‡Ç×JÚµÄû»Wû–V¿Û‘I‰}.“t@»S9Öb ”ä¼vøû ¹¡7«Ñ³dpÝ2ìYòé&.ƒ•dpÑ×`^ö cÌ °)°Ø¬ù:da[2Jè64¡­„î-¤ëÿÕäÓÜÂ6-ýÀîåç.à=M“t éxެAðÒ-Ù,‰ˆøƒ¤Édøb1ðÇʈrÏãý‹aT½6V/ÃæÑ žGØ»I;‘Žøìm c:nà-½$½}ô,lÓÖ¡ð>ào¤ápcu°xž'¿gã%msÊuh<áuSÚúLîôéˆø®¤™À—I‰á¢¦yªë=\5Л.’ÁWQï Ø° {ކdð"¹3jº5šÑƒ=Æ3tÛHzé¾ß¾¼‰ˆ;H)âñíbD,-›÷v4’v%¿ÿù’nŽ–tÙÞ÷Ýd¡ È ÷²òœ2ïc¥øQ¥Ùï¶ŠˆÊ{1 $£gÉàKʰJ28ƒVÉàý«¸d°±Ác‰.`màsd¡ ë€ï’¥w!³ô{*°³¬³a©!ð6à€oFDÕ®ø#ÀOɼ€§Iwüw s$k߄ے »ht ì‘"»l7¶)çŠTÜKzª.ƒU’àusšŽÅcŒYQJéáG#â×5Cn eŠËš5…º©’¶^Kºãl*tDéLøzIë϶'êõõ„_kºîšÔK·¦U2Xy®kúyvSì¼XæhŒ1ƒHU:¸Î@8¸YÒeÀoÈD½µ€—‘ Žw·öVÊw …}$m@½7`2)\Êò’Á*7À’A3ê±`Œéº]$íMë†<µ'Ú,,´.ð{J—ÁRⸯ2ǵÉàæÔ{Ö+Þ¡µË`å ˜eÉ é{Œ1fé"ëlZ~î"½òœ€o¾˜‰‹d°.Ip ’Á‡HÀŸi• >hÉ  ñûbÁ3$HÚØ;"ÎŒù"âà”XÏR‰Ph– ΢¾Ë %ƒf0±Á³j!iK²záhÎë#‹ÕI×*Ã¥U2Xõ¸/"–÷šÍ*‡C ƘUI»ýö#¿ü>]Cx½‰Ô{6¥U28ƒVÉàLKéƘBÒ¾¤a°;YPHÀÏ#âŒA˜{M²·B]’àø2ìIÕ›%ƒs,4£{Œ1+'%»ÿ Ò0Ø–|Z‡üÒ›G–"È|èY28–” þ…ÜøœI£€Ðüš)1+ˆ cL¿‘ôR² ÒQdëã*»ù»äñd͹«›Qo4K«|€³›~¾'"þ6Ø÷cÌa‚1få@Ò+ÈJ…Ÿ!K!¿àš¿ä–Gw—|„:ÉàeìCäÆß,œ‰%ƒfÕ #~Çm ÓD)µ{PDœ:Òk Hš|ø8iôô±”ìað¯À±åØsd¡™,/\ávÇÆt8ö 3)®òÝÈšø³#â1XVóÿÝ’FÄGt‘#ˆ¤ÞO&öõ]!²ëàO_Ðè2hÉ 1Ëãƒ1£IŸNn'ŸŠß(é­1½ 9˜.éÆˆ¸„–9R¼AÒÙdA¡Šþ|Oˆ¬88•ìªxc:›1#½cVI›HÚh§°GDì{’qóï-{3â>àೃ»ÒQÍØòçAdÂ`sŒt)°˜ô$ôF•—ðYà%D«±Ðn@Œvn—ô᡾cÌÐàƒé$>F&ÂU|•,»¹Áÿ øð½²1í‹I/ÁØÜÞSsÛŽ]O>IoܵÜ‚¤ué¹ Qõÿÿ¯@Kûáò9Í-¯kælBÖ)h~mIv?܈T;üDÒ>ä¿Ã3ƒxkÆt2áA°`†IkK#bIŸƒ—ç=¤PñVàôˆX,ôà02\pp p±¤Ï¶«YÏ^ÀÛ€×4ˆç%=M&ÞjÊfý*êë ¼¢ [Ì!“/¦UQ° |×÷÷šý0 ÆiûJºÈFcÆÔr p$pí@N’ôràõÀM‡×¦ÕÕ}!p´¤#âaIû“ž[3"b^ۜ㇖VÁíôsVŠò¢§&D•!³€Fq¡Ëi-;übŒ²ED¼@/„1fôcÁ 73ÉÒ¼µ‚¤ï§FÄmoUvš­î4ýGÄÝ’‚¬Ö÷pñ|ø`gIãÛZö~¸>"~Q³‘á‹twƒ€¤Mè¹ ´–¾8•FÙá¿÷z1Æcj袸ú%ý¸5"N.9™wd/çª<öN+çW•ýÆ5?8‚Lš»RÒ;"â)Iï> œPd}Û¯Œˆ Ëy;³"¢%6?X”&D[Rß„è¥eXsÙáßÒðÌrÙacÌPcÁ *e“Þ“ÜȾ¼Žl®stIRë&“þ ¸^Òñ0° pWÉlO–׎Àÿ–cWç5yÖ.Ç电켚ô i_-émÀ†À¤vÿ:à;eÍ{—¾øO")%Šë’'ÓPUe‡o΢a<䘽1+%ö ˜•I;ï$ÙGDHº˜|ò½ø%Ùñﻤ ¡‹ 1·K: 88xðûºk•pÁ%Àûh—wHúYùozDÜ[ÞŸ ü{Q1&éeŘ8­¼z⇴*&zûV#3÷ëÂë–aϳÈÿ\\vØ3ʱ`úDқȧò#7EÄÞ’þ“|*ß ø³¤#âAÒKðHDœTΟüQÒçÉÚüëKZ?"'å‡Ý’ö „szYÊ9Ài’¾K"b©¤wÇ‘¡„[iô ">Þ>AD<ÕŸ{Žˆ…5ŸÃ:ô,\½ {”Üøï"••!à²ÃƘ {LgPž€×ìE§~&ù4=8´ä ì³ËþŽ" „窓#â6Is"âjIsÈ<„#âÿ$}–446!›ýÔRν™ô[ŽÍ'Û E28‰zo@•Ÿ°¸—Üø/¥aÌ(’KcŒé fh(In;’O´Éb7ÝqóæX8x;ð”¤K"âó5Cg›TïIz#iï'i;r³_T@µÍ±.™}_½¿-Eþ?—4Ø ”9îÃÈ2¾?‹ˆîþÞk;’ÆQ/ÜŠ†dðII‚¿¦U2ø|ûœÆÓO:"·ÈBç2…ŒÅŸKÆáßœ.éµÕÆY6ï§È‚Aûó€/EÄ=eŽ Ëû;DÄ#=•)&7ôf÷øÓ¤R` pi˜4»ä»€$}88„ü1½éýÍÛ®q Ðgf~D,”ô:àÙ¾ÆÂ2É`]X`SÒ‚_ <@nüב¹•7`~®aŒ1Ä!3¤Ì"7è“#âÈ~À _"å{÷_þ‘”úí@nðûÛWR¾^bäÝÀ[ª¿DD—¤™¤,ð[åÚcFÄyeüR­p<éYØ?"•)¾\ éPÎ]øpzn¼=R¼)S¨— Ž/Þ)ŸÃ 2dÒ,\„1Ƙl Œ’vÞAndë“ölଈ¸ªmìêd8aQDÜ ‹›bù·”¡«O4Ú |x]QÜ ¼‹TÜTÆü¥Ëífù2Å—IÚ¸¯¬ïjÒcp?i |­‡DÁfã`õ²†«I/BHÚ€ž%ƒU7ÂyäÆÿàG4 -4ÆŒìA0½²ùÔ<¬Ö·˜4.‘45"Îôwd(à>`{IW’Oã/®ú·—$ÃýHoÁnMרÔ¹1Kú%°3¹‘/>@jï{c&0AÒ„ˆx¬Ìu»¤ÍËõ^n«E]0“ÜÌïïmâ"_Ü´2š$ƒu†Àzå´çHcjp>­’Á~I1f„±°²#iCòéyÛ¦×:±c§v/‰ˆ‹›ŽÝ!éYàä¢ €”öý[DœQjñÏ&õ¾MŸ"7úÙdái4Z÷v%MŠˆʱõ€¿FÄIÿ SŠÝF6-º7"~ּЈxVÒ[h« Pê ôÔàçôÒË (!–’*#` ÉàcäÆßE¶_n– Žª> Æ3:›iaÅ™Fú¹‘]DnÌË´3¹©¿˜ï-c6)…{šµù?Nvæ“ÒºKŠ$ð;À{I¡ x2"+×9¸IÒýq*i4,%€#ÉÒ¾{•õÇJz¨ÂÓ×ÝdDÜTw¼'"â«J&Sï Ø¨ ]BzGfíš›%ƒO`Œ1+'ö ¬tó#âк7%í \FÊ ¿¬WžØg“å·#KìYÈ§Ô ˜D#?`qÓ”ÒháÛ l&é%ñ·ˆx@ÒÁÀå’n,a€9d££»H«õÛqMÓõúª(Ø'’Ö¦gÉàZeØB’Á«h³-4Ƭb؃°ŠÐl)il‰ñO"7ý;J{á#È2ÄG—ñ•«ÿyI³ÉD{í‚5• ÿ>²dðIå½ÍȺ¬È'ôÛ"â7’¾HæÜ^Ö÷ûˆ8˜DÒD꽯,ë’ÁHUBå ’¦GÆÓ8Iq¡X“,%¼9§ŸAÊ ç‘EŒnèáÜe +$íL |8EÒÆ¤Çáp`_X–ðŠ(ÇOm[ß6ý½™"9Ü’å ­—•aÏÒ þ€†7àK1fåÀ R ÷Ì~œQSë.ðúNïªÞ“´5p™ÓpxD¿ÙØœVÉàLàOÀ¹4 ,4ƘUŠŽøÎ_é „RÉðà_Èû«îñ˜ˆ˜¾óŽ%kÔ…&”a‹9䯭’ÁA7LŒ1Æt,ö ’^M†"U—¥Œ¿ÞÏy*‰b»!0…¬˜ð8$ÁKi÷Z2hŒ1¦ìAJâ/o'±4ÜúKg€EÄÒ¦sDö¨óL,Ã*ÉàLà×´JÚ»2Ƴ’cÂPP6øýÈ~;“= DÃkP18ØMR»dp\ó4 oÀu´JŸÃcŒ\ìAlŠ*à`Òc°ºí†AEß*Î% ßgÒðÌÊ5cŒ15؃0”RŸ¾@**ÆÖŸ4,´³€Ï9IÐcÌ(¡#ê ŒéôÁZ’N ËXüPûóÁVã>\'i³![¥1ÆÓ:"Ä0š ‘òÁ§€édH`>™ˆX¤´ðù^æ ¼¸SÒC³TcŒ1f@ŒzÂh107"ŽŽ«JC6'š ¼ªéÏ-Êk"†•1†LJ<_Ò߇»J¡1Ƙ¢#<£Ù@¨¥È*¯›Úß/ ‡ i5 &“U §uÞ,éÀˆ¸sXmŒ1Æ´bÂpSÊ?R^7ב´°±$¹Ì±1Ƙa¦#’W:¡?DDe@cŒ1¦†Ñœ¤hŒ1ƬŒt„Á‚1Æ3¼tDhÛ‚1Æ3ü؃`Œ1ƘìA0ÆcL-ö cŒ1¦')cŒ1¦3±`Œ1Æ /ö cŒ1f9œ¤hŒ1ƘZìA0ÆcL 1cŒ1¦3±`Œ1Æ /ö cŒ1¦3±`Œ1Æ /ö cŒ1¦3ÍÂãÀ“#½cVó˟Ƙ¡¥#<Šèˆz ÆcÌJ¤M€Ý#â‚‘^Koü?Ÿ x³d­IEND®B`‚openchange-2.0/mapiproxy/documentation/pictures/mapiproxy_error_001.png000066400000000000000000000116051223057412600265550ustar00rootroot00000000000000‰PNG  IHDRówY©1sRGB®ÎébKGDÿÿÿ ½§“ pHYs  šœtIMEØ6ÆRŸtEXtCommentCreated with GIMPWàIDATxÚíÝy˜åÇñoõ1÷ÁƒJ¸ÅD0ȯU‰LŒ®Y}6n²OdñŽñ@£ÆÅh6›Ý51ƄĠ² ‰GÆ›ÁP9<ðæ¤gºkÿ¨é™î™îžêkººù}ž‡‡îž®îª·Þê_½o¯±~ÍJÉJóæ_çè‰Ç«$DDD²ÐÂ… ðlX[«ÉRžàƒ©ç=ÖõªFÈã®=†ÑóqçäF”ÇÖ{#?î|w×c#döBž„?îúâ®—È{,câËkëûâïHešÌ|G*ÓdÖSÒËØm¾ã© væ;Ê÷%<ßñÔ};ë)Ë6¯ÚfµÍj›uü6:Ÿ©0!ïÃÎÇ.íψˆˆäHË\DDDÒï‚)å O[]]ÍîY¦0É´DÎU[ºlEn·Ì?ëgzCÒŸ·íµÛ;úúÍl}uaçóÑ3oql9¬ù˵T;7áÏxë©+˜:w±¶6‘,Ñ#Ì›6ÿ€’±óz¼¹áÇ(;òröðsʺÜA>lÊõìXe=?ìøè¡þÉ›wôxmÄŒ›ØÞä#O¼ ØöêmV¨Ï¼ØòŠìcNº5%óÿÁó7öxíèÓïìuº÷ž»€‰gÝ£Z,"’Å*«¦°~ÍJ[¯Gõ¸ÆM‡ùƇž—uyƃ<Á >ýF¾6ý'|múO¬ýv[Óžy £SäãO»ƒñ§ÝÉøÓ¬ßð·«v‹ˆ$‚a ïxƒtÒ5Y½b6½tSÖÎ{gÏ] )¾ÑˆˆôÔ½›=é–yh w»áTZ…¶Î¾Z}og7{6 ¶Ì;Ûì E‰ä¡ÇÏã tÇÝnHÕÕÝì’IÁKÓ‚ÇÌED¤o‚¼{¨'Ý2·«|üÔ¿ÿ`ØIpý+#‡ÀÀ ¨{ï~v‡œ7xâU`a­rèèf7`è±×òÕ»÷„×ý¸ C§ÞÀŽUwE=nø 7òÉ›wðÉá—§/M‹Ç˜“n壗o ; îˆêÛ{òmlzéæÝìÝ™uê|ðü¼ÿ÷ðËÓŽ>ýN0 *ϸ‹õ+n`ý_¯ïñÝμ›÷ž».ê p“fßËêg®aõò®£cÏY„w®uÜüí“à¦Ìy GÌÔ¹‹Yõä|j—^¡ãæ""i­õO7»aš¦¹am­ZÑ  ´!Ö|k m³ÚfµÍ’šV.˜Ržðàjjj:oç:!ïÃÎ×t;W‘>ëÖ¬‰P˜‹ˆˆô¡êêꔦÂ\DD¤Eõ,YÏ\DD$Ëu¶ÌW-ý•†ˆHÂÌ(EÒO-s…¹ˆˆˆ(ÌEDDDa.""¢0…¹ˆˆˆ(ÌEDDDa.""¢0…¹ˆˆˆ(ÌEDDÄYaîr5SVþ†J\DD$ÅúdToþ§Œû}\®46T±éƒûÈÏ÷ªôEDD²¡ení ;ìÛ´ùö()­¥‹ùËsÛUú"""ÙæÝCK xÝn €©S·RûΖ<±Yk@DDÄÉaîr5âv-Ç0ÁpN³€k¼Áþ×û|¶c¿Ö‚ˆˆˆSü_ù#´ù ߆ËjÁD[3œ0}'LÛ̞بµ ""âÔ0w»–àqC~¾8|äãq[¿fþk,}úSvïnv\ÁTVM;¨+F´åOw¹8½ÜÓ5©ú܃½Þê7!¾åé«eR½Ìâ0P¾˜@;x ¯¸hZ€FŒü!гNù’“¦oåwK¶d¼B‡þËäÄÁPésyûòÇ1“õ6Û¶‰D>#•ei…¾–‰ßõkV²~ÍÊ^¿?—êšS–#ߦKÓüxÜO` ¬Ô x1[›xýe'ž¾¨Ï.0L.ûa-ÿð(.úîH.éóB ­ÌÁÇ™ä„yçsZ½Õ6‘Û˘ ëÀIÛJ:æ#-aÞ¯ôÚ[”•EÅüqI€ . &àÓOà°Ã௯㬳?å˜ñ›ùóÓ‡ó£Lpl !´ð£½žè´Á×Ö¯YVáb½7‘ïöZ÷ùëþ™½íEÆš§ÞÊ!Òü§ºÜí¼Ö}~씳Ýe³³ÀÍá-À`$;Á—^ô×Þvß™;ÂQ­óDVP:[]3§·³;?¹|œ.›×_®-[¢Ýå™Þ JÕoe2Ë›lY%:}*×YJÏf//XB›¯™B7xËŠÁôÎ<%@aA Ã\yL;¡ð>(Lû¸ðüM ¸g²ì6¯ j•{ª[é}±lj¥gnÙÒ²}âÝýçÂïC¬iíôD$òÝŽk™çµÿÓùEðzaÿ>(‡ ¿ÝÄ–¨¨N^ÞÌœ¹×ê}gTàqíæ_ú&?¾ssÏEAAžc÷À{;a!ZåŽ4m¤“¯ì~O<óíózÛ“ÙPí|§ÝË)÷XËïFm÷ø[÷eK´ÜPo“-¿xË«¯¶ »ËÕ[=MÅ|¥j=%³ÝÄ»MF µÐçñ”G¼ÛA<¿­v–!ë/]¿1ñ2LÓ47¬­MúÇ¢,o ®Ö)̇¥Pìo€Á°öPuÊ(Î5ŸÆúx¾v94íÀáÐÜuuøL8aÎ%|sö,Λãücç’Û-]&(¢íÔé–.[AMMMêZæÞ¶Ç0<ùnhl‚Ð+aÜP‡I[¿G­óáÚ±þoÚÅýhûªŽ¼þðýóßeÑ£#9óŒ1zT[ED$-­Ù\’’cæ¥Þgñ؋ۀ’|ðûÁ×f]VÞ …IÇøøåï_á´êϬóâüXo°nåê)*àÀnøÑ…ïá |Æ‹/mÑÚ‘ŒÑ„ˆs·Íл×I Ã¼È¿Ø òÞz‰¯ÍU:Î'Ù^¿T‡)©ÓÅ šîÅ€¢BFi45Y­r#dw¡Øz>ë;{¬.v7Ö™ìÁ–»4ù aT ÃØ·¼pí%¯sÇo†sêÉ#p¹Œ´†Z÷çñ‘èMø£íñÆ3ˆC¼gwƺo±ÝR9ï½}V¤!࡯u‰VN‰Ô/»ßë¦NDÅî´½µ<%žrÈÔ`<ñ.k<xdzàqH˜—²_kù_\í~hnéjmA^«^ÈãøïÍŒ«¨`à Ûq—`Ý8&´;~çNQ‚«¸ê›9ÿÔxàñYöÜF¾uvß_wžÌ v>'ß—ÊAÝ+g0‘xË"ƒôÅ .‰Ôt|·:’Y†T¢’ì@4ñÖ¯lŒ§·zœìï@¦¾‡„yaëoi7Àë£ ¯£UÞÌ®ÿðÏW{ 6~1€›~fpçCÛ¬VºÙñà€êöBy|uÍ †óO_Ç—Ž`öéGàõºQh±î@”̈XÙ~BY2="NûÜL–i¦îO©yÖ,é;ÖêÛŽJŽ…yëhkÚÇÅù€øººÌƒ­ó€Õúþè‹` “†A]}ïðoëj‘èõõ0äÜEyøë|\>wþ~¯¾¾“gv\Ù9ÝÎû“p ÷zS1ÚR¬Ö|²å’É2ÍÖõy0-oª—-Õe`ç°˜ƒÊ- WÔöwümà2Áíîè^ǰ.Ks…ü3 ȇÙÓ>ßåâÑ%‹™1c¿ÕÅnÐõÞà´íí°o/nÓà€JûÁ7¦lgÉS[²bÃÍt—RèF«k2Òª}=ßé:ñ.ÕË‘­­ôlœgµÒÓ7¶}¶× ICË<кšv?ø|°Ÿ¯ÛÄÄèÚ5X» . Zaùo¾ä§‹GÒØÚ@ÓŽ™œ=ãU|Ÿƒ?ÐÑ ïx?&˜ûñµCÀEí0ùÈ<õ«ÑlÙº—Ñ£úg4PÒõþXïKdÀx¿/Ö€‘^·3F<ƒF$3L¬rêËA]ÒQSõÝND%™h’<%åÎÁxìl{‰Ì—Ým<Ú:K÷6 ‰Ih •ò–‡Ùÿùãx=àqƒãFm.x¼0¸ŸîMÍPߘ¦3;ën”@¿r˜sý^^3œ«æù³+µÖDÄ­L˜dZR­ÔΣ´ÿF싺z.Ó´úÜ»ßߥã8À»ÌŽ÷˜FH+>ä½`½¿À >Ÿ‹Ÿÿy2/¼5ŠþeÍ”•h͉ˆˆt“ðÙì bÕÖøßÿyƒ–ÖfŒ˜—Gjº1ßíqùñµ{ØöyÊŠ[8®j3fŒÔGP«\r"̦NÃðáÃX·~gÇùoFxN›Ý2Ûìö7¢<7C&0ý{9nÒ¡Ž¹4MDD$gÂà!Erò•¤ˆˆH†¸T""" sQ˜‹ˆˆˆÂ\DDDa.""" sQ˜‹ˆˆˆÂ\DDDa.""" sQ˜‹ˆˆˆÂ\DDDa.""" sQ˜‹ˆˆˆÂ\DD$gyT"©QY5M…`Óú5+U" sg2MS…Cuu5555*…¹ˆ³mX[«Bˆ`é²*‘4Ñ1s…¹ˆˆˆ(ÌEDDDa.""¢0‘¬VY5­ó_÷×c=‘ì§³ÙEr$ÈC¯Ýîþ¼·×ED-sqPƒuS–H-r¹ˆÂ\Dr(ðEDa.""" sé+‘ºÝEDa."j»ÇÑE$7èlv‘ ôhÇǃïÓñs…¹ˆ84Ðí¼® É=êfQ˜‹ˆˆˆÂ\DDDæ"""+'’bK—­P!ˆˆÂ\$[UWW«DDa.’ÍjjjT"¢0ÉVº~[D2E'À‰ˆˆ(ÌEDDDa.""" s…¹ˆˆˆ(ÌEDDDa.""" s…¹ˆˆˆ(ÌEDDDa."""¶x.\¨RÉæ0×(O"""Ùíÿ¿ˆáÓ|ƒÅ IEND®B`‚openchange-2.0/mapiproxy/documentation/pictures/mapiproxy_error_001_fix.png000066400000000000000000000125731223057412600274300ustar00rootroot00000000000000‰PNG  IHDRXíúm2sRGB®ÎébKGDÿÿÿ ½§“ pHYs  šœtIMEØ ,i+/YtEXtCommentCreated with GIMPWÖIDATxÚíÝ$e}ÇñïP[þÑDJ£b´Ät—Û9vÃíVŽ€p§+r€$¡!ÜÁÁarÀYÃ$¢î„å‡Å¯r‚ºÊF.pÖŒ§è ÜÉž©h󣢩P‰š¿'ÌÎ\OO?ýÏ}µ¿;eêCwÈ»Ïï¼3øÞ—6÷…ë{6Ü%ïÙpWßô{vuÂuÍÅ÷ÊšÜ+""­‡?®\ïÝn”Ýn”g¸¬÷ØÓ÷wÂõÌË’µ{HDD¾ùù?í{Þ÷\btð,ÞÑ ×õW?*ë·<*""_ÛqAß4 ·Ï™ŠB‡lÒp­`³R½ÞYÁ;ϸY~üôrð©ÃË;k.UH¸‚uåÛüYìßÿè£÷ ôÁ>óÀe}}°OÝ÷QåóϾâá^Ût«ØoÜuqïïçmÞÕ×5ôøç6(ç5»õ˽{E¬^ƒÝNºŽ:n³¾lãÝ›NÙÖ«bEDþuï§{]EóÂb'\W¯ß!Ryþk×8›÷š‹ïüÖJDÈv_XÛÍÝ7¹ÞtÊõrÌäõ™/7Ø;zf§‚^þæ6Ž2yÿ•_èý~îæ]4*®á uRÁšú±kä•åòß/ÝÞ{ìèñ­‘Ó¾þ¤OÈ/~xkß…®îE®`õz¸‹ &¿÷îåçß¿Yþå{Ÿêýí­§}2²ò:vÍMòÓoߤ½Èuh÷öÞïºiðÇsòÒ“ÛäGO¾Ð¼Èåäu·Ë ‹×ÊóÛU®§]0/Ï>¶I¾ûè•;ý¢{dÏ®+ºfBº¢>¢õ¾ËZMäŒÊÓ÷_:ÐEнÐecÝU_”Å;.è"øàÊ…. ¨TUªmA­Ýn·ØÇ`/9p£´O0Ø Çƒ½øìeÃêW'þ&W«Õê}UvÕ«õë Wˆ| Lë/¼›kD€gº¯½&AÀæÐi̼‚ðgffÆË| X•§ +-ƃOzìs —ÐÀеC?QdT°@À `€€@À€W|“«ÄFÇ'K³-IâXx ×2…Ò¦-Ûd~ç;åØ"VEá )SeW•ŠozzZ6mÙ&Íf³’'já2çV[Ôª(Xý”­²+{×]Õ<†ËòÎæ›“¶¨;µ[ýp`¢è<Çpt»>`, tïÙýÏçr‚?¶À¡Q†eø^—î­‡ƒÿùâsÞ¨VAPé€Íª"Ê¢ª£²l‡ðãQûn_Õó‹~ü¹Þ®ÒÍßä˜[¦¯ªSµ>Áõ6Ýn›ó1jŸ‡ßáè^ô+YÁšüÁ›TJq¡—Õ«µIØš†—iuhZIúxûT¦w"¶ÇŸíqiS©'Y—,Û!ê\KºÎI·¡Œøˆë©{…NÚ¿Byx›í+øòÐ÷äû O[½fÝEZǬÏÓùÇíó2^ÿq}¤}ûn2½ë@S]Irâ»Z7Ÿ¡£z[ªê›z<ü˜é‰UÔ*¹ëWÔø^ÿ´óÏâÝY!Ö¦ qu±$‹Ä´+ ‹ut½Œ¸yÅõŸ%yLÕ­ãj»†Qç½êÖµ‰ïõ×Í¿JÄG\îPÝ㺆5Þ¶zò±m¾¦ªU•$Ôm׎içoZÙ‡_\\_˜5 Ù¤Ë6ÙnWí\Öc»Ön·Û&ßm.òw —¤ÕjI³Ù¬Ä÷¸Ëø}õî>¬ê…U;†‹|\t×izzš¯Ê€õz€ØGÀ€/Ú>XFN/î«g™û a𙙉íó ö TñdEñÌ®[+³ëÖr,bè/ô6è"OX `€€°@À `€€@À€o#ÃXè0îµe¼‹%€Šì0µh뀀7ÚÌ캵V•­ê.“Q·ÌŽ»w½nžáç›Ü~<ȶ£ì0W¯× 9’Úˆ¯Æˆl ÕMÒT!©ººIå©ê 0™§júðtªmN£Ñ ‚ S_oÉ£îÚ9ŒÛ8›l/€êáS@ÀšU´|@ŒML ïSº‹FQÁi2­nYÁþÔàE.WË€nvŒ kÁ&«.~©æ¡ª^M–·,Óå@i»€€Í°2¦Ò@À@‰ŒML°àë5 ž°@À@± ås°¶#Ou$ìP´Z-£éæwα—°¶šÍ¦vš2U®>ÆI`ìwí(âæsÓáy¹œ7ØÌOŠ aßz&ïa™‡@Ž ÕàçÃØ‡&ËWW¡›/ˆl¡p°–OÞ÷išÐäx%`KóvOUaw}ë“*[WE½½Œ;9uó2­ã~7¿é(iª¶×-;j?%]?“v¯T˜ªÖ'êß6·&"Œ Ø\…ižn=£ªtlçeR)™l«ÉúÚTkIo­ã¢;CõB Û×6m’&Ü’ŽüFw[Ê·“øõŒª²M:]Úçê‚ÉõºEUt®÷y*m›‚€­¼¸Ê6Ét>_|toóóþÂ[´+øT¬åÂ7¹VVE¬ŒÂÛªÛv×Õ¬ï6v=ÿ¨þx_Ç Õ,lî‚#/·žQŒ¦/ïß«œÎv½L×צͲ¸µŽÉ2TÓ¤Yg]¹Øö¨yp»¢ò©µÛív܇ùGÇ'­>ì¿°¸¤ýjëÂâ’Ì®[kk{åµÈ¬Šü<ÓÁhâBªˆ¥$y‘L²IÛÚÅ€+ªu°=.ãž¶•^’MtÍ€(i¿køÃ(%î q£{%mSÛ¶6Ù·q_nˆ N“1fÓ<léè|_eŠ:PŠÉð…iö…«}j³ª T5½®š-k×  §Aç²"Fu_¤R\¶µË¡ ³~>ò¥ÐÓÊrà ÛõV7G‘æµßòö"äk¸H“ФQÁæ.d£ÞŠÅ='nz›AB¢NÛÀp0y(%êÂ’j4/›ÁO\µµÉ2UÇÒÖÂ`/å3”Á^€¼w1 ?Š:ØK)> ¸x O¸‚.À!B¾1°@ÀX `€€tnEÀ€£ã“,øª`½|Ñ Ñhк*ÏyÀÖëuZ|,ƒ¼@}°@À `€€@À lø¸×üØÄ÷°€ #×å{~Ýwo÷ܽ^’åªæ €€Í%ßw UÍßÅr¹Û)PÎÇ"XX\RþmvÝZëŠ.ª2 >¶¼oïgxºªR·œpØuÿ^¦îqÝv¤™GT Çí ˆêõz!Ç9ñÕQLH–QáWñE=W7O“Çu§j½lædãÚ(¢":âkÆi^mT!ëúíô0ú:³X&#š%ؤ¢Þv§ Rݲ² רj@9åö"—îm+KT°™„§êBMÔEðô6•gÔ²’Ì38½Éò£æo².Áy§Ùnî"°ý˜“î‚QÜßÒÌS5U×…n¹&ëb;‚ ‹X ,°X¨ ¡|Öv´§¢Ž¤€€ŠV«e4ÝüÎ9öÖV³ÙÔN“´rÕ cX56_óEuŽ1οrÛ[«Õ¬’ªÖ·ýáÛÚ¨pÀÚ„+ÐE¦ív;q¸êîn ú»ÉmYâ^UIÆÝÞÆä–2á·ö¦·´Ñu¤¹iûÙÎ_·]6í¤ÛO¦óŽ›§É; “õ1ݾ4DZÉ-”P€ †l0\ƒ¡ë[ÜíWâÝv~q/Q·ƒQMo{KÝ6Ú܂Ǥ=’Î?é-|¢æ·I—i:`zšy&Ù6mΠï Øpåê#\mª§pÕ`z²Úy^%YGß·øI&ÏË2`ân¾i²qÇq‘;Ö“4•kð†IÃÏö]uK›ªò}‹Ÿ4—n²¬æTËŠj?ޱòÈÅE®n¨&©\»¤ê*yøÕÞæÕ?nZzóöÈÃÛм¿ÖciŽcÐEiŸkTˆ&9Qm.œè–k[u‡ŸgsK›$ËVµ“ë[ü¤Ý?6Ûh;oÓéMÚ$nÚ$mgÚæIÛÉÔÚív;îÃü£ã“Vö_X\Ò~µuaqIf×­5ž§í:øz[çë9yš?Ø?yc’)Y®K«ÕŠý†ipš¡T°õz£]>eà–<~R€ê¨|Ç Ê‹á €€*olbŠ€*X(/Ÿ"h4´,Öõ ùŒ+x XnNÏDÓ ž°@À `€€-5à<`‹,e¨û– ‚…ŒO T `Ç&¦zÿ©ß6[ ›,+êñp¥÷{Ôº©*E“uµi§¨y†WmîùT»€;™ÜÑ ê–ÅQwÅ žüQÓ‡+2“;¾Æ-+É-¦ãæ“äþöIÚÉv©fl^ØÞ=Ö6ÜLÃU²Yt ·-¼1@Àz ×ËÓU“á[mn@yTö"—ªR ‡b’·èQóKú¾ûBUÛF,ã 6x‚.ïß;2áðÒ…’‹ªÎdlÞZ'};®j#ÓuTµ©ÍzS%Ù¨µÛív܃£ã“™ A˜¦Rí ø¶°¸$­VKæwÎM3’‡“Üe¥ ¥î"°}ëÚ(#¾É,,.°àC«Õ"`À‡f³é¾vaq‰–àL½^/ìÍT½\äjµZR‹û8Te¶[¨¶4•ç¦-Û ¿ý#|Ÿ´~N£Ñ(Ŷ°r]ÉŸ"€ªl­V«Ä2‹ÊW[±@À&8QŠtâÔj5åúwÿüOµ}ªùÄM«ú{ÑÂ×t² ê$Ë)ò1ŒáÉú„k·Û¥h¸îvøØ¦àüÊÔfyÚoÞGU%™ 6A¸FUjQ• ª¢óõüàz¶Ûm'Kp>ICÓv;T•uÜïiÚ3j‡Û/®Ômƒéöƽ[0Ù^—ó Ú5 Ѳ¶/é~×=·½.æa². Ó2ê6Ô‹\ªWy›PHû|ÛêÓE«[¿àv…» âú…M¶­;O›íÉÛ ÏêÊ3Û-û™™ôÁª‚%퉛æùÁŠ,o!µ.Qa«ÚŽao›ê­´«õðµ=ª6F¶ÝT°)B6m5éúù¦'«Ë*6«PŽêKî>fZM»èÎðð„ *_ÁFäQ}V&'Q8 tÏWM§zÌE˜n—‹(Óm³¿i{ºÚŽàãqëlsÜÄÍWÕgj³n¶ëÖ{e>@m¦·­ÚlK².I¦Iº^i·M·®®ÚΤšÖ=Ïåqcò{ÒuK{ £¼ØÇWeÀ‡ÑñI{¡Òü*ËÈXI*X€7eÓ5 /;¿s®²Ã“èÏÖ¡z½ÎQ>–Ê:ø°@ÀX `€€°@À `€€@À ,€€X ,°X `,°@ÀX `€€°@À Ðú›|­±ÞyJIEND®B`‚openchange-2.0/mapiproxy/documentation/pictures/mapiproxy_error_002.png000066400000000000000000000122221223057412600265520ustar00rootroot00000000000000‰PNG  IHDRîr•Ä2ÚsRGB®ÎébKGDÿÿÿ ½§“ pHYs  šœtIMEØ 8¨­pIDATxÚíÝy”TåÆñï­êªê½Ù ˆ„Å€@ÜÅŒŠ'£‰G'“dÆd有q!FcŒ{ÔÄcrr23&Nrmµƒ!ÑxH¢pCÁA@(4ÐûRUóGUuWU×r×êºÝÏçœ>]˽·î}ß÷¾¿û¾wyÍ×Å_0âñ¸·ˆˆˆÜtÓMT¼öÊz¥„ˆˆˆOTÌ?ÿimp00Ò^÷¿ø0Œ¯ûf7ò¼NL›ûurêþ…¦½#íMæëþî{]l=snoÖ¶[Ïœ¯³¶·Øzö/:ÿ¶[OÓyä0_ræ‘Å|ªé[l=ͤu±õ´º½vË}ú6ÚÍ—Œ<²™/éÛë°n²—¾9ÒÚJ]˜/­ó–ÿ¦¯êþÂu“æ†ß  cŸµ¸EDDÄ×`{ÞÅ‹óïw4)p‹ˆˆ”’ëÉ›Ö Í÷ûÏ¿ïõ!ó¯q¼¼ÏÜÜ÷zÚÉ׳ý/7õ½Ÿ~êe›÷-ŽZv§íelxô 柷B{™ˆH™ÊÜm[ @íŒKLØòæýÔ~)ßø! G\ZA{âq߯0`÷†ÄûIÇçàï>wë€Ï¦,¼€ÏÜÀÔ“®vü5ħrðv2ˆæRý×øìÓKn/:ß««¯àÈ¥w¨‹ˆøÌìy ؼq©Ï³å¼8­õ­eí-÷g¼¯?âÒAÚv¤‚öä¿Ë'“;Ÿ½ÅÔüÓO½ÑµV÷O&‚ö¬3ocÖ™·ñé%·ðÚ®Q©ÂR9¨­í-îìà];óZ¶ühÀwÙ-îý¯ß—ñýÈÙ—Ó¼9ÑÝ:jÎìÛt/£ç,`ï«÷dL;öÈoö½Þ³ñ®ŒïÆèþýû‹™-Ë Ç^= å}Èüo÷½o}¢Õ:iÁwl%êŽgnfêÉ×÷½ßþ—›˜~Ê ¼ýç3ZÜÛÖÞ1ߌʼnú[O_Ÿñùá§ÏzÆ®Ið9ŸMô"lz"±}sÏþAß4¯¬¾ €yç ly¿¼êÊŒ÷Çœ{wßëš–g|wÜ?Ý›sÖ7^À‚óïÓž&"ârðž=oAFð6´sîš_§í­D—yk2h×ÍüÆ€VwÊdÐ1ë²÷òìÛÔRA{ÌÜå`|üÊÝ|ôÊÝŒw%%ƒö¸£®$ýþ½_J¥OsU_ÿà…dïTWyJ¢«ÜÈX+R]å)©®òtÛÖ&‚÷§Ý”q/_*hÏ<í0`ËŸ®ãͧ¾k+xsäÒ;rnæË'‚öÑÿHÓ—V]É‹ÿ÷MŽ9÷n^lJ(û¹D^¼ðØržôŠÁ{ý#—püù÷ahñ,x[ Úy[ܵ3.éë.¯›y 8¨ºGÍI\ðd˜\Æž—ïÊhmûÕ–§¯óíºoH Ú""âì®rÛ-îôàí ÑjYz«;ÑÒ¾Ó×Á;Õâ÷Ÿž#""C#h§Ÿï6¼ËêÉiãæ]™ì*—Á”º,uŽ[DD¼ ÚÙÜv‹Û¬†Y—qàõû2.P9ûòœÓŽž»œ½¯ÞÃÇi¨=ò›`­mèï*ôU|øÒ¨e_œ–rÈükؽáö¼§M>áZÞ}îVÞý[æùæÔí`V¶èF¶­½‘­i¨ÍX|33N»™·ž¾~@Wyö9î#θ•7ž¼–×ÿ˜¹ŽŸ^r;†³ÏºÍk®aÓï¿=à·ç.ý¯®¾:ïÅiG-»‹—¿’—Ò.PK]œvÌ?&Îs¿ðXÿj¹.N;þ¼¬ärÖ7^¦‹ÓDD\”¯Um¶«Üؼq]\ƒŒhÓù’34Ȉ)²½d$Ïþ‡uÿ…Ç5Ø~rÚÚµkûy:7ü&MkôÈS¯å{|© Ü"""Z¼x±«ËSàñPöè^Ni2¬ •J0µ¥¬àÊ=í†BÞªA1Œ[܆ÑËÄIŸ§§"•P[·ž^¾Ì“OÜÆ9gOñÕfúwf>7û}®†•yòÍgf=ÍQjmä[f®é³ÿ›i©˜Iw;ëR¬ug'ïÒ[ƒfÓ¾PÅhµLXI¿\yaf[ìOVö™ì–uúÿbeÐʶÛ'Ì”7³ieg?rc?Î÷“ü6S¦ìÖfê+éVh?2[WX©kÜ>à”À=jÌtt@õˆ p°™ùó·óý;VÒÒz>~áSe}´œž V?·ÒÅfužBÓ šV×ßnEdõ(>ײ¬l§“í0Û]]h™¹v~§iì¤\™I¿|¯½Þ—ì”'婨¤ýªX°ËU±:¨°R'8ÝïÍ–íô g%ÀY­ÌÌo7¯ÜÚÍî{^ìG%Ü@+ÁÀ*Œ8Á1ÀIŒ¾µüo,]6‹“ŽgÒ!õ¾é:*å|å²þfZË^v!š]o/Ò9×2í´T³ äûíÁ¼ÎÃlzØ-sv>½8`qc{¼(Kf–c¦Åœoúb­o·ê‡rÞ§|¸G4<@O7ÔÕ‚0€õ`Œ¡§½…Nüˆlå×Mäª+ŽóEF™)xå\ýz¾ÊÌz;É«¿m§[Ñ‹us3ýìvÿú¹,–z›»r3œ¦•ßÏ—rýK~;X0°’Š D"@ð&¡"˜øþ[—?Cãc»øøãv† ¿¶¾ãJ^¿´\‡RùËwþ¿œÖÉÏ•pö¹ú¡P/š×L½á÷ýÊëõ/i‹{Tà b½P]ášj èZ1"ã m‹Nÿ;§ž¸_®|›+¾1§¤GKVos(´³ê:Íwž(ß4›7®³9‹Öï3in Z€ÞV¨ì‚úѰw/-{ƒû¶ßý~çîð’dj¡ûñœ 8bå!ùNð0³.VÖÇ‹´µ;h‚™ÜZ¶“A]¬.Ëi¹2ó¼q«iZ¬\ÙÝf;eÐî -vòÊ­2•+øi€ëë\hz3Ë·Ú»RªRÊ6p‡z~AW BkÄ€V8r6Ì`Â!‡Ó3âÁĵj½$þ·í‡šô|¸—ðH¸ø‚—¸ûÁ©œ}ÖaTWyÛI`÷áòV"(¶,«¿me:7?±º:r·š–f·Ùé²ãÖ²ì–+«•¬•g”;Ýf»e°Ðï˜y×`”)·ê 2´H)ÛÀ]ZM´­™Pªj#BwOâ³`<5§›Ÿüê/…`0ày†[ÙÌ ®av§•©—ƒŸX-ô¹ºšŠ-Ûé€n,ÛÎ@nn“råvšš½ðÑìïyQ ÀSª2å$¿ÍL£Rü3@ŠS®?ò´>°ŠpÛm„‚0rl-FCš›!–¸“X!kŸÅ¢3÷õ_˜OöôÕa8t:ì~—èÁ6‚8✯òµ‹?Ã’Ó§""¥oÉèö>Qy…sþ•î÷!KÞ–œž8Ä1¶ÒÝ ±(T÷±‡ïæÑŸNçííÍLŸ6rØg¤Î=*]DDÛ’xÅ::·ÑÛ ]ÝqŒ8ôß”ÕÌ@E®þ׌´µÃ®÷ ƒxŽùâÉFx°j+^xæ•ÉÔTÆØôÚn×·Ù{#‹ xPl †ì–hú–§žŸÆÈúvêk+] ÚvП/°¹9xˆ•‡ÖÛl¡ØoZiÕZ`ÀÊö9Ms§ƒ^x1H‚Ó´nGZFÝφíÛøŸÿþío³ÎÕ7 N]ˆÒÝ[ÁŽ÷GR_ÓÁ1óƱpáÐ|‹“‡Ö{Qñ{9DÕí³šf^/g¨_£ "C8pÌ?ö0&OžÈ¦Í{’צ™19žŸãYß‘ç}Ȉ¨•$""ÞhlZãÍxÜ"""â n¨µ-"" Ü"""¢À-""¢À-""" Ü""" Ü"""¢À-""" Ü""" Ü"""¢À-""".Ó #"Îãlë ‚"jq‹øR<V‹-R¦‹¨Å-âo¯½²~XlgcÓe¶ˆZÜ"""¢À-""¢À-""" Ü"""¢À-2TÌž· ï/ûóBïEÄtU¹ÈÚé÷Lg¿/ö¹ˆ¨Å-"ƒ´!ñà“\-mmnñipnQà§ru‹ˆ·ˆ”IP6{Þ[DüIW•‹ ±àï|vj:ïQà‘2Þf>WÐñ?u•‹ˆˆ(p‹ˆˆˆ·ˆˆˆ·ˆˆˆø….N)Ʀ5JQàñƒÅ‹+DD[Ä/Ö®]«Dn?Ð}Ó"â6]œ&""¢À-""" Ü""" Ü"""⺿TDDÄG[·ªˆˆˆøÇÿBLú' íŽIEND®B`‚openchange-2.0/mapiproxy/documentation/pictures/mapiproxy_hook_life.png000066400000000000000000000307771223057412600270160ustar00rootroot00000000000000‰PNG  IHDR¾¡û¬¯sBIT|dˆ pHYs × ×B(›xtEXtSoftwarewww.inkscape.org›î< IDATxœíÝwxUÅÖÇñïJ½#EŠ"‚("6^,Ø+*Þ+b¯\¯½]¯]ÀÞûµ쀈]»"Š‚‚(Eé%zM÷Ùñœ„@zö9Éïóá8ø ¸Ø9÷ð0Å9w¥QrPyÆwá{ œ´7³á@;àäàx&ðpŒsîým´9!ø¾Ð¸ØXìÿœ/øžïiH ¾ïÔ¹2Ø^ ¼do›Ù¹ez•""Rã)9¨<¯7;çÖFìçœ;ø?ü_훜s3sy%´™|?ôð 0ø?”Ñè”›`fm¢®5?ñ2ð¾—£=0 ¸ 8 Ø Ô1³vfV\ˆˆH-¥ä â~&8çÖ8çFÇž†žqÎmpέÃ')øùhø®ýhSIAÝåÀ€Àå@‚sî{`$p ÁP†sn%ðpððspý‹ð½ÿ ®_0Dqð矾5((£»ÊåÑ£azÝê½æÈaè~{fxô˜ê½¾ˆÔT¦§2Æ¿àŽ‡åιwÂŽ¥ª=sÓ+¡­Ð1­ro¹nì{,ücN%6Z‚»/„ÍáÖ«áýv0îS¸·Kõ]¿¶z ˜£§2J¦žƒšaðYØAT¥`¦›™-4³‘fÖß̇—HM`f—™Yߨý Ì줨ýÃÌį̀ýÿ3³GÌìV3ëû‡™µ«ÞÈ#Ìl'3kÖõkÝÊX8çÖ„Cupν¬1 ·FŽ™-FáçeüìœËßV¥wÓ0hùd „üfÐ`8\ù¤í?0V\l†æO®{ÛÍ6ÖíÙûÀÞ'ÁI!wBÝßaÍQ» ¤üýn„žká½ö0á¸ãÌHùÁ@«wáÂï*çuŠÐX| ‰^|¼œÿ/df#œsÙÀnø‰Ð£—Íì,à `0¿ Q3k ¬:8çþz[:çG•iä)ι 3k†¿Ý;ßÌZôÐÿ÷[;çFÕí€ÿ›¿e|™vÎ-­Ü·§öQÏÄçÜ›ø»>rñs'º×Ÿ+Íl´™üRª€¼Îñoèr+ôü¬9Ft÷çžß–ß­o‡C΂ÕG€KÔÍi +¯„¦ÀéÂ>‹¶~Üö°â*h=ö?òëûwús›Ò w§"å;BVý-Û©°If¶>QUpÐ̺à?ôßÁ¯·R`£sî/`:Ðv+m¾Œ‡9ÀÌúà'EÿËÌî Ú܉¿ÓëˠΣDæ> 5³3Û ¿¸Ü¹fö¿ î£A¬€ín@/à€r¿ò7õT#33ü_ Eö·õUÚ²a¶Y×~ø7†¿}³Ið6äšÙ&üºwß;çrJüG*¤Éëpæï~{Ú×°è `2,<R¿†Ë‚¡œŒ'`ʱ…릌ƒ+?*ÝuÒ¾†‹¿öÛKŸ€™Ã!ãê²Å*Ra¯âï`j‹_ƒåœàø¹ÀPàüDç‚ÄáB3;X|‡ÿ .Ê€ÛœssÍl~âõFàŠ`Xð$àè ìÌmÄvð°ØÏ̶Zá'n¿íœË4³ï€ÙιËúÂeKq™˜ÙnøäŠ~ø”鲕º+á+¿e*òU“ÚoÈÖÿM’ð= uÖ@süQeL¶›ÙN\9Íýv^ ¨3!rî¨?`J‘ጺ“Kô¨ëì7f&Âäfe‹U¤Âm€¹@€™%Y`ׂgÂO;ç†TöûlÁ9çæÛ ðk´ln²ñw^¹ þæ \>é‡HÒߟ¬îÁ¯{~xñ 3»ÿ{¡2~O qšàé/ÄßzWæ'§[4âZ~ƒ_9²À:ü‡ÿrü-žï¿TÍ¿uÒRØ´kdÿ£]Ørˆ®¤5,¢lŒjkìn¾îžËafLj‹R M6d$Cnç .R’‹ðÚw½¼ãœ» ü¤Cà,ü‡|Y=œˆï=è‚_Nþk3ŒÿÝ\p+ð7À f6¿€øõ]ÎÞ:¿ào㞉¿<ë÷¥f¶É9W0D!å¯É@nm™ˆ'Abð~¹èLüÂøUÇ8ç2«>Šv£`ÆËðH_Øa ̺”È‚Uåu ü ^9º} “ϤpB$RY.ÇÿN] <÷å|’ûCT¹ñÿ÷Š&Þá?¨£][°áœ{×̾Á?¬îóऻ‚ù9@ï ÜËf6#¸ö¡Á$ã/Ílp0Î9·Ö̾:㟛Ä=ßS(ÏÉÔ2fÖ ø ÿ h~‚Ô•w‡B´äŸ¡ÞÆÈ~úBÈYç·Ï †e—À²,hù,,OºA·hêLH/úKr>ËO„%;CÊÏpòàȹÎ7Â_ÿ‚ñ'@Ãaà†C௶´Åà‚-ëm†äŸÊÿz¥6sÎM.²¿žÈ²ìÑdzñÏe)®YÅ›Rdþ¯ÿècÌleÔ±‹ikþÿ|tÛEÛ_„Ÿ!—‹ ™Y/àzç\¿°c‘êÜÆt,0Ñ9·¤‚mUÁ"HåuókÐømøÏÛ%—•Ø E¤æSÏÄ… w èÓqâù½!¿˜gVtÿ£úc)™’‘R™Ÿ ¯7>YrÙ¢– ùÅÌh¸v¹Úè1Ù"S”ˆ”Jf*¬¹(GrpË=•ŽˆHÒ ‰"""Rˆ’)Dà ""! žepwØqH•™èœ»9ì ÊCɈHxZëÂD*]ü “qIɈHxeι¯ÃD*W𬉸M4ç@D$<‰”é9"ÕCɈHx’Pr 1HɈHxñ‰)JDD£a‰IJDj¬ñᆯ"ûƒ…'û„C=“”ˆÔXY‰·Cd?¯ äÔ /)†z$&éVF‘˜6¦,l À/Aê*ø¤çûóÏö‚]gBï•~ÿ£6°¬œ;)´¥,4!Qb’zDªÅ¢xäXø²EÙêMÝf=Ÿ½vEwÀ]OGÎϽ~ëÙŸv üuiåÄ,Õ@à “Ôs R-ÚdCÚjó|þ$Ï„6£àÔ P¿„¿ó:BŸÞpì"˜~?¼4É÷\0¾zb—*¤a‰IJDJÍ¥Á»*ÖFòDÈé¹=`Ö?àŽ° ‡#GAu[ÖIœë€® y¬è(9ˆJ$&)9)•6› ÙŠ·³¾q°áÀÖCÂJß‹Ðáûâ—Xd? Ì;¹—9—[¯â1J5Ò°‚Ä$%"¥Ò2®}­bmÜw&d÷€Ô¯¡Ñ'Ð÷3è¼±äzùÛû ß\˜\rö„fús©“aUà¿¿þpHØJ’!1H%&)9©ÉÐñ{¸öÕ²×Mü ~|&O€ÍGBÚhø“?×j4Ì~ í¹!ayåÆ-ULà “”ˆT‹–9Ðvùê&.c.… ûBê‡0ðûȹ ÆÃ”à«¡í#Ðx=, †.º­†?DÊv2Êÿ¤ hXAb’’‘¸Ð{%ô]ü¹îë¡ûÇQ–ùoÍr ßÑpÆ´* OÊK=“´ÎHL«“ )E>Ô¿k 7Œ '©dI¨ç@bzDbÚ…ßß>–“®Y(áHeK²ÂB¤(õˆˆ„Gà “”ˆˆ„G%&)9 z$&)9 A’˜¤ä@D$<V¨!ÌìX3kXB™þf7(9 †jŽLà³­%f68Õ9É ’‘ð¨ç æ˜t~0³FÑ'‚Äà9`+ ™Å%""áQÏA áœË¾v~êÃ߉Á#øg%"R<½?|¶ßÙ ^ên<Ñ^î#:‡E 4!±f lvžÚヺÀBçÜÂc+%"Ró¯é»ûí?„9§Wíõn½>i]º²sNYÇTm<¦a…še þß4ØèŒO òwBŒ«ÌâbÖ¤ˆÄƒŸ¨úkl: V½,®úkU +Ô Î¹f6èJáÏ×µÀ»áDU>JD¤ žÞæÝ ®.4QøÜ'Ãæ6póÙO ‚Íûƒk‰³áò3ü£«oÍ^‡Ìs ¯ Ôù.¿å˜V0önÈíæÛLýN=ÖÁ­C ¿Ly ~Ë‚–ÀŸÀÐ=`ö!§ $¬ÀUïùúùi0øÈÚÒ¿€ÞÿƒÃ—VãV%5ÏHà 9êX20.œpÊGà "µÎüT¸m ~^Ø 6•ò÷Àç-aÎóÐä%èw<ä6†ÜÝ"ç³›CNÐåÿò Óœƒ÷ÎwAªóçr;Ãò  ë-°Ë@ØÔžèÏ¥äÂÁU½¡WÈkï_éÏ]r$,‡®—Ã…'ÀyŸÁ‡maÆ0¨û-œpq24Ÿ‰iýÐä èÛòÂø³*ôÖU> +Ô<àçDû!^na, ž‘¸5?µüuz Þ} f¾·-‚ÄyPwôz^^|Ÿ†Ä9ðßá~¿Éƒðü9[¹€A~ø¹3ì< Îþµðé†oÂSýö½oÀêS€§ýµÈ„·:ân26ïãË5Ë$ç@»àI†¿þÿ‚žŽj<*þ”ïáŠ`†ø”·`áuÀ}¥xƒª‹&$Öß•-»$O‹ìwÞ蓊âœñ m³€[ë@ý×à¦Ç#ç›ÎˆÚþV¶ôÛ_5‡1ïBÊ$H™ã‡\ý­¿„œÖúËÖϧEÅÛ`¹–ˆ)V¨aœsÎÌ>þYpˆ8º…±@\&ιlñŒ{‘Ú¢O&ôÙ©bmÌJ‡ß‚¼°’æA£OáÐ1[&R–ÂÆC#ûSëB^ûâ˶Ìë_^„7ºÂ¯¯ÃÐïàÜIþüŠnÀO~;swH æŒ;ËÏ <Èïß}!dõŽj8ò#»É a}ß²½ö˜¢a…ši$p4PÈtÎ- 9ž2‹Ëä@D*b~* » R'B§kàô饫×ëcøøz¸÷lØów)þ¯¢bïïïVhù8ð+¤ÍäU‘ºõ6BòÏeÝU* õÔ8ιUf¶hGœÝÂXÀœÛJâ/RC™Y 蘅J-uÝ$Øã8å°#)Ÿ§€9›sË*Ú’™}Üàœû¾âqI,1³³€Tç\Üõ©ç@D$<V¨¹^ÚÅcbdfÉ%“J”¯?,"•£ó@è¹ øsãC—u~A¤ZAk®oðãRÔk Ý5¶°M®ÈWÁ1+î¸+\‡¨ïYÀ¢,`EUG,»Î߯¸ÿûÃ`ÖÕpÆ´­—©QÔsPC9?fÿqØq”W4uÐ/±ä¢µÝßI€+’,Ý·bŽåV '|‰EZIb’–O®8Ûr7Áüw‹:m[‘ÚNà “4!±Ô,zcÃ0®˜Ó†ïQPr "…hXAb’z*G1½ÇÔc "[¥ä@bRŒ&/ïÏD-™úl/ÿXÖ°ýýA_dØ èl™”Ðá "µ‘†$&Åè°Â¼ãýã^ Yp$-&UÞ5†uYÇÃ-åxB[±ôE %à ' ""Ó„ÄR0KIRÂŽ£6‰Ñä ¨=î…”œÊmsy{ÿ¬÷r?¾ÕÀJ˜{`QÛPx¸ADD=¥Ó°ô©õ¤–ø(?ääàéýaeÈO…úÓáø/¡ãæ-Ëe¶„ä, jmö1­à×ÃýcdëÌ‚³> ž÷Œm ?翯 kwƒ:³á¢÷ =ß?vUo ìïë´˜g–â¸ÑŸíeí=P^ "…hÎA©u‡D-ñµ iÎA®Á Çá¯×aßËÎ…O{_~Á90ÿÄÈþ³½àËOaÕÛ–Ý ½íŸ6ðÇñ<ô,½²w„¥À}·úó+ëCÎàaÝþkuër¼rÌ=ù›’‰I!õºö‹<ß|ÒP’Ì$˜sÔy'òÌ÷ŒÁðððú9pÃ3‘²Éóà¶Kýö}§Cæmqüó/Xô,Ú†ÜXöøËÝ{ ,AD¢iXAbRHÉÁšC iZáÄ ©Óù?ßòÚCÝ©¾áïºS`ãž…Ëvy'²ÝyœO,~hýæ–;ô-•aîÄì ""MH”˜Rr×R~)_Ý•­ü÷ÕÇÃê"ÿ©’çÞ?jNd»ÅZÿ=«’f¼–§÷@"5™­®@õ(9Rr´²z—\®8MÃ\`»àÒ/˃åSyÆ—±÷@DªÆ”zÐ}}5_t»ŠTvÎ3 [$\!õq7ûòv€ÇŽŒÌ3Ø”sÒJ®{Ìl?$±ô\˜\?r<3 >oYú:ÿ®>|Ù¢l±G+:ùp‹“[ß‘*ðÕþpÃr§_8mS•ÿŽsÎm®ÈWUÇ'R!õ\ö)Üö,|n™IÓ!§;t¼þýý¶ëÖσ—ägàIðÖ8›†Ãu/UàE•¢÷@DJ–ц¦–¯nƒ Xû¬?fô‡[—Cb¤M€ƒž…ô¸tنǀAö.°ކÿ/|~y??4žü'ìû½ØŸ¹#ü~t/|{)dï­‡eÇ ·Aϵ‘v†îóÀ•7C£\§Ý«Á¦=¨;.zÞŸxàdpIPo!,9 \Ü~AU¾!®s0è9æw÷/ºù“púoþÜî¯À¦¨^„]‚ÔìÈþÉÂ~GÁ{úö¸ ZÝ §Îðç÷šù|"Q óZè4ö\9vÇÙðKø¥ ´\R¾×QÖ¹"²uÉÓaÅYP¡Ïð \*¸¶ßr»Á˜.°äÿûC¤¨a]`áãÐäNhõ!¬ß6·œ¿ç†>€Þ+ý¹Ÿ;ƒ« ٭ᎨÖÖBvçÂítýªðþN#aÒ@ÙÉÿA<¦/Ø85˜P¿¾$dÀøÓ Ðٰ߯´3$É“«+1Ýt_¬ðfq«&ŠHÕ¸úÿ—Ÿ)«3¦Âѽ!}<¬>ÞwÝonà¿'l„„¬ÈW½O ñ{…Û9nAáýSg@Òï~ ø^„:ïD–ûÏk–U¸Ý„,hô04êYO*r«~ÕRÏA¥QïˆH|;x9ü0𰟸ü˜ø ´™ó€ôùðŸ‘eo·á›°ê5rö†]oŽœK™YG@ßWB¸ w«ÔsP5¶Ñ{ "â™iIõØñÄÁðQ¿½)òÒÁ–A‡ ~UÝÔ1ùox²¬þ°~mxy÷’Ûîó>ä7_ð½“çz½äÂÛƒüÉðè10³Ne¾Â²PÏA¥*±÷`+eD¤¶0³ÆÀáÀ±ÀDàñp#oe/˜÷,|»H€Ä¹ÐîæH÷ÿ‰×À{C`îKp÷F ÉÏhs]Ém÷Z›¦ƒ Ÿ;,œ 3ï… _ÂÄ•àBÒóM¥¾Ä20hÕ$†@ÍS0!ÚÎEmk€Ñ›œ[‘Jh€™µ€ŽipQØ¡H\z ˜³Ù9·¬4¥ƒÞ=€¾@  þ³‡sWWY˜5ˆYófð¯:UÿÈæE)0±´Y {­Ùz™ñm¡Þ&80£rï‚ù©Ìk íWTçäÃ-=‘—ë7«áÅP#mëg%K+¢‰ÔpQ½ýƒïé@ °xÔ9wMHáÉVµÉ†6óJ.óÏ¿ªæúû¬7)ˆHrníª°ƒ‰gÅôìäà¬mð?çÜõÕ¡HÙhΈÔpÏô†Ì½á¦G+»e3Û¸8(ž-˜X”^¤x ô0³O¢ŽOwÎUpñ'‘Ê¥ä@Dj¸Í k§ªhÙ97ÎÌrµÀAÀöøƒº[©RxŽÈúÐ;ÿ®ŠØD*BɈH8ç~~0³ÀaÀ?€£ñ½ ©@Z°ÝxØÇ9·ØÌ–‡·È¶Äer`fizÔ©ˆÄçÜZàíà 3놿eñd +´&šÙÞø¡Ý-&1'.“üß½a!"²-ι©ÀTà>3«‚ŸŸp,ð-pñû{¸åãÔÑJ³ÕbµÅÝ¥™Õî4³Çœs›ÂŽGD¤4œsë÷ƒ/̬ p ê9(…•«á«˜YZ¸6ˆ»äÏp"~òÏèpC)çÜ 3Ûh½ƒ8çrܰã¨MâñÙ gßO 5 ‘ŠËE=ƒâ19Ø/ø~h¨QˆˆTœ&$JLŠ«äÀ̺ù”dfÃŒGD¤‚òˆÏá]©áâ*9Àß;\ðä&Àñ!Æ"#Æ6õ›¯wõ²•RPÏĤxKú‰985ÄXDbÄô`á-aGñ׉ð×?ÂŽ"N(9˜7É™5Z9ÜÎÌꄈH%ЄD‰Iñ4Öu8~Rð+b$àã?ø0¬ D*ßðá÷¡ñûy $,‡6OÁÅ_ûóóSáÅÁ°ù0Hœ ?(\ÿÆ`»ÿÁÒ‹€¸ë˜â¯“‘ ~-ƒŒ‹!¿)4xn|ÒŸ`d7ƒŸðûSêÁð·àÚ¾Ð(>2O‡¼N`k Ý¸è[_Ö¥À;aó!6öz ú.¬ä7ª&PÏĤ¸é9NêáŸj¶ÿà’FhhAjœÍé½?¬ß?Z¼ ó€Üài/ÿrv†=OƒîƒU箟» dœ;‚~§mý:Y Û–Ÿû\ ÿkÏ‚‡Oðç³›CÎvQq%ùò¹ÀÔº1º {ö„#@ëy‘²O†?ÁñÇ~.çÃ…Fv‚;®§÷+¹l\Ò„D‰Iq‘ÏJ?X¬Æ/?º8*ÄÐDªŠÁáÁ!ËàŠ<ÞÕŸÚp"4 ýgÁù?C½÷·¬ÞüU8{ 쳺äKµ| úÍ…u>€'–\'ÙùÞ%»Àäúpðr8!*9Hþ®~z¯„öÃaÓA%· >éx¨Üò,Ü0&¾ 9-áÂq¥«wÔsPC™ÙqföJØq”W¼d¬»ãŸ‘~¸sîg3Ã9÷£™ |af]œs3BŽQ¤%døÖ¿÷WÀš°iä7ƒ¶Ó"çêO‡õEîÜé4¹ô×Ú!º­ßay)þJï¼: „yð;àíÏ`ïûá¸þ|JT›MW€k¾íöžÛæ ÜÎú½d!{/¸á«Ò¾š-¹ºòSùëWç\¾™ÅÅiRf‰@JØA”W¼$½€>ι_¢ ¡ø…‘”H-ž Ë`ÁnÀ_þØÚ]·,—”_ú6gï ,òÛëºCâR¿² 6u”û¥[ázÿ UüS#øð6øùb8î†Ò_·h[ãOƒ/΂½!¿ä7² ñ Ðñ‡òµ[ ±Öå)ƒxI^ Z²… A˜ZÝc& wpIDAT‰„§î(X~¼ö'lhúxZ]ƹ0bd¶ÇÁv·úã»…/Á³½ u#,¼ Rçö0· |h[$/. ½VA¯GGaS ßæõ‡Õ§Ãê?ƒd¤&rffÎ9=qPbF\$[K J{^$¾Ô])?>–òÔ æ\ð0<“SŸ€Äù°Ýý°ò°¨²ã¡nVé¯×r(L¹òC£gàÊüñ#—ÀïC`Þµ@6´}¦E~mdœ¯Ü¶Ò¿ƒ~/úã©ó(4Ž^o3$—±[?=ÎLòûóS·Y<¾Ì;Ѓ…$fX<&«f6Ã9×%ì8$>™Y 蘅JÈæ§ÂÿfÂi»BuaG?žælvÎ-«ŒÖÌl-ÐÜ9W†„Nb™õNqÎÅåCã¢ç@DÊë—0q+K5©zc‘­ÐBHs”ˆÔhó›À’#·Ða–á÷ßÜ æî – ;þÿ˜);¥|q(Ô_ª¾×$1@%æ¨ç@¤Ôæ\ cƒ™C`Ãî0ù=xôî÷60ÿ¾"寅©{úí»ÿ“ƒìæ°¹üvV¤œ« #†Âš}á¯Ap˳Õñj$fhÎÄý@Š”MÜu’ß|`,¹ø¸äj뎃6÷Â%_oy.¿t=Îþ¦×…—~ñ= Ý×—/Ä_ÀØÞpÀ÷ÐsmùÚj¤a‰9ê9)“:ßE¶{|ù­á»¦%×kô&,x? Oö\‹œKÈô‰@× °ÆïZú˜r ^Ù n7 ‡ß@NC%qCÉÄõˆ”‰‹ú?“üBOp˜ $.›_?²}íkðùg0áxXxÜz:Ü~?gŠ\$òKø¿™‘ ¯÷…gBîàêùë[$ý ëw‡!»—ãÄ®I’ÕGs$æ(9)“MûCî#äà·ƒ!aô^ ›VÄDø°-ô]è¿çu‰ª—à'&ö¼ý9üø!¬«ÀBËèú#üÔòB~>¸†à¨3­b¯³Î4è4¿bmH)©ç@bŽ’‘²ÉAAÒ,È:Ú^æ§çC÷á»á0aät‚Ä¿"ÕnûR'@â*Øt Ô õó*ÊÑ‹áè[üvF2¼µ,;²{¦`ðàŠµ/ÕD%æÄëdc3û p1òE Ä ×[ü×ïιrNì+N“‘Ðz*,Ù:<\øvÄÁ·ÀÈN°dG8ð{ø}{èÜÆxЙ0£ä§@¯Wàð¥þøÞ3 áŠÂ×èr t›W¶¸Zæ“¿öû£[û‰‰šwÔs 1'^“ƒÝˆüg²ðK¯#¡½n*19€`mƒÅŸë? ˜å·{Duí¹ÄÕ}=tŸTøØÙS*ãÑ‹+Þ†T%sâ29pÎ- ;©Rf@åaG!5Ž&$J̉Ëä@$ƒî ;©‘Ôs 1G눈„K%æ(9 —z$æ(9 —’‰9JDDÂ¥ ‰s”T3ÛÃÌîŽÚßÅ̉ÚO7³‡Ì,=êØƒÁ±Óͬ¾™µ0³Óª;v •z$æ(9¨<“Ìì€`ÿBà„¨óÿöþuì@ü}ø-€[€ÆÀÑIE}3ÛÁÌêÇÚ˜YBT™f¶{P6ÑÌššY«‚òQåþ®gfIfÖ$(×0ªLŠ™u7³ÆQÇšYƒò¾1"²Mš(1G?•k0ÀÌ&à?è—F;8xx-8–çœ[¬öxýVÚ<¸øôFÌö0³ÿ€³€‰ÀÀOÀøÇoofÏ9ç>5³Å@73»X¼Œv1³[€ÀР®O˜Ù5@ ‰™uΨØ[$"Eä÷˜Ùma"•*ø ì ÊKÉAåZ ´Æ'ïÿ0³ÀjçÜ3[efss€Žf6ÈîÝF»ß9çn6³ƒðÝÓðÞ§à?𳀱ι_ͬ °Â9wµ™53³Y@NÐÆ^ÀéÀÓÀlçÜͬÐÿ™øøÒÌ’ñ½â{™.ʈHå(1¨™*øü”ð(9¨|ï] ’à`» hìæ8çN)¨hf;o¥Í‚ø4Ö«qÀbçÜL3›œcfÙÀãÀÆ | ¤GÛÔ ¶ß× œs˜Ù@|Òqpþù«ƒr·–ú]‘RqÎåâ'%ŠÄ %•o4ÐÛ9—mf˜™ÇÿçœË Æü¿ ºöËê#à| þƒ¿ ¡HÂ÷&tÊu1³+€]ι©fÖÉÌÎŽÄ'[0³=]ðÏèåœ[kf?ûSÀåˆ[DDâˆ9çJ.%% ºðSs £ŽíAð¡íœû-êx7ü¼]œs¿DOÚ;çfDk´»8Ø7üDÆt`,Pø?`ð#Ð ÿþËÀRçÜŸQõúSœs+Í, ØÞ9÷§™Õ ê-öÃY|ëœÛÔÝ èŒwÎô6Ä-3kÓࢰC‘¸ô0g³žñ"5™’ƒÆÌ¶®uÎ]v,±JÉTŒ’©ù4¬PÃ8ç–J DD¤Ü´ÎˆH-¬ÒÏÌE;ÖÌZFíÿ_Ð3Y°¿OPg`Ø3;°z#—ª¢ä@DDÒ€€sáïùR¯{û©À³^å" ·}»¯šâ•*¦a˜„¿3 üÂjÑkšœ<gf)ιìàøhçÜÒ` ø”¢ wg}„_æS 8?¡úiàà üªkœs×™ÙøÛ«#so™Y༠١ι¯ƒ[ÃWÍ—œsšÙõÀö@}àßÀvÀ%ÁþxçÜÐ ¾Gµ†’)0ÙÌöÆ/é>-êøiøõYã€QÁñk̬ þî¦ì`t!š{mœsyfö¾w"¿ðÛ  ps®`=•.Àü-ÕŸo×'á×]yøÛõ!À`$¾÷âpàçÜ3» xX€N›"í>q04Yy 0ÿ HÈÝ>†cEÊd¶‡ôÍÀŠÂ±Lí+{BÊ28î]èºÁŸŸY>8Žú¾ÙÛ—é8NŸŸ·„_Ž„ìPgœõ!4Ë…u‰ðì Ðöw03*¾ƒ !Ný^èݾ‡£GÎg$Ãk'Àîcá°ŒJÛEd›4¬ š\ƒŒàó»`î}µ#,yž w^sî¬`ÙðàÝ‘zÃ÷…yƒ g;Èk™WÁ cü‡wÅ—ÃÔ[à·aÝVŸß~#;EÊD+ÄòÙý0ÿ~Èm +n†WGÁ¬t_fv#_fÄ0ÿnÈk ÂK=à³OaåÅÓ2ÞññÔσÍÛäWáû&¾'ûÀ¼ y4Ê…•'ÃE–«v$,» Ú]žWDªzDBçêÀMøÒ‡‡%Cê¸ý`Hrpÿi°üvȸ ZæÀ)?B£##õg¥Ãsãáݵ¯FŽçì Çì}2aQ <ñ&L¹ú_°õXò›ÀÅ@»,{?|øŒ<nx¶p¹ëðì7¾ IÓàò³||_Þ cÆÂÈóá¦ÇáêÇáÎ}áã‡aÝõ0ïahô œàë7–Ü ³îŠô~džéQ½"RÔs ºFïG† :ÿì¿7þÈ'~’`BË |.¼×î·Ý¯_ +aSçÂí&ÿäðÃu¿€ìý¶KÝ/|bpÀ ߯†"uš|I æ§Bnhð‰O YÉ?ÂÆ ^z>~9ävƒ¯>‚ä_áÚ§#í1, Þ=Îï¿×²{C§èëˆH5Rr º†ó"Û-ƒnô&QÇš®óß³Rü÷ÿ 㾄 {AÂfHŸ ¶òn7uFáý€«sÒ¶Kƒ"uRg@~óÂÇ:þÙžÖ0h6µH½©ß2²ß'R~‚ü¦ÐrX$ñ?7¡Þ0Xy†ßŸr*$M†3¦m=N©JJDâÎÒ³!í#¸ýB¸ùA¸öµ-?À6ï^xMw°ÕÐqóÖÛ^Ó½H= qIác ù‘í½–ù°¬g‘z=!qadÿ¡!ëH ‹nÌ?(°ç»«Ÿ¿°¡?4y ’‘¸“° °Èþ£GA~Û-ËåôŒL@ß6iŸo»í ‡G>¸GîèÛh°:Ír!e,¬;¾k꽺+äìõƒz£v€Œ;¡ù ¸þZHœ ?ä'A8z1¤~ < .Åß}!"aÑ„D‘¸ÓþU˜ù*Üøžßw åë-Ë¥}GÁ¯SüäÄ„ èýÀ¶ÛNýÞû>þ²÷‡”oà_#·]g!0ñ%ø`Œþ röÔÏàü×ýœ„ŸŸ„´Oàš7}ùƒ/‡ÏFÃýá†ç"í´zæ¾u_*|[¦ˆT7%"¡IrÐiì5¶ÞiCpìÏȱn«`Öè¬pþD˜¹'||0¤l€>`FKÈ/Ò˜6¼~Û’^…ÃÆžý¿óÐnqá:mFA£gaþPïI8ëG?¡ {&,»Y8éŸÁ.G×ûÀÆ–Ðä^#ÀøúÐaòk¤üa°áDÈlV¸FA»]^/ñ­‘*eι’K‰Ô fÖ:¦ÁE%Ž[7½u?‡Ÿ(]ù\ƒçÂN'ÿ~¬ÒЊµ.î{,n‹ñ˜§€9›sZ]Rj,õˆHÈˇøÉ’œv4"¢ä@¤†Úÿh\†qû${{-*¹le;èXò=· ú¯-"ÅQr R#½¸ä2EõŸ]ùq”Æ^k€5á\[DŠ£[EDD¤%"""Rˆ’)Ds¤–Z |v—V‡€H•Ó:RëøuØÆÃ‡DJ¤u¤Fû£‹«AáÇIEND®B`‚openchange-2.0/mapiproxy/documentation/pictures/mapiproxy_logo.png000066400000000000000000000217631223057412600260120ustar00rootroot00000000000000‰PNG  IHDR``â˜w8 IDATxœí½y”eWußÿÙçÜá5O]Õ“º¥î–Z3XHÉ‚m°<È;D¶c2¬˜pˆÇ!+ùÅCŒ‰ƒ!q!rlX$6L°…Ah@“ÕB­n‰îVÏÝÕ5¿ª7¿;ýûãUA#Ô]%uµp׺«nUÝ{î¹{ŸóÝûì³Ï=¢ª\Æ¥ƒ¹Ôø›ŽË ¸Ä¸¬€KŒË ¸Ä¸¬€KŒË ¸Äð^ÎÅ"#Úr%èV~ å«”—wþJîy9ç³lhd8 z\u®ÃË€¬u 2Rî½$ª Ë5ºó ½µó‹Yö7+èÈ#À³ª³nMr]‹D†·? ôxïz×ÛƒŸþéwŽ^uÕ¶-ù|nÜS Kg²|¬éáß0t›¿Î9×l4š³û÷˜üØÇ>>ÿ§úçÕÅÅ¥8|Vu®µZ«*@d¸òn ÷Þ{¢ü+¿ò¯7]-"=|Cè¯""ú?WÀ¥iVá…#Çé—þó©O|âS3 O«Î}vµ›ÏkºœÏ@ß{Þó3úп¿: ƒ-€¿|ÉwkKÙð<[ºúê;?úÑ_í- ÁüÁÿr"#{UgOžï¾óö‘áànÞ¼±÷+_ùÜ•vy. Õ—Cæž={çî¹ç'÷œ>}f/ðIÕ¹s6ÔUÜP¹Ƚë]oÏmØ0ÚO·Çd@º‡ˆ¬[Yß&Gø;w^éß}÷÷‚l)O«¶Ü}÷÷嬵9º”“­ã‘®sy߇+ ö®»^_¦Ëcçð*ãíïé)y;vl÷UÕ ëH?ßùö÷%¡"b¯¼ò ÛÓS²µZ½ÿ|¯¢É ôûår qªš²Ž ‘ïF%(àz{Ë®¯¯×¯Õ¹ó]¼ÚHXÂ0X¡‹?ÿ2Î 2ß÷3cVô¬FAÔëÍèœÕú/SÐù¡@œeY§^o¤Ý_ÏÕ(ˆz½ž‰—v™‚Î’$Iãz½‘­&®Uƒqqœ8  Ä\¦ µ@8IÒ8Ž“U[ת´Œºªv¸ÀÐ÷”þeû¢²•®Û{öÏï(EQÔìêÎU)hù½Ëäs pŠuä­H^Q_ÁÊ7Æ$"݇–Ç®ëĪÄ@Ç‘t}îoG(w:Që›#¾/µÎԀ𠠊Ä)ùvJY…b„O»ús–¦—±ò»¬éÆžrN!Í”Ô)‘@Ëš"$/·Nh7›­PXíâµRPCUc^æ@Ì)¦SjFôeJÁxžQÄ‚³ª+Md…bV(nåÁ/nå"`<ÁG°ÂL)¥O¨y†6—>@耨Ýn7Aó«]¼V j-SК Št Õ¦%Nò*Û%IS\è‘9Ί¨vû€0rn;³b ]Jò ˆ|k1N ;mÛUDC."×ëh=)¨ Dt=¡óŽ.Ò ¯ÖÒÁ¥–ö9ëy8ßCÅ`|‹šî”†,ÏÚ¬xUñrÅ=Ër™î³Î~ÞJ‹h¹³ÿhQK)픜/,ù–¯¾ñv@ÔUÀêX+5U5¢KAçT@»ã ‹ F;)ycȬ¤Y’Îy&ÍÏG‚Q ¢Š*±j!p]E¬(@4µàÛn]ÅA[ “n/г<ºŠˆ=Â$¥?M CKżº6bYÍÎzzAíe zÉ ŠÔ[®±ÉH”¨5ĉ“$Í4Ÿó $ï¡ë-¿¢FTDÕ€—)zÖUÔȲƒUX\~»Ìƒœ,+k¥ +çâƒ`Á)a'eØ •У¶f^W*•ÎzRP‹.}KpŠ©TãÁ™J<ØÛW¤à›¬ÕÎ4NœcPFË©5BÛŠQg…Ô úX5di†ÌWTÑ0߇\€:!´B#géˆb¬Á%ˬãK×v,Wål%„V… “9úZ 6ï3ÿ*ØDss ëJA­—¢ çÔÌ-%ƒ­ˆëyYõæÑ¬liGVâTI3U1F<u™fI‚f™b=!M,% ‚îƒÊEL³í¤Ó:m´ã‹手X$Ë+´ðCŸüÌCoüÙT¶mD³T8xò0›FsŒl,É_wÙö!œÍ‰90kµ‘ V4íÁö—så?ºÿøys9_–#똖rvF6›Déñ §xeÏHhóA@àùêKZu­4PÕ¶6[‰lÚÐï‚\ A–šv&:»Ø¢™ŽM.²a4fb´Ÿ úú-â{:dòñSzë÷ŒË¾Ó¾oÔ¬tb§Õf*•ª¯[6†ÜýÖë便 ©&´;±<ùÕj¼]ܰ{GàÉ™ôÄÁgÇw,µçå¦Ý1;w°çk'eßS-òôA—^½ ïДjÎKõu›}¬¯Z.sf2.ÿu6ÂÿOoN~ü}µ¿ºPŠÓâPi"/{œ1VÍÔÚÄuâL+‹u͇\}Uà®Û>èîÈs§uêÌ´~Ü;sÊåf'jCý¦¯§·¼Ô?8RoÔ–†³Lõ/80ûŽ·]íî66A>G»^é[ªµzKAÃÈÄì¼e»,U>ÿ¥ca'q ßÒûôW¿V1ÁîÆ Wº´zã'ûGû™«¹¸%¥‡ŽÞ°{`þøÁã}×ì¨äF‡u#ܪo¦Ò*dÍÁ¹Þ¤nÛ:¾¸a0°{­Íÿä}¿å/-,N}â>P¸ãö{·Ò5¾/%`3]C; œxøÑûêwÜ~ï °8øð£÷­9Ø·f#¼‚OþæßªÜó³_xPwÛÒbkÃàpŸt¢Ìøžd=ù²ä{òT曜>ÝÒ™…Ľnw¯»õÚ¡ôΛwȧ<£O?ñ•ïk'Óo[œ´-p9#¢}ýG—*‹[œsᆿ<6:ô;·ì(Û|èv©R¹Òósv³61}ë÷þ÷kwßøÐüéÃ÷ Øc?¨†àeê-ìÛ—}°ÿö×sîÀ»<ßbÓ·þêâ©É[ûüŸ½ßóÚË2»7â[î~Çfâæ'|îÏÞ¹tbÿ­õ¢Çwmzæ×~ãçýO÷c?ùà—¿'KÓÕôw½û—øòïÿp+ðÛÀû€»«€þøMà?¿üp ÝÁ˜®«>Ÿú­·,}¨µØ84;[é³×í÷Â0°ívf¼0”Þ‚q‘yhÏ´ù¯Ÿ<â=¼gŠþÍÍ× XA½·ýð÷ÿÎ=?þö_MÓ4o­‘øÞŸú…Ý7ìüÒô™ÉïmKϳG:ùMÃa纛où;®ýÏÏÍ;ôÜ›çëÓhgÆ1šÿõÉdóÏ)ްsü<öÔWm¬êáb»±·%gNÍû†|ëïŽÜþSÿ¤íJ‡ö|þÏþéÔác…$ʼ4ކ†6n}êö·þÀŸ=øÈ3W?pÿ#ÿ¦;îüÝ›ÞúÎ óù?IãøCw¾á§wÿgYØÿeYÈÿæáGï; |øÁ;n¿7Ü<øð£÷5¿!¼ 6ÂçÆÇ~í͵0ôÕfý¡V-ªµ[‰Ý0Q¶›6–Ìæ‰A»c×fsÝÎ óÚÝ[ìæ‘œ77Óñ?ùW“„¡'¥žÒì•W_uðŠmO{¾×غ}ûžžþá¹ Ǩsþð¨øÍ,ç¢Øö>ùÈûN>÷ä{ÕEív+_.:))— ÓwÝ~íþ´Ÿé¤þ«ííÍjµP­ÖØ4>ȶ­£TêÆóZ·}ß-mÞ4<å7>ÒnÔ7ôÒN³ ±Áìÿ̽ÿ}èÊ=ú•g¾G„ìo»ë¯6oiaî€P]öÚ‡½/>L—1žþrY ®¥ÛCvŸ~¹r|Y^Ћñ¿>xGòÇz㡸Ýù\eræPw¤·ìÛñ1ÏlÙšñM%Ó?R0=ý=²Ð¶Þ¾ƒ ÞR#Åã‚ÀˆxXAB“¢â‰é6k`ú̾[ö=ì ?ùÎ7ýöûÞûþé–+6=ÓSò¹ñ¦²ôöDQÜ31Z(nèABë†EL£ì™Ø¼•þ¡Aª#YšÏ=?=ðŽwl—ž 9¢˜èØtÚÌûàAãôB?U#(Î:§ÁâìüЦÍc¹€EdöŽÛï5téÇ- üMË"x¨ïêÀƒß,¼uö‚Î…O|ðöúÏüòÞ/O›>27Þ:¶mcÿ¦‰¢ŒŒ„€¨Ø~}ãã®ÝQóÈï73S"ž‡ÑhYà"’÷Q—`Ò)KU@{òÀaîØÍ‡½sxdà ‹#ÐéÄýŸÿü_}pÓ†°27—\¿qÓŽÿ¶aüúäØÑ‡O59YFzsÌO»Üç÷÷>¸÷þ±Ãnþø-IáŠO¯ù• ÍUXjúlt\wë¾ü̃Ýó?ó·?:<6º¯67}£ˆüe¹¯ÿ‹µÅÊ÷ÿxùçGî¸ýÞ×.ßÿ üKà~ô¾³i¯¿t>üÁnPàä{?|p¦³X»aÒ%×¥IŸ×ÓW"_Ĉ)æÑñMãÇóy•KÖh^Ý 7íz`Ó#§ ydbbhòÚ¯þ|oo>ºjÇî½Æ¤ÜóÔ±ëvNôÎ ßþ;s³õÞȪQrOñÄmwÝø™©S3Ûßúïûô×íÞ³ï™YžÝŸ>¹Ô™jdŒ ˜7^£Yºæc'&g®¹æõoùðWNnz@SѦ}¦w$˜Mñ4Ìç¨6ãÖ¯|øßÿÇü…75+3^ü|ÿ`ßÿþ¯~o|Çí÷nþð à+À{€wÜ~ï3Àýt{ǪKR_ /Û Z ù¹ÑþàÔ_{VOÏÏ-Ýô ÷•$QÑÀ½ñ5×?×ÓË^+¨±ð“ïþ¡O§h‚ì¾vû‘]×n!ðÈ‚½ëÍ7=yÕõ7>98é÷ôÐ4š÷»±Ï÷âïÿÑ;ÿRõAo»eˆO}®tÿ™šåôl•+úJ¨âšÅVÌÕ_¸cûÌ骄õÜøàu·ök_ M2's‹‰+ß0T»íîþÔõ…O~ê‰g~þ½¹ðð£÷ýÆY¯xø9€;n¿÷ï¿Lwaö¿UxÉ Z ¿ü3›ôßÿÔæ3½åð³KssÇŽ™×ᲊ¨J.‡q)6`B‹É…PñÂ?‚×,!Í«È`Ù0Û²Œ–TÄC\7ÝvÝoyÛëÿH30¼ ;WV(¼õ-7±mc?cC°[÷mzÍ›>܈:±Í•ØóÔFëdœ(Yf h´|µÈihS4uLŒ®¥õ= üðc?z_ý[…·º´nôRøWïm}äÓæKSÓ[ž|"½îîÜ`¦"« ž3‚±Šs‚Ïzh¦dqJ–+ =&çD’L5çwÓU®¾nû‘ )H¡½eÈ"À ïø‘«Øºu3ñx•Z'?ý=o~ãôC¿÷ÖÏÈü+·óÜ‘âyLWê¼±gœù¥: ãäÌ|ÄPO óµ6£ãC«N¨<üè}‡€C"£ ò‚Ö‚÷þÈp:6RxìädeÏ'ïŸcSAÅW5ša<<k8Gæ‘4Åd efzB%ê.‘l9/.Ë ŠRYH9v&‘ÁeïSO35Ó|®L9gqFÅ„×ì¤IGà)z)ÎäÕZƒSÕRÞ0=ßqQzÁKwÖä] z1ÞwϨnÙ<ðtµ²øÜ§˜g¤¾Å„6Äbn®h>Dm¦Ö$—Ãzf«)}E!É”d%åI¡T²X‰9pà4â:|â~rèÓê¤4;°i´ß7ÔÛÙ÷ìaµÆàû>ÐŒ2:qÒÍ™·‚5Ðh¤1N/t²þâÄ^.þÅßw7žxæ«'*‡Ž4Î#¡1x˜\(& kº“õV+@†4#%·œÊø¨Îu{że×Î~®¼¢ÌO¼óo1:2*ª> •6›FˤIÂb¥¥3“×QreC«ZãÔ|‡z5¦ºT#ç'8稴:ÑÛnU²«/:ùw6Å;·÷=þçLf¾sˆŠ'HÎâ…Š!b,bm÷k*ÎVéó¥Ñë âºÂ·èrÊK¾à12ÜK„Ðl%¨ªÀR­ÅHÍ Y2׈Š»újœiX* Á†¾ô÷úôõäI’TRe懿M(èlô”‚3Õ¥ÖìÑÉÄõ¢(¡ ½/4´ˆ5àYÔxÝ”+à¡‘ ©C4ñÀXÔ9ĥ˱pÝÉܾ2E”‹Eš==ày>±‹¥§¯Ä¦þ”LIEH%(['J¸LäôL[J…`q^õÛ‹‚VðóïÜœõ–s§ö®j ‚ÁÓnºsà—ópš‰ ƒnjGÏC=ífO‡>â/ÿÏ÷ vÇøìNéÞCS´Ó /2¨7»Yº¡;ºëª*õv†ÑŒ‚çê ˆã˜3³æ`o®ýjÉãU¥  ”X˜[LHE Ú]û$ˆ®äk†ˆgÁ¥Ç0X(dËÙŒV Ân¦sà{ÊáI!+Œ¡8zzË:>4ˆdVkê`ÉrÅæ!ŽM9:qŒÍ”À:6…¸ÌÑjŲÔL§ä¶ñuÊz•bA/¾M?ðTT…L4 D³n†V Î R Ñ$ƒ¹9€8C[ÑrN1DQ7=ð»#aM`v!£ÒÎS*0àg˜ÐRo/’1Zrlë£Å4Ú†Åf›¼G¹(äCœ¤räd%ݼ¡gf^s%t^Z‚.Ê¢lñò¹­!±-‹jäIM—Ò¥("%Aqh=B· £'ó ÍD4M—﫺DI83/:±¥Ÿ›w—(\\'ôZDqë·ø >'æb*õâŽrBÁϨÖZÍHªõôÔ½~½½½\ JC×ï(PIp‹¦HšJw…[ö0tví+ Ö@3ƒÐÃV5ç«+äU]õdm$qÈà€åæÚD›Žj³m4ÇÆ¡ŒFª|õp›Å¦ƒ(RcÍVÚHž?Riõôä§Öñ5/],è|ø½ÿ7gúû©øZ­+N%µÒ%KETUm'hÁõ£ðÜ4ÚMÝ |ÉŒTÏÇ=Ѱ(Z*¢Wl€±A¡YÏì³LäÙ¾-¯ûNyºç@Æb+ÕÐ¥8ËFJÔ—ê,UZZ­'‡êû·¬gë¿0/Hdè¢ÐO«“&&zóÇΨ†92„Ì .SUPçƒ&ˆ;:^5ŒZ꺦¡§6—#1¦k”5CsöË(à õ* è®m–ë¯H°¥!}îtÄþç©Fm¼,"v1=9ôéÉGÒh'æù#‹'áï_ó- Yë„óÊñu’¶XúS#=ý–Ë;¯‘cÇOK9¨$©úõ÷\1^vM6àUwC£Ä5ê¨}ìt§xã®ùÀ—>KÚÉàøzån¡…Yj‰×›ÓÔó%Q§àD’õSåÔkš’<_÷¸(6àÿΆtfjé艳'pº¦<}J)xÐÉ`)Õs€ãbL‹­6 ¯­ÕT~¢Î#ÏÌsdªÉ Ç—äðÔ Z‹Œo*ÉÔä¬mTOÊÖ11SÓ)…>ÃyjTnͰ]\X “ɤïyÏþán}5n¯ÔÀj>ì+…—ËØy…™xøñé¾þ¾@Kå‚9~2q?ú½¾~ññX"ç38ÐLË9“eâI'óé-©ÖÔ|á‘EÝw ÂÂbM+‹sÚh×È’Œ›ÇIZ™œšœÌ 6Ó×ìÜÀ‰“ 4²@ŠÆãÎ׎133•tbyá¿r×ôÅx¯aeüŠÇ«ºP¯ïûXTÍcã¶ñøÓK:9›rìXÅ´Z){-éƒOM»ÏÜ¿ä¾üDbNLf’të)üâbMÁ¸µ|¸õ¢ö‚|ô箃?ûû_(ö µF2Ü[Œ{çg*¥Ù3ifH§•ˆ¦v”xÆ%c…¸xÕXl£ÝI*±ËâÏôû_íï­† é¯þ»üÖû¯utH|}‘Ä{?r@â85ž5â‚õlöÀï¿íÛMÐ/ÆÊ@ìBz€\%¼yﮕo0|'áÛs ö72XY¤=l׳FC`—¿!u^Osµù€å¡úùw¸Œ—D‰¯›ðÜX‚VrÐF׫Vƒ0BW†íóÍ­œO Zé^£;×»vßÍ.›—égAuþœžÌùà@ŽÈN‘‘Þu®çw1dÐÒæÎwåù€;ÔA{@oYÏ*~·Bd¸zà=ïnzçT€ê¼[Öàäu"#7‹ _Þõè _~d”î§Ëöð ;ú’Xm>  <²î–V?ìytRuîÛé«å— "#E`pÝÕòøhUuþ¼iŽkØKrhsp hÎ,ۈŮ¢d¹ ³Gßk9%÷¼œó‹V¶J £ [>P$ÝTVÛÞv- °ÀH˜^»ü38ïß]8—ÎnE5à0ð4h ¨©Î¯ú¹ä5ng;$ ½@™îG‰JÀÐòß¾uCç妷jkZþƒêYÿ“—Ñ›dõ{ÏYÆ‹¯]­Î/~G¥»¡sX »`»D K«QÏ Ö¼¡3€È—{CÀ7ï!üÝŽ¿£žu¤tßT_uáo*ô•n#%2¼"øuTÀÙu9W‘kaƒWúœµ<ÿ›.V@Uç^qÈø+à2Ö—}úKŒË ¸Ä¸¬€KŒË ¸ÄøÿY[ª¾iÖ8àIEND®B`‚openchange-2.0/mapiproxy/documentation/pictures/mapiproxy_overview.png000066400000000000000000000672261223057412600267240ustar00rootroot00000000000000‰PNG  IHDRƒHÞÿÐsBIT|dˆ pHYs × ×B(›xtEXtSoftwarewww.inkscape.org›î< IDATxœìy¸%Uuèkï]Uçœ{îÜ#ƒÌ“ *2¨‰…8¡ó|qŠÓSã£/&ãDœ¢/Ά 8%È " €ŒJÝôxÇ3WÕÞ{½?νÐ4Í ^Îïûê»§ªvíZ§Nuïµ×^ƒ¨* 0`À€™˜¥`À€ 0`ÀÒ1P 0`À€Á ”Á 0`À€G0n©°ã!"ÏÞ¸Õ¡w«ê϶Ónتú«;éëãÀÁ »]U}æ-ßêÐZUýý}ìk`·­ýJU[÷G¾Dä(nO›ªzÉ}ìg8t«C7¨êÍ÷W¾îŽ28ྰ3p,ðY`0µõIù2p$°ç¡0z'}]Ì/äöõC·°U€Œ¾…=FE/B ôP¼ƒ­ûǾÀO·Ú?x+€ˆT€gÏVkŸÿ¨ª³Ûôõ*à[í üúÁ{À#ŒïqÛÿq¿f+…NDž œDÒ» h¿>œ¡·â<˜Û¿ïï>ôà‰=`@D¸·ˆÈ€SÕK·s~ p5ðKàEÀˆªÞ™2¸xÍÏTÕúƒ òý"*.˜]V©2a„1ÀEp b@ (ýý˜ ýÿôçCä#ÌZ˜1B¾´ßfÇBD.Þ¨ªŸØæÜñôá-À¯þ>X ܦª›·Óç_UÕ‡«2XYØú—¨U "”…*Å`²òÀ "sÀOUõyÛ9w&ð8àb`3ðhà ô›ªê»·sÍ>ÀuÀ»Tu  xÐX<¬TÕ "OF–Xž{Eˆ$­œe³],…=ku†Æ#©`@p²0ÀZ(U‹ˆTúJᤃDg(Šn¤"s~Ÿ kœ¥³”ßug#ð à+ªZHÿ7ø(ð×À߯^:ñ\T‘"0VÂrvÊ ûZa$‚ñ $€8ÀôßÅ̦)…ö'&ÝBi•ÊʦnÎìí-ýî7¯ÜvR""+€w‰È?©jciD0 1obaŒðp ¨jüØRJ°¨îh¨"ÓMöØÒâàŽ×U&•,ͨZÑZOÄ,˜X, Ë ¥@EÀ!°°ô—-}ÅÐ XÖ*Æseù\Écm`ýå·©eËR}ï•¿¬K¶9Dä£Àëé[cv,NVæ»ì• ®Õs ilÖ·:E¥BDÕŠÈbÀ  $U`$–¥Âª{‘Cž)QÖU,7$†¹%û¢¶gVÕM"rðçôÝc®øƒ 6`ÀV8ÐGe÷]öK-Ì€ûKÓåüàO—ZŠn®£f9hº#äj·‡IRqIÀ‹­yé = u…`Û_FúÊŸ,l‹þ„‹@¯ßœdá¯fB–¥x`¢TöhzyɆzÂoR˶¾nîmú¿ÅüR ò@#¶“ëD£'«§Ú<ºÙeKub9ÕRp-%Iqý‰ŠQð@pÙÂd¥ ÿþY §?qÉè+‡Æs†! õ;uJõ‘#l±Êº,avÁê=à~²`Á>š¾;ÕK,΀ýA«ÊÿYëxJo©…pÿðœ[ÉùÁR‹±Ã Šiõtå›õðs²—‚ORdl £‚S° HÈql hGð(a>1TÀ˜¾–Ò_’[Ä5úÊIüØuaßi"g©Eí’å­¿­rƒ5 þMÞ7^AÿÙþh©y tý¬´±!‡ya¨Õ‚$Å%ÛîA%¡(•¼—`êôýW±}ŸVkn›¬,NR"ý‰IBÿ\dÁßuq³† à{äg{l¨%\W±¬ÿC?ƒ‡"r$ý “ƒé>¯ÓÐq_DV,µ X>ƒq¨ª¥­›‡M7e—n0cbb( !"&¶IÁYrŸ#2„8‡)RŒö• /0¿`uQ=1‡9×_®(t IÀ ô­ˆžþ5þ,ôa# 5a¸L!8™+Ù=nÈ,kK{éžÖŽ…ˆ<ø ýe·S–Xœû…Ô¶ÌéžëgâÞs³ºðš¤Nü²å¤Ác‹€Id`cÀ¤  ú–kÍ•ùD¨%}¥C¶ÿ~V鿃‹,Z Û 3ã,¼—@ű–Ô\dzSŒ\ LW·˜~äü€{ƩܖF+/RÕÓ–PžûÃ;Á5XŠø‘28à…*f®wÚ0Ã!S-»ˆzåhU{1š$©ëôăԇHF†ÕŒVÅŠU"âUi‹Ò˜„®DÁ êÁ;èõúr»ÚOw‚ô} çµouQnS7±Z¥¡S*Þ“•žÝϵC)7‹°Cúbþ¡‘½€ïÒ_>IUwHEeq²²fc|â––ìÑ$«F;d$Ø”ª1b!ò1ó d¸Ž´ûÖik”¨ÊZgXi!UhEÐêû~„³ôßúô•ÀÅÉŠQèJ?àkñý\œ¬¸TM|È Ú­ûŒW¸p0Y¹ÇœDßr{}Ëà·D䫪ú²¥ë¾1ÆÙ_¬(îøxέÌñÔ×”ÁTInÞä›í°{;·Ã¢1€—ÜklÏœ¬˜‘ºè¸•Ò{ªPd™J!A¬*bèYp"ªèú9H24Ë ÙFÇj@@U‘ÜéDb¤©0m@K …q…Bn?Øn­¦lE0…¡,Î{nLV×%–æÒ=Á‡."² pý%ù§©ê5K,Ò}bëÉÊLÛ¬VC,Jg|žç6º2)º3ÆF#2:JR¯÷'+X¬¯Ê|TÚVX¡Š¡§ ¢ ‚Æ~$±–}?ÖNV,ú*Ìémï¢ç¶‰J ¯hÀ¤P‹ ©hyŽLVîªzíÂÇK€SEäûÀÉ"òaU½j E0àŽËÄ>¸¼àôÃRžõ›ܸx¼Áñ‡D6¬ãÒ³¶n?ÏÑGYöÞPç‹¿¿­÷¬,øÞ!†G­æëW Uí÷ó¬C-mâï±ßÉ4cÿ2Êyow\N3ùá:ÿú¡Œ“ïÓ ¨t%p½s¼CZ Ü7B ]³¾}ð‹ý—¯µ£#\³áóè£fijQ [¦£ V¨t+’&V»)¬Q†‡¤1R—DÒ+ñæµÕicÄyEª±„Ѽ'=ɸ%Q¨YL&ô‘ ¥2lûƒíÂ@¬ –C:£bbРD›’…’]š%Yè¼Kü8RˆÈ*úŠàpÜör_޴É?~ãœîÔ‰/ò‹ˆ¶:!T«ÎUq·UÊBɬôŒ•4Dr ”A(¬!u†Š@/*zÓ,¸jj”¡ï»0œê*D¦ eB’ƒÏ`¹é+Š*·MV\dûlYM0Þ1ÚSRÒ(Ù¿j¸(uŸ ?§Ò·>(ƒ–”;Ô&.øö¡ž_ÿ[—So-7¸ÑœõYÏeŸßºm‡÷¬,¹à‹9ßüðíûøÎã.j‰M_ÄN¯bÑÓØlF3× tÚ4Š‚9õ´*Õ@ðÞ%åæÍÖ¯ÕbýzÂÌ<.QfM¤ÝÍ ›º„[š¤™2W…›»Ú÷3 ·1ö•B4|¿‚g,6qT¢p@î[êgúPAD–ÓWwŽWÕŸ/±H÷‰H¿®}ðšuÝ«U+£#¢•z*yÐ2øPdIÊPÍ…¢ˆ~ãzõ³Ó¦æqs³±=½E;3314£'ø@/@(ߘ‰åÍ7QÜpåô,e·K™y¡dºÒš lîR£Ø!Ð^¤7 ‚_x'}„  ïç»iㄚ€Ç‘¨¡ÒòÑ.xÔR?ˈɅ¿ƒ´R–œí. •_)§”\˜%™7yáS„êåJkõÖíz|ñ†e_ŽÌ<»Åv­ó‰µ·õ‘Þ0Á–÷̰ê%?;xÇÝ 4ÏSŸY··0²yˆž—lã“`ØóËîÅâ~““ð\ñ˜”çž?ć7œ9ÔåŸMyÖ5=¾rL¿Y´\–üÏáësö Èzc\ô?guøðÊÔ.†U7Žrþêì¸çˆÈK}vW™ˆ¼oaJU?ù‡’ÅÍ~}]ói%©”‰¶Ú¬Ù¸rÔ±ßj Î8<Ð.5éæ"Y†Az¾nÕ—Š !Í$EË Í ÄµÊÍg …B2ߖ̈ÆJÆŠ‘*ëÊH£(I³ eÕ (2Ÿ#óMìP…ÆŠ:…1ÔJ%S!äDÑŠe6ƒenTQUjª$Æ¡ÁC Oèttz´"—Cq·áaÊBíës€=€¶W{G`¾Vݼ¹8<ª¬ UüĈ+GÆí57ßA Ï‹¨ÉˆScÅ8'¡ÛÍ2ÁPAÕÈÌ,¥µ”õ:=UŠÕ+%Y·Ñ×z9¡QÚØž#ª‘jm˜r|ˆµêy ñÓ)qÖЭZÑU_H¡¿Äl¦ïa“…ÄB‹ˆð˜é{ŽW9ßøte"R^ |MUÛ[?œ~™¹ýwxÀ€%å–Á>’ #ç¶xÍqk_`Ùç?·mÙô„?ú¦aâÌ‚ÿ:éÎo“οËrdÓŒŸRrÁ?*ÉȺÃ;¼÷°mÛx.þ—’ŸŒÌ°Û«rÎø”2·[t†Õo(øÎÊ’ ?ÙჟPföêñÕÏͲÏK”æÎ YdËÞÊæÝ”®48éŒÈG€Ï•Ïl°SdgÍqä1w'÷€;ðRའÛ*ú¹Ì÷ßð‡"Fuë6vìå~x§eI¾ï.•8ZñåÊQ¼÷1Þ2]Æu3‘õsʦ¹¨½nÌ+ŽNbhf ±R!«TŦ1I!­%$­¤ SSÝØéaUÑñ!ZãÆkÌZ! YÆÆ*ØPšóï µŒ0TÁ‡@hF\³$˜3€5ÄvAœí;`‹ˆOD²D˜Í …“9¬ ’f2ÙÈoL|¤ò\ú5‰«À9"¢Ûl­%–ïnñA³[¶ôŒ˜e•?>buÓtoØäu® µ„|×qz»-£Üy…0\;1BÊèÛ0^—°|Ì…ËlÁÔ Õ ¾( ÝŽÚà5›yÌÞ®³Ë*‰«W¡{îJ}ÏU´Çêôˆˆ±—àGªx+øó°n[–L;hG…¾ -Oðд0#.Í’µØ"b³”ê|W‰‘t©ŸïC€Œ~ ÷¹ND.‘5ôKuŽÿKU×,©„p©eŽ8­ä¼·ôøÜyJoÿ õó¯ºõü<Ç=¤7Ìׯmò‚ÿÊ9ó J÷”Eß@¥\5ËÞ/Sš»D¦^ä8üÍw%HƒãQæåüƒ޼Ûú­=>9Yûæï=¶Æ{7G6Øv;×ó«…êq²Âëß:Ä?®ŸçÉ?÷üæUÀWSN8£Ç—N˜`í§Ú¼eˆCÜþ±…ûþ¿Å{XöûdÂÑ¿»;YÜU}ÖRËàƒV¯úÝÌÖoiíœf¿vc'L7­ìµzHŒh¬ÎuÕ“¨Ñ^¡ˆ‘("¡ðÄÂßZ²«¨lT’(b FñB’@šéÈøx•ZU(B¡†€ÐIÀ[Ñá‰½Ž”µ!¨8$h5‘á*„Ai$Š_^¥>_ S$=‚¯âë †HÏB ukH¼'d)+=WϸüšâãRàýwqþ!m5íæaøÆu­ÇN5üªGí4Rì´Ì©÷1Ì5 i–LÍgÚÎÒÖhHŒ ‘ÂlR!-¼@­Å/ÔýQ©¤ÐBsÞSäÁŽŽ$:\£gd6:Aœ!²¤í‚ИӲRR‡ŒÔ¢€F¨!7BÛ IÅPm–2\Ãá)멤 Ìù~…ÌZŠV2YÞ,ô±UÇõ©“Gr“9à©ÀqÀÞôÓü\ |øœªnZBÙ–„ÇñN Qòœ*¼æAygf9ðù‘5/®ò–7l1à.”Á~xééNÞýjòï ÕÛEŠy~u’0ôëÏ\°Þ©kðô£n[bÕLé,Æn¨ñÚãj¼÷%y¶&pÝBíÂ{¢䜾/`º|øó]]ÃH›ÿs˜eÏÍàÖ.©8ž°¦ä—ûl¯Ÿ!NY—ó•ÎsÌÂÐ/G|i”³/çòïÞYÁ|OD àÕªzÖݶÞ"òŸÀáÀrÀœUë7·÷˽®\µjRº½"¶;=Ê27Y£Cµ¨¨÷…–e‘áJðâ¢÷*y©cDň €ÁûžzÀ+)QBŒ”"PÎD ƒæ&I”àEm‚›ž÷½ ô¾S«eÎ8²²¤—¦ÄP"uAìBÁº”àLAk,¥ZQÍgÛRé”1"C)&*¶f˜ïFêÆ£`A«­Ô+ò[#·Ë÷pã "Ò~«ª¨êeÀe÷´9Œ~ž·#ïrýs[¿¥µ³MRfæó²ç½$ªŠ;Ò Ý.¾Z£KZgéG´bD¢€*i´¬ÊÆ‘!¢W’Nï=>M‘Ìà*B¯ç#ÆZ± ãÍž>z´*Çú¦9ppÔÂöyàâûØ×¯]ø|Kd9TÅLÏõvíæa§=w_ŽC£åi¶b¼Y•Ñz¢J†^3B0!Ç¥‰“—ÑXÓ_WU1Fú“•êDDDPH¬ar²¦ŠR–8$x° Ò+ˆçK‰1†¬šŠs ã>¤^L?‡fă-=ÍŠÁÖ­væRÉz…†Ò‹ÔÁÖ,­R±A0*¤b¥Þ)801ñÆ,1g áÍôBÞü–~¾ËûÂn }@ÿ}˜Fg»›}`{gRNøõZšw£ Öùäs¾õ£:Ÿº9ç+ËÇ[¼ñx¡rù$ÍW,ëòáemÞuþÖíî UÞõ³&ö¡vÿßu>ý5ÏÅu¥gƒBî(Û¿]WpæºǽµÊ[>ŸrÒ\“—9Ì/¼«û ñ[zœ:Üä¤OØÙP ünb˜¯_Yeóy-^7«4€V½#áØ3‡ù晳ìÁBU¯æþ)€[÷õ€FvGÅݲ©½ÿæéVZ©¤az¾Ôv7hµæÄ!Il@5j¢Öh飩Ö*EÔ& ÝV‡á‘*¡ð IÙ¢bŒH„¾–§¢VP#hˆ˜4Š .! ÂÆ]¾¬&IŠŒ'8‹¶Ú0׌R2…Xò2Múuì¤ôˆF¢Q$qØ t5RÖ¶4a¨Û3½ÜK”*Œ¤H&´ƒRE©¯=çd¤“ëÊZ&«e'Uý-°ûÔ×G€<}Ýz¹¾ycóÀn^šJ¯ô;-«êÎËkÚìšÝ@»0&„4M‚ŠÑ¬V•¼›#Ñ3V¯j³«DEŒ”c$Þ:Ž¢bHbìç\ðÛ‘(h»âpÝÄØo#‰ÌÎFм­µ˜h¨;¡%Mú©hD 1*bÁäÍ ¹q²†¶£Œ6šÚ)r •*R±˜T(ƒP ïÃe )K©£W$V– ªUõñß]°zïþ@ôõPF°óÛ¦©{ éòÑI¥kª¼nZ¿Óü—‘ ¶Çg'ïnå²àµ’OTxãFËî÷(0ªÇ'Ç-ûõžÞ½;YžÞ¸§éîr¾2¬tM…W> …;¬Û ³Býj€”ç´‡ùêu ǃPý9€2»—e¿/m}]•¿™2L|«Ç¿"LL CÛU„¡k„ñ;<øŒ´2N|±2õäÏýï.ÿ÷³k'û×T)Œ‡…Ï¿ÆKa㣵—ª½Ü«1ÎתNH jUk­Š ÆˆŠ*bç\ !ŠjÄ«E¯«™S«1ÛõTuVƒ1Öô—xc¿ÊƒŸk°råÆ*‚¨4*Ü´¾CYŠÖ‡†jNÄ$–B¬"ÆA§ *”>šJbÂPF™G©æ¹R­ŠÏRH ’4÷š¥NòVŽ¢žé剕ÎRÿîÈæéΞ×ÜÔ<ÂZ›D±ÑYÑ‘z¨ibÕYƒ1&kоÙOuQLÿý"*ív›,µ&I+Ú)g-ÆHƒ.¶ÑßWãÀ{%ÁYUBP­Õ FPkéÿذ¹¤ÝS®;\f“e}¿B-Š~ac“€FÄGèåÊHE g³m[ Qýp]ÌDµï [F ¡[hÄHO¢®«WdíÝ?©eDä>ë S˜5Bzõ$½» 4œa·WGnþ;ÃnïŸàÆÏ̲×_nø a§žà–\ëæ8ø»Jñaì›–=~ ÖGn9Xiï1Éüúýíò†È-o²+ ÙhxÔw•ÙÝ#›O†°"åyÏáô+ï?Mõtaìç†UW€óžªÌâGø¯£Sžs«¥{ ¹’ßA6ìôaxSä¦ç+íc…áÿž¤qknƒg<®àG§A²Ö²×'„‘éÀu'(ƒ¡ØO˜ü“LýÝmrL~H™9Y=òç”ÆòÀÚ—C±¯åÀ×så™÷öwXdPŽnÀÃŽ¢ŒÕ^ÇŒq&uçH£vi|0š¦ID"‚`…¾QDˆò¢0‚Qg­&‰¨u5ŠÜË-›Z¬˜¨Ñ) ÝD„QQÄC ª"ˆ±¢¡ÄDQ­T3-Š Ib` :9š²fmCò¢Ô¢WÑ¡š- k“J•Âe²&h44[‘"ïi–Ôht`r”®Fª!¢eèg¶)X¡%J% ¡Ù{NÔí•wÿÄü¡™iä+“DÓ‘!Q¯½Ü‹±#D#*‰ŠëÔ1ãlCˆFU© kð¹Æ²w¯1ß-7º¸´[rþ[AÊ!>øü*oŸZhû“iÆOQŠý¶î±Á³VfN6¬øÌ›þa«S_ž"¹ pÍß®ý¾e¿û•×óNû ØÑ!fÝ^1ÜézmDÐ(•4u‚ª”ei|D¼"ª*ÖÆô]¯ÒÒ$Á:+eˆÒíéõ¼$©•J}˜©F_䬃zEEQ¢"€Uœƒ4²j&ÆZ¡d"Ív!k×w¸æw›L«X1‘bc—bL(Ù IDATF³Ë–é®¶Û¾˜™‰I^Ó h½Š&‰èØP%Ž IèAÖm*%/|¯šâ´_®$%&V\´k,.u$ÖÚ‘Òkm©·'Fµ^\ÕÚ¨¢£©ª³b}1 TMâD+¦’Š©V­("ívÏøàÅ:§Î‰&Y“ ɦÙBÚͦYVG¬EŒ1’—*e‰k¤ŸPÅØ¾¯CPÌP½&ø\í[ü¤ÓS&F3­%%›·4dýú6é¢7×P×ÍÕ£Ñt¼n•P¨10ׄ´7^'·BVxb§$†Ht†VŒªNç°®9áHÛØþ¶U+ªZãÞ fºà‡Ÿ.øÞ§Á4ª¼ã[û*[žvj”s¿tOîn9èË[ïñÏ—€äÐÛuÛû+]éðž• Ž?dž§D0F|j¥'*ã ±,ƒzß[œ¬%ª³†zÖZg±¶¥îƒïû3ˆjÚëOVªU§e©ûC‹f™‰>z!Šä¥Ž8Z…‘2‚ô˜DDÈ‹€5kú“gE\âbˆŒÅžÒw!®Õ˜HºlœîiŒk­ô¼$óMÍ+U‰##FZ-•^YR«8¢ˆ5Zä1¯f¦ÚîIhvÑá 1DU@³Dl£££½B–×2ï瀻dž§<)²áÂÈP® ÜðÞ&/ºxë”oBºFÉ÷Rº²ß}ÆsÉSAãÈŒò“_,ïòÑIˆ÷)…@w¯ïò±Riß¡Fɹ{n{L¨]¯tŽÍxñ÷ï,ÕÞÁ½öŒlzAdë[üå­ ¢ ¾ý²ÈÌ 7 pô/Oz@óÇÝ[ Îx‰aòâeäI(9÷½wÖV™5³ìýåȦ§:þ–eß®û«i&?tOîUò“¿-øÆV?lY…²~ÿ¾AXqÿ®ä‘8Ó[9Q½~(‘µ1✳Öµ£õªÉ\b²ÄÚ²,M»[ÚNÇ›v»g»y4}ç}5Ö1ÖH^xÓj—Òî¨ÌÍ2×èJ¯Péõ¢t{UEEÀ¥LÍdR’Dû©e@±FCTÊ "Z«bV¬#NAQ%hÔ¹¹&ÝB%ËjéÄh…D$…—¼Ð¸i:—éÙ\+Uk…v'`ŒŠˆ’f†¹2”¼D ¯j ¢¨w¡ÚÉà ÕÌCˆ‰ÑlýPÍ••,5Æ9S­fB4Na4F1"¦ÝÎM«]ºV§´yL HQº=/í¶—ùfi¶ÌôdãæŽtº¼T|„P1Öm"ÓóQ(‹~ùÈ„°¸4lÔ‡HéUŠ¢¿œ<99b†‡ªÄ "bÐ¥ÓîJ³UŠØ*£U ^Ón·°o~Ïþõœ‹®úãéÙhR«1MU ñT3«6Át<â íVRlPh¢Á ÁL–éæauˆš,õo2à¡K—(9ÿàÖÖùÂßTyË@Ú9ß>µäì[«ˆç@X=ÇáÏyàîî«ý¾ë·ËØå”{´¼}gãQ¨ÿHiýQ“?¿ÕïP™5ž‹_·m{ËþçôøÜk·=÷@rŸ–‰…±ïüà$àÑ 62wœ0|kÔN`Írenœ…¨œÏ>¸ä“ Æ.Ÿà¦Ï6xÎAßíÑD6SåÍèñ©W+ÅrÃò_ŽqùW…ª–œ]mñÚ#[)ûæ(?¾`–ý_Ùød!™ËxÙç‡8e]¿þàÌ BçêV/SòåJ¹ë Ëß•© Ö~rëï3Ç‘'*~r’¹?YœUä|åâ&qaƒgž6Â/áQ¯©òúÓ>gØýg<ÿ¿K.ÚK)ö(¹è3,ÿÓ„gÞÁ”;ÏÑGy~û $<á[‹J¥+strdêp!ÝRåͧVù›©m¯oðüÇx~ù´QÎùôýz8#‚ÖkÉÌ®«‡¯¾äê-;ÛÄYk+’fN'5ÆV'猫Úî&ø@âj25ÏÓŸ¸ê”vÞÝqȹùÀU(3L°y»ÕNî Ë^F6½¾äìÌñøOYöZ[rÞ ‘-/†û Ÿò§§ä|ýØœ¯ž^rö@6§l~:Èâø~«us”Ÿ?ÍØéÊô˧vtša¯‘5+k«l>~’Þ ÷G¸Ê ã ï–\ðO‘ iðÜc…Ú¯ÀÞª=GÖ¨´vþ»Á3+8ûó†?ã8ô›« øÝ>k>`?Ýqèׄjló®ïÆÎ²ìóÀožeïeÜò±&¯~z±OM8êÒÈ ›„‰Ÿ;ùyà÷{Ú‡:ÿaèy‘"Ž2,ÿÞÖæåŒ“›-^ŽçŠ£€K#›ž¸úl` @ÙøìÀ5—¤üѵ˦ «Î·ìuMÂS7{οµïyŽ=²ä¢[öú”•‚³¿Ðä¥/æ«×ͲÇ;”¹£,},²æ˜6ï=-åù¼µÂ7Ï“.ùÕ{*¼ä5Eðî!®\V»ñ1{M^xóæÎcQ†!†¨&ÆhŒŠÄèUkµ4Z)4btj¶g{…3“£Yœ±qr¬.Ív`j¦ÿýëg½yv¾µj—Õ“k¦fçw`ï=vºÎYSÞ¸nóž!F³÷î«~÷Œ£>óàý–ÏÌ4½üð§Wwé•kk·{õN·¨=öÑ»_vâ O:m¸–5ÏûÅå/<û¼«ž:>V_×n÷Æa]Wþö¸§>î[;­o]úÛßsÚ÷/zÉŸ>ýqß|ÒaûŸsýµ×=ö ŸþÚk—¯Z¾Ñ‡èZÍöðÁ‡ìÿë§<ý¨ÿž\¹òæßþúêþñ¥o¼aÙòåjCY{—&·ü¯WžøÙ믾á€ÿøâ£×Ý|Ëê²(d×]W^ô1ûöžxðYy^T?ùñ¯tíÚ û¾ñM'¿éÊ+®?òŒoÿä5Ï}Þ pÆ·Ïù«¿|ÅóÞôчyݵ7ö‘ÿûïŸ}ÕkNúÛ#žð˜-ñÏ»ÃSIm{Õ²Úïç[s“íN¡fpÖÅZÕHÔC´b¬DU¥[xQUu¶*C5B–8íåH¯SR–cDœ3êK¯ÞGF‡STÑD’$ADTœcýæ&»®®’Y+=oDDÔQï‘ ¼°ˆˆÖ멬ZQ‘õ›:â‚\Uæ[=WÊ W¯Žïýë—¼ª?Y)c%K)r%ÍRõªª)ý¬èNˆŠO,.JéE5YÈ„m$Xc$/â²z…2øˆ#¬ˆlxóöÏI~1Ëÿ[iÿ‘a×á{¿Y<;Æ/Ï™aùç#S¯œå1çså Oé ñÏÏîðîEÖ¿©`ý[úòÂÄWï‹„£\ð³v:%²ñ žKþÝs ܘñg–óoÞ—>éógœñžÈæ¿;e=7ã¥_èò¯ ÙíŒBã\ý–9žøÛȺ7•œ"·ê¦!Œ~;·¸×ÜGËàdC¨ý¦ÁóŽ \ýÇ¡_ñ\¹]Í´äÂW&ÿk‚›>³ph«ú©f~‚©÷ÌqÈñ ~‚-ï˜çØNÉùŸ>í]ÀvŽÙXáõ·†mGÖ¿Üqð{ǸäGÀYÓTŽmóÎgŽsõi9_7¬¼a„3¯hpbŒü¾}ç>ƒÅ*¡~þ¶G…l“Ò]uWÏ¢Æ7v9¥iÙãÚÅþ»üý­ç=—ý…aù×ǹöÓLì_rÖÉÀ{"›_žð´—-X9`ÿÝ.›žj.Ûû?ÿ™e#›ÿø˜C°aScÙÍ·lÙ+q¦óä#ÿ„¯6Zäk_øÚ[¯¸ôªÃÞöþ7¿±ÕêÖýMûüþú›öYµzÅ-»í¶ê‡ˆèûßóÉ÷mÙ<³ây/:þ‹ûì¹úÂo|õûo½ð‚_ÿ¹/¼ÿˆÉecöÛ÷KÎøö9õ¾wê­Öÿgï¼ãí(ÊÇý¼3»{êí7½B Ašô ¨t¤H+ŠŠò³±!öŠ +Ø¥HTz==!¹ýž¾;óþþØsC¡‰Ðó|>7wËìÌÜ9s²ï¼ó–jǤI½ V)W sænôÀY_8íc=¸hög>yî§—/[9Õ{5™lTyýë÷üÑûO?á}Þ«ù̧Îýåßo¼ýàoóÑ}úú†&âÿιð=ï;îôí¶›sÍ›O<ãÎÓ?x⩇¾ß¹·Þrï¾ïß—þzÒɇ|ömo?â“öÓmñ\èÅ?§0(Ý,ü!ðÃõß[}&ð$m_ŽÓrœvJÌM™*_ÛD°>âKRâØsKÏÎY·¾´_=žÚÎòoÔùõëüj£]WŒí ¶qÁ¶O}^×ãØ]Ü!páº×Û¸à!à„µ¯ ±ËB瓳&¹nýøA™LvÜ=Á0«/Çÿ[ñ\=¨Ÿ§Ø ö“»¸p~áü„[ž6”eîïw¿M©ÍmçO󟾉ÆTÔ[×wgí”qž¡IBî®±ó Çß ¾'á®0LJÎL½Äû¯î§ø³QÞ8'-•LŒ8ð®'jÌݧ”žQx[?ÑretòºW•Úd!¿|}OfoyÄ “ÖôÑÐ}¯Ò˜˜æpÖ|ž3ÖÇBö>e`ÒØ¹ã±÷fÿ %>DD;Ú¢•³§ç·çƒÕª³µ†³6lâÔ$±1adMYÉg“±"¨šR©<¶¬Ü·¨¢]¡‰"#"è!ìxÅî;lö¯7¼f»+EÐw|Ð÷÷ÛsÞ_=p‡?,YÑ7Ó‹•Ž®q‹÷SNñÎg/»rþÑß¿àŠ÷,]Ù7-°Æ%„íçm<›-f^¿ßî[ÿr«93o¸ùŽ÷+—«ùj5U\rYu4ê©wÀÞûí|õžûîôçwÛé&O\øÐƒÎY¹héf>ͪêm±- ººC[Ì…¶XÈš0H”hkk3ù|ÞD™0,Ö£Å+ª X›L›Ú»Ì ¶­˜+Ö&Ó§Ž[êœFù\¶išº|A¸å®G·=ò]ßûþ_w¢KâÂÞùRAÅX%—K§ÉFÓÇõ‡81êµ»#¿ºR­GF+Ýê½´3’+ähøæWTÄuv„ÒÙÑ;®w¹ªÊ£­œF32ÇÜ­çÞÒÑž‹ë1ºtYßD€Íçn|Š©'¾c“M§ßY(äF/Z±9@…µ™3'ßÐÖ–?¡g @6›©¼ãGý_¹\í¸ëÎw»÷žGvÚu·W='¯úÏŽ¶håÖ³»®š;£x-‰/•ÊÐy±jL bƒl.²ù¶¼éìÈÛžŽ¼i/fl>kìªÕÕÌÃË­4(2bqgœ~ô—wÛa³›=t× >ñÿŽýü>»Ï»ú¨ƒw¾`ÉòÕ3ÃŒ•öΉ|íŒc>³hÉã³Oýð¹|ð3ç}d´Ò¹héªiaæ÷xû›öþÉ~»nõ‡ýwŸ÷‹×îõªŸßøÏ{Þ008Ò;88,Ýmš‹¬Ôkéü;èà}.Û÷5;]µÓn;ýñÍï~Û§|à‘¹ÜyßΪéýžÞîÇtþ—;ò¸C~:4\î¸âò^÷ÆcüÍ[Þyôw8h·ß~óœî›ÍfÊ?ÿùe‡T¸;åÝGä±Ç–m±zõÀ”oœý‘ýÃ0h#~Ûíæ^sËÍ÷î÷àƒ‹¶¹òŠN*rÃûì»ã Ú¶kÑâ¥D25ν¡ŸüEýt¹Ÿöï—8õoJcKË&gf9eè¥îÓ¿gÐ0ÉõÒØóÙÊ…ìu^ƒ?œ?ÀäQËœlÝTÿ>‰"?¼zˆ]>ÖOÏç,ÓnJ¸ÿ}†Iç 0ã†Þ…B× gx3¡í>ËÔóîúØ ó²ÊŠmÀ·ùæS¼˜ œûh º™u’лdlvŒNn¾l€q‡²Éù–Í q&á÷z~ÙÎ¥w§ïøën;uˆm ŽG‰Çžºÿ‘pÛɃl9>ÃQOÒ’ì𓘿;ȬUJ’SFö‹8þ¨´Î ç%\æ¯ú¶cñ`GÛøÕšíê,ïZj˜tl…/ÿr-3]Üsɳ÷Ó!"U CjΣëü¬{íÙÎÿSe^Œgþ¤ªßXûo7F|> n>£ø·—’þÑx³l>²ah}6´&²ªªÇ^]’¸áDJµ„l5¶ˆhSlD›a›:\¦áÞ±½é–ûvwÞÛ ¾ùÖ÷yÍ–ëqdB«6J¬ê™0wÖ$®™ÇWÍh+d‡Æwû[”PÞ«xŸ¾œ‡«y7.+Ë—.ßXD|Gï¸ÇL\é‚À9—P­yé׳àŽÛîÛæð£øEâÉßqÇ‚-J¥JÇìÙ3n¸õ–{÷½âòëO.óCÃ#¥žýð¢3OÿàI§ì²ë«þØÑÑÖ÷«_^ñ!U5{ïóêß=Íœú1Ð¹Îø¿ãúüË­íeªú¯õÝcˆŸÐ›{¤½ö?²¬²}©áge3"Æ«ãxçñÄ!„’xp’˜ÁÁÑ(‰Ãšó;ÖU0bÒÉšÏGUU µùÿ”ÆÀ­w?´ãξècùáývßòš­¶˜y×Ï~s݉A "F‰2éz¸½+ç3F*UÕ0bçÕÖëqÖç£a€Ld¤­½ q3b­î|±ÒQ0&m³°Rèì(ŒL9í‘DÃ2±28Tj¯ÕêÙ|!_2ƈze³™þ °q¹T]ôwù²Uc+¤Z­¢(¬xàn?»õ–{÷ýÇü;\½zpÊn»osYggÛS´6"²5#ýÎŽýðž¿’ÚZ¤ªÿöû¥ÅóÃ0ÉY6ûgÕPŸ z. Øý¢v.ºwCôéy ƒ–i? ØfÕS¯ÏºZhIçÜî| Kî娣c®92á¶£ Ýw¦ oq¿#³Æ#'`ûF‘¯Ráóov,ÞòéwÇ„Ãä=ï­,Œ Sþ^äëèâ±±Í Çâ=„h ϧËih˜yIÀÖBšR&Ç©G6øãÞJß4ÖAÈi7«ß2Ä;í.˜8`Û3;™ÿ·±2í\sÁ(‡®v,Ú=`Þo<+çl» _ÿ¸Ìé»x–Ìó,¿3ýûûtpõ¿F8ð ·¸ ‡¾©Ÿ> ÐÍà)÷› IDATò¯ ²Å£ŽÅ{ ¹¾tø˜Ú×0ù[†).ÏY+!<¦ÆY;·áóEUsMÑeìËÿlÇªì ­kÑÓAšÆ³Ú¯uÎß°teu‹ÅýµÃ(2ímÆ¡‘\`¬iïÌx#Å‚MÅA+`Ц6]1Å»¤ùRHbÌ®;Ìþçßæß¿Û‘§|ïûãzŠƒ —ôMh$I˜4m w?»ðú“~ó‡ùG×êq¶XÈŽžñ¾#Îèíé¨ yX±ªJìŒf›/ç?þþÊc¯ºâ¯‡{¯F½òÆýÚ̦/xèž{wPï©Ö¡˜5ê¼q'½åÐÿâç8ñÐßùWcmR¯Õs¯{ýž?zã1|Ã9\pþ?šÉD•þø3;\ý—sÞ/úl±˜zÇ)Gý_[{að„“ÞðùoŸý˯O™:áá§ßÙçù™=Óñ }Þü›óèÅè‡ógDÐ|.œ3³xݪÁúâýy±7]&l¡º ÈX4’eq.0ožX¬ˆ1ñÍùiÒ´#XÒΈø×í vvÞÛãÙñ’ÃÜéâ;XºY©\-F¡¡­Í4÷F®¸æŽ×¾õè=è.ÞußÂݧMê~xò¸ŽUQ˜F‚ixE14¿Ü{ç‚íúú‡»ÕÅáü¿Ýxh¾P™8}úÝ£«gÖ:©×czz{Wl9o³;¯¿ö_{m´ÉÌ{g̘”ùË×½µTªtì±çv¿x|eÿô+.¿þä¹[ÌúG©TéüÂç~øãO|ê” …ÜÈ®»osÙ´i¼òŠÞ,"zÈaû~ïi†öCÀ,ž,ðó"ž¿˜u¿Øm?ű²Å‹K ~ üvC÷cŒç- vñÈÏÖw½“]=vÜη¯}¯_=|îÉ×~{?ð¤~YÞ3˜å=OÒê¤uÏ¿¸nýíÞ~%ðmàºZ´ß\Zà›ç¯[n !§]Üs)péúî[f&Üq90æ¹ó÷±{!»Ô;ùǵÀµë{¶éX²^ç•.îý=ðûu¯w³ôì±ã<ŸZ•çSg¯[æù¢c{6ÿãXk’S w†Q-^²º±]©D1— |X+Jú2WüVsf.˜<±kU.k½ ‘q=Å¡Wo»ém¹\éé. ï¼Ãìn6kòCa{í:çÆ|>Sùý•·ÐÝž)¿ýØ=~qñŸïܯËTœQ€Ã_·Ã%+š˜8õ†/Þfîô‡ªU¥³=óøVsfÜÔÓÕ¾<ñ*ÙÈ*Àö»¼ú*Aµ422îõG¼îç§m|§ª—l±}p»¶¾qúÆ3î÷ªÆ†«–N<ùðm¿ÃV7_yù ŽŒ” Ûo?ç’×°Ëù<²t«\.SzÏûŽûS§Nxx¿ýwúÕƒ.Üvåʾ™££å®¶¶Âàž{mñ·Ïþå×wÙeë˃ ˆ×7ŽªºAc‰þ·&ž<.÷À„îÌ#KWV·XÒ_ßÞ{Âb!Ò(²šÏYÖz#¨¦q*¢`ð© MáÔÅO,VÔ!;n»É­Wßxï^?ùÝßßø§¿Ý³÷Â%}Scç‚8qOmŠ wÜ·hÞμà{‰ówÞ|éãÇ¿·³£‹±@ß@Ѻ—L”®V­\5õ­Çþ¿_x¯&nÄÑÑ'÷• Æ-X½j&€ª"& $êTÜ~¯ÙõOßúÚO>|Ƈ¿úÍ( Fœ™n¿ßF΀*D›Ïžüè§>xÄ·¼’ˆ s7òà'N?ê«a@C±Vt§ígÝ:o‹oU¯:©Ý°ÕV³ç%Õ Î›;ýžSNÜï<1¨IOm+мzë™7O›4ÆÞ†Œ›8aÉ>ì÷ Q'½=yíl`Ä2}ã™ Þ}ú;?nƒ@£Ð✗ĩÆNeó-6½k³9›Üå½óÙÈÞlMš®iöì·þ‹ï?ll¦LðÈç¾pÚácç¿þÕŸNðǶëíí\~Èaû<֥ŋĨb¥³#Yµ²¿>g¤Ré|&“É.°`DP^»Ï¶+—+…¶BÔ0!ÁÌi=Ë?r …¨XD ú¦#vÿ팩½‹EöÞmιÑ;ï]¶™ô]ošðØc+Gzó™¨ê © ¼ç­¯=·^odkõFvÆÔq‹wØfúCq «Wû÷ÞöüSÆß_k8ò™@vÜ}ç?wtv¬D]0}Æ„ÁÙ[ïp¹*Ò;nü’CŽ<è'¦LY'J.o(—^sàî—Ϙ9yñ­·Ü·µsI8eRï?öÚkû‹úû†&ÍÝbÖ?9tïïO:áá©S'<ü–·öéL6ª4qÖ9oçÌÙèfñ½n÷Ÿ<Ýb¥E‹Ï–0ØâšlÆŽl4)wcÇH²âÅ¥]Éæ;»²¾ž€¦é̉ ñ!Ð4Ÿ‰BâÑÔ•Ã(à•(­Ô„†‡Ð‚ó`fL¿p×WÏžßÕQDÐæ»7Uã(äód#Q! C íí;ì¼íß{z»—y@­Uêˆ:T,VÄÇNÈå ™œÑj%‘\Æ‚ˆzçð vÙãscõª©Õj½pÖçßwÄŒ“<û-^ :ŠÁŠŽb°r´’L~xE}¯ZŒ !ª"ÍÅŠ°÷¶‹2ébéÓzúN:z÷KêÞaŒàßtÄF!u#ºÝ¼î˜7w£;*U¯Óº Û4ÐÄ¡cI¶z»‹»ì0{~šV;ͽ] ‘z{Ƹ׼óÅD¾\®4+6°µ}_À®Ë´)ºbuË„In|øë’É„ª>‘ļG‰ÊæsgÝ3}ã™÷dBÕ|üÓ4+ã'ô,9ù-‡>)lÈÉo=ì3cǧ¾ë¬ëx`ávªjkÆÆlѢŠ£% ¶hÚÝ<üªMÛ]^Ýi ¿:­·++jMÓ̯¨I­Â¼€ªÇZ›jhPcH¼‚$ ÑzŒ”ëh6B*ô¥zà~¯úó!¯yÕŸTï‘0DñéÛ¼³#‡j@µ^ “¦M[ð‘O½÷“‹— ÓHj#O걂±KÄ9Á;KGHºhqJd-‰z´ië*¤ A•4ϱ¡áS£Â†‚x˜6©{ÙØbE1ESç“ÄC!‘¬z¬d3Í·µ ì°ó¶Ÿ8yÒc^UÂ0ÔÒh‚h‚ŠÅ+&ñÆç­ mÄJ.cñ^U½¢¨>k6ß|ã[ÚÛ‹³6™vW[{aðÅö-þ·àë\{nÀ^-ÒW8 ×e‡ØûݪÚz™ÿ›$N³w?<ºÿp•i[Ínó5'ŠACCbmªÉ“Ô[Ô«â½Ç^1F¨*8+©–¥£.F{Û`¸ŠZƒ:¨ˆT‰¢ô®NÅQMœÊà G½ ,º³Ú?Ta¨T×Ðf´§ÓVû+¡7Viˆ:y|Ö–œä"Ô©h&T,B­ž¸žŽL+hô+UìÊÆKV7vÙlfžrèZ¼*„Þ¼|*¾áÔã%µopÍk BT­BhÑb¤”¢Eé5çÀÔy$ŠP^ ´\òZ®ªÔñqÜ`\W K—R&£F½d³ê+u#a`¼ˆ§³-Юμ–ÊuÉfŸ8/…¬ñªõ˜î¶ÌMxx[<DdƒÈ eÞ?µÆùï†ò«”d˜’¬:ÿqÄo‹œ³äÙki±6crÃSâ ¾dÖ‰L9mC÷ã™è#º. , ýd¯¨ðÉ ÿn]17e†Ù÷Õÿ±ÎµxZ+µ-fÿÚžcéÒÇci«ˆ*µ€àED1&5º7BâSí ^ ¼GC MM!"Š'Ý–T“HØÔË«G¼"I"Z­*¥RBµ’Ä1Î)I¢„UAÕ‘‰ŒA½s‚‚ HcĉàT‘ÀˆX+$NŸ6^h‹W"¸I=ÑÝ¡øe·/(™Bˆà1"¤€ÓbF "‚ƒQEE0*„b0bÀ{ðŠX qLÓF!5‡@Á»¦&Ð¥¦ 4/‚âr9Cg‡addDâÄᜆ©çUº§œËgQ’TåmÀ9!² ƪ%Õ ¦¶εÛZ<;#¾e•³¯SŽW4:ÿ(çƒÏzVœóçÝ6t_ɼ"·‰•8IqC÷ã™q㔸Ûa«o„ì>òïÖÔàÒž˜¾ <%]N‹ÿk?Wæc“˜ðñ~z>7ÂÁóÆ®±ËCì¸Ï3ßÖO÷—†ÙýIÒý0{îÒOÏúé8gÙÇ>qGeßÜO÷—‡Øyϱ«%Þ;m€ KËorB•¯õŒÝdÓãG8h›&~d€qŸåMk²ˆ(Ub‡ýÒ¾¿ê AfXæýSŸxvîýt}}MßÔàŠüØõ—˜rZ?ß`ÜgJ¼÷)q =˶t, ÓãvMNHëÚâ°±”5¾×9À”Ó†ÙgÇ~º¿<È&'Ô¹°˜ŽùOß ®g€qŸ`Ò‡žÇÇÕâ0u\ö¡Õ«FX56¿)&5¦¼1`,"1é;NÔ+FšÚBÀ{Œ¦öX¢Ö®‘Q¿Fó‚ `ü„¬‰ãÛè×µ&˜kSH÷üÔH¤ê=hÏY*7¨7P¥ÞHLSOCœ¨†¡T_Êqkñâ3±'³`Z¯¹û%5ò!„1`ƒ`ך›ˆ¤"ž˜¦Í«¦óÐ+&I<Þyl€ Íù¨OÌѱ é.þAò9“ËŠP(äÅ«à}ªŠ´’ªªŒŒÔƒ1p1±¼W@õ¨*ÞyÍD¦% ¶xF”A£ÔçA°¸ƒ¿_µîý"ß]Tä'¬{½Á¥…Aæ9À¸O0îÓƒÌ=bLfyr™MNáàyu.hKßõ½g ²ÙÑC¼zßAf§TŸbת šA6}Óº²NÂ-Ñ [2À„ÿkÖsLÌ_rk—“†Ù÷Õ1×e™÷†ôý>óíÿþ(½0ž·0Xâ„ó•ÊF–¹)»±Ó—÷ó,9ÝñÐAó.vÜwü>På[ÝU¾rdûæ^sõGÙâpÏ¢mný2øÀ2ë/1ÿøÊ('n0ÄöûÇÜôuCçý!{ýÂúX?<G(qÁ²éŸnù܇n•^¤×0ùŽ=¨ÔÛ*œñã'žYñÚWAè~X软Îo~£ €Af~Ü±àØ€­/r,Þ˱ð£ ÷M`âG<‹Ž°l~)$™û=¤“a”£«”glw¾a“k•m뎙gõ1ŽÅ´9_õ¬Ú5`«‹”¡éÃìùÓtü=+NM¸íM[\æYµs™Sß›~HÿL)`ûË^ý§çû™µø÷èéŒo³yÇõ<2DµæµÑXD 2Lh‘À ÆŽ…þMÿÏÛ2³Q#H=F­1G!}Ñúæ™™(%•6Ë•úšh°NSë慠‹©6b1ÆPˆêÕšØ0Câhî] Q&ï¡Tµ³µò¶þ²ñÔÂÍå‘ruኺƒT hÒ~V@¬Á™T0c4Jt:‡Ç+ª""‚ºt±bš«Ž¦\÷¤ÅÊ„ ˆ'´ÑÕÓAÚ$>5žUÒÆÓ_AºXñž¶H©8*Õt±'N‚f¬&¤Þpÿ±üª-þ;º3~¬\Ìߺ|>á¦#K¼í7ŽŸWFvõ¬zµgÅfއ¾4Â;=µþƒwq<üEÏÊMÆ®òæM†Øõrǽçx÷S†÷v<ø•a^wE‰wÎ+çYfÓ6o=n„ƒ~ê¸çžá=•¾]^àPýÛÛÆÏÎèàºùYÞ}†gàõU¾zŒP¸9ϧá-wìpŽgÑ!cõ ¹»ºYü½Nnþ«¡óʘë÷pÜ÷NÔóºxäçí\zw÷^üÄ3™ûºYòNþy¡ç²„[÷€4àu¿ÿ 8c÷ˆ’LXÛ^Ï0þ².‹û'„‹G9~€gàuYÞùÉ®ýGW¦}x ð¬zkÄÁŸÉòŽÛs|òBÁòÆ9#²³OëâþtpÍ?;™]Þ÷tãWá3ã•‘²œú™ 'ß笟(ñÄ*_îMKhTà¬Oupïù¶2´@ÈÔÛ¹ò¶±ôx-^Æuf¶åí@¥ê4gŸôBÕP”dL@Q/ÒLY—þNµ„¤ïW˜ðgÖJàÓôvÚôÚlÔ•R9±jÁ»Ô˜Ë4·Øá$Ç)Cªªó«oƒëŽ8øu½4öîad·€WŸn\ó¿¸nÊðáYÞÉ¿šmÞóòÑ ö“»¸p~áü±-Ì1<Ë& Ñ‚€í¾¾ÌhÌåMa+\qH9½÷¥åàÛ«|¹W)OWªs˼çÜ2ï97áæSÁ¬Ñò ŵ¨Üj¨ŽPâ©sÖ›¹cíg„üj¨Nf]Ùìʘ¼Ñ³zS@c®Y³l˜ºV[ÁjÏŠ 5~Ø®«ÀW—AšÂGj|w"6¸ìcýi8›ây|ª»Ã0é9…툹qFZçÙ_«K—Ç\;½ÙŸYÞ3`yÕjÅýÛN'-þ3„T'tg®!>õþ5‚ZÒ‘ÁYÁ·&Ü ©fʼnG]º%<¦8\³g AsX ®{V÷•¨5b@°Öé{Œ QPc„@¼fC/•†ÅêœÇ{ň’ͤ’¥÷ÞˆðoÛª¶xù3¾+óhW[°bÙªX³©0g°ÍÅŠÓœsbD½¤¡0×,Vñ ®éÄ4¶lh.Vd,Φ5¨Oç«V+Ž‘R§FcIœ#´²f±’¸D‚ÀbEÉD‘&>$qc#¨5"ÙŒEU¥\u¦=õoÁkñŠ¢È>+tŸ®Ç³ú1½x˜Ýîé§íÇÃì¿ÃÚeK,$S¶ÿÄXú×±,bBáZeäµMÈRÂG»xàscïsËÌ$Ï™ ù”áƒÖÞê­saQ9P(\—ãc}Ãìu4¶°Ìþü˜ÒFÈi'ÿ¼FèüƒRÝu”c7{r›¶¿ß|L¦KG»!xŠ0ØCõð^â{‰wëà…§/W›%Ü”8u:øbÄ¡+ÓñŒ1ÚÔvÎäøpŸPX,DõP>þ‰Ÿ‘wò«ïóã?a™ûWe¤]šÔÅ£?}¦ö,[/áæ¯ 0Ë&·{Ïîâá§Í/ äq<|ð;7÷½¤þLåŸhkê/ë\|nÌ´‹”þ}À®D-›%†‰ßipé×™óä%އvÈpÄ%í\þ¯ºb«ï[¶<_)·Y¦/nçw®¯^åÛVøìwêüú|¡sÀñà®ÎyÆ(ú9N(ó¡Ê3ßnè^¼®'U‹—(’Š5Ò@ɺ±`ÑòÄ»´)VÕ¤>#hÄ$h{­'Í+kló½wihUtM`_@%PæPZ£„™P÷ëiÄU‰«™À(ªÔcð¯‘(EÔVÐ4¦œTkÉ褞|߆¹/Åp•o”œS‚1Ý^s®Ñ´sM3Ñ4G7í }¥¹X MºX3S0ÍÝ\cÒÅ˘P(6 ;S‹gBDPÛ4F ™ÀhÕy¬ ù\¨Þ{i4bM¦ãT62"@âœ$Λ|6\¾áF®Å+‘,§ e9åBà„[>9‘'z}Êqÿg”ê¥BN¡>ÀñÀg×_‹U†ºÖ¾"dW­¯d‘oÿy˜}G=\àY|˜Á"?ÿËX9¥:-msáGž¾ÍJ瓯…ëmsCð¼]±Û¹âÄQN:ɱp_Ãä?tpÃ/Çî ᣖ-/p<øš€íÏîàú¿4·>_[á‹Ç'Üy”Y°ý•–Ùÿx" X6»ªY€Næ_7ÂoO¸åõ wi˜4?-³ù-PÎ=ñÌœÛ=ý  |ëì gæxpË¿V†®¶l½À0ãâ€y Çž3lt©eÞ#]<òó2₩Áeû…ôÉ:—üÂ0³ ›å_b‡»íáYµ¡ûžˆCû„œ¶så±£¼ùÇ‚7™Õ–×Ü–Ö=ù;–Íêéñ”ó¶IëZö‘!v8ıtXª† ·…ìZUFaêyO|0[U SÖä…Íóáãêün/OßFÏ÷3kñQÈD&‰– Qnÿ6_¸®)ŠiÚVyE 0 ¬®¤× bð~LÓüzÄ)Z®‚‘ä-*ª¸¤!Šj½îñ>Ñb†D Î'ê€À¥û×Q êD¬ljt·gÞpƒÖâ¥"›1%±ÁƵqMe_˜têU4u&QkÐz ènGo ‚@3ç±oiÆTŸÚ"–êåQ§jpDÙœZï©Å êqƒ(0ˆ¨º$»DŒµ*ªX! ˆ¨z/Õj<0©·ÐZ¬´ø· ؾÑÅý?ê§ýĮ́ðéI©‰Z´ ª®ƒ¶ Ùå9)„xÛê½jBÇ”Ác*|r‚g0Rª;z~0oM^l!³J<Û'ÏY+Ÿ[“ëßÝuDJ祤V'èÐh‚ØPòQj7ÇuQT‹Y«êrQ–l¦@=Qêõ$µŒu/"EãX%°J½á¤»#»hÃŽ\‹ÿ<‹-:¦tÚïW†+ó];ùç5/´€í.Œùëq5~z$9@vûÝÚe„žûa5u.Ü#ÏY¿}¡m¾ÔüÇ2íUÈ>úŸªï¥Æ³ºXç·gÔ8û»Jej–wžø\CZüwÓ?ܘÚQ ÌHŒ·mÞ ±§ù¢”t‡×‚:ðµ:ä³øöÑ Ýº ¤/Ù0ÀY›FãˆcÄ;$ñHA! żh'ª ‰¾úå ïIDATêœs–BÖh[.b¸æµ\IÔƒQ¯Šˆ¤ i$‰Ä±3I⥷3sÿ†·/ •šë*‚À¥Z<µàÅ iÔ{Ÿ™ > µ{m8´3•Ä IÅ$ jêÕ”,µC¡io‡h&¯ªÆZë5r9+½]‘f¬—j#a´\Ç©¤žS‚D’8@÷¦˜ ·+-žý:Ì®»¯}­Áùaö;’ÉBæž Ç” |þ°«n;k”7o²ö3 ·DClsàói;UR… =åY}$D Ú¹äI‘=ÚøÍ¥>ìxèã#²ÕÚ÷ ƒ!¶=à¹úlþckãW/ëqÏDÓÎï-º-^^¨bF+n£Éy_®¨ Û$óò„3‰Ž%mÐD¡£ã‹0\o¾h‹€‘5yŒE=jS'ŒmnÑz‹ŒŒªz…0’ZCÛòµFBM#ª•8UCzƒAɆ¡#¸ÄI˜±$‰¾lìPZ¼øŒV’žžŽ€J‚¨)‚ £Í½(ðµd,D­$©P•PÒ]eµ5¶™¡.,ˆ—T“(NE+åç!¡-jÒhàO]C­V$°õê1Íe#¢P4q΀ùê"Zü Tv‹¹iß>ì¨> ’(õ­A0ýǼo¬l†ãGküèÔ˜Ωóó«üæˆVB<^©oN:ù®|>íÆÿγìCéñô3×½0/Žxý{üñ» .ûc?¹; ZqRß |Ò7 f¾À‘xqxÙJ©-Z¼(W“î(—)ÖcÈDââ"“îþÒô"–ÔiDë)¡Ýt¨Ž&ІXK,’†csÍôu¦ãCSïÏÔYÒûżЧ¤YÕ(dh`˜ÑŠŠ±hà NTŒSrù@ÃÒ+"qì—NèÎ>%‹ÿN¼'­ùYÓ¦ä}¹‚Ø"Z0–nاë¼.N’mˠõԡ$Hm½1¸±X„êR/b1M§ÀŠE†U5D¨Zïh+„xQ-ÇASЈïq ¡µF+ı3ÙP+ä‚Á 8l-^ùѶ5¾±§gÅvJ}2øŒÐõkC÷½Eν(dÿ'eZêàÚÔùõÞe>zŒ2¼9Ä ZbwUÄAkœ0¶6Lú†eöügj?Ë[~Sã¼ Çû.^_™v.¾'æ¦ýJœp´gp.4¦@´ÒÐ}cÈ^‹Ðb˜â “¾a˜r× ™ÿ -a°E‹g ‘PÌf­)×¼/äÄ bšöXžf° £ª Ä–bâÞ"ªé6Ø`MîbL3°´j· À{4HsÀJÃ+õX40ÐpVFÄX¢@ÕyQkUSC‹h&c±Æ"•Z]2Q82y|¾%þQ©%Q&Ê' d"tÌ¡)õÿX£¹ö4ö0ZN+±G]ªR L𦮡ŠxŸn57M7Ù¡&]°ˆ—T@ÌFJÆzFÊ¡jÒÿø•ªcQ«‚1ˆ†d2ÔIœ¨„Ö,í(f–<Ûßբź4íêÿüáY 7iúœ÷ÌeŽÍpüן­®žçÌg-²K½‹G~þLe “\7ËŸµ®—’–0Ø¢Å3  ŒøJ"ˆ£é ÖÓ ÅfAk^\¹†täð±B%FÖâ $~Ìò´©Y;X¡µ¨÷P©z­Ô=µzB­î4 F†KtwD8ç´ÚHPDŒ(A›F¿•‘RMòÙ :¹7÷²Ye¶xiˆÅ\ÖJ߈êäqâPŒOB´9?´ì°ÎkKíëD mHb QRç#iªRÍ7h­áÅ‹Ñ8Aã8¬Þ7㜓\ÆøZì0VTðV+Ú "^ÊÕ„b>ni­[´xyÒ[´x¢@Fë>CÓÒôÔÔr‚¯ÔÑÎ\êa\©cŒ–JÓPKS/TÕTm£¥ªR*ÕI’D¼­7<Î9UM(òŒŒT@¼ò‘öŒ'ÎDÖj„jˆ±¢mÅŒ(iG{T›Ü›¿Ãi9<ýï!F ÑH3³Æ@Piš1ŒÆ¸JÛÛ†/'P‹‘Ðb£º6…?h¦Nl&LôªV°¤žñ±­ÔÒüÂÕj]c­ÐÛÑh4h4Þ Ôˆªj` ÆB”J5Ú‹Qm\Wöž 7L-Z´x&ZÂ`‹Ï@62C£U×74R뉢¬Žë¶‚¢¡¨U¨ÅЙ#øjÐ$Í`ÚüWM3èîð¨§ZS©Õm4¼S¼w$Þ©óŽb>¢\«K=nhG!0IÜð£Õ†ä2YÅ{+„‘•|Ö˜J¹¢“Æå–u·g‡y®±´Zü…2Z×4¶ ªª¦1¢!h¬h­ÝE|¢ØZŒ!°BÕ»f\AšêCß\¬x´^JåzCÔA­¡êœSïÚÚò”+uœÆ m¾`”†Çd B«Qh¶bÆTÊ5ÍçÃÚÄžÜÖÈKµÕ¢E‹g¦% ¶hñ X#I[Vîʆºçò•Ué(潆FJ±hµŽt¶Sm@¤¡gœÃ¢$N±‰C¬Ái _)yê §‰sÚh¨xŸà],ù¬Á%^jõªõ¡–« ÉFU1íÅU«G˜Ð[X=¡;÷І¡’BÖöUênùh©2q™†L›á<¦`©WSªÁ¸|êE\©c¬ ¥Ajeà!Oilú3ZV††©7MœÇ;Ñ$ŽÅùD=J[[¤#åšÄqC#«’Ä Sª6M¨¹Œ%vŠ÷*½=³jõ°Nì-.›ÔÛš£-Z¼Ü †yÝa8šh¹Øár­˜Àd2APÈ‹ŒQc TQ††cÊÕX“FStAU Åœ4ÎÔFF’lƨ±Vp ^­8«ÅHÅkįœ·ioËQ¤Å 9»ló…ënY0¼çý—d¸¢‚ØjU™5Uâþa•á’`Œ#ĉ5FÅ£XÍDÆg3ÈpI®Ûr%Q—xœwš$±ª* ÚÙž—Z#6•R)1¢dBÑ®¶Œ Õµ–±ªÒÛ•Ô1:Z·Ù|Ü c[Ð-Z´xù¨ê‚ ݉-^îX#µYSò×X[Ûe¤Ïç3Çu7RΊ$ ©–+L” °Jï%[P‰2¢ÃCžF#Á%¯爈FÆPÈEÖëë.1Fjç‘(@Ämíy$Ÿ Ê]máýùl0´¡Ç¢ÅËl(ËÇu„Ãýî½TŽÉd-Õi¸¬)Uâ¤Ö¬ú¸Q7Æd2ä²ø(0 H#V‰©ÖœºØã5µ ”¦ã|>—¡RmØ$®'¹ŒcMêåUlh¶C¼÷¦µ+gN*Üßÿû©ñûNáï Ý/ eU éÊïÿ·wo»mA€ÿ™].IQÛr›¦Ò6-r‘GÈô­ú¦Ú´IÜ ’B‘²xÚéEìÛ¢‡B¬ùž`÷f÷ÿAbÇóOµÇøÅÛíøª9Lù¡9¤ïŸ]!)éþxÿÕWU–U‹¥× ›í„»ã€˜’¦˜$¥çYE‰ýh‚‚™4ÏD„ÀjUÊõ*ÿíj~É<Û¡kþVLZl›øâíŸý!/òº¾KÕ r9øc;FŸåðÞ¡Èä¨*Ö<-¤®{íLj'¤•êÊα*hJqòÌèûŽr\_”{ĤX/Ûù,»µ²rˆøçûGÌ£ jaИÿ@îýnxqó{ó’ôÉõ‚ƒJß |´ÀjÄ;ÒF“vCï½ú¡CŠ ìX©Ï%jÒ—ëâÝÕ"¼.‚Ío5ÿNLRÞ¼ëjSÞ6<¶Ò¤¤»6Á«¨JUzY_ Zï#öMÿPV4¥¤Ä"Æ]?„ô¾¬„@’`>/ðäªøÕÊŠ1Ÿ? ƒÆüý˜»fú:&a"÷Õf?®D@eîÅ9@‰ÐQûnÔ8M v48GÊdY︽Xf·žV³Ð¯Wù›SïË|ÞDá6õø¼ëc~»9ü¸˜Ï\Ñ$N‰œ†Œ±\x%†Q›¶×iÁL‚CG UG Á{rY®O×åMQxÌKÿ¾Ì]{Òc> ƒÆ|Bªpc”ån?¬cÂ,‰¸iÒ€@¤žå˜y¼ç±*\S•YÍLrêu›ÇKD³ºžnêþÛ»^¯wúñw…$ÇQÇqÂ0LˆqR8VïœzÇœe®ÿî›Ë×eà]UºÙ¥aÌ#caÐcÎÄCY©Ûñ2&-ðq؈ÞÊ!UQÇ$Ì”ÊܵË*ÛZY1æñ³0hŒ1ÆsÆøÔ 0ÆcŒ1§caÐcŒ1æŒY4ÆcŒ9cUæB¯ÂIEND®B`‚openchange-2.0/mapiproxy/documentation/pictures/mapiproxy_struct.png000066400000000000000000000354121223057412600263720ustar00rootroot00000000000000‰PNG  IHDR=a=B¤sBIT|dˆ pHYs × ×B(›xtEXtSoftwarewww.inkscape.org›î< IDATxœíg˜TUҀߚÈ0 9 *E0 FT &T]sÎw]]×5§5£~ºæ,Ä,( DA¤ Arž\ß:íô4=3Ý·{pÞçé§ûö=¡ºgîí:u*ˆªâñx<žm™ÔPÕÿV££NÀ»ªzUuÉáñ”GZu àñ„‘öØÿäJU]YÝòx<ÛÍ0¥§N5ËÑØÉR¯šåðxÊ$¥ºðxÂü\[Ý‚x<5I‘†"’GûZ´É)ç|š›3£‚qjÇ"“ÇSSðJÇãñÔ@Dd?™«€\ùCD—Ñ%SDžÖ›Dä}É ¯ˆ ‘•Àz`½ˆ¼'"­ÃÚ%" "æ\ "—Fȶ»ˆül‘e"rA?ºÇSiøí­éˆ)¾+°›à¾@0AU7D´MvvV3Uu]Øù`'w83qïü¤ª¸6Ý9À Uý=ë»c¦s–?ªj‘“©½kºDUׇõk¤«UõÏX¿§ÑûŸXì Ü/"KTõµˆö7¸ö퀓€+€‡D$ˆ)E¯=“î"ÒEU7ÍMÀKî¹;v?-" Tõs§H}IÉõ¾x(Jú7àñ$UõôlÄn’Ï?»× ÌZ„µëq^1%é²°6§…»[)*p†;1ÆÛ@ý°1V¸÷ïrÇ)íCÙÀ€³Ü{Ï„Ó(tïŸRÝß³øGéžk»9îÿúͰvë(QvZ©À\÷Þ{®M¿°ë§{¯!çÞ»64—{®-pºË\›'ܹsÂÆäÞ;8ì½Wªû»óÿ(ëá··<ùÀ+îxWà©|ˆÝüV?aÖš!"rd”ñ~>ÆÌìÿ2€‡Ë€…˜¢ôx²}†­VOÂ|}§TU'\»A"’í^Ànü+bù<žH+ùØ ,ÀüÝ:„ÎEiÿ¥ª.UÕ"ìúhàž»…µ{UD–3±ëìúè$"ßaVžùØb§YÄœÜs1ð‰{=³ y<5¯ôxÀ¶ öQÕs€Ý{»¹çã)1cŸ£ª7cæî\÷ÞeQÆ{è ªýUõ£°6ã1«Ò(à ÷ÞYe9Cªj1pœ“)ËÍ’¯»sÄ|[éæ§»sÝókªš_Ág÷xj*ϽåØ"ä$`º;—¥ýü°×…ç Â^‚-d>ts< Ltç^ö½~£d±Ú†ý^†‡œ«S±íd§Fã}z<#Ã^¯qÏ!E¤cع ªš'"“0“vøùo:+LˆÐʰ¶Z G0ÿƒéDžÙ ø†’Õm8µlUÝ("ÿ®.‘Oœ\/Déçñl+„üÕ>SÕÇÝõíz‹…Éa¯§¨êЈôþt~?mÝÛCUuˆˆìì1ÖOa¯/‘€A@6O Ç[z<«Ã^Gœ[öºMØëvQ·øµŒ1¾Έòø£ ¹®Ãž-@Ì™ù(ížtrïÜ…ý_OVÕ­)g"d ý›Ûršƒm;ŪŽÞu‡O‰ÈùFD–_eõ-׿7çÌ/œ)Y¤Üƒ-”ž*›ÇS•xK§"¾ÆÌÙiÀ­"ræÙÒÿ2†1F{c Ö(l»ê@àXU}«Œ~!þfluÙó*…ªÎ‘€1ÿ$€ÿÅ —ÇS“yÛÒ=s¾sà?óµ ñ-–˜0<ò'lë)Ü*sf9=³è´Å¶Ä^ÀYq1ß»•ضVv½ãæý@-ròà1Ìz»¸øæiÍõxj Rz³#!"1“ô­ªz·{op0BUû¸÷nîckËà7ÀѪZ "§aÑX-UuiØ<õ1Gdzd%ûÿ¿©j;×nf͹[Uo‘ΔÜ@‹±­°É@÷^ŽZ˜-"r˜“Ì2ÔBÃBê=Çãñ–ž›{°ˆª1ab)(mQ©êƒ.ŠädJòô|OißXX:@©?ªºVDöά=ͱÄg3°è¬`JØ×o–ó)8‹BùØõëçÚÿ夬ª£Dd&–Óç}¯ðx<'oéñlóˆH +ž^ 衪S«W*ÇãñÔ4¼¥Ç³=0¥ÒÄ+<Ç㉆Wz<ÛC°mº”8dz<ÇS ¿½åñx<g‡Àçéñx<dzCà•Çãñx<;^éñx<dzCà•Çãñx<;^éñx<dzCàCÖ=gGDš±Ìåe=ò±LëáßU5?Ú˜ÏöˆY÷$Éê—ó(~Ãn´¿…jfy<žø‘T 'p¬{ìŠU>_ƒõ ½®´Ú‡=ï,æ#wTõW<ží¯ôx!"iX…åc¾ÀnÀzì»Ö=Â_aU;`7Ü-8È=F«jq•~gADZ`ώĪ›æãUµ(À˜iÀ.ØuÙ«è¾+üŽª.LŠðO Á+=ž˜‘(¹é­C7ÝïãQXD¤)¶Òìà}€¡Ø wœúNÙ¸ 8Ë:þð¹ª.­„¹R€Ã€Ó±Ãs€·0hY²çóxª¯ôxÊEDÒ €Ë0Sø—ØM÷ Uý3Ésµb7ÜFÀ»ÀÛªú}2çñx¶D¤-p¶ ¸¢ªyU8:pv=öžîõ[Óžm¯ôx¢âV|§ÿÁ¶ îÆVÕö“ˆtróÄ¢ oVÕaU1·ÇS¸m¬[ӀDZ"ºÕªhˆHkà>Ì t ðŠ·Äz¶E¼ÒãÙ éÜ lnQÕoªYž#€G€?ëTuzuÊãñTÎ9ùvàràà>U]]½R•FDzb ‘kTõ»jÉ㉠¯ôxþÂÝÐr€[k’eÅý \üø¸MUWT«PO’‘F˜/[.p±ª.©f‘ÊDD8 ¸ ܤª‹«W*'6|rB"r5ð>¶o¿gMRxTµHUŸÁr‘lfŠÈ.TÞãÙf‘®ÀDà{àøš¬ð¨ñ*v-Î&º“ÇSãñ–žÉžöNRÕÕ+QlˆHGà¿@ ì‡âjÉ㉠®RÕwª[ž ˆÈ1ÀËÀµªúfuËãñ”‡·ôìÀ¸ô1XÒ²·…@Uç¨êqÀkÀxÙ»ºeòxbEŒÿGm« €ª~Ü-"·W·<Oyx¥gEDzaæô¡ªz†ªn®n™‚ ªWŸ‰ÈñÕ-Ç#/bywöSÕŸª[˜DQÕÀÀÑ"òš³ {<5¯ôì€8“úûÀùªú`uË“(ª:Kšø„ˆÜPÝòx<å!"·{}UueuË“,\ޮñߕ‘"Ò¸šEòx¶Âûôì`ˆH`8p¤ªþ\Ýò$i‰}¶ÉÀªZXÍ"y<¥p ŽG€jºÃr"ˆÈÀqضù6iEölŸx¥gBDZã±ØÏª[žÊ@D²×Ýáɾ–—§¦ "ûŸG«êÕ-Oe#"/µTuPuËâñ„ðJÏ‚SÆ/ªêãÕ-OeâŠ(ŽÀ2HßZÝòx<.h`°TU/«ä¹êb7Úð›nðV½y1°DU *YŽ&Ø6×õªú^eÎåñ”‡ˆda Ž×Uõ¿•0~7à÷Ȧb×Û’°G&Ðhåžwº£€€*ÿÈY—¿ÎVÕ‘Éß㉯ôìˆÈýÀ>À±Éösq ÕÁÀ¬*s6v“]öHÅn´¡›n3ìÆüðªÎN¦La²í |ôÞÞü—<Û"r+°ªžœÄ13« 4à=÷˜kM,iôNŽÀ$Þ©ª£“%§›ç`à ç¶”ó}╞í9 x ØKU×&qÜ®À•À‰Àrì†;Ô…®VÔ7 ×=8Ø€Y¢žRÕeÉ’ÑÍu6ð/ ‡ª®IæØOEˆHsàg,4ý·$yV.æGànUš„1kc —¿OæBAD®À4ïØì©V¼Ò³ã¬0“ûUõí$Ù¸SVžÞUÕ¹ ޹VQý\¬ ÆCªº!AQÃÇ è„…{ÇfO•!"Ï«UupÆj]M±bŸ£3ÊéÀ¥X%õϰ|I‰2sŽÍ[TõŠdŒçñÁçéÙ¾9»É$¬ðˆHšˆÜÌΝwVÕ{UxTõ÷£°æ4[D®p7àdp–uúßIÏã©çkÓ¸+ c|‹¥dا2U-PÕ'€ŽÀ2`’›;\ ‘¶IÏã‰oéÙNqÑZ³€ª:1Á±r€¡˜’|…ªÎI‚ˆåÍ·;–ž¿ V,áºZ"ÒÛfØÓW„öT"2Ûò}&ÁqNžÎRÕ¯’"\ìs‹mÿSUŸOÂxvSÕsËã ‚·ôl¿ÜŒN‚³¶ÂœSÙ €ªÎTÕ~˜óãÄd¬4Uu)ðp[¢cy<!"ÇaûÏ%8Î¥˜ÿΑU­ð¸|^׋È.D"<ôq¡õO•ã-=Û!NQùØ;«†³¸|<¡ª%K¾8eUp¾MUÿ/Á±³±l¸¿&C>'"2xRU?H`ŒÞX¢ÍTuaÒ„ &K¶Y¤ª'8Ö5˜CóiIÎ㉯ôl‡ˆÈ#˜/Ï- ŒÑs‚¾MU_¯¨}e""€WUõîǺ 訪KŠpO"Ò ó}k¡ªùÇh…ŸUSòÛ¸¯P¾¡ÀÉ]¸ý\àø!3µ§f‘""uE$5ô†ËÝz""õÂŽk¹D[¡ãœrúJDßLwÑ„Žë„›J£ô­vœÑ7[D2¢õ2VºˆÔ ;®Ñ·¾ˆH}Ó¢ôÍ ;®WNßT·: g‰H­°ã2¿÷Dpòœ ¼À©À[À[Õ­ð¸-µÞÀÅ"’èêð̼¾{â’UŒû ÿI{ñ?OÛˆyÂÛ¦VQÛðëH¢´MIRÛ´rÚ¦—Ó6-¼m2ž€Â“‰¥px´¦(<.Ô¼?p­ˆŸÀ8y˜s÷É’Íã‰úÁ‘9ºÏÌÆ¢{ °lå!gûÕXrÝ&îøwlÛºV”¾EÀ| ½;^‹eBo掀ÚQú¿Üñ:` ÐÜ/ÁæDéy¼ XƒåÄ HÈBúØ\ %îMá}7«°œz`éh2>6hƒåÞ‹ì›ëÚïâŽW¸v Ýñ,P)ò{/>^¬:îw –ìQUÝ7H7Æ}X$U ñ‹†ù 蟈¯’ˆ\¤ª’&\™sué'¦B÷=~š }óìõÂTX%°·K9&z@–nÝv^*ä tqmGdÀe´ã~ø;º¶_eÂáùªP$ðEFÙm?Í„£]Û-c3 k;# Ò#Ú†ÆÙ"0.Žt?ôSÓ G¡}ÑÖmפÀô48ĵ’MŠaç$´•=]Û‰ïÎSÕ-eþ* Ü´¾ØöÏ1ªzlr%K"Ò«!ÖGU 8F:–è U”Lù¶žk×Ð2Nt%7~J‡qõáò%­l 7……æ?×öÚ=ÜÿÒçµau: ZgÇ«^i ×./éóh38ûOhè®ÉWëC“|8Æå%ú.fdÃE«Kú<Ôn\Zr<¤ ô^»¹kìÃ:vÍp)<æ§Â' áÊrd¡!´Û ‡æÚñÈ,X’ syÚ¶O7‡ëÃr¢=ÞNY -Ý}êíº]Çm²ãIðC\²ªìyŸm¬‡=]¶ý³aS* \oÇKR`hc¸úÏÒŸÿŠ¥ö› ðRh G¸kvt-øµ6œ_Îwödè·Ú¸{Â{9vÿŠö÷Ö-vmЧ†PŒY úi ˆ%yX¬ª÷ìßxóªqÉüÄ¢Ižzõsp·9À‰ªúC2åÛz®ÛQ¢­{ªÍS<¹*g‘–ÀO@Ë ¥Vœey¦PT˜è³º‘s+°¤‹|$Dä& •ª^“LÙ¶žçÖVPk[°‚Ýc·uÂZ­£d! ¶XÎÄ’]ä»~¡gÅrªÖ ë³[ˆ‡Œµ[°…nha[ˆ-ü³Ë™w£›#´Îss… ÅØb¼<Ù7c‹“´ÀÍ]žìœ\¡Å®{웜œ!Ùó¼á²o¢ÄX£.%ßY4Ù (1ŽD›w£;.»PÆß{‰Þªq¤‡åééLù0‡Ã Üƒ…§Ö8…þŠ&yx%1rÇ€ó“%—Çã8–@m¹k/k²Âãxû5931†aYÙ+™_2J~Áî±u"ÚÔ‹8ΦDáûñÏ ;J+ PúÇ×>#ì8ÒJC´yëP¢4€É]+ì8%ÙkS¢4à^W${¥ƒ¹k=;BöŒ(²çPšz”þ΢É^›ÒDûÎ"e/ëï=¤A |þmx¶mÁ¬<óƒtvûôu€7“*Uòy¨'"‰Ü0?À²JW2#kUÜÆS9ü.á>xUÄi@ d bÁW·'U¢JÀYw®î–0?Ï8ǘl«‘W‰Ìõ× ÇqöºèT©Õ®=ñ’<×(`ç¿á æ\x[Mò㉆“ïFàHÇÛ8Æø X[ù7ÜE•;¾§lê‚Y#ªgiíŽE8áTàU äÏ!Ëá"r·ˆŒ‘Eä¹MDΑ¤¸3¨êwÀ,ÓrP†aO+‘³“Vsг­S§8Ú$µê¶'QÒ«+l#±¼:A褨ê‡ûÿ…‹rë-"ÿt7ÚsÝM¸}²¢i\TË\ಆ©óúî~QQm4PU­ÊûÛNÀª§ÃR3FD‘ñXÀ\à^Ì2:³ùüâ®ÍdXùoÆFî}ÄJ(=O ‰f×ô$¡Äû?Ž^JÜ { B,L60"R¸¸‹Ì‡yÀŽ…±µV‰È`Uý2‘¹7ßˆÈ ªº1@ÿaXh¿ÏÒìIm@•ÔÅRrŠÕË „Ûž~»þ†–å`,V¸ô¬ÆÝ?IK¡ª Dd"p¶e/€F"Ò^Uç•Ã㉲Sà•HÏ"϶I+`…Ë„þ˜µ2‹ÿ頻‡¨ê?Tõ6U=[UUÕÖÀÀ"ò… AŒªÎÄ"e‚†öNH¥@|Ã__ÕÆä”,A¬ôG? +{ñ4êþnyUª:ÏeC> ¸UDÎ $q Ð?ÎÉ9K‘QIÜï£'=ŽÆE)pö†êÃN>–«!nYe¶ê©ê”€ý›_¨ê¹å­Ø\Zþ.˜‚õ•ˆô 2g·¨Ü ÷à°e(‡Aþúª6º«ê¦*œ°-Á-­{ßé蜵ÿ+ÎsÞUôîr©*‚2螸2Nf•X‹ëæe·ñìôÊõ!ë5Ž J'ÍŠ™Dn¸£öxxNUŸŽ¥±ªªêì†û‚ˆtM`î€c%x!Ä_(ÙräåÞpËP¸÷ŸÕ-É6N"–žXÖÕ œ L ’°ÓEzÞ‘@×+æûv B%+=O i–ø§¼ß‹ éð?W§(5® Ûÿ°L8Ú^×_çŽ(9WCþš é›àŠˆ¨¢gN‚Ü°Ò ™ë¡Õlè?ÝŽóRàésíõŸA¥ÄŎÃìË!g üã^ÞÆß™‹àöD¢ ÂX^ ¦µ†Œ8tArÆ L"7Ü–@Ðdˆûb[ZÅÛWU§ˆÈÀG"r€ª.¯°ÓÖc,‘ù˜?D”ý¿çè#ËRk~nÂÔ"Hɇ”íÌéz "’R…ш‰*=#*l˱ðñ@¨êX¹KJÚ+à0¡-®ÑúÎÂòy<•Ìœô4x§ *§Ñ¦4X–Äíý™pòT{=êLXíj°¬ÿŽRí°½á‹JŽG_Z1øãDÈkWz®ùÀ´¯àŸw@njɼ‹¦Æ¯ôä×†ÂæPà+)¶»$ñÆþ]gÿ$¤-ƒCOIΘÅÀÏA°Û<ò£ÁoÖ×ce/Eɨê{"Ò³P†aØ 7ˆÒ3‹JµôLδ œXÑ–·€‡üt˜·´ }æÂ¸VðË^ÐíØ/Ì*0¼+,o yumÑn&fõ{ý @àèI0rOXÛºLƒÙùÝfƒ< õœ?ɯõ`B7ÈÚ ÝgÃ×@a1Ú¸”ò_v‚Ma×ù›³÷†CFÃ+a~]³/lj õ–Á±¡a¦ÀÛ½L–C~€Ö›`Z˜ÞÒs¡ÅrX¸ 4[ Gº-ÒÙõarW“åä8·_ ¥” ”ì3YXÊÙ $béiŽ)ï‰ð?`°ˆôXâk`HÀ¹gED‚fw.Ÿ'[òèêbMÌkµ  ëÊjÄÃĬ48s#hdÊòP˜qª)=ós`ÍQö^©”ŠŽ9ÎW#e#×)ÇÀ¡ÏlÝ®ù«Ðó˜|(,º Öõ?„Þ3c)/†u‡U­ ¥ÚÍ(¹a†Ói1¬}Únžá|Ñ~ïdŸ¡ãt8,,±ßëÛÇë÷=ŒØ66€¾c Y.Ìj ÷t_K-xí`{=pœÕýøv˜Ó 3¡þ2Øÿgh»¾âÏSüÄù²1Và+-0g tî Ø7ÄÀe"²WÀªËñ©A˜ì,"i•Þ|Üf¶NZSN‚U'Àì™×É,¥¿ÃŒaéY ™0GaêÃp‰K/0ö ÐHɃâ,˜§0ë)¸Â}'Óî¶qæþ›Ãèoy°âF8i*LÝæÜÙßÃq7À´6ðÓ½º~Øù;»>Kàœ‹¡ÓZ˜4Ös§À–=AÓ õ˜³3L¼ ŠÃ>óŒ¥Ðï:8p1,Û–Ÿ ¾„›ï‚¡wCîîÐñÈÞdóf,†#O·¾ŸK.„Fð°ë8èRì²oW«°‚‚AÈ$¸r–…åÙŒªªˆ<%G A¶”’ŠñνADÖcÁ‹‚ŒQ>'¬aëTÀŒj£nØúýô•ðÏ'6ÿÈn0ñQÈø ºŽÎ«Æî £/„ÍìO[ Ù³áòÇ g´ Ÿµ>NŸžì‰°á ø¡|ÒÏ~ìëDÙG^–ë:=lï­<ʶ¼"ÉØ=Éì=ÀÚyg5€»^„Éÿ…ù×ï7Áè2§µ‡i÷ÂÔ°­­ûn†‘/À¼›`ÞðéËðTXïŸî±>?“_þ|dŸZÇKVQ}k7í^ؘ_ Ÿ¼fc.¸ ¦>ŸÛgJÎ ’Lk-%•Pã¥>V•5XQ–À¸”ýOafú Ì£¤*l¹b•ckÍ¡û ó-K.€Ž@Ë祇—´Ýw0Üv8Ü×ö½ÉÎ/:wë1Ó×ÀÑç@½¦<ýpUù25„fŸÀaBæ¯PØ>Ž0 oé-^‚î×CÛ%0ùŸ¦ð4yŽ?rÆAa á®»‹Ÿ…Z3MaºûaSx|~ ýfÚ¹üVðÁÞÖ~•ûœ]?Ž÷¬Qzð+X´sÀ¾á¼‰ùÙáO ‘¤‡b ·J u *7dÛ‚`ó^Û>ì±kåÈ´-°*>}֚ˡ°>¬:ÑÜ^¶MÒ`nZI%ôŠèøLݾ>Öé‹¡ñظév÷6…(k:œ3n½ ›Á°}à”ˆ€kºÁ“ «¤:ΊMž÷¯´-²Ì9ÐýQh¿¦î[ß7‚Õý!íO8óBØ’C_……WÀ¸ñp`ØŠC  Ïy0î»(&ö‚ã¿€u÷ÁÜ¿Cê*8üFk[»Võ…Ôu0ø$¨W£ãüAÝ‘>_#ž£½^4ŽHþ÷W› ÌÆË îx"l]%ÿ‡)/ÇÛÑ­UDêÌ×Rzæè[#²,gd¼Ô§N†!»À†ƒ!í¸à ³ .¹¶ì^ÒvÍNðèI°¹ »mqXXvû>º½cÛ^¹ïÂè#!¯=¬/çæ•².x jÁœ¯aI;ذ[„œãáÚ—ìõ´&vûºmuýñ!L9Д#€œBè;¼÷ lêaV‹,¯íP˜ù/˜Ù­¼¶¦põ °}3'ED2Hã/‰(= ®ôÜYKªÊ®ªËDi¬ªqmèjžˆl‘úªdÑVDéJÕÈ• UÄ6å+½ay7h2Ã|WgÃ[ç xÙ¬øóêÁÇ'æ]ÍòZoViX€‘í`òI¾z ‡œ/å;ûƒ ¿¡×Z ¿û»-Ï—Ž„] Í8Xß–í§Âñ# ¹³òÍ­ ‚ܦÐj¬¹t,ï;M†AÎ’?±|{lÙ Ò×B§¯àÄ2¬ë“v…¦¶î8ÒoÜ×í AØ5õ}K{bɘ¿€¦•|ÞŽƒì%ÐjÌ8êÏ;ÙoýUOCf1 ÐCDòÊiÏxa¯O;ž@d¹0Û wCËø3¢ûÑ~½RW@»g ­fºÚM["" ]HqAXh±”£ kŠùáPDI%Áˆë½n˜2’¶¢Îsí‹B?daýµ„b§ÔÖ‡ù  ±óÙ;ù˜}%¬? ¾wÛÁ-Zyš(p¿ˆìú@<'z®Ð[Dúèßè#"‡G9W‘ÜôrIÃ÷Cñ”l›Å"S!ð²ˆ,+§MyýŸ‘µeœ+¯_+à¦æ-ç\Ç÷àBbgX?HË·×Á)S`Ÿiðú °òD9¾?ÖÍ^7…gjSxçE(ªg¿éÀ¦}€0¥§°|ù¬/αyö;Þ~#ë ÷€Ì? ¿¬?><‚ë`iXÓVÅ®²çÚ£à•v0øQó½}é(h ’3¶EKQCóee|Þ ¾yÚ~ó²¦ÃÆ}á»ãaÍ༯¶þº-‚oò °L?Ãõ™e–—²ÐZð¹°Ë$XéÌUu#ª§„)3»¯6ËM~+øò|X6 æžjç²]þ˜ÙõaÒ¿LÙjü¬8†ÿ:_f²Ô-€fÃ`Éy°b€ý@0{w^¢dÛW*xNô܉Ø5ø|€þ½°ÌåoF9‹ÜS1+i((a'`UÏgêŽ9Ï(§MYýÀ¢@çÅÙÌ'i ð{9mþ2 )]2¼~»®L=VÁžwÁˆGL™Èš—»Åéç™Â“5ο vÙhnágÃ>7B¿)pï[¦}¾ô gèeíS6¹gØg~îåÒóO¼È”ŽVÏÂÕ¯ÂÇ]`̳0ç* ŠÒÓr3´~Ÿk ÖÚ£`v>Ô? òJÆlý´Yµ>ê cŸ†9WRê~ZÔÀŒ$?‚õðUo˜·;Ì; ˜³œûGsŒ3ãR :Ý ç¯Ó®€S« ›ÂnwÀ)£`u Å…oX ·É)£aÅ[Pÿ·­M€ãŽÒ—@í°UàÆ½íå“Cá‚ÏKÞ¯½Üöòƒ3ɢǜo®Ö‹ang8/†›dËi° Ó;†ÃæÀOÍáûc¡ÃâØæï¼Æ+52G憫ìø“#a¿ñpÆ×0ô@sÎÜÜ®âñÀÔG”rJŒ²5µÕê\DVƒ8ãŠÈoÀ±>7‰ÈØË'˜Cô.ØÒê©xê¹U^F¬´"²Øõ´ˆÄÒw°^UƒFÏ”3öƒ1þ݃Òg$~ ëÜà¨{ ËY7C÷÷æ_™ò°OD ŽÔÕ6Ø–Qa3XÞ ˜ _óφ‚V¥ûlŠðsª?Þ¶~6Ô² ;™¯ìê]í|Ö,;=­DV€Ü]ìyñ%0ø’’÷‹ÚÖ\û(×Ù•o¢áðé°ü@Ø´?¬é Ã'š%'ÏÍ»è2V±°1ü^§ôg¿t¨ÛùɃãFÀcW›Eë÷GaÍánÇÄé¡à‰Y·Áà0?Ýü]KË—9¯ÄJ›cu|U+>ŸƒìB¸ñɲϯp–Ÿ¶/ÂaÅ/=ßBÐ |µkÜ |^Ú¶t3gá©Øþ?1(=§O€ÅoÚVÝèÿƒÑ. M  0ÆT»­†º£Ì?í^3Íõ¿]kNÕE¶C‡7}ÄØYMp‚ÑÀ+"’£ªqgVÕ/\‚ÁAØju)pr€Â‹ÙùÝBÉL¼Siþo䔟"’ß‚# µÛîé5]9îï²ÛrXyU‰•³Ý:¸åøx?¨µŽœ#ÝÖmËÿ¦þ÷ÂÂ(Ðmìógé9êFD¦n„k.†/÷±mßÃ'C ÷7=øX5v‰ÈïÔoì|Ý64‚†ËM¦œBXY º¾¼ýÝvôù„á€ÚVZZ1tYe&íÍ{B‡áq|yXŠ*Ìʼ˜Ø}J¡ªëœâsV.ÈŘ¥3PfuGCJ[gãaWJ[jâ!| µšé=9ú‚þ»V°áÀ’ãoÏ€°×inKo}9ÊUj˜¯S¸[Ⱥtøõ³†t¿Žø {¶"×·™nŒð­d€Ú«ì9/Ì/,7¹=uƒ4} ZG¤%hå^ý{ØiV®K†Ãà®;a}oøsO`„í”6…¦oBëוúa~?˜Â¢åf¨?ÒG¯ ¶í¾z_[d(@ÊSÆZ= Íæl-Û_ßGÜùåÒ`× , òàåÑ6ŠƒZ¯1Ðì7h°Î<º÷uáˇFXoNx¦N-1‡÷º¶dA›2„Î),™wß2LÛl€;.‡Ow79¥:;ëR¯ïìF^ßÝȻϹ ²Â¬7>“Þ‡Ù /rVÁ!ÓK¶ßz^eŽj»¸1ú þÃn ·Þ3Z¨n¦Û>ëTø¹#lj —³ì ÀË aðªØÚÿÅr‚G0­‘o0óü«ÇX‰UsN„º@Gd°è•…ûVâ wÐL™‹‘ƒQ*lw÷ÕöÑ8×ÂÌé[Pâ¨[ŸçÄ(e "ç§q. вr?d° ì>§EÉõMö[J¿÷öþðÛ‘°¹dOŽ>N¬t/V}§*ËPŒö‘Fªïõ –vá|*=‰â,UàÐï/a ž Ô"Á(в™™»UÜì/þwæÛ„mÃþëFûmûì?–¢Ã}°p€í2¼<Î ; 3{Áêcáþh0 Vía‰q+"?Õ¢)IuMáõÓLቇCǼ-f=ºý< T§É7°¸#¬íeÀÙkay'Xß~¿õ˜³ZÂ×ÿgÖãìùPX6¸ä• \°QãQðGXÛüêÆì :D3œ=†Ã·ý,:  SXž¹£`åɰò¨·Ä|—îá½+·<^¨— £ì–„‘Y\’Œ0{®°Gˆ²Ú¶ÙmÂÎ[A„VŠ–?o8}gJV—Õö±ËFØ%Êx=––øð¤Óx÷eöˆ$r®®+ƒ'¡Jú‰~˜´‘&ª$_Ï[Xfâ@JO¢¸¨³=)íK»<ÇG ¦mn§dý¤Bv~lís6Bí!3î Ù‰³rWØÔ ‡#^©úùƒ£ª¹"2 8†R¬13xFDvQÕ “D8ø6`ë?È~݆2•èD]7>¥gÓ¾aîÇñ™K!¯£¥{¸ècý3|ú?øe0L˜e[=CÀÂó,ÏÖª =F°I.ìò¼õûw¨ýdO‰£:¬ƒýn†©×@ÞÎPo,¤~gAB©N™¼äux*–Ÿ³oµ÷R6C£O¢Ùl­É²©»æ€í„4~Îu»8¿Cjß"ÆŒa‹·ÿÏðýÛ²J_R:ùè9Cà%ÕÇÁŒ;ܸë¡ÅÛÑFŠÞ›ìšH~OÒÑYªq[z‘°=õ¸©™ç;Æ®š Dd/àMUçîꛉ…ìgÉèê¢^.® ÿ‘+;Â.A Èzfu>Ü÷ƒªÆ§%98Ÿ˜CU5ž=Íðþz¨ê€äJÓÜï#TõÙ}ûWÕ¸³ª‹H°TUëTØ8ñûô$ÊŒ†PœbÛ´)qܶ¤Âu¢ûÖÄÂçàÐyæg4©¼÷’9Oïõw4¶¤]±ÀôÆZ Ö˜a£<òR`^}ÈK‡N«¢Å;f¬¤ÀÏ¡V!´_[6˜%iðJ”ðáÙ–øK.·Ò£ª›EäEà.,«ªéKÔ‚˜­2ãVxí¨´UæôLóëöT=+ËöYeJæÌˆ¤T¶þ L‘>ªôzˆWlô ‚סkOpž¶X ¢í„.}¢²Š‚+<`‘T£ºAÊ:óݨ;NpOÑÒ»3‘Y\ñgŠwÌXI/†½ãN)48{hV2õ$B>ð\“>=`JÏ} Üpÿ Ì‘îª:¹¢ÆÉBD²€+ñ+ýyD¤>0¡Z Ä[†Â“<:Vu Tu±ˆ,zc+j¥¾ˆ\ ‘ý‚FràvàqUÑ÷p+úïì›H¡VÏ_ìûÌëùõ!c-ìô³å´ñ”02+@Ⱥ§rÉ.¤1«ê.tûÔÒr™oÄü ªÂŒK±ªZŽ—~¹ôâ“u´¥Ò¬<ž”O€~Pzà¯hÈa"rTe_‡"ræOO¿ðþ9X"ijŠÐŽJUzîoƒ+oøC¿(¾­žÒI%…ézª‘OH ½ª¾ ü ¼QÒ¢R‘vÀ?0+SPïìÛŽJ5­ðVÔjcNŠˆÔª†‰?ŠH"õ‰cŽù¯Væu访Ç3°òôàƒnÍt!ñ*ñåps”àÏŽÉQ›ŞÇSsP`A"áÓ'EÉâgcá§%0F…ˆHððU ´B‘.@jNÈ0%¯’h·G…Õtš(Õ•§ª“€9ÀE Œ¡Ày@àCi$ñþBD:#¨ê´†@ð­-€>”ΆîñT)æÓã©9_öqÙPW§'0F–³ç0yÄ)'IÅ­‚_ÇËIvY!‰XyÀüˆ¾I ´‰;C¶'Y4ЪŒÜŠààV‰#GSiT58ø«o·_²„‘îÀ×ÀíªúbãdaÙm‡ìßÈUUïÓã©–¥úí­G:p~¢Î‹7w%b^w޽‡‘"´ ûV¸å0,)Q`åÌXéqrì‡Õ óx’†ªþŒ®Mpœ"U½¸ øHDž‘–AÇ‘,y z¸ZU_®¨O\|ž€ÃõÑÄ”A?žOº•̳­2<'æ{gæí W7g: †ž»¬²}1ød93Qÿ9øË tš[Í«'P[UË©7U.‡“ðeˆ7üöqµae(ªQ€Û€ëD$hy˜¿PÕO€nXÅôé"ò°³’Ä„ˆ´‘;€ÙXEó®ªc¹2ÇlÜü3aŽ!xªŠéQ•Y¹=5š‹Ö¦ÀtÁêmo J^¯Ë…iù%Çóò`inÉñÄ|Èݽï†\˜Öw~üžWr<%6åFï»)×·ŽçYÿÐñÔ|?Zß‚-0!¬ïÒ\“;t<-ß>WèxtXߢ-0.¬ïò\˜Ö÷ç|XSƼ‘Ç+rá—°¾³ól¼Ðñ¸|›/Zß5¹ðNí$üuoþ!" %üRã?À@¬ â 9]Dâò;‘Dä%lKë&U½8 [ÿnM ÿÑÀ ÊPƒÜöqx@^.¾«¼†¿²Þ'µíŠrÚnˆÒ6Da”¶¹å´]SÃÚ†¾£îÅUXwk+Tu.0sÔOÆxªê ˜ão1ð‰ˆü."ÏŠÈßDäéáœýDdˆÜ."c°hκ@U¤ªÉȶ}+–P4ÐÖ”³´öĶÙ*‘=/¬<ÛžÏMDj‡V½nEŸîü;‘  8TÅÛEEä…ÂEé› µ m³¨jAXßüPÊò ú¦99cé+@­P¡K×7%dMp™{ Êè Ö7s ï[ú¡ïe¬È¾@QXß,`Kè»Ò7#@±Î­‘€…ªúïDÇ ³ð/`wl…övC]*Vêþ†;a‘Q=±„g ¼ QÕõQ†ŽWŽÓ€€‚&%‘_€ :qV0ÇiÐ0l7¹ÜK/ׂMip¹«3ößpÔzØÃ)ám_È‚ÜÔ²Û>Я,i[—¸ú‡ÂÉk¡M1¬ø_Ã’qŸsŠõE›Kæ¼`54T˜Ÿïׇ\B²g³-IØù[¶žóçTø².\¿&zÛðÏÙvHËîzNîÖm'¥ÁØ:pÝÚ’¶õ à̼èm¿Ë†k\ôГ9Ð$úä©Þ^­?x"Ò³lž©ªIÿq‘Ý0klW 1Ð+º ÿ ˜ŒmA%Í¿LDÚãÝÖ ]ÃW¨ê¡É’+ú<ÿ͆ï›Âϵá¼0íøþæ¥#»žn}ÖA{÷= s Æܵ7/ >¯W®,{ŒÀ›¡‡û?“‹3`ûß\—byØn S:i ƒVB3—møíºÐ¸Žp×ÐO0).,GögÂÁ`wç¸ÿq¶eRàV6‹Ráý†pÍŠ²Çx¥>tÈ…žîz_ æÖ‚³×–Ýç±&pòjhíîGïåX2ÃãÜ=hf:|›—¬.{Œç˜5.¤œŽÌ‚•é0ÐýN,O7ÃuaI j­€zî;{£´Ê‡CÜw6)3úß{ð¯ð÷³ "­±Òó‡Ž*gì–˜iº/°v³MÇœ¨`Ëí_Ÿ€×T5"q[͉…¸ž«ªcŽÑ¥ªý#<žX‘ÞÀ›@¯íÅaו¬˜¤ª$0Æ·À“.M†ÇS%x¥g;GDÎÁÌЕžÝUJ*-¯®Ì„j.âÁªzBc<lVÕ¿'O2':"rpÐ3dÝV‘K1æý‚^çbµö†m’iòx*Â+=;"ò0fþ>¶Cx“‚ˆtâ= šÁYDêbY˜÷TÕ •Ù=ž¸‘瀦À‰ Ô‰«VDä0,·V/U]À8/sUõÞ$‰æñÄ„Yß1Œ9>>XÝ‚$‚ˆ4ÁBݯH dXÒ·‘^áñT1W`–лª[ 8?ž7€ÓTxcyÀþ/I¢y<1㕞gÝ9èç¶»¶9œ3øûÀ+ª8¡s²¾ K½ïñT.°aV¢â¾ª(ó’,\}­€õ£ ã"འÐO"øí­éŒ®UÕ·ª[žx‘籨”‰l ˆHàUÝ'iÂyW• ÆXæä³TxR€Û‡“%ŸÇ/ªº»Wã\”eDDºß_$ªð8^𠧺ðJφªþ ìe#ZÍkËÅå3z 8 8ZU7&8ä%X†»7•ÍãIUÍWÕó×€ "²uˉˆåâºÉ%(Mt¼Ã€C€;Ëã ŠWzv@Tup–ævœˆì\Í"m…ˆì| ‡ªêÒÇkÜ\¾­FÎx¶?Tõ!LÿX¬¸oµ×‰‘TùðÐWU‡&aÌt`pMå–}ñxÊÇ+=;(n¥y.fõøÞ¥±¯Û]bÕ¤'¸”ùÉÈùó–$±Ò²/{–¨êeÉ×ã© ÜÿoOà4à,Úk(ð®ªþpÌVÀq@à`L!y‹¨Jjéw/ù‹üº#™c{À§Àª:£2çòx<[ã"0—úúvžš†Wz}úÔÊÊÊÅÅåèèhjjêæÍ›+++·nÝâ‘ÖÖV ·Õõ˜þóx°ýîî.KJJ˜ƒczzúÅ‹]]]«««)))¥¥¥‚<êëë®XWmcc³··Ç¤¯¯/,,,>>~nnÐÏž=«ªªC$¡¡¡FFF±±±kkkååå^^^uuuòT‹,h;;;0÷÷÷ÃY^^1<~üXWW×ÉÉéÎ;0ýïñ®‚«ÇÏóçÏå)t%1§Âfùùù¨6 `yyydd”èÜ‚Zôôôz{{цëYƒ¸===EÄâ«äTˆéééšššæææÐ¼½½­¥¥åããÓÖÖh QYYygg'$$qkkk›˜˜lnn¢r–Q¯öööŽŽŽò©E%q†joܸ”“““[ZZÜÜÜЮ¯¯oGGGxx8  55µ‰‰ UUÕÛ·oïïïwwwB|ee¥ƒƒƒ 9Ƀ±µµåííSPP€€…< ÕÔÔTGG²›ššÐ:kˆ3!H ²Ò‚`ˆdii‰äjyÔÓððpOO²1pa©XZZ⇇‡€swwçWEE=X[[ Ù@*,#¼ADüÕ÷™?ÿ–'³Ù9U¯ËÝ;þJ¨Å“¥vt<à ˆ\AÁ{ǃ‹Ož¨3®˜™™‘zJMph~!µ¡¡ç1RyðàñöÚÚZ 1!!P… ÞGî’Ã_žb…"&¥Ì9äääÈœ·>|˜™™)q&hÁ騳ÑÑÑÀÀ@öã'4EÌvñ Bâ.€ØVB[H¶___çndd¤ºº:w…¦x}Þ§ fí²ýüü€ÎÞ° 8LƒëØ à ûã.6G!ÎÏϳŒ®¯¯Ï_‘­Ó2×ëÓT!¥†ãÒMhìÊ\p=~…0;Á9opAâdœ$Ü¿ÿÞ½{èçõK®µÅœœ=¨}d„BÈ5çOÒM—±µµ¥Î ˜ùìì,|(ÄßßâYC÷&*('ñÜwÝǽ“6NŠiÂÔJHJJ*++C(™rȦF‘,ò…oØ¥@aš•„Š ÒØÓÒÒ _>’·¿Uù…3Ú®Ì;=Þ‡G{{; ˆÄ"1/|ß9ß~°oD„K»Á.è“““hA#žÄÄDäV¢ø¹}¹H.“M$ Á¨ÖÕÕÕÙÙ)‹¼ÊícöÐ"ŠLÞå&ƒ @¿GòþÜúXÆPkÿ užQÀ‹8ˆP*A¨DÌÐ…ŠR R´þI­¶CÅ ¥­ˆí$.Z©HŒK¥¥T]M°DÅEA‡” Jˆƒ‰‚bqpS¬[ú3§\ÿ`J›ö^Óoxyï÷½÷~Ï{Þçœóœ£ÿ?Ðiÿ Ä™Ç^ ÄpÈ2Òä¹NfìW¥ïº‡t–\Î!Öé ôëEÁàààÌÌŒä-F9ORÜØØðQsïÞ=ÉåÌW¢¬|–ä+í tPh‰8h˜H{s©DMAxܽ{×GÛåp뇆†FFFRé¾§$˜ê€B¢1|lnn®¯¯Ÿžž6ÏÈÈ`f<&š+++«¨¨˜ššò¨±±Q…k)Ë‚§xLìS›sssæ,G!qéÌÒÒRz:///Z{KKKj„bŽ£HÍ•~2?;÷è¨ö€£ú«««‡‡‡ÑƒbÎÎÎÎÉɹsç¥As†àTA–——«|/ ƒ8Y¢¾   jA¥ˆJšxmmÍ2¬ ’¶*pöVÛâ7!zåÊßU¤¦/z,óE€¨>ÈyE«àŸŸ.r™´”¡Üñè'ÒÓ¡_XX¨©©Iâc“”ì×ÒÒ‚šŠŽ¦¦&RÓÑ ”1»ªMø¥rŸVŽÐa?ê{›´=¤? =ÉoŠ¿ÀË ØÙÙ„(…`BÄ öÕ|̯ÜòÈJqPýÇ_£µwÜYüzÈXÛücr3Ht8¹¾ýýýè2F‡À莉½™Ë)ÖXiÞÕÕ•ø©ú¯~®kùéƒ/0ÿÓ“ñÿ½Úoc’÷Ή›o\þèõ7?üÇ2<–ŠÝ5),,Tœ²7ËñÅùùù••êÂ~P¶¡¡arrÒ¼¯¯b8Cß_ùÆXóù÷ñ±ôãïb²·¹ßz·µé“òËoö¯l¼»»,sÖ¿=¿¢g¡ •å9FUQc9‹Z¼½½mí±tww÷³”\i Ü9\q &¶¸¸øèÑ#VtŸu~‰Ñ#­«;jKÔ›››ëëë‘M¢ß¼y3Ñ&䬑‰²²²bÁƒâQgg§1bN´ê ¸²²Rõþ bd3‹‹‹QYfxyy¹ªª CtkPekkË \ºtɬaàè…F 4ŠÍ^ßßßï0‡)pµ¶¶BVWW¹rìÓâ¦m€nìäœ ˆ)µ§OŸzqüÙO”ÅÐ!¦4ŠŠŠ ±ŸÛ·o—””<~üøúõëÞ‡-Rt{{ûèèhooo"%/Ì¥½vâ_`ÎúÁÁ³EK˜Gx!»Ú˜Ø|xxh½-á±yB%'ÚIÇ"@ôMX• ÷Üø n¢¯ä2;;Ë/%ÉûEë3lN:by˜yž>n Ú„#R§bˆ ßÑшÿŒAIãñ9½C±¢­­-Ò/æ¹°hMaÄüŽ*ÊÌÌäpTÿ_´‘RÚ¯ØÛÛcH±l``€½™_ùœûT^¸àÉšôêò9§ÿðáC´Z1‚ÙØŒ{ùHtQ×÷p‰§s.lã¿iË”µÁÿ€œ{ ±ªŠÃ>]JI´s0/Œ ÞPG$ó’ÌØ¦Ù£ ‰ø ^ÈÑ"! „,1_$ ²œõÁql¼ ÞÇñY’C^R3à )^zÉé×üi·›S39æœöÃaµ×Þgö·¾õý¿ÿZkÏ_ÿÅS ‘¡±¹tÝØÒ‹Z÷{ìÝ·áDë#ÈDÀ¹ûG[;¬-8ëíVK—.ÍÏÏ{äR¹¹¹"xZÀ3‹Ëý™òx@gêÿa7Äœ,KÄ€ØWÎI~û—.]J/Ä?t瑞äýq9a™'_¾|yß¾}¥,2×I“&ååå9ņĿ9:ò@Þiûöí“'O–a±¨%%%hè}ûöñ…;wŽ{ºj÷îÝì Ö§½`6 H&”™béà"#åß<í¡C‡©•²”qãÆÈ}.\èSV(ûÄåùóçy¬Ô mÛ¶-·‘o1ñµ_±bE=dA\â”)S…IKvkGùÑ JRXXÐAƒ­]»Á[¢Â݃iÓ¦Mê%j:uê$“Uf©uÝ\I[€USSýÞ½{_»v­]»v••• ë&L˜Ð¾}û‚‚‰ã™3g’‰ôlèGÓ ¼¼\v'e&±EÊÇŽ &ª¤ RAT5äuIì)–×IÕ·iÓ¦¬¬LâK[”cèÊ•+ݺuƒ¾ºxñ¢þ6lp)‰BN6:¹;vd:t ª ƾ½{÷jÓ±cÇ.]ºè†ØÇж8‹à1 »ìœå1  |?~Ä1'¹dÔ#¯º3‰›HÖÓ¢‘ͺ¼lٲؑ ˆˆo±ó3§~µ/4רÇGˆ++Ðn—_"‹ætÍÕëƒÃ‡wŸZW¯^2dHhôåË—]¥½q Wb#ÞèÑ£“™Üìðv,Z´¨oݺ5VÉ<eðœð‚ˆÏÓ§O3j¤¤ {¼þ@[e…éÓ§ïÚµ‹4 w'Nœ ÍÁþýû)rQQQ,d‘ÔÐúmÛ¶i0~üøþýû+è6DÞ¸qcìkEüÿd[ÕýðË×àð¾ÒSc™tD}ø„˜ê‚T,•if¤ÃÝç† ÆŽ{áÂ,Ö+Ú‹„zE3·‚>ýÁÖ®]»Æžh…X’áF¨CÙu vçÜùæ[S#_Ÿ~ ƒªÂ+=Í¡{âƒ,èœ^H À¥¿ÔàK&øÚ€R7¤ÂÒR¹`Á"Óàç~_ð¬«ÛòiqÑkÖݮ۶æÍÂIïÿ¾7å×Û›?{óÉ'Ú ÿîíú_=TñþÀÂ7¾ªüðù—ܸqKMMõǽOWx}Æ+Ÿ|¶åúõ[¬\žÛõ™§Ÿ›¨üó›žzvÜ Cûì­úæÆÅŠÏýbªMô—AŒ9m ùØl«%B¢6|BĮ؃z¹K–,:>ž?^¡Œ¶„¼rÖÓ¦M;wáCŒ†©S§’ªM©¨¹J—46•â·—nýü¤fçoïZÿNéæƒñµºüŽw+|ùÁ·û?R¸q³Öç÷GWÏ|õæÍÚkÖþôÝC^œÍ@…òKî9ÄšÿtR fÂTŒe@ƒ›> Úž={¤Èë¬S¸Bmm-|9<§T²zè=za)ÌÉ“'ûõë‡×Ççä—è>š_ܹs']ÖÒïêDÎðºG†ãù—ß©{ ‡ï&2ÔŠkðš;wîÌ™31ŽŒË}úô G^ãm`©w‰¾qjñâÅ—äjƒŽÀ)CP7ˆ¥¥¥¾ºOø¿Øñ¼fÍ?øìy¬„§E)Ñ4QQ·e`LUÙ{Íf[²Èû·•ÿV1øªª*äÂ2A̘1Â]uu5–7P“Ÿ={ÁW¯^í+°@†ª„›Ç˜5kÜ×­[§½€æB‚#‘AäQ£FÅKyzbåÊ•h.m)))Y¿~½åÝN9þ0Æ#ýׯ+@Ñ&œR¼í“^®O—¹Ã‰'¦g¦£瓎´nv(¹\ËXJoð¢QÓ¢_RXµjåWóóó±ØÃG¶Æl9Bì …n‘æÉ 4(‡ý@yZ,3Ôž0F;!)§ ú‰@Çãµ ÷ô£èIŠö±¢7HM3ÌmA¹E!N~æ1<†ˆÏð²Æ»tF+2âù#ú4XŒ¹Fn:•mt•b£kñU¡Ü«W/*¬Ûâ…nD«Þ:uê‹ S-é‰Úèôoõ³Eñ FwøYÍ]ÅÀDåðÈ\¼tCEEµÂSÄ §ì*#±–•zGv.Äîxý¾ÄÝh€©þsŸ²²2 '­Ð…º!²Äœ?vù´öùÏ¿ÈJ<9ÏÓ•È‹‰@äÀ0èFòòòrê7zÁˆ1yó:I$”±Rʧ'hjÏž=;^&4ˆÅÕˆuލ12Ø9sæÐ“d½5:/Y¯jX7º†í™ j2 üý‘#G ybAzâ,q²bgèСCeÁÄîÝ»ÿZ°ÌDv˜Ëe£0Å'5î {ôÖŒ3è83£?€î¶Ú¤Ã] ·R:7augåðâ½ mHÅfb#±†#¤ mb¹$ý”«32š={öÌÍ͘“Ú›5³ÍD¹±¬<YkÌ¡?¦?VPí¢¢"‚‹X™'3³u ûïÊŒâ1>áo¡lÒ> lVŒd“Ê¿yþ»ß}mê|KVyŒ{>Õ tÒ2…³øÍÀ¢±šæñÿ¹.;dú7Ø;󘪲;Ž¿XMF­£èD‚»7Šâ^,¶NŒRPÜ ¦âbÿÁV«IkµmâXu&1h4"‹Šƒ¸@DqAÅ]7ܪ¶—ԥ߷srç¾Pnçþñrß}çÞûî÷|Ï÷ü~çþÎïTŽËNíÞ—˃¾š¢=+¦¨3î+¡Õ÷xž£€ÖAdgÀZÓ½_FK·v˜.Õ©ûÞZ¬¨¨(99¹¤¤Ä3Hÿ­ Úâ?ä²÷íèÑ£8ß:tÀ“ÆáoÖ¬Ù¬9gwªuª„Å*©÷&bV®ÓÊÒÙ¼w˜:WÍÜ6áräÈ‘/^77ךÈhåÊ•™™™ÖÞÒ:øéX{ÙPlöìÙà˜””tíÚ5ƒÂõë×=zôìÙ3ŽÜ¼yS RŒ .(¨ùòåË+--½sçŽÎRÌÆÃ‡©†Ç›Dp\oI222ø¬a˽ƶºüaá LLLœ:uj“&M®\¹ÛнÑÅALG"4g8''çðáÃ!!!°ÕÇÇdõúnÇŽS¦L¡˜æ›:t õŽUQ‡€Nu*c¨Ëý®Ïa½_E(óØÈú@·¦¼îjø|ê]*Xè¥_÷îÝÙ¿}û6ЦM0ñÈÈH—;üãõë×W8>CvyJ˃‚‚¬\6“¥œaä•‹2M888¸qãÆSôøÐ\ö}}}ÓÒÒ–.]š’’‚ò.\¸ÐÌÐß½{7þˆ¿¿?œ2¥æÂdFIBCC‘š²²2̤Y3y$ÜB­„êAåµïÝ«W/`å8§S RrŒ˜˜5s"æ9µkÆ ÿ¹È+¸ü¡û~pBÉ<ÐŒu ¾blARé5¸tëÖ çE¢A÷Õ¢E l^0R¢9p?::²ÓÅij&LÇ£á+ÒÏEØ}Žgggs: ¥< ýl…v~ý›/â“sÞ‚²ÇÜUÿ^S>C±„rI̬š…`=øò»MsW õ8"ßÂÔhš*ü·{ãÆXÇÊ2À)hˆ‡……yþ×?þeÛéó7‡t2àgçJ' 4aɛї¯$Í ‰œ÷êÍ _Ôsþ¬q=ý¡ sYà€8ÍfÕŸa§øÔ×­¢6üèñ£ݾ´µyû‘zçp`÷Š_‰{ýêu£F n\Jªv.ëiñ0^©•ØÌ`E°É4‘Ä3j 逪 Ò€'=žŒ6Ôƒãà(šò`}ìØ1îB1êR“‚*øÇ{™}ßO[:’¶èØ7KÒöž°üÓïÇœ?¶æRÞ:öøo«’·nøüüñõ¦Àý’í¿¾óW¡¿ûÎý¶ÚÉ!gÍ p4ÿ9sæhNŽÕuDLÀnÑ¢Eè,šŽËg5ß8>>žS†ˆfìŸKíÚµ {#88˜åçç«c¬@ŽÓ7Lÿú‹XíÇ' û´[ÖÖ9<Þ™C_µôkÖåç¿5G>†ª7ï{-üèÖ7ËÒÿq§êg{a øÂ8•Æ‹í X"R2_¼x«°ØÁ’ UIG‚qçÔg"2€‚ZstÚ´i Çã:”ÁXt¹'°ìÛ·šp¹×E¤¼fš)ð^7ßO>¾sïM|ÿ¤ÑPŒ [³ÍOý#>GŽgüÕ‘b4úé×/j#Ř>{•í²o¦5i1ôµûzÕm›1Ì3# ‹C‘šš:räHÍæEgddë–-[ÒÓÓ¥È9992- jii)$MHHÐÊMôiXÊû÷ïç+W8p FÝñÌ™3†c{h¤Ÿ›îÙ³‡K­Y³è=§2¿u]‹_Œ˜ûúCݼ(†RÑeÁÖ€€°z0Å’ÅÌÀ Ó‹;º5l ™qüħ@jñ……ÅXZ ô)bPÊËŸÙîÝ»´æ]áLr#3ˆa{ã÷V«î«ÅŸÕ&{Bir/òºxñb°Ö`Ï"`4aÂl4Aã>@@€H{Çîҥˊ+@™N NëÔáÔ¥¤¤¬_¿M—àPë:S866–šƒõJF`EÖJa[ZÛÖ3°½íˆæXWÕŒõªAÙúöèúiæxZX@†GŸ>}°j7nܘ——‡ ÔZïhSÔ|Ù²eãÇ5j”øŽ¡ šêÞ¿ÿÜÜ\???¾jš*§sM€ž;wnÇŽ=˜° ó?»7öMz>'Ož¬±osÄä03ÖMOÝ_i Ö™òÖs=õtŠmMÛÔûJŒ/ËŒKNN²sçÎaäru°v ¡Ò3h”«HLLä®ÈOy•³fÍ‚Ñh:ŽµÊœ®á=d_éèzt<++ \ЬìiÔ+&‡ ±2/ =#š¸7³§1‡–/_>cÆ D_ “»¾Ý¡¥J§OŸnk^×dÒ-(Oò˜tãóçϯ¸a•ËeóšÚˆÁ+º=!D:Ξ= …éùnΛ7Os‰5x¯¥þ8…@Mè• Wã:TFñÎ;áø’%Kð!±ÛšjÀLîÚµ+õ¤µ ¹‚Þ˜Ø"»àŸÜ—>±ÒÛYó: M|±^±Û4]Å+**ÊÊb}š¹´Ö–ÄV‹a“þT bû)íðð¨*äS›éׯ_š‡D|/€'µ ;˜7È‚8”YÔƒ‡¤’h 4ÊCðúîÍå^•]¦bd“DDDp¨ô›@$[ xÑ"æßše´,„­iZW†ÐánTŪ“žK·Y÷7¸7×;Eáx-‚"5ÌE1µÌª•¯ˆìÖ»g„(å¹i*6X‡„„ÐZù†ê­+¸CU.Ò®];U÷H :)‚ÉÇÇÇÛ–@5}`yORY~UvƒÎUccèa´ ‚ÃHèÝ»7ÇáF9Øä§Ðô”yO6‰NTÐö5ÚÂg`` Fà”÷…Ÿð÷`±Ìm8Ny¨I>qâDЧW4o²5¼`³èkýø²iž¨à*@KÁZÈ(Pjº^-c]€©†ž•/t€Œ-Š ±Þˆ¹§Ð&8—)¦uD4ù]«&s Då`u}ʉê^†¹Fñåb!¾W®\Û×××\i|2‡<%ᬼ¥“}IVüU À–@vh\І¢P.•À‘QÕ©A®` »Ú_[׳K…›à«¼¾ÊSö­{3ÃùX @ŒwÇAE#Ê:¦ë¬V­ZÁSî jãžéµ)~@Ÿ8qB=›òíP¥–3¢• ©žM›6±“‘‘¡X„ˆÞÊ£æh‘^¬(% ­„ª7nÜèÑ£)ã²ÌfµN{¯±^Ä52åý  Qa@As…2˜"ˆ€z*ÅÈÂ}¼j-IH%)k5”ç'dtdY%U¦SܼÆÎãÊ“&M 3[]ÞZ=ùÝ»ØÁAá+Ó˜F€ÀkÄD#5Ðs þ)d€–Ny*İ`~hµE ëE”"øA™ú eè˜1c; ¼|Zÿ_ò™_Á7>>‰Auwšàë‘W<¤<;;›ægUi }ûöMHHÀ©¡/EvñkøTL éÓ§+‹¤çzj•Y®õ([á.++ƒ¼%%%ÐP†ÔÓ*¸ÈH¶œI û@©|r4„­@jP|§2dZ«Óä˜tXŠˆJçÇ Ékàí#÷Êt•Zó”ƒ4»kLˆÑe ŽERLX µòµtþ<ìÊ’HkĦ¥¥)·»@D^¤*ÐÅ1b†‡×5±äYs¹< õšíÂ… J®Šà‚8."–2ÒaÃѺ^’ˆìŒ9ªÕˆ²;ÅÄX×ݬ ð§pm—éšv[ß/Ċש1pß¡gSg뀼$ôŒcì¹:5ÆâwS ‡çàz‡íÝfžzMa ~øÑƨ–nÊa¾ß`ï\€«*Ò<žu­E ðäýÍ€#_¨Qd¤V]uœq©±ÖU)‘­AÝ)—Ç*‹Š@Áð&QD@TDDñQ[[º?îoì½ÞÜ„ à$ážJÝ:÷œ>}ú¦ÿýïwý}wZýÆUÿTi?¤Êl”«ÇY'Z©å_°¯ÈK¥Y¶Äxà >ãþŠè€5 $U>V®t\wÅ¥$:Ë Þã—H8ò=£~Ç­þ@‡a&úd:ô’Þ.ˆrÜ.%×” ò¾þúë±cÇÖ¨Q#99ÙèæŸþùÁƒ³²²7n¬ùÂÉ1ˆ«+ª¤·Ü”Ë¥›OÓò"uÆ +V¬¨W¯^­Zµ.ºè"—¿ýöÛ={öÔ¬Y³K—._|qô^ª“ÑÊUÀ!qüt÷V§ÏÝØ*..»nsÓdÔ}+GÝ·o_ýúõX‰\ZácÄFÓá<øÅL ¾ê@¹üÕ ¡ØE‹éš«I“&ˆ-:5Ê(ù)8`øêÕ«JûË/¿äqàËÉW_}¥·´˜2<ýôÓû÷ï×'·:”™™Ùµk×jÕª}öÙåAvÉ[q]']eµr‘¼&Mš¤á8RÕûÍ7ßh%×4rp1¨^ 9rD»DýâjoàÔŸÈèuëÖ×öíÛóxð£A›7n\JJŠÑ;²dëÖ­dÕ©S§æÍ›‹è÷ò„F¨ÚæÄƒ&0]‰YyÉ’%nbg@dôèÑ2_´S«ä¹ÓÄ è„‚‚‚½{÷je«•WÀÍáÇõöûE‡'ÐÊ–ö ßÊvíÚé›”Zö;"¬4 °qãF  ¥otñxdúôé}ôQÆ Ñß´ŸmÛ¶Ýu×]𳆇¶Z’›óq•Ê%77·[·nÖ¤H(ÐiÓ¦1X¢&ôÖôÛo¿Ý¦M÷Jé¤H'«4øR 6‘@Û¤wg¦ q±ÉrW7R>;kÖ,Þ>lØ0Yt:xŽö©á‹o¯ëׯW©ëuʘO>ùDo_äLoàþfº dztÄóè–ƒÝWV(SsÙÙÙ€ þš¡7m%X 7¤RÈV†§I †j×®M'bHIp¹2Ñï#ª®Ð6[¯ôÏãcT¯” {ž Ny¯Þ.MŠBM{¹ŽÆ ú #U¨R(Û=÷ÜCó#.Âßä y£@3¥%q\Ò  äJ ejQŸ `q.½  ¼¼<øX Öóî¿“½dctxB—ÝËÿt˪güú‹9|æ¿õgX™“]ïN÷ú_~Ý>}TJý‹ömý¯¤HÌÍV]éw휬ZS8Î8¿ÖJ„?ÿp¡_Ûu~AÝ_žŽ’§ö8«ÿüó\à舣]œÄxByë­· X·lÙbÜ's†šÑîQ¸Ø¥KqðàÁ=ö1ÂÐ1Æ,–kîƼyó8™1cݯ»÷Þ{ŽÀXÓ…½qÛ¡FªhbKzz:×áu» ¤×Hd1Ÿå9úõn{ëµé †~å/wÇÜͼeü7?>hÄ„ÉÓ—î|ÿã2òéÒ¡YÜëÿ=õŸA-ãŸÚöº«Mú“ÿãõ¸É¦Î8†Â5Ëžö+=SÉ4·Ü˜s¥fƒÖ¿êÂzWíÝ÷IU‘aqkÇŽÀÉñÜsÏ3LŸ>½¨¨hõêÕTór£¶C÷ÍæëK¯¼ÅgÃFiǘûoå“#G޶ëöëJe+ `!4A02|ƒÆ6lèÛ·/˜CY †6rupíÚµHjM5&NœJÈ„G† ”A˜ +ÂÂôEqq±³ÔÀ:)²?…<Ñx’"!íñÐ}4ˆ÷ªÎµöÐrr2C=XÛ¶m—,Yb›ÌÏÏ'çàt>ñÄ´F²š5k š6mZ§N­[·¢UÀ:mí6ª”ßÜâÖkz4k‹•fM’u}¯^]Åæ>¤7¿{tÖ}ÌlÞ¤îKÿ~Ï´—VôîÞ*:ý”Ùoæì˜™ºþñáâ?ÿÿqdáʧÇ?5wÛŽcárî5øº=ÿ*Nò¦¾<Õ-#ÇŸþ¹=pkÃu>Ø2kßþƒ7 ôÈ_õLk{`ÇœÉ~›ÃÓ‡÷gó9û¥¥¯­Ü;£ã)µþ·YísÎíȈ*lÕt€±ÿ‹/¾8vì1açf$À… ¡dÒ\xá…7NMM… I‘€ØÎ¹ Zʃ`´víÚŽ#i<7Üpúuë¶oßÎW¡ æ$E8^KÑ>}ú¸‚ÍSÒllˆ ”ÉÂ… 59xð Í€Vgоò^å2ÃÁ¼¼¼«¯¾š¶ád/¢‰’3­qþüù¼®_¿~ü„²ÃqŸª9f†}ß÷}Ðʉã”Ay×®]®©2,XãöìÙ³nݺÀ˜à šd€}ŒZp6Íhh\ðÁgΜ µ»Háú‹9tè¶M2¸Kø•[ôû éD9di8Š!tH†ŠÙhw#G/_¾œæ¸¹%ÅÒ<ÁÈ­Lž3í0;;›Ekq‹T‡ÓÜñÛ¶m+,,,”cVOsÏkØg·n½ª2Q–À $­Y³-‹¢…’—.]Ê­`Œ*ëà’¾‚x…›¡7Æa¤Glh¡aGÜf¶nÝš ýÀ!Ch ;v|üñÇ'Mšý#Ž)†3Ð (ØÕVŽ ]=ÉÈÈ å³Ï>K©¼‚r:Eˆ.2ø1ùð[HÌ•îÝ»“˜‚@BZÐÚz8Ð{‹—e7z´Ê ‚ЯX±ââ‹/6¨î)Ç´¹CÄô²ýx”—Õ")^þô•€•Ãu8löìÙÚøJº†ß‚·4r9šs¨Îî;lýwìOb¯hÜtœ,C7ë^\cË`Lgô°n…ÔñãÇ#Hè(Lƒ Âä´V†ÍäИNS$Ò»¸hÑ"ÄÃ3Ï<ù‹;ä õ’Øè¢.¸¸iXŸ’ׯ_¡²lÙ2’QrXÙp¥q¡œôÃÆX+¸V­Z¨v𢡠ƒ‘`Œ³>IpÛm·Êûî»ü÷>+®sú¸wÉÊàôdÈ'­H捻 »h¥—îò"_MbÎ'D»--YÔy‘ÃpÔ1E"nÁ8ü>~øa¿‹zä+oáüºë®ƒ/Êß`NvؽE¸꧎8PPP '˜/%%…þjtm™!„ ܪ̓Vð*þ‰†Á9\¨PþßÈáò8ÐQv§§§»|Ý¿™Þè꯼òÊäÉ“m$ 0ŽäÀ¥ 4¢Ê™é¢¹¹B9a}@Rò={öðlíÈáhUiDÏ€v‚øI‰:ßgýp$E9 ˆNQ‹c¨Úr^¼l ¬W€Ô>ǥÒ{X’"á¢ÌqòÚk¯ýhr­fÍpN: fʤG_/íýÀ4î-[EÒ1ÞAv@ð5 (÷ätà8>+G¦—•µ1Óç"gÝgJ•§¥¥ÙËÃsn;5;h~U~~¾Aݹ‚,Ò6oÞLÿîzŸíÛ·@]ÔSü¡zvØ¢ò·‹)dHJFfÚåíÝ»˜R0Û}+Œ[›ì1x` 4'JK_zãÆ‰2ÐJ)¶ÓÉH·ˆósrrr¼Î{ae44“¢ìîKÆLú±ñç‰öÂð™²Äð|•T¶ò¯Çm“§•KzÕ¦"!`WÔ4ds75¸O|…‚Æ ¾«EøÛvâbyÊ ·´¦RŽÉÜ øÈñ™9h_Akö:öÉ" †ÊÆåEð¨ž?Gªp= ¾ÝK»víÜ@h´`¨„Lrs€ûa©ž¢¥E»· ë2ÑþŠâÆ"<Ñ9  #ð*ãA•ýÌ8.k^9šTÜ~l,†5ˆã"@0ôÖ²eK­¸ —ƒ5€›I­þ®]»j½ ªŠ‹‹[µjŒ”¹ ÔФ¬¯½?ƒ6‡’ùdffæ¦M›Üb4hÐ §–µm+`K[M¾Ý£ªƒ6²Ä0z莃!M0‚&[´hA2v äž»œó.Ô#-ÜœÂ2¡0Û·o?¶vuø0H5¨<,K9¬»À½yóæ:À¥0j rcð å“!?“+y½zõ‚½GëbŒ¯ù8Ü%V! –ô¨¢=ÀxŒ"Ž:Ï!C†(mîܹT!ˆ×e‘vñÁ<<éòŒ¾yÄ­²j÷nA»Ã?-¬Ã'bAT ([γº-a …$àHOOg„·fÍ'¸ ¶vïÞ]PP@u^zé¥Ô=à Ç¯[·.X¡= ‰5Ñ$g×íœ;³ú]ÄÛUÔ0´>y\7Y^èÉ~”pó"FrjeîÂß$Ðä__´zL„_;vìHS$½„íæ¨¤ˆ= Ÿ°>$î'Äe£üd7p‰r9îd…U xýœÇ߇!s€Ö°~rðÇØŽ*‡srrøÊ žC?¸TÁuðá0îÒ5C™€‰ÜB-ò3š;#00änmûeØÔ Nbšë6pé:Ⱦ}û€5’|ÓEð%ìëIšù$ è uç€5…¡Í™3‡âQ6ÆhtÈâ+W®¤½‘-8æ·ô=z¼ûî»drÉ%— Eô†íì9fˆ¦/âZl'Ž¿Íj_ô-QýÔ7Õï„\:ùÔ—kÓ¦MÁ5­‘;È“‰]¡ï:t(üÛåÙ³gÛ­#îJ>õ¨¦¡Oð|®\±gpÁ¤MÚ“!ƒ¨T—.€•¦EHO1hc´† ÂÇtÜ¥`º»¥468žg;…¤¡.øÔLHK#A‡Ð|ªgJ®óE³rXÇŽ™¹KÊîÜ k׮ݲe ˜NIIq¿«\î·4è ꞯëÖ­Ööò©©©ÙÙÙT-H½âŠ+A‚Tý hêIåÓBÀèÒ¥KÍŠ“Ÿð·^éu èÜEXܵk×Ì™3=m™¡óŒŒ ZâÞ™”ú¼yó@-Dš‹‹‹×¯_Ý:åj5HĪ^Ô AFçÎJíqç£ÏÃN™Ž+"”­-·ûÓ)Ã[NÜ‚f¤¡0ÐtH‚/»ì² 5wË9­Z‹<åô­Xtë¨ÎÃ5up€Ü38dËCàþFL".”Ëç;.¥U)XBDÆ2’ããë:N:¦µ—O)x4l.Ö¬V’[\|Tl>®¸ötBM1‰¤€øËMd#SIŒ'í+§öŠ~ÞV¬Q¯,Ƈ¬'Ž>>nÖ€tý"r|•Ç•dN'ìb½@ã£"ñq91Ž8p ''gïÞ½ßùÎw222êׯozà#cÇ …‹•Å1ïÆºâ˜¯½öZAAA•*UÜäüÏþÓíþ×_=ŸÆy9*B šcÇöŠ£©:vïÞ]§NÓN;­råÊF¢¨Q£F~~þš5kjÖ¬)¾Ø#ŠÝÒ}êãu»ÇÇî¬å+$òH$÷ù-\¸ÐdîÑpƒ‡7•¡Ù)aYb(Ÿ°ó¼c·šR„¸•°žtÒIÆàq7nܱc‡ÑȾÌ*›ãu»ß^qt_pØê>~SùšÇÉíÓÿøÇ?øSL—Î襻½§„-vΗb0‰m' ŽÑ*€©,MÔg¤‹3Î8-+ŸrÊ)áÓ{ÔçŸÎŒÐô¬ne=ä¯(ÝŸ8Å=:„ªÑsâÌóÊâÏ>ûlôèÑ«V­âÝÄÎ;wéÒEÁP¬™–ë“&M:묳Î>ûì“O>ùÔSOM$“‚Ë3Ï<³nݺf’4ü\ôö]»v½øâ‹•*Uëßþö·ÓuÇwsèÈìѤt‰´ìX7—“ã˜ÛÝ߀jÕªU¥J•Ê•+A`½nݺÛn»Í ÞéË¿€¾aƆ$ä[£ …80´¹›Œú͹ôæ›o8p jÕªð75ƒcÇCéÕªU£ Ëñáâ¯+{ åD—>ÈšZÁèäË+VìܹZMü{Px>ùVÈw³¨äåbõêÕ öîÝkËð,oFò}nnn^^2à /ÑÆGö=q& ŒŠ¤+ÊDµØT!Y¶³/lùòå†p5ƒÎ—½*ÂÞx+!<¦'ÑÛœäççgdd|ï{ß ±…ø4ßž‘dMj oÛ¶:Lwm9=aÔ¨QK÷îÝ3Ñì ÅÊ'ÏÆðØ0Wapœþ’þþ÷¿?òÈ#°©¸¹òÊ+[´h!þ¢¸7½ ù€¯ùRÍ#›þùÏæ$¨*àÕ!ÛtfF)ŽÂe÷îÝÔð·¿ý-H Ã’Vi˜‹æ¡U!€búXñðÃׯ_ß4·ãÇîmÛ¶5‹O)ÐŒ·LWÔy^Ê›1b¯ö7 dåÊ•0+ìˆä5œ}Ð 'N4C 1Á‚É ‡•bL°þõë×oß¾½f͚܈´…°š¶öíÛ"M!ÌI4+çôãÝKçÊ#ŽSÞ™ÂQåô¢"&65*ƒµ€[¹råüùó5€‰.]º0ßRoÀ”È Ó.Eëw#µ¡.(Æ'…hµ=‹H˜¸aÆLÈL=M1€ ÷S'€ ]tÑ‚ ¨œG0¥/mžÅísæÌ¡©ˆ *¡åªanžÈpÁ cBºxˆf†ŒTapœÎ4p!<ÂÁaAsxiÙÕ Áɸà›±Û?å`6akæ…@\-Á§sÊà²U•(Êà«E $¹kšz«FðÊ•ƒ)©"Å1Ÿ`B¥þ`H k´yêÔ©(cõH½á‡óP·yófôíä‡é/çÇaìÏC*À²pžÃ7ïbv ×ý’wÞ@:3ÊkU.ò%€ÜP/7‚®¬[·µº…´­]»V-î°®.ý‹®¢æXôgŠf™Ö©#<šwÇaŸDž²uëV€¨]Å-Óz?õÁY[´gƒxêëÚFÈwêIQÅÚ(b—kË4|ð/;x·9^K±ÌÒÜïäŒ2šätmãv¨ˆS Ù V¬X¶[B\”ðrƦza©k/Ó€ ››3HwàJK"¹ÛŠÊÝÍjîun¤Ûp×9眃†Ö©.gРUNUõèß²e …bÉ1‡” ¬,Í—²6À^Á4Ÿ7Ú Aÿä­«8õÅp`%++ @Åï~Ù²e®ƒ'—4Yˆoðѵk×`‹õÈ‚ÅൠøÀ=W\«S t#æ‰àA ´çÓO?UËV«VÍMP(iªè!Ùçð+J¦aÆLøh=Ç*<…jÇŽË9¿´F”ç×ñ uúmJŒ: ǼÎ÷ߟOÔ8X¹r%¸tL‡¥\œã1Ú³gO—”U¨‹2r'àîÜzdÊãÖ=é™2h÷ÚµkŒŒ «â¡t8Ù°jÕ*À]½zuÐÆs´ÐÛ 3à0Ÿà;ˆlÆ&…|åS9·SÀ¦Îu«§«ÐNÃ_P Å~“q…ÁñúõëÝ íÖ7Þ½Ò"d~–H®–ñîµvEwù&ñê$Œoýár æNæà8&°@pRàFò¶*¦Ò?}Cyà …!Ñœœ©—\Òs=v§ˆ\ÕѾ}{Ú\¥Jî¥B5:¿¤ºáz ÝïÔÉB GhnÔ9)To•>ÃãÓQ[ÀqEܬý‹×ÌpÜ8]iûÀƒ$]ê‘°8ÝÉRüÉ]Èk0=hÐ Æ Ô´màѺ+u%/L=õÆØ­v7]C‘âïø¯_— Rn“YeáŸÀ†ƒ>—.] ª€ ãFÈ2¬\p£ý˜+.ŽÀ£”ܲe‹ñŒÁ™F·XÃÁnÓׄB"7¦ã5mÚÖ§3 l³ýÄ]}v õ1‰{ |Èsù95¢ch§Ó³¾œ¼­Ï>ÿûºMÛ3ëÕøÏS¿c÷0p¬N@›âeS+3=‚Õ“ˆ÷”ŒÝ†öd|"ô¨=L¼Ü˜$ßkp–†¥<…¦1Îuµ$W€}íA02]g#CR wùÔM4‘ÜýX©Ÿ§Ó%¨ýÀ9'`ßæ\¤«Pžö0pŽØàϲ›|îƒUë¶SzÂÐûÂÅëûý~÷Þý\œòÖGü¶Þ=ûµa“n¿¾Ç7]TR™…K×]{Ûso¿ñ¿ÚµÎŠqüåኆû‹\:Võò'˜à+”¥c±û/Ç¥déÙ5d 3Ž£DuV0úhЦYCc$„Æ*IpãªFk`bøžÐ78oß¾=臀Á>ˆÛý\ós!ZFZ´lÙòÖ0'Ikg”@;q-Üt¿Cns*éxýOn¿æ|Ï÷ì;ðÕßÖç5áu=¯ILÀ‡‡cÝ2„Lw.¿ür£û¸ ëÆ.¸ãC…K/½Ôu kD'¨U›ép\*¦a;~uN"<ÈÕ]õÝ€ÍE”ŒÞ?ºeee™¿ŒþÖ¹sg°ënˇçêš­'-§Wôïß?»¨ìǘ)9âøgÞOùj×Þýýž|g×Þ¿8ÖýÏ‹[ßsóüªÿ3#f-XûÊÓ7ßùÐà/’‡i# BâõᓎwìúôÂ+û")Ü3ë×þj¿Jÿyòu·ÿН®¹í9kÎ_1Œ?·mßÛáŸYòª^]^zî®/kò§GŸúÃÞüŸ4â¹A#:¶Ë7ò—\ÿé}/¾óÞT7ëÌ™úßç6©W±qì”Ë}ó%íóñظq#˜vÛRéï;lܵk@1jw`•(.G€Z4šwO¯›î˜¦ÉEGÇx7¬ÏEWp\ð£¯Úô%JÙwX–cÀ=—ýâåqo™]¯«ò¶U=³ÒA]Qtp¾{ß¿þü`ü¢œÕ[†¼pûÁiÆ_îQ¸ëá?„o»]ùÄâIÏ©ÃgÞ†íWÝòl(“·aÛ°w§ÝsÛeé-9ðÙß:ö¸/¹buò}ÿÃO&~¼hݲaɯþzpÖ~N¯Dò??wÁj>O¯q‰ªS‡¦³ç­ìÔý®Âõ0Ç©À8îc+_&XÔ¶ oZÔN‚°æ9ÑìÄ.à)zHÁ‰YvOpªJ]ßOäº^rÔ¶¦RÆ€°aöýQ!¦·5k]qQÝ)&å­-¬ÔŽ;´<ÈaoYðù_:7ÿnà }nÿmø¶YãZÓÞíþ<ÿʧ6nÙ½ý¹G®íÒþàþÅ'_ù§— Œ¯éÓ9ZàùߎâsÁ¤_IÕ€5o}!'o½þúøß?ôqÓ?á3wá`Øš“¶]ï*ܶgÿ¿žVé p}óªw<?iŸçuh:~Ô—¤Rµ‹zö~`ÞôßU`ûqØ‚ï6¡¨«»šXGJT¬¾ÂÎöÒ{‚Ó8ІÚþË_þ¢=+I†’¸ ¥çð´8AºØùUŸ÷1C5Œ¨Ð«Ø¥DZX|Ý•¸8pàÀYfΜ9ÔÃoñ‰.RÚŽls¿[{$ÕŲSNþΩ'§†&5aq·«Ùµï3\õtú½‚˜ãñÿºŠÏ™órS dÖ?›Ïö=ððÀá‹–­‹m[e–ÒAÌñÒ³wòùû?Ž_ìoƒÇ$æù«N«~ñiÕ{V:ëà„rUîæŠ½’(ÊÖ–ëÚFŽùôÓO3 :th°§'.à–?þ8Jäü ÎÜ]zÀ¿×_ýÞ{ïíÝ»·ÎIƒÞ¹s§¨åO5kˆÚíwÝu×äÉ“GŒAŸyá…dn¼ô¯<¡ÜÖcÆŒá2¥{þùçW¯^½cÇz£^öþê0¼Á’Ç…{2ìÅ[S¾úIÿ¡¯Ÿ&1ßtUç#xsÞÛ'ã¬3ö“ n¼kPVû;Ö&ùø"˜ÏÕkò‹ýVi‘ÚŠ˜»ã8ÄZåJ·|Br}ûömܸñ€úõëg’„hNš€HXmÕªU(WàSnß¾}ñâÅÅ©^ èåi7ýïÛ·ïî»ï¦ð7ÞxõÕWßrË-‰¤Ë¨ jø?ÉCDª€™AÒ©î»ï¾Ý»wÓUzè!júú›O šëܵlÙ2P>kÖ,AÌÌuÊ”)LI…¬Â)}„)ûÿ—y^Ó¬³ÓÉxÓÖ=|Nï¡—ž¸î¦¾]J©açî?ó™Qíôô¯&|2wÎ+kæ½ÚëâöüÙ뺧ÊÒ¤ISóÙ¤qb¿=¯ýÁIäÊ…CöçÄ»&Ø=iû†ÑÇ!7ŸK–,¼ï>úèÑGÇ÷ß?˜+jL  Ÿk§M›V»víÍ›7Ïž=;33sÏž=[¶lY´hQaaaôC&AØ/~ñ‹3Î8cÆŒíÚµƒb'L˜S[~~þŠ+@9$­f 2: Ÿ .üá@¹H3¨“gq/-TškQ¦m\ädÍš5<ÖçzÕªU©°  €ÂP>²$%6óá.æõêÑòWõ-½ÌòÜ­ÅÀwÏŸ=¹â¦çùü¯Ÿ^žRàÜ.÷>÷ò(Ͼ?õCÞžÎkdtKùá,ÿ¼å΃Ÿß[|«^tÿÁÊÛÝ‚€öÊ/õú¸Â¯ç9mrbÄ‹¯[·.´ MÖªU+Q´pÍ$Ï„Ïr0Ð_»víé§Ÿæ²'MšÛ28ûÇ?þ±>“”w¿#>åF#„ãhƒK/½QžîÙ³'_U®\´ý=yÐÚ¶m«çƒhã–¬¬¬M›6“"y¡Š4׬Y“~¨ešGÔ¯_?‘Œd|éÆzÛ¿ÿÙgŸMk}Ö1Z‚nÖ¨æŠ5èã’2 õùñ ÉAðàW—^تؼ·FÎþþŒ/ŠR­ykŸí’*yêÌœºÍoÒî6oÊKµ²¯í÷Èk÷?ôª%ûö¹ ¤†ÕªYíâ´g¶W+ó*í=‰/çulZáqlJWÓA ˜hÑ¢ÅðáÃ/¹äÈd4jÔˆ¯Rìbàë)®J€~È¢(†Ð {ݸ¢³´°ÏOXëüÀWô÷„ºnçö*Y–ʹâÆGµçœsä 4éiÜ¢=[Ëšá,²³³?ùäÈ\pë­·R¾F! l“ ÷ÚëÂçf~ýúÞù¡ž¿øØ5“?YõÁøELûßuÙì…yšÛÂñßÏüøÝ±sϪRùG½Î«^$*2ëeÜ~Ã2ët(]9ëåé³Woÿl„ò/Üø/è²!<6xÛö}íZ9ó+È}û‰_Ÿ·0—ÙÞ gï¬Y£Š×{^Ø6½½=ddÜÀë…»øöÙ§î(ÿöãCï—{é@*@€*}k:uê1tÆnp|jòÐpñî»ïvïÞ ›2³¨^½zK†ï3ϽK—.ãÆãY¦OµH^¾¥NÓ:Ñ%øÔ÷Úk¯ïn¸aôèÑ>ø`4÷ž¹BرcG€ÎO.%‰S±SÕ#8î~dè²Uùó>úE¼Jw4ù8ìÆÓ`¬_aG#QæOú}²C?þ¸3N S†ö 7Œð¢Å7‘ • :é?ݺu;¸"õÓŸ&’;Oµ¢4iÒ„»ãÕÆCÜÎT•‹T‹7X¦Zµjf­L×Ç‡æ†Ø®\Íó¤jXÓy/ž—­ós¬?þ˜Ù^‡zôèaiUƒ¢ZõF਷§F´*Uª¸³ÚÍÒÚM9Š´…5ñBð ïÃ?d ‡t¯»î:#µ©¿Û´i¦ ALÈ€ÎÑÍ þ7¿ù¢ˆîáînn !ysÍÜÜ\Š‚ç®—^z‰Â¾ªw²º%¬b–”`!e@ûê!³ž}øG¯<}s Í£ÆÇ¾¹`vEPnݺõw¿ûÐüõ¯ýÇ?þÑ €Á‰Þu`HÚ­xú‘V­Z/”h^^ž.—ü‰Š ™b—n£ÑÚM£ €ÈŸh’‡~Øý¡ºpÀè®Å¡Ï©S§R9 @"¿ùæ›Ï>û,mЉ‚îG…tšý† Rù Aƒú÷¸‘f ëÝÞö2•BºéľânêSOù–MëÄÐüªú8EÞ1éáÝóvÝ}äà>~üx óꫯ‚‰1cÆÀ^”Acx£>ò½ˆ l«‚(cTµá ˜ð9—rÍŒ»Pæ$¥¶·ß~Û­%€é•W^Q@ÊÃ^q‹Î@:Í]sÍ5H¦žÈq°ÈSLµsçNÃ}»qLÇVïMæ—À÷©§žâ‡Øo5K3Õéùå—_.V§ì ‰^¡*®0%8F¯ÁÄYìA³ÝòåÍ›7?Z5—±¶hÊ©®HY]3~YîÂRmŸ>}.½ôR}ÔúRë¯& —Ù¸|Ÿòè£rþc²óióZ½zµq*ıtÙ²;vðç#<“'O¦'üö·¿¥ Jk1ÈVÞ(\ñ¦¶Ÿüä'ï¼óeÎ?ÿü9sæPŒ[Ð*t0ˆ\šÁD‡;sæqiÄoa( ' —¶mÛF÷«_¿>1¦ÑaÿO¿õ­-ÉÃÿäO<¡¬:ŠGäáù}÷ÝWR±²?šbæ„¶,åÿ˜<Ê»>ŽŠ<Õ§~Œ†ª`K+Èxæ™g6nÜhŠÉ\]㫆Ƀ9äzë­·Ö«WoøðánÜ ˜Î!¶6OlÑ¢õÌ›7÷íÛ—y£?è·#>‚322àr¹“‹ŽÍš5ƒŒçÎ "o¸áŠ™5Ò¥¹9O p.vn0ÍïºãŽ;Þxã Êð3ùܼys)º«¤)Ýý÷ß¼†J³Ÿ|òÉ®]»rñ¦›n2²‘ãO~‚K˜FœÃýÖì-ü™R?\ã„»øÂ:<ÅGƒQF+äz´ÂÊɃz(Faù˜O`1>­“Æ”Ââþ ¢—’‡¹%|ek!ûp~<ôq"]×¥÷¨*„Ñv_´q5{öìé 56ëZ¤‡ìhä{î¹e¶w÷Ýwƒc¾â}À¾Õ«WWatðñ’V¬X.¯¾új˜²qãÆ(ò¦M›¢Å³í$ϰ‚®ÔðÉu®¸Ÿ B}ì±ÇFMYYYt'’RÀï¢Á‰¢ð‡n¤å§¡&NœHÍh ïàÿñ_Sþ4íç?þ8(á(ð‚ah¾åóvÏITÎg¨(ß|óÍü ò·ÐþFÜxPR€šÁ„ã;õ¨)Ã×§ð•–n­ćNu”1cF`nÊP9_Ñj¦nŠ•ÄÁÔª -ᢽ4ú¯õXDc:´Ý àãñ`èJj™¬*]„¯Æãàl©ÃÍEN¹åª«®âõÀ—À·K—.ÔoòÝ}¼‘z²³³ÿòýïàÀK—.íׯ߈#Ô ÎðôÊG:ÓêQi€f¿2—ã[o½uã7B6ô®h×CQðæ\®;÷Üs¹wáÂ…†Þâ[~åGQŒþÀ£‰`••¯÷çŸÍ“G`,Wn ãb”ÔéóÂÂ[ø·û-׎Ç&hKüŠŸ ©9py(à9ÏryˆÞžòC¢ò°ú'åmI)Lêþ ë7…@ŠR5m××`w3!®ÉŽIy43¾ƒ]])É”aüÓ‹½—c…em—x%Y(ÂÓ^¦ÿq$.;PÙ+o1܃-jͼ=3ahúƒ›ºíÎËø¯ÁLÔóóŸÿÜ÷@sÑ¢EèJz;Åø ²G½tîܹwïÞ?úѸ’——§ ×w9Ýu3%§ØM$3èø¯‹Nƒ´£-,{ÅW„ëp (t”ôéí´Ÿ¯ ”_ñô€kßp†Ê'Åè±|ÅÔ%ª› 8í’ª‘CJ1xÃ÷VKƒË8ƒtašËȪ¤ðmÉ1ç㨱Â@¶xñb^³›ØLeg` cª¢‡ƒ;(ç.÷q…ë®5P‰ÑçÝÈiZsí\†>I…òÖ5"¸½‡iÊ ¶nÝ:xð`&s#GޤUT¥·»Q&–-[fjc¾P¹›dõ¢†àQêB³nݺZèÌyJyz š¯ÐÖç[.ê Z쾦hx¡èÿ ØÙxp&x£¨2Çz»VàfµÃ>ïž?ù¤$ç-Ð[7T¨–²XSÝïg?ûé$¡I<ˆNÅÈcùœœ¿¢ _™…ʹNŸAÉ„ƒ?é65]{<™<8¡~¸–[ 5Y<<”“ãgwFÑ‹«W¯LwZ¶l JÆç†Ó3Ï<“™>pAðŸumO6Œ;ÿpfÔa°ÕªU+€…œpdç‰l„8dÆ'ÐÃ-Ê¡@=Ô¬'†pçÑ.€óŸâõó¸ 6pnÚjÍŒÀš†™ú‰ú‘ k*á¿Éûã?>}út*§0â{ÕªUüðÂÂBžÕ£Gƒ¾ôiÓ¦Ñá6ôª©V­Z.‹Dw–´Drd!Z¬Ó) ü] ~Bèo_Ã:H ˆ•’@!33Ómîé0ÃܬY³ŒLA@nn.Ü#m»þ'sƒ*´õÎ;¹#¾ÍL°£™C5;Pr…’†P€Ýb¤yD#±-¤dÍš5)fèD=.¸Ñ>ÊØB×2ÜÑMŸA[¤Â2…TK¢íÚµ3ð ê­‰:XSX¥ìàJ¤E>G úØMÉ£$¬Åñq¢,ñ„tQj°š®¥nhÌtsÏ&ß®]»–i“›R•Ú’A°‘è¾A 75 ëáØÍ·†Öt=þ¦ÿ a¹Å$7аºjذ¡7¹‹Ú4hÀ W²²²¨Š˜6 îyŠÑ ·mÛÆs÷ìÙlR¾X7Ú ¤°Ž1L T]ìf”+QLûï*}[nIã@¹²Ë1ŽËѺ´uíÀÜbT³€` ãÝó€̧Ÿ§;>¨¸€6îâÐÀ7ÐäìÙ³²u¦Ó¨§¢|€l.Ö«WOÙ`GâŠ*Qò:¿ä@Ïnw†Ê½h®s‚N5„3Ÿ!cý aÄN'0½½(sŽn »µ%)LÏÓ¶ÅnCåÇÆ¨ü[òpÝÁoöâÝKÆú-(…Ý-G—‡1î½ Üh_£BDóüùó;vìèëyǵ 9q¤·@¨šÆ4ePI÷îÝižÊF-â¡Ìáh 5Þ¡® q£½¸XM= œÆ/]º”{i¾Qí`—Î&²CL‚¨…ØÖ¥q0YëÁ_'ŽS<]xÓð®þ ¾*å)Ã= &5¨…=ÆF] éÎû‡xônò£6àÎ'”É” ÂÜ",¬3ƒEîU;vìĺ_ƒÛfÕªUA!PfVn4 ŽÕÄàrëÖ­´“G»ÚÒÕ,[¶L'c~ 8PKK8§$­âÄ»c ʼn"j£sâð &—Áå‚£¯Œ®€ØÂž%õlˆ¸¦\µ¯óBGs#M™dI"a ÃX>¦ƒˆ¼uã²¹è¶{,áã©S§ÊÓZ Q䮘PŒzBaô3HÊ}Ý•˜t‚fÚ¹k×.õ48¦=¦áA`P³ùxÌ•¢€ºˆ®Ð,hËi®˜Ú•EvŠì¿ÈÌ1”Ë‘®àÅ@~³fÍjÙ²¥VÕ…)÷€¸ÓΨ„¼xpž|Óaö† O$ܸaüŠ0.«¹©Ç@šFìä@p»âm` SPC4§x:àŠE¨P‚gîoL·ŒŒ :Õ¢¤m#¹ñ“O>AÞ µQÉ<‹ù"½…z rÊÿбâNjÍ(G˜ýšqœ"ìtT3fÌe—]fS£[\ô(çM\°’••åÖ:Õ­‰]¥D`ÜÒð<Æ aŠÂ–>ÍÎØtžÁFÔ4D1nvT>Ãn·hÑ"ðm† ÓžŽ/rÝ…q³sçNÎ÷îÝkX:*q?hæOîâ'nÃlº‚Öó‚­#À:Ý”gs*/ú8ú>/^¬µÕ!^ˆ vÍà 8vïÞ-Gjp Ý\?S30q²~ýzãQ [¸ Rê ÓD‘>À@ï’!ß©ڤ;wîìãtAfr¶råJS«ëÎAySýQX@ó©ÎqòdÝg%ƒ\”ë†Ä?~<Õ­àÑønîwÒ®•È)ö¸˜‰Ë…®¤âo…‘uÁÛÕ© <™] N\ IpIÏfÇÑf'ÊhS!˜Q†[ŒÝ¦ÑÍxº†šs—!ZnÔ®çº ‡õ»L¨3†Yý(ωŸÚI¨ÐàWzú›Ú‚…$lôçvmÉ´M‹µ´É„Ô«ÑðŠǪ‹ÇåBWñǀ˭s ƒ,Üf20m°gú¼`¾‚³{÷î 1oòtI—Ƀõ¦M› p šUÙ(Š_è|N_ƒÑë§¡™ÚTφ§0°ÖŽay@ÌÅQ£FuèЕÌC]àP\{íµÁóÉìLnÛ¶mûöíß|óMúÛêÕ«iUÇŽ³³³é“”)L¥dK¡Þ8¯^yÔ‰¢ô3:ш7º0q2Ž»ÌûÑG’.]º)¨ë½÷Þ«]»6H‚ÛÀ ;묳 H Ìà?wŒB±AÛs‚;Ž{Ox S.•G3âÛ%Ü4ê”ÎÜxTîŠäM«(|jé-Zýx¢Êgݺuݺu[¸p!}ƒ¤‚/TÍoÄtŒ¥K—Ž=š[”!Ï_:^S”qŠSo|”¯u@ÉkvPi~~>4 tÇ‹/¾ÈkMš4s‚ÁÝY—iwQÕ G `¤nÃöPFs2pÉË˃¤C´í @ÃV~wRbAédËô© \³AŒ‚F2bh{V¼:ï4º&¥ðš5ktòd0aá¹ØÁͯJ04h¦…ü3°;\Dœ.‹Ã,D3Šãv”)¾oZ×r“qÀyfëp³§žeèHSP’‰?àvè×òà–8eƒÁ¹˜™™Y§NœœœàW¤Y^7Ã$x5õ¹vY†Füµk×Bí*æeË–Ñx4 >I´U±„„h<'nÞ¼Y×~‚†d-'ü隇êjg"áh€@½Ñèagu âòÈÇ™ƒ²Ú¤¢‘F¼äº‰z™q‚ž®W¯^HºÁõ+®¸bÚ´i”òFÛv‹Ñžä1nܸË/¿œb€ÒÉY"™Ž—&LhÚ´)CAAÃ*C÷îÝuº§Nš„¡­¿C‡ECÏš5 ,Ò¤ÆÓ¯àlE×®]éš´$vEºÐªU«tˆ30màŠsAÏ º´aßðŸu±HÅ\Œ¡|œC‹9£VŽ9¦ÔdÆdù"¹ÎŒ :D6èwaZiw¹X°W¯^S¦Lá„I˜q8¹ˆbÊhÄ òF™™Ü ªáx³8¢e­ÊõMÈ`1‚%èTt§}ûöõèуñ "Bšá¨äÃ?„ª( &†Ú°ar5ÛL%Žg(L#© YÕ1yp¢Ú‰ÚsRÖ;šHIÑ-âãkãcp w¶nÝzüøñœÃjŒìP”øsqAËoš×Ï\ 2¼{ÁE@6xð`ª‚Y™„¹aàµ>à ©Íàn( êÑŸÎ…7XV…@õH‚È6wî\:¸§Iºùs;­¦TE1Šq<þ|Ôõ÷̺6©×‡zÆÅ ð8„½ˆ±(ꇙÒ<Åî–œ<>Žõñ?›;’U tzd”XÞ®]³9ñ¾ùŠOÊïJ`ëK©»:ø@Κ~¸p#×K³fÍÀ¥ÂõDQfHpFg0ª^Î!5è¾àÐë*m0°xÉ%—û…ÃT’¹LL#Û´iCUHó‰¸jhš3¬MÚÞÅ€À—†ñ©¦JD\ÛR6™ÛsŠ#FsyáãDrsPcÐWQ˜g 2pKi.+,^¼¸S§N@= ¾!Qô(`ÜŒøR;£üIÍ ÅL Ìêt‡pq„’t d²3GåÊ *§¼ÓAhÛØ„´S‹¨Äà›¦b: 3|²V ­jbó\‹u Å>$Rc—G¾1œ”Þîú¯…¼¼  £;„½rQ_¸æ¨ú‹\Ôg’[Œð•‚T£Ë©7Ö¬Y: ³á`mÔ•"ä¦væFcp»ÁÛ7oŽPf¸°°œ‰¢m‚‰´¸ƒ)¸ŒF]‰~•¹0>Ê‘®Hy7ºû¸/ݸa´µÕ«WC‡³‰mŒ`Ö0 Yrídµ3téÒ…áÞeg Æ9âTY"ÍA9Üï.’ŒŒ jx÷ÝwÁ=*–ÐÐt“'èŽ]÷Vj›lÜYYY017ºs6Éå“âJ%à¨u¢¤™\ŒÝò…ã2ZòÓ_¬]»6oÊܲe |iÚ2îÝG¤¢ŒÑ¾ŸšrÁs5#ñšñŠž¦K 7Œã†Ò0pÀ…bµFW­éKü°þÝäaÇãqtš ƒfE)¿1ºƒ+Q\xš¸XW”Ex„ìwÐ0,èÖ7¬8)„S](Q9´nÝÚ€kP¯·™Báúl€9j@8Å”GÕë(is‚hë5êœf`“HƈHþ64rúŠO@m:vcG¶oŽ›LU”A›–æDÒíÝÀYºïMØ4??˜“XC˜¹ÉÜÍâ™Ì¹Œ·víZeÐ4kWÀeÆ é `:ÄÑrñO>v´q[JÉíFz0š¾'”>.ãáÒ´6WÖœêÔæ¤ÐÚ—/_sk’ãÊöíÛIï"oäSâ¶mþ47:X§Xnn.D‹ðEˆÃå®+ ‚#h”z³¦«áDÚFèÄßh>.v Ø¹<#Jš‰hvŽh¶2]ÿŠ7Éí'®¼ÀÐÜî´/;;»yóæõë×G3¤†Râ¡ö-¶ý±8¡øø–¦ŠÅM±•(—kÔ¨¡aaÆ Ú4ÐÖ \HZìr¢m8ì):-yâ @Æ01j8]õ–ôtÃ3G­.)Ø|âóqÔ ñÕ×`W´wï^…‹ @Ö%CUµSXÂРUÌêj&ø›¯Š¾Å6/€|SX9^Xþ¦èŠ£û¦5¨ðʨÃàØôMˆ ÷?#!Ón\5z,*Âh³n-½é Nÿí1v¿Ñ8>Z˜Ö{!˜;@³YJ]ŽÖ‹C>6®€µ²?:ÚÎ׈b+‰Yù=ÏKü»-öp¡šôÿŠŽˆ2DŽ;ÜÚŽã›'Ž¿ŠD9¦88v•‡šã}MÇÿøÖqÀhYìe©Åæs.åYÎŽR~±†¼ø¨ð8ÖgòhŽ %ƒ¾XŒ¦ç§9úƒZ²~WyâàßP]qÔíÇS¡¦ì ‰ñtÂòqâß#«’_¿.msÄL÷üâøè¾ø”¤ÇaˆOxŒ~]ìƒQ®q|ìÞJ)5rÆv´tĿ#ÆÍ7QWòkiãxêøôtc1†bt7y]là•¨[RÌÓ1ŽSÀs¥€ãèêCVRÒÖ¦ã٣⣂á¸,kÚ%E¦*©K1µ¡">b;–Ž›hö¤áWX] ‹8)[¦ã£¼ÿ_€öÞή¢Ü×Þ÷~Ü£€ !$t:ó<“€ ‚ ¨ýð(¨€pdÐ{'T>TTŽˆ (rGf „„’@æN§ÓIºCf ÊñÞë÷d?ö{нwwºC& Š°k¯]«¦Õõ¯½õ»êÝTT’܉çÙXãu"˜FŠœrÚˆÜ.g,~¥]m{zË/4§œv "·´-ÚuJ“y>¿ö7¥¥VTFJ2ÇÙfê)ll² ÿœrÚMR‹ •e¾¼Þrß%8Â¥–†·$|D»Œ!vÿIN9eDΦõ{^ÎÐ’ãƒ×ާ%{ùížß·åï$ÿ‘ä”9Ÿº¾¹ {ÇÀ·}UXsÊi‡Ò>yvѶ+uÝ 1·-:O%¼SxtN9å”yWE¬D­Ÿûi$ßBr¶Ç]µ”ø)‘iD×ZQOlåÄ/SãœrÊR‹=ÂãæÍ›çÌ™3mÚ´^xA?\dÿOsêСØ1c† ²ß~ûîÁ´"Wꊴ\m<ãlN9eDÞ{EuuuüãÁ©OÍç?ýÓ?í»ï¾…0¾Éßþö·¿þõ¯Ë—/ïÓ§Ð .¿µ˜"„ÔAºxÝ‘sÊé,µxý mùŠ+ Ëzˈd¹Ðy¾¸ì¯Æ¹œ9sfÇŽ=ôP>Áq°»]®õwbû+ZN¾µî‡¾sÊéu†È%!É_/sjÁb@6Ü¿ñ5"Q ÇFÃô¦~’_|ñÅ%K–tíÚµ{÷îÜ1f¥rŒ=5ømÔ nË«iI¸‘÷rÊéõÈ%ôêuÁ­@Øpñ¶~ýzñtŸ}ö17aÄ…¢£  øî¿ÿþ|þõ¯]·nÀÝÈ­{DXTr”WñÎ+Z™;ç”Óë‘Ëuö¶I[‚\’b yõêÕÛnŸ}Y•+¸A›™ CÄ«}ó¸’eÃf—åÙY-l.ïøV\«Z2¡NýòeDÎ)§½#ïôÐ7^oݺuóæÍ`ׯCõä-ÍÙu´ÔæØ;€éOúS™Ÿ”NlÚ´é­o}ë¾ûîKùߪªª5kÖP;8E¸ÏS7nŽ?~èСØÐH+´AÙ]¸p!hKÉ  qÛßò–·(»aEJ¥EU¨Êã ,¾kjjzöìÙ¥K—:Е.*ÖKzä‘G{ì±8¬'3•ò©xä•W^ùÏÿüO>5?a„C9ijD{WSpWÕ6þ!UbdtÎ)§=Ï‘wV˜î»ï¾—^z©W¯^ÀÖ~ûí·o1qó«r[pyÆŒ`% Ì p_…JgS /¼ðB·nÝ@d€Ü‹ý•ëô°ÎØï\P8%Ð µººš¯4€e#rRZùŸ•R•R—J~R/m¦S֮ΈÏjAåŽ;R—{‚€{%³»'RWêf³|UxŽ5rÊ)#r»E;\‚ò„¶Û(“è€Dœ°×(”9—çÎ ºUUUuíÚµS§Nx _ÅÄ–ÚÏ} 3$iŠ;%¡0Ó3;BÃ<å‘%óÉÚЊ&œú›“#ÃM—™}/^ @ú=zôP\ôßrÒqh‰–P¾v¬lÉ«rKÝŠ0:§œ2"ïrDÞ¸q#ÀÄ'Ûùý‹ ~ÇFž‹BrX´]r‚$úœ:ÂÂ|~û@«+V‡G¸£”Yš\ŽDèòky±˜(‡Æ[zßU! $•ê‡ýíokll[÷)¦°ñ+ÉO 7mÚDƒí‹ºtbzŒOØ¡lÙ²…RÈÅ$ý ¯(Oð&oáÖ[o]¶l™B5óhˆÏõÑG}ÔQG±b…§-x]‘—ˆ•KVÍŠärÊ)#òkJAÊZ™WþóŸï¸ãŽƒšÓ[Š ˆP  6€Gyäÿ(&1«\$Z+<~>"ÞÂ\»Á‡árM6Ê¡º_|Ûºu«ÆuÛ €FŸõcݺuÀ“(©HŸ>}¨‚f÷íÛ—é…÷ùìØ±ãK/½$œÉúI”Ã"DX~hCEM8sN›6mýúõ´–ò)‡.€’t³W¯^ ¦Ãh›:Ekà ¼Ð¬¦Ö†|e”`ôÊOÜ…¤g¡­ÿ ”Ä ßr­«[´Í™#ç”y§%\Ìmg8Rh>“9²ñ_½z5()ÌÁÈTù*Q“ÁAÉÀO"”p_hÖ.ˆ#µ íÎg „~ªö¬“r„ÚrPæ¢{÷î>ú(`jiZ„Ϊ¿AÉ .Œó1ûE—ɬîL€K…Ñå§‚*Õ…7¢ôOõ£ ¯6]ášqS]ºÐ¬ð@½. )35ÿÌ™3ÉO«x ;ãIN–@®ùUÁõ²nÑ…Í›7³z)iï’œÚÍ—;™+¼6ó–œrʈ¼#{UÒ 7ܱ…”A͘ހ (^»v-`'ˆ0ÿ-ªÀ 7ॢbÒ”xÆ›JŠÓy®µ\8΃ðô3Ï4R§¾Ž‡zˆÆë#T‘…ïÂëZpAãäÉ“)9Uvn (§ [áÕÎçbÉr‰œrÚMˆœÊa!\!ÖŒ-‰¢›ÒR¦=Ü Bºaà ðn”"?˜ ‘ÁB¿”êz¡åžºžtñàÉõô øà¸n÷ „{z@GRÃAŸÈ|Ò5S(ª¬ÉCŠ":¹†eϘ1º †jøg›S™,CÄ}ˆ6yÂ*DÖ .Ó)vX‘@Ã=šS[nÍš5å4JÔÑÜ1¤’îÔ¡¾Ùâ4*¢× r˜;õn;z†Ju&Â9å´k9=Ö/ ?!cÖà¡¡«L¶œÿˆÔ $0PC°H¥ °ãBñ(ìù矅b«V! ’Hž-[¶¸Ú’^}èß FÐþÛo¿" $â…f› 8)ÀGQên"Ê×Í L½ $ƒ-Ú ­úHc©xúé§Óa ܤGÇ_ºtéòåËÝ ¯ªªîYÆJ@¶ÄßEØv+¾°yŒ˜æ…ʈÜÄxòINJVŸÄuÂWÓ®­RÊŽÛ>*§œ2"·5¥,¯"Ö0™ÇPá{õêÅ6¼Gܲa…L{0¼ ð§ÐY’°xàY {Ö¬Y*·ñ+E|TÑ­[7 B ^³éVåvI°H«ê\Pì@|W‚ò®ÍŸ?ÿñÇ÷D À¢yacæ¢Bi¥v}…fu–“Ð ÷@v\ÓjZÁDšC”?ï¼ó¦L™¢Ï ~¢yž…8ŸvÚi€5Õ)ñ&EÕÖÖ’sòäÉà졇š2ߤ§½c@ ÔqÃÍ Ø¿“›Ç_(¦††ò° …ˆ_‰M{´¢?åe+˜SN‘K£HTÄe` T­©©Q»V£çþýûó“ûîTpÁ„‡ö‚D€)×!MNX ˆ”°lÙ2ðœ-ýH—d¾»ÝÖ{÷î ˆÃ.)jÒ¤IJÂ¥<Ò•þùÏfU³@.š$x…# EêX([PDÈãÂ;òe%'j¤½RL+W®¤k*{¶ò\Õy–ÆS¾vÕªUøÃ”‰³0ˆìt‡by\‰ª[x”„4UÅá…k‡ ò3> ݼyóÜŽè6ÆËý•_§vê;প<|Iº¹É)§ŒÈí›BmÜf–<°Nœ8QYz ªÝ»wW +”½À#-#”K´T…;h²•¢j¸×5€ †•@A‡¦"` ØJÛÆŒùUh ÜÄ![X0O:Õüîë¹ÏƒÑr óâ4R$Õg¡Y¯@‘ÅKw¤óJYKÈ ¥ídU"æ>ù¤Ñ15ß±?¸PO,ÑçÛ®`N9eDÞ¾\Q,ûŽw¼dijjb'Î܆î‘ó°Ã¦M›Ö¯_?¦=8œ 8´tîܹõõõlÀSçé¤UÞúðÃ\*]h-­4x¤Ÿx…%°Hf §ºº‚™ÒI¥ÃÓ§Oç¾ú¹b.°¥ÔµÐìÁÇ•@]]nÖ›6mÒÎ+{-‰Q-ôhÔ'ªò”?­X±B?FàÁTÚi>‘m˜]¦^†Å¶92¢›¬|ðàÁ¢|¼Žr‹DOåûô‹_)З¢™†©½yófŠuqÑ¢EädÙp…:ß.=â”P‡BzáÕ¶!Y”œSFä¶Ê%Z'Å­ü$‹q ù¢L8ÚwÜÁüç«¢Þ††)$Ûg`…›ê“…˜ú@ÈUWW§€‹ÙÔ|ò”ùj7hÏ⨔‹È‚u L–‡pB$á ¶+ðšíŒA+…¹<ÅB>AR—‘7lçâèRÁ‚ã ¶Jré&h¨¨¯©Ÿ å¿d¨ªª:äCXEt-[[2ý’áBðµ>·×©šù©ˆU‡Õ‘Ά»ýÞ½{ÃÁ]„rÃ:Âl)(MO§Êí‚ÎV7CpN9µ‘KØM+rŒ4gšxâ‰'Ø:ãy*Õ³˜Â§°²Kþkjj`dt ‡%Á(=j&„Åðú‚ð¬Še"ZdI´”¥òÙà×`ÂepÊc4…a‡íÀ5FBø p[‹tXù8hCCuʡö䆂„]æ m¹†h«³X;nÞÓU‚v1”CÏO _¹r%}QNÍ@)Äð°ñÉ'Ÿœ4i’Èë Ц}€CŠÕÜP›FŒÁºU"nïÉ^ÉcN9åTŠ¢m9œÙ®WÌVÓøÖ[o…;ÿChL0ùո⤎“±À! mPf>ù:{öl>)“_ÇB³rXPQÐ4÷|,d»it;Ûàœ>á@v0Q[’º Ò0OAjxÏ1Åb«ö+²›ª`Û)bWÇÒeÀ¼ S HªgQuõ”ÃÐ$F@÷I"¯ êÐ;¶Íž R;lAh ÅÞsÏ=⾫KÔËëPÓYE‹T&îW®µ«$/Ž21MÏÛ+Vn=RjæË9eDnÇDjWˆâÚÚÚ)S¦8É Í!3¸Ð%…Z\AZÍ–{Bž»ï:¨n¡Ð`cxÜü4¤V{pªÓ)þ½™•›JcåÅ. :¯?®=⋼ôHÊÓHÁ+Š’žƒª€‹„Vã¡€l=lIÄ}]¸ÁUé:s¦dݺuäÔOitvV “ê®_¿ž%ÊØì¿…Û£œHŠÃ¡~*lq”ø¤ÞËùyƒ, Û^ äkyÀÃŒÈ9eDÞù‰-óÃ?üâ‹/г±ºYL`‘¢¦¦FEò„GöBâ´Aš%3( ¨IT+ûÕ£B¤%ó (cÕ]‘(¬{6Û( âµa Ù«y#½\JQµÀ­¤ÒBçÿnN©ÉœÊ ª÷ê4™Fd ZʲCkXm¹ 6,_¾\i‰²Ù«5꣙›`"HÊ…0j›Ã Úd!4õÂA jÊôm¤J hW,.ü5|=Öë£Y}8šÑ­[·ÐiÉcêv÷[™#ç”Ó.DdÕ`yÌ^µ‰¥¢IB•i*s€s+ €ó<¶‰€pÉF›O1WŽé³*¤&dqÜäÆŸrXwÙI¤PT7ÖœOµb©BO¡x¨ŒuíÚµ7næ\©%Ùx–2¹þk1…(#ôºBQDù² qT¨ƒ nê‡ÈBh¨Ý«W¯‹)uÕ¡¡¹ˆžºlÖ¬#õæ­ ¯Ï#FŒÚΨæìr¥'¿*t6IH-,GWWÄ¡”=u ¥ì¶H“·{8œ½[ä”yçÀñâÅ‹xàP,d”òYmçÜԻݳ2í!ÀE¼(4ûÛŒ0q"c>)S¸‰-vœ…¨ÄrìvêÔ N§x§.WÀh B§‚òéŽØg3ÔS¾a\jMõB”aõ›0ÂOœ1ʬ…6ãIs_?dc(øºråJ† 㱓0–•dœOúa>¸cX<‡t=[±b…ZÞžC†ÁKÄ*å>½fˆèhëDÞnЊþžº“v.®=-©¨*gvœSN;‘ƒÁM:U‡gÎpÝG„_Ikª«+ x²ÇSLì=z¨LÒ­~ׄŸU’ -Ÿ®/½.4G9 aˆå‡Y°Âh£F’5o GEa!½zõ꺺ºX¼T ¦ìÖi0Í3>HH«G?©ehk€q,<ÊÐC£nÉ’%j}höݧOZøØc-]ºÔVIHÃß¿_™xà#US8û >¨Î@v%?Ü?ôÐCAm ?¤®=ynºŒ‘ÁX$l_xD+v·…æEu?¨eÆ tGm2[WŒ{-Å9åôÆN;ͯSôÑG5‚F($„(V<y=þÒA³WÇ»NòåË—/\¸¤4h†mB^ꊌë-[¶îS¬¼RÇr@ƒ‘â‚ôÔJ3Ev=À¥cc†dXí ç%‰êÄîÝ»×ÔÔ(™¡Í¬={öä~CCêU«ôïÉg%ª´“üJ$x\=Ýe@]©t=õM.C<)A@Œ!UC9B™„kyÏëÜ‚R¯]»–Ö9…–«°¡ß 3{d§Ü#ÄëÖâ» %?éÛ·/#LƒY6xd m`qcc£cEùîÊÅÊÃ}e,Î)§È7n|àôNIŠã~f2@B)|tÎ mÃb¥l"f¡¨ë&=Õg– Þñ ,MgTMã«ZÊÂŽ40<Í™3'%k¡b¡ðÁ;¢¼>Ò´¼ Áঠ¶ $­¯¯×/‡Â~5º«"o†Â.ëÕêÊ}=s®Y³FãiAÜ“L:âàTWWÙ[ŠI”TçÄ…­Ð¬£¦R i@)- çA”!6ldœœ¾£*ÝvgÖ%6&„ìŽ9…ÐxõÁyõ,Ü„ÎGl•0åÔv1O¼œrÚUˆÌ[°`Æ]…¢yX¸ôÕžM±i ó‚üêÞ~xË& _-¹;$ÂÄEù¸ªµ€evîܹPTÏe²8óô$ •çê|]õ c’ÐФµaQºÍƒ`4¿ò IH½>ƒøI޼zõjí*gpPCápÉQmC^¬ÿ{ À…Ã{Š^À:û÷ï/à‚³ µ°&þp^Õ?øUû¨÷;NTŠ  ZËSTAËCÒMêó^¨Ú)ôwõR=C™5U÷ë×v’™Bxé…¢OTVp_£¾Ø…È»Kìô2ç”Ó®Bätމ5%’AAM÷ðNQ÷ ~ kn2½ Em9 m¥‡å{Û¥êÀ×¶òe]Ý.ÔB¥*#Ã.¹SVCYªçiŠwƒÊ¥ÑíLPW€¯8ˆP®wïÞìÒ¥ ]ã‚A%ª "QIÕ‘B³Éµ”VÚ(Ñ.•=¹èHŒSÏUŠÖêid¬\u4,Ô’Å‹›jDÐ}5(@OR/^¬:Cª»}<÷%* * ïÓ§9AdîôíÛ—BæÍ›GE µ{^G“Xçžzê)J`—!ÅÊŽTvÖcßAŤ!¸2ôÖ¥íUrÏ)§ŒÈ•SŠ’Ìgii×NŽÉädn‡ÍwÀ° À IÅ[  @jq6Ì.Bp!Æ >\è!§¾ƒù ðÉWª£1„ÒL®õ\Au€ˆÎì©WÕ eÄ Òè|~‚;Æ- ½Nœ8±PT(Õïà¤"©Œh ó<£™ðHSS“b–h/Í k €È‚škᢛ^Å$?óÌ3pRŠª©©#ÓMV pPÅd†”òõ‰!3U³¢P4´#'X©°ž¢ßkLH6q [»v­ÂåB1æ JÞ]]tÎçЭ*&7L*ÅÂLÃtâbY¯¶âŸPN9å´3¥©îTÈU%bªÁ…£z¶½ƒf2Ãàüq~2d_ÁVP€í?×ú–ŒHÂe%~úôéÚž…7 ¨1¼•ÂU˜sS€Å JT4¦à¾{ùÐ-+ñ0¡¶†ÎÒdY°² ê¥Á žâš††çŠÒª-k¼:®.†åVÚKcèÐv a0ÐgŸ}´UüŠz@s¸Ur šáÙ© Ôj’ÀyyÅ€<ÔèÂÔR¸ÞJyî6¨Bv¤öè›üÄâÄMVAÊÑä’%Ð[3P©NéÒ€R­¯å9å”ÓÎGd‘Nfç^X¯@âŽrI&*ó°…‚¡8g2 ±P 1§<—l/‰s!ñC¯8X]]ÍS…W‹¦)\è/@(Hb®f‚p¦$º¾¾fJ-)£—Ô ô.JºEá0<‰à˯,à”^~轓 ¸qŠr„xË R8Ð`Ñ\h}!iè¨ûÐ5Åä¾A¯îôÀ 2*“€sS‡G$·*Hðɵ~–}kµµµuuu´¹GvKœ ÍF4” }Öå?à®ç~®ÁnúKE.Ú›¤ª‹sÊiÏpd·Ìi€áØæWUU…>¯¬S[¦4˜Èæ×xz*(h–-–×"¨ÅY_–ö'ÐÄ@÷ ‹ÂSpY; ¥úöÔãšÕ°ÇKõ: Í–ßÚOšéBáL ÕYÕ5êDÛÈæ9[ýžDD=Ú2\å!®ÅÜ´=„v}ríp·ç¢‘Rl yš'«¥mPcWMC2î˜p“‹£>šÌ>B9¡Q§P˜Dµ“²ãˆÀ]QÝmg¥oýäžéÏ4ËÝöÿMß?·êÐ+æ|hÊ‚k~ñàß 7çgwúI‡ï‘ÙuÃoúù-‰ >~âgŸ´cål~éå›o›d×Ïùè °_F®ŒÈ­ ”™Óš]+H6ù”úF:4É$nñºuë´éFž˜Ìa~gD–¬åˆ`ª½†dS¹p¡¨§œZ]4-÷(_«n¾Â:)A æ°°Hµh¹ÉÆüÄO ¶AìVúlÃèˆr ÏÍ<²îÃø%Œî¦M›f|¿BÑSË ‰§atªC‡ #DU-×ÔÎO‹iéÒ¥ŒóêÕ«5IÛL\meÅÄžæ¹H(®Q*цŒ‡gQ•ä๠lDE±‘a­%±ƒîfè %€õ<¨³Ž]Ǥ­/¿’~=ç‹¿®ÊÛàøÆÓ;[^þëë}–.ªkºîw;¦o?|à‘ceäʈ¼}¦'c +TîÖ­[8Æ åvÒ÷˜zá³Â31ÝM1º7 !€¢[l¥xAo0¯¢I„¹ —ob7è (Š*yTH†¯-N‰;öð–ڸÆ Kcú…a4iÀ€â£.AT±­ƒ­K–,ñ4’ÉÜÃC“ú|2åÇ{Œ_]q³òÙ šGÉ£FŠƒ>3V¦… R£9] tˆJ~ [X <d Q]SSC›) ˆ‘L•UvéßîÅ_ÿÝ-ל»ÿ~o‰;s5•ÀqëéÙ……Pémé°¡=Ûþìêµ/®^·qÖ܆Ç÷îZÕåy>õñù×z9/mùKí’•þÙ@~õ¯yí#§^°hyÓsë¹îÞ­ÓÐA=óËk/sX¿øé®f|í;·þ=ùùG#š¯.>ïÔÏœÿ>.û9/mÉGÏ¿:%ÿë‚Ó>{áZP»âŒ³¯Ü¼ykIQ~ð¶ýþãwW Ü+-íû?þÃ÷ô{3|ñ³ÿü½þ[ áx¡ésÞ÷à“~ö‡ÅÂÿñ»$‡ïÀöÿ·[.?æ¨R÷ $ÇA–wÅ_íÕ—~èì/ü.‚ò¯n¹æ“[^æâ—þúùóOêrè-!òþûoó Õ·gç÷¼sxß^Uýzv~[ñÎO-þÉM­Y¿që˯|ò ¿øÊÅ8ù¸‘-5`Ô°Þï7xôðÞ\ß;iÖïïœÊÅ’†ÕÇ}ðŠ»~siu%¾œ¦½éëozÀëœ|äÇÏ8VjüÔì:þÝòûG^zéåÈ|÷m—ϘY{å5¿÷ë×¾ð‘Á{įCš¯?Ù ¼óñæ›=ùÓK`Ç\ÔϹèû -‡8¿ûý_ü'¼óºï}ºb«¾÷£TqôÛ‡ù·Ñ¸rwŽ9á3ó68‘.ýü™žÚAEÒ½iÓÖ/ýç·Ý> ¤>e—.ý™_ýâÇ2ªîIDöXÉOe‹NãŠpzrá“,Å Å—ž•…Ça‘«-<.œ¢…_ÊqÅÓêlÄqV´PQ‰KB[ü㤊…f æ`ýñ+÷õ@ÄW}S¤•¢ES…³Tü’6ÉáRS®í€«AáÂxÆA¥ ©ä7ÖÓsÏ=׫W¯2…G õÄCS0†.|k8¤Þ G£»MdqóÎ… ¯{~(_ôõ[·lý‡°ø¬ ãNïÔ4óàÝ7' —Ë‘'>:ëßïšâõ'?vÒ_ùxü.?|×÷n¼ù¾oü·ðõöÿ˜|ô‘C?üÁcË[µtîïª$ÜøÊ忘¿p™×÷þûUã?tÐþ?¿îó|þë/îäëwpkFä½BŽ¬Ù˜çK­;)@sÿ·¿ýíñÇß©S'Çžé¿øâ‹ .<餓$ÈaD‡ƒ¸…ñ[œe¥:XúfSšAžýŠI \NåÈå|¹äë¹çž{饗jßìi¡âêÿMœ8qöìÙßùÎwTPs­Ú°a•’-010º8A¤¦œ)S¦€‰ ‹~Ž Í>Bõ¸6}úô|ä#”l¿¸Ð*:ÔÃáJ„c9L·¥\pÁé§Ÿ>oÞ¼ÚÚÚÎ;Ÿzê©'œpÂw¿û]Úyá…úv\Zºté¢@ß–„ô‰¯Ï?ÿ|*Dnãöå5¦ë¿}& ¼õ/]·a³{gà˜­?›þÙ-?ôؼŠR‹kIת£‡÷™5o©ráíæ¿ò«g}𜫷lÙ†³×ÿúþëu_*µøÀ)ã>sÞ© uÛ°°vE\Ÿ÷ñ“Ë3œö)"2iþ¢å®TÈA-Èšï›8=®OýÐ¥¥9íEˆ¬ŠU [lÃÃWd¨^ˆwÝu××¾öµÆÆF?øàƒô£ap±#Ž8býúõ˜®â=ÅÍtÎß~ûí‹-úú׿>iÒ¤U«VrÈ!#GŽìÓ§9¯ºê*2|õ«_ Ï7ÑOzš—±ÕÉ.SÐt‘˜9sæ‰'ž¸qãFéaˆ›¿ùÍoN˜0˜ã“ŸÈàù›š\¯X±BE!O(4;híY¾|ù—¾ô¥áÇÓ)sñ]tѧ?ýé3Î8cèС¨¬FÞÕq­ÎC©CÃ/¼¤êðhÓ¦M/¿ü2@ ò^y啬1 /ÃxÞyçqÿË_þ2ôYgÊ,$¾lÙ²¾}ûùÛ¦zf°MŒX û](³µÙ¥iÿýÞrË50å_©†qÂø!Û…ã¢ùßD?ûCÇ|ð½cÓ ïüзw¬1³ç5´=su—Cž|`§~dÊܧ‹’ŠÚ%+ã×;ï{òÎ{§Õÿ·?ÿ´¤é¹õ5EyEÉÍí"oK‰üî8<`ÿÆÚÛ3h¾8òÚµk=£/4ûJ˜Ã°(61±bÀ…mòÔ©SÉ(Àø.¿üò|«¯¯ŒÂÙ’]}ß@…f?ñz _½zõ‹iìØ±ppîÃazè¡÷¾÷½÷ßÿç>÷9*‚W*mˆÐp%pÂ9'I-4šj¿D1 +>øÁ^{íµ²NÖ¨"¸Ïª@~¾Ò}ý]PæÒ¥K# *×ki*UÍ ©©4|ôÑG׬YÃÖÕÕ©2ÌZrÇwp‡rjjj€lƒ¤¨š¢Çz†×a[š„ægŸ}vàÀÀèõ×_OG~úÓŸŽ?^U9ø8‹ë õJÿU:•c‹hÿânÊôwsUÿý_/j{þ9‹ãúËž:~ì€ÒŒo}8®ßwâ˜íætÊÜAýkÀåãÁ¿W‰¾}ËŸî{ò2åY‹8|`ɳ©#Ò{Ž;üG×ÿ‡××þìŽ?1¤$Ã5×ý’uäÐvõî£g¼û«—ßX¬zëGÏùöm7}½b¶M›¶lÚ¼5ë]ìˆÌÜK¶8×b» ieæ¯[·ŽMñ‘GÉô¾é¦›6oÞ JÊ¿ ¦yöÙg?òÈ#º9j#T9;¦–Y³fuëÖÍxHš'À=/^ÌF›k¶ù={öÔiÑi§C'·q„¦& ›Õ›ÚÀÄŽ;F-%bbîÏž=[iŒ¶Ådõ`©äæ)§œÂ@ïà­´‡Aàæu×]÷™Ï|fîܹ¥~âÕØ¥:¨75r‚wª²¥ÑEÓè‚ÈrróÍ7S)ˆI!Fwåâä“OæšU0”ct+u« ×(³EÉŠ¤aÜÌÈôîÝ[ykF¡9"­rZÈðúY…c-Dè›Fûðç îõ|¿]Yÿ·Ù;zÌ€[þ}ª×߸掾=:=v@ýòµÏ.X¾eë+m”ZŒ{ß×ú÷êÒ¥êàöÛwqê% «â¹óÏzw[ù³—ý2dÇÖPÿnjh̘µÊü_2åf8>2Áå .ù hþö±ƒ¡½ÓŸ^tîYïùì…† êù‹îüÿy-¸Ù}ÈG3è¨#†pÀ~ -¿ýOE×~|õÅíEä Ïû@cÓÚŸÿò.®ïŸ8ýàê÷Ötëjøú~FÕ=ÈÀœî‰ã؇  Šù vèÐIX@\ŠÎ‚¡Ì<6êÆ#ýúõ[W®\Á2Ò“"PcáÂ…Duu5(Ñ4hîån½õVÊ?âˆ#4k¦|PÆðϧŸ~ú3Ï<£6t×®] Ò!Ñ.$ª]éa`´dÉI}¡èžB—•:•§4ë¶3“â%6 a¡èì˜GX{@dŠÕC)-§ÍZ$ª¾s“òáòR×Í&S)CA™PiMD˜m#G6n)¿*ÅrÕ£GýyŠ×,¢s(YËëXºVqCÓúÝŸúöì|ׯ>{É·~·tù6-‚¥+ÖÕ¯X[h–Šžô®LžÓ–r–,[S·lu¡YÁìmû¿õ’Ozê mµ <óCïºóÊ‘Ÿ~vÉÓÏÔ¥’}¸óϾwáàÝ_%™ü“3Ï¿zaÝ6ùÁ¢º&þ•l"ßsüá ~wÅU¿ýÕo—§?µÐBÿ±Z|â½ßúÚÙ;6nßýæ¿ðïªk~wýwmÞ¼¥i度•kâ#w¯é|êÉGeHÝ+9|…½†DÉ̬¤€p`›MþÙÏ~fƒO~ØÜùçŸgY½zõtÈîâ)<ÕüQ#Ÿ  µ÷MÛüB|F}­ Æ6î ¦è HhF––o¢¼:sæL ''O鈒6S)ÅÒ PÎ¥å.K")…@Ãi<5ª:­H d@(Š%Ü4ðRhÑù©7»!C†Ÿ…ç®»î=z4 è\UUE×¾÷½ïŠö/lAh$ˆLiÚÔéTϳ¸×q­9õ(ò|€a9ï¼óØOrÈ!´„nÂñµkÔÎj*¡æÍò+µ§¾ŸT´Ø ^¯þò‡ÚžyÄàîý¶²ömû½åWÛÒƒ—~úýÛ-¼D×¢•4fdßg¹¦üþ—ÿçéükß6ô€ýîùý7·›íŠK?Æ¿¶ûÅÿõaþµ1ó¥Ÿ?“4_ˆ,s–*Xdò^Ìjç¿ÙÜ¡Oœ8qòäÉ¿üå/Áe0P¸óÎ;¡·ª [–àf9ô^å¹d"A4áfýúõÀÄûÞ÷¾[n¹öúï|çÚk¯…{º[ÿío{ýõ×Ës5×3fŒ&źÒCå9<–©LÆ O¨ 3$ä¾ýío?ðÀ]ºtáš]¼ (ÅW<þøã…fkJÑX3t;Çh€ƒzøÔRŽõ•á@©ß 2eÊI'tÙe—½óïdÝb­š1cÆUW]ùu«áˆõîÝ[²¯'RÃc³BDh׈udY=j¤ƒ=ôqK¢üàä6l˜ïBÕ7†‚ë[L®ÁŠb\2=ßÛE)ûPÎ)#r›æI¯ëÃ7ÂE»«Õ©|ç°þôOòÉ'Ÿ~úé²``Pª@)I9ÝïG€gy Œ6 Fèx¹‡HNš4éÊ+¯?~|4þ»ßýîÌ3ÏÂlOGïQ‹~]Q, O³~Ùep@7ï_|ñ)§œrÖYgÝTLt“~­]»–f|èCúüç?Í5×°`ÀôUT#–ƒæÔ ņëŠÞq §û…fg¡’Ÿe†ÌµµµK—.eÄŽ=öØo|ãtêœsÎq05ýðYLQR]]†Žg»J9:0ºñÆ¡ù¾2n²ñ)Nù¼š€M“@d–@_wt»ë¢'–;  hE¸œþíñy¢Iz‘SN{"§J»!_üìˆA €’™ÜµkWjìØ±ç’SAÐmáÂ… Ó›Ù­BX%+ÙÔ%‚F‹þdƒH¾ýíogk/1´m ÿ6)Û{Þcuü¤\%\ê„"m˜S8äWI·¶ˆ©% ×JKàÈ`–Þâ)™ÕBwnïÿ¶¯9¤½i”R[EÎþýû»†ÙÓYš1tª3È{¾)s„ Á,<6µ¡¾¾žþ’ÇÕW%B—³ ösÞr_"-Áz*Ùý}ÕW?’Á"§Ý^kÜ3árùòåŠJiix$eÊðÇE‹obæÌ™÷Üs_A%è»r]‡M3›zCP§±2Õ%óæÍ£(\¤ãæÄ‰/^¬¦—ˆž>õÔS†"ýùÏŸ>43Ú@dOÌRë¾°qPü2}útjÑg¼%[‚ÞîåÚ¶AÔkhhøÔ§>5mÚ4Æá‰'žPsNÃâgîlذþê"*•ŒëÀÊw¿ûÝå^I)mÈ!ì'>ö±Iù5˜tÌçU«VÁ”ÅbãHŠ>Eõg¿´ð†wÓ`7 kÖ¬yòÉ'yäùæ7¿yÜqÇéÞúËñîÝX-.W2ôùóç³îòÖŒPSSÓ©S'Æ-5àloJíeZëœrʈü_ ˆ>DpÐÈáÙ ÐìçWckòŠ+ŒóÄ”Fï¾ûn¶ÃgŸ}ö‡?üaÙ–Þ5#”j¸ŽÙH9”0{öl.ĵù—ü¦Ì×îÝ»gOn8®´¨¥K—ÒÔáÇ—Ó´à•>òøã³—‡ìƒ/ýÌg>sï½÷¶4’ÍsÏ=WvžwBÇ™v’‡ÕHMÚv»ŒS¼lÙ²Ç{Œñ1Æhß¾}¯ºêªñãÇË‚ciq$ÁbJ€wK`í©/W—¤á˜‰ªÅgO Têî}ã7òù‘|¤1bPË#úJv¡‰.â:vì8uêTª½ˆœ*8VÜôóœsιå–[ÒlŸøÄ'~ô£Iàü ±ix×»Þµ7Ï·Ã;lΜ9ü9Ñàô>Íæ]·w2>û쳟ýìgwn¯™” ™ Ø˜P“'OÞYåS,Kþå—_nù9µ[jQqG©+5·ÿn`=2Îq*–õHÙ%_ydèС’SÐ 4ÿ¾ {ôÑGçΫbÃi§¦m³:Œ¡SÒÍãcÇŽå¼dÉ’‹/¾Ø™ÉŸûC=ôÑ~TyDòˆ#އô:º,@.Ö h²ªÄa©‘z,3ÿQGEãY9€<#‡~ò“Ÿ„!BŸÅ\–„‹.ºj¬Š´ÜYµ“0iᓺ \2lذp3¡ªT‡PÚ뉙ѵAÃAƒi» ù½á†Î8ã ÚpÙe—½÷½ïUq›ŽºPµ¶ð$€Jº-ÙÓQ}íÛ*ý|pK>͵?úh82ØÁ’ù§?ý ÐÿÖ·¾µpáBÁ(ˆŒ[mmí¤I“yä%é-‰}·{ÑJP¾ ÃŠæyÑ!ü©ðˆp<¹˜ÄeaŽiIÉä³À>×-ÿ®¾“¸OJ€`ò@f@“œ|53Ÿf¾¢˜JlÄ­…O²ñ¸µØ¤òDá?þñéU€w ¿|4hŒÄŸkûÂW›G£yÔ¯i¯¹¶mtŠÌäôŽl×5Ãr¬ËaáWžõšO²Y)Á‘%àÔèrH9üê Eýض¿]Ém|:¤ªð§Mî_}Ê!Š—Cj!ô{‘Ô¢•lLf‚ùÞs44`óÉ$7â‘Þ-Ü,ë­F@TK¬ÐìÎ;…æ°{á;¸„Æ1ÂßHDˆU`È^ÆMÐ2~É%—€¡Z z\&×ò85K¡HÇT´ äµÇSÏì[´hŽìß!°W_}5$ Ã^¾ººÌJ—“€~£r„ œÙÃ:´4×?W‡…ll)”ËÄó›ß|å+_a…p­Ò^œœ)&Uå¼sÿý÷Ç©& ÉA›ÁÚ§á²#„ݬg %(­±±±©©‰ nrMß¹©+PÈZ‘Z(úoŇT*Pæ%ò—Æò Ùä§ØP»þóŸÿ 4xÍ*èc”¤9KH™å[…Ûjf²Ù@%6 ´Írh@”Cáà¬Úœå‘aœã'‚r¢‘åR‹¸®©WÃ2ó\/í dý.—0ÈiŸeðIšÁÚvÓM7ÑŒr¾O9!U©9é]:n”Ü¡Cµµ€€ü4ýi¤⬠f”¬ÔqðAÛïµU3ì¸é,±È}ãèZ¤,%nüõcfƾÆž2'V@¹ !éCaöj~‘„uJݼóàÈ‘#¬ŠUÉ¡|0ñ%ƒáª:r©P,ûY(¿S§NLã{ï½·®®Ž¿E('¤Oi™ùKŠˆPáp=eúÑ¢¼äàõ|åB/ø‡~ø™gž©7ÑùóçéK_’€Hh”ó¬³Î2ŽjÀª7Âè šzFVº+¶ÁJÃ…µ@º#”*# îó·q>þøã/»ì2MÀ ”i©ÝŠ+Šáõø‰–³l0ì:§öVÓ—šDiÆ"QC|ýúõ¼8Þ/ '¯8ÝQµîl(Ù—xÚ«xÁ ÇFvÉ[;­˜ü‰Q…ÂË^_ËîxÔ¨Qü)RSšOŠ QøÕç5ÉFãkK¬P“ú"S°Âª•Ý4µŸ]L HD )6‚i½%EÛØTU<Î}>!éÑk iÉ‚ô÷õQàv8“/”¹‚lZEgcÄМ¾0nÀ}úÞù5]€ÓDÎ7”¹”S8޳£§žzŠ?hÃbª xÕ××KÍ”“Ô»ÒøXaôСCõY£ÀT­6ÈÒI7›ºÐÔ C(¢•xjWíWôO#*(#FŒ …,³T äQþÊ•+A¢³¤aUE½(¤Ä¿eèHˆà)zú•~û´™*ÀÚ3kÖ¬‹.ºèŒ3θæšk´sÑÝQXa±ºªP:¡4Ùb=Ê /ÉÊÄ­ÚÆ°ç8å”Sø{å)è3cÅJ©«LÐó¹çžSt³fÍm ÷iN\ë$„*À&Gв†ÅH‰€5×SHxQúì‰kD O]–˜x¤o­¾CQ/õ%M®½öZ¶5p´à¤²'f¯ÓR~Ä”–Ë¡œÛLcLùi9ˆ(>’D±øK9´õ€’S¡-%ÓDÁÏÚ…ÑiÒárBJ],t'Nù¨H®GGs`—¢Ò¾(!¡´´ {]¦æá¾…¤øCÄxR,× ‘{ãX¥P 7¥át„kŠQÝÑD*IG)}4ÃSÐ4ÂÚ¾Mn’“¾¸ö…‡árÕyêZ„ãóÔKd‰®ÅìÙ³YêÙ³0QÇŒ£¾„ÊÏ<ó ¨${²/¸….]O0ó™ä6lhd”™ª\ÅM)(Y<¢¢ÚÚÚ0T˜à<Ä@ÆËŧ[mÏnݺÑÙqÇŽ%ŒiÜèÉèÁ§ðê0Û2#…„¯¥t 3Š•hóŒ3î¿ÿ~ðz~ÔQG Áê-€w€&“_ÁM&ÔΛNAÆi­¬ñ=õ=/ºi!íð2D¬‹†"ÔTšüìZô@Ï}ªcy0\€¼›œÃ† ã«’ — Þ_•<ð _6ž†é¬7t‡þ0€bŸ~úiH:CÚ·oß>}úpÁòfK¤lå¾UÛHi•‚eå§À&3·åÌ­¥3@f;w*îÓKšTÂO_ g¯Øf±R)Jù#ÂnKw¤–ÚÖJu-d¶kTw,µrÛ’Ði§¿ˆ½ZŽì=²%í·yóæA9™Ûn‡ÃÍ1ü“•/ÇL]@\—fnºÝ/SSš‘2dHpd©œh”°×뿚Av&jè.2t 4Q JºUÛ uDØˆŠ¢jš>‚C÷K óA¡DV¦}±–¨¦¦p<øµ‚ p“ké__,&0nÕªUÜ‘e8†Ê1TÖÉ¸ìØ½ˆW$Í'× øÎ'¿‚È .†¨6mš½xk1Q¸gz®¢¼Îõ5 wôÈÆ"§gf,¯ŒÅƒ2«««%nÈÜ‘SG©›½râ\.ÓH©@Ðç’-Ú®VL‚Ó;/ðb×QNÛU1(9!xÓi¿™Z‚cø(ÕÒ,ŽìC_-D±Æ9VÁK+j§“¹ÿþ €jT·hÑ"ùNˆÄ &˜*‚QÞMÔzô$'a¤Fµq¹)4…‡M¾Ã œ”Y4¸¯+ä0{ ŒPVÎŒ5™Án·óû5ô”üJcÉ®AW­öÊSúHâ'É¥IMMMúñ¡^š$ j¯¼¹9‰ËéòcG@Cʯ©©4Ã]½˜œ ÍUXT†£N Œô–zµöƒDjîûÒ}¤¡¡!”¸[rZ_.µ( ]Xxµ&r„X Uåg»ÚçëeFý!½I^D›¹b’ŸâðQ‹T^#D|èP0ЄAL×5P@ƒPO<ñ“_›àBsDŒB³3±&X°.á!ýº vÂU€­Ý»wg×0‘™O¨ýˆ#t.îȵS‘…jyAÀCð× šJå-ª åOŽW®"Š„ÔÕB÷C^Ðe½õëˆÃ#5(gÏž=ÙpGa®ÝQ`­ùqãÆÁÜaÙܤL˜2êMzôèÁ'ÙÂR¦P´ðÖ×/S¨Ê9v–_»té2|øððjÄã¼,e>¼}iåX/=–í–„š-¿ˆ?¡ô­Ü;þÞàv9§œv7G.¢”Nf/SZ‡ ÌL@dÔ¨Q1‚£¥|G”/$eZ¦I*ƒëñÐ)‚˜j\Sìà&˜KEúñQ¼à¾°Î(P𬡄¬ÐM÷†  Ÿl«&6pàÀÕ«WƒVúYVXl½A!AðB³Æ[‘c(è ŠÀRrŸU¶ i4u'§š@˜Æ„´G ¯‡cVÊH’‡ùÕ’i$šÞÉ‚I»¢e„ÑAõðD^5¯aJRûÍEÂÑ ­8‰<°K¨‹:ò¸ï1žÓ_š“næLKZªxzÇ¡ÈXΑKò—Ó¢p;µ{D9å´·sä–nª; ÷ë×Ï#2¦ ¸À4 Ö¯_/TyÌÅ'0ÄLV׿>ÝÕÏÊS_š‡…Æ1Ÿ<Î'O…ÔB 0¤`‚ úÈÄ=›ÒÚ¦jÝ«ü„ÌÀÜÔ©S)dìØ±b5j·U)'Gô—îtîÜ™>êèRá¯=U <,?lêùÊ}M±¹®¯¯§:5ÖZQnk(U;\Pˆ–8AÌ©RM-.HtÖ‘wÇ `¢à×dÖå±>ê"ì4ϲB°’QŸQ5°ˆ!V()q޵Jý×^–¯µÜi} µq,ìKI£n·Ä‘Ó“d¯µíÌÎ9sʹPâð¥„ÝHÜTÉ2³&6…Uˆè`<ˆªÛvPŒÊUzS¶ëñ`ʤÒ”h"‡¨ÚDbr­·‰¨¦±œ°(Ú’ÿ°ÃS—Éê[ÃsH€B³¡„‚WýyÒl~­««K5ô€,l±1,C‡¸;­6Ñ“ÉO6Ã\©üÎ9•Üpy]hƒçIg‰â”™µøC{öìIa"Ï%é©yáÂ……D‰›î°íàÅÑõ”õFD÷Õ˜ÖE²[ ÕWÜX»¾‡*bqªåVH”UB›°ä”/½(‘;{ ›8§ŒÈ…–€8î0“õ"BÉUƒT†šX&|xê¥cgµÊX`(`(.€¡ˆd1jÔ(¹-TðL…HUAÀ0$‚îñ»u²Q~„ƒ3Ü‘ðDäÔQ}(YK¥ÃÃg¬}VF¯2‰^á%¡L`μêÉ4ªK›ìÿ,&å-¬|ª ¦1<¨Š¿\Æb“®]"=‚Ëk¸¬ª†ç„…¢^‡âåvöƒ×q&°r‡Ö2†ácÄwij»jÕ*«ì¬:vqdêI&ã¶råÊ9sæ„u»º(åšm©C’” /7§åêñ—æ¯*´d©qN‘[”]ÄVTwbl™A–I“& «ÀФa€âaÏBÛ=OãYZ¢%Á:œ‹*iÜ}}z(|àS&R]ûÄA7PK€ON-àÒlOó"“ æp6[… ¥*&‡â‡î²§Þ4‚é4º¤ºt–_C(Á8èyŽbyAú„Ó~ǽˆ‹Dœs†K?éêADu«V­¢1t™Ñs@Rûš%îŒ(œš¿—ŸÝµÄy+*_fPÎéMÈ媣éúÈ‘#™ŸÚS@ý Îz(¤tBŽéÉŒhÅäj=ú ÷oLõ=ÌógŸ}VË‘B³©EÐ%uÎÒ d¹Ôôò€Ñ£³ €;zÊC-KÓaPjøøÎ*²bÅ …-qV" 2,Y²dÑ¢E*`pt6^”®Üe²4’è/8"“‡gõÈ2Æ.PS¹Xþø“¤a!Íf4xŠgÁYñ@[ž5à4­R/øÀbÒ—…†‘¸ñ¹×®]«MŠãærçío;OMžÁWÊJÌ"¡¹>ÚͯóOž:ú裩+ŽÒ˜{¾j}…SJ%82TšôËA±#FŒ0À­¸v`œGŽÊ4´I·êÚÂé…Ø¥®ªª*Ymcc£Æè@$™YœÈ N1èN…­ —TÊø«JAEå²eËÜ ðjÆŒÔzÒ¬Ófî7ŽgYWl¯ŒW æR/#OïXb‡ Â;bqå¶Çw\ïÞ½ù•Æ,]º´Ð|þ™þy„5¶±èwnÉ´¯%It‰¶\N9½!ÓNˆê¤LöÆo4L§¨“L} ÁgE4cÁùÉÒŒŽ,m„DºÓY#A6lÉ<³’$*·¥(*ÒQ™<Ñóz1‘_}ôQ8£bPË—3†$>id0ä[Ï@g÷îÝA(õÆl›vwfþÍIpßZ'ª°¬'b9¬:Ú¬%ÔbÂÞm ÊÊ &«Ý;Í)*ûD.jÑu#ÂR×èÑ£©ˆ;jq°È5440>rsÆêÔSOeu™5k–ÝT£KG†õƒ6ð6U¯VÞÂWZÎhж~ýú±áàZ£’òºþ—Dliý¤.%—€r¦Ì9½ÙåÈ%I_º½zõb’CN™“:j0ATeš")6}útpÇ]óÀÉ&'7Ãß…qâ‚Y}/²€8äj¦-²újàˆî2@FI(Õ…ËùPó'ÅÔ âÐ<ˆ$­ARq]“{ên_uް¢Ö2[wšª‹yS.›w‘Hƒ:©´äÌb¬È9ÕÐQü 7Ë(iáAÃé’’PððBáL •2Ý2Pݤ‘|’ ÏûZ²dÉœ9s@O®ÁwÇŠ;ð_Y°`k\8É)†}«”‹ã&ÄÈfÕå^êõ©\"EÒÔýtK´·D¹"˜už´9eDÞŽ@ƒxüñÇßvÛm†.5Ò„t*@xëêê|x˜™Ä16uàp ˆèÈé•“_ûÝ"ƒÚ€ˆÂèpþÓÞÚ…cÖ ²Î ìÓY-FŽÝÈ&ŸMq0h?QË9ךšòS&ŸñgUƒhTA é/ʈ©î„NPù6¬-&€¯o߾ޤbw¾ó º3  ,`b–uªXh³Gá1öúÄOÄ´ ¬gAÛàËE D6”)aŸ;w®FÛšAš U)‰Ãˆ6…Ó]rZÓøŽâp¯PéÈ.àµ%wõ%b±B«q©sÊ)K-*.)>üðÃŒiÀ€l~¹VªP*”p‡.ߘ½@•á3€@AeX‚ÔœSA!ܶ"Æó2pŸ@ïÞ½{*½ûî»)çïx‡Ó€9Ѩ%”æžbHƒÁUÄDy5Ààû,p@ž)Pâ¬8à£jåâ#™Ad·©´ÔF[ÄÐr[¿~½†…´‡G(œ¥Ë%„ÇûôéÃ>€MUƒn\sÌ1;w"¹Éø°lÐȉ'rGʼnBÑß4#ÌOäW­jPÎ'ÝTj¬š³Jùj¹Ñx [õmGÀæÁŽiëhDquySĤ…7Mâ&ÒòÓxJcxC­oZ"¿%ôRÛë–ìE³Ô"§ŒÈRì¯Á¾Gy¤P´âSæÈM­ÅÜÚ«<«&V¸D ùõúÐðÕC|Hª5\h_0ÿCs €Óð €ô©ì£´qS1)Iðqåì¸e‘Z"H2<TÅ6¾FuJxáW´¢ºpÖ+á³?¼VŠº½, ð_«ÖÖÖêèNO Œ‰C´ðæNÏž==dÓb[éC¤öžvzÊåyD¡Šï•ØÐ^ ­†è¿P<]Œ8ßÔkT'–@^–ÌWKqwö‘2)Å ¦m|²xÖ%‚‹B .„Z"È%äŠ02"甥- .Ô‘bÆ{ì±ZÙ m5ú”•êª$qt@¡ÿIUâ43cG¯aå«"¨¼±|ùr}kv1vìX 8[¶l™ûež‚0ÐS¦LÑy›ªÁ¶$¼Ôë5M‰°¨¤#ªÖÄ“=­?BãMC>­ò„o3‚c —üªþ_‰ÑB³QŸË˜+™± ÕcƒÏj 7fÌz´dÉÏùÉ8 ´ â”K½}>µ¾iøÎêX(:8v¥áÓ¦M£dÚ_SSÃè¹ ©dz:;V÷™E‹¥Bqõj€n3<â#?cE³!æŠø´Špœ’ßB .,B:ìã©ðISN‘Û*JV1@>Ète/ ’jĬ~.@©âª¤ÏMw8SmAµVÙhÃd ëâ)ܰaÃ(aÆŒ²QµÁ€ Y°``4~üxjT˜*( Ð9餓XÀ¦´¡Ä“£xî“Æ I±¬ÈNž ·RlW…¼Òm•‘cÈ”Š_4 )Ùª‡2?q}çwÄô ¤ƒh3n ø• H]zÿáMÕÉ‹5@'JŒç“O>éR§à•eq¢#¼ˆºº:†ÅJ5HÑ"QKî$BPàŠ*ØÆÓŠÀQZúÁªH«å¢ÖG+ì8…õ©kͰܳ„´%çLsÊR‹í§°i,„W§ïú‰×ŽYbh” ý-ˆ,‚TìëAH®fn)_]4•1¸p¯Ý·o_ fÑ¢E  ¸ ´:ü ƒ™‹PHÐdCeáFTUËX°£Ù”&:膘J=âã0âuyä‘ ÝäÉ“ÉÏúö544°Ei3mÐôƒöhgÁƒr[µ¡ö<¨"OUUUñ+¸)gèôĦ ‡B[®ÉÉMOêtÁÞ5,„¿iE€&\›*‚Û~ÏÕ°?Îá Hʼn¶„ŸNïlNžæ…{èB%Uâ’ã»r!r*þ UEÏpÙ£EN‘·Ä%>áÂ-§ž0ÃǹFžãñ˜µ¯•gHDV!LZêÉ`@ÕJúÙ}ë&ðÕ ±¯Î¯lŽgW¯^MNi—Ž5”œÊd5Þ(MÓg5u„¦Ë% ýû÷‡¶»ÒX ØmjjòÎ}™jS`÷îݹ¿páBWÝg á²_\Ÿ¯ÊT 6˜ˆÈHÃ(ojdÙãqÍý¾ò"a4fÍše¨']j0zãÈ|•À¤ˆžTSDŽw¤¬FyzèºUt?_þ§Òï€1^Fäœ2"·¦ ͪ¸ÿ§9‰\ÿÙœ´»gÝò‡o„@dÀ¨¾¾xRÖ©¬Y},cÓQ…>†ÔÁˆHÉ#/·ê.—QiMM @ ²ëMõn!9å°žP]WLJv˜.,RËo½sœp ZdØk»@ä×_eX`Šç‡zÆÐ/„Ô[y1@IíPZ ^©Î?LÅ‘1x’…ÃséUÔÕÕy¦G]HÅzLjá Õ¹0Øq€ˆã¾ðr•Ô4&6ð7å³­ðâ«mîw L+†€Ê)§ŒÈ;¦S[Œ˜l©Ï0¾ •Úû­\¹þ TÉõ<,,Poœ%ZË …{ÜT€‚©á?zõê›q‹ÒsqcccD=e…k×®7n7§Nb%½{÷†ð®[·®¶¶VDzJÝu«UzSPÉ.ކáÉî„§¨}¡ëzîT9LHÜš‚+7§FàXÝp•#@II Ñl%Äb à¦Ôµ<ŒizªYhCTšœrzs¦}vgeI³ð²K¨„@uÍ£s 0(Ħ:eÓ`Êv IµNÇáÄGŽ‘#Gz §®1õèÑãH®…BÀwþüùðMõó@ÀÁƒƒ˜ÚhDx$þxN-œ»äA©=ä7LÃ=ú#=šFµ¶Ù³g«S,µÐ|V©tÅõÌbµ¹Û‚ ¥Õ½Ð­~–V&^~WCˉªÞøÊÝ•Ðá”/gÇ9å´Ó8ònööžÎ%€O½J’TsNY¡®!üê<èX85N£MûI` ÎÖX ê€ ¢à¯ÑH=RÓM%×F_^µjÌ]Í  Í"ݺuS§Bßl`Ÿ1¢¢/º¼ÐWr¡ÙÕ²zÁerMúi¿ìZœg¦gn±hIÑFõ†å³òèyŽsÊé Ë‘w¦#€[ø* \R&)jY¹rec1…Ãe@ÖÃ@²AŸ#HJ°HqÏ•Y‡Âï²eË4µßá¼” búuë¨1L´=KMàÒó·V6%¾á+%—+W4¸h  Ã^¡Y \~:—±8§œ2"ï4@—oÞ¼ù…^X¿~½¦†ºýUZ-ï®®®+ëëë=× x‚Õªj­lA …èÏ^b®[Y¼ ƒ‚¾ê2ÇUUU1À­¯»Šçom\ŸRgiñ7NçRkºrŒ.÷òÓJ¦œrÊi/EärÎeÌÍr] íƒ÷¬0D4õ‹ôbsÚ´iÓ–-[@ÛP æBËCµªC“/ˆyÈIäÅ©EŠÅžÝ]¥C‡ú š=‚+y°]R…Šúg…J mÏîr »œrÊy¯ ËÊjKN å¶qЍ™ 0­9¢§ˆ!¶.eÄ¡ã¬ô#xn3‚¹û7' X»¾ôŒ®í€Ø’χŠBÿ’¨£åhžu$rÊéMÈ­ìywÀ”vÇi†ÖÆlqN(X‡²]0僷`Á¡"ñ:¼E©…w€œ*ŒnEƒ¸¥W°?ŽL“sÊ)sä½–AšƒX— u*µ($^“"¥<44"Zrø»Ã+M»žjé½·Wf½K5Ž÷¸nON9eDÞc€ÛJÌ‹ÖA¡âîN)wwYxŸÂmד}N9eD~ãSà]„\í…•×È [ 'ú:JoŒ^ä”S»Òá/>õX¶c(œ ÒýøN[÷ÚïgÒƒÄ;öÊC¹6fªH½È¤!§Ì‘ßÈRˆòl%òнJ|¹g³ˆj UrÊ)#òÞ‹¤{!x튖¨ ëènW Ýž„V^\>ÜË)#ò®ÅͽÍ_¿@öú¬Š,9å”Ó\jñZ’þÕÚèÇy÷Ë.vX1n÷ƒ`Aä”S»Ò>yÊÓÄâ–"$½jÝ!ŒÛÍÚx=i”´¤u«ÂœrÊ9§=C~ß [ø–|å”SNojŽÜ5Û=°XRÑžjÆ®&ø%F+%V‹yâå”SÅôfÔÀ¯èP­-^Ö Eó+¯¼R²±h×>£d#ßvEÝ×ÅÀš ÍSwwy–SNYjQ×vІrcåÖ ã›g·Ñvµ¶œrÊéÍΑSÿ>¯†”Stn©_+ßvÛœ†:­¸È,§œÚ•þ+æ­Ø®¯IEND®B`‚openchange-2.0/mapiproxy/documentation/pictures/mapistore_logo.png000066400000000000000000000300111223057412600257470ustar00rootroot00000000000000‰PNG  IHDR``â˜w8 IDATxœí}i\×uÞwÞÖ¯÷žžÌ €€ ‚I“"Ë!mG"-F²¨ íRbÙ®ØR©²È;åT¶Š“Tì$NÊQ\±“XŽãRl—b*‘R‘íŠ"ÉVHš¢©Å4‚H˜ÁlÝ=½¾î~ëɾçâÍ`@ÈüÝ*zfÞzνgùÎwn3ã;ãÆ;ýÿ¿ï(àßQÀ;dƪºë¹7qíë}¦Ô €ºgÂÌvÇ›–eýÖç>÷ûÎ+¯œù—™Œƒ¿ûwÿÖÉ·­Ï,|ö³ÿkéÍ7/ñ±c÷¾øôÓï;ÉÌó>àI¹¹Ém²üßéáªÿGÛ~¿àÓÿñ?þæOÕëMþþïÿ ûäɇ¯»vU@E ÿý¿áò«¯žÃ{ßûøÿ|ä‘ïúaß àï3óÌmœY7{õûýãq Ã!ŸÏŸ&¢ðÛ¸nôsLD_ÿÝßýŸœ={þ¡~ðø¾ûŽ˜»)`×(èÌ™s—Ïž=cÇŽ|êÑGþ a3~À$€ðú×n·{ž‡ Ç1Â0Äh4B§Ó¹w4Ý z'Ÿ@àgžùÀr¹Ü‹_úÒsD4µk„·£ˆ¦è…þ„r¹Ü‹O?ýÔÇ€™”™«ÌÓÿ¿ÝÏ7sN†`f†Ó4õ ‚žça4Û~îízΛüüø‡?üô¯u:8¾›¬]~¿°¶¶Î'O>üÓJøU"zLiøv,í3{DË oô|ù—$‰~Ø$IE‚ €išŽmÛ'-Ëú£wÈi§=;;} R)ÀDS/0ׯ±÷»)à išôÞ÷~¯8‡Ô±á.Çßìhîòû2€În'%IRŽãI’h%ˆBÄEQ$aäízÖ·3¾ë®»À$@­í즀Z>Ÿãápô`6ë~Àaµ¼ôçvâ7ñ™Æ·Nfn`l“Îï÷ûF£-³š™EÑ¥¨Ïaú\fFOŠã–eÁu]d2™¯@E3·ø.×ûL&q È y8Ží«Ÿ+D¤ÀÌLD§ãâ·úœ%"ÄqŒ‹/þÅ$IÈ0 X–…R©„B¡À¶mÿofŽˆˆL0ó&Ìì†aˆB¡Û¶aš&LÓÔ³?Š"ŒF#­"²xœ+èç\ZZ‚a:yl·Û(•JOLLü˜Äž¿  u ïËÊàCöÝ@Žãiš§SÇ»{3#`æìåË—Ÿ2 ¹\†a Žct»]03åóù'Çù=Œã}‰,Ðï÷ß/ÂÇkš&ˆI’ “É “É`8Â÷}X–õ˲žMßœ™É¶m­f†çyà=•Jå DdîðÜëÛ~60ŽvÞr8Ž­bíTÌ»*€Ç£ 2×è-Lƒ±p¯ùûöÏ£Ñè/GQÃ0¶8Ô Ðn·%ºyŸiš¿ +çïdò¶?‡23ð}ŽãÀ²¬0ý÷8Ž·8ð$I0Ç1lÛ~ªP(|^]VΫEQôÝÃá0Ç1ˆ™L®ë~^ÉÈ0¸Þû¦eºÓ/wS€®Æ°€èz&(Žc{yyùÃDÛ¶‘Ïç½R©ô?0¶å[–d’$$J!‚K’ù|ù|r¿Ô½†¡¶û² ¶ Ô÷}ÄqŒB¡€l6Ès¶Ûí‡åÞr¼8n"B†à¨d.PïõžV«…ÍÍMÇAµZýÁB¡ð»†a€­"º]Ì‘dî;ke×°mÉD¸Ž :sæÌš¦‰L&ß÷1òqÿH¥Rù^úX™q–µõÖ†a ‚t³å~f€mÛZéHHü€ø(ó†á‰v»}Äqí?ÀqíÀ•RZ;ä+T®§&|ßG«ÕB’$Ï”Ëåß!¢׉¸˜qK&h{ˆr]†¡,y„aˆáp(ŽðÃårùWåØ$I A T*!“ÉÀ¶mˆS¶mƒÁQ!Š"ضÁxy'é0S-8¥0DQ¤‘P”™Ñívf³YýŒ¢€$IÍfáyž\'VÂÔ÷”£ÞQÁó<†×u?œÉd>«&k‹läÇÝd|=ð6}ED¤gä¶p&Š¢-+Ž0ŸÏ£\.’¤ôz½†|>¯£ù[’$p]F£ÑŽã|IJ¬Oʽ ÃÀ`0@†Za•Jý~Ì Ó4†Ã!\W°2"4™ý’AËê1 aÂóÿïåÏår™ ÃMºÌÜÚ.õyGÁ¿•RÆX;aA—.]úp¯×cf†mÛ,a%3£T*É’åF£ñ÷–––$Ã…eYòÚ‰êÊ÷}–—s¥ ý‚ ÃaIÌÇÑÇÉ3ÈŠÓ¥îÅâ7ä‚éDoss“‰èï5›M´Z-qìÚ_ˆrK¥§rõݰ à± m‡ï½þúëOHüŸÍfaY–N²lÛ3£×ëassNGÇðé¤KbzYp"Œ8ŽuB•Æ|ô¦Š1Ãá0m"6K‚ý $Hò&F ¦i¢ÛíÂ÷}Ôëu0³mt ïgY–vö“““7P}»Í&è•W^ù1…‰ˆ¡(ж8Dh·Ûäû>+gÌ «—,™,Ëb×uẮ—ð}_Ñþ,TŽF#ŠãXÏ^¥H’°°×ëÁ²,8ŽCù|ž³Ù¬†¹²É*1¤ ˜ˆÏçu ÃZ­w»]]µS š¬2É]w:Ôëõ¿:55õ_ä·EA·f‚¶-™-&èòåË_¼xñ/)t’€Æʉ9PÎR›¨t¼.‰ŽÊ`Y LÉdØ4M½ì=ÏC†E‘ÆäUè*IœvΦi²@#’`†Á¥RI"3IÂàyKR'×1M“%xP3UðG¹\fõ~Ì F___Êqœ¸R©üço» ÚØØøèÙ³gŸÞ^T˜Á²,LLLh\H"ÐAY3ây|ßG6›E6›ÕK^ÌØ`0ÐX|&“A¡P@.—ÓX¾Ü#Wˆ9á†^¯§£ÁªšÍ&\×ÕuªTëMÚ…ïûèõz(—ËZáÌŒápˆz½þÇqâl6ûkÛe©þ»=&huuõiÓ4©X,2.RY,%I‚÷KâbÛ6™¦ÉAP³Ùdå´Ä9ê8F#V§þ}Ç%mÛLD¨T*P+„ˆˆ‡Ã¡†±“$¡J¥ÂµZ ¥R ­V ­V‹ŠÅ"\×%œÍfaš&Ið QŽçy4Ø4M ‚@ç5b ­¬¬p¡P ÉÉIYÇ1g³Ù§çççå¶$b;™ Ë—/ÿõ –¥º¾¾.Õle®B¤cÏóÐétضm¸®K…BŌض-¥>ÞÜÜÔ)’$¤þ—hHÇ훦ÉÃá‚÷‡C4 ö<¶mÓÊÊ ÇqŒb±È˜˜˜@†,¦Ìu]¶,‹2™ ;Žƒv»­ÍeYlš&ŠÅ¢^UŽã ›ÍŠÒ¸Õja0 ßïs£Ñ@¥Rùh¡Pø@û‚ÛR‹„ƒÁà‡Êå2\×¥8ŽÑn·aY•J%T«U®V«d¦ È6I|D>ŸÇää$ )EFQD­VK°{¡33år9ø¾On&I‚n· Ïóȶmt»]´Z-‰rH|‰¬,µ ‘Íf111A²J=Ï£–E{÷îE>Ÿ'AmÛ(•Jسg®7(²P­Vƒëºð<<ÏÃúú:jµÚ …OꙬó€Û€‰PÅN*\žs¹ªÕª8K ‡CÝDl¾Äßjf¡X,Â÷}†N§#ÑŠ¾¾„’abccF®ë¢Z­" C}ñº¦ÏÛþYây5Ë1uxÙï÷qþüy8ŽÃõz¹\AÀu]  y÷z=‚ `y~¹žïûðG6›EÇ:' Ñ`ABkµâ8¦ápÈý~_;þL&C™L&ù"Žcò}Ÿ»Ý.år9Êd2<aÛ6EQÄ騬Z­’Êh4q¿ß×Å%•S†lY:ét:œ¢FF[e9VåÍ(`Ç ³Å0 –-I^]]Åää$çr9 u;5JôÁ®ë²,t:†R©¤³ 8eâtB'&, C#Ë= CVt ‡Ëì5MS³$z½+Å"›ÍrŠÜ¥‹4R§Îd2òÞ,…%åÄe"°ÊÒ¹T*Á²,½*äyoË Øvx JójÄ^‹³ËåršáJ´ôÏ*ÃÕÅ Çqຮ~héä:)e£\.o ÃÐ=YiHAr~¿¯}¡P€ïû:jJû Q„ä¢\©æ¥óQª@.)3$Q®ªaGdôíå13G’Ù¶Í“““ˆ¢ˆÇá(ŠÈ4M=£äåÄDåóyÚ³gÐ/†¡ä:ö¯V«p]÷ªýQ#mkEX–e‘aœf¼Åq,&B+¸V«Q·Ûe•Бa¬h1ªƒÓÐÉ^6›¥™™î÷û”ÉdXð Á„R¨,`ÅÀ Á`Àâ[Ò&h›oXÛMPLDaµZE­VÓñþÜÜKvkÛ¶.IŠPÙ0«ô š¨fž.°V“ÉdËå8…µË‹èçI…˜º9O®£î§¢2vÎçóº>‘FFåØTVÍ•J…%É’ %AdffIJ7664µ2m‚®N¤·o‚âL&ƒl6«Ã;(#PDúÅèU€¶/g9& Ix–žüiËïÓèhú~‚É5å\Ás¹ÜT5}œ\Cn›æ/É9âR(ª¦Lnƒ-tôê x{&(aæ(UW%™‘DDN‡³Ù,`¡J[½ ì ÂW/MÌ,&„¤> !̯M¡ïû¼¾¾Ž……ŒF# }¤ Uák·Û(—Ë•ã˜?€LÓä(Šˆ™y}}o¾ù&ŠÅ"ˆ…BÊå2g³Y.33©!E› ·‚%nÆi¡« ³JHðùÏž_}õUT«U¾÷Þ{±oß>ìÛ·OÏHf– ‡aˆ+W®P¿ßç\.×u¹Ùl¢V«Aðõ" ÅÒN?×… ðÕ¯~§OŸFµZÅþàò·¾õ-üøÿ¸NƼ •ÆcÀŒŸ}öYaÝñìì,&''qôèQv‡^H½|ßç—^z Ÿýìg‘ÏçÑï÷ñÁ~GŽáL&ƒÙÙYN­mÎèjŸÁ­›  ™1`fj·Ûp]­V‹^~ùe=z”<ÏÃg>ó<óÌ3˜œœ'HDß÷I°š/}éKøßø š™™!˲pøðaüÀüÍÏÏ ~¤M›º`Û6A€óçÏã¹çžÃüÈÀ0 ú…_øLMMáÉ'ŸßCårSSSRŸ&f¦~¿?üÃ?ă>Hù|¿ù›¿‰G}”ŠÅ¢ ¬´wï^d2Ra/µZ-4›M<üðÃ8qâ>ýéOc}}4 333P<¦ôlÛyÀö¡[†ÄVnllˆ}äf³‰ƒ¢Ñh`mmMSÄå¡‚ ÀÆÆ‹EÔëu,//ã™gžÁ{Þó|îsŸÃòò2Ö××ÑívqôèQ]ßefôû}ôû} ó›ßÄ»ßýnÜwß}€Ç{ /¿ü2<ÏC¯×0f`‹Eض­ÃÏF£N§ƒ÷¿ÿý ¸|ù².ÜKР`tº‰pF¥-Öu]”ËeضÑhÄËˢœœÔжȈÇ$ß»õ o7A %R Ã=ÏSÇmíúúºN”J¥RÚyq¯×ãN§ƒn·‹Ñh„F£l6‹ápȵZ …B®ë2©¯˜,‰é{™Ã0ŠŠ…kµLÓD¡Pª 7›MaDhxÂó<$I½^O#¡¹\Ž%±¡<€l6‹ÍÍM¬­­¡Ýn#›Íò¾}û V‹Da,Z™ „Æ´õDdôvMP‚«á àB¡À†aPÇtôèQ>}ú4åóy B¬gKÃáa±¹—––pìØ1êõzEJ¥¥z¾*ã”$*Š"²m›§¦¦ðæ›ob4¡R©ÐÊÊ 'I‚jµŠápÇq4¼Š’¨\.s>Ÿ§_|‘<È+++8|ø0MMMq±XÔ”sÃ0H|Ï=÷ ×ëáÌ™3RСééi䦭äÀ©Hꆣ ë픤Œ“1 /8Ž#&Ÿ8q³³³<Q*•tÄ ²fv¥RI× î»ï>Ôëu¼üòË|ùòe©@ñຮŽÏeªæ‚ï~÷»±¹¹‰¯|å+øÊW¾Â/^DEp]ûöíà]!S!#‹E|èCÂÊÊ Ÿ;wN2].‹˜EµZ…‚XÑ^¸×ë¡ÙlBÐÞ……LMM±ªØq¥Rْäü@ŒqàoO(·íÐCÌL.—C³ÙÄp8Äg?ûYd2T«UìÝ»Â4“)ò,˃>ˆB¡€~¿–”#œ«™ ™L£ÑH×xà \ºt £Ñ‡«¯¾ª•%þCL‹øÏó°°°€b±ˆV«…={ö`ffFÃ"…BAûÉkÚí6^zé%<÷ÜsØ»w/žxâ ìÙ³G7t …4,Ÿ™wœÒ7£€í&À8¡¡q5Œr¹œ8Uj6›¼ººJ<òqâ„F_£(¢\.—)‘$ :uŠŸ}öYT*:pà:tÇ'"b¡Ì LŲZ­òñãÇå=¤†LI’°ëº$` Óvä­&b;-TÖÇ*)á}ûöá'ò'±²²Â£Ñ—.]BE˜•L˜™ÇO¯×ÃÊÊ Îž=‹³gÏâÞ{ïå'žxÇŽ3s»ÝÖ÷–U  ]£Ñà^¯‡ßú­ßÂéÓ§qèÐ!ÌÏÏóñãÇñä“Oê½Á`À4ER%†\©TP.—±´´Ä¥R 'OžD.—ãN§£ÉWÂ⇜$ …Ž= ñN+++¼¾¾Ž£G² ¶Ó8ßRŽ7¢€M„g‚A@Žã`ß¾}X\\„ïûX]]Åêê*²ÙlÚ iššàúÔSOá®»îB½^Çùóç155`lB ͘–¨JšãðÆoàÌ™38xð ¾ïû¾¥RI·*‰ÂÒ-KaâðáÃø‰Ÿø ¬­­¡ÕjáüùóÃwÜq‡®ÎI”7I²uªÅÉ/--áôéÓX[[Ç>ô!©uèûoWWÀÍcAר ^¯#T«U* ¬­Â6¦B¡À (•Jš!Ñ@xä‘GðÐCih½^Ç«¯¾Jsss<;;‹(Š(IV ¢ºãŽ;Øu]>|ËËËxã7è·û·ùøæçç¡x©E‘dÂ"XÊd2¼¸¸ˆ»îº‹Â0äV«…••úÓ?ýSžŸŸÇÝwß Eæ¢ápÈžçQ»ÝfÈçóšL–$ íß¿Ÿƒ  ••¶, —.]¢f³)$ƒÝDzÓXÐ5¿S0Tõ—/_Æ`0@>ŸÇÔÔ’$ÁÆÆ|ßÇ]wÝ¥±s‰R­BRfD©T‚mÛxùå—ñ¹Ï}?öc?†»ï¾[ßOΤtqq‡0öI8uê®\¹‚……Üyçš*IX¼“`rrR×sŸ}öY<òÈ#xßûÞ¢1erii W®\çy˜ÅÄÄ666tuLVs§ÓÁp8Än¿e,h'Û5Y ê£ÑˆWVVtXÁ½ºÚT¯×EÊå2Êå2»®‹Á`ÀÌc®„§qs­VÃSO=…Çœ¥UÕ¶mKÊœqkÆœl7°gÏ>räN:…/~ñ‹xíµ×ðä“O²ÊXÉqn·Û‡:±R½ð}‹‹‹|÷ÝwSÜjµ@D¸p᫦–ÜDr åèyjj ý~Ÿ/\¸ 0aÔ]#KéÍ(€°3§‘†Ã! …Õ$El%YöB„UY,õz=†AçÎÓ½¹“““”ÍfI)†Ã!1³Ì,*•JÂ’#åL) %§“¦ééi]'¾pá:u ïz×»ÀÌh4tá€^¯‡……², ëëëèõzš*333C¹\žçÑ`0ÀÄÄ­¬¬hæµeYh·ÛhµZä8F£ -^5ŠléAÞ&KÜÒ^Û)œO©8 3`|yâN§#½Wzé v]¬xDÆ4Rx‘hIâþf³ÉÍfÙlÅbq£Õj±#—Ë¡P(@BHéK¶m÷Ýw+I’`uu£ÑHaº<55…B¡ÀªNŒZ­†Á`€+W®p¯×ÓõjRL a|‹EÞ³g¦¦¦8—Ë!Š"´Z-N—:ÓC î]ä|Ý.Ék~)Å¢@ÆRGÎÔ„±&ìiæ«[IÝXv8QtŒF£-<œÑh„z½Ž¥¥%––ËeÌÏσ™±±±ÏóÒ „‚? ¦ OUzƒE°aJ?›@ízEKŽ!¼'Õú„J¥Â¶m“Ð'åÚÛe)ª¸ì%ª§6Õ’JŠžÁ†ah;j¦¦¦„™@ª«…‚ ` U-<ÏÓµÚR©Äý~?G ÄIDAT£ÑˆªÕ* ·HtdY–ÀRì§Z­Æ™LF'‰ÒÓï÷Ñh44~†¡`YÔï÷YA499ÉÓÓÓ(—˹Q§ÓA&“щ¡`R ™¥z½Îžç‘ŽãmÛ¼ƒýß,3ލFo×{Æ¢¢HW¶Ät†Á‚½H:¯˜hR)ÒÉÝ÷åû>\×E6›åZ­Û¶!è©(J§ Q4¦¹)À®ßïKë†l6«7Ú6¨(Šàû>c’Íf9]bU«““$A¿ßg©ì),K`v]³³³,æ)ŽcM“ß¾®—¤í¨€ë Ó›&‰™˜˜@±XD¹\Ö LT± ¶PÈå…ÅÈòG&¡˜K±_:Û…–ÉdP©T099©[X}߇(Rðz9·ÝnÃ÷} eÏÍÍáðáÃ[Ú‘Äd–J%LMM!ŸÏëSDÃáP÷±]gÜŒ«p[§<Ȇ( ä8§ ;Ž£i!A@®ë²ïû:eO=,AÀª?€Úí6ÏÌÌ X,’ëº[–´Šx´I˜Yš/$§¨T*ú\I „e­ž$œefò}ŸmÛÖff4IM™â8fß÷Ñh4t›S³Ù$fæ|>O‹‹‹¬Z°ˆ™u—çοI°Óžçá7ÞÐ…‰ëÇÁùóçybb›››ð}_£œŠi¦é'€î €mÛ¬8žËÅ"Kçäö{†ÁÒÿ•Ú’†ƒ Ðû ¸R© X,êž0©9är9ž˜˜3£R©@„/80ÎuÂ0d¸éÖZQñ`0`[°‹·› ¾ÕNyÚÁ |8R§ÓaÏóH ¹\ŽÊå2×j5DQ„µµ5¨—&"ÒTæq‹’j  Ïó8ضMù|—/_F§Ó!ÏóxzzZC¾¬ˆ[)îz½mnn²l)£¸ütèÐ!–Ù¯ú¨ßï³eY411!¼VäóyÊårœö5ŠÎHÂzHwú¨•F¬ð'êv»h4š ¶{°óØALí¨/ 1÷ïß¹¹9œ={VŠØ,öU0õååeôz=!Û‚™)Š"é€Ñø¾8m`œ(‰ãç'«F§¸˜h4`f]ü\•7!›i¤9;¾ïKYajlK’¸ééit»]jµZBÞÕ@œÔ%„ZY*•H6ýHw‰nWÀÕXæ†Mðh®=Áu]N’ëëëèt:,±ïÔÔïÝ»kkküæ›o‚ˆÐl6ñæ›o¢×ëáÎ;ïäV«ß÷õvçÏŸçZ­"âååe´Ûmd2VµVé¢'1=êeØ0 H§‹mÛè÷û,ÁŽãH7%1³˜–hiffFSé•§V«ÅF/^„çyì8Z­–{[­–––Ðl61==Ísssèv»:T¨cûPrܱ¾²‹”v0A“““4==Á`@’¸t:ZZZÂp8$Çq°¹¹©÷ßñ}çΣV«¥;S$ú)—ËT©T¨R©@•"É4M¼ôÒKèõz$6Ù·Á Y ÌŒ|>yŽtÝ@Õ¢IÈ»žça0P6›%iœ¤‰‰ ”J%†A «‚mÛ´¹¹ ×uéÔ©SRtB«ÕÂóÏ?@1imm ËËË$þ(’<äZÀÿn7ï¢VyÀÖø5 ÃýSSSØ·oúý>/--Añùyssõzï¸ã)ùþxÏ×J¥ÂФÅNÅb1½Lõ6“;Žƒååe&²d­qk{Üï÷Ñl6aÛ6Ën’†ÁÂI’&qY9ŠÙÇ) «@3³e»©{û¾fÖø–çyœÉdP,yeeE:it‹®<£Œ……£? Ð?ºi´ýpÛ¶/IÄb*• ÇáÁ`@–ea4!ÝQ¨¸ö²‰=5òù<”ùàGªKÓC¤é¢T*é˜_¨îÍf£Ñsssh6›zÕICø¡ÃË&O333˜œœÔ×ït:¨T*˜ŸŸ‡ëº‚½^™L†£(Òýk*’]R>ŒG£ù¾b±ˆR©×uEÑ_¶ô¦±Â¡¥ ;™ RB$fþ7Dô3ò‡Z­†r¹ŒsçΑïû†!©æ;ffÚØØ“ãÕrÌår‡tñâE «Ü@²R Ã766Ç1‹EVŽ‘ºÝ.A€™™iU¥$IXV…Â’hzzškµšî¶,‹¢(âN§£¹l6K­V‹Õ6c²êõ:­¯¯óÊÊŠN‰ˆ”ó&ñsâ䕦N§Ã¦i’`U¶mÓ¡C‡xÏž=⌟ÝA®;ŽL„R¹ý/…Báä¡C‡þ[½^_èv»ØÜÜ„ µõ—Œjµ* 7 $I¢Ôõõu¬¯¯cÏž=œÏçe¿–FÁÖ … …‚ðYB^Yê®ër.—CǨT*ÒÀÍD„n·«!q©=¬¬¬`mm÷ï߯©ó2ë“$A³Ù„aEêõ:×ëuí³ Õùiš¦4ç±°®çççùðáØý¥r¹¬',Q––^ùW{÷ïß’ JÏ~p]÷Å™™™“wß}÷ ƒÁ`AöÌ;)•«t÷Éüü<Ä9K•ʲ,lnnjÈ@ ¡ƒ ¦T.—µIIoºZ.—5ZÌÂ-çª]W4ò*çA wÈè\L¨çy(—Ëz’ýFî#¸Ôœ³Ù,æææpÏ=÷àÈ‘#¿tàÀŸÙ.K˲>àn& Ú­˜œœ\>tèÐIÃ0^˜˜˜˜_]]%µô¦™LF³‰U¡=EÇö‚ψmU˜ÆõèrŸØ›4×s4aii ÅbÓÓÓØ»w¯6t»©ôz%ªÕTQ+Ñï÷ÅQ€ø¶m›8€ééiDQ´%GQÛ"£T*ñìì,íÝ»ü™k„…-%ÉU@Œëlø:33³ì8ÎÉéééZ­ÖÂææ&Z­–¦÷Ig‰P9ÔÖd:<0N¾d©]155%_GÙi“n;Î;‡0 51V¶L^^^† ‰õ.X²?]½^O7ü_>ꉙQ=ËtÇwàÀââ¢ÞKH BBs]—Ô¿´³¤XÉS¾pî† ÍÒ×O¡«ÕêrµZÝ·ÛßWVVN4›Í^yåzíµ×˜™uŸ–w-Ë¢$Iôþ¾ï³tÝ×j5–mÕ¤MÙl–‡Ã!¾ñoÀ²,?~œZ­ þÄÌP1?¯¯¯ëN,Ë"µ&LÓ¤(Šd+M®’€æææøÈ‘#tÏ=÷ð»~sƒpÞYœ»%bÉhä_¿œÿcÏž=ÈçóÅqüòp8ä3gÎh? ZS—&777¡šíØó<Ú·oOOOCjEe2n·Û( Úß„aÈ333zÆ+J:¯¬¬ ÝnóÜÜ%I‚3gÎðÆÆ†Ò˜YèŽlš&K]»P(`vv–ï½÷^>~ü8æççÿq¹\þgoC Ôï{"Ç÷”Û- êw:]´ÛS©Üšö-Ëz1ŸÏ;‹‹‹ûǹ455…K—.éݳ:Iô!õZÙ£Ñh€l¬AÒü–ÏçÇo¥2Îv»~¿¯ãrÙ“T:šÍ¦6?‚éHö @¶! ¹wµZÅþýû—÷ïßÿ=‹‹‹—nå½ÓãOþä‹Åõõ:06AÝåtí¯êÃáVVÖþö­*,Ë òù|¼ÿþý•JeéСC,ˆª*RÇì8ŠÅ" ­Ýó !Wáödš¦iÕžÐtß}÷ñwÞI®ëRBQ¡b±È®ëJ_ñr¹\>V­VÛ·úÎéñðÃïþú¯’D5v”Ñ¿co2ƒ¿þõWpäÈ]oë!LÓ\UŽŠææænèœ×_ýÄ©S§^xýõ׌#¤••í?Ô G,ÍbJ-A²×(ŠpèÐ!>vìŽ9òKû÷ï¿å u3ƒ¨F/¼ðû'ÿ÷¿Kv:n'h8°çÏ¿³gÏ?z÷Ýwþñí~À rŽãìøP³³³A˽^oáüùó:ldÕîŒÍPš¶.¸~N^\\ÄñãÇqøðáùýû÷¯Þî÷¸Î0/\¸ø/G£^Úé;Ä€4˜1@Ñ»Þõ ÀüÁ—·ß÷®=õíÝ„¹\î³³³?tüøq9rSSS(‹$t¡Á  »2A@ÌŒ™™?~>ú(î¿ÿþýüsþÙ³ç‹_ûÚÿ~áÏþìÌË‹ûðùÝŽÝñË<‰jΕ+§žûÖ·þì¡?ú£?Æ¡C®¼ÿýïýᙙ龾}t»Ý¤Ñh`uuÍfN­V õzý~_7u§÷øTsÏž=XXXÀÜÜܾ}ûö-ÿy=3QÍ~þùß{þþàË™¦‰|ä>xð!‹¹±sÿÀnäQ¢Zñµ×¾ö_OŸ>ûþçŸ ù|=vreqñŽ8ðàs»-©|õÛ™®wÌ ÅJx±Óé,(´u¡Ûí¾ ™w:Û$Rªv*,ݧ îo›ˆ¦€ ÀùÌg~í]ívç_¿öÚë‹<óÌP©”›ŸŸý¿»ž•þÚ_û+ ?üÃO¿òüó_C·;Þ1pqq?-,Ìr¡_ýæ7ÿìo|üãçëésõWñÁG}èWLÓœ%ÒÿTzÇñê—¿üÜOüôOÿ£Ó;ÝûßþÛ~ôñÇO~Ê4ÍYfƧ>õ_O|á _l¼þúÅ›úzÂO|⣳ýèG^ÜÜlÿúc}àŸÞ̹o1¿ç±cG~us³=wñâe^Zº‚0ŒpÇ{ñÄßK««w>þøw_¸Þ…®û…ÎJ»¹}ìG÷~â;sæÌk8}ú,Úí.ÝÇ%‚•TO:Ü1Bãõ˜%F ºzŒª é®xÒ[ 0 ƒôuÇJ¼Úì$›Ë>ã몯ƒ×÷¸zíñy©JŸ0Õgp•@vuâè3ÒÏ|Íóš¦Éss3xðÁc¸ë®ƒ/ÿ§ÿôéïû¹ŸûÙ~’$Ža»~¿ÀupU5€ Pþ—ù_{ä‘Ñó÷{Þ@ƒM©™Ž´¨Æ"b¾*º«û?% Ëw–é:ôU¥ ˜E[®Ÿ¾¶`,rÏŸƒ(Iâ-ûP\}èûhIk±o½ÎUÅ€•²0>óË¿ü©òÕ¯þqÀàsㆿuð†pÍI4e|ò“?oÿÔOýýî¿•ñÆ__€ÅÅïZÞÜ<¢Ýî./.~×Û²çÿá?ükçãÿ;·ãke0€äV}â-)à;ãö]µ¿3þ|Æwðï(àÿ 4À.<ˆÎ†IEND®B`‚openchange-2.0/mapiproxy/documentation/pictures/mpm_cache_case_one.png000066400000000000000000000261011223057412600265010ustar00rootroot00000000000000‰PNG  IHDR÷üjÅíPsBIT|dˆ pHYs × ×B(›xtEXtSoftwarewww.inkscape.org›î< IDATxœíÝwœ]Eýÿñ×; ¤H(л鈕"R©*"‚  XùÙá‹( ¢b¥èW¿ MPAPzIB=4 Hÿüþ˜9Ù³wïÖìîÝ=û~>çqïi³sËÞÏÌœ93Ь’t$p20/oZØ5"&5.Wffý‡¤€Q¥MDÄ^ÊOwÒè Øb¬RZ£Q1k‹¤QÀÚ5›ˆw‘³’yÀš¥õ‡•‘îäànf½a/àÿ€…y}>°0±a92«0w3ë †•ÖßnTFÌ÷þíNà`{à5àQàÕ†æÈ̬¹xظ¸£±Ùér‡ºþOÒYÀĈ8«Ñy1«GÒ§?—6Ͷ7Ë[ÃIKú Ûè¼t×Üͬ7Ü ¼ü x¦¡92«0w3ëqñ"ðIÛÏFąΓY• jtÌÌ̬{9¸›™™UŒƒ»™™YÅ8¸›™™UŒ;ÔUÇI!Ýb4'?ή·ó–K33ëqîÕ1‚4Äç°¼ -=o¶.i‰šsR¿ ÐV!¡ÍD{ÇFÄÜn~ýff–9¸WÇ«ñ£®œ(iÍ ­=¯·o)`ùNžW0TÊÆBR! W ¤Œ9]y¿ÌÌú:w#"ïä¥!$‰¦@g ÀáÀ²8o0TÒPš0˜K7 :²/ïRà`R ûï’>Üœ,é;Àk$m %½8ØTX™,-ét`çˆhµÔ.iï|î À’¾< lMj’Û3çß̬ßêƒw’t¤pñnR¡ Ö Òe“¡ÀÀ¤K"ªÊ¸j.ŽˆW%ýødDœZŒYØ("æJÚx 8="uÊ‘ôðË6j³WDÄùØÛ€}"âuI›߈ˆÃ$=\7•òpiDœ×.¥÷%àC1SÒöÀñEIÅeˆëÃH/ˆˆïå^»+~[—¾|."”tðùˆø”¤«€õ#âä6Î53³êÌ$¹óæ.¤@©ïÂëÀ¤Öçב*_˫ءû¯ßSêéy+©3Ù½’îNˆˆ§:Æ’–'•¦.* Þhï¼2I«—•Ò˜–/—t;)€“Ï91ÿݧH-[Óvp߆ԂéÒÃmkff=(÷Q88”ÔÊðð—°¾|_ÒgI×ô#õ|Ú^1]ÒÀáunc˜U'·DÄI“ƒëtàûpppmDÌÎ×”>¬!é4ïTRÏýÀF¤Î…[“¼™™õ²|ûäÙÀ椞ò×ãÚº´ZUC$LTbIgçDĽ’®.‰ˆ‹»’°¤Oïöþ–w]œ&iBDü´d~ \,é_¤‚È’q"©Äñ’¶~ÑN§—Kº†Ô<³0"NÉë®$}v‡tMIÒˤkóË’‚ösí¤6p^NàøvŽ73³ž18&"vûd_!R/ï¥mDÄ+’Þ ¼ÓšîÝçõ"bœ¤¥€u#âÁ¼}$ð~ÒµŒ;"âÙRkkDÄí5io<³JÛ†&ÕÌoˆ·òö1ÀÆÀøüøxQ:“ô.`zDLÏë#roç4f•ÒØ("n­ù{»“:î= ˆg%mß·ðå׺3pcñ¥’4Þ÷TæBÙĈ8«§ÿ–ÙâèÌ 6f½%ÿ^OŒˆ±ÎKwQ…ú XîÖ_8¸[_TÅà>¨ýCÌÌ̬?qp733«w33³Šé“Á]Ògrg7333ë¤îy¬ööŽ–{´# -[{Ü’*Íù\gzF$ ÍãÑ×û;Cò}‹Òk/offfýMÍV&iSÒ˜ï3r@ýIù–³|ŒHcÏ/ ,!éZÒ`0[gKšEº…m"p;°ðCIïF”.éEàÛyЛ_›æ¤ŸŽÎƒÑœG{~c`UI_¾ Œ•ôTD|ª§Þ33³ÞÖ“S‘>ï´6piHÚ²­H“×|$§Œ'_ˆGóö¡Àñå¼~°gD¼&é(ÒD1gÇEÄü|ÌïH“ÜÜAšŒfVD¼OÒî¤ÉnÖˆç$ýGÒ†1©ß 33³^Ó“Á}„¤SµH3 íX瘇‘’&çÒú„WHÚˆ4Ý…y<à‘¤¹–Ïö’ôiRKÀXÒ|îŘóÅ<ì“Hõ#Ï=D¡ÏÁÝÌÌ*¡'ƒûQ¤Q㾘h1Œk¼@IìNº«`G`Yà·áÀ^#“Ü›Á³vG‚igj¦³iL;|þâSw¨3ëÑÀGI·'nN £Hdþ_i`ö©L{»fºhr¡l!‹wÍti ‡.ïš©™u–ƒ{ÅIZ8ø,©)t(°Té™À¿£%-Ccj¦õ‚é\ïºim0íLÍtaGß_3³¾ÈÁ½‚ò}¬G'+Óö»#€÷fÞ[œÚéÌNž_®™:˜š™u#÷ Šˆù’~"¾’jð_öÉÓçš™Y?åfy "ÞþÕè|˜™ÙâsÍÝÌ̬bÜÍÌÌ*ÆÁÝÌ̬bÜÍÌÌ*ÆÁÝÌ̬bÜÍÌÌ*ÆÁÝÌ̬bÜÍÌÌ*ÆÁÝÌ̬bÜÍÌÌ*ÆÁÝÌ̬bÜÍÌÌ*ÆÁÝÌ̬bÜÍÌÌ*ÆÁÝÌ̬bÜÍÌÌ*ÆÁÝÌ̬bÜÍÌÌ*ÆÁÝÌ̬bÜÍÌÌ*ÆÁÝÌ̬bÜÍÌÌ*ÆÁÝÌ̬bÜÍÌÌ*ÆÁÝÌ̬bÜÍÌÌ*ÆÁÝÌ̬bÜÍÌÌ*ÆÁÝÌ̬bÜÍÌÌ*ÆÁÝÌ̬bÜÍÌÌ*ÆÁÝÌ̬bÜÍÌÌ*ÆÁÝÌ̬bÜÍÌÌ*ÆÁÝÌ̬bÜÍÌÌ*ÆÁÝÌ̬bÜÍÌÌ*ÆÁÝÌ̬bÜÍÌÌ*ÆÁÝÌ̬bÜÍÌÌ*ÆÁÝÌ̬bÜÍÌÌ*ÆÁÝÌ̬bÜÍÌÌ*ÆÁÝÌ̬bÜ«cˆ¤å 33k¼!΀u›•€Ûs€x˜\óøðBD,hX.Í̬Ç9¸WÇ ±€¤1ÀÀšyÙ8 ?_EÒ\ZýEˆ˜ÕûÙ73³îâà^Añ ð po½ý’FÐ<ø¯| x.ið­ÔþsúffÖG9¸@ñ60)/-H ¬JóÀn4ÿ1Àk´^ûŸó{øe˜™Y+Ü­…|M~r^n¯wL¾¶_þ[ûæç«JšOËZ¹ö?³‡_†™Ù€åàn]ÓéÀýõöK¬Nó¦ÿíiªý^¢õÚÿ´ˆˆ~ff•äàn=""ÞžÈK ’«Ð¼öÿAš +IšAëÁÿùˆ˜×Ã/Ã̬_rp·†ˆˆ…À”¼Œ«wŒ¤eiü7öÊÏW“´xžV ñf¿ 3³>ÉÁÝú¬ˆxxx Þ~ICiÙô¿ MMÿKSi½ö?ÕMÿfVEîÖoEÄ੼´ IÀÊ4¯ýïHSA`¬¤·hô‹çÏç¿afÖ¯8¸[eåZù‹y™PïI£hü7öÈÏWÏ„¶šþgôðË03ë4wÐ"â ࡼ´ iI`5š7ýoISÓÿhàeZ¯ý¿”û˜™õw³6DÄ\à¿yi!×ìW¢yíàSyÛÊ’fQœÿɤá~g÷ðË0³ÆÁÝl1ä¦ÿ©y¹«Þ1¹c_9ø¯ìJSÓÿÒ]ukÿñZ¿ 3«w³oä¥IK†û-7ý”¦¦ÿåHs´ÖôÿboÎô—‡Þ¸Òc ˜õMîf –ä³y©KÒŠ4¯ý¿øDÞ¶Š¤ÙԿݯ¨ý¿Óù}EÒºÀTIçgDċݕ¾™->w³~ "¦Ó€{êí—´̓ÿZÀN4Õþ—¤i¦¿zÁÿÕNféTÒˆ‚ß¾,ið㈸¥“é˜Ypp7«€ˆ˜<–—òuýòLk{ÒüW^¥~í2ðBy¦¿ˆI& $´;°­¤7IÿOdÖ8îf@ÌEо­Þ19À—kÿ[ûçm«JšGËàÿ#à—ÀÒÀ¨¼œ üXÒeÀ/"¢nÃÌzŽƒ»™›æ_î«·?ÏôWþkëª9t©üx8p¤ç€Ÿìþ\›Y=îfÖ!¹SÞãyAÒ†ÀuÀ’­œ2(ïÛ8ø"ð$mt4³îáànf&éÀŸ€¡À`yý5`©óߤ~ODÄ;’NkLŽÍ–!’v"ÝW»$ðOà†þ0d¦¤Û"â‹qþö1¾§Òï­4Íz‹¤ÁÀ/“ÆÜ¸›tÿcÀÓ½yϽ™ÕWÔÜ?ÜA*}ÿX¸´Q™ê„õ»z¢¤AÀe¤Ä­9¥«é·¡Ëy6ëFgFıΈ™µn@D|/"®Œˆ›_oïDI_t­¤[%–·ÌÛÿ%éØ<©’–”ôIIWIú¤mòö­$#é"I»”Ò¾PÒç$Ý"釒F”ÒÿI7Jút+ù%éw’¾-iœ¤•$m&é·’.•´{>ô€åókø©¤$‘Ó/iYà3¥t·”tv9¯’ŽôáÒ1—tˆ¤¡’.Èù?KÒæÿHÌú®ˆ˜S3kÛ :Ûnjë$Ikåãö! CycÞu0ؘ|7o?’tìç€ý€)yÈÍK€³€³%­œßXØ‹tíÞyû·súûfæªí¥ éÒÂQÀÛÀ.À,àBà4R‡žïJZø 0="öŒˆã€a¤¦ÆWókzƒ4H’–. Ýâs pJ¾mèàÿ•þö7€…À)±p&ð›ÖßM33³îÕ,¸K:‘Ïjç¼é¤[aN¶ŒˆçóìX#HAn%àcùøƒ€ŸåRÿ¬ˆx‰4zÖ]qoD<ü•´æ’†´œ \E ¶úœ™·ÿoù{ø]DÌ! Ô1#çåóÀLZo™x9"Ήˆ95}ö˯ù@àRဈ˜@šøcUIëC#âÁ<œèº’~ߣ%m#¿fffÝfQoyIß¶!­h뤈xKÒ&¤ö%Ý| Ü SXÞž—j'˜Ì/­Ï+åçÒ4˜ïjÕäô‹Î:åsk½X ÎÃH3vMÈëHƒoÔóB+Û‡/Ö¤ñl~þàPR¡æ|€üÞ| 8š4U裤Á=¦¶‘g33³n1@Ò7IµÓ/ËIZ>o#é˜Ú“$­ŒŒˆ IMï[ä²—“FµšÜJªíBj~ÿš¤¥% Ééßl/i#I«“&Á¸ªüþ82¥yD_ãÀfÀ´Ü§àaRáa!ðFž£=¶^Êiø¤_sH­eãr3HýŽÍiüX&ï{¸ø{D…™ó$Ýì–_ßÛu^›™™Y·S;-ðÖH: ˜íõ•0k¨<ˆÍ³áÁl¬ÏÈ}¢&FDeúFÕë-offfý˜ƒ»™™YÅ8¸›™™UL·÷×Õ<,/é÷]=ßÌ̬¿ërp—´„¤Hš×—"Ý.6 ¸‹4cTqìXÒˆtÛKzo)™á’vÉC¹þ Ü’ÏS~_Ik·’%í#é}ùþ÷w;JÚNÒz’–’´Acþ#¥óÖ“ô®š´ÖÉ- «Ölß*ߣ¿›¤•ò¶$mÕÉ·Íl@‘4LÒú’v•ôY`[š†“6³Ò¥ùÜ%}tÏùõÀé’N"Ý[¾° iÈ×ûHÃÈBªÉv$Ý~WÞ~.ðtNã˜<@Ì‘Àˤ!p¯ž"· pBM>ö! uûw`WÒ½ï[îAß“4Îûhà"Ò¨tã%ý›4ÜT`¡¤e"â<~üH÷º"鹈øNV÷&Ò ;OgI:—40Ír’ÉcÓ› (ùcE`V–UI#J>Oúÿ›L½ò©Fä×l éRp'à¯EÄm’.~—t °kDœT>8"î”ô-i$©0ààn•£4ãê´¼G‘ â“i à÷’F…œ L‰ˆù5ižFÓÐÍfÖCºÜ?@Óð¯÷“jÕ]QÔàŸÖ)…’Ž.‘¤YÖ®®9ÿ à‡Àã’þJ!¯ž;K?2»»Jº6¯Þ%é9R ÀTÒÏÒ9OOSóHtÆŸ2çqfîg`Ö¯äZ÷XÚ®uÏ¡©Æ],wÏ#âÞϹ™uDWƒûxRó÷x`SR€oÏ,Ò,eíMPspYžböIk—gk‹ˆgCóuÿsI×òþSçï”'­¹ X*"¾P>@ÒÁÀƒñ-IÃo¶‘Oëg}ZnUj«Ö=’T-î À¥ùù‹y¾3뇺Üÿ8CÒ?IÓ°þ´çÜüBÒ„ˆøQ{çNm§’Æ‘_ ¸§fV$JšÞõMRþq1CÒ›¹ùïVZÎw-pŒ¤ó€{H=óEê3p²¤)¤æþé˜õAù’ÕÊ´¸W!ÍeP[ëGS­û­ÞϹ™õ–.-Ÿk·»7çùÕɽޗˆ'[9g5`ˆ¸UÒv¤æòȵŒµ#â!Ik’jÚSIÍý&¹·Np_Ô‰o>pSÑL˜ü6%u蛬ל»ðàáˆx ”Þ¤‰åÇ#âIÛGÄø|ÌÀ‚ˆx!¯ï ÆcËWKîÜÙV­{8ð-ƒw±¼Tû¿ÒWxly닪8¶¼'Ž©÷þCÒ`ÒõìÖ÷JÀLZÜ“óL‡ý’ƒ»õEU î]m–7³:$¦õÀ½:°$éÖÎrÀ¾©ô|j¸Ämf‹ÉÁݬƒò I«Ñzð^xƒæûIR“ÉÀóñvïçÜÌw³LÒr´]ëLº²¼ÿSz>͵n3ë Üm@´$m׺W ÝyQÜ×ÑTëžÝû973ë<w«„|§Fk{5@¤;'ÊÁû_4uR{¥Ù63ëîÖçåAŠÚº5l9Ò¸åÀýp5MàÎéýœ›™5†ƒû&iT_BTR[“¬,¤ùä#“hªu{À!3³÷&>ôiÒD=Gzw÷ôßk«Ö=x…æû~à*šjÝóZ¦lff­qp $­G/ÿ0ÒØû»£ì-Fš" ºÒÖä#óhYë¾—¦Z÷ë‹“33kÉÁ½Âò0¼{'#H3}7wàü´¸× M…[LùY,w—çç/ÔNùiff=ÏÁ½‚$¾|•4"Ú2y×;ÀqjümMù¹ 0›–µî;iªu7üz½™™µäà^!’¶Žv!õÚ©oFKú/°-§ü\‚§ü43ë×Üû¹ÜamS𮥫S&{EÄ›=733k ÷þ¯è´öd~\ IjR,MSÀ¬/i¿ˆ˜ÑûÙ53³žæàÞÏEÄS’&QšòUÒÀú¤Nt›ÛcH€JÚ#"jLÎÍ̬§8¸WP¾/üѼ\^lÏèÖ"ýM€£$ý6"&5"ŸffÖ3܈Xü7/W78;ffÖC5:fffÖ½ÜÍÌÌ*ÆÁÝÌ̬bÜÍÌÌ*ÆÁÝÌ̬bÜÍÌÌ*ÆÁÝÌ̬bÜÍÌÌ*ÆÁÝÌ̬bÜÍÌÌ*ÆÁÝÌ̬bÜÍÌÌ*ÆÁÝÌ̬bÜÍÌÌ*ÆÁÝÌ̬bÜÍÌÌ*ÆÁÝÌ̬bÜÍÌÌ*ÆÁÝÌ̬bÜÍÌÌ*ÆÁÝÌ̬bÜÍÌÌ*ÆÁÝÌ̬bÜÍÌÌ*ÆÁÝÌ̬bÜÍÌÌ*ÆÁÝÌ̬bÜÍÌÌ*ÆÁÝÌ̬bÜÍÌÌ*ÆÁÝÌ̬bÜÍÌÌ*ÆÁÝÌ̬bÜÍÌÌ*ÆÁÝÌ̬bÜÍÌÌ*ÆÁÝÌ̬bÜÍÌÌ*ÆÁÝÌ̬bÜÍÌÌ*ÆÁÝÌ̬bÜÍÌÌ*ÆÁÝÌ̬bÜÍÌÌ*ÆÁÝÌ̬bÜÍÌÌ*ÆÁÝÌ̬bÜÍÌÌ*ÆÁÝÌ̬bÜÍÌÌ*ÆÁÝÌ̬bÜÍÌÌ*ÆÁÝÌ̬bÜÍÌÌ*ÆÁÝÌ̬bÜÍÌÌ*ÆÁÝÌ̬bÜÍÌÌ*ÆÁÝÌ̬bÜÍÌÌ*ÆÁÝÌ̬bÜÍÌÌ*ÆÁ½“ô)Iß—ô„¤õ/3³þBÒÀÍÀò’–tqƒ³Ô-†4:¶XFï*­¿?Sëƒ$-, †K ¼ ›33†äçïžm\VºkîfÖ><  L6mhŽÌ*̵<3ë ƒ€1¥õ%•³ÀÁ½{¸X˜×¼Þ¸ì˜™õ;hÞWƒòÑ­Üû±ˆÐè|˜™õWñ•Fç¡'8¸›Yo¸øEi}!ðBƒòbVyŠˆFçÁÌÌ̺‘{Ë›™™UŒƒ»™™YÅ8¸›™™UŒ;Ô ’>LÕîÆˆ˜&iG`àΈx¦±¹³ª«ýþ5:?fUæš{H:^Ò켜^³ïžÒ¾jö\Ú÷ƒš}»–öÍ–ô–¤G%ýPÒ°|Ìwò¾›º˜õ_‘†X8.¯ïÜÅôZômIKÚ£»Ò´Ê¨ýþY%é]’¶«³¬Ô i#é,IÛuG^{“¤!’v‘t°¤ý$m.©OV’Ü»fi<â¡Àç$´3°uiߢ÷W’€ÃKûËÛ ƒòö%€+{€õ€ŸÕüÝ%»éuüøiÒ„î²#ðIRÞÍ"𥳠²IDATʾIú¾=ÒèŒX»~ Œ¯³tǸ{GÓ|^Œ>OÒjÀcÀÀ_HˆMNoë¼Fqp_<¯#Ïæõc€y¤ \jí¬A_ûñü|—:Ç-ˆˆƒ"bà´¼mŸŽfHÒhI¿ôˆ¤’’ôþV?T{ß,Ÿ;HÒç%Ý-éUI÷Júl)íC%M”tjnQxVÒU’¶ÏûÏ"w€ãò±Çå}'Jº]Òë’ž‘ô·Ž¾&ë^’–ÊŸÍDIä™°•t ¤m%Ý‘¿7_,ó‘Ü*5-†÷×ì?$§÷³üý˜œ×Ë-8Ÿ'}ßÖÌ眙ù¼¤¿Iš*é:Ikçýcòþ{sËÖ=’®ËûÞÏ™"é¹ÜZ´NÞ·s>–4RÒ’î“´™¤+óþÍKù¿$oÛ¦Gßüþgð?¥e‚¤ÁùwfTqP~ŸGKZº|rÞ¶…¤•ë%žÓj1“eÞ¾Ž¤­$­.©YE)§;:¯j#ý5Š<çÔTª4VÒFJ“µåx`=à&àcyù ð|¿»rNsHÍö‘9Cò²‰¤¥ó¶¡¥ãŠ÷sdÍù«+µª ®Ù¾L>~°¤¡’6%"¼tr¾p))X?¬ Ìþ ü7ïߥtÎó¶“óóóKûwËÛææõaÀeyÛ#yÛñyýŽVò5˜ôÏÀkÀ¹À¿CóþGËù®ÉëŸÍëÇæõ§H%÷'óúyÿ7òú|àÒ0Ü÷ŸLÍÛ µ@E ø‘óv©yöFŽu–ÉŸGo·åçsHÓ›¹yÛ:ùœ#€ òwðçÀô¼ï¼ÿë¥ïÆC¤Z^‘f‘Fí÷ïê¼>¸˜œ×ÎßåUJù|›4Üò…¤‚ñyûÀùù‹À²9í ó¶gåç?Ëû¾“×›××Ìë/ƒýùô…ø[~ON¯³o(©ÆÀA¤a¯ÿ׿™Y¸¡ôùðµ¼ïº¼þ»ü™Ÿù6yÿhàšs¶Êû—/m?9çæ“jÒCò1cJßÁù;[œ³|>f›ü*ÿ/ÙÆ{Rü†ÿÚÊ1Ûæ×R¤ùù÷5ï/¾«?&ýFMñäüÒq?ÎÛ~“×w£)®0 دt|ñ¿s"0 XÐð/Q\JÆ%¤ÚzšÑ#ašwRí~fÞ¶>°Q~þ°TéÃ+>¸©¤³býè|L{Á½¢ €UJÛ‹/|{Á½øGûé:ü yý¡¼¿îÓhºD0Ÿ4ÚXñó|ÌWJÿÓyÛu¤&û1þ òBóà^ç7óúOòúßê|Ž£ó÷ô«À­yÿ/ó¾"¸¿DÓàX÷åm'´òý+‚û_òú ù»¤ÉrpÿRÿ¿ÛKÛžÉÛŽ*½Æ§ó÷3H?ôÅÿÁrùÿk0øVùµ{iöùÏÊ¿GŲIÞ¿aÞ7T€Šü¿¯üÛPÍ»#ó÷£¨dÁý-R+ ÿ›÷/M R»Φô»Góàþé÷êå¼þþ|LQ ›”¿¯ãJç,ŸÿÆš‚ë~y}°}+ïÉGKi¼M*¼|œ\ Ìß¹â7ô`ÿ¼¾Ø6S÷ùÀå¤Q×!‚ßÌßG‘ƺ`s`µ¼oðeRêMRh½œnÜçNs³üâ;Ÿô%Ýw×9æã¤¹¬gšröÍ猤å5¬ •Šo •lwŽˆ³;˜—µòãcñâ¢#æ·wbn>*š¶N%5=ý0¯¯Ssøí1?"æ³I_ÆåÚHþrR©zGàb`ª¤[:Ð f=ïŽüX|_ŠI3¦çÇ1’>Oªi\Mó륵ŸûÄÈ¿6¤xhú^µæ>€ˆx•T8€ØË.*=_­ø[¥m—÷EÄ›Àÿ’ZN+þ"â5RÍ~ð Òå)€óÚÉç@ô6̓{ñN"Ul–¾Gjš>,ö’¦ó àcñ‡ˆøuDü©&íó#âxR+!ÀN9í·€kI— &µ×k?#,¥|8?žg_«9o[`UÒïð `‹üú‘‚r ñORáöR¿§%µàlOú®¿I*àl^Jsßšäþ‹ˆoEÄ«HŽ}Iš5»"âü7—&ýoŒ!½¿SI­»®I÷ÇqhD|ÍÁ}1å‘?æÕÖ:VžG“®Ñü„ôaVsìüˆØ3"öŽˆ/EÄ-ÈÎóãÆ’Ö(6v$ˆæ¾â‡õ `ÙÒRûOõNéùš}³òãðÒ¶yq鋹+p/)ÐïÖ^¾¬ÇŸeñ9Î΃kŽû©·kDlBª Õ³uézà–ùqJ;yx/€ROì"¨—¯c.Œˆòl‡ÏåÇ÷”¶mVÞ—¯Ûô}œüJRyÊÙ3óãñ¤Ö¶Û#â‰vò9][”–I¥}÷Ñô½yž¦¾FEo&)µæ¾üX|ç†HÚˆÔÒr"©¶ZÌA0¢£i*S ¤åÇÂèü8˜P÷ÍÏ'’ 0õDÄõñ!Òïâ±yó>’–ÏÛ ö"Må4Ô$ucÍúòã!¤–N€sjò:²”nm _”nŸìÂß}Ô Ó¢#]þ‘Ù‘ôOð~š¦d]¸ØE©fwGj.ÝxXÒ?±¤Im©¹ž_®‡ŸNªm϶#ý8ØÆyeדšÞ¿+ioR+ÀZ’>IªÎ'•Jç‘®ÍZÿð4©¶þ]I¯{¶rÜhà1I3Iw©J[ö—t M­IÀÖjüç’zÞo+ié‡| R€¹4f/&ÕÌ?G*Tž \ i¯HTü¯iZKc$mQZ9"^ʽ.!¯ À¤>7ß#5•Ï#U`Ž’ô;RZ=×R EÀ š;4§ûçˆøŠ¤c€Ï´’¿ÖÒ¸‹T«ýœ¤ÇiYs4?öˆÉ’6¤e &ï;ŽTºžtiòé¼kH>§¸ dér×”|ÞF¤÷£lvÍúõ¤‚é¤À=“ô¦”î|`§\¡DÒÖ4UÈZ¤ëš{שæWn-*jï3IÍ«ÖÒ§€ûKK$Ï"õúéwâ9àxI»FÄtRÇÙ ½Ç/’î,úTÿæuùñHII¹Î:‰ô}:€Ô1¸Ù]ñ(ðR¿¡'%—ôéwsKêÛ’ô=šB*´^–·ÿ%ÿþ?Dz_†OK—Ó|”ÔDߪüÛ}.© 0 ¸("fæ}ÿ&ý_,Oº¤y»¤gHý¼Öj-MÏ gf‹MÒ×I?ôEÄÁ<çjà#¤»1zµæ,i)Ò­y¿&þ_oþý¾.·´mTg×í¤ÂÿѤÚèÏ#bn®Eî ¼Tô’´-é6ÞUI5Ý?Gă’!ÝRvEnAYÔéîõˆ8=Ÿû¡|î4RËÏá¤Ë3?4œ¦&ñDÄB¥Ñ·nˆsk‘*ÓH• rË1I»“.Ž%õ3™\SÖš÷d`wR_‘Ta\ JÇíAº_¤9>§9KÒ‘¤~!EÄã5鯜ßWj÷çÛ÷öÞG òÓògq]DÌÉÿ£€ßý­ÜÍl±õÃྀÔrù<©ø›½ù÷­gIÚ€t‰à`%RSÿƤŽlŸodÞz‹ƒ»™-¶\ûZtMö±ž³)©2)"ÚêxÕírÍt©#]íõPëçr­ýR_ H—.NŠˆY­œV)ÿ4f äÏÝIEND®B`‚openchange-2.0/mapiproxy/documentation/pictures/mpm_cache_case_two.png000066400000000000000000000471741223057412600265460ustar00rootroot00000000000000‰PNG  IHDR® œ!RsBIT|dˆ pHYs × ×B(›xtEXtSoftwarewww.inkscape.org›î< IDATxœìg”\ÅцŸW¤€ DQ‘M2˜L2`À$cÂGlc¢1L´ 6Æ`À€M9g0YäŒ @B" R}?ª¯öîhfwfvvgvUÏ9}fnè¾=ñ½Õ]]%3#‚ + énàÏföX…õ~ìff;¶OÏš]ë,à]3»°½¯ÕUéVïAÔù€Y«¨70oûRй€Ù;èZ]’õî@3’V¾fÖn6³±’–ÖÆwšÙWéü™u%/€»Íì³\{³[3÷´rí¾ÀÀBÀXà63û¾àœy€Í€×ÍìÙ‚c âÿ›÷™Ùi7à'ÀŠÀdà!3{· îæÀ@àá2Þ¦ Æâ’t»¤Çså‚z÷)h’n*øL/®wŸ‚ºóàR`°0ÐWÒÀ}ÀrÀÀK’¤ówvúÛ¯Hš@Rwà!àd`eà~`ή}4.<}€§%Í”;>/p° p¥¤‹²’Öž~¬<'itø§ÀaÀÀšÀPIkçêþ¸ Üü¸Œ÷©b$í.é©ÜïíiIs´ÇµêŽ™5Dž,Wî¨wŸ¢´ù3Zð™ÞSï>Eiöù¬Ž[ï§ò!°E;_ó"à-@i{.à`ÅÜ9×g•¨=plz¾#0èž¶WIß³Ë臀7€­ÓööÀT`´½ðY®íaÀž¹úG–hûhÜ’·§ó§í^ÀDà¨vxoO(ø½Ôû{Ö%† ƒ`Æf. gn»#Faî³ôO‹¯üNRv|!Ü*BÒÜÀÁÀúÀ€´B:o%àf6%m¿|^ꢒû¤¶zó‹æNyÉÌF˜Ù{É¢$é`)`cIë¤sûˤv{‡¦v—ć¿È½¾7ÍlLj÷IOµö-ÂAGóqî¹áóBSrû¿NGàŽ ;šÙIÅEÜ’é^Ðvávžsð9¦Ìì3I÷Ó\´'œ?%µ—‰ìu¸…š?>¼¹°'ð.°3nue},üŸm©A4Ì0x ˜<ˆ›æAçæààü3}³¾Ý ð?ò™ÙÓY†§ã·&Ñêü"W÷Y`ÝÜ<Õj”ðÖ“Ôw¹6‰Öœ¸ÓG«˜ÙÀ«À²}|!×ÇûÍì3› ü²àõ-&iáÔ¾¸#G{0 æ€×ðßÛ÷-Ö褔eq%¯™¥pÓ¼wÚýœ™=W«Ž˜ÙŽiBö%3Û¨VíõÃÌv‘Ôx?>Ó†d4p°<îå÷<|saf_HÚ¸JÒ“øŸïòøÎé¸SÃù’6½ýÞËU¿Øx[Ò½øר×™,é*àI/VÐÕ}›$m<‰Ï} ì ü¸.y$®Ž GvÝ’þ‚;œ\ ¬¼RÁuËÆÌ®Ký¸¸ÅÌ®më4jj.q‚ÔŸ´í]pèD3;¡¦i®­žt rÂÕ¯Þ} Š#é( Ÿ™Õ×ZøÞÌF쟷DzáÖÖsÙ<˜¤Åp¯Ágqë½—™½™Žõ6ÂÝá#’•Tìú+áÞŒã^€ß˜Ù’úã/åÎ]xÑ̾MÛ}q¯Á¹q|ÂÌ&¥cýñ9®áÀH`q˹ÓKú)îÿ8þ_:ÑÌŠŠl[™„«‹«;þF¿‹O8®Ü®= ‚ Ëbfo•Ø?¸¹Ä±øTB±c?Ð|ýV‹£@föMC|çö|RpîÛ_w—h÷ÜÅ?ãÙ‚ãO¶Ô¯ 2Ê™ãÌef‹gµs‚ ‚ EZµ¸Òdãg­AA#yAA«„pAŠX€A—%­ñ€/rΗ‰ÖšKuа4¢puKA4'பSëÝ¡ Ÿ´@y`U<`ïòøz«Oñÿºž©ÌLN¡—žHåi3û¦ý*§…kàϸ ~¯´ø¹ÃÿMÈ•ñÛ%Kr¡ ‚  Ö†í솯¡z ò~'pR‘:óák²~Š/t^VÒxpßû:ªïAu”9cM¹On÷A’vJÏ7·‚ü3mà[3Û£•þOüÖ»…2g©c)üK1¾£Lñ+,fö]u/7‚jH©CþŒ/:¾Ø0[˜ÜiÝØõ© iVjåô²IIéZÃ¥Ž¥ºÅ˜L•bˆ‹xŒÃAIsᲄ÷¦¶Ž¢˜ÙD®ÃElTòz…‹[š/ ¬R‰h¥¹Öí€}€Õð<^¯àŸë$Ü?$éM<Ãòå•Ì›™Ù•)éím’V /ÝŽ§Õ ÈId@îzDäÚSÆ‹Þø¼áA¸CC!™œ‡Åý¿‰-´«^rA¬Æôy øMrM/·ÞÞ¸`¿\Ü[Ê]>Yc«›àk¸N*•9¹Dw÷›Ù¹åÖ© íñÏðÚJƒ;Dä ŽÖ–XHZ8­)x>½‰ÀXà^<‹ï Ù¼œ¤cñ4öY¨µrÊ\ÛÅæ{IšJ™N3¹ç?Ã-%Kk©Zt°‘´p >Ôû33{¥Œ÷p2)N¡¤yðaÕ—%ýŸ™=ÔZýÄÁÀS’†¤H5ÃÌ®–t%0BÒÛÀe¸ˆ½_ËëtVÂâ Ú•°¸:Iw_à–ÇmÀ-9H: ègfGÕ¸/åÌ–~À¯€'qÒéÄŸ«Êi&ócpïÕrjJY’ëàq©™Xæk<XÚÌv¬ø j½íøÆºÀ¸Ñû©×•rx ‹+‚NCšë j§jæ %ýècfÛµpÎL¸ˆ­ü8xŠÒ^¦ó–8–/³âs‡ßÇH:‰ÖDp4>wxîSx¼êô)föƒ¤-pËpi|.r)à$àdI#h±ÑÕ\£³Â]„4Ÿtk½ûQ-ÉÂ8ؾ¥óÌl’¤Éx$CÌìš\»Íç¯ÁÅðŠ Ýü¹çãð˜‰Û3½u(IUG¤IåP\ àÿÙ™ÓÎÒÀÉxLÅ·ñCÚú^tB¸‚ h6>2³gÊ8÷¯øh›E ¦E£É–XŒMK ž.1³W[ª›÷=î€sðü½›ÕÌ–†úr¬Ï°¸‚ ¨;Éq5<‹qKçýØX¼Ìv×v³†V°>ì0àIç·ädafÏKš$i3{®Ì¶[ê·ða¿ßâ"5wpy¸x|Fv‹+‚F`)às3û¸•óÖž1³O[:IRwI§áÎ ïâ /Ã×´#éÊÀ·EÌìE<ÀïÆe¼†‡€Ÿ”q^‹$'•‹µ€sq§f6ÐÌv7³ÿÎÈ¢aqAÐ, ¼UÆyËà!œZã7øú§Íì³üIâ‘5†JZ©Œ˜…ûákªZâ5`Õ2úÖ³áÞ’]v¨¯­„ÅA#Ð_dÛƒq(‰¤Ù€c€= E ÀÌ&˜ÙîxÔùcʸæíÀz%²‘çy ÷îkföuˆVË„pAД+\hî¨PŒÙ€îe¤9ØOÒ-”â~,ÖJ{¯ãk«‚v&„+‚F ;å ×{´î˜ñ=žu{–NJkœ†[–qÝçie0y9~%i`ím „+‚Fà[Z·¤À…kPK'¤%ÇâÙŠw´\ §?¬\ÆuÇâ1[ãt ÍE©MVR^”žÍïK¬ƒ2á ‚ a0³/%üSÒº­YiXîpI/C$}\¼ŒÄ-œ%SÙ x¼;¶¥v“ÈÍüþ»³¤Bki^`<.<âëÐÃÝëó"õik¯#¨Œ® ÚŒ¤î-e ®‹p+çÿð­bfWKºøÂi`!\P†ãb²ð0·¤•˜~¸./L³ãpqú0øOÒ˜Í-ͬ$I[3™Ù¡mzåAY„pAPi¨lC`àLÜÊi3ff’öÇç®îmÍ:Ê1YãF¦¥ßãô5Í-¢1¸Kü4‡3ûTÒMÀ»fvX×ÞøO™ý ÚHW!©?î@ñ[\vlm>ªRÌìeIî“´ГÖ=îf¦¹§Ýà}|x0¥±ex"io¯¶}Ú8 XÛÌ&•QåhàªÜ7èB¸‚ (I²&öÀ‡Ùúâr£C<Š{é«×¦^j)+=™~MÒ»¸“C¶} °°½™}Ù/3ßïíðìÈ[—‘Ï‹3qw<3sÐA„pA0’ÖÆÅjs` >”1O¬x.°‹¤b¢47ð9Ó‹Ò£4·’¾(£/û^´‹™•¢©"Ò|ÝÁ¸olf/—Yõdàïföq­û”&„+$͈§é‡Ï[ÍÚ ˜ 6ÌDéàšDéC3›\‹~%—÷£$=\'é"à´Zy1JZİޙ(³Þ:xlÅ%kÑ |B¸‚  “¢6 Ä]Ã,( á"s?ð|if [sÔR†Yq/ÂCjèß"fö€¤•oI:¸,EŒ¯I áC}Ç—»Þ* ¡þØ£ÚëÕ˜äáWJ”Ä-§ÑÀ¨\y ¸6·}ð4°)°žZdE\Ìãs[ßâÿ½Ò¥gýè~,i‹Z9F´F’ûEZ‡u8p¬¤Ë»€çZsHÎ ûâ!š®–7³qvårÜ!ã¾ ë5 „+” | ¥Ei ž#jTAš{>®µ ¯Yl»ä&þr*ÿÍŸ ±,þg¿ °8ÐXxUÒÆföz ^vY˜Ù À¯$-‚mž ¬ i.ŸàsqSqËqI\ŒçNÇÿ lSŽk|!’NæÄ­´ „pAHsJ¥DiA<åüXš‹Ò3À ÙvG S™ÙWøZ¨'ð¨YÿçÃÅl9àIç›Ù[íÝŸ‚¾½Gòl”ÔXX·4»Ñ”sð&àOÀÛm ¿$éh|1óz•F¤jGW´)‡Ó¤¬L¢¹(Ä£gÛc«I‘ÑQ¤ˆc†.KÎ ÏQ$B{-ô|iÀzU -5$„+è¤!¡ÑµòTk+’æ eQêÇÉËiž3éæl_,Xí¤5i§¿Ö¯ UÐN„p ‹¤nø:¢ƒ‡ÍìôºnO|-R)QZŸ;É‹Ò(<“n¶olGyÛ퇤¹ñœ_“€5ÊÍù´/!\AÑæ~öÁÀöÇ“øQÃöûQZ”Â'ð?¢¹(½ ÜžíKó>AFÒ&¸ëý¥ÀÉ™'^«a†‚I‹ákÚvÆÓ´ü²Ì »AÂÔIƒð?‰=Ò®Þ§LnL2êÁôë–îÉ=oŽ ñIkå¶Á‡¦—®–‰ØƒMWPI½pAù¤ãûÉÙb_ÜÙ"[ÀÚ­ÄéÝÙñ(÷Ñd-ÅäxPK–ÀEëbàæ°°:!\A3$mƒ‹Ë¸pL–ô8pŒ™=Ue»ÓðïÝdÜ3¯%áZŸwº0朂öÀÌ^ų8ˆRÁŒË–x̺ÙL,zë÷§HÚcf˜Ù¯Í¬'>—µ žA÷Ràà+|xð+<.x\¼=§$ÍSÝË ‚ «WPÈDàRn`e< è`\HöÂÓYTMŠ:0x8¿?¹©/,‡îYÊYxIÒ¶ÕZ|AtB¸‚B ÓT<“ÒGü3mÏ×^NÙm‡¦2äy¸$0HRïH#36!\A3JD{ÈÓ=ÑQ}É0³‰ÀK©A0ƒs\A‹HZ•}xÏ_AP7B¸‚’Húð ¾(ø]`ÃpG‚ Þ„pE‘´©ADÅ‚ á ¦CÒŸð=qG‰5Íld}{Aà„sFÐ IÇ'¥Íoñ¨{géÝÍì²zô-‚B¸‚éœ{>p\ÁñW€® êFWPÈ0à‘Ž¿ÓQ ‚ (FWÐ 3;8¹Þý‚ (E8gAа¸‚AÒÆ@?`8ðVІAP1!\AG1?°DwIãpŽGä 7³Ñõëb® C0³ÿÔXœ»ðc`'`II³á ž‡Ó\ØÞ2³o‹4Á FWÐᤤo§rGþ˜¤á‚–•Ò㢒>¡ÀBKå3³{AÔ•® ¡0³/(žÚ¤;°0n¡- ,l—¶ûHÊ[i™°½)P‚ ëÂt Rº•©Ü™?&ivš,´¥€_Ò”¿ë3¦·ÐÞF…•“® Ócf_Ϥ2 IÝp+-µÁÀ6éy?IoSdèÑÌÆwXçƒ ¨˜® ËbfSñt,ïwçIê ,AÓÐã/Òãâ’¾ ˆÇ#02µA á fHÌìkà¹T¦‘¬´i>ô¸Uz>gÎJ+ôxüªãz36!\A#YTï§roþ˜¤Þ4÷xü9ðÜJûšâï§ù¹vCÒÀ03Ñž× ‚F!„+Ê$y(>ŸÊ4ä9_Òd¡- lžûKAñÅÖ_Ö¨kO/Iz8ÞÌži­BtfB¸‚ $ïÄQ©ÜŸ?&©>—–Yi›¿–ô Å=ß«ÄJ3³O$í <l(éU<Í]á9tEB¸‚ 1³o€S™F²Òæ§ÉB[Ø8mÏ#é]Š{<~^â:I:8X ¸øBÒ ÀUf6©ö¯.êCWÔd Nåü±öjqš†† Ò’’&2½…6÷œ<¿å€>©œüEÒÙÀáDtB¸‚ ÁH1_N¥’æ§¹ƒÈ†éq^Ü¡d$wÙ‘t)pf3:3!\AЉ0³1Àà¡ü~I³àv "UgKûIzø£™½ÐŽÝ ‚v!IA×`Nà` g çuOeàyI·¦º ¤9%mß×Û1v®e›ý$íTË6ƒæ„pA'GÒVø<×ÊÀ¬ÀxàK`ðð ð08ØXXØø¬ã{]’E¿tàõÎÜW¤K$åÛXø[›z´H A'EÒLÀiÀöx³w€7€÷hZD=º5×zwpœ11³5hfc\³6_ú× Ý aqAç¥p¤™-hf+™Ùfv‚™]af˜ÙÈZDíô+IK'éMI›JšOÒÓiZvÞÒ’‘ÔCÒ¯%)é/’>t½¤rçÎ!é_’F¦vo(¸æž’Þ’ôh²(³ý”ôI×HúXÒÚ’•t·¤$½*iÇÜù‡I:BÒå’FKºLÒ¢¹ãHZBÒ¬’^*RúIZ@Ò’FI“Úš=Õ?\ŸÎßVÒ 4‡˜]c¡Tœ¤×$ý:wì·é5]šúw¹¤Amý̺:!\AÐI1³ïRRÎvCRààd¬¼mfcï€_åNßx=õ©?ð[ÜME‡¸¾ä`½Tgrz&¥‰B wpªwŒ™3³!ÀÃé½ÊxÂÌ®NýûWzo‚á ‚ $I¶Â“sŽ‘t•¤…Óᛀ’VJÇß1³—rÕ_Í=ÿè…»å/€‹ÑtëÔ¦?ñ|ݹsÛÏæž/ŒIâ’ñ>|—ñJ m5CÒÀ©Àϳ(%’æÃÃyšêNæ(ÕF §e ¥úWø>ÍSfÛ3,!\A´ˆ™=jf›ãÞwŽLû'ãÌ~À>4·¶ZbnÅ­\e—òVÍH`Ióæö­Œ­´QIƒ«€í "íÜhf;›Ù©ø°džÉ”vt Ì]àu¸Z‘6‚ á ‚ $’‘´¥<¥‹pÑø wÊÅøüΊÀµå´ifâóR§KZKR_I›UÙÅ×p ìLI‹I:Xøw%$g‹;ñ9µ±’N¥0X^Ò<’6v+¨þ°SrN™=À̆Og$§}u€Ë*©AFW-aÀÞxà»pkéüiÍFâÂqu (œ1wÍϘ <‚¯+ÿóŸûzjøZЇç€,¸ð[¸›v}óW÷À6v~ifÙðà;¸ƒHÆ·øXÆ“øz·9ÒkÛ ¸<<•kãTü}:X ø³ŒmÓë¿+½îsKÞM}Ìøw Z@”õ@Ò७­IýðdŠýêÝ— 8’Žú™ÙQUÔ “µÌìÖÎÚI×·˜YYpg$,® ªBÒá¸eqIˆVБDäŒ ˜É/ ®‚»› ‚ Ý á ‚I=ñ5E+à u³Ç×)ÈÚ\.)´Qt8!\AÐÅ4Ó Ôb¸#ÀËøº¦³—Íì£4dž® 褤 »K1½H‰&º©af6©N] ‚šÂ€¬¨¸@½LΊªW?ƒ #á ‚"YQƒi.P+àë„2º8 ·¢&ש«AP7B¸IO{šÙëõîKP{rVT^ ¥¹uaEA3B¸›ÀLõîDÐ6Š ‚ÚÂÕ ’ÖÆï€–nÍ¢F§ãÝ€ÍÓñ7Ìì¡ÚÚ Oi°.0·™]–êo,‚ç2z¸DÝYñT ‹ŸwšÙW騦ÀsùˆÚ’ÖÁ#VŒªî•Õ¢¿ TfEe÷¯„ÕÂÕ:ÆÉõÀ“á-i3{.%‰»XOñp‚¤Íl¿mÝ<†ÇK6M‡² IDAT{*݉ßGÊ~8XÒÃf¶‘ºûãwí#€Ó$ý8‰èÎxŒ´?g—Ň.Ýö—#gE:LÍ*¬¨ ¨1!\åñ…™m i<Ôó9` \0æ6³‰’þ Œ”tQ.ˆf!÷›Ùi©­>f¶RÚ>øPÒyf6,_ÉÌÎÉoKºOFwžÐï&I'¤ì³»¤¨A)°¢2 +*êDWyÜ‘{þ"žÆ<½ø#)í7f6JÒÀñdqŸ7÷|M ›¤Ësû&à\3á’´™z}`NàGÀ›éºC%}„'ü» Ïô§Ê^bc#IÖΡ˴¢îÎ$¬¨ ¨!\å1!÷| нÈóŒx ƒRä3µžúáÂܾ ñ;ùBŽÃ‡·1³%]BóÏïB`?IãpQ»£HI}ƒðT%ç«hwÓ Ô¢xЉÌaâ^Ü£ïãRíAÐñ„pµ¡À’z›ÙIKàÎÏ•Yÿ\vKC|À4‡B6öH¢5°%pCîøUÀÀ)Àeùö:#)Ê€ßã1®²™ð¹¾B‡‰©¸8½Œ[Qgo†OW0³{%ݼ+é.<ÞÙföj™M\Š{$Ž–t ªg}Ü{°0õøåÀ%é:›Ó_t}ÚÀôŽÝirœ¸øM[Óx˜Ù«’~ Ü!iPj³&BAPoB¸ZAÒ`àj`ÇJæ³$ÍËôsR5©R˜ÙXIë×wJÚ.Å ‚ èÔ„pµ€¤þÀxfá’¢U†H]`fcÚ½Ó9Ìl‚¤­p‘¼Ï&AЩ á*¤Y€[«ÌìŠÜþ¼HeÃ~Ýhrœ¨‹H•Â̦HÚxTÒáfvV½ûAкŒpIZ˜ÇÌžªA[Â×@}<#éšÄªMŽÿö¯D¤RȦ¥ðĉ ¦2Wø»ðq3û´­¯#ÃÌ&IÚ>½–§ÍìÑZµAÐÑtzá’48·~ViC;óÒdAm ,‰ Id¶b‘ʵ=5¸5ðS<ÈîûÀ{À(©m/ƒ Úªç¸$í%éZIÏHzKÒ³’n”´Sr.hCÓ:÷è;èKqÑïÿúøb÷6\à àB3û¢ÒŠ’~ üذ=E+Ã̾7³=ñuf·¦ÌË•¶1ªqX­ûAО´Å9ã0`G`U`q|Ni[àܪ†¾@oà—ÀäT ||;LMuzko§…¶Õ²D·"$Í•êíkfo·áúcf§à.õվߧ{§×AÐ)h‹et?p.ð>d·°O:¶‡¤CÍì« Ûüof f;$uÇӈ̕JÿÜãü©Ìö˜æ™1³÷˽¨¤e€îföJ…ýwqÿ¯™Ý^EÝZ°ð”¤CÌìüJ*¦µ]Cpç–£Û¥wA5¦já2³CòÛÉi`;|Îi*.fm&9%|œJYHªôÚ[wVXI«áîê[WZ·V˜Ù7’¶ž–t¿™ «°‰óqÈ® :5YÇ•ˆ‹Àýµ YT)f6¹Â*[ày¶*åÀ™õNbfïgáD*­; ˜’¢àA4jג诓«„j…k|4‚ aérÂÕf6_¯ÔÌ)BÒ¥À7xØ£Á¸…6÷ÁôÎ!o™ÙxIÿN¡)fM‘Ô ø)°_…Uç¢B±KN0=Rø§ ‚†e†®¸øC‘䘅óh[ã I¼ ¬-i42©Ô´· žÏl;3ËGy/•»rû4͇³ ÊsŸgXj¥æÑ26+–Š&E ù+ðpޤS€KªH¢AP”KÂ[wÒá—̬ÒhèµìÃæÀéÀJföCÛêl,G“_(=Î‹Ç |÷h,*^kIàq`|¾*/lóãŽ$…Î!ÃÍì;IךÙ%-´¿n‘}LÆã.žÛZ~1Iýð€ÂýÚòú‚öCÒQ@?3;ªÞ} ÚŽ¤k[ÌìÚz÷¥½á*ÞÛñ?õÃêÙJ4xÑÌN+r,?–/ƒp mà_øìÌ}ºy4Içâ‹­gÃCepp†™.ѯ®'„«k1#W gW|˜ï3«ÆË°C‘´)“±èš¯4öz*ùzÂ_ëÑø<ÛÀž¸ûþ$¦wÝÿ+°1°$ž\Èö–t p’™ «é‹ ‚ ( „«fö¥¤_÷KzÍÌÞ¨wŸJ!i)à `[3û¦’ºiþjmàr3ûkA»sS|íG€r§Îœ·¶–ô8p¬™ ­æõA´FW ÌìI‡7IZ-¥Wi($ý¸ 8ÒÌž¨¢þ‚xn°¥ ™ÙÇxš“Grço\ƒ§M)üîôHeC`ÝëT<Š~AÍájä!¸ pWò4ü¤Þ}ÊH®éCð±ìË«læXàÂÖ^WŠÙx.°>¿UŒÌiC¸¶îä²Í-´ ‚6ÂÕ fö{IÇC%mÙÆ)¬ÓñˆöUM¨Kü÷xlé¼¥€ÛqGŽ xlÆY€I¸[ÿû¸·â;¸«ÿH`¤™}–ê÷Ã×§AÔ„®20³% ’´›™U™¢&HZf7pX¢Zœœ×RIËàᬮÇjd*£Úê¾AP-!\ebf×Jz¸AÒÀß­ƒ×$‡‘ ñ,ÿiC;?Æç¢öoé<3{Ø·ÚëA´ò©’§Üš¸Ý‹’~Þו4HÒU¸;úfm­Ù€«€ßGÒÈ :#!\bf#Íl]àÀ)’O.å5GÒ’.žÀ#m 6³çÛØì9ÀЮ¼81‚®M V‰™Ý%én`'à2Iï—÷·% ròà[wSß\¼îø’¶Mm¯ÜÖ¶‚ êEWHs\×HºØØ ±q牻IñKµ‘L.€An¬[WwâÖgµèkаy¥ •ƒ ‰®‚ñ^ \*iV\|6ǽñ–4_ÌûQzì…‹Õü@O` 0¸ODÙbàÚJIQ0îN1³kÙvAGÂUcRº»È¥"Ik™æN¥?¾þj 0¦•¤mFÒœÀÀufvA{^+‚ #áê’8} ¼Õ‘×M!¡îî4³ªdA4áUØEIVÞ½À#fvt½ûAP+B¸º ’–žÃEë÷õîOA-‰¡Â.†¤]³CÌìº:öc>`Y<ønAÍáê"¤,ÇçëwT0à4$¹l*Ëåž»õÇBç jJW@ÒºÀùÀp`53ßטO$™§åp×þ×q‘z wéÍÌ>Oõúá‚APB¸:1’ÎVÄ#ÅßZƒ6{‹3½5î™ ÔùÀ«f6º­× ‚ ¨„®NHÊÇu8°>Ÿõk3›TE; 1½@-|@“@]•ž0³)5yAm „«‘²1ïÇ0¼XÞÌ>*£^¦ŸƒZø §Wq×ù³7[ QAPoB¸œËp'\°f.–0³OKœ»lAYèN“@=\ÏCU 8‚ ^„p5’úâw×Mei<úÅQÀƒff’fJkµ ‡ùæ†Ñ4Ìw'>5®Ã_HA;ÂU$ ز;_*ó ‹Ïàbõ1°$°°¤eE€wi²¢.IïutVæ ‚Ž&„«$«é÷¸(ÞÀ#]ôJe0°pd:'¨[€Sðy¨ÉuèzAÝ áê`RàÛeÛÓãÚéqMõ8ðOàu3›P§®A4$!\íDZ°»4Ó{óõÁìf"uî(ñIºAЩáj# vóµ¾`7¨¿á5²N] ‚ ètá’´„™µ[¾«äP± Ó‡ÚÌ&¦ã ãÌìû‚ë Ï<>;ðnîü™~i?Iý€)f6¾H½fö]»¼!U ii`î"‡Þ6³69I:X¸ÄÌoK[Mšó\ÿÝÞ^7³Æ[SkfQ¢´Z€½îè ë½œ®·q½_{#àOé}¹÷ ³ôÙÌ\—¶³2èê˜ö=<—žO~ŽGÌ0àS`ïܵV†åÚ›œŽ/t=¶àZ¼’«÷fnÿ·Àþõ~ïr¯kH‘¾pp Ú¾+µµG½_g…ý¼Wä=¹°Þ}+VzHZ/iØ$3{24I½€UÓæfÖ,»°¤5ðu:ß™ÙЂc+}3m¾Þ1³os笛~/™Ù—T@ºö~øÝÀYé®óà#3;²’¶‚¶‘î¼ÅÿG™ÙÔ‚ãÙ÷\ÀH3û"wl~ ?ðM:Þlå³5ð"p*08Ø¡³}€í€ƒsõÖþ| lÜ‘ê\€‹ÛÀ%’ú7óWÏŽÄÿàîÅãPn…ßd\|ZPïDàyàïÀ?$½fe… nÍm?)©;Ð03û ¦Y"½ÈY”iü»ý‘™}XØxjk3{§Èþ…p‹õ`Lö»I¿—Ùñ|)©/~ó1¶Hû‹Ÿ¥óú¥Ý_YR¢ ­Þ#…ñï¹xè½U¯ ®)`üÿ½Y›’zã£xði¨¥wÓó‰–¬ùÜûùƒ™MHûºá–Þ,©Ýɹvû¦6Æ3á¡›©ëŠ9>,·ÿÁu^,wl 0°àø3L¯Ü_“»£Éí_¯Š»ƒ_§º¤í5Óö;5¼Yõõf½ï.¡PÄâJ_öosŸåûÀÏrÇ×Þ*ø®l”Ž=Qðýø’æwûaqÿ2‹ktÁþÒþËð5=†B“ÅõNÚÞ8÷ÞÀ×pMJÛóë§ç€ž©Îiß]iûð´=$× Ò¾ñ©'äþþRï÷/õ1³¸.(rl&š,ÙÝÒ¾{Òöi{qూïïÒ±Ìâú'¾nÑ€áÀOÓñ>øM^¾îà'éx¿ÜþñÐwSR»Ùç0.º†¯Õ:+W§:g š[½ßûµðž\žÎ;˜¥Ä9kÒü÷<¡à7›õél|} Ç¥Ç+rçšÿq«t®ÝÏ€mrçJûO¾KïG³7ðÒtb7\)K ׉iÿéñè‚ãÙõ:ü/û¢LVHç”%\øxþ2À’@÷´¯P¸fÅUxÑ‚º=p‘]èQplöô%>ö¿`A½Ÿ¥kŒKçõ+¨¿hêWïzÿ;èÇÞL¸€mhœÃ ÓöWøÝö<øâGn~ ¬™êl+ý&÷]ö>ÂUêsÈ„ë?û¿Kû‡/åÊ‹é;ž ×Íéü•Óö¹62á”û|ßÏ?4í{"÷ ×¶4 ¾TPN¯÷û—ú8$×Çq¹²b:¾þ§ü%pZ:÷®ô>vÏ}7‡¦ßÅo€_§º™pOuïNÛ§ã½ðÿÏ ñàÆÿHÇŸNÇóÂõð‡Ô·iÿ•¹ßÚpÜšÎßöÇ­¡±iû`K`$þÿ»f‰÷dó\ßâ{t|ö\?ŽÅ-ípY=“ ׸Õ}6þÿû}z?fKïáûé¼p+kBjçÀtÍ/Ió°©ÝL¸¾þƒ‹ë´Î¾š:˜¶ÿ™Îß5m?FºKÇo0³?™…sm/ ,Uï÷/õ%®qøŸmVçÎù¿Üo|40WÚ?˜¦›ð…Š´ ×?ÒöºiûÍÜ9«¿þ Ü—Ž›Žå…k­´ïâ´}\ÚÎŒŠÝÓö*¹:ýqQÌÄóš[½g·ð¾l„[ÈøO áIDATþk/»ÑÙ„¦Ó¬ÍçÓ¾ÓÓ9™p]TÐn6÷ú+ÜùÀgÒ±=rïqÖnfÕ’ÎÉ„ëø¬Í¼;üßqËeo\Å'àN…¬ƒ…fúXJÒjEÎ[Ò2øYæÁø~‘óŠq$ð;|~ìüÏðþr*¦‡â7`‘4LÒsøÄo«iÌÌò¿ÇñÏvüFää´ÿnüÆm-`¢¤+Íl8p>>äö–¤§$ ^~\Õ+k?n4³ÕseXîØ‹4…Â[ÐÂ,³ÖJ‘…^Êæ€f´$ðþŸönL;^ÀóéqbÁ9½Óc6_\Ö)ûmvÇçB·Æ?—i!놙=`fá¯ñwi÷’æÊµÙ#×ff}F¡¨`û’ô¸K*àó¬ù¾öεûmjW¥ÚÍ»Ã?Œ¹Ãÿä/ÀÕµÝÓãµf6YÒÀþÀn¸ªç9,•ŒÿšÙÃEÚ,Ævéñ3;-=¿®Ìº›ã¯í]\dÁ'£³±ûksçaf×'g”ã€uÌìZI×á?úo,çþ-é“ÔæaÀ“À­föj™ýêJ¼Š'ý\Ò_ñáÁårÇ2V•´¡™=˜&Y{áwß â–úö’–ÅoT‚Öy”&§‡i˜Ùÿҟ⮸5; ¿£¿-òLª÷FÚ›¶¿Í5sþgôyjó÷’îÃoÒfLJ¦.±äLefŸJZŸ£˜ÿ³ÁÌ~+éü~@jï8àÎÚ¼5cž”x1c¬™Jÿ×áS&Cñáì“pç”×ñØ^À’þžê.hfïæÚÊþÌ­àš»¤v¯6³$ØBÿ2G§Â6žÁßó}$ £¹ó 4}ÆÝ_˜ÙH˜¶  h,JIÇà7:÷á7'Y¬Ø,=J¾Í-ÍìƒToYü»–§Ð äÜ`ÙŸk›ðÿí{°WUÇ?«ÞÔFÁDÊGZ£–’â8–©ùHÒ™ÆÉfÊbj¦kÆI1•c>’¡ ŠŽ…Œ©)”N cƒh2Š–&äƒ ˆ^”ÕßµïÙ¿ÃïÞ‹—ß岿3{îoí×oŸsîïì½Ö^û»€9Q¶"þ¾ŒóÊ!æH¶UúM*áh4%5x :·Ói*D«áŽÈ[†6-“9qÕæaRKïB/¤o& L}ìÉT˜Ì‘g6)ëÖT\–©ngO®É<¸_È? yFÈG…ü|í»E6æ|3ñÂf×ПÛš ÛЦ²SÙ¨ý S›ë³{ô"Z9~9þ^Žüåè“þ¯ÆEÛb*,©W]»Ã_å3C¾9S<ïÄ/Dùd*3êKñ¿›Ìx îðÈ,èÈòp4•)u9Ú{rÀ£<7Œ¼«C¾<äéœx0ûœœ3® y3ÒðV†<±‹{27ëckö9ÿ=OÍÆ¾„ʤwF”'Sáø&ýçÇ'êfîÛ"ÒîÓ»?9´$SaçR?€< ™ÖV¸ûJ3[+?-ä›À^‘ˆ›³ZÌÏêßçîWðÿaÒlÎ5³{]«»1.SDOH³xòÖIn˜Ç¡‰6GWÁÖ:Í^f¶»»'u|³»­¶ND“÷)hõÚŸ± ]ã“.ÜCЄv0š”»ûSw?ÇÌæÇîðhŸrS¬¨ÎBf×™h5ÖFeJž†Vëÿîí +Øåp+•‘cIl%<ƒ^´W¸û›fv:09àîךÙRdÖÚYs’[ýÍháþpÈÏ¡ßMÒR—Äaþ3ÐÂzÚOKxƒê]’ÌzwGûÅÑÇ?Ìì“ȹi-Z8Þ‰^üë£N]ë]O÷Zïw‘vþ)t8û4uZ¹Üý<3»™Œ‡Sí ÞU¦Çç'šô?ikPi[ §!ëÍX4,kMV…«Æßp8¼Sãj2KÖ5®…4Ñ0€+#^È Î]Ìð=i\£ÑƒM«†ç‰ NzÖ¸Þ‹Z:š¼îGª¯Syª$kß4®È[‘óéÈ{­ÀþFå¹óÃV¯"K*©¤]#Å»ñf¤dœŸ½§®oõØvTzÕ쾞mñp”?‡æ!×Ëëkõ¦Å =ÑÅü©Ì4é3á"*×ÈmàîO™ÙhEZ}¤Ã‹¦q…¼*äd›ÛÌŽGG •üb4Ù¤ï»ÙoÓ¦ëýÑGZ)lÛ'"·÷Tï¤þC÷ãïȆ[PPP°#°9ÄL yR.lÙˆv0JX“‚‚‚‚‚ …¾ `„™ýØÌfšÙ=×.(è[(WAÁ®‰“ÐÑ–‘-GAÁ;F1¼k0³¢½ÃwŸÜêñì,ˆP$†<¹Ú€¹ûª(ìîîÿ­µŒÎ V»ûú¬,‘˜nq÷²äuwoÏêŒ@Çžs÷Wã{ ïÐ-È`µ7cw¹"ïâ!gâPùH´~ƃ$ÕÌ>@0ç¸ûÆìš =ñqí^Í~0®«“˜µ  GѸ ÞM|­â'¶z ;Ú ÂUh£ýY3›kfgGþ*3[/tÂ=»¹t?ŒXÙ3;èþoî5³tøs™ý*ûΛ¯áCþu´™õŸˆ~'ÆwŒò È `ð‡(›ˆ‚&,Јã0äÉ9°V6$ú|¤O²òˆìxÿ,¯“ ÅMhúY›¶46tVfXV>æVËÐh—H@-}WÖçàZ›mÈ’ûBBš‡£‰ä¢L^‹<]ÓÌS¢þXÖçsÈë5ü¼ ʇ #ê³ ×¯_Š:‹BþZÈ7†¼ML¿§â»Û#îiê³yÿyÜnF^¿—ÇxßDç#Œ¾¿í¡sDNDŠ@§‹²çïhr{O«ŸMI}3µ|%õÒƒ­˜.@ú]OÅXýð¬M:§—¿ ÎËÊS?S©˜/ÖÇDù!‘×ò¬¯ŸQ±k< :?ˆ¼;³ðdd꺑Æñ,>íRˆ[Bžò}h’~i/¢<1<ÙêgÓäY¥‰ê+!§s9¿ù—42; D´fSÖóhí^¤‰«j; ¦P]M\³C6ªs”_¥qâš”=1Ä/ÉòïÅY^ÎV1/Ë7*†1(‚€SZý\J껩˜ û?ŽFfŸÛÑËg>Ús¸™örŽÀ»Pd€£P ÂÁÀUMˆ‰Ï@{Yw FŒ™±ÇÑ>&©ÇeÍ%µò“ў˥1ÞKÑ x%¢"»i³£þè û™f6MŒíè¥ú¯¸–=Љ|€ ñwFãl%«Ëºø›ØRP½D²zšè'¢ƒõk#¿NPü¼»§MìÄÓF÷x:ù‡ÒžX½MN¢ÚÙrÞî¡ìs'—e|Oâû;ÃtĦRPЭž9KêD¥q­yÕŠw_´¿™‚@&¾Æ‘è4þ44Á½F#`Ò¸¦„¼gÖçt¯q¥ CN“ƵŽ,ü _ÙY!ÉúJÚÚ~Tœm\rQ–%þ­êW!sÖ^­~6MžUÒ¸F„œX_¯fÒ.S¨Œå!Ÿ×–øñþåIãz;žÉîTZÜùQ§+뱨gݧiÔ¸Ú²±O Ò¼÷AT@‰¥æÜ¨sx\ã ˆ4 ª¦>†"í>ñUþõݾÇ%õ¯T4®þ´ºM«ø×ÝýY—Wâi¡³ V”áHëI¬Ïõ•|â {™Š±y»Vò4†>ɱÈßÔWò/vQ–Ê7ÑÈk¸]Ãñˆqào}'ÄŸãï (ÏA]Ô[‡´ÒÕha±Ž*ÄDWØ-ê/G“âw_ÖMý[Q»=Ñýÿ íþpCD˜‹öD¿AÖbv„ËÀÝ;ÐÄ™œKêÌ< èɼS°ó£Æ iXDo5±XŸjfû£ý‹f8ÕÌf¡õ$ôqôÂê “ÌìçÀé!×ÉŽë¡þ‰¼Ê&˜Ù"*SßFªFW#g¥È¼9×ÌÆºûfw÷9qÚ“ƒ¾ûBü)ú-¦0B3Ð^Ý#!/DnêÉÜv1ºÇFÞcHûªP?‚œ=& gªWnó3ÉoE­ÍµH3:iG)&×[TôpÏÊÝ·šÙ hB:iòËP¨ö-A¦|âú¼ÀÌ&¡‰ô0*º´ß è+(znAA×hµÊWRï$¶ CrPȯeu’§ÙÁÈ ±=äG»ò†OŠúÉT¸:këÀuQÞ©0o³85ê$SáìÚø?ƒ&)§2!m%¢M£ߎ&¸Ä0ï(~Ù÷'SâZ2Èþœ¨L… ÞA›d*ì’»Ç{U”ß [}ÿJêû©h\ý aHФ4…Æ o—¡½‹vwßAõÎF&›YÈâ#è|NŽï#·ùCQèßFþšøŽMÆ3ñ†Â/ˆü¥Ñ¦!§»?hfGæ¥QÈTx›»'­cïhw‹»¿afßC‚™ÙnîþŠ»¿ff³‘sÇMî^xWÐ70™(ï@.õÝ¢0gl7"Ñg‘¶4;êAZÀæ„8èz,ò^Ü8Ð#lAß‚™ C–€M=V.( ìqô_ƒÎ.½ˆ»–I«Â3*ª‚‚íÁÿ1t³ OXxIEND®B`‚openchange-2.0/mapiproxy/documentation/pictures/mpm_pack_pack.png000066400000000000000000001416351223057412600255300ustar00rootroot00000000000000‰PNG  IHDRµ ˆ3ûÅsBIT|dˆ pHYs × ×B(›xtEXtSoftwarewww.inkscape.org›î< IDATxœìwTTÇÇ¿³½°KïM;öÞ{ï½Å$FMbŠÆXbª½E£&QcîػØ*¢Azï° l/óûC×T0(¨ïsΞ³oæÎÌÝ·ï½ûfæÎPJQÝ?j˜TFzmÊHŸÀºŒ:†•!Û@ƒRi<SðJ¥7гŒ:†¨Q*ÍÀ„2dÛhYFú§,J¥y\†luK¥‰žêÌ.•î  [uŒàZ*Íþ ê<€w©4 €)eÈ6йŒô1œJ¥9S†lgÍÊHŸ@R*ÍÀ€7¤óö¥Ò\Œ,C¶ßRiì§:‹J¥×ЧŒ:ð*•fàÓ2d[hÿuþ¯÷Ï»xÏ—¥3sÏÿ?íMßóCP:£:~°˜•‘ÎÀ/#Ý «T€¸ Ya2yzòI©tauˆpÊ©³à:K^ ³è:s_ siYA9uf¿AEeèÌB)SKßÀìü¯‚ÒÿëKtæ¾AÍÊÐùE×â¿t~JY×"÷×¢è×bY:ó߲Εqÿ0÷ü¿ufîù×")q200000¼Ó°ªZ†Ê‚1j ï ï„Q#„´"„¸Tµ ÕBˆ˜2¦Bsj„žLÔVzJiQ9Û­@F)••Sž÷ôb¨D4yéïÄ\-ÃûÇ;aÔ!|J)c¤þ…iNí]y£î À³ª•`````¨¶tz'zjN¨¶^t U ¥T`O¥µâûzQòBåC1uãÚ‘Ÿ]Ò#•Q/¥ô?y[20000|TÚð#ÕQ;½x›&Ã0ˆ-!‰ªhÃ܈¾òY•Uu&þž¿ÙÝcó4Šü ŸÏ¼Ô0nfÜM¾Rž^n×U†w›T¹Ak¿NÙb-ej(Go³~ªŠ¸¸ytS«»¶)™vsßt÷ã+Úw®È}°aHÃ#‹›õ€Ã‹š<¿qx}ˆ¹½SâÿK½ñ»g»,|QÙ»§Õ8¾¢}ç«:u?¿ÊúuËÙu}›]Úª×Ëd®ïšRó௠F¿n9‰wßêºáJë©ÅÏR´6j©G½#Ò6|¶.ažâ~A€v»ì²v£EgÞ{é2zT|mǧÿPP.a±å/¯ói;j}ïZ­Æ¿pýÝÎYëZ ^òƒw›I…pbE‡« ¬bY,nº{Ã~‹;NÜûö~ÃÛâA¦^òÉ‘Âl—Mô¹ £Eä7Ö›_V¦Ý¦‚7>³<`:®¹2w¦“„e ”í(aå¯í'¹PÇ–Süæµg0‘}ùsº¸ïµ“»uÿO<ÄÝÝ·P¯UvÈM©ãÖÀIYžzŠó’j¨Š²›8ÉbsÕlO÷O-cÐk¬]êõÜö¢²)Ïת [sùâû!§Í?¿2aÜòŒo+ú[X\¾ŽÅá½tÙ›+0°Ø\UEë6qò÷.A“Öù¾nùŠRiFMohÊ⓾ [öøQç´¼¼£Úúyÿ¥nBˆ€|Ji~¥([I™3’Í>»4åeFq„»gC¥ñ÷üÍ¢on­Ó}Úá`WHƒOüloЪšFßÜÚ4)üD^©‡ÃÀ«Å˜ÉíÆü™tà'ŸORžª”§Ï<ð­·{ƒ~)®oj^¿ËWAM‡ߨ=­¥FÒ~ÜÆÐëTäʶ‰ukuH¿¨~«¡ËïØÖh®}–·ý£:ÅyInVÎ ›n>†ªcé5E³6nܘ5}%AP¨¡Ï݉2ƒ0$]o9¸.?‚Ót §C5ÎR>Ñv÷âåÀ­©–»D\b{@ÞyÕ ¥ïªÞ’Û!:sWs¶êìc­ógÍ…±\6èùX­­ƒKÝÀSdjï^šÎÂAÂR¥è­Ç4$sÙOæªuQÇÔBƒ¸C ^–¯#ç½|­,¸|q@ê£óÃ, ::Ï”² a={™ÍI¼Ë»¶srƒ^k֤߇½š.ž<#Îo6 ÓXr¸‚gÏ36W âðDÚÓkz´Rå åð„¡y)¡õüìÓqįQ[Mrk8¢QYg€'4¿6zQüš¼Ô0îñåíî…ž]bëÛknŽF‘Ï:÷×ÀŽJyF=¯–cý›õÿõÙ‚Ñ3k{7/ȈìÁá‰Òû͸¸ƒÃhÙ¾Ž-kÓMd—Ú™+¤÷˜vä¨Ä¦¦žÍèY\þ3C~~•õ£k‡òE–)=>? 2w2\Þ:Þ[)O·Vç9éÔENÍGú·´8ãØ²6Ý(¨hß|¯/¹|³Œ¡?†:±ªsû¢Üøv¡Žµ;î<Éïqeü'„€Ö•6ühTQ¶ˆÄ˜ŽE>5á"EW`´­„êÍQyá¹* ‹«2hUÞ7÷Mw =_le€}ó½¦ßÜûÅjYfTçݳ]üƒŽÎsÌM v¡ BEAjó‚ôÈ¥ëã ÍÓ}Ú£‹¢”§÷ÝòÿöoEAjyV´hÇwv›B|—vì»3m·@nò}^JÄÿ{'~ù»(7¾Ã©5=NlÒöΫ¹.+.p”FYàšðÚC •‡Cô‘ÙÇG9z3òɳ%*#öÊ»O=ZÔýÐCw‹¿óÇä)ÜÐ ½¥ÁöÅ8­ÛÍ$céú%ì¢\%5»›¦³üäpш þ…ýï§ëòTF^‹¿óÇ®¿­löʼn¢žwÉzÀÃ,½ä“Ã…#'*ì6FãÕôϼ‚ÓtÐvSþèc4µâò VƒTõßÖ9yWY8ŸÓ*eÝ5Š|VüÝýÃÅ–.‡JæŸZÓã”^§¶dq¸Ê뻦$†À±åm÷tj+ž@’V\ò™I¾0;¶W^j˜µ[ãd‹ËšGZ»4z¨.Îozm¯pçðl§âüäÏJ…[îIAEVÎ °ïÇZûTEÙ^b ç/­Û¸ÿk7Ø9Ëñ¼´ða–NõαØ\…ª(‡•ŸÑHžÓ sú§E]ZÉ7³ŽÓªäG–´Ø¹É÷Ý‹râÀÙõýš„œYüPj«QÉ\-hü7ä§=hxw­A§6ç ¥©‘WþÜÖ®cˆÎÂÁ'ÐʹAÄ¥-c}òÓ|iíÒð¬¹}­«:M‘ ÿ#€¢Jë©ÑQ>—H! òŸ¢¥ôÞ­ãMÐfÔÚ#×v|jûø–ßÁ˜Û;" §­gÝØUùˆ«Väõ·<½/‡+¤‡øM¸ç?h䂘¿·c‘_¯ó—[vŸ™gª')üø'IáÇ:ua7KÇz¿¥F«]¿™Ñ¸ÏüìK[Æú€Rþø•™ŸÀŽ™6»/lQ¯~ׯc)5š{4>§ÝØ¿,nš“xw€pƒN]ß½aÿ™Zõá—®â»s­{l“}b)$òÑ wçv?|”£7K–lnOµÚ Ÿ/j½9XUkvqäo—º¿Hn•¬ç‹ãEm 5T–¡÷XÕÇì((´Fñù­6‰¸Ä°1Håé$aågqêþ‘÷i\¾A…j4Íâ1Kûí©¢;BÔÞuí8Á**™Õ^t¿¾=§\¡ë>tXlŽ–Ë7 Ø0¤Z™ß§ÝØ¿Ÿß0ôW¸°iD=›“9ò·¨Í°{¶KãÓ‹:ɳß5ŠG-Œ]{æº5 ôùÞzË!ËÒßò+[8=î8qkìñíw楄ŽÏ´Hê°×$«.θýó¡FƒÞÃÒ±îgn ú*÷íJÅævµîO(½–üàÔ@—º=¶´ÊfãVf¶ãp…@pY¿K`f}rðÜ SNmÿÆüzÌí’’ùy)¡ƒf6gxBsOh~/3öÆ“ ‡+¸?â·¨-à7ÃzÌU¿½:NÜs{‡®×—'ïOæð@fz­RØaüæ ‰MÍJ[{L)Õ®4£Æ!]—…gŽòk:)ÕÞkMr*«ê†“wgõ¨Eqk¬ Ø0¤azÔÅ¿.ü32¨Ñ`¿gŽû–§¢„ËG¾¨ž@#”ÚÇ7¸`‰ƒg[MÌí‹“ܸÏülÈMiÉå›…›ä¹éýü´ð–b aµûw"8xµ ¾µýK°vmücBÈáñ÷Š$Ö5þ:?äð›9 åÅÅœ­Þ9\zÀåÝ¡j·9Ń»xðÒ/Äió”Ô¼ãæ‚a@) âr_ø2Xßž“í,eï!=Ïçã…8­­«9;CÄ}Ãòf’ε¾='Ã$ïiÅN?¥qiáÂͱ³òlÄ,-´påfl RµqÉ)-„WÇ(ÂaÁ8¹¹0pj aÜ>ï<6îÍd<¾²†Ã»ÔíñlΩ07ÞƒÍᥚŽ9åà˜ÒõP£^ê÷­ÕQJ©Pjçµ¼tÏ®QÏYGî›ÿƒß kÂbRƒÞ~âêü~/Ó_ ±Ýçÿkƒý®0Š'²x¤”¥b±¹éF£ÞÚÁ³í —-¼.ÝOÍÒó3ç—EéOüQÑP“bt•´àpáKzð©%’èË›ôjuV¹†Â !Þ$ô•F­<¼†Q³ x啼-£VÕ˜ŒÚ¤?ä­ªZ—’0F­zb2j÷¾°ÚYÕº˜xŸZepàgŸ•ò̱ö­çôþêÌÝ7ٖɨõŸyåÚ›l§¼¼†Qc¿±)¥~ø°t¨£³rª7¿ªõ`x7¨eÍVLo-º^Õz0”Ÿ§kÔ¶¾R°¿"ãë·ÑΛâi8Å¢w%J?CðÅVƳ/Tµ ï6b–ö£&‚ĪփáMÂ5†÷†w¨B,Ÿ†@a`````ø„.!Äû0jšp®j%ª-\ÞH@UëÀÀÀðá¡ÉKW^ü?x(¥JÇß £ö:æÇsSÃN1»eWFeñ;³×Wf±‘·'LmUÕz|¨dßê^[A¡Ì1žú«ïkïUÆðß!¤°Â±HßO£¦Í7Äßù‡ܪVåCE«P¼ ‘drýÃu‡ýÃuïŒ~¡ò^)õöQ( R™} «ã«Ežç½4jZ­6Z«Ízµ Ã…VdeÕS 10®ª§Ò"µW2o- à y?!Ä@&¥ô•±Ò!€3„Bæí»*QB2)¥ÕõNb©£yU«ñ!CtJcqAV*YUëR +±eMGf¬§jQd'äÈx¥ Bˆ@Ïw¨P(÷p–™¥½…½gEÖÌ›V@©Š$FpÙ Õº»,€€Ôô¨«Ùz\¹Â¯1T>w|aQ\P=/W_cýþ¿É«Z•ˆsËÍã²ËîׄÀƒw¨QJ£+ZÆÓ·¿Â¥Qßjwð}&'õ'1:à_{)UGX"3£­KêÛ›d¨R¬<˜ã*‚V…¦/žŽ Å2îª ï , „XBžõÚ!.„fSI†w SOÍÀ1Bˆ;!d€MxâjËÀÀÀÀÀPí!„°! ”>$„| à€)¥ÕfÑSCý:sk bÃLÃÖø@<€yO7\«…·uf sSWzVªªÀ…§z100000ü Ji¥t³ÉpIL¥”¡”Nõ4­Ü<è-ŸûEñ‚ ÚÍù§´Ó*YYeeô5Š|VfÜM¾^§zn [fÜM¾F‘_n#®×©ÈÑe­{@عå6g×õmjÊ‹¼ú·ÅÑ¥­zŸøÙþEe3ãnòËÒ£"å&pŽ-oÛõUrG—¶êùºm|¨dÆÝäï™ë>ïøŠöK¦ïýÁcæ‘ÅÍûV¤®³ÖÝ>4ËüfX6¥ü­Á¨3löø¹îÄ•ÝûƒÇ·{æºÏÛ7¿Öçþà[‘kô9¾³Ûvn¹ÍËdvÏqýõü†¡ ^§þ;‡g;ÝØ=­Æë”}Ÿxxy½åñí;—þœü½KÛªÖ­,ô:‘eF=ç/ËŒâœZݵ͡¾ÃÎýÙ¿±RžÎ®Œ¶öͯõEäտߊG4 (¥4!„캀O)­ÐbH»‘|¿Ú[%Íx,¿7¡hepfmïž§×ôˆ;º¤åSÚ±emº^Ó#îä·­²€Uþp d%Üv*ȈìÑÛ¤AGæœÔ*eÎzuq™Ë6¯ú}ìsúžÏ­ïh×,§€³ÿ(ÊM¨ðÒ yv ·0;vÄ«ä sâÆU´n{çÕœõººwyÖc¾F‘7± =â;SÚé?z¶Tå|¤¥v«H]F½ÖÅt-ظ6^Jy:»8?ù‹ÁóîNñkä ïuQÎd¡Ä.Œ'¤eÆ^_tâ÷ÎC_ç÷غ7ßèäݹðe2ö­¸5ì—ô:õ'‡Ÿì’yîµt{Ÿ(Hh^œŸÜº8?¹u~Zø¯²¬èqÅùÉ­‹ò›WµneqmǧÞÇ—·Ûe:޹½SrdIËëòì˜.½F’4ùþÉ®•Ñ–F‘×§07^\u½ B¼t€ À…âE)-w!ûåZõ]Õ°9ü» YÚ0û 0'v$›+¸SR&52@~á÷&n½'2wz¶N%þž¿ÙÃ+5®ÝzB˜)Í£éð‘ÄÞ?ùÁ)Qè™%£X~´ÔÎ+DUœ+J =*®á;H!§Úé´J6°XœÄ‰«óûéu*²gŽë®‹›Gw4çöYàÉïŠßÇM}{Îwòî¬.©×Ùõýšô~ÛQëîÚº7Ó8zwú¢®ÿcžŸanÔkYEùI6½§Ÿ6•q¬ÕayÉ:BN/´ËM ³ë>Å?xÒ{½¾{j'?º¶É·Qïî¹5諌ºþ¹N]Ô¤ ãQöÙõý¸­†­ JìŒWü>n¨*Ì´·«ÙòQ›‘$WÊŸR!,%‹ÍK9¿qxýîSü#òÓÂGòDG¨Q/€¼Ô0îå­ã+åé¸é}Ÿ¶ïjÜg~¶F‘Ï:ù{—ÁÅ)#¹|³P”س0?=b€[‡øþM»#KZnHl®Àˆ_"w@À†! óSÃ;ŽZ»ê´ÿì†OûÉòËš‹ó“‡ð×(òYg×÷ëZ˜7œÅæf»5軥ý¸ pbUçöǫ̀aƒÖElá¼ØOáòRÃg'܉×( ØW¶´€Ã%i”…Rûã]?Ý»×Ú¥‘.7é^W6‡λͤÂÓ í¢·Òªd-„R‡Ó]>ÙíoíÒH·{Žë¯B3ÛâüäQ,.?ѧݧ«<Û*dé#ÇL»z6n7 ÄÖò´èKŸ :gBXEÃ~ û¤ä}ô¾Ònì߉ÀÎïìj˜Y×86xnЩ£K[õ¼´yŒONÒÝÎ<‘e²£Wû°Ä°cƒŒÄÒ±î…îÓs¸BzióUQ¶¥º8ÇY§.vòl1ú@ó 3àôš­äÙ;RJÙ¶5Zï>Å?âào GX8Ö‰ÈIê+¶t 0ëúe“.wÏvJ¸h¨ØÒ%¬÷Wg®s¸BzuÇ'ž…9qÎ:u‘¥FYàE@tFƒÎuß|¯/Å–.áê¢w®Àìê˜%É ŸV³­äï;»¾_“‚ŒÈNÞOtœ°%-l<ÄʹaDfìõ>|¡Eb—O÷œ´pðÑÀ=_¸§Dœ!¶r½ûNÿ3L7œ€ ¦È Vrߦ"/ƒâJ©”pF,/€è÷íöàâVF£ÁšÍ<3Þ‡ø½øÏ¨ý²ŒGÝüRï乿ùÀñ•:]ÛõÙ¢Üøöw}ÿ§I>úÆæ ¡Gfå§…‹µêÂúÔ ·“eFµÉнÑëö¡Yφ–".­]˜Û£¤.®Â.Öª íàøŠöþÚp§<3ºÃ…÷™†6 iè÷­ÕɼÔðþò¬Ç®íœÜ!-ê¢(õáÙM¸µåã[~~ñ÷þš—6Üï[«#™q7ù°ÓÔÞ®ïxùÏyÙ w†î˜i³K)Ogç$óS"ÎìÜ÷õÚ¢Ü¸Ž—¶Œ9wÛ¦KNR°•Ѩ·Õªdõd™Qm sâxûª½#/%¤F‘_#)üÄ°Êø?ª3æöµd'Üžüà”H¯SûÍlï›ò.o?X]”ӶͨuÓ8ŠÅâ(ÛŽ^?I«(hziËØá Ó×Wç˜@ø…5ëÄÎa½§ŸùX«’{_Ý>©/è5ŠfÊÂ̶­G¬žÌቒnÿØ¥n•ØÂÉ/¶>6aUöÇ}¾>w'5êÂwv5[mø{Þк>ŸÍYV8~ßûDQn ”‡gWp…æ©VNõ£ó3:‰¤‘–NõÎç$ß›r|y»þŸÑ0;1h­A¯‘r’´‡—×ï€[¾uÍI žcéXï‚…c ­’Å)§?º8_lá|¯0;vО¹nóà̺>Í]ß´U(±{T˜Ûsß<5Ÿî“›to­V%wµpð¹*0³‰!,–ÌÂÁ'ÐÆµq‚¹}ípº¨û_êN¸í?Ó¥äoØ5ÛyY~Zx©MÍ ¤°ã¿œXÙ±#ç%O‰8ý£Pj©”gt>»¾ßçpî¯A¾±w÷l™;†åÄõ4´•ígñ/!|BHK“Q» ` €¾ÖPWtøñ ㊠Îñ½ ±•›Rø‰á‘Wÿ*’:.™WœŸ<©^—é“Ç,IZdnëµ>7)x8È3£Æ¸Ôé>kÌ’¤Å>[K×éÛknŽ™•ÛYOô`ÔÂØõu:LÙ£.ʡשHÈé…v½¶V¯é§€ .;¿³ÿÛï[«“”Ìõœud™Q×j5~öèÅ +}:|6Cžõø#ÈN¸3ÆÜÁ{íØ¥É¿ŽY’´dÀ¬ë—þõ£(åOX•3qÜò´Ùl® 6èÐìçÆñ¯lÿ¨5ÍÆ­ÈøfìÒä_9\Ñ㋛Ǵ}RÔhÞ°û·ßY’¼P`fëŸqº{ûqØþcKǺGF-Œ]oãÖXcÔëjz4á7rÁã£Åÿ^9ÿFõ¥Ûgû¯êÔEmïž=D ¶> Bž-sQfö´qk²Ã«ùè¢ß]ۣשeÆÝäæÄu“Úzîõi?Y>dþý£„ÅÎyY^ÍGqøâÀ‹ÿŒê¸Mª×*›÷˜vø‚)?+áÎY ·ç z—¦ý~ö€ÂÜ„þ„°!§MÈN êf4÷í–{c€ÈÜi_Ç [âøb+cÛQëþ=œHˆ¦ëgûwx5]dãÖd‡ª0»{ÉìгKl­§B–ÖàâæÑŸRv±,µ¿)ßÁ«ÝöZ­Æ¹ÕïsR§.jSÖoâòÄQ™±7æZÐh˜ƒgÛBWøÁ/Jí™|¢ãÄ­±}¾:dáX'Q‘ŸR‹Íá§* R{›ä8\὿Fmúcè!Âbç]ß5¥¦FY  Ô(ÑiŠÍZYÒkú©{&y©}­í¾¿q©Í¨µ?hUò^ŸÑWjãñ÷ÀÙÏ úI§U´2ͱ8¼ØQ c×÷ž~:Xjç•@»¨×—'ï·±:¥Ç´#a.uº¤UÊ<ºñÏñ3mý\üÃ*'ñ.O¯)ncåÜð4›+T ¥ögäYŸM×X:ÖݾðãÓc³7­DUáäÝYÍJ¯px¢ï6“žM ;x¶Õ;+äôB;HtÑ—Ãß6Gðàæ¾éµ 1ôh½ò´cåÒp§,ãáuqîк¾8ðÿ¢í8qkìyÁ'ÄN]ý{žÄ¦¦žÅ„¹Öï½tªìŸ~&‡'¾´§ÉËÚ2èÕuMß5*Y}‘…ãý’ùÖnYì'C^O>9 û)ü,´',¶Ê`ÐòMǃæÜ>;qu~ÿÚ­'~^¹à¿xo¾+x·ýäk—FÓMs&DR‡39IÁãR#„Ç–¶ÊæºÔí¡’Øxœ/ÌŽžüà”èØ²6ݨÑàôª6zL=NFs…,c²G³{Ê”™väO¦¸ãõ]SjJm=ªymëtOìõåÉû<¡¹Ò­a?…GËã YÚˆ;‡g;OæOÿU¥â ›F ÍŒ»ÉÏIº;J(±;W2»åeé„ÅÉTçÚvž´#´i¿Ÿ#8<‘öeú‹ÌâõZ¥‡©7p៑u»OññÛ£e,6'--ò|™žÀäÿ·Šª8§§³O×uƒçÝ=eÐi,_UT–Åé=ýtð¸ߨÕl9»0'XnòývpiËX6›ëàÙV#Ø^,È|Ôx2·PÒrȲôÒõZ9×Ï£Ôøì…ãö¡YΦÿPbSSÂR³ØUûq‹S£ñà#£Æ®µ0v}·Ïz™ÎB©ÝeYfT;àÉð©Ñ¨wå9ª$8–âID‘/üÀ ÀTT *>$ÌSø*#ôíô2Ú˜? ÿ’ïÊ~àõ§ÙÕJ׺³$iqYéf–®~áçÿ'êÆ–ë¥¬‡ƒg›¹`nçµ'%âÌŠ½?x\Ò©‹^j`Lôýæü­íßX,as º~_–L×Éûv_Ñ~Úõ]SjZ8xoJ?±lßžW@Xzƒ^m;viÊ/¶îM÷dÆÞX¸w^Íf„ÅV™Y¹…Ôí8-´TUdçwö³8¼,ƒVU¿Å Å¿<×Χ{íüÎ^¾ó;û¿øb«»:u‘‡¹}í³¾½æÜÇ Jn¤?œ¾÷¦NÞ&?8õ5_dy_¯U:s¸‚Ð÷uX‰/²4p¸‚`hÚï§ì¦ý~º<¡y®VU íÆm8|mǧü‹›GïæòÅ!Þm'Íž YžZÝÝéòÖñû9!¶ž Ûwœ¼«Ì—ÑÿJzôeº8—ãÑtxqyäS#„é¯X´´ø™—ùöo-ÏÖïòÕD3 µW«qÿš»Œ½»WâÕ|t…®m¥<ýàâöÞm&e›¼K~~•µ…ƒÊ­A_eyꋼú·…éVQ®íøÜ2ö®_>¥´Bžõ&£Æp @8žôÔx”ÒOÿ%ü£V*jÔ!m¤”g^íeFímrëÀ·® !‡'èµJï «r&¼É¶LFmÜò´Ùo²òµò“w“n}ÿÃ<‘Å…Ñ‹âW¿É¶CНíütã„U¹¯½v±²ùPZe`2j&€÷е§SfCL±5z=ÝaZN)­ÐÎlo/]qÁ{%§×vmûàÒïÏæ CÏ.²»wêgû{§Ö<½®[Ð(óYgÿìÝ"%┊ò8úšÊÄí”\ñçyu½å­ƒ_»™Ò•òtöÅ-ÃëÀÅ-#ë%„4;õGçö±A;%%e6 h|ru‡Î1W¥õ¼¹oZ«Ûw)YÆÄƒK¿[_Ù1Á»²ÎIeÁ¢”^1}$ãÉ"l*ÐXkàçÒØ¼Þ+RžYè?}KaNlçг‹ü-n8 bîîyuÝÖ¤ð£sU…™·Œ¬w௲ÌGݯ옰ïÐ↣$Ö5õ¹Iw'øÿæ3Y£ÌgÝ>4cƒ,+ÚK!OÄÜÙ±ÍÔÆ…ÍûdÆÝ˜ ©Îm¹¹oÚ†¢¼„ö¿>ple«Þ°q`ïü´°~Jyzƒ ÿ =xf}ÖrÐlçlÿÄð£3TòŒú!ç,©ÿ¥­£ê†ž]¸Ã ÓT›¡HB!lÎÓ€ƒ$¨  ʱøÚ ¤¬ˆ^òÍ%mBXP¤®TåóÝY{êì“VZpdBH7ñ”Ò·¶%xEˆÜ&¼úw;Jl[·¦%w¾.‹œÄ»<Û͵ÀÓ­7ìbK—Ì®Ÿî­®.Î ÿ‘/Oµ JÕyhôà™ñ‰r÷é‰ìÆWPÜø³Â(“L_?Y¿´"£µ€msgnÂ×mDá^ÖìêâÌÅPADæNG†Î ß°Ô6ìüò]ö!lÙØ%™ŸÀÞÝ’ØxnôýÝ÷ÏüfqiÍ.û:ŽßþÃÅ­£Ž\X¯>›+HôýÝ“¸%é쟽Zöúâ윘ñ6nÍÖ™Ú“ÚÕö0óæù+;&x§<<ó €3OË ôŸîžs5» #r€[¡çwçòÄá£$-(­wÄ•µŠrã?ónóég--¯NÁ $Ƙbkõ°@ ¥t€ëx²ö+¡:Jø®¬ÓuöI[6²l+mÃY Š5Ì­ä^[ªé~a'VvìxëÀ·G5Š|O­Jîšvì»—É+åéì“«»Þ2gÆÞæ&‡l+ÎOn}eêöo,.îÿÿÃûß}µ{PªÎãô‹ƒaÓ­¶/ì&¾$âç"®¨tô¹Xw±Úzé…F¡é8En°ßI|aïHó£Ù £Ùœ€âv%å TF®Fÿ¤#LßKS¬¥ìÒiF ¤Ê cµnöþ`éP7 õ˜“C©Á2)ü¨¸i°IF¯)jiW³U84éýS6¥Fi\ð^‰s*‘¹ãºhP½N_=Û1ÝÂÞ{g^Zظ»Çæ8 :Ç^ŸŸ¾kÊs©Û3 ÚÞøØ¨×Ô×ëTäÔ;ìœm»71ìè­² žA§¬ªÂÌö"s§ ²ô–g=þͱîêjfЀ'ëbwšºŽ*bÑ„ ÜQÎYs–Ág·ô éØc•YPH«‚ôÜ#šö6CùG*CÓò­O« 2M°pðY6hÎís¥ód™QœË[Ç÷Ôª týÆ¿nÇi²€¿÷5Š÷Í÷ú’'4Oñí5ç"!ÐŒY’´öΫ9+)ìø(6W°+#æZ}PÊÒZŒY’¼0üü*ëG×6ã‹­’zL;|^dîd>ñ³}JÄ™¦ ”¨yÞ^-Æìyºi(.ü3²nnbpwƒAg!µõ¼Ôæåëo÷ì0˜x”£·¶²Š,„,töàåšòv†ªÝ¶ÞS5Së)ÏJÀ*þs äâ¹ÇZ§Ì"£ÍŒÓE=…¢½ü©å!às`¨iÉVi$x8/ ¸ÔX‘û¥-')_e”þÖÍìüÕ­óùXm=ðuà$m"½5Væ~YÛš“’«4JÍxDµ²·Ù….\Ùç‹}/Äjë 8D«5Pέ©VûÞþúðeEÕyu½%!¬B÷†ƒAÇæ‚°XÏü8<³àœÄ ú’Â/¬°!„(<›. :ú½³Ržö‰Hê°êÁÅU‹v›5z}yîÊžyN?ÇÞÝý…H긧d{iQçë7éýÓ¥[¦{°8¼G®d<œìT»Ó¢®ŸøGYÚdHQ¾¢)$vÊÂÌÆþõ\s­×{lê£sœ^×]Õgúù[¥ó« J)ð, òE6á‰óȪ×5$)K•µ©Ò6Ü{•£jõ†Ç—„ɳO;²¤EŸ˜ÛÿŸLÕ(òYG—¶>¥×©Ìùb«¤ #óüCŠ-ë?ˆÖÂÁ'ÐʹAdéú z-›ÃÏËM¾ï^±Z%Ïldnï}ñæ¾éî÷O-8ÌY¤ªŠ²ëùÿÚ`/ä&Ýs–e§£5ö¦¼•ו· •ž¹5Åj_gNʺ[ªzSZã$¬ÜßûHΙ ÜNÑ9üuGåµìš²C7n4j¨dTCÁƒ iV»9päÇ"5M/}b¹ïÖ«Ý¡™z÷ qZ[Ph©¨Ÿ/òþV;»zò¯¾©l G#5M޳8tu²åAÆ ½=²Ô‘ûö˜yïÔ/[DæN~eÉØº7?$ÏŽ™¾ÿgï–n™;m/ÊKàDnYoåÜè§¿Ä®ˆîàÂz€ÃR™¿F%éÛsîÁ’uɳ¢'íÿÙóÛİ#k$Ö5w—/ Ɉ¹6cÿÏž3)CM²ºÏ>§S¶ÞóƒË2ÿu>9´¨þ8Sž[ý¾)õ:}5.7ùÞÏ'WwèüfÎÎëcê©IØQJÓl'„t#„§–¯ÜœÓZäӬ滲þrú\˜\éÚVCÏ»»þ̺> sâGÞØóù²»Ç~Ø?fIò ›F´d±¹éëQÀá Ãîü­Gïé'Çßó×õúòä}ˆ¿çoF)úͰ>H©ÑŒÅæ¦Õëüåáİc>„Åν8aìÿÉ{²Pb·wðÜ SNmÿÆâRøùUO¼¦QŒY’¸öÿXÛ-=úr×ú½w%Zu¡Uƒnß^vkЗ™{©B\ÌÙêŸY¸Ÿ®7ߦ®5õXÑÈÕ}qÈNÌRç)–öžrÙ„—UÏÝT½{šÔ(›Ò\x{D~ ðÙD;¶‘ ö„©kzÛrR¥|¢€V®ÜØ#‘Ïnž¼6qbcaŒm$ˆí·CÖ ÀÅ~>üN› &Ö·ç$Mi. éQ‹W¡X{ ¯‡{ƒse™<=šŒØÛ|àÒt¨ÙxØI£^ólx¸ÛäCᲬ¨~×wOîаÛ÷›ë´Ÿ*{|{›Ô±V§Ÿ»M>ÆnþþÑ >¦2\¾$'Põj1þ9·û]fÌH ?Ú¬Nû©;v›• CçG¬¾¸yXS­RfáÝ{þæäˆSîàÙlt‘g³Ñ6ôUÊÒÜ=›¹^¿ròîªôj1¾H$u•qÒóÍŸ©Ša2j=ð|Dê–’Ä”·"Ùe­4éWåVŽ9+°ÞóM•¨#!ÖTÕ(ÂÉ3øb+ã 9·Ï8¸M¸ÿë«×wMÙ­¥ùPj0“eFµO”([•=/HˆºÕ°•;ÕØÔÔ@bØ1°9ü(“ˆNSì)6w¼a:f±¹©éQ—j€ÊbqRLé<¡yŠBžÞ¡†ï Eƃ'¦=º0áÒ–±³DæŽ~#~}´ UJ'޼‰“YpŠÜ`q1NëöSñ} Ÿ(.byUª/Í" #žKÞZx§¿ÿ¹ëˆË†ŽË~â­\Ëš-?öHól><³Ø(máÌM+.ß nâÄ‘Çæ̬D,9,ëivNу!êšS šfµÙFÌbb§¾af6ªßÝznx¯Y¿ÿzFXØûèûϸ~Ét\»Õ¤ÂÚ­&…›Ž]ë÷UºÖï{.¨;IY˜1Þ§íäñ¥ëqðj_بǜ3%Ó8\!í9íÔ³¨Ú­&=(™ßcʱP¡¥ŽuÚO•Õi?µÚŒÈB¸j™†Ãñü"ìÚRË[™ü†N’8_¹…-!¡ Κ/ªD=M4ÆÏÌjÇ=_¸›¾Û¸5QÐq…R­G³§©Ñ(<7è¯Q c×Z»¾íèõwEæN€èô:Õ³‡¨w›I…&ƒV+÷‹ YzGàIïΠ×Öê0áŸP0èµbïî•€BžÞÞÌÒõrQn§ÓGÛcÆ.Ký±qïyÔòŒ]ä oŸ/*}w¦¸Ù‘HÓòkÊ:wSuÞã|Ñf,»;kìy×SÑ¿ûj÷¿ï¨¼ÀËŠ±åžªþîPu¹‡úùð3rFËÎû.¿¦¬’®óšÐDlB ?ž/n¿'LíºøŠ¢C'×3N7¿“ª·t°”B.ÑpÙ¤:ï®ð^`åÜp™³w·üÊ®—'4O÷i;y|i'+Çzó%Ö/~¾¼'pÔà¥4‚2†ð4s¥ô…®Æ%Ѥ¸ ³›PQ=ö¹ø™Å-@Ü€”àš IDAT“bÿ‘ £24¥”^¨ŒzÞ‰¡G¾Š ÚÝ„Åæ¦z[Øú@«¡+Ò >xÿþ}?Ö:Àb±ó½ƒ­{³Å}¾ ¸-0³öß=ÛÅŸÃ?h=|Õªò´ÓrØŠk6Žèæ7Ãú (åKmj®|b ‡usÏ{oîùBÇæò› øíê-ÿõÒ£/¯bsøqF£ÁÂÌÊmÛ< /§¯7/É/Dí³õžÊ×Í‚ÿçéÁ6nÜ|8=Ñâø®PµûÖ{êFb.ÑŒo,xË{™îQ{^Iкõ$÷¯Ãñ²fÿkçƒAuùwLßY¸>ÙÒoÅ eýD™ÁâÂÇ–ÛÌXౡßXzð¡¦î”æÂ ±¾‚d ô¯ÛÊfvf¬Â?úIŽ› Èûþð«rú~}ùÚ›¨·tÏÏDÿ™7«í3´²xj³N“ŠL›B,=ÿ0sv˜$xæ#¿¡“$ÌUüUZVèÁö÷ö“”¹cuA€‘“0'_®Œ¡åî –_G‘sݶã,Þf”þôèË‚ÔGç-[ Z\¦¿{l¾C­–ãr-|þóÃ"1ô¨Ø¥^O%‡+¤pv}¿&Ù‰A_ŒY’ôiìí]RŸö“å&Ù¼Ô0nÌ]v{ÍÍà‹­ÞÚÛwÀ¦áÖ©NgPJs_-]5BêŽm$ü|]³ÂªÖåmá¶<÷«äïmÖVµ&=ÔXþ|Qq-M®¯´5­•!ÄAdîhcãÚ„ÓåãýÌã[æüÆAZeafö[ßOͼ·È÷ºÅ=´åäÝYíäÝù…½R“‹}ePÃwP™Û`p¸BZÒ €µK#µK£ê¶–„¡ŠèP“÷àÕR %1è5œ[M –º×‰Ïðš¨sH$€×º^«Mˆ†×ã©å'U­Cõg×péåªÖრ˶ØÍs™¤Ì…ìo‚¢pµ9ÏŽ£á;p^º­:E'4(Œ±ÿ6(l`‹X†WÉVùW•’´Vìë–'Œ!Ä@&³ý CU på¼5oÐüËzß­}U›y狜TÉ:©uwqøËä^—ô2÷¬Cr°µ(yìü‘eâ›h§4l ÛPÁÐÞ…{ìùN5<‰xÂìÀÀÀðÞCõ”PHþ…ì–Ò®(Lí ¬Á•Õ^ìp, ù¯|¯‚« w®5[Á³ã( ÷l‘}¦a-¡W^ã{›ÈÌýrW®[k7Hšý]fS÷o¬ \¸/íù•&cŸ¬žï·s,>1Þ˜Ôçmµÿ€Àƒw¨QJ£«Z†·Aq„Ú†cÁÖŠŒÜ¼€âÚ¾‡ÝN=þ>óìÝw|Eûðgvo¯÷Kï Uº ¤ˆˆ"(M±ëëOA_±÷ö׆ RTz¯Ò¤'„ôÞ¯×ÝÛÝùýc%\˜ïçãG27;ûÜ&wÏÎîìLŸšÎp‰–ö[ÿtÇuþ&zljé%Ã¥a¿Ff¹®ëϱ›K¾²$–|aIŒ¾Û˜wtbáXÛ>O1æ1U?¡›R<\ô‰LݲN_Fo“†ÿÓ;¢‚V×^v\¢ D¨oª•ÂóI âZ¤¿^YÀh¿¶§¢ÂqØ‚yL© i%èoPòQVù»=†·‹ŠS— À i¸Ä%ÑR|ø$]zÁš!N&Ÿ3éBØ­Ú,Ìý{ÂkZ[ï¾ýÏ5@D!ÜšZ]$©×, UN|ZË“ùH/ Œ‘®Ÿ²²êw{于ûÂå R›éFMyÍFWbçobv ¸E𫿥Kí]"&ëþΞ_٣ˆM»ÆUøbýÕê ‘†Jöý­¤x¦ç#[«6øöb[e¾t×â9†–ŽäZÅ:mç,mÒ¨ô›g¬ðËZ:Žk˜Íí#÷Êë“Ç2NÆHs” ‰2/ã†J¼ƒ„‘ê*óWìáq…cd‘‡•>25sØ=?e6ž~žÿì´7 _oж‚ÝÎÅ÷$ùýÃ^g¾oÕºˆ¼¿—©­zþöÛ_Îü&P¶ìåÎwyíc1tÑÎö½¦ü÷†iŸ^é¾üñÌ'‘›Þyÿ2ò˜òeò ýqÒ¿¯Ð+ˆ@uŠUÞÛÏxÁÏñºSΨ±©š2–ÇÔË«úU´{lª:?-\·&Mrù1e‘fSü‹ªô¨‡EÖ.£d(Ó²Òm „"„⚪½ú¬§"]–¢ë]–¢ëÍÅG?uTçvYŠ®wTç¤5×>¯Äš÷Gܲê½ÁÏ~ÞòÕ”´ßÎÜäqTtösîÐ’ŒMÏ4Õ¾X·erSµìLý$oÔ#«oõÈêÛhF~Z¡X6ê‘Õ·}lã$ÞïEy/SÔžxýã¼3–T”Ö/«ÈÝ#+:±VY¿Ü\rŒ©_`«È<ïIiö¾4ÖòSJ½rJ lÇw³’ÝÖ’Ù}n}óÁ™ï[oJê{çSÚÐöÿzžó|m:kò%¬ÛrÎ÷EC<_í³¤®Jwt›ªÍ¾µ‹ö”Ã'^ðØ à½Õ£?ûü"½#×ÕµWœ¢D%¥ü¯¬¸eK–+²ù#oBj„ÐŒ&(bYÏ\Gù0÷Q¾'æq¨a”tgSµ yÐlgcÿ³áøîÿtc㻎û|à]_ä/{¹ó´ßßT–µc¼!"u§D¦òU‰áí¯_è ­Y8l€LipXÊÒû"|ÝØg—&÷›îäý^´fÁÐQ{Yo„h_»ž“~îwÛ»¥K_L­ K>b.=>*4®çº‘¬8ˆeÛ¢i+ó÷‰½nk |݇£úÒŒ‚µWfu`Ýæ~¢àXò\Ò#!ñ=·Uæì¹Kiˆþâö—2Ÿiæ«@{¬ÛBmütü£2µCÿ™Ë®û\ÀÒSg‡Æ÷Ú[‘³ûµ1nÿ˜Ç6ì’0 °ñº›KŽŽ ë¹®¹Žy0’0 ‘8€­ý ñˆ¢„ˆÄìOOǾ‚EA%ø½¥JÃæ“Û>:f-Ïx!ʳë‡{!:uÄÃçürjå;†Û+³fa,ª0•ŒL½ÿηŠ_øa^øg‹jLIú}w¼–óñ⹡‹)Zbül`Sl÷·Ç=±mOIÆ&ÅÎïï~†÷{StaÉ_Mxz߯µŒ¼Þ\tä1 ˜A€8ZªÌÄ"¿xnØ72¥~ŸLe,¤(IUDò@7@ÿ)ÞÛ¦Ï'v­ÌÙó=¢h[rß»Þè7yAÉó¿D”Ä*ø½©c¹)¶Ûk7Ïݱ«"wlë—S^ä9OWð`’ܮоBo»±©šôáɪ €Á‰ª³sî/ò=bël÷ Ê›;iÓ'tÑ¿»­º‡Ïe3)¹)ÞÀÔÌr˜BOì¢-°{ù†Lg’FN³N9Ýœ(Ë5ûÃWÌŠ[±äˆ­ÝÆLWªIE;ïêi8Ù=Zn=Zê3¬8nOqs¢¬Âá×NÕ¦Oï©ÏEàó½–ÔÝùî$–ÇLßxeî¼!!ÇZê8]€Ö6Ù@‘Êo}cÍ+Ù½9Âó²8ú›Ð)²Š¦jc\zf^¯«Êm-¹¯ðøšgTº¨£†èÎå.KQŒ64qÆ”p øäºÛ¿™`¯ÊQš¹mDª°ˆ"¯ükÙÜÖ½?r¨³&ÿ–¸ž«Ô¦øý¬Û"pY‹Ÿ©*80Gmˆ=P–µãù¯vŸ°ìåÎw–œÚôœÊs´<{×Ü_ŸO¹À^™5¨^÷Ñè>·P‘½ë¿í®›øÎŒ…5Ó´aI+ò/ŸQf(ZbŸù¾e|TÇ¡ó¬eéwì_þä@ ˜žù¾e\§a> ð\—«zÌÛ )êÌEû-ƒŸXY>hÕIGL Ü͉ô++GÏêc8þÚM;~:lëgæTO =,gûýÔ˜µ¯Œß_·­| §x_½Œæý^5Æ‚‹<5æ?ëÿ<ãë\ÀXšÔ{êÛãŸüs{Dbÿ7ݶ²›¼öŠq±Æ¼:~Þ®É}ïzÞçª9{Ÿ†‘©wM~ñäÏ#î[š.Uè (ZZ5ú‘5‡»zªfÒ Ç5Åv{Õc+õ÷ê—¶ÿøTÔÞïE»~¸·=`,ц%‘ʵ©\»»àÈï6©Žï{küS»·iC¿uYІxleãbÒF½6þÉ?·Ç¤ÝøÅ22-M¡ ßèé¦oÿ$âǧ¢,žò“¹ä؃~ÖÕ?P‘ªvz{©<£èĺ.}n}#b¿ܰvÉóÉeìüL¨¯ KÚ pôO 1Æê㛘ÜÖâácüV€®#çš%©Ø¶hZGšQìOê=µÁ@}DG~ú{•t9o”\òWeî_ýñfß1;?Ó ~¶GÞá/,žö½2k&çu ©³ÝV€ÁÓx¶+€ËR4LmˆÝÐëæ—+)‰4½Iè5hF/}î·SbÔJß´õ»õ›ÂÛ1øí¸#AÁPìêtgâ7û­däÿí„ãœ1~Q”ܼ¨àŽçÖUŽè«(¸½». F'­¼¹“¦D&Aâæ,W»!‰ªÓqÆ;6US¦`(öH©Ïª’X&vÑÅèï$õéÙî£R ¨ùk+nØéŒjo’¶ÚÕ7šaF‘°iòJ‰žÚÁUˆšºí–pÝ­goÔ.{¹ó;Õ…o‘*t4#/æ9otà5F¡+¨½D…ù-¥'¥ãŸÚ½ZšôCeþþ‡|2r󖯦ÔÞ£CÈŸÒV@xbÿQàÁß®]ÛJRÝ_.Š|T }©RÁewnž»c×ô÷*~ï’~<çé¾ñÓñýÌ%Ç:bÀŒ­"³¿­"³?E3¹:$p–åëuóË•R¹Æ*м@ü Ý'”œ‰…Lyu hF~öÞTî¡_Rã6ÍXPsgXBŸÿui!öŸ­ƒR%Ìx¯jNÚ‡ïÁ¯ü{õ‹ïj°nKÄ™ÿScY\—›ì4£(æ¼öˆ@,òaÉ+EŸMhF.BŸñžã^¨šüâÉŸÚ°Ån[逄î·8EU¸ïׇf,¨º{Æ‚ê³>°Þxö½Id,-U`¨}Àh©¢„ó9Âÿ‰Aˆ¨¿¢ñâ Œ÷É¡¡G›·œ0³3×Î ¢D¯ \×Ç+K¯W–ÞÝÇxp|'mnCÛ3ůž“°ä§»bWÍzLÁ @¯ Îþ} "Ð4…ÎNùE!ýBí‚­‚³å D^Ä”„ømvü¯=c¥¿±whyéˆæ;WîŠï©q¢¤â_RÜ3ÊL€ò/¼±¼E-¢~¼òðj!„ÔÀaŒ¹¦jóRQ”äì—ºŸu ÷øÖ¡ ½¹žŒ}Á3—¹žðô¾°qé‹i3« Ž€ À˜ùkéã}Ç=±mwî¡e70rÍN©\½ýÈú7'tŸ°n×÷’H•{ê4w6©BWãuTh?ïYòh|ßÛÞ)’0 ×å&™ÚÓíÆ'nùròü‘¬øÂÓÍpáÁŒ\³ãøæÚ÷œ¼ñèÆ·À™/1âÒ!Šòxìå=×}4Új.:<çbõ·.ššê¨Êi¯L˦EµÀ³goÅw¬Y8¬ÂQ;H"Uî×GtäÃÛõ[_trݧ«ÞXâ¶•^GQLIÚàmù‡—ÿ«Ýn£žª9²þ æ·úÖGt̵•ŸJòy,íôa)û}ns¨ÏY=9¬]ß§•º(AªÐmÚöõ¯‡Æ÷úA8)ë2‡ÞúÌÁµç‹92ià¦ü#¿ÿoõ{ƒ ]Öâž‹dŸ+´ø-q`{ey;£Ô³¿Èkôñ¢´[”ÜÒ#Fn^~ÌÑ['§Øž± k™ƒ—s‚HÑ@.¡¸›_£g.y¹­)ê¼/ÿ2÷»¥‹6ÿT«wr¢²OœÂ²=Û^éâC6g¹"»G),;rÜ)Ó{é•9x¹Ï/ÒwöÔçöŠUT=½¦örekƒ’@Ì'5Þ&JÌ+ÙÏͰ ðcB%F´2ùsÍ¢&ˆ3`0dÀEWkmNruÈ’uŽZ@ÑLñžî×<ö?œ×~EIjD‘7$÷½k.B”ÓRvrö÷O˜C€øö='ψNùMщµÏÿ„iÄGuÖàPúžã^8¸åËÉ|ÿ„i¹>¼Ãçn[Y¯ì}‹o¢hi(ò!ŒLuðÆ? 1µûpÍÂa?Qm>D–´èÖùÎûe×yìwy‡W¼õý¦9%1{¾º×2)~³BQUûï„-Ú°¤âÀkÝGÏÿäÄ–…S­eéc#’d-;ÑÀÕé_g×jSüFCT§|©RÏVåíK+=µy˜Li8Òëæ—_ ÔчwøÂ^•3\®2¤ùÏú·†Íù9ó¯¥Ï*8úû4™ÒxzÌ£ë>0Fw-æ|Î îIè>áÞʼ}ƒ­åtlç1‡r.‰©)>rÍÈË"ÌýèÚ¿¦½YôÚ†OÆõ¨)>r+Bˆ7Fw]  6ÆþaŒéZP{B©ø`ðÌorh‰ì¾ÂkfÉաǤ ÝÓ!±Ý.i1G¢af7¯œ·ªb Ç‹L„–±<Øß´Ý ¤ýó‡‡núþµûë[ªB”RÊ÷ø Ý ðÌè¥ßûÒÆÊÁ%íziTø_ FæœõZt šÕ3gW£š¤ª(²résW–ÝhTJ\/ _x-É$+^yÒ‘úù^‹áÆꌑ4e>Ý뛫†rfŒJÚùèÀ]Wçˆ4š z5ÙÊ׿U¬É_åúáLµ<¾`ª±+_7†R©ŒKì}¿ªÏä×íMÝ6@íPi}DG64¡÷%õ³÷ý qÛJäÝGϯ”}ûÍÑÙ9»§oÿÄÐiè#ç¬9–sðÍùOuÁAiÞáå!=o~©§`Ëx[î×ÊDSžlNø·7ŸS`£@yc`?¦ž9šòFÄþÂjú±|P<&=5„P¸ÏŒX#‚hÓrž«ÔkK»•'f—Œ–G3VJAùiâS?‰Ú—÷zu'×)_(B8³ (_b­^íH’†J\¢KÒþõשGˇ¶.ô¯òŸíÉŠ8Æ‘0/äìF¶½£u·;¼î>Õ©rkèÍšŠÀÏúþʳk°Ñ*Šõ[F!iµ—aBRèI :@ä·pAW¨ãû‘{¤áîЈüñ–í®Ä^[Ú­`o÷œéå?Úº˜nTçÐrÄ—ýdëÎUóÒÔO£¶¿³ø&y cIý(ò@Ýf%Ê/‹`$CBÜ#¦ý”‰~Ë™™»é8ì3VþfO­[¦ë«,Öø§wPð^MGo_ßùëèÝMüÖšÆØ ƒ"©Aµ4Ý奙•÷Á@ä° |¢.½z½3Ñ4\ï>ÍÃnÖ–Ÿz¬|hÚ§Q›JYR ?4§Ä?fÊ ´5S_5S_x¡ý”ÿb‹-ýÞÚ'b²îpî+U#¦è TZ}o ‚â95‚ ˆ«)ðœ-¥ú…?,ŽPu`¼Wsÿ®“>ƒº³ÜøÝ2ÇoÅ  Pæ·2Û~O„<–qÊcWÍ+TÉ2;¹Ž{šîŠF­ãè+õ+}…~màgUšÌÂè¾DÙdD€ò/X7]žú½2³QÏ©¤FQO ©Iªò(…±¥ã¹–P G úôÆ>|—B=  c\ÞÒ±qíЇtÈvׯµtך˙& !¤€1A‘ÔÀ­v()Am“³&?åø×ƒo§i,ß•AÏé£<~–Ú–‹Vþ7Å/ cœÓÒ1qíÁ€©ëÂù˜qää¤ú*ðð"úêoVmfåžocÌ@AP$5‚ ˆ–"¥‘&%“©_NV¤Ø+š@šL“EA´AÑSCQP; 3ªIAœãLž0KOm¤´tAD«¥€ñAÑS€@ÖR'‚ Îcì€oƒ"©aŒÉÈ#‚ ⢂"©A´u2Q»r= NVLj“IÐyÇl:튜¨ªÔysku§O”«d;4¿o¹U IDATIUØ?AYsõ¢o=‚åžAD›µ-Ûñénó ë”EÓzêp‚H_h›vÕ µy…³ wnÏquI02–h­ÄñÞöš!ÿiîÔÜq·FAÑSC%€ clkáP‚ šÜ¶lWBŸ8EÎÍ4%×Ç+ÏN>œUÍ©üÛÚ)ßÌ…IReÍêcÌúñ-Éá5sW•ÔÈ(ïg“¢· j¯*í.sj4ûë[»zê³^ÜXyC´Ž±í/ô&¾ySøÆb›_½ü¸½3À“ºéOOVUxý˜š·ª|h´ž±-ñÆ÷o§Ì¾ÿzS†‚Aâ'±+O:º¸8Qo`ªßùgK§ AÉ g°ôÔ"@ÝÒAA4‡1©êœí¹î../±ø-Ñ/à³ ÿwuùØÁ‰êÂÿMŠÚðw±7nõIGìÌÞú­œr.¹9Ъ]‚l{Ž+1%TVÎ ˜Þ_äIS0÷ËôØß Jš[°³fØý×›ÍéküûmÕ7Ú½Ë"u°Ø“ÊP ~19zMv5þÕ>K*À×û-Þ±mÙ̸ßìo:|µMcERÃï×´tAÍa@;UÍï³âì©(ÛtÚ™6ö«üe^~¤ÔgðòX¶¯ÐýÑŸ–n!¼5Û•|¾vžXU>þ¡¥7…ªhçýÇd4Å=4À”.“ qý)WlZ¸¬èºh¹µg¬ÂÚ1\V´*Ý ¡ÿÐÓ ƒ’öOî¦;y°ÈÓÀ¤’8^ØP9pÉ[»x£Ô}uŽHãaŒYŒñÞ ¸üHÑÖé´ÿ¡ÆŒ‡3æüZ2êŽö×ÅÈ+å4°×Ç+KÏT+5(éóŽ_8>rUÇp™3ðs¥“—«e”[r¦û‹"E!8;ø„F ò"¦PµƒND×vz¾›³nMº3zs¶+yÉ{ï?îŽ_Úäo¾ EO ¢-ûý„#îh©Ï[éJ|HÏXEÅõñJ³€|¼H MRUôŠ•×HiÂÔÛÑ2o£ÖzßIWx²‚?UéÓž(÷éÒ+Ùø[:k ü–,ÚgIus"½â¸#µW¬"Ÿå1ú»Øk×ISúÆØð?}<–º¹ `ii¤§FÑÂ|¼H¿½­j“•&¥ÄqsšæHß8…àõ±~9lï´hŸµ?C?­‡þïNrûÌ^†¿—³uùå°½ûwScÖŤåJ)Å×mWJ#!ÁÀœ]d3TM³÷7íxg[Í €ÿçÓ6£’本 1($Ž*¯ºëÇâÛúÄ+sî»Þ˜Á‹˜úàÏšNŸ¨ÔÈ)ÏŒ^ú½*)Õª'Š•¯B c\ÔÒ±ÑöV¾–*ô§v‘z¸¿ÆÕÒ15''+H&}Wñr¶ –i²R c\ÝÒ±Ñö!„B@ÛÒq`Ç×\JE„KOòLAWÉ™hr\( ŠžAA\ Òû!‚ Ú ’Ô‚ ˆ6#Xî©AÄy!„0AÑSC݈Jlé8‚ ˆVK ³ƒb BÈ^Œ±¯¥c!‚ ZŸ@O-(’AA\Š ¸üHA—‚$5‚ ¢ÍФ†R#„f4PÞ !4 ò‰¡ðzeQ¡[¨;!Ô¹^š’×+OA o 1¡„ze:„дêö@õm |2B(¤bNE i q¡Øze„Ð ÔíêÝ@ùgîwÖ-‹Ek î3ÓÕ-“ž‰YZ¯¼)bî‹êÑ@ù4„®^YBhLu‡#„Rê•ÉÏÄL×+ïŒØ@· „¢ê•… „&_Ř›âóŽšØ@Ý¡n ”Ï8³¸oݲD„Ð Ô=g ùÌ_QÌ×êg¾7Bh`Œ[ý@@xå*Ð6PÒzeR05PWªzeá@Õ+W€¾6 o æ°êª@sž˜™fˆY ºÚ0€¬^™B¨«9OÌ¡ ©W&ãybVÖ+CgbFͳºò0 ë•ÉÀÐ@]=(ê•Qgbnèo±¡˜M ü-2rcnªÏOC1këÿ-ž)oDÌçûüÏüåÅ|-æÃÉ@‚ ¢ÍŠËAq)HR#‚ Ú ’Ô‚ ˆ6ƒ$5‚ ¢Í I ‚h3HR#‚ Ú ’Ô‚ ˆ6ƒ¬§FÄ5!„Z:¢ùMRCÉ@Ñ)°ŽüA¶E¾S6Œ-ö¦h !¤ˆQ4E[Dk㇠cÌ]ÎÖ!DËSi&>h¾ûˆK'úó=Áô‹¥ÔºÑjYÈ,2J#ÚÐVëËÞ¦k1F¡Šy0F*‹›®M¢5à\G»òý|¸¬¤@3ñ]û¥ä{¤y+rÞ% ¦¤€Qñ䋪A²ü&¿·+“w(å|S·K´,䯢/^‹¸–‘"AD›A’ADàëµ>ËbÆÜU[À{Ë=U £°èjõ9#¸.?!Gá½y÷±X°õ„XD©3UQo¾-ÓO±:‹ætÃØ+ÕÆÿt°9ömÏ7L`³`Á•HË’Wê“wþÞû!š†·úýHÖº|ÈWt$·Ð²vGuí×lðT¾+Qt³KµcM½_¿{Ò]þâPÑ_ÔÔŨlQÇ||!)¹ïÔJØónâw¼c_<Å9KžP0ʾÏë“Önv•>ÄÚWO6¥¥¿Ùû6gtš/ú+&¢îŠ7¤mÜnL=ü¢Ô­òVP«ÏºÁŒsnUsöµŸS’lEØ÷ɳæ!Ú”)ú«e¼çÀ@Þó÷ÈæÚ¿ÀåwGHf•X°F7×~ˆ+ç©|=Î]þÒQ0·§¤ñû%³óÞ£gBôVò²·úÃþͱowÙü1{j"¢õE1Ö¶üC[Vßûšc_DãaÑEù]{Ÿ¡eÉËCº”ÝÚµj¨:òå Œªw6€è/3`ÁÒ¯¹ö¯¹ç{S§Œ>¡]«†j¢ß½Elìy“ÏYìµµ =µfä©xùFDI‹õ)ý(Sä¸Jç%‹|Õ@Qj9ÕñD©* þþÀž{ãÍ €D‰²÷*mÂ’}Ž‚i}D¾<€æE6gЪRuÔ»‹Îwön옾ÀœžÐìo–¸">ËÓ(‰i15³îÙö"wÙSI~£Àw±çÝÄÓ²”buôû§\%¦ñžCÝ­3«c>ÚAËR8gñ}]ii¢E`³M‚/=M¢ìuLóqFCûÖ¶[ö% _øÙž7.ÇïÞû’ÈW.¢$áB3¾mâx«ÿ…1«™½3Ð{V„>\àwïUrޝcì¯9ù€®Ý¯wJ”=¼Öì3D¶`AKѺýêèw^—é'Ú\eÏ·÷Y¾Žfâ6 löLZÑùsCòÖ?Ú¿2쉲À¿å¦Ù5®ò—3EERó¿óËCzjÍˆÑ ÿ‹¾ëéëî÷T¼W÷5‰¢»QŠB@ò2‰<íO‰¢ëaKfçÿã½Gqû(&ò(çÜü¦#â@ÍêÄ{=%°YchE§õ˜·uvÍþöj__'š¢”,ºRëÿlvÆ‚‹®-è&°Ù1–ÌNOø¬?* ÖxÞ{|š-û†%‚/CÀ96Üë­~ÿ=αúE‘¯NõYÿlË8©¡}Ÿ›¸h°(C´¡U^^ºÖ(ß*A”â„«ä©ï-™½ç¸JŸJ¼Æ¨ú{ÍЗ’ê“·NÑ'o¨¹­Ù#ï¹Â 2ý­óµq_Œ XgÉÜW°`“cÁÙWä+®SG¿u—DÙý#ÞsôEgñCσ«ìÙDëéwšÓ“ß,(!s–_÷~9HRkFªˆ õ GEåõžªw7šO„­´å ™€E%7ÞeF”¦QÊRm»ßþÔÄ}{ÄïÚ©¹â{d†ióõI;þÐ'ï^JK~ô{Üy¶Q,ÊŒ=¦k¿v‹¶ÝÒG°èëà,šÝ«ß&Ñ”aO.¤(ôT½·Î|"tõt{9Ç:-€¶Ýï»’Jä©«©é tí×lu•ÎM¹’™êè…“Œ©™o™:—Í 8gÑ=ÿi3ÆNÅ·Ór^`T}çó¾“óD¾ò‚Câyï19ïÞ;–µÿ’ÜSk=ôIfÐòŽßŠþòÁÞšE¿×œˆûÆUö|{„¤~@€%ò4V"OcD6ÿZš°‚–%Z6OŨú¬Â‚}hß?-7ÎøTnš]£OÚ¸Ñêœs×MçÛ¿è¯ÐŠ‚9 ®N€h/Æ|«=‘&I­™éÚ¯Ùjê\6K÷íõ”¬ÝrÞsä%gጠÕe­¿&`еüô¾ùDèzó‰ÐõWp'`X ¢UGmÕ¢é"W•ÞÑLd†©S§ÂÇTQï £å¿ýe#…w®Ø,iCõyϾî€h—§âå'-íß²d´ ° óÙËBˆÙ{örUÈ£{ ZŸù›¨óÅ °YR{ÞØO€Ræè“w}Óôï’¸\EWŸ!eÇŠ.%Ó51 †`ÄZ—œ÷¾'Æ\”ÀõTü’§úã—8ן÷"Zóï9¬ª­|ªÈ õ)ZŸØz¾ö´ñ_1¥e¾Òµ| 8CÊžy­udQ{_Ë[³h3Ïfß ”ŒŒÿÕGHZLIc7;ìû¾þö¬}`¹«ìùöê¨WóDÁÚQÚÓ—²DióD¾jЕ¿“æAzjÍÈY4û:WÉÃiŸ½5_„aÑÑQªrJs‹®ög?”asË%?å­^xïù[ ò•´§òõ³÷Y0fÛ; gô°çXTË w¾ºïŒhjžÊ×ãêÞõ»vê‹rÀ" €(y¹(ØM×ÕÀ¿1fã)I¨K·èXà?E裥:X0÷ ümyk>HbV˜æTÔß·è/‘ز OÞõÅÄ™XZWÙü$sF§ÿ:‹èê³.3Øó§ôØÜ»(Z{@öx&Æþp{þý]eÏ·Ç¢‹¢å)?lÞ [ÎØQœs›Ú]ñZœ5{ø-ÿ´ŠÖòó#žª…QÖìa°àê%ÓYÙÐþ-§ûÍt•>™â©ZeË9Nð—L£˜È­WçÝ7é©5#‘¯2ùÝ=ç³þ,E@;0æb)‰i½&þ‡Eʰ§þrÎoNÛ†¼ÀÔ¹l–"ä‘'¼5ÿ{Ë–3|/¢dùûCiiâ7Êðg¿@´f7çÜô”ùD¨c.R¢ìý¬Üx—¹¡ý[2’_ùÊ;Á5ǵÐòŽoRœsöF´,oÍWÿç©z¿3Ek`Jì×#J}XûéZÞy³ß½ûsz\?Zš°CŸ¼kçÜø¡·æ³_}ÖŸw#JQ…[ZÞùG}Ò–µµ­J\–ôö Z}JäÍ£%ÊÞÏ.]×eÏŸ4 ¶áˆR³e 8{ÙQ½à1™aª¥~}âê’(ºYXÛJ k_õ¢Ïö›!ÚJ1a[4q‹>ÈÓXF=àiÞó÷x¿kw´L7æ~CÊ®¥Öìaï=>ÞÇbª)&úŸ?¢-”,a§§ò½€bT×?¥Ž~7«¡ýcÁç3ÿxAƒ¤š–%}aHÞüãÕy÷‡0Ž{Á!…:ò¹yèSAwY„µ­Ð \žJ¦½©†>s#÷b8çVµà;®‘é'WΜ­§{ÍÆ‚¹“1-žÏò£‰QpÐÒvþæ¾ù‰žKÅãÕØ™Óð%×FB(ÖhLú 2˜æ~ĘCî’ÿKãÙ¬‘¦¥í 5q_«[G`³¤žÊ·S)iœMñb!@íCÙ~×ö΋”DÑ=Ký^6€9=îcš‰þ‹QÙï÷He”}N©¢ÞÌmhßÞêO"üî½çŒºTE¾t4ðˆ@ká³}I»ŠæaŒ]—³=BI5#;\Ë;‹MóY—|Úµz`KÇÒ”ÎLhÌ‘žÚU Óßf[c¶‘j†»@3ü¼ÜóõΈà„«cÿ—éç«CËR¸ú‰N>¿ÂçŸo›3‰¬Ád }¤BúÈ9—% "‘¤D$Š®GDyIKÇA´~­ËFSeKÇA´>rãÔ,zmé8š IjAD÷ÍÑ–Ž†Ž'>jéˆÖ‰Qõ÷0ªþmö»„Œ~$‚ Ú ’Ô‚ ˆ6#¨.?r¬•’z6‘DÜÆ°¾¢&ÿr¬ Éä…äo¥­áLCú­@ÛÒ¡͢ć1ö4EK! Èû›¢-¢µñøŽTaŒ½—³5B@Ñ´1­ˆ4I ‚ .†\ž!‚ Ú ’Ô‚ ˆ6ƒ$5‚ ¢Í #€ˆ6§vP\p1L"haŒñ%ÍŸÚ„ Ê&Œ‡h]|A“ÔB FÕ+QªV»â*qy0oÇ~ïÑ"Œ±¯)Ú£¥qzF7*”¢´dT›"‚ß¹Ý9WÐ-3Lˆa4ÃÉUª6FðoÍWA“ÔÍHZ|³ôæ.{ò{›pÖJŽdÚñHª¾áœeVˆ &rÈîÞÅɈ¢  0Ü4+8—ÆÃF{jADB’AÑf¤FA´$©A4¿û@£¦ßâ}2Q°6z”®Àå3"_I‹‚•æ}²Ænl{œHR#‚höüÛ\>s©õùw<ì.9¥ñû™6ÕYôpwé;;ò§ÝÛØíƒ#ÚýîÒgÒ.µ>IjAgðžÃrGáÝ=l9£Ç8 gõ ”Ûs' ±žp§»üÅvgëzËm9£ÆZ³‡Mùʳ= Ëgl¹ãFbÌ!Ÿu‰Ñš=|‚ϲØxÝYühš5{øŒÅs ÆrÎêi=ÝÿNoõçá¬}Öš5x’-{ä8αYs¾¸…sº[O_?Ýž?¥Ýr¿û€Âš=l‚5kè­>ë2€»â8gÉã­Yƒn÷Y—9Çf5{ÄxOÕ¨úíÚó§ôw?šfË5ÀU2·ƒ-gÌè@ò¶çOéh‹µ­Ô9 fô¶åŒ8¼/CfË5ÖUúd €«ô©doõçáãç(˜Ù €µý¦·f¿Å[óuèÙãTòxGkö° b£F铤Fq†ßý—žµ¯þŒå=‡Y³N ¼Æ¨úòš?î©|/Z¬´-ç¦/­³S’ˆ Ñ_Éø;tÖ¬áïÑLL¥§âõwÙ³Ïвöù®²^aík´¶Ü[†rÎÍ“(‰©Z䫇×ß¿%£ËK›—(Qö>"ò Á—¡¥eÉ9Qé(ºïõ†böT¾ãwí˜ÆhFìA”æ_+]¾tÍD—Ò²ö®ÒyopÎ-=Xë²çii|¾è¯”9Šî}›–&y«ÿ÷¸»ü•øמGü®?GH”}2-§ûÍäÜ{ú!Ú`³e|½öõ½÷ùÛG JcsÝÿ“Àå%м9Êž;ñ[ÎèO¥v±ö5·[³GŒÇ‚Sî©þd€³ä‰®0Þ]ñV¬«äÉhYûwÅk/ú¬Ë ö¼I9ûºi”$´JôWÞØ˜ß!IjAu JuBŸ¸r›6þ»Ï®x(€(XÂXǺÛ0ÍÚW p=Ô‡bÂöèÚ-Ý£k÷ó>‰¢«ÀUöì—Š»hâ>?ÎÚVÝ„1fü®=7ˆ2OÕûÃߩ኿ҵ[º‡¢uëîWô—H0öFRv-ÕÄ~˜¡Š|©€b¢½¼çà`¿çÐh½‰ Ý·“(º80挜}åZ–d®û-KôòÞ“}ýî½ãsažÊwbhiüZmÂYÛŠXâw gí«ë'QÛîç/ÔQ¯æ‰\ñX,8¢yïÑaXpvaík´HÔ¶ûù+}ÒÚM€h·!e÷UÄùÊnžÊwb’—ëگإŠ|åSÍ©‰ûììi¢`¥6g”:úõ¬mÙX bà8I½ÕŸ ç½'‡ËM3éÚýºÑúýùýÕÃ×AÍs!œ{!©Ù]þR‚ÈWw0¥zÕ’ÙçŒ9…DžZÆ{œÓƒ åißùÌ?Ü£}øDëË$ÒèÓúÄ5›¯[NuØÓ&(ǘ3ÕÝ–bbx 0æBR à©|÷NFuývMÜçÇkŽG®ý%ç ‘jÇ8B:Íq?–æ­þø=UÄÓg{—®Òù·PÒ¸ }âÊm5'ã¾y‹Ñj;% /,ì0tØósƒÇQ>‰<­ý§¼X÷ù‡Œz;ð²=$^D;këiÀX¨úY=ÕŸkxïQ#¢ä•µï3b¯=wü$„¤vFÕ߃hC¹DZ¤OÚ°þŸãÔ#L`óŒP„1רµIR#‚ø,1§'½‹± iG})ÓO¬ðÖ|hNïð Æ¾ЉܣŠ|¡Ðg]ê1§§¼ ˆâ5±ÿ[ ÿj½«d®ÝšÙçuuÌûo¸JæÎ3g¤õ,È¥º1¿ÈôWzÍßÎãÉn¨—Ô$ò´e–ŒÔ÷)ªe÷í´4á8ëØx/—žäÀ Nè(º·›ß¹s ©ц¿ë¾FËS38çæÍéI£óçÜ“Ó&|»×’Ù{¨9#õ9L3Ê^ëµ ?hh?ŒzèŽÂ9Ï’Ús:S§¬g/tõ 7%ÑgšÓS^,¨dú _(Bî]é*¿A¦{?€&fá&{Þäù挴ë r©vä¯2Ãí«½5_äwPø¬¿ÄpÎ3=•ïEcÑE‰þ‰«dnŸuI£î›4™~¢Í²kiKÇA\>rO¸¦aÞ’„A±Öe6Ä„U‰þ²>ówZOåûÝT‘Ï?)7ͪ¶dt~ÑÚ"OÕ»!.T†Ï+ lï*{æM„¤fD)ª½5Ÿ+Mi§^säO½ öÖ¾ª=%‰8iHٱ–3j¬Àæ B’ Á—¨ööˆ£èÞn~ÇÖYš¸/^´é³üæ)ý+$ Ù…[wÅ;'¢xOåûÝ vÝÃÙיܕï¾DÑútOåÂcêáÿs—½Ôµ¯z¢5y"_=6¸JŸ(™WŸ´a½«ì™I´4.QʳgÍæŒÎO!JêÄ坯I5C—hâ¾<xÍ–{Ë0Á—> Ü‚Ew'€Úg”XûêˆÖyª>ŠÒµûåM,zâ_úõ¬M ß©Ÿå‡­Ë÷V}ÔÞÔ)ûiGѽÝ8ÇÖÙvÄïÞïD” Øé³-A1‘k\eóß¡™¸-1¥H\ IDATœ{Tn¸ãû«ñ;¿¼ç°œ–§pˆR7ùí¿û€ârz —Ûfc÷'°ÙR$ (Ú”«\žqM£¤1‡iiû]úäÍ«­;aL=¾P¢HûÕg]ÒßYxO/‘¡˜È6¦"ÿbïÛSµ0 ‹ÎdŠ‰Î¦˜èCœsçmu_ç½ÇoÕ&üü’)íäÛhëXw;Å„ ˜¨\ŒÙ0Ö¾&Ѻ ©î–?tí–îamË'"Ú˜E1‘y€™³øÑ4¿sçeøão;ìûÞ²ý7™þ¶ÃˆRç;ìû0‡‹RŠ +Ó'­ÿñr‡MÍœ‘öŒ½`úcœcë%_V½KfßÙÛó'}ÜTíÔ> à(œñäù^wÜõLcÚ³çÝ~¯«d^×+ìòØó§ô<¬}9HR#®u¸î¨2D©*kÿ¯vèÕ`Á©ĸ(ZçÈ;•éÆmªßEëj‡<#Êùj©«äñg(iL¹"ô¡_óúÚ½`цõ#$qbÌ«0î¼vÉÏÄ¡r#J]U[&õ`Á¡ÆØ¯Jqfµ„âG È¥ ÄÁÕþŸa1ö×½úºí‹þ*%å¥hƒ–ÆKucë éÆ Å„òg‚©ÝæUˆÒØ(ZçªoøV¢ìa­=~"ª}‹~5¢UVŠÖ9uÿ_õ€ AFIBÏ®T(F o¹iv:úÿýåq–Œ®ß`̵øÀŽ‚™½°`íK3Q¢¿DQ{rèDOÕ‡‘gf½˜˜Ã[óe˜³øÑ4kÖÐ‰Ž‚é½YÛozkÖàIžÊ÷¢ë¶é*›Ÿ$r…­YCoõÖ|pæÞföð ~÷Þ³«p;‹êlË7Rô—œsÍgþ6Äš=|Bà2­»â­XgÉÿ¥Z³Ofí EMµ½,[öÈq΢ºf‘(¯[_Ûþ#\¥O'Y³O\"öY—­Yƒn·åŒS7–ú3‡Ø²GŽp•>dË560÷$ƲåÞ<ž?­_`¿Ž‚é½ï¥îL'îŠ×âlÙ#Çž¹óÖ|jÍ<Éš5xò™KæãYûº[íy“6ö÷@’qc”=3x6{Ìù>@šø/þÄ¢7Jð—E‰|‰g³Ï^ì­ùê~kÖÀ)‹ŒÜ4»@d®0ÖSõÁÀ´4f«åT·çìy· ” $á‡eº›¾´åÝö^Ý{j#ÓßèwïiÍ6AôWöWǼ»QöÞà³|ÿkÖ Û±àì ÕÝtXðeM´fŸ òUƒê¶¡Ž~+!šØ‚DQ°k6'¦îë´´ÝF[ÎØÿZ2ûÎÆØÀ¨.Øìá¢àÐl^2`Ž¢˜ˆS¬í÷;œE÷u“jG-Ù‚Á¢`Ó \A{ÌÛ‰¢ÇïîÒgŸ³åÞ2Ôž7q°Ü8ÃŒEoŒ5{ÄxgÉã½5ßF’°R@´ZAR“({”P‰²ûiα¹#k[úÅ„W8‹ÿó ÍD–¹+ß|ÅUöl"çÜ’ÌÚV¼F1¡•œkçý®ÒùOPLt‰§êÃ×þÕ¦¢›í’(»eJäÝ€•ß½{¢TNGÁÌ,§®{˜÷žLC”ÊmÍörÝí=U £\å/¾C3‘e®’'?ðY›üέÝYë²iil!%1øýî½3¬Ù£ÞJéñ{ö÷»v? àwÿu7çÚ9šµ-{€b¢‹=ï¼ ø2µyZ&¢õvGÁôWÏw\ü®½÷û[ÇJT½2­Y7ÜÁ9·¥$¡5öܛߨ¿ÛsXô*EIçÜþjí6{¦ñ¾,yÝl9£Ç°Ö¥·QÒèr{þ”wܯ?+QtÊ”ÈSO‹¼E”¼š¢õ%e÷ÂËù’¤F\ÓÔÑïd«£^yb¬ ã]§ä¦käÆÇ䯙›(I¸`ê”õÍÄ”"JíR†>v¼~аG>£˜èbS§ÌÇtí–=KÑZ»Ü8ã¹a곆{R„<°‹#ÕŽÉ—g‘glÑÄ~œ¡ âuÞ{âì¥.™v´YnœúMmÓO*L3ÖŸ‰i³Ü8ó¨*ò…B]Âs)Ix¥1õÐ=´´_›°ø "ìÿÞ£˜ˆREØãsäÆ)ʰÇÊ•á?MÑz‹2üÉGäÆ'ä†;³äÆ+Lrž”(»ž DEÈýÿz6ɲýw™î–%e×à Ó=ÿßÞy‡GQ}}üÜi;Û[zƒ„„* Šˆ4EAAQ׆+*XD”&±,(Š]‘* ‚RHï}ûÌ–i÷ýc³qÄþ÷ó<>nfîœ{çnÈ9÷œï™FªÒC·×º¯Ÿ€¥î›Ë/u™{nÙÄZ®{Q±}ÒsÆŸÍ eRÕ«µ^×lLÛ°K—´â ÀE놘z|~+ɤ԰¦+ª :¾!B1¦®Ÿõwì_ý^413둼.qiAÅm1¦~°Gp=€T¥}nèþî>Z3p½àþntëùŒ©í&¨øÝ¤*m1uý^DhªCÁ4¬yªÉ듞+F("É”þõ:SÏ·„°©aŒ"µ¤K¾ÜXv Wß8>I©û­7twÉöÜèkym$Á¤|mèþî>J3€î(´©Ç¦­ÆÔ^ïìþhÝùïS×ïE¤¶„oX’LPÑ~‘ß3Zòe.»³`¨V°>eÍ]Ââ9Pq)VøÑ{p –ù^~ûÛV,ó©æž?|nÎØùB¤ëDó+ù '`,èE~ßXÀþD®nn‚Ô— îÍ×)R£…1\ä!]AÇUkã«ú_DE"DÖrƒµÜ``Ü*ÓD¸‚¡Å†îoïïìZ„(·:êöMô=õ¡c”æ,¿1íÓíÛjbfÖkbfÖ‡r„_ @ªz Úø*ã¥nh“:zFc¨ ­ÎuÃjg?úžzè`Kó@Äù…ü?k+¢(¡KüŠ"§¢«ê¿cƒYešØirsWúöÛß³ªÌ“í®Ò‰c©©›¥×/kOÕ§ÈïS“lOá÷†ðœMŒá"wÈm,ùް“,Ú ú­ê]5 ¨f®ÌòÛµ›Œ´~8Gfcœ›L¬y²ã÷ôß‘¢Èá~´ô›‰±`ÀŠ?š ÌX ˜°â‹¥Õ}?3öøl»½ðì›±ìê€ ÖrÝ:mü¼Ê–£©Ï#D{d–R÷ßdLûd§Èï½öÛ Üo €Ì"ÂPaÉ:¸ÚqlèuŠÔÒ @Q©cf®ð5¿t`™E¤¾ÊÒëà˶¼Œ'ÕQ·­‘…2³àÙq)­ò½ì?–eÎÜýž¯yM¬·ùÅiÖì£Ï†ÆlËË\ˆ¢Žºý _˺ëK‚ŽÉ7gìüˆ«}¨gÀ¹ézLL·½¦ž›¿´¼+|,0¦mxNðlOS¤Æ8¡xL?‚Ô»iŸn÷TÝÑGôhH^ý»ò¦Û1˜b–¬_Ÿw•]u¾ä;r iÝy›B. DZó® Þ&UÆËÞÖ%-?fËë±ãÄŠ?šRç|.Ì*r{Ì"÷ã(Èo9Ú} BŒcQÏƼjHYwN<Õwçž­-Y¿.FˆÁ­ó~5çØ|€à?TWù”‡ Ý^_r¿„tò*>Wÿø÷Šd£}Í/2glÿä÷öoËï5Ïš]¸Ð–Ÿ=ל±mÉÉ”#\åW5¦~¸çßm×Çó×ÙËyÄÔã³§R´8]ø;4€“ýaï’„•cC¾~áH‚ŽÉ×'­ìRšÄÍ™S™&µw¶Ž bÚögÛÄŽ»vbÛ¾B þ³ Z8g„û〉T¥ÿÕ»ü^E¨¯2MúМ±åAÑwøJK¯}¯³Öë_%è„Cç'—`…ÏÒ&,ZfÉ.˜-z÷Okµü¿ßDÐ ‡¬9%a…‹÷6­HÀدG”¥ÄšSò`ÀñÉP’évÀšS<Ë\ß°$Y3ó%oó óÎ/féŸY­O~þWY¬ àkY{­°­Ã˜­´fðwÖìü§}-ë®cô£¿Ô'¯\¡ˆuƒE~Ÿ:àÜ8]÷ÈóÖœ¢ÇL=7鮜Þ0&õI+Ÿ#¨è®æÁ @ñ² øµê¨é»DïáËnÛ$•aì®öá1ˆŠªÔ'­\ ØS=3[òå^Hk‡|jÉÎ]¾ ˜3w¯WGݺ–T¥í –ØÀН»&æþµ–¬ƒ÷K¾£íò˜°â¥0˜Z?gš3¶ÎÓÅÏ{Bôì˜ò7|År $K¶îʛθ¾˜ªÈŽóBáå\ͬ ±Ì¥sµs/]ƒeW?]ⲕ€E•§úž»å@©N«ÏíÌ>ß°$ÙoÏ |»åjfe†‡lcÅ›Òúÿ$À"êrus{„oÚK¾#¬Èí¾ÃÛ¸,Qävjƒöö©Î&è€,”Ó‚ûƒ·ù…øpe¿ý=+W7·GÇöÞæâCaê¡ñ„އ·ûM)åC›MÇ9PÌð K’ÃÛ†©‘$†ÔH"üý{|¶Ýšsl¾9ãÇO$›õwcéuà•£ßgÄ›£;¿¦A—ðdY𨬰å¥?KP1‡Q¢"{Ò¢\aOH‘Ûç ‘ª´ D+Eî§4Ší•  HÍéŒá¢M¡ó¿·‡!í£|ã³€Muh• ¢÷¹Ê§UdÛY†îï¼ÔqÌšØÙ¹Xqg‰ÜvAävȈÐUJÞƒ¬bƒáá­wâ/ÈÁ²³'W;炎«ÅÏ£«¸Ú9„¯ù¥8¬øâµñO”Ûò{O,j¹Ú9I€d¤{äyoÓóSmy=ocôcVº½v(dß–—¹QæR‚ÐÛ±ÌuåPGÝÖlqâ곈`K :Ib­7µpõó—¢öÿ÷•Ä'ùó,¢Ûæ] ׯ=6›o\¼6"Ee¼Ô-r;ø:]ÌDn§ÖU1m AYsË4k¹ö%Oõ}S¢öcïfM“^Ô%-?Öñ:{áYwVh ÔN¬ðŒ>é¹Áóƒ°dõ;?#‹5ûø†ÅÝä@É@Œ‹oXä°ôúeMȆ·qEÏ€óãŽÃÛ¸"Ue¸ømâÓù|ÃâéˆÔ5¶}÷asÆö»iRƒ–"ÒP†AR©£g,P¤FÒQ4âQ’N:¤‰¾çË]wÅõ£Ép}‘BO•™3w¯çjÅ#‚mñÛÞ4Xs t¦Fr&£ÈR멽•üýb©…  >ÝÕ@NFW•QÎø'(Œ„•@´:zÆ·Xv%üv\68KÆŽóTÝÑ€ä;þˆÜ®Ë½Ë±a¸6nÎàQPê>? îo'·ž¦‰{hŸãØy·L÷Í€(ÞY:q$€&úîE϶ù¸£³±!B­L·ï€P»ôÉÏ¿Aë.ØÊÇÚ Êr(˜Œ¸OímZÏZoþ¦ÔQ36¨£ïüˆÖ j·F±Ù_ð ‹—’L·­ŒnØ7š¸¹ï©ÌS7ÑÚ³Dßáh}ÊÚ×(6çcÉ—; ý<ù’4Q·¥ÈÎÓnQúÓj¦é¹É_p¹)ýëyÖì¼ÅŠØ4¤ãC ¶Ê’udk¹æ9Û>‘ Í2£þ`…ÀW;g°§jÆDY ,Y‡^´få.“ŽÂ¡KiÍÀïL=7nR}×ÏihAˆuÊBÕØÐqÖrÍ+–¬#+0öÅc, Éwä cêGóÃÕHÎdøºy™îò©wþÓýr5³ú¹Ê¯¾%ü˜»ò–Ëùº¹Yµ÷5¯‰u–Œ÷ό«J,gÄ¢F±Y;(u7©Êø@iÔS?ØC©löÛß¹Juó-!‚õ˜3v|lîùÝr,;¢‚Š €èmÜÜÏŽsæ×ˆŠ’Léßl ™nEîªÛïù½C¡QLé_½„Ç]9m–ä;§Žº¥Ym¶Ü×òòT_ó‹×(ˆÒô¯ Ô}èS^ÜNPÑ?kã|üyÍÆpÑ|ýÓŽ'R+r $É]9m6–QúäßÊpñ*¾qÙt’I)"ÙŒÏ:›ËvãW÷sRlöÎSµ;] Ô½¿—üw蓟o G÷ÛÞ¹+‚Õv´Ç Œ1ÇGW ÄÔZ{—>`Í)uÂx% Fˆm{ªTÄÊÛüÒc´î‚ý”ºÏf¬ø«¥`É:ü©J=Æ7.›ë,½´Ct) P¨Ðï „±ìl÷o!2¸¿A€e_??Upo¾–5OùŽ -‡±d³bÅ«Aˆö¶ïa@¤O‘]耧zæƒÓ¬‰¹÷©í,;L#ÊÛi·—æ,7ÖqlØÿ…”A®/ žª;ú8‹/﮸~p¨]HAD*ã;ÚàjÌàjfe:ŠÎ¿š«›“Î7<•â(9)X-:ˆ»âº³]eWŽ87ƒØA\e“‡]ÉÎ’ñyªgf‡ÎùíïYELVÄú˜ŽýÒÚ!¿ÒÚsê}ÍkbƒŠ##¯ðTßÙÀïüè\É_x…£häÁR:;µÎâ /ãžNéhÇ]yóY\탎¢‘“BÂAE’3ÇλV‘$_¿°›³øÂËD~&¨(2q@08ÄU6é¾~~jhe¡œvU\;Ä×¼&6¤Âr…+b å,¾h¼£hø”âJhÞE#'uüwpn4¹Ê§œw¢ïïŒp?†ç™{þðyÇÏ­ÇE5š3¶}Úîç°kÝ¿jãçm ýÜ1Oɘº~/´…Öš3~ü X½Öœ±ó#9P̸ʮ¼› ¬ûÃó9B˜Ò¿û*ô:¥5`Oû6ß| ߆~ÖÆ/¨ÐÆ/XÕÙLªhÉ:ôbø±ÖÈĶèD֥Ι-x¶$œ—Òº¡KDþçËÝ7€&î‘#žê™«ýˆn÷µ©kç9<ÛF(’­/­=÷]¿ííEˆ4ÿB©³wsÕ÷>¡2^z¿­ Ï,‚Ð7¡qÛ ,2gîzÌS}Ïýz€›}-¯EK¾ƒ—À.GÑÈçݰ·DnÇ(gɸdmÜ#»¸ÚG–3ú/ Ü7”åèqýЇ°Â«Eþ§{iݰ•××wôSÏTt“"TÛ(M¿B¬ð„«üšµ´nØj¿íõ{$_îFcêûmy"·ëJJ3è wÅ /[s § ÜŽ‹±Ì'3ú‘oyªî"y\Ni}æ*›²Î’{ƒ"6ts¸R‘zSlŸ-€hÙײîvMììyžªbÅ«”‘Ûý ­±8àøp†"T¤Žšž(““$­U|ÃS‹UÆq·\_[øú§–0† _À §‹ox*Å×òêÚ˜ûÛ©¶„sF,j„PÈigX³ N8a]…Tõ,YGVüY;þ^Xë?cÉÆ B§„°U¦«*b=Åšÿo.A'I­Z–ë“…*ZešÔNÆHešÐ„ÏËíìš';hí Û¸šÎ#éÄf‚Š•u‰Oßçw|Ü_÷È"ElP°¦ÉKƒí§¬@TŒÌèGïù½½T¦Iý¶7Ä’uèY¾vNAÅùÌ™»ÞçžNQÄz>ù…7:ÞAÇ~KÐIU*óÕ;BÉÝKKeA7÷^DšD’I-ÙG¦{ªn?:_h<ˆÐ)Öì‚'Ý•Óûc…#B!ÛÆ›æóuÃèG~€e×g¬åêH6+ÐzËiVÌÛ6rµ¤+²MËèGN#Ui§ÍÛ"tŠ"5v“EÃ0åm~i©êY(ËncÚ§ÛÝ•7z$_î ¾n¾Š ¶º¿³ßUv+Šu´EkúlL]¿×–×£šµ\ó6îѪ–£ÝnÀ’³·¹OÐåÛ’›| ©/öTÏÌùŸÎ¡Ô6yªïÎ,ĉރc+Œì/ìÁ7.•I&å{C÷wö;K/5)b]§yoÿƒ1õ£ÝÎ’‹ ‚{Ë Z;8WòåÙõIϸ+o>‹ ¢~6¦~°‡«™ek k—ÌÏƾ§O~!ß^Ðw(Wó@Zwîû†n¯²åg=®2_½V—°¨Ô^Ð÷®æþþæÌß´íñ:"õÅÆ´ »|-¯YDn§VòoL]ÿ ·qÅ@‚ŽÞnL}ÿ'OõL—àÙr™ŽÍ<(Êr$%7°ÂruóûÈþüÞ”fÀ»áûþ€%£¯ù奆n¯Þ^o®#ÿÙE-B€V £è“Wåt ä)ltÌÍ£Øì€.aQiG;$“*†{Z•K¶´³ÙÚ‡.ñÙb€ÖœÃNóbpø˜Â•<Úµ#X ÃS?h÷æß:Ævã$H³lLýhwÇñº½úkÇû4¦ml·?¬KXܦ:º‡àçãÕHNÜ•· % µfY¹+®ì,;ÎU>uè©îÅ]yËgÉØñîÊ›Ï:.@à”¿óû‰Ð]âÒ¢;¬út…1\\¡H-gÛò2žÂ²»Ó€ €à ¶¼Œ§å@éÅ'jw"hÍ€E,±åõ\ÚÃÖ'=W€eW?‚4å#B§¨£niF¤¾Æ–ßk¾-?ûQGÑÈIºäçs±Â'Úò2ž–…ªÑ¿§OMÜ#U ¬¶¼^ ÔÑ3êQ^[^æBÉ»ï*ÖrÍ—Û‹Þ_'Ùò2žDs¥ÜXË5_ŠÜOSƒù¶4GëFØüö÷æêŸ}œÑ\*wcèþúEjº”1\ÜVx+¾[^Ï%¢÷àdµõ†ohÍÙEr ê"[^ÏÅXñ%蓟ߡHM}mù½æÙòs ]kéõË„¨€½ ÿ½'ºÏ3BQÄS™…‘í IDAT=3[ešXÕY¹õ¿Á³UpnJ =Áÿ<Õ3³®OgSlÖ'”zÀ±Îžb[Žv[G©2>Wdg¬"Ö!™n_š3÷tšò6­¼K‘y²P66ªwå ®fV¦ßñÑ#ÇOrœg;Úc­¶QcAoÍ)šÛÙýÐÚ³}ˆÐþp~/¸¾¸I7w©Êr­Ív4ý5h^ô6½ø°·q¥QQ»(ÍYþ€k8gí]7ÙS=3ÛoïjRÕýuEjhÍ)uü¤ùIÀþkïú‰r ˜q]jHyéq‘ßkõ;>¼Ž ¢_Å2—`Í)y¨µnWfëüµª®à€c‰Þ_¯2¤¬~TTª½MËï#¨¨—dVŸüÒ’Ð/¥ß¹¡,|oà oÓªø‚¾¯å•˜PÒ¹¯yM,¥éëiUó¨dô£l’ÿ¨–Ò âŽâµñ *øúÝ :™WGÝÒ²‡±€øºy=T¦ u‚û‡hÛy£·qY=uKC('2àúr4B´ÆÍXqk±ÂY¼Ë㸖ðD^_óšXÖz]3"tŠä;ÂbÙI Ü ­=ÛAë†ñÞÆeÉšØÙÕáz‚{³^ô˜¦Žºs>k¾²1àÜdIJDbÖrƒÍ×òJŒÊ<ÙFfY‘¤èÙ¦W$Za-7ؼM+TÆËZÂ{%¾*4”æ,VøE¬gù†§SÂ÷÷°Â~Û»ÑáU"œ^„¢¹ÿ *ã¥n•ñÒáÇôI+  ðÏÚ>gÄ¢IÅ ÒÐ( UñŠØØT¥¶¹ ×7Š`­75zW„J"”¤Y&Ué6Dê ÊlSĆdh‹BC[JP±²:zF#߸8^pÿ`@ˆâØz¿ã#è¢Ì»­Ù…msŽâÑ—tÌ Ÿœ©‘Ä ŸCë.höµ¼Ó¦,‚’HR[oX©HMÀ¹ñ!Ej$ƒcÓT°–«+®Mi‚ëËtD `øí^ô¹>ۛɀý mj%Tt‘Àý˜†HC5I'×(bc& @°Ê±dcŽ, øº…®ETT6î±*‘ßû­§êö…@¨­ÙyKN4†oó ñ¾¦çg"ÒXæk~>Ã’uø!_óê«ÎO‹¡ñJþ¼*ãåëCjû·ùš_Y€U#Á$ÿ,WÞl‘|¹g5Þ¦çkvî2OÕ}îïn!è˜C"ÿHƒp Îïüx ­ºh}JŲ3FLJ.D™œŠP=ÖoÛâmZÕ_—¸ä~•i¢Ã^pÖ“ˆ4Tz›–fjbX*x¶õùŸî"(ëϾæÎF¤ùW„(Ÿ¯e]ϨÞå÷„î+àÜØ!.àúl–í{ü¶·W"ʺ›Ñ_ð_¿h&"T¾aqšÊxÉZŠíÛÌ×/xQQ;°ììÃ7<›‹!yWö7glZØ÷æ6UZ¨ÜàmZù"´u~Û±Öœâ9žª;úž-S©¯õ6¯Šú+"‰ÿI0ì/TuUãQ3ˆ4È+KÞƒ,©îø'«6ÈB9;sÝuÉŸ¯"™±+µì:S0èºÒV8B”1§šÛßûtäŒ9*ãøÍ"¿jÐÝötJPHSa¹Ú3\¥“&TÔÏÆ>kžìÀXf]×ájç^×>A¶,¸ºÇÓ¸ºÇÓüö·­šè{·Éþ’ Þ¦ !• €€sSwWéå#dž>CP±_2úQA™s%cÇ{jîË@JHÏ ‘AŸ¼*Ÿ`·¹Ê¦LPd×`®ö‘tOõýW“tÂn]Òò_©ù®nn_óšØpÀÐÈZ£âccô£7ë’V¼Ik‡üª{ô "6 õ6.KùŸ/úµÚÛ´*Þ×òêUÁˆ> Ô´öÜú”Õ¯ÓÚ!û}-¯E3ºáún¯>ŽOV8!ÚÅÕ>’ÞÉþUü¶·.C¤¡œ ãËÉSuÇ@SƶՒ¿à2Ñ»š©ÇKt‰KJBjÁÂ…˜ÔÄÌzÎÜsëgšØÙyP @HXn†±€ÏÖÉšèË,™{ß2gìø˜µÜð "4e–̽o…»]:þ ©ê¹ÝÔóû¯iþÕ’udÉf~ì·½y®»òÖ!˜ èø2DK|¶·Æµ¶ûÅ’ud%AÇí ¨¨KÖ¯Ï#DzÃu õ)/ç†ÆLPQ> ˜FkvÞbŠÍiPhKÖ‘•¬ùª϶˃ƒQÕY³>Ki¾€IKÖ‘·“¯_Ø/dS3³¾MÕ¤5”1\ò¦%ëðsKz9PÌž-Wt¯P‚¾{x±ÌÓ˺XWÙUzP:b/<ûfg鄇½MÏw·åg=~¦èÙÑå æGÑùW;‹/~Œ¯_˜ãª¸vö±á*›2“¯_xœhgðu÷rWÞ4 +a?vδ6'Qúàëtw•^>À×¼&ÞU6å8OVGŽ wÅõ3º2¦Î8#5ŠÍÞE©ûÛ)ußBJÓ¿€R÷Í£ÔJµñ *T¦‰«½M+o\_Ð%.yTðl¿!J4öøt-ÀoJ”º·‹b³w?;(u;Åfï o@µ~6¥mœ¥5)_‚HmyøØhMÿ&DèË×ã×ãÎOû¨L]ꨛžôÛÞœp~:.dKä®HM‰´~Ô;Öì¼ÅÆ´O^ÄX¢EnϹú¤sH6ó;Šíã0¤¼òa¨!AZv îo/A¤ÞfLÿꂊ•5q=,¸¾¾Ø×²æjÀ¿¹¬I6‹#Ù¬6õ }ÒŠGD~ÏÙžê»ïUÄF#¥îëg­7<å³½y AÇå†Ú©L“–ùZÖ]OªRsI¶×­cxTòçe¹+o™¥µVùíï]驾÷•qÂò`$×+nûy¾–uiÉ—þWBj7AÝ´vÈFF?ª<¨ÎÑZ`Q­)a+‰!ך»âú›@ñj5±³>„¥&@VT´ÿ·ædÛn{¥-Ä©k@„–ÊOͤÑM±Ù¿¨Œ—n ¶ÓÝzˆöTt«‹ôËB…æD·‰M€";hUA¤ÑXVǨjí[ã …w#Äø°ìÑv°Ôî¡Ö¶B*À’‘'AÝŒnø+¤*ã_Õý“ gÉÅ—„j*b Rù}jwåôþ\탊X=‘ âŽÊþ¢x,;‘tâQÆp¡'àÜhržèky-€¯ŸŸê©¹¿—£hø”pE‘p\åS‡ºÊ®á*»êüߎ]=4¨:råpwå]eWŒÀ Gpu§É’©p˜1\\IiÎÚ, å´«lÒÁý,Wù5ç´*¾<$¬ ੾³·£xÌ„Ž…DÏV§ê¶~AU“€s£Iòç«Ü•7¤µç6К!‡¸šú(B厢‘W„Ä­Ý•7t–Œ/Š™p{÷·ˆ¾Ã“œÅ^:æ,7ÖU~õÐh¸"ÖPáª)”ºOiîüm®º¯®pF¸C‰~áå ôÉ/æµ}jèµéè±æ©vÖ‚¶Ÿ(ׯ?±¢£­Žªž‚¹ç–v2[¦ô¯¿ }¦Ô}ýæŒíŸðõóS‘~K֯힚4Ñ÷Ôk¢ï9NL™Ñâý¨¶Ê*Ó$§Ê4éð6º„E¥º„EK¹º9éççéÇÏ%@p3—1\ØÎ搜º­ò‰&vv­&vö[Ý㿉Ê4i£ÏöÖ,DmXጲXßÀ—\z+­9ëBq–\:Ûš·!Úé(º`2kžòc;ŠìHð6­¸ c1€Ò ÞÈ×?9×ïüì „ŘöévOõÌGñè‰ú¤•ß…Ü*”ºoaÀõù®ò)n†RÖl³v¥,Ö' D z~'ڸǪ|-¯Ee–jΡ4C6üžë¡/²¹Ie¼x{gç)í$ï‰Àf¯HMIˆPåuÖîEvŒ$‘j«ä=8ÜQt~º6nÞ×"·çÿ`¿Èï2‹ÜWhãç=°ÞKiúT /ò{¼”¦‘·ñÙ$_óšY´aô›|ÃSóÁ.<[†ÈÊKýÈI:á¸Dt¬p„àÞü"­9kž¢p{Aÿ–¬_Ÿ<ÛQªô×T¦Ë·Ûò³%™ä_±~{áÙs´ñO¬ ü”¦_‰EnÏu$“ú³ä/ì,HȾ£—1Ʊ¯sµ¤œßFëG¾ÇÕÍ}Š ãô6­8W”¡ØÞÛ%ß‘Ñðqh,”:Çç®üîNfˆÜ®‡©åM‚Ži™’/w0k½q¸¾æ(M¿B‚éÀJ Eög¢WÙ•w‡‹N¤±Ë®æÐˆ"Û/ QÆ’ïÈ(WÙd•©Ç¦möcÃVUSvŽr–\ÜMešôK«¢ÉAÁ³íIRÕã-ÖtÅÖŽóv"ΈEí߯œ±óø´˜ÖEòo ÄÐ%,.Ñ%,~æï°ýo£_PÁZ®ÅÕ<8”P¥–©­7Ô)bÍ!MGOõÝ6¬p„¹×þGøºÇ{!*&R0elY멺ól‚Šq1úÑ[#Sßÿ)àú2Ï×üòZ7ò€)ý«Û½M«²©o MÖ'¯Ê§5ýŸ½cÃØE¨,P[§T¤† “$kNÑžÊ[aůÒÄÜŸ+ Õ*E¬/P[®ÿŽ`ºyXËÿ½¡2^Ö~o¡q2ÆK›±â3tÜšsìOå-ƒÔÑwÿÀš';d¡œV¤úׂ}ß'J*Xë´ÍÕî°%ëà2¾nnO‚Šñ©ÌS_aô£\*˔Քv×h¸ð'‘Ûy„o|v(­pðß*òg@„6×ÔcÓVÉ{p³lÒsðuÇ6¬åZW7‡‰NûZÖðºÄg‹í…ƒnÀ)‘Û=@a|-kGªŸw”Úkß'SnÉM~!ªÅœ¹ç]Ej$½+†…~q°d?—5O^ÄÕÎâõIÏHÞƒm.}sÆ+íý?&èÄoôÉ«Ú úͬЭãQy–\ åçkb\¡Žº­É–—þKø8‚[ HòTßÕ—`¾RĺþŠÔâf c¾Ä²C Àš§4y—s¡{Gˆn1gî^Ðr´Û+ííÅ5)RK“.qi‘·qY"Aö›z|¾…«}°:àúv‚§úžFÀB¼è=8@¡%Qº  mLQvKæOowýÛ‹,j"©ê){|¶=ôs¸Hqè…}†0@P‘ãývòBmoüm:›”º¯¿äO+­oò¡ÅÈ Ð¾ø"B ¯ÆÞ àPGßÕ:®_PÑÑv(ŒŸb³T˜×¡£M’IµñO”0†KÜLë8~+;ô1X—¸ô¸<±peZ7œ7é†wª1zZÐá+ð»Í16’M÷ãÖ2V"à8ñßpÒRKPÖÚðGѰ©ˆ4œ4íc) @òd‘Á  D¹Z‚­²=™®öáþ€Ô•ŠÔn/¬M¨À2ýÛ‘ 2 VPhZsV“àþþhxdt¸¨qh~‘E-B„Ú)[^úRŒeµÊ0ö’I¡®³åe< kBÑÓ¡K~îWéÚò³û–UŒaôqîÝ–Ü„O¢úÔµ+º‹€ðÙòz,ÇX¡iÍàõ¯¡Ô}6Úó{? ˆq Åš»¬c¿ã‹àÞr·1í“;ù†…ÜÅÎÔ%=÷Š§êŽ‡lùÙCˬÊ4á]Æ8ñ3¿ýÝû×W<`ñ¸D9Z;d¯ßñþíºÄÅ…~_1È-ªðÅ:š[^¯šØVŸl&5q8ŠFÝjËÏ™£¶ÞtÜk½©ÅÛ¼ºÚ–ßk>)Ttk¹æÇÎlu•3BQ$ÂéMDQ$B—ø‡E‚¡îe••,Dn§¶«îT‘Û©%èx±cø»ß±ÁìmxúÚðŠXá[~ÎË–ÌÝwaÅGt¼¦ãõá±]EðlÕ‘ªÔ@(‰+!û‹˜?’ðwЙjÊï%¤(rFD?FˆðwÁ7<•b?vÎ':oËï5ï÷سô½?1v2'³kËÏzìtÑü<]¡Øì@Gi¦ß³?Hë†ó-N¬y²£c‰(@ &¨˜$lA ]ßÕ1„ÃèGqáª$ˆÐ)ÿ+ @Ðþg´p"‹Z„ÿ°„K’ýÅŒ·iED8íAˆÁ–^û׺e„®ÙS‹ðŸ&˜ÿÎl‚4ó6­H¶æ”ÎæjçLSdG‚ŠúËž]‚gûxMÌÌgmy=#BÓàkY›€Ö<ùA¿ý­Gu ONçjç<íFkóÛßÔ[³ ŸpW\?J‘lñ×)ùTY(Bì81ÆS}÷ƒ€ÑÛ¼ºÊ’¹·-õÁY:q¤ì?:ÛìmXì·d^ஸv>"ÔM¾–uZkvÁ“ÿÐtE€“+hH¾#,©Jº¢ÐÌÑjž²­ÔH*’¢Øì€(f¡Vºr݉laÙ}œ:ȩƊ±ˆ:êPžŒ“Í•,”ÓˆÐ(áoÄ HöUè-²+ê%‘7µÿi×ãýèu–¬Ã«1.®ö¡ž”*s“¥×/k¡‚rZH¶d^Åè/z³3[¬õ†µ–¬#+°âKÐDßõ3AZb²P5öÄ£PTæŒ- ­ÙO*B]»$SÉwd’¡Ûó­ÙyÏ(²£O(¹UeºòUKÖ‘ æp%‘?¡²*Ÿ›v‹ÏöFl×mÝt±«bÚøSµs•ÿß¹ŽcCŸáëæí8vÞµÎÒËæxWvI Ä^8䦎Ǹڇû»«fŒ;u¿S‡r5³2ÜUwŒpWÜ0©+}†8é\UNÏÕ>ÜŸoX’*í%zvè\7œ°¬ÌÉÔKBDÞÔ"ü§ÁXb©o}*$ýXv«HUZõ /B'A«ŒÚBà1§zæC´vÈ&Ö[üïÝ͇Ȣ!B„°¿·>iéZcê‡KËÆÐq’íÝ.Of€»âúá1^kvÁ“ˆÐT`Å«¦Øì"tå®òkf’ªôoþ{ø/ÙS‹!B„N@TôOõ½(4 ò¤ùR´ö¼boÓªi¶¼Œl¬xÛ Å²æÉz›_üÀ˜öÑ'»>Â_GdQ‹!B„N°ôúù ‘Û©¥´çxCåX¬9%ývþ—µ¡ÏšØÙµ¬õúéŠPK‡'DËò(’Nø°«I×þ<‘E-B„N­Îwµ-AÅÊáUœ=Õwö½.4¤¼üüß3ºYÔ"Dˆáo@Ÿ¼ú(=eÃ)‘@‘"DˆpÆYÔ"Dˆ!ÂÃiå~”ýGox*²ŸaH¢Ó£þQ„3ŒeP¤ÆH"ô™ÀéUOæ” #œ®㿤VEÅE!uzTÄqæÅZAò—W=¼« „hJÝ;‘†È/Ç™†À¢÷—†ÿ<9ÖoÞ5´IEND®B`‚openchange-2.0/mapiproxy/documentation/pictures/mpm_pack_unpack.png000066400000000000000000001352621223057412600260720ustar00rootroot00000000000000‰PNG  IHDR´*91ðsBIT|dˆ pHYs × ×B(›xtEXtSoftwarewww.inkscape.org›î< IDATxœìwXTÇ×Ç¿sïݾKi" ˆ(ö öÞQcLŒ&ñ—Þ5–$ÆDcbL11jb½;ö®X•"é½,Ûwçýc *(,–ûy`ê™eÙsgæh`¥•¿´зšò`]«) ¨šò±|«)@ãjÊß`S¥LQV.¬RÞÀ´jÆð0±šò†WSÞÉku­RÆÖáZÇ7ÐZ}ª)­ÖX‡k ¬¦||=¯õµjÆö©Ãµvj µ²UÊ]h­Ãëp­Š*å6Xkp5å}ëp­`­ƒ«)ïú¸k€Ü«i,­º ²r9Y5åV$Õ”ÛUSn @PM¹}5/SVNª”sì«CÀ¶šr1ë'a­eÔÕZmª)·ÄZ…Õ”Û=åk7ÀZíêy­ÒZkÕ1 ´Vë:\+S¥œµÀZåÕ”+êp­\¬ÕªšrÙ㮕C)Uƒ‡‡‡‡‡ç)ƒ¢Ð‰TÒÈ<<<<<¹•e ;¼Ð‘ .b™} üó™ë‘ýž¡‰7v~³ÿ§Þ/ÀæÙ^¥EûØÊÑû¬Pb}7?ý–,7åz“’ÜÄ‘P”Ó#ãΙe¬P’O©Iptùè}›rÝF™Ÿ2.íüÔíü–÷vÄŠlj2 þ:pä¥\oRvë'MIޝXîºesNR¨Ð¡I»d¢±rò¹lëpýÚþùNÙ —¾²qö;eëpÄhЊ÷oÁÃÃÃc)n(þL}Çø« IÚ ã¨¸·•«©ž6HˆDÀÕãÕ©µËîès)ÊŽ}ɹY÷måå©‘G%F½6`âÂäoGμtDfã¶:7ùê ƒ^M Ze÷!Ÿ;âó !2[÷-UÇ ìó~>'§sBÙÝ~on¿Õ¤õðªÂ´‰p~ÓÛCbʼnòÝšA[Úgí6ǯXpC¢pú;xê†˜Ìøó"ƒ®´³[àaV ÑHfFmiþˆÎc—|4äÃcG}quù®±2œHv~ìÜðíãçǬ" SxrÍ”æ•ë“ÃöJ¬NKN™r;XP*8³aº0¬ é¥oã5ëÊN(¹riçg:þ>€®Ãˆ7ú¾±í¶NU ¢Ô$×k•ŠöÃç‡~ÿÈåºø[ððððÔ7Gt6úlÓ$ÛAÂi-vZ­ößl5Ú¤¥¾ Ÿ—v´¤„{BÈ4†RšG)­“PVmÏÞ§.É~ÑdÔ;÷~}ctyyüÕ­®„asÊ+S :•Wâµr¢³qö3€TÑè¡—Ý^ú-™0láÑ?G·RÜèìóÂúò:N$;þêÏ…}<‡ P+s¦„YìsîïÆ”RQaft×ÂÌè®FƒÖF,w¼”ró€”R“¸Yçɼ¨æ„ÒÔòŸYNt·(+¦iåz½¦ÄÏdÐ5*_$³ ¡ÔD€á„ÉåíVP¨×–ü'«A——ÞuiÞëƒâœøÁ~î²û»öCöðððð< äý« ëÞ¬óäBå•=_¸@Qvì 5™ÇÊÑgCÆÓs@©°ïô­‘Uëû¾±í¶Dî¸îÖ‰_?ì9eu!lß ¯o}iAܲ—Ä-ëûƶ]CT,'ºsôÏÑ­4—VUØÍ W“’ÜDΠSµmÙçý •ëM÷ƒ0šò±GͺòG‡ß$=hL†asÓcNZ@af47à{Â^^œþ‰«_ïwKò’^ªÉkÀÃÃÃÓÐ MDˆd±'[aàÆHqǤ†³%å ”(¥Yuúêů£WWWnÓÈ÷ûÐ=³×†îc`Yaj«~Ÿ[·–?Fž^þwÔ™*†ár«ë[•þ3v…lç÷ÂÞóûûµé8zÑêÓë_?{eÏËì-ˆù駈¥J2±Ìîäøob—7òê²$3öÌgë?v¤”šD^mÇ~^uBÕÆÏ\÷S€•X9oôé0¡$'ñJÅN«÷ëOíû±Ç ë>²ßÉ0lžÉhpm3xö”É/µqÛväû?#B–d+½öfFȲÂd“É`oëÒbyM^žêÑ(³úšÆëd‚®©Á&È…KŸ×[vóA}6„i<&‰S@©£ìŒ½%=ÀIΔŒÅutZBö§ ÂLÜSh‚‚º¹Æªµ<¤4”Ò¦„!„eNMýz¿¶½ðq¢íÇ…nVøt˜pÏ1Ÿª(M‹:.}Øñ_9±—6(ÎoyçPß7¶÷soÑ¿ÆÖ4a‡::x´SVí~d±ƒ}ã Òªå›¿hú '’eöš²f›º$›ór_sþÂÌh..t³}ÐÀ™Ùœ@Bk*¤Çœß½}Ø®ì~í¾DY!½vøGN[œý v<{àΰÌ_ì>c6Î~†êŒJj‚«o°ÆÕ7øÊŒ‡‡§fœNÔ5 (N€þ¢Œòº8ãŸWÔm‹4&éK­ÄaÓÚK?c>ì&96Õvµ‡5[ðËEU6Ëò_1Qàïkjo©€h6†k|Q‰9¢[}Mí_Ý:ü’÷ú´Ý%Cº5ƾÝYršØ°é“ƒÄ)1íÔ6Ü\t³¹[:¥­8YÄÝŽ-8+˜œWÛŠ“|ØÒþÍ„·öFi›¹Y1Š^ÝYÜ{û-{ËFÏF(0ßuŠ_{²ûí '¶þ¶Ä(°Ï‡ÆÃÃSgBšxÀteÅ_:HwKÊácϪÊîÍB[ü’7mw¤ÖMk œ­„”ôñ¦@oaŠ·[­R2Dû}û¿«–ÛI˜Šöe¸JŠš! z`Éÿ•à˜Œ&01]{Ûnõ—ÕÍ~¿¤î¼9B«Ü3ÉÚ"§Mõë;’dÉmXO”mÊTuj¶ÏÃÃóüAq$„¼K‰àSŽ >pÚ’ò,9§ò»•e>Î;¯sP騸[Aî[%wì¥D3&@”Ö֕˲0q ¨„#Ú¸<£´6ó ÷Ý9£m™Rh”l½©qW驸‡§ R‹.»#µ®©EFqHœ®ÅpQl\žQš\h”|ò‚4zaù‰»…FÇúXÿó Wöª¨®œ«yxxž}!Ãü@G&˜-¦ËÑØE)ý•ÒÃ’²å”š¤SvÔ¨ÐÍŠÍÙSvÈYÎh`ñ@ù¿KÏ«:~p@é$õü>²-œ |»³ää[{‹8ȘâåÃg¼íÙÿypMS[¦Â€ìÅ@qjbñæø-E#eLñoÃ{ÊëZ8rñ…ªÛ.8i²ÕBtcT QÚ¹d½ý'‡JèŒ8HIÑ—½eÇ,óŠðfÖûQ ` ¥ô©±ž®KäB¢·—2Ï„ÁÇS„5€±µ1 1(•Y)Jå#¹ZñÔ¼E*E¡”BæXÀ¿ì«=€ >*'£VC)m0†f˜Ÿ(s˜Ÿ(³¡åxž ”æXQc…F)5Bø§žç2+²„²¯„Î6ˆàWÖL `¥”¿âij¬Ð!VB¹sc€ã-#Ò‚Ô©mÈÃS”Ý£Íð.€·Ì-«Ò8K)m$f+GOé”Ò†vk®í°y t’ˆØ%¿±£AçñðBÜüóZ;Ji!dÌÇàÙ^lHùxx8]ÂCb–ãпFíxêžÔÈÓÿ ÊÃc !£ü à˜M„[V05ö§”*RFžçBˆ€3G)åÍHyxxª¥Ìßl)€~FPJ/Uªö‡y·6™Ró qL1ðæL }°Uê³€@0úЇ‡§Z!­l†9úGJiq•&¾RJ÷ü§sN$h•'´µŠÄÁSw¨tÏöî™RZ`=¯Ðxxxþ!ä]ó|L)]Ÿf)ÖÕ`¸ð“ zKG_çù/UHž9x…ÆÃÃS!ÄÀNºPJ靖(¥Çk8, ÞòIà‰· „0•³¿BĵqÐç!-$<¯^ý<<^l‘—r™-̾SŒ'_©}A¹I)ÝK`ÌñBkó9xê)ÉgfüyQuåÎÞÝ´õ1_}P˜ÍEŸÿ»‘_·×³lœýêäŸòЯƒ:x‰ ~§ .ÆãáyTÊ,ľ0À”Zì¼jŒ}ã¶êöCfñˆ]ß´yZ"ûà{BÈnœ­á¡BD<9Jéîú’,úì*ëË»>ß&“Áa.ºMü}‚O‡ OÔ<3þ¼(dù¨e“Ìž^^öÏg®‹z/à ²¢Ï®òvòì8{ðG/=hœš›rí ²" ø«;Ï£R–¿l€ A”Ò܇táá©O\4ƒ9åPk˜3Q×$Œ˜@`½Þ¡ùuŸ^ä×}úPØ<ÛëCPÊNø.ñÇ«ÿ~ÙH™—$>½nj#UQ†í ÷…ÿk‚¿2/Ùͯûô+¾]_+€”›¤Ia{œöM”é1'}zLþëŠÂ¡©0ïš.nû°N]dã00¼ÝÐyÙç6Îðtðh[pc§¯K@zçqK²b\K;·ÀìvCçe@jäQIüÕ­®6|‹’Âö´‘Ù5N3è5í/ÚVbÕ¨HS’£0ê5þS–æ+#')´"={af4waëûí:ŒXpÃѳƒÎmœáÙÈ»k^µm>Rk×Âî/¯H,ooЫÉÑßGt²s ä#}ð48„)~ð5¥tYCËÃót¢M5 2Wkš™46ýNö˜Ã ð?Jé]Bˆ7ÌA±?{X'Ji!€ bwéŸñZUA†&I¬>òû0CnÊõ9¡4åÒŽOÞ¸yl鎱ó"¶E]Õ<ãÎÉe +Še¢” Ú,3çF‰µ³qï÷]÷ ¥6'êã®lôl7tުİݟÆ_ÝÚ˜JÃs’BýÃv_œðmÂOIa{d§×¿¾ˆc2îœr>·*aÒ¢»_F]åyt%à ã"y¸A¯‘ƒRQaftWuqf’³¬Édt8òÇÈ ÿÛåŠkϢ΋sâ& ÄV×þ:è#{÷V¿ýèÄùİݟÆ_ÛæÈ $±ý…æé1'ÿæÎŸ·O.³½ºoÞ?œPz=÷îu/“Qߤ!^{Bˆ5€åZèM)½ÙÀ"ñ<¥Ü™V2@føZÂ@Èz>Îx”ÒU„6„îvØX›þ fåȰ\úä2ß©Tt#tïç̸ó·òÓ"Þ° (¥²ñó£_ÉìL>uþý̆é<ƒFFSj·èñÖºÖ>»çˆD ¶º0qaÒ"UQ:»užÿ¹’ÜÄ_oü¶'”FLZt÷+XûõÙ¸ÐÍ?šÇ7Úšu¥‡Â¡©!5ò¨äØŠqŸ¾´ ®âiuÇüV?gÜ9½xÍûVb¹Ã†N£¿_åÕnœ²(;vjëþŸ¼4pVΙ Ó½’Ã÷}à<ˆ¤¶g^Z·,ìðBǰË7ø3úüßÁ±ÕÙ‰ “iKó™M³šü'‡O}Céó‡Äa(¥|:"žGÆ~¤0ÔaŒ¨gÞ¿ÚÖÊk†¯wS®L»¼¸ôîÝ[‡Néµ%>CT,+Œöë>mvÇ‘ßý'û-!ä?2‹åöaš’œ z51tþµ{Åž!B® -ÇsHöýJ+6¡,¨°E%{™ñçE¶Îþúòÿ3À|O-–;˜ô Y•}?öèÕqÔ‹b™½ñÌúi=†vî`¾'¿~à›Î {Ïô੪ ÏUn‰]UŽÚ²çû.ý‡~t"„HªýÌ€—woÝÿ“kC,ºxŠøÀÜ!sê3W¥,D›/G)=RŸÒÕ‰ÂñFInâë[æø4Ö©‹ÚúJ„ü9&0+áâd¡Äæ¶NSÔB Vœ/¯Ó©‹zmšÕDhЩü…RÛ}6Î~†Vý?9q~ÓÛolœÙø+£^Û„Ê.ùuŸ^t7òhãÊãÚ8ûXV´ñs÷b…Ó5(ÍO/”X_0õ¶:uÑ@Ï ‘SÀÊÑkeÔ™¿%\Ýv c2¤&-ºŸÌÍ:¿ròúÁ¯ošÕD`Ы½AžÙŒ¶ ënÜòÖqC ò¼Pk0†è—HªZG ó}YEPa ‹w_®íŸï~äûë"©íšIߧέT*’Úlšô}Ú¬šŽ•Ÿzsvf왉6Îþª¢ìØqNÀ±•ã÷I»Ä Ǽûõ=øsÿ–Ý ” V֢׌™í‡}]ëLÆÅÙq:õ±)´¢¬˜aÙIWî<ŠBÛþUÀd¡Ä:cÄçžÙ|s”Òc„L˜ýÏÎPJ/Ö°«€«ÅîКÚN©‰€gÛÑ;YNT9~ôìkûNü=éNQv¬wЀÏ×'†ínÍ:MŠˆdJ³õˆÍ…£¦iÛ±ù¶¼·K]’åîÚ¬çšÞÓ6E—·±soµ˜šŒ¬ÂÁkGðkëî€O‡ %>& 9ðs¿.ÖNÍÓ_˜ø{rÙø‰,+¸'ÓÄïïN8³~š/(Eïi›¢ÿ5!º03ÆO!³½ÚyÜOßÙ»·ÖÀ¨/®îÏI =z~Ë»Á„0Æ=g\€ÆviÞ³âŸÁ¹Y÷iЪßÇy>' ùslo[×€-F½FÐ8ppzÝ¿Ò À‰x-[ÌQ?ù»Ò×7$±æB™ë4M$ÍÙbë.‚zóýË\¯i"oÃåË9‹=°$ÌTJ q¯tÙëÏúN)½l)yjaØ4½®´C^j¸ÀÞ½µ>öò†±¬@|+‹ª(=µnj»V}?ºéÞ¢Å_In"wzýë ¬øÿwjÚQãâÛë7Øû}×¾å¬ù^Š­ÔáG;”ß¹Ç^ڠȈ=ãØcòª˜²4(lšå17öÒ†‰í‡}½´|Ì#¿kÓ¸åàÄ=gV–ëäêɾ%ùÉ.­ú~ê4²Ô¥Y%"™)3þ¼(êÌÊ& Ï¢¬¸sÞ}ߨ~©|ççæ×çï&C+Þ1ÖX%^ßé3ðý;‘?Ç¿{ýÀ7í¼Ú»Ý¢çŒÂÔÈ£mi~;ƒ®4ãð²¡ù~/L‹ñ YzâïI~ÅÙqM­ýâË?ïžF!®zT*JЄ"­‰_dYœÑƒSh•Mè;ùá?G½_ß üºO¿ ^íÆ)½Ú«x³vÿKJùÏ÷ócÖ0äãSgª«+¿g+Ç3hd©gÐÈèÊeœ@BËdô™¶9 @Tuã9zvМyéžn¯WׯVþ}л+þ9¥Ö®ÆŸ_©n¬g “Ž ÔI”‰š õã 1yhjâP½ P_ íæÈ¢R_6;{«¦¥ÃQ”ë’„ú˜çaBZÃTø:ª*üAL"‰Íñ3ë§õõEè2w¨ÔªÑ½¦¤ùcdPfìéob«óÇW½4Onç±fÌܰ§×MõI¼±ûw¡Dq.ìÈâw)5:@ZÔqiêíÃèQZ˜Ú™R“õVU IDAT¬03º«@$ϼ{ûpp럽 W÷Í›Á°‚B++KÃ0‚bƒAã'×Li~÷æ¯9‘<<+ñ²Ï­ã¿\|q~ôßa‡:†ýqˉX85tïWÏ ‘›R£BÖªŠÒ;Þ¹°Ö-)l÷–&²BiÔæ9ÞsýºNÞyÜ’Ô”›~ÉìÞqôì²ù‹¦Ÿtªf¬P¿î#û/‚|þVëŸå¦F…¬ÏŒ;Ê D)WvÏšŸ¾w–»¿x£QçN©QZ˜]š“|5ýܦ·ç‘<.=æDg_ZôOW·0ÄZ -€\5vô¦b9:z´[íÒ¼grCËñ¼Bi`‰!XìŽ {»Æ_Ñ–+HY¬i® ×»ÕrÖDÕr»uˆ&É(¹ó^I0Õ3S‰UGAÕƒÄÌ(îf( 2F ÿZëSwÞ/élÝInÝMsç’>­öÛì'œùþ–êA”z«{Ö*$¦{va&@—m²Üc}¸äšÞ:é[Uç†Ph„÷`Î"ý¥tƒ¥ç·¼-áÚ¶o/šÁ Ä1 +,-¯ËM¾:Öº‘ï¯#g^:riûÇî1Ö¬°3ýΩ¡2[·uã¾¼µ)üÈb‡kû¿þÿS“Ö#6Ä]ÞØá¥qË z5ùçS—woÿÅλý¸"miþÈ#¿RÞvÃ'–›L{j2Ùøtœ82îœoãâ¿jø§gO¨ŠÒÙm_ì7èÕ«ï\\7L$µ=QÙº*Ôdtî5m]°GàÕÖ¹ÍßLŽøwpçqK*”gµírº¨G¹ëö¯[¾saíÖ>[NM;.ðö¿7v}Û.¢ ýöàÁïþê։߮ %V‰eö¸}ò÷¶-½[ù„ÊÒäl×:foÐŒ7–ROj‚üöð¢w É÷ßjU«´d”ÒTk !+Œ-·¾%„l¯Í8 !¤;!DV›NO*ß=p­ª?e(»«IÐCèÂd[rnC•Pˆ¡Ä$y°AGmöR=åJoé+Õ~vý„±­Ûìc%æ8vëÔž¬‚èšýª8-tfK27¨=½ÉCÓVª;G½V<¤ÉLé…reºl“èîÏê¶•¿ÒÿTT–¡äºÞ†³"*P´iSŒ–5dGÙàeŸe/Lü=™R“4;ñòû¶®-·U®Ók•Ýüû†æS“Éà’sR¬×”´³ui­|–KöÇ÷œ@BÅrÇm‘§~1äϱ½Y¡äZå°sC–ع¶ü ¢’¼DGЩ‹{fF¿¶þc§Õ;æ­b.7üÈŽeþ VN>W4à bËïÉäöM"tê•ëoøµ£ÉdpZÿ±Óêõ;­Vg÷1uÖåõ½^]2·£^[­Ïª“g‡¹w#~½öÛ£;¾œð yêVF’D.Ìš:ê €ù„^„PvjWS8|džG†âào˜ïj>й¡ä‘·æ²@`Ï(U±F…:ÞhoÛ[˜ BW¶”× Îê£Câ—ÊÀˆ9gE b&Wkt±~A˜_Ûye\±¡„J@g” œ˜Â‡õ©cz¸…: *lIvMþ)ÉOž<àí}—ö,ìäQ^ΉdWÓ£O´Äd^Ùó… aØ,Wß`@$/ÌŠiàväéå6Ôd|¨e­÷é[oún«VUêФÝï•ëzNY îß%Ás²..0P Vœ—Y»^9ëò¡Êmã®l¼X’“ÐÀ}•šÉhðN9)võ Ö(óï$Ö7*×ûv›zõâ¶K^Y’=µºþ¬ð¿†% êL&CElܲk—ñ!Kì¯ïŸ¿/òôòCUïùêÇq¢Çq¢ºŒ2³ æû³^®¢†Çe›²Ö¥ôB ÃóA™s6c1ÌGÑN¡ZUl‚…‰é«Õ¬¹®¼¡oj×O˜à²WîYÔy€K³›ïÞ:´pÓ¬&mX8G§. šüCæÛÞ^ÚwûÄomüÜÝÉR8$Ìܰ•Ç! “lå‹+"ù-­º°w³N/¿Y¹Þ·ëkÅ×þýêäúV‹evç zu#‘ÔöΘ¹a;î'¿u£æ³.-ØüEÓF^í_ÜsaÍ7b©Ý“Q/' ›kieVPJ)!ä"€»0gÙ¶GÍb9ûLÝ¡ñXBˆÌ~M0§>ÌwfŸŒ ª}µYê«\¢>ßÈH›±Ù[¨U1z‘,€Í`DTkÌåé³ÂäE¥íÇŠ.±VPq6P9¿" M˜]Ò™°Ääòš(\¡·k2Kr‘cÚê–%×u2VF*ü XyÕlU×èó“ìPÚrMkis6Óa„0ÅR¯Iÿÿ¾“OžA# r“Cÿ“Ä»ý‹'•ùw¯ÀÀwö_ÏK vnÓÿz´8ë/¿îÓ‹³YzÌÉWvÍ öî8acaF”“gШ¡ÄŠº4ëùxwx)SU”9»òج@”.’ÙÞcEÙÈ»ëØÊ¿û÷xó]uq–´ç+ÇôêÑG– ë¬SÚ7m;f?´öuVûa_;øË€NÚÒ(kzU8BÈ(¥{zR*•Y1P>†¨!„¼àwýʈfã̉øxxˆFSTvûoÝð<±†[„~ÕTSJ#k:à&Ìf× Ê…íï6±skU˜¾§™ÂÁ+§ë¸ß’ îÊEVâ%;±ÜA“~çDÀ°Ïž€•#ƒœ}zÜ ìýQ[5¦Uëþ3£›tÐå§… ®øª…_×i± 7v¸õœ¼¦"¥KÈÊQ­ƒ_ÛqaëÛޮ̓³î\^ßÒÙ§{|ÛAó²À W“Óë_m¡*JsöáÍ+Uw^W÷ÏuΈ9ÑÒ#pXxëþ3s*×Å_ݬH ßãÑçõ­·ëûõ²„_ÛL¢”FTª*°ŠRjÑ Äà ’…bë«7OüvøÛ5œP–¾ùíS¿]i~ââüôˆî!+GMœømêÌ#ˇ~Åp¢l±Â)*9|÷º´öú¸ù÷WŸX3Á?3îÌN –|óßÉ7÷ 8¡,"ïîõ¶ W7ï;7jõ±•£;dÜÁ $iw~8ãæ‰¥›Fͼ¾Ë W“-s=ÿ`J¬nDŸ_ÔºÿÌË忼ë÷;—ÖüîàÑî¾Y«Ÿ&Ê>ˆøœRZ5Cn€…–—Šç)¤ÑÐæ¢Wš90Oex®g,%nŠÐlF5ÍŸ ²®¦¼¦WZ1OÔ™6'’]›ðMÊW½šlœår>'9t Pj’½¼({ ìü®Õ¡ÄæÔø¯ãÒªò™-ó¼.ä§…/ýEÄ[æ6Y¿é ·%&£ÎeôásER;“Pb}ðÒîOFŒñØ’n’ÌÖ½"­†XæpxܼèUÉ{d§7¼zÀêoºàJè¾/\²âÏEdF½`×ñ¿Æ¶#„&-Ì|£ªÜé·Zß<4Å#`ðG½¦üóÔ=–E®Þ` ¥t}5MŽSJMÕ”óðü9Cæö–5´Ï+Ë/©íZ†ðX;´2KëÈ'J¡‰e€9wË ãoú& ì÷Š`¢eng+¯} ’Ú™XVwuÿ¼€þoî ³s ü3;éò6׿ÁÃDRsÊóƃÿI¸¾mYFì©=:MIŸ^S6,(KaïMZ,ˆþú¡ùNÅ9q¶woü†åDI,'Ê1´- 03º»Pj[m„î’¼¤™r»ÆKžeÆØ ŒRº º6¼2ãáá©K(¥w|õ¸ãE©ˆ½&–Ù…ªŠ3[æû.£QïݺßgQÉ{d¹w¯Ï—Ù6ž—•pa~~Z¸º½´< „)9µ~ÊçB±â˜K³^>SÊüäH‹:*¥¢¶ƒæegÜ99ÙÊÁ{ÝÄoÓ>³qnqe¯‘•£ÏEª°Mur;zvüŸª(㎋;©®þ)ãw˜×<£¡áááy²1™ØìMšFTO« ‰Wk!~„u„(BH!dymú3„W!¶u!Ìã¢×–tÙ2·Éœf:­H¬B*+Ÿr¼ÛM8ªUåÜ2×sö–9D냼ºiÏm™ñÔÊy㸹Q %6Ç,6§¼•ƒ×miÞ.̓ÿ©<–º$gè–yM?;±vâ:±¢Ñ? ’9„çÄ¿¾í+Ÿ÷r’CßFYÔÞS7_¡&ƒÍÆY.Ëv,hñ궯›W¤½(œ º¾¸lRq^Âk»µ]o/P=C™ €ùPV<<<âÖ¢#ú]NûY½=ì…“7ͪÅö€OеŒàÁ8 <!‡­ùÿ̰ÔÚegï×6G€w‡‰áÙ +Ò« œÝ²ÏGƒ,ÒÍÑ£ýÚŽ#§å§… ìÝZoøöáË0òóÐ_N¬žÐQ«ÊgDR;“ÔÚ%½8'þr¯WÖßcãìÓýkuI¶“ƒGÛ­åV•£gÝØqbÍ„Û%¹ MƒÎ^›xcGsÀ|¼ùò÷9“N¯ŸÒÎSÏÁÍLƒbäÆÂÉÝ=…·í¥Lé⳪Z9sÜ­ÙûÐnû{þÔ£¯Úüãaê`î1åÐ A¼ ³*‡Ìì);új[q’Åñ”aTQ&áCåFBb|×)þ}Ìáø(¥”²Àë5íüÄ(4ËR–?è €ß)¥[ZžgE¦Òd{"^'ìí-Ì­ïÉ~½¨jÝ«©ðæß£­Î–U\˜(°þ†Æóò]½ë›%·‚\¸âí75î¥:*ýúDi{ £^2H~æË.µuåŠ~<§ò[s]Ý~T QêOçU-ؼ=QÚf‹*.Š9—žWp 1½ßUe+aôJe. ôuäòÇëšNi#¾ìe^÷•T½Í¦pMóŒ“U;WAÚg=¤Oý‰ÕSr{DÑ“.ÍVȧÖÁÅdÔe.D‚Útæ!oØA)Í«I½¦X~ëäRG–åøm¸…`ãÃ[ÕBˆæ$zç(¥|âÏà”!ka~èms a ³ó½ô~Ý`¶:{@"CðŸpqõÉø@qêø@qªRGÙÞ¼´âŠº™›£4™À×UJrÜW©,(?ÔÅC/šE Œ)S`-&ˆÉ5Ú9+˜Š€«‚)ˆÊ6ÚõðDŽT@Ô. F ÍØ¢5×L¶°m‚õÖΪÚ\W8© —°ñEëõõXª§ÖDDâJ#¯–—q r³°ø±Æ5ûÀ^ªe·"»Ÿø;4FLL²æ¢í N—zc.êE¡_W[ß™™ÕÃqüεAÉCÛõ|ÜËO‹C™ `ÌyÍ,òÄÌóôC)5Â|’³ƒÒÀgFãÿwf•QÈ0€RGieIY¯¥é­[9 Š,¨\HŒ,£\Hôc[ŠÓ¾:^Šù}d×dŒÔzjŽ$"ªìR“¨òÍ^ÊèÊ•YuŒk)Šûß’!ÎM”„gšÎî% €R•Õ9õo&Ì>£óìà.H0˜@ü9庱V§M§½~Ì}G­§§$òÔ>T¶:f3³¡e(§L æ=ñ ÍP`â²v5sªÈ¼>4y0gŨõ…F‰ÛÛçñÖ©©«ò½rö—4ceŒÎd0‡©Ê;ªtÊØTègÒSÖ¾Ÿ<Ñ¡¿"#òíô^­77IX˜ÓRäÊ•6~Ó.¾|mš^¬Ë3 +Ï+vhlEÈ­Ü#J7§áŠhwìc‹Ã4Н«­­ÚJžš€«„¾ЃRšó°ö<<÷!À-˜ ݪÔ)aŽ˜>¥¡˜6„i|Ä·m$gòK´TêjÅäMï ‰gð¿Î’“Ã6ŽqD¯ÒSqáíýäaÃýDá3ö– ‘ ‰öô4Û5™§ScAA3—ÜiyþË& Ò£©0ª…§L+6‰­Å¤øËãÊÞsŽsDûçÅáÔb£xàšÂÉ®VL®Ö®¯0ìiVfO*!D @ó¤?Qe E& hRôöN5ÝB”Üžžì<Þ:5s{q@û£žÿ*#µò[SR‡@Êïymü–ºœe¤Œñöëi}Ü^µMr®ˆ ›2€ˆÉçk#•çÈ9¬t)º¢r©\æ8D‘è4Ü*£ü÷Ò(­£ë+6‘ i"(*¼ rzZ!$Àz#)¥±kÏÃSBÐÀ›zØà ˜/ìåeÍJÌ¢”.k!ËøyˆâÊÂþôê<£¼…#WRÙ‡ì½.ÒØ÷ºHc£r r7+Vc%2Î –Ýš,«8ÙIøÄáªã6µeÕ‘ØÿU¹ì¯ÑVg‹µô"Ç€Vöc²Dñ-»-I…F‰g¥]ßÍ÷ìWEæÍíY%¯ÌêÀd˜jw—ÖØb«£Ò$6–š*â|Éš KIÙæ®Þ!iin H¼y&eìûÉ3ç7~Ëîü£Ì-i"(T'ëår´¹]°ü©pÊ&„xøÀ[”ÒçÞ÷ާæBœ`Ž­7æ;Š?¼F)UBvÀ|‡¦ƒÙÔz(¥ô‰ˆ’#Skgî¾y´ü¹: íV®«£²2 ú ¹xB@ÌXÔ•ÉeaeŒ‘cþ ¥cÑ55˜ÏÄå-Å©Vm%YN#­ÒНªmŽ˜"ßJn±Üõß„Ù]íûÉÓå-DojÇò ë’{ºØUp ªmYzò¯yíe¾¢¢Òm#ÛÒ –Yå£S–Öü€Å”ÒÝ -Ï“OÙn,æÝX?˜Ý;^¢”^­Ô¦€0'U 0œRZï>fO. FsøU› oÉSÇØË•… ©†Êjs ¹3(µé.MÔæ8Û`Ylù¼å?û|ßèôÝßó%‚"ÇኛÚ\ç½ÀéRÖÖ"ÏÈÿ¥¿ g‚…Éa˜"ZÖRTèõ¥ÓÙ¼“ÊF§J‘DÄ t½× ÁŠÊk”·¸½a{=cSa3ß_]BtÆZE~T Åô‘Rü”ù íp˜Rú[ÝJÅó¬Aqð*̪U0'N£”–TÓüm˜Ow~†9£9|VCÌÇ“ -ÇsH€ µVJT MîSvEEñÔ$7âg”¿W*~.%PœÖ”=þ½8Bq„öuƒ¤+™ÛÂÌøSòž#¥€"%í[˹á™òdµñ—/{Ê^ æT <<ÕBéónl€=&?èè°Ì)Ì»²§ÎÒ—çÙ¤ì¡JUk…&·nÚ¼ÉÔS„y¢rƒ>Û4’ÂvU5~ 4ЗRÚ ]!‰7C`[a4ÀSÏP= %†”Òúl–9¡Ny7¦‡y7ö¥´&FN~0+3Þ¸ˆç‰ƒ+;Ï«MBÇœk+Æ:Ë´.oÉSd«¸#v£,Ùèƒ „Ì€ù~£¥T[ïÂ=@acÆÙw…åôYÑy½ƒ´9[,pdxŒ®Š2*@©[ÝqÚccRS¶4Êh%oÍ FjÏX¥––Dî{Néónl0€}¦RJkuL)½ùxRòðÔ€a0ßµÔØÊQ!0I¦· ½ì… ùù\­4ÑÊ‹jpÓI`ÌÊ,¿¾e« "'Öbg³Úd­•¬Wú°93Vh܉FÛ‚úãZ·‚1R6+ù«R—¦_ÉÛ f×ÇÖû !/À¬Ä†ÁœUáMJéÙ÷ªJõT°ö†Æ¡!ææRKLµ¹®xZ±0ö‰Âóp!^0_èO¥”^khyʰøÝ™2Üà,oÍå©îl OéšîµÙ9¹¨ñ½:Á(WE[üc}4bháHY 2K# ò¬šV-wZJ˜]Ú6c­ºi£‰âÄ[c GfïàR…ÎŒ²²23i)1´pxå9 KŒ­ÛTk‘½CÛÂa¸0º¾×]…æ„m0§ÝX àÃZÇk­[ ÷Eiví»SØy óEEVKQ¯”½ÇWð í)§ì‚ÿ€¯)¥u‘ÿ‘!„¼ h¸L¿6½„±œ51Èü¹ÌâPƒcé-ƒ£ÝQgE VI½Uëm(¢Ò¨WŠ{›´à“ÈI° ÆdïÔvècOúwÂê4NqOWýcf”t•4eó\^“$Õ×ïC:€w)¥'-<ïý¸«5 Õ‚FÁ<Õó\¤ûâÚS !D óåþJéʇµ·€<.öè 3€1 & ‡{Žj­:pÅ¡zçWÄÉ¥‘›ž‚xûÁ”ÒÛ†F[­ÍéA””UÝ1Ê Oë›ÙöÜN˜£ òZ ¿'“º6ÃtÏΓ°øÏ‘pìû%@@}~’‡ÖÇÚ‚’Rz¥æ½örÛÆÎ”4´ Ï3¥©Y,r—Ûp„Oéâ`ÍÓp”…zù@¥tvËB`¾¯ù æpH¡n MìÁr6D'taK©Áü*rcJ„NDí0T”^t¡Ä=¬OÁ(¡3S$tfUVò6\zÄÐÂ!  &‹Ã Oé=¼³î,È¿=¡¨¯6Õ(¹›ð ÚôKYăd0©)StQïÍYUX¿‚‘òV‚TŸ%ò«êó¬cãÀ´ ~“ùÔ@Ü:¿VQZÚÐbX@W˜¬žH…Vª3±Gb”n…jƒØÏIœßÕSúÀ;ZeDÜÿþ<Uâª1PÎVÌj{øÈ²Øgç9q Ìá^&6¤„›aαVÛo Lª˜ÿ)eçVÆZ-`”‹˜ÿ)ø?öî;>Š¢ÿøgv÷zÏ¥ÒHPEQAAl(*öîóØËcï"Š€ *ˆté5 é=—ëmïvç÷GH~‚ˆ’B˜÷ëåË8·»óK¼¹™ýPäÍ“a_扒ûC“Ùðü¤kK®-€|U¢Žua€#ÕU󂨚TVþ·¢™~à·7 P.lüYò7ÅÑêBuRÇœ¨Rr4¾çèùùr:8°qn§n<üÀ¬@)]ÐÞÁKnuÀxï¢ÊË%jóL>ðáÆúA½bUËŒêc/Ëÿiñ5__×õ+“¦!‰ñ«kk/ì¯)Ë”emí÷ ³®¹¨»¡¢íZqòBîp€sÚëÎúð2Ù‡Ñu]† `;¥t;!„óì ¿ïÙÃ&OÚ»bNGz#;ôÚüάa©ºì'GE7Ùìn|RàÇ}®®ÙÕÁè)ýLyÝ"•ÞeùîxHV½±®®ŸQÍî¹înÝ–lQú>Ù\ŸùíngŸ³“´µ_ír¦%G(œkxS>/j |±Ý‘¡ˆtÍ™æ:%'¹ƒ’0o»3#Á¤pm)ñu™ÔÇ´¿_µöVL¿äºSk=a}ßxMÅuÌG5 u\ à4/™B)àôËŠùÛÖïw§÷í¢®š±¬zÔÏÙîxúךQÝ"•õã{ó„´†€ß~€™hت£´-êlŽ¢!„¼`€4G'w Õu ô"ÞDœÆ³„·ãnÑLÕöà¿ I7Ü罨=cêÐwhWõ7²hùÀ{]=¿Úé8;#JUúÎÄø•宯´ƒµÐ/^U¼(Û•ùü˜˜?'“¢­ir€U¥”r <82j=P òÒűëU‘¿ÙåLɈV•Þ6$"vVø×ôƤG)]aYæ_³Þ¨æÃÁVôt—e(ó‡e•Ý'i†§êª†¥êZ}h½¤KXô½††%Ù¹0¡5BF˜À @ÓÂ!4 ?2 sH}ùÿ;ÅÞ¤.ß7Ö9 X, Ý!YhX)×!'”/ên¨¸¨»¡Â+Êüõ Ê&ü°×•¬Up¢LÁm*öuŽãhw«â˜ÊS££WeF«œ»Ä²‰:«–³7.)¬Í1z¡)¯_Œ^pÔÍéQJ—VÉùçì’#®%9.!À[—ÅÿøÙf{ï¿*;£_¼¦èù±1­ºy¦FUë­/~$ò¯kÍzŽtxOµ7Ñ>)Œ†Ž+@@  q™ 0 sšðf‡Õöebï>)3T/Ÿ¯?Cx©=ãd(Ðá:´Üê€1#Zíâ  SrÏAÖ(¸Ð…Ýõïn´q÷ ·îÒ)Ækƒ‡—ië”œÏæ“”ÍïÐÌZ.xä–çÍ;^¡/zeuí‰b{X¢$¯&˜pÿˆÈm”ž ¬ÛY°œÑEm_È×µ_‚¦$,©V¥ç…‹c6…elºðÃC7H›Zs%¯Ðˆjmijí6Ê>üœÛÕhØÄq ö²£aEãKhXÑhàðd{eög:—pÈOêJv(,çy%Jxʬ–,ËY®©Ø¿ÖÜwÔªUºˆ“2-ñÓ+ÃÎzÕ;ë­ };Ħ̵ ‚™Ž5¡çd‘¦ f²$nº¦]v-'„¨$ y'ãö¹ÓÖTõŒÔñOPÖ$˜u—ô4”À5ýÍÜüuÙ8µÀ…¼¢¬:?CŸwëÙ¹£2ô9,®mPqþÙS~ý;õœ™ ±§Eªª&^2I¦ ç¤èò»˜þ2GHcÖ®Y«jFÈD«ä‚Ï^³¦ÂÒÜömùÄXƒP/†©bdš~_'z Éá»ö÷š—BÎð,€{¼s¸8€†¥û ó¯­ýì†å9+^Y %Â9 ÇÛ Ç9¦¾Vwm{Çw¤u_LO-Íþuê5/•>Žª<á§W†Í¦TÖs_Ÿ³öÝÌÃo›2h⬽ºº¾|ïUÖO²&ôíÉ¥“_Ðíp©ë¾ðïˇò<Õg¥ù‘vE w‡žC{ìü¨ŽˆÜYâéR­JOóNãÚ3Íמi.(²‹Ú½"ÐxvÛˆÜÆ¹0X}{êœ#¯›jUzÝ”üMó²çÇÆüáe^àˆ¬þ?k¹Š‡øÕÔÄEÕî°:Æ 4ÝÅþxcÒ‚Âú.É¢ð6?¾3#„$¢aXñV;ðh‚|öD¶b˜¿rÁô¯sŒ€/þû¶Ö·fÒ;¿ß°àΤ|a(ÜõC Ç+ÂC®|=ý¼[û}ó€KŸÝŸ92{W½áu”i¤P@pÕD¹û—¦¹ž²œåšK_@å°"cðÔí݇Mw®ž}M÷Ä>ãÊóÖÜ'匉9=GÞÕÔY„C~²òƒËûw8eúàëܽæ‹»®Pµ%;RBA·9ôöÿõqýÍ1™5åy«qœ`¿ö•ÊëÀç¬à¥P°éÓ«dïí¾5o÷:ÿ¦ÛïÜVϾ¦{ÚYW—ì]õFßøŒgŒ}¢)«‡£*OX?ÿö³“úŒËiÕ7þ_0Vx4iü"ïÞð£íQ?¥ÔàÛÝ¡€J 4=Ré9ÖëÉ¥ïdÕÕ8|Ù’æ(xB3¢ŽWgsx.m)€—)¥‹!4|+r˜Ý®Á1§…Âß?P°í«.¼B}Б´jÙ»ãSüîêþ¯t®ø`Ò‘‰ýg^|ÿÊMû7Îé¶ß Ê"ÂñιDþgêÿê¦Ú¾P¿î‹é?©õ‘‹@)Éþí=s÷aÓ¿/Ù÷Ë¥ÙËœ •vï¶Ÿžz,wÃÇŸ]þäî…æßž\°íëw*ýæêÂ?ßñËóK'?›ÿqþÆ9Ã]µ‡îâE‰J±I–D¥’ÅQ•7$,úvr‚Ò/…ƒ©¿Í½©Ûˆ©³ ´¦ø¦Ï•ožê~SÀk¦P鳿z2ý¡”3&>4üº•ìû岜åÕ‚BSP[¼í©âÝ?¿5áÑÍK×|z]fñžÅo)5†õ»–¾x'•¥ˆöü4Wü¬7+á?Ú<^Kdû2Ñì? ]ÁiH['ãþ“ß¡µ§³ÂÿóÍÉ_µwííðøô"¿PJßJ©›B¼J)õ·k€ÌiC¡6l½zfѬfEK~ÿêî¤Êý¿UÛ+s.° Çy®{µúVøì~ËÒm??c+ÙÏñBÅ€ñÏÍIxÕŸ6wÕYº|{ù“»nûùé˜}«ßš`aYÎòKµ¦¸/¯x&{^Ñ®Eºµs®_àãçЩ¯ÖÜ+>¼¢Wåþµý¦<ð áŽjÙ»—&nÿö‹ÂßJZSÜœq¬þœÔÔ箾bÒã;Æ"SÂ?Î2ªBÂá¿wãk ¥®) Ï+Jk ·$ŽºýûmßÎè½yÃüÛoüúÞƒ =F½rÞMóóÀÚ¥ÏpÉŒê½+_©È_£ÎA± }^€ä~¼ œç…&€B¥;f~Nsl÷ðäçöàƒÕŸ\ݽdßÒ·W|py‰Î’PI¥pì/jL$Nx…º¨ñ¼.Y£v€µk¿ÒÚ¢-] pŸÓmÈb8sÜS5{V¼Úa’ô]k¾ËõGHïݶèû õ† o{Çİ¢a.„aZ2 A®oaãóí•­„9=q¼¢iuŸ½bßô¸Œ/\3«ì1µ>êÏw.äèíR…†NyþàÛ7¼á¡·tý±{¬q5ãäçöxhûÂù»–Í©PéóNxa3ÄgŽ|(匉õ ±\^çª9øœó—¹ùkÆoþþáóÒκz~}ù¾ØÄÞÿiþi˜Ó°ŒüÝga !f…Ê‘ÐK›¨ N|l˜•­ìpcw6•®°â©Uþ`‰ý…³2;èq–Û(¥­º[!d06êC)ÝÑšu1!$2¡÷ظѷ,´µw,ÇòÙý–_{wÏõ.™Ñaæ§N¦ß>¾6¢`Ï5”Ò´Á'!D{2¹ÛûÆ•tX*¦\öµɵ+°ÿß\ç¯üã;´:Ÿ$(íâQOó3'W½_´4Ü×*ïoö=æÌXgÆtzÖ.}^ŒÏ8—Íw!d€”Ò¿=©Wâ¼³w† ©ý˜Öfðn´Á¾„(4«u´þ¸+tjvÇF]b¨j­X¼ûƒ:^ËIêE›­îôˆªÂ‡%5\­s}BÈœ`¥´ClIÁt2¢LªŠþP´w§« •;á^ -ëðÏ¡ÉʹvúÿV‡VüfÝ ¨K ?¶F3jzûŠV*Q©H¸×œ„õÇ?«c#„Lp'€!‡Ÿã`˜“Î^³þöéͦöŽãô:mFÓBÈX(¥­tð/Q€†(û©êV† I÷[wûkœ®í~SÉÛ¶¾ª8EÓr ,¤.yÇ–vHê„["²U±Š@ñ›u=3fÅî¨þÎÕEòÊBüTsñ±+=Z·§£÷6þ¼yè¡Ë%¯Ìóºcgçïè!#¼àüÖ~®9­Õ{íeŽö‚Ái‘AP Ã5IYpíÄØWû“»Owãs"½Z׿ς®k<^=,ë½øÕŽ-~«m¥'òÿ[5$å¿‘ÛUñŠ@ÎíçžñCâ2¢ÜG«Ïplñ%öÿ1iqó: _©ëáØàMj^3É”ÛR§gßà‹Œœÿï̲| ` ¥4»½ãa:¯ÃÙdN‹S¦ýÞÎjˆ@)ÝuÜ£;e¬àˆ©«€ƒOT$¯ÌSD“ªôi’•¾’·mxó‚q%oÙú€”Y¤\úÌØ¿÷>pcÊÃQ«xýŸ;#Ë0m•*FøÓnÆ3ÔõGÖïÞ0<[3´÷œ.+Z¯•­‹` €(¥kÛ9†a˜“A`ëðshÍîO´ ¯ã$BÉ+ó®~3†&µ)ÊÚ´gc¶ª~É+óœ’È9·•érƒeSåG߸)¦’æZØ.)ƒU!móºÂnåŸæ”<ÙCþƒ•#{~Ôe…ªKÛ- 9™‹YàJé‚öއaæd8¼s[‡ïÐ8‘4ÉŠzФ(ëËîzgĶ=×”^ 0ó~}u¤>µùàŒš3Ã.I­´ Þ.7Yr9-J}<*[›¦t–¼gËHy(*·ñZ‘c Õ‘c ™Ç­êW ˆ”wåpèñnüÚ¶\íøoB üA)u¼ã†aN5'œœXaT_ ëIº·r\L3r®XÇõúµ¾t»üO“B> à2Jé);ÿÇ0 s,!är+)¥k%’N—¼y@ï—~R(U§ÍRÐöÆ *ºcɳ–z>!äi=ŒdÃ0•`/ÿß=!,zME+©Uö dñ…!üØ  ö¸2 ÀuÎ><ÎÌ0 Ó©BLÎ(¥ù'r"¥2Ÿ¬÷¥_ÕOÝJ¡1Gš¿+Hë|êÞÊ…r!€™†SJO¸3d†9Eäÿ£E!„íßEý·ïê˜gþ® æDÏ!„ô0ÀJé“Ã0LÇ@) Èiƒ]¶˜¶FIDÃV0·QJ7µw< Ã0muh !ÄŒ†M:_¦”þÐÞñ0 ôŽ2•òWÐ1!D `€¥”Ò·Û;†a˜¶$XÀÓÞ0ÿ!„ø@5€ÿ¶s8 Ã0mæðMÙRZÚÞÁ0'ÅKºEÿîÓò Ã0ƒÿdƒÏ¶´©Øg]™ïN©rK¦8£à¼ipľ8ƒpÌtS¿z#3¢Ôî(=€÷7Ög•ÚCf¥€ÐÐ]ÙyéúJ¾nuG¹À%†RJƒíÃ0L[:¼9qi‡]Rî ižZZ=.=Je›6в#R'xë½aÕ_óÉö³öTšæ×ò¤i•D̈RÙ¾ØæèÿØâª¡­yÛ"„Œð(€±”R{{ÇÃ0 Ó^:ìÚ¯yî®ÉÊÊ)g˜ `@¢¦éúÒVÏÝjï±·"ÐõÌ®šÂ›[rÿ(öG;Ę6Ú†ÌÝf¾5!n9ôŠUWOèm,í¯¶Ý³¨â2¿Oÿ¦|ôÙÉš¢eyžž·œmÝdRqÁy;}ÜI36Ë;©©¦S>z@WMéªýžî}âÕ¥w µî‰ÐòâoÞèyÛý~IoRs¾O&'üÚï!d€Œ¡”µG Ã0G¹•bmï@Ž4.ËXRT/ÆÝðeÙØ6Ö÷p¥¦Î÷É¥U#bô‚gö”„Å®€¤þh“=kT†¾2ɬ¬¾mˆuãçW%,1iø¦MK½¢Ì¿×•žbQV@~m0ñP](âÓ) ?“¢­yrYõØ ½Œy\½áó­öÁ;ËîòÔ»ª#>¾²Ëâ`˜ò¯¬©ïÿnr÷9Ö- ¯Oüþáó£7´õ{„4?¸RzÂYD†a: ;w¸-Òc B`ñÍÉsÏK×çï(÷'Œÿ´øºÍÅ>«;( ‡lb|¹+l|umÝÁ0›Š|éǺÎûëG^7¿ì2¿H•÷ˆü£±ü¶!»uJNÚ\ì‹´jy×¹iºêôH¥ghŠnÿÒ;I[Þxܸž†ýǺÆíC"ÖLèmüÓJNž@N0+ü–Áñ„4mÏsÅmJ¼,𜠞P ðê¥që×ôÆ,Íu§Mú¬dðÓ’æk¤­¶™WøÀW”ÒOÚ¨N†a˜ŽÌ à‡»(dÍoÌoÞh‰6Ì™¬ãzÅ©«¬:^L¶(«ÕMÃRµÕÃRµÕ*HgT8òk‚'RÏÈ4]U7lÞTì³–ØCš ‡|™c2 ¯±ÍÞ3¦Ü'›í=ûĪ‹€†Õ—ç¦éªgŽ‹ý]-`…3t¹ÿ…·äSJŸjÃ:†a:,Ji˜Rjë°‹Bfo¶|eM­Ñ â|}â5¥Wõ7ÀS£c~›»ÍÞóª/J':*CŸsf‚Æ>¥¿)gÎ{ßÉsK.ûàò.‹ÍJ[„–?j{²EYÕ¼ž'.ˆZþùV{O@Ö\Þ×´½q h„–÷N™[ryVŒºôÁ‘‘Ûà³-öþ³VÖXt*>0:S¿¯[¤ÒÛVï €Ñ0ÜÈ0 Ã4Cx)¥9dÖ¸cµ.¢KҮ¤—ǘ;}¶ý‘ïºqÍ©Ÿ¶w.qjvÔª¿ö;Ê«þéŽÕ Ã0àj,—c ¬ZÁÙÞ10 Ã0ÂB´€9BÇ;átôí ‰ßµw Ã0ÌqY\.PJÅöŽ„a†aþ;€/:좆a†ù;¯ñuØeû Ã0 s"8BH !„Ý©1 Ã0§4 ÛŽ˜Ú;†a†ù'!!Ä*ü“ôIŽ ç{|™KÛ1Gs‹ÛQœaæØL.?á¡F…Rë, Z, ¶+r⯯½c`†éˆ(¥6žP‡Fe‰Já°ßç®îôYB:"IÙ—†a˜c ”þ½ÏHBˆ@Lë†Ãü .Jie{Á0 ÓÑÉ*ØÖ Ã0Ì©Œ0€®½a†a˜‚¢ „týÛCŽ Ã0 ÓB,.aÃ0 Ó)°ÔW Ã0L§À:4†a¦Sà!Y„u{Â0 Ã0ÿ €ª±€48êÎíðŽ 'ZNZ(çÿ¢ü¨ !| eÇ*'Q~²ÚÄÚÚ9ÛÚR쬭¬­-¶õ/ÚÄÚzì6µZ[ !*BH&G)ýRêlöZ_£Ž¼€¡‡ÿ9Ò(ý[( G å“$´P~3ëAjÜ|øßÍY¤×´Pžq8ž#õÇÉkkF å× uÛ:¹…ò8µÛ:­…k$¡õÛÚ·…ò‰8ymUql Z¿­ƒ[(¿§v[Ïk¡|Z¿­æ#Ê 8ym×Bù@´~[ãšîœNV[¯h¡¼5Û* JéŸþAÃÝš®…r M å:êÊ ”-”-”›ðG”‘Ãåäˆr€¹…kL-”+Z(W·r[M­ÜVc'lkK¿?E´UÅÚzÊØ’˜ï IDAT¶UÛmåŽ(ãNb[õ¡­‡¬¶¶ôûkõ¶²eû Ã0L§ÀV92 Ã0ëІa˜Nuh Ã0L§À:4†a¦S`Ã0 Ó)°a†éX‡Æ0 Ãt ¬Cc†a:Ö¡1 Ã0‚ÐÞ0!D@CJ$¦¢”†Ú;†iÄ:4¦uizÆ+µLBÌt¢gkÀÁöŽãï „hUª³ ”Ù—«N‡£A÷–JJ©[ „hš3ºR^φ;áÀ¶* 8Ú+5Õñº¸ á’äöŠiîÂ1GmÒ…e‚ Ž¾Kjï@˜“+àøJtopøMa<×Å>Á>p:ѵTá,½­½Ã`†i쮌a†éX‡Æ0Ç rTþÚwbåpu›­QÙÃùëÞ‹¡Tdó= À_÷^Œè^¥oëzƒö/#õŸ[dÇpÊ/ ñ×ÍŽâ•ñA¥qŒ«½ca:OùƒAÇ×RÙÛàÝÞÊ',¼ªÛ–Ìí³Ã¾íjgáe¯Y{–ÜÙuÛózß#‰¥×poå2'D®´dîxpz6%pªÏëu¿ªPõ¼Ãœ¾îR^tì2…ð&›©ÛÒ'»^I,TØóÏ\ Pç­øo5¯îó±9må’“]×ÉtÊvhõyn‘ÅÒË(¨Õç5t}ëJµeJ½ýÀ—”³¤¯ZÔuÛrz=DÃuçRLáÕ™³"2ÿø¬5êaÚGÐñí]„ÓZ2þ¸“S$„E×/FÑõk%›‚JŽó[«nNˆ=¨‰þÏEêˆëmþº÷b¼•OÎwMÙhJ]¼ªµêd:&wé­½åPù]ìŒ š¨{*À]|CÂ%õ= ”µFÝœ%i£¾Jóp¥"qŒöo<ìß½JÐô ´F'Ã)Ù¡y+ŸM’‚…·k£ïš¨‹›Qî’Û{óÊÄÐpMmµá^ŸÍiÏ\-ºWþ§µê`Ú¥"¡’k°B7è>N‘¥q¬KiëwÉ´×À¶/z¨,×=¤ïòÚ~gÁ…†ý»¦S*ÆN›«Ž¸ùy]ÜŒ"9T&ØóûË«û|,öÜL©dæ]¿1gnù€åQÛÅ›ÒVüÒø³&òŽjí¿Iœ °í4öm=›mNcg†¤Ïv€³à e©îBH¶m_ôÅ„ø#¢GÞKúÏ­¾ªÉ’ó,äT©_Z2¶|öü3odAÛ»SÙ5ÍAMämOkcŸ,9²nÂéemÌÃe@ˆ’ª#®ûÃS¶Å,ºWFš¾mõœ¨SrMt¯L8Uacg†Ä÷÷*tC|ÎÂ+‡J¡ŠIr¨rbÝÞ¸E¶ìŒç è\l´eg>[»'zu힘åõygÞFeöýï¬Ïí{¯-;cf힨uu{æ{Êÿ›q¬úÍéË—“?ßpÁÖo-Ó–QRNˆ\*ºW½PŸ×ë~wñÔ3›¿®‹›õ0˜ÓÖN6§­¬‹ñ€«èªA!ß–§úÿ3¥,Íñ‘;uï½'‡«yJC„ÊîR ÷ruä÷) £‘B¥W:޼XÂþÝj®?‡S$lk­ö2—ÊtÙ¯Tö ´e'¾ã8xî„ s‘©ñ5còW+9Þº‚W$Îoø[\ù*¥"ñV<üˆÂ­ïòæå*ó•JÁ‚ëœ*{c¤à¡;yUò:C»㠧)õ×¾õ^ãç`KœcGÙóϸÅ[ñÈÛœ2ñ#môƒ¶3NÑM9}%•iuû’>´ï?wR ~nÓ¤¥1éÓMœû#'ÄþdN_5Ùœ¾l¸Kïø +ôqÏ^¥±^§,–_ì8xñ$ ’'RKoá„è½ÆÄ/%¼yßöù‡’X¨h¯62íÇÒ}ç …îìç¨äÌ:úض7úGWÑ”ÁÀ)¢EàÕYA^$DICÞS8>r™ Xòm1+M–PŠóU¿’ÚxMAÛo¾.öébcò—›9!f‰$÷W1P*WáeÏ€S—˜ÒV~ߺ-f:"mì“%ÚØ§FÞpHòï»Í]|Ãoõ¹ORÙÃÞ"Dá$^ä aoùý=¨ÈP™.ûJWª9UŠƒ"×JÁü ¯I8Mž9mí"•åªz]ü ¯Sìæ­|â˜_Þe©.ž†í™”ŠqB‡ÿJ9ª#¦Ú¨:ß_ûöd)7Í]zßÓÞÊç2u[ôœ Î Â…)(ÔYAðU¿Ú…Jž³U—^IeÀ Ñ>N³R‹.°Q”Z27| ¼*íMûþs¯öV·ÿTö$€(Ü4lNY¡±Þüœ.î©â–ê¯Ï뻪ҼL¡ô±)õ»umÑþ¿ëp.Ç2r¶[rbfPŠ.m¶útMN,‰… {^߽Ƥùg)M—tª‡ÿÝ…cpmÈoï8þBˆN;3étNN\ŸÛýQ€#zd¿ÖÞ±œLÇW‚§ä–J©û”¼C3$~°À1ŸãUébD榹æ6–)tgù­=ö¾à¿L¶fe¿àÅãÕÑ}ÇûÞ?Á°†a˜VtJvh sªà]ÂJ㸩‚î,o{ÇœÞÔ×͸N½b–uhÔÖkQÉ¥lï8˜Î‡%5&/`~0íNóøQA:Ö¡ÐF?СŸ~g†aŽï”ÌÂ0 Ã0GbwhL« ¯$W>C%ÛÛ«“EG¸½c8¢˜OPóN›îmÇ´`IÓg  Q™Æ' Ú^ì§“‘Cuœß1¯Œ†<í¶lŸ£áïŒé„(¥§D§F¨Ú;¦Õˆ”ÒÀƒý¢;³¥4ÔÞA0 ô6Bi§^ÅÉ0 Ü&Ø¢†a¦S`Ã0 Ó)°UŽL«âUi ¼"FÓÞq0'_(¸»¶=Bˆl­@gE)¥^!¶3sç%Òvœ(åÑjcòg<Ç™Ž0sÊÝËO郧ÒVuwWNwZ&Éî¼dˆŽïD†;4•Òxa’ :æ.ÜÌ)*äßICž Úyiµpl×åN…œzs ºþP›&œ¶Ùö;%Y$¢sqÓ+M/r*mÃü=®’;Øó_ Ü6N¥!†a†9&Ö¡1 Ã0ëІa˜Nuh Ã0L§À:4†a¦S`Ã0Ì y·t¸daÿ5¥b«¬l¦²‡ r:üƒé¬Cc†ùêóMküÙYxÅë²dïPã9]þTÀöEäɺž»ôŽ^®¢©À[5+ÙU4íê“uíÖÂR_1 ǯúåY,žhß?Ò¡4ŽÚ¾ªSCÞ­½µ1®T™Æ¹ÀSþHZØ¿3CŸðú*Al58•hJùz#8 ¯:[‹»)tgoÕ'¼–’X¨p—Üu.•=&CÂë‹ë’%;ï*ºî­1iöjNˆ‘¨ìá\EןC8ߘm¼KjNP÷øÞ˜ôÙöwóp¥~øg¦”pŠø•žŠ'†¶o©!¼©JÿBÁŸcÖ4§¯X¬yx¡®î¨Ÿo¥’§W8{Ž®K“Cç êÞnJE‹èüy¼ Î¨;Ñ÷ûŸbCŽ Ã0 ùSHA7øð%@8M™¾ËËï4vxÍqÊ$õ¬5€*Olº"®A” @i8¾mBoÀ¾Ð"‰…#¬=þ×~༠4\—*è׋¢Ž¬‡WwÿLtþ|£óàcœ"áO9\ ov4üÛX%‡k­@e_$¯LúƒJ«,9L KžÄ†Ø"…tô „5†®oç¨Ì“Ö‡ý{&Û²3ž 6\Ë:u—$Vœ]ŸÛïž¿Š—W¥‹¼2áw[væ³¶œ^×ç¾Þ]rK_[vÆs¢{Õ8›w·Eg€Fó`2KNÜù¸Jî Aû—)¥í–m_©’fLž/p‚…@Ðñ£ÉSñØí֬엠n_â'‘½Jnn¯øZr²cªÏís¿&òŽš¨Ûª…“‡ê¸…'ëúǬ7oÐ4¥þœ‹N&ѵTá)¹¯"®®?Ù×n „“!yNWµiB¨µë :¾7+£]„Óõ™ò¬Ó)ôÃ9§$‡Ê„úüsÞŽÈÜp7¥!Â+Sšâ]+ Jã(wóãÃþ=j4}'gØ¿GÝüoÐ4Âëìr¨&]ß好•3®¤4`R›¯øV÷Tq}Þ iÝ7Ïi{{óó¥Pi¦,ŒI,ë%‰EFI,N”Äâ¦ÔoŸ“CÕý|5oÆIba¬,¼Ô”òåL*{¬îâ‡ñª” 1éóW-™›ž—ÙcBÞZwé]=¥@ÞHsÚÒ™ú.¯În¬Çqð¢1!ïÆqÆäÏ—7¯_W¥\D¯zʹ•W¥æh£îþÂoûäɦכ«2wÞ¸Suۻ津¿Jbiº,Œ’ÄÂh)Xp©1yÎK”Lž²zûëfG…¼'Y2ÖÌÕîâéCþTw¨bˆB´tßöº»äö鼺{®)åË7ƒŽo€oëÔˆ{ž5§-©ÐöpBô¥aôg–Œ5ß»‹oMeŸÙ˜øáë¢kÙ½aÿµ,–fÉáª,Kæ†Ç½U3ÊáÚ®–Ì3Ãþìóýu³£‚ŽïnÒÅü÷CkÏü§Õ–«JNößs4Ž·HÝ·Ì>þ‘LKÚ¤C“ÄB…}ÿÈËÚ¢®“Åq`Ô%!ïFm{Ôí<4q„¯öí¸ö¨»­N·OóP™6æÁ}²äLÔÏ·Böwó”?tW ~Áµ á¿ú4eEàU©«MŸ'Df‡<ëÓ€¢6 Úþ¥áüUáÀÁa¶ÆUtíöü!QÙŸè¯ý gÈ»q¸ °„W¦„š¾Ó5ìß=Ý’¹éNˆ9ê«1é£Å„()•œ=M)_oÔDÞRp¡ ãÇ#·åþˬ œ"î7…nˆW$d‡ûÓõó†Q*FØ÷|Xקˡʮ¾‘MÉŸýBˆ’ÊaÛ wÓgá”Jüu³£xeê/¶ìô—Ývd]’X|ˆÞ€j¢î~C©fy7^`GݾÔ7 Q8°NÐôÿÁ”ºpƒ-;í@ðNmSèÎ^+ºW^‚¦ßb•yB®·òé‡#zìzľä¼29O è§2OX¬‹{¦È¾ø•œSaJ]¸(‰-;ícBN™¼ã#êÂ}ç‚RAi<ï[C×÷ö9Œ'‰EC@m½þ}ÂiÃþºO¯ k8EÌ>KÆoߊžß/R/*v;ÃÔíÇguV°>·Ï*óåßÉR½Vt-¿ TVòêÌuæn?®®Ïí{•ƒf@RY{xôOïavúK'‚p¡ˆ»Ÿ÷UÍL ØæÞ Â…)•Túø3ÔSmÇ‹îuCü°ÍéöïÈJ€È–î[i>§r*4}D½Ë–ÝýC×·_#œ1§‘9ÞtTÆ1ï;ŽyTÒpBT¶%sã¼Æóµ1÷¯w—ÞûH}NÖ9„7ï&¼ÕÏ ÖZ€—€ðUœ`uÊá:3!‚Û–ÝýuŽ×—º¾ý^8¯ñV<úX}nßaD0ï%B¤[ßåå<ûþá=mÙi/ƒ¨lÖ¬ìY„3æ›R¿ÿÍYxuÐQ0éºÆ9±†8M ,4‘Ógûë>¾1h_¨Q.x”Æ ¿ôUÏzDéàëjP™.]t|uØ»}'X*9Áê(¡’³ 8!ÒFe¯_ûH©è^¹«áÿ)Jº!ß“?ßÖRݺ˜ÿÌöÕ¼~Íþm4À…¬=óŸró<À…@TvC×·vùëfWúë>¸É¾x²>þù%îÒ»§×çd½$¨»/VG¹I•¥Œ¢¼`Lúpµ£`âT[vú‹ˆ&úž7uŸN¤²'Dði£ïÿ°Uþ N!ÎÂÉCoôÊbE´9mÉ wé½$±$®1[†³pòŽp‡9ÝõñÏýâ«}§•ƒ*SÊüµ„ÓË!ï·âñó†{t±O”¸Kïè¥4\P¦2Otì -!÷ª®†ÄöøëfGì †h£îüMežè:}5oœ 9 ÓDݾ\q­yLœí‚û“ÍiË~q—Ýß] ä%ß[%:±†¼Û®çqë•ú¡E²dçÝÅ7#¼ÅeLút‡®æ=ež)Kn'X\†®ïìlžíƒR‘¸Š® ( ªŒÉs×p¼Ej¼Ž®‹ÑÅ>¶TiãòVÍL ¹×ôÕÅÏX¥Ð ñ5Æç­|¶¯$^fß?Ò§Ÿ±œSÄ…Ü¥wŸ/hz´ÆœìqW9Öí‰]lHüð9\§ôT<úUTŸšó‡& —IJnÝ7Ï‘%;ï­x*St­¸R¡ü3¯Lª÷×}ürdïŠ+Ü¥÷f…<¿oHüègáäY‘½ ï©Û³LŸðÊÕ*Ë”z[vÆ»‘½Šî¨ÛÛåkMäô‡uqÏÕíK}ØøîS‚n°·>§ïÇ‘½Knt¼hŒØ?DðZ{îÂ]zo–è^5Κµï庽]çX2×ÝÒ¸ˆR‘ÔíÿÝÚóÀ0Ž·Huû’ß5&¾ÿ¨ªRz«^xÈœ¶ô ûQoEö*j–±åôzXiõ£Ê8ºÂ]z×S¦”…O8 ¯œ¡‹~–¿öÝQ„ÓzŒI³—ÕçýIdïÒlÙi¯hc}™WÆ]%w¼`ÍÚ{¯-»Ç]Ü“ÿm~ú39\Í{+Ÿë.ºVLV†ÇñVo ~Ác m»x4•}zKÆšï¯Ïí{ŸB?l…<” ‰…­Y¹Ï×çy› 9ãcÒ'»þî/·#®rl+ÎCGÇÛ - IDATÈ¡ª®Í;Cæä9W9Öí[Ä)â—ªLã :¾¿„ð¦jNSöící¹ÿ‰º½ñ 9E—å„ÓÛ¤`ÞTAÝë9\Á 1ûMiK–Øö¥ÎU臾öm¿LÐü4¨”ÄÒôˆî[?©Ïx3§ˆ/àq6ѽúJ…aÄBѵüvsÚÒ{´ýå1^•êÔFÝ]ùÿ1uù’¢6)M—,]ËG€p¯LÙöm™hHüèYWñM/*´¾ÖDݾË]2}† éÿƒªHdNŸðæ·Ž‚±kš3žS™'mõÕ¼ú€ é»DׯRÙo4§/ŸcËNߤО9C×&NWoÉXÿuݾ”·uż2¡JШ :ê+‰Å}ÚkD÷ê›#{ÝÑŸ·ò™dݧO©,_ÑFß{оÿÜwÚþ ¼a¼"a—9}ÅÏÿê{Ä*Çã9rÊ*•y¼S1ÙF8ÍAàñuTöD‹îÕúúÜ~„ý{{€@–‚…©@8m¨#&QÉ•ú§ëÞ¥²L©ox.r”Š„÷èâž)ÐYiãj¸¡œ$*Tæ+¶É²ë,^Ýc5º¾™Cew7WÑõˆ`Þ×|iëáús8Þ"‹IžòG§újÞœBxkn ~^©+›O%g÷{ÍhOù£S g( ù¶_ÓÅ>¶4Èë*¹c§LX Töføkßžì)t*Ç›òåP¥ 4^øº¯úÕ{mÙÝ^k>L%º–ëóÎz?ìÏÎ@¥ÀÁ†÷ˆoø¶Í)bê¨ìŒ9æÛ/Dç5´Io“C•ÑÇý}1…~Ä~…þœÍíÓ™pAsúÊOtqOËáê äpmzØ¿o•œ†¹€%cÍlsú²ÎoN_±Xi¼èg)TÖÏSv_O"Xv™R¾Þ¨²\ñaØ·cŒ!iö9T5äPÕPcÒGëDϺq€¬ y~¿TÖzÊ ‘ù!ïS¤@NªÚrå_˜‰dLYð¡>þ¹Cr¨ì"*9Âþ]çQÉÝ4È¢´+ à ¤À~•¼ÝÃìá²dO’IJQ@ˆ&ßœ¾b1Ì!*yzÿ¶Ê‘ ¯«óÍiË–h£ïûFUõó×}Mï7§ý²ÌøÑnMä-5aö¥C†÷‹@ÅXOÙƒ™Ñ)£k@·!áÜ sq$!J›)õ‡µúø—Þ \t²CÿjÙ~Ðñc"á4ejË¿{«f] ¹ Kγ<¦‰®UÃ9e×:‰JzçÁqcyuZ1!‚÷ðwMßÞ oØï(¸ô|^[¢pÞ,{«ž{F9ýú@ýüÇõsw«#¦ÚxeÊò kéKÚè¦á(D•iœËÍi*tg­W[oÞ°™¤‹›Qè·ÍIr—Ý×C¡\Íñ¦0¯L\A! †.³¾ Ø¿IVG\]ç«~@CÊBø@Ø·sª>á÷5ı‰SvÍÓÅ>ù{ þ‹JC„ãM~cò¼ç]EW=°¥¾·²á=ú)‰pÚR•eâ&_ÕËãüí;,æŸk|ÿæ¤!¼»iÈŸ¨KÌiK^9üeº!Cá‚MÏžþp•JAÓ¯Ft­´€$–X ¯«äx‹DxS®}ÿð+ oÊㄉp†JA¾Ò˜ÞVûé뮺¹ ´²ë×ʨÙE2ÃÓ¼ÖµiRÝ]ˆ–5D`'€&þ«×xO~Š­ìñWD¶"@5ûUα«««vÖHQpÚäß—“LÌ)[ù3/s®1˜”¦m¢$).FÝÿsRÒò©nˆ@›´v`´•=þ ïÉK`ô°•KÉÚ­ü1UÅ~rœ BóÝ ŸŽ YŸSò¶')y;%Kß @Éo©¡¤™û@J3öP²[ê)yÛS”¬]žoÌÛäRòvM4ÕþkœO¡á|8ªÆ'_ާª³&;ÞkY­ñ˜—ëµ3b/|Æ¥c¯x1ýbòKÙ+_jåž½Ü EœÏcVäëH{ÅèÌË­û¿ ­è¼ÌRØ'Û˜—9Þ˜—1éBåe!O×’˜Œ¹©Óx瞇¤úá«$š{æÝ9“%šþ?ÈÃ_^Í9÷ 0æeL2æ¦ÌpÕ¿eÌË|ÕV>z4l-)EÇÃçµIÙã[éÈ׌y™ã¹iÙŸQ²6‚‰ÜgÌM}Ó˜—1Áœß¥‰£É$p$³3@ícä¹Ú ¤é^’ŽÚeÌMžcÌKŸì¨ž”$Õ=üÇøÅ3ƼŒ ÆÜäÙ¼ë4°<"$ ÆÜ´lÞ{JFP†ãÆÜ”é^Ó²1Mÿï/4n—ÊUW qÖLMð˜W<Ò\×ËÏÕPapTOJò˜–cÔ½ªc?;z%uÝÌÜl{h9q‹ …Ï\¬ŒŽ1/c¢D;hEsqÕ áÛ¯l½‹^Fðžj¥OÛ÷Å¥œo)ì=Qz£?õÇ{r“ç2 'úŽSfÊÃ_™®=׿uÉÂ^Üv.}À‹Á^þlkPÅ.:ë{Â{ò$öògïÓ¥l[q©õþ÷Ð΅ǼB'Ñ´\ìÿdsuŽóÁÚ6ª(Y+·ß«õRÚù»²ÍÕ<.õs?[B‹\ ø4赬ÖЪnŽ 9®]ì\ÿ´RˆÔ0²’”¤œ×#J>áõ+mƒQÞYGË;Nú»ˆü ×'^Ëj³nö ,Ø#!5«b,¥]\¦mÆbÑ«õy™nÿÀ§©È9ÿì 0šÄ•süu8kçÄx­«{êR¶-µ?ÐKðÝFJRvj[®ÞÊ»Imeÿ†E{ Àœºyû®úù‘ãW`Ñ.Ñ øFðšWŽDyUÏ_T1æ6?c™ó;‚+œ  …ºÔ]ßž©¯îîÆÅOB<­è´^÷ÕAÞ[мH4åwNÖ§îYâ³yF¬(X³Œyé“)Y»-ÓÒž®ºwÚRòök5 Ëwû&˜ÑýE¾>•Vv]§Žýì(Æ<X@Ö’aE®º…ÈU·œYÛzµ£zêƒXt$ÚûRFM/6çwHâùºV´²ë:À"`)º·à-ºƒ #ŽTh­"rê>ÀàO^‰mÑRݰ%ŠÈ)7T˜ÍµÂ¿js±\ìysUKiçïÊ6Wó¸ÔÏýøžèšú.\ÌyW¦nr!®zÉ$pn¥Í‘…>wÅ릌º·=8™Ý˜\¹\ðžzRùÆ"‚Ž.´W¼0@9ýsCFþ,ØÂíϧ³ö-JÖ¾q´*fÁuÜ×s :’°—nëi\4V9íg[éãE®&QŸ¶¦àÍïæjXi/õ"ÕªèwçcÁ~Örš«þ½7¤úGVé[š*Ѭd”wÖéÒöLSÇ}ù>kýõœ+öòÑmcÒq2[ýÞÊÀÏhE–E—²i†&ñ§·Yû¶ÇH&f+%kó£2PD¼^Ži±!=o–&á»=Xdåš„åÓ8çŸ#ìeO>„HµE›´îmÖ¶ùÿD¾Ž¹ê[¶T.²å "[ÑU›´îM©adƒ¿^GÕÄ'H¦E±"|Ü—Ó’×}c\Ó 0+Ó·:2[ô–Æli¬³vF¬à-¸S›´nšÈÕe lE²ÈÕÑ"WÓ@`K†ÑЬ½Rýc_yLßxƒQ÷µ!RÓd¿áôÚ>!_ àÓÕ³—?ÛÚ^1f ‚EG-¡¡òÐÑ'­%Ã5æÄLËo]®Iüi»ÿ3¯mc¸×üÃH@¢;ÉÝøùY)=·T?ì7Ÿ,áå]‡¤WÝ ÖKQ¿Nèªÿ0.°<)MÙàêö#ò¦¶º´ýób°£fšÃcü2@1imà’kßÒž`âv“’d–”$íù†&*$I+üO§îÆOÏëuÄçÜ'£YîkmÇ• x Dª…s©á\,þq¸ã1‹wŽärÅ‘.Æ)„‰/¾ÜÊ/J’TOJÏݼXÛ†>"W“úweD¶‚æ]GG"çü³¯¥ð®ïì•/§¯<ï:ò< Š÷?Δßùñ˱ëßÄUÿA‚£jâYRG×3Xt¶ØÚYýF&AjO8«&¥^Cú‰éˆUˆ„T?ì°ÈյǢƒÀ˜E³@ªt¬£jâL¯eµ†”$í#¨ð£~u eôÛ{ÊpÜcZš)òu$íM®³ï‹‚çØ®ðÙá Xǃ¤úG?WÇ-y@TbÑ}Öw‘*Ñq2[—²õEι·ÉÓ k]ÓVuûI›ôë "˜#¡°è–U¢­æˆ5ù!!¨Ðý´¼ÃFCzÞ,]ê¶ñŠˆ ¥M+`šLf>ÛÔùŽª ©¾‰XPJ ÿ×@2±MÊ2ª;‰lE'Q0“{ªóY¥‰b þ[É®ÿ*¾eYÖ’!ùì\a7Ö’a;*ÇÝzeu<¸ ðï•൬ÔYKzóÂ%ÏÏŸÐ8çž`¿1/c" Ýaˆ;¢OݳķðÙÓ˜$¨°\]êÎe>Å W8 Ú¡IX>ÏUÿ~:çØ6 Æ¢„db·‰\egD(ªô­Ž½ËÚ·v$ÙŠ"ÖþGçØ>“€iWL&$ œ9¿Ë¤Ó{!˜ cö ’Ô}~•wã¢0Wý»£‹4"uÅê¸Ï–¢MÚ¤u`ƒ¥¨ï=^ËÏ/¨¢ßm.è9Xä*³/ yúyø+U€(›¶åÚΚ©Enã’ñ°ÄœÛ‘7¦ˆ4"ä5úVÇÞcmëÕöÊqÏæeˆ×ê[ùÐoƒ¹àö¡"Wß@ÈÃ'¿ånXðÆBŒMßêØ{îÆEa®º·Ç`cA*ÕÏ»¥ BéÐ$þ´Ý\Ðí!R’T¤Šùàˆ9ÿŽg1v(.eóF3`×ôÝ‹}+GP![e`e¡ÏïtTMxÎt²c„>mÿbYZÙãké° ”¬Í&Dj‹©ãRS„+"³—;«_̘›<amÒºlDjK*„E”¾ž BÎÚ‘‡ŽþÊÕðѬu’Qöøät}…ˆù”S¨#PD¼^Î9vì4ŸÌšˆr!RÕˆH Hõ)ß5ùK…$ð8ˆWÝÜh‘-l.èiaÔ½¸jg'rÎý­åáã6ùWHU“x÷áeô{›W‚XÛzµ×òs‚à-‰%¥©Åª˜sy÷1©«þÝ ‘k0LL­,ì…|Gå˽(yûeÔì"{Ř Ršj’‡>_c+ÑQ¢}°Àcþ6S“ðÃ.[éð,yøøcÎÚ™í¡ðˆ\]ˆ&ñûMˆPŠöŠ1œëà­”´UŽ*váa„ŒEa+û_g‘­ˆ—…=ÿ[`ÿ¬§õGLÞø”嵬Ժêç÷F¤Ö¨m¹z‹­ôñ‚· %ïpP³ ïBcf-~ð‘«Ž¥UÝ÷*£fùnb§¶«!«ã—n÷)¨ì–;ª^ëCJâ®Xû‚ÆÞßWGÉ;¬Ö$,ßݘ·–¸_L+á¨z5c^bÈ(œdÎïú¨£jR7DªíH4d7h÷]ZCÆ©q9 Xû%=J,º%§ï ±!ãÔ8s~×Gµ3³¡t!BÞ O;8ÃtòÖQ{ÎHåœ>cÌi9@ÓòçÉî†O¢]Öªã¾8ðW¾ ?ò°±»l¥#Æl -°Åw‡d–²—jã6-*eÆÞhcnò,:Z1ê>Ó°èQ#RW¤OÛû¥ñDëqŽêIIœ}GGR’¸OÛríÆ³ÆLôª©)Õ§íÿÌRÔïnDªk•³¿rT¿þˆ­ìíx÷‘,ZÑåGuü’Çc¾Ä¢›Æ¢G@ §ÏW`Ñ%µ•ý¯3 Æ¥j1k©³fú{ùs]oAR’²Y“øýfD(EGÕø¯õW­!=gî%^ûkB²jCFþ”À÷ '³›—Ó&ýþ+üz¦L«ãó‘Ù¥ŠÈì·e©üH´ƒ§Ÿ¯íÓ_Ä7š¼c_ê’7ýðÒÿÅ=§»´2jz±2júØæïK4ýg7O÷ùá€zvùß×·:²Àçâ,Ñôÿ0ðÿ¤úG7Ÿ«}Yèsµ²Ðçšxë[ùÀ¬IXöç™ÃRòök8Çî§e‘£>¤Yn}«ÃÒsÞö <⃒µ¶"”¼íIJÖÆÀÚ~@JRöÛ+^˜.ÑôÑœû#{”4õ˜õÔ€Y†ŒSãüç³ö-˪÷e·)¬}óý–S"%šAG½Öuóiy‡”¼c¥èžOhyǯ¼æ•ñ®c;$šÇœu³§ñîcsÎÝCÕñKÇÙ+_ÊÚÖ'¥inÖ¾í9uü7söm¯LÜ¥«5¸5ûô^´œQvßÍÚ~ïc)ê£KÞ¼Út¢Ý[$“°’ßrTd+eó”1/cIGåNf®úù‘®úy3uŸ°`÷­h`–¦•ÝÿôZWµ– Õj–ïn>NÍ¡•]÷{Í+žŒ?eTÝë½¶õïÓò¬7¶"Ózê~¥6yãZkÉд¢ëbι§ß•^§Kr ‘hô!,r•-e!O—ú?çÝÇ’ *¤€`b‹E®*‘úÓj #I·(@ˆ¶pÎÝúÀúið•#5"ß&pшÔÕøÞÓž3P–VÜö©!óÔXC橱”¬G,©RÝ#…çëƒÛ¸¸5 ¦Þcú>!i=€D÷P1l>[S¥ŽÿöM‚Ž^ûŽu:3PtD)AJy×±D‘ohE˳ΫEFJ’ˆ\E†ÈÕ¶qTMz °@#D`,Xie×rߘÈ+ücú×RÏÞSéX0¦;ª&=†E—2"rú"_oÌËXh-Úå\m_ÏÐòNZÑéÊän‚\ˆP¸°`Ñ©ã½p©Þyÿuu_ Ò©Š~ÿ„ÿiLÙâ­ÅšÄwr-í‡Egç:tœiÓ׆À:R½_“øãEäÔÏÉ»¡8¦MZÿ›ÈUÉ’—kÚ.÷¡à9ÙW:ªŽ’¶Z嵬Z ŠùðMJÖz•³fú}öòѽH&Ö—Ú^]Êæ%Ú¤ßÖcì ó-Ñ{i¯õ—‡±èÙ²®¬}‹cA¦MÞ¸Fóa®<ü•*ξu )I8Ð\‚Êcú¶/-ï¸DûÙQÿÄ…›Òk]=0¯äÝ9]ሼ1Äk]û0Æ"Ã:þ¸ýtk“ÖmhüIà*Û9ª'%!BY¬IXö§D3è»+¼LWæåHÒ-¶YK†=Î9wË]uï´…<³K`Kú¸êßâ]ûï§•·o½’úe†‘;oÁ}öòQmoQßs•ùúHGõ‰Žê7y÷1))IÜì¨zå α]᪛}º”ÔQ51É\Ðí!αóyZuÇ§Šˆ‰»£Õo$:ª& %™˜Ó¶"L+²Üú´ý‹E¾¾«Çô­/ºß“ÓßUÿn”À–ô‘…>»‡’µÙà1÷¸×ºVí¬ÓÜ.„€VõZ„Ãw#ŠY¥²ÅÜ éy³BÚÔö À"À»† BV€sZ©ã6`VÀ»sC€ÕbÌ"ÁSØ› Õû] g¨ã—ü!pUÝyÏÉ~Ѝé«} rιﴀ€ïž˜sþù„!=o&£êö3Æ‚ŒVd¹„³ô Iâw¼;g0k[ß$Ä…  Õ"ßáÍ9÷ÉxOÞ}†ô3HiêæsÕˆ»á£‘«ºÕ~b:IGíÌI}ýõ+ÈyÀ˜¢åýý¸ ÃßÕy1\´RH r%IY‹H­¨IZ·œ¤[ÚÊž˹öÅK´ƒ-RÝз<Æ%ÑÊîËT1æÒò[*(YëÔ¬Í1JÞ®ÔW_«-”´µ•’µ>ì+Óî¯r§2¤úÇŒò°—¦ðîc­ R—G21Md)Yæ>,XÃYëš{Yëš{Yû&½6iýjRšzÀVþÌˬcW2A‡sºƒµm¸€“_ÖÄ»@ñúDÖ¶®AG”jZ®YáëoÒ™”ͽs9ÇÎ(‚ŽÚçnüb¸D;ø]‰¦¿M“¸b'-ïô«£jüξ¹mS»Z¤díªTÑïd4÷.uÖÌ|ÂcZ6#j’Ö­%è°¯eåýˆÒíPF¿}‚`Zö?„Vtú˜’µ«‡¯”èþÈUÿÞOãâ‡X`ËCmåϼ,x‹Ó”-f/bÔ}m´¢ÓrwÃÂýŽ7"^ËJ­µøþXt®úw£¬%ÃÎv\ø‡±•ý¯Ý…Ký{\ª2ʵu޾;k¦&x­kÏŠåû¯BБsÓ²Ïw]uïo•c'ó2'sSfž]‚Ws“çxÌ?>/ÑÞ¿ªÙ¹vDjNsS¦³Öµÿ“hïÿÑœû»S—²mï>ö«aA$Aê‚ÔEˆ¶œñF”Õ^þÔ›ÆÜ–ï’¤_b0BÒzcnZ6kßò("”"É$®7æ&Í5æeLôÜP’–'¥úoÛÊŸë1¯ÐùíQ¶xë‘«ioÌkõ†1/süéåHdÌMËæÝyý/4VíÀFŒ=QÆÜÔ7®²ÛùË ¶ B^cÌMžÍ;þz¡z/ÄUW ¹Úó2Ç#Dð¢`×¥l×<˜ïßÀtâ–ç(ù­».Eéþâën3–Vݹ^ýþ‰«]÷¤Ò˜û9-k¿T¢|ÜQýÆ,FÙã³ÀÔ)çÜÛˆ‹Ý¤¾WCÅæJ TỉûÔžûì}Às~—áºÔÝߘN´+ }q©,äÉÓ‰[ÆPŠ;Î¥ÆT 9?^ËJ-£¾ÛxÝU¯¦x­ëiâ¿þ€”¦°ç»¦£¢aÌMË–hú-SFÏËðýßÒóž<L Ë;kÛ¨j -òu$ïΕ5‡9¬m£ŠRtpùÕ?ÎUçßžoߢ¼˜¶8çnyS Ê‹äŸV ¹Ú¨ã}(xòå~wäk"òoIiÚ?s"˜ü-¿õ¢þ¹n¬%Ã:óîCw“tÌauâ¿Z û<¢7Jà*Sœ5Óú”WÙÂVö¤À9w÷ŒIyØó %úa ¶’¡}¶üVJÖf³*vá^-ï/ruíÍîc»t)ÛÎ<]› îxXäê3©®PEÏûŽVvsšNf= PXt…É O~!¥ê´TÛ0‚Ôœåaå¬ÃÚÖv¹†tDHŒê®ß¼Ö5‘LÜmòÆ5"_GÚJ»G`ËÛS²¶›5 Ëw[ŠúÞƒE\ä*³ÔñK¦9*Ç= ò¦$‚ )`ÔwíVD¾Yb-~ ïÉëN2q´I¿­÷·g¯x>ݯ&Â(»¯°œxŸÈVt UÝW¨c?;Ê9¶+U“‰‚5Z¢éû³²ÅÛ¦“þr«ÈUf1ê>K9çž®Xt…ÊÃ^ú,PZËœße¸&ñ‡åŽêìLÁ{2M—²s¹9ÿ¶š–«¾ÃX ½–•Z‘«ïéª{KﵬÜÀ»ŽÞjÌMJJ’¶i“ÖÿÖ|Œ‚œÍ¹D&ÖNÒ‘'.cu¡ÉÌœßåQ‚ËóOf¶J±yÝçšx*\`Táý{Ó¼ŽK™Ì.v⼬Éìü+«¯ZÑÅu-'3ß?èßc_ RÝPSó­ƒ°óIDAT`Ù›¯e¥–sÿn®ÀÕ¦Ú˞ꢈœò#"•yú´‹(E§ :r«.yójÖ¾ù)mÒ¯stiNgÔw›l%Ã{aÁ©Ñ¥îžÅ»ÝÇ9v)*l;­ºsIàd {å7CFþ‚Ž,vT¿Þ@`KF2ê»7KÔ÷þà6~1Àm\2A9傎,,4QÙb½à-~@÷Ù[ó2¯uÍMËUÓxoAιOf+Ù‹.¥Ïžƒ÷±¶õj«Ìùúd]êÎלÕÙ=1`R¿tŽÀ–Þ'x‹Cìϧóž‚,}Úþ™"WÝÊQõêaUÌ‚<¿šˆ*ö“ã¾Lܪ؅sXÛÆQöŠ1ÏP²ŒMü×ó=æŸFˆ|͈¸QÓçzL˾dTwn¥ä·lr7|Üd cÊQ=¥ çÜÝO`«nǘEWݠ‘¯é*Ѷ R}Dö⇧Ã\‹Î0MËÕÙ¼'o/EJËAú|Íçþ]êîoýÒp~ôi]i½7 —=¡9k¦&ØJGtĘEóò3ÞŠæ‚;¾:¦]{<æåzË©þ½¯µ7nã—H:j%oïa”·mä='Îë©IÉÚþh.è±Àœû+"WC ÞÂ"ßÐÊœßu&¼æ)ç;×Y;m¨1/ý5Ás²—ÈÕ¶@HV¨Œš]¤Œž—Eg¼O‰ñRÝP“*îóÍ7ý*t'­ìæ$¨°|’‰ÛëSW”yÌËâoQ‘«ÏðÛã1¯H`”w¬'¨pAàÊo•¨ûl£YnDê÷pŽ]=@t¶0ÌšˆEwç$6o3uü—ë}w¹˜ycëØÙÏZ:|,&N;-‰šÄ—ꆚ¡ÈQ¶˜[(Õ>tR¬ÉMÇó–=¼ûH'À¬– uyÖâÁw](æŒVtÚpºÏåÓ7-þ®ì_¸ÏÙj2ÿ"WIý][‚·ùºKî¼…L`ÎÆ«ÅåÚ# fòjÝ,]ö„F2ñvRÒ²³oS:«^;#8,°e7Í xNªoqÖµ¶ãfB¢îw\äëÛpîãmI&þÐùʪ¢ßÙ’Y6 ‘ªZgí̳dâöÒófé[™¨l1ó"dV,:š¤ˆù:RäÛÒófLô>>¦æj¾e‘>­Z’€Ïñe<=É!„á´çª?Ä‚ £÷’’ø=Ù3Û·×DÈX’Ž=ÈÚ6uá=y,˜ÛP²Öû¥;iHÏ›eÈ(xMóÁ–¦íMžÖ©ýöú^kŽIuC–Òófé’7¼â×Mý+œw¿Mõæq‘«í…y %¿åOÞyà%J–Þ4–16‘¯ÿKå‘‚¿Ï‹7¬ÓÑÕÀ\Øk ¥°ÏWíìô£=[ù¨ž¶ÒÇï|ÏRØ{€?ÀZ2ì1{娗R§)¿óHË©û&¸ê?Œ¿¨òê(anª —ìXå¨|¹µdè—zÞ¹øÛYÚݸ(ÌÝðáp}«cï6ùR¢ø"U^Ö¶©%muT`Ëc9Ç.‹Žtc^údeÔìójcnÊLŒ9 £¾ë³À eGõ‰^ó÷O QºSâ­9‰ó¢l‚œ’µÿY“¸b§17émʉ©‘VÜökßô(%k·V¢tÂY3u¼¾Õ‘I悞O’„‚§ ½D;h"2»Ô\Ðí!‚ ¯ØâL,8¢)"5Åú´ƒ m¥Ã³8群$a6é÷uM•OBóuïݾ4ÖSƒ'I´¾ó‘ø÷ijo@œ<ìÅæuT½:Ë×LJõ#>”‡¿RnÌËXˆcĘSKµ| Œž—ïßüØÚRxφŒü)9‰ï#DÛ0vG‘’ä5"[Þc^%}n¶?näFG:ªÎc^¾×˜›4êRUüûÛD®†F¤Æ— ±cª±Àrjà«€y Ê©ˆþàD*E[éãVEäïHõnr5|ô¤9ÿö8âC‚ *ì€OyDU†HM1À¹Õ0e÷Ŗ»æ’Ö#R×drET¨‘º*Ÿ]†F@4ï;Ö–TˆS3½­ì‰{²ß!H]A…ºT±m´– ÔzjЀ˜R’بˆ|³Äœß5Õ˜›2 í‹•-æùÛ¤å–óÒ¦ÒÊ;V!R]§•_üöÊÃÆ}æn˜?Âcú.€ô2NfŸ«_¥ã RÓ$“ £yDêRŠN›•Q3rLöµŠˆ×ž'ÑøÙcþa8çÜsQºJ‚ qôù†Ö.¼œµ3bωᤤ崪w9çÜ'sV¿Ö‹VÞq\9¥ŒslW¸MK“D¶¼A…7 RéVÅ|œc-Ü]òÔaD8wã¢TYÈÓùŽê‰}c$ ý‡T7Äì¬+òF9ï:ØF:z“È7H¼æoonï>&å=ù÷»êD°ö?`Þ¤3t¨ûìUDL.ð˜¾6¸Kî…<µ]ªzÆiÇQ5>YdËî'%i_I4÷Öøö{íZ‰fÐÿï kߢtÖθ ÅI´úÕQhåíG•QÓ‹m¥wÀ¢]¡Žÿz"”¢µäá.iÜy‰´"+‡dlöŠ1¼;××KÈÚ¤u¶„¶—éIJ’*U1óó|v~kp7.º²«æCpA/ÇÆœ¸Ï”‘Ù“5Ó¦”>í&éèb@„(°åÉÊÈé?ÙËG½iÈ<5 áXØVC«C½½Ö_õ®ºycš+BpÎ}2wã§i¬mà ÚäßGîM5 ÿ]ýö0‰n¨É˜›òQHféèÆã-¾—…<5A™]Ú˜“ø¾:ö£)”¢³Ó”×ö³ÖåOXŠîé+x îD9 ¯û”Ú·ö7¤çÌm<ó¥.uûÓ–¢þc *¤X—²m…1/mª<ôùOe¡ÏÕz­kÕ^ó©¬ãgC2ËŸ0æeN¨û¬òo¸:k²ã=¦¥Ïc,2íÀ=y×!©¥xð¼ÌÒçl¥#:òîœNòð——9*_ý.¤M]WÝÜh·ñË‘ºÔݳ¹©›BZWÞ鬙ÚÒkY;È~ü¿Gà-dÌ…½ß É,}®ñXÄZUÜâa"W-uT¿þ]h›ú»¬Åƒ» \u‚>uÏW—zqo$/Ǜֶ^ín\Ô‹,Ã{Ž?’Yþäµ¶éjñ_órôZVkìcH4ýÞ‘ž(´^D+»~»¢äVQ²ÌJWýKhEÖ,FÝ'ÇU7ïu}«Ã/˜rÓÖR²6!Báùú²§~gí[ÑýøHgÍ´dÖºv$­ê±Œµm|V“ðÃË~é[ƒ£jü‡Ýi2Ã%Κ© :¶Þk]õ’:î˱QØZ2l!£ê5‹N™,tôa[éˆÏ$º!ÓhE×ZWíÌá€$‚T7lé톌‰ǣ—”þ£é·†µoíJÒ1§õ=ù¼çxïÜß^äkÛû”¡â?b”·/áÝ9YY¤ˆ˜´ÃZòèGŒªÇG¬cÇH‚2×§\xɦ™—ã—’Ô»>DË;|[œÈÕuPDL>o`,"¤§:š—è†1ö4 öµ•>ÖÑV:ìM‘­ˆÀ”ײ²©ª7"íÝP“O³é8£Ä9-£îkó¹bB`Kh‰vÈQ´e‘ÒV›|ëX´·´•>ÞQÚ¿›?ÉÄ•úšÐ–±Ž‰æ‚žƒUãLj|}ˆÞ(,Ú[ÊBG•š„EWB„W9µ‰*ˆÇüC4"äÕŒúžbQ°øösi)€4ä©,º[øÆD–ƒ}A„î&}ØŠ¿ÖŽ ¦V¢éo“è†!ó=±ÐQXpÕÏo@HišcŽDqºäÍÏ^k{‚\>í@+ Ò.wÒcúª%¢tG4 ßï–èþ”w¾€ Uµ-×n”‡>_„£âÅöÿƒÀUÜÊ{ ºÐª^’’–nÞ}¼“Ï{— sÕ½Ó€dâשã—îgí[;RÒŒ•êø¥ûIIü¯6T¸ˆ1Óò[On(YÛŸ4 ßíA¤ö˜«vv"kÛÔ@¤9Ç®~€‰³&ûL ˜Tÿ¨Ñ¯vBÉÚx¶:µox0¦\õó³5Óz‘’äŸÕñKhÜÁ¨îtøËKuCÌ"ol¯OÛû¥6yãZ,zÂ}û{«b/TFÍ>³Ê y² ÂœWÙC“°â5{Ř Àlç:t=!‚'¿³ö­.$÷»:~é~Jš±új]§ Nh»W`KSD¾qéé@÷PZy›¯p5,ˆ¼ú4ïÉÏôi‰µ-ÄØV,(­Eýïµ—?Û!ÊyZh÷Ì="U–Sï´—?ÝmE¤VtÖNÏ–…<õ8ï><¯êA2 ¼¶õs¤ºGÏxqÎ=÷¹êÞi!²ÕÝ“‰\u[FÙ} A…1æ"H:z›µä‘‘~å_›º}”¬íóɬ™©Êsа`OvÖL‹sÕ½3””$lÀ¢³½òå4ë©TØßÄQœ«þÝ(GÕ¤!¸AnPH&Ó¶\»QÛrõÖÿ’'ëÍ%kW¢× ²eD(|9s&Á%A޲Ž?ž‘hún,H±èh©Œš^쨚4`bó é'¦¢Í¢`” Ri H}=¬,8Ï¡œA²»Ï8Š RéSÞ@„€E/MêJÖþgCzÞ¬Öÿ§Múõ÷sõÁV6òVNjH?1‘ê|ÀI·¨Æ‚5¢iIô×ꢜڸˆd8@ˆmž6Æ·2±0[1e2%oï¡d·Ô#B•ëÛ7>™mÈ,~™dZÔcÑ×?,Z›H ^ œÐd!ÿÛIIÓ>¢dm<Œ²çJZžõ €_ÙJ‘Qßý±ÇøÕ}¼s¯,‚…HIRÖÖ¥Œšñ£(˜¢Yû–;iE§i”´uÓ §„¤ƒ@s®}]T1 ³þR*Ð$, Vç>ÞVûé뮺¹ ´²ë×ʨÙE2ÃÓ¼Ö_R¤º!»!- ÌgF0ÑÝÆ¯†I #fR²6yØ ŸpÎ]w ÞâdJ~ËMÒÚå$]`+{r,çÜ›@ÉÚX(iúvMâÊm´²ë Gõ”6æ*"&NôZ~îO0±yÚ–¿ü@šœc{BÐ&­ù*pHI’‡”¤nê™çnürÉÄRÒÔ_ûx%»¥ž’¥ï„›”ëMàÒmºÜ>Ø+FgŠ|é¬ë¿ rý# yº‰Ñ˜›:sü9Tj¾ªyJvË,zZ*"³K©.EHÒ@J[åñî#s“ÞÌ«šŸ§ˆš¶Gäko5æ¦Ìù†ŽÍ?§åíþðšWėǰèhaÌM™%°wž¯®KåºR ¹J ŽêIIÓ²qŒº÷B¿CŠ1/c‚D{ßOÅÿÓ×gÍôWýJךëqÍkY­qTO~Öž;àúPçhÎ¥Út¹}0æ$¾§Š[ü†£zòƒ$[èO r#ð_ÛC rr=+…(Â'¼~áR£¼³Ž–wœ­¯ˆ˜¼˜VvùÇYÍ ¹yÿt;72®ú÷{aÞØÍ˜—N¨¢ç/ŒIÓ‰vc0fÕò°—ËBž®wÕ¿å1~=€åã—zjYO êAÉÛ•*"³K-E÷ô•hæ\£oI¼ÈUÝJÐaÇu);—;*Ç¥r®}íD®>ƒ #ŽkZ®ZÉ»ËìϽ € R’ºCÛrõË©=o~7„$V}«£ïûÛ²•=Ñ^äªÃ•Ñïn±—?;@äRåíëT±‹ŽzÌËõ®ÚY#ÆgÅ Ù+_NcmæTЍ7ß÷ZV¥ñ®Ã÷ Bb‘ê‡ÿàÏšk[¯¶W DVMJSvh[®ÙôÏ\… AnN®+¥YèsµWZ£îmo.=#Õ?jü74 R'ÈBžlø§Û¹‘‘…>ó"•Ç éy³uo;]Rý°U´¼ã¿²…«~ÁDEÔŒ¯%ºÁk5Óš8S\Eªà- ØÊL-U lY¬À–u×$þ8]äêÚ¹êçG lI„à-¹O“°l{Ùw’¯:nÉ;ºÔ?gžÜ¾œs·Ü^1&Cðœì©MZ?KÙâÏýíXŠîéË9w÷WÇ/Ù`+{â‚Ô5j“Ö½íµmú?‘¯#ÕS_¢U½~•ž\ŽEWë@EÁLzÍ?WFMûL›´v%kã”êÉ5däO‘ž\æ6~qNoGgíì{H&î˜!#ª"âæi-Hë…ëê -ÈD(räáã+y÷±FË©{Lß@t·tT˜—ÿÝéþR’¸™’µñTH.çØ‘@P¡RòöFÕk³×º~ ïÎ=ä¨;éÁ¢;Öݰ0ƒ÷ät Ö‘Lwæ¦sÞ}ô)}zÞ‚Ô "W}lQ–¢~] ÑÝðI ]1ªè÷N¸êæ6‰÷rVMNG”&7ðÆÊQ9®§£zbG,ØšìÅú‘hØánX0Ö˜Ó²/£é¿˜Vd]±àr ÿ%®«'´ 7?”4ÝÕd‰®™²…Tÿ¨i™6iÝÛ†ô¼YÚ¤uo~N†J«ŠÂ˜EX°´û«"@¶Ê§ª! ¦Ö³ˆsîmG21Ç]õï÷ ˜˜ýú´ý37€ˆ(iæÁs§Eh#­¸m¾ß³• BЊοÒóféR·—GL.C„´Îݸ(Œsî–cÑ“h£<|l>l©~¯X,:Þ“7X—òÇ,©î᥀…³2¯H4÷ E¯Ê#&ÏöZ}9ãäæÀRÔ§ß’ãðz"ø„ä_…’µñ :ìˆ17-[³`ž_¡2ѯl!Q÷ýÄRÔw`AFP¡¹ºÔÝßøÏ—‡¿¼Ã^ñâDS^úíˆÔE¤ÁMP†R@¤¾–  V‘oÔ"DÙ¹i爐\³àcÞ“/sVOšl:ÑöDi#*Ä®l1÷¤¹ [†17i. ‰Ñžû"ÔùšÄ•Û¬%ü–SŒPDNûÖYýúcÆÜä!k“Ÿ*ÕøÄU÷öX$THzR’ÌÒòߘ zÎ@‚<ü•ù”¬Íæü.sILˆ ùÃg«¦J õ5i°ÙËŸë-°%w^FÕó‹í¢¹(¬%wA¤Ú)²ÕaÚ¤uí£3¶Ù>¹+LÒsg“LÜ&cnÒ\_"Ò @I’³ ˜ ˆô"Ü´²ç7¶Ò‘¯b¬€9…6iíLKÑ=³ÉjNª{¤Rd«·{­«ÿǹíÖ¥lýùÚööÆ!8¡ $ÈE¨£IXö'üé1¯ÐI´-º”í?pÎ}k(y;17é3mò†u¼ëÐfRšÂúsÖ©ã€#^ËJ-£éoEˆÁº´ã9ûv¥D;Ð  Ž_rþF 6ȹNhA‚ r™HuC̯ýB½¶Ïÿ^ ˜{ qŠ©ü“YË'‡$H W}ÚE×Ú†ÿ"Á -H A‚Ü'´ A‚ rSœÐ‚ $ÈMApB $H 7Á -H A‚Ü'´ A‚ rSœÐ‚ $ÈMApB $H 7Á -H A‚Ü¥¯‚ü³`è1}NÿÕn.D¾n°Š"‡DÞŒ®µA®&MS="Ѳ[b¥^è› kOnɵLð‰’Bp%àf…Ã_vÂÌ„ŠVÜ~­írõ¸¯à-©ø{]LîOôIEND®B`‚openchange-2.0/mapiproxy/documentation/pictures/mpm_stack.png000066400000000000000000000445111223057412600247140ustar00rootroot00000000000000‰PNG  IHDR~ÌíM®7sBIT|dˆ pHYs × ×B(›xtEXtSoftwarewww.inkscape.org›î< IDATxœìÝwxSeûðû9Ù³ištïIKK¡-Z6²— ™NÔWý9DEEÅ-(‚НˆÈÞ{hY-´´¥{ï™¶Ùy~@ú(Pš’ÜŸëâj’ç9ç܉µýöŒûJ) d „vN•]+†¼´µþæ±µøøÊœ;W|mgíÍcë>ðó‘:×ÜnLâèW;êý5·ŒÍ÷÷;xÕžu¨ú–±¼D׆1o«º—±õwòˆê±oŸ¬luLè ûN\ŽŒmXÐÙÍé'ÌM(¿ylã§¡n K`˜ðÞÙ²›Ç6}ÖÕ…0ÓíÆ€:ñý‹¥·Œ-ìæ ”’‰$–Ü<¶ùóîN&£šýÄüä¢{û*ÚÑ iäLþ(å–±m_Ç*ÕMUü)§ÜÓØ7½êÆJAkcÛ¿íçШ*O]‘wóØŽïÉjò%·«Ê“Ný43÷æ±K†Ø«Ê³dS?Ëʹyl×ÒQ²ÚÒùôÏr²ïelÿòÇ¥‰ÊéŸåfÝ·Œñ2–{ç¡Dìàwoc";¶[Ðp"Qøß2ÆÉÙ.AƒˆTØÊ˜’í4à¶cÎ}‰Ô±Ó­c%ÛÙ¯/HnH9N>½ÀΩ3ç^Æ„R7Ž£O$ÈœÃnÉ\9JÏ(¹ÜÛ˜ØÞƒãàÖ…È\Ão]ÎÞ“ëàÚì[˽9r—ÐÛŽÙ9w¹[·[Æìü¹Ç»G°o“ûp¥J?»GÞÓ˜DÀ•È܉ƒg÷[Ǿ<‰Ì8ôcQÊ´yLª ä‰í\ˆ[È6%¬ÆdN~<¡Ä™x…e†{ã˜"';ÞqÌ»ë6ÃðoøÌøB±’øu›Ìb8ÂÇýy¡ã×}:ÃpDm³s àóøvŒO÷i ‡gwØTîÃ7µÚŠÜøº?þØt÷Ÿ,Y‚{üµxnq£«¥k@u|&06­ž-½e?B¶€±t!„B¨}`ðC!„²üU „p+ .°-]B!Ô‘aðCÖB™zâ'©¥‹@u|zM !„Xº „,÷ kQþØ\üC!tGªÊ<æÀŠq lç‚lþ¢DVRj:-]B¨cã‰í©GçáU ½ëd„¬?„B6ƒË—ÒÈÑŸ4RJõ–®!KÀà‡B!d#0ø!„BÙ ~È*`;„Bèî0ø!kí\B¡»Àà‡¬EyX¿Yõ–.!Ô±©*ó˜­_v÷$„ˆ-] B–€ÁYJ©^æj°t¡Ž Û¹ [‡Á!„ÍÀv.ÈÖaðC!„²üB!„l?d!œÚ¢dlç‚BÝ?d-/ûÛ¹ „Bw€ÁY‹Šà>ÿ‡í\Bw„í\­Ãà‡¬¥T§ðˆÀv.¡;â‰í©{ð jÀv.ÈFaðC!d3¸|)ûe¶sA¶ ƒB!„À« º®ºø2'åè–®!t+Ô©)jÔ§¥–®¡G?d!ìñï^dIŒ÷»Ž¢ÔýRUÑ•—ŠàÆYBèß1è›xe%Ç2`ünéZzÔaðCÖÂ)éàWv}¦­¨þ7+áó쌣Ǭ¼ü ŠBý{Y™{Ožú’eé:²x޲•z¾ ²t¡ŽMU“Çlÿº'¶sA6 ƒ² ”R­Ò·'^¥‡º#žÀž:úöª¥kAÈ0ø!„²\¾”öœ¸XE)Åà‡l?„B!Á!„BÈF`ðCV®/ÏÀ«þB¡;Àà‡¬…SÒÁ¯ì,]B!Ô‘aðCÖÛ¹ „îJU“Çìø&ÆÛ¹ […ÁYlç‚j ߎ*<"êÛ¹ …Á!dutZ«¨ðŒÌÒu Ž‡+Ñ^S–Öc;d«0ø!„¬NzÚV·¿×yËÒu „PGƒÁ!du¼|”xì‹•–®!„:¶¥ @èA „°&ÌOa$ö^&KׂnïïucF‡w›qîâù_{jµuâа'Ou˜‘³{ÇKýªª®ºw žp¶gÌ›iåÜCûßî]U•æI)e\\"®ñcÃp(À?' —’|鯈¦Ær/ŸIûò@}]¾ 3cwp×nÏçl\?ndç°©‰—WwW«+e~þÃ/ôíÿñ%€Œ«;®$¯u÷ˆÍMI^×ÓÉ)<{èˆO;òQxNöp þÃ{÷Ù W3ÿlž224lú…ΓŠœi0hÙ]»=åðÁ¹Mœ´y›#0TW]îÛóÆ° OlÜÆåIŒøÈBè¸ÇY çÄ=Ÿâ9]\AþÉ>‡ö¿5M*u¯”J=ËŽš÷ÊŸ«NW««Ånn=®ž:ùÅÓçÏþìP[“-Ôëy¡aÓOyû HÊÊÜÛ{˦©ÃÌëÊÏ?Ñëàþ·žãñ$jG§°¬Ä +žØ»ûµ^5ÕY’‚¼1ÿÛî‰ØƒûÞ|N(TÔ;8tÊ?¿dúáƒïFT”§8ddìz6aÉHW·è«n½ ÷ïÕã\ÂÒ©ry@QüéÅOÜÿVw6G`’Ûû—Ø;땪˜—xq¥ÏÅó¿M •åè¦*/¿r*î«PóvãN|ÞC¥*vÂЇê(p²Uþ=žÅïçG€·ï ø£–Ÿøq±W¤Ñ¨çLšº}@EE²GVÖÞÈî¯d¹¹÷¬0iÓ€¢Â32½^ÍIOÛ2ö˜×åäžüø„¿˜LVFúöÃF,=ÝÚv]Ý£/Œ·ú0À?'qÓ®l`ÞCh4h…ÿsµ³KdÀáƒsŸö vpôã¿زi ;5åïÁ ùöìcC¿;[\|6ðïucžTÕzED½´ÁÇ÷±J?¿¡'Ò®lîmÞ›˜“}(¶kÄ Ûʉ&9¼b’™“b ”6Xº„ÚîñCVRªqñëí\¾¾C²ÍB‡JGǰ,ós‰Ô£²¡¾ØÀ W3ÿ]Ñó™{¾·mËÓ3²3÷öÒinØ«ëêÖ£yY?ÿajuµÓí¶ëáÙ»y®·ÏÀæòùöåæÐG©‰hÔ5޾~C2š×0<]£©UšŸ›¸~SuUFg‘عhÀ /.˜_ïÓïÄúú|ßü¼cÎ/÷5µüØ>ï&ßÛ'„&lç‚l?„P»bXìæó0 J†¶|n~|ìȇ:JòúìüÏÿïõ«‹‚;?q€Þ°®úº|{ó㊊T6›×t»íÖVgËÍ«ª®:°Xÿ›ËbqšC! e³yMU•éÍó+ÊS”-çïÝõƒByi]]ž_ê•næ×¥vž'çnçÏœú.ærÒ±ž½O³X<<ï´Áv.ÈÖaðCuHª†b›-PÔÕæ ®¦m‹¹yNAÁÉnµ5Ù‚ÆÆrnÆÕÑr‡ +·[_^úúB~}}!?'ë@”BrÛ¹Šà”ÌŒÝÑõõ…üšêLafÆ®ž eð€øÓ‹‚ òOÆNxbãòΡS·Ø;{FCC)×¼ldÔË' âbÊË’»öŒyëÔ¿ûBèÁÂs¢BRLì»ñ›6Œ ÿa‘Û|£QÇ÷ôêW__èÝrŽLæ“ÿß=ß§ÔÈâò¤5'mZ~»õIí<‹W.|ßdÒsB‡²a#–î¾ÝÜá#Þ¶yã3~ý)ìS b‰kþˆQË·•–^”Æøâéž1o¯qqªsqŠ+->¸iÃøÉÏ>j @Hè”Â#‡ß¯ârÅ î15ìA¡€@¤¥‹@í®žRšq÷iB3åãLW¾Ôù¾«]>ôCEÊá7§NßsöAÖ†þŠò±ƒ"°ÑÜÆÅìûï\>îÛÿã?»>›[QqEììÜ­þvëXôµâóa#–þ4¶¸²*íŽs[ª®º*$„{¹ÿm!ßÌ W3Ë–øÍïÞcæÆ˜Þso»Wµ]VæÇ“§¾4 ›}äôf4±iõliíƒX×£Œ"ÜdsØ‘®Šg&…úVZºÔ>Œ&JþHÌh€o,]ËærzË›ŠÆšÂGïÑ]dé‚Ѓ¡tì|Ç+/Y,ž©­AŽÍ´y.€Ü!°ÍàÌ©o‚S¯lŽæ ä•úPG'ò°Ѿ³‹±t!¨ÝÔ^-³…vã«Ñ!™–.µFõGb†³¥ëxª‚z>ÏI9¶¤6õÄ/»¯œøYÀbq2Ø<ñY¾X™èàžÜcü·Ù<¡O´·~þÃ::†µéPª_ÀðCrEP›ßýR««Î.™={͹ø°·…ٿr¢;™“¬§”6ZºKâˆx¼þ«ŸNc‹xØgÒFì¾, wñ"«@)Õ<·¸Qç40ñìö÷†¥ÿi£Ñ  3ª»èšjë˯’ì ¹ ‹Ãæ ÏóDì“#†ÏO“»…c˜GÐè±«Ž¶uîØqk=ÄRšµlí‚:&OLå.U5EÉøÿ=²IüÕé>æógߨ!ÇÖ<û›Á ‰¦Ô$1™Œú º.H§©ÛP•k*¼²W@V9Ãâf³ØÜ|©Äݾ¡¡”+;c«„:MSµËŸs•k ‹]ɰ¸Õ,6·’ÅTqy’JžÈ¡J¢ð©rï4¤Ò#täÏs2;í׺̳ëñÿqd“0ø!«¢mªfÒO­”W%)ì]C©)I1tê~”sÃDJEôzO8j2ºMjW“AÓ åÔ¥ª›ª0ø!ÔÁp¸¢Z;çN+õ•ƒA§v04 ƒ¶Ñ_]_ª e©ò’ÌcŠôÓ«„0•„aU1 »ŠaØ• ‹SŰù•l® ŠÃ—TQj*"s’² ‚Rª¶ð[ûW!aB)ÅÓXP›`ðC!„NàØÊ×æÇ„0.”šd„0õ„aU†UI€èh«ç.B(ÃåIv*½£W;ûõ)¨H9üæÝ.&@µ?›§9ûÈá»Í+HÞ%,LÛ¯PUåʵ • V¥0êÕFƒÆI¯­nª-Rz{p%!DåPqÓ×Ö^«è€ŸYFÙ ¿Y[ÇôàaðCA±‡Öƒ\k_¹ð¿ÄåPvýkœ¿þ¼2tÀLì5£Jâàc8¿ë#§äËÁ ßçDL,'M,÷^3éÇÝN¾±Z€kí\úG=T¡#›4/z؈¥§-]˽R×2WMv#s’î¹ËõðTsý_úÝæBCëA1úÝôš!¤ÚkÌŽRúåõóýñõ&À0PB–ÀJJiÞ½¼gd}0øÙ ½ÉÄ'„ „»‡9 ­¹ ˆ»éõjKž\lnç°éÓ·MF½³Xî5¯ëw·øG?ÕæÃMM•dú1íz7½®ATV–4ÐÝ#vG{n¡ûUW—磪+èRW—ß.ç»™Lz¶Á { ±Y<1•86V&=ôv.×&V^ÿwW„( õ ÿû#ÜüšˆR--@ðàÚ¹$×ÿÍ€· !—áÚÁd¬±¥+º ~6H­7(`>Üæâá¦sè(¥ÜEYçÖI}zîøÜº¯ïuYßÈ)µðíC(ëŽÊ²O¹‹u½‚û,nïm#t? ÷Ç-14ö·€Ÿ…RgM{lS qz !“+ѾÓWÔæœû»£]¤”R#\ûù[Ö–ù„\ æ £n3{ýkwøLªœÊ+©ËOþ6gÐ]÷^"ëÁÏIyÜ¢úÆ™–®ãað‹šªò‹ššz?ËŠdnưAoV=èšî¦±¶P&Kl¡ûqa÷‚0€òìSÁ£ßŒ;hézl¥TÅPL íékÉMpmO ² -ä‚,عMw¿)Ü—ª¬J,PÜüz—·K#,æ¶§ÐT_.ìNñàÉEÇžÞò0·{Ú©ùg‚GcQ­˜N}üJœzùÚü}–ÿû ~/n;ѯXÕtÃ7€‹DX¹blŸcwZî“£Ââ + *ãsU>2IÅ“áWƒvm¾æØ¿ö?n0Q‹!Æ(WEÖ+Ñ!iJ!ß&;°ŸÈ+µw“5¾ré#݇ !ôèHØúŽ¥&;Uuî0Ààga„9ð5\;¼«‡kÏñáÚE+IpÎÀJi©y9û`—·]úú·éÎäï÷¯HÈÄ“‹n¸0.tæ€ÏYw~ÙëϤ,=6Säj—j2˜8º:µa1zïñ]7Ç.›×–m'~¾wª®VíȵT\úî ‹Çiì6ø¯^ŒÍiËòÖäøsk¨rªÜGµæ~×q_ÁïHNq?.‹¥ñ±—dÝËrGsKºdUׇD¸(âË4‰%Õ]–%¤¾2<À}óÚ‰ö·i9%wq–• xµë.gXt*yöž§†Îéåádsüßθçb<œÎ.Óû„¥k±4B3ma!á dxñBQAÊî„P¢×¨[º[v½›Âð”À8výëEJiõƒÜžÈÃ>u|â{?Ün\¯Ò° ÷¥:B¨×ã]JÍ{Y<¶jbê‡_™ç{{·”¥ÇÞ` ¹Úߌ;g~½>£\Xž'wX.t±»áP¼²‡ÏñÁ[þ³`[ô×/§ývrh§cÐV7rŒZ8JôyÛ/;+"=jÄžòNA0é¤è@šR[ÓÄõV‘ðo¹?±®VÍÖ7hY"w™¶`wŠ£ÐÍNíî®(9–!׫´á!å7ïá,:¦àÉ…:E¤g}}F¹Pâ«PCò«ù|±ž-âo^ËϬ`wг¼‹[­,عñæzò¶_r•ø8¨œûø×u,mm“D§ÒHëÒË„ m’x;Üó©÷}¨·›‹Câíš‘R²ðØÅÐÔŠZW{¯ñÕèÄÎŽö Ž"Aá–©ƒ·›ç~u2)ø³c‰ó¾»”ÿVl—4€ôÊ:áÒø”®õZ½`X€{úÔ0¿þ˜ê{òµ3ü¿ßðáW'.õÛ:mð6€¥ñ)þÁJûšäòj‡óÅ•žùº]}ºkÀ ýœ–ƧøÇVøpXŒá©pÿK|\où‹gù¹4_7‰°±¼Q-8’SðVlØ™pgÕ†äl·=ARWýVlØEO;qó‡¾3=ßiSJN¨¯\R>!Ä'gkZž×û}»¦è&òþ¡s‘ Eç\ÿ†Yq>Ý[)âkÆvò*ÐŒÌçÇòkê#\ùsbšϹȯkà/?›œ]Sïä-“”Ïêš|"¯TÑ ÓËÒ+k}ÞÙŸ îìh_þÌMïÓÆ¸Äoy˾ϴôBèFMõ¥cÌw¡@…Çÿœáß÷ÉUwm…‚ŠPX o[úœìsìè–úóñ—»‘-àÔ_øtwííBbÔÂ1+ÎçïÉùûü8sðÛ?æçq%G2Æqí…Eº:µ³ßÔ¨U½™ÚêN i€2»ähÆóó/þ5´æJI¨¾^#',bÔÕª]}'G®êóÛôcWÿ{ÚëìûÛß0é|ž½°äì¼­¢©ù çݼÞÓ³6õ-‹ËŠ1Œ\“ÞÄó²Ûwrdʉ—þzÝ Ò:£eØ,mÿ5Ï|ëÒ/ Z[ÝÈÙÙoñ5!,!·Vê§¼\TØÄÁ™3•Ñ^u;û?/ð™›#>y þ-1e'3{N¼òá×§^Û“ù×Ùç¸RA©®Níªˆô<8âàëöúy|åùüÞ\;A¹¾AkïÔËç¸ûД²S9ƒ¨ÁÈÝ3|Ù\žLP9î¼ïõ¿Õ?ǯQo`Eþ¼åí*µÖ£›³Ã‰"U“óW'“øŒïßê္½ÃS×&e]Ü’šóVl—´¸ü2ûñë,qØ5Ž"AÑÖ´Ü'ãòË~[:2æTk˳Æ ÒéÍ—®ÃO ©ãµF£ÀD)ÛY,Ìß––7=¾°|ŲQ±q}Wí|æriuŸ0'ùI›Ñ~q"Éq€ë†›×ûë¹Ôáu½ƒÆ`:Ø].mPó?Ûp¨ÏÑÜ’‘!JY|e“ÆqSJöÄ#Ïš¤°kúêdRðÇ“Þòµ—$Æ•wÿ#1ƒ«6%ï÷íúv­VÇþ)áÊìwû„?+ðô×ÖŸ6ÌÝNT4¶“׎U7fÅöüåÒÔoâ. ß“QpöÀ3#ÖU4i8‘¿lý.ÐÁî¼RȯڟUØËW.©)kP‹´£¨¢Iã˜XReþËÈ–ƒ_µo·‰œ»OCݯê¢$ŽQ¯íÞâ%¦,;n ´¡^GñoÚ¹t4”ÒÄöÜ^Sqÿ–ˆ/^7?çÉEU#¾ñWy|Žìʲc¯ùNŠø=ö§)' ‹¡M%uÜ;­Kå•Qq&g(@êÏÇýJŽfŒ‹ýeê{þÓ»žû`G·”ÎôyÅu@`€®N-ÉÙtѵìT¶{ÉÑŒ!òp·3-××XPÚëû'>z!&÷úòo¿Ü碬“sãÙ÷·¿!sKxlÓ ›8¾ñNµ5•ÔG|<òÓ.o=–°)ø“¹oyÆð}¯L»ýðTü››§<~îÝŸNÏÜØ_W«VŽ<6{–}ˆKÃÞá˦RmÓï¡üÉNk^ìõýÄŸë•WŸQ.Üóí7I_îOò2:«,.kä¨ã³gšÏ‡ÔT4pøJ±¾è`êUN•רøw–·e;­¹ïà·ûjÁdÅ—k7?tUÛ÷ôð ÿ·#®•Zë‘=kòç–]©­q“ ³kT:7J.à§¾þÄ—/ï8™ºîrÖÓ_ ‰ŽqØF€miyÝÏ–û\)¯íT«Ñ:}20rõÍëÌ™=e>ÀKÛO¦ý’3u٨ظE§.],®¼÷éá¯Çz:Ýõ„V½ÉÄ+|kÚ\€c¹%ò}™…“V=Þ÷½‰}Š–mžóöþø!Û§ Ùúë¹´Iý½]¶›÷féä“æÃ 7ª½e]ŽŽš(Û¤7’‚½WÂŽ’LÿéÝ ¢>}1íדª¼-‰®OÔ\.Š93{S˜®NíÌWŠsmx~KËõñ䢂 brÍ˧.?Ñ”½á| "Ò³D_¯qŠøpø~óáÝ;ÕÆµ›CŸºLÅm(¨ ³s½|zÖ¦0™‹ËÖÖ”FT%…ÊB\.šwz1öXù™œ‘mù,³7œëÂóª*/¸UœËw“‰p¤üŠÒ¸¬Náï¹Âó*Ž>µúy÷¡!'»}0,‘¯?°ï×û~ý}\¶½Û'ü¸ù¹“X H­¨ K/¶5ôè&›!:€üºß(WE‚yì•îÁ‰k“2_:‘[*à^PÕ¤U4é‚Ò†&o©8ÝÄÌ:)dÉæÇÏG]Z{)óåÓe²ÓåþŽ"Af[B@Âî’ùñ®«¾,†è¾<ü»S— ¥”QiõöuFJIe“Æ{¨¿ûŸæù==œ’6_ÉñkËv2ªëL”²b~Ûþ &J ‹ÝñÜR·—£‚SWžOçz-Z·0ÂEÿnŸðã=Ümî|F„åÕ•_F)¶|ÍhÐu.JÝ/p òH\dÖ‘Û¹tt\;AU¯%“niÚ­¯S Ø"^5Ãaµùëš”wŽ„_ÁpXÔШp¤üNÓáˆyÕz•–o~îÔÛßà-ÿÙÞ_ÍßûÝ‚ÃSÿ;vèÎWþùß|î ¿×9"^®^#P—©„„Åèå]ÜêÛRO.l¾ø>A4 IDATE•[)¢WiEÔ`b]¯«É¥à“Ö à+DÍÛUDxÜ1[P½‘e~¬«×ˆÀÔTTÛ|«P‡p÷óŠî^Ù£ãÞü8aîÖþ9/Œ¹ºêÔŒN/÷ù-êÓÑdï}?!‡­i-€0LFJ™{YWN­*ÀK&Î @¨ÑD›?­ÑÄP`1¤ùjFDàž×ztÎÌ®®ĬØñÅ [Oôÿ︾GÌã¦Û×M ‹a(CÀd‚ÿ­ûnìùܾQX„è§…ù»vמkœÅÂF¹V›ÞdjÞ®ÁdjÞ‡a(Оe>Ô«1æqœÄ‚éáþG[lîð@׉P—÷æÔ¹Ÿ½Ðe_Faakö~óÙ ¨¯^yd­ „¬ƒNS? nøùNh/ì^ë<¯îµQÝ< ³7^ð,;-kK«•ÊóùÒ¢Ci#{øú) s’ {›ÇkSKEêŠ_Y°óú›—{Ê5üùÌ››?*‹Ë:âëWÐTR`ÔèŸcªK/jª½äa®%.ýKáýí¬”%G;u}Xʽ¼/Ç>µ,>§NèbWÙwÕ“Gnç;JŠk¯”À~€´§‚[Ž ”ââš”w¸P•TØÙ<&uÍ+=–1ºÇ¢ Z»@Cì)× \7c/ì=2í¿Cs7_õéèDŽ„¯6j ü›çß‹~Ž_¨“<}kj& çnmVõÖ“›ŽŒ¬nÒzþ2º÷2{qÆåòš.FJw±¡?Å_‰pØu}¼œo9ißW.U?Ó-`ÍÊóéÏ—¨šâ\$B@ze]¨‘ÒM,Bèª éá".»*ÚMY××Û%c÷Ղ鲊ƒýÜÚÔIÝl\°Wæò³©BÁÈ6_„ 7š€£Hµ?«0ìž3â ËÃÍsd|®ÁAÈÏ[“”é÷~ß®)e jn~]c¨¿ƒ]&@°R–—_6à?‘Vš/þ0RJÌëç°º`@dÒ‚‘IQ¿leÎ.îôjtH¦½€WUÕ¤±»—÷B÷#aë;nÔd2ï0ߥ‡¡”ŠUU¹ÃÛºX=MEƒÛ¾‘?MhùZ¯'íîüFÿŒ´ßN^<çw†ÍÒnújŽË€ÀS»S ]¤é!¯öËpŒõÝ™¼äÈKgóÙ9V_*ò¶çÕmyÏ>º®Ëù'qÊž!?:*»{]UåT9êê5¢¡;_ù'lÖÀ}Ç_\»`׀x;–Ïè„4ßÁJí}9gã…IÇžýC«Ê©rS—©<¹vüJ€ÈOF%fo¼³{Ð’¹.}ýóD U‰…þÃ;_° rª½ôõþáN±~—*ÎæuWF{%øM‰JÎý'qÚqËLj=åå½~xâLë•ßÞ}¿Ã9ÅÃ~ø;Úü\ÊãÔœyܲ¥#cNœ)( úaãÒ¥,^k4òüäÒœõO Ü [ÛÐ9øÇMsµƒ°V£w¶p‹?ù…9ˆ}=¤Ç®Qk÷Í÷^´þK¹€W’[« )*xŸÍjõv`_ Ž>¿þrÖø×w²iÊc;Ø Ñû,Zÿ¹£HPQ]×ýÅÈN?¼’¹%5w×Ä ¿ t°Kà°‡aôÇfŒúãnï·—‡SíøŸÕ %¾µ:1#U)ä—Ö7zwwS&¬8`ÿÌž×Ï?tþݰe›½5£ˆEˆ¡åòÑnÊSߟNþ¿m©¹—KÔÞön‘ylù˜Þûc~Ûæöí_?)ìÎL”[£ê|ú?cæÍ?t¾OBQEwo™8«^«—æÕ5„,ÓûO€¡þîç–œI~©Ë²ÍÝÝ”W>Þ÷è½þw´„òô—•„áò± BAAÊî@ÀL„& L¥&1P*Ôk±­‹µséBrÛÛr>~vîâ¸ÿÛЯ6­ÔO•]it|@åUêã»×¤3pXŽÖ©—Ob·†oñÛ¥ù*_)Ö<È×µjïµe£Ý”·|S\ïMxÃN c¼ÞÓ¯Õ{)Êø\žï5ž¡cîØ>!tÌm\aê}#§Œ®+KóRח´……óþzßtêÚ§•¶.êÚBæàïÓ\Éœ :Ji›ï…µ¸§‹0îRQ¾‹Dhñ¿ä”"ÚM"¼§;› ûG)mòê2F{÷™¡{u­ Sëß}úˆ>Ó~Ín96maá<®@ö‡¦±jÈí–ïH®Äö^jx¤÷r¡ÿyló‹;;ÂÞ>€gê=ÛQ÷ö™Y]ðÛÿÌðõ·Û[Øž&‡ú%¼ôx‡øFD¡£±®8Ø¿û´q±S~Îmm|ÚÂÂyžøBAò.akã Oè`ê÷Ìï5”RüCÙ¤~U/B!ëÒwúŠ5N¾±w JS>Éý¼,;Ž×^5!„îÕíñC!ô`Ý-ôÝë<„å`ðC!„²üU „¸øë¹¥ë@!„:2 ~ÈZÔx†Ži´t¡ŽMS_Êìþa !¤Ã_ˆ‚ÐÀÁYlç‚j Âæ€ÈÎY ØÎÙ(v±ªI8}Ó‘à»OEÖ€R MzC…¥ë@!Kà Lýž][½z¶ÿP€Œ?¼ ›¹í­Øu1¨uBvVuýYÕõ–®µ/Ãݧ „²fµi¥[ãßþGjé:PûbSJU–.!„Bí‹Ršq÷YÈÚà9~!„B6ƒ² ØÎ!„º; ~ÈZÔzÀv.¡;ÒÔ—2{âŒí\­Âà‡¬¥´Ñ»Ûx¼J!tG„ÍD©lç‚l?„B6ÃÜÎ…RŠ("›„Á!„BÈF`ðC!„²üB!„l?d!®'Ö¿„í\B¡;Àà‡¬E½kàÀ&KêØ° ²uüU ”6øELÖXº„PÇF 8{=˜,] B–€Á!„ÍàI”¦A/l¨¢”âŠÈ&aðC!„²üB!„l?„B!ÁYBˆË© ÿgoé:B¡Ž ƒ²*GïÄÉÚ½š<Èy¡¶ÓÔ—2û–Žp"„,] B–€ÁYJiƒgÔ–®£-v.î;*aë;nwš³cQïAqë^h¯š²„°€Í€Zº„,ƒBíLâà›zrù–3›g{´6¾ý»ØÁÕÅ—¿ŒúKF{׆µãI”¦A/n®Äv.ÈVaðC¨ z~C P*N?µrçÍáoÇ¢Þƒª‹’V²9‚ólŽ÷H „z 0ø!dl®è0¥&‡ôS+wÖ–¦¹ìXÔg`UQÒr "{.!„Âà‡ˆí=öÂ4Pj²/ËŽ[”ŠªŠJ„†ôý¿ã–®!„õÁà‡¬Â£ÖÎ¥sÿ×SJùÀ¢Ô$¥Ô$»ú;+°çsõ.!„Âà‡¬Å#ÓÎÀ?ú)Ãâ\½þ”×[·=O$ßa©º²všúRfÿÏc± ²UüUx”Ú¹˜ñEòD{Ët ˆƒ* !«G B(`;d£0ø!d! Ϩƒ@ÀÐò5ÄÔïé?R,UBÖŽ'Qš{y[¶sA¶ ƒB2pÆú+È ÁÍÅ6.!„ ~Y›+: ×9B° B¡‡ ƒBt­­ i ¸ØÆ!„ÐÄÁYBˆó©¯?2í\ÌZ´u†ÅÎÆ6.!„& ~ÈZ4Éݹ“µ¯·uÉÀ6.=|ØÎÙ:¶¥ @èA ”Ö?·¸Qlé:î—/=¬i¬ ´ö6.ªªv܆W»YºŽ‡IdçZÝgúŠ,K×nÛ¹ [‡Á¡VìýiD÷öÚ›'*€Æj^Û l¯í Äʺ~O¯¾z÷™NS]1KÎËøØ`¯êöÜn{©ªhǽ” íüJ2Žò“|ÖÛº™ZUH©Éîa¿Ú9”õšøCþƒ\§¹ËêÙÒGîB?„Z!ÒfMÙÝ·²}¶æ{Ô—‡uí±¢¶Q-ŒK¿œ íüØÆøÆÌØvßn{Ø¿7ÝùäÙ4Ò^Û«,¸ É &„ôu¯i¯mšõÞ,Æ-A ¡Ö6ªKT²Ì³çŽÀ ~Ù: ~µ‚!@Þ˜Ø~eò .yNöíÝgþ{§.ç(Ne\l·€‚¾ˆ«1Ç:ƒtÜŸIÞÙg‹-]BV/î@¨h¯Ð‡BȶaðCVâ|fÓ,™¥ë@!„:2 ~ÈZ4É\:ë,]ê˜Î+´×h wýyg2QrætžƒÉDñPø\=•ç@ÛðtF&ãt¾¼=jj+­ª‚9øËX%!„oéZ² ~È*PJë;žØdé:þŒÂJqIU}›~]É-“TÔ6pvMÖâééëÞK¼Xt×ßõõö“ÓÖ-(*ªÃPpš-kñ¤u kÕw=G<ç|‘ìû)ë>lºÚŠR#˜(%€áÙ$ ~uoþ´cÂwŽ÷hËÜW¿ßòì/Û΄?ìš²6|©³iÈ+ÛË)¥jKׂ%àU½!‹Û±ýŠÛÑ#YþAAÊÒ]»Ò¢årAíG †ÊË­-ÿ%¾/›ÍgÍîs4"Ò­Ö¼ÌÂOEÅŸÉḭ̈ˆqøðNç^z¥gšylË?ÉkVŸïËb3Ægž:Ñr[o¿¹³ï€~™#FlÝ’â~òDŽß·‹Fk­¶%?œ =z8+Üh4± ò¿8kvŸËësxPެ:ïWšQ©ÊøM)‡³»Ù»JÊŸúnÄÁ+ÇrœŽ¯¾#”ñƾÛï¸['e5Q²vîÞ˜ÜÄ’@.Ÿ­é5¹Ë™>OvÍi^ßÊsþg6%÷â 8šA/v¿áó\þÂ?C>u. —gµynYvµÃ”…Câ[«mó'‡#®žÎïLB£Æ'<öŸh«¼*¡Ž ÷ø!ÔF™öéÚ‰‡/d:MýdíÄ óÿ˜¶õdŠ{mƒšóÊ¢†Žÿ`õô¿^ôi¹Ìö¸÷'>Z3eäÜ•3Þúig?ƒÑÔ|x)·´Føôçë=oÕ³_¬=Ñr¹•»?ÿó¯5¨µ¬iŸ®Ø Ö²Z«íÈÅ,ÇéŸý5~ÄܕϿ±dÛ &¾ÕyÕ•+eŽûö¦ß²%¹OL¬Wrnn÷Œg7<÷é'‡&* u:#ç?/nzÍ<άý7¬O×)Ä1ÛÍMZþÃ÷'žÿáû“¡Gg9¾÷îž™B·)<Ü%óËÏO1L͇Åâ º¥¦–+ZnûlBA×Öêš=sû€Õ¿Ÿ×)Ø17"Ò=íßÏÿ쓃Qó³xò’JÜã7'N9’Ý-¸¯÷¥üË¥MøëÙ]‹âF{uuÉ®-U)~~nÓ óüŸú{ô…]iƒý»»_Hy æxõÄŸ‰>'Ö\ôùgá‘—¤Ž¢*—@‡Âõìªå¶2â z”fUÛ™Ÿç\,vÏL(èÜZ]K¦m“°%eˆo¤[º[°2gçw'Ÿ>ðs|ÐÃúB·Â=~µ‘F§g%¤ô/©R¹ôéâs6·´ÚùÕ{_ñr¶ÏpWÊJ=”yŸþqðU/'û/cü+œ»ê“êúÎ/»Þèâu¢G´güö¸”¾“>^ã±óË¿·û‡ô/èõ&ÞšµSÿP(D:/OûÚÞßûæ¼÷.yþ…è«ál×.‹¾9w®Ð>*ʽæÐÁŒÇFÙýù—Ããžyj½`ÓßICfÎêüÛ¯ñ}<=eWÿükê'g‰ê«/޼~¯õ &²ooúˆ™³ú¬4ïM4MÌž=éý>øð±söÝ?x€ÌÛýì„!”a3ƽ?žþÏË+Ç>4°´,«úÊ'W,¬+oà ¤|CúɼÃ^ëµjôÛ×öf~1üwÙ‘Uçõy²ëŠãk.öóu>ÿêê'v°¹ GV{æ^ë©È«¤Ì4c阯£Æ4ÕiD§6\ê7ø•éöÝ#„nƒ² „çN1/ÈzNü¾öî³ÿ±½;5±Ïe“‰’.3¾ëi'â×ÿ€¤¬âNÛâR‚cüOüº#¾¿‡£]ÆÚ¦ýàé$«ùdõYÙ%ÕÛÏð¨kÔ(-~ék±€g|elLJä¾ÿê~êùiëé!a¾.çV¼óÄ.€Ç"òƾÿûÂŒÂÊM÷Î.¥RT¨PˆtÝ"Ý*&O ÏàóÙ&‰˜W“x±Héå)kllÔɆ l>Dëvá|Q€Šòepˆc†ylò”𬯿{SÜìrC(€Gg§J6Õ>4°ÀÉOÞÄb3ºìsE| Oo2š8±S»4f¾Qniçw¤ ¨¯ltŒÙéˆy¬ûã!GVÝ{î½z*ß(¿çxzÃPÊ &.OÈQýë7‹j3 ~ÈZ4É\:‹ÛcCcb;g0 ¡v"~e¸¿k¶yÌÑ^\QXQçPQÛàîïšl›< kÎÂ5‡ô‰EŠÌ¢J¥“½$ϼ÷NÈç]Òì›·Õåµ ®…u¼è——RJ ¥@X 1\Î.‘?JÁÒÎríˆ8—Ëny;J)…HÏb1úÔ+åŠ~ýý*²²ª”<[ pÔååÍ-D/ÛSJ›OkáòXÚ•®ùªÝ’âúVÛxzÉš€.øtèïÆ•< ·ÙnCn»-?ß–žvÙŠäîvE•ùµJ.ÿÚçÉåsÔ5->£¼K%-—gsXÚ¦: Ïü¼®¼¡ÕÏSîn×èkNZææ\¿ïëßÒª*˜ãë_T95”R¼_/²9x޲ íÙÎ…Ãbn¸¡.‹aZý…*àqšÊjšI&ç”J F×Q&n²ñÕõMš~AÖ6¨›ç y­Vghþeš˜Y|Û^hB§¡w˜÷‰„_Þøüìò™ Ïý:ó³´5ïÌß7Ì*ïqÊ0„úøÊSvîLíQYÙÈMO¯ÇÅåFwê¤LˆŒrO½š^’x±X¦Ó™¿%Ķ\>8Ø)ãlBAgƒÁD2®VŠÏ&´zΞ““DëåeŸöÓ²SCJJ®µÙ1LäØÑ,å×íGée¯¶w‘dûý|Œ¦AËÊ>W$˽Páî’àÕÅùJîÅ’ð’«•bMƒ–ufcrÏ–Ë;8d$Î ¥&Jr.Ëò/—µz¾d§X¯*‰ƒ°dӂê›8Ú&=+õD®¢µù ¥F0hÕ,Àv.ÈFaðCè!‰ òHNÏ/OÍ—ktæûM'úËÄ‚Òè`ÏêÑ1!™M½ô·×Nl_µûl@]ƒÆÉ¼ìîùåµE•uüµ–µj÷ÙÞwØNR\rnï3Wòšƒãá ™N·›o >û|Øæêê&eÿ>?2vôœ¦¯¾¹àýùƒÎzzɲ&?ñçG=»ÿ8ß`0²¹\VsëŽéOu»ØÐ •D„/þì‰ Ìõ÷w¸íU¥ß-½¶¡A+îßç—/zõXúNDøâÏþøý|›Zî;x—Ã2…ùºÔM{¬Ûºo×{ù—í§«\N“·³ýó²#üË=”—†¾õÛÇ Ãb:{¼Ýv>qø‰¾QÙ?óùúùvbA¹Þ`ä xœ†S¯}Ó>ïôß›ûsßpÑü< PÑ™óîk-眽0s¡ùqT”{Í©3¯}“qµR̰²æ_âl6C·nöÏÜÜšDBŽAé(ÖÀ&óxžÕGO¼²$ãj¥ØÏß¡‘¹~€L&зÜn×n®µ‡¾¼¬¢¼›S-v¬—Jù†‡ð²ÓÉîÝÝ‹Êòýå§Ó3:wvújÈõÛ•¡{ãànW;bVïÍ /™*åp–×ÑÿžŸîæ\Ösbh¥kCÝ; ~Y‡Í2õ ñJ ÷sÝ3wù®w,]5ùkýôæž}ýúûU$$ä‡ýñû¹˜!Cÿ±d]ª‘sz7ßv0¸weÊ‘ìÈsÛ¯tÁà‡Ð£ ÏñCÈ|]äMŸÌzfxNE–®Åš &R]Õ¤tr–TYº–GYE^àÂÎ4×uóöõ¬-UyDëœdéšB÷÷øˆÈÊ®IDAT!«@q é÷ª]ôد° jöÊKÿ 7™(룃ã,]Ë£ìøê‹Á§7^ÑX«vêÜßw_øÐÀKׄº?¸ÇY ÐÎÛ¹ foÎÞÑ/!>¿×ÒŸÇýô(Üf­#›ðáÀ ß^žùÙžŸW˜R²êÕmC,]ÓýÒª*˜C+&;Bø–®!KÀà‡¬¥´6´ÿllç‚`îÛ»z<1øÇe/éÑÃÓêoµÖ^Ü:)|"\ RÊ;Yº–ûE©ôêàï?d£ð!dUÞŸ·'fÏî´áß/»¤o?ß K×ó¨;ý÷eOóãœ Å²Ìø‚h¹›ô‘=7•/u6 {})¥ôŽ÷rFÈZá9~YÈûÎûiõ6À‘‹™ÞéöÓë–Åç²M–®íQ¶kgêð¦&½Ý‹ÏoüÐüš¿¿"iï~³d]ª>;üÔºyû¤l.K£Viå.Фç—ÙnéºB÷ƒB²zß¹¡ƒ‰ã¦°Ë8p.#`htàr7…ÞFê_H¼hïíZ³ò<çó¡Öù}j¢À ŠK×µ!”RK×€ÐñÜâFWK×€êøL`lZ=[Zké:²¼¸!„BÈF`ðCVÛ¹ „Bw‡ÁY O$Çv.¡;Ò6U1ÇV?kí\­Â‹;U ”Ö<·¸Q`é:B5衱¶€ØÎÙ(Üã‡BÈf˜Û¹PJ± ²IüB!„l?„B!Á!„BÈF`ðCV¢8¿ëClç‚BÝ?d-LlŽÈdé"B¶sA¶Û¹ «@)­~nq#ßÒu „:6“N 5yÀv.ÈFá?„B6C s7œu¤Û¹ […Á!„BÈF`ðC!„²üB!„l?d!w/Xº„B¨#Ãà‡¬aáEê¡;Ó©kÉñµ/È!\Kׂ%àoJd(¥UÏ-nľ\¡;2jˆªìª8 ³t=µ7Üã‡BÈfdsŽQJ-] B–€Á!„BÈF`ðC!„²üB!„l?d° B!twüÕÀv.¡»Ñ©kIÜ_ÿ±Ãv.ÈVáoJd° B¨-ŒÚR]’"€JÀv.Èá?„B6C s7~3®Û¹ […Á!„BÈF`ðC!„²üB!„l?d!‰ûb;„Bè0ø!«AK—€êà° ²uØÎYlç‚j lç‚lîñC!d3° ²uüB!„l?„B!Á!„BÈF`ðCV"OÚÿ•ØÒu „B?d-ƒ¾¿ŸBw¤S×’Óë_“b;d«° ² ”ÒÊç7âr„Ði5u¤²à‚T¶sA6÷ „²{/Óè·OPJ,] B–€Á!„BÈF`ðC!„²üB!„l?d° B!twüµÀv.¡»ÒiêÉ™M³%ØÎý;÷ÒDpünnn·s³©Yºþ(&id¡%E%EEB õ""_ôBzå«^TjÚ¤à ( }!á¡|±YS›ÔTD]›yËyêÔmº9—·æn¦[/|Ó¼§ØõÒû}Þ~ùÝqpÏ#Vpœ Øà8@<Â!?îïÑ`æÇà8 Bð‡€h¨4ÚÈùÊÞ)8Έ,üD~" ?‘€…Øp×X;ž’¨f35î±nªÙ{ ×÷N䦱¾&Âe3nL³ÂIëÑm Y15¬“£ÚÄ`‹ÂamÜ&‡Zå“_[Ñík«|rHxsXÛäƒ- T›ÖÉ™fÁÍIë™~tsÙ ‰c}M²}ïL´÷6 nî±n™ÍÔ€lÞñ^™íËkåµÏ/‘m~zPJ)ä;O‹Føû œÃRÚH‘‘e_ßçFh#E.s¬ Æzì ´‘"ÃK>Þ÷Ÿõ2k-àÔ~‡„6R$ÇÎòÇÎJh#EüA-ðJh#E²^&×–|kÍcçµeŽÅi#E.Îüµy¯ °«lÊ)ËûPá™Ê…õÁúññޤTm(óN¯™?ÖjIÕ6.kï)D{”Iiá¬üÓ‚ÚP{M&¡Lý¥-8ÇŸÓ×m—*È•]ûËø­½f»$XÝ]xA`«ÎÀp<š}ð2â~5[±hÏ.ØtÕ["«!iNñUÄóÝO_ႲÜC×5³®fshÉ'Ë-AÌ餅‚ó²=Gn æªRƒ—<ïh¹°¦¯JùésùÇn:×·ý=MÀÃ(óßâÍý« ~x¸éÇì72ÿÄí™õÍò¡Zí6« NVL iVÕÇѧÚYxa&)EmuI³&UFV‘3-§$sMÃ3Òe7¨ M–;ûÀÅ•x›µû™rfX§–*“Üy%å1mô E0æwꨛÛWZ±o³~¥°¼M^áXOaÙÝpLëy#éiH±noñ¥Z.Þ6bnI´vÕ'ýÌüáËÏC1sßÚ¤–®úä/í;~åÅÒŸmrô“ÔÒU¿i~ƲPz½!ˆjêôœU ;‹ F¿f‘1¥EtåIEND®B`‚openchange-2.0/mapiproxy/documentation/pictures/userdoc.png000066400000000000000000000022531223057412600243770ustar00rootroot00000000000000‰PNG  IHDRàw=ørIDATH‰•VßkGÿÌìÌÎÞÞ®wIËÙ*6F¤9é¯C@_$-m BñMh}ÊS¥¥P(¥¥–úô¡‹}ðMTˆ‚Ô¶&Zc ˜ÄR/ôõÎÜÝÞîÎìLtLrV?°/ßa>ŸÏw¾?X‚ÿÁÜÜÓZÇñ”1æCù›sþ=¥ôÇC‡é§Ý'ý®]»FÇ)DQtN1^©Tàº. Óé Ñh I’sBˆGGGe?º]pff†0ÆhEß …ñ½{÷¢X,‚B|ßǾ}û „˜ìõz_>-ƒm”RĶíá8Ž?ÚµkÙš(¥»wïFÇŸ\½zµò\iš"Žã Çq缯;ÇqÀ9Q?³À™3gHÇDkýJ_æ­††ú±ÍcÇŽéùóçÎ9Œ1RBJ cÌ#W”‚1Î9¢(B’$­gȆáïI’@J ¥”RH’`Û6@k à8Îýx¶­Ácüš$ÉòÊÊJN–e`Œ!KKKPJÍ=ztî¹<Ïs]×ýeaa>çœs0ÆÀCX\\D±X¼réÒ¥W/_¾¼íLm NOO¿†á§Œ±w|ßçÝnkkk¨V«Ø³g`uu·o߯þýûáû>Â0ÄÆÆFCñC¡PøöðáÃÛ \¸pá+˲>&ùsܽ{7oÞDǵg­VÃÐÐP>#RJÜ»wõz}©T*ÕŸ¸xñ⇄Ÿkµ,ËÊE1ÐZ#Ill<2¶cÇŽü©6a½^Ç;w¦'''ßËfggÙúúúâÁƒ‡³}ó<0Æ MSB@)ÅÌÌ (¥£³laa1ÆŽ$I2ìº.Œ1y·d»çiÄYv½^”R¸®‹;wbmmí€YV©T^X^^/‹R"Š"h­ÁƒeY°,k‹PFœÍG†PJR B<ÏCEoKÓ´·¾¾þúÈÈ:ºÝ.Œ1Bä"ÙÅ,;­5Ò4Í )¥ µÎ͸®‹(ŠÞvëÖ­øÁƒopÎÑn·Ñjµ`Û6¤”OgHÓJ)H)‘¦iO’¶mƒ!,Ë*Ÿ={öeÖh4F„n–jð}?ïŒ~üø?yõNŸ>ýAÇßh­_ó<Õj®ë¶í|=o†”qc~~ÍfB(¥V‹ÅâSSS?Û,»S§N½E)}ŸR“RPJ½àEJ)ÏVÈãzIMÿZ–µBùËs…1öÛÉ“'ó_™ÿÒJ:—©Ôy¨IEND®B`‚openchange-2.0/mapiproxy/libmapiproxy.pc.in000066400000000000000000000006241223057412600211660ustar00rootroot00000000000000prefix=@prefix@ exec_prefix=@exec_prefix@ libdir=@libdir@ includedir=@includedir@ datarootdir=@prefix@/share datadir=@datadir@ modulesdir=@modulesdir@/dcerpc_mapiproxy Name: MAPIPROXY Description: MAPI Proxy and Server Module Library Version: @PACKAGE_VERSION@ Libs: -L${libdir} -lmapiproxy Libs.private: @LIBS@ Cflags: -I${includedir} Requires: talloc dcerpc ndr ldb Requires.private: samba-hostconfig openchange-2.0/mapiproxy/libmapiproxy/000077500000000000000000000000001223057412600202335ustar00rootroot00000000000000openchange-2.0/mapiproxy/libmapiproxy/dcesrv_mapiproxy_module.c000066400000000000000000000144261223057412600253510ustar00rootroot00000000000000/* MAPI Proxy OpenChange Project Copyright (C) Julien Kerihuel 2008-2011 This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see . */ #include "mapiproxy/dcesrv_mapiproxy.h" #include "libmapiproxy.h" #include /** \file dcesrv_mapiproxy_module.c \brief mapiproxy modules management */ static struct mp_module { struct mapiproxy_module *mp_module; } *mp_modules = NULL; int num_mp_modules; static struct mapiproxy_module_list *mpm_list = NULL; NTSTATUS mapiproxy_module_push(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx, void *r) { struct mapiproxy_module_list *mpm; const struct ndr_interface_table *table; NTSTATUS status; table = (const struct ndr_interface_table *)dce_call->context->iface->private_data; for (mpm = mpm_list; mpm; mpm = mpm->next) { if (mpm->module->endpoint && ((strcmp(mpm->module->endpoint, "any") == 0) || (table->name && (strcmp(table->name, mpm->module->endpoint) == 0)))) { if (mpm->module->push) { status = mpm->module->push(dce_call, mem_ctx, r); NT_STATUS_NOT_OK_RETURN(status); } } } return NT_STATUS_OK; } NTSTATUS mapiproxy_module_ndr_pull(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx, struct ndr_pull *pull) { struct mapiproxy_module_list *mpm; const struct ndr_interface_table *table; NTSTATUS status; table = (const struct ndr_interface_table *)dce_call->context->iface->private_data; for (mpm = mpm_list; mpm; mpm = mpm->next) { if (mpm->module->endpoint && ((strcmp(mpm->module->endpoint, "any") == 0) || (table->name && (strcmp(table->name, mpm->module->endpoint) == 0)))) { if (mpm->module->ndr_pull) { status = mpm->module->ndr_pull(dce_call, mem_ctx, pull); NT_STATUS_NOT_OK_RETURN(status); } } } return NT_STATUS_OK; } NTSTATUS mapiproxy_module_pull(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx, void *r) { struct mapiproxy_module_list *mpm; const struct ndr_interface_table *table; NTSTATUS status; table = (const struct ndr_interface_table *)dce_call->context->iface->private_data; for (mpm = mpm_list; mpm; mpm = mpm->next) { if (mpm->module->endpoint && ((strcmp(mpm->module->endpoint, "any") == 0) || (table->name && (strcmp(table->name, mpm->module->endpoint) == 0)))) { if (mpm->module->pull) { status = mpm->module->pull(dce_call, mem_ctx, r); NT_STATUS_NOT_OK_RETURN(status); } } } return NT_STATUS_OK; } NTSTATUS mapiproxy_module_dispatch(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx, void *r, struct mapiproxy *mapiproxy) { struct mapiproxy_module_list *mpm; const struct ndr_interface_table *table; NTSTATUS status; table = (const struct ndr_interface_table *)dce_call->context->iface->private_data; for (mpm = mpm_list; mpm; mpm = mpm->next) { if (mpm->module->endpoint && ((strcmp(mpm->module->endpoint, "any") == 0) || (table->name && (strcmp(table->name, mpm->module->endpoint) == 0)))) { if (mpm->module->dispatch) { status = mpm->module->dispatch(dce_call, mem_ctx, r, mapiproxy); NT_STATUS_NOT_OK_RETURN(status); } } } return NT_STATUS_OK; } NTSTATUS mapiproxy_module_unbind(struct server_id server_id, uint32_t context_id) { struct mapiproxy_module_list *mpm; NTSTATUS status; for (mpm = mpm_list; mpm; mpm = mpm->next) { if (mpm->module->unbind) { status = mpm->module->unbind(server_id, context_id); NT_STATUS_NOT_OK_RETURN(status); } } return NT_STATUS_OK; } extern NTSTATUS mapiproxy_module_register(const void *_mp_module) { const struct mapiproxy_module *mp_module = (const struct mapiproxy_module *) _mp_module; mp_modules = realloc_p(mp_modules, struct mp_module, num_mp_modules + 1); if (!mp_modules) { smb_panic("out of memory in mapiproxy_register"); } mp_modules[num_mp_modules].mp_module = (struct mapiproxy_module *) smb_xmemdup(mp_module, sizeof (*mp_module)); mp_modules[num_mp_modules].mp_module->name = smb_xstrdup(mp_module->name); num_mp_modules++; DEBUG(3, ("MAPIPROXY module '%s' registered\n", mp_module->name)); return NT_STATUS_OK; } static NTSTATUS mapiproxy_module_load(struct dcesrv_context *dce_ctx) { char **modules; struct mapiproxy_module_list *module; int i; NTSTATUS status; /* Fetch the module list from smb.conf */ modules = str_list_make(dce_ctx, lpcfg_parm_string(dce_ctx->lp_ctx, NULL, "dcerpc_mapiproxy", "modules"), NULL); /* Add modules to the list */ for (i = 0; modules[i]; i++) { module = talloc_zero(dce_ctx, struct mapiproxy_module_list); module->module = mapiproxy_module_byname(modules[i]); if (module->module) { DLIST_ADD_END(mpm_list, module, struct mapiproxy_module_list *); DEBUG(3, ("MAPIPROXY module '%s' loaded\n", modules[i])); if (module->module->init) { status = module->module->init(dce_ctx); NT_STATUS_NOT_OK_RETURN(status); } } else { DEBUG(0, ("MAPIPROXY module '%s' not found\n", modules[i])); } } for (module = mpm_list; module; module = module->next) { DEBUG(3, ("mapiproxy_module_load '%s' (%s)\n", module->module->name, module->module->description)); } return NT_STATUS_OK; } _PUBLIC_ NTSTATUS mapiproxy_module_init(struct dcesrv_context *dce_ctx) { openchange_plugin_init_fn *mpm; NTSTATUS ret; mpm = load_openchange_plugins(NULL, "dcerpc_mapiproxy"); if (mpm != NULL) { int i; for (i = 0; mpm[i]; i++) { mpm[i](); } } talloc_free(mpm); ret = mapiproxy_module_load(dce_ctx); return ret; } const struct mapiproxy_module *mapiproxy_module_byname(const char *name) { int i; if (!name) return NULL; for (i = 0; i < num_mp_modules; i++) { if (strcmp(mp_modules[i].mp_module->name, name) == 0) { return mp_modules[i].mp_module; } } return NULL; } openchange-2.0/mapiproxy/libmapiproxy/dcesrv_mapiproxy_server.c000066400000000000000000000264071223057412600253740ustar00rootroot00000000000000/* MAPI Proxy OpenChange Project Copyright (C) Julien Kerihuel 2009-2011 This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see . */ #include "mapiproxy/dcesrv_mapiproxy.h" #include "libmapiproxy.h" #include /** \file dcesrv_mapiproxy_server.c \brief mapiproxy server modules management */ static struct server_module { struct mapiproxy_module *server_module; } *server_modules = NULL; int num_server_modules; static struct mapiproxy_module_list *server_list = NULL; static TDB_CONTEXT *emsabp_tdb_ctx = NULL; static void *openchange_ldb_ctx = NULL; NTSTATUS mapiproxy_server_dispatch(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx, void *r, struct mapiproxy *mapiproxy) { struct mapiproxy_module_list *server; const struct ndr_interface_table *table; NTSTATUS status; table = (const struct ndr_interface_table *)dce_call->context->iface->private_data; for (server = server_list; server; server = server->next) { if (server->module->endpoint && table->name && !strcmp(table->name, server->module->endpoint)) { if (server->module->dispatch) { mapiproxy->norelay = true; status = server->module->dispatch(dce_call, mem_ctx, r, mapiproxy); NT_STATUS_NOT_OK_RETURN(status); } } } return NT_STATUS_OK; } NTSTATUS mapiproxy_server_unbind(struct server_id server_id, uint32_t context_id) { struct mapiproxy_module_list *server; NTSTATUS status; for (server = server_list; server; server = server->next) { if (server->module->unbind) { status = server->module->unbind(server_id, context_id); NT_STATUS_NOT_OK_RETURN(status); } } return NT_STATUS_OK; } extern NTSTATUS mapiproxy_server_register(const void *_server_module) { const struct mapiproxy_module *server_module = (const struct mapiproxy_module *) _server_module; server_modules = realloc_p(server_modules, struct server_module, num_server_modules + 1); if (!server_modules) { smb_panic("out of memory in mapiproxy_server_register"); } server_modules[num_server_modules].server_module = (struct mapiproxy_module *) smb_xmemdup(server_module, sizeof (*server_module)); server_modules[num_server_modules].server_module->name = smb_xstrdup(server_module->name); num_server_modules++; DEBUG(3, ("MAPIPROXY server '%s' registered\n", server_module->name)); return NT_STATUS_OK; } _PUBLIC_ bool mapiproxy_server_loaded(const char *endpoint) { struct mapiproxy_module_list *server; if (!endpoint) return false; for (server = server_list; server; server = server->next) { if (server->module->endpoint && !strcmp(endpoint, server->module->endpoint)) { return true; } } return false; } static NTSTATUS mapiproxy_server_overwrite(TALLOC_CTX *mem_ctx, const char *name, const char *endpoint) { struct mapiproxy_module_list *server; struct mapiproxy_module_list *server_load; if (!name) return NT_STATUS_NOT_FOUND; if (!endpoint) return NT_STATUS_NOT_FOUND; /* Step 0. Ensure given module matches with endpoint */ server_load = talloc_zero(mem_ctx, struct mapiproxy_module_list); server_load->module = mapiproxy_server_byname(name); if (!server_load->module) { DEBUG(0, ("MAPIPROXY ERROR: couldn't load server '%s'\n", name)); talloc_free(server_load); return NT_STATUS_NOT_FOUND; } else { if (strcmp(server_load->module->endpoint, endpoint)) { DEBUG(0, ("MAPIPROXY ERROR: %s endpoint expected for %s but %s found!\n", endpoint, server_load->module->name, server_load->module->endpoint)); talloc_free(server_load); return NT_STATUS_NOT_FOUND; } } /* Step 1. Seek if this module has already been loaded */ for (server = server_list; server; server = server->next) { if (!strcmp(server->module->name, name) && !strcmp(server->module->endpoint, endpoint)) { DEBUG(0, ("MAPIPROXY: server '%s' already loaded - skipped\n", name)); talloc_free(server_load); return NT_STATUS_OK; } } /* Step 2. Delete any loaded server matching given endpoint */ for (server = server_list; server; server = server->next) { if (!strcmp(server->module->endpoint, endpoint)) { DLIST_REMOVE(server_list, server); talloc_free(server); } } /* Step 3. Load custom server */ DLIST_ADD_END(server_list, server_load, struct mapiproxy_module_list *); return NT_STATUS_OK; } static NTSTATUS mapiproxy_server_load(struct dcesrv_context *dce_ctx) { NTSTATUS status; struct mapiproxy_module_list *server; bool server_mode; int i; const char *nspi; const char *emsmdb; const char *rfr; const char *server_name[] = { NDR_EXCHANGE_NSP_NAME, NDR_EXCHANGE_EMSMDB_NAME, NDR_EXCHANGE_DS_RFR_NAME, NULL }; /* Check server mode */ server_mode = lpcfg_parm_bool(dce_ctx->lp_ctx, NULL, "dcerpc_mapiproxy", "server", false); DEBUG(0, ("MAPIPROXY server mode %s\n", (server_mode == false) ? "disabled" : "enabled")); if (server_mode == true) { DEBUG(0, ("MAPIPROXY proxy mode disabled\n")); for (i = 0; server_name[i]; i++) { server = talloc_zero(dce_ctx, struct mapiproxy_module_list); server->module = mapiproxy_server_bystatus(server_name[i], MAPIPROXY_DEFAULT); if (server->module) { DLIST_ADD_END(server_list, server, struct mapiproxy_module_list *); } else { DEBUG(0, ("MAPIPROXY ERROR: couldn't load server '%s'\n", server_name[i])); } } } /* Check for override/custom NSPI server */ nspi = lpcfg_parm_string(dce_ctx->lp_ctx, NULL, "dcerpc_mapiproxy", "nspi_server"); mapiproxy_server_overwrite(dce_ctx, nspi, NDR_EXCHANGE_NSP_NAME); /* Check for override/custom EMSMDB server */ emsmdb = lpcfg_parm_string(dce_ctx->lp_ctx, NULL, "dcerpc_mapiproxy", "emsmdb_server"); mapiproxy_server_overwrite(dce_ctx, emsmdb, NDR_EXCHANGE_EMSMDB_NAME); /* Check for override/custom RFR server */ rfr = lpcfg_parm_string(dce_ctx->lp_ctx, NULL, "dcerpc_mapiproxy", "rfr_server"); mapiproxy_server_overwrite(dce_ctx, rfr, NDR_EXCHANGE_DS_RFR_NAME); for (server = server_list; server; server = server->next) { DEBUG(3, ("mapiproxy_server_load '%s' (%s)\n", server->module->name, server->module->description)); if (server->module->init) { status = server->module->init(dce_ctx); NT_STATUS_NOT_OK_RETURN(status); } } return NT_STATUS_OK; } /** \details Initialize mapiproxy servers modules \param dce_ctx pointer to the connection context \return NT_STATUS_OK on success otherwise NT error */ _PUBLIC_ NTSTATUS mapiproxy_server_init(struct dcesrv_context *dce_ctx) { openchange_plugin_init_fn *servers; NTSTATUS ret; servers = load_openchange_plugins(NULL, "dcerpc_mapiproxy_server"); if (servers != NULL) { int i; for (i = 0; servers[i]; i++) { servers[i](); } } talloc_free(servers); ret = mapiproxy_server_load(dce_ctx); return ret; } const struct mapiproxy_module *mapiproxy_server_bystatus(const char *name, enum mapiproxy_status status) { int i; if (!name) return NULL; for (i = 0; i < num_server_modules; i++) { if ((strcmp(server_modules[i].server_module->name, name) == 0) && (server_modules[i].server_module->status == status)) { return server_modules[i].server_module; } } return NULL; } const struct mapiproxy_module *mapiproxy_server_byname(const char *name) { int i; if (!name) return NULL; for (i = 0; i < num_server_modules; i++) { if ((strcmp(server_modules[i].server_module->name, name) == 0)) { return server_modules[i].server_module; } } return NULL; } /** \details Initialize an EMSABP TDB context available to all instances when Samba is not run in single mode. \param lp_ctx pointer to the loadparm context \note TDB database can't be opened twice with O_RDWR flags. We ensure here we have a general context initialized, which we'll reopen within forked instances return Allocated TDB context on success, otherwise NULL */ _PUBLIC_ TDB_CONTEXT *mapiproxy_server_emsabp_tdb_init(struct loadparm_context *lp_ctx) { char *tdb_path; TALLOC_CTX *mem_ctx; if (emsabp_tdb_ctx) return emsabp_tdb_ctx; mem_ctx = talloc_named(NULL, 0, "mapiproxy_server_emsabp_tdb_init"); if (!mem_ctx) return NULL; /* Step 0. Retrieve a TDB context pointer on the emsabp_tdb database */ tdb_path = talloc_asprintf(mem_ctx, "%s/%s", lpcfg_private_dir(lp_ctx), EMSABP_TDB_NAME); emsabp_tdb_ctx = tdb_open(tdb_path, 0, 0, O_RDWR|O_CREAT, 0600); talloc_free(tdb_path); if (!emsabp_tdb_ctx) { DEBUG(3, ("[%s:%d]: %s\n", __FUNCTION__, __LINE__, strerror(errno))); talloc_free(mem_ctx); return NULL; } talloc_free(mem_ctx); return emsabp_tdb_ctx; } /** \details Initialize an openchange LDB context available to all mapiproxy instances. This LDB context points on the OpenChange dispatcher database used within emsmdb default provider. \param lp_ctx pointer to the loadparm context \note The memory context is not free'd leading and causes a loss record. \return Allocated LDB context on success, otherwise NULL */ _PUBLIC_ void *mapiproxy_server_openchange_ldb_init(struct loadparm_context *lp_ctx) { char *ldb_path; TALLOC_CTX *mem_ctx; struct tevent_context *ev; int ret; struct ldb_result *res; struct ldb_dn *tmp_dn = NULL; static const char *attrs[] = { "rootDomainNamingContext", "defaultNamingContext", NULL }; /* Sanity checks */ if (openchange_ldb_ctx) return openchange_ldb_ctx; ev = tevent_context_init(talloc_autofree_context()); if (!ev) return NULL; mem_ctx = talloc_named(NULL, 0, "openchange_ldb_init"); if (!mem_ctx) return NULL; /* Step 0. Retrieve a LDB context pointer on openchange.ldb database */ ldb_path = talloc_asprintf(mem_ctx, "%s/%s", lpcfg_private_dir(lp_ctx), OPENCHANGE_LDB_NAME); openchange_ldb_ctx = ldb_init(mem_ctx, ev); if (!openchange_ldb_ctx) { talloc_free(mem_ctx); return NULL; } /* Step 1. Connect to the database */ ret = ldb_connect((struct ldb_context *)openchange_ldb_ctx, ldb_path, 0, NULL); talloc_free(ldb_path); if (ret != LDB_SUCCESS) { talloc_free(mem_ctx); return NULL; } /* Step 2. Search for the rootDSE record */ ret = ldb_search(openchange_ldb_ctx, mem_ctx, &res, ldb_dn_new(mem_ctx, openchange_ldb_ctx, "@ROOTDSE"), LDB_SCOPE_BASE, attrs, NULL); if (ret != LDB_SUCCESS) { talloc_free(mem_ctx); return NULL; } if (res->count != 1) { talloc_free(mem_ctx); return NULL; } /* Step 3. Set opaque naming */ tmp_dn = ldb_msg_find_attr_as_dn((struct ldb_context *)openchange_ldb_ctx, openchange_ldb_ctx, res->msgs[0], "rootDomainNamingContext"); ldb_set_opaque((struct ldb_context *)openchange_ldb_ctx, "rootDomainNamingContext", tmp_dn); tmp_dn = ldb_msg_find_attr_as_dn((struct ldb_context *)openchange_ldb_ctx, openchange_ldb_ctx, res->msgs[0], "defaultNamingContext"); ldb_set_opaque((struct ldb_context *)openchange_ldb_ctx, "defaultNamingContext", tmp_dn); return openchange_ldb_ctx; } openchange-2.0/mapiproxy/libmapiproxy/dcesrv_mapiproxy_session.c000066400000000000000000000116371223057412600255500ustar00rootroot00000000000000/* MAPI Proxy OpenChange Project Copyright (C) Julien Kerihuel 2008 This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see . */ #include "mapiproxy/dcesrv_mapiproxy.h" #include "libmapiproxy.h" /** \file dcesrv_mapiproxy_session.c \brief session API for mapiproxy modules */ /** \details Create and return an allocated pointer to a mpm session \param mem_ctx pointer to the memory context \param serverid reference to the session context server identifier structure \param context_id reference to the context identifier \return Pointer to an allocated mpm_session structure on success, otherwise NULL */ struct mpm_session *mpm_session_new(TALLOC_CTX *mem_ctx, struct server_id serverid, uint32_t context_id) { struct mpm_session *session = NULL; if (!mem_ctx) return NULL; session = talloc_zero(mem_ctx, struct mpm_session); if (!session) return NULL; session->server_id = serverid; session->context_id = context_id; session->ref_count = 0; session->destructor = NULL; session->private_data = NULL; return session; } /** \details Increment the ref_count associated to a session \param session pointer to the session where to increment ref_count \return true on success, otherwise false */ bool mpm_session_increment_ref_count(struct mpm_session *session) { if (!session) return false; session->ref_count += 1; return true; } /** \details Create and return an allocated pointer to a mpm session \param mem_ctx pointer to the memory context \param dce_call pointer to the session context \return Pointer to an allocated mpm_session structure on success, otherwise NULL */ struct mpm_session *mpm_session_init(TALLOC_CTX *mem_ctx, struct dcesrv_call_state *dce_call) { if (!mem_ctx) return NULL; if (!dce_call) return NULL; if (!dce_call->conn) return NULL; if (!dce_call->context) return NULL; return mpm_session_new(mem_ctx, dce_call->conn->server_id, dce_call->context->context_id); } /** \details Set the mpm session destructor \param session pointer to the mpm session context \param destructor pointer to the destructor function \return true on success, otherwise false */ bool mpm_session_set_destructor(struct mpm_session *session, bool (*destructor)(void *)) { if (!session) return false; if (!destructor) return false; session->destructor = destructor; return true; } /** \details Set the mpm session pointer on private data \param session pointer to the mpm session context \param private_data generic pointer on private data \return true on success, otherwise false */ bool mpm_session_set_private_data(struct mpm_session *session, void *private_data) { if (!session) return false; session->private_data = private_data; return true; } /** \details Release a mapiproxy session context \param session pointer to the mpm session context \return true on success, otherwise false */ bool mpm_session_release(struct mpm_session *session) { bool ret; if (!session) return false; if (session->ref_count) { session->ref_count -= 1; return false; } if (session->destructor) { ret = session->destructor(session->private_data); if (ret == false) return ret; } talloc_free(session); return true; } /** \details Compare the mpm session with the session context one \param session pointer to the mapiproxy module session \param sid reference to a server_id structure to compare \param context_id the connection context id to compare */ bool mpm_session_cmp_sub(struct mpm_session *session, struct server_id sid, uint32_t context_id) { if (!session) return false; if (memcmp(&session->server_id, &sid, sizeof(struct server_id) == 0) && (session->context_id == context_id)) { return true; } return false; } /** \details Compare the mpm session with the session context one This function is a wrapper on mpm_session_cmp_sub \param session pointer to the mapiproxy module session \param dce_call pointer to the session context \return true on success, otherwise false \sa mpm_session_cmp_sub */ bool mpm_session_cmp(struct mpm_session *session, struct dcesrv_call_state *dce_call) { if (!session || !dce_call) return false; return mpm_session_cmp_sub(session, dce_call->conn->server_id, dce_call->context->context_id); } openchange-2.0/mapiproxy/libmapiproxy/entryid.c000066400000000000000000000106671223057412600220670ustar00rootroot00000000000000/* OpenChange Server implementation EMSMDBP: EMSMDB Provider implementation Copyright (C) Julien Kerihuel 2009 This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see . */ /** \file entryid.c \brief EntryID convenient routines */ #include "mapiproxy/dcesrv_mapiproxy.h" #include "libmapiproxy.h" #include "libmapi/libmapi.h" #include "libmapi/libmapi_private.h" /** \details Build an Address Book EntryID from a legacyExchangeDN \param mem_ctx pointer to the memory context \param legacyExchangeDN the string to copy into the binary blob \param bin the binary blob where the function stores results */ _PUBLIC_ enum MAPISTATUS entryid_set_AB_EntryID(TALLOC_CTX *mem_ctx, const char *legacyExchangeDN, struct SBinary_short *bin) { /* Sanity checks */ OPENCHANGE_RETVAL_IF(!legacyExchangeDN, MAPI_E_INVALID_PARAMETER, NULL); OPENCHANGE_RETVAL_IF(!bin, MAPI_E_INVALID_PARAMETER, NULL); bin->cb = 28 + strlen(legacyExchangeDN) + 1; bin->lpb = talloc_array(mem_ctx, uint8_t, bin->cb); /* Fill EntryID: FIXME we should use PermanentEntryID here */ memset(bin->lpb, 0, bin->cb); memcpy(&bin->lpb[4], GUID_NSPI, 16); bin->lpb[20] = 0x1; memcpy(bin->lpb + 28, legacyExchangeDN, strlen(legacyExchangeDN)); return MAPI_E_SUCCESS; } /** \details Build a folder EntryID \param mem_ctx pointer to the memory context \param MailboxGuid pointer to the Mailbox Guid \param ReplGuid pointer to the Replica Guid \param FolderType the type of folder \param fid the folder identifier \param rbin the Binary_r structure where the function stores results \return MAPI_E_SUCCESS on success, otherwise MAPI_E_INVALID_PARAMETER */ _PUBLIC_ enum MAPISTATUS entryid_set_folder_EntryID(TALLOC_CTX *mem_ctx, struct GUID *MailboxGuid, struct GUID *ReplGuid, uint16_t FolderType, uint64_t fid, struct Binary_r **rbin) { struct Binary_r *bin; /* Sanity checks */ OPENCHANGE_RETVAL_IF(!MailboxGuid, MAPI_E_INVALID_PARAMETER, NULL); OPENCHANGE_RETVAL_IF(!ReplGuid, MAPI_E_INVALID_PARAMETER, NULL); bin = talloc_zero(mem_ctx, struct Binary_r); bin->cb = 46; bin->lpb = talloc_array(mem_ctx, uint8_t, bin->cb); /* 4 bytes: EntryID flags set to 0 */ memset(bin->lpb, 0, bin->cb); /* 16 bytes: MailboxGuid */ bin->lpb[4] = (MailboxGuid->time_low & 0xFF); bin->lpb[5] = ((MailboxGuid->time_low >> 8) & 0xFF); bin->lpb[6] = ((MailboxGuid->time_low >> 16) & 0xFF); bin->lpb[7] = ((MailboxGuid->time_low >> 24) & 0xFF); bin->lpb[8] = (MailboxGuid->time_mid & 0xFF); bin->lpb[9] = ((MailboxGuid->time_mid >> 8) & 0xFF); bin->lpb[10] = (MailboxGuid->time_hi_and_version & 0xFF); bin->lpb[11] = ((MailboxGuid->time_hi_and_version >> 8) & 0xFF); memcpy(&bin->lpb[12], MailboxGuid->clock_seq, sizeof (uint8_t) * 2); memcpy(&bin->lpb[14], MailboxGuid->node, sizeof (uint8_t) * 6); /* 2 bytes: FolderType */ bin->lpb[20] = (FolderType & 0xFF); bin->lpb[21] = ((FolderType >> 8) & 0xFF); /* 16 bytes: ReplGuid */ bin->lpb[22] = (ReplGuid->time_low & 0xFF); bin->lpb[23] = ((ReplGuid->time_low >> 8) & 0xFF); bin->lpb[24] = ((ReplGuid->time_low >> 16) & 0xFF); bin->lpb[25] = ((ReplGuid->time_low >> 24) & 0xFF); bin->lpb[26] = (ReplGuid->time_mid & 0xFF); bin->lpb[27] = ((ReplGuid->time_mid >> 8) & 0xFF); bin->lpb[28] = (ReplGuid->time_hi_and_version & 0xFF); bin->lpb[29] = ((ReplGuid->time_hi_and_version >> 8) & 0xFF); memcpy(&bin->lpb[30], ReplGuid->clock_seq, sizeof (uint8_t) * 2); memcpy(&bin->lpb[32], ReplGuid->node, sizeof (uint8_t) * 6); /* 6 bytes: FolderID, first two byte unset */ bin->lpb[38] = ((fid >> 16) & 0xFF); bin->lpb[39] = ((fid >> 24) & 0xFF); bin->lpb[40] = ((fid >> 32) & 0xFF); bin->lpb[41] = ((fid >> 40) & 0xFF); bin->lpb[42] = ((fid >> 48) & 0xFF); bin->lpb[43] = ((fid >> 56) & 0xFF); /* 44 and 45 are zero padding */ *rbin = bin; return MAPI_E_SUCCESS; } openchange-2.0/mapiproxy/libmapiproxy/libmapiproxy.h000066400000000000000000000302611223057412600231250ustar00rootroot00000000000000/* MAPI Proxy OpenChange Project Copyright (C) Julien Kerihuel 2008-2011 This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see . */ #ifndef __LIBMAPIPROXY_H__ #define __LIBMAPIPROXY_H__ #include #include #include #include #include #include #include #include #include #include #include struct mapiproxy { bool norelay; bool ahead; }; enum mapiproxy_status { MAPIPROXY_DEFAULT = 0x0, MAPIPROXY_CUSTOM = 0x1 }; struct mapiproxy_module { enum mapiproxy_status status; const char *name; const char *description; const char *endpoint; NTSTATUS (*init)(struct dcesrv_context *); NTSTATUS (*push)(struct dcesrv_call_state *, TALLOC_CTX *, void *); NTSTATUS (*ndr_pull)(struct dcesrv_call_state *, TALLOC_CTX *, struct ndr_pull *); NTSTATUS (*pull)(struct dcesrv_call_state *, TALLOC_CTX *, void *); NTSTATUS (*dispatch)(struct dcesrv_call_state *, TALLOC_CTX *, void *, struct mapiproxy *); NTSTATUS (*unbind)(struct server_id, uint32_t); }; struct mapiproxy_module_list { const struct mapiproxy_module *module; struct mapiproxy_module_list *prev; struct mapiproxy_module_list *next; }; struct mpm_session { struct server_id server_id; uint32_t context_id; uint32_t ref_count; bool (*destructor)(void *); void *private_data; }; struct auth_serversupplied_info { struct dom_sid *account_sid; struct dom_sid *primary_group_sid; size_t n_domain_groups; struct dom_sid **domain_groups; DATA_BLOB user_session_key; DATA_BLOB lm_session_key; const char *account_name; const char *domain_name; const char *full_name; const char *logon_script; const char *profile_path; const char *home_directory; const char *home_drive; const char *logon_server; NTTIME last_logon; NTTIME last_logoff; NTTIME acct_expiry; NTTIME last_password_change; NTTIME allow_password_change; NTTIME force_password_change; uint16_t logon_count; uint16_t bad_password_count; uint32_t acct_flags; bool authenticated; }; struct mapi_handles { uint32_t handle; uint32_t parent_handle; void *private_data; struct mapi_handles *prev; struct mapi_handles *next; }; struct mapi_handles_context { TDB_CONTEXT *tdb_ctx; uint32_t last_handle; struct mapi_handles *handles; }; struct openchangedb_table { uint64_t folderID; uint8_t table_type; struct SSortOrderSet *lpSortCriteria; struct mapi_SRestriction *restrictions; struct ldb_result *res; }; enum openchangedb_message_status { OPENCHANGEDB_MESSAGE_CREATE = 0x1, OPENCHANGEDB_MESSAGE_OPEN = 0x2 }; struct openchangedb_message { enum openchangedb_message_status status; uint64_t messageID; uint64_t folderID; void *ldb_ctx; struct ldb_message *msg; struct ldb_result *res; }; #define MAPI_HANDLES_RESERVED 0xFFFFFFFF #define MAPI_HANDLES_ROOT "root" #define MAPI_HANDLES_NULL "null" /** EMSABP server defines */ #define EMSABP_TDB_NAME "emsabp_tdb.tdb" /** Represents the NSPI Protocol in Permanent Entry IDs. */ static const uint8_t GUID_NSPI[] = { 0xDC, 0xA7, 0x40, 0xC8, 0xC0, 0x42, 0x10, 0x1A, 0xB4, 0xB9, 0x08, 0x00, 0x2B, 0x2F, 0xE1, 0x82 }; #define OPENCHANGE_LDB_NAME "openchange.ldb" #ifndef __BEGIN_DECLS #ifdef __cplusplus #define __BEGIN_DECLS extern "C" { #define __END_DECLS } #else #define __BEGIN_DECLS #define __END_DECLS #endif #endif __BEGIN_DECLS /* definitions from dcesrv_mapiproxy_module.c */ NTSTATUS mapiproxy_module_register(const void *); NTSTATUS mapiproxy_module_init(struct dcesrv_context *); NTSTATUS mapiproxy_module_push(struct dcesrv_call_state *, TALLOC_CTX *, void *); NTSTATUS mapiproxy_module_pull(struct dcesrv_call_state *, TALLOC_CTX *, void *); NTSTATUS mapiproxy_module_ndr_pull(struct dcesrv_call_state *, TALLOC_CTX *, struct ndr_pull *); NTSTATUS mapiproxy_module_dispatch(struct dcesrv_call_state *, TALLOC_CTX *, void *, struct mapiproxy *); NTSTATUS mapiproxy_module_unbind(struct server_id, uint32_t); const struct mapiproxy_module *mapiproxy_module_byname(const char *); /* definitions from dcesrv_mapiproxy_server.c */ NTSTATUS mapiproxy_server_register(const void *); NTSTATUS mapiproxy_server_init(struct dcesrv_context *); NTSTATUS mapiproxy_server_unbind(struct server_id, uint32_t); NTSTATUS mapiproxy_server_dispatch(struct dcesrv_call_state *, TALLOC_CTX *, void *, struct mapiproxy *); bool mapiproxy_server_loaded(const char *); const struct mapiproxy_module *mapiproxy_server_bystatus(const char *, enum mapiproxy_status); const struct mapiproxy_module *mapiproxy_server_byname(const char *); TDB_CONTEXT *mapiproxy_server_emsabp_tdb_init(struct loadparm_context *); void *mapiproxy_server_openchange_ldb_init(struct loadparm_context *); /* definitions from dcesrv_mapiproxy_session. c */ struct mpm_session *mpm_session_new(TALLOC_CTX *, struct server_id, uint32_t); struct mpm_session *mpm_session_init(TALLOC_CTX *, struct dcesrv_call_state *); bool mpm_session_increment_ref_count(struct mpm_session *); bool mpm_session_set_destructor(struct mpm_session *, bool (*destructor)(void *)); bool mpm_session_set_private_data(struct mpm_session *, void *); bool mpm_session_release(struct mpm_session *); bool mpm_session_cmp_sub(struct mpm_session *, struct server_id, uint32_t); bool mpm_session_cmp(struct mpm_session *, struct dcesrv_call_state *); /* definitions from openchangedb.c */ enum MAPISTATUS openchangedb_get_new_folderID(struct ldb_context *, uint64_t *); enum MAPISTATUS openchangedb_get_new_folderIDs(struct ldb_context *, TALLOC_CTX *, uint64_t, struct UI8Array_r **); enum MAPISTATUS openchangedb_get_new_changeNumber(struct ldb_context *, uint64_t *); enum MAPISTATUS openchangedb_get_new_changeNumbers(struct ldb_context *, TALLOC_CTX *, uint64_t, struct UI8Array_r **); enum MAPISTATUS openchangedb_get_next_changeNumber(struct ldb_context *, uint64_t *); enum MAPISTATUS openchangedb_reserve_fmid_range(struct ldb_context *, uint64_t, uint64_t *); enum MAPISTATUS openchangedb_get_SystemFolderID(struct ldb_context *, const char *, uint32_t, uint64_t *); enum MAPISTATUS openchangedb_get_PublicFolderID(struct ldb_context *, uint32_t, uint64_t *); enum MAPISTATUS openchangedb_get_distinguishedName(TALLOC_CTX *, struct ldb_context *, uint64_t, char **); enum MAPISTATUS openchangedb_get_mailboxDN(TALLOC_CTX *, struct ldb_context *, uint64_t, char **); enum MAPISTATUS openchangedb_get_MailboxGuid(struct ldb_context *, const char *, struct GUID *); enum MAPISTATUS openchangedb_get_MailboxReplica(struct ldb_context *, const char *, uint16_t *, struct GUID *); enum MAPISTATUS openchangedb_get_PublicFolderReplica(struct ldb_context *, uint16_t *, struct GUID *); enum MAPISTATUS openchangedb_get_parent_fid(struct ldb_context *, uint64_t, uint64_t *, bool); enum MAPISTATUS openchangedb_get_MAPIStoreURIs(struct ldb_context *, const char *, TALLOC_CTX *, struct StringArrayW_r **); enum MAPISTATUS openchangedb_get_mapistoreURI(TALLOC_CTX *, struct ldb_context *, uint64_t, char **, bool); enum MAPISTATUS openchangedb_set_mapistoreURI(struct ldb_context *, uint64_t, const char *, bool); enum MAPISTATUS openchangedb_get_fid(struct ldb_context *, const char *, uint64_t *); enum MAPISTATUS openchangedb_get_ReceiveFolder(TALLOC_CTX *, struct ldb_context *, const char *, const char *, uint64_t *, const char **); enum MAPISTATUS openchangedb_get_TransportFolder(struct ldb_context *, const char *, uint64_t *); enum MAPISTATUS openchangedb_lookup_folder_property(struct ldb_context *, uint32_t, uint64_t); enum MAPISTATUS openchangedb_set_folder_properties(struct ldb_context *, uint64_t, struct SRow *); char *openchangedb_set_folder_property_data(TALLOC_CTX *, struct SPropValue *); enum MAPISTATUS openchangedb_get_folder_property(TALLOC_CTX *, struct ldb_context *, uint32_t, uint64_t, void **); enum MAPISTATUS openchangedb_get_folder_count(struct ldb_context *, uint64_t, uint32_t *); enum MAPISTATUS openchangedb_get_message_count(struct ldb_context *, uint64_t, uint32_t *, bool); enum MAPISTATUS openchangedb_get_system_idx(struct ldb_context *, uint64_t, int *); enum MAPISTATUS openchangedb_get_table_property(TALLOC_CTX *, struct ldb_context *, const char *, uint32_t, uint32_t, void **); enum MAPISTATUS openchangedb_get_fid_by_name(struct ldb_context *, uint64_t, const char*, uint64_t *); enum MAPISTATUS openchangedb_get_mid_by_subject(struct ldb_context *, uint64_t, const char *, bool, uint64_t *); enum MAPISTATUS openchangedb_set_ReceiveFolder(struct ldb_context *, const char *, const char *, uint64_t); enum MAPISTATUS openchangedb_create_mailbox(struct ldb_context *, const char *, int, uint64_t *); enum MAPISTATUS openchangedb_create_folder(struct ldb_context *, uint64_t, uint64_t, uint64_t, const char *, int); enum MAPISTATUS openchangedb_delete_folder(struct ldb_context *, uint64_t); enum MAPISTATUS openchangedb_get_fid_from_partial_uri(struct ldb_context *, const char *, uint64_t *); enum MAPISTATUS openchangedb_get_users_from_partial_uri(TALLOC_CTX *, struct ldb_context *, const char *, uint32_t *, char ***, char ***); void *openchangedb_get_special_property(TALLOC_CTX *, struct ldb_context *, struct ldb_result *, uint32_t, const char *); void *openchangedb_get_property_data(TALLOC_CTX *, struct ldb_result *, uint32_t, uint32_t, const char *); void *openchangedb_get_property_data_message(TALLOC_CTX *, struct ldb_message *, uint32_t, const char *); /* definitions from openchangedb_table.c */ enum MAPISTATUS openchangedb_table_init(TALLOC_CTX *, uint8_t, uint64_t, void **); enum MAPISTATUS openchangedb_table_set_sort_order(void *, struct SSortOrderSet *); enum MAPISTATUS openchangedb_table_set_restrictions(void *, struct mapi_SRestriction *); enum MAPISTATUS openchangedb_table_get_property(TALLOC_CTX *, void *, struct ldb_context *, enum MAPITAGS, uint32_t, bool live_filtered, void **); /* definitions from openchangedb_message.c */ enum MAPISTATUS openchangedb_message_open(TALLOC_CTX *, struct ldb_context *, uint64_t, uint64_t, void **, void **); enum MAPISTATUS openchangedb_message_create(TALLOC_CTX *, struct ldb_context *, uint64_t, uint64_t, bool, void **); enum MAPISTATUS openchangedb_message_save(void *, uint8_t); enum MAPISTATUS openchangedb_message_get_property(TALLOC_CTX *, void *, uint32_t, void **); enum MAPISTATUS openchangedb_message_set_properties(TALLOC_CTX *, void *, struct SRow *); /* definitions from auto-generated openchangedb_property.c */ const char *openchangedb_property_get_attribute(uint32_t); /* definitions from mapi_handles.c */ struct mapi_handles_context *mapi_handles_init(TALLOC_CTX *); enum MAPISTATUS mapi_handles_release(struct mapi_handles_context *); enum MAPISTATUS mapi_handles_search(struct mapi_handles_context *, uint32_t, struct mapi_handles **); enum MAPISTATUS mapi_handles_add(struct mapi_handles_context *, uint32_t, struct mapi_handles **); enum MAPISTATUS mapi_handles_delete(struct mapi_handles_context *, uint32_t); enum MAPISTATUS mapi_handles_get_private_data(struct mapi_handles *, void **); enum MAPISTATUS mapi_handles_set_private_data(struct mapi_handles *, void *); enum MAPISTATUS mapi_handles_get_systemfolder(struct mapi_handles *, int *); enum MAPISTATUS mapi_handles_set_systemfolder(struct mapi_handles *, int); /* definitions from entryid.c */ enum MAPISTATUS entryid_set_AB_EntryID(TALLOC_CTX *, const char *, struct SBinary_short *); enum MAPISTATUS entryid_set_folder_EntryID(TALLOC_CTX *, struct GUID *, struct GUID *, uint16_t, uint64_t, struct Binary_r **); /* definitions from modules.c */ typedef NTSTATUS (*openchange_plugin_init_fn) (void); openchange_plugin_init_fn *load_openchange_plugins(TALLOC_CTX *mem_ctx, const char *path); __END_DECLS #endif /* ! __LIBMAPIPROXY_H__ */ openchange-2.0/mapiproxy/libmapiproxy/mapi_handles.c000066400000000000000000000366321223057412600230350ustar00rootroot00000000000000/* OpenChange Server implementation MAPI handles API implementation Copyright (C) Julien Kerihuel 2009 This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see . */ /** \file mapi_handles.c \brief API for MAPI handles management */ #include "mapiproxy/dcesrv_mapiproxy.h" #include "libmapi/libmapi.h" #include "libmapi/libmapi_private.h" #include "libmapiproxy.h" /** \details Initialize MAPI handles context \param mem_ctx pointer to the memory context \return Allocated MAPI handles context on success, otherwise NULL */ _PUBLIC_ struct mapi_handles_context *mapi_handles_init(TALLOC_CTX *mem_ctx) { struct mapi_handles_context *handles_ctx; /* Step 1. Initialize the context */ handles_ctx = talloc_zero(mem_ctx, struct mapi_handles_context); if (!handles_ctx) return NULL; /* Step 2. Initialize the TDB context */ handles_ctx->tdb_ctx = tdb_open(NULL, 0, TDB_INTERNAL, O_RDWR|O_CREAT, 0600); /* Step 3. Initialize the handles list */ handles_ctx->handles = NULL; /* Step 4. Set last_handle to the first valid value */ handles_ctx->last_handle = 1; return handles_ctx; } /** \details Release MAPI handles context \param handles_ctx pointer to the MAPI handles context \return MAPI_E_SUCCESS on success, otherwise MAPI error */ _PUBLIC_ enum MAPISTATUS mapi_handles_release(struct mapi_handles_context *handles_ctx) { /* Sanity checks */ OPENCHANGE_RETVAL_IF(!handles_ctx, MAPI_E_NOT_INITIALIZED, NULL); tdb_close(handles_ctx->tdb_ctx); talloc_free(handles_ctx); return MAPI_E_SUCCESS; } /** \details Search for a record in the TDB database \param handles_ctx pointer to the MAPI handles context \param handle MAPI handle to lookup \param rec pointer to the MAPI handle structure the function returns \return MAPI_E_SUCCESS on success, otherwise MAPI error */ _PUBLIC_ enum MAPISTATUS mapi_handles_search(struct mapi_handles_context *handles_ctx, uint32_t handle, struct mapi_handles **rec) { TALLOC_CTX *mem_ctx; TDB_DATA key; TDB_DATA dbuf; struct mapi_handles *el; /* Sanity checks */ OPENCHANGE_RETVAL_IF(!handles_ctx, MAPI_E_NOT_INITIALIZED, NULL); OPENCHANGE_RETVAL_IF(!handles_ctx->tdb_ctx, MAPI_E_NOT_INITIALIZED, NULL); OPENCHANGE_RETVAL_IF(handle == MAPI_HANDLES_RESERVED, MAPI_E_INVALID_PARAMETER, NULL); OPENCHANGE_RETVAL_IF(!rec, MAPI_E_INVALID_PARAMETER, NULL); mem_ctx = talloc_named(NULL, 0, "mapi_handles_search"); /* Step 1. Search for the handle within TDB database */ key.dptr = (unsigned char *) talloc_asprintf(mem_ctx, "0x%x", handle); key.dsize = strlen((const char *)key.dptr); dbuf = tdb_fetch(handles_ctx->tdb_ctx, key); talloc_free(key.dptr); OPENCHANGE_RETVAL_IF(!dbuf.dptr, MAPI_E_NOT_FOUND, mem_ctx); OPENCHANGE_RETVAL_IF(!dbuf.dsize, MAPI_E_NOT_FOUND, mem_ctx); talloc_free(mem_ctx); /* Ensure this is not a free'd record */ if (dbuf.dsize == (sizeof(MAPI_HANDLES_NULL) - 1) && !strncmp((char *)dbuf.dptr, MAPI_HANDLES_NULL, dbuf.dsize)) { free(dbuf.dptr); return MAPI_E_NOT_FOUND; } free(dbuf.dptr); /* Step 2. Return the record within the double chained list */ for (el = handles_ctx->handles; el; el = el->next) { if (el->handle == handle) { *rec = el; return MAPI_E_SUCCESS; } } return MAPI_E_CORRUPT_STORE; } /** \details Set a TDB record data as null meaning it can be reused in the future. \param handles_ctx pointer to the MAPI handles context \param handle handle key value to free \return MAPI_E_SUCCESS on success, otherwise MAPI error */ static enum MAPISTATUS mapi_handles_tdb_free(struct mapi_handles_context *handles_ctx, uint32_t handle) { TALLOC_CTX *mem_ctx; TDB_DATA key; TDB_DATA dbuf; int ret; /* Sanity checks */ OPENCHANGE_RETVAL_IF(!handles_ctx, MAPI_E_NOT_INITIALIZED, NULL); OPENCHANGE_RETVAL_IF(!handles_ctx->tdb_ctx, MAPI_E_NOT_INITIALIZED, NULL); OPENCHANGE_RETVAL_IF(handle == MAPI_HANDLES_RESERVED, MAPI_E_INVALID_PARAMETER, NULL); mem_ctx = talloc_named(NULL, 0, "mapi_handles_tdb_free"); key.dptr = (unsigned char *) talloc_asprintf(mem_ctx, "0x%x", handle); key.dsize = strlen((const char *)key.dptr); /* Step 1. Makes sure the record exists */ ret = tdb_exists(handles_ctx->tdb_ctx, key); OPENCHANGE_RETVAL_IF(!ret, MAPI_E_NOT_FOUND, mem_ctx); /* Step 2. Update existing record */ dbuf.dptr = (unsigned char *)MAPI_HANDLES_NULL; dbuf.dsize = sizeof(MAPI_HANDLES_NULL) - 1; ret = tdb_store(handles_ctx->tdb_ctx, key, dbuf, TDB_MODIFY); talloc_free(mem_ctx); if (ret == -1) { DEBUG(3, ("[%s:%d]: Unable to create 0x%x record: %s\n", __FUNCTION__, __LINE__, handle, tdb_errorstr(handles_ctx->tdb_ctx))); return MAPI_E_CORRUPT_STORE; } return MAPI_E_SUCCESS; } /** \details Update a TDB record */ static enum MAPISTATUS mapi_handles_tdb_update(struct mapi_handles_context *handles_ctx, uint32_t handle, uint32_t container_handle) { TALLOC_CTX *mem_ctx; TDB_DATA key; TDB_DATA dbuf; int ret; /* Sanity checks */ OPENCHANGE_RETVAL_IF(!handles_ctx, MAPI_E_NOT_INITIALIZED, NULL); OPENCHANGE_RETVAL_IF(!handles_ctx->tdb_ctx, MAPI_E_NOT_INITIALIZED, NULL); OPENCHANGE_RETVAL_IF(!handle, MAPI_E_INVALID_PARAMETER, NULL); mem_ctx = talloc_named(NULL, 0, "mapi_handles_tdb_update"); key.dptr = (unsigned char *) talloc_asprintf(mem_ctx, "0x%x", handle); key.dsize = strlen((const char *)key.dptr); /* Step 1. Makes sure the record exists */ ret = tdb_exists(handles_ctx->tdb_ctx, key); OPENCHANGE_RETVAL_IF(!ret, MAPI_E_NOT_FOUND, mem_ctx); /* Step 2. Update record */ dbuf.dptr = (unsigned char *) talloc_asprintf(mem_ctx, "0x%x", container_handle); dbuf.dsize = strlen((const char *)dbuf.dptr); ret = tdb_store(handles_ctx->tdb_ctx, key, dbuf, TDB_MODIFY); talloc_free(mem_ctx); if (ret == -1) { DEBUG(3, ("[%s:%d]: Unable to update 0x%x record: %s\n", __FUNCTION__, __LINE__, handle, tdb_errorstr(handles_ctx->tdb_ctx))); return MAPI_E_CORRUPT_STORE; } return MAPI_E_SUCCESS; } /** \details Traverse TDB database and search for the first record which dbuf value is "null" string. \param tdb_ctx pointer to the TDB context \param key the current TDB key \param dbuf the current TDB value \param state pointer on private data \return 1 when a free record is found, otherwise 0 */ static int mapi_handles_traverse_null(TDB_CONTEXT *tdb_ctx, TDB_DATA key, TDB_DATA dbuf, void *state) { TALLOC_CTX *mem_ctx; uint32_t *handle = (uint32_t *) state; char *handle_str = NULL; if (dbuf.dptr && (dbuf.dsize == sizeof(MAPI_HANDLES_NULL) - 1) && strncmp((const char *)dbuf.dptr, MAPI_HANDLES_NULL, dbuf.dsize) == 0) { mem_ctx = talloc_named(NULL, 0, "mapi_handles_traverse_null"); handle_str = talloc_strndup(mem_ctx, (char *)key.dptr, key.dsize); *handle = strtol((const char *) handle_str, NULL, 16); talloc_free(mem_ctx); return 1; } return 0; } /** \details Add a handles to the database and return a pointer on created record \param handles_ctx pointer to the MAPI handles context \param container_handle the container handle if available \param rec pointer on pointer to the MAPI handle structure the function returns \return MAPI_E_SUCCESS on success, otherwise MAPI error */ _PUBLIC_ enum MAPISTATUS mapi_handles_add(struct mapi_handles_context *handles_ctx, uint32_t container_handle, struct mapi_handles **rec) { TALLOC_CTX *mem_ctx; enum MAPISTATUS retval; TDB_DATA key; TDB_DATA dbuf; uint32_t handle = 0; struct mapi_handles *el; int ret; /* Sanity checks */ OPENCHANGE_RETVAL_IF(!handles_ctx, MAPI_E_NOT_INITIALIZED, NULL); OPENCHANGE_RETVAL_IF(!handles_ctx->tdb_ctx, MAPI_E_NOT_INITIALIZED, NULL); OPENCHANGE_RETVAL_IF(handle == MAPI_HANDLES_RESERVED, MAPI_E_INVALID_PARAMETER, NULL); OPENCHANGE_RETVAL_IF(!rec, MAPI_E_INVALID_PARAMETER, NULL); mem_ctx = talloc_named(NULL, 0, "mapi_handles_add"); /* Step 1. Seek the TDB database for the first free record */ ret = tdb_traverse(handles_ctx->tdb_ctx, mapi_handles_traverse_null, (void *)&handle); if (ret > -1 && handle > 0) { DEBUG(0, ("We have found free record 0x%x\n", handle)); retval = mapi_handles_tdb_update(handles_ctx, handle, container_handle); OPENCHANGE_RETVAL_IF(retval, retval, mem_ctx); el = talloc_zero((TALLOC_CTX *)handles_ctx, struct mapi_handles); if (!el) { mapi_handles_tdb_free(handles_ctx, handle); talloc_free(mem_ctx); return MAPI_E_NOT_ENOUGH_RESOURCES; } el->handle = handle; el->parent_handle = container_handle; el->private_data = NULL; *rec = el; DLIST_ADD_END(handles_ctx->handles, el, struct mapi_handles *); talloc_free(mem_ctx); return MAPI_E_SUCCESS; } /* Step 2. If no record is available, create a new one */ key.dptr = (unsigned char *) talloc_asprintf(mem_ctx, "0x%x", handles_ctx->last_handle); key.dsize = strlen((const char *)key.dptr); if (container_handle) { dbuf.dptr = (unsigned char *) talloc_asprintf(mem_ctx, "0x%x", container_handle); dbuf.dsize = strlen((const char *)dbuf.dptr); } else { dbuf.dptr = (unsigned char *) MAPI_HANDLES_ROOT; dbuf.dsize = strlen(MAPI_HANDLES_ROOT); } ret = tdb_store(handles_ctx->tdb_ctx, key, dbuf, TDB_INSERT); if (ret == -1) { DEBUG(3, ("[%s:%d]: Unable to create 0x%x record: %s\n", __FUNCTION__, __LINE__, handles_ctx->last_handle, tdb_errorstr(handles_ctx->tdb_ctx))); talloc_free(mem_ctx); return MAPI_E_CORRUPT_STORE; } el = talloc_zero((TALLOC_CTX *)handles_ctx, struct mapi_handles); if (!el) { mapi_handles_tdb_free(handles_ctx, handles_ctx->last_handle); talloc_free(mem_ctx); return MAPI_E_NOT_ENOUGH_RESOURCES; } el->handle = handles_ctx->last_handle; el->parent_handle = container_handle; el->private_data = NULL; *rec = el; DLIST_ADD_END(handles_ctx->handles, el, struct mapi_handles *); DEBUG(5, ("handle 0x%.2x is a father of 0x%.2x\n", container_handle, el->handle)); handles_ctx->last_handle += 1; talloc_free(mem_ctx); return MAPI_E_SUCCESS; } /** \details Get the private data associated to a MAPI handle \param handle pointer to the MAPI handle structure \param private_data pointer on pointer to the private data the function returns \return MAPI_E_SUCCESS on success, otherwise MAPI_E_NOT_FOUND */ _PUBLIC_ enum MAPISTATUS mapi_handles_get_private_data(struct mapi_handles *handle, void **private_data) { /* Sanity checks */ OPENCHANGE_RETVAL_IF(!handle, MAPI_E_INVALID_PARAMETER, NULL); OPENCHANGE_RETVAL_IF(!private_data, MAPI_E_INVALID_PARAMETER, NULL); OPENCHANGE_RETVAL_IF(!handle->private_data, MAPI_E_NOT_FOUND, NULL); *private_data = handle->private_data; return MAPI_E_SUCCESS; } /** \details Set the private data associated to a MAPI handle \param handle pointer to the MAPI handle structure \param private_data pointer to the private data to associate to the MAPI handle \return MAPI_E_SUCCESS on success, otherwise MAPI error */ _PUBLIC_ enum MAPISTATUS mapi_handles_set_private_data(struct mapi_handles *handle, void *private_data) { /* Sanity checks */ OPENCHANGE_RETVAL_IF(!handle, MAPI_E_INVALID_PARAMETER, NULL); OPENCHANGE_RETVAL_IF(handle->private_data, MAPI_E_UNABLE_TO_COMPLETE, NULL); handle->private_data = private_data; return MAPI_E_SUCCESS; } struct mapi_handles_private { struct mapi_handles_context *handles_ctx; uint32_t container_handle; }; /** \details Traverse TDB database and search for records which dbuf value is set to state. \param tdb_ctx pointer to the TDB context \param key the current TDB key (potential child handle) \param dbuf the current TDB value (parent handle) \param state pointer on private data \return 1 when a free record is found, otherwise 0 */ static int mapi_handles_traverse_delete(TDB_CONTEXT *tdb_ctx, TDB_DATA key, TDB_DATA dbuf, void *state) { TALLOC_CTX *mem_ctx; struct mapi_handles_private *handles_private = (struct mapi_handles_private *) state; uint32_t handle; char *container_handle_str = NULL; char *handle_str = NULL; mem_ctx = talloc_named(NULL, 0, "mapi_handles_traverse_delete"); container_handle_str = talloc_asprintf(mem_ctx, "0x%x", handles_private->container_handle); if (dbuf.dptr && strlen(container_handle_str) == dbuf.dsize && strncmp((const char *)dbuf.dptr, container_handle_str, dbuf.dsize) == 0) { handle_str = talloc_strndup(mem_ctx, (char *)key.dptr, key.dsize); DEBUG(5, ("handles being released must NOT have child handles attached to them (%s is a child of %s)\n", handle_str, container_handle_str)); handle = strtol((const char *) handle_str, NULL, 16); /* abort(); */ /* DEBUG(5, ("deleting child handle: %d, %s\n", handle, handle_str)); */ mapi_handles_delete(handles_private->handles_ctx, handle); } talloc_free(mem_ctx); return 0; } /** \details Remove the MAPI handle referenced by the handle parameter from the double chained list and mark its associated TDB record as null \param handles_ctx pointer to the MAPI handles context \param handle the handle to delete \return MAPI_E_SUCCESS on success, otherwise MAPI error */ _PUBLIC_ enum MAPISTATUS mapi_handles_delete(struct mapi_handles_context *handles_ctx, uint32_t handle) { TALLOC_CTX *mem_ctx; enum MAPISTATUS retval; TDB_DATA key; struct mapi_handles *el; struct mapi_handles_private handles_private; int ret; bool found = false; /* Sanity checks */ OPENCHANGE_RETVAL_IF(!handles_ctx, MAPI_E_NOT_INITIALIZED, NULL); OPENCHANGE_RETVAL_IF(!handles_ctx->tdb_ctx, MAPI_E_NOT_INITIALIZED, NULL); OPENCHANGE_RETVAL_IF(handle == MAPI_HANDLES_RESERVED, MAPI_E_INVALID_PARAMETER, NULL); DEBUG(4, ("[%s:%d]: Deleting MAPI handle 0x%x (handles_ctx: %p, tdb_ctx: %p)\n", __FUNCTION__, __LINE__, handle, handles_ctx, handles_ctx->tdb_ctx)); mem_ctx = talloc_named(NULL, 0, "mapi_handles_delete"); key.dptr = (unsigned char *) talloc_asprintf(mem_ctx, "0x%x", handle); key.dsize = strlen((const char *)key.dptr); /* Step 1. Make sure the record exists */ ret = tdb_exists(handles_ctx->tdb_ctx, key); OPENCHANGE_RETVAL_IF(!ret, MAPI_E_NOT_FOUND, mem_ctx); /* Step 2. Delete this record from the double chained list */ for (el = handles_ctx->handles; el; el = el->next) { if (el->handle == handle) { DLIST_REMOVE(handles_ctx->handles, el); talloc_free(el); found = true; break; } } /* This case should never occur */ OPENCHANGE_RETVAL_IF(found == false, MAPI_E_CORRUPT_STORE, mem_ctx); /* Step 3. Free this record within the TDB database */ retval = mapi_handles_tdb_free(handles_ctx, handle); /* if (retval) { */ /* abort(); */ /* } */ OPENCHANGE_RETVAL_IF(retval, retval, mem_ctx); /* Step 4. Delete hierarchy of children */ handles_private.handles_ctx = handles_ctx; handles_private.container_handle = handle; ret = tdb_traverse(handles_ctx->tdb_ctx, mapi_handles_traverse_delete, (void *)&handles_private); talloc_free(mem_ctx); DEBUG(4, ("[%s:%d]: Deleting MAPI handle 0x%x COMPLETE\n", __FUNCTION__, __LINE__, handle)); return MAPI_E_SUCCESS; } openchange-2.0/mapiproxy/libmapiproxy/modules.c000066400000000000000000000050571223057412600220560ustar00rootroot00000000000000/* Unix SMB/CIFS implementation. Samba utility functions Copyright (C) Jelmer Vernooij 2011 This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see . */ #include "mapiproxy/dcesrv_mapiproxy.h" #include "libmapiproxy.h" #include #include #include #include #define SAMBA_INIT_MODULE "samba_init_module" static openchange_plugin_init_fn load_plugin(const char *path) { void *handle; void *init_fn; char *error; handle = dlopen(path, RTLD_NOW); /* This call should reset any possible non-fatal errors that occured since last call to dl* functions */ error = dlerror(); if (handle == NULL) { DEBUG(0, ("Error loading plugin '%s': %s\n", path, error ? error : "")); return NULL; } init_fn = (openchange_plugin_init_fn)dlsym(handle, SAMBA_INIT_MODULE); if (init_fn == NULL) { DEBUG(0, ("Unable to find %s() in %s: %s\n", SAMBA_INIT_MODULE, path, dlerror())); DEBUG(1, ("Loading plugin '%s' failed\n", path)); dlclose(handle); return NULL; } return (openchange_plugin_init_fn)init_fn; } openchange_plugin_init_fn *load_openchange_plugins(TALLOC_CTX *mem_ctx, const char *subsystem) { DIR *dir; struct dirent *entry; char *filename, *path; int success = 0; openchange_plugin_init_fn *ret = talloc_array(mem_ctx, openchange_plugin_init_fn, 2); ret[0] = NULL; path = talloc_asprintf(mem_ctx, "%s/%s", MODULESDIR, subsystem); if (path == NULL) { return NULL; } dir = opendir(path); if (dir == NULL) { talloc_free(path); talloc_free(ret); return NULL; } while((entry = readdir(dir))) { if (strcmp(entry->d_name, ".") == 0 || strcmp(entry->d_name, "..") == 0) continue; filename = talloc_asprintf(mem_ctx, "%s/%s", path, entry->d_name); ret[success] = load_plugin(filename); if (ret[success]) { ret = talloc_realloc(mem_ctx, ret, openchange_plugin_init_fn, success+2); success++; ret[success] = NULL; } talloc_free(filename); } closedir(dir); talloc_free(path); return ret; } openchange-2.0/mapiproxy/libmapiproxy/openchangedb.c000066400000000000000000002123551223057412600230240ustar00rootroot00000000000000/* OpenChange Server implementation EMSMDBP: EMSMDB Provider implementation Copyright (C) Julien Kerihuel 2009-2011 This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see . */ /** \file openchangedb.c \brief OpenChange Dispatcher database routines */ #include #include "mapiproxy/dcesrv_mapiproxy.h" #include "mapiproxy/libmapiproxy/libmapiproxy.h" #include "libmapi/libmapi.h" #include "libmapi/libmapi_private.h" extern struct ldb_val ldb_binary_decode(TALLOC_CTX *, const char *); const char *openchangedb_nil_string = ""; /** \details Retrieve the mailbox FolderID for given recipient from openchange dispatcher database \param ldb_ctx pointer to the OpenChange LDB context \param recipient the mailbox username \param SystemIdx the system folder index \param FolderId pointer to the folder identifier the function returns \return MAPI_E_SUCCESS on success, otherwise MAPI error */ _PUBLIC_ enum MAPISTATUS openchangedb_get_SystemFolderID(struct ldb_context *ldb_ctx, const char *recipient, uint32_t SystemIdx, uint64_t *FolderId) { TALLOC_CTX *mem_ctx; struct ldb_result *res = NULL; const char * const attrs[] = { "*", NULL }; int ret; const char *dn; struct ldb_dn *ldb_dn = NULL; /* Sanity checks */ OPENCHANGE_RETVAL_IF(!ldb_ctx, MAPI_E_NOT_INITIALIZED, NULL); OPENCHANGE_RETVAL_IF(!recipient, MAPI_E_INVALID_PARAMETER, NULL); OPENCHANGE_RETVAL_IF(!FolderId, MAPI_E_INVALID_PARAMETER, NULL); mem_ctx = talloc_named(NULL, 0, "get_SystemFolderID"); /* Step 1. Search Mailbox Root DN */ ret = ldb_search(ldb_ctx, mem_ctx, &res, ldb_get_default_basedn(ldb_ctx), LDB_SCOPE_SUBTREE, attrs, "CN=%s", recipient); OPENCHANGE_RETVAL_IF(ret != LDB_SUCCESS || !res->count, MAPI_E_NOT_FOUND, mem_ctx); /* Step 2. If Mailbox root folder, check for FolderID within current record */ if (SystemIdx == 0x1) { *FolderId = ldb_msg_find_attr_as_uint64(res->msgs[0], "PidTagFolderId", 0); OPENCHANGE_RETVAL_IF(!*FolderId, MAPI_E_CORRUPT_STORE, mem_ctx); talloc_free(mem_ctx); return MAPI_E_SUCCESS; } dn = ldb_msg_find_attr_as_string(res->msgs[0], "distinguishedName", NULL); OPENCHANGE_RETVAL_IF(!dn, MAPI_E_CORRUPT_STORE, mem_ctx); /* Step 3. Search FolderID */ ldb_dn = ldb_dn_new(mem_ctx, ldb_ctx, dn); OPENCHANGE_RETVAL_IF(!ldb_dn, MAPI_E_CORRUPT_STORE, mem_ctx); ret = ldb_search(ldb_ctx, mem_ctx, &res, ldb_dn, LDB_SCOPE_SUBTREE, attrs, "(&(objectClass=systemfolder)(SystemIdx=%d))", SystemIdx); OPENCHANGE_RETVAL_IF(ret != LDB_SUCCESS || !res->count, MAPI_E_NOT_FOUND, mem_ctx); *FolderId = ldb_msg_find_attr_as_uint64(res->msgs[0], "PidTagFolderId", 0); OPENCHANGE_RETVAL_IF(!*FolderId, MAPI_E_CORRUPT_STORE, mem_ctx); talloc_free(mem_ctx); return MAPI_E_SUCCESS; } /** \details Retrieve the public folder FolderID (fid) for a given folder type \param ldb_ctx pointer to the OpenChange LDB context \param SystemIdx the system folder index \param FolderId pointer to the folder identifier the function returns \return MAPI_E_SUCCESS on success, otherwise MAPI error */ _PUBLIC_ enum MAPISTATUS openchangedb_get_PublicFolderID(struct ldb_context *ldb_ctx, uint32_t SystemIdx, uint64_t *FolderId) { TALLOC_CTX *mem_ctx; struct ldb_result *res = NULL; const char * const attrs[] = { "*", NULL }; int ret; /* Sanity checks */ OPENCHANGE_RETVAL_IF(!ldb_ctx, MAPI_E_NOT_INITIALIZED, NULL); OPENCHANGE_RETVAL_IF(!FolderId, MAPI_E_INVALID_PARAMETER, NULL); mem_ctx = talloc_named(NULL, 0, "get_PublicFolderID"); ret = ldb_search(ldb_ctx, mem_ctx, &res, ldb_get_default_basedn(ldb_ctx), LDB_SCOPE_SUBTREE, attrs, "(&(objectClass=publicfolder)(SystemIdx=%d))", SystemIdx); OPENCHANGE_RETVAL_IF(ret != LDB_SUCCESS, MAPI_E_NOT_FOUND, mem_ctx); OPENCHANGE_RETVAL_IF(res->count != 1, MAPI_E_NOT_FOUND, mem_ctx); *FolderId = ldb_msg_find_attr_as_uint64(res->msgs[0], "PidTagFolderId", 0); OPENCHANGE_RETVAL_IF(!*FolderId, MAPI_E_CORRUPT_STORE, mem_ctx); talloc_free(mem_ctx); return MAPI_E_SUCCESS; } /** \details Retrieve the distinguishedName associated to a mailbox system folder. \param parent_ctx pointer to the parent memory context \param ldb_ctx pointer to the openchange LDB context \param fid the Folder identifier to search for \param distinguishedName pointer on pointer to the distinguishedName string the function returns \return MAPI_E_SUCCESS on success, otherwise MAPI_E_NOT_FOUND */ _PUBLIC_ enum MAPISTATUS openchangedb_get_distinguishedName(TALLOC_CTX *parent_ctx, struct ldb_context *ldb_ctx, uint64_t fid, char **distinguishedName) { TALLOC_CTX *mem_ctx; struct ldb_result *res = NULL; const char * const attrs[] = { "*", NULL }; int ret; mem_ctx = talloc_named(NULL, 0, "get_distinguishedName"); ret = ldb_search(ldb_ctx, mem_ctx, &res, ldb_get_default_basedn(ldb_ctx), LDB_SCOPE_SUBTREE, attrs, "(PidTagFolderId=%"PRIu64")", fid); OPENCHANGE_RETVAL_IF(ret != LDB_SUCCESS || !res->count, MAPI_E_NOT_FOUND, mem_ctx); *distinguishedName = talloc_strdup(parent_ctx, ldb_msg_find_attr_as_string(res->msgs[0], "distinguishedName", NULL)); talloc_free(mem_ctx); return MAPI_E_SUCCESS; } /** \details Retrieve the mailboxDN associated to a mailbox system folder. \param parent_ctx pointer to the parent memory context \param ldb_ctx pointer to the openchange LDB context \param fid the folder identifier to search for \param mailboxDN pointer on pointer to the mailboxDN string the function returns \return MAPI_E_SUCCESS on success, otherwise MAPI_E_NOT_FOUND */ _PUBLIC_ enum MAPISTATUS openchangedb_get_mailboxDN(TALLOC_CTX *parent_ctx, struct ldb_context *ldb_ctx, uint64_t fid, char **mailboxDN) { TALLOC_CTX *mem_ctx; struct ldb_result *res = NULL; const char * const attrs[] = { "*", NULL }; int ret; mem_ctx = talloc_named(NULL, 0, "get_mailboxDN"); ret = ldb_search(ldb_ctx, mem_ctx, &res, ldb_get_default_basedn(ldb_ctx), LDB_SCOPE_SUBTREE, attrs, "(PidTagFolderId=%"PRIu64")", fid); OPENCHANGE_RETVAL_IF(ret != LDB_SUCCESS || !res->count, MAPI_E_NOT_FOUND, mem_ctx); *mailboxDN = talloc_strdup(parent_ctx, ldb_msg_find_attr_as_string(res->msgs[0], "mailboxDN", NULL)); talloc_free(mem_ctx); return MAPI_E_SUCCESS; } /** \details Retrieve the mailbox GUID for given recipient from openchange dispatcher database \param ldb_ctx pointer to the OpenChange LDB context \param recipient the mailbox username \param MailboxGUID pointer to the mailbox GUID the function returns \return MAPI_E_SUCCESS on success, otherwise MAPI error */ _PUBLIC_ enum MAPISTATUS openchangedb_get_MailboxGuid(struct ldb_context *ldb_ctx, const char *recipient, struct GUID *MailboxGUID) { TALLOC_CTX *mem_ctx; struct ldb_result *res = NULL; const char *guid; const char * const attrs[] = { "*", NULL }; int ret; /* Sanity checks */ OPENCHANGE_RETVAL_IF(!ldb_ctx, MAPI_E_NOT_INITIALIZED, NULL); OPENCHANGE_RETVAL_IF(!recipient, MAPI_E_INVALID_PARAMETER, NULL); OPENCHANGE_RETVAL_IF(!MailboxGUID, MAPI_E_INVALID_PARAMETER, NULL); mem_ctx = talloc_named(NULL, 0, "get_MailboxGuid"); /* Step 1. Search Mailbox DN */ ret = ldb_search(ldb_ctx, mem_ctx, &res, ldb_get_default_basedn(ldb_ctx), LDB_SCOPE_SUBTREE, attrs, "CN=%s", recipient); OPENCHANGE_RETVAL_IF(ret != LDB_SUCCESS || !res->count, MAPI_E_NOT_FOUND, mem_ctx); /* Step 2. Retrieve MailboxGUID attribute's value */ guid = ldb_msg_find_attr_as_string(res->msgs[0], "MailboxGUID", NULL); OPENCHANGE_RETVAL_IF(!guid, MAPI_E_CORRUPT_STORE, mem_ctx); GUID_from_string(guid, MailboxGUID); talloc_free(mem_ctx); return MAPI_E_SUCCESS; } /** \details Retrieve the mailbox replica identifier and GUID for given recipient from openchange dispatcher database \param ldb_ctx pointer to the OpenChange LDB context \param recipient the mailbox username \param ReplID pointer to the replica identifier the function returns \param ReplGUID pointer to the replica GUID the function returns \return MAPI_E_SUCCESS on success, otherwise MAPI error */ _PUBLIC_ enum MAPISTATUS openchangedb_get_MailboxReplica(struct ldb_context *ldb_ctx, const char *recipient, uint16_t *ReplID, struct GUID *ReplGUID) { TALLOC_CTX *mem_ctx; struct ldb_result *res = NULL; const char *guid; const char * const attrs[] = { "*", NULL }; int ret; /* Sanity checks */ OPENCHANGE_RETVAL_IF(!ldb_ctx, MAPI_E_NOT_INITIALIZED, NULL); OPENCHANGE_RETVAL_IF(!recipient, MAPI_E_INVALID_PARAMETER, NULL); mem_ctx = talloc_named(NULL, 0, "get_MailboxReplica"); /* Step 1. Search Mailbox DN */ ret = ldb_search(ldb_ctx, mem_ctx, &res, ldb_get_default_basedn(ldb_ctx), LDB_SCOPE_SUBTREE, attrs, "CN=%s", recipient); OPENCHANGE_RETVAL_IF(ret != LDB_SUCCESS || !res->count, MAPI_E_NOT_FOUND, mem_ctx); /* Step 2. Retrieve ReplicaID attribute's value */ if (ReplID) { *ReplID = ldb_msg_find_attr_as_int(res->msgs[0], "ReplicaID", 0); } /* Step 3/ Retrieve ReplicaGUID attribute's value */ if (ReplGUID) { guid = ldb_msg_find_attr_as_string(res->msgs[0], "ReplicaGUID", 0); OPENCHANGE_RETVAL_IF(!guid, MAPI_E_CORRUPT_STORE, mem_ctx); GUID_from_string(guid, ReplGUID); } talloc_free(mem_ctx); return MAPI_E_SUCCESS; } /** \details Retrieve the public folder replica identifier and GUID from the openchange dispatcher database \param ldb_ctx pointer to the OpenChange LDB context \param ReplID pointer to the replica identifier the function returns \param ReplGUID pointer to the replica GUID the function returns \return MAPI_E_SUCCESS on success, otherwise MAPI error */ _PUBLIC_ enum MAPISTATUS openchangedb_get_PublicFolderReplica(struct ldb_context *ldb_ctx, uint16_t *ReplID, struct GUID *ReplGUID) { TALLOC_CTX *mem_ctx; struct ldb_result *res = NULL; const char *guid; const char * const attrs[] = { "*", NULL }; int ret; /* Sanity checks */ OPENCHANGE_RETVAL_IF(!ldb_ctx, MAPI_E_NOT_INITIALIZED, NULL); mem_ctx = talloc_named(NULL, 0, "get_PublicFolderReplica"); /* Step 1. Search for public folder container */ ret = ldb_search(ldb_ctx, mem_ctx, &res, ldb_get_default_basedn(ldb_ctx), LDB_SCOPE_SUBTREE, attrs, "CN=publicfolders"); OPENCHANGE_RETVAL_IF(ret != LDB_SUCCESS || !res->count, MAPI_E_NOT_FOUND, mem_ctx); /* Step 2. Retrieve ReplicaID attribute's value */ if (ReplID != NULL) { *ReplID = ldb_msg_find_attr_as_int(res->msgs[0], "ReplicaID", 0); } /* Step 3. Retrieve ReplicaGUID attribute's value */ if (ReplGUID != NULL) { guid = ldb_msg_find_attr_as_string(res->msgs[0], "StoreGUID", 0); OPENCHANGE_RETVAL_IF(!guid, MAPI_E_CORRUPT_STORE, mem_ctx); GUID_from_string(guid, ReplGUID); } talloc_free(mem_ctx); return MAPI_E_SUCCESS; } /** \details Retrieve the mapistore URI associated to a mailbox system folder. \param parent_ctx pointer to the memory context \param ldb_ctx pointer to the openchange LDB context \param fid the Folder identifier to search for \param mapistoreURL pointer on pointer to the mapistore URI the function returns \param owner pointer on pointer to the owner of the parent mailbox \param mailboxstore boolean value which defines whether the record has to be searched within Public folders hierarchy or not \return MAPI_E_SUCCESS on success, otherwise MAPI_E_NOT_FOUND */ _PUBLIC_ enum MAPISTATUS openchangedb_get_mapistoreURI(TALLOC_CTX *parent_ctx, struct ldb_context *ldb_ctx, uint64_t fid, char **mapistoreURL, bool mailboxstore) { TALLOC_CTX *mem_ctx; struct ldb_result *res = NULL; const char * const attrs[] = { "*", NULL }; int ret; mem_ctx = talloc_named(NULL, 0, "get_mapistoreURI"); if (mailboxstore == true) { ret = ldb_search(ldb_ctx, mem_ctx, &res, ldb_get_default_basedn(ldb_ctx), LDB_SCOPE_SUBTREE, attrs, "(PidTagFolderId=%"PRIu64")", fid); } else { ret = ldb_search(ldb_ctx, mem_ctx, &res, ldb_get_root_basedn(ldb_ctx), LDB_SCOPE_SUBTREE, attrs, "(PidTagFolderId=%"PRIu64")", fid); } OPENCHANGE_RETVAL_IF(ret != LDB_SUCCESS || !res->count, MAPI_E_NOT_FOUND, mem_ctx); *mapistoreURL = talloc_strdup(parent_ctx, ldb_msg_find_attr_as_string(res->msgs[0], "MAPIStoreURI", NULL)); talloc_free(mem_ctx); return MAPI_E_SUCCESS; } /** \details Store the mapistore URI associated to a mailbox system folder. \param parent_ctx pointer to the memory context \param ldb_ctx pointer to the openchange LDB context \param fid the Folder identifier to search for \param mapistoreURL pointer on pointer to the mapistore URI the function returns \param owner pointer on pointer to the owner of the parent mailbox \param mailboxstore boolean value which defines whether the record has to be searched within Public folders hierarchy or not \return MAPI_E_SUCCESS on success, otherwise MAPI_E_NOT_FOUND */ _PUBLIC_ enum MAPISTATUS openchangedb_set_mapistoreURI(struct ldb_context *ldb_ctx, uint64_t fid, const char *mapistoreURL, bool mailboxstore) { TALLOC_CTX *mem_ctx; struct ldb_result *res = NULL; struct ldb_message *msg; const char * const attrs[] = { "*", NULL }; int ret; mem_ctx = talloc_named(NULL, 0, "get_mapistoreURI"); if (mailboxstore == true) { ret = ldb_search(ldb_ctx, mem_ctx, &res, ldb_get_default_basedn(ldb_ctx), LDB_SCOPE_SUBTREE, attrs, "(PidTagFolderId=%"PRIu64")", fid); } else { ret = ldb_search(ldb_ctx, mem_ctx, &res, ldb_get_root_basedn(ldb_ctx), LDB_SCOPE_SUBTREE, attrs, "(PidTagFolderId=%"PRIu64")", fid); } OPENCHANGE_RETVAL_IF(ret != LDB_SUCCESS || !res->count, MAPI_E_NOT_FOUND, mem_ctx); msg = ldb_msg_new(mem_ctx); msg->dn = ldb_dn_copy(msg, ldb_msg_find_attr_as_dn(ldb_ctx, mem_ctx, res->msgs[0], "distinguishedName")); ldb_msg_add_string(msg, "MAPIStoreURI", mapistoreURL); msg->elements[0].flags = LDB_FLAG_MOD_REPLACE; ret = ldb_modify(ldb_ctx, msg); OPENCHANGE_RETVAL_IF(ret != LDB_SUCCESS, MAPI_E_NO_SUPPORT, mem_ctx); talloc_free(mem_ctx); return ret; } /** \details Retrieve the parent fid associated to a mailbox system folder. \param ldb_ctx pointer to the openchange LDB context \param fid the Folder identifier to search for \param parent_fidp pointer to the parent_fid the function returns \param mailboxstore boolean value which defines whether the record has to be searched within Public folders hierarchy or not \return MAPI_E_SUCCESS on success, otherwise MAPI_E_NOT_FOUND */ _PUBLIC_ enum MAPISTATUS openchangedb_get_parent_fid(struct ldb_context *ldb_ctx, uint64_t fid, uint64_t *parent_fidp, bool mailboxstore) { TALLOC_CTX *mem_ctx; struct ldb_result *res = NULL; const char * const attrs[] = { "*", NULL }; int ret; mem_ctx = talloc_named(NULL, 0, "get_parent_fid"); if (mailboxstore == true) { ret = ldb_search(ldb_ctx, mem_ctx, &res, ldb_get_default_basedn(ldb_ctx), LDB_SCOPE_SUBTREE, attrs, "(PidTagFolderId=%"PRIu64")", fid); } else { ret = ldb_search(ldb_ctx, mem_ctx, &res, ldb_get_root_basedn(ldb_ctx), LDB_SCOPE_SUBTREE, attrs, "(PidTagFolderId=%"PRIu64")", fid); } OPENCHANGE_RETVAL_IF(ret != LDB_SUCCESS || !res->count, MAPI_E_NOT_FOUND, mem_ctx); *parent_fidp = ldb_msg_find_attr_as_uint64(res->msgs[0], "PidTagParentFolderId", 0x0); talloc_free(mem_ctx); return MAPI_E_SUCCESS; } /** \details Retrieve the fid associated with a mapistore URI. \param ldb_ctx pointer to the openchange LDB context \param fid the Folder identifier to search for \param mapistoreURL pointer on pointer to the mapistore URI the function returns \param mailboxstore boolean value which defines whether the record has to be searched within Public folders hierarchy or not \return MAPI_E_SUCCESS on success, otherwise MAPI_E_NOT_FOUND */ _PUBLIC_ enum MAPISTATUS openchangedb_get_fid(struct ldb_context *ldb_ctx, const char *mapistoreURL, uint64_t *fidp) { TALLOC_CTX *mem_ctx; struct ldb_result *res = NULL; const char * const attrs[] = { "*", NULL }; char *slashLessURL; size_t len; int ret; mem_ctx = talloc_named(NULL, 0, "openchangedb_get_fid"); ret = ldb_search(ldb_ctx, mem_ctx, &res, ldb_get_default_basedn(ldb_ctx), LDB_SCOPE_SUBTREE, attrs, "(MAPIStoreURI=%s)", mapistoreURL); if (ret != LDB_SUCCESS || !res->count) { len = strlen(mapistoreURL); if (mapistoreURL[len-1] == '/') { slashLessURL = talloc_strdup(mem_ctx, mapistoreURL); slashLessURL[len-1] = 0; ret = ldb_search(ldb_ctx, mem_ctx, &res, ldb_get_default_basedn(ldb_ctx), LDB_SCOPE_SUBTREE, attrs, "(MAPIStoreURI=%s)", slashLessURL); } OPENCHANGE_RETVAL_IF(ret != LDB_SUCCESS || !res->count, MAPI_E_NOT_FOUND, mem_ctx); } *fidp = ldb_msg_find_attr_as_uint64(res->msgs[0], "PidTagFolderId", 0x0); talloc_free(mem_ctx); return MAPI_E_SUCCESS; } /** \details Retrieve a list of mapistore URI in use for a certain user \param ldb_ctx pointer to the openchange LDB context \param fid the Folder identifier to search for \param mapistoreURL pointer on pointer to the mapistore URI the function returns \param mailboxstore boolean value which defines whether the record has to be searched within Public folders hierarchy or not \return MAPI_E_SUCCESS on success, otherwise MAPI_E_NOT_FOUND */ _PUBLIC_ enum MAPISTATUS openchangedb_get_MAPIStoreURIs(struct ldb_context *ldb_ctx, const char *username, TALLOC_CTX *mem_ctx, struct StringArrayW_r **urisP) { TALLOC_CTX *local_mem_ctx; struct ldb_result *res = NULL; struct ldb_dn *dn; const char * const attrs[] = { "*", NULL }; char *dnstr; int i, elements, ret; struct StringArrayW_r *uris; local_mem_ctx = talloc_named(NULL, 0, "openchangedb_get_fid"); /* fetch mailbox DN */ ret = ldb_search(ldb_ctx, local_mem_ctx, &res, ldb_get_default_basedn(ldb_ctx), LDB_SCOPE_SUBTREE, attrs, "(&(cn=%s)(MailboxGUID=*))", username); OPENCHANGE_RETVAL_IF(ret != LDB_SUCCESS || !res->count, MAPI_E_NOT_FOUND, local_mem_ctx); dnstr = talloc_strdup(local_mem_ctx, ldb_msg_find_attr_as_string(res->msgs[0], "distinguishedName", NULL)); OPENCHANGE_RETVAL_IF(!dnstr, MAPI_E_NOT_FOUND, local_mem_ctx); dn = ldb_dn_new(local_mem_ctx, ldb_ctx, dnstr); uris = talloc_zero(mem_ctx, struct StringArrayW_r); uris->lppszW = talloc_zero(uris, const char *); *urisP = uris; elements = 0; /* search subfolders which have a non-null mapistore uri */ ret = ldb_search(ldb_ctx, local_mem_ctx, &res, dn, LDB_SCOPE_SUBTREE, attrs, "(MAPIStoreURI=*)"); if (ret == LDB_SUCCESS) { for (i = 0; i < res->count; i++) { if ((uris->cValues + 1) > elements) { elements = uris->cValues + 16; uris->lppszW = talloc_realloc(uris, uris->lppszW, const char *, elements); } uris->lppszW[uris->cValues] = talloc_strdup(uris, ldb_msg_find_attr_as_string(res->msgs[i], "MAPIStoreURI", NULL)); uris->cValues++; } } talloc_free(local_mem_ctx); return MAPI_E_SUCCESS; } /** \details Retrieve the Explicit message class and Folder identifier associated to the MessageClass search pattern. \param parent_ctx pointer to the memory context \param ldb_ctx pointer to the openchange LDB context \param recipient pointer to the mailbox's username \param MessageClass substring to search for \param fid pointer to the folder identifier the function returns \param ExplicitMessageClass pointer on pointer to the complete message class the function returns \return MAPI_E_SUCCESS on success, otherwise MAPI_E_NOT_FOUND */ _PUBLIC_ enum MAPISTATUS openchangedb_get_ReceiveFolder(TALLOC_CTX *parent_ctx, struct ldb_context *ldb_ctx, const char *recipient, const char *MessageClass, uint64_t *fid, const char **ExplicitMessageClass) { TALLOC_CTX *mem_ctx; struct ldb_result *res = NULL; struct ldb_dn *dn; struct ldb_message_element *ldb_element; char *dnstr; const char * const attrs[] = { "*", NULL }; int ret; unsigned int i, j; size_t length; mem_ctx = talloc_named(NULL, 0, "get_ReceiveFolder"); DEBUG(5, ("openchangedb_get_ReceiveFolder, recipient: %s\n", recipient)); DEBUG(5, ("openchangedb_get_ReceiveFolder, MessageClass: %s\n", MessageClass)); /* Step 1. Find mailbox DN for the recipient */ ret = ldb_search(ldb_ctx, mem_ctx, &res, ldb_get_default_basedn(ldb_ctx), LDB_SCOPE_SUBTREE, attrs, "CN=%s", recipient); OPENCHANGE_RETVAL_IF(ret != LDB_SUCCESS || !res->count, MAPI_E_NOT_FOUND, mem_ctx); dnstr = talloc_strdup(mem_ctx, ldb_msg_find_attr_as_string(res->msgs[0], "distinguishedName", NULL)); OPENCHANGE_RETVAL_IF(!dnstr, MAPI_E_NOT_FOUND, mem_ctx); talloc_free(res); dn = ldb_dn_new(mem_ctx, ldb_ctx, dnstr); talloc_free(dnstr); /* Step 2A. As a special case, find the "All" target */ ret = ldb_search(ldb_ctx, mem_ctx, &res, dn, LDB_SCOPE_SUBTREE, attrs, "(PidTagMessageClass=All)"); OPENCHANGE_RETVAL_IF(ret != LDB_SUCCESS || (res->count != 1), MAPI_E_NOT_FOUND, mem_ctx); *fid = ldb_msg_find_attr_as_uint64(res->msgs[0], "PidTagFolderId", 0x0); *ExplicitMessageClass = ""; DEBUG(5, ("openchangedb_get_ReceiveFolder (All target), class: %s, fid: %.16"PRIx64"\n", *ExplicitMessageClass, *fid)); if (strcmp(MessageClass, "All") == 0) { /* we're done here */ talloc_free(mem_ctx); return MAPI_E_SUCCESS; } /* Step 2B. Search for all MessageClasses within user's mailbox */ ret = ldb_search(ldb_ctx, mem_ctx, &res, dn, LDB_SCOPE_SUBTREE, attrs, "(PidTagMessageClass=*)"); OPENCHANGE_RETVAL_IF(ret != LDB_SUCCESS || !res->count, MAPI_E_NOT_FOUND, mem_ctx); /* Step 3. Find the message class that has the longest matching string entry */ for (j = 0; j < res->count; ++j) { ldb_element = ldb_msg_find_element(res->msgs[j], "PidTagMessageClass"); DEBUG(6, ("openchangedb_get_ReceiveFolder, checking fid: %.16"PRIx64"\n", ldb_msg_find_attr_as_uint64(res->msgs[j], "PidTagFolderId", 0x0))); for (i = 0, length = 0; i < ldb_element[j].num_values; i++) { DEBUG(6, ("openchangedb_get_ReceiveFolder, element %i, data: %s\n", i, (char *)ldb_element->values[i].data)); if (MessageClass && !strncasecmp(MessageClass, (char *)ldb_element->values[i].data, strlen((char *)ldb_element->values[i].data)) && strlen((char *)ldb_element->values[i].data) > length) { *fid = ldb_msg_find_attr_as_uint64(res->msgs[j], "PidTagFolderId", 0x0); if (*ExplicitMessageClass && strcmp(*ExplicitMessageClass, "")) { talloc_free((char *)*ExplicitMessageClass); } if (MessageClass && !strcmp(MessageClass, "All")) { *ExplicitMessageClass = ""; } else { *ExplicitMessageClass = talloc_strdup(parent_ctx, (char *)ldb_element->values[i].data); } length = strlen((char *)ldb_element->values[i].data); } } } OPENCHANGE_RETVAL_IF(!*ExplicitMessageClass, MAPI_E_NOT_FOUND, mem_ctx); DEBUG(5, ("openchangedb_get_ReceiveFolder, fid: %.16"PRIx64"\n", *fid)); talloc_free(mem_ctx); return MAPI_E_SUCCESS; } /** \details Retrieve the Transport Folder FolderID for given recipient from openchange dispatcher database \param ldb_ctx pointer to the OpenChange LDB context \param recipient the mailbox username \param FolderId pointer to the folder identifier the function returns \return MAPI_E_SUCCESS on success, otherwise MAPI error */ _PUBLIC_ enum MAPISTATUS openchangedb_get_TransportFolder(struct ldb_context *ldb_ctx, const char *recipient, uint64_t *FolderId) { TALLOC_CTX *mem_ctx; struct ldb_result *res = NULL; const char * const attrs[] = { "*", NULL }; int ret; char *dnstr; struct ldb_dn *ldb_dn = NULL; /* Sanity checks */ OPENCHANGE_RETVAL_IF(!ldb_ctx, MAPI_E_NOT_INITIALIZED, NULL); OPENCHANGE_RETVAL_IF(!recipient, MAPI_E_INVALID_PARAMETER, NULL); OPENCHANGE_RETVAL_IF(!FolderId, MAPI_E_INVALID_PARAMETER, NULL); mem_ctx = talloc_named(NULL, 0, "get_TransportFolder"); /* Step 1. Find mailbox DN for the recipient */ ret = ldb_search(ldb_ctx, mem_ctx, &res, ldb_get_default_basedn(ldb_ctx), LDB_SCOPE_SUBTREE, attrs, "CN=%s", recipient); OPENCHANGE_RETVAL_IF(ret != LDB_SUCCESS || !res->count, MAPI_E_NOT_FOUND, mem_ctx); dnstr = talloc_strdup(mem_ctx, ldb_msg_find_attr_as_string(res->msgs[0], "distinguishedName", NULL)); OPENCHANGE_RETVAL_IF(!dnstr, MAPI_E_NOT_FOUND, mem_ctx); talloc_free(res); /* Step 2. Find "Outbox" in user mailbox */ ldb_dn = ldb_dn_new(mem_ctx, ldb_ctx, dnstr); talloc_free(dnstr); ret = ldb_search(ldb_ctx, mem_ctx, &res, ldb_dn, LDB_SCOPE_SUBTREE, attrs, "(PidTagDisplayName=%s)", "Outbox"); OPENCHANGE_RETVAL_IF(ret != LDB_SUCCESS || !res->count, MAPI_E_NOT_FOUND, mem_ctx); /* Step 2. If Mailbox root folder, check for FolderID within current record */ *FolderId = ldb_msg_find_attr_as_uint64(res->msgs[0], "PidTagFolderId", 0); OPENCHANGE_RETVAL_IF(!*FolderId, MAPI_E_CORRUPT_STORE, mem_ctx); talloc_free(mem_ctx); return MAPI_E_SUCCESS; } /** \details Retrieve the number of sub folders for a given fid \param ldb_ctx pointer to the openchange LDB context \param fid the folder identifier to use for the search \param RowCount pointer to the returned number of results \return MAPI_E_SUCCESS on success, otherwise MAPI_E_NOT_FOUND */ _PUBLIC_ enum MAPISTATUS openchangedb_get_folder_count(struct ldb_context *ldb_ctx, uint64_t fid, uint32_t *RowCount) { TALLOC_CTX *mem_ctx; struct ldb_result *res; const char * const attrs[] = { "*", NULL }; int ret; /* Sanity checks */ OPENCHANGE_RETVAL_IF(!ldb_ctx, MAPI_E_NOT_INITIALIZED, NULL); OPENCHANGE_RETVAL_IF(!RowCount, MAPI_E_INVALID_PARAMETER, NULL); mem_ctx = talloc_named(NULL, 0, "get_folder_count"); *RowCount = 0; ret = ldb_search(ldb_ctx, mem_ctx, &res, ldb_get_default_basedn(ldb_ctx), LDB_SCOPE_SUBTREE, attrs, "(PidTagParentFolderId=%"PRIu64")(PidTagFolderId=*)", fid); OPENCHANGE_RETVAL_IF(ret != LDB_SUCCESS, MAPI_E_NOT_FOUND, mem_ctx); *RowCount = res->count; talloc_free(mem_ctx); return MAPI_E_SUCCESS; } static char *openchangedb_unknown_property(TALLOC_CTX *mem_ctx, uint32_t proptag) { return talloc_asprintf(mem_ctx, "Unknown%.8x", proptag); } /** \details Check if a property exists within an openchange dispatcher database record \param ldb_ctx pointer to the openchange LDB context \param proptag the MAPI property tag to lookup \param fid the record folder identifier \return MAPI_E_SUCCESS on success, otherwise MAPI_E_NOT_FOUND */ _PUBLIC_ enum MAPISTATUS openchangedb_lookup_folder_property(struct ldb_context *ldb_ctx, uint32_t proptag, uint64_t fid) { TALLOC_CTX *mem_ctx; struct ldb_result *res = NULL; const char * const attrs[] = { "*", NULL }; const char *PidTagAttr = NULL; int ret; mem_ctx = talloc_named(NULL, 0, "get_folder_property"); /* Step 1. Find PidTagFolderId record */ ret = ldb_search(ldb_ctx, mem_ctx, &res, ldb_get_default_basedn(ldb_ctx), LDB_SCOPE_SUBTREE, attrs, "(PidTagFolderId=%"PRIu64")", fid); OPENCHANGE_RETVAL_IF(ret != LDB_SUCCESS || !res->count, MAPI_E_NOT_FOUND, mem_ctx); /* Step 2. Convert proptag into PidTag attribute */ PidTagAttr = openchangedb_property_get_attribute(proptag); if (!PidTagAttr) { PidTagAttr = openchangedb_unknown_property(mem_ctx, proptag); } /* Step 3. Search for attribute */ OPENCHANGE_RETVAL_IF(!ldb_msg_find_element(res->msgs[0], PidTagAttr), MAPI_E_NOT_FOUND, mem_ctx); talloc_free(mem_ctx); return MAPI_E_SUCCESS; } /** \details Retrieve a special MAPI property from an openchangedb record \param mem_ctx pointer to the memory context \param ldb_ctx pointer to the OpenChange LDB context \param res pointer to the LDB result \param proptag the MAPI property tag to lookup \param PidTagAttr the mapped MAPI property name \return pointer to valid data on success, otherwise NULL */ void *openchangedb_get_special_property(TALLOC_CTX *mem_ctx, struct ldb_context *ldb_ctx, struct ldb_result *res, uint32_t proptag, const char *PidTagAttr) { uint32_t *l; switch (proptag) { case PR_DEPTH: l = talloc_zero(mem_ctx, uint32_t); *l = 0; return (void *)l; } return NULL; } static struct BinaryArray_r *decode_mv_binary(TALLOC_CTX *mem_ctx, const char *str) { const char *start; char *tmp; size_t i, current, len; uint32_t j; struct BinaryArray_r *bin_array; bin_array = talloc_zero(mem_ctx, struct BinaryArray_r); start = str; len = strlen(str); i = 0; while (i < len && start[i] != ';') { i++; } if (i < len) { tmp = talloc_memdup(NULL, start, i + 1); tmp[i] = 0; bin_array->cValues = strtol(tmp, NULL, 16); bin_array->lpbin = talloc_array(bin_array, struct Binary_r, bin_array->cValues); talloc_free(tmp); i++; for (j = 0; j < bin_array->cValues; j++) { current = i; while (i < len && start[i] != ';') { i++; } tmp = talloc_memdup(bin_array, start + current, i - current + 1); tmp[i - current] = 0; i++; if (tmp[0] != 0 && strcmp(tmp, openchangedb_nil_string) != 0) { bin_array->lpbin[j].lpb = (uint8_t *) tmp; bin_array->lpbin[j].cb = ldb_base64_decode((char *) bin_array->lpbin[j].lpb); } else { bin_array->lpbin[j].lpb = talloc_zero(bin_array, uint8_t); bin_array->lpbin[j].cb = 0; } } } return bin_array; } static struct LongArray_r *decode_mv_long(TALLOC_CTX *mem_ctx, const char *str) { const char *start; char *tmp; size_t i, current, len; uint32_t j; struct LongArray_r *long_array; long_array = talloc_zero(mem_ctx, struct LongArray_r); start = str; len = strlen(str); i = 0; while (i < len && start[i] != ';') { i++; } if (i < len) { tmp = talloc_memdup(NULL, start, i + 1); tmp[i] = 0; long_array->cValues = strtol(tmp, NULL, 16); long_array->lpl = talloc_array(long_array, uint32_t, long_array->cValues); talloc_free(tmp); i++; for (j = 0; j < long_array->cValues; j++) { current = i; while (i < len && start[i] != ';') { i++; } tmp = talloc_memdup(long_array, start + current, i - current + 1); tmp[i - current] = 0; i++; long_array->lpl[j] = strtol(tmp, NULL, 16); talloc_free(tmp); } } return long_array; } /** \details Retrieve a MAPI property from a OpenChange LDB result set \param mem_ctx pointer to the memory context \param res pointer to the LDB results \param pos the LDB result index \param proptag the MAPI property tag to lookup \param PidTagAttr the mapped MAPI property name \return valid data pointer on success, otherwise NULL */ void *openchangedb_get_property_data(TALLOC_CTX *mem_ctx, struct ldb_result *res, uint32_t pos, uint32_t proptag, const char *PidTagAttr) { return openchangedb_get_property_data_message(mem_ctx, res->msgs[pos], proptag, PidTagAttr); } /** \details Retrieve a MAPI property from an OpenChange LDB message \param mem_ctx pointer to the memory context \param msg pointer to the LDB message \param proptag the MAPI property tag to lookup \param PidTagAttr the mapped MAPI property name \return valid data pointer on success, otherwise NULL */ void *openchangedb_get_property_data_message(TALLOC_CTX *mem_ctx, struct ldb_message *msg, uint32_t proptag, const char *PidTagAttr) { void *data; const char *str; uint64_t *ll; uint32_t *l; int *b; struct FILETIME *ft; struct Binary_r *bin; struct BinaryArray_r *bin_array; struct LongArray_r *long_array; struct ldb_val val; TALLOC_CTX *local_mem_ctx; switch (proptag & 0xFFFF) { case PT_BOOLEAN: b = talloc_zero(mem_ctx, int); *b = ldb_msg_find_attr_as_bool(msg, PidTagAttr, 0x0); data = (void *)b; break; case PT_LONG: l = talloc_zero(mem_ctx, uint32_t); *l = ldb_msg_find_attr_as_uint(msg, PidTagAttr, 0x0); data = (void *)l; break; case PT_I8: ll = talloc_zero(mem_ctx, uint64_t); *ll = ldb_msg_find_attr_as_uint64(msg, PidTagAttr, 0x0); data = (void *)ll; break; case PT_STRING8: case PT_UNICODE: str = ldb_msg_find_attr_as_string(msg, PidTagAttr, NULL); local_mem_ctx = talloc_zero(NULL, TALLOC_CTX); val = ldb_binary_decode(local_mem_ctx, str); data = (char *) talloc_strndup(mem_ctx, (char *) val.data, val.length); talloc_free(local_mem_ctx); break; case PT_SYSTIME: ft = talloc_zero(mem_ctx, struct FILETIME); ll = talloc_zero(mem_ctx, uint64_t); *ll = ldb_msg_find_attr_as_uint64(msg, PidTagAttr, 0x0); ft->dwLowDateTime = (*ll & 0xffffffff); ft->dwHighDateTime = *ll >> 32; data = (void *)ft; talloc_free(ll); break; case PT_BINARY: str = ldb_msg_find_attr_as_string(msg, PidTagAttr, 0x0); bin = talloc_zero(mem_ctx, struct Binary_r); if (strcmp(str, openchangedb_nil_string) == 0) { bin->lpb = (uint8_t *) talloc_zero(mem_ctx, uint8_t); bin->cb = 0; } else { bin->lpb = (uint8_t *) talloc_strdup(mem_ctx, str); bin->cb = ldb_base64_decode((char *) bin->lpb); } data = (void *)bin; break; case PT_MV_BINARY: str = ldb_msg_find_attr_as_string(msg, PidTagAttr, NULL); bin_array = decode_mv_binary(mem_ctx, str); data = (void *)bin_array; break; case PT_MV_LONG: str = ldb_msg_find_attr_as_string(msg, PidTagAttr, NULL); long_array = decode_mv_long(mem_ctx, str); data = (void *)long_array; break; default: DEBUG(0, ("[%s:%d] Property Type 0x%.4x not supported\n", __FUNCTION__, __LINE__, (proptag & 0xFFFF))); abort(); return NULL; } return data; } /** \details Build a MAPI property suitable for a OpenChange LDB message \param mem_ctx pointer to the memory context \param value the MAPI property \return valid string pointer on success, otherwise NULL */ _PUBLIC_ char *openchangedb_set_folder_property_data(TALLOC_CTX *mem_ctx, struct SPropValue *value) { char *data, *subdata; struct SPropValue *subvalue; NTTIME nt_time; uint32_t i; size_t data_len, subdata_len; struct BinaryArray_r *bin_array; switch (value->ulPropTag & 0xFFFF) { case PT_BOOLEAN: data = talloc_strdup(mem_ctx, value->value.b ? "TRUE" : "FALSE"); break; case PT_LONG: data = talloc_asprintf(mem_ctx, "%d", value->value.l); break; case PT_I8: data = talloc_asprintf(mem_ctx, "%"PRIu64, value->value.d); break; case PT_STRING8: data = talloc_strdup(mem_ctx, value->value.lpszA); break; case PT_UNICODE: data = talloc_strdup(mem_ctx, value->value.lpszW); break; case PT_SYSTIME: nt_time = ((uint64_t) value->value.ft.dwHighDateTime << 32) | value->value.ft.dwLowDateTime; data = talloc_asprintf(mem_ctx, "%"PRIu64, nt_time); break; case PT_BINARY: /* ldb silently prevents empty strings from being added to the db */ if (value->value.bin.cb > 0) data = ldb_base64_encode(mem_ctx, (char *) value->value.bin.lpb, value->value.bin.cb); else data = talloc_strdup(mem_ctx, openchangedb_nil_string); break; case PT_MV_BINARY: bin_array = &value->value.MVbin; data = talloc_asprintf(mem_ctx, "0x%.8x", bin_array->cValues); data_len = strlen(data); for (i = 0; i < bin_array->cValues; i++) { subvalue = talloc_zero(NULL, struct SPropValue); subvalue->ulPropTag = (value->ulPropTag & 0xffff0fff); subvalue->value.bin = bin_array->lpbin[i]; subdata = openchangedb_set_folder_property_data(subvalue, subvalue); subdata_len = strlen(subdata); data = talloc_realloc(mem_ctx, data, char, data_len + subdata_len + 2); *(data + data_len) = ';'; memcpy(data + data_len + 1, subdata, subdata_len); data_len += subdata_len + 1; talloc_free(subvalue); } *(data + data_len) = 0; break; default: DEBUG(0, ("[%s:%d] Property Type 0x%.4x not supported\n", __FUNCTION__, __LINE__, (value->ulPropTag & 0xFFFF))); data = NULL; } return data; } /** \details Allocates a new FolderID and returns it \param ldb_ctx pointer to the openchange LDB context \param fid pointer to the fid value the function returns \return MAPI_E_SUCCESS on success, otherwise MAPI error */ _PUBLIC_ enum MAPISTATUS openchangedb_get_new_folderID(struct ldb_context *ldb_ctx, uint64_t *fid) { TALLOC_CTX *mem_ctx; int ret; struct ldb_result *res; struct ldb_message *msg; const char * const attrs[] = { "*", NULL }; /* Get the current GlobalCount */ mem_ctx = talloc_named(NULL, 0, "get_next_folderID"); ret = ldb_search(ldb_ctx, mem_ctx, &res, ldb_get_root_basedn(ldb_ctx), LDB_SCOPE_SUBTREE, attrs, "(objectClass=server)"); OPENCHANGE_RETVAL_IF(ret != LDB_SUCCESS || !res->count, MAPI_E_NOT_FOUND, mem_ctx); *fid = ldb_msg_find_attr_as_uint64(res->msgs[0], "GlobalCount", 0); /* Update GlobalCount value */ msg = ldb_msg_new(mem_ctx); msg->dn = ldb_dn_copy(msg, ldb_msg_find_attr_as_dn(ldb_ctx, mem_ctx, res->msgs[0], "distinguishedName")); ldb_msg_add_fmt(msg, "GlobalCount", "%"PRIu64, ((*fid) + 1)); msg->elements[0].flags = LDB_FLAG_MOD_REPLACE; ret = ldb_modify(ldb_ctx, msg); OPENCHANGE_RETVAL_IF(ret != LDB_SUCCESS, MAPI_E_NO_SUPPORT, mem_ctx); talloc_free(mem_ctx); *fid = (exchange_globcnt(*fid) << 16) | 0x0001; return MAPI_E_SUCCESS; } /** \details Allocates a batch of new folder ids and returns them \param ldb_ctx pointer to the openchange LDB context \param fid pointer to the fid value the function returns \return MAPI_E_SUCCESS on success, otherwise MAPI error */ _PUBLIC_ enum MAPISTATUS openchangedb_get_new_folderIDs(struct ldb_context *ldb_ctx, TALLOC_CTX *mem_ctx, uint64_t max, struct UI8Array_r **fids_p) { TALLOC_CTX *local_mem_ctx; int ret; struct ldb_result *res; struct ldb_message *msg; const char * const attrs[] = { "*", NULL }; uint64_t fid, count; struct UI8Array_r *fids; /* Get the current GlobalCount */ local_mem_ctx = talloc_named(NULL, 0, "get_next_folderIDs"); ret = ldb_search(ldb_ctx, local_mem_ctx, &res, ldb_get_root_basedn(ldb_ctx), LDB_SCOPE_SUBTREE, attrs, "(objectClass=server)"); OPENCHANGE_RETVAL_IF(ret != LDB_SUCCESS || !res->count, MAPI_E_NOT_FOUND, local_mem_ctx); fid = ldb_msg_find_attr_as_uint64(res->msgs[0], "GlobalCount", 0); fids = talloc_zero(local_mem_ctx, struct UI8Array_r); fids->cValues = max; fids->lpui8 = talloc_array(fids, uint64_t, max); for (count = 0; count < max; count++) { fids->lpui8[count] = (exchange_globcnt(fid + count) << 16) | 0x0001; } /* Update GlobalCount value */ msg = ldb_msg_new(local_mem_ctx); msg->dn = ldb_dn_copy(msg, ldb_msg_find_attr_as_dn(ldb_ctx, local_mem_ctx, res->msgs[0], "distinguishedName")); ldb_msg_add_fmt(msg, "GlobalCount", "%"PRIu64, ((fid) + max)); msg->elements[0].flags = LDB_FLAG_MOD_REPLACE; ret = ldb_modify(ldb_ctx, msg); OPENCHANGE_RETVAL_IF(ret != LDB_SUCCESS, MAPI_E_NO_SUPPORT, local_mem_ctx); *fids_p = fids; (void) talloc_reference(mem_ctx, fids); talloc_free(local_mem_ctx); return MAPI_E_SUCCESS; } /** \details Allocates a new change number and returns it \param ldb_ctx pointer to the openchange LDB context \param cn pointer to the cn value the function returns \return MAPI_E_SUCCESS on success, otherwise MAPI error */ _PUBLIC_ enum MAPISTATUS openchangedb_get_new_changeNumber(struct ldb_context *ldb_ctx, uint64_t *cn) { TALLOC_CTX *mem_ctx; int ret; struct ldb_result *res; struct ldb_message *msg; const char * const attrs[] = { "*", NULL }; /* Get the current GlobalCount */ mem_ctx = talloc_named(NULL, 0, "get_next_changeNumber"); ret = ldb_search(ldb_ctx, mem_ctx, &res, ldb_get_root_basedn(ldb_ctx), LDB_SCOPE_SUBTREE, attrs, "(objectClass=server)"); OPENCHANGE_RETVAL_IF(ret != LDB_SUCCESS || !res->count, MAPI_E_NOT_FOUND, mem_ctx); *cn = ldb_msg_find_attr_as_uint64(res->msgs[0], "ChangeNumber", 1); /* Update GlobalCount value */ msg = ldb_msg_new(mem_ctx); msg->dn = ldb_dn_copy(msg, ldb_msg_find_attr_as_dn(ldb_ctx, mem_ctx, res->msgs[0], "distinguishedName")); ldb_msg_add_fmt(msg, "ChangeNumber", "%"PRIu64, ((*cn) + 1)); msg->elements[0].flags = LDB_FLAG_MOD_REPLACE; ret = ldb_modify(ldb_ctx, msg); OPENCHANGE_RETVAL_IF(ret != LDB_SUCCESS, MAPI_E_NO_SUPPORT, mem_ctx); talloc_free(mem_ctx); *cn = (exchange_globcnt(*cn) << 16) | 0x0001; return MAPI_E_SUCCESS; } /** \details Allocates a batch of new change numbers and returns them \param ldb_ctx pointer to the openchange LDB context \param cn pointer to the cn value the function returns \return MAPI_E_SUCCESS on success, otherwise MAPI error */ _PUBLIC_ enum MAPISTATUS openchangedb_get_new_changeNumbers(struct ldb_context *ldb_ctx, TALLOC_CTX *mem_ctx, uint64_t max, struct UI8Array_r **cns_p) { TALLOC_CTX *local_mem_ctx; int ret; struct ldb_result *res; struct ldb_message *msg; const char * const attrs[] = { "*", NULL }; uint64_t cn, count; struct UI8Array_r *cns; /* Get the current GlobalCount */ local_mem_ctx = talloc_named(NULL, 0, "get_new_changeNumber"); ret = ldb_search(ldb_ctx, local_mem_ctx, &res, ldb_get_root_basedn(ldb_ctx), LDB_SCOPE_SUBTREE, attrs, "(objectClass=server)"); OPENCHANGE_RETVAL_IF(ret != LDB_SUCCESS || !res->count, MAPI_E_NOT_FOUND, local_mem_ctx); cn = ldb_msg_find_attr_as_uint64(res->msgs[0], "ChangeNumber", 1); cns = talloc_zero(local_mem_ctx, struct UI8Array_r); cns->cValues = max; cns->lpui8 = talloc_array(cns, uint64_t, max); for (count = 0; count < max; count++) { cns->lpui8[count] = (exchange_globcnt(cn + count) << 16) | 0x0001; } /* Update GlobalCount value */ msg = ldb_msg_new(local_mem_ctx); msg->dn = ldb_dn_copy(msg, ldb_msg_find_attr_as_dn(ldb_ctx, local_mem_ctx, res->msgs[0], "distinguishedName")); ldb_msg_add_fmt(msg, "ChangeNumber", "%"PRIu64, (cn + max)); msg->elements[0].flags = LDB_FLAG_MOD_REPLACE; ret = ldb_modify(ldb_ctx, msg); OPENCHANGE_RETVAL_IF(ret != LDB_SUCCESS, MAPI_E_NO_SUPPORT, local_mem_ctx); *cns_p = cns; (void) talloc_reference(mem_ctx, cns); talloc_free(local_mem_ctx); return MAPI_E_SUCCESS; } /** \details Returns the change number that will be allocated when openchangedb_get_new_changeNumber is next invoked \param ldb_ctx pointer to the openchange LDB context \param cn pointer to the cn value the function returns \return MAPI_E_SUCCESS on success, otherwise MAPI error */ _PUBLIC_ enum MAPISTATUS openchangedb_get_next_changeNumber(struct ldb_context *ldb_ctx, uint64_t *cn) { TALLOC_CTX *mem_ctx; int ret; struct ldb_result *res; const char * const attrs[] = { "ChangeNumber", NULL }; /* Get the current GlobalCount */ mem_ctx = talloc_named(NULL, 0, "get_next_changeNumber"); ret = ldb_search(ldb_ctx, mem_ctx, &res, ldb_get_root_basedn(ldb_ctx), LDB_SCOPE_SUBTREE, attrs, "(objectClass=server)"); OPENCHANGE_RETVAL_IF(ret != LDB_SUCCESS || !res->count, MAPI_E_NOT_FOUND, mem_ctx); *cn = ldb_msg_find_attr_as_uint64(res->msgs[0], "ChangeNumber", 1); talloc_free(mem_ctx); *cn = (exchange_globcnt(*cn) << 16) | 0x0001; return MAPI_E_SUCCESS; } /** \details Reserve a range of FMID \param ldb_ctx pointer to the openchange LDB context \param fid pointer to the fid value the function returns \return MAPI_E_SUCCESS on success, otherwise MAPI error */ _PUBLIC_ enum MAPISTATUS openchangedb_reserve_fmid_range(struct ldb_context *ldb_ctx, uint64_t range_len, uint64_t *first_fmidp) { TALLOC_CTX *mem_ctx; int ret; struct ldb_result *res; struct ldb_message *msg; uint64_t fmid; const char * const attrs[] = { "*", NULL }; /* Step 1. Get the current GlobalCount */ mem_ctx = talloc_named(NULL, 0, "get_next_folderID"); ret = ldb_search(ldb_ctx, mem_ctx, &res, ldb_get_root_basedn(ldb_ctx), LDB_SCOPE_SUBTREE, attrs, "(objectClass=server)"); OPENCHANGE_RETVAL_IF(ret != LDB_SUCCESS || !res->count, MAPI_E_NOT_FOUND, mem_ctx); fmid = ldb_msg_find_attr_as_uint64(res->msgs[0], "GlobalCount", 0); /* Step 2. Update GlobalCount value */ mem_ctx = talloc_zero(NULL, void); msg = ldb_msg_new(mem_ctx); msg->dn = ldb_dn_copy(msg, ldb_msg_find_attr_as_dn(ldb_ctx, mem_ctx, res->msgs[0], "distinguishedName")); ldb_msg_add_fmt(msg, "GlobalCount", "%"PRIu64, (fmid + range_len)); msg->elements[0].flags = LDB_FLAG_MOD_REPLACE; ret = ldb_modify(ldb_ctx, msg); OPENCHANGE_RETVAL_IF(ret != LDB_SUCCESS, MAPI_E_NO_SUPPORT, mem_ctx); talloc_free(mem_ctx); *first_fmidp = (exchange_globcnt(fmid) << 16) | 0x0001; return MAPI_E_SUCCESS; } /** \details Retrieve a MAPI property value from a folder record \param parent_ctx pointer to the memory context \param ldb_ctx pointer to the openchange LDB context \param proptag the MAPI property tag to retrieve value for \param fid the record folder identifier \param data pointer on pointer to the data the function returns \return MAPI_E_SUCCESS on success, otherwise MAPI_E_NOT_FOUND */ _PUBLIC_ enum MAPISTATUS openchangedb_get_folder_property(TALLOC_CTX *parent_ctx, struct ldb_context *ldb_ctx, uint32_t proptag, uint64_t fid, void **data) { TALLOC_CTX *mem_ctx; struct ldb_result *res = NULL; const char * const attrs[] = { "*", NULL }; const char *PidTagAttr = NULL; int ret; mem_ctx = talloc_named(NULL, 0, "get_folder_property"); /* Step 1. Find PidTagFolderId record */ ret = ldb_search(ldb_ctx, mem_ctx, &res, ldb_get_default_basedn(ldb_ctx), LDB_SCOPE_SUBTREE, attrs, "(PidTagFolderId=%"PRIu64")", fid); OPENCHANGE_RETVAL_IF(ret != LDB_SUCCESS || !res->count, MAPI_E_NOT_FOUND, mem_ctx); /* Step 2. Convert proptag into PidTag attribute */ PidTagAttr = openchangedb_property_get_attribute(proptag); if (!PidTagAttr) { PidTagAttr = openchangedb_unknown_property(mem_ctx, proptag); } /* Step 3. Ensure the element exists */ OPENCHANGE_RETVAL_IF(!ldb_msg_find_element(res->msgs[0], PidTagAttr), MAPI_E_NOT_FOUND, mem_ctx); /* Step 4. Check if this is a "special property" */ *data = openchangedb_get_special_property(parent_ctx, ldb_ctx, res, proptag, PidTagAttr); OPENCHANGE_RETVAL_IF(*data != NULL, MAPI_E_SUCCESS, mem_ctx); /* Step 5. If this is not a "special property" */ *data = openchangedb_get_property_data(parent_ctx, res, 0, proptag, PidTagAttr); OPENCHANGE_RETVAL_IF(*data != NULL, MAPI_E_SUCCESS, mem_ctx); talloc_free(mem_ctx); return MAPI_E_NOT_FOUND; } _PUBLIC_ enum MAPISTATUS openchangedb_set_folder_properties(struct ldb_context *ldb_ctx, uint64_t fid, struct SRow *row) { TALLOC_CTX *mem_ctx; struct ldb_result *res = NULL; char *PidTagAttr = NULL; struct SPropValue *value; const char * const attrs[] = { "*", NULL }; struct ldb_message *msg; char *str_value; time_t unix_time; NTTIME nt_time; uint32_t i; int ret; unix_time = time(NULL); mem_ctx = talloc_named(NULL, 0, "set_folder_property"); /* Step 1. Find PidTagFolderId record */ ret = ldb_search(ldb_ctx, mem_ctx, &res, ldb_get_default_basedn(ldb_ctx), LDB_SCOPE_SUBTREE, attrs, "(PidTagFolderId=%"PRIu64")", fid); OPENCHANGE_RETVAL_IF(ret != LDB_SUCCESS || !res->count, MAPI_E_NOT_FOUND, mem_ctx); /* Step 2. Update GlobalCount value */ msg = ldb_msg_new(mem_ctx); msg->dn = ldb_dn_copy(msg, ldb_msg_find_attr_as_dn(ldb_ctx, mem_ctx, res->msgs[0], "distinguishedName")); for (i = 0; i < row->cValues; i++) { value = row->lpProps + i; switch (value->ulPropTag) { case PR_DEPTH: case PR_SOURCE_KEY: case PR_PARENT_SOURCE_KEY: case PR_CREATION_TIME: case PR_LAST_MODIFICATION_TIME: DEBUG(5, ("Ignored attempt to set handled property %.8x\n", value->ulPropTag)); break; default: /* Step 2. Convert proptag into PidTag attribute */ PidTagAttr = (char *) openchangedb_property_get_attribute(value->ulPropTag); if (!PidTagAttr) { PidTagAttr = openchangedb_unknown_property(mem_ctx, value->ulPropTag); } str_value = openchangedb_set_folder_property_data(mem_ctx, value); if (!str_value) { DEBUG(5, ("Ignored property of unhandled type %.4x\n", (value->ulPropTag & 0xffff))); continue; } ldb_msg_add_string(msg, PidTagAttr, str_value); msg->elements[msg->num_elements-1].flags = LDB_FLAG_MOD_REPLACE; } } /* We set the last modification time */ value = talloc_zero(NULL, struct SPropValue); value->ulPropTag = PR_LAST_MODIFICATION_TIME; unix_to_nt_time(&nt_time, unix_time); value->value.ft.dwLowDateTime = nt_time & 0xffffffff; value->value.ft.dwHighDateTime = nt_time >> 32; str_value = openchangedb_set_folder_property_data(mem_ctx, value); ldb_msg_add_string(msg, "PidTagLastModificationTime", str_value); msg->elements[msg->num_elements-1].flags = LDB_FLAG_MOD_REPLACE; value->ulPropTag = PidTagChangeNumber; openchangedb_get_new_changeNumber(ldb_ctx, (uint64_t *) &value->value.d); str_value = openchangedb_set_folder_property_data(mem_ctx, value); ldb_msg_add_string(msg, "PidTagChangeNumber", str_value); msg->elements[msg->num_elements-1].flags = LDB_FLAG_MOD_REPLACE; talloc_free(value); ret = ldb_modify(ldb_ctx, msg); OPENCHANGE_RETVAL_IF(ret != LDB_SUCCESS, MAPI_E_NO_SUPPORT, mem_ctx); talloc_free(mem_ctx); return MAPI_E_SUCCESS; } /** \details Retrieve a MAPI property from a table (ldb search results) \param parent_ctx pointer to the memory context \param ldb_ctx pointer to the openchange LDB context \param ldb_filter the ldb search string \param proptag the MAPI property tag to retrieve value for \param pos the record position in search results \param data pointer on pointer to the data the function returns \return MAPI_E_SUCCESS on success, otherwise MAPI_E_NOT_FOUND */ _PUBLIC_ enum MAPISTATUS openchangedb_get_table_property(TALLOC_CTX *parent_ctx, struct ldb_context *ldb_ctx, const char *ldb_filter, uint32_t proptag, uint32_t pos, void **data) { TALLOC_CTX *mem_ctx; struct ldb_result *res = NULL; const char * const attrs[] = { "*", NULL }; const char *PidTagAttr = NULL; int ret; mem_ctx = talloc_named(NULL, 0, "get_table_property"); /* Step 1. Fetch table results */ ret = ldb_search(ldb_ctx, mem_ctx, &res, ldb_get_default_basedn(ldb_ctx), LDB_SCOPE_SUBTREE, attrs, ldb_filter, NULL); OPENCHANGE_RETVAL_IF(ret != LDB_SUCCESS || !res->count, MAPI_E_INVALID_OBJECT, mem_ctx); /* Step 2. Ensure position is within search results range */ OPENCHANGE_RETVAL_IF(pos >= res->count, MAPI_E_INVALID_OBJECT, mem_ctx); /* Step 3. Convert proptag into PidTag attribute */ PidTagAttr = openchangedb_property_get_attribute(proptag); if (!PidTagAttr) { PidTagAttr = openchangedb_unknown_property(mem_ctx, proptag); } /* Step 4. Ensure the element exists */ OPENCHANGE_RETVAL_IF(!ldb_msg_find_element(res->msgs[0], PidTagAttr), MAPI_E_NOT_FOUND, mem_ctx); /* Step 5. Check if this is a "special property" */ *data = openchangedb_get_special_property(parent_ctx, ldb_ctx, res, proptag, PidTagAttr); OPENCHANGE_RETVAL_IF(*data != NULL, MAPI_E_SUCCESS, mem_ctx); /* Step 6. Check if this is not a "special property" */ *data = openchangedb_get_property_data(parent_ctx, res, pos, proptag, PidTagAttr); OPENCHANGE_RETVAL_IF(*data != NULL, MAPI_E_SUCCESS, mem_ctx); talloc_free(mem_ctx); return MAPI_E_NOT_FOUND; } /** \details Retrieve the folder ID associated with a given folder name This function looks up the specified foldername (as a PidTagDisplayName) and returns the associated folder ID. Note that folder names are only unique in the context of a parent folder, so the parent folder needs to be provided. \param ldb_ctx pointer to the openchange LDB context \param parent_fid the folder ID of the parent folder \param foldername the name to look up \param fid the folder ID for the folder with the specified name (0 if not found) \return MAPI_E_SUCCESS on success, otherwise MAPI_E_NOT_FOUND */ _PUBLIC_ enum MAPISTATUS openchangedb_get_fid_by_name(struct ldb_context *ldb_ctx, uint64_t parent_fid, const char* foldername, uint64_t *fid) { TALLOC_CTX *mem_ctx; struct ldb_result *res; const char * const attrs[] = { "*", NULL }; int ret; mem_ctx = talloc_named(NULL, 0, "get_fid_by_name"); ret = ldb_search(ldb_ctx, mem_ctx, &res, ldb_get_default_basedn(ldb_ctx), LDB_SCOPE_SUBTREE, attrs, "(&(PidTagParentFolderId=%"PRIu64")(PidTagDisplayName=%s))", parent_fid, foldername); OPENCHANGE_RETVAL_IF(ret != LDB_SUCCESS, MAPI_E_NOT_FOUND, mem_ctx); /* We should only ever get 0 records or 1 record, but there is always a chance that things got confused at some point, so just return one of the records */ OPENCHANGE_RETVAL_IF(res->count < 1, MAPI_E_NOT_FOUND, mem_ctx); *fid = ldb_msg_find_attr_as_uint64(res->msgs[0], "PidTagFolderId", 0); talloc_free(mem_ctx); return MAPI_E_SUCCESS; } /** \details Retrieve the message ID associated with a given subject (normalized) \param ldb_ctx pointer to the openchange LDB context \param parent_fid the folder ID of the parent folder \param subject the normalized subject to look up \param mid the message ID for the message (0 if not found) \return MAPI_E_SUCCESS on success, otherwise MAPI_E_NOT_FOUND */ _PUBLIC_ enum MAPISTATUS openchangedb_get_mid_by_subject(struct ldb_context *ldb_ctx, uint64_t parent_fid, const char *subject, bool mailboxstore, uint64_t *mid) { TALLOC_CTX *mem_ctx; struct ldb_result *res; struct ldb_dn *base_dn; const char * const attrs[] = { "*", NULL }; int ret; mem_ctx = talloc_named(NULL, 0, "get_mid_by_subject"); if (mailboxstore) { base_dn = ldb_get_default_basedn(ldb_ctx); } else { base_dn = ldb_get_root_basedn(ldb_ctx); } ret = ldb_search(ldb_ctx, mem_ctx, &res, base_dn, LDB_SCOPE_SUBTREE, attrs, "(&(PidTagParentFolderId=%"PRIu64")(PidTagNormalizedSubject=%s))", parent_fid, subject); OPENCHANGE_RETVAL_IF(ret != LDB_SUCCESS, MAPI_E_NOT_FOUND, mem_ctx); /* We should only ever get 0 records or 1 record, but there is always a chance that things got confused at some point, so just return one of the records */ OPENCHANGE_RETVAL_IF(res->count < 1, MAPI_E_NOT_FOUND, mem_ctx); *mid = ldb_msg_find_attr_as_uint64(res->msgs[0], "PidTagMessageId", 0); talloc_free(mem_ctx); return MAPI_E_SUCCESS; } _PUBLIC_ enum MAPISTATUS openchangedb_delete_folder(struct ldb_context *ldb_ctx, uint64_t fid) { TALLOC_CTX *mem_ctx; char *dnstr; struct ldb_dn *dn; int retval; enum MAPISTATUS ret; mem_ctx = talloc_zero(NULL, TALLOC_CTX); ret = openchangedb_get_distinguishedName(mem_ctx, ldb_ctx, fid, &dnstr); if (ret != MAPI_E_SUCCESS) { goto end; } dn = ldb_dn_new(mem_ctx, ldb_ctx, dnstr); retval = ldb_delete(ldb_ctx, dn); if (retval == LDB_SUCCESS) { ret = MAPI_E_SUCCESS; } else { ret = MAPI_E_CORRUPT_STORE; } end: talloc_free(mem_ctx); return ret; } /** \details Set the receive folder for a specific message class. \param parent_ctx pointer to the memory context \param ldb_ctx pointer to the openchange LDB context \param recipient pointer to the mailbox's username \param MessageClass message class (e.g. IPM.whatever) to set \param fid folder identifier for the recipient folder for the message class \return MAPI_E_SUCCESS on success, otherwise MAPI_E_NOT_FOUND */ _PUBLIC_ enum MAPISTATUS openchangedb_set_ReceiveFolder(struct ldb_context *ldb_ctx, const char *recipient, const char *MessageClass, uint64_t fid) { TALLOC_CTX *mem_ctx; struct ldb_result *res = NULL; struct ldb_dn *dn; char *dnstr; const char * const attrs[] = { "*", NULL }; int ret; mem_ctx = talloc_named(NULL, 0, "set_ReceiveFolder"); DEBUG(5, ("openchangedb_set_ReceiveFolder, recipient: %s\n", recipient)); DEBUG(5, ("openchangedb_set_ReceiveFolder, MessageClass: %s\n", MessageClass)); DEBUG(5, ("openchangedb_set_ReceiveFolder, fid: 0x%.16"PRIx64"\n", fid)); /* Step 1. Find mailbox DN for the recipient */ ret = ldb_search(ldb_ctx, mem_ctx, &res, ldb_get_default_basedn(ldb_ctx), LDB_SCOPE_SUBTREE, attrs, "CN=%s", recipient); OPENCHANGE_RETVAL_IF(ret != LDB_SUCCESS || !res->count, MAPI_E_NOT_FOUND, mem_ctx); dnstr = talloc_strdup(mem_ctx, ldb_msg_find_attr_as_string(res->msgs[0], "distinguishedName", NULL)); DEBUG(5, ("openchangedb_set_ReceiveFolder, dnstr: %s\n", dnstr)); OPENCHANGE_RETVAL_IF(!dnstr, MAPI_E_NOT_FOUND, mem_ctx); talloc_free(res); dn = ldb_dn_new(mem_ctx, ldb_ctx, dnstr); talloc_free(dnstr); /* Step 2. Search for the MessageClass within user's mailbox */ ret = ldb_search(ldb_ctx, mem_ctx, &res, dn, LDB_SCOPE_SUBTREE, attrs, "(PidTagMessageClass=%s)", MessageClass); DEBUG(5, ("openchangedb_get_ReceiveFolder, res->count: %i\n", res->count)); /* We should never have more than one record with a specific MessageClass */ OPENCHANGE_RETVAL_IF(ret != LDB_SUCCESS || (res->count > 1), MAPI_E_CORRUPT_STORE, mem_ctx); /* Step 3. Delete the old entry if applicable */ if (res->count) { /* we already have an entry for this message class, so delete it before creating the new one */ char *distinguishedName; struct ldb_message *msg; uint64_t folderid = ldb_msg_find_attr_as_uint64(res->msgs[0], "PidTagFolderId", 0x0); DEBUG(6, ("openchangedb_set_ReceiveFolder, fid to delete from: 0x%.16"PRIx64"\n", folderid)); openchangedb_get_distinguishedName(mem_ctx, ldb_ctx, folderid, &distinguishedName); DEBUG(6, ("openchangedb_set_ReceiveFolder, dn to delete from: %s\n", distinguishedName)); dn = ldb_dn_new(mem_ctx, ldb_ctx, distinguishedName); talloc_free(distinguishedName); msg = ldb_msg_new(mem_ctx); msg->dn = ldb_dn_copy(mem_ctx, dn); ldb_msg_add_string(msg, "PidTagMessageClass", MessageClass); msg->elements[0].flags = LDB_FLAG_MOD_DELETE; ret = ldb_modify(ldb_ctx, msg); if (ret != LDB_SUCCESS) { DEBUG(0, ("Failed to delete old message class entry: %s\n", ldb_strerror(ret))); talloc_free(mem_ctx); return MAPI_E_NO_SUPPORT; } } /* Step 4. Create the new entry if applicable */ if (fid != 0x0) { char *distinguishedName; struct ldb_message *msg; openchangedb_get_distinguishedName(mem_ctx, ldb_ctx, fid, &distinguishedName); DEBUG(6, ("openchangedb_set_ReceiveFolder, dn to create in: %s\n", distinguishedName)); dn = ldb_dn_new(mem_ctx, ldb_ctx, distinguishedName); talloc_free(distinguishedName); msg = ldb_msg_new(mem_ctx); msg->dn = ldb_dn_copy(mem_ctx, dn); ldb_msg_add_string(msg, "PidTagMessageClass", MessageClass); msg->elements[0].flags = LDB_FLAG_MOD_ADD; ret = ldb_modify(ldb_ctx, msg); if (ret != LDB_SUCCESS) { DEBUG(0, ("Failed to add message class entry: %s\n", ldb_strerror(ret))); talloc_free(mem_ctx); return MAPI_E_NO_SUPPORT; } } talloc_free(mem_ctx); return MAPI_E_SUCCESS; } _PUBLIC_ enum MAPISTATUS openchangedb_get_fid_from_partial_uri(struct ldb_context *ldb_ctx, const char *partialURI, uint64_t *fid) { TALLOC_CTX *mem_ctx; struct ldb_result *res = NULL; const char * const attrs[] = { "*", NULL }; int ret; mem_ctx = talloc_named(NULL, 0, "get_fid_from_partial_uri"); /* Search mapistoreURI given partial URI */ ret = ldb_search(ldb_ctx, mem_ctx, &res, ldb_get_default_basedn(ldb_ctx), LDB_SCOPE_SUBTREE, attrs, "(MAPIStoreURI=%s)", partialURI); OPENCHANGE_RETVAL_IF(ret != LDB_SUCCESS || !res->count, MAPI_E_NOT_FOUND, mem_ctx); OPENCHANGE_RETVAL_IF(res->count > 1, MAPI_E_COLLISION, mem_ctx); *fid = ldb_msg_find_attr_as_uint64(res->msgs[0], "PidTagFolderId", 0); talloc_free(mem_ctx); return MAPI_E_SUCCESS; } _PUBLIC_ enum MAPISTATUS openchangedb_get_users_from_partial_uri(TALLOC_CTX *parent_ctx, struct ldb_context *ldb_ctx, const char *partialURI, uint32_t *count, char ***MAPIStoreURI, char ***users) { TALLOC_CTX *mem_ctx; struct ldb_result *res = NULL; struct ldb_result *mres = NULL; const char *mailboxDN; struct ldb_dn *dn; const char * const attrs[] = { "*", NULL }; const char *tmp; int i; int ret; /* Sanity checks */ OPENCHANGE_RETVAL_IF(!ldb_ctx, MAPI_E_NOT_INITIALIZED, NULL); OPENCHANGE_RETVAL_IF(!partialURI, MAPI_E_INVALID_PARAMETER, NULL); OPENCHANGE_RETVAL_IF(!count, MAPI_E_INVALID_PARAMETER, NULL); OPENCHANGE_RETVAL_IF(!MAPIStoreURI, MAPI_E_INVALID_PARAMETER, NULL); OPENCHANGE_RETVAL_IF(!users, MAPI_E_INVALID_PARAMETER, NULL); mem_ctx = talloc_named(NULL, 0, "get_users_from_partial_uri"); /* Search mapistoreURI given partial URI */ ret = ldb_search(ldb_ctx, mem_ctx, &res, ldb_get_default_basedn(ldb_ctx), LDB_SCOPE_SUBTREE, attrs, "(MAPIStoreURI=%s)", partialURI); OPENCHANGE_RETVAL_IF(ret != LDB_SUCCESS || !res->count, MAPI_E_NOT_FOUND, mem_ctx); *count = res->count; *MAPIStoreURI = talloc_array(parent_ctx, char *, *count); *users = talloc_array(parent_ctx, char *, *count); for (i = 0; i != *count; i++) { tmp = ldb_msg_find_attr_as_string(res->msgs[i], "MAPIStoreURI", NULL); *MAPIStoreURI[i] = talloc_strdup((TALLOC_CTX *)*MAPIStoreURI, tmp); /* Retrieve the system user name */ mailboxDN = ldb_msg_find_attr_as_string(res->msgs[i], "mailboxDN", NULL); dn = ldb_dn_new(mem_ctx, ldb_ctx, mailboxDN); ret = ldb_search(ldb_ctx, mem_ctx, &mres, dn, LDB_SCOPE_SUBTREE, attrs, "(distinguishedName=%s)", mailboxDN); /* This should NEVER happen */ OPENCHANGE_RETVAL_IF(ret != LDB_SUCCESS || !res->count, MAPI_E_NOT_FOUND, mem_ctx); tmp = ldb_msg_find_attr_as_string(mres->msgs[0], "cn", NULL); *users[i] = talloc_strdup((TALLOC_CTX *)*users, tmp); talloc_free(mres); } talloc_free(mem_ctx); return MAPI_E_SUCCESS; } /** \details Create a folder in openchangedb \param ldb_ctx pointer to the openchangedb LDB context \param username the owner of the mailbox \param systemIdx the id of the mailbox \param fidp a pointer to the fid of the mailbox \return MAPISTORE_SUCCESS on success, otherwise MAPISTORE error */ _PUBLIC_ enum MAPISTATUS openchangedb_create_mailbox(struct ldb_context *ldb_ctx, const char *username, int systemIdx, uint64_t *fidp) { enum MAPISTATUS retval; TALLOC_CTX *mem_ctx; struct ldb_dn *mailboxdn; struct ldb_message *msg; NTTIME now; uint64_t fid, changeNum; struct GUID guid; /* Sanity Checks */ MAPI_RETVAL_IF(!ldb_ctx, MAPI_E_NOT_INITIALIZED, NULL); MAPI_RETVAL_IF(!username, MAPI_E_NOT_INITIALIZED, NULL); unix_to_nt_time(&now, time(NULL)); mem_ctx = talloc_named(NULL, 0, "openchangedb_create_mailbox"); openchangedb_get_new_folderID(ldb_ctx, &fid); openchangedb_get_new_changeNumber(ldb_ctx, &changeNum); /* Retrieve distinguesName for parent folder */ mailboxdn = ldb_dn_copy(mem_ctx, ldb_get_default_basedn(ldb_ctx)); MAPI_RETVAL_IF(!mailboxdn, MAPI_E_NOT_ENOUGH_MEMORY, mem_ctx); ldb_dn_add_child_fmt(mailboxdn, "CN=%s", username); MAPI_RETVAL_IF(!ldb_dn_validate(mailboxdn), MAPI_E_BAD_VALUE, mem_ctx); msg = ldb_msg_new(mem_ctx); MAPI_RETVAL_IF(!msg, MAPI_E_NOT_ENOUGH_MEMORY, mem_ctx); msg->dn = mailboxdn; ldb_msg_add_string(msg, "objectClass", "systemfolder"); ldb_msg_add_string(msg, "objectClass", "container"); ldb_msg_add_string(msg, "ReplicaID", "1"); guid = GUID_random(); ldb_msg_add_fmt(msg, "ReplicaGUID", "%s", GUID_string(mem_ctx, &guid)); guid = GUID_random(); ldb_msg_add_fmt(msg, "MailboxGUID", "%s", GUID_string(mem_ctx, &guid)); ldb_msg_add_string(msg, "cn", username); /* FIXME: PidTagAccess and PidTagRights are user-specific */ ldb_msg_add_string(msg, "PidTagAccess", "63"); ldb_msg_add_string(msg, "PidTagRights", "2043"); ldb_msg_add_fmt(msg, "PidTagDisplayName", "OpenChange Mailbox: %s", username); ldb_msg_add_fmt(msg, "PidTagCreationTime", "%"PRId64, now); ldb_msg_add_fmt(msg, "PidTagLastModificationTime", "%"PRId64, now); ldb_msg_add_string(msg, "PidTagSubFolders", "TRUE"); ldb_msg_add_fmt(msg, "PidTagFolderId", "%"PRIu64, fid); ldb_msg_add_fmt(msg, "PidTagChangeNumber", "%"PRIu64, changeNum); ldb_msg_add_fmt(msg, "PidTagFolderType", "1"); if (systemIdx > -1) { ldb_msg_add_fmt(msg, "SystemIdx", "%d", systemIdx); } ldb_msg_add_fmt(msg, "distinguishedName", "%s", ldb_dn_get_linearized(msg->dn)); msg->elements[0].flags = LDB_FLAG_MOD_ADD; if (ldb_add(ldb_ctx, msg) != LDB_SUCCESS) { retval = MAPI_E_CALL_FAILED; } else { if (fidp) { *fidp = fid; } retval = MAPI_E_SUCCESS; } talloc_free(mem_ctx); return retval; } /** \details Create a folder in openchangedb \param ldb_ctx pointer to the openchangedb LDB context \param parentFolderID the FID of the parent folder \param fid the FID of the folder to create \param MAPIStoreURI the mapistore URI to associate to this folder \param nt_time the creation time of the folder \param changeNumber the change number \return MAPISTORE_SUCCESS on success, otherwise MAPISTORE error */ _PUBLIC_ enum MAPISTATUS openchangedb_create_folder(struct ldb_context *ldb_ctx, uint64_t parentFolderID, uint64_t fid, uint64_t changeNumber, const char *MAPIStoreURI, int systemIdx) { enum MAPISTATUS retval; TALLOC_CTX *mem_ctx; char *dn; char *mailboxDN; char *parentDN; struct ldb_dn *basedn; struct ldb_message *msg; int error; NTTIME now; /* Sanity Checks */ MAPI_RETVAL_IF(!ldb_ctx, MAPI_E_NOT_INITIALIZED, NULL); MAPI_RETVAL_IF(!parentFolderID, MAPI_E_NOT_INITIALIZED, NULL); MAPI_RETVAL_IF(!fid, MAPI_E_NOT_INITIALIZED, NULL); MAPI_RETVAL_IF(!changeNumber, MAPI_E_NOT_INITIALIZED, NULL); unix_to_nt_time(&now, time(NULL)); mem_ctx = talloc_named(NULL, 0, "openchangedb_create_folder"); /* Retrieve distinguesName for parent folder */ retval = openchangedb_get_distinguishedName(mem_ctx, ldb_ctx, parentFolderID, &parentDN); MAPI_RETVAL_IF(retval, retval, mem_ctx); retval = openchangedb_get_mailboxDN(mem_ctx, ldb_ctx, parentFolderID, &mailboxDN); MAPI_RETVAL_IF(retval, retval, mem_ctx); dn = talloc_asprintf(mem_ctx, "CN=%"PRIu64",%s", fid, parentDN); MAPI_RETVAL_IF(!dn, MAPI_E_NOT_ENOUGH_MEMORY, mem_ctx); basedn = ldb_dn_new(mem_ctx, ldb_ctx, dn); talloc_free(dn); MAPI_RETVAL_IF(!ldb_dn_validate(basedn), MAPI_E_BAD_VALUE, mem_ctx); msg = ldb_msg_new(mem_ctx); MAPI_RETVAL_IF(!msg, MAPI_E_NOT_ENOUGH_MEMORY, mem_ctx); msg->dn = ldb_dn_copy(mem_ctx, basedn); ldb_msg_add_string(msg, "objectClass", "systemfolder"); ldb_msg_add_fmt(msg, "cn", "%"PRIu64, fid); ldb_msg_add_string(msg, "FolderType", "1"); ldb_msg_add_string(msg, "PidTagContentUnreadCount", "0"); ldb_msg_add_string(msg, "PidTagContentCount", "0"); ldb_msg_add_string(msg, "PidTagAttributeHidden", "0"); ldb_msg_add_string(msg, "PidTagAttributeSystem", "0"); ldb_msg_add_string(msg, "PidTagAttributeReadOnly", "0"); /* FIXME: PidTagAccess and PidTagRights are user-specific */ ldb_msg_add_string(msg, "PidTagAccess", "63"); ldb_msg_add_string(msg, "PidTagRights", "2043"); ldb_msg_add_fmt(msg, "PidTagFolderType", "1"); ldb_msg_add_fmt(msg, "PidTagCreationTime", "%"PRIu64, now); if (mailboxDN) { ldb_msg_add_string(msg, "mailboxDN", mailboxDN); } if (parentFolderID) { ldb_msg_add_fmt(msg, "PidTagParentFolderId", "%"PRIu64, parentFolderID); } ldb_msg_add_fmt(msg, "PidTagFolderId", "%"PRIu64, fid); ldb_msg_add_fmt(msg, "PidTagChangeNumber", "%"PRIu64, changeNumber); if (MAPIStoreURI) { ldb_msg_add_string(msg, "MAPIStoreURI", MAPIStoreURI); } if (systemIdx > -1) { ldb_msg_add_fmt(msg, "SystemIdx", "%d", systemIdx); } ldb_msg_add_fmt(msg, "distinguishedName", "%s", ldb_dn_get_linearized(msg->dn)); msg->elements[0].flags = LDB_FLAG_MOD_ADD; error = ldb_add(ldb_ctx, msg); switch (error) { case 0: retval = MAPI_E_SUCCESS; break; case 68: retval = MAPI_E_COLLISION; break; default: retval = MAPI_E_CALL_FAILED; } talloc_free(mem_ctx); return retval; } /** \details Retrieve the number of messages within the specified folder \param ldb_ctx pointer to the openchange LDB context \param fid the folder identifier to use for the search \param RowCount pointer to the returned number of results \return MAPI_E_SUCCESS on success, otherwise MAPI_E_NOT_FOUND */ _PUBLIC_ enum MAPISTATUS openchangedb_get_message_count(struct ldb_context *ldb_ctx, uint64_t fid, uint32_t *RowCount, bool fai) { TALLOC_CTX *mem_ctx; struct ldb_result *res; const char * const attrs[] = { "*", NULL }; const char *objectClass; int ret; /* Sanity checks */ OPENCHANGE_RETVAL_IF(!ldb_ctx, MAPI_E_NOT_INITIALIZED, NULL); OPENCHANGE_RETVAL_IF(!RowCount, MAPI_E_INVALID_PARAMETER, NULL); mem_ctx = talloc_named(NULL, 0, "get_message_count"); *RowCount = 0; objectClass = (fai ? "faiMessage" : "systemMessage"); ret = ldb_search(ldb_ctx, mem_ctx, &res, ldb_get_default_basedn(ldb_ctx), LDB_SCOPE_SUBTREE, attrs, "(&(objectClass=%s)(PidTagParentFolderId=%"PRIu64"))", objectClass, fid); printf("ldb error: %s\n", ldb_errstring(ldb_ctx)); OPENCHANGE_RETVAL_IF(ret != LDB_SUCCESS, MAPI_E_NOT_FOUND, mem_ctx); *RowCount = res->count; talloc_free(mem_ctx); return MAPI_E_SUCCESS; } /** \details Retrieve the system idx associated with a folder record \param ldb_ctx pointer to the openchange LDB context \param fid the folder identifier to use for the search \param system_idx_p pointer to the returned value \return MAPI_E_SUCCESS on success, otherwise MAPI_E_NOT_FOUND */ _PUBLIC_ enum MAPISTATUS openchangedb_get_system_idx(struct ldb_context *ldb_ctx, uint64_t fid, int *system_idx_p) { TALLOC_CTX *mem_ctx; struct ldb_result *res = NULL; const char * const attrs[] = { "SystemIdx", NULL }; int ret; mem_ctx = talloc_named(NULL, 0, "get_mapistoreURI"); ret = ldb_search(ldb_ctx, mem_ctx, &res, ldb_get_default_basedn(ldb_ctx), LDB_SCOPE_SUBTREE, attrs, "(PidTagFolderId=%"PRIu64")", fid); OPENCHANGE_RETVAL_IF(ret != LDB_SUCCESS || !res->count, MAPI_E_NOT_FOUND, mem_ctx); *system_idx_p = ldb_msg_find_attr_as_int(res->msgs[0], "SystemIdx", -1); talloc_free(mem_ctx); return MAPI_E_SUCCESS; } openchange-2.0/mapiproxy/libmapiproxy/openchangedb_message.c000066400000000000000000000312451223057412600245250ustar00rootroot00000000000000/* OpenChange Server implementation OpenChangeDB message object implementation Copyright (C) Julien Kerihuel 2011 This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see . */ /** \file openchangedb_message.c \brief OpenChange Dispatcher database message routines */ #include #include "mapiproxy/dcesrv_mapiproxy.h" #include "mapiproxy/libmapistore/mapistore.h" #include "libmapiproxy.h" #include "libmapi/libmapi.h" #include "libmapi/libmapi_private.h" /** \details Initialize and create a message object \param mem_ctx pointer to the memory context to use for allocation \param ldb_ctx pointer to the ldb context \param messageID the identifier of the message to create \param folderID the identifier of the folder where the message is created \param message_object pointer on pointer to the message object to return \return MAPI_E_SUCCESS on success, otherwise MAPI error */ _PUBLIC_ enum MAPISTATUS openchangedb_message_create(TALLOC_CTX *mem_ctx, struct ldb_context *ldb_ctx, uint64_t messageID, uint64_t folderID, bool fai, void **message_object) { enum MAPISTATUS retval; struct openchangedb_message *msg; struct ldb_dn *basedn; char *dn; char *parentDN; char *mailboxDN; int i; /* Sanity checks */ OPENCHANGE_RETVAL_IF(!ldb_ctx, MAPI_E_NOT_INITIALIZED, NULL); OPENCHANGE_RETVAL_IF(!message_object, MAPI_E_NOT_INITIALIZED, NULL); /* Retrieve distinguishedName of parent folder */ retval = openchangedb_get_distinguishedName(mem_ctx, ldb_ctx, folderID, &parentDN); OPENCHANGE_RETVAL_IF(retval, retval, NULL); /* Retrieve mailboxDN of parent folder */ retval = openchangedb_get_mailboxDN(mem_ctx, ldb_ctx, folderID, &mailboxDN); if (retval) { mailboxDN = NULL; } dn = talloc_asprintf(mem_ctx, "CN=%"PRIu64",%s", messageID, parentDN); OPENCHANGE_RETVAL_IF(!dn, MAPI_E_NOT_ENOUGH_MEMORY, NULL); basedn = ldb_dn_new(mem_ctx, ldb_ctx, dn); talloc_free(dn); OPENCHANGE_RETVAL_IF(!ldb_dn_validate(basedn), MAPI_E_BAD_VALUE, NULL); msg = talloc_zero(mem_ctx, struct openchangedb_message); OPENCHANGE_RETVAL_IF(!msg, MAPI_E_NOT_ENOUGH_MEMORY, NULL); msg->status = OPENCHANGEDB_MESSAGE_CREATE; msg->folderID = folderID; msg->messageID = messageID; msg->ldb_ctx = ldb_ctx; msg->msg = NULL; msg->res = NULL; msg->msg = ldb_msg_new((TALLOC_CTX *)msg); OPENCHANGE_RETVAL_IF(!msg->msg, MAPI_E_NOT_ENOUGH_MEMORY, msg); msg->msg->dn = ldb_dn_copy((TALLOC_CTX *)msg->msg, basedn); /* Add openchangedb required attributes */ ldb_msg_add_string(msg->msg, "objectClass", fai ? "faiMessage" : "systemMessage"); ldb_msg_add_fmt(msg->msg, "cn", "%"PRIu64, messageID); ldb_msg_add_fmt(msg->msg, "PidTagParentFolderId", "%"PRIu64, folderID); ldb_msg_add_fmt(msg->msg, "PidTagMessageId", "%"PRIu64, messageID); ldb_msg_add_fmt(msg->msg, "distinguishedName", "%s", ldb_dn_get_linearized(msg->msg->dn)); if (mailboxDN) { ldb_msg_add_string(msg->msg, "mailboxDN", mailboxDN); } /* Add required properties as described in [MS_OXCMSG] 3.2.5.2 */ ldb_msg_add_string(msg->msg, "PidTagDisplayBcc", ""); ldb_msg_add_string(msg->msg, "PidTagDisplayCc", ""); ldb_msg_add_string(msg->msg, "PidTagDisplayTo", ""); /* PidTagMessageSize */ /* PidTagSecurityDescriptor */ /* ldb_msg_add_string(msg->msg, "PidTagCreationTime", ""); */ /* ldb_msg_add_string(msg->msg, "PidTagLastModificationTime", ""); */ /* PidTagSearchKey */ /* PidTagMessageLocalId */ /* PidTagCreatorName */ /* PidTagCreatorEntryId */ ldb_msg_add_fmt(msg->msg, "PidTagHasNamedProperties", "%d", 0x0); /* PidTagLocaleId same as PidTagMessageLocaleId */ /* PidTagLocalCommitTime same as PidTagCreationTime */ /* Set LDB flag */ for (i = 0; i < msg->msg->num_elements; i++) { msg->msg->elements[i].flags = LDB_FLAG_MOD_ADD; } *message_object = (void *)msg; return MAPI_E_SUCCESS; } /** \details Save (commit) message in openchangedb database \param msg the message object \param SaveFlags flags associated to the save operation \return MAPI_E_SUCCESS on success, otherwise MAPI error */ _PUBLIC_ enum MAPISTATUS openchangedb_message_save(void *_msg, uint8_t SaveFlags) { struct openchangedb_message *msg = (struct openchangedb_message *)_msg; /* Sanity checks */ OPENCHANGE_RETVAL_IF(!msg, MAPI_E_NOT_INITIALIZED, NULL); OPENCHANGE_RETVAL_IF(!msg->ldb_ctx, MAPI_E_NOT_INITIALIZED, NULL); switch (msg->status) { case OPENCHANGEDB_MESSAGE_CREATE: OPENCHANGE_RETVAL_IF(!msg->msg, MAPI_E_NOT_INITIALIZED, NULL); if (ldb_add(msg->ldb_ctx, msg->msg) != LDB_SUCCESS) { return MAPI_E_CALL_FAILED; } break; case OPENCHANGEDB_MESSAGE_OPEN: if (ldb_modify(msg->ldb_ctx, msg->res->msgs[0]) != LDB_SUCCESS) { return MAPI_E_CALL_FAILED; } break; } /* FIXME: Deal with SaveFlags */ return MAPI_E_SUCCESS; } /** \details Initialize and open a message object \param mem_ctx pointer to the memory context to use for allocation \param ldb_ctx pointer to the ldb context \param messageID the identifier of the message to open \param folderID the identifier of the folder where the message is stored \param message_object pointer on pointer to the message object to return \param msgp pointer on pointer to the mapistore message to return \return MAPI_E_SUCCESS on success, otherwise MAPISTORE error */ _PUBLIC_ enum MAPISTATUS openchangedb_message_open(TALLOC_CTX *mem_ctx, struct ldb_context *ldb_ctx, uint64_t messageID, uint64_t folderID, void **message_object, void **msgp) { struct mapistore_message *mmsg; struct openchangedb_message *msg; const char * const attrs[] = { "*", NULL }; int ret; char *ldb_filter; /* Sanity checks */ OPENCHANGE_RETVAL_IF(!ldb_ctx, MAPI_E_NOT_INITIALIZED, NULL); OPENCHANGE_RETVAL_IF(!message_object, MAPI_E_NOT_INITIALIZED, NULL); msg = talloc_zero(mem_ctx, struct openchangedb_message); if (!msg) { return MAPI_E_NOT_ENOUGH_MEMORY; } printf("openchangedb_message_open: folderID=%"PRIu64" messageID=%"PRIu64"\n", folderID, messageID); msg->status = OPENCHANGEDB_MESSAGE_OPEN; msg->folderID = folderID; msg->messageID = messageID; msg->ldb_ctx = ldb_ctx; msg->msg = NULL; msg->res = NULL; /* Open the message and load results */ ldb_filter = talloc_asprintf(mem_ctx, "(&(PidTagParentFolderId=%"PRIu64")(PidTagMessageId=%"PRIu64"))", folderID, messageID); ret = ldb_search(ldb_ctx, (TALLOC_CTX *)msg, &msg->res, ldb_get_default_basedn(ldb_ctx), LDB_SCOPE_SUBTREE, attrs, ldb_filter, NULL); printf("We have found: %d messages for ldb_filter = %s\n", msg->res->count, ldb_filter); talloc_free(ldb_filter); OPENCHANGE_RETVAL_IF(ret != LDB_SUCCESS || !msg->res->count, MAPI_E_NOT_FOUND, msg); *message_object = (void *)msg; if (msgp) { mmsg = talloc_zero(mem_ctx, struct mapistore_message); mmsg->subject_prefix = NULL; mmsg->normalized_subject = (char *)ldb_msg_find_attr_as_string(msg->res->msgs[0], "PidTagNormalizedSubject", NULL); mmsg->columns = NULL; mmsg->recipients_count = 0; mmsg->recipients = NULL; *msgp = (void *)mmsg; } return MAPI_E_SUCCESS; } /** \details Retrieve a property on a LDB message \param mem_ctx pointer to the memory context \param message_object the openchangedb message to retrieve data from \param proptag the MAPI property tag to lookup \param data pointer on pointer to the data to return \return MAPI_E_SUCCESS on success, otherwise MAPI error */ _PUBLIC_ enum MAPISTATUS openchangedb_message_get_property(TALLOC_CTX *mem_ctx, void *message_object, uint32_t proptag, void **data) { struct openchangedb_message *msg; struct ldb_message *message; char *PidTagAttr = NULL; bool tofree = false; /* Sanity checks */ OPENCHANGE_RETVAL_IF(!message_object, MAPI_E_NOT_INITIALIZED, NULL); OPENCHANGE_RETVAL_IF(!data, MAPI_E_NOT_INITIALIZED, NULL); msg = (struct openchangedb_message *)message_object; /* Get results from correct location */ switch (msg->status) { case OPENCHANGEDB_MESSAGE_CREATE: OPENCHANGE_RETVAL_IF(!msg->msg, MAPI_E_NOT_INITIALIZED, NULL); message = msg->msg; break; case OPENCHANGEDB_MESSAGE_OPEN: OPENCHANGE_RETVAL_IF(!msg->res, MAPI_E_NOT_INITIALIZED, NULL); OPENCHANGE_RETVAL_IF(!msg->res->count, MAPI_E_NOT_INITIALIZED, NULL); message = msg->res->msgs[0]; break; } /* Turn property into PidTagAttr */ PidTagAttr = (char *) openchangedb_property_get_attribute(proptag); if (!PidTagAttr) { tofree = true; PidTagAttr = talloc_asprintf(mem_ctx, "%.8x", proptag); } /* Ensure the element exists */ OPENCHANGE_RETVAL_IF(!ldb_msg_find_element(message, PidTagAttr), MAPI_E_NOT_FOUND, (tofree == true) ? PidTagAttr : NULL); /* Retrieve data */ *data = openchangedb_get_property_data_message(mem_ctx, message, proptag, PidTagAttr); OPENCHANGE_RETVAL_IF(*data != NULL, MAPI_E_SUCCESS, (tofree == true) ? PidTagAttr : NULL); if (tofree == true) { talloc_free(PidTagAttr); } return MAPI_E_NOT_FOUND; } /** \details Set a list of properties on a message \param mem_ctx pointer to the memory context \param message_object pointer to the openchangedb message object \param row pointer to the SRow structure holding the array of properties to set on the message \return MAPI_E_SUCCESS on success, otherwise MAPI errors. */ _PUBLIC_ enum MAPISTATUS openchangedb_message_set_properties(TALLOC_CTX *mem_ctx, void *message_object, struct SRow *row) { struct openchangedb_message *msg = (struct openchangedb_message *) message_object; struct ldb_message *message; struct ldb_message_element *element; char *PidTagAttr = NULL; struct SPropValue value; char *str_value; int i; bool tofree = false; DEBUG(5, ("openchangedb_message_set_properties\n")); /* Sanity checks */ OPENCHANGE_RETVAL_IF(!msg, MAPI_E_NOT_INITIALIZED, NULL); OPENCHANGE_RETVAL_IF(!row, MAPI_E_NOT_INITIALIZED, NULL); /* Get results from correct location */ switch (msg->status) { case OPENCHANGEDB_MESSAGE_CREATE: OPENCHANGE_RETVAL_IF(!msg->msg, MAPI_E_NOT_INITIALIZED, NULL); message = msg->msg; break; case OPENCHANGEDB_MESSAGE_OPEN: OPENCHANGE_RETVAL_IF(!msg->res, MAPI_E_NOT_INITIALIZED, NULL); OPENCHANGE_RETVAL_IF(!msg->res->count, MAPI_E_NOT_INITIALIZED, NULL); message = msg->res->msgs[0]; break; } for (i = 0; i < row->cValues; i++) { tofree = false; value = row->lpProps[i]; switch (value.ulPropTag) { case PR_DEPTH: case PR_SOURCE_KEY: case PR_PARENT_SOURCE_KEY: case PR_CHANGE_KEY: DEBUG(5, ("Ignored attempt to set handled property %.8x\n", value.ulPropTag)); break; default: /* Convert proptag into PidTag attribute */ PidTagAttr = (char *) openchangedb_property_get_attribute(value.ulPropTag); if (!PidTagAttr) { PidTagAttr = talloc_asprintf(mem_ctx, "%.8x", value.ulPropTag); tofree = true; } str_value = openchangedb_set_folder_property_data((TALLOC_CTX *)message, &value); if (!str_value) { DEBUG(5, ("Ignored property of unhandled type %.4x\n", (value.ulPropTag & 0xFFFF))); continue; } else { element = ldb_msg_find_element(message, PidTagAttr); if (!element) { /* Case where the element doesn't exist */ ldb_msg_add_string(message, PidTagAttr, str_value); message->elements[message->num_elements - 1].flags = LDB_FLAG_MOD_ADD; } else { switch (msg->status) { case OPENCHANGEDB_MESSAGE_CREATE: ldb_msg_remove_element(message, element); ldb_msg_add_string(message, PidTagAttr, str_value); message->elements[message->num_elements - 1].flags = LDB_FLAG_MOD_ADD; break; case OPENCHANGEDB_MESSAGE_OPEN: if (element->flags == LDB_FLAG_MOD_ADD) { ldb_msg_remove_element(message, element); ldb_msg_add_string(message, PidTagAttr, str_value); message->elements[message->num_elements - 1].flags = LDB_FLAG_MOD_ADD; } else { ldb_msg_remove_element(message, element); ldb_msg_add_string(message, PidTagAttr, str_value); message->elements[message->num_elements - 1].flags = LDB_FLAG_MOD_REPLACE; } break; } } } if (tofree == true) { talloc_free((char *)PidTagAttr); } break; } } DEBUG(5, ("openchangedb_message_set_properties end\n")); return MAPI_E_SUCCESS; } openchange-2.0/mapiproxy/libmapiproxy/openchangedb_property.c000066400000000000000000001755371223057412600250020ustar00rootroot00000000000000 /* Automatically generated by script/makepropslist.py. Do not edit */ #include "mapiproxy/dcesrv_mapiproxy.h" #include "libmapiproxy.h" #include "libmapi/libmapi.h" #include "libmapi/libmapi_private.h" struct pidtags { uint32_t proptag; const char *pidtag; }; static struct pidtags pidtags[] = { { PidTag7BitDisplayName, "PidTag7BitDisplayName" }, { PidTagAccess, "PidTagAccess" }, { PidTagAccessLevel, "PidTagAccessLevel" }, { PidTagAccount, "PidTagAccount" }, { PidTagAdditionalRenEntryIds, "PidTagAdditionalRenEntryIds" }, { PidTagAdditionalRenEntryIdsEx, "PidTagAdditionalRenEntryIdsEx" }, { PidTagAddressBookAuthorizedSenders, "PidTagAddressBookAuthorizedSenders" }, { PidTagAddressBookContainerId, "PidTagAddressBookContainerId" }, { PidTagAddressBookDeliveryContentLength, "PidTagAddressBookDeliveryContentLength" }, { PidTagAddressBookDisplayTypeExtended, "PidTagAddressBookDisplayTypeExtended" }, { PidTagAddressBookDistributionListExternalMemberCount, "PidTagAddressBookDistributionListExternalMemberCount" }, { PidTagAddressBookDistributionListMemberCount, "PidTagAddressBookDistributionListMemberCount" }, { PidTagAddressBookDistributionListMemberSubmitAccepted, "PidTagAddressBookDistributionListMemberSubmitAccepted" }, { PidTagAddressBookDistributionListMemberSubmitRejected, "PidTagAddressBookDistributionListMemberSubmitRejected" }, { PidTagAddressBookDistributionListRejectMessagesFromDLMembers, "PidTagAddressBookDistributionListRejectMessagesFromDLMembers" }, { PidTagAddressBookEntryId, "PidTagAddressBookEntryId" }, { PidTagAddressBookExtensionAttribute1, "PidTagAddressBookExtensionAttribute1" }, { PidTagAddressBookExtensionAttribute15, "PidTagAddressBookExtensionAttribute15" }, { PidTagAddressBookFolderPathname, "PidTagAddressBookFolderPathname" }, { PidTagAddressBookHierarchicalChildDepartments, "PidTagAddressBookHierarchicalChildDepartments" }, { PidTagAddressBookHierarchicalDepartmentMembers, "PidTagAddressBookHierarchicalDepartmentMembers" }, { PidTagAddressBookHierarchicalIsHierarchicalGroup, "PidTagAddressBookHierarchicalIsHierarchicalGroup" }, { PidTagAddressBookHierarchicalParentDepartment, "PidTagAddressBookHierarchicalParentDepartment" }, { PidTagAddressBookHierarchicalRootDepartment, "PidTagAddressBookHierarchicalRootDepartment" }, { PidTagAddressBookHierarchicalShowInDepartments, "PidTagAddressBookHierarchicalShowInDepartments" }, { PidTagAddressBookHomeMessageDatabase, "PidTagAddressBookHomeMessageDatabase" }, { PidTagAddressBookIsMaster, "PidTagAddressBookIsMaster" }, { PidTagAddressBookIsMemberOfDistributionList, "PidTagAddressBookIsMemberOfDistributionList" }, { PidTagAddressBookManageDistributionList, "PidTagAddressBookManageDistributionList" }, { PidTagAddressBookManager, "PidTagAddressBookManager" }, { PidTagAddressBookManagerDistinguishedName, "PidTagAddressBookManagerDistinguishedName" }, { PidTagAddressBookMember, "PidTagAddressBookMember" }, { PidTagAddressBookMessageId, "PidTagAddressBookMessageId" }, { PidTagAddressBookModerationEnabled, "PidTagAddressBookModerationEnabled" }, { PidTagAddressBookNetworkAddress, "PidTagAddressBookNetworkAddress" }, { PidTagAddressBookObjectDistinguishedName, "PidTagAddressBookObjectDistinguishedName" }, { PidTagAddressBookObjectGuid, "PidTagAddressBookObjectGuid" }, { PidTagAddressBookOrganizationalUnitRootDistinguishedName, "PidTagAddressBookOrganizationalUnitRootDistinguishedName" }, { PidTagAddressBookOwner, "PidTagAddressBookOwner" }, { PidTagAddressBookOwnerBackLink, "PidTagAddressBookOwnerBackLink" }, { PidTagAddressBookParentEntryId, "PidTagAddressBookParentEntryId" }, { PidTagAddressBookPhoneticCompanyName, "PidTagAddressBookPhoneticCompanyName" }, { PidTagAddressBookPhoneticDepartmentName, "PidTagAddressBookPhoneticDepartmentName" }, { PidTagAddressBookPhoneticDisplayName, "PidTagAddressBookPhoneticDisplayName" }, { PidTagAddressBookPhoneticGivenName, "PidTagAddressBookPhoneticGivenName" }, { PidTagAddressBookPhoneticSurname, "PidTagAddressBookPhoneticSurname" }, { PidTagAddressBookProxyAddresses, "PidTagAddressBookProxyAddresses" }, { PidTagAddressBookPublicDelegates, "PidTagAddressBookPublicDelegates" }, { PidTagAddressBookReports, "PidTagAddressBookReports" }, { PidTagAddressBookRoomCapacity, "PidTagAddressBookRoomCapacity" }, { PidTagAddressBookRoomContainers, "PidTagAddressBookRoomContainers" }, { PidTagAddressBookRoomDescription, "PidTagAddressBookRoomDescription" }, { PidTagAddressBookSenderHintTranslations, "PidTagAddressBookSenderHintTranslations" }, { PidTagAddressBookSeniorityIndex, "PidTagAddressBookSeniorityIndex" }, { PidTagAddressBookTargetAddress, "PidTagAddressBookTargetAddress" }, { PidTagAddressBookUnauthorizedSenders, "PidTagAddressBookUnauthorizedSenders" }, { PidTagAddressBookX509Certificate, "PidTagAddressBookX509Certificate" }, { PidTagAddressType, "PidTagAddressType" }, { PidTagAlternateRecipientAllowed, "PidTagAlternateRecipientAllowed" }, { PidTagAnr, "PidTagAnr" }, { PidTagArchiveDate, "PidTagArchiveDate" }, { PidTagArchivePeriod, "PidTagArchivePeriod" }, { PidTagArchiveTag, "PidTagArchiveTag" }, { PidTagAssistant, "PidTagAssistant" }, { PidTagAssistantTelephoneNumber, "PidTagAssistantTelephoneNumber" }, { PidTagAssociated, "PidTagAssociated" }, { PidTagAssociatedContentCount, "PidTagAssociatedContentCount" }, { PidTagAttachAdditionalInformation, "PidTagAttachAdditionalInformation" }, { PidTagAttachContentBase, "PidTagAttachContentBase" }, { PidTagAttachContentId, "PidTagAttachContentId" }, { PidTagAttachContentLocation, "PidTagAttachContentLocation" }, { PidTagAttachDataBinary, "PidTagAttachDataBinary" }, { PidTagAttachDataObject, "PidTagAttachDataObject" }, { PidTagAttachEncoding, "PidTagAttachEncoding" }, { PidTagAttachExtension, "PidTagAttachExtension" }, { PidTagAttachFilename, "PidTagAttachFilename" }, { PidTagAttachFlags, "PidTagAttachFlags" }, { PidTagAttachLongFilename, "PidTagAttachLongFilename" }, { PidTagAttachLongPathname, "PidTagAttachLongPathname" }, { PidTagAttachMethod, "PidTagAttachMethod" }, { PidTagAttachMimeTag, "PidTagAttachMimeTag" }, { PidTagAttachNumber, "PidTagAttachNumber" }, { PidTagAttachPathname, "PidTagAttachPathname" }, { PidTagAttachPayloadClass, "PidTagAttachPayloadClass" }, { PidTagAttachPayloadProviderGuidString, "PidTagAttachPayloadProviderGuidString" }, { PidTagAttachRendering, "PidTagAttachRendering" }, { PidTagAttachSize, "PidTagAttachSize" }, { PidTagAttachTag, "PidTagAttachTag" }, { PidTagAttachTransportName, "PidTagAttachTransportName" }, { PidTagAttachmentContactPhoto, "PidTagAttachmentContactPhoto" }, { PidTagAttachmentFlags, "PidTagAttachmentFlags" }, { PidTagAttachmentHidden, "PidTagAttachmentHidden" }, { PidTagAttachmentLinkId, "PidTagAttachmentLinkId" }, { PidTagAttributeHidden, "PidTagAttributeHidden" }, { PidTagAttributeReadOnly, "PidTagAttributeReadOnly" }, { PidTagAttributeSystem, "PidTagAttributeSystem" }, { PidTagAutoForwardComment, "PidTagAutoForwardComment" }, { PidTagAutoForwarded, "PidTagAutoForwarded" }, { PidTagAutoResponseSuppress, "PidTagAutoResponseSuppress" }, { PidTagBirthday, "PidTagBirthday" }, { PidTagBlockStatus, "PidTagBlockStatus" }, { PidTagBody, "PidTagBody" }, { PidTagBodyContentId, "PidTagBodyContentId" }, { PidTagBodyContentLocation, "PidTagBodyContentLocation" }, { PidTagBodyHtml, "PidTagBodyHtml" }, { PidTagBusiness2TelephoneNumber, "PidTagBusiness2TelephoneNumber" }, { PidTagBusiness2TelephoneNumbers, "PidTagBusiness2TelephoneNumbers" }, { PidTagBusinessFaxNumber, "PidTagBusinessFaxNumber" }, { PidTagBusinessHomePage, "PidTagBusinessHomePage" }, { PidTagBusinessTelephoneNumber, "PidTagBusinessTelephoneNumber" }, { PidTagCallId, "PidTagCallId" }, { PidTagCallbackTelephoneNumber, "PidTagCallbackTelephoneNumber" }, { PidTagCarTelephoneNumber, "PidTagCarTelephoneNumber" }, { PidTagCdoRecurrenceid, "PidTagCdoRecurrenceid" }, { PidTagChangeKey, "PidTagChangeKey" }, { PidTagChangeNotificationGuid, "PidTagChangeNotificationGuid" }, { PidTagChangeNumber, "PidTagChangeNumber" }, { PidTagChildrensNames, "PidTagChildrensNames" }, { PidTagClientActions, "PidTagClientActions" }, { PidTagClientSubmitTime, "PidTagClientSubmitTime" }, { PidTagCnsetRead, "PidTagCnsetRead" }, { PidTagCnsetSeen, "PidTagCnsetSeen" }, { PidTagCnsetSeenFAI, "PidTagCnsetSeenFAI" }, { PidTagCodePageId, "PidTagCodePageId" }, { PidTagComment, "PidTagComment" }, { PidTagCompanyMainTelephoneNumber, "PidTagCompanyMainTelephoneNumber" }, { PidTagCompanyName, "PidTagCompanyName" }, { PidTagComputerNetworkName, "PidTagComputerNetworkName" }, { PidTagConflictEntryId, "PidTagConflictEntryId" }, { PidTagConflictItems, "PidTagConflictItems" }, { PidTagContainerClass, "PidTagContainerClass" }, { PidTagContainerContents, "PidTagContainerContents" }, { PidTagContainerFlags, "PidTagContainerFlags" }, { PidTagContainerHierarchy, "PidTagContainerHierarchy" }, { PidTagContentCount, "PidTagContentCount" }, { PidTagContentFilterPhishingConfidenceLevel, "PidTagContentFilterPhishingConfidenceLevel" }, { PidTagContentFilterSpamConfidenceLevel, "PidTagContentFilterSpamConfidenceLevel" }, { PidTagContentUnreadCount, "PidTagContentUnreadCount" }, { PidTagConversationId, "PidTagConversationId" }, { PidTagConversationIndex, "PidTagConversationIndex" }, { PidTagConversationIndexTracking, "PidTagConversationIndexTracking" }, { PidTagConversationTopic, "PidTagConversationTopic" }, { PidTagCountry, "PidTagCountry" }, { PidTagCreationTime, "PidTagCreationTime" }, { PidTagCreatorEntryId, "PidTagCreatorEntryId" }, { PidTagCreatorName, "PidTagCreatorName" }, { PidTagCreatorSId, "PidTagCreatorSId" }, { PidTagCreatorSimpleDisplayName, "PidTagCreatorSimpleDisplayName" }, { PidTagCustomerId, "PidTagCustomerId" }, { PidTagDamBackPatched, "PidTagDamBackPatched" }, { PidTagDamOriginalEntryId, "PidTagDamOriginalEntryId" }, { PidTagDefaultFormName, "PidTagDefaultFormName" }, { PidTagDefaultPostMessageClass, "PidTagDefaultPostMessageClass" }, { PidTagDefaultViewEntryId, "PidTagDefaultViewEntryId" }, { PidTagDeferredActionMessageOriginalEntryId, "PidTagDeferredActionMessageOriginalEntryId" }, { PidTagDeferredDeliveryTime, "PidTagDeferredDeliveryTime" }, { PidTagDeferredSendNumber, "PidTagDeferredSendNumber" }, { PidTagDeferredSendTime, "PidTagDeferredSendTime" }, { PidTagDeferredSendUnits, "PidTagDeferredSendUnits" }, { PidTagDelegateFlags, "PidTagDelegateFlags" }, { PidTagDelegatedByRule, "PidTagDelegatedByRule" }, { PidTagDeleteAfterSubmit, "PidTagDeleteAfterSubmit" }, { PidTagDeletedCountTotal, "PidTagDeletedCountTotal" }, { PidTagDeletedOn, "PidTagDeletedOn" }, { PidTagDepartmentName, "PidTagDepartmentName" }, { PidTagDepth, "PidTagDepth" }, { PidTagDesignInProgress, "PidTagDesignInProgress" }, { PidTagDisplayBcc, "PidTagDisplayBcc" }, { PidTagDisplayCc, "PidTagDisplayCc" }, { PidTagDisplayName, "PidTagDisplayName" }, { PidTagDisplayNamePrefix, "PidTagDisplayNamePrefix" }, { PidTagDisplayTo, "PidTagDisplayTo" }, { PidTagDisplayType, "PidTagDisplayType" }, { PidTagDisplayTypeEx, "PidTagDisplayTypeEx" }, { PidTagEcWarning, "PidTagEcWarning" }, { PidTagEmailAddress, "PidTagEmailAddress" }, { PidTagEndAttach, "PidTagEndAttach" }, { PidTagEndDate, "PidTagEndDate" }, { PidTagEndEmbed, "PidTagEndEmbed" }, { PidTagEndFolder, "PidTagEndFolder" }, { PidTagEndMessage, "PidTagEndMessage" }, { PidTagEndToRecip, "PidTagEndToRecip" }, { PidTagEntryId, "PidTagEntryId" }, { PidTagExceptionEndTime, "PidTagExceptionEndTime" }, { PidTagExceptionReplaceTime, "PidTagExceptionReplaceTime" }, { PidTagExceptionStartTime, "PidTagExceptionStartTime" }, { PidTagExchangeNTSecurityDescriptor, "PidTagExchangeNTSecurityDescriptor" }, { PidTagExpiryNumber, "PidTagExpiryNumber" }, { PidTagExpiryTime, "PidTagExpiryTime" }, { PidTagExpiryUnits, "PidTagExpiryUnits" }, { PidTagExtendedACLData, "PidTagExtendedACLData" }, { PidTagExtendedFolderFlags, "PidTagExtendedFolderFlags" }, { PidTagExtendedRuleMessageActions, "PidTagExtendedRuleMessageActions" }, { PidTagExtendedRuleMessageCondition, "PidTagExtendedRuleMessageCondition" }, { PidTagExtendedRuleSizeLimit, "PidTagExtendedRuleSizeLimit" }, { PidTagFXDelProp, "PidTagFXDelProp" }, { PidTagFXErrorInfo, "PidTagFXErrorInfo" }, { PidTagFaxNumberOfPages, "PidTagFaxNumberOfPages" }, { PidTagFlagCompleteTime, "PidTagFlagCompleteTime" }, { PidTagFlagStatus, "PidTagFlagStatus" }, { PidTagFlatUrlName, "PidTagFlatUrlName" }, { PidTagFolderAssociatedContents, "PidTagFolderAssociatedContents" }, { PidTagFolderFlags, "PidTagFolderFlags" }, { PidTagFolderId, "PidTagFolderId" }, { PidTagFolderType, "PidTagFolderType" }, { PidTagFolderViewList, "PidTagFolderViewList" }, { PidTagFolderViewsOnly, "PidTagFolderViewsOnly" }, { PidTagFolderExtendedViewInfo, "PidTagFolderExtendedViewInfo" }, { PidTagFolderWebViewInfo, "PidTagFolderWebViewInfo" }, { PidTagFollowupIcon, "PidTagFollowupIcon" }, { PidTagFreeBusyCountMonths, "PidTagFreeBusyCountMonths" }, { PidTagFreeBusyEntryIds, "PidTagFreeBusyEntryIds" }, { PidTagFreeBusyMessageEmailAddress, "PidTagFreeBusyMessageEmailAddress" }, { PidTagFreeBusyPublishEnd, "PidTagFreeBusyPublishEnd" }, { PidTagFreeBusyPublishStart, "PidTagFreeBusyPublishStart" }, { PidTagFreeBusyRangeTimestamp, "PidTagFreeBusyRangeTimestamp" }, { PidTagFtpSite, "PidTagFtpSite" }, { PidTagGatewayNeedsToRefresh, "PidTagGatewayNeedsToRefresh" }, { PidTagGender, "PidTagGender" }, { PidTagGeneration, "PidTagGeneration" }, { PidTagGivenName, "PidTagGivenName" }, { PidTagGovernmentIdNumber, "PidTagGovernmentIdNumber" }, { PidTagHasAttachments, "PidTagHasAttachments" }, { PidTagHasDeferredActionMessages, "PidTagHasDeferredActionMessages" }, { PidTagHasNamedProperties, "PidTagHasNamedProperties" }, { PidTagHasRules, "PidTagHasRules" }, { PidTagHierarchyChangeNumber, "PidTagHierarchyChangeNumber" }, { PidTagHobbies, "PidTagHobbies" }, { PidTagHome2TelephoneNumber, "PidTagHome2TelephoneNumber" }, { PidTagHome2TelephoneNumbers, "PidTagHome2TelephoneNumbers" }, { PidTagHomeAddressCity, "PidTagHomeAddressCity" }, { PidTagHomeAddressCountry, "PidTagHomeAddressCountry" }, { PidTagHomeAddressPostOfficeBox, "PidTagHomeAddressPostOfficeBox" }, { PidTagHomeAddressPostalCode, "PidTagHomeAddressPostalCode" }, { PidTagHomeAddressStateOrProvince, "PidTagHomeAddressStateOrProvince" }, { PidTagHomeAddressStreet, "PidTagHomeAddressStreet" }, { PidTagHomeFaxNumber, "PidTagHomeFaxNumber" }, { PidTagHomeTelephoneNumber, "PidTagHomeTelephoneNumber" }, { PidTagHtml, "PidTagHtml" }, { PidTagICalendarEndTime, "PidTagICalendarEndTime" }, { PidTagICalendarReminderNextTime, "PidTagICalendarReminderNextTime" }, { PidTagICalendarStartTime, "PidTagICalendarStartTime" }, { PidTagIconIndex, "PidTagIconIndex" }, { PidTagIdsetDeleted, "PidTagIdsetDeleted" }, { PidTagIdsetExpired, "PidTagIdsetExpired" }, { PidTagIdsetGiven, "PidTagIdsetGiven" }, { PidTagIdsetNoLongerInScope, "PidTagIdsetNoLongerInScope" }, { PidTagIdsetRead, "PidTagIdsetRead" }, { PidTagIdsetUnread, "PidTagIdsetUnread" }, { PidTagImapCachedMsgsize, "PidTagImapCachedMsgsize" }, { PidTagImportance, "PidTagImportance" }, { PidTagInConflict, "PidTagInConflict" }, { PidTagInReplyToId, "PidTagInReplyToId" }, { PidTagIncrSyncChg, "PidTagIncrSyncChg" }, { PidTagIncrSyncChgPartial, "PidTagIncrSyncChgPartial" }, { PidTagIncrSyncDel, "PidTagIncrSyncDel" }, { PidTagIncrSyncEnd, "PidTagIncrSyncEnd" }, { PidTagIncrSyncGroupId, "PidTagIncrSyncGroupId" }, { PidTagIncrSyncGroupInfo, "PidTagIncrSyncGroupInfo" }, { PidTagIncrSyncMessage, "PidTagIncrSyncMessage" }, { PidTagIncrSyncProgressMode, "PidTagIncrSyncProgressMode" }, { PidTagIncrSyncProgressPerMsg, "PidTagIncrSyncProgressPerMsg" }, { PidTagIncrSyncRead, "PidTagIncrSyncRead" }, { PidTagIncrSyncStateBegin, "PidTagIncrSyncStateBegin" }, { PidTagIncrSyncStateEnd, "PidTagIncrSyncStateEnd" }, { PidTagIncrementalSyncMessagePartial, "PidTagIncrementalSyncMessagePartial" }, { PidTagInitialDetailsPane, "PidTagInitialDetailsPane" }, { PidTagInitials, "PidTagInitials" }, { PidTagInstID, "PidTagInstID" }, { PidTagInstanceKey, "PidTagInstanceKey" }, { PidTagInstanceNum, "PidTagInstanceNum" }, { PidTagInternetArticleNumber, "PidTagInternetArticleNumber" }, { PidTagInternetCodepage, "PidTagInternetCodepage" }, { PidTagInternetMailOverrideFormat, "PidTagInternetMailOverrideFormat" }, { PidTagInternetMessageId, "PidTagInternetMessageId" }, { PidTagInternetReferences, "PidTagInternetReferences" }, { PidTagIpmAppointmentEntryId, "PidTagIpmAppointmentEntryId" }, { PidTagIpmContactEntryId, "PidTagIpmContactEntryId" }, { PidTagIpmDraftsEntryId, "PidTagIpmDraftsEntryId" }, { PidTagIpmJournalEntryId, "PidTagIpmJournalEntryId" }, { PidTagIpmNoteEntryId, "PidTagIpmNoteEntryId" }, { PidTagIpmPublicFoldersEntryId, "PidTagIpmPublicFoldersEntryId" }, { PidTagIpmTaskEntryId, "PidTagIpmTaskEntryId" }, { PidTagIsdnNumber, "PidTagIsdnNumber" }, { PidTagJunkAddRecipientsToSafeSendersList, "PidTagJunkAddRecipientsToSafeSendersList" }, { PidTagJunkIncludeContacts, "PidTagJunkIncludeContacts" }, { PidTagJunkPermanentlyDelete, "PidTagJunkPermanentlyDelete" }, { PidTagJunkPhishingEnableLinks, "PidTagJunkPhishingEnableLinks" }, { PidTagJunkThreshold, "PidTagJunkThreshold" }, { PidTagKeyword, "PidTagKeyword" }, { PidTagLanguage, "PidTagLanguage" }, { PidTagLastModificationTime, "PidTagLastModificationTime" }, { PidTagLastModifierEntryId, "PidTagLastModifierEntryId" }, { PidTagLastModifierName, "PidTagLastModifierName" }, { PidTagLastModifierSId, "PidTagLastModifierSId" }, { PidTagLastModifierSimpleDisplayName, "PidTagLastModifierSimpleDisplayName" }, { PidTagLastVerbExecuted, "PidTagLastVerbExecuted" }, { PidTagLastVerbExecutionTime, "PidTagLastVerbExecutionTime" }, { PidTagListHelp, "PidTagListHelp" }, { PidTagListSubscribe, "PidTagListSubscribe" }, { PidTagListUnsubscribe, "PidTagListUnsubscribe" }, { PidTagLocalCommitTime, "PidTagLocalCommitTime" }, { PidTagLocalCommitTimeMax, "PidTagLocalCommitTimeMax" }, { PidTagLocaleId, "PidTagLocaleId" }, { PidTagLocality, "PidTagLocality" }, { PidTagLocation, "PidTagLocation" }, { PidTagMailboxOwnerEntryId, "PidTagMailboxOwnerEntryId" }, { PidTagMailboxOwnerName, "PidTagMailboxOwnerName" }, { PidTagManagerName, "PidTagManagerName" }, { PidTagMappingSignature, "PidTagMappingSignature" }, { PidTagMaximumSubmitMessageSize, "PidTagMaximumSubmitMessageSize" }, { PidTagMemberId, "PidTagMemberId" }, { PidTagMemberName, "PidTagMemberName" }, { PidTagMemberRights, "PidTagMemberRights" }, { PidTagMessageAttachments, "PidTagMessageAttachments" }, { PidTagMessageCcMe, "PidTagMessageCcMe" }, { PidTagMessageClass, "PidTagMessageClass" }, { PidTagMessageCodepage, "PidTagMessageCodepage" }, { PidTagMessageDeliveryTime, "PidTagMessageDeliveryTime" }, { PidTagMessageEditorFormat, "PidTagMessageEditorFormat" }, { PidTagMessageFlags, "PidTagMessageFlags" }, { PidTagMessageHandlingSystemCommonName, "PidTagMessageHandlingSystemCommonName" }, { PidTagMessageLocaleId, "PidTagMessageLocaleId" }, { PidTagMessageRecipientMe, "PidTagMessageRecipientMe" }, { PidTagMessageRecipients, "PidTagMessageRecipients" }, { PidTagMessageSize, "PidTagMessageSize" }, { PidTagMessageSizeExtended, "PidTagMessageSizeExtended" }, { PidTagMessageStatus, "PidTagMessageStatus" }, { PidTagMessageSubmissionId, "PidTagMessageSubmissionId" }, { PidTagMessageToMe, "PidTagMessageToMe" }, { PidTagMid, "PidTagMessageId" }, { PidTagMiddleName, "PidTagMiddleName" }, { PidTagMimeSkeleton, "PidTagMimeSkeleton" }, { PidTagMobileTelephoneNumber, "PidTagMobileTelephoneNumber" }, { PidTagNativeBody, "PidTagNativeBody" }, { PidTagNewAttach, "PidTagNewAttach" }, { PidTagNewFXFolder, "PidTagNewFXFolder" }, { PidTagNextSendAcct, "PidTagNextSendAcct" }, { PidTagNickname, "PidTagNickname" }, { PidTagNormalMessageSize, "PidTagNormalMessageSize" }, { PidTagNormalizedSubject, "PidTagNormalizedSubject" }, { PidTagObjectType, "PidTagObjectType" }, { PidTagOfficeLocation, "PidTagOfficeLocation" }, { PidTagOfflineAddressBookCompressedSize, "PidTagOfflineAddressBookCompressedSize" }, { PidTagOfflineAddressBookContainerGuid, "PidTagOfflineAddressBookContainerGuid" }, { PidTagOfflineAddressBookDistinguishedName, "PidTagOfflineAddressBookDistinguishedName" }, { PidTagOfflineAddressBookFileSize, "PidTagOfflineAddressBookFileSize" }, { PidTagOfflineAddressBookFileType, "PidTagOfflineAddressBookFileType" }, { PidTagOfflineAddressBookLanguageId, "PidTagOfflineAddressBookLanguageId" }, { PidTagOfflineAddressBookMessageClass, "PidTagOfflineAddressBookMessageClass" }, { PidTagOfflineAddressBookName, "PidTagOfflineAddressBookName" }, { PidTagOfflineAddressBookSequence, "PidTagOfflineAddressBookSequence" }, { PidTagOfflineAddressBookShaHash, "PidTagOfflineAddressBookShaHash" }, { PidTagOfflineAddressBookTruncatedProperties, "PidTagOfflineAddressBookTruncatedProperties" }, { PidTagOrdinalMost, "PidTagOrdinalMost" }, { PidTagOrganizationalIdNumber, "PidTagOrganizationalIdNumber" }, { PidTagOriginalDeliveryTime, "PidTagOriginalDeliveryTime" }, { PidTagOriginalDisplayBcc, "PidTagOriginalDisplayBcc" }, { PidTagOriginalDisplayCc, "PidTagOriginalDisplayCc" }, { PidTagOriginalDisplayName, "PidTagOriginalDisplayName" }, { PidTagOriginalDisplayTo, "PidTagOriginalDisplayTo" }, { PidTagOriginalEntryId, "PidTagOriginalEntryId" }, { PidTagOriginalMessageClass, "PidTagOriginalMessageClass" }, { PidTagOriginalMessageId, "PidTagOriginalMessageId" }, { PidTagOriginalSearchKey, "PidTagOriginalSearchKey" }, { PidTagOriginalSenderAddressType, "PidTagOriginalSenderAddressType" }, { PidTagOriginalSenderEmailAddress, "PidTagOriginalSenderEmailAddress" }, { PidTagOriginalSenderEntryId, "PidTagOriginalSenderEntryId" }, { PidTagOriginalSenderName, "PidTagOriginalSenderName" }, { PidTagOriginalSenderSearchKey, "PidTagOriginalSenderSearchKey" }, { PidTagOriginalSensitivity, "PidTagOriginalSensitivity" }, { PidTagOriginalSentRepresentingAddressType, "PidTagOriginalSentRepresentingAddressType" }, { PidTagOriginalSentRepresentingEmailAddress, "PidTagOriginalSentRepresentingEmailAddress" }, { PidTagOriginalSentRepresentingEntryId, "PidTagOriginalSentRepresentingEntryId" }, { PidTagOriginalSentRepresentingName, "PidTagOriginalSentRepresentingName" }, { PidTagOriginalSentRepresentingSearchKey, "PidTagOriginalSentRepresentingSearchKey" }, { PidTagOriginalSubject, "PidTagOriginalSubject" }, { PidTagOriginalSubmitTime, "PidTagOriginalSubmitTime" }, { PidTagOriginatorDeliveryReportRequested, "PidTagOriginatorDeliveryReportRequested" }, { PidTagOriginatorNonDeliveryReportRequested, "PidTagOriginatorNonDeliveryReportRequested" }, { PidTagOstOstId, "PidTagOstOstId" }, { PidTagOtherAddressCity, "PidTagOtherAddressCity" }, { PidTagOtherAddressCountry, "PidTagOtherAddressCountry" }, { PidTagOtherAddressPostOfficeBox, "PidTagOtherAddressPostOfficeBox" }, { PidTagOtherAddressPostalCode, "PidTagOtherAddressPostalCode" }, { PidTagOtherAddressStateOrProvince, "PidTagOtherAddressStateOrProvince" }, { PidTagOtherAddressStreet, "PidTagOtherAddressStreet" }, { PidTagOtherTelephoneNumber, "PidTagOtherTelephoneNumber" }, { PidTagOutOfOfficeState, "PidTagOutOfOfficeState" }, { PidTagOwnerAppointmentId, "PidTagOwnerAppointmentId" }, { PidTagPagerTelephoneNumber, "PidTagPagerTelephoneNumber" }, { PidTagParentEntryId, "PidTagParentEntryId" }, { PidTagParentFolderId, "PidTagParentFolderId" }, { PidTagParentKey, "PidTagParentKey" }, { PidTagParentSourceKey, "PidTagParentSourceKey" }, { PidTagPersonalHomePage, "PidTagPersonalHomePage" }, { PidTagPolicyTag, "PidTagPolicyTag" }, { PidTagPostOfficeBox, "PidTagPostOfficeBox" }, { PidTagPostalAddress, "PidTagPostalAddress" }, { PidTagPostalCode, "PidTagPostalCode" }, { PidTagPredecessorChangeList, "PidTagPredecessorChangeList" }, { PidTagPrimaryFaxNumber, "PidTagPrimaryFaxNumber" }, { PidTagPrimarySendAccount, "PidTagPrimarySendAccount" }, { PidTagPrimarySmtpAddress, "PidTagPrimarySmtpAddress" }, { PidTagPrimaryTelephoneNumber, "PidTagPrimaryTelephoneNumber" }, { PidTagPriority, "PidTagPriority" }, { PidTagProcessed, "PidTagProcessed" }, { PidTagProfession, "PidTagProfession" }, { PidTagProhibitReceiveQuota, "PidTagProhibitReceiveQuota" }, { PidTagProhibitSendQuota, "PidTagProhibitSendQuota" }, { PidTagProviderSubmitTime, "PidTagProviderSubmitTime" }, { PidTagPublicFolderAdministrativeDescription, "PidTagPublicFolderAdministrativeDescription" }, { PidTagPublicFolderProxy, "PidTagPublicFolderProxy" }, { PidTagPurportedSenderDomain, "PidTagPurportedSenderDomain" }, { PidTagRadioTelephoneNumber, "PidTagRadioTelephoneNumber" }, { PidTagRead, "PidTagRead" }, { PidTagReadReceiptAddressType, "PidTagReadReceiptAddressType" }, { PidTagReadReceiptEmailAddress, "PidTagReadReceiptEmailAddress" }, { PidTagReadReceiptEntryId, "PidTagReadReceiptEntryId" }, { PidTagReadReceiptName, "PidTagReadReceiptName" }, { PidTagReadReceiptRequested, "PidTagReadReceiptRequested" }, { PidTagReadReceiptSearchKey, "PidTagReadReceiptSearchKey" }, { PidTagReceivedByAddressType, "PidTagReceivedByAddressType" }, { PidTagReceivedByEmailAddress, "PidTagReceivedByEmailAddress" }, { PidTagReceivedByEntryId, "PidTagReceivedByEntryId" }, { PidTagReceivedByFlags, "PidTagReceivedByFlags" }, { PidTagReceivedByName, "PidTagReceivedByName" }, { PidTagReceivedBySearchKey, "PidTagReceivedBySearchKey" }, { PidTagReceivedRepresentingAddressType, "PidTagReceivedRepresentingAddressType" }, { PidTagReceivedRepresentingEmailAddress, "PidTagReceivedRepresentingEmailAddress" }, { PidTagReceivedRepresentingEntryId, "PidTagReceivedRepresentingEntryId" }, { PidTagReceivedRepresentingFlags, "PidTagReceivedRepresentingFlags" }, { PidTagReceivedRepresentingName, "PidTagReceivedRepresentingName" }, { PidTagReceivedRepresentingSearchKey, "PidTagReceivedRepresentingSearchKey" }, { PidTagReceivedRepresentingSimpleDisplayName, "PidTagReceivedRepresentingSimpleDisplayName" }, { PidTagRecipientDisplayName, "PidTagRecipientDisplayName" }, { PidTagRecipientEntryId, "PidTagRecipientEntryId" }, { PidTagRecipientFlags, "PidTagRecipientFlags" }, { PidTagRecipientOrder, "PidTagRecipientOrder" }, { PidTagRecipientProposed, "PidTagRecipientProposed" }, { PidTagRecipientProposedEndTime, "PidTagRecipientProposedEndTime" }, { PidTagRecipientProposedStartTime, "PidTagRecipientProposedStartTime" }, { PidTagRecipientReassignmentProhibited, "PidTagRecipientReassignmentProhibited" }, { PidTagRecipientResourceState, "PidTagRecipientResourceState" }, { PidTagRecipientTrackStatus, "PidTagRecipientTrackStatus" }, { PidTagRecipientTrackStatusTime, "PidTagRecipientTrackStatusTime" }, { PidTagRecipientType, "PidTagRecipientType" }, { PidTagRecordKey, "PidTagRecordKey" }, { PidTagReferredByName, "PidTagReferredByName" }, { PidTagRemindersOnlineEntryId, "PidTagRemindersOnlineEntryId" }, { PidTagRemindersOfflineEntryId, "PidTagRemindersOfflineEntryId" }, { PidTagRemoteMessageTransferAgent, "PidTagRemoteMessageTransferAgent" }, { PidTagRenderingPosition, "PidTagRenderingPosition" }, { PidTagReplyRecipientEntries, "PidTagReplyRecipientEntries" }, { PidTagReplyRecipientNames, "PidTagReplyRecipientNames" }, { PidTagReplyRequested, "PidTagReplyRequested" }, { PidTagReplyTemplateId, "PidTagReplyTemplateId" }, { PidTagReplyTime, "PidTagReplyTime" }, { PidTagReportEntryId, "PidTagReportEntryId" }, { PidTagReportName, "PidTagReportName" }, { PidTagReportSearchKey, "PidTagReportSearchKey" }, { PidTagReportTag, "PidTagReportTag" }, { PidTagReportText, "PidTagReportText" }, { PidTagReportTime, "PidTagReportTime" }, { PidTagReportingMessageTransferAgent, "PidTagReportingMessageTransferAgent" }, { PidTagResolveMethod, "PidTagResolveMethod" }, { PidTagResponseRequested, "PidTagResponseRequested" }, { PidTagResponsibility, "PidTagResponsibility" }, { PidTagRetentionDate, "PidTagRetentionDate" }, { PidTagRetentionFlags, "PidTagRetentionFlags" }, { PidTagRetentionPeriod, "PidTagRetentionPeriod" }, { PidTagRights, "PidTagRights" }, { PidTagRoamingDatatypes, "PidTagRoamingDatatypes" }, { PidTagRoamingDictionary, "PidTagRoamingDictionary" }, { PidTagRoamingXmlStream, "PidTagRoamingXmlStream" }, { PidTagRowType, "PidTagRowType" }, { PidTagRowid, "PidTagRowid" }, { PidTagRtfCompressed, "PidTagRtfCompressed" }, { PidTagRtfInSync, "PidTagRtfInSync" }, { PidTagRtfSyncBodyCount, "PidTagRtfSyncBodyCount" }, { PidTagRtfSyncBodyCrc, "PidTagRtfSyncBodyCrc" }, { PidTagRtfSyncBodyTag, "PidTagRtfSyncBodyTag" }, { PidTagRtfSyncPrefixCount, "PidTagRtfSyncPrefixCount" }, { PidTagRtfSyncTrailingCount, "PidTagRtfSyncTrailingCount" }, { PidTagRuleActionNumber, "PidTagRuleActionNumber" }, { PidTagRuleActionType, "PidTagRuleActionType" }, { PidTagRuleActions, "PidTagRuleActions" }, { PidTagRuleCondition, "PidTagRuleCondition" }, { PidTagRuleError, "PidTagRuleError" }, { PidTagRuleFolderEntryId, "PidTagRuleFolderEntryId" }, { PidTagRuleId, "PidTagRuleId" }, { PidTagRuleIds, "PidTagRuleIds" }, { PidTagRuleLevel, "PidTagRuleLevel" }, { PidTagRuleMessageLevel, "PidTagRuleMessageLevel" }, { PidTagRuleMessageName, "PidTagRuleMessageName" }, { PidTagRuleMessageProvider, "PidTagRuleMessageProvider" }, { PidTagRuleMessageProviderData, "PidTagRuleMessageProviderData" }, { PidTagRuleMessageSequence, "PidTagRuleMessageSequence" }, { PidTagRuleMessageState, "PidTagRuleMessageState" }, { PidTagRuleMessageUserFlags, "PidTagRuleMessageUserFlags" }, { PidTagRuleName, "PidTagRuleName" }, { PidTagRuleProvider, "PidTagRuleProvider" }, { PidTagRuleProviderData, "PidTagRuleProviderData" }, { PidTagRuleSequence, "PidTagRuleSequence" }, { PidTagRuleState, "PidTagRuleState" }, { PidTagRuleUserFlags, "PidTagRuleUserFlags" }, { PidTagRwRulesStream, "PidTagRwRulesStream" }, { PidTagScheduleInfoAppointmentTombstone, "PidTagScheduleInfoAppointmentTombstone" }, { PidTagScheduleInfoAutoAcceptAppointments, "PidTagScheduleInfoAutoAcceptAppointments" }, { PidTagScheduleInfoDelegateEntryIds, "PidTagScheduleInfoDelegateEntryIds" }, { PidTagScheduleInfoDelegateNames, "PidTagScheduleInfoDelegateNames" }, { PidTagScheduleInfoDelegateNamesW, "PidTagScheduleInfoDelegateNamesW" }, { PidTagScheduleInfoDelegatorWantsCopy, "PidTagScheduleInfoDelegatorWantsCopy" }, { PidTagScheduleInfoDelegatorWantsInfo, "PidTagScheduleInfoDelegatorWantsInfo" }, { PidTagScheduleInfoDisallowOverlappingAppts, "PidTagScheduleInfoDisallowOverlappingAppts" }, { PidTagScheduleInfoDisallowRecurringAppts, "PidTagScheduleInfoDisallowRecurringAppts" }, { PidTagScheduleInfoDontMailDelegates, "PidTagScheduleInfoDontMailDelegates" }, { PidTagScheduleInfoFreeBusy, "PidTagScheduleInfoFreeBusy" }, { PidTagScheduleInfoFreeBusyAway, "PidTagScheduleInfoFreeBusyAway" }, { PidTagScheduleInfoFreeBusyBusy, "PidTagScheduleInfoFreeBusyBusy" }, { PidTagScheduleInfoFreeBusyMerged, "PidTagScheduleInfoFreeBusyMerged" }, { PidTagScheduleInfoFreeBusyTentative, "PidTagScheduleInfoFreeBusyTentative" }, { PidTagScheduleInfoMonthsAway, "PidTagScheduleInfoMonthsAway" }, { PidTagScheduleInfoMonthsBusy, "PidTagScheduleInfoMonthsBusy" }, { PidTagScheduleInfoMonthsMerged, "PidTagScheduleInfoMonthsMerged" }, { PidTagScheduleInfoMonthsTentative, "PidTagScheduleInfoMonthsTentative" }, { PidTagScheduleInfoResourceType, "PidTagScheduleInfoResourceType" }, { PidTagSchedulePlusFreeBusyEntryId, "PidTagSchedulePlusFreeBusyEntryId" }, { PidTagScriptData, "PidTagScriptData" }, { PidTagSearchFolderDefinition, "PidTagSearchFolderDefinition" }, { PidTagSearchFolderExpiration, "PidTagSearchFolderExpiration" }, { PidTagSearchFolderId, "PidTagSearchFolderId" }, { PidTagSearchFolderLastUsed, "PidTagSearchFolderLastUsed" }, { PidTagSearchFolderRecreateInfo, "PidTagSearchFolderRecreateInfo" }, { PidTagSearchFolderStorageType, "PidTagSearchFolderStorageType" }, { PidTagSearchKey, "PidTagSearchKey" }, { PidTagSecureOrigination, "PidTagSecureOrigination" }, { PidTagSecureSubmitFlags, "PidTagSecureSubmitFlags" }, { PidTagSecurityDescriptor, "PidTagSecurityDescriptor" }, { PidTagSecurityDescriptorAsXml, "PidTagSecurityDescriptorAsXml" }, { PidTagSelectable, "PidTagSelectable" }, { PidTagSendInternetEncoding, "PidTagSendInternetEncoding" }, { PidTagSendRichInfo, "PidTagSendRichInfo" }, { PidTagSenderAddressType, "PidTagSenderAddressType" }, { PidTagSenderEmailAddress, "PidTagSenderEmailAddress" }, { PidTagSenderEntryId, "PidTagSenderEntryId" }, { PidTagSenderFlags, "PidTagSenderFlags" }, { PidTagSenderIdStatus, "PidTagSenderIdStatus" }, { PidTagSenderName, "PidTagSenderName" }, { PidTagSenderSearchKey, "PidTagSenderSearchKey" }, { PidTagSenderSimpleDisplayName, "PidTagSenderSimpleDisplayName" }, { PidTagSenderSmtpAddress, "PidTagSenderSmtpAddress" }, { PidTagSenderTelephoneNumber, "PidTagSenderTelephoneNumber" }, { PidTagSensitivity, "PidTagSensitivity" }, { PidTagSentMailSvrEID, "PidTagSentMailSvrEID" }, { PidTagSentRepresentingAddressType, "PidTagSentRepresentingAddressType" }, { PidTagSentRepresentingEmailAddress, "PidTagSentRepresentingEmailAddress" }, { PidTagSentRepresentingEntryId, "PidTagSentRepresentingEntryId" }, { PidTagSentRepresentingFlags, "PidTagSentRepresentingFlags" }, { PidTagSentRepresentingName, "PidTagSentRepresentingName" }, { PidTagSentRepresentingSearchKey, "PidTagSentRepresentingSearchKey" }, { PidTagSentRepresentingSimpleDisplayName, "PidTagSentRepresentingSimpleDisplayName" }, { PidTagSessionInitiationProtocolUri, "PidTagSessionInitiationProtocolUri" }, { PidTagShorttermEntryIdFromObject, "PidTagShorttermEntryIdFromObject" }, { PidTagSortLocaleId, "PidTagSortLocaleId" }, { PidTagSourceKey, "PidTagSourceKey" }, { PidTagSpokenName, "PidTagSpokenName" }, { PidTagSpouseName, "PidTagSpouseName" }, { PidTagStartDate, "PidTagStartDate" }, { PidTagStartDateEtc, "PidTagStartDateEtc" }, { PidTagStartEmbed, "PidTagStartEmbed" }, { PidTagStartFAIMsg, "PidTagStartFAIMsg" }, { PidTagStartMessage, "PidTagStartMessage" }, { PidTagStartRecip, "PidTagStartRecip" }, { PidTagStartSubFld, "PidTagStartSubFld" }, { PidTagStartTopFld, "PidTagStartTopFld" }, { PidTagStorageQuotaLimit, "PidTagStorageQuotaLimit" }, { PidTagStateOrProvince, "PidTagStateOrProvince" }, { PidTagStoreEntryId, "PidTagStoreEntryId" }, { PidTagStoreState, "PidTagStoreState" }, { PidTagStoreSupportMask, "PidTagStoreSupportMask" }, { PidTagStreetAddress, "PidTagStreetAddress" }, { PidTagSubfolder, "PidTagSubfolder" }, { PidTagSubfolders, "PidTagSubfolders" }, { PidTagSubject, "PidTagSubject" }, { PidTagSubjectPrefix, "PidTagSubjectPrefix" }, { PidTagSurname, "PidTagSurname" }, { PidTagSwappedToDoData, "PidTagSwappedToDoData" }, { PidTagSwappedToDoStore, "PidTagSwappedToDoStore" }, { PidTagTargetEntryId, "PidTagTargetEntryId" }, { PidTagTcvConstLongOne, "PidTagTcvConstLongOne" }, { PidTagTelecommunicationsDeviceForDeafTelephoneNumber, "PidTagTelecommunicationsDeviceForDeafTelephoneNumber" }, { PidTagTelexNumber, "PidTagTelexNumber" }, { PidTagTemplateData, "PidTagTemplateData" }, { PidTagTemplateid, "PidTagTemplateid" }, { PidTagTemporaryDefaultDocument, "PidTagTemporaryDefaultDocument" }, { PidTagTextAttachmentCharset, "PidTagTextAttachmentCharset" }, { PidTagThumbnailPhoto, "PidTagThumbnailPhoto" }, { PidTagTitle, "PidTagTitle" }, { PidTagTnefCorrelationKey, "PidTagTnefCorrelationKey" }, { PidTagToDoItemFlags, "PidTagToDoItemFlags" }, { PidTagTransmittableDisplayName, "PidTagTransmittableDisplayName" }, { PidTagTransportMessageHeaders, "PidTagTransportMessageHeaders" }, { PidTagTrustSender, "PidTagTrustSender" }, { PidTagUrlCompName, "PidTagUrlCompName" }, { PidTagUrlCompNameSet, "PidTagUrlCompNameSet" }, { PidTagUrlName, "PidTagUrlName" }, { PidTagUserCertificate, "PidTagUserCertificate" }, { PidTagUserEntryId, "PidTagUserEntryId" }, { PidTagUserX509Certificate, "PidTagUserX509Certificate" }, { PidTagViewDescriptorBinary, "PidTagViewDescriptorBinary" }, { PidTagViewDescriptorName, "PidTagViewDescriptorName" }, { PidTagViewDescriptorStrings, "PidTagViewDescriptorStrings" }, { PidTagViewDescriptorVersion, "PidTagViewDescriptorVersion" }, { PidTagVoiceMessageAttachmentOrder, "PidTagVoiceMessageAttachmentOrder" }, { PidTagVoiceMessageSenderName, "PidTagVoiceMessageSenderName" }, { PidTagWeddingAnniversary, "PidTagWeddingAnniversary" }, { PidTagWlinkAddressBookEID, "PidTagWlinkAddressBookEID" }, { PidTagWlinkAddressBookStoreEID, "PidTagWlinkAddressBookStoreEID" }, { PidTagWlinkCalendarColor, "PidTagWlinkCalendarColor" }, { PidTagWlinkClientID, "PidTagWlinkClientID" }, { PidTagWlinkEntryId, "PidTagWlinkEntryId" }, { PidTagWlinkFlags, "PidTagWlinkFlags" }, { PidTagWlinkFolderType, "PidTagWlinkFolderType" }, { PidTagWlinkGroupClsid, "PidTagWlinkGroupClsid" }, { PidTagWlinkGroupHeaderID, "PidTagWlinkGroupHeaderID" }, { PidTagWlinkGroupName, "PidTagWlinkGroupName" }, { PidTagWlinkOrdinal, "PidTagWlinkOrdinal" }, { PidTagWlinkROGroupType, "PidTagWlinkROGroupType" }, { PidTagWlinkRecordKey, "PidTagWlinkRecordKey" }, { PidTagWlinkSection, "PidTagWlinkSection" }, { PidTagWlinkStoreEntryId, "PidTagWlinkStoreEntryId" }, { PidTagWlinkType, "PidTagWlinkType" }, { PidTagNTSDModificationTime, "PidTagNTSDModificationTime" }, { 0, NULL } }; /* TODO: this method would be faster with a lookup table */ _PUBLIC_ const char *openchangedb_property_get_attribute(uint32_t propTag) { uint32_t i, uniPropTag; if ((propTag & 0x0FFF) == PT_STRING8) { uniPropTag = ((propTag & 0xfffff000) | PT_UNICODE); } else { uniPropTag = propTag; } for (i = 0; pidtags[i].pidtag; i++) { if (pidtags[i].proptag == uniPropTag) { return pidtags[i].pidtag; } } DEBUG(0, ("[%s:%d]: Unsupported property tag '0x%.8x'\n", __FUNCTION__, __LINE__, propTag)); return NULL; } openchange-2.0/mapiproxy/libmapiproxy/openchangedb_table.c000066400000000000000000000250351223057412600241700ustar00rootroot00000000000000/* OpenChange Server implementation OpenChangeDB table object implementation Copyright (C) Julien Kerihuel 2011 This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see . */ /** \file openchangedb_table.c \brief OpenChange Dispatcher database table routines */ #include #include "mapiproxy/dcesrv_mapiproxy.h" #include "libmapiproxy.h" #include "libmapi/libmapi.h" #include "libmapi/libmapi_private.h" /** /details Initialize an openchangedb table \param mem_ctx pointer to the memory context to use for allocation \param table_type the type of table this object represents \param folderID the identifier of the folder this table represents \param table_object pointer on pointer to the table object to return \return MAPI_E_SUCCESS on success, otherwise MAPISTORE error */ _PUBLIC_ enum MAPISTATUS openchangedb_table_init(TALLOC_CTX *mem_ctx, uint8_t table_type, uint64_t folderID, void **table_object) { struct openchangedb_table *table; /* Sanity checks */ MAPI_RETVAL_IF(!table_object, MAPI_E_NOT_INITIALIZED, NULL); table = talloc_zero(mem_ctx, struct openchangedb_table); if (!table) { return MAPI_E_NOT_ENOUGH_MEMORY; } /* printf("openchangedb_table_init: folderID=%"PRIu64"\n", folderID); */ table->folderID = folderID; table->table_type = table_type; table->lpSortCriteria = NULL; table->restrictions = NULL; table->res = NULL; *table_object = (void *)table; return MAPI_E_SUCCESS; } /** \details Set sort order to specified openchangedb table object \param table_object pointer to the table object \param lpSortCriteria pointer to the sort order to save \return MAPI_E_SUCCESS on success, otherwise MAPI error */ _PUBLIC_ enum MAPISTATUS openchangedb_table_set_sort_order(void *table_object, struct SSortOrderSet *lpSortCriteria) { struct openchangedb_table *table; /* Sanity checks */ MAPI_RETVAL_IF(!table_object, MAPI_E_NOT_INITIALIZED, NULL); MAPI_RETVAL_IF(!lpSortCriteria, MAPI_E_INVALID_PARAMETER, NULL); table = (struct openchangedb_table *) table_object; if (table->res) { talloc_free(table->res); table->res = NULL; } if (table->lpSortCriteria) { talloc_free(table->lpSortCriteria); } if (lpSortCriteria) { table->lpSortCriteria = talloc_memdup((TALLOC_CTX *)table, lpSortCriteria, sizeof(struct SSortOrderSet)); if (!table->lpSortCriteria) { return MAPI_E_NOT_ENOUGH_MEMORY; } table->lpSortCriteria->aSort = talloc_memdup((TALLOC_CTX *)table->lpSortCriteria, lpSortCriteria->aSort, lpSortCriteria->cSorts * sizeof(struct SSortOrder)); if (!table->lpSortCriteria->aSort) { return MAPI_E_NOT_ENOUGH_MEMORY; } } else { table->lpSortCriteria = NULL; } return MAPI_E_SUCCESS; } _PUBLIC_ enum MAPISTATUS openchangedb_table_set_restrictions(void *table_object, struct mapi_SRestriction *res) { struct openchangedb_table *table; /* Sanity checks */ MAPI_RETVAL_IF(!table_object, MAPI_E_NOT_INITIALIZED, NULL); MAPI_RETVAL_IF(!res, MAPI_E_INVALID_PARAMETER, NULL); table = (struct openchangedb_table *) table_object; if (table->res) { talloc_free(table->res); table->res = NULL; } if (table->restrictions) { talloc_free(table->restrictions); table->restrictions = NULL; } MAPI_RETVAL_IF(!res, MAPI_E_SUCCESS, NULL); table->restrictions = talloc_zero((TALLOC_CTX *)table_object, struct mapi_SRestriction); switch (res->rt) { case RES_PROPERTY: table->restrictions->rt = res->rt; table->restrictions->res.resProperty.relop = res->res.resProperty.relop; table->restrictions->res.resProperty.ulPropTag = res->res.resProperty.ulPropTag; table->restrictions->res.resProperty.lpProp.ulPropTag = res->res.resProperty.lpProp.ulPropTag; switch (table->restrictions->res.resProperty.lpProp.ulPropTag & 0xFFFF) { case PT_STRING8: table->restrictions->res.resProperty.lpProp.value.lpszA = talloc_strdup((TALLOC_CTX *)table->restrictions, res->res.resProperty.lpProp.value.lpszA); break; case PT_UNICODE: table->restrictions->res.resProperty.lpProp.value.lpszW = talloc_strdup((TALLOC_CTX *)table->restrictions, res->res.resProperty.lpProp.value.lpszW); break; default: DEBUG(0, ("Unsupported property type for RES_PROPERTY restriction\n")); break; } break; default: DEBUG(0, ("Unsupported restriction type: 0x%x\n", res->rt)); } return MAPI_E_SUCCESS; } static char *openchangedb_table_build_filter(TALLOC_CTX *mem_ctx, struct openchangedb_table *table, uint64_t row_fmid, struct mapi_SRestriction *restrictions) { char *filter = NULL; const char *PidTagAttr = NULL; switch (table->table_type) { case 0x3 /* EMSMDBP_TABLE_FAI_TYPE */: filter = talloc_asprintf(mem_ctx, "(&(objectClass=faiMessage)(PidTagParentFolderId=%"PRIu64")(PidTagMessageId=", table->folderID); break; case 0x2 /* EMSMDBP_TABLE_MESSAGE_TYPE */: filter = talloc_asprintf(mem_ctx, "(&(objectClass=systemMessage)(PidTagParentFolderId=%"PRIu64")(PidTagMessageId=", table->folderID); break; case 0x1 /* EMSMDBP_TABLE_FOLDER_TYPE */: filter = talloc_asprintf(mem_ctx, "(&(PidTagParentFolderId=%"PRIu64")(PidTagFolderId=", table->folderID); break; } if (row_fmid == 0) { filter = talloc_asprintf_append(filter, "*)"); } else { filter = talloc_asprintf_append(filter, "%"PRIu64")", row_fmid); } if (restrictions) { switch (restrictions->rt) { case RES_PROPERTY: /* Retrieve PidTagName */ PidTagAttr = openchangedb_property_get_attribute(restrictions->res.resProperty.ulPropTag); if (!PidTagAttr) { talloc_free(filter); return NULL; } filter = talloc_asprintf_append(filter, "(%s=", PidTagAttr); switch (restrictions->res.resProperty.ulPropTag & 0xFFFF) { case PT_STRING8: filter = talloc_asprintf_append(filter, "%s)", restrictions->res.resProperty.lpProp.value.lpszA); break; case PT_UNICODE: filter = talloc_asprintf_append(filter, "%s)", restrictions->res.resProperty.lpProp.value.lpszW); break; default: DEBUG(0, ("Unsupported RES_PROPERTY property type: 0x%.4x\n", (restrictions->res.resProperty.ulPropTag & 0xFFFF))); talloc_free(filter); return NULL; } } } /* Close filter */ filter = talloc_asprintf_append(filter, ")"); return filter; } _PUBLIC_ enum MAPISTATUS openchangedb_table_get_property(TALLOC_CTX *mem_ctx, void *table_object, struct ldb_context *ldb_ctx, enum MAPITAGS proptag, uint32_t pos, bool live_filtered, void **data) { struct openchangedb_table *table; char *ldb_filter = NULL; struct ldb_result *res = NULL, *live_res = NULL; const char * const attrs[] = { "*", NULL }; const char *PidTagAttr = NULL, *childIdAttr; uint64_t *row_fmid; int ret; /* Sanity checks */ OPENCHANGE_RETVAL_IF(!table_object, MAPI_E_NOT_INITIALIZED, NULL); OPENCHANGE_RETVAL_IF(!ldb_ctx, MAPI_E_NOT_INITIALIZED, NULL); OPENCHANGE_RETVAL_IF(!data, MAPI_E_NOT_INITIALIZED, NULL); table = (struct openchangedb_table *)table_object; /* Fetch results */ if (!table->res) { /* Build ldb filter */ if (live_filtered) { ldb_filter = openchangedb_table_build_filter(NULL, table, 0, NULL); DEBUG(0, ("(live-filtered) ldb_filter = %s\n", ldb_filter)); } else { ldb_filter = openchangedb_table_build_filter(NULL, table, 0, table->restrictions); DEBUG(0, ("(pre-filtered) ldb_filter = %s\n", ldb_filter)); } OPENCHANGE_RETVAL_IF(!ldb_filter, MAPI_E_TOO_COMPLEX, NULL); ret = ldb_search(ldb_ctx, (TALLOC_CTX *)table_object, &table->res, ldb_get_default_basedn(ldb_ctx), LDB_SCOPE_SUBTREE, attrs, ldb_filter, NULL); talloc_free(ldb_filter); OPENCHANGE_RETVAL_IF(ret != LDB_SUCCESS, MAPI_E_INVALID_OBJECT, NULL); } res = table->res; /* Ensure position is within search results range */ OPENCHANGE_RETVAL_IF(pos >= res->count, MAPI_E_INVALID_OBJECT, NULL); /* If live filtering, make sure the specified row match the restrictions */ if (live_filtered) { TALLOC_CTX *local_mem_ctx; switch (table->table_type) { case 0x3 /* EMSMDBP_TABLE_FAI_TYPE */: case 0x2 /* EMSMDBP_TABLE_MESSAGE_TYPE */: childIdAttr = "PidTagMessageId"; break; case 0x1 /* EMSMDBP_TABLE_FOLDER_TYPE */: childIdAttr = "PidTagFolderId"; break; default: DEBUG(0, ("unsupported table type for openchangedb: %d\n", table->table_type)); abort(); } row_fmid = openchangedb_get_property_data(mem_ctx, res, pos, PR_MID, childIdAttr); if (!row_fmid || !*row_fmid) { DEBUG(0, ("ldb object must have a '%s' field\n", childIdAttr)); abort(); } local_mem_ctx = talloc_zero(NULL, TALLOC_CTX); ldb_filter = openchangedb_table_build_filter(local_mem_ctx, table, *row_fmid, table->restrictions); OPENCHANGE_RETVAL_IF(!ldb_filter, MAPI_E_TOO_COMPLEX, NULL); DEBUG(0, (" row ldb_filter = %s\n", ldb_filter)); ret = ldb_search(ldb_ctx, local_mem_ctx, &live_res, ldb_get_default_basedn(ldb_ctx), LDB_SCOPE_SUBTREE, attrs, ldb_filter, NULL); OPENCHANGE_RETVAL_IF(ret != LDB_SUCCESS || live_res->count == 0, MAPI_E_INVALID_OBJECT, local_mem_ctx); talloc_free(local_mem_ctx); } /* hacks for some attributes specific to tables */ if (proptag == PR_INST_ID) { if (table->table_type == 1) { proptag = PR_FID; } else { proptag = PR_MID; } } else if (proptag == PR_INSTANCE_NUM) { *data = talloc_zero(mem_ctx, uint32_t); return MAPI_E_SUCCESS; } /* Convert proptag into PidTag attribute */ if ((table->table_type != 0x1) && proptag == PR_FID) { proptag = PR_PARENT_FID; } PidTagAttr = openchangedb_property_get_attribute(proptag); OPENCHANGE_RETVAL_IF(!PidTagAttr, MAPI_E_NOT_FOUND, NULL); /* Ensure the element exists */ OPENCHANGE_RETVAL_IF(!ldb_msg_find_element(res->msgs[pos], PidTagAttr), MAPI_E_NOT_FOUND, NULL); /* Check if this is a "special property" */ *data = openchangedb_get_special_property(mem_ctx, ldb_ctx, res, proptag, PidTagAttr); OPENCHANGE_RETVAL_IF(*data != NULL, MAPI_E_SUCCESS, NULL); /* Check if this is NOT a "special property" */ *data = openchangedb_get_property_data(mem_ctx, res, pos, proptag, PidTagAttr); OPENCHANGE_RETVAL_IF(*data != NULL, MAPI_E_SUCCESS, NULL); return MAPI_E_NOT_FOUND; } openchange-2.0/mapiproxy/libmapiserver.pc.in000066400000000000000000000005401223057412600213100ustar00rootroot00000000000000prefix=@prefix@ exec_prefix=@exec_prefix@ libdir=@libdir@ includedir=@includedir@ datarootdir=@prefix@/share datadir=@datadir@ modulesdir=@modulesdir@/dcerpc_mapiproxy_server Name: MAPISERVER Description: Server side MAPI library Version: @PACKAGE_VERSION@ Libs: -L${libdir} -lmapiserver Libs.private: @LIBS@ Cflags: -I${includedir} Requires: talloc openchange-2.0/mapiproxy/libmapiserver/000077500000000000000000000000001223057412600203605ustar00rootroot00000000000000openchange-2.0/mapiproxy/libmapiserver/libmapiserver.h000066400000000000000000000445761223057412600234150ustar00rootroot00000000000000/* libmapiserver - MAPI library for Server side OpenChange Project Copyright (C) Julien Kerihuel 2009 This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see . */ #ifndef __LIBMAPISERVER_H__ #define __LIBMAPISERVER_H__ #ifndef _GNU_SOURCE #define _GNU_SOURCE 1 #endif #include #include #include #include #include #include #include #include #include "gen_ndr/exchange.h" #ifndef __BEGIN_DECLS #ifdef __cplusplus #define __BEGIN_DECLS extern "C" { #define __END_DECLS } #else #define __BEGIN_DECLS #define __END_DECLS #endif #endif #define SIZE_DFLT_MAPI_RESPONSE 6 /* Rops default and static size */ /** \details OpenFolderRop has fixed response size for -# HasRules: uint8_t -# IsGhosted: uint8_t */ #define SIZE_DFLT_ROPOPENFOLDER 2 /** \details OpenMessage has fixed response size for -# HasNamedProperties: uint8_t -# RecipientCount: uint16_t -# RowCount: uint8_t */ #define SIZE_DFLT_ROPOPENMESSAGE 4 /** \details GetHierarchyTableTop has fixed response size for: -# RowCount: uint32_t */ #define SIZE_DFLT_ROPGETHIERARCHYTABLE 4 /** \details GetContentsTableRop has fixed response size for: -# RowCount: uint32_t */ #define SIZE_DFLT_ROPGETCONTENTSTABLE 4 /** \details CreateMessageRop has fixed response size for: -# HasMessageId: uint8_t */ #define SIZE_DFLT_ROPCREATEMESSAGE 1 /** \details GetPropertiesSpecificRop has fixed response size for: -# layout: uint8_t */ #define SIZE_DFLT_ROPGETPROPERTIESSPECIFIC 1 /** \details GetPropertiesAllRop has fixed response size for: -# cValues: uint16_t */ #define SIZE_DFLT_ROPGETPROPERTIESALL 2 /** \details GetPropertiesListRop has fixed response size for: -# count: uint16_t */ #define SIZE_DFLT_ROPGETPROPERTIESLIST 2 /** \details: SetPropertiesRop has fixed response size for: -# PropertyProblemCount: uint16_t */ #define SIZE_DFLT_ROPSETPROPERTIES 2 /** \details: DeletePropertiesRop has fixed response size for: -# PropertyProblemCount: uint16_t */ #define SIZE_DFLT_ROPDELETEPROPERTIES 2 /** \details: CopyToRop has fixed response size for: -# PropertyProblemCount: uint16_t */ #define SIZE_DFLT_ROPCOPYTO 2 /** \details: SaveChangesMessageRop has fixed response size for: -# handle_idx: uint8_t -# MessageId: uint64_t */ #define SIZE_DFLT_ROPSAVECHANGESMESSAGE 9 /** \details ReloadCachedInformation has fixed response size for: -# HasNamedProperties: uint8_t -# RecipientCount: uint16_t -# RowCount: uint8_t */ #define SIZE_DFLT_ROPRELOADCACHEDINFORMATION 4 /** \details: SetMessageReadFlagRop has fixed response size for: -# ReadStatusChanged: uint8_t */ #define SIZE_DFLT_ROPSETMESSAGEREADFLAG 1 /** \details: CreateAttachRop has fixed response size for: -# AttachmentId: uint32_t */ #define SIZE_DFLT_ROPCREATEATTACH 4 /** \details: OpenEmbeddedMessage has fixed response size for: -# Reserved: uint8_t -# MessageId: uint64_t -# HasNamedProperties: uint8_t -# RecipientCount: uint16_t -# RecipientColumns.cValues: uint16_t -# RowCount: uint8_t */ #define SIZE_DFLT_ROPOPENEMBEDDEDMESSAGE 15 /** \details SetColumnsRop has fixed response size for: -# TableStatus: uint8_t */ #define SIZE_DFLT_ROPSETCOLUMNS 1 /** \details SortTableRop has fixed response size for: -# TableStatus: uint8_t */ #define SIZE_DFLT_ROPSORTTABLE 1 /** \details RestrictRop has fixed response size for: -# TableStatus: uint8_t */ #define SIZE_DFLT_ROPRESTRICT 1 /** \details QueryRowsRop has fixed size for: -# Origin: uint8_t -# RowCount: uint16_t */ #define SIZE_DFLT_ROPQUERYROWS 3 /** \details QueryPositionRop has fixed response size for: -# Numerator: uint32_t -# Denominator: uint32_t */ #define SIZE_DFLT_ROPQUERYPOSITION 8 /** \details SeekRowRop has fixed response size for: -# HasSought: uint8_t -# RowsSought: uint32_t */ #define SIZE_DFLT_ROPSEEKROW 5 /** \details CreateFolderRop has fixed response size for: -# folder_id: uint64_t -# isExistingFolder: uint8_t */ #define SIZE_DFLT_ROPCREATEFOLDER 9 /** \details DeleteFolderRop has fixed response size for: -# PartialCompletion: uint8_t */ #define SIZE_DFLT_ROPDELETEFOLDER 1 /** \details OpenStreamRop has fixed response size for: -# StreamSize: uint32_t */ #define SIZE_DFLT_ROPOPENSTREAM 4 /** \details ReadStreamRop has fixed response size for: -# DataSize: uint16_t */ #define SIZE_DFLT_ROPREADSTREAM 2 /** \details WriteStreamRop has fixed response size for: -# WrittenSize: uint16_t */ #define SIZE_DFLT_ROPWRITESTREAM 2 /** \details GetStreamSize has fixed response size for: -# StreamSize: uint32_t */ #define SIZE_DFLT_ROPGETSTREAMSIZE 4 /** \details SeekStream has fixed response size for: -# NewPosition: uint64_t */ #define SIZE_DFLT_ROPSEEKSTREAM 8 /** \details GetReceiveFolder has fixed response size for: -# folder_id: uint64_t */ #define SIZE_DFLT_ROPGETRECEIVEFOLDER 8 /** \details GetAddressTypes has fixed response size for: -# cValues: uint16_t -# size: uint16_t */ #define SIZE_DFLT_ROPGETADDRESSTYPES 4 /** \details TransportSend has fixed response size for: -# NoPropertiesReturned: uint8_t */ #define SIZE_DFLT_ROPTRANSPORTSEND 1 /** \details GetTransportFolder has fixed response size for: -# FolderId: uint64_t */ #define SIZE_DFLT_ROPGETTRANSPORTFOLDER 8 /** \details OptionsData has fixed response size for: -# Reserved: uint8_t -# OptionsInfo: uint16_t part of SBinary_short -# HelpFileSize: uint16_t */ #define SIZE_DFLT_ROPOPTIONSDATA 5 /** \details FindRow has fixed response size for: -# RowNoLongerVisible: uint8_t -# HasRowData: uint8_t */ #define SIZE_DFLT_ROPFINDROW 2 /** \details GetNamesFromIDs has fixed response size for: -# PropertyNameCount: uint16_t */ #define SIZE_DFLT_ROPGETNAMESFROMIDS 2 /** \details GetPropertyIdsFromNames has fixed response size for: -# count: uint16_t */ #define SIZE_DFLT_ROPGETPROPERTYIDSFROMNAMES 2 /** \details GetPropertyIdsFromNames has fixed response size for: -# PropertyProblemCount: uint16_t */ #define SIZE_DFLT_ROPDELETEPROPERTIESNOREPLICATE 2 /** \details EmptyFolder has fixed response size for: -# PartialCompletion: uint8_t */ #define SIZE_DFLT_ROPEMPTYFOLDER 1 /** \details MoveCopyMessages Rop has fixed response size for: -#: PartialCompletion: uint8_t */ #define SIZE_DFLT_ROPMOVECOPYMESSAGES 1 /** \details MoveFolder Rop has fixed response size for: -#: PartialCompletion: uint8_t */ #define SIZE_DFLT_ROPMOVEFOLDER 1 /** \details CopyFolder Rop has fixed response size for: -#: PartialCompletion: uint8_t */ #define SIZE_DFLT_ROPCOPYFOLDER 1 /** \details DeleteMessage Rop has fixed response size for: -# PartialCompletion: uint8_t */ #define SIZE_DFLT_ROPDELETEMESSAGE 1 /** \details Notify Rop has non-default fixed response size for: -# RopId: uint8_t -# NotificationHandle: uint32_t -# LogonId: uint8_t -# NotificationType: uint16_t */ #define SIZE_DFLT_ROPNOTIFY 8 /** \details GetSearchCriteria Rop has fixed response size for: -# RestrictionDataSize: uint16_t -# LogonId: uint8_t -# FolderIdCount: uint16_t -# SearchFlags: uint32_t */ #define SIZE_DFLT_ROPGETSEARCHCRITERIA 9 /** \details LongTermIdFromId Rop has fixed response size for: -# DatabaseGuid: 16 * uint8_t -# LongTermId: 6 * uint8_t -# Padding: uint16_t */ #define SIZE_DFLT_ROPLONGTERMIDFROMID 24; /** \details IdFromLongTermId Rop has fixed response size for: -# Id: 8 * uint8_t */ #define SIZE_DFLT_ROPIDFROMLONGTERMID 8; /** \details GetPerUserLongTermIds has fixed response size for: -# LongTermIdCount: uint16_t */ #define SIZE_DFLT_ROPGETPERUSERLONGTERMIDS 2 /** \details ReadPerUserInformation has fixed response size for: -# HasFinished: uint8_t -# DataSize: uint16_t */ #define SIZE_DFLT_ROPREADPERUSERINFORMATION 3 /** \details GetPerUserGuid has fixed response size for: -# DatabaseGuid: uint8_t * 16 */ #define SIZE_DFLT_ROPGETPERUSERGUID 16 /** \details GetStoreState has fixed response size for: -# StoreState: uin32_t */ #define SIZE_DFLT_ROPGETSTORESTATE 4 /** \details LogonRop has a fixed size for mailbox: -# LogonFlags: uint8_t -# FolderIDs: uint64_t * 13 -# ResponseFlags: uint8_t -# MailboxGUID: sizeof (struct GUID) -# ReplID: uint16_t -# ReplGUID: sizeof (struct GUID) -# LogonTime: uint8_t * 6 + uint16_t -# GwartTime: uint64_t -# StoreState: uint32_t */ #define SIZE_DFLT_ROPLOGON_MAILBOX 160 /** \details LogonRop has a fixed size for public folder logon: -# LogonFlags: uint8_t -# FolderIDs: uint64_t * 13 -# ReplId: uint16_t -# ReplGuid: sizeof (struct GUID) = 16 bytes -# PerUserGuid: sizeof (struct GUID) = 16 bytes */ #define SIZE_DFLT_ROPLOGON_PUBLICFOLDER 139 /** \details LogonRop has a fixed size for redirect response: -# LogonFlags: uint8_t -# ServerNameSize: uint8_t */ #define SIZE_DFLT_ROPLOGON_REDIRECT 2 #define SIZE_NULL_TRANSACTION 2 /** \details LongTermId structure is fixed size: -# DatabaseGUID: uint8_t * 16 -# GlobalCounter: uint8_t * 6 -# padding: uint16_t */ #define SIZE_DFLT_LONGTERMID 24 /** \details PropertyName structure is fixed size: -# Kind: uint8_t -# GUID: uint8_t * 16 */ #define SIZE_DFLT_PROPERTYNAME 17 /** \details FastTransferSourceGetBuffer has a fixed size for: -# TransferStatus: uint16_t -# InProgressCount: uint16_t -# TotalStepCount: uint16_t -# Reserved (1 byte): uint8_t -# TransferBufferSize (2 bytes): uint16_t */ #define SIZE_DFLT_ROPFASTTRANSFERSOURCEGETBUFFER 9 /** \details SyncImportMessageChange has a fixed size for: -# FolderId: uint64_t */ #define SIZE_DFLT_ROPSYNCIMPORTMESSAGECHANGE 8 /** \details SyncImportHierarchyChange has a fixed size for: -# FolderId: uint64_t */ #define SIZE_DFLT_ROPSYNCIMPORTHIERARCHYCHANGE 8 /** \details SyncImportMessageMove has a fixed size for: -# MessageId: uint64_t */ #define SIZE_DFLT_ROPSYNCIMPORTMESSAGEMOVE 8 /** \details GetLocalReplicaIds has a fixed size for: -# ReplGuid: sizeof (struct GUID) -# GlobalCount: uint8_t * 6 */ #define SIZE_DFLT_ROPGETLOCALREPLICAIDS 22 __BEGIN_DECLS /* definitions from libmapiserver_oxcfold.c */ uint16_t libmapiserver_RopOpenFolder_size(struct EcDoRpc_MAPI_REPL *); uint16_t libmapiserver_RopGetHierarchyTable_size(struct EcDoRpc_MAPI_REPL *); uint16_t libmapiserver_RopGetContentsTable_size(struct EcDoRpc_MAPI_REPL *); uint16_t libmapiserver_RopCreateFolder_size(struct EcDoRpc_MAPI_REPL *); uint16_t libmapiserver_RopDeleteFolder_size(struct EcDoRpc_MAPI_REPL *); uint16_t libmapiserver_RopDeleteMessage_size(struct EcDoRpc_MAPI_REPL *); uint16_t libmapiserver_RopSetSearchCriteria_size(struct EcDoRpc_MAPI_REPL *); uint16_t libmapiserver_RopGetSearchCriteria_size(struct EcDoRpc_MAPI_REPL *); uint16_t libmapiserver_RopEmptyFolder_size(struct EcDoRpc_MAPI_REPL *); uint16_t libmapiserver_RopMoveCopyMessages_size(struct EcDoRpc_MAPI_REPL *); uint16_t libmapiserver_RopMoveFolder_size(struct EcDoRpc_MAPI_REPL *); uint16_t libmapiserver_RopCopyFolder_size(struct EcDoRpc_MAPI_REPL *); /* definitions from libmapiserver_oxcmsg.c */ uint16_t libmapiserver_RopOpenMessage_size(struct EcDoRpc_MAPI_REPL *); uint16_t libmapiserver_RopCreateMessage_size(struct EcDoRpc_MAPI_REPL *); uint16_t libmapiserver_RopSaveChangesMessage_size(struct EcDoRpc_MAPI_REPL *); uint16_t libmapiserver_RopRemoveAllRecipients_size(struct EcDoRpc_MAPI_REPL *); uint16_t libmapiserver_RopModifyRecipients_size(struct EcDoRpc_MAPI_REPL *); uint16_t libmapiserver_RopReloadCachedInformation_size(struct EcDoRpc_MAPI_REPL *); uint16_t libmapiserver_RopSetMessageReadFlag_size(struct EcDoRpc_MAPI_REPL *); uint16_t libmapiserver_RopGetAttachmentTable_size(struct EcDoRpc_MAPI_REPL *); uint16_t libmapiserver_RopOpenAttach_size(struct EcDoRpc_MAPI_REPL *); uint16_t libmapiserver_RopCreateAttach_size(struct EcDoRpc_MAPI_REPL *); uint16_t libmapiserver_RopSaveChangesAttachment_size(struct EcDoRpc_MAPI_REPL *); uint16_t libmapiserver_RopOpenEmbeddedMessage_size(struct EcDoRpc_MAPI_REPL *response); /* definitions from libmapiserver_oxcnotif.c */ uint16_t libmapiserver_RopRegisterNotification_size(void); uint16_t libmapiserver_RopNotify_size(struct EcDoRpc_MAPI_REPL *); /* definitions from libmapiserver_oxcdata.c */ uint16_t libmapiserver_TypedString_size(struct TypedString); uint16_t libmapiserver_RecipientRow_size(struct RecipientRow); uint16_t libmapiserver_LongTermId_size(void); uint16_t libmapiserver_PropertyName_size(struct MAPINAMEID *); uint16_t libmapiserver_mapi_SPropValue_size(uint16_t, struct mapi_SPropValue *); /* definitions from libmapiserver_oxcprpt.c */ uint16_t libmapiserver_RopSetProperties_size(struct EcDoRpc_MAPI_REPL *); uint16_t libmapiserver_RopDeleteProperties_size(struct EcDoRpc_MAPI_REPL *); uint16_t libmapiserver_RopGetPropertiesSpecific_size(struct EcDoRpc_MAPI_REQ *, struct EcDoRpc_MAPI_REPL *); uint16_t libmapiserver_RopGetPropertiesAll_size(struct EcDoRpc_MAPI_REPL *); uint16_t libmapiserver_RopGetPropertiesList_size(struct EcDoRpc_MAPI_REPL *); uint16_t libmapiserver_RopOpenStream_size(struct EcDoRpc_MAPI_REPL *); uint16_t libmapiserver_RopReadStream_size(struct EcDoRpc_MAPI_REPL *); uint16_t libmapiserver_RopWriteStream_size(struct EcDoRpc_MAPI_REPL *); uint16_t libmapiserver_RopCommitStream_size(struct EcDoRpc_MAPI_REPL *); uint16_t libmapiserver_RopGetStreamSize_size(struct EcDoRpc_MAPI_REPL *); uint16_t libmapiserver_RopSeekStream_size(struct EcDoRpc_MAPI_REPL *); uint16_t libmapiserver_RopSetStreamSize_size(struct EcDoRpc_MAPI_REPL *); uint16_t libmapiserver_RopGetNamesFromIDs_size(struct EcDoRpc_MAPI_REPL *); uint16_t libmapiserver_RopGetPropertyIdsFromNames_size(struct EcDoRpc_MAPI_REPL *); uint16_t libmapiserver_RopDeletePropertiesNoReplicate_size(struct EcDoRpc_MAPI_REPL *); uint16_t libmapiserver_RopCopyTo_size(struct EcDoRpc_MAPI_REPL *); int libmapiserver_push_property(TALLOC_CTX *, uint32_t, const void *, DATA_BLOB *, uint8_t, uint8_t, uint8_t); struct SRow *libmapiserver_ROP_request_to_properties(TALLOC_CTX *, void *, uint8_t); /* definitions from libmapiserver_oxcstor.c */ uint16_t libmapiserver_RopLogon_size(struct EcDoRpc_MAPI_REQ *, struct EcDoRpc_MAPI_REPL *); uint16_t libmapiserver_RopRelease_size(void); uint16_t libmapiserver_RopSetReceiveFolder_size(struct EcDoRpc_MAPI_REPL *); uint16_t libmapiserver_RopGetReceiveFolder_size(struct EcDoRpc_MAPI_REPL *); uint16_t libmapiserver_RopLongTermIdFromId_size(struct EcDoRpc_MAPI_REPL *); uint16_t libmapiserver_RopIdFromLongTermId_size(struct EcDoRpc_MAPI_REPL *); uint16_t libmapiserver_RopGetPerUserLongTermIds_size(struct EcDoRpc_MAPI_REPL *); uint16_t libmapiserver_RopReadPerUserInformation_size(struct EcDoRpc_MAPI_REPL *); uint16_t libmapiserver_RopGetPerUserGuid_size(struct EcDoRpc_MAPI_REPL *); uint16_t libmapiserver_RopGetStoreState_size(struct EcDoRpc_MAPI_REPL *); uint16_t libmapiserver_RopGetReceiveFolderTable_size(struct EcDoRpc_MAPI_REPL *); /* definitions from libmapiserver_oxctabl.c */ uint16_t libmapiserver_RopSetColumns_size(struct EcDoRpc_MAPI_REPL *); uint16_t libmapiserver_RopSortTable_size(struct EcDoRpc_MAPI_REPL *); uint16_t libmapiserver_RopRestrict_size(struct EcDoRpc_MAPI_REPL *); uint16_t libmapiserver_RopQueryRows_size(struct EcDoRpc_MAPI_REPL *); uint16_t libmapiserver_RopQueryPosition_size(struct EcDoRpc_MAPI_REPL *); uint16_t libmapiserver_RopSeekRow_size(struct EcDoRpc_MAPI_REPL *); uint16_t libmapiserver_RopFindRow_size(struct EcDoRpc_MAPI_REPL *); uint16_t libmapiserver_RopResetTable_size(struct EcDoRpc_MAPI_REPL *); /* definitions from libmapiserver_oxomsg.c */ uint16_t libmapiserver_RopSubmitMessage_size(struct EcDoRpc_MAPI_REPL *); uint16_t libmapiserver_RopSetSpooler_size(struct EcDoRpc_MAPI_REPL *); uint16_t libmapiserver_RopGetAddressTypes_size(struct EcDoRpc_MAPI_REPL *); uint16_t libmapiserver_RopTransportSend_size(struct EcDoRpc_MAPI_REPL *); uint16_t libmapiserver_RopGetTransportFolder_size(struct EcDoRpc_MAPI_REPL *); uint16_t libmapiserver_RopOptionsData_size(struct EcDoRpc_MAPI_REPL *); /* definitions from libmapiserver_oxorule.c */ uint16_t libmapiserver_RopGetRulesTable_size(void); uint16_t libmapiserver_RopModifyRules_size(void); /* definitions from libmapiserver_oxcperm.c */ uint16_t libmapiserver_RopGetPermissionsTable_size(struct EcDoRpc_MAPI_REPL *); uint16_t libmapiserver_RopModifyPermissions_size(struct EcDoRpc_MAPI_REPL *); /* definitions from libmapiserver_oxcfxics.c */ uint16_t libmapiserver_RopFastTransferSourceCopyTo_size(struct EcDoRpc_MAPI_REPL *); uint16_t libmapiserver_RopFastTransferSourceGetBuffer_size(struct EcDoRpc_MAPI_REPL *); uint16_t libmapiserver_RopSyncConfigure_size(struct EcDoRpc_MAPI_REPL *); uint16_t libmapiserver_RopSyncImportMessageChange_size(struct EcDoRpc_MAPI_REPL *); uint16_t libmapiserver_RopSyncImportHierarchyChange_size(struct EcDoRpc_MAPI_REPL *); uint16_t libmapiserver_RopSyncImportDeletes_size(struct EcDoRpc_MAPI_REPL *); uint16_t libmapiserver_RopSyncUploadStateStreamBegin_size(struct EcDoRpc_MAPI_REPL *); uint16_t libmapiserver_RopSyncUploadStateStreamContinue_size(struct EcDoRpc_MAPI_REPL *); uint16_t libmapiserver_RopSyncUploadStateStreamEnd_size(struct EcDoRpc_MAPI_REPL *); uint16_t libmapiserver_RopSyncImportMessageMove_size(struct EcDoRpc_MAPI_REPL *); uint16_t libmapiserver_RopSyncOpenCollector_size(struct EcDoRpc_MAPI_REPL *); uint16_t libmapiserver_RopGetLocalReplicaIds_size(struct EcDoRpc_MAPI_REPL *); uint16_t libmapiserver_RopSyncImportReadStateChanges_size(struct EcDoRpc_MAPI_REPL *); uint16_t libmapiserver_RopSyncGetTransferState_size(struct EcDoRpc_MAPI_REPL *); uint16_t libmapiserver_RopSetLocalReplicaMidsetDeleted_size(struct EcDoRpc_MAPI_REPL *response); __END_DECLS #endif /* ! __LIBMAPISERVER_H__ */ openchange-2.0/mapiproxy/libmapiserver/libmapiserver_oxcdata.c000066400000000000000000000143131223057412600250750ustar00rootroot00000000000000/* libmapiserver - MAPI library for Server side OpenChange Project Copyright (C) Julien Kerihuel 2010 This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see . */ /** \file libmapiserver_oxcdata.c \brief OXCDATA Data Structures */ #include "libmapiserver.h" #include "libmapi/mapidefs.h" #include /** \details Calculate the size of a TypedString structure \param typedstring TypedString structure \return Size of typedstring structure */ _PUBLIC_ uint16_t libmapiserver_TypedString_size(struct TypedString typedstring) { uint16_t size = 0; size += sizeof (uint8_t); switch (typedstring.StringType) { case StringType_NONE: case StringType_EMPTY: break; case StringType_STRING8: if (typedstring.String.lpszA) { size += strlen(typedstring.String.lpszA) + 1; } break; case StringType_UNICODE_REDUCED: if (typedstring.String.lpszW_reduced) { size += strlen(typedstring.String.lpszW_reduced) + 1; } break; case StringType_UNICODE: if (typedstring.String.lpszW) { size += strlen_m_ext(typedstring.String.lpszW, CH_UTF8, CH_UTF16LE) * 2 + 2; } break; } return size; } /** \details Calculate the size of a RecipientRow structure \param recipientrow RecipientRow structure \return Size of RecipientRow structure */ _PUBLIC_ uint16_t libmapiserver_RecipientRow_size(struct RecipientRow recipientrow) { uint16_t size = 0; /* RecipientFlags */ size += sizeof (uint16_t); /* recipient_type */ if ((recipientrow.RecipientFlags & 0x7) == 0x1) { size += sizeof (uint8_t) * 2; /* AddressPrefixUsed + DisplayType */ size += strlen(recipientrow.X500DN.recipient_x500name) + 1; } /* recipient_EmailAddress */ switch (recipientrow.RecipientFlags & 0x208) { case 0x8: size += strlen(recipientrow.EmailAddress.lpszA); break; case 0x208: size += strlen(recipientrow.EmailAddress.lpszW) * 2 + 2; break; default: break; } /* recipient_DisplayName */ switch (recipientrow.RecipientFlags & 0x210) { case 0x10: size += strlen(recipientrow.DisplayName.lpszA); break; case 0x210: size += strlen_m_ext(recipientrow.DisplayName.lpszW, CH_UTF8, CH_UTF16LE) * 2 + 2; break; default: break; } /* recipient_SimpleDisplayName */ switch (recipientrow.RecipientFlags & 0x600) { case 0x400: size += strlen(recipientrow.SimpleDisplayName.lpszA); break; case 0x600: size += strlen_m_ext(recipientrow.SimpleDisplayName.lpszW, CH_UTF8, CH_UTF16LE) * 2 + 2; break; default: break; } /* recipient_TransmittableDisplayName */ switch (recipientrow.RecipientFlags & 0x260) { case 0x20: size += strlen(recipientrow.TransmittableDisplayName.lpszA); break; case 0x220: size += strlen_m_ext(recipientrow.TransmittableDisplayName.lpszW, CH_UTF8, CH_UTF16LE) * 2 + 2; break; default: break; } /* prop_count */ size += sizeof (uint16_t); /* layout */ size += sizeof (uint8_t); /* prop_values */ size += sizeof (uint16_t); size += recipientrow.prop_values.length; return size; } /** \details Calculate the size of a LongTermId structure \return Size of LongTermId structure */ _PUBLIC_ uint16_t libmapiserver_LongTermId_size(void) { return SIZE_DFLT_LONGTERMID; } /** \details Calculate the size of a PropertyName structure \return Size of PropertyName structure */ _PUBLIC_ uint16_t libmapiserver_PropertyName_size(struct MAPINAMEID *property_name) { int16_t size = SIZE_DFLT_PROPERTYNAME; if (property_name->ulKind == MNID_ID) { size += 4; /* LID */ } else if (property_name->ulKind == MNID_STRING) { /* MNID_STRING */ size += 1; /* NameSize */ size += property_name->kind.lpwstr.NameSize; } return size; } /** \details Calculate the size of a mapi_SPropValue array structure \return Size of mapi_SPropValue structure */ _PUBLIC_ uint16_t libmapiserver_mapi_SPropValue_size(uint16_t cValues, struct mapi_SPropValue *lpProps) { uint16_t size = 0; int i = 0; int j = 0; for (i = 0; i < cValues; i++) { size += 4; /* ulPropTag */ switch (lpProps[i].ulPropTag & 0xFFFF) { case PT_I2: /* Equivalent to PT_SHORT */ size += sizeof (uint16_t); break; case PT_LONG: size += sizeof (uint32_t); break; case PT_DOUBLE: size += sizeof (double); break; case PT_ERROR: size += sizeof (uint32_t); break; case PT_BOOLEAN: size += sizeof (uint8_t); break; case PT_I8: size += sizeof (int64_t); break; case PT_STRING8: size += strlen(lpProps[i].value.lpszA) + 1; break; case PT_UNICODE: size += strlen(lpProps[i].value.lpszW) * 2 + 2; break; case PT_SYSTIME: size += sizeof (uint32_t) * 2; break; case PT_CLSID: size += sizeof (struct GUID); break; case PT_SRESTRICT: case PT_ACTIONS: break; case PT_BINARY: case PT_SVREID: size += sizeof (uint16_t); size += lpProps[i].value.bin.cb; break; case PT_MV_LONG: size += sizeof (uint32_t); size += lpProps[i].value.MVl.cValues * sizeof (uint32_t); break; case PT_MV_STRING8: size += sizeof (uint32_t); for (j = 0; j < lpProps[i].value.MVszA.cValues; j++) { size += strlen(lpProps[i].value.MVszA.strings[j].lppszA) + 1; } break; case PT_MV_UNICODE: size += sizeof (uint32_t); for (j = 0; j < lpProps[i].value.MVszW.cValues; j++) { size += strlen(lpProps[i].value.MVszW.strings[j].lppszW) * 2 + 2; } break; case PT_MV_CLSID: size += sizeof (uint32_t); size += lpProps[i].value.MVguid.cValues * sizeof (struct GUID); break; case PT_MV_BINARY: size += sizeof (uint32_t); for (j = 0; j < lpProps[i].value.MVbin.cValues; j++) { size += 2; size += lpProps[i].value.MVbin.bin[j].cb; } break; default: abort(); } } return size; } openchange-2.0/mapiproxy/libmapiserver/libmapiserver_oxcfold.c000066400000000000000000000154641223057412600251200ustar00rootroot00000000000000/* libmapiserver - MAPI library for Server side OpenChange Project Copyright (C) Julien Kerihuel 2009 This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see . */ /** \file libmapiserver_oxcfold.c \brief OXCFOLD ROP Response size calculations */ #include "libmapiserver.h" /** \details Calculate OpenFolder Rop size \param response pointer to the OpenFolder EcDoRpc_MAPI_REPL structure \return Size of OpenFolder response */ _PUBLIC_ uint16_t libmapiserver_RopOpenFolder_size(struct EcDoRpc_MAPI_REPL *response) { uint16_t size = SIZE_DFLT_MAPI_RESPONSE; if (!response || response->error_code) { return size; } size += SIZE_DFLT_ROPOPENFOLDER; /* No ghosted folder for the moment */ return size; } /** \details Calculate GetHierarchyTable Rop size \param response pointer to the GetHierarchyTable EcDoRpc_MAPI_REPL structure \return Size of GetHierarchyTable response */ _PUBLIC_ uint16_t libmapiserver_RopGetHierarchyTable_size(struct EcDoRpc_MAPI_REPL *response) { uint16_t size = SIZE_DFLT_MAPI_RESPONSE; if (!response || response->error_code) { return size; } size += SIZE_DFLT_ROPGETHIERARCHYTABLE; return size; } /** \details Calculate GetContentsTable Rop size \param response pointer to the GetContentsTable EcDoRpc_MAPI_REPL structure \return Size of GetContentsTable response */ _PUBLIC_ uint16_t libmapiserver_RopGetContentsTable_size(struct EcDoRpc_MAPI_REPL *response) { uint16_t size = SIZE_DFLT_MAPI_RESPONSE; if (!response || response->error_code) { return size; } size += SIZE_DFLT_ROPGETCONTENTSTABLE; return size; } /** \details Calculate CreateFolder Rop size \param response pointer to the CreateFolder EcDoRpc_MAPI_REPL structure \return Size of CreateFolder response */ _PUBLIC_ uint16_t libmapiserver_RopCreateFolder_size(struct EcDoRpc_MAPI_REPL *response) { uint16_t size = SIZE_DFLT_MAPI_RESPONSE; if (!response || response->error_code) { return size; } size += SIZE_DFLT_ROPCREATEFOLDER; if (response->u.mapi_CreateFolder.IsExistingFolder != 0) { size += sizeof(response->u.mapi_CreateFolder.GhostUnion.GhostInfo.HasRules); size += sizeof(response->u.mapi_CreateFolder.GhostUnion.GhostInfo.IsGhosted); if (response->u.mapi_CreateFolder.GhostUnion.GhostInfo.IsGhosted != 0) { size += sizeof(response->u.mapi_CreateFolder.GhostUnion.GhostInfo.Ghost.Replicas.ServerCount); size += sizeof(response->u.mapi_CreateFolder.GhostUnion.GhostInfo.Ghost.Replicas.CheapServerCount); /* TODO: size += sizeof( servers )*/ } } return size; } /** \details Calculate DeleteFolder Rop size \param response pointer to the DeleteFolder EcDoRpc_MAPI_REPL structure \return Size of DeleteFolder response */ _PUBLIC_ uint16_t libmapiserver_RopDeleteFolder_size(struct EcDoRpc_MAPI_REPL *response) { uint16_t size = SIZE_DFLT_MAPI_RESPONSE; if (!response || response->error_code) { return size; } size += SIZE_DFLT_ROPDELETEFOLDER; return size; } /** \details Calculate DeleteMessage (0x1e) Rop size \param response pointer to the DeleteMessage EcDoRpc_MAPI_REPL structure \return Size of DeleteMessage response */ _PUBLIC_ uint16_t libmapiserver_RopDeleteMessage_size(struct EcDoRpc_MAPI_REPL *response) { uint16_t size = SIZE_DFLT_MAPI_RESPONSE; if (!response || response->error_code) { return size; } size += SIZE_DFLT_ROPDELETEMESSAGE; return size; } /** \details Calculate SetSearchCriteria (0x30) Rop size \param response pointer to the SetSearchCriteria EcDoRpc_MAPI_REPL structure \return Size of SetSearchCriteria response */ _PUBLIC_ uint16_t libmapiserver_RopSetSearchCriteria_size(struct EcDoRpc_MAPI_REPL *response) { return SIZE_DFLT_MAPI_RESPONSE; } /** \details Calculate GetSearchCriteria (0x31) Rop size \param response pointer to the GetSearchCriteria EcDoRpc_MAPI_REPL structure \return Size of GetSearchCriteria response */ _PUBLIC_ uint16_t libmapiserver_RopGetSearchCriteria_size(struct EcDoRpc_MAPI_REPL *response) { uint16_t size = SIZE_DFLT_MAPI_RESPONSE; if (!response || response->error_code) { return size; } size += SIZE_DFLT_ROPGETSEARCHCRITERIA; size += response->u.mapi_GetSearchCriteria.RestrictionDataSize; size += response->u.mapi_GetSearchCriteria.FolderIdCount * sizeof (uint64_t); return size; } /** \details Calculate EmptyFolder Rop size \param response pointer to the EmptyFolder EcDoRpc_MAPI_REPL structure \return Size of EmptyFolder response */ _PUBLIC_ uint16_t libmapiserver_RopEmptyFolder_size(struct EcDoRpc_MAPI_REPL *response) { uint16_t size = SIZE_DFLT_MAPI_RESPONSE; if (!response || response->error_code) { return size; } size += SIZE_DFLT_ROPEMPTYFOLDER; return size; } /** \details Calculate MoveCopyMessages rop size \param response pointer to the MoveCopyMessags EcDoRpc_MAPI_REPL structure \return Size of MoveCopyMessages response */ _PUBLIC_ uint16_t libmapiserver_RopMoveCopyMessages_size(struct EcDoRpc_MAPI_REPL *response) { uint16_t size = SIZE_DFLT_MAPI_RESPONSE; if (!response || response->error_code) { return size; } size += SIZE_DFLT_ROPMOVECOPYMESSAGES; return size; } /** \details Calculate MoveFolder rop size \param response pointer to the MoveFolder EcDoRpc_MAPI_REPL structure \return Size of MoveFolder response */ uint16_t libmapiserver_RopMoveFolder_size(struct EcDoRpc_MAPI_REPL *response) { uint16_t size = SIZE_DFLT_MAPI_RESPONSE; if (!response || (response->error_code && response->error_code != ecDstNullObject)) { return size; } size += SIZE_DFLT_ROPMOVEFOLDER; if (response->error_code == ecDstNullObject) { size += sizeof(uint32_t); /* DestHandleIndex */ } return size; } /** \details Calculate CopyFolder rop size \param response pointer to the CopyFolder EcDoRpc_MAPI_REPL structure \return Size of CopyFolder response */ uint16_t libmapiserver_RopCopyFolder_size(struct EcDoRpc_MAPI_REPL *response) { uint16_t size = SIZE_DFLT_MAPI_RESPONSE; if (!response || (response->error_code && response->error_code != ecDstNullObject)) { return size; } size += SIZE_DFLT_ROPCOPYFOLDER; if (response->error_code == ecDstNullObject) { size += sizeof(uint32_t); /* DestHandleIndex */ } return size; } openchange-2.0/mapiproxy/libmapiserver/libmapiserver_oxcfxics.c000066400000000000000000000154731223057412600253100ustar00rootroot00000000000000/* OpenChange Server implementation EMSMDBP: EMSMDB Provider implementation Copyright (C) Inverse inc. 2010 This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see . */ /** \file libmapiserver_oxcfxics.c \brief OXCFXICS ROP Response size calculations */ #include "libmapiserver.h" /** \details Calculate FastTransferSourceCopyTo (0x4d) Rop size \param response pointer to the FastTransferSourceCopyTo EcDoRpc_MAPI_REPL structure \return Size of FastTransferSourceCopyTo response */ _PUBLIC_ uint16_t libmapiserver_RopFastTransferSourceCopyTo_size(struct EcDoRpc_MAPI_REPL *response) { return SIZE_DFLT_MAPI_RESPONSE; } /** \details Calculate FastTransferSourceGetBuffer (0x4d) Rop size \param response pointer to the FastTransferSourceGetBuffer EcDoRpc_MAPI_REPL structure \return Size of FastTransferSourceGetBuffer response */ _PUBLIC_ uint16_t libmapiserver_RopFastTransferSourceGetBuffer_size(struct EcDoRpc_MAPI_REPL *response) { uint16_t size = SIZE_DFLT_MAPI_RESPONSE; if (!response || response->error_code) { if (response->error_code == ecServerBusy) { size += sizeof (uint32_t); /* size of BackoffTime */ } return size; } size += SIZE_DFLT_ROPFASTTRANSFERSOURCEGETBUFFER + response->u.mapi_FastTransferSourceGetBuffer.TransferBuffer.length; return size; } /** \details Calculate SyncConfigure (0x70) Rop size \param response pointer to the SyncConfigure EcDoRpc_MAPI_REPL structure \return Size of SyncConfigure response */ _PUBLIC_ uint16_t libmapiserver_RopSyncConfigure_size(struct EcDoRpc_MAPI_REPL *response) { return SIZE_DFLT_MAPI_RESPONSE; } /** \details Calculate SyncImportMessageChange (0x73) Rop size \param response pointer to the SyncImportMessageChange EcDoRpc_MAPI_REPL structure \return Size of SyncImportMessageChange response */ _PUBLIC_ uint16_t libmapiserver_RopSyncImportMessageChange_size(struct EcDoRpc_MAPI_REPL *response) { uint16_t size = SIZE_DFLT_MAPI_RESPONSE; if (!response || response->error_code) { return size; } size += SIZE_DFLT_ROPSYNCIMPORTMESSAGECHANGE; return size; } /** \details Calculate SyncImportHierarchyChange (0x73) Rop size \param response pointer to the SyncImportHierarchyChange EcDoRpc_MAPI_REPL structure \return Size of SyncImportHierarchyChange response */ _PUBLIC_ uint16_t libmapiserver_RopSyncImportHierarchyChange_size(struct EcDoRpc_MAPI_REPL *response) { uint16_t size = SIZE_DFLT_MAPI_RESPONSE; if (!response || response->error_code) { return size; } size += SIZE_DFLT_ROPSYNCIMPORTHIERARCHYCHANGE; return size; } /** \details Calculate SyncImportDeletes (0x74) Rop size \param response pointer to the SyncImportDeletes EcDoRpc_MAPI_REPL structure \return Size of SyncImportDeletes response */ _PUBLIC_ uint16_t libmapiserver_RopSyncImportDeletes_size(struct EcDoRpc_MAPI_REPL *response) { return SIZE_DFLT_MAPI_RESPONSE; } /** \details Calculate SyncUploadStateStreamBegin (0x75) Rop size \param response pointer to the SyncUploadStateStreamBegin EcDoRpc_MAPI_REPL structure \return Size of SyncUploadStateStreamBegin response */ _PUBLIC_ uint16_t libmapiserver_RopSyncUploadStateStreamBegin_size(struct EcDoRpc_MAPI_REPL *response) { return SIZE_DFLT_MAPI_RESPONSE; } /** \details Calculate SyncUploadStateStreamContinue (0x76) Rop size \param response pointer to the SyncUploadStateStreamContinue EcDoRpc_MAPI_REPL structure \return Size of SyncUploadStateStreamContinue response */ _PUBLIC_ uint16_t libmapiserver_RopSyncUploadStateStreamContinue_size(struct EcDoRpc_MAPI_REPL *response) { return SIZE_DFLT_MAPI_RESPONSE; } /** \details Calculate SyncUploadStateStreamEnd (0x77) Rop size \param response pointer to the SyncUploadStateStreamEnd EcDoRpc_MAPI_REPL structure \return Size of SyncUploadStateStreamEnd response */ _PUBLIC_ uint16_t libmapiserver_RopSyncUploadStateStreamEnd_size(struct EcDoRpc_MAPI_REPL *response) { return SIZE_DFLT_MAPI_RESPONSE; } /** \details Calculate SyncImportMessageMove (0x78) Rop size \param response pointer to the SyncImportMessageMove EcDoRpc_MAPI_REPL structure \return Size of SyncImportMessageMove response */ _PUBLIC_ uint16_t libmapiserver_RopSyncImportMessageMove_size(struct EcDoRpc_MAPI_REPL *response) { uint16_t size = SIZE_DFLT_MAPI_RESPONSE; if (!response || response->error_code) { return size; } size += SIZE_DFLT_ROPSYNCIMPORTMESSAGEMOVE; return size; } /** \details Calculate SyncOpenCollector (0x7e) Rop size \param response pointer to the SyncOpenCollector EcDoRpc_MAPI_REPL structure \return Size of SyncOpenCollector response */ _PUBLIC_ uint16_t libmapiserver_RopSyncOpenCollector_size(struct EcDoRpc_MAPI_REPL *response) { return SIZE_DFLT_MAPI_RESPONSE; } /** \details Calculate GetLocalReplicaIds (0x7f) Rop size \param response pointer to the GetLocalReplicaIds EcDoRpc_MAPI_REPL structure \return Size of GetLocalReplicaIds response */ _PUBLIC_ uint16_t libmapiserver_RopGetLocalReplicaIds_size(struct EcDoRpc_MAPI_REPL *response) { uint16_t size = SIZE_DFLT_MAPI_RESPONSE; if (!response || response->error_code) { return size; } size += SIZE_DFLT_ROPGETLOCALREPLICAIDS; return size; } /** \details Calculate SyncImportReadStateChanges (0x80) Rop size \param response pointer to the SyncImportReadStateChanges EcDoRpc_MAPI_REPL structure \return Size of SyncImportReadStateChanges response */ _PUBLIC_ uint16_t libmapiserver_RopSyncImportReadStateChanges_size(struct EcDoRpc_MAPI_REPL *response) { return SIZE_DFLT_MAPI_RESPONSE; } /** \details Calculate SyncGetTransferState (0x82) Rop size \param response pointer to the SyncGetTransferState EcDoRpc_MAPI_REPL structure \return Size of SyncGetTransferState response */ _PUBLIC_ uint16_t libmapiserver_RopSyncGetTransferState_size(struct EcDoRpc_MAPI_REPL *response) { return SIZE_DFLT_MAPI_RESPONSE; } /** \details Calculate SetLocalReplicaMidsetDeleted (0x93) Rop size \param response pointer to the SetLocalReplicaMidsetDeleted EcDoRpc_MAPI_REPL structure \return Size of SetLocalReplicaMidsetDeleted response */ _PUBLIC_ uint16_t libmapiserver_RopSetLocalReplicaMidsetDeleted_size(struct EcDoRpc_MAPI_REPL *response) { return SIZE_DFLT_MAPI_RESPONSE; } openchange-2.0/mapiproxy/libmapiserver/libmapiserver_oxcmsg.c000066400000000000000000000173111223057412600247530ustar00rootroot00000000000000/* libmapiserver - MAPI library for Server side OpenChange Project Copyright (C) Julien Kerihuel 2009-2010 This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see . */ /** \file libmapiserver_oxcmsg.c \brief OXCMSG ROP Response size calculations */ #include "libmapiserver.h" /** \details Calculate OpenMessage (0x3) Rop size \param response pointer to the OpenMessage EcDoRpc_MAPI_REPL structure \return Size of OpenMessage response */ _PUBLIC_ uint16_t libmapiserver_RopOpenMessage_size(struct EcDoRpc_MAPI_REPL *response) { uint16_t size = SIZE_DFLT_MAPI_RESPONSE; uint8_t i; if (!response || response->error_code) { return size; } size += SIZE_DFLT_ROPOPENMESSAGE; /* SubjectPrefix */ size += libmapiserver_TypedString_size(response->u.mapi_OpenMessage.SubjectPrefix); /* NormalizedSubject */ size += libmapiserver_TypedString_size(response->u.mapi_OpenMessage.NormalizedSubject); /* RecipientColumns */ size += sizeof (uint16_t); size += response->u.mapi_OpenMessage.RecipientColumns.cValues * sizeof (uint32_t); for (i = 0; i < response->u.mapi_OpenMessage.RowCount; i++) { size += sizeof (uint8_t); /* ulRecipClass */ size += sizeof (uint16_t); /* CODEPAGEID */ size += sizeof (uint16_t); /* uint16 */ size += libmapiserver_RecipientRow_size(response->u.mapi_OpenMessage.RecipientRows[i].RecipientRow); } return size; } /** \details Calculate CreateMessage (0x6) Rop size \param response pointer to the CreateMessage EcDoRpc_MAPI_REPL structure \return Size of CreateMessage response */ _PUBLIC_ uint16_t libmapiserver_RopCreateMessage_size(struct EcDoRpc_MAPI_REPL *response) { uint16_t size = SIZE_DFLT_MAPI_RESPONSE; if (!response || response->error_code) { return size; } size += SIZE_DFLT_ROPCREATEMESSAGE; if (response->u.mapi_CreateMessage.HasMessageId == 1) { size += sizeof (uint64_t); } return size; } /** \details Calculate SaveChangesMessage (0xc) Rop size \param response pointer to the SaveChangesMessage EcDoRpc_MAPI_REPL structure \return Size of SaveChangesMessage response */ _PUBLIC_ uint16_t libmapiserver_RopSaveChangesMessage_size(struct EcDoRpc_MAPI_REPL *response) { uint16_t size = SIZE_DFLT_MAPI_RESPONSE; if (!response || response->error_code) { return size; } size += SIZE_DFLT_ROPSAVECHANGESMESSAGE; return size; } /** \details Calculate RemoveAllRecipients (0xd) Rop size \param response pointer to the RemoveAllRecipients EcDoRpc_MAPI_REPL structure \return Size of RemoveAllRecipients response */ _PUBLIC_ uint16_t libmapiserver_RopRemoveAllRecipients_size(struct EcDoRpc_MAPI_REPL *response) { return SIZE_DFLT_MAPI_RESPONSE; } /** \details Calculate ModifyRecipients (0xe) Rop size \param response pointer to the ModifyRecipients EcDoRpc_MAPI_REPL structure \return Size of ModifyRecipients response */ _PUBLIC_ uint16_t libmapiserver_RopModifyRecipients_size(struct EcDoRpc_MAPI_REPL *response) { return SIZE_DFLT_MAPI_RESPONSE; } /** \details Calculate ReloadCachedInformation (0x10) Rop size \param response pointer to the ReloadCachedInformation EcDoRpc_MAPI_REPL structure \return Size of ReloadCachedInformation response */ _PUBLIC_ uint16_t libmapiserver_RopReloadCachedInformation_size(struct EcDoRpc_MAPI_REPL *response) { uint16_t size = SIZE_DFLT_MAPI_RESPONSE; uint8_t i; if (!response || response->error_code) { return size; } size += SIZE_DFLT_ROPRELOADCACHEDINFORMATION; /* SubjectPrefix */ size += libmapiserver_TypedString_size(response->u.mapi_ReloadCachedInformation.SubjectPrefix); /* NormalizedSubject */ size += libmapiserver_TypedString_size(response->u.mapi_ReloadCachedInformation.NormalizedSubject); /* RecipientColumns */ size += sizeof (uint16_t); size += response->u.mapi_ReloadCachedInformation.RecipientColumns.cValues * sizeof (uint32_t); for (i = 0; i < response->u.mapi_ReloadCachedInformation.RowCount; i++) { size += sizeof (uint8_t); size += sizeof (uint16_t); size += sizeof (uint16_t); size += libmapiserver_RecipientRow_size(response->u.mapi_ReloadCachedInformation.RecipientRows[i].RecipientRow); } return size; } /** \details Calculate SetMessageReadFlag (0x11) Rop size \param response pointer to the SetMessageReadFlag EcDoRpc_MAPI_REPL structure \return Size of SetMessageReadFlag response */ _PUBLIC_ uint16_t libmapiserver_RopSetMessageReadFlag_size(struct EcDoRpc_MAPI_REPL *response) { uint16_t size = SIZE_DFLT_MAPI_RESPONSE; if (!response || response->error_code) { return size; } size += SIZE_DFLT_ROPSETMESSAGEREADFLAG; if (response->u.mapi_SetMessageReadFlag.ReadStatusChanged == 0x1) { size += sizeof (uint8_t); size += sizeof (uint8_t) * 24; } return size; } /** \details Calculate GetAttachmentTable (0x21) Rop size \param response pointer to the GetAttachmentTable EcDoRpc_MAPI_REPL \return Size of GetAttachmentTable response */ _PUBLIC_ uint16_t libmapiserver_RopGetAttachmentTable_size(struct EcDoRpc_MAPI_REPL *response) { return SIZE_DFLT_MAPI_RESPONSE; } /** \details Calculate OpenAttach (0x22) Rop size \param response pointer to the OpenAttach EcDoRpc_MAPI_REPL \return Size of OpenAttach response */ _PUBLIC_ uint16_t libmapiserver_RopOpenAttach_size(struct EcDoRpc_MAPI_REPL *response) { return SIZE_DFLT_MAPI_RESPONSE; } /** \details Calculate CreateAttach (0x23) Rop size \param response pointer to the CreateAttach EcDoRpc_MAPI_REPL \return Size of CreateAttach response */ _PUBLIC_ uint16_t libmapiserver_RopCreateAttach_size(struct EcDoRpc_MAPI_REPL *response) { uint16_t size = SIZE_DFLT_MAPI_RESPONSE; if (!response || response->error_code) { return size; } size += SIZE_DFLT_ROPCREATEATTACH; return size; } /** \details Calculate SaveChangesAttachment (0x25) Rop size \param response pointer to the SaveChangesAttachment EcDoRpc_MAPI_REPL \return Size of SaveChangesAttachment response */ _PUBLIC_ uint16_t libmapiserver_RopSaveChangesAttachment_size(struct EcDoRpc_MAPI_REPL *response) { return SIZE_DFLT_MAPI_RESPONSE; } /** \details Calculate OpenEmbeddedMessage (0x46) Rop size \param response pointer to the OpenEmbeddedMessage EcDoRpc_MAPI_REPL \return Size of OpenEmbeddedMessage response */ _PUBLIC_ uint16_t libmapiserver_RopOpenEmbeddedMessage_size(struct EcDoRpc_MAPI_REPL *response) { uint16_t size = SIZE_DFLT_MAPI_RESPONSE; uint8_t i; if (!response || response->error_code) { return size; } size += SIZE_DFLT_ROPOPENEMBEDDEDMESSAGE; /* SubjectPrefix */ size += libmapiserver_TypedString_size(response->u.mapi_OpenMessage.SubjectPrefix); /* NormalizedSubject */ size += libmapiserver_TypedString_size(response->u.mapi_OpenMessage.NormalizedSubject); /* RecipientColumns */ size += response->u.mapi_OpenEmbeddedMessage.RecipientColumns.cValues * sizeof (uint32_t); for (i = 0; i < response->u.mapi_OpenEmbeddedMessage.RowCount; i++) { size += sizeof (uint8_t); size += sizeof (uint16_t); size += sizeof (uint16_t); size += libmapiserver_RecipientRow_size(response->u.mapi_OpenEmbeddedMessage.RecipientRows[i].RecipientRow); } return size; } openchange-2.0/mapiproxy/libmapiserver/libmapiserver_oxcnotif.c000066400000000000000000000221141223057412600253010ustar00rootroot00000000000000/* libmapiserver - MAPI library for Server side OpenChange Project Copyright (C) Julien Kerihuel 2009 This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see . */ /** \file libmapiserver_oxcnotif.c \brief OXCNOTIF ROP Response size calculations */ #include "libmapiserver.h" #include /** \details Calculate RegisterNotification Rop size \return Size of RegisterNotification response */ _PUBLIC_ uint16_t libmapiserver_RopRegisterNotification_size(void) { return SIZE_DFLT_MAPI_RESPONSE; } /** \details Calculate Notify Rop size \return Size of Notify response */ _PUBLIC_ uint16_t libmapiserver_RopNotify_size(struct EcDoRpc_MAPI_REPL *response) { uint16_t size = SIZE_DFLT_ROPNOTIFY; union NotificationData *NotificationData; /* TODO: to be completed... */ NotificationData = &response->u.mapi_Notify.NotificationData; printf("Looking for: 0x%x\n", response->u.mapi_Notify.NotificationType); switch (response->u.mapi_Notify.NotificationType) { /* Folders */ case 0x3010: /* different forms of folder modifications */ size += sizeof (uint32_t); break; case 0x1010: case 0x2010: size += sizeof (uint32_t); break; case 0x0010: /* folder modified */ size += sizeof(uint64_t) + sizeof(uint16_t); if (NotificationData->FolderModifiedNotification_10.TagCount != 0xffff) { size += sizeof(enum MAPITAGS) * NotificationData->FolderModifiedNotification_10.TagCount; } break; case 0x0004: /* folder created */ break; case 0x0002: /* newmail */ case 0x8002: size += sizeof (uint64_t) * 2 + sizeof (uint32_t) + sizeof (uint8_t); if (NotificationData->NewMailNotification.UnicodeFlag == false) { size += strlen(NotificationData->NewMailNotification.MessageClass.lpszA); } else { size += strlen(NotificationData->NewMailNotification.MessageClass.lpszW) * 2 + 2; } break; case 0x8004: /* message created */ case 0x8010: /* message modified */ size += sizeof(uint16_t); if (NotificationData->MessageCreatedNotification.TagCount != 0xffff) { size += sizeof(enum MAPITAGS) * NotificationData->MessageCreatedNotification.TagCount; } break; case 0x8008: /* message deleted */ case 0x0008: /* folder deleted */ size += 2 * sizeof(uint64_t); break; /* Tables */ case 0x0100: /* hierarchy table changed */ size += sizeof(uint16_t); /* TableEventType */ switch (NotificationData->HierarchyTableChange.TableEvent) { case TABLE_ROW_ADDED: size += 2 * sizeof(uint64_t); /* FID and InsertAfterFID */ size += sizeof(uint16_t) + NotificationData->HierarchyTableChange.HierarchyTableChangeUnion.HierarchyRowAddedNotification.Columns.length; /* blob length */ break; case TABLE_ROW_DELETED: size += sizeof(uint64_t); /* FID */ break; case TABLE_ROW_MODIFIED: size += 2 * sizeof(uint64_t); /* FID and InsertAfterFID */ size += sizeof(uint16_t) + NotificationData->HierarchyTableChange.HierarchyTableChangeUnion.HierarchyRowModifiedNotification.Columns.length; /* blob length */ break; default: /* TABLE_CHANGED and TABLE_RESTRICT_DONE */ size += 0; } break; case 0x8100: /* contents table changed */ size += sizeof(uint16_t); /* TableEventType */ switch (NotificationData->ContentsTableChange.TableEvent) { case TABLE_ROW_ADDED: size += 2 * (2 * sizeof(uint64_t) + sizeof(uint32_t)); /* FID, MID, Instance, InsertAfterFID, InsertAfterMID, InsertAfterInstance */ size += sizeof(uint16_t) + NotificationData->ContentsTableChange.ContentsTableChangeUnion.ContentsRowAddedNotification.Columns.length; /* blob length */ break; case TABLE_ROW_DELETED: size += 2 * sizeof(uint64_t) + sizeof(uint32_t); /* FID, MID, Instance */ break; case TABLE_ROW_MODIFIED: size += 2 * (2 * sizeof(uint64_t) + sizeof(uint32_t)); /* FID, MID, Instance, InsertAfterFID, InsertAfterMID, InsertAfterInstance */ size += sizeof(uint16_t) + NotificationData->ContentsTableChange.ContentsTableChangeUnion.ContentsRowModifiedNotification.Columns.length; break; default: /* TABLE_CHANGED and TABLE_RESTRICT_DONE */ size += 0; } break; case 0xc100: /* search table changed */ size += sizeof(uint16_t); /* TableEventType */ switch (NotificationData->SearchTableChange.TableEvent) { case TABLE_ROW_ADDED: size += 2 * (2 * sizeof(uint64_t) + sizeof(uint32_t)); /* FID, MID, Instance, InsertAfterFID, InsertAfterMID, InsertAfterInstance */ size += sizeof(uint16_t) + NotificationData->SearchTableChange.ContentsTableChangeUnion.ContentsRowAddedNotification.Columns.length; /* blob length */ break; case TABLE_ROW_DELETED: size += 2 * sizeof(uint64_t) + sizeof(uint32_t); /* FID, MID, Instance */ break; case TABLE_ROW_MODIFIED: size += 2 * (2 * sizeof(uint64_t) + sizeof(uint32_t)); /* FID, MID, Instance, InsertAfterFID, InsertAfterMID, InsertAfterInstance */ size += sizeof(uint16_t) + NotificationData->SearchTableChange.ContentsTableChangeUnion.ContentsRowModifiedNotification.Columns.length; break; default: /* TABLE_CHANGED and TABLE_RESTRICT_DONE */ size += 0; } break; /* case 0x0002: */ /* case 0x8002: */ /* size += sizeof(struct NewMailNotification); */ /* if (response->u.mapi_Notify.NewMailNotification.UnicodeFlag) { */ /* size += strlen_m_ext(response->u.mapi_Notify.NewMailNotification.MessageClass.lpszW, CH_UTF8, CH_UTF16BE) * 2 + 2; */ /* } */ /* else { */ /* size += strlen(response->u.mapi_Notify.NewMailNotification.MessageClass.lpszA) + 1; */ /* } */ /* break; */ /* case 0x0020: */ /* case 0x0040: */ /* size += sizeof(struct FolderMoveCopyNotification); */ /* break; */ /* case 0x0080: */ /* size += sizeof(struct SearchCompleteNotification); */ /* break; */ /* case 0x0100: */ /* size += sizeof(struct HierarchyTableChange); */ /* break; */ /* case 0x0200: */ /* size += sizeof(struct IcsNotification); */ /* break; */ /* case 0x1010: */ /* size += sizeof(struct FolderModifiedNotification_1010); */ /* break; */ /* case 0x2010: */ /* size += sizeof(struct FolderModifiedNotification_2010); */ /* break; */ /* case 0x3010: */ /* size += sizeof(struct FolderModifiedNotification_3010); */ /* break; */ case 0x8020: case 0x8040: size += sizeof(struct MessageMoveCopyNotification); break; /* case 0x8100: */ /* case 0xc100: */ /* size += sizeof(struct ContentsTableChange); */ /* break; */ /* case 0xc004: */ /* size += sizeof(struct SearchMessageCreatedNotification); */ /* break; */ /* case 0xc008: */ /* size += sizeof(struct SearchMessageRemovedNotification); */ /* break; */ /* case 0xc010: */ /* size += sizeof(struct SearchMessageModifiedNotification); */ /* break; */ default: DEBUG(5, (__location__": unhandled size case %.4x, expect buffer errors soon\n", response->u.mapi_Notify.NotificationType)); } return size; } openchange-2.0/mapiproxy/libmapiserver/libmapiserver_oxcperm.c000066400000000000000000000027711223057412600251340ustar00rootroot00000000000000/* libmapiserver - MAPI library for Server side OpenChange Project Copyright (C) Julien Kerihuel 2010 This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see . */ /** \file libmapiserver_oxcmsg.c \brief OXCMSG ROP Response size calculations */ #include "libmapiserver.h" /** \details Calculate GetPermissionsTable Rop size \param response pointer to the GetPermissionsTable EcDoRpc_MAPI_REPL structure \return Size of GetPermissionsTable response */ _PUBLIC_ uint16_t libmapiserver_RopGetPermissionsTable_size(struct EcDoRpc_MAPI_REPL *response) { return SIZE_DFLT_MAPI_RESPONSE; } /** \details Calculate ModifyPermissions Rop size \param response pointer to the ModifyPermissions EcDoRpc_MAPI_REPL structure \return Size of ModifyPermissions response */ _PUBLIC_ uint16_t libmapiserver_RopModifyPermissions_size(struct EcDoRpc_MAPI_REPL *response) { return SIZE_DFLT_MAPI_RESPONSE; } openchange-2.0/mapiproxy/libmapiserver/libmapiserver_oxcprpt.c000066400000000000000000000357241223057412600251620ustar00rootroot00000000000000/* libmapiserver - MAPI library for Server side OpenChange Project Copyright (C) Julien Kerihuel 2009 This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see . */ /** \file libmapiserver_oxcprpt.c \brief OXCPRPT ROP Response size calculations */ #include "libmapiserver.h" #include "libmapi/libmapi.h" #include "libmapi/mapidefs.h" #include "gen_ndr/ndr_exchange.h" #include /** \details Calculate GetPropertiesSpecific Rop size \param request pointer to the GetPropertiesSpecific EcDoRpc_MAPI_REQ structure \param response pointer to the GetPropertiesSpecific EcDoRpc_MAPI_REPL structure \return Size of GetPropsSpecific response */ _PUBLIC_ uint16_t libmapiserver_RopGetPropertiesSpecific_size(struct EcDoRpc_MAPI_REQ *request, struct EcDoRpc_MAPI_REPL *response) { uint16_t size = SIZE_DFLT_MAPI_RESPONSE; if (!response || response->error_code) { return size; } size += SIZE_DFLT_ROPGETPROPERTIESSPECIFIC; size += response->u.mapi_GetProps.prop_data.length; return size; } /** \details Calculate GetPropertiesAll Rop size \param request pointer to the GetPropertiesAll EcDoRpc_MAPI_REPL structure \return Size of GetPropsAll response */ _PUBLIC_ uint16_t libmapiserver_RopGetPropertiesAll_size(struct EcDoRpc_MAPI_REPL *response) { uint16_t size = SIZE_DFLT_MAPI_RESPONSE; if (!response || response->error_code) { return size; } size += SIZE_DFLT_ROPGETPROPERTIESALL; size += libmapiserver_mapi_SPropValue_size(response->u.mapi_GetPropsAll.properties.cValues, response->u.mapi_GetPropsAll.properties.lpProps); return size; } /** \details Calculate GetPropertiesList Rop size \param request pointer to the GetPropertiesList EcDoRpc_MAPI_REPL structure \return Size of GetPropertiesList response */ _PUBLIC_ uint16_t libmapiserver_RopGetPropertiesList_size(struct EcDoRpc_MAPI_REPL *response) { uint16_t size = SIZE_DFLT_MAPI_RESPONSE; if (!response || response->error_code) { return size; } size += SIZE_DFLT_ROPGETPROPERTIESLIST; size += sizeof (uint32_t) * response->u.mapi_GetPropList.count; return size; } /** \details Calculate SetProperties Rop size \param response pointer to the SetProperties EcDoRpc_MAPI_REPL structure \return Size of SetProperties response */ _PUBLIC_ uint16_t libmapiserver_RopSetProperties_size(struct EcDoRpc_MAPI_REPL *response) { uint16_t size = SIZE_DFLT_MAPI_RESPONSE; if (!response || response->error_code) { return size; } size += SIZE_DFLT_ROPSETPROPERTIES; if (response->u.mapi_SetProps.PropertyProblemCount) { size += response->u.mapi_SetProps.PropertyProblemCount * sizeof(struct PropertyProblem); } return size; } /** \details Calculate SetProperties Rop size \param response pointer to the SetProperties EcDoRpc_MAPI_REPL structure \return Size of SetProperties response */ _PUBLIC_ uint16_t libmapiserver_RopDeleteProperties_size(struct EcDoRpc_MAPI_REPL *response) { uint16_t size = SIZE_DFLT_MAPI_RESPONSE; if (!response || response->error_code) { return size; } size += SIZE_DFLT_ROPDELETEPROPERTIES; if (response->u.mapi_DeleteProps.PropertyProblemCount) { size += response->u.mapi_DeleteProps.PropertyProblemCount * sizeof(struct PropertyProblem); } return size; } /** \details Calculate CopyTo Rop size \param response pointer to the CopyTo EcDoRpc_MAPI_REPL structure \return Size of SetProperties response */ _PUBLIC_ uint16_t libmapiserver_RopCopyTo_size(struct EcDoRpc_MAPI_REPL *response) { uint16_t size = SIZE_DFLT_MAPI_RESPONSE; if (!response || response->error_code) { return size; } size += SIZE_DFLT_ROPCOPYTO; size += response->u.mapi_CopyTo.PropertyProblemCount * sizeof(struct PropertyProblem); return size; } /** \details Calculate OpenStream Rop size \param response pointer to the OpenStream EcDoRpc_MAPI_REPL structure \return Size of OpenStream response */ _PUBLIC_ uint16_t libmapiserver_RopOpenStream_size(struct EcDoRpc_MAPI_REPL *response) { uint16_t size = SIZE_DFLT_MAPI_RESPONSE; if (!response || response->error_code) { return size; } size += SIZE_DFLT_ROPOPENSTREAM; return size; } /** \details Calculate ReadStream Rop size \param response pointer to the ReadStream EcDoRpc_MAPI_REPL structure \return Size of ReadStream response */ _PUBLIC_ uint16_t libmapiserver_RopReadStream_size(struct EcDoRpc_MAPI_REPL *response) { uint16_t size = SIZE_DFLT_MAPI_RESPONSE; if (!response || response->error_code) { return size; } size += SIZE_DFLT_ROPREADSTREAM; if (response->u.mapi_ReadStream.data.length) { size += response->u.mapi_ReadStream.data.length; } return size; } /** \details Calculate WriteStream Rop size \param response pointer to the WriteStream EcDoRpc_MAPI_REPL structure \return Size of WriteStream response */ _PUBLIC_ uint16_t libmapiserver_RopWriteStream_size(struct EcDoRpc_MAPI_REPL *response) { uint16_t size = SIZE_DFLT_MAPI_RESPONSE; if (!response || response->error_code) { return size; } size += SIZE_DFLT_ROPWRITESTREAM; return size; } /** \details Calculate CommitStream Rop size \param response pointer to the CommitStream EcDoRpc_MAPI_REPL structure \return Size of CommitStream response */ _PUBLIC_ uint16_t libmapiserver_RopCommitStream_size(struct EcDoRpc_MAPI_REPL *response) { return SIZE_DFLT_MAPI_RESPONSE; } /** \details Calculate GetStreamSize Rop size \param response pointer to the GetStreamSize EcDoRpc_MAPI_REPL structure \return Size of GetStreamSize response */ _PUBLIC_ uint16_t libmapiserver_RopGetStreamSize_size(struct EcDoRpc_MAPI_REPL *response) { uint16_t size = SIZE_DFLT_MAPI_RESPONSE; if (!response || response->error_code) { return size; } size += SIZE_DFLT_ROPGETSTREAMSIZE; return size; } /** \details Calculate SeekStream Rop size \param response pointer to the SeekStream EcDoRpc_MAPI_REPL structure \return Size of SeekStream response */ _PUBLIC_ uint16_t libmapiserver_RopSeekStream_size(struct EcDoRpc_MAPI_REPL *response) { uint16_t size = SIZE_DFLT_MAPI_RESPONSE; if (!response || response->error_code) { return size; } size += SIZE_DFLT_ROPSEEKSTREAM; return size; } /** \details Calculate SetStreamSize Rop size \param response pointer to the SetStreamSize EcDoRpc_MAPI_REPL structure \return Size of SeekStream response */ _PUBLIC_ uint16_t libmapiserver_RopSetStreamSize_size(struct EcDoRpc_MAPI_REPL *response) { return SIZE_DFLT_MAPI_RESPONSE; } /** \details Calculate GetNamesFromIDs Rop size \param response pointer to the GetNamesFromIDs EcDoRpc_MAPI_REPL structure \return Size of GetNamesFromIDs response */ _PUBLIC_ uint16_t libmapiserver_RopGetNamesFromIDs_size(struct EcDoRpc_MAPI_REPL *response) { uint16_t size = SIZE_DFLT_MAPI_RESPONSE; uint16_t i; if (!response || response->error_code) { return size; } size += SIZE_DFLT_ROPGETNAMESFROMIDS; for (i = 0; i < response->u.mapi_GetNamesFromIDs.count; i++) { size += libmapiserver_PropertyName_size(response->u.mapi_GetNamesFromIDs.nameid + i); } return size; } /** \details Calculate GetPropertyIdsFromNames Rop size \param response pointer to the GetPropertyIdsFromNames EcDoRpc_MAPI_REPL structure \return Size of GetPropertyIdsFromNames response */ _PUBLIC_ uint16_t libmapiserver_RopGetPropertyIdsFromNames_size(struct EcDoRpc_MAPI_REPL *response) { uint16_t size = SIZE_DFLT_MAPI_RESPONSE; if (!response || (response->error_code && response->error_code != MAPI_W_ERRORS_RETURNED)) { return size; } size += SIZE_DFLT_ROPGETPROPERTYIDSFROMNAMES; if (response->u.mapi_GetIDsFromNames.count) { size += response->u.mapi_GetIDsFromNames.count * sizeof (uint16_t); } return size; } /** \details Calculate DeletePropertiesNoReplicate Rop size \param response pointer to the DeletePropertiesNoReplicate EcDoRpc_MAPI_REPL structure \return Size of DeletePropertiesNoReplicate response */ _PUBLIC_ uint16_t libmapiserver_RopDeletePropertiesNoReplicate_size(struct EcDoRpc_MAPI_REPL *response) { uint16_t size = SIZE_DFLT_MAPI_RESPONSE; if (!response || response->error_code) { return size; } size += SIZE_DFLT_ROPDELETEPROPERTIESNOREPLICATE; size += (response->u.mapi_DeletePropertiesNoReplicate.PropertyProblemCount * (sizeof(uint16_t) /* PropertyProblem.Index */ + sizeof(uint32_t) /* PropertyProblem.PropertyTag */ + sizeof(uint32_t) /* PropertyProblem.ErrorCode */)); return size; } /** \details Add a property value to a DATA blob. This convenient function should be used when creating a GetPropertiesSpecific reply response blob. \param mem_ctx pointer to the memory context \param property the property tag which value is meant to be appended to the blob \param value generic pointer on the property value \param blob the data blob the function uses to return the blob \param layout whether values should be prefixed by a layout \param flagged define if the properties are flagged or not \note blob.length must be set to 0 before this function is called the first time. Also the function only supports a limited set of property types at the moment. \return 0 on success; */ _PUBLIC_ int libmapiserver_push_property(TALLOC_CTX *mem_ctx, uint32_t property, const void *value, DATA_BLOB *blob, uint8_t layout, uint8_t flagged, uint8_t untyped) { struct ndr_push *ndr; struct SBinary_short bin; struct BinaryArray_r *bin_array; uint32_t i; ndr = ndr_push_init_ctx(mem_ctx); ndr_set_flags(&ndr->flags, LIBNDR_FLAG_NOALIGN); ndr->offset = 0; if (blob->length) { talloc_free(ndr->data); ndr->data = blob->data; ndr->offset = blob->length; } /* Step 1. Is the property typed */ if (untyped) { ndr_push_uint16(ndr, NDR_SCALARS, property & 0xFFFF); } /* Step 2. Is the property flagged */ if (flagged) { switch (property & 0xFFFF) { case PT_ERROR: switch (layout) { case 0x1: ndr_push_uint8(ndr, NDR_SCALARS, layout); goto end; case PT_ERROR: ndr_push_uint8(ndr, NDR_SCALARS, PT_ERROR); break; } break; default: ndr_push_uint8(ndr, NDR_SCALARS, 0x0); break; } } else { /* Step 3. Set the layout */ if (layout) { switch (property & 0xFFFF) { case PT_ERROR: ndr_push_uint8(ndr, NDR_SCALARS, PT_ERROR); break; default: ndr_push_uint8(ndr, NDR_SCALARS, 0x0); } } } /* Step 3. Push property data if supported */ switch (property & 0xFFFF) { case PT_I2: ndr_push_uint16(ndr, NDR_SCALARS, *(uint16_t *) value); break; case PT_LONG: case PT_ERROR: case PT_OBJECT: ndr_push_uint32(ndr, NDR_SCALARS, *(uint32_t *) value); break; case PT_DOUBLE: ndr_push_double(ndr, NDR_SCALARS, *(double *) value); break; case PT_I8: ndr_push_dlong(ndr, NDR_SCALARS, *(uint64_t *) value); break; case PT_BOOLEAN: ndr_push_uint8(ndr, NDR_SCALARS, *(uint8_t *) value); break; case PT_STRING8: ndr_set_flags(&ndr->flags, LIBNDR_FLAG_STR_NULLTERM|LIBNDR_FLAG_STR_ASCII); ndr_push_string(ndr, NDR_SCALARS, (char *) value); break; case PT_UNICODE: ndr_set_flags(&ndr->flags, LIBNDR_FLAG_STR_NULLTERM); ndr_push_string(ndr, NDR_SCALARS, (char *) value); break; case PT_BINARY: case PT_SVREID: /* PropertyRow expect a 16 bit header for BLOB in RopQueryRows and RopGetPropertiesSpecific */ bin.cb = ((struct Binary_r *) value)->cb; bin.lpb = ((struct Binary_r *) value)->lpb; ndr_push_SBinary_short(ndr, NDR_SCALARS, &bin); break; case PT_CLSID: ndr_push_GUID(ndr, NDR_SCALARS, (struct GUID *) value); break; case PT_SYSTIME: ndr_push_FILETIME(ndr, NDR_SCALARS, (struct FILETIME *) value); break; case PT_MV_LONG: ndr_push_mapi_MV_LONG_STRUCT(ndr, NDR_SCALARS, (struct mapi_MV_LONG_STRUCT *) value); break; case PT_MV_UNICODE: ndr_push_mapi_SLPSTRArrayW(ndr, NDR_SCALARS, (struct mapi_SLPSTRArrayW *) value); break; case PT_MV_BINARY: bin_array = (struct BinaryArray_r *) value; ndr_push_uint32(ndr, NDR_SCALARS, bin_array->cValues); for (i = 0; i < bin_array->cValues; i++) { bin.cb = bin_array->lpbin[i].cb; bin.lpb = bin_array->lpbin[i].lpb; ndr_push_SBinary_short(ndr, NDR_SCALARS, &bin); } break; default: if (property != 0) { DEBUG(5, ("unsupported type: %.4x\n", (property & 0xffff))); abort(); } break; } end: /* Step 4. Steal ndr context */ blob->data = ndr->data; talloc_steal(mem_ctx, blob->data); blob->length = ndr->offset; talloc_free(ndr); return 0; } /** \details Turn request parameters to SPropValue array. This convenient function should be used among MAPI ROPs that have parameters which can be turned to MAPI properties and are stored within backends. \param mem_ctx pointer to the memory context \param request generic pointer to the ROP request \param opnum MAPI opnum identifying ROP contents \note Developers must talloc_free returned SRow after they finish using it. \return Allocated SRow on success, otherwise NULL */ _PUBLIC_ struct SRow *libmapiserver_ROP_request_to_properties(TALLOC_CTX *mem_ctx, void *request, uint8_t opnum) { struct SRow *aRow; struct CreateFolder_req *CreateFolder_req; aRow = talloc_zero(mem_ctx, struct SRow); aRow->lpProps = talloc_array(aRow, struct SPropValue, 2); aRow->cValues = 0; switch (opnum) { case op_MAPI_CreateFolder: CreateFolder_req = (struct CreateFolder_req *) request; aRow->lpProps = add_SPropValue(mem_ctx, aRow->lpProps, &(aRow->cValues), PR_FOLDER_TYPE, (void *)&(CreateFolder_req->ulFolderType)); switch (CreateFolder_req->ulType) { case MAPI_FOLDER_ANSI: aRow->lpProps = add_SPropValue(mem_ctx, aRow->lpProps, &(aRow->cValues), PR_DISPLAY_NAME, (void *)(CreateFolder_req->FolderName.lpszA)); aRow->lpProps = add_SPropValue(mem_ctx, aRow->lpProps, &(aRow->cValues), PR_COMMENT, (void *)(CreateFolder_req->FolderComment.lpszA)); break; case MAPI_FOLDER_UNICODE: aRow->lpProps = add_SPropValue(mem_ctx, aRow->lpProps, &(aRow->cValues), PR_DISPLAY_NAME_UNICODE, (void *)(CreateFolder_req->FolderName.lpszW)); aRow->lpProps = add_SPropValue(mem_ctx, aRow->lpProps, &(aRow->cValues), PR_COMMENT_UNICODE, (void *)(CreateFolder_req->FolderComment.lpszW)); break; } break; default: DEBUG(0, ("[%s:%d]: opnum %d not implemented yet\n", __FUNCTION__, __LINE__, opnum)); talloc_free(aRow); return NULL; } return aRow; } openchange-2.0/mapiproxy/libmapiserver/libmapiserver_oxcstor.c000066400000000000000000000141671223057412600251620ustar00rootroot00000000000000/* libmapiserver - MAPI library for Server side OpenChange Project Copyright (C) Julien Kerihuel 2009 This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see . */ /** \file libmapiserver_oxcstor.c \brief OXCSTOR ROP Response size calculations */ #include "libmapiserver.h" #include /** \details Calculate Logon Rop size \param request pointer to the Logon EcDoRpc_MAPI_REQ structure \param response pointer to the Logon EcDoRpc_MAPI_REPL structure \return Size of Logon response */ _PUBLIC_ uint16_t libmapiserver_RopLogon_size(struct EcDoRpc_MAPI_REQ *request, struct EcDoRpc_MAPI_REPL *response) { uint16_t size = SIZE_DFLT_MAPI_RESPONSE; if (!response || (response->error_code && response->error_code != ecWrongServer)) { return size; } if (response->error_code == ecWrongServer) { size += SIZE_DFLT_ROPLOGON_REDIRECT; size += strlen (response->us.mapi_Logon.ServerName) + 1; } else if (request->u.mapi_Logon.LogonFlags & LogonPrivate) { size += SIZE_DFLT_ROPLOGON_MAILBOX; } else { size += SIZE_DFLT_ROPLOGON_PUBLICFOLDER; } return size; } /** \details Calculate SetReceiveFolder (0x26) Rop size \param response pointer to the SetReceiveFolder EcDoRpc_MAPI_REPL structure \return Size of SetReceiveFolder response */ _PUBLIC_ uint16_t libmapiserver_RopSetReceiveFolder_size(struct EcDoRpc_MAPI_REPL *response) { return SIZE_DFLT_MAPI_RESPONSE; } /** \details Calculate GetReceiveFolder Rop size \param response pointer to the GetReceiveFolder EcDoRpc_MAPI_REPL structure \return Size of GetReceiveFolder response */ _PUBLIC_ uint16_t libmapiserver_RopGetReceiveFolder_size(struct EcDoRpc_MAPI_REPL *response) { uint16_t size = SIZE_DFLT_MAPI_RESPONSE; if (!response || response->error_code) { return size; } size += SIZE_DFLT_ROPGETRECEIVEFOLDER; size += strlen(response->u.mapi_GetReceiveFolder.MessageClass) + 1; return size; } /** \details Calculate LongTermIdFromId Rop size \param response pointer to the LongTermIdFromId EcDoRpc_MAPI_REPL structure \return Size of LongTermIdFromId response */ _PUBLIC_ uint16_t libmapiserver_RopLongTermIdFromId_size(struct EcDoRpc_MAPI_REPL *response) { uint16_t size = SIZE_DFLT_MAPI_RESPONSE; if (!response || response->error_code) { return size; } size += SIZE_DFLT_ROPLONGTERMIDFROMID; return size; } /** \details Calculate IdFromLongTermId Rop size \param response pointer to the IdFromLongTermId EcDoRpc_MAPI_REPL structure \return Size of IdFromLongTermId response */ _PUBLIC_ uint16_t libmapiserver_RopIdFromLongTermId_size(struct EcDoRpc_MAPI_REPL *response) { uint16_t size = SIZE_DFLT_MAPI_RESPONSE; if (!response || response->error_code) { return size; } size += SIZE_DFLT_ROPIDFROMLONGTERMID; return size; } /** \details Calculate GetPerUserLongTermIds Rop size \param response pointer to the GetPerUserLongTermIds EcDoRpc_MAPI_REPL structure \return Size of GetPerUserLongTermIds response */ _PUBLIC_ uint16_t libmapiserver_RopGetPerUserLongTermIds_size(struct EcDoRpc_MAPI_REPL *response) { uint16_t size = SIZE_DFLT_MAPI_RESPONSE; uint16_t i; if (!response || response->error_code) { return size; } size += SIZE_DFLT_ROPGETPERUSERLONGTERMIDS; for (i = 0; i < response->u.mapi_GetPerUserLongTermIds.LongTermIdCount; i++) { size += libmapiserver_LongTermId_size(); } return size; } /** \details Calculate ReadPerUserInformation Rop size \param response pointer to the ReadPerUserInformation EcDoRpc_MAPI_REPL structure \return Size of ReadPerUserInformation response */ _PUBLIC_ uint16_t libmapiserver_RopReadPerUserInformation_size(struct EcDoRpc_MAPI_REPL *response) { uint16_t size = SIZE_DFLT_MAPI_RESPONSE; if (!response || response->error_code) { return size; } size += SIZE_DFLT_ROPREADPERUSERINFORMATION; if (response->u.mapi_ReadPerUserInformation.DataSize) { size += response->u.mapi_ReadPerUserInformation.DataSize; } return size; } /** \details Calculate GetPerUserLongTermIds Rop size \param response pointer to the GetPerUserLongTermIds EcDoRpc_MAPI_REPL structure \return Size of GetPerUserLongTermIds response */ _PUBLIC_ uint16_t libmapiserver_RopGetPerUserGuid_size(struct EcDoRpc_MAPI_REPL *response) { uint16_t size = SIZE_DFLT_MAPI_RESPONSE; if (!response || response->error_code) { return size; } size += SIZE_DFLT_ROPGETPERUSERGUID; return size; } /** \details Calculate GetStoreState Rop size \param response pointer to the GetStoreState EcDoRpc_MAPI_REPL structure \return Size of GetStoreState response */ _PUBLIC_ uint16_t libmapiserver_RopGetStoreState_size(struct EcDoRpc_MAPI_REPL *response) { uint16_t size = SIZE_DFLT_MAPI_RESPONSE; if (!response || response->error_code) { return size; } size += SIZE_DFLT_ROPGETSTORESTATE; return size; } /** \details Calculate GetReceiveFolderTable ROP size \param response pointer to the GetReceiveFolderTable EcDoRpc_MAPI_REPL structure \return Size of GetPerUserLongTermIds response */ _PUBLIC_ uint16_t libmapiserver_RopGetReceiveFolderTable_size(struct EcDoRpc_MAPI_REPL *response) { int i = 0; uint16_t size = SIZE_DFLT_MAPI_RESPONSE; if (!response || response->error_code) { return size; } size += sizeof(uint32_t); /* cValues */ for (i = 0; i < response->u.mapi_GetReceiveFolderTable.cValues; ++i) { size += sizeof(uint8_t); /* flag */ size += sizeof(uint64_t); /* fid */ size += strlen(response->u.mapi_GetReceiveFolderTable.entries[i].lpszMessageClass) + 1; size += sizeof(struct FILETIME); /* modiftime */ } return size; } openchange-2.0/mapiproxy/libmapiserver/libmapiserver_oxctabl.c000066400000000000000000000102041223057412600251010ustar00rootroot00000000000000/* libmapiserver - MAPI library for Server side OpenChange Project Copyright (C) Julien Kerihuel 2009 This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see . */ /** \file libmapiserver_oxctabl.c \brief OXCTABL ROP Response size calculations */ #include "libmapiserver.h" /** \details Calculate SetColumns Rop size \param response pointer to the SetColumns EcDoRpc_MAPI_REPL structure \return Size of SetColumns response */ _PUBLIC_ uint16_t libmapiserver_RopSetColumns_size(struct EcDoRpc_MAPI_REPL *response) { uint16_t size = SIZE_DFLT_MAPI_RESPONSE; if (!response || response->error_code) { return size; } size += SIZE_DFLT_ROPSETCOLUMNS; return size; } /** \details Calculate SortTable Rop size \param response pointer to the SortTable EcDoRpc_MAPI_REPL structure \return Size of SortTable response */ _PUBLIC_ uint16_t libmapiserver_RopSortTable_size(struct EcDoRpc_MAPI_REPL *response) { uint16_t size = SIZE_DFLT_MAPI_RESPONSE; if (!response || response->error_code) { return size; } size += SIZE_DFLT_ROPSORTTABLE; return size; } /** \details Calculate Restrict Rop size \param response pointer to the Restrict EcDoRpc_MAPI_REPL structure \return Size of Restrict response */ _PUBLIC_ uint16_t libmapiserver_RopRestrict_size(struct EcDoRpc_MAPI_REPL *response) { uint16_t size = SIZE_DFLT_MAPI_RESPONSE; if (!response || response->error_code) { return size; } size += SIZE_DFLT_ROPRESTRICT; return size; } /** \details Calculate QueryRows Rop size \param response pointer to the QueryRows EcDoRpc_MAPI_REPL structure \return Size of QueryRows response */ _PUBLIC_ uint16_t libmapiserver_RopQueryRows_size(struct EcDoRpc_MAPI_REPL *response) { uint16_t size = SIZE_DFLT_MAPI_RESPONSE; if (!response || response->error_code) { return size; } size += SIZE_DFLT_ROPQUERYROWS; if (response->u.mapi_QueryRows.RowCount) { size += response->u.mapi_QueryRows.RowData.length; } return size; } /** \details Calculate QueryPosition Rop size \param response pointer to the QueryPosition EcDoRpc_MAPI_REPL structure \return Size of QueryPosition response */ _PUBLIC_ uint16_t libmapiserver_RopQueryPosition_size(struct EcDoRpc_MAPI_REPL *response) { uint16_t size = SIZE_DFLT_MAPI_RESPONSE; if (!response || response->error_code) { return size; } size += SIZE_DFLT_ROPQUERYPOSITION; return size; } /** \details Calculate SeekRow Rop size \param response pointer to the SeekRow EcDoRpc_MAPI_REPL structure \return Size of SeekRow response */ _PUBLIC_ uint16_t libmapiserver_RopSeekRow_size(struct EcDoRpc_MAPI_REPL *response) { uint16_t size = SIZE_DFLT_MAPI_RESPONSE; if (!response || response->error_code) { return size; } size += SIZE_DFLT_ROPSEEKROW; return size; } /** \details Calculate FindRow Rop size \param response pointer to the FindRow EcDoRpc_MAPI_REPL structure \return Size of FindRow response */ _PUBLIC_ uint16_t libmapiserver_RopFindRow_size(struct EcDoRpc_MAPI_REPL *response) { uint16_t size = SIZE_DFLT_MAPI_RESPONSE; if (!response || response->error_code) { return size; } size += SIZE_DFLT_ROPFINDROW; if (response->u.mapi_FindRow.HasRowData) { size += response->u.mapi_FindRow.row.length; } return size; } /** \details Calculate ResetTable (0x81) Rop size \param response pointer to the ResetTable EcDoRpc_MAPI_REPL structure \return Size of ResetTable response */ _PUBLIC_ uint16_t libmapiserver_RopResetTable_size(struct EcDoRpc_MAPI_REPL *response) { return SIZE_DFLT_MAPI_RESPONSE; } openchange-2.0/mapiproxy/libmapiserver/libmapiserver_oxomsg.c000066400000000000000000000073721223057412600247750ustar00rootroot00000000000000/* libmapiserver - MAPI library for Server side OpenChange Project Copyright (C) Brad Hards 2010 This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see . */ /** \file libmapiserver_oxomsg.c \brief OXOMSG ROP Response size calculations */ #include "libmapiserver.h" #include /** \details Calculate SubmitMessage (0x32) Rop size \param response pointer to the SubmitMessage EcDoRpc_MAPI_REPL structure \return Size of SubmitMessage response */ _PUBLIC_ uint16_t libmapiserver_RopSubmitMessage_size(struct EcDoRpc_MAPI_REPL *response) { return SIZE_DFLT_MAPI_RESPONSE; } /** \details Calculate SetSpooler (0x47) Rop size \param response pointer to the SetSpooler EcDoRpc_MAPI_REPL structure \return Size of SetSpooler response */ _PUBLIC_ uint16_t libmapiserver_RopSetSpooler_size(struct EcDoRpc_MAPI_REPL *response) { return SIZE_DFLT_MAPI_RESPONSE; } /** \details Calculate GetAddressTypes (0x49) Rop size \param response pointer to the GetAddressTypes EcDoRpc_MAPI_REPL structure \return Size of GetAddressTypes response */ _PUBLIC_ uint16_t libmapiserver_RopGetAddressTypes_size(struct EcDoRpc_MAPI_REPL *response) { uint16_t size = SIZE_DFLT_MAPI_RESPONSE; if (!response || response->error_code) { return size; } size += SIZE_DFLT_ROPGETADDRESSTYPES; /* The length of the strings is variable, but given by the size parameter */ size += response->u.mapi_AddressTypes.size; return size; } /** \details Calculate TransportSend (0x4a) Rop size \param response pointer to the TransportSend EcDoRpc_MAPI_REPL structure \return Size of TransportSend response */ _PUBLIC_ uint16_t libmapiserver_RopTransportSend_size(struct EcDoRpc_MAPI_REPL *response) { uint16_t size = SIZE_DFLT_MAPI_RESPONSE; if (!response || response->error_code) { return size; } size += SIZE_DFLT_ROPTRANSPORTSEND; if (!response->u.mapi_TransportSend.NoPropertiesReturned) { abort(); } /* The length of the strings is variable, but given by the size parameter */ /* size += response->u.mapi_AddressTypes.size; */ return size; } /** \details Calculate GetTransportFolder (0x6d) ROP size \param response pointer to the GetTransportFolder EcDoRpc_MAPI_REPL structure \return Size of GetTransportFolder response */ _PUBLIC_ uint16_t libmapiserver_RopGetTransportFolder_size(struct EcDoRpc_MAPI_REPL *response) { uint16_t size = SIZE_DFLT_MAPI_RESPONSE; if (!response || response->error_code) { return size; } size += SIZE_DFLT_ROPGETTRANSPORTFOLDER; return size; } /** \details Calculate OptionsData (0x6f) Rop size \param response pointer to the OptionsData EcDoRpc_MAPI_REPL structure \return Size of OptionsData response */ _PUBLIC_ uint16_t libmapiserver_RopOptionsData_size(struct EcDoRpc_MAPI_REPL *response) { uint16_t size = SIZE_DFLT_MAPI_RESPONSE; if (!response || response->error_code) { return size; } size += SIZE_DFLT_ROPOPTIONSDATA; size += response->u.mapi_OptionsData.OptionsInfo.cb; size += response->u.mapi_OptionsData.HelpFileSize; if (response->u.mapi_OptionsData.HelpFileSize != 0) { size += strlen(response->u.mapi_OptionsData.HelpFileName.HelpFileName) + 1; } return size; } openchange-2.0/mapiproxy/libmapiserver/libmapiserver_oxorule.c000066400000000000000000000024451223057412600251520ustar00rootroot00000000000000/* libmapiserver - MAPI library for Server side OpenChange Project Copyright (C) Julien Kerihuel 2009 This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see . */ /** \file libmapiserver_oxorule.c \brief OXORULE ROP Response size calculations */ #include "libmapiserver.h" /** \details Calculate GetRulesTable Rop size \return Size of GetRulesTable response */ _PUBLIC_ uint16_t libmapiserver_RopGetRulesTable_size(void) { uint16_t size = SIZE_DFLT_MAPI_RESPONSE; return size; } /** \details Calculate ModifyRules Rop size \return Size of ModifyRules response */ _PUBLIC_ uint16_t libmapiserver_RopModifyRules_size(void) { uint16_t size = SIZE_DFLT_MAPI_RESPONSE; return size; } openchange-2.0/mapiproxy/libmapistore.pc.in000066400000000000000000000005101223057412600211330ustar00rootroot00000000000000prefix=@prefix@ exec_prefix=@exec_prefix@ libdir=@libdir@ includedir=@includedir@ datarootdir=@prefix@/share datadir=@datadir@ Name: MAPISTORE Description: MAPI Storage Abstraction Layer library Version: @PACKAGE_VERSION@ Libs: -L${libdir} -lmapistore Libs.private: @LIBS@ Cflags: -I${includedir} Requires: talloc tdb libmapi openchange-2.0/mapiproxy/libmapistore/000077500000000000000000000000001223057412600202065ustar00rootroot00000000000000openchange-2.0/mapiproxy/libmapistore/Doxyfile.in000066400000000000000000001471451223057412600223350ustar00rootroot00000000000000# Doxyfile 1.5.2 # This file describes the settings to be used by the documentation system # doxygen (www.doxygen.org) for a project # # All text after a hash (#) is considered a comment and will be ignored # The format is: # TAG = value [value, ...] # For lists items can also be appended using: # TAG += value [value, ...] # Values that contain spaces should be placed between quotes (" ") #--------------------------------------------------------------------------- # Project related configuration options #--------------------------------------------------------------------------- # This tag specifies the encoding used for all characters in the config file that # follow. The default is UTF-8 which is also the encoding used for all text before # the first occurrence of this tag. Doxygen uses libiconv (or the iconv built into # libc) for the transcoding. See http://www.gnu.org/software/libiconv for the list of # possible encodings. DOXYFILE_ENCODING = UTF-8 # The PROJECT_NAME tag is a single word (or a sequence of words surrounded # by quotes) that should identify the project. PROJECT_NAME = "OpenChange mapistore library" # The PROJECT_NUMBER tag can be used to enter a project or revision number. # This could be handy for archiving the generated documentation or # if some version control system is used. PROJECT_NUMBER = @PACKAGE_VERSION@ # The OUTPUT_DIRECTORY tag is used to specify the (relative or absolute) # base path where the generated documentation will be put. # If a relative path is entered, it will be relative to the location # where doxygen was started. If left blank the current directory will be used. OUTPUT_DIRECTORY = apidocs # If the CREATE_SUBDIRS tag is set to YES, then doxygen will create # 4096 sub-directories (in 2 levels) under the output directory of each output # format and will distribute the generated files over these directories. # Enabling this option can be useful when feeding doxygen a huge amount of # source files, where putting all generated files in the same directory would # otherwise cause performance problems for the file system. CREATE_SUBDIRS = NO # The OUTPUT_LANGUAGE tag is used to specify the language in which all # documentation generated by doxygen is written. Doxygen will use this # information to generate all constant output in the proper language. # The default language is English, other supported languages are: # Afrikaans, Arabic, Brazilian, Catalan, Chinese, Chinese-Traditional, # Croatian, Czech, Danish, Dutch, Finnish, French, German, Greek, Hungarian, # Italian, Japanese, Japanese-en (Japanese with English messages), Korean, # Korean-en, Lithuanian, Norwegian, Polish, Portuguese, Romanian, Russian, # Serbian, Slovak, Slovene, Spanish, Swedish, and Ukrainian. OUTPUT_LANGUAGE = English # If the BRIEF_MEMBER_DESC tag is set to YES (the default) Doxygen will # include brief member descriptions after the members that are listed in # the file and class documentation (similar to JavaDoc). # Set to NO to disable this. BRIEF_MEMBER_DESC = YES # If the REPEAT_BRIEF tag is set to YES (the default) Doxygen will prepend # the brief description of a member or function before the detailed description. # Note: if both HIDE_UNDOC_MEMBERS and BRIEF_MEMBER_DESC are set to NO, the # brief descriptions will be completely suppressed. REPEAT_BRIEF = YES # This tag implements a quasi-intelligent brief description abbreviator # that is used to form the text in various listings. Each string # in this list, if found as the leading text of the brief description, will be # stripped from the text and the result after processing the whole list, is # used as the annotated text. Otherwise, the brief description is used as-is. # If left blank, the following values are used ("$name" is automatically # replaced with the name of the entity): "The $name class" "The $name widget" # "The $name file" "is" "provides" "specifies" "contains" # "represents" "a" "an" "the" ABBREVIATE_BRIEF = # If the ALWAYS_DETAILED_SEC and REPEAT_BRIEF tags are both set to YES then # Doxygen will generate a detailed section even if there is only a brief # description. ALWAYS_DETAILED_SEC = NO # If the INLINE_INHERITED_MEMB tag is set to YES, doxygen will show all # inherited members of a class in the documentation of that class as if those # members were ordinary class members. Constructors, destructors and assignment # operators of the base classes will not be shown. INLINE_INHERITED_MEMB = NO # If the FULL_PATH_NAMES tag is set to YES then Doxygen will prepend the full # path before files name in the file list and in the header files. If set # to NO the shortest path that makes the file name unique will be used. FULL_PATH_NAMES = YES # If the FULL_PATH_NAMES tag is set to YES then the STRIP_FROM_PATH tag # can be used to strip a user-defined part of the path. Stripping is # only done if one of the specified strings matches the left-hand part of # the path. The tag can be used to show relative paths in the file list. # If left blank the directory from which doxygen is run is used as the # path to strip. STRIP_FROM_PATH = # The STRIP_FROM_INC_PATH tag can be used to strip a user-defined part of # the path mentioned in the documentation of a class, which tells # the reader which header file to include in order to use a class. # If left blank only the name of the header file containing the class # definition is used. Otherwise one should specify the include paths that # are normally passed to the compiler using the -I flag. STRIP_FROM_INC_PATH = # If the SHORT_NAMES tag is set to YES, doxygen will generate much shorter # (but less readable) file names. This can be useful is your file systems # doesn't support long names like on DOS, Mac, or CD-ROM. SHORT_NAMES = NO # If the JAVADOC_AUTOBRIEF tag is set to YES then Doxygen # will interpret the first line (until the first dot) of a JavaDoc-style # comment as the brief description. If set to NO, the JavaDoc # comments will behave just like the Qt-style comments (thus requiring an # explicit @brief command for a brief description. JAVADOC_AUTOBRIEF = YES # The MULTILINE_CPP_IS_BRIEF tag can be set to YES to make Doxygen # treat a multi-line C++ special comment block (i.e. a block of //! or /// # comments) as a brief description. This used to be the default behaviour. # The new default is to treat a multi-line C++ comment block as a detailed # description. Set this tag to YES if you prefer the old behaviour instead. MULTILINE_CPP_IS_BRIEF = NO # If the INHERIT_DOCS tag is set to YES (the default) then an undocumented # member inherits the documentation from any documented member that it # re-implements. INHERIT_DOCS = YES # If the SEPARATE_MEMBER_PAGES tag is set to YES, then doxygen will produce # a new page for each member. If set to NO, the documentation of a member will # be part of the file/class/namespace that contains it. SEPARATE_MEMBER_PAGES = NO # The TAB_SIZE tag can be used to set the number of spaces in a tab. # Doxygen uses this value to replace tabs by spaces in code fragments. TAB_SIZE = 8 # This tag can be used to specify a number of aliases that acts # as commands in the documentation. An alias has the form "name=value". # For example adding "sideeffect=\par Side Effects:\n" will allow you to # put the command \sideeffect (or @sideeffect) in the documentation, which # will result in a user-defined paragraph with heading "Side Effects:". # You can put \n's in the value part of an alias to insert newlines. ALIASES = # Set the OPTIMIZE_OUTPUT_FOR_C tag to YES if your project consists of C # sources only. Doxygen will then generate output that is more tailored for C. # For instance, some of the names that are used will be different. The list # of all members will be omitted, etc. OPTIMIZE_OUTPUT_FOR_C = YES # Set the OPTIMIZE_OUTPUT_JAVA tag to YES if your project consists of Java # sources only. Doxygen will then generate output that is more tailored for Java. # For instance, namespaces will be presented as packages, qualified scopes # will look different, etc. OPTIMIZE_OUTPUT_JAVA = NO # If you use STL classes (i.e. std::string, std::vector, etc.) but do not want to # include (a tag file for) the STL sources as input, then you should # set this tag to YES in order to let doxygen match functions declarations and # definitions whose arguments contain STL classes (e.g. func(std::string); v.s. # func(std::string) {}). This also make the inheritance and collaboration # diagrams that involve STL classes more complete and accurate. BUILTIN_STL_SUPPORT = NO # If you use Microsoft's C++/CLI language, you should set this option to YES to # enable parsing support. CPP_CLI_SUPPORT = NO # If member grouping is used in the documentation and the DISTRIBUTE_GROUP_DOC # tag is set to YES, then doxygen will reuse the documentation of the first # member in the group (if any) for the other members of the group. By default # all members of a group must be documented explicitly. DISTRIBUTE_GROUP_DOC = NO # Set the SUBGROUPING tag to YES (the default) to allow class member groups of # the same type (for instance a group of public functions) to be put as a # subgroup of that type (e.g. under the Public Functions section). Set it to # NO to prevent subgrouping. Alternatively, this can be done per class using # the \nosubgrouping command. SUBGROUPING = YES #--------------------------------------------------------------------------- # Build related configuration options #--------------------------------------------------------------------------- # If the EXTRACT_ALL tag is set to YES doxygen will assume all entities in # documentation are documented, even if no documentation was available. # Private class members and static file members will be hidden unless # the EXTRACT_PRIVATE and EXTRACT_STATIC tags are set to YES EXTRACT_ALL = NO # If the EXTRACT_PRIVATE tag is set to YES all private members of a class # will be included in the documentation. EXTRACT_PRIVATE = NO # If the EXTRACT_STATIC tag is set to YES all static members of a file # will be included in the documentation. EXTRACT_STATIC = NO # If the EXTRACT_LOCAL_CLASSES tag is set to YES classes (and structs) # defined locally in source files will be included in the documentation. # If set to NO only classes defined in header files are included. EXTRACT_LOCAL_CLASSES = NO # This flag is only useful for Objective-C code. When set to YES local # methods, which are defined in the implementation section but not in # the interface are included in the documentation. # If set to NO (the default) only methods in the interface are included. EXTRACT_LOCAL_METHODS = NO # If the HIDE_UNDOC_MEMBERS tag is set to YES, Doxygen will hide all # undocumented members of documented classes, files or namespaces. # If set to NO (the default) these members will be included in the # various overviews, but no documentation section is generated. # This option has no effect if EXTRACT_ALL is enabled. HIDE_UNDOC_MEMBERS = YES # If the HIDE_UNDOC_CLASSES tag is set to YES, Doxygen will hide all # undocumented classes that are normally visible in the class hierarchy. # If set to NO (the default) these classes will be included in the various # overviews. This option has no effect if EXTRACT_ALL is enabled. HIDE_UNDOC_CLASSES = YES # If the HIDE_FRIEND_COMPOUNDS tag is set to YES, Doxygen will hide all # friend (class|struct|union) declarations. # If set to NO (the default) these declarations will be included in the # documentation. HIDE_FRIEND_COMPOUNDS = YES # If the HIDE_IN_BODY_DOCS tag is set to YES, Doxygen will hide any # documentation blocks found inside the body of a function. # If set to NO (the default) these blocks will be appended to the # function's detailed documentation block. HIDE_IN_BODY_DOCS = NO # The INTERNAL_DOCS tag determines if documentation # that is typed after a \internal command is included. If the tag is set # to NO (the default) then the documentation will be excluded. # Set it to YES to include the internal documentation. INTERNAL_DOCS = NO # If the CASE_SENSE_NAMES tag is set to NO then Doxygen will only generate # file names in lower-case letters. If set to YES upper-case letters are also # allowed. This is useful if you have classes or files whose names only differ # in case and if your file system supports case sensitive file names. Windows # and Mac users are advised to set this option to NO. CASE_SENSE_NAMES = YES # If the HIDE_SCOPE_NAMES tag is set to NO (the default) then Doxygen # will show members with their full class and namespace scopes in the # documentation. If set to YES the scope will be hidden. HIDE_SCOPE_NAMES = NO # If the SHOW_INCLUDE_FILES tag is set to YES (the default) then Doxygen # will put a list of the files that are included by a file in the documentation # of that file. SHOW_INCLUDE_FILES = YES # If the INLINE_INFO tag is set to YES (the default) then a tag [inline] # is inserted in the documentation for inline members. INLINE_INFO = YES # If the SORT_MEMBER_DOCS tag is set to YES (the default) then doxygen # will sort the (detailed) documentation of file and class members # alphabetically by member name. If set to NO the members will appear in # declaration order. SORT_MEMBER_DOCS = YES # If the SORT_BRIEF_DOCS tag is set to YES then doxygen will sort the # brief documentation of file, namespace and class members alphabetically # by member name. If set to NO (the default) the members will appear in # declaration order. SORT_BRIEF_DOCS = YES # If the SORT_BY_SCOPE_NAME tag is set to YES, the class list will be # sorted by fully-qualified names, including namespaces. If set to # NO (the default), the class list will be sorted only by class name, # not including the namespace part. # Note: This option is not very useful if HIDE_SCOPE_NAMES is set to YES. # Note: This option applies only to the class list, not to the # alphabetical list. SORT_BY_SCOPE_NAME = NO # The GENERATE_TODOLIST tag can be used to enable (YES) or # disable (NO) the todo list. This list is created by putting \todo # commands in the documentation. GENERATE_TODOLIST = YES # The GENERATE_TESTLIST tag can be used to enable (YES) or # disable (NO) the test list. This list is created by putting \test # commands in the documentation. GENERATE_TESTLIST = YES # The GENERATE_BUGLIST tag can be used to enable (YES) or # disable (NO) the bug list. This list is created by putting \bug # commands in the documentation. GENERATE_BUGLIST = YES # The GENERATE_DEPRECATEDLIST tag can be used to enable (YES) or # disable (NO) the deprecated list. This list is created by putting # \deprecated commands in the documentation. GENERATE_DEPRECATEDLIST= YES # The ENABLED_SECTIONS tag can be used to enable conditional # documentation sections, marked by \if sectionname ... \endif. ENABLED_SECTIONS = # The MAX_INITIALIZER_LINES tag determines the maximum number of lines # the initial value of a variable or define consists of for it to appear in # the documentation. If the initializer consists of more lines than specified # here it will be hidden. Use a value of 0 to hide initializers completely. # The appearance of the initializer of individual variables and defines in the # documentation can be controlled using \showinitializer or \hideinitializer # command in the documentation regardless of this setting. MAX_INITIALIZER_LINES = 30 # Set the SHOW_USED_FILES tag to NO to disable the list of files generated # at the bottom of the documentation of classes and structs. If set to YES the # list will mention the files that were used to generate the documentation. SHOW_USED_FILES = YES # If the sources in your project are distributed over multiple directories # then setting the SHOW_DIRECTORIES tag to YES will show the directory hierarchy # in the documentation. The default is NO. SHOW_DIRECTORIES = NO # The FILE_VERSION_FILTER tag can be used to specify a program or script that # doxygen should invoke to get the current version for each file (typically from the # version control system). Doxygen will invoke the program by executing (via # popen()) the command , where is the value of # the FILE_VERSION_FILTER tag, and is the name of an input file # provided by doxygen. Whatever the program writes to standard output # is used as the file version. See the manual for examples. FILE_VERSION_FILTER = #--------------------------------------------------------------------------- # configuration options related to warning and progress messages #--------------------------------------------------------------------------- # The QUIET tag can be used to turn on/off the messages that are generated # by doxygen. Possible values are YES and NO. If left blank NO is used. QUIET = NO # The WARNINGS tag can be used to turn on/off the warning messages that are # generated by doxygen. Possible values are YES and NO. If left blank # NO is used. WARNINGS = YES # If WARN_IF_UNDOCUMENTED is set to YES, then doxygen will generate warnings # for undocumented members. If EXTRACT_ALL is set to YES then this flag will # automatically be disabled. WARN_IF_UNDOCUMENTED = YES # If WARN_IF_DOC_ERROR is set to YES, doxygen will generate warnings for # potential errors in the documentation, such as not documenting some # parameters in a documented function, or documenting parameters that # don't exist or using markup commands wrongly. WARN_IF_DOC_ERROR = YES # This WARN_NO_PARAMDOC option can be abled to get warnings for # functions that are documented, but have no documentation for their parameters # or return value. If set to NO (the default) doxygen will only warn about # wrong or incomplete parameter documentation, but not about the absence of # documentation. WARN_NO_PARAMDOC = NO # The WARN_FORMAT tag determines the format of the warning messages that # doxygen can produce. The string should contain the $file, $line, and $text # tags, which will be replaced by the file and line number from which the # warning originated and the warning text. Optionally the format may contain # $version, which will be replaced by the version of the file (if it could # be obtained via FILE_VERSION_FILTER) WARN_FORMAT = "$file:$line: $text" # The WARN_LOGFILE tag can be used to specify a file to which warning # and error messages should be written. If left blank the output is written # to stderr. WARN_LOGFILE = #--------------------------------------------------------------------------- # configuration options related to the input files #--------------------------------------------------------------------------- # The INPUT tag can be used to specify the files and/or directories that contain # documented source files. You may enter file names like "myfile.cpp" or # directories like "/usr/src/myproject". Separate the files or directories # with spaces. INPUT = mapiproxy/libmapistore # This tag can be used to specify the character encoding of the source files that # doxygen parses. Internally doxygen uses the UTF-8 encoding, which is also the default # input encoding. Doxygen uses libiconv (or the iconv built into libc) for the transcoding. # See http://www.gnu.org/software/libiconv for the list of possible encodings. INPUT_ENCODING = UTF-8 # If the value of the INPUT tag contains directories, you can use the # FILE_PATTERNS tag to specify one or more wildcard pattern (like *.cpp # and *.h) to filter out the source-files in the directories. If left # blank the following patterns are tested: # *.c *.cc *.cxx *.cpp *.c++ *.java *.ii *.ixx *.ipp *.i++ *.inl *.h *.hh *.hxx # *.hpp *.h++ *.idl *.odl *.cs *.php *.php3 *.inc *.m *.mm *.py FILE_PATTERNS = *.h *.c *.doxy # The RECURSIVE tag can be used to turn specify whether or not subdirectories # should be searched for input files as well. Possible values are YES and NO. # If left blank NO is used. RECURSIVE = YES # The EXCLUDE tag can be used to specify files and/or directories that should # excluded from the INPUT source files. This way you can easily exclude a # subdirectory from a directory tree whose root is specified with the INPUT tag. EXCLUDE = # The EXCLUDE_SYMLINKS tag can be used select whether or not files or # directories that are symbolic links (a Unix filesystem feature) are excluded # from the input. EXCLUDE_SYMLINKS = NO # If the value of the INPUT tag contains directories, you can use the # EXCLUDE_PATTERNS tag to specify one or more wildcard patterns to exclude # certain files from those directories. Note that the wildcards are matched # against the file with absolute path, so to exclude all test directories # for example use the pattern */test/* EXCLUDE_PATTERNS = *_private.h # The EXCLUDE_SYMBOLS tag can be used to specify one or more symbol names # (namespaces, classes, functions, etc.) that should be excluded from the output. # The symbol name can be a fully qualified name, a word, or if the wildcard * is used, # a substring. Examples: ANamespace, AClass, AClass::ANamespace, ANamespace::*Test EXCLUDE_SYMBOLS = # The EXAMPLE_PATH tag can be used to specify one or more files or # directories that contain example code fragments that are included (see # the \include command). EXAMPLE_PATH = # If the value of the EXAMPLE_PATH tag contains directories, you can use the # EXAMPLE_PATTERNS tag to specify one or more wildcard pattern (like *.cpp # and *.h) to filter out the source-files in the directories. If left # blank all files are included. EXAMPLE_PATTERNS = # If the EXAMPLE_RECURSIVE tag is set to YES then subdirectories will be # searched for input files to be used with the \include or \dontinclude # commands irrespective of the value of the RECURSIVE tag. # Possible values are YES and NO. If left blank NO is used. EXAMPLE_RECURSIVE = NO # The IMAGE_PATH tag can be used to specify one or more files or # directories that contain image that are included in the documentation (see # the \image command). IMAGE_PATH = doc/doxygen/pictures/ # The INPUT_FILTER tag can be used to specify a program that doxygen should # invoke to filter for each input file. Doxygen will invoke the filter program # by executing (via popen()) the command , where # is the value of the INPUT_FILTER tag, and is the name of an # input file. Doxygen will then use the output that the filter program writes # to standard output. If FILTER_PATTERNS is specified, this tag will be # ignored. INPUT_FILTER = "sed \ -e '20,40s/.*\//' \ -e '20,40s/.*\//' \ -e '20,40s/.*\//' \ -e '20,40s/.*\//' \ -e '20,40s/.*\//' \ -e '20,40s/.*\//' \ -e '20,40s/.*\//' \ -e '20,40s/.*\//' \ -e '20,40s/.*\//' \ -e '20,40s/.*\//' \ -e '20,40s/.*\//' \ -e '20,40s/.*\//' \ -e '20,40s/.*\//' \ -e '20,40s/.*\//' \ -e '20,40s/.*\//' \ -e '20,40s/.*\//' \ -e '20,40s/.*\//' \ -e '20,40s/.*\//' \ -e '20,40s/_PUBLIC_//'" # The FILTER_PATTERNS tag can be used to specify filters on a per file pattern # basis. Doxygen will compare the file name with each pattern and apply the # filter if there is a match. The filters are a list of the form: # pattern=filter (like *.cpp=my_cpp_filter). See INPUT_FILTER for further # info on how filters are used. If FILTER_PATTERNS is empty, INPUT_FILTER # is applied to all files. FILTER_PATTERNS = # If the FILTER_SOURCE_FILES tag is set to YES, the input filter (if set using # INPUT_FILTER) will be used to filter the input files when producing source # files to browse (i.e. when SOURCE_BROWSER is set to YES). FILTER_SOURCE_FILES = NO #--------------------------------------------------------------------------- # configuration options related to source browsing #--------------------------------------------------------------------------- # If the SOURCE_BROWSER tag is set to YES then a list of source files will # be generated. Documented entities will be cross-referenced with these sources. # Note: To get rid of all source code in the generated output, make sure also # VERBATIM_HEADERS is set to NO. SOURCE_BROWSER = NO # Setting the INLINE_SOURCES tag to YES will include the body # of functions and classes directly in the documentation. INLINE_SOURCES = NO # Setting the STRIP_CODE_COMMENTS tag to YES (the default) will instruct # doxygen to hide any special comment blocks from generated source code # fragments. Normal C and C++ comments will always remain visible. STRIP_CODE_COMMENTS = YES # If the REFERENCED_BY_RELATION tag is set to YES (the default) # then for each documented function all documented # functions referencing it will be listed. REFERENCED_BY_RELATION = YES # If the REFERENCES_RELATION tag is set to YES (the default) # then for each documented function all documented entities # called/used by that function will be listed. REFERENCES_RELATION = YES # If the REFERENCES_LINK_SOURCE tag is set to YES (the default) # and SOURCE_BROWSER tag is set to YES, then the hyperlinks from # functions in REFERENCES_RELATION and REFERENCED_BY_RELATION lists will # link to the source code. Otherwise they will link to the documentstion. REFERENCES_LINK_SOURCE = YES # If the USE_HTAGS tag is set to YES then the references to source code # will point to the HTML generated by the htags(1) tool instead of doxygen # built-in source browser. The htags tool is part of GNU's global source # tagging system (see http://www.gnu.org/software/global/global.html). You # will need version 4.8.6 or higher. USE_HTAGS = NO # If the VERBATIM_HEADERS tag is set to YES (the default) then Doxygen # will generate a verbatim copy of the header file for each class for # which an include is specified. Set to NO to disable this. VERBATIM_HEADERS = NO #--------------------------------------------------------------------------- # configuration options related to the alphabetical class index #--------------------------------------------------------------------------- # If the ALPHABETICAL_INDEX tag is set to YES, an alphabetical index # of all compounds will be generated. Enable this if the project # contains a lot of classes, structs, unions or interfaces. ALPHABETICAL_INDEX = NO # If the alphabetical index is enabled (see ALPHABETICAL_INDEX) then # the COLS_IN_ALPHA_INDEX tag can be used to specify the number of columns # in which this list will be split (can be a number in the range [1..20]) COLS_IN_ALPHA_INDEX = 5 # In case all classes in a project start with a common prefix, all # classes will be put under the same header in the alphabetical index. # The IGNORE_PREFIX tag can be used to specify one or more prefixes that # should be ignored while generating the index headers. IGNORE_PREFIX = #--------------------------------------------------------------------------- # configuration options related to the HTML output #--------------------------------------------------------------------------- # If the GENERATE_HTML tag is set to YES (the default) Doxygen will # generate HTML output. GENERATE_HTML = YES # The HTML_OUTPUT tag is used to specify where the HTML docs will be put. # If a relative path is entered the value of OUTPUT_DIRECTORY will be # put in front of it. If left blank `html' will be used as the default path. HTML_OUTPUT = html/libmapistore # The HTML_FILE_EXTENSION tag can be used to specify the file extension for # each generated HTML page (for example: .htm,.php,.asp). If it is left blank # doxygen will generate files with .html extension. HTML_FILE_EXTENSION = .html # The HTML_HEADER tag can be used to specify a personal HTML header for # each generated HTML page. If it is left blank doxygen will generate a # standard header. HTML_HEADER = doc/doxygen/header.html # The HTML_FOOTER tag can be used to specify a personal HTML footer for # each generated HTML page. If it is left blank doxygen will generate a # standard footer. HTML_FOOTER = doc/doxygen/footer.html # The HTML_STYLESHEET tag can be used to specify a user-defined cascading # style sheet that is used by each HTML page. It can be used to # fine-tune the look of the HTML output. If the tag is left blank doxygen # will generate a default style sheet. Note that doxygen will try to copy # the style sheet file to the HTML output directory, so don't put your own # stylesheet in the HTML output directory as well, or it will be erased! HTML_STYLESHEET = doc/doxygen/apidocs.css # If the HTML_ALIGN_MEMBERS tag is set to YES, the members of classes, # files or namespaces will be aligned in HTML using tables. If set to # NO a bullet list will be used. HTML_ALIGN_MEMBERS = YES # If the GENERATE_HTMLHELP tag is set to YES, additional index files # will be generated that can be used as input for tools like the # Microsoft HTML help workshop to generate a compressed HTML help file (.chm) # of the generated HTML documentation. GENERATE_HTMLHELP = NO # If the GENERATE_HTMLHELP tag is set to YES, the CHM_FILE tag can # be used to specify the file name of the resulting .chm file. You # can add a path in front of the file if the result should not be # written to the html output directory. CHM_FILE = # If the GENERATE_HTMLHELP tag is set to YES, the HHC_LOCATION tag can # be used to specify the location (absolute path including file name) of # the HTML help compiler (hhc.exe). If non-empty doxygen will try to run # the HTML help compiler on the generated index.hhp. HHC_LOCATION = # If the GENERATE_HTMLHELP tag is set to YES, the GENERATE_CHI flag # controls if a separate .chi index file is generated (YES) or that # it should be included in the master .chm file (NO). GENERATE_CHI = NO # If the GENERATE_HTMLHELP tag is set to YES, the BINARY_TOC flag # controls whether a binary table of contents is generated (YES) or a # normal table of contents (NO) in the .chm file. BINARY_TOC = NO # The TOC_EXPAND flag can be set to YES to add extra items for group members # to the contents of the HTML help documentation and to the tree view. TOC_EXPAND = NO # The DISABLE_INDEX tag can be used to turn on/off the condensed index at # top of each HTML page. The value NO (the default) enables the index and # the value YES disables it. DISABLE_INDEX = NO # This tag can be used to set the number of enum values (range [1..20]) # that doxygen will group on one line in the generated HTML documentation. ENUM_VALUES_PER_LINE = 4 # If the GENERATE_TREEVIEW tag is set to YES, a side panel will be # generated containing a tree-like index structure (just like the one that # is generated for HTML Help). For this to work a browser that supports # JavaScript, DHTML, CSS and frames is required (for instance Mozilla 1.0+, # Netscape 6.0+, Internet explorer 5.0+, or Konqueror). Windows users are # probably better off using the HTML help feature. GENERATE_TREEVIEW = NO # If the treeview is enabled (see GENERATE_TREEVIEW) then this tag can be # used to set the initial width (in pixels) of the frame in which the tree # is shown. TREEVIEW_WIDTH = 250 #--------------------------------------------------------------------------- # configuration options related to the LaTeX output #--------------------------------------------------------------------------- # If the GENERATE_LATEX tag is set to YES (the default) Doxygen will # generate Latex output. GENERATE_LATEX = NO # The LATEX_OUTPUT tag is used to specify where the LaTeX docs will be put. # If a relative path is entered the value of OUTPUT_DIRECTORY will be # put in front of it. If left blank `latex' will be used as the default path. LATEX_OUTPUT = latex # The LATEX_CMD_NAME tag can be used to specify the LaTeX command name to be # invoked. If left blank `latex' will be used as the default command name. LATEX_CMD_NAME = latex # The MAKEINDEX_CMD_NAME tag can be used to specify the command name to # generate index for LaTeX. If left blank `makeindex' will be used as the # default command name. MAKEINDEX_CMD_NAME = makeindex # If the COMPACT_LATEX tag is set to YES Doxygen generates more compact # LaTeX documents. This may be useful for small projects and may help to # save some trees in general. COMPACT_LATEX = NO # The PAPER_TYPE tag can be used to set the paper type that is used # by the printer. Possible values are: a4, a4wide, letter, legal and # executive. If left blank a4wide will be used. PAPER_TYPE = a4 # The EXTRA_PACKAGES tag can be to specify one or more names of LaTeX # packages that should be included in the LaTeX output. EXTRA_PACKAGES = # The LATEX_HEADER tag can be used to specify a personal LaTeX header for # the generated latex document. The header should contain everything until # the first chapter. If it is left blank doxygen will generate a # standard header. Notice: only use this tag if you know what you are doing! LATEX_HEADER = # If the PDF_HYPERLINKS tag is set to YES, the LaTeX that is generated # is prepared for conversion to pdf (using ps2pdf). The pdf file will # contain links (just like the HTML output) instead of page references # This makes the output suitable for online browsing using a pdf viewer. PDF_HYPERLINKS = YES # If the USE_PDFLATEX tag is set to YES, pdflatex will be used instead of # plain latex in the generated Makefile. Set this option to YES to get a # higher quality PDF documentation. USE_PDFLATEX = YES # If the LATEX_BATCHMODE tag is set to YES, doxygen will add the \\batchmode. # command to the generated LaTeX files. This will instruct LaTeX to keep # running if errors occur, instead of asking the user for help. # This option is also used when generating formulas in HTML. LATEX_BATCHMODE = NO # If LATEX_HIDE_INDICES is set to YES then doxygen will not # include the index chapters (such as File Index, Compound Index, etc.) # in the output. LATEX_HIDE_INDICES = NO #--------------------------------------------------------------------------- # configuration options related to the RTF output #--------------------------------------------------------------------------- # If the GENERATE_RTF tag is set to YES Doxygen will generate RTF output # The RTF output is optimized for Word 97 and may not look very pretty with # other RTF readers or editors. GENERATE_RTF = NO # The RTF_OUTPUT tag is used to specify where the RTF docs will be put. # If a relative path is entered the value of OUTPUT_DIRECTORY will be # put in front of it. If left blank `rtf' will be used as the default path. RTF_OUTPUT = rtf # If the COMPACT_RTF tag is set to YES Doxygen generates more compact # RTF documents. This may be useful for small projects and may help to # save some trees in general. COMPACT_RTF = NO # If the RTF_HYPERLINKS tag is set to YES, the RTF that is generated # will contain hyperlink fields. The RTF file will # contain links (just like the HTML output) instead of page references. # This makes the output suitable for online browsing using WORD or other # programs which support those fields. # Note: wordpad (write) and others do not support links. RTF_HYPERLINKS = NO # Load stylesheet definitions from file. Syntax is similar to doxygen's # config file, i.e. a series of assignments. You only have to provide # replacements, missing definitions are set to their default value. RTF_STYLESHEET_FILE = # Set optional variables used in the generation of an rtf document. # Syntax is similar to doxygen's config file. RTF_EXTENSIONS_FILE = #--------------------------------------------------------------------------- # configuration options related to the man page output #--------------------------------------------------------------------------- # If the GENERATE_MAN tag is set to YES (the default) Doxygen will # generate man pages GENERATE_MAN = YES # The MAN_OUTPUT tag is used to specify where the man pages will be put. # If a relative path is entered the value of OUTPUT_DIRECTORY will be # put in front of it. If left blank `man' will be used as the default path. MAN_OUTPUT = man # The MAN_EXTENSION tag determines the extension that is added to # the generated man pages (default is the subroutine's section .3) MAN_EXTENSION = .3 # If the MAN_LINKS tag is set to YES and Doxygen generates man output, # then it will generate one additional man file for each entity # documented in the real man page(s). These additional files # only source the real man page, but without them the man command # would be unable to find the correct page. The default is NO. MAN_LINKS = YES #--------------------------------------------------------------------------- # configuration options related to the XML output #--------------------------------------------------------------------------- # If the GENERATE_XML tag is set to YES Doxygen will # generate an XML file that captures the structure of # the code including all documentation. GENERATE_XML = NO # The XML_OUTPUT tag is used to specify where the XML pages will be put. # If a relative path is entered the value of OUTPUT_DIRECTORY will be # put in front of it. If left blank `xml' will be used as the default path. XML_OUTPUT = xml # The XML_SCHEMA tag can be used to specify an XML schema, # which can be used by a validating XML parser to check the # syntax of the XML files. XML_SCHEMA = # The XML_DTD tag can be used to specify an XML DTD, # which can be used by a validating XML parser to check the # syntax of the XML files. XML_DTD = # If the XML_PROGRAMLISTING tag is set to YES Doxygen will # dump the program listings (including syntax highlighting # and cross-referencing information) to the XML output. Note that # enabling this will significantly increase the size of the XML output. XML_PROGRAMLISTING = YES #--------------------------------------------------------------------------- # configuration options for the AutoGen Definitions output #--------------------------------------------------------------------------- # If the GENERATE_AUTOGEN_DEF tag is set to YES Doxygen will # generate an AutoGen Definitions (see autogen.sf.net) file # that captures the structure of the code including all # documentation. Note that this feature is still experimental # and incomplete at the moment. GENERATE_AUTOGEN_DEF = NO #--------------------------------------------------------------------------- # configuration options related to the Perl module output #--------------------------------------------------------------------------- # If the GENERATE_PERLMOD tag is set to YES Doxygen will # generate a Perl module file that captures the structure of # the code including all documentation. Note that this # feature is still experimental and incomplete at the # moment. GENERATE_PERLMOD = NO # If the PERLMOD_LATEX tag is set to YES Doxygen will generate # the necessary Makefile rules, Perl scripts and LaTeX code to be able # to generate PDF and DVI output from the Perl module output. PERLMOD_LATEX = NO # If the PERLMOD_PRETTY tag is set to YES the Perl module output will be # nicely formatted so it can be parsed by a human reader. This is useful # if you want to understand what is going on. On the other hand, if this # tag is set to NO the size of the Perl module output will be much smaller # and Perl will parse it just the same. PERLMOD_PRETTY = YES # The names of the make variables in the generated doxyrules.make file # are prefixed with the string contained in PERLMOD_MAKEVAR_PREFIX. # This is useful so different doxyrules.make files included by the same # Makefile don't overwrite each other's variables. PERLMOD_MAKEVAR_PREFIX = #--------------------------------------------------------------------------- # Configuration options related to the preprocessor #--------------------------------------------------------------------------- # If the ENABLE_PREPROCESSING tag is set to YES (the default) Doxygen will # evaluate all C-preprocessor directives found in the sources and include # files. ENABLE_PREPROCESSING = YES # If the MACRO_EXPANSION tag is set to YES Doxygen will expand all macro # names in the source code. If set to NO (the default) only conditional # compilation will be performed. Macro expansion can be done in a controlled # way by setting EXPAND_ONLY_PREDEF to YES. MACRO_EXPANSION = NO # If the EXPAND_ONLY_PREDEF and MACRO_EXPANSION tags are both set to YES # then the macro expansion is limited to the macros specified with the # PREDEFINED and EXPAND_AS_DEFINED tags. EXPAND_ONLY_PREDEF = NO # If the SEARCH_INCLUDES tag is set to YES (the default) the includes files # in the INCLUDE_PATH (see below) will be search if a #include is found. SEARCH_INCLUDES = YES # The INCLUDE_PATH tag can be used to specify one or more directories that # contain include files that are not input files but should be processed by # the preprocessor. INCLUDE_PATH = # You can use the INCLUDE_FILE_PATTERNS tag to specify one or more wildcard # patterns (like *.h and *.hpp) to filter out the header-files in the # directories. If left blank, the patterns specified with FILE_PATTERNS will # be used. INCLUDE_FILE_PATTERNS = # The PREDEFINED tag can be used to specify one or more macro names that # are defined before the preprocessor is started (similar to the -D option of # gcc). The argument of the tag is a list of macros of the form: name # or name=definition (no spaces). If the definition and the = are # omitted =1 is assumed. To prevent a macro definition from being # undefined via #undef or recursively expanded use the := operator # instead of the = operator. PREDEFINED = _PUBLIC_ # If the MACRO_EXPANSION and EXPAND_ONLY_PREDEF tags are set to YES then # this tag can be used to specify a list of macro names that should be expanded. # The macro definition that is found in the sources will be used. # Use the PREDEFINED tag if you want to use a different macro definition. EXPAND_AS_DEFINED = # If the SKIP_FUNCTION_MACROS tag is set to YES (the default) then # doxygen's preprocessor will remove all function-like macros that are alone # on a line, have an all uppercase name, and do not end with a semicolon. Such # function macros are typically used for boiler-plate code, and will confuse # the parser if not removed. SKIP_FUNCTION_MACROS = YES #--------------------------------------------------------------------------- # Configuration::additions related to external references #--------------------------------------------------------------------------- # The TAGFILES option can be used to specify one or more tagfiles. # Optionally an initial location of the external documentation # can be added for each tagfile. The format of a tag file without # this location is as follows: # TAGFILES = file1 file2 ... # Adding location for the tag files is done as follows: # TAGFILES = file1=loc1 "file2 = loc2" ... # where "loc1" and "loc2" can be relative or absolute paths or # URLs. If a location is present for each tag, the installdox tool # does not have to be run to correct the links. # Note that each tag file must have a unique name # (where the name does NOT include the path) # If a tag file is not located in the directory in which doxygen # is run, you must also specify the path to the tagfile here. TAGFILES = # When a file name is specified after GENERATE_TAGFILE, doxygen will create # a tag file that is based on the input files it reads. GENERATE_TAGFILE = # If the ALLEXTERNALS tag is set to YES all external classes will be listed # in the class index. If set to NO only the inherited external classes # will be listed. ALLEXTERNALS = NO # If the EXTERNAL_GROUPS tag is set to YES all external groups will be listed # in the modules index. If set to NO, only the current project's groups will # be listed. EXTERNAL_GROUPS = YES # The PERL_PATH should be the absolute path and name of the perl script # interpreter (i.e. the result of `which perl'). PERL_PATH = /usr/bin/perl #--------------------------------------------------------------------------- # Configuration options related to the dot tool #--------------------------------------------------------------------------- # If the CLASS_DIAGRAMS tag is set to YES (the default) Doxygen will # generate a inheritance diagram (in HTML, RTF and LaTeX) for classes with base # or super classes. Setting the tag to NO turns the diagrams off. Note that # this option is superseded by the HAVE_DOT option below. This is only a # fallback. It is recommended to install and use dot, since it yields more # powerful graphs. CLASS_DIAGRAMS = YES # You can define message sequence charts within doxygen comments using the \msc # command. Doxygen will then run the mscgen tool (see http://www.mcternan.me.uk/mscgen/) to # produce the chart and insert it in the documentation. The MSCGEN_PATH tag allows you to # specify the directory where the mscgen tool resides. If left empty the tool is assumed to # be found in the default search path. MSCGEN_PATH = # If set to YES, the inheritance and collaboration graphs will hide # inheritance and usage relations if the target is undocumented # or is not a class. HIDE_UNDOC_RELATIONS = YES # If you set the HAVE_DOT tag to YES then doxygen will assume the dot tool is # available from the path. This tool is part of Graphviz, a graph visualization # toolkit from AT&T and Lucent Bell Labs. The other options in this section # have no effect if this option is set to NO (the default) HAVE_DOT = NO # If the CLASS_GRAPH and HAVE_DOT tags are set to YES then doxygen # will generate a graph for each documented class showing the direct and # indirect inheritance relations. Setting this tag to YES will force the # the CLASS_DIAGRAMS tag to NO. CLASS_GRAPH = YES # If the COLLABORATION_GRAPH and HAVE_DOT tags are set to YES then doxygen # will generate a graph for each documented class showing the direct and # indirect implementation dependencies (inheritance, containment, and # class references variables) of the class with other documented classes. COLLABORATION_GRAPH = YES # If the GROUP_GRAPHS and HAVE_DOT tags are set to YES then doxygen # will generate a graph for groups, showing the direct groups dependencies GROUP_GRAPHS = YES # If the UML_LOOK tag is set to YES doxygen will generate inheritance and # collaboration diagrams in a style similar to the OMG's Unified Modeling # Language. UML_LOOK = NO # If set to YES, the inheritance and collaboration graphs will show the # relations between templates and their instances. TEMPLATE_RELATIONS = NO # If the ENABLE_PREPROCESSING, SEARCH_INCLUDES, INCLUDE_GRAPH, and HAVE_DOT # tags are set to YES then doxygen will generate a graph for each documented # file showing the direct and indirect include dependencies of the file with # other documented files. INCLUDE_GRAPH = YES # If the ENABLE_PREPROCESSING, SEARCH_INCLUDES, INCLUDED_BY_GRAPH, and # HAVE_DOT tags are set to YES then doxygen will generate a graph for each # documented header file showing the documented files that directly or # indirectly include this file. INCLUDED_BY_GRAPH = YES # If the CALL_GRAPH and HAVE_DOT tags are set to YES then doxygen will # generate a call dependency graph for every global function or class method. # Note that enabling this option will significantly increase the time of a run. # So in most cases it will be better to enable call graphs for selected # functions only using the \callgraph command. CALL_GRAPH = NO # If the CALLER_GRAPH and HAVE_DOT tags are set to YES then doxygen will # generate a caller dependency graph for every global function or class method. # Note that enabling this option will significantly increase the time of a run. # So in most cases it will be better to enable caller graphs for selected # functions only using the \callergraph command. CALLER_GRAPH = NO # If the GRAPHICAL_HIERARCHY and HAVE_DOT tags are set to YES then doxygen # will graphical hierarchy of all classes instead of a textual one. GRAPHICAL_HIERARCHY = YES # If the DIRECTORY_GRAPH, SHOW_DIRECTORIES and HAVE_DOT tags are set to YES # then doxygen will show the dependencies a directory has on other directories # in a graphical way. The dependency relations are determined by the #include # relations between the files in the directories. DIRECTORY_GRAPH = YES # The DOT_IMAGE_FORMAT tag can be used to set the image format of the images # generated by dot. Possible values are png, jpg, or gif # If left blank png will be used. DOT_IMAGE_FORMAT = png # The tag DOT_PATH can be used to specify the path where the dot tool can be # found. If left blank, it is assumed the dot tool can be found in the path. DOT_PATH = # The DOTFILE_DIRS tag can be used to specify one or more directories that # contain dot files that are included in the documentation (see the # \dotfile command). DOTFILE_DIRS = # The MAX_DOT_GRAPH_MAX_NODES tag can be used to set the maximum number of # nodes that will be shown in the graph. If the number of nodes in a graph # becomes larger than this value, doxygen will truncate the graph, which is # visualized by representing a node as a red box. Note that doxygen will always # show the root nodes and its direct children regardless of this setting. DOT_GRAPH_MAX_NODES = 50 # Set the DOT_TRANSPARENT tag to YES to generate images with a transparent # background. This is disabled by default, which results in a white background. # Warning: Depending on the platform used, enabling this option may lead to # badly anti-aliased labels on the edges of a graph (i.e. they become hard to # read). DOT_TRANSPARENT = NO # Set the DOT_MULTI_TARGETS tag to YES allow dot to generate multiple output # files in one run (i.e. multiple -o and -T options on the command line). This # makes dot run faster, but since only newer versions of dot (>1.8.10) # support this, this feature is disabled by default. DOT_MULTI_TARGETS = NO # If the GENERATE_LEGEND tag is set to YES (the default) Doxygen will # generate a legend page explaining the meaning of the various boxes and # arrows in the dot generated graphs. GENERATE_LEGEND = YES # If the DOT_CLEANUP tag is set to YES (the default) Doxygen will # remove the intermediate dot files that are used to generate # the various graphs. DOT_CLEANUP = YES #--------------------------------------------------------------------------- # Configuration::additions related to the search engine #--------------------------------------------------------------------------- # The SEARCHENGINE tag specifies whether or not a search engine should be # used. If set to NO the values of all tags below this one will be ignored. SEARCHENGINE = NO openchange-2.0/mapiproxy/libmapistore/mapistore.h000066400000000000000000000541661223057412600223760ustar00rootroot00000000000000/* OpenChange Storage Abstraction Layer library OpenChange Project Copyright (C) Julien Kerihuel 2009-2010 This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see . */ #ifndef __MAPISTORE_H #define __MAPISTORE_H /** \file mapistore.h \brief MAPISTORE general API This header contains general functions, primarily for users of the store (rather than storage providers). */ #ifndef _GNU_SOURCE #define _GNU_SOURCE #endif #ifndef _PUBLIC_ #define _PUBLIC_ #endif #include #include #include #include #include #include #include #if 0 #include #endif #include #include #include #include #include "libmapi/libmapi.h" /* forward declarations */ struct mapistore_mgmt_notif; typedef int (*init_backend_fn) (void); #define MAPISTORE_INIT_MODULE "mapistore_init_backend" #define MAPISTORE_FOLDER 1 #define MAPISTORE_MESSAGE 2 #define MAPISTORE_ATTACHMENT 3 #define MAPISTORE_TABLE 4 #define MAPISTORE_SOFT_DELETE 1 #define MAPISTORE_PERMANENT_DELETE 2 struct mapistore_message { /* message props */ char *subject_prefix; char *normalized_subject; /* recipients */ struct SPropTagArray *columns; uint32_t recipients_count; struct mapistore_message_recipient *recipients; }; struct mapistore_message_recipient { enum ulRecipClass type; char *username; void **data; }; struct indexing_folders_list { uint64_t *folderID; uint32_t count; }; enum mapistore_table_type { MAPISTORE_FOLDER_TABLE = 1, MAPISTORE_MESSAGE_TABLE = 2, MAPISTORE_FAI_TABLE = 3, MAPISTORE_RULE_TABLE = 4, MAPISTORE_ATTACHMENT_TABLE = 5, MAPISTORE_PERMISSIONS_TABLE = 6 }; enum mapistore_query_type { MAPISTORE_PREFILTERED_QUERY, MAPISTORE_LIVEFILTERED_QUERY, }; /* proof of concept: a new structure to simplify property queries */ struct mapistore_property_data { void *data; int error; /* basically MAPISTORE_SUCCESS or MAPISTORE_ERR_NOT_FOUND */ }; struct mapistore_connection_info { char *username; struct GUID replica_guid; uint16_t repl_id; struct mapistore_context *mstore_ctx; struct ldb_context *sam_ctx; /* samdb */ struct ldb_context *oc_ctx; /* openchangedb */ }; enum mapistore_context_role { MAPISTORE_MAIL_ROLE, MAPISTORE_DRAFTS_ROLE, MAPISTORE_SENTITEMS_ROLE, MAPISTORE_OUTBOX_ROLE, MAPISTORE_DELETEDITEMS_ROLE, MAPISTORE_CALENDAR_ROLE, MAPISTORE_CONTACTS_ROLE, MAPISTORE_TASKS_ROLE, MAPISTORE_NOTES_ROLE, MAPISTORE_JOURNAL_ROLE, MAPISTORE_FALLBACK_ROLE, MAPISTORE_MAX_ROLES }; struct mapistore_contexts_list { char *url; char *name; bool main_folder; enum mapistore_context_role role; char *tag; struct mapistore_contexts_list *prev; struct mapistore_contexts_list *next; }; struct tdb_wrap; struct mapistore_backend { /** backend operations */ struct { const char *name; const char *description; const char *namespace; enum mapistore_error (*init)(void); enum mapistore_error (*list_contexts)(const char *, struct tdb_wrap *, TALLOC_CTX *, struct mapistore_contexts_list **); enum mapistore_error (*create_context)(TALLOC_CTX *, struct mapistore_connection_info *, struct tdb_wrap *, const char *, void **); enum mapistore_error (*create_root_folder)(const char *, enum mapistore_context_role, uint64_t, const char *, TALLOC_CTX *, char **); } backend; /** context operations */ struct { enum mapistore_error (*get_path)(void *, TALLOC_CTX *, uint64_t, char **); enum mapistore_error (*get_root_folder)(void *, TALLOC_CTX *, uint64_t, void **); } context; /** oxcfold operations */ struct { enum mapistore_error (*open_folder)(void *, TALLOC_CTX *, uint64_t, void **); enum mapistore_error (*create_folder)(void *, TALLOC_CTX *, uint64_t, struct SRow *, void **); enum mapistore_error (*delete)(void *); enum mapistore_error (*open_message)(void *, TALLOC_CTX *, uint64_t, bool, void **); enum mapistore_error (*create_message)(void *, TALLOC_CTX *, uint64_t, uint8_t, void **); enum mapistore_error (*delete_message)(void *, uint64_t, uint8_t); enum mapistore_error (*move_copy_messages)(void *, void *, TALLOC_CTX *, uint32_t, uint64_t *, uint64_t *, struct Binary_r **, uint8_t); enum mapistore_error (*move_folder)(void *, void *, TALLOC_CTX *, const char *); enum mapistore_error (*copy_folder)(void *, void *, TALLOC_CTX *, bool, const char *); enum mapistore_error (*get_deleted_fmids)(void *, TALLOC_CTX *, enum mapistore_table_type, uint64_t, struct UI8Array_r **, uint64_t *); enum mapistore_error (*get_child_count)(void *, enum mapistore_table_type, uint32_t *); enum mapistore_error (*open_table)(void *, TALLOC_CTX *, enum mapistore_table_type, uint32_t, void **, uint32_t *); enum mapistore_error (*modify_permissions)(void *, uint8_t, uint16_t, struct PermissionData *); enum mapistore_error (*preload_message_bodies)(void *, enum mapistore_table_type, const struct UI8Array_r *); } folder; /** oxcmsg operations */ struct { enum mapistore_error (*get_message_data)(void *, TALLOC_CTX *, struct mapistore_message **); enum mapistore_error (*modify_recipients)(void *, struct SPropTagArray *, uint16_t, struct mapistore_message_recipient *); enum mapistore_error (*set_read_flag)(void *, uint8_t); enum mapistore_error (*save)(void *); enum mapistore_error (*submit)(void *, enum SubmitFlags); enum mapistore_error (*open_attachment)(void *, TALLOC_CTX *, uint32_t, void **); enum mapistore_error (*create_attachment)(void *, TALLOC_CTX *, void **, uint32_t *); enum mapistore_error (*get_attachment_table)(void *, TALLOC_CTX *, void **, uint32_t *); /* attachment operations */ enum mapistore_error (*open_embedded_message)(void *, TALLOC_CTX *, void **, uint64_t *, struct mapistore_message **); enum mapistore_error (*create_embedded_message)(void *, TALLOC_CTX *, void **, struct mapistore_message **); } message; /** oxctabl operations */ struct { enum mapistore_error (*get_available_properties)(void *, TALLOC_CTX *, struct SPropTagArray **); enum mapistore_error (*set_columns)(void *, uint16_t, enum MAPITAGS *); enum mapistore_error (*set_restrictions)(void *, struct mapi_SRestriction *, uint8_t *); enum mapistore_error (*set_sort_order)(void *, struct SSortOrderSet *, uint8_t *); enum mapistore_error (*get_row)(void *, TALLOC_CTX *, enum mapistore_query_type, uint32_t, struct mapistore_property_data **); enum mapistore_error (*get_row_count)(void *, enum mapistore_query_type, uint32_t *); enum mapistore_error (*handle_destructor)(void *, uint32_t); } table; /** oxcprpt operations */ struct { enum mapistore_error (*get_available_properties)(void *, TALLOC_CTX *, struct SPropTagArray **); enum mapistore_error (*get_properties)(void *, TALLOC_CTX *, uint16_t, enum MAPITAGS *, struct mapistore_property_data *); enum mapistore_error (*set_properties)(void *, struct SRow *); } properties; /** manager operations */ struct { enum mapistore_error (*generate_uri)(TALLOC_CTX *, const char *, const char *, const char *, const char *, char **); } manager; }; struct indexing_context_list; struct backend_context { const struct mapistore_backend *backend; void *backend_object; void *root_folder_object; struct indexing_context_list *indexing; uint32_t context_id; uint32_t ref_count; char *uri; }; struct backend_context_list { struct backend_context *ctx; struct backend_context_list *prev; struct backend_context_list *next; }; struct processing_context; struct mapistore_context { struct processing_context *processing_ctx; struct backend_context_list *context_list; struct indexing_context_list *indexing_list; struct replica_mapping_context_list *replica_mapping_list; struct mapistore_subscription_list *subscriptions; struct mapistore_notification_list *notifications; struct ldb_context *nprops_ctx; struct mapistore_connection_info *conn_info; #if 0 mqd_t mq_ipc; #endif }; struct mapistore_freebusy_properties { uint16_t nbr_months; uint32_t *months_ranges; struct Binary_r *freebusy_free; struct Binary_r *freebusy_tentative; struct Binary_r *freebusy_busy; struct Binary_r *freebusy_away; struct Binary_r *freebusy_merged; uint32_t publish_start; uint32_t publish_end; // char *email_address; struct FILETIME timestamp; }; #ifndef __BEGIN_DECLS #ifdef __cplusplus #define __BEGIN_DECLS extern "C" { #define __END_DECLS } #else #define __BEGIN_DECLS #define __END_DECLS #endif #endif __BEGIN_DECLS /* definitions from mapistore_interface.c */ /* these 2 will soon disappear */ int mapistore_getprops(struct mapistore_context *, uint32_t, TALLOC_CTX *, uint64_t, uint8_t, struct SPropTagArray *, struct SRow *); int mapistore_setprops(struct mapistore_context *, uint32_t, uint64_t, uint8_t, struct SRow *); struct mapistore_context *mapistore_init(TALLOC_CTX *, struct loadparm_context *, const char *); enum mapistore_error mapistore_release(struct mapistore_context *); enum mapistore_error mapistore_set_connection_info(struct mapistore_context *, struct ldb_context *, struct ldb_context *, const char *); enum mapistore_error mapistore_add_context(struct mapistore_context *, const char *, const char *, uint64_t, uint32_t *, void **); enum mapistore_error mapistore_add_context_ref_count(struct mapistore_context *, uint32_t); enum mapistore_error mapistore_del_context(struct mapistore_context *, uint32_t); enum mapistore_error mapistore_search_context_by_uri(struct mapistore_context *, const char *, uint32_t *, void **); const char *mapistore_errstr(enum mapistore_error); enum mapistore_error mapistore_list_contexts_for_user(struct mapistore_context *, const char *, TALLOC_CTX *, struct mapistore_contexts_list **); enum mapistore_error mapistore_create_root_folder(const char *, enum mapistore_context_role, uint64_t, const char *, TALLOC_CTX *, char **); enum mapistore_error mapistore_folder_open_folder(struct mapistore_context *, uint32_t, void *, TALLOC_CTX *, uint64_t, void **); enum mapistore_error mapistore_folder_create_folder(struct mapistore_context *, uint32_t, void *, TALLOC_CTX *, uint64_t, struct SRow *, void **); enum mapistore_error mapistore_folder_delete(struct mapistore_context *, uint32_t, void *, uint8_t); enum mapistore_error mapistore_folder_open_message(struct mapistore_context *, uint32_t, void *, TALLOC_CTX *, uint64_t, bool, void **); enum mapistore_error mapistore_folder_create_message(struct mapistore_context *, uint32_t, void *, TALLOC_CTX *, uint64_t, uint8_t, void **); enum mapistore_error mapistore_folder_delete_message(struct mapistore_context *, uint32_t, void *, uint64_t, uint8_t); enum mapistore_error mapistore_folder_move_copy_messages(struct mapistore_context *, uint32_t, void *, void *, TALLOC_CTX *, uint32_t, uint64_t *, uint64_t *, struct Binary_r **, uint8_t); enum mapistore_error mapistore_folder_move_folder(struct mapistore_context *, uint32_t, void *, void *, TALLOC_CTX *, const char *); enum mapistore_error mapistore_folder_copy_folder(struct mapistore_context *, uint32_t, void *, void *, TALLOC_CTX *, bool, const char *); enum mapistore_error mapistore_folder_get_deleted_fmids(struct mapistore_context *, uint32_t, void *, TALLOC_CTX *, enum mapistore_table_type, uint64_t, struct UI8Array_r **, uint64_t *); enum mapistore_error mapistore_folder_get_child_count(struct mapistore_context *, uint32_t, void *, enum mapistore_table_type, uint32_t *); enum mapistore_error mapistore_folder_get_child_fmids(struct mapistore_context *, uint32_t, void *, enum mapistore_table_type, TALLOC_CTX *, uint64_t **, uint32_t *); enum mapistore_error mapistore_folder_get_child_fid_by_name(struct mapistore_context *, uint32_t, void *, const char *, uint64_t *); enum mapistore_error mapistore_folder_open_table(struct mapistore_context *, uint32_t, void *, TALLOC_CTX *, enum mapistore_table_type, uint32_t, void **, uint32_t *); enum mapistore_error mapistore_folder_modify_permissions(struct mapistore_context *, uint32_t, void *, uint8_t, uint16_t, struct PermissionData *); enum mapistore_error mapistore_folder_preload_message_bodies(struct mapistore_context *, uint32_t, void *, enum mapistore_table_type, const struct UI8Array_r *); enum mapistore_error mapistore_folder_fetch_freebusy_properties(struct mapistore_context *, uint32_t, void *, struct tm *, struct tm *, TALLOC_CTX *, struct mapistore_freebusy_properties **); enum mapistore_error mapistore_message_get_message_data(struct mapistore_context *, uint32_t, void *, TALLOC_CTX *, struct mapistore_message **); enum mapistore_error mapistore_message_modify_recipients(struct mapistore_context *, uint32_t, void *, struct SPropTagArray *, uint16_t, struct mapistore_message_recipient *); enum mapistore_error mapistore_message_set_read_flag(struct mapistore_context *, uint32_t, void *, uint8_t); enum mapistore_error mapistore_message_save(struct mapistore_context *, uint32_t, void *); enum mapistore_error mapistore_message_submit(struct mapistore_context *, uint32_t, void *, enum SubmitFlags); enum mapistore_error mapistore_message_open_attachment(struct mapistore_context *, uint32_t, void *, TALLOC_CTX *, uint32_t, void **); enum mapistore_error mapistore_message_create_attachment(struct mapistore_context *, uint32_t, void *, TALLOC_CTX *, void **, uint32_t *); enum mapistore_error mapistore_message_get_attachment_table(struct mapistore_context *, uint32_t, void *, TALLOC_CTX *, void **, uint32_t *); enum mapistore_error mapistore_message_attachment_open_embedded_message(struct mapistore_context *, uint32_t, void *, TALLOC_CTX *, void **, uint64_t *, struct mapistore_message **msg); enum mapistore_error mapistore_message_attachment_create_embedded_message(struct mapistore_context *, uint32_t, void *, TALLOC_CTX *, void **, struct mapistore_message **msg); enum mapistore_error mapistore_table_get_available_properties(struct mapistore_context *, uint32_t, void *, TALLOC_CTX *, struct SPropTagArray **); enum mapistore_error mapistore_table_set_columns(struct mapistore_context *, uint32_t, void *, uint16_t, enum MAPITAGS *); enum mapistore_error mapistore_table_set_restrictions(struct mapistore_context *, uint32_t, void *, struct mapi_SRestriction *, uint8_t *); enum mapistore_error mapistore_table_set_sort_order(struct mapistore_context *, uint32_t, void *, struct SSortOrderSet *, uint8_t *); enum mapistore_error mapistore_table_get_row(struct mapistore_context *, uint32_t, void *, TALLOC_CTX *, enum mapistore_query_type, uint32_t, struct mapistore_property_data **); enum mapistore_error mapistore_table_get_row_count(struct mapistore_context *, uint32_t, void *, enum mapistore_query_type, uint32_t *); enum mapistore_error mapistore_table_handle_destructor(struct mapistore_context *, uint32_t, void *, uint32_t); enum mapistore_error mapistore_properties_get_available_properties(struct mapistore_context *, uint32_t, void *, TALLOC_CTX *, struct SPropTagArray **); enum mapistore_error mapistore_properties_get_properties(struct mapistore_context *, uint32_t, void *, TALLOC_CTX *, uint16_t, enum MAPITAGS *, struct mapistore_property_data *); enum mapistore_error mapistore_properties_set_properties(struct mapistore_context *, uint32_t, void *, struct SRow *); enum MAPISTATUS mapistore_error_to_mapi(enum mapistore_error); /* definitions from mapistore_processing.c */ enum mapistore_error mapistore_set_mapping_path(const char *); /* definitions from mapistore_backend.c */ enum mapistore_error mapistore_backend_register(const void *); const char *mapistore_backend_get_installdir(void); init_backend_fn *mapistore_backend_load(TALLOC_CTX *, const char *); struct backend_context *mapistore_backend_lookup(struct backend_context_list *, uint32_t); struct backend_context *mapistore_backend_lookup_by_uri(struct backend_context_list *, const char *); struct backend_context *mapistore_backend_lookup_by_name(TALLOC_CTX *, const char *); bool mapistore_backend_run_init(init_backend_fn *); /* definitions from mapistore_backend_defaults */ enum mapistore_error mapistore_backend_init_defaults(struct mapistore_backend *); /* definitions from mapistore_indexing.c */ enum mapistore_error mapistore_indexing_record_add_fid(struct mapistore_context *, uint32_t, const char *, uint64_t); enum mapistore_error mapistore_indexing_record_del_fid(struct mapistore_context *, uint32_t, const char *, uint64_t, uint8_t); enum mapistore_error mapistore_indexing_record_add_mid(struct mapistore_context *, uint32_t, const char *, uint64_t); enum mapistore_error mapistore_indexing_record_del_mid(struct mapistore_context *, uint32_t, const char *, uint64_t, uint8_t); enum mapistore_error mapistore_indexing_record_get_uri(struct mapistore_context *, const char *, TALLOC_CTX *, uint64_t, char **, bool *); enum mapistore_error mapistore_indexing_record_get_fmid(struct mapistore_context *, const char *, const char *, bool, uint64_t *, bool *); /* definitions from mapistore_replica_mapping.c */ enum mapistore_error mapistore_replica_mapping_add(struct mapistore_context *, const char *, struct replica_mapping_context_list **); enum mapistore_error mapistore_replica_mapping_guid_to_replid(struct mapistore_context *, const char *username, const struct GUID *, uint16_t *); enum mapistore_error mapistore_replica_mapping_replid_to_guid(struct mapistore_context *, const char *username, uint16_t, struct GUID *); /* definitions from mapistore_namedprops.c */ enum mapistore_error mapistore_namedprops_get_mapped_id(struct ldb_context *ldb_ctx, struct MAPINAMEID, uint16_t *); uint16_t mapistore_namedprops_next_unused_id(struct ldb_context *); enum mapistore_error mapistore_namedprops_create_id(struct ldb_context *, struct MAPINAMEID, uint16_t); enum mapistore_error mapistore_namedprops_get_nameid(struct ldb_context *, uint16_t, TALLOC_CTX *mem_ctx, struct MAPINAMEID **); enum mapistore_error mapistore_namedprops_get_nameid_type(struct ldb_context *, uint16_t, uint16_t *); /* definitions from mapistore_mgmt.c */ #if 0 enum mapistore_error mapistore_mgmt_backend_register_user(struct mapistore_connection_info *, const char *, const char *); enum mapistore_error mapistore_mgmt_backend_unregister_user(struct mapistore_connection_info *, const char *, const char *); enum mapistore_error mapistore_mgmt_interface_register_subscription(struct mapistore_connection_info *, struct mapistore_mgmt_notif *); enum mapistore_error mapistore_mgmt_interface_unregister_subscription(struct mapistore_connection_info *, struct mapistore_mgmt_notif *); enum mapistore_error mapistore_mgmt_interface_register_bind(struct mapistore_connection_info *, uint16_t, uint8_t *, uint16_t, uint8_t *); #endif /* definitions from mapistore_notifications.c (proof-of-concept) */ /* notifications subscriptions */ struct mapistore_subscription_list { struct mapistore_subscription *subscription; struct mapistore_subscription_list *next; struct mapistore_subscription_list *prev; }; struct mapistore_table_subscription_parameters { uint8_t table_type; uint64_t folder_id; /* the parent folder id */ }; struct mapistore_object_subscription_parameters { bool whole_store; uint64_t folder_id; uint64_t object_id; }; struct mapistore_subscription { uint32_t handle; uint16_t notification_types; union { struct mapistore_table_subscription_parameters table_parameters; struct mapistore_object_subscription_parameters object_parameters; } parameters; #if 0 char *mqueue_name; mqd_t mqueue; #endif }; struct mapistore_subscription *mapistore_new_subscription(TALLOC_CTX *, struct mapistore_context *, const char *, uint32_t, uint16_t, void *); /* notifications (implementation) */ struct mapistore_notification_list { struct mapistore_notification *notification; struct mapistore_notification_list *next; struct mapistore_notification_list *prev; }; enum mapistore_notification_type { MAPISTORE_OBJECT_CREATED = 1, MAPISTORE_OBJECT_MODIFIED = 2, MAPISTORE_OBJECT_DELETED = 3, MAPISTORE_OBJECT_COPIED = 4, MAPISTORE_OBJECT_MOVED = 5, MAPISTORE_OBJECT_NEWMAIL = 6 }; struct mapistore_table_notification_parameters { uint8_t table_type; uint32_t row_id; uint32_t handle; uint64_t folder_id; /* the parent folder id */ uint64_t object_id; /* the folder/message id */ uint32_t instance_id; }; struct mapistore_object_notification_parameters { uint64_t folder_id; /* the parent folder id */ uint64_t object_id; /* the folder/message id */ uint64_t old_folder_id; /* used for copy/move notifications */ uint64_t old_object_id; /* used for copy/move notifications */ uint16_t tag_count; enum MAPITAGS *tags; bool new_message_count; uint32_t message_count; }; struct mapistore_notification { uint32_t object_type; enum mapistore_notification_type event; union { struct mapistore_table_notification_parameters table_parameters; struct mapistore_object_notification_parameters object_parameters; } parameters; }; struct mapistore_subscription_list *mapistore_find_matching_subscriptions(struct mapistore_context *, struct mapistore_notification *); enum mapistore_error mapistore_delete_subscription(struct mapistore_context *, uint32_t, uint16_t); void mapistore_push_notification(struct mapistore_context *, uint8_t, enum mapistore_notification_type, void *); enum MAPISTATUS mapistore_get_queued_notifications(struct mapistore_context *, struct mapistore_subscription *, struct mapistore_notification_list **); enum MAPISTATUS mapistore_get_queued_notifications_named(struct mapistore_context *, const char *, struct mapistore_notification_list **); __END_DECLS #endif /* ! __MAPISTORE_H */ openchange-2.0/mapiproxy/libmapistore/mapistore_backend.c000066400000000000000000000575021223057412600240350ustar00rootroot00000000000000/* OpenChange Storage Abstraction Layer library OpenChange Project Note: init and load functions have been copied from samba4/source4/param/util.c initially wrote by Jelmer. Copyright (C) Jelmer Vernooij 2005-2007 Copyright (C) Julien Kerihuel 2009 This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see . */ #include #include #include #include #include "mapistore.h" #include "mapistore_errors.h" #include "mapistore_private.h" #include #include #include /** \file mapistore_backend.c \brief mapistore backends management API */ static struct mstore_backend { struct mapistore_backend *backend; } *backends = NULL; int num_backends; /** \details Register mapistore backends \param backend pointer to the mapistore backend to register \return MAPISTORE_SUCCESS on success */ _PUBLIC_ enum mapistore_error mapistore_backend_register(const void *_backend) { const struct mapistore_backend *backend = _backend; uint32_t i; /* Sanity checks */ MAPISTORE_RETVAL_IF(!backend, MAPISTORE_ERR_INVALID_PARAMETER, NULL); for (i = 0; i < num_backends; i++) { if (backends[i].backend && backend && backend->backend.name && backends[i].backend->backend.name && !strcmp(backends[i].backend->backend.name, backend->backend.name)) { DEBUG(3, ("MAPISTORE backend '%s' already registered\n", backend->backend.name)); return MAPISTORE_SUCCESS; } } backends = realloc_p(backends, struct mstore_backend, num_backends + 1); if (!backends) { smb_panic("out of memory in mapistore_backend_register"); } backends[num_backends].backend = smb_xmemdup(backend, sizeof (*backend)); backends[num_backends].backend->backend.name = smb_xstrdup(backend->backend.name); num_backends++; DEBUG(3, ("MAPISTORE backend '%s' registered\n", backend->backend.name)); return MAPISTORE_SUCCESS; } /** \details Check if the specified backend is registered given its name. \param name backend's name to lookup \return MAPISTORE_SUCCESS on success, otherwise MAPISTORE error */ _PUBLIC_ enum mapistore_error mapistore_backend_registered(const char *name) { int i; /* Sanity checks */ MAPISTORE_RETVAL_IF(!name, MAPISTORE_ERR_INVALID_PARAMETER, NULL); for (i = 0; i < num_backends; i++) { if (backends[i].backend && !strcmp(backends[i].backend->backend.name, name)) { return MAPISTORE_SUCCESS; } } return MAPISTORE_ERR_NOT_FOUND; } /** \details Return the full path where mapistore backends are installed. \return Pointer to the full path where backends are installed. */ _PUBLIC_ const char *mapistore_backend_get_installdir(void) { return MAPISTORE_BACKEND_INSTALLDIR; } /** \details Obtain the backend init function from a shared library file \param path full path to the backend shared library \return Pointer to the initialization function on success, otherwise NULL. */ static init_backend_fn load_backend(const char *path) { void *handle; void *init_fn; handle = dlopen(path, RTLD_NOW); if (handle == NULL) { DEBUG(0, ("Unable to open %s: %s\n", path, dlerror())); return NULL; } init_fn = dlsym(handle, MAPISTORE_INIT_MODULE); if (init_fn == NULL) { DEBUG(0, ("Unable to find %s() in %s: %s\n", MAPISTORE_INIT_MODULE, path, dlerror())); DEBUG(1, ("Loading mapistore backend '%s' failed\n", path)); dlclose(handle); return NULL; } return (init_backend_fn) init_fn; } /** \details Load backends from specified directory \param mem_ctx pointer to the memory context \param path name of the backend's shared library folder \return allocated array of functions pointers to initialization functions on success, otherwise NULL. */ static init_backend_fn *load_backends(TALLOC_CTX *mem_ctx, const char *path) { DIR *dir; struct dirent *entry; char *filename; int success = 0; init_backend_fn *ret; ret = talloc_array(mem_ctx, init_backend_fn, 2); ret[0] = NULL; dir = opendir(path); if (dir == NULL) { talloc_free(ret); return NULL; } while ((entry = readdir(dir))) { if (ISDOT(entry->d_name) || ISDOTDOT(entry->d_name)) { continue; } filename = talloc_asprintf(mem_ctx, "%s/%s", path, entry->d_name); ret[success] = load_backend(filename); if (ret[success]) { ret = talloc_realloc(mem_ctx, ret, init_backend_fn, success + 2); success++; ret[success] = NULL; } talloc_free(filename); } closedir(dir); return ret; } /** \details Load the initialization functions from backends DSO \param mem_ctx pointer to the memory context \param path pointer to the backend's DSO folder \return allocated array of functions pointers to initialization functions on success, otherwise NULL. */ _PUBLIC_ init_backend_fn *mapistore_backend_load(TALLOC_CTX *mem_ctx, const char *path) { if (!path) { path = mapistore_backend_get_installdir(); } return load_backends(mem_ctx, path); } /** \details Run specified initialization functions. \param fns pointer to an array of mapistore backends initialization functions \return true on success, otherwise false */ _PUBLIC_ bool mapistore_backend_run_init(init_backend_fn *fns) { int i; bool ret = true; if (fns == NULL) { return true; } for (i = 0; fns[i]; i++) { ret &= (bool)fns[i](); } return ret; } /** \details Initialize mapistore backends \param mem_ctx pointer to the memory context \param path pointer to folder where mapistore backends are installed \return MAPISTORE_SUCCESS on success, otherwise MAPISTORE_ERR_BACKEND_INIT */ enum mapistore_error mapistore_backend_init(TALLOC_CTX *mem_ctx, const char *path) { init_backend_fn *ret; bool status; int retval; int i; ret = mapistore_backend_load(mem_ctx, path); status = mapistore_backend_run_init(ret); talloc_free(ret); for (i = 0; i < num_backends; i++) { if (backends[i].backend) { retval = backends[i].backend->backend.init(); if (retval != MAPISTORE_SUCCESS) { DEBUG(3, ("[!] MAPISTORE backend '%s' initialization failed\n", backends[i].backend->backend.name)); } else { DEBUG(3, ("MAPISTORE backend '%s' loaded\n", backends[i].backend->backend.name)); } } } return (status != true) ? MAPISTORE_SUCCESS : MAPISTORE_ERR_BACKEND_INIT; } /** \details List backend contexts for given user \param mem_ctx pointer to the memory context \param namespace the backend namespace \param uri the backend parameters which can be passes inline \return a valid backend_context pointer on success, otherwise NULL */ enum mapistore_error mapistore_backend_list_contexts(const char *username, struct tdb_wrap *tdbwrap, TALLOC_CTX *mem_ctx, struct mapistore_contexts_list **contexts_listP) { enum mapistore_error retval; int i; struct mapistore_contexts_list *contexts_list = NULL, *current_contexts_list; MAPISTORE_RETVAL_IF(!username, MAPISTORE_ERR_INVALID_PARAMETER, NULL); MAPISTORE_RETVAL_IF(!contexts_listP, MAPISTORE_ERR_INVALID_PARAMETER, NULL); for (i = 0; i < num_backends; i++) { retval = backends[i].backend->backend.list_contexts(username, tdbwrap, mem_ctx, ¤t_contexts_list); if (retval != MAPISTORE_SUCCESS) { return retval; } DLIST_CONCATENATE(contexts_list, current_contexts_list, void); } *contexts_listP = contexts_list; (void) talloc_reference(mem_ctx, contexts_list); return MAPISTORE_SUCCESS; } /** \details Create backend context \param mem_ctx pointer to the memory context \param namespace the backend namespace \param uri the backend parameters which can be passes inline \return a valid backend_context pointer on success, otherwise NULL */ enum mapistore_error mapistore_backend_create_context(TALLOC_CTX *mem_ctx, struct mapistore_connection_info *conn_info, struct tdb_wrap *tdbwrap, const char *namespace, const char *uri, uint64_t fid, struct backend_context **context_p) { struct backend_context *context; enum mapistore_error retval; bool found = false; void *backend_object = NULL; int i; DEBUG(0, ("namespace is %s and backend_uri is '%s'\n", namespace, uri)); context = talloc_zero(NULL, struct backend_context); for (i = 0; i < num_backends; i++) { if (backends[i].backend->backend.namespace && !strcmp(namespace, backends[i].backend->backend.namespace)) { found = true; retval = backends[i].backend->backend.create_context(context, conn_info, tdbwrap, uri, &backend_object); if (retval != MAPISTORE_SUCCESS) { goto end; } break; } } if (found == false) { DEBUG(0, ("MAPISTORE: no backend with namespace '%s' is available\n", namespace)); retval = MAPISTORE_ERR_NOT_FOUND; goto end; } context->backend_object = backend_object; context->backend = backends[i].backend; retval = context->backend->context.get_root_folder(backend_object, context, fid, &context->root_folder_object); if (retval != MAPISTORE_SUCCESS) { goto end; } context->ref_count = 1; context->uri = talloc_asprintf(context, "%s%s", namespace, uri); *context_p = context; (void) talloc_reference(mem_ctx, context); end: talloc_unlink(NULL, context); return retval; } enum mapistore_error mapistore_backend_create_root_folder(const char *username, enum mapistore_context_role ctx_role, uint64_t fid, const char *name, TALLOC_CTX *mem_ctx, char **mapistore_urip) { enum mapistore_error retval = MAPISTORE_ERR_NOT_FOUND; int i; for (i = 0; retval == MAPISTORE_ERR_NOT_FOUND && i < num_backends; i++) { retval = backends[i].backend->backend.create_root_folder(username, ctx_role, fid, name, mem_ctx, mapistore_urip); } return retval; } /** \details Increase the ref count associated to a given backend \param bctx pointer to the backend context \return MAPISTORE_SUCCESS on success, otherwise MAPISTORE_ERROR */ _PUBLIC_ enum mapistore_error mapistore_backend_add_ref_count(struct backend_context *bctx) { if (!bctx) { return MAPISTORE_ERROR; } bctx->ref_count += 1; return MAPISTORE_SUCCESS; } /** \details Delete a context from the specified backend \param bctx pointer to the backend context \return MAPISTORE_SUCCESS on success, otherwise MAPISTORE error */ _PUBLIC_ enum mapistore_error mapistore_backend_delete_context(struct backend_context *bctx) { bctx->ref_count -= 1; if (bctx->ref_count) { return MAPISTORE_ERR_REF_COUNT; } talloc_free(bctx); return MAPISTORE_SUCCESS; } /** \details find the context matching given context identifier \param backend_list_ctx pointer to the backend context list \param context_id the context identifier to search \return Pointer to the mapistore_backend context on success, otherwise NULL */ _PUBLIC_ struct backend_context *mapistore_backend_lookup(struct backend_context_list *backend_list_ctx, uint32_t context_id) { struct backend_context_list *el; /* Sanity checks */ if (!backend_list_ctx) return NULL; for (el = backend_list_ctx; el; el = el->next) { if (el->ctx && el->ctx->context_id == context_id) { return el->ctx; } } return NULL; } /** \details find the context matching given uri string \param backend_list_ctx pointer to the backend context list \param uri the uri string to search \return Pointer to the mapistore_backend context on success, otherwise NULL */ _PUBLIC_ struct backend_context *mapistore_backend_lookup_by_uri(struct backend_context_list *backend_list_ctx, const char *uri) { struct backend_context_list *el; /* sanity checks */ if (!backend_list_ctx) return NULL; if (!uri) return NULL; for (el = backend_list_ctx; el; el = el->next) { if (el->ctx && el->ctx->uri && !strcmp(el->ctx->uri, uri)) { return el->ctx; } } return NULL; } /** \details Return a pointer on backend functions given its name \param mem_ctx pointer to the memory context \param name the backend name to lookup \return Allocated pointer to the mapistore_backend context on success, otherwise NULL */ _PUBLIC_ struct backend_context *mapistore_backend_lookup_by_name(TALLOC_CTX *mem_ctx, const char *name) { struct backend_context *context = NULL; int i; /* Sanity checks */ if (!name) return NULL; for (i = 0; i < num_backends; i++) { if (backends[i].backend && !strcmp(backends[i].backend->backend.name, name)) { context = talloc_zero(mem_ctx, struct backend_context); context->backend = backends[i].backend; context->ref_count = 0; context->uri = NULL; return context; } } return NULL; } enum mapistore_error mapistore_backend_get_path(struct backend_context *bctx, TALLOC_CTX *mem_ctx, uint64_t fmid, char **path) { enum mapistore_error ret; char *bpath = NULL; ret = bctx->backend->context.get_path(bctx->backend_object, mem_ctx, fmid, &bpath); if (!ret) { *path = talloc_asprintf(mem_ctx, "%s%s", bctx->backend->backend.namespace, bpath); } else { *path = NULL; } return ret; } enum mapistore_error mapistore_backend_folder_open_folder(struct backend_context *bctx, void *folder, TALLOC_CTX *mem_ctx, uint64_t fid, void **child_folder) { return bctx->backend->folder.open_folder(folder, mem_ctx, fid, child_folder); } enum mapistore_error mapistore_backend_folder_create_folder(struct backend_context *bctx, void *folder, TALLOC_CTX *mem_ctx, uint64_t fid, struct SRow *aRow, void **child_folder) { return bctx->backend->folder.create_folder(folder, mem_ctx, fid, aRow, child_folder); } enum mapistore_error mapistore_backend_folder_delete(struct backend_context *bctx, void *folder) { return bctx->backend->folder.delete(folder); } enum mapistore_error mapistore_backend_folder_open_message(struct backend_context *bctx, void *folder, TALLOC_CTX *mem_ctx, uint64_t mid, bool read_write, void **messagep) { return bctx->backend->folder.open_message(folder, mem_ctx, mid, read_write, messagep); } enum mapistore_error mapistore_backend_folder_create_message(struct backend_context *bctx, void *folder, TALLOC_CTX *mem_ctx, uint64_t mid, uint8_t associated, void **messagep) { return bctx->backend->folder.create_message(folder, mem_ctx, mid, associated, messagep); } enum mapistore_error mapistore_backend_folder_delete_message(struct backend_context *bctx, void *folder, uint64_t mid, uint8_t flags) { return bctx->backend->folder.delete_message(folder, mid, flags); } enum mapistore_error mapistore_backend_folder_move_copy_messages(struct backend_context *bctx, void *target_folder, void *source_folder, TALLOC_CTX *mem_ctx, uint32_t mid_count, uint64_t *source_mids, uint64_t *target_mids, struct Binary_r **target_change_keys, uint8_t want_copy) { return bctx->backend->folder.move_copy_messages(target_folder, source_folder, mem_ctx, mid_count, source_mids, target_mids, target_change_keys, want_copy); } enum mapistore_error mapistore_backend_folder_move_folder(struct backend_context *bctx, void *move_folder, void *target_folder, TALLOC_CTX *mem_ctx, const char *new_folder_name) { return bctx->backend->folder.move_folder(move_folder, target_folder, mem_ctx, new_folder_name); } enum mapistore_error mapistore_backend_folder_copy_folder(struct backend_context *bctx, void *move_folder, void *target_folder, TALLOC_CTX *mem_ctx, bool recursive, const char *new_folder_name) { return bctx->backend->folder.copy_folder(move_folder, target_folder, mem_ctx, recursive, new_folder_name); } enum mapistore_error mapistore_backend_folder_get_deleted_fmids(struct backend_context *bctx, void *folder, TALLOC_CTX *mem_ctx, enum mapistore_table_type table_type, uint64_t change_num, struct UI8Array_r **fmidsp, uint64_t *cnp) { return bctx->backend->folder.get_deleted_fmids(folder, mem_ctx, table_type, change_num, fmidsp, cnp); } enum mapistore_error mapistore_backend_folder_get_child_count(struct backend_context *bctx, void *folder, enum mapistore_table_type table_type, uint32_t *RowCount) { return bctx->backend->folder.get_child_count(folder, table_type, RowCount); } enum mapistore_error mapistore_backend_folder_get_child_fid_by_name(struct backend_context *bctx, void *folder, const char *name, uint64_t *fidp) { enum mapistore_error ret = MAPISTORE_SUCCESS; struct mapi_SRestriction name_restriction; void *table; uint8_t status; TALLOC_CTX *mem_ctx; enum MAPITAGS col; struct mapistore_property_data *data_pointers; uint32_t row_count; mem_ctx = talloc_zero(NULL, TALLOC_CTX); if (mapistore_backend_folder_open_table(bctx, folder, mem_ctx, MAPISTORE_FOLDER_TABLE, 0, &table, &row_count)) { talloc_free(mem_ctx); return MAPISTORE_ERROR; } name_restriction.rt = RES_PROPERTY; name_restriction.res.resProperty.relop = RELOP_EQ; name_restriction.res.resProperty.ulPropTag = PR_DISPLAY_NAME_UNICODE; name_restriction.res.resProperty.lpProp.ulPropTag = name_restriction.res.resProperty.ulPropTag; name_restriction.res.resProperty.lpProp.value.lpszW = name; col = PR_FID; mapistore_backend_table_set_columns(bctx, table, 1, &col); mapistore_backend_table_set_restrictions(bctx, table, &name_restriction, &status); ret = mapistore_backend_table_get_row(bctx, table, mem_ctx, MAPISTORE_PREFILTERED_QUERY, 0, &data_pointers); if (!ret) { if (data_pointers[0].error) { ret = MAPISTORE_ERROR; } else { *fidp = *(uint64_t *) data_pointers[0].data; } } talloc_free(mem_ctx); return ret; } enum mapistore_error mapistore_backend_folder_open_table(struct backend_context *bctx, void *folder, TALLOC_CTX *mem_ctx, enum mapistore_table_type table_type, uint32_t handle_id, void **table, uint32_t *row_count) { return bctx->backend->folder.open_table(folder, mem_ctx, table_type, handle_id, table, row_count); } enum mapistore_error mapistore_backend_folder_modify_permissions(struct backend_context *bctx, void *folder, uint8_t flags, uint16_t pcount, struct PermissionData *permissions) { return bctx->backend->folder.modify_permissions(folder, flags, pcount, permissions); } enum mapistore_error mapistore_backend_folder_preload_message_bodies(struct backend_context *bctx, void *folder, enum mapistore_table_type table_type, const struct UI8Array_r *mids) { return bctx->backend->folder.preload_message_bodies(folder, table_type, mids); } enum mapistore_error mapistore_backend_message_get_message_data(struct backend_context *bctx, void *message, TALLOC_CTX *mem_ctx, struct mapistore_message **msg) { return bctx->backend->message.get_message_data(message, mem_ctx, msg); } enum mapistore_error mapistore_backend_message_modify_recipients(struct backend_context *bctx, void *message, struct SPropTagArray *columns, uint16_t count, struct mapistore_message_recipient *recipients) { return bctx->backend->message.modify_recipients(message, columns, count, recipients); } enum mapistore_error mapistore_backend_message_set_read_flag(struct backend_context *bctx, void *message, uint8_t flag) { return bctx->backend->message.set_read_flag(message, flag); } enum mapistore_error mapistore_backend_message_save(struct backend_context *bctx, void *message) { return bctx->backend->message.save(message); } enum mapistore_error mapistore_backend_message_submit(struct backend_context *bctx, void *message, enum SubmitFlags flags) { return bctx->backend->message.submit(message, flags); } enum mapistore_error mapistore_backend_message_open_attachment(struct backend_context *bctx, void *message, TALLOC_CTX *mem_ctx, uint32_t aid, void **attachment) { return bctx->backend->message.open_attachment(message, mem_ctx, aid, attachment); } enum mapistore_error mapistore_backend_message_create_attachment(struct backend_context *bctx, void *message, TALLOC_CTX *mem_ctx, void **attachment, uint32_t *aid) { return bctx->backend->message.create_attachment(message, mem_ctx, attachment, aid); } enum mapistore_error mapistore_backend_message_get_attachment_table(struct backend_context *bctx, void *message, TALLOC_CTX *mem_ctx, void **table, uint32_t *row_count) { return bctx->backend->message.get_attachment_table(message, mem_ctx, table, row_count); } enum mapistore_error mapistore_backend_message_attachment_open_embedded_message(struct backend_context *bctx, void *attachment, TALLOC_CTX *mem_ctx, void **embedded_message, uint64_t *mid, struct mapistore_message **msg) { return bctx->backend->message.open_embedded_message(attachment, mem_ctx, embedded_message, mid, msg); } enum mapistore_error mapistore_backend_message_attachment_create_embedded_message(struct backend_context *bctx, void *attachment, TALLOC_CTX *mem_ctx, void **embedded_message, struct mapistore_message **msg) { return bctx->backend->message.create_embedded_message(attachment, mem_ctx, embedded_message, msg); } enum mapistore_error mapistore_backend_table_get_available_properties(struct backend_context *bctx, void *table, TALLOC_CTX *mem_ctx, struct SPropTagArray **propertiesp) { return bctx->backend->table.get_available_properties(table, mem_ctx, propertiesp); } enum mapistore_error mapistore_backend_table_set_columns(struct backend_context *bctx, void *table, uint16_t count, enum MAPITAGS *properties) { return bctx->backend->table.set_columns(table, count, properties); } enum mapistore_error mapistore_backend_table_set_restrictions(struct backend_context *bctx, void *table, struct mapi_SRestriction *restrictions, uint8_t *table_status) { return bctx->backend->table.set_restrictions(table, restrictions, table_status); } enum mapistore_error mapistore_backend_table_set_sort_order(struct backend_context *bctx, void *table, struct SSortOrderSet *sort_order, uint8_t *table_status) { return bctx->backend->table.set_sort_order(table, sort_order, table_status); } enum mapistore_error mapistore_backend_table_get_row(struct backend_context *bctx, void *table, TALLOC_CTX *mem_ctx, enum mapistore_query_type query_type, uint32_t rowid, struct mapistore_property_data **data) { return bctx->backend->table.get_row(table, mem_ctx, query_type, rowid, data); } enum mapistore_error mapistore_backend_table_get_row_count(struct backend_context *bctx, void *table, enum mapistore_query_type query_type, uint32_t *row_countp) { return bctx->backend->table.get_row_count(table, query_type, row_countp); } enum mapistore_error mapistore_backend_table_handle_destructor(struct backend_context *bctx, void *table, uint32_t handle_id) { return bctx->backend->table.handle_destructor(table, handle_id); } enum mapistore_error mapistore_backend_properties_get_available_properties(struct backend_context *bctx, void *object, TALLOC_CTX *mem_ctx, struct SPropTagArray **propertiesp) { return bctx->backend->properties.get_available_properties(object, mem_ctx, propertiesp); } enum mapistore_error mapistore_backend_properties_get_properties(struct backend_context *bctx, void *object, TALLOC_CTX *mem_ctx, uint16_t count, enum MAPITAGS *properties, struct mapistore_property_data *data) { return bctx->backend->properties.get_properties(object, mem_ctx, count, properties, data); } enum mapistore_error mapistore_backend_properties_set_properties(struct backend_context *bctx, void *object, struct SRow *aRow) { return bctx->backend->properties.set_properties(object, aRow); } enum mapistore_error mapistore_backend_manager_generate_uri(struct backend_context *bctx, TALLOC_CTX *mem_ctx, const char *username, const char *folder, const char *message, const char *root_uri, char **uri) { return bctx->backend->manager.generate_uri(mem_ctx, username, folder, message, root_uri, uri); } openchange-2.0/mapiproxy/libmapistore/mapistore_backend_defaults.c000066400000000000000000000371311223057412600257200ustar00rootroot00000000000000/* OpenChange Storage Abstraction Layer library OpenChange Project Copyright (C) Julien Kerihuel 2011-2012 This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see . */ #include "mapistore_errors.h" #include "mapistore.h" #include "mapistore_private.h" /** \file mapistore_backend_defaults.c \brief Initialize default behavior for mapistore backends */ static enum mapistore_error mapistore_op_defaults_init(void) { DEBUG(3, ("[%s:%d] MAPISTORE defaults - MAPISTORE_ERR_NOT_IMPLEMENTED\n", __FUNCTION__, __LINE__)); return MAPISTORE_ERR_NOT_IMPLEMENTED; } static enum mapistore_error mapistore_op_defaults_list_contexts(const char *owner, struct tdb_wrap *indexing, TALLOC_CTX *mem_ctx, struct mapistore_contexts_list **contexts_listp) { DEBUG(3, ("[%s:%d] MAPISTORE defaults - MAPISTORE_ERR_NOT_IMPLEMENTED\n", __FUNCTION__, __LINE__)); return MAPISTORE_ERR_NOT_IMPLEMENTED; } static enum mapistore_error mapistore_op_defaults_create_context(TALLOC_CTX *mem_ctx, struct mapistore_connection_info *conn_info, struct tdb_wrap *indexing_ctx, const char *uri, void **ctx) { DEBUG(3, ("[%s:%d] MAPISTORE defaults - MAPISTORE_ERR_NOT_IMPLEMENTED\n", __FUNCTION__, __LINE__)); return MAPISTORE_ERR_NOT_IMPLEMENTED; } static enum mapistore_error mapistore_op_defaults_create_root_folder(const char *username, enum mapistore_context_role ctx_role, uint64_t fid, const char *name, TALLOC_CTX *mem_ctx, char **mapistore_urip) { DEBUG(3, ("[%s:%d] MAPISTORE defaults - MAPISTORE_ERR_NOT_IMPLEMENTED\n", __FUNCTION__, __LINE__)); return MAPISTORE_ERR_NOT_IMPLEMENTED; } static enum mapistore_error mapistore_op_defaults_get_path(void *ctx_obj, TALLOC_CTX *mem_ctx, uint64_t fmid, char **path) { DEBUG(3, ("[%s:%d] MAPISTORE defaults - MAPISTORE_ERR_NOT_IMPLEMENTED\n", __FUNCTION__, __LINE__)); return MAPISTORE_ERR_NOT_IMPLEMENTED; } static enum mapistore_error mapistore_op_defaults_get_root_folder(void *backend_object, TALLOC_CTX *mem_ctx, uint64_t fid, void **root_folder_object) { DEBUG(3, ("[%s:%d] MAPISTORE defaults - MAPISTORE_ERR_NOT_IMPLEMENTED\n", __FUNCTION__, __LINE__)); return MAPISTORE_ERR_NOT_IMPLEMENTED; } static enum mapistore_error mapistore_op_defaults_open_folder(void *folder_object, TALLOC_CTX *mem_ctx, uint64_t fid, void **child_folder_object) { DEBUG(3, ("[%s:%d] MAPISTORE defaults - MAPISTORE_ERR_NOT_IMPLEMENTED\n", __FUNCTION__, __LINE__)); return MAPISTORE_ERR_NOT_IMPLEMENTED; } static enum mapistore_error mapistore_op_defaults_create_folder(void *folder_object, TALLOC_CTX *mem_ctx, uint64_t fid, struct SRow *aRow, void **child_folder_object) { DEBUG(3, ("[%s:%d] MAPISTORE defaults - MAPISTORE_ERR_NOT_IMPLEMENTED\n", __FUNCTION__, __LINE__)); return MAPISTORE_ERR_NOT_IMPLEMENTED; } static enum mapistore_error mapistore_op_defaults_delete_folder(void *folder_object) { DEBUG(3, ("[%s:%d] MAPISTORE defaults - MAPISTORE_ERR_NOT_IMPLEMENTED\n", __FUNCTION__, __LINE__)); return MAPISTORE_ERR_NOT_IMPLEMENTED; } static enum mapistore_error mapistore_op_defaults_open_message(void *folder_object, TALLOC_CTX *mem_ctx, uint64_t mid, bool rw, void **message_object) { DEBUG(3, ("[%s:%d] MAPISTORE defaults - MAPISTORE_ERR_NOT_IMPLEMENTED\n", __FUNCTION__, __LINE__)); return MAPISTORE_ERR_NOT_IMPLEMENTED; } static enum mapistore_error mapistore_op_defaults_create_message(void *folder_object, TALLOC_CTX *mem_ctx, uint64_t mid, uint8_t associated, void **message_object) { DEBUG(3, ("[%s:%d] MAPISTORE defaults - MAPISTORE_ERR_NOT_IMPLEMENTED\n", __FUNCTION__, __LINE__)); return MAPISTORE_ERR_NOT_IMPLEMENTED; } static enum mapistore_error mapistore_op_defaults_delete_message(void *folder_object, uint64_t mid, uint8_t flags) { DEBUG(3, ("[%s:%d] MAPISTORE defaults - MAPISTORE_ERR_NOT_IMPLEMENTED\n", __FUNCTION__, __LINE__)); return MAPISTORE_ERR_NOT_IMPLEMENTED; } static enum mapistore_error mapistore_op_defaults_move_copy_messages(void *target_folder, void *source_folder, TALLOC_CTX *mem_ctx, uint32_t mid_count, uint64_t *source_mids, uint64_t *target_mids, struct Binary_r **target_change_keys, uint8_t want_copy) { DEBUG(3, ("[%s:%d] MAPISTORE defaults - MAPISTORE_ERR_NOT_IMPLEMENTED\n", __FUNCTION__, __LINE__)); return MAPISTORE_ERR_NOT_IMPLEMENTED; } static enum mapistore_error mapistore_op_defaults_get_deleted_fmids(void *folder_object, TALLOC_CTX *mem_ctx, enum mapistore_table_type table_type, uint64_t change_num, struct UI8Array_r **fmidsp, uint64_t *cnp) { DEBUG(3, ("[%s:%d] MAPISTORE defaults - MAPISTORE_ERR_NOT_IMPLEMENTED\n", __FUNCTION__, __LINE__)); return MAPISTORE_ERR_NOT_IMPLEMENTED; } static enum mapistore_error mapistore_op_defaults_get_child_count(void *folder_object, enum mapistore_table_type table_type, uint32_t *RowCount) { DEBUG(3, ("[%s:%d] MAPISTORE defaults - MAPISTORE_ERR_NOT_IMPLEMENTED\n", __FUNCTION__, __LINE__)); return MAPISTORE_ERR_NOT_IMPLEMENTED; } static enum mapistore_error mapistore_op_defaults_open_table(void *folder_object, TALLOC_CTX *mem_ctx, enum mapistore_table_type table_type, uint32_t handle_id, void **table_object, uint32_t *row_count) { DEBUG(3, ("[%s:%d] MAPISTORE defaults - MAPISTORE_ERR_NOT_IMPLEMENTED\n", __FUNCTION__, __LINE__)); return MAPISTORE_ERR_NOT_IMPLEMENTED; } static enum mapistore_error mapistore_op_defaults_modify_permissions(void *folder_object, uint8_t flags, uint16_t pcount, struct PermissionData *permissions) { DEBUG(3, ("[%s:%d] MAPISTORE defaults - MAPISTORE_ERR_NOT_IMPLEMENTED\n", __FUNCTION__, __LINE__)); return MAPISTORE_ERR_NOT_IMPLEMENTED; } static enum mapistore_error mapistore_op_defaults_get_message_data(void *message_object, TALLOC_CTX *mem_ctx, struct mapistore_message **msg) { DEBUG(3, ("[%s:%d] MAPISTORE defaults - MAPISTORE_ERR_NOT_IMPLEMENTED\n", __FUNCTION__, __LINE__)); return MAPISTORE_ERR_NOT_IMPLEMENTED; } static enum mapistore_error mapistore_op_defaults_modify_recipients(void *message_object, struct SPropTagArray *columns, uint16_t count, struct mapistore_message_recipient *recipients) { DEBUG(3, ("[%s:%d] MAPISTORE defaults - MAPISTORE_ERR_NOT_IMPLEMENTED\n", __FUNCTION__, __LINE__)); return MAPISTORE_ERR_NOT_IMPLEMENTED; } static enum mapistore_error mapistore_op_defaults_set_read_flag(void *message_object, uint8_t flag) { DEBUG(3, ("[%s:%d] MAPISTORE defaults - MAPISTORE_ERR_NOT_IMPLEMENTED\n", __FUNCTION__, __LINE__)); return MAPISTORE_ERR_NOT_IMPLEMENTED; } static enum mapistore_error mapistore_op_defaults_save(void *message_object) { DEBUG(3, ("[%s:%d] MAPISTORE defaults - MAPISTORE_ERR_NOT_IMPLEMENTED\n", __FUNCTION__, __LINE__)); return MAPISTORE_ERR_NOT_IMPLEMENTED; } static enum mapistore_error mapistore_op_defaults_submit(void *message_object, enum SubmitFlags flags) { DEBUG(3, ("[%s:%d] MAPISTORE defaults - MAPISTORE_ERR_NOT_IMPLEMENTED\n", __FUNCTION__, __LINE__)); return MAPISTORE_ERR_NOT_IMPLEMENTED; } static enum mapistore_error mapistore_op_defaults_open_attachment(void *message_object, TALLOC_CTX *mem_ctx, uint32_t aid, void **attachment_object) { DEBUG(3, ("[%s:%d] MAPISTORE defaults - MAPISTORE_ERR_NOT_IMPLEMENTED\n", __FUNCTION__, __LINE__)); return MAPISTORE_ERR_NOT_IMPLEMENTED; } static enum mapistore_error mapistore_op_defaults_create_attachment(void *message_object, TALLOC_CTX *mem_ctx, void **attachment_object, uint32_t *aid) { DEBUG(3, ("[%s:%d] MAPISTORE defaults - MAPISTORE_ERR_NOT_IMPLEMENTED\n", __FUNCTION__, __LINE__)); return MAPISTORE_ERR_NOT_IMPLEMENTED; } static enum mapistore_error mapistore_op_defaults_get_attachment_table(void *message_object, TALLOC_CTX *mem_ctx, void **table_object, uint32_t *row_count) { DEBUG(3, ("[%s:%d] MAPISTORE defaults - MAPISTORE_ERR_NOT_IMPLEMENTED\n", __FUNCTION__, __LINE__)); return MAPISTORE_ERR_NOT_IMPLEMENTED; } static enum mapistore_error mapistore_op_defaults_open_embedded_message(void *message_object, TALLOC_CTX *mem_ctx, void **embedded_message_object, uint64_t *mid, struct mapistore_message **msg) { DEBUG(3, ("[%s:%d] MAPISTORE defaults - MAPISTORE_ERR_NOT_IMPLEMENTED\n", __FUNCTION__, __LINE__)); return MAPISTORE_ERR_NOT_IMPLEMENTED; } static enum mapistore_error mapistore_op_defaults_get_available_properties(void *x_object, TALLOC_CTX *mem_ctx, struct SPropTagArray **propertiesp) { DEBUG(3, ("[%s:%d] MAPISTORE defaults - MAPISTORE_ERR_NOT_IMPLEMENTED\n", __FUNCTION__, __LINE__)); return MAPISTORE_ERR_NOT_IMPLEMENTED; } static enum mapistore_error mapistore_op_defaults_set_columns(void *table_object, uint16_t count, enum MAPITAGS *properties) { DEBUG(3, ("[%s:%d] MAPISTORE defaults - MAPISTORE_ERR_NOT_IMPLEMENTED\n", __FUNCTION__, __LINE__)); return MAPISTORE_ERR_NOT_IMPLEMENTED; } static enum mapistore_error mapistore_op_defaults_set_restrictions(void *table_object, struct mapi_SRestriction *restrictions, uint8_t *table_status) { DEBUG(3, ("[%s:%d] MAPISTORE defaults - MAPISTORE_ERR_NOT_IMPLEMENTED\n", __FUNCTION__, __LINE__)); return MAPISTORE_ERR_NOT_IMPLEMENTED; } static enum mapistore_error mapistore_op_defaults_set_sort_order(void *table_object, struct SSortOrderSet *sort_order, uint8_t *table_status) { DEBUG(3, ("[%s:%d] MAPISTORE defaults - MAPISTORE_ERR_NOT_IMPLEMENTED\n", __FUNCTION__, __LINE__)); return MAPISTORE_ERR_NOT_IMPLEMENTED; } static enum mapistore_error mapistore_op_defaults_get_row(void *table_object, TALLOC_CTX *mem_ctx, enum mapistore_query_type query_type, uint32_t rowid, struct mapistore_property_data **data) { DEBUG(3, ("[%s:%d] MAPISTORE defaults - MAPISTORE_ERR_NOT_IMPLEMENTED\n", __FUNCTION__, __LINE__)); return MAPISTORE_ERR_NOT_IMPLEMENTED; } static enum mapistore_error mapistore_op_defaults_get_row_count(void *table_object, enum mapistore_query_type query_type, uint32_t *row_countp) { DEBUG(3, ("[%s:%d] MAPISTORE defaults - MAPISTORE_ERR_NOT_IMPLEMENTED\n", __FUNCTION__, __LINE__)); return MAPISTORE_ERR_NOT_IMPLEMENTED; } static enum mapistore_error mapistore_op_defaults_handle_destructor(void *table_object, uint32_t handle_id) { DEBUG(3, ("[%s:%d] MAPISTORE defaults - MAPISTORE_ERR_NOT_IMPLEMENTED\n", __FUNCTION__, __LINE__)); return MAPISTORE_ERR_NOT_IMPLEMENTED; } static enum mapistore_error mapistore_op_defaults_get_properties(void *x_object, TALLOC_CTX *mem_ctx, uint16_t count, enum MAPITAGS *properties, struct mapistore_property_data *data) { DEBUG(3, ("[%s:%d] MAPISTORE defaults - MAPISTORE_ERR_NOT_IMPLEMENTED\n", __FUNCTION__, __LINE__)); return MAPISTORE_ERR_NOT_IMPLEMENTED; } static enum mapistore_error mapistore_op_defaults_set_properties(void *x_object, struct SRow *aRow) { DEBUG(3, ("[%s:%d] MAPISTORE defaults - MAPISTORE_ERR_NOT_IMPLEMENTED\n", __FUNCTION__, __LINE__)); return MAPISTORE_ERR_NOT_IMPLEMENTED; } static enum mapistore_error mapistore_op_defaults_generate_uri(TALLOC_CTX *mem_ctx, const char *username, const char *folder, const char *message, const char *root_uri, char **uri) { DEBUG(3, ("[%s:%d] MAPISTORE defaults - MAPISTORE_ERR_NOT_IMPLEMENTED\n", __FUNCTION__, __LINE__)); return MAPISTORE_ERR_NOT_IMPLEMENTED; } extern enum mapistore_error mapistore_backend_init_defaults(struct mapistore_backend *backend) { /* Sanity checks */ MAPISTORE_RETVAL_IF(!backend, MAPISTORE_ERR_INVALID_PARAMETER, NULL); /* Backend operations */ backend->backend.name = NULL; backend->backend.description = NULL; backend->backend.namespace = NULL; backend->backend.init = mapistore_op_defaults_init; backend->backend.list_contexts = mapistore_op_defaults_list_contexts; backend->backend.create_context = mapistore_op_defaults_create_context; backend->backend.create_root_folder = mapistore_op_defaults_create_root_folder; /* context operations */ backend->context.get_path = mapistore_op_defaults_get_path; backend->context.get_root_folder = mapistore_op_defaults_get_root_folder; /* oxcfold semantics */ backend->folder.open_folder = mapistore_op_defaults_open_folder; backend->folder.create_folder = mapistore_op_defaults_create_folder; backend->folder.delete = mapistore_op_defaults_delete_folder; backend->folder.open_message = mapistore_op_defaults_open_message; backend->folder.create_message = mapistore_op_defaults_create_message; backend->folder.delete_message = mapistore_op_defaults_delete_message; backend->folder.move_copy_messages = mapistore_op_defaults_move_copy_messages; backend->folder.get_deleted_fmids = mapistore_op_defaults_get_deleted_fmids; backend->folder.get_child_count = mapistore_op_defaults_get_child_count; backend->folder.open_table = mapistore_op_defaults_open_table; backend->folder.modify_permissions = mapistore_op_defaults_modify_permissions; /* oxcmsg operations */ backend->message.get_message_data = mapistore_op_defaults_get_message_data; backend->message.modify_recipients = mapistore_op_defaults_modify_recipients; backend->message.set_read_flag = mapistore_op_defaults_set_read_flag; backend->message.save = mapistore_op_defaults_save; backend->message.submit = mapistore_op_defaults_submit; backend->message.open_attachment = mapistore_op_defaults_open_attachment; backend->message.create_attachment = mapistore_op_defaults_create_attachment; backend->message.get_attachment_table = mapistore_op_defaults_get_attachment_table; backend->message.open_embedded_message = mapistore_op_defaults_open_embedded_message; /* oxctabl operations */ backend->table.get_available_properties = mapistore_op_defaults_get_available_properties; backend->table.set_columns = mapistore_op_defaults_set_columns; backend->table.set_restrictions = mapistore_op_defaults_set_restrictions; backend->table.set_sort_order = mapistore_op_defaults_set_sort_order; backend->table.get_row = mapistore_op_defaults_get_row; backend->table.get_row_count = mapistore_op_defaults_get_row_count; backend->table.handle_destructor = mapistore_op_defaults_handle_destructor; /* oxcprpt operations */ backend->properties.get_available_properties = mapistore_op_defaults_get_available_properties; backend->properties.get_properties = mapistore_op_defaults_get_properties; backend->properties.set_properties = mapistore_op_defaults_set_properties; /* manager operations */ backend->manager.generate_uri = mapistore_op_defaults_generate_uri; return MAPISTORE_SUCCESS; } openchange-2.0/mapiproxy/libmapistore/mapistore_errors.h000066400000000000000000000073671223057412600237730ustar00rootroot00000000000000/* OpenChange Storage Abstraction Layer library OpenChange Project Copyright (C) Julien Kerihuel 2009 This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see . */ /** \file mapistore_errors.h This header provides a set of result codes for MAPISTORE function calls. */ #ifndef __MAPISTORE_ERRORS_H #define __MAPISTORE_ERRORS_H void mapistore_set_errno(int); #define MAPISTORE_RETVAL_IF(x,e,c) \ do { \ if (x) { \ mapistore_set_errno(e); \ if (c) { \ talloc_free(c); \ } \ return (e); \ } \ } while (0); #define MAPISTORE_SANITY_CHECKS(x,c) \ MAPISTORE_RETVAL_IF(!x, MAPISTORE_ERR_NOT_INITIALIZED, c); \ MAPISTORE_RETVAL_IF(!x->processing_ctx, MAPISTORE_ERR_NOT_INITIALIZED, c); \ MAPISTORE_RETVAL_IF(!x->context_list, MAPISTORE_ERR_NOT_INITIALIZED, c); enum mapistore_error { /** The function call succeeded. */ MAPISTORE_SUCCESS = 0, /** The function call failed for some non-specific reason. */ MAPISTORE_ERROR = 1, /** The function call failed because it was unable to allocate the memory required by underlying operations. */ MAPISTORE_ERR_NO_MEMORY = 2, /** The function call failed because underlying context has already been initialized */ MAPISTORE_ERR_ALREADY_INITIALIZED = 3, /** The function call failed because context has not been initialized. */ MAPISTORE_ERR_NOT_INITIALIZED = 4, /** The function call failed because an internal mapistore storage component has corrupted data. */ MAPISTORE_ERR_CORRUPTED = 5, /** The function call failed because one of the function parameters is invalid */ MAPISTORE_ERR_INVALID_PARAMETER = 6, /** The function call failed because the directory doesn't exist */ MAPISTORE_ERR_NO_DIRECTORY = 7, /** The function call failed because the underlying function couldn't open a database. */ MAPISTORE_ERR_DATABASE_INIT = 8, /** The function call failed because the underlying function didn't run a database operation successfully. */ MAPISTORE_ERR_DATABASE_OPS = 9, /** The function failed to register a storage backend */ MAPISTORE_ERR_BACKEND_REGISTER = 10, /** One of more storage backend initialization functions failed to complete successfully. */ MAPISTORE_ERR_BACKEND_INIT = 11, /** The function failed because mapistore failed to create a context */ MAPISTORE_ERR_CONTEXT_FAILED = 12, /** The function failed because the provided namespace is invalid */ MAPISTORE_ERR_INVALID_NAMESPACE = 13, /** The function failed to find requested record/data */ MAPISTORE_ERR_NOT_FOUND = 14, /** The function still has a reference count */ MAPISTORE_ERR_REF_COUNT = 15, /** The function already have record/data for the searched element */ MAPISTORE_ERR_EXIST = 16, /** The function failed to generate requested data/payload */ MAPISTORE_ERR_INVALID_DATA = 17, /** The function failed to send message */ MAPISTORE_ERR_MSG_SEND = 18, /** The function failed to receive message */ MAPISTORE_ERR_MSG_RCV = 19, /** The operation required privileges that the user does not have */ MAPISTORE_ERR_DENIED = 20, /** The function is not implemented */ MAPISTORE_ERR_NOT_IMPLEMENTED }; #endif /* ! __MAPISTORE_ERRORS_H */ openchange-2.0/mapiproxy/libmapistore/mapistore_indexing.c000066400000000000000000000504301223057412600242440ustar00rootroot00000000000000/* OpenChange Storage Abstraction Layer library OpenChange Project Copyright (C) Julien Kerihuel 2010 This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see . */ /** \file mapistore_indexing.c \brief MAPISTORE internal indexing functions This file contains functionality to map between folder / message identifiers and backend URI strings. */ #include #include "mapistore.h" #include "mapistore_errors.h" #include "mapistore_private.h" #include #include "libmapi/libmapi_private.h" #include /** \details Search the indexing record matching the username \param mstore_ctx pointer to the mapistore context \param username the username to lookup \return pointer to the tdb_wrap structure on success, otherwise NULL */ struct indexing_context_list *mapistore_indexing_search(struct mapistore_context *mstore_ctx, const char *username) { struct indexing_context_list *el; /* Sanity checks */ if (!mstore_ctx) return NULL; if (!mstore_ctx->indexing_list) return NULL; if (!username) return NULL; for (el = mstore_ctx->indexing_list; el; el = el->next) { if (el && el->username && !strcmp(el->username, username)) { return el; } } return NULL; } /** \details Open connection to indexing database for a given user \param mstore_ctx pointer to the mapistore context \param username name for which the indexing database has to be created \return MAPISTORE_SUCCESS on success, otherwise MAPISTORE error */ _PUBLIC_ enum mapistore_error mapistore_indexing_add(struct mapistore_context *mstore_ctx, const char *username, struct indexing_context_list **ictxp) { TALLOC_CTX *mem_ctx; struct indexing_context_list *ictx; char *dbpath = NULL; /* Sanity checks */ MAPISTORE_RETVAL_IF(!mstore_ctx, MAPISTORE_ERR_NOT_INITIALIZED, NULL); MAPISTORE_RETVAL_IF(!username, MAPISTORE_ERROR, NULL); /* Step 1. Search if the context already exists */ ictx = mapistore_indexing_search(mstore_ctx, username); *ictxp = ictx; MAPISTORE_RETVAL_IF(ictx, MAPISTORE_SUCCESS, NULL); mem_ctx = talloc_named(NULL, 0, "mapistore_indexing_init"); ictx = talloc_zero(mstore_ctx, struct indexing_context_list); /* Step 1. Open/Create the indexing database */ dbpath = talloc_asprintf(mem_ctx, "%s/%s/indexing.tdb", mapistore_get_mapping_path(), username); ictx->index_ctx = mapistore_tdb_wrap_open(ictx, dbpath, 0, 0, O_RDWR|O_CREAT, 0600); talloc_free(dbpath); if (!ictx->index_ctx) { DEBUG(3, ("[%s:%d]: %s\n", __FUNCTION__, __LINE__, strerror(errno))); talloc_free(ictx); talloc_free(mem_ctx); return MAPISTORE_ERR_DATABASE_INIT; } ictx->username = talloc_strdup(ictx, username); /* ictx->ref_count = 0; */ DLIST_ADD_END(mstore_ctx->indexing_list, ictx, struct indexing_context_list *); *ictxp = ictx; talloc_free(mem_ctx); return MAPISTORE_SUCCESS; } /* /\** */ /* \details Increase the ref count associated to a given indexing context */ /* \param ictx pointer to the indexing context */ /* \return MAPISTORE_SUCCESS on success, otherwise MAPISTORE_ERROR */ /* *\/ */ /* enum mapistore_error mapistore_indexing_add_ref_count(struct indexing_context_list *ictx) */ /* { */ /* MAPISTORE_RETVAL_IF(!ictx, MAPISTORE_ERROR, NULL); */ /* ictx->ref_count += 1; */ /* return MAPISTORE_SUCCESS; */ /* } */ /* /\** */ /* \details Decrease the ref count associated to a given indexing context */ /* \param ictx pointer to the indexing context */ /* \return MAPISTORE_SUCCESS on success, otherwise MAPISTORE_ERROR */ /* *\/ */ /* enum mapistore_error mapistore_indexing_del_ref_count(struct indexing_context_list *ictx) */ /* { */ /* MAPISTORE_RETVAL_IF(!ictx, MAPISTORE_ERROR, NULL); */ /* MAPISTORE_RETVAL_IF(!ictx->ref_count, MAPISTORE_SUCCESS, NULL); */ /* ictx->ref_count -= 1; */ /* return MAPISTORE_SUCCESS; */ /* } */ /** \details Convenient function to check if the folder/message ID passed in parameter already exists in the database or not and whether it is soft deleted or not \param ictx pointer to the indexing context \param fmid folder/message ID to lookup \param IsSoftDeleted pointer to boolean returned by the function which indicates whether the record is soft_deleted or not \return MAPISTORE_SUCCESS if the folder/message ID doesn't exist, otherwise MAPISTORE_ERR_EXIST. */ enum mapistore_error mapistore_indexing_search_existing_fmid(struct indexing_context_list *ictx, uint64_t fmid, bool *IsSoftDeleted) { int ret; TDB_DATA key; /* Sanity */ MAPISTORE_RETVAL_IF(!ictx, MAPISTORE_ERROR, NULL); MAPISTORE_RETVAL_IF(!fmid, MAPISTORE_ERROR, NULL); key.dptr = (unsigned char *) talloc_asprintf(ictx, "0x%.16"PRIx64, fmid); key.dsize = strlen((const char *)key.dptr); *IsSoftDeleted = false; ret = tdb_exists(ictx->index_ctx->tdb, key); talloc_free(key.dptr); /* If it doesn't exist look for a SOFT_DELETED entry */ if (!ret) { key.dptr = (unsigned char *) talloc_asprintf(ictx, "%s0x%.16"PRIx64, MAPISTORE_SOFT_DELETED_TAG, fmid); key.dsize = strlen((const char *)key.dptr); ret = tdb_exists(ictx->index_ctx->tdb, key); if (ret) { *IsSoftDeleted = true; } } MAPISTORE_RETVAL_IF(ret, MAPISTORE_ERR_EXIST, NULL); return MAPISTORE_SUCCESS; } enum mapistore_error mapistore_indexing_record_add(TALLOC_CTX *mem_ctx, struct indexing_context_list *ictx, uint64_t fmid, const char *mapistore_URI) { int ret; TDB_DATA key; TDB_DATA dbuf; /* Add the record given its fid and mapistore_uri */ key.dptr = (unsigned char *) talloc_asprintf(mem_ctx, "0x%.16"PRIx64, fmid); key.dsize = strlen((const char *) key.dptr); dbuf.dptr = (unsigned char *) talloc_strdup(mem_ctx, mapistore_URI); dbuf.dsize = strlen((const char *) dbuf.dptr); ret = tdb_store(ictx->index_ctx->tdb, key, dbuf, TDB_INSERT); talloc_free(key.dptr); talloc_free(dbuf.dptr); if (ret == -1) { DEBUG(3, ("[%s:%d]: Unable to create 0x%.16"PRIx64" record: %s\n", __FUNCTION__, __LINE__, fmid, mapistore_URI)); return MAPISTORE_ERR_DATABASE_OPS; } return MAPISTORE_SUCCESS; } /** \details Add a folder or message record to the indexing database \param mstore_ctx pointer to the mapistore context \param context_id the context identifier referencing the indexing database to update \param fmid the folder or message ID to add \param type MAPISTORE_FOLDER or MAPISTORE_MESSAGE \return MAPISTORE_SUCCESS on success, otherwise MAPISTORE error */ enum mapistore_error mapistore_indexing_record_add_fmid(struct mapistore_context *mstore_ctx, uint32_t context_id, const char *username, uint64_t fmid) { int ret; struct backend_context *backend_ctx; struct indexing_context_list *ictx; char *mapistore_URI = NULL; bool IsSoftDeleted = false; /* Sanity checks */ MAPISTORE_RETVAL_IF(!mstore_ctx, MAPISTORE_ERROR, NULL); MAPISTORE_RETVAL_IF(!context_id, MAPISTORE_ERROR, NULL); MAPISTORE_RETVAL_IF(!fmid, MAPISTORE_ERROR, NULL); /* Ensure the context exists */ backend_ctx = mapistore_backend_lookup(mstore_ctx->context_list, context_id); MAPISTORE_RETVAL_IF(!backend_ctx, MAPISTORE_ERR_INVALID_PARAMETER, NULL); MAPISTORE_RETVAL_IF(!backend_ctx->indexing, MAPISTORE_ERR_INVALID_PARAMETER, NULL); /* Check if the fid/mid doesn't already exist within the database */ ret = mapistore_indexing_add(mstore_ctx, username, &ictx); MAPISTORE_RETVAL_IF(ret, MAPISTORE_ERROR, NULL); MAPISTORE_RETVAL_IF(!ictx, MAPISTORE_ERROR, NULL); ret = mapistore_indexing_search_existing_fmid(ictx, fmid, &IsSoftDeleted); MAPISTORE_RETVAL_IF(ret, ret, NULL); /* Retrieve the mapistore URI given context_id and fmid */ mapistore_backend_get_path(backend_ctx, NULL, fmid, &mapistore_URI); /* DEBUG(0, ("mapistore_URI = %s\n", mapistore_URI)); */ MAPISTORE_RETVAL_IF(!mapistore_URI, MAPISTORE_ERROR, NULL); /* Add the record given its fid and mapistore_uri */ ret = mapistore_indexing_record_add(mstore_ctx, ictx, fmid, mapistore_URI); talloc_free(mapistore_URI); return ret; } /** \details Remove a folder or message record from the indexing database \param mstore_ctx pointer to the mapistore context \param context_id the context identifier referencing the indexing database to update \param fmid the folder or message ID to delete \param flags the type of deletion MAPISTORE_SOFT_DELETE or MAPISTORE_PERMANENT_DELETE \return MAPISTORE_SUCCESS on success, otherwise MAPISTORE error */ enum mapistore_error mapistore_indexing_record_del_fmid(struct mapistore_context *mstore_ctx, uint32_t context_id, const char *username, uint64_t fmid, uint8_t flags) { int ret; struct backend_context *backend_ctx; struct indexing_context_list *ictx; TDB_DATA key; TDB_DATA newkey; TDB_DATA dbuf; bool IsSoftDeleted = false; /* Sanity checks */ MAPISTORE_RETVAL_IF(!mstore_ctx, MAPISTORE_ERROR, NULL); MAPISTORE_RETVAL_IF(!context_id, MAPISTORE_ERROR, NULL); MAPISTORE_RETVAL_IF(!fmid, MAPISTORE_ERROR, NULL); /* Ensure the context exists */ backend_ctx = mapistore_backend_lookup(mstore_ctx->context_list, context_id); MAPISTORE_RETVAL_IF(!backend_ctx, MAPISTORE_ERR_INVALID_PARAMETER, NULL); MAPISTORE_RETVAL_IF(!backend_ctx->indexing, MAPISTORE_ERR_INVALID_PARAMETER, NULL); /* Check if the fid/mid still exists within the database */ ret = mapistore_indexing_add(mstore_ctx, username, &ictx); MAPISTORE_RETVAL_IF(ret, MAPISTORE_ERROR, NULL); MAPISTORE_RETVAL_IF(!ictx, MAPISTORE_ERROR, NULL); ret = mapistore_indexing_search_existing_fmid(ictx, fmid, &IsSoftDeleted); MAPISTORE_RETVAL_IF(!ret, ret, NULL); if (IsSoftDeleted == true) { key.dptr = (unsigned char *) talloc_asprintf(mstore_ctx, "%s0x%.16"PRIx64, MAPISTORE_SOFT_DELETED_TAG, fmid); } else { key.dptr = (unsigned char *) talloc_asprintf(mstore_ctx, "0x%.16"PRIx64, fmid); } key.dsize = strlen((const char *) key.dptr); switch (flags) { case MAPISTORE_SOFT_DELETE: /* nothing to do if the record is already soft deleted */ MAPISTORE_RETVAL_IF(IsSoftDeleted == true, MAPISTORE_SUCCESS, NULL); newkey.dptr = (unsigned char *) talloc_asprintf(mstore_ctx, "%s0x%.16"PRIx64, MAPISTORE_SOFT_DELETED_TAG, fmid); newkey.dsize = strlen ((const char *)newkey.dptr); /* Retrieve previous value */ dbuf = tdb_fetch(ictx->index_ctx->tdb, key); /* Add new record */ ret = tdb_store(ictx->index_ctx->tdb, newkey, dbuf, TDB_INSERT); free(dbuf.dptr); /* Delete previous record */ ret = tdb_delete(ictx->index_ctx->tdb, key); talloc_free(key.dptr); talloc_free(newkey.dptr); break; case MAPISTORE_PERMANENT_DELETE: ret = tdb_delete(ictx->index_ctx->tdb, key); talloc_free(key.dptr); MAPISTORE_RETVAL_IF(ret, MAPISTORE_ERR_DATABASE_OPS, NULL); break; } return MAPISTORE_SUCCESS; } /** \details Returns record data \param mstore_ctx pointer to the mapistore context \param username the name of the account where to look for the indexing database \param mem_ctx pointer to the memory context \param fmid the fmid/key to the record \param urip pointer to the uri pointer \param soft_deletedp pointer to the soft deleted pointer \return MAPISTORE_SUCCESS on success, otherwise MAPISTORE error */ _PUBLIC_ enum mapistore_error mapistore_indexing_record_get_uri(struct mapistore_context *mstore_ctx, const char *username, TALLOC_CTX *mem_ctx, uint64_t fmid, char **urip, bool *soft_deletedp) { struct indexing_context_list *ictx; TDB_DATA key, dbuf; int ret; /* Sanity checks */ MAPISTORE_RETVAL_IF(!mstore_ctx, MAPISTORE_ERR_NOT_INITIALIZED, NULL); MAPISTORE_RETVAL_IF(!username, MAPISTORE_ERR_NOT_INITIALIZED, NULL); MAPISTORE_RETVAL_IF(!urip, MAPISTORE_ERR_NOT_INITIALIZED, NULL); MAPISTORE_RETVAL_IF(!soft_deletedp, MAPISTORE_ERR_NOT_INITIALIZED, NULL); /* Check if the fmid exists within the database */ ret = mapistore_indexing_add(mstore_ctx, username, &ictx); MAPISTORE_RETVAL_IF(ret, MAPISTORE_ERROR, NULL); MAPISTORE_RETVAL_IF(!ictx, MAPISTORE_ERROR, NULL); key.dptr = (unsigned char *) talloc_asprintf(mstore_ctx, "0x%.16"PRIx64, fmid); key.dsize = strlen((const char *) key.dptr); ret = tdb_exists(ictx->index_ctx->tdb, key); if (ret) { *soft_deletedp = false; } else { talloc_free(key.dptr); key.dptr = (unsigned char *) talloc_asprintf(ictx, "%s0x%.16"PRIx64, MAPISTORE_SOFT_DELETED_TAG, fmid); key.dsize = strlen((const char *)key.dptr); ret = tdb_exists(ictx->index_ctx->tdb, key); if (ret) { *soft_deletedp = true; } else { talloc_free(key.dptr); *urip = NULL; return MAPISTORE_ERR_NOT_FOUND; } } dbuf = tdb_fetch(ictx->index_ctx->tdb, key); *urip = talloc_strndup(mem_ctx, (const char *) dbuf.dptr, dbuf.dsize); free(dbuf.dptr); talloc_free(key.dptr); return MAPISTORE_SUCCESS; } /** \details A slow but effective way to retrieve an fmid from a uri \param mstore_ctx pointer to the mapistore context \param mem_ctx pointer to the talloc context \param fmid the fmid/key to the record \param urip pointer to the uri pointer \param soft_deletedp pointer to the soft deleted pointer \return MAPISTORE_SUCCESS on success, otherwise MAPISTORE error */ struct tdb_get_fid_data { bool found; uint64_t fmid; char *uri; size_t uri_len; uint32_t wildcard_count; char *startswith; char *endswith; }; static int tdb_get_fid_traverse(struct tdb_context *tdb_ctx, TDB_DATA key, TDB_DATA value, void *data) { struct tdb_get_fid_data *tdb_data; char *key_str, *cmp_uri, *slash_ptr; TALLOC_CTX *mem_ctx; int ret = 0; mem_ctx = talloc_zero(NULL, void); tdb_data = data; cmp_uri = talloc_array(mem_ctx, char, value.dsize + 1); memcpy(cmp_uri, value.dptr, value.dsize); *(cmp_uri + value.dsize) = 0; slash_ptr = cmp_uri + value.dsize - 1; if (*slash_ptr == '/') { *slash_ptr = 0; } if (strcmp(cmp_uri, tdb_data->uri) == 0) { key_str = talloc_strndup(mem_ctx, (char *) key.dptr, key.dsize); tdb_data->fmid = strtoull(key_str, NULL, 16); tdb_data->found = true; ret = 1; } talloc_free(mem_ctx); return ret; } static int tdb_get_fid_traverse_partial(struct tdb_context *tdb_ctx, TDB_DATA key, TDB_DATA value, void *data) { struct tdb_get_fid_data *tdb_data; char *key_str, *cmp_uri, *slash_ptr; TALLOC_CTX *mem_ctx; int ret = 0; mem_ctx = talloc_zero(NULL, void); tdb_data = data; cmp_uri = talloc_array(mem_ctx, char, value.dsize + 1); memcpy(cmp_uri, value.dptr, value.dsize); *(cmp_uri + value.dsize) = 0; slash_ptr = cmp_uri + value.dsize - 1; if (*slash_ptr == '/') { *slash_ptr = 0; } if (!strncmp(cmp_uri, tdb_data->startswith, strlen(tdb_data->startswith)) && !strncmp(cmp_uri + (strlen(cmp_uri) - strlen(tdb_data->endswith)), tdb_data->endswith, strlen(tdb_data->endswith))) { key_str = talloc_strndup(mem_ctx, (char *) key.dptr, key.dsize); tdb_data->fmid = strtoull(key_str, NULL, 16); tdb_data->found = true; ret = 1; } talloc_free(mem_ctx); return ret; } _PUBLIC_ enum mapistore_error mapistore_indexing_record_get_fmid(struct mapistore_context *mstore_ctx, const char *username, const char *uri, bool partial, uint64_t *fmidp, bool *soft_deletedp) { struct indexing_context_list *ictx; int ret; struct tdb_get_fid_data tdb_data; char *slash_ptr; uint32_t i; /* SANITY checks */ MAPISTORE_RETVAL_IF(!mstore_ctx, MAPISTORE_ERR_NOT_INITIALIZED, NULL); MAPISTORE_RETVAL_IF(!username, MAPISTORE_ERR_NOT_INITIALIZED, NULL); MAPISTORE_RETVAL_IF(!fmidp, MAPISTORE_ERR_NOT_INITIALIZED, NULL); MAPISTORE_RETVAL_IF(!soft_deletedp, MAPISTORE_ERR_NOT_INITIALIZED, NULL); /* Check if the fmid exists within the database */ ret = mapistore_indexing_add(mstore_ctx, username, &ictx); MAPISTORE_RETVAL_IF(ret, MAPISTORE_ERROR, NULL); MAPISTORE_RETVAL_IF(!ictx, MAPISTORE_ERROR, NULL); tdb_data.found = false; tdb_data.uri = talloc_strdup(NULL, uri); tdb_data.uri_len = strlen(uri); tdb_data.startswith = NULL; tdb_data.endswith = NULL; tdb_data.wildcard_count = 0; slash_ptr = tdb_data.uri + tdb_data.uri_len - 1; if (*slash_ptr == '/') { *slash_ptr = 0; tdb_data.uri_len--; } if (partial == false) { tdb_traverse_read(ictx->index_ctx->tdb, tdb_get_fid_traverse, &tdb_data); } else { for (tdb_data.wildcard_count = 0, i = 0; i < strlen(uri); i++) { if (uri[i] == '*') tdb_data.wildcard_count += 1; } switch (tdb_data.wildcard_count) { case 0: /* complete URI */ partial = true; break; case 1: /* start and end only */ tdb_data.endswith = strchr(uri, '*') + 1; tdb_data.startswith = talloc_strndup(NULL, uri, strlen(uri) - strlen(tdb_data.endswith) - 1); break; default: DEBUG(0, ("[%s:%d]: Too many wildcards found (1 maximum)\n", __FUNCTION__, __LINE__)); talloc_free(tdb_data.uri); return MAPISTORE_ERR_NOT_FOUND; } if (partial == true) { tdb_traverse_read(ictx->index_ctx->tdb, tdb_get_fid_traverse_partial, &tdb_data); talloc_free(tdb_data.startswith); } else { tdb_traverse_read(ictx->index_ctx->tdb, tdb_get_fid_traverse, &tdb_data); } } talloc_free(tdb_data.uri); if (tdb_data.found) { *fmidp = tdb_data.fmid; *soft_deletedp = false; /* TODO: implement the feature */ ret = MAPISTORE_SUCCESS; } else { ret = MAPISTORE_ERR_NOT_FOUND; } return ret; } /** \details Add a fid record to the indexing database \param mstore_ctx pointer to the mapistore context \param context_id the context identifier referencing the indexing database to update \param fid the fid to add \note This is a wrapper to the internal common mapistore_indexing_record_add_fmid function. \return MAPISTORE_SUCCESS on success, otherwise MAPISTORE error */ _PUBLIC_ enum mapistore_error mapistore_indexing_record_add_fid(struct mapistore_context *mstore_ctx, uint32_t context_id, const char *username, uint64_t fid) { return mapistore_indexing_record_add_fmid(mstore_ctx, context_id, username, fid); } /** \details Delete a fid record from the indexing database \param mstore_ctx pointer to the mapistore context \param context_id the context identifier referencing the indexing database to update \param fid the fid to remove \param flags the type of deletion MAPISTORE_SOFT_DELETE or MAPISTORE_PERMANENT_DELETE \return MAPISTORE_SUCCESS on success, otherwise MAPISTORE error */ _PUBLIC_ enum mapistore_error mapistore_indexing_record_del_fid(struct mapistore_context *mstore_ctx, uint32_t context_id, const char *username, uint64_t fid, uint8_t flags) { return mapistore_indexing_record_del_fmid(mstore_ctx, context_id, username, fid, flags); } /** \details Add a mid record to the indexing database \param mstore_ctx pointer to the mapistore context \param context_id the context identifier referencing the indexing database to update \param mid the mid to add \note This is a wrapper to the internal common mapistore_indexing_record_add_fmid function. \return MAPISTORE_SUCCESS on success, otherwise MAPISTORE error */ _PUBLIC_ enum mapistore_error mapistore_indexing_record_add_mid(struct mapistore_context *mstore_ctx, uint32_t context_id, const char *username, uint64_t mid) { return mapistore_indexing_record_add_fmid(mstore_ctx, context_id, username, mid); } /** \details Delete a mid record from the indexing database \param mstore_ctx pointer to the mapistore context \param context_id the context identifier referencing the indexing database to update \param mid the mid to remove \param flags the type of deletion MAPISTORE_SOFT_DELETE or MAPISTORE_PERMANENT_DELETE \return MAPISTORE_SUCCESS on success, otherwise MAPISTORE error */ _PUBLIC_ enum mapistore_error mapistore_indexing_record_del_mid(struct mapistore_context *mstore_ctx, uint32_t context_id, const char *username, uint64_t mid, uint8_t flags) { return mapistore_indexing_record_del_fmid(mstore_ctx, context_id, username, mid, flags); } openchange-2.0/mapiproxy/libmapistore/mapistore_interface.c000066400000000000000000001725421223057412600244100ustar00rootroot00000000000000/* OpenChange Storage Abstraction Layer library OpenChange Project Copyright (C) Julien Kerihuel 2009 This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see . */ #include #include #include #include "mapistore.h" #include "mapistore_errors.h" #include "mapistore_private.h" #include "mapistore_nameid.h" #include #include "libmapi/libmapi_private.h" #include /** \details Initialize the mapistore context \param mem_ctx pointer to the memory context \param path the path to the location to load the backend providers from (NULL for default) \return allocate mapistore context on success, otherwise NULL */ _PUBLIC_ struct mapistore_context *mapistore_init(TALLOC_CTX *mem_ctx, struct loadparm_context *lp_ctx, const char *path) { int retval; struct mapistore_context *mstore_ctx; const char *private_dir; char *mapping_path; if (!lp_ctx) { return NULL; } mstore_ctx = talloc_zero(mem_ctx, struct mapistore_context); if (!mstore_ctx) { return NULL; } mstore_ctx->processing_ctx = talloc_zero(mstore_ctx, struct processing_context); private_dir = lpcfg_private_dir(lp_ctx); if (!private_dir) { DEBUG(5, ("private directory was not returned from configuration\n")); return NULL; } mapping_path = talloc_asprintf(NULL, "%s/mapistore", private_dir); mkdir(mapping_path, 0700); mapistore_set_mapping_path(mapping_path); talloc_free(mapping_path); retval = mapistore_init_mapping_context(mstore_ctx->processing_ctx); if (retval != MAPISTORE_SUCCESS) { DEBUG(0, ("[%s:%d]: %s\n", __FUNCTION__, __LINE__, mapistore_errstr(retval))); talloc_free(mstore_ctx); return NULL; } retval = mapistore_backend_init(mstore_ctx, path); if (retval != MAPISTORE_SUCCESS) { DEBUG(0, ("[%s:%d]: %s\n", __FUNCTION__, __LINE__, mapistore_errstr(retval))); talloc_free(mstore_ctx); return NULL; } mstore_ctx->context_list = NULL; mstore_ctx->indexing_list = talloc_zero(mstore_ctx, struct indexing_context_list); mstore_ctx->replica_mapping_list = talloc_zero(mstore_ctx, struct replica_mapping_context_list); mstore_ctx->notifications = NULL; mstore_ctx->subscriptions = NULL; mstore_ctx->conn_info = NULL; mstore_ctx->nprops_ctx = NULL; retval = mapistore_namedprops_init(mstore_ctx, &(mstore_ctx->nprops_ctx)); if (retval != MAPISTORE_SUCCESS) { DEBUG(0, ("[%s:%d]: %s\n", __FUNCTION__, __LINE__, mapistore_errstr(retval))); talloc_free(mstore_ctx); return NULL; } #if 0 mstore_ctx->mq_ipc = mq_open(MAPISTORE_MQUEUE_IPC, O_WRONLY|O_NONBLOCK|O_CREAT, 0755, NULL); if (mstore_ctx->mq_ipc == -1) { DEBUG(0, ("[%s:%d]: Failed to open mqueue for %s\n", __FUNCTION__, __LINE__, MAPISTORE_MQUEUE_IPC)); talloc_free(mstore_ctx); return NULL; } #endif return mstore_ctx; } /** \details Release the mapistore context and destroy any data associated \param mstore_ctx pointer to the mapistore context \note The function needs to rely on talloc destructors which is not implemented in code yet. \return MAPISTORE_SUCCESS on success, otherwise MAPISTORE error */ _PUBLIC_ enum mapistore_error mapistore_release(struct mapistore_context *mstore_ctx) { /* Sanity checks */ MAPISTORE_RETVAL_IF(!mstore_ctx, MAPISTORE_ERR_NOT_INITIALIZED, NULL); DEBUG(5, ("freeing up mstore_ctx ref: %p\n", mstore_ctx)); talloc_free(mstore_ctx->nprops_ctx); talloc_free(mstore_ctx->processing_ctx); talloc_free(mstore_ctx->context_list); return MAPISTORE_SUCCESS; } /** \details Set connection info for current mapistore context \param mstore_ctx pointer to the mapistore context \param oc_ctx pointer to the openchange ldb database \param username pointer to the current username \return MAPISTORE_SUCCESS on success, otherwise MAPISTORE error */ _PUBLIC_ enum mapistore_error mapistore_set_connection_info(struct mapistore_context *mstore_ctx, struct ldb_context *sam_ctx, struct ldb_context *oc_ctx, const char *username) { /* Sanity checks */ MAPISTORE_RETVAL_IF(!mstore_ctx, MAPISTORE_ERR_NOT_INITIALIZED, NULL); MAPISTORE_RETVAL_IF(!sam_ctx, MAPISTORE_ERR_INVALID_PARAMETER, NULL); MAPISTORE_RETVAL_IF(!oc_ctx, MAPISTORE_ERR_INVALID_PARAMETER, NULL); MAPISTORE_RETVAL_IF(!username, MAPISTORE_ERR_INVALID_PARAMETER, NULL); mstore_ctx->conn_info = talloc_zero(mstore_ctx, struct mapistore_connection_info); mstore_ctx->conn_info->mstore_ctx = mstore_ctx; mstore_ctx->conn_info->sam_ctx = sam_ctx; mstore_ctx->conn_info->oc_ctx = oc_ctx; (void) talloc_reference(mstore_ctx->conn_info, mstore_ctx->conn_info->oc_ctx); mstore_ctx->conn_info->username = talloc_strdup(mstore_ctx->conn_info, username); return MAPISTORE_SUCCESS; } /* TODO: the "owner" parameter should be deduced from the uri */ /** \details Add a new connection context to mapistore \param mstore_ctx pointer to the mapistore context \param uri the connection context URI \param context_id pointer to the context identifier the function returns \return MAPISTORE_SUCCESS on success, otherwise MAPISTORE error */ _PUBLIC_ enum mapistore_error mapistore_add_context(struct mapistore_context *mstore_ctx, const char *owner, const char *uri, uint64_t fid, uint32_t *context_id, void **backend_object) { TALLOC_CTX *mem_ctx; int retval; struct backend_context *backend_ctx; struct backend_context_list *backend_list; char *namespace; char *namespace_start; char *backend_uri; char *mapistore_dir; struct indexing_context_list *ictx; /* Step 1. Perform Sanity Checks on URI */ if (!uri || strlen(uri) < 4) { return MAPISTORE_ERR_INVALID_NAMESPACE; } mem_ctx = talloc_named(NULL, 0, "mapistore_add_context"); namespace = talloc_strdup(mem_ctx, uri); namespace_start = namespace; namespace = strchr(namespace, ':'); if (!namespace) { DEBUG(0, ("[%s:%d]: Error - Invalid namespace '%s'\n", __FUNCTION__, __LINE__, namespace_start)); talloc_free(mem_ctx); return MAPISTORE_ERR_INVALID_NAMESPACE; } if (namespace[1] && namespace[1] == '/' && namespace[2] && namespace[2] == '/' && namespace[3]) { /* ensure the user mapistore directory exists before any mapistore operation occurs */ mapistore_dir = talloc_asprintf(mem_ctx, "%s/%s", mapistore_get_mapping_path(), owner); mkdir(mapistore_dir, 0700); mapistore_indexing_add(mstore_ctx, owner, &ictx); /* mapistore_indexing_add_ref_count(ictx); */ backend_uri = talloc_strdup(mem_ctx, &namespace[3]); namespace[3] = '\0'; retval = mapistore_backend_create_context(mstore_ctx, mstore_ctx->conn_info, ictx->index_ctx, namespace_start, backend_uri, fid, &backend_ctx); if (retval != MAPISTORE_SUCCESS) { return retval; } backend_ctx->indexing = ictx; backend_list = talloc_zero((TALLOC_CTX *) mstore_ctx, struct backend_context_list); backend_list->ctx = backend_ctx; retval = mapistore_get_context_id(mstore_ctx->processing_ctx, &backend_list->ctx->context_id); if (retval != MAPISTORE_SUCCESS) { talloc_free(mem_ctx); return MAPISTORE_ERR_CONTEXT_FAILED; } *context_id = backend_list->ctx->context_id; *backend_object = backend_list->ctx->root_folder_object; DLIST_ADD_END(mstore_ctx->context_list, backend_list, struct backend_context_list *); } else { DEBUG(0, ("[%s:%d]: Error - Invalid URI '%s'\n", __FUNCTION__, __LINE__, uri)); talloc_free(mem_ctx); return MAPISTORE_ERR_INVALID_NAMESPACE; } talloc_free(mem_ctx); return MAPISTORE_SUCCESS; } /** \details Increase the reference counter of an existing context \param mstore_ctx pointer to the mapistore context \param contex_id the context identifier referencing the context to update \return MAPISTORE_SUCCESS on success, otherwise MAPISTORE error */ _PUBLIC_ enum mapistore_error mapistore_add_context_ref_count(struct mapistore_context *mstore_ctx, uint32_t context_id) { struct backend_context *backend_ctx; int retval; /* Sanity checks */ MAPISTORE_SANITY_CHECKS(mstore_ctx, NULL); if (context_id == -1) return MAPISTORE_ERROR; /* Step 0. Ensure the context exists */ DEBUG(0, ("mapistore_add_context_ref_count: context_is to increment is %d\n", context_id)); backend_ctx = mapistore_backend_lookup(mstore_ctx->context_list, context_id); MAPISTORE_RETVAL_IF(!backend_ctx, MAPISTORE_ERR_INVALID_PARAMETER, NULL); /* Step 1. Increment the ref count */ retval = mapistore_backend_add_ref_count(backend_ctx); /* Step 2. Increment backend indexing ref count */ if (backend_ctx->indexing) { /* mapistore_indexing_add_ref_count(backend_ctx->indexing); */ } else { DEBUG(0, ("[%s:%d]: This should never occur\n", __FUNCTION__, __LINE__)); abort(); } return retval; } /** \details Search for an existing context given its uri \param mstore_ctx pointer to the mapistore context \param uri the URI to lookup \param context_id pointer to the context identifier to return \return MAPISTORE_SUCCESS on success, otherwise MAPISTORE error */ _PUBLIC_ enum mapistore_error mapistore_search_context_by_uri(struct mapistore_context *mstore_ctx, const char *uri, uint32_t *context_id, void **backend_object) { struct backend_context *backend_ctx; /* Sanity checks */ MAPISTORE_SANITY_CHECKS(mstore_ctx, NULL); if (!uri) return MAPISTORE_ERROR; backend_ctx = mapistore_backend_lookup_by_uri(mstore_ctx->context_list, uri); MAPISTORE_RETVAL_IF(!backend_ctx, MAPISTORE_ERR_NOT_FOUND, NULL); *context_id = backend_ctx->context_id; *backend_object = backend_ctx->root_folder_object; return MAPISTORE_SUCCESS; } /** \details Delete an existing connection context from mapistore \param mstore_ctx pointer to the mapistore context \param context_id the context identifier referencing the context to delete \return MAPISTORE_SUCCESS on success, otherwise MAPISTORE error */ _PUBLIC_ enum mapistore_error mapistore_del_context(struct mapistore_context *mstore_ctx, uint32_t context_id) { struct backend_context_list *backend_list; struct backend_context *backend_ctx; int retval; bool found = false; /* Sanity checks */ MAPISTORE_SANITY_CHECKS(mstore_ctx, NULL); if (context_id == -1) return MAPISTORE_ERROR; /* Step 0. Ensure the context exists */ DEBUG(0, ("mapistore_del_context: context_id to del is %d\n", context_id)); backend_ctx = mapistore_backend_lookup(mstore_ctx->context_list, context_id); MAPISTORE_RETVAL_IF(!backend_ctx, MAPISTORE_ERR_INVALID_PARAMETER, NULL); /* search the backend_list item */ for (backend_list = mstore_ctx->context_list; backend_list; backend_list = backend_list->next) { if (backend_list->ctx->context_id == context_id) { found = true; break; } } if (found == false) { return MAPISTORE_ERROR; } /* Step 1. Release the indexing context within backend */ /* if (backend_ctx->indexing) { mapistore_indexing_del_ref_count(backend_ctx->indexing); if (backend_ctx->indexing->ref_count == 0) { DEBUG(5, ("freeing up mapistore_indexing ctx: %p\n", backend_ctx->indexing)); DLIST_REMOVE(mstore_ctx->indexing_list, backend_ctx->indexing); talloc_unlink(mstore_ctx->indexing_list, backend_ctx->indexing); backend_ctx->indexing = NULL; } } */ /* Step 2. Delete the context within backend */ retval = mapistore_backend_delete_context(backend_ctx); switch (retval) { case MAPISTORE_ERR_REF_COUNT: return MAPISTORE_SUCCESS; case MAPISTORE_SUCCESS: DLIST_REMOVE(mstore_ctx->context_list, backend_list); /* Step 2. Add the free'd context id to the free list */ retval = mapistore_free_context_id(mstore_ctx->processing_ctx, context_id); break; default: return retval; } return retval; } void mapistore_set_errno(int status) { errno = status; } /** \details return a string explaining what a mapistore error constant means. \param mapistore_err the mapistore error constant \return constant string */ _PUBLIC_ const char *mapistore_errstr(enum mapistore_error mapistore_err) { switch (mapistore_err) { case MAPISTORE_SUCCESS: return "Success"; case MAPISTORE_ERROR: return "Non-specific error"; case MAPISTORE_ERR_NO_MEMORY: return "No memory available"; case MAPISTORE_ERR_ALREADY_INITIALIZED: return "Already initialized"; case MAPISTORE_ERR_NOT_INITIALIZED: return "Not initialized"; case MAPISTORE_ERR_CORRUPTED: return "Corrupted"; case MAPISTORE_ERR_INVALID_PARAMETER: return "Invalid Parameter"; case MAPISTORE_ERR_NO_DIRECTORY: return "No such file or directory"; case MAPISTORE_ERR_DATABASE_INIT: return "Database initialization failed"; case MAPISTORE_ERR_DATABASE_OPS: return "Database operation failed"; case MAPISTORE_ERR_BACKEND_REGISTER: return "Storage backend registration failed"; case MAPISTORE_ERR_BACKEND_INIT: return "Storage backend initialization failed"; case MAPISTORE_ERR_CONTEXT_FAILED: return "Failed creating the context"; case MAPISTORE_ERR_INVALID_NAMESPACE: return "Invalid Namespace"; case MAPISTORE_ERR_NOT_FOUND: return "Not Found"; case MAPISTORE_ERR_REF_COUNT: return "Reference counter not NULL"; case MAPISTORE_ERR_EXIST: return "Already Exists"; case MAPISTORE_ERR_INVALID_DATA: return "Invalid Data"; case MAPISTORE_ERR_MSG_SEND: return "Error while sending message"; case MAPISTORE_ERR_MSG_RCV: return "Error receiving message"; case MAPISTORE_ERR_DENIED: return "Insufficient rights to perform the operation"; case MAPISTORE_ERR_NOT_IMPLEMENTED: return "Not implemented"; } return "Unknown error"; } _PUBLIC_ enum mapistore_error mapistore_list_contexts_for_user(struct mapistore_context *mstore_ctx, const char *owner, TALLOC_CTX *mem_ctx, struct mapistore_contexts_list **contexts_listp) { char *mapistore_dir; struct indexing_context_list *ictx; /* ensure the user mapistore directory exists before any mapistore operation occurs */ mapistore_dir = talloc_asprintf(mem_ctx, "%s/%s", mapistore_get_mapping_path(), owner); mkdir(mapistore_dir, 0700); mapistore_indexing_add(mstore_ctx, owner, &ictx); /* mapistore_indexing_add_ref_count(ictx); */ return mapistore_backend_list_contexts(owner, ictx->index_ctx, mem_ctx, contexts_listp); } _PUBLIC_ enum mapistore_error mapistore_create_root_folder(const char *username, enum mapistore_context_role ctx_role, uint64_t fid, const char *name, TALLOC_CTX *mem_ctx, char **mapistore_urip) { /* Sanity checks */ MAPISTORE_RETVAL_IF(!username, MAPISTORE_ERR_INVALID_PARAMETER, NULL); MAPISTORE_RETVAL_IF(!mapistore_urip, MAPISTORE_ERR_INVALID_PARAMETER, NULL); return mapistore_backend_create_root_folder(username, ctx_role, fid, name, mem_ctx, mapistore_urip); } /** \details Open a directory in mapistore \param mstore_ctx pointer to the mapistore context \param context_id the context identifier referencing the backend where the directory will be opened \param parent_fid the parent folder identifier \param fid folder identifier to open \return MAPISTORE_SUCCESS on success, otherwise MAPISTORE errors */ _PUBLIC_ enum mapistore_error mapistore_folder_open_folder(struct mapistore_context *mstore_ctx, uint32_t context_id, void *folder, TALLOC_CTX *mem_ctx, uint64_t fid, void **child_folder) { struct backend_context *backend_ctx; /* Sanity checks */ MAPISTORE_SANITY_CHECKS(mstore_ctx, NULL); /* Step 1. Search the context */ backend_ctx = mapistore_backend_lookup(mstore_ctx->context_list, context_id); MAPISTORE_RETVAL_IF(!backend_ctx, MAPISTORE_ERR_INVALID_PARAMETER, NULL); /* Step 2. Call backend open_folder */ return mapistore_backend_folder_open_folder(backend_ctx, folder, mem_ctx, fid, child_folder); } /** \details Create a directory in mapistore \param mstore_ctx pointer to the mapistore context \param context_id the context identifier referencing the backend where the directory will be created \param parent_fid the parent folder identifier \param new_fid the folder identifier for the new folder \param aRow pointer to MAPI data structures with properties to be added to the new folder \return MAPISTORE_SUCCESS on success, otherwise MAPISTORE errors */ _PUBLIC_ enum mapistore_error mapistore_folder_create_folder(struct mapistore_context *mstore_ctx, uint32_t context_id, void *folder, TALLOC_CTX *mem_ctx, uint64_t fid, struct SRow *aRow, void **child_folder) { struct backend_context *backend_ctx; /* Sanity checks */ MAPISTORE_SANITY_CHECKS(mstore_ctx, NULL); /* Step 1. Search the context */ backend_ctx = mapistore_backend_lookup(mstore_ctx->context_list, context_id); MAPISTORE_RETVAL_IF(!backend_ctx, MAPISTORE_ERR_INVALID_PARAMETER, NULL); /* Step 2. Call backend create_folder */ return mapistore_backend_folder_create_folder(backend_ctx, folder, mem_ctx, fid, aRow, child_folder); } /** \details Remove a directory in mapistore \param mstore_ctx pointer to the mapistore context \param context_id the context identifier referencing the backend \param parent_fid the parent folder identifier \param fid the folder identifier representing the folder to delete \param flags flags that control the behaviour of the operation \return MAPISTORE_SUCCESS on success, otherwise MAPISTORE errors */ _PUBLIC_ enum mapistore_error mapistore_folder_delete(struct mapistore_context *mstore_ctx, uint32_t context_id, void *folder, uint8_t flags) { struct backend_context *backend_ctx; enum mapistore_error ret; TALLOC_CTX *mem_ctx; void *subfolder; uint64_t *child_fmids; uint32_t i, child_count; /* TODO : handle the removal of entries in indexing.tdb */ /* Sanity checks */ MAPISTORE_SANITY_CHECKS(mstore_ctx, NULL); mem_ctx = talloc_zero(NULL, TALLOC_CTX); /* Step 1. Find the backend context */ backend_ctx = mapistore_backend_lookup(mstore_ctx->context_list, context_id); if (!backend_ctx) { ret = MAPISTORE_ERR_INVALID_PARAMETER; goto end; } /* Step 2a. Handle deletion of normal messages */ ret = mapistore_folder_get_child_fmids(mstore_ctx, context_id, folder, MAPISTORE_MESSAGE_TABLE, mem_ctx, &child_fmids, &child_count); if (ret != MAPISTORE_SUCCESS) { goto end; } if (child_count > 0) { if ((flags & DEL_MESSAGES)) { for (i = 0; i < child_count; i++) { ret = mapistore_backend_folder_delete_message(backend_ctx, folder, child_fmids[i], 0); if (ret != MAPISTORE_SUCCESS) { goto end; } } } else { ret = MAPISTORE_ERR_EXIST; goto end; } } /* Step 2b. Handle deletion of FAI messages */ ret = mapistore_folder_get_child_fmids(mstore_ctx, context_id, folder, MAPISTORE_FAI_TABLE, mem_ctx, &child_fmids, &child_count); if (ret != MAPISTORE_SUCCESS) { goto end; } if (child_count > 0) { if ((flags & DEL_MESSAGES)) { for (i = 0; i < child_count; i++) { ret = mapistore_backend_folder_delete_message(backend_ctx, folder, child_fmids[i], 0); if (ret != MAPISTORE_SUCCESS) { goto end; } } } else { ret = MAPISTORE_ERR_EXIST; goto end; } } /* Step 3. Handle deletion of child folders */ ret = mapistore_folder_get_child_fmids(mstore_ctx, context_id, folder, MAPISTORE_FOLDER_TABLE, mem_ctx, &child_fmids, &child_count); if (ret != MAPISTORE_SUCCESS) { goto end; } if (child_count > 0) { if ((flags & DEL_FOLDERS)) { for (i = 0; i < child_count; i++) { ret = mapistore_backend_folder_open_folder(backend_ctx, folder, mem_ctx, child_fmids[i], &subfolder); if (ret != MAPISTORE_SUCCESS) { goto end; } ret = mapistore_backend_folder_delete(backend_ctx, subfolder); if (ret != MAPISTORE_SUCCESS) { goto end; } } } else { ret = MAPISTORE_ERR_EXIST; goto end; } } /* Step 3. Call backend delete_folder */ ret = mapistore_backend_folder_delete(backend_ctx, folder); end: talloc_free(mem_ctx); return ret; } /** \details Open a message in mapistore \param mstore_ctx pointer to the mapistore context \param context_id the context identifier referencing the backend where the directory will be opened \param parent_fid the parent folder identifier \param mid the message identifier to open \param pointer to the mapistore_message structure \return MAPISTORE SUCCESS on success, otherwise MAPISTORE errors */ _PUBLIC_ enum mapistore_error mapistore_folder_open_message(struct mapistore_context *mstore_ctx, uint32_t context_id, void *folder, TALLOC_CTX *mem_ctx, uint64_t mid, bool read_write, void **messagep) { struct backend_context *backend_ctx; /* Sanity checks */ MAPISTORE_SANITY_CHECKS(mstore_ctx, NULL); /* Step 1. Search the context */ backend_ctx = mapistore_backend_lookup(mstore_ctx->context_list, context_id); MAPISTORE_RETVAL_IF(!backend_ctx, MAPISTORE_ERR_INVALID_PARAMETER, NULL); /* Step 2. Call backend open_message */ return mapistore_backend_folder_open_message(backend_ctx, folder, mem_ctx, mid, read_write, messagep); } /** \details Create a message in mapistore \param mstore_ctx pointer to the mapistore context \param context_id the context identifier referencing the backend where the messagewill be created \param parent_fid the parent folder identifier \param mid the message identifier to create \return MAPISTORE_SUCCESS on success, otherwise MAPISTORE errors */ _PUBLIC_ enum mapistore_error mapistore_folder_create_message(struct mapistore_context *mstore_ctx, uint32_t context_id, void *folder, TALLOC_CTX *mem_ctx, uint64_t mid, uint8_t associated, void **messagep) { struct backend_context *backend_ctx; /* Sanity checks */ MAPISTORE_SANITY_CHECKS(mstore_ctx, NULL); /* Step 1. Search the context */ backend_ctx = mapistore_backend_lookup(mstore_ctx->context_list, context_id); MAPISTORE_RETVAL_IF(!backend_ctx, MAPISTORE_ERR_INVALID_PARAMETER, NULL); /* Step 2. Call backend create_message */ return mapistore_backend_folder_create_message(backend_ctx, folder, mem_ctx, mid, associated, messagep); } /** \details Delete a message from mapistore \param mstore_ctx pointer to the mapistore context \param context_id the context identifier referencing the backend where the message's to be located is stored \param mid the message identifier of the folder to delete \param flags flags that control the behaviour of the operation (MAPISTORE_SOFT_DELETE or MAPISTORE_PERMANENT_DELETE) \return MAPISTORE_SUCCESS on success, otherwise MAPISTORE errors */ _PUBLIC_ enum mapistore_error mapistore_folder_delete_message(struct mapistore_context *mstore_ctx, uint32_t context_id, void *folder, uint64_t mid, uint8_t flags) { struct backend_context *backend_ctx; /* Sanity checks */ MAPISTORE_SANITY_CHECKS(mstore_ctx, NULL); /* Step 1. Search the context */ backend_ctx = mapistore_backend_lookup(mstore_ctx->context_list, context_id); MAPISTORE_RETVAL_IF(!backend_ctx, MAPISTORE_ERR_INVALID_PARAMETER, NULL); /* Step 2. Call backend operation */ return mapistore_backend_folder_delete_message(backend_ctx, folder, mid, flags); } /** */ _PUBLIC_ enum mapistore_error mapistore_folder_move_copy_messages(struct mapistore_context *mstore_ctx, uint32_t context_id, void *target_folder, void *source_folder, TALLOC_CTX *mem_ctx, uint32_t mid_count, uint64_t *source_mids, uint64_t *target_mids, struct Binary_r **target_change_keys, uint8_t want_copy) { struct backend_context *backend_ctx; /* Sanity checks */ MAPISTORE_SANITY_CHECKS(mstore_ctx, NULL); /* Step 1. Search the context */ backend_ctx = mapistore_backend_lookup(mstore_ctx->context_list, context_id); MAPISTORE_RETVAL_IF(!backend_ctx, MAPISTORE_ERR_INVALID_PARAMETER, NULL); /* Step 2. Call backend operation */ return mapistore_backend_folder_move_copy_messages(backend_ctx, target_folder, source_folder, mem_ctx, mid_count, source_mids, target_mids, target_change_keys, want_copy); } /** */ _PUBLIC_ enum mapistore_error mapistore_folder_move_folder(struct mapistore_context *mstore_ctx, uint32_t context_id, void *move_folder, void *target_folder, TALLOC_CTX *mem_ctx, const char *new_folder_name) { struct backend_context *backend_ctx; /* Sanity checks */ MAPISTORE_SANITY_CHECKS(mstore_ctx, NULL); /* Step 1. Search the context */ backend_ctx = mapistore_backend_lookup(mstore_ctx->context_list, context_id); MAPISTORE_RETVAL_IF(!backend_ctx, MAPISTORE_ERR_INVALID_PARAMETER, NULL); /* Step 2. Call backend operation */ return mapistore_backend_folder_move_folder(backend_ctx, move_folder, target_folder, mem_ctx, new_folder_name); } /** */ _PUBLIC_ enum mapistore_error mapistore_folder_copy_folder(struct mapistore_context *mstore_ctx, uint32_t context_id, void *move_folder, void *target_folder, TALLOC_CTX *mem_ctx, bool recursive, const char *new_folder_name) { struct backend_context *backend_ctx; /* Sanity checks */ MAPISTORE_SANITY_CHECKS(mstore_ctx, NULL); /* Step 1. Search the context */ backend_ctx = mapistore_backend_lookup(mstore_ctx->context_list, context_id); MAPISTORE_RETVAL_IF(!backend_ctx, MAPISTORE_ERR_INVALID_PARAMETER, NULL); /* Step 2. Call backend operation */ return mapistore_backend_folder_copy_folder(backend_ctx, move_folder, target_folder, mem_ctx, recursive, new_folder_name); } /** \details Get the array of deleted items following a specific change number \param mstore_ctx pointer to the mapistore context \param context_id the context identifier referencing the backend where the message's to be located is stored \param folder the folder backend object \param mem_ctx the TALLOC_CTX that should be used as parent for the returned array \param table_type the type of object that we want to take into account \param change_num the reference change number \param fmidsp a pointer to the returned array \return MAPISTORE_SUCCESS on success, otherwise MAPISTORE errors */ _PUBLIC_ enum mapistore_error mapistore_folder_get_deleted_fmids(struct mapistore_context *mstore_ctx, uint32_t context_id, void *folder, TALLOC_CTX *mem_ctx, enum mapistore_table_type table_type, uint64_t change_num, struct UI8Array_r **fmidsp, uint64_t *cnp) { struct backend_context *backend_ctx; /* Sanity checks */ MAPISTORE_SANITY_CHECKS(mstore_ctx, NULL); /* Step 1. Search the context */ backend_ctx = mapistore_backend_lookup(mstore_ctx->context_list, context_id); MAPISTORE_RETVAL_IF(!backend_ctx, MAPISTORE_ERR_INVALID_PARAMETER, NULL); /* Step 2. Call backend operation */ return mapistore_backend_folder_get_deleted_fmids(backend_ctx, folder, mem_ctx, table_type, change_num, fmidsp, cnp); } /** \details Retrieve the number of child messages within a mapistore folder \param mstore_ctx pointer to the mapistore context \param context_id the context identifier referencing the backend \param fid the folder identifier \param RowCount pointer to the count result to return \return MAPISTORE_SUCCESS on success, otherwise MAPISTORE errors */ _PUBLIC_ enum mapistore_error mapistore_folder_get_child_count(struct mapistore_context *mstore_ctx, uint32_t context_id, void *folder, enum mapistore_table_type table_type, uint32_t *RowCount) { struct backend_context *backend_ctx; /* Sanity checks */ MAPISTORE_SANITY_CHECKS(mstore_ctx, NULL); /* Step 0. Ensure the context exists */ backend_ctx = mapistore_backend_lookup(mstore_ctx->context_list, context_id); MAPISTORE_RETVAL_IF(!backend_ctx, MAPISTORE_ERR_INVALID_PARAMETER, NULL); /* Step 2. Call backend get_child_count */ return mapistore_backend_folder_get_child_count(backend_ctx, folder, table_type, RowCount); } /** \details Retrieve the folder IDs of child folders within a mapistore folder \param mstore_ctx pointer to the mapistore context \param context_id the context identifier referencing the backend \param fid the folder identifier (for the parent folder) \param child_fids pointer to where to return the array of child fids \param child_fid_count pointer to the count result to return \note The caller is responsible for freeing the \p child_fids array when it is no longer required. \return MAPISTORE_SUCCESS on success, otherwise MAPISTORE errors */ _PUBLIC_ enum mapistore_error mapistore_folder_get_child_fmids(struct mapistore_context *mstore_ctx, uint32_t context_id, void *folder, enum mapistore_table_type table_type, TALLOC_CTX *mem_ctx, uint64_t *child_fmids[], uint32_t *child_fmid_count) { TALLOC_CTX *local_mem_ctx; enum mapistore_error ret; void *backend_table; uint32_t i, row_count; uint64_t *fmids, *current_fmid; enum MAPITAGS fmid_column; struct mapistore_property_data *row_data; switch (table_type) { case MAPISTORE_FOLDER_TABLE: fmid_column = PR_FID; break; case MAPISTORE_MESSAGE_TABLE: case MAPISTORE_FAI_TABLE: fmid_column = PR_MID; break; case MAPISTORE_RULE_TABLE: fmid_column = PR_RULE_ID; break; case MAPISTORE_ATTACHMENT_TABLE: fmid_column = PR_ATTACH_ID; break; case MAPISTORE_PERMISSIONS_TABLE: fmid_column = PR_MEMBER_ID; break; } local_mem_ctx = talloc_zero(NULL, TALLOC_CTX); ret = mapistore_folder_open_table(mstore_ctx, context_id, folder, local_mem_ctx, table_type, 0, &backend_table, &row_count); if (ret != MAPISTORE_SUCCESS) { goto end; } ret = mapistore_table_set_columns(mstore_ctx, context_id, backend_table, 1, &fmid_column); if (ret != MAPISTORE_SUCCESS) { goto end; } *child_fmid_count = row_count; fmids = talloc_array(mem_ctx, uint64_t, row_count); *child_fmids = fmids; current_fmid = fmids; for (i = 0; i < row_count; i++) { mapistore_table_get_row(mstore_ctx, context_id, backend_table, local_mem_ctx, MAPISTORE_PREFILTERED_QUERY, i, &row_data); *current_fmid = *(uint64_t *) row_data->data; current_fmid++; } end: talloc_free(local_mem_ctx); return ret; } _PUBLIC_ enum mapistore_error mapistore_folder_get_child_fid_by_name(struct mapistore_context *mstore_ctx, uint32_t context_id, void *folder, const char *name, uint64_t *fidp) { struct backend_context *backend_ctx; /* Sanity checks */ MAPISTORE_SANITY_CHECKS(mstore_ctx, NULL); /* Step 1. Search the context */ backend_ctx = mapistore_backend_lookup(mstore_ctx->context_list, context_id); MAPISTORE_RETVAL_IF(!backend_ctx, MAPISTORE_ERR_INVALID_PARAMETER, NULL); /* Step 2. Call backend operation */ return mapistore_backend_folder_get_child_fid_by_name(backend_ctx, folder, name, fidp); } _PUBLIC_ enum mapistore_error mapistore_folder_open_table(struct mapistore_context *mstore_ctx, uint32_t context_id, void *folder, TALLOC_CTX *mem_ctx, enum mapistore_table_type table_type, uint32_t handle_id, void **table, uint32_t *row_count) { struct backend_context *backend_ctx; /* Sanity checks */ MAPISTORE_SANITY_CHECKS(mstore_ctx, NULL); /* Step 1. Search the context */ backend_ctx = mapistore_backend_lookup(mstore_ctx->context_list, context_id); MAPISTORE_RETVAL_IF(!backend_ctx, MAPISTORE_ERR_INVALID_PARAMETER, NULL); /* Step 2. Call backend operation */ return mapistore_backend_folder_open_table(backend_ctx, folder, mem_ctx, table_type, handle_id, table, row_count); } _PUBLIC_ enum mapistore_error mapistore_folder_modify_permissions(struct mapistore_context *mstore_ctx, uint32_t context_id, void *folder, uint8_t flags, uint16_t pcount, struct PermissionData *permissions) { struct backend_context *backend_ctx; /* Sanity checks */ MAPISTORE_SANITY_CHECKS(mstore_ctx, NULL); /* Step 1. Search the context */ backend_ctx = mapistore_backend_lookup(mstore_ctx->context_list, context_id); MAPISTORE_RETVAL_IF(!backend_ctx, MAPISTORE_ERR_INVALID_PARAMETER, NULL); /* Step 2. Call backend operation */ return mapistore_backend_folder_modify_permissions(backend_ctx, folder, flags, pcount, permissions); } _PUBLIC_ enum mapistore_error mapistore_folder_preload_message_bodies(struct mapistore_context *mstore_ctx, uint32_t context_id, void *folder, enum mapistore_table_type table_type, const struct UI8Array_r *mids) { struct backend_context *backend_ctx; /* Sanity checks */ MAPISTORE_SANITY_CHECKS(mstore_ctx, NULL); /* Step 1. Search the context */ backend_ctx = mapistore_backend_lookup(mstore_ctx->context_list, context_id); MAPISTORE_RETVAL_IF(!backend_ctx, MAPISTORE_ERR_INVALID_PARAMETER, NULL); /* Step 2. Call backend operation */ return mapistore_backend_folder_preload_message_bodies(backend_ctx, folder, table_type, mids); } /* freebusy helper */ static int mapistore_days_in_month(int month, int year) { static int max_mdays[] = {31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31}; int dec_year, days; if (month == 1) { dec_year = year % 100; if ((dec_year == 0 && ((((year + 1900) / 100) % 4) == 0)) || (dec_year % 4) == 0) { days = 29; } else { days = max_mdays[month]; } } else { days = max_mdays[month]; } return days; } static int mapistore_mins_in_ymon(uint32_t ymon) { return mapistore_days_in_month((ymon & 0xf) - 1, ymon >> 4) * 24 * 60; } static inline void mapistore_freebusy_make_range(struct tm *start_time, struct tm *end_time) { time_t now; struct tm time_data; int mw_delta, month; /* (from OXOPFFB - 3.1.4.1.1) Start of range is 12:00 A.M. UTC on the first day of the month or the first day of the week, whichever occurs earlier at the time of publishing. End of range is calculated by adding the value of the PidTagFreeBusyCountMonths property ([MS-OXOCAL] section 2.2.12.1) to start of range. Since PidTagFreeBusyCountMonths is not supported yet, we use a count of 3 months */ now = time(NULL); time_data = *gmtime(&now); time_data.tm_hour = 0; time_data.tm_min = 0; time_data.tm_sec = 0; /* take the first day of the week OR the first day of the month */ month = time_data.tm_mon; if (time_data.tm_mday < 7) { mw_delta = (time_data.tm_wday + 1 - time_data.tm_mday); if (mw_delta > 0) { if (time_data.tm_mon > 0) { time_data.tm_mon--; } else { time_data.tm_mon = 11; time_data.tm_year--; } time_data.tm_mday = mapistore_days_in_month(time_data.tm_mon, time_data.tm_year) + 1 - mw_delta; } else { time_data.tm_mday = 1; } } else { mw_delta = 0; time_data.tm_mday = 1; } *start_time = time_data; time_data.tm_mon = month + 2; if (time_data.tm_mon > 11) { time_data.tm_year++; time_data.tm_mon -= 12; } time_data.tm_mday = mapistore_days_in_month(time_data.tm_mon, time_data.tm_year) + 1 - mw_delta; time_data.tm_hour = 23; time_data.tm_min = 59; time_data.tm_sec = 59; *end_time = time_data; } static void mapistore_freebusy_convert_filetime(struct FILETIME *ft_value, uint32_t *ymon, uint32_t *mins) { NTTIME nt_time; time_t u_time; struct tm *gm_time; nt_time = ((NTTIME) ft_value->dwHighDateTime << 32) | ft_value->dwLowDateTime; u_time = nt_time_to_unix(nt_time); gm_time = gmtime(&u_time); *ymon = ((gm_time->tm_year + 1900) << 4) | (gm_time->tm_mon + 1); *mins = gm_time->tm_min + (gm_time->tm_hour + ((gm_time->tm_mday - 1) * 24)) * 60; } static uint16_t mapistore_freebusy_find_month_range(uint32_t ymon, uint32_t *months_ranges, uint16_t nbr_months, bool *overflow) { uint16_t range; if (nbr_months > 0) { if (months_ranges[0] > ymon) { *overflow = true; return 0; } else { if (months_ranges[nbr_months - 1] < ymon) { *overflow = true; return (nbr_months - 1); } else { *overflow = false; for (range = 0; range < nbr_months; range++) { if (months_ranges[range] == ymon) { return range; } } } } } return (uint16_t) -1; } /* TODO: both following methods could be merged. This would certainly enhance performance by avoiding to wander through long arrays multiple times */ static void mapistore_freebusy_fill_fbarray(uint8_t **minutes_array, uint32_t *months_ranges, uint16_t nbr_months, struct FILETIME *start, struct FILETIME *end) { uint32_t i, max, start_ymon, start_mins, end_ymon, end_mins; uint16_t start_mr_idx, end_mr_idx; bool start_range_overflow, end_range_overflow; mapistore_freebusy_convert_filetime(start, &start_ymon, &start_mins); mapistore_freebusy_convert_filetime(end, &end_ymon, &end_mins); start_mr_idx = mapistore_freebusy_find_month_range(start_ymon, months_ranges, nbr_months, &start_range_overflow); if (start_range_overflow) { start_mins = 0; } end_mr_idx = mapistore_freebusy_find_month_range(end_ymon, months_ranges, nbr_months, &end_range_overflow); if (end_range_overflow) { end_mins = mapistore_mins_in_ymon(end_ymon); } /* head */ if (end_mr_idx > start_mr_idx) { /* end occurs after start range */ /* middle */ for (i = start_mr_idx + 1; i < end_mr_idx; i++) { memset(minutes_array[i], 1, mapistore_mins_in_ymon(months_ranges[i])); } /* tail */ memset(minutes_array[end_mr_idx], 1, end_mins); max = mapistore_mins_in_ymon(start_ymon); /* = max chunk for first range */ } else { /* end occurs on same range as start */ max = end_mins; } memset(minutes_array[start_mr_idx] + start_mins, 1, (max - start_mins)); } static const int max_mins_per_month = 31 * 24 * 60; static void mapistore_freebusy_compile_fbarray(TALLOC_CTX *mem_ctx, uint8_t *minutes_array, struct Binary_r *fb_bin) { int i; bool filled; struct ndr_push *ndr; TALLOC_CTX *local_mem_ctx; local_mem_ctx = talloc_zero(NULL, TALLOC_CTX); ndr = ndr_push_init_ctx(local_mem_ctx); filled = (minutes_array[0] != 0); if (filled) { ndr_push_uint16(ndr, NDR_SCALARS, 0); } for (i = 1; i < max_mins_per_month; i++) { if (filled && !minutes_array[i]) { ndr_push_uint16(ndr, NDR_SCALARS, (i - 1)); filled = false; } else if (!filled && minutes_array[i]) { ndr_push_uint16(ndr, NDR_SCALARS, i); filled = true; } } if (filled) { ndr_push_uint16(ndr, NDR_SCALARS, (max_mins_per_month - 1)); } fb_bin->cb = ndr->offset; fb_bin->lpb = ndr->data; (void) talloc_reference(mem_ctx, fb_bin->lpb); talloc_free(local_mem_ctx); } static void mapistore_freebusy_merge_subarray(uint8_t *minutes_array, uint8_t *included_array) { int i; for (i = 0; i < max_mins_per_month; i++) { if (included_array[i]) { minutes_array[i] = 1; } } } enum mapistore_error mapistore_folder_fetch_freebusy_properties(struct mapistore_context *mstore_ctx, uint32_t context_id, void *folder, struct tm *start_tm, struct tm *end_tm, TALLOC_CTX *mem_ctx, struct mapistore_freebusy_properties **fb_props_p) { enum mapistore_error ret; struct mapistore_freebusy_properties *fb_props; struct backend_context *backend_ctx; TALLOC_CTX *local_mem_ctx; void *table; uint32_t row_count; struct SPropTagArray *props; struct mapistore_property_data *row_data; struct mapi_SRestriction and_res; uint8_t state; struct tm local_start_tm, local_end_tm; time_t start_time, end_time; NTTIME nt_time; struct mapi_SRestriction_and time_restrictions[2]; int i, month, nbr_months; uint8_t **minutes_array, **free_array, **tentative_array, **busy_array, **oof_array; char *tz; /* Sanity checks */ MAPISTORE_SANITY_CHECKS(mstore_ctx, NULL); backend_ctx = mapistore_backend_lookup(mstore_ctx->context_list, context_id); MAPISTORE_RETVAL_IF(!backend_ctx, MAPISTORE_ERR_INVALID_PARAMETER, NULL); local_mem_ctx = talloc_zero(NULL, TALLOC_CTX); /* fetch events from this month for 3 months: start + enddate + fbstatus */ ret = mapistore_folder_open_table(mstore_ctx, context_id, folder, local_mem_ctx, MAPISTORE_MESSAGE_TABLE, 0, &table, &row_count); if (ret != MAPISTORE_SUCCESS) { goto end; } fb_props = talloc_zero(local_mem_ctx, struct mapistore_freebusy_properties); /* fetch freebusy range */ if (start_tm && end_tm) { local_start_tm = *start_tm; local_end_tm = *end_tm; } else { mapistore_freebusy_make_range(&local_start_tm, &local_end_tm); } unix_to_nt_time(&nt_time, time(NULL)); fb_props->timestamp.dwLowDateTime = (nt_time & 0xffffffff); fb_props->timestamp.dwHighDateTime = nt_time >> 32; tz = getenv("TZ"); setenv("TZ", "", 1); tzset(); start_time = mktime(&local_start_tm); end_time = mktime(&local_end_tm); if (tz) { setenv("TZ", tz, 1); } else { unsetenv("TZ"); } tzset(); /* setup restriction */ and_res.rt = RES_AND; and_res.res.resAnd.cRes = 2; and_res.res.resAnd.res = time_restrictions; time_restrictions[0].rt = RES_PROPERTY; time_restrictions[0].res.resProperty.relop = RELOP_GE; time_restrictions[0].res.resProperty.ulPropTag = PidLidAppointmentEndWhole; time_restrictions[0].res.resProperty.lpProp.ulPropTag = PidLidAppointmentEndWhole; unix_to_nt_time(&nt_time, start_time); time_restrictions[0].res.resProperty.lpProp.value.ft.dwLowDateTime = (nt_time & 0xffffffff); time_restrictions[0].res.resProperty.lpProp.value.ft.dwHighDateTime = nt_time >> 32; fb_props->publish_start = (uint32_t) (nt_time / (60 * 10000000)); time_restrictions[1].rt = RES_PROPERTY; time_restrictions[1].res.resProperty.relop = RELOP_LE; time_restrictions[1].res.resProperty.ulPropTag = PidLidAppointmentStartWhole; time_restrictions[1].res.resProperty.lpProp.ulPropTag = PidLidAppointmentStartWhole; unix_to_nt_time(&nt_time, end_time); time_restrictions[1].res.resProperty.lpProp.value.ft.dwLowDateTime = (nt_time & 0xffffffff); time_restrictions[1].res.resProperty.lpProp.value.ft.dwHighDateTime = nt_time >> 32; fb_props->publish_end = (uint32_t) (nt_time / (60 * 10000000)); mapistore_table_set_restrictions(mstore_ctx, context_id, table, &and_res, &state); /* setup table columns */ props = talloc_zero(local_mem_ctx, struct SPropTagArray); props->cValues = 3; props->aulPropTag = talloc_array(props, enum MAPITAGS, props->cValues); props->aulPropTag[0] = PidLidAppointmentStartWhole; props->aulPropTag[1] = PidLidAppointmentEndWhole; props->aulPropTag[2] = PidLidBusyStatus; mapistore_table_set_columns(mstore_ctx, context_id, table, props->cValues, props->aulPropTag); /* setup months arrays */ if (local_start_tm.tm_year == local_end_tm.tm_year) { nbr_months = (local_end_tm.tm_mon - local_start_tm.tm_mon + 1); } else { nbr_months = (12 - local_start_tm.tm_mon) + local_end_tm.tm_mon + 1; } fb_props->months_ranges = talloc_array(fb_props, uint32_t, nbr_months); if (local_start_tm.tm_year == local_end_tm.tm_year) { for (i = 0; i < nbr_months; i++) { fb_props->months_ranges[i] = ((local_start_tm.tm_year + 1900) << 4) + (local_start_tm.tm_mon + 1 + i); } } else { month = local_start_tm.tm_mon; i = 0; while (month < 12) { fb_props->months_ranges[i] = ((local_start_tm.tm_year + 1900) << 4) + month + 1; i++; month++; } month = 0; while (month < local_end_tm.tm_mon) { fb_props->months_ranges[i] = ((local_end_tm.tm_year + 1900) << 4) + month + 1; i++; month++; } fb_props->months_ranges[i] = ((local_end_tm.tm_year + 1900) << 4) + month + 1; } /* fetch events and fill freebusy arrays */ free_array = talloc_array(local_mem_ctx, uint8_t *, nbr_months); tentative_array = talloc_array(local_mem_ctx, uint8_t *, nbr_months); busy_array = talloc_array(local_mem_ctx, uint8_t *, nbr_months); oof_array = talloc_array(local_mem_ctx, uint8_t *, nbr_months); for (i = 0; i < nbr_months; i++) { free_array[i] = talloc_array(free_array, uint8_t, max_mins_per_month); memset(free_array[i], 0, max_mins_per_month); tentative_array[i] = talloc_array(tentative_array, uint8_t, max_mins_per_month); memset(tentative_array[i], 0, max_mins_per_month); busy_array[i] = talloc_array(tentative_array, uint8_t, max_mins_per_month); memset(busy_array[i], 0, max_mins_per_month); oof_array[i] = talloc_array(tentative_array, uint8_t, max_mins_per_month); memset(oof_array[i], 0, max_mins_per_month); } i = 0; while (mapistore_table_get_row(mstore_ctx, context_id, table, local_mem_ctx, MAPISTORE_PREFILTERED_QUERY, i, &row_data) == MAPISTORE_SUCCESS) { if (row_data[0].error == MAPISTORE_SUCCESS && row_data[1].error == MAPISTORE_SUCCESS && row_data[2].error == MAPISTORE_SUCCESS) { switch (*((uint32_t *) row_data[2].data)) { case olFree: minutes_array = free_array; break; case olTentative: minutes_array = tentative_array; break; case olBusy: minutes_array = busy_array; break; case olOutOfOffice: minutes_array = oof_array; break; default: minutes_array = NULL; } if (minutes_array) { mapistore_freebusy_fill_fbarray(minutes_array, fb_props->months_ranges, nbr_months, row_data[0].data, row_data[1].data); } } i++; } /* compile minutes array into arrays of ranges */ fb_props->nbr_months = nbr_months; fb_props->freebusy_free = talloc_array(fb_props, struct Binary_r, nbr_months); fb_props->freebusy_tentative = talloc_array(fb_props, struct Binary_r, nbr_months); fb_props->freebusy_busy = talloc_array(fb_props, struct Binary_r, nbr_months); fb_props->freebusy_away = talloc_array(fb_props, struct Binary_r, nbr_months); fb_props->freebusy_merged = talloc_array(fb_props, struct Binary_r, nbr_months); for (i = 0; i < nbr_months; i++) { mapistore_freebusy_compile_fbarray(fb_props, free_array[i], fb_props->freebusy_free + i); mapistore_freebusy_compile_fbarray(fb_props, tentative_array[i], fb_props->freebusy_tentative + i); mapistore_freebusy_compile_fbarray(fb_props, busy_array[i], fb_props->freebusy_busy + i); mapistore_freebusy_compile_fbarray(fb_props, oof_array[i], fb_props->freebusy_away + i); mapistore_freebusy_merge_subarray(busy_array[i], oof_array[i]); mapistore_freebusy_compile_fbarray(fb_props, busy_array[i], fb_props->freebusy_merged + i); } *fb_props_p = fb_props; /* we bind fb_props to mem_ctx, because it will be released with the local_mem_ctx */ (void) talloc_reference(mem_ctx, fb_props); ret = MAPISTORE_SUCCESS; end: talloc_free(local_mem_ctx); return ret; } /** \details Modify recipients of a message in mapistore \param mstore_ctx pointer to the mapistore context \param context_id the context identifier referencing the backend where properties will be stored \param mid the identifier referencing the message \rows the array of recipient rows \count the number of elements in the array \return MAPISTORE_SUCCESS on success, otherwise MAPISTORE errors */ enum mapistore_error mapistore_message_get_message_data(struct mapistore_context *mstore_ctx, uint32_t context_id, void *message, TALLOC_CTX *mem_ctx, struct mapistore_message **msg) { struct backend_context *backend_ctx; /* Sanity checks */ MAPISTORE_SANITY_CHECKS(mstore_ctx, NULL); /* Step 1. Search the context */ backend_ctx = mapistore_backend_lookup(mstore_ctx->context_list, context_id); MAPISTORE_RETVAL_IF(!backend_ctx, MAPISTORE_ERR_INVALID_PARAMETER, NULL); /* Step 2. Call backend modifyrecipients */ return mapistore_backend_message_get_message_data(backend_ctx, message, mem_ctx, msg); } /** \details Modify recipients of a message in mapistore \param mstore_ctx pointer to the mapistore context \param context_id the context identifier referencing the backend where properties will be stored \param mid the identifier referencing the message \rows the array of recipient rows \count the number of elements in the array \return MAPISTORE_SUCCESS on success, otherwise MAPISTORE errors */ enum mapistore_error mapistore_message_modify_recipients(struct mapistore_context *mstore_ctx, uint32_t context_id, void *message, struct SPropTagArray *columns, uint16_t count, struct mapistore_message_recipient *recipients) { struct backend_context *backend_ctx; /* Sanity checks */ MAPISTORE_SANITY_CHECKS(mstore_ctx, NULL); /* Step 1. Search the context */ backend_ctx = mapistore_backend_lookup(mstore_ctx->context_list, context_id); MAPISTORE_RETVAL_IF(!backend_ctx, MAPISTORE_ERR_INVALID_PARAMETER, NULL); /* Step 2. Call backend modifyrecipients */ return mapistore_backend_message_modify_recipients(backend_ctx, message, columns, count, recipients); } /** \details Commit the changes made to a message in mapistore \param mstore_ctx pointer to the mapistore context \param context_id the context identifier referencing the backend where the message's changes will be saved \param mid the message identifier to save \param flags flags associated to the commit operation \return MAPISTORE_SUCCESS on success, otherwise MAPISTORE errors */ _PUBLIC_ enum mapistore_error mapistore_message_set_read_flag(struct mapistore_context *mstore_ctx, uint32_t context_id, void *message, uint8_t flag) { struct backend_context *backend_ctx; /* Sanity checks */ MAPISTORE_SANITY_CHECKS(mstore_ctx, NULL); /* Step 1. Search the context */ backend_ctx = mapistore_backend_lookup(mstore_ctx->context_list, context_id); MAPISTORE_RETVAL_IF(!backend_ctx, MAPISTORE_ERR_INVALID_PARAMETER, NULL); /* Step 2. Call backend savechangesmessage */ return mapistore_backend_message_set_read_flag(backend_ctx, message, flag); } /** \details Commit the changes made to a message in mapistore \param mstore_ctx pointer to the mapistore context \param context_id the context identifier referencing the backend where the message's changes will be saved \param mid the message identifier to save \param flags flags associated to the commit operation \return MAPISTORE_SUCCESS on success, otherwise MAPISTORE errors */ _PUBLIC_ enum mapistore_error mapistore_message_save(struct mapistore_context *mstore_ctx, uint32_t context_id, void *message) { struct backend_context *backend_ctx; /* Sanity checks */ MAPISTORE_SANITY_CHECKS(mstore_ctx, NULL); /* Step 1. Search the context */ backend_ctx = mapistore_backend_lookup(mstore_ctx->context_list, context_id); MAPISTORE_RETVAL_IF(!backend_ctx, MAPISTORE_ERR_INVALID_PARAMETER, NULL); /* Step 2. Call backend savechangesmessage */ return mapistore_backend_message_save(backend_ctx, message); } /** \details Submits a message for sending. \param mstore_ctx pointer to the mapistore context \param context_id the context identifier referencing the backend where the message will be submitted \param mid the message identifier representing the message to submit \param flags flags associated to the submit operation \return MAPISTORE_SUCCESS on success, otherwise MAPISTORE errors */ _PUBLIC_ enum mapistore_error mapistore_message_submit(struct mapistore_context *mstore_ctx, uint32_t context_id, void *message, enum SubmitFlags flags) { struct backend_context *backend_ctx; /* Sanity checks */ MAPISTORE_SANITY_CHECKS(mstore_ctx, NULL); /* Step 1. Search the context */ backend_ctx = mapistore_backend_lookup(mstore_ctx->context_list, context_id); MAPISTORE_RETVAL_IF(!backend_ctx, MAPISTORE_ERR_INVALID_PARAMETER, NULL); /* Step 2. Call backend submitmessage */ return mapistore_backend_message_submit(backend_ctx, message, flags); } _PUBLIC_ enum mapistore_error mapistore_message_get_attachment_table(struct mapistore_context *mstore_ctx, uint32_t context_id, void *message, TALLOC_CTX *mem_ctx, void **table, uint32_t *row_count) { struct backend_context *backend_ctx; /* Sanity checks */ MAPISTORE_SANITY_CHECKS(mstore_ctx, NULL); /* Step 1. Search the context */ backend_ctx = mapistore_backend_lookup(mstore_ctx->context_list, context_id); MAPISTORE_RETVAL_IF(!backend_ctx, MAPISTORE_ERR_INVALID_PARAMETER, NULL); /* Step 2. Call backend operation */ return mapistore_backend_message_get_attachment_table(backend_ctx, message, mem_ctx, table, row_count); } _PUBLIC_ enum mapistore_error mapistore_message_open_attachment(struct mapistore_context *mstore_ctx, uint32_t context_id, void *message, TALLOC_CTX *mem_ctx, uint32_t aid, void **attachment) { struct backend_context *backend_ctx; /* Sanity checks */ MAPISTORE_SANITY_CHECKS(mstore_ctx, NULL); /* Step 1. Search the context */ backend_ctx = mapistore_backend_lookup(mstore_ctx->context_list, context_id); MAPISTORE_RETVAL_IF(!backend_ctx, MAPISTORE_ERR_INVALID_PARAMETER, NULL); /* Step 2. Call backend operation */ return mapistore_backend_message_open_attachment(backend_ctx, message, mem_ctx, aid, attachment); } _PUBLIC_ enum mapistore_error mapistore_message_create_attachment(struct mapistore_context *mstore_ctx, uint32_t context_id, void *message, TALLOC_CTX *mem_ctx, void **attachment, uint32_t *aid) { struct backend_context *backend_ctx; /* Sanity checks */ MAPISTORE_SANITY_CHECKS(mstore_ctx, NULL); /* Step 1. Search the context */ backend_ctx = mapistore_backend_lookup(mstore_ctx->context_list, context_id); MAPISTORE_RETVAL_IF(!backend_ctx, MAPISTORE_ERR_INVALID_PARAMETER, NULL); /* Step 2. Call backend operation */ return mapistore_backend_message_create_attachment(backend_ctx, message, mem_ctx, attachment, aid); } _PUBLIC_ enum mapistore_error mapistore_message_attachment_open_embedded_message(struct mapistore_context *mstore_ctx, uint32_t context_id, void *attachment, TALLOC_CTX *mem_ctx, void **embedded_message, uint64_t *mid, struct mapistore_message **msg) { struct backend_context *backend_ctx; /* Sanity checks */ MAPISTORE_SANITY_CHECKS(mstore_ctx, NULL); /* Step 1. Search the context */ backend_ctx = mapistore_backend_lookup(mstore_ctx->context_list, context_id); MAPISTORE_RETVAL_IF(!backend_ctx, MAPISTORE_ERR_INVALID_PARAMETER, NULL); /* Step 2. Call backend operation */ return mapistore_backend_message_attachment_open_embedded_message(backend_ctx, attachment, mem_ctx, embedded_message, mid, msg); } _PUBLIC_ enum mapistore_error mapistore_message_attachment_create_embedded_message(struct mapistore_context *mstore_ctx, uint32_t context_id, void *attachment, TALLOC_CTX *mem_ctx, void **embedded_message, struct mapistore_message **msg) { struct backend_context *backend_ctx; /* Sanity checks */ MAPISTORE_SANITY_CHECKS(mstore_ctx, NULL); /* Step 1. Search the context */ backend_ctx = mapistore_backend_lookup(mstore_ctx->context_list, context_id); MAPISTORE_RETVAL_IF(!backend_ctx, MAPISTORE_ERR_INVALID_PARAMETER, NULL); /* Step 2. Call backend operation */ return mapistore_backend_message_attachment_create_embedded_message(backend_ctx, attachment, mem_ctx, embedded_message, msg); } _PUBLIC_ enum mapistore_error mapistore_table_get_available_properties(struct mapistore_context *mstore_ctx, uint32_t context_id, void *table, TALLOC_CTX *mem_ctx, struct SPropTagArray **propertiesp) { struct backend_context *backend_ctx; /* Sanity checks */ MAPISTORE_SANITY_CHECKS(mstore_ctx, NULL); /* Step 1. Search the context */ backend_ctx = mapistore_backend_lookup(mstore_ctx->context_list, context_id); MAPISTORE_RETVAL_IF(!backend_ctx, MAPISTORE_ERR_INVALID_PARAMETER, NULL); /* Step 2. Call backend operation */ return mapistore_backend_table_get_available_properties(backend_ctx, table, mem_ctx, propertiesp); } _PUBLIC_ enum mapistore_error mapistore_table_set_columns(struct mapistore_context *mstore_ctx, uint32_t context_id, void *table, uint16_t count, enum MAPITAGS *properties) { struct backend_context *backend_ctx; /* Sanity checks */ MAPISTORE_SANITY_CHECKS(mstore_ctx, NULL); /* Step 1. Search the context */ backend_ctx = mapistore_backend_lookup(mstore_ctx->context_list, context_id); MAPISTORE_RETVAL_IF(!backend_ctx, MAPISTORE_ERR_INVALID_PARAMETER, NULL); /* Step 2. Call backend operation */ return mapistore_backend_table_set_columns(backend_ctx, table, count, properties); } _PUBLIC_ enum mapistore_error mapistore_table_set_restrictions(struct mapistore_context *mstore_ctx, uint32_t context_id, void *table, struct mapi_SRestriction *restrictions, uint8_t *table_status) { struct backend_context *backend_ctx; /* Sanity checks */ MAPISTORE_SANITY_CHECKS(mstore_ctx, NULL); /* Step 1. Search the context */ backend_ctx = mapistore_backend_lookup(mstore_ctx->context_list, context_id); MAPISTORE_RETVAL_IF(!backend_ctx, MAPISTORE_ERR_INVALID_PARAMETER, NULL); /* Step 2. Call backend operation */ return mapistore_backend_table_set_restrictions(backend_ctx, table, restrictions, table_status); } _PUBLIC_ enum mapistore_error mapistore_table_set_sort_order(struct mapistore_context *mstore_ctx, uint32_t context_id, void *table, struct SSortOrderSet *sort_order, uint8_t *table_status) { struct backend_context *backend_ctx; /* Sanity checks */ MAPISTORE_SANITY_CHECKS(mstore_ctx, NULL); /* Step 1. Search the context */ backend_ctx = mapistore_backend_lookup(mstore_ctx->context_list, context_id); MAPISTORE_RETVAL_IF(!backend_ctx, MAPISTORE_ERR_INVALID_PARAMETER, NULL); /* Step 2. Call backend operation */ return mapistore_backend_table_set_sort_order(backend_ctx, table, sort_order, table_status); } _PUBLIC_ enum mapistore_error mapistore_table_get_row(struct mapistore_context *mstore_ctx, uint32_t context_id, void *table, TALLOC_CTX *mem_ctx, enum mapistore_query_type query_type, uint32_t rowid, struct mapistore_property_data **data) { struct backend_context *backend_ctx; /* Sanity checks */ MAPISTORE_SANITY_CHECKS(mstore_ctx, NULL); /* Step 1. Search the context */ backend_ctx = mapistore_backend_lookup(mstore_ctx->context_list, context_id); MAPISTORE_RETVAL_IF(!backend_ctx, MAPISTORE_ERR_INVALID_PARAMETER, NULL); /* Step 2. Call backend operation */ return mapistore_backend_table_get_row(backend_ctx, table, mem_ctx, query_type, rowid, data); } _PUBLIC_ enum mapistore_error mapistore_table_get_row_count(struct mapistore_context *mstore_ctx, uint32_t context_id, void *table, enum mapistore_query_type query_type, uint32_t *row_countp) { struct backend_context *backend_ctx; /* Sanity checks */ MAPISTORE_SANITY_CHECKS(mstore_ctx, NULL); /* Step 1. Search the context */ backend_ctx = mapistore_backend_lookup(mstore_ctx->context_list, context_id); MAPISTORE_RETVAL_IF(!backend_ctx, MAPISTORE_ERR_INVALID_PARAMETER, NULL); /* Step 2. Call backend operation */ return mapistore_backend_table_get_row_count(backend_ctx, table, query_type, row_countp); } _PUBLIC_ enum mapistore_error mapistore_table_handle_destructor(struct mapistore_context *mstore_ctx, uint32_t context_id, void *table, uint32_t handle_id) { struct backend_context *backend_ctx; /* Sanity checks */ MAPISTORE_SANITY_CHECKS(mstore_ctx, NULL); /* Step 1. Search the context */ backend_ctx = mapistore_backend_lookup(mstore_ctx->context_list, context_id); MAPISTORE_RETVAL_IF(!backend_ctx, MAPISTORE_ERR_INVALID_PARAMETER, NULL); /* Step 2. Call backend operation */ return mapistore_backend_table_handle_destructor(backend_ctx, table, handle_id); } _PUBLIC_ enum mapistore_error mapistore_properties_get_available_properties(struct mapistore_context *mstore_ctx, uint32_t context_id, void *object, TALLOC_CTX *mem_ctx, struct SPropTagArray **propertiesp) { struct backend_context *backend_ctx; /* Sanity checks */ MAPISTORE_SANITY_CHECKS(mstore_ctx, NULL); /* Step 1. Search the context */ backend_ctx = mapistore_backend_lookup(mstore_ctx->context_list, context_id); MAPISTORE_RETVAL_IF(!backend_ctx, MAPISTORE_ERR_INVALID_PARAMETER, NULL); /* Step 2. Call backend operation */ return mapistore_backend_properties_get_available_properties(backend_ctx, object, mem_ctx, propertiesp); } _PUBLIC_ enum mapistore_error mapistore_properties_get_properties(struct mapistore_context *mstore_ctx, uint32_t context_id, void *object, TALLOC_CTX *mem_ctx, uint16_t count, enum MAPITAGS *properties, struct mapistore_property_data *data) { struct backend_context *backend_ctx; /* Sanity checks */ MAPISTORE_SANITY_CHECKS(mstore_ctx, NULL); /* Step 1. Search the context */ backend_ctx = mapistore_backend_lookup(mstore_ctx->context_list, context_id); MAPISTORE_RETVAL_IF(!backend_ctx, MAPISTORE_ERR_INVALID_PARAMETER, NULL); /* Step 2. Call backend operation */ return mapistore_backend_properties_get_properties(backend_ctx, object, mem_ctx, count, properties, data); } _PUBLIC_ enum mapistore_error mapistore_properties_set_properties(struct mapistore_context *mstore_ctx, uint32_t context_id, void *object, struct SRow *aRow) { struct backend_context *backend_ctx; /* Sanity checks */ MAPISTORE_SANITY_CHECKS(mstore_ctx, NULL); /* Step 1. Search the context */ backend_ctx = mapistore_backend_lookup(mstore_ctx->context_list, context_id); MAPISTORE_RETVAL_IF(!backend_ctx, MAPISTORE_ERR_INVALID_PARAMETER, NULL); /* Step 2. Call backend operation */ return mapistore_backend_properties_set_properties(backend_ctx, object, aRow); } _PUBLIC_ enum MAPISTATUS mapistore_error_to_mapi(enum mapistore_error mapistore_err) { enum MAPISTATUS mapi_err; switch(mapistore_err) { case MAPISTORE_SUCCESS: mapi_err = MAPI_E_SUCCESS; break; case MAPISTORE_ERROR: mapi_err = MAPI_E_NO_SUPPORT; break; case MAPISTORE_ERR_NO_MEMORY: mapi_err = MAPI_E_NOT_ENOUGH_MEMORY; break; case MAPISTORE_ERR_ALREADY_INITIALIZED: case MAPISTORE_ERR_NOT_INITIALIZED: mapi_err = MAPI_E_NOT_INITIALIZED; break; case MAPISTORE_ERR_CORRUPTED: mapi_err = MAPI_E_CORRUPT_STORE; break; case MAPISTORE_ERR_INVALID_PARAMETER: mapi_err = MAPI_E_INVALID_PARAMETER; break; case MAPISTORE_ERR_NO_DIRECTORY: case MAPISTORE_ERR_DATABASE_INIT: case MAPISTORE_ERR_DATABASE_OPS: case MAPISTORE_ERR_BACKEND_REGISTER: case MAPISTORE_ERR_BACKEND_INIT: case MAPISTORE_ERR_CONTEXT_FAILED: case MAPISTORE_ERR_INVALID_NAMESPACE: mapi_err = MAPI_E_DISK_ERROR; break; case MAPISTORE_ERR_NOT_FOUND: mapi_err = MAPI_E_NOT_FOUND; break; case MAPISTORE_ERR_REF_COUNT: mapi_err = MAPI_E_COLLISION; break; case MAPISTORE_ERR_EXIST: mapi_err = MAPI_E_COLLISION; break; case MAPISTORE_ERR_INVALID_DATA: case MAPISTORE_ERR_MSG_SEND: case MAPISTORE_ERR_MSG_RCV: mapi_err = MAPI_E_DISK_ERROR; break; case MAPISTORE_ERR_DENIED: mapi_err = MAPI_E_NO_ACCESS; break; case MAPISTORE_ERR_NOT_IMPLEMENTED: mapi_err = MAPI_E_NOT_IMPLEMENTED; break; default: DEBUG (4, ("[%s] unknown mapistore error: %.8x\n", __PRETTY_FUNCTION__, mapistore_err)); mapi_err = MAPI_E_INVALID_PARAMETER; } return mapi_err; } openchange-2.0/mapiproxy/libmapistore/mapistore_ldb_wrap.c000066400000000000000000000055301223057412600242320ustar00rootroot00000000000000/* Unix SMB/CIFS implementation. LDB wrap functions Copyright (C) Andrew Tridgell 2004-2009 This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see . */ #include "config.h" #include #include #include "mapistore.h" #include "mapistore_private.h" #include #include static struct ldb_wrap *ldb_wrap_list; /* see if two database opens are equivalent */ static bool mapistore_ldb_wrap_same_context(const struct ldb_wrap_context *c1, const struct ldb_wrap_context *c2) { return (c1->ev == c2->ev && c1->flags == c2->flags && (c1->url == c2->url || strcmp(c1->url, c2->url) == 0)); } /* free a ldb_wrap structure */ static int mapistore_ldb_wrap_destructor(struct ldb_wrap *w) { DLIST_REMOVE(ldb_wrap_list, w); return 0; } /* wrapped connection to a ldb database to close just talloc_free() the returned ldb_context TODO: We need an error_string parameter */ struct ldb_context *mapistore_ldb_wrap_connect(TALLOC_CTX *mem_ctx, struct tevent_context *ev, const char *url, unsigned int flags) { struct ldb_context *ldb; int ret; struct ldb_wrap *w; struct ldb_wrap_context c; c.url = url; c.ev = ev; c.flags = flags; /* see if we can re-use an existing ldb */ for (w = ldb_wrap_list; w; w = w->next) { if (mapistore_ldb_wrap_same_context(&c, &w->context)) { return talloc_reference(mem_ctx, w->ldb); } } /* we want to use the existing event context if possible. This relies on the fact that in smbd, everything is a child of the main event_context */ if (ev == NULL) { return NULL; } ldb = ldb_init(mem_ctx, ev); if (ldb == NULL) { return NULL; } ldb_set_create_perms(ldb, 0600); ret = ldb_connect(ldb, url, flags, NULL); if (ret != LDB_SUCCESS) { talloc_free(ldb); return NULL; } /* add to the list of open ldb contexts */ w = talloc(ldb, struct ldb_wrap); if (w == NULL) { talloc_free(ldb); return NULL; } w->context = c; w->context.url = talloc_strdup(w, url); if (w->context.url == NULL) { talloc_free(ldb); return NULL; } w->ldb = ldb; DLIST_ADD(ldb_wrap_list, w); DEBUG(3,("ldb_wrap open of %s\n", url)); talloc_set_destructor(w, mapistore_ldb_wrap_destructor); return ldb; } openchange-2.0/mapiproxy/libmapistore/mapistore_namedprops.c000066400000000000000000000312731223057412600246130ustar00rootroot00000000000000/* OpenChange Storage Abstraction Layer library OpenChange Project Copyright (C) Julien Kerihuel 2010-2013 This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see . */ #include "mapistore.h" #include "mapistore_errors.h" #include "mapistore_private.h" #include "libmapi/libmapi_private.h" #include #include static const char *mapistore_namedprops_get_ldif_path(void) { return MAPISTORE_LDIF; } /** \details Initialize the named properties database or return pointer to the existing one if already initialized/opened. \param mem_ctx pointer to the memory context \param ldb_ctx pointer on pointer to the ldb context the function returns \return MAPISTORE_SUCCESS on success, otherwise MAPISTORE error */ enum mapistore_error mapistore_namedprops_init(TALLOC_CTX *mem_ctx, struct ldb_context **_ldb_ctx) { int ret; struct stat sb; struct ldb_context *ldb_ctx = NULL; struct ldb_ldif *ldif; char *filename; FILE *f; struct tevent_context *ev; char *database; /* Sanity checks */ MAPISTORE_RETVAL_IF(!mem_ctx, MAPISTORE_ERR_INVALID_PARAMETER, NULL); MAPISTORE_RETVAL_IF(!_ldb_ctx, MAPISTORE_ERR_INVALID_PARAMETER, NULL); ev = tevent_context_init(mem_ctx); MAPISTORE_RETVAL_IF(!ev, MAPISTORE_ERR_NO_MEMORY, NULL); database = talloc_asprintf(mem_ctx, "%s/%s", mapistore_get_mapping_path(), MAPISTORE_DB_NAMED); DEBUG(0, ("database = %s\n", database)); /* Step 1. Stat the database and populate it if it doesn't exist */ if (stat(database, &sb) == -1) { ldb_ctx = mapistore_ldb_wrap_connect(ldb_ctx, ev, database, 0); talloc_free(database); MAPISTORE_RETVAL_IF(!ldb_ctx, MAPISTORE_ERR_DATABASE_INIT, NULL); filename = talloc_asprintf(mem_ctx, "%s/mapistore_namedprops.ldif", mapistore_namedprops_get_ldif_path()); f = fopen(filename, "r"); talloc_free(filename); MAPISTORE_RETVAL_IF(!f, MAPISTORE_ERROR, NULL); ldb_transaction_start(ldb_ctx); /* dn: @INDEXLIST @IDXATTR: cn @IDXATTR: oleguid @IDXATTR: mappedId */ { TALLOC_CTX *_mem_ctx; struct ldb_message *msg; _mem_ctx = talloc_zero(NULL, TALLOC_CTX); msg = ldb_msg_new(_mem_ctx); msg->dn = ldb_dn_new(msg, ldb_ctx, "@INDEXLIST"); ldb_msg_add_string(msg, "@IDXATTR", "cn"); ldb_msg_add_string(msg, "@IDXATTR", "oleguid"); ldb_msg_add_string(msg, "@IDXATTR", "mappedId"); msg->elements[0].flags = LDB_FLAG_MOD_ADD; ret = ldb_add(ldb_ctx, msg); if (ret != LDB_SUCCESS) { fclose(f); talloc_free(_mem_ctx); return MAPISTORE_ERR_DATABASE_INIT; } talloc_free(_mem_ctx); } while ((ldif = ldb_ldif_read_file(ldb_ctx, f))) { struct ldb_message *normalized_msg; ret = ldb_msg_normalize(ldb_ctx, mem_ctx, ldif->msg, &normalized_msg); MAPISTORE_RETVAL_IF(ret, MAPISTORE_ERR_DATABASE_INIT, NULL); ret = ldb_add(ldb_ctx, normalized_msg); talloc_free(normalized_msg); if (ret != LDB_SUCCESS) { fclose(f); return MAPISTORE_ERR_DATABASE_INIT; } ldb_ldif_read_free(ldb_ctx, ldif); } ldb_transaction_commit(ldb_ctx); fclose(f); } else { ldb_ctx = mapistore_ldb_wrap_connect(ldb_ctx, ev, database, 0); talloc_free(database); MAPISTORE_RETVAL_IF(!ldb_ctx, MAPISTORE_ERR_DATABASE_INIT, NULL); } *_ldb_ctx = ldb_ctx; return MAPISTORE_SUCCESS; } /** \details return the next unmapped property ID \param ldb_ctx pointer to the namedprops ldb context \return 0 on error, the next mapped id otherwise */ _PUBLIC_ uint16_t mapistore_namedprops_next_unused_id(struct ldb_context *ldb_ctx) { uint16_t highest_id = 0, current_id; TALLOC_CTX *mem_ctx; struct ldb_result *res = NULL; const char * const attrs[] = { "mappedId", NULL }; int ret; unsigned int i; mem_ctx = talloc_named(NULL, 0, "mapistore_namedprops_get_mapped_propID"); ret = ldb_search(ldb_ctx, mem_ctx, &res, ldb_get_default_basedn(ldb_ctx), LDB_SCOPE_SUBTREE, attrs, "(cn=*)"); MAPISTORE_RETVAL_IF(ret != LDB_SUCCESS, 0, mem_ctx); for (i = 0; i < res->count; i++) { current_id = ldb_msg_find_attr_as_uint(res->msgs[i], "mappedId", 0); if (current_id > 0 && highest_id < current_id) { highest_id = current_id; } } talloc_free(mem_ctx); DEBUG(5, ("next_mapped_id: %d\n", (highest_id + 1))); return (highest_id + 1); } /** \details return the mapped property ID matching the nameid structure passed in parameter. \param ldb_ctx pointer to the namedprops ldb context \param nameid the MAPINAMEID structure to lookup \param propID pointer to the property ID the function returns \return MAPISTORE_SUCCESS on success, otherwise MAPISTORE_ERROR */ _PUBLIC_ enum mapistore_error mapistore_namedprops_create_id(struct ldb_context *ldb_ctx, struct MAPINAMEID nameid, uint16_t mapped_id) { int ret; TALLOC_CTX *mem_ctx; char *ldif_record; struct ldb_ldif *ldif; char *hex_id; char *dec_id; char *dec_mappedid; char *guid; struct ldb_message *normalized_msg; const char *ldif_records[] = { NULL, NULL }; mem_ctx = talloc_zero(NULL, TALLOC_CTX); dec_mappedid = talloc_asprintf(mem_ctx, "%u", mapped_id); guid = GUID_string(mem_ctx, &nameid.lpguid); switch (nameid.ulKind) { case MNID_ID: hex_id = talloc_asprintf(mem_ctx, "%.4x", nameid.kind.lid); dec_id = talloc_asprintf(mem_ctx, "%u", nameid.kind.lid); ldif_record = talloc_asprintf(mem_ctx, "dn: CN=0x%s,CN=%s,CN=default\n" \ "objectClass: MNID_ID\n" \ "cn: 0x%s\n" \ "propType: PT_NULL\n" \ "oleguid: %s\n" \ "mappedId: %s\n" \ "propId: %s\n", hex_id, guid, hex_id, guid, dec_mappedid, dec_id); break; case MNID_STRING: ldif_record = talloc_asprintf(mem_ctx, "dn: CN=%s,CN=%s,CN=default\n" \ "objectClass: MNID_STRING\n" \ "cn: %s\n" \ "propType: PT_NULL\n" \ "oleguid: %s\n" \ "mappedId: %s\n" \ "propName: %s\n", nameid.kind.lpwstr.Name, guid, nameid.kind.lpwstr.Name, guid, dec_mappedid, nameid.kind.lpwstr.Name); break; default: abort(); } DEBUG(5, ("inserting record:\n%s\n", ldif_record)); ldif_records[0] = ldif_record; ldif = ldb_ldif_read_string(ldb_ctx, ldif_records); ret = ldb_msg_normalize(ldb_ctx, mem_ctx, ldif->msg, &normalized_msg); MAPISTORE_RETVAL_IF(ret, MAPISTORE_ERR_DATABASE_INIT, mem_ctx); ret = ldb_add(ldb_ctx, normalized_msg); talloc_free(normalized_msg); MAPISTORE_RETVAL_IF(ret != LDB_SUCCESS, MAPISTORE_ERR_DATABASE_INIT, mem_ctx); talloc_free(mem_ctx); return ret; } /** \details return the mapped property ID matching the nameid structure passed in parameter. \param ldb_ctx pointer to the namedprops ldb context \param nameid the MAPINAMEID structure to lookup \param propID pointer to the property ID the function returns \return MAPISTORE_SUCCESS on success, otherwise MAPISTORE_ERROR */ _PUBLIC_ enum mapistore_error mapistore_namedprops_get_mapped_id(struct ldb_context *ldb_ctx, struct MAPINAMEID nameid, uint16_t *propID) { TALLOC_CTX *mem_ctx; struct ldb_result *res = NULL; const char * const attrs[] = { "*", NULL }; int ret; char *filter = NULL; char *guid; /* Sanity checks */ MAPISTORE_RETVAL_IF(!ldb_ctx, MAPISTORE_ERROR, NULL); MAPISTORE_RETVAL_IF(!propID, MAPISTORE_ERROR, NULL); *propID = 0; mem_ctx = talloc_named(NULL, 0, "mapistore_namedprops_get_mapped_propID"); guid = GUID_string(mem_ctx, (const struct GUID *)&nameid.lpguid); switch (nameid.ulKind) { case MNID_ID: filter = talloc_asprintf(mem_ctx, "(&(objectClass=MNID_ID)(oleguid=%s)(cn=0x%.4x))", guid, nameid.kind.lid); break; case MNID_STRING: filter = talloc_asprintf(mem_ctx, "(&(objectClass=MNID_STRING)(oleguid=%s)(cn=%s))", guid, nameid.kind.lpwstr.Name); break; } talloc_free(guid); ret = ldb_search(ldb_ctx, mem_ctx, &res, ldb_get_default_basedn(ldb_ctx), LDB_SCOPE_SUBTREE, attrs, "%s", filter); MAPISTORE_RETVAL_IF((ret != LDB_SUCCESS || !res->count), MAPISTORE_ERROR, mem_ctx); *propID = ldb_msg_find_attr_as_uint(res->msgs[0], "mappedId", 0); MAPISTORE_RETVAL_IF(!*propID, MAPISTORE_ERROR, mem_ctx); talloc_free(mem_ctx); return MAPISTORE_SUCCESS; } /** \details return the nameid structture matching the mapped property ID passed in parameter. \param ldb_ctx pointer to the namedprops ldb context \param propID the property ID to lookup \param nameid pointer to the MAPINAMEID structure the function returns \return MAPISTORE_SUCCESS on success, otherwise MAPISTORE_ERROR */ _PUBLIC_ enum mapistore_error mapistore_namedprops_get_nameid(struct ldb_context *ldb_ctx, uint16_t propID, TALLOC_CTX *mem_ctx, struct MAPINAMEID **nameidp) { TALLOC_CTX *local_mem_ctx; struct ldb_result *res = NULL; const char * const attrs[] = { "*", NULL }; int ret; const char *guid, *oClass, *cn; struct MAPINAMEID *nameid; int rc = MAPISTORE_SUCCESS; /* Sanity checks */ MAPISTORE_RETVAL_IF(!ldb_ctx, MAPISTORE_ERROR, NULL); MAPISTORE_RETVAL_IF(!nameidp, MAPISTORE_ERROR, NULL); MAPISTORE_RETVAL_IF(propID < 0x8000, MAPISTORE_ERROR, NULL); local_mem_ctx = talloc_zero(NULL, TALLOC_CTX); ret = ldb_search(ldb_ctx, local_mem_ctx, &res, ldb_get_default_basedn(ldb_ctx), LDB_SCOPE_SUBTREE, attrs, "(mappedId=%d)", propID); MAPISTORE_RETVAL_IF(ret != LDB_SUCCESS || !res->count, MAPISTORE_ERROR, local_mem_ctx); guid = ldb_msg_find_attr_as_string(res->msgs[0], "oleguid", 0); MAPISTORE_RETVAL_IF(!guid, MAPISTORE_ERROR, local_mem_ctx); cn = ldb_msg_find_attr_as_string(res->msgs[0], "cn", 0); MAPISTORE_RETVAL_IF(!cn, MAPISTORE_ERROR, local_mem_ctx); oClass = ldb_msg_find_attr_as_string(res->msgs[0], "objectClass", 0); MAPISTORE_RETVAL_IF(!propID, MAPISTORE_ERROR, local_mem_ctx); nameid = talloc_zero(mem_ctx, struct MAPINAMEID); GUID_from_string(guid, &nameid->lpguid); if (strcmp(oClass, "MNID_ID") == 0) { nameid->ulKind = MNID_ID; nameid->kind.lid = strtol(cn, NULL, 16); } else if (strcmp(oClass, "MNID_STRING") == 0) { nameid->ulKind = MNID_STRING; nameid->kind.lpwstr.NameSize = strlen(cn) * 2 + 2; nameid->kind.lpwstr.Name = talloc_strdup(nameid, cn); } else { talloc_free(nameid); nameid = NULL; rc = MAPISTORE_ERROR; } *nameidp = nameid; talloc_free(local_mem_ctx); return rc; } /** \details return the type matching the mapped property ID passed in parameter. \param ldb_ctx pointer to the namedprops ldb context \param propID the property ID to lookup \param propTypeP pointer to the uint16_t that will receive the property type \return MAPISTORE_SUCCESS on success, otherwise MAPISTORE_ERROR */ _PUBLIC_ enum mapistore_error mapistore_namedprops_get_nameid_type(struct ldb_context *ldb_ctx, uint16_t propID, uint16_t *propTypeP) { TALLOC_CTX *mem_ctx; struct ldb_result *res = NULL; const char * const attrs[] = { "propType", NULL }; int ret, type; int rc = MAPISTORE_SUCCESS; /* Sanity checks */ MAPISTORE_RETVAL_IF(!ldb_ctx, MAPISTORE_ERROR, NULL); MAPISTORE_RETVAL_IF(!propTypeP, MAPISTORE_ERROR, NULL); MAPISTORE_RETVAL_IF(propID < 0x8000, MAPISTORE_ERROR, NULL); mem_ctx = talloc_zero(NULL, TALLOC_CTX); ret = ldb_search(ldb_ctx, mem_ctx, &res, ldb_get_default_basedn(ldb_ctx), LDB_SCOPE_SUBTREE, attrs, "(mappedId=%d)", propID); MAPISTORE_RETVAL_IF(ret != LDB_SUCCESS || !res->count, MAPISTORE_ERROR, mem_ctx); type = ldb_msg_find_attr_as_int(res->msgs[0], "propType", 0); MAPISTORE_RETVAL_IF(!type, MAPISTORE_ERROR, mem_ctx); switch (type) { case PT_SHORT: case PT_LONG: case PT_FLOAT: case PT_DOUBLE: case PT_CURRENCY: case PT_APPTIME: case PT_ERROR: case PT_BOOLEAN: case PT_OBJECT: case PT_I8: case PT_STRING8: case PT_UNICODE: case PT_SYSTIME: case PT_CLSID: case PT_SVREID: case PT_SRESTRICT: case PT_ACTIONS: case PT_BINARY: case PT_MV_SHORT: case PT_MV_LONG: case PT_MV_FLOAT: case PT_MV_DOUBLE: case PT_MV_CURRENCY: case PT_MV_APPTIME: case PT_MV_I8: case PT_MV_STRING8: case PT_MV_UNICODE: case PT_MV_SYSTIME: case PT_MV_CLSID: case PT_MV_BINARY: break; default: DEBUG(0, ("%d is not a valid type for a named property (%.4x)\n", type, propID)); abort(); } *propTypeP = type; talloc_free(mem_ctx); return rc; } openchange-2.0/mapiproxy/libmapistore/mapistore_notification.c000066400000000000000000000525651223057412600251400ustar00rootroot00000000000000/* OpenChange Storage Abstraction Layer library OpenChange Project Copyright (C) Wolfgang Sourdeau 2011 This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see . */ #include #include #include "mapiproxy/libmapistore/mapistore.h" #include "mapiproxy/libmapistore/mapistore_private.h" #include "mapiproxy/libmapistore/mapistore_errors.h" #include "mapiproxy/libmapistore/mgmt/mapistore_mgmt.h" #include "mapiproxy/libmapistore/mgmt/gen_ndr/ndr_mapistore_mgmt.h" #if 0 static int mapistore_subscription_destructor(void *data) { struct mapistore_subscription *subscription = (struct mapistore_subscription *) data; DEBUG(0, ("#### DELETING SUBSCRIPTION ###\n")); if (!data) return -1; DEBUG(0, ("### 1. NotificationFlags = 0x%x\n", subscription->notification_types)); DEBUG(0, ("### 2. handle = 0x%x\n", subscription->handle)); if (subscription->mqueue != -1) { if (mq_unlink(subscription->mqueue_name) == -1) { perror("mq_unlink"); } DEBUG(0, ("%s unlinked\n", subscription->mqueue_name)); talloc_free(subscription->mqueue_name); } return 0; } #endif struct mapistore_subscription *mapistore_new_subscription(TALLOC_CTX *mem_ctx, struct mapistore_context *mstore_ctx, const char *username, uint32_t handle, uint16_t notification_types, void *notification_parameters) { #if 0 int ret; struct mapistore_connection_info c; struct mapistore_mgmt_notif n; struct mapistore_subscription *new_subscription; struct mapistore_table_subscription_parameters *table_parameters; struct mapistore_object_subscription_parameters *object_parameters; unsigned int prio; struct mq_attr attr; DATA_BLOB data; new_subscription = talloc_zero(mem_ctx, struct mapistore_subscription); new_subscription->handle = handle; new_subscription->notification_types = notification_types; new_subscription->mqueue = -1; new_subscription->mqueue_name = NULL; if (notification_types == fnevTableModified) { table_parameters = notification_parameters; new_subscription->parameters.table_parameters = *table_parameters; } else { object_parameters = notification_parameters; new_subscription->parameters.object_parameters = *object_parameters; /* NewMail POC: open newmail mail queue */ if (notification_types & fnevNewMail || notification_types & fnevObjectCreated) { new_subscription->mqueue_name = talloc_asprintf((TALLOC_CTX *)new_subscription, MAPISTORE_MQUEUE_NEWMAIL_FMT, username); new_subscription->mqueue = mq_open(new_subscription->mqueue_name, O_RDONLY|O_NONBLOCK|O_CREAT, 0777, NULL); if (new_subscription->mqueue == -1) { perror("mq_open"); talloc_free(new_subscription->mqueue_name); return new_subscription; } /* Empty queue since we only want to retrieve new data from now */ ret = mq_getattr(new_subscription->mqueue, &attr); if (ret == -1) { perror("mq_getattr"); } else { data.data = talloc_size(mem_ctx, attr.mq_msgsize); while ((data.length = mq_receive(new_subscription->mqueue, (char *)data.data, attr.mq_msgsize, &prio)) != -1) { dump_data(0, data.data, data.length); talloc_free(data.data); data.data = talloc_size(mem_ctx, attr.mq_msgsize); } talloc_free(data.data); } /* Set destructor on new_subscription as we want to unlink the queue upon release */ talloc_set_destructor((void *)new_subscription, (int (*)(void *))mapistore_subscription_destructor); /* Send notification to tell about newmail */ n.WholeStore = object_parameters->whole_store; n.NotificationFlags = notification_types; if (n.WholeStore == true) { n.FolderID = 0; n.MessageID = 0; n.MAPIStoreURI = NULL; } else { n.FolderID = object_parameters->folder_id; n.MessageID = object_parameters->object_id; /* FIXME */ n.MAPIStoreURI = NULL; } c.username = (char *)username; c.mstore_ctx = mstore_ctx; ret = mapistore_mgmt_interface_register_subscription(&c, &n); DEBUG(0, ("[%s:%d]: registering notification: %d\n", __FUNCTION__, __LINE__, ret)); } } return new_subscription; #endif return NULL; } _PUBLIC_ void mapistore_push_notification(struct mapistore_context *mstore_ctx, uint8_t object_type, enum mapistore_notification_type event, void *parameters) { #if 0 struct mapistore_notification *new_notification; struct mapistore_notification_list *new_list; struct mapistore_table_notification_parameters *table_parameters; struct mapistore_object_notification_parameters *object_parameters; if (!mstore_ctx) return; new_list = talloc_zero(mstore_ctx, struct mapistore_notification_list); new_notification = talloc_zero(new_list, struct mapistore_notification); new_list->notification = new_notification; new_notification->object_type = object_type; new_notification->event = event; if (object_type == MAPISTORE_TABLE) { table_parameters = parameters; new_notification->parameters.table_parameters = *table_parameters; } else { object_parameters = parameters; new_notification->parameters.object_parameters = *object_parameters; if (new_notification->parameters.object_parameters.tag_count > 0 && new_notification->parameters.object_parameters.tag_count != 0xffff) { new_notification->parameters.object_parameters.tags = talloc_memdup(new_notification, new_notification->parameters.object_parameters.tags, sizeof(enum MAPITAGS) * new_notification->parameters.object_parameters.tag_count); } } DLIST_ADD_END(mstore_ctx->notifications, new_list, void); #endif } #if 0 static struct mapistore_notification_list *mapistore_notification_process_mqueue_notif(TALLOC_CTX *mem_ctx, DATA_BLOB data) { struct mapistore_notification_list *nl; struct mapistore_mgmt_command command; struct ndr_pull *ndr_pull = NULL; ndr_pull = ndr_pull_init_blob(&data, mem_ctx); ndr_pull_mapistore_mgmt_command(ndr_pull, NDR_SCALARS|NDR_BUFFERS, &command); /* verbose */ { struct ndr_print *ndr_print; ndr_print = talloc_zero(mem_ctx, struct ndr_print); ndr_print->print = ndr_print_printf_helper; ndr_print->depth = 1; ndr_print_mapistore_mgmt_command(ndr_print, "command", &command); talloc_free(ndr_print); } if (command.type != MAPISTORE_MGMT_NOTIF) { DEBUG(0, ("[%s:%d]: Invalid command type received: 0x%x\n", __FUNCTION__, __LINE__, command.type)); return NULL; } if (command.command.notification.status != MAPISTORE_MGMT_SEND) { DEBUG(0, ("[%s:%d]: Invalid notification status: 0x%x\n", __FUNCTION__, __LINE__, command.command.notification.status)); return NULL; } nl = talloc_zero(mem_ctx, struct mapistore_notification_list); nl->notification = talloc_zero((TALLOC_CTX *)nl, struct mapistore_notification); /* On newmail notification received, trigger 3 notifications: 1. FolderModifiedNotification (0x3010) 2. MessageObjectCreated (0x8004) 3. FolderModification (0x10) */ switch (command.command.notification.NotificationFlags) { case 0x8004: nl->notification->object_type = MAPISTORE_MESSAGE; nl->notification->event = MAPISTORE_OBJECT_CREATED; nl->notification->parameters.object_parameters.folder_id = command.command.notification.FolderID; nl->notification->parameters.object_parameters.object_id = command.command.notification.MessageID; nl->notification->parameters.object_parameters.tag_count = 24; nl->notification->parameters.object_parameters.tags = talloc_array(nl->notification, enum MAPITAGS, nl->notification->parameters.object_parameters.tag_count); nl->notification->parameters.object_parameters.tags[0] = PR_RCVD_REPRESENTING_ENTRYID; nl->notification->parameters.object_parameters.tags[1] = PR_RCVD_REPRESENTING_ADDRTYPE; nl->notification->parameters.object_parameters.tags[2] = PR_RCVD_REPRESENTING_EMAIL_ADDRESS; nl->notification->parameters.object_parameters.tags[3] = PR_RCVD_REPRESENTING_NAME; nl->notification->parameters.object_parameters.tags[4] = PR_RCVD_REPRESENTING_SEARCH_KEY; nl->notification->parameters.object_parameters.tags[5] = PidTagReceivedRepresentingFlags; nl->notification->parameters.object_parameters.tags[6] = 0x67BA0102; nl->notification->parameters.object_parameters.tags[7] = PR_CONTENT_FILTER_SCL; nl->notification->parameters.object_parameters.tags[8] = PR_LAST_MODIFICATION_TIME; nl->notification->parameters.object_parameters.tags[9] = PR_LAST_MODIFIER_ENTRYID; nl->notification->parameters.object_parameters.tags[10] = PR_LAST_MODIFIER_NAME; nl->notification->parameters.object_parameters.tags[11] = PR_MODIFIER_FLAGS; nl->notification->parameters.object_parameters.tags[12] = 0x67BE0102; nl->notification->parameters.object_parameters.tags[13] = PR_LOCAL_COMMIT_TIME; nl->notification->parameters.object_parameters.tags[14] = PR_RECEIVED_BY_SEARCH_KEY; nl->notification->parameters.object_parameters.tags[15] = PR_RECEIVED_BY_ENTRYID; nl->notification->parameters.object_parameters.tags[16] = PR_RECEIVED_BY_ADDRTYPE; nl->notification->parameters.object_parameters.tags[17] = PR_RECEIVED_BY_EMAIL_ADDRESS; nl->notification->parameters.object_parameters.tags[18] = PR_RECEIVED_BY_NAME; nl->notification->parameters.object_parameters.tags[19] = PidTagReceivedByFlags; nl->notification->parameters.object_parameters.tags[20] = 0x67B90102; nl->notification->parameters.object_parameters.tags[21] = PR_MESSAGE_FLAGS; nl->notification->parameters.object_parameters.tags[22] = PR_MESSAGE_SIZE; nl->notification->parameters.object_parameters.tags[23] = PR_INTERNET_ARTICLE_NUMBER; break; case 0x3010: nl->notification->object_type = MAPISTORE_FOLDER; nl->notification->event = MAPISTORE_OBJECT_MODIFIED; nl->notification->parameters.object_parameters.folder_id = command.command.notification.FolderID; nl->notification->parameters.object_parameters.tag_count = 0x5; nl->notification->parameters.object_parameters.tags = talloc_array(nl->notification, enum MAPITAGS, nl->notification->parameters.object_parameters.tag_count); nl->notification->parameters.object_parameters.tags[0] = PR_CONTENT_COUNT; nl->notification->parameters.object_parameters.tags[1] = PR_CONTENT_UNREAD; nl->notification->parameters.object_parameters.tags[2] = PR_MESSAGE_SIZE; nl->notification->parameters.object_parameters.tags[3] = PR_RECIPIENT_ON_NORMAL_MSG_COUNT; nl->notification->parameters.object_parameters.tags[4] = PR_NORMAL_MESSAGE_SIZE; nl->notification->parameters.object_parameters.message_count = command.command.notification.TotalNumberOfMessages; break; default: DEBUG(3, ("Unsupported Notification Type: 0x%x\n", command.command.notification.NotificationFlags)); break; /* TODO: Finir de faire les notifications FIX dcesrv_exchange_emsmdb.c: fill_notification Faire le test allelouia */ } /* HACK: we only support NewMail notifications for now */ return nl; } #endif /** \details Return the list of pending mapistore notifications available on the queue name specified in argument. \param mstore_ctx pointer to the mapistore context \param mqueue_name the name of the queue to open \param nl pointer on pointer to the list of mapistore notifications to return \return MAPISTORE_SUCCESS on success, otherwise MAPISTORE error. */ _PUBLIC_ enum MAPISTATUS mapistore_get_queued_notifications_named(struct mapistore_context *mstore_ctx, const char *mqueue_name, struct mapistore_notification_list **nl) { bool found = false; #if 0 int ret; mqd_t mqueue; struct mapistore_notification_list *nlist = NULL; struct mapistore_notification_list *el = NULL; unsigned int prio; struct mq_attr attr; DATA_BLOB data; printf("[%s:%d]: queue name = %s\n", __FUNCTION__, __LINE__, ((mqueue_name) ? mqueue_name : NULL)); /* Sanity checks */ MAPISTORE_RETVAL_IF(!mstore_ctx, MAPISTORE_ERR_NOT_INITIALIZED, NULL); MAPISTORE_RETVAL_IF(!nl, MAPISTORE_ERR_INVALID_PARAMETER, NULL); mqueue = mq_open(mqueue_name, O_RDONLY|O_NONBLOCK|O_CREAT, 0777, NULL); if (mqueue == -1) { perror("mq_open"); return MAPISTORE_ERR_NOT_INITIALIZED; } /* Retrieve queue attributes */ ret = mq_getattr(mqueue, &attr); if (ret == -1) { perror("mq_getattr"); /* set proper error message here and remove above */ if (mq_close(mqueue) == -1) { perror("mq_close"); } MAPISTORE_RETVAL_IF(ret == -1, MAPISTORE_ERR_NOT_FOUND, NULL); } data.data = talloc_size((TALLOC_CTX *)mstore_ctx, attr.mq_msgsize); while ((data.length = mq_receive(mqueue, (char *)data.data, attr.mq_msgsize, &prio)) != -1) { printf("* we received a notification on queue %s\n", mqueue_name); if (!nlist) { nlist = talloc_zero((TALLOC_CTX *)mstore_ctx, struct mapistore_notification_list); } el = mapistore_notification_process_mqueue_notif((TALLOC_CTX *)nlist, data); printf("* processing notification returned %p\n", el); if (el) { DLIST_ADD_END(nlist, el, struct mapistore_notification_list); } talloc_free(data.data); found = true; data.data = talloc_size((TALLOC_CTX *)mstore_ctx, attr.mq_msgsize); } talloc_free(data.data); if (found == true) { *nl = nlist; } if (mq_close(mqueue) == -1) { perror("mq_close"); } #endif return (found == false) ? MAPISTORE_ERR_NOT_FOUND : MAPISTORE_SUCCESS; } /** \details Return the list of pending mapistore notifications within the queue pointed by the mapistore subscription structure. \param mstore_ctx pointer to the mapistore context \param s pointer to the mapistore subscription where the mqueue file descriptor is stored \param nl pointer on pointer to the list of mapistore noficiations to return \return MAPISTORE_SUCCESS on success, otherwise MAPISTORE error */ _PUBLIC_ enum MAPISTATUS mapistore_get_queued_notifications(struct mapistore_context *mstore_ctx, struct mapistore_subscription *s, struct mapistore_notification_list **nl) { bool found = false; #if 0 int ret; struct mapistore_notification_list *nlist = NULL; struct mapistore_notification_list *el = NULL; unsigned int prio; struct mq_attr attr; DATA_BLOB data; DEBUG(0, ("mapistore_get_queued_notifications: queue name = %s\n", s->mqueue_name)); DEBUG(0, ("mapistore_get_queued_notifications: before sanity checks\n")); /* Sanity checks */ MAPISTORE_RETVAL_IF(!mstore_ctx, MAPISTORE_ERR_NOT_INITIALIZED, NULL); MAPISTORE_RETVAL_IF(!s, MAPISTORE_ERR_INVALID_PARAMETER, NULL); MAPISTORE_RETVAL_IF(!nl, MAPISTORE_ERR_INVALID_PARAMETER, NULL); MAPISTORE_RETVAL_IF(s->mqueue == -1, MAPISTORE_ERR_NOT_FOUND, NULL); DEBUG(0, ("mapistore_get_queued_notifications: after sanity checks\n")); /* Retrieve queue attributes */ ret = mq_getattr(s->mqueue, &attr); if (ret == -1) { perror("mq_getattr"); /* set proper error message here and remove above */ MAPISTORE_RETVAL_IF(ret == -1, MAPISTORE_ERR_NOT_FOUND, NULL); } data.data = talloc_size((TALLOC_CTX *)mstore_ctx, attr.mq_msgsize); while ((data.length = mq_receive(s->mqueue, (char *)data.data, attr.mq_msgsize, &prio)) != -1) { if (!nlist) { nlist = talloc_zero((TALLOC_CTX *)mstore_ctx, struct mapistore_notification_list); } el = mapistore_notification_process_mqueue_notif((TALLOC_CTX *)nlist, data); if (el) { DLIST_ADD_END(nlist, el, struct mapistore_notification_list); } talloc_free(data.data); found = true; data.data = talloc_size((TALLOC_CTX *)mstore_ctx, attr.mq_msgsize); } talloc_free(data.data); if (found == true) { *nl = nlist; } DEBUG(0, ("mapistore_get_queued_notification: found = %s\n", (found == false) ? "MAPISTORE_ERR_NOT_FOUND" : "MAPISTORE_SUCCESS")); #endif return (found == false) ? MAPISTORE_ERR_NOT_FOUND : MAPISTORE_SUCCESS; } #if 0 static bool notification_matches_subscription(struct mapistore_notification *notification, struct mapistore_subscription *subscription) { bool result; struct mapistore_table_notification_parameters *n_table_parameters; struct mapistore_table_subscription_parameters *s_table_parameters; struct mapistore_object_notification_parameters *n_object_parameters; struct mapistore_object_subscription_parameters *s_object_parameters; result = false; if (notification->object_type == MAPISTORE_TABLE) { if (subscription->notification_types & fnevTableModified) { n_table_parameters = ¬ification->parameters.table_parameters; if (subscription->handle == n_table_parameters->handle) { s_table_parameters = &subscription->parameters.table_parameters; result = (n_table_parameters->table_type == s_table_parameters->table_type && n_table_parameters->folder_id == s_table_parameters->folder_id); } } } else { if (((subscription->notification_types & fnevObjectCreated) && notification->event == MAPISTORE_OBJECT_CREATED) || ((subscription->notification_types & fnevObjectModified) && notification->event == MAPISTORE_OBJECT_MODIFIED) || ((subscription->notification_types & fnevObjectDeleted) && notification->event == MAPISTORE_OBJECT_DELETED) || ((subscription->notification_types & fnevObjectCopied) && notification->event == MAPISTORE_OBJECT_COPIED) || ((subscription->notification_types & fnevObjectMoved) && notification->event == MAPISTORE_OBJECT_MOVED)) { n_object_parameters = ¬ification->parameters.object_parameters; s_object_parameters = &subscription->parameters.object_parameters; if (s_object_parameters->whole_store) result = true; else { if (notification->object_type == MAPISTORE_FOLDER) { result = (n_object_parameters->object_id == s_object_parameters->folder_id); } else if (notification->object_type == MAPISTORE_MESSAGE) { result = (n_object_parameters->folder_id == s_object_parameters->folder_id && (s_object_parameters->object_id == 0 || n_object_parameters->object_id == s_object_parameters->object_id)); } else { DEBUG(5, ("[%s] warning: considering notification for unhandled object: %d...\n", __PRETTY_FUNCTION__, notification->object_type)); } } } } return result; } #endif _PUBLIC_ enum mapistore_error mapistore_delete_subscription(struct mapistore_context *mstore_ctx, uint32_t identifier, uint16_t NotificationFlags) { struct mapistore_subscription_list *el; /* Sanity checks */ MAPISTORE_RETVAL_IF(!mstore_ctx, MAPISTORE_ERR_NOT_INITIALIZED, NULL); for (el = mstore_ctx->subscriptions; el; el = el->next) { if ((el->subscription->handle == identifier) && (el->subscription->notification_types == NotificationFlags)) { DEBUG(0, ("*** DELETING SUBSCRIPTION ***\n")); DEBUG(0, ("subscription: handle = 0x%x\n", el->subscription->handle)); DEBUG(0, ("subscription: types = 0x%x\n", el->subscription->notification_types)); #if 0 DEBUG(0, ("subscription: mqueue = %d\n", el->subscription->mqueue)); DEBUG(0, ("subscription: mqueue name = %s\n", el->subscription->mqueue_name)); #endif DLIST_REMOVE(mstore_ctx->subscriptions, el); talloc_free(el); return MAPISTORE_SUCCESS; } } return MAPISTORE_ERR_NOT_FOUND; } _PUBLIC_ struct mapistore_subscription_list *mapistore_find_matching_subscriptions(struct mapistore_context *mstore_ctx, struct mapistore_notification *notification) { #if 0 struct mapistore_subscription_list *matching_subscriptions, *new_element, *current_element; if (!mstore_ctx) return NULL; matching_subscriptions = NULL; current_element = mstore_ctx->subscriptions; while (current_element) { if (notification_matches_subscription(notification, current_element->subscription)) { new_element = talloc_memdup(mstore_ctx, current_element, sizeof(struct mapistore_subscription_list)); DLIST_ADD_END(matching_subscriptions, new_element, void); } current_element = current_element->next; } return matching_subscriptions; #endif return NULL; } openchange-2.0/mapiproxy/libmapistore/mapistore_private.h000066400000000000000000000260441223057412600241220ustar00rootroot00000000000000/* OpenChange Storage Abstraction Layer library OpenChange Project Copyright (C) Julien Kerihuel 2009-2010 This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see . */ #ifndef __MAPISTORE_PRIVATE_H__ #define __MAPISTORE_PRIVATE_H__ #include #ifndef ISDOT #define ISDOT(path) ( \ *((const char *)(path)) == '.' && \ *(((const char *)(path)) + 1) == '\0' \ ) #endif #ifndef ISDOTDOT #define ISDOTDOT(path) ( \ *((const char *)(path)) == '.' && \ *(((const char *)(path)) + 1) == '.' && \ *(((const char *)(path)) + 2) == '\0' \ ) #endif struct tdb_wrap { struct tdb_context *tdb; const char *name; struct tdb_wrap *prev; struct tdb_wrap *next; }; struct ldb_wrap { struct ldb_wrap *next; struct ldb_wrap *prev; struct ldb_wrap_context { const char *url; struct tevent_context *ev; unsigned int flags; } context; struct ldb_context *ldb; }; /** Identifier mapping context. This structure stores PR_MID and PR_FID identifiers to backend identifiers mapping. It points to a database containing the used identifiers. The last_id structure member references the last identifier value which got created. There is no identifier available with a value higher than last_id. */ struct id_mapping_context { struct tdb_wrap *used_ctx; uint64_t last_id; }; /** Free context identifier list This structure is a double chained list storing unused context identifiers. */ struct context_id_list { uint32_t context_id; struct context_id_list *prev; struct context_id_list *next; }; struct processing_context { struct id_mapping_context *mapping_ctx; struct context_id_list *free_ctx; uint32_t last_context_id; uint64_t dflt_start_id; }; /** Indexing identifier list */ struct indexing_context_list { struct tdb_wrap *index_ctx; char *username; // uint32_t ref_count; struct indexing_context_list *prev; struct indexing_context_list *next; }; #define MAPISTORE_DB_NAMED "named_properties.ldb" #define MAPISTORE_DB_INDEXING "indexing.tdb" #define MAPISTORE_SOFT_DELETED_TAG "SOFT_DELETED:" struct replica_mapping_context_list { struct tdb_context *tdb; char *username; uint32_t ref_count; struct replica_mapping_context_list *prev; struct replica_mapping_context_list *next; }; #define MAPISTORE_DB_REPLICA_MAPPING "replica_mapping.tdb" /** The database name where in use ID mappings are stored */ #define MAPISTORE_DB_LAST_ID_KEY "mapistore_last_id" #define MAPISTORE_DB_LAST_ID_VAL 0x15000 #define MAPISTORE_DB_NAME_USED_ID "mapistore_id_mapping_used.tdb" /** MAPIStore management defines */ #define MAPISTORE_MQUEUE_IPC "/mapistore_ipc" #define MAPISTORE_MQUEUE_NEWMAIL_FMT "/%s#newmail" __BEGIN_DECLS /** Properties used in mapistore but not referenced anymore in MS-OXCPROPS.pdf */ #define PR_ATTACH_ID 0x3f880014 #define PR_MODIFIER_FLAGS 0x405a0003 #define PR_RECIPIENT_ON_NORMAL_MSG_COUNT 0x66af0003 /* definitions from mapistore_processing.c */ const char *mapistore_get_mapping_path(void); enum mapistore_error mapistore_init_mapping_context(struct processing_context *); enum mapistore_error mapistore_get_context_id(struct processing_context *, uint32_t *); enum mapistore_error mapistore_free_context_id(struct processing_context *, uint32_t); /* definitions from mapistore_backend.c */ enum mapistore_error mapistore_backend_init(TALLOC_CTX *, const char *); enum mapistore_error mapistore_backend_registered(const char *); enum mapistore_error mapistore_backend_list_contexts(const char *, struct tdb_wrap *, TALLOC_CTX *, struct mapistore_contexts_list **); enum mapistore_error mapistore_backend_create_context(TALLOC_CTX *, struct mapistore_connection_info *, struct tdb_wrap *, const char *, const char *, uint64_t, struct backend_context **); enum mapistore_error mapistore_backend_create_root_folder(const char *, enum mapistore_context_role, uint64_t, const char *, TALLOC_CTX *, char **); enum mapistore_error mapistore_backend_add_ref_count(struct backend_context *); enum mapistore_error mapistore_backend_delete_context(struct backend_context *); enum mapistore_error mapistore_backend_get_path(struct backend_context *, TALLOC_CTX *, uint64_t, char **); enum mapistore_error mapistore_backend_folder_open_folder(struct backend_context *, void *, TALLOC_CTX *, uint64_t, void **); enum mapistore_error mapistore_backend_folder_create_folder(struct backend_context *, void *, TALLOC_CTX *, uint64_t, struct SRow *, void **); enum mapistore_error mapistore_backend_folder_delete(struct backend_context *, void *); enum mapistore_error mapistore_backend_folder_open_message(struct backend_context *, void *, TALLOC_CTX *, uint64_t, bool, void **); enum mapistore_error mapistore_backend_folder_create_message(struct backend_context *, void *, TALLOC_CTX *, uint64_t, uint8_t, void **); enum mapistore_error mapistore_backend_folder_delete_message(struct backend_context *, void *, uint64_t, uint8_t); enum mapistore_error mapistore_backend_folder_move_copy_messages(struct backend_context *, void *, void *, TALLOC_CTX *, uint32_t, uint64_t *, uint64_t *, struct Binary_r **, uint8_t); enum mapistore_error mapistore_backend_folder_move_folder(struct backend_context *, void *, void *, TALLOC_CTX *, const char *); enum mapistore_error mapistore_backend_folder_copy_folder(struct backend_context *, void *, void *, TALLOC_CTX *, bool, const char *); enum mapistore_error mapistore_backend_folder_get_deleted_fmids(struct backend_context *, void *, TALLOC_CTX *, enum mapistore_table_type, uint64_t, struct UI8Array_r **, uint64_t *); enum mapistore_error mapistore_backend_folder_get_child_count(struct backend_context *, void *, enum mapistore_table_type, uint32_t *); enum mapistore_error mapistore_backend_folder_get_child_fid_by_name(struct backend_context *, void *, const char *, uint64_t *); enum mapistore_error mapistore_backend_folder_open_table(struct backend_context *, void *, TALLOC_CTX *, enum mapistore_table_type, uint32_t, void **, uint32_t *); enum mapistore_error mapistore_backend_folder_modify_permissions(struct backend_context *, void *, uint8_t, uint16_t, struct PermissionData *); enum mapistore_error mapistore_backend_folder_preload_message_bodies(struct backend_context *, void *, enum mapistore_table_type, const struct UI8Array_r *); enum mapistore_error mapistore_backend_message_get_message_data(struct backend_context *, void *, TALLOC_CTX *, struct mapistore_message **); enum mapistore_error mapistore_backend_message_modify_recipients(struct backend_context *, void *, struct SPropTagArray *, uint16_t, struct mapistore_message_recipient *); enum mapistore_error mapistore_backend_message_set_read_flag(struct backend_context *, void *, uint8_t); enum mapistore_error mapistore_backend_message_save(struct backend_context *, void *); enum mapistore_error mapistore_backend_message_submit(struct backend_context *, void *, enum SubmitFlags); enum mapistore_error mapistore_backend_message_get_attachment_table(struct backend_context *, void *, TALLOC_CTX *, void **, uint32_t *); enum mapistore_error mapistore_backend_message_open_attachment(struct backend_context *, void *, TALLOC_CTX *, uint32_t, void **); enum mapistore_error mapistore_backend_message_create_attachment(struct backend_context *, void *, TALLOC_CTX *, void **, uint32_t *); enum mapistore_error mapistore_backend_message_attachment_open_embedded_message(struct backend_context *, void *, TALLOC_CTX *, void **, uint64_t *, struct mapistore_message **msg); enum mapistore_error mapistore_backend_message_attachment_create_embedded_message(struct backend_context *, void *, TALLOC_CTX *, void **, struct mapistore_message **msg); enum mapistore_error mapistore_backend_table_get_available_properties(struct backend_context *, void *, TALLOC_CTX *, struct SPropTagArray **); enum mapistore_error mapistore_backend_table_set_columns(struct backend_context *, void *, uint16_t, enum MAPITAGS *); enum mapistore_error mapistore_backend_table_set_restrictions(struct backend_context *, void *, struct mapi_SRestriction *, uint8_t *); enum mapistore_error mapistore_backend_table_set_sort_order(struct backend_context *, void *, struct SSortOrderSet *, uint8_t *); enum mapistore_error mapistore_backend_table_get_row(struct backend_context *, void *, TALLOC_CTX *, enum mapistore_query_type, uint32_t, struct mapistore_property_data **); enum mapistore_error mapistore_backend_table_get_row_count(struct backend_context *, void *, enum mapistore_query_type, uint32_t *); enum mapistore_error mapistore_backend_table_handle_destructor(struct backend_context *, void *, uint32_t); enum mapistore_error mapistore_backend_properties_get_available_properties(struct backend_context *, void *, TALLOC_CTX *, struct SPropTagArray **); enum mapistore_error mapistore_backend_properties_get_properties(struct backend_context *, void *, TALLOC_CTX *, uint16_t, enum MAPITAGS *, struct mapistore_property_data *); enum mapistore_error mapistore_backend_properties_set_properties(struct backend_context *, void *, struct SRow *); enum mapistore_error mapistore_backend_manager_generate_uri(struct backend_context *, TALLOC_CTX *, const char *, const char *, const char *, const char *, char **); /* definitions from mapistore_tdb_wrap.c */ struct tdb_wrap *mapistore_tdb_wrap_open(TALLOC_CTX *, const char *, int, int, int, mode_t); /* definitions from mapistore_ldb_wrap.c */ struct ldb_context *mapistore_ldb_wrap_connect(TALLOC_CTX *, struct tevent_context *, const char *, unsigned int); /* definitions from mapistore_indexing.c */ struct indexing_context_list *mapistore_indexing_search(struct mapistore_context *, const char *); enum mapistore_error mapistore_indexing_add(struct mapistore_context *, const char *, struct indexing_context_list **); enum mapistore_error mapistore_indexing_search_existing_fmid(struct indexing_context_list *, uint64_t, bool *); enum mapistore_error mapistore_indexing_record_add(TALLOC_CTX *, struct indexing_context_list *, uint64_t, const char *); enum mapistore_error mapistore_indexing_record_add_fmid(struct mapistore_context *, uint32_t, const char *, uint64_t); enum mapistore_error mapistore_indexing_record_del_fmid(struct mapistore_context *, uint32_t, const char *, uint64_t, uint8_t); // enum mapistore_error mapistore_indexing_add_ref_count(struct indexing_context_list *); // enum mapistore_error mapistore_indexing_del_ref_count(struct indexing_context_list *); /* definitions from mapistore_namedprops.c */ enum mapistore_error mapistore_namedprops_init(TALLOC_CTX *, struct ldb_context **); __END_DECLS #endif /* ! __MAPISTORE_PRIVATE_H__ */ openchange-2.0/mapiproxy/libmapistore/mapistore_processing.c000066400000000000000000000147551223057412600246250ustar00rootroot00000000000000/* OpenChange Storage Abstraction Layer library OpenChange Project Copyright (C) Julien Kerihuel 2009-2012 This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see . */ #include #include #include #include #include #include "mapistore.h" #include "mapistore_errors.h" #include "mapistore_private.h" #include #include "libmapi/libmapi_private.h" #include char *mapping_path = NULL; /** \details Set the mapping path \param path pointer to the mapping path \note The mapping path can be set unless id_mapping_context is initialized. If path is NULL and mapping path is not yet initialized, then mapping_path will be reset to its default value when the initialization routine is called. \return MAPISTORE_SUCCESS on success, otherwise MAPISTORE error */ _PUBLIC_ enum mapistore_error mapistore_set_mapping_path(const char *path) { TALLOC_CTX *mem_ctx; DIR *dir; /* Case 1. Path is set to NULL */ if (!path) { if (mapping_path) { talloc_free(mapping_path); } mapping_path = NULL; return MAPISTORE_SUCCESS; } if (mapping_path) { talloc_free(mapping_path); mapping_path = NULL; } /* Case 2. path is initialized */ /* Step 1. Check if path is valid path */ dir = opendir(path); MAPISTORE_RETVAL_IF(!dir, MAPISTORE_ERR_NO_DIRECTORY, NULL); /* Step 2. TODO: Check for write permissions */ /* FIXME: Should have a better error name here */ MAPISTORE_RETVAL_IF(closedir(dir) == -1, MAPISTORE_ERR_NO_DIRECTORY, NULL); mem_ctx = talloc_autofree_context(); mapping_path = talloc_strdup(mem_ctx, path); return MAPISTORE_SUCCESS; } /** \details Return the current mapping path \return pointer to the mapping path. */ const char *mapistore_get_mapping_path(void) { return (const char *)mapping_path; } /** \details Initialize the ID mapping context or return the existing one if already initialized. \param pctx pointer to the processing context \return MAPISTORE_SUCCESS on success, otherwise MAPISTORE error */ enum mapistore_error mapistore_init_mapping_context(struct processing_context *pctx) { TDB_DATA key; TDB_DATA dbuf; TALLOC_CTX *mem_ctx; char *dbpath; uint64_t last_id; char *tmp_buf; int ret; /* Sanity checks */ MAPISTORE_RETVAL_IF(!pctx, MAPISTORE_ERR_NOT_INITIALIZED, NULL); MAPISTORE_RETVAL_IF(pctx->mapping_ctx, MAPISTORE_ERR_ALREADY_INITIALIZED, NULL); pctx->mapping_ctx = talloc_zero(pctx, struct id_mapping_context); MAPISTORE_RETVAL_IF(!pctx->mapping_ctx, MAPISTORE_ERR_NO_MEMORY, NULL); mem_ctx = talloc_named(NULL, 0, "mapistore_init_mapping_context"); /* Open/Create the used ID database */ if (!pctx->mapping_ctx->used_ctx) { dbpath = talloc_asprintf(mem_ctx, "%s/%s", mapistore_get_mapping_path(), MAPISTORE_DB_NAME_USED_ID); pctx->mapping_ctx->used_ctx = mapistore_tdb_wrap_open(pctx, dbpath, 0, 0, O_RDWR|O_CREAT, 0600); talloc_free(dbpath); if (!pctx->mapping_ctx->used_ctx) { DEBUG(3, ("[%s:%d]: %s\n", __FUNCTION__, __LINE__, strerror(errno))); talloc_free(mem_ctx); talloc_free(pctx->mapping_ctx); return MAPISTORE_ERR_DATABASE_INIT; } } /* Retrieve the last ID value */ key.dptr = (unsigned char *) MAPISTORE_DB_LAST_ID_KEY; key.dsize = strlen(MAPISTORE_DB_LAST_ID_KEY); dbuf = tdb_fetch(pctx->mapping_ctx->used_ctx->tdb, key); /* If the record doesn't exist, insert it */ if (!dbuf.dptr || !dbuf.dsize) { dbuf.dptr = (unsigned char *) talloc_asprintf(mem_ctx, "0x%"PRIx64, (uint64_t) MAPISTORE_DB_LAST_ID_VAL); dbuf.dsize = strlen((const char *) dbuf.dptr); last_id = MAPISTORE_DB_LAST_ID_VAL; ret = tdb_store(pctx->mapping_ctx->used_ctx->tdb, key, dbuf, TDB_INSERT); talloc_free(dbuf.dptr); if (ret == -1) { DEBUG(3, ("[%s:%d]: Unable to create %s record: %s\n", __FUNCTION__, __LINE__, MAPISTORE_DB_LAST_ID_KEY, tdb_errorstr(pctx->mapping_ctx->used_ctx->tdb))); talloc_free(mem_ctx); talloc_free(pctx->mapping_ctx); return MAPISTORE_ERR_DATABASE_OPS; } } else { tmp_buf = talloc_strndup(mem_ctx, (char *)dbuf.dptr, dbuf.dsize); free(dbuf.dptr); last_id = strtoull(tmp_buf, NULL, 16); talloc_free(tmp_buf); } pctx->mapping_ctx->last_id = last_id; talloc_free(mem_ctx); return MAPISTORE_SUCCESS; } /** \details Return an unused or new context identifier \param pctx pointer to the processing context \param context_id pointer to the context identifier the function returns \return a non zero context identifier on success, otherwise 0. */ enum mapistore_error mapistore_get_context_id(struct processing_context *pctx, uint32_t *context_id) { struct context_id_list *el; /* Sanity checks */ MAPISTORE_RETVAL_IF(!pctx, MAPISTORE_ERR_NOT_INITIALIZED, NULL); /* Step 1. The free context list doesn't exist yet */ if (!pctx->free_ctx) { pctx->last_context_id++; *context_id = pctx->last_context_id; } /* Step 2. We have a free list */ for (el = pctx->free_ctx; el; el = el->next) { if (el->context_id) { *context_id = el->context_id; DLIST_REMOVE(pctx->free_ctx, el); break; } } return MAPISTORE_SUCCESS; } /** \details Add a context identifier to the list \param pctx pointer to the processing context \param context_id the identifier referencing the context to free \return MAPISTORE_SUCCESS on success, otherwise MAPISTORE error */ enum mapistore_error mapistore_free_context_id(struct processing_context *pctx, uint32_t context_id) { struct context_id_list *el; /* Sanity checks */ MAPISTORE_RETVAL_IF(!pctx, MAPISTORE_ERR_NOT_INITIALIZED, NULL); /* Step 1. Ensure the list is not corrupted */ for (el = pctx->free_ctx; el; el = el->next) { if (el->context_id == context_id) { return MAPISTORE_ERR_CORRUPTED; } } /* Step 2. Create the element and add it to the list */ el = talloc_zero((TALLOC_CTX *)pctx, struct context_id_list); el->context_id = context_id; DLIST_ADD_END(pctx->free_ctx, el, struct context_id_list *); return MAPISTORE_SUCCESS; } openchange-2.0/mapiproxy/libmapistore/mapistore_replica_mapping.c000066400000000000000000000233401223057412600255710ustar00rootroot00000000000000/* OpenChange Storage Abstraction Layer library OpenChange Project Copyright (C) Wolfgang Sourdeau 2011 This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see . */ #include #include "mapistore.h" #include "mapistore_errors.h" #include "mapistore_private.h" #include #include "libmapi/libmapi_private.h" #include static void mapistore_replica_mapping_set_next_replid(struct tdb_context *, uint16_t); static uint16_t mapistore_replica_mapping_get_next_replid(struct tdb_context *); /* Special repl ids: - 0x01 is for server replica - 0x02 is for GetLocalReplicaIDs */ /** \details Search the replica_mapping record matching the username \param mstore_ctx pointer to the mapistore context \param username the username to lookup \return pointer to the tdb_wrap structure on success, otherwise NULL */ static struct replica_mapping_context_list *mapistore_replica_mapping_search(struct mapistore_context *mstore_ctx, const char *username) { struct replica_mapping_context_list *el; /* Sanity checks */ if (!mstore_ctx) return NULL; if (!mstore_ctx->replica_mapping_list) return NULL; if (!username) return NULL; for (el = mstore_ctx->replica_mapping_list; el; el = el->next) { if (el && el->username && !strcmp(el->username, username)) { return el; } } return NULL; } /** \details Open connection to replica_mapping database for a given user \param mstore_ctx pointer to the mapistore context \param username name for which the replica_mapping database has to be created \return MAPISTORE_SUCCESS on success, otherwise MAPISTORE error */ static int context_list_destructor(struct replica_mapping_context_list *rmctx) { tdb_close(rmctx->tdb); return 1; } _PUBLIC_ enum mapistore_error mapistore_replica_mapping_add(struct mapistore_context *mstore_ctx, const char *username, struct replica_mapping_context_list **rmctxp) { TALLOC_CTX *mem_ctx; struct replica_mapping_context_list *rmctx; char *dbpath = NULL; /* Sanity checks */ MAPISTORE_RETVAL_IF(!mstore_ctx, MAPISTORE_ERR_NOT_INITIALIZED, NULL); MAPISTORE_RETVAL_IF(!username, MAPISTORE_ERROR, NULL); /* Step 1. Search if the context already exists */ rmctx = mapistore_replica_mapping_search(mstore_ctx, username); *rmctxp = rmctx; MAPISTORE_RETVAL_IF(rmctx, MAPISTORE_SUCCESS, NULL); mem_ctx = talloc_named(NULL, 0, "mapistore_replica_mapping_init"); rmctx = talloc_zero(mstore_ctx->replica_mapping_list, struct replica_mapping_context_list); /* Step 1. Open/Create the replica_mapping database */ dbpath = talloc_asprintf(mem_ctx, "%s/%s/" MAPISTORE_DB_REPLICA_MAPPING, mapistore_get_mapping_path(), username); rmctx->tdb = tdb_open(dbpath, 0, 0, O_RDWR|O_CREAT, 0600); if (!rmctx->tdb) { DEBUG(3, ("[%s:%d]: %s (%s)\n", __FUNCTION__, __LINE__, strerror(errno), dbpath)); talloc_free(rmctx); talloc_free(mem_ctx); return MAPISTORE_ERR_DATABASE_INIT; } talloc_set_destructor(rmctx, context_list_destructor); rmctx->username = talloc_strdup(rmctx, username); rmctx->ref_count = 0; DLIST_ADD_END(mstore_ctx->replica_mapping_list, rmctx, struct replica_mapping_context_list *); *rmctxp = rmctx; talloc_free(mem_ctx); return MAPISTORE_SUCCESS; } /* _PUBLIC_ enum mapistore_error mapistore_replica_mapping_add(struct mapistore_context *mstore_ctx, const char *username) */ /* { */ /* TALLOC_CTX *mem_ctx; */ /* char *dbpath = NULL; */ /* /\* Sanity checks *\/ */ /* MAPISTORE_RETVAL_IF(!mstore_ctx, MAPISTORE_ERR_NOT_INITIALIZED, NULL); */ /* MAPISTORE_RETVAL_IF(!username, MAPISTORE_ERROR, NULL); */ /* mem_ctx = talloc_named(NULL, 0, "mapistore_replica_mapping_add"); */ /* /\* Step 1. Open/Create the replica_mapping database *\/ */ /* dbpath = talloc_asprintf(mem_ctx, "%s/%s/" MAPISTORE_DB_REPLICA_MAPPING, */ /* mapistore_get_mapping_path(), username); */ /* mstore_ctx->replica_mapping_ctx = tdb_wrap_open(mstore_ctx, dbpath, 0, 0, O_RDWR|O_CREAT, 0600); */ /* talloc_free(dbpath); */ /* if (!mstore_ctx->replica_mapping_ctx) { */ /* DEBUG(3, ("[%s:%d]: %s\n", __FUNCTION__, __LINE__, strerror(errno))); */ /* talloc_free(mem_ctx); */ /* return MAPISTORE_ERR_DATABASE_INIT; */ /* } */ /* if (mapistore_replica_mapping_get_next_replid(mstore_ctx->replica_mapping_ctx->tdb) == 0xffff) { */ /* mapistore_replica_mapping_set_next_replid(mstore_ctx->replica_mapping_ctx->tdb, 0x3); */ /* } */ /* talloc_free(mem_ctx); */ /* return MAPI_E_SUCCESS; */ /* } */ static void mapistore_replica_mapping_set_next_replid(struct tdb_context *tdb, uint16_t replid) { TDB_DATA key; TDB_DATA replid_data; void *mem_ctx; int ret, op; mem_ctx = talloc_zero(NULL, void); /* GUID to ReplID */ key.dptr = (unsigned char *) "next_replid"; key.dsize = strlen((const char *) key.dptr); replid_data.dptr = (unsigned char *) talloc_asprintf(mem_ctx, "0x%.4x", replid); replid_data.dsize = strlen((const char *) replid_data.dptr); ret = tdb_exists(tdb, key); op = (ret) ? TDB_MODIFY : TDB_INSERT; tdb_store(tdb, key, replid_data, op); talloc_free(mem_ctx); } static uint16_t mapistore_replica_mapping_get_next_replid(struct tdb_context *tdb) { TDB_DATA key; TDB_DATA replid_data; int ret; char *tmp_data; uint16_t replid; /* GUID to ReplID */ key.dptr = (unsigned char *) "next_replid"; key.dsize = strlen((const char *) key.dptr); ret = tdb_exists(tdb, key); if (!ret) { return 0xffff; } replid_data = tdb_fetch(tdb, key); tmp_data = talloc_strndup(NULL, (char *) replid_data.dptr, replid_data.dsize); replid = strtoul(tmp_data, NULL, 16); talloc_free(tmp_data); return replid; } static void mapistore_replica_mapping_add_pair(struct tdb_context *tdb, const struct GUID *guidP, uint16_t replid) { TDB_DATA guid_key; TDB_DATA replid_key; void *mem_ctx; mem_ctx = talloc_zero(NULL, void); /* GUID to ReplID */ guid_key.dptr = (unsigned char *) GUID_string(mem_ctx, guidP); guid_key.dsize = strlen((const char *) guid_key.dptr); replid_key.dptr = (unsigned char *) talloc_asprintf(mem_ctx, "0x%.4x", replid); replid_key.dsize = strlen((const char *) replid_key.dptr); tdb_store(tdb, guid_key, replid_key, TDB_INSERT); tdb_store(tdb, replid_key, guid_key, TDB_INSERT); talloc_free(mem_ctx); } static enum mapistore_error mapistore_replica_mapping_search_guid(struct tdb_context *tdb, const struct GUID *guidP, uint16_t *replidP) { TDB_DATA guid_key; TDB_DATA replid_key; void *mem_ctx; int ret; mem_ctx = talloc_zero(NULL, void); guid_key.dptr = (unsigned char *) GUID_string(mem_ctx, guidP); guid_key.dsize = strlen((const char *) guid_key.dptr); ret = tdb_exists(tdb, guid_key); if (!ret) { talloc_free(mem_ctx); return MAPISTORE_ERROR; } replid_key = tdb_fetch(tdb, guid_key); *replidP = strtoul((char *) replid_key.dptr + 2, NULL, 16); talloc_free(mem_ctx); return MAPISTORE_SUCCESS; } /** \details Search a replica guid in the database, creates it if it does not exist \param mstore_ctx pointer to the mapistore context \param guidP the replica guid \param replidP pointer to the returned replica id \return MAPISTORE_SUCCESS on success, otherwise MAPISTORE error */ _PUBLIC_ enum mapistore_error mapistore_replica_mapping_guid_to_replid(struct mapistore_context *mstore_ctx, const char *username, const struct GUID *guidP, uint16_t *replidP) { int ret; uint16_t new_replid; struct replica_mapping_context_list *list; ret = mapistore_replica_mapping_add(mstore_ctx, username, &list); MAPISTORE_RETVAL_IF(ret, MAPISTORE_ERROR, NULL); MAPISTORE_RETVAL_IF(!list, MAPISTORE_ERROR, NULL); ret = mapistore_replica_mapping_search_guid(list->tdb, guidP, replidP); if (ret == MAPISTORE_SUCCESS) { return ret; } new_replid = mapistore_replica_mapping_get_next_replid(list->tdb); if (new_replid == 0xffff) { /* should never occur */ DEBUG(0, ("%s: FATAL: next replica id is not configured for this database\n", __FUNCTION__)); return MAPISTORE_ERROR; } mapistore_replica_mapping_add_pair(list->tdb, guidP, new_replid); mapistore_replica_mapping_set_next_replid(list->tdb, new_replid + 1); *replidP = new_replid; return MAPISTORE_SUCCESS; } /** \details Search a replica id in the database \param mstore_ctx pointer to the mapistore context \param replid the replica id \param guidP pointer to the returned replica guid \return MAPISTORE_SUCCESS on success, otherwise MAPISTORE error */ _PUBLIC_ enum mapistore_error mapistore_replica_mapping_replid_to_guid(struct mapistore_context *mstore_ctx, const char *username, uint16_t replid, struct GUID *guidP) { void *mem_ctx; TDB_DATA guid_key, replid_key; int ret; struct replica_mapping_context_list *list; ret = mapistore_replica_mapping_add(mstore_ctx, username, &list); MAPISTORE_RETVAL_IF(ret, MAPISTORE_ERROR, NULL); MAPISTORE_RETVAL_IF(!list, MAPISTORE_ERROR, NULL); mem_ctx = talloc_zero(NULL, void); replid_key.dptr = (unsigned char *) talloc_asprintf(mem_ctx, "0x%.4x", replid); replid_key.dsize = strlen((const char *) replid_key.dptr); ret = tdb_exists(list->tdb, replid_key); if (!ret) { talloc_free(mem_ctx); return MAPISTORE_ERROR; } guid_key = tdb_fetch(list->tdb, replid_key); GUID_from_string((char *) guid_key.dptr, guidP); talloc_free(mem_ctx); return MAPISTORE_SUCCESS; } openchange-2.0/mapiproxy/libmapistore/mapistore_tdb_wrap.c000066400000000000000000000057471223057412600242540ustar00rootroot00000000000000/* Unix SMB/CIFS implementation. TDB wrap functions Copyright (C) Andrew Tridgell 2004 Copyright (C) Jelmer Vernooij 2007 This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see . */ #include "config.h" #include #include #include "mapistore.h" #include "mapistore_private.h" #include static struct tdb_wrap *tdb_list; /* destroy the last connection to a tdb */ static int mapistore_tdb_wrap_destructor(struct tdb_wrap *w) { tdb_close(w->tdb); DLIST_REMOVE(tdb_list, w); return 0; } /* Log tdb messages via DEBUG(). */ static void mapistore_tdb_wrap_log(TDB_CONTEXT *tdb, enum tdb_debug_level level, const char *format, ...) PRINTF_ATTRIBUTE(3,4); static void mapistore_tdb_wrap_log(TDB_CONTEXT *tdb, enum tdb_debug_level level, const char *format, ...) { va_list ap; char *ptr = NULL; int dl; va_start(ap, format); vasprintf(&ptr, format, ap); va_end(ap); switch (level) { case TDB_DEBUG_FATAL: dl = 0; break; case TDB_DEBUG_ERROR: dl = 1; break; case TDB_DEBUG_WARNING: dl = 2; break; case TDB_DEBUG_TRACE: dl = 5; break; default: dl = 0; } if (ptr != NULL) { const char *name = tdb_name(tdb); DEBUG(dl, ("tdb(%s): %s", name ? name : "unnamed", ptr)); free(ptr); } } /** \details wrapped connection to a tdb database \param mem_ctx pointer to the memory context \param name tdb database name \param hash_size the hash size \param tdb_flags TDB flags \param open_flags open flags \param mode \note to close just talloc_free() the tdb_wrap pointer \return pointer to an allocated tdb_wrap structure on success, otherwise NULL */ struct tdb_wrap *mapistore_tdb_wrap_open(TALLOC_CTX *mem_ctx, const char *name, int hash_size, int tdb_flags, int open_flags, mode_t mode) { struct tdb_wrap *w; struct tdb_logging_context log_ctx; log_ctx.log_fn = mapistore_tdb_wrap_log; for (w = tdb_list; w; w = w->next) { if (strcmp(name, w->name) == 0) { return talloc_reference(mem_ctx, w); } } w = talloc(mem_ctx, struct tdb_wrap); if (w == NULL) { return NULL; } w->name = talloc_strdup(w, name); w->tdb = tdb_open_ex(name, hash_size, tdb_flags, open_flags, mode, &log_ctx, NULL); if (w->tdb == NULL) { talloc_free(w); return NULL; } talloc_set_destructor(w, mapistore_tdb_wrap_destructor); DLIST_ADD(tdb_list, w); return w; } openchange-2.0/mapiproxy/libmapistore/mgmt/000077500000000000000000000000001223057412600211525ustar00rootroot00000000000000openchange-2.0/mapiproxy/libmapistore/mgmt/mapistore_mgmt.c000066400000000000000000000621051223057412600243510ustar00rootroot00000000000000/* OpenChange Storage Abstraction Layer library OpenChange Project Copyright (C) Julien Kerihuel 2011 This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see . */ /** \file mapistore_mgmt.c \brief Provides mapistore management routine for administrative/services tools. Using this interface virtually restrict mapistore features to the specific management functions subset. */ #include "mapiproxy/libmapistore/mapistore.h" #include "mapiproxy/libmapistore/mapistore_errors.h" #include "mapiproxy/libmapistore/mapistore_private.h" #include "mapiproxy/libmapistore/mgmt/mapistore_mgmt.h" #include "mapiproxy/libmapistore/mgmt/gen_ndr/ndr_mapistore_mgmt.h" static void mgmt_ipc_process_notif(struct mapistore_mgmt_context *mgmt_ctx, DATA_BLOB data) { struct mapistore_mgmt_command command; struct ndr_pull *ndr_pull = NULL; ndr_pull = ndr_pull_init_blob(&data, (TALLOC_CTX *)mgmt_ctx); ndr_pull_mapistore_mgmt_command(ndr_pull, NDR_SCALARS|NDR_BUFFERS, &command); if (mgmt_ctx->verbose == true) { struct ndr_print *ndr_print; ndr_print = talloc_zero((TALLOC_CTX *)mgmt_ctx, struct ndr_print); ndr_print->print = ndr_print_printf_helper; ndr_print->depth = 1; ndr_print_mapistore_mgmt_command(ndr_print, "command", &command); talloc_free(ndr_print); } switch (command.type) { case MAPISTORE_MGMT_USER: mapistore_mgmt_message_user_command(mgmt_ctx, command.command.user); break; case MAPISTORE_MGMT_BIND: printf("switch_case: MAPISTORE_MGMT_BIND\n"); mapistore_mgmt_message_bind_command(mgmt_ctx, command.command.bind); break; case MAPISTORE_MGMT_NOTIF: mapistore_mgmt_message_notification_command(mgmt_ctx, command.command.notification); break; default: DEBUG(0, ("[%s:%d]: Invalid command type: %d\n", __FUNCTION__, __LINE__, command.type)); break; } talloc_free(ndr_pull); } #if 0 static void mgmt_ipc_notif_handler(int signo, siginfo_t *info, void *unused) { struct mapistore_mgmt_context *mgmt_ctx; struct mq_attr attr; struct sigevent se; DATA_BLOB data; unsigned int prio; mgmt_ctx = (struct mapistore_mgmt_context *)info->si_value.sival_ptr; if (mq_getattr(mgmt_ctx->mq_ipc, &attr) != 0) { perror("mq_getattr"); return; } data.data = talloc_size(mgmt_ctx, attr.mq_msgsize); data.length = mq_receive(mgmt_ctx->mq_ipc, (char *)data.data, attr.mq_msgsize, &prio); if (data.length == -1) { talloc_free(data.data); perror("mq_receive"); return; } mgmt_ipc_process_notif(mgmt_ctx, data); talloc_free(data.data); /* Reset notification as it resets each time */ se.sigev_signo = info->si_signo; se.sigev_value = info->si_value; se.sigev_notify = SIGEV_SIGNAL; if (mq_notify(mgmt_ctx->mq_ipc, &se) == -1) { perror("mq_notify"); return; } data.data = talloc_size(mgmt_ctx, attr.mq_msgsize); while ((data.length = mq_receive(mgmt_ctx->mq_ipc, (char *)data.data, attr.mq_msgsize, NULL)) != -1) { if (data.length == -1) { talloc_free(data.data); return; } else { mgmt_ipc_process_notif(mgmt_ctx, data); talloc_free(data.data); data.data = talloc_size(mgmt_ctx, attr.mq_msgsize); } } talloc_free(data.data); } #endif /** \details Initialize a mapistore manager context. \param mstore_ctx Pointer to an existing mapistore_context \return allocated mapistore_mgmt context on success, otherwise NULL */ _PUBLIC_ struct mapistore_mgmt_context *mapistore_mgmt_init(struct mapistore_context *mstore_ctx) { struct mapistore_mgmt_context *mgmt_ctx; int ret; unsigned int prio; DATA_BLOB data; struct mq_attr attr; /* struct sigaction sa; struct sigevent se; */ if (!mstore_ctx) return NULL; mgmt_ctx = talloc_zero(mstore_ctx, struct mapistore_mgmt_context); if (!mgmt_ctx) { return NULL; } mgmt_ctx->mstore_ctx = mstore_ctx; mgmt_ctx->verbose = false; mgmt_ctx->users = NULL; mgmt_ctx->mq_ipc = mq_open(MAPISTORE_MQUEUE_IPC, O_RDONLY|O_NONBLOCK|O_CREAT, 0755, NULL); if (mgmt_ctx->mq_ipc == -1) { perror("mq_open"); talloc_free(mgmt_ctx); return NULL; } /* Setup asynchronous notification request on this message queue */ /** TODO: fix signal handler before restoring this code sa.sa_sigaction = mgmt_ipc_notif_handler; sigemptyset(&sa.sa_mask); sa.sa_flags = SA_SIGINFO; if (sigaction(SIGIO, &sa, NULL) == -1) { perror("sigaction"); talloc_free(mgmt_ctx); return NULL; } se.sigev_notify = SIGEV_SIGNAL; se.sigev_signo = SIGIO; se.sigev_value.sival_ptr = (void *) mgmt_ctx; if (mq_notify(mgmt_ctx->mq_ipc, &se) == -1) { perror("mq_notify"); talloc_free(mgmt_ctx); return NULL; } */ /* Empty queue since new notification only occurs flushed/empty queue */ ret = mq_getattr(mgmt_ctx->mq_ipc, &attr); if (ret == -1) { perror("mq_getattr"); return mgmt_ctx; } data.data = talloc_size(mgmt_ctx, attr.mq_msgsize); while ((data.length = mq_receive(mgmt_ctx->mq_ipc, (char *)data.data, attr.mq_msgsize, &prio)) != -1) { mgmt_ipc_process_notif(mgmt_ctx, data); talloc_free(data.data); data.data = talloc_size(mgmt_ctx, attr.mq_msgsize); } talloc_free(data.data); return mgmt_ctx; } /** \details Release the mapistore management context and destory any data associated. \param mgmt_ctx pointer to the mapistore management context \return MAPISTORE_SUCCESS on success, otherwise MAPISTORE error */ _PUBLIC_ enum mapistore_error mapistore_mgmt_release(struct mapistore_mgmt_context *mgmt_ctx) { /* Sanity checks */ MAPISTORE_RETVAL_IF(!mgmt_ctx, MAPISTORE_ERR_NOT_INITIALIZED, NULL); MAPISTORE_RETVAL_IF(!mgmt_ctx->mstore_ctx, MAPISTORE_ERR_NOT_INITIALIZED, NULL); if (mq_close(mgmt_ctx->mq_ipc) == -1) { perror("mq_close"); talloc_free(mgmt_ctx); return MAPISTORE_SUCCESS; } if (mq_unlink(MAPISTORE_MQUEUE_IPC) == -1) { perror("mq_unlink"); } talloc_free(mgmt_ctx); return MAPISTORE_SUCCESS; } /** \details Set mapistore management verbosity \param mgmt_ctx pointer to the mapistore management context \param verbose boolean value that sets or unset verbosity \return MAPISTORE_SUCCESS on success, otherwise MAPISTORE error */ _PUBLIC_ enum mapistore_error mapistore_mgmt_set_verbosity(struct mapistore_mgmt_context *mgmt_ctx, bool verbose) { /* Sanity checks */ MAPISTORE_RETVAL_IF(!mgmt_ctx, MAPISTORE_ERR_NOT_INITIALIZED, NULL); mgmt_ctx->verbose = verbose; return MAPISTORE_SUCCESS; } /** \details Check if the specified backend is registered in mapistore \param mgmt_ctx pointer to the mapistore management context \param backend pointer to the backend name \return MAPISTORE_SUCCESS on success, otherwise MAPISTORE error */ _PUBLIC_ enum mapistore_error mapistore_mgmt_registered_backend(struct mapistore_mgmt_context *mgmt_ctx, const char *backend) { /* Sanity checks */ MAPISTORE_RETVAL_IF(backend == NULL, MAPISTORE_ERR_INVALID_PARAMETER, NULL); MAPISTORE_RETVAL_IF(mgmt_ctx == NULL, MAPISTORE_ERR_INVALID_PARAMETER, NULL); MAPISTORE_RETVAL_IF(mgmt_ctx->mstore_ctx == NULL, MAPISTORE_ERR_INVALID_PARAMETER, NULL); return mapistore_backend_registered(backend); } #if 0 static int mgmt_user_registration_cmd(enum mapistore_mgmt_status status, unsigned msg_prio, struct mapistore_connection_info *conn_info, const char *backend, const char *vuser) { int ret; TALLOC_CTX *mem_ctx; DATA_BLOB data; struct mapistore_mgmt_command cmd; enum ndr_err_code ndr_err; /* Sanity checks */ MAPISTORE_RETVAL_IF(!conn_info, MAPISTORE_ERR_NOT_INITIALIZED, NULL); MAPISTORE_RETVAL_IF(!conn_info->mstore_ctx, MAPISTORE_ERR_NOT_INITIALIZED, NULL); MAPISTORE_RETVAL_IF(!conn_info->username, MAPISTORE_ERR_NOT_INITIALIZED, NULL); MAPISTORE_RETVAL_IF(!backend, MAPISTORE_ERR_INVALID_PARAMETER, NULL); MAPISTORE_RETVAL_IF(!vuser, MAPISTORE_ERR_INVALID_PARAMETER, NULL); cmd.type = MAPISTORE_MGMT_USER; cmd.command.user.status = status; cmd.command.user.backend = backend; cmd.command.user.username = conn_info->username; cmd.command.user.vuser = vuser; mem_ctx = talloc_new(NULL); ndr_err = ndr_push_struct_blob(&data, mem_ctx, &cmd, (ndr_push_flags_fn_t)ndr_push_mapistore_mgmt_command); if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) { DEBUG(0, ("! [%s:%d][%s]: Failed to push mapistore_mgmt_command into NDR blob\n", __FILE__, __LINE__, __FUNCTION__)); talloc_free(mem_ctx); return MAPISTORE_ERR_INVALID_DATA; } ret = mq_send(conn_info->mstore_ctx->mq_ipc, (const char *)data.data, data.length, msg_prio); if (ret == -1) { talloc_free(mem_ctx); return MAPISTORE_ERR_MSG_SEND; } talloc_free(mem_ctx); return MAPISTORE_SUCCESS; } #endif /** \details Retrieve the list of registered usernames \param mgmt_ctx pointer to the mapistore management context \param backend the name of the backend to lookup \param vuser the name of the virtual user to lookup \return Allocated mapistore management user list on success, otherwise NULL */ _PUBLIC_ struct mapistore_mgmt_users_list *mapistore_mgmt_registered_users(struct mapistore_mgmt_context *mgmt_ctx, const char *backend, const char *vuser) { struct mapistore_mgmt_users_list *ulist = NULL; struct mapistore_mgmt_users *el; bool found = false; int i; /* Sanity checks */ if (!mgmt_ctx) return NULL; if (!mgmt_ctx->users) return NULL; if (!backend) return NULL; if (!vuser) return NULL; ulist = talloc_zero((TALLOC_CTX *)mgmt_ctx, struct mapistore_mgmt_users_list); ulist->count = 0; ulist->user = (const char **) talloc_array((TALLOC_CTX *)ulist, char *, ulist->count + 1); for (el = mgmt_ctx->users; el; el = el->next) { if (!strcmp(el->info->backend, backend) && !strcmp(el->info->vuser, vuser)) { /* Check if the user hasn't already been inserted */ for (i = 0; i != ulist->count; i++) { if (ulist->user && !strcmp(ulist->user[i], el->info->username)) { found = true; break; } } if (found == false) { ulist->user = (const char **) talloc_realloc(ulist->user, ulist->user, char *, ulist->count + 1); ulist->user[ulist->count] = talloc_strdup((TALLOC_CTX *) ulist->user, el->info->username); ulist->count += 1; } } } return (ulist); } /** \details Register the mapping between a system user and a backend user for a specific backend. \param conn_info pointer to the connection information \param backend the name of the backend \param vuser the name of the matching user in the backend \return MAPISTORE_SUCCESS on success, otherwise MAPISTORE error */ #if 0 _PUBLIC_ enum mapistore_error mapistore_mgmt_backend_register_user(struct mapistore_connection_info *conn_info, const char *backend, const char *vuser) { return mgmt_user_registration_cmd(MAPISTORE_MGMT_REGISTER, MAPISTORE_COMMAND_USER_REGISTER_PRIO, conn_info, backend, vuser); } #endif /** \details Unregister the mapping between a system user and a backend user for a specific backend. \param conn_info pointer to the connection information \param backend the name of the backend \param vuser the name of the matching user in the backend \return MAPISTORE_SUCCESS on success, otherwise MAPISTORE error */ #if 0 _PUBLIC_ enum mapistore_error mapistore_mgmt_backend_unregister_user(struct mapistore_connection_info *conn_info, const char *backend, const char *vuser) { return mgmt_user_registration_cmd(MAPISTORE_MGMT_UNREGISTER, MAPISTORE_COMMAND_USER_UNREGISTER_PRIO, conn_info, backend, vuser); } #endif /** \details Retrieves a partial or complete URI from the backend depending on the specified parameters. This function is used by the mapistore management interface to get from backend either the expected URI for further registration or a partial (backend compliant) URI for partial search. \param mgmt_ctx Pointer to the mapistore management context \param backend the name of the backend \param username the name of the user in the backend \param folder the name of the folder in the backend \param message the name of the message in the backend \param uri pointer on pointer to the URI to return \note The returned uri is allocated and needs to be free'd using talloc_free() upon end of use. \return MAPISTORE_SUCCESS on success, otherwise MAPISTORE error */ _PUBLIC_ enum mapistore_error mapistore_mgmt_generate_uri(struct mapistore_mgmt_context *mgmt_ctx, const char *backend, const char *username, const char *folder, const char *message, const char *rootURI, char **uri) { struct backend_context *backend_ctx; /* Sanity checks */ MAPISTORE_RETVAL_IF(!mgmt_ctx, MAPISTORE_ERR_NOT_INITIALIZED, NULL); MAPISTORE_RETVAL_IF(!rootURI && !backend, MAPISTORE_ERR_INVALID_PARAMETER, NULL); MAPISTORE_RETVAL_IF(!uri, MAPISTORE_ERR_INVALID_PARAMETER, NULL); backend_ctx = mapistore_backend_lookup_by_name((TALLOC_CTX *)mgmt_ctx, backend); MAPISTORE_RETVAL_IF(!backend_ctx, MAPISTORE_ERR_INVALID_PARAMETER, NULL); mapistore_backend_manager_generate_uri(backend_ctx, (TALLOC_CTX *)mgmt_ctx, username, folder, message, rootURI, uri); /* We are not really deleting a context, but freeing the * allocated memory to backend_ctx */ mapistore_backend_delete_context(backend_ctx); return MAPISTORE_SUCCESS; } /** \details Check if a message is already registered within indexing database for the user. \param mgmt_ctx Pointer to the mapistore management context \param backend the name of the backend \param sysuser the name of the mapistore user (openchange) \param username the name of the user on the remote system the backend manages \param folder the name of the folder on the remote system the backend manages \param message the name of the message on the remote system the backend manages \return true if the message is registered, otherwise false */ _PUBLIC_ enum mapistore_error mapistore_mgmt_registered_message(struct mapistore_mgmt_context *mgmt_ctx, const char *backend, const char *sysuser, const char *username, const char *folder, const char *rootURI, const char *message) { struct indexing_context_list *ictxp; char *uri; int ret; uint64_t mid; bool retval; bool softdeleted; ret = mapistore_mgmt_generate_uri(mgmt_ctx, backend, username, folder, message, rootURI, &uri); if (ret != MAPISTORE_SUCCESS) return false; ret = mapistore_indexing_add(mgmt_ctx->mstore_ctx, sysuser, &ictxp); if (ret != MAPISTORE_SUCCESS) { talloc_free(uri); return false; } if (rootURI) { ret = mapistore_indexing_record_get_fmid(mgmt_ctx->mstore_ctx, sysuser, uri, false, &mid, &softdeleted); } else { ret = mapistore_indexing_record_get_fmid(mgmt_ctx->mstore_ctx, sysuser, uri, true, &mid, &softdeleted); } if (ret == MAPISTORE_SUCCESS) { retval = true; } else { retval = false; } talloc_free(uri); return retval; } /** \details Register a message in the indexing database of the user \param mgmt_ctx Pointer to the mapistore management context \param backend the backend for which we register the message \param sysuser the name of the openchage user \param mid the message ID to register \param uri partial URI without message extension \param messageID the message identifier in the backend \param registered_uri pointer on pointer to the registered MAPIStore URI \return MAPISTORE_SUCCESS on success, otherwise MAPISTORE error */ _PUBLIC_ enum mapistore_error mapistore_mgmt_register_message(struct mapistore_mgmt_context *mgmt_ctx, const char *backend, const char *sysuser, uint64_t mid, const char *rootURI, const char *messageID, char **registered_uri) { struct indexing_context_list *ictxp; int ret; char *uri; ret = mapistore_mgmt_generate_uri(mgmt_ctx, backend, NULL, NULL, messageID, rootURI, &uri); MAPISTORE_RETVAL_IF(ret, ret, NULL); DEBUG(0, ("mapistore_mgmt_register_message: %s for user %s\n", uri, sysuser)); ret = mapistore_indexing_add(mgmt_ctx->mstore_ctx, sysuser, &ictxp); MAPISTORE_RETVAL_IF(ret, ret, uri); ret = mapistore_indexing_record_add(mgmt_ctx, ictxp, mid, uri); MAPISTORE_RETVAL_IF(ret, ret, uri); *registered_uri = uri; return MAPISTORE_SUCCESS; } /** \details Check if the subscription described by NotificationFlags has been registered for specified folder. \param mgmt_ctx pointer to the mapistore management context \param username the username to lookup \param folderURI the mapistore URI to lookup \param NotificationFlags the subscription type \return MAPISTORE_SUCCESS on success, otherwise MAPISTORE error */ _PUBLIC_ enum mapistore_error mapistore_mgmt_registered_folder_subscription(struct mapistore_mgmt_context *mgmt_ctx, const char *username, const char *folderURI, uint16_t NotificationFlags) { struct mapistore_mgmt_users *uel; struct mapistore_mgmt_notif *el; bool found = false; printf("Looking for 0x%x\n", NotificationFlags); /* Sanity checks */ MAPISTORE_RETVAL_IF(!mgmt_ctx, MAPISTORE_ERR_NOT_INITIALIZED, NULL); MAPISTORE_RETVAL_IF(!mgmt_ctx->users, MAPISTORE_ERR_NOT_FOUND, NULL); MAPISTORE_RETVAL_IF(!username, MAPISTORE_ERR_INVALID_PARAMETER, NULL); /* MAPISTORE_RETVAL_IF(!folderURI, MAPISTORE_ERR_INVALID_PARAMETER, NULL); */ if (!folderURI) { for (uel = mgmt_ctx->users; uel; uel = uel->next) { if (uel->info->username && !strcmp(uel->info->username, username)) { if (uel->notifications) { for (el = uel->notifications; el; el = el->next) { if ((el->WholeStore == true) && (el->NotificationFlags & NotificationFlags)) { DEBUG(0, ("[%s:%d]: WholeStore matching subscription found for 0x%x\n", __FUNCTION__, __LINE__, NotificationFlags)); found = true; goto end; } } } } } } for (uel = mgmt_ctx->users; uel; uel = uel->next) { if (uel->info->username && !strcmp(uel->info->username, username)) { if (uel->notifications) { for (el = uel->notifications; el; el = el->next) { if (!el->MessageID && el->MAPIStoreURI && !strcmp(el->MAPIStoreURI, folderURI) && (el->NotificationFlags & NotificationFlags)) { DEBUG(0, ("[%s:%d]: Subscription found\n", __FUNCTION__, __LINE__)); found = true; goto end; } else if ((el->WholeStore == true) && (el->NotificationFlags & NotificationFlags)) { DEBUG(0, ("[%s:%d]: WholeStore matching subscription found\n", __FUNCTION__, __LINE__)); found = true; goto end; } } } } } end: return ((found == true) ? MAPISTORE_SUCCESS : MAPISTORE_ERR_NOT_FOUND); } #if 0 static int mgmt_notification_registration_cmd(enum mapistore_mgmt_status status, unsigned msg_prio, struct mapistore_connection_info *conn_info, struct mapistore_mgmt_notif *notification) { int ret; TALLOC_CTX *mem_ctx; DATA_BLOB data; struct mapistore_mgmt_command cmd; enum ndr_err_code ndr_err; /* Sanity checks */ MAPISTORE_RETVAL_IF(!conn_info, MAPISTORE_ERR_NOT_INITIALIZED, NULL); MAPISTORE_RETVAL_IF(!conn_info->mstore_ctx, MAPISTORE_ERR_NOT_INITIALIZED, NULL); MAPISTORE_RETVAL_IF(!conn_info->username, MAPISTORE_ERR_NOT_INITIALIZED, NULL); MAPISTORE_RETVAL_IF(!notification, MAPISTORE_ERR_INVALID_PARAMETER, NULL); MAPISTORE_RETVAL_IF(notification->WholeStore == false && !notification->MAPIStoreURI, MAPISTORE_ERR_INVALID_PARAMETER, NULL); /* TotalNumberOfMessages and UnreadNumberOfMessages are not initialized here, triggering a warning in valgrind */ memset(&cmd, 0, sizeof(struct mapistore_mgmt_command)); cmd.type = MAPISTORE_MGMT_NOTIF; cmd.command.notification.status = status; printf("NotificationFlags = 0x%x\n", notification->NotificationFlags); cmd.command.notification.NotificationFlags = notification->NotificationFlags; cmd.command.notification.username = conn_info->username; cmd.command.notification.WholeStore = notification->WholeStore; if (notification->WholeStore == false) { cmd.command.notification.FolderID = notification->FolderID; cmd.command.notification.MessageID = notification->MessageID; cmd.command.notification.MAPIStoreURI = notification->MAPIStoreURI; } else { cmd.command.notification.FolderID = 0; cmd.command.notification.MessageID = 0; cmd.command.notification.MAPIStoreURI = NULL; } mem_ctx = talloc_new(NULL); ndr_err = ndr_push_struct_blob(&data, mem_ctx, &cmd, (ndr_push_flags_fn_t)ndr_push_mapistore_mgmt_command); if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) { DEBUG(0, ("! [%s:%d][%s]: Failed to push mapistore_mgmt_command into NDR blob\n", __FILE__, __LINE__, __FUNCTION__)); talloc_free(mem_ctx); return MAPISTORE_ERR_INVALID_DATA; } ret = mq_send(conn_info->mstore_ctx->mq_ipc, (const char *)data.data, data.length, msg_prio); if (ret == -1) { talloc_free(mem_ctx); return MAPISTORE_ERR_MSG_SEND; } talloc_free(mem_ctx); return MAPISTORE_SUCCESS; } #endif /** \details Register a subscription for the given user \param conn_info pointer to the connection information \param notification pointer to the structure holding notification data \return MAPISTORE_SUCCESS on success, otherwise MAPISTORE error */ #if 0 _PUBLIC_ enum mapistore_error mapistore_mgmt_interface_register_subscription(struct mapistore_connection_info *conn_info, struct mapistore_mgmt_notif *notification) { return mgmt_notification_registration_cmd(MAPISTORE_MGMT_REGISTER, MAPISTORE_COMMAND_NOTIF_REGISTER_PRIO, conn_info, notification); } #endif /** \details Unregister a subscription for the given user \param conn_info pointer to the connection information \param notification pointer to the structure holding notification data \return MAPISTORE_SUCCESS on success, otherwise MAPISTORE error */ #if 0 _PUBLIC_ enum mapistore_error mapistore_mgmt_interface_unregister_subscription(struct mapistore_connection_info *conn_info, struct mapistore_mgmt_notif *notification) { return mgmt_notification_registration_cmd(MAPISTORE_MGMT_UNREGISTER, MAPISTORE_COMMAND_NOTIF_UNREGISTER_PRIO, conn_info, notification); } #endif #if 0 static enum mapistore_error mgmt_bind_registration_command(enum mapistore_mgmt_status status, unsigned msg_prio, struct mapistore_connection_info *conn_info, uint16_t cbContext, uint8_t *rgbContext, uint16_t cbCallbackAddress, uint8_t *rgbCallbackAddress) { int ret; TALLOC_CTX *mem_ctx; DATA_BLOB data; struct mapistore_mgmt_command cmd; enum ndr_err_code ndr_err; /* Sanity checks */ MAPISTORE_RETVAL_IF(!conn_info, MAPISTORE_ERR_NOT_INITIALIZED, NULL); MAPISTORE_RETVAL_IF(!conn_info->mstore_ctx, MAPISTORE_ERR_NOT_INITIALIZED, NULL); MAPISTORE_RETVAL_IF(!conn_info->username, MAPISTORE_ERR_NOT_INITIALIZED, NULL); MAPISTORE_RETVAL_IF(!rgbContext, MAPISTORE_ERR_INVALID_PARAMETER, NULL); MAPISTORE_RETVAL_IF(!rgbCallbackAddress, MAPISTORE_ERR_INVALID_PARAMETER, NULL); mem_ctx = talloc_new(NULL); cmd.type = MAPISTORE_MGMT_BIND; cmd.command.bind.username = conn_info->username; cmd.command.bind.cbContext = cbContext; cmd.command.bind.rgbContext = rgbContext; cmd.command.bind.cbCallbackAddress = cbCallbackAddress; cmd.command.bind.rgbCallbackAddress = rgbCallbackAddress; ndr_err = ndr_push_struct_blob(&data, mem_ctx, &cmd, (ndr_push_flags_fn_t)ndr_push_mapistore_mgmt_command); if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) { DEBUG(0, ("! [%s:%d][%s]: Failed to push mapistore_mgmt_command into NDR blob\n", __FILE__, __LINE__, __FUNCTION__)); talloc_free(mem_ctx); return MAPISTORE_ERR_INVALID_DATA; } ret = mq_send(conn_info->mstore_ctx->mq_ipc, (const char *)data.data, data.length, msg_prio); if (ret == -1) { talloc_free(mem_ctx); return MAPISTORE_ERR_MSG_SEND; } talloc_free(mem_ctx); return MAPISTORE_SUCCESS; } #endif /** \details Register a callback address for UDP notifications to be dispatched for given user \param conn_info pointer to the connection information \param cbContext number of bytes in rgbContext \param rgbContext array of bytes holding the notification key \param cbCallbackAddress number of bytes in rgbCallbackAddress \param rgbCallbackAddress array of bytes holding the sockaddr structure to send \return MAPISTORE_SUCCESS on success, otherwise MAPISTORE error */ #if 0 _PUBLIC_ enum mapistore_error mapistore_mgmt_interface_register_bind(struct mapistore_connection_info *conn_info, uint16_t cbContext, uint8_t *rgbContext, uint16_t cbCallbackAddress, uint8_t *rgbCallbackAddress) { return mgmt_bind_registration_command(MAPISTORE_MGMT_REGISTER, MAPISTORE_COMMAND_NOTIF_SOCKET_REGISTER_PRIO, conn_info, cbContext, rgbContext, cbCallbackAddress, rgbCallbackAddress); } #endif openchange-2.0/mapiproxy/libmapistore/mgmt/mapistore_mgmt.h000066400000000000000000000102041223057412600243470ustar00rootroot00000000000000/* OpenChange Storage Abstraction Layer library OpenChange Project Copyright (C) Julien Kerihuel 2009-2010 This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see . */ #ifndef __MAPISTORE_MGMT_H #define __MAPISTORE_MGMT_H #include #include #include #include #include #include #include #include #include "gen_ndr/mapistore_mgmt.h" /* forward declaration */ struct mapistore_context; struct mapistore_mgmt_users_list { uint32_t count; const char **user; }; struct mapistore_mgmt_notif { bool WholeStore; uint16_t NotificationFlags; uint64_t FolderID; uint64_t MessageID; const char *MAPIStoreURI; uint32_t ref_count; struct mapistore_mgmt_notif *prev; struct mapistore_mgmt_notif *next; }; struct mapistore_mgmt_notify_context { int fd; struct sockaddr *addr; uint16_t context_len; uint8_t *context_data; }; struct mapistore_mgmt_users { struct mapistore_mgmt_user_cmd *info; struct mapistore_mgmt_notif *notifications; uint32_t ref_count; struct mapistore_mgmt_notify_context *notify_ctx; struct mapistore_mgmt_users *prev; struct mapistore_mgmt_users *next; }; struct mapistore_mgmt_context { struct mapistore_context *mstore_ctx; struct mapistore_mgmt_users *users; mqd_t mq_ipc; bool verbose; }; #ifndef __BEGIN_DECLS #ifdef __cplusplus #define __BEGIN_DECLS extern "C" { #define __END_DECLS } #else #define __BEGIN_DECLS #define __END_DECLS #endif #endif __BEGIN_DECLS /* definitions from mapistore_mgmt.c */ struct mapistore_mgmt_context *mapistore_mgmt_init(struct mapistore_context *); enum mapistore_error mapistore_mgmt_release(struct mapistore_mgmt_context *); enum mapistore_error mapistore_mgmt_registered_backend(struct mapistore_mgmt_context *, const char *); struct mapistore_mgmt_users_list *mapistore_mgmt_existing_users(struct mapistore_mgmt_context *, void *, const char *, const char *, const char *); struct mapistore_mgmt_users_list *mapistore_mgmt_registered_users(struct mapistore_mgmt_context *, const char *, const char *); enum mapistore_error mapistore_mgmt_set_verbosity(struct mapistore_mgmt_context *, bool); enum mapistore_error mapistore_mgmt_generate_uri(struct mapistore_mgmt_context *, const char *, const char *, const char *, const char *, const char *, char **); enum mapistore_error mapistore_mgmt_registered_message(struct mapistore_mgmt_context *, const char *, const char *, const char *,const char *, const char *, const char *); enum mapistore_error mapistore_mgmt_register_message(struct mapistore_mgmt_context *, const char *, const char *, uint64_t, const char *, const char *, char **); enum mapistore_error mapistore_mgmt_registered_folder_subscription(struct mapistore_mgmt_context *, const char *, const char *, uint16_t); /* definitions from mapistore_mgmt_messages.c */ enum mapistore_error mapistore_mgmt_message_user_command(struct mapistore_mgmt_context *, struct mapistore_mgmt_user_cmd); enum mapistore_error mapistore_mgmt_message_notification_command(struct mapistore_mgmt_context *, struct mapistore_mgmt_notification_cmd); enum mapistore_error mapistore_mgmt_message_bind_command(struct mapistore_mgmt_context *, struct mapistore_mgmt_bind_cmd); /* definitions from mapistore_mgmt_send.c */ enum mapistore_error mapistore_mgmt_send_newmail_notification(struct mapistore_mgmt_context *, const char *, uint64_t, uint64_t, const char *); enum mapistore_error mapistore_mgmt_send_udp_notification(struct mapistore_mgmt_context *, const char *); __END_DECLS #endif /* ! __MAPISTORE_MGMT_H */ openchange-2.0/mapiproxy/libmapistore/mgmt/mapistore_mgmt.idl000066400000000000000000000045421223057412600247000ustar00rootroot00000000000000/* IDL struct for mapistore mgmt interface */ [ pointer_default(unique) ] interface mapistore_mgmt { typedef [enum8bit] enum { MAPISTORE_COMMAND_NOTIF_REGISTER_PRIO = 26, MAPISTORE_COMMAND_NOTIF_UNREGISTER_PRIO = 27, MAPISTORE_COMMAND_NOTIF_SOCKET_REGISTER_PRIO = 28, MAPISTORE_COMMAND_NOTIF_SOCKET_UNREGISTER_PRIO = 29, MAPISTORE_COMMAND_USER_REGISTER_PRIO = 30, MAPISTORE_COMMAND_USER_UNREGISTER_PRIO = 31 } mapistore_mgmt_command_priority; typedef [enum16bit] enum { MAPISTORE_MGMT_SEND = 0x0, MAPISTORE_MGMT_REGISTER = 0x1, MAPISTORE_MGMT_UNREGISTER = 0x2 } mapistore_mgmt_status; typedef [public] struct { mapistore_mgmt_status status; [string, charset(UTF16)] uint16 *backend; [string, charset(UTF16)] uint16 *username; [string, charset(UTF16)] uint16 *vuser; } mapistore_mgmt_user_cmd; typedef [public] struct { [string, charset(UTF16)] uint16 *username; uint16 cbContext; [size_is(cbContext)] uint8 rgbContext[*]; uint16 cbCallbackAddress; [size_is(cbCallbackAddress)] uint8 rgbCallbackAddress[*]; } mapistore_mgmt_bind_cmd; typedef [public,bitmap16bit] bitmap { mgmt_notification_type_newmail = 0x2, mgmt_notification_type_objectcreated = 0x4, mgmt_notification_type_objectmodified = 0x10, mgmt_notification_type_Tbit = 0x1000, mgmt_notification_type_Ubit = 0x2000, mgmt_notification_type_Mbit = 0x8000 } mapistore_mgmt_notification_type; typedef [public] struct { mapistore_mgmt_status status; mapistore_mgmt_notification_type NotificationFlags; [string, charset(UTF16)] uint16 *username; boolean8 WholeStore; hyper FolderID; hyper MessageID; [string, charset(UTF16)] uint16 *MAPIStoreURI; uint32 TotalNumberOfMessages; uint32 UnreadNumberOfMessages; } mapistore_mgmt_notification_cmd; typedef [enum16bit] enum { MAPISTORE_MGMT_USER = 0x1, MAPISTORE_MGMT_BIND = 0x2, MAPISTORE_MGMT_NOTIF = 0x3 } mapistore_mgmt_command_type; typedef [public,switch_type(uint16)] union { [case(MAPISTORE_MGMT_USER)] mapistore_mgmt_user_cmd user; [case(MAPISTORE_MGMT_BIND)] mapistore_mgmt_bind_cmd bind; [case(MAPISTORE_MGMT_NOTIF)] mapistore_mgmt_notification_cmd notification; } mapistore_mgmt_commands; typedef [public] struct { mapistore_mgmt_command_type type; [switch_is(type)] mapistore_mgmt_commands command; } mapistore_mgmt_command; }openchange-2.0/mapiproxy/libmapistore/mgmt/mapistore_mgmt_messages.c000066400000000000000000000313741223057412600262440ustar00rootroot00000000000000/* OpenChange Storage Abstraction Layer library OpenChange Project Copyright (C) Julien Kerihuel 2011 This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see . */ /** \file mapistore_mgmt_messages.c \brief Process IPC messages received on command message queue. */ #include "mapiproxy/libmapistore/mapistore.h" #include "mapiproxy/libmapistore/mapistore_errors.h" #include "mapiproxy/libmapistore/mapistore_private.h" #include "mapiproxy/libmapistore/mgmt/mapistore_mgmt.h" #include "mapiproxy/libmapistore/mgmt/gen_ndr/ndr_mapistore_mgmt.h" static enum mapistore_error mapistore_mgmt_message_user_command_add(struct mapistore_mgmt_context *mgmt_ctx, struct mapistore_mgmt_user_cmd user_cmd, bool populated) { struct mapistore_mgmt_users *el; el = talloc_zero((TALLOC_CTX *)mgmt_ctx, struct mapistore_mgmt_users); if (!el) { DEBUG(0, ("[%s:%d]: Not enough memory\n", __FUNCTION__, __LINE__)); return MAPISTORE_ERR_NO_MEMORY; } el->info = talloc_zero((TALLOC_CTX *)el, struct mapistore_mgmt_user_cmd); if (!el->info) { talloc_free(el); DEBUG(0, ("[%s:%d]: Not enough memory\n", __FUNCTION__, __LINE__)); return MAPISTORE_ERR_NO_MEMORY; } if (populated == true) { el->info->backend = talloc_strdup((TALLOC_CTX *)el->info, user_cmd.backend); el->info->vuser = talloc_strdup((TALLOC_CTX *)el->info, user_cmd.vuser); } else { el->info->backend = NULL; el->info->vuser = NULL; } el->info->username = talloc_strdup((TALLOC_CTX *)el->info, user_cmd.username); el->ref_count = 1; el->notify_ctx = NULL; DLIST_ADD_END(mgmt_ctx->users, el, struct mapistore_mgmt_users); return MAPISTORE_SUCCESS; } enum mapistore_error mapistore_mgmt_message_user_command(struct mapistore_mgmt_context *mgmt_ctx, struct mapistore_mgmt_user_cmd user_cmd) { struct mapistore_mgmt_users *el; bool found = false; /* Sanity checks */ MAPISTORE_RETVAL_IF(!mgmt_ctx, MAPISTORE_ERR_NOT_INITIALIZED, NULL); MAPISTORE_RETVAL_IF(user_cmd.backend == NULL || user_cmd.username == NULL || user_cmd.vuser == NULL, MAPISTORE_ERR_INVALID_PARAMETER, NULL); if (mgmt_ctx->users == NULL) { if (user_cmd.status == MAPISTORE_MGMT_REGISTER) { return mapistore_mgmt_message_user_command_add(mgmt_ctx, user_cmd, true); } else { DEBUG(0, ("[%s:%d]: Trying to unregister user %s in empty list\n", __FUNCTION__, __LINE__, user_cmd.username)); return MAPISTORE_SUCCESS; } } else { /* Search users list and perform action */ for (el = mgmt_ctx->users; el; el = el->next) { /* Case where username exists but record is incomplete */ if (!strcmp(el->info->username, user_cmd.username) && !el->info->backend && !el->info->vuser) { found = true; switch (user_cmd.status) { case MAPISTORE_MGMT_REGISTER: el->info->backend = talloc_strdup((TALLOC_CTX *)el->info, user_cmd.backend); el->info->vuser = talloc_strdup((TALLOC_CTX *)el->info, user_cmd.vuser); break; case MAPISTORE_MGMT_UNREGISTER: el->ref_count -= 1; /* Delete record if ref_count is 0 */ if (el->ref_count == 0) { DLIST_REMOVE(mgmt_ctx->users, el); talloc_free(el); break; } break; case MAPISTORE_MGMT_SEND: break; } } /* Case where the record exists */ if ((!strcmp(el->info->backend, user_cmd.backend)) && (!strcmp(el->info->username, user_cmd.username)) && (!strcmp(el->info->vuser, user_cmd.vuser))) { found = true; switch (user_cmd.status) { case MAPISTORE_MGMT_REGISTER: el->ref_count += 1; break; case MAPISTORE_MGMT_UNREGISTER: el->ref_count -= 1; /* Delete record if ref_count is 0 */ if (el->ref_count == 0) { DLIST_REMOVE(mgmt_ctx->users, el); talloc_free(el); break; } break; default: DEBUG(0, ("[%s:%d]: Invalid user command status: %d\n", __FUNCTION__, __LINE__, user_cmd.status)); break; } } } /* Case where no matching record was found: insert */ if (found == false) { switch (user_cmd.status) { case MAPISTORE_MGMT_REGISTER: return mapistore_mgmt_message_user_command_add(mgmt_ctx, user_cmd, true); break; case MAPISTORE_MGMT_UNREGISTER: DEBUG(0, ("[%s:%d]: Trying to unregister non-existing users %s\n", __FUNCTION__, __LINE__, user_cmd.username)); break; default: DEBUG(0, ("[%s:%d]: Invalid user command status: %d\n", __FUNCTION__, __LINE__, user_cmd.status)); break; } } } return MAPISTORE_SUCCESS; } enum mapistore_error mapistore_mgmt_message_bind_command(struct mapistore_mgmt_context *mgmt_ctx, struct mapistore_mgmt_bind_cmd bind) { struct mapistore_mgmt_users *el; bool found = false; struct mapistore_mgmt_user_cmd user_cmd; /* Sanity checks */ MAPISTORE_RETVAL_IF(!mgmt_ctx, MAPISTORE_ERR_NOT_INITIALIZED, NULL); MAPISTORE_RETVAL_IF(!bind.username, MAPISTORE_ERR_INVALID_PARAMETER, NULL); MAPISTORE_RETVAL_IF(!bind.cbContext || !bind.cbCallbackAddress, MAPISTORE_ERR_INVALID_PARAMETER, NULL); /* If bind occurs before any user registration */ if (!mgmt_ctx->users) { user_cmd.username = bind.username; mapistore_mgmt_message_user_command_add(mgmt_ctx, user_cmd, false); } for (el = mgmt_ctx->users; el; el = el->next) { if (!strcmp(el->info->username, bind.username)) { /* Return existing notify context when existing */ if (el->notify_ctx) { talloc_free(el->notify_ctx); } found = true; el->notify_ctx = talloc_zero((TALLOC_CTX *)el, struct mapistore_mgmt_notify_context); el->notify_ctx->context_len = bind.cbContext; el->notify_ctx->context_data = talloc_memdup((TALLOC_CTX *)el->notify_ctx, bind.rgbContext, bind.cbContext); el->notify_ctx->addr = talloc_memdup((TALLOC_CTX *)el->notify_ctx, bind.rgbCallbackAddress, bind.cbCallbackAddress); /* socket / connect calls */ #ifdef SOCK_NONBLOCK el->notify_ctx->fd = socket(PF_INET, SOCK_DGRAM|SOCK_NONBLOCK, IPPROTO_UDP); #else /* SOCK_NONBLOCK */ { int flags; el->notify_ctx->fd = socket(PF_INET, SOCK_DGRAM, IPPROTO_UDP); flags = fcntl(el->notify_ctx->fd, F_GETFL, 0); fcntl(el->notify_ctx->fd, F_SETFL, flags | O_NONBLOCK); } #endif /* SOCK_NONBLOCK */ if (el->notify_ctx->fd == -1) { perror("socket"); talloc_free(el->notify_ctx); found = false; } else { if (connect(el->notify_ctx->fd, el->notify_ctx->addr, sizeof (struct sockaddr)) == -1) { perror("connect"); talloc_free(el->notify_ctx); found = false; } } } } return (found == true) ? MAPISTORE_SUCCESS : MAPISTORE_ERR_NOT_FOUND; } static enum mapistore_error mapistore_mgmt_message_notification_command_add(struct mapistore_mgmt_users *user_cmd, struct mapistore_mgmt_notification_cmd notif) { struct mapistore_mgmt_notif *el; el = talloc_zero((TALLOC_CTX *)user_cmd, struct mapistore_mgmt_notif); if (!el) { DEBUG(0, ("[%s:%d]: Not enough memory\n", __FUNCTION__, __LINE__)); return MAPISTORE_ERR_NO_MEMORY; } el->WholeStore = notif.WholeStore; el->NotificationFlags = notif.NotificationFlags; el->ref_count = 1; if (el->WholeStore == false) { el->MAPIStoreURI = talloc_strdup((TALLOC_CTX *)el, notif.MAPIStoreURI); el->FolderID = notif.FolderID; el->MessageID = notif.MessageID; } DLIST_ADD_END(user_cmd->notifications, el, struct mapistore_mgmt_notif); return MAPISTORE_SUCCESS; } static bool mapistore_mgmt_message_notification_wholestore(struct mapistore_mgmt_users *user_cmd, struct mapistore_mgmt_notification_cmd notif) { struct mapistore_mgmt_notif *el; bool found = false; if (notif.WholeStore == false) return false; switch (notif.status) { case MAPISTORE_MGMT_REGISTER: for (el = user_cmd->notifications; el; el = el->next) { if ((el->WholeStore == true) && (el->NotificationFlags == notif.NotificationFlags)) { found = true; el->ref_count += 1; break; } } if (found == false) { mapistore_mgmt_message_notification_command_add(user_cmd, notif); } break; case MAPISTORE_MGMT_UNREGISTER: for (el = user_cmd->notifications; el; el = el->next) { if ((el->WholeStore == true) && (el->NotificationFlags == notif.NotificationFlags)) { el->ref_count -= 1; if (!el->ref_count) { DEBUG(0, ("[%s:%d]: Deleting WholeStore subscription\n", __FUNCTION__, __LINE__)); DLIST_REMOVE(user_cmd->notifications, el); talloc_free(el); return true; } } } DEBUG(0, ("[%s:%d]: Unregistered subscription found\n", __FUNCTION__, __LINE__)); break; case MAPISTORE_MGMT_SEND: break; } return true; } static bool mapistore_mgmt_message_notification_message(struct mapistore_mgmt_users *user_cmd, struct mapistore_mgmt_notification_cmd notif) { struct mapistore_mgmt_notif *el; bool found = false; if (!notif.MessageID) return false; switch (notif.status) { case MAPISTORE_MGMT_REGISTER: for (el = user_cmd->notifications; el; el = el->next) { if ((el->MessageID == notif.MessageID) && (el->NotificationFlags == notif.NotificationFlags)) { found = true; el->ref_count += 1; break; } } if (found == false) { mapistore_mgmt_message_notification_command_add(user_cmd, notif); } break; case MAPISTORE_MGMT_UNREGISTER: for (el = user_cmd->notifications; el; el = el->next) { if ((el->MessageID == notif.MessageID) && (el->NotificationFlags == notif.NotificationFlags)) { el->ref_count -= 1; if (!el->ref_count) { DEBUG(0, ("[%s:%d]: Deleting Message subscription\n", __FUNCTION__, __LINE__)); DLIST_REMOVE(user_cmd->notifications, el); talloc_free(el); return true; } } } DEBUG(0, ("[%s:%d]: Unregistered subscription found\n", __FUNCTION__, __LINE__)); break; case MAPISTORE_MGMT_SEND: break; } return true; } static bool mapistore_mgmt_message_notification_folder(struct mapistore_mgmt_users *user_cmd, struct mapistore_mgmt_notification_cmd notif) { struct mapistore_mgmt_notif *el; bool found = false; if (!notif.FolderID) return false; switch (notif.status) { case MAPISTORE_MGMT_REGISTER: for (el = user_cmd->notifications; el; el = el->next) { if (!el->MessageID && (el->FolderID == notif.FolderID) && (el->NotificationFlags == notif.NotificationFlags)) { found = true; el->ref_count += 1; break; } } if (found == false) { mapistore_mgmt_message_notification_command_add(user_cmd, notif); } break; case MAPISTORE_MGMT_UNREGISTER: for (el = user_cmd->notifications; el; el = el->next) { if (!el->MessageID && (el->FolderID == notif.FolderID) && (el->NotificationFlags == notif.NotificationFlags)) { el->ref_count -= 1; if (!el->ref_count) { DEBUG(0, ("[%s:%d]: Deleting Folder subscription\n", __FUNCTION__, __LINE__)); DLIST_REMOVE(user_cmd->notifications, el); talloc_free(el); return true; } } } DEBUG(0, ("[%s:%d]: Unregistered subscription found\n", __FUNCTION__, __LINE__)); break; case MAPISTORE_MGMT_SEND: break; } return true; } enum mapistore_error mapistore_mgmt_message_notification_command(struct mapistore_mgmt_context *mgmt_ctx, struct mapistore_mgmt_notification_cmd notif) { struct mapistore_mgmt_users *el; bool ret; /* Sanity checks */ MAPISTORE_RETVAL_IF(!mgmt_ctx, MAPISTORE_ERR_NOT_INITIALIZED, NULL); MAPISTORE_RETVAL_IF(!mgmt_ctx->users, MAPISTORE_ERR_NOT_INITIALIZED, NULL); MAPISTORE_RETVAL_IF(!notif.username || (!notif.MAPIStoreURI && notif.WholeStore == false) || (!notif.FolderID && notif.WholeStore == false), MAPI_E_INVALID_PARAMETER, NULL); for (el = mgmt_ctx->users; el; el = el->next) { if (!strcmp(el->info->username, notif.username)) { /* Case where no notifications has been registered yet */ if (el->notifications == NULL) { mapistore_mgmt_message_notification_command_add(el, notif); } else { /* subscription on wholestore case */ ret = mapistore_mgmt_message_notification_wholestore(el, notif); if (ret == false) { /* subscription on message case */ ret = mapistore_mgmt_message_notification_message(el, notif); if (ret == false) { /* subscription on folder case */ ret = mapistore_mgmt_message_notification_folder(el, notif); } } } } } return MAPISTORE_SUCCESS; } openchange-2.0/mapiproxy/libmapistore/mgmt/mapistore_mgmt_send.c000066400000000000000000000266301223057412600253650ustar00rootroot00000000000000/* OpenChange Storage Abstraction Layer library OpenChange Project Copyright (C) Julien Kerihuel 2011 This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see . */ /** \file mapistore_mgmt_send.c \brief Provides mapistore management routine for sending messages/notifications from administrative/services tools to OpenChange Server/listener process. Using this interface virtually restrict mapistore features to the specific management functions subset. */ #include "mapiproxy/libmapistore/mapistore.h" #include "mapiproxy/libmapistore/mapistore_errors.h" #include "mapiproxy/libmapistore/mapistore_private.h" #include "mapiproxy/libmapistore/mgmt/mapistore_mgmt.h" #include "mapiproxy/libmapistore/mgmt/gen_ndr/ndr_mapistore_mgmt.h" enum mapistore_error mapistore_mgmt_send_udp_notification(struct mapistore_mgmt_context *mgmt_ctx, const char *username) { struct mapistore_mgmt_users *el; ssize_t len; bool found = false; printf("mapistore_mgmt_send_udp_notification\n"); /* Sanity checks */ MAPISTORE_RETVAL_IF(!mgmt_ctx, MAPISTORE_ERR_NOT_INITIALIZED, NULL); MAPISTORE_RETVAL_IF(!mgmt_ctx->users, MAPISTORE_ERR_NOT_INITIALIZED, NULL); MAPISTORE_RETVAL_IF(!username, MAPISTORE_ERR_INVALID_PARAMETER, NULL); for (el = mgmt_ctx->users; el; el = el->next) { if (!strcmp(el->info->username, username) && el->notify_ctx) { len = send(el->notify_ctx->fd, (const void *)el->notify_ctx->context_data, el->notify_ctx->context_len, MSG_DONTWAIT); if (len == -1) { perror("send"); } else { printf("UDP NOTIFICATION SENT, size is: %zu\n", len); found = true; } } } return (found == true) ? MAPISTORE_SUCCESS : MAPISTORE_ERR_NOT_FOUND; } /* /\** */ /* \details Send a newmail notification over irpc to the listener */ /* process */ /* \param mgmt_ctx pointer to the mapistore management context */ /* \param username the openchange user to deliver the notification to */ /* \param FolderID the identifier of the folder which received the newmail */ /* \param MessageID the identifier of the received message */ /* \param MAPIStoreURI the URI of the new message */ /* \return MAPISTORE_SUCCESS on success, otherwise MAPISTORE error. */ /* *\/ */ /* enum mapistore_error mapistore_mgmt_send_newmail_notification(struct mapistore_mgmt_context *mgmt_ctx, */ /* const char *username, */ /* uint64_t FolderID, */ /* uint64_t MessageID, */ /* const char *MAPIStoreURI) */ /* { */ /* mqd_t mqfd; */ /* int ret; */ /* TALLOC_CTX *mem_ctx; */ /* DATA_BLOB data; */ /* struct mapistore_mgmt_command cmd; */ /* enum ndr_err_code ndr_err; */ /* char *queue; */ /* /\* Sanity checks *\/ */ /* printf("mapistore_mgmt_send_newmail_notification\n"); */ /* MAPISTORE_RETVAL_IF(!mgmt_ctx, MAPISTORE_ERR_NOT_INITIALIZED, NULL); */ /* MAPISTORE_RETVAL_IF(!username, MAPISTORE_ERR_INVALID_PARAMETER, NULL); */ /* MAPISTORE_RETVAL_IF(!MAPIStoreURI, MAPISTORE_ERR_INVALID_PARAMETER, NULL); */ /* mem_ctx = talloc_new(NULL); */ /* /\* Try to open the newmail queue for specified user *\/ */ /* queue = talloc_asprintf(mem_ctx, MAPISTORE_MQUEUE_NEWMAIL_FMT, username); */ /* mqfd = mq_open(queue, O_WRONLY|O_NONBLOCK); */ /* if (mqfd == -1) { */ /* ret = mapistore_mgmt_send_udp_notification(mgmt_ctx, username); */ /* printf("[%s:%d] mapistore_mgmt_send_udp_notification: %d\n", __FUNCTION__, __LINE__, ret); */ /* perror("mq_open"); */ /* talloc_free(mem_ctx); */ /* return MAPISTORE_ERR_NOT_FOUND; */ /* } */ /* /\* Prepare DATA_BLOB notification *\/ */ /* cmd.type = MAPISTORE_MGMT_NOTIF; */ /* cmd.command.notification.status = MAPISTORE_MGMT_SEND; */ /* cmd.command.notification.NotificationFlags = mgmt_notification_type_newmail; */ /* cmd.command.notification.username = username; */ /* cmd.command.notification.WholeStore = 0; */ /* cmd.command.notification.FolderID = FolderID; */ /* cmd.command.notification.MessageID = MessageID; */ /* cmd.command.notification.MAPIStoreURI = MAPIStoreURI; */ /* ndr_err = ndr_push_struct_blob(&data, mem_ctx, &cmd, (ndr_push_flags_fn_t)ndr_push_mapistore_mgmt_command); */ /* if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) { */ /* DEBUG(0, ("! [%s:%d][%s]: Failed to push mapistore_mgmt_command into NDR blob\n", */ /* __FUNCTION__, __LINE__, __FUNCTION__)); */ /* mq_close(mqfd); */ /* talloc_free(mem_ctx); */ /* return MAPISTORE_ERR_INVALID_DATA; */ /* } */ /* /\* Send the message *\/ */ /* ret = mq_send(mqfd, (const char *)data.data, data.length, 0); */ /* if (ret == -1) { */ /* perror("mq_send"); */ /* talloc_free(mem_ctx); */ /* mq_close(mqfd); */ /* return MAPISTORE_ERR_MSG_SEND; */ /* } */ /* mq_close(mqfd); */ /* talloc_free(mem_ctx); */ /* /\* Send UDP notification *\/ */ /* ret = mapistore_mgmt_send_udp_notification(mgmt_ctx, username); */ /* printf("[%s:%d] mapistore_mgmt_send_udp_notification: %d\n", __FUNCTION__, __LINE__, ret); */ /* return MAPISTORE_SUCCESS; */ /* } */ static enum mapistore_error mapistore_mgmt_push_send(TALLOC_CTX *mem_ctx, mqd_t mqfd, struct mapistore_mgmt_command cmd) { DATA_BLOB data; enum ndr_err_code ndr_err; int ret; /* Sanity checks */ MAPISTORE_RETVAL_IF(!mqfd, MAPISTORE_ERR_NOT_FOUND, NULL); /* Prepare DATA_BLOB with data pushed */ ndr_err = ndr_push_struct_blob(&data, mem_ctx, &cmd, (ndr_push_flags_fn_t)ndr_push_mapistore_mgmt_command); if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) { DEBUG(0, ("! [%s:%d][%s]: Failed to push mapistore_mgmt_command into NDR blob\n", __FUNCTION__, __LINE__, __FUNCTION__)); mq_close(mqfd); return MAPISTORE_ERR_INVALID_DATA; } /* Send the message */ ret = mq_send(mqfd, (const char *)data.data, data.length, 0); if (ret == -1) { printf("Notification Pushed with error: ret = %d\n", ret); perror("mq_send"); mq_close(mqfd); return MAPISTORE_ERR_MSG_SEND; } printf("Notification Pushed successfully: ret = %d\n", ret); return MAPISTORE_SUCCESS; } /** \details Send notifications */ enum mapistore_error mapistore_mgmt_send_newmail_notification(struct mapistore_mgmt_context *mgmt_ctx, const char *username, uint64_t FolderID, uint64_t MessageID, const char *MAPIStoreURI) { mqd_t mqfd; int ret; TALLOC_CTX *mem_ctx; struct mapistore_mgmt_command cmd; char *queue; /* Sanity checks */ printf("[%s:%d]: mapistore_mgmt_send_newmail_global_notification\n", __FUNCTION__, __LINE__); MAPISTORE_RETVAL_IF(!mgmt_ctx, MAPISTORE_ERR_NOT_INITIALIZED, NULL); MAPISTORE_RETVAL_IF(!username, MAPISTORE_ERR_NOT_INITIALIZED, NULL); MAPISTORE_RETVAL_IF(!MAPIStoreURI, MAPISTORE_ERR_INVALID_PARAMETER, NULL); mem_ctx = talloc_new(NULL); /* Try to open the newmail queue for specified user */ queue = talloc_asprintf(mem_ctx, MAPISTORE_MQUEUE_NEWMAIL_FMT, username); mqfd = mq_open(queue, O_WRONLY|O_NONBLOCK); if (mqfd == -1) { ret = mapistore_mgmt_send_udp_notification(mgmt_ctx, username); perror("mq_open"); talloc_free(mem_ctx); return MAPISTORE_ERR_NOT_FOUND; } /* fnevNewmail subscription case */ ret = mapistore_mgmt_registered_folder_subscription(mgmt_ctx, username, NULL, mgmt_notification_type_newmail); /* if (ret == MAPISTORE_SUCCESS) { */ /* memset(&cmd, 0x0, sizeof (struct mapistore_mgmt_command)); */ /* cmd.type = MAPISTORE_MGMT_NOTIF; */ /* cmd.command.notification.status = MAPISTORE_MGMT_SEND; */ /* cmd.command.notification.NotificationFlags = mgmt_notification_type_newmail | mgmt_notification_type_Mbit; */ /* cmd.command.notification.username = username; */ /* cmd.command.notification.WholeStore = 0; */ /* cmd.command.notification.FolderID = FolderID; */ /* cmd.command.notification.MessageID = MessageID; */ /* cmd.command.notification.MAPIStoreURI = MAPIStoreURI; */ /* cmd.command.notification.TotalNumberOfMessages = 0; */ /* cmd.command.notification.UnreadNumberOfMessages = 0; */ /* mapistore_mgmt_push_send(mem_ctx, mqfd, cmd); */ /* printf("NEWMAIL notification sent on %s\n", queue); */ /* } */ /* fnevObjectModified subscription case (fntevTbit + fnevUbit) (0x3010) but only 0x10 looked up */ ret = mapistore_mgmt_registered_folder_subscription(mgmt_ctx, username, NULL, mgmt_notification_type_objectmodified); if (ret == MAPISTORE_SUCCESS) { memset(&cmd, 0x0, sizeof (struct mapistore_mgmt_command)); cmd.type = MAPISTORE_MGMT_NOTIF; cmd.command.notification.status = MAPISTORE_MGMT_SEND; cmd.command.notification.NotificationFlags = mgmt_notification_type_objectmodified | mgmt_notification_type_Tbit | mgmt_notification_type_Ubit; cmd.command.notification.WholeStore = 0; cmd.command.notification.FolderID = FolderID; cmd.command.notification.MessageID = MessageID; cmd.command.notification.MAPIStoreURI = NULL; /* Calculate the total number of messages and unread messages */ cmd.command.notification.TotalNumberOfMessages = 4; cmd.command.notification.UnreadNumberOfMessages = 1; mapistore_mgmt_push_send(mgmt_ctx, mqfd, cmd); printf("0x3010 notification sent on %s\n", queue); } /* fnevObjectCreated subscription case (0x8004) but only 0x4 looked up */ ret = mapistore_mgmt_registered_folder_subscription(mgmt_ctx, username, NULL, mgmt_notification_type_objectcreated); if (ret == MAPISTORE_SUCCESS) { memset(&cmd, 0x0, sizeof (struct mapistore_mgmt_command)); cmd.type = MAPISTORE_MGMT_NOTIF; cmd.command.notification.status = MAPISTORE_MGMT_SEND; cmd.command.notification.NotificationFlags = mgmt_notification_type_objectcreated | mgmt_notification_type_Mbit; cmd.command.notification.WholeStore = 0; cmd.command.notification.FolderID = FolderID; cmd.command.notification.MessageID = MessageID; cmd.command.notification.MAPIStoreURI = MAPIStoreURI; cmd.command.notification.TotalNumberOfMessages = 0; cmd.command.notification.UnreadNumberOfMessages = 0; mapistore_mgmt_push_send(mgmt_ctx, mqfd, cmd); printf("0x8004 notification sent on %s\n", queue); } /* fnevObjectModified (0x10) subscription case */ ret = mapistore_mgmt_registered_folder_subscription(mgmt_ctx, username, NULL, mgmt_notification_type_objectmodified); if (ret == MAPISTORE_SUCCESS) { memset(&cmd, 0x0, sizeof (struct mapistore_mgmt_command)); cmd.type = MAPISTORE_MGMT_NOTIF; cmd.command.notification.status = MAPISTORE_MGMT_SEND; cmd.command.notification.NotificationFlags = mgmt_notification_type_objectmodified; cmd.command.notification.FolderID = FolderID; cmd.command.notification.MessageID = MessageID; cmd.command.notification.MAPIStoreURI = MAPIStoreURI; cmd.command.notification.TotalNumberOfMessages = 0; cmd.command.notification.UnreadNumberOfMessages = 0; } /* Send UDP notification */ ret = mapistore_mgmt_send_udp_notification(mgmt_ctx, username); printf("[%s:%d] mapistore_mgmt_send_udp_notification: %d\n", __FUNCTION__, __LINE__, ret); talloc_free(mem_ctx); return MAPISTORE_SUCCESS; } openchange-2.0/mapiproxy/libmapistore/tests/000077500000000000000000000000001223057412600213505ustar00rootroot00000000000000openchange-2.0/mapiproxy/libmapistore/tests/mapistore_test.c000066400000000000000000000064501223057412600245630ustar00rootroot00000000000000/* OpenChange Storage Abstraction Layer library test tool OpenChange Project Copyright (C) Julien Kerihuel 2009 This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see . */ #include "mapiproxy/libmapistore/mapistore.h" #include "mapiproxy/libmapistore/mapistore_errors.h" #include #include #include #include #include /** \file mapistore_test.c \brief Test mapistore implementation */ int main(int argc, const char *argv[]) { TALLOC_CTX *mem_ctx; int retval; struct mapistore_context *mstore_ctx; struct loadparm_context *lp_ctx; poptContext pc; int opt; const char *opt_debug = NULL; uint32_t context_id = 0; uint32_t context_id2 = 0; uint32_t context_id3 = 0; void *root_folder; enum { OPT_DEBUG=1000 }; struct poptOption long_options[] = { POPT_AUTOHELP { "debuglevel", 'd', POPT_ARG_STRING, NULL, OPT_DEBUG, "set the debug level", NULL }, { NULL, 0, 0, NULL, 0, NULL, NULL } }; mem_ctx = talloc_named(NULL, 0, "mapistore_test"); lp_ctx = loadparm_init_global(true); setup_logging(NULL, DEBUG_STDOUT); pc = poptGetContext("mapistore_test", argc, argv, long_options, 0); while ((opt = poptGetNextOpt(pc)) != -1) { switch (opt) { case OPT_DEBUG: opt_debug = poptGetOptArg(pc); break; } } poptFreeContext(pc); if (opt_debug) { lpcfg_set_cmdline(lp_ctx, "log level", opt_debug); } retval = mapistore_set_mapping_path("/tmp"); if (retval != MAPISTORE_SUCCESS) { DEBUG(0, ("%s\n", mapistore_errstr(retval))); exit (1); } mstore_ctx = mapistore_init(mem_ctx, lp_ctx, NULL); if (!mstore_ctx) { DEBUG(0, ("%s\n", mapistore_errstr(retval))); exit (1); } retval = mapistore_add_context(mstore_ctx, "openchange", "sqlite:///tmp/test.db", -1, &context_id, &root_folder); if (retval != MAPISTORE_SUCCESS) { DEBUG(0, ("%s\n", mapistore_errstr(retval))); exit (1); } retval = mapistore_add_context(mstore_ctx, "openchange", "sqlite:///tmp/test2.db", -1, &context_id2, &root_folder); if (retval != MAPISTORE_SUCCESS) { DEBUG(0, ("%s\n", mapistore_errstr(retval))); exit (1); } DEBUG(0, ("Context ID: [1] = %d and [2] = %d\n", context_id, context_id2)); retval = mapistore_add_context(mstore_ctx, "openchange", "fsocpf:///tmp/fsocpf", -1, &context_id3, &root_folder); if (retval != MAPISTORE_SUCCESS) { DEBUG(0, ("%s\n", mapistore_errstr(retval))); exit (1); } retval = mapistore_del_context(mstore_ctx, context_id); retval = mapistore_del_context(mstore_ctx, context_id2); retval = mapistore_del_context(mstore_ctx, context_id3); retval = mapistore_release(mstore_ctx); if (retval != MAPISTORE_SUCCESS) { DEBUG(0, ("%s\n", mapistore_errstr(retval))); exit (1); } return 0; } openchange-2.0/mapiproxy/modules/000077500000000000000000000000001223057412600171645ustar00rootroot00000000000000openchange-2.0/mapiproxy/modules/mpm_cache.c000066400000000000000000001164151223057412600212540ustar00rootroot00000000000000/* MAPI Proxy - Cache module OpenChange Project Copyright (C) Julien Kerihuel 2008 This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see . */ /** \file mpm_cache.c \brief Cache messages and attachments so we can reduce WAN traffic */ #include "libmapi/libmapi.h" #include "libmapi/libmapi_private.h" #include "mapiproxy/dcesrv_mapiproxy.h" #include "mapiproxy/libmapiproxy/libmapiproxy.h" #include "mapiproxy/modules/mpm_cache.h" #include #include #include #include struct mpm_cache *mpm = NULL; /** \details Find the position of the given MAPI call in a serialized MAPI request. If the request includes a Release call, then request and replies indexes for other calls will mismatch. \param opnum The MAPI opnum to seek \param mapi_req Pointer to the MAPI request calls array \return On success, returns the call position, otherwise -1. */ static uint32_t cache_find_call_request_index(uint8_t opnum, struct EcDoRpc_MAPI_REQ *mapi_req) { uint32_t i; for (i = 0; mapi_req[i].opnum; i++) { if (mapi_req[i].opnum == opnum) { return i; } } return -1; } /** \details Dump time statistic between OpenStream and Release This function monitors the effective time required to open, read and close a stream. \param stream the mpm_stream entry */ static void cache_dump_stream_stat(struct mpm_stream *stream) { TALLOC_CTX *mem_ctx; struct timeval tv_end; uint64_t sec; uint64_t usec; char *name; const char *stage; mem_ctx = (TALLOC_CTX *)mpm; if (stream->attachment) { name = talloc_asprintf(mem_ctx, "0x%"PRIx64"/0x%"PRIx64"/%d", stream->attachment->message->FolderId, stream->attachment->message->MessageId, stream->attachment->AttachmentID); } else if (stream->message) { name = talloc_asprintf(mem_ctx, "0x%"PRIx64"/0x%"PRIx64, stream->message->FolderId, stream->message->MessageId); } else { return; } gettimeofday(&tv_end, NULL); sec = tv_end.tv_sec - stream->tv_start.tv_sec; if ((tv_end.tv_usec - stream->tv_start.tv_usec) < 0) { sec -= 1; usec = tv_end.tv_usec + stream->tv_start.tv_usec; while (usec > 1000000) { usec -= 1000000; sec += 1; } } else { usec = tv_end.tv_usec - stream->tv_start.tv_usec; } if (stream->ahead == true) { stage = "[read ahead]"; } else if ((stream->ahead == false) && (stream->cached == true)) { stage = "[cached mode]"; } else { stage = "[non cached]"; } DEBUG(1, ("STATISTIC: %-20s %s The difference is %ld seconds %ld microseconds\n", stage, name, (long int)sec, (long int)usec)); talloc_free(name); } /** \details 1. close the existing FILE * 2. build complete file path 3. replace __FILE__ arguments with complete file path 4. call execve 5. stat the sync'd file 6. open the stream again 7. mark the file as cached \param stream pointer on the mpm_stream entry */ static NTSTATUS cache_exec_sync_cmd(struct mpm_stream *stream) { uint32_t i; int ret = 0; char **args; struct stat sb; pid_t pid; int status; mpm_cache_stream_close(stream); for (i = 0; mpm->sync_cmd[i]; i++); args = talloc_array((TALLOC_CTX *)mpm, char *, i + 1); for (i = 0; mpm->sync_cmd[i]; i++){ if (strstr(mpm->sync_cmd[i], "__FILE__")) { args[i] = string_sub_talloc((TALLOC_CTX *)args, mpm->sync_cmd[i], "__FILE__", stream->filename); } else { args[i] = talloc_strdup((TALLOC_CTX *)args, mpm->sync_cmd[i]); } } args[i] = NULL; for (i = 0; args[i]; i++){ DEBUG(0, ("'%s' ", args[i])); } DEBUG(0, ("\n")); switch(pid = fork()) { case -1: DEBUG(0, ("Failed to fork\n")); break; case 0: ret = execve(args[0], args, NULL); break; default: wait(&status); break; } talloc_free(args); if (ret == -1) { perror("execve: "); return NT_STATUS_INVALID_PARAMETER; } ret = stat(stream->filename, &sb); if (ret == -1) { perror("stat: "); return NT_STATUS_INVALID_PARAMETER; } if (sb.st_size != stream->StreamSize) { DEBUG(0, ("Sync'd file size is 0x%x and 0x%x was expected\n", (uint32_t)sb.st_size, stream->StreamSize)); return NT_STATUS_INVALID_PARAMETER; } mpm_cache_stream_open(mpm, stream); stream->cached = true; return NT_STATUS_OK; } /** \details Track down Release calls and update the mpm_cache global list - removing associated entries. This function recursively remove child entries whenever necessary. \param dce_call pointer to the session context \param EcDoRpc pointer to the EcDoRpc operation \param handle_idx the handle to track down \return NT_STATUS_OK */ static NTSTATUS cache_pull_Release(struct dcesrv_call_state *dce_call, struct EcDoRpc *EcDoRpc, uint32_t handle_idx) { struct mpm_message *message; struct mpm_attachment *attach; struct mpm_stream *stream; char *server_id_printable = NULL; /* Look over messages */ for (message = mpm->messages; message; message = message->next) { if ((mpm_session_cmp(message->session, dce_call) == true) && (EcDoRpc->in.mapi_request->handles[handle_idx] == message->handle)) { server_id_printable = server_id_str(NULL, &(message->session->server_id)); DEBUG(2, ("* [%s:%d] [s(%s),c(0x%x)] Del: Message 0x%"PRIx64" 0x%"PRIx64": 0x%x\n", MPM_LOCATION, server_id_printable, message->session->context_id, message->FolderId, message->MessageId, message->handle)); talloc_free(server_id_printable); /* Loop over children attachments */ attach = mpm->attachments; while (attach) { if ((mpm_session_cmp(attach->session, dce_call) == true) && (message->handle == attach->parent_handle)) { server_id_printable = server_id_str(NULL, &(attach->session->server_id)); DEBUG(2, ("* [%s:%d] [s(%s),c(0x%x)] Del recursive 1: Attachment %d: 0x%x\n", MPM_LOCATION, server_id_printable, attach->session->context_id, attach->AttachmentID, attach->handle)); talloc_free(server_id_printable); /* Loop over children streams */ stream = mpm->streams; while (stream) { if ((mpm_session_cmp(stream->session, dce_call) == true) && (attach->handle == stream->parent_handle)) { server_id_printable = server_id_str(NULL, &(stream->session->server_id)); DEBUG(2, ("* [%s:%d] [s(%s),c(0x%x)] Del recursive 1-2: Stream 0x%x\n", MPM_LOCATION, server_id_printable, stream->session->context_id, stream->handle)); talloc_free(server_id_printable); mpm_session_release(stream->session); mpm_cache_stream_close(stream); talloc_free(stream->filename); DLIST_REMOVE(mpm->streams, stream); talloc_free(stream); stream = mpm->streams; } else { stream = stream->next; } } mpm_session_release(attach->session); DLIST_REMOVE(mpm->attachments, attach); talloc_free(attach); attach = mpm->attachments; } else { attach = attach->next; } } /* Look over children streams */ stream = mpm->streams; while (stream) { if ((mpm_session_cmp(stream->session, dce_call) == true) && (message->handle == stream->parent_handle)) { server_id_printable = server_id_str(NULL, &(stream->session->server_id)); DEBUG(2, ("* [%s:%d] [s(%s),c(0x%x)] Del recursive 1: Stream 0x%x\n", MPM_LOCATION, server_id_printable, stream->session->context_id, stream->handle)); talloc_free(server_id_printable); mpm_session_release(stream->session); mpm_cache_stream_close(stream); DLIST_REMOVE(mpm->streams, stream); talloc_free(stream->filename); talloc_free(stream); stream = mpm->streams; } else { stream = stream->next; } } mpm_session_release(message->session); DLIST_REMOVE(mpm->messages, message); talloc_free(message); return NT_STATUS_OK; } } /* Look over attachments */ for (attach = mpm->attachments; attach; attach = attach->next) { if ((mpm_session_cmp(attach->session, dce_call) == true) && (EcDoRpc->in.mapi_request->handles[handle_idx] == attach->handle)) { server_id_printable = server_id_str(NULL, &(attach->session->server_id)); DEBUG(2, ("* [%s:%d] [s(%s),c(0x%x)] Del: Attachment %d: 0x%x\n", MPM_LOCATION, server_id_printable, attach->session->context_id, attach->AttachmentID, attach->handle)); talloc_free(server_id_printable); /* Loop over children streams */ stream = mpm->streams; while (stream) { if ((mpm_session_cmp(stream->session, dce_call) == true) && (attach->handle == stream->parent_handle)) { server_id_printable = server_id_str(NULL, &(stream->session->server_id)); DEBUG(2, ("* [%s:%d] [s(%s),c(0x%x)] Del recursive 2: Stream 0x%x\n", MPM_LOCATION, server_id_printable, stream->session->context_id, stream->handle)); talloc_free(server_id_printable); mpm_session_release(stream->session); mpm_cache_stream_close(stream); DLIST_REMOVE(mpm->streams, stream); talloc_free(stream->filename); talloc_free(stream); stream = mpm->streams; } else { stream = stream->next; } } mpm_session_release(attach->session); DLIST_REMOVE(mpm->attachments, attach); talloc_free(attach); return NT_STATUS_OK; } } /* Look over streams */ for (stream = mpm->streams; stream; stream = stream->next) { if ((mpm_session_cmp(stream->session, dce_call) == true) && (EcDoRpc->in.mapi_request->handles[handle_idx] == stream->handle)) { server_id_printable = server_id_str(NULL, &(stream->session->server_id)); DEBUG(2, ("* [%s:%d] [s(%s),c(0x%x)] Del: Stream 0x%x\n", MPM_LOCATION, server_id_printable, stream->session->context_id, stream->handle)); talloc_free(server_id_printable); mpm_session_release(stream->session); mpm_cache_stream_close(stream); DLIST_REMOVE(mpm->streams, stream); talloc_free(stream->filename); talloc_free(stream); return NT_STATUS_OK; } } return NT_STATUS_OK; } /** \details Monitor OpenMessage requests and register a message in the mpm_messages list. This is the first step for message registration: * set Folder ID and Message ID * set the handle to 0xFFFFFFFF * Insert the message to the list \param dce_call pointer to the session context \param mem_ctx the memory context \param request reference to the OpenMessage request \return NT_STATUS_OK on success */ static NTSTATUS cache_pull_OpenMessage(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx, struct OpenMessage_req request) { struct mpm_message *message; /* Check if the message has already been registered */ for (message = mpm->messages; message; message = message->next) { if ((mpm_session_cmp(message->session, dce_call) == true) && (request.FolderId == message->FolderId) && (request.MessageId == message->MessageId)) { DLIST_REMOVE(mpm->messages, message); } } message = talloc((TALLOC_CTX *)mpm, struct mpm_message); NT_STATUS_HAVE_NO_MEMORY(message); message->session = mpm_session_init((TALLOC_CTX *)mpm, dce_call); NT_STATUS_HAVE_NO_MEMORY(message->session); message->FolderId = request.FolderId; message->MessageId = request.MessageId; message->handle = 0xFFFFFFFF; DLIST_ADD_END(mpm->messages, message, struct mpm_message *); return NT_STATUS_OK; } /** \details Monitor OpenMessage replies and store OpenMessage MAPI handle. This is the second step for message registration: * Seek for a given FolderId/MessageId in the mpm_message list * If a match is found (expected) and MAPI retval is set to MAPI_E_SUCCESS, update the handle field for the element and commit this message in the tdb store. * If retval is different from MAPI_E_SUCCESS, then delete the record \param dce_call pointer to the session context \param mapi_req reference to the OpenMessage MAPI request entry \param mapi_repl reference to the OpenMessage MAPI response entry \param EcDoRpc pointer to the current EcDoRpc operation \return NT_STATUS_OK */ static NTSTATUS cache_push_OpenMessage(struct dcesrv_call_state *dce_call, struct EcDoRpc_MAPI_REQ mapi_req, struct EcDoRpc_MAPI_REPL mapi_repl, struct EcDoRpc *EcDoRpc) { struct mpm_message *el; struct mapi_response *mapi_response; struct OpenMessage_req request; char *server_id_printable = NULL; request = mapi_req.u.mapi_OpenMessage; mapi_response = EcDoRpc->out.mapi_response; for (el = mpm->messages; el; el = el->next) { if ((el->FolderId == request.FolderId) && (el->MessageId == request.MessageId) && (mpm_session_cmp(el->session, dce_call) == true)) { if (mapi_repl.error_code == MAPI_E_SUCCESS) { mpm_cache_ldb_add_message((TALLOC_CTX *)mpm, mpm->ldb_ctx, el); el->handle = mapi_response->handles[request.handle_idx]; server_id_printable = server_id_str(NULL, &(el->session->server_id)); DEBUG(2, ("* [%s:%d] [s(%s),c(0x%x)] Add: Message 0x%"PRIx64" 0x%"PRIx64" 0x%x\n", MPM_LOCATION, server_id_printable, el->session->context_id, el->FolderId, el->MessageId, el->handle)); talloc_free(server_id_printable); } else { server_id_printable = server_id_str(NULL, &(el->session->server_id)); DEBUG(0, ("* [%s:%d] [s(%s),c(0x%x)] Del: Message OpenMessage returned %s\n", MPM_LOCATION, server_id_printable, el->session->context_id, mapi_get_errstr(mapi_repl.error_code))); talloc_free(server_id_printable); DLIST_REMOVE(mpm->messages, el); } return NT_STATUS_OK; } } return NT_STATUS_OK; } /** \details Monitor OpenAttach requests and register an attachment in the mpm_messages list. This is the first step for attachment registration. This function first ensures the attachment is not already registered, otherwise delete it. It next creates the attachment entry in the global mpm_message structure. \param dce_call pointer to the session context \param mem_ctx the memory context \param mapi_req reference to the OpenAttach EcDoRpc_MAPI_REQ entry \param EcDoRpc pointer to the EcDoRpc operation \return NT_STATUS_OK on success, otherwise NT_STATUS_NO_MEMORY */ static NTSTATUS cache_pull_OpenAttach(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx, struct EcDoRpc_MAPI_REQ mapi_req, struct EcDoRpc *EcDoRpc) { struct mpm_message *el; struct mpm_attachment *attach; struct mapi_request *mapi_request; struct OpenAttach_req request; char *server_id_printable = NULL; mapi_request = EcDoRpc->in.mapi_request; request = mapi_req.u.mapi_OpenAttach; for (attach = mpm->attachments; attach; attach = attach->next) { /* Check if the attachment has already been registered */ if ((mpm_session_cmp(attach->session, dce_call) == true) && (mapi_request->handles[mapi_req.handle_idx] == attach->parent_handle) && (request.AttachmentID == attach->AttachmentID)) { DLIST_REMOVE(mpm->attachments, attach); } } attach = talloc((TALLOC_CTX *)mpm, struct mpm_attachment); NT_STATUS_HAVE_NO_MEMORY(attach); attach->session = mpm_session_init((TALLOC_CTX *)mpm, dce_call); NT_STATUS_HAVE_NO_MEMORY(attach->session); attach->AttachmentID = request.AttachmentID; attach->parent_handle = mapi_request->handles[mapi_req.handle_idx]; attach->handle = 0xFFFFFFFF; for (el = mpm->messages; el; el = el->next) { if ((mpm_session_cmp(el->session, dce_call) == true) && attach->parent_handle == el->handle) { attach->message = el; break; } } server_id_printable = server_id_str(NULL, &(attach->session->server_id)); DEBUG(2, ("* [%s:%d] [s(%s),c(0x%x)] Add [1]: Attachment %d parent handle (0x%x) 0x%"PRIx64", 0x%"PRIx64" added to the list\n", MPM_LOCATION, server_id_printable, attach->session->context_id, request.AttachmentID, attach->parent_handle, attach->message->FolderId, attach->message->MessageId)); talloc_free(server_id_printable); DLIST_ADD_END(mpm->attachments, attach, struct mpm_attachment *); return NT_STATUS_OK; } /** \details Monitor OpenAttach replies and store OpenAttach MAPI handle. This is the second step for attachment registration: * Seek for a given parent_handle/attachmentID in the mpm_attachments list. * if a match is found (expected) and MAPI retval is set to MAPI_E_SUCCESS, update the handle parameter for the element and commit this attachment in the tdb store. * If retval is different from MAPI_E_SUCCESS, then delete the element. \param dce_call pointer to the session context \param mapi_req reference to the OpenAttach request entry \param mapi_repl reference to the OpenAttach MAPI response entry \param EcDoRpc pointer to the current EcDoRpc operation \return NT_STATUS_OK */ static NTSTATUS cache_push_OpenAttach(struct dcesrv_call_state *dce_call, struct EcDoRpc_MAPI_REQ mapi_req, struct EcDoRpc_MAPI_REPL mapi_repl, struct EcDoRpc *EcDoRpc) { struct mpm_attachment *el; struct mapi_request *mapi_request; struct mapi_response *mapi_response; struct OpenAttach_req request; char *server_id_printable = NULL; mapi_request = EcDoRpc->in.mapi_request; mapi_response = EcDoRpc->out.mapi_response; request = mapi_req.u.mapi_OpenAttach; for (el = mpm->attachments; el; el = el->next) { if ((mpm_session_cmp(el->session, dce_call) == true) && (mapi_request->handles[mapi_req.handle_idx] == el->parent_handle) && (request.AttachmentID == el->AttachmentID)) { if (mapi_repl.error_code == MAPI_E_SUCCESS) { el->handle = mapi_response->handles[request.handle_idx]; server_id_printable = server_id_str(NULL, &(el->session->server_id)); DEBUG(2, ("* [%s:%d] [s(%s),c(0x%x)] Add [2]: Attachment %d with handle 0x%x and parent handle 0x%x\n", MPM_LOCATION, server_id_printable, el->session->context_id, el->AttachmentID, el->handle, el->parent_handle)); talloc_free(server_id_printable); mpm_cache_ldb_add_attachment((TALLOC_CTX *)mpm, mpm->ldb_ctx, el); } else { server_id_printable = server_id_str(NULL, &(el->session->server_id)); DEBUG(0, ("* [%s:%d] [s(%s),c(0x%x)] Del: Attachment OpenAttach returned %s\n", MPM_LOCATION, server_id_printable, el->session->context_id, mapi_get_errstr(mapi_repl.error_code))); talloc_free(server_id_printable); DLIST_REMOVE(mpm->attachments, el); } return NT_STATUS_OK; } } return NT_STATUS_OK; } /** \details Monitor OpenStream requests and register a stream in the mpm_streams list. We are only interested in monitoring streams related to attachments or messages. This is the first step for stream registration: * Look whether this stream inherits from a message or attachment * Fill the stream element according to previous statement * Add it to the mpm_stream list \param dce_call pointer to the session context \param mem_ctx the memory context \param mapi_req reference to the OpenStream MAPI request \param EcDoRpc pointer to the current EcDoRpc operation \return NT_STATUS_OK on success, otherwise NT_STATUS_NO_MEMORY */ static NTSTATUS cache_pull_OpenStream(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx, struct EcDoRpc_MAPI_REQ mapi_req, struct EcDoRpc *EcDoRpc) { struct mpm_stream *stream; struct mpm_attachment *attach; struct mpm_message *message; struct mapi_request *mapi_request; struct OpenStream_req request; char *server_id_printable = NULL; mapi_request = EcDoRpc->in.mapi_request; request = mapi_req.u.mapi_OpenStream; for (attach = mpm->attachments; attach; attach = attach->next) { if ((mpm_session_cmp(attach->session, dce_call) == true) && mapi_request->handles[mapi_req.handle_idx] == attach->handle) { stream = talloc((TALLOC_CTX *)mpm, struct mpm_stream); NT_STATUS_HAVE_NO_MEMORY(stream); stream->session = mpm_session_init((TALLOC_CTX *)mpm, dce_call); NT_STATUS_HAVE_NO_MEMORY(stream->session); stream->handle = 0xFFFFFFFF; stream->parent_handle = attach->handle; stream->PropertyTag = request.PropertyTag; stream->StreamSize = 0; stream->filename = NULL; stream->attachment = attach; stream->cached = false; stream->message = NULL; stream->ahead = (mpm->ahead == true) ? true : false; gettimeofday(&stream->tv_start, NULL); server_id_printable = server_id_str(NULL, &(stream->session->server_id)); DEBUG(2, ("* [%s:%d] [s(%s),c(0x%x)] Stream::attachment added 0x%x 0x%"PRIx64" 0x%"PRIx64"\n", MPM_LOCATION, server_id_printable, stream->session->context_id, stream->parent_handle, stream->attachment->message->FolderId, stream->attachment->message->MessageId)); talloc_free(server_id_printable); DLIST_ADD_END(mpm->streams, stream, struct mpm_stream *); return NT_STATUS_OK; } } for (message = mpm->messages; message; message = message->next) { if ((mpm_session_cmp(message->session, dce_call) == true) && mapi_request->handles[mapi_req.handle_idx] == message->handle) { stream = talloc((TALLOC_CTX *)mpm, struct mpm_stream); NT_STATUS_HAVE_NO_MEMORY(stream); stream->session = mpm_session_init((TALLOC_CTX *)mpm, dce_call); NT_STATUS_HAVE_NO_MEMORY(stream->session); stream->handle = 0xFFFFFFFF; stream->parent_handle = message->handle; stream->PropertyTag = request.PropertyTag; stream->StreamSize = 0; stream->filename = NULL; stream->attachment = NULL; stream->cached = false; stream->ahead = (mpm->ahead == true) ? true : false; gettimeofday(&stream->tv_start, NULL); server_id_printable = server_id_str(NULL, &(stream->session->server_id)); DEBUG(2, ("* [%s:%d] [s(%s),c(0x%x)] Stream::message added 0x%x\n", MPM_LOCATION, server_id_printable, stream->session->context_id, stream->parent_handle)); talloc_free(server_id_printable); stream->message = message; DLIST_ADD_END(mpm->streams, stream, struct mpm_stream *); return NT_STATUS_OK; } } DEBUG(1, ("* [%s:%d] Stream: Not related to any attachment or message ?!?\n", MPM_LOCATION)); return NT_STATUS_OK; } /** \details Monitor OpenStream replies and store the OpenStream MAPI handle. This is the second step for stream registration: * Seek the parent_handle/PropertyTag couple in the mpm_streams list. * If a match is found (expected) and MAPI retval is set to MAPI_E_SUCCESS, update the handle field and StreamSize parameters for the element and commit this stream in the tdb store. * If retval is different from MAPI_E_SUCCESS, then delete the * element. \param dce_call pointer to the session context \param mapi_req reference to the OpenStream MAPI request entry \param mapi_repl reference to the OpenStream MAPI response entry \param EcDoRpc pointer to the current EcDoRpc operation \return NT_STATUS_OK */ static NTSTATUS cache_push_OpenStream(struct dcesrv_call_state *dce_call, struct EcDoRpc_MAPI_REQ mapi_req, struct EcDoRpc_MAPI_REPL mapi_repl, struct EcDoRpc *EcDoRpc) { struct mpm_stream *el; struct mapi_request *mapi_request; struct mapi_response *mapi_response; struct OpenStream_req request; struct OpenStream_repl response; char *server_id_printable = NULL; mapi_request = EcDoRpc->in.mapi_request; mapi_response = EcDoRpc->out.mapi_response; request = mapi_req.u.mapi_OpenStream; response = mapi_repl.u.mapi_OpenStream; for (el = mpm->streams; el; el = el->next) { if ((mpm_session_cmp(el->session, dce_call) == true) && (mapi_request->handles[mapi_req.handle_idx] == el->parent_handle)) { if (request.PropertyTag == el->PropertyTag) { if (mapi_repl.error_code == MAPI_E_SUCCESS) { el->handle = mapi_response->handles[request.handle_idx]; el->StreamSize = response.StreamSize; server_id_printable = server_id_str(NULL, &(el->session->server_id)); DEBUG(2, ("* [%s:%d] [s(%s),c(0x%x)] Add [2]: Stream for Property Tag 0x%x, handle 0x%x and size = %d\n", MPM_LOCATION, server_id_printable, el->session->context_id, el->PropertyTag, el->handle, el->StreamSize)); talloc_free(server_id_printable); mpm_cache_ldb_add_stream(mpm, mpm->ldb_ctx, el); } else { server_id_printable = server_id_str(NULL, &(el->session->server_id)); DEBUG(0, ("* [%s:%d] [s(%s),c(0x%x)] Del: Stream OpenStream returned %s\n", MPM_LOCATION, server_id_printable, el->session->context_id, mapi_get_errstr(mapi_repl.error_code))); talloc_free(server_id_printable); DLIST_REMOVE(mpm->streams, el); } return NT_STATUS_OK; } } } return NT_STATUS_OK; } /** \details Monitor ReadStream replies. This function writes ReadStream data received from remote server and associated to messages or attachments to the opened associated file. This function only writes data if the file is not already cached, otherwise it just returns. \param dce_call pointer to the session context \param mapi_req reference to the ReadStream MAPI request \param mapi_repl reference to the ReadStream MAPI reply \param EcDoRpc pointer to the current EcDoRpc operation \return NT_STATUS_OK \sa cache_dispatch */ static NTSTATUS cache_push_ReadStream(struct dcesrv_call_state *dce_call, struct EcDoRpc_MAPI_REQ mapi_req, struct EcDoRpc_MAPI_REPL mapi_repl, struct EcDoRpc *EcDoRpc) { struct mpm_stream *stream; struct mapi_response *mapi_response; struct ReadStream_repl response; /* struct ReadStream_req request; */ char *server_id_printable = NULL; mapi_response = EcDoRpc->out.mapi_response; response = mapi_repl.u.mapi_ReadStream; /* request = mapi_req.u.mapi_ReadStream; */ /* Check if the handle is registered */ for (stream = mpm->streams; stream; stream = stream->next) { if ((mpm_session_cmp(stream->session, dce_call) == true) && mapi_response->handles[mapi_repl.handle_idx] == stream->handle) { if (stream->fp && stream->cached == false) { if (mpm->sync == true && stream->StreamSize > mpm->sync_min) { cache_exec_sync_cmd(stream); } else { server_id_printable = server_id_str(NULL, &(stream->session->server_id)); DEBUG(5, ("* [%s:%d] [s(%s),c(0x%x)] %zd bytes from remove server\n", MPM_LOCATION, server_id_printable, stream->session->context_id, response.data.length)); talloc_free(server_id_printable); mpm_cache_stream_write(stream, response.data.length, response.data.data); if (stream->offset == stream->StreamSize) { if (response.data.length) { cache_dump_stream_stat(stream); } } } } else if (stream->cached == true) { /* This is managed by the dispatch routine */ } return NT_STATUS_OK; } } return NT_STATUS_OK; } /** \details Analyze EcDoRpc MAPI requests This function loops over EcDoRpc MAPI calls and search for the opnums required by the cache module to monitor Stream traffic properly. \param dce_call the session context \param mem_ctx the memory context \param r generic pointer on EcDoRpc operation \return NT_STATUS_OK */ static NTSTATUS cache_pull(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx, void *r) { struct EcDoRpc *EcDoRpc; struct EcDoRpc_MAPI_REQ *mapi_req; uint32_t i; if (dce_call->pkt.u.request.opnum != 0x2) { return NT_STATUS_OK; } EcDoRpc = (struct EcDoRpc *) r; if (!EcDoRpc) return NT_STATUS_OK; if (!&(EcDoRpc->in)) return NT_STATUS_OK; if (!EcDoRpc->in.mapi_request) return NT_STATUS_OK; if (!EcDoRpc->in.mapi_request->mapi_req) return NT_STATUS_OK; /* If this is an idle request, do not go further */ if (EcDoRpc->in.mapi_request->length == 2) { return NT_STATUS_OK; } mapi_req = EcDoRpc->in.mapi_request->mapi_req; for (i = 0; mapi_req[i].opnum; i++) { switch (mapi_req[i].opnum) { case op_MAPI_OpenMessage: cache_pull_OpenMessage(dce_call, (TALLOC_CTX *)mpm, mapi_req[i].u.mapi_OpenMessage); break; case op_MAPI_OpenAttach: cache_pull_OpenAttach(dce_call, (TALLOC_CTX *)mpm, mapi_req[i], EcDoRpc); break; case op_MAPI_OpenStream: cache_pull_OpenStream(dce_call, (TALLOC_CTX *)mpm, mapi_req[i], EcDoRpc); break; case op_MAPI_Release: cache_pull_Release(dce_call, EcDoRpc, mapi_req[i].handle_idx); break; } } return NT_STATUS_OK; } /** \details Analyze EcDoRpc MAPI responses This function loops over EcDoRpc MAPI calls and search for the opnums required by the cache module to monitor Stream traffic properly. \param dce_call pointer to the session context \param mem_ctx the memory context \param r generic pointer on EcDoRpc operation \return NT_STATUS_OK */ static NTSTATUS cache_push(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx, void *r) { struct EcDoRpc *EcDoRpc; struct EcDoRpc_MAPI_REPL *mapi_repl; struct EcDoRpc_MAPI_REQ *mapi_req; uint32_t i; uint32_t index; if (dce_call->pkt.u.request.opnum != 0x2) { return NT_STATUS_OK; } EcDoRpc = (struct EcDoRpc *) r; if (!EcDoRpc) return NT_STATUS_OK; if (!&(EcDoRpc->out)) return NT_STATUS_OK; if (!EcDoRpc->out.mapi_response) return NT_STATUS_OK; if (!EcDoRpc->out.mapi_response->mapi_repl) return NT_STATUS_OK; /* If this is an idle request, do not got further */ if (EcDoRpc->out.mapi_response->length == 2) { return NT_STATUS_OK; } mapi_repl = EcDoRpc->out.mapi_response->mapi_repl; mapi_req = EcDoRpc->in.mapi_request->mapi_req; for (i = 0; mapi_repl[i].opnum; i++) { switch (mapi_repl[i].opnum) { case op_MAPI_OpenMessage: index = cache_find_call_request_index(op_MAPI_OpenMessage, mapi_req); if (index == -1) break; cache_push_OpenMessage(dce_call, mapi_req[index], mapi_repl[i], EcDoRpc); break; case op_MAPI_OpenAttach: index = cache_find_call_request_index(op_MAPI_OpenAttach, mapi_req); if (index == -1) break; cache_push_OpenAttach(dce_call, mapi_req[index], mapi_repl[i], EcDoRpc); break; case op_MAPI_OpenStream: index = cache_find_call_request_index(op_MAPI_OpenStream, mapi_req); if (index == -1) break; cache_push_OpenStream(dce_call, mapi_req[index], mapi_repl[i], EcDoRpc); break; case op_MAPI_ReadStream: index = cache_find_call_request_index(op_MAPI_ReadStream, mapi_req); if (index == -1) break; cache_push_ReadStream(dce_call, mapi_req[index], mapi_repl[i], EcDoRpc); break; default: break; } } return NT_STATUS_OK; } /** \details Dispatch function. This function avoids calling dcerpc_ndr_request - understand forwarding client request to remove server - when the client is reading a message/attachment stream available in the cache. This function can also be used to loop over dcerpc_ndr_request and perform a read-ahead operation. \param dce_call the session context \param mem_ctx the memory context \param r pointer on EcDoRpc operation \param mapiproxy pointer to a mapiproxy structure controlling mapiproxy behavior. \return NT_STATUS_OK */ static NTSTATUS cache_dispatch(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx, void *r, struct mapiproxy *mapiproxy) { struct EcDoRpc *EcDoRpc; struct mapi_request *mapi_request; struct mapi_response *mapi_response; struct EcDoRpc_MAPI_REQ *mapi_req; struct mpm_stream *stream; uint32_t i; uint32_t count; if (dce_call->pkt.u.request.opnum != 0x2) { return NT_STATUS_OK; } EcDoRpc = (struct EcDoRpc *) r; if (!EcDoRpc->in.mapi_request->mapi_req) return NT_STATUS_OK; /* If this is an idle request, do not got further */ if (EcDoRpc->in.mapi_request->length == 2) { return NT_STATUS_OK; } mapi_request = EcDoRpc->in.mapi_request; mapi_response = EcDoRpc->out.mapi_response; mapi_req = mapi_request->mapi_req; for (count = 0, i = 0; mapi_req[i].opnum; i++) { switch (mapi_req[i].opnum) { case op_MAPI_ReadStream: count++; break; } } /* If we have more than count cached calls, forward to Exchange */ if (i > count) return NT_STATUS_OK; for (i = 0; mapi_req[i].opnum; i++) { switch (mapi_req[i].opnum) { case op_MAPI_ReadStream: { struct ReadStream_req request; request = mapi_req[i].u.mapi_ReadStream; for (stream = mpm->streams; stream; stream = stream->next) { if ((mpm_session_cmp(stream->session, dce_call) == true) && (mapi_request->handles[mapi_req[i].handle_idx] == stream->handle)) { if (stream->cached == true) { cached: mapiproxy->norelay = true; mapiproxy->ahead = false; /* Create a fake ReadStream reply */ mapi_response->mapi_repl = talloc_array(mem_ctx, struct EcDoRpc_MAPI_REPL, i + 2); mapi_response->mapi_repl[i].opnum = op_MAPI_ReadStream; mapi_response->mapi_repl[i].handle_idx = mapi_req[i].handle_idx; mapi_response->mapi_repl[i].error_code = MAPI_E_SUCCESS; mapi_response->mapi_repl[i].u.mapi_ReadStream.data.length = 0; mapi_response->mapi_repl[i].u.mapi_ReadStream.data.data = talloc_size(mem_ctx, request.ByteCount); mpm_cache_stream_read(stream, (size_t) request.ByteCount, &mapi_response->mapi_repl[i].u.mapi_ReadStream.data.length, &mapi_response->mapi_repl[i].u.mapi_ReadStream.data.data); if (stream->offset == stream->StreamSize) { if (mapi_response->mapi_repl[i].u.mapi_ReadStream.data.length) { cache_dump_stream_stat(stream); } } DEBUG(5, ("* [%s:%d] %zd bytes read from cache\n", MPM_LOCATION, mapi_response->mapi_repl[i].u.mapi_ReadStream.data.length)); mapi_response->handles = talloc_array(mem_ctx, uint32_t, 1); mapi_response->handles[0] = stream->handle; mapi_response->mapi_len = 0xE + mapi_response->mapi_repl[i].u.mapi_ReadStream.data.length; mapi_response->length = mapi_response->mapi_len - 4; *EcDoRpc->out.length = mapi_response->mapi_len; EcDoRpc->out.size = EcDoRpc->in.size; break; } else if ((stream->cached == false) && (stream->ahead == true)) { if (mapiproxy->ahead == true) { mpm_cache_stream_write(stream, mapi_response->mapi_repl[i].u.mapi_ReadStream.data.length, mapi_response->mapi_repl[i].u.mapi_ReadStream.data.data); /* When read ahead is over */ if (stream->offset == stream->StreamSize) { cache_dump_stream_stat(stream); mpm_cache_stream_reset(stream); stream->cached = true; stream->ahead = false; goto cached; } } else { mapiproxy->ahead = true; } } } } } break; } } return NT_STATUS_OK; } /** \details */ static NTSTATUS cache_unbind(struct server_id server_id, uint32_t context_id) { struct mpm_message *message; struct mpm_attachment *attach; struct mpm_stream *stream; char *server_id_printable = NULL; /* Look over messages still attached to the session */ message = mpm->messages; while (message) { if ((mpm_session_cmp_sub(message->session, server_id, context_id) == true)) { server_id_printable = server_id_str(NULL, &(message->session->server_id)); DEBUG(2, ("[%s:%d]: [s(%s),c(0x%x)] Message - 0x%"PRIx64"/0x%"PRIx64" handle(0x%x)\n", MPM_LOCATION, server_id_printable, message->session->context_id, message->FolderId, message->MessageId, message->handle)); talloc_free(server_id_printable); mpm_session_release(message->session); DLIST_REMOVE(mpm->messages, message); talloc_free(message); message = mpm->messages; } else { message = message->next; } } /* Look over attachments still attached to the session */ attach = mpm->attachments; while (attach) { if ((mpm_session_cmp_sub(attach->session, server_id, context_id) == true)) { server_id_printable = server_id_str(NULL, &(attach->session->server_id)); DEBUG(2, ("[%s:%d]: [s(%s),c(0x%x)] Attachment - AttachmentID(0x%x) handle(0x%x)\n", MPM_LOCATION, server_id_printable, attach->session->context_id, attach->AttachmentID, attach->handle)); talloc_free(server_id_printable); mpm_session_release(attach->session); DLIST_REMOVE(mpm->attachments, attach); talloc_free(attach); attach = mpm->attachments; } else { attach = attach->next; } } stream = mpm->streams; while (stream) { if ((mpm_session_cmp_sub(stream->session, server_id, context_id) == true)) { server_id_printable = server_id_str(NULL, &(stream->session->server_id)); DEBUG(2, ("[%s:%d]: [s(%s),c(0x%x)] Stream - handle(0x%x)\n", MPM_LOCATION, server_id_printable, stream->session->context_id, stream->handle)); talloc_free(server_id_printable); mpm_session_release(stream->session); mpm_cache_stream_close(stream); talloc_free(stream->filename); DLIST_REMOVE(mpm->streams, stream); talloc_free(stream); stream = mpm->streams; } else { stream = stream->next; } } return NT_STATUS_OK; } /** \details Initialize the cache module and retrieve configuration from smb.conf Possible smb.conf parameters: * mpm_cache:database \param dce_ctx the session context \return NT_STATUS_OK on success otherwise NT_STATUS_INVALID_PARAMETER, NT_STATUS_NO_MEMORY */ static NTSTATUS cache_init(struct dcesrv_context *dce_ctx) { char *database; NTSTATUS status; struct loadparm_context *lp_ctx; mpm = talloc_zero(dce_ctx, struct mpm_cache); if (!mpm) return NT_STATUS_NO_MEMORY; mpm->messages = NULL; mpm->attachments = NULL; mpm->streams = NULL; mpm->ahead = lpcfg_parm_bool(dce_ctx->lp_ctx, NULL, MPM_NAME, "ahead", false); mpm->sync = lpcfg_parm_bool(dce_ctx->lp_ctx, NULL, MPM_NAME, "sync", false); mpm->sync_min = lpcfg_parm_int(dce_ctx->lp_ctx, NULL, MPM_NAME, "sync_min", 500000); mpm->sync_cmd = str_list_make(dce_ctx, lpcfg_parm_string(dce_ctx->lp_ctx, NULL, MPM_NAME, "sync_cmd"), " "); mpm->dbpath = lpcfg_parm_string(dce_ctx->lp_ctx, NULL, MPM_NAME, "path"); if ((mpm->ahead == true) && mpm->sync) { DEBUG(0, ("%s: cache:ahead and cache:sync are exclusive!\n", MPM_ERROR)); talloc_free(mpm); return NT_STATUS_INVALID_PARAMETER; } if (!mpm->dbpath) { DEBUG(0, ("%s: Missing mpm_cache:path parameter\n", MPM_ERROR)); talloc_free(mpm); return NT_STATUS_INVALID_PARAMETER; } database = talloc_asprintf(dce_ctx->lp_ctx, "tdb://%s/%s", mpm->dbpath, MPM_DB); status = mpm_cache_ldb_createdb(dce_ctx, database, &mpm->ldb_ctx); if (!NT_STATUS_IS_OK(status)) { talloc_free(database); talloc_free(mpm); return NT_STATUS_NO_MEMORY; } lp_ctx = loadparm_init(dce_ctx); lpcfg_load_default(lp_ctx); dcerpc_init(); talloc_free(database); return NT_STATUS_OK; } /** \details Entry point for the cache mapiproxy module \return NT_STATUS_OK on success, otherwise NTSTATUS error */ NTSTATUS samba_init_module(void) { struct mapiproxy_module module; NTSTATUS ret; /* Fill in our name */ module.name = "cache"; module.description = "Cache MAPI messages and attachments"; module.endpoint = "exchange_emsmdb"; /* Fill in all the operations */ module.init = cache_init; module.unbind = cache_unbind; module.push = cache_push; module.ndr_pull = NULL; module.pull = cache_pull; module.dispatch = cache_dispatch; /* Register ourselves with the MAPIPROXY subsystem */ ret = mapiproxy_module_register(&module); if (!NT_STATUS_IS_OK(ret)) { DEBUG(0, ("Failed to register the 'cache' mapiproxy module!\n")); return ret; } return ret; } openchange-2.0/mapiproxy/modules/mpm_cache.h000066400000000000000000000064361223057412600212620ustar00rootroot00000000000000/* MAPI Proxy - Cache module OpenChange Project Copyright (C) Julien Kerihuel 2008 This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see . */ #ifndef __MPM_CACHE_H #define __MPM_CACHE_H #include #include #include #include #ifndef __BEGIN_DECLS #ifdef __cplusplus #define __BEGIN_DECLS extern "C" { #define __END_DECLS } #else #define __BEGIN_DECLS #define __END_DECLS #endif #endif struct mpm_message { struct mpm_session *session; uint32_t handle; uint64_t FolderId; uint64_t MessageId; struct mpm_message *prev; struct mpm_message *next; }; struct mpm_attachment { struct mpm_session *session; uint32_t parent_handle; uint32_t handle; uint32_t AttachmentID; struct mpm_message *message; struct mpm_attachment *prev; struct mpm_attachment *next; }; /** A stream can either be for a message or attachment */ struct mpm_stream { struct mpm_session *session; uint32_t parent_handle; uint32_t handle; enum MAPITAGS PropertyTag; uint32_t StreamSize; size_t offset; FILE *fp; char *filename; bool cached; bool ahead; struct timeval tv_start; struct mpm_attachment *attachment; struct mpm_message *message; struct mpm_stream *prev; struct mpm_stream *next; }; /* TODO: Make use of dce_ctx->context->context_id to differentiate sessions ? */ struct mpm_cache { struct ldb_context *ldb_ctx; struct mpm_message *messages; struct mpm_attachment *attachments; struct mpm_stream *streams; const char *dbpath; bool ahead; bool sync; int sync_min; char **sync_cmd; }; __BEGIN_DECLS NTSTATUS samba_init_module(void); NTSTATUS mpm_cache_ldb_createdb(struct dcesrv_context *, const char *, struct ldb_context **); NTSTATUS mpm_cache_ldb_add_message(TALLOC_CTX *, struct ldb_context *, struct mpm_message *); NTSTATUS mpm_cache_ldb_add_attachment(TALLOC_CTX *, struct ldb_context *, struct mpm_attachment *); NTSTATUS mpm_cache_ldb_add_stream(struct mpm_cache *, struct ldb_context *, struct mpm_stream *); NTSTATUS mpm_cache_stream_open(struct mpm_cache *, struct mpm_stream *); NTSTATUS mpm_cache_stream_close(struct mpm_stream *); NTSTATUS mpm_cache_stream_write(struct mpm_stream *, uint16_t, uint8_t *); NTSTATUS mpm_cache_stream_read(struct mpm_stream *, size_t, size_t *, uint8_t **); NTSTATUS mpm_cache_stream_reset(struct mpm_stream *); __END_DECLS /* * Defines */ #define MPM_NAME "mpm_cache" #define MPM_ERROR "[ERROR] mpm_cache:" #define MPM_DB "mpm_cache.ldb" #define MPM_DB_STORAGE "data" #define MPM_LOCATION __FUNCTION__, __LINE__ #define MPM_SESSION(x) x->session->server_id.pid, x->session->server_id.task_id, x->session->server_id.vnn, x->session->context_id #endif /* __MPM_CACHE_H */ openchange-2.0/mapiproxy/modules/mpm_cache_ldb.c000066400000000000000000000255501223057412600220740ustar00rootroot00000000000000/* MAPI Proxy - Cache module OpenChange Project Copyright (C) Julien Kerihuel 2008 This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see . */ /** \file mpm_cache_ldb.c \brief LDB routines for the cache module */ #include "mapiproxy/dcesrv_mapiproxy.h" #include "mapiproxy/libmapiproxy/libmapiproxy.h" #include "mapiproxy/modules/mpm_cache.h" #include "libmapi/libmapi.h" #include "libmapi/libmapi_private.h" #include /** \details Create the cache database \param dce_ctx pointer to the session context \param database the complete path to the tdb store \param ldb_ctx pointer to pointer on the the LDB context \return NT_STATUS_OK on success, otherwise NT_ERROR: NT_STATUS_NO_MEMORY, NT_STATUS_NOT_FOUND. */ NTSTATUS mpm_cache_ldb_createdb(struct dcesrv_context *dce_ctx, const char *database, struct ldb_context **ldb_ctx) { struct ldb_context *tmp_ctx; struct tevent_context *ev; int ret; ev = tevent_context_init(dce_ctx); if (!ev) return NT_STATUS_NO_MEMORY; tmp_ctx = ldb_init(dce_ctx, ev); if (!tmp_ctx) return NT_STATUS_NO_MEMORY; ret = ldb_connect(tmp_ctx, database, 0, NULL); if (ret != LDB_SUCCESS) { return NT_STATUS_NOT_FOUND; } *ldb_ctx = tmp_ctx; return NT_STATUS_OK; } /** \details Add a folder record to the TDB store \param mem_ctx pointer to the memory context \param ldb_ctx pointer to the LDB context \param FolderId the ID we will be using to uniquely create the record \return NT_STATUS_OK on success, otherwise NT_STATUS_NOT_FOUND */ static NTSTATUS mpm_cache_ldb_add_folder(TALLOC_CTX *mem_ctx, struct ldb_context *ldb_ctx, uint64_t FolderId) { struct ldb_message *msg; char *dn; int ret; msg = ldb_msg_new(mem_ctx); if (msg == NULL) { return NT_STATUS_NO_MEMORY; } dn = talloc_asprintf(mem_ctx, "CN=0x%"PRIx64",CN=Cache", FolderId); msg->dn = ldb_dn_new(ldb_ctx, ldb_ctx, dn); talloc_free(dn); if (!msg->dn) { return NT_STATUS_NO_MEMORY; } ret = ldb_add(ldb_ctx, msg); if (ret != 0) { DEBUG(0, ("* [%s:%d] Failed to modify record %s: %s\n", MPM_LOCATION, ldb_dn_get_linearized(msg->dn), ldb_errstring(ldb_ctx))); return NT_STATUS_UNSUCCESSFUL; } return NT_STATUS_OK; } /** \details Add a message record to the TDB store \param mem_ctx pointer to the memory context \param ldb_ctx pointer to the LDB context \param message pointer to the mpm_message entry with the folder and message ID \return NT_STATUS_OK on success, otherwise a NT error */ NTSTATUS mpm_cache_ldb_add_message(TALLOC_CTX *mem_ctx, struct ldb_context *ldb_ctx, struct mpm_message *message) { NTSTATUS status; struct ldb_message *msg; struct ldb_dn *dn; struct ldb_result *res; char *basedn; int ret; /* First check if the CN=Folder,CN=Cache entry exists */ basedn = talloc_asprintf(mem_ctx, "CN=0x%"PRIx64",CN=Cache", message->FolderId); dn = ldb_dn_new(mem_ctx, ldb_ctx, basedn); talloc_free(basedn); if (!dn) return NT_STATUS_UNSUCCESSFUL; ret = ldb_search(ldb_ctx, mem_ctx, &res, dn, LDB_SCOPE_BASE, NULL, NULL); if (ret == LDB_SUCCESS && !res->count) { DEBUG(5, ("* [%s:%d] We have to create folder TDB record: CN=0x%"PRIx64",CN=Cache\n", MPM_LOCATION, message->FolderId)); status = mpm_cache_ldb_add_folder(mem_ctx, ldb_ctx, message->FolderId); if (!NT_STATUS_IS_OK(status)) return status; } /* Search if the message doesn't already exist */ basedn = talloc_asprintf(mem_ctx, "CN=0x%"PRIx64",CN=0x%"PRIx64",CN=Cache", message->MessageId, message->FolderId); dn = ldb_dn_new(mem_ctx, ldb_ctx, basedn); talloc_free(basedn); if (!dn) return NT_STATUS_UNSUCCESSFUL; ret = ldb_search(ldb_ctx, mem_ctx, &res, dn, LDB_SCOPE_BASE, NULL, NULL); if (res->count) return NT_STATUS_OK; /* Create the CN=Message,CN=Folder,CN=Cache */ msg = ldb_msg_new(mem_ctx); if (msg == NULL) return NT_STATUS_NO_MEMORY; basedn = talloc_asprintf(mem_ctx, "CN=0x%"PRIx64",CN=0x%"PRIx64",CN=Cache", message->MessageId, message->FolderId); msg->dn = ldb_dn_new(ldb_ctx, ldb_ctx, basedn); talloc_free(basedn); if (!msg->dn) return NT_STATUS_NO_MEMORY; ret = ldb_add(ldb_ctx, msg); if (ret != 0) { DEBUG(0, ("* [%s:%d] Failed to modify record %s: %s\n", MPM_LOCATION, ldb_dn_get_linearized(msg->dn), ldb_errstring(ldb_ctx))); return NT_STATUS_UNSUCCESSFUL; } return NT_STATUS_OK; } /** \details Add an attachment record to the TDB store \param mem_ctx pointer to the memory context \param ldb_ctx pointer to the LDB context \param attach pointer to the mpm_attachment entry \return NT_STATUS_OK on success, otherwise a NT error */ NTSTATUS mpm_cache_ldb_add_attachment(TALLOC_CTX *mem_ctx, struct ldb_context *ldb_ctx, struct mpm_attachment *attach) { struct mpm_message *message; struct ldb_message *msg; struct ldb_dn *dn; struct ldb_result *res; char *basedn; int ret; message = attach->message; /* Search if the attachment doesn't already exist */ basedn = talloc_asprintf(mem_ctx, "CN=%d,CN=0x%"PRIx64",CN=0x%"PRIx64",CN=Cache", attach->AttachmentID, message->MessageId, message->FolderId); dn = ldb_dn_new(mem_ctx, ldb_ctx, basedn); talloc_free(basedn); if (!dn) return NT_STATUS_UNSUCCESSFUL; ret = ldb_search(ldb_ctx, mem_ctx, &res, dn, LDB_SCOPE_BASE, NULL, NULL); if (ret == LDB_SUCCESS && res->count) return NT_STATUS_OK; DEBUG(2, ("* [%s:%d] Create the attachment TDB record\n", MPM_LOCATION)); msg = ldb_msg_new(mem_ctx); if (msg == NULL) return NT_STATUS_NO_MEMORY; basedn = talloc_asprintf(mem_ctx, "CN=%d,CN=0x%"PRIx64",CN=0x%"PRIx64",CN=Cache", attach->AttachmentID, message->MessageId, message->FolderId); msg->dn = ldb_dn_new(ldb_ctx, ldb_ctx, basedn); talloc_free(basedn); if (!msg->dn) return NT_STATUS_NO_MEMORY; ret = ldb_add(ldb_ctx, msg); if (ret != 0) { DEBUG(0, ("* [%s:%d] Failed to modify record %s: %s\n", MPM_LOCATION, ldb_dn_get_linearized(msg->dn), ldb_errstring(ldb_ctx))); return NT_STATUS_UNSUCCESSFUL; } return NT_STATUS_OK; } /** \details Add stream references to a message or attachment in the TDB store \param mpm pointer to the cache module general structure \param ldb_ctx pointer to the LDB context \param stream pointer to the mpm_stream entry \return NT_STATUS_OK on success, otherwise NT error */ NTSTATUS mpm_cache_ldb_add_stream(struct mpm_cache *mpm, struct ldb_context *ldb_ctx, struct mpm_stream *stream) { TALLOC_CTX *mem_ctx; struct mpm_message *message; struct mpm_attachment *attach; struct ldb_message *msg; struct ldb_dn *dn; const char * const attrs[] = { "*", NULL }; struct ldb_result *res; char *basedn = NULL; char *attribute; int ret; uint32_t i; mem_ctx = (TALLOC_CTX *) mpm; if (stream->attachment) { attach = stream->attachment; message = attach->message; } else if (stream->message) { attach = NULL; message = stream->message; } else { return NT_STATUS_OK; } /* This is a stream for an attachment */ if (stream->attachment) { basedn = talloc_asprintf(mem_ctx, "CN=%d,CN=0x%"PRIx64",CN=0x%"PRIx64",CN=Cache", attach->AttachmentID, message->MessageId, message->FolderId); dn = ldb_dn_new(mem_ctx, ldb_ctx, basedn); talloc_free(basedn); if (!dn) return NT_STATUS_UNSUCCESSFUL; ret = ldb_search(ldb_ctx, mem_ctx, &res, dn, LDB_SCOPE_BASE, attrs, "(0x%x=*)", stream->PropertyTag); if (ret == LDB_SUCCESS && res->count == 1) { attribute = talloc_asprintf(mem_ctx, "0x%x", stream->PropertyTag); basedn = (char *) ldb_msg_find_attr_as_string(res->msgs[0], attribute, NULL); talloc_free(attribute); DEBUG(2, ("* [%s:%d] Loading from cache 0x%x = %s\n", MPM_LOCATION, stream->PropertyTag, basedn)); stream->filename = talloc_strdup(mem_ctx, basedn); stream->cached = true; stream->ahead = false; mpm_cache_stream_open(mpm, stream); return NT_STATUS_OK; } /* Otherwise create the stream with basedn above */ basedn = talloc_asprintf(mem_ctx, "CN=%d,CN=0x%"PRIx64",CN=0x%"PRIx64",CN=Cache", attach->AttachmentID, message->MessageId, message->FolderId); DEBUG(2, ("* [%s:%d] Create the stream TDB record for attachment\n", MPM_LOCATION)); } if (stream->message) { basedn = talloc_asprintf(mem_ctx, "CN=0x%"PRIx64",CN=0x%"PRIx64",CN=Cache", message->MessageId, message->FolderId); dn = ldb_dn_new(mem_ctx, ldb_ctx, basedn); talloc_free(basedn); if (!dn) return NT_STATUS_UNSUCCESSFUL; ret = ldb_search(ldb_ctx, mem_ctx, &res, dn, LDB_SCOPE_BASE, attrs, "(0x%x=*)", stream->PropertyTag); if (ret == LDB_SUCCESS && res->count == 1) { attribute = talloc_asprintf(mem_ctx, "0x%x", stream->PropertyTag); basedn = (char *) ldb_msg_find_attr_as_string(res->msgs[0], attribute, NULL); talloc_free(attribute); DEBUG(2, ("* [%s:%d] Loading from cache 0x%x = %s\n", MPM_LOCATION, stream->PropertyTag, basedn)); stream->filename = talloc_strdup(mem_ctx, basedn); stream->cached = true; stream->ahead = false; mpm_cache_stream_open(mpm, stream); return NT_STATUS_OK; } /* Otherwise create the stream with basedn above */ basedn = talloc_asprintf(mem_ctx, "CN=0x%"PRIx64",CN=0x%"PRIx64",CN=Cache", message->MessageId, message->FolderId); DEBUG(2, ("* [%s:%d] Modify the message TDB record and append stream information\n", MPM_LOCATION)); } stream->cached = false; mpm_cache_stream_open(mpm, stream); msg = ldb_msg_new(mem_ctx); if (msg == NULL) return NT_STATUS_NO_MEMORY; msg->dn = ldb_dn_new(ldb_ctx, ldb_ctx, basedn); talloc_free(basedn); if (!msg->dn) return NT_STATUS_NO_MEMORY; attribute = talloc_asprintf(mem_ctx, "0x%x", stream->PropertyTag); ldb_msg_add_fmt(msg, attribute, "%s", stream->filename); talloc_free(attribute); attribute = talloc_asprintf(mem_ctx, "0x%x_StreamSize", stream->PropertyTag); ldb_msg_add_fmt(msg, attribute, "%d", stream->StreamSize); talloc_free(attribute); /* mark all the message elements as LDB_FLAG_MOD_REPLACE */ for (i=0;inum_elements;i++) { msg->elements[i].flags = LDB_FLAG_MOD_REPLACE; } ret = ldb_modify(ldb_ctx, msg); if (ret != 0) { DEBUG(0, ("* [%s:%d] Failed to modify record %s: %s\n", MPM_LOCATION, ldb_dn_get_linearized(msg->dn), ldb_errstring(ldb_ctx))); return NT_STATUS_UNSUCCESSFUL; } return NT_STATUS_OK; } openchange-2.0/mapiproxy/modules/mpm_cache_stream.c000066400000000000000000000130001223057412600226110ustar00rootroot00000000000000/* MAPI Proxy - Cache module OpenChange Project Copyright (C) Julien Kerihuel 2008 This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see . */ /** \file mpm_cache_stream.c \brief Storage routines for the cache module */ #include "mapiproxy/dcesrv_mapiproxy.h" #include "mapiproxy/libmapiproxy/libmapiproxy.h" #include "mapiproxy/modules/mpm_cache.h" #include "libmapi/libmapi.h" #include "libmapi/libmapi_private.h" #include #include #include #include /** \details Create a file: message or attachment in the cache If the stream is attached to an attachment: FolderID/MessageID/AttachmentID.stream If the stream is attached to a message: FolderID/MessageID.stream \param mpm pointer to the cache module general structure \param stream pointer to the mpm_stream entry \return Return a FILE pointer otherwise NULL */ NTSTATUS mpm_cache_stream_open(struct mpm_cache *mpm, struct mpm_stream *stream) { TALLOC_CTX *mem_ctx; char *file; int ret; mem_ctx = (TALLOC_CTX *) mpm; if (stream->filename) { stream->fp = fopen(stream->filename, "r"); stream->offset = 0; return NT_STATUS_OK; } if (stream->message) { /* Create the folder */ file = talloc_asprintf(mem_ctx, "%s/0x%"PRIx64, mpm->dbpath, stream->message->FolderId); ret = mkdir(file, 0777); talloc_free(file); if ((ret == -1) && (errno != EEXIST)) return NT_STATUS_UNSUCCESSFUL; /* Open the file */ file = talloc_asprintf(mem_ctx, "%s/0x%"PRIx64"/0x%"PRIx64".stream", mpm->dbpath, stream->message->FolderId, stream->message->MessageId); DEBUG(2, ("* [%s:%d]: Opening Message stream %s\n", MPM_LOCATION, file)); stream->filename = talloc_strdup(mem_ctx, file); stream->fp = fopen(file, "w+"); stream->offset = 0; talloc_free(file); return NT_STATUS_OK; } if (stream->attachment) { /* Create the folders */ file = talloc_asprintf(mem_ctx, "%s/0x%"PRIx64, mpm->dbpath, stream->attachment->message->FolderId); ret = mkdir(file, 0777); talloc_free(file); if ((ret == -1) && (errno != EEXIST)) return NT_STATUS_UNSUCCESSFUL; file = talloc_asprintf(mem_ctx, "%s/0x%"PRIx64"/0x%"PRIx64, mpm->dbpath, stream->attachment->message->FolderId, stream->attachment->message->MessageId); ret = mkdir(file, 0777); talloc_free(file); if ((ret == -1) && (errno != EEXIST)) return NT_STATUS_UNSUCCESSFUL; file = talloc_asprintf(mem_ctx, "%s/0x%"PRIx64"/0x%"PRIx64"/%d.stream", mpm->dbpath, stream->attachment->message->FolderId, stream->attachment->message->MessageId, stream->attachment->AttachmentID); DEBUG(2, ("* [%s:%d]: Opening Attachment stream %s\n", MPM_LOCATION, file)); stream->filename = talloc_strdup(mem_ctx, file); stream->fp = fopen(file, "w+"); stream->offset = 0; talloc_free(file); return NT_STATUS_OK; } return NT_STATUS_OK; } /** \details Close the filesystem stream \param stream pointer to the mpm_stream entry \return NT_STATUS_OK on success, otherwise NT_STATUS_NOT_FOUND */ NTSTATUS mpm_cache_stream_close(struct mpm_stream *stream) { if (stream && stream->fp) { fclose(stream->fp); stream->fp = NULL; } else { return NT_STATUS_NOT_FOUND; } return NT_STATUS_OK; } /** \details Read input_size bytes from a local binary stream \param stream pointer to the mpm_stream entry \param input_size the number of bytes to read \param length output pointer to the length effectively read from the stream \param data output pointer to the binary data read from the stream \return NT_STATUS_OK */ NTSTATUS mpm_cache_stream_read(struct mpm_stream *stream, size_t input_size, size_t *length, uint8_t **data) { fseek(stream->fp, stream->offset, SEEK_SET); *length = fread(*data, sizeof (uint8_t), input_size, stream->fp); stream->offset += *length; DEBUG(5, ("* [%s:%d]: Current offset: 0x%zx\n", MPM_LOCATION, stream->offset)); return NT_STATUS_OK; } /** \details Write length bytes to a local stream \param stream pointer to the mpm_stream entry \param length the data length to write to the stream \param data pointer to the data to write to the stream \return NT_STATUS_OK on success, otherwise NT_STATUS_UNSUCCESSFUL */ NTSTATUS mpm_cache_stream_write(struct mpm_stream *stream, uint16_t length, uint8_t *data) { uint32_t WrittenSize; fseek(stream->fp, stream->offset, SEEK_SET); WrittenSize = fwrite(data, sizeof (uint8_t), length, stream->fp); if (WrittenSize != length) { DEBUG(0, ("* [%s:%d] WrittenSize != length\n", MPM_LOCATION)); return NT_STATUS_UNSUCCESSFUL; } stream->offset += WrittenSize; return NT_STATUS_OK; } /** \details Rewind a stream to the beginning \param stream pointer to the mpm_stream entry \return NT_STATUS_OK on success */ NTSTATUS mpm_cache_stream_reset(struct mpm_stream *stream) { fseek(stream->fp, 0, SEEK_SET); stream->offset = 0; return NT_STATUS_OK; } openchange-2.0/mapiproxy/modules/mpm_downgrade.c000066400000000000000000000101341223057412600221520ustar00rootroot00000000000000/* MAPI Proxy - Downgrade Module OpenChange Project Copyright (C) Julien Kerihuel 2008 This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see . */ /** \file mpm_downgrade.c \brief Downgrade EMSMDB protocol version EcDoConnect/EcDoRpc */ #include "mapiproxy/dcesrv_mapiproxy.h" #include "mapiproxy/dcesrv_mapiproxy_proto.h" #include "mapiproxy/libmapiproxy/libmapiproxy.h" #include /** \details This function replaces the store_version short array returned by Exchange in EcDoConnect with a version matching Exchange 2000. Otherwise Outlook tries to upgrade indefinitely. \param dce_call pointer to the session context \param r pointer to the EcDoConnect structure \return true on success */ static bool downgrade_EcDoConnect(struct dcesrv_call_state *dce_call, struct EcDoConnect *r) { r->out.rgwServerVersion[0] = 0x0006; r->out.rgwServerVersion[1] = 0x1141; r->out.rgwServerVersion[2] = 0x0005; return true; } static NTSTATUS downgrade_push(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx, void *r) { const struct ndr_interface_table *table; uint16_t opnum; const char *name; table = (const struct ndr_interface_table *)dce_call->context->iface->private_data; opnum = dce_call->pkt.u.request.opnum; name = table->calls[opnum].name; if (table->name && !strcmp(table->name, "exchange_emsmdb")) { if (name && !strcmp(name, "EcDoConnect")) { downgrade_EcDoConnect(dce_call, (struct EcDoConnect *)r); } } return NT_STATUS_OK; } static NTSTATUS downgrade_ndr_pull(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx, struct ndr_pull *pull) { return NT_STATUS_OK; } static NTSTATUS downgrade_pull(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx, void *r) { return NT_STATUS_OK; } /** \details Returns the nca_op_rng_error DCERPC status code when Outlook sends an EcDoConnectEx requrest. \param dce_call pointer to the session context \param mem_ctx pointer to the memory context \param r generic pointer to EcDoConnectEx structure \param mapiproxy pointer to the mapiproxy structure \return NT_STATUS_NET_WRITE_FAULT when EcDoConnectEx is detected, otherwise NT_STATUS_OK */ static NTSTATUS downgrade_dispatch(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx, void *r, struct mapiproxy *mapiproxy) { const struct ndr_interface_table *table; uint16_t opnum; table = (const struct ndr_interface_table *)dce_call->context->iface->private_data; opnum = dce_call->pkt.u.request.opnum; if ((opnum == 0xA) && (table->name && !strcmp(table->name, "exchange_emsmdb"))) { dce_call->fault_code = DCERPC_FAULT_OP_RNG_ERROR; return NT_STATUS_NET_WRITE_FAULT; } return NT_STATUS_OK; } /** \details Entry point for the downgrade mapiproxy module \return NT_STATUS_OK on success, otherwise NTSTATUS error */ NTSTATUS samba_init_module(void) { struct mapiproxy_module module; NTSTATUS ret; /* Fill in our name */ module.name = "downgrade"; module.description = "Downgrade EMSMDB protocol version EcDoConnect/EcDoRpc"; module.endpoint = "exchange_emsmdb"; /* Fill in all the operations */ module.init = NULL; module.unbind = NULL; module.push = downgrade_push; module.ndr_pull = downgrade_ndr_pull; module.pull = downgrade_pull; module.dispatch = downgrade_dispatch; /* Register ourselves with the MAPIPROXY subsystem */ ret = mapiproxy_module_register(&module); if (!NT_STATUS_IS_OK(ret)) { DEBUG(0, ("Failed to register the 'downgrade' mapiproxy module!\n")); return ret; } return ret; } openchange-2.0/mapiproxy/modules/mpm_dummy.c000066400000000000000000000050111223057412600213310ustar00rootroot00000000000000/* MAPI Proxy - Dummy Module OpenChange Project Copyright (C) Julien Kerihuel 2008 This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see . */ #include "mapiproxy/dcesrv_mapiproxy.h" #include "mapiproxy/dcesrv_mapiproxy_proto.h" #include /** \details Dummy init function which reads a parametric option from smb.conf and display it on the log channel. */ static NTSTATUS dummy_init(struct dcesrv_context *dce_ctx) { const char *test; test = lpcfg_parm_string(dce_ctx->lp_ctx, NULL, "mpm_dummy", "test"); if (test) { DEBUG(0, ("Sample dummy string: %s\n", test)); } return NT_STATUS_OK; } static NTSTATUS dummy_unbind(struct server_id server_id, uint32_t context_id) { return NT_STATUS_OK; } static NTSTATUS dummy_push(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx, void *r) { return NT_STATUS_OK; } static NTSTATUS dummy_ndr_pull(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx, struct ndr_pull *ndr) { return NT_STATUS_OK; } static NTSTATUS dummy_pull(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx, void *r) { return NT_STATUS_OK; } static NTSTATUS dummy_dispatch(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx, void *r, struct mapiproxy *mapiproxy) { return NT_STATUS_OK; } NTSTATUS samba_init_module(void) { struct mapiproxy_module module; NTSTATUS ret; /* Fill in our name */ module.name = "dummy"; module.description = "dummy MAPIPROXY module"; module.endpoint = "exchange_emsmdb"; /* Fill in all the operations */ module.init = dummy_init; module.unbind = dummy_unbind; module.push = dummy_push; module.ndr_pull = dummy_ndr_pull; module.pull = dummy_pull; module.dispatch = dummy_dispatch; /* Register ourselves with the MAPIPROXY subsytem */ ret = mapiproxy_module_register(&module); if (!NT_STATUS_IS_OK(ret)) { DEBUG(0, ("Failed to register 'dummy' mapiproxy module!\n")); return ret; } return ret; } openchange-2.0/mapiproxy/modules/mpm_pack.c000066400000000000000000000227761223057412600211350ustar00rootroot00000000000000/* MAPI Proxy - Unpack/Pack Module OpenChange Project Copyright (C) Julien Kerihuel 2008 This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see . */ /** \file mpm_pack.c \brief Pack/Unpack specified MAPI calls into/from a custom MAPI call */ #include "mapiproxy/dcesrv_mapiproxy.h" #include "mapiproxy/libmapiproxy/libmapiproxy.h" #include #define MPM_NAME "mpm_pack" #define MPM_PACK_ERROR "[ERROR] mpm_pack:" NTSTATUS samba_init_module(void); static struct mpm_pack { uint8_t *mapi_calls; bool lasthop; } *mpm = NULL; static uint32_t proxypack(TALLOC_CTX *mem_ctx, struct EcDoRpc_MAPI_REQ *mapi_req, struct ndr_push *ndr) { struct proxypack_req request; uint32_t size; /* Fill in the proxypack operation */ size = 0; request.bin.cb = ndr->offset; size += sizeof (uint16_t); request.bin.lpb = talloc_memdup(mem_ctx, ndr->data, ndr->offset); size += ndr->offset; /* Fill the MAPI_REQ request */ mapi_req->opnum = op_MAPI_proxypack; mapi_req->logon_id = 0; mapi_req->handle_idx = 0; mapi_req->u.mapi_proxypack = request; size += 5; return size; } /** \details unpack proxypack contents and restore the original EcDoRpc request */ static bool unpack(TALLOC_CTX *mem_ctx, struct EcDoRpc *EcDoRpc) { struct EcDoRpc_MAPI_REQ *mapi_req; struct EcDoRpc_MAPI_REQ *mapi_newreq; struct ndr_pull *ndr; bool found; uint32_t i; uint8_t pos; uint32_t count; uint32_t nopack_count = 0; uint32_t nopack_idx = 0; uint32_t pack_idx = 0; mapi_req = EcDoRpc->in.mapi_request->mapi_req; /* Seek the unpack call */ for (i = 0, found = false; mapi_req[i].opnum; i++) { if (mapi_req[i].opnum == op_MAPI_proxypack) { found = true; break; } } /* Nothing to unpack */ if (found == false) return false; ndr = talloc_zero(mem_ctx, struct ndr_pull); ndr->data_size = mapi_req[i].u.mapi_proxypack.bin.cb; ndr->data = mapi_req[i].u.mapi_proxypack.bin.lpb; for (nopack_count = 0; mapi_req[nopack_count].opnum; nopack_count++); /* Merge unpacked and non packed calls < last packed call position */ mapi_newreq = talloc_zero(mem_ctx, struct EcDoRpc_MAPI_REQ); for (count = 0; ndr->offset != ndr->data_size; count++) { NDR_CHECK(ndr_pull_uint8(ndr, NDR_SCALARS, &pos)); if (pack_idx < pos) { while (pack_idx < pos) { if (nopack_idx >= nopack_count) break; mapi_newreq = talloc_realloc(mem_ctx, mapi_newreq, struct EcDoRpc_MAPI_REQ, pack_idx + 2); mapi_newreq[pack_idx] = mapi_req[nopack_idx]; nopack_idx++; pack_idx++; } } if (pos > pack_idx) { pack_idx = pos; } mapi_newreq = talloc_realloc(mem_ctx, mapi_newreq, struct EcDoRpc_MAPI_REQ, pack_idx + 2); NDR_CHECK(ndr_pull_EcDoRpc_MAPI_REQ(ndr, NDR_SCALARS, &mapi_newreq[pos])); pack_idx++; } /* Append remaining non packed calls */ mapi_newreq[pack_idx].opnum = 0; while (mapi_req[nopack_idx].opnum) { if (nopack_idx > nopack_count) break; if (mapi_req[nopack_idx].opnum != op_MAPI_proxypack) { mapi_newreq = talloc_realloc(mem_ctx, mapi_newreq, struct EcDoRpc_MAPI_REQ, pack_idx + 2); mapi_newreq[pack_idx] = mapi_req[nopack_idx]; pack_idx++; mapi_newreq[pack_idx].opnum = 0; } nopack_idx++; } /* Update mapi_request length and mapi_req pointer */ EcDoRpc->in.mapi_request->mapi_len -= (5 + count); EcDoRpc->in.mapi_request->length -= (5 + count); EcDoRpc->in.mapi_request->mapi_req = mapi_newreq; return true; } /** \details pack EcDoRpc calls into proxypack */ static bool pack(TALLOC_CTX *mem_ctx, struct EcDoRpc *EcDoRpc) { struct EcDoRpc_MAPI_REQ *mapi_req; struct EcDoRpc_MAPI_REQ *mapi_newreq; struct ndr_push *ndr; struct ndr_push *nopack_ndr; uint32_t size; uint32_t handle_size; uint32_t i, j; uint32_t idx; bool found; mapi_req = EcDoRpc->in.mapi_request->mapi_req; ndr = talloc_zero(mem_ctx, struct ndr_push); nopack_ndr = talloc_zero(mem_ctx, struct ndr_push); mapi_newreq = talloc_array(mem_ctx, struct EcDoRpc_MAPI_REQ, 2); for (i = 0, idx = 0; mapi_req[i].opnum; i++) { found = false; for (j = 0; mpm->mapi_calls[j]; j++) { if (mapi_req[i].opnum == mpm->mapi_calls[j]) { ndr_push_uint8(ndr, NDR_SCALARS, i); ndr_push_EcDoRpc_MAPI_REQ(ndr, NDR_SCALARS, &mapi_req[i]); found = true; break; } } if (found == false) { mapi_newreq = talloc_realloc(mem_ctx, mapi_newreq, struct EcDoRpc_MAPI_REQ, idx + 2); ndr_push_EcDoRpc_MAPI_REQ(nopack_ndr, NDR_SCALARS, &mapi_req[i]); mapi_newreq[idx] = mapi_req[i]; idx++; } } if (ndr->offset == 0) { talloc_free(mapi_newreq); talloc_free(nopack_ndr); talloc_free(ndr); return false; } DEBUG(3, ("============ non packed =============\n")); dump_data(3, nopack_ndr->data, nopack_ndr->offset); DEBUG(3, ("=====================================\n")); DEBUG(3, ("\n============ packed =============\n")); dump_data(3, ndr->data, ndr->offset); DEBUG(3, ("=================================\n")); /* Fill in the proxypack operation */ mapi_newreq = talloc_realloc(mem_ctx, mapi_newreq, struct EcDoRpc_MAPI_REQ, idx + 2); size = proxypack(mem_ctx, &mapi_newreq[idx], ndr); talloc_free(ndr); if (!size) return false; idx++; mapi_newreq[idx].opnum = 0; /* Recalculate the EcDoRpc request size */ handle_size = EcDoRpc->in.mapi_request->mapi_len - EcDoRpc->in.mapi_request->length; EcDoRpc->in.mapi_request->mapi_len = nopack_ndr->offset + size + handle_size; EcDoRpc->in.mapi_request->length = nopack_ndr->offset + size; /* Replace EcDoRpc_MAPI_REQ */ talloc_free(EcDoRpc->in.mapi_request->mapi_req); EcDoRpc->in.mapi_request->mapi_req = mapi_newreq; /* Free memory */ talloc_free(nopack_ndr); return true; } static NTSTATUS pack_push(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx, void *r) { return NT_STATUS_OK; } static NTSTATUS pack_ndr_pull(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx, struct ndr_pull *pull) { return NT_STATUS_OK; } /** \details pack EcDoRpc MAPI requests This function searches for MAPI opnums to pack in the requests, add this opnums to the mapiproxy opnum DATA blob and refactor the request to remove references to these calls in the original request. */ static NTSTATUS pack_pull(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx, void *r) { struct EcDoRpc *EcDoRpc; bool ret = false; if (dce_call->pkt.u.request.opnum != 0x2) { return NT_STATUS_OK; } EcDoRpc = (struct EcDoRpc *) r; if (!EcDoRpc->in.mapi_request->mapi_req) return NT_STATUS_OK; /* If this is an idle request, do not go further */ if (EcDoRpc->in.mapi_request->length == 2) { return NT_STATUS_OK; } /* If this is not a last-hop */ if (mpm->lasthop == false) return NT_STATUS_OK; ret = unpack(mem_ctx, EcDoRpc); if (ret == false) { ret = pack(mem_ctx, EcDoRpc); } return NT_STATUS_OK; } /** \details Initialize the pack module and retrieve configuration from smb.conf. Possible parameters: * mpm_pack:opnums = 0x1, 0x2, 0x3 * mpm_pack:lasthop = true|false */ static NTSTATUS pack_init(struct dcesrv_context *dce_ctx) { char **calls; unsigned long opnum; int i; int j; struct loadparm_context *lp_ctx; /* Fetch the mapi call list from smb.conf */ calls = str_list_make(dce_ctx, lpcfg_parm_string(dce_ctx->lp_ctx, NULL, MPM_NAME, "opnums"), NULL); mpm = talloc_zero(dce_ctx, struct mpm_pack); mpm->mapi_calls = talloc_zero(mpm, uint8_t); for (i = 0; calls[i]; i++) { opnum = strtol(calls[i], NULL, 16); if (opnum <= 0 || opnum >= 0xFF) { DEBUG(0, ("%s: invalid MAPI opnum 0x%.2x\n", MPM_PACK_ERROR, (uint32_t)opnum)); talloc_free(mpm); return NT_STATUS_INVALID_PARAMETER; } /* avoid duplicated opnums */ for (j = 0; j < i; j++) { if (opnum == mpm->mapi_calls[j]) { DEBUG(0, ("%s: duplicated opnum: 0x%.2x\n", MPM_PACK_ERROR, (uint32_t)opnum)); talloc_free(mpm); return NT_STATUS_INVALID_PARAMETER; } } mpm->mapi_calls = talloc_realloc(mpm, mpm->mapi_calls, uint8_t, i + 2); mpm->mapi_calls[i] = (uint8_t) opnum; } mpm->mapi_calls[i] = 0; /* Fetch the lasthop parameter from smb.conf */ mpm->lasthop = lpcfg_parm_bool(dce_ctx->lp_ctx, NULL, MPM_NAME, "lasthop", true); lp_ctx = loadparm_init(dce_ctx); lpcfg_load_default(lp_ctx); dcerpc_init(); return NT_STATUS_OK; } /** \details Entry point for the pack mapiproxy module \return NT_STATUS_OK on success, otherwise NTSTATUS error */ NTSTATUS samba_init_module(void) { struct mapiproxy_module module; NTSTATUS ret; /* Fill in our name */ module.name = "pack"; module.description = "Pack specified MAPI calls into a custom MAPI call"; module.endpoint = "exchange_emsmdb"; /* Fill in all the operations */ module.init = pack_init; module.unbind = NULL; module.push = pack_push; module.ndr_pull = pack_ndr_pull; module.pull = pack_pull; module.dispatch = NULL; /* Register ourselves with the MAPIPROXY subsystem */ ret = mapiproxy_module_register(&module); if (!NT_STATUS_IS_OK(ret)) { DEBUG(0, ("Failed to register the 'pack' mapiproxy module!\n"));; return ret; } return ret; } openchange-2.0/mapiproxy/servers/000077500000000000000000000000001223057412600172055ustar00rootroot00000000000000openchange-2.0/mapiproxy/servers/default/000077500000000000000000000000001223057412600206315ustar00rootroot00000000000000openchange-2.0/mapiproxy/servers/default/emsmdb/000077500000000000000000000000001223057412600221005ustar00rootroot00000000000000openchange-2.0/mapiproxy/servers/default/emsmdb/dcesrv_exchange_emsmdb.c000066400000000000000000002451111223057412600267270ustar00rootroot00000000000000/* MAPI Proxy - Exchange EMSMDB Server OpenChange Project Copyright (C) Julien Kerihuel 2009-2011 This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see . */ /** \file dcesrv_exchange_emsmdb.c \brief OpenChange EMSMDB Server implementation */ #include #include "mapiproxy/dcesrv_mapiproxy.h" #include "mapiproxy/libmapiserver/libmapiserver.h" #include "dcesrv_exchange_emsmdb.h" struct exchange_emsmdb_session *emsmdb_session = NULL; void *openchange_ldb_ctx = NULL; static struct exchange_emsmdb_session *dcesrv_find_emsmdb_session(struct GUID *uuid) { struct exchange_emsmdb_session *session, *found_session = NULL; for (session = emsmdb_session; !found_session && session; session = session->next) { if (GUID_equal(uuid, &session->uuid)) { found_session = session; } } return found_session; } /* FIXME: See _unbind below */ /* static struct exchange_emsmdb_session *dcesrv_find_emsmdb_session_by_server_id(const struct server_id *server_id, uint32_t context_id) */ /* { */ /* struct exchange_emsmdb_session *session; */ /* for (session = emsmdb_session; session; session = session->next) { */ /* if (session->session */ /* && session->session->server_id.id == server_id->id && session->session->server_id.id2 == server_id->id2 && session->session->server_id.node == server_id->node */ /* && session->session->context_id == context_id) { */ /* return session; */ /* } */ /* } */ /* return NULL; */ /* } */ /** \details exchange_emsmdb EcDoConnect (0x0) function \param dce_call pointer to the session context \param mem_ctx pointer to the memory context \param r pointer to the EcDoConnect request data \note Session linking is not supported at the moment \return MAPI_E_SUCCESS on success */ static enum MAPISTATUS dcesrv_EcDoConnect(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx, struct EcDoConnect *r) { struct emsmdbp_context *emsmdbp_ctx; struct dcesrv_handle *handle; struct policy_handle wire_handle; struct exchange_emsmdb_session *session; struct ldb_message *msg; const char *mailNickname; const char *userDN; char *dnprefix; DEBUG(3, ("exchange_emsmdb: EcDoConnect (0x0)\n")); /* Step 0. Ensure incoming user is authenticated */ if (!dcesrv_call_authenticated(dce_call)) { DEBUG(1, ("No challenge requested by client, cannot authenticate\n")); failure: wire_handle.handle_type = EXCHANGE_HANDLE_EMSMDB; wire_handle.uuid = GUID_zero(); *r->out.handle = wire_handle; r->out.pcmsPollsMax = talloc_zero(mem_ctx, uint32_t); r->out.pcRetry = talloc_zero(mem_ctx, uint32_t); r->out.pcmsRetryDelay = talloc_zero(mem_ctx, uint32_t); r->out.picxr = talloc_zero(mem_ctx, uint32_t); r->out.pullTimeStamp = talloc_zero(mem_ctx, uint32_t); *r->out.pcmsPollsMax = 0; *r->out.pcRetry = 0; *r->out.pcmsRetryDelay = 0; *r->out.szDisplayName = NULL; *r->out.szDNPrefix = NULL; r->out.rgwServerVersion[0] = 0; r->out.rgwServerVersion[1] = 0; r->out.rgwServerVersion[2] = 0; r->out.rgwClientVersion[0] = 0; r->out.rgwClientVersion[1] = 0; r->out.rgwClientVersion[2] = 0; *r->out.pullTimeStamp = 0; r->out.result = MAPI_E_LOGON_FAILED; return MAPI_E_LOGON_FAILED; } /* Step 1. Initialize the emsmdbp context */ emsmdbp_ctx = emsmdbp_init(dce_call->conn->dce_ctx->lp_ctx, dcesrv_call_account_name(dce_call), openchange_ldb_ctx); if (!emsmdbp_ctx) { smb_panic("unable to initialize emsmdbp context"); return MAPI_E_FAILONEPROVIDER; } /* Step 2. Check if incoming user belongs to the Exchange organization */ if (emsmdbp_verify_user(dce_call, emsmdbp_ctx) == false) { talloc_free(emsmdbp_ctx); goto failure; } /* Step 3. Check if input user DN belongs to the Exchange organization */ if (emsmdbp_verify_userdn(dce_call, emsmdbp_ctx, r->in.szUserDN, &msg) == false) { talloc_free(emsmdbp_ctx); goto failure; } emsmdbp_ctx->szUserDN = talloc_strdup(emsmdbp_ctx, r->in.szUserDN); emsmdbp_ctx->userLanguage = r->in.ulLcidString; /* Step 4. Retrieve the display name of the user */ *r->out.szDisplayName = ldb_msg_find_attr_as_string(msg, "displayName", NULL); emsmdbp_ctx->szDisplayName = talloc_strdup(emsmdbp_ctx, *r->out.szDisplayName); /* Step 5. Retrieve the dinstinguished name of the server */ mailNickname = ldb_msg_find_attr_as_string(msg, "mailNickname", NULL); userDN = ldb_msg_find_attr_as_string(msg, "legacyExchangeDN", NULL); dnprefix = strstr(userDN, mailNickname); if (!dnprefix) { talloc_free(emsmdbp_ctx); goto failure; } *dnprefix = '\0'; *r->out.szDNPrefix = strupper_talloc(mem_ctx, userDN); /* Step 6. Fill EcDoConnect reply */ handle = dcesrv_handle_new(dce_call->context, EXCHANGE_HANDLE_EMSMDB); OPENCHANGE_RETVAL_IF(!handle, MAPI_E_NOT_ENOUGH_RESOURCES, emsmdbp_ctx); handle->data = (void *) emsmdbp_ctx; *r->out.handle = handle->wire_handle; r->out.pcmsPollsMax = talloc_zero(mem_ctx, uint32_t); *r->out.pcmsPollsMax = EMSMDB_PCMSPOLLMAX; r->out.pcRetry = talloc_zero(mem_ctx, uint32_t); *r->out.pcRetry = EMSMDB_PCRETRY; r->out.pcmsRetryDelay = talloc_zero(mem_ctx, uint32_t); *r->out.pcmsRetryDelay = EMSMDB_PCRETRYDELAY; r->out.picxr = talloc_zero(mem_ctx, uint32_t); *r->out.picxr = 0; /* The following server version is not supported by Outlook 2010 */ r->out.rgwServerVersion[0] = 0x6; r->out.rgwServerVersion[1] = 0x1141; r->out.rgwServerVersion[2] = 0x5; /* This one is but requires EcDoConnectEx/EcDoRpcExt2/Async * EMSMDB implementation */ /* r->out.rgwServerVersion[0] = 0x8; */ /* r->out.rgwServerVersion[1] = 0x82B4; */ /* r->out.rgwServerVersion[2] = 0x3; */ r->out.rgwClientVersion[0] = r->in.rgwClientVersion[0]; r->out.rgwClientVersion[1] = r->in.rgwClientVersion[1]; r->out.rgwClientVersion[2] = r->in.rgwClientVersion[2]; r->out.pullTimeStamp = talloc_zero(mem_ctx, uint32_t); *r->out.pullTimeStamp = time(NULL); r->out.result = MAPI_E_SUCCESS; /* Search for an existing session and increment ref_count, otherwise create it */ session = dcesrv_find_emsmdb_session(&handle->wire_handle.uuid); if (session) { DEBUG(0, ("[exchange_emsmdb]: Increment session ref count for %d\n", session->session->context_id)); mpm_session_increment_ref_count(session->session); } else { /* Step 7. Associate this emsmdbp context to the session */ session = talloc((TALLOC_CTX *)emsmdb_session, struct exchange_emsmdb_session); OPENCHANGE_RETVAL_IF(!session, MAPI_E_NOT_ENOUGH_RESOURCES, emsmdbp_ctx); session->pullTimeStamp = *r->out.pullTimeStamp; session->session = mpm_session_init((TALLOC_CTX *)emsmdb_session, dce_call); OPENCHANGE_RETVAL_IF(!session->session, MAPI_E_NOT_ENOUGH_RESOURCES, emsmdbp_ctx); session->uuid = handle->wire_handle.uuid; mpm_session_set_private_data(session->session, (void *) emsmdbp_ctx); mpm_session_set_destructor(session->session, emsmdbp_destructor); DEBUG(0, ("[exchange_emsmdb]: New session added: %d\n", session->session->context_id)); DLIST_ADD_END(emsmdb_session, session, struct exchange_emsmdb_session *); } return MAPI_E_SUCCESS; } /** \details exchange_emsmdb EcDoDisconnect (0x1) function \param dce_call pointer to the session context \param mem_ctx pointer to the memory context \param r pointer to the EcDoDisconnect request data \return MAPI_E_SUCCESS on success */ static enum MAPISTATUS dcesrv_EcDoDisconnect(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx, struct EcDoDisconnect *r) { struct dcesrv_handle *h; struct exchange_emsmdb_session *session; bool ret; DEBUG(3, ("exchange_emsmdb: EcDoDisconnect (0x1)\n")); /* Step 0. Ensure incoming user is authenticated */ if (!dcesrv_call_authenticated(dce_call)) { DEBUG(1, ("No challenge requested by client, cannot authenticate\n")); return MAPI_E_LOGON_FAILED; } /* Step 1. Retrieve handle and free if emsmdbp context and session are available */ h = dcesrv_handle_fetch(dce_call->context, r->in.handle, DCESRV_HANDLE_ANY); if (h) { session = dcesrv_find_emsmdb_session(&r->in.handle->uuid); if (session) { ret = mpm_session_release(session->session); if (ret == true) { DLIST_REMOVE(emsmdb_session, session); DEBUG(5, ("[%s:%d]: Session found and released\n", __FUNCTION__, __LINE__)); } else { DEBUG(5, ("[%s:%d]: Session found and ref_count decreased\n", __FUNCTION__, __LINE__)); } } else { DEBUG(5, (" emsmdb_session NOT found\n")); } } r->out.handle->handle_type = 0; r->out.handle->uuid = GUID_zero(); r->out.result = MAPI_E_SUCCESS; return MAPI_E_SUCCESS; } static bool emsmdbp_fill_notification(TALLOC_CTX *mem_ctx, struct emsmdbp_context *emsmdbp_ctx, struct EcDoRpc_MAPI_REPL *mapi_repl, struct mapistore_subscription *subscription, struct mapistore_notification *notification, uint16_t *sizep) { bool success = true; struct Notify_repl *reply; struct emsmdbp_object *handle_object; struct emsmdbp_object_table *table; struct mapi_handles *handle_object_handle; enum MAPISTATUS retval; void **data_pointers; DATA_BLOB *table_row; enum MAPISTATUS *retvals; uint32_t contextID, saved_prop_count, prev_instance; enum MAPITAGS *saved_properties, *previous_row_properties; uint64_t prev_fid, prev_mid; mapi_repl->opnum = op_MAPI_Notify; reply = &mapi_repl->u.mapi_Notify; reply->LogonId = 0; /* TODO: seems to be always 0 ? */ retval = mapi_handles_search(emsmdbp_ctx->handles_ctx, subscription->handle, &handle_object_handle); if (retval) { reply->NotificationType = fnevCriticalError; DEBUG(5, ("notification handle not found\n")); goto end; } retval = mapi_handles_get_private_data(handle_object_handle, (void **) &handle_object); if (retval) { reply->NotificationType = fnevCriticalError; DEBUG(5, ("object not found for notification handle\n")); goto end; } reply->NotificationHandle = subscription->handle; switch (notification->object_type) { case MAPISTORE_MESSAGE: reply->NotificationType = fnevMbit; break; case MAPISTORE_FOLDER: if (notification->parameters.object_parameters.new_message_count) { reply->NotificationType = fnevTbit; } else { reply->NotificationType = 0; // FIXME - THIS IS WRONG - IT'S AN INVALID NOTIFICATION TYPE } break; case MAPISTORE_TABLE: reply->NotificationType = fnevTableModified; if (notification->parameters.table_parameters.table_type != MAPISTORE_FOLDER_TABLE) { reply->NotificationType |= (fnevMbit | fnevSbit); } break; default: reply->NotificationType = fnevCriticalError; DEBUG(5, ("unknown value for notification object type: %d\n", notification->object_type)); goto end; } if (notification->object_type == MAPISTORE_TABLE) { table = handle_object->object.table; /* FIXME: here is a hack to update table counters and which would not be needed if the backend had access to the table structure... */ if (notification->event == MAPISTORE_OBJECT_CREATED) { table->denominator++; } else if (notification->event == MAPISTORE_OBJECT_DELETED) { table->denominator--; if (table->numerator >= table->denominator) { table->numerator = table->denominator; } } if (notification->parameters.table_parameters.table_type == MAPISTORE_FOLDER_TABLE) { if (notification->event == MAPISTORE_OBJECT_CREATED || notification->event == MAPISTORE_OBJECT_MODIFIED) { if (notification->parameters.table_parameters.row_id > 0) { /* FIXME: this hack enables the fetching of some properties from the previous row */ saved_prop_count = table->prop_count; saved_properties = table->properties; previous_row_properties = talloc_array(NULL, enum MAPITAGS, 1); previous_row_properties[0] = PR_FID; table->properties = previous_row_properties; table->prop_count = 1; contextID = emsmdbp_get_contextID(handle_object); mapistore_table_set_columns(emsmdbp_ctx->mstore_ctx, contextID, handle_object->backend_object, table->prop_count, (enum MAPITAGS *) table->properties); data_pointers = emsmdbp_object_table_get_row_props(mem_ctx, emsmdbp_ctx, handle_object, notification->parameters.table_parameters.row_id - 1, MAPISTORE_PREFILTERED_QUERY, &retvals); if (data_pointers) { prev_fid = *(uint32_t *) data_pointers[0]; talloc_free(data_pointers); } else { prev_fid = -1; } table->prop_count = saved_prop_count; table->properties = saved_properties; talloc_free(previous_row_properties); mapistore_table_set_columns(emsmdbp_ctx->mstore_ctx, contextID, handle_object->backend_object, table->prop_count, (enum MAPITAGS *) table->properties); } else { prev_fid = 0; } table_row = talloc_zero(mem_ctx, DATA_BLOB); data_pointers = emsmdbp_object_table_get_row_props(mem_ctx, emsmdbp_ctx, handle_object, notification->parameters.table_parameters.row_id, MAPISTORE_PREFILTERED_QUERY, &retvals); if (data_pointers) { emsmdbp_fill_table_row_blob(mem_ctx, emsmdbp_ctx, table_row, table->prop_count, (enum MAPITAGS *) table->properties, data_pointers, retvals); talloc_free(data_pointers); talloc_free(retvals); } else { success = false; DEBUG(5, (__location__": no data returned for row, notification ignored\n")); } } /* FIXME: for some reason, TABLE_ROW_MODIFIED and TABLE_ROW_DELETED do not work... */ reply->NotificationData.SearchTableChange.TableEvent = TABLE_CHANGED; switch (notification->event) { case MAPISTORE_OBJECT_CREATED: /* case MAPISTORE_OBJECT_MODIFIED: */ reply->NotificationData.HierarchyTableChange.TableEvent = (notification->event == MAPISTORE_OBJECT_CREATED ? TABLE_ROW_ADDED : TABLE_ROW_MODIFIED); reply->NotificationData.HierarchyTableChange.HierarchyTableChangeUnion.HierarchyRowAddedNotification.FID = notification->parameters.table_parameters.object_id; reply->NotificationData.HierarchyTableChange.HierarchyTableChangeUnion.HierarchyRowAddedNotification.InsertAfterFID = prev_fid; reply->NotificationData.HierarchyTableChange.HierarchyTableChangeUnion.HierarchyRowAddedNotification.Columns = *table_row; break; case MAPISTORE_OBJECT_MODIFIED: case MAPISTORE_OBJECT_DELETED: case MAPISTORE_OBJECT_COPIED: case MAPISTORE_OBJECT_MOVED: case MAPISTORE_OBJECT_NEWMAIL: break; /* case MAPISTORE_OBJECT_DELETED: */ /* reply->NotificationData.HierarchyTableChange.TableEvent = TABLE_ROW_DELETED; */ /* reply->NotificationData.HierarchyTableChange.HierarchyTableChangeUnion.HierarchyRowDeletedNotification.FID = notification->parameters.table_parameters.object_id; */ /* break; */ /* default: */ /* reply->NotificationType = fnevCriticalError; */ /* DEBUG(5, ("unknown value for notification event: %d\n", notification->event)); */ /* goto end; */ } } else { if (notification->event == MAPISTORE_OBJECT_CREATED || notification->event == MAPISTORE_OBJECT_MODIFIED) { if (notification->parameters.table_parameters.row_id > 0) { /* FIXME: this hack enables the fetching of some properties from the previous row */ saved_prop_count = table->prop_count; saved_properties = table->properties; previous_row_properties = talloc_array(NULL, enum MAPITAGS, 3); previous_row_properties[0] = PR_FID; previous_row_properties[1] = PR_MID; previous_row_properties[2] = PR_INSTANCE_NUM; table->properties = previous_row_properties; table->prop_count = 3; contextID = emsmdbp_get_contextID(handle_object); mapistore_table_set_columns(emsmdbp_ctx->mstore_ctx, contextID, handle_object->backend_object, table->prop_count, (enum MAPITAGS *) table->properties); data_pointers = emsmdbp_object_table_get_row_props(mem_ctx, emsmdbp_ctx, handle_object, notification->parameters.table_parameters.row_id - 1, MAPISTORE_PREFILTERED_QUERY, NULL); if (data_pointers) { prev_fid = *(uint64_t *) data_pointers[0]; prev_mid = *(uint64_t *) data_pointers[1]; prev_instance = *(uint32_t *) data_pointers[2]; talloc_free(data_pointers); } else { prev_fid = -1; prev_mid = -1; prev_instance = -1; } table->prop_count = saved_prop_count; table->properties = saved_properties; talloc_free(previous_row_properties); mapistore_table_set_columns(emsmdbp_ctx->mstore_ctx, contextID, handle_object->backend_object, table->prop_count, (enum MAPITAGS *) table->properties); } else { prev_fid = 0; prev_mid = 0; prev_instance = 0; } table_row = talloc_zero(mem_ctx, DATA_BLOB); data_pointers = emsmdbp_object_table_get_row_props(mem_ctx, emsmdbp_ctx, handle_object, notification->parameters.table_parameters.row_id, MAPISTORE_PREFILTERED_QUERY, &retvals); if (data_pointers) { emsmdbp_fill_table_row_blob(mem_ctx, emsmdbp_ctx, table_row, table->prop_count, (enum MAPITAGS *) table->properties, data_pointers, retvals); talloc_free(data_pointers); talloc_free(retvals); } else { success = false; DEBUG(5, (__location__": no data returned for row, notification ignored\n")); } } /* FIXME: for some reason, TABLE_ROW_MODIFIED and TABLE_ROW_DELETED do not work... */ reply->NotificationData.SearchTableChange.TableEvent = TABLE_CHANGED; switch (notification->event) { case MAPISTORE_OBJECT_CREATED: /* case MAPISTORE_OBJECT_MODIFIED: */ reply->NotificationData.SearchTableChange.TableEvent = (notification->event == MAPISTORE_OBJECT_CREATED ? TABLE_ROW_ADDED : TABLE_ROW_MODIFIED); reply->NotificationData.SearchTableChange.ContentsTableChangeUnion.ContentsRowAddedNotification.FID = notification->parameters.table_parameters.folder_id; reply->NotificationData.SearchTableChange.ContentsTableChangeUnion.ContentsRowAddedNotification.MID = notification->parameters.table_parameters.object_id; reply->NotificationData.SearchTableChange.ContentsTableChangeUnion.ContentsRowAddedNotification.Instance = notification->parameters.table_parameters.instance_id; reply->NotificationData.SearchTableChange.ContentsTableChangeUnion.ContentsRowAddedNotification.InsertAfterFID = prev_fid; reply->NotificationData.SearchTableChange.ContentsTableChangeUnion.ContentsRowAddedNotification.InsertAfterMID = prev_mid; reply->NotificationData.SearchTableChange.ContentsTableChangeUnion.ContentsRowAddedNotification.InsertAfterInstance = prev_instance; reply->NotificationData.SearchTableChange.ContentsTableChangeUnion.ContentsRowAddedNotification.Columns = *table_row; break; /* case MAPISTORE_OBJECT_DELETED: */ /* reply->NotificationData.SearchTableChange.TableEvent = TABLE_ROW_DELETED; */ /* reply->NotificationData.SearchTableChange.ContentsTableChangeUnion.ContentsRowDeletedNotification.FID = notification->parameters.table_parameters.folder_id; */ /* reply->NotificationData.SearchTableChange.ContentsTableChangeUnion.ContentsRowDeletedNotification.MID = notification->parameters.table_parameters.object_id; */ /* reply->NotificationData.SearchTableChange.ContentsTableChangeUnion.ContentsRowDeletedNotification.Instance = notification->parameters.table_parameters.instance_id; */ /* break; */ /* default: */ /* reply->NotificationType = fnevCriticalError; */ /* DEBUG(5, ("unknown value for notification event: %d\n", notification->event)); */ /* goto end; */ case MAPISTORE_OBJECT_MODIFIED: case MAPISTORE_OBJECT_DELETED: case MAPISTORE_OBJECT_COPIED: case MAPISTORE_OBJECT_MOVED: case MAPISTORE_OBJECT_NEWMAIL: break; } } } else { switch (notification->event) { case MAPISTORE_OBJECT_NEWMAIL: reply->NotificationType |= fnevNewMail; break; case MAPISTORE_OBJECT_CREATED: reply->NotificationType |= fnevObjectCreated; break; case MAPISTORE_OBJECT_DELETED: reply->NotificationType |= fnevObjectDeleted; break; case MAPISTORE_OBJECT_MODIFIED: reply->NotificationType |= fnevObjectModified; break; case MAPISTORE_OBJECT_COPIED: reply->NotificationType |= fnevObjectCopied; break; case MAPISTORE_OBJECT_MOVED: reply->NotificationType |= fnevObjectMoved; break; default: reply->NotificationType = fnevCriticalError; DEBUG(5, ("unknown value for notification event: %d\n", notification->event)); goto end; } if (notification->object_type == MAPISTORE_MESSAGE) { switch (notification->event) { case MAPISTORE_OBJECT_NEWMAIL: reply->NotificationData.NewMailNotification.FID = notification->parameters.object_parameters.folder_id; reply->NotificationData.NewMailNotification.MID = notification->parameters.object_parameters.object_id; /* Hack for now */ reply->NotificationData.NewMailNotification.MessageFlags = 0x4; reply->NotificationData.NewMailNotification.UnicodeFlag = true; reply->NotificationData.NewMailNotification.MessageClass.lpszW = "IPF.Note"; break; case MAPISTORE_OBJECT_CREATED: reply->NotificationData.MessageCreatedNotification.FID = notification->parameters.object_parameters.folder_id; reply->NotificationData.MessageCreatedNotification.MID = notification->parameters.object_parameters.object_id; reply->NotificationData.MessageCreatedNotification.TagCount = notification->parameters.object_parameters.tag_count; if (notification->parameters.object_parameters.tag_count && notification->parameters.object_parameters.tag_count != 0xffff) { reply->NotificationData.MessageCreatedNotification.NotificationTags.Tags = talloc_memdup(mem_ctx, notification->parameters.object_parameters.tags, notification->parameters.object_parameters.tag_count * sizeof(enum MAPITAGS)); } else { reply->NotificationData.MessageCreatedNotification.NotificationTags.Tags = NULL; } break; case MAPISTORE_OBJECT_MODIFIED: reply->NotificationData.MessageModifiedNotification.FID = notification->parameters.object_parameters.folder_id; reply->NotificationData.MessageModifiedNotification.MID = notification->parameters.object_parameters.object_id; reply->NotificationData.MessageModifiedNotification.TagCount = notification->parameters.object_parameters.tag_count; if (notification->parameters.object_parameters.tag_count && notification->parameters.object_parameters.tag_count != 0xffff) { reply->NotificationData.MessageModifiedNotification.NotificationTags.Tags = talloc_memdup(mem_ctx, notification->parameters.object_parameters.tags, notification->parameters.object_parameters.tag_count * sizeof(enum MAPITAGS)); } else { reply->NotificationData.MessageModifiedNotification.NotificationTags.Tags = NULL; } break; case MAPISTORE_OBJECT_COPIED: case MAPISTORE_OBJECT_MOVED: reply->NotificationData.MessageMoveNotification.FID = notification->parameters.object_parameters.folder_id; reply->NotificationData.MessageMoveNotification.MID = notification->parameters.object_parameters.object_id; reply->NotificationData.MessageMoveNotification.OldFID = notification->parameters.object_parameters.old_folder_id; reply->NotificationData.MessageMoveNotification.OldMID = notification->parameters.object_parameters.old_object_id; break; default: /* MAPISTORE_OBJECT_DELETED */ reply->NotificationData.MessageDeletedNotification.FID = notification->parameters.object_parameters.folder_id; reply->NotificationData.MessageDeletedNotification.MID = notification->parameters.object_parameters.object_id; } } else { /* MAPISTORE_FOLDER */ switch (notification->event) { case MAPISTORE_OBJECT_NEWMAIL: reply->NotificationData.NewMailNotification.FID = notification->parameters.object_parameters.folder_id; reply->NotificationData.NewMailNotification.MID = notification->parameters.object_parameters.object_id; /* Hack for now */ reply->NotificationData.NewMailNotification.MessageFlags = 0x4; reply->NotificationData.NewMailNotification.UnicodeFlag = true; reply->NotificationData.NewMailNotification.MessageClass.lpszW = "IPF.Note"; break; case MAPISTORE_OBJECT_CREATED: reply->NotificationData.FolderCreatedNotification.ParentFID = notification->parameters.object_parameters.folder_id; reply->NotificationData.FolderCreatedNotification.FID = notification->parameters.object_parameters.object_id; reply->NotificationData.FolderCreatedNotification.TagCount = notification->parameters.object_parameters.tag_count; if (notification->parameters.object_parameters.tag_count && notification->parameters.object_parameters.tag_count != 0xffff) { reply->NotificationData.FolderCreatedNotification.NotificationTags.Tags = talloc_memdup(mem_ctx, notification->parameters.object_parameters.tags, notification->parameters.object_parameters.tag_count * sizeof(enum MAPITAGS)); } else { reply->NotificationData.FolderCreatedNotification.NotificationTags.Tags = NULL; } break; case MAPISTORE_OBJECT_MODIFIED: reply->NotificationData.FolderModifiedNotification_10.FID = notification->parameters.object_parameters.object_id; reply->NotificationData.FolderModifiedNotification_10.TagCount = notification->parameters.object_parameters.tag_count; if (notification->parameters.object_parameters.tag_count && notification->parameters.object_parameters.tag_count != 0xffff) { reply->NotificationData.FolderModifiedNotification_10.NotificationTags.Tags = talloc_memdup(mem_ctx, notification->parameters.object_parameters.tags, notification->parameters.object_parameters.tag_count * sizeof(enum MAPITAGS)); } else { reply->NotificationData.FolderModifiedNotification_10.NotificationTags.Tags = NULL; } if (notification->parameters.object_parameters.new_message_count) { reply->NotificationData.FolderModifiedNotification_1010.TotalMessageCount = notification->parameters.object_parameters.message_count; } break; default: /* MAPISTORE_OBJECT_DELETED */ reply->NotificationData.FolderDeletedNotification.ParentFID = notification->parameters.object_parameters.folder_id; reply->NotificationData.FolderDeletedNotification.FID = notification->parameters.object_parameters.object_id; } } } end: *sizep += libmapiserver_RopNotify_size(mapi_repl); return success; } static struct mapi_response *EcDoRpc_process_transaction(TALLOC_CTX *mem_ctx, struct emsmdbp_context *emsmdbp_ctx, struct mapi_request *mapi_request) { enum MAPISTATUS retval; struct mapi_response *mapi_response; struct mapistore_notification_list *notification_holder; /* struct mapistore_notification_list *nlist; struct mapistore_notification_list *el; struct mapistore_subscription_list *sel; */ struct mapistore_subscription_list *subscription_list; struct mapistore_subscription_list *subscription_holder; uint32_t handles_length; uint16_t size = 0; uint32_t i; uint32_t idx; bool needs_realloc = true; /* Sanity checks */ if (!emsmdbp_ctx) return NULL; if (!mapi_request) return NULL; /* Allocate mapi_response */ mapi_response = talloc_zero(mem_ctx, struct mapi_response); mapi_response->handles = mapi_request->handles; /* Step 1. Handle Idle requests case */ if (mapi_request->mapi_len <= 2) { mapi_response->mapi_len = 2; idx = 0; goto notif; } /* Step 2. Process serialized MAPI requests */ mapi_response->mapi_repl = talloc_zero(mem_ctx, struct EcDoRpc_MAPI_REPL); for (i = 0, idx = 0, size = 0; mapi_request->mapi_req[i].opnum != 0; i++) { DEBUG(0, ("MAPI Rop: 0x%.2x (%d)\n", mapi_request->mapi_req[i].opnum, size)); if (mapi_request->mapi_req[i].opnum != op_MAPI_Release) { mapi_response->mapi_repl = talloc_realloc(mem_ctx, mapi_response->mapi_repl, struct EcDoRpc_MAPI_REPL, idx + 2); } switch (mapi_request->mapi_req[i].opnum) { case op_MAPI_Release: /* 0x01 */ retval = EcDoRpc_RopRelease(mem_ctx, emsmdbp_ctx, &(mapi_request->mapi_req[i]), mapi_request->handles, &size); break; case op_MAPI_OpenFolder: /* 0x02 */ retval = EcDoRpc_RopOpenFolder(mem_ctx, emsmdbp_ctx, &(mapi_request->mapi_req[i]), &(mapi_response->mapi_repl[idx]), mapi_response->handles, &size); break; case op_MAPI_OpenMessage: /* 0x3 */ retval = EcDoRpc_RopOpenMessage(mem_ctx, emsmdbp_ctx, &(mapi_request->mapi_req[i]), &(mapi_response->mapi_repl[idx]), mapi_response->handles, &size); break; case op_MAPI_GetHierarchyTable: /* 0x04 */ retval = EcDoRpc_RopGetHierarchyTable(mem_ctx, emsmdbp_ctx, &(mapi_request->mapi_req[i]), &(mapi_response->mapi_repl[idx]), mapi_response->handles, &size); break; case op_MAPI_GetContentsTable: /* 0x05 */ retval = EcDoRpc_RopGetContentsTable(mem_ctx, emsmdbp_ctx, &(mapi_request->mapi_req[i]), &(mapi_response->mapi_repl[idx]), mapi_response->handles, &size); break; case op_MAPI_CreateMessage: /* 0x06 */ retval = EcDoRpc_RopCreateMessage(mem_ctx, emsmdbp_ctx, &(mapi_request->mapi_req[i]), &(mapi_response->mapi_repl[idx]), mapi_response->handles, &size); break; case op_MAPI_GetProps: /* 0x07 */ retval = EcDoRpc_RopGetPropertiesSpecific(mem_ctx, emsmdbp_ctx, &(mapi_request->mapi_req[i]), &(mapi_response->mapi_repl[idx]), mapi_response->handles, &size); break; case op_MAPI_GetPropsAll: /* 0x8 */ retval = EcDoRpc_RopGetPropertiesAll(mem_ctx, emsmdbp_ctx, &(mapi_request->mapi_req[i]), &(mapi_response->mapi_repl[idx]), mapi_response->handles, &size); break; case op_MAPI_GetPropList: /* 0x9 */ retval = EcDoRpc_RopGetPropertiesList(mem_ctx, emsmdbp_ctx, &(mapi_request->mapi_req[i]), &(mapi_response->mapi_repl[idx]), mapi_response->handles, &size); break; case op_MAPI_SetProps: /* 0x0a */ retval = EcDoRpc_RopSetProperties(mem_ctx, emsmdbp_ctx, &(mapi_request->mapi_req[i]), &(mapi_response->mapi_repl[idx]), mapi_response->handles, &size); break; case op_MAPI_DeleteProps: /* 0xb */ retval = EcDoRpc_RopDeleteProperties(mem_ctx, emsmdbp_ctx, &(mapi_request->mapi_req[i]), &(mapi_response->mapi_repl[idx]), mapi_response->handles, &size); break; case op_MAPI_SaveChangesMessage: /* 0x0c */ retval = EcDoRpc_RopSaveChangesMessage(mem_ctx, emsmdbp_ctx, &(mapi_request->mapi_req[i]), &(mapi_response->mapi_repl[idx]), mapi_response->handles, &size); break; case op_MAPI_RemoveAllRecipients: /* 0xd */ retval = EcDoRpc_RopRemoveAllRecipients(mem_ctx, emsmdbp_ctx, &(mapi_request->mapi_req[i]), &(mapi_response->mapi_repl[idx]), mapi_response->handles, &size); break; case op_MAPI_ModifyRecipients: /* 0xe */ retval = EcDoRpc_RopModifyRecipients(mem_ctx, emsmdbp_ctx, &(mapi_request->mapi_req[i]), &(mapi_response->mapi_repl[idx]), mapi_response->handles, &size); break; /* op_MAPI_ReadRecipients: 0xf */ case op_MAPI_ReloadCachedInformation: /* 0x10 */ retval = EcDoRpc_RopReloadCachedInformation(mem_ctx, emsmdbp_ctx, &(mapi_request->mapi_req[i]), &(mapi_response->mapi_repl[idx]), mapi_response->handles, &size); break; case op_MAPI_SetMessageReadFlag: /* 0x11 */ retval = EcDoRpc_RopSetMessageReadFlag(mem_ctx, emsmdbp_ctx, &(mapi_request->mapi_req[i]), &(mapi_response->mapi_repl[idx]), mapi_response->handles, &size); break; case op_MAPI_SetColumns: /* 0x12 */ retval = EcDoRpc_RopSetColumns(mem_ctx, emsmdbp_ctx, &(mapi_request->mapi_req[i]), &(mapi_response->mapi_repl[idx]), mapi_response->handles, &size); break; case op_MAPI_SortTable: /* 0x13 */ retval = EcDoRpc_RopSortTable(mem_ctx, emsmdbp_ctx, &(mapi_request->mapi_req[i]), &(mapi_response->mapi_repl[idx]), mapi_response->handles, &size); break; case op_MAPI_Restrict: /* 0x14 */ retval = EcDoRpc_RopRestrict(mem_ctx, emsmdbp_ctx, &(mapi_request->mapi_req[i]), &(mapi_response->mapi_repl[idx]), mapi_response->handles, &size); break; case op_MAPI_QueryRows: /* 0x15 */ retval = EcDoRpc_RopQueryRows(mem_ctx, emsmdbp_ctx, &(mapi_request->mapi_req[i]), &(mapi_response->mapi_repl[idx]), mapi_response->handles, &size); break; /* op_MAPI_GetStatus: 0x16 */ case op_MAPI_QueryPosition: /* 0x17 */ retval = EcDoRpc_RopQueryPosition(mem_ctx, emsmdbp_ctx, &(mapi_request->mapi_req[i]), &(mapi_response->mapi_repl[idx]), mapi_response->handles, &size); break; case op_MAPI_SeekRow: /* 0x18 */ retval = EcDoRpc_RopSeekRow(mem_ctx, emsmdbp_ctx, &(mapi_request->mapi_req[i]), &(mapi_response->mapi_repl[idx]), mapi_response->handles, &size); break; /* op_MAPI_SeekRowBookmark: 0x19 */ /* op_MAPI_SeekRowApprox: 0x1a */ /* op_MAPI_CreateBookmark: 0x1b */ case op_MAPI_CreateFolder: /* 0x1c */ retval = EcDoRpc_RopCreateFolder(mem_ctx, emsmdbp_ctx, &(mapi_request->mapi_req[i]), &(mapi_response->mapi_repl[idx]), mapi_response->handles, &size); break; case op_MAPI_DeleteFolder: /* 0x1d */ retval = EcDoRpc_RopDeleteFolder(mem_ctx, emsmdbp_ctx, &(mapi_request->mapi_req[i]), &(mapi_response->mapi_repl[idx]), mapi_response->handles, &size); break; case op_MAPI_DeleteMessages: /* 0x1e */ retval = EcDoRpc_RopDeleteMessages(mem_ctx, emsmdbp_ctx, &(mapi_request->mapi_req[i]), &(mapi_response->mapi_repl[idx]), mapi_response->handles, &size); break; /* op_MAPI_GetMessageStatus: 0x1f */ /* op_MAPI_SetMessageStatus: 0x20 */ case op_MAPI_GetAttachmentTable: /* 0x21 */ retval = EcDoRpc_RopGetAttachmentTable(mem_ctx, emsmdbp_ctx, &(mapi_request->mapi_req[i]), &(mapi_response->mapi_repl[idx]), mapi_response->handles, &size); break; case op_MAPI_OpenAttach: /* 0x22 */ retval = EcDoRpc_RopOpenAttach(mem_ctx, emsmdbp_ctx, &(mapi_request->mapi_req[i]), &(mapi_response->mapi_repl[idx]), mapi_response->handles, &size); break; case op_MAPI_CreateAttach: /* 0x23 */ retval = EcDoRpc_RopCreateAttach(mem_ctx, emsmdbp_ctx, &(mapi_request->mapi_req[i]), &(mapi_response->mapi_repl[idx]), mapi_response->handles, &size); break; /* op_MAPI_DeleteAttach: 0x24 */ case op_MAPI_SaveChangesAttachment: /* 0x25 */ retval = EcDoRpc_RopSaveChangesAttachment(mem_ctx, emsmdbp_ctx, &(mapi_request->mapi_req[i]), &(mapi_response->mapi_repl[idx]), mapi_response->handles, &size); break; case op_MAPI_SetReceiveFolder: /* 0x26 */ retval = EcDoRpc_RopSetReceiveFolder(mem_ctx, emsmdbp_ctx, &(mapi_request->mapi_req[i]), &(mapi_response->mapi_repl[idx]), mapi_response->handles, &size); break; case op_MAPI_GetReceiveFolder: /* 0x27 */ retval = EcDoRpc_RopGetReceiveFolder(mem_ctx, emsmdbp_ctx, &(mapi_request->mapi_req[i]), &(mapi_response->mapi_repl[idx]), mapi_response->handles, &size); break; case op_MAPI_RegisterNotification: /* 0x29 */ retval = EcDoRpc_RopRegisterNotification(mem_ctx, emsmdbp_ctx, &(mapi_request->mapi_req[i]), &(mapi_response->mapi_repl[idx]), mapi_response->handles, &size); break; /* op_MAPI_Notify: 0x2a */ case op_MAPI_OpenStream: /* 0x2b */ retval = EcDoRpc_RopOpenStream(mem_ctx, emsmdbp_ctx, &(mapi_request->mapi_req[i]), &(mapi_response->mapi_repl[idx]), mapi_response->handles, &size); break; case op_MAPI_ReadStream: /* 0x2c */ retval = EcDoRpc_RopReadStream(mem_ctx, emsmdbp_ctx, &(mapi_request->mapi_req[i]), &(mapi_response->mapi_repl[idx]), mapi_response->handles, &size); break; case op_MAPI_WriteStream: /* 0x2d */ retval = EcDoRpc_RopWriteStream(mem_ctx, emsmdbp_ctx, &(mapi_request->mapi_req[i]), &(mapi_response->mapi_repl[idx]), mapi_response->handles, &size); break; case op_MAPI_SeekStream: /* 0x2e */ retval = EcDoRpc_RopSeekStream(mem_ctx, emsmdbp_ctx, &(mapi_request->mapi_req[i]), &(mapi_response->mapi_repl[idx]), mapi_response->handles, &size); break; case op_MAPI_SetStreamSize: /* 0x2f */ retval = EcDoRpc_RopSetStreamSize(mem_ctx, emsmdbp_ctx, &(mapi_request->mapi_req[i]), &(mapi_response->mapi_repl[idx]), mapi_response->handles, &size); break; case op_MAPI_SetSearchCriteria: /* 0x30 */ retval = EcDoRpc_RopSetSearchCriteria(mem_ctx, emsmdbp_ctx, &(mapi_request->mapi_req[i]), &(mapi_response->mapi_repl[idx]), mapi_response->handles, &size); break; case op_MAPI_GetSearchCriteria: /* 0x31 */ retval = EcDoRpc_RopGetSearchCriteria(mem_ctx, emsmdbp_ctx, &(mapi_request->mapi_req[i]), &(mapi_response->mapi_repl[idx]), mapi_response->handles, &size); break; case op_MAPI_SubmitMessage: /* 0x32 */ retval = EcDoRpc_RopSubmitMessage(mem_ctx, emsmdbp_ctx, &(mapi_request->mapi_req[i]), &(mapi_response->mapi_repl[idx]), mapi_response->handles, &size); break; case op_MAPI_MoveCopyMessages: /* 0x33 */ retval = EcDoRpc_RopMoveCopyMessages(mem_ctx, emsmdbp_ctx, &(mapi_request->mapi_req[i]), &(mapi_response->mapi_repl[idx]), mapi_response->handles, &size); break; /* op_MAPI_AbortSubmit: 0x34 */ case op_MAPI_MoveFolder: /* 0x35 */ retval = EcDoRpc_RopMoveFolder(mem_ctx, emsmdbp_ctx, &(mapi_request->mapi_req[i]), &(mapi_response->mapi_repl[idx]), mapi_response->handles, &size); break; case op_MAPI_CopyFolder: /* 0x36 */ retval = EcDoRpc_RopCopyFolder(mem_ctx, emsmdbp_ctx, &(mapi_request->mapi_req[i]), &(mapi_response->mapi_repl[idx]), mapi_response->handles, &size); break; /* op_MAPI_QueryColumnsAll: 0x37 */ /* op_MAPI_Abort: 0x38 */ case op_MAPI_CopyTo: /* 0x39 */ retval = EcDoRpc_RopCopyTo(mem_ctx, emsmdbp_ctx, &(mapi_request->mapi_req[i]), &(mapi_response->mapi_repl[idx]), mapi_response->handles, &size); break; /* op_MAPI_CopyToStream: 0x3a */ /* op_MAPI_CloneStream: 0x3b */ case op_MAPI_GetPermissionsTable: /* 0x3e */ retval = EcDoRpc_RopGetPermissionsTable(mem_ctx, emsmdbp_ctx, &(mapi_request->mapi_req[i]), &(mapi_response->mapi_repl[idx]), mapi_response->handles, &size); break; case op_MAPI_GetRulesTable: /* 0x3f */ retval = EcDoRpc_RopGetRulesTable(mem_ctx, emsmdbp_ctx, &(mapi_request->mapi_req[i]), &(mapi_response->mapi_repl[idx]), mapi_response->handles, &size); break; case op_MAPI_ModifyPermissions: /* 0x40 */ retval = EcDoRpc_RopModifyPermissions(mem_ctx, emsmdbp_ctx, &(mapi_request->mapi_req[i]), &(mapi_response->mapi_repl[idx]), mapi_response->handles, &size); break; case op_MAPI_ModifyRules: /* 0x41 */ retval = EcDoRpc_RopModifyRules(mem_ctx, emsmdbp_ctx, &(mapi_request->mapi_req[i]), &(mapi_response->mapi_repl[idx]), mapi_response->handles, &size); break; /* op_MAPI_GetOwningServers: 0x42 */ case op_MAPI_LongTermIdFromId: /* 0x43 */ retval = EcDoRpc_RopLongTermIdFromId(mem_ctx, emsmdbp_ctx, &(mapi_request->mapi_req[i]), &(mapi_response->mapi_repl[idx]), mapi_response->handles, &size); break; case op_MAPI_IdFromLongTermId: /* 0x44 */ retval = EcDoRpc_RopIdFromLongTermId(mem_ctx, emsmdbp_ctx, &(mapi_request->mapi_req[i]), &(mapi_response->mapi_repl[idx]), mapi_response->handles, &size); break; /* op_MAPI_PublicFolderIsGhosted: 0x45 */ case op_MAPI_OpenEmbeddedMessage: /* 0x46 */ retval = EcDoRpc_RopOpenEmbeddedMessage(mem_ctx, emsmdbp_ctx, &(mapi_request->mapi_req[i]), &(mapi_response->mapi_repl[idx]), mapi_response->handles, &size); break; case op_MAPI_SetSpooler: /* 0x47 */ retval = EcDoRpc_RopSetSpooler(mem_ctx, emsmdbp_ctx, &(mapi_request->mapi_req[i]), &(mapi_response->mapi_repl[idx]), mapi_response->handles, &size); break; /* op_MAPI_SpoolerLockMessage: 0x48 */ case op_MAPI_AddressTypes: /*x49 */ retval = EcDoRpc_RopGetAddressTypes(mem_ctx, emsmdbp_ctx, &(mapi_request->mapi_req[i]), &(mapi_response->mapi_repl[idx]), mapi_response->handles, &size); break; case op_MAPI_TransportSend: /* 0x4a */ retval = EcDoRpc_RopTransportSend(mem_ctx, emsmdbp_ctx, &(mapi_request->mapi_req[i]), &(mapi_response->mapi_repl[idx]), mapi_response->handles, &size); break; /* op_MAPI_FastTransferSourceCopyMessages: 0x4b */ /* op_MAPI_FastTransferSourceCopyFolder: 0x4c */ case op_MAPI_FastTransferSourceCopyTo: /* 0x4d */ retval = EcDoRpc_RopFastTransferSourceCopyTo(mem_ctx, emsmdbp_ctx, &(mapi_request->mapi_req[i]), &(mapi_response->mapi_repl[idx]), mapi_response->handles, &size); break; case op_MAPI_FastTransferSourceGetBuffer: /* 0x4e */ retval = EcDoRpc_RopFastTransferSourceGetBuffer(mem_ctx, emsmdbp_ctx, &(mapi_request->mapi_req[i]), &(mapi_response->mapi_repl[idx]), mapi_response->handles, &size); break; case op_MAPI_FindRow: /* 0x4f */ retval = EcDoRpc_RopFindRow(mem_ctx, emsmdbp_ctx, &(mapi_request->mapi_req[i]), &(mapi_response->mapi_repl[idx]), mapi_response->handles, &size); break; /* op_MAPI_Progress: 0x50 */ /* op_MAPI_TransportNewMail: 0x51 */ /* op_MAPI_GetValidAttachments: 0x52 */ case op_MAPI_GetNamesFromIDs: /* 0x55 */ retval = EcDoRpc_RopGetNamesFromIDs(mem_ctx, emsmdbp_ctx, &(mapi_request->mapi_req[i]), &(mapi_response->mapi_repl[idx]), mapi_response->handles, &size); break; case op_MAPI_GetIDsFromNames: /* 0x56 */ retval = EcDoRpc_RopGetPropertyIdsFromNames(mem_ctx, emsmdbp_ctx, &(mapi_request->mapi_req[i]), &(mapi_response->mapi_repl[idx]), mapi_response->handles, &size); break; /* op_MAPI_UpdateDeferredActionMessages: 0x57 */ case op_MAPI_EmptyFolder: /* 0x58 */ retval = EcDoRpc_RopEmptyFolder(mem_ctx, emsmdbp_ctx, &(mapi_request->mapi_req[i]), &(mapi_response->mapi_repl[idx]), mapi_response->handles, &size); break; /* op_MAPI_ExpandRow: 0x59 */ /* op_MAPI_CollapseRow: 0x5a */ /* op_MAPI_LockRegionStream: 0x5b */ /* op_MAPI_UnlockRegionStream: 0x5c */ case op_MAPI_CommitStream: /* 0x5d */ retval = EcDoRpc_RopCommitStream(mem_ctx, emsmdbp_ctx, &(mapi_request->mapi_req[i]), &(mapi_response->mapi_repl[idx]), mapi_response->handles, &size); break; case op_MAPI_GetStreamSize: /* 0x5e */ retval = EcDoRpc_RopGetStreamSize(mem_ctx, emsmdbp_ctx, &(mapi_request->mapi_req[i]), &(mapi_response->mapi_repl[idx]), mapi_response->handles, &size); break; /* op_MAPI_QueryNamedProperties: 0x5f */ case op_MAPI_GetPerUserLongTermIds: /* 0x60 */ retval = EcDoRpc_RopGetPerUserLongTermIds(mem_ctx, emsmdbp_ctx, &(mapi_request->mapi_req[i]), &(mapi_response->mapi_repl[idx]), mapi_response->handles, &size); break; case op_MAPI_GetPerUserGuid: /* 0x61 */ retval = EcDoRpc_RopGetPerUserGuid(mem_ctx, emsmdbp_ctx, &(mapi_request->mapi_req[i]), &(mapi_response->mapi_repl[idx]), mapi_response->handles, &size); break; case op_MAPI_ReadPerUserInformation: /* 0x63 */ retval = EcDoRpc_RopReadPerUserInformation(mem_ctx, emsmdbp_ctx, &(mapi_request->mapi_req[i]), &(mapi_response->mapi_repl[idx]), mapi_response->handles, &size); break; /* op_MAPI_ReadPerUserInformation: 0x63 */ /* op_MAPI_SetReadFlags: 0x66 */ /* op_MAPI_CopyProperties: 0x67 */ /* op_MAPI_GetReceiveFolderTable: 0x68 */ /* op_MAPI_GetCollapseState: 0x6b */ /* op_MAPI_SetCollapseState: 0x6c */ case op_MAPI_GetTransportFolder: /* 0x6d */ retval = EcDoRpc_RopGetTransportFolder(mem_ctx, emsmdbp_ctx, &(mapi_request->mapi_req[i]), &(mapi_response->mapi_repl[idx]), mapi_response->handles, &size); break; /* op_MAPI_Pending: 0x6e */ case op_MAPI_OptionsData: /* 0x6f */ retval = EcDoRpc_RopOptionsData(mem_ctx, emsmdbp_ctx, &(mapi_request->mapi_req[i]), &(mapi_response->mapi_repl[idx]), mapi_response->handles, &size); break; case op_MAPI_SyncConfigure: /* 0x70 */ retval = EcDoRpc_RopSyncConfigure(mem_ctx, emsmdbp_ctx, &(mapi_request->mapi_req[i]), &(mapi_response->mapi_repl[idx]), mapi_response->handles, &size); break; case op_MAPI_SyncImportMessageChange: /* 0x72 */ retval = EcDoRpc_RopSyncImportMessageChange(mem_ctx, emsmdbp_ctx, &(mapi_request->mapi_req[i]), &(mapi_response->mapi_repl[idx]), mapi_response->handles, &size); break; case op_MAPI_SyncImportHierarchyChange: /* 0x73 */ retval = EcDoRpc_RopSyncImportHierarchyChange(mem_ctx, emsmdbp_ctx, &(mapi_request->mapi_req[i]), &(mapi_response->mapi_repl[idx]), mapi_response->handles, &size); break; case op_MAPI_SyncImportDeletes: /* 0x74 */ retval = EcDoRpc_RopSyncImportDeletes(mem_ctx, emsmdbp_ctx, &(mapi_request->mapi_req[i]), &(mapi_response->mapi_repl[idx]), mapi_response->handles, &size); break; case op_MAPI_SyncUploadStateStreamBegin: /* 0x75 */ retval = EcDoRpc_RopSyncUploadStateStreamBegin(mem_ctx, emsmdbp_ctx, &(mapi_request->mapi_req[i]), &(mapi_response->mapi_repl[idx]), mapi_response->handles, &size); break; case op_MAPI_SyncUploadStateStreamContinue: /* 0x76 */ retval = EcDoRpc_RopSyncUploadStateStreamContinue(mem_ctx, emsmdbp_ctx, &(mapi_request->mapi_req[i]), &(mapi_response->mapi_repl[idx]), mapi_response->handles, &size); break; case op_MAPI_SyncUploadStateStreamEnd: /* 0x77 */ retval = EcDoRpc_RopSyncUploadStateStreamEnd(mem_ctx, emsmdbp_ctx, &(mapi_request->mapi_req[i]), &(mapi_response->mapi_repl[idx]), mapi_response->handles, &size); break; case op_MAPI_SyncImportMessageMove: /* 0x78 */ retval = EcDoRpc_RopSyncImportMessageMove(mem_ctx, emsmdbp_ctx, &(mapi_request->mapi_req[i]), &(mapi_response->mapi_repl[idx]), mapi_response->handles, &size); break; /* op_MAPI_SetPropertiesNoReplicate: 0x79 */ case op_MAPI_DeletePropertiesNoReplicate: /* 0x7a */ retval = EcDoRpc_RopDeletePropertiesNoReplicate(mem_ctx, emsmdbp_ctx, &(mapi_request->mapi_req[i]), &(mapi_response->mapi_repl[idx]), mapi_response->handles, &size); break; case op_MAPI_GetStoreState: /* 0x7b */ retval = EcDoRpc_RopGetStoreState(mem_ctx, emsmdbp_ctx, &(mapi_request->mapi_req[i]), &(mapi_response->mapi_repl[idx]), mapi_response->handles, &size); break; case op_MAPI_SyncOpenCollector: /* 0x7e */ retval = EcDoRpc_RopSyncOpenCollector(mem_ctx, emsmdbp_ctx, &(mapi_request->mapi_req[i]), &(mapi_response->mapi_repl[idx]), mapi_response->handles, &size); break; case op_MAPI_GetLocalReplicaIds: /* 0x7f */ retval = EcDoRpc_RopGetLocalReplicaIds(mem_ctx, emsmdbp_ctx, &(mapi_request->mapi_req[i]), &(mapi_response->mapi_repl[idx]), mapi_response->handles, &size); break; case op_MAPI_SyncImportReadStateChanges: /* 0x80 */ retval = EcDoRpc_RopSyncImportReadStateChanges(mem_ctx, emsmdbp_ctx, &(mapi_request->mapi_req[i]), &(mapi_response->mapi_repl[idx]), mapi_response->handles, &size); break; case op_MAPI_ResetTable: /* 0x81 */ retval = EcDoRpc_RopResetTable(mem_ctx, emsmdbp_ctx, &(mapi_request->mapi_req[i]), &(mapi_response->mapi_repl[idx]), mapi_response->handles, &size); break; case op_MAPI_SyncGetTransferState: /* 0x82 */ retval = EcDoRpc_RopSyncGetTransferState(mem_ctx, emsmdbp_ctx, &(mapi_request->mapi_req[i]), &(mapi_response->mapi_repl[idx]), mapi_response->handles, &size); break; /* op_MAPI_OpenPublicFolderByName: 0x87 */ /* op_MAPI_SetSyncNotificationGuid: 0x88 */ /* op_MAPI_FreeBookmark: 0x89 */ /* op_MAPI_WriteAndCommitStream: 0x90 */ /* op_MAPI_HardDeleteMessages: 0x91 */ /* op_MAPI_HardDeleteMessagesAndSubfolders: 0x92 */ case op_MAPI_SetLocalReplicaMidsetDeleted: /* 0x93 */ retval = EcDoRpc_RopSetLocalReplicaMidsetDeleted(mem_ctx, emsmdbp_ctx, &(mapi_request->mapi_req[i]), &(mapi_response->mapi_repl[idx]), mapi_response->handles, &size); break; case op_MAPI_Logon: /* 0xfe */ retval = EcDoRpc_RopLogon(mem_ctx, emsmdbp_ctx, &(mapi_request->mapi_req[i]), &(mapi_response->mapi_repl[idx]), mapi_response->handles, &size); break; default: DEBUG(1, ("MAPI Rop: 0x%.2x not implemented!\n", mapi_request->mapi_req[i].opnum)); } if (mapi_request->mapi_req[i].opnum != op_MAPI_Release) { idx++; } } notif: /* Step 3. Notifications/Pending calls should be processed here */ /* Note: GetProps and GetRows are filled with flag NDR_REMAINING, which may hide the content of the following replies. */ while ((notification_holder = emsmdbp_ctx->mstore_ctx->notifications)) { subscription_list = mapistore_find_matching_subscriptions(emsmdbp_ctx->mstore_ctx, notification_holder->notification); while ((subscription_holder = subscription_list)) { if (needs_realloc) { mapi_response->mapi_repl = talloc_realloc(mem_ctx, mapi_response->mapi_repl, struct EcDoRpc_MAPI_REPL, idx + 2); } needs_realloc = emsmdbp_fill_notification(mapi_response->mapi_repl, emsmdbp_ctx, &(mapi_response->mapi_repl[idx]), subscription_holder->subscription, notification_holder->notification, &size); DLIST_REMOVE(subscription_list, subscription_holder); talloc_free(subscription_holder); idx++; } DLIST_REMOVE(emsmdbp_ctx->mstore_ctx->notifications, notification_holder); talloc_free(notification_holder); } #if 0 DEBUG(0, ("subscriptions: %p\n", emsmdbp_ctx->mstore_ctx->subscriptions)); /* Process notifications available on subscriptions queues */ for (sel = emsmdbp_ctx->mstore_ctx->subscriptions; sel; sel = sel->next) { DEBUG(0, ("subscription = %p\n", sel->subscription)); if (sel->subscription) { DEBUG(0, ("subscription: handle = 0x%x\n", sel->subscription->handle)); DEBUG(0, ("subscription: types = 0x%x\n", sel->subscription->notification_types)); DEBUG(0, ("subscription: mqueue = %d\n", sel->subscription->mqueue)); DEBUG(0, ("subscription: mqueue name = %s\n", sel->subscription->mqueue_name)); } retval = mapistore_get_queued_notifications(emsmdbp_ctx->mstore_ctx, sel->subscription, &nlist); if (retval == MAPI_E_SUCCESS) { for (el = nlist; el->notification; el = el->next) { if (needs_realloc) { mapi_response->mapi_repl = talloc_realloc(mem_ctx, mapi_response->mapi_repl, struct EcDoRpc_MAPI_REPL, idx + 2); } needs_realloc = emsmdbp_fill_notification(mapi_response->mapi_repl, emsmdbp_ctx, &(mapi_response->mapi_repl[idx]), sel->subscription, el->notification, &size); idx++; } talloc_free(nlist); } } #endif if (mapi_response->mapi_repl) { mapi_response->mapi_repl[idx].opnum = 0; } /* Step 4. Fill mapi_response structure */ handles_length = mapi_request->mapi_len - mapi_request->length; mapi_response->length = size + sizeof (mapi_response->length); mapi_response->mapi_len = mapi_response->length + handles_length; return mapi_response; } /** \details exchange_emsmdb EcDoRpc (0x2) function \param dce_call pointer to the session context \param mem_ctx pointer to the memory context \param r pointer to the EcDoRpc request data \return MAPI_E_SUCCESS on success */ static enum MAPISTATUS dcesrv_EcDoRpc(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx, struct EcDoRpc *r) { struct exchange_emsmdb_session *session; struct emsmdbp_context *emsmdbp_ctx = NULL; struct mapi_request *mapi_request; struct mapi_response *mapi_response; DEBUG(3, ("exchange_emsmdb: EcDoRpc (0x2)\n")); /* Step 0. Ensure incoming user is authenticated */ if (!dcesrv_call_authenticated(dce_call)) { DEBUG(1, ("No challenge requested by client, cannot authenticate\n")); r->out.handle->handle_type = 0; r->out.handle->uuid = GUID_zero(); r->out.result = DCERPC_FAULT_CONTEXT_MISMATCH; return MAPI_E_LOGON_FAILED; } /* Retrieve the emsmdbp_context from the session management system */ session = dcesrv_find_emsmdb_session(&r->in.handle->uuid); if (session) { emsmdbp_ctx = (struct emsmdbp_context *)session->session->private_data; } else { r->out.handle->handle_type = 0; r->out.handle->uuid = GUID_zero(); r->out.result = DCERPC_FAULT_CONTEXT_MISMATCH; return MAPI_E_LOGON_FAILED; } /* Step 1. Process EcDoRpc requests */ mapi_request = r->in.mapi_request; mapi_response = EcDoRpc_process_transaction(mem_ctx, emsmdbp_ctx, mapi_request); /* Step 2. Fill EcDoRpc reply */ r->out.handle = r->in.handle; r->out.size = r->in.size; r->out.offset = r->in.offset; r->out.mapi_response = mapi_response; r->out.length = talloc_zero(mem_ctx, uint16_t); *r->out.length = mapi_response->mapi_len; r->out.result = MAPI_E_SUCCESS; return MAPI_E_SUCCESS; } /** \details exchange_emsmdb EcGetMoreRpc (0x3) function \param dce_call pointer to the session context \param mem_ctx pointer to the memory context \param r pointer to the EcGetMoreRpc request data \return MAPI_E_SUCCESS on success */ static void dcesrv_EcGetMoreRpc(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx, struct EcGetMoreRpc *r) { DEBUG(3, ("exchange_emsmdb: EcGetMoreRpc (0x3) not implemented\n")); DCESRV_FAULT_VOID(DCERPC_FAULT_OP_RNG_ERROR); } /** \details exchange_emsmdb EcRRegisterPushNotification (0x4) function \param dce_call pointer to the session context \param mem_ctx pointer to the memory context \param r pointer to the EcRRegisterPushNotification request data \return MAPI_E_SUCCESS on success */ static enum MAPISTATUS dcesrv_EcRRegisterPushNotification(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx, struct EcRRegisterPushNotification *r) { int retval; struct exchange_emsmdb_session *session; /* struct emsmdbp_context *emsmdbp_ctx = NULL; */ DEBUG(3, ("exchange_emsmdb: EcRRegisterPushNotification (0x4)\n")); if (!dcesrv_call_authenticated(dce_call)) { DEBUG(1, ("No challenge requested by client, cannot authenticate\n")); r->out.handle->handle_type = 0; r->out.handle->uuid = GUID_zero(); r->out.result = DCERPC_FAULT_CONTEXT_MISMATCH; return MAPI_E_LOGON_FAILED; } /* Retrieve the emsmdbp_context from the session management system */ session = dcesrv_find_emsmdb_session(&r->in.handle->uuid); if (session) { /* emsmdbp_ctx = (struct emsmdbp_context *)session->session->private_data; */ } else { r->out.handle->handle_type = 0; r->out.handle->uuid = GUID_zero(); r->out.result = DCERPC_FAULT_CONTEXT_MISMATCH; return MAPI_E_LOGON_FAILED; } /* retval = mapistore_mgmt_interface_register_bind(emsmdbp_ctx->mstore_ctx->conn_info, r->in.cbContext, r->in.rgbContext, r->in.cbCallbackAddress, r->in.rgbCallbackAddress); */ retval = MAPI_E_SUCCESS; /* DEBUG(0, ("[%s:%d]: retval = 0x%x\n", __FUNCTION__, __LINE__, retval)); */ if (retval == MAPI_E_SUCCESS) { r->out.handle = r->in.handle; /* FIXME: Create a notification object and return associated handle */ *r->out.hNotification = 244; } return MAPI_E_SUCCESS; } /** \details exchange_emsmdb EcRUnregisterPushNotification (0x5) function \param dce_call pointer to the session context \param mem_ctx pointer to the memory context \param r pointer to the EcRUnregisterPushNotification request data \return MAPI_E_SUCCESS on success */ static enum MAPISTATUS dcesrv_EcRUnregisterPushNotification(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx, struct EcRUnregisterPushNotification *r) { DEBUG(3, ("exchange_emsmdb: EcRUnregisterPushNotification (0x5) not implemented\n")); DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR); } /** \details exchange_emsmdb EcDummyRpc (0x6) function \param dce_call pointer to the session context \param mem_ctx pointer to the memory context \param r pointer to the EcDummyRpc request data \return MAPI_E_SUCCESS on success */ static void dcesrv_EcDummyRpc(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx, struct EcDummyRpc *r) { DEBUG(3, ("exchange_emsmdb: EcDummyRpc (0x6) not implemented\n")); DCESRV_FAULT_VOID(DCERPC_FAULT_OP_RNG_ERROR); } /** \details exchange_emsmdb EcRGetDCName (0x7) function \param dce_call pointer to the session context \param mem_ctx pointer to the memory context \param r pointer to the EcRGetDCName request data \return MAPI_E_SUCCESS on success */ static void dcesrv_EcRGetDCName(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx, struct EcRGetDCName *r) { DEBUG(3, ("exchange_emsmdb: EcRGetDCName (0x7) not implemented\n")); DCESRV_FAULT_VOID(DCERPC_FAULT_OP_RNG_ERROR); } /** \details exchange_emsmdb EcRNetGetDCName (0x8) function \param dce_call pointer to the session context \param mem_ctx pointer to the memory context \param r pointer to the EcRNetGetDCName request data \return MAPI_E_SUCCESS on success */ static void dcesrv_EcRNetGetDCName(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx, struct EcRNetGetDCName *r) { DEBUG(3, ("exchange_emsmdb: EcRNetGetDCName (0x8) not implemented\n")); DCESRV_FAULT_VOID(DCERPC_FAULT_OP_RNG_ERROR); } /** \details exchange_emsmdb EcDoRpcExt (0x9) function \param dce_call pointer to the session context \param mem_ctx pointer to the memory context \param r pointer to the EcDoRpcExt request data \return MAPI_E_SUCCESS on success */ static enum MAPISTATUS dcesrv_EcDoRpcExt(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx, struct EcDoRpcExt *r) { DEBUG(3, ("exchange_emsmdb: EcDoRpcExt (0x9) not implemented\n")); DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR); } /* check if a client version is too low to use */ /* TODO: this could be much more sophisticated */ static bool clientVersionIsTooLow(const uint16_t rgwClientVersion[3]) { if (rgwClientVersion[0] < 0x000B) { return true; } else { return false; } } /** \details exchange_emsmdb EcDoConnectEx (0xA) function \param dce_call pointer to the session context \param mem_ctx pointer to the memory context \param r pointer to the EcDoConnectEx request data \return MAPI_E_SUCCESS on success */ static enum MAPISTATUS dcesrv_EcDoConnectEx(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx, struct EcDoConnectEx *r) { struct emsmdbp_context *emsmdbp_ctx; struct dcesrv_handle *handle; struct policy_handle wire_handle; struct exchange_emsmdb_session *session; struct ldb_message *msg; const char *mailNickname; const char *userDN; char *dnprefix; DEBUG(3, ("exchange_emsmdb: EcDoConnectEx (0xA)\n")); /* Step 0. Ensure incoming user is authenticated */ if (!dcesrv_call_authenticated(dce_call)) { DEBUG(1, ("No challenge requested by client, cannot authenticate\n")); failure: wire_handle.handle_type = EXCHANGE_HANDLE_EMSMDB; wire_handle.uuid = GUID_zero(); *r->out.handle = wire_handle; *r->out.pcmsPollsMax = 0; *r->out.pcRetry = 0; *r->out.pcmsRetryDelay = 0; *r->out.picxr = 0; r->out.szDNPrefix = NULL; r->out.szDisplayName = NULL; r->out.rgwServerVersion[0] = 0; r->out.rgwServerVersion[1] = 0; r->out.rgwServerVersion[2] = 0; r->out.rgwBestVersion[0] = 0; r->out.rgwBestVersion[1] = 0; r->out.rgwBestVersion[2] = 0; *r->out.pulTimeStamp = 0; r->out.rgbAuxOut = NULL; *r->out.pcbAuxOut = 0; r->out.result = MAPI_E_LOGON_FAILED; return MAPI_E_LOGON_FAILED; } /* Step 1. Initialize the emsmdbp context */ emsmdbp_ctx = emsmdbp_init(dce_call->conn->dce_ctx->lp_ctx, dcesrv_call_account_name(dce_call), openchange_ldb_ctx); if (!emsmdbp_ctx) { DEBUG(0, ("FATAL: unable to initialize emsmdbp context")); goto failure; } /* Step 2. Check if incoming user belongs to the Exchange organization */ if (emsmdbp_verify_user(dce_call, emsmdbp_ctx) == false) { talloc_free(emsmdbp_ctx); goto failure; } /* Step 3. Check if input user DN belongs to the Exchange organization */ if (emsmdbp_verify_userdn(dce_call, emsmdbp_ctx, r->in.szUserDN, &msg) == false) { talloc_free(emsmdbp_ctx); goto failure; } emsmdbp_ctx->szUserDN = talloc_strdup(emsmdbp_ctx, r->in.szUserDN); emsmdbp_ctx->userLanguage = r->in.ulLcidString; /* Step 4. Retrieve the display name of the user */ *r->out.szDisplayName = ldb_msg_find_attr_as_string(msg, "displayName", NULL); emsmdbp_ctx->szDisplayName = talloc_strdup(emsmdbp_ctx, *r->out.szDisplayName); /* Step 5. Retrieve the distinguished name of the server */ mailNickname = ldb_msg_find_attr_as_string(msg, "mailNickname", NULL); userDN = ldb_msg_find_attr_as_string(msg, "legacyExchangeDN", NULL); dnprefix = strstr(userDN, mailNickname); if (!dnprefix) { talloc_free(emsmdbp_ctx); goto failure; } *dnprefix = '\0'; *r->out.szDNPrefix = strupper_talloc(mem_ctx, userDN); /* Step 6. Fill EcDoConnectEx reply */ handle = dcesrv_handle_new(dce_call->context, EXCHANGE_HANDLE_EMSMDB); OPENCHANGE_RETVAL_IF(!handle, MAPI_E_NOT_ENOUGH_RESOURCES, emsmdbp_ctx); handle->data = (void *) emsmdbp_ctx; *r->out.handle = handle->wire_handle; *r->out.pcmsPollsMax = EMSMDB_PCMSPOLLMAX; *r->out.pcRetry = EMSMDB_PCRETRY; *r->out.pcmsRetryDelay = EMSMDB_PCRETRYDELAY; *r->out.picxr = 0; r->out.rgwServerVersion[0] = 0x8; r->out.rgwServerVersion[1] = 0x82B4; r->out.rgwServerVersion[2] = 0x3; r->out.pulTimeStamp = talloc_zero(mem_ctx, uint32_t); *r->out.pulTimeStamp = time(NULL); *r->out.pcbAuxOut = 0; r->out.rgbAuxOut = NULL; r->out.result = MAPI_E_SUCCESS; if (clientVersionIsTooLow(r->in.rgwClientVersion)) { r->out.rgwBestVersion[0] = 0x000B; r->out.rgwBestVersion[1] = 0x8000; r->out.rgwBestVersion[2] = 0x0000; r->out.result = MAPI_E_VERSION; } else { r->out.rgwBestVersion[0] = r->in.rgwClientVersion[0]; r->out.rgwBestVersion[1] = r->in.rgwClientVersion[1]; r->out.rgwBestVersion[2] = r->in.rgwClientVersion[2]; r->out.result = MAPI_E_SUCCESS; } /* Search for an existing session and increment ref_count, otherwise create it */ session = dcesrv_find_emsmdb_session(&handle->wire_handle.uuid); if (session) { DEBUG(0, ("[exchange_emsmdb]: Increment session ref count for %d\n", session->session->context_id)); mpm_session_increment_ref_count(session->session); } else { /* Step 7. Associate this emsmdbp context to the session */ session = talloc((TALLOC_CTX *)emsmdb_session, struct exchange_emsmdb_session); OPENCHANGE_RETVAL_IF(!session, MAPI_E_NOT_ENOUGH_RESOURCES, emsmdbp_ctx); session->pullTimeStamp = *r->out.pulTimeStamp; session->session = mpm_session_init((TALLOC_CTX *)emsmdb_session, dce_call); OPENCHANGE_RETVAL_IF(!session->session, MAPI_E_NOT_ENOUGH_RESOURCES, emsmdbp_ctx); session->uuid = handle->wire_handle.uuid; mpm_session_set_private_data(session->session, (void *) emsmdbp_ctx); mpm_session_set_destructor(session->session, emsmdbp_destructor); DEBUG(0, ("[exchange_emsmdb]: New session added: %d\n", session->session->context_id)); DLIST_ADD_END(emsmdb_session, session, struct exchange_emsmdb_session *); } return MAPI_E_SUCCESS; } /** \details exchange_emsmdb EcDoRpcExt2 (0xB) function \param dce_call pointer to the session context \param mem_ctx pointer to the memory context \param r pointer to the EcDoRpcExt2 request data \return MAPI_E_SUCCESS on success */ static enum MAPISTATUS dcesrv_EcDoRpcExt2(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx, struct EcDoRpcExt2 *r) { struct exchange_emsmdb_session *session; struct emsmdbp_context *emsmdbp_ctx = NULL; struct mapi2k7_request mapi2k7_request; struct mapi_response *mapi_response; struct RPC_HEADER_EXT RPC_HEADER_EXT; struct ndr_pull *ndr_pull = NULL; struct ndr_push *ndr_uncomp_rgbOut; struct ndr_push *ndr_comp_rgbOut; struct ndr_push *ndr_rgbOut; uint32_t pulFlags = 0x0; uint32_t pulTransTime = 0; DATA_BLOB rgbIn; DEBUG(3, ("exchange_emsmdb: EcDoRpcExt2 (0xB)\n")); r->out.rgbOut = NULL; *r->out.pcbOut = 0; r->out.rgbAuxOut = NULL; *r->out.pcbAuxOut = 0; /* Step 0. Ensure incoming user is authenticated */ if (!dcesrv_call_authenticated(dce_call)) { DEBUG(1, ("No challenge requested by client, cannot authenticate\n")); r->out.handle->handle_type = 0; r->out.handle->uuid = GUID_zero(); r->out.result = DCERPC_FAULT_CONTEXT_MISMATCH; return MAPI_E_LOGON_FAILED; } /* Retrieve the emsmdbp_context from the session management system */ session = dcesrv_find_emsmdb_session(&r->in.handle->uuid); if (!session) { r->out.handle->handle_type = 0; r->out.handle->uuid = GUID_zero(); r->out.result = DCERPC_FAULT_CONTEXT_MISMATCH; return MAPI_E_LOGON_FAILED; } emsmdbp_ctx = (struct emsmdbp_context *)session->session->private_data; /* Extract mapi_request from rgbIn */ rgbIn.data = r->in.rgbIn; rgbIn.length = r->in.cbIn; ndr_pull = ndr_pull_init_blob(&rgbIn, mem_ctx); ndr_set_flags(&ndr_pull->flags, LIBNDR_FLAG_NOALIGN|LIBNDR_FLAG_REF_ALLOC); ndr_pull_mapi2k7_request(ndr_pull, NDR_SCALARS|NDR_BUFFERS, &mapi2k7_request); talloc_free(ndr_pull); mapi_response = EcDoRpc_process_transaction(mem_ctx, emsmdbp_ctx, mapi2k7_request.mapi_request); talloc_free(mapi2k7_request.mapi_request); /* Fill EcDoRpcExt2 reply */ r->out.handle = r->in.handle; *r->out.pulFlags = pulFlags; /* Push MAPI response into a DATA blob */ ndr_uncomp_rgbOut = ndr_push_init_ctx(mem_ctx); ndr_set_flags(&ndr_uncomp_rgbOut->flags, LIBNDR_FLAG_NOALIGN); ndr_push_mapi_response(ndr_uncomp_rgbOut, NDR_SCALARS|NDR_BUFFERS, mapi_response); talloc_free(mapi_response); /* TODO: compress if requested */ ndr_comp_rgbOut = ndr_uncomp_rgbOut; /* Build RPC_HEADER_EXT header for MAPI response DATA blob */ RPC_HEADER_EXT.Version = 0x0000; RPC_HEADER_EXT.Flags = RHEF_Last; RPC_HEADER_EXT.Flags |= (mapi2k7_request.header.Flags & RHEF_XorMagic); RPC_HEADER_EXT.Size = ndr_comp_rgbOut->offset; RPC_HEADER_EXT.SizeActual = ndr_comp_rgbOut->offset; /* Obfuscate content if applicable*/ if (RPC_HEADER_EXT.Flags & RHEF_XorMagic) { obfuscate_data(ndr_comp_rgbOut->data, ndr_comp_rgbOut->offset, 0xA5); } /* Push the constructed blob */ ndr_rgbOut = ndr_push_init_ctx(mem_ctx); ndr_set_flags(&ndr_rgbOut->flags, LIBNDR_FLAG_NOALIGN); ndr_push_RPC_HEADER_EXT(ndr_rgbOut, NDR_SCALARS|NDR_BUFFERS, &RPC_HEADER_EXT); ndr_push_bytes(ndr_rgbOut, ndr_comp_rgbOut->data, ndr_comp_rgbOut->offset); /* Push MAPI response into a DATA blob */ r->out.rgbOut = ndr_rgbOut->data; *r->out.pcbOut = ndr_rgbOut->offset; *r->out.pulTransTime = pulTransTime; return MAPI_E_SUCCESS; } /** \details exchange_emsmdb EcUnknown0xC (0xc) function \param dce_call pointer to the session context \param mem_ctx pointer to the memory context \param r pointer to the EcUnknown0xC request data \return MAPI_E_SUCCESS on success */ static void dcesrv_EcUnknown0xC(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx, struct EcUnknown0xC *r) { DEBUG(3, ("exchange_emsmdb: EcUnknown0xC (0xc) not implemented\n")); DCESRV_FAULT_VOID(DCERPC_FAULT_OP_RNG_ERROR); } /** \details exchange_emsmdb EcUnknown0xD (0xc) function \param dce_call pointer to the session context \param mem_ctx pointer to the memory context \param r pointer to the EcUnknown0xD request data \return MAPI_E_SUCCESS on success */ static void dcesrv_EcUnknown0xD(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx, struct EcUnknown0xD *r) { DEBUG(3, ("exchange_emsmdb: EcUnknown0xC (0xd) not implemented\n")); DCESRV_FAULT_VOID(DCERPC_FAULT_OP_RNG_ERROR); } /** \details exchange_emsmdb EcGetMoreRpc (0xe) function \param dce_call pointer to the session context \param mem_ctx pointer to the memory context \param r pointer to the EcDoAsyncConnectExt request data \return MAPI_E_SUCCESS on success */ static enum MAPISTATUS dcesrv_EcDoAsyncConnectEx(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx, struct EcDoAsyncConnectEx *r) { DEBUG(3, ("exchange_emsmdb: EcDoAsyncConnectEx (0xe) not implemented\n")); r->out.result = ecRejected; DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR); return MAPI_E_SUCCESS; } /** \details Dispatch incoming EMSMDB call to the correct OpenChange server function \param dce_call pointer to the session context \param mem_ctx pointer to the memory context \param r generic pointer on EMSMDB data \param mapiproxy pointer to the mapiproxy structure controlling mapiproxy behavior \return NT_STATUS_OK; */ static NTSTATUS dcesrv_exchange_emsmdb_dispatch(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx, void *r, struct mapiproxy *mapiproxy) { const struct ndr_interface_table *table; uint16_t opnum; table = (const struct ndr_interface_table *) dce_call->context->iface->private_data; opnum = dce_call->pkt.u.request.opnum; /* Sanity checks */ if (!table) return NT_STATUS_UNSUCCESSFUL; if (table->name && strcmp(table->name, NDR_EXCHANGE_EMSMDB_NAME)) return NT_STATUS_UNSUCCESSFUL; switch (opnum) { case NDR_ECDOCONNECT: dcesrv_EcDoConnect(dce_call, mem_ctx, (struct EcDoConnect *)r); break; case NDR_ECDODISCONNECT: dcesrv_EcDoDisconnect(dce_call, mem_ctx, (struct EcDoDisconnect *)r); break; case NDR_ECDORPC: dcesrv_EcDoRpc(dce_call, mem_ctx, (struct EcDoRpc *)r); break; case NDR_ECGETMORERPC: dcesrv_EcGetMoreRpc(dce_call, mem_ctx, (struct EcGetMoreRpc *)r); break; case NDR_ECRREGISTERPUSHNOTIFICATION: dcesrv_EcRRegisterPushNotification(dce_call, mem_ctx, (struct EcRRegisterPushNotification *)r); break; case NDR_ECRUNREGISTERPUSHNOTIFICATION: dcesrv_EcRUnregisterPushNotification(dce_call, mem_ctx, (struct EcRUnregisterPushNotification *)r); break; case NDR_ECDUMMYRPC: dcesrv_EcDummyRpc(dce_call, mem_ctx, (struct EcDummyRpc *)r); break; case NDR_ECRGETDCNAME: dcesrv_EcRGetDCName(dce_call, mem_ctx, (struct EcRGetDCName *)r); break; case NDR_ECRNETGETDCNAME: dcesrv_EcRNetGetDCName(dce_call, mem_ctx, (struct EcRNetGetDCName *)r); break; case NDR_ECDORPCEXT: dcesrv_EcDoRpcExt(dce_call, mem_ctx, (struct EcDoRpcExt *)r); break; case NDR_ECDOCONNECTEX: dcesrv_EcDoConnectEx(dce_call, mem_ctx, (struct EcDoConnectEx *)r); break; case NDR_ECDORPCEXT2: dcesrv_EcDoRpcExt2(dce_call, mem_ctx, (struct EcDoRpcExt2 *)r); break; case NDR_ECUNKNOWN0XC: dcesrv_EcUnknown0xC(dce_call, mem_ctx, (struct EcUnknown0xC *)r); break; case NDR_ECUNKNOWN0XD: dcesrv_EcUnknown0xD(dce_call, mem_ctx, (struct EcUnknown0xD *)r); break; case NDR_ECDOASYNCCONNECTEX: dcesrv_EcDoAsyncConnectEx(dce_call, mem_ctx, (struct EcDoAsyncConnectEx *)r); break; } return NT_STATUS_OK; } /** \details Initialize the EMSMDB OpenChange server \param dce_ctx pointer to the server context \return NT_STATUS_OK on success */ static NTSTATUS dcesrv_exchange_emsmdb_init(struct dcesrv_context *dce_ctx) { /* Initialize exchange_emsmdb session */ emsmdb_session = talloc_zero(dce_ctx, struct exchange_emsmdb_session); if (!emsmdb_session) return NT_STATUS_NO_MEMORY; emsmdb_session->session = NULL; /* Open read/write context on OpenChange dispatcher database */ openchange_ldb_ctx = emsmdbp_openchange_ldb_init(dce_ctx->lp_ctx); if (!openchange_ldb_ctx) { smb_panic("unable to initialize 'openchange.ldb' context"); } return NT_STATUS_OK; } /** \details Terminate the EMSMDB connection and release the associated session and context if still available. This case occurs when the client doesn't call EcDoDisconnect but quit unexpectedly. \param server_id reference to the server identifier structure \param context_id the connection context identifier \return NT_STATUS_OK on success */ /* FIXME: code temporarily disabled as we don't master the logic behind session handles yet... */ static NTSTATUS dcesrv_exchange_emsmdb_unbind(struct server_id server_id, uint32_t context_id) { /* struct exchange_emsmdb_session *session; */ /* bool ret; */ DEBUG (0, ("dcesrv_exchange_emsmdb_unbind\n")); /* session = dcesrv_find_emsmdb_session_by_server_id(&server_id, context_id); */ /* if (session) { */ /* ret = mpm_session_release(session->session); */ /* if (ret == true) { */ /* DLIST_REMOVE(emsmdb_session, session); */ /* DEBUG(5, ("[%s:%d]: Session found and released\n", */ /* __FUNCTION__, __LINE__)); */ /* } else { */ /* DEBUG(5, ("[%s:%d]: Session found and ref_count decreased\n", */ /* __FUNCTION__, __LINE__)); */ /* } */ /* } */ return NT_STATUS_OK; } /** \details Entry point for the default OpenChange EMSMDB server \return NT_STATUS_OK on success, otherwise NTSTATUS error */ NTSTATUS samba_init_module(void) { struct mapiproxy_module server; NTSTATUS ret; /* Fill in our name */ server.name = "exchange_emsmdb"; server.status = MAPIPROXY_DEFAULT; server.description = "OpenChange EMSMDB server"; server.endpoint = "exchange_emsmdb"; /* Fill in all the operations */ server.init = dcesrv_exchange_emsmdb_init; server.unbind = dcesrv_exchange_emsmdb_unbind; server.dispatch = dcesrv_exchange_emsmdb_dispatch; server.push = NULL; server.pull = NULL; server.ndr_pull = NULL; /* Register ourselves with the MAPIPROXY server subsystem */ ret = mapiproxy_server_register(&server); if (!NT_STATUS_IS_OK(ret)) { DEBUG(0, ("Failed to register the 'exchange_emsmdb' default mapiproxy server!\n")); return ret; } return ret; } openchange-2.0/mapiproxy/servers/default/emsmdb/dcesrv_exchange_emsmdb.h000066400000000000000000000651171223057412600267420ustar00rootroot00000000000000/* MAPI Proxy - Exchange EMSMDB Server OpenChange Project Copyright (C) Julien Kerihuel 2009-2010 This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see . */ #ifndef __DCESRV_EXCHANGE_EMSMDB_H #define __DCESRV_EXCHANGE_EMSMDB_H #include "libmapi/libmapi.h" #include "libmapi/libmapi_private.h" #include "mapiproxy/libmapiproxy/libmapiproxy.h" #include "mapiproxy/libmapistore/mapistore.h" #include "mapiproxy/libmapistore/mapistore_errors.h" #include #include #include #include #include #include #ifndef __BEGIN_DECLS #ifdef __cplusplus #define __BEGIN_DECLS extern "C" { #define __END_DECLS } #else #define __BEGIN_DECLS #define __END_DECLS #endif #endif struct emsmdbp_context { char *szUserDN; char *szDisplayName; uint32_t userLanguage; char *username; struct loadparm_context *lp_ctx; struct ldb_context *oc_ctx; struct ldb_context *samdb_ctx; struct mapistore_context *mstore_ctx; struct mapi_handles_context *handles_ctx; TALLOC_CTX *mem_ctx; }; struct exchange_emsmdb_session { uint32_t pullTimeStamp; struct mpm_session *session; struct GUID uuid; struct exchange_emsmdb_session *prev; struct exchange_emsmdb_session *next; }; struct emsmdbp_stream { size_t position; DATA_BLOB buffer; }; struct emsmdbp_syncconfigure_request { bool is_collector; bool contents_mode; bool unicode; bool use_cpid; bool recover_mode; bool force_unicode; bool no_deletions; bool no_soft_deletions; bool no_foreign_identifiers; bool request_eid; /* contents only */ bool partial_item; bool fai; bool normal; bool ignored_specified_on_fai; bool best_body; bool ignore_no_longer_in_scope; bool read_state; bool progress; bool request_message_size; bool request_cn; bool order_by_delivery_time; DATA_BLOB restriction; }; enum emsmdbp_object_type { EMSMDBP_OBJECT_UNDEF = 0x0, EMSMDBP_OBJECT_MAILBOX = 0x1, EMSMDBP_OBJECT_FOLDER = 0x2, EMSMDBP_OBJECT_MESSAGE = 0x3, EMSMDBP_OBJECT_TABLE = 0x4, EMSMDBP_OBJECT_STREAM = 0x5, EMSMDBP_OBJECT_ATTACHMENT = 0x6, EMSMDBP_OBJECT_SUBSCRIPTION = 0x7, EMSMDBP_OBJECT_FTCONTEXT = 0x8, /* Fast Transfer */ EMSMDBP_OBJECT_SYNCCONTEXT = 0x9 }; struct emsmdbp_object_mailbox { uint64_t folderID; char *owner_Name; char *owner_EssDN; char *szUserDN; char *owner_username; bool mailboxstore; }; struct emsmdbp_object_folder { uint64_t folderID; uint32_t contextID; /* requires mapistore_root == true, undefined otherwise */ bool mapistore_root; /* root mapistore container or not */ struct SRow *postponed_props; /* storage for properties set until PR_CONTAINER_CLASS_UNICODE is set */ }; struct emsmdbp_object_message { uint64_t folderID; uint64_t messageID; bool read_write; struct mapistore_freebusy_properties *fb_properties; }; struct emsmdbp_object_table { enum mapistore_table_type ulType; uint32_t handle; bool restricted; uint16_t prop_count; enum MAPITAGS *properties; uint32_t numerator; uint32_t denominator; struct mapistore_subscription_list *subscription_list; }; struct emsmdbp_object_stream { bool read_write; bool needs_commit; enum MAPITAGS property; struct emsmdbp_stream stream; }; struct emsmdbp_stream_data { enum MAPITAGS prop_tag; DATA_BLOB data; struct emsmdbp_stream_data *next; struct emsmdbp_stream_data *prev; }; struct emsmdbp_object_attachment { uint32_t attachmentID; }; struct emsmdbp_object_subscription { uint32_t handle; struct mapistore_subscription_list *subscription_list; }; struct emsmdbp_object_synccontext { struct emsmdbp_syncconfigure_request request; /* debugging */ unsigned int sent_objects; unsigned int skipped_objects; unsigned int total_objects; struct timeval request_start; /* uploaded synchronization state */ struct idset *idset_given; struct idset *cnset_seen; struct idset *cnset_seen_fai; struct idset *cnset_read; struct SPropTagArray properties; struct SPropTagArray fai_properties; /* sync state upload */ enum StateProperty state_property; struct emsmdbp_stream state_stream; /* data download */ uint16_t sync_stage; void *sync_data; uint16_t steps; uint16_t total_steps; /* download buffers */ struct emsmdbp_stream stream; uint32_t *cutmarks; uint32_t next_cutmark_idx; }; struct emsmdbp_object_ftcontext { uint16_t steps; uint16_t total_steps; struct emsmdbp_stream stream; uint32_t *cutmarks; uint32_t next_cutmark_idx; }; union emsmdbp_objects { struct emsmdbp_object_mailbox *mailbox; struct emsmdbp_object_folder *folder; struct emsmdbp_object_message *message; struct emsmdbp_object_table *table; struct emsmdbp_object_stream *stream; struct emsmdbp_object_attachment *attachment; struct emsmdbp_object_subscription *subscription; struct emsmdbp_object_synccontext *synccontext; struct emsmdbp_object_ftcontext *ftcontext; }; struct emsmdbp_object { struct emsmdbp_object *parent_object; enum emsmdbp_object_type type; union emsmdbp_objects object; struct emsmdbp_context *emsmdbp_ctx; void *backend_object; /* used with mapistore */ struct emsmdbp_stream_data *stream_data; }; #define EMSMDB_PCMSPOLLMAX 60000 #define EMSMDB_PCRETRY 6 #define EMSMDB_PCRETRYDELAY 10000 enum emsmdbp_mailbox_systemidx { EMSMDBP_MAILBOX_ROOT = 1, EMSMDBP_DEFERRED_ACTION, EMSMDBP_SPOOLER_QUEUE, EMSMDBP_COMMON_VIEWS, EMSMDBP_SCHEDULE, EMSMDBP_SEARCH, EMSMDBP_VIEWS, EMSMDBP_SHORTCUTS, /* search folders */ EMSMDBP_REMINDERS, EMSMDBP_TODO, EMSMDBP_TRACKEDMAILPROCESSING, /* user-visible folders */ EMSMDBP_TOP_INFORMATION_STORE, EMSMDBP_INBOX, EMSMDBP_OUTBOX, EMSMDBP_SENT_ITEMS, EMSMDBP_DELETED_ITEMS, EMSMDBP_MAX_MAILBOX_SYSTEMIDX }; enum emsmdbp_pf_systemidx { EMSMDBP_PF_ROOT = 1, EMSMDBP_PF_IPMSUBTREE, EMSMDBP_PF_NONIPMSUBTREE, EMSMDBP_PF_EFORMSREGISTRY, EMSMDBP_PF_FREEBUSY, EMSMDBP_PF_OAB, EMSMDBP_PF_LOCALEFORMS, EMSMDBP_PF_LOCALFREEBUSY, EMSMDBP_PF_LOCALOAB, EMSMDBP_MAX_PF_SYSTEMIDX }; struct emsmdbp_special_folder { enum mapistore_context_role role; enum MAPITAGS entryid_property; const char *name; }; __BEGIN_DECLS NTSTATUS samba_init_module(void); struct ldb_context *samdb_connect(TALLOC_CTX *, struct tevent_context *, struct loadparm_context *, struct auth_session_info *, int); /* definitions from emsmdbp.c */ struct emsmdbp_context *emsmdbp_init(struct loadparm_context *, const char *, void *); void *emsmdbp_openchange_ldb_init(struct loadparm_context *); bool emsmdbp_destructor(void *); bool emsmdbp_verify_user(struct dcesrv_call_state *, struct emsmdbp_context *); bool emsmdbp_verify_userdn(struct dcesrv_call_state *, struct emsmdbp_context *, const char *, struct ldb_message **); enum MAPISTATUS emsmdbp_resolve_recipient(TALLOC_CTX *, struct emsmdbp_context *, char *, struct mapi_SPropTagArray *, struct RecipientRow *); const struct GUID *const MagicGUIDp; int emsmdbp_guid_to_replid(struct emsmdbp_context *, const char *username, const struct GUID *, uint16_t *); int emsmdbp_replid_to_guid(struct emsmdbp_context *, const char *username, const uint16_t, struct GUID *); int emsmdbp_source_key_from_fmid(TALLOC_CTX *, struct emsmdbp_context *, const char *username, uint64_t, struct Binary_r **); /* definitions from emsmdbp_object.c */ const char *emsmdbp_getstr_type(struct emsmdbp_object *); bool emsmdbp_is_mapistore(struct emsmdbp_object *); bool emsmdbp_is_mailboxstore(struct emsmdbp_object *); char *emsmdbp_get_owner(struct emsmdbp_object *object); int emsmdbp_get_uri_from_fid(TALLOC_CTX *, struct emsmdbp_context *, uint64_t, char **); int emsmdbp_get_fid_from_uri(struct emsmdbp_context *, const char *, uint64_t *); uint32_t emsmdbp_get_contextID(struct emsmdbp_object *); /* definitions from emsmdbp_privisioning.c */ enum MAPISTATUS emsmdbp_mailbox_provision(struct emsmdbp_context *, const char *); enum MAPISTATUS emsmdbp_mailbox_provision_public_freebusy(struct emsmdbp_context *, const char *); /* With emsmdbp_object_create_folder and emsmdbp_object_open_folder, the parent object IS the direct parent */ enum mapistore_error emsmdbp_object_get_fid_by_name(struct emsmdbp_context *, struct emsmdbp_object *, const char *, uint64_t *); enum MAPISTATUS emsmdbp_object_create_folder(struct emsmdbp_context *, struct emsmdbp_object *, TALLOC_CTX *, uint64_t, struct SRow *, struct emsmdbp_object **); enum mapistore_error emsmdbp_object_open_folder(TALLOC_CTX *, struct emsmdbp_context *, struct emsmdbp_object *, uint64_t, struct emsmdbp_object **); enum mapistore_error emsmdbp_object_open_folder_by_fid(TALLOC_CTX *, struct emsmdbp_context *, struct emsmdbp_object *, uint64_t, struct emsmdbp_object **); struct emsmdbp_object *emsmdbp_object_init(TALLOC_CTX *, struct emsmdbp_context *, struct emsmdbp_object *parent_object); int emsmdbp_object_copy_properties(struct emsmdbp_context *, struct emsmdbp_object *, struct emsmdbp_object *, struct SPropTagArray *, bool); struct emsmdbp_object *emsmdbp_object_mailbox_init(TALLOC_CTX *, struct emsmdbp_context *, const char *, bool); struct emsmdbp_object *emsmdbp_object_folder_init(TALLOC_CTX *, struct emsmdbp_context *, uint64_t, struct emsmdbp_object *); int emsmdbp_folder_get_folder_count(struct emsmdbp_context *, struct emsmdbp_object *, uint32_t *); enum mapistore_error emsmdbp_folder_delete(struct emsmdbp_context *, struct emsmdbp_object *, uint64_t, uint8_t); enum mapistore_error emsmdbp_folder_move_folder(struct emsmdbp_context *, struct emsmdbp_object *, struct emsmdbp_object *, TALLOC_CTX *, const char *); struct emsmdbp_object *emsmdbp_folder_open_table(TALLOC_CTX *, struct emsmdbp_object *, uint32_t, uint32_t); struct emsmdbp_object *emsmdbp_object_table_init(TALLOC_CTX *, struct emsmdbp_context *, struct emsmdbp_object *); int emsmdbp_object_table_get_available_properties(TALLOC_CTX *, struct emsmdbp_context *, struct emsmdbp_object *, struct SPropTagArray **); void **emsmdbp_object_table_get_row_props(TALLOC_CTX *, struct emsmdbp_context *, struct emsmdbp_object *, uint32_t, enum mapistore_query_type, enum MAPISTATUS **); struct emsmdbp_object *emsmdbp_object_message_init(TALLOC_CTX *, struct emsmdbp_context *, uint64_t, struct emsmdbp_object *); enum mapistore_error emsmdbp_object_message_open(TALLOC_CTX *, struct emsmdbp_context *, struct emsmdbp_object *, uint64_t, uint64_t, bool, struct emsmdbp_object **, struct mapistore_message **); struct emsmdbp_object *emsmdbp_object_message_open_attachment_table(TALLOC_CTX *, struct emsmdbp_context *, struct emsmdbp_object *); struct emsmdbp_object *emsmdbp_object_stream_init(TALLOC_CTX *, struct emsmdbp_context *, struct emsmdbp_object *); int emsmdbp_object_stream_commit(struct emsmdbp_object *); struct emsmdbp_object *emsmdbp_object_attachment_init(TALLOC_CTX *, struct emsmdbp_context *, uint64_t, struct emsmdbp_object *); struct emsmdbp_object *emsmdbp_object_subscription_init(TALLOC_CTX *, struct emsmdbp_context *, struct emsmdbp_object *); int emsmdbp_object_get_available_properties(TALLOC_CTX *, struct emsmdbp_context *, struct emsmdbp_object *, struct SPropTagArray **); int emsmdbp_object_set_properties(struct emsmdbp_context *, struct emsmdbp_object *, struct SRow *); void **emsmdbp_object_get_properties(TALLOC_CTX *, struct emsmdbp_context *, struct emsmdbp_object *, struct SPropTagArray *, enum MAPISTATUS **); struct emsmdbp_object *emsmdbp_object_synccontext_init(TALLOC_CTX *, struct emsmdbp_context *, struct emsmdbp_object *); struct emsmdbp_object *emsmdbp_object_ftcontext_init(TALLOC_CTX *, struct emsmdbp_context *, struct emsmdbp_object *); struct emsmdbp_stream_data *emsmdbp_stream_data_from_value(TALLOC_CTX *, enum MAPITAGS, void *value, bool); struct emsmdbp_stream_data *emsmdbp_object_get_stream_data(struct emsmdbp_object *, enum MAPITAGS); DATA_BLOB emsmdbp_stream_read_buffer(struct emsmdbp_stream *, uint32_t); void emsmdbp_stream_write_buffer(TALLOC_CTX *, struct emsmdbp_stream *, DATA_BLOB); void emsmdbp_fill_table_row_blob(TALLOC_CTX *, struct emsmdbp_context *, DATA_BLOB *, uint16_t, enum MAPITAGS *, void **, enum MAPISTATUS *); void emsmdbp_fill_row_blob(TALLOC_CTX *, struct emsmdbp_context *, uint8_t *, DATA_BLOB *,struct SPropTagArray *, void **, enum MAPISTATUS *, bool *); /* definitions from oxcfold.c */ enum MAPISTATUS EcDoRpc_RopOpenFolder(TALLOC_CTX *, struct emsmdbp_context *, struct EcDoRpc_MAPI_REQ *, struct EcDoRpc_MAPI_REPL *, uint32_t *, uint16_t *); enum MAPISTATUS EcDoRpc_RopGetHierarchyTable(TALLOC_CTX *, struct emsmdbp_context *, struct EcDoRpc_MAPI_REQ *, struct EcDoRpc_MAPI_REPL *, uint32_t *, uint16_t *); enum MAPISTATUS EcDoRpc_RopGetContentsTable(TALLOC_CTX *, struct emsmdbp_context *, struct EcDoRpc_MAPI_REQ *, struct EcDoRpc_MAPI_REPL *, uint32_t *, uint16_t *); enum MAPISTATUS EcDoRpc_RopCreateFolder(TALLOC_CTX *, struct emsmdbp_context *, struct EcDoRpc_MAPI_REQ *, struct EcDoRpc_MAPI_REPL *, uint32_t *, uint16_t *); enum MAPISTATUS EcDoRpc_RopDeleteFolder(TALLOC_CTX *, struct emsmdbp_context *, struct EcDoRpc_MAPI_REQ *, struct EcDoRpc_MAPI_REPL *, uint32_t *, uint16_t *); enum MAPISTATUS EcDoRpc_RopDeleteMessages(TALLOC_CTX *, struct emsmdbp_context *, struct EcDoRpc_MAPI_REQ *, struct EcDoRpc_MAPI_REPL *, uint32_t *, uint16_t *); enum MAPISTATUS EcDoRpc_RopSetSearchCriteria(TALLOC_CTX *, struct emsmdbp_context *, struct EcDoRpc_MAPI_REQ *, struct EcDoRpc_MAPI_REPL *, uint32_t *, uint16_t *); enum MAPISTATUS EcDoRpc_RopGetSearchCriteria(TALLOC_CTX *, struct emsmdbp_context *, struct EcDoRpc_MAPI_REQ *, struct EcDoRpc_MAPI_REPL *, uint32_t *, uint16_t *); enum MAPISTATUS EcDoRpc_RopEmptyFolder(TALLOC_CTX *, struct emsmdbp_context *, struct EcDoRpc_MAPI_REQ *, struct EcDoRpc_MAPI_REPL *, uint32_t *, uint16_t *); enum MAPISTATUS EcDoRpc_RopMoveCopyMessages(TALLOC_CTX *, struct emsmdbp_context *, struct EcDoRpc_MAPI_REQ *, struct EcDoRpc_MAPI_REPL *, uint32_t *, uint16_t *); enum MAPISTATUS EcDoRpc_RopMoveFolder(TALLOC_CTX *, struct emsmdbp_context *, struct EcDoRpc_MAPI_REQ *, struct EcDoRpc_MAPI_REPL *, uint32_t *, uint16_t *); enum MAPISTATUS EcDoRpc_RopCopyFolder(TALLOC_CTX *, struct emsmdbp_context *, struct EcDoRpc_MAPI_REQ *, struct EcDoRpc_MAPI_REPL *, uint32_t *, uint16_t *); /* definitions from oxcmsg.c */ enum MAPISTATUS EcDoRpc_RopOpenMessage(TALLOC_CTX *, struct emsmdbp_context *, struct EcDoRpc_MAPI_REQ *, struct EcDoRpc_MAPI_REPL *, uint32_t *, uint16_t *); enum MAPISTATUS EcDoRpc_RopCreateMessage(TALLOC_CTX *, struct emsmdbp_context *, struct EcDoRpc_MAPI_REQ *, struct EcDoRpc_MAPI_REPL *, uint32_t *, uint16_t *); enum MAPISTATUS EcDoRpc_RopSaveChangesMessage(TALLOC_CTX *, struct emsmdbp_context *, struct EcDoRpc_MAPI_REQ *, struct EcDoRpc_MAPI_REPL *, uint32_t *, uint16_t *); enum MAPISTATUS EcDoRpc_RopRemoveAllRecipients(TALLOC_CTX *, struct emsmdbp_context *, struct EcDoRpc_MAPI_REQ *, struct EcDoRpc_MAPI_REPL *, uint32_t *, uint16_t *); enum MAPISTATUS EcDoRpc_RopModifyRecipients(TALLOC_CTX *, struct emsmdbp_context *, struct EcDoRpc_MAPI_REQ *, struct EcDoRpc_MAPI_REPL *, uint32_t *, uint16_t *); enum MAPISTATUS EcDoRpc_RopReloadCachedInformation(TALLOC_CTX *, struct emsmdbp_context *, struct EcDoRpc_MAPI_REQ *, struct EcDoRpc_MAPI_REPL *, uint32_t *, uint16_t *); enum MAPISTATUS EcDoRpc_RopSetMessageReadFlag(TALLOC_CTX *, struct emsmdbp_context *, struct EcDoRpc_MAPI_REQ *, struct EcDoRpc_MAPI_REPL *, uint32_t *, uint16_t *); enum MAPISTATUS EcDoRpc_RopGetAttachmentTable(TALLOC_CTX *, struct emsmdbp_context *, struct EcDoRpc_MAPI_REQ *, struct EcDoRpc_MAPI_REPL *, uint32_t *, uint16_t *); enum MAPISTATUS EcDoRpc_RopOpenAttach(TALLOC_CTX *, struct emsmdbp_context *, struct EcDoRpc_MAPI_REQ *, struct EcDoRpc_MAPI_REPL *, uint32_t *, uint16_t *); enum MAPISTATUS EcDoRpc_RopCreateAttach(TALLOC_CTX *, struct emsmdbp_context *, struct EcDoRpc_MAPI_REQ *, struct EcDoRpc_MAPI_REPL *, uint32_t *, uint16_t *); enum MAPISTATUS EcDoRpc_RopSaveChangesAttachment(TALLOC_CTX *, struct emsmdbp_context *, struct EcDoRpc_MAPI_REQ *, struct EcDoRpc_MAPI_REPL *, uint32_t *, uint16_t *); enum MAPISTATUS EcDoRpc_RopOpenEmbeddedMessage(TALLOC_CTX *, struct emsmdbp_context *, struct EcDoRpc_MAPI_REQ *, struct EcDoRpc_MAPI_REPL *, uint32_t *, uint16_t *); /* definitions from oxcnotif.c */ enum MAPISTATUS EcDoRpc_RopRegisterNotification(TALLOC_CTX *, struct emsmdbp_context *, struct EcDoRpc_MAPI_REQ *, struct EcDoRpc_MAPI_REPL *, uint32_t *, uint16_t *); /* definitions from oxcprpt.c */ enum MAPISTATUS EcDoRpc_RopGetPropertiesSpecific(TALLOC_CTX *, struct emsmdbp_context *, struct EcDoRpc_MAPI_REQ *, struct EcDoRpc_MAPI_REPL *, uint32_t *, uint16_t *); enum MAPISTATUS EcDoRpc_RopGetPropertiesAll(TALLOC_CTX *, struct emsmdbp_context *, struct EcDoRpc_MAPI_REQ *, struct EcDoRpc_MAPI_REPL *, uint32_t *, uint16_t *); enum MAPISTATUS EcDoRpc_RopGetPropertiesList(TALLOC_CTX *, struct emsmdbp_context *, struct EcDoRpc_MAPI_REQ *, struct EcDoRpc_MAPI_REPL *, uint32_t *, uint16_t *); enum MAPISTATUS EcDoRpc_RopSetProperties(TALLOC_CTX *, struct emsmdbp_context *, struct EcDoRpc_MAPI_REQ *, struct EcDoRpc_MAPI_REPL *, uint32_t *, uint16_t *); enum MAPISTATUS EcDoRpc_RopDeleteProperties(TALLOC_CTX *, struct emsmdbp_context *, struct EcDoRpc_MAPI_REQ *, struct EcDoRpc_MAPI_REPL *, uint32_t *, uint16_t *); enum MAPISTATUS EcDoRpc_RopOpenStream(TALLOC_CTX *, struct emsmdbp_context *, struct EcDoRpc_MAPI_REQ *, struct EcDoRpc_MAPI_REPL *, uint32_t *, uint16_t *); enum MAPISTATUS EcDoRpc_RopReadStream(TALLOC_CTX *, struct emsmdbp_context *, struct EcDoRpc_MAPI_REQ *, struct EcDoRpc_MAPI_REPL *, uint32_t *, uint16_t *); enum MAPISTATUS EcDoRpc_RopWriteStream(TALLOC_CTX *, struct emsmdbp_context *, struct EcDoRpc_MAPI_REQ *, struct EcDoRpc_MAPI_REPL *, uint32_t *, uint16_t *); enum MAPISTATUS EcDoRpc_RopCommitStream(TALLOC_CTX *, struct emsmdbp_context *, struct EcDoRpc_MAPI_REQ *, struct EcDoRpc_MAPI_REPL *, uint32_t *, uint16_t *); enum MAPISTATUS EcDoRpc_RopGetStreamSize(TALLOC_CTX *, struct emsmdbp_context *, struct EcDoRpc_MAPI_REQ *, struct EcDoRpc_MAPI_REPL *, uint32_t *, uint16_t *); enum MAPISTATUS EcDoRpc_RopSeekStream(TALLOC_CTX *, struct emsmdbp_context *, struct EcDoRpc_MAPI_REQ *, struct EcDoRpc_MAPI_REPL *, uint32_t *, uint16_t *); enum MAPISTATUS EcDoRpc_RopSetStreamSize(TALLOC_CTX *, struct emsmdbp_context *, struct EcDoRpc_MAPI_REQ *, struct EcDoRpc_MAPI_REPL *, uint32_t *, uint16_t *); enum MAPISTATUS EcDoRpc_RopGetNamesFromIDs(TALLOC_CTX *, struct emsmdbp_context *, struct EcDoRpc_MAPI_REQ *, struct EcDoRpc_MAPI_REPL *, uint32_t *, uint16_t *); enum MAPISTATUS EcDoRpc_RopGetPropertyIdsFromNames(TALLOC_CTX *, struct emsmdbp_context *, struct EcDoRpc_MAPI_REQ *, struct EcDoRpc_MAPI_REPL *, uint32_t *, uint16_t *); enum MAPISTATUS EcDoRpc_RopDeletePropertiesNoReplicate(TALLOC_CTX *, struct emsmdbp_context *, struct EcDoRpc_MAPI_REQ *, struct EcDoRpc_MAPI_REPL *, uint32_t *, uint16_t *); enum MAPISTATUS EcDoRpc_RopCopyTo(TALLOC_CTX *, struct emsmdbp_context *, struct EcDoRpc_MAPI_REQ *, struct EcDoRpc_MAPI_REPL *, uint32_t *, uint16_t *); /* definitions from oxcstor.c */ enum MAPISTATUS EcDoRpc_RopLogon(TALLOC_CTX *, struct emsmdbp_context *, struct EcDoRpc_MAPI_REQ *, struct EcDoRpc_MAPI_REPL *, uint32_t *, uint16_t *); enum MAPISTATUS EcDoRpc_RopRelease(TALLOC_CTX *, struct emsmdbp_context *, struct EcDoRpc_MAPI_REQ *, uint32_t *, uint16_t *); enum MAPISTATUS EcDoRpc_RopGetReceiveFolder(TALLOC_CTX *, struct emsmdbp_context *, struct EcDoRpc_MAPI_REQ *, struct EcDoRpc_MAPI_REPL *, uint32_t *, uint16_t *); enum MAPISTATUS EcDoRpc_RopSetReceiveFolder(TALLOC_CTX *, struct emsmdbp_context *, struct EcDoRpc_MAPI_REQ *, struct EcDoRpc_MAPI_REPL *, uint32_t *, uint16_t *); enum MAPISTATUS EcDoRpc_RopGetPerUserLongTermIds(TALLOC_CTX *, struct emsmdbp_context *, struct EcDoRpc_MAPI_REQ *, struct EcDoRpc_MAPI_REPL *, uint32_t *, uint16_t *); enum MAPISTATUS EcDoRpc_RopGetPerUserGuid(TALLOC_CTX *, struct emsmdbp_context *, struct EcDoRpc_MAPI_REQ *, struct EcDoRpc_MAPI_REPL *, uint32_t *, uint16_t *); enum MAPISTATUS EcDoRpc_RopGetStoreState(TALLOC_CTX *, struct emsmdbp_context *, struct EcDoRpc_MAPI_REQ *, struct EcDoRpc_MAPI_REPL *, uint32_t *, uint16_t *); enum MAPISTATUS EcDoRpc_RopReadPerUserInformation(TALLOC_CTX *, struct emsmdbp_context *, struct EcDoRpc_MAPI_REQ *, struct EcDoRpc_MAPI_REPL *, uint32_t *, uint16_t *); enum MAPISTATUS EcDoRpc_RopLongTermIdFromId(TALLOC_CTX *, struct emsmdbp_context *, struct EcDoRpc_MAPI_REQ *, struct EcDoRpc_MAPI_REPL *, uint32_t *, uint16_t *); enum MAPISTATUS EcDoRpc_RopIdFromLongTermId(TALLOC_CTX *, struct emsmdbp_context *, struct EcDoRpc_MAPI_REQ *, struct EcDoRpc_MAPI_REPL *, uint32_t *, uint16_t *); /* definition from oxctabl.c */ enum MAPISTATUS EcDoRpc_RopSetColumns(TALLOC_CTX *, struct emsmdbp_context *, struct EcDoRpc_MAPI_REQ *, struct EcDoRpc_MAPI_REPL *, uint32_t *, uint16_t *); enum MAPISTATUS EcDoRpc_RopSortTable(TALLOC_CTX *, struct emsmdbp_context *, struct EcDoRpc_MAPI_REQ *, struct EcDoRpc_MAPI_REPL *, uint32_t *, uint16_t *); enum MAPISTATUS EcDoRpc_RopRestrict(TALLOC_CTX *, struct emsmdbp_context *, struct EcDoRpc_MAPI_REQ *, struct EcDoRpc_MAPI_REPL *, uint32_t *, uint16_t *); enum MAPISTATUS EcDoRpc_RopQueryRows(TALLOC_CTX *, struct emsmdbp_context *, struct EcDoRpc_MAPI_REQ *, struct EcDoRpc_MAPI_REPL *, uint32_t *, uint16_t *); enum MAPISTATUS EcDoRpc_RopQueryPosition(TALLOC_CTX *, struct emsmdbp_context *, struct EcDoRpc_MAPI_REQ *, struct EcDoRpc_MAPI_REPL *, uint32_t *, uint16_t *); enum MAPISTATUS EcDoRpc_RopSeekRow(TALLOC_CTX *, struct emsmdbp_context *, struct EcDoRpc_MAPI_REQ *, struct EcDoRpc_MAPI_REPL *, uint32_t *, uint16_t *); enum MAPISTATUS EcDoRpc_RopFindRow(TALLOC_CTX *, struct emsmdbp_context *, struct EcDoRpc_MAPI_REQ *, struct EcDoRpc_MAPI_REPL *, uint32_t *, uint16_t *); enum MAPISTATUS EcDoRpc_RopResetTable(TALLOC_CTX *, struct emsmdbp_context *, struct EcDoRpc_MAPI_REQ *, struct EcDoRpc_MAPI_REPL *, uint32_t *, uint16_t *); /* definition from oxomsg.c */ enum MAPISTATUS EcDoRpc_RopSubmitMessage(TALLOC_CTX *, struct emsmdbp_context *, struct EcDoRpc_MAPI_REQ *, struct EcDoRpc_MAPI_REPL *, uint32_t *, uint16_t *); enum MAPISTATUS EcDoRpc_RopSetSpooler(TALLOC_CTX *, struct emsmdbp_context *, struct EcDoRpc_MAPI_REQ *, struct EcDoRpc_MAPI_REPL *, uint32_t *, uint16_t *); enum MAPISTATUS EcDoRpc_RopGetAddressTypes(TALLOC_CTX *, struct emsmdbp_context *, struct EcDoRpc_MAPI_REQ *, struct EcDoRpc_MAPI_REPL *, uint32_t *, uint16_t *); enum MAPISTATUS EcDoRpc_RopTransportSend(TALLOC_CTX *, struct emsmdbp_context *, struct EcDoRpc_MAPI_REQ *, struct EcDoRpc_MAPI_REPL *, uint32_t *, uint16_t *); enum MAPISTATUS EcDoRpc_RopGetTransportFolder(TALLOC_CTX *, struct emsmdbp_context *, struct EcDoRpc_MAPI_REQ *, struct EcDoRpc_MAPI_REPL *, uint32_t *, uint16_t *); enum MAPISTATUS EcDoRpc_RopOptionsData(TALLOC_CTX *, struct emsmdbp_context *, struct EcDoRpc_MAPI_REQ *, struct EcDoRpc_MAPI_REPL *, uint32_t *, uint16_t *); /* definitions from oxorule.c */ enum MAPISTATUS EcDoRpc_RopGetRulesTable(TALLOC_CTX *, struct emsmdbp_context *, struct EcDoRpc_MAPI_REQ *, struct EcDoRpc_MAPI_REPL *, uint32_t *, uint16_t *); enum MAPISTATUS EcDoRpc_RopModifyRules(TALLOC_CTX *, struct emsmdbp_context *, struct EcDoRpc_MAPI_REQ *, struct EcDoRpc_MAPI_REPL *, uint32_t *, uint16_t *); /* definitions from oxcperm.c */ enum MAPISTATUS EcDoRpc_RopGetPermissionsTable(TALLOC_CTX *, struct emsmdbp_context *, struct EcDoRpc_MAPI_REQ *, struct EcDoRpc_MAPI_REPL *, uint32_t *, uint16_t *); enum MAPISTATUS EcDoRpc_RopModifyPermissions(TALLOC_CTX *, struct emsmdbp_context *, struct EcDoRpc_MAPI_REQ *, struct EcDoRpc_MAPI_REPL *, uint32_t *, uint16_t *); /* definitions from oxcfxics.c */ enum MAPISTATUS EcDoRpc_RopFastTransferSourceCopyTo(TALLOC_CTX *, struct emsmdbp_context *, struct EcDoRpc_MAPI_REQ *, struct EcDoRpc_MAPI_REPL *, uint32_t *, uint16_t *); enum MAPISTATUS EcDoRpc_RopFastTransferSourceGetBuffer(TALLOC_CTX *, struct emsmdbp_context *, struct EcDoRpc_MAPI_REQ *, struct EcDoRpc_MAPI_REPL *, uint32_t *, uint16_t *); enum MAPISTATUS EcDoRpc_RopSyncConfigure(TALLOC_CTX *, struct emsmdbp_context *, struct EcDoRpc_MAPI_REQ *, struct EcDoRpc_MAPI_REPL *, uint32_t *, uint16_t *); enum MAPISTATUS EcDoRpc_RopSyncImportMessageChange(TALLOC_CTX *, struct emsmdbp_context *, struct EcDoRpc_MAPI_REQ *, struct EcDoRpc_MAPI_REPL *, uint32_t *, uint16_t *); enum MAPISTATUS EcDoRpc_RopSyncImportHierarchyChange(TALLOC_CTX *, struct emsmdbp_context *, struct EcDoRpc_MAPI_REQ *, struct EcDoRpc_MAPI_REPL *, uint32_t *, uint16_t *); enum MAPISTATUS EcDoRpc_RopSyncImportDeletes(TALLOC_CTX *, struct emsmdbp_context *, struct EcDoRpc_MAPI_REQ *, struct EcDoRpc_MAPI_REPL *, uint32_t *, uint16_t *); enum MAPISTATUS EcDoRpc_RopSyncUploadStateStreamBegin(TALLOC_CTX *, struct emsmdbp_context *, struct EcDoRpc_MAPI_REQ *, struct EcDoRpc_MAPI_REPL *, uint32_t *, uint16_t *); enum MAPISTATUS EcDoRpc_RopSyncUploadStateStreamContinue(TALLOC_CTX *, struct emsmdbp_context *, struct EcDoRpc_MAPI_REQ *, struct EcDoRpc_MAPI_REPL *, uint32_t *, uint16_t *); enum MAPISTATUS EcDoRpc_RopSyncUploadStateStreamEnd(TALLOC_CTX *, struct emsmdbp_context *, struct EcDoRpc_MAPI_REQ *, struct EcDoRpc_MAPI_REPL *, uint32_t *, uint16_t *); enum MAPISTATUS EcDoRpc_RopSyncImportMessageMove(TALLOC_CTX *, struct emsmdbp_context *, struct EcDoRpc_MAPI_REQ *, struct EcDoRpc_MAPI_REPL *, uint32_t *, uint16_t *); enum MAPISTATUS EcDoRpc_RopSyncOpenCollector(TALLOC_CTX *, struct emsmdbp_context *, struct EcDoRpc_MAPI_REQ *, struct EcDoRpc_MAPI_REPL *, uint32_t *, uint16_t *); enum MAPISTATUS EcDoRpc_RopGetLocalReplicaIds(TALLOC_CTX *, struct emsmdbp_context *, struct EcDoRpc_MAPI_REQ *, struct EcDoRpc_MAPI_REPL *, uint32_t *, uint16_t *); enum MAPISTATUS EcDoRpc_RopSyncImportReadStateChanges(TALLOC_CTX *, struct emsmdbp_context *, struct EcDoRpc_MAPI_REQ *, struct EcDoRpc_MAPI_REPL *, uint32_t *, uint16_t *); enum MAPISTATUS EcDoRpc_RopSyncGetTransferState(TALLOC_CTX *, struct emsmdbp_context *, struct EcDoRpc_MAPI_REQ *, struct EcDoRpc_MAPI_REPL *, uint32_t *, uint16_t *); enum MAPISTATUS EcDoRpc_RopSetLocalReplicaMidsetDeleted(TALLOC_CTX *, struct emsmdbp_context *, struct EcDoRpc_MAPI_REQ *, struct EcDoRpc_MAPI_REPL *, uint32_t *, uint16_t *); __END_DECLS #endif /* __DCESRV_EXCHANGE_EMSMDB_H */ openchange-2.0/mapiproxy/servers/default/emsmdb/emsmdbp.c000066400000000000000000000363521223057412600237040ustar00rootroot00000000000000/* OpenChange Server implementation EMSMDBP: EMSMDB Provider implementation Copyright (C) Julien Kerihuel 2009 This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see . */ /** \file emsmdbp.c \brief EMSMDB Provider implementation */ #define TEVENT_DEPRECATED #include "mapiproxy/dcesrv_mapiproxy.h" #include "dcesrv_exchange_emsmdb.h" #include "mapiproxy/libmapiserver/libmapiserver.h" #include static struct GUID MagicGUID = { .time_low = 0xbeefface, .time_mid = 0xcafe, .time_hi_and_version = 0xbabe, .clock_seq = { 0x12, 0x34 }, .node = { 0xde, 0xad, 0xfa, 0xce, 0xca, 0xfe } }; const struct GUID *const MagicGUIDp = &MagicGUID; /** \details Release the MAPISTORE context used by EMSMDB provider context \param data pointer on data to destroy \return 0 on success, otherwise -1 */ static int emsmdbp_mapi_store_destructor(void *data) { struct mapistore_context *mstore_ctx = (struct mapistore_context *) data; mapistore_release(mstore_ctx); DEBUG(6, ("[%s:%d]: MAPISTORE context released\n", __FUNCTION__, __LINE__)); return true; } /** \details Release the MAPI handles context used by EMSMDB provider context \param data pointer on data to destroy \return 0 on success, otherwise -1 */ static int emsmdbp_mapi_handles_destructor(void *data) { enum MAPISTATUS retval; struct mapi_handles_context *handles_ctx = (struct mapi_handles_context *) data; retval = mapi_handles_release(handles_ctx); DEBUG(6, ("[%s:%d]: MAPI handles context released (%s)\n", __FUNCTION__, __LINE__, mapi_get_errstr(retval))); return (retval == MAPI_E_SUCCESS) ? 0 : -1; } /** \details Initialize the EMSMDBP context and open connections to Samba databases. \param lp_ctx pointer to the loadparm_context \param username account name for current session \param ldb_ctx pointer to the openchange dispatcher ldb database \return Allocated emsmdbp_context pointer on success, otherwise NULL */ _PUBLIC_ struct emsmdbp_context *emsmdbp_init(struct loadparm_context *lp_ctx, const char *username, void *ldb_ctx) { TALLOC_CTX *mem_ctx; struct emsmdbp_context *emsmdbp_ctx; struct tevent_context *ev; enum mapistore_error ret; /* Sanity Checks */ if (!lp_ctx) return NULL; mem_ctx = talloc_named(NULL, 0, "emsmdbp_init"); emsmdbp_ctx = talloc_zero(mem_ctx, struct emsmdbp_context); if (!emsmdbp_ctx) { talloc_free(mem_ctx); return NULL; } emsmdbp_ctx->mem_ctx = mem_ctx; ev = tevent_context_init(mem_ctx); if (!ev) { talloc_free(mem_ctx); return NULL; } tevent_loop_allow_nesting(ev); /* Save a pointer to the loadparm context */ emsmdbp_ctx->lp_ctx = lp_ctx; /* return an opaque context pointer on samDB database */ emsmdbp_ctx->samdb_ctx = samdb_connect(mem_ctx, ev, lp_ctx, system_session(lp_ctx), 0); if (!emsmdbp_ctx->samdb_ctx) { talloc_free(mem_ctx); DEBUG(0, ("[%s:%d]: Connection to \"sam.ldb\" failed\n", __FUNCTION__, __LINE__)); return NULL; } /* Reference global OpenChange dispatcher database pointer within current context */ emsmdbp_ctx->oc_ctx = ldb_ctx; /* Initialize the mapistore context */ emsmdbp_ctx->mstore_ctx = mapistore_init(mem_ctx, lp_ctx, NULL); if (!emsmdbp_ctx->mstore_ctx) { DEBUG(0, ("[%s:%d]: MAPISTORE initialization failed\n", __FUNCTION__, __LINE__)); talloc_free(mem_ctx); return NULL; } ret = mapistore_set_connection_info(emsmdbp_ctx->mstore_ctx, emsmdbp_ctx->samdb_ctx, emsmdbp_ctx->oc_ctx, username); if (ret != MAPISTORE_SUCCESS) { DEBUG(0, ("[%s:%d]: MAPISTORE connection info initialization failed\n", __FUNCTION__, __LINE__)); talloc_free(mem_ctx); return NULL; } talloc_set_destructor((void *)emsmdbp_ctx->mstore_ctx, (int (*)(void *))emsmdbp_mapi_store_destructor); /* Initialize MAPI handles context */ emsmdbp_ctx->handles_ctx = mapi_handles_init(mem_ctx); if (!emsmdbp_ctx->handles_ctx) { DEBUG(0, ("[%s:%d]: MAPI handles context initialization failed\n", __FUNCTION__, __LINE__)); talloc_free(mem_ctx); return NULL; } talloc_set_destructor((void *)emsmdbp_ctx->handles_ctx, (int (*)(void *))emsmdbp_mapi_handles_destructor); return emsmdbp_ctx; } /** \details Open openchange.ldb database \param lp_ctx pointer on the loadparm_context \note This function is just a wrapper over mapiproxy_server_openchange_ldb_init \return Allocated LDB context on success, otherwise NULL */ _PUBLIC_ void *emsmdbp_openchange_ldb_init(struct loadparm_context *lp_ctx) { /* Sanity checks */ if (!lp_ctx) return NULL; return mapiproxy_server_openchange_ldb_init(lp_ctx); } _PUBLIC_ bool emsmdbp_destructor(void *data) { struct emsmdbp_context *emsmdbp_ctx = (struct emsmdbp_context *)data; if (!emsmdbp_ctx) return false; talloc_unlink(emsmdbp_ctx, emsmdbp_ctx->oc_ctx); talloc_free(emsmdbp_ctx->mem_ctx); DEBUG(0, ("[%s:%d]: emsmdbp_ctx found and released\n", __FUNCTION__, __LINE__)); return true; } /** \details Check if the authenticated user belongs to the Exchange organization and is enabled \param dce_call pointer to the session context \param emsmdbp_ctx pointer to the EMSMDBP context \return true on success, otherwise false */ _PUBLIC_ bool emsmdbp_verify_user(struct dcesrv_call_state *dce_call, struct emsmdbp_context *emsmdbp_ctx) { int ret; const char *username = NULL; int msExchUserAccountControl; struct ldb_result *res = NULL; const char * const recipient_attrs[] = { "msExchUserAccountControl", NULL }; username = dcesrv_call_account_name(dce_call); ret = ldb_search(emsmdbp_ctx->samdb_ctx, emsmdbp_ctx, &res, ldb_get_default_basedn(emsmdbp_ctx->samdb_ctx), LDB_SCOPE_SUBTREE, recipient_attrs, "sAMAccountName=%s", username); /* If the search failed */ if (ret != LDB_SUCCESS || !res->count) { return false; } /* If msExchUserAccountControl attribute is not found */ if (!res->msgs[0]->num_elements) { return false; } /* If the attribute exists check its value */ msExchUserAccountControl = ldb_msg_find_attr_as_int(res->msgs[0], "msExchUserAccountControl", 2); if (msExchUserAccountControl == 2) { return false; } /* Get a copy of the username for later use and setup missing conn_info components */ emsmdbp_ctx->username = talloc_strdup(emsmdbp_ctx, username); openchangedb_get_MailboxReplica(emsmdbp_ctx->oc_ctx, emsmdbp_ctx->username, &emsmdbp_ctx->mstore_ctx->conn_info->repl_id, &emsmdbp_ctx->mstore_ctx->conn_info->replica_guid); return true; } /** \details Check if the user record which legacyExchangeDN points to belongs to the Exchange organization and is enabled \param dce_call pointer to the session context \param emsmdbp_ctx pointer to the EMSMDBP context \param legacyExchangeDN pointer to the userDN to lookup \param msg pointer on pointer to the LDB message matching the record \note Users can set msg to NULL if they do not intend to retrieve the message \return true on success, otherwise false */ _PUBLIC_ bool emsmdbp_verify_userdn(struct dcesrv_call_state *dce_call, struct emsmdbp_context *emsmdbp_ctx, const char *legacyExchangeDN, struct ldb_message **msg) { int ret; int msExchUserAccountControl; struct ldb_result *res = NULL; const char * const recipient_attrs[] = { "*", NULL }; /* Sanity Checks */ if (!legacyExchangeDN) return false; ret = ldb_search(emsmdbp_ctx->samdb_ctx, emsmdbp_ctx, &res, ldb_get_default_basedn(emsmdbp_ctx->samdb_ctx), LDB_SCOPE_SUBTREE, recipient_attrs, "(legacyExchangeDN=%s)", legacyExchangeDN); /* If the search failed */ if (ret != LDB_SUCCESS || !res->count) { return false; } /* Checks msExchUserAccountControl value */ msExchUserAccountControl = ldb_msg_find_attr_as_int(res->msgs[0], "msExchUserAccountControl", 2); if (msExchUserAccountControl == 2) { return false; } if (msg) { *msg = res->msgs[0]; } return true; } /** \details Resolve a recipient and build the associated RecipientRow structure \param mem_ctx pointer to the memory context \param emsmdbp_ctx pointer to the EMSMDBP context \param recipient pointer to the recipient string \param properties array of properties to lookup for a recipient \param row the RecipientRow to fill in \note This is a very preliminary implementation with a lot of pseudo-hardcoded things. Lot of work is required to make this function generic and to cover all different cases \return Allocated RecipientRow on success, otherwise NULL */ _PUBLIC_ enum MAPISTATUS emsmdbp_resolve_recipient(TALLOC_CTX *mem_ctx, struct emsmdbp_context *emsmdbp_ctx, char *recipient, struct mapi_SPropTagArray *properties, struct RecipientRow *row) { enum MAPISTATUS retval; struct ldb_result *res = NULL; const char * const recipient_attrs[] = { "*", NULL }; int ret; uint32_t i; uint32_t property = 0; void *data; char *str; char *username; char *legacyExchangeDN; uint32_t org_length; uint32_t l; /* Sanity checks */ OPENCHANGE_RETVAL_IF(!mem_ctx, MAPI_E_NOT_INITIALIZED, NULL); OPENCHANGE_RETVAL_IF(!emsmdbp_ctx, MAPI_E_NOT_INITIALIZED, NULL); OPENCHANGE_RETVAL_IF(!emsmdbp_ctx->samdb_ctx, MAPI_E_NOT_INITIALIZED, NULL); OPENCHANGE_RETVAL_IF(!properties, MAPI_E_INVALID_PARAMETER, NULL); OPENCHANGE_RETVAL_IF(!recipient, MAPI_E_INVALID_PARAMETER, NULL); OPENCHANGE_RETVAL_IF(!row, MAPI_E_INVALID_PARAMETER, NULL); ret = ldb_search(emsmdbp_ctx->samdb_ctx, emsmdbp_ctx, &res, ldb_get_default_basedn(emsmdbp_ctx->samdb_ctx), LDB_SCOPE_SUBTREE, recipient_attrs, "(&(objectClass=user)(sAMAccountName=*%s*)(!(objectClass=computer)))", recipient); /* If the search failed, build an external recipient: very basic for the moment */ if (ret != LDB_SUCCESS || !res->count) { failure: row->RecipientFlags = 0x07db; row->EmailAddress.lpszW = talloc_strdup(mem_ctx, recipient); row->DisplayName.lpszW = talloc_strdup(mem_ctx, recipient); row->SimpleDisplayName.lpszW = talloc_strdup(mem_ctx, recipient); row->prop_count = properties->cValues; row->layout = 0x1; row->prop_values.length = 0; for (i = 0; i < properties->cValues; i++) { switch (properties->aulPropTag[i]) { case PidTagSmtpAddress: property = properties->aulPropTag[i]; data = (void *) recipient; break; default: retval = MAPI_E_NOT_FOUND; property = (properties->aulPropTag[i] & 0xFFFF0000) + PT_ERROR; data = (void *)&retval; break; } libmapiserver_push_property(mem_ctx, property, (const void *)data, &row->prop_values, row->layout, 0, 0); } return MAPI_E_SUCCESS; } /* Otherwise build a RecipientRow for resolved username */ username = (char *) ldb_msg_find_attr_as_string(res->msgs[0], "mailNickname", NULL); legacyExchangeDN = (char *) ldb_msg_find_attr_as_string(res->msgs[0], "legacyExchangeDN", NULL); if (!username || !legacyExchangeDN) { DEBUG(0, ("record found but mailNickname or legacyExchangeDN is missing for %s\n", recipient)); goto failure; } org_length = strlen(legacyExchangeDN) - strlen(username); /* Check if we need a flagged blob */ row->layout = 0; for (i = 0; i < properties->cValues; i++) { switch (properties->aulPropTag[i]) { case PR_DISPLAY_TYPE: case PR_OBJECT_TYPE: case PidTagAddressBookDisplayNamePrintable: case PidTagSmtpAddress: break; default: row->layout = 1; break; } } row->RecipientFlags = 0x06d1; row->AddressPrefixUsed.prefix_size = org_length; row->DisplayType.display_type = SINGLE_RECIPIENT; row->X500DN.recipient_x500name = talloc_strdup(mem_ctx, username); row->DisplayName.lpszW = talloc_strdup(mem_ctx, username); row->SimpleDisplayName.lpszW = talloc_strdup(mem_ctx, username); row->prop_count = properties->cValues; row->prop_values.length = 0; /* Add this very small set of properties */ for (i = 0; i < properties->cValues; i++) { switch (properties->aulPropTag[i]) { case PR_DISPLAY_TYPE: property = properties->aulPropTag[i]; l = 0x0; data = (void *)&l; break; case PR_OBJECT_TYPE: property = properties->aulPropTag[i]; l = MAPI_MAILUSER; data = (void *)&l; break; case PidTagAddressBookDisplayNamePrintable: property = properties->aulPropTag[i]; str = (char *) ldb_msg_find_attr_as_string(res->msgs[0], "mailNickname", NULL); data = (void *) str; break; case PidTagSmtpAddress: property = properties->aulPropTag[i]; str = (char *) ldb_msg_find_attr_as_string(res->msgs[0], "legacyExchangeDN", NULL); data = (void *) str; break; default: retval = MAPI_E_NOT_FOUND; property = (properties->aulPropTag[i] & 0xFFFF0000) + PT_ERROR; data = (void *)&retval; break; } libmapiserver_push_property(mem_ctx, property, (const void *)data, &row->prop_values, row->layout, 0, 0); } return MAPI_E_SUCCESS; } _PUBLIC_ int emsmdbp_guid_to_replid(struct emsmdbp_context *emsmdbp_ctx, const char *username, const struct GUID *guidP, uint16_t *replidP) { uint16_t replid; struct GUID guid; if (GUID_equal(guidP, MagicGUIDp)) { *replidP = 2; return MAPI_E_SUCCESS; } openchangedb_get_MailboxReplica(emsmdbp_ctx->oc_ctx, username, &replid, &guid); if (GUID_equal(guidP, &guid)) { *replidP = replid; return MAPI_E_SUCCESS; } if (mapistore_replica_mapping_guid_to_replid(emsmdbp_ctx->mstore_ctx, username, guidP, &replid) == MAPISTORE_SUCCESS) { *replidP = replid; return MAPI_E_SUCCESS; } return MAPI_E_NOT_FOUND; } _PUBLIC_ int emsmdbp_replid_to_guid(struct emsmdbp_context *emsmdbp_ctx, const char *username, const uint16_t replid, struct GUID *guidP) { uint16_t db_replid; struct GUID guid; if (replid == 2) { *guidP = MagicGUID; return MAPI_E_SUCCESS; } openchangedb_get_MailboxReplica(emsmdbp_ctx->oc_ctx, username, &db_replid, &guid); if (replid == db_replid) { *guidP = guid; return MAPI_E_SUCCESS; } if (mapistore_replica_mapping_replid_to_guid(emsmdbp_ctx->mstore_ctx, username, replid, &guid) == MAPISTORE_SUCCESS) { *guidP = guid; return MAPI_E_SUCCESS; } return MAPI_E_NOT_FOUND; } _PUBLIC_ int emsmdbp_source_key_from_fmid(TALLOC_CTX *mem_ctx, struct emsmdbp_context *emsmdbp_ctx, const char *username, uint64_t fmid, struct Binary_r **source_keyP) { struct Binary_r *source_key; uint64_t gc; uint16_t replid; uint8_t *bytes; int i; replid = fmid & 0xffff; source_key = talloc_zero(NULL, struct Binary_r); source_key->cb = 22; source_key->lpb = talloc_array(source_key, uint8_t, source_key->cb); if (emsmdbp_replid_to_guid(emsmdbp_ctx, username, replid, (struct GUID *) source_key->lpb)) { talloc_free(source_key); return MAPISTORE_ERROR; } (void) talloc_reference(mem_ctx, source_key); talloc_unlink(NULL, source_key); gc = fmid >> 16; bytes = source_key->lpb + 16; for (i = 0; i < 6; i++) { bytes[i] = gc & 0xff; gc >>= 8; } *source_keyP = source_key; return MAPISTORE_SUCCESS; } openchange-2.0/mapiproxy/servers/default/emsmdb/emsmdbp_object.c000066400000000000000000003144231223057412600252300ustar00rootroot00000000000000/* OpenChange Server implementation EMSMDBP: EMSMDB Provider implementation Copyright (C) Julien Kerihuel 2009-2013 This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see . */ /** \file emsmdbp_object.c \brief Server-side specific objects init/release routines */ #include #include #include "mapiproxy/dcesrv_mapiproxy.h" #include "mapiproxy/libmapiproxy/libmapiproxy.h" #include "mapiproxy/libmapiserver/libmapiserver.h" #include "mapiproxy/libmapistore/mapistore_nameid.h" #include "libmapi/property_tags.h" #include "libmapi/property_altnames.h" #include "dcesrv_exchange_emsmdb.h" const char *emsmdbp_getstr_type(struct emsmdbp_object *object) { switch (object->type) { case EMSMDBP_OBJECT_UNDEF: return "undefined"; case EMSMDBP_OBJECT_MAILBOX: return "mailbox"; case EMSMDBP_OBJECT_FOLDER: return "folder"; case EMSMDBP_OBJECT_MESSAGE: return "message"; case EMSMDBP_OBJECT_TABLE: return "table"; case EMSMDBP_OBJECT_STREAM: return "stream"; case EMSMDBP_OBJECT_ATTACHMENT: return "attachment"; case EMSMDBP_OBJECT_SUBSCRIPTION: return "subscription"; case EMSMDBP_OBJECT_SYNCCONTEXT: return "synccontext"; case EMSMDBP_OBJECT_FTCONTEXT: return "ftcontext"; default: return "unknown"; } } /** \details Convenient function to determine whether specified object is using mapistore or not \param object pointer to the emsmdp object \return true if parent is using mapistore, otherwise false */ bool emsmdbp_is_mapistore(struct emsmdbp_object *object) { /* Sanity checks - probably pointless */ if (!object) { return false; } switch (object->type) { case EMSMDBP_OBJECT_MAILBOX: return false; case EMSMDBP_OBJECT_FOLDER: if (object->object.folder->mapistore_root) { return true; } default: if (object->parent_object) { return emsmdbp_is_mapistore(object->parent_object); } } return false; } static struct emsmdbp_object *emsmdbp_get_mailbox(struct emsmdbp_object *object) { if (object->type == EMSMDBP_OBJECT_MAILBOX) { return object; } return emsmdbp_get_mailbox(object->parent_object); } /** \details Convenient function to determine whether specified mapi_handles refers to object within mailbox or public folders store. \param object pointer to the emsmdp object \return true if parent is within mailbox store, otherwise false */ bool emsmdbp_is_mailboxstore(struct emsmdbp_object *object) { struct emsmdbp_object *mailbox = emsmdbp_get_mailbox(object); return mailbox->object.mailbox->mailboxstore; } /** \details Convenience function to determine the owner of an object \param object pointer to the emsmdp object \return true if parent is within mailbox store, otherwise false */ char *emsmdbp_get_owner(struct emsmdbp_object *object) { struct emsmdbp_object *mailbox; mailbox = emsmdbp_get_mailbox(object); return mailbox->object.mailbox->owner_username; } /** \details Return the contextID associated to a handle \param object pointer to the emsmdp object \return contextID value on success, otherwise -1 */ _PUBLIC_ uint32_t emsmdbp_get_contextID(struct emsmdbp_object *object) { switch (object->type) { case EMSMDBP_OBJECT_MAILBOX: return -1; case EMSMDBP_OBJECT_FOLDER: if (object->object.folder->mapistore_root) { return object->object.folder->contextID; } else if (object->parent_object) { return emsmdbp_get_contextID(object->parent_object); } break; default: if (object->parent_object) { return emsmdbp_get_contextID(object->parent_object); } } return -1; } _PUBLIC_ enum mapistore_error emsmdbp_object_get_fid_by_name(struct emsmdbp_context *emsmdbp_ctx, struct emsmdbp_object *parent_folder, const char *name, uint64_t *fidp) { uint64_t folderID; if (!emsmdbp_ctx) return MAPISTORE_ERROR; if (!parent_folder) return MAPISTORE_ERROR; if (!name) return MAPISTORE_ERROR; if (!fidp) return MAPISTORE_ERROR; if (parent_folder->type == EMSMDBP_OBJECT_FOLDER) { folderID = parent_folder->object.folder->folderID; } else if (parent_folder->type == EMSMDBP_OBJECT_MAILBOX) { folderID = parent_folder->object.mailbox->folderID; } else { return MAPISTORE_ERROR; } if (emsmdbp_is_mapistore(parent_folder)) { if (mapistore_folder_get_child_fid_by_name(emsmdbp_ctx->mstore_ctx, emsmdbp_get_contextID(parent_folder), parent_folder->backend_object, name, fidp)) { return MAPISTORE_ERR_NOT_FOUND; } return MAPISTORE_SUCCESS; } else { return openchangedb_get_fid_by_name(emsmdbp_ctx->oc_ctx, folderID, name, fidp); } } static enum mapistore_context_role emsmdbp_container_class_to_role(const char *container_class) { enum mapistore_context_role i, role = MAPISTORE_FALLBACK_ROLE; static const char **container_classes = NULL; bool found = false; if (!container_classes) { container_classes = talloc_array(NULL, const char *, MAPISTORE_MAX_ROLES); for (i = MAPISTORE_MAIL_ROLE; i < MAPISTORE_MAX_ROLES; i++) { container_classes[i] = "IPF.Note"; } container_classes[MAPISTORE_CALENDAR_ROLE] = "IPF.Appointment"; container_classes[MAPISTORE_CONTACTS_ROLE] = "IPF.Contact"; container_classes[MAPISTORE_TASKS_ROLE] = "IPF.Task"; container_classes[MAPISTORE_NOTES_ROLE] = "IPF.StickyNote"; container_classes[MAPISTORE_JOURNAL_ROLE] = "IPF.Journal"; container_classes[MAPISTORE_FALLBACK_ROLE] = ""; } if (container_class) { for (i = 0; !found && i < MAPISTORE_MAX_ROLES; i++) { if (strcmp(container_class, container_classes[i]) == 0) { role = i; found = true; } } } return role; } static enum mapistore_error emsmdbp_object_folder_commit_creation(struct emsmdbp_context *emsmdbp_ctx, struct emsmdbp_object *new_folder, bool force_container_class) { enum mapistore_error ret = MAPISTORE_SUCCESS; enum MAPISTATUS retval; struct SPropValue *value; char *mapistore_uri, *owner; enum mapistore_context_role role; TALLOC_CTX *mem_ctx; uint64_t parent_fid, fid; uint32_t context_id; if (!new_folder->object.folder->postponed_props) { return ret; } mem_ctx = talloc_zero(NULL, TALLOC_CTX); value = get_SPropValue_SRow(new_folder->object.folder->postponed_props, PR_CONTAINER_CLASS_UNICODE); if (!value) { /* Sometimes Outlook does pass non-unicode values. */ value = get_SPropValue_SRow(new_folder->object.folder->postponed_props, PR_CONTAINER_CLASS); } if (value) { role = emsmdbp_container_class_to_role(value->value.lpszW); } else if (force_container_class) { DEBUG(5, (__location__": forcing folder backend role to 'fallback'\n")); role = MAPISTORE_FALLBACK_ROLE; } else { DEBUG(5, (__location__": container class not set yet\n")); goto end; } value = get_SPropValue_SRow(new_folder->object.folder->postponed_props, PR_DISPLAY_NAME_UNICODE); if (!value) { DEBUG(5, (__location__": display name not set yet\n")); goto end; } fid = new_folder->object.folder->folderID; owner = emsmdbp_get_owner(new_folder); ret = mapistore_create_root_folder(owner, role, fid, value->value.lpszW, mem_ctx, &mapistore_uri); if (ret != MAPISTORE_SUCCESS) { goto end; } ret = mapistore_add_context(emsmdbp_ctx->mstore_ctx, owner, mapistore_uri, fid, &context_id, &new_folder->backend_object); if (ret != MAPISTORE_SUCCESS) { abort(); } new_folder->object.folder->contextID = context_id; if (new_folder->parent_object->type == EMSMDBP_OBJECT_MAILBOX) { parent_fid = new_folder->parent_object->object.mailbox->folderID; } else { /* EMSMDBP_OBJECT_FOLDER */ parent_fid = new_folder->parent_object->object.folder->folderID; } value = get_SPropValue_SRow(new_folder->object.folder->postponed_props, PidTagChangeNumber); retval = openchangedb_create_folder(emsmdbp_ctx->oc_ctx, parent_fid, fid, value->value.d, mapistore_uri, -1); if (retval != MAPI_E_SUCCESS) { if (retval == MAPI_E_COLLISION) { ret = MAPISTORE_ERR_EXIST; } else { ret = MAPISTORE_ERR_NOT_FOUND; } DEBUG(0, (__location__": openchangedb folder creation failed: 0x%.8x\n", retval)); goto end; } mapistore_indexing_record_add_fid(emsmdbp_ctx->mstore_ctx, context_id, owner, fid); new_folder->object.folder->contextID = context_id; openchangedb_set_folder_properties(emsmdbp_ctx->oc_ctx, fid, new_folder->object.folder->postponed_props); mapistore_properties_set_properties(emsmdbp_ctx->mstore_ctx, context_id, new_folder->backend_object, new_folder->object.folder->postponed_props); talloc_unlink(new_folder, new_folder->object.folder->postponed_props); new_folder->object.folder->postponed_props = NULL; DEBUG(5, ("new mapistore context created at uri: %s\n", mapistore_uri)); end: talloc_free(mem_ctx); return ret; } _PUBLIC_ enum MAPISTATUS emsmdbp_object_create_folder(struct emsmdbp_context *emsmdbp_ctx, struct emsmdbp_object *parent_folder, TALLOC_CTX *mem_ctx, uint64_t fid, struct SRow *rowp, struct emsmdbp_object **new_folderp) { uint64_t parentFolderID, testFolderID; struct SPropValue *value; int retval; struct emsmdbp_object *new_folder; struct SRow *postponed_props; /* Sanity checks */ if (!emsmdbp_ctx) return MAPISTORE_ERROR; if (!parent_folder) return MAPISTORE_ERROR; if (!rowp) return MAPISTORE_ERROR; new_folder = emsmdbp_object_folder_init(mem_ctx, emsmdbp_ctx, fid, parent_folder); if (emsmdbp_is_mapistore(parent_folder)) { retval = mapistore_folder_create_folder(emsmdbp_ctx->mstore_ctx, emsmdbp_get_contextID(parent_folder), parent_folder->backend_object, new_folder, fid, rowp, &new_folder->backend_object); if (retval != MAPISTORE_SUCCESS) { talloc_free(new_folder); return mapistore_error_to_mapi(retval); } } else { parentFolderID = parent_folder->object.folder->folderID; value = get_SPropValue_SRow(rowp, PR_DISPLAY_NAME_UNICODE); if (!value) { value = get_SPropValue_SRow(rowp, PR_DISPLAY_NAME); } if (!value) { talloc_free(new_folder); return MAPI_E_INVALID_PARAMETER; } if (openchangedb_get_fid_by_name(emsmdbp_ctx->oc_ctx, parentFolderID, value->value.lpszW, &testFolderID) == MAPI_E_SUCCESS) { /* this folder already exists */ DEBUG(4, ("emsmdbp_object: CreateFolder Duplicate Folder error\n")); talloc_free(new_folder); return MAPI_E_COLLISION; } value = get_SPropValue_SRow(rowp, PidTagChangeNumber); if (value) { postponed_props = talloc_zero(new_folder, struct SRow); postponed_props->cValues = rowp->cValues; postponed_props->lpProps = talloc_array(postponed_props, struct SPropValue, rowp->cValues); mapi_copy_spropvalues(postponed_props->lpProps, rowp->lpProps, postponed_props->lpProps, rowp->cValues); new_folder->object.folder->postponed_props = postponed_props; new_folder->object.folder->mapistore_root = true; emsmdbp_object_folder_commit_creation(emsmdbp_ctx, new_folder, false); } else { DEBUG(0, (__location__": PidTagChangeNumber *must* be present\n")); abort(); } } *new_folderp = new_folder; return MAPI_E_SUCCESS; } _PUBLIC_ enum mapistore_error emsmdbp_object_open_folder(TALLOC_CTX *mem_ctx, struct emsmdbp_context *emsmdbp_ctx, struct emsmdbp_object *parent, uint64_t fid, struct emsmdbp_object **folder_object_p) { struct emsmdbp_object *folder_object, *mailbox_object; enum mapistore_error retval; enum MAPISTATUS ret; char *path; char *owner; uint32_t contextID; uint64_t parent_fid, oc_parent_fid; void *local_ctx; folder_object = emsmdbp_object_folder_init(mem_ctx, emsmdbp_ctx, fid, parent); if (emsmdbp_is_mapistore(parent)) { DEBUG(0, ("%s: opening child mapistore folder\n", __FUNCTION__)); retval = mapistore_folder_open_folder(emsmdbp_ctx->mstore_ctx, emsmdbp_get_contextID(parent), parent->backend_object, folder_object, fid, &folder_object->backend_object); if (retval != MAPISTORE_SUCCESS) { talloc_free(folder_object); return retval; } } else { local_ctx = talloc_zero(NULL, void); retval = openchangedb_get_mapistoreURI(local_ctx, emsmdbp_ctx->oc_ctx, fid, &path, true); if (retval == MAPISTORE_SUCCESS && path) { folder_object->object.folder->mapistore_root = true; /* system/special folder */ DEBUG(0, ("%s: opening base mapistore folder\n", __FUNCTION__)); retval = mapistore_search_context_by_uri(emsmdbp_ctx->mstore_ctx, path, &contextID, &folder_object->backend_object); if (retval == MAPISTORE_SUCCESS) { retval = mapistore_add_context_ref_count(emsmdbp_ctx->mstore_ctx, contextID); } else { owner = emsmdbp_get_owner(folder_object); retval = mapistore_add_context(emsmdbp_ctx->mstore_ctx, owner, path, folder_object->object.folder->folderID, &contextID, &folder_object->backend_object); if (retval != MAPISTORE_SUCCESS) { talloc_free(local_ctx); talloc_free(folder_object); return retval; } mapistore_indexing_record_add_fid(emsmdbp_ctx->mstore_ctx, contextID, owner, fid); } folder_object->object.folder->contextID = contextID; /* (void) talloc_reference(folder_object, folder_object->backend_object); */ } else { switch (parent->type) { case EMSMDBP_OBJECT_MAILBOX: parent_fid = parent->object.mailbox->folderID; break; case EMSMDBP_OBJECT_FOLDER: parent_fid = parent->object.folder->folderID; break; default: DEBUG(5, ("you should never get here\n")); abort(); } mailbox_object = emsmdbp_get_mailbox(parent); ret = openchangedb_get_parent_fid(emsmdbp_ctx->oc_ctx, fid, &oc_parent_fid, mailbox_object->object.mailbox->mailboxstore); if (ret != MAPI_E_SUCCESS) { DEBUG(0, ("folder %.16"PRIx64" or %.16"PRIx64" does not exist\n", parent_fid, fid)); talloc_free(local_ctx); talloc_free(folder_object); return MAPISTORE_ERR_NOT_FOUND; } if (oc_parent_fid != parent_fid) { DEBUG(0, ("parent folder mismatch: expected %.16"PRIx64" but got %.16"PRIx64"\n", parent_fid, oc_parent_fid)); talloc_free(local_ctx); talloc_free(folder_object); return MAPISTORE_ERR_NOT_FOUND; } DEBUG(0, ("%s: opening openchangedb folder\n", __FUNCTION__)); } talloc_free(local_ctx); } *folder_object_p = folder_object; return MAPISTORE_SUCCESS; } _PUBLIC_ int emsmdbp_get_uri_from_fid(TALLOC_CTX *mem_ctx, struct emsmdbp_context *emsmdbp_ctx, uint64_t fid, char **urip) { enum MAPISTATUS retval; bool soft_deleted; retval = openchangedb_get_mapistoreURI(mem_ctx, emsmdbp_ctx->oc_ctx, fid, urip, true); /* FIXME: always mailboxstore */ if (retval == MAPI_E_SUCCESS) { return MAPISTORE_SUCCESS; } return mapistore_indexing_record_get_uri(emsmdbp_ctx->mstore_ctx, emsmdbp_ctx->username, mem_ctx, fid, urip, &soft_deleted); } _PUBLIC_ int emsmdbp_get_fid_from_uri(struct emsmdbp_context *emsmdbp_ctx, const char *uri, uint64_t *fidp) { int ret; bool soft_deleted; ret = openchangedb_get_fid(emsmdbp_ctx->oc_ctx, uri, fidp); if (ret != MAPI_E_SUCCESS) { ret = (int) mapistore_indexing_record_get_fmid(emsmdbp_ctx->mstore_ctx, emsmdbp_ctx->username, uri, false, fidp, &soft_deleted); } return ret; } static char *emsmdbp_compute_parent_uri(TALLOC_CTX *mem_ctx, char *uri) { char *parent_uri, *slash, *lastchar; int len; if (!uri) return NULL; parent_uri = talloc_strdup(mem_ctx, uri); len = strlen(parent_uri); lastchar = parent_uri + len - 1; if (*lastchar == '/') { *lastchar = 0; } slash = strrchr(parent_uri, '/'); if (slash) { *(slash + 1) = 0; } else { talloc_free(parent_uri); parent_uri = NULL; } return parent_uri; } static int emsmdbp_get_parent_fid(struct emsmdbp_context *emsmdbp_ctx, uint64_t fid, uint64_t *parent_fidp) { TALLOC_CTX *mem_ctx; int retval = MAPISTORE_SUCCESS; bool soft_deleted; char *uri, *parent_uri; mem_ctx = talloc_zero(NULL, void); retval = openchangedb_get_parent_fid(emsmdbp_ctx->oc_ctx, fid, parent_fidp, true); if (retval == MAPISTORE_SUCCESS) { goto end; } retval = openchangedb_get_parent_fid(emsmdbp_ctx->oc_ctx, fid, parent_fidp, false); if (retval == MAPISTORE_SUCCESS) { goto end; } retval = mapistore_indexing_record_get_uri(emsmdbp_ctx->mstore_ctx, emsmdbp_ctx->username, mem_ctx, fid, &uri, &soft_deleted); if (retval == MAPISTORE_SUCCESS) { parent_uri = emsmdbp_compute_parent_uri(mem_ctx, uri); if (parent_uri) { retval = emsmdbp_get_fid_from_uri(emsmdbp_ctx, parent_uri, parent_fidp); } else { retval = MAPISTORE_ERR_NOT_FOUND; } } end: talloc_free(mem_ctx); return retval; } /** \details Return the folder object associated to specified folder identified \param mem_ctx pointer to the memory context \param emsmdbp_ctx pointer to the emsmdbp context \param context_object pointer to current context object \param fid pointer to the Folder Identifier to lookup \return Valid emsmdbp object structure on success, otherwise NULL */ _PUBLIC_ enum mapistore_error emsmdbp_object_open_folder_by_fid(TALLOC_CTX *mem_ctx, struct emsmdbp_context *emsmdbp_ctx, struct emsmdbp_object *context_object, uint64_t fid, struct emsmdbp_object **folder_object_p) { uint64_t parent_fid; int retval; struct emsmdbp_object *parent_object; if ((context_object->type == EMSMDBP_OBJECT_MAILBOX && fid == context_object->object.mailbox->folderID) || (context_object->type == EMSMDBP_OBJECT_FOLDER && fid == context_object->object.folder->folderID)) { *folder_object_p = context_object; return MAPISTORE_SUCCESS; } else { parent_object = emsmdbp_get_mailbox(context_object); if (fid == parent_object->object.mailbox->folderID) { *folder_object_p = parent_object; return MAPISTORE_SUCCESS; } } retval = emsmdbp_get_parent_fid(emsmdbp_ctx, fid, &parent_fid); if (retval == MAPISTORE_SUCCESS) { if (parent_fid) { retval = emsmdbp_object_open_folder_by_fid(mem_ctx, emsmdbp_ctx, context_object, parent_fid, &parent_object); if (retval != MAPISTORE_SUCCESS) { return retval; } return emsmdbp_object_open_folder(mem_ctx, emsmdbp_ctx, parent_object, fid, folder_object_p); } else { *folder_object_p = emsmdbp_object_folder_init(mem_ctx, emsmdbp_ctx, fid, NULL); return MAPISTORE_SUCCESS; } } return MAPISTORE_ERROR; } _PUBLIC_ int emsmdbp_object_stream_commit(struct emsmdbp_object *stream_object) { int rc; struct emsmdbp_object_stream *stream; void *stream_data; uint8_t *utf8_buffer; struct Binary_r *binary_data; struct SRow aRow; size_t converted_size; uint16_t propType; if (!stream_object || stream_object->type != EMSMDBP_OBJECT_STREAM) return MAPISTORE_ERROR; stream = stream_object->object.stream; rc = MAPISTORE_SUCCESS; if (stream->needs_commit) { stream->needs_commit = false; aRow.cValues = 1; aRow.lpProps = talloc_zero(NULL, struct SPropValue); propType = stream->property & 0xffff; if (propType == PT_BINARY) { binary_data = talloc(aRow.lpProps, struct Binary_r); binary_data->cb = stream->stream.buffer.length; binary_data->lpb = stream->stream.buffer.data; stream_data = binary_data; } else if (propType == PT_STRING8) { stream_data = stream->stream.buffer.data; } else { /* PT_UNICODE */ utf8_buffer = talloc_array(aRow.lpProps, uint8_t, stream->stream.buffer.length + 2); convert_string(CH_UTF16LE, CH_UTF8, stream->stream.buffer.data, stream->stream.buffer.length, utf8_buffer, stream->stream.buffer.length, &converted_size); utf8_buffer[converted_size] = 0; stream_data = utf8_buffer; } set_SPropValue_proptag(aRow.lpProps, stream->property, stream_data); emsmdbp_object_set_properties(stream_object->emsmdbp_ctx, stream_object->parent_object, &aRow); talloc_free(aRow.lpProps); } return rc; } /** \details talloc destructor for emsmdbp_objects \param data generic pointer on data \return 0 on success, otherwise -1 */ static int emsmdbp_object_destructor(void *data) { struct emsmdbp_object *object = (struct emsmdbp_object *) data; int ret = MAPISTORE_SUCCESS; uint32_t contextID; unsigned int missing_objects; struct timeval request_end, request_delta; if (!data) return -1; if (!emsmdbp_is_mapistore(object)) goto nomapistore; DEBUG(4, ("[%s:%d]: emsmdbp %s object released\n", __FUNCTION__, __LINE__, emsmdbp_getstr_type(object))); contextID = emsmdbp_get_contextID(object); switch (object->type) { case EMSMDBP_OBJECT_FOLDER: if (object->object.folder->mapistore_root) { ret = mapistore_del_context(object->emsmdbp_ctx->mstore_ctx, contextID); } DEBUG(4, ("[%s:%d] mapistore folder context retval = %d\n", __FUNCTION__, __LINE__, ret)); break; case EMSMDBP_OBJECT_TABLE: if (emsmdbp_is_mapistore(object) && object->backend_object && object->object.table->handle > 0) { mapistore_table_handle_destructor(object->emsmdbp_ctx->mstore_ctx, emsmdbp_get_contextID(object), object->backend_object, object->object.table->handle); } if (object->object.table->subscription_list) { DLIST_REMOVE(object->emsmdbp_ctx->mstore_ctx->subscriptions, object->object.table->subscription_list); talloc_free(object->object.table->subscription_list); /* talloc_unlink(object->emsmdbp_ctx, object->object.table->subscription_list); */ } break; case EMSMDBP_OBJECT_STREAM: emsmdbp_object_stream_commit(object); break; case EMSMDBP_OBJECT_SUBSCRIPTION: if (object->object.subscription->subscription_list) { DLIST_REMOVE(object->emsmdbp_ctx->mstore_ctx->subscriptions, object->object.subscription->subscription_list); talloc_free(object->object.subscription->subscription_list); } break; case EMSMDBP_OBJECT_SYNCCONTEXT: gettimeofday(&request_end, NULL); request_delta.tv_sec = request_end.tv_sec - object->object.synccontext->request_start.tv_sec; if (request_end.tv_usec < object->object.synccontext->request_start.tv_usec) { request_delta.tv_sec--; request_delta.tv_usec = 1000000 + request_end.tv_usec - object->object.synccontext->request_start.tv_usec; } else { request_delta.tv_usec = request_end.tv_usec - object->object.synccontext->request_start.tv_usec; } missing_objects = (object->object.synccontext->total_objects - object->object.synccontext->skipped_objects - object->object.synccontext->sent_objects); DEBUG(5, ("free synccontext: sent: %u, skipped: %u, total: %u -> missing: %u\n", object->object.synccontext->sent_objects, object->object.synccontext->skipped_objects, object->object.synccontext->total_objects, missing_objects)); DEBUG(5, (" time taken for transmitting entire data: %lu.%.6lu\n", request_delta.tv_sec, request_delta.tv_usec)); break; case EMSMDBP_OBJECT_UNDEF: case EMSMDBP_OBJECT_MAILBOX: case EMSMDBP_OBJECT_MESSAGE: case EMSMDBP_OBJECT_ATTACHMENT: case EMSMDBP_OBJECT_FTCONTEXT: break; } nomapistore: talloc_unlink(object, object->parent_object); return 0; } /** \details Initialize an emsmdbp_object \param mem_ctx pointer to the memory context \param emsmdbp_ctx pointer to the emsmdb provider context \return Allocated emsmdbp object on success, otherwise NULL */ _PUBLIC_ struct emsmdbp_object *emsmdbp_object_init(TALLOC_CTX *mem_ctx, struct emsmdbp_context *emsmdbp_ctx, struct emsmdbp_object *parent_object) { struct emsmdbp_object *object = NULL; object = talloc_zero(mem_ctx, struct emsmdbp_object); if (!object) return NULL; talloc_set_destructor((void *)object, (int (*)(void *))emsmdbp_object_destructor); object->type = EMSMDBP_OBJECT_UNDEF; object->emsmdbp_ctx = emsmdbp_ctx; object->object.mailbox = NULL; object->object.folder = NULL; object->object.message = NULL; object->object.stream = NULL; object->backend_object = NULL; object->parent_object = parent_object; (void) talloc_reference(object, parent_object); object->stream_data = NULL; return object; } static int emsmdbp_copy_properties(struct emsmdbp_context *emsmdbp_ctx, struct emsmdbp_object *source_object, struct emsmdbp_object *dest_object, struct SPropTagArray *excluded_tags) { TALLOC_CTX *mem_ctx; bool properties_exclusion[65536]; struct SPropTagArray *properties, *needed_properties; void **data_pointers; enum MAPISTATUS *retvals = NULL; struct SRow *aRow; struct SPropValue newValue; uint32_t i; mem_ctx = talloc_zero(NULL, TALLOC_CTX); if (emsmdbp_object_get_available_properties(mem_ctx, emsmdbp_ctx, source_object, &properties) == MAPISTORE_ERROR) { DEBUG(0, ("["__location__"] - mapistore support not implemented yet - shouldn't occur\n")); talloc_free(mem_ctx); return MAPI_E_NO_SUPPORT; } /* 1. Exclusions */ memset(properties_exclusion, 0, 65536 * sizeof(bool)); /* 1a. Explicit exclusions */ properties_exclusion[(uint16_t) (PidTagRowType >> 16)] = true; properties_exclusion[(uint16_t) (PidTagInstanceKey >> 16)] = true; properties_exclusion[(uint16_t) (PidTagInstanceNum >> 16)] = true; properties_exclusion[(uint16_t) (PidTagInstID >> 16)] = true; properties_exclusion[(uint16_t) (PidTagFolderId >> 16)] = true; properties_exclusion[(uint16_t) (PidTagMid >> 16)] = true; properties_exclusion[(uint16_t) (PidTagSourceKey >> 16)] = true; properties_exclusion[(uint16_t) (PidTagParentSourceKey >> 16)] = true; properties_exclusion[(uint16_t) (PidTagParentFolderId >> 16)] = true; properties_exclusion[(uint16_t) (PidTagChangeNumber >> 16)] = true; properties_exclusion[(uint16_t) (PidTagChangeKey >> 16)] = true; properties_exclusion[(uint16_t) (PidTagPredecessorChangeList >> 16)] = true; /* 1b. Request exclusions */ if (excluded_tags != NULL) { for (i = 0; i < excluded_tags->cValues; i++) { properties_exclusion[(uint16_t) (excluded_tags->aulPropTag[i] >> 16)] = true; } } needed_properties = talloc_zero(mem_ctx, struct SPropTagArray); needed_properties->aulPropTag = talloc_zero(needed_properties, void); for (i = 0; i < properties->cValues; i++) { if (!properties_exclusion[(uint16_t) (properties->aulPropTag[i] >> 16)]) { SPropTagArray_add(mem_ctx, needed_properties, properties->aulPropTag[i]); } } data_pointers = emsmdbp_object_get_properties(mem_ctx, emsmdbp_ctx, source_object, needed_properties, &retvals); if (data_pointers) { aRow = talloc_zero(mem_ctx, struct SRow); for (i = 0; i < needed_properties->cValues; i++) { if (retvals[i] == MAPI_E_SUCCESS) { /* _PUBLIC_ enum MAPISTATUS SRow_addprop(struct SRow *aRow, struct SPropValue spropvalue) */ set_SPropValue_proptag(&newValue, needed_properties->aulPropTag[i], data_pointers[i]); SRow_addprop(aRow, newValue); } } if (emsmdbp_object_set_properties(emsmdbp_ctx, dest_object, aRow) != MAPISTORE_SUCCESS) { talloc_free(mem_ctx); return MAPI_E_NO_SUPPORT; } } else { talloc_free(mem_ctx); return MAPI_E_NO_SUPPORT; } talloc_free(mem_ctx); return MAPI_E_SUCCESS; } /* FIXME: this function is already present in oxcmsg... */ struct emsmdbp_prop_index { uint32_t display_name; /* PR_DISPLAY_NAME_UNICODE or PR_7BIT_DISPLAY_NAME_UNICODE or PR_RECIPIENT_DISPLAY_NAME_UNICODE */ uint32_t email_address; /* PR_EMAIL_ADDRESS_UNICODE or PR_SMTP_ADDRESS_UNICODE */ }; static inline void emsmdbp_fill_prop_index(struct emsmdbp_prop_index *prop_index, struct SPropTagArray *properties) { if (SPropTagArray_find(*properties, PR_DISPLAY_NAME_UNICODE, &prop_index->display_name) == MAPI_E_NOT_FOUND && SPropTagArray_find(*properties, PR_7BIT_DISPLAY_NAME_UNICODE, &prop_index->display_name) == MAPI_E_NOT_FOUND && SPropTagArray_find(*properties, PR_RECIPIENT_DISPLAY_NAME_UNICODE, &prop_index->display_name) == MAPI_E_NOT_FOUND) { prop_index->display_name = (uint32_t) -1; } if (SPropTagArray_find(*properties, PR_EMAIL_ADDRESS_UNICODE, &prop_index->email_address) == MAPI_E_NOT_FOUND && SPropTagArray_find(*properties, PR_SMTP_ADDRESS_UNICODE, &prop_index->email_address) == MAPI_E_NOT_FOUND) { prop_index->email_address = (uint32_t) -1; } } static inline int emsmdbp_copy_message_recipients_mapistore(struct emsmdbp_context *emsmdbp_ctx, struct emsmdbp_object *source_object, struct emsmdbp_object *dest_object) { TALLOC_CTX *mem_ctx; struct mapistore_message *msg_data; uint32_t contextID, i; struct emsmdbp_prop_index prop_index; struct SPropTagArray *new_columns; void **new_data; if (!emsmdbp_is_mapistore(source_object) || !emsmdbp_is_mapistore(dest_object)) { /* we silently fail for non-mapistore messages */ return MAPI_E_SUCCESS; } /* Fetch data from source message */ mem_ctx = talloc_zero(NULL, TALLOC_CTX); contextID = emsmdbp_get_contextID(source_object); mapistore_message_get_message_data(emsmdbp_ctx->mstore_ctx, contextID, source_object->backend_object, mem_ctx, &msg_data); /* By convention, we pass PR_DISPLAY_NAME_UNICODE and PR_EMAIL_ADDRESS_UNICODE to the backend, so we prepend them to each values array */ if (msg_data->recipients_count > 0 && (msg_data->columns->cValues < 2 || msg_data->columns->aulPropTag[0] != PR_DISPLAY_NAME_UNICODE || msg_data->columns->aulPropTag[1] != PR_EMAIL_ADDRESS_UNICODE)) { emsmdbp_fill_prop_index(&prop_index, msg_data->columns); new_columns = talloc_zero(mem_ctx, struct SPropTagArray); new_columns->cValues = msg_data->columns->cValues + 2; new_columns->aulPropTag = talloc_array(new_columns, enum MAPITAGS, new_columns->cValues); memcpy(new_columns->aulPropTag + 2, msg_data->columns->aulPropTag, sizeof(enum MAPITAGS) * msg_data->columns->cValues); new_columns->aulPropTag[0] = PR_DISPLAY_NAME_UNICODE; new_columns->aulPropTag[1] = PR_EMAIL_ADDRESS_UNICODE; for (i = 0; i < msg_data->recipients_count; i++) { new_data = talloc_array(mem_ctx, void *, new_columns->cValues); memcpy(new_data + 2, msg_data->recipients[i].data, sizeof(void *) * msg_data->columns->cValues); if (prop_index.display_name != (uint32_t) -1) { new_data[0] = msg_data->recipients[i].data[prop_index.display_name]; } else { new_data[0] = NULL; } if (prop_index.email_address != (uint32_t) -1) { new_data[1] = msg_data->recipients[i].data[prop_index.email_address]; } else { new_data[1] = NULL; } msg_data->recipients[i].data = new_data; } msg_data->columns = new_columns; /* Copy data into dest message */ mapistore_message_modify_recipients(emsmdbp_ctx->mstore_ctx, contextID, dest_object->backend_object, msg_data->columns, msg_data->recipients_count, msg_data->recipients); } talloc_free(mem_ctx); return MAPI_E_SUCCESS; } static inline int emsmdbp_copy_message_attachments_mapistore(struct emsmdbp_context *emsmdbp_ctx, struct emsmdbp_object *source_object, struct emsmdbp_object *dest_object) { TALLOC_CTX *mem_ctx; uint32_t i, count, contextID, dest_num; void **data_pointers; enum MAPISTATUS *retvals; uint32_t *attach_nums; struct emsmdbp_object *table_object, *source_attach, *dest_attach; enum MAPITAGS column; int ret; if (!emsmdbp_is_mapistore(source_object) || !emsmdbp_is_mapistore(dest_object)) { /* we silently fail for non-mapistore messages */ return MAPI_E_SUCCESS; } mem_ctx = talloc_zero(NULL, TALLOC_CTX); /* we fetch the attachment nums */ table_object = emsmdbp_object_message_open_attachment_table(mem_ctx, emsmdbp_ctx, source_object); if (!table_object) { talloc_free(mem_ctx); return MAPI_E_NOT_FOUND; } column = PR_ATTACH_NUM; table_object->object.table->prop_count = 1; table_object->object.table->properties = &column; contextID = emsmdbp_get_contextID(table_object); mapistore_table_set_columns(emsmdbp_ctx->mstore_ctx, contextID, table_object->backend_object, 1, &column); count = table_object->object.table->denominator; attach_nums = talloc_array(mem_ctx, uint32_t, count); for (i = 0; i < table_object->object.table->denominator; i++) { data_pointers = emsmdbp_object_table_get_row_props(mem_ctx, emsmdbp_ctx, table_object, i, MAPISTORE_PREFILTERED_QUERY, &retvals); if (!data_pointers) { talloc_free(mem_ctx); return MAPISTORE_ERROR; } if (retvals[0] != MAPI_E_SUCCESS) { talloc_free(mem_ctx); DEBUG(5, ("cannot copy attachments without PR_ATTACH_NUM\n")); return MAPISTORE_ERROR; } attach_nums[i] = *(uint32_t *) data_pointers[0]; } /* we open each attachment manually and copy their props to created dest attachments */ for (i = 0; i < count; i++) { source_attach = emsmdbp_object_attachment_init(mem_ctx, emsmdbp_ctx, source_object->object.message->messageID, source_object); if (!source_attach || mapistore_message_open_attachment(emsmdbp_ctx->mstore_ctx, contextID, source_object->backend_object, source_attach, attach_nums[i], &source_attach->backend_object)) { talloc_free(mem_ctx); return MAPISTORE_ERROR; } dest_attach = emsmdbp_object_attachment_init(mem_ctx, emsmdbp_ctx, dest_object->object.message->messageID, dest_object); if (!dest_attach || mapistore_message_create_attachment(emsmdbp_ctx->mstore_ctx, contextID, dest_object->backend_object, dest_attach, &dest_attach->backend_object, &dest_num)) { talloc_free(mem_ctx); return MAPISTORE_ERROR; } ret = emsmdbp_copy_properties(emsmdbp_ctx, source_attach, dest_attach, NULL); if (ret != MAPI_E_SUCCESS) { talloc_free(mem_ctx); return ret; } } talloc_free(mem_ctx); return MAPI_E_SUCCESS; } /** \details Copy properties from an object to another object \param emsmdbp_ctx pointer to the emsmdb provider context \param source_object pointer to the source object \param target_object pointer to the target object \param excluded_properties pointer to a SPropTagArray listing properties that must not be copied \param deep_copy indicates whether subobjects must be copied \return Allocated emsmdbp object on success, otherwise NULL */ _PUBLIC_ int emsmdbp_object_copy_properties(struct emsmdbp_context *emsmdbp_ctx, struct emsmdbp_object *source_object, struct emsmdbp_object *target_object, struct SPropTagArray *excluded_properties, bool deep_copy) { int ret; if (!(source_object->type == EMSMDBP_OBJECT_FOLDER || source_object->type == EMSMDBP_OBJECT_MAILBOX || source_object->type == EMSMDBP_OBJECT_MESSAGE || source_object->type == EMSMDBP_OBJECT_ATTACHMENT)) { DEBUG(0, (__location__": object must be EMSMDBP_OBJECT_FOLDER, EMSMDBP_OBJECT_MAILBOX, EMSMDBP_OBJECT_MESSAGE or EMSMDBP_OBJECT_ATTACHMENT (type = %d)\n", source_object->type)); ret = MAPI_E_NO_SUPPORT; goto end; } if (target_object->type != source_object->type) { DEBUG(0, ("source and destination objects type must match (type = %d)\n", target_object->type)); ret = MAPI_E_NO_SUPPORT; goto end; } /* copy properties (common to all object types) */ ret = emsmdbp_copy_properties(emsmdbp_ctx, source_object, target_object, excluded_properties); if (ret != MAPI_E_SUCCESS) { goto end; } /* type specific ops */ switch (source_object->type) { case EMSMDBP_OBJECT_MESSAGE: if (emsmdbp_is_mapistore(source_object) && emsmdbp_is_mapistore(target_object)) { ret = emsmdbp_copy_message_recipients_mapistore(emsmdbp_ctx, source_object, target_object); if (ret != MAPI_E_SUCCESS) { goto end; } if (deep_copy) { ret = emsmdbp_copy_message_attachments_mapistore(emsmdbp_ctx, source_object, target_object); if (ret != MAPI_E_SUCCESS) { goto end; } } } else { DEBUG(0, ("Cannot copy recipients or attachments to or from non-mapistore messages\n")); } break; default: if (deep_copy) { DEBUG(0, ("Cannot deep copy non-message objects\n")); } } end: return ret; } /** \details Initialize a mailbox object \param mem_ctx pointer to the memory context \param emsmdbp_ctx pointer to the emsmdb provider context \param request pointer to the Logon MAPI request \param mailboxstore boolean which specifies whether the mailbox object is a PF store or a private mailbox store \return Allocated emsmdbp object on success, otherwise NULL */ _PUBLIC_ struct emsmdbp_object *emsmdbp_object_mailbox_init(TALLOC_CTX *mem_ctx, struct emsmdbp_context *emsmdbp_ctx, const char *essDN, bool mailboxstore) { struct emsmdbp_object *object; const char *displayName, *accountName; const char * const recipient_attrs[] = { "*", NULL }; int ret; struct ldb_result *res = NULL; /* Sanity checks */ if (!emsmdbp_ctx) return NULL; if (!essDN) return NULL; object = emsmdbp_object_init(mem_ctx, emsmdbp_ctx, NULL); if (!object) return NULL; /* Initialize the mailbox object */ object->object.mailbox = talloc_zero(object, struct emsmdbp_object_mailbox); if (!object->object.mailbox) { talloc_free(object); return NULL; } object->type = EMSMDBP_OBJECT_MAILBOX; object->object.mailbox->owner_Name = NULL; object->object.mailbox->owner_EssDN = NULL; object->object.mailbox->szUserDN = NULL; object->object.mailbox->folderID = 0x0; object->object.mailbox->mailboxstore = mailboxstore; if (mailboxstore == true) { object->object.mailbox->owner_EssDN = talloc_strdup(object->object.mailbox, essDN); ret = ldb_search(emsmdbp_ctx->samdb_ctx, mem_ctx, &res, ldb_get_default_basedn(emsmdbp_ctx->samdb_ctx), LDB_SCOPE_SUBTREE, recipient_attrs, "legacyExchangeDN=%s", object->object.mailbox->owner_EssDN); if (!ret && res->count == 1) { accountName = ldb_msg_find_attr_as_string(res->msgs[0], "sAMAccountName", NULL); if (accountName) { object->object.mailbox->owner_username = talloc_strdup(object->object.mailbox, accountName); /* Retrieve Mailbox folder identifier */ openchangedb_get_SystemFolderID(emsmdbp_ctx->oc_ctx, object->object.mailbox->owner_username, 0x1, &object->object.mailbox->folderID); } displayName = ldb_msg_find_attr_as_string(res->msgs[0], "displayName", NULL); if (displayName) { object->object.mailbox->owner_Name = talloc_strdup(object->object.mailbox, displayName); } } } else { /* Retrieve Public folder identifier */ openchangedb_get_PublicFolderID(emsmdbp_ctx->oc_ctx, EMSMDBP_PF_ROOT, &object->object.mailbox->folderID); } object->object.mailbox->szUserDN = talloc_strdup(object->object.mailbox, emsmdbp_ctx->szUserDN); talloc_free(res); return object; } /** \details Initialize a folder object \param mem_ctx pointer to the memory context \param emsmdbp_ctx pointer to the emsmdb provider context \param folderID the folder identifier \param parent emsmdbp object of the parent folder for this folder \return Allocated emsmdbp object on success, otherwise NULL */ _PUBLIC_ struct emsmdbp_object *emsmdbp_object_folder_init(TALLOC_CTX *mem_ctx, struct emsmdbp_context *emsmdbp_ctx, uint64_t folderID, struct emsmdbp_object *parent_object) { struct emsmdbp_object *object; /* Sanity checks */ if (!emsmdbp_ctx) return NULL; object = emsmdbp_object_init(mem_ctx, emsmdbp_ctx, parent_object); if (!object) return NULL; object->object.folder = talloc_zero(object, struct emsmdbp_object_folder); if (!object->object.folder) { talloc_free(object); return NULL; } object->type = EMSMDBP_OBJECT_FOLDER; object->object.folder->folderID = folderID; object->object.folder->mapistore_root = false; object->object.folder->contextID = (uint32_t) -1; return object; } int emsmdbp_folder_get_folder_count(struct emsmdbp_context *emsmdbp_ctx, struct emsmdbp_object *folder, uint32_t *row_countp) { int retval; uint64_t folderID; if (emsmdbp_is_mapistore(folder)) { retval = (int) mapistore_folder_get_child_count(emsmdbp_ctx->mstore_ctx, emsmdbp_get_contextID(folder), folder->backend_object, MAPISTORE_FOLDER_TABLE, row_countp); } else { if (folder->type == EMSMDBP_OBJECT_FOLDER) { folderID = folder->object.folder->folderID; } else if (folder->type == EMSMDBP_OBJECT_MAILBOX) { folderID = folder->object.folder->folderID; } else { DEBUG(5, ("unsupported object type\n")); return MAPISTORE_ERROR; } printf("emsmdbp_folder_get_folder_count: folderID = %"PRIu64"\n", folderID); retval = (int) openchangedb_get_folder_count(emsmdbp_ctx->oc_ctx, folderID, row_countp); } return retval; } _PUBLIC_ enum mapistore_error emsmdbp_folder_move_folder(struct emsmdbp_context *emsmdbp_ctx, struct emsmdbp_object *move_folder, struct emsmdbp_object *target_folder, TALLOC_CTX *mem_ctx, const char *new_name) { enum mapistore_error ret; enum MAPISTATUS retval; uint32_t contextID; int system_idx; bool is_top_of_IS, is_special; /* TODO: we should provide the ability to perform this operation between non-mapistore objects or between mapistore and non-mapistore objects */ if (!emsmdbp_is_mapistore(move_folder)) { return MAPISTORE_ERR_DENIED; } if (!emsmdbp_is_mapistore(target_folder)) { /* TODO: converting a non-mapistore root object to one is not trivial but should be implemented one day. */ return MAPISTORE_ERR_DENIED; /* target is the "Top of Information Store" ? */ retval = openchangedb_get_system_idx(emsmdbp_ctx->oc_ctx, target_folder->object.folder->folderID, &system_idx); if (retval != MAPI_E_SUCCESS) { return MAPISTORE_ERROR; } is_top_of_IS = (system_idx == EMSMDBP_TOP_INFORMATION_STORE); if (!is_top_of_IS) { return MAPISTORE_ERR_DENIED; } } else { is_top_of_IS = false; } /* we check whether the folder is a special folder that cannot be moved */ if (move_folder->object.folder->mapistore_root) { retval = openchangedb_get_system_idx(emsmdbp_ctx->oc_ctx, move_folder->object.folder->folderID, &system_idx); if (retval != MAPI_E_SUCCESS) { return MAPISTORE_ERROR; } is_special = (system_idx != -1); if (is_special) { return MAPISTORE_ERR_DENIED; } } contextID = emsmdbp_get_contextID(move_folder); ret = mapistore_folder_move_folder(emsmdbp_ctx->mstore_ctx, contextID, move_folder->backend_object, target_folder->backend_object, mem_ctx, new_name); if (move_folder->object.folder->mapistore_root) { retval = openchangedb_delete_folder(emsmdbp_ctx->oc_ctx, move_folder->object.folder->folderID); if (retval) { DEBUG(0, ("an error occurred during the deletion of the folder entry in the openchange db: %d", retval)); } } if (is_top_of_IS) { /* pass */ } return ret; } _PUBLIC_ enum mapistore_error emsmdbp_folder_delete(struct emsmdbp_context *emsmdbp_ctx, struct emsmdbp_object *parent_folder, uint64_t fid, uint8_t flags) { enum mapistore_error ret; enum MAPISTATUS mapiret; TALLOC_CTX *mem_ctx; bool mailboxstore; uint32_t context_id; void *subfolder; char *mapistoreURL; mem_ctx = talloc_zero(NULL, TALLOC_CTX); mailboxstore = emsmdbp_is_mailboxstore(parent_folder); if (emsmdbp_is_mapistore(parent_folder)) { /* fid is not a mapistore root */ DEBUG(0, ("Deleting mapistore folder\n")); /* handled by mapistore */ context_id = emsmdbp_get_contextID(parent_folder); ret = mapistore_folder_open_folder(emsmdbp_ctx->mstore_ctx, context_id, parent_folder->backend_object, mem_ctx, fid, &subfolder); if (ret != MAPISTORE_SUCCESS) { goto end; } ret = mapistore_folder_delete(emsmdbp_ctx->mstore_ctx, context_id, subfolder, flags); if (ret != MAPISTORE_SUCCESS) { goto end; } } else { mapiret = openchangedb_get_mapistoreURI(mem_ctx, emsmdbp_ctx->oc_ctx, fid, &mapistoreURL, mailboxstore); if (mapiret != MAPI_E_SUCCESS) { ret = MAPISTORE_ERR_NOT_FOUND; goto end; } mapiret = openchangedb_delete_folder(emsmdbp_ctx->oc_ctx, fid); if (mapiret != MAPI_E_SUCCESS) { ret = MAPISTORE_ERR_NOT_FOUND; goto end; } if (mapistoreURL) { /* fid is mapistore root */ ret = mapistore_search_context_by_uri(emsmdbp_ctx->mstore_ctx, mapistoreURL, &context_id, &subfolder); if (ret == MAPISTORE_SUCCESS) { mapistore_add_context_ref_count(emsmdbp_ctx->mstore_ctx, context_id); } else { ret = mapistore_add_context(emsmdbp_ctx->mstore_ctx, emsmdbp_ctx->username, mapistoreURL, fid, &context_id, &subfolder); if (ret != MAPISTORE_SUCCESS) { goto end; } } ret = mapistore_folder_delete(emsmdbp_ctx->mstore_ctx, context_id, subfolder, flags); if (ret != MAPISTORE_SUCCESS) { goto end; } mapistore_del_context(emsmdbp_ctx->mstore_ctx, context_id); } } ret = MAPISTORE_SUCCESS; end: talloc_free(mem_ctx); return ret; } _PUBLIC_ struct emsmdbp_object *emsmdbp_folder_open_table(TALLOC_CTX *mem_ctx, struct emsmdbp_object *parent_object, uint32_t table_type, uint32_t handle_id) { struct emsmdbp_object *table_object; uint64_t folderID; uint8_t mstore_type; int ret; if (!(parent_object->type != EMSMDBP_OBJECT_FOLDER || parent_object->type != EMSMDBP_OBJECT_MAILBOX)) { DEBUG(0, (__location__": parent_object must be EMSMDBP_OBJECT_FOLDER or EMSMDBP_OBJECT_MAILBOX (type = %d)\n", parent_object->type)); return NULL; } if (parent_object->type == EMSMDBP_OBJECT_FOLDER && parent_object->object.folder->postponed_props) { emsmdbp_object_folder_commit_creation(parent_object->emsmdbp_ctx, parent_object, true); } table_object = emsmdbp_object_table_init(mem_ctx, parent_object->emsmdbp_ctx, parent_object); if (table_object) { table_object->object.table->handle = handle_id; table_object->object.table->ulType = table_type; if (emsmdbp_is_mapistore(parent_object)) { switch (table_type) { case MAPISTORE_MESSAGE_TABLE: mstore_type = MAPISTORE_MESSAGE_TABLE; break; case MAPISTORE_FAI_TABLE: mstore_type = MAPISTORE_FAI_TABLE; break; case MAPISTORE_FOLDER_TABLE: mstore_type = MAPISTORE_FOLDER_TABLE; break; case MAPISTORE_PERMISSIONS_TABLE: mstore_type = MAPISTORE_PERMISSIONS_TABLE; break; default: DEBUG(5, ("Unhandled table type for folders: %d\n", table_type)); abort(); } ret = mapistore_folder_open_table(parent_object->emsmdbp_ctx->mstore_ctx, emsmdbp_get_contextID(parent_object), parent_object->backend_object, table_object, mstore_type, handle_id, &table_object->backend_object, &table_object->object.table->denominator); if (ret != MAPISTORE_SUCCESS) { talloc_free(table_object); table_object = NULL; } } else { if (table_type == MAPISTORE_FOLDER_TABLE) { /* this gets data both for openchangedb and mapistore: needs improvement */ emsmdbp_folder_get_folder_count(parent_object->emsmdbp_ctx, parent_object, &table_object->object.table->denominator); } else { /* Retrieve folder ID */ switch (parent_object->type) { case EMSMDBP_OBJECT_FOLDER: folderID = parent_object->object.folder->folderID; break; case EMSMDBP_OBJECT_MAILBOX: folderID = parent_object->object.mailbox->folderID; break; default: DEBUG(5, ("Unsupported object type")); table_object->object.table->denominator = 0; return table_object; } /* Non-mapistore message tables */ switch (table_type) { case MAPISTORE_MESSAGE_TABLE: openchangedb_get_message_count(parent_object->emsmdbp_ctx->oc_ctx, folderID, &table_object->object.table->denominator, false); break; case MAPISTORE_FAI_TABLE: openchangedb_get_message_count(parent_object->emsmdbp_ctx->oc_ctx, folderID, &table_object->object.table->denominator, true); break; default: DEBUG(0, ("Unhandled openchangedb table type for folders: %d\n", table_type)); table_object->object.table->denominator = 0; abort(); } } if (!emsmdbp_is_mapistore(parent_object)) { /* Retrieve folder ID */ switch (parent_object->type) { case EMSMDBP_OBJECT_FOLDER: folderID = parent_object->object.folder->folderID; break; case EMSMDBP_OBJECT_MAILBOX: folderID = parent_object->object.mailbox->folderID; break; default: DEBUG(5, ("Unsupported object type")); table_object->object.table->denominator = 0; return table_object; } DEBUG(0, ("Initializaing openchangedb table\n")); openchangedb_table_init((TALLOC_CTX *)table_object, table_type, folderID, &table_object->backend_object); } } } return table_object; } /** \details Initialize a table object \param mem_ctx pointer to the memory context \param emsmdbp_ctx pointer to the emsmdb provider context \param parent emsmdbp object of the parent \return Allocated emsmdbp object on success, otherwise NULL */ _PUBLIC_ struct emsmdbp_object *emsmdbp_object_table_init(TALLOC_CTX *mem_ctx, struct emsmdbp_context *emsmdbp_ctx, struct emsmdbp_object *parent) { struct emsmdbp_object *object; /* Sanity checks */ if (!emsmdbp_ctx) return NULL; if (!parent) return NULL; if (parent->type != EMSMDBP_OBJECT_FOLDER && parent->type != EMSMDBP_OBJECT_MAILBOX && parent->type != EMSMDBP_OBJECT_MESSAGE) return NULL; /* Initialize table object */ object = emsmdbp_object_init(mem_ctx, emsmdbp_ctx, parent); if (!object) return NULL; object->object.table = talloc_zero(object, struct emsmdbp_object_table); if (!object->object.table) { talloc_free(object); return NULL; } object->type = EMSMDBP_OBJECT_TABLE; object->object.table->prop_count = 0; object->object.table->properties = NULL; object->object.table->numerator = 0; object->object.table->denominator = 0; object->object.table->ulType = 0; object->object.table->restricted = false; object->object.table->subscription_list = NULL; return object; } _PUBLIC_ int emsmdbp_object_table_get_available_properties(TALLOC_CTX *mem_ctx, struct emsmdbp_context *emsmdbp_ctx, struct emsmdbp_object *table_object, struct SPropTagArray **propertiesp) { int retval; struct SPropTagArray *properties; uint32_t contextID; if (table_object->type != EMSMDBP_OBJECT_TABLE) { return MAPISTORE_ERROR; } if (emsmdbp_is_mapistore(table_object)) { contextID = emsmdbp_get_contextID(table_object); retval = mapistore_table_get_available_properties(emsmdbp_ctx->mstore_ctx, contextID, table_object->backend_object, mem_ctx, propertiesp); } else { properties = talloc_zero(mem_ctx, struct SPropTagArray); properties->aulPropTag = talloc_zero(properties, enum MAPITAGS); /* TODO: this list might not be complete */ SPropTagArray_add(properties, properties, PR_FID); SPropTagArray_add(properties, properties, PR_PARENT_FID); SPropTagArray_add(properties, properties, PR_DISPLAY_NAME_UNICODE); SPropTagArray_add(properties, properties, PR_COMMENT_UNICODE); SPropTagArray_add(properties, properties, PR_ACCESS); SPropTagArray_add(properties, properties, PR_ACCESS_LEVEL); SPropTagArray_add(properties, properties, PidTagRights); SPropTagArray_add(properties, properties, PidTagExtendedFolderFlags); SPropTagArray_add(properties, properties, PidTagDesignInProgress); SPropTagArray_add(properties, properties, PidTagSecureOrigination); SPropTagArray_add(properties, properties, PR_NTSD_MODIFICATION_TIME); SPropTagArray_add(properties, properties, PR_ADDITIONAL_REN_ENTRYIDS); SPropTagArray_add(properties, properties, PR_ADDITIONAL_REN_ENTRYIDS_EX); SPropTagArray_add(properties, properties, PR_CREATION_TIME); SPropTagArray_add(properties, properties, PR_CREATOR_SID); SPropTagArray_add(properties, properties, PR_CREATOR_ENTRYID); SPropTagArray_add(properties, properties, PR_LAST_MODIFICATION_TIME); SPropTagArray_add(properties, properties, PR_LAST_MODIFIER_SID); SPropTagArray_add(properties, properties, PR_LAST_MODIFIER_ENTRYID); SPropTagArray_add(properties, properties, PR_ATTR_HIDDEN); SPropTagArray_add(properties, properties, PR_ATTR_SYSTEM); SPropTagArray_add(properties, properties, PR_ATTR_READONLY); SPropTagArray_add(properties, properties, PR_EXTENDED_ACL_DATA); SPropTagArray_add(properties, properties, PR_CONTAINER_CLASS_UNICODE); SPropTagArray_add(properties, properties, PR_CONTENT_COUNT); SPropTagArray_add(properties, properties, PidTagAssociatedContentCount); SPropTagArray_add(properties, properties, PR_SUBFOLDERS); SPropTagArray_add(properties, properties, PR_MAPPING_SIGNATURE); SPropTagArray_add(properties, properties, PR_USER_ENTRYID); SPropTagArray_add(properties, properties, PR_MAILBOX_OWNER_ENTRYID); SPropTagArray_add(properties, properties, PR_MAILBOX_OWNER_NAME_UNICODE); SPropTagArray_add(properties, properties, PR_IPM_APPOINTMENT_ENTRYID); SPropTagArray_add(properties, properties, PR_IPM_CONTACT_ENTRYID); SPropTagArray_add(properties, properties, PR_IPM_JOURNAL_ENTRYID); SPropTagArray_add(properties, properties, PR_IPM_NOTE_ENTRYID); SPropTagArray_add(properties, properties, PR_IPM_TASK_ENTRYID); SPropTagArray_add(properties, properties, PR_IPM_DRAFTS_ENTRYID); SPropTagArray_add(properties, properties, PR_REMINDERS_ONLINE_ENTRYID); SPropTagArray_add(properties, properties, PR_IPM_PUBLIC_FOLDERS_ENTRYID); SPropTagArray_add(properties, properties, PR_FOLDER_XVIEWINFO_E); SPropTagArray_add(properties, properties, PR_FOLDER_VIEWLIST); SPropTagArray_add(properties, properties, PR_FREEBUSY_ENTRYIDS); SPropTagArray_add(properties, properties, 0x36de0003); /* some unknown prop that outlook sets */ *propertiesp = properties; retval = MAPISTORE_SUCCESS; } return retval; } _PUBLIC_ void **emsmdbp_object_table_get_row_props(TALLOC_CTX *mem_ctx, struct emsmdbp_context *emsmdbp_ctx, struct emsmdbp_object *table_object, uint32_t row_id, enum mapistore_query_type query_type, enum MAPISTATUS **retvalsp) { void **data_pointers; enum MAPISTATUS retval; enum mapistore_error ret; enum MAPISTATUS *retvals; struct emsmdbp_object_table *table; struct mapistore_property_data *properties; uint32_t contextID, i, num_props; struct emsmdbp_object *rowobject; uint64_t *rowFMId; uint64_t parentFolderId; bool mapistore_folder; void *odb_ctx; char *owner; struct Binary_r *binr; table = table_object->object.table; num_props = table_object->object.table->prop_count; data_pointers = talloc_array(mem_ctx, void *, num_props); memset(data_pointers, 0, sizeof(void *) * num_props); retvals = talloc_array(mem_ctx, enum MAPISTATUS, num_props); memset(retvals, 0, sizeof(uint32_t) * num_props); if (emsmdbp_is_mapistore(table_object)) { contextID = emsmdbp_get_contextID(table_object); retval = mapistore_table_get_row(emsmdbp_ctx->mstore_ctx, contextID, table_object->backend_object, data_pointers, query_type, row_id, &properties); if (retval == MAPI_E_SUCCESS) { for (i = 0; i < num_props; i++) { data_pointers[i] = properties[i].data; if (properties[i].error) { retvals[i] = mapistore_error_to_mapi(properties[i].error); } else { if (properties[i].data == NULL) { retvals[i] = MAPI_E_NOT_FOUND; } } } } else { DEBUG(5, ("%s: invalid object (likely due to a restriction)\n", __location__)); talloc_free(retvals); talloc_free(data_pointers); return NULL; } } else { if (table_object->parent_object->type == EMSMDBP_OBJECT_FOLDER) { parentFolderId = table_object->parent_object->object.folder->folderID; } else if (table_object->parent_object->type == EMSMDBP_OBJECT_MAILBOX) { parentFolderId = table_object->parent_object->object.mailbox->folderID; } else { DEBUG(5, ("%s: non-mapistore tables can only be client of folder objects\n", __location__)); talloc_free(retvals); talloc_free(data_pointers); return NULL; } odb_ctx = talloc_zero(NULL, void); /* Setup table_filter for openchangedb */ /* switch (table_object->object.table->ulType) { */ /* case MAPISTORE_MESSAGE_TABLE: */ /* table_filter = talloc_asprintf(odb_ctx, "(&(PidTagParentFolderId=%"PRIu64")(PidTagMessageId=*))", folderID); */ /* break; */ /* case MAPISTORE_FOLDER_TABLE: */ /* table_filter = talloc_asprintf(odb_ctx, "(&(PidTagParentFolderId=%"PRIu64")(PidTagFolderId=*))", folderID); */ /* break; */ /* default: */ /* DEBUG(5, ("[%s:%d]: Unsupported table type for openchangedb: %d\n", __FUNCTION__, __LINE__, */ /* table_object->object.table->ulType)); */ /* talloc_free(retvals); */ /* talloc_free(data_pointers); */ /* return NULL; */ /* } */ /* 1. retrieve the object id from odb */ switch (table_object->object.table->ulType) { case MAPISTORE_FOLDER_TABLE: retval = openchangedb_table_get_property(odb_ctx, table_object->backend_object, emsmdbp_ctx->oc_ctx, PR_FID, row_id, (query_type == MAPISTORE_LIVEFILTERED_QUERY), (void **) &rowFMId); break; case MAPISTORE_MESSAGE_TABLE: retval = openchangedb_table_get_property(odb_ctx, table_object->backend_object, emsmdbp_ctx->oc_ctx, PR_MID, row_id, (query_type == MAPISTORE_LIVEFILTERED_QUERY), (void **) &rowFMId); break; /* case MAPISTORE_FAI_TABLE: retval = openchangedb_table_get_property(odb_ctx, table_object->backend_object, emsmdbp_ctx->oc_ctx, PR_MID, row_id, (query_type == MAPISTORE_LIVEFILTERED_QUERY), (void **) &rowFMId); break; */ default: DEBUG(5, ("table type %d not supported for non-mapistore table\n", table_object->object.table->ulType)); retval = MAPI_E_INVALID_OBJECT; } /* printf("openchangedb_table_get_property retval = 0x%.8x\n", retval); */ if (retval != MAPI_E_SUCCESS) { talloc_free(retvals); talloc_free(data_pointers); talloc_free(odb_ctx); return NULL; } /* 2. open the corresponding object */ switch (table_object->object.table->ulType) { case MAPISTORE_FOLDER_TABLE: ret = emsmdbp_object_open_folder(odb_ctx, table_object->parent_object->emsmdbp_ctx, table_object->parent_object, *(uint64_t *)rowFMId, &rowobject); if (ret == MAPISTORE_SUCCESS) { mapistore_folder = emsmdbp_is_mapistore(rowobject); if (mapistore_folder) { contextID = emsmdbp_get_contextID(rowobject); } } break; case MAPISTORE_MESSAGE_TABLE: ret = emsmdbp_object_message_open(odb_ctx, table_object->parent_object->emsmdbp_ctx, table_object->parent_object, parentFolderId, *(uint64_t *)rowFMId, false, &rowobject, NULL); mapistore_folder = false; break; default: DEBUG(5, ("you should never get here\n")); abort(); } if (ret != MAPISTORE_SUCCESS) { talloc_free(retvals); talloc_free(data_pointers); talloc_free(odb_ctx); return NULL; } /* read the row properties */ retval = MAPI_E_SUCCESS; for (i = 0; retval != MAPI_E_INVALID_OBJECT && i < num_props; i++) { if (mapistore_folder) { /* a hack to avoid fetching dynamic fields from openchange.ldb */ switch (table->properties[i]) { case PR_CONTENT_COUNT: case PidTagAssociatedContentCount: case PR_CONTENT_UNREAD: case PidTagFolderChildCount: case PR_SUBFOLDERS: case PidTagDeletedCountTotal: case PidTagAccess: case PidTagAccessLevel: case PidTagRights: { struct SPropTagArray props; void **local_data_pointers; enum MAPISTATUS *local_retvals; props.cValues = 1; props.aulPropTag = table->properties + i; local_data_pointers = emsmdbp_object_get_properties(data_pointers, emsmdbp_ctx, rowobject, &props, &local_retvals); data_pointers[i] = local_data_pointers[0]; retvals[i] = local_retvals[0]; } break; case PidTagSourceKey: owner = emsmdbp_get_owner(table_object); emsmdbp_source_key_from_fmid(data_pointers, emsmdbp_ctx, owner, rowobject->object.folder->folderID, &binr); data_pointers[i] = binr; retval = MAPI_E_SUCCESS; break; default: retval = openchangedb_table_get_property(data_pointers, table_object->backend_object, emsmdbp_ctx->oc_ctx, table->properties[i], row_id, (query_type == MAPISTORE_LIVEFILTERED_QUERY), data_pointers + i); /* retval = openchangedb_get_table_property(data_pointers, emsmdbp_ctx->oc_ctx, */ /* emsmdbp_ctx->username, */ /* table_filter, table->properties[i], */ /* row_id, data_pointers + i); */ } } else { retval = openchangedb_table_get_property(data_pointers, table_object->backend_object, emsmdbp_ctx->oc_ctx, table->properties[i], row_id, (query_type == MAPISTORE_LIVEFILTERED_QUERY), data_pointers + i); } /* DEBUG(5, (" %.8x: %d", table->properties[j], retval)); */ if (retval == MAPI_E_INVALID_OBJECT) { DEBUG(5, ("%s: invalid object in non-mapistore folder, count set to 0\n", __location__)); talloc_free(retvals); talloc_free(data_pointers); talloc_free(odb_ctx); return NULL; } else { retvals[i] = retval; } } talloc_free(odb_ctx); } if (retvalsp) { *retvalsp = retvals; } return data_pointers; } _PUBLIC_ void emsmdbp_fill_table_row_blob(TALLOC_CTX *mem_ctx, struct emsmdbp_context *emsmdbp_ctx, DATA_BLOB *table_row, uint16_t num_props, enum MAPITAGS *properties, void **data_pointers, enum MAPISTATUS *retvals) { uint16_t i; uint8_t flagged; enum MAPITAGS property; void *data; uint32_t retval; flagged = 0; for (i = 0; !flagged && i < num_props; i++) { if (retvals[i] != MAPI_E_SUCCESS) { flagged = 1; } } if (flagged) { libmapiserver_push_property(mem_ctx, 0x0000000b, (const void *)&flagged, table_row, 0, 0, 0); } else { libmapiserver_push_property(mem_ctx, 0x00000000, (const void *)&flagged, table_row, 0, 1, 0); } for (i = 0; i < num_props; i++) { property = properties[i]; retval = retvals[i]; if (retval != MAPI_E_SUCCESS) { property = (property & 0xFFFF0000) + PT_ERROR; data = &retval; } else { data = data_pointers[i]; } libmapiserver_push_property(mem_ctx, property, data, table_row, flagged?PT_ERROR:0, flagged, 0); } } /** \details Initialize a message object \param mem_ctx pointer to the memory context \param emsmdbp_ctx pointer to the emsmdb provider context \param messageID the message identifier \param parent emsmdbp object of the parent \return Allocated emsmdbp object on success, otherwise NULL */ _PUBLIC_ struct emsmdbp_object *emsmdbp_object_message_init(TALLOC_CTX *mem_ctx, struct emsmdbp_context *emsmdbp_ctx, uint64_t messageID, struct emsmdbp_object *parent) { struct emsmdbp_object *object; /* Sanity checks */ if (!emsmdbp_ctx) return NULL; if (!parent) return NULL; if (parent->type != EMSMDBP_OBJECT_FOLDER && parent->type != EMSMDBP_OBJECT_MAILBOX && parent->type != EMSMDBP_OBJECT_ATTACHMENT) { DEBUG(5, ("expecting EMSMDBP_OBJECT_FOLDER/_MAILBOX/_ATTACHMENT as type of parent object\n")); return NULL; } /* Initialize message object */ object = emsmdbp_object_init(mem_ctx, emsmdbp_ctx, parent); if (!object) return NULL; object->object.message = talloc_zero(object, struct emsmdbp_object_message); if (!object->object.message) { talloc_free(object); return NULL; } object->type = EMSMDBP_OBJECT_MESSAGE; object->object.message->messageID = messageID; object->object.message->read_write = false; return object; } static struct mapistore_freebusy_properties *emsmdbp_fetch_freebusy(TALLOC_CTX *mem_ctx, struct emsmdbp_context *emsmdbp_ctx, const char *username, struct tm *start_tm, struct tm *end_tm) { TALLOC_CTX *local_mem_ctx; struct mapistore_freebusy_properties *fb_props; char *email, *tmp; struct SPropTagArray *props; void **data_pointers; enum MAPISTATUS *retvals = NULL; struct emsmdbp_object *mailbox, *inbox, *calendar; uint64_t inboxFID, calendarFID; uint32_t contextID; int i; fb_props = NULL; local_mem_ctx = talloc_zero(NULL, TALLOC_CTX); // WARNING: the mechanism here will fail if username is not all lower-case, as LDB does not support case-insensitive queries tmp = talloc_strdup(local_mem_ctx, username); while (*tmp) { *tmp = tolower(*tmp); tmp++; } email = talloc_asprintf(fb_props, "/o=First Organization/ou=First Administrative Group/cn=Recipients/cn=%s", username); /* open user mailbox */ mailbox = emsmdbp_object_mailbox_init(local_mem_ctx, emsmdbp_ctx, email, true); if (!mailbox) { goto end; } /* open Inbox */ openchangedb_get_SystemFolderID(emsmdbp_ctx->oc_ctx, username, EMSMDBP_INBOX, &inboxFID); if (emsmdbp_object_open_folder_by_fid(local_mem_ctx, emsmdbp_ctx, mailbox, inboxFID, &inbox) != MAPISTORE_SUCCESS) { goto end; } /* retrieve Calendar entry id */ props = talloc_zero(mem_ctx, struct SPropTagArray); props->cValues = 1; props->aulPropTag = talloc_zero(props, enum MAPITAGS); props->aulPropTag[0] = PR_IPM_APPOINTMENT_ENTRYID; data_pointers = emsmdbp_object_get_properties(local_mem_ctx, emsmdbp_ctx, inbox, props, &retvals); if (!data_pointers || retvals[0] != MAPI_E_SUCCESS) { goto end; } calendarFID = 0; for (i = 0; i < 6; i++) { calendarFID <<= 8; calendarFID |= *(((struct Binary_r *) data_pointers[0])->lpb + (43 - i)); } calendarFID <<= 16; calendarFID |= 1; /* open user calendar */ if (emsmdbp_object_open_folder_by_fid(local_mem_ctx, emsmdbp_ctx, mailbox, calendarFID, &calendar) != MAPISTORE_SUCCESS) { goto end; } if (!emsmdbp_is_mapistore(calendar)) { DEBUG(5, ("non-mapistore calendars are not supported for freebusy\n")); goto end; } contextID = emsmdbp_get_contextID(calendar); mapistore_folder_fetch_freebusy_properties(emsmdbp_ctx->mstore_ctx, contextID, calendar->backend_object, start_tm, end_tm, mem_ctx, &fb_props); end: talloc_free(local_mem_ctx); return fb_props; } static void emsmdbp_object_message_fill_freebusy_properties(struct emsmdbp_object *message_object) { /* freebusy mechanism: - lookup events in range now + 3 months, requesting end date, start date and PidLidBusyStatus - fill (olTentative) PidTagScheduleInfoMonthsTentative, PidTagScheduleInfoFreeBusyTentative - fill (olBusy) PidTagScheduleInfoMonthsBusy, PidTagScheduleInfoFreeBusyBusy - fill (olOutOfOffice) PidTagScheduleInfoMonthsAway, PidTagScheduleInfoFreeBusyAway - fill (olBusy + olOutOfOffice) PidTagScheduleInfoMonthsMerged, PidTagScheduleInfoFreeBusyMerged - fill PidTagFreeBusyPublishStart, PidTagFreeBusyPublishEnd and PidTagFreeBusyRangeTimestamp. - fill PidTagFreeBusyMessageEmailAddress */ TALLOC_CTX *mem_ctx; struct mapistore_freebusy_properties *fb_props; char *subject, *username; struct SPropTagArray *props; void **data_pointers; enum MAPISTATUS *retvals = NULL; mem_ctx = talloc_zero(NULL, TALLOC_CTX); /* 1. retrieve subject and deduce username */ props = talloc_zero(mem_ctx, struct SPropTagArray); props->cValues = 1; props->aulPropTag = talloc_zero(props, enum MAPITAGS); props->aulPropTag[0] = PR_NORMALIZED_SUBJECT_UNICODE; data_pointers = emsmdbp_object_get_properties(mem_ctx, message_object->emsmdbp_ctx, message_object, props, &retvals); if (!data_pointers || retvals[0] != MAPI_E_SUCCESS) { goto end; } subject = data_pointers[0]; /* FIXME: this is wrong, as the CN attribute may differ from the user's username (sAMAccountName) */ // format is "..../CN=" username = strrchr(subject, '/'); if (!username) { goto end; } username += 4; username = talloc_strdup(mem_ctx, username); fb_props = emsmdbp_fetch_freebusy(mem_ctx, message_object->emsmdbp_ctx, username, NULL, NULL); message_object->object.message->fb_properties = fb_props; end: talloc_free(mem_ctx); return; } _PUBLIC_ enum mapistore_error emsmdbp_object_message_open(TALLOC_CTX *mem_ctx, struct emsmdbp_context *emsmdbp_ctx, struct emsmdbp_object *parent_object, uint64_t folderID, uint64_t messageID, bool read_write, struct emsmdbp_object **messageP, struct mapistore_message **msgp) { struct emsmdbp_object *folder_object, *message_object = NULL; uint32_t contextID; bool mapistore; TALLOC_CTX *local_mem_ctx; enum mapistore_error ret = MAPISTORE_SUCCESS; if (!messageP) return MAPISTORE_ERROR; if (!parent_object) return MAPISTORE_ERROR; local_mem_ctx = talloc_zero(NULL, TALLOC_CTX); ret = emsmdbp_object_open_folder_by_fid(local_mem_ctx, emsmdbp_ctx, parent_object, folderID, &folder_object); if (ret != MAPISTORE_SUCCESS) { goto end; } mapistore = emsmdbp_is_mapistore(folder_object); switch (mapistore) { case false: /* system/special folder */ message_object = emsmdbp_object_message_init(mem_ctx, emsmdbp_ctx, messageID, folder_object); ret = openchangedb_message_open(mem_ctx, emsmdbp_ctx->oc_ctx, messageID, folderID, &message_object->backend_object, (void **)msgp); if (ret != MAPISTORE_SUCCESS) { printf("Invalid openchangedb message\n"); talloc_free(message_object); goto end; } emsmdbp_object_message_fill_freebusy_properties(message_object); break; case true: /* mapistore implementation goes here */ message_object = emsmdbp_object_message_init(mem_ctx, emsmdbp_ctx, messageID, folder_object); contextID = emsmdbp_get_contextID(folder_object); ret = mapistore_folder_open_message(emsmdbp_ctx->mstore_ctx, contextID, folder_object->backend_object, message_object, messageID, read_write, &message_object->backend_object); if (ret == MAPISTORE_SUCCESS && msgp) { if (mapistore_message_get_message_data(emsmdbp_ctx->mstore_ctx, contextID, message_object->backend_object, mem_ctx, msgp) != MAPISTORE_SUCCESS) { ret = MAPISTORE_ERROR; } } if (ret != MAPISTORE_SUCCESS) { talloc_free(message_object); } } end: talloc_free(local_mem_ctx); if (ret == MAPISTORE_SUCCESS) { message_object->object.message->read_write = read_write; *messageP = message_object; } return ret; } _PUBLIC_ struct emsmdbp_object *emsmdbp_object_message_open_attachment_table(TALLOC_CTX *mem_ctx, struct emsmdbp_context *emsmdbp_ctx, struct emsmdbp_object *message_object) { struct emsmdbp_object *table_object = NULL; uint32_t contextID; /* Sanity checks */ if (!emsmdbp_ctx) return NULL; if (!message_object || message_object->type != EMSMDBP_OBJECT_MESSAGE) return NULL; switch (emsmdbp_is_mapistore(message_object)) { case false: /* system/special folder */ DEBUG(0, ("[%s] not implemented yet - shouldn't occur\n", __location__)); table_object = NULL; break; case true: contextID = emsmdbp_get_contextID(message_object); table_object = emsmdbp_object_table_init(mem_ctx, emsmdbp_ctx, message_object); if (table_object) { table_object->object.table->ulType = MAPISTORE_ATTACHMENT_TABLE; mapistore_message_get_attachment_table(emsmdbp_ctx->mstore_ctx, contextID, message_object->backend_object, table_object, &table_object->backend_object, &table_object->object.table->denominator); } } return table_object; } /** \details Initialize a stream object \param mem_ctx pointer to the memory context \param emsmdbp_ctx pointer to the emsmdb provider cotnext \param property the stream property identifier \param parent emsmdbp object of the parent */ _PUBLIC_ struct emsmdbp_object *emsmdbp_object_stream_init(TALLOC_CTX *mem_ctx, struct emsmdbp_context *emsmdbp_ctx, struct emsmdbp_object *parent) { struct emsmdbp_object *object; /* Sanity checks */ if (!emsmdbp_ctx) return NULL; if (!parent) return NULL; object = emsmdbp_object_init(mem_ctx, emsmdbp_ctx, parent); if (!object) return NULL; object->object.stream = talloc_zero(object, struct emsmdbp_object_stream); if (!object->object.stream) { talloc_free(object); return NULL; } object->type = EMSMDBP_OBJECT_STREAM; object->object.stream->property = 0; object->object.stream->needs_commit = false; object->object.stream->stream.buffer.data = NULL; object->object.stream->stream.buffer.length = 0; object->object.stream->stream.position = 0; return object; } /** \details Initialize a attachment object \param mem_ctx pointer to the memory context \param emsmdbp_ctx pointer to the emsmdb provider cotnext \param folderID the folder identifier \param messageID the message identifier \param parent emsmdbp object of the parent */ _PUBLIC_ struct emsmdbp_object *emsmdbp_object_attachment_init(TALLOC_CTX *mem_ctx, struct emsmdbp_context *emsmdbp_ctx, uint64_t messageID, struct emsmdbp_object *parent) { struct emsmdbp_object *object; /* Sanity checks */ if (!emsmdbp_ctx) return NULL; if (!parent) return NULL; object = emsmdbp_object_init(mem_ctx, emsmdbp_ctx, parent); if (!object) return NULL; object->object.attachment = talloc_zero(object, struct emsmdbp_object_attachment); if (!object->object.attachment) { talloc_free(object); return NULL; } object->type = EMSMDBP_OBJECT_ATTACHMENT; object->object.attachment->attachmentID = -1; return object; } /** \details Initialize a notification subscription object \param mem_ctx pointer to the memory context \param emsmdbp_ctx pointer to the emsmdb provider cotnext \param whole_store whether the subscription applies to the specified change on the entire store or stricly on the specified folder/message \param folderID the folder identifier \param messageID the message identifier \param parent emsmdbp object of the parent */ _PUBLIC_ struct emsmdbp_object *emsmdbp_object_subscription_init(TALLOC_CTX *mem_ctx, struct emsmdbp_context *emsmdbp_ctx, struct emsmdbp_object *parent) { struct emsmdbp_object *object; /* Sanity checks */ if (!emsmdbp_ctx) return NULL; if (!parent) return NULL; object = emsmdbp_object_init(mem_ctx, emsmdbp_ctx, parent); if (!object) return NULL; object->object.subscription = talloc_zero(object, struct emsmdbp_object_subscription); if (!object->object.subscription) { talloc_free(object); return NULL; } object->type = EMSMDBP_OBJECT_SUBSCRIPTION; object->object.subscription->subscription_list = NULL; return object; } _PUBLIC_ int emsmdbp_object_get_available_properties(TALLOC_CTX *mem_ctx, struct emsmdbp_context *emsmdbp_ctx, struct emsmdbp_object *object, struct SPropTagArray **propertiesp) { uint32_t contextID; if (!(object->type == EMSMDBP_OBJECT_FOLDER || object->type == EMSMDBP_OBJECT_MAILBOX || object->type == EMSMDBP_OBJECT_MESSAGE || object->type == EMSMDBP_OBJECT_ATTACHMENT)) { DEBUG(0, (__location__": object must be EMSMDBP_OBJECT_FOLDER, EMSMDBP_OBJECT_MAILBOX, EMSMDBP_OBJECT_MESSAGE or EMSMDBP_OBJECT_ATTACHMENT (type = %d)\n", object->type)); return MAPISTORE_ERROR; } if (!emsmdbp_is_mapistore(object)) { DEBUG(5, (__location__": only mapistore is supported at this time\n")); return MAPISTORE_ERROR; } contextID = emsmdbp_get_contextID(object); return mapistore_properties_get_available_properties(emsmdbp_ctx->mstore_ctx, contextID, object->backend_object, mem_ctx, propertiesp); } static int emsmdbp_object_get_properties_systemspecialfolder(TALLOC_CTX *mem_ctx, struct emsmdbp_context *emsmdbp_ctx, struct emsmdbp_object *object, struct SPropTagArray *properties, void **data_pointers, enum MAPISTATUS *retvals) { enum MAPISTATUS retval = MAPI_E_SUCCESS; struct emsmdbp_object_folder *folder; char *owner; int i; uint32_t *obj_count; uint8_t *has_subobj; struct Binary_r *binr; time_t unix_time; NTTIME nt_time; struct FILETIME *ft; folder = (struct emsmdbp_object_folder *) object->object.folder; for (i = 0; i < properties->cValues; i++) { if (properties->aulPropTag[i] == PR_FOLDER_CHILD_COUNT) { obj_count = talloc_zero(data_pointers, uint32_t); retval = openchangedb_get_folder_count(emsmdbp_ctx->oc_ctx, object->object.folder->folderID, obj_count); data_pointers[i] = obj_count; } else if (properties->aulPropTag[i] == PR_SUBFOLDERS) { obj_count = talloc_zero(NULL, uint32_t); retval = openchangedb_get_folder_count(emsmdbp_ctx->oc_ctx, object->object.folder->folderID, obj_count); has_subobj = talloc_zero(data_pointers, uint8_t); *has_subobj = (*obj_count > 0) ? 1 : 0; data_pointers[i] = has_subobj; talloc_free(obj_count); } else if (properties->aulPropTag[i] == PR_SOURCE_KEY) { owner = emsmdbp_get_owner(object); emsmdbp_source_key_from_fmid(data_pointers, emsmdbp_ctx, owner, object->object.folder->folderID, &binr); data_pointers[i] = binr; retval = MAPI_E_SUCCESS; } else if (properties->aulPropTag[i] == PR_CONTENT_COUNT || properties->aulPropTag[i] == PidTagAssociatedContentCount || properties->aulPropTag[i] == PR_CONTENT_UNREAD || properties->aulPropTag[i] == PR_DELETED_COUNT_TOTAL) { obj_count = talloc_zero(data_pointers, uint32_t); *obj_count = 0; data_pointers[i] = obj_count; retval = MAPI_E_SUCCESS; } else if (properties->aulPropTag[i] == PidTagLocalCommitTimeMax) { /* TODO: temporary hack */ unix_time = time(NULL) & 0xffffff00; unix_to_nt_time(&nt_time, unix_time); ft = talloc_zero(data_pointers, struct FILETIME); ft->dwLowDateTime = (nt_time & 0xffffffff); ft->dwHighDateTime = nt_time >> 32; data_pointers[i] = ft; retval = MAPI_E_SUCCESS; } else { retval = openchangedb_get_folder_property(data_pointers, emsmdbp_ctx->oc_ctx, properties->aulPropTag[i], folder->folderID, data_pointers + i); } retvals[i] = retval; } return MAPISTORE_SUCCESS; } static int emsmdbp_object_get_properties_message(TALLOC_CTX *mem_ctx, struct emsmdbp_context *emsmdbp_ctx, struct emsmdbp_object *object, struct SPropTagArray *properties, void **data_pointers, enum MAPISTATUS *retvals) { enum MAPISTATUS retval; int i; char *owner, *email_address; struct Binary_r *binr; struct mapistore_freebusy_properties *fb_props; struct LongArray_r *long_array; struct BinaryArray_r *bin_array; fb_props = object->object.message->fb_properties; owner = emsmdbp_get_owner(object); /* FIXME: this is wrong, as the CN attribute may differ from the user's username (sAMAccountName) */ email_address = talloc_asprintf(data_pointers, "/o=First Organization/ou=First Administrative Group/cn=Recipients/cn=%s", owner); /* Look over properties */ for (i = 0; i < properties->cValues; i++) { if (properties->aulPropTag[i] == PR_SOURCE_KEY) { emsmdbp_source_key_from_fmid(data_pointers, emsmdbp_ctx, owner, object->object.message->folderID, &binr); data_pointers[i] = binr; retval = MAPI_E_SUCCESS; } else { if (fb_props) { switch (properties->aulPropTag[i]) { case PR_SCHDINFO_MONTHS_TENTATIVE: case PR_SCHDINFO_MONTHS_BUSY: case PR_SCHDINFO_MONTHS_OOF: case PR_SCHDINFO_MONTHS_MERGED: long_array = talloc_zero(data_pointers, struct LongArray_r); long_array->cValues = fb_props->nbr_months; long_array->lpl = fb_props->months_ranges; data_pointers[i] = long_array; retval = MAPI_E_SUCCESS; break; case PR_SCHDINFO_FREEBUSY_TENTATIVE: bin_array = talloc_zero(data_pointers, struct BinaryArray_r); bin_array->cValues = fb_props->nbr_months; bin_array->lpbin = fb_props->freebusy_tentative; data_pointers[i] = bin_array; retval = MAPI_E_SUCCESS; break; case PR_SCHDINFO_FREEBUSY_BUSY: bin_array = talloc_zero(data_pointers, struct BinaryArray_r); bin_array->cValues = fb_props->nbr_months; bin_array->lpbin = fb_props->freebusy_busy; data_pointers[i] = bin_array; retval = MAPI_E_SUCCESS; break; case PR_SCHDINFO_FREEBUSY_OOF: bin_array = talloc_zero(data_pointers, struct BinaryArray_r); bin_array->cValues = fb_props->nbr_months; bin_array->lpbin = fb_props->freebusy_away; data_pointers[i] = bin_array; retval = MAPI_E_SUCCESS; break; case PR_SCHDINFO_FREEBUSY_MERGED: bin_array = talloc_zero(data_pointers, struct BinaryArray_r); bin_array->cValues = fb_props->nbr_months; bin_array->lpbin = fb_props->freebusy_merged; data_pointers[i] = bin_array; retval = MAPI_E_SUCCESS; break; case PR_FREEBUSY_PUBLISH_START: data_pointers[i] = &fb_props->publish_start; retval = MAPI_E_SUCCESS; break; case PR_FREEBUSY_PUBLISH_END: data_pointers[i] = &fb_props->publish_end; retval = MAPI_E_SUCCESS; break; case PidTagFreeBusyMessageEmailAddress: data_pointers[i] = email_address; retval = MAPI_E_SUCCESS; break; case PR_FREEBUSY_RANGE_TIMESTAMP: data_pointers[i] = &fb_props->timestamp; retval = MAPI_E_SUCCESS; break; default: retval = openchangedb_message_get_property(data_pointers, object->backend_object, properties->aulPropTag[i], data_pointers + i); } } else { retval = openchangedb_message_get_property(data_pointers, object->backend_object, properties->aulPropTag[i], data_pointers + i); } } retvals[i] = retval; } return MAPI_E_SUCCESS; } static int emsmdbp_object_get_properties_mapistore_root(TALLOC_CTX *mem_ctx, struct emsmdbp_context *emsmdbp_ctx, struct emsmdbp_object *object, struct SPropTagArray *properties, void **data_pointers, enum MAPISTATUS *retvals) { enum MAPISTATUS retval = MAPI_E_SUCCESS; struct emsmdbp_object_folder *folder; char *owner; struct Binary_r *binr; int i; uint32_t contextID; uint32_t *obj_count; uint8_t *has_subobj; /* time_t unix_time; */ /* NTTIME nt_time; */ /* struct FILETIME *ft; */ contextID = emsmdbp_get_contextID(object); folder = (struct emsmdbp_object_folder *) object->object.folder; for (i = 0; i < properties->cValues; i++) { if (properties->aulPropTag[i] == PR_CONTENT_COUNT) { /* a hack to avoid fetching dynamic fields from openchange.ldb */ obj_count = talloc_zero(data_pointers, uint32_t); retval = mapistore_folder_get_child_count(emsmdbp_ctx->mstore_ctx, contextID, object->backend_object, MAPISTORE_MESSAGE_TABLE, obj_count); if (!retval) { data_pointers[i] = obj_count; } } else if (properties->aulPropTag[i] == PidTagAssociatedContentCount) { obj_count = talloc_zero(data_pointers, uint32_t); retval = mapistore_folder_get_child_count(emsmdbp_ctx->mstore_ctx, emsmdbp_get_contextID(object), object->backend_object, MAPISTORE_FAI_TABLE, obj_count); if (!retval) { data_pointers[i] = obj_count; } } else if (properties->aulPropTag[i] == PR_FOLDER_CHILD_COUNT) { obj_count = talloc_zero(data_pointers, uint32_t); retval = emsmdbp_folder_get_folder_count(emsmdbp_ctx, object, obj_count); if (!retval) { data_pointers[i] = obj_count; } } else if (properties->aulPropTag[i] == PR_SUBFOLDERS) { obj_count = talloc_zero(NULL, uint32_t); retval = emsmdbp_folder_get_folder_count(emsmdbp_ctx, object, obj_count); if (!retval) { has_subobj = talloc_zero(data_pointers, uint8_t); *has_subobj = (*obj_count > 0) ? 1 : 0; data_pointers[i] = has_subobj; } talloc_free(obj_count); } else if (properties->aulPropTag[i] == PR_SOURCE_KEY) { owner = emsmdbp_get_owner(object); emsmdbp_source_key_from_fmid(data_pointers, emsmdbp_ctx, owner, object->object.folder->folderID, &binr); data_pointers[i] = binr; retval = MAPI_E_SUCCESS; } else if (properties->aulPropTag[i] == PR_FOLDER_TYPE) { obj_count = talloc_zero(data_pointers, uint32_t); *obj_count = FOLDER_GENERIC; data_pointers[i] = obj_count; retval = MAPI_E_SUCCESS; } else if (properties->aulPropTag[i] == PR_CONTENT_UNREAD || properties->aulPropTag[i] == PR_DELETED_COUNT_TOTAL) { /* TODO: temporary hack */ obj_count = talloc_zero(data_pointers, uint32_t); *obj_count = 0; data_pointers[i] = obj_count; retval = MAPI_E_SUCCESS; } else if (properties->aulPropTag[i] == PidTagLocalCommitTimeMax || properties->aulPropTag[i] == PR_RIGHTS || properties->aulPropTag[i] == PR_ACCESS || properties->aulPropTag[i] == PR_ACCESS_LEVEL || properties->aulPropTag[i] == PidTagRights || properties->aulPropTag[i] == PidTagAccessControlListData || properties->aulPropTag[i] == PidTagExtendedACLData) { struct mapistore_property_data prop_data; mapistore_properties_get_properties(emsmdbp_ctx->mstore_ctx, contextID, object->backend_object, data_pointers, 1, properties->aulPropTag + i, &prop_data); data_pointers[i] = prop_data.data; if (prop_data.error) { retval = mapistore_error_to_mapi(prop_data.error); } else { if (prop_data.data == NULL) { retval = MAPI_E_NOT_FOUND; } else { retval = MAPI_E_SUCCESS; } } } else { retval = openchangedb_get_folder_property(data_pointers, emsmdbp_ctx->oc_ctx, properties->aulPropTag[i], folder->folderID, data_pointers + i); } retvals[i] = retval; } return MAPISTORE_SUCCESS; } static int emsmdbp_object_get_properties_mailbox(TALLOC_CTX *mem_ctx, struct emsmdbp_context *emsmdbp_ctx, struct emsmdbp_object *object, struct SPropTagArray *properties, void **data_pointers, enum MAPISTATUS *retvals) { uint32_t i; struct SBinary_short *bin; for (i = 0; i < properties->cValues; i++) { switch (properties->aulPropTag[i]) { case PR_MAPPING_SIGNATURE: case PidTagIpmPublicFoldersEntryId: retvals[i] = MAPI_E_NO_ACCESS; break; case PR_USER_ENTRYID: bin = talloc_zero(data_pointers, struct SBinary_short); retvals[i] = entryid_set_AB_EntryID(data_pointers, object->object.mailbox->szUserDN, bin); data_pointers[i] = bin; break; case PR_MAILBOX_OWNER_ENTRYID: if (object->object.mailbox->mailboxstore == false) { retvals[i] = MAPI_E_NO_ACCESS; } else { bin = talloc_zero(data_pointers, struct SBinary_short); retvals[i] = entryid_set_AB_EntryID(data_pointers, object->object.mailbox->owner_EssDN, bin); data_pointers[i] = bin; } break; case PidTagMailboxOwnerName: if (object->object.mailbox->mailboxstore == false) { retvals[i] = MAPI_E_NO_ACCESS; } else { retvals[i] = MAPI_E_SUCCESS; data_pointers[i] = talloc_strdup(data_pointers, object->object.mailbox->owner_Name); } break; default: retvals[i] = openchangedb_get_folder_property(data_pointers, emsmdbp_ctx->oc_ctx, properties->aulPropTag[i], object->object.mailbox->folderID, data_pointers + i); } } return MAPISTORE_SUCCESS; } static int emsmdbp_object_get_properties_mapistore(TALLOC_CTX *mem_ctx, struct emsmdbp_context *emsmdbp_ctx, struct emsmdbp_object *object, struct SPropTagArray *properties, void **data_pointers, enum MAPISTATUS *retvals) { uint32_t contextID = -1; struct mapistore_property_data *prop_data; int i, ret; contextID = emsmdbp_get_contextID(object); prop_data = talloc_array(NULL, struct mapistore_property_data, properties->cValues); memset(prop_data, 0, sizeof(struct mapistore_property_data) * properties->cValues); ret = mapistore_properties_get_properties(emsmdbp_ctx->mstore_ctx, contextID, object->backend_object, prop_data, properties->cValues, properties->aulPropTag, prop_data); if (ret == MAPISTORE_SUCCESS) { for (i = 0; i < properties->cValues; i++) { if (prop_data[i].error) { retvals[i] = mapistore_error_to_mapi(prop_data[i].error); } else { if (prop_data[i].data == NULL) { retvals[i] = MAPI_E_NOT_FOUND; } else { data_pointers[i] = prop_data[i].data; (void) talloc_reference(data_pointers, prop_data[i].data); } } } } talloc_free(prop_data); return ret; } _PUBLIC_ void **emsmdbp_object_get_properties(TALLOC_CTX *mem_ctx, struct emsmdbp_context *emsmdbp_ctx, struct emsmdbp_object *object, struct SPropTagArray *properties, enum MAPISTATUS **retvalsp) { void **data_pointers; enum MAPISTATUS *retvals; bool mapistore; int retval = MAPISTORE_SUCCESS; data_pointers = talloc_array(mem_ctx, void *, properties->cValues); memset(data_pointers, 0, sizeof(void *) * properties->cValues); retvals = talloc_array(mem_ctx, enum MAPISTATUS, properties->cValues); memset(retvals, 0, sizeof(enum MAPISTATUS) * properties->cValues); /* Temporary hack: If this is a mapistore root container * (e.g. Inbox, Calendar etc.), directly stored under * IPM.Subtree, then fetch properties from openchange * dispatcher db, not mapistore */ if (object && object->type == EMSMDBP_OBJECT_FOLDER && object->object.folder->mapistore_root == true) { if (object->object.folder->postponed_props) { emsmdbp_object_folder_commit_creation(emsmdbp_ctx, object, true); } retval = emsmdbp_object_get_properties_mapistore_root(mem_ctx, emsmdbp_ctx, object, properties, data_pointers, retvals); } else { mapistore = emsmdbp_is_mapistore(object); /* Nasty hack */ if (!object) { DEBUG(5, ("[%s] what's that hack!??\n", __location__)); mapistore = true; } switch (mapistore) { case false: switch (object->type) { case EMSMDBP_OBJECT_MAILBOX: retval = emsmdbp_object_get_properties_mailbox(mem_ctx, emsmdbp_ctx, object, properties, data_pointers, retvals); break; case EMSMDBP_OBJECT_FOLDER: retval = emsmdbp_object_get_properties_systemspecialfolder(mem_ctx, emsmdbp_ctx, object, properties, data_pointers, retvals); break; case EMSMDBP_OBJECT_MESSAGE: retval = emsmdbp_object_get_properties_message(mem_ctx, emsmdbp_ctx, object, properties, data_pointers, retvals); break; default: retval = MAPISTORE_ERROR; break; } break; case true: /* folder or messages handled by mapistore */ retval = emsmdbp_object_get_properties_mapistore(mem_ctx, emsmdbp_ctx, object, properties, data_pointers, retvals); break; } } if (retvalsp) { *retvalsp = retvals; } if (retval) { talloc_free(data_pointers); data_pointers = NULL; } return data_pointers; } /* TODO: handling of "property problems" */ _PUBLIC_ int emsmdbp_object_set_properties(struct emsmdbp_context *emsmdbp_ctx, struct emsmdbp_object *object, struct SRow *rowp) { TALLOC_CTX *mem_ctx; uint32_t contextID, new_cvalues; char *mapistore_uri, *new_uri; size_t mapistore_uri_len, new_uri_len; bool mapistore; enum mapistore_error ret; struct SRow *postponed_props; bool soft_deleted; /* Sanity checks */ if (!emsmdbp_ctx) return MAPI_E_CALL_FAILED; if (!object) return MAPI_E_CALL_FAILED; if (!rowp) return MAPI_E_CALL_FAILED; if (!(object->type == EMSMDBP_OBJECT_FOLDER || object->type == EMSMDBP_OBJECT_MAILBOX || object->type == EMSMDBP_OBJECT_MESSAGE || object->type == EMSMDBP_OBJECT_ATTACHMENT)) { DEBUG(0, (__location__": object must be EMSMDBP_OBJECT_FOLDER, EMSMDBP_OBJECT_MAILBOX, EMSMDBP_OBJECT_MESSAGE or EMSMDBP_OBJECT_ATTACHMENT (type = %d)\n", object->type)); return MAPI_E_NO_SUPPORT; } if (object->type == EMSMDBP_OBJECT_FOLDER) { postponed_props = object->object.folder->postponed_props; if (postponed_props) { new_cvalues = postponed_props->cValues + rowp->cValues; postponed_props->lpProps = talloc_realloc(postponed_props, postponed_props->lpProps, struct SPropValue, new_cvalues); mapi_copy_spropvalues(postponed_props, rowp->lpProps, postponed_props->lpProps + postponed_props->cValues, rowp->cValues); postponed_props->cValues = new_cvalues; ret = emsmdbp_object_folder_commit_creation(emsmdbp_ctx, object, false); if (ret == MAPISTORE_SUCCESS) { return MAPI_E_SUCCESS; } else { return MAPI_E_NOT_FOUND; } } } /* Temporary hack: If this is a mapistore root container * (e.g. Inbox, Calendar etc.), directly stored under * IPM.Subtree, then set properties from openchange * dispatcher db, not mapistore */ if (object->type == EMSMDBP_OBJECT_FOLDER && object->object.folder->mapistore_root == true) { mem_ctx = talloc_zero(NULL, TALLOC_CTX); mapistore_uri = NULL; openchangedb_get_mapistoreURI(mem_ctx, emsmdbp_ctx->oc_ctx, object->object.folder->folderID, &mapistore_uri, true); openchangedb_set_folder_properties(emsmdbp_ctx->oc_ctx, object->object.folder->folderID, rowp); contextID = emsmdbp_get_contextID(object); mapistore_properties_set_properties(emsmdbp_ctx->mstore_ctx, contextID, object->backend_object, rowp); /* if the display name of a resource has changed, some backends may have modified the folder uri and we need to update the openchangedb record accordingly */ if (mapistore_uri) { new_uri = NULL; mapistore_indexing_record_get_uri(emsmdbp_ctx->mstore_ctx, emsmdbp_ctx->username, mem_ctx, object->object.folder->folderID, &new_uri, &soft_deleted); if (new_uri) { mapistore_uri_len = strlen(mapistore_uri); new_uri_len = strlen(new_uri); /* handling of the final '/' */ if (mapistore_uri[mapistore_uri_len-1] == '/') { if (new_uri[new_uri_len-1] != '/') { new_uri = talloc_asprintf(mem_ctx, "%s/", new_uri); new_uri_len++; } } else { if (new_uri[new_uri_len-1] == '/') { new_uri[new_uri_len-1] = 0; new_uri_len--; } } if (strcmp(mapistore_uri, new_uri) != 0) { openchangedb_set_mapistoreURI(emsmdbp_ctx->oc_ctx, object->object.folder->folderID, new_uri, true); } } } talloc_free(mem_ctx); } else { contextID = emsmdbp_get_contextID(object); mapistore = emsmdbp_is_mapistore(object); switch (mapistore) { case false: if (object->type == EMSMDBP_OBJECT_FOLDER) { openchangedb_set_folder_properties(emsmdbp_ctx->oc_ctx, object->object.folder->folderID, rowp); } else if (object->type == EMSMDBP_OBJECT_MAILBOX) { openchangedb_set_folder_properties(emsmdbp_ctx->oc_ctx, object->object.mailbox->folderID, rowp); } else if (object->type == EMSMDBP_OBJECT_MESSAGE) { openchangedb_message_set_properties((TALLOC_CTX *)object->object.message, object->backend_object, rowp); } else { DEBUG(0, ("Setting properties on openchangedb not implemented yet for non-folder object type\n")); return MAPI_E_NO_SUPPORT; } break; case true: mapistore_properties_set_properties(emsmdbp_ctx->mstore_ctx, contextID, object->backend_object, rowp); break; } } return MAPI_E_SUCCESS; } _PUBLIC_ void emsmdbp_fill_row_blob(TALLOC_CTX *mem_ctx, struct emsmdbp_context *emsmdbp_ctx, uint8_t *layout, DATA_BLOB *property_row, struct SPropTagArray *properties, void **data_pointers, enum MAPISTATUS *retvals, bool *untyped_status) { uint16_t i; uint8_t flagged; enum MAPITAGS property; void *data; uint32_t retval; flagged = 0; for (i = 0; !flagged && i < properties->cValues; i++) { if (retvals[i] != MAPI_E_SUCCESS || untyped_status[i] || !data_pointers[i]) { flagged = 1; } } *layout = flagged; for (i = 0; i < properties->cValues; i++) { retval = retvals[i]; if (retval != MAPI_E_SUCCESS) { property = (properties->aulPropTag[i] & 0xFFFF0000) + PT_ERROR; data = &retval; } else { property = properties->aulPropTag[i]; data = data_pointers[i]; } libmapiserver_push_property(mem_ctx, property, data, property_row, flagged ? PT_ERROR : 0, flagged, untyped_status[i]); } } _PUBLIC_ struct emsmdbp_stream_data *emsmdbp_stream_data_from_value(TALLOC_CTX *mem_ctx, enum MAPITAGS prop_tag, void *value, bool read_write) { uint16_t prop_type; struct emsmdbp_stream_data *stream_data; size_t converted_size; stream_data = talloc_zero(mem_ctx, struct emsmdbp_stream_data); stream_data->prop_tag = prop_tag; prop_type = prop_tag & 0xffff; if (prop_type == PT_STRING8) { stream_data->data.length = strlen(value) + 1; stream_data->data.data = value; (void) talloc_reference(stream_data, stream_data->data.data); } else if (prop_type == PT_UNICODE) { stream_data->data.length = strlen_m_ext((char *) value, CH_UTF8, CH_UTF16LE) * 2; stream_data->data.data = talloc_array(stream_data, uint8_t, stream_data->data.length + 2); convert_string(CH_UTF8, CH_UTF16LE, value, strlen(value), stream_data->data.data, stream_data->data.length, &converted_size); memset(stream_data->data.data + stream_data->data.length, 0, 2 * sizeof(uint8_t)); } else if (prop_type == PT_BINARY) { stream_data->data.length = ((struct Binary_r *) value)->cb; if (read_write) { stream_data->data.data = talloc_memdup(stream_data, ((struct Binary_r *) value)->lpb, stream_data->data.length); } else { stream_data->data.data = ((struct Binary_r *) value)->lpb; } (void) talloc_reference(stream_data, value); } else { talloc_free(stream_data); return NULL; } return stream_data; } _PUBLIC_ DATA_BLOB emsmdbp_stream_read_buffer(struct emsmdbp_stream *stream, uint32_t length) { DATA_BLOB buffer; uint32_t real_length; real_length = length; if (real_length + stream->position > stream->buffer.length) { real_length = stream->buffer.length - stream->position; } buffer.length = real_length; buffer.data = stream->buffer.data + stream->position; stream->position += real_length; return buffer; } _PUBLIC_ void emsmdbp_stream_write_buffer(TALLOC_CTX *mem_ctx, struct emsmdbp_stream *stream, DATA_BLOB new_buffer) { size_t new_position; uint32_t old_length; uint8_t *old_data; new_position = stream->position + new_buffer.length; if (new_position >= stream->buffer.length) { old_length = stream->buffer.length; stream->buffer.length = new_position; if (stream->buffer.data) { old_data = stream->buffer.data; stream->buffer.data = talloc_realloc(mem_ctx, stream->buffer.data, uint8_t, stream->buffer.length); if (!stream->buffer.data) { DEBUG(5, ("WARNING: [bug] lost buffer pointer (data = NULL)\n")); stream->buffer.data = talloc_array(mem_ctx, uint8_t, stream->buffer.length); memcpy(stream->buffer.data, old_data, old_length); } } else { stream->buffer.data = talloc_array(mem_ctx, uint8_t, stream->buffer.length); } } memcpy(stream->buffer.data + stream->position, new_buffer.data, new_buffer.length); stream->position = new_position; } _PUBLIC_ struct emsmdbp_stream_data *emsmdbp_object_get_stream_data(struct emsmdbp_object *object, enum MAPITAGS prop_tag) { struct emsmdbp_stream_data *current_data; for (current_data = object->stream_data; current_data; current_data = current_data->next) { if (current_data->prop_tag == prop_tag) { DEBUG(5, ("[%s]: found data for tag %.8x\n", __FUNCTION__, prop_tag)); return current_data; } } return NULL; } /** \details Initialize a synccontext object \param mem_ctx pointer to the memory context \param emsmdbp_ctx pointer to the emsmdb provider cotnext \param whole_store whether the subscription applies to the specified change on the entire store or stricly on the specified folder/message \param folderID the folder identifier \param messageID the message identifier \param parent emsmdbp object of the parent */ _PUBLIC_ struct emsmdbp_object *emsmdbp_object_synccontext_init(TALLOC_CTX *mem_ctx, struct emsmdbp_context *emsmdbp_ctx, struct emsmdbp_object *parent_object) { struct emsmdbp_object *synccontext_object; /* Sanity checks */ if (!emsmdbp_ctx) return NULL; if (!parent_object) return NULL; if (!(parent_object->type == EMSMDBP_OBJECT_FOLDER || parent_object->type == EMSMDBP_OBJECT_MAILBOX)) { DEBUG(0, (__location__": parent_object must be EMSMDBP_OBJECT_FOLDER or EMSMDBP_OBJECT_MAILBOX (type = %d)\n", parent_object->type)); return NULL; } synccontext_object = emsmdbp_object_init(mem_ctx, emsmdbp_ctx, parent_object); if (!synccontext_object) return NULL; synccontext_object->object.synccontext = talloc_zero(synccontext_object, struct emsmdbp_object_synccontext); if (!synccontext_object->object.synccontext) { talloc_free(synccontext_object); return NULL; } synccontext_object->type = EMSMDBP_OBJECT_SYNCCONTEXT; (void) talloc_reference(synccontext_object->object.synccontext, parent_object); synccontext_object->object.synccontext->state_property = 0; synccontext_object->object.synccontext->state_stream.buffer.length = 0; synccontext_object->object.synccontext->state_stream.buffer.data = talloc_zero(synccontext_object->object.synccontext, uint8_t); synccontext_object->object.synccontext->stream.buffer.length = 0; synccontext_object->object.synccontext->stream.buffer.data = NULL; synccontext_object->object.synccontext->cnset_seen = talloc_zero(emsmdbp_ctx, struct idset); openchangedb_get_MailboxReplica(emsmdbp_ctx->oc_ctx, emsmdbp_ctx->username, NULL, &synccontext_object->object.synccontext->cnset_seen->repl.guid); synccontext_object->object.synccontext->cnset_seen->ranges = talloc_zero(synccontext_object->object.synccontext->cnset_seen, struct globset_range); synccontext_object->object.synccontext->cnset_seen->range_count = 1; synccontext_object->object.synccontext->cnset_seen->ranges->next = NULL; synccontext_object->object.synccontext->cnset_seen->ranges->prev = synccontext_object->object.synccontext->cnset_seen->ranges; synccontext_object->object.synccontext->cnset_seen->ranges->low = 0xffffffffffffffffLL; synccontext_object->object.synccontext->cnset_seen->ranges->high = 0x0; /* synccontext_object->object.synccontext->property_tags.cValues = 0; */ /* synccontext_object->object.synccontext->property_tags.aulPropTag = NULL; */ return synccontext_object; } /** \details Initialize a ftcontext object \param mem_ctx pointer to the memory context \param emsmdbp_ctx pointer to the emsmdb provider cotnext \param whole_store whether the subscription applies to the specified change on the entire store or stricly on the specified folder/message \param folderID the folder identifier \param messageID the message identifier \param parent emsmdbp object of the parent */ _PUBLIC_ struct emsmdbp_object *emsmdbp_object_ftcontext_init(TALLOC_CTX *mem_ctx, struct emsmdbp_context *emsmdbp_ctx, struct emsmdbp_object *parent) { struct emsmdbp_object *object; /* Sanity checks */ if (!emsmdbp_ctx) return NULL; if (!parent) return NULL; object = emsmdbp_object_init(mem_ctx, emsmdbp_ctx, parent); if (!object) return NULL; object->object.ftcontext = talloc_zero(object, struct emsmdbp_object_ftcontext); if (!object->object.ftcontext) { talloc_free(object); return NULL; } object->type = EMSMDBP_OBJECT_FTCONTEXT; return object; } openchange-2.0/mapiproxy/servers/default/emsmdb/emsmdbp_provisioning.c000066400000000000000000000734221223057412600265110ustar00rootroot00000000000000/* OpenChange Server implementation EMSMDBP: EMSMDB Provider implementation Copyright (C) Wolfgang Sourdeau 2012 This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see . */ /** \file emsmdbp_provisioning.c \brief Account provisioning */ #include #include #include #include "dcesrv_exchange_emsmdb.h" #include _PUBLIC_ enum MAPISTATUS emsmdbp_mailbox_provision_public_freebusy(struct emsmdbp_context *emsmdbp_ctx, const char *EssDN) { enum MAPISTATUS ret; char *dn_root, *dn_user, *cn_ptr; uint64_t public_fb_fid, group_fid, fb_mid, change_num; size_t i, max; void *message_object; struct SRow property_row; TALLOC_CTX *mem_ctx; mem_ctx = talloc_zero(NULL, TALLOC_CTX); dn_root = talloc_asprintf(mem_ctx, "EX:%s", EssDN); cn_ptr = strstr(dn_root, "/cn"); if (!cn_ptr) { ret = MAPI_E_INVALID_PARAMETER; goto end; } dn_user = talloc_asprintf(mem_ctx, "USER-%s", cn_ptr); *cn_ptr = 0; /* convert dn_root to lowercase */ max = cn_ptr - dn_root; for (i = 3; i < max; i++) { dn_root[i] = tolower(dn_root[i]); } /* convert dn_user to uppercase. Yes, it's stupid like that. */ max = strlen(dn_user); for (i = 5; i < max; i++) { dn_user[i] = toupper(dn_user[i]); } ret = openchangedb_get_PublicFolderID(emsmdbp_ctx->oc_ctx, EMSMDBP_PF_FREEBUSY, &public_fb_fid); if (ret != MAPI_E_SUCCESS) { DEBUG(5, ("provisioning: freebusy root folder not found in openchange.ldb\n")); goto end; } ret = openchangedb_get_fid_by_name(emsmdbp_ctx->oc_ctx, public_fb_fid, dn_root, &group_fid); if (ret != MAPI_E_SUCCESS) { openchangedb_get_new_folderID(emsmdbp_ctx->oc_ctx, &group_fid); openchangedb_get_new_changeNumber(emsmdbp_ctx->oc_ctx, &change_num); openchangedb_create_folder(emsmdbp_ctx->oc_ctx, public_fb_fid, group_fid, change_num, NULL, -1); } ret = openchangedb_get_mid_by_subject(emsmdbp_ctx->oc_ctx, group_fid, dn_user, false, &fb_mid); if (ret != MAPI_E_SUCCESS) { openchangedb_get_new_folderID(emsmdbp_ctx->oc_ctx, &fb_mid); openchangedb_get_new_changeNumber(emsmdbp_ctx->oc_ctx, &change_num); openchangedb_message_create(mem_ctx, emsmdbp_ctx->oc_ctx, fb_mid, group_fid, false, &message_object); property_row.cValues = 1; property_row.lpProps = talloc_zero(mem_ctx, struct SPropValue); property_row.lpProps[0].ulPropTag = PR_NORMALIZED_SUBJECT_UNICODE; property_row.lpProps[0].value.lpszW = dn_user; openchangedb_message_set_properties(mem_ctx, message_object, &property_row); openchangedb_message_save(message_object, 0); } ret = MAPI_E_SUCCESS; end: talloc_free(mem_ctx); return ret; } _PUBLIC_ enum MAPISTATUS emsmdbp_mailbox_provision(struct emsmdbp_context *emsmdbp_ctx, const char *username) { /* auto-provisioning: During private logon: - fetch list of available folders from all backends + list of capabilities (handled folder types) + fallback entry - if fallback is not available: FAIL - fetch list of existing folders from openchangedb - if mailbox does not exist: - create basic structure - if certain folders are not available (Inbox, Deleted Items, Spooler Queue, Outbox), use fallback - synchronize list of non-mandatory and secondary folders - update relevant entry ids in relevant objects - ability to leave creation of fallback and other url to the relevant backend - freebusy entry folder creation = createfolder + setprops (class) + release * RopLogon entries (mandatory) (autoprovisioning) mailbox (Root): (None) "Common Views": (None) (sogo://wsourdeau:wsourdeau@common-views/) -> fallback "Deferred Action": (None) (sogo://wsourdeau:wsourdeau@deferred-actions/) -> fallback "Search" (Finder): None (sogo://wsourdeau:wsourdeau@search/) -> fallback "Schedule": (None) (sogo://wsourdeau:wsourdeau@schedule/) -> fallback "Shortcuts": (None) (sogo://wsourdeau:wsourdeau@shortcuts/) -> fallback "Spooler Queue": (None) (sogo://wsourdeau:wsourdeau@spooler-queue/) -> fallback "Views": (sogo://wsourdeau:wsourdeau@views/) -> fallback "IPM Subtree" (Top of Personal Folders): (None) * autoprovisioning backend based "Inbox": IPF.Note (sogo://wsourdeau:wsourdeau@inbox/) "Outbox": IPF.Note (sogo://wsourdeau:wsourdeau@outbox/) "Sent Items": IPF.Note (sogo://wsourdeau:wsourdeau@sent-items/) "Deleted Items": IPF.Note (sogo://wsourdeau:wsourdeau@deleted-items/) * additional special folders "Calendar": IPF.Appointment (PidTagIpmAppointmentEntryId) "Contacts": IPF.Contact (PidTagIpmContactEntryId) "Notes": IPF.StickyNote (PidTagIpmNoteEntryId) "Tasks": IPF.Task (PidTagIpmTaskEntryId) "Journal": IPF.Journal (PidTagIpmJournalEntryId) "Drafts": IPF.Note (PidTagIpmDraftsEntryId) * client-created: "Freebusy Data": "Reminders": Outlook.Reminder (sogo://wsourdeau:wsourdeau@reminders/) (PidTagRemindersOnlineEntryId) -> fallback "To-Do blabnla" "Sync Issues": IPF.Note (PidTagAdditionalRenEntryIds) "Junk E-mail": IPF.Note (PidTagAdditionalRenEntryIds) ... Exchange hierarchy for virgin account: FolderId: 0x67ca828f02000001 Display Name: " "; Container Class: MAPI_E_NOT_FOUND; Message Class: MAPI_E_NOT_FOUND; Has Subfolders: TRUE; FolderId: 0x71ca828f02000001 Display Name: " Common Views"; Container Class: MAPI_E_NOT_FOUND; Message Class: MAPI_E_NOT_FOUND; Has Subfolders: FALSE; FolderId: 0x69ca828f02000001 Display Name: " Deferred Action"; Container Class: MAPI_E_NOT_FOUND; Message Class: MAPI_E_NOT_FOUND; Has Subfolders: FALSE; FolderId: 0x6fca828f02000001 Display Name: " Finder"; Container Class: MAPI_E_NOT_FOUND; Message Class: MAPI_E_NOT_FOUND; Has Subfolders: FALSE; FolderId: 0x72ca828f02000001 Display Name: " Schedule"; Container Class: MAPI_E_NOT_FOUND; Message Class: MAPI_E_NOT_FOUND; Has Subfolders: FALSE; FolderId: 0x73ca828f02000001 Display Name: " Shortcuts"; Container Class: MAPI_E_NOT_FOUND; Message Class: MAPI_E_NOT_FOUND; Has Subfolders: FALSE; FolderId: 0x6aca828f02000001 Display Name: " Spooler Queue"; Container Class: MAPI_E_NOT_FOUND; Message Class: MAPI_E_NOT_FOUND; Has Subfolders: FALSE; FolderId: 0x70ca828f02000001 Display Name: " Views"; Container Class: MAPI_E_NOT_FOUND; Message Class: MAPI_E_NOT_FOUND; Has Subfolders: FALSE; FolderId: 0x68ca828f02000001 Display Name: "Top of Information Store"; Container Class: MAPI_E_NOT_FOUND; Message Class: MAPI_E_NOT_FOUND; Has Subfolders: TRUE; FolderId: 0x6bca828f02000001 Display Name: " Boîte de réception"; Container Class: " IPF.Note"; Message Class: MAPI_E_NOT_FOUND; Has Subfolders: FALSE; FolderId: 0x6cca828f02000001 Display Name: " Boîte d'envoi"; Container Class: " IPF.Note"; Message Class: MAPI_E_NOT_FOUND; Has Subfolders: FALSE; FolderId: 0x67c3828f02000001 Display Name: " Brouillons"; Container Class: " IPF.Note"; Message Class: MAPI_E_NOT_FOUND; Has Subfolders: FALSE; FolderId: 0x65c3828f02000001 Display Name: " Calendrier"; Container Class: " IPF.Appointment"; Message Class: MAPI_E_NOT_FOUND; Has Subfolders: FALSE; FolderId: 0x66c3828f02000001 Display Name: " Contacts"; Container Class: " IPF.Contact"; Message Class: MAPI_E_NOT_FOUND; Has Subfolders: FALSE; FolderId: 0x6dca828f02000001 Display Name: " Éléments envoyés"; Container Class: " IPF.Note"; Message Class: MAPI_E_NOT_FOUND; Has Subfolders: FALSE; FolderId: 0x6eca828f02000001 Display Name: " Éléments supprimés"; Container Class: " IPF.Note"; Message Class: MAPI_E_NOT_FOUND; Has Subfolders: FALSE; FolderId: 0x68c3828f02000001 Display Name: " Journal"; Container Class: " IPF.Journal"; Message Class: MAPI_E_NOT_FOUND; Has Subfolders: FALSE; FolderId: 0x69c3828f02000001 Display Name: " Notes"; Container Class: " IPF.StickyNote"; Message Class: MAPI_E_NOT_FOUND; Has Subfolders: FALSE; FolderId: 0x6ac3828f02000001 Display Name: " Tâches"; Container Class: " IPF.Task"; Message Class: MAPI_E_NOT_FOUND; Has Subfolders: FALSE; */ TALLOC_CTX *mem_ctx; enum MAPISTATUS ret; enum mapistore_error retval; struct mapistore_contexts_list *contexts_list; struct StringArrayW_r *existing_uris; struct mapistore_contexts_list *main_entries[MAPISTORE_MAX_ROLES], *secondary_entries[MAPISTORE_MAX_ROLES], *next_entry, *current_entry; static const char *folder_names[] = {NULL, "Root", "Deferred Action", "Spooler Queue", "Common Views", "Schedule", "Finder", "Views", "Shortcuts", "Reminders", "To-Do", "Tracked Mail Processing", "Top of Information Store", "Inbox", "Outbox", "Sent Items", "Deleted Items"}; static struct emsmdbp_special_folder special_folders[] = {{MAPISTORE_DRAFTS_ROLE, PR_IPM_DRAFTS_ENTRYID, "Drafts"}, {MAPISTORE_CALENDAR_ROLE, PR_IPM_APPOINTMENT_ENTRYID, "Calendar"}, {MAPISTORE_CONTACTS_ROLE, PR_IPM_CONTACT_ENTRYID, "Contacts"}, {MAPISTORE_TASKS_ROLE, PR_IPM_TASK_ENTRYID, "Tasks"}, {MAPISTORE_NOTES_ROLE, PR_IPM_NOTE_ENTRYID, "Notes"}, {MAPISTORE_JOURNAL_ROLE, PR_IPM_JOURNAL_ENTRYID, "Journal"}}; const char **container_classes; const char *search_container_classes[] = {"Outlook.Reminder", "IPF.Task", "IPF.Note"}; uint32_t context_id, row_count; uint64_t mailbox_fid = 0, ipm_fid, inbox_fid = 0, current_fid, current_mid, found_fid, current_cn; char *fallback_url, *entryid_dump, *url; const char *mapistore_url, *current_name, *base_name; struct emsmdbp_special_folder *current_folder; struct SRow property_row; int i, j, nbr_special_folders = sizeof(special_folders) / sizeof(struct emsmdbp_special_folder); DATA_BLOB entryid_data; struct FolderEntryId folder_entryid; struct Binary_r *entryId; bool exists, reminders_created; void *backend_object, *backend_table, *backend_message; mem_ctx = talloc_zero(NULL, TALLOC_CTX); ldb_transaction_start(emsmdbp_ctx->oc_ctx); /* Retrieve list of folders from backends */ retval = mapistore_list_contexts_for_user(emsmdbp_ctx->mstore_ctx, username, mem_ctx, &contexts_list); if (retval != MAPISTORE_SUCCESS) { talloc_free(mem_ctx); return MAPI_E_DISK_ERROR; } /* Fix mapistore uris in returned entries */ current_entry = contexts_list; while (current_entry) { mapistore_url = current_entry->url; if (mapistore_url) { if (mapistore_url[strlen(mapistore_url)-1] != '/') { current_entry->url = talloc_asprintf(mem_ctx, "%s/", mapistore_url); } /* DEBUG(5, ("received entry: '%s' (%p)\n", current_entry->url, current_entry)); */ } else { DEBUG(5, ("received entry without uri\n")); abort(); } current_entry = current_entry->next; } /* Retrieve list of existing entries */ ret = openchangedb_get_MAPIStoreURIs(emsmdbp_ctx->oc_ctx, username, mem_ctx, &existing_uris); if (ret == MAPI_E_SUCCESS) { for (i = 0; i < existing_uris->cValues; i++) { /* DEBUG(5, ("checking entry '%s'\n", existing_uris->lppszW[i])); */ exists = false; mapistore_url = existing_uris->lppszW[i]; if (mapistore_url[strlen(mapistore_url)-1] != '/') { abort(); } current_entry = contexts_list; while (!exists && current_entry) { /* DEBUG(5, (" compare with '%s'\n", current_entry->url)); */ if (strcmp(mapistore_url, current_entry->url) == 0) { /* DEBUG(5, (" entry found\n")); */ exists = true; } current_entry = current_entry->next; } if (!exists) { DEBUG(5, (" removing entry '%s'\n", mapistore_url)); openchangedb_get_fid(emsmdbp_ctx->oc_ctx, mapistore_url, &found_fid); openchangedb_delete_folder(emsmdbp_ctx->oc_ctx, found_fid); } } } container_classes = talloc_array(mem_ctx, const char *, MAPISTORE_MAX_ROLES); for (i = MAPISTORE_MAIL_ROLE; i < MAPISTORE_MAX_ROLES; i++) { container_classes[i] = "IPF.Note"; } container_classes[MAPISTORE_CALENDAR_ROLE] = "IPF.Appointment"; container_classes[MAPISTORE_CONTACTS_ROLE] = "IPF.Contact"; container_classes[MAPISTORE_TASKS_ROLE] = "IPF.Task"; container_classes[MAPISTORE_NOTES_ROLE] = "IPF.StickyNote"; container_classes[MAPISTORE_JOURNAL_ROLE] = "IPF.Journal"; memset(&property_row, 0, sizeof(struct SRow)); memset(main_entries, 0, sizeof(struct mapistore_contexts_list *) * MAPISTORE_MAX_ROLES); memset(secondary_entries, 0, sizeof(struct mapistore_contexts_list *) * MAPISTORE_MAX_ROLES); /* Sort them between our main_entries and secondary_entries */ current_entry = contexts_list; while (current_entry) { next_entry = current_entry->next; current_entry->next = NULL; current_entry->prev = NULL; if (current_entry->main_folder) { if (main_entries[current_entry->role]) { DEBUG(5, ("duplicate entry for role %d ignored\n existing entry: %s\n current entry: %s\n", current_entry->role, main_entries[current_entry->role]->url, current_entry->url)); } else { main_entries[current_entry->role] = current_entry; } } else { DLIST_ADD_END(secondary_entries[current_entry->role], current_entry, void); } current_entry = next_entry; } /* Fallback role MUST exist */ if (!main_entries[MAPISTORE_FALLBACK_ROLE]) { DEBUG(5, ("No fallback provisioning role was found while such role is mandatory. Provisiong must be done manually.\n")); talloc_free(mem_ctx); return MAPI_E_DISK_ERROR; } fallback_url = main_entries[MAPISTORE_FALLBACK_ROLE]->url; if (fallback_url[strlen(fallback_url)-1] != '/') { fallback_url = talloc_asprintf(mem_ctx, "%s/", fallback_url); } /* Mailbox and subfolders */ ret = openchangedb_get_SystemFolderID(emsmdbp_ctx->oc_ctx, username, EMSMDBP_MAILBOX_ROOT, &mailbox_fid); if (ret != MAPI_E_SUCCESS) { openchangedb_create_mailbox(emsmdbp_ctx->oc_ctx, username, EMSMDBP_MAILBOX_ROOT, &mailbox_fid); } property_row.lpProps = talloc_array(mem_ctx, struct SPropValue, 4); /* allocate max needed until the end of the function */ property_row.cValues = 1; property_row.lpProps[0].ulPropTag = PR_DISPLAY_NAME_UNICODE; for (i = EMSMDBP_DEFERRED_ACTION; i < EMSMDBP_REMINDERS; i++) { /* TODO: mapistore_tag change */ ret = openchangedb_get_SystemFolderID(emsmdbp_ctx->oc_ctx, username, i, ¤t_fid); if (ret != MAPI_E_SUCCESS) { openchangedb_get_new_folderID(emsmdbp_ctx->oc_ctx, ¤t_fid); openchangedb_get_new_changeNumber(emsmdbp_ctx->oc_ctx, ¤t_cn); mapistore_url = talloc_asprintf(mem_ctx, "%s0x%"PRIx64"/", fallback_url, current_fid); openchangedb_create_folder(emsmdbp_ctx->oc_ctx, mailbox_fid, current_fid, current_cn, mapistore_url, i); property_row.lpProps[0].value.lpszW = folder_names[i]; openchangedb_set_folder_properties(emsmdbp_ctx->oc_ctx, current_fid, &property_row); /* instantiate the new folder in the backend to make sure it is initialized properly */ retval = mapistore_add_context(emsmdbp_ctx->mstore_ctx, username, mapistore_url, current_fid, &context_id, &backend_object); mapistore_indexing_record_add_fid(emsmdbp_ctx->mstore_ctx, context_id, username, current_fid); mapistore_del_context(emsmdbp_ctx->mstore_ctx, context_id); } } reminders_created = false; j = 0; property_row.cValues = 3; property_row.lpProps[1].ulPropTag = PidTagContainerClass; property_row.lpProps[2].ulPropTag = PidTagFolderType; property_row.lpProps[2].value.l = 2; for (i = EMSMDBP_REMINDERS; i < EMSMDBP_TOP_INFORMATION_STORE; i++) { ret = openchangedb_get_SystemFolderID(emsmdbp_ctx->oc_ctx, username, i, ¤t_fid); if (ret != MAPI_E_SUCCESS) { openchangedb_get_new_folderID(emsmdbp_ctx->oc_ctx, ¤t_fid); openchangedb_get_new_changeNumber(emsmdbp_ctx->oc_ctx, ¤t_cn); openchangedb_create_folder(emsmdbp_ctx->oc_ctx, mailbox_fid, current_fid, current_cn, NULL, i); property_row.lpProps[0].value.lpszW = folder_names[i]; property_row.lpProps[1].value.lpszW = search_container_classes[j]; openchangedb_set_folder_properties(emsmdbp_ctx->oc_ctx, current_fid, &property_row); if (i == EMSMDBP_REMINDERS) { reminders_created = true; } } j++; } /* IPM and subfolders */ ret = openchangedb_get_SystemFolderID(emsmdbp_ctx->oc_ctx, username, EMSMDBP_TOP_INFORMATION_STORE, &ipm_fid); if (ret != MAPI_E_SUCCESS) { openchangedb_get_new_folderID(emsmdbp_ctx->oc_ctx, &ipm_fid); openchangedb_get_new_changeNumber(emsmdbp_ctx->oc_ctx, ¤t_cn); property_row.cValues = 2; property_row.lpProps[1].ulPropTag = PR_SUBFOLDERS; property_row.lpProps[0].value.lpszW = folder_names[EMSMDBP_TOP_INFORMATION_STORE]; property_row.lpProps[1].value.b = true; openchangedb_create_folder(emsmdbp_ctx->oc_ctx, mailbox_fid, ipm_fid, current_cn, NULL, EMSMDBP_TOP_INFORMATION_STORE); openchangedb_set_folder_properties(emsmdbp_ctx->oc_ctx, ipm_fid, &property_row); openchangedb_set_ReceiveFolder(emsmdbp_ctx->oc_ctx, username, "IPC", mailbox_fid); } property_row.cValues = 2; property_row.lpProps[1].ulPropTag = PR_CONTAINER_CLASS_UNICODE; property_row.lpProps[1].value.lpszW = "IPF.Note"; /* TODO: mapistore_url/mapistore_tag change */ for (i = EMSMDBP_INBOX; i < EMSMDBP_MAX_MAILBOX_SYSTEMIDX; i++) { ret = openchangedb_get_SystemFolderID(emsmdbp_ctx->oc_ctx, username, i, ¤t_fid); if (ret == MAPI_E_SUCCESS) { if (i == EMSMDBP_INBOX) { inbox_fid = current_fid; } } else { openchangedb_get_new_folderID(emsmdbp_ctx->oc_ctx, ¤t_fid); openchangedb_get_new_changeNumber(emsmdbp_ctx->oc_ctx, ¤t_cn); current_name = folder_names[i]; switch (i) { case EMSMDBP_INBOX: current_entry = main_entries[MAPISTORE_MAIL_ROLE]; inbox_fid = current_fid; break; case EMSMDBP_OUTBOX: current_entry = main_entries[MAPISTORE_OUTBOX_ROLE]; break; case EMSMDBP_SENT_ITEMS: current_entry = main_entries[MAPISTORE_SENTITEMS_ROLE]; break; case EMSMDBP_DELETED_ITEMS: current_entry = main_entries[MAPISTORE_DELETEDITEMS_ROLE]; break; default: current_entry = NULL; } if (current_entry) { if (current_entry->name) { current_name = current_entry->name; } mapistore_url = current_entry->url; } else { mapistore_url = talloc_asprintf(mem_ctx, "%s0x%"PRIx64"/", fallback_url, current_fid); } /* Ensure the name is unique */ base_name = current_name; j = 1; while (openchangedb_get_fid_by_name(emsmdbp_ctx->oc_ctx, ipm_fid, current_name, &found_fid) == MAPI_E_SUCCESS) { current_name = talloc_asprintf(mem_ctx, "%s (%d)", base_name, j); j++; } openchangedb_create_folder(emsmdbp_ctx->oc_ctx, ipm_fid, current_fid, current_cn, mapistore_url, i); property_row.lpProps[0].value.lpszW = current_name; openchangedb_set_folder_properties(emsmdbp_ctx->oc_ctx, current_fid, &property_row); /* instantiate the new folder in the backend to make sure it is initialized properly */ retval = mapistore_add_context(emsmdbp_ctx->mstore_ctx, username, mapistore_url, current_fid, &context_id, &backend_object); mapistore_indexing_record_add_fid(emsmdbp_ctx->mstore_ctx, context_id, username, current_fid); mapistore_del_context(emsmdbp_ctx->mstore_ctx, context_id); if (i == EMSMDBP_INBOX) { /* set INBOX as receive folder for "All", "IPM", "Report.IPM" */ openchangedb_set_ReceiveFolder(emsmdbp_ctx->oc_ctx, username, "All", inbox_fid); openchangedb_set_ReceiveFolder(emsmdbp_ctx->oc_ctx, username, "IPM", inbox_fid); openchangedb_set_ReceiveFolder(emsmdbp_ctx->oc_ctx, username, "Report.IPM", inbox_fid); } } } /* Main special folders */ /* TODO: handle entryId change + mapistore_url/mapistore_tag change */ memset(&folder_entryid, 0, sizeof(struct FolderEntryId)); openchangedb_get_MailboxGuid(emsmdbp_ctx->oc_ctx, username, &folder_entryid.ProviderUID); folder_entryid.FolderType = eitLTPrivateFolder; openchangedb_get_MailboxReplica(emsmdbp_ctx->oc_ctx, username, NULL, &folder_entryid.FolderDatabaseGuid); for (i = 0; i < nbr_special_folders; i++) { current_folder = special_folders + i; ret = openchangedb_get_folder_property(mem_ctx, emsmdbp_ctx->oc_ctx, current_folder->entryid_property, mailbox_fid, (void **) &entryId); if (ret != MAPI_E_SUCCESS) { property_row.cValues = 2; property_row.lpProps[0].ulPropTag = PR_DISPLAY_NAME_UNICODE; openchangedb_get_new_folderID(emsmdbp_ctx->oc_ctx, ¤t_fid); openchangedb_get_new_changeNumber(emsmdbp_ctx->oc_ctx, ¤t_cn); current_name = current_folder->name; current_entry = main_entries[current_folder->role]; if (current_entry) { if (current_entry->name) { current_name = current_entry->name; } mapistore_url = current_entry->url; } else { mapistore_url = talloc_asprintf(mem_ctx, "%s0x%"PRIx64"/", fallback_url, current_fid); } /* Ensure the name is unique */ base_name = current_name; j = 1; while (openchangedb_get_fid_by_name(emsmdbp_ctx->oc_ctx, ipm_fid, current_name, &found_fid) == MAPI_E_SUCCESS) { current_name = talloc_asprintf(mem_ctx, "%s (%d)", base_name, j); j++; } property_row.lpProps[0].value.lpszW = current_name; property_row.lpProps[1].value.lpszW = container_classes[current_folder->role]; openchangedb_create_folder(emsmdbp_ctx->oc_ctx, ipm_fid, current_fid, current_cn, mapistore_url, i); openchangedb_set_folder_properties(emsmdbp_ctx->oc_ctx, current_fid, &property_row); /* instantiate the new folder in the backend to make sure it is initialized properly */ retval = mapistore_add_context(emsmdbp_ctx->mstore_ctx, username, mapistore_url, current_fid, &context_id, &backend_object); mapistore_indexing_record_add_fid(emsmdbp_ctx->mstore_ctx, context_id, username, current_fid); mapistore_del_context(emsmdbp_ctx->mstore_ctx, context_id); /* set entryid on mailbox and inbox */ folder_entryid.FolderGlobalCounter.value = (current_fid >> 16); ndr_push_struct_blob(&entryid_data, mem_ctx, &folder_entryid, (ndr_push_flags_fn_t)ndr_push_FolderEntryId); property_row.cValues = 1; property_row.lpProps[0].ulPropTag = current_folder->entryid_property; property_row.lpProps[0].value.bin.cb = entryid_data.length; property_row.lpProps[0].value.bin.lpb = entryid_data.data; entryid_dump = ndr_print_struct_string(mem_ctx, (ndr_print_fn_t) ndr_print_FolderEntryId, current_name, &folder_entryid); DEBUG(5, ("%s\n", entryid_dump)); openchangedb_set_folder_properties(emsmdbp_ctx->oc_ctx, mailbox_fid, &property_row); openchangedb_set_folder_properties(emsmdbp_ctx->oc_ctx, inbox_fid, &property_row); } } /* DEBUG(5, ("size of operation: %ld\n", talloc_total_size(mem_ctx))); */ /* PidTagRemindersOnlineEntryId */ if (reminders_created) { openchangedb_get_SystemFolderID(emsmdbp_ctx->oc_ctx, username, EMSMDBP_REMINDERS, &found_fid); folder_entryid.FolderGlobalCounter.value = (found_fid >> 16); ndr_push_struct_blob(&entryid_data, mem_ctx, &folder_entryid, (ndr_push_flags_fn_t)ndr_push_FolderEntryId); property_row.cValues = 1; property_row.lpProps[0].ulPropTag = PidTagRemindersOnlineEntryId; property_row.lpProps[0].value.bin.cb = entryid_data.length; property_row.lpProps[0].value.bin.lpb = entryid_data.data; entryid_dump = ndr_print_struct_string(mem_ctx, (ndr_print_fn_t) ndr_print_FolderEntryId, "Reminders", &folder_entryid); DEBUG(5, ("%s\n", entryid_dump)); openchangedb_set_folder_properties(emsmdbp_ctx->oc_ctx, mailbox_fid, &property_row); openchangedb_set_folder_properties(emsmdbp_ctx->oc_ctx, inbox_fid, &property_row); } /* secondary folders */ property_row.cValues = 2; property_row.lpProps[0].ulPropTag = PR_DISPLAY_NAME_UNICODE; for (i = MAPISTORE_MAIL_ROLE; i < MAPISTORE_MAX_ROLES; i++) { /* secondary fallback roles are only used for synchronization */ if (i == MAPISTORE_FALLBACK_ROLE) { continue; } property_row.lpProps[1].value.lpszW = container_classes[i]; current_entry = secondary_entries[i]; while (current_entry) { mapistore_url = current_entry->url; if (openchangedb_get_fid(emsmdbp_ctx->oc_ctx, mapistore_url, &found_fid) != MAPI_E_SUCCESS) { /* DEBUG(5, ("creating secondary entry '%s'\n", current_entry->url)); */ openchangedb_get_new_folderID(emsmdbp_ctx->oc_ctx, ¤t_fid); openchangedb_get_new_changeNumber(emsmdbp_ctx->oc_ctx, ¤t_cn); current_name = current_entry->name; /* Ensure the name is unique */ base_name = current_name; j = 1; while (openchangedb_get_fid_by_name(emsmdbp_ctx->oc_ctx, ipm_fid, current_name, &found_fid) == MAPI_E_SUCCESS) { current_name = talloc_asprintf(mem_ctx, "%s (%d)", base_name, j); j++; } property_row.lpProps[0].value.lpszW = current_name; openchangedb_create_folder(emsmdbp_ctx->oc_ctx, ipm_fid, current_fid, current_cn, mapistore_url, -1); openchangedb_set_folder_properties(emsmdbp_ctx->oc_ctx, current_fid, &property_row); /* instantiate the new folder in the backend to make sure it is initialized properly */ retval = mapistore_add_context(emsmdbp_ctx->mstore_ctx, username, mapistore_url, current_fid, &context_id, &backend_object); mapistore_indexing_record_add_fid(emsmdbp_ctx->mstore_ctx, context_id, username, current_fid); mapistore_del_context(emsmdbp_ctx->mstore_ctx, context_id); } else { /* DEBUG(5, ("secondary entry '%s' already exists\n", current_entry->url)); */ } current_entry = current_entry->next; } } /** create root/Freebusy Data folder + "LocalFreebusy" message (OXODLGT) */ /* FIXME: the problem here is that only the owner of a mailbox can create the delegation message and its container, meaning that when sharing an object, a delegate must at least login once to OpenChange before any one subscribes to his resources */ if (strcmp(emsmdbp_ctx->username, username) == 0) { struct mapi_SRestriction restriction; uint8_t status; /* find out whether the "Freebusy Data" folder exists at the mailbox root */ ret = openchangedb_get_fid_by_name(emsmdbp_ctx->oc_ctx, mailbox_fid, "Freebusy Data", ¤t_fid); if (ret == MAPI_E_NOT_FOUND) { /* create the folder */ openchangedb_get_new_folderID(emsmdbp_ctx->oc_ctx, ¤t_fid); openchangedb_get_new_changeNumber(emsmdbp_ctx->oc_ctx, ¤t_cn); property_row.cValues = 3; property_row.lpProps[0].ulPropTag = PidTagDisplayName; property_row.lpProps[0].value.lpszW = "Freebusy Data"; property_row.lpProps[1].ulPropTag = PidTagParentFolderId; property_row.lpProps[1].value.d = mailbox_fid; property_row.lpProps[2].ulPropTag = PidTagChangeNumber; property_row.lpProps[2].value.d = current_cn; mapistore_url = talloc_asprintf(mem_ctx, "%s0x%"PRIx64"/", fallback_url, current_fid); openchangedb_create_folder(emsmdbp_ctx->oc_ctx, mailbox_fid, current_fid, current_cn, mapistore_url, -1); openchangedb_set_folder_properties(emsmdbp_ctx->oc_ctx, current_fid, &property_row); /* instantiate the new folder in the backend to make sure it is initialized properly */ mapistore_add_context(emsmdbp_ctx->mstore_ctx, username, mapistore_url, current_fid, &context_id, &backend_object); mapistore_indexing_record_add_fid(emsmdbp_ctx->mstore_ctx, context_id, username, current_fid); mapistore_properties_set_properties(emsmdbp_ctx->mstore_ctx, context_id, backend_object, &property_row); } else { /* open the existing folder */ openchangedb_get_mapistoreURI(mem_ctx, emsmdbp_ctx->oc_ctx, current_fid, &url, true); mapistore_add_context(emsmdbp_ctx->mstore_ctx, username, url, current_fid, &context_id, &backend_object); /* if (emsmdbp_ctx->mstore_ctx */ /* mapistore_search_context_by_uri(emsmdbp_ctx->mstore_ctx, url, &context_id, &backend_object); */ } /* find out whether "LocalFreebusy" message exists */ mapistore_folder_open_table(emsmdbp_ctx->mstore_ctx, context_id, backend_object, mem_ctx, MAPISTORE_MESSAGE_TABLE, 0, &backend_table, &row_count); restriction.rt = RES_PROPERTY; restriction.res.resProperty.relop = RELOP_EQ; restriction.res.resProperty.ulPropTag = restriction.res.resProperty.lpProp.ulPropTag = PidTagSubject; restriction.res.resProperty.lpProp.value.lpszW = "LocalFreebusy"; mapistore_table_set_restrictions(emsmdbp_ctx->mstore_ctx, context_id, backend_table, &restriction, &status); mapistore_table_get_row_count(emsmdbp_ctx->mstore_ctx, context_id, backend_table, MAPISTORE_PREFILTERED_QUERY, &row_count); if (row_count == 0) { /* create the message */ openchangedb_get_new_folderID(emsmdbp_ctx->oc_ctx, ¤t_mid); if (mapistore_folder_create_message(emsmdbp_ctx->mstore_ctx, context_id, backend_object, mem_ctx, current_mid, false, &backend_message) != MAPISTORE_SUCCESS) { abort(); } property_row.cValues = 3; property_row.lpProps[0].ulPropTag = PidTagMessageClass; property_row.lpProps[0].value.lpszW = "IPM.Microsoft.ScheduleData.FreeBusy"; property_row.lpProps[1].ulPropTag = PidTagSubjectPrefix; property_row.lpProps[1].value.lpszW = ""; property_row.lpProps[2].ulPropTag = PidTagNormalizedSubject; property_row.lpProps[2].value.lpszW = "LocalFreebusy"; mapistore_properties_set_properties(emsmdbp_ctx->mstore_ctx, context_id, backend_message, &property_row); mapistore_message_save(emsmdbp_ctx->mstore_ctx, context_id, backend_message); } mapistore_del_context(emsmdbp_ctx->mstore_ctx, context_id); } ldb_transaction_commit(emsmdbp_ctx->oc_ctx); /* TODO: rename/create/delete folders at IPM level */ talloc_free(mem_ctx); return MAPI_E_SUCCESS; } openchange-2.0/mapiproxy/servers/default/emsmdb/oxcfold.c000066400000000000000000001306211223057412600237050ustar00rootroot00000000000000/* OpenChange Server implementation EMSMDBP: EMSMDB Provider implementation Copyright (C) Julien Kerihuel 2009-2010 This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see . */ /** \file oxcfold.c \brief Folder object routines and Rops */ #include "mapiproxy/dcesrv_mapiproxy.h" #include "mapiproxy/libmapiproxy/libmapiproxy.h" #include "mapiproxy/libmapiserver/libmapiserver.h" #include "dcesrv_exchange_emsmdb.h" /** \details EcDoRpc OpenFolder (0x02) Rop. This operation opens an existing folder. \param mem_ctx pointer to the memory context \param emsmdbp_ctx pointer to the emsmdb provider context \param mapi_req pointer to the OpenFolder EcDoRpc_MAPI_REQ structure \param mapi_repl pointer to the OpenFolder EcDoRpc_MAPI_REPL structure \param handles pointer to the MAPI handles array \param size pointer to the mapi_response size to update \return MAPI_E_SUCCESS on success, otherwise MAPI error */ _PUBLIC_ enum MAPISTATUS EcDoRpc_RopOpenFolder(TALLOC_CTX *mem_ctx, struct emsmdbp_context *emsmdbp_ctx, struct EcDoRpc_MAPI_REQ *mapi_req, struct EcDoRpc_MAPI_REPL *mapi_repl, uint32_t *handles, uint16_t *size) { enum MAPISTATUS retval; enum mapistore_error ret; struct mapi_handles *parent = NULL; struct mapi_handles *rec = NULL; void *private_data; struct emsmdbp_object *object, *parent_object; uint32_t handle; struct OpenFolder_req *request; struct OpenFolder_repl *response; DEBUG(4, ("exchange_emsmdb: [OXCFOLD] OpenFolder (0x02)\n")); /* Sanity checks */ OPENCHANGE_RETVAL_IF(!emsmdbp_ctx, MAPI_E_NOT_INITIALIZED, NULL); OPENCHANGE_RETVAL_IF(!mapi_req, MAPI_E_INVALID_PARAMETER, NULL); OPENCHANGE_RETVAL_IF(!mapi_repl, MAPI_E_INVALID_PARAMETER, NULL); OPENCHANGE_RETVAL_IF(!handles, MAPI_E_INVALID_PARAMETER, NULL); OPENCHANGE_RETVAL_IF(!size, MAPI_E_INVALID_PARAMETER, NULL); request = &mapi_req->u.mapi_OpenFolder; response = &mapi_repl->u.mapi_OpenFolder; mapi_repl->opnum = mapi_req->opnum; mapi_repl->error_code = MAPI_E_SUCCESS; mapi_repl->handle_idx = request->handle_idx; /* Step 1. Retrieve parent handle in the hierarchy */ handle = handles[mapi_req->handle_idx]; retval = mapi_handles_search(emsmdbp_ctx->handles_ctx, handle, &parent); if (retval) { DEBUG(5, (" handle (%x) not found: %x\n", handle, mapi_req->handle_idx)); mapi_repl->error_code = MAPI_E_INVALID_OBJECT; goto end; } /* With OpenFolder, the parent object may NOT BE the direct parent folder of the folder */ mapi_handles_get_private_data(parent, &private_data); parent_object = private_data; if (!parent_object || (parent_object->type != EMSMDBP_OBJECT_FOLDER && parent_object->type != EMSMDBP_OBJECT_MAILBOX)) { DEBUG(5, (" invalid handle (%x): %x\n", handle, mapi_req->handle_idx)); mapi_repl->error_code = MAPI_E_INVALID_OBJECT; goto end; } /* Fill EcDoRpc_MAPI_REPL reply */ response->HasRules = 0; response->IsGhosted = 0; mapi_handles_add(emsmdbp_ctx->handles_ctx, 0, &rec); ret = emsmdbp_object_open_folder_by_fid(rec, emsmdbp_ctx, parent_object, request->folder_id, &object); if (ret != MAPISTORE_SUCCESS) { if (ret == MAPISTORE_ERR_DENIED) { mapi_repl->error_code = MAPI_E_NO_ACCESS; } else { mapi_repl->error_code = MAPI_E_NOT_FOUND; } goto end; } retval = mapi_handles_set_private_data(rec, object); handles[mapi_repl->handle_idx] = rec->handle; end: *size += libmapiserver_RopOpenFolder_size(mapi_repl); return MAPI_E_SUCCESS; } /** \details EcDoRpc GetHierarchyTable (0x04) Rop. This operation gets the subfolder hierarchy table for a folder. \param mem_ctx pointer to the memory context \param emsmdbp_ctx pointer to the emsmdb provider context \param mapi_req pointer to the GetHierarchyTable EcDoRpc_MAPI_REQ structure \param mapi_repl pointer to the GetHierarchyTable EcDoRpc_MAPI_REPL structure \param handles pointer to the MAPI handles array \param size pointer to the mapi_response size to update \return MAPI_E_SUCCESS on success, otherwise MAPI error */ _PUBLIC_ enum MAPISTATUS EcDoRpc_RopGetHierarchyTable(TALLOC_CTX *mem_ctx, struct emsmdbp_context *emsmdbp_ctx, struct EcDoRpc_MAPI_REQ *mapi_req, struct EcDoRpc_MAPI_REPL *mapi_repl, uint32_t *handles, uint16_t *size) { enum MAPISTATUS retval; struct mapi_handles *parent; struct mapi_handles *rec = NULL; struct emsmdbp_object *object = NULL, *parent_object = NULL; struct mapistore_subscription_list *subscription_list; struct mapistore_subscription *subscription; struct mapistore_table_subscription_parameters subscription_parameters; void *data; uint64_t folderID; uint32_t handle; DEBUG(4, ("exchange_emsmdb: [OXCFOLD] GetHierarchyTable (0x04)\n")); /* Sanity checks */ OPENCHANGE_RETVAL_IF(!emsmdbp_ctx, MAPI_E_NOT_INITIALIZED, NULL); OPENCHANGE_RETVAL_IF(!mapi_req, MAPI_E_INVALID_PARAMETER, NULL); OPENCHANGE_RETVAL_IF(!mapi_repl, MAPI_E_INVALID_PARAMETER, NULL); OPENCHANGE_RETVAL_IF(!handles, MAPI_E_INVALID_PARAMETER, NULL); OPENCHANGE_RETVAL_IF(!size, MAPI_E_INVALID_PARAMETER, NULL); /* Initialize default empty GetHierarchyTable reply */ mapi_repl->opnum = mapi_req->opnum; mapi_repl->error_code = MAPI_E_SUCCESS; mapi_repl->handle_idx = mapi_req->u.mapi_GetHierarchyTable.handle_idx; /* GetHierarchyTable can only be called for mailbox/folder objects */ handle = handles[mapi_req->handle_idx]; retval = mapi_handles_search(emsmdbp_ctx->handles_ctx, handle, &parent); if (retval) { DEBUG(5, (" handle (%x) not found: %x\n", handle, mapi_req->handle_idx)); mapi_repl->error_code = MAPI_E_INVALID_OBJECT; goto end; } mapi_handles_get_private_data(parent, &data); parent_object = (struct emsmdbp_object *)data; if (!parent_object) { DEBUG(5, (" no object found\n")); mapi_repl->error_code = MAPI_E_NO_SUPPORT; goto end; } switch (parent_object->type) { case EMSMDBP_OBJECT_MAILBOX: folderID = parent_object->object.mailbox->folderID; break; case EMSMDBP_OBJECT_FOLDER: folderID = parent_object->object.folder->folderID; break; default: DEBUG(5, (" unsupported object type\n")); mapi_repl->error_code = MAPI_E_NO_SUPPORT; goto end; } /* Initialize Table object */ retval = mapi_handles_add(emsmdbp_ctx->handles_ctx, handle, &rec); handles[mapi_repl->handle_idx] = rec->handle; object = emsmdbp_folder_open_table(rec, parent_object, MAPISTORE_FOLDER_TABLE, rec->handle); if (!object) { mapi_repl->error_code = MAPI_E_INVALID_OBJECT; goto end; } mapi_handles_set_private_data(rec, object); mapi_repl->u.mapi_GetHierarchyTable.RowCount = object->object.table->denominator; /* notifications */ if ((mapi_req->u.mapi_GetHierarchyTable.TableFlags & TableFlags_NoNotifications)) { DEBUG(5, (" notifications skipped\n")); } else { /* we attach the subscription to the session object */ subscription_list = talloc_zero(emsmdbp_ctx->mstore_ctx, struct mapistore_subscription_list); DLIST_ADD(emsmdbp_ctx->mstore_ctx->subscriptions, subscription_list); subscription_parameters.table_type = MAPISTORE_FOLDER_TABLE; subscription_parameters.folder_id = folderID; /* note that a mapistore_subscription can exist without a corresponding emsmdbp_object (tables) */ subscription = mapistore_new_subscription(subscription_list, emsmdbp_ctx->mstore_ctx, emsmdbp_ctx->username, rec->handle, fnevTableModified, &subscription_parameters); subscription_list->subscription = subscription; object->object.table->subscription_list = subscription_list; } end: *size += libmapiserver_RopGetHierarchyTable_size(mapi_repl); return MAPI_E_SUCCESS; } /** \details EcDoRpc GetContentsTable (0x05) Rop. This operation get the content table of a container. \param mem_ctx pointer to the memory context \param emsmdbp_ctx pointer to the emsmdb provider context \param mapi_req pointer to the GetContentsTable EcDoRpc_MAPI_REQ structure \param mapi_repl pointer to the GetContentsTable EcDoRpc_MAPI_REPL structure \param handles pointer to the MAPI handles array \param size pointer to the mapi_response size to update \return MAPI_E_SUCCESS on success, otherwise MAPI error */ _PUBLIC_ enum MAPISTATUS EcDoRpc_RopGetContentsTable(TALLOC_CTX *mem_ctx, struct emsmdbp_context *emsmdbp_ctx, struct EcDoRpc_MAPI_REQ *mapi_req, struct EcDoRpc_MAPI_REPL *mapi_repl, uint32_t *handles, uint16_t *size) { enum MAPISTATUS retval; struct mapi_handles *parent; struct mapi_handles *rec = NULL; struct emsmdbp_object *object = NULL, *parent_object; struct mapistore_subscription_list *subscription_list; struct mapistore_subscription *subscription; struct mapistore_table_subscription_parameters subscription_parameters; void *data; uint64_t folderID; uint32_t handle; uint8_t table_type; DEBUG(4, ("exchange_emsmdb: [OXCFOLD] GetContentsTable (0x05)\n")); /* Sanity checks */ OPENCHANGE_RETVAL_IF(!emsmdbp_ctx, MAPI_E_NOT_INITIALIZED, NULL); OPENCHANGE_RETVAL_IF(!mapi_req, MAPI_E_INVALID_PARAMETER, NULL); OPENCHANGE_RETVAL_IF(!mapi_repl, MAPI_E_INVALID_PARAMETER, NULL); OPENCHANGE_RETVAL_IF(!handles, MAPI_E_INVALID_PARAMETER, NULL); OPENCHANGE_RETVAL_IF(!size, MAPI_E_INVALID_PARAMETER, NULL); /* Initialize default empty GetContentsTable reply */ mapi_repl->opnum = mapi_req->opnum; mapi_repl->handle_idx = mapi_req->u.mapi_GetContentsTable.handle_idx; mapi_repl->error_code = MAPI_E_SUCCESS; mapi_repl->u.mapi_GetContentsTable.RowCount = 0; handle = handles[mapi_req->handle_idx]; retval = mapi_handles_search(emsmdbp_ctx->handles_ctx, handle, &parent); if (retval) { DEBUG(5, (" handle (%x) not found: %x\n", handle, mapi_req->handle_idx)); mapi_repl->error_code = MAPI_E_NO_SUPPORT; goto end; } /* GetContentsTable can only be called for folder objects */ retval = mapi_handles_get_private_data(parent, &data); if (retval) { mapi_repl->error_code = retval; DEBUG(5, (" handle data not found, idx = %x\n", mapi_req->handle_idx)); goto end; } parent_object = (struct emsmdbp_object *)data; if (!parent_object) { mapi_repl->error_code = MAPI_E_NO_SUPPORT; DEBUG(5, (" handle data not found, idx = %x\n", mapi_req->handle_idx)); goto end; } if (parent_object->type != EMSMDBP_OBJECT_FOLDER) { mapi_repl->error_code = MAPI_E_INVALID_OBJECT; goto end; } folderID = parent_object->object.folder->folderID; if ((mapi_req->u.mapi_GetContentsTable.TableFlags & TableFlags_Associated)) { DEBUG(5, (" table is FAI table\n")); table_type = MAPISTORE_FAI_TABLE; } else { DEBUG(5, (" table is contents table\n")); table_type = MAPISTORE_MESSAGE_TABLE; } /* Initialize Table object */ retval = mapi_handles_add(emsmdbp_ctx->handles_ctx, handle, &rec); handles[mapi_repl->handle_idx] = rec->handle; object = emsmdbp_folder_open_table(rec, parent_object, table_type, rec->handle); if (!object) { mapi_repl->error_code = MAPI_E_INVALID_OBJECT; goto end; } mapi_handles_set_private_data(rec, object); mapi_repl->u.mapi_GetContentsTable.RowCount = object->object.table->denominator; /* notifications */ if ((mapi_req->u.mapi_GetContentsTable.TableFlags & TableFlags_NoNotifications)) { DEBUG(5, (" notifications skipped\n")); } else { /* we attach the subscription to the session object */ subscription_list = talloc_zero(emsmdbp_ctx->mstore_ctx, struct mapistore_subscription_list); DLIST_ADD(emsmdbp_ctx->mstore_ctx->subscriptions, subscription_list); if ((mapi_req->u.mapi_GetContentsTable.TableFlags & TableFlags_Associated)) { subscription_parameters.table_type = MAPISTORE_FAI_TABLE; } else { subscription_parameters.table_type = MAPISTORE_MESSAGE_TABLE; } subscription_parameters.folder_id = folderID; /* note that a mapistore_subscription can exist without a corresponding emsmdbp_object (tables) */ subscription = mapistore_new_subscription(subscription_list, emsmdbp_ctx->mstore_ctx, emsmdbp_ctx->username, rec->handle, fnevTableModified, &subscription_parameters); subscription_list->subscription = subscription; object->object.table->subscription_list = subscription_list; } end: *size += libmapiserver_RopGetContentsTable_size(mapi_repl); return MAPI_E_SUCCESS; } /** \details EcDoRpc CreateFolder (0x1c) Rop. This operation creates a folder on the remote server. \param mem_ctx pointer to the memory context \param emsmdbp_ctx pointer to the emsmdb provider context \param mapi_req pointer to the CreateFolder EcDoRpc_MAPI_REQ structure \param mapi_repl pointer to the CreateFolder EcDoRpc_MAPI_REPL structure \param handles pointer to the MAPI handles array \param size pointer to the mapi_response size to update \return MAPI_E_SUCCESS on success, otherwise MAPI error \note We do not provide support for GhostInfo */ _PUBLIC_ enum MAPISTATUS EcDoRpc_RopCreateFolder(TALLOC_CTX *mem_ctx, struct emsmdbp_context *emsmdbp_ctx, struct EcDoRpc_MAPI_REQ *mapi_req, struct EcDoRpc_MAPI_REPL *mapi_repl, uint32_t *handles, uint16_t *size) { enum MAPISTATUS retval; enum mapistore_error ret; struct mapi_handles *parent = NULL; uint32_t handle; uint64_t parent_fid, fid, cn; struct SPropValue cnValue; struct emsmdbp_object *parent_object = NULL; struct emsmdbp_object *object = NULL; struct CreateFolder_req *request; struct CreateFolder_repl *response; struct SRow *aRow = NULL; void *data; struct mapi_handles *rec = NULL; DEBUG(4, ("exchange_emsmdb: [OXCFOLD] CreateFolder (0x1c)\n")); /* Sanity checks */ OPENCHANGE_RETVAL_IF(!emsmdbp_ctx, MAPI_E_NOT_INITIALIZED, NULL); OPENCHANGE_RETVAL_IF(!mapi_req, MAPI_E_INVALID_PARAMETER, NULL); OPENCHANGE_RETVAL_IF(!mapi_repl, MAPI_E_INVALID_PARAMETER, NULL); OPENCHANGE_RETVAL_IF(!handles, MAPI_E_INVALID_PARAMETER, NULL); OPENCHANGE_RETVAL_IF(!size, MAPI_E_INVALID_PARAMETER, NULL); /* Set up sensible values for the reply */ mapi_repl->opnum = mapi_req->opnum; mapi_repl->error_code = MAPI_E_SUCCESS; mapi_repl->handle_idx = mapi_req->u.mapi_CreateFolder.handle_idx; /* Step 1. Retrieve parent handle in the hierarchy */ handle = handles[mapi_req->handle_idx]; retval = mapi_handles_search(emsmdbp_ctx->handles_ctx, handle, &parent); OPENCHANGE_RETVAL_IF(retval, retval, NULL); /* With CreateFolder, the parent object really IS the parent object */ mapi_handles_get_private_data(parent, &data); parent_object = (struct emsmdbp_object *)data; if (!parent_object) { DEBUG(4, ("exchange_emsmdb: [OXCFOLD] CreateFolder null object\n")); mapi_repl->error_code = MAPI_E_NO_SUPPORT; goto end; } if (parent_object->type != EMSMDBP_OBJECT_FOLDER && parent_object->type != EMSMDBP_OBJECT_MAILBOX) { DEBUG(4, ("exchange_emsmdb: [OXCFOLD] CreateFolder wrong object type: 0x%x\n", parent_object->type)); mapi_repl->error_code = MAPI_E_NO_SUPPORT; goto end; } request = &mapi_req->u.mapi_CreateFolder; response = &mapi_repl->u.mapi_CreateFolder; /* DEBUG(4, ("exchange_emsmdb: [OXCFOLD] CreateFolder parent: 0x%.16"PRIx64"\n", parent_fid)); */ /* DEBUG(4, ("exchange_emsmdb: [OXCFOLD] Creating %s\n", request->FolderName.lpszW)); */ /* if (request->ulFolderType != FOLDER_GENERIC) { */ /* DEBUG(4, ("exchange_emsmdb: [OXCFOLD] Unexpected folder type 0x%x\n", request->ulType)); */ /* mapi_repl->error_code = MAPI_E_NO_SUPPORT; */ /* goto end; */ /* } */ response->IsExistingFolder = false; ret = emsmdbp_object_get_fid_by_name(emsmdbp_ctx, parent_object, request->FolderName.lpszW, &fid); if (ret == MAPISTORE_SUCCESS) { if (request->ulFlags != OPEN_IF_EXISTS) { mapi_repl->error_code = MAPI_E_COLLISION; goto end; } response->IsExistingFolder = true; } mapi_handles_add(emsmdbp_ctx->handles_ctx, 0, &rec); if (response->IsExistingFolder) { ret = emsmdbp_object_open_folder_by_fid(rec, emsmdbp_ctx, parent_object, fid, &object); if (ret != MAPISTORE_SUCCESS) { DEBUG(5, (__location__": failure opening existing folder\n")); mapi_handles_delete(emsmdbp_ctx->handles_ctx, rec->handle); mapi_repl->error_code = retval; if (ret == MAPISTORE_ERR_DENIED) { mapi_repl->error_code = MAPI_E_NO_ACCESS; } else { mapi_repl->error_code = MAPI_E_CALL_FAILED; } goto end; } } else { /* Step 3. Turn CreateFolder parameters into MAPI property array */ retval = openchangedb_get_new_folderID(emsmdbp_ctx->oc_ctx, &fid); if (retval != MAPI_E_SUCCESS) { DEBUG(4, ("exchange_emsmdb: [OXCFOLD] Could not obtain a new folder id\n")); mapi_repl->error_code = MAPI_E_NO_SUPPORT; goto end; } retval = openchangedb_get_new_changeNumber(emsmdbp_ctx->oc_ctx, &cn); if (retval != MAPI_E_SUCCESS) { DEBUG(4, ("exchange_emsmdb: [OXCFOLD] Could not obtain a new folder cn\n")); mapi_repl->error_code = MAPI_E_NO_SUPPORT; goto end; } parent_fid = parent_object->object.folder->folderID; aRow = libmapiserver_ROP_request_to_properties(mem_ctx, (void *)&mapi_req->u.mapi_CreateFolder, op_MAPI_CreateFolder); aRow->lpProps = add_SPropValue(mem_ctx, aRow->lpProps, &(aRow->cValues), PR_PARENT_FID, (void *)(&parent_fid)); cnValue.ulPropTag = PidTagChangeNumber; cnValue.value.d = cn; SRow_addprop(aRow, cnValue); retval = emsmdbp_object_create_folder(emsmdbp_ctx, parent_object, rec, fid, aRow, &object); if (retval != MAPI_E_SUCCESS) { DEBUG(5, (__location__": folder creation failed\n")); mapi_handles_delete(emsmdbp_ctx->handles_ctx, rec->handle); mapi_repl->error_code = retval; goto end; } } handles[mapi_repl->handle_idx] = rec->handle; mapi_handles_set_private_data(rec, object); response->folder_id = fid; if (response->IsExistingFolder == true) { response->GhostUnion.GhostInfo.HasRules = false; response->GhostUnion.GhostInfo.IsGhosted = false; } end: *size += libmapiserver_RopCreateFolder_size(mapi_repl); if (aRow) { talloc_free(aRow); } return MAPI_E_SUCCESS; } /** \details EcDoRpc DeleteFolder (0x1d) Rop. This operation deletes a folder on the remote server. \param mem_ctx pointer to the memory context \param emsmdbp_ctx pointer to the emsmdb provider context \param mapi_req pointer to the DeleteFolder EcDoRpc_MAPI_REQ structure \param mapi_repl pointer to the DeleteFolder EcDoRpc_MAPI_REPL structure \param handles pointer to the MAPI handles array \param size pointer to the mapi_response size to update \return MAPI_E_SUCCESS on success, otherwise MAPI error */ _PUBLIC_ enum MAPISTATUS EcDoRpc_RopDeleteFolder(TALLOC_CTX *mem_ctx, struct emsmdbp_context *emsmdbp_ctx, struct EcDoRpc_MAPI_REQ *mapi_req, struct EcDoRpc_MAPI_REPL *mapi_repl, uint32_t *handles, uint16_t *size) { enum MAPISTATUS retval; enum mapistore_error ret; struct mapi_handles *rec = NULL; uint32_t handle; void *handle_priv_data; struct emsmdbp_object *handle_object = NULL; DEBUG(4, ("exchange_emsmdb: [OXCFOLD] DeleteFolder (0x1d)\n")); /* Sanity checks */ OPENCHANGE_RETVAL_IF(!emsmdbp_ctx, MAPI_E_NOT_INITIALIZED, NULL); OPENCHANGE_RETVAL_IF(!mapi_req, MAPI_E_INVALID_PARAMETER, NULL); OPENCHANGE_RETVAL_IF(!mapi_repl, MAPI_E_INVALID_PARAMETER, NULL); OPENCHANGE_RETVAL_IF(!handles, MAPI_E_INVALID_PARAMETER, NULL); OPENCHANGE_RETVAL_IF(!size, MAPI_E_INVALID_PARAMETER, NULL); /* Initialize default empty DeleteFolder reply */ mapi_repl->opnum = mapi_req->opnum; mapi_repl->error_code = MAPI_E_SUCCESS; mapi_repl->handle_idx = mapi_req->handle_idx; /* TODO: factor this out to be convenience API */ /* Convert the handle index into a handle, and then get the folder id */ handle = handles[mapi_req->handle_idx]; retval = mapi_handles_search(emsmdbp_ctx->handles_ctx, handle, &rec); OPENCHANGE_RETVAL_IF(retval, retval, NULL); mapi_handles_get_private_data(rec, &handle_priv_data); handle_object = (struct emsmdbp_object *)handle_priv_data; if (!handle_object) { DEBUG(4, ("exchange_emsmdb: [OXCFOLD] DeleteFolder null object\n")); mapi_repl->error_code = MAPI_E_NO_SUPPORT; return MAPI_E_SUCCESS; } if (handle_object->type != EMSMDBP_OBJECT_FOLDER) { DEBUG(4, ("exchange_emsmdb: [OXCFOLD] DeleteFolder wrong object type: 0x%x\n", handle_object->type)); mapi_repl->error_code = MAPI_E_NO_SUPPORT; return MAPI_E_SUCCESS; } retval = MAPI_E_SUCCESS; ret = emsmdbp_folder_delete(emsmdbp_ctx, handle_object, mapi_req->u.mapi_DeleteFolder.FolderId, mapi_req->u.mapi_DeleteFolder.DeleteFolderFlags); if (ret == MAPISTORE_ERR_EXIST) { mapi_repl->u.mapi_DeleteFolder.PartialCompletion = true; } else if (ret != MAPISTORE_SUCCESS) { DEBUG(4, ("exchange_emsmdb: [OXCFOLD] DeleteFolder failed to delete fid 0x%.16"PRIx64" (0x%x)", mapi_req->u.mapi_DeleteFolder.FolderId, retval)); retval = MAPI_E_NOT_FOUND; } mapi_repl->error_code = retval; *size += libmapiserver_RopDeleteFolder_size(mapi_repl); return MAPI_E_SUCCESS; } /** \details EcDoRpc DeleteMessage (0x1e) Rop. This operation (soft) deletes a message on the server. \param mem_ctx pointer to the memory context \param emsmdbp_ctx pointer to the emsmdb provider context \param mapi_req pointer to the DeleteMessage EcDoRpc_MAPI_REQ structure \param mapi_repl pointer to the DeleteMessage EcDoRpc_MAPI_REPL structure \param handles pointer to the MAPI handles array \param size pointer to the mapi_response size to update \return MAPI_E_SUCCESS on success, otherwise MAPI error */ _PUBLIC_ enum MAPISTATUS EcDoRpc_RopDeleteMessages(TALLOC_CTX *mem_ctx, struct emsmdbp_context *emsmdbp_ctx, struct EcDoRpc_MAPI_REQ *mapi_req, struct EcDoRpc_MAPI_REPL *mapi_repl, uint32_t *handles, uint16_t *size) { uint32_t parent_folder_handle; struct mapi_handles *parent_folder = NULL; void *parent_folder_private_data; struct emsmdbp_object *parent_object; char *owner; enum MAPISTATUS retval; uint32_t contextID; int i; DEBUG(4, ("exchange_emsmdb: [OXCFOLD] DeleteMessage (0x1e)\n")); /* Sanity checks */ OPENCHANGE_RETVAL_IF(!emsmdbp_ctx, MAPI_E_NOT_INITIALIZED, NULL); OPENCHANGE_RETVAL_IF(!mapi_req, MAPI_E_INVALID_PARAMETER, NULL); OPENCHANGE_RETVAL_IF(!mapi_repl, MAPI_E_INVALID_PARAMETER, NULL); OPENCHANGE_RETVAL_IF(!handles, MAPI_E_INVALID_PARAMETER, NULL); OPENCHANGE_RETVAL_IF(!size, MAPI_E_INVALID_PARAMETER, NULL); mapi_repl->opnum = mapi_req->opnum; mapi_repl->error_code = MAPI_E_SUCCESS; mapi_repl->u.mapi_DeleteMessages.PartialCompletion = false; parent_folder_handle = handles[mapi_req->handle_idx]; retval = mapi_handles_search(emsmdbp_ctx->handles_ctx, parent_folder_handle, &parent_folder); if (retval != MAPI_E_SUCCESS) { mapi_repl->error_code = MAPI_E_NOT_FOUND; goto delete_message_response; } retval = mapi_handles_get_private_data(parent_folder, &parent_folder_private_data); parent_object = (struct emsmdbp_object *)parent_folder_private_data; if (!parent_object || parent_object->type != EMSMDBP_OBJECT_FOLDER) { mapi_repl->error_code = MAPI_E_NO_SUPPORT; goto delete_message_response; } if (!emsmdbp_is_mapistore(parent_object) ) { DEBUG(0, ("Got parent folder not in mapistore\n")); mapi_repl->error_code = MAPI_E_NO_SUPPORT; goto delete_message_response; } contextID = emsmdbp_get_contextID(parent_object); owner = emsmdbp_get_owner(parent_object); for (i = 0; i < mapi_req->u.mapi_DeleteMessages.cn_ids; ++i) { int ret; uint64_t mid = mapi_req->u.mapi_DeleteMessages.message_ids[i]; DEBUG(0, ("MID %i to delete: 0x%.16"PRIx64"\n", i, mid)); ret = mapistore_folder_delete_message(emsmdbp_ctx->mstore_ctx, contextID, parent_object->backend_object, mid, MAPISTORE_SOFT_DELETE); if (ret != MAPISTORE_SUCCESS && ret != MAPISTORE_ERR_NOT_FOUND) { if (ret == MAPISTORE_ERR_DENIED) { mapi_repl->error_code = MAPI_E_NO_ACCESS; } else { mapi_repl->error_code = MAPI_E_CALL_FAILED; } goto delete_message_response; } ret = mapistore_indexing_record_del_mid(emsmdbp_ctx->mstore_ctx, contextID, owner, mid, MAPISTORE_SOFT_DELETE); if (ret != MAPISTORE_SUCCESS) { mapi_repl->error_code = MAPI_E_CALL_FAILED; goto delete_message_response; } } delete_message_response: *size += libmapiserver_RopDeleteMessage_size(mapi_repl); return MAPI_E_SUCCESS; } /** \details EcDoRpc SetSearchCriteria (0x30) Rop. This operation sets the search criteria for a search folder. \param mem_ctx pointer to the memory context \param emsmdbp_ctx pointer to the emsmdb provider context \param mapi_req pointer to the SetSearchCriteria EcDoRpc_MAPI_REQ structure \param mapi_repl pointer to the SetSearchCriteria EcDoRpc_MAPI_REPL structure \param handles pointer to the MAPI handles array \param size pointer to the mapi_response size to update \return MAPI_E_SUCCESS on success, otherwise MAPI error */ _PUBLIC_ enum MAPISTATUS EcDoRpc_RopSetSearchCriteria(TALLOC_CTX *mem_ctx, struct emsmdbp_context *emsmdbp_ctx, struct EcDoRpc_MAPI_REQ *mapi_req, struct EcDoRpc_MAPI_REPL *mapi_repl, uint32_t *handles, uint16_t *size) { DEBUG(4, ("exchange_emsmdb: [OXCFOLD] SetSearchCriteria (0x30)\n")); /* Sanity checks */ OPENCHANGE_RETVAL_IF(!emsmdbp_ctx, MAPI_E_NOT_INITIALIZED, NULL); OPENCHANGE_RETVAL_IF(!mapi_req, MAPI_E_INVALID_PARAMETER, NULL); OPENCHANGE_RETVAL_IF(!mapi_repl, MAPI_E_INVALID_PARAMETER, NULL); OPENCHANGE_RETVAL_IF(!handles, MAPI_E_INVALID_PARAMETER, NULL); OPENCHANGE_RETVAL_IF(!size, MAPI_E_INVALID_PARAMETER, NULL); mapi_repl->opnum = mapi_req->opnum; mapi_repl->handle_idx = mapi_req->handle_idx; mapi_repl->error_code = MAPI_E_SUCCESS; /* TODO: actually implement this */ *size += libmapiserver_RopSetSearchCriteria_size(mapi_repl); return MAPI_E_SUCCESS; } /** \details EcDoRpc GetSearchCriteria (0x31) Rop. This operation gets the search criteria for a search folder. \param mem_ctx pointer to the memory context \param emsmdbp_ctx pointer to the emsmdb provider context \param mapi_req pointer to the GetSearchCriteria EcDoRpc_MAPI_REQ structure \param mapi_repl pointer to the GetSearchCriteria EcDoRpc_MAPI_REPL structure \param handles pointer to the MAPI handles array \param size pointer to the mapi_response size to update \return MAPI_E_SUCCESS on success, otherwise MAPI error */ _PUBLIC_ enum MAPISTATUS EcDoRpc_RopGetSearchCriteria(TALLOC_CTX *mem_ctx, struct emsmdbp_context *emsmdbp_ctx, struct EcDoRpc_MAPI_REQ *mapi_req, struct EcDoRpc_MAPI_REPL *mapi_repl, uint32_t *handles, uint16_t *size) { /* struct mapi_SRestriction *res; */ DEBUG(4, ("exchange_emsmdb: [OXCFOLD] GetSearchCriteria (0x31)\n")); /* Sanity checks */ OPENCHANGE_RETVAL_IF(!emsmdbp_ctx, MAPI_E_NOT_INITIALIZED, NULL); OPENCHANGE_RETVAL_IF(!mapi_req, MAPI_E_INVALID_PARAMETER, NULL); OPENCHANGE_RETVAL_IF(!mapi_repl, MAPI_E_INVALID_PARAMETER, NULL); OPENCHANGE_RETVAL_IF(!handles, MAPI_E_INVALID_PARAMETER, NULL); OPENCHANGE_RETVAL_IF(!size, MAPI_E_INVALID_PARAMETER, NULL); mapi_repl->opnum = mapi_req->opnum; mapi_repl->handle_idx = mapi_req->handle_idx; mapi_repl->error_code = MAPI_E_SUCCESS; /* res = NULL; */ mapi_repl->u.mapi_GetSearchCriteria.RestrictionDataSize = 0; mapi_repl->u.mapi_GetSearchCriteria.LogonId = mapi_req->logon_id; mapi_repl->u.mapi_GetSearchCriteria.FolderIdCount = 0; mapi_repl->u.mapi_GetSearchCriteria.FolderIds = NULL; mapi_repl->u.mapi_GetSearchCriteria.SearchFlags = 0; /* TODO: actually implement this */ *size += libmapiserver_RopGetSearchCriteria_size(mapi_repl); return MAPI_E_SUCCESS; } static enum MAPISTATUS RopEmptyFolder_GenericFolder(TALLOC_CTX *mem_ctx, struct emsmdbp_context *emsmdbp_ctx, struct EmptyFolder_req request, struct EmptyFolder_repl *response, struct mapi_handles *folder) { enum MAPISTATUS ret = MAPI_E_SUCCESS; void *folder_priv; struct emsmdbp_object *folder_object = NULL; uint32_t context_id; enum mapistore_error retval; uint64_t *childFolders; uint32_t childFolderCount; uint32_t i; uint8_t flags = DELETE_HARD_DELETE| DEL_MESSAGES | DEL_FOLDERS; TALLOC_CTX *local_mem_ctx; void *subfolder; /* Step 1. Retrieve the fid for the folder, given the handle */ mapi_handles_get_private_data(folder, &folder_priv); folder_object = (struct emsmdbp_object *) folder_priv; if (!folder_object) { DEBUG(4, ("exchange_emsmdb: [OXCFOLD] EmptyFolder null object")); return MAPI_E_NO_SUPPORT; } if (folder_object->type != EMSMDBP_OBJECT_FOLDER) { DEBUG(4, ("exchange_emsmdb: [OXCFOLD] EmptyFolder wrong object type: 0x%x\n", folder_object->type)); return MAPI_E_NO_SUPPORT; } context_id = emsmdbp_get_contextID(folder_object); local_mem_ctx = talloc_zero(NULL, TALLOC_CTX); retval = mapistore_folder_get_child_fmids(emsmdbp_ctx->mstore_ctx, context_id, folder_object->backend_object, MAPISTORE_FOLDER_TABLE, local_mem_ctx, &childFolders, &childFolderCount); if (retval) { DEBUG(4, ("exchange_emsmdb: [OXCFOLD] EmptyFolder bad retval: 0x%x", retval)); ret = MAPI_E_NOT_FOUND; goto end; } /* Step 3. Delete contents of the folder in mapistore */ for (i = 0; i < childFolderCount; ++i) { retval = mapistore_folder_open_folder(emsmdbp_ctx->mstore_ctx, context_id, folder, local_mem_ctx, childFolders[i], &subfolder); if (retval != MAPISTORE_SUCCESS) { ret = MAPI_E_NOT_FOUND; goto end; } retval = mapistore_folder_delete(emsmdbp_ctx->mstore_ctx, context_id, subfolder, flags); if (retval) { DEBUG(4, ("exchange_emsmdb: [OXCFOLD] EmptyFolder failed to delete fid 0x%.16"PRIx64" (0x%x)", childFolders[i], retval)); ret = MAPI_E_NOT_FOUND; goto end; } } end: talloc_free(local_mem_ctx); return ret; } /** \details EcDoRpc EmptyFolder (0x58) Rop. This operation removes the sub-folders and messages from a given parent folder. \param mem_ctx pointer to the memory context \param emsmdbp_ctx pointer to the emsmdb provider context \param mapi_req pointer to the EmptyFolder EcDoRpc_MAPI_REQ structure \param mapi_repl pointer to the EmptyFolder EcDoRpc_MAPI_REPL structure \param handles pointer to the MAPI handles array \param size pointer to the mapi_response size to update \return MAPI_E_SUCCESS on success, otherwise MAPI error */ _PUBLIC_ enum MAPISTATUS EcDoRpc_RopEmptyFolder(TALLOC_CTX *mem_ctx, struct emsmdbp_context *emsmdbp_ctx, struct EcDoRpc_MAPI_REQ *mapi_req, struct EcDoRpc_MAPI_REPL *mapi_repl, uint32_t *handles, uint16_t *size) { enum MAPISTATUS retval; struct mapi_handles *folder = NULL; struct emsmdbp_object *folder_object; void *private_data; bool mapistore = false; DEBUG(4, ("exchange_emsmdb: [OXCFOLD] EmptyFolder (0x58)\n")); /* Sanity checks */ OPENCHANGE_RETVAL_IF(!emsmdbp_ctx, MAPI_E_NOT_INITIALIZED, NULL); OPENCHANGE_RETVAL_IF(!mapi_req, MAPI_E_INVALID_PARAMETER, NULL); OPENCHANGE_RETVAL_IF(!mapi_repl, MAPI_E_INVALID_PARAMETER, NULL); OPENCHANGE_RETVAL_IF(!handles, MAPI_E_INVALID_PARAMETER, NULL); OPENCHANGE_RETVAL_IF(!size, MAPI_E_INVALID_PARAMETER, NULL); mapi_repl->opnum = mapi_req->opnum; mapi_repl->handle_idx = mapi_req->handle_idx; mapi_repl->u.mapi_EmptyFolder.PartialCompletion = 0; /* Step 1. Retrieve folder handle */ retval = mapi_handles_search(emsmdbp_ctx->handles_ctx, handles[mapi_req->handle_idx], &folder); OPENCHANGE_RETVAL_IF(retval, retval, NULL); mapi_handles_get_private_data(folder, &private_data); folder_object = private_data; mapistore = emsmdbp_is_mapistore(folder_object); switch (mapistore) { case false: /* system/special folder */ DEBUG(0, ("TODO Empty system/special folder\n")); #if 0 retval = RopEmptyFolder_SystemSpecialFolder(mem_ctx, emsmdbp_ctx, mapi_req->u.mapi_EmptyFolder, &mapi_repl->u.mapi_EmptyFolder); #endif retval = MAPI_E_SUCCESS; // TODO: temporary hack. mapi_repl->error_code = retval; break; case true: /* handled by mapistore */ retval = RopEmptyFolder_GenericFolder(mem_ctx, emsmdbp_ctx, mapi_req->u.mapi_EmptyFolder, &mapi_repl->u.mapi_EmptyFolder, folder); mapi_repl->error_code = retval; break; } *size += libmapiserver_RopEmptyFolder_size(mapi_repl); /* reply filled in above */ return MAPI_E_SUCCESS; } /** */ _PUBLIC_ enum MAPISTATUS EcDoRpc_RopMoveCopyMessages(TALLOC_CTX *mem_ctx, struct emsmdbp_context *emsmdbp_ctx, struct EcDoRpc_MAPI_REQ *mapi_req, struct EcDoRpc_MAPI_REPL *mapi_repl, uint32_t *handles, uint16_t *size) { enum MAPISTATUS retval; uint32_t handle; uint32_t contextID; struct mapi_handles *rec = NULL; void *private_data = NULL; struct emsmdbp_object *destination_object; struct emsmdbp_object *source_object; uint64_t *targetMIDs; uint32_t i; bool mapistore = false; DEBUG(4, ("exchange_emsmdb: [OXCFOLD] RopMoveCopyMessages (0x33)\n")); /* Sanity checks */ OPENCHANGE_RETVAL_IF(!emsmdbp_ctx, MAPI_E_NOT_INITIALIZED, NULL); OPENCHANGE_RETVAL_IF(!mapi_req, MAPI_E_INVALID_PARAMETER, NULL); OPENCHANGE_RETVAL_IF(!mapi_repl, MAPI_E_INVALID_PARAMETER, NULL); OPENCHANGE_RETVAL_IF(!handles, MAPI_E_INVALID_PARAMETER, NULL); OPENCHANGE_RETVAL_IF(!size, MAPI_E_INVALID_PARAMETER, NULL); mapi_repl->opnum = mapi_req->opnum; mapi_repl->error_code = MAPI_E_SUCCESS; mapi_repl->handle_idx = mapi_req->handle_idx; mapi_repl->u.mapi_MoveCopyMessages.PartialCompletion = 0; /* Get the destionation information */ handle = handles[mapi_req->u.mapi_MoveCopyMessages.handle_idx]; retval = mapi_handles_search(emsmdbp_ctx->handles_ctx, handle, &rec); if (retval) { mapi_repl->error_code = MAPI_E_INVALID_OBJECT; DEBUG(5, (" handle (%x) not found: %x\n", handle, mapi_req->handle_idx)); goto end; } retval = mapi_handles_get_private_data(rec, &private_data); /* object is our destination folder */ destination_object = private_data; if (!destination_object) { mapi_repl->error_code = MAPI_E_INVALID_OBJECT; DEBUG(5, (" object (%x) not found: %x\n", handle, mapi_req->handle_idx)); goto end; } /* Get the source folder information */ handle = handles[mapi_req->handle_idx]; retval = mapi_handles_search(emsmdbp_ctx->handles_ctx, handle, &rec); if (retval) { mapi_repl->error_code = MAPI_E_INVALID_OBJECT; DEBUG(5, (" handle (%x) not found: %x\n", handle, mapi_req->handle_idx)); goto end; } retval = mapi_handles_get_private_data(rec, &private_data); source_object = private_data; if (!source_object) { mapi_repl->error_code = MAPI_E_INVALID_OBJECT; DEBUG(5, (" object (%x) not found: %x\n", handle, mapi_req->u.mapi_MoveCopyMessages.handle_idx)); goto end; } contextID = emsmdbp_get_contextID(destination_object); mapistore = emsmdbp_is_mapistore(source_object); if (mapistore) { /* We prepare a set of new MIDs for the backend */ targetMIDs = talloc_array(NULL, uint64_t, mapi_req->u.mapi_MoveCopyMessages.count); for (i = 0; i < mapi_req->u.mapi_MoveCopyMessages.count; i++) { openchangedb_get_new_folderID(emsmdbp_ctx->oc_ctx, &targetMIDs[i]); } /* We invoke the backend method */ mapistore_folder_move_copy_messages(emsmdbp_ctx->mstore_ctx, contextID, destination_object->backend_object, source_object->backend_object, mem_ctx, mapi_req->u.mapi_MoveCopyMessages.count, mapi_req->u.mapi_MoveCopyMessages.message_id, targetMIDs, NULL, mapi_req->u.mapi_MoveCopyMessages.WantCopy); talloc_free(targetMIDs); /* /\* The backend might do this for us. In any case, we try to add it ourselves *\/ */ /* mapistore_indexing_record_add_mid(emsmdbp_ctx->mstore_ctx, contextID, targetMID); */ } else { DEBUG(0, ("["__location__"] - mapistore support not implemented yet - shouldn't occur\n")); mapi_repl->error_code = MAPI_E_NO_SUPPORT; } end: *size += libmapiserver_RopMoveCopyMessages_size(mapi_repl); return MAPI_E_SUCCESS; } /** \details EcDoRpc EmptyFolder (0x58) Rop. This operation removes the sub-folders and messages from a given parent folder. \param mem_ctx pointer to the memory context \param emsmdbp_ctx pointer to the emsmdb provider context \param mapi_req pointer to the EmptyFolder EcDoRpc_MAPI_REQ structure \param mapi_repl pointer to the EmptyFolder EcDoRpc_MAPI_REPL structure \param handles pointer to the MAPI handles array \param size pointer to the mapi_response size to update \return MAPI_E_SUCCESS on success, otherwise MAPI error */ enum MAPISTATUS EcDoRpc_RopMoveFolder(TALLOC_CTX *mem_ctx, struct emsmdbp_context *emsmdbp_ctx, struct EcDoRpc_MAPI_REQ *mapi_req, struct EcDoRpc_MAPI_REPL *mapi_repl, uint32_t *handles, uint16_t *size) { enum MAPISTATUS retval; enum mapistore_error ret; uint32_t handle; struct mapi_handles *handle_object; void *private_data; struct MoveFolder_req *request; struct MoveFolder_repl *response; struct emsmdbp_object *source_parent; struct emsmdbp_object *move_folder; struct emsmdbp_object *target_folder; DEBUG(4, ("exchange_emsmdb: [OXCSTOR] MoveFolder (0x35)\n")); /* Sanity checks */ OPENCHANGE_RETVAL_IF(!emsmdbp_ctx, MAPI_E_NOT_INITIALIZED, NULL); OPENCHANGE_RETVAL_IF(!mapi_req, MAPI_E_INVALID_PARAMETER, NULL); OPENCHANGE_RETVAL_IF(!mapi_repl, MAPI_E_INVALID_PARAMETER, NULL); OPENCHANGE_RETVAL_IF(!handles, MAPI_E_INVALID_PARAMETER, NULL); OPENCHANGE_RETVAL_IF(!size, MAPI_E_INVALID_PARAMETER, NULL); mapi_repl->opnum = mapi_req->opnum; mapi_repl->handle_idx = mapi_req->handle_idx; mapi_repl->error_code = MAPI_E_SUCCESS; request = &mapi_req->u.mapi_MoveFolder; response = &mapi_repl->u.mapi_MoveFolder; /* Retrieve the source parent handle in the hierarchy */ handle = handles[mapi_req->handle_idx]; retval = mapi_handles_search(emsmdbp_ctx->handles_ctx, handle, &handle_object); if (retval) { DEBUG(5, (" handle (%x) not found: %x\n", handle, mapi_req->handle_idx)); mapi_repl->error_code = MAPI_E_INVALID_OBJECT; goto end; } mapi_handles_get_private_data(handle_object, &private_data); source_parent = private_data; if (!source_parent || source_parent->type != EMSMDBP_OBJECT_FOLDER) { DEBUG(5, (" invalid handle (%x): %x\n", handle, mapi_req->handle_idx)); mapi_repl->error_code = MAPI_E_INVALID_OBJECT; goto end; } /* Open the folder being moved as it will be the actor object in this process */ ret = emsmdbp_object_open_folder(mem_ctx, emsmdbp_ctx, source_parent, request->FolderId, &move_folder); if (ret != MAPISTORE_SUCCESS) { mapi_repl->error_code = mapistore_error_to_mapi(ret); goto end; } /* Retrieve the destination parent handle in the hierarchy */ handle = handles[request->handle_idx]; retval = mapi_handles_search(emsmdbp_ctx->handles_ctx, handle, &handle_object); if (retval) { DEBUG(5, (" handle (%x) not found: %x\n", handle, mapi_req->handle_idx)); mapi_repl->error_code = MAPI_E_INVALID_OBJECT; goto end; } mapi_handles_get_private_data(handle_object, &private_data); target_folder = private_data; if (!target_folder || target_folder->type != EMSMDBP_OBJECT_FOLDER) { DEBUG(5, (" invalid handle (%x): %x\n", handle, mapi_req->handle_idx)); mapi_repl->error_code = MAPI_E_INVALID_OBJECT; goto end; } ret = emsmdbp_folder_move_folder(emsmdbp_ctx, move_folder, target_folder, mem_ctx, request->NewFolderName.lpszW); mapi_repl->error_code = mapistore_error_to_mapi(ret); response->PartialCompletion = false; end: *size += libmapiserver_RopMoveFolder_size(mapi_repl); handles[mapi_repl->handle_idx] = handles[mapi_req->handle_idx]; return MAPI_E_SUCCESS; } /** \details EcDoRpc EmptyFolder (0x58) Rop. This operation removes the sub-folders and messages from a given parent folder. \param mem_ctx pointer to the memory context \param emsmdbp_ctx pointer to the emsmdb provider context \param mapi_req pointer to the EmptyFolder EcDoRpc_MAPI_REQ structure \param mapi_repl pointer to the EmptyFolder EcDoRpc_MAPI_REPL structure \param handles pointer to the MAPI handles array \param size pointer to the mapi_response size to update \return MAPI_E_SUCCESS on success, otherwise MAPI error */ enum MAPISTATUS EcDoRpc_RopCopyFolder(TALLOC_CTX *mem_ctx, struct emsmdbp_context *emsmdbp_ctx, struct EcDoRpc_MAPI_REQ *mapi_req, struct EcDoRpc_MAPI_REPL *mapi_repl, uint32_t *handles, uint16_t *size) { enum MAPISTATUS retval; enum mapistore_error ret; uint32_t handle; struct mapi_handles *handle_object; void *private_data; struct CopyFolder_req *request; struct CopyFolder_repl *response; struct emsmdbp_object *source_parent; struct emsmdbp_object *copy_folder; struct emsmdbp_object *target_folder; uint32_t contextID; DEBUG(4, ("exchange_emsmdb: [OXCSTOR] CopyFolder (0x36)\n")); /* Sanity checks */ OPENCHANGE_RETVAL_IF(!emsmdbp_ctx, MAPI_E_NOT_INITIALIZED, NULL); OPENCHANGE_RETVAL_IF(!mapi_req, MAPI_E_INVALID_PARAMETER, NULL); OPENCHANGE_RETVAL_IF(!mapi_repl, MAPI_E_INVALID_PARAMETER, NULL); OPENCHANGE_RETVAL_IF(!handles, MAPI_E_INVALID_PARAMETER, NULL); OPENCHANGE_RETVAL_IF(!size, MAPI_E_INVALID_PARAMETER, NULL); mapi_repl->opnum = mapi_req->opnum; mapi_repl->handle_idx = mapi_req->handle_idx; mapi_repl->error_code = MAPI_E_SUCCESS; request = &mapi_req->u.mapi_CopyFolder; response = &mapi_repl->u.mapi_CopyFolder; /* Retrieve the source parent handle in the hierarchy */ handle = handles[mapi_req->handle_idx]; retval = mapi_handles_search(emsmdbp_ctx->handles_ctx, handle, &handle_object); if (retval) { DEBUG(5, (" handle (%x) not found: %x\n", handle, mapi_req->handle_idx)); mapi_repl->error_code = MAPI_E_INVALID_OBJECT; goto end; } mapi_handles_get_private_data(handle_object, &private_data); source_parent = private_data; if (!source_parent || source_parent->type != EMSMDBP_OBJECT_FOLDER) { DEBUG(5, (" invalid handle (%x): %x\n", handle, mapi_req->handle_idx)); mapi_repl->error_code = MAPI_E_INVALID_OBJECT; goto end; } /* Open the folder being copied as it will be the actor object in this process */ ret = emsmdbp_object_open_folder(mem_ctx, emsmdbp_ctx, source_parent, request->FolderId, ©_folder); if (ret != MAPISTORE_SUCCESS) { mapi_repl->error_code = mapistore_error_to_mapi(ret); goto end; } /* TODO: we should provide the ability to perform this operation between non-mapistore objects or between mapistore and non-mapistore objects */ if (!emsmdbp_is_mapistore(copy_folder)) { mapi_repl->error_code = MAPI_E_NO_ACCESS; goto end; } /* Retrieve the destination parent handle in the hierarchy */ handle = handles[request->handle_idx]; retval = mapi_handles_search(emsmdbp_ctx->handles_ctx, handle, &handle_object); if (retval) { DEBUG(5, (" handle (%x) not found: %x\n", handle, mapi_req->handle_idx)); mapi_repl->error_code = MAPI_E_INVALID_OBJECT; goto end; } mapi_handles_get_private_data(handle_object, &private_data); target_folder = private_data; if (!target_folder || target_folder->type != EMSMDBP_OBJECT_FOLDER) { DEBUG(5, (" invalid handle (%x): %x\n", handle, mapi_req->handle_idx)); mapi_repl->error_code = MAPI_E_INVALID_OBJECT; goto end; } if (!emsmdbp_is_mapistore(target_folder)) { mapi_repl->error_code = MAPI_E_NO_ACCESS; goto end; } contextID = emsmdbp_get_contextID(copy_folder); ret = mapistore_folder_copy_folder(emsmdbp_ctx->mstore_ctx, contextID, copy_folder->backend_object, target_folder->backend_object, mem_ctx, request->WantRecursive, request->NewFolderName.lpszW); mapi_repl->error_code = mapistore_error_to_mapi(ret); response->PartialCompletion = false; end: *size += libmapiserver_RopCopyFolder_size(mapi_repl); handles[mapi_repl->handle_idx] = handles[mapi_req->handle_idx]; return MAPI_E_SUCCESS; } openchange-2.0/mapiproxy/servers/default/emsmdb/oxcfxics.c000066400000000000000000004224111223057412600240760ustar00rootroot00000000000000/* OpenChange Server implementation EMSMDBP: EMSMDB Provider implementation Copyright (C) Wolfgang Sourdeau 2010-2012 This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see . */ /** \file oxcfxics.c \brief FastTransfer and ICS object routines and Rops */ #include "mapiproxy/libmapiserver/libmapiserver.h" #include "dcesrv_exchange_emsmdb.h" #include "gen_ndr/ndr_exchange.h" /* a constant time offset by which the first change number ever can be produced by OpenChange */ #define oc_version_time 0x4dbb2dbe /* the maximum buffer that will be populated during msg synchronization operations (note: this is a soft limit) */ static const size_t max_message_sync_size = 262144; static const uint32_t message_preload_interval = 150; /** notes: * conventions: - binary data must be returned as Binary_r - PidTagChangeNumber, PidTagChangeKey and PidTagPredecessorChangeList *must* be handled by the backend code - PidTagSourceKey, PidTagParentSourceKey are deduced automatically from PidTagMid/PidTagFolderId and PidTagParentFolderId * PidTag*Key should be computed in the same manner in oxcprpt and oxctabl - all string properties are fetched via their _UNICODE version - "PidTagLastModificationTime" is left to the backend, maybe setprops operations could provide an optional one, for reference... ? idea: getprops on tables and objects without property array = get all props * no deletions yet for non-mapistore objects * no conflict resolution * ImportHierarchyChange require the same changes as RopOpenFolder with regards to opening folder and mapistore v2 functionality * there is a hack with get props and get table props for root mapistore folders, that can be solved with mapistore v2 * another missing feature (3.3.5.5.4.1.1): "A move of a folder from one parent to another is modeled as a modification of a folder, where the value of PidTagParentSourceKey of the folder changes to reflect the new parent." * HACK: CnsetSeen = CnsetSeenFAI = CnsetRead */ struct oxcfxics_prop_index { uint32_t parent_fid; uint32_t eid; uint32_t change_number; /* PidTagChangeNumber */ uint32_t change_key; /* PidTagChangeKey */ uint32_t predecessor_change_list; uint32_t last_modification_time; uint32_t display_name; uint32_t associated; uint32_t message_size; }; struct oxcfxics_sync_data { struct GUID replica_guid; uint8_t table_type; struct oxcfxics_prop_index prop_index; struct ndr_push *ndr; struct ndr_push *cutmarks_ndr; struct rawidset *eid_set; struct rawidset *cnset_seen; struct rawidset *cnset_read; struct rawidset *deleted_eid_set; struct oxcfxics_message_sync_data *message_sync_data; }; struct oxcfxics_message_sync_data { uint64_t *mids; uint64_t count; uint64_t max; }; /** ndr helpers */ #if 1 #define oxcfxics_ndr_check(x,y) #else static void oxcfxics_ndr_check(struct ndr_push *ndr, const char *label) { if (ndr->data == NULL) { DEBUG(5, ("ndr->data is null!!!\n")); abort(); } if (ndr->offset >= ndr->alloc_size) { DEBUG(5, ("inconcistency: ndr->alloc_size must be > ndr->offset\n")); abort(); } DEBUG(5, ("'%s' state: ptr: %p alloc: %d offset: %d\n", label, ndr->data, ndr->alloc_size, ndr->offset)); } #endif #if 1 #define oxcfxics_check_cutmark_buffer(x,y) #else static void oxcfxics_check_cutmark_buffer(void *cutmark_buffer, DATA_BLOB *data_buffer) { uint32_t *digits_ptr; uint32_t min_size, prev_cutmark, cutmark; bool done; digits_ptr = cutmark_buffer; prev_cutmark = 0; done = false; while (!done) { cutmark = digits_ptr[1]; if (cutmark == 0xffffffff) { done = true; } else { min_size = digits_ptr[0]; if (min_size > 0) { if (min_size != 4 && min_size != 8) { DEBUG(0, ("invalid min_size: %d\n", min_size)); abort(); } } if (cutmark < prev_cutmark && prev_cutmark > 0) { DEBUG(0, ("cutmark goes backward\n")); abort(); } if (cutmark > data_buffer->length) { DEBUG(0, ("cutmark goes beyond the buffer size\n")); abort(); } digits_ptr += 2; } } } #endif static const int message_properties_shift = 7; static const int folder_properties_shift = 7; static void oxcfxics_ndr_push_simple_data(struct ndr_push *ndr, uint16_t prop_type, const void *value) { uint32_t string_len; uint32_t saved_flags; const struct Binary_r *bin_value; switch (prop_type) { case PT_I2: ndr_push_uint16(ndr, NDR_SCALARS, *(uint16_t *) value); break; case PT_LONG: case PT_ERROR: case PT_OBJECT: ndr_push_uint32(ndr, NDR_SCALARS, *(uint32_t *) value); break; case PT_DOUBLE: ndr_push_double(ndr, NDR_SCALARS, *(double *) value); break; case PT_I8: ndr_push_dlong(ndr, NDR_SCALARS, *(uint64_t *) value); break; case PT_BOOLEAN: ndr_push_uint16(ndr, NDR_SCALARS, (*(uint8_t *) value) ? 1 : 0); break; case PT_STRING8: saved_flags = ndr->flags; string_len = strlen(value) + 1; ndr_push_uint32(ndr, NDR_SCALARS, string_len); ndr_set_flags(&ndr->flags, LIBNDR_FLAG_STR_NULLTERM|LIBNDR_FLAG_STR_ASCII); ndr_push_string(ndr, NDR_SCALARS, (char *) value); ndr->flags = saved_flags; break; case PT_UNICODE: saved_flags = ndr->flags; string_len = strlen_m_ext((char *) value, CH_UTF8, CH_UTF16LE) * 2 + 2; ndr_push_uint32(ndr, NDR_SCALARS, string_len); ndr_set_flags(&ndr->flags, LIBNDR_FLAG_STR_NULLTERM); ndr_push_string(ndr, NDR_SCALARS, (char *) value); ndr->flags = saved_flags; break; case PT_SVREID: case PT_BINARY: bin_value = value; if (bin_value->cb > 0) { ndr_push_Binary_r(ndr, NDR_BUFFERS, bin_value); } else { ndr_push_uint32(ndr, NDR_SCALARS, 0); } break; case PT_CLSID: ndr_push_GUID(ndr, NDR_SCALARS, (struct GUID *) value); break; case PT_SYSTIME: ndr_push_FILETIME(ndr, NDR_SCALARS, (struct FILETIME *) value); break; case PT_NULL: break; default: DEBUG(5, ("%s: unsupported property type: %.4x\n", __FUNCTION__, prop_type)); abort(); } } static uint32_t oxcfxics_compute_cutmark_min_value_buffer(uint16_t prop_type) { uint32_t min_value_buffer; if ((prop_type & MV_FLAG)) { /* TODO: minimal cutmarks are difficult to deduce for multi values */ min_value_buffer = 8; } else { switch (prop_type) { case PT_I2: case PT_LONG: case PT_ERROR: case PT_OBJECT: case PT_FLOAT: case PT_DOUBLE: case PT_I8: case PT_BOOLEAN: case PT_SYSTIME: case PT_CLSID: min_value_buffer = 0; break; case PT_STRING8: case PT_UNICODE: case PT_SVREID: case PT_BINARY: min_value_buffer = 8; break; default: DEBUG(5, ("%s: unsupported property type: %.4x\n", __FUNCTION__, prop_type)); abort(); } } return min_value_buffer; } static void oxcfxics_ndr_push_properties(struct ndr_push *ndr, struct ndr_push *cutmarks_ndr, void *nprops_ctx, struct SPropTagArray *properties, void **data_pointers, enum MAPISTATUS *retvals) { uint32_t i, j, min_value_buffer; enum MAPITAGS property; struct MAPINAMEID *nameid; struct BinaryArray_r *bin_array; struct StringArrayW_r *unicode_array; struct ShortArray_r *short_array; struct LongArray_r *long_array; struct UI8Array_r *ui8_array; uint16_t prop_type, propID; int retval; uint32_t saved_flags; for (i = 0; i < properties->cValues; i++) { if (retvals[i] == MAPI_E_SUCCESS) { property = properties->aulPropTag[i]; prop_type = property & 0xffff; ndr_push_uint32(ndr, NDR_SCALARS, property); if (property > 0x80000000) { propID = property >> 16; retval = mapistore_namedprops_get_nameid(nprops_ctx, propID, NULL, &nameid); if (retval != MAPISTORE_SUCCESS) { DEBUG(0, ("no definition found for named property with id '%.8x'\n", property)); continue; } ndr_push_GUID(ndr, NDR_SCALARS, &nameid->lpguid); switch (nameid->ulKind) { case MNID_ID: ndr_push_uint8(ndr, NDR_SCALARS, 0); ndr_push_uint32(ndr, NDR_SCALARS, nameid->kind.lid); break; case MNID_STRING: saved_flags = ndr->flags; ndr_push_uint8(ndr, NDR_SCALARS, 1); ndr_set_flags(&ndr->flags, LIBNDR_FLAG_STR_NULLTERM); ndr_push_string(ndr, NDR_SCALARS, nameid->kind.lpwstr.Name); ndr->flags = saved_flags; break; } talloc_free(nameid); } ndr_push_uint32(cutmarks_ndr, NDR_SCALARS, 0); ndr_push_uint32(cutmarks_ndr, NDR_SCALARS, ndr->offset); if ((prop_type & MV_FLAG)) { prop_type &= 0x0fff; switch (prop_type) { case PT_SHORT: short_array = data_pointers[i]; ndr_push_uint32(ndr, NDR_SCALARS, short_array->cValues); for (j = 0; j < short_array->cValues; j++) { oxcfxics_ndr_push_simple_data(ndr, prop_type, short_array->lpi + j); } break; case PT_LONG: long_array = data_pointers[i]; ndr_push_uint32(ndr, NDR_SCALARS, long_array->cValues); for (j = 0; j < long_array->cValues; j++) { oxcfxics_ndr_push_simple_data(ndr, prop_type, long_array->lpl + j); } break; case PT_I8: ui8_array = data_pointers[i]; ndr_push_uint32(ndr, NDR_SCALARS, ui8_array->cValues); for (j = 0; j < ui8_array->cValues; j++) { oxcfxics_ndr_push_simple_data(ndr, prop_type, ui8_array->lpui8 + j); } break; case PT_BINARY: bin_array = data_pointers[i]; ndr_push_uint32(ndr, NDR_SCALARS, bin_array->cValues); for (j = 0; j < bin_array->cValues; j++) { oxcfxics_ndr_push_simple_data(ndr, prop_type, bin_array->lpbin + j); } break; case PT_UNICODE: unicode_array = data_pointers[i]; ndr_push_uint32(ndr, NDR_SCALARS, unicode_array->cValues); for (j = 0; j < unicode_array->cValues; j++) { oxcfxics_ndr_push_simple_data(ndr, prop_type, unicode_array->lppszW[j]); } break; default: DEBUG(5, (__location__": no handling for multi values of type %.4x\n", prop_type)); abort(); } } else { oxcfxics_ndr_push_simple_data(ndr, prop_type, data_pointers[i]); } min_value_buffer = oxcfxics_compute_cutmark_min_value_buffer(prop_type); ndr_push_uint32(cutmarks_ndr, NDR_SCALARS, min_value_buffer); ndr_push_uint32(cutmarks_ndr, NDR_SCALARS, ndr->offset); } } } static int oxcfxics_fmid_from_source_key(struct emsmdbp_context *emsmdbp_ctx, const char *owner, struct SBinary_short *source_key, uint64_t *fmidp) { uint64_t fmid, base; uint16_t replid; const uint8_t *bytes; int i; if (emsmdbp_guid_to_replid(emsmdbp_ctx, owner, (const struct GUID *) source_key->lpb, &replid)) { return MAPISTORE_ERROR; } bytes = source_key->lpb + 16; fmid = 0; base = 1; for (i = 0; i < 6; i++) { fmid |= (uint64_t) bytes[i] * base; base <<= 8; } fmid <<= 16; fmid |= replid; *fmidp = fmid; return MAPISTORE_SUCCESS; } static struct Binary_r *oxcfxics_make_xid(TALLOC_CTX *mem_ctx, struct GUID *replica_guid, uint64_t *id, uint8_t idlength) { struct ndr_push *ndr; struct Binary_r *data; uint8_t i; uint64_t current_id; if (!mem_ctx) return NULL; if (!replica_guid || !id) return NULL; if (idlength > 8) return NULL; /* GUID */ ndr = ndr_push_init_ctx(NULL); ndr_set_flags(&ndr->flags, LIBNDR_FLAG_NOALIGN); ndr->offset = 0; ndr_push_GUID(ndr, NDR_SCALARS, replica_guid); /* id */ current_id = *id; for (i = 0; i < idlength; i++) { ndr_push_uint8(ndr, NDR_SCALARS, current_id & 0xff); current_id >>= 8; } data = talloc_zero(mem_ctx, struct Binary_r); data->cb = ndr->offset; data->lpb = ndr->data; (void) talloc_reference(data, ndr->data); talloc_free(ndr); return data; } static inline struct Binary_r *oxcfxics_make_gid(TALLOC_CTX *mem_ctx, struct GUID *replica_guid, uint64_t id) { return oxcfxics_make_xid(mem_ctx, replica_guid, &id, 6); } /** \details EcDoRpc EcDoRpc_RopFastTransferSourceCopyTo (0x4d) Rop. This operation initializes a FastTransfer operation to download content from a given messaging object and its descendant subobjects. \param mem_ctx pointer to the memory context \param emsmdbp_ctx pointer to the emsmdb provider context \param mapi_req pointer to the EcDoRpc_RopFastTransferSourceCopyTo EcDoRpc_MAPI_REQ structure \param mapi_repl pointer to the EcDoRpc_RopFastTransferSourceCopyTo EcDoRpc_MAPI_REPL structure \param handles pointer to the MAPI handles array \param size pointer to the mapi_response size to update \return MAPI_E_SUCCESS on success, otherwise MAPI error */ _PUBLIC_ enum MAPISTATUS EcDoRpc_RopFastTransferSourceCopyTo(TALLOC_CTX *mem_ctx, struct emsmdbp_context *emsmdbp_ctx, struct EcDoRpc_MAPI_REQ *mapi_req, struct EcDoRpc_MAPI_REPL *mapi_repl, uint32_t *handles, uint16_t *size) { enum MAPISTATUS retval; struct mapi_handles *parent_object_handle = NULL, *object_handle; struct emsmdbp_object *parent_object = NULL, *object; struct FastTransferSourceCopyTo_req *request; uint32_t parent_handle_id, i; void *data; struct SPropTagArray *needed_properties; void **data_pointers; enum MAPISTATUS *retvals; struct ndr_push *ndr, *cutmarks_ndr; DEBUG(4, ("exchange_emsmdb: [OXCFXICS] FastTransferSourceCopyTo (0x4d)\n")); /* Sanity checks */ OPENCHANGE_RETVAL_IF(!emsmdbp_ctx, MAPI_E_NOT_INITIALIZED, NULL); OPENCHANGE_RETVAL_IF(!mapi_req, MAPI_E_INVALID_PARAMETER, NULL); OPENCHANGE_RETVAL_IF(!mapi_repl, MAPI_E_INVALID_PARAMETER, NULL); OPENCHANGE_RETVAL_IF(!handles, MAPI_E_INVALID_PARAMETER, NULL); OPENCHANGE_RETVAL_IF(!size, MAPI_E_INVALID_PARAMETER, NULL); request = &mapi_req->u.mapi_FastTransferSourceCopyTo; mapi_repl->opnum = mapi_req->opnum; mapi_repl->error_code = MAPI_E_SUCCESS; mapi_repl->handle_idx = request->handle_idx; /* Step 1. Retrieve object handle */ parent_handle_id = handles[mapi_req->handle_idx]; retval = mapi_handles_search(emsmdbp_ctx->handles_ctx, parent_handle_id, &parent_object_handle); if (retval) { mapi_repl->error_code = MAPI_E_INVALID_OBJECT; DEBUG(5, (" handle (%x) not found: %x\n", parent_handle_id, mapi_req->handle_idx)); goto end; } /* Step 2. Check whether the parent object supports fetching properties */ mapi_handles_get_private_data(parent_object_handle, &data); parent_object = (struct emsmdbp_object *) data; if (request->Level > 0) { mapi_repl->error_code = MAPI_E_INVALID_OBJECT; DEBUG(5, (" no support for levels > 0\n")); goto end; } if (emsmdbp_object_get_available_properties(mem_ctx, emsmdbp_ctx, parent_object, &needed_properties) == MAPISTORE_SUCCESS) { if (needed_properties->cValues > 0) { for (i = 0; i < request->PropertyTags.cValues; i++) { SPropTagArray_delete(mem_ctx, needed_properties, request->PropertyTags.aulPropTag[i]); } data_pointers = emsmdbp_object_get_properties(mem_ctx, emsmdbp_ctx, parent_object, needed_properties, &retvals); if (data_pointers == NULL) { mapi_repl->error_code = MAPI_E_INVALID_OBJECT; DEBUG(5, (" unexpected error\n")); goto end; } ndr = ndr_push_init_ctx(NULL); ndr_set_flags(&ndr->flags, LIBNDR_FLAG_NOALIGN); ndr->offset = 0; cutmarks_ndr = ndr_push_init_ctx(NULL); ndr_set_flags(&cutmarks_ndr->flags, LIBNDR_FLAG_NOALIGN); cutmarks_ndr->offset = 0; oxcfxics_ndr_push_properties(ndr, cutmarks_ndr, emsmdbp_ctx->mstore_ctx->nprops_ctx, needed_properties, data_pointers, retvals); retval = mapi_handles_add(emsmdbp_ctx->handles_ctx, parent_handle_id, &object_handle); object = emsmdbp_object_ftcontext_init(object_handle, emsmdbp_ctx, parent_object); if (object == NULL) { mapi_repl->error_code = MAPI_E_INVALID_OBJECT; DEBUG(5, (" context object not created\n")); goto end; } ndr_push_uint32(cutmarks_ndr, NDR_SCALARS, 0); ndr_push_uint32(cutmarks_ndr, NDR_SCALARS, 0xffffffff); (void) talloc_reference(object, ndr->data); (void) talloc_reference(object, cutmarks_ndr->data); object->object.ftcontext->cutmarks = (uint32_t *) cutmarks_ndr->data; object->object.ftcontext->stream.buffer.data = ndr->data; object->object.ftcontext->stream.buffer.length = ndr->offset; talloc_free(ndr); talloc_free(cutmarks_ndr); mapi_handles_set_private_data(object_handle, object); handles[mapi_repl->handle_idx] = object_handle->handle; talloc_free(data_pointers); talloc_free(retvals); } } end: *size += libmapiserver_RopFastTransferSourceCopyTo_size(mapi_repl); return MAPI_E_SUCCESS; } static void oxcfxics_push_messageChange_recipients(struct emsmdbp_context *emsmdbp_ctx, struct oxcfxics_sync_data *sync_data, struct emsmdbp_object *message_object, struct mapistore_message *msg) { TALLOC_CTX *local_mem_ctx; enum MAPISTATUS *retvals; struct mapistore_message_recipient *recipient; uint32_t i, j, min_string_value_buffer; uint32_t cn_idx = (uint32_t) -1, email_idx = (uint32_t) -1; ndr_push_uint32(sync_data->ndr, NDR_SCALARS, PidTagFXDelProp); ndr_push_uint32(sync_data->ndr, NDR_SCALARS, PidTagMessageRecipients); ndr_push_uint32(sync_data->cutmarks_ndr, NDR_SCALARS, 0); ndr_push_uint32(sync_data->cutmarks_ndr, NDR_SCALARS, sync_data->ndr->offset); min_string_value_buffer = oxcfxics_compute_cutmark_min_value_buffer(PT_UNICODE); if (msg) { local_mem_ctx = talloc_zero(NULL, TALLOC_CTX); if (SPropTagArray_find(*msg->columns, PidTagDisplayName, &cn_idx) == MAPI_E_NOT_FOUND && SPropTagArray_find(*msg->columns, PidTag7BitDisplayName, &cn_idx) == MAPI_E_NOT_FOUND && SPropTagArray_find(*msg->columns, PidTagRecipientDisplayName, &cn_idx) == MAPI_E_NOT_FOUND) { cn_idx = (uint32_t) -1; } if (SPropTagArray_find(*msg->columns, PidTagEmailAddress, &email_idx) == MAPI_E_NOT_FOUND && SPropTagArray_find(*msg->columns, PidTagSmtpAddress, &email_idx) == MAPI_E_NOT_FOUND) { email_idx = (uint32_t) -1; } retvals = talloc_array(local_mem_ctx, enum MAPISTATUS, msg->columns->cValues); for (i = 0; i < msg->recipients_count; i++) { recipient = msg->recipients + i; ndr_push_uint32(sync_data->ndr, NDR_SCALARS, PidTagStartRecip); ndr_push_uint32(sync_data->cutmarks_ndr, NDR_SCALARS, 0); ndr_push_uint32(sync_data->cutmarks_ndr, NDR_SCALARS, sync_data->ndr->offset); ndr_push_uint32(sync_data->ndr, NDR_SCALARS, PidTagRowid); ndr_push_uint32(sync_data->ndr, NDR_SCALARS, i); ndr_push_uint32(sync_data->cutmarks_ndr, NDR_SCALARS, 0); ndr_push_uint32(sync_data->cutmarks_ndr, NDR_SCALARS, sync_data->ndr->offset); if (email_idx != (uint32_t) -1 && recipient->data[email_idx]) { ndr_push_uint32(sync_data->ndr, NDR_SCALARS, PidTagAddressType); oxcfxics_ndr_push_simple_data(sync_data->ndr, 0x1f, "SMTP"); ndr_push_uint32(sync_data->cutmarks_ndr, NDR_SCALARS, min_string_value_buffer); ndr_push_uint32(sync_data->cutmarks_ndr, NDR_SCALARS, sync_data->ndr->offset); ndr_push_uint32(sync_data->ndr, NDR_SCALARS, PidTagEmailAddress); oxcfxics_ndr_push_simple_data(sync_data->ndr, 0x1f, recipient->data[email_idx]); ndr_push_uint32(sync_data->cutmarks_ndr, NDR_SCALARS, min_string_value_buffer); ndr_push_uint32(sync_data->cutmarks_ndr, NDR_SCALARS, sync_data->ndr->offset); } if (cn_idx != (uint32_t) -1 && recipient->data[cn_idx]) { ndr_push_uint32(sync_data->ndr, NDR_SCALARS, PidTagDisplayName); oxcfxics_ndr_push_simple_data(sync_data->ndr, 0x1f, recipient->data[cn_idx]); ndr_push_uint32(sync_data->cutmarks_ndr, NDR_SCALARS, min_string_value_buffer); ndr_push_uint32(sync_data->cutmarks_ndr, NDR_SCALARS, sync_data->ndr->offset); } ndr_push_uint32(sync_data->ndr, NDR_SCALARS, PidTagRecipientType); ndr_push_uint32(sync_data->ndr, NDR_SCALARS, recipient->type); ndr_push_uint32(sync_data->cutmarks_ndr, NDR_SCALARS, 0); ndr_push_uint32(sync_data->cutmarks_ndr, NDR_SCALARS, sync_data->ndr->offset); for (j = 0; j < msg->columns->cValues; j++) { if (recipient->data[j] == NULL) { retvals[j] = MAPISTORE_ERR_NOT_FOUND; } else { retvals[j] = MAPISTORE_SUCCESS; } } oxcfxics_ndr_push_properties(sync_data->ndr, sync_data->cutmarks_ndr, emsmdbp_ctx->mstore_ctx->nprops_ctx, msg->columns, recipient->data, retvals); ndr_push_uint32(sync_data->ndr, NDR_SCALARS, PidTagEndToRecip); ndr_push_uint32(sync_data->cutmarks_ndr, NDR_SCALARS, 0); ndr_push_uint32(sync_data->cutmarks_ndr, NDR_SCALARS, sync_data->ndr->offset); } talloc_free(local_mem_ctx); } } /* FIXME: attachment_object should be an emsmdbp_object but we lack time to create the struct */ static void oxcfxics_push_messageChange_attachment_embedded_message(struct emsmdbp_context *emsmdbp_ctx, uint32_t contextID, struct emsmdbp_object_synccontext *synccontext, struct oxcfxics_sync_data *sync_data, void *attachment) { TALLOC_CTX *mem_ctx; enum mapistore_error ret; struct mapistore_message *msg; void *embedded_message; uint64_t messageID; struct SPropTagArray *properties; struct mapistore_property_data *prop_data; void **data_pointers; enum MAPISTATUS *retvals; uint32_t i; mem_ctx = talloc_zero(NULL, TALLOC_CTX); ret = mapistore_message_attachment_open_embedded_message(emsmdbp_ctx->mstore_ctx, contextID, attachment, mem_ctx, &embedded_message, &messageID, &msg); if (ret == MAPISTORE_SUCCESS) { ndr_push_uint32(sync_data->ndr, NDR_SCALARS, PidTagStartEmbed); ndr_push_uint32(sync_data->cutmarks_ndr, NDR_SCALARS, 0); ndr_push_uint32(sync_data->cutmarks_ndr, NDR_SCALARS, sync_data->ndr->offset); properties = &synccontext->properties; /* ret = mapistore_properties_get_available_properties(emsmdbp_ctx->mstore_ctx, contextID, embedded_message, mem_ctx, &available_properties); */ prop_data = talloc_array(mem_ctx, struct mapistore_property_data, properties->cValues); memset(prop_data, 0, sizeof(struct mapistore_property_data) * properties->cValues); ret = mapistore_properties_get_properties(emsmdbp_ctx->mstore_ctx, contextID, embedded_message, mem_ctx, properties->cValues, properties->aulPropTag, prop_data); data_pointers = talloc_array(mem_ctx, void *, properties->cValues); retvals = talloc_array(mem_ctx, enum MAPISTATUS, properties->cValues); for (i = 0; i < properties->cValues; i++) { switch (prop_data[i].error) { case MAPISTORE_SUCCESS: if (prop_data[i].data) { data_pointers[i] = prop_data[i].data; retvals[i] = MAPI_E_SUCCESS; } else { retvals[i] = MAPI_E_NOT_FOUND; } break; default: retvals[i] = MAPI_E_NOT_FOUND; } } oxcfxics_ndr_push_properties(sync_data->ndr, sync_data->cutmarks_ndr, emsmdbp_ctx->mstore_ctx->nprops_ctx, properties, data_pointers, retvals); ndr_push_uint32(sync_data->ndr, NDR_SCALARS, PidTagFXDelProp); ndr_push_uint32(sync_data->ndr, NDR_SCALARS, PidTagMessageRecipients); ndr_push_uint32(sync_data->cutmarks_ndr, NDR_SCALARS, 0); ndr_push_uint32(sync_data->cutmarks_ndr, NDR_SCALARS, sync_data->ndr->offset); ndr_push_uint32(sync_data->ndr, NDR_SCALARS, PidTagFXDelProp); ndr_push_uint32(sync_data->ndr, NDR_SCALARS, PidTagMessageAttachments); ndr_push_uint32(sync_data->cutmarks_ndr, NDR_SCALARS, 0); ndr_push_uint32(sync_data->cutmarks_ndr, NDR_SCALARS, sync_data->ndr->offset); ndr_push_uint32(sync_data->ndr, NDR_SCALARS, PidTagEndEmbed); ndr_push_uint32(sync_data->cutmarks_ndr, NDR_SCALARS, 0); ndr_push_uint32(sync_data->cutmarks_ndr, NDR_SCALARS, sync_data->ndr->offset); RAWIDSET_push_guid_glob(sync_data->eid_set, &sync_data->replica_guid, (messageID >> 16) & 0x0000ffffffffffff); } talloc_free(mem_ctx); } static void oxcfxics_push_messageChange_attachments(struct emsmdbp_context *emsmdbp_ctx, struct emsmdbp_object_synccontext *synccontext, struct oxcfxics_sync_data *sync_data, struct emsmdbp_object *message_object) { TALLOC_CTX *mem_ctx; struct emsmdbp_object *table_object; static enum MAPITAGS prop_tags[] = { PidTagAttachMethod, PidTagAttachTag, PidTagAttachSize, PidTagAttachEncoding, PidTagAttachFlags, PidTagAttachmentFlags, PidTagAttachmentHidden, PidTagAttachmentLinkId, PidTagAttachExtension, PidTagAttachFilename, PidTagAttachLongFilename, PidTagAttachContentId, PidTagAttachMimeTag, PidTagDisplayName, PidTagCreationTime, PidTagLastModificationTime, PidTagAttachDataBinary, PidTagAttachmentContactPhoto, PidTagRenderingPosition, PidTagRecordKey, PidTagExceptionStartTime, PidTagExceptionEndTime, PidTagExceptionReplaceTime }; static const int prop_count = sizeof(prop_tags) / sizeof (enum MAPITAGS); struct SPropTagArray query_props; uint32_t i, method, contextID; enum MAPISTATUS *retvals; void **data_pointers, *attachment_object; ndr_push_uint32(sync_data->ndr, NDR_SCALARS, PidTagFXDelProp); ndr_push_uint32(sync_data->ndr, NDR_SCALARS, PidTagMessageAttachments); table_object = emsmdbp_object_message_open_attachment_table(NULL, emsmdbp_ctx, message_object); if (table_object && table_object->object.table->denominator > 0) { table_object->object.table->properties = prop_tags; table_object->object.table->prop_count = prop_count; contextID = emsmdbp_get_contextID(table_object); if (emsmdbp_is_mapistore(table_object)) { mapistore_table_set_columns(emsmdbp_ctx->mstore_ctx, contextID, table_object->backend_object, prop_count, prop_tags); } for (i = 0; i < table_object->object.table->denominator; i++) { mem_ctx = talloc_zero(NULL, void); data_pointers = emsmdbp_object_table_get_row_props(mem_ctx, emsmdbp_ctx, table_object, i, MAPISTORE_PREFILTERED_QUERY, &retvals); if (data_pointers) { ndr_push_uint32(sync_data->ndr, NDR_SCALARS, PidTagNewAttach); ndr_push_uint32(sync_data->cutmarks_ndr, NDR_SCALARS, 0); ndr_push_uint32(sync_data->cutmarks_ndr, NDR_SCALARS, sync_data->ndr->offset); ndr_push_uint32(sync_data->ndr, NDR_SCALARS, PidTagAttachNumber); ndr_push_uint32(sync_data->ndr, NDR_SCALARS, i); ndr_push_uint32(sync_data->cutmarks_ndr, NDR_SCALARS, 0); ndr_push_uint32(sync_data->cutmarks_ndr, NDR_SCALARS, sync_data->ndr->offset); query_props.cValues = prop_count; query_props.aulPropTag = prop_tags; oxcfxics_ndr_push_properties(sync_data->ndr, sync_data->cutmarks_ndr, emsmdbp_ctx->mstore_ctx->nprops_ctx, &query_props, data_pointers, (enum MAPISTATUS *) retvals); if (retvals[0] == MAPI_E_SUCCESS) { method = *((uint32_t *) data_pointers[0]); if (method == afEmbeddedMessage) { mapistore_message_open_attachment(emsmdbp_ctx->mstore_ctx, contextID, message_object->backend_object, mem_ctx, i, &attachment_object); oxcfxics_push_messageChange_attachment_embedded_message(emsmdbp_ctx, contextID, synccontext, sync_data, attachment_object); } } ndr_push_uint32(sync_data->ndr, NDR_SCALARS, PidTagEndAttach); ndr_push_uint32(sync_data->cutmarks_ndr, NDR_SCALARS, 0); ndr_push_uint32(sync_data->cutmarks_ndr, NDR_SCALARS, sync_data->ndr->offset); } else { DEBUG(5, ("no data returned for attachment row %d\n", i)); abort(); } talloc_free(mem_ctx); } } talloc_free(table_object); } static void oxcfxics_table_set_cn_restriction(struct emsmdbp_context *emsmdbp_ctx, struct emsmdbp_object *table_object, const char *owner, struct idset *cnset_seen) { struct mapi_SRestriction cn_restriction; struct idset *local_cnset; uint16_t repl_id; uint8_t state; if (!emsmdbp_is_mapistore(table_object)) { DEBUG(5, (__location__": table restrictions not supported by non-mapistore tables\n")); return; } local_cnset = cnset_seen; while (local_cnset && (emsmdbp_guid_to_replid(emsmdbp_ctx, owner, &local_cnset->repl.guid, &repl_id) != MAPI_E_SUCCESS || repl_id != 1)) { local_cnset = local_cnset->next; } if (!local_cnset) { DEBUG(5, (__location__": no change set available -> no table restrictions\n")); return; } if (local_cnset->range_count != 1) { DEBUG(5, (__location__": no valid change set available (range_count = %d) -> no table restrictions\n", local_cnset->range_count)); return; } cn_restriction.rt = RES_PROPERTY; cn_restriction.res.resProperty.relop = RELOP_GT; cn_restriction.res.resProperty.ulPropTag = PidTagChangeNumber; cn_restriction.res.resProperty.lpProp.ulPropTag = PidTagChangeNumber; cn_restriction.res.resProperty.lpProp.value.d = (cnset_seen->ranges[0].high << 16) | repl_id; mapistore_table_set_restrictions(emsmdbp_ctx->mstore_ctx, emsmdbp_get_contextID(table_object), table_object->backend_object, &cn_restriction, &state); } static bool oxcfxics_push_messageChange(struct emsmdbp_context *emsmdbp_ctx, struct emsmdbp_object_synccontext *synccontext, const char *owner, struct oxcfxics_sync_data *sync_data, struct emsmdbp_object *folder_object) { TALLOC_CTX *mem_ctx, *msg_ctx; bool folder_is_mapistore, end_of_table; struct emsmdbp_object *table_object, *message_object; uint32_t i; static enum MAPITAGS mid_property = PidTagMid; enum MAPISTATUS *retvals, *header_retvals; void **data_pointers, **header_data_pointers; struct FILETIME *lm_time; NTTIME nt_time; uint32_t unix_time, contextID; struct UI8Array_r preload_mids; enum mapistore_table_type mstore_type; struct SPropTagArray query_props; struct Binary_r predecessors_data; struct Binary_r *bin_data; uint64_t eid, cn; struct mapistore_message *msg; struct GUID replica_guid; struct idset *original_cnset_seen; struct UI8Array_r *deleted_eids; struct SPropTagArray *properties; struct oxcfxics_message_sync_data *message_sync_data; mem_ctx = talloc_zero(NULL, void); if (sync_data->table_type == MAPISTORE_FAI_TABLE) { original_cnset_seen = synccontext->cnset_seen_fai; properties = &synccontext->fai_properties; mstore_type = MAPISTORE_FAI_TABLE; } else { original_cnset_seen = synccontext->cnset_seen; properties = &synccontext->properties; mstore_type = MAPISTORE_MESSAGE_TABLE; } if (sync_data->message_sync_data) { message_sync_data = sync_data->message_sync_data; } else { message_sync_data = talloc_zero(NULL, struct oxcfxics_message_sync_data); sync_data->message_sync_data = message_sync_data; /* we only push "messageChangeFull" since we don't handle property-based changes */ /* messageChangeFull = IncrSyncChg messageChangeHeader IncrSyncMessage propList messageChildren */ table_object = emsmdbp_folder_open_table(mem_ctx, folder_object, sync_data->table_type, 0); if (!table_object) { DEBUG(5, ("could not open folder table\n")); abort(); } table_object->object.table->prop_count = 1; table_object->object.table->properties = &mid_property; oxcfxics_table_set_cn_restriction(emsmdbp_ctx, table_object, owner, original_cnset_seen); message_sync_data->max = 0; if (emsmdbp_is_mapistore(table_object)) { contextID = emsmdbp_get_contextID(folder_object); mapistore_table_set_columns(emsmdbp_ctx->mstore_ctx, contextID, table_object->backend_object, table_object->object.table->prop_count, table_object->object.table->properties); mapistore_table_get_row_count(emsmdbp_ctx->mstore_ctx, contextID, table_object->backend_object, MAPISTORE_PREFILTERED_QUERY, &table_object->object.table->denominator); synccontext->total_objects += table_object->object.table->denominator; DEBUG(5, ("push_messageChange: %d objects in table\n", table_object->object.table->denominator)); /* fetch maching mids */ message_sync_data->mids = talloc_array(message_sync_data, uint64_t, table_object->object.table->denominator); for (i = 0; i < table_object->object.table->denominator; i++) { data_pointers = emsmdbp_object_table_get_row_props(mem_ctx, emsmdbp_ctx, table_object, i, MAPISTORE_PREFILTERED_QUERY, &retvals); if (data_pointers) { if (retvals[0] == MAPI_E_SUCCESS) { message_sync_data->mids[message_sync_data->max] = *(uint64_t *) data_pointers[0]; message_sync_data->max++; } } } } message_sync_data->count = 0; } folder_is_mapistore = emsmdbp_is_mapistore(folder_object); if (folder_is_mapistore) { contextID = emsmdbp_get_contextID(folder_object); } /* open each message and fetch properties */ for (; sync_data->ndr->offset < max_message_sync_size && message_sync_data->count < message_sync_data->max; message_sync_data->count++) { msg_ctx = talloc_zero(NULL, TALLOC_CTX); if (folder_is_mapistore && (message_sync_data->count % message_preload_interval) == 0) { preload_mids.lpui8 = message_sync_data->mids + message_sync_data->count; if ((message_sync_data->count + message_preload_interval) < message_sync_data->max) { preload_mids.cValues = message_preload_interval; } else { preload_mids.cValues = message_sync_data->max - message_sync_data->count; } mapistore_folder_preload_message_bodies(emsmdbp_ctx->mstore_ctx, contextID, folder_object->backend_object, mstore_type, &preload_mids); } eid = *(message_sync_data->mids + message_sync_data->count); if (eid == 0x7fffffffffffffffLL) { DEBUG(0, ("message without a valid eid\n")); goto end_row; } if (emsmdbp_object_message_open(msg_ctx, emsmdbp_ctx, folder_object, folder_object->object.folder->folderID, eid, false, &message_object, &msg) != MAPISTORE_SUCCESS) { DEBUG(5, ("message '%.16"PRIx64"' could not be open, skipped\n", eid)); goto end_row; } data_pointers = emsmdbp_object_get_properties(msg_ctx, emsmdbp_ctx, message_object, properties, &retvals); if (!data_pointers) { DEBUG(5, ("message '%.16"PRIx64"' returned no value, skipped\n", eid)); goto end_row; } oxcfxics_ndr_check(sync_data->ndr, "sync_data->ndr"); oxcfxics_ndr_check(sync_data->cutmarks_ndr, "sync_data->cutmarks_ndr"); /** fixed header props */ header_data_pointers = talloc_array(data_pointers, void *, 9); header_retvals = talloc_array(header_data_pointers, enum MAPISTATUS, 9); memset(header_retvals, 0, 9 * sizeof(uint32_t)); query_props.aulPropTag = talloc_array(header_data_pointers, enum MAPITAGS, 9); i = 0; /* source key */ emsmdbp_replid_to_guid(emsmdbp_ctx, owner, eid & 0xffff, &replica_guid); RAWIDSET_push_guid_glob(sync_data->eid_set, &replica_guid, (eid >> 16) & 0x0000ffffffffffff); /* bin_data = oxcfxics_make_gid(header_data_pointers, &sync_data->replica_guid, eid >> 16); */ emsmdbp_source_key_from_fmid(header_data_pointers, emsmdbp_ctx, owner, eid, &bin_data); query_props.aulPropTag[i] = PidTagSourceKey; header_data_pointers[i] = bin_data; i++; /* last modification time */ if (retvals[sync_data->prop_index.last_modification_time]) { unix_time = oc_version_time; unix_to_nt_time(&nt_time, unix_time); lm_time = talloc_zero(header_data_pointers, struct FILETIME); lm_time->dwLowDateTime = (nt_time & 0xffffffff); lm_time->dwHighDateTime = nt_time >> 32; } else { lm_time = (struct FILETIME *) data_pointers[sync_data->prop_index.last_modification_time]; nt_time = ((uint64_t) lm_time->dwHighDateTime << 32) | lm_time->dwLowDateTime; unix_time = nt_time_to_unix(nt_time); } query_props.aulPropTag[i] = PidTagLastModificationTime; header_data_pointers[i] = lm_time; i++; if (retvals[sync_data->prop_index.change_number]) { DEBUG(5, (__location__": mandatory property PidTagChangeNumber not returned for message\n")); abort(); } cn = ((*(uint64_t *) data_pointers[sync_data->prop_index.change_number]) >> 16) & 0x0000ffffffffffff; if (IDSET_includes_guid_glob(original_cnset_seen, &sync_data->replica_guid, cn)) { synccontext->skipped_objects++; DEBUG(5, (__location__": message changes: cn %.16"PRIx64" already present\n", cn)); goto end_row; } /* The "cnset_seen" range is going to be merged later with the one from synccontext since the ids are not sorted */ RAWIDSET_push_guid_glob(sync_data->cnset_seen, &sync_data->replica_guid, cn); /* change key */ /* bin_data = oxcfxics_make_gid(header_data_pointers, &sync_data->replica_guid, cn); */ if (retvals[sync_data->prop_index.change_key]) { DEBUG(5, (__location__": mandatory property PidTagChangeKey not returned for message\n")); abort(); } query_props.aulPropTag[i] = PidTagChangeKey; bin_data = data_pointers[sync_data->prop_index.change_key]; header_data_pointers[i] = bin_data; i++; /* predecessor change list */ query_props.aulPropTag[i] = PidTagPredecessorChangeList; if (retvals[sync_data->prop_index.predecessor_change_list]) { DEBUG(5, (__location__": mandatory property PidTagPredecessorChangeList not returned for message\n")); /* abort(); */ predecessors_data.cb = bin_data->cb + 1; predecessors_data.lpb = talloc_array(header_data_pointers, uint8_t, predecessors_data.cb); *predecessors_data.lpb = bin_data->cb & 0xff; memcpy(predecessors_data.lpb + 1, bin_data->lpb, bin_data->cb); header_data_pointers[i] = &predecessors_data; } else { bin_data = data_pointers[sync_data->prop_index.predecessor_change_list]; header_data_pointers[i] = bin_data; } i++; /* associated (could be based on table type ) */ query_props.aulPropTag[i] = PidTagAssociated; if (retvals[sync_data->prop_index.associated]) { header_data_pointers[i] = talloc_zero(header_data_pointers, uint8_t); } else { header_data_pointers[i] = data_pointers[sync_data->prop_index.associated]; } i++; /* message id (conditional) */ if (synccontext->request.request_eid) { query_props.aulPropTag[i] = PidTagMid; header_data_pointers[i] = &eid; i++; } /* message size (conditional) */ if (synccontext->request.request_message_size) { query_props.aulPropTag[i] = PidTagMessageSize; header_data_pointers[i] = data_pointers[sync_data->prop_index.message_size]; if (retvals[sync_data->prop_index.parent_fid]) { header_data_pointers[i] = talloc_zero(header_data_pointers, uint32_t); } else { header_data_pointers[i] = data_pointers[sync_data->prop_index.message_size]; } i++; } /* cn (conditional) */ if (synccontext->request.request_cn) { query_props.aulPropTag[i] = PidTagChangeNumber; header_data_pointers[i] = talloc_zero(header_data_pointers, uint64_t); *(uint64_t *) header_data_pointers[i] = (cn << 16) | (eid & 0xffff); i++; } query_props.cValues = i; ndr_push_uint32(sync_data->ndr, NDR_SCALARS, PidTagIncrSyncChg); ndr_push_uint32(sync_data->cutmarks_ndr, NDR_SCALARS, 0); ndr_push_uint32(sync_data->cutmarks_ndr, NDR_SCALARS, sync_data->ndr->offset); oxcfxics_ndr_push_properties(sync_data->ndr, sync_data->cutmarks_ndr, emsmdbp_ctx->mstore_ctx->nprops_ctx, &query_props, header_data_pointers, (enum MAPISTATUS *) header_retvals); /** remaining props */ ndr_push_uint32(sync_data->ndr, NDR_SCALARS, PidTagIncrSyncMessage); ndr_push_uint32(sync_data->cutmarks_ndr, NDR_SCALARS, 0); ndr_push_uint32(sync_data->cutmarks_ndr, NDR_SCALARS, sync_data->ndr->offset); /* we shift the number of remaining properties to the amount of properties explicitly requested in RopSyncConfigure that were used above */ if (properties->cValues > message_properties_shift) { query_props.cValues = properties->cValues - message_properties_shift; query_props.aulPropTag = properties->aulPropTag + message_properties_shift; oxcfxics_ndr_push_properties(sync_data->ndr, sync_data->cutmarks_ndr, emsmdbp_ctx->mstore_ctx->nprops_ctx, &query_props, data_pointers + message_properties_shift, (enum MAPISTATUS *) retvals + message_properties_shift); } /* messageChildren: [ PidTagFXDelProp ] [ *(StartRecip propList EndToRecip) ] [ PidTagFXDelProp ] [ *(NewAttach propList [embeddedMessage] EndAttach) ] embeddedMessage: StartEmbed messageContent EndEmbed */ oxcfxics_push_messageChange_recipients(emsmdbp_ctx, sync_data, message_object, msg); oxcfxics_push_messageChange_attachments(emsmdbp_ctx, synccontext, sync_data, message_object); synccontext->sent_objects++; end_row: talloc_free(msg_ctx); } if (sync_data->ndr->offset >= max_message_sync_size) { DEBUG(5, ("reached max sync size: %u >= %zu\n", sync_data->ndr->offset, max_message_sync_size)); } if (message_sync_data->count < message_sync_data->max) { end_of_table = false; DEBUG(5, ("table status: count: %"PRId64", max: %"PRId64"\n", message_sync_data->count, message_sync_data->max)); } else { /* fetch deleted ids */ if (folder_is_mapistore) { if (original_cnset_seen && original_cnset_seen->range_count > 0) { cn = (original_cnset_seen->ranges[0].high << 16) | 0x0001; } else { cn = 0; } if (!mapistore_folder_get_deleted_fmids(emsmdbp_ctx->mstore_ctx, contextID, folder_object->backend_object, mem_ctx, sync_data->table_type, cn, &deleted_eids, &cn)) { for (i = 0; i < deleted_eids->cValues; i++) { RAWIDSET_push_guid_glob(sync_data->deleted_eid_set, &sync_data->replica_guid, (deleted_eids->lpui8[i] >> 16) & 0x0000ffffffffffff); } if (deleted_eids->cValues > 0) { RAWIDSET_push_guid_glob(sync_data->cnset_seen, &sync_data->replica_guid, (cn >> 16) & 0x0000ffffffffffff); } } preload_mids.cValues = 0; mapistore_folder_preload_message_bodies(emsmdbp_ctx->mstore_ctx, contextID, folder_object->backend_object, mstore_type, &preload_mids); } DEBUG(5, ("end of table reached: count: %"PRId64", max: %"PRId64"\n", message_sync_data->count, message_sync_data->max)); talloc_free(message_sync_data); sync_data->message_sync_data = NULL; end_of_table = true; } talloc_free(mem_ctx); return end_of_table; } static void oxcfxics_fill_synccontext_with_messageChange(struct emsmdbp_object_synccontext *synccontext, TALLOC_CTX *mem_ctx, struct emsmdbp_context *emsmdbp_ctx, const char *owner, struct emsmdbp_object *parent_object) { struct oxcfxics_sync_data *sync_data; struct idset *new_idset, *old_idset; /* contentsSync = [progressTotal] *( [progressPerMessage] messageChange ) [deletions] [readStateChanges] state IncrSyncEnd */ if (synccontext->sync_stage == 0) { /* 1. we setup the mandatory properties indexes */ sync_data = talloc_zero(NULL, struct oxcfxics_sync_data); openchangedb_get_MailboxReplica(emsmdbp_ctx->oc_ctx, owner, NULL, &sync_data->replica_guid); SPropTagArray_find(synccontext->properties, PidTagMid, &sync_data->prop_index.eid); SPropTagArray_find(synccontext->properties, PidTagChangeNumber, &sync_data->prop_index.change_number); SPropTagArray_find(synccontext->properties, PidTagChangeKey, &sync_data->prop_index.change_key); SPropTagArray_find(synccontext->properties, PidTagPredecessorChangeList, &sync_data->prop_index.predecessor_change_list); SPropTagArray_find(synccontext->properties, PidTagLastModificationTime, &sync_data->prop_index.last_modification_time); SPropTagArray_find(synccontext->properties, PidTagAssociated, &sync_data->prop_index.associated); SPropTagArray_find(synccontext->properties, PidTagMessageSize, &sync_data->prop_index.message_size); sync_data->cnset_read = RAWIDSET_make(sync_data, false, true); sync_data->eid_set = RAWIDSET_make(sync_data, false, false); sync_data->deleted_eid_set = RAWIDSET_make(sync_data, false, false); synccontext->sync_data = sync_data; synccontext->sync_stage = 1; } else { sync_data = synccontext->sync_data; talloc_free(sync_data->ndr); talloc_free(sync_data->cutmarks_ndr); } sync_data->ndr = ndr_push_init_ctx(sync_data); ndr_set_flags(&sync_data->ndr->flags, LIBNDR_FLAG_NOALIGN); sync_data->ndr->offset = 0; sync_data->cutmarks_ndr = ndr_push_init_ctx(sync_data); ndr_set_flags(&sync_data->cutmarks_ndr->flags, LIBNDR_FLAG_NOALIGN); sync_data->cutmarks_ndr->offset = 0; if (synccontext->sync_stage == 1) { /* 2a. we build the message stream (normal messages) */ if (synccontext->request.normal) { if (!sync_data->message_sync_data) { sync_data->cnset_seen = RAWIDSET_make(NULL, false, true); sync_data->table_type = MAPISTORE_MESSAGE_TABLE; } if (oxcfxics_push_messageChange(emsmdbp_ctx, synccontext, owner, sync_data, parent_object)) { new_idset = RAWIDSET_convert_to_idset(NULL, sync_data->cnset_seen); old_idset = synccontext->cnset_seen; /* IDSET_dump (synccontext->cnset_seen, "initial cnset_seen"); */ synccontext->cnset_seen = IDSET_merge_idsets(synccontext, old_idset, new_idset); /* IDSET_dump (synccontext->cnset_seen, "merged cnset_seen"); */ talloc_free(old_idset); talloc_free(new_idset); talloc_free(sync_data->cnset_seen); synccontext->sync_stage = 2; } } else { synccontext->sync_stage = 2; } } if (synccontext->sync_stage == 2) { /* 2b. we build the message stream (FAI messages) */ if (synccontext->request.fai) { if (!sync_data->message_sync_data) { sync_data->cnset_seen = RAWIDSET_make(NULL, false, true); sync_data->table_type = MAPISTORE_FAI_TABLE; } if (oxcfxics_push_messageChange(emsmdbp_ctx, synccontext, owner, sync_data, parent_object)) { new_idset = RAWIDSET_convert_to_idset(NULL, sync_data->cnset_seen); old_idset = synccontext->cnset_seen_fai; /* IDSET_dump (synccontext->cnset_seen, "initial cnset_seen_fai"); */ synccontext->cnset_seen_fai = IDSET_merge_idsets(synccontext, old_idset, new_idset); /* IDSET_dump (synccontext->cnset_seen, "merged cnset_seen_fai"); */ talloc_free(old_idset); talloc_free(new_idset); talloc_free(sync_data->cnset_seen); synccontext->sync_stage = 3; } } else { synccontext->sync_stage = 3; } } if (synccontext->sync_stage == 3) { /* deletions */ if (sync_data->deleted_eid_set->count > 0 && !synccontext->request.no_deletions) { IDSET_remove_rawidset(synccontext->idset_given, sync_data->deleted_eid_set); new_idset = RAWIDSET_convert_to_idset(NULL, sync_data->deleted_eid_set); /* FIXME: we "convert" the idset hackishly */ new_idset->idbased = true; new_idset->repl.id = 1; ndr_push_uint32(sync_data->ndr, NDR_SCALARS, PidTagIncrSyncDel); ndr_push_uint32(sync_data->cutmarks_ndr, NDR_SCALARS, 0); ndr_push_uint32(sync_data->cutmarks_ndr, NDR_SCALARS, sync_data->ndr->offset); ndr_push_uint32(sync_data->ndr, NDR_SCALARS, PidTagIdsetDeleted); ndr_push_uint32(sync_data->cutmarks_ndr, NDR_SCALARS, 0); ndr_push_uint32(sync_data->cutmarks_ndr, NDR_SCALARS, sync_data->ndr->offset); ndr_push_idset(sync_data->ndr, new_idset); ndr_push_uint32(sync_data->cutmarks_ndr, NDR_SCALARS, 0); ndr_push_uint32(sync_data->cutmarks_ndr, NDR_SCALARS, sync_data->ndr->offset); /* IDSET_dump (new_idset, "cnset_deleted"); */ talloc_free(new_idset); } /* state */ ndr_push_uint32(sync_data->ndr, NDR_SCALARS, PidTagIncrSyncStateBegin); ndr_push_uint32(sync_data->cutmarks_ndr, NDR_SCALARS, 0); ndr_push_uint32(sync_data->cutmarks_ndr, NDR_SCALARS, sync_data->ndr->offset); new_idset = RAWIDSET_convert_to_idset(NULL, sync_data->eid_set); old_idset = synccontext->idset_given; /* IDSET_dump (synccontext->idset_given, "initial idset_given"); */ synccontext->idset_given = IDSET_merge_idsets(synccontext, old_idset, new_idset); /* IDSET_dump (synccontext->idset_given, "merged idset_given"); */ talloc_free(old_idset); talloc_free(new_idset); IDSET_dump (synccontext->cnset_seen, "cnset_seen"); ndr_push_uint32(sync_data->ndr, NDR_SCALARS, PidTagCnsetSeen); ndr_push_uint32(sync_data->cutmarks_ndr, NDR_SCALARS, 0); ndr_push_uint32(sync_data->cutmarks_ndr, NDR_SCALARS, sync_data->ndr->offset); ndr_push_idset(sync_data->ndr, synccontext->cnset_seen); ndr_push_uint32(sync_data->cutmarks_ndr, NDR_SCALARS, 0); ndr_push_uint32(sync_data->cutmarks_ndr, NDR_SCALARS, sync_data->ndr->offset); if (synccontext->request.fai) { IDSET_dump (synccontext->cnset_seen_fai, "cnset_seen_fai"); ndr_push_uint32(sync_data->ndr, NDR_SCALARS, PidTagCnsetSeenFAI); ndr_push_uint32(sync_data->cutmarks_ndr, NDR_SCALARS, 0); ndr_push_uint32(sync_data->cutmarks_ndr, NDR_SCALARS, sync_data->ndr->offset); ndr_push_idset(sync_data->ndr, synccontext->cnset_seen_fai); ndr_push_uint32(sync_data->cutmarks_ndr, NDR_SCALARS, 0); ndr_push_uint32(sync_data->cutmarks_ndr, NDR_SCALARS, sync_data->ndr->offset); } IDSET_dump (synccontext->idset_given, "idset_given"); ndr_push_uint32(sync_data->ndr, NDR_SCALARS, PidTagIdsetGiven); ndr_push_idset(sync_data->ndr, synccontext->idset_given); if (synccontext->request.read_state) { IDSET_dump (synccontext->cnset_read, "cnset_read"); ndr_push_uint32(sync_data->ndr, NDR_SCALARS, PidTagCnsetRead); ndr_push_idset(sync_data->ndr, synccontext->cnset_read); } ndr_push_uint32(sync_data->ndr, NDR_SCALARS, PidTagIncrSyncStateEnd); ndr_push_uint32(sync_data->cutmarks_ndr, NDR_SCALARS, 0); ndr_push_uint32(sync_data->cutmarks_ndr, NDR_SCALARS, sync_data->ndr->offset); /* end of stream */ ndr_push_uint32(sync_data->ndr, NDR_SCALARS, PidTagIncrSyncEnd); ndr_push_uint32(sync_data->cutmarks_ndr, NDR_SCALARS, 0); ndr_push_uint32(sync_data->cutmarks_ndr, NDR_SCALARS, sync_data->ndr->offset); synccontext->sync_stage = 4; } ndr_push_uint32(sync_data->cutmarks_ndr, NDR_SCALARS, 0); ndr_push_uint32(sync_data->cutmarks_ndr, NDR_SCALARS, 0xffffffff); synccontext->cutmarks = (uint32_t *) sync_data->cutmarks_ndr->data; synccontext->next_cutmark_idx = 1; synccontext->stream.position = 0; synccontext->stream.buffer.data = sync_data->ndr->data; synccontext->stream.buffer.length = sync_data->ndr->offset; if (synccontext->sync_stage == 4) { (void) talloc_reference(synccontext, sync_data->ndr->data); (void) talloc_reference(synccontext, sync_data->cutmarks_ndr->data); talloc_free(sync_data); synccontext->sync_data = NULL; } } static void oxcfxics_push_folderChange(struct emsmdbp_context *emsmdbp_ctx, struct emsmdbp_object_synccontext *synccontext, const char *owner, struct emsmdbp_object *topmost_folder_object, struct oxcfxics_sync_data *sync_data, struct emsmdbp_object *folder_object) { TALLOC_CTX *mem_ctx; struct emsmdbp_object *table_object, *subfolder_object; uint64_t eid, cn; struct Binary_r predecessors_data; struct Binary_r *bin_data; struct FILETIME *lm_time; NTTIME nt_time; int32_t unix_time, contextID; uint32_t i, j; enum MAPISTATUS *retvals, *header_retvals; void **data_pointers, **header_data_pointers; struct SPropTagArray query_props; struct GUID replica_guid; mem_ctx = talloc_zero(NULL, void); contextID = emsmdbp_get_contextID(folder_object); /* 2b. we build the stream */ table_object = emsmdbp_folder_open_table(mem_ctx, folder_object, MAPISTORE_FOLDER_TABLE, 0); if (!table_object) { DEBUG(5, ("folder does not handle hierarchy tables\n")); return; } table_object->object.table->prop_count = synccontext->properties.cValues; table_object->object.table->properties = synccontext->properties.aulPropTag; oxcfxics_table_set_cn_restriction(emsmdbp_ctx, table_object, owner, synccontext->cnset_seen); if (emsmdbp_is_mapistore(table_object)) { mapistore_table_set_columns(emsmdbp_ctx->mstore_ctx, contextID, table_object->backend_object, synccontext->properties.cValues, synccontext->properties.aulPropTag); mapistore_table_get_row_count(emsmdbp_ctx->mstore_ctx, contextID, table_object->backend_object, MAPISTORE_PREFILTERED_QUERY, &table_object->object.table->denominator); synccontext->total_objects += table_object->object.table->denominator; } for (i = 0; i < table_object->object.table->denominator; i++) { data_pointers = emsmdbp_object_table_get_row_props(mem_ctx, emsmdbp_ctx, table_object, i, MAPISTORE_PREFILTERED_QUERY, &retvals); if (data_pointers) { /** fixed header props */ header_data_pointers = talloc_array(NULL, void *, 8); header_retvals = talloc_array(header_data_pointers, enum MAPISTATUS, 8); memset(header_retvals, 0, 8 * sizeof(uint32_t)); query_props.aulPropTag = talloc_array(header_data_pointers, enum MAPITAGS, 8); j = 0; /* parent source key */ if (folder_object == topmost_folder_object) { /* No parent source key at the first hierarchy level */ bin_data = talloc_zero(header_data_pointers, struct Binary_r); bin_data->lpb = (uint8_t *) ""; } else { emsmdbp_source_key_from_fmid(header_data_pointers, emsmdbp_ctx, owner, *(uint64_t *) data_pointers[sync_data->prop_index.parent_fid], &bin_data); } query_props.aulPropTag[j] = PidTagParentSourceKey; header_data_pointers[j] = bin_data; j++; /* source key */ eid = *(uint64_t *) data_pointers[sync_data->prop_index.eid]; if (eid == 0x7fffffffffffffffLL) { DEBUG(0, ("folder without a valid eid\n")); talloc_free(header_data_pointers); continue; } emsmdbp_replid_to_guid(emsmdbp_ctx, owner, eid & 0xffff, &replica_guid); RAWIDSET_push_guid_glob(sync_data->eid_set, &replica_guid, (eid >> 16) & 0x0000ffffffffffff); /* bin_data = oxcfxics_make_gid(header_data_pointers, &sync_data->replica_guid, eid >> 16); */ emsmdbp_source_key_from_fmid(header_data_pointers, emsmdbp_ctx, owner, eid, &bin_data); query_props.aulPropTag[j] = PidTagSourceKey; header_data_pointers[j] = bin_data; j++; /* last modification time */ if (retvals[sync_data->prop_index.last_modification_time]) { unix_time = oc_version_time; unix_to_nt_time(&nt_time, unix_time); lm_time = talloc_zero(header_data_pointers, struct FILETIME); lm_time->dwLowDateTime = (nt_time & 0xffffffff); lm_time->dwHighDateTime = nt_time >> 32; } else { lm_time = (struct FILETIME *) data_pointers[sync_data->prop_index.last_modification_time]; nt_time = ((uint64_t) lm_time->dwHighDateTime << 32) | lm_time->dwLowDateTime; unix_time = nt_time_to_unix(nt_time); } query_props.aulPropTag[j] = PidTagLastModificationTime; header_data_pointers[j] = lm_time; j++; if (retvals[sync_data->prop_index.change_number]) { DEBUG(5, (__location__": mandatory property PidTagChangeNumber not returned for folder\n")); abort(); } cn = ((*(uint64_t *) data_pointers[sync_data->prop_index.change_number]) >> 16) & 0x0000ffffffffffff; if (IDSET_includes_guid_glob(synccontext->cnset_seen, &sync_data->replica_guid, cn)) { synccontext->skipped_objects++; DEBUG(5, (__location__": folder changes: cn %.16"PRIx64" already present\n", cn)); goto end_row; } RAWIDSET_push_guid_glob(sync_data->cnset_seen, &sync_data->replica_guid, cn); /* change key */ if (retvals[sync_data->prop_index.change_key]) { bin_data = oxcfxics_make_gid(header_data_pointers, &sync_data->replica_guid, cn); } else { bin_data = data_pointers[sync_data->prop_index.change_key]; } query_props.aulPropTag[j] = PidTagChangeKey; header_data_pointers[j] = bin_data; j++; /* predecessor... (already computed) */ query_props.aulPropTag[j] = PidTagPredecessorChangeList; if (retvals[sync_data->prop_index.predecessor_change_list]) { predecessors_data.cb = bin_data->cb + 1; predecessors_data.lpb = talloc_array(header_data_pointers, uint8_t, predecessors_data.cb); *predecessors_data.lpb = bin_data->cb & 0xff; memcpy(predecessors_data.lpb + 1, bin_data->lpb, bin_data->cb); header_data_pointers[j] = &predecessors_data; } else { bin_data = data_pointers[sync_data->prop_index.predecessor_change_list]; header_data_pointers[j] = bin_data; } j++; /* display name */ query_props.aulPropTag[j] = PidTagDisplayName; if (retvals[sync_data->prop_index.display_name]) { header_data_pointers[j] = ""; } else { header_data_pointers[j] = data_pointers[sync_data->prop_index.display_name]; } j++; /* folder id (conditional) */ if (synccontext->request.request_eid) { query_props.aulPropTag[j] = PidTagFolderId; header_data_pointers[j] = data_pointers[sync_data->prop_index.eid]; j++; } /* parent folder id (conditional) */ if (synccontext->request.no_foreign_identifiers) { query_props.aulPropTag[j] = PidTagParentFolderId; header_data_pointers[j] = data_pointers[sync_data->prop_index.parent_fid]; if (retvals[sync_data->prop_index.parent_fid]) { header_data_pointers[j] = talloc_zero(header_data_pointers, uint64_t); } else { header_data_pointers[j] = data_pointers[sync_data->prop_index.parent_fid]; } j++; } query_props.cValues = j; ndr_push_uint32(sync_data->ndr, NDR_SCALARS, PidTagIncrSyncChg); ndr_push_uint32(sync_data->cutmarks_ndr, NDR_SCALARS, 0); ndr_push_uint32(sync_data->cutmarks_ndr, NDR_SCALARS, sync_data->ndr->offset); oxcfxics_ndr_push_properties(sync_data->ndr, sync_data->cutmarks_ndr, emsmdbp_ctx->mstore_ctx->nprops_ctx, &query_props, header_data_pointers, (enum MAPISTATUS *) header_retvals); /** remaining props */ if (table_object->object.table->prop_count > folder_properties_shift) { query_props.cValues = table_object->object.table->prop_count - folder_properties_shift; query_props.aulPropTag = table_object->object.table->properties + folder_properties_shift; oxcfxics_ndr_push_properties(sync_data->ndr, sync_data->cutmarks_ndr, emsmdbp_ctx->mstore_ctx->nprops_ctx, &query_props, data_pointers + folder_properties_shift, (enum MAPISTATUS *) retvals + folder_properties_shift); } synccontext->sent_objects++; end_row: talloc_free(header_data_pointers); talloc_free(data_pointers); talloc_free(retvals); /* TODO: check return code */ emsmdbp_object_open_folder(NULL, emsmdbp_ctx, folder_object, eid, &subfolder_object); oxcfxics_push_folderChange(emsmdbp_ctx, synccontext, owner, topmost_folder_object, sync_data, subfolder_object); talloc_free(subfolder_object); } /* else { */ /* DEBUG(5, ("no data returned for folder row %d\n", i)); */ /* abort(); */ /* } */ } talloc_free(mem_ctx); } static void oxcfxics_prepare_synccontext_with_folderChange(struct emsmdbp_object_synccontext *synccontext, TALLOC_CTX *mem_ctx, struct emsmdbp_context *emsmdbp_ctx, const char *owner, struct emsmdbp_object *parent_object) { struct oxcfxics_sync_data *sync_data; struct idset *new_idset, *old_idset; /* 1b. we setup context data */ sync_data = talloc_zero(NULL, struct oxcfxics_sync_data); openchangedb_get_MailboxReplica(emsmdbp_ctx->oc_ctx, owner, NULL, &sync_data->replica_guid); SPropTagArray_find(synccontext->properties, PidTagParentFolderId, &sync_data->prop_index.parent_fid); SPropTagArray_find(synccontext->properties, PidTagFolderId, &sync_data->prop_index.eid); SPropTagArray_find(synccontext->properties, PidTagChangeNumber, &sync_data->prop_index.change_number); SPropTagArray_find(synccontext->properties, PidTagChangeKey, &sync_data->prop_index.change_key); SPropTagArray_find(synccontext->properties, PidTagPredecessorChangeList, &sync_data->prop_index.predecessor_change_list); SPropTagArray_find(synccontext->properties, PidTagLastModificationTime, &sync_data->prop_index.last_modification_time); SPropTagArray_find(synccontext->properties, PidTagDisplayName, &sync_data->prop_index.display_name); sync_data->ndr = ndr_push_init_ctx(sync_data); ndr_set_flags(&sync_data->ndr->flags, LIBNDR_FLAG_NOALIGN); sync_data->ndr->offset = 0; sync_data->cutmarks_ndr = ndr_push_init_ctx(sync_data); ndr_set_flags(&sync_data->cutmarks_ndr->flags, LIBNDR_FLAG_NOALIGN); sync_data->cutmarks_ndr->offset = 0; sync_data->cnset_seen = RAWIDSET_make(sync_data, false, true); sync_data->eid_set = RAWIDSET_make(sync_data, false, false); oxcfxics_push_folderChange(emsmdbp_ctx, synccontext, owner, parent_object, sync_data, parent_object); /* deletions (mapistore v2) */ /* state */ ndr_push_uint32(sync_data->ndr, NDR_SCALARS, PidTagIncrSyncStateBegin); new_idset = RAWIDSET_convert_to_idset(NULL, sync_data->cnset_seen); old_idset = synccontext->cnset_seen; /* IDSET_dump (synccontext->cnset_seen, "initial cnset_seen (folder change)"); */ synccontext->cnset_seen = IDSET_merge_idsets(synccontext, old_idset, new_idset); /* IDSET_dump (synccontext->cnset_seen, "merged cnset_seen (folder change)"); */ talloc_free(old_idset); talloc_free(new_idset); ndr_push_uint32(sync_data->ndr, NDR_SCALARS, PidTagCnsetSeen); ndr_push_uint32(sync_data->cutmarks_ndr, NDR_SCALARS, 0); ndr_push_uint32(sync_data->cutmarks_ndr, NDR_SCALARS, sync_data->ndr->offset); ndr_push_idset(sync_data->ndr, synccontext->cnset_seen); ndr_push_uint32(sync_data->cutmarks_ndr, NDR_SCALARS, 0); ndr_push_uint32(sync_data->cutmarks_ndr, NDR_SCALARS, sync_data->ndr->offset); new_idset = RAWIDSET_convert_to_idset(NULL, sync_data->eid_set); old_idset = synccontext->idset_given; /* IDSET_dump (synccontext->idset_given, "initial idset_given (folder change)"); */ synccontext->idset_given = IDSET_merge_idsets(synccontext, old_idset, new_idset); /* IDSET_dump (synccontext->idset_given, "merged idset_given (folder change)"); */ talloc_free(old_idset); talloc_free(new_idset); ndr_push_uint32(sync_data->ndr, NDR_SCALARS, PidTagIdsetGiven); ndr_push_uint32(sync_data->cutmarks_ndr, NDR_SCALARS, 0); ndr_push_uint32(sync_data->cutmarks_ndr, NDR_SCALARS, sync_data->ndr->offset); ndr_push_idset(sync_data->ndr, synccontext->idset_given); ndr_push_uint32(sync_data->cutmarks_ndr, NDR_SCALARS, 0); ndr_push_uint32(sync_data->cutmarks_ndr, NDR_SCALARS, sync_data->ndr->offset); ndr_push_uint32(sync_data->ndr, NDR_SCALARS, PidTagIncrSyncStateEnd); ndr_push_uint32(sync_data->cutmarks_ndr, NDR_SCALARS, 0); ndr_push_uint32(sync_data->cutmarks_ndr, NDR_SCALARS, sync_data->ndr->offset); /* end of stream */ ndr_push_uint32(sync_data->ndr, NDR_SCALARS, PidTagIncrSyncEnd); ndr_push_uint32(sync_data->cutmarks_ndr, NDR_SCALARS, 0); ndr_push_uint32(sync_data->cutmarks_ndr, NDR_SCALARS, sync_data->ndr->offset); ndr_push_uint32(sync_data->cutmarks_ndr, NDR_SCALARS, 0); ndr_push_uint32(sync_data->cutmarks_ndr, NDR_SCALARS, 0xffffffff); synccontext->cutmarks = (uint32_t *) sync_data->cutmarks_ndr->data; synccontext->next_cutmark_idx = 1; synccontext->stream.position = 0; synccontext->stream.buffer.data = sync_data->ndr->data; synccontext->stream.buffer.length = sync_data->ndr->offset; (void) talloc_reference(synccontext, sync_data->ndr->data); (void) talloc_reference(synccontext, sync_data->cutmarks_ndr->data); talloc_free(sync_data); } static inline void oxcfxics_fill_ftcontext_fasttransfer_response(struct FastTransferSourceGetBuffer_repl *response, uint32_t request_buffer_size, TALLOC_CTX *mem_ctx, struct emsmdbp_object_ftcontext *ftcontext, struct emsmdbp_context *emsmdbp_ctx) { uint32_t buffer_size, min_value_buffer, mark_idx, max_cutmark; buffer_size = request_buffer_size; if (ftcontext->stream.position == 0) { ftcontext->steps = 0; ftcontext->total_steps = (ftcontext->stream.buffer.length / request_buffer_size) + 1; ftcontext->next_cutmark_idx = 1; oxcfxics_check_cutmark_buffer(ftcontext->cutmarks, &ftcontext->stream.buffer); DEBUG(5, ("fast transfer buffer is %d bytes long\n", (uint32_t) ftcontext->stream.buffer.length)); } ftcontext->steps += 1; if (ftcontext->stream.position + request_buffer_size < ftcontext->stream.buffer.length) { mark_idx = ftcontext->next_cutmark_idx; max_cutmark = ftcontext->stream.position + request_buffer_size; /* FIXME: cutmark lookups would be faster using a binary search */ while (ftcontext->cutmarks[mark_idx] != 0xffffffff && ftcontext->cutmarks[mark_idx] < max_cutmark) { buffer_size = ftcontext->cutmarks[mark_idx] - ftcontext->stream.position; mark_idx += 2; } if (buffer_size < request_buffer_size && ftcontext->cutmarks[mark_idx] != 0xffffffff) { min_value_buffer = ftcontext->cutmarks[mark_idx-1]; if (min_value_buffer && (request_buffer_size - buffer_size > min_value_buffer)) { buffer_size = request_buffer_size; } } ftcontext->next_cutmark_idx = mark_idx; } response->TransferBuffer = emsmdbp_stream_read_buffer(&ftcontext->stream, buffer_size); response->TotalStepCount = ftcontext->total_steps; if (ftcontext->stream.position == ftcontext->stream.buffer.length) { response->TransferStatus = TransferStatus_Done; response->InProgressCount = response->TotalStepCount; } else { response->TransferStatus = TransferStatus_Partial; response->InProgressCount = ftcontext->steps; } } static uint32_t oxcfxics_advance_cutmarks(struct emsmdbp_object_synccontext *synccontext, uint32_t request_buffer_size) { uint32_t buffer_size, min_value_buffer, mark_idx, max_cutmark; buffer_size = request_buffer_size; mark_idx = synccontext->next_cutmark_idx; max_cutmark = synccontext->stream.position + request_buffer_size; /* FIXME: cutmark lookups would be faster using a binary search */ while (synccontext->cutmarks[mark_idx] != 0xffffffff && synccontext->cutmarks[mark_idx] < max_cutmark) { buffer_size = synccontext->cutmarks[mark_idx] - synccontext->stream.position; mark_idx += 2; } if (buffer_size < request_buffer_size && synccontext->cutmarks[mark_idx] != 0xffffffff) { min_value_buffer = synccontext->cutmarks[mark_idx-1]; if (min_value_buffer && (request_buffer_size - buffer_size > min_value_buffer)) { buffer_size = request_buffer_size; } } synccontext->next_cutmark_idx = mark_idx; return buffer_size; } static inline void oxcfxics_fill_synccontext_fasttransfer_response(struct FastTransferSourceGetBuffer_repl *response, uint32_t request_buffer_size, TALLOC_CTX *mem_ctx, struct emsmdbp_object_synccontext *synccontext, struct emsmdbp_object *parent_object) { char *owner; size_t old_chunk_size, new_chunk_size; uint32_t buffer_size; bool end_of_buffer = false; DATA_BLOB joint_buffer; owner = emsmdbp_get_owner(parent_object); DEBUG(5, ("start syncstream: position = %zu, size = %zu\n", synccontext->stream.position, synccontext->stream.buffer.length)); if (synccontext->stream.position + request_buffer_size < synccontext->stream.buffer.length) { /* the current chunk has not been "emptied" yet */ buffer_size = oxcfxics_advance_cutmarks(synccontext, request_buffer_size); response->TransferBuffer = emsmdbp_stream_read_buffer(&synccontext->stream, buffer_size); } else { /* the current chunk not does exist or we reached its end */ if (synccontext->request.contents_mode) { DEBUG(5, ("content mode, stage %d\n", synccontext->sync_stage)); if (synccontext->sync_stage == 4) { /* the last chunk was the last one */ end_of_buffer = true; response->TransferBuffer = emsmdbp_stream_read_buffer(&synccontext->stream, request_buffer_size); } else if (synccontext->sync_stage == 0) { /* no chunk sent yet, so we create a new one */ oxcfxics_fill_synccontext_with_messageChange(synccontext, mem_ctx, parent_object->emsmdbp_ctx, owner, parent_object); oxcfxics_check_cutmark_buffer(synccontext->cutmarks, &synccontext->stream.buffer); if (request_buffer_size < synccontext->stream.buffer.length) { buffer_size = oxcfxics_advance_cutmarks(synccontext, request_buffer_size); } else { buffer_size = request_buffer_size; if (synccontext->sync_stage == 4) { end_of_buffer = true; } else { abort(); } } response->TransferBuffer = emsmdbp_stream_read_buffer(&synccontext->stream, buffer_size); } else { /* we have reached the end of a middle chunk, we must thus finish it and complete the buffer with the content of the next chunk */ old_chunk_size = synccontext->stream.buffer.length - synccontext->stream.position; if (old_chunk_size > 0) { joint_buffer.length = old_chunk_size; joint_buffer.data = talloc_memdup(mem_ctx, synccontext->stream.buffer.data + synccontext->stream.position, joint_buffer.length); } oxcfxics_fill_synccontext_with_messageChange(synccontext, mem_ctx, parent_object->emsmdbp_ctx, owner, parent_object); oxcfxics_check_cutmark_buffer(synccontext->cutmarks, &synccontext->stream.buffer); new_chunk_size = request_buffer_size - old_chunk_size; if (synccontext->stream.buffer.length < new_chunk_size) { new_chunk_size = synccontext->stream.buffer.length; if (synccontext->sync_stage == 4) { end_of_buffer = true; } else { abort(); } } else { new_chunk_size = oxcfxics_advance_cutmarks(synccontext, new_chunk_size); } if (new_chunk_size > 0) { if (old_chunk_size) { joint_buffer.length += new_chunk_size; joint_buffer.data = talloc_realloc(mem_ctx, joint_buffer.data, uint8_t, joint_buffer.length); memcpy(joint_buffer.data + old_chunk_size, synccontext->stream.buffer.data, new_chunk_size); synccontext->stream.position += new_chunk_size; } else { joint_buffer = emsmdbp_stream_read_buffer(&synccontext->stream, new_chunk_size); } } response->TransferBuffer = joint_buffer; DEBUG(5, ("joint buffers of sizes %zu and %zu\n", old_chunk_size, new_chunk_size)); } } else { buffer_size = request_buffer_size; if (synccontext->stream.buffer.data) { end_of_buffer = true; } else { oxcfxics_prepare_synccontext_with_folderChange(synccontext, mem_ctx, parent_object->emsmdbp_ctx, owner, parent_object); oxcfxics_check_cutmark_buffer(synccontext->cutmarks, &synccontext->stream.buffer); DEBUG(5, ("synccontext buffer is %u bytes long\n", (uint32_t) synccontext->stream.buffer.length)); } response->TransferBuffer = emsmdbp_stream_read_buffer(&synccontext->stream, buffer_size); } } response->TotalStepCount = synccontext->total_steps; /* if (synccontext->stream.position == synccontext->stream.buffer.length) { */ if (end_of_buffer) { response->TransferStatus = TransferStatus_Done; response->InProgressCount = response->TotalStepCount; } else { response->TransferStatus = TransferStatus_Partial; response->InProgressCount = synccontext->steps; } DEBUG(5, (" end syncstream: position = %zu, size = %zu", synccontext->stream.position, synccontext->stream.buffer.length)); } /** \details EcDoRpc EcDoRpc_RopFastTransferSourceGetBuffer (0x4e) Rop. This operation downloads the next portion of a FastTransfer stream that is produced by a previously configured download operation. \param mem_ctx pointer to the memory context \param emsmdbp_ctx pointer to the emsmdb provider context \param mapi_req pointer to the FastTransferSourceGetBuffer EcDoRpc_MAPI_REQ structure \param mapi_repl pointer to the FastTransferSourceGetBuffer EcDoRpc_MAPI_REPL structure \param handles pointer to the MAPI handles array \param size pointer to the mapi_response size to update \return MAPI_E_SUCCESS on success, otherwise MAPI error */ _PUBLIC_ enum MAPISTATUS EcDoRpc_RopFastTransferSourceGetBuffer(TALLOC_CTX *mem_ctx, struct emsmdbp_context *emsmdbp_ctx, struct EcDoRpc_MAPI_REQ *mapi_req, struct EcDoRpc_MAPI_REPL *mapi_repl, uint32_t *handles, uint16_t *size) { enum MAPISTATUS retval; uint32_t handle_id; struct mapi_handles *object_handle = NULL; struct emsmdbp_object *object = NULL; struct FastTransferSourceGetBuffer_req *request; struct FastTransferSourceGetBuffer_repl *response; uint32_t request_buffer_size; void *data; DEBUG(4, ("exchange_emsmdb: [OXCFXICS] FastTransferSourceGetBuffer (0x4e)\n")); /* Sanity checks */ OPENCHANGE_RETVAL_IF(!emsmdbp_ctx, MAPI_E_NOT_INITIALIZED, NULL); OPENCHANGE_RETVAL_IF(!mapi_req, MAPI_E_INVALID_PARAMETER, NULL); OPENCHANGE_RETVAL_IF(!mapi_repl, MAPI_E_INVALID_PARAMETER, NULL); OPENCHANGE_RETVAL_IF(!handles, MAPI_E_INVALID_PARAMETER, NULL); OPENCHANGE_RETVAL_IF(!size, MAPI_E_INVALID_PARAMETER, NULL); mapi_repl->opnum = mapi_req->opnum; mapi_repl->error_code = MAPI_E_SUCCESS; mapi_repl->handle_idx = mapi_req->handle_idx; /* Step 1. Retrieve object handle */ handle_id = handles[mapi_req->handle_idx]; retval = mapi_handles_search(emsmdbp_ctx->handles_ctx, handle_id, &object_handle); if (retval) { mapi_repl->error_code = MAPI_E_INVALID_OBJECT; DEBUG(5, (" handle (%x) not found: %x\n", handle_id, mapi_req->handle_idx)); goto end; } /* Step 2. Check whether the parent object supports fetching properties */ mapi_handles_get_private_data(object_handle, &data); object = (struct emsmdbp_object *) data; if (!object) { mapi_repl->error_code = MAPI_E_INVALID_OBJECT; DEBUG(5, (" object not found\n")); goto end; } request = &mapi_req->u.mapi_FastTransferSourceGetBuffer; response = &mapi_repl->u.mapi_FastTransferSourceGetBuffer; request_buffer_size = request->BufferSize; if (request_buffer_size == 0xBABE) { request_buffer_size = request->MaximumBufferSize.MaximumBufferSize; } /* Step 3. Perform the read operation */ switch (object->type) { case EMSMDBP_OBJECT_FTCONTEXT: oxcfxics_fill_ftcontext_fasttransfer_response(response, request_buffer_size, mem_ctx, object->object.ftcontext, emsmdbp_ctx); break; case EMSMDBP_OBJECT_SYNCCONTEXT: oxcfxics_fill_synccontext_fasttransfer_response(response, request_buffer_size, mem_ctx, object->object.synccontext, object->parent_object); break; default: mapi_repl->error_code = MAPI_E_INVALID_OBJECT; DEBUG(5, (" object type %d not supported\n", object->type)); goto end; } response->TransferBufferSize = response->TransferBuffer.length; response->Reserved = 0; end: *size += libmapiserver_RopFastTransferSourceGetBuffer_size(mapi_repl); return MAPI_E_SUCCESS; } /** \details EcDoRpc EcDoRpc_RopSyncConfigure (0x70) Rop. \param mem_ctx pointer to the memory context \param emsmdbp_ctx pointer to the emsmdb provider context \param mapi_req pointer to the SyncConfigure EcDoRpc_MAPI_REQ structure \param mapi_repl pointer to the SyncConfigure EcDoRpc_MAPI_REPL structure \param handles pointer to the MAPI handles array \param size pointer to the mapi_response size to update \return MAPI_E_SUCCESS on success, otherwise MAPI error */ _PUBLIC_ enum MAPISTATUS EcDoRpc_RopSyncConfigure(TALLOC_CTX *mem_ctx, struct emsmdbp_context *emsmdbp_ctx, struct EcDoRpc_MAPI_REQ *mapi_req, struct EcDoRpc_MAPI_REPL *mapi_repl, uint32_t *handles, uint16_t *size) { struct SyncConfigure_req *request; uint32_t folder_handle; struct mapi_handles *folder_rec; struct mapi_handles *synccontext_rec; struct emsmdbp_object *folder_object; struct emsmdbp_object *synccontext_object; struct emsmdbp_object *table_object; struct emsmdbp_object_synccontext *synccontext; enum MAPISTATUS retval; bool *properties_exclusion; bool include_props; uint16_t i, j; void *data = NULL; struct SPropTagArray *available_properties; DEBUG(4, ("exchange_emsmdb: [OXCFXICS] RopSyncConfigure (0x70)\n")); /* Sanity checks */ OPENCHANGE_RETVAL_IF(!emsmdbp_ctx, MAPI_E_NOT_INITIALIZED, NULL); OPENCHANGE_RETVAL_IF(!mapi_req, MAPI_E_INVALID_PARAMETER, NULL); OPENCHANGE_RETVAL_IF(!mapi_repl, MAPI_E_INVALID_PARAMETER, NULL); OPENCHANGE_RETVAL_IF(!handles, MAPI_E_INVALID_PARAMETER, NULL); OPENCHANGE_RETVAL_IF(!size, MAPI_E_INVALID_PARAMETER, NULL); request = &mapi_req->u.mapi_SyncConfigure; mapi_repl->opnum = mapi_req->opnum; mapi_repl->error_code = MAPI_E_SUCCESS; mapi_repl->handle_idx = request->handle_idx; folder_handle = handles[mapi_req->handle_idx]; retval = mapi_handles_search(emsmdbp_ctx->handles_ctx, folder_handle, &folder_rec); if (retval) { DEBUG(5, (" handle (%x) not found: %x\n", folder_handle, mapi_req->handle_idx)); mapi_repl->error_code = MAPI_E_INVALID_OBJECT; goto end; } mapi_handles_get_private_data(folder_rec, &data); folder_object = (struct emsmdbp_object *)data; if (!folder_object || folder_object->type != EMSMDBP_OBJECT_FOLDER) { DEBUG(5, (" object not found or not a folder\n")); mapi_repl->error_code = MAPI_E_INVALID_OBJECT; goto end; } synccontext_object = emsmdbp_object_synccontext_init(NULL, emsmdbp_ctx, folder_object); synccontext = synccontext_object->object.synccontext; gettimeofday(&synccontext->request_start, NULL); /* SynchronizationType */ synccontext->request.is_collector = false; synccontext->request.contents_mode = (request->SynchronizationType == Contents); /* SendOptions */ synccontext->request.unicode = (request->SendOptions & FastTransfer_Unicode); synccontext->request.use_cpid = (request->SendOptions & FastTransfer_UseCpid); synccontext->request.recover_mode = (request->SendOptions & FastTransfer_RecoverMode); synccontext->request.force_unicode = (request->SendOptions & FastTransfer_ForceUnicode); synccontext->request.partial_item = (request->SendOptions & FastTransfer_PartialItem); /* SynchronizationFlag */ if (synccontext->request.unicode && !(request->SynchronizationFlag & SynchronizationFlag_Unicode)) { DEBUG(4, ("unhandled value for SynchronizationType: %d\n", request->SynchronizationType)); mapi_repl->error_code = MAPI_E_INVALID_PARAMETER; talloc_free(synccontext_object); goto end; } synccontext->request.no_deletions = (request->SynchronizationFlag & SynchronizationFlag_NoDeletions); synccontext->request.no_soft_deletions = (request->SynchronizationFlag & SynchronizationFlag_NoSoftDeletions); synccontext->request.ignore_no_longer_in_scope = (request->SynchronizationFlag & SynchronizationFlag_NoSoftDeletions); synccontext->request.read_state = (request->SynchronizationFlag & SynchronizationFlag_ReadState); synccontext->request.fai = (request->SynchronizationFlag & SynchronizationFlag_FAI); synccontext->request.normal = (request->SynchronizationFlag & SynchronizationFlag_Normal); synccontext->request.no_foreign_identifiers = (request->SynchronizationFlag & SynchronizationFlag_NoForeignIdentifiers); synccontext->request.best_body = (request->SynchronizationFlag & SynchronizationFlag_BestBody); synccontext->request.ignored_specified_on_fai = (request->SynchronizationFlag & SynchronizationFlag_IgnoreSpecifiedOnFAI); synccontext->request.progress = (request->SynchronizationFlag & SynchronizationFlag_Progress); /* SynchronizationExtraFlag */ synccontext->request.request_eid = (request->SynchronizationExtraFlags & Eid); synccontext->request.request_message_size = (request->SynchronizationExtraFlags & MessageSize); synccontext->request.request_cn = (request->SynchronizationExtraFlags & Cn); synccontext->request.order_by_delivery_time = (request->SynchronizationExtraFlags & OrderByDeliveryTime); /* Building the real properties array... */ properties_exclusion = talloc_array(NULL, bool, 65536); memset(properties_exclusion, 0, 65536 * sizeof(bool)); synccontext->properties.cValues = 0; synccontext->properties.aulPropTag = talloc_zero(synccontext, enum MAPITAGS); if (synccontext->request.contents_mode) { /* keyword: messageChangeHeader */ SPropTagArray_add(synccontext, &synccontext->properties, PidTagMid); /* PidTagSourceKey */ SPropTagArray_add(synccontext, &synccontext->properties, PidTagAssociated); SPropTagArray_add(synccontext, &synccontext->properties, PidTagMessageSize); } else { /* keyword: folderChange */ SPropTagArray_add(synccontext, &synccontext->properties, PidTagParentFolderId); /* PidTagParentSourceKey */ SPropTagArray_add(synccontext, &synccontext->properties, PidTagFolderId); /* PidTagSourceKey */ properties_exclusion[PidTagMessageClass >> 16] = false; } SPropTagArray_add(synccontext, &synccontext->properties, PidTagChangeNumber); SPropTagArray_add(synccontext, &synccontext->properties, PidTagChangeKey); SPropTagArray_add(synccontext, &synccontext->properties, PidTagPredecessorChangeList); SPropTagArray_add(synccontext, &synccontext->properties, PidTagLastModificationTime); SPropTagArray_add(synccontext, &synccontext->properties, PidTagDisplayName); if (!synccontext->request.contents_mode) { SPropTagArray_add(synccontext, &synccontext->properties, PidTagRights); SPropTagArray_add(synccontext, &synccontext->properties, PidTagAccessLevel); } for (j = 0; j < synccontext->properties.cValues; j++) { i = (synccontext->properties.aulPropTag[j] & 0xffff0000) >> 16; properties_exclusion[i] = true; } /* Explicit exclusions */ properties_exclusion[(uint16_t) (PidTagRowType >> 16)] = true; properties_exclusion[(uint16_t) (PidTagInstanceKey >> 16)] = true; properties_exclusion[(uint16_t) (PidTagInstanceNum >> 16)] = true; properties_exclusion[(uint16_t) (PidTagInstID >> 16)] = true; properties_exclusion[(uint16_t) (PidTagFolderId >> 16)] = true; properties_exclusion[(uint16_t) (PidTagMid >> 16)] = true; properties_exclusion[(uint16_t) (PidTagSourceKey >> 16)] = true; properties_exclusion[(uint16_t) (PidTagParentSourceKey >> 16)] = true; properties_exclusion[(uint16_t) (PidTagParentFolderId >> 16)] = true; /* Include or exclude specified properties passed in array */ include_props = ((request->SynchronizationFlag & SynchronizationFlag_OnlySpecifiedProperties)); for (j = 0; j < request->PropertyTags.cValues; j++) { i = (uint16_t) (request->PropertyTags.aulPropTag[j] >> 16); if (!properties_exclusion[i]) { properties_exclusion[i] = true; /* avoid including the same prop twice */ if (include_props) { SPropTagArray_add(synccontext, &synccontext->properties, request->PropertyTags.aulPropTag[j]); } } } /* When "best body" is requested and one of the required properties is excluded, we include it back */ if (!include_props && ((request->SynchronizationFlag & SynchronizationFlag_BestBody))) { properties_exclusion[PidTagBodyHtml >> 16] = false; properties_exclusion[PidTagBody >> 16] = false; } /* we instantiate a table object that will help us retrieve the list of available properties */ /* FIXME: the table_get_available_properties operations should actually be replaced with per-object requests, since not all message/folder types return the same available properties */ if (!include_props) { if (synccontext->request.contents_mode) { if (synccontext->request.normal) { table_object = emsmdbp_folder_open_table(NULL, folder_object, MAPISTORE_MESSAGE_TABLE, 0); if (!table_object) { DEBUG(5, ("could not open message table\n")); abort(); } if (emsmdbp_object_table_get_available_properties(mem_ctx, emsmdbp_ctx, table_object, &available_properties) == MAPISTORE_SUCCESS) { for (j = 0; j < available_properties->cValues; j++) { i = (available_properties->aulPropTag[j] & 0xffff0000) >> 16; if (!properties_exclusion[i]) { properties_exclusion[i] = true; SPropTagArray_add(synccontext, &synccontext->properties, available_properties->aulPropTag[j]); } } talloc_free(available_properties->aulPropTag); talloc_free(available_properties); } talloc_free(table_object); } if (synccontext->request.fai) { synccontext->fai_properties.cValues = synccontext->properties.cValues; synccontext->fai_properties.aulPropTag = talloc_memdup(synccontext, synccontext->properties.aulPropTag, synccontext->properties.cValues * sizeof (enum MAPITAGS)); table_object = emsmdbp_folder_open_table(NULL, folder_object, MAPISTORE_FAI_TABLE, 0); if (!table_object) { DEBUG(5, ("could not open FAI table\n")); abort(); } if (emsmdbp_object_table_get_available_properties(mem_ctx, emsmdbp_ctx, table_object, &available_properties) == MAPISTORE_SUCCESS) { for (j = 0; j < available_properties->cValues; j++) { i = (available_properties->aulPropTag[j] & 0xffff0000) >> 16; if (!properties_exclusion[i]) { properties_exclusion[i] = true; SPropTagArray_add(synccontext, &synccontext->fai_properties, available_properties->aulPropTag[j]); } } talloc_free(available_properties->aulPropTag); talloc_free(available_properties); } talloc_free(table_object); } } else { table_object = emsmdbp_folder_open_table(NULL, folder_object, MAPISTORE_FOLDER_TABLE, 0); if (!table_object) { DEBUG(5, ("could not open folder table\n")); abort(); } if (emsmdbp_object_table_get_available_properties(mem_ctx, emsmdbp_ctx, table_object, &available_properties) == MAPISTORE_SUCCESS) { for (j = 0; j < available_properties->cValues; j++) { i = (available_properties->aulPropTag[j] & 0xffff0000) >> 16; if (!properties_exclusion[i]) { properties_exclusion[i] = true; SPropTagArray_add(synccontext, &synccontext->properties, available_properties->aulPropTag[j]); } } talloc_free(available_properties->aulPropTag); talloc_free(available_properties); } talloc_free(table_object); } } talloc_free(properties_exclusion); /* TODO: handle restrictions */ /* The properties array is now ready and further processing must occur in the first FastTransferSource_GetBuffer since we need to wait to receive the state streams in order to build it. */ retval = mapi_handles_add(emsmdbp_ctx->handles_ctx, folder_handle, &synccontext_rec); (void) talloc_reference(synccontext_rec, synccontext_object); mapi_handles_set_private_data(synccontext_rec, synccontext_object); talloc_free(synccontext_object); handles[mapi_repl->handle_idx] = synccontext_rec->handle; end: *size += libmapiserver_RopSyncConfigure_size(mapi_repl); return MAPI_E_SUCCESS; } /** \details EcDoRpc EcDoRpc_RopSyncImportMessageChange (0x72) Rop. \param mem_ctx pointer to the memory context \param emsmdbp_ctx pointer to the emsmdb provider context \param mapi_req pointer to the SyncImportMessageChange EcDoRpc_MAPI_REQ structure \param mapi_repl pointer to the SyncImportMessageChange EcDoRpc_MAPI_REPL structure \param handles pointer to the MAPI handles array \param size pointer to the mapi_response size to update \return MAPI_E_SUCCESS on success, otherwise MAPI error */ _PUBLIC_ enum MAPISTATUS EcDoRpc_RopSyncImportMessageChange(TALLOC_CTX *mem_ctx, struct emsmdbp_context *emsmdbp_ctx, struct EcDoRpc_MAPI_REQ *mapi_req, struct EcDoRpc_MAPI_REPL *mapi_repl, uint32_t *handles, uint16_t *size) { enum MAPISTATUS retval; enum mapistore_error ret; struct mapi_handles *synccontext_object_handle = NULL, *message_object_handle; struct emsmdbp_object *synccontext_object = NULL, *message_object; uint32_t synccontext_handle_id; void *data; struct SyncImportMessageChange_req *request; struct SyncImportMessageChange_repl *response; char *owner; uint64_t folderID, messageID; struct GUID replica_guid; uint16_t repl_id, i; struct mapistore_message *msg; struct SRow aRow; DEBUG(4, ("exchange_emsmdb: [OXCFXICS] RopSyncImportMessageChange (0x72)\n")); /* Sanity checks */ OPENCHANGE_RETVAL_IF(!emsmdbp_ctx, MAPI_E_NOT_INITIALIZED, NULL); OPENCHANGE_RETVAL_IF(!mapi_req, MAPI_E_INVALID_PARAMETER, NULL); OPENCHANGE_RETVAL_IF(!mapi_repl, MAPI_E_INVALID_PARAMETER, NULL); OPENCHANGE_RETVAL_IF(!handles, MAPI_E_INVALID_PARAMETER, NULL); OPENCHANGE_RETVAL_IF(!size, MAPI_E_INVALID_PARAMETER, NULL); request = &mapi_req->u.mapi_SyncImportMessageChange; response = &mapi_repl->u.mapi_SyncImportMessageChange; mapi_repl->opnum = mapi_req->opnum; mapi_repl->error_code = MAPI_E_SUCCESS; mapi_repl->handle_idx = request->handle_idx; /* Step 1. Retrieve object handle */ synccontext_handle_id = handles[mapi_req->handle_idx]; retval = mapi_handles_search(emsmdbp_ctx->handles_ctx, synccontext_handle_id, &synccontext_object_handle); if (retval) { DEBUG(5, (" handle (%x) not found: %x\n", synccontext_handle_id, mapi_req->handle_idx)); mapi_repl->error_code = MAPI_E_INVALID_OBJECT; goto end; } mapi_handles_get_private_data(synccontext_object_handle, &data); synccontext_object = (struct emsmdbp_object *)data; if (!synccontext_object || synccontext_object->type != EMSMDBP_OBJECT_SYNCCONTEXT) { DEBUG(5, (" object not found or not a synccontext\n")); mapi_repl->error_code = MAPI_E_INVALID_OBJECT; goto end; } if (!emsmdbp_is_mapistore(synccontext_object->parent_object)) { DEBUG(5, (" cannot create message on non-mapistore object\n")); mapi_repl->error_code = MAPI_E_NO_SUPPORT; goto end; } /* The type of messages handled in the collector contexts must be specified in order for the transfer state operations to work properly */ if (request->ImportFlag & ImportFlag_Associated) { synccontext_object->object.synccontext->request.fai = true; } else { synccontext_object->object.synccontext->request.normal = true; } folderID = synccontext_object->parent_object->object.folder->folderID; owner = emsmdbp_get_owner(synccontext_object); openchangedb_get_MailboxReplica(emsmdbp_ctx->oc_ctx, owner, &repl_id, &replica_guid); if (oxcfxics_fmid_from_source_key(emsmdbp_ctx, owner, &request->PropertyValues.lpProps[0].value.bin, &messageID)) { mapi_repl->error_code = MAPI_E_NOT_FOUND; goto end; } /* Initialize Message object */ retval = mapi_handles_add(emsmdbp_ctx->handles_ctx, 0, &message_object_handle); handles[mapi_repl->handle_idx] = message_object_handle->handle; ret = emsmdbp_object_message_open(message_object_handle, emsmdbp_ctx, synccontext_object->parent_object, folderID, messageID, true, &message_object, &msg); if (ret == MAPISTORE_ERR_NOT_FOUND) { message_object = emsmdbp_object_message_init(message_object_handle, emsmdbp_ctx, messageID, synccontext_object->parent_object); if (mapistore_folder_create_message(emsmdbp_ctx->mstore_ctx, emsmdbp_get_contextID(synccontext_object->parent_object), synccontext_object->parent_object->backend_object, message_object, messageID, (request->ImportFlag & ImportFlag_Associated), &message_object->backend_object)) { mapi_handles_delete(emsmdbp_ctx->handles_ctx, message_object_handle->handle); DEBUG(5, ("could not open nor create mapistore message\n")); mapi_repl->error_code = MAPI_E_NOT_FOUND; goto end; } message_object->object.message->read_write = true; } else if (ret != MAPISTORE_SUCCESS) { mapi_handles_delete(emsmdbp_ctx->handles_ctx, message_object_handle->handle); if (ret == MAPISTORE_ERR_DENIED) { mapi_repl->error_code = MAPI_E_NO_ACCESS; } else { mapi_repl->error_code = MAPI_E_INVALID_OBJECT; } goto end; } mapi_handles_set_private_data(message_object_handle, message_object); response->MessageId = 0; /* Must be set to 0 */ aRow.cValues = request->PropertyValues.cValues; aRow.lpProps = talloc_array(mem_ctx, struct SPropValue, aRow.cValues + 2); for (i = 0; i < request->PropertyValues.cValues; i++) { cast_SPropValue(aRow.lpProps, &request->PropertyValues.lpProps[i], &(aRow.lpProps[i])); } emsmdbp_object_set_properties(emsmdbp_ctx, message_object, &aRow); end: *size += libmapiserver_RopSyncImportMessageChange_size(mapi_repl); return MAPI_E_SUCCESS; } /** \details EcDoRpc EcDoRpc_RopSyncImportHierarchyChange (0x73) Rop. \param mem_ctx pointer to the memory context \param emsmdbp_ctx pointer to the emsmdb provider context \param mapi_req pointer to the SyncImportHierarchyChange EcDoRpc_MAPI_REQ structure \param mapi_repl pointer to the SyncImportHierarchyChange EcDoRpc_MAPI_REPL structure \param handles pointer to the MAPI handles array \param size pointer to the mapi_response size to update \return MAPI_E_SUCCESS on success, otherwise MAPI error */ _PUBLIC_ enum MAPISTATUS EcDoRpc_RopSyncImportHierarchyChange(TALLOC_CTX *mem_ctx, struct emsmdbp_context *emsmdbp_ctx, struct EcDoRpc_MAPI_REQ *mapi_req, struct EcDoRpc_MAPI_REPL *mapi_repl, uint32_t *handles, uint16_t *size) { enum MAPISTATUS retval; enum mapistore_error ret; struct mapi_handles *synccontext_object_handle = NULL; struct emsmdbp_object *synccontext_object = NULL, *folder_object = NULL, *parent_folder = NULL; uint32_t synccontext_handle_id; void *data; struct SyncImportHierarchyChange_req *request; struct SyncImportHierarchyChange_repl *response; char *owner; const char *new_folder_name; uint64_t parentFolderID; uint64_t folderID, cn; struct GUID replica_guid; uint16_t repl_id; uint32_t i; struct SRow aRow; bool folder_was_open = true; DEBUG(4, ("exchange_emsmdb: [OXCFXICS] RopSyncImportHierarchyChange (0x73)\n")); /* Sanity checks */ OPENCHANGE_RETVAL_IF(!emsmdbp_ctx, MAPI_E_NOT_INITIALIZED, NULL); OPENCHANGE_RETVAL_IF(!mapi_req, MAPI_E_INVALID_PARAMETER, NULL); OPENCHANGE_RETVAL_IF(!mapi_repl, MAPI_E_INVALID_PARAMETER, NULL); OPENCHANGE_RETVAL_IF(!handles, MAPI_E_INVALID_PARAMETER, NULL); OPENCHANGE_RETVAL_IF(!size, MAPI_E_INVALID_PARAMETER, NULL); mapi_repl->opnum = mapi_req->opnum; mapi_repl->error_code = MAPI_E_SUCCESS; mapi_repl->handle_idx = mapi_req->handle_idx; /* Step 1. Retrieve object handle */ synccontext_handle_id = handles[mapi_req->handle_idx]; retval = mapi_handles_search(emsmdbp_ctx->handles_ctx, synccontext_handle_id, &synccontext_object_handle); if (retval) { mapi_repl->error_code = MAPI_E_INVALID_OBJECT; DEBUG(5, (" handle (%x) not found: %x\n", synccontext_handle_id, mapi_req->handle_idx)); goto end; } mapi_handles_get_private_data(synccontext_object_handle, &data); synccontext_object = (struct emsmdbp_object *)data; if (!synccontext_object || synccontext_object->type != EMSMDBP_OBJECT_SYNCCONTEXT) { DEBUG(5, (" object not found or not a synccontext\n")); mapi_repl->error_code = MAPI_E_INVALID_OBJECT; goto end; } request = &mapi_req->u.mapi_SyncImportHierarchyChange; response = &mapi_repl->u.mapi_SyncImportHierarchyChange; owner = emsmdbp_get_owner(synccontext_object); openchangedb_get_MailboxReplica(emsmdbp_ctx->oc_ctx, owner, &repl_id, &replica_guid); /* deduce the parent folder id (fixed position 0). */ if (oxcfxics_fmid_from_source_key(emsmdbp_ctx, owner, &request->HierarchyValues.lpProps[0].value.bin, &parentFolderID)) { mapi_repl->error_code = MAPI_E_NOT_FOUND; goto end; } /* deduce the folder id (fixed position 1) */ if (oxcfxics_fmid_from_source_key(emsmdbp_ctx, owner, &request->HierarchyValues.lpProps[1].value.bin, &folderID)) { mapi_repl->error_code = MAPI_E_NOT_FOUND; goto end; } aRow.cValues = request->HierarchyValues.cValues + request->PropertyValues.cValues; aRow.lpProps = talloc_array(mem_ctx, struct SPropValue, aRow.cValues + 3); for (i = 0; i < request->HierarchyValues.cValues; i++) { cast_SPropValue(aRow.lpProps, request->HierarchyValues.lpProps + i, aRow.lpProps + i); } for (i = 0; i < request->PropertyValues.cValues; i++) { cast_SPropValue(aRow.lpProps, request->PropertyValues.lpProps + i, aRow.lpProps + request->HierarchyValues.cValues + i); } /* Initialize folder object */ if (synccontext_object->parent_object->object.folder->folderID == parentFolderID) { parent_folder = synccontext_object->parent_object; folder_was_open = true; } else { /* TODO: check return code */ emsmdbp_object_open_folder_by_fid(NULL, emsmdbp_ctx, synccontext_object->parent_object, parentFolderID, &parent_folder); folder_was_open = false; } if (emsmdbp_object_open_folder_by_fid(NULL, emsmdbp_ctx, synccontext_object->parent_object, folderID, &folder_object) != MAPISTORE_SUCCESS) { retval = openchangedb_get_new_changeNumber(emsmdbp_ctx->oc_ctx, &cn); if (retval) { DEBUG(5, (__location__": unable to obtain a change number\n")); folder_object = NULL; mapi_repl->error_code = MAPI_E_NO_SUPPORT; goto end; } aRow.lpProps[aRow.cValues].ulPropTag = PidTagChangeNumber; aRow.lpProps[aRow.cValues].value.d = cn; aRow.cValues++; retval = emsmdbp_object_create_folder(emsmdbp_ctx, parent_folder, NULL, folderID, &aRow, &folder_object); if (retval) { mapi_repl->error_code = retval; DEBUG(5, (__location__": folder creation failed\n")); folder_object = NULL; goto end; } } if (folder_object->parent_object->object.folder->folderID != parent_folder->object.folder->folderID) { /* a move was requested */ new_folder_name = find_SPropValue_data(&aRow, PidTagDisplayName); ret = emsmdbp_folder_move_folder(emsmdbp_ctx, folder_object, parent_folder, mem_ctx, new_folder_name); if (ret != MAPISTORE_SUCCESS) { mapi_repl->error_code = mapistore_error_to_mapi(ret); goto end; } } /* Set properties on folder object */ retval = emsmdbp_object_set_properties(emsmdbp_ctx, folder_object, &aRow); if (retval) { mapi_repl->error_code = MAPI_E_NO_SUPPORT; goto end; } response->FolderId = 0; /* Must be set to 0 */ end: if (folder_object) { talloc_free(folder_object); } if (!folder_was_open) { talloc_free(parent_folder); } *size += libmapiserver_RopSyncImportHierarchyChange_size(mapi_repl); return MAPI_E_SUCCESS; } /** \details EcDoRpc SyncImportDeletes (0x74) Rop. \param mem_ctx pointer to the memory context \param emsmdbp_ctx pointer to the emsmdb provider context \param mapi_req pointer to the SyncImportDeletes EcDoRpc_MAPI_REQ \param mapi_repl pointer to the SyncImportDeletes EcDoRpc_MAPI_REPL \param handles pointer to the MAPI handles array \param size pointer to the mapi_response size to update \return MAPI_E_SUCCESS on success, otherwise MAPI error */ _PUBLIC_ enum MAPISTATUS EcDoRpc_RopSyncImportDeletes(TALLOC_CTX *mem_ctx, struct emsmdbp_context *emsmdbp_ctx, struct EcDoRpc_MAPI_REQ *mapi_req, struct EcDoRpc_MAPI_REPL *mapi_repl, uint32_t *handles, uint16_t *size) { enum MAPISTATUS retval; struct mapi_handles *synccontext_object_handle = NULL; struct emsmdbp_object *synccontext_object = NULL; uint32_t synccontext_handle_id; void *data; struct SyncImportDeletes_req *request; uint32_t contextID; uint64_t objectID; char *owner; struct GUID replica_guid; uint16_t repl_id; struct mapi_SBinaryArray *object_array; uint8_t delete_type; uint32_t i; int ret; DEBUG(4, ("exchange_emsmdb: [OXCSTOR] SyncImportDeletes (0x74)\n")); /* Sanity checks */ OPENCHANGE_RETVAL_IF(!emsmdbp_ctx, MAPI_E_NOT_INITIALIZED, NULL); OPENCHANGE_RETVAL_IF(!mapi_req, MAPI_E_INVALID_PARAMETER, NULL); OPENCHANGE_RETVAL_IF(!mapi_repl, MAPI_E_INVALID_PARAMETER, NULL); OPENCHANGE_RETVAL_IF(!handles, MAPI_E_INVALID_PARAMETER, NULL); OPENCHANGE_RETVAL_IF(!size, MAPI_E_INVALID_PARAMETER, NULL); mapi_repl->opnum = mapi_req->opnum; mapi_repl->error_code = MAPI_E_SUCCESS; mapi_repl->handle_idx = mapi_req->handle_idx; /* Step 1. Retrieve object handle */ synccontext_handle_id = handles[mapi_req->handle_idx]; retval = mapi_handles_search(emsmdbp_ctx->handles_ctx, synccontext_handle_id, &synccontext_object_handle); if (retval) { DEBUG(5, (" handle (%x) not found: %x\n", synccontext_handle_id, mapi_req->handle_idx)); mapi_repl->error_code = MAPI_E_INVALID_OBJECT; goto end; } mapi_handles_get_private_data(synccontext_object_handle, &data); synccontext_object = (struct emsmdbp_object *)data; if (!synccontext_object || synccontext_object->type != EMSMDBP_OBJECT_SYNCCONTEXT) { DEBUG(5, (" object not found or not a synccontext\n")); mapi_repl->error_code = MAPI_E_INVALID_OBJECT; goto end; } request = &mapi_req->u.mapi_SyncImportDeletes; if (request->Flags & SyncImportDeletes_HardDelete) { delete_type = MAPISTORE_PERMANENT_DELETE; } else { delete_type = MAPISTORE_SOFT_DELETE; } owner = emsmdbp_get_owner(synccontext_object); openchangedb_get_MailboxReplica(emsmdbp_ctx->oc_ctx, owner, &repl_id, &replica_guid); if (request->Flags & SyncImportDeletes_Hierarchy) { object_array = &request->PropertyValues.lpProps[0].value.MVbin; for (i = 0; i < object_array->cValues; i++) { ret = oxcfxics_fmid_from_source_key(emsmdbp_ctx, owner, object_array->bin + i, &objectID); if (ret == MAPISTORE_SUCCESS) { emsmdbp_folder_delete(emsmdbp_ctx, synccontext_object->parent_object, objectID, 0xff); } } } else { if (!emsmdbp_is_mapistore(synccontext_object)) { DEBUG(5, (" no message deletes on non-mapistore store\n")); mapi_repl->error_code = MAPI_E_INVALID_OBJECT; goto end; } contextID = emsmdbp_get_contextID(synccontext_object); object_array = &request->PropertyValues.lpProps[0].value.MVbin; for (i = 0; i < object_array->cValues; i++) { ret = oxcfxics_fmid_from_source_key(emsmdbp_ctx, owner, object_array->bin + i, &objectID); if (ret == MAPISTORE_SUCCESS) { ret = mapistore_folder_delete_message(emsmdbp_ctx->mstore_ctx, contextID, synccontext_object->parent_object->backend_object, objectID, delete_type); if (ret != MAPISTORE_SUCCESS) { DEBUG(5, ("message deletion failed for fmid: 0x%.16"PRIx64"\n", objectID)); } ret = mapistore_indexing_record_del_mid(emsmdbp_ctx->mstore_ctx, contextID, owner, objectID, delete_type); if (ret != MAPISTORE_SUCCESS) { DEBUG(5, ("message deletion of index record failed for fmid: 0x%.16"PRIx64"\n", objectID)); } } } } end: *size += libmapiserver_RopSyncImportDeletes_size(mapi_repl); return MAPI_E_SUCCESS; } /** \details EcDoRpc EcDoRpc_RopSyncUploadStateStreamBegin (0x75) Rop. \param mem_ctx pointer to the memory context \param emsmdbp_ctx pointer to the emsmdb provider context \param mapi_req pointer to the SyncUploadStateStreamBegin EcDoRpc_MAPI_REQ structure \param mapi_repl pointer to the SyncUploadStateStreamBegin EcDoRpc_MAPI_REPL structure \param handles pointer to the MAPI handles array \param size pointer to the mapi_response size to update \return MAPI_E_SUCCESS on success, otherwise MAPI error */ _PUBLIC_ enum MAPISTATUS EcDoRpc_RopSyncUploadStateStreamBegin(TALLOC_CTX *mem_ctx, struct emsmdbp_context *emsmdbp_ctx, struct EcDoRpc_MAPI_REQ *mapi_req, struct EcDoRpc_MAPI_REPL *mapi_repl, uint32_t *handles, uint16_t *size) { uint32_t synccontext_handle; struct mapi_handles *synccontext_rec; struct emsmdbp_object *synccontext_object; enum MAPISTATUS retval; enum StateProperty property; void *data = NULL; DEBUG(4, ("exchange_emsmdb: [OXCFXICS] RopSyncUploadStateStreamBegin (0x75)\n")); /* Sanity checks */ OPENCHANGE_RETVAL_IF(!emsmdbp_ctx, MAPI_E_NOT_INITIALIZED, NULL); OPENCHANGE_RETVAL_IF(!mapi_req, MAPI_E_INVALID_PARAMETER, NULL); OPENCHANGE_RETVAL_IF(!mapi_repl, MAPI_E_INVALID_PARAMETER, NULL); OPENCHANGE_RETVAL_IF(!handles, MAPI_E_INVALID_PARAMETER, NULL); OPENCHANGE_RETVAL_IF(!size, MAPI_E_INVALID_PARAMETER, NULL); mapi_repl->opnum = mapi_req->opnum; mapi_repl->error_code = MAPI_E_SUCCESS; mapi_repl->handle_idx = mapi_req->handle_idx; synccontext_handle = handles[mapi_req->handle_idx]; retval = mapi_handles_search(emsmdbp_ctx->handles_ctx, synccontext_handle, &synccontext_rec); if (retval) { DEBUG(5, (" handle (%x) not found: %x\n", synccontext_handle, mapi_req->handle_idx)); mapi_repl->error_code = MAPI_E_INVALID_OBJECT; goto end; } mapi_handles_get_private_data(synccontext_rec, &data); synccontext_object = (struct emsmdbp_object *)data; if (!synccontext_object || synccontext_object->type != EMSMDBP_OBJECT_SYNCCONTEXT) { DEBUG(5, (" object not found or not a synccontext\n")); mapi_repl->error_code = MAPI_E_INVALID_OBJECT; goto end; } if (synccontext_object->object.synccontext->state_property != 0) { DEBUG(5, (" stream already in pending state\n")); mapi_repl->error_code = MAPI_E_NOT_INITIALIZED; goto end; } property = mapi_req->u.mapi_SyncUploadStateStreamBegin.StateProperty; if (!(property == PidTagIdsetGiven || property == PidTagCnsetSeen || property == PidTagCnsetSeenFAI || property == PidTagCnsetRead)) { DEBUG(5, (" state property is invalid\n")); mapi_repl->error_code = MAPI_E_INVALID_PARAMETER; goto end; } synccontext_object->object.synccontext->state_property = property; memset(&synccontext_object->object.synccontext->state_stream, 0, sizeof(struct emsmdbp_stream)); synccontext_object->object.synccontext->state_stream.buffer.data = talloc_zero(synccontext_object->object.synccontext, uint8_t); end: *size += libmapiserver_RopSyncUploadStateStreamBegin_size(mapi_repl); return MAPI_E_SUCCESS; } /** \details EcDoRpc EcDoRpc_RopSyncUploadStateStreamContinue (0x76) Rop. \param mem_ctx pointer to the memory context \param emsmdbp_ctx pointer to the emsmdb provider context \param mapi_req pointer to the SyncUploadStateStreamContinue EcDoRpc_MAPI_REQ structure \param mapi_repl pointer to the SyncUploadStateStreamContinue EcDoRpc_MAPI_REPL structure \param handles pointer to the MAPI handles array \param size pointer to the mapi_response size to update \return MAPI_E_SUCCESS on success, otherwise MAPI error */ _PUBLIC_ enum MAPISTATUS EcDoRpc_RopSyncUploadStateStreamContinue(TALLOC_CTX *mem_ctx, struct emsmdbp_context *emsmdbp_ctx, struct EcDoRpc_MAPI_REQ *mapi_req, struct EcDoRpc_MAPI_REPL *mapi_repl, uint32_t *handles, uint16_t *size) { uint32_t synccontext_handle; struct mapi_handles *synccontext_rec; struct emsmdbp_object *synccontext_object; enum MAPISTATUS retval; void *data = NULL; struct SyncUploadStateStreamContinue_req *request; DATA_BLOB new_data; DEBUG(4, ("exchange_emsmdb: [OXCFXICS] RopSyncUploadStateStreamContinue (0x76)\n")); /* Sanity checks */ OPENCHANGE_RETVAL_IF(!emsmdbp_ctx, MAPI_E_NOT_INITIALIZED, NULL); OPENCHANGE_RETVAL_IF(!mapi_req, MAPI_E_INVALID_PARAMETER, NULL); OPENCHANGE_RETVAL_IF(!mapi_repl, MAPI_E_INVALID_PARAMETER, NULL); OPENCHANGE_RETVAL_IF(!handles, MAPI_E_INVALID_PARAMETER, NULL); OPENCHANGE_RETVAL_IF(!size, MAPI_E_INVALID_PARAMETER, NULL); mapi_repl->opnum = mapi_req->opnum; mapi_repl->error_code = MAPI_E_SUCCESS; mapi_repl->handle_idx = mapi_req->handle_idx; synccontext_handle = handles[mapi_req->handle_idx]; retval = mapi_handles_search(emsmdbp_ctx->handles_ctx, synccontext_handle, &synccontext_rec); if (retval) { DEBUG(5, (" handle (%x) not found: %x\n", synccontext_handle, mapi_req->handle_idx)); mapi_repl->error_code = MAPI_E_INVALID_OBJECT; goto end; } mapi_handles_get_private_data(synccontext_rec, &data); synccontext_object = (struct emsmdbp_object *)data; if (!synccontext_object || synccontext_object->type != EMSMDBP_OBJECT_SYNCCONTEXT) { DEBUG(5, (" object not found or not a synccontext\n")); mapi_repl->error_code = MAPI_E_INVALID_OBJECT; goto end; } if (synccontext_object->object.synccontext->state_property == 0) { DEBUG(5, (" attempt to feed an idle stream\n")); mapi_repl->error_code = MAPI_E_NOT_INITIALIZED; goto end; } request = &mapi_req->u.mapi_SyncUploadStateStreamContinue; new_data.length = request->StreamDataSize; new_data.data = request->StreamData; emsmdbp_stream_write_buffer(synccontext_object->object.synccontext, &synccontext_object->object.synccontext->state_stream, new_data); end: *size += libmapiserver_RopSyncUploadStateStreamContinue_size(mapi_repl); return MAPI_E_SUCCESS; } static void oxcfxics_check_cnset(struct ldb_context *oc_ctx, struct idset *parsed_idset, const char *label) { uint64_t next_cn, high_cn; if (parsed_idset) { openchangedb_get_next_changeNumber(oc_ctx, &next_cn); next_cn = exchange_globcnt(next_cn >> 16); high_cn = exchange_globcnt(parsed_idset->ranges->high); if (high_cn >= next_cn) { DEBUG(0, ("inconsistency: idset range for '%s' is referencing a change number that has not been issued yet: %"PRIx64" >= %"PRIx64" \n", label, high_cn, next_cn)); abort(); } } } /** \details EcDoRpc EcDoRpc_RopSyncUploadStateStreamEnd (0x77) Rop. \param mem_ctx pointer to the memory context \param emsmdbp_ctx pointer to the emsmdb provider context \param mapi_req pointer to the SyncUploadStateStreamEnd EcDoRpc_MAPI_REQ structure \param mapi_repl pointer to the SyncUploadStateStreamEnd EcDoRpc_MAPI_REPL structure \param handles pointer to the MAPI handles array \param size pointer to the mapi_response size to update \return MAPI_E_SUCCESS on success, otherwise MAPI error */ _PUBLIC_ enum MAPISTATUS EcDoRpc_RopSyncUploadStateStreamEnd(TALLOC_CTX *mem_ctx, struct emsmdbp_context *emsmdbp_ctx, struct EcDoRpc_MAPI_REQ *mapi_req, struct EcDoRpc_MAPI_REPL *mapi_repl, uint32_t *handles, uint16_t *size) { uint32_t synccontext_handle; struct mapi_handles *synccontext_rec; struct emsmdbp_object *synccontext_object; struct emsmdbp_object_synccontext *synccontext; struct idset *parsed_idset, *old_idset = NULL; enum MAPISTATUS retval; void *data = NULL; DEBUG(4, ("exchange_emsmdb: [OXCFXICS] RopSyncUploadStateStreamEnd (0x77)\n")); /* Sanity checks */ OPENCHANGE_RETVAL_IF(!emsmdbp_ctx, MAPI_E_NOT_INITIALIZED, NULL); OPENCHANGE_RETVAL_IF(!mapi_req, MAPI_E_INVALID_PARAMETER, NULL); OPENCHANGE_RETVAL_IF(!mapi_repl, MAPI_E_INVALID_PARAMETER, NULL); OPENCHANGE_RETVAL_IF(!handles, MAPI_E_INVALID_PARAMETER, NULL); OPENCHANGE_RETVAL_IF(!size, MAPI_E_INVALID_PARAMETER, NULL); mapi_repl->opnum = mapi_req->opnum; mapi_repl->error_code = MAPI_E_SUCCESS; mapi_repl->handle_idx = mapi_req->handle_idx; synccontext_handle = handles[mapi_req->handle_idx]; retval = mapi_handles_search(emsmdbp_ctx->handles_ctx, synccontext_handle, &synccontext_rec); if (retval) { DEBUG(5, (" handle (%x) not found: %x\n", synccontext_handle, mapi_req->handle_idx)); mapi_repl->error_code = MAPI_E_INVALID_OBJECT; goto end; } mapi_handles_get_private_data(synccontext_rec, &data); synccontext_object = (struct emsmdbp_object *)data; if (!synccontext_object || synccontext_object->type != EMSMDBP_OBJECT_SYNCCONTEXT) { DEBUG(5, (" object not found or not a synccontext\n")); mapi_repl->error_code = MAPI_E_INVALID_OBJECT; goto end; } if (synccontext_object->object.synccontext->state_property == 0) { DEBUG(5, (" attempt to end an idle stream\n")); mapi_repl->error_code = MAPI_E_NOT_INITIALIZED; goto end; } if (synccontext_object->object.synccontext->request.is_collector) { DEBUG(5, (" synccontext is collector\n")); } /* parse IDSET */ synccontext = synccontext_object->object.synccontext; parsed_idset = IDSET_parse(synccontext, synccontext->state_stream.buffer, false); switch (synccontext->state_property) { case PidTagIdsetGiven: if (parsed_idset && parsed_idset->range_count == 0) { DEBUG(5, ("empty idset, ignored\n")); } old_idset = synccontext->idset_given; synccontext->idset_given = parsed_idset; break; case PidTagCnsetSeen: if (parsed_idset) { parsed_idset->single = true; } oxcfxics_check_cnset(emsmdbp_ctx->oc_ctx, parsed_idset, "cnset_seen"); old_idset = synccontext->cnset_seen; synccontext->cnset_seen = parsed_idset; break; case PidTagCnsetSeenFAI: if (parsed_idset) { parsed_idset->single = true; } oxcfxics_check_cnset(emsmdbp_ctx->oc_ctx, parsed_idset, "cnset_seen_fai"); old_idset = synccontext->cnset_seen_fai; synccontext->cnset_seen_fai = parsed_idset; break; case PidTagCnsetRead: if (parsed_idset) { parsed_idset->single = true; } oxcfxics_check_cnset(emsmdbp_ctx->oc_ctx, parsed_idset, "cnset_seen_read"); old_idset = synccontext->cnset_read; synccontext->cnset_read = parsed_idset; break; } if (old_idset) { talloc_free(old_idset); } /* reset synccontext state */ if (synccontext->state_stream.buffer.length > 0) { talloc_free(synccontext->state_stream.buffer.data); synccontext->state_stream.buffer.data = talloc_zero(synccontext, uint8_t); synccontext->state_stream.buffer.length = 0; } synccontext->state_property = 0; end: *size += libmapiserver_RopSyncUploadStateStreamEnd_size(mapi_repl); return MAPI_E_SUCCESS; } /** \details EcDoRpc SyncImportMessageMove (0x78) Rop. \param mem_ctx pointer to the memory context \param emsmdbp_ctx pointer to the emsmdb provider context \param mapi_req pointer to the SyncImportMessageMove EcDoRpc_MAPI_REQ \param mapi_repl pointer to the SyncImportMessageMove EcDoRpc_MAPI_REPL \param handles pointer to the MAPI handles array \param size pointer to the mapi_response size to update \return MAPI_E_SUCCESS on success, otherwise MAPI error */ static bool convertIdToFMID(const struct GUID *replica_guid, uint8_t *data, uint32_t size, uint64_t *fmidP) { struct GUID guid; uint64_t base, fmid; uint32_t i; if (size < 17) { return false; } GUID_from_string((char *) data, &guid); if (!GUID_equal(replica_guid, &guid)) { return false; } fmid = 0; base = 1; for (i = 16; i < size; i++) { fmid |= (uint64_t) data[i] * base; base <<= 8; } fmid <<= 16; fmid |= 1; *fmidP = fmid; return true; } _PUBLIC_ enum MAPISTATUS EcDoRpc_RopSyncImportMessageMove(TALLOC_CTX *mem_ctx, struct emsmdbp_context *emsmdbp_ctx, struct EcDoRpc_MAPI_REQ *mapi_req, struct EcDoRpc_MAPI_REPL *mapi_repl, uint32_t *handles, uint16_t *size) { struct SyncImportMessageMove_req *request; struct SyncImportMessageMove_repl *response; struct GUID replica_guid; uint64_t sourceFID, sourceMID, destMID; struct Binary_r *change_key; uint32_t contextID, synccontext_handle; void *data; struct mapi_handles *synccontext_rec; struct emsmdbp_object *synccontext_object; struct emsmdbp_object *source_folder_object; char *owner; enum MAPISTATUS retval; bool mapistore; DEBUG(4, ("exchange_emsmdb: [OXCSTOR] SyncImportMessageMove (0x78)\n")); /* Sanity checks */ OPENCHANGE_RETVAL_IF(!emsmdbp_ctx, MAPI_E_NOT_INITIALIZED, NULL); OPENCHANGE_RETVAL_IF(!mapi_req, MAPI_E_INVALID_PARAMETER, NULL); OPENCHANGE_RETVAL_IF(!mapi_repl, MAPI_E_INVALID_PARAMETER, NULL); OPENCHANGE_RETVAL_IF(!handles, MAPI_E_INVALID_PARAMETER, NULL); OPENCHANGE_RETVAL_IF(!size, MAPI_E_INVALID_PARAMETER, NULL); mapi_repl->opnum = mapi_req->opnum; mapi_repl->handle_idx = mapi_req->handle_idx; mapi_repl->error_code = MAPI_E_SUCCESS; /* Step 1. Retrieve object handle */ synccontext_handle = handles[mapi_req->handle_idx]; retval = mapi_handles_search(emsmdbp_ctx->handles_ctx, synccontext_handle, &synccontext_rec); if (retval) { mapi_repl->error_code = MAPI_E_INVALID_OBJECT; DEBUG(5, (" handle (%x) not found: %x\n", synccontext_handle, mapi_req->handle_idx)); goto end; } mapi_handles_get_private_data(synccontext_rec, &data); synccontext_object = (struct emsmdbp_object *) data; if (!synccontext_object || synccontext_object->type != EMSMDBP_OBJECT_SYNCCONTEXT) { DEBUG(5, (" object not found or not a synccontext\n")); mapi_repl->error_code = MAPI_E_INVALID_OBJECT; goto end; } request = &mapi_req->u.mapi_SyncImportMessageMove; /* FIXME: we consider the local replica to always have id 1. This is correct for now but might pose problems if the local replica handling changes. */ owner = emsmdbp_get_owner(synccontext_object); emsmdbp_replid_to_guid(emsmdbp_ctx, owner, 1, &replica_guid); if (!convertIdToFMID(&replica_guid, request->SourceFolderId, request->SourceFolderIdSize, &sourceFID)) { mapi_repl->error_code = MAPI_E_NOT_FOUND; goto end; } if (!convertIdToFMID(&replica_guid, request->SourceMessageId, request->SourceMessageIdSize, &sourceMID)) { mapi_repl->error_code = MAPI_E_NOT_FOUND; goto end; } if (!convertIdToFMID(&replica_guid, request->DestinationMessageId, request->DestinationMessageIdSize, &destMID)) { mapi_repl->error_code = MAPI_E_NOT_FOUND; goto end; } if (emsmdbp_object_open_folder_by_fid(NULL, emsmdbp_ctx, synccontext_object, sourceFID, &source_folder_object) != MAPISTORE_SUCCESS) { mapi_repl->error_code = MAPI_E_NOT_FOUND; goto end; } contextID = emsmdbp_get_contextID(synccontext_object); mapistore = emsmdbp_is_mapistore(synccontext_object) && emsmdbp_is_mapistore(source_folder_object); change_key = talloc_zero(mem_ctx, struct Binary_r); change_key->cb = request->ChangeNumberSize; change_key->lpb = request->ChangeNumber; if (mapistore) { /* We invoke the backend method */ mapistore_folder_move_copy_messages(emsmdbp_ctx->mstore_ctx, contextID, synccontext_object->parent_object->backend_object, source_folder_object->backend_object, mem_ctx, 1, &sourceMID, &destMID, &change_key, false); } else { DEBUG(0, ("["__location__"] - mapistore support not implemented yet - shouldn't occur\n")); mapi_repl->error_code = MAPI_E_NO_SUPPORT; } talloc_free(source_folder_object); response = &mapi_repl->u.mapi_SyncImportMessageMove; response->MessageId = 0; end: *size += libmapiserver_RopSyncImportMessageMove_size(mapi_repl); return MAPI_E_SUCCESS; } /** \details EcDoRpc EcDoRpc_RopSyncOpenCollector (0x7e) Rop. \param mem_ctx pointer to the memory context \param emsmdbp_ctx pointer to the emsmdb provider context \param mapi_req pointer to the SyncOpenCollector EcDoRpc_MAPI_REQ structure \param mapi_repl pointer to the SyncOpenCollector EcDoRpc_MAPI_REPL structure \param handles pointer to the MAPI handles array \param size pointer to the mapi_response size to update \return MAPI_E_SUCCESS on success, otherwise MAPI error */ _PUBLIC_ enum MAPISTATUS EcDoRpc_RopSyncOpenCollector(TALLOC_CTX *mem_ctx, struct emsmdbp_context *emsmdbp_ctx, struct EcDoRpc_MAPI_REQ *mapi_req, struct EcDoRpc_MAPI_REPL *mapi_repl, uint32_t *handles, uint16_t *size) { uint32_t folder_handle; struct mapi_handles *folder_rec; struct mapi_handles *synccontext_rec; struct emsmdbp_object *folder_object; struct emsmdbp_object *synccontext_object; enum MAPISTATUS retval; void *data = NULL; DEBUG(4, ("exchange_emsmdb: [OXCFXICS] RopSyncOpenCollector (0x7e)\n")); /* Sanity checks */ OPENCHANGE_RETVAL_IF(!emsmdbp_ctx, MAPI_E_NOT_INITIALIZED, NULL); OPENCHANGE_RETVAL_IF(!mapi_req, MAPI_E_INVALID_PARAMETER, NULL); OPENCHANGE_RETVAL_IF(!mapi_repl, MAPI_E_INVALID_PARAMETER, NULL); OPENCHANGE_RETVAL_IF(!handles, MAPI_E_INVALID_PARAMETER, NULL); OPENCHANGE_RETVAL_IF(!size, MAPI_E_INVALID_PARAMETER, NULL); mapi_repl->opnum = mapi_req->opnum; mapi_repl->error_code = MAPI_E_SUCCESS; mapi_repl->handle_idx = mapi_req->u.mapi_SyncOpenCollector.handle_idx; folder_handle = handles[mapi_req->handle_idx]; retval = mapi_handles_search(emsmdbp_ctx->handles_ctx, folder_handle, &folder_rec); if (retval) { DEBUG(5, (" handle (%x) not found: %x\n", folder_handle, mapi_req->handle_idx)); mapi_repl->error_code = MAPI_E_INVALID_OBJECT; goto end; } mapi_handles_get_private_data(folder_rec, &data); folder_object = (struct emsmdbp_object *)data; if (!folder_object || folder_object->type != EMSMDBP_OBJECT_FOLDER) { DEBUG(5, (" object not found or not a folder\n")); mapi_repl->error_code = MAPI_E_INVALID_OBJECT; goto end; } retval = mapi_handles_add(emsmdbp_ctx->handles_ctx, folder_handle, &synccontext_rec); synccontext_object = emsmdbp_object_synccontext_init((TALLOC_CTX *)synccontext_rec, emsmdbp_ctx, folder_object); synccontext_object->object.synccontext->request.is_collector = true; talloc_steal(synccontext_rec, synccontext_object); retval = mapi_handles_set_private_data(synccontext_rec, synccontext_object); synccontext_object->object.synccontext->request.contents_mode = (mapi_req->u.mapi_SyncOpenCollector.IsContentsCollector != 0); handles[mapi_repl->handle_idx] = synccontext_rec->handle; end: *size += libmapiserver_RopSyncOpenCollector_size(mapi_repl); return MAPI_E_SUCCESS; } /** \details EcDoRpc EcDoRpc_RopGetLocalReplicaIds (0x7f) Rop. This operation reserves a range of IDs to be used by a local replica. \param mem_ctx pointer to the memory context \param emsmdbp_ctx pointer to the emsmdb provider context \param mapi_req pointer to the GetLocalReplicaIds EcDoRpc_MAPI_REQ structure \param mapi_repl pointer to the GetLocalReplicaIds EcDoRpc_MAPI_REPL structure \param handles pointer to the MAPI handles array \param size pointer to the mapi_response size to update \return MAPI_E_SUCCESS on success, otherwise MAPI error */ _PUBLIC_ enum MAPISTATUS EcDoRpc_RopGetLocalReplicaIds(TALLOC_CTX *mem_ctx, struct emsmdbp_context *emsmdbp_ctx, struct EcDoRpc_MAPI_REQ *mapi_req, struct EcDoRpc_MAPI_REPL *mapi_repl, uint32_t *handles, uint16_t *size) { struct GetLocalReplicaIds_req *request; struct mapi_handles *object_handle; uint32_t handle_id; uint64_t new_id; uint8_t i; void *data; int retval; struct emsmdbp_object *mailbox_object; DEBUG(4, ("exchange_emsmdb: [OXCFXICS] RopGetLocalReplicaIds (0x7f)\n")); /* Sanity checks */ OPENCHANGE_RETVAL_IF(!emsmdbp_ctx, MAPI_E_NOT_INITIALIZED, NULL); OPENCHANGE_RETVAL_IF(!mapi_req, MAPI_E_INVALID_PARAMETER, NULL); OPENCHANGE_RETVAL_IF(!mapi_repl, MAPI_E_INVALID_PARAMETER, NULL); OPENCHANGE_RETVAL_IF(!handles, MAPI_E_INVALID_PARAMETER, NULL); OPENCHANGE_RETVAL_IF(!size, MAPI_E_INVALID_PARAMETER, NULL); mapi_repl->opnum = mapi_req->opnum; mapi_repl->error_code = MAPI_E_SUCCESS; mapi_repl->handle_idx = mapi_req->handle_idx; /* Step 1. Retrieve object handle */ handle_id = handles[mapi_req->handle_idx]; retval = mapi_handles_search(emsmdbp_ctx->handles_ctx, handle_id, &object_handle); if (retval) { mapi_repl->error_code = MAPI_E_INVALID_OBJECT; DEBUG(5, (" handle (%x) not found: %x\n", handle_id, mapi_req->handle_idx)); goto end; } /* Step 2. Check whether the parent object supports fetching properties */ mapi_handles_get_private_data(object_handle, &data); mailbox_object = (struct emsmdbp_object *) data; if (!mailbox_object || mailbox_object->type != EMSMDBP_OBJECT_MAILBOX) { DEBUG(5, (" object not found or not a folder\n")); mapi_repl->error_code = MAPI_E_INVALID_OBJECT; goto end; } request = &mapi_req->u.mapi_GetLocalReplicaIds; emsmdbp_replid_to_guid(emsmdbp_ctx, mailbox_object->object.mailbox->owner_username, 0x0001, &mapi_repl->u.mapi_GetLocalReplicaIds.ReplGuid); openchangedb_reserve_fmid_range(emsmdbp_ctx->oc_ctx, request->IdCount, &new_id); new_id >>= 16; for (i = 0; i < 6 ; i++) { mapi_repl->u.mapi_GetLocalReplicaIds.GlobalCount[i] = new_id & 0xff; new_id >>= 8; } end: *size += libmapiserver_RopGetLocalReplicaIds_size(mapi_repl); return MAPI_E_SUCCESS; } /** \details Retrieve a MessageReadState structure from a binary blob \param mem_ctx pointer to the memory context \param bin pointer to the Binary_r structure with raw MessageReadState data \return Allocated MessageReadState structure on success, otherwise NULL \note Developers must free the allocated MessageReadState when finished. */ static struct MessageReadState *get_MessageReadState(TALLOC_CTX *mem_ctx, struct Binary_r *bin) { struct MessageReadState *message_read_states = NULL; struct ndr_pull *ndr; enum ndr_err_code ndr_err_code; /* Sanity checks */ if (!bin) return NULL; if (!bin->cb) return NULL; if (!bin->lpb) return NULL; ndr = talloc_zero(mem_ctx, struct ndr_pull); ndr->offset = 0; ndr->data = bin->lpb; ndr->data_size = bin->cb; ndr_set_flags(&ndr->flags, LIBNDR_FLAG_NOALIGN); message_read_states = talloc_zero(mem_ctx, struct MessageReadState); ndr_err_code = ndr_pull_MessageReadState(ndr, NDR_SCALARS, message_read_states); /* talloc_free(ndr); */ if (ndr_err_code != NDR_ERR_SUCCESS) { talloc_free(message_read_states); return NULL; } return message_read_states; } /** \details EcDoRpc SyncImportReadStateChanges (0x80) Rop. \param mem_ctx pointer to the memory context \param emsmdbp_ctx pointer to the emsmdb provider context \param mapi_req pointer to the SyncImportReadStateChanges EcDoRpc_MAPI_REQ \param mapi_repl pointer to the SyncImportReadStateChanges EcDoRpc_MAPI_REPL \param handles pointer to the MAPI handles array \param size pointer to the mapi_response size to update \return MAPI_E_SUCCESS on success, otherwise MAPI error */ _PUBLIC_ enum MAPISTATUS EcDoRpc_RopSyncImportReadStateChanges(TALLOC_CTX *mem_ctx, struct emsmdbp_context *emsmdbp_ctx, struct EcDoRpc_MAPI_REQ *mapi_req, struct EcDoRpc_MAPI_REPL *mapi_repl, uint32_t *handles, uint16_t *size) { struct SyncImportReadStateChanges_req *request; uint32_t contextID, synccontext_handle; void *data; struct mapi_handles *synccontext_rec; struct emsmdbp_object *synccontext_object, *folder_object, *message_object; enum MAPISTATUS retval; enum mapistore_error ret; struct MessageReadState *read_states; uint32_t read_states_size; struct Binary_r *bin_data; char *owner; uint64_t mid, base; uint16_t replid; int i; struct mapistore_message *msg; struct GUID guid; DATA_BLOB guid_blob = { .length = 16, .data = NULL }; uint8_t flag; DEBUG(4, ("exchange_emsmdb: [OXCSTOR] SyncImportReadStateChanges (0x80)\n")); /* Sanity checks */ OPENCHANGE_RETVAL_IF(!emsmdbp_ctx, MAPI_E_NOT_INITIALIZED, NULL); OPENCHANGE_RETVAL_IF(!mapi_req, MAPI_E_INVALID_PARAMETER, NULL); OPENCHANGE_RETVAL_IF(!mapi_repl, MAPI_E_INVALID_PARAMETER, NULL); OPENCHANGE_RETVAL_IF(!handles, MAPI_E_INVALID_PARAMETER, NULL); OPENCHANGE_RETVAL_IF(!size, MAPI_E_INVALID_PARAMETER, NULL); mapi_repl->opnum = mapi_req->opnum; mapi_repl->handle_idx = mapi_req->handle_idx; mapi_repl->error_code = MAPI_E_SUCCESS; /* Step 1. Retrieve object handle */ synccontext_handle = handles[mapi_req->handle_idx]; retval = mapi_handles_search(emsmdbp_ctx->handles_ctx, synccontext_handle, &synccontext_rec); if (retval) { mapi_repl->error_code = MAPI_E_INVALID_OBJECT; DEBUG(5, (" handle (%x) not found: %x\n", synccontext_handle, mapi_req->handle_idx)); goto end; } mapi_handles_get_private_data(synccontext_rec, &data); synccontext_object = (struct emsmdbp_object *) data; if (!synccontext_object || synccontext_object->type != EMSMDBP_OBJECT_SYNCCONTEXT) { DEBUG(5, (" object not found or not a synccontext\n")); mapi_repl->error_code = MAPI_E_INVALID_OBJECT; goto end; } request = &mapi_req->u.mapi_SyncImportReadStateChanges; folder_object = synccontext_object->parent_object; if (emsmdbp_is_mapistore(folder_object)) { contextID = emsmdbp_get_contextID(folder_object); bin_data = talloc_zero(mem_ctx, struct Binary_r); bin_data->cb = request->MessageReadStates.length; bin_data->lpb = request->MessageReadStates.data; while (bin_data->cb) { read_states = get_MessageReadState(mem_ctx, bin_data); read_states_size = read_states->MessageIdSize + 3; bin_data->cb -= read_states_size; bin_data->lpb += read_states_size; guid_blob.data = read_states->MessageId; if (GUID_from_data_blob(&guid_blob, &guid).v != 0) { continue; } owner = emsmdbp_get_owner(synccontext_object); if (emsmdbp_guid_to_replid(emsmdbp_ctx, owner, &guid, &replid)) { continue; } mid = 0; base = 1; for (i = 16; i < read_states->MessageIdSize; i++) { mid |= (uint64_t) read_states->MessageId[i] * base; base <<= 8; } mid <<= 16; mid |= replid; if (read_states->MarkAsRead) { flag = SUPPRESS_RECEIPT | CLEAR_RN_PENDING; } else { flag = CLEAR_READ_FLAG | CLEAR_NRN_PENDING; } ret = emsmdbp_object_message_open(NULL, emsmdbp_ctx, folder_object, folder_object->object.folder->folderID, mid, true, &message_object, &msg); if (ret == MAPISTORE_SUCCESS) { mapistore_message_set_read_flag(emsmdbp_ctx->mstore_ctx, contextID, message_object->backend_object, flag); talloc_free(message_object); } } } else { DEBUG(0, (__location__ ": operation not supported on non-mapistore objects\n")); } end: *size += libmapiserver_RopSyncImportReadStateChanges_size(mapi_repl); handles[mapi_repl->handle_idx] = handles[mapi_req->handle_idx]; return MAPI_E_SUCCESS; } static void oxcfxics_fill_transfer_state_arrays(TALLOC_CTX *mem_ctx, struct emsmdbp_context *emsmdbp_ctx, struct emsmdbp_object_synccontext *synccontext, const char *owner, struct oxcfxics_sync_data *sync_data, struct emsmdbp_object *folder_object) { struct SPropTagArray *count_query_props; uint64_t eid, cn; uint32_t i, nr_eid; void **data_pointers; enum MAPISTATUS *retvals; struct emsmdbp_object *table_object, *subfolder_object; struct emsmdbp_object_table *table; uint32_t unix_time; struct FILETIME *lm_time; NTTIME nt_time; void *local_mem_ctx; struct GUID replica_guid; local_mem_ctx = talloc_zero(NULL, void); /* Query the amount of rows and update sync_data structure */ count_query_props = talloc_zero(local_mem_ctx, struct SPropTagArray); count_query_props->cValues = 1; count_query_props->aulPropTag = talloc_zero(count_query_props, enum MAPITAGS); switch (sync_data->table_type) { case MAPISTORE_FOLDER_TABLE: count_query_props->aulPropTag[0] = PidTagFolderChildCount; break; case MAPISTORE_MESSAGE_TABLE: count_query_props->aulPropTag[0] = PidTagContentCount; break; case MAPISTORE_FAI_TABLE: count_query_props->aulPropTag[0] = PidTagAssociatedContentCount; break; default: abort(); } data_pointers = emsmdbp_object_get_properties(local_mem_ctx, emsmdbp_ctx, folder_object, count_query_props, (enum MAPISTATUS **) &retvals); if (data_pointers && !retvals[0]) { nr_eid = *(uint32_t *) data_pointers[0]; } else { DEBUG(5, ("could not retrieve number of rows in table\n")); abort(); } if (!nr_eid) { return; } /* Fetch the actual table data */ table_object = emsmdbp_folder_open_table(local_mem_ctx, folder_object, sync_data->table_type, 0); if (!table_object) { DEBUG(5, ("could not open folder table\n")); abort(); } table_object->object.table->prop_count = synccontext->properties.cValues; table_object->object.table->properties = synccontext->properties.aulPropTag; if (emsmdbp_is_mapistore(table_object)) { mapistore_table_set_columns(emsmdbp_ctx->mstore_ctx, emsmdbp_get_contextID(table_object), table_object->backend_object, synccontext->properties.cValues, synccontext->properties.aulPropTag); } table = table_object->object.table; for (i = 0; i < table->denominator; i++) { data_pointers = emsmdbp_object_table_get_row_props(NULL, emsmdbp_ctx, table_object, i, MAPISTORE_PREFILTERED_QUERY, &retvals); if (data_pointers) { eid = *(uint64_t *) data_pointers[0]; emsmdbp_replid_to_guid(emsmdbp_ctx, owner, eid & 0xffff, &replica_guid); RAWIDSET_push_guid_glob(sync_data->eid_set, &replica_guid, (eid >> 16) & 0x0000ffffffffffff); if (retvals[1]) { unix_time = oc_version_time; } else { lm_time = (struct FILETIME *) data_pointers[1]; nt_time = ((uint64_t) lm_time->dwHighDateTime << 32) | lm_time->dwLowDateTime; unix_time = nt_time_to_unix(nt_time); } if (unix_time < oc_version_time) { unix_time = oc_version_time; } if (retvals[sync_data->prop_index.change_number]) { DEBUG(5, (__location__": mandatory property PidTagChangeNumber not returned for message\n")); abort(); } cn = ((*(uint64_t *) data_pointers[sync_data->prop_index.change_number]) >> 16) & 0x0000ffffffffffff; RAWIDSET_push_guid_glob(sync_data->cnset_seen, &sync_data->replica_guid, cn); talloc_free(retvals); talloc_free(data_pointers); if (sync_data->table_type == MAPISTORE_FOLDER_TABLE) { /* TODO: check return code */ emsmdbp_object_open_folder(local_mem_ctx, emsmdbp_ctx, folder_object, eid, &subfolder_object); oxcfxics_fill_transfer_state_arrays(mem_ctx, emsmdbp_ctx, synccontext, owner, sync_data, subfolder_object); talloc_free(subfolder_object); } } } talloc_free(local_mem_ctx); } static void oxcfxics_ndr_push_transfer_state(struct ndr_push *ndr, const char *owner, struct emsmdbp_object *synccontext_object) { void *mem_ctx; struct idset *new_idset, *old_idset; struct oxcfxics_sync_data *sync_data; struct emsmdbp_context *emsmdbp_ctx; struct emsmdbp_object_synccontext *synccontext; emsmdbp_ctx = synccontext_object->emsmdbp_ctx; synccontext = synccontext_object->object.synccontext; ndr_push_uint32(ndr, NDR_SCALARS, PidTagIncrSyncStateBegin); mem_ctx = talloc_zero(NULL, void); sync_data = talloc_zero(mem_ctx, struct oxcfxics_sync_data); openchangedb_get_MailboxReplica(emsmdbp_ctx->oc_ctx, owner, NULL, &sync_data->replica_guid); sync_data->prop_index.eid = 0; sync_data->prop_index.change_number = 1; synccontext->properties.cValues = 2; synccontext->properties.aulPropTag = talloc_array(synccontext, enum MAPITAGS, 2); synccontext->properties.aulPropTag[1] = PidTagChangeNumber; sync_data->ndr = ndr; sync_data->cutmarks_ndr = ndr_push_init_ctx(sync_data); ndr_set_flags(&sync_data->cutmarks_ndr->flags, LIBNDR_FLAG_NOALIGN); sync_data->cutmarks_ndr->offset = 0; sync_data->cnset_seen = RAWIDSET_make(sync_data, false, true); sync_data->eid_set = RAWIDSET_make(sync_data, false, false); if (synccontext->request.contents_mode) { synccontext->properties.aulPropTag[0] = PidTagMid; if (synccontext->request.normal) { sync_data->table_type = MAPISTORE_MESSAGE_TABLE; oxcfxics_fill_transfer_state_arrays(mem_ctx, emsmdbp_ctx, synccontext, owner, sync_data, synccontext_object->parent_object); } if (synccontext->request.fai) { sync_data->table_type = MAPISTORE_FAI_TABLE; oxcfxics_fill_transfer_state_arrays(mem_ctx, emsmdbp_ctx, synccontext, owner, sync_data, synccontext_object->parent_object); } } else { synccontext->properties.aulPropTag[0] = PidTagFolderId; sync_data->table_type = MAPISTORE_FOLDER_TABLE; oxcfxics_fill_transfer_state_arrays(mem_ctx, emsmdbp_ctx, synccontext, owner, sync_data, synccontext_object->parent_object); } /* for some reason, Exchange returns the same range for PidTagCnsetSeen, PidTagCnsetSeenFAI and PidTagCnsetRead */ new_idset = RAWIDSET_convert_to_idset(NULL, sync_data->cnset_seen); old_idset = synccontext->cnset_seen; synccontext->cnset_seen = IDSET_merge_idsets(synccontext, old_idset, new_idset); oxcfxics_check_cnset(emsmdbp_ctx->oc_ctx, synccontext->cnset_seen, "cnset_seen"); talloc_free(old_idset); talloc_free(new_idset); ndr_push_uint32(ndr, NDR_SCALARS, PidTagCnsetSeen); ndr_push_idset(ndr, synccontext->cnset_seen); if (synccontext->request.contents_mode && synccontext->request.fai) { ndr_push_uint32(ndr, NDR_SCALARS, PidTagCnsetSeenFAI); ndr_push_idset(ndr, synccontext->cnset_seen); } new_idset = RAWIDSET_convert_to_idset(NULL, sync_data->eid_set); old_idset = synccontext->idset_given; synccontext->idset_given = IDSET_merge_idsets(synccontext, old_idset, new_idset); talloc_free(old_idset); talloc_free(new_idset); ndr_push_uint32(ndr, NDR_SCALARS, PidTagIdsetGiven); ndr_push_idset(ndr, synccontext->idset_given); if (synccontext->request.contents_mode && synccontext->request.read_state) { ndr_push_uint32(ndr, NDR_SCALARS, PidTagCnsetRead); ndr_push_idset(ndr, synccontext->cnset_seen); } talloc_free(mem_ctx); ndr_push_uint32(ndr, NDR_SCALARS, PidTagIncrSyncStateEnd); } /** \details EcDoRpc EcDoRpc_RopSyncGetTransferState (0x82) Rop. \param mem_ctx pointer to the memory context \param emsmdbp_ctx pointer to the emsmdb provider context \param mapi_req pointer to the SyncGetTransferState EcDoRpc_MAPI_REQ structure \param mapi_repl pointer to the SyncGetTransferState EcDoRpc_MAPI_REPL structure \param handles pointer to the MAPI handles array \param size pointer to the mapi_response size to update \return MAPI_E_SUCCESS on success, otherwise MAPI error */ _PUBLIC_ enum MAPISTATUS EcDoRpc_RopSyncGetTransferState(TALLOC_CTX *mem_ctx, struct emsmdbp_context *emsmdbp_ctx, struct EcDoRpc_MAPI_REQ *mapi_req, struct EcDoRpc_MAPI_REPL *mapi_repl, uint32_t *handles, uint16_t *size) { uint32_t synccontext_handle_id; struct mapi_handles *synccontext_handle, *ftcontext_handle; struct emsmdbp_object *synccontext_object, *ftcontext_object; struct emsmdbp_object_ftcontext *ftcontext; enum MAPISTATUS retval; void *data = NULL; struct ndr_push *ndr; char *owner; DEBUG(4, ("exchange_emsmdb: [OXCFXICS] RopSyncGetTransferState (0x82)\n")); /* Sanity checks */ OPENCHANGE_RETVAL_IF(!emsmdbp_ctx, MAPI_E_NOT_INITIALIZED, NULL); OPENCHANGE_RETVAL_IF(!mapi_req, MAPI_E_INVALID_PARAMETER, NULL); OPENCHANGE_RETVAL_IF(!mapi_repl, MAPI_E_INVALID_PARAMETER, NULL); OPENCHANGE_RETVAL_IF(!handles, MAPI_E_INVALID_PARAMETER, NULL); OPENCHANGE_RETVAL_IF(!size, MAPI_E_INVALID_PARAMETER, NULL); mapi_repl->opnum = mapi_req->opnum; mapi_repl->error_code = MAPI_E_SUCCESS; mapi_repl->handle_idx = mapi_req->u.mapi_SyncGetTransferState.handle_idx; synccontext_handle_id = handles[mapi_req->handle_idx]; retval = mapi_handles_search(emsmdbp_ctx->handles_ctx, synccontext_handle_id, &synccontext_handle); if (retval) { DEBUG(5, (" handle (%x) not found: %x\n", synccontext_handle_id, mapi_req->handle_idx)); mapi_repl->error_code = MAPI_E_INVALID_OBJECT; goto end; } mapi_handles_get_private_data(synccontext_handle, &data); synccontext_object = (struct emsmdbp_object *)data; if (!synccontext_object || synccontext_object->type != EMSMDBP_OBJECT_SYNCCONTEXT) { DEBUG(5, (" object not found or not a synccontext\n")); mapi_repl->error_code = MAPI_E_INVALID_OBJECT; goto end; } ndr = ndr_push_init_ctx(NULL); ndr_set_flags(&ndr->flags, LIBNDR_FLAG_NOALIGN); ndr->offset = 0; owner = emsmdbp_get_owner(synccontext_object); oxcfxics_ndr_push_transfer_state(ndr, owner, synccontext_object); retval = mapi_handles_add(emsmdbp_ctx->handles_ctx, synccontext_handle_id, &ftcontext_handle); ftcontext_object = emsmdbp_object_ftcontext_init((TALLOC_CTX *)ftcontext_handle, emsmdbp_ctx, synccontext_object); mapi_handles_set_private_data(ftcontext_handle, ftcontext_object); handles[mapi_repl->handle_idx] = ftcontext_handle->handle; ftcontext = ftcontext_object->object.ftcontext; (void) talloc_reference(ftcontext, ndr->data); ftcontext->stream.buffer.data = ndr->data; ftcontext->stream.buffer.length = ndr->offset; talloc_free(ndr); /* cutmarks */ ndr = ndr_push_init_ctx(ftcontext); ndr_set_flags(&ndr->flags, LIBNDR_FLAG_NOALIGN); ndr->offset = 0; ndr_push_uint32(ndr, NDR_SCALARS, 0); ndr_push_uint32(ndr, NDR_SCALARS, 0xffffffff); ftcontext->cutmarks = (uint32_t *) ndr->data; (void) talloc_reference(ftcontext, ndr->data); talloc_free(ndr); end: *size += libmapiserver_RopSyncGetTransferState_size(mapi_repl); return MAPI_E_SUCCESS; } /** \details EcDoRpc SetLocalReplicaMidsetDeleted (0x93) Rop. \param mem_ctx pointer to the memory context \param emsmdbp_ctx pointer to the emsmdb provider context \param mapi_req pointer to the SetLocalReplicaMidsetDeleted EcDoRpc_MAPI_REQ \param mapi_repl pointer to the SetLocalReplicaMidsetDeleted EcDoRpc_MAPI_REPL \param handles pointer to the MAPI handles array \param size pointer to the mapi_response size to update \return MAPI_E_SUCCESS on success, otherwise MAPI error */ _PUBLIC_ enum MAPISTATUS EcDoRpc_RopSetLocalReplicaMidsetDeleted(TALLOC_CTX *mem_ctx, struct emsmdbp_context *emsmdbp_ctx, struct EcDoRpc_MAPI_REQ *mapi_req, struct EcDoRpc_MAPI_REPL *mapi_repl, uint32_t *handles, uint16_t *size) { DEBUG(4, ("exchange_emsmdb: [OXCSTOR] SetLocalReplicaMidsetDeleted (0x93) - stub\n")); /* Sanity checks */ OPENCHANGE_RETVAL_IF(!emsmdbp_ctx, MAPI_E_NOT_INITIALIZED, NULL); OPENCHANGE_RETVAL_IF(!mapi_req, MAPI_E_INVALID_PARAMETER, NULL); OPENCHANGE_RETVAL_IF(!mapi_repl, MAPI_E_INVALID_PARAMETER, NULL); OPENCHANGE_RETVAL_IF(!handles, MAPI_E_INVALID_PARAMETER, NULL); OPENCHANGE_RETVAL_IF(!size, MAPI_E_INVALID_PARAMETER, NULL); mapi_repl->opnum = mapi_req->opnum; mapi_repl->handle_idx = mapi_req->handle_idx; mapi_repl->error_code = MAPI_E_SUCCESS; /* TODO effective work here */ *size += libmapiserver_RopSetLocalReplicaMidsetDeleted_size(mapi_repl); handles[mapi_repl->handle_idx] = handles[mapi_req->handle_idx]; return MAPI_E_SUCCESS; } openchange-2.0/mapiproxy/servers/default/emsmdb/oxcmsg.c000066400000000000000000001632211223057412600235510ustar00rootroot00000000000000/* OpenChange Server implementation EMSMDBP: EMSMDB Provider implementation Copyright (C) Julien Kerihuel 2009-2013 This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see . */ /** \file oxcmsg.c \brief Message and Attachment object routines and Rops */ #include #include "mapiproxy/dcesrv_mapiproxy.h" #include "mapiproxy/libmapiproxy/libmapiproxy.h" #include "mapiproxy/libmapiserver/libmapiserver.h" #include "dcesrv_exchange_emsmdb.h" struct oxcmsg_prop_index { uint32_t display_name; /* PR_DISPLAY_NAME_UNICODE or PR_7BIT_DISPLAY_NAME_UNICODE or PR_RECIPIENT_DISPLAY_NAME_UNICODE */ uint32_t email_address; /* PR_EMAIL_ADDRESS_UNICODE or PR_SMTP_ADDRESS_UNICODE */ }; static inline void oxcmsg_fill_prop_index(struct oxcmsg_prop_index *prop_index, struct SPropTagArray *properties) { if (SPropTagArray_find(*properties, PR_DISPLAY_NAME_UNICODE, &prop_index->display_name) == MAPI_E_NOT_FOUND && SPropTagArray_find(*properties, PR_7BIT_DISPLAY_NAME_UNICODE, &prop_index->display_name) == MAPI_E_NOT_FOUND && SPropTagArray_find(*properties, PR_RECIPIENT_DISPLAY_NAME_UNICODE, &prop_index->display_name) == MAPI_E_NOT_FOUND) { prop_index->display_name = (uint32_t) -1;; } if (SPropTagArray_find(*properties, PR_EMAIL_ADDRESS_UNICODE, &prop_index->email_address) == MAPI_E_NOT_FOUND && SPropTagArray_find(*properties, PR_SMTP_ADDRESS_UNICODE, &prop_index->email_address) == MAPI_E_NOT_FOUND) { prop_index->email_address = (uint32_t) -1;; } } static void oxcmsg_fill_RecipientRow(TALLOC_CTX *mem_ctx, struct emsmdbp_context *emsmdbp_ctx, struct RecipientRow *row, struct mapistore_message_recipient *recipient, struct oxcmsg_prop_index *prop_index) { struct ldb_result *res = NULL; const char * const recipient_attrs[] = { "*", NULL }; int ret; char *full_name, *email_address, *simple_name, *legacyExchangeDN; if (!recipient->username) { goto smtp_recipient; } ret = ldb_search(emsmdbp_ctx->samdb_ctx, emsmdbp_ctx, &res, ldb_get_default_basedn(emsmdbp_ctx->samdb_ctx), LDB_SCOPE_SUBTREE, recipient_attrs, "(&(objectClass=user)(sAMAccountName=*%s*)(!(objectClass=computer)))", recipient->username); /* If the search failed, build an external recipient: very basic for the moment */ if (ret != LDB_SUCCESS || !res->count) { DEBUG(0, ("record not found for %s\n", recipient->username)); goto smtp_recipient; } full_name = (char *) ldb_msg_find_attr_as_string(res->msgs[0], "displayName", NULL); if (!full_name) { DEBUG(0, ("record found but displayName is missing for %s\n", recipient->username)); goto smtp_recipient; } simple_name = (char *) ldb_msg_find_attr_as_string(res->msgs[0], "mailNickname", NULL); if (!simple_name) { DEBUG(0, ("record found but mailNickname is missing for %s\n", recipient->username)); goto smtp_recipient; } legacyExchangeDN = (char *) ldb_msg_find_attr_as_string(res->msgs[0], "legacyExchangeDN", NULL); if (!legacyExchangeDN) { DEBUG(0, ("record found but legacyExchangeDN is missing for %s\n", recipient->username)); goto smtp_recipient; } row->RecipientFlags = 0x06d1; row->AddressPrefixUsed.prefix_size = strlen(legacyExchangeDN) - strlen(recipient->username); row->DisplayType.display_type = SINGLE_RECIPIENT; row->X500DN.recipient_x500name = talloc_strdup(mem_ctx, recipient->username); row->DisplayName.lpszW = talloc_strdup(mem_ctx, full_name); row->SimpleDisplayName.lpszW = talloc_strdup(mem_ctx, simple_name); return; smtp_recipient: row->RecipientFlags = 0x303; /* type = SMTP, no rich text, unicode */ row->RecipientFlags |= 0x80; /* from doc: a different transport is responsible for delivery to this recipient. */ if (prop_index->display_name != (uint32_t) -1) { full_name = recipient->data[prop_index->display_name]; if (full_name) { row->RecipientFlags |= 0x10; row->DisplayName.lpszW = talloc_strdup(mem_ctx, full_name); row->RecipientFlags |= 0x0400; row->SimpleDisplayName.lpszW = row->DisplayName.lpszW; } } if (prop_index->email_address != (uint32_t) -1) { email_address = recipient->data[prop_index->email_address]; if (email_address) { row->RecipientFlags |= 0x08; row->EmailAddress.lpszW = talloc_strdup(mem_ctx, email_address); } } } static void oxcmsg_fill_RecipientRow_data(TALLOC_CTX *mem_ctx, struct emsmdbp_context *emsmdbp_ctx, struct RecipientRow *row, struct SPropTagArray *properties, struct mapistore_message_recipient *recipient) { uint32_t i, retval; void *data; enum MAPITAGS property; row->prop_count = properties->cValues; row->prop_values.length = 0; row->layout = 0; for (i = 0; i < properties->cValues; i++) { if (recipient->data[i] == NULL) { row->layout = 1; break; } } for (i = 0; i < properties->cValues; i++) { property = properties->aulPropTag[i]; data = recipient->data[i]; if (data == NULL) { retval = MAPI_E_NOT_FOUND; property = (property & 0xffff0000) + PT_ERROR; data = (void *)&retval; } libmapiserver_push_property(mem_ctx, property, (const void *)data, &row->prop_values, row->layout, 0, 0); } } static void oxcmsg_fill_OpenRecipientRow(TALLOC_CTX *mem_ctx, struct emsmdbp_context *emsmdbp_ctx, struct OpenRecipientRow *row, struct SPropTagArray *properties, struct mapistore_message_recipient *recipient, struct oxcmsg_prop_index *prop_index) { row->CodePageId = CP_USASCII; row->Reserved = 0; row->RecipientType = recipient->type; oxcmsg_fill_RecipientRow(mem_ctx, emsmdbp_ctx, &row->RecipientRow, recipient, prop_index); oxcmsg_fill_RecipientRow_data(mem_ctx, emsmdbp_ctx, &row->RecipientRow, properties, recipient); } /** \details EcDoRpc OpenMessage (0x03) Rop. This operation opens an existing message in a mailbox. \param mem_ctx pointer to the memory context \param emsmdbp_ctx pointer to the emsmdb provider context \param mapi_req pointer to the OpenMessage EcDoRpc_MAPI_REQ structure \param mapi_repl pointer to the OpenMessage EcDoRpc_MAPI_REPL structure \param handles pointer to the MAPI handles array \param size pointer to the mapi_response size to update \return MAPI_E_SUCCESS on success, otherwise MAPI error */ _PUBLIC_ enum MAPISTATUS EcDoRpc_RopOpenMessage(TALLOC_CTX *mem_ctx, struct emsmdbp_context *emsmdbp_ctx, struct EcDoRpc_MAPI_REQ *mapi_req, struct EcDoRpc_MAPI_REPL *mapi_repl, uint32_t *handles, uint16_t *size) { struct OpenMessage_req *request; struct OpenMessage_repl *response; enum mapistore_error ret; enum MAPISTATUS retval; uint32_t parent_handle_id; struct mapi_handles *object_handle = NULL; struct mapi_handles *context_object_handle = NULL; struct emsmdbp_object *object = NULL; struct emsmdbp_object *context_object = NULL; struct mapistore_message *msg; void *data; uint64_t folderID; uint64_t messageID = 0; struct oxcmsg_prop_index prop_index; int i; DEBUG(4, ("exchange_emsmdb: [OXCMSG] OpenMessage (0x03)\n")); /* Sanity checks */ OPENCHANGE_RETVAL_IF(!emsmdbp_ctx, MAPI_E_NOT_INITIALIZED, NULL); OPENCHANGE_RETVAL_IF(!mapi_req, MAPI_E_INVALID_PARAMETER, NULL); OPENCHANGE_RETVAL_IF(!mapi_repl, MAPI_E_INVALID_PARAMETER, NULL); OPENCHANGE_RETVAL_IF(!handles, MAPI_E_INVALID_PARAMETER, NULL); OPENCHANGE_RETVAL_IF(!size, MAPI_E_INVALID_PARAMETER, NULL); request = &mapi_req->u.mapi_OpenMessage; response = &mapi_repl->u.mapi_OpenMessage; mapi_repl->opnum = mapi_req->opnum; mapi_repl->error_code = MAPI_E_SUCCESS; mapi_repl->handle_idx = request->handle_idx; parent_handle_id = handles[mapi_req->handle_idx]; retval = mapi_handles_search(emsmdbp_ctx->handles_ctx, parent_handle_id, &context_object_handle); OPENCHANGE_RETVAL_IF(retval, retval, NULL); /* With OpenMessage, the parent object may NOT BE the direct parent folder of the message */ mapi_handles_get_private_data(context_object_handle, &data); context_object = (struct emsmdbp_object *)data; if (!context_object) { mapi_repl->error_code = MAPI_E_NOT_FOUND; *size += libmapiserver_RopOpenMessage_size(NULL); return MAPI_E_SUCCESS; } /* OpenMessage can only be called for mailbox/folder objects */ if (!(context_object->type == EMSMDBP_OBJECT_MAILBOX || context_object->type == EMSMDBP_OBJECT_FOLDER)) { mapi_repl->error_code = MAPI_E_INVALID_OBJECT; goto end; } messageID = request->MessageId; folderID = request->FolderId; /* Initialize Message object */ retval = mapi_handles_add(emsmdbp_ctx->handles_ctx, 0, &object_handle); if (request->OpenModeFlags == ReadOnly) { ret = emsmdbp_object_message_open(object_handle, emsmdbp_ctx, context_object, folderID, messageID, false, &object, &msg); } else if (request->OpenModeFlags == OpenSoftDelete) { ret = MAPISTORE_ERROR; } else { /* ReadWrite/BestAccess */ ret = emsmdbp_object_message_open(object_handle, emsmdbp_ctx, context_object, folderID, messageID, true, &object, &msg); if (ret == MAPISTORE_ERR_DENIED && request->OpenModeFlags == BestAccess) { ret = emsmdbp_object_message_open(object_handle, emsmdbp_ctx, context_object, folderID, messageID, false, &object, &msg); } } if (ret != MAPISTORE_SUCCESS) { mapi_handles_delete(emsmdbp_ctx->handles_ctx, object_handle->handle); if (ret == MAPISTORE_ERR_DENIED) { mapi_repl->error_code = MAPI_E_NO_ACCESS; } else if (ret == MAPISTORE_ERR_NOT_FOUND) { mapi_repl->error_code = MAPI_E_NOT_FOUND; } else { mapi_repl->error_code = MAPI_E_CALL_FAILED; } goto end; } handles[mapi_repl->handle_idx] = object_handle->handle; retval = mapi_handles_set_private_data(object_handle, object); /* Build the OpenMessage reply */ response->HasNamedProperties = true; if (msg->subject_prefix && strlen(msg->subject_prefix) > 0) { response->SubjectPrefix.StringType = StringType_UNICODE; response->SubjectPrefix.String.lpszW = talloc_strdup(mem_ctx, msg->subject_prefix); } else { response->SubjectPrefix.StringType = StringType_EMPTY; } if (msg->normalized_subject && strlen(msg->normalized_subject) > 0) { response->NormalizedSubject.StringType = StringType_UNICODE; response->NormalizedSubject.String.lpszW = talloc_strdup(mem_ctx, msg->normalized_subject); } else { response->NormalizedSubject.StringType = StringType_EMPTY; } if (msg->columns) { response->RecipientColumns.cValues = msg->columns->cValues; response->RecipientColumns.aulPropTag = msg->columns->aulPropTag; } else { response->RecipientColumns.cValues = 0; } response->RecipientCount = msg->recipients_count; response->RowCount = msg->recipients_count; if (msg->recipients_count > 0) { response->RecipientRows = talloc_array(mem_ctx, struct OpenRecipientRow, msg->recipients_count + 1); oxcmsg_fill_prop_index(&prop_index, msg->columns); for (i = 0; i < msg->recipients_count; i++) { oxcmsg_fill_OpenRecipientRow(mem_ctx, emsmdbp_ctx, &(response->RecipientRows[i]), msg->columns, msg->recipients + i, &prop_index); } } else { response->RecipientCount = 0; } response->RowCount = response->RecipientCount; end: *size += libmapiserver_RopOpenMessage_size(mapi_repl); return MAPI_E_SUCCESS; } /** \details EcDoRpc CreateMessage (0x06) Rop. This operation creates a message object in the mailbox. \param mem_ctx pointer to the memory context \param emsmdbp_ctx pointer to the emsmdb provider context \param mapi_req pointer to the CreateMessage EcDoRpc_MAPI_REQ structure \param mapi_repl pointer to the CreateMessage EcDoRpc_MAPI_REPL structure \param handles pointer to the MAPI handles array \param size pointer to the mapi_response size to update \return MAPI_E_SUCCESS on success, otherwise MAPI error */ _PUBLIC_ enum MAPISTATUS EcDoRpc_RopCreateMessage(TALLOC_CTX *mem_ctx, struct emsmdbp_context *emsmdbp_ctx, struct EcDoRpc_MAPI_REQ *mapi_req, struct EcDoRpc_MAPI_REPL *mapi_repl, uint32_t *handles, uint16_t *size) { enum MAPISTATUS retval; enum mapistore_error ret; struct mapi_handles *context_handle = NULL; struct mapi_handles *message_handle = NULL; struct emsmdbp_object *context_object = NULL; struct emsmdbp_object *folder_object = NULL; struct emsmdbp_object *message_object = NULL; uint32_t handle; uint64_t folderID, messageID; uint32_t contextID; bool mapistore = false; void *data; struct SRow aRow; uint32_t pt_long; bool pt_boolean; struct SBinary_short *pt_binary; struct timeval tv; struct FILETIME ft; NTTIME time; DEBUG(4, ("exchange_emsmdb: [OXCMSG] CreateMessage (0x06)\n")); /* Sanity checks */ OPENCHANGE_RETVAL_IF(!emsmdbp_ctx, MAPI_E_NOT_INITIALIZED, NULL); OPENCHANGE_RETVAL_IF(!mapi_req, MAPI_E_INVALID_PARAMETER, NULL); OPENCHANGE_RETVAL_IF(!mapi_repl, MAPI_E_INVALID_PARAMETER, NULL); OPENCHANGE_RETVAL_IF(!handles, MAPI_E_INVALID_PARAMETER, NULL); OPENCHANGE_RETVAL_IF(!size, MAPI_E_INVALID_PARAMETER, NULL); mapi_repl->opnum = mapi_req->opnum; mapi_repl->error_code = MAPI_E_SUCCESS; mapi_repl->handle_idx = mapi_req->u.mapi_CreateMessage.handle_idx; mapi_repl->u.mapi_CreateMessage.HasMessageId = 0; handle = handles[mapi_req->handle_idx]; retval = mapi_handles_search(emsmdbp_ctx->handles_ctx, handle, &context_handle); if (retval) { mapi_repl->error_code = MAPI_E_INVALID_OBJECT; DEBUG(5, (" handle (%x) not found: %x\n", handle, mapi_req->handle_idx)); goto end; } /* With CreateMessage, the parent object may NOT BE the direct parent folder of the message */ retval = mapi_handles_get_private_data(context_handle, &data); if (retval) { mapi_repl->error_code = retval; DEBUG(5, (" handle data not found, idx = %x\n", mapi_req->handle_idx)); goto end; } context_object = data; folderID = mapi_req->u.mapi_CreateMessage.FolderId; /* Step 1. Retrieve parent handle in the hierarchy */ ret = emsmdbp_object_open_folder_by_fid(mem_ctx, emsmdbp_ctx, context_object, folderID, &folder_object); if (ret != MAPISTORE_SUCCESS) { if (ret == MAPISTORE_ERR_DENIED) { mapi_repl->error_code = MAPI_E_NO_ACCESS; } else { mapi_repl->error_code = MAPI_E_NO_SUPPORT; } goto end; } /* This should be handled differently here: temporary hack */ retval = openchangedb_get_new_folderID(emsmdbp_ctx->oc_ctx, &messageID); if (retval) { mapi_repl->error_code = MAPI_E_NO_SUPPORT; goto end; } mapi_repl->u.mapi_CreateMessage.HasMessageId = 1; mapi_repl->u.mapi_CreateMessage.MessageId.MessageId = messageID; /* Initialize Message object */ handle = handles[mapi_req->handle_idx]; retval = mapi_handles_add(emsmdbp_ctx->handles_ctx, 0, &message_handle); message_object = emsmdbp_object_message_init((TALLOC_CTX *)message_handle, emsmdbp_ctx, messageID, folder_object); message_object->object.message->read_write = true; contextID = emsmdbp_get_contextID(folder_object); mapistore = emsmdbp_is_mapistore(folder_object); switch (mapistore) { case true: ret = mapistore_folder_create_message(emsmdbp_ctx->mstore_ctx, contextID, folder_object->backend_object, message_object, messageID, mapi_req->u.mapi_CreateMessage.AssociatedFlag, &message_object->backend_object); if (ret != MAPISTORE_SUCCESS) { if (ret == MAPISTORE_ERR_DENIED) { mapi_repl->error_code = MAPI_E_NO_ACCESS; } else if (ret == MAPISTORE_ERR_NOT_FOUND) { mapi_repl->error_code = MAPI_E_NOT_FOUND; } else { mapi_repl->error_code = MAPI_E_CALL_FAILED; } goto end; } break; case false: retval = openchangedb_message_create(emsmdbp_ctx->mstore_ctx, emsmdbp_ctx->oc_ctx, messageID, folderID, mapi_req->u.mapi_CreateMessage.AssociatedFlag, &message_object->backend_object); DEBUG(5, ("openchangedb_create_message returned 0x%.8x\n", retval)); break; } handles[mapi_repl->handle_idx] = message_handle->handle; /* Add default properties to message MS-OXCMSG 3.2.5.2 */ retval = mapi_handles_set_private_data(message_handle, message_object); /* Set default properties for message: MS-OXCMSG 3.2.5.2 */ aRow.ulAdrEntryPad = 0; aRow.lpProps = talloc_array(mem_ctx, struct SPropValue, 23); aRow.cValues = 0; pt_long = 0x1; set_SPropValue_proptag(aRow.lpProps + aRow.cValues, PR_IMPORTANCE, (const void *)&pt_long); aRow.cValues++; set_SPropValue_proptag(aRow.lpProps + aRow.cValues, PR_MESSAGE_CLASS_UNICODE, (const void *)"IPM.Note"); aRow.cValues++; pt_long = 0x0; set_SPropValue_proptag(aRow.lpProps + aRow.cValues, PR_SENSITIVITY, (const void *)&pt_long); aRow.cValues++; set_SPropValue_proptag(aRow.lpProps + aRow.cValues, PR_DISPLAY_TO_UNICODE, (const void *)""); aRow.cValues++; set_SPropValue_proptag(aRow.lpProps + aRow.cValues, PR_DISPLAY_CC_UNICODE, (const void *)""); aRow.cValues++; set_SPropValue_proptag(aRow.lpProps + aRow.cValues, PR_DISPLAY_BCC_UNICODE, (const void *)""); aRow.cValues++; pt_long = 0x9; set_SPropValue_proptag(aRow.lpProps + aRow.cValues, PR_MESSAGE_FLAGS, (const void *)&pt_long); aRow.cValues++; pt_boolean = false; set_SPropValue_proptag(aRow.lpProps + aRow.cValues, PR_HASATTACH, (const void *)&pt_boolean); aRow.cValues++; set_SPropValue_proptag(aRow.lpProps + aRow.cValues, PR_HAS_NAMED_PROPERTIES, (const void *)&pt_boolean); aRow.cValues++; set_SPropValue_proptag(aRow.lpProps + aRow.cValues, PR_URL_COMP_NAME_SET, (const void *)&pt_boolean); aRow.cValues++; pt_long = 0x1; set_SPropValue_proptag(aRow.lpProps + aRow.cValues, PR_TRUST_SENDER, (const void *)&pt_long); aRow.cValues++; pt_long = 0x3; set_SPropValue_proptag(aRow.lpProps + aRow.cValues, PR_ACCESS, (const void *)&pt_long); aRow.cValues++; pt_long = 0x1; set_SPropValue_proptag(aRow.lpProps + aRow.cValues, PR_ACCESS_LEVEL, (const void *)&pt_long); aRow.cValues++; set_SPropValue_proptag(aRow.lpProps + aRow.cValues, PR_URL_COMP_NAME_UNICODE, (const void *)"No Subject.EML"); aRow.cValues++; gettimeofday(&tv, NULL); time = timeval_to_nttime(&tv); ft.dwLowDateTime = (time << 32) >> 32; ft.dwHighDateTime = time >> 32; set_SPropValue_proptag(aRow.lpProps + aRow.cValues, PR_CREATION_TIME, (const void *)&ft); aRow.cValues++; set_SPropValue_proptag(aRow.lpProps + aRow.cValues, PR_LAST_MODIFICATION_TIME, (const void *)&ft); aRow.cValues++; set_SPropValue_proptag(aRow.lpProps + aRow.cValues, PR_LOCAL_COMMIT_TIME, (const void *)&ft); aRow.cValues++; /* we copy CodePageId (uint16_t) into an uint32_t to avoid a buffer error */ pt_long = mapi_req->u.mapi_CreateMessage.CodePageId; set_SPropValue_proptag(aRow.lpProps + aRow.cValues, PR_MESSAGE_LOCALE_ID, (const void *)&pt_long); aRow.cValues++; set_SPropValue_proptag(aRow.lpProps + aRow.cValues, PR_LOCALE_ID, (const void *)&pt_long); aRow.cValues++; set_SPropValue_proptag(aRow.lpProps + aRow.cValues, PR_CREATOR_NAME_UNICODE, (const void *)emsmdbp_ctx->szDisplayName); aRow.cValues++; set_SPropValue_proptag(aRow.lpProps + aRow.cValues, PR_LAST_MODIFIER_NAME_UNICODE, (const void *)emsmdbp_ctx->szDisplayName); aRow.cValues++; pt_binary = talloc_zero(mem_ctx, struct SBinary_short); entryid_set_AB_EntryID(pt_binary, emsmdbp_ctx->szUserDN, pt_binary); set_SPropValue_proptag(aRow.lpProps + aRow.cValues, PR_CREATOR_ENTRYID, (const void *)pt_binary); aRow.cValues++; set_SPropValue_proptag(aRow.lpProps + aRow.cValues, PR_LAST_MODIFIER_ENTRYID, (const void *)pt_binary); aRow.cValues++; /* TODO: some required properties are not set: PidTagSearchKey, PidTagMessageSize, PidTagSecurityDescriptor */ emsmdbp_object_set_properties(emsmdbp_ctx, message_object, &aRow); DEBUG(0, ("CreateMessage: 0x%.16"PRIx64": mapistore = %s\n", folderID, mapistore ? "true" : "false")); end: *size += libmapiserver_RopCreateMessage_size(mapi_repl); return MAPI_E_SUCCESS; } /** \details EcDoRpc SaveChangesMessage (0x0c) Rop. This operation operation commits the changes made to a message. \param mem_ctx pointer to the memory context \param emsmdbp_ctx pointer to the emsmdb provider context \param mapi_req pointer to the SaveChangesMessage EcDoRpc_MAPI_REQ structure \param mapi_repl pointer to the SaveChangesMessage EcDoRpc_MAPI_REPL structure \param handles pointer to the MAPI handles array \param size pointer to the mapi_response size to update \return MAPI_E_SUCCESS on success, otherwise MAPI error */ _PUBLIC_ enum MAPISTATUS EcDoRpc_RopSaveChangesMessage(TALLOC_CTX *mem_ctx, struct emsmdbp_context *emsmdbp_ctx, struct EcDoRpc_MAPI_REQ *mapi_req, struct EcDoRpc_MAPI_REPL *mapi_repl, uint32_t *handles, uint16_t *size) { enum MAPISTATUS retval; uint32_t handle; struct mapi_handles *rec = NULL; void *private_data; bool mapistore = false; struct emsmdbp_object *object; uint64_t messageID; uint32_t contextID; char *owner; uint8_t flags; enum mapistore_error ret; DEBUG(4, ("exchange_emsmdb: [OXCMSG] SaveChangesMessage (0x0c)\n")); /* Sanity checks */ OPENCHANGE_RETVAL_IF(!emsmdbp_ctx, MAPI_E_NOT_INITIALIZED, NULL); OPENCHANGE_RETVAL_IF(!mapi_req, MAPI_E_INVALID_PARAMETER, NULL); OPENCHANGE_RETVAL_IF(!mapi_repl, MAPI_E_INVALID_PARAMETER, NULL); OPENCHANGE_RETVAL_IF(!handles, MAPI_E_INVALID_PARAMETER, NULL); OPENCHANGE_RETVAL_IF(!size, MAPI_E_INVALID_PARAMETER, NULL); mapi_repl->opnum = mapi_req->opnum; mapi_repl->error_code = MAPI_E_SUCCESS; mapi_repl->handle_idx = mapi_req->handle_idx; handle = handles[mapi_req->u.mapi_SaveChangesMessage.handle_idx]; retval = mapi_handles_search(emsmdbp_ctx->handles_ctx, handle, &rec); if (retval) { mapi_repl->error_code = MAPI_E_INVALID_OBJECT; goto end; } retval = mapi_handles_get_private_data(rec, &private_data); object = (struct emsmdbp_object *)private_data; if (!object || object->type != EMSMDBP_OBJECT_MESSAGE) { mapi_repl->error_code = MAPI_E_INVALID_OBJECT; goto end; } flags = mapi_req->u.mapi_SaveChangesMessage.SaveFlags; mapistore = emsmdbp_is_mapistore(object); switch (mapistore) { case false: retval = openchangedb_message_save(object->backend_object, flags); DEBUG(0, ("[%s:%d]: openchangedb_save_message: retval = 0x%x\n", __FUNCTION__, __LINE__, retval)); break; case true: contextID = emsmdbp_get_contextID(object); messageID = object->object.message->messageID; ret = mapistore_message_save(emsmdbp_ctx->mstore_ctx, contextID, object->backend_object); if (ret == MAPISTORE_ERR_DENIED) { mapi_repl->error_code = MAPI_E_NO_ACCESS; goto end; } owner = emsmdbp_get_owner(object); mapistore_indexing_record_add_mid(emsmdbp_ctx->mstore_ctx, contextID, owner, messageID); break; } mapi_repl->u.mapi_SaveChangesMessage.handle_idx = mapi_req->u.mapi_SaveChangesMessage.handle_idx; mapi_repl->u.mapi_SaveChangesMessage.MessageId = object->object.message->messageID; end: *size += libmapiserver_RopSaveChangesMessage_size(mapi_repl); return MAPI_E_SUCCESS; } /** \details EcDoRpc RemoveAllRecipients (0x0d) Rop. This operation removes all recipients from a message. \param mem_ctx pointer to the memory context \param emsmdbp_ctx pointer to the emsmdb provider context \param mapi_req pointer to the RemoveAllRecipients EcDoRpc_MAPI_REQ structure \param mapi_repl pointer to the RemoveAllRecipients EcDoRpc_MAPI_REPL structure \param handles pointer to the MAPI handles array \param size pointer to the mapi_response size to update \return MAPI_E_SUCCESS on success, otherwise MAPI error */ _PUBLIC_ enum MAPISTATUS EcDoRpc_RopRemoveAllRecipients(TALLOC_CTX *mem_ctx, struct emsmdbp_context *emsmdbp_ctx, struct EcDoRpc_MAPI_REQ *mapi_req, struct EcDoRpc_MAPI_REPL *mapi_repl, uint32_t *handles, uint16_t *size) { struct mapi_handles *rec = NULL; struct emsmdbp_object *object; enum MAPISTATUS retval; uint32_t handle; void *private_data; bool mapistore = false; uint32_t contextID; struct SPropTagArray columns; DEBUG(4, ("exchange_emsmdb: [OXCMSG] RemoveAllRecipients (0x0d)\n")); /* Sanity checks */ OPENCHANGE_RETVAL_IF(!emsmdbp_ctx, MAPI_E_NOT_INITIALIZED, NULL); OPENCHANGE_RETVAL_IF(!mapi_req, MAPI_E_INVALID_PARAMETER, NULL); OPENCHANGE_RETVAL_IF(!mapi_repl, MAPI_E_INVALID_PARAMETER, NULL); OPENCHANGE_RETVAL_IF(!handles, MAPI_E_INVALID_PARAMETER, NULL); OPENCHANGE_RETVAL_IF(!size, MAPI_E_INVALID_PARAMETER, NULL); mapi_repl->opnum = mapi_req->opnum; mapi_repl->error_code = MAPI_E_SUCCESS; handle = handles[mapi_req->handle_idx]; retval = mapi_handles_search(emsmdbp_ctx->handles_ctx, handle, &rec); if (retval) { mapi_repl->error_code = MAPI_E_NOT_FOUND; goto end; } mapi_repl->handle_idx = mapi_req->handle_idx; retval = mapi_handles_get_private_data(rec, &private_data); object = (struct emsmdbp_object *)private_data; if (!object || object->type != EMSMDBP_OBJECT_MESSAGE) { mapi_repl->error_code = MAPI_E_NO_SUPPORT; goto end; } mapistore = emsmdbp_is_mapistore(object); if (mapistore) { contextID = emsmdbp_get_contextID(object); memset(&columns, 0, sizeof(struct SPropTagArray)); mapistore_message_modify_recipients(emsmdbp_ctx->mstore_ctx, contextID, &columns, object->backend_object, 0, NULL); } else { DEBUG(0, ("Not implement yet - shouldn't occur\n")); } end: *size += libmapiserver_RopRemoveAllRecipients_size(mapi_repl); return MAPI_E_SUCCESS; } static void oxcmsg_parse_ModifyRecipientRow(TALLOC_CTX *mem_ctx, struct ModifyRecipientRow *recipient_row, uint16_t prop_count, enum MAPITAGS *properties, struct mapistore_message_recipient *recipient) { int i, data_pos; uint8_t *src_value; void *dest_value; char *uni_value; struct Binary_r *bin_value; struct FILETIME *ft_value; size_t value_size = 0; const uint16_t *unicode_char; size_t dest_size, dest_len; recipient->type = recipient_row->RecipClass; if ((recipient_row->RecipientRow.RecipientFlags & 0x07) == 1) { recipient->username = (char *) recipient_row->RecipientRow.X500DN.recipient_x500name; } else { recipient->username = NULL; } recipient->data = talloc_array(mem_ctx, void *, prop_count + 2); /* PR_DISPLAY_NAME_UNICODE */ switch ((recipient_row->RecipientRow.RecipientFlags & 0x210)) { case 0x10: recipient->data[0] = (void *) recipient_row->RecipientRow.DisplayName.lpszA; break; case 0x210: recipient->data[0] = (void *) recipient_row->RecipientRow.DisplayName.lpszW; break; default: recipient->data[0] = NULL; } /* PR_EMAIL_ADDRESS_UNICODE */ switch ((recipient_row->RecipientRow.RecipientFlags & 0x208)) { case 0x08: recipient->data[1] = (void *) recipient_row->RecipientRow.EmailAddress.lpszA; break; case 0x208: recipient->data[1] = (void *) recipient_row->RecipientRow.EmailAddress.lpszW; break; default: recipient->data[1] = NULL; } data_pos = 0; for (i = 0; i < prop_count; i++) { if (properties[i] & MV_FLAG) { DEBUG(0, ("multivalue not supported yet\n")); abort(); } if (recipient_row->RecipientRow.layout) { data_pos++; if (recipient_row->RecipientRow.prop_values.data[data_pos] != 0) { recipient->data[i+2] = NULL; if (recipient_row->RecipientRow.prop_values.data[data_pos] == 0xa) { data_pos += 4; } continue; } } dest_value = src_value = recipient_row->RecipientRow.prop_values.data + data_pos; switch (properties[i] & 0xffff) { case PT_BOOLEAN: value_size = sizeof(uint8_t); break; case PT_I2: value_size = sizeof(uint16_t); break; case PT_LONG: case PT_ERROR: value_size = sizeof(uint32_t); break; case PT_DOUBLE: value_size = sizeof(double); break; case PT_I8: value_size = sizeof(uint64_t); break; case PT_STRING8: value_size = strlen(dest_value) + 1; break; case PT_SYSTIME: ft_value = talloc_zero(recipient->data, struct FILETIME); ft_value->dwLowDateTime = *(uint32_t *) src_value; ft_value->dwHighDateTime = *(uint32_t *) (src_value + 4); value_size = sizeof(uint64_t); dest_value = ft_value; break; case PT_UNICODE: unicode_char = (const uint16_t *) src_value; value_size = 0; while (*unicode_char++) value_size += 2; dest_size = value_size * 3 + 3; uni_value = talloc_array(recipient->data, char, dest_size); convert_string(CH_UTF16LE, CH_UTF8, src_value, value_size, uni_value, dest_size, &dest_len); uni_value[dest_len] = 0; dest_value = uni_value; value_size += 2; break; case PT_BINARY: bin_value = talloc_zero(recipient->data, struct Binary_r); bin_value->cb = *(uint16_t *) src_value; bin_value->lpb = src_value + 2; value_size = (bin_value->cb + sizeof(uint16_t)); dest_value = bin_value; break; } recipient->data[i+2] = dest_value; data_pos += value_size; } } /** \details EcDoRpc ModifyRecipients (0x0e) Rop. This operation modifies an existing message to add recipients (TO, CC, BCC). \param mem_ctx pointer to the memory context \param emsmdbp_ctx pointer to the emsmdb provider context \param mapi_req pointer to the ModifyRecipients EcDoRpc_MAPI_REQ structure \param mapi_repl pointer to the ModifyRecipients EcDoRpc_MAPI_REPL structure \param handles pointer to the MAPI handles array \param size pointer to the mapi_response size to update \return MAPI_E_SUCCESS on success, otherwise MAPI error */ _PUBLIC_ enum MAPISTATUS EcDoRpc_RopModifyRecipients(TALLOC_CTX *mem_ctx, struct emsmdbp_context *emsmdbp_ctx, struct EcDoRpc_MAPI_REQ *mapi_req, struct EcDoRpc_MAPI_REPL *mapi_repl, uint32_t *handles, uint16_t *size) { struct mapi_handles *rec = NULL; struct emsmdbp_object *object; enum MAPISTATUS retval; uint32_t handle; void *private_data; bool mapistore = false; uint32_t contextID; struct mapistore_message_recipient *recipients; struct SPropTagArray *columns; int i; DEBUG(4, ("exchange_emsmdb: [OXCMSG] ModifyRecipients (0x0e)\n")); /* Sanity checks */ OPENCHANGE_RETVAL_IF(!emsmdbp_ctx, MAPI_E_NOT_INITIALIZED, NULL); OPENCHANGE_RETVAL_IF(!mapi_req, MAPI_E_INVALID_PARAMETER, NULL); OPENCHANGE_RETVAL_IF(!mapi_repl, MAPI_E_INVALID_PARAMETER, NULL); OPENCHANGE_RETVAL_IF(!handles, MAPI_E_INVALID_PARAMETER, NULL); OPENCHANGE_RETVAL_IF(!size, MAPI_E_INVALID_PARAMETER, NULL); mapi_repl->opnum = mapi_req->opnum; mapi_repl->error_code = MAPI_E_SUCCESS; handle = handles[mapi_req->handle_idx]; retval = mapi_handles_search(emsmdbp_ctx->handles_ctx, handle, &rec); if (retval) { mapi_repl->error_code = MAPI_E_NOT_FOUND; goto end; } mapi_repl->handle_idx = mapi_req->handle_idx; retval = mapi_handles_get_private_data(rec, &private_data); object = (struct emsmdbp_object *)private_data; if (!object || object->type != EMSMDBP_OBJECT_MESSAGE) { mapi_repl->error_code = MAPI_E_NO_SUPPORT; goto end; } mapistore = emsmdbp_is_mapistore(object); if (mapistore) { /* Convention: we somewhat flatten the row and provide PR_DISPLAY_NAME_UNICODE and PR_EMAIL_ADDRESS_UNICODE to the backend */ contextID = emsmdbp_get_contextID(object); columns = talloc_zero(mem_ctx, struct SPropTagArray); columns->cValues = mapi_req->u.mapi_ModifyRecipients.prop_count + 2; columns->aulPropTag = talloc_array(columns, enum MAPITAGS, columns->cValues); columns->aulPropTag[0] = PR_DISPLAY_NAME_UNICODE; columns->aulPropTag[1] = PR_EMAIL_ADDRESS_UNICODE; memcpy(columns->aulPropTag + 2, mapi_req->u.mapi_ModifyRecipients.properties, mapi_req->u.mapi_ModifyRecipients.prop_count * sizeof(enum MAPITAGS)); recipients = talloc_array(mem_ctx, struct mapistore_message_recipient, mapi_req->u.mapi_ModifyRecipients.cValues); for (i = 0; i < mapi_req->u.mapi_ModifyRecipients.cValues; i++) { oxcmsg_parse_ModifyRecipientRow(recipients, mapi_req->u.mapi_ModifyRecipients.RecipientRow + i, mapi_req->u.mapi_ModifyRecipients.prop_count, mapi_req->u.mapi_ModifyRecipients.properties, recipients + i); } mapistore_message_modify_recipients(emsmdbp_ctx->mstore_ctx, contextID, object->backend_object, columns, mapi_req->u.mapi_ModifyRecipients.cValues, recipients); } else { DEBUG(0, ("Not implement yet - shouldn't occur\n")); } end: *size += libmapiserver_RopModifyRecipients_size(mapi_repl); return MAPI_E_SUCCESS; } /** \details EcDoRpc ReloadCachedInformation (0x10) Rop. This operation gets message and recipient information from a message. \param mem_ctx pointer to the memory context \param emsmdbp_ctx pointer to the emsmdb provider context \param mapi_req pointer to the ReloadCachedInformation EcDoRpc_MAPI_REQ structure \param mapi_repl pointer to the ReloadCachedInformation EcDoRpc_MAPI_REPL structure \param handles pointer to the MAPI handles array \param size pointer to the mapi_response size to update \return MAPI_E_SUCCESS on success, otherwise MAPI error */ _PUBLIC_ enum MAPISTATUS EcDoRpc_RopReloadCachedInformation(TALLOC_CTX *mem_ctx, struct emsmdbp_context *emsmdbp_ctx, struct EcDoRpc_MAPI_REQ *mapi_req, struct EcDoRpc_MAPI_REPL *mapi_repl, uint32_t *handles, uint16_t *size) { enum MAPISTATUS retval; uint32_t handle; struct mapi_handles *rec = NULL; void *private_data; bool mapistore = false; struct mapistore_message *msg; struct emsmdbp_object *object; uint32_t contextID; struct oxcmsg_prop_index prop_index; int i; DEBUG(4, ("exchange_emsmdb: [OXCMSG] ReloadCachedInformation (0x10)\n")); /* Sanity checks */ OPENCHANGE_RETVAL_IF(!emsmdbp_ctx, MAPI_E_NOT_INITIALIZED, NULL); OPENCHANGE_RETVAL_IF(!mapi_req, MAPI_E_INVALID_PARAMETER, NULL); OPENCHANGE_RETVAL_IF(!mapi_repl, MAPI_E_INVALID_PARAMETER, NULL); OPENCHANGE_RETVAL_IF(!handles, MAPI_E_INVALID_PARAMETER, NULL); OPENCHANGE_RETVAL_IF(!size, MAPI_E_INVALID_PARAMETER, NULL); mapi_repl->opnum = mapi_req->opnum; mapi_repl->error_code = MAPI_E_SUCCESS; mapi_repl->handle_idx = mapi_req->handle_idx; handle = handles[mapi_req->handle_idx]; retval = mapi_handles_search(emsmdbp_ctx->handles_ctx, handle, &rec); if (retval) { mapi_repl->error_code = MAPI_E_NOT_FOUND; goto end; } retval = mapi_handles_get_private_data(rec, &private_data); object = (struct emsmdbp_object *)private_data; if (!object || object->type != EMSMDBP_OBJECT_MESSAGE) { mapi_repl->error_code = MAPI_E_NO_SUPPORT; goto end; } mapistore = emsmdbp_is_mapistore(object); switch (mapistore) { case false: DEBUG(0, ("Not implemented yet - shouldn't occur\n")); break; case true: contextID = emsmdbp_get_contextID(object); if (mapistore_message_get_message_data(emsmdbp_ctx->mstore_ctx, contextID, object->backend_object, mem_ctx, &msg) != MAPISTORE_SUCCESS) { mapi_repl->error_code = MAPI_E_NOT_FOUND; goto end; } /* Build the ReloadCachedInformation reply */ if (msg->subject_prefix && strlen(msg->subject_prefix) > 0) { mapi_repl->u.mapi_ReloadCachedInformation.SubjectPrefix.StringType = StringType_UNICODE; mapi_repl->u.mapi_ReloadCachedInformation.SubjectPrefix.String.lpszW = talloc_strdup(mem_ctx, msg->subject_prefix); } else { mapi_repl->u.mapi_ReloadCachedInformation.SubjectPrefix.StringType = StringType_EMPTY; } if (msg->normalized_subject && strlen(msg->normalized_subject) > 0) { mapi_repl->u.mapi_ReloadCachedInformation.NormalizedSubject.StringType = StringType_UNICODE; mapi_repl->u.mapi_ReloadCachedInformation.NormalizedSubject.String.lpszW = talloc_strdup(mem_ctx, msg->normalized_subject); } else { mapi_repl->u.mapi_ReloadCachedInformation.NormalizedSubject.StringType = StringType_EMPTY; } if (msg->columns) { mapi_repl->u.mapi_ReloadCachedInformation.RecipientColumns.cValues = msg->columns->cValues; mapi_repl->u.mapi_ReloadCachedInformation.RecipientColumns.aulPropTag = msg->columns->aulPropTag; } else { mapi_repl->u.mapi_ReloadCachedInformation.RecipientColumns.cValues = 0; } mapi_repl->u.mapi_ReloadCachedInformation.RecipientCount = msg->recipients_count; mapi_repl->u.mapi_ReloadCachedInformation.RowCount = msg->recipients_count; if (msg->recipients_count > 0) { mapi_repl->u.mapi_ReloadCachedInformation.RecipientRows = talloc_array(mem_ctx, struct OpenRecipientRow, msg->recipients_count + 1); oxcmsg_fill_prop_index(&prop_index, msg->columns); for (i = 0; i < msg->recipients_count; i++) { oxcmsg_fill_OpenRecipientRow(mem_ctx, emsmdbp_ctx, &(mapi_repl->u.mapi_ReloadCachedInformation.RecipientRows[i]), msg->columns, msg->recipients + i, &prop_index); } } break; } end: *size += libmapiserver_RopReloadCachedInformation_size(mapi_repl); return MAPI_E_SUCCESS; } /** \details EcDoRpc SetMessageReadFlag (0x11) Rop. This operation sets or clears the message read flag. \param mem_ctx pointer to the memory context \param emsmdbp_ctx pointer to the emsmdb provider context \param mapi_req pointer to the SetMessageReadFlag EcDoRpc_MAPI_REQ structure \param mapi_repl pointer to the SetMessageReadFlag EcDoRpc_MAPI_REPL structure \param handles pointer to the MAPI handles array \param size pointer to the mapi_response size to update \return MAPI_E_SUCCESS on success, otherwise MAPI error */ _PUBLIC_ enum MAPISTATUS EcDoRpc_RopSetMessageReadFlag(TALLOC_CTX *mem_ctx, struct emsmdbp_context *emsmdbp_ctx, struct EcDoRpc_MAPI_REQ *mapi_req, struct EcDoRpc_MAPI_REPL *mapi_repl, uint32_t *handles, uint16_t *size) { struct SetMessageReadFlag_req *request; /* struct SetMessageReadFlag_repl *response; */ enum MAPISTATUS retval; uint32_t handle; struct mapi_handles *rec = NULL; struct emsmdbp_object *message_object = NULL; uint32_t contextID; void *data; DEBUG(4, ("exchange_emsmdb: [OXCMSG] SetMessageReadFlag (0x11)\n")); /* Sanity checks */ OPENCHANGE_RETVAL_IF(!emsmdbp_ctx, MAPI_E_NOT_INITIALIZED, NULL); OPENCHANGE_RETVAL_IF(!mapi_req, MAPI_E_INVALID_PARAMETER, NULL); OPENCHANGE_RETVAL_IF(!mapi_repl, MAPI_E_INVALID_PARAMETER, NULL); OPENCHANGE_RETVAL_IF(!handles, MAPI_E_INVALID_PARAMETER, NULL); OPENCHANGE_RETVAL_IF(!size, MAPI_E_INVALID_PARAMETER, NULL); request = &mapi_req->u.mapi_SetMessageReadFlag; /* response = &mapi_repl->u.mapi_SetMessageReadFlag; */ mapi_repl->opnum = mapi_req->opnum; mapi_repl->error_code = MAPI_E_SUCCESS; mapi_repl->handle_idx = mapi_req->handle_idx; handle = handles[request->handle_idx]; retval = mapi_handles_search(emsmdbp_ctx->handles_ctx, handle, &rec); if (retval) { mapi_repl->error_code = MAPI_E_INVALID_OBJECT; DEBUG(5, (" handle (%x) not found: %x\n", handle, mapi_req->handle_idx)); goto end; } retval = mapi_handles_get_private_data(rec, &data); if (retval) { mapi_repl->error_code = retval; DEBUG(5, (" handle data not found, idx = %x\n", mapi_req->handle_idx)); goto end; } message_object = (struct emsmdbp_object *) data; if (!message_object || message_object->type != EMSMDBP_OBJECT_MESSAGE) { DEBUG(5, (" no object or object is not a message\n")); mapi_repl->error_code = MAPI_E_NO_SUPPORT; goto end; } switch (emsmdbp_is_mapistore(message_object)) { case false: DEBUG(0, ("Not implemented yet\n")); break; case true: contextID = emsmdbp_get_contextID(message_object); mapistore_message_set_read_flag(emsmdbp_ctx->mstore_ctx, contextID, message_object->backend_object, request->flags); break; } /* TODO: public folders */ mapi_repl->u.mapi_SetMessageReadFlag.ReadStatusChanged = false; end: *size += libmapiserver_RopSetMessageReadFlag_size(mapi_repl); return MAPI_E_SUCCESS; } /** \details EcDoRpc GetAttachmentTable (0x21) Rop. This operation gets the attachment table of a message. \param mem_ctx pointer to the memory context \param emsmdbp_ctx pointer to the emsmdb provider context \param mapi_req pointer to the GetAttachmentTable EcDoRpc_MAPI_REQ structure \param mapi_repl pointer to the GetAttachmentTable EcDoRpc_MAPI_REPL structure \param handles pointer to the MAPI handles array \param size pointer to the mapi_response size to update \return MAPI_E_SUCCESS on success, otherwise MAPI error */ _PUBLIC_ enum MAPISTATUS EcDoRpc_RopGetAttachmentTable(TALLOC_CTX *mem_ctx, struct emsmdbp_context *emsmdbp_ctx, struct EcDoRpc_MAPI_REQ *mapi_req, struct EcDoRpc_MAPI_REPL *mapi_repl, uint32_t *handles, uint16_t *size) { enum MAPISTATUS retval; uint32_t handle; struct mapi_handles *rec = NULL; struct mapi_handles *table_rec = NULL; struct emsmdbp_object *message_object = NULL; struct emsmdbp_object *table_object = NULL; void *data; DEBUG(4, ("exchange_emsmdb: [OXCMSG] GetAttachmentTable (0x21)\n")); /* Sanity checks */ OPENCHANGE_RETVAL_IF(!emsmdbp_ctx, MAPI_E_NOT_INITIALIZED, NULL); OPENCHANGE_RETVAL_IF(!mapi_req, MAPI_E_INVALID_PARAMETER, NULL); OPENCHANGE_RETVAL_IF(!mapi_repl, MAPI_E_INVALID_PARAMETER, NULL); OPENCHANGE_RETVAL_IF(!handles, MAPI_E_INVALID_PARAMETER, NULL); OPENCHANGE_RETVAL_IF(!size, MAPI_E_INVALID_PARAMETER, NULL); mapi_repl->opnum = mapi_req->opnum; mapi_repl->error_code = MAPI_E_SUCCESS; mapi_repl->handle_idx = mapi_req->u.mapi_GetAttachmentTable.handle_idx; handle = handles[mapi_req->handle_idx]; retval = mapi_handles_search(emsmdbp_ctx->handles_ctx, handle, &rec); if (retval) { mapi_repl->error_code = MAPI_E_INVALID_OBJECT; DEBUG(5, (" handle (%x) not found: %x\n", handle, mapi_req->handle_idx)); goto end; } retval = mapi_handles_get_private_data(rec, &data); if (retval) { mapi_repl->error_code = retval; DEBUG(5, (" handle data not found, idx = %x\n", mapi_req->handle_idx)); goto end; } message_object = (struct emsmdbp_object *) data; if (!message_object || message_object->type != EMSMDBP_OBJECT_MESSAGE) { DEBUG(5, (" no object or object is not a message\n")); mapi_repl->error_code = MAPI_E_NO_SUPPORT; goto end; } retval = mapi_handles_add(emsmdbp_ctx->handles_ctx, handle, &table_rec); handles[mapi_repl->handle_idx] = table_rec->handle; table_object = emsmdbp_object_message_open_attachment_table(table_rec, emsmdbp_ctx, message_object); if (!table_object) { mapi_handles_delete(emsmdbp_ctx->handles_ctx, table_rec->handle); mapi_repl->error_code = MAPI_E_NOT_FOUND; goto end; } mapi_handles_set_private_data(table_rec, table_object); end: *size += libmapiserver_RopGetAttachmentTable_size(mapi_repl); return MAPI_E_SUCCESS; } /** \details EcDoRpc OpenAttach (0x22) Rop. This operation open an attachment from the message handle. \param mem_ctx pointer to the memory context \param emsmdbp_ctx pointer to the emsmdb provider context \param mapi_req pointer to the OpenAttach EcDoRpc_MAPI_REQ structure \param mapi_repl pointer to the OpenAttach EcDoRpc_MAPI_REPL structure \param handles pointer to the MAPI handles array \param size pointer to the mapi_response size to update \return MAPI_E_SUCCESS on success, otherwise MAPI error */ _PUBLIC_ enum MAPISTATUS EcDoRpc_RopOpenAttach(TALLOC_CTX *mem_ctx, struct emsmdbp_context *emsmdbp_ctx, struct EcDoRpc_MAPI_REQ *mapi_req, struct EcDoRpc_MAPI_REPL *mapi_repl, uint32_t *handles, uint16_t *size) { enum MAPISTATUS retval; uint32_t handle; uint32_t attachmentID; uint32_t contextID; struct mapi_handles *rec = NULL; struct mapi_handles *attachment_rec = NULL; struct emsmdbp_object *message_object = NULL; struct emsmdbp_object *attachment_object = NULL; void *data; DEBUG(4, ("exchange_emsmdb: [OXCMSG] OpenAttach (0x22)\n")); /* Sanity checks */ OPENCHANGE_RETVAL_IF(!emsmdbp_ctx, MAPI_E_NOT_INITIALIZED, NULL); OPENCHANGE_RETVAL_IF(!mapi_req, MAPI_E_INVALID_PARAMETER, NULL); OPENCHANGE_RETVAL_IF(!mapi_repl, MAPI_E_INVALID_PARAMETER, NULL); OPENCHANGE_RETVAL_IF(!handles, MAPI_E_INVALID_PARAMETER, NULL); OPENCHANGE_RETVAL_IF(!size, MAPI_E_INVALID_PARAMETER, NULL); mapi_repl->opnum = mapi_req->opnum; mapi_repl->error_code = MAPI_E_SUCCESS; mapi_repl->handle_idx = mapi_req->u.mapi_OpenAttach.handle_idx; handle = handles[mapi_req->handle_idx]; retval = mapi_handles_search(emsmdbp_ctx->handles_ctx, handle, &rec); if (retval) { mapi_repl->error_code = MAPI_E_INVALID_OBJECT; DEBUG(5, (" handle (%x) not found: %x\n", handle, mapi_req->handle_idx)); goto end; } retval = mapi_handles_get_private_data(rec, &data); if (retval) { mapi_repl->error_code = retval; DEBUG(5, (" handle data not found, idx = %x\n", mapi_req->handle_idx)); goto end; } message_object = (struct emsmdbp_object *) data; if (!message_object || message_object->type != EMSMDBP_OBJECT_MESSAGE) { DEBUG(5, (" no object or object is not a message\n")); mapi_repl->error_code = MAPI_E_NO_SUPPORT; goto end; } switch (emsmdbp_is_mapistore(message_object)) { case false: /* system/special folder */ DEBUG(0, ("Not implemented yet - shouldn't occur\n")); break; case true: contextID = emsmdbp_get_contextID(message_object); attachmentID = mapi_req->u.mapi_OpenAttach.AttachmentID; retval = mapi_handles_add(emsmdbp_ctx->handles_ctx, 0, &attachment_rec); handles[mapi_repl->handle_idx] = attachment_rec->handle; attachment_object = emsmdbp_object_attachment_init((TALLOC_CTX *)attachment_rec, emsmdbp_ctx, message_object->object.message->messageID, message_object); if (attachment_object) { retval = mapistore_message_open_attachment(emsmdbp_ctx->mstore_ctx, contextID, message_object->backend_object, attachment_object, attachmentID, &attachment_object->backend_object); if (retval) { mapi_handles_delete(emsmdbp_ctx->handles_ctx, attachment_rec->handle); DEBUG(5, ("could not open nor create mapistore message\n")); mapi_repl->error_code = MAPI_E_NOT_FOUND; } retval = mapi_handles_set_private_data(attachment_rec, attachment_object); } } end: *size += libmapiserver_RopOpenAttach_size(mapi_repl); return MAPI_E_SUCCESS; } /** \details EcDoRpc CreateAttach (0x23) Rop. This operation open an attachment from the message handle. \param mem_ctx pointer to the memory context \param emsmdbp_ctx pointer to the emsmdb provider context \param mapi_req pointer to the CreateAttach EcDoRpc_MAPI_REQ structure \param mapi_repl pointer to the CreateAttach EcDoRpc_MAPI_REPL structure \param handles pointer to the MAPI handles array \param size pointer to the mapi_response size to update \return MAPI_E_SUCCESS on success, otherwise MAPI error */ _PUBLIC_ enum MAPISTATUS EcDoRpc_RopCreateAttach(TALLOC_CTX *mem_ctx, struct emsmdbp_context *emsmdbp_ctx, struct EcDoRpc_MAPI_REQ *mapi_req, struct EcDoRpc_MAPI_REPL *mapi_repl, uint32_t *handles, uint16_t *size) { enum MAPISTATUS retval; uint32_t handle; uint32_t contextID; uint64_t messageID; struct mapi_handles *rec = NULL; struct mapi_handles *attachment_rec = NULL; struct emsmdbp_object *message_object = NULL; struct emsmdbp_object *attachment_object = NULL; void *data; DEBUG(4, ("exchange_emsmdb: [OXCMSG] CreateAttach (0x23)\n")); /* Sanity checks */ OPENCHANGE_RETVAL_IF(!emsmdbp_ctx, MAPI_E_NOT_INITIALIZED, NULL); OPENCHANGE_RETVAL_IF(!mapi_req, MAPI_E_INVALID_PARAMETER, NULL); OPENCHANGE_RETVAL_IF(!mapi_repl, MAPI_E_INVALID_PARAMETER, NULL); OPENCHANGE_RETVAL_IF(!handles, MAPI_E_INVALID_PARAMETER, NULL); OPENCHANGE_RETVAL_IF(!size, MAPI_E_INVALID_PARAMETER, NULL); mapi_repl->opnum = mapi_req->opnum; mapi_repl->error_code = MAPI_E_SUCCESS; mapi_repl->handle_idx = mapi_req->u.mapi_CreateAttach.handle_idx; handle = handles[mapi_req->handle_idx]; retval = mapi_handles_search(emsmdbp_ctx->handles_ctx, handle, &rec); if (retval) { mapi_repl->error_code = MAPI_E_INVALID_OBJECT; DEBUG(5, (" handle (%x) not found: %x\n", handle, mapi_req->handle_idx)); goto end; } retval = mapi_handles_get_private_data(rec, &data); if (retval) { mapi_repl->error_code = retval; DEBUG(5, (" handle data not found, idx = %x\n", mapi_req->handle_idx)); goto end; } message_object = (struct emsmdbp_object *) data; if (!message_object || message_object->type != EMSMDBP_OBJECT_MESSAGE) { DEBUG(5, (" no object or object is not a message\n")); mapi_repl->error_code = MAPI_E_NO_SUPPORT; goto end; } if (!message_object->object.message->read_write) { DEBUG(5, (" parent message object is not open read/write\n")); mapi_repl->error_code = MAPI_E_NO_ACCESS; goto end; } switch (emsmdbp_is_mapistore(message_object)) { case false: /* system/special folder */ DEBUG(0, ("Not implemented yet - shouldn't occur\n")); break; case true: messageID = message_object->object.message->messageID; contextID = emsmdbp_get_contextID(message_object); retval = mapi_handles_add(emsmdbp_ctx->handles_ctx, 0, &attachment_rec); handles[mapi_repl->handle_idx] = attachment_rec->handle; attachment_object = emsmdbp_object_attachment_init((TALLOC_CTX *)attachment_rec, emsmdbp_ctx, messageID, message_object); if (attachment_object) { retval = mapistore_message_create_attachment(emsmdbp_ctx->mstore_ctx, contextID, message_object->backend_object, attachment_object, &attachment_object->backend_object, &mapi_repl->u.mapi_CreateAttach.AttachmentID); if (retval) { mapi_handles_delete(emsmdbp_ctx->handles_ctx, attachment_rec->handle); DEBUG(5, ("could not open nor create mapistore message\n")); mapi_repl->error_code = MAPI_E_NOT_FOUND; } retval = mapi_handles_set_private_data(attachment_rec, attachment_object); } } end: *size += libmapiserver_RopCreateAttach_size(mapi_repl); return MAPI_E_SUCCESS; } /** \details EcDoRpc SaveChangesAttachment (0x25) Rop. This operation open an attachment from the message handle. \param mem_ctx pointer to the memory context \param emsmdbp_ctx pointer to the emsmdb provider context \param mapi_req pointer to the SaveChangesAttachment EcDoRpc_MAPI_REQ structure \param mapi_repl pointer to the SaveChangesAttachment EcDoRpc_MAPI_REPL structure \param handles pointer to the MAPI handles array \param size pointer to the mapi_response size to update \return MAPI_E_SUCCESS on success, otherwise MAPI error */ _PUBLIC_ enum MAPISTATUS EcDoRpc_RopSaveChangesAttachment(TALLOC_CTX *mem_ctx, struct emsmdbp_context *emsmdbp_ctx, struct EcDoRpc_MAPI_REQ *mapi_req, struct EcDoRpc_MAPI_REPL *mapi_repl, uint32_t *handles, uint16_t *size) { DEBUG(4, ("exchange_emsmdb: [OXCMSG] SaveChangesAttachment (0x25) -- valid stub\n")); /* Sanity checks */ OPENCHANGE_RETVAL_IF(!emsmdbp_ctx, MAPI_E_NOT_INITIALIZED, NULL); OPENCHANGE_RETVAL_IF(!mapi_req, MAPI_E_INVALID_PARAMETER, NULL); OPENCHANGE_RETVAL_IF(!mapi_repl, MAPI_E_INVALID_PARAMETER, NULL); OPENCHANGE_RETVAL_IF(!handles, MAPI_E_INVALID_PARAMETER, NULL); OPENCHANGE_RETVAL_IF(!size, MAPI_E_INVALID_PARAMETER, NULL); mapi_repl->opnum = mapi_req->opnum; mapi_repl->error_code = MAPI_E_SUCCESS; mapi_repl->handle_idx = mapi_req->u.mapi_SaveChangesAttachment.handle_idx; *size += libmapiserver_RopSaveChangesAttachment_size(mapi_repl); return MAPI_E_SUCCESS; } /** \details EcDoRpc OpenEmbeddedMessage (0x46) Rop. This operation open an attachment from the message handle. \param mem_ctx pointer to the memory context \param emsmdbp_ctx pointer to the emsmdb provider context \param mapi_req pointer to the OpenEmbeddedMessage EcDoRpc_MAPI_REQ structure \param mapi_repl pointer to the OpenEmbeddedMessage EcDoRpc_MAPI_REPL structure \param handles pointer to the MAPI handles array \param size pointer to the mapi_response size to update \return MAPI_E_SUCCESS on success, otherwise MAPI error */ _PUBLIC_ enum MAPISTATUS EcDoRpc_RopOpenEmbeddedMessage(TALLOC_CTX *mem_ctx, struct emsmdbp_context *emsmdbp_ctx, struct EcDoRpc_MAPI_REQ *mapi_req, struct EcDoRpc_MAPI_REPL *mapi_repl, uint32_t *handles, uint16_t *size) { struct OpenEmbeddedMessage_req *request; struct OpenEmbeddedMessage_repl *response; enum mapistore_error ret; enum MAPISTATUS retval; uint32_t handle; uint32_t contextID; uint64_t messageID; struct mapi_handles *attachment_rec = NULL; struct mapi_handles *message_rec = NULL; struct mapistore_message *msg; void *backend_attachment_message; struct emsmdbp_object *attachment_object = NULL; struct emsmdbp_object *message_object = NULL; bool mapistore; struct oxcmsg_prop_index prop_index; int i; DEBUG(4, ("exchange_emsmdb: [OXCMSG] OpenEmbeddedMessage (0x46)\n")); /* Sanity checks */ OPENCHANGE_RETVAL_IF(!emsmdbp_ctx, MAPI_E_NOT_INITIALIZED, NULL); OPENCHANGE_RETVAL_IF(!mapi_req, MAPI_E_INVALID_PARAMETER, NULL); OPENCHANGE_RETVAL_IF(!mapi_repl, MAPI_E_INVALID_PARAMETER, NULL); OPENCHANGE_RETVAL_IF(!handles, MAPI_E_INVALID_PARAMETER, NULL); OPENCHANGE_RETVAL_IF(!size, MAPI_E_INVALID_PARAMETER, NULL); request = &mapi_req->u.mapi_OpenEmbeddedMessage; response = &mapi_repl->u.mapi_OpenEmbeddedMessage; mapi_repl->opnum = mapi_req->opnum; mapi_repl->error_code = MAPI_E_SUCCESS; mapi_repl->handle_idx = mapi_req->u.mapi_OpenEmbeddedMessage.handle_idx; handle = handles[mapi_req->handle_idx]; retval = mapi_handles_search(emsmdbp_ctx->handles_ctx, handle, &attachment_rec); if (retval) { DEBUG(5, (" handle (%x) not found: %x\n", handle, mapi_req->handle_idx)); mapi_repl->error_code = MAPI_E_INVALID_OBJECT; goto end; } retval = mapi_handles_get_private_data(attachment_rec, (void *) &attachment_object); if (!attachment_object || attachment_object->type != EMSMDBP_OBJECT_ATTACHMENT) { DEBUG(5, (" no object or object is not an attachment\n")); mapi_repl->error_code = MAPI_E_NO_SUPPORT; goto end; } memset(response, 0, sizeof(struct OpenEmbeddedMessage_repl)); mapistore = emsmdbp_is_mapistore(attachment_object); switch (mapistore) { case false: DEBUG(0, ("Not implemented - shouldn't occur\n")); break; case true: contextID = emsmdbp_get_contextID(attachment_object); if (request->OpenModeFlags == MAPI_CREATE) { retval = openchangedb_get_new_folderID(emsmdbp_ctx->oc_ctx, &messageID); if (retval) { mapi_repl->error_code = MAPI_E_NO_SUPPORT; goto end; } ret = mapistore_message_attachment_create_embedded_message(emsmdbp_ctx->mstore_ctx, contextID, attachment_object->backend_object, NULL, &backend_attachment_message, &msg); if (ret != MAPISTORE_SUCCESS) { mapi_repl->error_code = MAPI_E_NOT_FOUND; goto end; } } else { ret = mapistore_message_attachment_open_embedded_message(emsmdbp_ctx->mstore_ctx, contextID, attachment_object->backend_object, NULL, &backend_attachment_message, &messageID, &msg); if (ret != MAPISTORE_SUCCESS) { mapi_repl->error_code = MAPI_E_NOT_FOUND; goto end; } } response->MessageId = messageID; if (msg->subject_prefix && strlen(msg->subject_prefix) > 0) { response->SubjectPrefix.StringType = StringType_UNICODE; response->SubjectPrefix.String.lpszW = talloc_strdup(mem_ctx, msg->subject_prefix); } else { response->SubjectPrefix.StringType = StringType_EMPTY; } if (msg->normalized_subject && strlen(msg->normalized_subject) > 0) { response->NormalizedSubject.StringType = StringType_UNICODE; response->NormalizedSubject.String.lpszW = talloc_strdup(mem_ctx, msg->normalized_subject); } else { response->NormalizedSubject.StringType = StringType_EMPTY; } if (msg->columns) { response->RecipientColumns.cValues = msg->columns->cValues; response->RecipientColumns.aulPropTag = msg->columns->aulPropTag; } else { response->RecipientColumns.cValues = 0; } response->RecipientCount = msg->recipients_count; response->RowCount = msg->recipients_count; if (msg->recipients_count > 0) { response->RecipientRows = talloc_array(mem_ctx, struct OpenRecipientRow, msg->recipients_count + 1); oxcmsg_fill_prop_index(&prop_index, msg->columns); for (i = 0; i < msg->recipients_count; i++) { oxcmsg_fill_OpenRecipientRow(mem_ctx, emsmdbp_ctx, &(response->RecipientRows[i]), msg->columns, msg->recipients + i, &prop_index); } } /* Initialize Message object */ handle = handles[mapi_req->handle_idx]; retval = mapi_handles_add(emsmdbp_ctx->handles_ctx, 0, &message_rec); handles[mapi_repl->handle_idx] = message_rec->handle; message_object = emsmdbp_object_message_init((TALLOC_CTX *)message_rec, emsmdbp_ctx, messageID, attachment_object); message_object->backend_object = backend_attachment_message; message_object->object.message->read_write = (request->OpenModeFlags != MAPI_READONLY); talloc_reference(message_object, backend_attachment_message); talloc_free(backend_attachment_message); talloc_free(msg); retval = mapi_handles_set_private_data(message_rec, message_object); break; } end: *size += libmapiserver_RopOpenEmbeddedMessage_size(mapi_repl); return MAPI_E_SUCCESS; } openchange-2.0/mapiproxy/servers/default/emsmdb/oxcnotif.c000066400000000000000000000117141223057412600241010ustar00rootroot00000000000000/* OpenChange Server implementation EMSMDBP: EMSMDB Provider implementation Copyright (C) Julien Kerihuel 2009 This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see . */ /** \file oxcnotif.c \brief Core Notifications routines and Rops */ #include "mapiproxy/dcesrv_mapiproxy.h" #include "mapiproxy/libmapiproxy/libmapiproxy.h" #include "mapiproxy/libmapiserver/libmapiserver.h" #include "dcesrv_exchange_emsmdb.h" /** \details EcDoRpc RegisterNotification (0x29) Rop. This operation subscribes for specified notifications on the server and returns a handle of the subscription to the client. \param mem_ctx pointer to the memory context \param emsmdbp_ctx pointer to the emsmdb provider context \param mapi_req pointer to the RegisterNotification EcDoRpc_MAPI_REQ structure \param mapi_repl pointer to the RegisterNotification EcDoRpc_MAPI_REPL structure \param handles pointer to the MAPI handles array \param size pointer to the mapi_response size to update \return MAPI_E_SUCCESS on success, otherwise MAPI error */ _PUBLIC_ enum MAPISTATUS EcDoRpc_RopRegisterNotification(TALLOC_CTX *mem_ctx, struct emsmdbp_context *emsmdbp_ctx, struct EcDoRpc_MAPI_REQ *mapi_req, struct EcDoRpc_MAPI_REPL *mapi_repl, uint32_t *handles, uint16_t *size) { enum MAPISTATUS retval; struct mapi_handles *parent_rec = NULL; struct mapi_handles *subscription_rec = NULL; uint32_t handle; struct emsmdbp_object *parent_object; struct emsmdbp_object *subscription_object; struct mapistore_subscription *subscription; struct mapistore_subscription_list *subscription_list; struct mapistore_object_subscription_parameters subscription_parameters; void *data; DEBUG(4, ("exchange_emsmdb: [OXCNOTIF] RegisterNotification (0x29)\n")); /* Sanity checks */ OPENCHANGE_RETVAL_IF(!emsmdbp_ctx, MAPI_E_NOT_INITIALIZED, NULL); OPENCHANGE_RETVAL_IF(!mapi_req, MAPI_E_INVALID_PARAMETER, NULL); OPENCHANGE_RETVAL_IF(!mapi_repl, MAPI_E_INVALID_PARAMETER, NULL); OPENCHANGE_RETVAL_IF(!handles, MAPI_E_INVALID_PARAMETER, NULL); OPENCHANGE_RETVAL_IF(!size, MAPI_E_INVALID_PARAMETER, NULL); mapi_repl->opnum = mapi_req->opnum; mapi_repl->handle_idx = mapi_req->u.mapi_RegisterNotification.handle_idx; mapi_repl->error_code = MAPI_E_SUCCESS; handle = handles[mapi_req->handle_idx]; retval = mapi_handles_search(emsmdbp_ctx->handles_ctx, handle, &parent_rec); if (retval) { mapi_repl->error_code = MAPI_E_INVALID_OBJECT; DEBUG(5, (" handle (%x) not found: %x\n", handle, mapi_req->handle_idx)); goto end; } retval = mapi_handles_get_private_data(parent_rec, &data); if (retval) { mapi_repl->error_code = retval; DEBUG(5, (" handle data not found, idx = %x\n", mapi_req->handle_idx)); goto end; } parent_object = (struct emsmdbp_object *) data; retval = mapi_handles_add(emsmdbp_ctx->handles_ctx, handle, &subscription_rec); if (retval) { mapi_repl->error_code = retval; goto end; } handles[mapi_repl->handle_idx] = subscription_rec->handle; /* emsmdb_object */ subscription_object = emsmdbp_object_subscription_init(subscription_rec, emsmdbp_ctx, parent_object); mapi_handles_set_private_data(subscription_rec, subscription_object); /* we attach the subscription to the session object. note: a mapistore_subscription can exist without a corresponding emsmdbp_object (tables) */ subscription_list = talloc_zero(emsmdbp_ctx->mstore_ctx, struct mapistore_subscription_list); DLIST_ADD(emsmdbp_ctx->mstore_ctx->subscriptions, subscription_list); subscription_parameters.folder_id = mapi_req->u.mapi_RegisterNotification.FolderId.ID; subscription_parameters.object_id = mapi_req->u.mapi_RegisterNotification.MessageId.ID; subscription_parameters.whole_store = mapi_req->u.mapi_RegisterNotification.WantWholeStore; subscription = mapistore_new_subscription(subscription_list, emsmdbp_ctx->mstore_ctx, emsmdbp_ctx->username, subscription_rec->handle, mapi_req->u.mapi_RegisterNotification.NotificationFlags, &subscription_parameters); subscription_list->subscription = subscription; subscription_object->object.subscription->subscription_list = subscription_list; end: *size += libmapiserver_RopRegisterNotification_size(); return MAPI_E_SUCCESS; } openchange-2.0/mapiproxy/servers/default/emsmdb/oxcperm.c000066400000000000000000000153551223057412600237320ustar00rootroot00000000000000/* OpenChange Server implementation EMSMDBP: EMSMDB Provider implementation Copyright (C) Julien Kerihuel 2010 This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see . */ /** \file oxcperm.c \brief Access and Operation Permissions Rops */ #include "mapiproxy/dcesrv_mapiproxy.h" #include "mapiproxy/libmapiproxy/libmapiproxy.h" #include "mapiproxy/libmapiserver/libmapiserver.h" #include "dcesrv_exchange_emsmdb.h" /** \details EcDoRpc GetPermissionsTable (0x3e) Rop. This operation get the permissions table of a folder. \param mem_ctx pointer to the memory context \param emsmdbp_ctx pointer to the emsmdb provider context \param mapi_req pointer to the GetPermissionsTable EcDoRpc_MAPI_REQ structure \param mapi_repl pointer to the GetPermissionsTable EcDoRpc_MAPI_REPL structure \param handles pointer to the MAPI handles array \param size pointer to the mapi_response size to update \return MAPI_E_SUCCESS on success, otherwise MAPI error */ _PUBLIC_ enum MAPISTATUS EcDoRpc_RopGetPermissionsTable(TALLOC_CTX *mem_ctx, struct emsmdbp_context *emsmdbp_ctx, struct EcDoRpc_MAPI_REQ *mapi_req, struct EcDoRpc_MAPI_REPL *mapi_repl, uint32_t *handles, uint16_t *size) { enum MAPISTATUS retval; struct mapi_handles *parent; struct mapi_handles *rec; struct emsmdbp_object *parent_object, *object; void *data = NULL; uint32_t handle; DEBUG(4, ("exchange_emsmdb: [OXCPERM] GetPermissionsTable (0x3e)\n")); /* Sanity checks */ OPENCHANGE_RETVAL_IF(!emsmdbp_ctx, MAPI_E_NOT_INITIALIZED, NULL); OPENCHANGE_RETVAL_IF(!mapi_req, MAPI_E_INVALID_PARAMETER, NULL); OPENCHANGE_RETVAL_IF(!mapi_repl, MAPI_E_INVALID_PARAMETER, NULL); OPENCHANGE_RETVAL_IF(!handles, MAPI_E_INVALID_PARAMETER, NULL); OPENCHANGE_RETVAL_IF(!size, MAPI_E_INVALID_PARAMETER, NULL); mapi_repl->opnum = mapi_req->opnum; mapi_repl->handle_idx = mapi_req->u.mapi_GetPermissionsTable.handle_idx; mapi_repl->error_code = MAPI_E_SUCCESS; /* Ensure parent handle references a folder object */ handle = handles[mapi_req->handle_idx]; retval = mapi_handles_search(emsmdbp_ctx->handles_ctx, handle, &parent); if (retval) { mapi_repl->error_code = MAPI_E_INVALID_OBJECT; DEBUG(5, (" handle (%x) not found: %x\n", handle, mapi_req->handle_idx)); goto end; } retval = mapi_handles_get_private_data(parent, &data); if (retval || !data) { mapi_repl->error_code = MAPI_E_NOT_FOUND; DEBUG(5, (" handle data not found, idx = %x\n", mapi_req->handle_idx)); goto end; } parent_object = (struct emsmdbp_object *) data; if (parent_object->type != EMSMDBP_OBJECT_FOLDER) { mapi_repl->error_code = MAPI_E_INVALID_OBJECT; DEBUG(5, (" unhandled object type: %d\n", parent_object->type)); goto end; } /* Initialize Table object */ retval = mapi_handles_add(emsmdbp_ctx->handles_ctx, handle, &rec); handles[mapi_repl->handle_idx] = rec->handle; if (emsmdbp_is_mapistore(parent_object)) { object = emsmdbp_folder_open_table(rec, parent_object, MAPISTORE_PERMISSIONS_TABLE, mapi_repl->handle_idx); } else { object = emsmdbp_object_table_init((TALLOC_CTX *)rec, emsmdbp_ctx, parent_object); } if (object) { retval = mapi_handles_set_private_data(rec, object); } else { mapi_handles_delete(emsmdbp_ctx->handles_ctx, rec->handle); mapi_repl->error_code = MAPI_E_NOT_FOUND; goto end; } end: *size += libmapiserver_RopGetPermissionsTable_size(mapi_repl); return MAPI_E_SUCCESS; } /** \details EcDoRpc ModifyPermissions (0x40) Rop. This operation gets the GUID of a public folder's per-user information. \param mem_ctx pointer to the memory context \param emsmdbp_ctx pointer to the emsmdb provider context \param mapi_req pointer to the GetPerUserLongTermIds EcDoRpc_MAPI_REQ \param mapi_repl pointer to the GetPerUserLongTermIds EcDoRpc_MAPI_REPL \param handles pointer to the MAPI handles array \param size pointer to the mapi_response size to update \return MAPI_E_SUCCESS on success, otherwise MAPI error */ _PUBLIC_ enum MAPISTATUS EcDoRpc_RopModifyPermissions(TALLOC_CTX *mem_ctx, struct emsmdbp_context *emsmdbp_ctx, struct EcDoRpc_MAPI_REQ *mapi_req, struct EcDoRpc_MAPI_REPL *mapi_repl, uint32_t *handles, uint16_t *size) { enum MAPISTATUS retval; struct mapi_handles *folder; struct emsmdbp_object *folder_object; void *data = NULL; uint32_t handle; struct ModifyPermissions_req *request; DEBUG(4, ("exchange_emsmdb: [OXCSTOR] ModifyPermissions (0x40)\n")); /* Sanity checks */ OPENCHANGE_RETVAL_IF(!emsmdbp_ctx, MAPI_E_NOT_INITIALIZED, NULL); OPENCHANGE_RETVAL_IF(!mapi_req, MAPI_E_INVALID_PARAMETER, NULL); OPENCHANGE_RETVAL_IF(!mapi_repl, MAPI_E_INVALID_PARAMETER, NULL); OPENCHANGE_RETVAL_IF(!handles, MAPI_E_INVALID_PARAMETER, NULL); OPENCHANGE_RETVAL_IF(!size, MAPI_E_INVALID_PARAMETER, NULL); mapi_repl->opnum = mapi_req->opnum; mapi_repl->handle_idx = mapi_req->handle_idx; mapi_repl->error_code = MAPI_E_SUCCESS; /* Ensure handle references a folder object */ handle = handles[mapi_req->handle_idx]; retval = mapi_handles_search(emsmdbp_ctx->handles_ctx, handle, &folder); if (retval) { mapi_repl->error_code = MAPI_E_INVALID_OBJECT; DEBUG(5, (" handle (%x) not found: %x\n", handle, mapi_req->handle_idx)); goto end; } retval = mapi_handles_get_private_data(folder, &data); if (retval || !data) { mapi_repl->error_code = MAPI_E_INVALID_OBJECT; DEBUG(5, (" handle data not found, idx = %x\n", mapi_req->handle_idx)); goto end; } folder_object = (struct emsmdbp_object *) data; if (folder_object->type != EMSMDBP_OBJECT_FOLDER) { mapi_repl->error_code = MAPI_E_INVALID_OBJECT; DEBUG(5, (" unhandled object type: %d\n", folder_object->type)); goto end; } request = &mapi_req->u.mapi_ModifyPermissions; if (emsmdbp_is_mapistore(folder_object)) { retval = mapistore_folder_modify_permissions(emsmdbp_ctx->mstore_ctx, emsmdbp_get_contextID(folder_object), folder_object->backend_object, request->rowList.ModifyFlags, request->rowList.ModifyCount, request->rowList.PermissionsData); } else { mapi_repl->error_code = MAPI_E_NOT_FOUND; } end: *size += libmapiserver_RopModifyPermissions_size(mapi_repl); return MAPI_E_SUCCESS; } openchange-2.0/mapiproxy/servers/default/emsmdb/oxcprpt.c000066400000000000000000001410361223057412600237500ustar00rootroot00000000000000/* OpenChange Server implementation EMSMDBP: EMSMDB Provider implementation Copyright (C) Julien Kerihuel 2009 This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see . */ /** \file oxcprpt.c \brief Property and Stream Object routines and Rops */ #include #include #include #include "libmapi/libmapi.h" #include "mapiproxy/dcesrv_mapiproxy.h" #include "mapiproxy/libmapiproxy/libmapiproxy.h" #include "mapiproxy/libmapiserver/libmapiserver.h" #include "dcesrv_exchange_emsmdb.h" /** \details EcDoRpc GetPropertiesSpecific (0x07) Rop. This operation retrieves from properties data from specified object. \param mem_ctx pointer to the memory context \param emsmdbp_ctx pointer to the emsmdb provider context \param mapi_req pointer to the GetPropertiesSpecific EcDoRpc_MAPI_REQ structure \param mapi_repl pointer to the GetPropertiesSpecific EcDoRpc_MAPI_REPL structure \param handles pointer to the MAPI handles array \param size pointer to the mapi_response size to update \return MAPI_E_SUCCESS on success, otherwise MAPI error */ _PUBLIC_ enum MAPISTATUS EcDoRpc_RopGetPropertiesSpecific(TALLOC_CTX *mem_ctx, struct emsmdbp_context *emsmdbp_ctx, struct EcDoRpc_MAPI_REQ *mapi_req, struct EcDoRpc_MAPI_REPL *mapi_repl, uint32_t *handles, uint16_t *size) { enum MAPISTATUS retval; struct GetProps_req *request; struct GetProps_repl *response; uint32_t handle; uint16_t property_id, property_type; struct mapi_handles *rec = NULL; void *private_data = NULL; struct emsmdbp_object *object; struct SPropTagArray *properties; void **data_pointers; enum MAPISTATUS *retvals = NULL; bool *untyped_status; uint16_t i, propType; uint32_t stream_size; struct emsmdbp_stream_data *stream_data; DEBUG(4, ("exchange_emsmdb: [OXCPRPT] GetPropertiesSpecific (0x07)\n")); /* Sanity checks */ OPENCHANGE_RETVAL_IF(!emsmdbp_ctx, MAPI_E_NOT_INITIALIZED, NULL); OPENCHANGE_RETVAL_IF(!mapi_req, MAPI_E_INVALID_PARAMETER, NULL); OPENCHANGE_RETVAL_IF(!mapi_repl, MAPI_E_INVALID_PARAMETER, NULL); OPENCHANGE_RETVAL_IF(!handles, MAPI_E_INVALID_PARAMETER, NULL); OPENCHANGE_RETVAL_IF(!size, MAPI_E_INVALID_PARAMETER, NULL); request = &mapi_req->u.mapi_GetProps; response = &mapi_repl->u.mapi_GetProps; /* Initialize GetProps response blob */ response->prop_data.length = 0; response->prop_data.data = NULL; /* Fill EcDoRpc_MAPI_REPL reply */ mapi_repl->opnum = mapi_req->opnum; mapi_repl->handle_idx = mapi_req->handle_idx; mapi_repl->error_code = MAPI_E_NOT_FOUND; handle = handles[mapi_req->handle_idx]; retval = mapi_handles_search(emsmdbp_ctx->handles_ctx, handle, &rec); if (retval) { mapi_repl->error_code = MAPI_E_INVALID_OBJECT; DEBUG(5, (" handle (%x) not found: %x\n", handle, mapi_req->handle_idx)); goto end; } retval = mapi_handles_get_private_data(rec, &private_data); object = private_data; if (!object) { mapi_repl->error_code = MAPI_E_INVALID_OBJECT; DEBUG(5, (" object (%x) not found: %x\n", handle, mapi_req->handle_idx)); goto end; } if (!(object->type == EMSMDBP_OBJECT_MAILBOX || object->type == EMSMDBP_OBJECT_FOLDER || object->type == EMSMDBP_OBJECT_MESSAGE || object->type == EMSMDBP_OBJECT_ATTACHMENT)) { mapi_repl->error_code = MAPI_E_INVALID_OBJECT; DEBUG(5, (" GetProperties cannot occur on an object of type '%s' (%d)\n", emsmdbp_getstr_type(object), object->type)); goto end; } properties = talloc_zero(NULL, struct SPropTagArray); properties->cValues = request->prop_count; properties->aulPropTag = talloc_array(properties, enum MAPITAGS, request->prop_count); untyped_status = talloc_array(NULL, bool, request->prop_count); for (i = 0; i < request->prop_count; i++) { properties->aulPropTag[i] = request->properties[i]; if ((request->properties[i] & 0xffff) == 0) { property_id = request->properties[i] >> 16; if (property_id < 0x8000) { property_type = get_property_type(property_id); } else { property_type = 0; mapistore_namedprops_get_nameid_type(emsmdbp_ctx->mstore_ctx->nprops_ctx, property_id, &property_type); } if (property_type) { properties->aulPropTag[i] |= property_type; untyped_status[i] = true; } else { properties->aulPropTag[i] |= PT_ERROR; /* fail with a MAPI_E_NOT_FOUND */ untyped_status[i] = false; } } else { untyped_status[i] = false; } } data_pointers = emsmdbp_object_get_properties(mem_ctx, emsmdbp_ctx, object, properties, &retvals); if (data_pointers) { for (i = 0; i < request->prop_count; i++) { if (retvals[i] == MAPI_E_SUCCESS) { propType = properties->aulPropTag[i] & 0xffff; if (propType == PT_STRING8) { stream_size = strlen((const char *) data_pointers[i]) + 1; } else if (propType == PT_UNICODE) { stream_size = strlen_m_ext((char *) data_pointers[i], CH_UTF8, CH_UTF16LE) * 2 + 2; } else if (propType == PT_BINARY) { stream_size = ((struct Binary_r *) data_pointers[i])->cb; } else { stream_size = 0; } if (stream_size > 8192) { DEBUG(5, ("%s: attaching stream data for property %.8x\n", __FUNCTION__, properties->aulPropTag[i])); stream_data = emsmdbp_stream_data_from_value(object, properties->aulPropTag[i], data_pointers[i], false); if (stream_data) { DLIST_ADD(object->stream_data, stream_data); } /* This will trigger the opening of a property stream from the client. */ retvals[i] = MAPI_E_NOT_ENOUGH_MEMORY; } } } mapi_repl->error_code = MAPI_E_SUCCESS; emsmdbp_fill_row_blob(mem_ctx, emsmdbp_ctx, &response->layout, &response->prop_data, properties, data_pointers, retvals, untyped_status); talloc_free(data_pointers); } talloc_free(properties); talloc_free(retvals); end: *size += libmapiserver_RopGetPropertiesSpecific_size(mapi_req, mapi_repl); return MAPI_E_SUCCESS; } /** \details EcDoRpc GetPropertiesAll (0x08) Rop. This operation gets all the property values for an object. \param mem_ctx pointer to the memory context \param emsmdbp_ctx pointer to the emsmdb provider context \param mapi_req pointer to the GetPropertiesAll EcDoRpc_MAPI_REQ structure \param mapi_repl pointer to the GetPropertiesAll EcDoRpc_MAPI_REPL structure \param handles pointer to the MAPI handles array \param size pointer to the mapi_response size to update \return MAPI_E_SUCCESS on success, otherwise MAPI error */ _PUBLIC_ enum MAPISTATUS EcDoRpc_RopGetPropertiesAll(TALLOC_CTX *mem_ctx, struct emsmdbp_context *emsmdbp_ctx, struct EcDoRpc_MAPI_REQ *mapi_req, struct EcDoRpc_MAPI_REPL *mapi_repl, uint32_t *handles, uint16_t *size) { enum MAPISTATUS retval; enum MAPISTATUS *retvals = NULL; struct GetPropsAll_repl *response; uint32_t handle; struct mapi_handles *rec = NULL; void *private_data = NULL; struct emsmdbp_object *object; struct SPropTagArray *SPropTagArray; struct SPropValue tmp_value; void **data_pointers; int i; DEBUG(4, ("exchange_emsmdb: [OXCPRPT] GetPropertiesAll (0x08)\n")); /* Sanity checks */ OPENCHANGE_RETVAL_IF(!emsmdbp_ctx, MAPI_E_NOT_INITIALIZED, NULL); OPENCHANGE_RETVAL_IF(!mapi_req, MAPI_E_INVALID_PARAMETER, NULL); OPENCHANGE_RETVAL_IF(!mapi_repl, MAPI_E_INVALID_PARAMETER, NULL); OPENCHANGE_RETVAL_IF(!handles, MAPI_E_INVALID_PARAMETER, NULL); OPENCHANGE_RETVAL_IF(!size, MAPI_E_INVALID_PARAMETER, NULL); response = &mapi_repl->u.mapi_GetPropsAll; /* Initialize GetPropsAll response */ response->properties.cValues = 0; response->properties.lpProps = NULL; /* Fill EcDoRpc_MAPI_REPL reply */ mapi_repl->opnum = mapi_req->opnum; mapi_repl->handle_idx = mapi_req->handle_idx; /* mapi_repl->error_code = MAPI_E_NOT_FOUND; */ mapi_repl->error_code = MAPI_E_SUCCESS; handle = handles[mapi_req->handle_idx]; retval = mapi_handles_search(emsmdbp_ctx->handles_ctx, handle, &rec); if (retval) { mapi_repl->error_code = MAPI_E_INVALID_OBJECT; DEBUG(5, (" handle (%x) not found: %x\n", handle, mapi_req->handle_idx)); goto end; } retval = mapi_handles_get_private_data(rec, &private_data); object = private_data; if (!object) { mapi_repl->error_code = MAPI_E_INVALID_OBJECT; DEBUG(5, (" object (%x) not found: %x\n", handle, mapi_req->handle_idx)); goto end; } retval = emsmdbp_object_get_available_properties(mem_ctx, emsmdbp_ctx, object, &SPropTagArray); if (retval) { mapi_repl->error_code = MAPI_E_INVALID_OBJECT; DEBUG(5, (" object (%x) not found: %x\n", handle, mapi_req->handle_idx)); goto end; } data_pointers = emsmdbp_object_get_properties(mem_ctx, emsmdbp_ctx, object, SPropTagArray, &retvals); if (data_pointers) { response->properties.lpProps = talloc_array(mem_ctx, struct mapi_SPropValue, SPropTagArray->cValues); response->properties.cValues = 0; for (i = 0; i < SPropTagArray->cValues; i++) { if (retvals[i] == MAPI_E_SUCCESS) { tmp_value.ulPropTag = SPropTagArray->aulPropTag[i]; if (set_SPropValue(&tmp_value, data_pointers[i])) { cast_mapi_SPropValue(mem_ctx, response->properties.lpProps + response->properties.cValues, &tmp_value); response->properties.cValues++; } } } } end: *size += libmapiserver_RopGetPropertiesAll_size(mapi_repl); return MAPI_E_SUCCESS; } /** \details EcDoRpc GetPropertiesList (0x9) Rop. This operation retrieves the list of MAPI tags for an object. \param mem_ctx pointer to the memory context \param emsmdbp_ctx pointer to the emsmdb provider context \param mapi_req pointer to the SetProperties EcDoRpc_MAPI_REQ structure \param mapi_repl pointer to the SetProperties EcDoRpc_MAPI_REPL structure \param handles pointer to the MAPI handles array \param size pointer to the mapi_response size to update \return MAPI_E_SUCCESS on success, otherwise MAPI error */ _PUBLIC_ enum MAPISTATUS EcDoRpc_RopGetPropertiesList(TALLOC_CTX *mem_ctx, struct emsmdbp_context *emsmdbp_ctx, struct EcDoRpc_MAPI_REQ *mapi_req, struct EcDoRpc_MAPI_REPL *mapi_repl, uint32_t *handles, uint16_t *size) { enum MAPISTATUS retval; struct GetPropList_repl *response; uint32_t handle; struct mapi_handles *rec = NULL; void *private_data = NULL; struct emsmdbp_object *object; struct SPropTagArray *SPropTagArray; DEBUG(4, ("exchange_emsmdb: [OXCPRPT] GetPropertiesList (0x9)\n")); /* Sanity checks */ OPENCHANGE_RETVAL_IF(!emsmdbp_ctx, MAPI_E_NOT_INITIALIZED, NULL); OPENCHANGE_RETVAL_IF(!mapi_req, MAPI_E_INVALID_PARAMETER, NULL); OPENCHANGE_RETVAL_IF(!mapi_repl, MAPI_E_INVALID_PARAMETER, NULL); OPENCHANGE_RETVAL_IF(!handles, MAPI_E_INVALID_PARAMETER, NULL); OPENCHANGE_RETVAL_IF(!size, MAPI_E_INVALID_PARAMETER, NULL); response = &mapi_repl->u.mapi_GetPropList; /* Initialize GetPropList response */ response->count = 0; response->tags = NULL; /* Fill EcDoRpc_MAPI_REPL reply */ mapi_repl->opnum = mapi_req->opnum; mapi_repl->handle_idx = mapi_req->handle_idx; mapi_repl->error_code = MAPI_E_SUCCESS; handle = handles[mapi_req->handle_idx]; retval = mapi_handles_search(emsmdbp_ctx->handles_ctx, handle, &rec); if (retval) { mapi_repl->error_code = MAPI_E_INVALID_OBJECT; DEBUG(5, (" handle (%x) not found: %x\n", handle, mapi_req->handle_idx)); goto end; } retval = mapi_handles_get_private_data(rec, &private_data); object = private_data; if (!object) { mapi_repl->error_code = MAPI_E_INVALID_OBJECT; DEBUG(5, (" object (%x) not found: %x\n", handle, mapi_req->handle_idx)); goto end; } retval = emsmdbp_object_get_available_properties(mem_ctx, emsmdbp_ctx, object, &SPropTagArray); if (retval) { mapi_repl->error_code = MAPI_E_INVALID_OBJECT; DEBUG(5, (" object (%x) not found: %x\n", handle, mapi_req->handle_idx)); goto end; } response->count = SPropTagArray->cValues; response->tags = SPropTagArray->aulPropTag; end: *size += libmapiserver_RopGetPropertiesList_size(mapi_repl); return MAPI_E_SUCCESS; } /** \details EcDoRpc SetProperties (0x0a) Rop. This operation sets property values for an object. \param mem_ctx pointer to the memory context \param emsmdbp_ctx pointer to the emsmdb provider context \param mapi_req pointer to the SetProperties EcDoRpc_MAPI_REQ structure \param mapi_repl pointer to the SetProperties EcDoRpc_MAPI_REPL structure \param handles pointer to the MAPI handles array \param size pointer to the mapi_response size to update \return MAPI_E_SUCCESS on success, otherwise MAPI error */ _PUBLIC_ enum MAPISTATUS EcDoRpc_RopSetProperties(TALLOC_CTX *mem_ctx, struct emsmdbp_context *emsmdbp_ctx, struct EcDoRpc_MAPI_REQ *mapi_req, struct EcDoRpc_MAPI_REPL *mapi_repl, uint32_t *handles, uint16_t *size) { enum MAPISTATUS retval; uint32_t handle; struct mapi_handles *rec = NULL; void *private_data = NULL; struct emsmdbp_object *object; uint16_t i; struct SRow aRow; DEBUG(4, ("exchange_emsmdb: [OXCPRPT] SetProperties (0x0a)\n")); /* Sanity checks */ OPENCHANGE_RETVAL_IF(!emsmdbp_ctx, MAPI_E_NOT_INITIALIZED, NULL); OPENCHANGE_RETVAL_IF(!mapi_req, MAPI_E_INVALID_PARAMETER, NULL); OPENCHANGE_RETVAL_IF(!mapi_repl, MAPI_E_INVALID_PARAMETER, NULL); OPENCHANGE_RETVAL_IF(!handles, MAPI_E_INVALID_PARAMETER, NULL); OPENCHANGE_RETVAL_IF(!size, MAPI_E_INVALID_PARAMETER, NULL); mapi_repl->opnum = mapi_req->opnum; mapi_repl->error_code = MAPI_E_SUCCESS; mapi_repl->handle_idx = mapi_req->handle_idx; mapi_repl->u.mapi_SetProps.PropertyProblemCount = 0; mapi_repl->u.mapi_SetProps.PropertyProblem = NULL; handle = handles[mapi_req->handle_idx]; retval = mapi_handles_search(emsmdbp_ctx->handles_ctx, handle, &rec); if (retval) { mapi_repl->error_code = MAPI_E_INVALID_OBJECT; DEBUG(5, (" handle (%x) not found: %x\n", handle, mapi_req->handle_idx)); goto end; } retval = mapi_handles_get_private_data(rec, &private_data); object = (struct emsmdbp_object *)private_data; if (!object) { mapi_repl->error_code = MAPI_E_NO_SUPPORT; goto end; } if (object->type == EMSMDBP_OBJECT_MESSAGE && !object->object.message->read_write) { mapi_repl->error_code = MAPI_E_NO_ACCESS; goto end; } aRow.cValues = mapi_req->u.mapi_SetProps.values.cValues; aRow.lpProps = talloc_array(mem_ctx, struct SPropValue, aRow.cValues + 2); for (i = 0; i < mapi_req->u.mapi_SetProps.values.cValues; i++) { cast_SPropValue(aRow.lpProps, &(mapi_req->u.mapi_SetProps.values.lpProps[i]), &(aRow.lpProps[i])); } retval = emsmdbp_object_set_properties(emsmdbp_ctx, object, &aRow); if (retval) { mapi_repl->error_code = MAPI_E_NO_SUPPORT; goto end; } end: *size += libmapiserver_RopSetProperties_size(mapi_repl); return MAPI_E_SUCCESS; } /** \details EcDoRpc DeleteProperties (0x0b) Rop. This operation deletes property values for an object. \param mem_ctx pointer to the memory context \param emsmdbp_ctx pointer to the emsmdb provider context \param mapi_req pointer to the DeleteProperties EcDoRpc_MAPI_REQ structure \param mapi_repl pointer to the DeleteProperties EcDoRpc_MAPI_REPL structure \param handles pointer to the MAPI handles array \param size pointer to the mapi_response size to update \return MAPI_E_SUCCESS on success, otherwise MAPI error */ _PUBLIC_ enum MAPISTATUS EcDoRpc_RopDeleteProperties(TALLOC_CTX *mem_ctx, struct emsmdbp_context *emsmdbp_ctx, struct EcDoRpc_MAPI_REQ *mapi_req, struct EcDoRpc_MAPI_REPL *mapi_repl, uint32_t *handles, uint16_t *size) { DEBUG(4, ("exchange_emsmdb: [OXCPRPT] DeleteProperties (0x0b) -- stub\n")); /* Sanity checks */ OPENCHANGE_RETVAL_IF(!emsmdbp_ctx, MAPI_E_NOT_INITIALIZED, NULL); OPENCHANGE_RETVAL_IF(!mapi_req, MAPI_E_INVALID_PARAMETER, NULL); OPENCHANGE_RETVAL_IF(!mapi_repl, MAPI_E_INVALID_PARAMETER, NULL); OPENCHANGE_RETVAL_IF(!handles, MAPI_E_INVALID_PARAMETER, NULL); OPENCHANGE_RETVAL_IF(!size, MAPI_E_INVALID_PARAMETER, NULL); mapi_repl->opnum = mapi_req->opnum; mapi_repl->error_code = MAPI_E_SUCCESS; mapi_repl->handle_idx = mapi_req->handle_idx; mapi_repl->u.mapi_DeleteProps.PropertyProblemCount = 0; mapi_repl->u.mapi_DeleteProps.PropertyProblem = NULL; *size += libmapiserver_RopDeleteProperties_size(mapi_repl); return MAPI_E_SUCCESS; } /** \details EcDoRpc OpenStream (0x2b) Rop. This operation opens a property for streaming access. \param mem_ctx pointer to the memory context \param emsmdbp_ctx pointer to the emsmdb provider context \param mapi_req pointer to the OpenStream EcDoRpc_MAPI_REQ structure \param mapi_repl pointer to the OpenStream EcDoRpc_MAPI_REPL structure \param handles pointer to the MAPI handles array \param size pointer to the mapi response size to update \return MAPI_E_SUCCESS on success, otherwise MAPI error */ _PUBLIC_ enum MAPISTATUS EcDoRpc_RopOpenStream(TALLOC_CTX *mem_ctx, struct emsmdbp_context *emsmdbp_ctx, struct EcDoRpc_MAPI_REQ *mapi_req, struct EcDoRpc_MAPI_REPL *mapi_repl, uint32_t *handles, uint16_t *size) { enum MAPISTATUS retval; struct mapi_handles *parent = NULL; struct mapi_handles *rec = NULL; struct emsmdbp_object *object = NULL; struct emsmdbp_object *parent_object = NULL; struct OpenStream_req *request; uint32_t handle; void *data; struct SPropTagArray properties; void **data_pointers; enum MAPISTATUS *retvals; struct emsmdbp_stream_data *stream_data; enum OpenStream_OpenModeFlags mode; DEBUG(4, ("exchange_emsmdb: [OXCPRPT] OpenStream (0x2b)\n")); /* Sanity checks */ OPENCHANGE_RETVAL_IF(!emsmdbp_ctx, MAPI_E_NOT_INITIALIZED, NULL); OPENCHANGE_RETVAL_IF(!mapi_req, MAPI_E_INVALID_PARAMETER, NULL); OPENCHANGE_RETVAL_IF(!mapi_repl, MAPI_E_INVALID_PARAMETER, NULL); OPENCHANGE_RETVAL_IF(!handles, MAPI_E_INVALID_PARAMETER, NULL); OPENCHANGE_RETVAL_IF(!size, MAPI_E_INVALID_PARAMETER, NULL); mapi_repl->opnum = mapi_req->opnum; mapi_repl->error_code = MAPI_E_SUCCESS; mapi_repl->handle_idx = mapi_req->u.mapi_OpenStream.handle_idx; mapi_repl->u.mapi_OpenStream.StreamSize = 0; /* Step 1. Retrieve parent handle in the hierarchy */ handle = handles[mapi_req->handle_idx]; retval = mapi_handles_search(emsmdbp_ctx->handles_ctx, handle, &parent); if (retval) { mapi_repl->error_code = MAPI_E_INVALID_OBJECT; DEBUG(5, (" handle (%x) not found: %x\n", handle, mapi_req->handle_idx)); goto end; } mapi_handles_get_private_data(parent, &data); parent_object = (struct emsmdbp_object *) data; if (!(parent_object->type == EMSMDBP_OBJECT_FOLDER || parent_object->type == EMSMDBP_OBJECT_MESSAGE || parent_object->type == EMSMDBP_OBJECT_ATTACHMENT)) { mapi_repl->error_code = MAPI_E_NO_SUPPORT; goto end; } request = &mapi_req->u.mapi_OpenStream; mode = request->OpenModeFlags; if (mode == OpenStream_BestAccess) { if (parent_object->type == EMSMDBP_OBJECT_MESSAGE) { if (parent_object->object.message->read_write) { mode = OpenStream_ReadWrite; } else { mode = OpenStream_ReadOnly; } } else { mode = OpenStream_ReadOnly; } } if (parent_object->type == EMSMDBP_OBJECT_MESSAGE && !parent_object->object.message->read_write && (mode == OpenStream_ReadWrite || mode == OpenStream_Create)) { mapi_repl->error_code = MAPI_E_NO_ACCESS; goto end; } if (request->PropertyTag == PidTagSecurityDescriptorAsXml) { /* exception; see oxcperm - 3.1.4.1 Retrieving Folder Permissions */ mapi_repl->error_code = MAPI_E_NO_SUPPORT; /* ecNotImplemented = MAPI_E_NO_SUPPORT */ goto end; } /* TODO: implementation status: - OpenStream_ReadOnly (supported) - OpenStream_ReadWrite (supported) - OpenStream_Create (supported) - OpenStream_BestAccess */ object = emsmdbp_object_stream_init(NULL, emsmdbp_ctx, parent_object); object->object.stream->property = request->PropertyTag; object->object.stream->stream.position = 0; object->object.stream->stream.buffer.length = 0; if (mode == OpenStream_ReadOnly || mode == OpenStream_ReadWrite) { object->object.stream->read_write = (mode == OpenStream_ReadWrite); stream_data = emsmdbp_object_get_stream_data(parent_object, object->object.stream->property); if (stream_data) { object->object.stream->stream.buffer = stream_data->data; (void) talloc_reference(object->object.stream, object->object.stream->stream.buffer.data); DLIST_REMOVE(parent_object->stream_data, stream_data); talloc_free(stream_data); } else { properties.cValues = 1; properties.aulPropTag = &request->PropertyTag; data_pointers = emsmdbp_object_get_properties(mem_ctx, emsmdbp_ctx, parent_object, &properties, &retvals); if (data_pointers == NULL) { mapi_repl->error_code = MAPI_E_INVALID_OBJECT; talloc_free(object); goto end; } if (retvals[0] == MAPI_E_SUCCESS) { stream_data = emsmdbp_stream_data_from_value(data_pointers, request->PropertyTag, data_pointers[0], object->object.stream->read_write); object->object.stream->stream.buffer = stream_data->data; (void) talloc_reference(object, stream_data); talloc_free(data_pointers); talloc_free(retvals); } else { mapi_repl->error_code = retvals[0]; talloc_free(data_pointers); talloc_free(retvals); talloc_free(object); goto end; } } } else { /* OpenStream_Create */ object->object.stream->read_write = true; object->object.stream->stream.buffer.data = talloc_zero(object->object.stream, uint8_t); object->object.stream->stream.buffer.length = 0; } mapi_repl->u.mapi_OpenStream.StreamSize = object->object.stream->stream.buffer.length; retval = mapi_handles_add(emsmdbp_ctx->handles_ctx, handle, &rec); (void) talloc_reference(rec, object); handles[mapi_repl->handle_idx] = rec->handle; mapi_handles_set_private_data(rec, object); talloc_free(object); end: *size += libmapiserver_RopOpenStream_size(mapi_repl); return MAPI_E_SUCCESS; } /** \details EcDoRpc ReadStream (0x2c) Rop. This operation reads bytes from a stream. \param mem_ctx pointer to the memory context \param emsmdbp_ctx pointer to the emsmdb provider context \param mapi_req pointer to the ReadStream EcDoRpc_MAPI_REQ structure \param mapi_repl pointer to the ReadStream EcDoRpc_MAPI_REPL structure \param handles pointer to the MAPI handles array \param size pointer to the mapi response size to update \return MAPI_E_SUCCESS on success, otherwise MAPI error */ _PUBLIC_ enum MAPISTATUS EcDoRpc_RopReadStream(TALLOC_CTX *mem_ctx, struct emsmdbp_context *emsmdbp_ctx, struct EcDoRpc_MAPI_REQ *mapi_req, struct EcDoRpc_MAPI_REPL *mapi_repl, uint32_t *handles, uint16_t *size) { enum MAPISTATUS retval; struct mapi_handles *rec = NULL; void *private_data; struct emsmdbp_object *object; uint32_t handle, buffer_size; DEBUG(4, ("exchange_emsmdb: [OXCPRPT] ReadStream (0x2c)\n")); /* Sanity checks */ OPENCHANGE_RETVAL_IF(!emsmdbp_ctx, MAPI_E_NOT_INITIALIZED, NULL); OPENCHANGE_RETVAL_IF(!mapi_req, MAPI_E_INVALID_PARAMETER, NULL); OPENCHANGE_RETVAL_IF(!mapi_repl, MAPI_E_INVALID_PARAMETER, NULL); OPENCHANGE_RETVAL_IF(!handles, MAPI_E_INVALID_PARAMETER, NULL); OPENCHANGE_RETVAL_IF(!size, MAPI_E_INVALID_PARAMETER, NULL); mapi_repl->opnum = mapi_req->opnum; mapi_repl->error_code = MAPI_E_SUCCESS; mapi_repl->handle_idx = mapi_req->handle_idx; mapi_repl->u.mapi_ReadStream.data.length = 0; mapi_repl->u.mapi_ReadStream.data.data = NULL; /* Step 1. Retrieve parent handle in the hierarchy */ handle = handles[mapi_req->handle_idx]; retval = mapi_handles_search(emsmdbp_ctx->handles_ctx, handle, &rec); if (retval) { mapi_repl->error_code = MAPI_E_INVALID_OBJECT; DEBUG(5, (" handle (%x) not found: %x\n", handle, mapi_req->handle_idx)); goto end; } /* Step 2. Retrieve the stream object */ retval = mapi_handles_get_private_data(rec, &private_data); object = (struct emsmdbp_object *) private_data; if (!object || object->type != EMSMDBP_OBJECT_STREAM) { mapi_repl->error_code = MAPI_E_INVALID_OBJECT; DEBUG(5, (" invalid object\n")); goto end; } /* Step 3. Return the data and update the position in the stream */ buffer_size = mapi_req->u.mapi_ReadStream.ByteCount; /* careful here, let's switch to idiot mode */ if (buffer_size == 0xBABE) { buffer_size = mapi_req->u.mapi_ReadStream.MaximumByteCount.value; } mapi_repl->u.mapi_ReadStream.data = emsmdbp_stream_read_buffer(&object->object.stream->stream, buffer_size); end: *size += libmapiserver_RopReadStream_size(mapi_repl); return MAPI_E_SUCCESS; } /** \details EcDoRpc WriteStream (0x2d) Rop. This operation writes bytes to a stream. \param mem_ctx pointer to the memory context \param emsmdbp_ctx pointer to the emsmdb provider context \param mapi_req pointer to the WriteStream EcDoRpc_MAPI_REQ structure \param mapi_repl pointer to the WriteStream EcDoRpc_MAPI_REPL structure \param handles pointer to the MAPI handles array \param size pointer to the mapi response size to update \return MAPI_E_SUCCESS on success, otherwise MAPI error */ _PUBLIC_ enum MAPISTATUS EcDoRpc_RopWriteStream(TALLOC_CTX *mem_ctx, struct emsmdbp_context *emsmdbp_ctx, struct EcDoRpc_MAPI_REQ *mapi_req, struct EcDoRpc_MAPI_REPL *mapi_repl, uint32_t *handles, uint16_t *size) { enum MAPISTATUS retval; struct mapi_handles *parent = NULL; void *private_data; struct emsmdbp_object *object; uint32_t handle; struct WriteStream_req *request; DEBUG(4, ("exchange_emsmdb: [OXCPRPT] WriteStream (0x2d)\n")); /* Sanity checks */ OPENCHANGE_RETVAL_IF(!emsmdbp_ctx, MAPI_E_NOT_INITIALIZED, NULL); OPENCHANGE_RETVAL_IF(!mapi_req, MAPI_E_INVALID_PARAMETER, NULL); OPENCHANGE_RETVAL_IF(!mapi_repl, MAPI_E_INVALID_PARAMETER, NULL); OPENCHANGE_RETVAL_IF(!handles, MAPI_E_INVALID_PARAMETER, NULL); OPENCHANGE_RETVAL_IF(!size, MAPI_E_INVALID_PARAMETER, NULL); mapi_repl->opnum = mapi_req->opnum; mapi_repl->error_code = MAPI_E_SUCCESS; mapi_repl->handle_idx = mapi_req->handle_idx; mapi_repl->u.mapi_WriteStream.WrittenSize = 0; /* Step 1. Retrieve parent handle in the hierarchy */ handle = handles[mapi_req->handle_idx]; retval = mapi_handles_search(emsmdbp_ctx->handles_ctx, handle, &parent); if (retval) { mapi_repl->error_code = MAPI_E_INVALID_OBJECT; DEBUG(5, (" handle (%x) not found: %x\n", handle, mapi_req->handle_idx)); goto end; } retval = mapi_handles_get_private_data(parent, &private_data); object = (struct emsmdbp_object *) private_data; if (!object || object->type != EMSMDBP_OBJECT_STREAM) { mapi_repl->error_code = MAPI_E_INVALID_OBJECT; DEBUG(5, (" invalid object\n")); goto end; } if (!object->object.stream->read_write) { mapi_repl->error_code = MAPI_E_NO_ACCESS; goto end; } request = &mapi_req->u.mapi_WriteStream; if (request->data.length > 0) { emsmdbp_stream_write_buffer(object->object.stream, &object->object.stream->stream, request->data); mapi_repl->u.mapi_WriteStream.WrittenSize = request->data.length; } object->object.stream->needs_commit = true; end: *size += libmapiserver_RopWriteStream_size(mapi_repl); return MAPI_E_SUCCESS; } /** \details EcDoRpc CommitStream (0x5d) Rop. \param mem_ctx pointer to the memory context \param emsmdbp_ctx pointer to the emsmdb provider context \param mapi_req pointer to the DeleteProperties EcDoRpc_MAPI_REQ structure \param mapi_repl pointer to the DeleteProperties EcDoRpc_MAPI_REPL structure \param handles pointer to the MAPI handles array \param size pointer to the mapi_response size to update \return MAPI_E_SUCCESS on success, otherwise MAPI error */ _PUBLIC_ enum MAPISTATUS EcDoRpc_RopCommitStream(TALLOC_CTX *mem_ctx, struct emsmdbp_context *emsmdbp_ctx, struct EcDoRpc_MAPI_REQ *mapi_req, struct EcDoRpc_MAPI_REPL *mapi_repl, uint32_t *handles, uint16_t *size) { enum MAPISTATUS retval; struct mapi_handles *rec = NULL; struct emsmdbp_object *object = NULL; uint32_t handle; void *private_data; DEBUG(4, ("exchange_emsmdb: [OXCPRPT] CommitStream (0x5d)\n")); /* Sanity checks */ OPENCHANGE_RETVAL_IF(!emsmdbp_ctx, MAPI_E_NOT_INITIALIZED, NULL); OPENCHANGE_RETVAL_IF(!mapi_req, MAPI_E_INVALID_PARAMETER, NULL); OPENCHANGE_RETVAL_IF(!mapi_repl, MAPI_E_INVALID_PARAMETER, NULL); OPENCHANGE_RETVAL_IF(!handles, MAPI_E_INVALID_PARAMETER, NULL); OPENCHANGE_RETVAL_IF(!size, MAPI_E_INVALID_PARAMETER, NULL); mapi_repl->opnum = mapi_req->opnum; mapi_repl->error_code = MAPI_E_SUCCESS; mapi_repl->handle_idx = mapi_req->handle_idx; /* Step 1. Retrieve parent handle in the hierarchy */ handle = handles[mapi_req->handle_idx]; retval = mapi_handles_search(emsmdbp_ctx->handles_ctx, handle, &rec); if (retval) { mapi_repl->error_code = MAPI_E_INVALID_OBJECT; DEBUG(5, (" handle (%x) not found: %x\n", handle, mapi_req->handle_idx)); goto end; } retval = mapi_handles_get_private_data(rec, &private_data); object = (struct emsmdbp_object *) private_data; if (!object || object->type != EMSMDBP_OBJECT_STREAM) { mapi_repl->error_code = MAPI_E_INVALID_OBJECT; DEBUG(5, (" invalid object\n")); goto end; } if (!object->object.stream->read_write) { mapi_repl->error_code = MAPI_E_NO_ACCESS; goto end; } emsmdbp_object_stream_commit(object); end: *size += libmapiserver_RopCommitStream_size(mapi_repl); return MAPI_E_SUCCESS; } /** \details EcDoRpc GetStreamSize (0x5e) Rop. This operation returns the number of bytes in a stream. \param mem_ctx pointer to the memory context \param emsmdbp_ctx pointer to the emsmdb provider context \param mapi_req pointer to the WriteStream EcDoRpc_MAPI_REQ structure \param mapi_repl pointer to the WriteStream EcDoRpc_MAPI_REPL structure \param handles pointer to the MAPI handles array \param size pointer to the mapi response size to update \return MAPI_E_SUCCESS on success, otherwise MAPI error */ _PUBLIC_ enum MAPISTATUS EcDoRpc_RopGetStreamSize(TALLOC_CTX *mem_ctx, struct emsmdbp_context *emsmdbp_ctx, struct EcDoRpc_MAPI_REQ *mapi_req, struct EcDoRpc_MAPI_REPL *mapi_repl, uint32_t *handles, uint16_t *size) { enum MAPISTATUS retval; struct mapi_handles *parent = NULL; void *private_data; struct emsmdbp_object *object = NULL; uint32_t handle; DEBUG(4, ("exchange_emsmdb: [OXCPRPT] GetStreamSize (0x5e)\n")); /* Sanity checks */ OPENCHANGE_RETVAL_IF(!emsmdbp_ctx, MAPI_E_NOT_INITIALIZED, NULL); OPENCHANGE_RETVAL_IF(!mapi_req, MAPI_E_INVALID_PARAMETER, NULL); OPENCHANGE_RETVAL_IF(!mapi_repl, MAPI_E_INVALID_PARAMETER, NULL); OPENCHANGE_RETVAL_IF(!handles, MAPI_E_INVALID_PARAMETER, NULL); OPENCHANGE_RETVAL_IF(!size, MAPI_E_INVALID_PARAMETER, NULL); mapi_repl->opnum = mapi_req->opnum; mapi_repl->error_code = MAPI_E_SUCCESS; mapi_repl->handle_idx = mapi_req->handle_idx; /* Step 1. Retrieve parent handle in the hierarchy */ handle = handles[mapi_req->handle_idx]; retval = mapi_handles_search(emsmdbp_ctx->handles_ctx, handle, &parent); if (retval) { mapi_repl->error_code = MAPI_E_INVALID_OBJECT; DEBUG(5, (" handle (%x) not found: %x\n", handle, mapi_req->handle_idx)); goto end; } retval = mapi_handles_get_private_data(parent, &private_data); object = (struct emsmdbp_object *) private_data; if (!object || object->type != EMSMDBP_OBJECT_STREAM) { mapi_repl->error_code = MAPI_E_INVALID_OBJECT; DEBUG(5, (" invalid object\n")); goto end; } mapi_repl->u.mapi_GetStreamSize.StreamSize = object->object.stream->stream.buffer.length; end: *size += libmapiserver_RopGetStreamSize_size(mapi_repl); return MAPI_E_SUCCESS; } /** \details EcDoRpc SeekStream (0x2e) Rop. This operation positions the cursor in the stream. \param mem_ctx pointer to the memory context \param emsmdbp_ctx pointer to the emsmdb provider context \param mapi_req pointer to the WriteStream EcDoRpc_MAPI_REQ structure \param mapi_repl pointer to the WriteStream EcDoRpc_MAPI_REPL structure \param handles pointer to the MAPI handles array \param size pointer to the mapi response size to update \return MAPI_E_SUCCESS on success, otherwise MAPI error */ _PUBLIC_ enum MAPISTATUS EcDoRpc_RopSeekStream(TALLOC_CTX *mem_ctx, struct emsmdbp_context *emsmdbp_ctx, struct EcDoRpc_MAPI_REQ *mapi_req, struct EcDoRpc_MAPI_REPL *mapi_repl, uint32_t *handles, uint16_t *size) { enum MAPISTATUS retval; struct mapi_handles *parent = NULL; void *private_data; struct emsmdbp_object *object = NULL; uint32_t handle, new_position; DEBUG(4, ("exchange_emsmdb: [OXCPRPT] SeekStream (0x2e)\n")); /* Sanity checks */ OPENCHANGE_RETVAL_IF(!emsmdbp_ctx, MAPI_E_NOT_INITIALIZED, NULL); OPENCHANGE_RETVAL_IF(!mapi_req, MAPI_E_INVALID_PARAMETER, NULL); OPENCHANGE_RETVAL_IF(!mapi_repl, MAPI_E_INVALID_PARAMETER, NULL); OPENCHANGE_RETVAL_IF(!handles, MAPI_E_INVALID_PARAMETER, NULL); OPENCHANGE_RETVAL_IF(!size, MAPI_E_INVALID_PARAMETER, NULL); mapi_repl->opnum = mapi_req->opnum; mapi_repl->error_code = MAPI_E_SUCCESS; mapi_repl->handle_idx = mapi_req->handle_idx; /* Step 1. Retrieve parent handle in the hierarchy */ handle = handles[mapi_req->handle_idx]; retval = mapi_handles_search(emsmdbp_ctx->handles_ctx, handle, &parent); if (retval) { mapi_repl->error_code = MAPI_E_INVALID_OBJECT; DEBUG(5, (" handle (%x) not found: %x\n", handle, mapi_req->handle_idx)); goto end; } retval = mapi_handles_get_private_data(parent, &private_data); object = (struct emsmdbp_object *) private_data; if (!object || object->type != EMSMDBP_OBJECT_STREAM) { mapi_repl->error_code = MAPI_E_INVALID_OBJECT; DEBUG(5, (" invalid object\n")); goto end; } switch (mapi_req->u.mapi_SeekStream.Origin) { case 0: /* beginning */ new_position = 0; break; case 1: /* current */ new_position = object->object.stream->stream.position; break; case 2: /* end */ new_position = object->object.stream->stream.buffer.length; break; default: mapi_repl->error_code = MAPI_E_INVALID_PARAMETER; goto end; } new_position += mapi_req->u.mapi_SeekStream.Offset; if (new_position < object->object.stream->stream.buffer.length + 1) { object->object.stream->stream.position = new_position; mapi_repl->u.mapi_SeekStream.NewPosition = new_position; } else { mapi_repl->error_code = MAPI_E_DISK_ERROR; } end: *size += libmapiserver_RopSeekStream_size(mapi_repl); return MAPI_E_SUCCESS; } /** \details EcDoRpc SetStreamSize (0x2f) Rop. This operation copy messages from one folder to another. \param mem_ctx pointer to the memory context \param emsmdbp_ctx pointer to the emsmdb provider context \param mapi_req pointer to the DeleteProperties EcDoRpc_MAPI_REQ structure \param mapi_repl pointer to the DeleteProperties EcDoRpc_MAPI_REPL structure \param handles pointer to the MAPI handles array \param size pointer to the mapi_response size to update \return MAPI_E_SUCCESS on success, otherwise MAPI error */ _PUBLIC_ enum MAPISTATUS EcDoRpc_RopSetStreamSize(TALLOC_CTX *mem_ctx, struct emsmdbp_context *emsmdbp_ctx, struct EcDoRpc_MAPI_REQ *mapi_req, struct EcDoRpc_MAPI_REPL *mapi_repl, uint32_t *handles, uint16_t *size) { enum MAPISTATUS retval; struct mapi_handles *parent = NULL; void *private_data; struct emsmdbp_object *object; uint32_t handle; DEBUG(4, ("exchange_emsmdb: [OXCPRPT] SetStreamSize (0x2f)\n")); /* Sanity checks */ OPENCHANGE_RETVAL_IF(!emsmdbp_ctx, MAPI_E_NOT_INITIALIZED, NULL); OPENCHANGE_RETVAL_IF(!mapi_req, MAPI_E_INVALID_PARAMETER, NULL); OPENCHANGE_RETVAL_IF(!mapi_repl, MAPI_E_INVALID_PARAMETER, NULL); OPENCHANGE_RETVAL_IF(!handles, MAPI_E_INVALID_PARAMETER, NULL); OPENCHANGE_RETVAL_IF(!size, MAPI_E_INVALID_PARAMETER, NULL); mapi_repl->opnum = mapi_req->opnum; mapi_repl->error_code = MAPI_E_SUCCESS; mapi_repl->handle_idx = mapi_req->handle_idx; mapi_repl->u.mapi_WriteStream.WrittenSize = 0; /* Step 1. Retrieve parent handle in the hierarchy */ handle = handles[mapi_req->handle_idx]; retval = mapi_handles_search(emsmdbp_ctx->handles_ctx, handle, &parent); if (retval) { mapi_repl->error_code = MAPI_E_INVALID_OBJECT; DEBUG(5, (" handle (%x) not found: %x\n", handle, mapi_req->handle_idx)); goto end; } retval = mapi_handles_get_private_data(parent, &private_data); object = (struct emsmdbp_object *) private_data; if (!object || object->type != EMSMDBP_OBJECT_STREAM) { mapi_repl->error_code = MAPI_E_INVALID_OBJECT; DEBUG(5, (" invalid object\n")); goto end; } end: *size += libmapiserver_RopSetStreamSize_size(mapi_repl); return MAPI_E_SUCCESS; } /** \details EcDoRpc GetPropertyIdsFromNames (0x56) Rop. This operation gets property IDs for specified property names. \param mem_ctx pointer to the memory context \param emsmdbp_ctx pointer to the emsmdb provider context \param mapi_req pointer to the GetPropertyIdsFromNames EcDoRpc_MAPI_REQ structure \param mapi_repl pointer to the GetPropertyIdsFromNames EcDoRpc_MAPI_REPL structure \param handles pointer to the MAPI handles array \param size pointer to the mapi_response size to update \return MAPI_E_SUCCESS on success, otherwise MAPI error */ _PUBLIC_ enum MAPISTATUS EcDoRpc_RopGetPropertyIdsFromNames(TALLOC_CTX *mem_ctx, struct emsmdbp_context *emsmdbp_ctx, struct EcDoRpc_MAPI_REQ *mapi_req, struct EcDoRpc_MAPI_REPL *mapi_repl, uint32_t *handles, uint16_t *size) { int i, ret; struct GUID *lpguid; bool has_transaction = false; uint16_t mapped_id; DEBUG(4, ("exchange_emsmdb: [OXCPRPT] GetPropertyIdsFromNames (0x56)\n")); /* Sanity checks */ OPENCHANGE_RETVAL_IF(!emsmdbp_ctx, MAPI_E_NOT_INITIALIZED, NULL); OPENCHANGE_RETVAL_IF(!mapi_req, MAPI_E_INVALID_PARAMETER, NULL); OPENCHANGE_RETVAL_IF(!mapi_repl, MAPI_E_INVALID_PARAMETER, NULL); OPENCHANGE_RETVAL_IF(!handles, MAPI_E_INVALID_PARAMETER, NULL); OPENCHANGE_RETVAL_IF(!size, MAPI_E_INVALID_PARAMETER, NULL); mapi_repl->opnum = mapi_req->opnum; mapi_repl->error_code = MAPI_E_SUCCESS; mapi_repl->handle_idx = mapi_req->handle_idx; mapi_repl->u.mapi_GetIDsFromNames.count = mapi_req->u.mapi_GetIDsFromNames.count; mapi_repl->u.mapi_GetIDsFromNames.propID = talloc_array(mem_ctx, uint16_t, mapi_req->u.mapi_GetIDsFromNames.count); for (i = 0; i < mapi_req->u.mapi_GetIDsFromNames.count; i++) { ret = mapistore_namedprops_get_mapped_id(emsmdbp_ctx->mstore_ctx->nprops_ctx, mapi_req->u.mapi_GetIDsFromNames.nameid[i], &mapi_repl->u.mapi_GetIDsFromNames.propID[i]); if (ret != MAPISTORE_SUCCESS) { if (mapi_req->u.mapi_GetIDsFromNames.ulFlags == GetIDsFromNames_GetOrCreate) { if (!has_transaction) { has_transaction = true; ldb_transaction_start(emsmdbp_ctx->mstore_ctx->nprops_ctx); mapped_id = mapistore_namedprops_next_unused_id(emsmdbp_ctx->mstore_ctx->nprops_ctx); if (mapped_id == 0) { abort(); } } else { mapped_id++; } mapistore_namedprops_create_id(emsmdbp_ctx->mstore_ctx->nprops_ctx, mapi_req->u.mapi_GetIDsFromNames.nameid[i], mapped_id); mapi_repl->u.mapi_GetIDsFromNames.propID[i] = mapped_id; } else { mapi_repl->u.mapi_GetIDsFromNames.propID[i] = 0x0000; lpguid = &mapi_req->u.mapi_GetIDsFromNames.nameid[i].lpguid; DEBUG(5, (" no mapping for property %.8x-%.4x-%.4x-%.2x%.2x-%.2x%.2x%.2x%.2x%.2x%.2x:", lpguid->time_low, lpguid->time_mid, lpguid->time_hi_and_version, lpguid->clock_seq[0], lpguid->clock_seq[1], lpguid->node[0], lpguid->node[1], lpguid->node[2], lpguid->node[3], lpguid->node[4], lpguid->node[5])); if (mapi_req->u.mapi_GetIDsFromNames.nameid[i].ulKind == MNID_ID) DEBUG(5, ("%.4x\n", mapi_req->u.mapi_GetIDsFromNames.nameid[i].kind.lid)); else if (mapi_req->u.mapi_GetIDsFromNames.nameid[i].ulKind == MNID_STRING) DEBUG(5, ("%s\n", mapi_req->u.mapi_GetIDsFromNames.nameid[i].kind.lpwstr.Name)); else DEBUG(5, ("[invalid ulKind]")); mapi_repl->error_code = MAPI_W_ERRORS_RETURNED; } } } if (has_transaction) { ldb_transaction_commit(emsmdbp_ctx->mstore_ctx->nprops_ctx); } *size += libmapiserver_RopGetPropertyIdsFromNames_size(mapi_repl); return MAPI_E_SUCCESS; } /** \details EcDoRpc GetNamesFromIDs (0x56) Rop. This operation gets property IDs for specified property names. \param mem_ctx pointer to the memory context \param emsmdbp_ctx pointer to the emsmdb provider context \param mapi_req pointer to the GetNamesFromIDs EcDoRpc_MAPI_REQ structure \param mapi_repl pointer to the GetNamesFromIDs EcDoRpc_MAPI_REPL structure \param handles pointer to the MAPI handles array \param size pointer to the mapi_response size to update \return MAPI_E_SUCCESS on success, otherwise MAPI error */ _PUBLIC_ enum MAPISTATUS EcDoRpc_RopGetNamesFromIDs(TALLOC_CTX *mem_ctx, struct emsmdbp_context *emsmdbp_ctx, struct EcDoRpc_MAPI_REQ *mapi_req, struct EcDoRpc_MAPI_REPL *mapi_repl, uint32_t *handles, uint16_t *size) { uint16_t i; struct GetNamesFromIDs_req *request; struct GetNamesFromIDs_repl *response; struct MAPINAMEID *nameid; DEBUG(4, ("exchange_emsmdb: [OXCPRPT] GetNamesFromIDs (0x55)\n")); /* Sanity checks */ OPENCHANGE_RETVAL_IF(!emsmdbp_ctx, MAPI_E_NOT_INITIALIZED, NULL); OPENCHANGE_RETVAL_IF(!mapi_req, MAPI_E_INVALID_PARAMETER, NULL); OPENCHANGE_RETVAL_IF(!mapi_repl, MAPI_E_INVALID_PARAMETER, NULL); OPENCHANGE_RETVAL_IF(!handles, MAPI_E_INVALID_PARAMETER, NULL); OPENCHANGE_RETVAL_IF(!size, MAPI_E_INVALID_PARAMETER, NULL); mapi_repl->opnum = mapi_req->opnum; mapi_repl->error_code = MAPI_E_SUCCESS; mapi_repl->handle_idx = mapi_req->handle_idx; request = &mapi_req->u.mapi_GetNamesFromIDs; response = &mapi_repl->u.mapi_GetNamesFromIDs; response->nameid = talloc_array(mem_ctx, struct MAPINAMEID, request->PropertyIdCount); response->count = request->PropertyIdCount; for (i = 0; i < request->PropertyIdCount; i++) { if (request->PropertyIds[i] < 0x8000) { response->nameid[i].ulKind = MNID_ID; GUID_from_string(PS_MAPI, &response->nameid[i].lpguid); response->nameid[i].kind.lid = (uint32_t) request->PropertyIds[i] << 16 | get_property_type(request->PropertyIds[i]); } else if (mapistore_namedprops_get_nameid(emsmdbp_ctx->mstore_ctx->nprops_ctx, request->PropertyIds[i], mem_ctx, &nameid) == MAPISTORE_SUCCESS) { response->nameid[i] = *nameid; } else { response->nameid[i].ulKind = 0xff; } } *size += libmapiserver_RopGetNamesFromIDs_size(mapi_repl); return MAPI_E_SUCCESS; } /** \details EcDoRpc DeletePropertiesNoReplicate (0x7a) Rop. deletes property values from an object without invoking replication. \param mem_ctx pointer to the memory context \param emsmdbp_ctx pointer to the emsmdb provider context \param mapi_req pointer to the DeletePropertiesNoReplicate EcDoRpc_MAPI_REQ structure \param mapi_repl pointer to the DeletePropertiesNoReplicate EcDoRpc_MAPI_REPL structure \param handles pointer to the MAPI handles array \param size pointer to the mapi_response size to update \return MAPI_E_SUCCESS on success, otherwise MAPI error */ _PUBLIC_ enum MAPISTATUS EcDoRpc_RopDeletePropertiesNoReplicate(TALLOC_CTX *mem_ctx, struct emsmdbp_context *emsmdbp_ctx, struct EcDoRpc_MAPI_REQ *mapi_req, struct EcDoRpc_MAPI_REPL *mapi_repl, uint32_t *handles, uint16_t *size) { DEBUG(4, ("exchange_emsmdb: [OXCPRPT] DeletePropertiesNoReplicate (0x7a) -- stub\n")); /* Sanity checks */ OPENCHANGE_RETVAL_IF(!emsmdbp_ctx, MAPI_E_NOT_INITIALIZED, NULL); OPENCHANGE_RETVAL_IF(!mapi_req, MAPI_E_INVALID_PARAMETER, NULL); OPENCHANGE_RETVAL_IF(!mapi_repl, MAPI_E_INVALID_PARAMETER, NULL); OPENCHANGE_RETVAL_IF(!handles, MAPI_E_INVALID_PARAMETER, NULL); OPENCHANGE_RETVAL_IF(!size, MAPI_E_INVALID_PARAMETER, NULL); mapi_repl->opnum = mapi_req->opnum; mapi_repl->error_code = MAPI_E_SUCCESS; mapi_repl->handle_idx = mapi_req->handle_idx; mapi_repl->u.mapi_DeletePropertiesNoReplicate.PropertyProblemCount = 0; mapi_repl->u.mapi_DeletePropertiesNoReplicate.PropertyProblem = NULL; *size += libmapiserver_RopDeletePropertiesNoReplicate_size(mapi_repl); return MAPI_E_SUCCESS; } /** \details EcDoRpc CopyTo (0x39) Rop. This operation copy messages from one folder to another. \param mem_ctx pointer to the memory context \param emsmdbp_ctx pointer to the emsmdb provider context \param mapi_req pointer to the DeleteProperties EcDoRpc_MAPI_REQ structure \param mapi_repl pointer to the DeleteProperties EcDoRpc_MAPI_REPL structure \param handles pointer to the MAPI handles array \param size pointer to the mapi_response size to update \return MAPI_E_SUCCESS on success, otherwise MAPI error */ _PUBLIC_ enum MAPISTATUS EcDoRpc_RopCopyTo(TALLOC_CTX *mem_ctx, struct emsmdbp_context *emsmdbp_ctx, struct EcDoRpc_MAPI_REQ *mapi_req, struct EcDoRpc_MAPI_REPL *mapi_repl, uint32_t *handles, uint16_t *size) { struct CopyTo_req *request; struct CopyTo_repl *response; enum MAPISTATUS retval; uint32_t handle; struct mapi_handles *rec = NULL; void *private_data = NULL; struct emsmdbp_object *source_object; struct emsmdbp_object *dest_object; struct SPropTagArray excluded_tags; DEBUG(4, ("exchange_emsmdb: [OXCPRPT] CopyTo (0x39)\n")); /* Sanity checks */ OPENCHANGE_RETVAL_IF(!emsmdbp_ctx, MAPI_E_NOT_INITIALIZED, NULL); OPENCHANGE_RETVAL_IF(!mapi_req, MAPI_E_INVALID_PARAMETER, NULL); OPENCHANGE_RETVAL_IF(!mapi_repl, MAPI_E_INVALID_PARAMETER, NULL); OPENCHANGE_RETVAL_IF(!handles, MAPI_E_INVALID_PARAMETER, NULL); OPENCHANGE_RETVAL_IF(!size, MAPI_E_INVALID_PARAMETER, NULL); request = &mapi_req->u.mapi_CopyTo; response = &mapi_repl->u.mapi_CopyTo; mapi_repl->opnum = mapi_req->opnum; mapi_repl->error_code = MAPI_E_SUCCESS; mapi_repl->handle_idx = mapi_req->handle_idx; response->PropertyProblemCount = 0; response->PropertyProblem = NULL; if (request->WantAsynchronous) { DEBUG(0, (" warning: asynchronous operations are not supported\n")); } if ((request->CopyFlags & CopyFlagsMove)) { DEBUG(0, (" moving properties is not supported\n")); } if ((request->CopyFlags & CopyFlagsNoOverwrite)) { DEBUG(0, (" properties WILL BE overwriten despite the operation flags\n")); } /* Get the source object */ handle = handles[mapi_req->handle_idx]; retval = mapi_handles_search(emsmdbp_ctx->handles_ctx, handle, &rec); if (retval) { mapi_repl->error_code = MAPI_E_INVALID_OBJECT; DEBUG(0, (" handle (%x) not found: %x\n", handle, mapi_req->handle_idx)); goto end; } retval = mapi_handles_get_private_data(rec, &private_data); source_object = private_data; if (!source_object) { mapi_repl->error_code = MAPI_E_INVALID_OBJECT; DEBUG(0, (" object (%x) not found: %x\n", handle, mapi_req->handle_idx)); goto end; } /* Get the destination object */ handle = handles[request->handle_idx]; retval = mapi_handles_search(emsmdbp_ctx->handles_ctx, handle, &rec); if (retval) { mapi_repl->error_code = MAPI_E_INVALID_OBJECT; DEBUG(0, (" handle (%x) not found: %x\n", handle, mapi_req->handle_idx)); goto end; } retval = mapi_handles_get_private_data(rec, &private_data); dest_object = private_data; if (!dest_object) { mapi_repl->error_code = MAPI_E_INVALID_OBJECT; DEBUG(0, (" object (%x) not found: %x\n", handle, mapi_req->handle_idx)); goto end; } excluded_tags.cValues = request->ExcludedTags.cValues; excluded_tags.aulPropTag = request->ExcludedTags.aulPropTag; mapi_repl->error_code = emsmdbp_object_copy_properties(emsmdbp_ctx, source_object, dest_object, &excluded_tags, request->WantSubObjects); end: *size += libmapiserver_RopCopyTo_size(mapi_repl); return MAPI_E_SUCCESS; } openchange-2.0/mapiproxy/servers/default/emsmdb/oxcstor.c000066400000000000000000001042351223057412600237520ustar00rootroot00000000000000/* OpenChange Server implementation EMSMDBP: EMSMDB Provider implementation Copyright (C) Julien Kerihuel 2009 This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see . */ /** \file oxcstor.c \brief Server-side store objects routines and Rops */ #include "mapiproxy/dcesrv_mapiproxy.h" #include "mapiproxy/libmapiproxy/libmapiproxy.h" #include "mapiproxy/libmapiserver/libmapiserver.h" #include "dcesrv_exchange_emsmdb.h" #include /** \details Logs on a private mailbox \param mem_ctx pointer to the memory context \param emsmdbp_ctx pointer to the emsmdb provider context \param mapi_req pointer to the RopLogon EcDoRpc_MAPI_REQ structure \param mapi_repl pointer to the RopLogon EcDoRpc_MAPI_REPL structure the function returns \return MAPI_E_SUCCESS on success, otherwise MAPI error */ static enum MAPISTATUS RopLogon_Mailbox(TALLOC_CTX *mem_ctx, struct emsmdbp_context *emsmdbp_ctx, struct EcDoRpc_MAPI_REQ *mapi_req, struct EcDoRpc_MAPI_REPL *mapi_repl) { struct Logon_req *request; struct Logon_repl *response; const char * const attrs[] = { "*", NULL }; enum MAPISTATUS ret; struct ldb_result *res = NULL; const char *username; struct tm *LogonTime; time_t t; NTTIME nttime; request = &mapi_req->u.mapi_Logon; response = &mapi_repl->u.mapi_Logon; /* Sanity checks */ OPENCHANGE_RETVAL_IF(!request->EssDN, MAPI_E_INVALID_PARAMETER, NULL); /* Step 0. Retrieve user record */ ret = ldb_search(emsmdbp_ctx->samdb_ctx, mem_ctx, &res, ldb_get_default_basedn(emsmdbp_ctx->samdb_ctx), LDB_SCOPE_SUBTREE, attrs, "legacyExchangeDN=%s", request->EssDN); OPENCHANGE_RETVAL_IF((ret || res->count != 1), ecUnknownUser, NULL); /* Step 1. Retrieve username from record */ username = ldb_msg_find_attr_as_string(res->msgs[0], "sAMAccountName", NULL); OPENCHANGE_RETVAL_IF(!username, ecUnknownUser, NULL); /* Step 2. Init and or update the user mailbox (auto-provisioning) */ ret = emsmdbp_mailbox_provision(emsmdbp_ctx, username); OPENCHANGE_RETVAL_IF(ret, MAPI_E_DISK_ERROR, NULL); /* TODO: freebusy entry should be created only during freebusy lookups */ ret = emsmdbp_mailbox_provision_public_freebusy(emsmdbp_ctx, request->EssDN); OPENCHANGE_RETVAL_IF(ret, MAPI_E_DISK_ERROR, NULL); /* Step 3. Set LogonFlags */ response->LogonFlags = request->LogonFlags; /* Step 4. Build FolderIds list */ openchangedb_get_SystemFolderID(emsmdbp_ctx->oc_ctx, username, EMSMDBP_MAILBOX_ROOT, &response->LogonType.store_mailbox.Root); openchangedb_get_SystemFolderID(emsmdbp_ctx->oc_ctx, username, EMSMDBP_DEFERRED_ACTION, &response->LogonType.store_mailbox.DeferredAction); openchangedb_get_SystemFolderID(emsmdbp_ctx->oc_ctx, username, EMSMDBP_SPOOLER_QUEUE, &response->LogonType.store_mailbox.SpoolerQueue); openchangedb_get_SystemFolderID(emsmdbp_ctx->oc_ctx, username, EMSMDBP_TOP_INFORMATION_STORE, &response->LogonType.store_mailbox.IPMSubTree); openchangedb_get_SystemFolderID(emsmdbp_ctx->oc_ctx, username, EMSMDBP_INBOX, &response->LogonType.store_mailbox.Inbox); openchangedb_get_SystemFolderID(emsmdbp_ctx->oc_ctx, username, EMSMDBP_OUTBOX, &response->LogonType.store_mailbox.Outbox); openchangedb_get_SystemFolderID(emsmdbp_ctx->oc_ctx, username, EMSMDBP_SENT_ITEMS, &response->LogonType.store_mailbox.SentItems); openchangedb_get_SystemFolderID(emsmdbp_ctx->oc_ctx, username, EMSMDBP_DELETED_ITEMS, &response->LogonType.store_mailbox.DeletedItems); openchangedb_get_SystemFolderID(emsmdbp_ctx->oc_ctx, username, EMSMDBP_COMMON_VIEWS, &response->LogonType.store_mailbox.CommonViews); openchangedb_get_SystemFolderID(emsmdbp_ctx->oc_ctx, username, EMSMDBP_SCHEDULE, &response->LogonType.store_mailbox.Schedule); openchangedb_get_SystemFolderID(emsmdbp_ctx->oc_ctx, username, EMSMDBP_SEARCH, &response->LogonType.store_mailbox.Search); openchangedb_get_SystemFolderID(emsmdbp_ctx->oc_ctx, username, EMSMDBP_VIEWS, &response->LogonType.store_mailbox.Views); openchangedb_get_SystemFolderID(emsmdbp_ctx->oc_ctx, username, EMSMDBP_SHORTCUTS, &response->LogonType.store_mailbox.Shortcuts); /* Step 5. Set ResponseFlags */ response->LogonType.store_mailbox.ResponseFlags = ResponseFlags_Reserved; if (username && emsmdbp_ctx->username && strcmp(username, emsmdbp_ctx->username) == 0) { response->LogonType.store_mailbox.ResponseFlags |= ResponseFlags_OwnerRight | ResponseFlags_SendAsRight; } /* Step 6. Retrieve MailboxGuid */ openchangedb_get_MailboxGuid(emsmdbp_ctx->oc_ctx, username, &response->LogonType.store_mailbox.MailboxGuid); /* Step 7. Retrieve mailbox replication information */ openchangedb_get_MailboxReplica(emsmdbp_ctx->oc_ctx, username, &response->LogonType.store_mailbox.ReplId, &response->LogonType.store_mailbox.ReplGUID); /* Step 8. Set LogonTime both in openchange dispatcher database and reply */ t = time(NULL); LogonTime = localtime(&t); response->LogonType.store_mailbox.LogonTime.Seconds = LogonTime->tm_sec; response->LogonType.store_mailbox.LogonTime.Minutes = LogonTime->tm_min; response->LogonType.store_mailbox.LogonTime.Hour = LogonTime->tm_hour; response->LogonType.store_mailbox.LogonTime.DayOfWeek = LogonTime->tm_wday; response->LogonType.store_mailbox.LogonTime.Day = LogonTime->tm_mday; response->LogonType.store_mailbox.LogonTime.Month = LogonTime->tm_mon + 1; response->LogonType.store_mailbox.LogonTime.Year = LogonTime->tm_year + 1900; /* Step 9. Retrieve GwartTime */ unix_to_nt_time(&nttime, t); response->LogonType.store_mailbox.GwartTime = nttime - 1000000; /* Step 10. Set StoreState */ response->LogonType.store_mailbox.StoreState = 0x0; return MAPI_E_SUCCESS; } /** \details Logs on a public folder store \param mem_ctx pointer to the memory context \param emsmdbp_ctx pointer to the emsmdb provider context \param mapi_req pointer to the RopLogon EcDoRpc_MAPI_REQ structure \param mapi_repl pointer to the RopLogon EcDoRpc_MAPI_REPL structure that the function returns \return MAPI_E_SUCCESS on success, otherwise MAPI error */ static enum MAPISTATUS RopLogon_PublicFolder(TALLOC_CTX *mem_ctx, struct emsmdbp_context *emsmdbp_ctx, struct EcDoRpc_MAPI_REQ *mapi_req, struct EcDoRpc_MAPI_REPL *mapi_repl) { struct Logon_req *request; struct Logon_repl *response; request = &mapi_req->u.mapi_Logon; response = &mapi_repl->u.mapi_Logon; response->LogonFlags = request->LogonFlags; openchangedb_get_PublicFolderID(emsmdbp_ctx->oc_ctx, EMSMDBP_PF_ROOT, &response->LogonType.store_pf.Root); openchangedb_get_PublicFolderID(emsmdbp_ctx->oc_ctx, EMSMDBP_PF_IPMSUBTREE, &response->LogonType.store_pf.IPMSubTree); openchangedb_get_PublicFolderID(emsmdbp_ctx->oc_ctx, EMSMDBP_PF_NONIPMSUBTREE, &response->LogonType.store_pf.NonIPMSubTree); openchangedb_get_PublicFolderID(emsmdbp_ctx->oc_ctx, EMSMDBP_PF_EFORMSREGISTRY, &response->LogonType.store_pf.EFormsRegistry); openchangedb_get_PublicFolderID(emsmdbp_ctx->oc_ctx, EMSMDBP_PF_FREEBUSY, &response->LogonType.store_pf.FreeBusy); openchangedb_get_PublicFolderID(emsmdbp_ctx->oc_ctx, EMSMDBP_PF_OAB, &response->LogonType.store_pf.OAB); response->LogonType.store_pf.LocalizedEFormsRegistry = 0; openchangedb_get_PublicFolderID(emsmdbp_ctx->oc_ctx, EMSMDBP_PF_LOCALFREEBUSY, &response->LogonType.store_pf.LocalFreeBusy); openchangedb_get_PublicFolderID(emsmdbp_ctx->oc_ctx, EMSMDBP_PF_LOCALOAB, &response->LogonType.store_pf.LocalOAB); response->LogonType.store_pf.NNTPIndex = 0; memset(response->LogonType.store_pf._empty, 0, sizeof(uint64_t) * 3); openchangedb_get_PublicFolderReplica(emsmdbp_ctx->oc_ctx, &response->LogonType.store_pf.ReplId, &response->LogonType.store_pf.Guid); memset(&response->LogonType.store_pf.PerUserGuid, 0, sizeof(struct GUID)); return MAPI_E_SUCCESS; } /** \details EcDoRpc Logon (0xFE) Rop. This operation logs on to a private mailbox or public folder. \param mem_ctx pointer to the memory context \param emsmdbp_ctx pointer to the emsmdb provider context \param mapi_req pointer to the Logon EcDoRpc_MAPI_REQ structure \param mapi_repl pointer to the Logon EcDoRpc_MAPI_REPL structure the function returns \param handles pointer to the MAPI handles array \param size pointer to the mapi_response size to update \note Users are only allowed to open their own mailbox at the moment. This limitation will be removed when significant progress have been made. \return MAPI_E_SUCCESS on success, otherwise MAPI error */ _PUBLIC_ enum MAPISTATUS EcDoRpc_RopLogon(TALLOC_CTX *mem_ctx, struct emsmdbp_context *emsmdbp_ctx, struct EcDoRpc_MAPI_REQ *mapi_req, struct EcDoRpc_MAPI_REPL *mapi_repl, uint32_t *handles, uint16_t *size) { enum MAPISTATUS retval; struct Logon_req *request; struct mapi_handles *rec = NULL; struct emsmdbp_object *object; bool mailboxstore = true; DEBUG(4, ("exchange_emsmdb: [OXCSTOR] Logon (0xFE)\n")); /* Sanity checks */ OPENCHANGE_RETVAL_IF(!emsmdbp_ctx, MAPI_E_NOT_INITIALIZED, NULL); OPENCHANGE_RETVAL_IF(!mapi_req, MAPI_E_INVALID_PARAMETER, NULL); OPENCHANGE_RETVAL_IF(!mapi_repl, MAPI_E_INVALID_PARAMETER, NULL); OPENCHANGE_RETVAL_IF(!handles, MAPI_E_INVALID_PARAMETER, NULL); OPENCHANGE_RETVAL_IF(!size, MAPI_E_INVALID_PARAMETER, NULL); request = &mapi_req->u.mapi_Logon; /* Fill EcDoRpc_MAPI_REPL reply */ mapi_repl->opnum = mapi_req->opnum; mapi_repl->handle_idx = mapi_req->handle_idx; if (request->LogonFlags & LogonPrivate) { retval = RopLogon_Mailbox(mem_ctx, emsmdbp_ctx, mapi_req, mapi_repl); mapi_repl->error_code = retval; *size += libmapiserver_RopLogon_size(mapi_req, mapi_repl); } else { retval = RopLogon_PublicFolder(mem_ctx, emsmdbp_ctx, mapi_req, mapi_repl); /* mapi_repl->error_code = MAPI_E_LOGON_FAILED; */ mapi_repl->error_code = retval; mailboxstore = false; *size += libmapiserver_RopLogon_size(mapi_req, mapi_repl); } if (!mapi_repl->error_code) { retval = mapi_handles_add(emsmdbp_ctx->handles_ctx, 0, &rec); object = emsmdbp_object_mailbox_init((TALLOC_CTX *)rec, emsmdbp_ctx, request->EssDN, mailboxstore); retval = mapi_handles_set_private_data(rec, object); handles[mapi_repl->handle_idx] = rec->handle; } return retval; } /** \details EcDoRpc Release (0x01) Rop. This operation releases an existing MAPI handle. \param mem_ctx pointer to the memory context \param emsmdbp_ctx pointer to the emsmdb provider context \param request pointer to the Release EcDoRpc_MAPI_REQ \param handles pointer to the MAPI handles array \param size pointer to the mapi_response size to update \return MAPI_E_SUCCESS on success, otherwise MAPI error */ _PUBLIC_ enum MAPISTATUS EcDoRpc_RopRelease(TALLOC_CTX *mem_ctx, struct emsmdbp_context *emsmdbp_ctx, struct EcDoRpc_MAPI_REQ *request, uint32_t *handles, uint16_t *size) { /* struct mapistore_subscription_list *subscription_list, *subscription_holder; struct mapistore_subscription *subscription; struct mapistore_subscription_list *el;*/ enum MAPISTATUS retval; uint32_t handle; handle = handles[request->handle_idx]; #if 0 next: for (el = emsmdbp_ctx->mstore_ctx->subscriptions; el; el = el->next) { if (handle == el->subscription->handle) { DEBUG(0, ("*** DELETING SUBSCRIPTION ***\n")); DEBUG(0, ("subscription: handle = 0x%x\n", el->subscription->handle)); DEBUG(0, ("subscription: types = 0x%x\n", el->subscription->notification_types)); DEBUG(0, ("subscription: mqueue = %d\n", el->subscription->mqueue)); DEBUG(0, ("subscription: mqueue name = %s\n", el->subscription->mqueue_name)); DLIST_REMOVE(emsmdbp_ctx->mstore_ctx->subscriptions, el); goto next; } } #endif /* If we have notification's subscriptions attached to this handle, we obviously remove them in order to avoid invoking them once all ROPs are processed */ /* retry: */ /* subscription_list = emsmdbp_ctx->mstore_ctx->subscriptions; */ /* subscription_holder = subscription_list; */ /* while (subscription_holder) { */ /* subscription = subscription_holder->subscription; */ /* if (handle == subscription->handle) { */ /* DEBUG(0, ("*** DELETING SUBSCRIPTION ***\n")); */ /* DEBUG(0, ("subscription: handle = 0x%x\n", subscription->handle)); */ /* DEBUG(0, ("subscription: types = 0x%x\n", subscription->notification_types)); */ /* DEBUG(0, ("subscription: mqueue = %d\n", subscription->mqueue)); */ /* DEBUG(0, ("subscription: mqueue name = %s\n", subscription->mqueue_name)); */ /* DLIST_REMOVE(subscription_list, subscription_holder); */ /* talloc_free(subscription_holder); */ /* goto retry; */ /* } */ /* subscription_holder = subscription_holder->next; */ /* } */ /* We finally really delete the handle */ retval = mapi_handles_delete(emsmdbp_ctx->handles_ctx, handle); OPENCHANGE_RETVAL_IF(retval && retval != MAPI_E_NOT_FOUND, retval, NULL); return MAPI_E_SUCCESS; } /* Test MessageClass string according to [MS-OXCSTOR] section 2.2.1.2.1.1 and 2.2.1.3.1.2 */ static bool MessageClassIsValid(const char *MessageClass) { size_t len = strlen(MessageClass); int i; if (len + 1 > 255) { return false; } for (i = 0; i < len; i++) { if ((MessageClass[i] < 32) || (MessageClass[i] > 126)) { return false; } if ((MessageClass[i] == '.') && (MessageClass[i + 1]) && (MessageClass[i + 1] == '.')) { return false; } } if (MessageClass[0] && (MessageClass[0] == '.')) { return false; } if (MessageClass[0] && (MessageClass[len] == '.')) { return false; } return true; } /** \details EcDoRpc SetReceiveFolder (0x26) Rop Internals. This routine performs the SetReceiveFolder internals. \param mem_ctx pointer to the memory context \param emsmdbp_ctx pointer to the emsmdb provider context \param mapi_req pointer to the SetReceiveFolder EcDoRpc_MAPI_REQ \param mapi_repl pointer to the SetReceiveFolder EcDoRpc_MAPI_REPL \param handles pointer to the MAPI handles array \return MAPI_E_SUCCESS on success, otherwise MAPI error */ static enum MAPISTATUS RopSetReceiveFolder(TALLOC_CTX *mem_ctx, struct emsmdbp_context *emsmdbp_ctx, struct EcDoRpc_MAPI_REQ *mapi_req, struct EcDoRpc_MAPI_REPL *mapi_repl, uint32_t *handles) { enum MAPISTATUS retval; struct mapi_handles *rec = NULL; struct emsmdbp_object *object = NULL; const char *MessageClass = NULL; void *private_data = NULL; uint32_t handle; uint64_t fid; /* Step 1. Ensure the referring MAPI handle is mailbox one */ handle = handles[mapi_req->handle_idx]; retval = mapi_handles_search(emsmdbp_ctx->handles_ctx, handle, &rec); OPENCHANGE_RETVAL_IF(retval, retval, NULL); retval = mapi_handles_get_private_data(rec, (void **)&private_data); object = (struct emsmdbp_object *) private_data; OPENCHANGE_RETVAL_IF(retval, retval, NULL); OPENCHANGE_RETVAL_IF(object->type != EMSMDBP_OBJECT_MAILBOX, MAPI_E_NO_SUPPORT, NULL); /* Step 2. Verify MessageClass string */ fid = mapi_req->u.mapi_SetReceiveFolder.fid; MessageClass = mapi_req->u.mapi_SetReceiveFolder.lpszMessageClass; if (!MessageClass || (strcmp(MessageClass, "") == 0)) { MessageClass="All"; } if ((fid == 0x0) && (strcmp(MessageClass, "All"))) { return MAPI_E_CALL_FAILED; } if (strcasecmp(MessageClass, "IPM") == 0) { return MAPI_E_NO_ACCESS; } if (strcasecmp(MessageClass, "Report.IPM") == 0) { return MAPI_E_NO_ACCESS; } if (! MessageClassIsValid(MessageClass) ) { return MAPI_E_INVALID_PARAMETER; } /* Step 3.Set the receive folder for this message class within user mailbox */ retval = openchangedb_set_ReceiveFolder(emsmdbp_ctx->oc_ctx, object->object.mailbox->owner_username, MessageClass, fid); OPENCHANGE_RETVAL_IF(retval, ecNoReceiveFolder, NULL); return MAPI_E_SUCCESS; } /** \details EcDoRpc SetReceiveFolder (0x26) Rop. This operation sets the receive folder for incoming messages of a particular message class \param mem_ctx pointer to the memory context \param emsmdbp_ctx pointer to the emsmdb provider context \param mapi_req pointer to the SetReceiveFolder EcDoRpc_MAPI_REQ \param mapi_repl pointer to the SetReceiveFolder EcDoRpc_MAPI_REPL \param handles pointer to the MAPI handles array \param size pointer to the mapi_response size to update \return MAPI_E_SUCCESS on success, otherwise MAPI error */ _PUBLIC_ enum MAPISTATUS EcDoRpc_RopSetReceiveFolder(TALLOC_CTX *mem_ctx, struct emsmdbp_context *emsmdbp_ctx, struct EcDoRpc_MAPI_REQ *mapi_req, struct EcDoRpc_MAPI_REPL *mapi_repl, uint32_t *handles, uint16_t *size) { enum MAPISTATUS retval; DEBUG(4, ("exchange_emsmdb: [OXCSTOR] SetReceiveFolder (0x26)\n")); /* Sanity checks */ OPENCHANGE_RETVAL_IF(!emsmdbp_ctx, MAPI_E_NOT_INITIALIZED, NULL); OPENCHANGE_RETVAL_IF(!mapi_req, MAPI_E_INVALID_PARAMETER, NULL); OPENCHANGE_RETVAL_IF(!mapi_repl, MAPI_E_INVALID_PARAMETER, NULL); OPENCHANGE_RETVAL_IF(!handles, MAPI_E_INVALID_PARAMETER, NULL); OPENCHANGE_RETVAL_IF(!size, MAPI_E_INVALID_PARAMETER, NULL); /* Call effective code */ retval = RopSetReceiveFolder(mem_ctx, emsmdbp_ctx, mapi_req, mapi_repl, handles); mapi_repl->opnum = mapi_req->opnum; mapi_repl->handle_idx = mapi_req->handle_idx; mapi_repl->error_code = retval; *size += libmapiserver_RopSetReceiveFolder_size(mapi_repl); handles[mapi_repl->handle_idx] = handles[mapi_req->handle_idx]; return retval; } /** \details EcDoRpc GetReceiveFolder (0x27) Rop Internals. This routine performs the GetReceiveFolder internals. \param mem_ctx pointer to the memory context \param emsmdbp_ctx pointer to the emsmdb provider context \param mapi_req pointer to the GetReceiveFolder EcDoRpc_MAPI_REQ \param mapi_repl pointer to the GetReceiveFolder EcDoRpc_MAPI_REPL \param handles pointer to the MAPI handles array \return MAPI_E_SUCCESS on success, otherwise MAPI error */ static enum MAPISTATUS RopGetReceiveFolder(TALLOC_CTX *mem_ctx, struct emsmdbp_context *emsmdbp_ctx, struct EcDoRpc_MAPI_REQ *mapi_req, struct EcDoRpc_MAPI_REPL *mapi_repl, uint32_t *handles) { enum MAPISTATUS retval; struct mapi_handles *rec = NULL; struct emsmdbp_object *object = NULL; const char *MessageClass = NULL; void *private_data = NULL; uint32_t handle; /* Step 1. Ensure the referring MAPI handle is mailbox one */ handle = handles[mapi_req->handle_idx]; retval = mapi_handles_search(emsmdbp_ctx->handles_ctx, handle, &rec); OPENCHANGE_RETVAL_IF(retval, retval, NULL); retval = mapi_handles_get_private_data(rec, (void **)&private_data); object = (struct emsmdbp_object *) private_data; OPENCHANGE_RETVAL_IF(retval, retval, NULL); OPENCHANGE_RETVAL_IF(object->type != EMSMDBP_OBJECT_MAILBOX, MAPI_E_NO_SUPPORT, NULL); /* Step 2. Verify MessageClass string */ MessageClass = mapi_req->u.mapi_GetReceiveFolder.MessageClass; if (!MessageClass || !strcmp(MessageClass, "")) { MessageClass="All"; } if (! MessageClassIsValid(MessageClass) ) { return MAPI_E_INVALID_PARAMETER; } /* Step 3. Search for the specified MessageClass substring within user mailbox */ retval = openchangedb_get_ReceiveFolder(mem_ctx, emsmdbp_ctx->oc_ctx, object->object.mailbox->owner_username, MessageClass, &mapi_repl->u.mapi_GetReceiveFolder.folder_id, &mapi_repl->u.mapi_GetReceiveFolder.MessageClass); OPENCHANGE_RETVAL_IF(retval, ecNoReceiveFolder, NULL); return MAPI_E_SUCCESS; } /** \details EcDoRpc GetReceiveFolder (0x27) Rop. This operation gets the receive folder for incoming messages of a particular message class \param mem_ctx pointer to the memory context \param emsmdbp_ctx pointer to the emsmdb provider context \param mapi_req pointer to the GetReceiveFolder EcDoRpc_MAPI_REQ \param mapi_repl pointer to the GetReceiveFolder EcDoRpc_MAPI_REPL \param handles pointer to the MAPI handles array \param size pointer to the mapi_response size to update \return MAPI_E_SUCCESS on success, otherwise MAPI error */ _PUBLIC_ enum MAPISTATUS EcDoRpc_RopGetReceiveFolder(TALLOC_CTX *mem_ctx, struct emsmdbp_context *emsmdbp_ctx, struct EcDoRpc_MAPI_REQ *mapi_req, struct EcDoRpc_MAPI_REPL *mapi_repl, uint32_t *handles, uint16_t *size) { enum MAPISTATUS retval; DEBUG(4, ("exchange_emsmdb: [OXCSTOR] GetReceiveFolder (0x27)\n")); /* Sanity checks */ OPENCHANGE_RETVAL_IF(!emsmdbp_ctx, MAPI_E_NOT_INITIALIZED, NULL); OPENCHANGE_RETVAL_IF(!mapi_req, MAPI_E_INVALID_PARAMETER, NULL); OPENCHANGE_RETVAL_IF(!mapi_repl, MAPI_E_INVALID_PARAMETER, NULL); OPENCHANGE_RETVAL_IF(!handles, MAPI_E_INVALID_PARAMETER, NULL); OPENCHANGE_RETVAL_IF(!size, MAPI_E_INVALID_PARAMETER, NULL); /* Call effective code */ retval = RopGetReceiveFolder(mem_ctx, emsmdbp_ctx, mapi_req, mapi_repl, handles); mapi_repl->opnum = mapi_req->opnum; mapi_repl->handle_idx = mapi_req->handle_idx; mapi_repl->error_code = retval; *size += libmapiserver_RopGetReceiveFolder_size(mapi_repl); handles[mapi_repl->handle_idx] = handles[mapi_req->handle_idx]; return retval; } /** \details EcDoRpc EcDoRpc_RopLongTermIdFromId (0x43) Rop. \param mem_ctx pointer to the memory context \param emsmdbp_ctx pointer to the emsmdb provider context \param mapi_req pointer to the LongTermIdFromId EcDoRpc_MAPI_REQ structure \param mapi_repl pointer to the LongTermIdFromId EcDoRpc_MAPI_REPL structure \param handles pointer to the MAPI handles array \param size pointer to the mapi_response size to update \return MAPI_E_SUCCESS on success, otherwise MAPI error */ _PUBLIC_ enum MAPISTATUS EcDoRpc_RopLongTermIdFromId(TALLOC_CTX *mem_ctx, struct emsmdbp_context *emsmdbp_ctx, struct EcDoRpc_MAPI_REQ *mapi_req, struct EcDoRpc_MAPI_REPL *mapi_repl, uint32_t *handles, uint16_t *size) { struct LongTermIdFromId_req *request; struct LongTermIdFromId_repl *response; enum MAPISTATUS retval; uint32_t handle; struct mapi_handles *rec = NULL; struct emsmdbp_object *object = NULL; void *data; uint16_t req_repl_id; uint64_t id; uint8_t i; DEBUG(4, ("exchange_emsmdb: [OXCSTOR] LongTermIdFromId (0x43)\n")); /* Sanity checks */ OPENCHANGE_RETVAL_IF(!emsmdbp_ctx, MAPI_E_NOT_INITIALIZED, NULL); OPENCHANGE_RETVAL_IF(!mapi_req, MAPI_E_INVALID_PARAMETER, NULL); OPENCHANGE_RETVAL_IF(!mapi_repl, MAPI_E_INVALID_PARAMETER, NULL); OPENCHANGE_RETVAL_IF(!handles, MAPI_E_INVALID_PARAMETER, NULL); OPENCHANGE_RETVAL_IF(!size, MAPI_E_INVALID_PARAMETER, NULL); mapi_repl->opnum = mapi_req->opnum; mapi_repl->error_code = MAPI_E_SUCCESS; mapi_repl->handle_idx = mapi_req->handle_idx; request = &mapi_req->u.mapi_LongTermIdFromId; response = &mapi_repl->u.mapi_LongTermIdFromId; req_repl_id = request->Id & 0xffff; handle = handles[mapi_req->handle_idx]; retval = mapi_handles_search(emsmdbp_ctx->handles_ctx, handle, &rec); if (retval) { mapi_repl->error_code = MAPI_E_INVALID_OBJECT; DEBUG(5, (" handle (%x) not found: %x\n", handle, mapi_req->handle_idx)); goto end; } retval = mapi_handles_get_private_data(rec, &data); if (retval) { mapi_repl->error_code = retval; DEBUG(5, (" handle data not found, idx = %x\n", mapi_req->handle_idx)); goto end; } object = (struct emsmdbp_object *) data; if (!object || object->type != EMSMDBP_OBJECT_MAILBOX) { abort(); DEBUG(5, (" no object or object is not a mailbox\n")); mapi_repl->error_code = MAPI_E_NO_SUPPORT; goto end; } if (emsmdbp_replid_to_guid(emsmdbp_ctx, object->object.mailbox->owner_username, req_repl_id, &response->LongTermId.DatabaseGuid)) { mapi_repl->error_code = MAPI_E_NOT_FOUND; goto end; } id = request->Id >> 16; for (i = 0; i < 6; i++) { response->LongTermId.GlobalCounter[i] = id & 0xff; id >>= 8; } response->LongTermId.padding = 0; end: *size += libmapiserver_RopLongTermIdFromId_size(mapi_repl); return MAPI_E_SUCCESS; } /* NEW and cleaner version that does not work: */ /** \details EcDoRpc (0x44) Rop. This operation sets or clears the message read flag. \param mem_ctx pointer to the memory context \param emsmdbp_ctx pointer to the emsmdb provider context \param mapi_req pointer to the SetMessageReadFlag EcDoRpc_MAPI_REQ structure \param mapi_repl pointer to the SetMessageReadFlag EcDoRpc_MAPI_REPL structure \param handles pointer to the MAPI handles array \param size pointer to the mapi_response size to update \return MAPI_E_SUCCESS on success, otherwise MAPI error */ _PUBLIC_ enum MAPISTATUS EcDoRpc_RopIdFromLongTermId(TALLOC_CTX *mem_ctx, struct emsmdbp_context *emsmdbp_ctx, struct EcDoRpc_MAPI_REQ *mapi_req, struct EcDoRpc_MAPI_REPL *mapi_repl, uint32_t *handles, uint16_t *size) { struct IdFromLongTermId_req *request; struct IdFromLongTermId_repl *response; enum MAPISTATUS retval; uint32_t handle; struct mapi_handles *rec = NULL; struct emsmdbp_object *object = NULL; void *data; uint16_t repl_id; uint64_t fmid, base; uint8_t i, ctr_byte; DEBUG(4, ("exchange_emsmdb: [OXCSTOR] RopIdFromLongTermId (0x44)\n")); /* Sanity checks */ OPENCHANGE_RETVAL_IF(!emsmdbp_ctx, MAPI_E_NOT_INITIALIZED, NULL); OPENCHANGE_RETVAL_IF(!mapi_req, MAPI_E_INVALID_PARAMETER, NULL); OPENCHANGE_RETVAL_IF(!mapi_repl, MAPI_E_INVALID_PARAMETER, NULL); OPENCHANGE_RETVAL_IF(!handles, MAPI_E_INVALID_PARAMETER, NULL); OPENCHANGE_RETVAL_IF(!size, MAPI_E_INVALID_PARAMETER, NULL); mapi_repl->opnum = mapi_req->opnum; mapi_repl->error_code = MAPI_E_SUCCESS; mapi_repl->handle_idx = mapi_req->handle_idx; request = &mapi_req->u.mapi_IdFromLongTermId; response = &mapi_repl->u.mapi_IdFromLongTermId; if (GUID_all_zero(&request->LongTermId.DatabaseGuid)) { mapi_repl->error_code = MAPI_E_INVALID_PARAMETER; goto end; } ctr_byte = 0; for (i = 0; i < 6; i++) { ctr_byte = request->LongTermId.GlobalCounter[i]; if (ctr_byte) break; } if (ctr_byte == 0) { mapi_repl->error_code = MAPI_E_INVALID_PARAMETER; goto end; } handle = handles[mapi_req->handle_idx]; retval = mapi_handles_search(emsmdbp_ctx->handles_ctx, handle, &rec); if (retval) { mapi_repl->error_code = MAPI_E_INVALID_OBJECT; DEBUG(5, (" handle (%x) not found: %x\n", handle, mapi_req->handle_idx)); goto end; } retval = mapi_handles_get_private_data(rec, &data); if (retval) { mapi_repl->error_code = retval; DEBUG(5, (" handle data not found, idx = %x\n", mapi_req->handle_idx)); goto end; } object = (struct emsmdbp_object *) data; if (!object || object->type != EMSMDBP_OBJECT_MAILBOX) { abort(); DEBUG(5, (" no object or object is not a mailbox\n")); mapi_repl->error_code = MAPI_E_NO_SUPPORT; goto end; } if (emsmdbp_guid_to_replid(emsmdbp_ctx, object->object.mailbox->owner_username, &request->LongTermId.DatabaseGuid, &repl_id)) { mapi_repl->error_code = MAPI_E_NOT_FOUND; goto end; } fmid = 0; base = 1; for (i = 0; i < 6; i++) { fmid |= (uint64_t) request->LongTermId.GlobalCounter[i] * base; base <<= 8; } response->Id = fmid << 16 | repl_id; end: *size += libmapiserver_RopIdFromLongTermId_size(mapi_repl); return MAPI_E_SUCCESS; } /** \details EcDoRpc GetPerUserLongTermIds (0x60) Rop. This operations gets the long-term ID of a public folder that is identified by the per-user GUID of the logged on user. \param mem_ctx pointer to the memory context \param emsmdbp_ctx pointer to the emsmdb provider context \param mapi_req pointer to the GetPerUserLongTermIds EcDoRpc_MAPI_REQ \param mapi_repl pointer to the GetPerUserLongTermIds EcDoRpc_MAPI_REPL \param handles pointer to the MAPI handles array \param size pointer to the mapi_response size to update \return MAPI_E_SUCCESS on success, otherwise MAPI error */ _PUBLIC_ enum MAPISTATUS EcDoRpc_RopGetPerUserLongTermIds(TALLOC_CTX *mem_ctx, struct emsmdbp_context *emsmdbp_ctx, struct EcDoRpc_MAPI_REQ *mapi_req, struct EcDoRpc_MAPI_REPL *mapi_repl, uint32_t *handles, uint16_t *size) { DEBUG(4, ("exchange_emsmdb: [OXCSTOR] GetPerUserLongTermIds (0x60) - valid stub\n")); /* Sanity checks */ OPENCHANGE_RETVAL_IF(!emsmdbp_ctx, MAPI_E_NOT_INITIALIZED, NULL); OPENCHANGE_RETVAL_IF(!mapi_req, MAPI_E_INVALID_PARAMETER, NULL); OPENCHANGE_RETVAL_IF(!mapi_repl, MAPI_E_INVALID_PARAMETER, NULL); OPENCHANGE_RETVAL_IF(!handles, MAPI_E_INVALID_PARAMETER, NULL); OPENCHANGE_RETVAL_IF(!size, MAPI_E_INVALID_PARAMETER, NULL); /* Ensure the request is performed against a private mailbox * logon, not a public folders logon. If the operation is * performed against a public folders logon, return * MAPI_E_NO_SUPPORT */ mapi_repl->opnum = mapi_req->opnum; mapi_repl->handle_idx = mapi_req->handle_idx; mapi_repl->error_code = MAPI_E_SUCCESS; /* TODO effective work here */ mapi_repl->u.mapi_GetPerUserLongTermIds.LongTermIdCount = 0; mapi_repl->u.mapi_GetPerUserLongTermIds.LongTermIds = NULL; *size += libmapiserver_RopGetPerUserLongTermIds_size(mapi_repl); handles[mapi_repl->handle_idx] = handles[mapi_req->handle_idx]; return MAPI_E_SUCCESS; } /** \details EcDoRpc GetPerUserGuid (0x61) Rop. This operation gets the GUID of a public folder's per-user information. \param mem_ctx pointer to the memory context \param emsmdbp_ctx pointer to the emsmdb provider context \param mapi_req pointer to the GetPerUserLongTermIds EcDoRpc_MAPI_REQ \param mapi_repl pointer to the GetPerUserLongTermIds EcDoRpc_MAPI_REPL \param handles pointer to the MAPI handles array \param size pointer to the mapi_response size to update \return MAPI_E_SUCCESS on success, otherwise MAPI error */ _PUBLIC_ enum MAPISTATUS EcDoRpc_RopGetPerUserGuid(TALLOC_CTX *mem_ctx, struct emsmdbp_context *emsmdbp_ctx, struct EcDoRpc_MAPI_REQ *mapi_req, struct EcDoRpc_MAPI_REPL *mapi_repl, uint32_t *handles, uint16_t *size) { DEBUG(4, ("exchange_emsmdb: [OXCSTOR] GetPerUserGuid (0x61) - stub\n")); /* Sanity checks */ OPENCHANGE_RETVAL_IF(!emsmdbp_ctx, MAPI_E_NOT_INITIALIZED, NULL); OPENCHANGE_RETVAL_IF(!mapi_req, MAPI_E_INVALID_PARAMETER, NULL); OPENCHANGE_RETVAL_IF(!mapi_repl, MAPI_E_INVALID_PARAMETER, NULL); OPENCHANGE_RETVAL_IF(!handles, MAPI_E_INVALID_PARAMETER, NULL); OPENCHANGE_RETVAL_IF(!size, MAPI_E_INVALID_PARAMETER, NULL); /* Ensure the request is performed against a private mailbox * logon, not a public folders logon. If the operation is * performed against a public folders logon, return * MAPI_E_NO_SUPPORT */ mapi_repl->opnum = mapi_req->opnum; mapi_repl->handle_idx = mapi_req->handle_idx; mapi_repl->error_code = MAPI_E_NOT_FOUND; /* TODO effective work here */ *size += libmapiserver_RopGetPerUserGuid_size(mapi_repl); handles[mapi_repl->handle_idx] = handles[mapi_req->handle_idx]; return MAPI_E_SUCCESS; } /** \details EcDoRpc ReadPerUserInformation (0x63) Rop. This operation gets per-user information for a public folder. \param mem_ctx pointer to the memory context \param emsmdbp_ctx pointer to the emsmdb provider context \param mapi_req pointer to the ReadPerUserInformation EcDoRpc_MAPI_REQ \param mapi_repl pointer to the ReadPerUserInformation EcDoRpc_MAPI_REPL \param handles pointer to the MAPI handles array \param size pointer to the mapi_response size to update \return MAPI_E_SUCCESS on success, otherwise MAPI error */ _PUBLIC_ enum MAPISTATUS EcDoRpc_RopReadPerUserInformation(TALLOC_CTX *mem_ctx, struct emsmdbp_context *emsmdbp_ctx, struct EcDoRpc_MAPI_REQ *mapi_req, struct EcDoRpc_MAPI_REPL *mapi_repl, uint32_t *handles, uint16_t *size) { DEBUG(4, ("exchange_emsmdb: [OXCSTOR] ReadPerUserInformation (0x63) - stub\n")); /* Sanity checks */ OPENCHANGE_RETVAL_IF(!emsmdbp_ctx, MAPI_E_NOT_INITIALIZED, NULL); OPENCHANGE_RETVAL_IF(!mapi_req, MAPI_E_INVALID_PARAMETER, NULL); OPENCHANGE_RETVAL_IF(!mapi_repl, MAPI_E_INVALID_PARAMETER, NULL); OPENCHANGE_RETVAL_IF(!handles, MAPI_E_INVALID_PARAMETER, NULL); OPENCHANGE_RETVAL_IF(!size, MAPI_E_INVALID_PARAMETER, NULL); mapi_repl->opnum = mapi_req->opnum; mapi_repl->handle_idx = mapi_req->handle_idx; mapi_repl->error_code = MAPI_E_SUCCESS; mapi_repl->u.mapi_ReadPerUserInformation.HasFinished = true; mapi_repl->u.mapi_ReadPerUserInformation.DataSize = 0x0; mapi_repl->u.mapi_ReadPerUserInformation.Data.length = 0x0; mapi_repl->u.mapi_ReadPerUserInformation.Data.data = NULL; *size += libmapiserver_RopReadPerUserInformation_size(mapi_repl); handles[mapi_repl->handle_idx] = handles[mapi_req->handle_idx]; return MAPI_E_SUCCESS; } /** \details EcDoRpc GetStoreState (0x63) Rop. This operation gets per-user information for a public folder. \param mem_ctx pointer to the memory context \param emsmdbp_ctx pointer to the emsmdb provider context \param mapi_req pointer to the GetStoreState EcDoRpc_MAPI_REQ \param mapi_repl pointer to the GetStoreState EcDoRpc_MAPI_REPL \param handles pointer to the MAPI handles array \param size pointer to the mapi_response size to update \return MAPI_E_SUCCESS on success, otherwise MAPI error */ _PUBLIC_ enum MAPISTATUS EcDoRpc_RopGetStoreState(TALLOC_CTX *mem_ctx, struct emsmdbp_context *emsmdbp_ctx, struct EcDoRpc_MAPI_REQ *mapi_req, struct EcDoRpc_MAPI_REPL *mapi_repl, uint32_t *handles, uint16_t *size) { DEBUG(4, ("exchange_emsmdb: [OXCSTOR] GetStoreState (0x63) - stub\n")); /* Sanity checks */ OPENCHANGE_RETVAL_IF(!emsmdbp_ctx, MAPI_E_NOT_INITIALIZED, NULL); OPENCHANGE_RETVAL_IF(!mapi_req, MAPI_E_INVALID_PARAMETER, NULL); OPENCHANGE_RETVAL_IF(!mapi_repl, MAPI_E_INVALID_PARAMETER, NULL); OPENCHANGE_RETVAL_IF(!handles, MAPI_E_INVALID_PARAMETER, NULL); OPENCHANGE_RETVAL_IF(!size, MAPI_E_INVALID_PARAMETER, NULL); mapi_repl->opnum = mapi_req->opnum; mapi_repl->handle_idx = mapi_req->handle_idx; mapi_repl->error_code = MAPI_E_NOT_IMPLEMENTED; *size += libmapiserver_RopGetStoreState_size(mapi_repl); handles[mapi_repl->handle_idx] = handles[mapi_req->handle_idx]; return MAPI_E_SUCCESS; } openchange-2.0/mapiproxy/servers/default/emsmdb/oxctabl.c000066400000000000000000001013011223057412600236740ustar00rootroot00000000000000/* OpenChange Server implementation EMSMDBP: EMSMDB Provider implementation Copyright (C) Julien Kerihuel 2009-2013 This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see . */ /** \file oxctabl.c \brief Table object routines and Rops */ #include "mapiproxy/dcesrv_mapiproxy.h" #include "mapiproxy/libmapiproxy/libmapiproxy.h" #include "mapiproxy/libmapiserver/libmapiserver.h" #include "dcesrv_exchange_emsmdb.h" #include "libmapi/libmapi_private.h" /** \details EcDoRpc SetColumns (0x12) Rop. This operation sets the properties to be included in the table. \param mem_ctx pointer to the memory context \param emsmdbp_ctx pointer to the emsmdb provider context \param mapi_req pointer to the SetColumns EcDoRpc_MAPI_REQ structure \param mapi_repl pointer to the SetColumns EcDoRpc_MAPI_REPL structure \param handles pointer to the MAPI handles array \param size pointer to the mapi_response size to update \return MAPI_E_SUCCESS on success, otherwise MAPI error */ _PUBLIC_ enum MAPISTATUS EcDoRpc_RopSetColumns(TALLOC_CTX *mem_ctx, struct emsmdbp_context *emsmdbp_ctx, struct EcDoRpc_MAPI_REQ *mapi_req, struct EcDoRpc_MAPI_REPL *mapi_repl, uint32_t *handles, uint16_t *size) { enum MAPISTATUS retval; struct mapi_handles *parent; struct emsmdbp_object *object; struct emsmdbp_object_table *table; struct SetColumns_req request; void *data = NULL; uint32_t handle; DEBUG(4, ("exchange_emsmdb: [OXCTABL] SetColumns (0x12)\n")); /* Sanity checks */ OPENCHANGE_RETVAL_IF(!emsmdbp_ctx, MAPI_E_NOT_INITIALIZED, NULL); OPENCHANGE_RETVAL_IF(!mapi_req, MAPI_E_INVALID_PARAMETER, NULL); OPENCHANGE_RETVAL_IF(!mapi_repl, MAPI_E_INVALID_PARAMETER, NULL); OPENCHANGE_RETVAL_IF(!handles, MAPI_E_INVALID_PARAMETER, NULL); OPENCHANGE_RETVAL_IF(!size, MAPI_E_INVALID_PARAMETER, NULL); /* Initialize default empty SetColumns reply */ mapi_repl->opnum = mapi_req->opnum; mapi_repl->handle_idx = mapi_req->handle_idx; mapi_repl->error_code = MAPI_E_SUCCESS; mapi_repl->u.mapi_SetColumns.TableStatus = TBLSTAT_COMPLETE; *size += libmapiserver_RopSetColumns_size(mapi_repl); handle = handles[mapi_req->handle_idx]; retval = mapi_handles_search(emsmdbp_ctx->handles_ctx, handle, &parent); if (retval) { mapi_repl->error_code = MAPI_E_INVALID_OBJECT; DEBUG(5, (" handle (%x) not found: %x\n", handle, mapi_req->handle_idx)); goto end; } retval = mapi_handles_get_private_data(parent, &data); if (retval) { mapi_repl->error_code = retval; DEBUG(5, (" handle data not found, idx = %x\n", mapi_req->handle_idx)); goto end; } object = (struct emsmdbp_object *) data; if (object) { table = object->object.table; OPENCHANGE_RETVAL_IF(!table, MAPI_E_INVALID_PARAMETER, NULL); if (table->ulType == MAPISTORE_RULE_TABLE) { DEBUG(5, (" query on rules table are all faked right now\n")); goto end; } request = mapi_req->u.mapi_SetColumns; if (request.prop_count) { table->prop_count = request.prop_count; table->properties = talloc_memdup(table, request.properties, request.prop_count * sizeof (uint32_t)); if (emsmdbp_is_mapistore(object)) { DEBUG(5, ("[%s] object: %p, backend_object: %p\n", __FUNCTION__, object, object->backend_object)); mapistore_table_set_columns(emsmdbp_ctx->mstore_ctx, emsmdbp_get_contextID(object), object->backend_object, request.prop_count, request.properties); } else { /* openchangedb case */ DEBUG(5, ("[%s] object: Setting Columns on openchangedb table\n", __FUNCTION__)); } } } end: return MAPI_E_SUCCESS; } /** \details EcDoRpc SortTable (0x13) Rop. This operation defines the order of rows of a table based on sort criteria. \param mem_ctx pointer to the memory context \param emsmdbp_ctx pointer to the emsmdb provider context \param mapi_req pointer to the SortTable EcDoRpc_MAPI_REQ structure \param mapi_repl pointer to the SortTable EcDoRpc_MAPI_REPL structure \param handles pointer to the MAPI handles array \param size pointer to the mapi_response size to update \return MAPI_E_SUCCESS on success, otherwise MAPI error */ _PUBLIC_ enum MAPISTATUS EcDoRpc_RopSortTable(TALLOC_CTX *mem_ctx, struct emsmdbp_context *emsmdbp_ctx, struct EcDoRpc_MAPI_REQ *mapi_req, struct EcDoRpc_MAPI_REPL *mapi_repl, uint32_t *handles, uint16_t *size) { enum MAPISTATUS retval; struct mapi_handles *parent; struct emsmdbp_object *object; struct emsmdbp_object_table *table; struct SortTable_req *request; uint32_t handle; void *data = NULL; uint8_t status; DEBUG(4, ("exchange_emsmdb: [OXCTABL] SortTable (0x13)\n")); /* Sanity checks */ OPENCHANGE_RETVAL_IF(!emsmdbp_ctx, MAPI_E_NOT_INITIALIZED, NULL); OPENCHANGE_RETVAL_IF(!mapi_req, MAPI_E_INVALID_PARAMETER, NULL); OPENCHANGE_RETVAL_IF(!mapi_repl, MAPI_E_INVALID_PARAMETER, NULL); OPENCHANGE_RETVAL_IF(!handles, MAPI_E_INVALID_PARAMETER, NULL); OPENCHANGE_RETVAL_IF(!size, MAPI_E_INVALID_PARAMETER, NULL); mapi_repl->opnum = mapi_req->opnum; mapi_repl->handle_idx = mapi_req->handle_idx; mapi_repl->error_code = MAPI_E_SUCCESS; mapi_repl->u.mapi_SortTable.TableStatus = TBLSTAT_COMPLETE; if ((mapi_req->u.mapi_SortTable.SortTableFlags & TBL_ASYNC)) { DEBUG(5, (" requested async operation -> failure\n")); mapi_repl->error_code = MAPI_E_UNKNOWN_FLAGS; goto end; } handle = handles[mapi_req->handle_idx]; retval = mapi_handles_search(emsmdbp_ctx->handles_ctx, handle, &parent); if (retval) { mapi_repl->error_code = MAPI_E_INVALID_OBJECT; DEBUG(5, (" handle (%x) not found: %x\n", handle, mapi_req->handle_idx)); goto end; } retval = mapi_handles_get_private_data(parent, &data); if (retval) { mapi_repl->error_code = retval; DEBUG(5, (" handle data not found, idx = %x\n", mapi_req->handle_idx)); goto end; } object = (struct emsmdbp_object *) data; /* Ensure referring object exists and is a table */ if (!object || (object->type != EMSMDBP_OBJECT_TABLE)) { mapi_repl->error_code = MAPI_E_INVALID_OBJECT; DEBUG(5, (" missing object or not table\n")); goto end; } table = object->object.table; OPENCHANGE_RETVAL_IF(!table, MAPI_E_INVALID_PARAMETER, NULL); if (table->ulType != MAPISTORE_MESSAGE_TABLE && table->ulType != MAPISTORE_FAI_TABLE) { mapi_repl->error_code = MAPI_E_NO_SUPPORT; DEBUG(5, (" query performed on non contents table\n")); goto end; } OPENCHANGE_RETVAL_IF(!mapi_req, MAPI_E_INVALID_PARAMETER, NULL); /* we reset the cursor to the beginning of the table */ table->numerator = 0; /* TODO: we should invalidate current bookmarks on the table */ /* If parent folder has a mapistore context */ request = &mapi_req->u.mapi_SortTable; if (emsmdbp_is_mapistore(object)) { status = TBLSTAT_COMPLETE; retval = mapistore_table_set_sort_order(emsmdbp_ctx->mstore_ctx, emsmdbp_get_contextID(object), object->backend_object, &request->lpSortCriteria, &status); if (retval) { mapi_repl->error_code = retval; goto end; } mapi_repl->u.mapi_SortTable.TableStatus = status; } else { /* Parent folder doesn't have any mapistore context associated */ status = TBLSTAT_COMPLETE; mapi_repl->u.mapi_SortTable.TableStatus = status; retval = openchangedb_table_set_sort_order(object->backend_object, &request->lpSortCriteria); if (retval) { mapi_repl->error_code = retval; goto end; } } end: *size += libmapiserver_RopSortTable_size(mapi_repl); return MAPI_E_SUCCESS; } /** \details EcDoRpc SortTable (0x14) Rop. This operation establishes a filter for a table. \param mem_ctx pointer to the memory context \param emsmdbp_ctx pointer to the emsmdb provider context \param mapi_req pointer to the Restrict EcDoRpc_MAPI_REQ structure \param mapi_repl pointer to the Restrict EcDoRpc_MAPI_REPL structure \param handles pointer to the MAPI handles array \param size pointer to the mapi_response size to update \return MAPI_E_SUCCESS on success, otherwise MAPI error */ _PUBLIC_ enum MAPISTATUS EcDoRpc_RopRestrict(TALLOC_CTX *mem_ctx, struct emsmdbp_context *emsmdbp_ctx, struct EcDoRpc_MAPI_REQ *mapi_req, struct EcDoRpc_MAPI_REPL *mapi_repl, uint32_t *handles, uint16_t *size) { enum MAPISTATUS retval; struct mapi_handles *parent; struct emsmdbp_object *object; struct emsmdbp_object_table *table; struct Restrict_req request; uint32_t handle, contextID; void *data = NULL; uint8_t status; DEBUG(4, ("exchange_emsmdb: [OXCTABL] Restrict (0x14)\n")); /* Sanity checks */ OPENCHANGE_RETVAL_IF(!emsmdbp_ctx, MAPI_E_NOT_INITIALIZED, NULL); OPENCHANGE_RETVAL_IF(!mapi_req, MAPI_E_INVALID_PARAMETER, NULL); OPENCHANGE_RETVAL_IF(!mapi_repl, MAPI_E_INVALID_PARAMETER, NULL); OPENCHANGE_RETVAL_IF(!handles, MAPI_E_INVALID_PARAMETER, NULL); OPENCHANGE_RETVAL_IF(!size, MAPI_E_INVALID_PARAMETER, NULL); request = mapi_req->u.mapi_Restrict; mapi_repl->opnum = mapi_req->opnum; mapi_repl->handle_idx = mapi_req->handle_idx; mapi_repl->error_code = MAPI_E_SUCCESS; mapi_repl->u.mapi_Restrict.TableStatus = TBLSTAT_COMPLETE; handle = handles[mapi_req->handle_idx]; retval = mapi_handles_search(emsmdbp_ctx->handles_ctx, handle, &parent); if (retval) { mapi_repl->error_code = MAPI_E_INVALID_OBJECT; DEBUG(5, (" handle (%x) not found: %x\n", handle, mapi_req->handle_idx)); goto end; } retval = mapi_handles_get_private_data(parent, &data); if (retval) { mapi_repl->error_code = retval; DEBUG(5, (" handle data not found, idx = %x\n", mapi_req->handle_idx)); goto end; } object = (struct emsmdbp_object *) data; /* Ensure referring object exists and is a table */ if (!object || (object->type != EMSMDBP_OBJECT_TABLE)) { mapi_repl->error_code = MAPI_E_INVALID_OBJECT; DEBUG(5, (" missing object or not table\n")); goto end; } table = object->object.table; OPENCHANGE_RETVAL_IF(!table, MAPI_E_INVALID_PARAMETER, NULL); table->restricted = true; if (table->ulType == MAPISTORE_RULE_TABLE) { DEBUG(5, (" query on rules table are all faked right now\n")); goto end; } /* If parent folder has a mapistore context */ if (emsmdbp_is_mapistore(object)) { status = TBLSTAT_COMPLETE; contextID = emsmdbp_get_contextID(object); retval = mapistore_table_set_restrictions(emsmdbp_ctx->mstore_ctx, contextID, object->backend_object, &request.restrictions, &status); if (retval) { mapi_repl->error_code = retval; goto end; } mapistore_table_get_row_count(emsmdbp_ctx->mstore_ctx, contextID, object->backend_object, MAPISTORE_PREFILTERED_QUERY, &object->object.table->denominator); mapi_repl->u.mapi_Restrict.TableStatus = status; /* Parent folder doesn't have any mapistore context associated */ } else { DEBUG(0, ("not mapistore Restrict: Not implemented yet\n")); goto end; } end: *size += libmapiserver_RopRestrict_size(mapi_repl); return MAPI_E_SUCCESS; } /** \details EcDoRpc QueryRows (0x15) Rop. This operation retrieves rows from a table. \param mem_ctx pointer to the memory context \param emsmdbp_ctx pointer to the emsmdb provider context \param mapi_req pointer to the QueryRows EcDoRpc_MAPI_REQ structure \param mapi_repl pointer to the QueryRows EcDoRpc_MAPI_REPL structure \param handles pointer to the MAPI handles array \param size pointer to the mapi_response size to update */ _PUBLIC_ enum MAPISTATUS EcDoRpc_RopQueryRows(TALLOC_CTX *mem_ctx, struct emsmdbp_context *emsmdbp_ctx, struct EcDoRpc_MAPI_REQ *mapi_req, struct EcDoRpc_MAPI_REPL *mapi_repl, uint32_t *handles, uint16_t *size) { struct mapi_handles *parent; struct emsmdbp_object *object; struct emsmdbp_object_table *table; struct QueryRows_req *request; struct QueryRows_repl *response; enum MAPISTATUS retval; void *data; enum MAPISTATUS *retvals; void **data_pointers; uint32_t count, max; uint32_t handle; uint32_t i = 0; DEBUG(4, ("exchange_emsmdb: [OXCTABL] QueryRows (0x15)\n")); /* Sanity checks */ OPENCHANGE_RETVAL_IF(!emsmdbp_ctx, MAPI_E_NOT_INITIALIZED, NULL); OPENCHANGE_RETVAL_IF(!mapi_req, MAPI_E_INVALID_PARAMETER, NULL); OPENCHANGE_RETVAL_IF(!mapi_repl, MAPI_E_INVALID_PARAMETER, NULL); OPENCHANGE_RETVAL_IF(!handles, MAPI_E_INVALID_PARAMETER, NULL); OPENCHANGE_RETVAL_IF(!size, MAPI_E_INVALID_PARAMETER, NULL); request = &mapi_req->u.mapi_QueryRows; response = &mapi_repl->u.mapi_QueryRows; mapi_repl->opnum = mapi_req->opnum; mapi_repl->handle_idx = mapi_req->handle_idx; mapi_repl->error_code = MAPI_E_NOT_FOUND; response->RowData.length = 0; handle = handles[mapi_req->handle_idx]; retval = mapi_handles_search(emsmdbp_ctx->handles_ctx, handle, &parent); if (retval) { mapi_repl->error_code = MAPI_E_INVALID_OBJECT; DEBUG(5, (" handle (%x) not found: %x\n", handle, mapi_req->handle_idx)); goto end; } retval = mapi_handles_get_private_data(parent, &data); if (retval) { DEBUG(5, (" handle data not found, idx = %x\n", mapi_req->handle_idx)); goto end; } object = (struct emsmdbp_object *) data; /* Ensure referring object exists and is a table */ if (!object) { DEBUG(5, (" missing object\n")); goto end; } if (object->type != EMSMDBP_OBJECT_TABLE) { DEBUG(5, (" unhandled object type: %d\n", object->type)); goto end; } table = object->object.table; count = 0; if (table->ulType == MAPISTORE_RULE_TABLE) { DEBUG(5, (" query on rules table are all faked right now\n")); goto finish; } /* Ensure we are in a case which we can handle, until the featureset is complete. */ if (!request->ForwardRead) { DEBUG(0, (" !ForwardRead is not supported yet\n")); abort(); } /* Lookup the properties */ max = table->numerator + request->RowCount; if (max > table->denominator) { max = table->denominator; } for (i = table->numerator; i < max; i++) { data_pointers = emsmdbp_object_table_get_row_props(mem_ctx, emsmdbp_ctx, object, i, MAPISTORE_PREFILTERED_QUERY, &retvals); if (data_pointers) { emsmdbp_fill_table_row_blob(mem_ctx, emsmdbp_ctx, &response->RowData, table->prop_count, table->properties, data_pointers, retvals); talloc_free(retvals); talloc_free(data_pointers); count++; } else { count = 0; goto finish; } } finish: if ((request->QueryRowsFlags & TBL_NOADVANCE) != TBL_NOADVANCE) { table->numerator = i; } /* QueryRows reply parameters */ mapi_repl->error_code = MAPI_E_SUCCESS; response->RowCount = count; if (count) { if ((count < request->RowCount) || (table->numerator > (table->denominator - 2))) { response->Origin = BOOKMARK_END; } else { response->Origin = BOOKMARK_CURRENT; } /* dump_data(0, response.RowData.data, response.RowData.length); */ } else { /* useless code for the moment */ if (table->restricted) { response->Origin = BOOKMARK_BEGINNING; } else { response->Origin = BOOKMARK_END; } response->RowData.length = 0; response->RowData.data = NULL; DEBUG(5, ("%s: returning empty data set\n", __location__)); } end: *size += libmapiserver_RopQueryRows_size(mapi_repl); return MAPI_E_SUCCESS; } /** \details EcDoRpc QueryPosition (0x17) Rop. This operation returns the location of cursor in the table. \param mem_ctx pointer to the memory context \param emsmdbp_ctx pointer to the emsmdb provider context \param mapi_req pointer to the QueryPosition EcDoRpc_MAPI_REQ structure \param mapi_repl pointer to the QueryPosition EcDoRpc_MAPI_REPL structure \param handles pointer to the MAPI handles array \param size pointer to the mapi_response size to update \return MAPI_E_SUCCESS on success, otherwise MAPI error */ _PUBLIC_ enum MAPISTATUS EcDoRpc_RopQueryPosition(TALLOC_CTX *mem_ctx, struct emsmdbp_context *emsmdbp_ctx, struct EcDoRpc_MAPI_REQ *mapi_req, struct EcDoRpc_MAPI_REPL *mapi_repl, uint32_t *handles, uint16_t *size) { enum MAPISTATUS retval; struct mapi_handles *parent; struct emsmdbp_object *object; struct emsmdbp_object_table *table; void *data; uint32_t handle; DEBUG(4, ("exchange_emsmdb: [OXCTABL] QueryPosition (0x17)\n")); /* Sanity checks */ OPENCHANGE_RETVAL_IF(!emsmdbp_ctx, MAPI_E_NOT_INITIALIZED, NULL); OPENCHANGE_RETVAL_IF(!mapi_req, MAPI_E_INVALID_PARAMETER, NULL); OPENCHANGE_RETVAL_IF(!mapi_repl, MAPI_E_INVALID_PARAMETER, NULL); OPENCHANGE_RETVAL_IF(!handles, MAPI_E_INVALID_PARAMETER, NULL); OPENCHANGE_RETVAL_IF(!size, MAPI_E_INVALID_PARAMETER, NULL); mapi_repl->opnum = mapi_req->opnum; mapi_repl->handle_idx = mapi_req->handle_idx; mapi_repl->error_code = MAPI_E_NOT_FOUND; handle = handles[mapi_req->handle_idx]; retval = mapi_handles_search(emsmdbp_ctx->handles_ctx, handle, &parent); if (retval) { mapi_repl->error_code = MAPI_E_INVALID_OBJECT; DEBUG(5, (" handle (%x) not found: %x\n", handle, mapi_req->handle_idx)); goto end; } retval = mapi_handles_get_private_data(parent, &data); if (retval) { DEBUG(5, (" no private data or object is not a table")); goto end; } object = (struct emsmdbp_object *) data; /* Ensure object exists and is table type */ if (!object || (object->type != EMSMDBP_OBJECT_TABLE)) { DEBUG(5, (" no object or object is not a table\n")); goto end; } table = object->object.table; mapi_repl->u.mapi_QueryPosition.Numerator = table->numerator; mapi_repl->u.mapi_QueryPosition.Denominator = table->denominator; mapi_repl->error_code = MAPI_E_SUCCESS; end: *size += libmapiserver_RopQueryPosition_size(mapi_repl); return MAPI_E_SUCCESS; } /** \details EcDoRpc SeekRow (0x18) Rop. This operation moves the cursor to a specific position in a table. \param mem_ctx pointer to the memory context \param emsmdbp_ctx pointer to the emsmdb provider context \param mapi_req pointer to the SeekRow EcDoRpc_MAPI_REQ structure \param mapi_repl pointer to the SeekRow EcDoRpc_MAPI_REPL structure \param handles pointer to the MAPI handles array \param size pointer to the mapi_response size to update \return MAPI_E_SUCCESS on success, otherwise MAPI error */ _PUBLIC_ enum MAPISTATUS EcDoRpc_RopSeekRow(TALLOC_CTX *mem_ctx, struct emsmdbp_context *emsmdbp_ctx, struct EcDoRpc_MAPI_REQ *mapi_req, struct EcDoRpc_MAPI_REPL *mapi_repl, uint32_t *handles, uint16_t *size) { uint32_t handle; enum MAPISTATUS retval; struct mapi_handles *parent; struct emsmdbp_object *object; struct emsmdbp_object_table *table; void *data; int32_t next_position; DEBUG(4, ("exchange_emsmdb: [OXCTABL] SeekRow (0x18)\n")); /* Sanity checks */ OPENCHANGE_RETVAL_IF(!emsmdbp_ctx, MAPI_E_NOT_INITIALIZED, NULL); OPENCHANGE_RETVAL_IF(!mapi_req, MAPI_E_INVALID_PARAMETER, NULL); OPENCHANGE_RETVAL_IF(!mapi_repl, MAPI_E_INVALID_PARAMETER, NULL); OPENCHANGE_RETVAL_IF(!handles, MAPI_E_INVALID_PARAMETER, NULL); OPENCHANGE_RETVAL_IF(!size, MAPI_E_INVALID_PARAMETER, NULL); mapi_repl->opnum = mapi_req->opnum; mapi_repl->handle_idx = mapi_req->handle_idx; mapi_repl->error_code = MAPI_E_SUCCESS; mapi_repl->u.mapi_SeekRow.HasSoughtLess = 0; mapi_repl->u.mapi_SeekRow.RowsSought = 0; handle = handles[mapi_req->handle_idx]; retval = mapi_handles_search(emsmdbp_ctx->handles_ctx, handle, &parent); if (retval) { mapi_repl->error_code = MAPI_E_INVALID_OBJECT; DEBUG(5, (" handle (%x) not found: %x\n", handle, mapi_req->handle_idx)); goto end; } retval = mapi_handles_get_private_data(parent, &data); if (retval) { mapi_repl->error_code = retval; DEBUG(5, (" handle data not found, idx = %x\n", mapi_req->handle_idx)); goto end; } object = (struct emsmdbp_object *) data; /* Ensure object exists and is table type */ if (!object || (object->type != EMSMDBP_OBJECT_TABLE)) { mapi_repl->error_code = MAPI_E_INVALID_OBJECT; DEBUG(5, (" no object or object is not a table\n")); goto end; } /* We don't handle backward/forward yet , just go through the * entire table, nor do we handle bookmarks */ table = object->object.table; if (mapi_req->u.mapi_SeekRow.origin == BOOKMARK_BEGINNING) { next_position = mapi_req->u.mapi_SeekRow.offset; } else if (mapi_req->u.mapi_SeekRow.origin == BOOKMARK_CURRENT) { next_position = table->numerator + mapi_req->u.mapi_SeekRow.offset; } else if (mapi_req->u.mapi_SeekRow.origin == BOOKMARK_END) { next_position = table->denominator - 1 + mapi_req->u.mapi_SeekRow.offset; } else { next_position = 0; mapi_repl->error_code = MAPI_E_NOT_FOUND; DEBUG(5, (" unhandled 'origin' type: %d\n", mapi_req->u.mapi_SeekRow.origin)); } if (mapi_repl->error_code == MAPI_E_SUCCESS) { if (next_position < 0) { next_position = 0; mapi_repl->u.mapi_SeekRow.HasSoughtLess = 1; } else if (next_position >= table->denominator) { next_position = table->denominator - 1; mapi_repl->u.mapi_SeekRow.HasSoughtLess = 1; } if (mapi_req->u.mapi_SeekRow.WantRowMovedCount) { mapi_repl->u.mapi_SeekRow.RowsSought = (next_position - table->numerator); } else { mapi_repl->u.mapi_SeekRow.RowsSought = 0; } table->numerator = next_position; } end: *size += libmapiserver_RopSeekRow_size(mapi_repl); return MAPI_E_SUCCESS; } /** \details EcDoRpc FindRow (0x4f) Rop. This operation moves the cursor to a row in a table that matches specific search criteria. \param mem_ctx pointer to the memory context \param emsmdbp_ctx pointer to the emsmdb provider context \param mapi_req pointer to the FindRow EcDoRpc_MAPI_REQ structure \param mapi_repl pointer to the FindRow EcDoRpc_MAPI_REPL structure \param handles pointer to the MAPI handles array \param size pointer to the mapi_response size to update \return MAPI_E_SUCCESS on success, otherwise MAPI error */ _PUBLIC_ enum MAPISTATUS EcDoRpc_RopFindRow(TALLOC_CTX *mem_ctx, struct emsmdbp_context *emsmdbp_ctx, struct EcDoRpc_MAPI_REQ *mapi_req, struct EcDoRpc_MAPI_REPL *mapi_repl, uint32_t *handles, uint16_t *size) { struct mapi_handles *parent; struct emsmdbp_object *object; struct emsmdbp_object_table *table; struct FindRow_req request; enum MAPISTATUS retval; void *data = NULL; enum MAPISTATUS *retvals; void **data_pointers; uint32_t handle; DATA_BLOB row; uint32_t property; uint8_t flagged; uint8_t status = 0; uint32_t i; bool found = false; DEBUG(4, ("exchange_emsmdb: [OXCTABL] FindRow (0x4f)\n")); /* Sanity checks */ OPENCHANGE_RETVAL_IF(!emsmdbp_ctx, MAPI_E_NOT_INITIALIZED, NULL); OPENCHANGE_RETVAL_IF(!mapi_req, MAPI_E_INVALID_PARAMETER, NULL); OPENCHANGE_RETVAL_IF(!mapi_repl, MAPI_E_INVALID_PARAMETER, NULL); OPENCHANGE_RETVAL_IF(!handles, MAPI_E_INVALID_PARAMETER, NULL); OPENCHANGE_RETVAL_IF(!size, MAPI_E_INVALID_PARAMETER, NULL); request = mapi_req->u.mapi_FindRow; mapi_repl->opnum = mapi_req->opnum; mapi_repl->handle_idx = mapi_req->handle_idx; mapi_repl->error_code = MAPI_E_SUCCESS; mapi_repl->u.mapi_FindRow.RowNoLongerVisible = 0; mapi_repl->u.mapi_FindRow.HasRowData = 0; mapi_repl->u.mapi_FindRow.row.length = 0; mapi_repl->u.mapi_FindRow.row.data = NULL; handle = handles[mapi_req->handle_idx]; retval = mapi_handles_search(emsmdbp_ctx->handles_ctx, handle, &parent); if (retval) { mapi_repl->error_code = MAPI_E_INVALID_OBJECT; DEBUG(5, (" handle (%x) not found: %x\n", handle, mapi_req->handle_idx)); goto end; } retval = mapi_handles_get_private_data(parent, &data); if (retval) { mapi_repl->error_code = retval; DEBUG(5, (" handle data not found, idx = %x\n", mapi_req->handle_idx)); goto end; } object = (struct emsmdbp_object *) data; /* Ensure object exists and is table type */ if (!object || (object->type != EMSMDBP_OBJECT_TABLE)) { mapi_repl->error_code = MAPI_E_INVALID_OBJECT; DEBUG(5, (" no object or object is not a table\n")); goto end; } /* We don't handle backward/forward yet , just go through the * entire table, nor do we handle bookmarks */ table = object->object.table; if (table->ulType == MAPISTORE_RULE_TABLE) { DEBUG(5, (" query on rules table are all faked right now\n")); goto end; } if (mapi_req->u.mapi_FindRow.origin == BOOKMARK_BEGINNING) { table->numerator = 0; } if (mapi_req->u.mapi_FindRow.ulFlags == DIR_BACKWARD) { DEBUG(5, (" only DIR_FORWARD is supported right now, using work-around\n")); table->numerator = 0; } memset (&row, 0, sizeof(DATA_BLOB)); switch (emsmdbp_is_mapistore(object)) { case true: /* Restrict rows to be fetched */ retval = mapistore_table_set_restrictions(emsmdbp_ctx->mstore_ctx, emsmdbp_get_contextID(object), object->backend_object, &request.res, &status); /* Then fetch rows */ /* Lookup the properties and check if we need to flag the PropertyRow blob */ while (!found && table->numerator < table->denominator) { flagged = 0; data_pointers = emsmdbp_object_table_get_row_props(NULL, emsmdbp_ctx, object, table->numerator, MAPISTORE_LIVEFILTERED_QUERY, &retvals); if (data_pointers) { found = true; for (i = 0; i < table->prop_count; i++) { if (retvals[i] != MAPI_E_SUCCESS) { flagged = 1; } } if (flagged) { libmapiserver_push_property(mem_ctx, 0x0000000b, (const void *)&flagged, &row, 0, 0, 0); } else { libmapiserver_push_property(mem_ctx, 0x00000000, (const void *)&flagged, &row, 0, 1, 0); } /* Push the properties */ for (i = 0; i < table->prop_count; i++) { property = table->properties[i]; retval = retvals[i]; if (retval == MAPI_E_NOT_FOUND) { property = (property & 0xFFFF0000) + PT_ERROR; data = &retval; } else { data = data_pointers[i]; } libmapiserver_push_property(mem_ctx, property, data, &row, flagged?PT_ERROR:0, flagged, 0); } talloc_free(retvals); talloc_free(data_pointers); } else { table->numerator++; } } retval = mapistore_table_set_restrictions(emsmdbp_ctx->mstore_ctx, emsmdbp_get_contextID(object), object->backend_object, NULL, &status); /* Adjust parameters */ if (found) { mapi_repl->u.mapi_FindRow.HasRowData = 1; } else { mapi_repl->error_code = MAPI_E_NOT_FOUND; } mapi_repl->u.mapi_FindRow.row.length = row.length; mapi_repl->u.mapi_FindRow.row.data = row.data; break; case false: memset (&row, 0, sizeof(DATA_BLOB)); DEBUG(0, ("FindRow for openchangedb\n")); /* Restrict rows to be fetched */ retval = openchangedb_table_set_restrictions(object->backend_object, &request.res); /* Then fetch rows */ /* Lookup the properties and check if we need to flag the PropertyRow blob */ while (!found && table->numerator < table->denominator) { flagged = 0; data_pointers = emsmdbp_object_table_get_row_props(NULL, emsmdbp_ctx, object, table->numerator, MAPISTORE_LIVEFILTERED_QUERY, &retvals); if (data_pointers) { found = true; for (i = 0; i < table->prop_count; i++) { if (retvals[i] != MAPI_E_SUCCESS) { flagged = 1; } } if (flagged) { libmapiserver_push_property(mem_ctx, 0x0000000b, (const void *)&flagged, &row, 0, 0, 0); } else { libmapiserver_push_property(mem_ctx, 0x00000000, (const void *)&flagged, &row, 0, 1, 0); } /* Push the properties */ for (i = 0; i < table->prop_count; i++) { property = table->properties[i]; retval = retvals[i]; if (retval == MAPI_E_NOT_FOUND) { property = (property & 0xFFFF0000) + PT_ERROR; data = &retval; } else { data = data_pointers[i]; } libmapiserver_push_property(mem_ctx, property, data, &row, flagged?PT_ERROR:0, flagged, 0); } talloc_free(retvals); talloc_free(data_pointers); } else { table->numerator++; } } /* Reset restrictions */ openchangedb_table_set_restrictions(object->backend_object, NULL); /* Adjust parameters */ if (found) { mapi_repl->u.mapi_FindRow.HasRowData = 1; } else { mapi_repl->error_code = MAPI_E_NOT_FOUND; } mapi_repl->u.mapi_FindRow.row.length = row.length; mapi_repl->u.mapi_FindRow.row.data = row.data; break; } end: *size += libmapiserver_RopFindRow_size(mapi_repl); return MAPI_E_SUCCESS; } /** \details EcDoRpc ResetTable (0x81) Rop. This operation resets the table as follows: - Removes the existing column set, restriction, and sort order (ignored) from the table. - Invalidates bookmarks. (ignored) - Resets the cursor to the beginning of the table. \param mem_ctx pointer to the memory context \param emsmdbp_ctx pointer to the emsmdb provider context \param mapi_req pointer to the SetColumns EcDoRpc_MAPI_REQ structure \param mapi_repl pointer to the SetColumns EcDoRpc_MAPI_REPL structure \param handles pointer to the MAPI handles array \param size pointer to the mapi_response size to update \return MAPI_E_SUCCESS on success, otherwise MAPI error */ _PUBLIC_ enum MAPISTATUS EcDoRpc_RopResetTable(TALLOC_CTX *mem_ctx, struct emsmdbp_context *emsmdbp_ctx, struct EcDoRpc_MAPI_REQ *mapi_req, struct EcDoRpc_MAPI_REPL *mapi_repl, uint32_t *handles, uint16_t *size) { enum MAPISTATUS retval; struct mapi_handles *parent; struct emsmdbp_object *object; struct emsmdbp_object_table *table; void *data; uint32_t handle, contextID; uint8_t status; /* ignored */ DEBUG(4, ("exchange_emsmdb: [OXCTABL] ResetTable (0x81)\n")); /* Sanity checks */ OPENCHANGE_RETVAL_IF(!emsmdbp_ctx, MAPI_E_NOT_INITIALIZED, NULL); OPENCHANGE_RETVAL_IF(!mapi_req, MAPI_E_INVALID_PARAMETER, NULL); OPENCHANGE_RETVAL_IF(!mapi_repl, MAPI_E_INVALID_PARAMETER, NULL); OPENCHANGE_RETVAL_IF(!handles, MAPI_E_INVALID_PARAMETER, NULL); OPENCHANGE_RETVAL_IF(!size, MAPI_E_INVALID_PARAMETER, NULL); /* Initialize default empty ResetTable reply */ mapi_repl->opnum = mapi_req->opnum; mapi_repl->handle_idx = mapi_req->handle_idx; *size += libmapiserver_RopResetTable_size(mapi_repl); handle = handles[mapi_req->handle_idx]; retval = mapi_handles_search(emsmdbp_ctx->handles_ctx, handle, &parent); if (retval) { mapi_repl->error_code = MAPI_E_INVALID_OBJECT; DEBUG(5, (" handle (%x) not found: %x\n", handle, mapi_req->handle_idx)); goto end; } retval = mapi_handles_get_private_data(parent, &data); if (retval) { mapi_repl->error_code = retval; DEBUG(5, (" handle data not found, idx = %x\n", mapi_req->handle_idx)); goto end; } object = (struct emsmdbp_object *) data; /* Ensure referring object exists and is a table */ if (!object || (object->type != EMSMDBP_OBJECT_TABLE)) { mapi_repl->error_code = MAPI_E_INVALID_OBJECT; DEBUG(5, (" missing object or not table\n")); goto end; } mapi_repl->error_code = MAPI_E_SUCCESS; table = object->object.table; if (table->ulType == MAPISTORE_RULE_TABLE) { DEBUG(5, (" query on rules table are all faked right now\n")); } else { /* 1.1. removes the existing column set */ if (table->properties) { talloc_free(table->properties); table->properties = NULL; table->prop_count = 0; } /* 1.2. empty restrictions */ if (emsmdbp_is_mapistore(object)) { contextID = emsmdbp_get_contextID(object); retval = mapistore_table_set_restrictions(emsmdbp_ctx->mstore_ctx, contextID, object->backend_object, NULL, &status); mapistore_table_get_row_count(emsmdbp_ctx->mstore_ctx, contextID, object->backend_object, MAPISTORE_PREFILTERED_QUERY, &object->object.table->denominator); } else { DEBUG(0, (" mapistore Restrict: Not implemented yet\n")); goto end; } /* 3. reset the cursor to the beginning of the table. */ table->numerator = 0; } end: return MAPI_E_SUCCESS; } openchange-2.0/mapiproxy/servers/default/emsmdb/oxomsg.c000066400000000000000000000520201223057412600235570ustar00rootroot00000000000000/* OpenChange Server implementation EMSMDBP: EMSMDB Provider implementation Copyright (C) Brad Hards 2010 This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see . */ /** \file oxomsg.c \brief Server-side message routines and Rops */ #include "mapiproxy/libmapiserver/libmapiserver.h" #include "dcesrv_exchange_emsmdb.h" static void oxomsg_mapistore_handle_message_relocation(struct emsmdbp_context *emsmdbp_ctx, struct emsmdbp_object *old_message_object) { TALLOC_CTX *mem_ctx; enum MAPITAGS properties[] = { PidTagTargetEntryId, PidTagSentMailSvrEID }; uint32_t properties_count = sizeof(properties) / sizeof(enum MAPITAGS); struct mapistore_property_data *property_data; enum MAPITAGS ex_properties[] = { PidTagTargetEntryId, PidTagChangeKey, PidTagPredecessorChangeList }; struct SPropTagArray excluded_tags = { sizeof(ex_properties) / sizeof(enum MAPITAGS), ex_properties }; struct Binary_r *bin_data; struct MessageEntryId *entryID; struct PtypServerId *folderSvrID; uint32_t contextID; uint64_t folderID; uint64_t messageID; uint16_t replID; int ret, i; char *owner; struct emsmdbp_object *folder_object; struct emsmdbp_object *message_object; mem_ctx = talloc_zero(NULL, TALLOC_CTX); property_data = talloc_array(mem_ctx, struct mapistore_property_data, properties_count); contextID = emsmdbp_get_contextID(old_message_object); mapistore_properties_get_properties(emsmdbp_ctx->mstore_ctx, contextID, old_message_object->backend_object, mem_ctx, properties_count, properties, property_data); for (i = 0; i < properties_count; i++) { if (property_data[i].error) { continue; } /* DEBUG(5, (__location__": old message fid: %.16"PRIx64"\n", old_message_object->parent_object->object.folder->folderID)); */ /* DEBUG(5, (__location__": old message mid: %.16"PRIx64"\n", old_message_object->object.message->messageID)); */ owner = emsmdbp_get_owner(old_message_object); bin_data = property_data[i].data; switch (properties[i]) { case PidTagTargetEntryId: entryID = get_MessageEntryId(mem_ctx, bin_data); if (!entryID) { DEBUG(5, (__location__": invalid entryID\n")); continue; } ret = emsmdbp_guid_to_replid(emsmdbp_ctx, owner, &entryID->FolderDatabaseGuid, &replID); if (ret) { DEBUG(5, (__location__": unable to deduce folder replID\n")); continue; } folderID = (entryID->FolderGlobalCounter.value << 16) | replID; /* DEBUG(5, (__location__": dest folder id: %.16"PRIx64"\n", folderID)); */ ret = emsmdbp_guid_to_replid(emsmdbp_ctx, owner, &entryID->MessageDatabaseGuid, &replID); if (ret) { DEBUG(5, (__location__": unable to deduce message replID\n")); continue; } messageID = (entryID->MessageGlobalCounter.value << 16) | replID; /* DEBUG(5, (__location__": dest message id: %.16"PRIx64"\n", messageID)); */ break; case PidTagSentMailSvrEID: folderSvrID = get_PtypServerId(mem_ctx, bin_data); if (!folderSvrID) { DEBUG(5, (__location__": invalid folderSvrID\n")); continue; } folderID = folderSvrID->FolderId; openchangedb_get_new_folderID(emsmdbp_ctx->oc_ctx, &messageID); /* DEBUG(5, (__location__": dest folder id: %.16"PRIx64"\n", folderID)); */ break; default: DEBUG(5, (__location__": invalid entryid property: %.8x\n", properties[i])); continue; } if (emsmdbp_object_open_folder_by_fid(mem_ctx, emsmdbp_ctx, old_message_object, folderID, &folder_object) != MAPISTORE_SUCCESS) { DEBUG(5, (__location__": unable to open folder\n")); continue; } message_object = emsmdbp_object_message_init(mem_ctx, emsmdbp_ctx, messageID, folder_object); if (mapistore_folder_create_message(emsmdbp_ctx->mstore_ctx, contextID, folder_object->backend_object, message_object, messageID, false, &message_object->backend_object)) { DEBUG(5, (__location__": unable to create message in backend\n")); continue; } /* FIXME: (from oxomsg 3.2.5.1) PidTagMessageFlags: mfUnsent and mfRead must be cleared */ emsmdbp_object_copy_properties(emsmdbp_ctx, old_message_object, message_object, &excluded_tags, true); mapistore_message_save(emsmdbp_ctx->mstore_ctx, contextID, message_object->backend_object); mapistore_indexing_record_add_mid(emsmdbp_ctx->mstore_ctx, contextID, owner, messageID); } talloc_free(mem_ctx); } /** \details EcDoRpc SubmitMessage (0x32) Rop. This operation marks a message as being ready to send (subject to some flags). \param mem_ctx pointer to the memory context \param emsmdbp_ctx pointer to the emsmdb provider context \param mapi_req pointer to the SubmitMessage EcDoRpc_MAPI_REQ structure \param mapi_repl pointer to the SubmitMessage EcDoRpc_MAPI_REPL structure \param handles pointer to the MAPI handles array \param size pointer to the mapi_response size to update \return MAPI_E_SUCCESS on success, otherwise MAPI error */ _PUBLIC_ enum MAPISTATUS EcDoRpc_RopSubmitMessage(TALLOC_CTX *mem_ctx, struct emsmdbp_context *emsmdbp_ctx, struct EcDoRpc_MAPI_REQ *mapi_req, struct EcDoRpc_MAPI_REPL *mapi_repl, uint32_t *handles, uint16_t *size) { enum MAPISTATUS retval; uint32_t handle; struct mapi_handles *rec = NULL; void *private_data; bool mapistore = false; struct emsmdbp_object *object; char *owner; uint64_t messageID; uint32_t contextID; uint8_t flags; DEBUG(4, ("exchange_emsmdb: [OXCMSG] SubmitMessage (0x32)\n")); /* Sanity checks */ OPENCHANGE_RETVAL_IF(!emsmdbp_ctx, MAPI_E_NOT_INITIALIZED, NULL); OPENCHANGE_RETVAL_IF(!mapi_req, MAPI_E_INVALID_PARAMETER, NULL); OPENCHANGE_RETVAL_IF(!mapi_repl, MAPI_E_INVALID_PARAMETER, NULL); OPENCHANGE_RETVAL_IF(!handles, MAPI_E_INVALID_PARAMETER, NULL); OPENCHANGE_RETVAL_IF(!size, MAPI_E_INVALID_PARAMETER, NULL); mapi_repl->opnum = mapi_req->opnum; mapi_repl->error_code = MAPI_E_SUCCESS; mapi_repl->handle_idx = mapi_req->handle_idx; handle = handles[mapi_req->handle_idx]; retval = mapi_handles_search(emsmdbp_ctx->handles_ctx, handle, &rec); if (retval) { mapi_repl->error_code = MAPI_E_NOT_FOUND; goto end; } retval = mapi_handles_get_private_data(rec, &private_data); object = (struct emsmdbp_object *)private_data; if (!object || object->type != EMSMDBP_OBJECT_MESSAGE) { mapi_repl->error_code = MAPI_E_NO_SUPPORT; goto end; } mapistore = emsmdbp_is_mapistore(object); switch (mapistore) { case false: DEBUG(0, ("Not implemented yet - shouldn't occur\n")); break; case true: /* Check if we still have uncommitted streams attached to this message */ { struct mapi_handles *handles; for (handles = emsmdbp_ctx->handles_ctx->handles; handles; handles = handles->next) { if (handles->parent_handle == rec->handle) { struct emsmdbp_object *object2 = NULL; void *private_data2; struct mapi_handles *rec2 = NULL; retval = mapi_handles_search(emsmdbp_ctx->handles_ctx, handles->handle, &rec2); if (retval) { continue; } retval = mapi_handles_get_private_data(rec2, &private_data2); object2 = (struct emsmdbp_object *)private_data2; if (object2->type == EMSMDBP_OBJECT_STREAM) { emsmdbp_object_stream_commit(object2); } } } } messageID = object->object.message->messageID; contextID = emsmdbp_get_contextID(object); flags = mapi_req->u.mapi_SubmitMessage.SubmitFlags; owner = emsmdbp_get_owner(object); mapistore_message_submit(emsmdbp_ctx->mstore_ctx, emsmdbp_get_contextID(object), object->backend_object, flags); oxomsg_mapistore_handle_message_relocation(emsmdbp_ctx, object); mapistore_indexing_record_add_mid(emsmdbp_ctx->mstore_ctx, contextID, owner, messageID); break; } end: *size += libmapiserver_RopSubmitMessage_size(mapi_repl); return MAPI_E_SUCCESS; } /* Get the organisation name (like "First Organization") as a DN. */ static bool mapiserver_get_org_dn(struct emsmdbp_context *emsmdbp_ctx, struct ldb_dn **basedn) { int ret; struct ldb_result *res = NULL; ret = ldb_search(emsmdbp_ctx->samdb_ctx, emsmdbp_ctx, &res, ldb_get_config_basedn(emsmdbp_ctx->samdb_ctx), LDB_SCOPE_SUBTREE, NULL, "(|(objectClass=msExchOrganizationContainer))"); /* If the search failed */ if (ret != LDB_SUCCESS) { DEBUG(1, ("exchange_emsmdb: [OXOMSG] mapiserver_get_org_dn ldb_search failure.\n")); return false; } /* If we didn't get the expected entry */ if (res->count != 1) { DEBUG(1, ("exchange_emsmdb: [OXOMSG] mapiserver_get_org_dn unexpected entry count: %i (expected 1).\n", res->count)); return false; } *basedn = ldb_dn_new(emsmdbp_ctx, emsmdbp_ctx->samdb_ctx, ldb_msg_find_attr_as_string(res->msgs[0], "distinguishedName", NULL)); return true; } /** \details EcDoRpc SetSpooler (0x47) Rop. This operation informs the server that the client intends to act as a mail spooler \param mem_ctx pointer to the memory context \param emsmdbp_ctx pointer to the emsmdbp provider context \param mapi_req pointer to the SeSpooler EcDoRpc_MAPI_REQ \param mapi_repl pointer to the SetSpooler EcDoRpc_MAPI_REPL \param handles pointer to the MAPI handles array \param size pointer to the mapi_response size to update \return MAPI_E_SUCCESS on success, otherwise MAPI error */ _PUBLIC_ enum MAPISTATUS EcDoRpc_RopSetSpooler(TALLOC_CTX *mem_ctx, struct emsmdbp_context *emsmdbp_ctx, struct EcDoRpc_MAPI_REQ *mapi_req, struct EcDoRpc_MAPI_REPL *mapi_repl, uint32_t *handles, uint16_t *size) { DEBUG(4, ("exchange_emsmdb: [OXOMSG] SetSpooler (0x47)\n")); /* Sanity checks */ OPENCHANGE_RETVAL_IF(!emsmdbp_ctx, MAPI_E_NOT_INITIALIZED, NULL); OPENCHANGE_RETVAL_IF(!mapi_req, MAPI_E_INVALID_PARAMETER, NULL); OPENCHANGE_RETVAL_IF(!mapi_repl, MAPI_E_INVALID_PARAMETER, NULL); OPENCHANGE_RETVAL_IF(!handles, MAPI_E_INVALID_PARAMETER, NULL); OPENCHANGE_RETVAL_IF(!size, MAPI_E_INVALID_PARAMETER, NULL); mapi_repl->opnum = mapi_req->opnum; mapi_repl->error_code = MAPI_E_SUCCESS; /* TODO: actually implement related server-side behavior */ *size += libmapiserver_RopSetSpooler_size(NULL); return MAPI_E_SUCCESS; } /** \details EcDoRpc GetAddressTypes (0x49) Rop. This operation gets the valid address types (e.g. "SMTP", "X400", "EX") \param mem_ctx pointer to the memory context \param emsmdbp_ctx pointer to the emsmdb provider context \param mapi_req pointer to the AddressTypes EcDoRpc_MAPI_REQ \param mapi_repl pointer to the AddressTypes EcDoRpc_MAPI_REPL \param handles pointer to the MAPI handles array \param size pointer to the mapi_response size to update \return MAPI_E_SUCCESS on success, otherwise MAPI error */ _PUBLIC_ enum MAPISTATUS EcDoRpc_RopGetAddressTypes(TALLOC_CTX *mem_ctx, struct emsmdbp_context *emsmdbp_ctx, struct EcDoRpc_MAPI_REQ *mapi_req, struct EcDoRpc_MAPI_REPL *mapi_repl, uint32_t *handles, uint16_t *size) { enum MAPISTATUS retval = MAPI_E_SUCCESS; int ret; struct ldb_result *res = NULL; const char * const attrs[] = { "msExchTemplateRDNs", NULL }; uint32_t j; struct ldb_dn *basedn = 0; DEBUG(4, ("exchange_emsmdb: [OXOMSG] AddressTypes (0x49)\n")); /* Sanity checks */ OPENCHANGE_RETVAL_IF(!emsmdbp_ctx, MAPI_E_NOT_INITIALIZED, NULL); OPENCHANGE_RETVAL_IF(!mapi_req, MAPI_E_INVALID_PARAMETER, NULL); OPENCHANGE_RETVAL_IF(!mapi_repl, MAPI_E_INVALID_PARAMETER, NULL); OPENCHANGE_RETVAL_IF(!handles, MAPI_E_INVALID_PARAMETER, NULL); OPENCHANGE_RETVAL_IF(!size, MAPI_E_INVALID_PARAMETER, NULL); mapiserver_get_org_dn(emsmdbp_ctx, &basedn); ldb_dn_add_child_fmt(basedn, "CN=ADDRESSING"); ldb_dn_add_child_fmt(basedn, "CN=ADDRESS-TEMPLATES"); ret = ldb_search(emsmdbp_ctx->samdb_ctx, emsmdbp_ctx, &res, basedn, LDB_SCOPE_SUBTREE, attrs, "CN=%x", emsmdbp_ctx->userLanguage); /* If the search failed */ if (ret != LDB_SUCCESS) { DEBUG(1, ("exchange_emsmdb: [OXOMSG] AddressTypes ldb_search failure.\n")); return MAPI_E_CORRUPT_STORE; } /* If we didn't get the expected entry */ if (res->count != 1) { DEBUG(1, ("exchange_emsmdb: [OXOMSG] AddressTypes unexpected entry count: %i (expected 1).\n", res->count)); return MAPI_E_CORRUPT_STORE; } /* If we didn't get the expected number of elements in our record */ if (res->msgs[0]->num_elements != 1) { DEBUG(1, ("exchange_emsmdb: [OXOMSG] AddressTypes unexpected element count: %i (expected 1).\n", res->msgs[0]->num_elements)); return MAPI_E_CORRUPT_STORE; } /* If we didn't get at least one address type, things are probably bad. It _could_ be allowable though. */ if (res->msgs[0]->elements[0].num_values < 1) { DEBUG(1, ("exchange_emsmdb: [OXOMSG] AddressTypes unexpected values count: %i (expected 1).\n", res->msgs[0]->num_elements)); } /* If we got to here, it looks sane. Build the reply message. */ mapi_repl->opnum = mapi_req->opnum; mapi_repl->handle_idx = mapi_req->handle_idx; mapi_repl->error_code = retval; mapi_repl->u.mapi_AddressTypes.cValues = res->msgs[0]->elements[0].num_values; mapi_repl->u.mapi_AddressTypes.size = 0; mapi_repl->u.mapi_AddressTypes.transport = talloc_array(mem_ctx, struct mapi_LPSTR, mapi_repl->u.mapi_AddressTypes.cValues); for (j = 0; j < mapi_repl->u.mapi_AddressTypes.cValues; ++j) { const char *addr_type; addr_type = (const char *)res->msgs[0]->elements[0].values[j].data; mapi_repl->u.mapi_AddressTypes.transport[j].lppszA = talloc_asprintf(mem_ctx, "%s", addr_type); mapi_repl->u.mapi_AddressTypes.size += (strlen(mapi_repl->u.mapi_AddressTypes.transport[j].lppszA) + 1); } *size += libmapiserver_RopGetAddressTypes_size(mapi_repl); handles[mapi_repl->handle_idx] = handles[mapi_req->handle_idx]; return retval; } /** \details EcDoRpc TransportSend (0x4a) Rop. This operation sends a message. \param mem_ctx pointer to the memory context \param emsmdbp_ctx pointer to the emsmdb provider context \param mapi_req pointer to the TransportSend EcDoRpc_MAPI_REQ structure \param mapi_repl pointer to the TransportSend EcDoRpc_MAPI_REPL structure \param handles pointer to the MAPI handles array \param size pointer to the mapi_response size to update \return MAPI_E_SUCCESS on success, otherwise MAPI error */ _PUBLIC_ enum MAPISTATUS EcDoRpc_RopTransportSend(TALLOC_CTX *mem_ctx, struct emsmdbp_context *emsmdbp_ctx, struct EcDoRpc_MAPI_REQ *mapi_req, struct EcDoRpc_MAPI_REPL *mapi_repl, uint32_t *handles, uint16_t *size) { struct TransportSend_repl *response; enum MAPISTATUS retval; uint32_t handle; struct mapi_handles *rec = NULL; void *private_data; bool mapistore = false; struct emsmdbp_object *object; DEBUG(4, ("exchange_emsmdb: [OXCMSG] TransportSend (0x4a)\n")); /* Sanity checks */ OPENCHANGE_RETVAL_IF(!emsmdbp_ctx, MAPI_E_NOT_INITIALIZED, NULL); OPENCHANGE_RETVAL_IF(!mapi_req, MAPI_E_INVALID_PARAMETER, NULL); OPENCHANGE_RETVAL_IF(!mapi_repl, MAPI_E_INVALID_PARAMETER, NULL); OPENCHANGE_RETVAL_IF(!handles, MAPI_E_INVALID_PARAMETER, NULL); OPENCHANGE_RETVAL_IF(!size, MAPI_E_INVALID_PARAMETER, NULL); mapi_repl->opnum = mapi_req->opnum; mapi_repl->error_code = MAPI_E_SUCCESS; mapi_repl->handle_idx = mapi_req->handle_idx; handle = handles[mapi_req->handle_idx]; retval = mapi_handles_search(emsmdbp_ctx->handles_ctx, handle, &rec); if (retval) { mapi_repl->error_code = MAPI_E_NOT_FOUND; goto end; } retval = mapi_handles_get_private_data(rec, &private_data); object = (struct emsmdbp_object *)private_data; if (!object || object->type != EMSMDBP_OBJECT_MESSAGE) { mapi_repl->error_code = MAPI_E_NO_SUPPORT; goto end; } response = &mapi_repl->u.mapi_TransportSend; mapistore = emsmdbp_is_mapistore(object); switch (mapistore) { case false: DEBUG(0, ("Not implemented yet - shouldn't occur\n")); break; case true: mapistore_message_submit(emsmdbp_ctx->mstore_ctx, emsmdbp_get_contextID(object), object->backend_object, 0); oxomsg_mapistore_handle_message_relocation(emsmdbp_ctx, object); /* mapistore_indexing_record_add_mid(emsmdbp_ctx->mstore_ctx, contextID, messageID); */ break; } response->NoPropertiesReturned = 1; end: *size += libmapiserver_RopTransportSend_size(mapi_repl); return MAPI_E_SUCCESS; } /** \details EcDoRpc OptionsData (0x6f) Rop. This doesn't really do anything, but could be used to provide HelpData if we wanted to do something like that later. \param mem_ctx pointer to the memory context \param emsmdbp_ctx pointer to the emsmdb provider context \param mapi_req pointer to the OptionsData EcDoRpc_MAPI_REQ \param mapi_repl pointer to the OptionsData EcDoRpc_MAPI_REPL \param handles pointer to the MAPI handles array \param size pointer to the mapi_response size to update \return MAPI_E_SUCCESS on success, otherwise MAPI error */ _PUBLIC_ enum MAPISTATUS EcDoRpc_RopOptionsData(TALLOC_CTX *mem_ctx, struct emsmdbp_context *emsmdbp_ctx, struct EcDoRpc_MAPI_REQ *mapi_req, struct EcDoRpc_MAPI_REPL *mapi_repl, uint32_t *handles, uint16_t *size) { enum MAPISTATUS retval = MAPI_E_SUCCESS; DEBUG(4, ("exchange_emsmdb: [OXOMSG] OptionsData (0x6f)\n")); /* Sanity checks */ OPENCHANGE_RETVAL_IF(!emsmdbp_ctx, MAPI_E_NOT_INITIALIZED, NULL); OPENCHANGE_RETVAL_IF(!mapi_req, MAPI_E_INVALID_PARAMETER, NULL); OPENCHANGE_RETVAL_IF(!mapi_repl, MAPI_E_INVALID_PARAMETER, NULL); OPENCHANGE_RETVAL_IF(!handles, MAPI_E_INVALID_PARAMETER, NULL); OPENCHANGE_RETVAL_IF(!size, MAPI_E_INVALID_PARAMETER, NULL); mapi_repl->opnum = mapi_req->opnum; mapi_repl->handle_idx = mapi_req->handle_idx; mapi_repl->error_code = retval; mapi_repl->u.mapi_OptionsData.Reserved = 0x01; /* always 1, as specified in the doc */ mapi_repl->u.mapi_OptionsData.OptionsInfo.cb = 0x0000; mapi_repl->u.mapi_OptionsData.OptionsInfo.lpb = talloc_array(mem_ctx, uint8_t, mapi_repl->u.mapi_OptionsData.OptionsInfo.cb); mapi_repl->u.mapi_OptionsData.HelpFileSize = 0x0000; mapi_repl->u.mapi_OptionsData.HelpFile = talloc_array(mem_ctx, uint8_t, mapi_repl->u.mapi_OptionsData.HelpFileSize); *size += libmapiserver_RopOptionsData_size(mapi_repl); handles[mapi_repl->handle_idx] = handles[mapi_req->handle_idx]; return retval; } /** \details EcDoRpc GetTransportFolder (0x6d) ROP. \param mem_ctx pointer to the memory context \param emsmdbp_ctx pointer to the emsmdb provider context \param mapi_req pointer to the GetTransportFolder EcDoRpc_MAPI_REQ \param mapi_repl pointer to the GetTransportFolder EcDoRpc_MAPI_REPL \param handles pointer to the MAPI handles array \param size pointer to the mapi_response size to update \return MAPI_E_SUCCESS on success, otherwise MAPI error */ _PUBLIC_ enum MAPISTATUS EcDoRpc_RopGetTransportFolder(TALLOC_CTX *mem_ctx, struct emsmdbp_context *emsmdbp_ctx, struct EcDoRpc_MAPI_REQ *mapi_req, struct EcDoRpc_MAPI_REPL *mapi_repl, uint32_t *handles, uint16_t *size) { enum MAPISTATUS retval; struct mapi_handles *rec = NULL; struct emsmdbp_object *object = NULL; void *private_data = NULL; uint32_t handle; DEBUG(4, ("exchange_emsmdb: [OXOMSG] GetTransportFolder (0x6d)\n")); /* Sanity checks */ OPENCHANGE_RETVAL_IF(!emsmdbp_ctx, MAPI_E_NOT_INITIALIZED, NULL); OPENCHANGE_RETVAL_IF(!mapi_req, MAPI_E_INVALID_PARAMETER, NULL); OPENCHANGE_RETVAL_IF(!mapi_repl, MAPI_E_INVALID_PARAMETER, NULL); OPENCHANGE_RETVAL_IF(!handles, MAPI_E_INVALID_PARAMETER, NULL); OPENCHANGE_RETVAL_IF(!size, MAPI_E_INVALID_PARAMETER, NULL); mapi_repl->opnum = mapi_req->opnum; mapi_repl->handle_idx = mapi_req->handle_idx; mapi_repl->error_code = MAPI_E_SUCCESS; /* Step 1. Ensure the referring MAPI handle is mailbox one */ handle = handles[mapi_req->handle_idx]; retval = mapi_handles_search(emsmdbp_ctx->handles_ctx, handle, &rec); OPENCHANGE_RETVAL_IF(retval, retval, NULL); retval = mapi_handles_get_private_data(rec, (void **)&private_data); OPENCHANGE_RETVAL_IF(retval, retval, NULL); object = (struct emsmdbp_object *) private_data; if (!object || object->type != EMSMDBP_OBJECT_MAILBOX) { mapi_repl->error_code = ecNullObject; DEBUG(5, (" invalid object\n")); goto end; } /* Step 2. Search for the specified MessageClass substring within user mailbox */ retval = openchangedb_get_TransportFolder(emsmdbp_ctx->oc_ctx, object->object.mailbox->owner_username, &mapi_repl->u.mapi_GetTransportFolder.FolderId); if (retval) { mapi_repl->error_code = MAPI_E_NOT_FOUND; } end: *size += libmapiserver_RopGetTransportFolder_size(mapi_repl); handles[mapi_repl->handle_idx] = handles[mapi_req->handle_idx]; return MAPI_E_SUCCESS; } openchange-2.0/mapiproxy/servers/default/emsmdb/oxorule.c000066400000000000000000000135331223057412600237460ustar00rootroot00000000000000/* OpenChange Server implementation EMSMDBP: EMSMDB Provider implementation Copyright (C) Julien Kerihuel 2009 This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see . */ /** \file oxctabl.c \brief E-mail rules object routines and Rops */ #include "mapiproxy/dcesrv_mapiproxy.h" #include "mapiproxy/libmapiproxy/libmapiproxy.h" #include "mapiproxy/libmapiserver/libmapiserver.h" #include "dcesrv_exchange_emsmdb.h" /** \details EcDoRpc GetRulesTable (0x3f) Rop. This operation gets the rules table of a folder. \param mem_ctx pointer to the memory context \param emsmdbp_ctx pointer to the emsmdb provider context \param mapi_req pointer to the GetRulesTable EcDoRpc_MAPI_REQ structure \param mapi_repl pointer to the GetRulesTable EcDoRpc_MAPI_REPL structure \param handles pointer to the MAPI handles array \param size pointer to the mapi_response size to update \return MAPI_E_SUCCESS on success, otherwise MAPI error */ _PUBLIC_ enum MAPISTATUS EcDoRpc_RopGetRulesTable(TALLOC_CTX *mem_ctx, struct emsmdbp_context *emsmdbp_ctx, struct EcDoRpc_MAPI_REQ *mapi_req, struct EcDoRpc_MAPI_REPL *mapi_repl, uint32_t *handles, uint16_t *size) { enum MAPISTATUS retval; struct mapi_handles *parent; struct mapi_handles *rec; struct emsmdbp_object *object; void *data = NULL; uint32_t handle; DEBUG(4, ("exchange_emsmdb: [OXORULE] GetRulesTable (0x3f) -- stub\n")); /* Sanity checks */ OPENCHANGE_RETVAL_IF(!emsmdbp_ctx, MAPI_E_NOT_INITIALIZED, NULL); OPENCHANGE_RETVAL_IF(!mapi_req, MAPI_E_INVALID_PARAMETER, NULL); OPENCHANGE_RETVAL_IF(!mapi_repl, MAPI_E_INVALID_PARAMETER, NULL); OPENCHANGE_RETVAL_IF(!handles, MAPI_E_INVALID_PARAMETER, NULL); OPENCHANGE_RETVAL_IF(!size, MAPI_E_INVALID_PARAMETER, NULL); /* Initialize default GetRulesTable reply */ mapi_repl->opnum = mapi_req->opnum; mapi_repl->handle_idx = mapi_req->u.mapi_GetRulesTable.handle_idx; mapi_repl->error_code = MAPI_E_SUCCESS; /* Ensure parent handle references a folder object */ handle = handles[mapi_req->handle_idx]; retval = mapi_handles_search(emsmdbp_ctx->handles_ctx, handle, &parent); if (retval) { mapi_repl->error_code = MAPI_E_INVALID_OBJECT; DEBUG(5, (" handle (%x) not found: %x\n", handle, mapi_req->handle_idx)); goto end; } retval = mapi_handles_get_private_data(parent, &data); if (retval) { mapi_repl->error_code = MAPI_E_NOT_FOUND; DEBUG(5, (" handle data not found, idx = %x\n", mapi_req->handle_idx)); goto end; } object = (struct emsmdbp_object *) data; if (object->type != EMSMDBP_OBJECT_FOLDER) { mapi_repl->error_code = MAPI_E_INVALID_OBJECT; DEBUG(5, (" unhandled object type: %d\n", object->type)); goto end; } /* Initialize Table object */ handle = handles[mapi_req->handle_idx]; retval = mapi_handles_add(emsmdbp_ctx->handles_ctx, handle, &rec); handles[mapi_repl->handle_idx] = rec->handle; object = emsmdbp_object_table_init((TALLOC_CTX *)rec, emsmdbp_ctx, object); if (object) { retval = mapi_handles_set_private_data(rec, object); /* rules tables are stub objects for now */ object->object.table->denominator = 0; object->object.table->ulType = MAPISTORE_RULE_TABLE; } end: *size += libmapiserver_RopGetRulesTable_size(); return MAPI_E_SUCCESS; } /** \details EcDoRpc ModifyRules (0x41) Rop. This operation modifies the rules associated with a folder \param mem_ctx pointer to the memory context \param emsmdbp_ctx pointer to the emsmdb provider context \param mapi_req pointer to the ModifyRules EcDoRpc_MAPI_REQ structure \param mapi_repl pointer to the ModifyRules EcDoRpc_MAPI_REPL structure \param handles pointer to the MAPI handles array \param size pointer to the mapi_response size to update \return MAPI_E_SUCCESS on success, otherwise MAPI error */ _PUBLIC_ enum MAPISTATUS EcDoRpc_RopModifyRules(TALLOC_CTX *mem_ctx, struct emsmdbp_context *emsmdbp_ctx, struct EcDoRpc_MAPI_REQ *mapi_req, struct EcDoRpc_MAPI_REPL *mapi_repl, uint32_t *handles, uint16_t *size) { enum MAPISTATUS retval; struct mapi_handles *parent; struct emsmdbp_object *object; void *data = NULL; uint32_t handle; DEBUG(4, ("exchange_emsmdb: [OXORULE] ModifyRules (0x41)\n")); /* Sanity checks */ OPENCHANGE_RETVAL_IF(!emsmdbp_ctx, MAPI_E_NOT_INITIALIZED, NULL); OPENCHANGE_RETVAL_IF(!mapi_req, MAPI_E_INVALID_PARAMETER, NULL); OPENCHANGE_RETVAL_IF(!mapi_repl, MAPI_E_INVALID_PARAMETER, NULL); OPENCHANGE_RETVAL_IF(!handles, MAPI_E_INVALID_PARAMETER, NULL); OPENCHANGE_RETVAL_IF(!size, MAPI_E_INVALID_PARAMETER, NULL); /* Ensure parent handle references a folder object */ handle = handles[mapi_req->handle_idx]; retval = mapi_handles_search(emsmdbp_ctx->handles_ctx, handle, &parent); OPENCHANGE_RETVAL_IF(retval, retval, NULL); /* Initialize default ModifyRules reply */ mapi_repl->opnum = mapi_req->opnum; mapi_repl->handle_idx = mapi_req->handle_idx; mapi_repl->error_code = MAPI_E_SUCCESS; mapi_handles_get_private_data(parent, &data); object = (struct emsmdbp_object *) data; if (!object || object->type != EMSMDBP_OBJECT_FOLDER) { mapi_repl->error_code = MAPI_E_NOT_FOUND; goto end; } handles[mapi_repl->handle_idx] = handles[mapi_req->handle_idx]; end: *size += libmapiserver_RopModifyRules_size(); return MAPI_E_SUCCESS; } openchange-2.0/mapiproxy/servers/default/nspi/000077500000000000000000000000001223057412600216025ustar00rootroot00000000000000openchange-2.0/mapiproxy/servers/default/nspi/dcesrv_exchange_nsp.c000066400000000000000000001263251223057412600257670ustar00rootroot00000000000000/* MAPI Proxy - Exchange NSPI Server OpenChange Project Copyright (C) Julien Kerihuel 2009-2011 This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see . */ /** \file dcesrv_exchange_nsp.c \brief OpenChange NSPI Server implementation */ #include "mapiproxy/dcesrv_mapiproxy.h" #include "dcesrv_exchange_nsp.h" static struct exchange_nsp_session *nsp_session = NULL; static TDB_CONTEXT *emsabp_tdb_ctx = NULL; static struct exchange_nsp_session *dcesrv_find_nsp_session(struct GUID *uuid) { struct exchange_nsp_session *session, *found_session = NULL; for (session = nsp_session; !found_session && session; session = session->next) { if (GUID_equal(uuid, &session->uuid)) { found_session = session; } } return found_session; } static struct emsabp_context *dcesrv_find_emsabp_context(struct GUID *uuid) { struct exchange_nsp_session *session; struct emsabp_context *emsabp_ctx = NULL; session = dcesrv_find_nsp_session(uuid); if (session) { emsabp_ctx = (struct emsabp_context *)session->session->private_data;; } return emsabp_ctx; } /** \details exchange_nsp NspiBind (0x0) function, Initiates a NSPI session with the client. This function checks if the user is an Exchange user and input parameters like codepage are valid. If it passes the tests, the function initializes an emsabp context and returns to the client a valid policy_handle and expected reply parameters. \param dce_call pointer to the session context \param mem_ctx pointer to the memory context \param r pointer to the NspiBind call structure \return MAPI_E_SUCCESS on success, otherwise a MAPI error */ static void dcesrv_NspiBind(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx, struct NspiBind *r) { struct GUID *guid = (struct GUID *) NULL; struct emsabp_context *emsabp_ctx; struct dcesrv_handle *handle; struct policy_handle wire_handle; struct exchange_nsp_session *session; DEBUG(5, ("exchange_nsp: NspiBind (0x0)\n")); /* Step 0. Ensure incoming user is authenticated */ if (!dcesrv_call_authenticated(dce_call) && (r->in.dwFlags & fAnonymousLogin)) { DEBUG(1, ("No challenge requested by client, cannot authenticate\n")); wire_handle.handle_type = EXCHANGE_HANDLE_NSP; wire_handle.uuid = GUID_zero(); *r->out.handle = wire_handle; r->out.mapiuid = r->in.mapiuid; DCESRV_NSP_RETURN(r, MAPI_E_FAILONEPROVIDER, NULL); } /* Step 1. Initialize the emsabp context */ emsabp_ctx = emsabp_init(dce_call->conn->dce_ctx->lp_ctx, emsabp_tdb_ctx); if (!emsabp_ctx) { smb_panic("unable to initialize emsabp context"); DCESRV_NSP_RETURN(r, MAPI_E_FAILONEPROVIDER, NULL); } /* Step 2. Check if incoming user belongs to the Exchange organization */ if ((emsabp_verify_user(dce_call, emsabp_ctx) == false) && (r->in.dwFlags & fAnonymousLogin)) { talloc_free(emsabp_ctx); wire_handle.handle_type = EXCHANGE_HANDLE_NSP; wire_handle.uuid = GUID_zero(); *r->out.handle = wire_handle; r->out.mapiuid = r->in.mapiuid; DCESRV_NSP_RETURN(r, MAPI_E_LOGON_FAILED, emsabp_tdb_ctx); } /* Step 3. Check if valid cpID has been supplied */ if (emsabp_verify_codepage(emsabp_ctx, r->in.pStat->CodePage) == false) { talloc_free(emsabp_ctx); wire_handle.handle_type = EXCHANGE_HANDLE_NSP; wire_handle.uuid = GUID_zero(); *r->out.handle = wire_handle; r->out.mapiuid = r->in.mapiuid; DCESRV_NSP_RETURN(r, MAPI_E_UNKNOWN_CPID, emsabp_tdb_ctx); } /* Step 4. Retrieve OpenChange server GUID */ guid = (struct GUID *) samdb_ntds_objectGUID(emsabp_ctx->samdb_ctx); if (!guid) { DCESRV_NSP_RETURN(r, MAPI_E_FAILONEPROVIDER, emsabp_ctx); } /* Step 5. Fill NspiBind reply */ handle = dcesrv_handle_new(dce_call->context, EXCHANGE_HANDLE_NSP); if (!handle) { DCESRV_NSP_RETURN(r, MAPI_E_NOT_ENOUGH_RESOURCES, emsabp_ctx); } handle->data = (void *) emsabp_ctx; *r->out.handle = handle->wire_handle; r->out.mapiuid = guid; /* Search for an existing session and increment ref_count, otherwise create it */ session = dcesrv_find_nsp_session(&handle->wire_handle.uuid); if (session) { mpm_session_increment_ref_count(session->session); DEBUG(5, (" [unexpected]: existing nsp_session: %p; session: %p (ref++)\n", session, session->session)); } else { DEBUG(0, ("Creating new session\n")); /* Step 6. Associate this emsabp context to the session */ session = talloc((TALLOC_CTX *)nsp_session, struct exchange_nsp_session); if (!session) { DCESRV_NSP_RETURN(r, MAPI_E_NOT_ENOUGH_RESOURCES, emsabp_ctx); } session->session = mpm_session_init((TALLOC_CTX *)nsp_session, dce_call); if (!session->session) { DCESRV_NSP_RETURN(r, MAPI_E_NOT_ENOUGH_RESOURCES, emsabp_ctx); } session->uuid = handle->wire_handle.uuid; mpm_session_set_private_data(session->session, (void *) emsabp_ctx); mpm_session_set_destructor(session->session, emsabp_destructor); DLIST_ADD_END(nsp_session, session, struct exchange_nsp_session *); } DCESRV_NSP_RETURN(r, MAPI_E_SUCCESS, NULL); } /** \details exchange_nsp NspiUnbind (0x1) function, Terminates a NSPI session with the client \param dce_call pointer to the session context \param mem_ctx pointer to the memory context \param r pointer to the NspiUnbind call structure */ static void dcesrv_NspiUnbind(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx, struct NspiUnbind *r) { struct dcesrv_handle *h; struct exchange_nsp_session *session; bool ret; DEBUG(5, ("exchange_nsp: NspiUnbind (0x1)\n")); /* Step 0. Ensure incoming user is authenticated */ if (!dcesrv_call_authenticated(dce_call)) { DEBUG(1, ("No challenge requested by client, cannot authenticate\n")); DCESRV_NSP_RETURN(r, MAPI_E_LOGON_FAILED, NULL); } /* Step 1. Retrieve handle and free if emsabp context and session are available */ h = dcesrv_handle_fetch(dce_call->context, r->in.handle, DCESRV_HANDLE_ANY); if (h) { session = dcesrv_find_nsp_session(&r->in.handle->uuid); if (session) { ret = mpm_session_release(session->session); if (ret == true) { DLIST_REMOVE(nsp_session, session); DEBUG(0, ("[%s:%d]: Session found and released\n", __FUNCTION__, __LINE__)); } else { DEBUG(0, ("[%s:%d]: Session found and ref_count decreased\n", __FUNCTION__, __LINE__)); } } else { DEBUG(5, (" nsp_session NOT found\n")); } } r->out.result = (enum MAPISTATUS) 1; DCESRV_NSP_RETURN(r, MAPI_E_SUCCESS, NULL); } /** \details exchange_nsp NspiUpdateStat (0x2) function \param dce_call pointer to the session context \param mem_ctx pointer to the memory context \param r pointer to the NspiUpdateStat request data \return MAPI_E_SUCCESS on success */ static void dcesrv_NspiUpdateStat(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx, struct NspiUpdateStat *r) { enum MAPISTATUS retval = MAPI_E_SUCCESS; struct emsabp_context *emsabp_ctx = NULL; uint32_t row, row_max; TALLOC_CTX *local_mem_ctx; struct PropertyTagArray_r *mids; DEBUG(3, ("exchange_nsp: NspiUpdateStat (0x2)")); /* Step 0. Ensure incoming user is authenticated */ if (!dcesrv_call_authenticated(dce_call)) { DEBUG(1, ("No challenge requested by client, cannot authenticate\n")); DCESRV_NSP_RETURN(r, MAPI_E_LOGON_FAILED, NULL); } emsabp_ctx = dcesrv_find_emsabp_context(&r->in.handle->uuid); if (!emsabp_ctx) { DCESRV_NSP_RETURN(r, MAPI_E_CALL_FAILED, NULL); } local_mem_ctx = talloc_zero(NULL, TALLOC_CTX); /* Step 1. Sanity Checks (MS-NSPI Server Processing Rules) */ if (r->in.pStat->ContainerID && (emsabp_tdb_lookup_MId(emsabp_ctx->tdb_ctx, r->in.pStat->ContainerID) == false)) { retval = MAPI_E_INVALID_BOOKMARK; goto end; } mids = talloc_zero(local_mem_ctx, struct PropertyTagArray_r); if (emsabp_search(local_mem_ctx, emsabp_ctx, mids, NULL, r->in.pStat, 0) != MAPI_E_SUCCESS) { row_max = 0; } else { row_max = mids->cValues; } if (r->in.pStat->CurrentRec == MID_CURRENT) { /* Fractional positioning (3.1.1.4.2) */ row = r->in.pStat->NumPos * row_max / r->in.pStat->TotalRecs; if (row > row_max) { row = row_max; } } else { if (r->in.pStat->CurrentRec == MID_BEGINNING_OF_TABLE) { row = 0; } else if (r->in.pStat->CurrentRec == MID_END_OF_TABLE) { row = row_max; } else { retval = MAPI_E_NOT_FOUND; row = 0; while (row < row_max) { if ((uint32_t) mids->aulPropTag[row] == (uint32_t) r->in.pStat->CurrentRec) { retval = MAPI_E_SUCCESS; break; } else { row++; } } if (retval == MAPI_E_NOT_FOUND) { goto end; } } } if (-r->in.pStat->Delta > row) { row = 0; r->in.pStat->CurrentRec = mids->aulPropTag[row]; } else if (r->in.pStat->Delta + row >= row_max) { row = row_max; r->in.pStat->CurrentRec = MID_END_OF_TABLE; } else { row += r->in.pStat->Delta; r->in.pStat->CurrentRec = mids->aulPropTag[row]; } r->in.pStat->Delta = 0; r->in.pStat->NumPos = row; r->in.pStat->TotalRecs = row_max; end: r->out.pStat = r->in.pStat; DCESRV_NSP_RETURN(r, retval, local_mem_ctx); } /** \details exchange_nsp NspiQueryRows (0x3) function \param dce_call pointer to the session context \param mem_ctx pointer to the memory context \param r pointer to the NspiQueryRows request data \return MAPI_E_SUCCESS on success */ static void dcesrv_NspiQueryRows(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx, struct NspiQueryRows *r) { enum MAPISTATUS retval = MAPI_E_SUCCESS; struct emsabp_context *emsabp_ctx = NULL; struct SPropTagArray *pPropTags; struct PropertyRowSet_r *pRows; uint32_t i, j, count; DEBUG(3, ("exchange_nsp: NspiQueryRows (0x3)\n")); /* Step 0. Ensure incoming user is authenticated */ if (!dcesrv_call_authenticated(dce_call)) { DEBUG(1, ("No challenge requested by client, cannot authenticate\n")); DCESRV_NSP_RETURN(r, MAPI_E_LOGON_FAILED, NULL); } emsabp_ctx = dcesrv_find_emsabp_context(&r->in.handle->uuid); if (!emsabp_ctx) { DCESRV_NSP_RETURN(r, MAPI_E_CALL_FAILED, NULL); } /* Step 1. Sanity Checks (MS-NSPI Server Processing Rules) */ if (r->in.pStat->ContainerID && r->in.lpETable == NULL && (emsabp_tdb_lookup_MId(emsabp_ctx->tdb_ctx, r->in.pStat->ContainerID) == false)) { retval = MAPI_E_INVALID_BOOKMARK; goto failure; } if (r->in.pPropTags == NULL) { pPropTags = set_SPropTagArray(mem_ctx, 0x7, PR_EMS_AB_CONTAINERID, PR_OBJECT_TYPE, PR_DISPLAY_TYPE, PR_DISPLAY_NAME, PR_OFFICE_TELEPHONE_NUMBER, PR_COMPANY_NAME, PR_OFFICE_LOCATION); } else { pPropTags = r->in.pPropTags; } /* Allocate RowSet to be filled in */ pRows = talloc_zero(mem_ctx, struct PropertyRowSet_r); /* Step 2. Fill ppRows */ if (r->in.lpETable == NULL) { /* Step 2.1 Fill ppRows for supplied Container ID */ struct ldb_result *ldb_res; retval = emsabp_ab_container_enum(mem_ctx, emsabp_ctx, r->in.pStat->ContainerID, &ldb_res); if (!MAPI_STATUS_IS_OK(retval)) { goto failure; } count = ldb_res->count - r->in.pStat->NumPos; if (r->in.Count < count) { count = r->in.Count; } if (count) { pRows->cRows = count; pRows->aRow = talloc_array(mem_ctx, struct PropertyRow_r, count); } /* fetch required attributes for every entry found */ for (i = 0; i < count; i++) { retval = emsabp_fetch_attrs_from_msg(mem_ctx, emsabp_ctx, pRows->aRow + i, ldb_res->msgs[i+r->in.pStat->NumPos], 0, r->in.dwFlags, pPropTags); if (!MAPI_STATUS_IS_OK(retval)) { goto failure; } } r->in.pStat->NumPos = r->in.pStat->Delta + pRows->cRows; r->in.pStat->CurrentRec = MID_END_OF_TABLE; r->in.pStat->TotalRecs = pRows->cRows; r->in.pStat->Delta = 0; } else { /* Step 2.2 Fill ppRows for supplied table of MIds */ j = 0; if (r->in.pStat->NumPos < r->in.dwETableCount) { pRows->cRows = r->in.dwETableCount - r->in.pStat->NumPos; pRows->aRow = talloc_array(mem_ctx, struct PropertyRow_r, pRows->cRows); for (i = r->in.pStat->NumPos; i < r->in.dwETableCount; i++) { retval = emsabp_fetch_attrs(mem_ctx, emsabp_ctx, &(pRows->aRow[j]), r->in.lpETable[i], r->in.dwFlags, pPropTags); if (retval != MAPI_E_SUCCESS) { goto failure; } j++; } } r->in.pStat->CurrentRec = MID_END_OF_TABLE; r->in.pStat->TotalRecs = j; r->in.pStat->Delta = 0; } /* Step 3. Fill output params */ *r->out.ppRows = pRows; memcpy(r->out.pStat, r->in.pStat, sizeof (struct STAT)); DCESRV_NSP_RETURN(r, MAPI_E_SUCCESS, NULL); failure: r->out.pStat = r->in.pStat; *r->out.ppRows = NULL; DCESRV_NSP_RETURN(r, retval, NULL); } /** \details exchange_nsp NspiSeekEntries (0x4) function \param dce_call pointer to the session context \param mem_ctx pointer to the memory context \param r pointer to the NspiSeekEntries request data \return MAPI_E_SUCCESS on success */ static void dcesrv_NspiSeekEntries(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx, struct NspiSeekEntries *r) { enum MAPISTATUS retval = MAPI_E_SUCCESS, ret; struct emsabp_context *emsabp_ctx = NULL; uint32_t row; struct PropertyTagArray_r *mids, *all_mids; struct Restriction_r *seek_restriction; DEBUG(3, ("exchange_nsp: NspiSeekEntries (0x4)\n")); emsabp_ctx = dcesrv_find_emsabp_context(&r->in.handle->uuid); if (!emsabp_ctx) { DCESRV_NSP_RETURN(r, MAPI_E_CALL_FAILED, NULL); } /* Step 1. Sanity Checks (MS-NSPI Server Processing Rules) */ if (r->in.pStat->ContainerID && (emsabp_tdb_lookup_MId(emsabp_ctx->tdb_ctx, r->in.pStat->ContainerID) == false)) { retval = MAPI_E_INVALID_BOOKMARK; goto end; } if (!r->in.pTarget) { retval = MAPI_E_INVALID_PARAMETER; goto end; } if (r->in.lpETable) { all_mids = r->in.lpETable; } else { all_mids = talloc_zero(mem_ctx, struct PropertyTagArray_r); emsabp_search(mem_ctx, emsabp_ctx, all_mids, NULL, r->in.pStat, 0); } /* find the records matching the qualifier */ seek_restriction = talloc_zero(mem_ctx, struct Restriction_r); seek_restriction->rt = RES_PROPERTY; seek_restriction->res.resProperty.relop = RELOP_GE; seek_restriction->res.resProperty.ulPropTag = r->in.pTarget->ulPropTag; seek_restriction->res.resProperty.lpProp = r->in.pTarget; mids = talloc_zero(mem_ctx, struct PropertyTagArray_r); if (emsabp_search(mem_ctx, emsabp_ctx, mids, seek_restriction, r->in.pStat, 0) != MAPI_E_SUCCESS) { mids = all_mids; retval = MAPI_E_NOT_FOUND; } r->in.pStat->CurrentRec = MID_END_OF_TABLE; r->in.pStat->NumPos = r->in.pStat->TotalRecs = all_mids->cValues; for (row = 0; row < all_mids->cValues; row++) { if (all_mids->aulPropTag[row] == mids->aulPropTag[0]) { r->in.pStat->CurrentRec = mids->aulPropTag[0]; r->in.pStat->NumPos = row; break; } } /* now we need to populate the rows, if properties were requested */ r->out.pStat = r->in.pStat; if (!r->in.pPropTags || !r->in.pPropTags->cValues) { *r->out.pRows = NULL; goto end; } r->out.pRows = talloc_zero(mem_ctx, struct PropertyRowSet_r *); r->out.pRows[0] = talloc_zero(mem_ctx, struct PropertyRowSet_r); r->out.pRows[0]->cRows = mids->cValues; r->out.pRows[0]->aRow = talloc_array(mem_ctx, struct PropertyRow_r, mids->cValues); for (row = 0; row < mids->cValues; row++) { ret = emsabp_fetch_attrs(mem_ctx, emsabp_ctx, &(r->out.pRows[0]->aRow[row]), mids->aulPropTag[row], fEphID, r->in.pPropTags); if (ret) { retval = ret; DEBUG(5, ("failure looking up value %d\n", row)); goto end; } } end: DCESRV_NSP_RETURN(r, retval, NULL); } /** \details exchange_nsp NspiGetMatches (0x5) function \param dce_call pointer to the session context \param mem_ctx pointer to the memory context \param r pointer to the NspiGetMatches request data \return MAPI_E_SUCCESS on success */ static void dcesrv_NspiGetMatches(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx, struct NspiGetMatches *r) { enum MAPISTATUS retval; struct emsabp_context *emsabp_ctx = NULL; struct PropertyTagArray_r *ppOutMIds = NULL; uint32_t i; DEBUG(3, ("exchange_nsp: NspiGetMatches (0x5)\n")); /* Step 0. Ensure incoming user is authenticated */ if (!dcesrv_call_authenticated(dce_call)) { DEBUG(1, ("No challenge requested by client, cannot authenticate\n")); DCESRV_NSP_RETURN(r, MAPI_E_LOGON_FAILED, NULL); } emsabp_ctx = dcesrv_find_emsabp_context(&r->in.handle->uuid); if (!emsabp_ctx) { DCESRV_NSP_RETURN(r, MAPI_E_CALL_FAILED, NULL); } /* Step 1. Retrieve MIds array given search criterias */ ppOutMIds = talloc_zero(mem_ctx, struct PropertyTagArray_r); ppOutMIds->cValues = 0; ppOutMIds->aulPropTag = NULL; retval = emsabp_search(mem_ctx, emsabp_ctx, ppOutMIds, r->in.Filter, r->in.pStat, r->in.ulRequested); if (retval != MAPI_E_SUCCESS) { failure: r->out.pStat = r->in.pStat; *r->out.ppOutMIds = ppOutMIds; r->out.ppRows = talloc(mem_ctx, struct PropertyRowSet_r *); r->out.ppRows[0] = NULL; DCESRV_NSP_RETURN(r, retval, NULL); } *r->out.ppOutMIds = ppOutMIds; /* Step 2. Retrieve requested properties for these MIds */ r->out.ppRows = talloc_zero(mem_ctx, struct PropertyRowSet_r *); r->out.ppRows[0] = talloc_zero(mem_ctx, struct PropertyRowSet_r); r->out.ppRows[0]->cRows = ppOutMIds->cValues; r->out.ppRows[0]->aRow = talloc_array(mem_ctx, struct PropertyRow_r, ppOutMIds->cValues); for (i = 0; i < ppOutMIds->cValues; i++) { retval = emsabp_fetch_attrs(mem_ctx, emsabp_ctx, &(r->out.ppRows[0]->aRow[i]), ppOutMIds->aulPropTag[i], fEphID, r->in.pPropTags); if (retval) { DEBUG(5, ("failure looking up value %d\n", i)); goto failure; } } DCESRV_NSP_RETURN(r, MAPI_E_SUCCESS, NULL); } /** \details exchange_nsp NspiResortRestriction (0x6) function \param dce_call pointer to the session context \param mem_ctx pointer to the memory context \param r pointer to the NspiResortRestriction request data \return MAPI_E_SUCCESS on success */ static void dcesrv_NspiResortRestriction(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx, struct NspiResortRestriction *r) { DEBUG(3, ("exchange_nsp: NspiResortRestriction (0x6) not implemented\n")); DCESRV_NSP_RETURN(r, DCERPC_FAULT_OP_RNG_ERROR, NULL); } /** \details exchange_nsp NspiDNToMId (0x7) function \param dce_call pointer to the session context \param mem_ctx pointer to the memory context \param r pointer to the NspiDNToMId request data \note Only searches within configuration.ldb are supported at the moment. \return MAPI_E_SUCCESS on success */ static void dcesrv_NspiDNToMId(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx, struct NspiDNToMId *r) { enum MAPISTATUS retval; struct emsabp_context *emsabp_ctx = NULL; struct ldb_message *msg; uint32_t i; uint32_t MId; const char *dn; bool pbUseConfPartition; DEBUG(3, ("exchange_nsp: NspiDNToMId (0x7)\n")); /* Step 0. Ensure incoming user is authenticated */ if (!dcesrv_call_authenticated(dce_call)) { DEBUG(1, ("No challenge requested by client, cannot authenticate\n")); DCESRV_NSP_RETURN(r, MAPI_E_LOGON_FAILED, NULL); } emsabp_ctx = dcesrv_find_emsabp_context(&r->in.handle->uuid); if (!emsabp_ctx) { DCESRV_NSP_RETURN(r, MAPI_E_CALL_FAILED, NULL); } r->out.ppMIds = talloc_array(mem_ctx, struct PropertyTagArray_r *, 2); r->out.ppMIds[0] = talloc_zero(mem_ctx, struct PropertyTagArray_r); r->out.ppMIds[0]->cValues = r->in.pNames->Count; r->out.ppMIds[0]->aulPropTag = talloc_array(mem_ctx, uint32_t, r->in.pNames->Count); for (i = 0; i < r->in.pNames->Count; i++) { /* Step 1. Check if the input legacyDN exists */ retval = emsabp_search_legacyExchangeDN(emsabp_ctx, r->in.pNames->Strings[i], &msg, &pbUseConfPartition); if (retval != MAPI_E_SUCCESS) { r->out.ppMIds[0]->aulPropTag[i] = (enum MAPITAGS) 0; } else { TDB_CONTEXT *tdb_ctx = (pbUseConfPartition ? emsabp_ctx->tdb_ctx : emsabp_ctx->ttdb_ctx); dn = ldb_msg_find_attr_as_string(msg, "distinguishedName", NULL); retval = emsabp_tdb_fetch_MId(tdb_ctx, dn, &MId); if (retval) { retval = emsabp_tdb_insert(tdb_ctx, dn); retval = emsabp_tdb_fetch_MId(tdb_ctx, dn, &MId); } r->out.ppMIds[0]->aulPropTag[i] = (enum MAPITAGS) MId; } } DCESRV_NSP_RETURN(r, MAPI_E_SUCCESS, NULL); } /** \details exchange_nsp NspiGetPropList (0x8) function \param dce_call pointer to the session context \param mem_ctx pointer to the memory context \param r pointer to the NspiGetPropList request data \return MAPI_E_SUCCESS on success */ static void dcesrv_NspiGetPropList(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx, struct NspiGetPropList *r) { DEBUG(3, ("exchange_nsp: NspiGetPropList (0x8) not implemented\n")); DCESRV_NSP_RETURN(r, DCERPC_FAULT_OP_RNG_ERROR, NULL); } /** \details exchange_nsp NspiGetProps (0x9) function \param dce_call pointer to the session context \param mem_ctx pointer to the memory context \param r pointer to the NspiGetProps request data \return MAPI_E_SUCCESS on success */ static void dcesrv_NspiGetProps(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx, struct NspiGetProps *r) { enum MAPISTATUS retval; struct emsabp_context *emsabp_ctx = NULL; uint32_t MId; int i; struct SPropTagArray *pPropTags; DEBUG(3, ("exchange_nsp: NspiGetProps (0x9)\n")); /* Step 0. Ensure incoming user is authenticated */ if (!dcesrv_call_authenticated(dce_call)) { DEBUG(1, ("No challenge requested by client, cannot authenticate\n")); DCESRV_NSP_RETURN(r, MAPI_E_LOGON_FAILED, NULL); } emsabp_ctx = dcesrv_find_emsabp_context(&r->in.handle->uuid); if (!emsabp_ctx) { DCESRV_NSP_RETURN(r, MAPI_E_CALL_FAILED, NULL); } MId = r->in.pStat->CurrentRec; /* Step 1. Sanity Checks (MS-NSPI Server Processing Rules) */ if (r->in.pStat->ContainerID && (emsabp_tdb_lookup_MId(emsabp_ctx->tdb_ctx, r->in.pStat->ContainerID) == false)) { DCESRV_NSP_RETURN(r, MAPI_E_INVALID_BOOKMARK, NULL); } /* Step 2. Fetch properties */ r->out.ppRows = talloc_array(mem_ctx, struct PropertyRow_r *, 2); r->out.ppRows[0] = talloc_zero(r->out.ppRows, struct PropertyRow_r); pPropTags = r->in.pPropTags; if (!pPropTags) { pPropTags = talloc_zero(r, struct SPropTagArray); pPropTags->cValues = 9; pPropTags->aulPropTag = talloc_array(pPropTags, enum MAPITAGS, pPropTags->cValues + 1); pPropTags->aulPropTag[0] = PR_ADDRTYPE_UNICODE; pPropTags->aulPropTag[1] = PR_SMTP_ADDRESS_UNICODE; pPropTags->aulPropTag[2] = PR_OBJECT_TYPE; pPropTags->aulPropTag[3] = PR_DISPLAY_TYPE; pPropTags->aulPropTag[4] = PR_ENTRYID; pPropTags->aulPropTag[5] = PR_ORIGINAL_ENTRYID; pPropTags->aulPropTag[6] = PR_SEARCH_KEY; pPropTags->aulPropTag[7] = PR_INSTANCE_KEY; pPropTags->aulPropTag[8] = PR_EMAIL_ADDRESS; pPropTags->aulPropTag[pPropTags->cValues] = 0; r->in.pPropTags = pPropTags; } retval = emsabp_fetch_attrs(mem_ctx, emsabp_ctx, r->out.ppRows[0], MId, r->in.dwFlags, pPropTags); if (retval != MAPI_E_SUCCESS) { /* Is MId is not found, proceed as if no attributes were found */ if (retval == MAPI_E_INVALID_BOOKMARK) { uint32_t ulPropTag; struct PropertyRow_r *aRow; aRow = r->out.ppRows[0]; aRow->Reserved = 0x0; aRow->cValues = r->in.pPropTags->cValues; aRow->lpProps = talloc_array(mem_ctx, struct PropertyValue_r, aRow->cValues); for (i = 0; i < aRow->cValues; i++) { ulPropTag = r->in.pPropTags->aulPropTag[i]; ulPropTag = (ulPropTag & 0xFFFF0000) | PT_ERROR; aRow->lpProps[i].ulPropTag = (enum MAPITAGS) ulPropTag; aRow->lpProps[i].dwAlignPad = 0x0; set_PropertyValue(&(aRow->lpProps[i]), NULL); } retval = MAPI_W_ERRORS_RETURNED; } else { talloc_free(r->out.ppRows); r->out.ppRows = NULL; } DCESRV_NSP_RETURN(r, retval, NULL); } /* Step 3. Properties are fetched. Provide proper return value. ErrorsReturned should be returned when at least one property is not found */ for (i = 0; i < r->out.ppRows[0]->cValues; i++) { if ((r->out.ppRows[0]->lpProps[i].ulPropTag & 0xFFFF) == PT_ERROR) { retval = MAPI_W_ERRORS_RETURNED; break; } } DCESRV_NSP_RETURN(r, retval, NULL); } /** \details exchange_nsp NspiCompareMIds (0xA) function \param dce_call pointer to the session context \param mem_ctx pointer to the memory context \param r pointer to the NspiCompareMIds request data \return MAPI_E_SUCCESS on success */ static void dcesrv_NspiCompareMIds(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx, struct NspiCompareMIds *r) { DEBUG(3, ("exchange_nsp: NspiCompareMIds (0xA) not implemented\n")); DCESRV_NSP_RETURN(r, DCERPC_FAULT_OP_RNG_ERROR, NULL); } /** \details exchange_nsp NspiModProps (0xB) function \param dce_call pointer to the session context \param mem_ctx pointer to the memory context \param r pointer to the NspiModProps request data \return MAPI_E_SUCCESS on success */ static void dcesrv_NspiModProps(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx, struct NspiModProps *r) { DEBUG(3, ("exchange_nsp: NspiModProps (0xB) not implemented\n")); DCESRV_NSP_RETURN(r, DCERPC_FAULT_OP_RNG_ERROR, NULL); } /** \details exchange_nsp NspiGetSpecialTable (0xC) function \param dce_call pointer to the session context \param mem_ctx pointer to the memory context \param r pointer to the NspiGetSpecialTable request data \note MS-NSPI specifies lpVersion "holds the value of the version number of the hierarchy table that the client has." We will ignore this for the moment. \return MAPI_E_SUCCESS on success */ static void dcesrv_NspiGetSpecialTable(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx, struct NspiGetSpecialTable *r) { struct emsabp_context *emsabp_ctx = NULL; DEBUG(3, ("exchange_nsp: NspiGetSpecialTable (0xC)\n")); /* Step 0. Ensure incoming user is authenticated */ if (!dcesrv_call_authenticated(dce_call)) { DEBUG(1, ("No challenge requested by client, cannot authenticate\n")); DCESRV_NSP_RETURN(r, MAPI_E_LOGON_FAILED, NULL); } emsabp_ctx = dcesrv_find_emsabp_context(&r->in.handle->uuid); if (!emsabp_ctx) { DCESRV_NSP_RETURN(r, MAPI_E_CALL_FAILED, NULL); } /* Step 1. (FIXME) We arbitrary set lpVersion to 0x1 */ r->out.lpVersion = talloc_zero(mem_ctx, uint32_t); *r->out.lpVersion = 0x1; /* Step 2. Allocate output SRowSet and call associated emsabp function */ r->out.ppRows = talloc_zero(mem_ctx, struct PropertyRowSet_r *); if (!r->out.ppRows) { DCESRV_NSP_RETURN(r, MAPI_E_NOT_ENOUGH_RESOURCES, NULL); } r->out.ppRows[0] = talloc_zero(mem_ctx, struct PropertyRowSet_r); if (!r->out.ppRows[0]) { DCESRV_NSP_RETURN(r, MAPI_E_NOT_ENOUGH_RESOURCES, NULL); } switch (r->in.dwFlags) { case NspiAddressCreationTemplates: case NspiAddressCreationTemplates|NspiUnicodeStrings: DEBUG(0, ("CreationTemplates Table requested\n")); r->out.result = emsabp_get_CreationTemplatesTable(mem_ctx, emsabp_ctx, r->in.dwFlags, r->out.ppRows); break; case NspiUnicodeStrings: case 0x0: DEBUG(0, ("Hierarchy Table requested\n")); r->out.result = emsabp_get_HierarchyTable(mem_ctx, emsabp_ctx, r->in.dwFlags, r->out.ppRows); break; default: talloc_free(r->out.ppRows); talloc_free(r->out.ppRows[0]); DCESRV_NSP_RETURN(r, MAPI_E_NO_SUPPORT, NULL); } } /** \details exchange_nsp NspiGetTemplateInfo (0xD) function \param dce_call pointer to the session context \param mem_ctx pointer to the memory context \param r pointer to the NspiGetTemplateInfo request data \return MAPI_E_SUCCESS on success */ static void dcesrv_NspiGetTemplateInfo(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx, struct NspiGetTemplateInfo *r) { DEBUG(3, ("exchange_nsp: NspiGetTemplateInfo (0xD) not implemented\n")); DCESRV_NSP_RETURN(r, DCERPC_FAULT_OP_RNG_ERROR, NULL); } /** \details exchange_nsp NspiModLinkAtt (0xE) function \param dce_call pointer to the session context \param mem_ctx pointer to the memory context \param r pointer to the NspiModLinkAtt request data \return MAPI_E_SUCCESS on success */ static void dcesrv_NspiModLinkAtt(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx, struct NspiModLinkAtt *r) { DEBUG(3, ("exchange_nsp: NspiModLinkAtt (0xE) not implemented\n")); DCESRV_NSP_RETURN(r, DCERPC_FAULT_OP_RNG_ERROR, NULL); } /** \details exchange_nsp NspiDeleteEntries (0xF) function \param dce_call pointer to the session context \param mem_ctx pointer to the memory context \param r pointer to the NspiDeleteEntries request data \return MAPI_E_SUCCESS on success */ static void dcesrv_NspiDeleteEntries(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx, struct NspiDeleteEntries *r) { DEBUG(3, ("exchange_nsp: NspiDeleteEntries (0xF) not implemented\n")); DCESRV_NSP_RETURN(r, DCERPC_FAULT_OP_RNG_ERROR, NULL); } /** \details exchange_nsp NspiQueryColumns (0x10) function \param dce_call pointer to the session context \param mem_ctx pointer to the memory context \param r pointer to the NspiQueryColumns request data \return MAPI_E_SUCCESS on success */ static void dcesrv_NspiQueryColumns(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx, struct NspiQueryColumns *r) { DEBUG(3, ("exchange_nsp: NspiQueryColumns (0x10) not implemented\n")); DCESRV_NSP_RETURN(r, DCERPC_FAULT_OP_RNG_ERROR, NULL); } /** \details exchange_nsp NspiGetNamesFromIDs (0x11) function \param dce_call pointer to the session context \param mem_ctx pointer to the memory context \param r pointer to the NspiGetNamesFromIDs request data \return MAPI_E_SUCCESS on success */ static void dcesrv_NspiGetNamesFromIDs(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx, struct NspiGetNamesFromIDs *r) { DEBUG(3, ("exchange_nsp: NspiGetNamesFromIDs (0x11) not implemented\n")); DCESRV_NSP_RETURN(r, DCERPC_FAULT_OP_RNG_ERROR, NULL); } /** \details exchange_nsp NspiGetIDsFromNames (0x12) function \param dce_call pointer to the session context \param mem_ctx pointer to the memory context \param r pointer to the NspiGetIDsFromNames request data \return MAPI_E_SUCCESS on success */ static void dcesrv_NspiGetIDsFromNames(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx, struct NspiGetIDsFromNames *r) { DEBUG(3, ("exchange_nsp: NspiGetIDsFromNames (0x12) not implemented\n")); DCESRV_NSP_RETURN(r, DCERPC_FAULT_OP_RNG_ERROR, NULL); } /** \details exchange_nsp NspiResolveNames (0x13) function \param dce_call pointer to the session context \param mem_ctx pointer to the memory context \param r pointer to the NspiResolveNames request data \return MAPI_E_SUCCESS on success */ static void dcesrv_NspiResolveNames(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx, struct NspiResolveNames *r) { enum MAPISTATUS retval = MAPI_E_SUCCESS; struct emsabp_context *emsabp_ctx = NULL; struct ldb_message *ldb_msg_ab; struct SPropTagArray *pPropTags; const char *purportedSearch; struct PropertyTagArray_r *pMIds = NULL; struct PropertyRowSet_r *pRows = NULL; struct StringsArray_r *paStr; uint32_t i; int ret; const char * const recipient_attrs[] = { "*", NULL }; const char * const search_attr[] = { "mailNickName", "mail", "name", "displayName", "givenName", "sAMAccountName", "proxyAddresses" }; DEBUG(3, ("exchange_nsp: NspiResolveNames (0x13)\n")); if (!dcesrv_call_authenticated(dce_call)) { DEBUG(1, ("No challenge requested by client, cannot authenticate\n")); } emsabp_ctx = dcesrv_find_emsabp_context(&r->in.handle->uuid); if (!emsabp_ctx) { DCESRV_NSP_RETURN(r, MAPI_E_CALL_FAILED, NULL); } /* Step 1. Prepare in/out data */ retval = emsabp_ab_container_by_id(mem_ctx, emsabp_ctx, r->in.pStat->ContainerID, &ldb_msg_ab); if (!MAPI_STATUS_IS_OK(retval)) { DCESRV_NSP_RETURN(r, MAPI_E_INVALID_BOOKMARK, NULL); } purportedSearch = ldb_msg_find_attr_as_string(ldb_msg_ab, "purportedSearch", NULL); if (!purportedSearch) { DCESRV_NSP_RETURN(r, MAPI_E_INVALID_BOOKMARK, NULL); } /* Set the default list of property tags if none were provided in input */ if (!r->in.pPropTags) { pPropTags = set_SPropTagArray(mem_ctx, 0x7, PR_EMS_AB_CONTAINERID, PR_OBJECT_TYPE, PR_DISPLAY_TYPE, PR_DISPLAY_NAME, PR_OFFICE_TELEPHONE_NUMBER, PR_COMPANY_NAME, PR_OFFICE_LOCATION); } else { pPropTags = r->in.pPropTags; } /* Allocate output MIds */ paStr = r->in.paStr; pMIds = talloc(mem_ctx, struct PropertyTagArray_r); pMIds->cValues = paStr->Count; pMIds->aulPropTag = (uint32_t *) talloc_array(mem_ctx, uint32_t, pMIds->cValues); pRows = talloc(mem_ctx, struct PropertyRowSet_r); pRows->cRows = 0; pRows->aRow = talloc_array(mem_ctx, struct PropertyRow_r, pMIds->cValues); /* Step 2. Fetch AB container records */ for (i = 0; i < paStr->Count; i++) { struct ldb_result *ldb_res; char *filter = talloc_strdup(mem_ctx, ""); int j; /* Build search filter */ for (j = 0; j < ARRAY_SIZE(search_attr); j++) { char *attr_filter = talloc_asprintf(mem_ctx, "(%s=%s)", search_attr[j], paStr->Strings[i]); filter = talloc_strdup_append(filter, attr_filter); talloc_free(attr_filter); } /* Search AD */ filter = talloc_asprintf(mem_ctx, "(&%s(|%s))", purportedSearch, filter); ret = ldb_search(emsabp_ctx->samdb_ctx, mem_ctx, &ldb_res, ldb_get_default_basedn(emsabp_ctx->samdb_ctx), LDB_SCOPE_SUBTREE, recipient_attrs, "%s", filter); /* Determine name resolution status and fetch object upon success */ if (ret != LDB_SUCCESS || ldb_res->count == 0) { pMIds->aulPropTag[i] = MAPI_UNRESOLVED; } else if (ldb_res->count > 1) { pMIds->aulPropTag[i] = MAPI_AMBIGUOUS; } else { pMIds->aulPropTag[i] = MAPI_RESOLVED; emsabp_fetch_attrs_from_msg(mem_ctx, emsabp_ctx, &pRows->aRow[pRows->cRows], ldb_res->msgs[0], 0, 0, pPropTags); pRows->cRows++; } } *r->out.ppMIds = pMIds; if (pRows->cRows) { *r->out.ppRows = pRows; } DCESRV_NSP_RETURN(r, retval, NULL); } /** \details exchange_nsp NspiResolveNamesW (0x14) function \param dce_call pointer to the session context \param mem_ctx pointer to the memory context \param r pointer to the NspiResolveNamesW request data \return MAPI_E_SUCCESS on success */ static void dcesrv_NspiResolveNamesW(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx, struct NspiResolveNamesW *r) { enum MAPISTATUS retval = MAPI_E_SUCCESS; struct emsabp_context *emsabp_ctx = NULL; struct ldb_message *ldb_msg_ab; struct SPropTagArray *pPropTags; const char *purportedSearch; struct PropertyTagArray_r *pMIds = NULL; struct PropertyRowSet_r *pRows = NULL; struct StringsArrayW_r *paWStr; uint32_t i; int ret; const char * const recipient_attrs[] = { "*", NULL }; const char * const search_attr[] = { "mailNickName", "mail", "name", "displayName", "givenName", "sAMAccountName" }; DEBUG(3, ("exchange_nsp: NspiResolveNamesW (0x14)\n")); /* Step 0. Ensure incoming user is authenticated */ if (!dcesrv_call_authenticated(dce_call)) { DEBUG(1, ("No challenge requested by client, cannot authenticate\n")); DCESRV_NSP_RETURN(r, MAPI_E_LOGON_FAILED, NULL); } emsabp_ctx = dcesrv_find_emsabp_context(&r->in.handle->uuid); if (!emsabp_ctx) { DCESRV_NSP_RETURN(r, MAPI_E_CALL_FAILED, NULL); } /* Step 1. Prepare in/out data */ retval = emsabp_ab_container_by_id(mem_ctx, emsabp_ctx, r->in.pStat->ContainerID, &ldb_msg_ab); if (!MAPI_STATUS_IS_OK(retval)) { DCESRV_NSP_RETURN(r, MAPI_E_INVALID_BOOKMARK, NULL); } purportedSearch = ldb_msg_find_attr_as_string(ldb_msg_ab, "purportedSearch", NULL); if (!purportedSearch) { DCESRV_NSP_RETURN(r, MAPI_E_INVALID_BOOKMARK, NULL); } /* Set default list of property tags if none were provided in input */ if (!r->in.pPropTags) { pPropTags = set_SPropTagArray(mem_ctx, 0x7, PR_EMS_AB_CONTAINERID, PR_OBJECT_TYPE, PR_DISPLAY_TYPE, PR_DISPLAY_NAME, PR_OFFICE_TELEPHONE_NUMBER, PR_COMPANY_NAME, PR_OFFICE_LOCATION); } else { pPropTags = r->in.pPropTags; } /* Allocate output MIds */ paWStr = r->in.paWStr; pMIds = talloc(mem_ctx, struct PropertyTagArray_r); pMIds->cValues = paWStr->Count; pMIds->aulPropTag = talloc_array(mem_ctx, uint32_t, pMIds->cValues); pRows = talloc(mem_ctx, struct PropertyRowSet_r); pRows->cRows = 0; pRows->aRow = talloc_array(mem_ctx, struct PropertyRow_r, pMIds->cValues); /* Step 2. Fetch AB container records */ for (i = 0; i < paWStr->Count; i++) { struct ldb_result *ldb_res; char *filter = talloc_strdup(mem_ctx, ""); int j; /* Build search filter */ for (j = 0; j < ARRAY_SIZE(search_attr); j++) { char *attr_filter = talloc_asprintf(mem_ctx, "(%s=%s)", search_attr[j], paWStr->Strings[i]); filter = talloc_strdup_append(filter, attr_filter); talloc_free(attr_filter); } /* Search AD */ filter = talloc_asprintf(mem_ctx, "(&%s(|%s))", purportedSearch, filter); ret = ldb_search(emsabp_ctx->samdb_ctx, mem_ctx, &ldb_res, ldb_get_default_basedn(emsabp_ctx->samdb_ctx), LDB_SCOPE_SUBTREE, recipient_attrs, "%s", filter); /* Determine name resolutation status and fetch object upon success */ if (ret != LDB_SUCCESS || ldb_res->count == 0) { pMIds->aulPropTag[i] = MAPI_UNRESOLVED; } else if (ldb_res->count > 1) { pMIds->aulPropTag[i] = MAPI_AMBIGUOUS; } else { pMIds->aulPropTag[i] = MAPI_RESOLVED; emsabp_fetch_attrs_from_msg(mem_ctx, emsabp_ctx, &pRows->aRow[pRows->cRows], ldb_res->msgs[0], 0, 0, pPropTags); pRows->cRows++; } } *r->out.ppMIds = pMIds; if (pRows->cRows) { *r->out.ppRows = pRows; } DCESRV_NSP_RETURN(r, retval, NULL); } /** \details Dispatch incoming NSPI call to the correct OpenChange server function. \param dce_call pointer to the session context \param mem_ctx pointer to the memory context \param r generic pointer on NSPI data \param mapiproxy pointer to the mapiproxy structure controlling mapiproxy behavior \return NT_STATUS_OK */ static NTSTATUS dcesrv_exchange_nsp_dispatch(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx, void *r, struct mapiproxy *mapiproxy) { const struct ndr_interface_table *table; uint16_t opnum; DEBUG (0, ("dcesrv_exchange_nsp_dispatch\n")); table = (const struct ndr_interface_table *) dce_call->context->iface->private_data; opnum = dce_call->pkt.u.request.opnum; /* Sanity checks */ if (!table) return NT_STATUS_UNSUCCESSFUL; if (table->name && strcmp(table->name, NDR_EXCHANGE_NSP_NAME)) return NT_STATUS_UNSUCCESSFUL; switch (opnum) { case NDR_NSPIBIND: dcesrv_NspiBind(dce_call, mem_ctx, (struct NspiBind *)r); break; case NDR_NSPIUNBIND: dcesrv_NspiUnbind(dce_call, mem_ctx, (struct NspiUnbind *)r); break; case NDR_NSPIUPDATESTAT: dcesrv_NspiUpdateStat(dce_call, mem_ctx, (struct NspiUpdateStat *)r); break; case NDR_NSPIQUERYROWS: dcesrv_NspiQueryRows(dce_call, mem_ctx, (struct NspiQueryRows *)r); break; case NDR_NSPISEEKENTRIES: dcesrv_NspiSeekEntries(dce_call, mem_ctx, (struct NspiSeekEntries *)r); break; case NDR_NSPIGETMATCHES: dcesrv_NspiGetMatches(dce_call, mem_ctx, (struct NspiGetMatches *)r); break; case NDR_NSPIRESORTRESTRICTION: dcesrv_NspiResortRestriction(dce_call, mem_ctx, (struct NspiResortRestriction *)r); break; case NDR_NSPIDNTOMID: dcesrv_NspiDNToMId(dce_call, mem_ctx, (struct NspiDNToMId *)r); break; case NDR_NSPIGETPROPLIST: dcesrv_NspiGetPropList(dce_call, mem_ctx, (struct NspiGetPropList *)r); break; case NDR_NSPIGETPROPS: dcesrv_NspiGetProps(dce_call, mem_ctx, (struct NspiGetProps *)r); break; case NDR_NSPICOMPAREMIDS: dcesrv_NspiCompareMIds(dce_call, mem_ctx, (struct NspiCompareMIds *)r); break; case NDR_NSPIMODPROPS: dcesrv_NspiModProps(dce_call, mem_ctx, (struct NspiModProps *)r); break; case NDR_NSPIGETSPECIALTABLE: dcesrv_NspiGetSpecialTable(dce_call, mem_ctx, (struct NspiGetSpecialTable *)r); break; case NDR_NSPIGETTEMPLATEINFO: dcesrv_NspiGetTemplateInfo(dce_call, mem_ctx, (struct NspiGetTemplateInfo *)r); break; case NDR_NSPIMODLINKATT: dcesrv_NspiModLinkAtt(dce_call, mem_ctx, (struct NspiModLinkAtt *)r); break; case NDR_NSPIDELETEENTRIES: dcesrv_NspiDeleteEntries(dce_call, mem_ctx, (struct NspiDeleteEntries *)r); break; case NDR_NSPIQUERYCOLUMNS: dcesrv_NspiQueryColumns(dce_call, mem_ctx, (struct NspiQueryColumns *)r); break; case NDR_NSPIGETNAMESFROMIDS: dcesrv_NspiGetNamesFromIDs(dce_call, mem_ctx, (struct NspiGetNamesFromIDs *)r); break; case NDR_NSPIGETIDSFROMNAMES: dcesrv_NspiGetIDsFromNames(dce_call, mem_ctx, (struct NspiGetIDsFromNames *)r); break; case NDR_NSPIRESOLVENAMES: dcesrv_NspiResolveNames(dce_call, mem_ctx, (struct NspiResolveNames *)r); break; case NDR_NSPIRESOLVENAMESW: dcesrv_NspiResolveNamesW(dce_call, mem_ctx, (struct NspiResolveNamesW *)r); break; } return NT_STATUS_OK; } /** \details Initialize the NSPI OpenChange server \param dce_ctx pointer to the server context \return NT_STATUS_OK on success, otherwise NT_STATUS_NO_MEMORY */ static NTSTATUS dcesrv_exchange_nsp_init(struct dcesrv_context *dce_ctx) { DEBUG (0, ("dcesrv_exchange_nsp_init\n")); /* Initialize exchange_nsp session */ nsp_session = talloc_zero(dce_ctx, struct exchange_nsp_session); if (!nsp_session) return NT_STATUS_NO_MEMORY; nsp_session->session = NULL; /* Open a read-write pointer on the EMSABP TDB database */ emsabp_tdb_ctx = emsabp_tdb_init((TALLOC_CTX *)dce_ctx, dce_ctx->lp_ctx); if (!emsabp_tdb_ctx) { smb_panic("unable to initialize EMSABP context"); } return NT_STATUS_OK; } /** \details Terminates the NSPI connection and release the associated session and context if still available. This case occurs when the client doesn't call NspiUnbind but quit unexpectedly. \param server_id reference to the server identifier structure \param context_id the connection context identifier \return NT_STATUS_OK on success */ static NTSTATUS dcesrv_exchange_nsp_unbind(struct server_id server_id, uint32_t context_id) { DEBUG (0, ("dcesrv_exchange_nsp_unbind\n")); return NT_STATUS_OK; } /** \details Entry point for the default OpenChange NSPI server \return NT_STATUS_OK on success, otherwise NTSTATUS error */ NTSTATUS samba_init_module(void) { struct mapiproxy_module server; NTSTATUS ret; /* Fill in our name */ server.name = "exchange_nsp"; server.status = MAPIPROXY_DEFAULT; server.description = "OpenChange NSPI server"; server.endpoint = "exchange_nsp"; /* Fill in all the operations */ server.init = dcesrv_exchange_nsp_init; server.unbind = dcesrv_exchange_nsp_unbind; server.dispatch = dcesrv_exchange_nsp_dispatch; server.push = NULL; server.pull = NULL; server.ndr_pull = NULL; /* Register ourselves with the MAPIPROXY server subsystem */ ret = mapiproxy_server_register(&server); if (!NT_STATUS_IS_OK(ret)) { DEBUG(0, ("Failed to register the 'exchange_nsp' default mapiproxy server!\n")); return ret; } return ret; } openchange-2.0/mapiproxy/servers/default/nspi/dcesrv_exchange_nsp.h000066400000000000000000000145511223057412600257710ustar00rootroot00000000000000/* MAPI Proxy - Exchange NSPI Server OpenChange Project Copyright (C) Julien Kerihuel 2009 This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see . */ #ifndef __DCESRV_EXCHANGE_NSP_H #define __DCESRV_EXCHANGE_NSP_H #include "libmapi/libmapi.h" #include "libmapi/libmapi_private.h" #include "mapiproxy/libmapiproxy/libmapiproxy.h" #include #include #include #include #include #ifndef __BEGIN_DECLS #ifdef __cplusplus #define __BEGIN_DECLS extern "C" { #define __END_DECLS } #else #define __BEGIN_DECLS #define __END_DECLS #endif #endif struct emsabp_context { const char *account_name; struct loadparm_context *lp_ctx; struct ldb_context *samdb_ctx; void *ldb_ctx; TDB_CONTEXT *tdb_ctx; TDB_CONTEXT *ttdb_ctx; TALLOC_CTX *mem_ctx; }; struct exchange_nsp_session { struct mpm_session *session; struct GUID uuid; struct exchange_nsp_session *prev; struct exchange_nsp_session *next; }; struct emsabp_MId { uint32_t MId; char *dn; }; /** PermanentEntryID structure */ struct PermanentEntryID { uint8_t ID_type; /* constant: 0x0 */ uint8_t R1; /* reserved: 0x0 */ uint8_t R2; /* reserved: 0x0 */ uint8_t R3; /* reserved: 0x0 */ struct FlatUID_r ProviderUID; /* constant: GUID_NSPI */ uint32_t R4; /* constant: 0x1 */ uint32_t DisplayType; /* must match one of the existing Display Type value */ char *dn; /* DN string representing the object GUID */ }; /** EphemeralEntryID structure */ struct EphemeralEntryID { uint8_t ID_type; /* constant: 0x87 */ uint8_t R1; /* reserved: 0x0 */ uint8_t R2; /* reserved: 0x0 */ uint8_t R3; /* reserved: 0x0 */ struct FlatUID_r ProviderUID; /* NSPI server GUID */ uint32_t R4; /* constant: 0x1 */ uint32_t DisplayType; /* must match one of the existing Display Type value */ uint32_t MId; /* MId of this object */ }; #define EMSABP_DN "/guid=%08X%04X%04X%02X%02X%02X%02X%02X%02X%02X%02X" #define EMSABP_ADDRTYPE "EX" /** NSPI PR_CONTAINER_FLAGS values */ #define AB_RECIPIENTS 0x1 #define AB_SUBCONTAINERS 0x2 #define AB_UNMODIFIABLE 0x8 #define EMSABP_TDB_MID_START 0x1b28 #define EMSABP_TDB_TMP_MID_START 0x5000 #define EMSABP_TDB_DATA_REC "MId_index" #define DCESRV_NSP_RETURN(r,c,ctx) { r->out.result = c; return; if (ctx) talloc_free(ctx); } __BEGIN_DECLS NTSTATUS samba_init_module(void); struct ldb_context *samdb_connect(TALLOC_CTX *, struct tevent_context *, struct loadparm_context *, struct auth_session_info *, int); const struct GUID *samdb_ntds_objectGUID(struct ldb_context *); /* definitions from emsabp.c */ struct emsabp_context *emsabp_init(struct loadparm_context *, TDB_CONTEXT *); bool emsabp_destructor(void *); enum MAPISTATUS emsabp_get_account_info(TALLOC_CTX *, struct emsabp_context *, const char *, struct ldb_message **); bool emsabp_verify_user(struct dcesrv_call_state *, struct emsabp_context *); bool emsabp_verify_codepage(struct emsabp_context *, uint32_t); bool emsabp_verify_lcid(struct emsabp_context *, uint32_t); enum MAPISTATUS emsabp_set_EphemeralEntryID(struct emsabp_context *, uint32_t, uint32_t, struct EphemeralEntryID *); enum MAPISTATUS emsabp_set_PermanentEntryID(struct emsabp_context *, uint32_t, struct ldb_message *, struct PermanentEntryID *); enum MAPISTATUS emsabp_EphemeralEntryID_to_Binary_r(TALLOC_CTX *, struct EphemeralEntryID *, struct Binary_r *); enum MAPISTATUS emsabp_PermanentEntryID_to_Binary_r(TALLOC_CTX *, struct PermanentEntryID *, struct Binary_r *); enum MAPISTATUS emsabp_get_HierarchyTable(TALLOC_CTX *, struct emsabp_context *, uint32_t, struct PropertyRowSet_r **); enum MAPISTATUS emsabp_get_CreationTemplatesTable(TALLOC_CTX *, struct emsabp_context *, uint32_t, struct PropertyRowSet_r **); void *emsabp_query(TALLOC_CTX *, struct emsabp_context *, struct ldb_message *, uint32_t, uint32_t, uint32_t); enum MAPISTATUS emsabp_fetch_attrs_from_msg(TALLOC_CTX *, struct emsabp_context *, struct PropertyRow_r *, struct ldb_message *, uint32_t, uint32_t, struct SPropTagArray *); enum MAPISTATUS emsabp_fetch_attrs(TALLOC_CTX *, struct emsabp_context *, struct PropertyRow_r *, uint32_t, uint32_t, struct SPropTagArray *); enum MAPISTATUS emsabp_table_fetch_attrs(TALLOC_CTX *, struct emsabp_context *, struct PropertyRow_r *, uint32_t, struct PermanentEntryID *, struct PermanentEntryID *, struct ldb_message *, bool); enum MAPISTATUS emsabp_search(TALLOC_CTX *, struct emsabp_context *, struct PropertyTagArray_r *, struct Restriction_r *, struct STAT *, uint32_t); enum MAPISTATUS emsabp_search_dn(struct emsabp_context *, const char *, struct ldb_message **); enum MAPISTATUS emsabp_search_legacyExchangeDN(struct emsabp_context *, const char *, struct ldb_message **, bool *); enum MAPISTATUS emsabp_ab_container_by_id(TALLOC_CTX *, struct emsabp_context *, uint32_t, struct ldb_message **); enum MAPISTATUS emsabp_ab_container_enum(TALLOC_CTX *, struct emsabp_context *, uint32_t, struct ldb_result **); /* definitions from emsabp_tdb.c */ TDB_CONTEXT *emsabp_tdb_init(TALLOC_CTX *, struct loadparm_context *); enum MAPISTATUS emsabp_tdb_close(TDB_CONTEXT *); enum MAPISTATUS emsabp_tdb_fetch(TDB_CONTEXT *, const char *, TDB_DATA *); enum MAPISTATUS emsabp_tdb_insert(TDB_CONTEXT *, const char *); enum MAPISTATUS emsabp_tdb_fetch_MId(TDB_CONTEXT *, const char *, uint32_t *); bool emsabp_tdb_lookup_MId(TDB_CONTEXT *, uint32_t); enum MAPISTATUS emsabp_tdb_fetch_dn_from_MId(TALLOC_CTX *, TDB_CONTEXT *, uint32_t, char **); TDB_CONTEXT *emsabp_tdb_init_tmp(TALLOC_CTX *); /* definitions from emsabp_property.c */ const char *emsabp_property_get_attribute(uint32_t); uint32_t emsabp_property_get_ulPropTag(const char *); int emsabp_property_is_ref(uint32_t); const char *emsabp_property_get_ref_attr(uint32_t); __END_DECLS #endif /* __DCESRV_EXCHANGE_NSP_H */ openchange-2.0/mapiproxy/servers/default/nspi/emsabp.c000066400000000000000000001305361223057412600232250ustar00rootroot00000000000000/* OpenChange Server implementation. EMSABP: Address Book Provider implementation Copyright (C) Julien Kerihuel 2006-2013. Copyright (C) Pauline Khun 2006. This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see . */ /** \file emsabp.c \brief Address Book Provider implementation */ #define TEVENT_DEPRECATED #include "mapiproxy/dcesrv_mapiproxy.h" #include "dcesrv_exchange_nsp.h" /** \details Initialize the EMSABP context and open connections to Samba databases. \param lp_ctx pointer to the loadparm context \param tdb_ctx pointer to the EMSABP TDB context \return Allocated emsabp_context on success, otherwise NULL */ _PUBLIC_ struct emsabp_context *emsabp_init(struct loadparm_context *lp_ctx, TDB_CONTEXT *tdb_ctx) { TALLOC_CTX *mem_ctx; struct emsabp_context *emsabp_ctx; struct tevent_context *ev; /* Sanity checks */ if (!lp_ctx) return NULL; mem_ctx = talloc_named(NULL, 0, "emsabp_init"); emsabp_ctx = talloc_zero(mem_ctx, struct emsabp_context); if (!emsabp_ctx) { talloc_free(mem_ctx); return NULL; } emsabp_ctx->mem_ctx = mem_ctx; ev = tevent_context_init(mem_ctx); if (!ev) { talloc_free(mem_ctx); return NULL; } tevent_loop_allow_nesting(ev); /* Save a pointer to the loadparm context */ emsabp_ctx->lp_ctx = lp_ctx; /* Return an opaque context pointer on samDB database */ emsabp_ctx->samdb_ctx = samdb_connect(mem_ctx, ev, lp_ctx, system_session(lp_ctx), 0); if (!emsabp_ctx->samdb_ctx) { talloc_free(mem_ctx); DEBUG(0, ("[%s:%d]: Connection to \"sam.ldb\" failed\n", __FUNCTION__, __LINE__)); return NULL; } /* Reference the global TDB context to the current emsabp context */ emsabp_ctx->tdb_ctx = tdb_ctx; /* Initialize a temporary (on-memory) TDB database to store * temporary MId used within EMSABP */ emsabp_ctx->ttdb_ctx = emsabp_tdb_init_tmp(emsabp_ctx->mem_ctx); if (!emsabp_ctx->ttdb_ctx) { smb_panic("unable to create on-memory TDB database"); } return emsabp_ctx; } _PUBLIC_ bool emsabp_destructor(void *data) { struct emsabp_context *emsabp_ctx = (struct emsabp_context *)data; if (emsabp_ctx) { if (emsabp_ctx->ttdb_ctx) { tdb_close(emsabp_ctx->ttdb_ctx); } talloc_free(emsabp_ctx->mem_ctx); return true; } return false; } /** \details Get AD record for Mail-enabled account \param mem_ctx pointer to the session context \param emsabp_ctx pointer to the EMSABP context \param username User common name \param ldb_msg Pointer on pointer to ldb_message to return result to \return MAPI_E_SUCCESS on success, otherwise MAPI_E_NOT_ENOUGH_RESOURCES, MAPI_E_NOT_FOUND or MAPI_E_CORRUPT_STORE */ _PUBLIC_ enum MAPISTATUS emsabp_get_account_info(TALLOC_CTX *mem_ctx, struct emsabp_context *emsabp_ctx, const char *username, struct ldb_message **ldb_msg) { int ret; int msExchUserAccountControl; struct ldb_result *res = NULL; const char * const recipient_attrs[] = { "*", NULL }; ret = ldb_search(emsabp_ctx->samdb_ctx, mem_ctx, &res, ldb_get_default_basedn(emsabp_ctx->samdb_ctx), LDB_SCOPE_SUBTREE, recipient_attrs, "sAMAccountName=%s", username); OPENCHANGE_RETVAL_IF((ret != LDB_SUCCESS || !res->count), MAPI_E_NOT_FOUND, NULL); /* Check if more than one record was found */ OPENCHANGE_RETVAL_IF(res->count != 1, MAPI_E_CORRUPT_STORE, NULL); msExchUserAccountControl = ldb_msg_find_attr_as_int(res->msgs[0], "msExchUserAccountControl", -1); switch (msExchUserAccountControl) { case -1: /* msExchUserAccountControl attribute is not found */ return MAPI_E_NOT_FOUND; case 0: *ldb_msg = res->msgs[0]; return MAPI_E_SUCCESS; case 2: /* Account is disabled */ *ldb_msg = res->msgs[0]; return MAPI_E_ACCOUNT_DISABLED; default: /* Unknown value for msExchUserAccountControl attribute */ return MAPI_E_CORRUPT_STORE; } /* We should never get here anyway */ return MAPI_E_CORRUPT_STORE; } /** \details Check if the authenticated user belongs to the Exchange organization \param dce_call pointer to the session context \param emsabp_ctx pointer to the EMSABP context \return true on success, otherwise false */ _PUBLIC_ bool emsabp_verify_user(struct dcesrv_call_state *dce_call, struct emsabp_context *emsabp_ctx) { int ret; TALLOC_CTX *mem_ctx; const char *username = NULL; struct ldb_message *ldb_msg = NULL; username = dcesrv_call_account_name(dce_call); mem_ctx = talloc_named(emsabp_ctx->mem_ctx, 0, __FUNCTION__); ret = emsabp_get_account_info(mem_ctx, emsabp_ctx, username, &ldb_msg); /* cache account_name upon success */ if (MAPI_STATUS_IS_OK(ret)) { emsabp_ctx->account_name = talloc_strdup(emsabp_ctx->mem_ctx, username); } talloc_free(mem_ctx); return MAPI_STATUS_IS_OK(ret); } /** \details Check if the provided codepage is correct \param emsabp_ctx pointer to the EMSABP context \param CodePage the codepage identifier \note The prototype is currently incorrect, but we are looking for a better way to check codepage, maybe within AD. At the moment this function is just a wrapper over libmapi valid_codepage function. \return true on success, otherwise false */ _PUBLIC_ bool emsabp_verify_codepage(struct emsabp_context *emsabp_ctx, uint32_t CodePage) { return mapi_verify_cpid(CodePage); } /** \details Build an EphemeralEntryID structure \param emsabp_ctx pointer to the EMSABP context \param DisplayType the AB object display type \param MId the MId value \param ephEntryID pointer to the EphemeralEntryID returned by the function \return MAPI_E_SUCCESS on success, otherwise MAPI_E_NOT_ENOUGH_RESOURCES or MAPI_E_CORRUPT_STORE */ _PUBLIC_ enum MAPISTATUS emsabp_set_EphemeralEntryID(struct emsabp_context *emsabp_ctx, uint32_t DisplayType, uint32_t MId, struct EphemeralEntryID *ephEntryID) { struct GUID *guid = (struct GUID *) NULL; /* Sanity checks */ OPENCHANGE_RETVAL_IF(!ephEntryID, MAPI_E_NOT_ENOUGH_RESOURCES, NULL); guid = (struct GUID *) samdb_ntds_objectGUID(emsabp_ctx->samdb_ctx); OPENCHANGE_RETVAL_IF(!guid, MAPI_E_CORRUPT_STORE, NULL); ephEntryID->ID_type = 0x87; ephEntryID->R1 = 0x0; ephEntryID->R2 = 0x0; ephEntryID->R3 = 0x0; ephEntryID->ProviderUID.ab[0] = (guid->time_low & 0xFF); ephEntryID->ProviderUID.ab[1] = ((guid->time_low >> 8) & 0xFF); ephEntryID->ProviderUID.ab[2] = ((guid->time_low >> 16) & 0xFF); ephEntryID->ProviderUID.ab[3] = ((guid->time_low >> 24) & 0xFF); ephEntryID->ProviderUID.ab[4] = (guid->time_mid & 0xFF); ephEntryID->ProviderUID.ab[5] = ((guid->time_mid >> 8) & 0xFF); ephEntryID->ProviderUID.ab[6] = (guid->time_hi_and_version & 0xFF); ephEntryID->ProviderUID.ab[7] = ((guid->time_hi_and_version >> 8) & 0xFF); memcpy(ephEntryID->ProviderUID.ab + 8, guid->clock_seq, sizeof (uint8_t) * 2); memcpy(ephEntryID->ProviderUID.ab + 10, guid->node, sizeof (uint8_t) * 6); ephEntryID->R4 = 0x1; ephEntryID->DisplayType = DisplayType; ephEntryID->MId = MId; return MAPI_E_SUCCESS; } /** \details Map an EphemeralEntryID structure into a Binary_r structure \param mem_ctx pointer to the memory context \param ephEntryID pointer to the Ephemeral EntryID structure \param bin pointer to the Binary_r structure the server will return \return MAPI_E_SUCCESS on success, otherwise MAPI_E_INVALID_PARAMETER */ _PUBLIC_ enum MAPISTATUS emsabp_EphemeralEntryID_to_Binary_r(TALLOC_CTX *mem_ctx, struct EphemeralEntryID *ephEntryID, struct Binary_r *bin) { /* Sanity checks */ OPENCHANGE_RETVAL_IF(!ephEntryID, MAPI_E_INVALID_PARAMETER, NULL); OPENCHANGE_RETVAL_IF(!bin, MAPI_E_INVALID_PARAMETER, NULL); bin->cb = sizeof (*ephEntryID); bin->lpb = talloc_array(mem_ctx, uint8_t, bin->cb); /* Copy EphemeralEntryID into bin->lpb */ memset(bin->lpb, 0, bin->cb); bin->lpb[0] = ephEntryID->ID_type; bin->lpb[1] = ephEntryID->R1; bin->lpb[2] = ephEntryID->R2; bin->lpb[3] = ephEntryID->R3; memcpy(bin->lpb + 4, ephEntryID->ProviderUID.ab, 16); bin->lpb[20] = (ephEntryID->R4 & 0xFF); bin->lpb[21] = ((ephEntryID->R4 >> 8) & 0xFF); bin->lpb[22] = ((ephEntryID->R4 >> 16) & 0xFF); bin->lpb[23] = ((ephEntryID->R4 >> 24) & 0xFF); bin->lpb[24] = (ephEntryID->DisplayType & 0xFF); bin->lpb[25] = ((ephEntryID->DisplayType >> 8) & 0xFF); bin->lpb[26] = ((ephEntryID->DisplayType >> 16) & 0xFF); bin->lpb[27] = ((ephEntryID->DisplayType >> 24) & 0xFF); bin->lpb[28] = (ephEntryID->MId & 0xFF); bin->lpb[29] = ((ephEntryID->MId >> 8) & 0xFF); bin->lpb[30] = ((ephEntryID->MId >> 16) & 0xFF); bin->lpb[31] = ((ephEntryID->MId >> 24) & 0xFF); return MAPI_E_SUCCESS; } /** \details Build a PermanentEntryID structure \param emsabp_ctx pointer to the EMSABP context \param DisplayType the AB object display type \param msg pointer to the LDB message \param permEntryID pointer to the PermanentEntryID returned by the function \note This function only covers DT_CONTAINER AddressBook objects. It should be extended in the future to support more containers. \return MAPI_E_SUCCESS on success, otherwise MAPI_E_NOT_ENOUGH_RESOURCES or MAPI_E_CORRUPT_STORE */ _PUBLIC_ enum MAPISTATUS emsabp_set_PermanentEntryID(struct emsabp_context *emsabp_ctx, uint32_t DisplayType, struct ldb_message *msg, struct PermanentEntryID *permEntryID) { struct GUID *guid = (struct GUID *) NULL; const struct ldb_val *ldb_value = NULL; const char *dn_str; /* Sanity checks */ OPENCHANGE_RETVAL_IF(!permEntryID, MAPI_E_NOT_ENOUGH_RESOURCES, NULL); permEntryID->ID_type = 0x0; permEntryID->R1 = 0x0; permEntryID->R2 = 0x0; permEntryID->R3 = 0x0; memcpy(permEntryID->ProviderUID.ab, GUID_NSPI, 16); permEntryID->R4 = 0x1; permEntryID->DisplayType = DisplayType; if (!msg) { permEntryID->dn = talloc_strdup(emsabp_ctx->mem_ctx, "/"); } else if (DisplayType == DT_CONTAINER) { ldb_value = ldb_msg_find_ldb_val(msg, "objectGUID"); OPENCHANGE_RETVAL_IF(!ldb_value, MAPI_E_CORRUPT_STORE, NULL); guid = talloc_zero(emsabp_ctx->mem_ctx, struct GUID); GUID_from_data_blob(ldb_value, guid); permEntryID->dn = talloc_asprintf(emsabp_ctx->mem_ctx, EMSABP_DN, guid->time_low, guid->time_mid, guid->time_hi_and_version, guid->clock_seq[0], guid->clock_seq[1], guid->node[0], guid->node[1], guid->node[2], guid->node[3], guid->node[4], guid->node[5]); talloc_free(guid); } else { dn_str = ldb_msg_find_attr_as_string(msg, "legacyExchangeDN", NULL); OPENCHANGE_RETVAL_IF(!dn_str, MAPI_E_CORRUPT_STORE, NULL); permEntryID->dn = talloc_strdup(emsabp_ctx->mem_ctx, dn_str); } return MAPI_E_SUCCESS; } /** \details Map a PermanentEntryID structure into a Binary_r structure (for PR_ENTRYID and PR_EMS_AB_PARENT_ENTRYID properties) \param mem_ctx pointer to the memory context \param permEntryID pointer to the Permanent EntryID structure \param bin pointer to the Binary_r structure the server will return \return MAPI_E_SUCCESS on success, otherwise MAPI_E_INVALID_PARAMETER */ _PUBLIC_ enum MAPISTATUS emsabp_PermanentEntryID_to_Binary_r(TALLOC_CTX *mem_ctx, struct PermanentEntryID *permEntryID, struct Binary_r *bin) { /* Sanity checks */ OPENCHANGE_RETVAL_IF(!permEntryID, MAPI_E_INVALID_PARAMETER, NULL); OPENCHANGE_RETVAL_IF(!bin, MAPI_E_INVALID_PARAMETER, NULL); /* Remove const char * size and replace it with effective dn string length */ bin->cb = 28 + strlen(permEntryID->dn) + 1; bin->lpb = talloc_array(mem_ctx, uint8_t, bin->cb); /* Copy PermanantEntryID intro bin->lpb */ memset(bin->lpb, 0, bin->cb); bin->lpb[0] = permEntryID->ID_type; bin->lpb[1] = permEntryID->R1; bin->lpb[2] = permEntryID->R2; bin->lpb[3] = permEntryID->R3; memcpy(bin->lpb + 4, permEntryID->ProviderUID.ab, 16); bin->lpb[20] = (permEntryID->R4 & 0xFF); bin->lpb[21] = ((permEntryID->R4 >> 8) & 0xFF); bin->lpb[22] = ((permEntryID->R4 >> 16) & 0xFF); bin->lpb[23] = ((permEntryID->R4 >> 24) & 0xFF); bin->lpb[24] = (permEntryID->DisplayType & 0xFF); bin->lpb[25] = ((permEntryID->DisplayType >> 8) & 0xFF); bin->lpb[26] = ((permEntryID->DisplayType >> 16) & 0xFF); bin->lpb[27] = ((permEntryID->DisplayType >> 24) & 0xFF); memcpy(bin->lpb + 28, permEntryID->dn, strlen(permEntryID->dn) + 1); return MAPI_E_SUCCESS; } /** \details Find the attribute matching the specified property tag and return the associated data. \param mem_ctx pointer to the memory context \param emsabp_ctx pointer to the EMSABP context \param msg pointer to the LDB message \param ulPropTag the property tag to lookup \param MId Minimal Entry ID associated to the current message \param dwFlags bit flags specifying whether or not the server must return the values of the property PidTagEntryId in the Ephemeral or Permanent Entry ID format \note This implementation is at the moment limited to MAILUSER, which means we arbitrary set PR_OBJECT_TYPE and PR_DISPLAY_TYPE while we should have a generic method to fill these properties. \return Valid generic pointer on success, otherwise NULL */ _PUBLIC_ void *emsabp_query(TALLOC_CTX *mem_ctx, struct emsabp_context *emsabp_ctx, struct ldb_message *msg, uint32_t ulPropTag, uint32_t MId, uint32_t dwFlags) { enum MAPISTATUS retval; void *data = (void *) NULL; const char *attribute; const char *ref_attribute; const char *ldb_string = NULL; const struct ldb_val *ldb_val; char *tmp_str; struct Binary_r *bin; struct StringArray_r *mvszA; struct EphemeralEntryID ephEntryID; struct PermanentEntryID permEntryID; struct ldb_message *msg2 = NULL; struct ldb_message_element *ldb_element; int ret; const char *dn = NULL; uint32_t i; /* Step 1. Fill attributes not in AD but created using EMSABP databases */ switch (ulPropTag) { case PR_ADDRTYPE: case PR_ADDRTYPE_UNICODE: data = (void *) talloc_strdup(mem_ctx, EMSABP_ADDRTYPE /* "SMTP" */); return data; case PR_OBJECT_TYPE: data = talloc_zero(mem_ctx, uint32_t); *((uint32_t *)data) = MAPI_MAILUSER; return data; case PR_DISPLAY_TYPE: data = talloc_zero(mem_ctx, uint32_t); *((uint32_t *)data) = DT_MAILUSER; return data; case PR_SEND_RICH_INFO: data = talloc_zero(mem_ctx, uint8_t); *((uint8_t *)data) = false; return data; case PR_SEND_INTERNET_ENCODING: data = talloc_zero(mem_ctx, uint32_t); *((uint32_t *)data) = 0x00160000; return data; case PidTagAddressBookHierarchicalIsHierarchicalGroup: data = talloc_zero(mem_ctx, uint32_t); *((uint32_t *)data) = 0; return data; case PR_ENTRYID: case PR_ORIGINAL_ENTRYID: bin = talloc(mem_ctx, struct Binary_r); if (dwFlags & fEphID) { retval = emsabp_set_EphemeralEntryID(emsabp_ctx, DT_MAILUSER, MId, &ephEntryID); retval = emsabp_EphemeralEntryID_to_Binary_r(mem_ctx, &ephEntryID, bin); } else { retval = emsabp_set_PermanentEntryID(emsabp_ctx, DT_MAILUSER, msg, &permEntryID); retval = emsabp_PermanentEntryID_to_Binary_r(mem_ctx, &permEntryID, bin); } return bin; case PR_SEARCH_KEY: /* retrieve email address attribute, i.e. legacyExchangeDN */ ldb_string = ldb_msg_find_attr_as_string(msg, emsabp_property_get_attribute(PidTagEmailAddress), NULL); if (!ldb_string) return NULL; tmp_str = talloc_strdup_upper(mem_ctx, ldb_string); if (!tmp_str) return NULL; /* make binary for PR_SEARCH_KEY */ bin = talloc(mem_ctx, struct Binary_r); bin->lpb = (uint8_t *)talloc_asprintf(mem_ctx, "EX:%s", tmp_str); bin->cb = strlen((const char *)bin->lpb) + 1; talloc_free(tmp_str); return bin; case PR_INSTANCE_KEY: bin = talloc_zero(mem_ctx, struct Binary_r); bin->cb = 4; bin->lpb = talloc_array(mem_ctx, uint8_t, bin->cb); memset(bin->lpb, 0, bin->cb); bin->lpb[0] = MId & 0xFF; bin->lpb[1] = (MId >> 8) & 0xFF; bin->lpb[2] = (MId >> 16) & 0xFF; bin->lpb[3] = (MId >> 24) & 0xFF; return bin; case PR_EMS_AB_OBJECT_GUID: ldb_val = ldb_msg_find_ldb_val(msg, emsabp_property_get_attribute(PR_EMS_AB_OBJECT_GUID)); if (!ldb_val) return NULL; bin = talloc_zero(mem_ctx, struct Binary_r); bin->cb = ldb_val->length; bin->lpb = talloc_memdup(bin, ldb_val->data, ldb_val->length); return bin; default: break; } /* Step 2. Retrieve the attribute name associated to ulPropTag and handle the ref case */ attribute = emsabp_property_get_attribute(ulPropTag); if (!attribute) return NULL; ret = emsabp_property_is_ref(ulPropTag); if (ret == 1) { ref_attribute = emsabp_property_get_ref_attr(ulPropTag); if (ref_attribute) { dn = ldb_msg_find_attr_as_string(msg, attribute, NULL); retval = emsabp_search_dn(emsabp_ctx, dn, &msg2); if (retval != MAPI_E_SUCCESS) { return NULL; } attribute = ref_attribute; } } else { msg2 = msg; } /* Step 3. Retrieve data associated to the attribute/tag */ switch (ulPropTag & 0xFFFF) { case PT_STRING8: case PT_UNICODE: ldb_string = ldb_msg_find_attr_as_string(msg2, attribute, NULL); if (!ldb_string) return NULL; data = talloc_strdup(mem_ctx, ldb_string); break; case PT_MV_STRING8: case PT_MV_UNICODE: ldb_element = ldb_msg_find_element(msg2, attribute); if (!ldb_element) return NULL; mvszA = talloc(mem_ctx, struct StringArray_r); mvszA->cValues = ldb_element[0].num_values & 0xFFFFFFFF; mvszA->lppszA = talloc_array(mem_ctx, const char *, mvszA->cValues); for (i = 0; i < mvszA->cValues; i++) { mvszA->lppszA[i] = talloc_strdup(mem_ctx, (char *)ldb_element->values[i].data); } data = (void *) mvszA; break; default: DEBUG(3, ("[%s:%d]: Unsupported property type: 0x%x\n", __FUNCTION__, __LINE__, (ulPropTag & 0xFFFF))); break; } return data; } /** \details Build the SRow array entry for the specified ldb_message. \param mem_ctx pointer to the memory context \param emsabp_ctx pointer to the EMSABP context \param aRow pointer to the SRow structure where results will be stored \param ldb_msg ldb_message record to fetch results from \param MId MId of the entry to fetch (may be 0) \param dwFlags input call flags (default to 0) \param pPropTags pointer to the property tags array \return MAPI_E_SUCCESS on success, otherwise MAPI error */ _PUBLIC_ enum MAPISTATUS emsabp_fetch_attrs_from_msg(TALLOC_CTX *mem_ctx, struct emsabp_context *emsabp_ctx, struct PropertyRow_r *aRow, struct ldb_message *ldb_msg, uint32_t MId, uint32_t dwFlags, struct SPropTagArray *pPropTags) { enum MAPISTATUS retval; const char *dn; void *data; uint32_t ulPropTag; int i; OPENCHANGE_RETVAL_IF(pPropTags == NULL, MAPI_E_INVALID_PARAMETER, NULL); /* Step 0. Create MId if necessary */ if (MId == 0) { dn = ldb_msg_find_attr_as_string(ldb_msg, "distinguishedName", NULL); OPENCHANGE_RETVAL_IF(!dn, MAPI_E_CORRUPT_DATA, NULL); retval = emsabp_tdb_fetch_MId(emsabp_ctx->ttdb_ctx, dn, &MId); if (retval) { retval = emsabp_tdb_insert(emsabp_ctx->ttdb_ctx, dn); OPENCHANGE_RETVAL_IF(retval, MAPI_E_CORRUPT_STORE, NULL); retval = emsabp_tdb_fetch_MId(emsabp_ctx->ttdb_ctx, dn, &MId); OPENCHANGE_RETVAL_IF(retval, MAPI_E_CORRUPT_STORE, NULL); } } /* Step 1. Retrieve property values and build aRow */ aRow->Reserved = 0x0; aRow->cValues = pPropTags->cValues; aRow->lpProps = talloc_array(mem_ctx, struct PropertyValue_r, aRow->cValues); for (i = 0; i < aRow->cValues; i++) { ulPropTag = pPropTags->aulPropTag[i]; data = emsabp_query(mem_ctx, emsabp_ctx, ldb_msg, ulPropTag, MId, dwFlags); if (!data) { ulPropTag = (ulPropTag & 0xFFFF0000) | PT_ERROR; } aRow->lpProps[i].ulPropTag = (enum MAPITAGS) ulPropTag; aRow->lpProps[i].dwAlignPad = 0x0; set_PropertyValue(&(aRow->lpProps[i]), data); } return MAPI_E_SUCCESS; } /** \details Builds the SRow array entry for the specified MId. The function retrieves the DN associated to the specified MId within its on-memory TDB database. It next fetches the LDB record matching the DN and finally retrieve the requested properties for this record. \param mem_ctx pointer to the memory context \param emsabp_ctx pointer to the EMSABP context \param aRow pointer to the SRow structure where results will be stored \param MId MId to fetch properties for \param dwFlags bit flags specifying whether or not the server must return the values of the property PidTagEntryId in the Ephemeral or Permanent Entry ID format \param pPropTags pointer to the property tags array \note We currently assume records are users.ldb \return MAPI_E_SUCCESS on success, otherwise MAPI error */ _PUBLIC_ enum MAPISTATUS emsabp_fetch_attrs(TALLOC_CTX *mem_ctx, struct emsabp_context *emsabp_ctx, struct PropertyRow_r *aRow, uint32_t MId, uint32_t dwFlags, struct SPropTagArray *pPropTags) { enum MAPISTATUS retval; char *dn; const char * const recipient_attrs[] = { "*", NULL }; struct ldb_result *res = NULL; struct ldb_dn *ldb_dn = NULL; int ret; uint32_t ulPropTag; void *data; int i; /* Step 0. Try to Retrieve the dn associated to the MId first from temp TDB (users) */ retval = emsabp_tdb_fetch_dn_from_MId(mem_ctx, emsabp_ctx->ttdb_ctx, MId, &dn); if (!MAPI_STATUS_IS_OK(retval)) { /* If it fails try to retrieve it from the on-disk TDB database (conf) */ retval = emsabp_tdb_fetch_dn_from_MId(mem_ctx, emsabp_ctx->tdb_ctx, MId, &dn); } OPENCHANGE_RETVAL_IF(retval, MAPI_E_INVALID_BOOKMARK, NULL); /* Step 1. Fetch the LDB record */ ldb_dn = ldb_dn_new(mem_ctx, emsabp_ctx->samdb_ctx, dn); OPENCHANGE_RETVAL_IF(!ldb_dn_validate(ldb_dn), MAPI_E_CORRUPT_STORE, NULL); ret = ldb_search(emsabp_ctx->samdb_ctx, emsabp_ctx->mem_ctx, &res, ldb_dn, LDB_SCOPE_BASE, recipient_attrs, NULL); OPENCHANGE_RETVAL_IF(ret != LDB_SUCCESS || !res->count || res->count != 1, MAPI_E_CORRUPT_STORE, NULL); /* Step 2. Retrieve property values and build aRow */ aRow->Reserved = 0x0; aRow->cValues = pPropTags->cValues; aRow->lpProps = talloc_array(mem_ctx, struct PropertyValue_r, aRow->cValues); for (i = 0; i < aRow->cValues; i++) { ulPropTag = pPropTags->aulPropTag[i]; data = emsabp_query(mem_ctx, emsabp_ctx, res->msgs[0], ulPropTag, MId, dwFlags); if (!data) { ulPropTag &= 0xFFFF0000; ulPropTag += PT_ERROR; } aRow->lpProps[i].ulPropTag = (enum MAPITAGS) ulPropTag; aRow->lpProps[i].dwAlignPad = 0x0; set_PropertyValue(&(aRow->lpProps[i]), data); } return MAPI_E_SUCCESS; } /** \details Builds the SRow array entry for the specified table record. \param mem_ctx pointer to the memory context \param emsabp_ctx pointer to the EMSABP context \param aRow pointer to the SRow structure where results will be stored \param dwFlags flags controlling whether strings should be unicode encoded or not \param permEntryID pointer to the current record Permanent EntryID \param parentPermEntryID pointer to the parent record Permanent EntryID \param msg pointer to the LDB message for current record \param child boolean value specifying whether current record is root or child within containers hierarchy \return MAPI_E_SUCCESS on success, otherwise MAPI error */ _PUBLIC_ enum MAPISTATUS emsabp_table_fetch_attrs(TALLOC_CTX *mem_ctx, struct emsabp_context *emsabp_ctx, struct PropertyRow_r *aRow, uint32_t dwFlags, struct PermanentEntryID *permEntryID, struct PermanentEntryID *parentPermEntryID, struct ldb_message *msg, bool child) { enum MAPISTATUS retval; struct SPropTagArray *SPropTagArray; struct PropertyValue_r lpProps; int proptag; uint32_t i; uint32_t containerID = 0; const char *dn = NULL; /* Step 1. Build the array of properties to fetch and map */ if (child == false) { SPropTagArray = set_SPropTagArray(mem_ctx, 0x6, PR_ENTRYID, PR_CONTAINER_FLAGS, PR_DEPTH, PR_EMS_AB_CONTAINERID, ((dwFlags & NspiUnicodeStrings) ? PR_DISPLAY_NAME_UNICODE : PR_DISPLAY_NAME), PR_EMS_AB_IS_MASTER); } else { SPropTagArray = set_SPropTagArray(mem_ctx, 0x7, PR_ENTRYID, PR_CONTAINER_FLAGS, PR_DEPTH, PR_EMS_AB_CONTAINERID, ((dwFlags & NspiUnicodeStrings) ? PR_DISPLAY_NAME_UNICODE : PR_DISPLAY_NAME), PR_EMS_AB_IS_MASTER, PR_EMS_AB_PARENT_ENTRYID); } /* Step 2. Allocate SPropValue array and update SRow cValues field */ aRow->Reserved = 0x0; aRow->cValues = 0x0; aRow->lpProps = talloc_zero(mem_ctx, struct PropertyValue_r); /* Step 3. Global Address List or real container */ if (!msg) { /* Global Address List record is constant */ for (i = 0; i < SPropTagArray->cValues; i++) { lpProps.ulPropTag = SPropTagArray->aulPropTag[i]; lpProps.dwAlignPad = 0x0; switch (SPropTagArray->aulPropTag[i]) { case PR_ENTRYID: emsabp_PermanentEntryID_to_Binary_r(mem_ctx, permEntryID, &(lpProps.value.bin)); break; case PR_CONTAINER_FLAGS: lpProps.value.l = AB_RECIPIENTS | AB_UNMODIFIABLE; break; case PR_DEPTH: lpProps.value.l = 0x0; break; case PR_EMS_AB_CONTAINERID: lpProps.value.l = 0x0; break; case PidTagDisplayName: lpProps.value.lpszW = NULL; break; case PR_EMS_AB_IS_MASTER: lpProps.value.b = false; break; default: break; } PropertyRow_addprop(aRow, lpProps); /* PropertyRow_addprop internals overwrite with MAPI_E_NOT_FOUND when data is NULL */ if (SPropTagArray->aulPropTag[i] == PR_DISPLAY_NAME || SPropTagArray->aulPropTag[i] == PR_DISPLAY_NAME_UNICODE) { aRow->lpProps[aRow->cValues - 1].value.lpszA = NULL; aRow->lpProps[aRow->cValues - 1].value.lpszW = NULL; } } } else { for (i = 0; i < SPropTagArray->cValues; i++) { lpProps.ulPropTag = SPropTagArray->aulPropTag[i]; lpProps.dwAlignPad = 0x0; switch (SPropTagArray->aulPropTag[i]) { case PR_ENTRYID: emsabp_PermanentEntryID_to_Binary_r(mem_ctx, permEntryID, &(lpProps.value.bin)); break; case PR_CONTAINER_FLAGS: switch (child) { case true: lpProps.value.l = AB_RECIPIENTS | AB_SUBCONTAINERS | AB_UNMODIFIABLE; break; case false: lpProps.value.l = AB_RECIPIENTS | AB_UNMODIFIABLE; } break; case PR_DEPTH: switch (child) { case true: lpProps.value.l = 0x1; break; case false: lpProps.value.l = 0x0; break; } break; case PR_EMS_AB_CONTAINERID: dn = ldb_msg_find_attr_as_string(msg, "distinguishedName", NULL); retval = emsabp_tdb_fetch_MId(emsabp_ctx->tdb_ctx, dn, &containerID); if (retval) { retval = emsabp_tdb_insert(emsabp_ctx->tdb_ctx, dn); OPENCHANGE_RETVAL_IF(retval, MAPI_E_CORRUPT_STORE, NULL); retval = emsabp_tdb_fetch_MId(emsabp_ctx->tdb_ctx, dn, &containerID); OPENCHANGE_RETVAL_IF(retval, MAPI_E_CORRUPT_STORE, NULL); } lpProps.value.l = containerID; break; case PidTagDisplayName_string8: lpProps.value.lpszA = talloc_strdup(mem_ctx, ldb_msg_find_attr_as_string(msg, "displayName", NULL)); if (!lpProps.value.lpszA) { proptag = (int) lpProps.ulPropTag; proptag &= 0xFFFF0000; proptag += PT_ERROR; lpProps.ulPropTag = (enum MAPITAGS) proptag; } break; case PidTagDisplayName: lpProps.value.lpszW = talloc_strdup(mem_ctx, ldb_msg_find_attr_as_string(msg, "displayName", NULL)); if (!lpProps.value.lpszW) { proptag = (int) lpProps.ulPropTag; proptag &= 0xFFFF0000; proptag += PT_ERROR; lpProps.ulPropTag = (enum MAPITAGS) proptag; } break; case PR_EMS_AB_IS_MASTER: /* FIXME: harcoded value - no load balancing */ lpProps.value.l = 0x0; break; case PR_EMS_AB_PARENT_ENTRYID: emsabp_PermanentEntryID_to_Binary_r(mem_ctx, parentPermEntryID, &lpProps.value.bin); break; default: break; } PropertyRow_addprop(aRow, lpProps); } } return MAPI_E_SUCCESS; } /** \details Retrieve and build the HierarchyTable requested by GetSpecialTable NSPI call \param mem_ctx pointer to the memory context \param emsabp_ctx pointer to the EMSABP context \param dwFlags flags controlling whether strings should be UNICODE or not \param SRowSet pointer on pointer to the output SRowSet array \return MAPI_E_SUCCESS on success, otherwise MAPI_E_CORRUPT_STORE */ _PUBLIC_ enum MAPISTATUS emsabp_get_HierarchyTable(TALLOC_CTX *mem_ctx, struct emsabp_context *emsabp_ctx, uint32_t dwFlags, struct PropertyRowSet_r **SRowSet) { enum MAPISTATUS retval; struct PropertyRow_r *aRow; struct PermanentEntryID gal; struct PermanentEntryID parentPermEntryID; struct PermanentEntryID permEntryID; enum ldb_scope scope = LDB_SCOPE_SUBTREE; struct ldb_request *req; struct ldb_result *res = NULL; struct ldb_dn *ldb_dn = NULL; struct ldb_control **controls; const char * const recipient_attrs[] = { "*", NULL }; const char *control_strings[2] = { "server_sort:0:0:displayName", NULL }; const char *addressBookRoots; int ret; uint32_t aRow_idx; uint32_t i; /* Step 1. Build the 'Global Address List' object using PermanentEntryID */ aRow = talloc_zero(mem_ctx, struct PropertyRow_r); OPENCHANGE_RETVAL_IF(!aRow, MAPI_E_NOT_ENOUGH_RESOURCES, NULL); aRow_idx = 0; retval = emsabp_set_PermanentEntryID(emsabp_ctx, DT_CONTAINER, NULL, &gal); OPENCHANGE_RETVAL_IF(retval, retval, aRow); retval = emsabp_table_fetch_attrs(mem_ctx, emsabp_ctx, &aRow[aRow_idx], dwFlags, &gal, NULL, NULL, false); aRow_idx++; /* Step 2. Retrieve the object pointed by addressBookRoots attribute: 'All Address Lists' */ ret = ldb_search(emsabp_ctx->samdb_ctx, emsabp_ctx->mem_ctx, &res, ldb_get_config_basedn(emsabp_ctx->samdb_ctx), scope, recipient_attrs, "(addressBookRoots=*)"); OPENCHANGE_RETVAL_IF(ret != LDB_SUCCESS || !res->count, MAPI_E_CORRUPT_STORE, aRow); addressBookRoots = ldb_msg_find_attr_as_string(res->msgs[0], "addressBookRoots", NULL); OPENCHANGE_RETVAL_IF(!addressBookRoots, MAPI_E_CORRUPT_STORE, aRow); ldb_dn = ldb_dn_new(emsabp_ctx->mem_ctx, emsabp_ctx->samdb_ctx, addressBookRoots); talloc_free(res); OPENCHANGE_RETVAL_IF(!ldb_dn_validate(ldb_dn), MAPI_E_CORRUPT_STORE, aRow); scope = LDB_SCOPE_BASE; ret = ldb_search(emsabp_ctx->samdb_ctx, emsabp_ctx->mem_ctx, &res, ldb_dn, scope, recipient_attrs, NULL); OPENCHANGE_RETVAL_IF(ret != LDB_SUCCESS || !res->count || res->count != 1, MAPI_E_CORRUPT_STORE, aRow); aRow = talloc_realloc(mem_ctx, aRow, struct PropertyRow_r, aRow_idx + 1); retval = emsabp_set_PermanentEntryID(emsabp_ctx, DT_CONTAINER, res->msgs[0], &parentPermEntryID); emsabp_table_fetch_attrs(mem_ctx, emsabp_ctx, &aRow[aRow_idx], dwFlags, &parentPermEntryID, NULL, res->msgs[0], false); aRow_idx++; talloc_free(res); /* Step 3. Retrieve 'All Address Lists' subcontainers */ res = talloc_zero(mem_ctx, struct ldb_result); OPENCHANGE_RETVAL_IF(!res, MAPI_E_NOT_ENOUGH_RESOURCES, aRow); controls = ldb_parse_control_strings(emsabp_ctx->samdb_ctx, emsabp_ctx->mem_ctx, control_strings); ret = ldb_build_search_req(&req, emsabp_ctx->samdb_ctx, emsabp_ctx->mem_ctx, ldb_dn, LDB_SCOPE_SUBTREE, "(purportedSearch=*)", recipient_attrs, controls, res, ldb_search_default_callback, NULL); if (ret != LDB_SUCCESS) { talloc_free(res); talloc_free(aRow); return MAPI_E_CORRUPT_STORE; } ret = ldb_request(emsabp_ctx->samdb_ctx, req); if (ret == LDB_SUCCESS) { ret = ldb_wait(req->handle, LDB_WAIT_ALL); } talloc_free(req); if (ret != LDB_SUCCESS || !res->count) { talloc_free(res); talloc_free(aRow); return MAPI_E_CORRUPT_STORE; } aRow = talloc_realloc(mem_ctx, aRow, struct PropertyRow_r, aRow_idx + res->count + 1); for (i = 0; res->msgs[i]; i++) { retval = emsabp_set_PermanentEntryID(emsabp_ctx, DT_CONTAINER, res->msgs[i], &permEntryID); emsabp_table_fetch_attrs(mem_ctx, emsabp_ctx, &aRow[aRow_idx], dwFlags, &permEntryID, &parentPermEntryID, res->msgs[i], true); talloc_free(permEntryID.dn); memset(&permEntryID, 0, sizeof (permEntryID)); aRow_idx++; } talloc_free(res); talloc_free(parentPermEntryID.dn); /* Step 4. Build output SRowSet */ SRowSet[0]->cRows = aRow_idx; SRowSet[0]->aRow = aRow; return MAPI_E_SUCCESS; } /** \details Retrieve and build the CreationTemplates Table requested by GetSpecialTable NSPI call \param mem_ctx pointer to the memory context \param emsabp_ctx pointer to the EMSABP context \param dwFlags flags controlling whether strings should be UNICODE or not \param SRowSet pointer on pointer to the output SRowSet array \return MAPI_E_SUCCESS on success, otherwise MAPI_E_CORRUPT_STORE */ _PUBLIC_ enum MAPISTATUS emsabp_get_CreationTemplatesTable(TALLOC_CTX *mem_ctx, struct emsabp_context *emsabp_ctx, uint32_t dwFlags, struct PropertyRowSet_r **SRowSet) { return MAPI_E_SUCCESS; } /** \details Search Active Directory given input search criterias. The function associates for each records returned by the search a unique session Minimal Entry ID and a LDB message. \param mem_ctx pointer to the memory context \param emsabp_ctx pointer to the EMSABP context \param MIds pointer to the list of MIds the function returns \param restriction pointer to restriction rules to apply to the search \param pStat pointer the STAT structure associated to the search \param limit the limit number of results the function can return \note SortTypePhoneticDisplayName sort type is currently not supported. \return MAPI_E_SUCCESS on success, otherwise MAPI error */ _PUBLIC_ enum MAPISTATUS emsabp_search(TALLOC_CTX *mem_ctx, struct emsabp_context *emsabp_ctx, struct PropertyTagArray_r *MIds, struct Restriction_r *restriction, struct STAT *pStat, uint32_t limit) { enum MAPISTATUS retval; struct ldb_result *res = NULL; struct PropertyRestriction_r *res_prop = NULL; const char * const recipient_attrs[] = { "*", NULL }; int ret; uint32_t i; const char *dn; char *fmt_str; const char *fmt_attr; char *attr; /* Step 0. Sanity Checks (MS-NSPI Server Processing Rules) */ if (pStat->SortType == SortTypePhoneticDisplayName) { return MAPI_E_CALL_FAILED; } if (((pStat->SortType == SortTypeDisplayName) || (pStat->SortType == SortTypePhoneticDisplayName)) && (pStat->ContainerID && (emsabp_tdb_lookup_MId(emsabp_ctx->tdb_ctx, pStat->ContainerID) == false))) { return MAPI_E_INVALID_BOOKMARK; } if (restriction && (pStat->SortType != SortTypeDisplayName) && (pStat->SortType != SortTypePhoneticDisplayName)) { return MAPI_E_CALL_FAILED; } /* Step 1. Apply restriction and retrieve results from AD */ if (restriction) { /* FIXME: We only support RES_PROPERTY restriction */ if ((uint32_t)restriction->rt != RES_PROPERTY) { return MAPI_E_TOO_COMPLEX; } res_prop = (struct PropertyRestriction_r *)&(restriction->res.resProperty); fmt_attr = emsabp_property_get_attribute(res_prop->ulPropTag); if (fmt_attr == NULL) { return MAPI_E_NO_SUPPORT; } attr = (char *)get_PropertyValue_data(res_prop->lpProp); if (attr == NULL) { return MAPI_E_NO_SUPPORT; } if ((res_prop->ulPropTag & 0xFFFF) == 0x101e) { struct StringArray_r *attr_ml = (struct StringArray_r *) get_PropertyValue_data(res_prop->lpProp); attr = (char *)attr_ml->lppszA[0]; } else { attr = (char *)get_PropertyValue_data(res_prop->lpProp); } if (attr == NULL) { return MAPI_E_NO_SUPPORT; } /* Special case: anr doesn't return correct result with partial search */ if (!strcmp(fmt_attr, "anr")) { fmt_str = talloc_asprintf(mem_ctx, "(&(objectClass=user)(|(%s=%s)(userPrincipalName=%s))(!(objectClass=computer)))", fmt_attr, attr, attr); } else if (!strcmp(fmt_attr, "legacyExchangeDN")) { fmt_str = talloc_asprintf(mem_ctx, "(&(objectClass=user)(|(%s=%s)(%s%s)(anr=%s))(!(objectClass=computer)))", fmt_attr, attr, fmt_attr, attr, attr); } else { fmt_str = talloc_asprintf(mem_ctx, "(&(objectClass=user)(%s=*%s*)(!(objectClass=computer)))", fmt_attr, attr); } } else { fmt_str = talloc_strdup(mem_ctx, "(&(objectClass=user)(displayName=*)(!(objectClass=computer)))"); attr = NULL; } ret = ldb_search(emsabp_ctx->samdb_ctx, emsabp_ctx, &res, ldb_get_default_basedn(emsabp_ctx->samdb_ctx), LDB_SCOPE_SUBTREE, recipient_attrs, fmt_str, attr); talloc_free(fmt_str); if (ret != LDB_SUCCESS) { return MAPI_E_NOT_FOUND; } if (res == NULL) { return MAPI_E_INVALID_OBJECT; } if (!res->count) { return MAPI_E_NOT_FOUND; } if (limit && res->count > limit) { return MAPI_E_TABLE_TOO_BIG; } MIds->aulPropTag = (uint32_t *) talloc_array(mem_ctx, uint32_t, res->count); MIds->cValues = res->count; /* Step 2. Create session MId for all fetched records */ for (i = 0; i < res->count; i++) { dn = ldb_msg_find_attr_as_string(res->msgs[i], "distinguishedName", NULL); retval = emsabp_tdb_fetch_MId(emsabp_ctx->ttdb_ctx, dn, (uint32_t *)&(MIds->aulPropTag[i])); if (retval) { retval = emsabp_tdb_insert(emsabp_ctx->ttdb_ctx, dn); OPENCHANGE_RETVAL_IF(retval, MAPI_E_CORRUPT_STORE, NULL); retval = emsabp_tdb_fetch_MId(emsabp_ctx->ttdb_ctx, dn, (uint32_t *) &(MIds->aulPropTag[i])); OPENCHANGE_RETVAL_IF(retval, MAPI_E_CORRUPT_STORE, NULL); } } return MAPI_E_SUCCESS; } /** \details Search for a given DN within AD and return the associated LDB message. \param emsabp_ctx pointer to the EMSABP context \param dn pointer to the DN string to search for \param ldb_res pointer on pointer to the LDB message returned by the function \return MAPI_E_SUCCESS on success, otherwise MAPI error */ _PUBLIC_ enum MAPISTATUS emsabp_search_dn(struct emsabp_context *emsabp_ctx, const char *dn, struct ldb_message **ldb_res) { struct ldb_dn *ldb_dn = NULL; struct ldb_result *res = NULL; const char * const recipient_attrs[] = { "*", NULL }; int ret; /* Sanity Checks */ OPENCHANGE_RETVAL_IF(!dn, MAPI_E_INVALID_PARAMETER, NULL); OPENCHANGE_RETVAL_IF(!ldb_res, MAPI_E_INVALID_PARAMETER, NULL); ldb_dn = ldb_dn_new(emsabp_ctx->mem_ctx, emsabp_ctx->samdb_ctx, dn); OPENCHANGE_RETVAL_IF(!ldb_dn_validate(ldb_dn), MAPI_E_CORRUPT_STORE, NULL); ret = ldb_search(emsabp_ctx->samdb_ctx, emsabp_ctx->mem_ctx, &res, ldb_dn, LDB_SCOPE_BASE, recipient_attrs, NULL); OPENCHANGE_RETVAL_IF(ret != LDB_SUCCESS || !res->count || res->count != 1, MAPI_E_CORRUPT_STORE, NULL); *ldb_res = res->msgs[0]; return MAPI_E_SUCCESS; } /** \details Search for a given AD record given its legacyDN parameter and return the associated LDB message. \param emsabp_ctx pointer to the EMSABP context \param legacyDN pointer to the legacyDN attribute value to lookup \param ldb_res pointer on pointer to the LDB message returned by the function \param pbUseConfPartition pointer on boolean specifying whether the legacyExchangeDN was retrieved from the Configuration parition or not \return MAPI_E_SUCCESS on success, otherwise MAPI error */ _PUBLIC_ enum MAPISTATUS emsabp_search_legacyExchangeDN(struct emsabp_context *emsabp_ctx, const char *legacyDN, struct ldb_message **ldb_res, bool *pbUseConfPartition) { const char * const recipient_attrs[] = { "*", NULL }; int ret; struct ldb_result *res = NULL; /* Sanity Checks */ OPENCHANGE_RETVAL_IF(!legacyDN, MAPI_E_INVALID_PARAMETER, NULL); OPENCHANGE_RETVAL_IF(!ldb_res, MAPI_E_INVALID_PARAMETER, NULL); OPENCHANGE_RETVAL_IF(!pbUseConfPartition, MAPI_E_INVALID_PARAMETER, NULL); *pbUseConfPartition = true; ret = ldb_search(emsabp_ctx->samdb_ctx, emsabp_ctx->mem_ctx, &res, ldb_get_config_basedn(emsabp_ctx->samdb_ctx), LDB_SCOPE_SUBTREE, recipient_attrs, "(legacyExchangeDN=%s)", legacyDN); if (ret != LDB_SUCCESS || res->count == 0) { *pbUseConfPartition = false; ret = ldb_search(emsabp_ctx->samdb_ctx, emsabp_ctx->mem_ctx, &res, ldb_get_default_basedn(emsabp_ctx->samdb_ctx), LDB_SCOPE_SUBTREE, recipient_attrs, "(legacyExchangeDN=%s)", legacyDN); } OPENCHANGE_RETVAL_IF(ret != LDB_SUCCESS || !res->count, MAPI_E_NOT_FOUND, NULL); *ldb_res = res->msgs[0]; return MAPI_E_SUCCESS; } /** \details Fetch Address Book container record for given ContainerID \param mem_ctx memory context for allocation \param emsabp_ctx pointer to the EMSABP context \param ContainerID id of the container to fetch \param ldb_msg pointer on pointer to the LDB message returned by the function \return MAPI_E_SUCCESS on success, otherwise MAPI_ERROR */ _PUBLIC_ enum MAPISTATUS emsabp_ab_container_by_id(TALLOC_CTX *mem_ctx, struct emsabp_context *emsabp_ctx, uint32_t ContainerID, struct ldb_message **ldb_msg) { int ret; char *dn; const char * const recipient_attrs[] = { "globalAddressList", NULL }; struct ldb_result *res = NULL; if (!ContainerID) { /* if GAL is requested */ ret = ldb_search(emsabp_ctx->samdb_ctx, mem_ctx, &res, ldb_get_config_basedn(emsabp_ctx->samdb_ctx), LDB_SCOPE_SUBTREE, recipient_attrs, "(globalAddressList=*)"); OPENCHANGE_RETVAL_IF(ret != LDB_SUCCESS || !res->count, MAPI_E_CORRUPT_STORE, NULL); /* TODO: If more than one GAL, determine the most appropriate */ dn = (char *) ldb_msg_find_attr_as_string(res->msgs[0], "globalAddressList", NULL); OPENCHANGE_RETVAL_IF(!dn, MAPI_E_CORRUPT_STORE, NULL); } else { /* fetch a container we have already recorded */ ret = emsabp_tdb_fetch_dn_from_MId(mem_ctx, emsabp_ctx->tdb_ctx, ContainerID, &dn); OPENCHANGE_RETVAL_IF(!MAPI_STATUS_IS_OK(ret), MAPI_E_INVALID_BOOKMARK, NULL); } ret = emsabp_search_dn(emsabp_ctx, dn, ldb_msg); OPENCHANGE_RETVAL_IF(!MAPI_STATUS_IS_OK(ret), MAPI_E_CORRUPT_STORE, NULL); return MAPI_E_SUCCESS; } /** \details Enumerate AB container entries \param mem_ctx pointer to the memory context \param emsabp_ctx pointer to the EMSABP context \param ContainerID id of the container to fetch \param ldb_res pointer on pointer to the LDB result returned by the function \return MAPI_E_SUCCESS on success, otherwise MAPI error */ _PUBLIC_ enum MAPISTATUS emsabp_ab_container_enum(TALLOC_CTX *mem_ctx, struct emsabp_context *emsabp_ctx, uint32_t ContainerID, struct ldb_result **ldb_resp) { enum MAPISTATUS retval; int ldb_ret; struct ldb_request *ldb_req; struct ldb_result *ldb_res; struct ldb_message *ldb_msg_ab; const char *purportedSearch; char *expression; const char * const recipient_attrs[] = { "*", NULL }; struct ldb_server_sort_control **ldb_sort_controls; /* Fetch AB container record */ retval = emsabp_ab_container_by_id(mem_ctx, emsabp_ctx, ContainerID, &ldb_msg_ab); OPENCHANGE_RETVAL_IF(!MAPI_STATUS_IS_OK(retval), MAPI_E_INVALID_BOOKMARK, NULL); purportedSearch = ldb_msg_find_attr_as_string(ldb_msg_ab, "purportedSearch", NULL); if (!purportedSearch) { *ldb_resp = talloc_zero(mem_ctx, struct ldb_result); return MAPI_E_SUCCESS; } OPENCHANGE_RETVAL_IF(!purportedSearch, MAPI_E_INVALID_BOOKMARK, NULL); /* Search AD with purportedSearch filter */ ldb_res = talloc_zero(mem_ctx, struct ldb_result); if (!ldb_res) { *ldb_resp = NULL; return MAPI_E_NOT_FOUND; } expression = talloc_asprintf(mem_ctx, "%s", purportedSearch); if (!expression) { talloc_free(ldb_res); return MAPI_E_NOT_FOUND; } ldb_req = NULL; ldb_ret = ldb_build_search_req(&ldb_req, emsabp_ctx->samdb_ctx, mem_ctx, ldb_get_default_basedn(emsabp_ctx->samdb_ctx), LDB_SCOPE_SUBTREE, expression, recipient_attrs, NULL, ldb_res, ldb_search_default_callback, NULL); if (ldb_ret != LDB_SUCCESS) goto done; ldb_sort_controls = talloc_array(expression, struct ldb_server_sort_control *, 2); ldb_sort_controls[0] = talloc(ldb_sort_controls, struct ldb_server_sort_control); ldb_sort_controls[0]->attributeName = talloc_strdup(ldb_sort_controls, "displayName"); ldb_sort_controls[0]->orderingRule = NULL; ldb_sort_controls[0]->reverse = 0; ldb_sort_controls[1] = NULL; ldb_request_add_control(ldb_req, LDB_CONTROL_SERVER_SORT_OID, false, ldb_sort_controls); ldb_ret = ldb_request(emsabp_ctx->samdb_ctx, ldb_req); if (ldb_ret == LDB_SUCCESS) { ldb_ret = ldb_wait(ldb_req->handle, LDB_WAIT_ALL); } done: talloc_free(expression); if (ldb_req) { talloc_free(ldb_req); } if (ldb_ret != LDB_SUCCESS) { talloc_free(ldb_res); ldb_res = NULL; } *ldb_resp = ldb_res; return (ldb_ret != LDB_SUCCESS) ? MAPI_E_NOT_FOUND : MAPI_E_SUCCESS; } openchange-2.0/mapiproxy/servers/default/nspi/emsabp_property.c000066400000000000000000000111451223057412600251630ustar00rootroot00000000000000/* OpenChange Server implementation. EMSABP: Address Book Provider implementation Copyright (C) Julien Kerihuel 2009. This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see . */ /** \file emsabp_property.c \brief Property Tag to AD attributes mapping */ #include "dcesrv_exchange_nsp.h" struct emsabp_property { uint32_t ulPropTag; const char *attribute; bool ref; const char *ref_attr; }; /* MAPI Property tags to AD attributes mapping */ static const struct emsabp_property emsabp_property[] = { { PidTagAnr, "anr", false, NULL }, { PidTagAccount, "sAMAccountName", false, NULL }, { PidTagGivenName, "givenName", false, NULL }, { PidTagSurname, "sn", false, NULL }, { PidTagOriginalDisplayName, "displayName", false, NULL }, { PidTagTransmittableDisplayName, "displayName", false, NULL }, { PidTagPrimarySmtpAddress, "mail", false, NULL }, { PidTag7BitDisplayName, "displayName", false, NULL }, { PR_EMS_AB_HOME_MTA, "homeMTA", true, "legacyExchangeDN" }, { PR_EMS_AB_ASSOC_NT_ACCOUNT, "assocNTAccount", false, NULL }, { PidTagDepartmentName, "department", false, NULL }, { PidTagCompanyName, "company", false, NULL }, { PidTagDisplayName, "displayName", false, NULL }, { PidTagEmailAddress, "legacyExchangeDN", false, NULL }, { PidTagAddressBookHomeMessageDatabase, "homeMDB", true, "legacyExchangeDN" }, { PidTagAddressBookProxyAddresses, "proxyAddresses", false, NULL }, { PidTagAddressBookNetworkAddress, "networkAddress", false, NULL }, { PidTagTitle, "personalTitle", false, NULL }, { PidTagAddressBookObjectGuid, "objectGUID", false, NULL }, { 0, NULL, false, NULL } }; /** \details Return the AD attribute name associated to a property tag \param ulPropTag the property tag to lookup \return valid pointer to the attribute name on success, otherwise NULL */ _PUBLIC_ const char *emsabp_property_get_attribute(uint32_t ulPropTag) { int i; uint32_t uniPropTag; if ((ulPropTag & 0x0fff) == PT_STRING8) { uniPropTag = (ulPropTag & 0xfffff000) | PT_UNICODE; } else { uniPropTag = ulPropTag; } for (i = 0; emsabp_property[i].attribute; i++) { if (uniPropTag == emsabp_property[i].ulPropTag) { return emsabp_property[i].attribute; } } return NULL; } /** \details Return the property tag associated to AD attribute name \param attribute the AD attribute name to lookup \return property tag value on success, otherwise PT_ERROR */ _PUBLIC_ uint32_t emsabp_property_get_ulPropTag(const char *attribute) { int i; if (!attribute) return PT_ERROR; for (i = 0; emsabp_property[i].attribute; i++) { if (!strcmp(attribute, emsabp_property[i].attribute)) { return emsabp_property[i].ulPropTag; } } return PT_ERROR; } /** \details Returns whether the given attribute's value references another AD record \param ulPropTag the property tag to lookup \return 1 if the attribute is a reference, 0 if not and -1 if an error occurred. */ _PUBLIC_ int emsabp_property_is_ref(uint32_t ulPropTag) { int i; uint32_t uniPropTag; if (!ulPropTag) return -1; if ((ulPropTag & 0x0fff) == PT_STRING8) { uniPropTag = (ulPropTag & 0xfffff000) | PT_UNICODE; } else { uniPropTag = ulPropTag; } for (i = 0; emsabp_property[i].attribute; i++) { if (uniPropTag == emsabp_property[i].ulPropTag) { return (emsabp_property[i].ref == true) ? 1 : 0; } } return -1; } /** \details Returns the reference attr for a given attribute \param ulPropTag property tag to lookup \return pointer to a valid reference attribute on success, otherwise NULL */ _PUBLIC_ const char *emsabp_property_get_ref_attr(uint32_t ulPropTag) { int i; uint32_t uniPropTag; if (!ulPropTag) return NULL; if ((ulPropTag & 0x0fff) == PT_STRING8) { uniPropTag = (ulPropTag & 0xfffff000) | PT_UNICODE; } else { uniPropTag = ulPropTag; } for (i = 0; emsabp_property[i].attribute; i++) { if (uniPropTag == emsabp_property[i].ulPropTag) { return emsabp_property[i].ref_attr; } } return NULL; } openchange-2.0/mapiproxy/servers/default/nspi/emsabp_tdb.c000066400000000000000000000241421223057412600240510ustar00rootroot00000000000000/* OpenChange Server implementation. EMSABP: Address Book Provider implementation Copyright (C) Julien Kerihuel 2006-2009. This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see . */ /** \file emsabp_tdb.c \brief EMSABP TDB database API */ #include "mapiproxy/dcesrv_mapiproxy.h" #include "dcesrv_exchange_nsp.h" #include /** \details Structure to be used for MId traversal within TDB */ struct traverse_MId { uint32_t MId; bool found; }; /** \details Open EMSABP TDB database \param mem_ctx pointer to the memory context \param lp_ctx pointer to the loadparm context \return MAPI_E_SUCCESS on success, otherwise MAPI error */ _PUBLIC_ TDB_CONTEXT *emsabp_tdb_init(TALLOC_CTX *mem_ctx, struct loadparm_context *lp_ctx) { enum MAPISTATUS retval; TDB_CONTEXT *tdb_ctx; TDB_DATA key; TDB_DATA dbuf; int ret; /* Sanity checks */ if (!lp_ctx) return NULL; /* Step 0. Retrieve a TDB context pointer on the emsabp_tdb database */ tdb_ctx = mapiproxy_server_emsabp_tdb_init(lp_ctx); if (!tdb_ctx) return NULL; /* Step 1. If EMSABP_TDB_DATA_REC doesn't exist, create it */ retval = emsabp_tdb_fetch(tdb_ctx, EMSABP_TDB_DATA_REC, &dbuf); if (retval == MAPI_E_NOT_FOUND) { key.dptr = (unsigned char *) EMSABP_TDB_DATA_REC; key.dsize = strlen(EMSABP_TDB_DATA_REC); dbuf.dptr = (unsigned char *) talloc_asprintf(mem_ctx, "0x%x", EMSABP_TDB_MID_START); dbuf.dsize = strlen((const char *)dbuf.dptr); ret = tdb_store(tdb_ctx, key, dbuf, TDB_INSERT); if (ret == -1) { DEBUG(3, ("[%s:%d]: Unable to create %s record: %s\n", __FUNCTION__, __LINE__, EMSABP_TDB_DATA_REC, tdb_errorstr(tdb_ctx))); tdb_close(tdb_ctx); return NULL; } } else { free (dbuf.dptr); } return tdb_ctx; } /** \details Initialize a temporary (on-memory) TDB database. This database is used to store temporary MId used within a session lifetime. \param mem_ctx pointer to the memory context \return Allocated TDB context on success, otherwise NULL */ _PUBLIC_ TDB_CONTEXT *emsabp_tdb_init_tmp(TALLOC_CTX *mem_ctx) { TDB_CONTEXT *tdb_ctx; TDB_DATA key; TDB_DATA dbuf; int ret; /* Step 0. Initialize the temporary TDB database */ tdb_ctx = tdb_open(NULL, 0, TDB_INTERNAL, O_RDWR|O_CREAT, 0600); /* Step 1. Create EMSABP_TMP_TDB_DATA_REC record */ key.dptr = (unsigned char *) EMSABP_TDB_DATA_REC; key.dsize = strlen(EMSABP_TDB_DATA_REC); dbuf.dptr = (unsigned char *) talloc_asprintf(mem_ctx, "0x%x", EMSABP_TDB_TMP_MID_START); dbuf.dsize = strlen((const char *)dbuf.dptr); ret = tdb_store(tdb_ctx, key, dbuf, TDB_INSERT); if (ret == -1) { DEBUG(3, ("[%s:%d]: Unable to create %s record: %s\n", __FUNCTION__, __LINE__, EMSABP_TDB_DATA_REC, tdb_errorstr(tdb_ctx))); tdb_close(tdb_ctx); return NULL; } return tdb_ctx; } /** \details Close EMSABP TDB database \return MAPI_E_SUCCESS on success, otherwise MAPI_E_INVALID_PARAMETER */ _PUBLIC_ enum MAPISTATUS emsabp_tdb_close(TDB_CONTEXT *tdb_ctx) { /* Sanity checks */ OPENCHANGE_RETVAL_IF(!tdb_ctx, MAPI_E_INVALID_PARAMETER, NULL); tdb_close(tdb_ctx); DEBUG(0, ("TDB database closed\n")); return MAPI_E_SUCCESS; } /** \details Fetch an element within a TDB database given its key \param tdb_ctx pointer to the EMSABP TDB context \param keyname pointer to the TDB key to fetch \param result pointer on TDB results \return MAPI_E_SUCCESS on success, otherwise MAPI_E_NOT_FOUND */ _PUBLIC_ enum MAPISTATUS emsabp_tdb_fetch(TDB_CONTEXT *tdb_ctx, const char *keyname, TDB_DATA *result) { TDB_DATA key; TDB_DATA dbuf; size_t keylen; /* Sanity checks */ OPENCHANGE_RETVAL_IF(!tdb_ctx, MAPI_E_NOT_INITIALIZED, NULL); OPENCHANGE_RETVAL_IF(!keyname, MAPI_E_INVALID_PARAMETER, NULL); keylen = strlen(keyname); OPENCHANGE_RETVAL_IF(!keylen, MAPI_E_INVALID_PARAMETER, NULL); key.dptr = (unsigned char *)keyname; key.dsize = keylen; dbuf = tdb_fetch(tdb_ctx, key); OPENCHANGE_RETVAL_IF(!dbuf.dptr, MAPI_E_NOT_FOUND, NULL); OPENCHANGE_RETVAL_IF(!dbuf.dsize, MAPI_E_NOT_FOUND, NULL); if (!result) { free (dbuf.dptr); } else { *result = dbuf; } return MAPI_E_SUCCESS; } /** \details Retrieve the Minimal EntryID associated to a given DN \param tdb_ctx pointer to the EMSABP TDB context \param keyname pointer to the TDB key to search for \param MId pointer on the integer the function returns \return MAPI_E_SUCCESS on success, otherwise MAPI error */ _PUBLIC_ enum MAPISTATUS emsabp_tdb_fetch_MId(TDB_CONTEXT *tdb_ctx, const char *keyname, uint32_t *MId) { TALLOC_CTX *mem_ctx; TDB_DATA key; TDB_DATA dbuf; char *str; /* Sanity checks */ OPENCHANGE_RETVAL_IF(!tdb_ctx, MAPI_E_NOT_INITIALIZED, NULL); OPENCHANGE_RETVAL_IF(!keyname, MAPI_E_INVALID_PARAMETER, NULL); OPENCHANGE_RETVAL_IF(!MId, MAPI_E_INVALID_PARAMETER, NULL); key.dptr = (unsigned char *) keyname; key.dsize = strlen(keyname); dbuf = tdb_fetch(tdb_ctx, key); OPENCHANGE_RETVAL_IF(!dbuf.dptr, MAPI_E_NOT_FOUND, NULL); OPENCHANGE_RETVAL_IF(!dbuf.dsize, MAPI_E_NOT_FOUND, NULL); mem_ctx = talloc_named(NULL, 0, "emsabp_tdb_fetch_MId"); str = talloc_strndup(mem_ctx, (char *)dbuf.dptr, dbuf.dsize); *MId = strtol((const char *)str, NULL, 16); talloc_free(mem_ctx); free(dbuf.dptr); return MAPI_E_SUCCESS; } static int emsabp_tdb_traverse_MId(TDB_CONTEXT *tdb_ctx, TDB_DATA key, TDB_DATA dbuf, void *state) { TALLOC_CTX *mem_ctx; uint32_t value; char *value_str = NULL; struct traverse_MId *mid_trav = (struct traverse_MId *) state; mem_ctx = talloc_named(NULL, 0, "emsabp_tdb_traverse_MId"); value_str = talloc_strndup(mem_ctx, (char *)dbuf.dptr, dbuf.dsize); value = strtol((const char *)value_str, NULL, 16); talloc_free(mem_ctx); if (value == mid_trav->MId) { mid_trav->found = true; return 1; } return 0; } /** \details Traverse the EMSABP TDB database and look for the input MId \param tdb_ctx pointer to the EMSABP TDB context \param MId MID to lookup \return true on success, otherwise false */ _PUBLIC_ bool emsabp_tdb_lookup_MId(TDB_CONTEXT *tdb_ctx, uint32_t MId) { int ret; struct traverse_MId mid_trav = { MId, false }; ret = tdb_traverse(tdb_ctx, emsabp_tdb_traverse_MId, (void *)&mid_trav); return (ret > 0) && mid_trav.found; } static int emsabp_tdb_traverse_MId_DN(TDB_CONTEXT *tdb_ctx, TDB_DATA key, TDB_DATA dbuf, void *state) { char *MId; uint32_t value; struct emsabp_MId *emsabp_MId = (struct emsabp_MId *) state; if (key.dptr) { if (!strncmp((const char *)key.dptr, "CN=", 3)) { MId = talloc_strndup(emsabp_MId, (char *)dbuf.dptr, dbuf.dsize); value = strtol((const char *)MId, NULL, 16); talloc_free(MId); if (value == emsabp_MId->MId) { emsabp_MId->dn = talloc_strndup(emsabp_MId, (char *)key.dptr, key.dsize); return 1; } } } return 0; } /** \details Traverse the EMSABP TDB and fetch the DN associated with the MId \param mem_ctx pointer to the memory context \param tdb_ctx pointer to the EMSABP TDB context \param MId MID to search \param dn pointer on pointer to the dn to return \return MAPI_E_SUCCESS on success, otherwise false */ _PUBLIC_ enum MAPISTATUS emsabp_tdb_fetch_dn_from_MId(TALLOC_CTX *mem_ctx, TDB_CONTEXT *tdb_ctx, uint32_t MId, char **dn) { int ret; struct emsabp_MId *emsabp_MId; emsabp_MId = talloc_zero(mem_ctx, struct emsabp_MId); emsabp_MId->dn = NULL; emsabp_MId->MId = MId; ret = tdb_traverse(tdb_ctx, emsabp_tdb_traverse_MId_DN, (void *)emsabp_MId); if (ret > -1 && emsabp_MId->dn) { *dn = talloc_strdup(mem_ctx, emsabp_MId->dn); talloc_free(emsabp_MId); return MAPI_E_SUCCESS; } *dn = NULL; talloc_free(emsabp_MId); return MAPI_E_NOT_FOUND; } /** \details Insert an element into TDB database \param tdb_ctx pointer to the EMSABP TDB context \param keyname pointer to the TDB key name string \return MAPI_E_SUCCESS on success, otherwise MAPI error */ _PUBLIC_ enum MAPISTATUS emsabp_tdb_insert(TDB_CONTEXT *tdb_ctx, const char *keyname) { enum MAPISTATUS retval; TALLOC_CTX *mem_ctx; TDB_DATA key; TDB_DATA dbuf; char *str; int index; int ret; /* Sanity checks */ OPENCHANGE_RETVAL_IF(!tdb_ctx, MAPI_E_NOT_INITIALIZED, NULL); OPENCHANGE_RETVAL_IF(!keyname, MAPI_E_INVALID_PARAMETER, NULL); mem_ctx = talloc_named(NULL, 0, "emsabp_tdb_insert"); OPENCHANGE_RETVAL_IF(!mem_ctx, MAPI_E_NOT_ENOUGH_RESOURCES, NULL); /* Step 1. Check if the record already exists */ retval = emsabp_tdb_fetch(tdb_ctx, keyname, &dbuf); OPENCHANGE_RETVAL_IF(!retval, ecExiting, mem_ctx); /* Step 2. Retrieve the latest TDB data value inserted */ retval = emsabp_tdb_fetch(tdb_ctx, EMSABP_TDB_DATA_REC, &dbuf); OPENCHANGE_RETVAL_IF(retval, retval, mem_ctx); str = talloc_strndup(mem_ctx, (char *)dbuf.dptr, dbuf.dsize); index = strtol(str, NULL, 16); index += 1; talloc_free(str); free(dbuf.dptr); dbuf.dptr = (unsigned char *)talloc_asprintf(mem_ctx, "0x%x", index); dbuf.dsize = strlen((const char *)dbuf.dptr); /* Step 3. Insert the new record */ key.dptr = (unsigned char *)keyname; key.dsize = strlen(keyname); ret = tdb_store(tdb_ctx, key, dbuf, TDB_INSERT); OPENCHANGE_RETVAL_IF(ret == -1, MAPI_E_CORRUPT_STORE, mem_ctx); /* Step 4. Update Data record */ key.dptr = (unsigned char *) EMSABP_TDB_DATA_REC; key.dsize = strlen((const char *)key.dptr); ret = tdb_store(tdb_ctx, key, dbuf, TDB_MODIFY); OPENCHANGE_RETVAL_IF(ret == -1, MAPI_E_CORRUPT_STORE, mem_ctx); talloc_free(mem_ctx); return MAPI_E_SUCCESS; } openchange-2.0/mapiproxy/servers/default/rfr/000077500000000000000000000000001223057412600214225ustar00rootroot00000000000000openchange-2.0/mapiproxy/servers/default/rfr/dcesrv_exchange_ds_rfr.c000066400000000000000000000145061223057412600262630ustar00rootroot00000000000000/* MAPI Proxy - Exchange RFR Server OpenChange Project Copyright (C) Julien Kerihuel 2009 This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see . */ /** \file dcesrv_exchange_ds_rfr.c \brief OpenChange RFR Server implementation */ #include "mapiproxy/dcesrv_mapiproxy.h" #include "dcesrv_exchange_ds_rfr.h" /** \details exchange_ds_rfr RfrGetNewDSA (0x0) function \param dce_call pointer to the session context \param mem_ctx pointer to the memory context \param r pointer to the RfrGetNewDSA request data \note We incorrectly assume input pUserDN is correct and available, but it is OK for now. \return MAPI_E_SUCCESS on success */ static enum MAPISTATUS dcesrv_RfrGetNewDSA(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx, struct RfrGetNewDSA *r) { const char *netbiosname = NULL; const char *realm = NULL; char *fqdn = NULL; DEBUG(5, ("exchange_ds_rfr: RfrGetNewDSA (0x0)\n")); /* Step 0. Ensure incoming user is authenticated */ if (!dcesrv_call_authenticated(dce_call)) { DEBUG(1, ("No challenge requested by client, cannot authenticate\n")); r->out.ppszUnused = NULL; r->out.ppszServer = NULL; r->out.result = MAPI_E_LOGON_FAILED; return MAPI_E_LOGON_FAILED; } /* Step 1. We don't have load-balancing support yet, just return Samba FQDN name */ netbiosname = lpcfg_netbios_name(dce_call->conn->dce_ctx->lp_ctx); realm = lpcfg_realm(dce_call->conn->dce_ctx->lp_ctx); if (!netbiosname || !realm) { r->out.ppszUnused = NULL; r->out.ppszServer = NULL; r->out.result = MAPI_E_NO_SUPPORT; return MAPI_E_NO_SUPPORT; } fqdn = talloc_asprintf(mem_ctx, "%s.%s", netbiosname, realm); r->out.ppszUnused = NULL; r->out.ppszServer = talloc_array(mem_ctx, const char *, 2); r->out.ppszServer[0] = strlower_talloc(mem_ctx, fqdn); r->out.ppszServer[1] = NULL; r->out.result = MAPI_E_SUCCESS; return MAPI_E_SUCCESS; } /** \details exchange_ds_rrf RfrGetFQDNFromLegacyDN (0x1) function \param dce_call pointer to the session context \param mem_ctx pointer to the memory context \param r pointer to the RfrGetFQDNFromLegacyDN request data \return MAPI_E_SUCCESS on success */ static enum MAPISTATUS dcesrv_RfrGetFQDNFromLegacyDN(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx, struct RfrGetFQDNFromLegacyDN *r) { char *fqdn; const char *netbiosname = NULL; const char *realm = NULL; DEBUG(3, ("exchange_ds_rfr: RfrGetFQDNFromLegacyDN (0x1)\n")); if (!dcesrv_call_authenticated(dce_call)) { DEBUG(1, ("No challenge requested by client, cannot authenticate\n")); failure: r->out.ppszServerFQDN = talloc_array(mem_ctx, const char *, 2); r->out.ppszServerFQDN[0] = NULL; r->out.result = MAPI_E_LOGON_FAILED; return MAPI_E_LOGON_FAILED; } netbiosname = lpcfg_netbios_name(dce_call->conn->dce_ctx->lp_ctx); realm = lpcfg_realm(dce_call->conn->dce_ctx->lp_ctx); if (!netbiosname || !realm) { goto failure; } fqdn = talloc_asprintf(mem_ctx, "%s.%s", netbiosname, realm); r->out.ppszServerFQDN = talloc_array(mem_ctx, const char *, 2); r->out.ppszServerFQDN[0] = strlower_talloc(mem_ctx, fqdn); talloc_free(fqdn); r->out.result = MAPI_E_SUCCESS; return MAPI_E_SUCCESS; } /** \details Dispatch incoming RFR call to the correct OpenChange server function \param dce_call pointer to the session context \param mem_ctx pointer to the memory context \param r generic pointer on RFR data \param mapiproxy pointer to the mapiproxy structure controlling mapiproxy behavior \return NT_STATUS_OK */ static NTSTATUS dcesrv_exchange_ds_rfr_dispatch(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx, void *r, struct mapiproxy *mapiproxy) { const struct ndr_interface_table *table; uint16_t opnum; table = (const struct ndr_interface_table *) dce_call->context->iface->private_data; opnum = dce_call->pkt.u.request.opnum; /* Sanity checks */ if (!table) return NT_STATUS_UNSUCCESSFUL; if (table->name && strcmp(table->name, NDR_EXCHANGE_DS_RFR_NAME)) return NT_STATUS_UNSUCCESSFUL; switch (opnum) { case NDR_RFRGETNEWDSA: dcesrv_RfrGetNewDSA(dce_call, mem_ctx, (struct RfrGetNewDSA *)r); break; case NDR_RFRGETFQDNFROMLEGACYDN: dcesrv_RfrGetFQDNFromLegacyDN(dce_call, mem_ctx, (struct RfrGetFQDNFromLegacyDN *)r); break; } return NT_STATUS_OK; } /** \details Initialize the RFR OpenChange server \param dce_ctx pointer to the server context \return NT_STATUS_OK on success */ static NTSTATUS dcesrv_exchange_ds_rfr_init(struct dcesrv_context *dce_ctx) { return NT_STATUS_OK; } /** \details Terminate the RFR connection \param server_id reference to the server identifier structure \param context_id the connection context identifier \return NT_STATUS_OK on success */ static NTSTATUS dcesrv_exchange_ds_rfr_unbind(struct server_id server_id, uint32_t context_id) { return NT_STATUS_OK; } /** \details Entry point for the default OpenChange RFR server \return NT_STATUS_OK on success, otherwise NTSTATUS error */ NTSTATUS samba_init_module(void) { struct mapiproxy_module server; NTSTATUS ret; /* Fill in our name */ server.name = "exchange_ds_rfr"; server.status = MAPIPROXY_DEFAULT; server.description = "OpenChange RFR server"; server.endpoint = "exchange_ds_rfr"; /* Fill in all the operations */ server.init = dcesrv_exchange_ds_rfr_init; server.unbind = dcesrv_exchange_ds_rfr_unbind; server.dispatch = dcesrv_exchange_ds_rfr_dispatch; server.push = NULL; server.pull = NULL; server.ndr_pull = NULL; /* Register ourselves with the MAPIPROXY server subsystem */ ret = mapiproxy_server_register(&server); if (!NT_STATUS_IS_OK(ret)) { DEBUG(0, ("Failed to register the 'exchange_ds_rfr' default mapiproxy server!\n")); return ret; } return ret; } openchange-2.0/mapiproxy/servers/default/rfr/dcesrv_exchange_ds_rfr.h000066400000000000000000000022161223057412600262630ustar00rootroot00000000000000/* MAPI Proxy - Exchange RFR Server OpenChange Project Copyright (C) Julien Kerihuel 2009 This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see . */ #ifndef __DCESRV_EXCHANGE_DS_RFR_H #define __DCESRV_EXCHANGE_DS_RFR_H #include "mapiproxy/libmapiproxy/libmapiproxy.h" #include #ifndef __BEGIN_DECLS #ifdef __cplusplus #define __BEGIN_DECLS extern "C" { #define __END_DECLS } #else #define __BEGIN_DECLS #define __END_DECLS #endif #endif __BEGIN_DECLS NTSTATUS samba_init_module(void); __END_DECLS #endif /* __DCESRV_EXCHANGE_DS_RFR_H */ openchange-2.0/mapiproxy/services/000077500000000000000000000000001223057412600173375ustar00rootroot00000000000000openchange-2.0/mapiproxy/services/client/000077500000000000000000000000001223057412600206155ustar00rootroot00000000000000openchange-2.0/mapiproxy/services/client/OCSManager/000077500000000000000000000000001223057412600225345ustar00rootroot00000000000000openchange-2.0/mapiproxy/services/client/OCSManager/ClientAuthentication.py000066400000000000000000000066651223057412600272410ustar00rootroot00000000000000#!/usr/bin/python import os import hashlib from lxml import etree from base64 import urlsafe_b64encode as encode from base64 import urlsafe_b64decode as decode """ OCSManager Client Authentication documentation """ class ClientAuthentication(object): """Authentication class documentation. Prepare XML request payloads and analyze response payloads. """ def __init__(self): self.username = None self.password = None self.salt = None def _check_document(self, payload): """Perform common preliminary XML checks on payload and return lxml object.""" try: xmlData = etree.XML(payload) except etree.XMLSyntaxError: return (True, 'Invalid document') if xmlData.tag != "ocsmanager": return (True, 'Incorrect root element %s' % xmlData.tag) return (False, xmlData) def setTokenPayload(self, login=None): """Prepare the payload for token authentication phase. """ root = etree.Element('ocsmanager') login_element = etree.SubElement(root, "login") login_element.text = login return etree.tostring(root, xml_declaration=True, encoding="utf-8") def getTokenPayload(self, payload=None): """Extract content from the token payload returned by the server. """ (error, xmlData) = self._check_document(payload) if error is True: return (error, xmlData) d = {} token = xmlData.find('token') if token is None: return (True, 'No token parameter received') if not 'type' in token.attrib: return (True, 'No type attribute in token parameter') if token.attrib['type'] != 'salt': return (True, 'Expected type=salt for attribute, got type=%s' % token.attrib['type']) d["token"] = token.text salt = xmlData.find('salt') if salt is None: return (True, 'No salt parameter received') d["salt"] = salt.text ttl = xmlData.find('ttl') if ttl is None: return (True, 'No TTL parameter received') d["ttl"] = int(ttl.text) return (False, d) def getTokenLogin(self, payload=None): """Extract token login from login response payload. """ (error, xmlData) = self._check_document(payload) if error is True: return (error, xmlData) token = xmlData.find('token') if token is None: return (True, 'No token parameter received') if token.text is None: return (True, 'Empty token received') return (False, token.text) def setLoginPayload(self, d=None): """Prepare the payload for the login authentication stage. """ salt = decode(d["salt"]) salt_token = decode(d["token"]) if d["encryption"] == "plain": h = hashlib.sha1(d['password']) h.update(salt) sshaPassword = "{SSHA}" + encode(h.digest() + salt) elif d["encryption"] == "ssha": sshaPassword = d['password'] else: return (True, 'Unsupported encryption scheme: %s' % d["encryption"]) payload = "%s:%s:%s" % (d["username"], sshaPassword, salt_token) h = hashlib.sha1(payload) h.update(salt_token) token = h.hexdigest() root = etree.Element('ocsmanager') token_element = etree.SubElement(root, 'token') token_element.text = token return (False, etree.tostring(root, xml_declaration=True, encoding="utf-8")) openchange-2.0/mapiproxy/services/client/OCSManager/ClientNotification.py000066400000000000000000000031511223057412600266730ustar00rootroot00000000000000#!/usr/bin/python import os from lxml import etree """ OCSManager Client Notification documentation """ class ClientNotification(object): """Client Notification class documentation. Prepare XML request payloads and analyze response payloads. """ def __init__(self): return None def setNewMailPayload(self, tokenLogin=None, newmail=None): """Prepare newmail payload. """ if tokenLogin is None: return (True, 'User not authenticated') if newmail is None: return (True, 'Missing newmail arguments') # Sanity checks on newmail dictionary if not "backend" in newmail: return (True, 'Missing backend parameter') if not "username" in newmail: return (True, 'Missing username parameter') if not "folder" in newmail: return (True, 'Missing folder parameter') if not "msgid" in newmail: return (True, 'Missing msgid parameter') root = etree.Element('ocsmanager') token = etree.SubElement(root, "token") token.text = tokenLogin notification = etree.SubElement(root, "notification", category="newmail") backend = etree.SubElement(notification, "backend") backend.text = newmail['backend'] username = etree.SubElement(notification, "username") username.text = newmail['username'] folder = etree.SubElement(notification, "folder") folder.text = newmail['folder'] messageID = etree.SubElement(notification, "messageID") messageID.text = newmail['msgid'] return (False, etree.tostring(root, xml_declaration=True, encoding="utf-8")) openchange-2.0/mapiproxy/services/client/OCSManager/Network.py000066400000000000000000000143541223057412600245460ustar00rootroot00000000000000#!/usr/bin/python import os import tempfile import StringIO import pycurl import urllib from lxml import etree from OCSManager import ClientAuthentication from OCSManager import ClientNotification """ OCSManager Network documentation """ class Network(object): """Network class documentation. Perform authentication and network operation on OpenChange Service Manager. """ def __init__(self, host=None, port=None, verbose=False): """Initialize OCSManager Network instance. """ if host is None: return None if port is None: return None self.auth = ClientAuthentication.ClientAuthentication() self.curl = pycurl.Curl() self.host = host self.port = port self.verbose = verbose self.token = None self.base_uri = 'http://%s:%s' % (host, port) (self.fp,self.cookie) = tempfile.mkstemp() def __del__(self): self.curl.close() def __make_url(self, service=None): """Generate the URL to connect to.""" if service is None: return None return "%s/%s" % (self.base_uri, service) def __get_error(self, data): """Retrieve error code and associated string if available. """ if data is None: return (None, None) try: dataXML = etree.XML(data) except etree.XMLSyntaxError: return (None, None) error = dataXML.find('error') if error is None: return (None, None) if not "code" in error.attrib: return (None, None) if error.text is None: return (None, None) code = error.attrib["code"] string = error.text return (code, string) def __make_request(self, url=None, postfields=None, headers=None, data=None): """Build common part of the PyCurl request. """ if data is None: return (True, 'Invalid StringIO buffer') if url is None: return (True, 'Missing URL') if self.verbose is True: print postfields self.curl.setopt(pycurl.URL, url) if headers is not None: self.curl.setopt(pycurl.HTTPHEADER, headers) else: self.curl.setopt(pycurl.HTTPHEADER, ['Content-Type: text/xml']) self.curl.setopt(pycurl.FOLLOWLOCATION, 1) self.curl.setopt(pycurl.COOKIEFILE, self.cookie) self.curl.setopt(pycurl.COOKIEJAR, self.cookie) self.curl.setopt(pycurl.WRITEFUNCTION, data.write) self.curl.setopt(pycurl.VERBOSE, self.verbose) return (False, None) def __exec_request(self, data=None): """Execute the request and perform HTTP error code and error XML payload sanity checks. Return response payload on success""" try: self.curl.perform() except pycurl.error, e: return (True, "(code=%s): %s" % (e.args[0], e.args[1])) if self.verbose is True: print data.getvalue() if self.curl.getinfo(self.curl.HTTP_CODE) != 200: return (True, self.curl.getinfo(self.curl.HTTP_CODE)) (code, string) = self.__get_error(data.getvalue()) if code is not None and int(code) != 200: return (True, "[%s]: %s" % (code, string)) return (False, data.getvalue()) def __put(self, url=None, postfields=None, headers=None): """Make a HTTP PUT request. """ if postfields is None: return (True, 'Empty PUT payload') data = StringIO.StringIO() (error, msg) = self.__make_request(url, postfields, headers, data) if error is True: return (error, msg) self.curl.setopt(pycurl.PUT, 1) self.curl.setopt(pycurl.INFILESIZE, len(postfields)) self.curl.setopt(pycurl.READFUNCTION, StringIO.StringIO(postfields).read) return self.__exec_request(data) def __post(self, url=None, postfields=None, headers=None): """Make a HTTP POST request. """ if postfields is None: return (True, 'Empty POST payload') data = StringIO.StringIO() (error, msg) = self.__make_request(url, postfields, headers, data) if error is True: return (error, msg) self.curl.setopt(pycurl.POSTFIELDS, postfields) self.curl.setopt(pycurl.POST, 1) return self.__exec_request(data) def __login_token(self, login): """First stage of the authentication process. """ postfields = self.auth.setTokenPayload(login) url = self.__make_url('authenticate/token') return self.__post(url, postfields, None) def __login(self, d): """Second stage of the authentication process. """ (error, payload) = self.auth.setLoginPayload(d) if error is True: return (error, payload) url = self.__make_url('authenticate/login') return self.__post(url, payload, None) def login(self, username=None, password=None, encryption=None): """Log onto OCSManager service. Returns (False, None) tupple on success, otherwise (True, reason) """ if username is None: return (True, 'Missing username parameter') if password is None: return (True, 'Missing password parameter') if encryption is None: return (True, 'Missing encryption parameter') (error, data) = self.__login_token(username) if error is True: return (error, data) # Retrieve parameters from reply (error, d) = self.auth.getTokenPayload(data) if error is True: return (error, d) d["username"] = username d["password"] = password d["encryption"] = encryption (error, data) = self.__login(d) if error is True: return (error, data) (error,tokenLogin) = self.auth.getTokenLogin(data) if error is True: return (error, data) self.token = tokenLogin return (False, None) def newmail(self, newmail): """Sends a newmail notification to OCSManager service. """ if self.token is None: return (True, 'User not authenticated') notif = ClientNotification.ClientNotification() (error, payload) = notif.setNewMailPayload(self.token, newmail) if error is True: return (error, payload) url = self.__make_url('notification/newmail') return self.__put(url, payload, None) openchange-2.0/mapiproxy/services/client/OCSManager/__init__.py000066400000000000000000000000001223057412600246330ustar00rootroot00000000000000openchange-2.0/mapiproxy/services/client/newmail.py000077500000000000000000000100241223057412600226230ustar00rootroot00000000000000#!/usr/bin/python import os,sys import argparse import ConfigParser from OCSManager import Network def parse_config_file(filename): """Parse configuration file.""" cfg = {'username': None, 'password': None, 'encryption': None, 'host': None, 'port': None} if filename is None: return cfg config = ConfigParser.ConfigParser() try: config.read(filename) except ConfigParser.MissingSectionHeaderError: print '[!] Invalid configuration file: %s' % filename sys.exit() if config.has_section('Config') is False: print '[!] Missing Config section' sys.exit() if config.has_option('Config', 'username'): cfg['username'] = config.get('Config', 'username') if config.has_option('Config', 'password'): cfg['password'] = config.get('Config', 'password') if config.has_option('Config', 'host'): cfg['host'] = config.get('Config', 'host') if config.has_option('Config', 'port'): cfg['port'] = config.getint('Config', 'port') # Sanity checks on options return cfg def parse_error(arg): print '[!] Missing %s argument' % arg sys.exit() def parse_arguments(): """Parse command line arguments.""" parser = argparse.ArgumentParser(description='New Mail notification sender for OCSManager service.', epilog="Written by Julien Kerihuel ") parser.add_argument('--config', action='store', help='Path to the newmail configuration file') parser.add_argument('--username', action='store', help='Specify the username for the service') parser.add_argument('--password', action='store', help='Specify the password for the service') parser.add_argument('--host', action='store', help='Specify the host running the service') parser.add_argument('--port', action='store', type=int, help='Specify the port where the service is running') parser.add_argument('--backend', action='store', required=True, help='Specify the backend that will handle this notification') parser.add_argument('--user', action='store', required=True, help='Specify the destination user for this notification') parser.add_argument('--folder', action='store', required=True, help='Specify the destination folder for this notification') parser.add_argument('--msgid', action='store', required=True, help='Specify the message identifier for this notification') parser.add_argument('--verbose', action='store_true', help='Enable verbosity on network transactions') args = parser.parse_args() cfg = parse_config_file(args.config) # Override config parameters if supplied on command line if args.username is not None: cfg['username'] = args.username if args.password is not None: cfg['password'] = args.password if args.host is not None: cfg['host'] = args.host if args.port is not None: cfg['port'] = args.port cfg['verbose'] = args.verbose # Preliminary sanity checks on parameters if cfg['username'] is None: parse_error('username') if cfg['password'] is None: parse_error('password') if cfg['host'] is None: parse_error('host') if cfg['port'] is None: parse_error('port') if cfg['password'].startswith('{SSHA}'): cfg['encryption'] = "ssha" else: print '[I] Assuming plain password' cfg['encryption'] = "plain" # Retrieve nemail notification parameters cfg['newmail'] = {} cfg['newmail']['backend'] = args.backend cfg['newmail']['username'] = args.user cfg['newmail']['folder'] = args.folder cfg['newmail']['msgid'] = args.msgid return cfg def error_check(function): (error, code) = function if error is True: print '[!] Error: %s' % code sys.exit() def main(): cfg = parse_arguments() conn = Network.Network(cfg['host'], cfg['port'], cfg['verbose']) error_check(conn.login(cfg['username'], cfg['password'], cfg['encryption'])) print '[I] Authentication successful' error_check(conn.newmail(cfg['newmail'])) print '[I] NewMail notification sent' if __name__ == "__main__": main() openchange-2.0/mapiproxy/services/client/ocsmanager.cfg000066400000000000000000000001571223057412600234200ustar00rootroot00000000000000[Config] username = openchange password = {SSHA}I6Hy5Wv0wuxyXvMBFWFQDVVN12_CLaX9 host = 127.0.0.1 port = 5000 openchange-2.0/mapiproxy/services/ocsmanager/000077500000000000000000000000001223057412600214565ustar00rootroot00000000000000openchange-2.0/mapiproxy/services/ocsmanager/MANIFEST.in000066400000000000000000000001751223057412600232170ustar00rootroot00000000000000include ocsmanager/config/deployment.ini_tmpl recursive-include ocsmanager/public * recursive-include ocsmanager/templates * openchange-2.0/mapiproxy/services/ocsmanager/README.txt000066400000000000000000000007171223057412600231610ustar00rootroot00000000000000This file is for you to describe the ocsmanager application. Typically you would include information such as the information below: Installation and Setup ====================== Install ``ocsmanager`` using easy_install:: easy_install ocsmanager Make a config file as follows:: paster make-config ocsmanager config.ini Tweak the config file as appropriate and then setup the application:: paster setup-app config.ini Then you are ready to go. openchange-2.0/mapiproxy/services/ocsmanager/development.ini000066400000000000000000000035051223057412600245040ustar00rootroot00000000000000# # ocsmanager - Pylons development environment configuration # # The %(here)s variable will be replaced with the parent directory of this file # [DEFAULT] debug = true # Uncomment and replace with the address which should receive any error reports #email_to = you@yourdomain.com smtp_server = localhost error_email_from = paste@localhost [server:main] use = egg:Paste#http host = 127.0.0.1 port = 5000 [perso:test] app = clear [app:main] use = egg:ocsmanager full_stack = true static_files = true cache_dir = %(here)s/data beaker.session.key = ocsmanager beaker.session.secret = somesecret # If you'd like to fine-tune the individual locations of the cache data dirs # for the Cache data, or the Session saves, un-comment the desired settings # here: #beaker.cache.data_dir = %(here)s/data/cache #beaker.session.data_dir = %(here)s/data/sessions # WARNING: *THE LINE BELOW MUST BE UNCOMMENTED ON A PRODUCTION ENVIRONMENT* # Debug mode will enable the interactive debugging tool, allowing ANYONE to # execute malicious code after an exception is raised. #set debug = false # override OCSManager authentication scheme. Possible values for auth # are: #auth = ldap auth = config # Logging configuration [loggers] keys = root, routes, ocsmanager, rpclib [handlers] keys = console [formatters] keys = generic [logger_root] level = INFO handlers = console [logger_routes] level = INFO handlers = qualname = routes.middleware # "level = DEBUG" logs the route matched and routing variables. [logger_ocsmanager] level = DEBUG handlers = qualname = ocsmanager [logger_rpclib] level = NOTSET handlers = console qualname = rpclib [handler_console] class = StreamHandler args = (sys.stderr,) level = NOTSET formatter = generic [formatter_generic] format = %(asctime)s,%(msecs)03d %(levelname)-5.5s [%(name)s] [%(threadName)s] %(message)s datefmt = %H:%M:%S openchange-2.0/mapiproxy/services/ocsmanager/docs/000077500000000000000000000000001223057412600224065ustar00rootroot00000000000000openchange-2.0/mapiproxy/services/ocsmanager/docs/index.txt000066400000000000000000000011671223057412600242630ustar00rootroot00000000000000ocsmanager ++++++++++ This is the main index page of your documentation. It should be written in `reStructuredText format `_. You can generate your documentation in HTML format by running this command:: setup.py pudge For this to work you will need to download and install `buildutils`_, `pudge`_, and `pygments`_. The ``pudge`` command is disabled by default; to ativate it in your project, run:: setup.py addcommand -p buildutils.pudge_command .. _buildutils: http://pypi.python.org/pypi/buildutils .. _pudge: http://pudge.lesscode.org/ .. _pygments: http://pygments.org/ openchange-2.0/mapiproxy/services/ocsmanager/ez_setup.py000066400000000000000000000227641223057412600237010ustar00rootroot00000000000000#!python """Bootstrap setuptools installation If you want to use setuptools in your package's setup.py, just include this file in the same directory with it, and add this to the top of your setup.py:: from ez_setup import use_setuptools use_setuptools() If you want to require a specific version of setuptools, set a download mirror, or use an alternate download directory, you can do so by supplying the appropriate options to ``use_setuptools()``. This file can also be run as a script to install or upgrade setuptools. """ import sys DEFAULT_VERSION = "0.6c9" DEFAULT_URL = "http://pypi.python.org/packages/%s/s/setuptools/" % sys.version[:3] md5_data = { 'setuptools-0.6b1-py2.3.egg': '8822caf901250d848b996b7f25c6e6ca', 'setuptools-0.6b1-py2.4.egg': 'b79a8a403e4502fbb85ee3f1941735cb', 'setuptools-0.6b2-py2.3.egg': '5657759d8a6d8fc44070a9d07272d99b', 'setuptools-0.6b2-py2.4.egg': '4996a8d169d2be661fa32a6e52e4f82a', 'setuptools-0.6b3-py2.3.egg': 'bb31c0fc7399a63579975cad9f5a0618', 'setuptools-0.6b3-py2.4.egg': '38a8c6b3d6ecd22247f179f7da669fac', 'setuptools-0.6b4-py2.3.egg': '62045a24ed4e1ebc77fe039aa4e6f7e5', 'setuptools-0.6b4-py2.4.egg': '4cb2a185d228dacffb2d17f103b3b1c4', 'setuptools-0.6c1-py2.3.egg': 'b3f2b5539d65cb7f74ad79127f1a908c', 'setuptools-0.6c1-py2.4.egg': 'b45adeda0667d2d2ffe14009364f2a4b', 'setuptools-0.6c2-py2.3.egg': 'f0064bf6aa2b7d0f3ba0b43f20817c27', 'setuptools-0.6c2-py2.4.egg': '616192eec35f47e8ea16cd6a122b7277', 'setuptools-0.6c3-py2.3.egg': 'f181fa125dfe85a259c9cd6f1d7b78fa', 'setuptools-0.6c3-py2.4.egg': 'e0ed74682c998bfb73bf803a50e7b71e', 'setuptools-0.6c3-py2.5.egg': 'abef16fdd61955514841c7c6bd98965e', 'setuptools-0.6c4-py2.3.egg': 'b0b9131acab32022bfac7f44c5d7971f', 'setuptools-0.6c4-py2.4.egg': '2a1f9656d4fbf3c97bf946c0a124e6e2', 'setuptools-0.6c4-py2.5.egg': '8f5a052e32cdb9c72bcf4b5526f28afc', 'setuptools-0.6c5-py2.3.egg': 'ee9fd80965da04f2f3e6b3576e9d8167', 'setuptools-0.6c5-py2.4.egg': 'afe2adf1c01701ee841761f5bcd8aa64', 'setuptools-0.6c5-py2.5.egg': 'a8d3f61494ccaa8714dfed37bccd3d5d', 'setuptools-0.6c6-py2.3.egg': '35686b78116a668847237b69d549ec20', 'setuptools-0.6c6-py2.4.egg': '3c56af57be3225019260a644430065ab', 'setuptools-0.6c6-py2.5.egg': 'b2f8a7520709a5b34f80946de5f02f53', 'setuptools-0.6c7-py2.3.egg': '209fdf9adc3a615e5115b725658e13e2', 'setuptools-0.6c7-py2.4.egg': '5a8f954807d46a0fb67cf1f26c55a82e', 'setuptools-0.6c7-py2.5.egg': '45d2ad28f9750e7434111fde831e8372', 'setuptools-0.6c8-py2.3.egg': '50759d29b349db8cfd807ba8303f1902', 'setuptools-0.6c8-py2.4.egg': 'cba38d74f7d483c06e9daa6070cce6de', 'setuptools-0.6c8-py2.5.egg': '1721747ee329dc150590a58b3e1ac95b', 'setuptools-0.6c9-py2.3.egg': 'a83c4020414807b496e4cfbe08507c03', 'setuptools-0.6c9-py2.4.egg': '260a2be2e5388d66bdaee06abec6342a', 'setuptools-0.6c9-py2.5.egg': 'fe67c3e5a17b12c0e7c541b7ea43a8e6', 'setuptools-0.6c9-py2.6.egg': 'ca37b1ff16fa2ede6e19383e7b59245a', } import sys, os try: from hashlib import md5 except ImportError: from md5 import md5 def _validate_md5(egg_name, data): if egg_name in md5_data: digest = md5(data).hexdigest() if digest != md5_data[egg_name]: print >>sys.stderr, ( "md5 validation of %s failed! (Possible download problem?)" % egg_name ) sys.exit(2) return data def use_setuptools( version=DEFAULT_VERSION, download_base=DEFAULT_URL, to_dir=os.curdir, download_delay=15 ): """Automatically find/download setuptools and make it available on sys.path `version` should be a valid setuptools version number that is available as an egg for download under the `download_base` URL (which should end with a '/'). `to_dir` is the directory where setuptools will be downloaded, if it is not already available. If `download_delay` is specified, it should be the number of seconds that will be paused before initiating a download, should one be required. If an older version of setuptools is installed, this routine will print a message to ``sys.stderr`` and raise SystemExit in an attempt to abort the calling script. """ was_imported = 'pkg_resources' in sys.modules or 'setuptools' in sys.modules def do_download(): egg = download_setuptools(version, download_base, to_dir, download_delay) sys.path.insert(0, egg) import setuptools; setuptools.bootstrap_install_from = egg try: import pkg_resources except ImportError: return do_download() try: pkg_resources.require("setuptools>="+version); return except pkg_resources.VersionConflict, e: if was_imported: print >>sys.stderr, ( "The required version of setuptools (>=%s) is not available, and\n" "can't be installed while this script is running. Please install\n" " a more recent version first, using 'easy_install -U setuptools'." "\n\n(Currently using %r)" ) % (version, e.args[0]) sys.exit(2) else: del pkg_resources, sys.modules['pkg_resources'] # reload ok return do_download() except pkg_resources.DistributionNotFound: return do_download() def download_setuptools( version=DEFAULT_VERSION, download_base=DEFAULT_URL, to_dir=os.curdir, delay = 15 ): """Download setuptools from a specified location and return its filename `version` should be a valid setuptools version number that is available as an egg for download under the `download_base` URL (which should end with a '/'). `to_dir` is the directory where the egg will be downloaded. `delay` is the number of seconds to pause before an actual download attempt. """ import urllib2, shutil egg_name = "setuptools-%s-py%s.egg" % (version,sys.version[:3]) url = download_base + egg_name saveto = os.path.join(to_dir, egg_name) src = dst = None if not os.path.exists(saveto): # Avoid repeated downloads try: from distutils import log if delay: log.warn(""" --------------------------------------------------------------------------- This script requires setuptools version %s to run (even to display help). I will attempt to download it for you (from %s), but you may need to enable firewall access for this script first. I will start the download in %d seconds. (Note: if this machine does not have network access, please obtain the file %s and place it in this directory before rerunning this script.) ---------------------------------------------------------------------------""", version, download_base, delay, url ); from time import sleep; sleep(delay) log.warn("Downloading %s", url) src = urllib2.urlopen(url) # Read/write all in one block, so we don't create a corrupt file # if the download is interrupted. data = _validate_md5(egg_name, src.read()) dst = open(saveto,"wb"); dst.write(data) finally: if src: src.close() if dst: dst.close() return os.path.realpath(saveto) def main(argv, version=DEFAULT_VERSION): """Install or upgrade setuptools and EasyInstall""" try: import setuptools except ImportError: egg = None try: egg = download_setuptools(version, delay=0) sys.path.insert(0,egg) from setuptools.command.easy_install import main return main(list(argv)+[egg]) # we're done here finally: if egg and os.path.exists(egg): os.unlink(egg) else: if setuptools.__version__ == '0.0.1': print >>sys.stderr, ( "You have an obsolete version of setuptools installed. Please\n" "remove it from your system entirely before rerunning this script." ) sys.exit(2) req = "setuptools>="+version import pkg_resources try: pkg_resources.require(req) except pkg_resources.VersionConflict: try: from setuptools.command.easy_install import main except ImportError: from easy_install import main main(list(argv)+[download_setuptools(delay=0)]) sys.exit(0) # try to force an exit else: if argv: from setuptools.command.easy_install import main main(argv) else: print "Setuptools version",version,"or greater has been installed." print '(Run "ez_setup.py -U setuptools" to reinstall or upgrade.)' def update_md5(filenames): """Update our built-in md5 registry""" import re for name in filenames: base = os.path.basename(name) f = open(name,'rb') md5_data[base] = md5(f.read()).hexdigest() f.close() data = [" %r: %r,\n" % it for it in md5_data.items()] data.sort() repl = "".join(data) import inspect srcfile = inspect.getsourcefile(sys.modules[__name__]) f = open(srcfile, 'rb'); src = f.read(); f.close() match = re.search("\nmd5_data = {\n([^}]+)}", src) if not match: print >>sys.stderr, "Internal error!" sys.exit(2) src = src[:match.start(1)] + repl + src[match.end(1):] f = open(srcfile,'w') f.write(src) f.close() if __name__=='__main__': if len(sys.argv)>2 and sys.argv[1]=='--md5update': update_md5(sys.argv[2:]) else: main(sys.argv[1:]) openchange-2.0/mapiproxy/services/ocsmanager/ocsmanager-apache.conf000066400000000000000000000005611223057412600256650ustar00rootroot00000000000000 ProxyRequests Off SetEnv proxy-nokeepalive 1 ProxyPreserveHost On ProxyPass /autodiscover http://127.0.0.1:5000/autodiscover retry=0 ProxyPass /ews http://127.0.0.1:5000/ews retry=0 ProxyPass /_debug http://127.0.0.1:5000/_debug retry=0 Order allow,deny Allow from all openchange-2.0/mapiproxy/services/ocsmanager/ocsmanager.ini000066400000000000000000000036171223057412600243050ustar00rootroot00000000000000# # ocsmanager - Pylons configuration # # The %(here)s variable will be replaced with the parent directory of this file # [DEFAULT] debug = true email_to = you@yourdomain.com smtp_server = localhost error_email_from = paste@localhost [main] # Possible authentication system # auth = file #auth = ldap auth = single mapistore_root = /var/lib/samba/private mapistore_data = /var/lib/samba/private/mapistore debug = no [auth:file] #file = [auth:ldap] host = ldap://xxx port = 489 bind_dn = bind_pw = basedn = #filter = (cn=%s) #attrs = userPassword, x-isActive [auth:single] username = openchange # password is test password = {SSHA}I6Hy5Wv0wuxyXvMBFWFQDVVN12_CLaX9 [server:main] use = egg:Paste#http host = 127.0.0.1 port = 5000 [app:main] use = egg:ocsmanager full_stack = true static_files = true cache_dir = %(here)s/data beaker.session.key = ocsmanager beaker.session.secret = SDyKK3dKyDgW0mlpqttTMGU1f app_instance_uuid = {ee533ebc-f266-49d1-ae10-d017ee6aa98c} NTLMAUTHHANDLER_WORKDIR = /var/cache/ntlmauthhandler [rpcproxy:ldap] host = localhost port = 389 basedn = CN=Users,DC=example,DC=com # If you'd like to fine-tune the individual locations of the cache data dirs # for the Cache data, or the Session saves, un-comment the desired settings # here: #beaker.cache.data_dir = %(here)s/data/cache #beaker.session.data_dir = %(here)s/data/sessions # WARNING: *THE LINE BELOW MUST BE UNCOMMENTED ON A PRODUCTION ENVIRONMENT* # Debug mode will enable the interactive debugging tool, allowing ANYONE to # execute malicious code after an exception is raised. set debug = false # Logging configuration [loggers] keys = root [handlers] keys = console [formatters] keys = generic [logger_root] level = INFO handlers = console [handler_console] class = StreamHandler args = (sys.stderr,) level = NOTSET formatter = generic [formatter_generic] format = %(asctime)s %(levelname)-5.5s [%(name)s] [%(threadName)s] %(message)s openchange-2.0/mapiproxy/services/ocsmanager/ocsmanager/000077500000000000000000000000001223057412600235755ustar00rootroot00000000000000openchange-2.0/mapiproxy/services/ocsmanager/ocsmanager/__init__.py000066400000000000000000000000001223057412600256740ustar00rootroot00000000000000openchange-2.0/mapiproxy/services/ocsmanager/ocsmanager/config/000077500000000000000000000000001223057412600250425ustar00rootroot00000000000000openchange-2.0/mapiproxy/services/ocsmanager/ocsmanager/config/__init__.py000066400000000000000000000000001223057412600271410ustar00rootroot00000000000000openchange-2.0/mapiproxy/services/ocsmanager/ocsmanager/config/deployment.ini_tmpl000066400000000000000000000025021223057412600307560ustar00rootroot00000000000000# # ocsmanager - Pylons configuration # # The %(here)s variable will be replaced with the parent directory of this file # [DEFAULT] debug = true email_to = you@yourdomain.com smtp_server = localhost error_email_from = paste@localhost [server:main] use = egg:Paste#http host = 0.0.0.0 port = 5000 [app:main] use = egg:ocsmanager full_stack = true static_files = true cache_dir = %(here)s/data beaker.session.key = ocsmanager beaker.session.secret = ${app_instance_secret} app_instance_uuid = ${app_instance_uuid} # If you'd like to fine-tune the individual locations of the cache data dirs # for the Cache data, or the Session saves, un-comment the desired settings # here: #beaker.cache.data_dir = %(here)s/data/cache #beaker.session.data_dir = %(here)s/data/sessions # WARNING: *THE LINE BELOW MUST BE UNCOMMENTED ON A PRODUCTION ENVIRONMENT* # Debug mode will enable the interactive debugging tool, allowing ANYONE to # execute malicious code after an exception is raised. set debug = false # Logging configuration [loggers] keys = root [handlers] keys = console [formatters] keys = generic [logger_root] level = INFO handlers = console [handler_console] class = StreamHandler args = (sys.stderr,) level = NOTSET formatter = generic [formatter_generic] format = %(asctime)s %(levelname)-5.5s [%(name)s] [%(threadName)s] %(message)s openchange-2.0/mapiproxy/services/ocsmanager/ocsmanager/config/environment.py000066400000000000000000000103561223057412600277650ustar00rootroot00000000000000"""Pylons environment configuration""" import os from mako.lookup import TemplateLookup from pylons.configuration import PylonsConfig from pylons.error import handle_mako_error import ocsmanager.lib.app_globals as app_globals import ocsmanager.lib.helpers import ocsmanager.lib.config as OCSConfig from ocsmanager.config.routing import make_map import openchange.mapistore as mapistore # samba import samba.param from samba import Ldb from samba.samdb import SamDB from samba.auth import system_session, admin_session FIRST_ORGANIZATION = "First Organization" FIRST_ORGANIZATION_UNIT = "First Administrative Group" def _load_samba_environment(): """Load the samba configuration vars from smb.conf and the sam.db. """ params = samba.param.LoadParm() params.load_default() netbiosname = params.get("netbios name") hostname = netbiosname.lower() dnsdomain = params.get("realm") dnsdomain = dnsdomain.lower() serverrole = params.get("server role") if serverrole == "domain controller": domaindn = "DC=" + dnsdomain.replace(".", ",DC=") else: domaindn = "CN=" + netbiosname rootdn = domaindn configdn = "CN=Configuration," + rootdn firstorg = FIRST_ORGANIZATION firstou = FIRST_ORGANIZATION_UNIT samdb_ldb = SamDB(url=params.samdb_url(), lp=params) sam_environ = {"samdb_ldb": samdb_ldb, "private_dir": params.get("private dir"), "domaindn": domaindn, "oc_user_basedn": "CN=%s,CN=%s,CN=%s,%s" \ % (firstou, firstorg, netbiosname, domaindn), "firstorgdn": ("CN=%s,CN=Microsoft Exchange,CN=Services,%s" % (firstorg, configdn)), "legacyserverdn": ("/o=%s/ou=%s/cn=Configuration/cn=Servers" "/cn=%s" % (firstorg, firstou, netbiosname)), "hostname": hostname, "dnsdomain": dnsdomain} # OpenChange dispatcher DB names return sam_environ def _load_ocdb(): """Return a Ldb object pointing to the openchangedb.ldb """ params = samba.param.LoadParm() params.load_default() ocdb = Ldb(os.path.join(params.get("private dir"), "openchange.ldb")) return ocdb def load_environment(global_conf, app_conf): """Configure the Pylons environment via the ``pylons.config`` object """ config = PylonsConfig() # Pylons paths root = os.path.dirname(os.path.dirname(os.path.abspath(__file__))) paths = dict(root=root, controllers=os.path.join(root, 'controllers'), static_files=os.path.join(root, 'public'), templates=[os.path.join(root, 'templates')]) # Initialize config with the basic options config.init_app(global_conf, app_conf, package='ocsmanager', paths=paths) config['routes.map'] = make_map(config) config['pylons.app_globals'] = app_globals.Globals(config) config['pylons.h'] = ocsmanager.lib.helpers # Setup cache object as early as possible import pylons pylons.cache._push_object(config['pylons.app_globals'].cache) # Create the Mako TemplateLookup, with the default auto-escaping config['pylons.app_globals'].mako_lookup = TemplateLookup( directories=paths['templates'], error_handler=handle_mako_error, module_directory=os.path.join(app_conf['cache_dir'], 'templates'), input_encoding='utf-8', default_filters=['escape'], imports=['from webhelpers.html import escape']) # CONFIGURATION OPTIONS HERE (note: all config options will override # any Pylons config options) ocsconfig = OCSConfig.OCSConfig(os.path.join(config.get('here'), 'ocsmanager.ini')) config['ocsmanager'] = ocsconfig.load() config['samba'] = _load_samba_environment() config['oc_ldb'] = _load_ocdb() mapistore.set_mapping_path(config['ocsmanager']['main']['mapistore_data']) mstore = mapistore.MAPIStore(config['ocsmanager']['main']['mapistore_root']) config['mapistore'] = mstore config['management'] = mstore.management() if config['ocsmanager']['main']['debug'] == "yes": config['management'].verbose = True; return config openchange-2.0/mapiproxy/services/ocsmanager/ocsmanager/config/middleware.py000066400000000000000000000056401223057412600275360ustar00rootroot00000000000000"""Pylons middleware initialization""" from beaker.middleware import SessionMiddleware from paste.cascade import Cascade from paste.registry import RegistryManager from paste.urlparser import StaticURLParser from paste.deploy.converters import asbool from pylons.middleware import ErrorHandler, StatusCodeRedirect from pylons.wsgiapp import PylonsApp from routes.middleware import RoutesMiddleware from openchange.web.auth.NTLMAuthHandler import NTLMAuthHandler from ocsmanager.config.environment import load_environment # from paste.auth.basic import AuthBasicHandler # from ocsmanager.model.OCSAuthenticator import * def make_app(global_conf, full_stack=True, static_files=True, **app_conf): """Create a Pylons WSGI application and return it ``global_conf`` The inherited configuration for this application. Normally from the [DEFAULT] section of the Paste ini file. ``full_stack`` Whether this application provides a full WSGI stack (by default, meaning it handles its own exceptions and errors). Disable full_stack when this application is "managed" by another WSGI middleware. ``static_files`` Whether this application serves its own static files; disable when another web server is responsible for serving them. ``app_conf`` The application's local configuration. Normally specified in the [app:] section of the Paste ini file (where defaults to main). """ # Configure the Pylons environment config = load_environment(global_conf, app_conf) # The Pylons WSGI app app = PylonsApp(config=config) # Routing/Session Middleware app = RoutesMiddleware(app, config['routes.map']) app = SessionMiddleware(app, config) # CUSTOM MIDDLEWARE HERE (filtered by error handling middlewares) if asbool(full_stack): # Handle Python exceptions app = ErrorHandler(app, global_conf, **config['pylons.errorware']) # Display error documents for 401, 403, 404 status codes (and # 500 when debug is disabled) if asbool(config['debug']): app = StatusCodeRedirect(app, [417]) else: app = StatusCodeRedirect(app, [400, 401, 403, 404, 417, 500]) # authenticator = OCSAuthenticator(config) # app = AuthBasicHandler(app, "OCSManager", authenticator) fqdn = "%(hostname)s.%(dnsdomain)s" % config["samba"] auth_handler = NTLMAuthHandler(app) def ntlm_env_setter(environ, start_response): environ["NTLMAUTHHANDLER_WORKDIR"] = app_conf["NTLMAUTHHANDLER_WORKDIR"] return auth_handler(environ, start_response) # Establish the Registry for this application app = RegistryManager(ntlm_env_setter) if asbool(static_files): # Serve static files static_app = StaticURLParser(config['pylons.paths']['static_files']) app = Cascade([static_app, app]) app.config = config return app openchange-2.0/mapiproxy/services/ocsmanager/ocsmanager/config/routing.py000066400000000000000000000021421223057412600271020ustar00rootroot00000000000000"""Routes configuration The more specific and detailed routes should be defined first so they may take precedent over the more generic routes. For more information refer to the routes manual at http://routes.groovie.org/docs/ """ from routes import Mapper def make_map(config): """Create, configure and return the routes Mapper""" map = Mapper(directory=config['pylons.paths']['controllers'], always_scan=config['debug']) map.minimization = False map.explicit = False # The ErrorController route (handles 404/500 error pages); it should # likely stay at the top, ensuring it can always be resolved map.connect('/error/{action}', controller='error') map.connect('/error/{action}/{id}', controller='error') # CUSTOM ROUTES HERE map.connect('/autodiscover/{action}.xml', controller="autodiscover") map.connect('/ews/{controller}') map.connect('/ews/{controller}.wsdl') map.connect('/{controller}/{action}') map.connect('/{controller}/{action}/{id}') # RPC over HTTP map.connect('/rpc/rpcproxy.dll', controller='rpcproxy') return map openchange-2.0/mapiproxy/services/ocsmanager/ocsmanager/controllers/000077500000000000000000000000001223057412600261435ustar00rootroot00000000000000openchange-2.0/mapiproxy/services/ocsmanager/ocsmanager/controllers/__init__.py000066400000000000000000000000001223057412600302420ustar00rootroot00000000000000openchange-2.0/mapiproxy/services/ocsmanager/ocsmanager/controllers/as.py000066400000000000000000000502171223057412600271250ustar00rootroot00000000000000import logging import datetime from time import time from pylons import request, response, session, tmpl_context as c, url from pylons import config from pylons.controllers.util import abort, redirect from pylons.decorators.rest import restrict import rpclib from rpclib.application import Application from rpclib.decorator import rpc, srpc from rpclib.interface.wsdl import Wsdl11 from rpclib.protocol.soap import Soap11 from rpclib.service import ServiceBase from rpclib.server.wsgi import WsgiApplication from rpclib.util.simple import wsgi_soap_application from lxml.etree import Element, ElementTree, tostring import ldb from openchange import mapistore from ocsmanager.lib.base import BaseController, render from ews_types import * log = logging.getLogger(__name__) """ * sample REQUEST (availability): 300 0 02:00:00 1 11 Sunday -60 02:00:00 2 3 Sunday openchange@inverse.ca SMTP Organizer false 0 30 2012-04-29T00:00:00 2012-06-10T00:00:00 Exchange response (reformatted): NoError 2012-04-29T00:00:00 Poor 2012-04-30T00:00:00 Poor ... 2012-06-07T00:00:00 Poor 2012-06-08T00:00:00 Poor 2012-06-09T00:00:00 Poor * request2: (freebusy) 300 0 02:00:00 1 11 Sunday -60 02:00:00 2 3 Sunday wsourdeau@inverse.local SMTP Required 2012-04-18T09:00:00 2012-05-18T09:00:00 30 Detailed Error response (unknown user): Unable to resolve e-mail address <>SMTP:wsourdeau@inverse.ca to an Active Directory object. ErrorMailRecipientNotFound 0 Microsoft.Exchange.InfoWorker.Common.Availability.MailRecipientNotFoundException 5009 None success response: NoError FreeBusy 2012-05-15T00:00:00-04:00 2012-05-16T00:00:00-04:00 Free 2012-05-16T08:00:00-04:00 2012-05-16T08:30:00-04:00 Busy 300 0 1 11 Sunday -60 2 3 Sunday Monday Tuesday Wednesday Thursday Friday 480 1020 """ class ExchangeService(ServiceBase): @staticmethod def _open_user_calendar_folder(email): # lookup usercn from email ldbdb = config["samba"]["samdb_ldb"] base_dn = "CN=Users,%s" % config["samba"]["domaindn"] ldb_filter = "(&(objectClass=user)(mail=%s))" % email res = ldbdb.search(base=base_dn, scope=ldb.SCOPE_SUBTREE, expression=ldb_filter, attrs=["cn"]) if len(res) == 1: ldb_record = res[0] usercn = ldb_record["cn"][0] else: usercn = None cal_folder = None # lookup mapistore url for cal folder cal_folder = None if usercn is not None: ldbdb = config["oc_ldb"] base_dn = "CN=%s,%s" % (usercn, config["samba"]["oc_user_basedn"]) ldb_filter = "(&(objectClass=systemfolder)(PidTagContainerClass=IPF.Appointment)(MAPIStoreURI=*))" res = ldbdb.search(base=base_dn, scope=ldb.SCOPE_SUBTREE, expression=ldb_filter, attrs=["MAPIStoreURI"]) for x in xrange(len(res)): ldb_record = res[x] uri = ldb_record["MAPIStoreURI"][0] if str(uri).find("/personal") > -1: # FIXME: this is evil context = config["mapistore"].add_context(uri, usercn) cal_folder = context.open() return cal_folder @staticmethod def _timezone_datetime(year, tz_time): # we round the dates to midnight since events are unlikely to start at # such an early time of day return datetime.datetime(year, tz_time.Month + 1, tz_time.DayOrder + 1) @staticmethod def _freebusy_date(timezone, utcdate): bias = timezone.Bias if timezone.DaylightTime is not None: std_datetime = ExchangeService._timezone_datetime(utcdate.year, timezone.StandardTime) dst_datetime = ExchangeService._timezone_datetime(utcdate.year, timezone.DaylightTime) if std_datetime < dst_datetime: if utcdate >= std_datetime and utcdate < dst_datetime: bias = bias + timezone.StandardTime.Bias else: bias = bias + timezone.DaylightTime.Bias else: if utcdate >= dst_datetime and utcdate < std_datetime: bias = bias + timezone.DaylightTime.Bias else: bias = bias + timezone.StandardTime.Bias return utcdate - datetime.timedelta(0, bias * 60) @staticmethod def _freebusy_response(cal_folder, timezone, freebusy_view_options): start = freebusy_view_options.TimeWindow.StartTime end = freebusy_view_options.TimeWindow.EndTime # a = time() # print "fetching freebusy" freebusy_props = cal_folder.fetch_freebusy_properties(start, end) # print "fetched freebusy: %f secs" % (time() - a) fb_response = FreeBusyResponse() fb_response.ResponseMessage = ResponseMessageType() fb_response.ResponseMessage.ResponseClass = "Success" fb_response.ResponseMessage.ResponseCode = "NoError" fb_response.FreeBusyView = FreeBusyView() fb_response.FreeBusyView.FreeBusyViewType = "FreeBusy" events = [] fb_types = {"free": "Free", "tentative": "Tentative", "busy": "Busy", "away": "OOF"} for (fb_attribute, label) in fb_types.iteritems(): fb_event_list = getattr(freebusy_props, fb_attribute) for fb_event in fb_event_list: event = CalendarEvent() event.StartTime = ExchangeService._freebusy_date(timezone, fb_event[0]) event.EndTime = ExchangeService._freebusy_date(timezone, fb_event[1]) event.BusyType = label events.append(event) fb_response.FreeBusyView.CalendarEventArray = events fb_response.FreeBusyView.WorkingHours = WorkingHours() fb_response.FreeBusyView.WorkingHours.TimeZone = timezone period = WorkingPeriod() period.DayOfWeek = "Monday Tuesday Wednesday Thursday Friday" period.StartTimeInMinutes = 8 * 60 period.EndTimeInMinutes = 18 * 60 fb_response.FreeBusyView.WorkingHours.WorkingPeriodArray = [period] return fb_response @staticmethod def _freebusy_lookup_error_response(): fb_response = FreeBusyResponse() fb_response.ResponseMessage = ResponseMessageType() fb_response.ResponseMessage.ResponseClass = "Error" fb_response.ResponseMessage.MessageText \ = "Unable to open the requested user's calendar" fb_response.ResponseMessage.ResponseCode = "ErrorMailRecipientNotFound" fb_response.FreeBusyView = FreeBusyView() fb_response.FreeBusyView.FreeBusyViewType = "None" return [fb_response] @staticmethod def _suggestions_response(timezone, suggestions_view_options): suggestions = SuggestionsResponseType() suggestions.ResponseMessage = ResponseMessageType(ResponseClass="NoError") start = suggestions_view_options.DetailedSuggestionsWindow.StartTime end = suggestions_view_options.DetailedSuggestionsWindow.EndTime current = start delta_day = datetime.timedelta(days=1) suggestions_list = [] while current < end: suggestion = SuggestionDayResult() suggestion.Date = current suggestion.DayQuality = "Poor" suggestion.SuggestionArray = [] suggestions_list.append(suggestion) current = current + delta_day suggestions.SuggestionDayResultArray = suggestions_list return suggestions @staticmethod def _suggestions_lookup_error_response(): suggestions = SuggestionsResponseType() suggestions.ResponseMessage = ResponseMessageType(ResponseClass="NoError") suggestions.ResponseMessage.ResponseClass = "Error" suggestions.ResponseMessage.MessageText \ = "Unable to open the requested user's calendar" suggestions.ResponseMessage.ResponseCode = "ErrorMailRecipientNotFound" suggestions.SuggestionDayResultArray = [] return suggestions @rpc(SerializableTimeZone, ArrayOfMailboxData, FreeBusyViewOptionsType, SuggestionsViewOptionsType, _in_message_name="GetUserAvailabilityRequest", _in_variable_names={"timezone": "TimeZone", "mailbox_data_array": "MailboxDataArray", "freebusy_view_options": "FreeBusyViewOptions", "suggestions_view_options": "SuggestionsViewOptions"}, _out_message="GetUserAvailabilityResponse", _out_header=ServerVersionInfo, _out_variable_names=("FreeBusyResponseArray", "SuggestionsResponse"), _returns=(ArrayOfFreeBusyResponse,SuggestionsResponseType), _soap_body_style="document") def GetUserAvailabilityRequest(ctx, timezone = None, mailbox_data_array = None, freebusy_view_options = None, suggestions_view_options = None): ctx.out_header = ServerVersionInfo(MajorVersion=8, MinorVersion=0, MajorBuildNumber=685, MinorBuildNumber=24) fb_requests = [] for x in xrange(len(mailbox_data_array)): user_email = mailbox_data_array[x].Email.Address calendar_folder = ExchangeService._open_user_calendar_folder(user_email) fb_requests.append({"folder": calendar_folder, "email": user_email}) if freebusy_view_options is not None: freebusy = [] for fb_request in fb_requests: calendar_folder = fb_request["folder"] if calendar_folder is None: log.warn("no calendar folder found for '%s'" % user_email) fb_response \ = ExchangeService._freebusy_lookup_error_response() else: fb_response \ = ExchangeService._freebusy_response(calendar_folder, timezone, freebusy_view_options) freebusy.append(fb_response) else: freebusy = None if suggestions_view_options is not None: suggestions \ = ExchangeService._suggestions_response(timezone, suggestions_view_options) else: suggestions = None return (freebusy, suggestions) EwsApp = Application([ExchangeService], EWS_M_NS, name="ExchangeApplication", interface=Wsdl11(), in_protocol=Soap11(), out_protocol=Soap11()) AsController = WsgiApplication(EwsApp) openchange-2.0/mapiproxy/services/ocsmanager/ocsmanager/controllers/authenticate.py000066400000000000000000000066511223057412600312030ustar00rootroot00000000000000import logging import hashlib import os from base64 import urlsafe_b64encode as encode from base64 import urlsafe_b64decode as decode from pylons import request, response, session, tmpl_context as c, url from pylons.controllers.util import abort, redirect from pylons.decorators.rest import restrict from ocsmanager.model import AuthenticateModel from ocsmanager.lib.base import BaseController, render log = logging.getLogger(__name__) class AuthenticateController(BaseController): def _auth_abort(self, code, message): c.code = code c.message = message return render('/error.xml') @restrict('POST') def token(self): """ Return a session token, one-time hash and password hash for the user. """ # Ensure Content-type is text/xml if request.headers.get("Content-Type", "").startswith("text/xml") is False: return self._auth_abort(417, 'Invalid Parameter') # Retrieve request XML body payload = request.body if payload is None: log.error('Empty payload in auth:token()') return self._auth_abort(417, 'Invalid Parameter') # Retrieve the salt from the model authModel = AuthenticateModel.AuthenticateModel() login = authModel.getTokenLogin(payload) if login is None: return self._auth_abort(417, 'Invalid Parameter') salt = authModel.getTokenLoginSalt(login) if salt is None: log.debug('Invalid user %s', login) salt = encode(hashlib.sha1(os.urandom(4)).digest()) session['token'] = encode(hashlib.sha1(os.urandom(8)).digest()) session['token_salt'] = encode(hashlib.sha1(os.urandom(8)).digest()) session['salt'] = salt session['login'] = login session.save() c.token_salt = session['token_salt'] c.salt = salt response.set_cookie('token', session['token']) response.headers['content-type'] = 'text/xml; charset=utf-8' return render('/token.xml') @restrict('POST') def login(self): """Authenticate the user on ocsmanager. """ if not "ocsmanager" in request.cookies: return self._auth_abort(403, 'Invalid Session') if not "token" in session: return self._auth_abort(403, 'Invalid Session') if not "token" in request.cookies: return self._auth_abort(403, 'Invalid Token') if request.cookies.get('token') != session['token']: return self._auth_abort(403, 'Invalid Token') if not "login" in session: return self._auth_abort(403, 'Invalid Session') payload = request.body if payload is None: log.error('Empty payload in auth:login()') return self._auth_abort(417, 'Invalid Parameter') authModel = AuthenticateModel.AuthenticateModel() (error, msg) = authModel.verifyPassword(session['login'], session['token_salt'], session['salt'], payload) if error is True: response.delete_cookie('token') session['token'] = None return self._auth_abort(401, 'Invalid credentials') # Authentication was successful, remove auth token - no longer needed session['token'] = None response.delete_cookie('token') session['tokenLogin'] = hashlib.sha1(os.urandom(8)).hexdigest() session.save() c.tokenLogin = encode(session['tokenLogin']) c.ttl = 10 return render('/login.xml') openchange-2.0/mapiproxy/services/ocsmanager/ocsmanager/controllers/autodiscover.py000066400000000000000000000250671223057412600312360ustar00rootroot00000000000000"""This module provides an implementation of the autodiscovery protocol. """ from cStringIO import StringIO from time import time, strftime, localtime import traceback import uuid from xml.etree.ElementTree import Element, ElementTree, tostring from pylons import request, response from pylons import config from pylons.decorators.rest import restrict import ldb from ocsmanager.lib.base import BaseController REQUEST_XMLNS = ("http://schemas.microsoft.com/exchange/autodiscover/outlook" "/requestschema/2006") RESPONSE_XMLNS = ("http://schemas.microsoft.com/exchange/autodiscover" "/responseschema/2006") RESPONSEA_XMLNS = ("http://schemas.microsoft.com/exchange/autodiscover/outlook" "/responseschema/2006a") # NOTE: the use of this module requires proper configuration of either SCP or # the SRV field for "_Autodiscover._tcp" in the name service. See MS-OXDISCO. class AutodiscoverHandler(object): """This class parses the XML request, interprets it, find the requested answers and spills back an appropriate XML response. """ def __init__(self, req, env): self.environ = env self.request = None self._parse_request(req.body) self.http_server_name = None server_env_names = iter(["HTTP_X_FORWARDED_SERVER", "HTTP_X_FORWARDED_HOST", "HTTP_HOST"]) try: while self.http_server_name == None: env_name = server_env_names.next() if env_name in self.environ: self.http_server_name \ = (self.environ[env_name].split(":"))[0] except StopIteration: pass def _parse_request(self, body): if body is not None and len(body) > 0: tree = ElementTree(file=StringIO(body)) xrq = tree.find("{%s}Request" % REQUEST_XMLNS) if xrq is not None: adrq = {} for child in xrq.getchildren(): nameidx = child.tag.find("}") + 1 tagname = child.tag[nameidx:] adrq[tagname] = child.text self.request = adrq def _append_elements(self, top_element, tree_dict): for (tag, value) in tree_dict.iteritems(): new_element = Element(tag) if isinstance(value, dict): self._append_elements(new_element, value) else: new_element.text = value top_element.append(new_element) def _fetch_user_ldb_record(self): samdb = config["samba"]["samdb_ldb"] # fetch user data if "LegacyDN" in self.request: ldb_filter = ("(legacyExchangeDN=%s)" % self.request["LegacyDN"]) elif "EMailAddress" in self.request: ldb_filter = ("(&(objectClass=user)(mail=%s))" % self.request["EMailAddress"]) # TODO: handle missing parameter base_dn = "CN=Users,%s" % config["samba"]["domaindn"] res = samdb.search(base=base_dn, scope=ldb.SCOPE_SUBTREE, expression=ldb_filter, attrs=["*"]) if len(res) == 1: ldb_record = res[0] else: ldb_record = None # TODO: handle invalid nbr of records return ldb_record def _fill_deployment_id(self, record): samdb = config["samba"]["samdb_ldb"] # fetch first org data base_dn = config["samba"]["firstorgdn"] res = samdb.search(base=base_dn, scope=ldb.SCOPE_BASE, attrs=["*"]) if len(res) == 1: ldb_record = res[0] if "objectGUID" in ldb_record: guid = uuid.UUID(bytes=ldb_record["objectGUID"][0]) record["DeploymentId"] = str(guid) # TODO: handle invalid nbr of records def _get_user_record(self, ldb_record): record = None if "samba" in config: record = {} if "displayName" in ldb_record: record["DisplayName"] = ldb_record["displayName"][0] if "legacyExchangeDN" in ldb_record: record["LegacyDN"] = ldb_record["legacyExchangeDN"][0] self._fill_deployment_id(record) else: raise RuntimeError("samba config not loaded") return record def _fetch_mdb_dn(self, user_ldb_record): mdb_dn = None if "homeMDB" in user_ldb_record: base_dn = user_ldb_record["homeMDB"][0] samdb = config["samba"]["samdb_ldb"] res = samdb.search(base=base_dn, scope=ldb.SCOPE_BASE, attrs=["*"]) if len(res) == 1: ldb_record = res[0] if "legacyExchangeDN" in ldb_record: mdb_dn = ldb_record["legacyExchangeDN"][0] # TODO: handle invalid nbr of records return mdb_dn def _append_user_found_response(self, resp_element, ldb_record): #TODO: check user_record response_tree = {"User": self._get_user_record(ldb_record)} self._append_elements(resp_element, response_tree) account_element = Element("Account") resp_element.append(account_element) self._append_elements(account_element, {"AccountType": "email", "Action": "settings"}) mdb_dn = self._fetch_mdb_dn(ldb_record) """ EXCH: The Protocol element contains information that the Autodiscover client can use to communicate with the mailbox via a remote procedure call (RPC). For details, see [MS- OXCRPC]. The AuthPackage element, the ServerVersion element, or the ServerDN element can be used. """ prot_element = Element("Protocol") account_element.append(prot_element) response_tree = \ {"Type": "EXCH", "ServerDN": config["samba"]["legacyserverdn"], "ServerVersion": "720082AD", # TODO: that is from ex2010 "MdbDN": mdb_dn, "Server": self.http_server_name, "ASUrl": "https://%s/ews/as" \ % self.http_server_name, # availability "OOFUrl": "https://%s/ews/oof" \ % self.http_server_name, # out-of-office "OABUrl": "https://%s/ews/oab" \ % self.http_server_name, # offline address book } self._append_elements(prot_element, response_tree) """ EXPR: The Protocol element contains information that the Autodiscover client can use to communicate when outside the firewall, including RPC/HTTP connections. For details, see [MS- RPCH]. The AccountType element MUST be set to email. The AuthPackage element or the ServerVersion element can be used. """ prot_element = Element("Protocol") account_element.append(prot_element) samba_server_name = "%(hostname)s.%(dnsdomain)s" % config["samba"] response_tree = {"Type": "EXPR", "Server": samba_server_name, "SSL": "Off", "AuthPackage": "Ntlm"} self._append_elements(prot_element, response_tree) """ WEB: The Protocol element contains settings the client can use to connect via a Web browser. The AccountType element MUST be set to email. """ # TODO: implement the above. OWA = SOGo? def _append_error(self, resp_element, error_code): error_messages = {500: "Unknown e-mail address", 501: "No configuration information available" \ " for e-mail address", 600: "Invalid request", 601: "Configuration information not available", 602: "Error in configuration information for" \ " e-mail address", 603: "An internal error occurred", 0: "An unknown error occurred"} seconds_as_float = time() seconds_as_int = int(seconds_as_float) millisecs = int((seconds_as_float - seconds_as_int) * 1000000) time_val = "%s.%d" % (strftime("%2H:%2M:%2S", localtime(seconds_as_int)), millisecs) server_id = abs(hash(self.http_server_name)) error_element = Element("Error", {"Time": time_val, "Id": str(server_id)}) resp_element.append(error_element) if error_code in error_messages: message = error_messages[error_code] else: message = error_messages[0] response_tree = {"ErrorCode": str(error_code), "Message": message} self._append_elements(error_element, response_tree) error_element.append(Element("DebugData")) def response(self): """The method the actually performs the class's parsing and interpretation work. Returns a fully formatted XML response. """ ## TODO: # error handling when self.request is none # error handling when samba_ldb is not available top_element = Element("Autodiscover", {"xmlns": RESPONSE_XMLNS}) resp_element = Element("Response") top_element.append(resp_element) if self.request is not None: ldb_record = self._fetch_user_ldb_record() if ldb_record is None: self._append_error(resp_element, 500) else: resp_element.set("xmlns", RESPONSEA_XMLNS) self._append_user_found_response(resp_element, ldb_record) else: self._append_error(resp_element, 600) body = ("\n" + tostring(top_element, "utf-8")) return body class AutodiscoverController(BaseController): """The constroller class for Autodiscover requests.""" @restrict('POST', 'GET') def autodiscover(self, **kwargs): #TODO: authentication try: if "environ" in kwargs: environ = kwargs["environ"] else: environ = None rqh = AutodiscoverHandler(request, environ) response.headers["content-type"] = "application/xml" body = rqh.response() except: response.status = 500 response.headers["content-type"] = "text/plain" # TODO: disable the showing of exception in prod body = "An exception occurred:\n" + traceback.format_exc() return body openchange-2.0/mapiproxy/services/ocsmanager/ocsmanager/controllers/error.py000066400000000000000000000020441223057412600276460ustar00rootroot00000000000000import cgi from paste.urlparser import PkgResourcesParser from pylons import request from pylons.controllers.util import forward from pylons.middleware import error_document_template from webhelpers.html.builder import literal from ocsmanager.lib.base import BaseController class ErrorController(BaseController): """Generates error documents as and when they are required. The ErrorDocuments middleware forwards to ErrorController when error related status codes are returned from the application. This behaviour can be altered by changing the parameters to the ErrorDocuments middleware in your config/middleware.py file. """ def document(self): """Render the error document""" resp = request.environ.get('pylons.original_response') content = cgi.escape(request.GET.get('message', '')) page = """ %(message)s """ % {'code':cgi.escape(request.GET.get('code', str(resp.status_int))), 'message': content} return page openchange-2.0/mapiproxy/services/ocsmanager/ocsmanager/controllers/ews_types.py000066400000000000000000001136061223057412600305460ustar00rootroot00000000000000"""This module defines the minimum set of SOAP types required for providing the Exchange Web Services. The definitions here are loosely based on the wsdl files provided by the Exchange doc. """ from rpclib.model.complex import * from rpclib.model.primitive import * #aliases Short = Integer16 EWS_T_NS = "http://schemas.microsoft.com/exchange/services/2006/types" # t EWS_M_NS = "http://schemas.microsoft.com/exchange/services/2006/messages" # m """ """ DayOfWeekType = String """ """ class SerializableTimeZoneTime(ComplexModel): __namespace__ = EWS_T_NS _type_info = {"Bias": Integer, "Time": String, "DayOrder": Short, "Month": Short, "DayOfWeek": DayOfWeekType} """ """ class SerializableTimeZone(ComplexModel): __namespace__ = EWS_T_NS _type_info = {"Bias": Integer, "StandardTime": SerializableTimeZoneTime, "DaylightTime": SerializableTimeZoneTime} """ """ class EmailAddress(ComplexModel): __namespace__ = EWS_T_NS _type_info = {"Name": String, "Address": String, "RoutingType": String} """ """ MeetingAttendeeType = String """ """ class MailboxData(ComplexModel): __namespace__ = EWS_T_NS _type_info = {"Email": EmailAddress, "AttendeeType": MeetingAttendeeType, "ExcludeConflicts": Boolean} """ ArrayOfMailboxData """ ArrayOfMailboxData = Array(MailboxData) class Duration(ComplexModel): __namespace__ = EWS_T_NS _type_info = {"StartTime": DateTime, "EndTime": DateTime} """ """ FreeBusyViewType = String """ FreeBusyViewOptions """ class FreeBusyViewOptionsType(ComplexModel): __namespace__ = EWS_T_NS _type_info = {"TimeWindow": Duration, "MergedFreeBusyIntervalInMinutes": Integer, "RequestedView": FreeBusyViewType} """ """ SuggestionQuality = String """ """ class SuggestionsViewOptionsType(ComplexModel): __namespace__ = EWS_T_NS _type_info = {"GoodThreshold": Integer, "MaximumResultsByDay": Integer, "MaximumNonWorkHourResultsByDay": Integer, "MeetingDurationInMinutes": Integer, "MinimumSuggestionQuality": SuggestionQuality, "DetailedSuggestionsWindow": Duration, "CurrentMeetingTime": DateTime, "GlobalObjectId": String} """ INPUT: """ class GetUserAvailabilityRequestType(ComplexModel): __namespace__ = EWS_M_NS _type_info = {"TimeZone": SerializableTimeZone, "MailboxDataArray": ArrayOfMailboxData, "FreeBusyViewOptions": FreeBusyViewOptionsType, "SuggestionsViewOptions": SuggestionsViewOptionsType} """ Represents the message keys that can be returned by response error messages """ ResponseCodeType = String """ """ ResponseClassType = String """ """ class ResponseMessageType(ComplexModel): __namespace__ = EWS_M_NS _type_info = {"ResponseClass": XmlAttribute(String), "MessageText": String, "ResponseCode": ResponseCodeType, "DescriptiveLinkKey": Integer, "MessageXml": Array(AnyXml)} """ """ LegacyFreeBusyType = String """ """ class CalendarEventDetails(ComplexModel): __namespace__ = EWS_T_NS _type_info = {"ID": String, "Subject": String, "Location": String, "IsMeeting": Boolean, "IsRecurring": Boolean, "IsException": Boolean, "IsReminderSet": Boolean, "IsPrivate": Boolean} """ """ class CalendarEvent(ComplexModel): __namespace__ = EWS_T_NS _type_info = {"StartTime": DateTime, "EndTime": DateTime, "BusyType": LegacyFreeBusyType, "CalendarEventDetails": CalendarEventDetails} """ """ ArrayOfCalendarEvent = Array(CalendarEvent) """ """ DaysOfWeekType = String """ """ class WorkingPeriod(ComplexModel): __namespace__ = EWS_T_NS _type_info = {"DayOfWeek": DaysOfWeekType, "StartTimeInMinutes": Integer, "EndTimeInMinutes": Integer} """ """ ArrayOfWorkingPeriod = Array(WorkingPeriod) """ """ class WorkingHours(ComplexModel): __namespace__ = EWS_T_NS _type_info = {"TimeZone": SerializableTimeZone, "WorkingPeriodArray": ArrayOfWorkingPeriod} """ """ class FreeBusyView(ComplexModel): __namespace__ = EWS_T_NS _type_info = {"FreeBusyViewType": FreeBusyViewType, "MergedFreeBusy": String, "CalendarEventArray": ArrayOfCalendarEvent, "WorkingHours": WorkingHours} """ """ class FreeBusyResponse(ComplexModel): __namespace__ = EWS_M_NS _type_info = {"ResponseMessage": ResponseMessageType, "FreeBusyView": FreeBusyView} """ """ ArrayOfFreeBusyResponse = Array(FreeBusyResponse) """ """ class UnknownAttendeeConflictData(ComplexModel): __namespace__ = EWS_T_NS _type_info = {} class IndividualAttendeeConflictData(ComplexModel): __namespace__ = EWS_T_NS _type_info = {} class TooBigGroupAttendeeConflictData(ComplexModel): __namespace__ = EWS_T_NS _type_info = {} """ """ class GroupAttendeeConflictData(ComplexModel): __namespace__ = EWS_T_NS _type_info = {"NumberOfMembers": Integer, "NumberOfMembersAvailable": Integer, "NumberOfMembersWithConflict": Integer, "NumberOfMembersWithNoData": Integer} """ """ class ArrayOfAttendeeConflictData(ComplexModel): __namespace__ = EWS_T_NS _type_info = {"UnknownAttendeeConflictData": UnknownAttendeeConflictData, "IndividualAttendeeConflictData": IndividualAttendeeConflictData, "TooBigGroupAttendeeConflictData": TooBigGroupAttendeeConflictData, "GroupAttendeeConflictData": GroupAttendeeConflictData} """ """ class Suggestion(ComplexModel): __namespace__ = EWS_T_NS _type_info = {"MeetingType": DateTime, "IsWorkTime": Boolean, "SuggestionQuality": SuggestionQuality, "AttendeeConflictDataArray": ArrayOfAttendeeConflictData} """ """ ArrayOfSuggestion = Array(Suggestion) """ """ class SuggestionDayResult(ComplexModel): __namespace__ = EWS_T_NS _type_info = {"Date": DateTime, "DayQuality": SuggestionQuality, "SuggestionArray": ArrayOfSuggestion} """ """ ArrayOfSuggestionDayResult = Array(SuggestionDayResult) ArrayOfSuggestionDayResult.__namespace__ = EWS_M_NS """ """ class SuggestionsResponseType(ComplexModel): __namespace__ = EWS_M_NS _type_info = {"ResponseMessage": ResponseMessageType, "SuggestionDayResultArray": ArrayOfSuggestionDayResult} """ OUTPUT: """ class GetUserAvailabilityResponseType(ComplexModel): __namespace__ = EWS_M_NS _type_info = {"FreeBusyResponseArray": ArrayOfFreeBusyResponse, "SuggestionsResponse": SuggestionsResponseType} class ServerVersionInfo(ComplexModel): __namespace__ = EWS_T_NS _type_info = {"MajorVersion": XmlAttribute(Integer), "MinorVersion": XmlAttribute(Integer), "MajorBuildNumber": XmlAttribute(Integer), "MinorBuildNumber": XmlAttribute(Integer)} openchange-2.0/mapiproxy/services/ocsmanager/ocsmanager/controllers/notification.py000066400000000000000000000022761223057412600312120ustar00rootroot00000000000000import logging from pylons import request, response, session, tmpl_context as c, url from pylons.controllers.util import abort, redirect from pylons.decorators.rest import restrict from ocsmanager.model import AuthenticateModel from ocsmanager.model import NotificationModel from ocsmanager.lib.base import BaseController, render log = logging.getLogger(__name__) class NotificationController(BaseController): def _abort(self, code, message): c.code = code c.message = message return render('/error.xml') @restrict('PUT') def newmail(self): """ Send a newmail notification to be dispatched to OpenChange Server. """ notification = NotificationModel.NotificationModel() authModel = AuthenticateModel.AuthenticateModel() token = authModel.getSessionToken(request.body) if token is None: return self._abort(472, 'Invalid token') if token != session['tokenLogin']: return self._abort(403, 'Access forbidden') (error,params) = notification.getNewMailParams(request.body) if error is True: return self._abort(417, params) print params return render('/notification.xml') openchange-2.0/mapiproxy/services/ocsmanager/ocsmanager/controllers/rpcproxy.py000066400000000000000000000020511223057412600304010ustar00rootroot00000000000000import logging from pylons import request, response, session, tmpl_context as c, url from pylons.controllers.util import abort, redirect # from ocsmanager.model import RPCProxyAuthenticateModel from ocsmanager.lib.base import BaseController, render log = logging.getLogger(__name__) class RpcproxyController(BaseController): def index(self): # auth = RPCProxyAuthenticateModel.RPCProxyAuthenticateModel() if request.method == 'RPC_IN_DATA': log.debug('IN Channel Request') # retval = auth.Authenticate(request.authorization) response.headers['Content-Type'] = 'application/rpc' # if retval == 1: # log.debug('Authentication failure') # return elif request.method == 'RPC_OUT_DATA': log.debug('OUT Channel Request') # retval = auth.Authenticate(request.authorization) response.headers['Content-Type'] = 'application/rpc' if retval == 1: log.debug('Authentication failure') return '' openchange-2.0/mapiproxy/services/ocsmanager/ocsmanager/lib/000077500000000000000000000000001223057412600243435ustar00rootroot00000000000000openchange-2.0/mapiproxy/services/ocsmanager/ocsmanager/lib/__init__.py000066400000000000000000000000001223057412600264420ustar00rootroot00000000000000openchange-2.0/mapiproxy/services/ocsmanager/ocsmanager/lib/app_globals.py000066400000000000000000000010351223057412600271770ustar00rootroot00000000000000"""The application's Globals object""" from beaker.cache import CacheManager from beaker.util import parse_cache_config_options class Globals(object): """Globals acts as a container for objects available throughout the life of the application """ def __init__(self, config): """One instance of Globals is created during application initialization and is available during requests via the 'app_globals' variable """ self.cache = CacheManager(**parse_cache_config_options(config)) openchange-2.0/mapiproxy/services/ocsmanager/ocsmanager/lib/base.py000066400000000000000000000010631223057412600256270ustar00rootroot00000000000000"""The base Controller API Provides the BaseController class for subclassing. """ from pylons.controllers import WSGIController from pylons.templating import render_mako as render class BaseController(WSGIController): def __call__(self, environ, start_response): """Invoke the Controller""" # WSGIController.__call__ dispatches to the Controller method # the request is routed to. This routing information is # available in environ['pylons.routes_dict'] return WSGIController.__call__(self, environ, start_response) openchange-2.0/mapiproxy/services/ocsmanager/ocsmanager/lib/config.py000066400000000000000000000104251223057412600261640ustar00rootroot00000000000000import ConfigParser import os, sys import logging log = logging.getLogger(__name__) class OCSConfig(object): """OCSConfig class documentation. Load and retrieve ocsmanager options from configuration file. """ def __init__(self, config): """Initialize OCSConfig instance. """ self.cfg = ConfigParser.ConfigParser() self.config = config self.d = {} def __get_section(self, section=None): if not self.cfg.has_section(section): log.error("%s: Missing [%s] section", self.config, section) sys.exit() def __get_option(self, section=None, option=None, shash=None, ohash=None, dflt=None): if dflt is None and not self.cfg.has_option(section, option): log.error("%s: Missing %s option in [%s] section", self.config, option, section) sys.exit() if dflt is not None and not self.cfg.has_option(section, option): cfg_option = dflt else: cfg_option = self.cfg.get(section, option) if shash is not None: if not shash in self.d: self.d[shash] = {} else: if not section in self.d: self.d[section] = {} if shash is None and ohash is None: self.d[section][option] = cfg_option if shash is not None and ohash is None: self.d[shash][option] = cfg_option if shash is not None and ohash is not None: self.d[shash][ohash] = cfg_option if shash is None and ohash is not None: self.d[section][ohash] = cfg_option def __parse_main(self): """Parse [main] configuration section. """ self.__get_section('main') self.__get_option('main', 'auth', 'auth', 'type') self.__get_option('main', 'mapistore_root') self.__get_option('main', 'mapistore_data') self.__get_option('main', 'debug') if self.d['main']['debug'] != "yes" and self.d['main']['debug'] != "no": log.error("%s: invalid debug value: %s. Must be set to yes or no", self.config, self.d['main']['debug']) sys.exit() if not self.cfg.has_section('auth:%s' % self.d['auth']['type']): log.error("%s: Missing [auth:%s] section", self.config, self.d['auth']['type']) sys.exit() def __parse_auth(self): section = 'auth:%s' % self.d['auth'].get('type') self.__get_section(section) if self.d['auth']['type'] == 'single': self.__get_option(section, 'username', 'auth', None) self.__get_option(section, 'password', 'auth', None) if self.d['auth']['password'].startswith('{SSHA}'): self.d['auth']['encryption'] = 'ssha' else: self.d['auth']['encryption'] = 'plain' if self.d['auth']['type'] == 'file': self.__getoption(section, 'file', 'auth', None) if self.d['auth']['type'] == 'ldap': self.__get_option(section, 'host', 'auth', None) self.__get_option(section, 'port', 'auth', None, 389) self.__get_option(section, 'bind_dn', 'auth', None) self.__get_option(section, 'bind_pw', 'auth', None) self.__get_option(section, 'basedn', 'auth', None) self.__get_option(section, 'filter', 'auth', None, '(cn=%s)') self.__get_option(section, 'attrs', 'auth', None, '*') def __parse_rpcproxy(self): self.__get_section('rpcproxy:ldap') self.__get_option('rpcproxy:ldap', 'host', 'rpcproxy', 'ldap_host') self.__get_option('rpcproxy:ldap', 'port', 'rpcproxy', 'ldap_port') self.__get_option('rpcproxy:ldap', 'basedn', 'rpcproxy', 'ldap_basedn') def load(self): """Load the configuration file. """ cfg = {} try: os.stat(self.config) except OSError as e: log.error("%s (%s): %s", self.config, e.args[0], e.args[1]) sys.exit() try: self.cfg.read(self.config) except ConfigParser.MissingSectionHeaderError: log.error("%s: Invalid Configuration File", self.config) sys.exit() self.__parse_main() self.__parse_auth() self.__parse_rpcproxy() return self.d openchange-2.0/mapiproxy/services/ocsmanager/ocsmanager/lib/helpers.py000066400000000000000000000004211223057412600263540ustar00rootroot00000000000000"""Helper functions Consists of functions to typically be used within templates, but also available to Controllers. This module is available to templates as 'h'. """ # Import helpers as desired, or define your own, ie: #from webhelpers.html.tags import checkbox, password openchange-2.0/mapiproxy/services/ocsmanager/ocsmanager/lib/utils.py000066400000000000000000000010261223057412600260540ustar00rootroot00000000000000"""The applications Utils function""" from lxml import etree def validateDocXML(payload): """Perform common preliminary XML checks on payload and return lxml object on success with error status set to False.""" try: xmlData = etree.XML(payload) except etree.XMLSyntaxError: return (True, 'Invalid document') if xmlData.tag is None: return (True, 'Invalid root element') if xmlData.tag != 'ocsmanager': return (True, 'Invalid root element %s' % xmlData.tag) return (False, xmlData) openchange-2.0/mapiproxy/services/ocsmanager/ocsmanager/model/000077500000000000000000000000001223057412600246755ustar00rootroot00000000000000openchange-2.0/mapiproxy/services/ocsmanager/ocsmanager/model/AuthenticateModel.py000066400000000000000000000043751223057412600306570ustar00rootroot00000000000000from pylons import config from lxml import etree import re from base64 import urlsafe_b64encode as encode from base64 import urlsafe_b64decode as decode from ocsmanager.model.auth import SingleAuthenticateModel as single from ocsmanager.lib.utils import validateDocXML #from ocsmanager.model.auth import LDAPAuthenticateModel as ldap #from ocsmanager.model.auth import FileAuthenticateModel as mfile class AuthenticateModel: def __init__(self): auth_type = config['ocsmanager']['auth']['type'] if auth_type == 'single': self.model = single.SingleAuthenticateModel() # elif auth_type == 'ldap': # self.model = ldap.LDAPAuthenticateModel() # elif auth_type == 'file': # self.model = mfile.FileAuthenticateModel() else: log.error('Unsupported authentication scheme: %s', auth_type) sys.exit() def getTokenLoginSalt(self, login): """Returns the salt of the SSHA user password on success, otherwise None.""" return self.model.getSalt(login) def getSessionToken(self, payload): """Validate XML document and extract authentication token from the payload.""" (error, xmlData) = validateDocXML(payload) if error is True: return None token = xmlData.find('token') if token is None: return None return decode(token.text) def getTokenLogin(self, payload): """Validate XML document and retrieve the login from XML payload.""" (error, xmlData) = validateDocXML(payload) if error is True: return None login = xmlData.find('login') if login is None: return None # Ensure login is made of allowed characters (prevent from injections) if re.match(r'^[A-Za-z0-9_.@-]+$', login.text) is None: return None return login.text def verifyPassword(self, login, token_salt, salt, payload): """Check if the supplied login hash is correct. """ (error, xmlData) = validateDocXML(payload) if error is True: return (error, xmlData) token = xmlData.find('token') if token is None: return (True, 'No token parameter found') return self.model.verifyPassword(login, token_salt, salt, token.text) openchange-2.0/mapiproxy/services/ocsmanager/ocsmanager/model/NotificationModel.py000066400000000000000000000076621223057412600306710ustar00rootroot00000000000000from pylons import config from lxml import etree from ocsmanager.lib.utils import validateDocXML import re class NotificationModel: def getNewMailParams(self, payload): """Retrieve newmail parameters.""" (error, xmlData) = validateDocXML(payload) if error is True: return (error, xmlData) # Retrieve MAPIStore management object mgmt = config['mapistore'] # Initialize dictionary params = {} # Retrieve notification and ensure it's newmail notification = xmlData.find('notification') if notification is None: return (True, 'Missing Notification') if not 'category' in notification.attrib: return (True, 'Missing notification type') if notification.attrib['category'] != 'newmail': return (True, 'Invalid notification type') # backend parameter param = notification.find('backend') if param is None or param.text is None: return (True, 'Invalid/Missing backend parameter') if mgmt.registered_backend(param.text) is False: return (True, 'Specified backend is invalid') params['backend'] = param.text # folder parameter param = notification.find('folder') if param is None or param.text is None: return (True, 'Invalid/Missing folder parameter') params['folder'] = param.text # messageID parameter param = notification.find('messageID') if param is None or param.text is None: retrun (True, 'Invalid/Missing messageID parameter') params['messageID'] = param.text # username parameter param = notification.find('username') if param is None or param.text is None: return (True, 'Invalid/Missing username parameter') params['vuser'] = param.text # Search for openchange user matching above attributes ed = mgmt.existing_users(params['backend'], params['vuser'], params['folder']) if ed['count'] == 0: return (True, 'Invalid user') print ed count = 0 for info in ed['infos']: ret = mgmt.registered_message(params['backend'], info['username'], params['vuser'], params['folder'], info['mapistoreURI'], params['messageID']) if ret is True: print 'Message already registered for user %s' % info['username'] count = count + 1 else: # Register the message in all users indexing databases message = mgmt.register_message(params['backend'], info['username'], info['mapistoreURI'], params['messageID']) if not message: print "Unable to register URI for user %s" % (info['username']) else: print "[REGISTERED] user %s: (%s, %s)" % (info['username'], hex(message[0]), message[1]) # Case where all users referencing this folder already got notified if count == ed['count']: return (True, 'Message already registered') # Only trigger a notification for registered users rd = mgmt.registered_users(params['backend'], param.text) print rd if rd["count"] == 0: return (True, 'User not registered') params['usernames'] = rd["usernames"] # Trigger newmail notification for registered users (rd) who subscribed for newmail Notification for info in ed['infos']: for username in params['usernames']: # print 'Searching for fnevNewmail for %s on %s' % (username, info['mapistoreURI']) # ret = mgmt.registered_subscription(username, info['mapistoreURI'], 1, 4) # if ret is True: print 'Sending newmail notif on /%s#newmail' % username ret = mgmt.send_newmail(username, info['username'], info['mapistoreURI'], message[1]) if ret is False: print 'Error while sending newmail notif' return (False, params) openchange-2.0/mapiproxy/services/ocsmanager/ocsmanager/model/OCSAuthenticator.py000066400000000000000000000017061223057412600304320ustar00rootroot00000000000000import ldap import logging logger = logging.getLogger(__name__) class OCSAuthenticator(object): def __init__(self, config): self.config = config def __call__(self, environ, username, password): result = False config = self.config['ocsmanager']['rpcproxy'] # FIXME: we should perform an indirect bind, based on sAMAccountName userdn = 'CN=%s,%s' % (username, config['ldap_basedn']) try: # FIXME: should be # 'ocsmanager' alone since we require auth from # all actions l = ldap.open(config['ldap_host']) l.protocol_version = ldap.VERSION3 l.simple_bind(userdn, password) l.result() # this will cause an exception in case of a failure result = True except ldap.LDAPError, e: logger.info("authentication failure for '%s'", userdn) logger.debug(e) l.unbind() return result openchange-2.0/mapiproxy/services/ocsmanager/ocsmanager/model/RPCProxyAuthenticateModel.py000066400000000000000000000033731223057412600322630ustar00rootroot00000000000000import ldap import logging from pylons import config from base64 import urlsafe_b64encode as encode from base64 import urlsafe_b64decode as decode log = logging.getLogger(__name__) class RPCProxyAuthenticateModel: def __init__(self): self.auth_type = None self.ldap = {} self.ldap['host'] = config['ocsmanager']['rpcproxy']['ldap_host'] self.ldap['post'] = config['ocsmanager']['rpcproxy']['ldap_port'] self.ldap['basedn'] = config['ocsmanager']['rpcproxy']['ldap_basedn'] return def Authenticate(self, auth): """ Authenticate user depending on the authentication type. Return 0 on success otherwise 1. """ if auth is None or len(auth) != 2: return 1 if auth[0] == 'Basic': return self.AuthenticateBasic(auth[1]) elif auth[0] == 'NTLM': return self.AuthenticateNTLM(auth[1]) else: return 1 def AuthenticateBasic(self, payload): """ Implement Basic authentication scheme support. """ blob = decode(payload) credentials = blob.split(':') if len(credentials[0].split('\\')) == 2: username = credentials[0].split('\\')[1] else: username = credentials[0] try: l = ldap.open(self.ldap['host']) l.protocol_version = ldap.VERSION3 username = 'CN=%s,%s' % (username, self.ldap['basedn']) password = credentials[1] l.simple_bind(username, password) except ldap.LDAPError, e: log.debug(e) return 1 return 0 def AuthenticateNTLM(self, payload): """ Implement NTLM authentication scheme support. """ return 1 openchange-2.0/mapiproxy/services/ocsmanager/ocsmanager/model/__init__.py000066400000000000000000000000001223057412600267740ustar00rootroot00000000000000openchange-2.0/mapiproxy/services/ocsmanager/ocsmanager/model/auth/000077500000000000000000000000001223057412600256365ustar00rootroot00000000000000openchange-2.0/mapiproxy/services/ocsmanager/ocsmanager/model/auth/SingleAuthenticateModel.py000066400000000000000000000034341223057412600327550ustar00rootroot00000000000000import os, sys import hashlib from base64 import urlsafe_b64encode as encode from base64 import urlsafe_b64decode as decode from pylons import config class SingleAuthenticateModel(object): def __init__(self): self.username = config['ocsmanager']['auth']['username'] self.password = config['ocsmanager']['auth']['password'] self.encryption = config['ocsmanager']['auth']['encryption'] if self.encryption == "plain": self.salt = os.urandom(4) elif self.encryption == "ssha": challenge_bytes = decode(self.password[6:]) self.salt = challenge_bytes[20:] else: log.error("%s: Unsupported password encryption: %s", self.encryption) sys.exit() def getSalt(self, username): if username != self.username: return None return encode(self.salt) def verifyPassword(self, username, token_salt64, salt64, payload): if username != self.username: return (True, 'Invalid Username/Password') salt = decode(salt64) token_salt = decode(token_salt64) # Recreate the payload and compare it if self.encryption == "plain": h = hashlib.sha1(self.password) h.update(salt) sshaPassword = "{SSHA}" + encode(h.digest() + salt) elif self.encryption == "ssha": sshaPassword = self.password else: log.error("%s: Unsupported password encryption: %s", self.encryption) sys.exit() h = hashlib.sha1(str(username) + ':' + str(sshaPassword) + ':' + str(token_salt)) h.update(token_salt) phash = h.hexdigest() # Final authentication check if phash == payload: return (False, None) return (True, 'Invalid Credentials') openchange-2.0/mapiproxy/services/ocsmanager/ocsmanager/model/auth/__init__.py000066400000000000000000000000001223057412600277350ustar00rootroot00000000000000openchange-2.0/mapiproxy/services/ocsmanager/ocsmanager/templates/000077500000000000000000000000001223057412600255735ustar00rootroot00000000000000openchange-2.0/mapiproxy/services/ocsmanager/ocsmanager/templates/error.xml000066400000000000000000000001601223057412600274430ustar00rootroot00000000000000 ${c.message} openchange-2.0/mapiproxy/services/ocsmanager/ocsmanager/templates/login.xml000066400000000000000000000001701223057412600274230ustar00rootroot00000000000000 ${c.tokenLogin} ${c.ttl} openchange-2.0/mapiproxy/services/ocsmanager/ocsmanager/templates/notification.xml000066400000000000000000000001011223057412600307730ustar00rootroot00000000000000 openchange-2.0/mapiproxy/services/ocsmanager/ocsmanager/templates/token.xml000066400000000000000000000002271223057412600274360ustar00rootroot00000000000000 ${c.token_salt} ${c.salt} 10 openchange-2.0/mapiproxy/services/ocsmanager/ocsmanager/tests/000077500000000000000000000000001223057412600247375ustar00rootroot00000000000000openchange-2.0/mapiproxy/services/ocsmanager/ocsmanager/tests/__init__.py000066400000000000000000000017721223057412600270570ustar00rootroot00000000000000"""Pylons application test package This package assumes the Pylons environment is already loaded, such as when this script is imported from the `nosetests --with-pylons=test.ini` command. This module initializes the application via ``websetup`` (`paster setup-app`) and provides the base testing objects. """ from unittest import TestCase from paste.deploy import loadapp from paste.script.appinstall import SetupCommand from pylons import url from routes.util import URLGenerator from webtest import TestApp import pylons.test __all__ = ['environ', 'url', 'TestController'] # Invoke websetup with the current config file SetupCommand('setup-app').run([pylons.test.pylonsapp.config['__file__']]) environ = {} class TestController(TestCase): def __init__(self, *args, **kwargs): wsgiapp = pylons.test.pylonsapp config = wsgiapp.config self.app = TestApp(wsgiapp) url._push_object(URLGenerator(config['routes.map'], environ)) TestCase.__init__(self, *args, **kwargs) openchange-2.0/mapiproxy/services/ocsmanager/ocsmanager/tests/functional/000077500000000000000000000000001223057412600271015ustar00rootroot00000000000000openchange-2.0/mapiproxy/services/ocsmanager/ocsmanager/tests/functional/__init__.py000066400000000000000000000000001223057412600312000ustar00rootroot00000000000000openchange-2.0/mapiproxy/services/ocsmanager/ocsmanager/tests/functional/test_authenticate.py000066400000000000000000000046011223057412600331710ustar00rootroot00000000000000from ocsmanager.tests import * import paste.httpexceptions as httpexceptions from xml.etree import ElementTree as ET class TestAuthenticateController(TestController): def test_token(self): """ Test token function with XML payload using valid username. """ response = self.app.post(url(controller='authenticate', action='token'), params={'payload':'jkerihuel'}) xmlData = ET.XML(response.body) assert xmlData is not None, "expected valid XML to be returned" tokens = xmlData.findall("token") assert tokens is not None, "No token received" assert len(tokens) == 2, "2 tokens expected got %d" % len(tokens) number = 0 for token in tokens: assert "type" in token.attrib, 'no type option specified: %s' % token.attrib assert token.text is not None, 'no text value for token type=%s' % token.attrib['type'] if "type" in token.attrib: if token.attrib["type"] == "session": number += 1 if token.attrib["type"] == "salt" : number += 1 assert number == 2, "Invalid token types: got %d on 2" % number salt = xmlData.find("salt") assert salt is not None, "No salt received" def test_token_no_login(self): """ Test token function with XML payload without username. """ response = self.app.post(url(controller='authenticate', action='token'), params={'payload':''}) xmlData = ET.XML(response.body) assert xmlData is not None, "expected valid XML to be returned" error = xmlData.find('error') assert error is not None code = error.attrib['code'] assert code == '417', "Invalid error code %s, expected 417" % code def test_token_no_payload(self): """ Test token with no payload. Expect error XML with code 417.""" response = self.app.post(url(controller='authenticate', action='token'), params='') xmlData = ET.XML(response.body) assert xmlData is not None, "expected valid XML to be returned" error = xmlData.find('error') assert error is not None code = error.attrib['code'] assert code == '417', "Invalid error code %s, expected 417" % code openchange-2.0/mapiproxy/services/ocsmanager/ocsmanager/tests/functional/test_notification.py000066400000000000000000000003301223057412600331740ustar00rootroot00000000000000from ocsmanager.tests import * class TestNotificationController(TestController): def test_index(self): response = self.app.get(url(controller='notification', action='index')) # Test response... openchange-2.0/mapiproxy/services/ocsmanager/ocsmanager/tests/functional/test_rpcproxy.py000066400000000000000000000003201223057412600323730ustar00rootroot00000000000000from ocsmanager.tests import * class TestRpcproxyController(TestController): def test_index(self): response = self.app.get(url(controller='rpcproxy', action='index')) # Test response... openchange-2.0/mapiproxy/services/ocsmanager/ocsmanager/tests/test_models.py000066400000000000000000000000001223057412600276210ustar00rootroot00000000000000openchange-2.0/mapiproxy/services/ocsmanager/ocsmanager/websetup.py000066400000000000000000000006541223057412600260120ustar00rootroot00000000000000"""Setup the ocsmanager application""" import logging import pylons.test from ocsmanager.config.environment import load_environment log = logging.getLogger(__name__) def setup_app(command, conf, vars): """Place any commands to setup ocsmanager here""" # Don't reload the app if it was loaded under the testing environment if not pylons.test.pylonsapp: load_environment(conf.global_conf, conf.local_conf) openchange-2.0/mapiproxy/services/ocsmanager/production.ini000066400000000000000000000031651223057412600243520ustar00rootroot00000000000000# # ocsmanager - Pylons development environment configuration # # The %(here)s variable will be replaced with the parent directory of this file # [DEFAULT] debug = true # Uncomment and replace with the address which should receive any error reports #email_to = you@yourdomain.com smtp_server = localhost error_email_from = paste@localhost [server:main] use = egg:Paste#http host = 127.0.0.1 port = 5000 [app:main] use = egg:ocsmanager full_stack = true static_files = true cache_dir = %(here)s/data beaker.session.key = ocsmanager beaker.session.secret = somesecret # If you'd like to fine-tune the individual locations of the cache data dirs # for the Cache data, or the Session saves, un-comment the desired settings # here: #beaker.cache.data_dir = %(here)s/data/cache #beaker.session.data_dir = %(here)s/data/sessions # WARNING: *THE LINE BELOW MUST BE UNCOMMENTED ON A PRODUCTION ENVIRONMENT* # Debug mode will enable the interactive debugging tool, allowing ANYONE to # execute malicious code after an exception is raised. set debug = false # Logging configuration [loggers] keys = root, routes, ocsmanager [handlers] keys = console [formatters] keys = generic [logger_root] level = INFO handlers = console [logger_routes] level = INFO handlers = qualname = routes.middleware # "level = DEBUG" logs the route matched and routing variables. [logger_ocsmanager] level = DEBUG handlers = qualname = ocsmanager [handler_console] class = StreamHandler args = (sys.stderr,) level = NOTSET formatter = generic [formatter_generic] format = %(asctime)s,%(msecs)03d %(levelname)-5.5s [%(name)s] [%(threadName)s] %(message)s datefmt = %H:%M:%S openchange-2.0/mapiproxy/services/ocsmanager/setup.cfg000066400000000000000000000011251223057412600232760ustar00rootroot00000000000000[egg_info] tag_build = dev tag_svn_revision = true [easy_install] find_links = http://www.pylonshq.com/download/ [nosetests] with-pylons = test.ini # Babel configuration [compile_catalog] domain = ocsmanager directory = ocsmanager/i18n statistics = true [extract_messages] add_comments = TRANSLATORS: output_file = ocsmanager/i18n/ocsmanager.pot width = 80 [init_catalog] domain = ocsmanager input_file = ocsmanager/i18n/ocsmanager.pot output_dir = ocsmanager/i18n [update_catalog] domain = ocsmanager input_file = ocsmanager/i18n/ocsmanager.pot output_dir = ocsmanager/i18n previous = true openchange-2.0/mapiproxy/services/ocsmanager/setup.py000066400000000000000000000021131223057412600231650ustar00rootroot00000000000000try: from setuptools import setup, find_packages except ImportError: from ez_setup import use_setuptools use_setuptools() from setuptools import setup, find_packages setup( name='ocsmanager', version='0.1', description='OpenChange Service Manager', author='Julien Kerihuel', author_email='j.kerihuel@openchange.org', url='http://www.openchange.org', install_requires=[ "Pylons>=0.10", ], setup_requires=["PasteScript>=1.6.3"], packages=find_packages(exclude=['ez_setup']), include_package_data=True, test_suite='nose.collector', package_data={'ocsmanager': ['i18n/*/LC_MESSAGES/*.mo']}, #message_extractors={'ocsmanager': [ # ('**.py', 'python', None), # ('templates/**.mako', 'mako', {'input_encoding': 'utf-8'}), # ('public/**', 'ignore', None)]}, zip_safe=False, paster_plugins=['PasteScript', 'Pylons'], entry_points=""" [paste.app_factory] main = ocsmanager.config.middleware:make_app [paste.app_install] main = pylons.util:PylonsInstaller """, ) openchange-2.0/mapiproxy/services/ocsmanager/test.ini000066400000000000000000000007751223057412600231470ustar00rootroot00000000000000# # ocsmanager - Pylons testing environment configuration # # The %(here)s variable will be replaced with the parent directory of this file # [DEFAULT] debug = true # Uncomment and replace with the address which should receive any error reports #email_to = you@yourdomain.com smtp_server = localhost error_email_from = paste@localhost [server:main] use = egg:Paste#http host = 127.0.0.1 port = 5000 [app:main] use = config:development.ini # Add additional test specific configuration options as necessary. openchange-2.0/mapiproxy/services/plugins/000077500000000000000000000000001223057412600210205ustar00rootroot00000000000000openchange-2.0/mapiproxy/services/plugins/dovecot/000077500000000000000000000000001223057412600224635ustar00rootroot00000000000000openchange-2.0/mapiproxy/services/plugins/dovecot/ocsmanager-plugin.c000066400000000000000000000173061223057412600262510ustar00rootroot00000000000000/* OpenChange Service Manager Plugin for Dovecot OpenChange Project Copyright (C) Julien Kerihuel 2011. This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see . */ /* Step 1. Compile the plugin gcc -fPIC -shared -DHAVE_CONFIG_H `echo $DOVECOT_CFLAGS $LIBDOVECOT_INCLUDE $LIBDOVECOT_STORAGE_INCLUDE` ocsmanager-plugin.c -L/usr/lib/dovecot/modules/ -l15_notify_plugin -o ocsmanager_plugin.so Step 2: Install the plugin sudo cp ocsmanager_plugin.so /usr/lib/dovecot/modules/ocsmanager_plugin.so Step 3: Configure ocsmanager plugin options in dovecot.conf plugin { ocsmanager_backend = SOGo ocsmanager_newmail = /home/openchange/openchange/sogo-good/mapiproxy/services/client/newmail.py ocsmanager_config = /home/openchange/openchange/sogo-good/mapiproxy/services/client/ocsmanager.cfg } Step 4: Restart dovecot */ #include "ocsmanager-plugin.h" #define OCSMANAGER_USER_CONTEXT(obj) \ MODULE_CONTEXT(obj, ocsmanager_user_module) enum ocsmanager_field { OCSMANAGER_FIELD_UID = 0x1, OCSMANAGER_FIELD_BOX = 0x2, OCSMANAGER_FIELD_MSGID = 0x4, OCSMANAGER_FIELD_PSIZE = 0x8, OCSMANAGER_FIELD_VSIZE = 0x10, OCSMANAGER_FIELD_FLAGS = 0x20, OCSMANAGER_FIELD_FROM = 0x40, OCSMANAGER_FIELD_SUBJECT = 0x80 }; #define OCSMANAGER_DEFAULT_FIELDS \ (OCSMANAGER_FIELD_UID | OCSMANAGER_FIELD_BOX | \ OCSMANAGER_FIELD_MSGID | OCSMANAGER_FIELD_PSIZE) enum ocsmanager_event { OCSMANAGER_EVENT_DELETE = 0x1, OCSMANAGER_EVENT_UNDELETE = 0x2, OCSMANAGER_EVENT_EXPUNGE = 0x4, OCSMANAGER_EVENT_SAVE = 0x8, OCSMANAGER_EVENT_COPY = 0x10, OCSMANAGER_EVENT_MAILBOX_CREATE = 0x20, OCSMANAGER_EVENT_MAILBOX_DELETE = 0x40, OCSMANAGER_EVENT_MAILBOX_RENAME = 0x80, OCSMANAGER_EVENT_FLAG_CHANGE = 0x100 }; #define OCSMANAGER_DEFAULT_EVENTS (OCSMANAGER_EVENT_SAVE) struct ocsmanager_user { union mail_user_module_context module_ctx; enum ocsmanager_field fields; enum ocsmanager_event events; char *username; const char *backend; const char *bin; const char *config; }; struct ocsmanager_message { struct ocsmanager_message *prev; struct ocsmanager_message *next; enum ocsmanager_event event; bool ignore; uint32_t uid; char *destination_folder; char *username; const char *backend; char *bin; char *config; }; struct ocsmanager_mail_txn_context { pool_t pool; struct ocsmanager_message *messages; struct ocsmanager_message *messages_tail; }; static MODULE_CONTEXT_DEFINE_INIT(ocsmanager_user_module, &mail_user_module_register); static void ocsmanager_mail_user_created(struct mail_user *user) { struct ocsmanager_user *ocsuser; const char *str; i_debug("ocsmanager_mail_user_created"); i_debug("username = %s", user->username); ocsuser = p_new(user->pool, struct ocsmanager_user, 1); MODULE_CONTEXT_SET(user, ocsmanager_user_module, ocsuser); ocsuser->fields = OCSMANAGER_DEFAULT_FIELDS; ocsuser->events = OCSMANAGER_DEFAULT_EVENTS; ocsuser->username = p_strdup(user->pool, user->username); str = mail_user_plugin_getenv(user, "ocsmanager_backend"); if (!str) { i_fatal("Missing ocsmanager_backend parameter in dovecot.conf"); } ocsuser->backend = str; str = mail_user_plugin_getenv(user, "ocsmanager_newmail"); if (!str) { i_fatal("Missing ocsmanager_newmail parameter in dovecot.conf"); } ocsuser->bin = str; str = mail_user_plugin_getenv(user, "ocsmanager_config"); if (!str) { i_fatal("Missing ocsmanager_config parameter in dovecot.conf"); } ocsuser->config = str; } static void ocsmanager_mail_save(void *txn, struct mail *mail) { i_debug("ocsmanager_mail_save"); i_debug("message UID = %d\n", mail->uid); } static void ocsmanager_mail_copy(void *txn, struct mail *src, struct mail *dst) { struct ocsmanager_mail_txn_context *ctx = (struct ocsmanager_mail_txn_context *) txn; struct ocsmanager_user *mctx = OCSMANAGER_USER_CONTEXT(dst->box->storage->user); struct ocsmanager_message *msg; int i; if (strcmp(src->box->storage->name, "raw") == 0) { /* special case: lda/lmtp is saving a mail */ msg = p_new(ctx->pool, struct ocsmanager_message, 1); msg->event = OCSMANAGER_EVENT_COPY; msg->ignore = FALSE; msg->username = p_strdup(ctx->pool, mctx->username); msg->backend = p_strdup(ctx->pool, mctx->backend); msg->destination_folder = p_strdup(ctx->pool, mailbox_get_name(dst->box)); msg->bin = p_strdup(ctx->pool, mctx->bin); msg->config = p_strdup(ctx->pool, mctx->config); /* FIXME: Quick hack of the night */ msg->username[0] = toupper(msg->username[0]); for (i = 0; i < strlen(msg->destination_folder); i++) { msg->destination_folder[i] = tolower(msg->destination_folder[i]); } DLLIST2_APPEND(&ctx->messages, &ctx->messages_tail, msg); } } static void *ocsmanager_mail_transaction_begin(struct mailbox_transaction_context *t ATTR_UNUSED) { pool_t pool; struct ocsmanager_mail_txn_context *ctx; pool = pool_alloconly_create("ocsmanager", 2048); ctx = p_new(pool, struct ocsmanager_mail_txn_context, 1); ctx->pool = pool; return ctx; } static void ocsmanager_mail_transaction_commit(void *txn, struct mail_transaction_commit_changes *changes) { struct ocsmanager_mail_txn_context *ctx = (struct ocsmanager_mail_txn_context *)txn; uint32_t uid; struct ocsmanager_message *msg; unsigned int n = 0; struct seq_range_iter iter; char *command; seq_range_array_iter_init(&iter, &changes->saved_uids); for (msg = ctx->messages; msg != NULL; msg = msg->next) { if (msg->event == OCSMANAGER_EVENT_COPY) { if (!seq_range_array_iter_nth(&iter, n++, &uid)) uid = 0; msg->uid = uid; i_debug("# uid = %d", msg->uid); i_debug("# folder = %s", msg->destination_folder); i_debug("# username = %s", msg->username); i_debug("# backend = %s", msg->backend); /* FIXME: I'm ashamed but I'm tired */ command = p_strdup_printf(ctx->pool, "python %s --config %s --backend %s --user %s --folder %s --msgid %d", msg->bin, msg->config, msg->backend, msg->username, msg->destination_folder, msg->uid); system(command); } } i_assert(!seq_range_array_iter_nth(&iter, n, &uid)); pool_unref(&ctx->pool); } static void ocsmanager_mail_transaction_rollback(void *txn) { struct ocsmanager_mail_txn_context *ctx = (struct ocsmanager_mail_txn_context *) txn; pool_unref(&ctx->pool); } static const struct notify_vfuncs ocsmanager_vfuncs = { .mail_transaction_begin = ocsmanager_mail_transaction_begin, .mail_save = ocsmanager_mail_save, .mail_copy = ocsmanager_mail_copy, .mail_transaction_commit = ocsmanager_mail_transaction_commit, .mail_transaction_rollback = ocsmanager_mail_transaction_rollback, }; static struct notify_context *ocsmanager_ctx; static struct mail_storage_hooks ocsmanager_mail_storage_hooks = { .mail_user_created = ocsmanager_mail_user_created }; void ocsmanager_plugin_init(struct module *module) { i_debug("oscmanager_plugin_init"); ocsmanager_ctx = notify_register(&ocsmanager_vfuncs); mail_storage_hooks_add(module, &ocsmanager_mail_storage_hooks); } void ocsmanager_plugin_deinit(void) { i_debug("oscmanager_plugin_deinit"); mail_storage_hooks_remove(&ocsmanager_mail_storage_hooks); notify_unregister(ocsmanager_ctx); } const char *ocsmanager_plugin_dependencies[] = { "notify", NULL }; openchange-2.0/mapiproxy/services/plugins/dovecot/ocsmanager-plugin.h000066400000000000000000000024471223057412600262560ustar00rootroot00000000000000/* OpenChange Service Manager Plugin for Dovecot OpenChange Project Copyright (C) Julien Kerihuel 2011. This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see . */ #ifndef __OCSMANAGER_PLUGIN_H #define __OCSMANAGER_PLUGIN_H #include "lib.h" #include "llist.h" #include "array.h" #include "config.h" #include "module-dir.h" #include "mail-user.h" #include "mail-storage-private.h" #include "mailbox-list-private.h" #include "notify-plugin.h" #include #include extern const char *ocsmanager_plugin_dependencies[]; const char *ocsmanager_plugin_version = DOVECOT_VERSION; void ocsmanager_plugin_init(struct module *); void ocsmanager_plugin_deinit(void); #endif /* __OCSMANAGER_PLUGIN_H */ openchange-2.0/mapiproxy/services/setup.sh000077500000000000000000000020541223057412600210370ustar00rootroot00000000000000#!/bin/bash echo '############################################################' echo 'Run the script from local directory' echo 'Also ensure OpenChange is compiled prior running the script' echo '############################################################' echo '[*] Installing virtualenv' sudo easy_install virtualenv echo '[*] Creating the isolated python environment' virtualenv mydevenv echo '[*] Installing Pylons 1.0 in mydevenv' curl http://pylonshq.com/download/1.0/go-pylons.py | python - mydevenv echo '[*] Copying OpenChange bindings in mydevenv' cp -rfi ../../python/openchange mydevenv/lib/python2.7/site-packages/ echo '[*] Activating the virtual environment' source mydevenv/bin/activate echo '[*] Reconfiguring ocsmanager' cd ocsmanager python setup.py develop echo '@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@' echo 'To run the ocsmanager service:' echo 'source mydevenv/bin/activate' echo 'cd ocsmanager' echo 'paster serve --reload development.ini' echo '@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@' openchange-2.0/mapiproxy/services/utils/000077500000000000000000000000001223057412600204775ustar00rootroot00000000000000openchange-2.0/mapiproxy/services/utils/genpass.py000077500000000000000000000005231223057412600225140ustar00rootroot00000000000000#!/usr/bin/python import os import sys import hashlib from base64 import urlsafe_b64encode as encode def main(): if len(sys.argv) != 2: print '%s password' % (sys.argv[0]) salt = os.urandom(4) h = hashlib.sha1(sys.argv[0]) h.update(salt) print "{SSHA}" + encode(h.digest() + salt) sys.exit() if __name__ == "__main__": main() openchange-2.0/mapiproxy/services/web/000077500000000000000000000000001223057412600201145ustar00rootroot00000000000000openchange-2.0/mapiproxy/services/web/rpcproxy/000077500000000000000000000000001223057412600220025ustar00rootroot00000000000000openchange-2.0/mapiproxy/services/web/rpcproxy/rpcproxy.conf000066400000000000000000000010571223057412600245420ustar00rootroot00000000000000## The extremely high timeout is required by outlook KeepAliveTimeout 120 WSGILazyInitialization On WSGIPythonPath /usr/lib/openchange/web/rpcproxy SetEnv RPCPROXY_LOGLEVEL INFO SetEnv NTLMAUTHHANDLER_WORKDIR /var/cache/ntlmauthhandler SetEnv SAMBA_HOST 127.0.0.1 WSGIPassAuthorization On WSGIProcessGroup %{GLOBAL} WSGIScriptAlias /rpc/rpcproxy.dll /usr/lib/openchange/web/rpcproxy/rpcproxy.wsgi WSGIScriptAlias /rpcwithcert/rpcproxy.dll /usr/lib/openchange/web/rpcproxy/rpcproxy.wsgi openchange-2.0/mapiproxy/services/web/rpcproxy/rpcproxy.wsgi000066400000000000000000000023041223057412600245620ustar00rootroot00000000000000#!/usr/bin/python # # rpcproxy.wsgi -- OpenChange RPC-over-HTTP implementation # # Copyright (C) 2012 Julien Kerihuel # Wolfgang Sourdeau # # This program is free software; you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by # the Free Software Foundation; either version 3 of the License, or # (at your option) any later version. # # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program. If not, see . # # this is the WSGI starting point for rpcproxy import logging import os from openchange.web.auth.NTLMAuthHandler import * from rpcproxy.RPCProxyApplication import * SAMBA_HOST = "127.0.0.1" LOG_LEVEL = logging.INFO application = NTLMAuthHandler(RPCProxyApplication(samba_host=SAMBA_HOST, log_level=LOG_LEVEL)) openchange-2.0/mapiproxy/services/web/rpcproxy/rpcproxy/000077500000000000000000000000001223057412600236705ustar00rootroot00000000000000openchange-2.0/mapiproxy/services/web/rpcproxy/rpcproxy/RPCProxyApplication.py000066400000000000000000000100131223057412600301070ustar00rootroot00000000000000# RPCProxyApplication.py -- OpenChange RPC-over-HTTP implementation # # Copyright (C) 2012 Wolfgang Sourdeau # # This program is free software; you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by # the Free Software Foundation; either version 3 of the License, or # (at your option) any later version. # # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program. If not, see . # import logging from errno import EEXIST from os import umask, mkdir, rmdir, listdir, getpid from os.path import join from uuid import uuid4 from shutil import rmtree import sys from channels import RPCProxyInboundChannelHandler,\ RPCProxyOutboundChannelHandler class RPCProxyApplication(object): def __init__(self, samba_host, log_level=logging.DEBUG): # we keep a reference to the rmtree function until our instance is # deleted self.rmtree = rmtree dirname = "/tmp/rpcproxy" try: mkdir(dirname) except: pass self.sockets_dir = dirname print >>sys.stderr, "RPCProxy started" # has_socket_dir = False # umask(0077) # while not has_socket_dir: # # leafname = "rpcproxy-%s" % str(uuid4()) # leafname = "rpcproxy" # % getpid() # dirname = "/tmp/%s" % leafname # try: # mkdir(dirname) # has_socket_dir = True # self.sockets_dir = dirname # except OSError, e: # if e.errno != EEXIST: # raise self.samba_host = samba_host self.log_level = log_level def __del__(self): # self.rmtree(self.sockets_dir) pass def __call__(self, environ, start_response): if "REQUEST_METHOD" in environ: method = environ["REQUEST_METHOD"] method_name = "_do_" + method if hasattr(self, method_name): if "wsgi.errors" in environ: log_stream = environ["wsgi.errors"] else: log_stream = sys.stderr logHandler = logging.StreamHandler(log_stream) fmter = logging.Formatter("[%(process)d:%(name)s] %(levelname)s: %(message)s") logHandler.setFormatter(fmter) if "REMOTE_PORT" in environ: rmt_port = environ["REMOTE_PORT"] else: rmt_port = "" logger = logging.Logger(method + ":" + rmt_port) logger.setLevel(self.log_level) logger.addHandler(logHandler) # logger.set_name(method) channel_method = getattr(self, method_name) channel = channel_method(logger) response = channel.sequence(environ, start_response) else: response = self._unsupported_method(environ, start_response) else: response = self._unsupported_method(environ, start_response) return response @staticmethod def _unsupported_method(environ, start_response): msg = "Unsupported method" start_response("501 Not Implemented", [("Content-Type", "text/plain"), ("Content-length", str(len(msg)))]) return [msg] def _do_RPC_IN_DATA(self, logger): return RPCProxyInboundChannelHandler(self.sockets_dir, logger) def _do_RPC_OUT_DATA(self, logger): return RPCProxyOutboundChannelHandler(self.sockets_dir, self.samba_host, logger) openchange-2.0/mapiproxy/services/web/rpcproxy/rpcproxy/__init__.py000066400000000000000000000000001223057412600257670ustar00rootroot00000000000000openchange-2.0/mapiproxy/services/web/rpcproxy/rpcproxy/channels.py000066400000000000000000000474501223057412600260470ustar00rootroot00000000000000# channels.py -- OpenChange RPC-over-HTTP implementation # # Copyright (C) 2012 Julien Kerihuel # Wolfgang Sourdeau # # This program is free software; you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by # the Free Software Foundation; either version 3 of the License, or # (at your option) any later version. # # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program. If not, see . # import os from select import poll, POLLIN, POLLHUP from socket import socket, AF_INET, AF_UNIX, SOCK_STREAM, MSG_WAITALL, \ SHUT_RDWR, error as socket_error from struct import pack, unpack_from import sys from time import time, sleep from uuid import UUID # from rpcproxy.RPCH import RPCH, RTS_FLAG_ECHO from openchange.utils.fdunix import send_socket, receive_socket from openchange.utils.packets import RTS_CMD_CONNECTION_TIMEOUT, \ RTS_CMD_VERSION, RTS_CMD_RECEIVE_WINDOW_SIZE, \ RTS_CMD_CONNECTION_TIMEOUT, RTS_FLAG_ECHO, RTS_FLAG_OTHER_CMD, \ RTS_CMD_DATA_LABELS, RPCPacket, RPCRTSPacket, RPCRTSOutPacket """Documentation: 1. "Connection Establishment" sequence (from RPCH.pdf, 3.2.1.5.3.1) client -> IN request -> proxy in # server -> legacy server response -> proxy in # server -> legacy server response -> proxy out client -> Out request -> proxy out client -> A1 -> proxy out client -> B1 -> proxy in # proxy out -> A2 -> server proxy out -> OUT channel response -> client # proxy in -> B2 -> server proxy out -> A3 -> client # server -> C1 -> proxy out # server -> B3 -> proxy in proxy out -> C2 -> client 2. internal unix socket protocols Note: OUT proxy is always the server * establishing virtual connection OUT proxy listens on unix socket IN proxy connects to OUT proxy IN -> OUT: "IP" IN -> OUT: in_window_size IN -> OUT: in_conn_timeout OUT -> IN: sends connection to OpenChange (TODO: socket close at this point?) * channel recycling (unused yet, hypothethical) When new OUT conn arrives: new OUT -> OUT: "OP" OUT -> new OUT: OUT listening socket (fdunix) OUT -> new OUT: IN socket (fdunix) OUT -> new OUT: oc socket (fdunix) close OUT socket locally """ # those id must have the same length INBOUND_PROXY_ID = "IP" OUTBOUND_PROXY_ID = "OP" def _safe_close(socket_obj): try: socket_obj.shutdown(SHUT_RDWR) socket_obj.close() except: pass class RPCProxyChannelHandler(object): def __init__(self, sockets_dir, logger): self.sockets_dir = sockets_dir self.logger = logger self.unix_socket = None self.client_socket = None # placeholder for wsgi.input self.bytes_read = 0 self.bytes_written = 0 self.startup_time = time() self.channel_cookie = None self.connection_cookie = None def handle_echo_request(self, environ, start_response): self.logger.debug("handling echo request") packet = RPCRTSOutPacket() packet.flags = RTS_FLAG_ECHO data = packet.make() self.bytes_written = self.bytes_written + packet.size start_response("200 Success", [("Content-length", "%d" % packet.size), ("Content-Type", "application/rpc")]) return [data] def log_connection_stats(self): self.logger.debug("channel kept alive during %f secs;" " %d bytes received; %d bytes sent" % ((time() - self.startup_time), self.bytes_read, self.bytes_written)) class RPCProxyInboundChannelHandler(RPCProxyChannelHandler): def __init__(self, sockets_dir, logger): RPCProxyChannelHandler.__init__(self, sockets_dir, logger) self.oc_conn = None self.window_size = 0 self.conn_timeout = 0 self.client_keepalive = 0 self.association_group_id = None def _receive_conn_b1(self): # CONN/B1 RTS PDU (TODO: validation) # receive the cookie self.logger.debug("receiving CONN/B1") packet = RPCPacket.from_file(self.client_socket, self.logger) if not isinstance(packet, RPCRTSPacket): raise Exception("Unexpected non-rts packet received for CONN/B1") self.logger.debug("packet headers = " + packet.pretty_dump()) self.connection_cookie = str(UUID(bytes=packet.commands[1]["Cookie"])) self.channel_cookie = str(UUID(bytes=packet.commands[2]["Cookie"])) self.client_keepalive = packet.commands[4]["ClientKeepalive"] self.association_group_id = str(UUID(bytes=packet.commands[5] \ ["AssociationGroupId"])) self.bytes_read = self.bytes_read + packet.size def _connect_to_OUT_channel(self): # connect as a client to the cookie unix socket socket_name = os.path.join(self.sockets_dir, self.connection_cookie) self.logger.debug("connecting to OUT via unix socket '%s'" % socket_name) unix_socket = socket(AF_UNIX, SOCK_STREAM) connected = False attempt = 0 while not connected and attempt < 10: try: attempt = attempt + 1 unix_socket.connect(socket_name) self.unix_socket = unix_socket connected = True except socket_error: self.logger.debug("handling socket.error: %s" % str(sys.exc_info())) self.logger.warn("reattempting to connect to OUT" " channel... (%d/10)" % attempt) sleep(1) if connected: self.logger.debug("connection succeeded") self.logger.debug("sending window size and connection timeout") # identify ourselves as the IN proxy unix_socket.sendall(INBOUND_PROXY_ID) # send window_size to 256Kib (max size allowed) # and conn_timeout (in milliseconds, max size allowed) unix_socket.sendall(pack("= 128: self.logger.debug("processing IN channel request") self.client_socket = environ["wsgi.input"] self._receive_conn_b1() connected = self._connect_to_OUT_channel() if connected: start_response("200 Success", [("Content-Type", "application/rpc"), ("Content-length", "0")]) self._runloop() # shutting down sockets self.logger.debug("notifying OUT channel of shutdown") try: self.unix_socket.sendall(INBOUND_PROXY_ID + "q") _safe_close(self.unix_socket) self.logger.debug("OUT channel successfully notified") except socket_error: self.logger.debug("(OUT channel already shutdown the unix socket)") # OUT channel already closed the connection pass _safe_close(self.oc_conn) self.log_connection_stats() self.logger.debug("exiting from main sequence") # TODO: error handling start_response("200 Success", [("Content-length", "0"), ("Content-Type", "application/rpc")]) yield "" else: raise Exception("This content-length is not handled") # OLD CODE # msg = "RPC_IN_DATA method" # content_length = environ["CONTENT_LENGTH"] # # echo request # if content_length <= 10: # pass # start_response("200 OK", [("Content-Type", "text/plain"), # ("Content-length", "%s" % len(msg))]) # return [msg] class RPCProxyOutboundChannelHandler(RPCProxyChannelHandler): def __init__(self, sockets_dir, samba_host, logger): RPCProxyChannelHandler.__init__(self, sockets_dir, logger) self.samba_host = samba_host self.oc_conn = None self.in_window_size = 0 self.in_conn_timeout = 0 def _receive_conn_a1(self): # receive the cookie # TODO: validation of CONN/A1 self.logger.debug("receiving CONN/A1") packet = RPCPacket.from_file(self.client_socket, self.logger) if not isinstance(packet, RPCRTSPacket): raise Exception("Unexpected non-rts packet received for CONN/A1") self.logger.debug("packet headers = " + packet.pretty_dump()) self.connection_cookie = str(UUID(bytes=packet.commands[1]["Cookie"])) self.channel_cookie = str(UUID(bytes=packet.commands[2]["Cookie"])) def _send_conn_a3(self): self.logger.debug("sending CONN/A3 to client") # send the A3 response to the client packet = RPCRTSOutPacket(self.logger) # we set the min timeout value allowed, as we would actually need # either configuration values from Apache or from some config file packet.add_command(RTS_CMD_CONNECTION_TIMEOUT, 120000) self.bytes_written = self.bytes_written + packet.size return packet.make() def _send_conn_c2(self): self.logger.debug("sending CONN/C2 to client") # send the C2 response to the client packet = RPCRTSOutPacket(self.logger) # we set the min timeout value allowed, as we would actually need # either configuration values from Apache or from some config file packet.add_command(RTS_CMD_VERSION, 1) packet.add_command(RTS_CMD_RECEIVE_WINDOW_SIZE, self.in_window_size) packet.add_command(RTS_CMD_CONNECTION_TIMEOUT, self.in_conn_timeout) self.bytes_written = self.bytes_written + packet.size return packet.make() def _setup_oc_socket(self): # create IP connection to OpenChange self.logger.debug("connecting to %s:1024" % self.samba_host) connected = False while not connected: try: oc_conn = socket(AF_INET, SOCK_STREAM) oc_conn.connect((self.samba_host, 1024)) connected = True except socket_error: self.logger.debug("failure to connect, retrying...") sleep(1) self.logger.debug("connection to OC succeeeded (fileno=%d)" % oc_conn.fileno()) self.oc_conn = oc_conn def _setup_channel_socket(self): # TODO: add code to create missing socket dir # create the corresponding unix socket if not os.access(self.sockets_dir, os.R_OK | os.W_OK | os.X_OK): raise IOError("Socket directory '%s' does not exist or has the" " wrong permissions" % self.sockets_dir) socket_name = os.path.join(self.sockets_dir, self.connection_cookie) self.logger.debug("creating unix socket '%s'" % socket_name) if os.access(socket_name, os.F_OK): os.remove(socket_name) server_socket = socket(AF_UNIX, SOCK_STREAM) server_socket.bind(socket_name) server_socket.listen(2) self.server_socket = server_socket def _wait_IN_channel(self): self.logger.debug("waiting for connection from IN") # wait for the IN channel to connect as a B1 should be occurring # on the other side fd_pool = poll() fd_pool.register(self.server_socket.fileno(), POLLIN) # wait for 10 seconds data = fd_pool.poll(1000.0) if data is not None: unix_socket = self.server_socket.accept()[0] self.logger.debug("connection established with IN channel") data = unix_socket.recv(2, MSG_WAITALL) if data != INBOUND_PROXY_ID: raise IOError("connection must be from IN proxy (1): /%s/" % data) self.logger.debug("receiving window size + conn_timeout") # receive the WindowSize + ConnectionTimeout (self.in_window_size, self.in_conn_timeout) = \ unpack_from(" 0: # FIXME: notify IN channel? self.logger.debug("connection closed from OC") status = False elif event_no & POLLIN > 0: oc_packet = RPCPacket.from_file(self.oc_conn, self.logger) self.logger.debug("packet headers = " + oc_packet.pretty_dump()) if isinstance(oc_packet, RPCRTSPacket): raise Exception("Unexpected rts packet received") self.logger.debug("sending data to client") self.bytes_read = self.bytes_read + oc_packet.size server_data = oc_packet.data elif fd == unix_fd: if event_no & POLLHUP > 0: # FIXME: notify IN channel? self.logger.debug("connection closed from IN channel") status = False self.logger.debug("ignored event '%d' on unix socket (closing)" % event_no) # FIXME: we should listen to what the IN channel has to say status = False else: raise Exception("invalid poll event: %s" % str(data)) return (status, server_data) def _runloop(self): self.logger.debug("runloop") unix_fd = self.unix_socket.fileno() oc_fd = self.oc_conn.fileno() fd_pool = poll() fd_pool.register(unix_fd, POLLIN) fd_pool.register(oc_fd, POLLIN) # Listen for data from the listener status = True while status: self.logger.debug("step in loop") chunks = fd_pool.poll(2000.0) if len(chunks) == 0: # send ping packets? pass else: for data in chunks: event_status, server_data \ = self._process_server_event(unix_fd, oc_fd, data) if server_data is not None: self.bytes_written \ = self.bytes_written + len(server_data) self.logger.debug("data sent") yield server_data status = status and event_status def _terminate_sockets(self): socket_name = os.path.join(self.sockets_dir, self.connection_cookie) self.logger.debug("removing and closing unix socket '%s'" % socket_name) if os.access(socket_name, os.F_OK): os.remove(socket_name) if self.unix_socket is not None: _safe_close(self.unix_socket) _safe_close(self.server_socket) _safe_close(self.oc_conn) def sequence(self, environ, start_response): self.logger.debug("processing request") if "REMOTE_PORT" in environ: self.logger.debug("remote port = %s" % environ["REMOTE_PORT"]) # self.logger.debug("path: ' + self.path) content_length = int(environ["CONTENT_LENGTH"]) self.logger.debug("request size is %d" % content_length) if content_length <= 0x10: # echo request for data in self.handle_echo_request(environ, start_response): yield data elif content_length == 76: self.logger.debug("processing nonreplacement Out channel" "request") self.client_socket = environ["wsgi.input"] self._receive_conn_a1() # Content-length = 1 Gib start_response("200 Success", [("Content-Type", "application/rpc"), ("Content-length", "%d" % (1024 ** 3))]) yield self._send_conn_a3() self._setup_oc_socket() self._setup_channel_socket() connected = self._wait_IN_channel() if connected: yield self._send_conn_c2() self.logger.debug("total bytes sent yet: %d" % self.bytes_written) for data in self._runloop(): yield data self._terminate_sockets() elif content_length == 120: # Out channel request: replacement OUT channel raise Exception("Replacement OUT channel request not handled") else: raise Exception("This content-length is not handled") self.log_connection_stats() self.logger.debug("exiting from main sequence") openchange-2.0/mapiproxy/services/web/rpcproxy/rpcproxy/utils.py000066400000000000000000000022031223057412600253770ustar00rootroot00000000000000# utils.py -- OpenChange RPC-over-HTTP implementation # # Copyright (C) 2012 Wolfgang Sourdeau # # This program is free software; you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by # the Free Software Foundation; either version 3 of the License, or # (at your option) any later version. # # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program. If not, see . # import json def prettify_dict(adict): """This method makes use of the JSON API to return a properly indented representation of a dict. """ def _unhandled_objects(obj): return str(obj) lines = json.dumps(adict, default=_unhandled_objects, sort_keys=True, indent=4) return "%s\n" % "\n".join([l.rstrip() for l in lines.splitlines()]) openchange-2.0/mapiproxy/services/web/rpcproxy/setup.py000077500000000000000000000006521223057412600235220ustar00rootroot00000000000000#!/usr/bin/python from distutils.core import setup setup(name="rpcproxy", version="1.0", description="A RPC-over-HTTP implementation for Samba, using wsgi", author="Julien Kerihuel, Wolfgang Sourdeau", author_email="j.kerihuel@openchange.org, wsourdeau@inverse.ca", url="http://www.openchange.org/", scripts=["rpcproxy.wsgi"], packages=["rpcproxy"], requires=["openchange"] ) openchange-2.0/missing000077500000000000000000000254061223057412600150720ustar00rootroot00000000000000#! /bin/sh # Common stub for a few missing GNU programs while installing. scriptversion=2005-06-08.21 # Copyright (C) 1996, 1997, 1999, 2000, 2002, 2003, 2004, 2005 # Free Software Foundation, Inc. # Originally by Fran,cois Pinard , 1996. # This program is free software; you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by # the Free Software Foundation; either version 2, or (at your option) # any later version. # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # You should have received a copy of the GNU General Public License # along with this program; if not, write to the Free Software # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA # 02110-1301, USA. # As a special exception to the GNU General Public License, if you # distribute this file as part of a program that contains a # configuration script generated by Autoconf, you may include it under # the same distribution terms that you use for the rest of that program. if test $# -eq 0; then echo 1>&2 "Try \`$0 --help' for more information" exit 1 fi run=: # In the cases where this matters, `missing' is being run in the # srcdir already. if test -f configure.ac; then configure_ac=configure.ac else configure_ac=configure.in fi msg="missing on your system" case "$1" in --run) # Try to run requested program, and just exit if it succeeds. run= shift "$@" && exit 0 # Exit code 63 means version mismatch. This often happens # when the user try to use an ancient version of a tool on # a file that requires a minimum version. In this case we # we should proceed has if the program had been absent, or # if --run hadn't been passed. if test $? = 63; then run=: msg="probably too old" fi ;; -h|--h|--he|--hel|--help) echo "\ $0 [OPTION]... PROGRAM [ARGUMENT]... Handle \`PROGRAM [ARGUMENT]...' for when PROGRAM is missing, or return an error status if there is no known handling for PROGRAM. Options: -h, --help display this help and exit -v, --version output version information and exit --run try to run the given command, and emulate it if it fails Supported PROGRAM values: aclocal touch file \`aclocal.m4' autoconf touch file \`configure' autoheader touch file \`config.h.in' automake touch all \`Makefile.in' files bison create \`y.tab.[ch]', if possible, from existing .[ch] flex create \`lex.yy.c', if possible, from existing .c help2man touch the output file lex create \`lex.yy.c', if possible, from existing .c makeinfo touch the output file tar try tar, gnutar, gtar, then tar without non-portable flags yacc create \`y.tab.[ch]', if possible, from existing .[ch] Send bug reports to ." exit $? ;; -v|--v|--ve|--ver|--vers|--versi|--versio|--version) echo "missing $scriptversion (GNU Automake)" exit $? ;; -*) echo 1>&2 "$0: Unknown \`$1' option" echo 1>&2 "Try \`$0 --help' for more information" exit 1 ;; esac # Now exit if we have it, but it failed. Also exit now if we # don't have it and --version was passed (most likely to detect # the program). case "$1" in lex|yacc) # Not GNU programs, they don't have --version. ;; tar) if test -n "$run"; then echo 1>&2 "ERROR: \`tar' requires --run" exit 1 elif test "x$2" = "x--version" || test "x$2" = "x--help"; then exit 1 fi ;; *) if test -z "$run" && ($1 --version) > /dev/null 2>&1; then # We have it, but it failed. exit 1 elif test "x$2" = "x--version" || test "x$2" = "x--help"; then # Could not run --version or --help. This is probably someone # running `$TOOL --version' or `$TOOL --help' to check whether # $TOOL exists and not knowing $TOOL uses missing. exit 1 fi ;; esac # If it does not exist, or fails to run (possibly an outdated version), # try to emulate it. case "$1" in aclocal*) echo 1>&2 "\ WARNING: \`$1' is $msg. You should only need it if you modified \`acinclude.m4' or \`${configure_ac}'. You might want to install the \`Automake' and \`Perl' packages. Grab them from any GNU archive site." touch aclocal.m4 ;; autoconf) echo 1>&2 "\ WARNING: \`$1' is $msg. You should only need it if you modified \`${configure_ac}'. You might want to install the \`Autoconf' and \`GNU m4' packages. Grab them from any GNU archive site." touch configure ;; autoheader) echo 1>&2 "\ WARNING: \`$1' is $msg. You should only need it if you modified \`acconfig.h' or \`${configure_ac}'. You might want to install the \`Autoconf' and \`GNU m4' packages. Grab them from any GNU archive site." files=`sed -n 's/^[ ]*A[CM]_CONFIG_HEADER(\([^)]*\)).*/\1/p' ${configure_ac}` test -z "$files" && files="config.h" touch_files= for f in $files; do case "$f" in *:*) touch_files="$touch_files "`echo "$f" | sed -e 's/^[^:]*://' -e 's/:.*//'`;; *) touch_files="$touch_files $f.in";; esac done touch $touch_files ;; automake*) echo 1>&2 "\ WARNING: \`$1' is $msg. You should only need it if you modified \`Makefile.am', \`acinclude.m4' or \`${configure_ac}'. You might want to install the \`Automake' and \`Perl' packages. Grab them from any GNU archive site." find . -type f -name Makefile.am -print | sed 's/\.am$/.in/' | while read f; do touch "$f"; done ;; autom4te) echo 1>&2 "\ WARNING: \`$1' is needed, but is $msg. You might have modified some files without having the proper tools for further handling them. You can get \`$1' as part of \`Autoconf' from any GNU archive site." file=`echo "$*" | sed -n 's/.*--output[ =]*\([^ ]*\).*/\1/p'` test -z "$file" && file=`echo "$*" | sed -n 's/.*-o[ ]*\([^ ]*\).*/\1/p'` if test -f "$file"; then touch $file else test -z "$file" || exec >$file echo "#! /bin/sh" echo "# Created by GNU Automake missing as a replacement of" echo "# $ $@" echo "exit 0" chmod +x $file exit 1 fi ;; bison|yacc) echo 1>&2 "\ WARNING: \`$1' $msg. You should only need it if you modified a \`.y' file. You may need the \`Bison' package in order for those modifications to take effect. You can get \`Bison' from any GNU archive site." rm -f y.tab.c y.tab.h if [ $# -ne 1 ]; then eval LASTARG="\${$#}" case "$LASTARG" in *.y) SRCFILE=`echo "$LASTARG" | sed 's/y$/c/'` if [ -f "$SRCFILE" ]; then cp "$SRCFILE" y.tab.c fi SRCFILE=`echo "$LASTARG" | sed 's/y$/h/'` if [ -f "$SRCFILE" ]; then cp "$SRCFILE" y.tab.h fi ;; esac fi if [ ! -f y.tab.h ]; then echo >y.tab.h fi if [ ! -f y.tab.c ]; then echo 'main() { return 0; }' >y.tab.c fi ;; lex|flex) echo 1>&2 "\ WARNING: \`$1' is $msg. You should only need it if you modified a \`.l' file. You may need the \`Flex' package in order for those modifications to take effect. You can get \`Flex' from any GNU archive site." rm -f lex.yy.c if [ $# -ne 1 ]; then eval LASTARG="\${$#}" case "$LASTARG" in *.l) SRCFILE=`echo "$LASTARG" | sed 's/l$/c/'` if [ -f "$SRCFILE" ]; then cp "$SRCFILE" lex.yy.c fi ;; esac fi if [ ! -f lex.yy.c ]; then echo 'main() { return 0; }' >lex.yy.c fi ;; help2man) echo 1>&2 "\ WARNING: \`$1' is $msg. You should only need it if you modified a dependency of a manual page. You may need the \`Help2man' package in order for those modifications to take effect. You can get \`Help2man' from any GNU archive site." file=`echo "$*" | sed -n 's/.*-o \([^ ]*\).*/\1/p'` if test -z "$file"; then file=`echo "$*" | sed -n 's/.*--output=\([^ ]*\).*/\1/p'` fi if [ -f "$file" ]; then touch $file else test -z "$file" || exec >$file echo ".ab help2man is required to generate this page" exit 1 fi ;; makeinfo) echo 1>&2 "\ WARNING: \`$1' is $msg. You should only need it if you modified a \`.texi' or \`.texinfo' file, or any other file indirectly affecting the aspect of the manual. The spurious call might also be the consequence of using a buggy \`make' (AIX, DU, IRIX). You might want to install the \`Texinfo' package or the \`GNU make' package. Grab either from any GNU archive site." # The file to touch is that specified with -o ... file=`echo "$*" | sed -n 's/.*-o \([^ ]*\).*/\1/p'` if test -z "$file"; then # ... or it is the one specified with @setfilename ... infile=`echo "$*" | sed 's/.* \([^ ]*\) *$/\1/'` file=`sed -n '/^@setfilename/ { s/.* \([^ ]*\) *$/\1/; p; q; }' $infile` # ... or it is derived from the source name (dir/f.texi becomes f.info) test -z "$file" && file=`echo "$infile" | sed 's,.*/,,;s,.[^.]*$,,'`.info fi # If the file does not exist, the user really needs makeinfo; # let's fail without touching anything. test -f $file || exit 1 touch $file ;; tar) shift # We have already tried tar in the generic part. # Look for gnutar/gtar before invocation to avoid ugly error # messages. if (gnutar --version > /dev/null 2>&1); then gnutar "$@" && exit 0 fi if (gtar --version > /dev/null 2>&1); then gtar "$@" && exit 0 fi firstarg="$1" if shift; then case "$firstarg" in *o*) firstarg=`echo "$firstarg" | sed s/o//` tar "$firstarg" "$@" && exit 0 ;; esac case "$firstarg" in *h*) firstarg=`echo "$firstarg" | sed s/h//` tar "$firstarg" "$@" && exit 0 ;; esac fi echo 1>&2 "\ WARNING: I can't seem to be able to run \`tar' with the given arguments. You may want to install GNU tar or Free paxutils, or check the command line arguments." exit 1 ;; *) echo 1>&2 "\ WARNING: \`$1' is needed, and is $msg. You might have modified some files without having the proper tools for further handling them. Check the \`README' file, it often tells you about the needed prerequisites for installing this package. You may also peek at any GNU archive site, in case some other package would contain this missing \`$1' program." exit 1 ;; esac exit 0 # Local variables: # eval: (add-hook 'write-file-hooks 'time-stamp) # time-stamp-start: "scriptversion=" # time-stamp-format: "%:y-%02m-%02d.%02H" # time-stamp-end: "$" # End: openchange-2.0/ndr_mapi.c000066400000000000000000002670171223057412600154360ustar00rootroot00000000000000/* OpenChange implementation. libndr mapi support Copyright (C) Julien Kerihuel 2005-2010 This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see . */ #include "libmapi/libmapi.h" #include "libmapi/libmapi_private.h" #include #include "gen_ndr/ndr_exchange.h" #include "gen_ndr/ndr_property.h" #define MIN(a,b) ((a)<(b)?(a):(b)) _PUBLIC_ void obfuscate_data(uint8_t *data, uint32_t size, uint8_t salt) { uint32_t i; for (i=0; idata_size - ndrpull->offset); plain_chunk_offset = ndrpull->offset; NDR_CHECK(ndr_pull_advance(ndrpull, plain_chunk_size)); plain_chunk.data = ndrpull->data + plain_chunk_offset; plain_chunk.length = plain_chunk_size; if (plain_chunk_size < max_plain_size) { *last = true; }; NDR_CHECK(ndr_push_expand(ndrpush, max_comp_size)); comp_chunk.data = ndrpush->data + ndrpush->offset; comp_chunk.length = max_comp_size; /* Compressing the buffer using LZ Xpress algorithm */ ret = lzxpress_compress(plain_chunk.data, plain_chunk.length, comp_chunk.data, comp_chunk.length); if (ret < 0) { return ndr_pull_error(ndrpull, NDR_ERR_COMPRESSION, "XPRESS lzxpress_compress() returned %d\n", (int)ret); } comp_chunk.length = ret; ndrpush->offset += comp_chunk.length; return NDR_ERR_SUCCESS; } static enum ndr_err_code ndr_pull_lxpress_chunk(struct ndr_pull *ndrpull, struct ndr_push *ndrpush, ssize_t decompressed_len, bool *last) { DATA_BLOB comp_chunk; DATA_BLOB plain_chunk; uint32_t plain_chunk_offset; int ret; /* Step 1. Retrieve the compressed buf */ comp_chunk.length = ndrpull->data_size; comp_chunk.data = ndrpull->data; plain_chunk_offset = ndrpush->offset; NDR_CHECK(ndr_push_zero(ndrpush, decompressed_len)); plain_chunk.length = decompressed_len; plain_chunk.data = ndrpush->data + plain_chunk_offset; ret = lzxpress_decompress(comp_chunk.data, comp_chunk.length, plain_chunk.data, plain_chunk.length); if (ret < 0) { return ndr_pull_error(ndrpull, NDR_ERR_COMPRESSION, "XPRESS lzxpress_decompress() returned %d\n", (int)ret); } plain_chunk.length = ret; ndrpush->offset = ret; if ((decompressed_len < 0x00010000) || (ndrpull->offset+4 >= ndrpull->data_size)) { /* this is the last chunk */ *last = true; } return NDR_ERR_SUCCESS; } _PUBLIC_ enum ndr_err_code ndr_pull_lzxpress_decompress(struct ndr_pull *subndr, struct ndr_pull **_comndr, ssize_t decompressed_len) { struct ndr_push *ndrpush; struct ndr_pull *comndr; DATA_BLOB uncompressed; bool last = false; ndrpush = ndr_push_init_ctx(subndr); NDR_ERR_HAVE_NO_MEMORY(ndrpush); while (!last) { NDR_CHECK(ndr_pull_lxpress_chunk(subndr, ndrpush, decompressed_len, &last)); } uncompressed = ndr_push_blob(ndrpush); if (uncompressed.length != decompressed_len) { return ndr_pull_error(subndr, NDR_ERR_COMPRESSION, "Bad uncompressed_len [%u] != [%u](0x%08X) (PULL)", (int)uncompressed.length, (int)decompressed_len, (int)decompressed_len); } comndr = talloc_zero(subndr, struct ndr_pull); NDR_ERR_HAVE_NO_MEMORY(comndr); comndr->flags = subndr->flags; comndr->current_mem_ctx = subndr->current_mem_ctx; comndr->data = uncompressed.data; comndr->data_size = uncompressed.length; comndr->offset = 0; *_comndr = comndr; return NDR_ERR_SUCCESS; } /** \details Push a compressed LZXPRESS blob \param subndr pointer to the compressed blob the function returns \param _uncomndr pointer on pointer to the uncompressed DATA blob \return NDR_ERR_SUCCESS on success, otherwise NDR error */ _PUBLIC_ enum ndr_err_code ndr_push_lzxpress_compress(struct ndr_push *subndr, struct ndr_push *uncomndr) { struct ndr_pull *ndrpull; bool last = false; ndrpull = talloc_zero(uncomndr, struct ndr_pull); NDR_ERR_HAVE_NO_MEMORY(ndrpull); ndrpull->flags = uncomndr->flags; ndrpull->data = uncomndr->data; ndrpull->data_size = uncomndr->offset; ndrpull->offset = 0; while (!last) { NDR_CHECK(ndr_push_lxpress_chunk(subndr, ndrpull, &last)); } return NDR_ERR_SUCCESS; } _PUBLIC_ enum ndr_err_code ndr_pull_mapi2k7_request(struct ndr_pull *ndr, int ndr_flags, struct mapi2k7_request *r) { if (ndr_flags & NDR_SCALARS) { NDR_CHECK(ndr_pull_align(ndr, 4)); NDR_CHECK(ndr_pull_RPC_HEADER_EXT(ndr, NDR_SCALARS, &r->header)); { uint32_t _flags_save_mapi_request = ndr->flags; ndr_set_flags(&ndr->flags, LIBNDR_FLAG_REMAINING|LIBNDR_FLAG_NOALIGN); { struct ndr_pull *_ndr_buffer; if (ndr->flags & LIBNDR_FLAG_REF_ALLOC) { NDR_PULL_ALLOC(ndr, r->mapi_request); } NDR_CHECK(ndr_pull_subcontext_start(ndr, &_ndr_buffer, 0, -1)); { if (r->header.Flags & RHEF_Compressed) { struct ndr_pull *_ndr_data_compressed = NULL; NDR_CHECK(ndr_pull_lzxpress_decompress(_ndr_buffer, &_ndr_data_compressed, r->header.SizeActual)); NDR_CHECK(ndr_pull_mapi_request(_ndr_data_compressed, NDR_SCALARS|NDR_BUFFERS, r->mapi_request)); } else if (r->header.Flags & RHEF_XorMagic) { obfuscate_data(_ndr_buffer->data, _ndr_buffer->data_size, 0xA5); NDR_CHECK(ndr_pull_mapi_request(_ndr_buffer, NDR_SCALARS|NDR_BUFFERS, r->mapi_request)); } else { NDR_CHECK(ndr_pull_mapi_request(_ndr_buffer, NDR_SCALARS|NDR_BUFFERS, r->mapi_request)); } } NDR_CHECK(ndr_pull_subcontext_end(ndr, _ndr_buffer, 0, -1)); } ndr->flags = _flags_save_mapi_request; } } return NDR_ERR_SUCCESS; } _PUBLIC_ enum ndr_err_code ndr_pull_mapi2k7_response(struct ndr_pull *ndr, int ndr_flags, struct mapi2k7_response *r) { if (ndr_flags & NDR_SCALARS) { NDR_CHECK(ndr_pull_RPC_HEADER_EXT(ndr, NDR_SCALARS, &r->header)); { uint32_t _flags_save_mapi_response = ndr->flags; ndr_set_flags(&ndr->flags, LIBNDR_FLAG_NOALIGN|LIBNDR_FLAG_REMAINING); { struct ndr_pull *_ndr_buffer; if (ndr->flags & LIBNDR_FLAG_REF_ALLOC) { NDR_PULL_ALLOC(ndr, r->mapi_response); } NDR_CHECK((ndr_pull_subcontext_start(ndr, &_ndr_buffer, 0, r->header.Size))); { if (r->header.Flags & RHEF_Compressed) { struct ndr_pull *_ndr_data_compressed = NULL; NDR_CHECK(ndr_pull_lzxpress_decompress(_ndr_buffer, &_ndr_data_compressed, r->header.SizeActual)); NDR_CHECK(ndr_pull_mapi_response(_ndr_data_compressed, NDR_SCALARS|NDR_BUFFERS, r->mapi_response)); } else if (r->header.Flags & RHEF_XorMagic) { obfuscate_data(_ndr_buffer->data, _ndr_buffer->data_size, 0xA5); NDR_CHECK(ndr_pull_mapi_response(_ndr_buffer, NDR_SCALARS|NDR_BUFFERS, r->mapi_response)); } else { NDR_CHECK(ndr_pull_mapi_response(_ndr_buffer, NDR_SCALARS|NDR_BUFFERS, r->mapi_response)); } } NDR_CHECK(ndr_pull_subcontext_end(ndr, _ndr_buffer, 0, r->header.Size)); } ndr->flags = _flags_save_mapi_response; } } return NDR_ERR_SUCCESS; } _PUBLIC_ void ndr_print_AUX_HEADER(struct ndr_print *ndr, const char *name, const struct AUX_HEADER *r) { ndr_print_struct(ndr, name, "AUX_HEADER"); { uint32_t _flags_save_STRUCT = ndr->flags; ndr_set_flags(&ndr->flags, LIBNDR_FLAG_NOALIGN); ndr->depth++; ndr_print_uint16(ndr, "Size", r->Size); ndr_print_AUX_VERSION(ndr, "Version", r->Version); switch (r->Version) { case AUX_VERSION_1: ndr_print_AUX_HEADER_TYPE_1(ndr, "Type", (enum AUX_HEADER_TYPE_1) r->Type); ndr_print_set_switch_value(ndr, &r->Payload_1, r->Type); ndr_print_AUX_HEADER_TYPE_UNION_1(ndr, "Payload", &r->Payload_1); break; case AUX_VERSION_2: ndr_print_AUX_HEADER_TYPE_2(ndr, "Type", (enum AUX_HEADER_TYPE_2) r->Type); ndr_print_set_switch_value(ndr, &r->Payload_2, r->Type); ndr_print_AUX_HEADER_TYPE_UNION_2(ndr, "Payload", &r->Payload_2); } ndr->depth--; ndr->flags = _flags_save_STRUCT; } } _PUBLIC_ enum ndr_err_code ndr_pull_AUX_HEADER(struct ndr_pull *ndr, int ndr_flags, struct AUX_HEADER *r) { struct ndr_pull *_ndr_buffer; uint32_t _flags_save_STRUCT = ndr->flags; ndr_set_flags(&ndr->flags, LIBNDR_FLAG_NOALIGN); if (ndr_flags & NDR_SCALARS) { NDR_CHECK(ndr_pull_align(ndr, 4)); NDR_CHECK(ndr_pull_uint16(ndr, NDR_SCALARS, &r->Size)); NDR_CHECK(ndr_pull_subcontext_start(ndr, &_ndr_buffer, 0, r->Size - 2)); { NDR_CHECK(ndr_pull_AUX_VERSION(_ndr_buffer, NDR_SCALARS, &r->Version)); NDR_CHECK(ndr_pull_uint8(_ndr_buffer, NDR_SCALARS, &r->Type)); switch (r->Version) { case AUX_VERSION_1: NDR_CHECK(ndr_pull_set_switch_value(_ndr_buffer, &r->Payload_1, r->Type)); NDR_CHECK(ndr_pull_AUX_HEADER_TYPE_UNION_1(_ndr_buffer, NDR_SCALARS, &r->Payload_1)); break; case AUX_VERSION_2: NDR_CHECK(ndr_pull_set_switch_value(_ndr_buffer, &r->Payload_2, r->Type)); NDR_CHECK(ndr_pull_AUX_HEADER_TYPE_UNION_2(_ndr_buffer, NDR_SCALARS, &r->Payload_2)); break; } } NDR_CHECK(ndr_pull_subcontext_end(ndr, _ndr_buffer, 0, -1)); } if (ndr_flags & NDR_BUFFERS) { } ndr->flags = _flags_save_STRUCT; return NDR_ERR_SUCCESS; } _PUBLIC_ void ndr_print_mapi2k7_AuxInfo(struct ndr_print *ndr, const char *name, const struct mapi2k7_AuxInfo *r) { uint32_t i; if (r && r->AUX_HEADER) { ndr_print_struct(ndr, name, "mapi2k7_AuxInfo"); ndr->depth++; ndr_print_RPC_HEADER_EXT(ndr, "RPC_HEADER_EXT", &r->RPC_HEADER_EXT); for (i = 0; r->AUX_HEADER[i].Size; i++) { ndr_print_AUX_HEADER(ndr, "AUX_HEADER", &r->AUX_HEADER[i]); } ndr->depth--; } else { ndr_print_pointer(ndr, "mapi2k7_AuxInfo", NULL); } } _PUBLIC_ enum ndr_err_code ndr_pull_mapi2k7_AuxInfo(struct ndr_pull *ndr, int ndr_flags, struct mapi2k7_AuxInfo *r) { if (ndr_flags & NDR_SCALARS) { /* Sanity Checks */ if (!ndr->data_size) { r->AUX_HEADER = NULL; return NDR_ERR_SUCCESS; } NDR_CHECK(ndr_pull_align(ndr, 4)); NDR_CHECK(ndr_pull_RPC_HEADER_EXT(ndr, NDR_SCALARS, &r->RPC_HEADER_EXT)); { uint32_t _flags_save_DATA_BLOB = ndr->flags; ndr_set_flags(&ndr->flags, LIBNDR_FLAG_NOALIGN|LIBNDR_FLAG_REMAINING); if (r->RPC_HEADER_EXT.Size) { struct ndr_pull *_ndr_buffer; TALLOC_CTX *_mem_save_AUX_HEADER_0; uint32_t cntr_AUX_HEADER_0 = 0; _mem_save_AUX_HEADER_0 = NDR_PULL_GET_MEM_CTX(ndr); NDR_CHECK(ndr_pull_subcontext_start(ndr, &_ndr_buffer, 0, r->RPC_HEADER_EXT.Size)); { r->AUX_HEADER = talloc_array(_mem_save_AUX_HEADER_0, struct AUX_HEADER, 2); /* lzxpress case */ if (r->RPC_HEADER_EXT.Flags & RHEF_Compressed) { struct ndr_pull *_ndr_data_compressed = NULL; ndr_set_flags(&ndr->flags, LIBNDR_FLAG_NOALIGN); NDR_CHECK(ndr_pull_lzxpress_decompress(_ndr_buffer, &_ndr_data_compressed, r->RPC_HEADER_EXT.SizeActual)); for (cntr_AUX_HEADER_0 = 0; _ndr_data_compressed->offset < _ndr_data_compressed->data_size; cntr_AUX_HEADER_0++) { NDR_CHECK(ndr_pull_AUX_HEADER(_ndr_data_compressed, NDR_SCALARS, &r->AUX_HEADER[cntr_AUX_HEADER_0])); r->AUX_HEADER = talloc_realloc(_mem_save_AUX_HEADER_0, r->AUX_HEADER, struct AUX_HEADER, cntr_AUX_HEADER_0 + 2); } r->AUX_HEADER = talloc_realloc(_mem_save_AUX_HEADER_0, r->AUX_HEADER, struct AUX_HEADER, cntr_AUX_HEADER_0 + 2); r->AUX_HEADER[cntr_AUX_HEADER_0].Size = 0; /* obfuscation case */ } else if (r->RPC_HEADER_EXT.Flags & RHEF_XorMagic) { obfuscate_data(_ndr_buffer->data, _ndr_buffer->data_size, 0xA5); for (cntr_AUX_HEADER_0 = 0; _ndr_buffer->offset < _ndr_buffer->data_size; cntr_AUX_HEADER_0++) { NDR_CHECK(ndr_pull_AUX_HEADER(_ndr_buffer, NDR_SCALARS, &r->AUX_HEADER[cntr_AUX_HEADER_0])); r->AUX_HEADER = talloc_realloc(_mem_save_AUX_HEADER_0, r->AUX_HEADER, struct AUX_HEADER, cntr_AUX_HEADER_0 + 2); } r->AUX_HEADER = talloc_realloc(_mem_save_AUX_HEADER_0, r->AUX_HEADER, struct AUX_HEADER, cntr_AUX_HEADER_0 + 2); r->AUX_HEADER[cntr_AUX_HEADER_0].Size = 0; /* plain case */ } else { for (cntr_AUX_HEADER_0 = 0; _ndr_buffer->offset < _ndr_buffer->data_size; cntr_AUX_HEADER_0++) { NDR_CHECK(ndr_pull_AUX_HEADER(_ndr_buffer, NDR_SCALARS, &r->AUX_HEADER[cntr_AUX_HEADER_0])); r->AUX_HEADER = talloc_realloc(_mem_save_AUX_HEADER_0, r->AUX_HEADER, struct AUX_HEADER, cntr_AUX_HEADER_0 + 2); } r->AUX_HEADER = talloc_realloc(_mem_save_AUX_HEADER_0, r->AUX_HEADER, struct AUX_HEADER, cntr_AUX_HEADER_0 + 2); r->AUX_HEADER[cntr_AUX_HEADER_0].Size = 0; } } NDR_CHECK(ndr_pull_subcontext_end(ndr, _ndr_buffer, 0, -1)); } else { r->AUX_HEADER = NULL; } ndr->flags = _flags_save_DATA_BLOB; } } if (ndr_flags & NDR_BUFFERS) { } return NDR_ERR_SUCCESS; } /* print mapi_request / mapi_response structures */ void ndr_print_mapi_request(struct ndr_print *ndr, const char *name, const struct mapi_request *r) { uint32_t rlength; rlength = r->mapi_len - r->length; ndr_print_uint32(ndr, "mapi_len", r->mapi_len); if (r->length && r->length > sizeof(uint16_t)) { uint32_t cntr_mapi_req_0; ndr_print_uint16(ndr, "length", r->length); ndr->depth++; for (cntr_mapi_req_0=0; r->mapi_req[cntr_mapi_req_0].opnum; cntr_mapi_req_0++) { char *idx_0 = NULL; int ret; ret = asprintf(&idx_0, "[%u]", cntr_mapi_req_0); if (ret != -1 && idx_0) { ndr_print_EcDoRpc_MAPI_REQ(ndr, "mapi_request", &r->mapi_req[cntr_mapi_req_0]); free(idx_0); } } ndr->depth--; } if (rlength) { uint32_t i; ndr->depth++; ndr->print(ndr, "%-25s: (handles) number=%u", name, rlength / 4); ndr->depth++; for (i = 0; i < (rlength / 4); i++) { ndr_print_uint32(ndr, "handle", r->handles[i]); } ndr->depth--; } } void ndr_print_mapi_response(struct ndr_print *ndr, const char *name, const struct mapi_response *r) { uint32_t rlength; rlength = r->mapi_len - r->length; ndr->print(ndr, "%-25s: length=%u", name, r->length); if (r->length && r->length > sizeof(uint16_t)) { uint32_t cntr_mapi_repl_0; ndr->print(ndr, "%s: ARRAY(%d)", name, r->length - 2); ndr->depth++; for (cntr_mapi_repl_0=0; r->mapi_repl[cntr_mapi_repl_0].opnum; cntr_mapi_repl_0++) { ndr_print_EcDoRpc_MAPI_REPL(ndr, "mapi_repl", &r->mapi_repl[cntr_mapi_repl_0]); } ndr->depth--; } ndr->print(ndr, "%-25s: (handles) number=%u", name, rlength / 4); if (rlength) { uint32_t i; ndr->depth++; for (i = 0; i < (rlength / 4); i++) { ndr_print_uint32(ndr, "handle id", r->handles[i]); } ndr->depth--; } } /* push mapi_request / mapi_response onto the wire. MAPI length field includes length bytes. But these bytes do not belong to the mapi content in the user context. We have to add them when pushing mapi content length (uint16_t) and next subtract when pushing the content blob */ enum ndr_err_code ndr_push_mapi_request(struct ndr_push *ndr, int ndr_flags, const struct mapi_request *r) { uint32_t cntr_mapi_req_0; uint32_t count; ndr_set_flags(&ndr->flags, LIBNDR_FLAG_NOALIGN); NDR_CHECK(ndr_push_uint16(ndr, NDR_SCALARS, r->length)); for (count = 0; ndr->offset < r->length - 2; count++) { NDR_CHECK(ndr_push_EcDoRpc_MAPI_REQ(ndr, NDR_SCALARS, &r->mapi_req[count])); } count = (r->mapi_len - r->length) / sizeof(uint32_t); for (cntr_mapi_req_0=0; cntr_mapi_req_0 < count; cntr_mapi_req_0++) { NDR_CHECK(ndr_push_uint32(ndr, NDR_SCALARS, r->handles[cntr_mapi_req_0])); } return NDR_ERR_SUCCESS; } enum ndr_err_code ndr_push_mapi_response(struct ndr_push *ndr, int ndr_flags, const struct mapi_response *r) { uint32_t cntr_mapi_repl_0; uint32_t count; ndr_set_flags(&ndr->flags, LIBNDR_FLAG_NOALIGN); NDR_CHECK(ndr_push_uint16(ndr, NDR_SCALARS, r->length)); if (r->length > sizeof (uint16_t)) { for (count = 0; ndr->offset < r->length - 2; count++) { NDR_CHECK(ndr_push_EcDoRpc_MAPI_REPL(ndr, NDR_SCALARS, &r->mapi_repl[count])); } } count = (r->mapi_len - r->length) / sizeof (uint32_t); for (cntr_mapi_repl_0 = 0; cntr_mapi_repl_0 handles[cntr_mapi_repl_0])); } return NDR_ERR_SUCCESS; } /* pull mapi_request / mapi_response from the wire */ enum ndr_err_code ndr_pull_mapi_request(struct ndr_pull *ndr, int ndr_flags, struct mapi_request *r) { uint32_t length,count; uint32_t cntr_mapi_req_0; TALLOC_CTX *_mem_save_mapi_req_0; TALLOC_CTX *_mem_save_handles_0; struct ndr_pull *_ndr_mapi_req; if (ndr->flags & LIBNDR_FLAG_REMAINING) { length = ndr->data_size - ndr->offset; } else { NDR_CHECK(ndr_pull_uint32(ndr, NDR_SCALARS, &length)); } r->mapi_len = length; NDR_CHECK(ndr_pull_uint16(ndr, NDR_SCALARS, &r->length)); /* If length equals length field then skipping subcontext */ if (r->length > sizeof (uint16_t)) { NDR_CHECK(ndr_pull_subcontext_start(ndr, &_ndr_mapi_req, 0, r->length - 2)); _mem_save_mapi_req_0 = NDR_PULL_GET_MEM_CTX(_ndr_mapi_req); r->mapi_req = talloc_zero(_mem_save_mapi_req_0, struct EcDoRpc_MAPI_REQ); for (cntr_mapi_req_0 = 0; _ndr_mapi_req->offset < _ndr_mapi_req->data_size - 2; cntr_mapi_req_0++) { NDR_CHECK(ndr_pull_EcDoRpc_MAPI_REQ(_ndr_mapi_req, NDR_SCALARS, &r->mapi_req[cntr_mapi_req_0])); r->mapi_req = talloc_realloc(_mem_save_mapi_req_0, r->mapi_req, struct EcDoRpc_MAPI_REQ, cntr_mapi_req_0 + 2); } r->mapi_req = talloc_realloc(_mem_save_mapi_req_0, r->mapi_req, struct EcDoRpc_MAPI_REQ, cntr_mapi_req_0 + 2); r->mapi_req[cntr_mapi_req_0].opnum = 0; if (_ndr_mapi_req->offset != r->length - 2) { return NDR_ERR_BUFSIZE; } NDR_CHECK(ndr_pull_subcontext_end(ndr, _ndr_mapi_req, 4, -1)); _mem_save_handles_0 = NDR_PULL_GET_MEM_CTX(ndr); count = (r->mapi_len - r->length) / sizeof(uint32_t); r->handles = talloc_array(_mem_save_handles_0, uint32_t, count + 1); for (cntr_mapi_req_0=0; cntr_mapi_req_0 < count; cntr_mapi_req_0++) { NDR_CHECK(ndr_pull_uint32(ndr, NDR_SCALARS, &r->handles[cntr_mapi_req_0])); } } else { r->handles = NULL; } return NDR_ERR_SUCCESS; } enum ndr_err_code ndr_pull_mapi_response(struct ndr_pull *ndr, int ndr_flags, struct mapi_response *r) { uint32_t length,count; uint32_t cntr_mapi_repl_0; TALLOC_CTX *_mem_save_mapi_repl_0; TALLOC_CTX *_mem_save_handles_0; struct ndr_pull *_ndr_mapi_repl; if (ndr->flags & LIBNDR_FLAG_REMAINING) { length = ndr->data_size - ndr->offset; } else { NDR_CHECK(ndr_pull_uint32(ndr, NDR_SCALARS, &length)); } r->mapi_len = length; NDR_CHECK(ndr_pull_uint16(ndr, NDR_SCALARS, &r->length)); /* If length equals length field then skipping subcontext */ if (r->length > sizeof (uint16_t)) { _mem_save_mapi_repl_0 = NDR_PULL_GET_MEM_CTX(ndr); r->mapi_repl = talloc_zero_array(_mem_save_mapi_repl_0, struct EcDoRpc_MAPI_REPL, 2); NDR_CHECK(ndr_pull_subcontext_start(ndr, &_ndr_mapi_repl, 0, r->length - 2)); for (cntr_mapi_repl_0 = 0; _ndr_mapi_repl->offset < _ndr_mapi_repl->data_size - 2; cntr_mapi_repl_0++) { NDR_CHECK(ndr_pull_EcDoRpc_MAPI_REPL(_ndr_mapi_repl, NDR_SCALARS, &r->mapi_repl[cntr_mapi_repl_0])); r->mapi_repl = talloc_realloc(_ndr_mapi_repl, r->mapi_repl, struct EcDoRpc_MAPI_REPL, cntr_mapi_repl_0 + 2); } r->mapi_repl[cntr_mapi_repl_0].opnum = 0; NDR_CHECK(ndr_pull_subcontext_end(ndr, _ndr_mapi_repl, 4, -1)); talloc_free(_ndr_mapi_repl); } else { r->mapi_repl = NULL; } _mem_save_handles_0 = NDR_PULL_GET_MEM_CTX(ndr); count = (r->mapi_len - r->length) / sizeof(uint32_t); NDR_PULL_ALLOC_N(ndr, r->handles, count + 1); for (cntr_mapi_repl_0=0; cntr_mapi_repl_0 < count; cntr_mapi_repl_0++) { NDR_CHECK(ndr_pull_uint32(ndr, NDR_SCALARS, &r->handles[cntr_mapi_repl_0])); } NDR_PULL_SET_MEM_CTX(ndr, _mem_save_handles_0, LIBNDR_FLAG_REF_ALLOC); return NDR_ERR_SUCCESS; } /* We stop processing the IDL if MAPISTATUS is different from MAPI_E_SUCCESS */ _PUBLIC_ enum ndr_err_code ndr_push_EcDoRpc_MAPI_REPL(struct ndr_push *ndr, int ndr_flags, const struct EcDoRpc_MAPI_REPL *r) { if (r->opnum != op_MAPI_Release) { uint32_t _flags_save_STRUCT = ndr->flags; ndr_set_flags(&ndr->flags, LIBNDR_FLAG_NOALIGN); if (ndr_flags & NDR_SCALARS) { NDR_CHECK(ndr_push_align(ndr, 8)); NDR_CHECK(ndr_push_uint8(ndr, NDR_SCALARS, r->opnum)); if ((r->opnum == op_MAPI_Notify) || (r->opnum == op_MAPI_Pending)) { NDR_CHECK(ndr_push_set_switch_value(ndr, &r->u, r->opnum)); NDR_CHECK(ndr_push_EcDoRpc_MAPI_REPL_UNION(ndr, NDR_SCALARS, &r->u)); } else { NDR_CHECK(ndr_push_uint8(ndr, NDR_SCALARS, r->handle_idx)); NDR_CHECK(ndr_push_MAPISTATUS(ndr, NDR_SCALARS, r->error_code)); if (r->error_code == MAPI_E_SUCCESS) { NDR_CHECK(ndr_push_set_switch_value(ndr, &r->u, r->opnum)); NDR_CHECK(ndr_push_EcDoRpc_MAPI_REPL_UNION(ndr, NDR_SCALARS, &r->u)); } else { switch (r->opnum) { case op_MAPI_Logon: { if (r->error_code == ecWrongServer) { NDR_CHECK(ndr_push_Logon_redirect(ndr, NDR_SCALARS, &(r->us.mapi_Logon))); } break; } case op_MAPI_GetIDsFromNames: { /* MAPI_W_ERRORS_RETURNED still enables the final array to be passed */ if (r->error_code == MAPI_W_ERRORS_RETURNED) { NDR_CHECK(ndr_push_set_switch_value(ndr, &r->u, r->opnum)); NDR_CHECK(ndr_push_EcDoRpc_MAPI_REPL_UNION(ndr, NDR_SCALARS, &r->u)); } break; } case op_MAPI_MoveFolder: case op_MAPI_CopyFolder: { /* ecDstNullObject requires the return of an additional uint32_t for DestHandleIndex */ if (r->error_code == ecDstNullObject) { NDR_CHECK(ndr_push_set_switch_value(ndr, &r->u, r->opnum)); NDR_CHECK(ndr_push_EcDoRpc_MAPI_REPL_UNION(ndr, NDR_SCALARS, &r->u)); } break; } default: break; } } } } if (ndr_flags & NDR_BUFFERS) { NDR_CHECK(ndr_push_EcDoRpc_MAPI_REPL_UNION(ndr, NDR_BUFFERS, &r->u)); } ndr->flags = _flags_save_STRUCT; } return NDR_ERR_SUCCESS; } enum ndr_err_code ndr_pull_EcDoRpc_MAPI_REPL(struct ndr_pull *ndr, int ndr_flags, struct EcDoRpc_MAPI_REPL *r) { { uint32_t _flags_save_STRUCT = ndr->flags; ndr_set_flags(&ndr->flags, LIBNDR_FLAG_NOALIGN); if (ndr_flags & NDR_SCALARS) { NDR_CHECK(ndr_pull_align(ndr, 8)); NDR_CHECK(ndr_pull_uint8(ndr, NDR_SCALARS, &r->opnum)); if ((r->opnum == op_MAPI_Notify) || (r->opnum == op_MAPI_Pending)) { NDR_CHECK(ndr_pull_set_switch_value(ndr, &r->u, r->opnum)); NDR_CHECK(ndr_pull_EcDoRpc_MAPI_REPL_UNION(ndr, NDR_SCALARS, &r->u)); } else { NDR_CHECK(ndr_pull_uint8(ndr, NDR_SCALARS, &r->handle_idx)); NDR_CHECK(ndr_pull_MAPISTATUS(ndr, NDR_SCALARS, &r->error_code)); if ( r->error_code == MAPI_E_SUCCESS) { NDR_CHECK(ndr_pull_set_switch_value(ndr, &r->u, r->opnum)); if (r->opnum == op_MAPI_MoveFolder) { r->u.mapi_MoveFolder.HasDestHandleIndex = false; } else if (r->opnum == op_MAPI_CopyFolder) { r->u.mapi_CopyFolder.HasDestHandleIndex = false; } NDR_CHECK(ndr_pull_EcDoRpc_MAPI_REPL_UNION(ndr, NDR_SCALARS, &r->u)); } else { switch (r->opnum) { case op_MAPI_Logon: { if (r->error_code == ecWrongServer) { NDR_CHECK(ndr_pull_Logon_redirect(ndr, NDR_SCALARS, &(r->us.mapi_Logon))); } break;} case op_MAPI_GetIDsFromNames: { /* MAPI_W_ERRORS_RETURNED still enables the final array to be passed */ if (r->error_code == MAPI_W_ERRORS_RETURNED) { NDR_CHECK(ndr_pull_set_switch_value(ndr, &r->u, r->opnum)); NDR_CHECK(ndr_pull_EcDoRpc_MAPI_REPL_UNION(ndr, NDR_SCALARS, &r->u)); } break;} case op_MAPI_MoveFolder: { /* ecDstNullObject requires the return of an additional uint32_t for DestHandleIndex */ if (r->error_code == ecDstNullObject) { r->u.mapi_MoveFolder.HasDestHandleIndex = true; NDR_CHECK(ndr_pull_set_switch_value(ndr, &r->u, r->opnum)); NDR_CHECK(ndr_pull_EcDoRpc_MAPI_REPL_UNION(ndr, NDR_SCALARS, &r->u)); } else { r->u.mapi_MoveFolder.HasDestHandleIndex = false; } break; } case op_MAPI_CopyFolder: { /* ecDstNullObject requires the return of an additional uint32_t for DestHandleIndex */ if (r->error_code == ecDstNullObject) { r->u.mapi_CopyFolder.HasDestHandleIndex = true; NDR_CHECK(ndr_pull_set_switch_value(ndr, &r->u, r->opnum)); NDR_CHECK(ndr_pull_EcDoRpc_MAPI_REPL_UNION(ndr, NDR_SCALARS, &r->u)); } else { r->u.mapi_CopyFolder.HasDestHandleIndex = false; } break; } default: break; } } } } if (ndr_flags & NDR_BUFFERS) { ndr->flags = _flags_save_STRUCT; } } return NDR_ERR_SUCCESS; } void ndr_print_EcDoRpc_MAPI_REPL(struct ndr_print *ndr, const char *name, const struct EcDoRpc_MAPI_REPL *r) { ndr_print_struct(ndr, name, "EcDoRpc_MAPI_REPL"); { uint32_t _flags_save_STRUCT = ndr->flags; ndr_set_flags(&ndr->flags, LIBNDR_FLAG_NOALIGN); ndr->depth++; ndr_print_uint8(ndr, "opnum", r->opnum); if ((r->opnum != op_MAPI_Notify) && (r->opnum != op_MAPI_Pending)) { ndr_print_uint8(ndr, "handle_idx", r->handle_idx); ndr_print_MAPISTATUS(ndr, "error_code", r->error_code); if (r->error_code == MAPI_E_SUCCESS) { ndr_print_set_switch_value(ndr, &r->u, r->opnum); ndr_print_EcDoRpc_MAPI_REPL_UNION(ndr, "u", &r->u); } else { switch (r->opnum) { case op_MAPI_Logon: { if (r->error_code == ecWrongServer) { ndr_print_set_switch_value(ndr, &r->us, r->opnum); ndr_print_EcDoRpc_MAPI_REPL_UNION_SPECIAL(ndr, "us", &r->us); } break;} case op_MAPI_GetIDsFromNames: { /* MAPI_W_ERRORS_RETURNED still enables the final array to be passed */ if (r->error_code == MAPI_W_ERRORS_RETURNED) { ndr_print_set_switch_value(ndr, &r->u, r->opnum); ndr_print_EcDoRpc_MAPI_REPL_UNION(ndr, "u", &r->u); } break; } case op_MAPI_MoveFolder: case op_MAPI_CopyFolder: { /* ecDstNullObject requires the return of an additional uint32_t for DestHandleIndex */ if (r->error_code == ecDstNullObject) { ndr_print_set_switch_value(ndr, &r->u, r->opnum); ndr_print_EcDoRpc_MAPI_REPL_UNION(ndr, "u", &r->u); } break; } default: break; } } } else { ndr_print_set_switch_value(ndr, &r->u, r->opnum); ndr_print_EcDoRpc_MAPI_REPL_UNION(ndr, "u", &r->u); } ndr->depth--; ndr->flags = _flags_save_STRUCT; } } _PUBLIC_ enum ndr_err_code ndr_pull_EcDoRpc(struct ndr_pull *ndr, int flags, struct EcDoRpc *r) { TALLOC_CTX *_mem_save_handle_0; TALLOC_CTX *_mem_save_mapi_request_0; TALLOC_CTX *_mem_save_mapi_response_0; TALLOC_CTX *_mem_save_length_0; if (flags & NDR_IN) { ZERO_STRUCT(r->out); if (ndr->flags & LIBNDR_FLAG_REF_ALLOC) { NDR_PULL_ALLOC(ndr, r->in.handle); } _mem_save_handle_0 = NDR_PULL_GET_MEM_CTX(ndr); NDR_PULL_SET_MEM_CTX(ndr, r->in.handle, LIBNDR_FLAG_REF_ALLOC); NDR_CHECK(ndr_pull_policy_handle(ndr, NDR_SCALARS|NDR_BUFFERS, r->in.handle)); NDR_PULL_SET_MEM_CTX(ndr, _mem_save_handle_0, LIBNDR_FLAG_REF_ALLOC); NDR_CHECK(ndr_pull_uint32(ndr, NDR_SCALARS, &r->in.size)); NDR_CHECK(ndr_pull_uint32(ndr, NDR_SCALARS, &r->in.offset)); { uint32_t _flags_save_mapi_request = ndr->flags; ndr_set_flags(&ndr->flags, LIBNDR_FLAG_REMAINING|LIBNDR_FLAG_NOALIGN); if (ndr->flags & LIBNDR_FLAG_REF_ALLOC) { NDR_PULL_ALLOC(ndr, r->in.mapi_request); } _mem_save_mapi_request_0 = NDR_PULL_GET_MEM_CTX(ndr); NDR_PULL_SET_MEM_CTX(ndr, r->in.mapi_request, LIBNDR_FLAG_REF_ALLOC); { struct ndr_pull *_ndr_mapi_request; NDR_CHECK(ndr_pull_subcontext_start(ndr, &_ndr_mapi_request, 4, -1)); obfuscate_data(_ndr_mapi_request->data, _ndr_mapi_request->data_size, 0xA5); NDR_CHECK(ndr_pull_mapi_request(_ndr_mapi_request, NDR_SCALARS|NDR_BUFFERS, r->in.mapi_request)); NDR_CHECK(ndr_pull_subcontext_end(ndr, _ndr_mapi_request, 4, -1)); } NDR_PULL_SET_MEM_CTX(ndr, _mem_save_mapi_request_0, LIBNDR_FLAG_REF_ALLOC); ndr->flags = _flags_save_mapi_request; } if (ndr->flags & LIBNDR_FLAG_REF_ALLOC) { NDR_PULL_ALLOC(ndr, r->in.length); } _mem_save_length_0 = NDR_PULL_GET_MEM_CTX(ndr); NDR_PULL_SET_MEM_CTX(ndr, r->in.length, LIBNDR_FLAG_REF_ALLOC); NDR_CHECK(ndr_pull_uint16(ndr, NDR_SCALARS, r->in.length)); NDR_PULL_SET_MEM_CTX(ndr, _mem_save_length_0, LIBNDR_FLAG_REF_ALLOC); NDR_CHECK(ndr_pull_uint16(ndr, NDR_SCALARS, &r->in.max_data)); NDR_PULL_ALLOC(ndr, r->out.handle); *r->out.handle = *r->in.handle; NDR_PULL_ALLOC(ndr, r->out.mapi_response); ZERO_STRUCTP(r->out.mapi_response); NDR_PULL_ALLOC(ndr, r->out.length); *r->out.length = *r->in.length; } if (flags & NDR_OUT) { if (ndr->flags & LIBNDR_FLAG_REF_ALLOC) { NDR_PULL_ALLOC(ndr, r->out.handle); } _mem_save_handle_0 = NDR_PULL_GET_MEM_CTX(ndr); NDR_PULL_SET_MEM_CTX(ndr, r->out.handle, LIBNDR_FLAG_REF_ALLOC); NDR_CHECK(ndr_pull_policy_handle(ndr, NDR_SCALARS|NDR_BUFFERS, r->out.handle)); NDR_PULL_SET_MEM_CTX(ndr, _mem_save_handle_0, LIBNDR_FLAG_REF_ALLOC); NDR_CHECK(ndr_pull_uint32(ndr, NDR_SCALARS, &r->out.size)); NDR_CHECK(ndr_pull_uint32(ndr, NDR_SCALARS, &r->out.offset)); { uint32_t _flags_save_mapi_response = ndr->flags; ndr_set_flags(&ndr->flags, LIBNDR_FLAG_REMAINING|LIBNDR_FLAG_NOALIGN); if (ndr->flags & LIBNDR_FLAG_REF_ALLOC) { NDR_PULL_ALLOC(ndr, r->out.mapi_response); } _mem_save_mapi_response_0 = NDR_PULL_GET_MEM_CTX(ndr); NDR_PULL_SET_MEM_CTX(ndr, r->out.mapi_response, LIBNDR_FLAG_REF_ALLOC); { struct ndr_pull *_ndr_mapi_response; NDR_CHECK(ndr_pull_subcontext_start(ndr, &_ndr_mapi_response, 4, -1)); obfuscate_data(_ndr_mapi_response->data, _ndr_mapi_response->data_size, 0xA5); NDR_CHECK(ndr_pull_mapi_response(_ndr_mapi_response, NDR_SCALARS|NDR_BUFFERS, r->out.mapi_response)); NDR_CHECK(ndr_pull_subcontext_end(ndr, _ndr_mapi_response, 4, -1)); } NDR_PULL_SET_MEM_CTX(ndr, _mem_save_mapi_response_0, LIBNDR_FLAG_REF_ALLOC); ndr->flags = _flags_save_mapi_response; } if (ndr->flags & LIBNDR_FLAG_REF_ALLOC) { NDR_PULL_ALLOC(ndr, r->out.length); } _mem_save_length_0 = NDR_PULL_GET_MEM_CTX(ndr); NDR_PULL_SET_MEM_CTX(ndr, r->out.length, LIBNDR_FLAG_REF_ALLOC); NDR_CHECK(ndr_pull_uint16(ndr, NDR_SCALARS, r->out.length)); NDR_PULL_SET_MEM_CTX(ndr, _mem_save_length_0, LIBNDR_FLAG_REF_ALLOC); NDR_CHECK(ndr_pull_MAPISTATUS(ndr, NDR_SCALARS, &r->out.result)); } return NDR_ERR_SUCCESS; } _PUBLIC_ enum ndr_err_code ndr_push_EcDoRpc(struct ndr_push *ndr, int flags, const struct EcDoRpc *r) { if (flags & NDR_IN) { if (r->in.handle == NULL) { return ndr_push_error(ndr, NDR_ERR_INVALID_POINTER, "NULL [ref] pointer"); } NDR_CHECK(ndr_push_policy_handle(ndr, NDR_SCALARS|NDR_BUFFERS, r->in.handle)); NDR_CHECK(ndr_push_uint32(ndr, NDR_SCALARS, r->in.size)); NDR_CHECK(ndr_push_uint32(ndr, NDR_SCALARS, r->in.offset)); { uint32_t _flags_save_mapi_request = ndr->flags; ndr_set_flags(&ndr->flags, LIBNDR_FLAG_REMAINING|LIBNDR_FLAG_NOALIGN); if (r->in.mapi_request == NULL) { return ndr_push_error(ndr, NDR_ERR_INVALID_POINTER, "NULL [ref] pointer"); } { struct ndr_push *_ndr_mapi_request; NDR_CHECK(ndr_push_subcontext_start(ndr, &_ndr_mapi_request, 4, -1)); NDR_CHECK(ndr_push_mapi_request(_ndr_mapi_request, NDR_SCALARS|NDR_BUFFERS, r->in.mapi_request)); obfuscate_data(_ndr_mapi_request->data, _ndr_mapi_request->offset, 0xA5); NDR_CHECK(ndr_push_subcontext_end(ndr, _ndr_mapi_request, 4, -1)); } ndr->flags = _flags_save_mapi_request; } if (r->in.length == NULL) { return ndr_push_error(ndr, NDR_ERR_INVALID_POINTER, "NULL [ref] pointer"); } NDR_CHECK(ndr_push_uint16(ndr, NDR_SCALARS, *r->in.length)); NDR_CHECK(ndr_push_uint16(ndr, NDR_SCALARS, r->in.max_data)); } if (flags & NDR_OUT) { if (r->out.handle == NULL) { return ndr_push_error(ndr, NDR_ERR_INVALID_POINTER, "NULL [ref] pointer"); } NDR_CHECK(ndr_push_policy_handle(ndr, NDR_SCALARS|NDR_BUFFERS, r->out.handle)); NDR_CHECK(ndr_push_uint32(ndr, NDR_SCALARS, r->out.size)); NDR_CHECK(ndr_push_uint32(ndr, NDR_SCALARS, r->out.offset)); { uint32_t _flags_save_mapi_response = ndr->flags; ndr_set_flags(&ndr->flags, LIBNDR_FLAG_REMAINING|LIBNDR_FLAG_NOALIGN); if (r->out.mapi_response == NULL) { return ndr_push_error(ndr, NDR_ERR_INVALID_POINTER, "NULL [ref] pointer"); } { struct ndr_push *_ndr_mapi_response; NDR_CHECK(ndr_push_subcontext_start(ndr, &_ndr_mapi_response, 4, -1)); NDR_CHECK(ndr_push_mapi_response(_ndr_mapi_response, NDR_SCALARS|NDR_BUFFERS, r->out.mapi_response)); obfuscate_data(_ndr_mapi_response->data, _ndr_mapi_response->alloc_size, 0xA5); NDR_CHECK(ndr_push_subcontext_end(ndr, _ndr_mapi_response, 4, -1)); } ndr->flags = _flags_save_mapi_response; } if (r->out.length == NULL) { return ndr_push_error(ndr, NDR_ERR_INVALID_POINTER, "NULL [ref] pointer"); } NDR_CHECK(ndr_push_uint16(ndr, NDR_SCALARS, *r->out.length)); NDR_CHECK(ndr_push_MAPISTATUS(ndr, NDR_SCALARS, r->out.result)); } return NDR_ERR_SUCCESS; } _PUBLIC_ enum ndr_err_code ndr_push_EcDoConnectEx(struct ndr_push *ndr, int flags, const struct EcDoConnectEx *r) { uint32_t cntr_rgwClientVersion_0; uint32_t cntr_rgwServerVersion_0; uint32_t cntr_rgwBestVersion_0; if (flags & NDR_IN) { NDR_CHECK(ndr_push_uint3264(ndr, NDR_SCALARS, ndr_charset_length(r->in.szUserDN, CH_DOS))); NDR_CHECK(ndr_push_uint3264(ndr, NDR_SCALARS, 0)); NDR_CHECK(ndr_push_uint3264(ndr, NDR_SCALARS, ndr_charset_length(r->in.szUserDN, CH_DOS))); NDR_CHECK(ndr_push_charset(ndr, NDR_SCALARS, r->in.szUserDN, ndr_charset_length(r->in.szUserDN, CH_DOS), sizeof (uint8_t), CH_DOS)); NDR_CHECK(ndr_push_uint32(ndr, NDR_SCALARS, r->in.ulFlags)); NDR_CHECK(ndr_push_uint32(ndr, NDR_SCALARS, r->in.ulConMod)); NDR_CHECK(ndr_push_uint32(ndr, NDR_SCALARS, r->in.cbLimit)); NDR_CHECK(ndr_push_uint32(ndr, NDR_SCALARS, r->in.ulCpid)); NDR_CHECK(ndr_push_uint32(ndr, NDR_SCALARS, r->in.ulLcidString)); NDR_CHECK(ndr_push_uint32(ndr, NDR_SCALARS, r->in.ulLcidSort)); NDR_CHECK(ndr_push_uint32(ndr, NDR_SCALARS, r->in.ulIcxrLink)); NDR_CHECK(ndr_push_uint16(ndr, NDR_SCALARS, r->in.usFCanConvertCodePages)); for (cntr_rgwClientVersion_0 = 0; cntr_rgwClientVersion_0 < 3; cntr_rgwClientVersion_0++) { NDR_CHECK(ndr_push_uint16(ndr, NDR_SCALARS, r->in.rgwClientVersion[cntr_rgwClientVersion_0])); } if (r->in.pulTimeStamp == NULL) { return ndr_push_error(ndr, NDR_ERR_INVALID_POINTER, "NULL [ref] pointer"); } NDR_CHECK(ndr_push_uint32(ndr, NDR_SCALARS, *r->in.pulTimeStamp)); { uint32_t _flags_save_mapi2k7_AuxInfo = ndr->flags; struct ndr_push *_ndr_rgbAuxIn; ndr_set_flags(&ndr->flags, LIBNDR_FLAG_NOALIGN|LIBNDR_FLAG_REMAINING); NDR_CHECK(ndr_push_subcontext_start(ndr, &_ndr_rgbAuxIn, 4, -1)); if (r->in.cbAuxIn) { if (r->in.rgbAuxIn == NULL) { return ndr_push_error(ndr, NDR_ERR_INVALID_POINTER, "NULL [ref] pointer"); } NDR_CHECK(ndr_push_mapi2k7_AuxInfo(_ndr_rgbAuxIn, NDR_SCALARS|NDR_BUFFERS, r->in.rgbAuxIn)); } NDR_CHECK(ndr_push_subcontext_end(ndr, _ndr_rgbAuxIn, 4, -1)); ndr->flags = _flags_save_mapi2k7_AuxInfo; } NDR_CHECK(ndr_push_uint32(ndr, NDR_SCALARS, r->in.cbAuxIn)); if (r->in.pcbAuxOut == NULL) { return ndr_push_error(ndr, NDR_ERR_INVALID_POINTER, "NULL [ref] pointer"); } NDR_CHECK(ndr_push_uint32(ndr, NDR_SCALARS, *r->in.pcbAuxOut)); } if (flags & NDR_OUT) { if (r->out.handle == NULL) { return ndr_push_error(ndr, NDR_ERR_INVALID_POINTER, "NULL [ref] pointer"); } NDR_CHECK(ndr_push_policy_handle(ndr, NDR_SCALARS|NDR_BUFFERS, r->out.handle)); if (r->out.pcmsPollsMax == NULL) { return ndr_push_error(ndr, NDR_ERR_INVALID_POINTER, "NULL [ref] pointer"); } NDR_CHECK(ndr_push_uint32(ndr, NDR_SCALARS, *r->out.pcmsPollsMax)); if (r->out.pcRetry == NULL) { return ndr_push_error(ndr, NDR_ERR_INVALID_POINTER, "NULL [ref] pointer"); } NDR_CHECK(ndr_push_uint32(ndr, NDR_SCALARS, *r->out.pcRetry)); if (r->out.pcmsRetryDelay == NULL) { return ndr_push_error(ndr, NDR_ERR_INVALID_POINTER, "NULL [ref] pointer"); } NDR_CHECK(ndr_push_uint32(ndr, NDR_SCALARS, *r->out.pcmsRetryDelay)); if (r->out.picxr == NULL) { return ndr_push_error(ndr, NDR_ERR_INVALID_POINTER, "NULL [ref] pointer"); } NDR_CHECK(ndr_push_uint32(ndr, NDR_SCALARS, *r->out.picxr)); if (r->out.szDNPrefix == NULL || *r->out.szDNPrefix == NULL) { return ndr_push_error(ndr, NDR_ERR_INVALID_POINTER, "NULL [ref] pointer"); } NDR_CHECK(ndr_push_unique_ptr(ndr, *r->out.szDNPrefix)); if (r->out.szDNPrefix) { NDR_CHECK(ndr_push_uint3264(ndr, NDR_SCALARS, ndr_charset_length(*r->out.szDNPrefix, CH_DOS))); NDR_CHECK(ndr_push_uint3264(ndr, NDR_SCALARS, 0)); NDR_CHECK(ndr_push_uint3264(ndr, NDR_SCALARS, ndr_charset_length(*r->out.szDNPrefix, CH_DOS))); NDR_CHECK(ndr_push_charset(ndr, NDR_SCALARS, *r->out.szDNPrefix, ndr_charset_length(*r->out.szDNPrefix, CH_DOS), sizeof(uint8_t), CH_DOS)); } if (r->out.szDisplayName == NULL) { return ndr_push_error(ndr, NDR_ERR_INVALID_POINTER, "NULL [ref] pointer"); } NDR_CHECK(ndr_push_unique_ptr(ndr, *r->out.szDisplayName)); if (*r->out.szDisplayName) { NDR_CHECK(ndr_push_uint3264(ndr, NDR_SCALARS, ndr_charset_length(*r->out.szDisplayName, CH_DOS))); NDR_CHECK(ndr_push_uint3264(ndr, NDR_SCALARS, 0)); NDR_CHECK(ndr_push_uint3264(ndr, NDR_SCALARS, ndr_charset_length(*r->out.szDisplayName, CH_DOS))); NDR_CHECK(ndr_push_charset(ndr, NDR_SCALARS, *r->out.szDisplayName, ndr_charset_length(*r->out.szDisplayName, CH_DOS), sizeof(uint8_t), CH_DOS)); } for (cntr_rgwServerVersion_0 = 0; cntr_rgwServerVersion_0 < 3; cntr_rgwServerVersion_0++) { NDR_CHECK(ndr_push_uint16(ndr, NDR_SCALARS, r->out.rgwServerVersion[cntr_rgwServerVersion_0])); } for (cntr_rgwBestVersion_0 = 0; cntr_rgwBestVersion_0 < 3; cntr_rgwBestVersion_0++) { NDR_CHECK(ndr_push_uint16(ndr, NDR_SCALARS, r->out.rgwBestVersion[cntr_rgwBestVersion_0])); } if (r->out.pulTimeStamp == NULL) { return ndr_push_error(ndr, NDR_ERR_INVALID_POINTER, "NULL [ref] pointer"); } NDR_CHECK(ndr_push_uint32(ndr, NDR_SCALARS, *r->out.pulTimeStamp)); NDR_CHECK(ndr_push_uint3264(ndr, NDR_SCALARS, *r->out.pcbAuxOut)); NDR_CHECK(ndr_push_uint3264(ndr, NDR_SCALARS, 0)); NDR_CHECK(ndr_push_uint3264(ndr, NDR_SCALARS, *r->out.pcbAuxOut)); /* Only try to fetch rgbAuxOut if pcbAuxOut is > 0 */ if (r->out.pcbAuxOut && *r->out.pcbAuxOut) { NDR_CHECK(ndr_push_mapi2k7_AuxInfo(ndr, NDR_SCALARS, r->out.rgbAuxOut)); } if (r->out.pcbAuxOut == NULL) { return ndr_push_error(ndr, NDR_ERR_INVALID_POINTER, "NULL [ref] pointer"); } NDR_CHECK(ndr_push_uint32(ndr, NDR_SCALARS, *r->out.pcbAuxOut)); NDR_CHECK(ndr_push_MAPISTATUS(ndr, NDR_SCALARS, r->out.result)); } return NDR_ERR_SUCCESS; } _PUBLIC_ enum ndr_err_code ndr_pull_EcDoConnectEx(struct ndr_pull *ndr, int flags, struct EcDoConnectEx *r) { uint32_t _ptr_szDNPrefix; uint32_t _ptr_szDisplayName; uint32_t cntr_rgwClientVersion_0; uint32_t cntr_rgwServerVersion_0; uint32_t cntr_rgwBestVersion_0; TALLOC_CTX *_mem_save_handle_0; TALLOC_CTX *_mem_save_pcmsPollsMax_0; TALLOC_CTX *_mem_save_pcRetry_0; TALLOC_CTX *_mem_save_pcmsRetryDelay_0; TALLOC_CTX *_mem_save_picxr_0; TALLOC_CTX *_mem_save_szDNPrefix_0; TALLOC_CTX *_mem_save_szDNPrefix_1; TALLOC_CTX *_mem_save_szDisplayName_0; TALLOC_CTX *_mem_save_szDisplayName_1; TALLOC_CTX *_mem_save_pulTimeStamp_0; TALLOC_CTX *_mem_save_rgbAuxIn_0; TALLOC_CTX *_mem_save_pcbAuxOut_0; TALLOC_CTX *_mem_save_rgbAuxOut_1; if (flags & NDR_IN) { ZERO_STRUCT(r->out); NDR_CHECK(ndr_pull_array_size(ndr, &r->in.szUserDN)); NDR_CHECK(ndr_pull_array_length(ndr, &r->in.szUserDN)); if (ndr_get_array_length(ndr, &r->in.szUserDN) > ndr_get_array_size(ndr, &r->in.szUserDN)) { return ndr_pull_error(ndr, NDR_ERR_ARRAY_SIZE, "Bad array size %u should exceed array length %u", ndr_get_array_size(ndr, &r->in.szUserDN), ndr_get_array_length(ndr, &r->in.szUserDN)); } NDR_CHECK(ndr_check_string_terminator(ndr, ndr_get_array_length(ndr, &r->in.szUserDN), sizeof(uint8_t))); NDR_CHECK(ndr_pull_charset(ndr, NDR_SCALARS, &r->in.szUserDN, ndr_get_array_length(ndr, &r->in.szUserDN), sizeof(uint8_t), CH_DOS)); NDR_CHECK(ndr_pull_uint32(ndr, NDR_SCALARS, &r->in.ulFlags)); NDR_CHECK(ndr_pull_uint32(ndr, NDR_SCALARS, &r->in.ulConMod)); NDR_CHECK(ndr_pull_uint32(ndr, NDR_SCALARS, &r->in.cbLimit)); NDR_CHECK(ndr_pull_uint32(ndr, NDR_SCALARS, &r->in.ulCpid)); NDR_CHECK(ndr_pull_uint32(ndr, NDR_SCALARS, &r->in.ulLcidString)); NDR_CHECK(ndr_pull_uint32(ndr, NDR_SCALARS, &r->in.ulLcidSort)); NDR_CHECK(ndr_pull_uint32(ndr, NDR_SCALARS, &r->in.ulIcxrLink)); NDR_CHECK(ndr_pull_uint16(ndr, NDR_SCALARS, &r->in.usFCanConvertCodePages)); for (cntr_rgwClientVersion_0 = 0; cntr_rgwClientVersion_0 < 3; cntr_rgwClientVersion_0++) { NDR_CHECK(ndr_pull_uint16(ndr, NDR_SCALARS, &r->in.rgwClientVersion[cntr_rgwClientVersion_0])); } if (ndr->flags & LIBNDR_FLAG_REF_ALLOC) { NDR_PULL_ALLOC(ndr, r->in.pulTimeStamp); } _mem_save_pulTimeStamp_0 = NDR_PULL_GET_MEM_CTX(ndr); NDR_PULL_SET_MEM_CTX(ndr, r->in.pulTimeStamp, LIBNDR_FLAG_REF_ALLOC); NDR_CHECK(ndr_pull_uint32(ndr, NDR_SCALARS, r->in.pulTimeStamp)); NDR_PULL_SET_MEM_CTX(ndr, _mem_save_pulTimeStamp_0, LIBNDR_FLAG_REF_ALLOC); { uint32_t _flags_save_mapi2k7_AuxInfo = ndr->flags; ndr_set_flags(&ndr->flags, LIBNDR_FLAG_NOALIGN|LIBNDR_FLAG_REMAINING); if (ndr->flags & LIBNDR_FLAG_REF_ALLOC) { NDR_PULL_ALLOC(ndr, r->in.rgbAuxIn); } _mem_save_rgbAuxIn_0 = NDR_PULL_GET_MEM_CTX(ndr); NDR_PULL_SET_MEM_CTX(ndr, r->in.rgbAuxIn, LIBNDR_FLAG_REF_ALLOC); { struct ndr_pull *_ndr_rgbAuxIn; NDR_CHECK(ndr_pull_subcontext_start(ndr, &_ndr_rgbAuxIn, 4, -1)); NDR_CHECK(ndr_pull_mapi2k7_AuxInfo(_ndr_rgbAuxIn, NDR_SCALARS|NDR_BUFFERS, r->in.rgbAuxIn)); NDR_CHECK(ndr_pull_subcontext_end(ndr, _ndr_rgbAuxIn, 4, -1)); } NDR_PULL_SET_MEM_CTX(ndr, _mem_save_rgbAuxIn_0, LIBNDR_FLAG_REF_ALLOC); ndr->flags = _flags_save_mapi2k7_AuxInfo; } NDR_CHECK(ndr_pull_uint32(ndr, NDR_SCALARS, &r->in.cbAuxIn)); if (ndr->flags & LIBNDR_FLAG_REF_ALLOC) { NDR_PULL_ALLOC(ndr, r->in.pcbAuxOut); } _mem_save_pcbAuxOut_0 = NDR_PULL_GET_MEM_CTX(ndr); NDR_PULL_SET_MEM_CTX(ndr, r->in.pcbAuxOut, LIBNDR_FLAG_REF_ALLOC); NDR_CHECK(ndr_pull_uint32(ndr, NDR_SCALARS, r->in.pcbAuxOut)); if (*r->in.pcbAuxOut > 0x1008) { return ndr_pull_error(ndr, NDR_ERR_RANGE, "value out of range"); } NDR_PULL_SET_MEM_CTX(ndr, _mem_save_pcbAuxOut_0, LIBNDR_FLAG_REF_ALLOC); NDR_PULL_ALLOC(ndr, r->out.handle); ZERO_STRUCTP(r->out.handle); NDR_PULL_ALLOC(ndr, r->out.pcmsPollsMax); ZERO_STRUCTP(r->out.pcmsPollsMax); NDR_PULL_ALLOC(ndr, r->out.pcRetry); ZERO_STRUCTP(r->out.pcRetry); NDR_PULL_ALLOC(ndr, r->out.pcmsRetryDelay); ZERO_STRUCTP(r->out.pcmsRetryDelay); NDR_PULL_ALLOC(ndr, r->out.picxr); ZERO_STRUCTP(r->out.picxr); NDR_PULL_ALLOC(ndr, r->out.szDNPrefix); ZERO_STRUCTP(r->out.szDNPrefix); NDR_PULL_ALLOC(ndr, r->out.szDisplayName); ZERO_STRUCTP(r->out.szDisplayName); NDR_PULL_ALLOC(ndr, r->out.pulTimeStamp); *r->out.pulTimeStamp = *r->in.pulTimeStamp; NDR_PULL_ALLOC(ndr, r->out.pcbAuxOut); *r->out.pcbAuxOut = *r->in.pcbAuxOut; } if (flags & NDR_OUT) { if (ndr->flags & LIBNDR_FLAG_REF_ALLOC) { NDR_PULL_ALLOC(ndr, r->out.handle); } _mem_save_handle_0 = NDR_PULL_GET_MEM_CTX(ndr); NDR_PULL_SET_MEM_CTX(ndr, r->out.handle, LIBNDR_FLAG_REF_ALLOC); NDR_CHECK(ndr_pull_policy_handle(ndr, NDR_SCALARS|NDR_BUFFERS, r->out.handle)); NDR_PULL_SET_MEM_CTX(ndr, _mem_save_handle_0, LIBNDR_FLAG_REF_ALLOC); if (ndr->flags & LIBNDR_FLAG_REF_ALLOC) { NDR_PULL_ALLOC(ndr, r->out.pcmsPollsMax); } _mem_save_pcmsPollsMax_0 = NDR_PULL_GET_MEM_CTX(ndr); NDR_PULL_SET_MEM_CTX(ndr, r->out.pcmsPollsMax, LIBNDR_FLAG_REF_ALLOC); NDR_CHECK(ndr_pull_uint32(ndr, NDR_SCALARS, r->out.pcmsPollsMax)); NDR_PULL_SET_MEM_CTX(ndr, _mem_save_pcmsPollsMax_0, LIBNDR_FLAG_REF_ALLOC); if (ndr->flags & LIBNDR_FLAG_REF_ALLOC) { NDR_PULL_ALLOC(ndr, r->out.pcRetry); } _mem_save_pcRetry_0 = NDR_PULL_GET_MEM_CTX(ndr); NDR_PULL_SET_MEM_CTX(ndr, r->out.pcRetry, LIBNDR_FLAG_REF_ALLOC); NDR_CHECK(ndr_pull_uint32(ndr, NDR_SCALARS, r->out.pcRetry)); NDR_PULL_SET_MEM_CTX(ndr, _mem_save_pcRetry_0, LIBNDR_FLAG_REF_ALLOC); if (ndr->flags & LIBNDR_FLAG_REF_ALLOC) { NDR_PULL_ALLOC(ndr, r->out.pcmsRetryDelay); } _mem_save_pcmsRetryDelay_0 = NDR_PULL_GET_MEM_CTX(ndr); NDR_PULL_SET_MEM_CTX(ndr, r->out.pcmsRetryDelay, LIBNDR_FLAG_REF_ALLOC); NDR_CHECK(ndr_pull_uint32(ndr, NDR_SCALARS, r->out.pcmsRetryDelay)); NDR_PULL_SET_MEM_CTX(ndr, _mem_save_pcmsRetryDelay_0, LIBNDR_FLAG_REF_ALLOC); if (ndr->flags & LIBNDR_FLAG_REF_ALLOC) { NDR_PULL_ALLOC(ndr, r->out.picxr); } _mem_save_picxr_0 = NDR_PULL_GET_MEM_CTX(ndr); NDR_PULL_SET_MEM_CTX(ndr, r->out.picxr, LIBNDR_FLAG_REF_ALLOC); NDR_CHECK(ndr_pull_uint32(ndr, NDR_SCALARS, r->out.picxr)); NDR_PULL_SET_MEM_CTX(ndr, _mem_save_picxr_0, LIBNDR_FLAG_REF_ALLOC); _mem_save_szDNPrefix_0 = NDR_PULL_GET_MEM_CTX(ndr); NDR_PULL_SET_MEM_CTX(ndr, r->out.szDNPrefix, LIBNDR_FLAG_REF_ALLOC); NDR_CHECK(ndr_pull_generic_ptr(ndr, &_ptr_szDNPrefix)); if (_ptr_szDNPrefix) { NDR_PULL_ALLOC(ndr, *r->out.szDNPrefix); } else { *r->out.szDNPrefix = NULL; } if (*r->out.szDNPrefix) { _mem_save_szDNPrefix_1 = NDR_PULL_GET_MEM_CTX(ndr); NDR_PULL_SET_MEM_CTX(ndr, *r->out.szDNPrefix, 0); NDR_CHECK(ndr_pull_array_size(ndr, r->out.szDNPrefix)); NDR_CHECK(ndr_pull_array_length(ndr, r->out.szDNPrefix)); if (ndr_get_array_length(ndr, r->out.szDNPrefix) > ndr_get_array_size(ndr, r->out.szDNPrefix)) { return ndr_pull_error(ndr, NDR_ERR_ARRAY_SIZE, "Bad array size %u should exceed array length %u", ndr_get_array_size(ndr, r->out.szDNPrefix), ndr_get_array_length(ndr, r->out.szDNPrefix)); } NDR_CHECK(ndr_check_string_terminator(ndr, ndr_get_array_length(ndr, r->out.szDNPrefix), sizeof(uint8_t))); NDR_CHECK(ndr_pull_charset(ndr, NDR_SCALARS, r->out.szDNPrefix, ndr_get_array_length(ndr, r->out.szDNPrefix), sizeof(uint8_t), CH_DOS)); NDR_PULL_SET_MEM_CTX(ndr, _mem_save_szDNPrefix_1, 0); } NDR_PULL_SET_MEM_CTX(ndr, _mem_save_szDNPrefix_0, LIBNDR_FLAG_REF_ALLOC); if (ndr->flags & LIBNDR_FLAG_REF_ALLOC) { NDR_PULL_ALLOC(ndr, r->out.szDisplayName); } _mem_save_szDisplayName_0 = NDR_PULL_GET_MEM_CTX(ndr); NDR_PULL_SET_MEM_CTX(ndr, r->out.szDisplayName, LIBNDR_FLAG_REF_ALLOC); NDR_CHECK(ndr_pull_generic_ptr(ndr, &_ptr_szDisplayName)); if (_ptr_szDisplayName) { NDR_PULL_ALLOC(ndr, *r->out.szDisplayName); } else { *r->out.szDisplayName = NULL; } if (*r->out.szDisplayName) { _mem_save_szDisplayName_1 = NDR_PULL_GET_MEM_CTX(ndr); NDR_PULL_SET_MEM_CTX(ndr, *r->out.szDisplayName, 0); NDR_CHECK(ndr_pull_array_size(ndr, r->out.szDisplayName)); NDR_CHECK(ndr_pull_array_length(ndr, r->out.szDisplayName)); if (ndr_get_array_length(ndr, r->out.szDisplayName) > ndr_get_array_size(ndr, r->out.szDisplayName)) { return ndr_pull_error(ndr, NDR_ERR_ARRAY_SIZE, "Bad array size %u should exceed array length %u", ndr_get_array_size(ndr, r->out.szDisplayName), ndr_get_array_length(ndr, r->out.szDisplayName)); } NDR_CHECK(ndr_check_string_terminator(ndr, ndr_get_array_length(ndr, r->out.szDisplayName), sizeof(uint8_t))); NDR_CHECK(ndr_pull_charset(ndr, NDR_SCALARS, r->out.szDisplayName, ndr_get_array_length(ndr, r->out.szDisplayName), sizeof(uint8_t), CH_DOS)); NDR_PULL_SET_MEM_CTX(ndr, _mem_save_szDisplayName_1, 0); } NDR_PULL_SET_MEM_CTX(ndr, _mem_save_szDisplayName_0, LIBNDR_FLAG_REF_ALLOC); for (cntr_rgwServerVersion_0 = 0; cntr_rgwServerVersion_0 < 3; cntr_rgwServerVersion_0++) { NDR_CHECK(ndr_pull_uint16(ndr, NDR_SCALARS, &r->out.rgwServerVersion[cntr_rgwServerVersion_0])); } for (cntr_rgwBestVersion_0 = 0; cntr_rgwBestVersion_0 < 3; cntr_rgwBestVersion_0++) { NDR_CHECK(ndr_pull_uint16(ndr, NDR_SCALARS, &r->out.rgwBestVersion[cntr_rgwBestVersion_0])); } if (ndr->flags & LIBNDR_FLAG_REF_ALLOC) { NDR_PULL_ALLOC(ndr, r->out.pulTimeStamp); } _mem_save_pulTimeStamp_0 = NDR_PULL_GET_MEM_CTX(ndr); NDR_PULL_SET_MEM_CTX(ndr, r->out.pulTimeStamp, LIBNDR_FLAG_REF_ALLOC); NDR_CHECK(ndr_pull_uint32(ndr, NDR_SCALARS, r->out.pulTimeStamp)); NDR_PULL_SET_MEM_CTX(ndr, _mem_save_pulTimeStamp_0, LIBNDR_FLAG_REF_ALLOC); NDR_CHECK(ndr_pull_array_size(ndr, &r->out.rgbAuxOut)); NDR_CHECK(ndr_pull_array_length(ndr, &r->out.rgbAuxOut)); if (ndr_get_array_length(ndr, &r->out.rgbAuxOut) > ndr_get_array_size(ndr, &r->out.rgbAuxOut)) { return ndr_pull_error(ndr, NDR_ERR_ARRAY_SIZE, "Bad array size %u should exceed array length %u", ndr_get_array_size(ndr, &r->out.rgbAuxOut), ndr_get_array_length(ndr, &r->out.rgbAuxOut)); } if (ndr->flags & LIBNDR_FLAG_REF_ALLOC) { NDR_PULL_ALLOC_N(ndr, r->out.rgbAuxOut, ndr_get_array_size(ndr, &r->out.rgbAuxOut)); } /* Only try to pull rgbAuxOut if the fake array size is > 0 */ if (ndr_get_array_size(ndr, &r->out.rgbAuxOut)) { _mem_save_rgbAuxOut_1 = NDR_PULL_GET_MEM_CTX(ndr); NDR_PULL_SET_MEM_CTX(ndr, r->out.rgbAuxOut, 0); NDR_CHECK(ndr_pull_mapi2k7_AuxInfo(ndr, NDR_SCALARS, r->out.rgbAuxOut)); NDR_PULL_SET_MEM_CTX(ndr, _mem_save_rgbAuxOut_1, 0); } if (ndr->flags & LIBNDR_FLAG_REF_ALLOC) { NDR_PULL_ALLOC(ndr, r->out.pcbAuxOut); } _mem_save_pcbAuxOut_0 = NDR_PULL_GET_MEM_CTX(ndr); NDR_PULL_SET_MEM_CTX(ndr, r->out.pcbAuxOut, LIBNDR_FLAG_REF_ALLOC); NDR_CHECK(ndr_pull_uint32(ndr, NDR_SCALARS, r->out.pcbAuxOut)); if (*r->out.pcbAuxOut > 0x1008) { return ndr_pull_error(ndr, NDR_ERR_RANGE, "value out of range"); } NDR_PULL_SET_MEM_CTX(ndr, _mem_save_pcbAuxOut_0, LIBNDR_FLAG_REF_ALLOC); NDR_CHECK(ndr_pull_MAPISTATUS(ndr, NDR_SCALARS, &r->out.result)); } return NDR_ERR_SUCCESS; } _PUBLIC_ void ndr_print_EcDoConnectEx(struct ndr_print *ndr, const char *name, int flags, const struct EcDoConnectEx *r) { uint32_t cntr_rgwClientVersion_0; uint32_t cntr_rgwServerVersion_0; uint32_t cntr_rgwBestVersion_0; ndr_print_struct(ndr, name, "EcDoConnectEx"); ndr->depth++; if (flags & NDR_SET_VALUES) { ndr->flags |= LIBNDR_PRINT_SET_VALUES; } if (flags & NDR_IN) { ndr_print_struct(ndr, "in", "EcDoConnectEx"); ndr->depth++; ndr_print_string(ndr, "szUserDN", r->in.szUserDN); ndr_print_uint32(ndr, "ulFlags", r->in.ulFlags); ndr_print_uint32(ndr, "ulConMod", r->in.ulConMod); ndr_print_uint32(ndr, "cbLimit", r->in.cbLimit); ndr_print_uint32(ndr, "ulCpid", r->in.ulCpid); ndr_print_uint32(ndr, "ulLcidString", r->in.ulLcidString); ndr_print_uint32(ndr, "ulLcidSort", r->in.ulLcidSort); ndr_print_uint32(ndr, "ulIcxrLink", r->in.ulIcxrLink); ndr_print_uint16(ndr, "usFCanConvertCodePages", r->in.usFCanConvertCodePages); ndr->print(ndr, "%s: ARRAY(%d)", "rgwClientVersion", (int)3); ndr->depth++; for (cntr_rgwClientVersion_0=0;cntr_rgwClientVersion_0<3;cntr_rgwClientVersion_0++) { char *idx_0=NULL; if (asprintf(&idx_0, "[%d]", cntr_rgwClientVersion_0) != -1) { ndr_print_uint16(ndr, "rgwClientVersion", r->in.rgwClientVersion[cntr_rgwClientVersion_0]); free(idx_0); } } ndr->depth--; ndr_print_ptr(ndr, "pulTimeStamp", r->in.pulTimeStamp); ndr->depth++; ndr_print_uint32(ndr, "pulTimeStamp", *r->in.pulTimeStamp); ndr->depth--; ndr_print_ptr(ndr, "rgbAuxIn", r->in.rgbAuxIn); if (r->in.rgbAuxIn) { ndr->depth++; ndr_print_mapi2k7_AuxInfo(ndr, "rgbAuxIn", r->in.rgbAuxIn); ndr->depth--; } ndr_print_uint32(ndr, "cbAuxIn", r->in.cbAuxIn); ndr_print_ptr(ndr, "pcbAuxOut", r->in.pcbAuxOut); ndr->depth++; ndr_print_uint32(ndr, "pcbAuxOut", *r->in.pcbAuxOut); ndr->depth--; ndr->depth--; } if (flags & NDR_OUT) { ndr_print_struct(ndr, "out", "EcDoConnectEx"); ndr->depth++; ndr_print_ptr(ndr, "handle", r->out.handle); ndr->depth++; ndr_print_policy_handle(ndr, "handle", r->out.handle); ndr->depth--; ndr_print_ptr(ndr, "pcmsPollsMax", r->out.pcmsPollsMax); ndr->depth++; ndr_print_uint32(ndr, "pcmsPollsMax", *r->out.pcmsPollsMax); ndr->depth--; ndr_print_ptr(ndr, "pcRetry", r->out.pcRetry); ndr->depth++; ndr_print_uint32(ndr, "pcRetry", *r->out.pcRetry); ndr->depth--; ndr_print_ptr(ndr, "pcmsRetryDelay", r->out.pcmsRetryDelay); ndr->depth++; ndr_print_uint32(ndr, "pcmsRetryDelay", *r->out.pcmsRetryDelay); ndr->depth--; ndr_print_ptr(ndr, "picxr", r->out.picxr); ndr->depth++; ndr_print_uint32(ndr, "picxr", *r->out.picxr); ndr->depth--; ndr_print_ptr(ndr, "szDNPrefix", r->out.szDisplayName); ndr->depth++; if (r->out.szDNPrefix && *r->out.szDNPrefix) { ndr_print_ptr(ndr, "szDNPrefix", *r->out.szDNPrefix); ndr->depth++; ndr_print_string(ndr, "szDNPrefix", *r->out.szDNPrefix); ndr->depth--; } ndr->depth--; ndr_print_ptr(ndr, "szDisplayName", r->out.szDisplayName); ndr->depth++; if (r->out.szDisplayName && *r->out.szDisplayName) { ndr_print_ptr(ndr, "szDisplayName", *r->out.szDisplayName); ndr->depth++; ndr_print_string(ndr, "szDisplayName", *r->out.szDisplayName); ndr->depth--; } ndr->depth--; ndr->print(ndr, "%s: ARRAY(%d)", "rgwServerVersion", (int)3); ndr->depth++; for (cntr_rgwServerVersion_0=0;cntr_rgwServerVersion_0<3;cntr_rgwServerVersion_0++) { char *idx_0=NULL; if (asprintf(&idx_0, "[%d]", cntr_rgwServerVersion_0) != -1) { ndr_print_uint16(ndr, "rgwServerVersion", r->out.rgwServerVersion[cntr_rgwServerVersion_0]); free(idx_0); } } ndr->depth--; ndr->print(ndr, "%s: ARRAY(%d)", "rgwBestVersion", (int)3); ndr->depth++; for (cntr_rgwBestVersion_0=0;cntr_rgwBestVersion_0<3;cntr_rgwBestVersion_0++) { char *idx_0=NULL; if (asprintf(&idx_0, "[%d]", cntr_rgwBestVersion_0) != -1) { ndr_print_uint16(ndr, "rgwBestVersion", r->out.rgwBestVersion[cntr_rgwBestVersion_0]); free(idx_0); } } ndr->depth--; ndr_print_ptr(ndr, "pulTimeStamp", r->out.pulTimeStamp); if (r->out.pulTimeStamp) { ndr->depth++; ndr_print_uint32(ndr, "pulTimeStamp", *r->out.pulTimeStamp); ndr->depth--; } ndr_print_ptr(ndr, "rgbAuxOut", r->out.rgbAuxOut); if (r->out.rgbAuxOut && r->out.pcbAuxOut) { ndr->depth++; ndr_print_mapi2k7_AuxInfo(ndr, "rgbAuxOut", r->out.rgbAuxOut); ndr->depth--; } ndr_print_ptr(ndr, "pcbAuxOut", r->out.pcbAuxOut); if (r->out.pcbAuxOut) { ndr->depth++; ndr_print_uint32(ndr, "pcbAuxOut", *r->out.pcbAuxOut); ndr->depth--; } ndr_print_MAPISTATUS(ndr, "result", r->out.result); ndr->depth--; } ndr->depth--; } _PUBLIC_ void ndr_print_EcDoRpcExt(struct ndr_print *ndr, const char *name, int flags, const struct EcDoRpcExt *r) { DATA_BLOB rgbIn; DATA_BLOB rgbOut; struct ndr_pull *ndr_pull; struct mapi2k7_request *mapi_request; struct mapi2k7_response *mapi_response; TALLOC_CTX *mem_ctx; mem_ctx = talloc_named(NULL, 0, "ndr_print_EcDoRpcExt2"); ndr_print_struct(ndr, name, "EcDoRpcExt"); if (r == NULL) { ndr_print_null(ndr); return; } ndr->depth++; if (flags & NDR_SET_VALUES) { ndr->flags |= LIBNDR_PRINT_SET_VALUES; } if (flags & NDR_IN) { ndr_print_struct(ndr, "in", "EcDoRpcExt"); ndr->depth++; ndr_print_ptr(ndr, "handle", r->in.handle); ndr->depth++; ndr_print_policy_handle(ndr, "handle", r->in.handle); ndr->depth--; ndr_print_ptr(ndr, "pulFlags", r->in.pulFlags); ndr->depth++; ndr_print_uint32(ndr, "pulFlags", *r->in.pulFlags); ndr->depth--; /* Put MAPI request blob into a ndr_pull structure */ rgbIn.data = talloc_memdup(mem_ctx, r->in.rgbIn, r->in.cbIn); rgbIn.length = r->in.cbIn; dump_data(0, rgbIn.data, rgbIn.length); ndr_pull = ndr_pull_init_blob(&rgbIn, mem_ctx); ndr_set_flags(&ndr_pull->flags, LIBNDR_FLAG_NOALIGN); mapi_request = talloc_zero(mem_ctx, struct mapi2k7_request); mapi_request->mapi_request = talloc_zero(mapi_request, struct mapi_request); ndr_pull_mapi2k7_request(ndr_pull, NDR_SCALARS|NDR_BUFFERS, mapi_request); ndr_print_mapi2k7_request(ndr, "mapi_request", (const struct mapi2k7_request *)mapi_request); talloc_free(mapi_request); talloc_free(ndr_pull); talloc_free(rgbIn.data); ndr_print_uint32(ndr, "cbIn", r->in.cbIn); ndr_print_ptr(ndr, "pcbOut", r->in.pcbOut); ndr->depth++; ndr_print_uint32(ndr, "pcbOut", *r->in.pcbOut); ndr->depth--; ndr_print_array_uint8(ndr, "Reserved0", r->in.Reserved0, *r->in.Reserved1); ndr_print_ptr(ndr, "Reserved1", r->in.Reserved1); ndr->depth++; ndr_print_uint32(ndr, "Reserved1", *r->in.Reserved1); ndr->depth--; ndr->depth--; } if (flags & NDR_OUT) { ndr_print_struct(ndr, "out", "EcDoRpcExt"); ndr->depth++; ndr_print_ptr(ndr, "handle", r->out.handle); ndr->depth++; ndr_print_policy_handle(ndr, "handle", r->out.handle); ndr->depth--; ndr_print_ptr(ndr, "pulFlags", r->out.pulFlags); ndr->depth++; ndr_print_uint32(ndr, "pulFlags", *r->out.pulFlags); ndr->depth--; /* Put MAPI response blob into a ndr_pull structure */ if (*r->out.pcbOut) { rgbOut.data = talloc_memdup(mem_ctx, r->out.rgbOut, *r->out.pcbOut); rgbOut.length = *r->out.pcbOut; ndr_pull = ndr_pull_init_blob(&rgbOut, mem_ctx); ndr_set_flags(&ndr_pull->flags, LIBNDR_FLAG_NOALIGN); while (ndr_pull->offset < ndr_pull->data_size) { mapi_response = talloc_zero(NULL, struct mapi2k7_response); mapi_response->mapi_response = talloc_zero(mapi_response, struct mapi_response); ndr_pull_mapi2k7_response(ndr_pull, NDR_SCALARS|NDR_BUFFERS, mapi_response); ndr_print_mapi2k7_response(ndr, "mapi_response", (const struct mapi2k7_response *)mapi_response); talloc_free(mapi_response); } talloc_free(ndr_pull); talloc_free(rgbOut.data); } ndr_print_ptr(ndr, "pcbOut", r->out.pcbOut); ndr->depth++; ndr_print_uint32(ndr, "pcbOut", *r->out.pcbOut); ndr->depth--; ndr_print_array_uint8(ndr, "Reserved0", r->out.Reserved0, *r->out.Reserved1); ndr_print_ptr(ndr, "Reserved1", r->out.Reserved1); ndr->depth++; ndr_print_uint32(ndr, "Reserved1", *r->out.Reserved1); ndr->depth--; ndr_print_ptr(ndr, "pulTransTime", r->out.pulTransTime); ndr->depth++; ndr_print_uint32(ndr, "pulTransTime", *r->out.pulTransTime); ndr->depth--; ndr_print_MAPISTATUS(ndr, "result", r->out.result); ndr->depth--; } ndr->depth--; talloc_free(mem_ctx); } _PUBLIC_ void ndr_print_EcDoRpcExt2(struct ndr_print *ndr, const char *name, int flags, const struct EcDoRpcExt2 *r) { uint32_t cntr_rgbAuxOut_0; DATA_BLOB rgbIn; DATA_BLOB rgbAuxIn; DATA_BLOB rgbOut; struct ndr_pull *ndr_pull; struct mapi2k7_request *mapi_request; struct mapi2k7_response *mapi_response; TALLOC_CTX *mem_ctx; mem_ctx = talloc_named(NULL, 0, "ndr_print_EcDoRpcExt2"); ndr_print_struct(ndr, name, "EcDoRpcExt2"); ndr->depth++; if (flags & NDR_SET_VALUES) { ndr->flags |= LIBNDR_PRINT_SET_VALUES; } if (flags & NDR_IN) { ndr_print_struct(ndr, "in", "EcDoRpcExt2"); ndr->depth++; ndr_print_ptr(ndr, "handle", r->in.handle); ndr->depth++; ndr_print_policy_handle(ndr, "handle", r->in.handle); ndr->depth--; ndr_print_ptr(ndr, "pulFlags", r->in.pulFlags); ndr->depth++; ndr_print_uint32(ndr, "pulFlags", *r->in.pulFlags); ndr->depth--; /* Put MAPI request blob into a ndr_pull structure */ rgbIn.data = (uint8_t *)talloc_memdup(mem_ctx, r->in.rgbIn, r->in.cbIn); rgbIn.length = r->in.cbIn; dump_data(0, rgbIn.data, rgbIn.length); ndr_pull = ndr_pull_init_blob(&rgbIn, mem_ctx); ndr_set_flags(&ndr_pull->flags, LIBNDR_FLAG_NOALIGN); mapi_request = talloc_zero(mem_ctx, struct mapi2k7_request); mapi_request->mapi_request = talloc_zero(mapi_request, struct mapi_request); ndr_pull_mapi2k7_request(ndr_pull, NDR_SCALARS|NDR_BUFFERS, mapi_request); ndr_print_mapi2k7_request(ndr, "mapi_request", (const struct mapi2k7_request *)mapi_request); talloc_free(mapi_request); talloc_free(ndr_pull); talloc_free(rgbIn.data); ndr_print_uint32(ndr, "cbIn", r->in.cbIn); ndr_print_ptr(ndr, "pcbOut", r->in.pcbOut); ndr->depth++; ndr_print_uint32(ndr, "pcbOut", *r->in.pcbOut); ndr->depth--; rgbAuxIn.data = r->in.rgbAuxIn; rgbAuxIn.length = r->in.cbAuxIn; ndr_print_DATA_BLOB(ndr, "rgbAuxIn", rgbAuxIn); /* ndr_print_array_uint8(ndr, "rgbAuxIn", r->in.rgbAuxIn, r->in.cbAuxIn); */ ndr_print_uint32(ndr, "cbAuxIn", r->in.cbAuxIn); ndr_print_ptr(ndr, "pcbAuxOut", r->in.pcbAuxOut); ndr->depth++; ndr_print_uint32(ndr, "pcbAuxOut", *r->in.pcbAuxOut); ndr->depth--; ndr->depth--; } if (flags & NDR_OUT) { ndr_print_struct(ndr, "out", "EcDoRpcExt2"); ndr->depth++; ndr_print_ptr(ndr, "handle", r->out.handle); ndr->depth++; ndr_print_policy_handle(ndr, "handle", r->out.handle); ndr->depth--; ndr_print_ptr(ndr, "pulFlags", r->out.pulFlags); ndr->depth++; ndr_print_uint32(ndr, "pulFlags", *r->out.pulFlags); ndr->depth--; /* Put MAPI response blob into a ndr_pull structure */ if (*r->out.pcbOut) { rgbOut.data = (uint8_t *)talloc_memdup(mem_ctx, r->out.rgbOut, *r->out.pcbOut); rgbOut.length = *r->out.pcbOut; ndr_pull = ndr_pull_init_blob(&rgbOut, mem_ctx); ndr_set_flags(&ndr_pull->flags, LIBNDR_FLAG_NOALIGN); while (ndr_pull->offset < ndr_pull->data_size) { mapi_response = talloc_zero(NULL, struct mapi2k7_response); mapi_response->mapi_response = talloc_zero(mapi_response, struct mapi_response); ndr_pull_mapi2k7_response(ndr_pull, NDR_SCALARS|NDR_BUFFERS, mapi_response); ndr_print_mapi2k7_response(ndr, "mapi_response", (const struct mapi2k7_response *)mapi_response); talloc_free(mapi_response); } talloc_free(ndr_pull); talloc_free(rgbOut.data); } /* ndr_print_array_uint8(ndr, "rgbOut", r->out.rgbOut, *r->out.pcbOut); */ ndr_print_ptr(ndr, "pcbOut", r->out.pcbOut); ndr->depth++; ndr_print_uint32(ndr, "pcbOut", *r->out.pcbOut); ndr->depth--; if (r->out.rgbAuxOut && r->out.pcbAuxOut) { ndr->print(ndr, "%s: ARRAY(%d)", "rgbAuxOut", (int)*r->out.pcbAuxOut); ndr->depth++; for (cntr_rgbAuxOut_0=0;cntr_rgbAuxOut_0<*r->out.pcbAuxOut;cntr_rgbAuxOut_0++) { char *idx_0=NULL; if (asprintf(&idx_0, "[%d]", cntr_rgbAuxOut_0) != -1) { ndr_print_uint32(ndr, "rgbAuxOut", r->out.rgbAuxOut[cntr_rgbAuxOut_0]); free(idx_0); } } } else { ndr->print(ndr, "%s: NULL", "rgbAuxOut"); } ndr->depth--; ndr_print_ptr(ndr, "pcbAuxOut", r->out.pcbAuxOut); ndr->depth++; ndr_print_uint32(ndr, "pcbAuxOut", *r->out.pcbAuxOut); ndr->depth--; ndr_print_ptr(ndr, "pulTransTime", r->out.pulTransTime); ndr->depth++; ndr_print_uint32(ndr, "pulTransTime", *r->out.pulTransTime); ndr->depth--; ndr_print_MAPISTATUS(ndr, "result", r->out.result); ndr->depth--; } ndr->depth--; talloc_free(mem_ctx); } /* We need to pull QueryRows replies on our own: If we have no results, do not push/pull the DATA_BLOB */ enum ndr_err_code ndr_push_QueryRows_repl(struct ndr_push *ndr, int ndr_flags, const struct QueryRows_repl *r) { { uint32_t _flags_save_STRUCT = ndr->flags; ndr_set_flags(&ndr->flags, LIBNDR_FLAG_NOALIGN); if (ndr_flags & NDR_SCALARS) { NDR_CHECK(ndr_push_align(ndr, 4)); NDR_CHECK(ndr_push_uint8(ndr, NDR_SCALARS, r->Origin)); NDR_CHECK(ndr_push_uint16(ndr, NDR_SCALARS, r->RowCount)); if (r->RowCount) { uint32_t _flags_save_DATA_BLOB = ndr->flags; ndr_set_flags(&ndr->flags, LIBNDR_FLAG_REMAINING); NDR_CHECK(ndr_push_DATA_BLOB(ndr, NDR_SCALARS, r->RowData)); ndr->flags = _flags_save_DATA_BLOB; } } if (ndr_flags & NDR_BUFFERS) { } ndr->flags = _flags_save_STRUCT; } return NDR_ERR_SUCCESS; } enum ndr_err_code ndr_pull_QueryRows_repl(struct ndr_pull *ndr, int ndr_flags, struct QueryRows_repl *r) { { uint32_t _flags_save_STRUCT = ndr->flags; ndr_set_flags(&ndr->flags, LIBNDR_FLAG_NOALIGN); if (ndr_flags & NDR_SCALARS) { NDR_CHECK(ndr_pull_align(ndr, 4)); NDR_CHECK(ndr_pull_uint8(ndr, NDR_SCALARS, &r->Origin)); NDR_CHECK(ndr_pull_uint16(ndr, NDR_SCALARS, &r->RowCount)); if (r->RowCount) { uint32_t _flags_save_DATA_BLOB = ndr->flags; ndr_set_flags(&ndr->flags, LIBNDR_FLAG_REMAINING); NDR_CHECK(ndr_pull_DATA_BLOB(ndr, NDR_SCALARS, &r->RowData)); ndr->flags = _flags_save_DATA_BLOB; } else { r->RowData.length = 0; r->RowData.data = NULL; } } if (ndr_flags & NDR_BUFFERS) { } ndr->flags = _flags_save_STRUCT; } return NDR_ERR_SUCCESS; } enum ndr_err_code ndr_push_Logon_req(struct ndr_push *ndr, int ndr_flags, const struct Logon_req *r) { { uint32_t _flags_save_STRUCT = ndr->flags; ndr_set_flags(&ndr->flags, LIBNDR_FLAG_NOALIGN); if (ndr_flags & NDR_SCALARS) { NDR_CHECK(ndr_push_align(ndr, 4)); NDR_CHECK(ndr_push_LogonFlags(ndr, NDR_SCALARS, r->LogonFlags)); NDR_CHECK(ndr_push_OpenFlags(ndr, NDR_SCALARS, r->OpenFlags)); NDR_CHECK(ndr_push_StoreState(ndr, NDR_SCALARS, r->StoreState)); if (r->EssDN && r->EssDN[0] != '\0') { uint32_t _flags_save_string = ndr->flags; ndr_set_flags(&ndr->flags, LIBNDR_FLAG_STR_ASCII|LIBNDR_FLAG_STR_SIZE2); NDR_CHECK(ndr_push_string(ndr, NDR_SCALARS, r->EssDN)); ndr->flags = _flags_save_string; } else { NDR_CHECK(ndr_push_uint16(ndr, NDR_SCALARS, 0)); } } if (ndr_flags & NDR_BUFFERS) { } ndr->flags = _flags_save_STRUCT; } return NDR_ERR_SUCCESS; } /* MoveFolder */ enum ndr_err_code ndr_push_MoveFolder_repl(struct ndr_push *ndr, int ndr_flags, const struct MoveFolder_repl *r) { { uint32_t _flags_save_STRUCT = ndr->flags; ndr_set_flags(&ndr->flags, LIBNDR_FLAG_NOALIGN); if (ndr_flags & NDR_SCALARS) { NDR_CHECK(ndr_push_align(ndr, 4)); if (r->HasDestHandleIndex) { NDR_CHECK(ndr_push_uint32(ndr, NDR_SCALARS, r->DestHandleIndex)); } NDR_CHECK(ndr_push_uint8(ndr, NDR_SCALARS, r->PartialCompletion)); } if (ndr_flags & NDR_BUFFERS) { } ndr->flags = _flags_save_STRUCT; } return NDR_ERR_SUCCESS; } enum ndr_err_code ndr_pull_MoveFolder_repl(struct ndr_pull *ndr, int ndr_flags, struct MoveFolder_repl *r) { { uint32_t _flags_save_STRUCT = ndr->flags; ndr_set_flags(&ndr->flags, LIBNDR_FLAG_NOALIGN); if (ndr_flags & NDR_SCALARS) { NDR_CHECK(ndr_pull_align(ndr, 4)); if (r->HasDestHandleIndex) { NDR_CHECK(ndr_pull_uint32(ndr, NDR_SCALARS, &r->DestHandleIndex)); } NDR_CHECK(ndr_pull_uint8(ndr, NDR_SCALARS, &r->PartialCompletion)); } if (ndr_flags & NDR_BUFFERS) { } ndr->flags = _flags_save_STRUCT; } return NDR_ERR_SUCCESS; } _PUBLIC_ void ndr_print_MoveFolder_repl(struct ndr_print *ndr, const char *name, const struct MoveFolder_repl *r) { ndr_print_struct(ndr, name, "MoveFolder_repl"); if (r == NULL) { ndr_print_null(ndr); return; } { uint32_t _flags_save_STRUCT = ndr->flags; ndr_set_flags(&ndr->flags, LIBNDR_FLAG_NOALIGN); ndr->depth++; if (r->HasDestHandleIndex) { ndr_print_uint32(ndr, "DestHandleIndex", r->DestHandleIndex); } ndr_print_uint8(ndr, "PartialCompletion", r->PartialCompletion); ndr->depth--; ndr->flags = _flags_save_STRUCT; } } /* /MoveFolder */ /* CopyFolder */ enum ndr_err_code ndr_push_CopyFolder_repl(struct ndr_push *ndr, int ndr_flags, const struct CopyFolder_repl *r) { { uint32_t _flags_save_STRUCT = ndr->flags; ndr_set_flags(&ndr->flags, LIBNDR_FLAG_NOALIGN); if (ndr_flags & NDR_SCALARS) { NDR_CHECK(ndr_push_align(ndr, 4)); if (r->HasDestHandleIndex) { NDR_CHECK(ndr_push_uint32(ndr, NDR_SCALARS, r->DestHandleIndex)); } NDR_CHECK(ndr_push_uint8(ndr, NDR_SCALARS, r->PartialCompletion)); } if (ndr_flags & NDR_BUFFERS) { } ndr->flags = _flags_save_STRUCT; } return NDR_ERR_SUCCESS; } enum ndr_err_code ndr_pull_CopyFolder_repl(struct ndr_pull *ndr, int ndr_flags, struct CopyFolder_repl *r) { { uint32_t _flags_save_STRUCT = ndr->flags; ndr_set_flags(&ndr->flags, LIBNDR_FLAG_NOALIGN); if (ndr_flags & NDR_SCALARS) { NDR_CHECK(ndr_pull_align(ndr, 4)); if (r->HasDestHandleIndex) { NDR_CHECK(ndr_pull_uint32(ndr, NDR_SCALARS, &r->DestHandleIndex)); } NDR_CHECK(ndr_pull_uint8(ndr, NDR_SCALARS, &r->PartialCompletion)); } if (ndr_flags & NDR_BUFFERS) { } ndr->flags = _flags_save_STRUCT; } return NDR_ERR_SUCCESS; } _PUBLIC_ void ndr_print_CopyFolder_repl(struct ndr_print *ndr, const char *name, const struct CopyFolder_repl *r) { ndr_print_struct(ndr, name, "CopyFolder_repl"); if (r == NULL) { ndr_print_null(ndr); return; } { uint32_t _flags_save_STRUCT = ndr->flags; ndr_set_flags(&ndr->flags, LIBNDR_FLAG_NOALIGN); ndr->depth++; if (r->HasDestHandleIndex) { ndr_print_uint32(ndr, "DestHandleIndex", r->DestHandleIndex); } ndr_print_uint8(ndr, "PartialCompletion", r->PartialCompletion); ndr->depth--; ndr->flags = _flags_save_STRUCT; } } /* /CopyFolder */ _PUBLIC_ void ndr_print_SBinary_short(struct ndr_print *ndr, const char *name, const struct SBinary_short *r) { ndr->print(ndr, "%-25s: SBinary_short cb=%u", name, (unsigned)r->cb); { uint32_t _flags_save_STRUCT = ndr->flags; ndr_set_flags(&ndr->flags, LIBNDR_FLAG_NOALIGN); ndr->depth++; dump_data(0, r->lpb, r->cb); ndr->depth--; ndr->flags = _flags_save_STRUCT; } } _PUBLIC_ void ndr_print_Binary_r(struct ndr_print *ndr, const char *name, const struct Binary_r *r) { ndr->print(ndr, "%-25s: Binary_r cb=%u", name, (unsigned)r->cb); { uint32_t _flags_save_STRUCT = ndr->flags; ndr_set_flags(&ndr->flags, LIBNDR_FLAG_NOALIGN); ndr->depth++; dump_data(0, r->lpb, r->cb); ndr->depth--; ndr->flags = _flags_save_STRUCT; } } _PUBLIC_ void ndr_print_fuzzyLevel(struct ndr_print *ndr, const char *name, uint32_t r) { ndr_print_uint32(ndr, name, r); ndr->depth++; switch ((r & 0x0000FFFF)) { case FL_FULLSTRING: ndr->print(ndr, "%-25s: FL_FULLSTRING", "lower 16 bits"); break; case FL_SUBSTRING: ndr->print(ndr, "%-25s: FL_SUBSTRING", "lower 16 bits"); break; case FL_PREFIX: ndr->print(ndr, "%-25s: FL_PREFIX", "lower 16 bits"); break; } ndr->print(ndr, "%-25s", "higher 16 bits"); ndr_print_bitmap_flag(ndr, sizeof(uint32_t), "FL_IGNORECASE", FL_IGNORECASE, r); ndr_print_bitmap_flag(ndr, sizeof(uint32_t), "FL_IGNORENONSPACE", FL_IGNORENONSPACE, r); ndr_print_bitmap_flag(ndr, sizeof(uint32_t), "FL_LOOSE", FL_LOOSE, r); ndr->depth--; } /* * Fake wrapper over mapi_SRestriction. Workaround the no-pointer deep * recursion problem in pidl */ enum ndr_err_code ndr_push_mapi_SRestriction_wrap(struct ndr_push *ndr, int ndr_flags, const struct mapi_SRestriction_wrap *r) { return ndr_push_mapi_SRestriction(ndr, ndr_flags, (struct mapi_SRestriction *)r); } enum ndr_err_code ndr_pull_mapi_SRestriction_wrap(struct ndr_pull *ndr, int ndr_flags, struct mapi_SRestriction_wrap *r) { return ndr_pull_mapi_SRestriction(ndr, ndr_flags, (struct mapi_SRestriction *)r); } void ndr_print_mapi_SRestriction_wrap(struct ndr_print *ndr, const char *name, const struct mapi_SRestriction_wrap *r) { ndr_print_mapi_SRestriction(ndr, name, (const struct mapi_SRestriction *)r); } /* * Fake wrapper over mapi_SPropValue. Workaround the no-pointer deep * recursion problem in pidl */ enum ndr_err_code ndr_push_mapi_SPropValue_wrap(struct ndr_push *ndr, int ndr_flags, const struct mapi_SPropValue_wrap *r) { NDR_CHECK(ndr_push_align(ndr, 8)); return ndr_push_mapi_SPropValue(ndr, NDR_SCALARS, (const struct mapi_SPropValue *)r); } enum ndr_err_code ndr_pull_mapi_SPropValue_wrap(struct ndr_pull *ndr, int ndr_flags, struct mapi_SPropValue_wrap *r) { return ndr_pull_mapi_SPropValue(ndr, NDR_SCALARS, (struct mapi_SPropValue *)r); } void ndr_print_mapi_SPropValue_wrap(struct ndr_print *ndr, const char *name, const struct mapi_SPropValue_wrap *r) { ndr_print_mapi_SPropValue(ndr, name, (const struct mapi_SPropValue *)r); } /* * Fake wrapper over mapi_SPropValue_array. Workaround the no-pointer deep * recursion problem in pidl */ enum ndr_err_code ndr_push_mapi_SPropValue_array_wrap(struct ndr_push *ndr, int ndr_flags, const struct mapi_SPropValue_array_wrap *r) { NDR_CHECK(ndr_push_align(ndr, 8)); return ndr_push_mapi_SPropValue_array(ndr, NDR_SCALARS, (const struct mapi_SPropValue_array *)r); } enum ndr_err_code ndr_pull_mapi_SPropValue_array_wrap(struct ndr_pull *ndr, int ndr_flags, struct mapi_SPropValue_array_wrap *r) { return ndr_pull_mapi_SPropValue_array(ndr, NDR_SCALARS, (struct mapi_SPropValue_array *)r); } void ndr_print_mapi_SPropValue_array_wrap(struct ndr_print *ndr, const char *name, const struct mapi_SPropValue_array_wrap *r) { ndr_print_mapi_SPropValue_array(ndr, name, (const struct mapi_SPropValue_array *)r); } enum ndr_err_code ndr_push_RestrictionVariable(struct ndr_push *ndr, int ndr_flags, const union RestrictionVariable *r) { { uint32_t _flags_save_STRUCT = ndr->flags; ndr_set_flags(&ndr->flags, LIBNDR_FLAG_NOALIGN); if (ndr_flags & NDR_SCALARS) { int level = ndr_push_get_switch_value(ndr, r); switch (level) { case 0x0: { break; } case 0x1: { NDR_CHECK(ndr_push_mapi_SRestriction_comment(ndr, NDR_SCALARS, &r->res[0])); break; } default: return ndr_push_error(ndr, NDR_ERR_BAD_SWITCH, "Bad switch value %u", level); } } if (ndr_flags & NDR_BUFFERS) { int level = ndr_push_get_switch_value(ndr, r); switch (level) { case 0x0: break; case 0x1: if (r->res) { NDR_CHECK(ndr_push_mapi_SRestriction_comment(ndr, NDR_BUFFERS, &r->res[0])); } break; default: return ndr_push_error(ndr, NDR_ERR_BAD_SWITCH, "Bad switch value %u", level); } } ndr->flags = _flags_save_STRUCT; } return NDR_ERR_SUCCESS; } enum ndr_err_code ndr_pull_RestrictionVariable(struct ndr_pull *ndr, int ndr_flags, union RestrictionVariable *r) { int level; TALLOC_CTX *_mem_save_res_0; level = ndr_pull_get_switch_value(ndr, r); { uint32_t _flags_save_STRUCT = ndr->flags; ndr_set_flags(&ndr->flags, LIBNDR_FLAG_NOALIGN); if (ndr_flags & NDR_SCALARS) { switch (level) { case 0x0: { break; } case 0x1: { NDR_CHECK(ndr_pull_align(ndr, 4)); NDR_PULL_ALLOC_N(ndr, r->res, 1); _mem_save_res_0 = NDR_PULL_GET_MEM_CTX(ndr); NDR_PULL_SET_MEM_CTX(ndr, r->res, 0); NDR_CHECK(ndr_pull_mapi_SRestriction_comment(ndr, NDR_SCALARS, &r->res[0])); NDR_PULL_SET_MEM_CTX(ndr, _mem_save_res_0, 0); break; } default: return ndr_pull_error(ndr, NDR_ERR_BAD_SWITCH, "Bad switch value %u", level); } } if (ndr_flags & NDR_BUFFERS) { switch (level) { case 0x0: break; case 0x1: if (r->res) { _mem_save_res_0 = NDR_PULL_GET_MEM_CTX(ndr); NDR_PULL_SET_MEM_CTX(ndr, r->res, 0); NDR_CHECK(ndr_pull_mapi_SRestriction_comment(ndr, NDR_BUFFERS, &r->res[0])); NDR_PULL_SET_MEM_CTX(ndr, _mem_save_res_0, 0); break; } default: return ndr_pull_error(ndr, NDR_ERR_BAD_SWITCH, "Bad switch value %u", level); } } ndr->flags = _flags_save_STRUCT; } return NDR_ERR_SUCCESS; } _PUBLIC_ void ndr_print_RestrictionVariable(struct ndr_print *ndr, const char *name, const union RestrictionVariable *r) { int level; level = ndr_print_get_switch_value(ndr, r); ndr_print_union(ndr, name, level, "RestrictionVariable"); switch (level) { case 0x0: break; case 0x1: ndr_print_ptr(ndr, "res", r->res); ndr->depth++; if (r->res) { ndr_set_flags(&ndr->flags, LIBNDR_FLAG_NOALIGN); ndr_print_mapi_SRestriction_comment(ndr, "res", &r->res[0]); } ndr->depth--; break; } } enum ndr_err_code ndr_push_Release_req(struct ndr_push *ndr, int ndr_flags, const struct Release_req *r) { return NDR_ERR_SUCCESS; } enum ndr_err_code ndr_pull_Release_req(struct ndr_pull *ndr, int ndr_flags, struct Release_req *r) { return NDR_ERR_SUCCESS; } enum ndr_err_code ndr_push_Release_repl(struct ndr_push *ndr, int ndr_flags, const struct Release_repl *r) { return NDR_ERR_SUCCESS; } enum ndr_err_code ndr_pull_Release_repl(struct ndr_pull *ndr, int ndr_flags, struct Release_repl *r) { return NDR_ERR_SUCCESS; } enum ndr_err_code ndr_push_GetSearchCriteria_repl(struct ndr_push *ndr, int ndr_flags, const struct GetSearchCriteria_repl *r) { uint32_t cntr_FolderIds_0; { uint32_t _flags_save_STRUCT = ndr->flags; ndr_set_flags(&ndr->flags, LIBNDR_FLAG_NOALIGN); if (ndr_flags & NDR_SCALARS) { NDR_CHECK(ndr_push_align(ndr, 8)); NDR_CHECK(ndr_push_uint16(ndr, NDR_SCALARS, r->RestrictionDataSize)); if (r->RestrictionDataSize) { struct ndr_push *_ndr_RestrictionData; NDR_CHECK(ndr_push_subcontext_start(ndr, &_ndr_RestrictionData, 0, r->RestrictionDataSize)); NDR_CHECK(ndr_push_mapi_SRestriction(_ndr_RestrictionData, NDR_SCALARS|NDR_BUFFERS, &r->RestrictionData)); NDR_CHECK(ndr_push_subcontext_end(ndr, _ndr_RestrictionData, 0, r->RestrictionDataSize)); } NDR_CHECK(ndr_push_uint8(ndr, NDR_SCALARS, r->LogonId)); NDR_CHECK(ndr_push_uint16(ndr, NDR_SCALARS, r->FolderIdCount)); for (cntr_FolderIds_0 = 0; cntr_FolderIds_0 < r->FolderIdCount; cntr_FolderIds_0++) { NDR_CHECK(ndr_push_hyper(ndr, NDR_SCALARS, r->FolderIds[cntr_FolderIds_0])); } NDR_CHECK(ndr_push_SearchFlags(ndr, NDR_SCALARS, r->SearchFlags)); NDR_CHECK(ndr_push_trailer_align(ndr, 8)); } if (ndr_flags & NDR_BUFFERS) { } ndr->flags = _flags_save_STRUCT; } return NDR_ERR_SUCCESS; } enum ndr_err_code ndr_pull_GetSearchCriteria_repl(struct ndr_pull *ndr, int ndr_flags, struct GetSearchCriteria_repl *r) { uint32_t cntr_FolderIds_0; TALLOC_CTX *_mem_save_FolderIds_0; { uint32_t _flags_save_STRUCT = ndr->flags; ndr_set_flags(&ndr->flags, LIBNDR_FLAG_NOALIGN); if (ndr_flags & NDR_SCALARS) { NDR_CHECK(ndr_pull_align(ndr, 8)); NDR_CHECK(ndr_pull_uint16(ndr, NDR_SCALARS, &r->RestrictionDataSize)); if (r->RestrictionDataSize) { struct ndr_pull *_ndr_RestrictionData; NDR_CHECK(ndr_pull_subcontext_start(ndr, &_ndr_RestrictionData, 0, r->RestrictionDataSize)); NDR_CHECK(ndr_pull_mapi_SRestriction(_ndr_RestrictionData, NDR_SCALARS|NDR_BUFFERS, &r->RestrictionData)); NDR_CHECK(ndr_pull_subcontext_end(ndr, _ndr_RestrictionData, 0, r->RestrictionDataSize)); } NDR_CHECK(ndr_pull_uint8(ndr, NDR_SCALARS, &r->LogonId)); NDR_CHECK(ndr_pull_uint16(ndr, NDR_SCALARS, &r->FolderIdCount)); NDR_PULL_ALLOC_N(ndr, r->FolderIds, r->FolderIdCount); _mem_save_FolderIds_0 = NDR_PULL_GET_MEM_CTX(ndr); NDR_PULL_SET_MEM_CTX(ndr, r->FolderIds, 0); for (cntr_FolderIds_0 = 0; cntr_FolderIds_0 < r->FolderIdCount; cntr_FolderIds_0++) { NDR_CHECK(ndr_pull_hyper(ndr, NDR_SCALARS, &r->FolderIds[cntr_FolderIds_0])); } NDR_PULL_SET_MEM_CTX(ndr, _mem_save_FolderIds_0, 0); NDR_CHECK(ndr_pull_SearchFlags(ndr, NDR_SCALARS, &r->SearchFlags)); NDR_CHECK(ndr_pull_trailer_align(ndr, 8)); } if (ndr_flags & NDR_BUFFERS) { } ndr->flags = _flags_save_STRUCT; } return NDR_ERR_SUCCESS; } void ndr_print_GetSearchCriteria_repl(struct ndr_print *ndr, const char *name, const struct GetSearchCriteria_repl *r) { uint32_t cntr_FolderIds_0; ndr_print_struct(ndr, name, "GetSearchCriteria_repl"); { uint32_t _flags_save_STRUCT = ndr->flags; ndr_set_flags(&ndr->flags, LIBNDR_FLAG_NOALIGN); ndr->depth++; ndr_print_uint16(ndr, "RestrictionDataSize", r->RestrictionDataSize); if (r->RestrictionDataSize) { ndr_print_mapi_SRestriction(ndr, "RestrictionData", &r->RestrictionData); } else { ndr_print_uint8(ndr, "RestrictionData", 0); } ndr_print_uint8(ndr, "LogonId", r->LogonId); ndr_print_uint16(ndr, "FolderIdCount", r->FolderIdCount); ndr->print(ndr, "%s: ARRAY(%d)", "FolderIds", (int)r->FolderIdCount); ndr->depth++; for (cntr_FolderIds_0=0;cntr_FolderIds_0FolderIdCount;cntr_FolderIds_0++) { char *idx_0=NULL; if (asprintf(&idx_0, "[%d]", cntr_FolderIds_0) != -1) { ndr_print_hyper(ndr, "FolderIds", r->FolderIds[cntr_FolderIds_0]); free(idx_0); } } ndr->depth--; ndr_print_SearchFlags(ndr, "SearchFlags", r->SearchFlags); ndr->depth--; ndr->flags = _flags_save_STRUCT; } } enum ndr_err_code ndr_push_Backoff_req(struct ndr_push *ndr, int ndr_flags, const struct Backoff_req *r) { return NDR_ERR_SUCCESS; } enum ndr_err_code ndr_pull_Backoff_req(struct ndr_pull *ndr, int ndr_flags, struct Backoff_req *r) { return NDR_ERR_SUCCESS; } enum ndr_err_code ndr_push_Backoff_repl(struct ndr_push *ndr, int ndr_flags, const struct Backoff_repl *r) { return NDR_ERR_SUCCESS; } enum ndr_err_code ndr_pull_Backoff_repl(struct ndr_pull *ndr, int ndr_flags, struct Backoff_repl *r) { return NDR_ERR_SUCCESS; } enum ndr_err_code ndr_push_BufferTooSmall_req(struct ndr_push *ndr, int ndr_flags, const struct BufferTooSmall_req *r) { return NDR_ERR_SUCCESS; } enum ndr_err_code ndr_pull_BufferTooSmall_req(struct ndr_pull *ndr, int ndr_flags, struct BufferTooSmall_req *r) { return NDR_ERR_SUCCESS; } enum ndr_err_code ndr_push_BufferTooSmall_repl(struct ndr_push *ndr, int ndr_flags, const struct BufferTooSmall_repl *r) { return NDR_ERR_SUCCESS; } enum ndr_err_code ndr_pull_BufferTooSmall_repl(struct ndr_pull *ndr, int ndr_flags, struct BufferTooSmall_repl *r) { return NDR_ERR_SUCCESS; } /* property.idl */ _PUBLIC_ enum ndr_err_code ndr_push_ExtendedException(struct ndr_push *ndr, int ndr_flags, uint16_t WriterVersion2, const struct ExceptionInfo *ExceptionInfo, const struct ExtendedException *r) { bool subjectIsSet, locationIsSet; { uint32_t _flags_save_STRUCT = ndr->flags; subjectIsSet = (ExceptionInfo->OverrideFlags & ARO_SUBJECT) == ARO_SUBJECT; locationIsSet = (ExceptionInfo->OverrideFlags & ARO_LOCATION) == ARO_LOCATION; ndr_set_flags(&ndr->flags, LIBNDR_FLAG_NOALIGN); NDR_PUSH_CHECK_FLAGS(ndr, ndr_flags); if (ndr_flags & NDR_SCALARS) { NDR_CHECK(ndr_push_align(ndr, 4)); if (WriterVersion2 > 0x3008) { NDR_CHECK(ndr_push_ChangeHighlight(ndr, NDR_SCALARS, &r->ChangeHighlight)); } NDR_CHECK(ndr_push_uint32(ndr, NDR_SCALARS, r->ReservedBlockEE1Size)); NDR_CHECK(ndr_push_array_uint8(ndr, NDR_SCALARS, r->ReservedBlockEE1, r->ReservedBlockEE1Size)); if (subjectIsSet || locationIsSet) { NDR_CHECK(ndr_push_uint32(ndr, NDR_SCALARS, r->StartDateTime)); NDR_CHECK(ndr_push_uint32(ndr, NDR_SCALARS, r->EndDateTime)); NDR_CHECK(ndr_push_uint32(ndr, NDR_SCALARS, r->OriginalStartDate)); } if (subjectIsSet) { uint32_t _flags_save_string = ndr->flags; ndr_set_flags(&ndr->flags, LIBNDR_FLAG_STR_SIZE2|LIBNDR_FLAG_STR_NOTERM); NDR_CHECK(ndr_push_string(ndr, NDR_SCALARS, r->Subject)); ndr->flags = _flags_save_string; } if (locationIsSet) { uint32_t _flags_save_string = ndr->flags; ndr_set_flags(&ndr->flags, LIBNDR_FLAG_STR_SIZE2|LIBNDR_FLAG_STR_NOTERM); NDR_CHECK(ndr_push_string(ndr, NDR_SCALARS, r->Location)); ndr->flags = _flags_save_string; } if (subjectIsSet || locationIsSet) { NDR_CHECK(ndr_push_uint32(ndr, NDR_SCALARS, r->ReservedBlockEE2Size)); NDR_CHECK(ndr_push_array_uint8(ndr, NDR_SCALARS, r->ReservedBlockEE2, r->ReservedBlockEE2Size)); } NDR_CHECK(ndr_push_trailer_align(ndr, 4)); } if (ndr_flags & NDR_BUFFERS) { } ndr->flags = _flags_save_STRUCT; } return NDR_ERR_SUCCESS; } _PUBLIC_ enum ndr_err_code ndr_pull_ExtendedException(struct ndr_pull *ndr, int ndr_flags, uint16_t WriterVersion2, const struct ExceptionInfo *ExceptionInfo, struct ExtendedException *r) { bool subjectIsSet, locationIsSet; { uint32_t _flags_save_STRUCT = ndr->flags; subjectIsSet = (ExceptionInfo->OverrideFlags & ARO_SUBJECT) == ARO_SUBJECT; locationIsSet = (ExceptionInfo->OverrideFlags & ARO_LOCATION) == ARO_LOCATION; ndr_set_flags(&ndr->flags, LIBNDR_FLAG_NOALIGN); NDR_PULL_CHECK_FLAGS(ndr, ndr_flags); if (ndr_flags & NDR_SCALARS) { NDR_CHECK(ndr_pull_align(ndr, 4)); if (WriterVersion2 > 0x3008) { NDR_CHECK(ndr_pull_ChangeHighlight(ndr, NDR_SCALARS, &r->ChangeHighlight)); } else { memset(&r->ChangeHighlight, 0, sizeof(struct ChangeHighlight)); } NDR_CHECK(ndr_pull_uint32(ndr, NDR_SCALARS, &r->ReservedBlockEE1Size)); NDR_PULL_ALLOC_N(ndr, r->ReservedBlockEE1, r->ReservedBlockEE1Size); NDR_CHECK(ndr_pull_array_uint8(ndr, NDR_SCALARS, r->ReservedBlockEE1, r->ReservedBlockEE1Size)); if (subjectIsSet || locationIsSet) { NDR_CHECK(ndr_pull_uint32(ndr, NDR_SCALARS, &r->StartDateTime)); NDR_CHECK(ndr_pull_uint32(ndr, NDR_SCALARS, &r->EndDateTime)); NDR_CHECK(ndr_pull_uint32(ndr, NDR_SCALARS, &r->OriginalStartDate)); } if (subjectIsSet) { uint32_t _flags_save_string = ndr->flags; ndr_set_flags(&ndr->flags, LIBNDR_FLAG_STR_SIZE2|LIBNDR_FLAG_STR_NOTERM); NDR_CHECK(ndr_pull_string(ndr, NDR_SCALARS, &r->Subject)); ndr->flags = _flags_save_string; } if (locationIsSet) { uint32_t _flags_save_string = ndr->flags; ndr_set_flags(&ndr->flags, LIBNDR_FLAG_STR_SIZE2|LIBNDR_FLAG_STR_NOTERM); NDR_CHECK(ndr_pull_string(ndr, NDR_SCALARS, &r->Location)); ndr->flags = _flags_save_string; } if (subjectIsSet || locationIsSet) { NDR_CHECK(ndr_pull_uint32(ndr, NDR_SCALARS, &r->ReservedBlockEE2Size)); NDR_PULL_ALLOC_N(ndr, r->ReservedBlockEE2, r->ReservedBlockEE2Size); NDR_CHECK(ndr_pull_array_uint8(ndr, NDR_SCALARS, r->ReservedBlockEE2, r->ReservedBlockEE2Size)); } NDR_CHECK(ndr_pull_trailer_align(ndr, 4)); } if (ndr_flags & NDR_BUFFERS) { } ndr->flags = _flags_save_STRUCT; } return NDR_ERR_SUCCESS; } _PUBLIC_ enum ndr_err_code ndr_push_AppointmentRecurrencePattern(struct ndr_push *ndr, int ndr_flags, const struct AppointmentRecurrencePattern *r) { uint32_t cntr_ExceptionInfo_0; uint32_t cntr_ReservedBlock1_0; uint32_t cntr_ExtendedException_0; uint32_t cntr_ReservedBlock2_0; { uint32_t _flags_save_STRUCT = ndr->flags; ndr_set_flags(&ndr->flags, LIBNDR_FLAG_NOALIGN); NDR_PUSH_CHECK_FLAGS(ndr, ndr_flags); if (ndr_flags & NDR_SCALARS) { NDR_CHECK(ndr_push_align(ndr, 4)); NDR_CHECK(ndr_push_RecurrencePattern(ndr, NDR_SCALARS, &r->RecurrencePattern)); NDR_CHECK(ndr_push_uint32(ndr, NDR_SCALARS, r->ReaderVersion2)); NDR_CHECK(ndr_push_uint32(ndr, NDR_SCALARS, r->WriterVersion2)); NDR_CHECK(ndr_push_uint32(ndr, NDR_SCALARS, r->StartTimeOffset)); NDR_CHECK(ndr_push_uint32(ndr, NDR_SCALARS, r->EndTimeOffset)); NDR_CHECK(ndr_push_uint16(ndr, NDR_SCALARS, r->ExceptionCount)); for (cntr_ExceptionInfo_0 = 0; cntr_ExceptionInfo_0 < r->ExceptionCount; cntr_ExceptionInfo_0++) { NDR_CHECK(ndr_push_ExceptionInfo(ndr, NDR_SCALARS, &r->ExceptionInfo[cntr_ExceptionInfo_0])); } NDR_CHECK(ndr_push_uint32(ndr, NDR_SCALARS, r->ReservedBlock1Size)); for (cntr_ReservedBlock1_0 = 0; cntr_ReservedBlock1_0 < r->ReservedBlock1Size; cntr_ReservedBlock1_0++) { NDR_CHECK(ndr_push_uint32(ndr, NDR_SCALARS, r->ReservedBlock1[cntr_ReservedBlock1_0])); } for (cntr_ExtendedException_0 = 0; cntr_ExtendedException_0 < r->ExceptionCount; cntr_ExtendedException_0++) { NDR_CHECK(ndr_push_ExtendedException(ndr, NDR_SCALARS, r->WriterVersion2, r->ExceptionInfo + cntr_ExtendedException_0, &r->ExtendedException[cntr_ExtendedException_0])); } NDR_CHECK(ndr_push_uint32(ndr, NDR_SCALARS, r->ReservedBlock2Size)); for (cntr_ReservedBlock2_0 = 0; cntr_ReservedBlock2_0 < r->ReservedBlock2Size; cntr_ReservedBlock2_0++) { NDR_CHECK(ndr_push_uint32(ndr, NDR_SCALARS, r->ReservedBlock2[cntr_ReservedBlock2_0])); } NDR_CHECK(ndr_push_trailer_align(ndr, 4)); } if (ndr_flags & NDR_BUFFERS) { NDR_CHECK(ndr_push_RecurrencePattern(ndr, NDR_BUFFERS, &r->RecurrencePattern)); for (cntr_ExceptionInfo_0 = 0; cntr_ExceptionInfo_0 < r->ExceptionCount; cntr_ExceptionInfo_0++) { NDR_CHECK(ndr_push_ExceptionInfo(ndr, NDR_BUFFERS, &r->ExceptionInfo[cntr_ExceptionInfo_0])); } } ndr->flags = _flags_save_STRUCT; } return NDR_ERR_SUCCESS; } _PUBLIC_ enum ndr_err_code ndr_pull_AppointmentRecurrencePattern(struct ndr_pull *ndr, int ndr_flags, struct AppointmentRecurrencePattern *r) { uint32_t cntr_ExceptionInfo_0; TALLOC_CTX *_mem_save_ExceptionInfo_0; uint32_t cntr_ReservedBlock1_0; TALLOC_CTX *_mem_save_ReservedBlock1_0; uint32_t cntr_ExtendedException_0; TALLOC_CTX *_mem_save_ExtendedException_0; uint32_t cntr_ReservedBlock2_0; TALLOC_CTX *_mem_save_ReservedBlock2_0; { uint32_t _flags_save_STRUCT = ndr->flags; ndr_set_flags(&ndr->flags, LIBNDR_FLAG_NOALIGN); NDR_PULL_CHECK_FLAGS(ndr, ndr_flags); if (ndr_flags & NDR_SCALARS) { NDR_CHECK(ndr_pull_align(ndr, 4)); NDR_CHECK(ndr_pull_RecurrencePattern(ndr, NDR_SCALARS, &r->RecurrencePattern)); NDR_CHECK(ndr_pull_uint32(ndr, NDR_SCALARS, &r->ReaderVersion2)); NDR_CHECK(ndr_pull_uint32(ndr, NDR_SCALARS, &r->WriterVersion2)); NDR_CHECK(ndr_pull_uint32(ndr, NDR_SCALARS, &r->StartTimeOffset)); NDR_CHECK(ndr_pull_uint32(ndr, NDR_SCALARS, &r->EndTimeOffset)); NDR_CHECK(ndr_pull_uint16(ndr, NDR_SCALARS, &r->ExceptionCount)); NDR_PULL_ALLOC_N(ndr, r->ExceptionInfo, r->ExceptionCount); _mem_save_ExceptionInfo_0 = NDR_PULL_GET_MEM_CTX(ndr); NDR_PULL_SET_MEM_CTX(ndr, r->ExceptionInfo, 0); for (cntr_ExceptionInfo_0 = 0; cntr_ExceptionInfo_0 < r->ExceptionCount; cntr_ExceptionInfo_0++) { NDR_CHECK(ndr_pull_ExceptionInfo(ndr, NDR_SCALARS, &r->ExceptionInfo[cntr_ExceptionInfo_0])); } NDR_PULL_SET_MEM_CTX(ndr, _mem_save_ExceptionInfo_0, 0); NDR_CHECK(ndr_pull_uint32(ndr, NDR_SCALARS, &r->ReservedBlock1Size)); NDR_PULL_ALLOC_N(ndr, r->ReservedBlock1, r->ReservedBlock1Size); _mem_save_ReservedBlock1_0 = NDR_PULL_GET_MEM_CTX(ndr); NDR_PULL_SET_MEM_CTX(ndr, r->ReservedBlock1, 0); for (cntr_ReservedBlock1_0 = 0; cntr_ReservedBlock1_0 < r->ReservedBlock1Size; cntr_ReservedBlock1_0++) { NDR_CHECK(ndr_pull_uint32(ndr, NDR_SCALARS, &r->ReservedBlock1[cntr_ReservedBlock1_0])); } NDR_PULL_SET_MEM_CTX(ndr, _mem_save_ReservedBlock1_0, 0); NDR_PULL_ALLOC_N(ndr, r->ExtendedException, r->ExceptionCount); _mem_save_ExtendedException_0 = NDR_PULL_GET_MEM_CTX(ndr); NDR_PULL_SET_MEM_CTX(ndr, r->ExtendedException, 0); for (cntr_ExtendedException_0 = 0; cntr_ExtendedException_0 < r->ExceptionCount; cntr_ExtendedException_0++) { NDR_CHECK(ndr_pull_ExtendedException(ndr, NDR_SCALARS, r->WriterVersion2, r->ExceptionInfo + cntr_ExtendedException_0, &r->ExtendedException[cntr_ExtendedException_0])); } NDR_PULL_SET_MEM_CTX(ndr, _mem_save_ExtendedException_0, 0); NDR_CHECK(ndr_pull_uint32(ndr, NDR_SCALARS, &r->ReservedBlock2Size)); NDR_PULL_ALLOC_N(ndr, r->ReservedBlock2, r->ReservedBlock2Size); _mem_save_ReservedBlock2_0 = NDR_PULL_GET_MEM_CTX(ndr); NDR_PULL_SET_MEM_CTX(ndr, r->ReservedBlock2, 0); for (cntr_ReservedBlock2_0 = 0; cntr_ReservedBlock2_0 < r->ReservedBlock2Size; cntr_ReservedBlock2_0++) { NDR_CHECK(ndr_pull_uint32(ndr, NDR_SCALARS, &r->ReservedBlock2[cntr_ReservedBlock2_0])); } NDR_PULL_SET_MEM_CTX(ndr, _mem_save_ReservedBlock2_0, 0); NDR_CHECK(ndr_pull_trailer_align(ndr, 4)); } if (ndr_flags & NDR_BUFFERS) { NDR_CHECK(ndr_pull_RecurrencePattern(ndr, NDR_BUFFERS, &r->RecurrencePattern)); _mem_save_ExceptionInfo_0 = NDR_PULL_GET_MEM_CTX(ndr); NDR_PULL_SET_MEM_CTX(ndr, r->ExceptionInfo, 0); for (cntr_ExceptionInfo_0 = 0; cntr_ExceptionInfo_0 < r->ExceptionCount; cntr_ExceptionInfo_0++) { NDR_CHECK(ndr_pull_ExceptionInfo(ndr, NDR_BUFFERS, &r->ExceptionInfo[cntr_ExceptionInfo_0])); } NDR_PULL_SET_MEM_CTX(ndr, _mem_save_ExceptionInfo_0, 0); } ndr->flags = _flags_save_STRUCT; } return NDR_ERR_SUCCESS; } openchange-2.0/packaging/000077500000000000000000000000001223057412600154105ustar00rootroot00000000000000openchange-2.0/packaging/rhel/000077500000000000000000000000001223057412600163425ustar00rootroot00000000000000openchange-2.0/packaging/rhel/doxygen_to_devhelp.xsl000066400000000000000000000024151223057412600227620ustar00rootroot00000000000000 .html# openchange-2.0/packaging/rhel/ocsmanager-ini-path-fix.diff000066400000000000000000000010141223057412600236020ustar00rootroot00000000000000Index: mapiproxy/services/ocsmanager/ocsmanager.ini =================================================================== --- mapiproxy/services/ocsmanager/ocsmanager.ini (revision 4075) +++ mapiproxy/services/ocsmanager/ocsmanager.ini (working copy) @@ -14,8 +14,8 @@ # auth = file #auth = ldap auth = single -mapistore_root = /var/lib/samba/private -mapistore_data = /var/lib/samba/private/mapistore +mapistore_root = /var/lib/samba4/private +mapistore_data = /var/lib/samba4/private/mapistore debug = no [auth:file] openchange-2.0/packaging/rhel/openchange-1.0-no_ocpf.diff000066400000000000000000000571731223057412600232350ustar00rootroot00000000000000diff -durpN openchange-1.0.0.20120405.sogo.old/Makefile openchange-1.0.0.20120405.sogo/Makefile --- openchange-1.0.0.20120405.sogo.old/Makefile 2012-04-03 14:42:40.000000000 -0400 +++ openchange-1.0.0.20120405.sogo/Makefile 2012-04-05 11:49:50.000000000 -0400 @@ -76,7 +76,7 @@ distclean:: clean rm -f Doxyfile rm -f libmapi/Doxyfile rm -f libmapiadmin/Doxyfile - rm -f libocpf/Doxyfile + # rm -f libocpf/Doxyfile rm -f libmapi++/Doxyfile rm -f mapiproxy/Doxyfile rm -f mapiproxy/libmapistore/Doxyfile @@ -603,7 +603,7 @@ endif rm -f libocpf.$(SHLIBEXT).$(PACKAGE_VERSION) libocpf.$(SHLIBEXT).* \ libocpf.$(SHLIBEXT) -clean:: libocpf-clean +# clean:: libocpf-clean libocpf-distclean:: rm -f libocpf.pc @@ -1095,8 +1095,8 @@ clean:: openchangeclient-clean bin/openchangeclient: utils/openchangeclient.o \ utils/openchange-tools.o \ - libmapi.$(SHLIBEXT).$(PACKAGE_VERSION) \ - libocpf.$(SHLIBEXT).$(PACKAGE_VERSION) + libmapi.$(SHLIBEXT).$(PACKAGE_VERSION) + # libocpf.$(SHLIBEXT).$(PACKAGE_VERSION) @echo "Linking $@" @$(CC) $(CFLAGS) -o $@ $^ $(LDFLAGS) $(LIBS) -lpopt @@ -1601,7 +1601,6 @@ doxygen: $(DOXYGEN) Doxyfile; \ $(DOXYGEN) libmapi/Doxyfile; \ $(DOXYGEN) libmapiadmin/Doxyfile; \ - $(DOXYGEN) libocpf/Doxyfile; \ $(DOXYGEN) libmapi++/Doxyfile; \ $(DOXYGEN) mapiproxy/Doxyfile; \ $(DOXYGEN) utils/mapitest/Doxyfile; \ @@ -1611,7 +1610,7 @@ doxygen: cp -f doc/doxygen/pictures/* apidocs/html/libmapi; \ cp -f doc/doxygen/pictures/* apidocs/html/libmapiadmin; \ cp -f doc/doxygen/pictures/* apidocs/html/libmapi++; \ - cp -f doc/doxygen/pictures/* apidocs/html/libocpf; \ + $(DOXYGEN) libocpf/Doxyfile; \ cp -f doc/doxygen/pictures/* apidocs/html/mapitest; \ cp -f doc/doxygen/pictures/* apidocs/html/mapiproxy; \ cp -f doc/doxygen/pictures/* apidocs/html/libmapistore; \ @@ -1620,6 +1619,9 @@ doxygen: rm -f apidocs/man/man3/bug.3; \ rm -f apidocs/man/man3/*.c.3; \ fi + # $(DOXYGEN) libocpf/Doxyfile; \ + # cp -f doc/doxygen/pictures/* apidocs/html/libocpf; \ + etags: etags `find $(srcdir) -name "*.[ch]"` @@ -1645,8 +1647,8 @@ coverage-init: coverage:: rm -f libmapi/\.gcov - rm -f ./libocpf/lex.yy.gcda - rm -f libocpf/\.gcov + # rm -f ./libocpf/lex.yy.gcda + # rm -f libocpf/\.gcov rm -f ./\.gcov lcov --base-directory . --directory . --output-file oc_cov.info --capture genhtml -o covresults oc_cov.info diff -durpN openchange-1.0.0.20120405.sogo.old/configure.ac openchange-1.0.0.20120405.sogo/configure.ac --- openchange-1.0.0.20120405.sogo.old/configure.ac 2012-04-03 14:42:40.000000000 -0400 +++ openchange-1.0.0.20120405.sogo/configure.ac 2012-04-05 11:49:50.000000000 -0400 @@ -337,24 +337,26 @@ dnl Check for Flex dnl Flex version < 2.5.35 is fine but 2.5.4 beta is not. This is the dnl default version provided under FreeBSD or RHL5 dnl ---------------------------------------------------------------------------- -if test x"$OPENCHANGE_VERSION_IS_SVN_SNAPSHOT" = x"yes"; then - AC_ARG_VAR([FLEX], [Location of the flex program.]) - AC_CHECK_PROG([FLEX], [flex], [flex]) +dnl if test x"$OPENCHANGE_VERSION_IS_SVN_SNAPSHOT" = x"yes"; then +dnl AC_ARG_VAR([FLEX], [Location of the flex program.]) +dnl AC_CHECK_PROG([FLEX], [flex], [flex]) - if test x"$FLEX" = x""; then - AC_MSG_WARN([No version of flex was found!]) - AC_MSG_ERROR([Please install flex]) - else - V=`$FLEX --version | awk '{print $NF}'` - W=`echo $V | awk -F. '{if (((($1*100 + $2)*100 + $3) > 20535) || $3 == 4) print "no"}'` - if test "x$W" != x ; then - AC_MSG_WARN([Adjust your FLEX environment variable]) - AC_MSG_ERROR([Flex version 2.5.35 or below is needed. You have $V]) - fi - fi +dnl if test x"$FLEX" = x""; then +dnl AC_MSG_WARN([No version of flex was found!]) +dnl AC_MSG_ERROR([Please install flex]) +dnl else +dnl V=`$FLEX --version | awk '{print $NF}'` +dnl W=`echo $V | awk -F. '{if (((($1*100 + $2)*100 + $3) > 20535) || $3 == 4) print "no"}'` +dnl if test "x$W" != x ; then +dnl AC_MSG_WARN([Adjust your FLEX environment variable]) +dnl AC_MSG_ERROR([Flex version 2.5.35 or below is needed. You have $V]) +dnl fi +dnl fi - AC_SUBST(FLEX) -fi +dnl AC_SUBST(FLEX) +dnl fi +FLEX=/bin/false +AC_SUBST(FLEX) dnl --------------------------------------------------------------------------- dnl Samba4 modules @@ -501,17 +503,17 @@ dnl #################################### dnl --------------------------------------------------------------------------- dnl Check for Bison dnl --------------------------------------------------------------------------- -if test x"$OPENCHANGE_VERSION_IS_SVN_SNAPSHOT" = x"yes"; then - AC_ARG_VAR([BISON], [Location of the bison program.]) - AC_PATH_PROG([BISON], [bison], [bison]) +dnl if test x"$OPENCHANGE_VERSION_IS_SVN_SNAPSHOT" = x"yes"; then +dnl AC_ARG_VAR([BISON], [Location of the bison program.]) +dnl AC_PATH_PROG([BISON], [bison], [bison]) - if test x"$BISON" != x""; then - OC_RULE_ADD(libocpf, LIBS) - AC_SUBST(BISON) - fi -else - OC_RULE_ADD(libocpf, LIBS) -fi +dnl if test x"$BISON" != x""; then +dnl OC_RULE_ADD(libocpf, LIBS) +dnl AC_SUBST(BISON) +dnl fi +dnl else +dnl OC_RULE_ADD(libocpf, LIBS) +dnl fi @@ -565,11 +567,6 @@ if test x"$enable_libpopt" = x"yes"; the OC_RULE_ADD(mapitest, TOOLS) fi - if test x"$enable_libocpf" = x"yes"; then - OC_RULE_ADD(openchangeclient, TOOLS) - # OC_RULE_ADD(mapistore_fsocpf, MAPISTORE) - fi - if test x"$have_libical" = x"yes"; then OC_RULE_ADD(exchange2ical, TOOLS) fi @@ -738,9 +735,9 @@ AC_SUBST(OPENCHANGE_QT4) dnl *********************** dnl Makefiles dnl *********************** -AC_CONFIG_FILES([config.mk libmapi.pc libmapiadmin.pc libocpf.pc mapiproxy/libmapiproxy.pc +AC_CONFIG_FILES([config.mk libmapi.pc libmapiadmin.pc mapiproxy/libmapiproxy.pc mapiproxy/libmapiserver.pc mapiproxy/libmapistore.pc libmapi++.pc - Doxyfile libmapi++/Doxyfile libocpf/Doxyfile libmapiadmin/Doxyfile + Doxyfile libmapi++/Doxyfile libmapiadmin/Doxyfile libmapi/Doxyfile mapiproxy/Doxyfile utils/mapitest/Doxyfile mapiproxy/libmapistore/Doxyfile]) AC_OUTPUT @@ -752,7 +749,7 @@ dnl #################################### OC_SETVAL(libmapi) OC_SETVAL(libmapiadmin) -OC_SETVAL(libocpf) +dnl OC_SETVAL(libocpf) OC_SETVAL(libmapixx) OC_SETVAL(openchangeclient) @@ -777,7 +774,6 @@ OpenChange Configuration (Please review) Thread support: $enable_pthread $enable_thread_lib - libmapi++ (C++ library): $enable_libmapixx - libmapiadmin: $enable_libmapiadmin - - libocpf: $enable_libocpf * OpenChange Server: - mapiproxy: $enable_mapiproxy diff -durpN openchange-1.0.0.20120405.sogo.old/utils/openchangeclient.c openchange-1.0.0.20120405.sogo/utils/openchangeclient.c --- openchange-1.0.0.20120405.sogo.old/utils/openchangeclient.c 2012-04-03 14:11:37.000000000 -0400 +++ openchange-1.0.0.20120405.sogo/utils/openchangeclient.c 2012-04-05 11:49:50.000000000 -0400 @@ -2511,199 +2511,199 @@ static bool openchangeclient_userlist(TA } -static bool openchangeclient_ocpf_syntax(struct oclient *oclient) -{ - int ret; - struct ocpf_file *element; - uint32_t context_id; +/* static bool openchangeclient_ocpf_syntax(struct oclient *oclient) */ +/* { */ +/* int ret; */ +/* struct ocpf_file *element; */ +/* uint32_t context_id; */ - /* Sanity checks */ - if (!oclient->ocpf_files || !oclient->ocpf_files->next) { - errno = MAPI_E_INVALID_PARAMETER; - return false; - } +/* /\* Sanity checks *\/ */ +/* if (!oclient->ocpf_files || !oclient->ocpf_files->next) { */ +/* errno = MAPI_E_INVALID_PARAMETER; */ +/* return false; */ +/* } */ - /* Step 1. Initialize OCPF context */ - ret = ocpf_init(); - if (ret == -1) { - errno = MAPI_E_CALL_FAILED; - return false; - } +/* /\* Step 1. Initialize OCPF context *\/ */ +/* ret = ocpf_init(); */ +/* if (ret == -1) { */ +/* errno = MAPI_E_CALL_FAILED; */ +/* return false; */ +/* } */ - /* Step2. Parse OCPF files */ - for (element = oclient->ocpf_files; element->next; element = element->next) { - ret = ocpf_new_context(element->filename, &context_id, OCPF_FLAGS_READ); - if (ret == -1) { - errno = MAPI_E_INVALID_PARAMETER; - return false; - } - ret = ocpf_parse(context_id); - if (ret == -1) { - DEBUG(0, ("ocpf_parse failed ...\n")); - errno = MAPI_E_INVALID_PARAMETER; - return false; - } +/* /\* Step2. Parse OCPF files *\/ */ +/* for (element = oclient->ocpf_files; element->next; element = element->next) { */ +/* ret = ocpf_new_context(element->filename, &context_id, OCPF_FLAGS_READ); */ +/* if (ret == -1) { */ +/* errno = MAPI_E_INVALID_PARAMETER; */ +/* return false; */ +/* } */ +/* ret = ocpf_parse(context_id); */ +/* if (ret == -1) { */ +/* DEBUG(0, ("ocpf_parse failed ...\n")); */ +/* errno = MAPI_E_INVALID_PARAMETER; */ +/* return false; */ +/* } */ - /* Dump OCPF contents */ - ocpf_dump(context_id); +/* /\* Dump OCPF contents *\/ */ +/* ocpf_dump(context_id); */ - ret = ocpf_del_context(context_id); - } +/* ret = ocpf_del_context(context_id); */ +/* } */ - /* Step4. Release OCPF context */ - ret = ocpf_release(); - if (ret == -1) { - errno = MAPI_E_CALL_FAILED; - return false; - } +/* /\* Step4. Release OCPF context *\/ */ +/* ret = ocpf_release(); */ +/* if (ret == -1) { */ +/* errno = MAPI_E_CALL_FAILED; */ +/* return false; */ +/* } */ - return true; -} +/* return true; */ +/* } */ -static bool openchangeclient_ocpf_sender(TALLOC_CTX *mem_ctx, mapi_object_t *obj_store, struct oclient *oclient) -{ - enum MAPISTATUS retval; - int ret; - struct ocpf_file *element; - mapi_object_t obj_folder; - mapi_object_t obj_message; - uint32_t cValues = 0; - struct SPropValue *lpProps; - uint32_t context_id; +/* static bool openchangeclient_ocpf_sender(TALLOC_CTX *mem_ctx, mapi_object_t *obj_store, struct oclient *oclient) */ +/* { */ +/* enum MAPISTATUS retval; */ +/* int ret; */ +/* struct ocpf_file *element; */ +/* mapi_object_t obj_folder; */ +/* mapi_object_t obj_message; */ +/* uint32_t cValues = 0; */ +/* struct SPropValue *lpProps; */ +/* uint32_t context_id; */ - /* Sanity Check */ - if (!oclient->ocpf_files || !oclient->ocpf_files->next) { - errno = MAPI_E_INVALID_PARAMETER; - return false; - } +/* /\* Sanity Check *\/ */ +/* if (!oclient->ocpf_files || !oclient->ocpf_files->next) { */ +/* errno = MAPI_E_INVALID_PARAMETER; */ +/* return false; */ +/* } */ - /* Step1. Initialize OCPF context */ - ret = ocpf_init(); - if (ret == -1) { - errno = MAPI_E_CALL_FAILED; - return false; - } +/* /\* Step1. Initialize OCPF context *\/ */ +/* ret = ocpf_init(); */ +/* if (ret == -1) { */ +/* errno = MAPI_E_CALL_FAILED; */ +/* return false; */ +/* } */ - /* Step2. Parse OCPF files */ - for (element = oclient->ocpf_files; element->next; element = element->next) { - ret = ocpf_new_context(element->filename, &context_id, OCPF_FLAGS_READ); - ret = ocpf_parse(context_id); - if (ret == -1) { - errno = MAPI_E_INVALID_PARAMETER; - return false; - } - } +/* /\* Step2. Parse OCPF files *\/ */ +/* for (element = oclient->ocpf_files; element->next; element = element->next) { */ +/* ret = ocpf_new_context(element->filename, &context_id, OCPF_FLAGS_READ); */ +/* ret = ocpf_parse(context_id); */ +/* if (ret == -1) { */ +/* errno = MAPI_E_INVALID_PARAMETER; */ +/* return false; */ +/* } */ +/* } */ - /* Step3. Open destination folder using ocpf API */ - mapi_object_init(&obj_folder); - retval = ocpf_OpenFolder(context_id, obj_store, &obj_folder); - if (retval != MAPI_E_SUCCESS) return false; +/* /\* Step3. Open destination folder using ocpf API *\/ */ +/* mapi_object_init(&obj_folder); */ +/* retval = ocpf_OpenFolder(context_id, obj_store, &obj_folder); */ +/* if (retval != MAPI_E_SUCCESS) return false; */ - /* Step4. Create the message */ - mapi_object_init(&obj_message); - retval = CreateMessage(&obj_folder, &obj_message); - if (retval != MAPI_E_SUCCESS) return false; +/* /\* Step4. Create the message *\/ */ +/* mapi_object_init(&obj_message); */ +/* retval = CreateMessage(&obj_folder, &obj_message); */ +/* if (retval != MAPI_E_SUCCESS) return false; */ - /* Step5, Set message recipients */ - retval = ocpf_set_Recipients(mem_ctx, context_id, &obj_message); - if (retval != MAPI_E_SUCCESS && GetLastError() != MAPI_E_NOT_FOUND) return false; - errno = MAPI_E_SUCCESS; +/* /\* Step5, Set message recipients *\/ */ +/* retval = ocpf_set_Recipients(mem_ctx, context_id, &obj_message); */ +/* if (retval != MAPI_E_SUCCESS && GetLastError() != MAPI_E_NOT_FOUND) return false; */ +/* errno = MAPI_E_SUCCESS; */ - /* Step6. Set message properties */ - retval = ocpf_set_SPropValue(mem_ctx, context_id, &obj_folder, &obj_message); - if (retval != MAPI_E_SUCCESS) return false; +/* /\* Step6. Set message properties *\/ */ +/* retval = ocpf_set_SPropValue(mem_ctx, context_id, &obj_folder, &obj_message); */ +/* if (retval != MAPI_E_SUCCESS) return false; */ - /* Step7. Set message properties */ - lpProps = ocpf_get_SPropValue(context_id, &cValues); +/* /\* Step7. Set message properties *\/ */ +/* lpProps = ocpf_get_SPropValue(context_id, &cValues); */ - retval = SetProps(&obj_message, 0, lpProps, cValues); - MAPIFreeBuffer(lpProps); - if (retval != MAPI_E_SUCCESS) return false; +/* retval = SetProps(&obj_message, 0, lpProps, cValues); */ +/* MAPIFreeBuffer(lpProps); */ +/* if (retval != MAPI_E_SUCCESS) return false; */ - /* Step8. Save message */ - retval = SaveChangesMessage(&obj_folder, &obj_message, KeepOpenReadOnly); - if (retval != MAPI_E_SUCCESS) return false; +/* /\* Step8. Save message *\/ */ +/* retval = SaveChangesMessage(&obj_folder, &obj_message, KeepOpenReadOnly); */ +/* if (retval != MAPI_E_SUCCESS) return false; */ - mapi_object_release(&obj_message); - mapi_object_release(&obj_folder); +/* mapi_object_release(&obj_message); */ +/* mapi_object_release(&obj_folder); */ - ocpf_del_context(context_id); +/* ocpf_del_context(context_id); */ - return true; -} +/* return true; */ +/* } */ -static bool openchangeclient_ocpf_dump(TALLOC_CTX *mem_ctx, mapi_object_t *obj_store, struct oclient *oclient) -{ - enum MAPISTATUS retval; - int ret; - mapi_object_t obj_folder; - mapi_object_t obj_message; - mapi_id_t id_tis; - const char *fid_str; - uint64_t fid; - uint64_t mid; - const char *item = NULL; - char *filename = NULL; - struct mapi_SPropValue_array lpProps; - uint32_t context_id; +/* static bool openchangeclient_ocpf_dump(TALLOC_CTX *mem_ctx, mapi_object_t *obj_store, struct oclient *oclient) */ +/* { */ +/* enum MAPISTATUS retval; */ +/* int ret; */ +/* mapi_object_t obj_folder; */ +/* mapi_object_t obj_message; */ +/* mapi_id_t id_tis; */ +/* const char *fid_str; */ +/* uint64_t fid; */ +/* uint64_t mid; */ +/* const char *item = NULL; */ +/* char *filename = NULL; */ +/* struct mapi_SPropValue_array lpProps; */ +/* uint32_t context_id; */ - /* retrieve the FID/MID for ocpf_dump parameter */ - item = oclient->ocpf_dump; +/* /\* retrieve the FID/MID for ocpf_dump parameter *\/ */ +/* item = oclient->ocpf_dump; */ - fid_str = strsep((char **)&item, "/"); - if (!fid_str || !item) { - DEBUG(0, (" Invalid ID: %s\n", fid_str ? fid_str : "null")); - errno = MAPI_E_INVALID_PARAMETER; - return false; - } +/* fid_str = strsep((char **)&item, "/"); */ +/* if (!fid_str || !item) { */ +/* DEBUG(0, (" Invalid ID: %s\n", fid_str ? fid_str : "null")); */ +/* errno = MAPI_E_INVALID_PARAMETER; */ +/* return false; */ +/* } */ - fid = strtoull(fid_str, NULL, 16); - mid = strtoull(item, NULL, 16); +/* fid = strtoull(fid_str, NULL, 16); */ +/* mid = strtoull(item, NULL, 16); */ - /* Step 1. search the folder from Top Information Store */ - mapi_object_init(&obj_folder); - retval = GetDefaultFolder(obj_store, &id_tis, olFolderTopInformationStore); - if (retval != MAPI_E_SUCCESS) return false; +/* /\* Step 1. search the folder from Top Information Store *\/ */ +/* mapi_object_init(&obj_folder); */ +/* retval = GetDefaultFolder(obj_store, &id_tis, olFolderTopInformationStore); */ +/* if (retval != MAPI_E_SUCCESS) return false; */ - retval = folder_lookup(mem_ctx, fid, obj_store, id_tis, &obj_folder); - if (retval != MAPI_E_SUCCESS) return false; +/* retval = folder_lookup(mem_ctx, fid, obj_store, id_tis, &obj_folder); */ +/* if (retval != MAPI_E_SUCCESS) return false; */ - /* Step 2. search the message */ - mapi_object_init(&obj_message); - retval = message_lookup(mem_ctx, mid, &obj_folder, &obj_message); - if (retval != MAPI_E_SUCCESS) return false; +/* /\* Step 2. search the message *\/ */ +/* mapi_object_init(&obj_message); */ +/* retval = message_lookup(mem_ctx, mid, &obj_folder, &obj_message); */ +/* if (retval != MAPI_E_SUCCESS) return false; */ - /* Step 3. retrieve all message properties */ - retval = GetPropsAll(&obj_message, MAPI_UNICODE, &lpProps); +/* /\* Step 3. retrieve all message properties *\/ */ +/* retval = GetPropsAll(&obj_message, MAPI_UNICODE, &lpProps); */ - /* Step 4. save the message */ - ret = ocpf_init(); +/* /\* Step 4. save the message *\/ */ +/* ret = ocpf_init(); */ - filename = talloc_asprintf(mem_ctx, "%"PRIx64".ocpf", mid); - DEBUG(0, ("OCPF output file: %s\n", filename)); +/* filename = talloc_asprintf(mem_ctx, "%"PRIx64".ocpf", mid); */ +/* DEBUG(0, ("OCPF output file: %s\n", filename)); */ - ret = ocpf_new_context(filename, &context_id, OCPF_FLAGS_CREATE); - talloc_free(filename); - ret = ocpf_write_init(context_id, fid); +/* ret = ocpf_new_context(filename, &context_id, OCPF_FLAGS_CREATE); */ +/* talloc_free(filename); */ +/* ret = ocpf_write_init(context_id, fid); */ - ret = ocpf_write_auto(context_id, &obj_message, &lpProps); - if (ret == OCPF_SUCCESS) { - ret = ocpf_write_commit(context_id); - } +/* ret = ocpf_write_auto(context_id, &obj_message, &lpProps); */ +/* if (ret == OCPF_SUCCESS) { */ +/* ret = ocpf_write_commit(context_id); */ +/* } */ - ret = ocpf_del_context(context_id); +/* ret = ocpf_del_context(context_id); */ - ret = ocpf_release(); +/* ret = ocpf_release(); */ - mapi_object_release(&obj_message); - mapi_object_release(&obj_folder); +/* mapi_object_release(&obj_message); */ +/* mapi_object_release(&obj_folder); */ - return true; -} +/* return true; */ +/* } */ static bool openchangeclient_freebusy(mapi_object_t *obj_store, struct oclient *oclient) @@ -2828,8 +2828,8 @@ int main(int argc, const char *argv[]) bool opt_mkdir = false; bool opt_rmdir = false; bool opt_userlist = false; - bool opt_ocpf_syntax = false; - bool opt_ocpf_sender = false; + /* bool opt_ocpf_syntax = false; */ + /* bool opt_ocpf_sender = false; */ const char *opt_profdb = NULL; char *opt_profname = NULL; const char *opt_username = NULL; @@ -2852,8 +2852,9 @@ int main(int argc, const char *argv[]) OPT_MAPI_TASKSTATUS, OPT_MAPI_IMPORTANCE, OPT_MAPI_LABEL, OPT_PF, OPT_FOLDER, OPT_MAPI_COLOR, OPT_SENDNOTE, OPT_MKDIR, OPT_RMDIR, OPT_FOLDER_NAME, OPT_FOLDER_COMMENT, OPT_USERLIST, OPT_MAPI_PRIVATE, - OPT_UPDATE, OPT_DELETEITEMS, OPT_OCPF_FILE, OPT_OCPF_SYNTAX, - OPT_OCPF_SENDER, OPT_OCPF_DUMP, OPT_FREEBUSY, OPT_FORCE, OPT_FETCHSUMMARY, + OPT_UPDATE, OPT_DELETEITEMS, + /* OPT_OCPF_FILE, OPT_OCPF_SYNTAX, OPT_OCPF_SENDER, OPT_OCPF_DUMP, */ + OPT_FREEBUSY, OPT_FORCE, OPT_FETCHSUMMARY, OPT_USERNAME }; struct poptOption long_options[] = { @@ -2907,10 +2908,10 @@ int main(int argc, const char *argv[]) {"debuglevel", 'd', POPT_ARG_STRING, NULL, OPT_DEBUG, "set Debug Level", NULL }, {"dump-data", 0, POPT_ARG_NONE, NULL, OPT_DUMPDATA, "dump the hex data", NULL }, {"private", 0, POPT_ARG_NONE, NULL, OPT_MAPI_PRIVATE, "set the private flag on messages", NULL }, - {"ocpf-file", 0, POPT_ARG_STRING, NULL, OPT_OCPF_FILE, "set OCPF file", NULL }, - {"ocpf-dump", 0, POPT_ARG_STRING, NULL, OPT_OCPF_DUMP, "dump message into OCPF file", NULL }, - {"ocpf-syntax", 0, POPT_ARG_NONE, NULL, OPT_OCPF_SYNTAX, "check OCPF files syntax", NULL }, - {"ocpf-sender", 0, POPT_ARG_NONE, NULL, OPT_OCPF_SENDER, "send message using OCPF files contents", NULL }, + /* {"ocpf-file", 0, POPT_ARG_STRING, NULL, OPT_OCPF_FILE, "set OCPF file", NULL }, */ + /* {"ocpf-dump", 0, POPT_ARG_STRING, NULL, OPT_OCPF_DUMP, "dump message into OCPF file", NULL }, */ + /* {"ocpf-syntax", 0, POPT_ARG_NONE, NULL, OPT_OCPF_SYNTAX, "check OCPF files syntax", NULL }, */ + /* {"ocpf-sender", 0, POPT_ARG_NONE, NULL, OPT_OCPF_SENDER, "send message using OCPF files contents", NULL }, */ POPT_OPENCHANGE_VERSION {NULL, 0, 0, NULL, 0, NULL, NULL} }; @@ -3077,28 +3078,28 @@ int main(int argc, const char *argv[]) case OPT_MAPI_PRIVATE: oclient.private = true; break; - case OPT_OCPF_FILE: - { - struct ocpf_file *element; + /* case OPT_OCPF_FILE: */ + /* { */ + /* struct ocpf_file *element; */ - if (!oclient.ocpf_files) { - oclient.ocpf_files = talloc_zero(mem_ctx, struct ocpf_file); - } + /* if (!oclient.ocpf_files) { */ + /* oclient.ocpf_files = talloc_zero(mem_ctx, struct ocpf_file); */ + /* } */ - element = talloc_zero(mem_ctx, struct ocpf_file); - element->filename = talloc_strdup(mem_ctx, poptGetOptArg(pc)); - DLIST_ADD(oclient.ocpf_files, element); - break; - } - case OPT_OCPF_SYNTAX: - opt_ocpf_syntax = true; - break; - case OPT_OCPF_SENDER: - opt_ocpf_sender = true; - break; - case OPT_OCPF_DUMP: - oclient.ocpf_dump = poptGetOptArg(pc); - break; + /* element = talloc_zero(mem_ctx, struct ocpf_file); */ + /* element->filename = talloc_strdup(mem_ctx, poptGetOptArg(pc)); */ + /* DLIST_ADD(oclient.ocpf_files, element); */ + /* break; */ + /* } */ + /* case OPT_OCPF_SYNTAX: */ + /* opt_ocpf_syntax = true; */ + /* break; */ + /* case OPT_OCPF_SENDER: */ + /* opt_ocpf_sender = true; */ + /* break; */ + /* case OPT_OCPF_DUMP: */ + /* oclient.ocpf_dump = poptGetOptArg(pc); */ + /* break; */ case OPT_FORCE: oclient.force = true; break; @@ -3161,14 +3162,14 @@ int main(int argc, const char *argv[]) /* One of the rare options which doesn't require MAPI to get * initialized */ - if (opt_ocpf_syntax) { - bool ret = openchangeclient_ocpf_syntax(&oclient); - mapi_errstr("OCPF Syntax", GetLastError()); - if (ret != true) { - exit(1); - } - exit (0); - } + /* if (opt_ocpf_syntax) { */ + /* bool ret = openchangeclient_ocpf_syntax(&oclient); */ + /* mapi_errstr("OCPF Syntax", GetLastError()); */ + /* if (ret != true) { */ + /* exit(1); */ + /* } */ + /* exit (0); */ + /* } */ /** * Initialize MAPI subsystem @@ -3242,21 +3243,21 @@ int main(int argc, const char *argv[]) /** * OCPF sending command */ - if (opt_ocpf_sender) { - bool ret = openchangeclient_ocpf_sender(mem_ctx, &obj_store, &oclient); - mapi_errstr("OCPF Sender", GetLastError()); - if (ret != true) { - goto end; - } - } + /* if (opt_ocpf_sender) { */ + /* bool ret = openchangeclient_ocpf_sender(mem_ctx, &obj_store, &oclient); */ + /* mapi_errstr("OCPF Sender", GetLastError()); */ + /* if (ret != true) { */ + /* goto end; */ + /* } */ + /* } */ - if (oclient.ocpf_dump) { - bool ret = openchangeclient_ocpf_dump(mem_ctx, &obj_store, &oclient); - mapi_errstr("OCPF Dump", GetLastError()); - if (ret != true) { - goto end; - } - } + /* if (oclient.ocpf_dump) { */ + /* bool ret = openchangeclient_ocpf_dump(mem_ctx, &obj_store, &oclient); */ + /* mapi_errstr("OCPF Dump", GetLastError()); */ + /* if (ret != true) { */ + /* goto end; */ + /* } */ + /* } */ if (opt_fetchitems) { bool ret = openchangeclient_fetchitems(mem_ctx, &obj_store, opt_fetchitems, &oclient); openchange-2.0/packaging/rhel/openchange-ocsmanager.init000066400000000000000000000042751223057412600234630ustar00rootroot00000000000000#!/bin/bash ### BEGIN INIT INFO # Provides: ocsmanager # Required-Start: $remote_fs $network # Required-Stop: $remote_fs $network # Default-Start: 2 3 4 5 # Default-Stop: 0 1 6 # Short-Description: OCSManager server ### END INIT INFO # OCSManager init script for Debian GNU/Linux # # Copyright (C) 2012 Inverse inc. # # Author: Wolfgang Sourdeau # # This file is free software; you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by # the Free Software Foundation; either version 2, or (at your option) # any later version. # # This file is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program; see the file COPYING. If not, write to # the Free Software Foundation, Inc., 59 Temple Place - Suite 330, # Boston, MA 02111-1307, USA. PATH=/sbin:/bin:/usr/sbin:/usr/bin NAME=ocsmanager DAEMON=/usr/bin/paster DESC="OCSManager application" # OCSManager must be run as root, for now USER=root CONFFILE=/etc/ocsmanager/$NAME.ini PIDFILE=/var/run/ocsmanager/$NAME.pid LOGFILE=/var/log/ocsmanager/$NAME.log if [ ! -x $DAEMON ]; then echo "$DAEMON is not executable." exit 1 fi set -e case "$1" in start) echo "Starting $DESC" # Ensure directory's existence and permissions install -o $USER -g adm -m 755 -d /var/run/$NAME install -o $USER -g adm -m 750 -d /var/log/$NAME $DAEMON serve $CONFFILE --daemon --pid-file $PIDFILE --log-file $LOGFILE || /bin/true ;; stop) echo "Stopping $DESC" $DAEMON serve $CONFFILE --stop-daemon --pid-file $PIDFILE || /bin/true ;; restart|force-reload) echo "Restarting $DESC" $DAEMON serve $CONFFILE --stop-daemon --pid-file $PIDFILE || /bin/true $DAEMON serve $CONFFILE --daemon --pid-file $PIDFILE --log-file $LOGFILE || /bin/true ;; status) $DAEMON serve $CONFFILE --status --pid-file $PIDFILE ;; *) echo "Usage: $NAME {start|stop|restart|status}" >&2 exit 1 ;; esac exit 0 openchange-2.0/packaging/rhel/openchange.spec000066400000000000000000000343571223057412600213410ustar00rootroot00000000000000%{!?python_sys_pyver: %global python_sys_pyver %(/usr/bin/python -c "import sys; print sys.hexversion")} # if hex(sys.hexversion) < 0x02060000 %if %{python_sys_pyver} < 33947648 %global __python /usr/bin/python2.6 %endif %{!?python_noarch_sitearch: %global python_noarch_sitearch %(%{__python} -c "from distutils.sysconfig import get_python_lib; print get_python_lib(0)")} %{!?python_sitearch: %global python_sitearch %(%{__python} -c "from distutils.sysconfig import get_python_lib; print get_python_lib(1)")} %global samba4_version 4.0.0alpha18-2 %global talloc_version 1.2.0 %global python_config python2.6-config ### Abstract ### # Licensing Note: The code is GPLv3+ and the IDL files are public domain. Name: openchange Version: 1.0.0%{?build_suffix}.sogo Release: 1%{?dist} Group: Applications/System Summary: Provides access to Microsoft Exchange servers using native protocols License: GPLv3+ and Public Domain URL: http://www.openchange.org/ Source0: http://downloads.sourceforge.net/openchange/openchange-%{version}.tar.gz Source1: doxygen_to_devhelp.xsl Source2: openchange-ocsmanager.init Patch0: openchange-1.0-no_ocpf.diff Patch1: ocsmanager-ini-path-fix.diff BuildRoot: %(mktemp -ud %{_tmppath}/%{name}-%{version}-%{release}-XXXXXX) AutoReqProv: 0 Requires: samba4 >= %{samba4_version} ### Build Dependencies ### BuildRequires: bison BuildRequires: doxygen BuildRequires: file # BuildRequires: flex BuildRequires: pkgconfig BuildRequires: libxslt BuildRequires: popt BuildRequires: samba4 >= %{samba4_version} BuildRequires: sqlite-devel BuildRequires: zlib-devel BuildRequires: automake BuildRequires: autoconf %if %{python_sys_pyver} < 33947648 BuildRequires: python26-devel BuildRequires: python26-setuptools >= 0.6c9 BuildRequires: python26-paste-script %else BuildRequires: python-devel BuildRequires: python-setuptools >= 0.6c9 BuildRequires: python-paste-script %endif %if 0%{?rhel} >= 6 BuildRequires: popt-devel %endif %description OpenChange provides libraries to access Microsoft Exchange servers using native protocols. Requires: devhelp %package ocsmanager Group: Applications/System Summary: OpenChange - web services Requires: openchange = %{version}-%{release} %if %{python_sys_pyver} < 33947648 Requires: python26 Requires: python26-pylons Requires: python26-rpclib %else Requires: python Requires: python-pylons Requires: python-rpclib %endif %description ocsmanager This packages provides web services for OpenChange in the form of a Pylons application. %package rpcproxy Group: Applications/System Summary: OpenChange - RPC-over-HTTP proxy Requires: openchange = %{version}-%{release} %if %{python_sys_pyver} < 33947648 Requires: python26 Requires: python26-mod_wsgi %else Requires: python Requires: mod_wsgi %endif %description rpcproxy This package contains a a RPC-over-HTTP python implementation for Samba, using wsgi. # %package devel # Summary: Developer tools for OpenChange libraries # Group: Development/Libraries # Requires: openchange = %{version}-%{release} # %description devel # This package provides the development tools and headers for # OpenChange, providing libraries to access Microsoft Exchange servers # using native protocols. # %package devel-docs # Summary: Developer documentation for OpenChange libraries # Group: Development/Libraries # Requires: openchange = %{version}-%{release} # %description devel-docs # This package contains developer documentation for Openchange. # %package client # Summary: User tools for OpenChange libraries # Group: Applications/System # Requires: openchange = %{version}-%{release} # %description client # This package provides the user tools for OpenChange, providing access to # Microsoft Exchange servers using native protocols. # %if %{build_python_package} # %package python # Summary: Python bindings for OpenChange libraries # Group: Development/Libraries # Requires: openchange = %{version}-%{release} # %description python # This module contains a wrapper that allows the use of OpenChange via Python. # %endif # %if %{build_server_package} # %package server # Summary: Server-side modules for OpenChange # Group: Applications/System # Requires: openchange = %{version}-%{release} # Requires: sqlite # %description server # This package provides the server elements for OpenChange. # %endif %prep %setup -q -n %{name}-%{version} %patch0 -p1 %patch1 -p0 %build ./autogen.sh mkdir rpmbin ln -s %{__python} rpmbin/python ln -s /usr/bin/%{python_config} rpmbin/python-config export PATH=$PWD/rpmbin:$PATH CFLAGS="-O2 -ggdb" \ PYTHON=%{__python} \ PYTHON_CONFIG="/bin/false" \ %configure --with-modulesdir=%{_libdir}/samba4/modules --datadir=%{_datadir}/samba PYTHON=%{__python} # Parallel builds prohibited by makefile make make doxygen for x in openchange_newuser openchange_provision; do \ sed -e 's@/bin/python$@/bin/python2.6@g' setup/$x > setup/$x.sed; \ mv -f setup/$x.sed setup/$x; \ chmod 755 setup/$x; \ done %install rm -rf $RPM_BUILD_ROOTS make install DESTDIR=$RPM_BUILD_ROOT SERVER_MODULESDIR=%{_libdir}/samba4/modules/dcerpc_server cp -r libmapi++ $RPM_BUILD_ROOT%{_includedir} # This makes the right links, as rpmlint requires that the # ldconfig-created links be recorded in the RPM. /sbin/ldconfig -N -n $RPM_BUILD_ROOT/%{_libdir} mkdir $RPM_BUILD_ROOT%{_mandir} cp -r doc/man/man1 $RPM_BUILD_ROOT%{_mandir} cp -r apidocs/man/man3 $RPM_BUILD_ROOT%{_mandir} # Avoid a file conflict with man-pages package. # Page is still reachable as "mapi_obj_bookmark". rm -rf $RPM_BUILD_ROOT%{_mandir}/man3/index.3 install -d $RPM_BUILD_ROOT%{_datadir}/devhelp/books/openchange-libmapi cp -r apidocs/html/libmapi/* $RPM_BUILD_ROOT%{_datadir}/devhelp/books/openchange-libmapi install -d $RPM_BUILD_ROOT%{_datadir}/devhelp/books/openchange-libmapiadmin cp -r apidocs/html/libmapiadmin/* $RPM_BUILD_ROOT%{_datadir}/devhelp/books/openchange-libmapiadmin # mkdir -p $RPM_BUILD_ROOT%{_datadir}/devhelp/books/openchange-libocpf # cp -r apidocs/html/libocpf/* $RPM_BUILD_ROOT%{_datadir}/devhelp/books/openchange-libocpf install -d $RPM_BUILD_ROOT%{_datadir}/devhelp/books/openchange-mapitest cp -r apidocs/html/mapitest/* $RPM_BUILD_ROOT%{_datadir}/devhelp/books/openchange-mapitest install -d $RPM_BUILD_ROOT%{_datadir}/devhelp/books/openchange-mapiproxy cp -r apidocs/html/mapiproxy/* $RPM_BUILD_ROOT%{_datadir}/devhelp/books/openchange-mapiproxy install -d $RPM_BUILD_ROOT%{_datadir}/devhelp/books/openchange-libmapi++ cp -r apidocs/html/libmapi++/* $RPM_BUILD_ROOT%{_datadir}/devhelp/books/openchange-libmapi++ # OCSMANAGER install -d $RPM_BUILD_ROOT/etc/ocsmanager install -m 644 mapiproxy/services/ocsmanager/ocsmanager.ini $RPM_BUILD_ROOT/etc/ocsmanager install -d $RPM_BUILD_ROOT/etc/httpd/conf.d/ install -m 644 mapiproxy/services/ocsmanager/ocsmanager-apache.conf $RPM_BUILD_ROOT/etc/httpd/conf.d/ocsmanager.conf install -d $RPM_BUILD_ROOT/etc/init.d install -m 755 %{_sourcedir}/openchange-ocsmanager.init $RPM_BUILD_ROOT/etc/init.d/openchange-ocsmanager install -d -m 750 $RPM_BUILD_ROOT/var/log/ocsmanager # used by ocsmanager and rpcproxy install -d -m 700 -o apache -g apache $RPM_BUILD_ROOT/var/cache/ntlmauthhandler (cd mapiproxy/services/ocsmanager; %{__python} setup.py install --root=$RPM_BUILD_ROOT --prefix=/usr) # RPCPROXY install -m 0644 mapiproxy/services/web/rpcproxy/rpcproxy.conf $RPM_BUILD_ROOT/etc/httpd/conf.d/rpcproxy.conf install -d $RPM_BUILD_ROOT/usr/lib/openchange/web/rpcproxy install -m 0644 mapiproxy/services/web/rpcproxy/rpcproxy.wsgi $RPM_BUILD_ROOT/usr/lib/openchange/web/rpcproxy/rpcproxy.wsgi (cd mapiproxy/services/web/rpcproxy; python$* setup.py install --install-lib=/usr/lib/openchange/web/rpcproxy --root $RPM_BUILD_ROOT \ --install-scripts=/usr/lib/openchange/web/rpcproxy) %clean rm -rf $RPM_BUILD_ROOT %post /sbin/ldconfig %postun /sbin/ldconfig # %if %{build_server_package} # %post server -p /sbin/ldconfig # %postun server -p /sbin/ldconfig # %endif %files %defattr(-,root,root,-) %doc ChangeLog COPYING IDL_LICENSE.txt VERSION /var/cache/ntlmauthhandler # %{_libdir}/libmapi-openchange.so.* %{_libdir}/libmapiadmin.so.* %{_libdir}/libmapi.so.* %{_libdir}/libmapiproxy.so.* # %{_libdir}/libocpf.so.* # %files devel # %defattr(-,root,root,-) %{_includedir}/* %{_libdir}/*.so %{_libdir}/pkgconfig/* %{_mandir}/man3/* %doc apidocs/html/libmapi # %doc apidocs/html/libocpf %doc apidocs/html/overview %doc apidocs/html/index.html # %files devel-docs # %defattr(-,root,root,-) %doc %{_datadir}/devhelp/books/* # %files client # %defattr(-,root,root,-) %{_bindir}/* %{_mandir}/man1/* # %if %{build_python_package} # %files python # %defattr(-,root,root,-) %{python_sitearch}/openchange # %endif # %if %{build_server_package} # %files server # %defattr(-,root,root,-) %{_sbindir}/* %{_libdir}/libmapiserver.so.* %{_libdir}/libmapistore.so.* # %{_libdir}/mapistore_backends/mapistore_sqlite3.so %{_libdir}/samba4/modules/*/* %{_libdir}/nagios/check_exchange %{_datadir}/samba/* # %endif %files ocsmanager %config(noreplace) /etc/init.d/openchange-ocsmanager %config(noreplace) /etc/ocsmanager/* %config(noreplace) /etc/httpd/conf.d/ocsmanager.conf %{python_noarch_sitearch}/ocsmanager* /var/log/ocsmanager %files rpcproxy %config(noreplace) /etc/httpd/conf.d/rpcproxy.conf /usr/lib/openchange/web/rpcproxy/* /usr/lib/openchange/web/rpcproxy/rpcproxy/* %changelog * Wed Aug 9 2012 Jean Raby 1.0.prerelease - add missing log folder for ocsmanager * Wed Aug 1 2012 Jean Raby 1.0.prerelease - split openchange, ocsmanager and rpcproxy - use install -d instead of mkdir, for consistency - add rpcproxy * Tue Jul 31 2012 Jean Raby 1.0.prerelease - use ocsmanager.ini from the distribution - install the apache config now shipped with the distribution - create /var/lib/ntlmauthhandler. needed by ocsmanager - use config(noreplace) for ocsmanager config files * Wed Oct 12 2011 Wolfgang Sourdeau 4.0.0-25.alpha17.1 - Update package to openchange-sogo 0.11.20111210 - Build everything unconditionnally and in the same package - Removed auto dependencies * Tue Apr 26 2011 Milan Crha - 0.9-16 - Add patch for Gnome bug #632784 (send to recipients with Unicode letters in a name) * Thu Mar 10 2011 Milan Crha - 0.9-15 - Rebuild against newer libldb (previously was picked old version) * Mon Feb 21 2011 Milan Crha - 0.9-14 - Rebuild against newer libldb * Tue Feb 08 2011 Fedora Release Engineering - 0.9-13 - Rebuilt for https://fedoraproject.org/wiki/Fedora_15_Mass_Rebuild * Wed Feb 02 2011 Milan Crha - 0.9-12 - Add patch for message sending, found by Gianluca Cecchi (RH bug #674034) * Thu Dec 16 2010 Matthew Barnes - 0.9-11 - Re-fix man-pages file conflict (RH bug #654729). * Thu Dec 02 2010 Milan Crha - 0.9-10 - Add patch for talloc abort in FindGoodServer, found by Jeff Raber (RH bug #602661) * Wed Sep 29 2010 jkeating - 0.9-9 - Rebuilt for gcc bug 634757 * Mon Sep 13 2010 Matthew Barnes - 0.9-8 - Backport unicode and properties support (RH bug #605364). * Wed Jul 21 2010 David Malcolm - 0.9-7 - Rebuilt for https://fedoraproject.org/wiki/Features/Python_2.7/MassRebuild * Thu Jun 24 2010 Matthew Barnes - 0.9-6 - Disable python and server subpackages until they're needed. * Wed Jun 23 2010 Matthew Barnes - 0.9-5 - More spec file cleanups. * Fri Jun 18 2010 Matthew Barnes - 0.9-4 - Spec file cleanups. * Mon May 24 2010 Matthew Barnes - 0.9-3 - Avoid a file conflict with man-pages package. * Sat Jan 09 2010 Matthew Barnes - 0.9-2 - Add a devel-docs subpackage (RH bug #552984). * Sat Dec 26 2009 Matthew Barnes - 0.9-1 - Update to 0.9 (COCHRANE) - Bump samba4 requirement to alpha10. * Wed Sep 23 2009 Matthew Barnes - 0.8.2-5 - Rebuild. * Sat Jul 25 2009 Fedora Release Engineering - 0.8.2-4 - Rebuilt for https://fedoraproject.org/wiki/Fedora_12_Mass_Rebuild * Mon Jun 29 2009 Matthew Barnes - 0.8.2-3 - Rename libmapi so as not to conflict with Zarafa (RH bug #505783). * Thu May 07 2009 Matthew Barnes - 0.8.2-2 - Do not own the pkgconfig directory (RH bug #499655). * Tue Mar 31 2009 Matthew Barnes - 0.8.2-1 - Update to 0.8.2 - Add a server subpackage. - Add BuildRequires: sqlite-devel (for server) * Sun Mar 08 2009 Matthew Barnes - 0.8-6 - Fix build breakage. - Explicitly require libldb-devel. - Bump samba4 requirement to alpha7. * Wed Feb 25 2009 Matthew Barnes - 0.8-5 - Rebuild with correct tarball. * Wed Feb 25 2009 Matthew Barnes - 0.8-4 - Formal package review cleanups. * Wed Feb 25 2009 Matthew Barnes - 0.8-3 - Add documentation files. * Thu Feb 19 2009 Matthew Barnes - 0.8-2 - Add some missing build requirements. * Thu Jan 20 2009 Matthew Barnes - 0.8-1 - Update to 0.8 (ROMULUS) * Sat Jan 17 2009 Matthew Barnes - 0.8-0.7.svn949 - Add missing BuildRequires: zlib-devel * Sat Dec 27 2008 Matthew Barnes - 0.8-0.6.svn949 - Update to SVN revision 949. * Mon Dec 15 2008 Matthew Barnes - 0.8-0.5.svn909 - Package review feedback (RH bug #453395). * Fri Dec 12 2008 Matthew Barnes - 0.8-0.4.svn909 - Update to SVN revision 909. - Bump the samba4 requirement. * Fri Aug 29 2008 Andrew Bartlett - 0:0.8-0.3.svn960.fc9 - Bump version - Don't make the Samba4 version distro-dependent * Sat Jul 26 2008 Brad Hards - 0:0.8-0.2.svnr674.fc10 - Bump version - Install documentation / man pages correctly - Remove epoch (per https://bugzilla.redhat.com/show_bug.cgi?id=453395) - Remove %%post and %%postun (per https://bugzilla.redhat.com/show_bug.cgi?id=453395) - Remove talloc dependency (per https://bugzilla.redhat.com/show_bug.cgi?id=453395) - Take out libmapiproxy, because we aren't up to server side yet. * Sat Jul 12 2008 Andrew Bartlett - 0:0.7-0.2.svnr627.fc9 - Add popt-devel BR * Mon Jun 30 2008 Andrew Bartlett - 0:0.7-0.1.svnr627.fc9 - Initial package of OpenChange for Fedora openchange-2.0/properties_enum.h000066400000000000000000003506131223057412600170650ustar00rootroot00000000000000/* Automatically generated by script/makepropslist.py. Do not edit */ typedef [v1_enum, flag(NDR_PAHEX)] enum { PidTag7BitDisplayName = 0x39FF001F, PidTag7BitDisplayName_Error = 0x39FF000A, PidTag7BitDisplayName_string8 = 0x39FF001E, PidTagAccess = 0x0FF40003, PidTagAccessLevel = 0x0FF70003, PidTagAccessLevel_Error = 0x0FF7000A, PidTagAccess_Error = 0x0FF4000A, PidTagAccount = 0x3A00001F, PidTagAccessControlListData = 0x3FE00102, PidTagAccessControlListData_Error = 0x3FE0000A, PidTagAccount_Error = 0x3A00000A, PidTagAccount_string8 = 0x3A00001E, PidTagAdditionalRenEntryIds = 0x36D81102, PidTagAdditionalRenEntryIdsEx = 0x36D90102, PidTagAdditionalRenEntryIdsEx_Error = 0x36D9000A, PidTagAdditionalRenEntryIds_Error = 0x36D8000A, PidTagAddressBookAuthorizedSenders = 0x8CD8000D, PidTagAddressBookAuthorizedSenders_Error = 0x8CD8000A, PidTagAddressBookContainerId = 0xFFFD0003, PidTagAddressBookContainerId_Error = 0xFFFD000A, PidTagAddressBookDeliveryContentLength = 0x806A0003, PidTagAddressBookDeliveryContentLength_Error = 0x806A000A, PidTagAddressBookDisplayTypeExtended = 0x8C930003, PidTagAddressBookDisplayTypeExtended_Error = 0x8C93000A, PidTagAddressBookDistributionListExternalMemberCount = 0x8CE30003, PidTagAddressBookDistributionListExternalMemberCount_Error = 0x8CE3000A, PidTagAddressBookDistributionListMemberCount = 0x8CE20003, PidTagAddressBookDistributionListMemberCount_Error = 0x8CE2000A, PidTagAddressBookDistributionListMemberSubmitAccepted = 0x8073000D, PidTagAddressBookDistributionListMemberSubmitAccepted_Error = 0x8073000A, PidTagAddressBookDistributionListMemberSubmitRejected = 0x8CDA000D, PidTagAddressBookDistributionListMemberSubmitRejected_Error = 0x8CDA000A, PidTagAddressBookDistributionListRejectMessagesFromDLMembers = 0x8CDB000D, PidTagAddressBookDistributionListRejectMessagesFromDLMembers_Error = 0x8CDB000A, PidTagAddressBookEntryId = 0x663B0102, PidTagAddressBookEntryId_Error = 0x663B000A, PidTagAddressBookExtensionAttribute1 = 0x802D001F, PidTagAddressBookExtensionAttribute15 = 0x8C61001F, PidTagAddressBookExtensionAttribute15_Error = 0x8C61000A, PidTagAddressBookExtensionAttribute15_string8 = 0x8C61001E, PidTagAddressBookExtensionAttribute1_Error = 0x802D000A, PidTagAddressBookExtensionAttribute1_string8 = 0x802D001E, PidTagAddressBookFolderPathname = 0x8004001F, PidTagAddressBookFolderPathname_Error = 0x8004000A, PidTagAddressBookFolderPathname_string8 = 0x8004001E, PidTagAddressBookHierarchicalChildDepartments = 0x8C9A000D, PidTagAddressBookHierarchicalChildDepartments_Error = 0x8C9A000A, PidTagAddressBookHierarchicalDepartmentMembers = 0x8C97000D, PidTagAddressBookHierarchicalDepartmentMembers_Error = 0x8C97000A, PidTagAddressBookHierarchicalIsHierarchicalGroup = 0x8CDD000B, PidTagAddressBookHierarchicalIsHierarchicalGroup_Error = 0x8CDD000A, PidTagAddressBookHierarchicalParentDepartment = 0x8C99000D, PidTagAddressBookHierarchicalParentDepartment_Error = 0x8C99000A, PidTagAddressBookHierarchicalRootDepartment = 0x8C98001E, PidTagAddressBookHierarchicalRootDepartment_Error = 0x8C98000A, PidTagAddressBookHierarchicalShowInDepartments = 0x8C94000D, PidTagAddressBookHierarchicalShowInDepartments_Error = 0x8C94000A, PidTagAddressBookHomeMessageDatabase = 0x8006001F, PidTagAddressBookHomeMessageDatabase_string8 = 0x8006001E, PidTagAddressBookHomeMessageDatabase_Error = 0x8006000A, PidTagAddressBookIsMaster = 0xFFFB000B, PidTagAddressBookIsMaster_Error = 0xFFFB000A, PidTagAddressBookIsMemberOfDistributionList = 0x8008101E, PidTagAddressBookIsMemberOfDistributionList_Error = 0x8008000A, PidTagAddressBookManageDistributionList = 0x6704000D, PidTagAddressBookManageDistributionList_Error = 0x6704000A, PidTagAddressBookManager = 0x8005000D, PidTagAddressBookManagerDistinguishedName = 0x8005001F, PidTagAddressBookManager_Error = 0x8005000A, PidTagAddressBookMember = 0x8009101E, PidTagAddressBookMember_Error = 0x8009000A, PidTagAddressBookMessageId = 0x674F0014, PidTagAddressBookMessageId_Error = 0x674F000A, PidTagAddressBookModerationEnabled = 0x8CB5000B, PidTagAddressBookModerationEnabled_Error = 0x8CB5000A, PidTagAddressBookNetworkAddress = 0x8170101F, PidTagAddressBookNetworkAddress_string8 = 0x8170101E, PidTagAddressBookNetworkAddress_Error = 0x8170000A, PidTagAddressBookObjectDistinguishedName = 0x803C001F, PidTagAddressBookObjectDistinguishedName_Error = 0x803C000A, PidTagAddressBookObjectDistinguishedName_string8 = 0x803C001E, PidTagAddressBookObjectGuid = 0x8C6D0102, PidTagAddressBookObjectGuid_Error = 0x8C6D000A, PidTagAddressBookOrganizationalUnitRootDistinguishedName = 0x8CA8001F, PidTagAddressBookOrganizationalUnitRootDistinguishedName_Error = 0x8CA8000A, PidTagAddressBookOrganizationalUnitRootDistinguishedName_string8 = 0x8CA8001E, PidTagAddressBookOwner = 0x800C000D, PidTagAddressBookOwnerBackLink = 0x8024000D, PidTagAddressBookOwnerBackLink_Error = 0x8024000A, PidTagAddressBookOwner_Error = 0x800C000A, PidTagAddressBookParentEntryId = 0xFFFC0102, PidTagAddressBookParentEntryId_Error = 0xFFFC000A, PidTagAddressBookPhoneticCompanyName = 0x8C91001F, PidTagAddressBookPhoneticCompanyName_Error = 0x8C91000A, PidTagAddressBookPhoneticCompanyName_string8 = 0x8C91001E, PidTagAddressBookPhoneticDepartmentName = 0x8C90001F, PidTagAddressBookPhoneticDepartmentName_Error = 0x8C90000A, PidTagAddressBookPhoneticDepartmentName_string8 = 0x8C90001E, PidTagAddressBookPhoneticDisplayName = 0x8C92001F, PidTagAddressBookPhoneticDisplayName_Error = 0x8C92000A, PidTagAddressBookPhoneticDisplayName_string8 = 0x8C92001E, PidTagAddressBookPhoneticGivenName = 0x8C8E001F, PidTagAddressBookPhoneticGivenName_Error = 0x8C8E000A, PidTagAddressBookPhoneticGivenName_string8 = 0x8C8E001E, PidTagAddressBookPhoneticSurname = 0x8C8F001F, PidTagAddressBookPhoneticSurname_Error = 0x8C8F000A, PidTagAddressBookPhoneticSurname_string8 = 0x8C8F001E, PidTagAddressBookProxyAddresses = 0x800F101F, PidTagAddressBookProxyAddresses_string8 = 0x800F101E, PidTagAddressBookProxyAddresses_Error = 0x800F000A, PidTagAddressBookPublicDelegates = 0x8015000D, PidTagAddressBookPublicDelegates_Error = 0x8015000A, PidTagAddressBookReports = 0x800E000D, PidTagAddressBookReports_Error = 0x800E000A, PidTagAddressBookRoomCapacity = 0x08070003, PidTagAddressBookRoomCapacity_Error = 0x0807000A, PidTagAddressBookRoomContainers = 0x8C96101F, PidTagAddressBookRoomContainers_Error = 0x8C96000A, PidTagAddressBookRoomDescription = 0x0809001F, PidTagAddressBookRoomDescription_Error = 0x0809000A, PidTagAddressBookRoomDescription_string8 = 0x0809001E, PidTagAddressBookSenderHintTranslations = 0x8CAC101F, PidTagAddressBookSenderHintTranslations_Error = 0x8CAC000A, PidTagAddressBookSeniorityIndex = 0x8CA00003, PidTagAddressBookSeniorityIndex_Error = 0x8CA0000A, PidTagAddressBookTargetAddress = 0x8011001F, PidTagAddressBookTargetAddress_Error = 0x8011000A, PidTagAddressBookTargetAddress_string8 = 0x8011001E, PidTagAddressBookUnauthorizedSenders = 0x8CD9000D, PidTagAddressBookUnauthorizedSenders_Error = 0x8CD9000A, PidTagAddressBookX509Certificate = 0x8C6A1102, PidTagAddressBookX509Certificate_Error = 0x8C6A000A, PidTagAddressType = 0x3002001F, PidTagAddressType_Error = 0x3002000A, PidTagAddressType_string8 = 0x3002001E, PidTagAlternateRecipientAllowed = 0x0002000B, PidTagAlternateRecipientAllowed_Error = 0x0002000A, PidTagAnr = 0x360C001F, PidTagAnr_Error = 0x360C000A, PidTagAnr_string8 = 0x360C001E, PidTagArchiveDate = 0x301F0040, PidTagArchiveDate_Error = 0x301F000A, PidTagArchivePeriod = 0x301E0003, PidTagArchivePeriod_Error = 0x301E000A, PidTagArchiveTag = 0x30180102, PidTagArchiveTag_Error = 0x3018000A, PidTagAssistant = 0x3A30001F, PidTagAssistantTelephoneNumber = 0x3A2E001F, PidTagAssistantTelephoneNumber_Error = 0x3A2E000A, PidTagAssistantTelephoneNumber_string8 = 0x3A2E001E, PidTagAssistant_Error = 0x3A30000A, PidTagAssistant_string8 = 0x3A30001E, PidTagAssociated = 0x67AA000B, PidTagAssociated_Error = 0x67AA000A, PidTagAttachAdditionalInformation = 0x370F0102, PidTagAttachAdditionalInformation_Error = 0x370F000A, PidTagAttachContentBase = 0x3711001F, PidTagAttachContentBase_Error = 0x3711000A, PidTagAttachContentBase_string8 = 0x3711001E, PidTagAttachContentId = 0x3712001F, PidTagAttachContentId_Error = 0x3712000A, PidTagAttachContentId_string8 = 0x3712001E, PidTagAttachContentLocation = 0x3713001F, PidTagAttachContentLocation_Error = 0x3713000A, PidTagAttachContentLocation_string8 = 0x3713001E, PidTagAttachDataBinary = 0x37010102, PidTagAttachDataBinary_Error = 0x3701000A, PidTagAttachDataObject = 0x3701000D, PidTagAttachEncoding = 0x37020102, PidTagAttachEncoding_Error = 0x3702000A, PidTagAttachExtension = 0x3703001F, PidTagAttachExtension_Error = 0x3703000A, PidTagAttachExtension_string8 = 0x3703001E, PidTagAttachFilename = 0x3704001F, PidTagAttachFilename_Error = 0x3704000A, PidTagAttachFilename_string8 = 0x3704001E, PidTagAttachFlags = 0x37140003, PidTagAttachFlags_Error = 0x3714000A, PidTagAttachLongFilename = 0x3707001F, PidTagAttachLongFilename_Error = 0x3707000A, PidTagAttachLongFilename_string8 = 0x3707001E, PidTagAttachLongPathname = 0x370D001F, PidTagAttachLongPathname_Error = 0x370D000A, PidTagAttachLongPathname_string8 = 0x370D001E, PidTagAttachMethod = 0x37050003, PidTagAttachMethod_Error = 0x3705000A, PidTagAttachMimeTag = 0x370E001F, PidTagAttachMimeTag_Error = 0x370E000A, PidTagAttachMimeTag_string8 = 0x370E001E, PidTagAttachNumber = 0x0E210003, PidTagAttachNumber_Error = 0x0E21000A, PidTagAttachPathname = 0x3708001F, PidTagAttachPathname_Error = 0x3708000A, PidTagAttachPathname_string8 = 0x3708001E, PidTagAttachPayloadClass = 0x371A001F, PidTagAttachPayloadClass_Error = 0x371A000A, PidTagAttachPayloadClass_string8 = 0x371A001E, PidTagAttachPayloadProviderGuidString = 0x3719001F, PidTagAttachPayloadProviderGuidString_Error = 0x3719000A, PidTagAttachPayloadProviderGuidString_string8 = 0x3719001E, PidTagAttachRendering = 0x37090102, PidTagAttachRendering_Error = 0x3709000A, PidTagAttachSize = 0x0E200003, PidTagAttachSize_Error = 0x0E20000A, PidTagAttachTag = 0x370A0102, PidTagAttachTag_Error = 0x370A000A, PidTagAttachTransportName = 0x370C001F, PidTagAttachTransportName_Error = 0x370C000A, PidTagAttachTransportName_string8 = 0x370C001E, PidTagAttachmentContactPhoto = 0x7FFF000B, PidTagAttachmentContactPhoto_Error = 0x7FFF000A, PidTagAttachmentFlags = 0x7FFD0003, PidTagAttachmentFlags_Error = 0x7FFD000A, PidTagAttachmentHidden = 0x7FFE000B, PidTagAttachmentHidden_Error = 0x7FFE000A, PidTagAttachmentLinkId = 0x7FFA0003, PidTagAttachmentLinkId_Error = 0x7FFA000A, PidTagAttributeHidden = 0x10F4000B, PidTagAttributeHidden_Error = 0x10F4000A, PidTagAttributeReadOnly = 0x10F6000B, PidTagAttributeReadOnly_Error = 0x10F6000A, PidTagAttributeSystem = 0x10F5000B, PidTagAttributeSystem_Error = 0x10F5000A, PidTagAutoForwardComment = 0x0004001F, PidTagAutoForwardComment_Error = 0x0004000A, PidTagAutoForwardComment_string8 = 0x0004001E, PidTagAutoForwarded = 0x0005000B, PidTagAutoForwarded_Error = 0x0005000A, PidTagAutoResponseSuppress = 0x3FDF0003, PidTagAutoResponseSuppress_Error = 0x3FDF000A, PidTagBirthday = 0x3A420040, PidTagBirthday_Error = 0x3A42000A, PidTagBlockStatus = 0x10960003, PidTagBlockStatus_Error = 0x1096000A, PidTagBody = 0x1000001F, PidTagBodyContentId = 0x1015001F, PidTagBodyContentId_Error = 0x1015000A, PidTagBodyContentId_string8 = 0x1015001E, PidTagBodyContentLocation = 0x1014001F, PidTagBodyContentLocation_Error = 0x1014000A, PidTagBodyContentLocation_string8 = 0x1014001E, PidTagBodyHtml = 0x1013001F, PidTagBodyHtml_Error = 0x1013000A, PidTagBodyHtml_string8 = 0x1013001E, PidTagBody_Error = 0x1000000A, PidTagBody_string8 = 0x1000001E, PidTagBusiness2TelephoneNumber = 0x3A1B001F, PidTagBusiness2TelephoneNumber_Error = 0x3A1B000A, PidTagBusiness2TelephoneNumber_string8 = 0x3A1B001E, PidTagBusiness2TelephoneNumbers = 0x3A1B101F, PidTagBusinessFaxNumber = 0x3A24001F, PidTagBusinessFaxNumber_Error = 0x3A24000A, PidTagBusinessFaxNumber_string8 = 0x3A24001E, PidTagBusinessHomePage = 0x3A51001F, PidTagBusinessHomePage_Error = 0x3A51000A, PidTagBusinessHomePage_string8 = 0x3A51001E, PidTagBusinessTelephoneNumber = 0x3A08001F, PidTagBusinessTelephoneNumber_Error = 0x3A08000A, PidTagBusinessTelephoneNumber_string8 = 0x3A08001E, PidTagCallId = 0x6806001F, PidTagCallId_Error = 0x6806000A, PidTagCallId_string8 = 0x6806001E, PidTagCallbackTelephoneNumber = 0x3A02001F, PidTagCallbackTelephoneNumber_Error = 0x3A02000A, PidTagCallbackTelephoneNumber_string8 = 0x3A02001E, PidTagCarTelephoneNumber = 0x3A1E001F, PidTagCarTelephoneNumber_Error = 0x3A1E000A, PidTagCarTelephoneNumber_string8 = 0x3A1E001E, PidTagCdoRecurrenceid = 0x10C50040, PidTagCdoRecurrenceid_Error = 0x10C5000A, PidTagChangeKey = 0x65E20102, PidTagChangeKey_Error = 0x65E2000A, PidTagChangeNotificationGuid = 0x66370048, PidTagChangeNotificationGuid_Error = 0x6637000A, PidTagChangeNumber = 0x67A40014, PidTagChangeNumber_Error = 0x67A4000A, PidTagChildrensNames = 0x3A58101F, PidTagChildrensNames_Error = 0x3A58000A, PidTagClientActions = 0x66450102, PidTagClientActions_Error = 0x6645000A, PidTagClientSubmitTime = 0x00390040, PidTagClientSubmitTime_Error = 0x0039000A, PidTagCnsetRead = 0x67D20102, PidTagCnsetRead_Error = 0x67D2000A, PidTagCnsetSeen = 0x67960102, PidTagCnsetSeenFAI = 0x67DA0102, PidTagCnsetSeenFAI_Error = 0x67DA000A, PidTagCnsetSeen_Error = 0x6796000A, PidTagCodePageId = 0x66C30003, PidTagCodePageId_Error = 0x66C3000A, PidTagComment = 0x3004001F, PidTagComment_Error = 0x3004000A, PidTagComment_string8 = 0x3004001E, PidTagCompanyMainTelephoneNumber = 0x3A57001F, PidTagCompanyMainTelephoneNumber_Error = 0x3A57000A, PidTagCompanyMainTelephoneNumber_string8 = 0x3A57001E, PidTagCompanyName = 0x3A16001F, PidTagCompanyName_Error = 0x3A16000A, PidTagCompanyName_string8 = 0x3A16001E, PidTagComputerNetworkName = 0x3A49001F, PidTagComputerNetworkName_Error = 0x3A49000A, PidTagComputerNetworkName_string8 = 0x3A49001E, PidTagConflictEntryId = 0x3FF00102, PidTagConflictEntryId_Error = 0x3FF0000A, PidTagConflictItems = 0x10981102, PidTagConflictItems_Error = 0x1098000A, PidTagContainerClass = 0x3613001F, PidTagContainerClass_Error = 0x3613000A, PidTagContainerClass_string8 = 0x3613001E, PidTagContainerContents = 0x360F000D, PidTagContainerContents_Error = 0x360F000A, PidTagContainerFlags = 0x36000003, PidTagContainerFlags_Error = 0x3600000A, PidTagContainerHierarchy = 0x360E000D, PidTagContainerHierarchy_Error = 0x360E000A, PidTagContentCount = 0x36020003, PidTagContentCount_Error = 0x3602000A, PidTagContentFilterPhishingConfidenceLevel = 0x40840003, PidTagContentFilterPhishingConfidenceLevel_Error = 0x4084000A, PidTagContentFilterSpamConfidenceLevel = 0x40760003, PidTagContentFilterSpamConfidenceLevel_Error = 0x4076000A, PidTagContentUnreadCount = 0x36030003, PidTagContentUnreadCount_Error = 0x3603000A, PidTagConversationId = 0x30130102, PidTagConversationId_Error = 0x3013000A, PidTagConversationIndex = 0x00710102, PidTagConversationIndexTracking = 0x3016000B, PidTagConversationIndexTracking_Error = 0x3016000A, PidTagConversationIndex_Error = 0x0071000A, PidTagConversationTopic = 0x0070001F, PidTagConversationTopic_Error = 0x0070000A, PidTagConversationTopic_string8 = 0x0070001E, PidTagCountry = 0x3A26001F, PidTagCountry_Error = 0x3A26000A, PidTagCountry_string8 = 0x3A26001E, PidTagCreationTime = 0x30070040, PidTagCreationTime_Error = 0x3007000A, PidTagCreatorEntryId = 0x3FF90102, PidTagCreatorEntryId_Error = 0x3FF9000A, PidTagCreatorName = 0x3FF8001F, PidTagCreatorName_Error = 0x3FF8000A, PidTagCreatorName_string8 = 0x3FF8001E, PidTagCreatorSId = 0x0E580102, PidTagCreatorSimpleDisplayName = 0x4038001F, PidTagCreatorSimpleDisplayName_Error = 0x4038000A, PidTagCreatorSimpleDisplayName_string8 = 0x4038001E, PidTagCustomerId = 0x3A4A001F, PidTagCustomerId_Error = 0x3A4A000A, PidTagCustomerId_string8 = 0x3A4A001E, PidTagDamBackPatched = 0x6647000B, PidTagDamBackPatched_Error = 0x6647000A, PidTagDamOriginalEntryId = 0x66460102, PidTagDamOriginalEntryId_Error = 0x6646000A, PidTagDefaultFormName = 0x36E6001F, PidTagDefaultFormName_string8 = 0x36E6001E, PidTagDefaultFormName_Error = 0x36E6000A, PidTagDefaultPostMessageClass = 0x36E5001F, PidTagDefaultPostMessageClass_Error = 0x36E5000A, PidTagDefaultPostMessageClass_string8 = 0x36E5001E, PidTagDefaultViewEntryId = 0x36160102, PidTagDeferredActionMessageOriginalEntryId = 0x674100FB, PidTagDeferredActionMessageOriginalEntryId_Error = 0x6741000A, PidTagDeferredDeliveryTime = 0x000F0040, PidTagDeferredDeliveryTime_Error = 0x000F000A, PidTagDeferredSendNumber = 0x3FEB0003, PidTagDeferredSendNumber_Error = 0x3FEB000A, PidTagDeferredSendTime = 0x3FEF0040, PidTagDeferredSendTime_Error = 0x3FEF000A, PidTagDeferredSendUnits = 0x3FEC0003, PidTagDeferredSendUnits_Error = 0x3FEC000A, PidTagDelegateFlags = 0x686B1003, PidTagDelegateFlags_Error = 0x686B000A, PidTagDelegatedByRule = 0x3FE3000B, PidTagDelegatedByRule_Error = 0x3FE3000A, PidTagDeleteAfterSubmit = 0x0E01000B, PidTagDeleteAfterSubmit_Error = 0x0E01000A, PidTagDeletedOn = 0x668F0040, PidTagDeletedOn_Error = 0x668F000A, PidTagDepartmentName = 0x3A18001F, PidTagDepartmentName_Error = 0x3A18000A, PidTagDepartmentName_string8 = 0x3A18001E, PidTagDepth = 0x30050003, PidTagDepth_Error = 0x3005000A, PidTagDesignInProgress = 0x3fe4000b, PidTagDisplayBcc = 0x0E02001F, PidTagDisplayBcc_Error = 0x0E02000A, PidTagDisplayBcc_string8 = 0x0E02001E, PidTagDisplayCc = 0x0E03001F, PidTagDisplayCc_Error = 0x0E03000A, PidTagDisplayCc_string8 = 0x0E03001E, PidTagDisplayName = 0x3001001F, PidTagDisplayNamePrefix = 0x3A45001F, PidTagDisplayNamePrefix_Error = 0x3A45000A, PidTagDisplayNamePrefix_string8 = 0x3A45001E, PidTagDisplayName_Error = 0x3001000A, PidTagDisplayName_string8 = 0x3001001E, PidTagDisplayTo = 0x0E04001F, PidTagDisplayTo_Error = 0x0E04000A, PidTagDisplayTo_string8 = 0x0E04001E, PidTagDisplayType = 0x39000003, PidTagDisplayTypeEx = 0x39050003, PidTagDisplayTypeEx_Error = 0x3905000A, PidTagDisplayType_Error = 0x3900000A, PidTagEcWarning = 0x400F0003, PidTagEcWarning_Error = 0x400F000A, PidTagEmailAddress = 0x3003001F, PidTagEmailAddress_Error = 0x3003000A, PidTagEmailAddress_string8 = 0x3003001E, PidTagEndAttach = 0x400E0003, PidTagEndAttach_Error = 0x400E000A, PidTagEndDate = 0x00610040, PidTagEndDate_Error = 0x0061000A, PidTagEndEmbed = 0x40020003, PidTagEndEmbed_Error = 0x4002000A, PidTagEndFolder = 0x400B0003, PidTagEndFolder_Error = 0x400B000A, PidTagEndMessage = 0x400D0003, PidTagEndMessage_Error = 0x400D000A, PidTagEndToRecip = 0x40040003, PidTagEndToRecip_Error = 0x4004000A, PidTagEntryId = 0x0FFF0102, PidTagEntryId_Error = 0x0FFF000A, PidTagExceptionEndTime = 0x7FFC0040, PidTagExceptionEndTime_Error = 0x7FFC000A, PidTagExceptionReplaceTime = 0x7FF90040, PidTagExceptionReplaceTime_Error = 0x7FF9000A, PidTagExceptionStartTime = 0x7FFB0040, PidTagExceptionStartTime_Error = 0x7FFB000A, PidTagExchangeNTSecurityDescriptor = 0x0E840102, PidTagExchangeNTSecurityDescriptor_Error = 0x0E84000A, PidTagExpiryNumber = 0x3FED0003, PidTagExpiryNumber_Error = 0x3FED000A, PidTagExpiryTime = 0x00150040, PidTagExpiryTime_Error = 0x0015000A, PidTagExpiryUnits = 0x3FEE0003, PidTagExpiryUnits_Error = 0x3FEE000A, PidTagExtendedACLData = 0x3FFE0102, PidTagExtendedFolderFlags = 0x36DA0102, PidTagExtendedFolderFlags_Error = 0x36DA000A, PidTagExtendedRuleMessageActions = 0x0E990102, PidTagExtendedRuleMessageActions_Error = 0x0E99000A, PidTagExtendedRuleMessageCondition = 0x0E9A0102, PidTagExtendedRuleMessageCondition_Error = 0x0E9A000A, PidTagExtendedRuleSizeLimit = 0x0E9B0003, PidTagExtendedRuleSizeLimit_Error = 0x0E9B000A, PidTagFXDelProp = 0x40160003, PidTagFXDelProp_Error = 0x4016000A, PidTagFXErrorInfo = 0x40180003, PidTagFXErrorInfo_Error = 0x4018000A, PidTagFaxNumberOfPages = 0x68040003, PidTagFaxNumberOfPages_Error = 0x6804000A, PidTagFlagCompleteTime = 0x10910040, PidTagFlagCompleteTime_Error = 0x1091000A, PidTagFlagStatus = 0x10900003, PidTagFlagStatus_Error = 0x1090000A, PidTagFlatUrlName = 0x670E001F, PidTagFlatUrlName_Error = 0x670E000A, PidTagFlatUrlName_string8 = 0x670E001E, PidTagFolderAssociatedContents = 0x3610000D, PidTagFolderAssociatedContents_Error = 0x3610000A, PidTagFolderExtendedViewInfo = 0x36e00102, PidTagFolderFlags = 0x66A80003, PidTagFolderFlags_Error = 0x66A8000A, PidTagFolderId = 0x67480014, PidTagFolderId_Error = 0x6748000A, PidTagFolderType = 0x36010003, PidTagFolderType_Error = 0x3601000A, PidTagFolderViewList = 0x36EB0102, PidTagFolderViewsOnly = 0x36E10003, PidTagFolderWebViewInfo = 0x36DF0102, PidTagFollowupIcon = 0x10950003, PidTagFollowupIcon_Error = 0x1095000A, PidTagFreeBusyCountMonths = 0x68690003, PidTagFreeBusyCountMonths_Error = 0x6869000A, PidTagFreeBusyEntryIds = 0x36E41102, PidTagFreeBusyEntryIds_Error = 0x36E4000A, PidTagFreeBusyMessageEmailAddress = 0x6849001F, PidTagFreeBusyMessageEmailAddress_Error = 0x6849000A, PidTagFreeBusyMessageEmailAddress_string8 = 0x6849001E, PidTagFreeBusyPublishEnd = 0x68480003, PidTagFreeBusyPublishEnd_Error = 0x6848000A, PidTagFreeBusyPublishStart = 0x68470003, PidTagFreeBusyPublishStart_Error = 0x6847000A, PidTagFreeBusyRangeTimestamp = 0x68680040, PidTagFreeBusyRangeTimestamp_Error = 0x6868000A, PidTagFtpSite = 0x3A4C001F, PidTagFtpSite_Error = 0x3A4C000A, PidTagFtpSite_string8 = 0x3A4C001E, PidTagGatewayNeedsToRefresh = 0x6846000B, PidTagGatewayNeedsToRefresh_Error = 0x6846000A, PidTagGender = 0x3A4D0002, PidTagGender_Error = 0x3A4D000A, PidTagGeneration = 0x3A05001F, PidTagGeneration_Error = 0x3A05000A, PidTagGeneration_string8 = 0x3A05001E, PidTagGivenName = 0x3A06001F, PidTagGivenName_Error = 0x3A06000A, PidTagGivenName_string8 = 0x3A06001E, PidTagGovernmentIdNumber = 0x3A07001F, PidTagGovernmentIdNumber_Error = 0x3A07000A, PidTagGovernmentIdNumber_string8 = 0x3A07001E, PidTagHasAttachments = 0x0E1B000B, PidTagHasAttachments_Error = 0x0E1B000A, PidTagHasDeferredActionMessages = 0x3FEA000B, PidTagHasDeferredActionMessages_Error = 0x3FEA000A, PidTagHasNamedProperties = 0x664A000B, PidTagHasNamedProperties_Error = 0x664A000A, PidTagHasRules = 0x663A000B, PidTagHasRules_Error = 0x663A000A, PidTagHierarchyChangeNumber = 0x663E0003, PidTagHierarchyChangeNumber_Error = 0x663E000A, PidTagHobbies = 0x3A43001F, PidTagHobbies_Error = 0x3A43000A, PidTagHobbies_string8 = 0x3A43001E, PidTagHome2TelephoneNumber = 0x3A2F001F, PidTagHome2TelephoneNumber_Error = 0x3A2F000A, PidTagHome2TelephoneNumber_string8 = 0x3A2F001E, PidTagHome2TelephoneNumbers = 0x3A2F101F, PidTagHomeAddressCity = 0x3A59001F, PidTagHomeAddressCity_Error = 0x3A59000A, PidTagHomeAddressCity_string8 = 0x3A59001E, PidTagHomeAddressCountry = 0x3A5A001F, PidTagHomeAddressCountry_Error = 0x3A5A000A, PidTagHomeAddressCountry_string8 = 0x3A5A001E, PidTagHomeAddressPostOfficeBox = 0x3A5E001F, PidTagHomeAddressPostOfficeBox_Error = 0x3A5E000A, PidTagHomeAddressPostOfficeBox_string8 = 0x3A5E001E, PidTagHomeAddressPostalCode = 0x3A5B001F, PidTagHomeAddressPostalCode_Error = 0x3A5B000A, PidTagHomeAddressPostalCode_string8 = 0x3A5B001E, PidTagHomeAddressStateOrProvince = 0x3A5C001F, PidTagHomeAddressStateOrProvince_Error = 0x3A5C000A, PidTagHomeAddressStateOrProvince_string8 = 0x3A5C001E, PidTagHomeAddressStreet = 0x3A5D001F, PidTagHomeAddressStreet_Error = 0x3A5D000A, PidTagHomeAddressStreet_string8 = 0x3A5D001E, PidTagHomeFaxNumber = 0x3A25001F, PidTagHomeFaxNumber_Error = 0x3A25000A, PidTagHomeFaxNumber_string8 = 0x3A25001E, PidTagHomeTelephoneNumber = 0x3A09001F, PidTagHomeTelephoneNumber_Error = 0x3A09000A, PidTagHomeTelephoneNumber_string8 = 0x3A09001E, PidTagHtml = 0x10130102, PidTagICalendarEndTime = 0x10C40040, PidTagICalendarEndTime_Error = 0x10C4000A, PidTagICalendarReminderNextTime = 0x10CA0040, PidTagICalendarReminderNextTime_Error = 0x10CA000A, PidTagICalendarStartTime = 0x10C30040, PidTagICalendarStartTime_Error = 0x10C3000A, PidTagIconIndex = 0x10800003, PidTagIconIndex_Error = 0x1080000A, PidTagIdsetDeleted = 0x67E50102, PidTagIdsetDeleted_Error = 0x67E5000A, PidTagIdsetExpired = 0x67930102, PidTagIdsetExpired_Error = 0x6793000A, PidTagIdsetGiven = 0x40170003, PidTagIdsetGiven_Error = 0x4017000A, PidTagIdsetNoLongerInScope = 0x40210102, PidTagIdsetNoLongerInScope_Error = 0x4021000A, PidTagIdsetRead = 0x402D0102, PidTagIdsetRead_Error = 0x402D000A, PidTagIdsetUnread = 0x402E0102, PidTagIdsetUnread_Error = 0x402E000A, PidTagImapCachedMsgsize = 0x10F00102, PidTagImapCachedMsgsize_Error = 0x10F0000A, PidTagImportance = 0x00170003, PidTagImportance_Error = 0x0017000A, PidTagInConflict = 0x666C000B, PidTagInConflict_Error = 0x666C000A, PidTagInReplyToId = 0x1042001F, PidTagInReplyToId_Error = 0x1042000A, PidTagInReplyToId_string8 = 0x1042001E, PidTagIncrSyncChg = 0x40120003, PidTagIncrSyncChgPartial = 0x407D0003, PidTagIncrSyncChgPartial_Error = 0x407D000A, PidTagIncrSyncChg_Error = 0x4012000A, PidTagIncrSyncDel = 0x40130003, PidTagIncrSyncDel_Error = 0x4013000A, PidTagIncrSyncEnd = 0x40140003, PidTagIncrSyncEnd_Error = 0x4014000A, PidTagIncrSyncGroupId = 0x407C0003, PidTagIncrSyncGroupId_Error = 0x407C000A, PidTagIncrSyncGroupInfo = 0x407B0102, PidTagIncrSyncGroupInfo_Error = 0x407B000A, PidTagIncrSyncMessage = 0x40150003, PidTagIncrSyncMessage_Error = 0x4015000A, PidTagIncrSyncProgressMode = 0x4074000B, PidTagIncrSyncProgressMode_Error = 0x4074000A, PidTagIncrSyncProgressPerMsg = 0x4075000B, PidTagIncrSyncProgressPerMsg_Error = 0x4075000A, PidTagIncrSyncRead = 0x402F0003, PidTagIncrSyncRead_Error = 0x402F000A, PidTagIncrSyncStateBegin = 0x403A0003, PidTagIncrSyncStateBegin_Error = 0x403A000A, PidTagIncrSyncStateEnd = 0x403B0003, PidTagIncrSyncStateEnd_Error = 0x403B000A, PidTagIncrementalSyncMessagePartial = 0x407A0003, PidTagIncrementalSyncMessagePartial_Error = 0x407A000A, PidTagInitialDetailsPane = 0x3F080003, PidTagInitialDetailsPane_Error = 0x3F08000A, PidTagInitials = 0x3A0A001F, PidTagInitials_Error = 0x3A0A000A, PidTagInitials_string8 = 0x3A0A001E, PidTagInstID = 0x674D0014, PidTagInstID_Error = 0x674D000A, PidTagInstanceKey = 0x0FF60102, PidTagInstanceKey_Error = 0x0FF6000A, PidTagInstanceNum = 0x674E0003, PidTagInstanceNum_Error = 0x674E000A, PidTagInternetArticleNumber = 0x0E230003, PidTagInternetArticleNumber_Error = 0x0E23000A, PidTagInternetCodepage = 0x3FDE0003, PidTagInternetCodepage_Error = 0x3FDE000A, PidTagInternetMailOverrideFormat = 0x59020003, PidTagInternetMailOverrideFormat_Error = 0x5902000A, PidTagInternetMessageId = 0x1035001F, PidTagInternetMessageId_Error = 0x1035000A, PidTagInternetMessageId_string8 = 0x1035001E, PidTagInternetReferences = 0x1039001F, PidTagInternetReferences_Error = 0x1039000A, PidTagInternetReferences_string8 = 0x1039001E, PidTagIpmAppointmentEntryId = 0x36D00102, PidTagIpmAppointmentEntryId_Error = 0x36D0000A, PidTagIpmContactEntryId = 0x36D10102, PidTagIpmContactEntryId_Error = 0x36D1000A, PidTagIpmDraftsEntryId = 0x36D70102, PidTagIpmDraftsEntryId_Error = 0x36D7000A, PidTagIpmJournalEntryId = 0x36D20102, PidTagIpmJournalEntryId_Error = 0x36D2000A, PidTagIpmNoteEntryId = 0x36D30102, PidTagIpmNoteEntryId_Error = 0x36D3000A, PidTagIpmTaskEntryId = 0x36D40102, PidTagIpmTaskEntryId_Error = 0x36D4000A, PidTagIsdnNumber = 0x3A2D001F, PidTagIsdnNumber_Error = 0x3A2D000A, PidTagIsdnNumber_string8 = 0x3A2D001E, PidTagJunkAddRecipientsToSafeSendersList = 0x61030003, PidTagJunkAddRecipientsToSafeSendersList_Error = 0x6103000A, PidTagJunkIncludeContacts = 0x61000003, PidTagJunkIncludeContacts_Error = 0x6100000A, PidTagJunkPermanentlyDelete = 0x61020003, PidTagJunkPermanentlyDelete_Error = 0x6102000A, PidTagJunkPhishingEnableLinks = 0x6107000B, PidTagJunkPhishingEnableLinks_Error = 0x6107000A, PidTagJunkThreshold = 0x61010003, PidTagJunkThreshold_Error = 0x6101000A, PidTagKeyword = 0x3A0B001F, PidTagKeyword_Error = 0x3A0B000A, PidTagKeyword_string8 = 0x3A0B001E, PidTagLanguage = 0x3A0C001F, PidTagLanguage_Error = 0x3A0C000A, PidTagLanguage_string8 = 0x3A0C001E, PidTagLastModificationTime = 0x30080040, PidTagLastModificationTime_Error = 0x3008000A, PidTagLastModifierEntryId = 0x3FFB0102, PidTagLastModifierEntryId_Error = 0x3FFB000A, PidTagLastModifierName = 0x3FFA001F, PidTagLastModifierName_Error = 0x3FFA000A, PidTagLastModifierName_string8 = 0x3FFA001E, PidTagLastModifierSId = 0x0E590102, PidTagLastModifierSimpleDisplayName = 0x4039001F, PidTagLastModifierSimpleDisplayName_Error = 0x4039000A, PidTagLastModifierSimpleDisplayName_string8 = 0x4039001E, PidTagLastVerbExecuted = 0x10810003, PidTagLastVerbExecuted_Error = 0x1081000A, PidTagLastVerbExecutionTime = 0x10820040, PidTagLastVerbExecutionTime_Error = 0x1082000A, PidTagListHelp = 0x1043001F, PidTagListHelp_Error = 0x1043000A, PidTagListHelp_string8 = 0x1043001E, PidTagListSubscribe = 0x1044001F, PidTagListSubscribe_Error = 0x1044000A, PidTagListSubscribe_string8 = 0x1044001E, PidTagListUnsubscribe = 0x1045001F, PidTagListUnsubscribe_Error = 0x1045000A, PidTagListUnsubscribe_string8 = 0x1045001E, PidTagLocalCommitTime = 0x67090040, PidTagLocalCommitTime_Error = 0x6709000A, PidTagLocaleId = 0x66A10003, PidTagLocaleId_Error = 0x66A1000A, PidTagLocality = 0x3A27001F, PidTagLocality_Error = 0x3A27000A, PidTagLocality_string8 = 0x3A27001E, PidTagLocation = 0x3A0D001F, PidTagLocation_Error = 0x3A0D000A, PidTagLocation_string8 = 0x3A0D001E, PidTagMailboxOwnerEntryId = 0x661B0102, PidTagMailboxOwnerEntryId_Error = 0x661B000A, PidTagMailboxOwnerName = 0x661C001F, PidTagMailboxOwnerName_Error = 0x661C000A, PidTagMailboxOwnerName_string8 = 0x661C001E, PidTagManagerName = 0x3A4E001F, PidTagManagerName_Error = 0x3A4E000A, PidTagManagerName_string8 = 0x3A4E001E, PidTagMappingSignature = 0x0FF80102, PidTagMappingSignature_Error = 0x0FF8000A, PidTagMaximumSubmitMessageSize = 0x666D0003, PidTagMaximumSubmitMessageSize_Error = 0x666D000A, PidTagMemberId = 0x66710014, PidTagMemberId_Error = 0x6671000A, PidTagMemberName = 0x6672001F, PidTagMemberName_Error = 0x6672000A, PidTagMemberName_string8 = 0x6672001E, PidTagMemberRights = 0x66730003, PidTagMemberRights_Error = 0x6673000A, PidTagMessageAttachments = 0x0E13000D, PidTagMessageAttachments_Error = 0x0E13000A, PidTagMessageCcMe = 0x0058000B, PidTagMessageCcMe_Error = 0x0058000A, PidTagMessageClass = 0x001A001F, PidTagMessageClass_Error = 0x001A000A, PidTagMessageClass_string8 = 0x001A001E, PidTagMessageCodepage = 0x3FFD0003, PidTagMessageCodepage_Error = 0x3FFD000A, PidTagMessageDeliveryTime = 0x0E060040, PidTagMessageDeliveryTime_Error = 0x0E06000A, PidTagMessageEditorFormat = 0x59090003, PidTagMessageEditorFormat_Error = 0x5909000A, PidTagMessageFlags = 0x0E070003, PidTagMessageFlags_Error = 0x0E07000A, PidTagMessageHandlingSystemCommonName = 0x3A0F001F, PidTagMessageHandlingSystemCommonName_Error = 0x3A0F000A, PidTagMessageHandlingSystemCommonName_string8 = 0x3A0F001E, PidTagMessageLocaleId = 0x3FF10003, PidTagMessageLocaleId_Error = 0x3FF1000A, PidTagMessageRecipientMe = 0x0059000B, PidTagMessageRecipientMe_Error = 0x0059000A, PidTagMessageRecipients = 0x0E12000D, PidTagMessageRecipients_Error = 0x0E12000A, PidTagMessageSize = 0x0E080003, PidTagMessageSizeExtended = 0x0E080014, PidTagMessageSize_Error = 0x0E08000A, PidTagMessageStatus = 0x0E170003, PidTagMessageStatus_Error = 0x0E17000A, PidTagMessageSubmissionId = 0x00470102, PidTagMessageSubmissionId_Error = 0x0047000A, PidTagMessageToMe = 0x0057000B, PidTagMessageToMe_Error = 0x0057000A, PidTagMid = 0x674A0014, PidTagMid_Error = 0x674A000A, PidTagMiddleName = 0x3A44001F, PidTagMiddleName_Error = 0x3A44000A, PidTagMiddleName_string8 = 0x3A44001E, PidTagMimeSkeleton = 0x04700102, PidTagMimeSkeleton_Error = 0x0470000A, PidTagMobileTelephoneNumber = 0x3A1C001F, PidTagMobileTelephoneNumber_Error = 0x3A1C000A, PidTagMobileTelephoneNumber_string8 = 0x3A1C001E, PidTagNativeBody = 0x10160003, PidTagNativeBody_Error = 0x1016000A, PidTagNewAttach = 0x40000003, PidTagNewAttach_Error = 0x4000000A, PidTagNewFXFolder = 0x40110102, PidTagNewFXFolder_Error = 0x4011000A, PidTagNextSendAcct = 0x0E29001F, PidTagNextSendAcct_Error = 0x0E29000A, PidTagNextSendAcct_string8 = 0x0E29001E, PidTagNickname = 0x3A4F001F, PidTagNickname_Error = 0x3A4F000A, PidTagNickname_string8 = 0x3A4F001E, PidTagNormalMessageSize = 0x66B30003, PidTagNormalMessageSize_Error = 0x66B3000A, PidTagNormalizedSubject = 0x0E1D001F, PidTagNormalizedSubject_Error = 0x0E1D000A, PidTagNormalizedSubject_string8 = 0x0E1D001E, PidTagNTSDModificationTime = 0x3FD60040, PidTagObjectType = 0x0FFE0003, PidTagObjectType_Error = 0x0FFE000A, PidTagOfficeLocation = 0x3A19001F, PidTagOfficeLocation_Error = 0x3A19000A, PidTagOfficeLocation_string8 = 0x3A19001E, PidTagOfflineAddressBookCompressedSize = 0x68090003, PidTagOfflineAddressBookCompressedSize_Error = 0x6809000A, PidTagOfflineAddressBookContainerGuid = 0x6802001E, PidTagOfflineAddressBookContainerGuid_Error = 0x6802000A, PidTagOfflineAddressBookDistinguishedName = 0x6804001E, PidTagOfflineAddressBookFileSize = 0x680A0003, PidTagOfflineAddressBookFileSize_Error = 0x680A000A, PidTagOfflineAddressBookFileType = 0x68080003, PidTagOfflineAddressBookFileType_Error = 0x6808000A, PidTagOfflineAddressBookLanguageId = 0x68070003, PidTagOfflineAddressBookLanguageId_Error = 0x6807000A, PidTagOfflineAddressBookMessageClass = 0x68030003, PidTagOfflineAddressBookMessageClass_Error = 0x6803000A, PidTagOfflineAddressBookName = 0x6800001F, PidTagOfflineAddressBookName_Error = 0x6800000A, PidTagOfflineAddressBookName_string8 = 0x6800001E, PidTagOfflineAddressBookSequence = 0x68010003, PidTagOfflineAddressBookSequence_Error = 0x6801000A, PidTagOfflineAddressBookShaHash = 0x68060102, PidTagOfflineAddressBookTruncatedProperties = 0x68051003, PidTagOfflineAddressBookTruncatedProperties_Error = 0x6805000A, PidTagOrdinalMost = 0x36E20003, PidTagOrdinalMost_Error = 0x36E2000A, PidTagOrganizationalIdNumber = 0x3A10001F, PidTagOrganizationalIdNumber_Error = 0x3A10000A, PidTagOrganizationalIdNumber_string8 = 0x3A10001E, PidTagOriginalDeliveryTime = 0x00550040, PidTagOriginalDeliveryTime_Error = 0x0055000A, PidTagOriginalDisplayBcc = 0x0072001F, PidTagOriginalDisplayBcc_Error = 0x0072000A, PidTagOriginalDisplayBcc_string8 = 0x0072001E, PidTagOriginalDisplayCc = 0x0073001F, PidTagOriginalDisplayCc_Error = 0x0073000A, PidTagOriginalDisplayCc_string8 = 0x0073001E, PidTagOriginalDisplayName = 0x3A13001F, PidTagOriginalDisplayName_Error = 0x3A13000A, PidTagOriginalDisplayName_string8 = 0x3A13001E, PidTagOriginalDisplayTo = 0x0074001F, PidTagOriginalDisplayTo_Error = 0x0074000A, PidTagOriginalDisplayTo_string8 = 0x0074001E, PidTagOriginalEntryId = 0x3A120102, PidTagOriginalEntryId_Error = 0x3A12000A, PidTagOriginalMessageClass = 0x004B001F, PidTagOriginalMessageClass_Error = 0x004B000A, PidTagOriginalMessageClass_string8 = 0x004B001E, PidTagOriginalMessageId = 0x1046001F, PidTagOriginalMessageId_Error = 0x1046000A, PidTagOriginalMessageId_string8 = 0x1046001E, PidTagOriginalSearchKey = 0x3A140102, PidTagOriginalSearchKey_Error = 0x3A14000A, PidTagOriginalSenderAddressType = 0x0066001F, PidTagOriginalSenderAddressType_Error = 0x0066000A, PidTagOriginalSenderAddressType_string8 = 0x0066001E, PidTagOriginalSenderEmailAddress = 0x0067001F, PidTagOriginalSenderEmailAddress_Error = 0x0067000A, PidTagOriginalSenderEmailAddress_string8 = 0x0067001E, PidTagOriginalSenderEntryId = 0x005B0102, PidTagOriginalSenderEntryId_Error = 0x005B000A, PidTagOriginalSenderName = 0x005A001F, PidTagOriginalSenderName_Error = 0x005A000A, PidTagOriginalSenderName_string8 = 0x005A001E, PidTagOriginalSenderSearchKey = 0x005C0102, PidTagOriginalSenderSearchKey_Error = 0x005C000A, PidTagOriginalSensitivity = 0x002E0003, PidTagOriginalSensitivity_Error = 0x002E000A, PidTagOriginalSentRepresentingAddressType = 0x0068001F, PidTagOriginalSentRepresentingAddressType_Error = 0x0068000A, PidTagOriginalSentRepresentingAddressType_string8 = 0x0068001E, PidTagOriginalSentRepresentingEmailAddress = 0x0069001F, PidTagOriginalSentRepresentingEmailAddress_Error = 0x0069000A, PidTagOriginalSentRepresentingEmailAddress_string8 = 0x0069001E, PidTagOriginalSentRepresentingEntryId = 0x005E0102, PidTagOriginalSentRepresentingEntryId_Error = 0x005E000A, PidTagOriginalSentRepresentingName = 0x005D001F, PidTagOriginalSentRepresentingName_Error = 0x005D000A, PidTagOriginalSentRepresentingName_string8 = 0x005D001E, PidTagOriginalSentRepresentingSearchKey = 0x005F0102, PidTagOriginalSentRepresentingSearchKey_Error = 0x005F000A, PidTagOriginalSubject = 0x0049001F, PidTagOriginalSubject_Error = 0x0049000A, PidTagOriginalSubject_string8 = 0x0049001E, PidTagOriginalSubmitTime = 0x004E0040, PidTagOriginalSubmitTime_Error = 0x004E000A, PidTagOriginatorDeliveryReportRequested = 0x0023000B, PidTagOriginatorDeliveryReportRequested_Error = 0x0023000A, PidTagOriginatorNonDeliveryReportRequested = 0x0C08000B, PidTagOriginatorNonDeliveryReportRequested_Error = 0x0C08000A, PidTagOstOstId = 0x7C040102, PidTagOtherAddressCity = 0x3A5F001F, PidTagOtherAddressCity_Error = 0x3A5F000A, PidTagOtherAddressCity_string8 = 0x3A5F001E, PidTagOtherAddressCountry = 0x3A60001F, PidTagOtherAddressCountry_Error = 0x3A60000A, PidTagOtherAddressCountry_string8 = 0x3A60001E, PidTagOtherAddressPostOfficeBox = 0x3A64001F, PidTagOtherAddressPostOfficeBox_Error = 0x3A64000A, PidTagOtherAddressPostOfficeBox_string8 = 0x3A64001E, PidTagOtherAddressPostalCode = 0x3A61001F, PidTagOtherAddressPostalCode_Error = 0x3A61000A, PidTagOtherAddressPostalCode_string8 = 0x3A61001E, PidTagOtherAddressStateOrProvince = 0x3A62001F, PidTagOtherAddressStateOrProvince_Error = 0x3A62000A, PidTagOtherAddressStateOrProvince_string8 = 0x3A62001E, PidTagOtherAddressStreet = 0x3A63001F, PidTagOtherAddressStreet_Error = 0x3A63000A, PidTagOtherAddressStreet_string8 = 0x3A63001E, PidTagOtherTelephoneNumber = 0x3A1F001F, PidTagOtherTelephoneNumber_Error = 0x3A1F000A, PidTagOtherTelephoneNumber_string8 = 0x3A1F001E, PidTagOutOfOfficeState = 0x661D000B, PidTagOutOfOfficeState_Error = 0x661D000A, PidTagOwnerAppointmentId = 0x00620003, PidTagOwnerAppointmentId_Error = 0x0062000A, PidTagPagerTelephoneNumber = 0x3A21001F, PidTagPagerTelephoneNumber_Error = 0x3A21000A, PidTagPagerTelephoneNumber_string8 = 0x3A21001E, PidTagParentEntryId = 0x0E090102, PidTagParentEntryId_Error = 0x0E09000A, PidTagParentFolderId = 0x67490014, PidTagParentFolderId_Error = 0x6749000A, PidTagParentKey = 0x00250102, PidTagParentKey_Error = 0x0025000A, PidTagParentSourceKey = 0x65E10102, PidTagParentSourceKey_Error = 0x65E1000A, PidTagPersonalHomePage = 0x3A50001F, PidTagPersonalHomePage_Error = 0x3A50000A, PidTagPersonalHomePage_string8 = 0x3A50001E, PidTagPolicyTag = 0x30190102, PidTagPolicyTag_Error = 0x3019000A, PidTagPostOfficeBox = 0x3A2B001F, PidTagPostOfficeBox_Error = 0x3A2B000A, PidTagPostOfficeBox_string8 = 0x3A2B001E, PidTagPostalAddress = 0x3A15001F, PidTagPostalAddress_Error = 0x3A15000A, PidTagPostalAddress_string8 = 0x3A15001E, PidTagPostalCode = 0x3A2A001F, PidTagPostalCode_Error = 0x3A2A000A, PidTagPostalCode_string8 = 0x3A2A001E, PidTagPredecessorChangeList = 0x65E30102, PidTagPredecessorChangeList_Error = 0x65E3000A, PidTagPrimaryFaxNumber = 0x3A23001F, PidTagPrimaryFaxNumber_Error = 0x3A23000A, PidTagPrimaryFaxNumber_string8 = 0x3A23001E, PidTagPrimarySendAccount = 0x0E28001F, PidTagPrimarySendAccount_Error = 0x0E28000A, PidTagPrimarySendAccount_string8 = 0x0E28001E, PidTagPrimarySmtpAddress = 0x39FE001F, PidTagPrimarySmtpAddress_Error = 0x39FE000A, PidTagPrimarySmtpAddress_string8 = 0x39FE001E, PidTagPrimaryTelephoneNumber = 0x3A1A001F, PidTagPrimaryTelephoneNumber_Error = 0x3A1A000A, PidTagPrimaryTelephoneNumber_string8 = 0x3A1A001E, PidTagPriority = 0x00260003, PidTagPriority_Error = 0x0026000A, PidTagProcessed = 0x7D01000B, PidTagProcessed_Error = 0x7D01000A, PidTagProfession = 0x3A46001F, PidTagProfession_Error = 0x3A46000A, PidTagProfession_string8 = 0x3A46001E, PidTagProhibitReceiveQuota = 0x666A0003, PidTagProhibitReceiveQuota_Error = 0x666A000A, PidTagProhibitSendQuota = 0x666E0003, PidTagProhibitSendQuota_Error = 0x666E000A, PidTagProviderSubmitTime = 0x00480040, PidTagProviderSubmitTime_Error = 0x0048000A, PidTagPublicFolderAdministrativeDescription = 0x671C001F, PidTagPublicFolderAdministrativeDescription_Error = 0x671C000A, PidTagPublicFolderAdministrativeDescription_string8 = 0x671C001E, PidTagPublicFolderProxy = 0x671D0102, PidTagPublicFolderProxy_Error = 0x671D000A, PidTagPurportedSenderDomain = 0x4083001F, PidTagPurportedSenderDomain_Error = 0x4083000A, PidTagPurportedSenderDomain_string8 = 0x4083001E, PidTagRadioTelephoneNumber = 0x3A1D001F, PidTagRadioTelephoneNumber_Error = 0x3A1D000A, PidTagRadioTelephoneNumber_string8 = 0x3A1D001E, PidTagRead = 0x0E69000B, PidTagReadReceiptAddressType = 0x4029001F, PidTagReadReceiptAddressType_Error = 0x4029000A, PidTagReadReceiptAddressType_string8 = 0x4029001E, PidTagReadReceiptEmailAddress = 0x402A001F, PidTagReadReceiptEmailAddress_Error = 0x402A000A, PidTagReadReceiptEmailAddress_string8 = 0x402A001E, PidTagReadReceiptEntryId = 0x00460102, PidTagReadReceiptEntryId_Error = 0x0046000A, PidTagReadReceiptName = 0x402B001F, PidTagReadReceiptName_Error = 0x402B000A, PidTagReadReceiptName_string8 = 0x402B001E, PidTagReadReceiptRequested = 0x0029000B, PidTagReadReceiptRequested_Error = 0x0029000A, PidTagReadReceiptSearchKey = 0x00530102, PidTagReadReceiptSearchKey_Error = 0x0053000A, PidTagRead_Error = 0x0E69000A, PidTagReceivedByAddressType = 0x0075001F, PidTagReceivedByAddressType_Error = 0x0075000A, PidTagReceivedByAddressType_string8 = 0x0075001E, PidTagReceivedByEmailAddress = 0x0076001F, PidTagReceivedByEmailAddress_Error = 0x0076000A, PidTagReceivedByEmailAddress_string8 = 0x0076001E, PidTagReceivedByEntryId = 0x003F0102, PidTagReceivedByEntryId_Error = 0x003F000A, PidTagReceivedByFlags = 0x401B0003, PidTagReceivedByFlags_Error = 0x401B000A, PidTagReceivedByName = 0x0040001F, PidTagReceivedByName_Error = 0x0040000A, PidTagReceivedByName_string8 = 0x0040001E, PidTagReceivedBySearchKey = 0x00510102, PidTagReceivedBySearchKey_Error = 0x0051000A, PidTagReceivedRepresentingAddressType = 0x0077001F, PidTagReceivedRepresentingAddressType_Error = 0x0077000A, PidTagReceivedRepresentingAddressType_string8 = 0x0077001E, PidTagReceivedRepresentingEmailAddress = 0x0078001F, PidTagReceivedRepresentingEmailAddress_Error = 0x0078000A, PidTagReceivedRepresentingEmailAddress_string8 = 0x0078001E, PidTagReceivedRepresentingEntryId = 0x00430102, PidTagReceivedRepresentingEntryId_Error = 0x0043000A, PidTagReceivedRepresentingFlags = 0x401C0003, PidTagReceivedRepresentingFlags_Error = 0x401C000A, PidTagReceivedRepresentingName = 0x0044001F, PidTagReceivedRepresentingName_Error = 0x0044000A, PidTagReceivedRepresentingName_string8 = 0x0044001E, PidTagReceivedRepresentingSearchKey = 0x00520102, PidTagReceivedRepresentingSearchKey_Error = 0x0052000A, PidTagReceivedRepresentingSimpleDisplayName = 0x4035001F, PidTagReceivedRepresentingSimpleDisplayName_Error = 0x4035000A, PidTagReceivedRepresentingSimpleDisplayName_string8 = 0x4035001E, PidTagRecipientDisplayName = 0x5FF6001F, PidTagRecipientDisplayName_Error = 0x5FF6000A, PidTagRecipientDisplayName_string8 = 0x5FF6001E, PidTagRecipientEntryId = 0x5FF70102, PidTagRecipientEntryId_Error = 0x5FF7000A, PidTagRecipientFlags = 0x5FFD0003, PidTagRecipientFlags_Error = 0x5FFD000A, PidTagRecipientOrder = 0x5FDF0003, PidTagRecipientOrder_Error = 0x5FDF000A, PidTagRecipientProposed = 0x5FE1000B, PidTagRecipientProposedEndTime = 0x5FE40040, PidTagRecipientProposedEndTime_Error = 0x5FE4000A, PidTagRecipientProposedStartTime = 0x5FE30040, PidTagRecipientProposedStartTime_Error = 0x5FE3000A, PidTagRecipientProposed_Error = 0x5FE1000A, PidTagRecipientReassignmentProhibited = 0x002B000B, PidTagRecipientReassignmentProhibited_Error = 0x002B000A, PidTagRecipientResourceState = 0x5FDE0003, PidTagRecipientResourceState_Error = 0x5FDE000A, PidTagRecipientTrackStatus = 0x5FFF0003, PidTagRecipientTrackStatusTime = 0x5FFB0040, PidTagRecipientTrackStatusTime_Error = 0x5FFB000A, PidTagRecipientTrackStatus_Error = 0x5FFF000A, PidTagRecipientType = 0x0C150003, PidTagRecipientType_Error = 0x0C15000A, PidTagRecordKey = 0x0FF90102, PidTagRecordKey_Error = 0x0FF9000A, PidTagReferredByName = 0x3A47001F, PidTagReferredByName_Error = 0x3A47000A, PidTagReferredByName_string8 = 0x3A47001E, PidTagRemindersOnlineEntryId = 0x36D50102, PidTagRemindersOnlineEntryId_Error = 0x36D5000A, PidTagRemindersOfflineEntryId = 0x36D60102, PidTagRemindersOfflineEntryId_Error = 0x36D6000A, PidTagRemoteMessageTransferAgent = 0x0C21001F, PidTagRemoteMessageTransferAgent_Error = 0x0C21000A, PidTagRemoteMessageTransferAgent_string8 = 0x0C21001E, PidTagRenderingPosition = 0x370B0003, PidTagRenderingPosition_Error = 0x370B000A, PidTagReplyRecipientEntries = 0x004F0102, PidTagReplyRecipientEntries_Error = 0x004F000A, PidTagReplyRecipientNames = 0x0050001F, PidTagReplyRecipientNames_Error = 0x0050000A, PidTagReplyRecipientNames_string8 = 0x0050001E, PidTagReplyRequested = 0x0C17000B, PidTagReplyRequested_Error = 0x0C17000A, PidTagReplyTemplateId = 0x65C20102, PidTagReplyTemplateId_Error = 0x65C2000A, PidTagReplyTime = 0x00300040, PidTagReplyTime_Error = 0x0030000A, PidTagReportEntryId = 0x00450102, PidTagReportEntryId_Error = 0x0045000A, PidTagReportName = 0x003A001F, PidTagReportName_Error = 0x003A000A, PidTagReportName_string8 = 0x003A001E, PidTagReportSearchKey = 0x00540102, PidTagReportSearchKey_Error = 0x0054000A, PidTagReportTag = 0x00310102, PidTagReportTag_Error = 0x0031000A, PidTagReportText = 0x1001001F, PidTagReportText_Error = 0x1001000A, PidTagReportText_string8 = 0x1001001E, PidTagReportTime = 0x00320040, PidTagReportTime_Error = 0x0032000A, PidTagReportingMessageTransferAgent = 0x6820001F, PidTagReportingMessageTransferAgent_Error = 0x6820000A, PidTagReportingMessageTransferAgent_string8 = 0x6820001E, PidTagResolveMethod = 0x3FE70003, PidTagResolveMethod_Error = 0x3FE7000A, PidTagResponseRequested = 0x0063000B, PidTagResponseRequested_Error = 0x0063000A, PidTagResponsibility = 0x0E0F000B, PidTagResponsibility_Error = 0x0E0F000A, PidTagRetentionDate = 0x301C0040, PidTagRetentionDate_Error = 0x301C000A, PidTagRetentionFlags = 0x301D0003, PidTagRetentionFlags_Error = 0x301D000A, PidTagRetentionPeriod = 0x301A0003, PidTagRetentionPeriod_Error = 0x301A000A, PidTagRights = 0x66390003, PidTagRights_Error = 0x6639000A, PidTagRoamingDatatypes = 0x7C060003, PidTagRoamingDatatypes_Error = 0x7C06000A, PidTagRoamingDictionary = 0x7C070102, PidTagRoamingDictionary_Error = 0x7C07000A, PidTagRoamingXmlStream = 0x7C080102, PidTagRoamingXmlStream_Error = 0x7C08000A, PidTagRowType = 0x0FF50003, PidTagRowType_Error = 0x0FF5000A, PidTagRowid = 0x30000003, PidTagRowid_Error = 0x3000000A, PidTagRtfCompressed = 0x10090102, PidTagRtfCompressed_Error = 0x1009000A, PidTagRtfInSync = 0x0E1F000B, PidTagRtfInSync_Error = 0x0E1F000A, PidTagRtfSyncBodyCount = 0x10070003, PidTagRtfSyncBodyCount_Error = 0x1007000A, PidTagRtfSyncBodyCrc = 0x10060003, PidTagRtfSyncBodyCrc_Error = 0x1006000A, PidTagRtfSyncBodyTag = 0x1008001F, PidTagRtfSyncBodyTag_Error = 0x1008000A, PidTagRtfSyncBodyTag_string8 = 0x1008001E, PidTagRtfSyncPrefixCount = 0x10100003, PidTagRtfSyncPrefixCount_Error = 0x1010000A, PidTagRtfSyncTrailingCount = 0x10110003, PidTagRtfSyncTrailingCount_Error = 0x1011000A, PidTagRuleActionNumber = 0x66500003, PidTagRuleActionNumber_Error = 0x6650000A, PidTagRuleActionType = 0x66490003, PidTagRuleActionType_Error = 0x6649000A, PidTagRuleActions = 0x668000FE, PidTagRuleActions_Error = 0x6680000A, PidTagRuleCondition = 0x667900FD, PidTagRuleCondition_Error = 0x6679000A, PidTagRuleError = 0x66480003, PidTagRuleError_Error = 0x6648000A, PidTagRuleFolderEntryId = 0x66510102, PidTagRuleFolderEntryId_Error = 0x6651000A, PidTagRuleId = 0x66740014, PidTagRuleId_Error = 0x6674000A, PidTagRuleIds = 0x66750102, PidTagRuleIds_Error = 0x6675000A, PidTagRuleLevel = 0x66830003, PidTagRuleLevel_Error = 0x6683000A, PidTagRuleMessageLevel = 0x65ED0003, PidTagRuleMessageLevel_Error = 0x65ED000A, PidTagRuleMessageName = 0x65EC001F, PidTagRuleMessageName_Error = 0x65EC000A, PidTagRuleMessageName_string8 = 0x65EC001E, PidTagRuleMessageProvider = 0x65EB001F, PidTagRuleMessageProviderData = 0x65EE0102, PidTagRuleMessageProviderData_Error = 0x65EE000A, PidTagRuleMessageProvider_Error = 0x65EB000A, PidTagRuleMessageProvider_string8 = 0x65EB001E, PidTagRuleMessageSequence = 0x65F30003, PidTagRuleMessageSequence_Error = 0x65F3000A, PidTagRuleMessageState = 0x65E90003, PidTagRuleMessageState_Error = 0x65E9000A, PidTagRuleMessageUserFlags = 0x65EA0003, PidTagRuleMessageUserFlags_Error = 0x65EA000A, PidTagRuleName = 0x6682001F, PidTagRuleName_Error = 0x6682000A, PidTagRuleName_string8 = 0x6682001E, PidTagRuleProvider = 0x6681001F, PidTagRuleProviderData = 0x66840102, PidTagRuleProviderData_Error = 0x6684000A, PidTagRuleProvider_Error = 0x6681000A, PidTagRuleProvider_string8 = 0x6681001E, PidTagRuleSequence = 0x66760003, PidTagRuleSequence_Error = 0x6676000A, PidTagRuleState = 0x66770003, PidTagRuleState_Error = 0x6677000A, PidTagRuleUserFlags = 0x66780003, PidTagRuleUserFlags_Error = 0x6678000A, PidTagRwRulesStream = 0x68020102, PidTagScheduleInfoAppointmentTombstone = 0x686A0102, PidTagScheduleInfoAppointmentTombstone_Error = 0x686A000A, PidTagScheduleInfoAutoAcceptAppointments = 0x686D000B, PidTagScheduleInfoAutoAcceptAppointments_Error = 0x686D000A, PidTagScheduleInfoDelegateEntryIds = 0x68451102, PidTagScheduleInfoDelegateEntryIds_Error = 0x6845000A, PidTagScheduleInfoDelegateNames = 0x6844101F, PidTagScheduleInfoDelegateNamesW = 0x684A101F, PidTagScheduleInfoDelegateNamesW_Error = 0x684A000A, PidTagScheduleInfoDelegateNames_Error = 0x6844000A, PidTagScheduleInfoDelegatorWantsCopy = 0x6842000B, PidTagScheduleInfoDelegatorWantsCopy_Error = 0x6842000A, PidTagScheduleInfoDelegatorWantsInfo = 0x684B000B, PidTagScheduleInfoDelegatorWantsInfo_Error = 0x684B000A, PidTagScheduleInfoDisallowOverlappingAppts = 0x686F000B, PidTagScheduleInfoDisallowOverlappingAppts_Error = 0x686F000A, PidTagScheduleInfoDisallowRecurringAppts = 0x686E000B, PidTagScheduleInfoDisallowRecurringAppts_Error = 0x686E000A, PidTagScheduleInfoDontMailDelegates = 0x6843000B, PidTagScheduleInfoDontMailDelegates_Error = 0x6843000A, PidTagScheduleInfoFreeBusy = 0x686C0102, PidTagScheduleInfoFreeBusyAway = 0x68561102, PidTagScheduleInfoFreeBusyAway_Error = 0x6856000A, PidTagScheduleInfoFreeBusyBusy = 0x68541102, PidTagScheduleInfoFreeBusyBusy_Error = 0x6854000A, PidTagScheduleInfoFreeBusyMerged = 0x68501102, PidTagScheduleInfoFreeBusyMerged_Error = 0x6850000A, PidTagScheduleInfoFreeBusyTentative = 0x68521102, PidTagScheduleInfoFreeBusyTentative_Error = 0x6852000A, PidTagScheduleInfoFreeBusy_Error = 0x686C000A, PidTagScheduleInfoMonthsAway = 0x68551003, PidTagScheduleInfoMonthsAway_Error = 0x6855000A, PidTagScheduleInfoMonthsBusy = 0x68531003, PidTagScheduleInfoMonthsBusy_Error = 0x6853000A, PidTagScheduleInfoMonthsMerged = 0x684F1003, PidTagScheduleInfoMonthsMerged_Error = 0x684F000A, PidTagScheduleInfoMonthsTentative = 0x68511003, PidTagScheduleInfoMonthsTentative_Error = 0x6851000A, PidTagScheduleInfoResourceType = 0x68410003, PidTagScheduleInfoResourceType_Error = 0x6841000A, PidTagSchedulePlusFreeBusyEntryId = 0x66220102, PidTagSchedulePlusFreeBusyEntryId_Error = 0x6622000A, PidTagScriptData = 0x00040102, PidTagSearchFolderDefinition = 0x68450102, PidTagSearchFolderExpiration = 0x683A0003, PidTagSearchFolderExpiration_Error = 0x683A000A, PidTagSearchFolderId = 0x68420102, PidTagSearchFolderLastUsed = 0x68340003, PidTagSearchFolderLastUsed_Error = 0x6834000A, PidTagSearchFolderRecreateInfo = 0x68440102, PidTagSearchFolderStorageType = 0x68460003, PidTagSearchKey = 0x300B0102, PidTagSearchKey_Error = 0x300B000A, PidTagSecureOrigination = 0x3fe5000b, PidTagSecureSubmitFlags = 0x65C60003, PidTagSecureSubmitFlags_Error = 0x65C6000A, PidTagSecurityDescriptor = 0x0E270102, PidTagSecurityDescriptorAsXml = 0x0E6A001F, PidTagSecurityDescriptorAsXml_Error = 0x0E6A000A, PidTagSecurityDescriptorAsXml_string8 = 0x0E6A001E, PidTagSecurityDescriptor_Error = 0x0E27000A, PidTagSelectable = 0x3609000B, PidTagSelectable_Error = 0x3609000A, PidTagSendInternetEncoding = 0x3A710003, PidTagSendInternetEncoding_Error = 0x3A71000A, PidTagSendRichInfo = 0x3A40000B, PidTagSendRichInfo_Error = 0x3A40000A, PidTagSenderAddressType = 0x0C1E001F, PidTagSenderAddressType_Error = 0x0C1E000A, PidTagSenderAddressType_string8 = 0x0C1E001E, PidTagSenderEmailAddress = 0x0C1F001F, PidTagSenderEmailAddress_Error = 0x0C1F000A, PidTagSenderEmailAddress_string8 = 0x0C1F001E, PidTagSenderEntryId = 0x0C190102, PidTagSenderEntryId_Error = 0x0C19000A, PidTagSenderFlags = 0x40190003, PidTagSenderFlags_Error = 0x4019000A, PidTagSenderIdStatus = 0x40790003, PidTagSenderIdStatus_Error = 0x4079000A, PidTagSenderName = 0x0C1A001F, PidTagSenderName_Error = 0x0C1A000A, PidTagSenderName_string8 = 0x0C1A001E, PidTagSenderSearchKey = 0x0C1D0102, PidTagSenderSearchKey_Error = 0x0C1D000A, PidTagSenderSimpleDisplayName = 0x4030001F, PidTagSenderSimpleDisplayName_Error = 0x4030000A, PidTagSenderSimpleDisplayName_string8 = 0x4030001E, PidTagSenderSmtpAddress = 0x5D01001F, PidTagSenderSmtpAddress_Error = 0x5D01000A, PidTagSenderSmtpAddress_string8 = 0x5D01001E, PidTagSenderTelephoneNumber = 0x6802001F, PidTagSensitivity = 0x00360003, PidTagSensitivity_Error = 0x0036000A, PidTagSentMailSvrEID = 0x674000FB, PidTagSentMailSvrEID_Error = 0x6740000A, PidTagSentRepresentingAddressType = 0x0064001F, PidTagSentRepresentingAddressType_Error = 0x0064000A, PidTagSentRepresentingAddressType_string8 = 0x0064001E, PidTagSentRepresentingEmailAddress = 0x0065001F, PidTagSentRepresentingEmailAddress_Error = 0x0065000A, PidTagSentRepresentingEmailAddress_string8 = 0x0065001E, PidTagSentRepresentingEntryId = 0x00410102, PidTagSentRepresentingEntryId_Error = 0x0041000A, PidTagSentRepresentingFlags = 0x401A0003, PidTagSentRepresentingFlags_Error = 0x401A000A, PidTagSentRepresentingName = 0x0042001F, PidTagSentRepresentingName_Error = 0x0042000A, PidTagSentRepresentingName_string8 = 0x0042001E, PidTagSentRepresentingSearchKey = 0x003B0102, PidTagSentRepresentingSearchKey_Error = 0x003B000A, PidTagSentRepresentingSimpleDisplayName = 0x4031001F, PidTagSentRepresentingSimpleDisplayName_Error = 0x4031000A, PidTagSentRepresentingSimpleDisplayName_string8 = 0x4031001E, PidTagSessionInitiationProtocolUri = 0x5FE5001F, PidTagSessionInitiationProtocolUri_Error = 0x5FE5000A, PidTagSessionInitiationProtocolUri_string8 = 0x5FE5001E, PidTagShorttermEntryIdFromObject = 0x66720102, PidTagSortLocaleId = 0x67050003, PidTagSortLocaleId_Error = 0x6705000A, PidTagSourceKey = 0x65E00102, PidTagSourceKey_Error = 0x65E0000A, PidTagSpokenName = 0x8CC20102, PidTagSpokenName_Error = 0x8CC2000A, PidTagSpouseName = 0x3A48001F, PidTagSpouseName_Error = 0x3A48000A, PidTagSpouseName_string8 = 0x3A48001E, PidTagStartDate = 0x00600040, PidTagStartDateEtc = 0x301B0102, PidTagStartDateEtc_Error = 0x301B000A, PidTagStartDate_Error = 0x0060000A, PidTagStartEmbed = 0x40010003, PidTagStartEmbed_Error = 0x4001000A, PidTagStartFAIMsg = 0x40100003, PidTagStartFAIMsg_Error = 0x4010000A, PidTagStartMessage = 0x400C0003, PidTagStartMessage_Error = 0x400C000A, PidTagStartRecip = 0x40030003, PidTagStartRecip_Error = 0x4003000A, PidTagStartSubFld = 0x400A0003, PidTagStartSubFld_Error = 0x400A000A, PidTagStartTopFld = 0x40090003, PidTagStartTopFld_Error = 0x4009000A, PidTagStateOrProvince = 0x3A28001F, PidTagStateOrProvince_Error = 0x3A28000A, PidTagStateOrProvince_string8 = 0x3A28001E, PidTagStorageQuotaLimit = 0x3FF50003, PidTagStorageQuotaLimit_Error = 0x3FF5000A, PidTagStoreEntryId = 0x0FFB0102, PidTagStoreEntryId_Error = 0x0FFB000A, PidTagStoreState = 0x340E0003, PidTagStoreState_Error = 0x340E000A, PidTagStoreSupportMask = 0x340D0003, PidTagStoreSupportMask_Error = 0x340D000A, PidTagStreetAddress = 0x3A29001F, PidTagStreetAddress_Error = 0x3A29000A, PidTagStreetAddress_string8 = 0x3A29001E, PidTagSubfolder = 0x6708000B, PidTagSubfolder_Error = 0x6708000A, PidTagSubfolders = 0x360A000B, PidTagSubfolders_Error = 0x360A000A, PidTagSubject = 0x0037001F, PidTagSubjectPrefix = 0x003D001F, PidTagSubjectPrefix_Error = 0x003D000A, PidTagSubjectPrefix_string8 = 0x003D001E, PidTagSubject_Error = 0x0037000A, PidTagSubject_string8 = 0x0037001E, PidTagSurname = 0x3A11001F, PidTagSurname_Error = 0x3A11000A, PidTagSurname_string8 = 0x3A11001E, PidTagSwappedToDoData = 0x0E2D0102, PidTagSwappedToDoData_Error = 0x0E2D000A, PidTagSwappedToDoStore = 0x0E2C0102, PidTagSwappedToDoStore_Error = 0x0E2C000A, PidTagTargetEntryId = 0x30100102, PidTagTargetEntryId_Error = 0x3010000A, PidTagTcvConstLongOne = 0x80080003, PidTagTelecommunicationsDeviceForDeafTelephoneNumber = 0x3A4B001F, PidTagTelecommunicationsDeviceForDeafTelephoneNumber_Error = 0x3A4B000A, PidTagTelecommunicationsDeviceForDeafTelephoneNumber_string8 = 0x3A4B001E, PidTagTelexNumber = 0x3A2C001F, PidTagTelexNumber_Error = 0x3A2C000A, PidTagTelexNumber_string8 = 0x3A2C001E, PidTagTemplateData = 0x00010102, PidTagTemplateData_Error = 0x0001000A, PidTagTemplateid = 0x39020102, PidTagTemplateid_Error = 0x3902000A, PidTagTemporaryDefaultDocument = 0x3F20001F, PidTagTemporaryDefaultDocument_Error = 0x3F20000A, PidTagTemporaryDefaultDocument_string8 = 0x3F20001E, PidTagTextAttachmentCharset = 0x371B001F, PidTagTextAttachmentCharset_Error = 0x371B000A, PidTagTextAttachmentCharset_string8 = 0x371B001E, PidTagThumbnailPhoto = 0x8C9E0102, PidTagThumbnailPhoto_Error = 0x8C9E000A, PidTagTitle = 0x3A17001F, PidTagTitle_Error = 0x3A17000A, PidTagTitle_string8 = 0x3A17001E, PidTagTnefCorrelationKey = 0x007F0102, PidTagTnefCorrelationKey_Error = 0x007F000A, PidTagToDoItemFlags = 0x0E2B0003, PidTagToDoItemFlags_Error = 0x0E2B000A, PidTagTransmittableDisplayName = 0x3A20001F, PidTagTransmittableDisplayName_Error = 0x3A20000A, PidTagTransmittableDisplayName_string8 = 0x3A20001E, PidTagTransportMessageHeaders = 0x007D001F, PidTagTransportMessageHeaders_Error = 0x007D000A, PidTagTransportMessageHeaders_string8 = 0x007D001E, PidTagTrustSender = 0x0E790003, PidTagTrustSender_Error = 0x0E79000A, PidTagUrlCompName = 0x10F3001F, PidTagUrlCompNameSet = 0x0E62000B, PidTagUrlCompNameSet_Error = 0x0E62000A, PidTagUrlCompName_Error = 0x10F3000A, PidTagUrlCompName_string8 = 0x10F3001E, PidTagUrlName = 0x6707001F, PidTagUrlName_Error = 0x6707000A, PidTagUrlName_string8 = 0x6707001E, PidTagUserCertificate = 0x3A220102, PidTagUserCertificate_Error = 0x3A22000A, PidTagUserEntryId = 0x66190102, PidTagUserEntryId_Error = 0x6619000A, PidTagUserX509Certificate = 0x3A701102, PidTagUserX509Certificate_Error = 0x3A70000A, PidTagViewDescriptorBinary = 0x70010102, PidTagViewDescriptorBinary_Error = 0x7001000A, PidTagViewDescriptorName = 0x7006001F, PidTagViewDescriptorName_Error = 0x7006000A, PidTagViewDescriptorName_string8 = 0x7006001E, PidTagViewDescriptorStrings = 0x7002001F, PidTagViewDescriptorStrings_Error = 0x7002000A, PidTagViewDescriptorStrings_string8 = 0x7002001E, PidTagViewDescriptorVersion = 0x70070003, PidTagViewDescriptorVersion_Error = 0x7007000A, PidTagVoiceMessageAttachmentOrder = 0x6805001F, PidTagVoiceMessageSenderName = 0x6803001F, PidTagWeddingAnniversary = 0x3A410040, PidTagWeddingAnniversary_Error = 0x3A41000A, PidTagWlinkAddressBookEID = 0x68540102, PidTagWlinkAddressBookStoreEID = 0x68910102, PidTagWlinkAddressBookStoreEID_Error = 0x6891000A, PidTagWlinkCalendarColor = 0x68530003, PidTagWlinkClientID = 0x68900048, PidTagWlinkClientID_Error = 0x6890000A, PidTagWlinkEntryId = 0x684C0102, PidTagWlinkEntryId_Error = 0x684C000A, PidTagWlinkFlags = 0x684A0003, PidTagWlinkFolderType = 0x684F0048, PidTagWlinkGroupClsid = 0x68500048, PidTagWlinkGroupHeaderID = 0x68420048, PidTagWlinkGroupName = 0x6851001F, PidTagWlinkOrdinal = 0x684B0102, PidTagWlinkROGroupType = 0x68920003, PidTagWlinkROGroupType_Error = 0x6892000A, PidTagWlinkRecordKey = 0x684D0102, PidTagWlinkRecordKey_Error = 0x684D000A, PidTagWlinkSection = 0x68520003, PidTagWlinkStoreEntryId = 0x684E0102, PidTagWlinkStoreEntryId_Error = 0x684E000A, PidTagWlinkType = 0x68490003, PidTagAssociatedContentCount = 0x36170003, PidTagFolderChildCount = 0x66380003, PidTagDeletedCountTotal = 0x670B0003, PidTagIpmPublicFoldersEntryId = 0x66310102, PidTagLocalCommitTimeMax = 0x670a0040, PidTagConversationKey = 0x000b0102, PidTagContactEmailAddresses = 0x3a56101f, PidTagGenerateExchangeViews = 0x36e9000b, PidTagLatestDeliveryTime = 0x00190040, PidTagMailPermission = 0x3a0e000b, PidTagOriginalAuthorName = 0x004d001f, MAPI_PROP_RESERVED = 0xFFFFFFFF } MAPITAGS; openchange-2.0/property.idl000066400000000000000000000246041223057412600160500ustar00rootroot00000000000000#include "idl_types.h" cpp_quote("#include ") import "exchange.idl"; [ pointer_default(unique) ] interface property { typedef [v1_enum] enum { afNone = 0x00000000, afByValue = 0x00000001, afByReference = 0x00000002, afByReferenceOnly = 0x00000004, afEmbeddedMessage = 0x00000005, afStorage = 0x00000006 } AttachmentMethod; typedef [v1_enum] enum { seOpenToDelete = 0x00000001, seNoFrame = 0x00000008, seCoerceToInbox = 0x00000010, seOpenToCopy = 0x00000020, seOpenToMove = 0x00000040, seOpenForCtxMenu = 0x00000100, seCannotUndoDelete = 0x00000400, seCannotUndoCopy = 0x00000800, seCannotUndoMove = 0x00001000, seHasScript = 0x00002000, seOpenToPermDelete = 0x00004000 } SideEffects; typedef [enum16bit] enum { RecurFrequency_Daily = 0x200A, RecurFrequency_Weekly = 0x200B, RecurFrequency_Monthly = 0x200C, RecurFrequency_Yearly = 0x200D } RecurFrequency; typedef [v1_enum] enum { rectypeNone = 0x00000000, rectypeDaily = 0x00000001, rectypeWeekly = 0x00000002, rectypeMonthly = 0x00000003, rectypeYearly = 0x00000004 } RecurrenceType; typedef [enum16bit] enum { PatternType_Day = 0x0, PatternType_Week = 0x1, PatternType_Month = 0x2, PatternType_MonthNth = 0x3, PatternType_MonthEnd = 0x4, PatternType_HjMonth = 0xA, PatternType_HjMonthNth = 0xB, PatternType_HjMonthEnd = 0xC } PatternType; typedef [enum16bit] enum { CAL_DEFAULT = 0x0, CAL_GREGORIAN = 0x1, CAL_GREGORIAN_US = 0x2, CAL_JAPAN = 0x3, CAL_TAIWAN = 0x4, CAL_KOREA = 0x5, CAL_HIJRI = 0x6, CAL_THAI = 0x7, CAL_HEBREW = 0x8, CAL_GREGORIAN_ME_FRENCH = 0x9, CAL_GREGORIAN_ARABIC = 0xA, CAL_GREGORIAN_XLIT_ENGLISH = 0xB, CAL_GREGORIAN_XLIT_FRENCH = 0xC, CAL_LUNAR_JAPANESE = 0xE, CAL_CHINESE_LUNAR = 0xF, CAL_SAKA = 0x10, CAL_LUNAR_KOREAN = 0x14 } CalendarType; typedef [bitmap32bit] bitmap { Su = 0x00000001, M = 0x00000002, Tu = 0x00000004, W = 0x00000008, Th = 0x00000010, F = 0x00000020, Sa = 0x00000040 } WeekRecurrencePattern; typedef [v1_enum] enum { olFree = 0x00000000, olTentative = 0x00000001, olBusy = 0x00000002, olOutOfOffice = 0x00000003 } FreeBusyStatus; /* oxocal - 2.2.1.2 */ typedef [v1_enum] enum { RecurrenceN_First = 0x1, RecurrenceN_Second = 0x2, RecurrenceN_Third = 0x3, RecurrenceN_Fourth = 0x4, RecurrenceN_Last = 0x5 } RecurrenceN; typedef [flag(NDR_NOALIGN)] struct { WeekRecurrencePattern WeekRecurrencePattern; RecurrenceN N; } MonthRecurrencePattern; typedef [nodiscriminant,flag(NDR_NOALIGN)] union { [case(0x1)] WeekRecurrencePattern WeekRecurrencePattern; [case(0x2)] uint32 Day; [case(0x3)] MonthRecurrencePattern MonthRecurrencePattern; [case(0x4)] uint32 Day; [case(0xA)] uint32 Day; [case(0xB)] MonthRecurrencePattern MonthRecurrencePattern; [case(0xC)] uint32 Day; [case(0x0)]; [default]; } PatternTypeSpecific; typedef [v1_enum] enum { END_AFTER_DATE = 0x00002021, END_AFTER_N_OCCURRENCES = 0x00002022, END_NEVER_END = 0x00002023, NEVER_END = 0xFFFFFFFF } EndType; typedef [v1_enum] enum { FirstDOW_Sunday = 0x0, FirstDOW_Monday = 0x1, FirstDOW_Tuesday = 0x2, FirstDOW_Wednesday = 0x3, FirstDOW_Thursday = 0x4, FirstDOW_Friday = 0x5, FirstDOW_Saturday = 0x6 } FirstDOW; typedef [enum16bit] enum { ARO_SUBJECT = 0x0001, ARO_MEETINGTYPE = 0x0002, ARO_REMINDERDELTA = 0x0004, ARO_REMINDER = 0x0008, ARO_LOCATION = 0x0010, ARO_BUSYSTATUS = 0x0020, ARO_ATTACHMENT = 0x0040, ARO_SUBTYPE = 0x0080, ARO_APPTCOLOR = 0x0100, ARO_EXCEPTIONAL_BODY = 0x0200 } OverrideFlags; typedef [public,flag(NDR_NOALIGN)] struct { uint16 ReaderVersion; uint16 WriterVersion; RecurFrequency RecurFrequency; PatternType PatternType; CalendarType CalendarType; uint32 FirstDateTime; uint32 Period; uint32 SlidingFlag; [switch_is(PatternType)] PatternTypeSpecific PatternTypeSpecific; EndType EndType; uint32 OccurrenceCount; FirstDOW FirstDOW; uint32 DeletedInstanceCount; uint32 DeletedInstanceDates[DeletedInstanceCount]; uint32 ModifiedInstanceCount; uint32 ModifiedInstanceDates[ModifiedInstanceCount]; uint32 StartDate; uint32 EndDate; } RecurrencePattern; typedef [public,flag(NDR_NOALIGN)] struct { uint16 msgLength; uint16 msgLength2; uint8 msg[msgLength2]; } Exception_Msg; typedef [nodiscriminant, flag(NDR_NOALIGN)] union { [case(0x0000)] ; [case(0x0001)] Exception_Msg subjectMsg; [case(0x0002)] uint32 mType; [case(0x0004)] uint32 rDelta; [case(0x0008)] uint32 rSet; [case(0x0010)] Exception_Msg locationMsg; [case(0x0020)] uint32 bStatus; [case(0x0040)] uint32 attachment; [case(0x0080)] uint32 sType; [case(0x0100)] uint32 aColor; [default]; } Exception_Value; typedef [public,flag(NDR_NOALIGN)] struct { uint32 StartDateTime; uint32 EndDateTime; uint32 OriginalStartDate; OverrideFlags OverrideFlags; [switch_is(OverrideFlags & 0x0001)] Exception_Value Subject; [switch_is(OverrideFlags & 0x0002)] Exception_Value MeetingType; [switch_is(OverrideFlags & 0x0004)] Exception_Value ReminderDelta; [switch_is(OverrideFlags & 0x0008)] Exception_Value ReminderSet; [switch_is(OverrideFlags & 0x0010)] Exception_Value Location; [switch_is(OverrideFlags & 0x0020)] Exception_Value BusyStatus; [switch_is(OverrideFlags & 0x0040)] Exception_Value Attachment; [switch_is(OverrideFlags & 0x0080)] Exception_Value SubType; [switch_is(OverrideFlags & 0x0100)] Exception_Value AppointmentColor; /* Those are fantom fields: even if they are mentionned in the documentation, they must not be read/written to. */ // uint32 ReservedBlock1Size; // uint8 ReservedBlock1[ReservedBlock1Size]; } ExceptionInfo; typedef [v1_enum] enum { BIT_CH_START = 0x00000001, BIT_CH_END = 0x00000002, BIT_CH_RECUR = 0x00000004, BIT_CH_LOCATION = 0x00000008, BIT_CH_SUBJECT = 0x00000010, BIT_CH_REQATT = 0x00000020, BIT_CH_OPTATT = 0x00000040, BIT_CH_BODY = 0x00000080, BIT_CH_RESPONSE = 0x00000200, BIT_CH_PROPOSE = 0x00000400 } ChangeHighlightFlags; typedef [public,flag(NDR_NOALIGN)] struct { uint32 Size; ChangeHighlightFlags Value; uint8 Reserved[Size-4]; } ChangeHighlight; typedef [nopull,nopush,noprint,flag(NDR_NOALIGN)] struct { ChangeHighlight ChangeHighlight; uint32 ReservedBlockEE1Size; uint8 ReservedBlockEE1[ReservedBlockEE1Size]; uint32 StartDateTime; uint32 EndDateTime; uint32 OriginalStartDate; [flag(LIBNDR_FLAG_STR_SIZE2|LIBNDR_FLAG_STR_NOTERM|LIBNDR_FLAG_STR_CHARLEN)] string Subject; [flag(LIBNDR_FLAG_STR_SIZE2|LIBNDR_FLAG_STR_NOTERM|LIBNDR_FLAG_STR_CHARLEN)] string Location; uint32 ReservedBlockEE2Size; uint8 ReservedBlockEE2[ReservedBlockEE2Size]; } ExtendedException; typedef [nopull,nopush,flag(NDR_NOALIGN)] struct { RecurrencePattern RecurrencePattern; uint32 ReaderVersion2; uint32 WriterVersion2; uint32 StartTimeOffset; uint32 EndTimeOffset; uint16 ExceptionCount; ExceptionInfo ExceptionInfo[ExceptionCount]; uint32 ReservedBlock1Size; uint32 ReservedBlock1[ReservedBlock1Size]; ExtendedException ExtendedException[ExceptionCount]; uint32 ReservedBlock2Size; uint32 ReservedBlock2[ReservedBlock2Size]; } AppointmentRecurrencePattern; /* [MS-DIF].pdf Section 2.3.6 */ typedef [public,flag(NDR_NOALIGN)] struct { uint16 wYear; uint16 wMonth; uint16 wDayOfWeek; uint16 wDay; uint16 wHour; uint16 wMinute; uint16 wSecond; uint16 wMilliseconds; } SYSTEMTIME; /* pidLidTimeZoneStruct */ typedef [public,flag(NDR_NOALIGN)] struct { uint32 lBias; uint32 lStandardBias; uint32 lDaylightBias; uint16 wStandardYear; SYSTEMTIME stStandardDate; uint16 wDaylightYear; SYSTEMTIME stDaylightDate; } TimeZoneStruct; typedef [enum16bit] enum { TZRULE_FLAG_RECUR_CURRENT_TZREG = 0x8000, TZRULE_FLAG_EFFECTIVE_TZREG = 0x4000 } TZRuleFlag; /* pidLidAppointmentTimeZoneDefinitionRecur, * PidLidAppointmentTimeZoneDefinitionStartDisplay, * PidLidAppointmentTimeZoneDefinitionEndDisplay */ typedef [public,flag(NDR_NOALIGN)] struct { uint8 major; /* 0x02 */ uint8 minor; /* 0x01 */ uint16 reserved; /* must be 0x003E */ TZRuleFlag flags; uint16 wYear; uint8 X[14]; /* all zeroes */ uint32 lBias; uint32 lStandardBias; uint32 lDaylightBias; SYSTEMTIME stStandardDate; SYSTEMTIME stDaylightDate; } TZRule; typedef [public,flag(NDR_NOALIGN)] struct { uint8 major; /* 0x02 */ uint8 minor; /* 0x01 */ uint16 cbHeader; uint16 reserved; /* 0x0002 */ [flag(LIBNDR_FLAG_STR_SIZE2|LIBNDR_FLAG_STR_NOTERM)] string keyName; uint16 cRules; TZRule TZRules[cRules]; } TimeZoneDefinition; /* pidLidGlobalObjectId */ typedef [public,flag(NDR_NOALIGN)] struct { uint8 ByteArrayID[16]; uint8 YH; uint8 YL; uint8 Month; uint8 D; FILETIME CreationTime; uint8 X[8]; uint32 Size; uint8 Data[Size]; } GlobalObjectId; typedef [enum16bit] enum { eitLTPrivateFolder = 0x01, eitLTPPublicFolder = 0x03, eitLTPMappedPublicFolder = 0x05, eitLTPPrivateMessage = 0x07, eitLTPPublicMessage = 0x09, eitLTPMappedPublicMessage = 0x0b, eitLTPPublicNewsgroupFolder = 0x0c } EntryIdFolderType; /* PtypServerId */ typedef [public,flag(NDR_NOALIGN)] struct { uint8 ours; dlong FolderId; dlong MessageId; int32 Instance; } PtypServerId; /* FolderEntryId */ typedef [public,flag(NDR_NOALIGN)] struct { uint32 Flags; GUID ProviderUID; EntryIdFolderType FolderType; GUID FolderDatabaseGuid; [switch_is(1)] GLOBCNT FolderGlobalCounter; uint16 Pad; } FolderEntryId; /* PR_ENTRYID/PR_TARGET_ENTRYID (messages) */ typedef [public,flag(NDR_NOALIGN)] struct { uint32 Flags; GUID ProviderUID; EntryIdFolderType MessageType; GUID FolderDatabaseGuid; [switch_is(1)] GLOBCNT FolderGlobalCounter; uint16 Pad1; GUID MessageDatabaseGuid; [switch_is(1)] GLOBCNT MessageGlobalCounter; uint16 Pad2; } MessageEntryId; /* AddressBookEntryId */ typedef [public,flag(NDR_NOALIGN)] struct { uint32 Flags; GUID ProviderUID; uint32 Version; uint32 Type; astring X500DN; } AddressBookEntryId; } openchange-2.0/pyopenchange/000077500000000000000000000000001223057412600161445ustar00rootroot00000000000000openchange-2.0/pyopenchange/mapistore/000077500000000000000000000000001223057412600201475ustar00rootroot00000000000000openchange-2.0/pyopenchange/mapistore/context.c000066400000000000000000000160161223057412600220030ustar00rootroot00000000000000/* OpenChange MAPI implementation. Python interface to mapistore context Copyright (C) Julien Kerihuel 2010-2011. This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see . */ #include #include #include "pyopenchange/mapistore/pymapistore.h" static void py_MAPIStoreContext_dealloc(PyObject *_self) { PyMAPIStoreContextObject *self = (PyMAPIStoreContextObject *) _self; mapistore_del_context(self->mstore_ctx, self->context_id); Py_XDECREF(self->parent); PyObject_Del(_self); } static PyObject *py_MAPIStoreContext_open(PyMAPIStoreContextObject *self, PyObject *args) { PyMAPIStoreFolderObject *folder; folder = PyObject_New(PyMAPIStoreFolderObject, &PyMAPIStoreFolder); folder->context = self; Py_INCREF(folder->context); folder->folder_object = self->folder_object; (void) talloc_reference(NULL, folder->folder_object); folder->fid = self->fid; return (PyObject *)folder; } /* FIXME: fix subscription code before reenabling this */ #if 0 static PyObject *py_MAPIStoreContext_register_subscription(PyMAPIStoreContextObject *self, PyObject *args) { int ret; struct mapistore_mgmt_notif n; const char *mapistoreURI; bool WholeStore; uint16_t NotificationFlags; uint64_t FolderID; bool softdeleted; struct mapistore_subscription_list *subscription_list; struct mapistore_subscription *subscription; struct mapistore_object_subscription_parameters subscription_params; uint32_t random_int; PyMAPIStoreGlobals *globals; if (!PyArg_ParseTuple(args, "sbh", &mapistoreURI, &WholeStore, &NotificationFlags)) { return NULL; } n.WholeStore = WholeStore; n.NotificationFlags = NotificationFlags; if (WholeStore == true) { n.FolderID = 0; n.MessageID = 0; n.MAPIStoreURI = NULL; } else { /* Retrieve folderID from mapistoreURI in openchange.ldb */ globals = get_PyMAPIStoreGlobals(); ret = openchangedb_get_fid(globals->ocdb_ctx, mapistoreURI, &FolderID); if (ret != MAPISTORE_SUCCESS) { /* Try to retrieve URI from user indexing.tdb */ ret = mapistore_indexing_record_get_fmid(self->mstore_ctx, self->mstore_ctx->conn_info->username, mapistoreURI, false, &FolderID, &softdeleted); if (ret != MAPISTORE_SUCCESS || softdeleted == true) { return PyBool_FromLong(false); } } n.FolderID = FolderID; n.MessageID = 0; n.MAPIStoreURI = mapistoreURI; } #if 0 ret = mapistore_mgmt_interface_register_subscription(self->mstore_ctx->conn_info, &n); #endif /* Upon success attach subscription to session object using * existing mapistore_notification.c implementation */ if (ret == MAPISTORE_SUCCESS) { subscription_list = talloc_zero(self->mstore_ctx, struct mapistore_subscription_list); DLIST_ADD(self->mstore_ctx->subscriptions, subscription_list); subscription_params.folder_id = n.FolderID; subscription_params.object_id = n.MessageID; subscription_params.whole_store = n.WholeStore; /* In OpenChange server, we use handle_id of the * object, just use rand for now in bindings */ random_int = rand(); subscription = mapistore_new_subscription(subscription_list, self->mstore_ctx, self->mstore_ctx->conn_info->username, random_int, n.NotificationFlags, &subscription_params); subscription_list->subscription = subscription; } return PyInt_FromLong(!ret ? random_int : -1); } static PyObject *py_MAPIStoreContext_unregister_subscription(PyMAPIStoreContextObject *self, PyObject *args) { int ret; struct mapistore_mgmt_notif n; const char *mapistoreURI; bool WholeStore; uint16_t NotificationFlags; uint64_t FolderID; uint32_t identifier; PyMAPIStoreGlobals *globals; if (!PyArg_ParseTuple(args, "sbhi", &mapistoreURI, &WholeStore, &NotificationFlags, &identifier)) { return NULL; } n.WholeStore = WholeStore; n.NotificationFlags = NotificationFlags; if (WholeStore == true) { n.FolderID = 0; n.MessageID = 0; n.MAPIStoreURI = NULL; } else { /* Retrieve folderID from mapistoreURI in openchange.ldb */ globals = get_PyMAPIStoreGlobals(); ret = openchangedb_get_fid(globals->ocdb_ctx, mapistoreURI, &FolderID); if (ret != MAPISTORE_SUCCESS) { /* Try to retrieve URI from user indexing.tdb */ } n.FolderID = FolderID; n.MessageID = 0; n.MAPIStoreURI = mapistoreURI; } #if 0 ret = mapistore_mgmt_interface_unregister_subscription(self->mstore_ctx->conn_info, &n); #endif /* Remove matching notifications from mapistore_notification system */ if (ret == MAPISTORE_SUCCESS) { ret = mapistore_delete_subscription(self->mstore_ctx, identifier, NotificationFlags); } return PyBool_FromLong(!ret ? true : false); } static PyObject *py_MAPIStoreContext_get_notifications(PyMAPIStoreContextObject *self, PyObject *args) { int ret; struct mapistore_subscription_list *sel; struct mapistore_notification_list *nlist; for (sel = self->mstore_ctx->subscriptions; sel; sel = sel->next) { ret = mapistore_get_queued_notifications(self->mstore_ctx, sel->subscription, &nlist); if (ret == MAPISTORE_SUCCESS) { while (nlist) { printf("notification FolderID: 0x%"PRIx64"\n", nlist->notification->parameters.object_parameters.folder_id); printf("notification MessageID: 0x%"PRIx64"\n", nlist->notification->parameters.object_parameters.object_id); nlist = nlist->next; } talloc_free(nlist); } } if (ret != MAPISTORE_SUCCESS) { return Py_None; } return Py_None; } #endif /* disabled notifications */ static PyMethodDef mapistore_context_methods[] = { { "open", (PyCFunction)py_MAPIStoreContext_open, METH_VARARGS }, #if 0 { "add_subscription", (PyCFunction)py_MAPIStoreContext_register_subscription, METH_VARARGS }, { "delete_subscription", (PyCFunction)py_MAPIStoreContext_unregister_subscription, METH_VARARGS }, { "get_notifications", (PyCFunction)py_MAPIStoreContext_get_notifications, METH_VARARGS }, #endif /* disabled notifications */ { NULL }, }; static PyGetSetDef mapistore_context_getsetters[] = { { NULL } }; PyTypeObject PyMAPIStoreContext = { PyObject_HEAD_INIT(NULL) 0, .tp_name = "mapistore context", .tp_basicsize = sizeof (PyMAPIStoreContextObject), .tp_methods = mapistore_context_methods, .tp_getset = mapistore_context_getsetters, .tp_doc = "mapistore context object", .tp_dealloc = (destructor)py_MAPIStoreContext_dealloc, .tp_flags = Py_TPFLAGS_DEFAULT, }; void initmapistore_context(PyObject *m) { if (PyType_Ready(&PyMAPIStoreContext) < 0) { return; } Py_INCREF(&PyMAPIStoreContext); } openchange-2.0/pyopenchange/mapistore/folder.c000066400000000000000000000156311223057412600215740ustar00rootroot00000000000000/* OpenChange MAPI implementation. Python interface to mapistore folder Copyright (C) Julien Kerihuel 2011. This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see . */ #include #include "pyopenchange/mapistore/pymapistore.h" #include "gen_ndr/exchange.h" static void py_MAPIStoreFolder_dealloc(PyObject *_self) { PyMAPIStoreFolderObject *self = (PyMAPIStoreFolderObject *)_self; talloc_unlink(NULL, self->folder_object); Py_XDECREF(self->context); PyObject_Del(_self); } static PyObject *py_MAPIStoreFolder_create_folder(PyMAPIStoreFolderObject *self, PyObject *args, PyObject *kwargs) { int ret; /* PyMAPIStoreFolderObject *folder; */ char *kwnames[] = { "name", "description", "foldertype", "flags" }; const char *name; const char *desc = NULL; uint16_t foldertype = FOLDER_GENERIC; uint16_t flags = NONE; uint64_t fid; if (!PyArg_ParseTupleAndKeywords(args, kwargs, "s|shh", kwnames, &name, &desc, &foldertype, &flags)) { return NULL; } /* Step 1. Check if the folder already exists */ ret = mapistore_folder_get_child_fid_by_name(self->context->mstore_ctx, self->context->context_id, self->context->folder_object, name, &fid); if (ret == MAPISTORE_SUCCESS) { if (flags != OPEN_IF_EXISTS) { PyErr_SetMAPIStoreError(ret); return NULL; } } /* TODO: Complete the implementation */ return Py_None; } static PyObject *py_MAPIStoreFolder_get_fid(PyMAPIStoreFolderObject *self, void *closure) { return PyLong_FromLongLong(self->fid); } static PyObject *py_MAPIStoreFolder_get_child_count(PyMAPIStoreFolderObject *self, PyObject *args, PyObject *kwargs) { uint32_t RowCount; enum mapistore_table_type table_type; char *kwnames[] = { "table_type" }; int retval; if (!PyArg_ParseTupleAndKeywords(args, kwargs, "i", kwnames, &table_type)) { return NULL; } retval = mapistore_folder_get_child_count(self->context->mstore_ctx, self->context->context_id, (self->folder_object ? self->folder_object : self->context->folder_object), table_type, &RowCount); if (retval != MAPISTORE_SUCCESS) { return PyInt_FromLong(-1); } return PyInt_FromLong(RowCount); } static void convert_datetime_to_tm(TALLOC_CTX *mem_ctx, PyObject *datetime, struct tm *tm) { PyObject *value; value = PyObject_GetAttrString(datetime, "year"); tm->tm_year = PyInt_AS_LONG(value) - 1900; value = PyObject_GetAttrString(datetime, "month"); tm->tm_mon = PyInt_AS_LONG(value) - 1; value = PyObject_GetAttrString(datetime, "day"); tm->tm_mday = PyInt_AS_LONG(value); value = PyObject_GetAttrString(datetime, "hour"); tm->tm_hour = PyInt_AS_LONG(value); value = PyObject_GetAttrString(datetime, "minute"); tm->tm_min = PyInt_AS_LONG(value); value = PyObject_GetAttrString(datetime, "second"); tm->tm_sec = PyInt_AS_LONG(value); #ifdef __USE_BSD value = PyObject_CallMethod(datetime, "utcoffset", NULL); if (value && value != Py_None) { tm->tm_gmtoff = PyInt_AS_LONG(value); } else { tm->tm_gmtoff = 0; } value = PyObject_CallMethod(datetime, "tzname", NULL); if (value && value != Py_None) { tm->tm_zone = talloc_strdup(mem_ctx, PyString_AsString(value)); } else { tm->tm_zone = NULL; } #else value = PyObject_CallMethod(datetime, "utcoffset", NULL); if (value && value != Py_None) { tm->__tm_gmtoff = PyInt_AS_LONG(value); } else { tm->__tm_gmtoff = 0; } value = PyObject_CallMethod(datetime, "tzname", NULL); if (value && value != Py_None) { tm->__tm_zone = talloc_strdup(mem_ctx, PyString_AsString(value)); } else { tm->__tm_zone = NULL; } #endif } static PyObject *py_MAPIStoreFolder_fetch_freebusy_properties(PyMAPIStoreFolderObject *self, PyObject *args, PyObject *kwargs) { TALLOC_CTX *mem_ctx; char *kwnames[] = { "startdate", "enddate", NULL }; PyObject *start = NULL, *end = NULL, *result = NULL; struct tm *start_tm, *end_tm; enum mapistore_error retval; struct mapistore_freebusy_properties *fb_props; PyMAPIStoreGlobals *globals; if (!PyArg_ParseTupleAndKeywords(args, kwargs, "|OO", kwnames, &start, &end)) { return NULL; } mem_ctx = talloc_zero(NULL, TALLOC_CTX); globals = get_PyMAPIStoreGlobals(); if (start) { if (!PyObject_IsInstance(start, globals->datetime_datetime_class)) { PyErr_SetString(PyExc_TypeError, "'start' must either be a datetime.datetime instance or None"); goto end; } start_tm = talloc_zero(mem_ctx, struct tm); convert_datetime_to_tm(mem_ctx, start, start_tm); } else { start_tm = NULL; } if (end) { if (!PyObject_IsInstance(end, globals->datetime_datetime_class)) { PyErr_SetString(PyExc_TypeError, "'end' must either be a datetime.datetime instance or None"); goto end; } end_tm = talloc_zero(mem_ctx, struct tm); convert_datetime_to_tm(mem_ctx, end, end_tm); } else { end_tm = NULL; } retval = mapistore_folder_fetch_freebusy_properties(self->context->mstore_ctx, self->context->context_id, self->folder_object, start_tm, end_tm, mem_ctx, &fb_props); if (retval != MAPISTORE_SUCCESS) { PyErr_SetMAPIStoreError(retval); goto end; } result = (PyObject *) instantiate_freebusy_properties(fb_props); end: talloc_free(mem_ctx); return result; } static PyMethodDef mapistore_folder_methods[] = { { "create_folder", (PyCFunction)py_MAPIStoreFolder_create_folder, METH_VARARGS|METH_KEYWORDS }, { "get_child_count", (PyCFunction)py_MAPIStoreFolder_get_child_count, METH_VARARGS|METH_KEYWORDS }, { "fetch_freebusy_properties", (PyCFunction)py_MAPIStoreFolder_fetch_freebusy_properties, METH_VARARGS|METH_KEYWORDS }, { NULL }, }; static PyGetSetDef mapistore_folder_getsetters[] = { { (char *)"fid", (getter)py_MAPIStoreFolder_get_fid, NULL, NULL }, { NULL } }; PyTypeObject PyMAPIStoreFolder = { PyObject_HEAD_INIT(NULL) 0, .tp_name = "mapistore folder", .tp_basicsize = sizeof (PyMAPIStoreFolderObject), .tp_methods = mapistore_folder_methods, .tp_getset = mapistore_folder_getsetters, .tp_doc = "mapistore folder object", .tp_dealloc = (destructor)py_MAPIStoreFolder_dealloc, .tp_flags = Py_TPFLAGS_DEFAULT, }; void initmapistore_folder(PyObject *m) { if (PyType_Ready(&PyMAPIStoreFolder) < 0) { return; } Py_INCREF(&PyMAPIStoreFolder); PyModule_AddObject(m, "FOLDER_GENERIC", PyInt_FromLong(0x1)); PyModule_AddObject(m, "FOLDER_SEARCH", PyInt_FromLong(0x2)); PyModule_AddObject(m, "NONE", PyInt_FromLong(0x0)); PyModule_AddObject(m, "OPEN_IF_EXISTS", PyInt_FromLong(0x1)); } openchange-2.0/pyopenchange/mapistore/freebusy_properties.c000066400000000000000000000160361223057412600244210ustar00rootroot00000000000000/* OpenChange MAPI implementation. Python interface to mapistore folder Copyright (C) Wolfgang Sourdeau 2012. This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see . */ #include #include #include "mapiproxy/libmapistore/mapistore.h" #include #include "pymapistore.h" static void py_MAPIStoreFreeBusyProperties_dealloc(PyObject *_self); struct PyMemberDef PyMAPIStoreFreeBusyProperties_members[] = { { "timestamp", T_OBJECT_EX, offsetof(PyMAPIStoreFreeBusyPropertiesObject, timestamp), RO, "docstring of publish_start" }, /* start date of the returned ranges */ { "publish_start", T_OBJECT_EX, offsetof(PyMAPIStoreFreeBusyPropertiesObject, publish_start), RO, "docstring of publish_start" }, /* end date of the returned ranges */ { "publish_end", T_OBJECT_EX, offsetof(PyMAPIStoreFreeBusyPropertiesObject, publish_end), RO, "docstring of publish_end" }, /* tuples of tuples of date ranges, based on event/participation status */ { "free", T_OBJECT_EX, offsetof(PyMAPIStoreFreeBusyPropertiesObject, free), RO, "docstring of free" }, { "tentative", T_OBJECT_EX, offsetof(PyMAPIStoreFreeBusyPropertiesObject, tentative), RO, "docstring of tentative" }, { "busy", T_OBJECT_EX, offsetof(PyMAPIStoreFreeBusyPropertiesObject, busy), RO, "docstring of busy" }, { "away", T_OBJECT_EX, offsetof(PyMAPIStoreFreeBusyPropertiesObject, away), RO, "docstring of away" }, /* combination of the above tuples */ { "merged", T_OBJECT_EX, offsetof(PyMAPIStoreFreeBusyPropertiesObject, merged), RO, "docstring of merged" }, { NULL } }; PyTypeObject PyMAPIStoreFreeBusyProperties = { PyObject_HEAD_INIT(NULL) 0, .tp_name = "FreeBusyProperties", .tp_members = PyMAPIStoreFreeBusyProperties_members, .tp_basicsize = sizeof (PyMAPIStoreFreeBusyPropertiesObject), .tp_doc = "mapistore freebusy properties object", .tp_dealloc = (destructor)py_MAPIStoreFreeBusyProperties_dealloc, .tp_flags = Py_TPFLAGS_DEFAULT, }; static PyObject *make_datetime_from_nttime(NTTIME nt_time) { time_t unix_time; PyMAPIStoreGlobals *globals; unix_time = nt_time_to_unix(nt_time); globals = get_PyMAPIStoreGlobals(); return PyObject_CallMethod(globals->datetime_datetime_class, "utcfromtimestamp", "i", unix_time); } static PyObject *make_datetime_from_filetime(struct FILETIME *filetime) { NTTIME nt_time; nt_time = ((NTTIME) filetime->dwHighDateTime << 32) | filetime->dwLowDateTime; return make_datetime_from_nttime(nt_time); } static PyObject *make_datetime_from_minutes(uint32_t minutes) { NTTIME nt_time; nt_time = (NTTIME) minutes * (60 * 10000000); return make_datetime_from_nttime(nt_time); } static PyObject *make_datetime_from_ymon_and_minutes(uint32_t ymon, uint16_t offset_mins) { struct tm tm; int year, hours; time_t unix_time; PyMAPIStoreGlobals *globals; memset(&tm, 0, sizeof(struct tm)); year = ymon >> 4; tm.tm_year = year - 1900; tm.tm_mon = (ymon & 0x000f) - 1; tm.tm_min = offset_mins % 60; hours = offset_mins / 60; tm.tm_mday = 1 + (hours / 24); tm.tm_hour = hours % 24; unix_time = mktime(&tm); globals = get_PyMAPIStoreGlobals(); return PyObject_CallMethod(globals->datetime_datetime_class, "utcfromtimestamp", "i", unix_time); } static PyObject *make_range_tuple_from_range(uint32_t ymon, uint16_t *minutes_range_start) { PyObject *range_tuple, *datetime; range_tuple = PyTuple_New(2); datetime = make_datetime_from_ymon_and_minutes(ymon, minutes_range_start[0]); PyTuple_SET_ITEM(range_tuple, 0, datetime); datetime = make_datetime_from_ymon_and_minutes(ymon, minutes_range_start[1]); PyTuple_SET_ITEM(range_tuple, 1, datetime); return range_tuple; } static PyObject *make_fb_tuple(struct mapistore_freebusy_properties *fb_props, struct Binary_r *ranges) { int i, j, range_nbr, nbr_ranges, nbr_minute_ranges; struct Binary_r *current_ranges; uint16_t *minutes_range_start; PyObject *tuple, *range_tuple; char *tz; nbr_ranges = 0; for (i = 0; i < fb_props->nbr_months; i++) { current_ranges = ranges + i; nbr_ranges += (current_ranges->cb / (2 * sizeof(uint16_t))); } tz = getenv("TZ"); setenv("TZ", "", 1); tzset(); tuple = PyTuple_New(nbr_ranges); range_nbr = 0; for (i = 0; i < fb_props->nbr_months; i++) { current_ranges = ranges + i; minutes_range_start = (uint16_t *) current_ranges->lpb; nbr_minute_ranges = (current_ranges->cb / (2 * sizeof(uint16_t))); for (j = 0; j < nbr_minute_ranges; j++) { range_tuple = make_range_tuple_from_range(fb_props->months_ranges[i], minutes_range_start); PyTuple_SET_ITEM(tuple, range_nbr, range_tuple); minutes_range_start += 2; range_nbr++; } } if (tz) { setenv("TZ", tz, 1); } else { unsetenv("TZ"); } tzset(); return tuple; } PyMAPIStoreFreeBusyPropertiesObject* instantiate_freebusy_properties(struct mapistore_freebusy_properties *fb_props) { PyMAPIStoreFreeBusyPropertiesObject *fb_props_object; PyObject *value; fb_props_object = PyObject_New(PyMAPIStoreFreeBusyPropertiesObject, &PyMAPIStoreFreeBusyProperties); value = make_datetime_from_filetime(&fb_props->timestamp); fb_props_object->timestamp = value; Py_INCREF(value); value = make_datetime_from_minutes(fb_props->publish_start); fb_props_object->publish_start = value; Py_INCREF(value); value = make_datetime_from_minutes(fb_props->publish_end); fb_props_object->publish_end = value; Py_INCREF(value); value = make_fb_tuple(fb_props, fb_props->freebusy_free); fb_props_object->free = value; Py_INCREF(value); value = make_fb_tuple(fb_props, fb_props->freebusy_tentative); fb_props_object->tentative = value; Py_INCREF(value); value = make_fb_tuple(fb_props, fb_props->freebusy_busy); fb_props_object->busy = value; Py_INCREF(value); value = make_fb_tuple(fb_props, fb_props->freebusy_away); fb_props_object->away = value; Py_INCREF(value); value = make_fb_tuple(fb_props, fb_props->freebusy_merged); fb_props_object->merged = value; Py_INCREF(value); return fb_props_object; } static void py_MAPIStoreFreeBusyProperties_dealloc(PyObject *_self) { PyMAPIStoreFreeBusyPropertiesObject *self = (PyMAPIStoreFreeBusyPropertiesObject *)_self; Py_XDECREF(self->timestamp); Py_XDECREF(self->publish_start); Py_XDECREF(self->publish_end); Py_XDECREF(self->free); Py_XDECREF(self->tentative); Py_XDECREF(self->busy); Py_XDECREF(self->away); Py_XDECREF(self->merged); PyObject_Del(_self); } void initmapistore_freebusy_properties(PyObject *parent_module) { if (PyType_Ready(&PyMAPIStoreFreeBusyProperties) < 0) { return; } Py_INCREF(&PyMAPIStoreFreeBusyProperties); } openchange-2.0/pyopenchange/mapistore/gen_errors.py000077500000000000000000000044271223057412600227000ustar00rootroot00000000000000#!/usr/bin/python import os from os.path import dirname import sys def parse_equality(line, last_value): if line[-1] == ",": line = line[:-1] error_name = None error_value = -1 equ_idx = line.find("=") if equ_idx > -1: error_name = line[0:equ_idx].strip() error_value = int(line[equ_idx+1:].strip()) else: error_name = line.strip() error_value = last_value + 1 return (error_name, error_value) def read_errors(errors_file): errors = {} in_enum = False done = False error_value = -1 while not done: line = errors_file.readline().strip() if in_enum: if line.find("}") > -1: done = True elif line.find("MAPISTORE_") > -1: (error_name, error_value) \ = parse_equality(line, error_value) if error_name is not None: errors[error_name] = error_value elif line.find("enum mapistore_error") > -1: in_enum = True return errors def output_errors(output_file, errors): output_file.write("""/* mapistore_errors.c -- auto-generated */ #include #include "pymapistore.h" void initmapistore_errors(PyObject *parent_module) { PyObject *errors_module; errors_module = Py_InitModule3("errors", NULL, "Error codes of the mapistore operations"); if (errors_module == NULL) { return; } PyModule_AddObject(parent_module, "errors", errors_module); """) for error_name, error_value in errors.iteritems(): error_value = errors[error_name] output_file.write(" PyModule_AddObject(errors_module, \"%s\"," \ " PyInt_FromLong(%d));\n" % (error_name, error_value)) output_file.write("}\n") if __name__ == "__main__": if len(sys.argv) > 2: errors_file = open(sys.argv[1]) errors = read_errors(errors_file) if sys.argv[2] == "-": output_file = sys.stdout close_out = False else: output_file = open(sys.argv[2], "w+") output_errors(output_file, errors) else: sys.stderr.write("2 arguments required: mapistore_error.h and output" " filename (or \"-\")\n") sys.exit(-1) openchange-2.0/pyopenchange/mapistore/mgmt.c000066400000000000000000000221231223057412600212570ustar00rootroot00000000000000/* OpenChange MAPI implementation. Python interface to mapistore management Copyright (C) Julien Kerihuel 2011. This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see . */ #include #include "pyopenchange/mapistore/pymapistore.h" static void py_MAPIStoreMGMT_dealloc(PyObject *_self) { PyMAPIStoreMGMTObject *self = (PyMAPIStoreMGMTObject *)_self; printf("deallocate MGMT object\n"); mapistore_mgmt_release(self->mgmt_ctx); Py_XDECREF(self->parent); PyObject_Del(_self); } static PyObject *py_MAPIStoreMGMT_registered_backend(PyMAPIStoreMGMTObject *self, PyObject *args) { int ret; const char *bname; if (!PyArg_ParseTuple(args, "s", &bname)) { return NULL; } ret = mapistore_mgmt_registered_backend(self->mgmt_ctx, bname); return PyBool_FromLong(ret == MAPISTORE_SUCCESS ? true : false); } static PyObject *py_MAPIStoreMGMT_registered_users(PyMAPIStoreMGMTObject *self, PyObject *args) { PyObject *dict; PyObject *userlist; const char *backend; const char *vuser; struct mapistore_mgmt_users_list *ulist; int i; if (!PyArg_ParseTuple(args, "ss", &backend, &vuser)) { return NULL; } dict = PyDict_New(); PyDict_SetItemString(dict, "backend", PyString_FromString(backend)); PyDict_SetItemString(dict, "user", PyString_FromString(vuser)); ulist = mapistore_mgmt_registered_users(self->mgmt_ctx, backend, vuser); userlist = PyList_New(0); if (ulist && ulist->count != 0) { PyDict_SetItem(dict, PyString_FromString("count"), PyLong_FromLong(ulist->count)); for (i = 0; i < ulist->count; i++) { PyList_Append(userlist, PyString_FromString(ulist->user[i])); } } else { PyDict_SetItem(dict, PyString_FromString("count"), PyLong_FromLong(0)); } PyDict_SetItem(dict, PyString_FromString("usernames"), userlist); if (ulist) { talloc_free(ulist); } return (PyObject *)dict; } static PyObject *py_MAPIStoreMGMT_registered_message(PyMAPIStoreMGMTObject *self, PyObject *args) { const char *backend; const char *sysuser; const char *vuser; const char *folder; const char *message; const char *rootURI; int ret; if (!PyArg_ParseTuple(args, "ssszzs", &backend, &sysuser, &vuser, &folder, &rootURI, &message)) { return NULL; } ret = mapistore_mgmt_registered_message(self->mgmt_ctx, backend, sysuser, vuser, folder, rootURI, message); return PyBool_FromLong(ret); } static PyObject *py_MAPIStoreMGMT_register_message(PyMAPIStoreMGMTObject *self, PyObject *args) { const char *backend; const char *user; const char *uri; const char *messageID; char *registered_uri; PyObject *retlist; uint64_t mid; int ret; PyMAPIStoreGlobals *globals; if (!PyArg_ParseTuple(args, "ssss", &backend, &user, &uri, &messageID)) { return NULL; } retlist = PyList_New(0); /* Gets a new message ID */ globals = get_PyMAPIStoreGlobals(); ret = openchangedb_get_new_folderID(globals->ocdb_ctx, &mid); if (ret) return (PyObject *)retlist; /* Register the message within specified user indexing database */ ret = mapistore_mgmt_register_message(self->mgmt_ctx, backend, user, mid, uri, messageID, ®istered_uri); if (ret) return (PyObject *)retlist; PyList_Append(retlist, PyLong_FromLongLong(mid)); PyList_Append(retlist, PyString_FromString(registered_uri)); talloc_free(registered_uri); return (PyObject *) retlist; } static PyObject *py_MAPIStoreMGMT_existing_users(PyMAPIStoreMGMTObject *self, PyObject *args) { PyObject *dict; PyObject *userlist; PyObject *item; char **MAPIStoreURI; char **users; uint32_t count; char *uri; const char *backend; const char *vuser; const char *folder; int ret; int i; PyMAPIStoreGlobals *globals; if (!PyArg_ParseTuple(args, "sss", &backend, &vuser, &folder)) { return NULL; } dict = PyDict_New(); userlist = PyList_New(0); PyDict_SetItemString(dict, "backend", PyString_FromString(backend)); PyDict_SetItemString(dict, "user", PyString_FromString(vuser)); PyDict_SetItemString(dict, "count", PyLong_FromLong(0)); PyDict_SetItem(dict, PyString_FromString("infos"), userlist); ret = mapistore_mgmt_generate_uri(self->mgmt_ctx, backend, vuser, folder, NULL, NULL, &uri); if (ret != MAPISTORE_SUCCESS) return (PyObject *)dict; printf("uri: %s\n", uri); globals = get_PyMAPIStoreGlobals(); ret = openchangedb_get_users_from_partial_uri(self->mgmt_ctx, globals->ocdb_ctx, uri, &count, &MAPIStoreURI, &users); if (ret != MAPISTORE_SUCCESS) return (PyObject *)dict; PyDict_SetItemString(dict, "count", PyLong_FromLong(count)); for (i = 0; i != count; i++) { item = PyDict_New(); PyDict_SetItemString(item, "username", PyString_FromString(users[i])); PyDict_SetItemString(item, "mapistoreURI", PyString_FromString(MAPIStoreURI[i])); PyList_Append(userlist, item); } PyDict_SetItem(dict, PyString_FromString("infos"), userlist); return (PyObject *)dict; } static PyObject *py_MAPIStoreMGMT_registered_subscription(PyMAPIStoreMGMTObject *self, PyObject *args) { int ret; const char *username; const char *uri; uint16_t type; uint16_t NotificationFlags; if (!PyArg_ParseTuple(args, "sshh", &username, &uri, &type, &NotificationFlags)) { return NULL; } switch (type) { case MAPISTORE_FOLDER: ret = mapistore_mgmt_registered_folder_subscription(self->mgmt_ctx, username, uri, NotificationFlags); return PyBool_FromLong((ret == MAPISTORE_SUCCESS) ? true : false); break; case MAPISTORE_MESSAGE: DEBUG(0, ("[%s:%d]: Unsupported subscription type\n", __FUNCTION__, __LINE__)); return PyBool_FromLong(false); break; } return PyBool_FromLong(false); } static PyObject *py_MAPIStoreMGMT_send_newmail(PyMAPIStoreMGMTObject *self, PyObject *args) { int ret; const char *username; const char *storeuser; const char *FolderURI; const char *MessageURI; uint64_t FolderID; uint64_t MessageID; bool softdeleted; PyMAPIStoreGlobals *globals; if (!PyArg_ParseTuple(args, "ssss", &username, &storeuser, &FolderURI, &MessageURI)) { return NULL; } /* Turn MessageURI into MessageID from indexing database */ ret = mapistore_indexing_record_get_fmid(self->mgmt_ctx->mstore_ctx, storeuser, MessageURI, false, &MessageID, &softdeleted); if (ret != MAPISTORE_SUCCESS || softdeleted == true) { return PyBool_FromLong(false); } /* Turn FolderURI into FolderID from openchangedb or indexing database */ globals = get_PyMAPIStoreGlobals(); ret = openchangedb_get_fid(globals->ocdb_ctx, FolderURI, &FolderID); if (ret != MAPI_E_SUCCESS) { ret = mapistore_indexing_record_get_fmid(self->mgmt_ctx->mstore_ctx, username, FolderURI, false, &FolderID, &softdeleted); if (ret != MAPISTORE_SUCCESS || softdeleted == true) { return PyBool_FromLong(false); } } /* Send notification on user queue */ ret = mapistore_mgmt_send_newmail_notification(self->mgmt_ctx, username, FolderID, MessageID, MessageURI); return PyBool_FromLong((ret == MAPISTORE_SUCCESS) ? true : false); } static PyObject *obj_get_verbose(PyMAPIStoreMGMTObject *self, void *closure) { return PyBool_FromLong(self->mgmt_ctx->verbose); } static int obj_set_verbose(PyMAPIStoreMGMTObject *self, PyObject *verbose, void *closure) { if (!PyBool_Check(verbose)) return -1; if (mapistore_mgmt_set_verbosity(self->mgmt_ctx, PyLong_AsLong(verbose)) != MAPISTORE_SUCCESS) return -1; return 0; } static PyMethodDef mapistore_mgmt_methods[] = { { "registered_backend", (PyCFunction)py_MAPIStoreMGMT_registered_backend, METH_VARARGS }, { "registered_users", (PyCFunction)py_MAPIStoreMGMT_registered_users, METH_VARARGS }, { "registered_message", (PyCFunction)py_MAPIStoreMGMT_registered_message, METH_VARARGS }, { "register_message", (PyCFunction)py_MAPIStoreMGMT_register_message, METH_VARARGS }, { "registered_subscription", (PyCFunction)py_MAPIStoreMGMT_registered_subscription, METH_VARARGS }, { "existing_users", (PyCFunction)py_MAPIStoreMGMT_existing_users, METH_VARARGS }, { "send_newmail", (PyCFunction)py_MAPIStoreMGMT_send_newmail, METH_VARARGS }, { NULL }, }; static PyGetSetDef mapistore_mgmt_getsetters[] = { { (char *)"verbose", (getter)obj_get_verbose, (setter)obj_set_verbose, "Enable/Disable verbosity for management object" }, { NULL } }; PyTypeObject PyMAPIStoreMGMT = { PyObject_HEAD_INIT(NULL) 0, .tp_name = "mapistore_mgmt", .tp_basicsize = sizeof (PyMAPIStoreMGMTObject), .tp_methods = mapistore_mgmt_methods, .tp_getset = mapistore_mgmt_getsetters, .tp_doc = "mapistore management object", .tp_dealloc = (destructor)py_MAPIStoreMGMT_dealloc, .tp_flags = Py_TPFLAGS_DEFAULT, }; void initmapistore_mgmt(PyObject *m) { if (PyType_Ready(&PyMAPIStoreMGMT) < 0) { return; } Py_INCREF(&PyMAPIStoreMGMT); } openchange-2.0/pyopenchange/mapistore/pymapistore.c000066400000000000000000000365141223057412600227000ustar00rootroot00000000000000/* OpenChange MAPI implementation. Python interface to mapistore Copyright (C) Julien Kerihuel 2010-2011. This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see . */ #include #include "pyopenchange/mapistore/pymapistore.h" #include "pyopenchange/pymapi.h" #include #include /* static PyTypeObject *SPropValue_Type; */ extern struct ldb_context *samdb_connect(TALLOC_CTX *, struct tevent_context *, struct loadparm_context *, struct auth_session_info *, int); void initmapistore(void); static PyMAPIStoreGlobals globals; void PyErr_SetMAPIStoreError(uint32_t retval) { PyErr_SetObject(PyExc_RuntimeError, Py_BuildValue("(i, s)", retval, mapistore_errstr(retval))); } PyMAPIStoreGlobals *get_PyMAPIStoreGlobals() { return &globals; } static void sam_ldb_init(const char *syspath) { TALLOC_CTX *mem_ctx; /* char *ldb_path; */ struct loadparm_context *lp_ctx; struct tevent_context *ev; int ret; struct ldb_result *res; struct ldb_dn *tmp_dn = NULL; static const char *attrs[] = { "rootDomainNamingContext", "defaultNamingContext", NULL }; /* Sanity checks */ if (globals.samdb_ctx) return; mem_ctx = talloc_zero(NULL, TALLOC_CTX); ev = tevent_context_init(talloc_autofree_context()); if (!ev) goto end; /* /\* Step 1. Retrieve a LDB context pointer on sam.ldb database *\/ */ /* ldb_path = talloc_asprintf(mem_ctx, "%s/sam.ldb", syspath); */ /* Step 2. Connect to the database */ lp_ctx = loadparm_init_global(true); globals.samdb_ctx = samdb_connect(NULL, NULL, lp_ctx, system_session(lp_ctx), 0); if (!globals.samdb_ctx) goto end; /* Step 3. Search for rootDSE record */ ret = ldb_search(globals.samdb_ctx, mem_ctx, &res, ldb_dn_new(mem_ctx, globals.samdb_ctx, "@ROOTDSE"), LDB_SCOPE_BASE, attrs, NULL); if (ret != LDB_SUCCESS) goto end; if (res->count != 1) goto end; /* Step 4. Set opaque naming */ tmp_dn = ldb_msg_find_attr_as_dn(globals.samdb_ctx, globals.samdb_ctx, res->msgs[0], "rootDomainNamingContext"); ldb_set_opaque(globals.samdb_ctx, "rootDomainNamingContext", tmp_dn); tmp_dn = ldb_msg_find_attr_as_dn(globals.samdb_ctx, globals.samdb_ctx, res->msgs[0], "defaultNamingContext"); ldb_set_opaque(globals.samdb_ctx, "defaultNamingContext", tmp_dn); end: talloc_free(mem_ctx); } static void openchange_ldb_init(const char *syspath) { TALLOC_CTX *mem_ctx; struct ldb_context *ldb_ctx; char *ldb_path; struct tevent_context *ev; int ret; struct ldb_result *res; struct ldb_dn *tmp_dn = NULL; static const char *attrs[] = { "rootDomainNamingContext", "defaultNamingContext", NULL }; /* Sanity checks */ if (globals.ocdb_ctx) return; /* ev = tevent_context_init(talloc_autofree_context()); */ /* if (!ev) { */ /* return NULL; */ /* } */ ev = NULL; mem_ctx = talloc_zero(NULL, TALLOC_CTX); /* Step 1. Retrieve a LDB context pointer on openchange.ldb database */ ldb_ctx = ldb_init(mem_ctx, ev); if (!ldb_ctx) { goto end; } /* Step 2. Connect to the database */ ldb_path = talloc_asprintf(mem_ctx, "%s/openchange.ldb", syspath); ret = ldb_connect(ldb_ctx, ldb_path, 0, NULL); if (ret != LDB_SUCCESS) { goto end; } /* Step 3. Search for rootDSE record */ ret = ldb_search(ldb_ctx, mem_ctx, &res, ldb_dn_new(mem_ctx, ldb_ctx, "@ROOTDSE"), LDB_SCOPE_BASE, attrs, NULL); if (ret != LDB_SUCCESS || res->count != 1) { goto end; } /* Step 4. Set opaque naming */ tmp_dn = ldb_msg_find_attr_as_dn(ldb_ctx, ldb_ctx, res->msgs[0], "rootDomainNamingContext"); ldb_set_opaque(ldb_ctx, "rootDomainNamingContext", tmp_dn); tmp_dn = ldb_msg_find_attr_as_dn(ldb_ctx, ldb_ctx, res->msgs[0], "defaultNamingContext"); ldb_set_opaque(ldb_ctx, "defaultNamingContext", tmp_dn); globals.ocdb_ctx = ldb_ctx; (void) talloc_reference(NULL, globals.ocdb_ctx); end: talloc_free(mem_ctx); } static PyObject *py_MAPIStore_new(PyTypeObject *type, PyObject *args, PyObject *kwargs) { TALLOC_CTX *mem_ctx; struct loadparm_context *lp_ctx; struct mapistore_context *mstore_ctx; PyMAPIStoreObject *msobj; char *kwnames[] = { "syspath", "path", NULL }; const char *path = NULL; const char *syspath = NULL; if (!PyArg_ParseTupleAndKeywords(args, kwargs, "s|s", kwnames, &syspath, &path)) { return NULL; } /* Initialize ldb context on sam.ldb */ sam_ldb_init(syspath); if (globals.samdb_ctx == NULL) { PyErr_SetString(PyExc_SystemError, "error in sam_ldb_init"); return NULL; } mem_ctx = talloc_new(NULL); if (mem_ctx == NULL) { PyErr_NoMemory(); return NULL; } /* Initialize ldb context on openchange.ldb */ openchange_ldb_init(syspath); if (globals.ocdb_ctx == NULL) { PyErr_SetString(PyExc_SystemError, "error in openchange_ldb_init"); talloc_free(mem_ctx); return NULL; } /* Initialize configuration */ lp_ctx = loadparm_init(mem_ctx); lpcfg_load_default(lp_ctx); /* Initialize mapistore */ mstore_ctx = mapistore_init(mem_ctx, lp_ctx, path); if (mstore_ctx == NULL) { PyErr_SetString(PyExc_SystemError, "error in mapistore_init"); talloc_free(mem_ctx); return NULL; } msobj = PyObject_New(PyMAPIStoreObject, &PyMAPIStore); msobj->mem_ctx = mem_ctx; msobj->mstore_ctx = mstore_ctx; return (PyObject *) msobj; } static void py_MAPIStore_dealloc(PyObject *_self) { PyMAPIStoreObject *self = (PyMAPIStoreObject *)_self; mapistore_release(self->mstore_ctx); talloc_free(self->mem_ctx); PyObject_Del(_self); } static PyObject *py_MAPIStore_new_mgmt(PyMAPIStoreObject *self, PyObject *args) { PyMAPIStoreMGMTObject *obj; obj = PyObject_New(PyMAPIStoreMGMTObject, &PyMAPIStoreMGMT); obj->mgmt_ctx = mapistore_mgmt_init(self->mstore_ctx); if (obj->mgmt_ctx == NULL) { PyErr_SetMAPIStoreError(MAPISTORE_ERR_NOT_INITIALIZED); return NULL; } obj->mem_ctx = self->mem_ctx; obj->parent = self; Py_INCREF(obj->parent); return (PyObject *) obj; } static PyObject *py_MAPIStore_add_context(PyMAPIStoreObject *self, PyObject *args) { int ret; PyMAPIStoreContextObject *context; uint32_t context_id = 0; const char *uri; const char *username; void *folder_object; uint64_t fid = 0; if (!PyArg_ParseTuple(args, "ss", &uri, &username)) { return NULL; } /* printf("Add context: %s\n", uri); */ /* Initialize connection info */ ret = mapistore_set_connection_info(self->mstore_ctx, globals.samdb_ctx, globals.ocdb_ctx, username); if (ret != MAPISTORE_SUCCESS) { PyErr_SetMAPIStoreError(ret); return NULL; } /* Get FID given mapistore_uri and username */ ret = openchangedb_get_fid(globals.ocdb_ctx, uri, &fid); if (ret != MAPISTORE_SUCCESS) { PyErr_SetMAPIStoreError(ret); return NULL; } ret = mapistore_add_context(self->mstore_ctx, username, uri, fid, &context_id, &folder_object); if (ret != MAPISTORE_SUCCESS) { PyErr_SetMAPIStoreError(ret); return NULL; } context = PyObject_New(PyMAPIStoreContextObject, &PyMAPIStoreContext); context->mem_ctx = self->mem_ctx; context->mstore_ctx = self->mstore_ctx; context->fid = fid; context->folder_object = folder_object; context->context_id = context_id; context->parent = self; Py_INCREF(context->parent); return (PyObject *) context; } /* static PyObject *py_MAPIStore_delete_context(PyMAPIStoreObject *self, PyObject *args) */ /* { */ /* PyMAPIStoreContextObject *context; */ /* int ret = MAPISTORE_SUCCESS; */ /* if (!PyArg_ParseTuple(args, "O", &context)) { */ /* return NULL; */ /* } */ /* /\* mapistore_del_context(context->mstore_ctx, context->context_id); *\/ */ /* /\* Py_XDECREF(context); *\/ */ /* return PyInt_FromLong(ret); */ /* } */ /* static PyObject *py_MAPIStore_search_context_by_uri(PyMAPIStoreObject *self, PyObject *args) */ /* { */ /* int ret; */ /* uint32_t context_id = 0; */ /* const char *uri; */ /* void *backend_object; */ /* if (!PyArg_ParseTuple(args, "s", &uri)) { */ /* return NULL; */ /* } */ /* ret = mapistore_search_context_by_uri(self->mstore_ctx, uri, &context_id, &backend_object); */ /* if (ret != MAPISTORE_SUCCESS) { */ /* return NULL; */ /* } */ /* return PyInt_FromLong(context_id); */ /* } */ /* static PyObject *py_MAPIStore_add_context_ref_count(PyMAPIStoreObject *self, PyObject *args) */ /* { */ /* uint32_t context_id = 0; */ /* if (!PyArg_ParseTuple(args, "k", &context_id)) { */ /* return NULL; */ /* } */ /* return PyInt_FromLong(mapistore_add_context_ref_count(self->mstore_ctx, context_id)); */ /* } */ /* static PyObject *py_MAPIStore_create_folder(PyMAPIStoreObject *self, PyObject *args) */ /* { */ /* uint32_t context_id; */ /* uint64_t parent_fid; */ /* uint64_t fid; */ /* PyObject *mod_mapi; */ /* PyObject *pySPropValue; */ /* PySPropValueObject *SPropValue; */ /* struct SRow aRow; */ /* mod_mapi = PyImport_ImportModule("openchange.mapi"); */ /* if (mod_mapi == NULL) { */ /* printf("Can't load module\n"); */ /* return NULL; */ /* } */ /* SPropValue_Type = (PyTypeObject *)PyObject_GetAttrString(mod_mapi, "SPropValue"); */ /* if (SPropValue_Type == NULL) { */ /* return NULL; */ /* } */ /* if (!PyArg_ParseTuple(args, "kKKO", &context_id, &parent_fid, &fid, &pySPropValue)) { */ /* return NULL; */ /* } */ /* if (!PyObject_TypeCheck(pySPropValue, SPropValue_Type)) { */ /* PyErr_SetString(PyExc_TypeError, "Function require SPropValue object"); */ /* return NULL; */ /* } */ /* SPropValue = (PySPropValueObject *)pySPropValue; */ /* aRow.cValues = SPropValue->cValues; */ /* aRow.lpProps = SPropValue->SPropValue; */ /* return PyInt_FromLong(mapistore_folder_create_folder(self->mstore_ctx, context_id, parent_fid, fid, &aRow)); */ /* } */ /* static PyObject *py_MAPIStore_delete_folder(PyMAPIStoreObject *self, PyObject *args) */ /* { */ /* uint32_t context_id; */ /* uint64_t parent_fid; */ /* uint64_t fid; */ /* uint8_t flags; */ /* if (!PyArg_ParseTuple(args, "kKKH", &context_id, &parent_fid, &fid, &flags)) { */ /* return NULL; */ /* } */ /* return PyInt_FromLong(mapistore_folder_delete_folder(self->mstore_ctx, context_id, parent_fid, fid, flags)); */ /* } */ /* static PyObject *py_MAPIStore_setprops(PyMAPIStoreObject *self, PyObject *args) */ /* { */ /* uint32_t context_id; */ /* uint64_t fid; */ /* uint8_t object_type; */ /* PyObject *mod_mapi; */ /* PyObject *pySPropValue; */ /* PySPropValueObject *SPropValue; */ /* struct SRow aRow; */ /* mod_mapi = PyImport_ImportModule("openchange.mapi"); */ /* if (mod_mapi == NULL) { */ /* printf("Can't load module\n"); */ /* return NULL; */ /* } */ /* SPropValue_Type = (PyTypeObject *)PyObject_GetAttrString(mod_mapi, "SPropValue"); */ /* if (SPropValue_Type == NULL) { */ /* return NULL; */ /* } */ /* if (!PyArg_ParseTuple(args, "kKbO", &context_id, &fid, &object_type, &pySPropValue)) { */ /* return NULL; */ /* } */ /* if (!PyObject_TypeCheck(pySPropValue, SPropValue_Type)) { */ /* PyErr_SetString(PyExc_TypeError, "Function require SPropValue object"); */ /* return NULL; */ /* } */ /* SPropValue = (PySPropValueObject *)pySPropValue; */ /* aRow.cValues = SPropValue->cValues; */ /* aRow.lpProps = SPropValue->SPropValue; */ /* return PyInt_FromLong(mapistore_setprops(self->mstore_ctx, context_id, fid, object_type, &aRow)); */ /* } */ /* static PyObject *py_MAPIStore_get_folder_count(PyMAPIStoreObject *self, PyObject *args) */ /* { */ /* uint32_t context_id; */ /* uint64_t fid; */ /* uint8_t object_type; */ /* uint32_t RowCount = 0; */ /* if (!PyArg_ParseTuple(args, "kKb", &context_id, &fid, &object_type)) { */ /* return NULL; */ /* } */ /* switch (object_type) { */ /* case MAPISTORE_FOLDER: */ /* mapistore_folder_get_folder_count(self->mstore_ctx, context_id, */ /* fid, &RowCount); */ /* break; */ /* case MAPISTORE_MESSAGE: */ /* mapistore_folder_get_message_count(self->mstore_ctx, context_id, */ /* fid, MAPISTORE_MESSAGE_TABLE, &RowCount); */ /* break; */ /* default: */ /* RowCount = 0; */ /* break; */ /* } */ /* return PyInt_FromLong(RowCount); */ /* } */ static PyMethodDef mapistore_methods[] = { { "management", (PyCFunction)py_MAPIStore_new_mgmt, METH_VARARGS }, { "add_context", (PyCFunction)py_MAPIStore_add_context, METH_VARARGS }, /* { "delete_context", (PyCFunction)py_MAPIStore_delete_context, METH_VARARGS }, */ /* { "search_context_by_uri", (PyCFunction)py_MAPIStore_search_context_by_uri, METH_VARARGS }, */ /* { "add_context_ref_count", (PyCFunction)py_MAPIStore_add_context_ref_count, METH_VARARGS }, */ /* { "create_folder", (PyCFunction)py_MAPIStore_create_folder, METH_VARARGS }, */ /* { "delete_folder", (PyCFunction)py_MAPIStore_delete_folder, METH_VARARGS }, */ /* { "setprops", (PyCFunction)py_MAPIStore_setprops, METH_VARARGS }, */ /* { "get_folder_count", (PyCFunction)py_MAPIStore_get_folder_count, METH_VARARGS }, */ { NULL }, }; PyTypeObject PyMAPIStore = { PyObject_HEAD_INIT(NULL) 0, .tp_name = "mapistore.MAPIStore", .tp_basicsize = sizeof (PyMAPIStoreObject), .tp_doc = "mapistore object", .tp_methods = mapistore_methods, /* .tp_getset = mapistore_getsetters, */ .tp_new = py_MAPIStore_new, .tp_dealloc = (destructor)py_MAPIStore_dealloc, .tp_flags = Py_TPFLAGS_DEFAULT, }; static PyObject *py_mapistore_set_mapping_path(PyObject *mod, PyObject *args) { const char *mapping_path; if (!PyArg_ParseTuple(args, "s", &mapping_path)) { return NULL; } return PyInt_FromLong(mapistore_set_mapping_path(mapping_path)); } static PyObject *py_mapistore_errstr(PyObject *mod, PyObject *args) { int ret; if (!PyArg_ParseTuple(args, "k", &ret)) { return NULL; } return PyString_FromString(mapistore_errstr(ret)); } static PyMethodDef py_mapistore_global_methods[] = { { "set_mapping_path", (PyCFunction)py_mapistore_set_mapping_path, METH_VARARGS }, { "errstr", (PyCFunction)py_mapistore_errstr, METH_VARARGS }, { NULL }, }; static void load_modules(void) { PyObject *datetime_dict; globals.datetime_module = PyImport_ImportModule("datetime"); Py_INCREF(globals.datetime_module); if (globals.datetime_module) { datetime_dict = PyModule_GetDict(globals.datetime_module); globals.datetime_datetime_class = PyDict_GetItemString(datetime_dict, "datetime"); if (PyType_Check(globals.datetime_datetime_class)) { Py_INCREF(globals.datetime_datetime_class); } else { fprintf (stderr, "failure loading datetime.datetime class\n"); } } else { fprintf (stderr, "failure loading datetime module\n"); } } void initmapistore(void) { PyObject *m; memset(&globals, 0, sizeof(PyMAPIStoreGlobals)); load_modules(); m = Py_InitModule3("mapistore", py_mapistore_global_methods, "An interface to OpenChange MAPIStore"); if (m == NULL) { return; } if (PyType_Ready(&PyMAPIStore) < 0) { return; } Py_INCREF(&PyMAPIStore); PyModule_AddObject(m, "MAPIStore", (PyObject *)&PyMAPIStore); initmapistore_mgmt(m); initmapistore_context(m); initmapistore_folder(m); initmapistore_freebusy_properties(m); initmapistore_errors(m); initmapistore_table(m); } openchange-2.0/pyopenchange/mapistore/pymapistore.h000066400000000000000000000060201223057412600226720ustar00rootroot00000000000000/* OpenChange MAPI implementation. Python interface to mapistore Copyright (C) Julien Kerihuel 2010. This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see . */ #ifndef __PYMAPISTORE_H_ #define __PYMAPISTORE_H_ #include #include "mapiproxy/libmapistore/mapistore.h" #include "mapiproxy/libmapistore/mapistore_errors.h" #include "mapiproxy/libmapistore/mgmt/mapistore_mgmt.h" #include "mapiproxy/libmapiproxy/libmapiproxy.h" #include typedef struct { PyObject *datetime_module; PyObject *datetime_datetime_class; struct ldb_context *samdb_ctx; struct ldb_context *ocdb_ctx; } PyMAPIStoreGlobals; typedef struct { PyObject_HEAD TALLOC_CTX *mem_ctx; struct mapistore_context *mstore_ctx; } PyMAPIStoreObject; typedef struct { PyObject_HEAD TALLOC_CTX *mem_ctx; struct mapistore_mgmt_context *mgmt_ctx; PyMAPIStoreObject *parent; } PyMAPIStoreMGMTObject; typedef struct { PyObject_HEAD TALLOC_CTX *mem_ctx; struct mapistore_context *mstore_ctx; uint64_t fid; void *folder_object; uint32_t context_id; PyMAPIStoreObject *parent; } PyMAPIStoreContextObject; typedef struct { PyObject_HEAD TALLOC_CTX *mem_ctx; PyMAPIStoreContextObject *context; void *folder_object; uint64_t fid; } PyMAPIStoreFolderObject; typedef struct { PyObject_HEAD PyObject *timestamp; PyObject *publish_start; PyObject *publish_end; PyObject *free; PyObject *tentative; PyObject *busy; PyObject *away; PyObject *merged; } PyMAPIStoreFreeBusyPropertiesObject; typedef struct { PyObject_HEAD } PyMAPIStoreTableObject; PyAPI_DATA(PyTypeObject) PyMAPIStore; PyAPI_DATA(PyTypeObject) PyMAPIStoreMGMT; PyAPI_DATA(PyTypeObject) PyMAPIStoreContext; PyAPI_DATA(PyTypeObject) PyMAPIStoreFolder; PyAPI_DATA(PyTypeObject) PyMAPIStoreTable; #ifndef __BEGIN_DECLS #ifdef __cplusplus #define __BEGIN_DECLS extern "C" { #define __END_DECLS } #else #define __BEGIN_DECLS #define __END_DECLS #endif #endif __BEGIN_DECLS void PyErr_SetMAPIStoreError(uint32_t); /* internal calls */ PyMAPIStoreGlobals *get_PyMAPIStoreGlobals(void); void initmapistore_context(PyObject *); void initmapistore_folder(PyObject *); void initmapistore_mgmt(PyObject *); void initmapistore_freebusy_properties(PyObject *); void initmapistore_table(PyObject *); void initmapistore_errors(PyObject *); PyMAPIStoreFreeBusyPropertiesObject* instantiate_freebusy_properties(struct mapistore_freebusy_properties *); __END_DECLS #endif /* ! __PYMAPISTORE_H_ */ openchange-2.0/pyopenchange/mapistore/table.c000066400000000000000000000030351223057412600214030ustar00rootroot00000000000000/* OpenChange MAPI implementation. Python interface to mapistore table Copyright (C) Julien Kerihuel 2011. This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see . */ #include #include "pyopenchange/mapistore/pymapistore.h" #include "gen_ndr/exchange.h" static void py_MAPIStoreTable_dealloc(PyObject *_self) { PyObject_Del(_self); } static PyMethodDef mapistore_table_methods[] = { { NULL }, }; static PyGetSetDef mapistore_table_getsetters[] = { { NULL } }; PyTypeObject PyMAPIStoreTable = { PyObject_HEAD_INIT(NULL) 0, .tp_name = "MAPIStoreTable", .tp_basicsize = sizeof (PyMAPIStoreTableObject), .tp_methods = mapistore_table_methods, .tp_getset = mapistore_table_getsetters, .tp_doc = "mapistore table object", .tp_dealloc = (destructor)py_MAPIStoreTable_dealloc, .tp_flags = Py_TPFLAGS_DEFAULT, }; void initmapistore_table(PyObject *m) { if (PyType_Ready(&PyMAPIStoreTable) < 0) { return; } Py_INCREF(&PyMAPIStoreTable); } openchange-2.0/pyopenchange/pymapi.c000066400000000000000000000130551223057412600176130ustar00rootroot00000000000000/* OpenChange MAPI implementation. Python interface to openchange Copyright (C) Julien Kerihuel 2010. This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see . */ #include #include "libmapi/libmapi.h" #include "pyopenchange/pymapi.h" void initmapi(void); static PyObject *py_SPropValue_new(PyTypeObject *type, PyObject *args, PyObject *kwargs) { TALLOC_CTX *mem_ctx; PySPropValueObject *SPropValue; mem_ctx = talloc_new(NULL); if (mem_ctx == NULL) { PyErr_NoMemory(); return NULL; } SPropValue = PyObject_New(PySPropValueObject, &PySPropValue); SPropValue->mem_ctx = mem_ctx; SPropValue->SPropValue = talloc_array(mem_ctx, struct SPropValue, 2); SPropValue->cValues = 0; return (PyObject *) SPropValue; } static void py_SPropValue_dealloc(PyObject *_self) { PySPropValueObject *self = (PySPropValueObject *)_self; talloc_free(self->mem_ctx); PyObject_Del(_self); } static PyObject *py_SPropValue_add(PySPropValueObject *self, PyObject *args) { uint32_t proptag; PyObject *data; int i; NTTIME nt; if (!PyArg_ParseTuple(args, "lO", &proptag, &data)) { return NULL; } /* Ensure this tag has not already been added to the list */ for (i = 0; i < self->cValues; i++) { if (self->SPropValue[i].ulPropTag == proptag) { return NULL; } } self->SPropValue = talloc_realloc(self->mem_ctx, self->SPropValue, struct SPropValue, self->cValues + 2); switch (proptag & 0xFFFF) { case PT_I2: if (!PyInt_Check(data)) { PyErr_SetString(PyExc_TypeError, "Property Tag requires long"); return NULL; } self->SPropValue[self->cValues].value.i = (uint16_t) PyInt_AsLong(data); break; case PT_LONG: if (!PyInt_Check(data)) { PyErr_SetString(PyExc_TypeError, "Property Tag requires long"); return NULL; } self->SPropValue[self->cValues].value.l = PyInt_AsLong(data); break; case PT_DOUBLE: if (!PyFloat_Check(data)) { PyErr_SetString(PyExc_TypeError, "Property Tag requires double"); return NULL; } self->SPropValue[self->cValues].value.dbl = PyFloat_AsDouble(data); break; case PT_BOOLEAN: if (!PyBool_Check(data)) { PyErr_SetString(PyExc_TypeError, "Property Tag requires boolean"); return NULL; } self->SPropValue[self->cValues].value.b = PyInt_AsLong(data); break; case PT_I8: if (!PyLong_Check(data)) { PyErr_SetString(PyExc_TypeError, "Property Tag requires long long int"); return NULL; } self->SPropValue[self->cValues].value.d = PyLong_AsLongLong(data); break; case PT_STRING8: if (!PyString_Check(data)) { PyErr_SetString(PyExc_TypeError, "Property Tag requires string"); return NULL; } self->SPropValue[self->cValues].value.lpszA = talloc_strdup(self->mem_ctx, PyString_AsString(data)); break; case PT_UNICODE: if (!PyString_Check(data)) { PyErr_SetString(PyExc_TypeError, "Property Tag requires string"); return NULL; } self->SPropValue[self->cValues].value.lpszW = talloc_strdup(self->mem_ctx, PyString_AsString(data)); break; case PT_SYSTIME: if (!PyFloat_Check(data)) { PyErr_SetString(PyExc_TypeError, "Property Tag requires float"); return NULL; } unix_to_nt_time(&nt, PyFloat_AsDouble(data)); self->SPropValue[self->cValues].value.ft.dwLowDateTime = (nt << 32) >> 32; self->SPropValue[self->cValues].value.ft.dwHighDateTime = nt >> 32; break; case PT_ERROR: if (!PyInt_Check(data)) { PyErr_SetString(PyExc_TypeError, "Property Tag requires long"); return NULL; } self->SPropValue[self->cValues].value.err = PyInt_AsLong(data); break; default: printf("Missing support for 0x%.4x type\n", (proptag & 0xFFFF)); Py_RETURN_NONE; } self->SPropValue[self->cValues].ulPropTag = proptag; self->cValues += 1; Py_RETURN_NONE; } static PyObject *py_SPropValue_dump(PySPropValueObject *self, PyObject *args) { int i; char *sep; if (!PyArg_ParseTuple(args, "s", &sep)) { return NULL; } for (i = 0; i < self->cValues; i++) { mapidump_SPropValue(self->SPropValue[i], sep); } Py_RETURN_NONE; } static PyMethodDef mapi_SPropValue_methods[] = { { "add", (PyCFunction)py_SPropValue_add, METH_VARARGS }, { "dump", (PyCFunction)py_SPropValue_dump, METH_VARARGS }, { NULL }, }; static PyGetSetDef mapi_SPropValue_getsetters[] = { { NULL } }; PyTypeObject PySPropValue = { PyObject_HEAD_INIT(NULL) 0, .tp_name = "SPropValue", .tp_basicsize = sizeof (PySPropValueObject), .tp_methods = mapi_SPropValue_methods, .tp_getset = mapi_SPropValue_getsetters, .tp_doc = "SPropValue MAPI structure", .tp_new = py_SPropValue_new, .tp_dealloc = (destructor)py_SPropValue_dealloc, .tp_flags = Py_TPFLAGS_DEFAULT, }; static PyMethodDef py_mapi_global_methods[] = { { NULL } }; void initmapi(void) { PyObject *m; if (PyType_Ready(&PySPropValue) < 0) { return; } m = Py_InitModule3("mapi", py_mapi_global_methods, "An interface to OpenChange MAPI"); if (m == NULL) { return; } /* Add all properties - generated by mparse.pl */ pymapi_add_properties(m); Py_INCREF(&PySPropValue); PyModule_AddObject(m, "SPropValue", (PyObject *)&PySPropValue); } openchange-2.0/pyopenchange/pymapi.h000066400000000000000000000022241223057412600176140ustar00rootroot00000000000000/* OpenChange MAPI implementation. Python interface to openchange Copyright (C) Julien Kerihuel 2010. This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see . */ #ifndef __PYMAPI_H_ #define __PYMAPI_H_ #include #include "libmapi/libmapi.h" #include typedef struct { PyObject_HEAD TALLOC_CTX *mem_ctx; struct SPropValue *SPropValue; uint32_t cValues; } PySPropValueObject; PyAPI_DATA(PyTypeObject) PySPropValue; /* definitions from auto-generated pymapi_properties.c */ int pymapi_add_properties(PyObject *); #endif /* ! __PYMAPI_H_ */ openchange-2.0/pyopenchange/pymapi_properties.c000066400000000000000000003020461223057412600220700ustar00rootroot00000000000000 /* Automatically generated by script/makepropslist.py. Do not edit */ #include #include "pyopenchange/pymapi.h" int pymapi_add_properties(PyObject *m) { PyModule_AddObject(m, "PidTag7BitDisplayName", PyInt_FromLong(0x39FF001F)); PyModule_AddObject(m, "PidTag7BitDisplayName_Error", PyInt_FromLong(0x39FF000A)); PyModule_AddObject(m, "PidTagAccess", PyInt_FromLong(0x0FF40003)); PyModule_AddObject(m, "PidTagAccessLevel", PyInt_FromLong(0x0FF70003)); PyModule_AddObject(m, "PidTagAccessLevel_Error", PyInt_FromLong(0x0FF7000A)); PyModule_AddObject(m, "PidTagAccess_Error", PyInt_FromLong(0x0FF4000A)); PyModule_AddObject(m, "PidTagAccount", PyInt_FromLong(0x3A00001F)); PyModule_AddObject(m, "PidTagAccount_Error", PyInt_FromLong(0x3A00000A)); PyModule_AddObject(m, "PidTagAdditionalRenEntryIds", PyInt_FromLong(0x36D81102)); PyModule_AddObject(m, "PidTagAdditionalRenEntryIdsEx", PyInt_FromLong(0x36D90102)); PyModule_AddObject(m, "PidTagAdditionalRenEntryIdsEx_Error", PyInt_FromLong(0x36D9000A)); PyModule_AddObject(m, "PidTagAdditionalRenEntryIds_Error", PyInt_FromLong(0x36D8000A)); PyModule_AddObject(m, "PidTagAddressBookAuthorizedSenders", PyInt_FromLong(0x8CD8000D)); PyModule_AddObject(m, "PidTagAddressBookAuthorizedSenders_Error", PyInt_FromLong(0x8CD8000A)); PyModule_AddObject(m, "PidTagAddressBookContainerId", PyInt_FromLong(0xFFFD0003)); PyModule_AddObject(m, "PidTagAddressBookContainerId_Error", PyInt_FromLong(0xFFFD000A)); PyModule_AddObject(m, "PidTagAddressBookDeliveryContentLength", PyInt_FromLong(0x806A0003)); PyModule_AddObject(m, "PidTagAddressBookDeliveryContentLength_Error", PyInt_FromLong(0x806A000A)); PyModule_AddObject(m, "PidTagAddressBookDisplayTypeExtended", PyInt_FromLong(0x8C930003)); PyModule_AddObject(m, "PidTagAddressBookDisplayTypeExtended_Error", PyInt_FromLong(0x8C93000A)); PyModule_AddObject(m, "PidTagAddressBookDistributionListExternalMemberCount", PyInt_FromLong(0x8CE30003)); PyModule_AddObject(m, "PidTagAddressBookDistributionListExternalMemberCount_Error", PyInt_FromLong(0x8CE3000A)); PyModule_AddObject(m, "PidTagAddressBookDistributionListMemberCount", PyInt_FromLong(0x8CE20003)); PyModule_AddObject(m, "PidTagAddressBookDistributionListMemberCount_Error", PyInt_FromLong(0x8CE2000A)); PyModule_AddObject(m, "PidTagAddressBookDistributionListMemberSubmitAccepted", PyInt_FromLong(0x8073000D)); PyModule_AddObject(m, "PidTagAddressBookDistributionListMemberSubmitAccepted_Error", PyInt_FromLong(0x8073000A)); PyModule_AddObject(m, "PidTagAddressBookDistributionListMemberSubmitRejected", PyInt_FromLong(0x8CDA000D)); PyModule_AddObject(m, "PidTagAddressBookDistributionListMemberSubmitRejected_Error", PyInt_FromLong(0x8CDA000A)); PyModule_AddObject(m, "PidTagAddressBookDistributionListRejectMessagesFromDLMembers", PyInt_FromLong(0x8CDB000D)); PyModule_AddObject(m, "PidTagAddressBookDistributionListRejectMessagesFromDLMembers_Error", PyInt_FromLong(0x8CDB000A)); PyModule_AddObject(m, "PidTagAddressBookEntryId", PyInt_FromLong(0x663B0102)); PyModule_AddObject(m, "PidTagAddressBookEntryId_Error", PyInt_FromLong(0x663B000A)); PyModule_AddObject(m, "PidTagAddressBookExtensionAttribute1", PyInt_FromLong(0x802D001F)); PyModule_AddObject(m, "PidTagAddressBookExtensionAttribute15", PyInt_FromLong(0x8C61001F)); PyModule_AddObject(m, "PidTagAddressBookExtensionAttribute15_Error", PyInt_FromLong(0x8C61000A)); PyModule_AddObject(m, "PidTagAddressBookExtensionAttribute1_Error", PyInt_FromLong(0x802D000A)); PyModule_AddObject(m, "PidTagAddressBookFolderPathname", PyInt_FromLong(0x8004001F)); PyModule_AddObject(m, "PidTagAddressBookFolderPathname_Error", PyInt_FromLong(0x8004000A)); PyModule_AddObject(m, "PidTagAddressBookHierarchicalChildDepartments", PyInt_FromLong(0x8C9A000D)); PyModule_AddObject(m, "PidTagAddressBookHierarchicalChildDepartments_Error", PyInt_FromLong(0x8C9A000A)); PyModule_AddObject(m, "PidTagAddressBookHierarchicalDepartmentMembers", PyInt_FromLong(0x8C97000D)); PyModule_AddObject(m, "PidTagAddressBookHierarchicalDepartmentMembers_Error", PyInt_FromLong(0x8C97000A)); PyModule_AddObject(m, "PidTagAddressBookHierarchicalIsHierarchicalGroup", PyInt_FromLong(0x8CDD000B)); PyModule_AddObject(m, "PidTagAddressBookHierarchicalIsHierarchicalGroup_Error", PyInt_FromLong(0x8CDD000A)); PyModule_AddObject(m, "PidTagAddressBookHierarchicalParentDepartment", PyInt_FromLong(0x8C99000D)); PyModule_AddObject(m, "PidTagAddressBookHierarchicalParentDepartment_Error", PyInt_FromLong(0x8C99000A)); PyModule_AddObject(m, "PidTagAddressBookHierarchicalRootDepartment", PyInt_FromLong(0x8C98001E)); PyModule_AddObject(m, "PidTagAddressBookHierarchicalRootDepartment_Error", PyInt_FromLong(0x8C98000A)); PyModule_AddObject(m, "PidTagAddressBookHierarchicalShowInDepartments", PyInt_FromLong(0x8C94000D)); PyModule_AddObject(m, "PidTagAddressBookHierarchicalShowInDepartments_Error", PyInt_FromLong(0x8C94000A)); PyModule_AddObject(m, "PidTagAddressBookHomeMessageDatabase", PyInt_FromLong(0x8006001E)); PyModule_AddObject(m, "PidTagAddressBookHomeMessageDatabase_Error", PyInt_FromLong(0x8006000A)); PyModule_AddObject(m, "PidTagAddressBookIsMaster", PyInt_FromLong(0xFFFB000B)); PyModule_AddObject(m, "PidTagAddressBookIsMaster_Error", PyInt_FromLong(0xFFFB000A)); PyModule_AddObject(m, "PidTagAddressBookIsMemberOfDistributionList", PyInt_FromLong(0x8008101E)); PyModule_AddObject(m, "PidTagAddressBookIsMemberOfDistributionList_Error", PyInt_FromLong(0x8008000A)); PyModule_AddObject(m, "PidTagAddressBookManageDistributionList", PyInt_FromLong(0x6704000D)); PyModule_AddObject(m, "PidTagAddressBookManageDistributionList_Error", PyInt_FromLong(0x6704000A)); PyModule_AddObject(m, "PidTagAddressBookManager", PyInt_FromLong(0x8005000D)); PyModule_AddObject(m, "PidTagAddressBookManagerDistinguishedName", PyInt_FromLong(0x8005001F)); PyModule_AddObject(m, "PidTagAddressBookManager_Error", PyInt_FromLong(0x8005000A)); PyModule_AddObject(m, "PidTagAddressBookMember", PyInt_FromLong(0x8009101E)); PyModule_AddObject(m, "PidTagAddressBookMember_Error", PyInt_FromLong(0x8009000A)); PyModule_AddObject(m, "PidTagAddressBookMessageId", PyInt_FromLong(0x674F0014)); PyModule_AddObject(m, "PidTagAddressBookMessageId_Error", PyInt_FromLong(0x674F000A)); PyModule_AddObject(m, "PidTagAddressBookModerationEnabled", PyInt_FromLong(0x8CB5000B)); PyModule_AddObject(m, "PidTagAddressBookModerationEnabled_Error", PyInt_FromLong(0x8CB5000A)); PyModule_AddObject(m, "PidTagAddressBookNetworkAddress", PyInt_FromLong(0x8170101F)); PyModule_AddObject(m, "PidTagAddressBookNetworkAddress_Error", PyInt_FromLong(0x8170000A)); PyModule_AddObject(m, "PidTagAddressBookObjectDistinguishedName", PyInt_FromLong(0x803C001F)); PyModule_AddObject(m, "PidTagAddressBookObjectDistinguishedName_Error", PyInt_FromLong(0x803C000A)); PyModule_AddObject(m, "PidTagAddressBookObjectGuid", PyInt_FromLong(0x8C6D0102)); PyModule_AddObject(m, "PidTagAddressBookObjectGuid_Error", PyInt_FromLong(0x8C6D000A)); PyModule_AddObject(m, "PidTagAddressBookOrganizationalUnitRootDistinguishedName", PyInt_FromLong(0x8CA8001F)); PyModule_AddObject(m, "PidTagAddressBookOrganizationalUnitRootDistinguishedName_Error", PyInt_FromLong(0x8CA8000A)); PyModule_AddObject(m, "PidTagAddressBookOwner", PyInt_FromLong(0x800C000D)); PyModule_AddObject(m, "PidTagAddressBookOwnerBackLink", PyInt_FromLong(0x8024000D)); PyModule_AddObject(m, "PidTagAddressBookOwnerBackLink_Error", PyInt_FromLong(0x8024000A)); PyModule_AddObject(m, "PidTagAddressBookOwner_Error", PyInt_FromLong(0x800C000A)); PyModule_AddObject(m, "PidTagAddressBookParentEntryId", PyInt_FromLong(0xFFFC0102)); PyModule_AddObject(m, "PidTagAddressBookParentEntryId_Error", PyInt_FromLong(0xFFFC000A)); PyModule_AddObject(m, "PidTagAddressBookPhoneticCompanyName", PyInt_FromLong(0x8C91001F)); PyModule_AddObject(m, "PidTagAddressBookPhoneticCompanyName_Error", PyInt_FromLong(0x8C91000A)); PyModule_AddObject(m, "PidTagAddressBookPhoneticDepartmentName", PyInt_FromLong(0x8C90001F)); PyModule_AddObject(m, "PidTagAddressBookPhoneticDepartmentName_Error", PyInt_FromLong(0x8C90000A)); PyModule_AddObject(m, "PidTagAddressBookPhoneticDisplayName", PyInt_FromLong(0x8C92001F)); PyModule_AddObject(m, "PidTagAddressBookPhoneticDisplayName_Error", PyInt_FromLong(0x8C92000A)); PyModule_AddObject(m, "PidTagAddressBookPhoneticGivenName", PyInt_FromLong(0x8C8E001F)); PyModule_AddObject(m, "PidTagAddressBookPhoneticGivenName_Error", PyInt_FromLong(0x8C8E000A)); PyModule_AddObject(m, "PidTagAddressBookPhoneticSurname", PyInt_FromLong(0x8C8F001F)); PyModule_AddObject(m, "PidTagAddressBookPhoneticSurname_Error", PyInt_FromLong(0x8C8F000A)); PyModule_AddObject(m, "PidTagAddressBookProxyAddresses", PyInt_FromLong(0x800F101F)); PyModule_AddObject(m, "PidTagAddressBookProxyAddresses_Error", PyInt_FromLong(0x800F000A)); PyModule_AddObject(m, "PidTagAddressBookPublicDelegates", PyInt_FromLong(0x8015000D)); PyModule_AddObject(m, "PidTagAddressBookPublicDelegates_Error", PyInt_FromLong(0x8015000A)); PyModule_AddObject(m, "PidTagAddressBookReports", PyInt_FromLong(0x800E000D)); PyModule_AddObject(m, "PidTagAddressBookReports_Error", PyInt_FromLong(0x800E000A)); PyModule_AddObject(m, "PidTagAddressBookRoomCapacity", PyInt_FromLong(0x08070003)); PyModule_AddObject(m, "PidTagAddressBookRoomCapacity_Error", PyInt_FromLong(0x0807000A)); PyModule_AddObject(m, "PidTagAddressBookRoomContainers", PyInt_FromLong(0x8C96101F)); PyModule_AddObject(m, "PidTagAddressBookRoomContainers_Error", PyInt_FromLong(0x8C96000A)); PyModule_AddObject(m, "PidTagAddressBookRoomDescription", PyInt_FromLong(0x0809001F)); PyModule_AddObject(m, "PidTagAddressBookRoomDescription_Error", PyInt_FromLong(0x0809000A)); PyModule_AddObject(m, "PidTagAddressBookSenderHintTranslations", PyInt_FromLong(0x8CAC101F)); PyModule_AddObject(m, "PidTagAddressBookSenderHintTranslations_Error", PyInt_FromLong(0x8CAC000A)); PyModule_AddObject(m, "PidTagAddressBookSeniorityIndex", PyInt_FromLong(0x8CA00003)); PyModule_AddObject(m, "PidTagAddressBookSeniorityIndex_Error", PyInt_FromLong(0x8CA0000A)); PyModule_AddObject(m, "PidTagAddressBookTargetAddress", PyInt_FromLong(0x8011001F)); PyModule_AddObject(m, "PidTagAddressBookTargetAddress_Error", PyInt_FromLong(0x8011000A)); PyModule_AddObject(m, "PidTagAddressBookUnauthorizedSenders", PyInt_FromLong(0x8CD9000D)); PyModule_AddObject(m, "PidTagAddressBookUnauthorizedSenders_Error", PyInt_FromLong(0x8CD9000A)); PyModule_AddObject(m, "PidTagAddressBookX509Certificate", PyInt_FromLong(0x8C6A1102)); PyModule_AddObject(m, "PidTagAddressBookX509Certificate_Error", PyInt_FromLong(0x8C6A000A)); PyModule_AddObject(m, "PidTagAddressType", PyInt_FromLong(0x3002001F)); PyModule_AddObject(m, "PidTagAddressType_Error", PyInt_FromLong(0x3002000A)); PyModule_AddObject(m, "PidTagAlternateRecipientAllowed", PyInt_FromLong(0x0002000B)); PyModule_AddObject(m, "PidTagAlternateRecipientAllowed_Error", PyInt_FromLong(0x0002000A)); PyModule_AddObject(m, "PidTagAnr", PyInt_FromLong(0x360C001F)); PyModule_AddObject(m, "PidTagAnr_Error", PyInt_FromLong(0x360C000A)); PyModule_AddObject(m, "PidTagArchiveDate", PyInt_FromLong(0x301F0040)); PyModule_AddObject(m, "PidTagArchiveDate_Error", PyInt_FromLong(0x301F000A)); PyModule_AddObject(m, "PidTagArchivePeriod", PyInt_FromLong(0x301E0003)); PyModule_AddObject(m, "PidTagArchivePeriod_Error", PyInt_FromLong(0x301E000A)); PyModule_AddObject(m, "PidTagArchiveTag", PyInt_FromLong(0x30180102)); PyModule_AddObject(m, "PidTagArchiveTag_Error", PyInt_FromLong(0x3018000A)); PyModule_AddObject(m, "PidTagAssistant", PyInt_FromLong(0x3A30001F)); PyModule_AddObject(m, "PidTagAssistantTelephoneNumber", PyInt_FromLong(0x3A2E001F)); PyModule_AddObject(m, "PidTagAssistantTelephoneNumber_Error", PyInt_FromLong(0x3A2E000A)); PyModule_AddObject(m, "PidTagAssistant_Error", PyInt_FromLong(0x3A30000A)); PyModule_AddObject(m, "PidTagAssociated", PyInt_FromLong(0x67AA000B)); PyModule_AddObject(m, "PidTagAssociated_Error", PyInt_FromLong(0x67AA000A)); PyModule_AddObject(m, "PidTagAttachAdditionalInformation", PyInt_FromLong(0x370F0102)); PyModule_AddObject(m, "PidTagAttachAdditionalInformation_Error", PyInt_FromLong(0x370F000A)); PyModule_AddObject(m, "PidTagAttachContentBase", PyInt_FromLong(0x3711001F)); PyModule_AddObject(m, "PidTagAttachContentBase_Error", PyInt_FromLong(0x3711000A)); PyModule_AddObject(m, "PidTagAttachContentId", PyInt_FromLong(0x3712001F)); PyModule_AddObject(m, "PidTagAttachContentId_Error", PyInt_FromLong(0x3712000A)); PyModule_AddObject(m, "PidTagAttachContentLocation", PyInt_FromLong(0x3713001F)); PyModule_AddObject(m, "PidTagAttachContentLocation_Error", PyInt_FromLong(0x3713000A)); PyModule_AddObject(m, "PidTagAttachDataBinary", PyInt_FromLong(0x37010102)); PyModule_AddObject(m, "PidTagAttachDataBinary_Error", PyInt_FromLong(0x3701000A)); PyModule_AddObject(m, "PidTagAttachDataObject", PyInt_FromLong(0x3701000D)); PyModule_AddObject(m, "PidTagAttachEncoding", PyInt_FromLong(0x37020102)); PyModule_AddObject(m, "PidTagAttachEncoding_Error", PyInt_FromLong(0x3702000A)); PyModule_AddObject(m, "PidTagAttachExtension", PyInt_FromLong(0x3703001F)); PyModule_AddObject(m, "PidTagAttachExtension_Error", PyInt_FromLong(0x3703000A)); PyModule_AddObject(m, "PidTagAttachFilename", PyInt_FromLong(0x3704001F)); PyModule_AddObject(m, "PidTagAttachFilename_Error", PyInt_FromLong(0x3704000A)); PyModule_AddObject(m, "PidTagAttachFlags", PyInt_FromLong(0x37140003)); PyModule_AddObject(m, "PidTagAttachFlags_Error", PyInt_FromLong(0x3714000A)); PyModule_AddObject(m, "PidTagAttachLongFilename", PyInt_FromLong(0x3707001F)); PyModule_AddObject(m, "PidTagAttachLongFilename_Error", PyInt_FromLong(0x3707000A)); PyModule_AddObject(m, "PidTagAttachLongPathname", PyInt_FromLong(0x370D001F)); PyModule_AddObject(m, "PidTagAttachLongPathname_Error", PyInt_FromLong(0x370D000A)); PyModule_AddObject(m, "PidTagAttachMethod", PyInt_FromLong(0x37050003)); PyModule_AddObject(m, "PidTagAttachMethod_Error", PyInt_FromLong(0x3705000A)); PyModule_AddObject(m, "PidTagAttachMimeTag", PyInt_FromLong(0x370E001F)); PyModule_AddObject(m, "PidTagAttachMimeTag_Error", PyInt_FromLong(0x370E000A)); PyModule_AddObject(m, "PidTagAttachNumber", PyInt_FromLong(0x0E210003)); PyModule_AddObject(m, "PidTagAttachNumber_Error", PyInt_FromLong(0x0E21000A)); PyModule_AddObject(m, "PidTagAttachPathname", PyInt_FromLong(0x3708001F)); PyModule_AddObject(m, "PidTagAttachPathname_Error", PyInt_FromLong(0x3708000A)); PyModule_AddObject(m, "PidTagAttachPayloadClass", PyInt_FromLong(0x371A001F)); PyModule_AddObject(m, "PidTagAttachPayloadClass_Error", PyInt_FromLong(0x371A000A)); PyModule_AddObject(m, "PidTagAttachPayloadProviderGuidString", PyInt_FromLong(0x3719001F)); PyModule_AddObject(m, "PidTagAttachPayloadProviderGuidString_Error", PyInt_FromLong(0x3719000A)); PyModule_AddObject(m, "PidTagAttachRendering", PyInt_FromLong(0x37090102)); PyModule_AddObject(m, "PidTagAttachRendering_Error", PyInt_FromLong(0x3709000A)); PyModule_AddObject(m, "PidTagAttachSize", PyInt_FromLong(0x0E200003)); PyModule_AddObject(m, "PidTagAttachSize_Error", PyInt_FromLong(0x0E20000A)); PyModule_AddObject(m, "PidTagAttachTag", PyInt_FromLong(0x370A0102)); PyModule_AddObject(m, "PidTagAttachTag_Error", PyInt_FromLong(0x370A000A)); PyModule_AddObject(m, "PidTagAttachTransportName", PyInt_FromLong(0x370C001F)); PyModule_AddObject(m, "PidTagAttachTransportName_Error", PyInt_FromLong(0x370C000A)); PyModule_AddObject(m, "PidTagAttachmentContactPhoto", PyInt_FromLong(0x7FFF000B)); PyModule_AddObject(m, "PidTagAttachmentContactPhoto_Error", PyInt_FromLong(0x7FFF000A)); PyModule_AddObject(m, "PidTagAttachmentFlags", PyInt_FromLong(0x7FFD0003)); PyModule_AddObject(m, "PidTagAttachmentFlags_Error", PyInt_FromLong(0x7FFD000A)); PyModule_AddObject(m, "PidTagAttachmentHidden", PyInt_FromLong(0x7FFE000B)); PyModule_AddObject(m, "PidTagAttachmentHidden_Error", PyInt_FromLong(0x7FFE000A)); PyModule_AddObject(m, "PidTagAttachmentLinkId", PyInt_FromLong(0x7FFA0003)); PyModule_AddObject(m, "PidTagAttachmentLinkId_Error", PyInt_FromLong(0x7FFA000A)); PyModule_AddObject(m, "PidTagAttributeHidden", PyInt_FromLong(0x10F4000B)); PyModule_AddObject(m, "PidTagAttributeHidden_Error", PyInt_FromLong(0x10F4000A)); PyModule_AddObject(m, "PidTagAttributeReadOnly", PyInt_FromLong(0x10F6000B)); PyModule_AddObject(m, "PidTagAttributeReadOnly_Error", PyInt_FromLong(0x10F6000A)); PyModule_AddObject(m, "PidTagAttributeSystem", PyInt_FromLong(0x10F5000B)); PyModule_AddObject(m, "PidTagAttributeSystem_Error", PyInt_FromLong(0x10F5000A)); PyModule_AddObject(m, "PidTagAutoForwardComment", PyInt_FromLong(0x0004001F)); PyModule_AddObject(m, "PidTagAutoForwardComment_Error", PyInt_FromLong(0x0004000A)); PyModule_AddObject(m, "PidTagAutoForwarded", PyInt_FromLong(0x0005000B)); PyModule_AddObject(m, "PidTagAutoForwarded_Error", PyInt_FromLong(0x0005000A)); PyModule_AddObject(m, "PidTagAutoResponseSuppress", PyInt_FromLong(0x3FDF0003)); PyModule_AddObject(m, "PidTagAutoResponseSuppress_Error", PyInt_FromLong(0x3FDF000A)); PyModule_AddObject(m, "PidTagBirthday", PyInt_FromLong(0x3A420040)); PyModule_AddObject(m, "PidTagBirthday_Error", PyInt_FromLong(0x3A42000A)); PyModule_AddObject(m, "PidTagBlockStatus", PyInt_FromLong(0x10960003)); PyModule_AddObject(m, "PidTagBlockStatus_Error", PyInt_FromLong(0x1096000A)); PyModule_AddObject(m, "PidTagBody", PyInt_FromLong(0x1000001F)); PyModule_AddObject(m, "PidTagBodyContentId", PyInt_FromLong(0x1015001F)); PyModule_AddObject(m, "PidTagBodyContentId_Error", PyInt_FromLong(0x1015000A)); PyModule_AddObject(m, "PidTagBodyContentLocation", PyInt_FromLong(0x1014001F)); PyModule_AddObject(m, "PidTagBodyContentLocation_Error", PyInt_FromLong(0x1014000A)); PyModule_AddObject(m, "PidTagBodyHtml", PyInt_FromLong(0x1013001F)); PyModule_AddObject(m, "PidTagBodyHtml_Error", PyInt_FromLong(0x1013000A)); PyModule_AddObject(m, "PidTagBody_Error", PyInt_FromLong(0x1000000A)); PyModule_AddObject(m, "PidTagBusiness2TelephoneNumber", PyInt_FromLong(0x3A1B001F)); PyModule_AddObject(m, "PidTagBusiness2TelephoneNumber_Error", PyInt_FromLong(0x3A1B000A)); PyModule_AddObject(m, "PidTagBusiness2TelephoneNumbers", PyInt_FromLong(0x3A1B101F)); PyModule_AddObject(m, "PidTagBusinessFaxNumber", PyInt_FromLong(0x3A24001F)); PyModule_AddObject(m, "PidTagBusinessFaxNumber_Error", PyInt_FromLong(0x3A24000A)); PyModule_AddObject(m, "PidTagBusinessHomePage", PyInt_FromLong(0x3A51001F)); PyModule_AddObject(m, "PidTagBusinessHomePage_Error", PyInt_FromLong(0x3A51000A)); PyModule_AddObject(m, "PidTagBusinessTelephoneNumber", PyInt_FromLong(0x3A08001F)); PyModule_AddObject(m, "PidTagBusinessTelephoneNumber_Error", PyInt_FromLong(0x3A08000A)); PyModule_AddObject(m, "PidTagCallId", PyInt_FromLong(0x6806001F)); PyModule_AddObject(m, "PidTagCallId_Error", PyInt_FromLong(0x6806000A)); PyModule_AddObject(m, "PidTagCallbackTelephoneNumber", PyInt_FromLong(0x3A02001F)); PyModule_AddObject(m, "PidTagCallbackTelephoneNumber_Error", PyInt_FromLong(0x3A02000A)); PyModule_AddObject(m, "PidTagCarTelephoneNumber", PyInt_FromLong(0x3A1E001F)); PyModule_AddObject(m, "PidTagCarTelephoneNumber_Error", PyInt_FromLong(0x3A1E000A)); PyModule_AddObject(m, "PidTagCdoRecurrenceid", PyInt_FromLong(0x10C50040)); PyModule_AddObject(m, "PidTagCdoRecurrenceid_Error", PyInt_FromLong(0x10C5000A)); PyModule_AddObject(m, "PidTagChangeKey", PyInt_FromLong(0x65E20102)); PyModule_AddObject(m, "PidTagChangeKey_Error", PyInt_FromLong(0x65E2000A)); PyModule_AddObject(m, "PidTagChangeNotificationGuid", PyInt_FromLong(0x66370048)); PyModule_AddObject(m, "PidTagChangeNotificationGuid_Error", PyInt_FromLong(0x6637000A)); PyModule_AddObject(m, "PidTagChangeNumber", PyInt_FromLong(0x67A40014)); PyModule_AddObject(m, "PidTagChangeNumber_Error", PyInt_FromLong(0x67A4000A)); PyModule_AddObject(m, "PidTagChildrensNames", PyInt_FromLong(0x3A58101F)); PyModule_AddObject(m, "PidTagChildrensNames_Error", PyInt_FromLong(0x3A58000A)); PyModule_AddObject(m, "PidTagClientActions", PyInt_FromLong(0x66450102)); PyModule_AddObject(m, "PidTagClientActions_Error", PyInt_FromLong(0x6645000A)); PyModule_AddObject(m, "PidTagClientSubmitTime", PyInt_FromLong(0x00390040)); PyModule_AddObject(m, "PidTagClientSubmitTime_Error", PyInt_FromLong(0x0039000A)); PyModule_AddObject(m, "PidTagCnsetRead", PyInt_FromLong(0x67D20102)); PyModule_AddObject(m, "PidTagCnsetRead_Error", PyInt_FromLong(0x67D2000A)); PyModule_AddObject(m, "PidTagCnsetSeen", PyInt_FromLong(0x67960102)); PyModule_AddObject(m, "PidTagCnsetSeenFAI", PyInt_FromLong(0x67DA0102)); PyModule_AddObject(m, "PidTagCnsetSeenFAI_Error", PyInt_FromLong(0x67DA000A)); PyModule_AddObject(m, "PidTagCnsetSeen_Error", PyInt_FromLong(0x6796000A)); PyModule_AddObject(m, "PidTagCodePageId", PyInt_FromLong(0x66C30003)); PyModule_AddObject(m, "PidTagCodePageId_Error", PyInt_FromLong(0x66C3000A)); PyModule_AddObject(m, "PidTagComment", PyInt_FromLong(0x3004001F)); PyModule_AddObject(m, "PidTagComment_Error", PyInt_FromLong(0x3004000A)); PyModule_AddObject(m, "PidTagCompanyMainTelephoneNumber", PyInt_FromLong(0x3A57001F)); PyModule_AddObject(m, "PidTagCompanyMainTelephoneNumber_Error", PyInt_FromLong(0x3A57000A)); PyModule_AddObject(m, "PidTagCompanyName", PyInt_FromLong(0x3A16001F)); PyModule_AddObject(m, "PidTagCompanyName_Error", PyInt_FromLong(0x3A16000A)); PyModule_AddObject(m, "PidTagComputerNetworkName", PyInt_FromLong(0x3A49001F)); PyModule_AddObject(m, "PidTagComputerNetworkName_Error", PyInt_FromLong(0x3A49000A)); PyModule_AddObject(m, "PidTagConflictEntryId", PyInt_FromLong(0x3FF00102)); PyModule_AddObject(m, "PidTagConflictEntryId_Error", PyInt_FromLong(0x3FF0000A)); PyModule_AddObject(m, "PidTagConflictItems", PyInt_FromLong(0x10981102)); PyModule_AddObject(m, "PidTagConflictItems_Error", PyInt_FromLong(0x1098000A)); PyModule_AddObject(m, "PidTagContainerClass", PyInt_FromLong(0x3613001F)); PyModule_AddObject(m, "PidTagContainerClass_Error", PyInt_FromLong(0x3613000A)); PyModule_AddObject(m, "PidTagContainerContents", PyInt_FromLong(0x360F000D)); PyModule_AddObject(m, "PidTagContainerContents_Error", PyInt_FromLong(0x360F000A)); PyModule_AddObject(m, "PidTagContainerFlags", PyInt_FromLong(0x36000003)); PyModule_AddObject(m, "PidTagContainerFlags_Error", PyInt_FromLong(0x3600000A)); PyModule_AddObject(m, "PidTagContainerHierarchy", PyInt_FromLong(0x360E000D)); PyModule_AddObject(m, "PidTagContainerHierarchy_Error", PyInt_FromLong(0x360E000A)); PyModule_AddObject(m, "PidTagContentCount", PyInt_FromLong(0x36020003)); PyModule_AddObject(m, "PidTagContentCount_Error", PyInt_FromLong(0x3602000A)); PyModule_AddObject(m, "PidTagContentFilterPhishingConfidenceLevel", PyInt_FromLong(0x40840003)); PyModule_AddObject(m, "PidTagContentFilterPhishingConfidenceLevel_Error", PyInt_FromLong(0x4084000A)); PyModule_AddObject(m, "PidTagContentFilterSpamConfidenceLevel", PyInt_FromLong(0x40760003)); PyModule_AddObject(m, "PidTagContentFilterSpamConfidenceLevel_Error", PyInt_FromLong(0x4076000A)); PyModule_AddObject(m, "PidTagContentUnreadCount", PyInt_FromLong(0x36030003)); PyModule_AddObject(m, "PidTagContentUnreadCount_Error", PyInt_FromLong(0x3603000A)); PyModule_AddObject(m, "PidTagConversationId", PyInt_FromLong(0x30130102)); PyModule_AddObject(m, "PidTagConversationId_Error", PyInt_FromLong(0x3013000A)); PyModule_AddObject(m, "PidTagConversationIndex", PyInt_FromLong(0x00710102)); PyModule_AddObject(m, "PidTagConversationIndexTracking", PyInt_FromLong(0x3016000B)); PyModule_AddObject(m, "PidTagConversationIndexTracking_Error", PyInt_FromLong(0x3016000A)); PyModule_AddObject(m, "PidTagConversationIndex_Error", PyInt_FromLong(0x0071000A)); PyModule_AddObject(m, "PidTagConversationTopic", PyInt_FromLong(0x0070001F)); PyModule_AddObject(m, "PidTagConversationTopic_Error", PyInt_FromLong(0x0070000A)); PyModule_AddObject(m, "PidTagCountry", PyInt_FromLong(0x3A26001F)); PyModule_AddObject(m, "PidTagCountry_Error", PyInt_FromLong(0x3A26000A)); PyModule_AddObject(m, "PidTagCreationTime", PyInt_FromLong(0x30070040)); PyModule_AddObject(m, "PidTagCreationTime_Error", PyInt_FromLong(0x3007000A)); PyModule_AddObject(m, "PidTagCreatorEntryId", PyInt_FromLong(0x3FF90102)); PyModule_AddObject(m, "PidTagCreatorEntryId_Error", PyInt_FromLong(0x3FF9000A)); PyModule_AddObject(m, "PidTagCreatorName", PyInt_FromLong(0x3FF8001F)); PyModule_AddObject(m, "PidTagCreatorName_Error", PyInt_FromLong(0x3FF8000A)); PyModule_AddObject(m, "PidTagCreatorSimpleDisplayName", PyInt_FromLong(0x4038001F)); PyModule_AddObject(m, "PidTagCreatorSimpleDisplayName_Error", PyInt_FromLong(0x4038000A)); PyModule_AddObject(m, "PidTagCustomerId", PyInt_FromLong(0x3A4A001F)); PyModule_AddObject(m, "PidTagCustomerId_Error", PyInt_FromLong(0x3A4A000A)); PyModule_AddObject(m, "PidTagDamBackPatched", PyInt_FromLong(0x6647000B)); PyModule_AddObject(m, "PidTagDamBackPatched_Error", PyInt_FromLong(0x6647000A)); PyModule_AddObject(m, "PidTagDamOriginalEntryId", PyInt_FromLong(0x66460102)); PyModule_AddObject(m, "PidTagDamOriginalEntryId_Error", PyInt_FromLong(0x6646000A)); PyModule_AddObject(m, "PidTagDefaultPostMessageClass", PyInt_FromLong(0x36E5001F)); PyModule_AddObject(m, "PidTagDefaultPostMessageClass_Error", PyInt_FromLong(0x36E5000A)); PyModule_AddObject(m, "PidTagDeferredActionMessageOriginalEntryId", PyInt_FromLong(0x674100FB)); PyModule_AddObject(m, "PidTagDeferredActionMessageOriginalEntryId_Error", PyInt_FromLong(0x6741000A)); PyModule_AddObject(m, "PidTagDeferredDeliveryTime", PyInt_FromLong(0x000F0040)); PyModule_AddObject(m, "PidTagDeferredDeliveryTime_Error", PyInt_FromLong(0x000F000A)); PyModule_AddObject(m, "PidTagDeferredSendNumber", PyInt_FromLong(0x3FEB0003)); PyModule_AddObject(m, "PidTagDeferredSendNumber_Error", PyInt_FromLong(0x3FEB000A)); PyModule_AddObject(m, "PidTagDeferredSendTime", PyInt_FromLong(0x3FEF0040)); PyModule_AddObject(m, "PidTagDeferredSendTime_Error", PyInt_FromLong(0x3FEF000A)); PyModule_AddObject(m, "PidTagDeferredSendUnits", PyInt_FromLong(0x3FEC0003)); PyModule_AddObject(m, "PidTagDeferredSendUnits_Error", PyInt_FromLong(0x3FEC000A)); PyModule_AddObject(m, "PidTagDelegateFlags", PyInt_FromLong(0x686B1003)); PyModule_AddObject(m, "PidTagDelegateFlags_Error", PyInt_FromLong(0x686B000A)); PyModule_AddObject(m, "PidTagDelegatedByRule", PyInt_FromLong(0x3FE3000B)); PyModule_AddObject(m, "PidTagDelegatedByRule_Error", PyInt_FromLong(0x3FE3000A)); PyModule_AddObject(m, "PidTagDeleteAfterSubmit", PyInt_FromLong(0x0E01000B)); PyModule_AddObject(m, "PidTagDeleteAfterSubmit_Error", PyInt_FromLong(0x0E01000A)); PyModule_AddObject(m, "PidTagDeletedOn", PyInt_FromLong(0x668F0040)); PyModule_AddObject(m, "PidTagDeletedOn_Error", PyInt_FromLong(0x668F000A)); PyModule_AddObject(m, "PidTagDepartmentName", PyInt_FromLong(0x3A18001F)); PyModule_AddObject(m, "PidTagDepartmentName_Error", PyInt_FromLong(0x3A18000A)); PyModule_AddObject(m, "PidTagDepth", PyInt_FromLong(0x30050003)); PyModule_AddObject(m, "PidTagDepth_Error", PyInt_FromLong(0x3005000A)); PyModule_AddObject(m, "PidTagDisplayBcc", PyInt_FromLong(0x0E02001F)); PyModule_AddObject(m, "PidTagDisplayBcc_Error", PyInt_FromLong(0x0E02000A)); PyModule_AddObject(m, "PidTagDisplayCc", PyInt_FromLong(0x0E03001F)); PyModule_AddObject(m, "PidTagDisplayCc_Error", PyInt_FromLong(0x0E03000A)); PyModule_AddObject(m, "PidTagDisplayName", PyInt_FromLong(0x3001001F)); PyModule_AddObject(m, "PidTagDisplayNamePrefix", PyInt_FromLong(0x3A45001F)); PyModule_AddObject(m, "PidTagDisplayNamePrefix_Error", PyInt_FromLong(0x3A45000A)); PyModule_AddObject(m, "PidTagDisplayName_Error", PyInt_FromLong(0x3001000A)); PyModule_AddObject(m, "PidTagDisplayTo", PyInt_FromLong(0x0E04001F)); PyModule_AddObject(m, "PidTagDisplayTo_Error", PyInt_FromLong(0x0E04000A)); PyModule_AddObject(m, "PidTagDisplayType", PyInt_FromLong(0x39000003)); PyModule_AddObject(m, "PidTagDisplayTypeEx", PyInt_FromLong(0x39050003)); PyModule_AddObject(m, "PidTagDisplayTypeEx_Error", PyInt_FromLong(0x3905000A)); PyModule_AddObject(m, "PidTagDisplayType_Error", PyInt_FromLong(0x3900000A)); PyModule_AddObject(m, "PidTagEcWarning", PyInt_FromLong(0x400F0003)); PyModule_AddObject(m, "PidTagEcWarning_Error", PyInt_FromLong(0x400F000A)); PyModule_AddObject(m, "PidTagEmailAddress", PyInt_FromLong(0x3003001F)); PyModule_AddObject(m, "PidTagEmailAddress_Error", PyInt_FromLong(0x3003000A)); PyModule_AddObject(m, "PidTagEndAttach", PyInt_FromLong(0x400E0003)); PyModule_AddObject(m, "PidTagEndAttach_Error", PyInt_FromLong(0x400E000A)); PyModule_AddObject(m, "PidTagEndDate", PyInt_FromLong(0x00610040)); PyModule_AddObject(m, "PidTagEndDate_Error", PyInt_FromLong(0x0061000A)); PyModule_AddObject(m, "PidTagEndEmbed", PyInt_FromLong(0x40020003)); PyModule_AddObject(m, "PidTagEndEmbed_Error", PyInt_FromLong(0x4002000A)); PyModule_AddObject(m, "PidTagEndFolder", PyInt_FromLong(0x400B0003)); PyModule_AddObject(m, "PidTagEndFolder_Error", PyInt_FromLong(0x400B000A)); PyModule_AddObject(m, "PidTagEndMessage", PyInt_FromLong(0x400D0003)); PyModule_AddObject(m, "PidTagEndMessage_Error", PyInt_FromLong(0x400D000A)); PyModule_AddObject(m, "PidTagEndToRecip", PyInt_FromLong(0x40040003)); PyModule_AddObject(m, "PidTagEndToRecip_Error", PyInt_FromLong(0x4004000A)); PyModule_AddObject(m, "PidTagEntryId", PyInt_FromLong(0x0FFF0102)); PyModule_AddObject(m, "PidTagEntryId_Error", PyInt_FromLong(0x0FFF000A)); PyModule_AddObject(m, "PidTagExceptionEndTime", PyInt_FromLong(0x7FFC0040)); PyModule_AddObject(m, "PidTagExceptionEndTime_Error", PyInt_FromLong(0x7FFC000A)); PyModule_AddObject(m, "PidTagExceptionReplaceTime", PyInt_FromLong(0x7FF90040)); PyModule_AddObject(m, "PidTagExceptionReplaceTime_Error", PyInt_FromLong(0x7FF9000A)); PyModule_AddObject(m, "PidTagExceptionStartTime", PyInt_FromLong(0x7FFB0040)); PyModule_AddObject(m, "PidTagExceptionStartTime_Error", PyInt_FromLong(0x7FFB000A)); PyModule_AddObject(m, "PidTagExchangeNTSecurityDescriptor", PyInt_FromLong(0x0E840102)); PyModule_AddObject(m, "PidTagExchangeNTSecurityDescriptor_Error", PyInt_FromLong(0x0E84000A)); PyModule_AddObject(m, "PidTagExpiryNumber", PyInt_FromLong(0x3FED0003)); PyModule_AddObject(m, "PidTagExpiryNumber_Error", PyInt_FromLong(0x3FED000A)); PyModule_AddObject(m, "PidTagExpiryTime", PyInt_FromLong(0x00150040)); PyModule_AddObject(m, "PidTagExpiryTime_Error", PyInt_FromLong(0x0015000A)); PyModule_AddObject(m, "PidTagExpiryUnits", PyInt_FromLong(0x3FEE0003)); PyModule_AddObject(m, "PidTagExpiryUnits_Error", PyInt_FromLong(0x3FEE000A)); PyModule_AddObject(m, "PidTagExtendedFolderFlags", PyInt_FromLong(0x36DA0102)); PyModule_AddObject(m, "PidTagExtendedFolderFlags_Error", PyInt_FromLong(0x36DA000A)); PyModule_AddObject(m, "PidTagExtendedRuleMessageActions", PyInt_FromLong(0x0E990102)); PyModule_AddObject(m, "PidTagExtendedRuleMessageActions_Error", PyInt_FromLong(0x0E99000A)); PyModule_AddObject(m, "PidTagExtendedRuleMessageCondition", PyInt_FromLong(0x0E9A0102)); PyModule_AddObject(m, "PidTagExtendedRuleMessageCondition_Error", PyInt_FromLong(0x0E9A000A)); PyModule_AddObject(m, "PidTagExtendedRuleSizeLimit", PyInt_FromLong(0x0E9B0003)); PyModule_AddObject(m, "PidTagExtendedRuleSizeLimit_Error", PyInt_FromLong(0x0E9B000A)); PyModule_AddObject(m, "PidTagFXDelProp", PyInt_FromLong(0x40160003)); PyModule_AddObject(m, "PidTagFXDelProp_Error", PyInt_FromLong(0x4016000A)); PyModule_AddObject(m, "PidTagFXErrorInfo", PyInt_FromLong(0x40180003)); PyModule_AddObject(m, "PidTagFXErrorInfo_Error", PyInt_FromLong(0x4018000A)); PyModule_AddObject(m, "PidTagFaxNumberOfPages", PyInt_FromLong(0x68040003)); PyModule_AddObject(m, "PidTagFaxNumberOfPages_Error", PyInt_FromLong(0x6804000A)); PyModule_AddObject(m, "PidTagFlagCompleteTime", PyInt_FromLong(0x10910040)); PyModule_AddObject(m, "PidTagFlagCompleteTime_Error", PyInt_FromLong(0x1091000A)); PyModule_AddObject(m, "PidTagFlagStatus", PyInt_FromLong(0x10900003)); PyModule_AddObject(m, "PidTagFlagStatus_Error", PyInt_FromLong(0x1090000A)); PyModule_AddObject(m, "PidTagFlatUrlName", PyInt_FromLong(0x670E001F)); PyModule_AddObject(m, "PidTagFlatUrlName_Error", PyInt_FromLong(0x670E000A)); PyModule_AddObject(m, "PidTagFolderAssociatedContents", PyInt_FromLong(0x3610000D)); PyModule_AddObject(m, "PidTagFolderAssociatedContents_Error", PyInt_FromLong(0x3610000A)); PyModule_AddObject(m, "PidTagFolderId", PyInt_FromLong(0x67480014)); PyModule_AddObject(m, "PidTagFolderId_Error", PyInt_FromLong(0x6748000A)); PyModule_AddObject(m, "PidTagFolderType", PyInt_FromLong(0x36010003)); PyModule_AddObject(m, "PidTagFolderType_Error", PyInt_FromLong(0x3601000A)); PyModule_AddObject(m, "PidTagFollowupIcon", PyInt_FromLong(0x10950003)); PyModule_AddObject(m, "PidTagFollowupIcon_Error", PyInt_FromLong(0x1095000A)); PyModule_AddObject(m, "PidTagFreeBusyCountMonths", PyInt_FromLong(0x68690003)); PyModule_AddObject(m, "PidTagFreeBusyCountMonths_Error", PyInt_FromLong(0x6869000A)); PyModule_AddObject(m, "PidTagFreeBusyEntryIds", PyInt_FromLong(0x36E41102)); PyModule_AddObject(m, "PidTagFreeBusyEntryIds_Error", PyInt_FromLong(0x36E4000A)); PyModule_AddObject(m, "PidTagFreeBusyMessageEmailAddress", PyInt_FromLong(0x6849001F)); PyModule_AddObject(m, "PidTagFreeBusyMessageEmailAddress_Error", PyInt_FromLong(0x6849000A)); PyModule_AddObject(m, "PidTagFreeBusyPublishEnd", PyInt_FromLong(0x68480003)); PyModule_AddObject(m, "PidTagFreeBusyPublishEnd_Error", PyInt_FromLong(0x6848000A)); PyModule_AddObject(m, "PidTagFreeBusyPublishStart", PyInt_FromLong(0x68470003)); PyModule_AddObject(m, "PidTagFreeBusyPublishStart_Error", PyInt_FromLong(0x6847000A)); PyModule_AddObject(m, "PidTagFreeBusyRangeTimestamp", PyInt_FromLong(0x68680040)); PyModule_AddObject(m, "PidTagFreeBusyRangeTimestamp_Error", PyInt_FromLong(0x6868000A)); PyModule_AddObject(m, "PidTagFtpSite", PyInt_FromLong(0x3A4C001F)); PyModule_AddObject(m, "PidTagFtpSite_Error", PyInt_FromLong(0x3A4C000A)); PyModule_AddObject(m, "PidTagGatewayNeedsToRefresh", PyInt_FromLong(0x6846000B)); PyModule_AddObject(m, "PidTagGatewayNeedsToRefresh_Error", PyInt_FromLong(0x6846000A)); PyModule_AddObject(m, "PidTagGender", PyInt_FromLong(0x3A4D0002)); PyModule_AddObject(m, "PidTagGender_Error", PyInt_FromLong(0x3A4D000A)); PyModule_AddObject(m, "PidTagGeneration", PyInt_FromLong(0x3A05001F)); PyModule_AddObject(m, "PidTagGeneration_Error", PyInt_FromLong(0x3A05000A)); PyModule_AddObject(m, "PidTagGivenName", PyInt_FromLong(0x3A06001F)); PyModule_AddObject(m, "PidTagGivenName_Error", PyInt_FromLong(0x3A06000A)); PyModule_AddObject(m, "PidTagGovernmentIdNumber", PyInt_FromLong(0x3A07001F)); PyModule_AddObject(m, "PidTagGovernmentIdNumber_Error", PyInt_FromLong(0x3A07000A)); PyModule_AddObject(m, "PidTagHasAttachments", PyInt_FromLong(0x0E1B000B)); PyModule_AddObject(m, "PidTagHasAttachments_Error", PyInt_FromLong(0x0E1B000A)); PyModule_AddObject(m, "PidTagHasDeferredActionMessages", PyInt_FromLong(0x3FEA000B)); PyModule_AddObject(m, "PidTagHasDeferredActionMessages_Error", PyInt_FromLong(0x3FEA000A)); PyModule_AddObject(m, "PidTagHasNamedProperties", PyInt_FromLong(0x664A000B)); PyModule_AddObject(m, "PidTagHasNamedProperties_Error", PyInt_FromLong(0x664A000A)); PyModule_AddObject(m, "PidTagHasRules", PyInt_FromLong(0x663A000B)); PyModule_AddObject(m, "PidTagHasRules_Error", PyInt_FromLong(0x663A000A)); PyModule_AddObject(m, "PidTagHierarchyChangeNumber", PyInt_FromLong(0x663E0003)); PyModule_AddObject(m, "PidTagHierarchyChangeNumber_Error", PyInt_FromLong(0x663E000A)); PyModule_AddObject(m, "PidTagHobbies", PyInt_FromLong(0x3A43001F)); PyModule_AddObject(m, "PidTagHobbies_Error", PyInt_FromLong(0x3A43000A)); PyModule_AddObject(m, "PidTagHome2TelephoneNumber", PyInt_FromLong(0x3A2F001F)); PyModule_AddObject(m, "PidTagHome2TelephoneNumber_Error", PyInt_FromLong(0x3A2F000A)); PyModule_AddObject(m, "PidTagHome2TelephoneNumbers", PyInt_FromLong(0x3A2F101F)); PyModule_AddObject(m, "PidTagHomeAddressCity", PyInt_FromLong(0x3A59001F)); PyModule_AddObject(m, "PidTagHomeAddressCity_Error", PyInt_FromLong(0x3A59000A)); PyModule_AddObject(m, "PidTagHomeAddressCountry", PyInt_FromLong(0x3A5A001F)); PyModule_AddObject(m, "PidTagHomeAddressCountry_Error", PyInt_FromLong(0x3A5A000A)); PyModule_AddObject(m, "PidTagHomeAddressPostOfficeBox", PyInt_FromLong(0x3A5E001F)); PyModule_AddObject(m, "PidTagHomeAddressPostOfficeBox_Error", PyInt_FromLong(0x3A5E000A)); PyModule_AddObject(m, "PidTagHomeAddressPostalCode", PyInt_FromLong(0x3A5B001F)); PyModule_AddObject(m, "PidTagHomeAddressPostalCode_Error", PyInt_FromLong(0x3A5B000A)); PyModule_AddObject(m, "PidTagHomeAddressStateOrProvince", PyInt_FromLong(0x3A5C001F)); PyModule_AddObject(m, "PidTagHomeAddressStateOrProvince_Error", PyInt_FromLong(0x3A5C000A)); PyModule_AddObject(m, "PidTagHomeAddressStreet", PyInt_FromLong(0x3A5D001F)); PyModule_AddObject(m, "PidTagHomeAddressStreet_Error", PyInt_FromLong(0x3A5D000A)); PyModule_AddObject(m, "PidTagHomeFaxNumber", PyInt_FromLong(0x3A25001F)); PyModule_AddObject(m, "PidTagHomeFaxNumber_Error", PyInt_FromLong(0x3A25000A)); PyModule_AddObject(m, "PidTagHomeTelephoneNumber", PyInt_FromLong(0x3A09001F)); PyModule_AddObject(m, "PidTagHomeTelephoneNumber_Error", PyInt_FromLong(0x3A09000A)); PyModule_AddObject(m, "PidTagHtml", PyInt_FromLong(0x10130102)); PyModule_AddObject(m, "PidTagICalendarEndTime", PyInt_FromLong(0x10C40040)); PyModule_AddObject(m, "PidTagICalendarEndTime_Error", PyInt_FromLong(0x10C4000A)); PyModule_AddObject(m, "PidTagICalendarReminderNextTime", PyInt_FromLong(0x10CA0040)); PyModule_AddObject(m, "PidTagICalendarReminderNextTime_Error", PyInt_FromLong(0x10CA000A)); PyModule_AddObject(m, "PidTagICalendarStartTime", PyInt_FromLong(0x10C30040)); PyModule_AddObject(m, "PidTagICalendarStartTime_Error", PyInt_FromLong(0x10C3000A)); PyModule_AddObject(m, "PidTagIconIndex", PyInt_FromLong(0x10800003)); PyModule_AddObject(m, "PidTagIconIndex_Error", PyInt_FromLong(0x1080000A)); PyModule_AddObject(m, "PidTagIdsetDeleted", PyInt_FromLong(0x67E50102)); PyModule_AddObject(m, "PidTagIdsetDeleted_Error", PyInt_FromLong(0x67E5000A)); PyModule_AddObject(m, "PidTagIdsetExpired", PyInt_FromLong(0x67930102)); PyModule_AddObject(m, "PidTagIdsetExpired_Error", PyInt_FromLong(0x6793000A)); PyModule_AddObject(m, "PidTagIdsetGiven", PyInt_FromLong(0x40170003)); PyModule_AddObject(m, "PidTagIdsetGiven_Error", PyInt_FromLong(0x4017000A)); PyModule_AddObject(m, "PidTagIdsetNoLongerInScope", PyInt_FromLong(0x40210102)); PyModule_AddObject(m, "PidTagIdsetNoLongerInScope_Error", PyInt_FromLong(0x4021000A)); PyModule_AddObject(m, "PidTagIdsetRead", PyInt_FromLong(0x402D0102)); PyModule_AddObject(m, "PidTagIdsetRead_Error", PyInt_FromLong(0x402D000A)); PyModule_AddObject(m, "PidTagIdsetUnread", PyInt_FromLong(0x402E0102)); PyModule_AddObject(m, "PidTagIdsetUnread_Error", PyInt_FromLong(0x402E000A)); PyModule_AddObject(m, "PidTagImapCachedMsgsize", PyInt_FromLong(0x10F00102)); PyModule_AddObject(m, "PidTagImapCachedMsgsize_Error", PyInt_FromLong(0x10F0000A)); PyModule_AddObject(m, "PidTagImportance", PyInt_FromLong(0x00170003)); PyModule_AddObject(m, "PidTagImportance_Error", PyInt_FromLong(0x0017000A)); PyModule_AddObject(m, "PidTagInConflict", PyInt_FromLong(0x666C000B)); PyModule_AddObject(m, "PidTagInConflict_Error", PyInt_FromLong(0x666C000A)); PyModule_AddObject(m, "PidTagInReplyToId", PyInt_FromLong(0x1042001F)); PyModule_AddObject(m, "PidTagInReplyToId_Error", PyInt_FromLong(0x1042000A)); PyModule_AddObject(m, "PidTagIncrSyncChg", PyInt_FromLong(0x40120003)); PyModule_AddObject(m, "PidTagIncrSyncChgPartial", PyInt_FromLong(0x407D0003)); PyModule_AddObject(m, "PidTagIncrSyncChgPartial_Error", PyInt_FromLong(0x407D000A)); PyModule_AddObject(m, "PidTagIncrSyncChg_Error", PyInt_FromLong(0x4012000A)); PyModule_AddObject(m, "PidTagIncrSyncDel", PyInt_FromLong(0x40130003)); PyModule_AddObject(m, "PidTagIncrSyncDel_Error", PyInt_FromLong(0x4013000A)); PyModule_AddObject(m, "PidTagIncrSyncEnd", PyInt_FromLong(0x40140003)); PyModule_AddObject(m, "PidTagIncrSyncEnd_Error", PyInt_FromLong(0x4014000A)); PyModule_AddObject(m, "PidTagIncrSyncGroupId", PyInt_FromLong(0x407C0003)); PyModule_AddObject(m, "PidTagIncrSyncGroupId_Error", PyInt_FromLong(0x407C000A)); PyModule_AddObject(m, "PidTagIncrSyncGroupInfo", PyInt_FromLong(0x407B0102)); PyModule_AddObject(m, "PidTagIncrSyncGroupInfo_Error", PyInt_FromLong(0x407B000A)); PyModule_AddObject(m, "PidTagIncrSyncMessage", PyInt_FromLong(0x40150003)); PyModule_AddObject(m, "PidTagIncrSyncMessage_Error", PyInt_FromLong(0x4015000A)); PyModule_AddObject(m, "PidTagIncrSyncProgressMode", PyInt_FromLong(0x4074000B)); PyModule_AddObject(m, "PidTagIncrSyncProgressMode_Error", PyInt_FromLong(0x4074000A)); PyModule_AddObject(m, "PidTagIncrSyncProgressPerMsg", PyInt_FromLong(0x4075000B)); PyModule_AddObject(m, "PidTagIncrSyncProgressPerMsg_Error", PyInt_FromLong(0x4075000A)); PyModule_AddObject(m, "PidTagIncrSyncRead", PyInt_FromLong(0x402F0003)); PyModule_AddObject(m, "PidTagIncrSyncRead_Error", PyInt_FromLong(0x402F000A)); PyModule_AddObject(m, "PidTagIncrSyncStateBegin", PyInt_FromLong(0x403A0003)); PyModule_AddObject(m, "PidTagIncrSyncStateBegin_Error", PyInt_FromLong(0x403A000A)); PyModule_AddObject(m, "PidTagIncrSyncStateEnd", PyInt_FromLong(0x403B0003)); PyModule_AddObject(m, "PidTagIncrSyncStateEnd_Error", PyInt_FromLong(0x403B000A)); PyModule_AddObject(m, "PidTagIncrementalSyncMessagePartial", PyInt_FromLong(0x407A0003)); PyModule_AddObject(m, "PidTagIncrementalSyncMessagePartial_Error", PyInt_FromLong(0x407A000A)); PyModule_AddObject(m, "PidTagInitialDetailsPane", PyInt_FromLong(0x3F080003)); PyModule_AddObject(m, "PidTagInitialDetailsPane_Error", PyInt_FromLong(0x3F08000A)); PyModule_AddObject(m, "PidTagInitials", PyInt_FromLong(0x3A0A001F)); PyModule_AddObject(m, "PidTagInitials_Error", PyInt_FromLong(0x3A0A000A)); PyModule_AddObject(m, "PidTagInstID", PyInt_FromLong(0x674D0014)); PyModule_AddObject(m, "PidTagInstID_Error", PyInt_FromLong(0x674D000A)); PyModule_AddObject(m, "PidTagInstanceKey", PyInt_FromLong(0x0FF60102)); PyModule_AddObject(m, "PidTagInstanceKey_Error", PyInt_FromLong(0x0FF6000A)); PyModule_AddObject(m, "PidTagInstanceNum", PyInt_FromLong(0x674E0003)); PyModule_AddObject(m, "PidTagInstanceNum_Error", PyInt_FromLong(0x674E000A)); PyModule_AddObject(m, "PidTagInternetArticleNumber", PyInt_FromLong(0x0E230003)); PyModule_AddObject(m, "PidTagInternetArticleNumber_Error", PyInt_FromLong(0x0E23000A)); PyModule_AddObject(m, "PidTagInternetCodepage", PyInt_FromLong(0x3FDE0003)); PyModule_AddObject(m, "PidTagInternetCodepage_Error", PyInt_FromLong(0x3FDE000A)); PyModule_AddObject(m, "PidTagInternetMailOverrideFormat", PyInt_FromLong(0x59020003)); PyModule_AddObject(m, "PidTagInternetMailOverrideFormat_Error", PyInt_FromLong(0x5902000A)); PyModule_AddObject(m, "PidTagInternetMessageId", PyInt_FromLong(0x1035001F)); PyModule_AddObject(m, "PidTagInternetMessageId_Error", PyInt_FromLong(0x1035000A)); PyModule_AddObject(m, "PidTagInternetReferences", PyInt_FromLong(0x1039001F)); PyModule_AddObject(m, "PidTagInternetReferences_Error", PyInt_FromLong(0x1039000A)); PyModule_AddObject(m, "PidTagIpmAppointmentEntryId", PyInt_FromLong(0x36D00102)); PyModule_AddObject(m, "PidTagIpmAppointmentEntryId_Error", PyInt_FromLong(0x36D0000A)); PyModule_AddObject(m, "PidTagIpmContactEntryId", PyInt_FromLong(0x36D10102)); PyModule_AddObject(m, "PidTagIpmContactEntryId_Error", PyInt_FromLong(0x36D1000A)); PyModule_AddObject(m, "PidTagIpmDraftsEntryId", PyInt_FromLong(0x36D70102)); PyModule_AddObject(m, "PidTagIpmDraftsEntryId_Error", PyInt_FromLong(0x36D7000A)); PyModule_AddObject(m, "PidTagIpmJournalEntryId", PyInt_FromLong(0x36D20102)); PyModule_AddObject(m, "PidTagIpmJournalEntryId_Error", PyInt_FromLong(0x36D2000A)); PyModule_AddObject(m, "PidTagIpmNoteEntryId", PyInt_FromLong(0x36D30102)); PyModule_AddObject(m, "PidTagIpmNoteEntryId_Error", PyInt_FromLong(0x36D3000A)); PyModule_AddObject(m, "PidTagIpmTaskEntryId", PyInt_FromLong(0x36D40102)); PyModule_AddObject(m, "PidTagIpmTaskEntryId_Error", PyInt_FromLong(0x36D4000A)); PyModule_AddObject(m, "PidTagIsdnNumber", PyInt_FromLong(0x3A2D001F)); PyModule_AddObject(m, "PidTagIsdnNumber_Error", PyInt_FromLong(0x3A2D000A)); PyModule_AddObject(m, "PidTagJunkAddRecipientsToSafeSendersList", PyInt_FromLong(0x61030003)); PyModule_AddObject(m, "PidTagJunkAddRecipientsToSafeSendersList_Error", PyInt_FromLong(0x6103000A)); PyModule_AddObject(m, "PidTagJunkIncludeContacts", PyInt_FromLong(0x61000003)); PyModule_AddObject(m, "PidTagJunkIncludeContacts_Error", PyInt_FromLong(0x6100000A)); PyModule_AddObject(m, "PidTagJunkPermanentlyDelete", PyInt_FromLong(0x61020003)); PyModule_AddObject(m, "PidTagJunkPermanentlyDelete_Error", PyInt_FromLong(0x6102000A)); PyModule_AddObject(m, "PidTagJunkPhishingEnableLinks", PyInt_FromLong(0x6107000B)); PyModule_AddObject(m, "PidTagJunkPhishingEnableLinks_Error", PyInt_FromLong(0x6107000A)); PyModule_AddObject(m, "PidTagJunkThreshold", PyInt_FromLong(0x61010003)); PyModule_AddObject(m, "PidTagJunkThreshold_Error", PyInt_FromLong(0x6101000A)); PyModule_AddObject(m, "PidTagKeyword", PyInt_FromLong(0x3A0B001F)); PyModule_AddObject(m, "PidTagKeyword_Error", PyInt_FromLong(0x3A0B000A)); PyModule_AddObject(m, "PidTagLanguage", PyInt_FromLong(0x3A0C001F)); PyModule_AddObject(m, "PidTagLanguage_Error", PyInt_FromLong(0x3A0C000A)); PyModule_AddObject(m, "PidTagLastModificationTime", PyInt_FromLong(0x30080040)); PyModule_AddObject(m, "PidTagLastModificationTime_Error", PyInt_FromLong(0x3008000A)); PyModule_AddObject(m, "PidTagLastModifierEntryId", PyInt_FromLong(0x3FFB0102)); PyModule_AddObject(m, "PidTagLastModifierEntryId_Error", PyInt_FromLong(0x3FFB000A)); PyModule_AddObject(m, "PidTagLastModifierName", PyInt_FromLong(0x3FFA001F)); PyModule_AddObject(m, "PidTagLastModifierName_Error", PyInt_FromLong(0x3FFA000A)); PyModule_AddObject(m, "PidTagLastModifierSimpleDisplayName", PyInt_FromLong(0x4039001F)); PyModule_AddObject(m, "PidTagLastModifierSimpleDisplayName_Error", PyInt_FromLong(0x4039000A)); PyModule_AddObject(m, "PidTagLastVerbExecuted", PyInt_FromLong(0x10810003)); PyModule_AddObject(m, "PidTagLastVerbExecuted_Error", PyInt_FromLong(0x1081000A)); PyModule_AddObject(m, "PidTagLastVerbExecutionTime", PyInt_FromLong(0x10820040)); PyModule_AddObject(m, "PidTagLastVerbExecutionTime_Error", PyInt_FromLong(0x1082000A)); PyModule_AddObject(m, "PidTagListHelp", PyInt_FromLong(0x1043001F)); PyModule_AddObject(m, "PidTagListHelp_Error", PyInt_FromLong(0x1043000A)); PyModule_AddObject(m, "PidTagListSubscribe", PyInt_FromLong(0x1044001F)); PyModule_AddObject(m, "PidTagListSubscribe_Error", PyInt_FromLong(0x1044000A)); PyModule_AddObject(m, "PidTagListUnsubscribe", PyInt_FromLong(0x1045001F)); PyModule_AddObject(m, "PidTagListUnsubscribe_Error", PyInt_FromLong(0x1045000A)); PyModule_AddObject(m, "PidTagLocalCommitTime", PyInt_FromLong(0x67090040)); PyModule_AddObject(m, "PidTagLocalCommitTime_Error", PyInt_FromLong(0x6709000A)); PyModule_AddObject(m, "PidTagLocaleId", PyInt_FromLong(0x66A10003)); PyModule_AddObject(m, "PidTagLocaleId_Error", PyInt_FromLong(0x66A1000A)); PyModule_AddObject(m, "PidTagLocality", PyInt_FromLong(0x3A27001F)); PyModule_AddObject(m, "PidTagLocality_Error", PyInt_FromLong(0x3A27000A)); PyModule_AddObject(m, "PidTagLocation", PyInt_FromLong(0x3A0D001F)); PyModule_AddObject(m, "PidTagLocation_Error", PyInt_FromLong(0x3A0D000A)); PyModule_AddObject(m, "PidTagMailboxOwnerEntryId", PyInt_FromLong(0x661B0102)); PyModule_AddObject(m, "PidTagMailboxOwnerEntryId_Error", PyInt_FromLong(0x661B000A)); PyModule_AddObject(m, "PidTagMailboxOwnerName", PyInt_FromLong(0x661C001F)); PyModule_AddObject(m, "PidTagMailboxOwnerName_Error", PyInt_FromLong(0x661C000A)); PyModule_AddObject(m, "PidTagManagerName", PyInt_FromLong(0x3A4E001F)); PyModule_AddObject(m, "PidTagManagerName_Error", PyInt_FromLong(0x3A4E000A)); PyModule_AddObject(m, "PidTagMappingSignature", PyInt_FromLong(0x0FF80102)); PyModule_AddObject(m, "PidTagMappingSignature_Error", PyInt_FromLong(0x0FF8000A)); PyModule_AddObject(m, "PidTagMaximumSubmitMessageSize", PyInt_FromLong(0x666D0003)); PyModule_AddObject(m, "PidTagMaximumSubmitMessageSize_Error", PyInt_FromLong(0x666D000A)); PyModule_AddObject(m, "PidTagMemberId", PyInt_FromLong(0x66710014)); PyModule_AddObject(m, "PidTagMemberId_Error", PyInt_FromLong(0x6671000A)); PyModule_AddObject(m, "PidTagMemberName", PyInt_FromLong(0x6672001F)); PyModule_AddObject(m, "PidTagMemberName_Error", PyInt_FromLong(0x6672000A)); PyModule_AddObject(m, "PidTagMemberRights", PyInt_FromLong(0x66730003)); PyModule_AddObject(m, "PidTagMemberRights_Error", PyInt_FromLong(0x6673000A)); PyModule_AddObject(m, "PidTagMessageAttachments", PyInt_FromLong(0x0E13000D)); PyModule_AddObject(m, "PidTagMessageAttachments_Error", PyInt_FromLong(0x0E13000A)); PyModule_AddObject(m, "PidTagMessageCcMe", PyInt_FromLong(0x0058000B)); PyModule_AddObject(m, "PidTagMessageCcMe_Error", PyInt_FromLong(0x0058000A)); PyModule_AddObject(m, "PidTagMessageClass", PyInt_FromLong(0x001A001F)); PyModule_AddObject(m, "PidTagMessageClass_Error", PyInt_FromLong(0x001A000A)); PyModule_AddObject(m, "PidTagMessageCodepage", PyInt_FromLong(0x3FFD0003)); PyModule_AddObject(m, "PidTagMessageCodepage_Error", PyInt_FromLong(0x3FFD000A)); PyModule_AddObject(m, "PidTagMessageDeliveryTime", PyInt_FromLong(0x0E060040)); PyModule_AddObject(m, "PidTagMessageDeliveryTime_Error", PyInt_FromLong(0x0E06000A)); PyModule_AddObject(m, "PidTagMessageEditorFormat", PyInt_FromLong(0x59090003)); PyModule_AddObject(m, "PidTagMessageEditorFormat_Error", PyInt_FromLong(0x5909000A)); PyModule_AddObject(m, "PidTagMessageFlags", PyInt_FromLong(0x0E070003)); PyModule_AddObject(m, "PidTagMessageFlags_Error", PyInt_FromLong(0x0E07000A)); PyModule_AddObject(m, "PidTagMessageHandlingSystemCommonName", PyInt_FromLong(0x3A0F001F)); PyModule_AddObject(m, "PidTagMessageHandlingSystemCommonName_Error", PyInt_FromLong(0x3A0F000A)); PyModule_AddObject(m, "PidTagMessageLocaleId", PyInt_FromLong(0x3FF10003)); PyModule_AddObject(m, "PidTagMessageLocaleId_Error", PyInt_FromLong(0x3FF1000A)); PyModule_AddObject(m, "PidTagMessageRecipientMe", PyInt_FromLong(0x0059000B)); PyModule_AddObject(m, "PidTagMessageRecipientMe_Error", PyInt_FromLong(0x0059000A)); PyModule_AddObject(m, "PidTagMessageRecipients", PyInt_FromLong(0x0E12000D)); PyModule_AddObject(m, "PidTagMessageRecipients_Error", PyInt_FromLong(0x0E12000A)); PyModule_AddObject(m, "PidTagMessageSize", PyInt_FromLong(0x0E080003)); PyModule_AddObject(m, "PidTagMessageSizeExtended", PyInt_FromLong(0x0E080014)); PyModule_AddObject(m, "PidTagMessageSize_Error", PyInt_FromLong(0x0E08000A)); PyModule_AddObject(m, "PidTagMessageStatus", PyInt_FromLong(0x0E170003)); PyModule_AddObject(m, "PidTagMessageStatus_Error", PyInt_FromLong(0x0E17000A)); PyModule_AddObject(m, "PidTagMessageSubmissionId", PyInt_FromLong(0x00470102)); PyModule_AddObject(m, "PidTagMessageSubmissionId_Error", PyInt_FromLong(0x0047000A)); PyModule_AddObject(m, "PidTagMessageToMe", PyInt_FromLong(0x0057000B)); PyModule_AddObject(m, "PidTagMessageToMe_Error", PyInt_FromLong(0x0057000A)); PyModule_AddObject(m, "PidTagMid", PyInt_FromLong(0x674A0014)); PyModule_AddObject(m, "PidTagMid_Error", PyInt_FromLong(0x674A000A)); PyModule_AddObject(m, "PidTagMiddleName", PyInt_FromLong(0x3A44001F)); PyModule_AddObject(m, "PidTagMiddleName_Error", PyInt_FromLong(0x3A44000A)); PyModule_AddObject(m, "PidTagMimeSkeleton", PyInt_FromLong(0x04700102)); PyModule_AddObject(m, "PidTagMimeSkeleton_Error", PyInt_FromLong(0x0470000A)); PyModule_AddObject(m, "PidTagMobileTelephoneNumber", PyInt_FromLong(0x3A1C001F)); PyModule_AddObject(m, "PidTagMobileTelephoneNumber_Error", PyInt_FromLong(0x3A1C000A)); PyModule_AddObject(m, "PidTagNativeBody", PyInt_FromLong(0x10160003)); PyModule_AddObject(m, "PidTagNativeBody_Error", PyInt_FromLong(0x1016000A)); PyModule_AddObject(m, "PidTagNewAttach", PyInt_FromLong(0x40000003)); PyModule_AddObject(m, "PidTagNewAttach_Error", PyInt_FromLong(0x4000000A)); PyModule_AddObject(m, "PidTagNewFXFolder", PyInt_FromLong(0x40110102)); PyModule_AddObject(m, "PidTagNewFXFolder_Error", PyInt_FromLong(0x4011000A)); PyModule_AddObject(m, "PidTagNextSendAcct", PyInt_FromLong(0x0E29001F)); PyModule_AddObject(m, "PidTagNextSendAcct_Error", PyInt_FromLong(0x0E29000A)); PyModule_AddObject(m, "PidTagNickname", PyInt_FromLong(0x3A4F001F)); PyModule_AddObject(m, "PidTagNickname_Error", PyInt_FromLong(0x3A4F000A)); PyModule_AddObject(m, "PidTagNormalMessageSize", PyInt_FromLong(0x66B30003)); PyModule_AddObject(m, "PidTagNormalMessageSize_Error", PyInt_FromLong(0x66B3000A)); PyModule_AddObject(m, "PidTagNormalizedSubject", PyInt_FromLong(0x0E1D001F)); PyModule_AddObject(m, "PidTagNormalizedSubject_Error", PyInt_FromLong(0x0E1D000A)); PyModule_AddObject(m, "PidTagObjectType", PyInt_FromLong(0x0FFE0003)); PyModule_AddObject(m, "PidTagObjectType_Error", PyInt_FromLong(0x0FFE000A)); PyModule_AddObject(m, "PidTagOfficeLocation", PyInt_FromLong(0x3A19001F)); PyModule_AddObject(m, "PidTagOfficeLocation_Error", PyInt_FromLong(0x3A19000A)); PyModule_AddObject(m, "PidTagOfflineAddressBookCompressedSize", PyInt_FromLong(0x68090003)); PyModule_AddObject(m, "PidTagOfflineAddressBookCompressedSize_Error", PyInt_FromLong(0x6809000A)); PyModule_AddObject(m, "PidTagOfflineAddressBookContainerGuid", PyInt_FromLong(0x6802001E)); PyModule_AddObject(m, "PidTagOfflineAddressBookContainerGuid_Error", PyInt_FromLong(0x6802000A)); PyModule_AddObject(m, "PidTagOfflineAddressBookDistinguishedName", PyInt_FromLong(0x6804001E)); PyModule_AddObject(m, "PidTagOfflineAddressBookFileSize", PyInt_FromLong(0x680A0003)); PyModule_AddObject(m, "PidTagOfflineAddressBookFileSize_Error", PyInt_FromLong(0x680A000A)); PyModule_AddObject(m, "PidTagOfflineAddressBookFileType", PyInt_FromLong(0x68080003)); PyModule_AddObject(m, "PidTagOfflineAddressBookFileType_Error", PyInt_FromLong(0x6808000A)); PyModule_AddObject(m, "PidTagOfflineAddressBookLanguageId", PyInt_FromLong(0x68070003)); PyModule_AddObject(m, "PidTagOfflineAddressBookLanguageId_Error", PyInt_FromLong(0x6807000A)); PyModule_AddObject(m, "PidTagOfflineAddressBookMessageClass", PyInt_FromLong(0x68030003)); PyModule_AddObject(m, "PidTagOfflineAddressBookMessageClass_Error", PyInt_FromLong(0x6803000A)); PyModule_AddObject(m, "PidTagOfflineAddressBookName", PyInt_FromLong(0x6800001F)); PyModule_AddObject(m, "PidTagOfflineAddressBookName_Error", PyInt_FromLong(0x6800000A)); PyModule_AddObject(m, "PidTagOfflineAddressBookSequence", PyInt_FromLong(0x68010003)); PyModule_AddObject(m, "PidTagOfflineAddressBookSequence_Error", PyInt_FromLong(0x6801000A)); PyModule_AddObject(m, "PidTagOfflineAddressBookShaHash", PyInt_FromLong(0x68060102)); PyModule_AddObject(m, "PidTagOfflineAddressBookTruncatedProperties", PyInt_FromLong(0x68051003)); PyModule_AddObject(m, "PidTagOfflineAddressBookTruncatedProperties_Error", PyInt_FromLong(0x6805000A)); PyModule_AddObject(m, "PidTagOrdinalMost", PyInt_FromLong(0x36E20003)); PyModule_AddObject(m, "PidTagOrdinalMost_Error", PyInt_FromLong(0x36E2000A)); PyModule_AddObject(m, "PidTagOrganizationalIdNumber", PyInt_FromLong(0x3A10001F)); PyModule_AddObject(m, "PidTagOrganizationalIdNumber_Error", PyInt_FromLong(0x3A10000A)); PyModule_AddObject(m, "PidTagOriginalDeliveryTime", PyInt_FromLong(0x00550040)); PyModule_AddObject(m, "PidTagOriginalDeliveryTime_Error", PyInt_FromLong(0x0055000A)); PyModule_AddObject(m, "PidTagOriginalDisplayBcc", PyInt_FromLong(0x0072001F)); PyModule_AddObject(m, "PidTagOriginalDisplayBcc_Error", PyInt_FromLong(0x0072000A)); PyModule_AddObject(m, "PidTagOriginalDisplayCc", PyInt_FromLong(0x0073001F)); PyModule_AddObject(m, "PidTagOriginalDisplayCc_Error", PyInt_FromLong(0x0073000A)); PyModule_AddObject(m, "PidTagOriginalDisplayName", PyInt_FromLong(0x3A13001F)); PyModule_AddObject(m, "PidTagOriginalDisplayName_Error", PyInt_FromLong(0x3A13000A)); PyModule_AddObject(m, "PidTagOriginalDisplayTo", PyInt_FromLong(0x0074001F)); PyModule_AddObject(m, "PidTagOriginalDisplayTo_Error", PyInt_FromLong(0x0074000A)); PyModule_AddObject(m, "PidTagOriginalEntryId", PyInt_FromLong(0x3A120102)); PyModule_AddObject(m, "PidTagOriginalEntryId_Error", PyInt_FromLong(0x3A12000A)); PyModule_AddObject(m, "PidTagOriginalMessageClass", PyInt_FromLong(0x004B001F)); PyModule_AddObject(m, "PidTagOriginalMessageClass_Error", PyInt_FromLong(0x004B000A)); PyModule_AddObject(m, "PidTagOriginalMessageId", PyInt_FromLong(0x1046001F)); PyModule_AddObject(m, "PidTagOriginalMessageId_Error", PyInt_FromLong(0x1046000A)); PyModule_AddObject(m, "PidTagOriginalSearchKey", PyInt_FromLong(0x3A140102)); PyModule_AddObject(m, "PidTagOriginalSearchKey_Error", PyInt_FromLong(0x3A14000A)); PyModule_AddObject(m, "PidTagOriginalSenderAddressType", PyInt_FromLong(0x0066001F)); PyModule_AddObject(m, "PidTagOriginalSenderAddressType_Error", PyInt_FromLong(0x0066000A)); PyModule_AddObject(m, "PidTagOriginalSenderEmailAddress", PyInt_FromLong(0x0067001F)); PyModule_AddObject(m, "PidTagOriginalSenderEmailAddress_Error", PyInt_FromLong(0x0067000A)); PyModule_AddObject(m, "PidTagOriginalSenderEntryId", PyInt_FromLong(0x005B0102)); PyModule_AddObject(m, "PidTagOriginalSenderEntryId_Error", PyInt_FromLong(0x005B000A)); PyModule_AddObject(m, "PidTagOriginalSenderName", PyInt_FromLong(0x005A001F)); PyModule_AddObject(m, "PidTagOriginalSenderName_Error", PyInt_FromLong(0x005A000A)); PyModule_AddObject(m, "PidTagOriginalSenderSearchKey", PyInt_FromLong(0x005C0102)); PyModule_AddObject(m, "PidTagOriginalSenderSearchKey_Error", PyInt_FromLong(0x005C000A)); PyModule_AddObject(m, "PidTagOriginalSensitivity", PyInt_FromLong(0x002E0003)); PyModule_AddObject(m, "PidTagOriginalSensitivity_Error", PyInt_FromLong(0x002E000A)); PyModule_AddObject(m, "PidTagOriginalSentRepresentingAddressType", PyInt_FromLong(0x0068001F)); PyModule_AddObject(m, "PidTagOriginalSentRepresentingAddressType_Error", PyInt_FromLong(0x0068000A)); PyModule_AddObject(m, "PidTagOriginalSentRepresentingEmailAddress", PyInt_FromLong(0x0069001F)); PyModule_AddObject(m, "PidTagOriginalSentRepresentingEmailAddress_Error", PyInt_FromLong(0x0069000A)); PyModule_AddObject(m, "PidTagOriginalSentRepresentingEntryId", PyInt_FromLong(0x005E0102)); PyModule_AddObject(m, "PidTagOriginalSentRepresentingEntryId_Error", PyInt_FromLong(0x005E000A)); PyModule_AddObject(m, "PidTagOriginalSentRepresentingName", PyInt_FromLong(0x005D001F)); PyModule_AddObject(m, "PidTagOriginalSentRepresentingName_Error", PyInt_FromLong(0x005D000A)); PyModule_AddObject(m, "PidTagOriginalSentRepresentingSearchKey", PyInt_FromLong(0x005F0102)); PyModule_AddObject(m, "PidTagOriginalSentRepresentingSearchKey_Error", PyInt_FromLong(0x005F000A)); PyModule_AddObject(m, "PidTagOriginalSubject", PyInt_FromLong(0x0049001F)); PyModule_AddObject(m, "PidTagOriginalSubject_Error", PyInt_FromLong(0x0049000A)); PyModule_AddObject(m, "PidTagOriginalSubmitTime", PyInt_FromLong(0x004E0040)); PyModule_AddObject(m, "PidTagOriginalSubmitTime_Error", PyInt_FromLong(0x004E000A)); PyModule_AddObject(m, "PidTagOriginatorDeliveryReportRequested", PyInt_FromLong(0x0023000B)); PyModule_AddObject(m, "PidTagOriginatorDeliveryReportRequested_Error", PyInt_FromLong(0x0023000A)); PyModule_AddObject(m, "PidTagOriginatorNonDeliveryReportRequested", PyInt_FromLong(0x0C08000B)); PyModule_AddObject(m, "PidTagOriginatorNonDeliveryReportRequested_Error", PyInt_FromLong(0x0C08000A)); PyModule_AddObject(m, "PidTagOtherAddressCity", PyInt_FromLong(0x3A5F001F)); PyModule_AddObject(m, "PidTagOtherAddressCity_Error", PyInt_FromLong(0x3A5F000A)); PyModule_AddObject(m, "PidTagOtherAddressCountry", PyInt_FromLong(0x3A60001F)); PyModule_AddObject(m, "PidTagOtherAddressCountry_Error", PyInt_FromLong(0x3A60000A)); PyModule_AddObject(m, "PidTagOtherAddressPostOfficeBox", PyInt_FromLong(0x3A64001F)); PyModule_AddObject(m, "PidTagOtherAddressPostOfficeBox_Error", PyInt_FromLong(0x3A64000A)); PyModule_AddObject(m, "PidTagOtherAddressPostalCode", PyInt_FromLong(0x3A61001F)); PyModule_AddObject(m, "PidTagOtherAddressPostalCode_Error", PyInt_FromLong(0x3A61000A)); PyModule_AddObject(m, "PidTagOtherAddressStateOrProvince", PyInt_FromLong(0x3A62001F)); PyModule_AddObject(m, "PidTagOtherAddressStateOrProvince_Error", PyInt_FromLong(0x3A62000A)); PyModule_AddObject(m, "PidTagOtherAddressStreet", PyInt_FromLong(0x3A63001F)); PyModule_AddObject(m, "PidTagOtherAddressStreet_Error", PyInt_FromLong(0x3A63000A)); PyModule_AddObject(m, "PidTagOtherTelephoneNumber", PyInt_FromLong(0x3A1F001F)); PyModule_AddObject(m, "PidTagOtherTelephoneNumber_Error", PyInt_FromLong(0x3A1F000A)); PyModule_AddObject(m, "PidTagOutOfOfficeState", PyInt_FromLong(0x661D000B)); PyModule_AddObject(m, "PidTagOutOfOfficeState_Error", PyInt_FromLong(0x661D000A)); PyModule_AddObject(m, "PidTagOwnerAppointmentId", PyInt_FromLong(0x00620003)); PyModule_AddObject(m, "PidTagOwnerAppointmentId_Error", PyInt_FromLong(0x0062000A)); PyModule_AddObject(m, "PidTagPagerTelephoneNumber", PyInt_FromLong(0x3A21001F)); PyModule_AddObject(m, "PidTagPagerTelephoneNumber_Error", PyInt_FromLong(0x3A21000A)); PyModule_AddObject(m, "PidTagParentEntryId", PyInt_FromLong(0x0E090102)); PyModule_AddObject(m, "PidTagParentEntryId_Error", PyInt_FromLong(0x0E09000A)); PyModule_AddObject(m, "PidTagParentFolderId", PyInt_FromLong(0x67490014)); PyModule_AddObject(m, "PidTagParentFolderId_Error", PyInt_FromLong(0x6749000A)); PyModule_AddObject(m, "PidTagParentKey", PyInt_FromLong(0x00250102)); PyModule_AddObject(m, "PidTagParentKey_Error", PyInt_FromLong(0x0025000A)); PyModule_AddObject(m, "PidTagParentSourceKey", PyInt_FromLong(0x65E10102)); PyModule_AddObject(m, "PidTagParentSourceKey_Error", PyInt_FromLong(0x65E1000A)); PyModule_AddObject(m, "PidTagPersonalHomePage", PyInt_FromLong(0x3A50001F)); PyModule_AddObject(m, "PidTagPersonalHomePage_Error", PyInt_FromLong(0x3A50000A)); PyModule_AddObject(m, "PidTagPolicyTag", PyInt_FromLong(0x30190102)); PyModule_AddObject(m, "PidTagPolicyTag_Error", PyInt_FromLong(0x3019000A)); PyModule_AddObject(m, "PidTagPostOfficeBox", PyInt_FromLong(0x3A2B001F)); PyModule_AddObject(m, "PidTagPostOfficeBox_Error", PyInt_FromLong(0x3A2B000A)); PyModule_AddObject(m, "PidTagPostalAddress", PyInt_FromLong(0x3A15001F)); PyModule_AddObject(m, "PidTagPostalAddress_Error", PyInt_FromLong(0x3A15000A)); PyModule_AddObject(m, "PidTagPostalCode", PyInt_FromLong(0x3A2A001F)); PyModule_AddObject(m, "PidTagPostalCode_Error", PyInt_FromLong(0x3A2A000A)); PyModule_AddObject(m, "PidTagPredecessorChangeList", PyInt_FromLong(0x65E30102)); PyModule_AddObject(m, "PidTagPredecessorChangeList_Error", PyInt_FromLong(0x65E3000A)); PyModule_AddObject(m, "PidTagPrimaryFaxNumber", PyInt_FromLong(0x3A23001F)); PyModule_AddObject(m, "PidTagPrimaryFaxNumber_Error", PyInt_FromLong(0x3A23000A)); PyModule_AddObject(m, "PidTagPrimarySendAccount", PyInt_FromLong(0x0E28001F)); PyModule_AddObject(m, "PidTagPrimarySendAccount_Error", PyInt_FromLong(0x0E28000A)); PyModule_AddObject(m, "PidTagPrimarySmtpAddress", PyInt_FromLong(0x39FE001F)); PyModule_AddObject(m, "PidTagPrimarySmtpAddress_Error", PyInt_FromLong(0x39FE000A)); PyModule_AddObject(m, "PidTagPrimaryTelephoneNumber", PyInt_FromLong(0x3A1A001F)); PyModule_AddObject(m, "PidTagPrimaryTelephoneNumber_Error", PyInt_FromLong(0x3A1A000A)); PyModule_AddObject(m, "PidTagPriority", PyInt_FromLong(0x00260003)); PyModule_AddObject(m, "PidTagPriority_Error", PyInt_FromLong(0x0026000A)); PyModule_AddObject(m, "PidTagProcessed", PyInt_FromLong(0x7D01000B)); PyModule_AddObject(m, "PidTagProcessed_Error", PyInt_FromLong(0x7D01000A)); PyModule_AddObject(m, "PidTagProfession", PyInt_FromLong(0x3A46001F)); PyModule_AddObject(m, "PidTagProfession_Error", PyInt_FromLong(0x3A46000A)); PyModule_AddObject(m, "PidTagProhibitReceiveQuota", PyInt_FromLong(0x666A0003)); PyModule_AddObject(m, "PidTagProhibitReceiveQuota_Error", PyInt_FromLong(0x666A000A)); PyModule_AddObject(m, "PidTagProhibitSendQuota", PyInt_FromLong(0x666E0003)); PyModule_AddObject(m, "PidTagProhibitSendQuota_Error", PyInt_FromLong(0x666E000A)); PyModule_AddObject(m, "PidTagProviderSubmitTime", PyInt_FromLong(0x00480040)); PyModule_AddObject(m, "PidTagProviderSubmitTime_Error", PyInt_FromLong(0x0048000A)); PyModule_AddObject(m, "PidTagPublicFolderAdministrativeDescription", PyInt_FromLong(0x671C001F)); PyModule_AddObject(m, "PidTagPublicFolderAdministrativeDescription_Error", PyInt_FromLong(0x671C000A)); PyModule_AddObject(m, "PidTagPublicFolderProxy", PyInt_FromLong(0x671D0102)); PyModule_AddObject(m, "PidTagPublicFolderProxy_Error", PyInt_FromLong(0x671D000A)); PyModule_AddObject(m, "PidTagPurportedSenderDomain", PyInt_FromLong(0x4083001F)); PyModule_AddObject(m, "PidTagPurportedSenderDomain_Error", PyInt_FromLong(0x4083000A)); PyModule_AddObject(m, "PidTagRadioTelephoneNumber", PyInt_FromLong(0x3A1D001F)); PyModule_AddObject(m, "PidTagRadioTelephoneNumber_Error", PyInt_FromLong(0x3A1D000A)); PyModule_AddObject(m, "PidTagRead", PyInt_FromLong(0x0E69000B)); PyModule_AddObject(m, "PidTagReadReceiptAddressType", PyInt_FromLong(0x4029001F)); PyModule_AddObject(m, "PidTagReadReceiptAddressType_Error", PyInt_FromLong(0x4029000A)); PyModule_AddObject(m, "PidTagReadReceiptEmailAddress", PyInt_FromLong(0x402A001F)); PyModule_AddObject(m, "PidTagReadReceiptEmailAddress_Error", PyInt_FromLong(0x402A000A)); PyModule_AddObject(m, "PidTagReadReceiptEntryId", PyInt_FromLong(0x00460102)); PyModule_AddObject(m, "PidTagReadReceiptEntryId_Error", PyInt_FromLong(0x0046000A)); PyModule_AddObject(m, "PidTagReadReceiptName", PyInt_FromLong(0x402B001F)); PyModule_AddObject(m, "PidTagReadReceiptName_Error", PyInt_FromLong(0x402B000A)); PyModule_AddObject(m, "PidTagReadReceiptRequested", PyInt_FromLong(0x0029000B)); PyModule_AddObject(m, "PidTagReadReceiptRequested_Error", PyInt_FromLong(0x0029000A)); PyModule_AddObject(m, "PidTagReadReceiptSearchKey", PyInt_FromLong(0x00530102)); PyModule_AddObject(m, "PidTagReadReceiptSearchKey_Error", PyInt_FromLong(0x0053000A)); PyModule_AddObject(m, "PidTagRead_Error", PyInt_FromLong(0x0E69000A)); PyModule_AddObject(m, "PidTagReceivedByAddressType", PyInt_FromLong(0x0075001F)); PyModule_AddObject(m, "PidTagReceivedByAddressType_Error", PyInt_FromLong(0x0075000A)); PyModule_AddObject(m, "PidTagReceivedByEmailAddress", PyInt_FromLong(0x0076001F)); PyModule_AddObject(m, "PidTagReceivedByEmailAddress_Error", PyInt_FromLong(0x0076000A)); PyModule_AddObject(m, "PidTagReceivedByEntryId", PyInt_FromLong(0x003F0102)); PyModule_AddObject(m, "PidTagReceivedByEntryId_Error", PyInt_FromLong(0x003F000A)); PyModule_AddObject(m, "PidTagReceivedByFlags", PyInt_FromLong(0x401B0003)); PyModule_AddObject(m, "PidTagReceivedByFlags_Error", PyInt_FromLong(0x401B000A)); PyModule_AddObject(m, "PidTagReceivedByName", PyInt_FromLong(0x0040001F)); PyModule_AddObject(m, "PidTagReceivedByName_Error", PyInt_FromLong(0x0040000A)); PyModule_AddObject(m, "PidTagReceivedBySearchKey", PyInt_FromLong(0x00510102)); PyModule_AddObject(m, "PidTagReceivedBySearchKey_Error", PyInt_FromLong(0x0051000A)); PyModule_AddObject(m, "PidTagReceivedRepresentingAddressType", PyInt_FromLong(0x0077001F)); PyModule_AddObject(m, "PidTagReceivedRepresentingAddressType_Error", PyInt_FromLong(0x0077000A)); PyModule_AddObject(m, "PidTagReceivedRepresentingEmailAddress", PyInt_FromLong(0x0078001F)); PyModule_AddObject(m, "PidTagReceivedRepresentingEmailAddress_Error", PyInt_FromLong(0x0078000A)); PyModule_AddObject(m, "PidTagReceivedRepresentingEntryId", PyInt_FromLong(0x00430102)); PyModule_AddObject(m, "PidTagReceivedRepresentingEntryId_Error", PyInt_FromLong(0x0043000A)); PyModule_AddObject(m, "PidTagReceivedRepresentingFlags", PyInt_FromLong(0x401C0003)); PyModule_AddObject(m, "PidTagReceivedRepresentingFlags_Error", PyInt_FromLong(0x401C000A)); PyModule_AddObject(m, "PidTagReceivedRepresentingName", PyInt_FromLong(0x0044001F)); PyModule_AddObject(m, "PidTagReceivedRepresentingName_Error", PyInt_FromLong(0x0044000A)); PyModule_AddObject(m, "PidTagReceivedRepresentingSearchKey", PyInt_FromLong(0x00520102)); PyModule_AddObject(m, "PidTagReceivedRepresentingSearchKey_Error", PyInt_FromLong(0x0052000A)); PyModule_AddObject(m, "PidTagReceivedRepresentingSimpleDisplayName", PyInt_FromLong(0x4035001F)); PyModule_AddObject(m, "PidTagReceivedRepresentingSimpleDisplayName_Error", PyInt_FromLong(0x4035000A)); PyModule_AddObject(m, "PidTagRecipientDisplayName", PyInt_FromLong(0x5FF6001F)); PyModule_AddObject(m, "PidTagRecipientDisplayName_Error", PyInt_FromLong(0x5FF6000A)); PyModule_AddObject(m, "PidTagRecipientEntryId", PyInt_FromLong(0x5FF70102)); PyModule_AddObject(m, "PidTagRecipientEntryId_Error", PyInt_FromLong(0x5FF7000A)); PyModule_AddObject(m, "PidTagRecipientFlags", PyInt_FromLong(0x5FFD0003)); PyModule_AddObject(m, "PidTagRecipientFlags_Error", PyInt_FromLong(0x5FFD000A)); PyModule_AddObject(m, "PidTagRecipientOrder", PyInt_FromLong(0x5FDF0003)); PyModule_AddObject(m, "PidTagRecipientOrder_Error", PyInt_FromLong(0x5FDF000A)); PyModule_AddObject(m, "PidTagRecipientProposed", PyInt_FromLong(0x5FE1000B)); PyModule_AddObject(m, "PidTagRecipientProposedEndTime", PyInt_FromLong(0x5FE40040)); PyModule_AddObject(m, "PidTagRecipientProposedEndTime_Error", PyInt_FromLong(0x5FE4000A)); PyModule_AddObject(m, "PidTagRecipientProposedStartTime", PyInt_FromLong(0x5FE30040)); PyModule_AddObject(m, "PidTagRecipientProposedStartTime_Error", PyInt_FromLong(0x5FE3000A)); PyModule_AddObject(m, "PidTagRecipientProposed_Error", PyInt_FromLong(0x5FE1000A)); PyModule_AddObject(m, "PidTagRecipientReassignmentProhibited", PyInt_FromLong(0x002B000B)); PyModule_AddObject(m, "PidTagRecipientReassignmentProhibited_Error", PyInt_FromLong(0x002B000A)); PyModule_AddObject(m, "PidTagRecipientResourceState", PyInt_FromLong(0x5FDE0003)); PyModule_AddObject(m, "PidTagRecipientResourceState_Error", PyInt_FromLong(0x5FDE000A)); PyModule_AddObject(m, "PidTagRecipientTrackStatus", PyInt_FromLong(0x5FFF0003)); PyModule_AddObject(m, "PidTagRecipientTrackStatusTime", PyInt_FromLong(0x5FFB0040)); PyModule_AddObject(m, "PidTagRecipientTrackStatusTime_Error", PyInt_FromLong(0x5FFB000A)); PyModule_AddObject(m, "PidTagRecipientTrackStatus_Error", PyInt_FromLong(0x5FFF000A)); PyModule_AddObject(m, "PidTagRecipientType", PyInt_FromLong(0x0C150003)); PyModule_AddObject(m, "PidTagRecipientType_Error", PyInt_FromLong(0x0C15000A)); PyModule_AddObject(m, "PidTagRecordKey", PyInt_FromLong(0x0FF90102)); PyModule_AddObject(m, "PidTagRecordKey_Error", PyInt_FromLong(0x0FF9000A)); PyModule_AddObject(m, "PidTagReferredByName", PyInt_FromLong(0x3A47001F)); PyModule_AddObject(m, "PidTagReferredByName_Error", PyInt_FromLong(0x3A47000A)); PyModule_AddObject(m, "PidTagRemindersOnlineEntryId", PyInt_FromLong(0x36D50102)); PyModule_AddObject(m, "PidTagRemindersOnlineEntryId_Error", PyInt_FromLong(0x36D5000A)); PyModule_AddObject(m, "PidTagRemoteMessageTransferAgent", PyInt_FromLong(0x0C21001F)); PyModule_AddObject(m, "PidTagRemoteMessageTransferAgent_Error", PyInt_FromLong(0x0C21000A)); PyModule_AddObject(m, "PidTagRenderingPosition", PyInt_FromLong(0x370B0003)); PyModule_AddObject(m, "PidTagRenderingPosition_Error", PyInt_FromLong(0x370B000A)); PyModule_AddObject(m, "PidTagReplyRecipientEntries", PyInt_FromLong(0x004F0102)); PyModule_AddObject(m, "PidTagReplyRecipientEntries_Error", PyInt_FromLong(0x004F000A)); PyModule_AddObject(m, "PidTagReplyRecipientNames", PyInt_FromLong(0x0050001F)); PyModule_AddObject(m, "PidTagReplyRecipientNames_Error", PyInt_FromLong(0x0050000A)); PyModule_AddObject(m, "PidTagReplyRequested", PyInt_FromLong(0x0C17000B)); PyModule_AddObject(m, "PidTagReplyRequested_Error", PyInt_FromLong(0x0C17000A)); PyModule_AddObject(m, "PidTagReplyTemplateId", PyInt_FromLong(0x65C20102)); PyModule_AddObject(m, "PidTagReplyTemplateId_Error", PyInt_FromLong(0x65C2000A)); PyModule_AddObject(m, "PidTagReplyTime", PyInt_FromLong(0x00300040)); PyModule_AddObject(m, "PidTagReplyTime_Error", PyInt_FromLong(0x0030000A)); PyModule_AddObject(m, "PidTagReportEntryId", PyInt_FromLong(0x00450102)); PyModule_AddObject(m, "PidTagReportEntryId_Error", PyInt_FromLong(0x0045000A)); PyModule_AddObject(m, "PidTagReportName", PyInt_FromLong(0x003A001F)); PyModule_AddObject(m, "PidTagReportName_Error", PyInt_FromLong(0x003A000A)); PyModule_AddObject(m, "PidTagReportSearchKey", PyInt_FromLong(0x00540102)); PyModule_AddObject(m, "PidTagReportSearchKey_Error", PyInt_FromLong(0x0054000A)); PyModule_AddObject(m, "PidTagReportTag", PyInt_FromLong(0x00310102)); PyModule_AddObject(m, "PidTagReportTag_Error", PyInt_FromLong(0x0031000A)); PyModule_AddObject(m, "PidTagReportText", PyInt_FromLong(0x1001001F)); PyModule_AddObject(m, "PidTagReportText_Error", PyInt_FromLong(0x1001000A)); PyModule_AddObject(m, "PidTagReportTime", PyInt_FromLong(0x00320040)); PyModule_AddObject(m, "PidTagReportTime_Error", PyInt_FromLong(0x0032000A)); PyModule_AddObject(m, "PidTagReportingMessageTransferAgent", PyInt_FromLong(0x6820001F)); PyModule_AddObject(m, "PidTagReportingMessageTransferAgent_Error", PyInt_FromLong(0x6820000A)); PyModule_AddObject(m, "PidTagResolveMethod", PyInt_FromLong(0x3FE70003)); PyModule_AddObject(m, "PidTagResolveMethod_Error", PyInt_FromLong(0x3FE7000A)); PyModule_AddObject(m, "PidTagResponseRequested", PyInt_FromLong(0x0063000B)); PyModule_AddObject(m, "PidTagResponseRequested_Error", PyInt_FromLong(0x0063000A)); PyModule_AddObject(m, "PidTagResponsibility", PyInt_FromLong(0x0E0F000B)); PyModule_AddObject(m, "PidTagResponsibility_Error", PyInt_FromLong(0x0E0F000A)); PyModule_AddObject(m, "PidTagRetentionDate", PyInt_FromLong(0x301C0040)); PyModule_AddObject(m, "PidTagRetentionDate_Error", PyInt_FromLong(0x301C000A)); PyModule_AddObject(m, "PidTagRetentionFlags", PyInt_FromLong(0x301D0003)); PyModule_AddObject(m, "PidTagRetentionFlags_Error", PyInt_FromLong(0x301D000A)); PyModule_AddObject(m, "PidTagRetentionPeriod", PyInt_FromLong(0x301A0003)); PyModule_AddObject(m, "PidTagRetentionPeriod_Error", PyInt_FromLong(0x301A000A)); PyModule_AddObject(m, "PidTagRights", PyInt_FromLong(0x66390003)); PyModule_AddObject(m, "PidTagRights_Error", PyInt_FromLong(0x6639000A)); PyModule_AddObject(m, "PidTagRoamingDatatypes", PyInt_FromLong(0x7C060003)); PyModule_AddObject(m, "PidTagRoamingDatatypes_Error", PyInt_FromLong(0x7C06000A)); PyModule_AddObject(m, "PidTagRoamingDictionary", PyInt_FromLong(0x7C070102)); PyModule_AddObject(m, "PidTagRoamingDictionary_Error", PyInt_FromLong(0x7C07000A)); PyModule_AddObject(m, "PidTagRoamingXmlStream", PyInt_FromLong(0x7C080102)); PyModule_AddObject(m, "PidTagRoamingXmlStream_Error", PyInt_FromLong(0x7C08000A)); PyModule_AddObject(m, "PidTagRowType", PyInt_FromLong(0x0FF50003)); PyModule_AddObject(m, "PidTagRowType_Error", PyInt_FromLong(0x0FF5000A)); PyModule_AddObject(m, "PidTagRowid", PyInt_FromLong(0x30000003)); PyModule_AddObject(m, "PidTagRowid_Error", PyInt_FromLong(0x3000000A)); PyModule_AddObject(m, "PidTagRtfCompressed", PyInt_FromLong(0x10090102)); PyModule_AddObject(m, "PidTagRtfCompressed_Error", PyInt_FromLong(0x1009000A)); PyModule_AddObject(m, "PidTagRtfInSync", PyInt_FromLong(0x0E1F000B)); PyModule_AddObject(m, "PidTagRtfInSync_Error", PyInt_FromLong(0x0E1F000A)); PyModule_AddObject(m, "PidTagRtfSyncBodyCount", PyInt_FromLong(0x10070003)); PyModule_AddObject(m, "PidTagRtfSyncBodyCount_Error", PyInt_FromLong(0x1007000A)); PyModule_AddObject(m, "PidTagRtfSyncBodyCrc", PyInt_FromLong(0x10060003)); PyModule_AddObject(m, "PidTagRtfSyncBodyCrc_Error", PyInt_FromLong(0x1006000A)); PyModule_AddObject(m, "PidTagRtfSyncBodyTag", PyInt_FromLong(0x1008001F)); PyModule_AddObject(m, "PidTagRtfSyncBodyTag_Error", PyInt_FromLong(0x1008000A)); PyModule_AddObject(m, "PidTagRtfSyncPrefixCount", PyInt_FromLong(0x10100003)); PyModule_AddObject(m, "PidTagRtfSyncPrefixCount_Error", PyInt_FromLong(0x1010000A)); PyModule_AddObject(m, "PidTagRtfSyncTrailingCount", PyInt_FromLong(0x10110003)); PyModule_AddObject(m, "PidTagRtfSyncTrailingCount_Error", PyInt_FromLong(0x1011000A)); PyModule_AddObject(m, "PidTagRuleActionNumber", PyInt_FromLong(0x66500003)); PyModule_AddObject(m, "PidTagRuleActionNumber_Error", PyInt_FromLong(0x6650000A)); PyModule_AddObject(m, "PidTagRuleActionType", PyInt_FromLong(0x66490003)); PyModule_AddObject(m, "PidTagRuleActionType_Error", PyInt_FromLong(0x6649000A)); PyModule_AddObject(m, "PidTagRuleActions", PyInt_FromLong(0x668000FE)); PyModule_AddObject(m, "PidTagRuleActions_Error", PyInt_FromLong(0x6680000A)); PyModule_AddObject(m, "PidTagRuleCondition", PyInt_FromLong(0x667900FD)); PyModule_AddObject(m, "PidTagRuleCondition_Error", PyInt_FromLong(0x6679000A)); PyModule_AddObject(m, "PidTagRuleError", PyInt_FromLong(0x66480003)); PyModule_AddObject(m, "PidTagRuleError_Error", PyInt_FromLong(0x6648000A)); PyModule_AddObject(m, "PidTagRuleFolderEntryId", PyInt_FromLong(0x66510102)); PyModule_AddObject(m, "PidTagRuleFolderEntryId_Error", PyInt_FromLong(0x6651000A)); PyModule_AddObject(m, "PidTagRuleId", PyInt_FromLong(0x66740014)); PyModule_AddObject(m, "PidTagRuleId_Error", PyInt_FromLong(0x6674000A)); PyModule_AddObject(m, "PidTagRuleIds", PyInt_FromLong(0x66750102)); PyModule_AddObject(m, "PidTagRuleIds_Error", PyInt_FromLong(0x6675000A)); PyModule_AddObject(m, "PidTagRuleLevel", PyInt_FromLong(0x66830003)); PyModule_AddObject(m, "PidTagRuleLevel_Error", PyInt_FromLong(0x6683000A)); PyModule_AddObject(m, "PidTagRuleMessageLevel", PyInt_FromLong(0x65ED0003)); PyModule_AddObject(m, "PidTagRuleMessageLevel_Error", PyInt_FromLong(0x65ED000A)); PyModule_AddObject(m, "PidTagRuleMessageName", PyInt_FromLong(0x65EC001F)); PyModule_AddObject(m, "PidTagRuleMessageName_Error", PyInt_FromLong(0x65EC000A)); PyModule_AddObject(m, "PidTagRuleMessageProvider", PyInt_FromLong(0x65EB001F)); PyModule_AddObject(m, "PidTagRuleMessageProviderData", PyInt_FromLong(0x65EE0102)); PyModule_AddObject(m, "PidTagRuleMessageProviderData_Error", PyInt_FromLong(0x65EE000A)); PyModule_AddObject(m, "PidTagRuleMessageProvider_Error", PyInt_FromLong(0x65EB000A)); PyModule_AddObject(m, "PidTagRuleMessageSequence", PyInt_FromLong(0x65F30003)); PyModule_AddObject(m, "PidTagRuleMessageSequence_Error", PyInt_FromLong(0x65F3000A)); PyModule_AddObject(m, "PidTagRuleMessageState", PyInt_FromLong(0x65E90003)); PyModule_AddObject(m, "PidTagRuleMessageState_Error", PyInt_FromLong(0x65E9000A)); PyModule_AddObject(m, "PidTagRuleMessageUserFlags", PyInt_FromLong(0x65EA0003)); PyModule_AddObject(m, "PidTagRuleMessageUserFlags_Error", PyInt_FromLong(0x65EA000A)); PyModule_AddObject(m, "PidTagRuleName", PyInt_FromLong(0x6682001F)); PyModule_AddObject(m, "PidTagRuleName_Error", PyInt_FromLong(0x6682000A)); PyModule_AddObject(m, "PidTagRuleProvider", PyInt_FromLong(0x6681001F)); PyModule_AddObject(m, "PidTagRuleProviderData", PyInt_FromLong(0x66840102)); PyModule_AddObject(m, "PidTagRuleProviderData_Error", PyInt_FromLong(0x6684000A)); PyModule_AddObject(m, "PidTagRuleProvider_Error", PyInt_FromLong(0x6681000A)); PyModule_AddObject(m, "PidTagRuleSequence", PyInt_FromLong(0x66760003)); PyModule_AddObject(m, "PidTagRuleSequence_Error", PyInt_FromLong(0x6676000A)); PyModule_AddObject(m, "PidTagRuleState", PyInt_FromLong(0x66770003)); PyModule_AddObject(m, "PidTagRuleState_Error", PyInt_FromLong(0x6677000A)); PyModule_AddObject(m, "PidTagRuleUserFlags", PyInt_FromLong(0x66780003)); PyModule_AddObject(m, "PidTagRuleUserFlags_Error", PyInt_FromLong(0x6678000A)); PyModule_AddObject(m, "PidTagRwRulesStream", PyInt_FromLong(0x68020102)); PyModule_AddObject(m, "PidTagScheduleInfoAppointmentTombstone", PyInt_FromLong(0x686A0102)); PyModule_AddObject(m, "PidTagScheduleInfoAppointmentTombstone_Error", PyInt_FromLong(0x686A000A)); PyModule_AddObject(m, "PidTagScheduleInfoAutoAcceptAppointments", PyInt_FromLong(0x686D000B)); PyModule_AddObject(m, "PidTagScheduleInfoAutoAcceptAppointments_Error", PyInt_FromLong(0x686D000A)); PyModule_AddObject(m, "PidTagScheduleInfoDelegateEntryIds", PyInt_FromLong(0x68451102)); PyModule_AddObject(m, "PidTagScheduleInfoDelegateEntryIds_Error", PyInt_FromLong(0x6845000A)); PyModule_AddObject(m, "PidTagScheduleInfoDelegateNames", PyInt_FromLong(0x6844101F)); PyModule_AddObject(m, "PidTagScheduleInfoDelegateNamesW", PyInt_FromLong(0x684A101F)); PyModule_AddObject(m, "PidTagScheduleInfoDelegateNamesW_Error", PyInt_FromLong(0x684A000A)); PyModule_AddObject(m, "PidTagScheduleInfoDelegateNames_Error", PyInt_FromLong(0x6844000A)); PyModule_AddObject(m, "PidTagScheduleInfoDelegatorWantsCopy", PyInt_FromLong(0x6842000B)); PyModule_AddObject(m, "PidTagScheduleInfoDelegatorWantsCopy_Error", PyInt_FromLong(0x6842000A)); PyModule_AddObject(m, "PidTagScheduleInfoDelegatorWantsInfo", PyInt_FromLong(0x684B000B)); PyModule_AddObject(m, "PidTagScheduleInfoDelegatorWantsInfo_Error", PyInt_FromLong(0x684B000A)); PyModule_AddObject(m, "PidTagScheduleInfoDisallowOverlappingAppts", PyInt_FromLong(0x686F000B)); PyModule_AddObject(m, "PidTagScheduleInfoDisallowOverlappingAppts_Error", PyInt_FromLong(0x686F000A)); PyModule_AddObject(m, "PidTagScheduleInfoDisallowRecurringAppts", PyInt_FromLong(0x686E000B)); PyModule_AddObject(m, "PidTagScheduleInfoDisallowRecurringAppts_Error", PyInt_FromLong(0x686E000A)); PyModule_AddObject(m, "PidTagScheduleInfoDontMailDelegates", PyInt_FromLong(0x6843000B)); PyModule_AddObject(m, "PidTagScheduleInfoDontMailDelegates_Error", PyInt_FromLong(0x6843000A)); PyModule_AddObject(m, "PidTagScheduleInfoFreeBusy", PyInt_FromLong(0x686C0102)); PyModule_AddObject(m, "PidTagScheduleInfoFreeBusyAway", PyInt_FromLong(0x68561102)); PyModule_AddObject(m, "PidTagScheduleInfoFreeBusyAway_Error", PyInt_FromLong(0x6856000A)); PyModule_AddObject(m, "PidTagScheduleInfoFreeBusyBusy", PyInt_FromLong(0x68541102)); PyModule_AddObject(m, "PidTagScheduleInfoFreeBusyBusy_Error", PyInt_FromLong(0x6854000A)); PyModule_AddObject(m, "PidTagScheduleInfoFreeBusyMerged", PyInt_FromLong(0x68501102)); PyModule_AddObject(m, "PidTagScheduleInfoFreeBusyMerged_Error", PyInt_FromLong(0x6850000A)); PyModule_AddObject(m, "PidTagScheduleInfoFreeBusyTentative", PyInt_FromLong(0x68521102)); PyModule_AddObject(m, "PidTagScheduleInfoFreeBusyTentative_Error", PyInt_FromLong(0x6852000A)); PyModule_AddObject(m, "PidTagScheduleInfoFreeBusy_Error", PyInt_FromLong(0x686C000A)); PyModule_AddObject(m, "PidTagScheduleInfoMonthsAway", PyInt_FromLong(0x68551003)); PyModule_AddObject(m, "PidTagScheduleInfoMonthsAway_Error", PyInt_FromLong(0x6855000A)); PyModule_AddObject(m, "PidTagScheduleInfoMonthsBusy", PyInt_FromLong(0x68531003)); PyModule_AddObject(m, "PidTagScheduleInfoMonthsBusy_Error", PyInt_FromLong(0x6853000A)); PyModule_AddObject(m, "PidTagScheduleInfoMonthsMerged", PyInt_FromLong(0x684F1003)); PyModule_AddObject(m, "PidTagScheduleInfoMonthsMerged_Error", PyInt_FromLong(0x684F000A)); PyModule_AddObject(m, "PidTagScheduleInfoMonthsTentative", PyInt_FromLong(0x68511003)); PyModule_AddObject(m, "PidTagScheduleInfoMonthsTentative_Error", PyInt_FromLong(0x6851000A)); PyModule_AddObject(m, "PidTagScheduleInfoResourceType", PyInt_FromLong(0x68410003)); PyModule_AddObject(m, "PidTagScheduleInfoResourceType_Error", PyInt_FromLong(0x6841000A)); PyModule_AddObject(m, "PidTagSchedulePlusFreeBusyEntryId", PyInt_FromLong(0x66220102)); PyModule_AddObject(m, "PidTagSchedulePlusFreeBusyEntryId_Error", PyInt_FromLong(0x6622000A)); PyModule_AddObject(m, "PidTagScriptData", PyInt_FromLong(0x00040102)); PyModule_AddObject(m, "PidTagSearchFolderDefinition", PyInt_FromLong(0x68450102)); PyModule_AddObject(m, "PidTagSearchFolderExpiration", PyInt_FromLong(0x683A0003)); PyModule_AddObject(m, "PidTagSearchFolderExpiration_Error", PyInt_FromLong(0x683A000A)); PyModule_AddObject(m, "PidTagSearchFolderId", PyInt_FromLong(0x68420102)); PyModule_AddObject(m, "PidTagSearchFolderLastUsed", PyInt_FromLong(0x68340003)); PyModule_AddObject(m, "PidTagSearchFolderLastUsed_Error", PyInt_FromLong(0x6834000A)); PyModule_AddObject(m, "PidTagSearchFolderRecreateInfo", PyInt_FromLong(0x68440102)); PyModule_AddObject(m, "PidTagSearchFolderStorageType", PyInt_FromLong(0x68460003)); PyModule_AddObject(m, "PidTagSearchKey", PyInt_FromLong(0x300B0102)); PyModule_AddObject(m, "PidTagSearchKey_Error", PyInt_FromLong(0x300B000A)); PyModule_AddObject(m, "PidTagSecureSubmitFlags", PyInt_FromLong(0x65C60003)); PyModule_AddObject(m, "PidTagSecureSubmitFlags_Error", PyInt_FromLong(0x65C6000A)); PyModule_AddObject(m, "PidTagSecurityDescriptor", PyInt_FromLong(0x0E270102)); PyModule_AddObject(m, "PidTagSecurityDescriptorAsXml", PyInt_FromLong(0x0E6A001F)); PyModule_AddObject(m, "PidTagSecurityDescriptorAsXml_Error", PyInt_FromLong(0x0E6A000A)); PyModule_AddObject(m, "PidTagSecurityDescriptor_Error", PyInt_FromLong(0x0E27000A)); PyModule_AddObject(m, "PidTagSelectable", PyInt_FromLong(0x3609000B)); PyModule_AddObject(m, "PidTagSelectable_Error", PyInt_FromLong(0x3609000A)); PyModule_AddObject(m, "PidTagSendInternetEncoding", PyInt_FromLong(0x3A710003)); PyModule_AddObject(m, "PidTagSendInternetEncoding_Error", PyInt_FromLong(0x3A71000A)); PyModule_AddObject(m, "PidTagSendRichInfo", PyInt_FromLong(0x3A40000B)); PyModule_AddObject(m, "PidTagSendRichInfo_Error", PyInt_FromLong(0x3A40000A)); PyModule_AddObject(m, "PidTagSenderAddressType", PyInt_FromLong(0x0C1E001F)); PyModule_AddObject(m, "PidTagSenderAddressType_Error", PyInt_FromLong(0x0C1E000A)); PyModule_AddObject(m, "PidTagSenderEmailAddress", PyInt_FromLong(0x0C1F001F)); PyModule_AddObject(m, "PidTagSenderEmailAddress_Error", PyInt_FromLong(0x0C1F000A)); PyModule_AddObject(m, "PidTagSenderEntryId", PyInt_FromLong(0x0C190102)); PyModule_AddObject(m, "PidTagSenderEntryId_Error", PyInt_FromLong(0x0C19000A)); PyModule_AddObject(m, "PidTagSenderFlags", PyInt_FromLong(0x40190003)); PyModule_AddObject(m, "PidTagSenderFlags_Error", PyInt_FromLong(0x4019000A)); PyModule_AddObject(m, "PidTagSenderIdStatus", PyInt_FromLong(0x40790003)); PyModule_AddObject(m, "PidTagSenderIdStatus_Error", PyInt_FromLong(0x4079000A)); PyModule_AddObject(m, "PidTagSenderName", PyInt_FromLong(0x0C1A001F)); PyModule_AddObject(m, "PidTagSenderName_Error", PyInt_FromLong(0x0C1A000A)); PyModule_AddObject(m, "PidTagSenderSearchKey", PyInt_FromLong(0x0C1D0102)); PyModule_AddObject(m, "PidTagSenderSearchKey_Error", PyInt_FromLong(0x0C1D000A)); PyModule_AddObject(m, "PidTagSenderSimpleDisplayName", PyInt_FromLong(0x4030001F)); PyModule_AddObject(m, "PidTagSenderSimpleDisplayName_Error", PyInt_FromLong(0x4030000A)); PyModule_AddObject(m, "PidTagSenderSmtpAddress", PyInt_FromLong(0x5D01001F)); PyModule_AddObject(m, "PidTagSenderSmtpAddress_Error", PyInt_FromLong(0x5D01000A)); PyModule_AddObject(m, "PidTagSenderTelephoneNumber", PyInt_FromLong(0x6802001F)); PyModule_AddObject(m, "PidTagSensitivity", PyInt_FromLong(0x00360003)); PyModule_AddObject(m, "PidTagSensitivity_Error", PyInt_FromLong(0x0036000A)); PyModule_AddObject(m, "PidTagSentMailSvrEID", PyInt_FromLong(0x674000FB)); PyModule_AddObject(m, "PidTagSentMailSvrEID_Error", PyInt_FromLong(0x6740000A)); PyModule_AddObject(m, "PidTagSentRepresentingAddressType", PyInt_FromLong(0x0064001F)); PyModule_AddObject(m, "PidTagSentRepresentingAddressType_Error", PyInt_FromLong(0x0064000A)); PyModule_AddObject(m, "PidTagSentRepresentingEmailAddress", PyInt_FromLong(0x0065001F)); PyModule_AddObject(m, "PidTagSentRepresentingEmailAddress_Error", PyInt_FromLong(0x0065000A)); PyModule_AddObject(m, "PidTagSentRepresentingEntryId", PyInt_FromLong(0x00410102)); PyModule_AddObject(m, "PidTagSentRepresentingEntryId_Error", PyInt_FromLong(0x0041000A)); PyModule_AddObject(m, "PidTagSentRepresentingFlags", PyInt_FromLong(0x401A0003)); PyModule_AddObject(m, "PidTagSentRepresentingFlags_Error", PyInt_FromLong(0x401A000A)); PyModule_AddObject(m, "PidTagSentRepresentingName", PyInt_FromLong(0x0042001F)); PyModule_AddObject(m, "PidTagSentRepresentingName_Error", PyInt_FromLong(0x0042000A)); PyModule_AddObject(m, "PidTagSentRepresentingSearchKey", PyInt_FromLong(0x003B0102)); PyModule_AddObject(m, "PidTagSentRepresentingSearchKey_Error", PyInt_FromLong(0x003B000A)); PyModule_AddObject(m, "PidTagSentRepresentingSimpleDisplayName", PyInt_FromLong(0x4031001F)); PyModule_AddObject(m, "PidTagSentRepresentingSimpleDisplayName_Error", PyInt_FromLong(0x4031000A)); PyModule_AddObject(m, "PidTagSessionInitiationProtocolUri", PyInt_FromLong(0x5FE5001F)); PyModule_AddObject(m, "PidTagSessionInitiationProtocolUri_Error", PyInt_FromLong(0x5FE5000A)); PyModule_AddObject(m, "PidTagSortLocaleId", PyInt_FromLong(0x67050003)); PyModule_AddObject(m, "PidTagSortLocaleId_Error", PyInt_FromLong(0x6705000A)); PyModule_AddObject(m, "PidTagSourceKey", PyInt_FromLong(0x65E00102)); PyModule_AddObject(m, "PidTagSourceKey_Error", PyInt_FromLong(0x65E0000A)); PyModule_AddObject(m, "PidTagSpokenName", PyInt_FromLong(0x8CC20102)); PyModule_AddObject(m, "PidTagSpokenName_Error", PyInt_FromLong(0x8CC2000A)); PyModule_AddObject(m, "PidTagSpouseName", PyInt_FromLong(0x3A48001F)); PyModule_AddObject(m, "PidTagSpouseName_Error", PyInt_FromLong(0x3A48000A)); PyModule_AddObject(m, "PidTagStartDate", PyInt_FromLong(0x00600040)); PyModule_AddObject(m, "PidTagStartDateEtc", PyInt_FromLong(0x301B0102)); PyModule_AddObject(m, "PidTagStartDateEtc_Error", PyInt_FromLong(0x301B000A)); PyModule_AddObject(m, "PidTagStartDate_Error", PyInt_FromLong(0x0060000A)); PyModule_AddObject(m, "PidTagStartEmbed", PyInt_FromLong(0x40010003)); PyModule_AddObject(m, "PidTagStartEmbed_Error", PyInt_FromLong(0x4001000A)); PyModule_AddObject(m, "PidTagStartFAIMsg", PyInt_FromLong(0x40100003)); PyModule_AddObject(m, "PidTagStartFAIMsg_Error", PyInt_FromLong(0x4010000A)); PyModule_AddObject(m, "PidTagStartMessage", PyInt_FromLong(0x400C0003)); PyModule_AddObject(m, "PidTagStartMessage_Error", PyInt_FromLong(0x400C000A)); PyModule_AddObject(m, "PidTagStartRecip", PyInt_FromLong(0x40030003)); PyModule_AddObject(m, "PidTagStartRecip_Error", PyInt_FromLong(0x4003000A)); PyModule_AddObject(m, "PidTagStartSubFld", PyInt_FromLong(0x400A0003)); PyModule_AddObject(m, "PidTagStartSubFld_Error", PyInt_FromLong(0x400A000A)); PyModule_AddObject(m, "PidTagStartTopFld", PyInt_FromLong(0x40090003)); PyModule_AddObject(m, "PidTagStartTopFld_Error", PyInt_FromLong(0x4009000A)); PyModule_AddObject(m, "PidTagStateOrProvince", PyInt_FromLong(0x3A28001F)); PyModule_AddObject(m, "PidTagStateOrProvince_Error", PyInt_FromLong(0x3A28000A)); PyModule_AddObject(m, "PidTagStoreEntryId", PyInt_FromLong(0x0FFB0102)); PyModule_AddObject(m, "PidTagStoreEntryId_Error", PyInt_FromLong(0x0FFB000A)); PyModule_AddObject(m, "PidTagStoreState", PyInt_FromLong(0x340E0003)); PyModule_AddObject(m, "PidTagStoreState_Error", PyInt_FromLong(0x340E000A)); PyModule_AddObject(m, "PidTagStoreSupportMask", PyInt_FromLong(0x340D0003)); PyModule_AddObject(m, "PidTagStoreSupportMask_Error", PyInt_FromLong(0x340D000A)); PyModule_AddObject(m, "PidTagStreetAddress", PyInt_FromLong(0x3A29001F)); PyModule_AddObject(m, "PidTagStreetAddress_Error", PyInt_FromLong(0x3A29000A)); PyModule_AddObject(m, "PidTagSubfolder", PyInt_FromLong(0x6708000B)); PyModule_AddObject(m, "PidTagSubfolder_Error", PyInt_FromLong(0x6708000A)); PyModule_AddObject(m, "PidTagSubfolders", PyInt_FromLong(0x360A000B)); PyModule_AddObject(m, "PidTagSubfolders_Error", PyInt_FromLong(0x360A000A)); PyModule_AddObject(m, "PidTagSubject", PyInt_FromLong(0x0037001F)); PyModule_AddObject(m, "PidTagSubjectPrefix", PyInt_FromLong(0x003D001F)); PyModule_AddObject(m, "PidTagSubjectPrefix_Error", PyInt_FromLong(0x003D000A)); PyModule_AddObject(m, "PidTagSubject_Error", PyInt_FromLong(0x0037000A)); PyModule_AddObject(m, "PidTagSurname", PyInt_FromLong(0x3A11001F)); PyModule_AddObject(m, "PidTagSurname_Error", PyInt_FromLong(0x3A11000A)); PyModule_AddObject(m, "PidTagSwappedToDoData", PyInt_FromLong(0x0E2D0102)); PyModule_AddObject(m, "PidTagSwappedToDoData_Error", PyInt_FromLong(0x0E2D000A)); PyModule_AddObject(m, "PidTagSwappedToDoStore", PyInt_FromLong(0x0E2C0102)); PyModule_AddObject(m, "PidTagSwappedToDoStore_Error", PyInt_FromLong(0x0E2C000A)); PyModule_AddObject(m, "PidTagTargetEntryId", PyInt_FromLong(0x30100102)); PyModule_AddObject(m, "PidTagTargetEntryId_Error", PyInt_FromLong(0x3010000A)); PyModule_AddObject(m, "PidTagTcvConstLongOne", PyInt_FromLong(0x80080003)); PyModule_AddObject(m, "PidTagTelecommunicationsDeviceForDeafTelephoneNumber", PyInt_FromLong(0x3A4B001F)); PyModule_AddObject(m, "PidTagTelecommunicationsDeviceForDeafTelephoneNumber_Error", PyInt_FromLong(0x3A4B000A)); PyModule_AddObject(m, "PidTagTelexNumber", PyInt_FromLong(0x3A2C001F)); PyModule_AddObject(m, "PidTagTelexNumber_Error", PyInt_FromLong(0x3A2C000A)); PyModule_AddObject(m, "PidTagTemplateData", PyInt_FromLong(0x00010102)); PyModule_AddObject(m, "PidTagTemplateData_Error", PyInt_FromLong(0x0001000A)); PyModule_AddObject(m, "PidTagTemplateid", PyInt_FromLong(0x39020102)); PyModule_AddObject(m, "PidTagTemplateid_Error", PyInt_FromLong(0x3902000A)); PyModule_AddObject(m, "PidTagTemporaryDefaultDocument", PyInt_FromLong(0x3F20001F)); PyModule_AddObject(m, "PidTagTemporaryDefaultDocument_Error", PyInt_FromLong(0x3F20000A)); PyModule_AddObject(m, "PidTagTextAttachmentCharset", PyInt_FromLong(0x371B001F)); PyModule_AddObject(m, "PidTagTextAttachmentCharset_Error", PyInt_FromLong(0x371B000A)); PyModule_AddObject(m, "PidTagThumbnailPhoto", PyInt_FromLong(0x8C9E0102)); PyModule_AddObject(m, "PidTagThumbnailPhoto_Error", PyInt_FromLong(0x8C9E000A)); PyModule_AddObject(m, "PidTagTitle", PyInt_FromLong(0x3A17001F)); PyModule_AddObject(m, "PidTagTitle_Error", PyInt_FromLong(0x3A17000A)); PyModule_AddObject(m, "PidTagTnefCorrelationKey", PyInt_FromLong(0x007F0102)); PyModule_AddObject(m, "PidTagTnefCorrelationKey_Error", PyInt_FromLong(0x007F000A)); PyModule_AddObject(m, "PidTagToDoItemFlags", PyInt_FromLong(0x0E2B0003)); PyModule_AddObject(m, "PidTagToDoItemFlags_Error", PyInt_FromLong(0x0E2B000A)); PyModule_AddObject(m, "PidTagTransmittableDisplayName", PyInt_FromLong(0x3A20001F)); PyModule_AddObject(m, "PidTagTransmittableDisplayName_Error", PyInt_FromLong(0x3A20000A)); PyModule_AddObject(m, "PidTagTransportMessageHeaders", PyInt_FromLong(0x007D001F)); PyModule_AddObject(m, "PidTagTransportMessageHeaders_Error", PyInt_FromLong(0x007D000A)); PyModule_AddObject(m, "PidTagTrustSender", PyInt_FromLong(0x0E790003)); PyModule_AddObject(m, "PidTagTrustSender_Error", PyInt_FromLong(0x0E79000A)); PyModule_AddObject(m, "PidTagUrlCompName", PyInt_FromLong(0x10F3001F)); PyModule_AddObject(m, "PidTagUrlCompNameSet", PyInt_FromLong(0x0E62000B)); PyModule_AddObject(m, "PidTagUrlCompNameSet_Error", PyInt_FromLong(0x0E62000A)); PyModule_AddObject(m, "PidTagUrlCompName_Error", PyInt_FromLong(0x10F3000A)); PyModule_AddObject(m, "PidTagUrlName", PyInt_FromLong(0x6707001F)); PyModule_AddObject(m, "PidTagUrlName_Error", PyInt_FromLong(0x6707000A)); PyModule_AddObject(m, "PidTagUserCertificate", PyInt_FromLong(0x3A220102)); PyModule_AddObject(m, "PidTagUserCertificate_Error", PyInt_FromLong(0x3A22000A)); PyModule_AddObject(m, "PidTagUserEntryId", PyInt_FromLong(0x66190102)); PyModule_AddObject(m, "PidTagUserEntryId_Error", PyInt_FromLong(0x6619000A)); PyModule_AddObject(m, "PidTagUserX509Certificate", PyInt_FromLong(0x3A701102)); PyModule_AddObject(m, "PidTagUserX509Certificate_Error", PyInt_FromLong(0x3A70000A)); PyModule_AddObject(m, "PidTagViewDescriptorBinary", PyInt_FromLong(0x70010102)); PyModule_AddObject(m, "PidTagViewDescriptorBinary_Error", PyInt_FromLong(0x7001000A)); PyModule_AddObject(m, "PidTagViewDescriptorName", PyInt_FromLong(0x7006001F)); PyModule_AddObject(m, "PidTagViewDescriptorName_Error", PyInt_FromLong(0x7006000A)); PyModule_AddObject(m, "PidTagViewDescriptorStrings", PyInt_FromLong(0x7002001F)); PyModule_AddObject(m, "PidTagViewDescriptorStrings_Error", PyInt_FromLong(0x7002000A)); PyModule_AddObject(m, "PidTagViewDescriptorVersion", PyInt_FromLong(0x70070003)); PyModule_AddObject(m, "PidTagViewDescriptorVersion_Error", PyInt_FromLong(0x7007000A)); PyModule_AddObject(m, "PidTagVoiceMessageAttachmentOrder", PyInt_FromLong(0x6805001F)); PyModule_AddObject(m, "PidTagVoiceMessageSenderName", PyInt_FromLong(0x6803001F)); PyModule_AddObject(m, "PidTagWeddingAnniversary", PyInt_FromLong(0x3A410040)); PyModule_AddObject(m, "PidTagWeddingAnniversary_Error", PyInt_FromLong(0x3A41000A)); PyModule_AddObject(m, "PidTagWlinkAddressBookEID", PyInt_FromLong(0x68540102)); PyModule_AddObject(m, "PidTagWlinkAddressBookStoreEID", PyInt_FromLong(0x68910102)); PyModule_AddObject(m, "PidTagWlinkAddressBookStoreEID_Error", PyInt_FromLong(0x6891000A)); PyModule_AddObject(m, "PidTagWlinkCalendarColor", PyInt_FromLong(0x68530003)); PyModule_AddObject(m, "PidTagWlinkClientID", PyInt_FromLong(0x68900048)); PyModule_AddObject(m, "PidTagWlinkClientID_Error", PyInt_FromLong(0x6890000A)); PyModule_AddObject(m, "PidTagWlinkEntryId", PyInt_FromLong(0x684C0102)); PyModule_AddObject(m, "PidTagWlinkEntryId_Error", PyInt_FromLong(0x684C000A)); PyModule_AddObject(m, "PidTagWlinkFlags", PyInt_FromLong(0x684A0003)); PyModule_AddObject(m, "PidTagWlinkFolderType", PyInt_FromLong(0x684F0048)); PyModule_AddObject(m, "PidTagWlinkGroupClsid", PyInt_FromLong(0x68500048)); PyModule_AddObject(m, "PidTagWlinkGroupHeaderID", PyInt_FromLong(0x68420048)); PyModule_AddObject(m, "PidTagWlinkGroupName", PyInt_FromLong(0x6851001F)); PyModule_AddObject(m, "PidTagWlinkOrdinal", PyInt_FromLong(0x684B0102)); PyModule_AddObject(m, "PidTagWlinkROGroupType", PyInt_FromLong(0x68920003)); PyModule_AddObject(m, "PidTagWlinkROGroupType_Error", PyInt_FromLong(0x6892000A)); PyModule_AddObject(m, "PidTagWlinkRecordKey", PyInt_FromLong(0x684D0102)); PyModule_AddObject(m, "PidTagWlinkRecordKey_Error", PyInt_FromLong(0x684D000A)); PyModule_AddObject(m, "PidTagWlinkSection", PyInt_FromLong(0x68520003)); PyModule_AddObject(m, "PidTagWlinkStoreEntryId", PyInt_FromLong(0x684E0102)); PyModule_AddObject(m, "PidTagWlinkStoreEntryId_Error", PyInt_FromLong(0x684E000A)); PyModule_AddObject(m, "PidTagWlinkType", PyInt_FromLong(0x68490003)); return 0; } openchange-2.0/pyopenchange/pyocpf.c000066400000000000000000000172041223057412600176140ustar00rootroot00000000000000/* OpenChange OCPF (OpenChange Property File) implementation. Python interface to ocpf Copyright (C) Julien Kerihuel 2010. This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see . */ #include #include "pyopenchange/pyocpf.h" #include "pyopenchange/pymapi.h" #include "libocpf/ocpf.h" static PyTypeObject *SPropValue_Type; void initocpf(void); PyAPI_DATA(PyTypeObject) PyOcpf; static PyObject *py_new_context(PyTypeObject *type, PyObject *args, PyObject *kwargs) { TALLOC_CTX *mem_ctx; PyOcpfObject *ocpf_object; char *kwnames[] = { "filename", "flags", NULL }; int ret; const char *filename; uint32_t context_id; uint8_t flags; if (!PyArg_ParseTupleAndKeywords(args, kwargs, "sH", kwnames, &filename, &flags)) { return NULL; } mem_ctx = talloc_new(NULL); if (mem_ctx == NULL) { PyErr_NoMemory(); return NULL; } printf("filename = %s, flags = 0x%x\n", filename, flags); ret = ocpf_new_context(filename, &context_id, flags); if (ret == OCPF_ERROR) { return NULL; } printf("context_id = %d\n", context_id); ocpf_object = PyObject_New(PyOcpfObject, &PyOcpf); ocpf_object->context_id = context_id; ocpf_object->mem_ctx = mem_ctx; return (PyObject *) ocpf_object; } static PyObject *py_ocpf_parse(PyOcpfObject *self) { int ret; ret = ocpf_parse(self->context_id); return PyInt_FromLong(ret); } static PyObject *py_ocpf_set_SPropValue_array(PyOcpfObject *self) { int ret; ret = ocpf_server_set_SPropValue(self->mem_ctx, self->context_id); return PyInt_FromLong(ret); } static PyObject *py_ocpf_get_SPropValue(PyOcpfObject *self) { uint32_t cValues = 0; PyObject *mod_mapi; PySPropValueObject *pySPropValue; struct SPropValue *SPropValue; mod_mapi = PyImport_ImportModule("openchange.mapi"); if (mod_mapi == NULL) { printf("Can't load module\n"); return NULL; } SPropValue_Type = (PyTypeObject *)PyObject_GetAttrString(mod_mapi, "SPropValue"); if (SPropValue_Type == NULL) return NULL; SPropValue = ocpf_get_SPropValue(self->context_id, &cValues); pySPropValue = (PySPropValueObject *)SPropValue_Type->tp_new(NULL, NULL, NULL); talloc_free(pySPropValue->SPropValue); pySPropValue->SPropValue = SPropValue; talloc_steal(pySPropValue->mem_ctx, pySPropValue->SPropValue); pySPropValue->cValues = cValues; return (PyObject *) pySPropValue; } static PyObject *py_ocpf_add_SPropValue(PyOcpfObject *self, PyObject *args) { PyObject *mod_mapi; PyObject *pySPropValue; PySPropValueObject *SPropValue; int ret; int i; mod_mapi = PyImport_ImportModule("openchange.mapi"); if (mod_mapi == NULL) { printf("Can't load module\n"); return NULL; } SPropValue_Type = (PyTypeObject *)PyObject_GetAttrString(mod_mapi, "SPropValue"); if (SPropValue_Type == NULL) { return NULL; } if (!PyArg_ParseTuple(args, "O", &pySPropValue)) { return NULL; } if (!PyObject_TypeCheck(pySPropValue, SPropValue_Type)) { PyErr_SetString(PyExc_TypeError, "Function requires SPropValue obnject"); return NULL; } SPropValue = (PySPropValueObject *) pySPropValue; for (i = 0; i < SPropValue->cValues; i++) { ret = ocpf_server_add_SPropValue(self->context_id, &SPropValue->SPropValue[i]); if (ret) { return PyInt_FromLong(ret); } } return PyInt_FromLong(ret); } static PyObject *py_ocpf_dump(PyOcpfObject *self) { ocpf_dump(self->context_id); Py_RETURN_NONE; } static PyObject *py_ocpf_write_init(PyOcpfObject *self, PyObject *args) { int ret; uint64_t folder_id; if (!PyArg_ParseTuple(args, "K", &folder_id)) { return NULL; } ret = ocpf_write_init(self->context_id, folder_id); return PyInt_FromLong(ret); } static PyObject *py_ocpf_write(PyOcpfObject *self, PyObject *args) { int ret; PyObject *pySPropValue; PySPropValueObject *SPropValue; struct mapi_SPropValue_array mapi_lpProps; PyObject *mod_mapi; int i; mod_mapi = PyImport_ImportModule("openchange.mapi"); if (mod_mapi == NULL) { printf("Can't load module\n"); return NULL; } SPropValue_Type = (PyTypeObject *)PyObject_GetAttrString(mod_mapi, "SPropValue"); if (SPropValue_Type == NULL) return NULL; if (!PyArg_ParseTuple(args, "O", &pySPropValue)) { return NULL; } if (!PyObject_TypeCheck(pySPropValue, SPropValue_Type)) { PyErr_SetString(PyExc_TypeError, "Function require SPropValue object"); return NULL; } SPropValue = (PySPropValueObject *) pySPropValue; mapi_lpProps.cValues = SPropValue->cValues; mapi_lpProps.lpProps = talloc_array(SPropValue->mem_ctx, struct mapi_SPropValue, SPropValue->cValues); for (i = 0; i < SPropValue->cValues; i++) { cast_mapi_SPropValue((TALLOC_CTX *)mapi_lpProps.lpProps, &(mapi_lpProps.lpProps[i]), &(SPropValue->SPropValue[i])); } ret = ocpf_write_auto(self->context_id, NULL, &mapi_lpProps); talloc_free(mapi_lpProps.lpProps); return PyInt_FromLong(ret); } static PyObject *py_ocpf_write_commit(PyOcpfObject *self) { int ret; ret = ocpf_write_commit(self->context_id); return PyInt_FromLong(ret); } static PyObject *py_ocpf_set_type(PyOcpfObject *self, PyObject *args) { const char *type; if (!PyArg_ParseTuple(args, "s", &type)) { return NULL; } return PyInt_FromLong(ocpf_server_set_type(self->context_id, type)); } static PyMethodDef py_ocpf_global_methods[] = { { NULL } }; static PyMethodDef ocpf_methods[] = { { "parse", (PyCFunction) py_ocpf_parse, METH_NOARGS }, { "dump", (PyCFunction) py_ocpf_dump, METH_NOARGS }, { "write_init", (PyCFunction) py_ocpf_write_init, METH_VARARGS }, { "write", (PyCFunction) py_ocpf_write, METH_VARARGS }, { "write_commit", (PyCFunction) py_ocpf_write_commit, METH_NOARGS }, { "set_SPropValue_array", (PyCFunction) py_ocpf_set_SPropValue_array, METH_NOARGS }, { "get_SPropValue", (PyCFunction) py_ocpf_get_SPropValue, METH_NOARGS }, { "add_SPropValue", (PyCFunction) py_ocpf_add_SPropValue, METH_VARARGS }, { "set_type", (PyCFunction) py_ocpf_set_type, METH_VARARGS }, { NULL }, }; static PyGetSetDef ocpf_getsetters[] = { { NULL } }; static void py_ocpf_dealloc(PyObject *_self) { PyOcpfObject *self = (PyOcpfObject *)_self; talloc_free(self->mem_ctx); printf("ocpf_del_context\n"); ocpf_del_context(self->context_id); PyObject_Del(_self); } PyTypeObject PyOcpf = { PyObject_HEAD_INIT(NULL) 0, .tp_name = "OCPF", .tp_basicsize = sizeof(PyOcpfObject), .tp_methods = ocpf_methods, .tp_getset = ocpf_getsetters, .tp_doc = "OCPF context", .tp_new = py_new_context, .tp_dealloc = (destructor)py_ocpf_dealloc, .tp_flags = Py_TPFLAGS_DEFAULT, }; void initocpf(void) { PyObject *m; if (PyType_Ready(&PyOcpf) < 0) { return; } m = Py_InitModule3("ocpf", py_ocpf_global_methods, "An interface to OCPF, an OpenChange file format used to represent MAPI messages"); if (m == NULL) { return; } PyModule_AddObject(m, "OCPF_FLAGS_RDWR", PyInt_FromLong(OCPF_FLAGS_RDWR)); PyModule_AddObject(m, "OCPF_FLAGS_READ", PyInt_FromLong(OCPF_FLAGS_READ)); PyModule_AddObject(m, "OCPF_FLAGS_WRITE", PyInt_FromLong(OCPF_FLAGS_WRITE)); PyModule_AddObject(m, "OCPF_FLAGS_CREATE", PyInt_FromLong(OCPF_FLAGS_CREATE)); Py_INCREF(&PyOcpf); PyModule_AddObject(m, "Ocpf", (PyObject *)&PyOcpf); /* Initialize OCPF subsystem */ ocpf_init(); } openchange-2.0/pyopenchange/pyocpf.h000066400000000000000000000017311223057412600176170ustar00rootroot00000000000000/* OpenChange OCPF (OpenChange Property File) implementation. Python interface to ocpf Copyright (C) Julien Kerihuel 2010. This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see . */ #ifndef _PYOCPF_H_ #define _PYOCPF_H_ #include #include typedef struct { PyObject_HEAD uint32_t context_id; TALLOC_CTX *mem_ctx; } PyOcpfObject; #endif /* !_PYOCPF_H_ */ openchange-2.0/pyopenchange/tests/000077500000000000000000000000001223057412600173065ustar00rootroot00000000000000openchange-2.0/pyopenchange/tests/mapistore_mgmt.py000077500000000000000000000030451223057412600227140ustar00rootroot00000000000000#!/usr/bin/python # NOTE: # # For this test, we are running the whole environment on a different # server: imap, ldap, postgresql, postfix, openchange, samba and sogo. # We have configured SOGo backend locally and adjusted defaults to # connect to this remote server. # # Finally we are accessing the openchange.ldb file through sshfs and # map it to expected /usr/local/samba/private folder. # sshfs openchange@ip_addr:/usr/local/samba/private /usr/local/samba/private # We have also adjusted the permissions to allow openchange user to # read/write openchange.ldb file remotely. # # Do not forget to run memcached with the user account running the # script. # import os import sys import time sys.path.append("python") import openchange.mapistore as mapistore dirname = "/usr/local/samba/private/mapistore" if not os.path.exists(dirname): os.mkdir("/usr/local/samba/private/mapistore") mapistore.set_mapping_path(dirname) MAPIStore = mapistore.mapistore(syspath="/usr/local/samba/private") mgmt = MAPIStore.management() #while 1: # time.sleep(5) # d = mgmt.registered_users("SOGo", "Administrator") # print d print "Is SOGo backend registered: %s" % mgmt.registered_backend("SOGo") print "Is NonExistent backend registered: %s" % mgmt.registered_backend("NonExistent") print "Registered message: %s" % mgmt.registered_message("SOGo", "Administrator", "Administrator", "inbox", "61") print "Registered message: %s" % mgmt.registered_message("SOGo", "Administrator", "Administrator", "inbox", "74") mgmt.existing_users("SOGo", "Administrator", "inbox") openchange-2.0/pyopenchange/tests/mapistore_sogo.py000077500000000000000000000041541223057412600227210ustar00rootroot00000000000000#!/usr/bin/python # NOTE: # # For this test, we are running the whole environment on a different # server: imap, ldap, postgresql, postfix, openchange, samba and sogo. # We have configured SOGo backend locally and adjusted defaults to # connect to this remote server. # # Finally we are accessing the openchange.ldb file through sshfs and # map it at the top of the checkout within private folder: # sshfs openchange@ip_addr:/usr/local/samba/private private # We have also adjusted the permissions to allow openchange user to # read/write openchange.ldb file remotely. # # Do not forget to run memcached with the user account running the # script. # import os import sys import time sys.path.append("python") import openchange.mapistore as mapistore dirname = "/usr/local/samba/private/mapistore" if not os.path.exists(dirname): os.mkdir("/usr/local/samba/private/mapistore") mapistore.set_mapping_path(dirname) MAPIStore = mapistore.mapistore(syspath="/usr/local/samba/private") MAPICtx = MAPIStore.add_context("sogo://Administrator:Administrator@inbox/", "Administrator") Inbox = MAPICtx.open() identifier = MAPICtx.add_subscription("sogo://Administrator:Administrator@inbox/", False, 0x2) while 1: time.sleep(1) MAPICtx.get_notifications() time.sleep(15) MAPICtx.delete_subscription("sogo://Administrator:Administrator@inbox/", False, 0x2, identifier) #Calendar = MAPIStore.add_context("sogo://Administator:Administrator@inbox/", "Administrator").open() #time.sleep(5) #print Calendar.folder_count #time.sleep(5) #MAPICtx = MAPIStore.add_context("sogo://Administrator:Administrator@inbox/", "GoodAdmin") Inbox.create_folder(name="Test") time.sleep(15) NewCalender = MAPICtx.open() print "[I] We have %d sub folders, %d messages and %d fai messages within %s" % (Inbox.folder_count, Inbox.message_count, Inbox.fai_message_count, hex(Inbox.fid)) MAPIStore.delete_context(MAPICtx) openchange-2.0/pyopenchange/tests/mapistore_test.py000077500000000000000000000027311223057412600227300ustar00rootroot00000000000000#!/usr/bin/python import sys sys.path.append("python") import os import openchange import openchange.mapistore as mapistore from openchange import mapi dirname = "/tmp/mapistore" if not os.path.exists(dirname): os.mkdir("/tmp/mapistore") mapistore.set_mapping_path("/tmp/mapistore") MAPIStore = mapistore.mapistore() ctx_id = MAPIStore.add_context("sogo://openchange:openchange@mail/") SPropParent = mapi.SPropValue() SPropParent.add(mapi.PR_FID, 0x0000000000160001) SPropParent.add(mapi.PR_DISPLAY_NAME, "parent") SPropParent.add(mapi.PR_COMMENT, "test parent") SPropParent.add(mapi.PR_FOLDER_TYPE, 1) MAPIStore.setprops(ctx_id, 0x0000000000160001, mapistore.MAPISTORE_FOLDER, SPropParent) SPropValue = mapi.SPropValue() SPropValue.add(mapi.PR_PARENT_FID, 0x0000000000010001) SPropValue.add(mapi.PR_DISPLAY_NAME, "test") SPropValue.add(mapi.PR_COMMENT, "test folder") SPropValue.add(mapi.PR_FOLDER_TYPE, 1) MAPIStore.mkdir(ctx_id, 0x0000000000160001, 0x0000000000020001, SPropValue) count = MAPIStore.get_folder_count(ctx_id, 0x0000000000010001, mapistore.MAPISTORE_FOLDER) print "After mkdir: %d" % (count) MAPIStore.rmdir(ctx_id, 0x0000000000160001, 0x0000000000020001, mapistore.DEL_FOLDERS) count = MAPIStore.get_folder_count(ctx_id, 0x0000000000010001, mapistore.MAPISTORE_FOLDER) print "After rmdir: %d" % (count) count = MAPIStore.get_folder_count(ctx_id, 0x0000000000010001, mapistore.MAPISTORE_MESSAGE) print "List messages: %d" % (count) MAPIStore.del_context(ctx_id) openchange-2.0/pyopenchange/tests/ocpf_test.py000077500000000000000000000023301223057412600216470ustar00rootroot00000000000000#!/usr/bin/python import sys sys.path.append("python") import os import openchange import openchange.ocpf as ocpf import openchange.mapi as mapi from openchange.ocpf import Ocpf filename = os.getcwd() + "/../../libocpf/examples/sample_appointment.ocpf"; ctx = Ocpf(filename, ocpf.OCPF_FLAGS_READ) ret = ctx.parse() ret = ctx.set_SPropValue_array() SPropValue = ctx.get_SPropValue() ret = ctx.dump() SPropValue.dump("1. SPropValue: ") del SPropValue SPropValue = mapi.SPropValue() SPropValue.add(mapi.PR_CONVERSATION_TOPIC, "New subject from python") SPropValue.add(mapi.PR_NORMALIZED_SUBJECT, "New subject from python") ret = ctx.add_SPropValue(SPropValue) ret = ctx.set_SPropValue_array() print "\n" print "New SpropValue after replacing subject:" print "=======================================" del SPropValue SPropValue = ctx.get_SPropValue() SPropValue.dump("2. SPropValue: ") print print "Writing ocpf_test.ocpf file:" print "============================" filename = os.getcwd() + "/ocpf_test.ocpf"; ctx2 = Ocpf(filename, ocpf.OCPF_FLAGS_CREATE) # dummy test to ensure we can set an ocpf parameter properly ret = ctx2.write_init(0x12345678) ret = ctx2.write(SPropValue) ret = ctx2.write_commit() ret = ctx2.dump() del ctx openchange-2.0/pyopenchange/tests/properties.py000077500000000000000000000006161223057412600220620ustar00rootroot00000000000000#!/usr/bin/python import sys sys.path.append("python") from openchange import mapi import time SPropValue = mapi.SPropValue() SPropValue.add(mapi.PidTagSubject, "This is a test") SPropValue.add(mapi.PidTagImportance, 4096) SPropValue.add(mapi.PidTagMessageToMe, True) SPropValue.add(mapi.PidTagMessageCcMe, False) SPropValue.add(mapi.PidTagStartDate, time.time()) SPropValue.dump("Python: ") openchange-2.0/pyopenchange/tests/sogo_readdir.py000077500000000000000000000021201223057412600223170ustar00rootroot00000000000000#!/usr/bin/python # -*- coding: utf-8 -*- import sys sys.path.append("python") import os import openchange import openchange.mapistore as mapistore from openchange import mapi dirname = "/tmp/mapistore" if not os.path.exists(dirname): os.mkdir("/tmp/mapistore") mapistore.set_mapping_path("/tmp/mapistore") MAPIStore = mapistore.mapistore() ctx_id = MAPIStore.add_context("sogo://openchange:openchange@mail/") count = MAPIStore.get_folder_count(ctx_id, 0x0000000000160001, mapistore.MAPISTORE_FOLDER) print "Number of folders in INBOX: %d" % (count) SPropValue = mapi.SPropValue() SPropValue.add(mapi.PR_PARENT_FID, 0x0000000000160001) SPropValue.add(mapi.PR_DISPLAY_NAME, "testé") SPropValue.add(mapi.PR_COMMENT, "test folder") SPropValue.add(mapi.PR_FOLDER_TYPE, 1) MAPIStore.mkdir(ctx_id, 0x0000000000160001, 0x00000000001620001, SPropValue) count = MAPIStore.get_folder_count(ctx_id, 0x0000000000160001, mapistore.MAPISTORE_FOLDER) print "Number of folders in INBOX: %d" % (count) MAPIStore.del_context(ctx_id) openchange-2.0/python/000077500000000000000000000000001223057412600150055ustar00rootroot00000000000000openchange-2.0/python/openchange/000077500000000000000000000000001223057412600171145ustar00rootroot00000000000000openchange-2.0/python/openchange/__init__.py000066400000000000000000000027721223057412600212350ustar00rootroot00000000000000#!/usr/bin/python # OpenChange Python bindings # Copyright (C) Jelmer Vernooij 2008 # # This program is free software; you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by # the Free Software Foundation; either version 3 of the License, or # (at your option) any later version. # # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program. If not, see . # __docformat__ = 'restructuredText' import os, sys try: import samba except ImportError: # Try to fix up sys.path if Samba is installed in an unusual location SAMBA_PREFIXES = ["/usr/local/samba", "/opt/samba"] for samba_prefix in SAMBA_PREFIXES: if not os.path.isdir(samba_prefix): continue for lib_dir in ["lib", "lib64"]: python_version = "%d.%d" % sys.version_info[:2] path = os.path.join(samba_prefix, lib_dir, "python%s" % python_version, "site-packages") if os.path.isdir(os.path.join(path, "samba")): sys.path.append(path) break import samba def test_suite(): import openchange.tests return openchange.tests.test_suite() openchange-2.0/python/openchange/mailbox.py000066400000000000000000000254711223057412600211320ustar00rootroot00000000000000#!/usr/bin/python # OpenChange provisioning # Copyright (C) Julien Kerihuel 2009 # Copyright (C) Jelmer Vernooij 2009 # # This program is free software; you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by # the Free Software Foundation; either version 3 of the License, or # (at your option) any later version. # # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program. If not, see . # import os import samba from samba import Ldb, unix2nttime import ldb import uuid import time from openchange.urlutils import * __docformat__ = 'restructuredText' class NoSuchServer(Exception): """Raised when a server could not be found.""" class OpenChangeDB(object): """The OpenChange database. """ def __init__(self, url): self.url = url self.ldb = Ldb(self.url) self.nttime = samba.unix2nttime(int(time.time())) def reopen(self): self.ldb = Ldb(self.url) def setup(self): self.ldb.add_ldif(""" dn: @OPTIONS checkBaseOnSearch: TRUE dn: @INDEXLIST @IDXATTR: cn dn: @ATTRIBUTES cn: CASE_INSENSITIVE dn: CASE_INSENSITIVE """) self.reopen() def add_rootDSE(self, ocserverdn, firstorg, firstou): self.ldb.add({"dn": "@ROOTDSE", "defaultNamingContext": "CN=%s,CN=%s,%s" % (firstou, firstorg, ocserverdn), "rootDomainNamingContext": ocserverdn, "vendorName": "OpenChange Team (http://www.openchange.org)"}) def add_server(self, ocserverdn, netbiosname, firstorg, firstou): self.ldb.add({"dn": ocserverdn, "objectClass": ["top", "server"], "cn": netbiosname, "GlobalCount": "1", "ChangeNumber": "1", "ReplicaID": "1"}) self.ldb.add({"dn": "CN=%s,%s" % (firstorg, ocserverdn), "objectClass": ["top", "org"], "cn": firstorg}) self.ldb.add({"dn": "CN=%s,CN=%s,%s" % (firstou, firstorg, ocserverdn), "objectClass": ["top", "ou"], "cn": firstou}) def add_root_public_folder(self, dn, fid, change_num, SystemIdx, childcount): self.ldb.add({"dn": dn, "objectClass": ["publicfolder"], "cn": fid, "PidTagFolderId": fid, "PidTagChangeNumber": change_num, "PidTagDisplayName": "Public Folder Root", "PidTagCreationTime": "%d" % self.nttime, "PidTagLastModificationTime": "%d" % self.nttime, "PidTagSubFolders": str(childcount != 0).upper(), "PidTagFolderChildCount": str(childcount), "SystemIdx": str(SystemIdx)}) def add_sub_public_folder(self, dn, parentfid, fid, change_num, name, SystemIndex, childcount): self.ldb.add({"dn": dn, "objectClass": ["publicfolder"], "cn": fid, "PidTagFolderId": fid, "PidTagParentFolderId": parentfid, "PidTagChangeNumber": change_num, "PidTagDisplayName": name, "PidTagCreationTime": "%d" % self.nttime, "PidTagLastModificationTime": "%d" % self.nttime, "PidTagAttributeHidden": str(0), "PidTagAttributeReadOnly": str(0), "PidTagAttributeSystem": str(0), "PidTagContainerClass": "IPF.Note (check this)", "PidTagSubFolders": str(childcount != 0).upper(), "PidTagFolderChildCount": str(childcount), "FolderType": str(1), "SystemIdx": str(SystemIndex)}) def add_one_public_folder(self, parent_fid, path, children, SystemIndex, names, dn_prefix = None): name = path[-1] GlobalCount = self.get_message_GlobalCount(names.netbiosname) ChangeNumber = self.get_message_ChangeNumber(names.netbiosname) ReplicaID = self.get_message_ReplicaID(names.netbiosname) if dn_prefix is None: dn_prefix = "CN=publicfolders,CN=%s,CN=%s,%s" % (names.firstou, names.firstorg, names.ocserverdn) fid = gen_mailbox_folder_fid(GlobalCount, ReplicaID) dn = "CN=%s,%s" % (fid, dn_prefix) change_num = gen_mailbox_folder_fid(ChangeNumber, ReplicaID) childcount = len(children) print "\t* %-40s: 0x%.16x (%s)" % (name, int(fid, 10), fid) if parent_fid == 0: self.add_root_public_folder(dn, fid, change_num, SystemIndex, childcount) else: self.add_sub_public_folder(dn, parent_fid, fid, change_num, name, SystemIndex, childcount); GlobalCount += 1 self.set_message_GlobalCount(names.netbiosname, GlobalCount=GlobalCount) ChangeNumber += 1 self.set_message_ChangeNumber(names.netbiosname, ChangeNumber=ChangeNumber) for name, grandchildren in children.iteritems(): self.add_one_public_folder(fid, path + (name,), grandchildren[0], grandchildren[1], names, dn) def add_public_folders(self, names): pfstoreGUID = str(uuid.uuid4()) self.ldb.add({"dn": "CN=publicfolders,CN=%s,CN=%s,%s" % (names.firstou, names.firstorg, names.ocserverdn), "objectClass": ["container"], "cn": "publicfolders", "StoreGUID": pfstoreGUID, "ReplicaID": str(1)}) public_folders = ({ "IPM_SUBTREE": ({}, 2), "NON_IPM_SUBTREE": ({ "EFORMS REGISTRY": ({}, 4), "Events Root": ({}, -1), "OFFLINE ADDRESS BOOK": ({ "/o=%s/cn=addrlists/cn=oabs/cn=Default Offline Address Book" % (names.firstorg): ({}, 9), }, 6), "SCHEDULE+ FREE BUSY": ({ "EX:/o=%s/ou=%s" % (names.firstorg.lower(), names.firstou.lower()): ({}, 8), }, 5), }, 3), }, 1) self.add_one_public_folder(0, ("Public Folder Root",), public_folders[0], public_folders[1], names) def lookup_server(self, cn, attributes=[]): # Step 1. Search Server object filter = "(&(objectClass=server)(cn=%s))" % cn res = self.ldb.search("", scope=ldb.SCOPE_SUBTREE, expression=filter, attrs=attributes) if len(res) != 1: raise NoSuchServer(cn) return res[0] def lookup_mailbox_user(self, server, username, attributes=[]): """Check if a user already exists in openchange database. :param server: Server object name :param username: Username object :return: LDB Object of the user """ server_dn = self.lookup_server(server, []).dn # Step 2. Search User object filter = "(&(objectClass=mailbox)(cn=%s))" % (username) return self.ldb.search(server_dn, scope=ldb.SCOPE_SUBTREE, expression=filter, attrs=attributes) def lookup_public_folder(self, server, displayname, attributes=[]): """Retrieve the record for a public folder matching a specific display name :param server: Server Object Name :param displayname: Display Name of the Folder :param attributes: Requested Attributes :return: LDB Object of the Folder """ server_dn = self.lookup_server(server, []).dn filter = "(&(objectClass=publicfolder)(PidTagDisplayName=%s))" % (displayname) return self.ldb.search(server_dn, scope=ldb.SCOPE_SUBTREE, expression=filter, attrs=attributes) def get_message_attribute(self, server, attribute): """Retrieve attribute value from given message database (server). :param server: Server object name """ return int(self.lookup_server(server, [attribute])[attribute][0], 10) def get_message_ReplicaID(self, server): """Retrieve current mailbox Replica ID for given message database (server). :param server: Server object name """ return self.get_message_attribute(server, "ReplicaID") def get_message_GlobalCount(self, server): """Retrieve current mailbox Global Count for given message database (server). :param server: Server object name """ return self.get_message_attribute(server, "GlobalCount") def set_message_GlobalCount(self, server, GlobalCount): """Update current mailbox GlobalCount for given message database (server). :param server: Server object name :param index: Mailbox new GlobalCount value """ server_dn = self.lookup_server(server, []).dn newGlobalCount = """ dn: %s changetype: modify replace: GlobalCount GlobalCount: %d """ % (server_dn, GlobalCount) self.ldb.transaction_start() try: self.ldb.modify_ldif(newGlobalCount) finally: self.ldb.transaction_commit() def get_message_ChangeNumber(self, server): """Retrieve current mailbox Global Count for given message database (server). :param server: Server object name """ return self.get_message_attribute(server, "ChangeNumber") def set_message_ChangeNumber(self, server, ChangeNumber): """Update current mailbox ChangeNumber for given message database (server). :param server: Server object name :param index: Mailbox new ChangeNumber value """ server_dn = self.lookup_server(server, []).dn newChangeNumber = """ dn: %s changetype: modify replace: ChangeNumber ChangeNumber: %d """ % (server_dn, ChangeNumber) self.ldb.transaction_start() try: self.ldb.modify_ldif(newChangeNumber) finally: self.ldb.transaction_commit() def reverse_int64counter(GlobalCount): rev_counter = 0 for x in xrange(6): sh = x * 8 unsh = (7-x) * 8 rev_counter = rev_counter | (((GlobalCount >> sh) & 0xff) << unsh) return rev_counter def gen_mailbox_folder_fid(GlobalCount, ReplicaID): """Generates a Folder ID from index. :param GlobalCount: Message database global counter :param ReplicaID: Message database replica identifier """ return "%d" % (ReplicaID | reverse_int64counter(GlobalCount)) openchange-2.0/python/openchange/provision.py000066400000000000000000000571041223057412600215250ustar00rootroot00000000000000#!/usr/bin/python # OpenChange provisioning # Copyright (C) Jelmer Vernooij 2008-2009 # Copyright (C) Julien Kerihuel 2009 # # This program is free software; you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by # the Free Software Foundation; either version 3 of the License, or # (at your option) any later version. # # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program. If not, see . # from base64 import b64encode import os from openchange import mailbox from samba import Ldb, dsdb from samba.samdb import SamDB import ldb from ldb import LdbError, SCOPE_SUBTREE, SCOPE_BASE from samba import read_and_sub_file from samba.auth import system_session from samba.provision import (setup_add_ldif, setup_modify_ldif) from samba.net import Net from samba.dcerpc import nbt from openchange.urlutils import openchangedb_url __docformat__ = 'restructuredText' DEFAULTSITE = "Default-First-Site-Name" FIRST_ORGANIZATION = "First Organization" FIRST_ORGANIZATION_UNIT = "First Administrative Group" # This is a hack. Kind-of cute, but still a hack def abstract(): import inspect caller = inspect.getouterframes(inspect.currentframe())[1][3] raise NotImplementedError(caller + ' must be implemented in subclass') # Define an abstraction for progress reporting from the provisioning class AbstractProgressReporter(object): def __init__(self): self.currentStep = 0 def reportNextStep(self, stepName): self.currentStep = self.currentStep + 1 self.doReporting(stepName) def doReporting(self, stepName): abstract() # A concrete example of a progress reporter - just provides text output for # each new step. class TextProgressReporter(AbstractProgressReporter): def doReporting(self, stepName): print "[+] Step %d: %s" % (self.currentStep, stepName) class ProvisionNames(object): def __init__(self): self.rootdn = None self.domaindn = None self.configdn = None self.schemadn = None self.dnsdomain = None self.netbiosname = None self.domain = None self.hostname = None self.serverrole = None self.firstorg = None self.firstou = None self.firstorgdn = None # OpenChange dispatcher database specific self.ocfirstorgdn = None self.ocserverdn = None def guess_names_from_smbconf(lp, firstorg=None, firstou=None): """Guess configuration settings to use from smb.conf. :param lp: Loadparm context. :param firstorg: First Organization :param firstou: First Organization Unit """ netbiosname = lp.get("netbios name") hostname = netbiosname.lower() dnsdomain = lp.get("realm") dnsdomain = dnsdomain.lower() serverrole = lp.get("server role") # Note: "server role" can have many forms, even for the same function: # "member server", "domain controller", "active directory domain # controller"... if "domain controller" in serverrole or serverrole == "member server": domain = lp.get("workgroup") domaindn = "DC=" + dnsdomain.replace(".", ",DC=") else: domain = netbiosname domaindn = "CN=" + netbiosname rootdn = domaindn configdn = "CN=Configuration," + rootdn schemadn = "CN=Schema," + configdn sitename = DEFAULTSITE names = ProvisionNames() names.serverrole = serverrole names.rootdn = rootdn names.domaindn = domaindn names.configdn = configdn names.schemadn = schemadn names.dnsdomain = dnsdomain names.domain = domain names.netbiosname = netbiosname names.hostname = hostname names.sitename = sitename if firstorg is None: firstorg = FIRST_ORGANIZATION if firstou is None: firstou = FIRST_ORGANIZATION_UNIT names.firstorg = firstorg names.firstou = firstou names.firstorgdn = "CN=%s,CN=Microsoft Exchange,CN=Services,%s" % (firstorg, configdn) names.serverdn = "CN=%s,CN=Servers,CN=%s,CN=Sites,%s" % (netbiosname, sitename, configdn) # OpenChange dispatcher DB names names.ocserverdn = "CN=%s,%s" % (names.netbiosname, names.domaindn) names.ocfirstorg = firstorg names.ocfirstorgdn = "CN=%s,CN=%s,%s" % (firstou, names.ocfirstorg, names.ocserverdn) return names def provision_schema(setup_path, names, lp, creds, reporter, ldif, msg, modify_mode=False): """Provision/modify schema using LDIF specified file :param setup_path: Path to the setup directory. :param names: provision names object. :param lp: Loadparm context :param creds: Credentials Context :param reporter: A progress reporter instance (subclass of AbstractProgressReporter) :param ldif: path to the LDIF file :param msg: reporter message :param modify_mode: whether entries are added or modified """ session_info = system_session() db = SamDB(url=get_ldb_url(lp, creds, names), session_info=session_info, credentials=creds, lp=lp) db.transaction_start() try: reporter.reportNextStep(msg) if modify_mode: ldif_function = setup_modify_ldif else: ldif_function = setup_add_ldif ldif_function(db, setup_path(ldif), { "FIRSTORG": names.firstorg, "FIRSTORGDN": names.firstorgdn, "CONFIGDN": names.configdn, "SCHEMADN": names.schemadn, "DOMAINDN": names.domaindn, "DOMAIN": names.domain, "DNSDOMAIN": names.dnsdomain, "NETBIOSNAME": names.netbiosname, "HOSTNAME": names.hostname }) except: db.transaction_cancel() raise db.transaction_commit() def modify_schema(setup_path, names, lp, creds, reporter, ldif, msg): """Modify schema using LDIF specified file :param setup_path: Path to the setup directory. :param names: provision names object. :param lp: Loadparm context :param creds: Credentials Context :param reporter: A progress reporter instance (subclass of AbstractProgressReporter) :param ldif: path to the LDIF file :param msg: reporter message """ return provision_schema(setup_path, names, lp, creds, reporter, ldif, msg, True) def deprovision_schema(setup_path, names, lp, creds, reporter, ldif, msg, modify_mode=False): """Deprovision/unmodify schema using LDIF specified file, by reverting the modifications contained therein. :param setup_path: Path to the setup directory. :param names: provision names object. :param lp: Loadparm context :param creds: Credentials Context :param reporter: A progress reporter instance (subclass of AbstractProgressReporter) :param ldif: path to the LDIF file :param msg: reporter message :param modify_mode: whether entries are added or modified """ session_info = system_session() db = SamDB(url=get_ldb_url(lp, creds, names), session_info=session_info, credentials=creds, lp=lp) db.transaction_start() try: reporter.reportNextStep(msg) ldif_content = read_and_sub_file(setup_path(ldif), {"FIRSTORG": names.firstorg, "FIRSTORGDN": names.firstorgdn, "CONFIGDN": names.configdn, "SCHEMADN": names.schemadn, "DOMAINDN": names.domaindn, "DOMAIN": names.domain, "DNSDOMAIN": names.dnsdomain, "NETBIOSNAME": names.netbiosname, "HOSTNAME": names.hostname }) if modify_mode: lines = ldif_content.splitlines() keep_line = False entries = [] current_entry = [] entries.append(current_entry) for line in lines: skip_this_line = False if line.startswith("dn:") or line == "": # current_entry.append("") current_entry = [] entries.append(current_entry) keep_line = True elif line.startswith("add:"): keep_line = True line = "delete:" + line[4:] elif line.startswith("replace:"): keep_line = False elif line.startswith("#") or line.strip() == "": skip_this_line = True if keep_line and not skip_this_line: current_entry.append(line) entries.reverse() for entry in entries: ldif_content = "\n".join(entry) print ldif_content try: db.modify_ldif(ldif_content) except: pass else: lines = ldif_content.splitlines() lines.reverse() for line in lines: if line.startswith("dn:"): db.delete(line[4:]) except: db.transaction_cancel() raise db.transaction_commit() def unmodify_schema(setup_path, names, lp, creds, reporter, ldif, msg): """Unmodify schema using LDIF specified file :param setup_path: Path to the setup directory. :param names: provision names object. :param lp: Loadparm context :param creds: Credentials Context :param reporter: A progress reporter instance (subclass of AbstractProgressReporter) :param ldif: path to the LDIF file :param msg: reporter message """ return deprovision_schema(setup_path, names, lp, creds, reporter, ldif, msg, True) def install_schemas(setup_path, names, lp, creds, reporter): """Install the OpenChange-specific schemas in the SAM LDAP database. :param setup_path: Path to the setup directory. :param names: provision names object. :param lp: Loadparm context :param creds: Credentials Context :param reporter: A progress reporter instance (subclass of AbstractProgressReporter) """ session_info = system_session() lp.set("dsdb:schema update allowed", "yes") # Step 1. Extending the prefixmap attribute of the schema DN record names = guess_names_from_smbconf(lp, None, None) samdb = SamDB(url=get_ldb_url(lp, creds, names), session_info=session_info, credentials=creds, lp=lp) reporter.reportNextStep("Register Exchange OIDs") try: schemadn = str(names.schemadn) current = samdb.search(expression="objectClass=classSchema", base=schemadn, scope=SCOPE_BASE) schema_ldif = "" prefixmap_data = "" for ent in current: schema_ldif += samdb.write_ldif(ent, ldb.CHANGETYPE_NONE) prefixmap_data = open(setup_path("AD/prefixMap.txt"), 'r').read() prefixmap_data = b64encode(prefixmap_data) # We don't actually add this ldif, just parse it prefixmap_ldif = "dn: %s\nprefixMap:: %s\n\n" % (schemadn, prefixmap_data) dsdb._dsdb_set_schema_from_ldif(samdb, prefixmap_ldif, schema_ldif, schemadn) except RuntimeError as err: print ("[!] error while provisioning the prefixMap: %s" % str(err)) except LdbError as err: print ("[!] error while provisioning the prefixMap: %s" % str(err)) try: provision_schema(setup_path, names, lp, creds, reporter, "AD/oc_provision_schema_attributes.ldif", "Add Exchange attributes to Samba schema") provision_schema(setup_path, names, lp, creds, reporter, "AD/oc_provision_schema_auxiliary_class.ldif", "Add Exchange auxiliary classes to Samba schema") provision_schema(setup_path, names, lp, creds, reporter, "AD/oc_provision_schema_objectCategory.ldif", "Add Exchange objectCategory to Samba schema") provision_schema(setup_path, names, lp, creds, reporter, "AD/oc_provision_schema_container.ldif", "Add Exchange containers to Samba schema") provision_schema(setup_path, names, lp, creds, reporter, "AD/oc_provision_schema_subcontainer.ldif", "Add Exchange *sub* containers to Samba schema") provision_schema(setup_path, names, lp, creds, reporter, "AD/oc_provision_schema_sub_CfgProtocol.ldif", "Add Exchange CfgProtocol subcontainers to Samba schema") provision_schema(setup_path, names, lp, creds, reporter, "AD/oc_provision_schema_sub_mailGateway.ldif", "Add Exchange mailGateway subcontainers to Samba schema") provision_schema(setup_path, names, lp, creds, reporter, "AD/oc_provision_schema.ldif", "Add Exchange classes to Samba schema") modify_schema(setup_path, names, lp, creds, reporter, "AD/oc_provision_schema_possSuperior.ldif", "Add possSuperior attributes to Exchange classes") modify_schema(setup_path, names, lp, creds, reporter, "AD/oc_provision_schema_modify.ldif", "Extend existing Samba classes and attributes") except LdbError, ldb_error: print ("[!] error while provisioning the Exchange" " schema classes (%d): %s" % ldb_error.args) try: provision_schema(setup_path, names, lp, creds, reporter, "AD/oc_provision_configuration.ldif", "Exchange Samba with Exchange configuration objects") modify_schema(setup_path, names, lp, creds, reporter, "AD/oc_provision_configuration_finalize.ldif", "Finalize Exchange configuration objects") print "[SUCCESS] Done!" except LdbError, ldb_error: print ("[!] error while provisioning the Exchange configuration" " objects (%d): %s" % ldb_error.args) def get_ldb_url(lp, creds, names): if names.serverrole == "member server": net = Net(creds, lp) dc = net.finddc(domain=names.dnsdomain, flags=nbt.NBT_SERVER_LDAP) url = "ldap://" + dc.pdc_dns_name else: url = lp.samdb_url() return url def get_user_dn(ldb, basedn, username): if not isinstance(ldb, Ldb): raise TypeError("'ldb' argument must be an Ldb intance") ldb_filter = "(&(objectClass=user)(sAMAccountName=%s))" % username res = ldb.search(base=basedn, scope=SCOPE_SUBTREE, expression=ldb_filter, attrs=["*"]) user_dn = None if len(res) == 1: user_dn = res[0].dn.get_linearized() return user_dn def newuser(lp, creds, username=None): """extend user record with OpenChange settings. :param lp: Loadparm context :param creds: Credentials context :param username: Name of user to extend """ names = guess_names_from_smbconf(lp, None, None) db = Ldb(url=get_ldb_url(lp, creds, names), session_info=system_session(), credentials=creds, lp=lp) user_dn = get_user_dn(db, "CN=Users,%s" % names.domaindn, username) if user_dn: extended_user = """ dn: %(user_dn)s changetype: modify add: mailNickName mailNickname: %(username)s add: homeMDB homeMDB: CN=Mailbox Store (%(netbiosname)s),CN=First Storage Group,CN=InformationStore,CN=%(netbiosname)s,CN=Servers,CN=First Administrative Group,CN=Administrative Groups,CN=%(firstorg)s,CN=Microsoft Exchange,CN=Services,CN=Configuration,%(domaindn)s add: homeMTA homeMTA: CN=Mailbox Store (%(netbiosname)s),CN=First Storage Group,CN=InformationStore,CN=%(netbiosname)s,CN=Servers,CN=First Administrative Group,CN=Administrative Groups,CN=%(firstorg)s,CN=Microsoft Exchange,CN=Services,CN=Configuration,%(domaindn)s add: legacyExchangeDN legacyExchangeDN: /o=%(firstorg)s/ou=First Administrative Group/cn=Recipients/cn=%(username)s add: proxyAddresses proxyAddresses: =EX:/o=%(firstorg)s/ou=First Administrative Group/cn=Recipients/cn=%(username)s proxyAddresses: smtp:postmaster@%(dnsdomain)s proxyAddresses: X400:c=US;a= ;p=First Organizati;o=Exchange;s=%(username)s proxyAddresses: SMTP:%(username)s@%(dnsdomain)s replace: msExchUserAccountControl msExchUserAccountControl: 0 """ ldif_value = extended_user % {"user_dn": user_dn, "username": username, "netbiosname": names.netbiosname, "firstorg": names.firstorg, "domaindn": names.domaindn, "dnsdomain": names.dnsdomain} db.modify_ldif(ldif_value) res = db.search(base=user_dn, scope=SCOPE_BASE, attrs=["*"]) if len(res) == 1: record = res[0] else: raise Exception, \ "this should never happen as we just modified the record..." record_keys = map(lambda x: x.lower(), record.keys()) if "displayname" not in record_keys: extended_user = "dn: %s\nadd: displayName\ndisplayName: %s\n" % (user_dn, username) db.modify_ldif(extended_user) if "mail" not in record_keys: extended_user = "dn: %s\nadd: mail\nmail: %s@%s\n" % (user_dn, username, names.dnsdomain) db.modify_ldif(extended_user) print "[+] User %s extended and enabled" % username else: print "[!] User '%s' not found" % username def accountcontrol(lp, creds, username=None, value=0): """enable/disable an OpenChange user account. :param lp: Loadparm context :param creds: Credentials context :param username: Name of user to disable :param value: the control value """ names = guess_names_from_smbconf(lp, None, None) db = Ldb(url=get_ldb_url(lp, creds, names), session_info=system_session(), credentials=creds, lp=lp) user_dn = get_user_dn(db, "CN=Users,%s" % names.domaindn, username) extended_user = """ dn: %s changetype: modify replace: msExchUserAccountControl msExchUserAccountControl: %d """ % (user_dn, value) db.modify_ldif(extended_user) if value == 2: print "[+] Account %s disabled" % username else: print "[+] Account %s enabled" % username def provision(setup_path, lp, creds, firstorg=None, firstou=None, reporter=None): """Extend Samba4 with OpenChange data. :param setup_path: Path to the setup directory :param lp: Loadparm context :param creds: Credentials context :param firstorg: First Organization :param firstou: First Organization Unit :param reporter: A progress reporter instance (subclass of AbstractProgressReporter) If a progress reporter is not provided, a text output reporter is provided """ names = guess_names_from_smbconf(lp, firstorg, firstou) print "NOTE: This operation can take several minutes" if reporter is None: reporter = TextProgressReporter() # Install OpenChange-specific schemas install_schemas(setup_path, names, lp, creds, reporter) def deprovision(setup_path, lp, creds, firstorg=None, firstou=None, reporter=None): """Remote all configuration entries added by the OpenChange installation. :param setup_path: Path to the setup directory. :param names: provision names object. :param lp: Loadparm context :param creds: Credentials Context :param reporter: A progress reporter instance (subclass of AbstractProgressReporter) """ if reporter is None: reporter = TextProgressReporter() session_info = system_session() lp.set("dsdb:schema update allowed", "yes") names = guess_names_from_smbconf(lp, None, None) samdb = SamDB(url=get_ldb_url(lp, creds, names), session_info=session_info, credentials=creds, lp=lp) try: deprovision_schema(setup_path, names, lp, creds, reporter, "AD/oc_provision_configuration.ldif", "Remove Exchange configuration objects") except LdbError, ldb_error: print ("[!] error while deprovisioning the Exchange configuration" " objects (%d): %s" % ldb_error.args) except RuntimeError as err: print ("[!] error while deprovisioning the Exchange configuration" " objects (%d): %s" % ldb_error.args) ## NOTE: AD schema objects cannot be deleted (it's a feature!) # try: # unmodify_schema(setup_path, names, lp, creds, reporter, "AD/oc_provision_schema_modify.ldif", "Remove exchange attributes from existing Samba classes") # unmodify_schema(setup_path, names, lp, creds, reporter, "AD/oc_provision_schema_possSuperior.ldif", "Remove possSuperior attributes to Exchange classes") # deprovision_schema(setup_path, names, lp, creds, reporter, "AD/oc_provision_schema.ldif", "Remove Exchange classes from Samba schema") # deprovision_schema(setup_path, names, lp, creds, reporter, "AD/oc_provision_schema_sub_mailGateway.ldif", "Remove Exchange mailGateway subcontainers from Samba schema") # deprovision_schema(setup_path, names, lp, creds, reporter, "AD/oc_provision_schema_sub_CfgProtocol.ldif", "Remove Exchange CfgProtocol subcontainers from Samba schema") # deprovision_schema(setup_path, names, lp, creds, reporter, "AD/oc_provision_schema_subcontainer.ldif", "Remove Exchange *sub* containers from Samba schema") # deprovision_schema(setup_path, names, lp, creds, reporter, "AD/oc_provision_schema_container.ldif", "Remove Exchange containers from Samba schema") # deprovision_schema(setup_path, names, lp, creds, reporter, "AD/oc_provision_schema_objectCategory.ldif", "Remove Exchange objectCategory from Samba schema") # deprovision_schema(setup_path, names, lp, creds, reporter, "AD/oc_provision_schema_auxiliary_class.ldif", "Remove Exchange auxiliary classes from Samba schema") # deprovision_schema(setup_path, names, lp, creds, reporter, "AD/oc_provision_schema_attributes.ldif", "Remove Exchange attributes from Samba schema") # print "[SUCCESS] Done!" # except LdbError, ldb_error: # print ("[!] error while deprovisioning the Exchange" # " schema classes (%d): %s" # % ldb_error.args) def openchangedb_provision(lp, firstorg=None, firstou=None, mapistore=None): """Create the OpenChange database. :param lp: Loadparm context :param firstorg: First Organization :param firstou: First Organization Unit :param mapistore: The public folder store type (fsocpf, sqlite, etc) """ names = guess_names_from_smbconf(lp, firstorg, firstou) print "Setting up openchange db" openchange_ldb = mailbox.OpenChangeDB(openchangedb_url(lp)) openchange_ldb.setup() print "Adding root DSE" openchange_ldb.add_rootDSE(names.ocserverdn, names.firstorg, names.firstou) # Add a server object # It is responsible for holding the GlobalCount identifier (48 bytes) # and the Replica identifier openchange_ldb.add_server(names.ocserverdn, names.netbiosname, names.firstorg, names.firstou) print "[+] Public Folders" print "===================" openchange_ldb.add_public_folders(names) def find_setup_dir(): """Find the setup directory used by provision.""" dirname = os.path.dirname(__file__) if "/site-packages/" in dirname: prefix = dirname[:dirname.index("/site-packages/")] for suffix in ["share/openchange/setup", "share/setup", "share/samba/setup", "setup"]: ret = os.path.join(prefix, suffix) if os.path.isdir(ret): return ret # In source tree ret = os.path.join(dirname, "../../setup") if os.path.isdir(ret): return ret raise Exception("Unable to find setup directory.") openchange-2.0/python/openchange/tests/000077500000000000000000000000001223057412600202565ustar00rootroot00000000000000openchange-2.0/python/openchange/tests/__init__.py000066400000000000000000000005011223057412600223630ustar00rootroot00000000000000 def test_suite(): import unittest loader = unittest.TestLoader() suite = unittest.TestSuite() from openchange.tests import (test_provision, test_mailbox) suite.addTests(loader.loadTestsFromModule(test_provision)) suite.addTests(loader.loadTestsFromModule(test_mailbox)) return suite openchange-2.0/python/openchange/tests/test_mailbox.py000066400000000000000000000051451223057412600233270ustar00rootroot00000000000000#!/usr/bin/python # OpenChange provisioning # Copyright (C) Jelmer Vernooij 2009 # # This program is free software; you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by # the Free Software Foundation; either version 3 of the License, or # (at your option) any later version. # # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program. If not, see . # from openchange.mailbox import NoSuchServer, OpenChangeDB, gen_mailbox_folder_fid import os import unittest class OpenChangeDBTests(unittest.TestCase): """Tests for OpenChangeDB.""" def setUp(self): if os.path.exists("openchange.ldb"): os.unlink("openchange.ldb") self.db = OpenChangeDB("openchange.ldb") self.db.setup() def test_user_exists_no_server(self): self.assertRaises(NoSuchServer, self.db.user_exists, "someserver", "foo") def test_server_lookup_doesnt_exist(self): self.assertRaises(NoSuchServer, self.db.lookup_server, "nonexistantserver") def test_server_lookup(self): self.db.add_server("dc=blaserver", "blaserver", "firstorg", "firstou") self.assertEquals("dc=blaserver", str(self.db.lookup_server("blaserver")['dn'])) def test_add_mailbox_user(self): self.db.add_server("cn=myserver", "myserver", "firstorg", "firstou") self.db.add_mailbox_user("cn=firstorg,cn=firstou,cn=myserver", "someuser") self.assertTrue(self.db.user_exists("myserver", "someuser")) def test_msg_globalcount_initial(self): self.db.add_server("dc=myserver", "myserver", "firstorg", "firstou") self.assertEquals(1, self.db.get_message_GlobalCount("myserver")) def test_set_msg_globalcount(self): self.db.add_server("dc=myserver", "myserver", "firstorg", "firstou") self.db.set_message_GlobalCount("myserver", 42) self.assertEquals(42, self.db.get_message_GlobalCount("myserver")) def test_msg_replicaid_initial(self): self.db.add_server("dc=myserver", "myserver", "firstorg", "firstou") self.assertEquals(1, self.db.get_message_ReplicaID("myserver")) class MailboxFIDTests(unittest.TestCase): def test_simple(self): self.assertEquals("0x00000000109282806", gen_mailbox_folder_fid(4242, 534534)) openchange-2.0/python/openchange/tests/test_provision.py000066400000000000000000000034361223057412600237250ustar00rootroot00000000000000#!/usr/bin/python # OpenChange provisioning # Copyright (C) Jelmer Vernooij 2009 # # This program is free software; you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by # the Free Software Foundation; either version 3 of the License, or # (at your option) any later version. # # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program. If not, see . # from samba import param from samba.credentials import Credentials from samba.tests import TestCaseInTempDir from samba.tests.samdb import SamDBTestCase from openchange.provision import (install_schemas, openchangedb_provision, guess_names_from_smbconf, find_setup_dir) import os import shutil class ExtendedSamDBTestCase(SamDBTestCase): def test_install_schemas(self): def setup_path(relpath): return os.path.join(find_setup_dir(), relpath) names = guess_names_from_smbconf(self.lp) creds = Credentials() creds.set_anonymous() self.lp.set("sam database", os.path.join(self.tempdir, "samdb.ldb")) install_schemas(setup_path, names, self.lp, creds) class OpenChangeDBProvisionTestCase(TestCaseInTempDir): def test_provision(self): lp = param.LoadParm() lp.load_default() lp.set("private dir", self.tempdir) openchangedb_provision(lp) shutil.rmtree(os.path.join(self.tempdir, "mapistore")) os.unlink(os.path.join(self.tempdir, "openchange.ldb")) openchange-2.0/python/openchange/urlutils.py000066400000000000000000000017141223057412600213540ustar00rootroot00000000000000#!/usr/bin/python # OpenChange provisioning # Copyright (C) Jelmer Vernooij 2008-2009 # Copyright (C) Julien Kerihuel 2009 # Copyright (C) Brad Hards 2010 # # This program is free software; you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by # the Free Software Foundation; either version 3 of the License, or # (at your option) any later version. # # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program. If not, see . # import os def openchangedb_url(lp): return os.path.join(lp.get("private dir"), "openchange.ldb") openchange-2.0/python/openchange/utils/000077500000000000000000000000001223057412600202545ustar00rootroot00000000000000openchange-2.0/python/openchange/utils/__init__.py000066400000000000000000000000001223057412600223530ustar00rootroot00000000000000openchange-2.0/python/openchange/utils/fdunix.py000066400000000000000000000111131223057412600221200ustar00rootroot00000000000000# fdunix.py -- OpenChange RPC-over-HTTP implementation # # Copyright (C) 2012 Wolfgang Sourdeau # # This program is free software; you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by # the Free Software Foundation; either version 3 of the License, or # (at your option) any later version. # # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program. If not, see . # """A module that provides functions to send and receive a filedescriptor over a unix socket. """ from ctypes import * from struct import pack_into, unpack_from from os import fdopen, O_RDONLY, O_WRONLY, O_RDWR from fcntl import fcntl, F_GETFL from socket import fromfd, _socketobject, AF_INET, SOCK_STREAM # definitions SOL_SOCKET = 1 SCM_RIGHTS = 1 c_socklen_t = c_uint32 class CMSGHdr(Structure): _fields_ = [("cmsg_len", c_size_t), ("cmsg_level", c_int), ("cmsg_type", c_int)] FDBuffer = (c_byte * sizeof(c_int)) class CMSG(Structure): # The cmsg_data must be an array of chars rather than a pointer of chars, # therefore we must diverge from the C struct due to the fact that ctypes # only accept definitions of fixed-length arrays. _fields_ = [("cmsg_hdr", CMSGHdr), ("cmsg_data", FDBuffer)] class IOVec(Structure): _fields_ = [("iov_base", c_char_p), ("iov_len", c_size_t)] class MSGHdr(Structure): _fields_ = [("msg_name", c_char_p), ("msg_namelen", c_socklen_t), ("msg_iov", POINTER(IOVec)), ("msg_iovlen", c_size_t), ("msg_control", POINTER(CMSG)), ("msg_controllen", c_size_t), ("msg_flags", c_int)] def CMSG_ALIGN(x): return ((x + sizeof(c_size_t) - 1) & ~(sizeof(c_size_t) - 1)) def CMSG_SPACE(x): return CMSG_ALIGN(x) + CMSG_ALIGN(sizeof(CMSGHdr)) def CMSG_LEN(x): return CMSG_ALIGN(sizeof(CMSGHdr)) + x # symbols setup libc = CDLL("libc.so.6", use_errno=True) if libc is None: raise RuntimeError("could not open C library") sendmsg = libc.sendmsg sendmsg.argtypes = (c_int, POINTER(MSGHdr), c_int) recvmsg = libc.recvmsg recvmsg.argtypes = (c_int, POINTER(MSGHdr), c_int) strerror = libc.strerror strerror.restype = c_char_p strerror.argtypes = (c_int,) errno = libc.errno def send_socket(socket, sobject): """This function sends a filedescriptor. socket: must be a unix socket fd: must be a socket of a socket object Returns True on success, False otherwise """ if not isinstance(sobject, _socketobject): raise TypeError("'sobject' must either be a file or a socket object") iov = IOVec() iov.iov_base = "A" iov.iov_len = 1 cmsg = CMSG() cmsg.cmsg_hdr.cmsg_len = CMSG_LEN(sizeof(c_int)) cmsg.cmsg_hdr.cmsg_level = SOL_SOCKET cmsg.cmsg_hdr.cmsg_type = SCM_RIGHTS pack_into("i", cmsg.cmsg_data, 0, sobject.fileno()) msgh = MSGHdr() msgh.msg_name = None msgh.msg_namelen = 0 msgh.msg_iov = (iov,) msgh.msg_iovlen = 1 msgh.msg_control = pointer(cmsg) msgh.msg_controllen = CMSG_SPACE(sizeof(c_int)) msgh.msg_flags = 0 rc = sendmsg(socket.fileno(), pointer(msgh), 0) if rc == -1: errno = get_errno() raise OSError(errno, strerror(errno)) return True def receive_socket(socket): """This function receives a socket object via a UNIX socket. socket: must be a unix socket Returns a socket object or None if the operation fails. """ iov = IOVec() iov.iov_base = "A" iov.iov_len = 1 cmsg = CMSG() cmsg.cmsg_hdr.cmsg_len = CMSG_LEN(sizeof(c_int)) msgh = MSGHdr() msgh.msg_name = None msgh.msg_namelen = 0 msgh.msg_iov = (iov,) msgh.msg_iovlen = 1 msgh.msg_control = pointer(cmsg) msgh.msg_controllen = CMSG_SPACE(sizeof(c_int)) msgh.msg_flags = 0 # rc = recvmsg(socket.fileno(), pointer(msgh), 0) rc = recvmsg(socket.fileno(), pointer(msgh), 0) if rc == -1: errno = get_errno() raise OSError(errno, strerror(errno)) (value,) = unpack_from("i", cmsg.cmsg_data) # the 'mode' parameter should probably passed as part of the message (fd,) = unpack_from("i", cmsg.cmsg_data) newfile = fromfd(fd, AF_INET, SOCK_STREAM) return newfile openchange-2.0/python/openchange/utils/packets.py000066400000000000000000000573031223057412600222700ustar00rootroot00000000000000# packets.py -- OpenChange RPC-over-HTTP implementation # # Copyright (C) 2012 Wolfgang Sourdeau # # This program is free software; you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by # the Free Software Foundation; either version 3 of the License, or # (at your option) any later version. # # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program. If not, see . # import logging from socket import _socketobject, MSG_WAITALL from struct import pack, unpack_from from uuid import UUID PFC_FIRST_FRAG = 1 PFC_LAST_FRAG = 2 PFC_PENDING_CANCEL = 4 PFC_SUPPORT_HEADER_SIGN = 4 PFC_RESERVED_1 = 8 PFC_CONC_MPX = 16 PFC_DID_NOT_EXECUTE = 32 PFC_MAYBE = 64 PFC_OBJECT_UUID = 128 PFC_FLAG_LABELS = ("PFC_FIRST_FRAG", "PFC_LAST_FRAG", "PFC_(PENDING_CANCEL|SUPPORT_HEADER_SIGN)", "PFC_RESERVED_1", "PFC_CONC_MPX", "PFC_DID_NOT_EXECUTE", "PFC_MAYBE", "PFC_OBJECT_UUID") # taken from dcerpc.idl DCERPC_PKT_REQUEST = 0 DCERPC_PKT_PING = 1 DCERPC_PKT_RESPONSE = 2 DCERPC_PKT_FAULT = 3 DCERPC_PKT_WORKING = 4 DCERPC_PKT_NOCALL = 5 DCERPC_PKT_REJECT = 6 DCERPC_PKT_ACK = 7 DCERPC_PKT_CL_CANCEL = 8 DCERPC_PKT_FACK = 9 DCERPC_PKT_CANCEL_ACK = 10 DCERPC_PKT_BIND = 11 DCERPC_PKT_BIND_ACK = 12 DCERPC_PKT_BIND_NAK = 13 DCERPC_PKT_ALTER = 14 DCERPC_PKT_ALTER_RESP = 15 DCERPC_PKT_AUTH_3 = 16 DCERPC_PKT_SHUTDOWN = 17 DCERPC_PKT_CO_CANCEL = 18 DCERPC_PKT_ORPHANED = 19 DCERPC_PKT_RTS = 20 DCERPC_PKG_LABELS = ("DCERPC_PKT_REQUEST", "DCERPC_PKT_PING", "DCERPC_PKT_RESPONSE", "DCERPC_PKT_FAULT", "DCERPC_PKT_WORKING", "DCERPC_PKT_NOCALL", "DCERPC_PKT_REJECT", "DCERPC_PKT_ACK", "DCERPC_PKT_CL_CANCEL", "DCERPC_PKT_FACK", "DCERPC_PKT_CANCEL_ACK", "DCERPC_PKT_BIND", "DCERPC_PKT_BIND_ACK", "DCERPC_PKT_BIND_NAK", "DCERPC_PKT_ALTERA", "DCERPC_PKT_ALTER_RESP", "DCERPC_PKT_AUTH_3", "DCERPC_PKT_SHUTDOWN", "DCERPC_PKT_CO_CANCEL", "DCERPC_PKT_ORPHANED", "DCERPC_PKT_RTS") RTS_FLAG_NONE = 0 RTS_FLAG_PING = 1 RTS_FLAG_OTHER_CMD = 2 RTS_FLAG_RECYCLE_CHANNEL = 4 RTS_FLAG_IN_CHANNEL = 8 RTS_FLAG_OUT_CHANNEL = 0x10 RTS_FLAG_EOF = 0x20 RTS_FLAG_ECHO = 0x40 RTS_FLAG_LABELS = ("RTS_FLAG_PING", "RTS_FLAG_OTHER_CMD", "RTS_FLAG_RECYCLE_CHANNEL", "RTS_FLAG_IN_CHANNEL", "RTS_FLAG_OUT_CHANNEL", "RTS_FLAG_EOF", "RTS_FLAG_ECHO") RTS_CMD_RECEIVE_WINDOW_SIZE = 0 RTS_CMD_FLOW_CONTROL_ACK = 1 RTS_CMD_CONNECTION_TIMEOUT = 2 RTS_CMD_COOKIE = 3 RTS_CMD_CHANNEL_LIFETIME = 4 RTS_CMD_CLIENT_KEEPALIVE = 5 RTS_CMD_VERSION = 6 RTS_CMD_EMPTY = 7 RTS_CMD_PADDING = 8 RTS_CMD_NEGATIVE_ANCE = 9 RTS_CMD_ANCE = 10 RTS_CMD_CLIENT_ADDRESS = 11 RTS_CMD_ASSOCIATION_GROUP_ID = 12 RTS_CMD_DESTINATION = 13 RTS_CMD_PING_TRAFFIC_SENT_NOTIFY = 14 RTS_CMD_SIZES = (8, 28, 8, 20, 8, 8, 8, 4, 8, 4, 4, 8, 20, 8, 8) RTS_CMD_DATA_LABELS = ("ReceiveWindowSize", "FlowControlAck", "ConnectionTimeout", "Cookie", "ChannelLifetime", "ClientKeepalive", "Version", "Empty", "Padding", "NegativeANCE", "ANCE", "ClientAddress", "AssociationGroupId", "Destination", "PingTrafficSentNotify") RPC_C_AUTHN_NONE = 0x0 RPC_C_AUTHN_GSS_NEGOTIATE = 0x9 # SPNEGO RPC_C_AUTHN_WINNT = 0xa # NTLM RPC_C_AUTHN_GSS_SCHANNEL = 0xe # TLS RPC_C_AUTHN_GSS_KERBEROS = 0x10 # Kerberos RPC_C_AUTHN_NETLOGON = 0x44 # Netlogon RPC_C_AUTHN_DEFAULT = 0xff # (NTLM) RPC_C_AUTHN_LEVEL_DEFAULT = 0 RPC_C_AUTHN_LEVEL_NONE = 1 RPC_C_AUTHN_LEVEL_CONNECT = 2 RPC_C_AUTHN_LEVEL_CALL = 3 RPC_C_AUTHN_LEVEL_PKT = 4 RPC_C_AUTHN_LEVEL_PKT_INTEGRITY = 5 RPC_C_AUTHN_LEVEL_PKT_PRIVACY = 6 class RTSParsingException(IOError): """This exception occurs when a serious issue occurred while parsing an RTS packet. """ pass class RPCPacket(object): def __init__(self, data, logger=None): self.logger = logger # BLOB level self.data = data self.size = 0 # parsed offset from the start of the "data" blob self.offset = 0 # header is common to all PDU self.header = None @staticmethod def from_file(input_file, logger=None): """This static method acts as a constructor and returns an input packet with the proper class, based on the packet headers. The "input_file" parameter must either be a file or a sockect object. """ if isinstance(input_file, _socketobject): def read_file(count): return input_file.recv(count, MSG_WAITALL) elif hasattr(file, "read") and callable(file.read): def read_file(count): return input_file.read(count) else: raise ValueError("'input_file' must either be a socket object or" " provide a 'read' method") fields = ("rpc_vers", "rpc_vers_minor", "ptype", "pfc_flags", "drep", "frag_length", "auth_length", "call_id") header_data = read_file(16) # len_header_data = len(header_data) # if len_header_data < 16: # raise RTSParsingException("read only %d header bytes from input" # % len_header_data) # TODO: value validation values = unpack_from(" 0: flag_values.append(PFC_FLAG_LABELS[exp]) values.append(", ".join(flag_values)) fields = ["ptype", "pfc_flags", "drep", "frag_length", "auth_length", "call_id"] for field in fields[2:]: values.append(self.header[field]) return (fields, values) # fault PDU (stub) class RPCFaultPacket(RPCPacket): def __init__(self, data, logger=None): RPCPacket.__init__(self, data, logger) # bind_ack PDU (incomplete) class RPCBindACKPacket(RPCPacket): def __init__(self, data, logger=None): RPCPacket.__init__(self, data, logger) self.ntlm_payload = None def parse(self): auth_offset = self.header["frag_length"] - self.header["auth_length"] self.ntlm_payload = self.data[auth_offset:] # bind_nak PDU (stub) class RPCBindNAKPacket(RPCPacket): def __init__(self, data, logger=None): RPCPacket.__init__(self, data, logger) # FIXME: command parameters are either int32 values or binary blobs, both when # parsing and when producing class RPCRTSPacket(RPCPacket): parsers = None def __init__(self, data, logger=None): RPCPacket.__init__(self, data, logger) # RTS commands self.commands = [] def parse(self): fields = ("flags", "nbr_commands") values = unpack_from(" 15: raise RTSParsingException("command type unknown: %d" % command_type) self.offset = self.offset + 4 command = {"type": command_type} command_size = RTS_CMD_SIZES[command_type] if command_size > 4: data_size = command_size - 4 if command_type in self.parsers: parser = self.parsers[command_type] data_value = parser(self, data_size) elif data_size == 4: # commands with int32 values (data_value,) = unpack_from(" 0: flags_value.append(RTS_FLAG_LABELS[exp]) values.append(", ".join(flags_value)) values.append(self.header["nbr_commands"]) return (fields, values) # Those are the parser method for commands with a size > 4. They are defined # here since the "RPCRTSPacket" symbol is not accessible as long as the class # definition is not over RPCRTSPacket.parsers = {RTS_CMD_FLOW_CONTROL_ACK: RPCRTSPacket._parse_command_flow_control_ack, RTS_CMD_COOKIE: RPCRTSPacket._parse_command_cookie, RTS_CMD_ASSOCIATION_GROUP_ID: RPCRTSPacket._parse_command_cookie, RTS_CMD_PADDING: RPCRTSPacket._parse_command_padding_data, RTS_CMD_CLIENT_ADDRESS: RPCRTSPacket._parse_command_client_address} ### OUT packets # bind PDU (strict minimum required for NTLMSSP auth) class RPCBindOutPacket(object): def __init__(self, logger=None): self.logger = logger self.size = 0 self.data = None self.call_id = 1 self.ntlm_payload = None def make(self): if self.data is None: self._make_packet_data() return self.data def _make_packet_data(self): if self.ntlm_payload is None: raise ValueError("'ntlm_payload' attribute must not be None") ntlm_payload_size = len(self.ntlm_payload) align_modulo = ntlm_payload_size % 4 if align_modulo > 0: padding = (4 - align_modulo) * "\0" else: padding = "" len_padding = len(padding) # rfr: 1544f5e0-613c-11d1-93df-00c04fd7bd09, v1 # mgmt: afa8bd80-7d8a-11c9-bef4-08002b102989, v1 svc_guid = UUID('{afa8bd80-7d8a-11c9-bef4-08002b102989}') iface_version_major = 1 iface_version_minor = 0 p_content_elem = ("\x01\x00\x00\x00\x00\x00\x01\x00" "%s%s" "\x04\x5d\x88\x8a\xeb\x1c\xc9\x11\x9f\xe8\x08\x00" "\x2b\x10\x48\x60\x02\x00\x00\x00" % (svc_guid.bytes_le, pack(" 0: len_padding = (4 - align_modulo) else: len_padding = 0 header_data = pack(" 15: raise RTSParsingException("command type unknown: %d (%s)" % (command_type, str(type(command_type)))) self.size = self.size + 4 values = [pack(" 4: if command_type == RTS_CMD_FLOW_CONTROL_ACK: data = self._make_command_flow_control_ack(args[0]) elif (command_type == RTS_CMD_COOKIE or command_type == RTS_CMD_ASSOCIATION_GROUP_ID): data = self._make_command_cookie(args[0]) elif command_type == RTS_CMD_PADDING: data = self._make_command_padding_data(args[0]) elif command_type == RTS_CMD_CLIENT_ADDRESS: data = self._make_command_client_address(args[0]) else: # command with int32 value if self.logger is not None: self.logger.debug("cmd %s with data %d" % (RTS_CMD_DATA_LABELS[command_type], args[0])) data = pack(" # # This program is free software; you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by # the Free Software Foundation; either version 3 of the License, or # (at your option) any later version. # # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program. If not, see . # """This module provides the NTLMAuthHandler class, a WSGI middleware that enables NTLM authentication via RPC to Samba. It works by proxying the NTLMSSP payload between the client and the samba server. Accessorily it could be used against an MS Exchange service, but this is untested. """ # TODO: security checks! from fcntl import flock, LOCK_EX, LOCK_UN import httplib from os import _exit, getpid, getuid, fork, setsid, stat, umask, unlink, \ waitpid, close as close_fd from os.path import join, exists from select import poll, POLLIN, POLLHUP from socket import socket, SHUT_RDWR, AF_INET, AF_UNIX, \ SOCK_STREAM, MSG_WAITALL, error as socket_error from struct import pack, unpack, unpack_from, error as struct_error import sys from time import sleep, time from uuid import uuid4 from openchange.utils.packets import RPCAuth3OutPacket, RPCBindACKPacket, \ RPCBindOutPacket, RPCFaultPacket, RPCPacket, RPCPingOutPacket # TODO: we should make use of port 135 to discover which port our service uses SAMBA_PORT = 1024 # those are left unconfigurable, at least for now CLIENT_TIMEOUT = 60 * 5 # 5 minutes since last use ACTIVITY_TIMEOUT = CLIENT_TIMEOUT # 5 minutes since any socket has been used ## client-daemon protocol: # * server knows client? # client -> server "k" + sizeof(cookie) + cookie # server->client = 0 or 1 (binary) # # * ntlm transaction # client -> server "t" + sizeof(cookie) + cookie + sizeof(ntlm-payload) + # ntlm-payload # server -> client = 0 or 1 (binary) + sizeof(ntlm-payload) + ntlm-payload def _safe_close(socket_obj): try: socket_obj.shutdown(SHUT_RDWR) socket_obj.close() except: pass class _NTLMDaemon(object): def __init__(self, samba_host, socket_filename, owner_pair): self.socket_filename = socket_filename self.owner_pair = owner_pair self.samba_host = samba_host self.client_data = {} def run(self): if exists(self.socket_filename): unlink(self.socket_filename) child_pid = fork() if child_pid == 0: self._daemonize() _exit(0) elif child_pid > 0: # we wait for the child to exit before going on waitpid(child_pid, 0) # we are the child # print >> sys.stderr, "waiting for ntlm daemon to create socket (%d)" % getpid() while not exists(self.socket_filename): pass # print >> sys.stderr, "socket of ntlm daemon now exists (%d)" % getpid() else: raise Exception("failure to fork NTLM daemon") def _daemonize(self): # this code is inspire by the recipe described here: # http://code.activestate.com/recipes/278731-creating-a-daemon-the-python-way/ setsid() import resource MAXFD = 1024 # we close all open file descriptors != sys.stderr.fileno() maxfd = resource.getrlimit(resource.RLIMIT_NOFILE)[1] if (maxfd == resource.RLIM_INFINITY): maxfd = MAXFD if hasattr(sys.stderr, "fileno"): stderr_fileno = sys.stderr.fileno() else: # mod_wsgi replace sys.stderr with a fake file without a "fileno" # method stderr_fileno = -1 # close all fd > 4 for fd in xrange(3, maxfd): if fd != stderr_fileno: try: close_fd(fd) except OSError: pass # free up some memory global httplib del httplib del resource # print >> sys.stderr, "cleanup done" child_pid = fork() if child_pid > 0: _exit(0) print >> sys.stderr, ("NTLMAuthHandler daemon spawned with pid %d" % getpid()) # forked processes inherits lock created by flock, so we need to # unlock the file here # flock(lockf.fileno(), LOCK_UN) # lockf.close() # we are the daemon self._run_as_daemon() def _run_as_daemon(self): client_sockets = {} last_cleanup = time() last_activity = time() # ensure only the current user can connect to our socket umask(0077) # create socket and listen server_socket = socket(AF_UNIX, SOCK_STREAM) server_socket.bind(self.socket_filename) server_socket.listen(10) # The socket must have the same owner as its parent directory, this is # achieved in two ways: either we are running as root and no fence # shall stop us, or we cannot run as anyother used because the socket # creation will already have failed in the target directory. current_uid = getuid() if current_uid == 0: chown(self.socket_filename, self.owner_pair[0], self.owner_pair[1]) elif current_uid != self.owner_pair[0]: unlink(self.socket_filename) raise IOError("The NTLMAuthHandler daemon must either be started" " as root or as the owner of the directory" " specified for 'NTLMAUTHHANDLER_WORKDIR' (current" " uid=%d)." % current_uid) server_fd = server_socket.fileno() fd_pool = poll() fd_pool.register(server_fd, POLLIN) shutdown = False # loop and handle requests while not shutdown: chunks = fd_pool.poll(2000.0) now = time() if len(chunks) == 0: # nothing happened in the last 2 secs if last_activity + 30.0 < now: shutdown = True elif last_cleanup + 60.0 < now: # print >> sys.stderr, ("cleaning up old client ids (%d)" # % getpid()) self._cleanup_client_data(now - CLIENT_TIMEOUT) last_cleanup = now else: last_activity = now for data in chunks: filedesc, event_no = data if filedesc == server_fd: # we are receiving a new connection new_socket = server_socket.accept()[0] new_socket_fd = new_socket.fileno() client_sockets[new_socket_fd] = new_socket fd_pool.register(new_socket_fd, POLLIN) # print >> sys.stderr, ("registered new client socket" # " %d (%d)" # % (new_socket_fd, getpid())) elif filedesc in client_sockets: # print >> sys.stderr, ("handling event %d from client" # " socket %d" % (event_no, filedesc)) client_socket = client_sockets[filedesc] if (event_no & POLLHUP > 0 or not self._process_client_request(client_socket, now)): # print >> sys.stderr, ("removed client socket from" # " pool (%d)" % getpid()) _safe_close(client_socket) fd_pool.unregister(filedesc) del client_sockets[filedesc] else: raise Exception("%d is an unknown file descriptor" " (%d)" % (filedesc, getpid())) # close server socket and remove fs entry _safe_close(server_socket) # unlink(self.socket_filename) # close client sockets [_safe_close(client_socket) for client_socket in client_sockets.itervalues()] print >> sys.stderr, ("NTLMAuthHandler daemon shutdown (%d)" % getpid()) def _cleanup_client_data(self, time_limit): def _cleanup_record(client_id): record = self.client_data[client_id] if "server" in record: # print >> sys.stderr, "closing server socket" server = record["server"] _safe_close(server) del self.client_data[client_id] # we make use of "keys()" here because we cannot use a dictionary as # iterator while adding or removing records for client_id in self.client_data.keys(): if self.client_data[client_id]["last_used"] < time_limit: _cleanup_record(client_id) def _process_client_request(self, client_socket, now): success = True data = client_socket.recv(5, MSG_WAITALL) tag = data[0] len_client_id = unpack_from("> sys.stderr, "len_client_id: %d" % len_client_id # print >> sys.stderr, "type(len_client_id): %s" % type(len_client_id) if len_client_id > 0: client_id = client_socket.recv(len_client_id, MSG_WAITALL) else: client_id = "" if tag == "k": if client_id in self.client_data: self.client_data[client_id]["last_used"] = now response = 1 else: response = 0 client_socket.sendall(pack("> sys.stderr, "* client auth stage1" server = self.client_data[client_id]["server"] # print >> sys.stderr, "host: %s" % str(server.getsockname()) # print >> sys.stderr, "building auth_3 and ping packets" packet = RPCAuth3OutPacket() packet.ntlm_payload = ntlm_payload server.sendall(packet.make()) # FIXME, this is a hack: # A ping at this stage will trigger a connection close from Samba and # an error from Exchange. Since a successful authentication does not # trigger a response from the server, this provides a simple way to # ensure that it passed, without actually performing an RPC operation # on the "mgmt" interface. The choice of "mgmt" was due to the fact # that we want to keep this authenticator middleware to be reusable # for other Samba services while "mgmt" seemes to be the only # available interface from Samba outside of the ones provided by # OpenChange. packet = RPCPingOutPacket() packet.call_id = 2 server.sendall(packet.make()) # print >> sys.stderr, "sent auth3 and ping packets, receiving response" try: packet = RPCPacket.from_file(server) if isinstance(packet, RPCFaultPacket): if packet.header["call_id"] == 2: # the Fault packet related to our Ping operation response = 1 else: response = 0 else: raise ValueError("unexpected packet") except socket_error: # Samba closed the connection response = 1 except struct_error: # Samba closed the connection response = 1 if response == 1: # authentication completed self.client_data[client_id]["status"] = "ok" del self.client_data[client_id]["server"] else: # we start over with the whole process del self.client_data[client_id] _safe_close(server) # print >> sys.stderr, "* done with client auth stage1" return response def _handle_negotiate(self, client_id, ntlm_payload): # print >> sys.stderr, "* client auth stage0" # print >> sys.stderr, "connecting to host" server = None connected = False attempt = 0 while not connected: try: attempt = attempt + 1 # TODO: we should query port 135 for the right service server = socket(AF_INET, SOCK_STREAM) server.connect((self.samba_host, SAMBA_PORT)) connected = True except: print >> sys.stderr, ("NTLMAuthHandler: caught exception when" " connecting to samba host: attempt %d" % attempt) sleep(1) # print >> sys.stderr, "host: %s" % str(server.getsockname()) # print >> sys.stderr, "building bind packet" packet = RPCBindOutPacket() packet.ntlm_payload = ntlm_payload # print >> sys.stderr, "sending bind packet" server.sendall(packet.make()) # print >> sys.stderr, "sent bind packet, receiving response" packet = RPCPacket.from_file(server) # print >> sys.stderr, "response parsed: %s" % packet.pretty_dump() if isinstance(packet, RPCBindACKPacket): # print >> sys.stderr, "ACK received" self.client_data[client_id] = {"status": "challenged", "last_used": time(), "server": server} response = 1 ntlm_payload = packet.ntlm_payload else: response = 0 ntlm_payload = "" # print >> sys.stderr, "* done with client auth stage0" return (response, ntlm_payload) class _NTLMAuthClient(object): def __init__(self, work_dir, samba_host): self.work_dir = work_dir self.samba_host = samba_host self.connection = None def server_knows_client(self, client_id): # print >> sys.stderr, "server knows client? (%d)" % getpid() payload = "k%s%s" % (pack(" 0: code = unpack_from("> sys.stderr, ("server knows client: %d (%d)" # % (code, getpid())) else: # print >> sys.stderr, ("received empty response (%d)" % getpid()) code = 0 return code != 0 def ntlm_transaction(self, client_id="", ntlm_payload=""): # print >> sys.stderr, "ntlm_transaction (%d)" % getpid() payload = ("t%s%s%s%s" % (pack(" 0: (code, len_ntlm_payload) = unpack_from(" 0: ntlm_payload = self._recv_from_server(len_ntlm_payload) if len(ntlm_payload) != len_ntlm_payload: code = 0 else: ntlm_payload = "" else: # print >> sys.stderr, ("received empty response (%d)" % getpid()) code = 0 ntlm_payload = "" # print >> sys.stderr, "ntlm_transaction result: %d (%d)" % (code, getpid()) return (code != 0, ntlm_payload) def _send_to_server(self, payload): if self.connection is None: self._make_connection() # sends a series of bytes to the server and make sure it receives them # by restarting it if needed # print >>sys.stderr, "sending data (%d)" % getpid() sent = False while not sent: try: self.connection.sendall(payload) sent = True except IOError: # print >> sys.stderr, ("(send) reconnecting to server (%d)..." # % getpid()) sleep(1) self._make_connection() # print >>sys.stderr, "sent data (%d)" % getpid() def _recv_from_server(self, nbr_bytes): # print >>sys.stderr, "receiving data (%d)" % getpid() # receives a payload from the server and returns an empty string if # something went wrong, just as if the actual request failed try: payload = self.connection.recv(nbr_bytes, MSG_WAITALL) if payload is None: payload = "" except IOError: # if the server has died, we must return an error anyway payload = "" # print >>sys.stderr, "received data (%d)" % getpid() return payload def _make_connection(self): # we create a lock in order to make sure that we would be the only # process or thread starting a daemon if needed lock_filename = join(self.work_dir, "ntlm-%s.lock" % self.samba_host) if not exists(lock_filename): lockf = open(lock_filename, "w+") lockf.close() lockf = open(lock_filename, "r") # print >> sys.stderr, "acquiring lock (%d)" % getpid() lock_fd = lockf.fileno() flock(lock_fd, LOCK_EX) # print >> sys.stderr, "acquired lock (%d)" % getpid() self.connection = self._connect_to_daemon(self.work_dir, self.samba_host) flock(lock_fd, LOCK_UN) lockf.close() @staticmethod def _connect_to_daemon(work_dir, samba_host): socket_filename = join(work_dir, "ntlm-%s" % samba_host) stat_s = stat(work_dir) connection = socket(AF_UNIX, SOCK_STREAM) try: connection.connect(socket_filename) except socket_error: # the socket does not exist or is invalid, therefore we need to # respawn the daemon daemon = _NTLMDaemon(samba_host, socket_filename, (stat_s.st_uid, stat_s.st_gid)) daemon.run() connection.connect(socket_filename) return connection def close(self): if self.connection is not None: _safe_close(self.connection) self.connection = None class NTLMAuthHandler(object): """ HTTP/1.0 ``NTLM`` authentication middleware Parameters: application -- the application object that is called only upon successful authentication. """ def __init__(self, application): self.application = application def __call__(self, env, start_response): (work_dir, samba_host, cookie_name, has_auth) \ = self._read_environment(env) connection = _NTLMAuthClient(work_dir, samba_host) # TODO: validate authorization payload cookies = self._get_cookies(env) if cookie_name in cookies: client_id = cookies[cookie_name] server_knows_client = connection.server_knows_client(client_id) # print >> sys.stderr, \ # "server knows client (pid: %d): %s" % (getpid(), # str(server_knows_client)) else: server_knows_client = False # print >> sys.stderr, "client did not pass auth cookie" if has_auth: auth = env["HTTP_AUTHORIZATION"] ntlm_payload = auth[5:].decode("base64") if server_knows_client: # stage 1, where the client has already received the challenge # from the server and is now sending an AUTH message # server_knows_client implies that client_id is valid (success, payload) \ = connection.ntlm_transaction(client_id, ntlm_payload) if success: connection.close() response = self.application(env, start_response) else: response = self._in_progress_response(start_response) else: # stage 0, where the cookie has not been set yet and where we # know the NTLM payload is a NEGOTIATE message client_id = str(uuid4()) (success, ntlm_payload) \ = connection.ntlm_transaction(client_id, ntlm_payload) if success: response = self._in_progress_response(start_response, ntlm_payload, client_id, cookie_name) else: response = self._in_progress_response(start_response) else: if server_knows_client: # authenticated, where no NTLM payload is provided anymore connection.close() response = self.application(env, start_response) else: # this client has never been seen # note: this is the only case where the "connection" object is # uselessly instantiated response = self._in_progress_response(start_response, None) connection.close() return response @staticmethod def _read_environment(env): if "NTLMAUTHHANDLER_WORKDIR" in env: work_dir = env["NTLMAUTHHANDLER_WORKDIR"] if not exists(work_dir): raise ValueError("the directory specified for" " 'NTLMAUTHHANDLER_WORKDIR' does not exist:" " '%s'" % work_dir) else: raise ValueError("'NTLMAUTHHANDLER_WORKDIR' is not set in" " the environment") if "SAMBA_HOST" in env: samba_host = env["SAMBA_HOST"] else: print >> sys.stderr, \ "'SAMBA_HOST' not configured, 'localhost' will be used" samba_host = "localhost" if "NTLMAUTHHANDLER_COOKIENAME" in env: cookie_name = env["NTLMAUTHHANDLER_COOKIENAME"] else: cookie_name = "oc-ntlm-auth" has_auth = "HTTP_AUTHORIZATION" in env return (work_dir, samba_host, cookie_name, has_auth) @staticmethod def _get_cookies(env): cookies = {} if "HTTP_COOKIE" in env: cookie_str = env["HTTP_COOKIE"] for pair in cookie_str.split(";"): (key, value) = pair.strip().split("=") cookies[key] = value return cookies @staticmethod def _in_progress_response(start_response, ntlm_data=None, client_id=None, cookie_name=None): status = "401 %s" % httplib.responses[401] content = "More data needed..." headers = [("Content-Type", "text/plain"), ("Content-Length", "%d" % len(content))] if ntlm_data is None: www_auth_value = "NTLM" else: enc_ntlm_data = ntlm_data.encode("base64") www_auth_value = ("NTLM %s" % enc_ntlm_data.strip().replace("\n", "")) if client_id is not None: # MUST occur when ntlm_data is None, can still occur otherwise headers.append(("Set-Cookie", "%s=%s" % (cookie_name, client_id))) headers.append(("WWW-Authenticate", www_auth_value)) start_response(status, headers) return [content] openchange-2.0/python/openchange/web/auth/__init__.py000066400000000000000000000000001223057412600227310ustar00rootroot00000000000000openchange-2.0/qt/000077500000000000000000000000001223057412600141105ustar00rootroot00000000000000openchange-2.0/qt/demo/000077500000000000000000000000001223057412600150345ustar00rootroot00000000000000openchange-2.0/qt/demo/demoapp.cpp000066400000000000000000000106411223057412600171670ustar00rootroot00000000000000#include #include "demoapp.h" #include "../lib/foldermodel.h" #include "../lib/messagesmodel.h" #include using namespace libmapipp; DemoApp::DemoApp() { m_textEdit = new QTextEdit; setCentralWidget( m_textEdit ); createActions(); createMenus(); login(); addFolderDockWidget(); addMessagesDockWidget(); openMessage( 0 ); resize( 1100, 900 ); } void DemoApp::about() { QMessageBox::about( this, tr( "OpenChange GUI Test Harness" ), tr( "This test harness is for demonstrating and testing " "some of the OpenChange functionality. It is not " "intended for use in production.

We mean it.
" ) ); } void DemoApp::createActions() { m_aboutAction = new QAction( tr( "About" ), this ); connect( m_aboutAction, SIGNAL( triggered() ), this, SLOT( about() ) ); m_quitAction = new QAction( tr( "&Quit" ), this ); // Use this if we ever require Qt 4.6 // m_quitAction->setShortcuts( QKeySequence::Quit ); m_quitAction->setShortcut( QKeySequence( Qt::Key_Q, Qt::CTRL ) ); m_quitAction->setStatusTip( tr( "Quit the application" ) ); connect( m_quitAction, SIGNAL( triggered() ), this, SLOT( close() ) ); } void DemoApp::createMenus() { m_fileMenu = menuBar()->addMenu( tr( "&File" ) ); m_fileMenu->addAction( m_quitAction ); m_helpMenu = menuBar()->addMenu( tr( "&Help" ) ); m_helpMenu->addAction( m_aboutAction ); } void DemoApp::login() { // Initialize MAPI Session m_mapi_session = new libmapipp::session(); m_mapi_session->login(); } void DemoApp::addFolderDockWidget() { m_folderDock = new QDockWidget( tr( "Folders" ), this ); FolderModel *folder = new FolderModel( m_mapi_session ); m_folderModel = folder->buildModel(); QTreeView *folderDockView = new QTreeView( m_folderDock ); folderDockView->setModel( m_folderModel ); folderDockView->expandToDepth( 2 ); connect( folderDockView, SIGNAL( clicked(QModelIndex) ), this, SLOT( folderChanged(QModelIndex) ) ); m_folderDock->setWidget( folderDockView ); addDockWidget(Qt::LeftDockWidgetArea, m_folderDock); } void DemoApp::addMessagesDockWidget() { QDockWidget *messagesDock = new QDockWidget( tr( "Messages" ), this ); // Get Default Inbox folder ID. mapi_id_t inbox_id = m_mapi_session->get_message_store().get_default_folder(olFolderInbox); // std::cout << "inbox_id: " << inbox_id << std::endl; // Open Inbox Folder m_folder = new folder(m_mapi_session->get_message_store(), inbox_id); MessagesModel *messages = new MessagesModel( m_folder ); m_messagesDockView = new QTableView( messagesDock ); m_messagesModel = messages->buildModel(); m_messagesDockView->setModel( m_messagesModel ); m_messagesDockView->setShowGrid( false ); m_messagesDockView->resizeColumnsToContents(); m_messagesDockView->resizeRowsToContents(); connect( m_messagesDockView, SIGNAL( clicked(QModelIndex) ), this, SLOT( messageChanged(QModelIndex) ) ); messagesDock->setWidget( m_messagesDockView ); splitDockWidget( m_folderDock, messagesDock, Qt::Horizontal ); } void DemoApp::folderChanged(const QModelIndex &index) { QStandardItem *item = m_folderModel->itemFromIndex( index ); if (item) { qlonglong folderId = item->data().toLongLong(); m_folder = new folder(m_mapi_session->get_message_store(), folderId); MessagesModel *messages = new MessagesModel( m_folder ); m_messagesModel = messages->buildModel(); m_messagesDockView->setModel( m_messagesModel ); } } void DemoApp::messageChanged( const QModelIndex &index ) { QStandardItem *item = m_messagesModel->itemFromIndex( index ); if ( item ) { quint32 messageNumber = item->data().toUInt(); openMessage( messageNumber ); } } void DemoApp::openMessage( quint32 messageNumber ) { libmapipp::folder::message_container_type messages = m_folder->fetch_messages(); // std::cout << "Folder contains " << messages.size() << " messages" << std::endl; // Get the properties we are interested in libmapipp::property_container msg_props = messages[messageNumber]->get_property_container(); msg_props << PR_BODY_HTML; msg_props.fetch(); if ( msg_props[PR_BODY_HTML] ) { QString body = QString( (const char*)msg_props[PR_BODY_HTML] ); m_textEdit->setHtml( body ); } else { m_textEdit->setHtml( QString() ); } } #include "demoapp.moc" openchange-2.0/qt/demo/demoapp.h000066400000000000000000000020361223057412600166330ustar00rootroot00000000000000#ifndef DEMOAPP_H #define DEMOAPP_H #include #include class QAction; class QMenu; class QTextEdit; class QStandardItem; class QTableView; namespace libmapipp { class session; class folder; }; class DemoApp : public QMainWindow { Q_OBJECT public: DemoApp(); private slots: void about(); void folderChanged( const QModelIndex &index ); void messageChanged( const QModelIndex &index ); private: void createActions(); void createMenus(); void login(); void addFolderDockWidget(); void addMessagesDockWidget(); void openMessage( quint32 messageNumber ); QMenu *m_fileMenu; QMenu *m_helpMenu; QAction *m_quitAction; QAction *m_aboutAction; QDockWidget *m_folderDock; QStandardItemModel *m_folderModel; QTableView *m_messagesDockView; QStandardItemModel *m_messagesModel; libmapipp::folder *m_folder; QTextEdit *m_textEdit; libmapipp::session *m_mapi_session; }; #endif openchange-2.0/qt/demo/main.cpp000066400000000000000000000003121223057412600164600ustar00rootroot00000000000000#include "demoapp.h" #include int main(int argc, char *argv[]) { QApplication app(argc, argv); DemoApp *demo = new DemoApp(); demo->show(); return app.exec(); } openchange-2.0/qt/lib/000077500000000000000000000000001223057412600146565ustar00rootroot00000000000000openchange-2.0/qt/lib/foldermodel.cpp000066400000000000000000000053441223057412600176640ustar00rootroot00000000000000#include #include #include #include #include #include #include "foldermodel.h" #include using namespace libmapipp; FolderModel::FolderModel( libmapipp::session *mapi_session ) : m_mapi_session( mapi_session ) { m_folderModel = new QStandardItemModel(); QStringList folderModelHeaders; folderModelHeaders << QString( "Folder Name" ) << QString( "FolderId" ) << QString( "Container Class" ); m_folderModel->setHorizontalHeaderLabels( folderModelHeaders ); } void FolderModel::add_folder_to_tree(libmapipp::folder& up_folder, QStandardItem *parentItem) { property_container up_folder_property_container = up_folder.get_property_container(); up_folder_property_container << PR_DISPLAY_NAME << PR_CONTAINER_CLASS; up_folder_property_container.fetch(); std::string display_name = static_cast(up_folder_property_container[PR_DISPLAY_NAME]); std::string container_class; if (up_folder_property_container[PR_CONTAINER_CLASS]) container_class = static_cast(up_folder_property_container[PR_CONTAINER_CLASS]); QList< QStandardItem * > row; QStandardItem *name = new QStandardItem( QString::fromStdString( display_name ) ); name->setData( (qlonglong)up_folder.get_id() ); QStandardItem *folderId = new QStandardItem( QString::number( up_folder.get_id(), 16 ) ); QStandardItem *containerClass = new QStandardItem( QString::fromStdString( container_class ) ); row << name << folderId << containerClass; parentItem->appendRow( row ); // Fetch Top Information Folder Hierarchy (child folders) folder::hierarchy_container_type hierarchy = up_folder.fetch_hierarchy(); for (unsigned int i = 0; i < hierarchy.size(); ++i) { add_folder_to_tree(*hierarchy[i], name); } } QStandardItemModel* FolderModel::buildModel() { try { // Get Default Top Information Store folder ID mapi_id_t top_folder_id = m_mapi_session->get_message_store().get_default_folder(olFolderTopInformationStore); // Open Top Information Folder folder top_folder( m_mapi_session->get_message_store(), top_folder_id ); QStandardItem *parentItem = m_folderModel->invisibleRootItem(); add_folder_to_tree(top_folder, parentItem); } catch (mapi_exception e) // Catch any mapi exceptions { std::cout << "MAPI Exception @ main: " << e.what() << std::endl; } catch (std::runtime_error e) // Catch runtime exceptions { std::cout << "std::runtime_error exception @ main: " << e.what() << std::endl; } return m_folderModel; } #include "foldermodel.moc" openchange-2.0/qt/lib/foldermodel.h000066400000000000000000000007711223057412600173300ustar00rootroot00000000000000#ifndef FOLDERMODEL_H #define FOLDERMODEL_H class QStandardItem; class QStandardItemModel; namespace libmapipp { class folder; class session; } class FolderModel : public QStandardItemModel { Q_OBJECT public: FolderModel( libmapipp::session *mapi_session ); QStandardItemModel* buildModel(); private: libmapipp::session *m_mapi_session; QStandardItemModel *m_folderModel; void add_folder_to_tree(libmapipp::folder& up_folder, QStandardItem *parentItem); }; #endif openchange-2.0/qt/lib/messagesmodel.cpp000066400000000000000000000033111223057412600202100ustar00rootroot00000000000000#include "messagesmodel.h" #include using namespace libmapipp; MessagesModel::MessagesModel( libmapipp::folder *folder ): m_mapi_folder( folder ) { } QStandardItemModel* MessagesModel::buildModel() { // Fetch messages in Inbox Folder folder::message_container_type messages = m_mapi_folder->fetch_messages(); QStandardItemModel *messagesModel = new QStandardItemModel(); QStringList messagesModelHeaders; messagesModelHeaders << QString( "Topic" ) << QString( "To" ) << QString( "From" ); messagesModel->setHorizontalHeaderLabels( messagesModelHeaders ); for ( unsigned int i = 0; i < messages.size(); ++i ) { property_container message_property_container = messages[i]->get_property_container(); // Add Property Tags to be fetched and then fetch the properties. message_property_container << PR_DISPLAY_TO << PR_CONVERSATION_TOPIC << PR_SENDER_NAME; message_property_container.fetch_all(); std::string to; std::string subject; std::string from; for (property_container::iterator Iter = message_property_container.begin(); Iter != message_property_container.end(); Iter++) { if (Iter.get_tag() == PR_DISPLAY_TO) to = (const char*) *Iter; else if (Iter.get_tag() == PR_CONVERSATION_TOPIC) subject = (const char*) *Iter; else if (Iter.get_tag() == PR_SENDER_NAME) from = (const char*) *Iter; } QList< QStandardItem * > row; row << new QStandardItem( QString::fromStdString( subject ) ); row[0]->setData( (quint32) i ); row << new QStandardItem( QString::fromStdString( to ) ); row << new QStandardItem( QString::fromStdString( from ) ); messagesModel->appendRow( row ); } return messagesModel; } #include "messagesmodel.moc" openchange-2.0/qt/lib/messagesmodel.h000066400000000000000000000006061223057412600176610ustar00rootroot00000000000000#ifndef MESSAGESMODEL_H #define MESSAGESMODEL_H class QStandardItem; #include namespace libmapipp { class folder; class session; } class MessagesModel : public QStandardItemModel { Q_OBJECT public: MessagesModel( libmapipp::folder *folder ); QStandardItemModel *buildModel(); private: libmapipp::folder *m_mapi_folder; }; #endif openchange-2.0/script/000077500000000000000000000000001223057412600147705ustar00rootroot00000000000000openchange-2.0/script/check_exchange000077500000000000000000000117711223057412600176440ustar00rootroot00000000000000#!/usr/bin/perl # # Nagois Plug-In to check Exchange Server # # Bill Edmunds, Academic Services, University of Exeter # 25th March, 2008 # use strict; use lib "nagios/plugins"; use utils qw($TIMEOUT %ERRORS &print_revision &support); use vars qw($PROGNAME); use Time::HiRes qw(gettimeofday tv_interval); # Variables $PROGNAME = 'check_exchange'; my $SUCCESS = 'MAPI_E_SUCCESS'; my $MYTIME = 10; my $version = "1.0"; my $verbose = 0; my $pdb = '/usr/lib/nagios/plugins/check_exchange.ldb'; my $cmd = 'openchangeclient'; my $author = "Bill Edmunds, Academic Services, University of Exeter"; my $email = 'W.Edmunds@exeter.ac.uk'; my ($host, $stime, $etime, $warning, $critical); our($opt_h, $opt_V, $opt_v, $opt_H, $opt_d, $opt_w, $opt_c); my $status = 'UNKNOWN'; $ENV{'BASH_ENV'}=''; $ENV{'ENV'}=''; $ENV{'PATH'}='/usr/local/samba/bin'; $ENV{'LC_ALL'}='C'; # Options use Getopt::Long; Getopt::Long::Configure('bundling'); GetOptions( "V" => \$opt_V, "version" => \$opt_V, "h" => \$opt_h, "help" => \$opt_h, "v+" => \$opt_v, "verbose+" => \$opt_v, "H=s" => \$opt_H, "hostname=s" => \$opt_H, "d=s" => \$opt_d, "database=s" => \$opt_d, "w=f" => \$opt_w, "warning=f" => \$opt_w, "c=f" => \$opt_c, "critical=f" => \$opt_c, ); # -h means help if ($opt_h) { print_help(); exit $ERRORS{'OK'}; } # -V means version if ($opt_V) { print_revision($PROGNAME, "\$Revision: $version \$ "); exit $ERRORS{'OK'}; } # -v means verbose if ($opt_v) { $verbose = 1; print "$PROGNAME: Check access to MS Exchange via Openchange client\n\n"; } # -H means host/profile name $opt_H || plugin_error("No hostname specified"); if (! utils::is_hostname($opt_H)){ plugin_error("$opt_H is not a valid host name"); } else { $host = $opt_H; } # -d means profile database name if (defined($opt_d) && -r $opt_d) { $pdb = $opt_d; } else { plugin_error("No profile database available") if ! -r $pdb; } $verbose && print "$PROGNAME: Profile database is $pdb\n\n"; # -c means critical threshold if ($opt_c && $opt_c =~ /^\d+\.*\d*$/ && $opt_c < $TIMEOUT) { $critical = $opt_c; } else { plugin_error("Specify critical threshold 0.1 - $TIMEOUT"); } # -w means warning threshold if ($opt_w =~ /^\d+\.*\d*/ && $opt_w < $critical) { $warning = $opt_w; } else { plugin_error("Specify warning threshold 0.0 - $critical"); } # Timeout if (defined($TIMEOUT)) { $verbose && print "$PROGNAME: Alarm set at $TIMEOUT\n\n"; alarm($TIMEOUT); } else { $verbose && print "$PROGNAME: Alarm set at $MYTIME\n\n"; alarm($MYTIME); } $stime = [gettimeofday]; $verbose && print "$PROGNAME: Running $cmd -f $pdb -p $host -F\n\n"; open(CMD, "$cmd -f $pdb -p $host -F |") || plugin_error("Can't run openchangeclient"); while() { if ($verbose > 1) { print "$PROGNAME: $_"; } $status = 'OK' if /$SUCCESS/io; last if $status eq 'OK'; } $etime = tv_interval($stime); $status = 'CRITICAL' if ($etime >= $critical || $status eq 'UNKNOWN'); $status = 'WARNING' if ($etime >= $warning && $status ne 'CRITICAL'); $verbose && print "$PROGNAME: status $status\n\n"; #print "Elapsed time: $etime|time=$etime\n"; # update to include measurement unit for Centreon graphs printf "Elapsed time: %s|time=%ss\n",$etime,$etime; exit $ERRORS{"$status"}; # print_usage: Print usage information sub print_usage { print < -P -u -p -M LOCALHOST -D -I -c Note that HOSTNAME is strictly the profile name, and the host connection is really derived from the IPADDRESS. The author wishes to offer thanks to the OpenChange team at: openchange.org EndOfHelp } sub plugin_error { my $msg = $_[0]; print STDERR "$PROGNAME: $msg\n"; print_usage(); exit $ERRORS{'UNKNOWN'}; } openchange-2.0/script/installman.sh000077500000000000000000000011341223057412600174700ustar00rootroot00000000000000#!/bin/sh MANDIR=$1 shift 1 MANPAGES=$* for I in $MANPAGES do SECTION=`echo $I | grep -o '.$'` DIR="$MANDIR/man$SECTION" if [ ! -d "$DIR" ] then mkdir -p "$DIR" fi BASE=`basename $I` echo "Installing manpage \"$BASE\" in $DIR" cp $I $DIR done cat << EOF ====================================================================== The man pages have been installed. You may uninstall them using the command the command "make uninstallman" or make "uninstall" to uninstall binaries, man pages and shell scripts. ====================================================================== EOF exit 0 openchange-2.0/script/installoc.sh000077500000000000000000000005161223057412600173210ustar00rootroot00000000000000#!/bin/sh # install OpenChange miscellaneous files SRCDIR="$1" JSDIR="$2" SETUPDIR="$3" cd $SRCDIR || exit 1 echo "Installing OpenChange js libs.." cp libmapi/setup/scripting/libjs/*.js $JSDIR || exit 1 echo "Done.." echo "Installing OpenChange setup templates.." cp libmapi/setup/*.ldif $SETUPDIR || exit 1 echo "All Ok" exit 0 openchange-2.0/script/installsamba4.sh000077500000000000000000000211361223057412600200700ustar00rootroot00000000000000#!/usr/bin/env bash # # VARS # . `dirname $0`/samba4_ver.sh if which gmake 2>/dev/null; then MAKE=gmake else MAKE=make fi # If you have a samba checkout (even not up-to-date), you can make this a lot faster using --reference, e.g. # SAMBA_GIT_REFERENCE="--reference $HOME/samba-master" if test x"$SAMBA_GIT_REPO" = x""; then SAMBA_GIT_REPO=git://git.samba.org/samba.git fi # Set SAMBA_PREFIX to wherever you want to install to. Defaults to /usr/local/samba, as if you did the build manually if test x"$SAMBA_PREFIX" = x""; then SAMBA_PREFIX="/usr/local/samba" fi export CPPFLAGS="-I${SAMBA_PREFIX}/include" # use ccache for faster rebuild, where available if which ccache 2>/dev/null; then export CC="ccache gcc" else export CC="gcc" fi export PKG_CONFIG_PATH=$SAMBA_PREFIX/lib/pkgconfig:$PKG_CONFIG_PATH pythondir=`python -c "from distutils import sysconfig; print sysconfig.get_python_lib(0,0,'/')"` export PYTHONPATH=$SAMBA_PREFIX$pythondir:$PYTHONPATH RUNDIR=$(readlink -f $(dirname $0)) HOST_OS=`$RUNDIR/../config.guess` BUILDTOOLS=$RUNDIR/../samba4/buildtools/ # # Error check # error_check() { error=$1 step=$2 if [ $error -ne 0 ]; then echo "Error in $2 (error code $1)" exit 1 fi } cleanup_lib() { lib="$1" if test -f samba4/$lib/Makefile; then echo "cleaning up $lib directory" pushd samba4/$lib $MAKE distclean popd fi } cleanup_talloc() { cleanup_lib "lib/talloc" } cleanup_tdb() { cleanup_lib "lib/tdb" } cleanup_ldb() { cleanup_lib "lib/ldb" } delete_install() { # cleanup existing existing samba4 installation if test -d $SAMBA_PREFIX; then echo "@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@" echo "A previous samba4 installation has been detected in $SAMBA_PREFIX" echo "It is highly recommended to delete it prior compiling Samba4" echo "@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@" echo "" echo -n "Proceed removing all of $SAMBA_PREFIX? [Yn]: " read answer case "$answer" in Y|y|yes) echo "Step0: Removing previous samba4 installation" if test -w $SAMBA_PREFIX; then rm -rf $SAMBA_PREFIX else sudo rm -rf $SAMBA_PREFIX fi ;; N|n|no) echo "Step0: Keep previous samba4 installation" ;; esac fi cleanup_talloc cleanup_tdb cleanup_ldb } # # Checkout Samba4 # checkout() { GITPATH=`whereis -b git` if test x"$GITPATH" = x"git:"; then echo "git was not found in your path!" echo "Please install git" exit 1 fi echo "Step1: Fetching Samba4 latest GIT revision" git clone $SAMBA_GIT_REPO $SAMBA_GIT_REFERENCE samba4 error_check $? "Step1" echo "Step2: Creating openchange local copy" pushd samba4 git checkout -b openchange origin/master error_check $? "Step2" if test x"$SAMBA4_GIT_REV" != x""; then echo "Step3: Revert to commit $SAMBA4_GIT_REV" git reset --hard $SAMBA4_GIT_REV error_check $? "Step3" fi popd return $? } # # Update Samba4 # update() { GITPATH=`whereis -b git` if test x"$GITPATH" = x"git:"; then echo "git was not found in your path!" echo "Please install git" exit 1 fi echo "Step1: Update Samba4 to latest GIT revision" pushd samba4 git pull error_check $? "Step1" if test x"$SAMBA4_GIT_REV" != x""; then echo "Step3: Revert to commit $SAMBA4_GIT_REV" git reset --hard $SAMBA4_GIT_REV error_check $? "Step3" fi popd return $? } # # Download Samba4 release # download() { WGETPATH=`whereis -b wget` TARPATH=`whereis -b tar` if test x"$WGETPATH" = x"wget:"; then echo "wget was not found in your path!" echo "Please install wget" exit 1 fi if test x"$TARPATH" = x"tar:"; then echo "tar was not found in your path!" echo "Please install tar" exit 1 fi echo "Step0: Checking for previous samba4 directory" if test -d samba4; then echo "@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@" echo "A previous samba4 directory has been detected in current folder." echo "Should we delete the existing samba4 directory?" echo "@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@" echo "" echo -n "Proceed? [Yn]: " read answer case "$answer" in Y|y|yes) echo "Step0: removing previous samba4 directory" sudo rm -rf samba4 ;; N|n|no) echo "Step0: Keep existing directory" return ;; esac fi echo "Step1: Fetching samba-$SAMBA4_RELEASE tarball" if ! test -e samba-$SAMBA4_RELEASE.tar.gz; then rm -rf samba-$SAMBA4_RELEASE.tar.gz wget http://ftp.samba.org/pub/samba/stable/samba-$SAMBA4_RELEASE.tar.gz error_check $? "Step1" fi echo "Step2: Extracting $SAMBA4_RELEASE" tar xzvf samba-$SAMBA4_RELEASE.tar.gz error_check $? "Step2" mv samba-$SAMBA4_RELEASE samba4 return $? } # # Apply patches to samba4 # patch() { case "$HOST_OS" in *freebsd*) echo "[+] Patching heimdal for FreeBSD" pushd samba4/source4/heimdal/lib/roken sed "s/#if defined(HAVE_OPENPTY) || defined(__linux) || defined(__osf__)/#if defined(HAVE_OPENPTY) || defined(__linux) || defined(__osf__) || defined(__FreeBSD__)/g" rkpty.c > rkpty2.c mv rkpty2.c rkpty.c sed -e "54i\\ #if defined(__FreeBSD__)\\ #include \\ #include \\ #include \\ #endif" rkpty.c > rkpty2.c mv rkpty2.c rkpty.c popd ;; esac return $? } # # Compile and Install samba4 packages: # talloc, tdb, tevent, ldb # packages() { delete_install for lib in lib/talloc lib/tdb lib/tevent lib/ldb; do echo "Building and installing $lib library" export PKG_CONFIG_PATH=$PKG_CONFIG_PATH:$SAMBA_PREFIX/lib/pkgconfig pushd samba4/$lib error_check $? "$lib setup" extra="" if [ "$lib" == "lib/ldb" ]; then extra="--builtin-libraries=ccan" fi echo ./configure -C --prefix=$SAMBA_PREFIX --enable-developer --bundled-libraries=NONE $extra ./configure -C --prefix=$SAMBA_PREFIX --enable-developer --bundled-libraries=NONE $extra error_check $? "$lib configure" $MAKE -j error_check $? "$lib make" if test -w `dirname $SAMBA_PREFIX`; then $MAKE install error_check $? "$lib make install" else sudo $MAKE install error_check $? "$lib sudo make install" fi $MAKE distclean error_check $? "$lib make distclean" popd export PKG_CONFIG_PATH=$PKG_CONFIG_PATH:$SAMBA_PREFIX/lib/pkgconfig done } # # Compile Samba4 # compile() { echo "Step1: Preparing Samba4 system" pushd samba4/source4 error_check $? "samba4 setup" cd $RUNDIR/../samba4 export PKG_CONFIG_PATH=$PKG_CONFIG_PATH:$SAMBA_PREFIX/lib/pkgconfig ./configure.developer -C --prefix=$SAMBA_PREFIX --builtin-libraries=ccan,replace error_check $? "samba4 configure" echo "Step2: Compile Samba4 (Source)" $MAKE -j error_check $? "samba4 make" popd } # # Post install operations # post_install() { case "$HOST_OS" in *freebsd*) pushd samba4/pidl error_check $? "post_install setup" if test -w `dirname $SAMBA_PREFIX`; then $MAKE install error_check $? "post make install" else sudo $MAKE install error_check $? "post sudo make install" fi popd echo "[+] Add comparison_fn_t support to ndr.h header file" pushd $SAMBA_PREFIX/include if test -w $SAMBA_PREFIX/include; then sed -e "34i\\ #if defined(__FreeBSD__)\\ # ifndef HAVE_COMPARISON_FN_T\\ typedef int (*comparison_fn_t)(const void *, const void *);\\ # endif\\ #endif" ndr.h > /tmp/ndr.h mv /tmp/ndr.h ndr.h else sudo sed -e "34i\\ #if defined(__FreeBSD__)\\ # ifndef HAVE_COMPARISON_FN_T\\ typedef int (*comparison_fn_t)(const void *, const void *);\\ # endif\\ #endif" ndr.h > /tmp/ndr.h sudo mv /tmp/ndr.h ndr.h fi popd ;; esac } # # Install Samba4 # install() { echo "Step1: Installing Samba" echo "===> we are in $PWD" pushd samba4/source4 error_check $? "samba4 setup" cd $RUNDIR/../samba4 if test -w `dirname $SAMBA_PREFIX`; then $MAKE install error_check $? "samba4 install" else sudo $MAKE install error_check $? "samba4 install" fi popd } # # main program # case $1 in checkout) checkout ;; download) download ;; patch) patch ;; packages) packages ;; compile) compile ;; install) install ;; post_install) post_install ;; git-all) checkout patch packages compile install post_install ;; git-update) update packages compile install post_install ;; all) download patch packages compile install post_install ;; *) echo $"Usage: $0 {checkout|patch|packages|compile|install|post_install|git-all}" echo $"Usage: $0 {download|patch|packages|compile|install|post_install|all}" ;; esac exit 0 openchange-2.0/script/makepropslist.py000077500000000000000000001725471223057412600202620ustar00rootroot00000000000000#!/usr/bin/env python # -*- coding: utf-8 -*- import argparse import string import subprocess import sys import tempfile knownpropsets = { "PSETID_PostRss" : "{00062041-0000-0000-C000-000000000046}", "PSETID_Sharing" : "{00062040-0000-0000-C000-000000000046}", "PS_PUBLIC_STRINGS" : "{00020329-0000-0000-C000-000000000046}", "PSETID_Common" : "{00062008-0000-0000-C000-000000000046}", "PSETID_Appointment" : "{00062002-0000-0000-C000-000000000046}", "PSETID_Address" : "{00062004-0000-0000-C000-000000000046}", "PSETID_Meeting" : "{6ED8DA90-450B-101B-98DA-00AA003F1305}", "PSETID_Log" : "{0006200A-0000-0000-C000-000000000046}", "PSETID_CalendarAssistant" : "{11000E07-B51B-40D6-AF21-CAA85EDAB1D0}", "PSETID_Note" : "{0006200E-0000-0000-C000-000000000046}", "PSETID_Task": "{00062003-0000-0000-C000-000000000046}", "PS_INTERNET_HEADERS" : "{00020386-0000-0000-C000-000000000046}", "PSETID_UnifiedMessaging" : "{4442858E-A9E3-4E80-B900-317A210CC15B}", "PS_MAPI" : "{00020328-0000-0000-C000-000000000046}", "PSETID_Attachment" : "{96357f7f-59e1-47d0-99a7-46515c183b54}", "PSETID_AirSync" : "{71035549-0739-4DCB-9163-00F0580DBBDF}", "PSETID_Messaging" : "{41F28F13-83F4-4114-A584-EEDB5A6B0BFF}" } knowndatatypes = { "PtypInteger16" : "0x0002", "PtypInteger32" : "0x0003", "PtypFloating64" : "0x0005", "PtypBoolean" : "0x000B", "PtypEmbeddedTable" : "0x000D", "PtypObject" : "0x000D", "PtypString8" : "0x001E", "PtypString" : "0x001F", "PtypInteger64" : "0x0014", "PtypBinary" : "0x0102", "PtypTime" : "0x0040", "PtypGuid" : "0x0048", "PtypServerId" : "0x00FB", "PtypRestriction" : "0x00FD", "PtypRuleAction" : "0x00FE", "PtypMultipleInteger32" : "0x1003", "PtypMultipleString8" : "0x101E", "PtypMultipleString" : "0x101F", "PtypMultipleTime" : "0x1040", "PtypMultipleBinary" : "0x1102", } datatypemap = { "PtypInteger16" : "PT_SHORT", "PtypInteger32" : "PT_LONG", "PtypFloating64" : "PT_DOUBLE", "PtypBoolean" : "PT_BOOLEAN", "PtypEmbeddedTable" : "PT_OBJECT", "PtypObject" : "PT_OBJECT", "PtypString8" : "PT_STRING8", "PtypString" : "PT_UNICODE", "PtypInteger64" : "PT_I8", "PtypBinary" : "PT_BINARY", "PtypTime" : "PT_SYSTIME", "PtypGuid" : "PT_CLSID", "PtypServerId" : "PT_SVREID", "PtypRestriction" : "PT_SRESTRICT", "PtypRuleAction" : "PT_ACTIONS", "PtypMultipleInteger32" : "PT_MV_LONG", "PtypMultipleString8" : "PT_MV_STRING8", "PtypMultipleString" : "PT_MV_UNICODE", "PtypMultipleTime" : "PT_MV_SYSTIME", "PtypMultipleBinary" : "PT_MV_BINARY" } knownrefs = [ "[MS-ASAIRS]", "[MS-ASCAL]", "[MS-ASCMD]", "[MS-ASCNTC]", "[MS-ASCON]", "[MS-ASDOC]", "[MS-ASDTYPE]", "[MS-ASEMAIL]", "[MS-ASHTTP]", "[MS-ASMS]", "[MS-ASNOTE]", "[MS-ASPROV]", "[MS-ASRM]", "[MS-ASTASK]", "[MS-ASWBXML]", "[MS-CAB]", "[MS-MCI]", "[MS-OXABREF]", "[MS-OXBBODY]", "[MS-OXCDATA]", "[MS-OXCETF]", "[MS-OXCFOLD]", "[MS-OXCFXICS]", "[MS-OXCHGTR]", "[MS-OXCICAL]", "[MS-OXCMAIL]", "[MS-OXCMSG]", "[MS-OXCNOTIF]", "[MS-OXCPERM]", "[MS-OXCPRPT]", "[MS-OXCROPS]", "[MS-OXCRPC]", "[MS-OXCSPAM]", "[MS-OXCSTOR]", "[MS-OXCSYNC]", "[MS-OXCTABL]", "[MS-OXDISCO]", "[MS-OXDOCO]", "[MS-OXDSCLI]", "[MS-OXGLOS]", "[MS-OXIMAP4]", "[MS-OXLDAP]", "[MS-OXMSG]", "[MS-OXMVMBX]", "[MS-OXOABK]", "[MS-OXOABKT]", "[MS-OXOAB]", "[MS-OXOCAL]", "[MS-OXOCFG]", "[MS-OXOCNTC]", "[MS-OXODLGT]", "[MS-OXODOC]", "[MS-OXOFLAG]", "[MS-OXOJRNL]", "[MS-OXOMSG]", "[MS-OXONOTE]", "[MS-OXOPFFB]", "[MS-OXOPOST]", "[MS-OXORMDR]", "[MS-OXORMMS]", "[MS-OXORSS]", "[MS-OXORULE]", "[MS-OXOSFLD]", "[MS-OXOSMIME]", "[MS-OXOSMMS]", "[MS-OXOSRCH]", "[MS-OXOTASK]", "[MS-OXOUM]", "[MS-OXPFOAB]", "[MS-OXPHISH]", "[MS-OXPOP3]", "[MS-OXPROPS]", "[MS-OXPROTO]", "[MS-OXPSVAL]", "[MS-OXREF]", "[MS-OXRTFCP]", "[MS-OXRTFEX]", "[MS-OXSHARE]", "[MS-OXSHRMSG]", "[MS-OXSMTP]", "[MS-OXTNEF]", "[MS-OXVCARD]", "[MS-OXWAVLS]", "[MS-OXWCONFIG]", "[MS-OXWMT]", "[MS-OXWOAB]", "[MS-OXWOOF]", "[MS-OXWSADISC]", "[MS-OXWSATT]", "[MS-OXWSAUTID]", "[MS-OXWSBTRF]", "[MS-OXWSCDATA]", "[MS-OXWSCONT]", "[MS-OXWSCONV]", "[MS-OXWSCORE]", "[MS-OXWSCVTID]", "[MS-OXWSDLGM]", "[MS-OXWSDLIST]", "[MS-OXWSFOLD]", "[MS-OXWSGTRM]", "[MS-OXWSGTZ]", "[MS-OXWSLVID]", "[MS-OXWSMSG]", "[MS-OXWSMSHR]", "[MS-OXWSMTGS]", "[MS-OXWSMTRK]", "[MS-OXWSNTIF]", "[MS-OXWSPOST]", "[MS-OXWSPSNTIF]", "[MS-OXWSRSLNM]", "[MS-OXWSRULES]", "[MS-OXWSSRCH]", "[MS-OXWSSYNC]", "[MS-OXWSTASK]", "[MS-OXWSUSRCFG]", "[MS-OXWSXPROP]", "[MS-OXWUMS]", "[MS-PATCH]", "[MS-XJRNL]", "[MS-XLOGIN]", "[MS-XWDCAL]", "[MS-XWDCNTC]", "[MS-XWDDOC]", "[MS-XWDEXT]", "[MS-XWDFOLD]", "[MS-XWDMAIL]", "[MS-XWDNOTIF]", "[MS-XWDREPL]", "[MS-XWDSEARCH]", "[MS-XWDSTRUCTDOC]", "[MS-XWDVSEC]", "[MS-NSPI]" ] knownareas = [ "AB Container", "Access Control Properties", "Access Control Properties Property set", "Address book", "Address Book", "Address Properties", "Address Properties Property set", "Appointment Property set", "Appointment", "Archive", "BestBody", "Calendar", "Calendar Document", "Calendar Document Property set", "Calendar Property set", "Common", "Common Property set", "Conferencing", "Configuration", "Conflict Note", "Contact Properties", "Container Properties", "Container Properties Property set", "Conversation Actions", "Conversations", "Email", "E-mail", "Email Property set", "Exchange", "Exchange Administrative", "ExchangeAdministrative", "ExchangeAdministrative Property set", "ExchangeFolder", "ExchangeFolder Property set", "ExchangeMessageReadOnly", "ExchangeMessageStore", "ExchangeNonTransmittableReserved", "Exchange Profile Configuration", "Exchange Property set", "Flagging", "Folder Properties", "Free/Busy Properties", "General Message Properties", "General Message Properties Property set", "General Report Properties", "History Properties", "IC", "ICS", "ID Properties", "ID Properties Property set", "Journal", "Mail", "MapiAddressBook", "MapiAttachment", "MapiCommon", "MapiContainer", "MAPI Display Tables", "MapiEnvelope", "MapiEnvelope Property set", "MapiMailUser", "MapiMessage", "MapiMessageStore", "MapiNonTransmittable", "MapiNonTransmittable Property set", "MapiRecipient", "MapiStatus", "Meeting Response", "Meetings", "Message Attachment Properties", "Message Attachment Properties Property set", "MessageClassDefinedNonTransmittable", "Message Class Defined Transmittable", "MessageClassDefinedTransmittable", "Message Properties", "Message Properties Property set", "Message Store Properties", "Message Time Properties", "Message Time Properties Property set", "MIME properties", "MIME Properties", "MIME Properties Property set", "Miscellaneous Properties", "Miscellaneous Properties Property set", "Offline Address Book Properties", "Outlook Application", "ProviderDefinedNonTransmittable", "PST Internal", "Reminders", "RenMessageFolder", "RSS", "Rules", "Run-time configuration", "Search", "Secure Messaging", "Secure Messaging Properties", "Server", "Server-side Rules Properties", "Server-Side Rules Properties", "Sharing", "SMS", "Spam", "Sticky Notes", "Structured Documents", "Structured Documents Property set", "Sync", "Table Properties", "Tasks", "Transport Envelope", "TransportEnvelope", "TransportRecipient", "UM", "Unified Messaging" ] properties = [] def make_properties_list(propsfilename): next_num = 1 propname = "" propertyinfo = {} propsfile = file(propsfilename) for line in propsfile: if line.startswith("2 Structures"): break for line in propsfile: if line.startswith("2."): section_num = line.split()[0] sub_section_num = section_num.split(".")[1] if int(sub_section_num) != next_num: print "expected", next_num, "got", sub_section_num next_num += 1 propname = line.split()[1] if propertyinfo.has_key("CanonicalName"): properties.append(propertyinfo.copy()) propertyinfo = {} if line.strip().startswith("Canonical name:"): canonicalname = line.strip().split(":")[1].strip() if ((propname != "") and (propname != canonicalname)): print "expected", propname, "got", canonicalname propertyinfo["CanonicalName"] = canonicalname if line.strip().startswith("Property name:"): propertyname = line.split(":", 1) propertyinfo["PropertyName"] = propertyname[1].strip() if line.strip().startswith("Description:"): description = line.strip().split(":")[1].strip() while (1): nextline = propsfile.next().strip() if (nextline.isspace() or (len(nextline) == 0)): break description += (" " + nextline) propertyinfo["Description"] = description if line.strip().startswith("Alternate names:"): altname = line.strip().partition(":")[2] while (1): nextline = propsfile.next().strip() if (nextline.isspace() or (len(nextline) == 0)): break altname += (", " + nextline) propertyinfo["AlternateNames"] = altname if line.strip().startswith("Data type:"): datatype = line.strip().split(":")[1].strip() datatypename, datatypeval = datatype.split(",") propertyinfo["DataTypeName"] = datatypename.strip() propertyinfo["DataTypeValue"] = datatypeval.strip() if line.strip().startswith("Property set:"): propset = line.strip().split(":")[1].strip() if propset.find(" ") != -1: propsetname, propsetval = propset.split(" ") propertyinfo["PropertySet"] = propsetname.strip() propertyinfo["PropertySetValue"] = propsetval.strip() if line.strip().startswith("Property ID:"): propid = line.strip().split(":")[1].strip() if propid.startswith("0x"): propertyinfo["PropertyId"] = int(propid, 16) else: print "In section 2.%(section)i (%(propname)s):" % { 'section': (next_num -1), 'propname': propname } print "\t", propid, "doesn't appear to have correct (hex) format" if line.strip().startswith("Property long ID (LID):"): proplid = line.strip().split(":")[1].strip() if proplid.startswith("0x"): propertyinfo["PropertyLid"] = int(proplid, 16) else: print "In section 2.%(section)i (%(propname)s):" % { 'section': (next_num -1), 'propname': propname } print "\t", proplid, "doesn't appear to have correct (hex) format" if line.strip().startswith("Area:"): areaname = line.strip().split(":")[1].strip() if (knownareas.count(areaname) == 1): propertyinfo["Area"] = areaname else: print "In section 2.%(section)i (%(propname)s):" % { 'section': (next_num -1), 'propname': propname } print "\t", areaname, "isn't an expected area name (typo?)" if line.strip().startswith("References:") or line.strip().startswith("Reference:"): references = line.strip().split(":")[1].strip() while (1): nextline = propsfile.next().strip() if (nextline.isspace() or (len(nextline) == 0)): break references += (nextline) propertyinfo["References"] = references if line.strip().startswith("Defining Reference:") or line.strip().startswith("Defining reference:") or line.strip().startswith("Defining references"): reference = line.strip().split(":")[1].strip() propertyinfo["DefiningReference"] = reference propertyinfo["OXPROPS_Sect"] = "2.%i" % (next_num -1) #The whole file should now be parsed properties.append(propertyinfo) # sanity check print "Last section parsed was section 2.%(section)i" % { 'section': (next_num-1) } # Debugging dump of everything def debug_dump(): for entry in properties: print entry extra_private_tags_struct = """\t{ PidTagFolderChildCount, PT_LONG, \"PidTagFolderChildCount\" }, """ temporary_private_tags = """ #define openchange_private_ROOT_FOLDER_FID PROP_TAG(PT_I8 , 0xd001) /* 0xd0010014 */ #define openchange_private_ROOT_FOLDER_FID_ERROR PROP_TAG(PT_ERROR , 0xd001) /* 0xd001000a */ #define openchange_private_DEFERRED_ACTIONS_FID PROP_TAG(PT_I8 , 0xd002) /* 0xd0020014 */ #define openchange_private_DEFERRED_ACTIONS_FID_ERROR PROP_TAG(PT_ERROR , 0xd002) /* 0xd002000a */ #define openchange_private_SPOOLER_QUEUE_FID PROP_TAG(PT_I8 , 0xd003) /* 0xd0030014 */ #define openchange_private_SPOOLER_QUEUE_FID_ERROR PROP_TAG(PT_ERROR , 0xd003) /* 0xd003000a */ #define openchange_private_IPM_SUBTREE_FID PROP_TAG(PT_I8 , 0xd004) /* 0xd0040014 */ #define openchange_private_IPM_SUBTREE_FID_ERROR PROP_TAG(PT_ERROR , 0xd004) /* 0xd004000a */ #define openchange_private_INBOX_FID PROP_TAG(PT_I8 , 0xd005) /* 0xd0050014 */ #define openchange_private_INBOX_FID_ERROR PROP_TAG(PT_ERROR , 0xd005) /* 0xd005000a */ #define openchange_private_OUTBOX_FID PROP_TAG(PT_I8 , 0xd006) /* 0xd0060014 */ #define openchange_private_OUTBOX_FID_ERROR PROP_TAG(PT_ERROR , 0xd006) /* 0xd006000a */ #define openchange_private_SENT_ITEMS_FID PROP_TAG(PT_I8 , 0xd007) /* 0xd0070014 */ #define openchange_private_SENT_ITEMS_FID_ERROR PROP_TAG(PT_ERROR , 0xd007) /* 0xd007000a */ #define openchange_private_DELETED_ITEMS_FID PROP_TAG(PT_I8 , 0xd008) /* 0xd0080014 */ #define openchange_private_DELETED_ITEMS_FID_ERROR PROP_TAG(PT_ERROR , 0xd008) /* 0xd008000a */ #define openchange_private_COMMON_VIEWS_FID PROP_TAG(PT_I8 , 0xd009) /* 0xd0090014 */ #define openchange_private_COMMON_VIEWS_FID_ERROR PROP_TAG(PT_ERROR , 0xd009) /* 0xd009000a */ #define openchange_private_SCHEDULE_FID PROP_TAG(PT_I8 , 0xd00a) /* 0xd00a0014 */ #define openchange_private_SCHEDULE_FID_ERROR PROP_TAG(PT_ERROR , 0xd00a) /* 0xd00a000a */ #define openchange_private_SEARCH_FID PROP_TAG(PT_I8 , 0xd00b) /* 0xd00b0014 */ #define openchange_private_SEARCH_FID_ERROR PROP_TAG(PT_ERROR , 0xd00b) /* 0xd00b000a */ #define openchange_private_VIEWS_FID PROP_TAG(PT_I8 , 0xd00c) /* 0xd00c0014 */ #define openchange_private_VIEWS_FID_ERROR PROP_TAG(PT_ERROR , 0xd00c) /* 0xd00c000a */ #define openchange_private_SHORTCUTS_FID PROP_TAG(PT_I8 , 0xd00d) /* 0xd00d0014 */ #define openchange_private_SHORTCUTS_FID_ERROR PROP_TAG(PT_ERROR , 0xd00d) /* 0xd00d000a */ #define openchange_private_MailboxGUID PROP_TAG(PT_CLSID , 0xd00e) /* 0xd00e0048 */ #define openchange_private_MailboxGUID_ERROR PROP_TAG(PT_ERROR , 0xd00e) /* 0xd00e000a */ #define openchange_private_ReplicaID PROP_TAG(PT_SHORT , 0xd00f) /* 0xd00f0002 */ #define openchange_private_ReplicaID_ERROR PROP_TAG(PT_ERROR , 0xd00f) /* 0xd00f000a */ #define openchange_private_ReplicaGUID PROP_TAG(PT_CLSID , 0xd010) /* 0xd0100048 */ #define openchange_private_ReplicaGUID_ERROR PROP_TAG(PT_ERROR , 0xd010) /* 0xd010000a */ #define openchange_private_CONTACT_FID PROP_TAG(PT_I8 , 0xd011) /* 0xd0110014 */ #define openchange_private_CONTACT_FID_ERROR PROP_TAG(PT_ERROR , 0xd011) /* 0xd011000a */ #define openchange_private_CALENDAR_FID PROP_TAG(PT_I8 , 0xd012) /* 0xd0120014 */ #define openchange_private_CALENDAR_FID_ERROR PROP_TAG(PT_ERROR , 0xd012) /* 0xd012000a */ #define openchange_private_JOURNAL_FID PROP_TAG(PT_I8 , 0xd013) /* 0xd0130014 */ #define openchange_private_JOURNAL_FID_ERROR PROP_TAG(PT_ERROR , 0xd013) /* 0xd013000a */ #define openchange_private_NOTE_FID PROP_TAG(PT_I8 , 0xd014) /* 0xd0140014 */ #define openchange_private_NOTE_FID_ERROR PROP_TAG(PT_ERROR , 0xd014) /* 0xd014000a */ #define openchange_private_TASK_FID PROP_TAG(PT_I8 , 0xd015) /* 0xd0150014 */ #define openchange_private_TASK_FID_ERROR PROP_TAG(PT_ERROR , 0xd015) /* 0xd015000a */ #define openchange_private_DRAFTS_FID PROP_TAG(PT_I8 , 0xd016) /* 0xd0160014 */ #define openchange_private_DRAFTS_FID_ERROR PROP_TAG(PT_ERROR , 0xd016) /* 0xd016000a */ #define openchange_private_PF_ROOT PROP_TAG(PT_I8 , 0xd017) /* 0xd0170014 */ #define openchange_private_PF_ROOT_ERROR PROP_TAG(PT_ERROR , 0xd017) /* 0xd017000a */ #define openchange_private_PF_IPM_SUBTREE PROP_TAG(PT_I8 , 0xd018) /* 0xd0180014 */ #define openchange_private_PF_IPM_SUBTREE_ERROR PROP_TAG(PT_ERROR , 0xd018) /* 0xd018000a */ #define openchange_private_PF_NONIPM_SUBTREE PROP_TAG(PT_I8 , 0xd019) /* 0xd0190014 */ #define openchange_private_PF_NONIPM_SUBTREE_ERROR PROP_TAG(PT_ERROR , 0xd019) /* 0xd019000a */ #define openchange_private_PF_EFORMS PROP_TAG(PT_I8 , 0xd01a) /* 0xd01a0014 */ #define openchange_private_PF_EFORMS_ERROR PROP_TAG(PT_ERROR , 0xd01a) /* 0xd01a000a */ #define openchange_private_PF_FREEBUSY PROP_TAG(PT_I8 , 0xd01b) /* 0xd01b0014 */ #define openchange_private_PF_FREEBUSY_ERROR PROP_TAG(PT_ERROR , 0xd01b) /* 0xd01b000a */ #define openchange_private_PF_OAB PROP_TAG(PT_I8 , 0xd01c) /* 0xd01c0014 */ #define openchange_private_PF_OAB_ERROR PROP_TAG(PT_ERROR , 0xd01c) /* 0xd01c000a */ #define openchange_private_PF_LOCAL_EFORMS PROP_TAG(PT_I8 , 0xd01d) /* 0xd01d0014 */ #define openchange_private_PF_LOCAL_EFORMS_ERROR PROP_TAG(PT_ERROR , 0xd01d) /* 0xd01d000a */ #define openchange_private_PF_LOCAL_FREEBUSY PROP_TAG(PT_I8 , 0xd01e) /* 0xd01e0014 */ #define openchange_private_PF_LOCAL_FREEBUSY_ERROR PROP_TAG(PT_ERROR , 0xd01e) /* 0xd01e000a */ #define openchange_private_PF_LOCAL_OAB PROP_TAG(PT_I8 , 0xd01f) /* 0xd01f0014 */ #define openchange_private_PF_LOCAL_OAB_ERROR PROP_TAG(PT_ERROR , 0xd01f) /* 0xd01f000a */ """ temporary_private_tags_struct = """\t{ openchange_private_ROOT_FOLDER_FID, PT_I8, "openchange_private_ROOT_FOLDER_FID" }, { openchange_private_DEFERRED_ACTIONS_FID, PT_I8, "openchange_private_DEFERRED_ACTIONS_FID" }, { openchange_private_SPOOLER_QUEUE_FID, PT_I8, "openchange_private_SPOOLER_QUEUE_FID" }, { openchange_private_IPM_SUBTREE_FID, PT_I8, "openchange_private_IPM_SUBTREE_FID" }, { openchange_private_INBOX_FID, PT_I8, "openchange_private_INBOX_FID" }, { openchange_private_OUTBOX_FID, PT_I8, "openchange_private_OUTBOX_FID" }, { openchange_private_SENT_ITEMS_FID, PT_I8, "openchange_private_SENT_ITEMS_FID" }, { openchange_private_DELETED_ITEMS_FID, PT_I8, "openchange_private_DELETED_ITEMS_FID" }, { openchange_private_COMMON_VIEWS_FID, PT_I8, "openchange_private_COMMON_VIEWS_FID" }, { openchange_private_SCHEDULE_FID, PT_I8, "openchange_private_SCHEDULE_FID" }, { openchange_private_SEARCH_FID, PT_I8, "openchange_private_SEARCH_FID" }, { openchange_private_VIEWS_FID, PT_I8, "openchange_private_VIEWS_FID" }, { openchange_private_SHORTCUTS_FID, PT_I8, "openchange_private_SHORTCUTS_FID" }, { openchange_private_MailboxGUID, PT_CLSID, "openchange_private_MailboxGUID" }, { openchange_private_ReplicaID, PT_SHORT, "openchange_private_ReplicaID" }, { openchange_private_ReplicaGUID, PT_CLSID, "openchange_private_ReplicaGUID" }, { openchange_private_CONTACT_FID, PT_I8, "openchange_private_CONTACT_FID" }, { openchange_private_CALENDAR_FID, PT_I8, "openchange_private_CALENDAR_FID" }, { openchange_private_JOURNAL_FID, PT_I8, "openchange_private_JOURNAL_FID" }, { openchange_private_NOTE_FID, PT_I8, "openchange_private_NOTE_FID" }, { openchange_private_TASK_FID, PT_I8, "openchange_private_TASK_FID" }, { openchange_private_DRAFTS_FID, PT_I8, "openchange_private_DRAFTS_FID" }, { openchange_private_PF_ROOT, PT_I8, "openchange_private_PF_ROOT" }, { openchange_private_PF_IPM_SUBTREE, PT_I8, "openchange_private_PF_IPM_SUBTREE" }, { openchange_private_PF_NONIPM_SUBTREE, PT_I8, "openchange_private_PF_NONIPM_SUBTREE" }, { openchange_private_PF_EFORMS, PT_I8, "openchange_private_PF_EFORMS" }, { openchange_private_PF_FREEBUSY, PT_I8, "openchange_private_PF_FREEBUSY" }, { openchange_private_PF_OAB, PT_I8, "openchange_private_PF_OAB" }, { openchange_private_PF_LOCAL_EFORMS, PT_I8, "openchange_private_PF_LOCAL_EFORMS" }, { openchange_private_PF_LOCAL_FREEBUSY, PT_I8, "openchange_private_PF_LOCAL_FREEBUSY" }, { openchange_private_PF_LOCAL_OAB, PT_I8, "openchange_private_PF_LOCAL_OAB" }, """ def make_mapi_properties_file(): proplines = [] altnamelines = [] previous_propid_list = [] for entry in properties: if (entry.has_key("CanonicalName") == False): print "Section", entry["OXPROPS_Sect"], "has no canonical name entry" continue if (entry.has_key("DataTypeName") == False): print "Section", entry["OXPROPS_Sect"], "has no data type entry" continue if entry.has_key("PropertyId"): propline = "#define " propline += string.ljust(entry["CanonicalName"], 68) propline += " PROP_TAG(" propline += string.ljust(datatypemap[entry["DataTypeName"]], 13) + ", " propline += "0x" + format(entry["PropertyId"], "04X") propline += ") " propline += "/* 0x" + format(entry["PropertyId"], "04X") + knowndatatypes[entry["DataTypeName"]][2:] + " */" propline += "\n" proplines.append(propline) propline = "#define " propline += string.ljust(entry["CanonicalName"] + "_Error", 68) propline += " PROP_TAG(" propline += string.ljust("PT_ERROR", 13) + ", " propline += "0x" + format(entry["PropertyId"], "04X") propline += ") " propline += "/* 0x" + format(entry["PropertyId"], "04X") + "000A" + " */" propline += "\n" proplines.append(propline) if entry.has_key("AlternateNames"): for altname in entry["AlternateNames"].split(","): altname = altname.strip() if altname.count(" ") > 0: print "skipping non-conforming alternative name:", altname elif altname.startswith("PR_"): if altname.endswith("_A"): continue if altname.endswith("_W"): continue if knowndatatypes[entry["DataTypeName"]][2:] == "001F": altline = "#define " + string.ljust(altname + "_UNICODE", 68) altline += " PROP_TAG(PT_UNICODE , 0x" + format(entry["PropertyId"], "04X") + ")" altline += " /* 0x" + format(entry["PropertyId"], "04X") + "001F */" + "\n" altnamelines.append(altline) altline = "#define " + string.ljust(altname, 68) altline += " PROP_TAG(PT_STRING8 , 0x" + format(entry["PropertyId"], "04X") + ")" altline += " /* 0x" + format(entry["PropertyId"], "04X") + "001E */" + "\n" altnamelines.append(altline) elif knowndatatypes[entry["DataTypeName"]][2:] == "101F": altline = "#define " + string.ljust(altname + "_UNICODE", 68) altline += " PROP_TAG(PT_MV_UNICODE, 0x" + format(entry["PropertyId"], "04X") + ")" altline += " /* 0x" + format(entry["PropertyId"], "04X") + "101F */" + "\n" altnamelines.append(altline) altline = "#define " + string.ljust(altname, 68) altline += " PROP_TAG(PT_MV_STRING8, 0x" + format(entry["PropertyId"], "04X") + ")" altline += " /* 0x" + format(entry["PropertyId"], "04X") + "101E */" + "\n" altnamelines.append (altline) else: altnamelines.append("#define " + string.ljust(altname, 68) + " " + entry["CanonicalName"] + "\n") altline = "#define " + string.ljust(altname + "_ERROR", 68) altline += " PROP_TAG(PT_ERROR , 0x" + format(entry["PropertyId"], "04X") + ")" altline += " /* 0x" + format(entry["PropertyId"], "04X") + "000A */" + "\n" altnamelines.append(altline) # hack until we properly handle named properties proplines.append(temporary_private_tags) # supplemental properties / alternative names altnamelines.append("#define PidTagFolderChildCount PROP_TAG(PT_LONG , 0x6638) /* 0x66380003 */\n") altnamelines.append("#define PR_DEFAULT_PROFILE 0x00010102\n") altnamelines.append("#define PR_PROFILE_HOME_SERVER_ADDRS 0x6613101e\n") altnamelines.append("#define PR_FID PidTagFolderId\n") altnamelines.append("#define PR_MID PidTagMid\n") altnamelines.append("#define PR_INSTANCE_NUM PidTagInstanceNum\n") altnamelines.append("#define PR_FOLDER_CHILD_COUNT 0x66380003\n") altnamelines.append("#define PR_INST_ID 0x674d0014\n") altnamelines.append("#define PR_RULE_MSG_PROVIDER 0x65eb001e\n") altnamelines.append("#define PR_RULE_MSG_NAME 0x65ec001e\n") altnamelines.append("#define PR_TRANSMITTABLE_DISPLAY_NAME_UNICODE PidTagTransmittableDisplayName\n") altnamelines.append("#define PR_TRANSMITTABLE_DISPLAY_NAME 0x3a20001e\n") altnamelines.append("#define PR_ADDRBOOK_MID PidTagAddressBookMessageId\n") altnamelines.append("#define PR_FREEBUSY_LAST_MODIFIED PidTagFreeBusyRangeTimestamp\n") altnamelines.append("#define PR_FREEBUSY_START_RANGE PidTagFreeBusyPublishStart\n") altnamelines.append("#define PR_FREEBUSY_END_RANGE PidTagFreeBusyPublishEnd\n") altnamelines.append("#define PR_FREEBUSY_ALL_MONTHS PidTagScheduleInfoMonthsMerged\n") altnamelines.append("#define PR_FREEBUSY_ALL_EVENTS PidTagScheduleInfoFreeBusyMerged\n") altnamelines.append("#define PR_FREEBUSY_TENTATIVE_MONTHS PidTagScheduleInfoMonthsTentative\n") altnamelines.append("#define PR_FREEBUSY_TENTATIVE_EVENTS PidTagScheduleInfoFreeBusyTentative\n") altnamelines.append("#define PR_FREEBUSY_BUSY_MONTHS PidTagScheduleInfoMonthsBusy\n") altnamelines.append("#define PR_FREEBUSY_BUSY_EVENTS PidTagScheduleInfoFreeBusyBusy\n") altnamelines.append("#define PR_FREEBUSY_OOF_MONTHS PidTagScheduleInfoMonthsAway\n") altnamelines.append("#define PR_FREEBUSY_OOF_EVENTS PidTagScheduleInfoFreeBusyAway\n") altnamelines.append("#define PR_REMINDERS_ONLINE_ENTRYID 0x36d50102\n") altnamelines.append("#define PR_IPM_PUBLIC_FOLDERS_ENTRYID PidTagIpmPublicFoldersEntryId\n") altnamelines.append("#define PR_PARENT_FID PidTagParentFolderId\n") altnamelines.append("#define PR_URL_COMP_NAME_SET PidTagUrlCompNameSet\n") altnamelines.append("#define PR_ASSOC_CONTENT_COUNT PidTagAssociatedContentCount\n") altnamelines.append("#define PR_NTSD_MODIFICATION_TIME 0x3FD60040\n") altnamelines.append("#define PR_CREATOR_SID 0x0E580102\n") altnamelines.append("#define PR_LAST_MODIFIER_SID 0x0E590102\n") altnamelines.append("#define PR_EXTENDED_ACL_DATA 0x3FFE0102\n") altnamelines.append("#define PR_FOLDER_XVIEWINFO_E 0x36E00102\n") altnamelines.append("#define PR_FOLDER_VIEWLIST 0x36EB0102\n") altnamelines.append("#define PR_DELETED_COUNT_TOTAL 0x670B0003\n") altnamelines.append("#define PR_EMS_AB_HOME_MTA 0x8007001F\n") altnamelines.append("#define PR_EMS_AB_ASSOC_NT_ACCOUNT 0x80270102\n") altnamelines.append("#define PR_FX_DEL_PROP PidTagFXDelProp\n") altnamelines.append("#define PR_START_RECIP PidTagStartRecip\n") altnamelines.append("#define PR_END_RECIP PidTagEndToRecip\n") altnamelines.append("#define PR_NEW_ATTACH PidTagNewAttach\n") altnamelines.append("#define PR_END_ATTACH PidTagEndAttach\n") altnamelines.append("#define PR_ASSOCIATED PidTagAssociated\n") altnamelines.append("#define PR_INCR_SYNC_CHG PidTagIncrSyncChg\n") altnamelines.append("#define PR_INCR_SYNC_MSG PidTagIncrSyncMessage\n") altnamelines.append("#define PR_INCR_SYNC_DEL PidTagIncrSyncDel\n") altnamelines.append("#define PR_INCR_SYNC_STATE_BEGIN PidTagIncrSyncStateBegin\n") altnamelines.append("#define PR_INCR_SYNC_STATE_END PidTagIncrSyncStateEnd\n") altnamelines.append("#define PR_INCR_SYNC_END PidTagIncrSyncEnd\n") altnamelines.append("#define PR_DELETED_MSG_COUNT 0x66400003\n") altnamelines.append("#define PR_RECIPIENT_ON_NORMAL_MSG_COUNT 0x66af0003\n") altnamelines.append("#define PR_CONVERSATION_KEY PidTagConversationKey\n") # write properties out to a master header file f = open('libmapi/property_tags.h', 'w') f.write("/* Automatically generated by script/makepropslist.py. Do not edit */\n") sortedproplines = sorted(proplines) for propline in sortedproplines: f.write(propline) f.close() f = open('libmapi/property_altnames.h', 'w') f.write("/* Automatically generated by script/makepropslist.py. Do not edit */\n") sortedaltnamelines = sorted(altnamelines) for propline in sortedaltnamelines: f.write(propline) f.close() # write canonical properties out for lookup proplines = [] f = open('libmapi/property_tags.c', 'w') proplines = [] f.write("/* Automatically generated by script/makepropslist.py. Do not edit */\n") f.write("#include \"libmapi/libmapi.h\"\n") f.write("#include \"libmapi/libmapi_private.h\"\n") f.write("#include \"gen_ndr/ndr_exchange.h\"\n") f.write("#include \"libmapi/property_tags.h\"\n\n") f.write("struct mapi_proptags\n") f.write("{\n") f.write("\tuint32_t proptag;\n") f.write("\tuint32_t proptype;\n") f.write("\tconst char *propname;\n") f.write("};\n") f.write("\n") for entry in properties: if (entry.has_key("CanonicalName") == False): print "Section", entry["OXPROPS_Sect"], "has no canonical name entry" continue if (entry.has_key("DataTypeName") == False): print "Section", entry["OXPROPS_Sect"], "has no data type entry" continue if entry.has_key("PropertyId"): propline = "\t{ " propline += string.ljust(entry["CanonicalName"] + ",", 68) propline += string.ljust(datatypemap[entry["DataTypeName"]] + ",", 14) propline += string.ljust("\"" + entry["CanonicalName"] + "\"" , 68) + "},\n" proplines.append(propline) propline = "\t{ " propline += string.ljust(entry["CanonicalName"] + "_Error,", 68) propline += string.ljust("PT_ERROR,", 14) propline += string.ljust("\"" + entry["CanonicalName"] + "_Error" + "\"" , 68) + "},\n" proplines.append(propline) proplines.append(extra_private_tags_struct) # this is just a temporary hack till we properly support named properties proplines.append(temporary_private_tags_struct) sortedproplines = sorted(proplines) f.write("static struct mapi_proptags canonical_property_tags[] = {\n") for propline in sortedproplines: f.write(propline) f.write("\t{ 0, 0, \"NULL\" }\n") f.write("};\n") f.write(""" _PUBLIC_ const char *get_proptag_name(uint32_t proptag) { uint32_t idx; for (idx = 0; canonical_property_tags[idx].proptag; idx++) { if (canonical_property_tags[idx].proptag == proptag) { return canonical_property_tags[idx].propname; } } if (((proptag & 0xFFFF) == PT_STRING8) || ((proptag & 0xFFFF) == PT_MV_STRING8)) { proptag += 1; /* try as _UNICODE variant */ } for (idx = 0; canonical_property_tags[idx].proptag; idx++) { if (canonical_property_tags[idx].proptag == proptag) { return canonical_property_tags[idx].propname; } } return NULL; } _PUBLIC_ uint32_t get_proptag_value(const char *propname) { uint32_t idx; for (idx = 0; canonical_property_tags[idx].proptag; idx++) { if (!strcmp(canonical_property_tags[idx].propname, propname)) { return canonical_property_tags[idx].proptag; } } return 0; } _PUBLIC_ uint16_t get_property_type(uint16_t untypedtag) { uint32_t idx; uint16_t current_type; for (idx = 0; canonical_property_tags[idx].proptag; idx++) { if ((canonical_property_tags[idx].proptag >> 16) == untypedtag) { current_type = canonical_property_tags[idx].proptype; if (current_type != PT_ERROR && current_type != PT_STRING8) { return current_type; } } } DEBUG(5, ("%s: type for property '%x' could not be deduced\\n", __FUNCTION__, untypedtag)); return 0; } """) f.close() # write canonical properties out for IDL input proplines = [] previous_idl_proptags = [] previous_idl_pidtags = [] f = open('properties_enum.h', 'w') f.write("/* Automatically generated by script/makepropslist.py. Do not edit */\n") f.write("typedef [v1_enum, flag(NDR_PAHEX)] enum {\n") for entry in properties: if (entry.has_key("CanonicalName") == False): print "Section", entry["OXPROPS_Sect"], "has no canonical name entry" continue if (entry.has_key("DataTypeName") == False): print "Section", entry["OXPROPS_Sect"], "has no data type entry" continue if entry.has_key("PropertyId"): if entry["PropertyId"] in previous_idl_proptags: # Generate property tag pidtag = format(entry["PropertyId"], "04X") + knowndatatypes[entry["DataTypeName"]][2:] if pidtag in previous_idl_pidtags: print "Skipping output of enum entry for", entry["CanonicalName"], "(duplicate)" continue else: propline = "\t" + string.ljust(entry["CanonicalName"], 68) propline += " = 0x" + format(entry["PropertyId"], "04X") + knowndatatypes[entry["DataTypeName"]][2:] propline += ",\n" proplines.append(propline) continue propline = "\t" + string.ljust(entry["CanonicalName"], 68) propline += " = 0x" + format(entry["PropertyId"], "04X") + knowndatatypes[entry["DataTypeName"]][2:] propline += ",\n" proplines.append(propline) if entry["DataTypeName"] == "PtypString": propline = "\t" + string.ljust(entry["CanonicalName"] + "_string8", 68) propline += " = 0x" + format(entry["PropertyId"], "04X") + "001E" propline += ",\n" proplines.append(propline) propline = "\t" + string.ljust(entry["CanonicalName"] + "_Error", 68) propline += " = 0x" + format(entry["PropertyId"], "04X") + "000A" propline += ",\n" proplines.append(propline) previous_idl_proptags.append(entry["PropertyId"]) previous_idl_pidtags.append(format(entry["PropertyId"], "04X") + knowndatatypes[entry["DataTypeName"]][2:]) sortedproplines = sorted(proplines) for propline in sortedproplines: f.write(propline) # Add additional properties, referenced on MSDN but not in MS-OXCPROPS f.write("\t" + string.ljust("PidTagAssociatedContentCount", 68) + " = 0x36170003,\n") f.write("\t" + string.ljust("PidTagFolderChildCount", 68) + " = 0x66380003,\n") f.write("\t" + string.ljust("PidTagDeletedCountTotal", 68) + " = 0x670B0003,\n") f.write("\t" + string.ljust("PidTagIpmPublicFoldersEntryId", 68) + " = 0x66310102,\n") f.write("\t" + string.ljust("PidTagLocalCommitTimeMax", 68) + " = 0x670a0040,\n") f.write("\t" + string.ljust("PidTagConversationKey", 68) + " = 0x000b0102,\n") f.write("\t" + string.ljust("PidTagContactEmailAddresses", 68) + " = 0x3a56101f,\n") f.write("\t" + string.ljust("PidTagGenerateExchangeViews", 68) + " = 0x36e9000b,\n") f.write("\t" + string.ljust("PidTagLatestDeliveryTime", 68) + " = 0x00190040,\n") f.write("\t" + string.ljust("PidTagMailPermission", 68) + " = 0x3a0e000b,\n") f.write("\t" + string.ljust("PidTagOriginalAuthorName", 68) + " = 0x004d001f,\n") f.write("\tMAPI_PROP_RESERVED = 0xFFFFFFFF\n") f.write("} MAPITAGS;\n") f.close() # write canonical properties out for pyopenchange mapistore proplines = [] previous_idl_proptags = [] previous_idl_pidtags = [] f = open('pyopenchange/pymapi_properties.c', 'w') f.write(""" /* Automatically generated by script/makepropslist.py. Do not edit */ #include #include "pyopenchange/pymapi.h" int pymapi_add_properties(PyObject *m) { """) for entry in properties: if (entry.has_key("CanonicalName") == False): print "Section", entry["OXPROPS_Sect"], "has no canonical name entry" continue if (entry.has_key("DataTypeName") == False): print "Section", entry["OXPROPS_Sect"], "has no data type entry" continue if entry.has_key("PropertyId"): if entry["PropertyId"] in previous_idl_proptags: pidtag = format(entry["PropertyId"], "04X") + knowndatatypes[entry["DataTypeName"]][2:] if pidtag in previous_idl_pidtags: print "Skipping output of Python bindings entry for", entry["CanonicalName"], "(duplicate)" continue else: propline = "\tPyModule_AddObject(m, \"" + entry["CanonicalName"] + "\", " propline += "PyInt_FromLong(0x" + format(entry["PropertyId"], "04X") propline += knowndatatypes[entry["DataTypeName"]][2:] propline += "));\n" proplines.append(propline) continue propline = "\tPyModule_AddObject(m, \"" + entry["CanonicalName"] + "\", " propline += "PyInt_FromLong(0x" + format(entry["PropertyId"], "04X") propline += knowndatatypes[entry["DataTypeName"]][2:] propline += "));\n" proplines.append(propline) propline = "\tPyModule_AddObject(m, \"" + entry["CanonicalName"] + "_Error\", " propline += "PyInt_FromLong(0x" + format(entry["PropertyId"], "04X") + "000A" propline += "));\n" proplines.append(propline) previous_idl_proptags.append(entry["PropertyId"]) previous_idl_pidtags.append(format(entry["PropertyId"], "04X") + knowndatatypes[entry["DataTypeName"]][2:]) sortedproplines = sorted(proplines) for propline in sortedproplines: f.write(propline) f.write(""" return 0; } """) f.close() # write canonical properties out for openchangedb - probably remove this later proplines = [] previous_idl_proptags = [] previous_idl_pidtags = [] f = open('mapiproxy/libmapiproxy/openchangedb_property.c', 'w') f.write(""" /* Automatically generated by script/makepropslist.py. Do not edit */ #include "mapiproxy/dcesrv_mapiproxy.h" #include "libmapiproxy.h" #include "libmapi/libmapi.h" #include "libmapi/libmapi_private.h" struct pidtags { uint32_t proptag; const char *pidtag; }; static struct pidtags pidtags[] = { """) for entry in properties: if (entry.has_key("CanonicalName") == False): print "Section", entry["OXPROPS_Sect"], "has no canonical name entry" continue if (entry.has_key("DataTypeName") == False): print "Section", entry["OXPROPS_Sect"], "has no data type entry" continue if entry.has_key("PropertyId"): if entry["PropertyId"] in previous_idl_proptags: pidtag = format(entry["PropertyId"], "04X") + knowndatatypes[entry["DataTypeName"]][2:] if pidtag in previous_idl_pidtags: print "Skipping output of pidtags entry for", entry["CanonicalName"], "(duplicate)" continue else: propline = "\t{ " + string.ljust(entry["CanonicalName"] + ",", 68) propline += "\"" + entry["CanonicalName"] + "\" },\n" proplines.append(propline) continue propline = "\t{ " + string.ljust(entry["CanonicalName"] + ",", 68) propline += "\"" + entry["CanonicalName"] + "\" },\n" proplines.append(propline) previous_idl_proptags.append(entry["PropertyId"]) previous_idl_pidtags.append(format(entry["PropertyId"], "04X") + knowndatatypes[entry["DataTypeName"]][2:]) sortedproplines = sorted(proplines) for propline in sortedproplines: f.write(propline) f.write("""\t{ 0, NULL } }; _PUBLIC_ const char *openchangedb_property_get_attribute(uint32_t proptag) { uint32_t i; for (i = 0; pidtags[i].pidtag; i++) { if (pidtags[i].proptag == proptag) { return pidtags[i].pidtag; } } DEBUG(0, ("[%s:%d]: Unsupported property tag '0x%.8x'\\n", __FUNCTION__, __LINE__, proptag)); return NULL; } """) previous_canonical_names = {} def check_duplicate_canonical_names(): print "Checking canonical names:" for entry in properties: canonicalname = entry["CanonicalName"] if previous_canonical_names.has_key(canonicalname): print "\tIn section", entry["OXPROPS_Sect"], ", canonical name:", entry["CanonicalName"], "duplicates name in section", previous_canonical_names[canonicalname] previous_canonical_names[canonicalname] = (entry["OXPROPS_Sect"]) def check_duplicate_alternative_names(): print "Checking alternative names:" previous_alternative_names = {} for entry in properties: if entry.has_key("AlternateNames"): for altname in entry["AlternateNames"].split(", "): altname = altname.strip() if altname.count(" ") > 0: print "\tIn section", entry["OXPROPS_Sect"], ", alternative name:", altname, "contains space" if previous_alternative_names.has_key(altname): print "\tIn section", entry["OXPROPS_Sect"], ", alternative name:", altname, "duplicates name in section", previous_alternative_names[altname] if previous_canonical_names.has_key(altname): print "\tIn section", entry["OXPROPS_Sect"], ", alternative name:", altname, "duplicates canonical name in section", previous_alternative_names[altname] previous_alternative_names[altname] = (entry["OXPROPS_Sect"]) def check_duplicate_propids(): print "Checking property IDs / LIDs:" previous_propids = {} previous_proplids = {} for entry in properties: if entry.has_key("PropertyId"): propnum = entry["PropertyId"] if previous_propids.has_key(propnum) and propnum < 0x6800: print "\tIn section", entry["OXPROPS_Sect"], "(" + entry["CanonicalName"] + ")" print "\t\tProperty id 0x" + format(propnum, "04x"), "(" + entry["DataTypeName"] + ") duplicates property id in section", previous_propids[propnum][0], "(" + previous_propids[propnum][1] + ")" if (entry.has_key("DataTypeName")): previous_propids[propnum] = (entry["OXPROPS_Sect"], entry["DataTypeName"]) else: previous_propids[propnum] = (entry["OXPROPS_Sect"], "[No DataType]") elif entry.has_key("PropertyLid"): propnum = entry["PropertyLid"] if previous_proplids.has_key(propnum): print "\tIn section", entry["OXPROPS_Sect"], "(" + entry["CanonicalName"] + ")" print "\t\tProperty LID 0x" + format(propnum, "08x"), "(" + entry["DataTypeName"] + ") duplicates property LID in section", previous_proplids[propnum][0], "(" + previous_proplids[propnum][1] + ")" if (entry.has_key("DataTypeName")): previous_proplids[propnum] = (entry["OXPROPS_Sect"], entry["DataTypeName"]) else: previous_proplids[propnum] = (entry["OXPROPS_Sect"], "[No DataTypeName]") elif entry["CanonicalName"].startswith("PidLid"): print "Section", entry["OXPROPS_Sect"], "(" + entry["CanonicalName"] + ") has neither LID nor ID" elif entry["CanonicalName"].startswith("PidName"): pass else: print "Section", entry["OXPROPS_Sect"], "(" + entry["CanonicalName"] + ") is weird" if (entry["CanonicalName"].startswith("PidName") and (entry.has_key("PropertyId") or entry.has_key("PropertyLid"))): print "Section", entry["OXPROPS_Sect"], "(" + entry["CanonicalName"], "in", entry["PropertySet"] + ") has neither LID or ID" def check_proptypes(): print "Checking that data types match:" for entry in properties: datatypename = entry["DataTypeName"] datatypevalue = entry["DataTypeValue"] if (knowndatatypes.has_key(datatypename) == False): print "\tIn section %(section)s : unknown data type %(type)s" % { 'section': entry["OXPROPS_Sect"], 'type': datatypename } elif (knowndatatypes[datatypename] != datatypevalue): print "\tIn section %(section)s : got value %(value)i for type %(type)i (expected %(expected)i)" % { 'section': entry["OXPROPS_Sect"], 'value': datatypeval, 'type': datatypename, 'expected': knowndatatype[datatypename] } def check_propsets(): print "Checking that property sets match:" for entry in properties: if entry.has_key("PropertySet"): propsetname = entry["PropertySet"] propsetvalue = entry["PropertySetValue"] if (knownpropsets.has_key(propsetname) == False): print "\tIn section %(section)s : unknown property set %(propset)s" % { 'section': entry["OXPROPS_Sect"], 'propset': propsetname } elif (knownpropsets[propsetname] != propsetvalue): print "\tIn section %(section)s : got value %(value)s for type %(type)s (expected %(expected)s)" % { 'section': entry["OXPROPS_Sect"], 'value': propsetvalue, 'type': propsetname, 'expected': knownpropsets[propsetname] } def check_descriptions(): print "Checking for descriptions:" for entry in properties: if entry.has_key("Description") == False: print "\tIn section %(section)s : there is no description" % { 'section': entry["OXPROPS_Sect"] } def check_areas(): print "Checking for areas:" for entry in properties: if entry.has_key("Area") == False: print "\tIn section %(section)s : there is no area" % { 'section': entry["OXPROPS_Sect"] } def check_reference_line(entry, line, isdefining): if line.endswith(","): print "\tIn section %(section)s : trailing comma in (defining?) references" % { 'section': entry["OXPROPS_Sect"] } line = line.rstrip(",") for docentry in line.split(","): docentry = docentry.strip() if docentry == "": print "\tIn section %(section)s : empty (defining) reference section" % { 'section': entry["OXPROPS_Sect"] } elif knownrefs.count(docentry) != 1: if len(docentry.split(" ")) > 1: if docentry.split(" ")[1].strip().startswith("section"): # thats ok pass else: print "\tIn section %(section)s : missing comma in (defining?) references: %(docentry)s" % { 'section': entry["OXPROPS_Sect"], 'docentry': docentry } else: print "\tIn section %(section)s : unknown document: %(docname)s" % { 'section': entry["OXPROPS_Sect"], 'docname': docentry } else: try: reffile = file("docs/" + docentry + ".txt") reftext = reffile.read().replace(" ", "") if docentry == "[MS-OXCFXICS]": if (reftext.count((entry["CanonicalName"][6:])) < 1): print "\tIn section %(section)s : (defining) references contains %(docname)s, but %(prop)s wasn't found in that document" % { 'section': entry["OXPROPS_Sect"], 'docname': docentry, 'prop': entry['CanonicalName'] } elif reftext.count(entry["CanonicalName"]) < 1: print "\tIn section %(section)s : (defining) references contains %(docname)s, but %(prop)s wasn't found in that document" % { 'section': entry["OXPROPS_Sect"], 'docname': docentry, 'prop': entry['CanonicalName'] } except IOError: pass def check_references(): print "Checking for references:" for entry in properties: if entry.has_key("References"): check_reference_line(entry, entry["References"], False) elif entry.has_key("DefiningReference"): check_reference_line(entry, entry["DefiningReference"], True) else: print "\tIn section %(section)s : there is no (defining) reference entry" % { 'section': entry["OXPROPS_Sect"] } def check_properties_list(): check_proptypes() check_propsets() check_duplicate_canonical_names() check_duplicate_alternative_names() check_duplicate_propids() # check_descriptions() check_areas() check_references() def next_available_id(knownprops, increment): try: knownprops.index(increment) knownprops.remove(increment) increment += 1 return next_available_id(knownprops, increment) except ValueError: return increment def find_key(dic, val): """return the key of dictionary dic given the value""" try: for k,v in dic.iteritems(): if v == val: return k except ValueError: print "Value %s not found" % val def make_mapi_named_properties_file(): content = "" attributes = "" start_content = "" namedprops = [] knownprops = [] previous_ldif_lid = [] previous_ldif_name = [] for entry in properties: if (entry.has_key("CanonicalName") == False): print "Section", entry["OXPROPS_Sect"], "has no canonical name entry" continue if (entry.has_key("DataTypeName") == False): print "Section", entry["OXPROPS_Sect"], "has no data type entry" continue if (entry.has_key("PropertyId") == False): if entry.has_key("PropertySet"): guid = entry["PropertySet"] else: guid = "[No PropSet]" # Its a named property name = entry["CanonicalName"] proptype = entry["DataTypeName"] if entry.has_key("PropertyLid"): proplid = "0x" + format(entry["PropertyLid"], "04x") if proplid in previous_ldif_lid: print "Skipping output for named properties MNID_ID", name, "(duplicate)" continue; kind = "MNID_ID" OOM = "NULL" # use as default propname = "NULL" if entry.has_key("PropertyName"): OOM = entry["PropertyName"].strip() elif entry.has_key("AlternateNames"): altname = entry["AlternateNames"].strip() if altname.startswith("dispid"): OOM = altname[6:] else: OOM = altname else: pass previous_ldif_lid.append(proplid) else: proplid = "0x0000" kind = "MNID_STRING" OOM = "NULL" propname = "NULL" # use as default if entry.has_key("PropertyName"): propname = entry["PropertyName"].strip() elif entry.has_key("AlternateNames"): for altname in entry["AlternateNames"]: altname = altname.strip() if altname.startswith("dispid"): propname = altname[6:] search_dup = "%s/%s" % (propname, guid) if search_dup in previous_ldif_name: print "Skipping output for named properties MNID_STRING", name, "(duplicate)" continue; previous_ldif_name.append(search_dup) namedprop = (name, OOM, proplid, propname, knowndatatypes[proptype], kind, guid) namedprops.append(namedprop) else: # It's not a named property # Store conflicting properties with propid > 0x8000 propid = entry["PropertyId"] if propid >= 0x8000: try: knownprops.index(propid) except ValueError: knownprops.append(propid) # Create the default GUID containers for key in sorted(knownpropsets): cn = knownpropsets[key].strip('{}').lower() oleguid_ldif = "dn: CN=%s,CN=External,CN=Server\n" \ "objectClass: External\n" \ "cn: %s\n" \ "name: %s\n" \ "oleguid: %s\n\n" % (cn, cn, str(key), cn) content += oleguid_ldif # Write named properties sortednamedprops = sorted(namedprops, key=lambda namedprops: namedprops[6]) # sort by guid increment = next_available_id(knownprops, 0x8000) for line in sortednamedprops: oleguid = knownpropsets[line[6]].strip('{}').lower() if line[5] == "MNID_STRING": named_props_ldif = "dn: CN=%s,CN=MNID_STRING,CN=%s,CN=External,CN=Server\n" \ "objectClass: External\n" \ "objectClass: MNID_STRING\n" \ "cn: %s\n" \ "canonical: %s\n" \ "oleguid: %s\n" \ "mapped_id: 0x%.4x\n" \ "prop_id: %s\n" \ "prop_type: %s\n" \ "prop_name: %s\n\n" % ( line[3], oleguid, line[3], line[0], oleguid, increment, line[2], line[4], line[3]) else: named_props_ldif = "dn: CN=%s,CN=MNID_ID,CN=%s,CN=External,CN=Server\n" \ "objectClass: External\n" \ "objectClass: MNID_ID\n" \ "cn: %s\n" \ "canonical: %s\n" \ "oleguid: %s\n" \ "mapped_id: 0x%.4x\n" \ "prop_id: %s\n" \ "prop_type: %s\n" \ "oom: %s\n\n" % ( line[2], oleguid, line[2], line[0], oleguid, increment, line[2], line[4], line[1]) content += named_props_ldif increment += 1 increment = next_available_id(knownprops, increment) # Store remaining reserved named properties IDs in attributes for ids in sorted(knownprops): attributes += "reserved_tags: 0x%.4x\n" % ids start_content = "# LDIF file automatically auto-generated by script/makepropslist.py. Do not edit\n\n" start_content += "dn: CN=Server\n" \ "objectClass: top\n" \ "cn: Server\n\n" \ \ "dn: CN=Internal,CN=Server\n" \ "objectClass: Internal\n" \ "objectClass: container\n" \ "objectClass: top\n" \ "cn: Internal\n" \ "mapping_index: 0x0001\n\n" \ \ "dn: CN=External,CN=Server\n" \ "objectClass: External\n" \ "objectClass: container\n" \ "objectClass: top\n" \ "cn: External\n" \ "mapping_index: 0x%.4x\n" % increment start_content += attributes + "\n" start_content += "dn: CN=Users,CN=Server\n" \ "objectClass: container\n" \ "objectClass: top\n" \ "cn: Users\n\n" content = start_content + content # wite named properties buffered file out to LDIF file f = open('setup/mapistore/mapistore_namedprops_v2.ldif', 'w') f.write(content) f.close() # write named properties defines and structure f = open('libmapi/mapi_nameid.h', 'w') f.write(""" /* Automatically generated by script/makepropslist.py. Do not edit */ #ifndef __MAPI_NAMEID_H__ #define __MAPI_NAMEID_H__ /* NOTE TO DEVELOPERS: If this is a MNID_STRING named property, then * we use the arbitrary 0xa000-0xafff property ID range for internal * mapping purpose only. */ struct mapi_nameid_tags { uint32_t proptag; const char *OOM; uint16_t lid; const char *Name; uint32_t propType; uint8_t ulKind; const char *OLEGUID; uint32_t position; }; struct mapi_nameid_names { uint32_t proptag; const char *propname; }; struct mapi_nameid { struct MAPINAMEID *nameid; uint16_t count; struct mapi_nameid_tags *entries; }; /* MNID_ID named properties */ """) for line in sortednamedprops: if line[5] == "MNID_ID": proptag = "0x%.8x" % (int(line[2], 16) << 16 | int(line[4], 16)) propline = "#define %s %s\n" % (string.ljust(line[0], 60), string.ljust(proptag, 20)) f.write(propline) f.write("\n/* MNID_STRING named properties (internal mapping) */\n") mnstring_id = 0xa000 for line in sortednamedprops: if line[5] == "MNID_STRING": proptag = "0x%.8x" % ((mnstring_id << 16) | int(line[4], 16)) propline = "#define %s %s\n" % (string.ljust(line[0], 60), string.ljust(proptag, 20)) mnstring_id += 1 f.write(propline) # Additional properties propline = "#define %s %s\n" % (string.ljust("PidLidRemoteTransferSize", 60), string.ljust("0x8f050003", 20)) f.write(propline) f.write("#endif /* ! MAPI_NAMEID_H__ */") f.close() # write named properties internal mapping f = open('libmapi/mapi_nameid_private.h', 'w') f.write(""" /* Automatically generated by script/makepropslist.py. Do not edit */ #ifndef __MAPI_NAMEID_PRIVATE_H__ #define __MAPI_NAMEID_PRIVATE_H__ static struct mapi_nameid_tags mapi_nameid_tags[] = { """) for line in sortednamedprops: if line[5] == "MNID_ID": OOM = "\"%s\"" % line[1] key = find_key(knowndatatypes, line[4]) datatype = datatypemap[key] propline = "{ %s, %s, %s, %s, %s, %s, %s, %s },\n" % ( string.ljust(line[0], 60), string.ljust(OOM, 65), line[2], line[3], string.ljust(datatype, 15), "MNID_ID", line[6], "0x0") f.write(propline) for line in sortednamedprops: if line[5] == "MNID_STRING": OOM = "%s" % line[1] key = find_key(knowndatatypes, line[4]) datatype = datatypemap[key] propline = "{ %s, %s, %s, \"%s\", %s, %s, %s, %s },\n" % ( string.ljust(line[0], 60), string.ljust(OOM, 65), line[2], line[3], string.ljust(datatype, 15), "MNID_STRING", line[6], "0x0") f.write(propline) # Addtional named properties propline = "{ %s, %s, %s, %s, %s, %s, %s, %s },\n" % ( string.ljust("PidLidRemoteTransferSize", 60), string.ljust("\"RemoteTransferSize\"", 65), "0x8f05", "NULL", string.ljust("PT_LONG", 15), "MNID_ID", "PSETID_Remote", "0x0") f.write(propline) propline = "{ %s, %s, %s, %s, %s, %s, %s, %s }\n" % ( string.ljust("0x00000000", 60), string.ljust("NULL", 65), "0x0000", "NULL", string.ljust("PT_UNSPECIFIED", 15), "0x0", "NULL", "0x0") f.write(propline) f.write(""" }; """) f.write(""" static struct mapi_nameid_names mapi_nameid_names[] = { """) for line in sortednamedprops: propline = "{ %s, \"%s\" },\n" % (string.ljust(line[0], 60), line[0]) f.write(propline) # Additional named properties propline = "{ %s, \"%s\" }\n" % (string.ljust("PidLidRemoteTransferSize", 60), "PidLidRemoteTransferSize") propline = "{ %s, \"%s\" }\n" % (string.ljust("0x00000000", 60), "NULL") f.write(propline) f.write(""" }; #endif /* !MAPI_NAMEID_PRIVATE_H__ */ """) f.close() def dump_areas_count(): areas = {} for area in knownareas: areas[area] = 0 for entry in properties: if (entry.has_key("Area") == False): print "Section", entry["OXPROPS_Sect"], "has no area entry" else: areas[entry["Area"]] += 1 for area in knownareas: print area, ":", areas[area] def fix_problems(propsfilename): retcode = subprocess.call(["sed", "-i", "-e", "s/.Dta type: PtypBoolean, 0x000B/Data type: PtypBoolean, 0x000B/", "-e", "s/.Data Type: PtypString, 0x001F/Data type: PtypString, 0x001F/", "-e", "s/.Data type: PtyString, 0x001F/Data type: PtypString, 0x001F/", "-e", "s/.Area: MAPI Display Tables\[MS-OXOABK\] section 2.2.3.33/Area: MAPI Display Tables\\nDefining Reference: \[MS-OXOABK\] section 2.2.3.33/", "-e", "s/.Area: ProviderDefinedNonTransmittable\[MS-OXCTABL\] section 2.2.1.2/Area: ProviderDefinedNonTransmittable\\nDefining Reference: \[MS-OXCTABL\] section 2.2.1.2/", "-e", "s/.Area: Server-Side Rules Properties\[MS-OXORULE\] section 2.2.1.3.2.2/Area: Server-Side Rules Properties\\nDefining Reference: \[MS-OXORULE\] section 2.2.1.3.2.2/", "-e", "s/.Area: MapiMailUser\[MS-OXOABK\] section 2.2.4.66/Area: MapiMailUser\\nDefining Reference: \[MS-OXOABK\] section 2.2.4.66/", "-e", "s/.Description: \[MS-OXORULE\] section 2.2.7.3/Defining Reference: \[MS-OXORULE\] section 2.2.7.3/", "-e", "s/.Property set: PSTID_Sharing {00062040-0000-0000-C000-000000000046}/Property set: PSETID_Sharing {00062040-0000-0000-C000-000000000046}/", "-e", "s/.Property set: PSETID_Address {00062004-0000-0000-C000-00000000046}/Property set: PSETID_Address {00062004-0000-0000-C000-000000000046}/", "-e", "s/.Property set: PSETID_Address{00062004-0000-0000-C000-000000000046}/Property set: PSETID_Address {00062004-0000-0000-C000-000000000046}/", "-e", "s/.Property set: PSETID_Appointment {00062002-0000-0000-C000-0000000000046}/Property set: PSETID_Appointment {00062002-0000-0000-C000-000000000046}/", "-e", "s/.Property set: PSETID_Address {00062004-0000-0000-C00-0000000000046}/Property set: PSETID_Address {00062004-0000-0000-C000-000000000046}/", "-e", "s/.Consuming Reference: \[MS-OXCICAL\] Alternate names: PR_NEXT_SEND_ACCT/Consuming Reference: \[MS-OXCICAL\]\\nAlternate names: PR_NEXT_SEND_ACCT/", "-e", "s/.Alternate names: PR_WB_SF_ID//", "-e", "s/.Alternate names: PR_WB_SF_TAG//", "-e", "s/.Alternate names: PR_EMS_AB_DL_MEM_REJECT_PERMS//", "-e", "s/.Alternate names: PR_EMS_AB_DL_MEM_SUBMIT_PERMS//", propsfilename]) if retcode != 0: print "Could not fix problem:", retcode sys.exit(retcode) def main(): oxpropsparser = argparse.ArgumentParser(description='Convert MS-OXPROPS to other formats') oxpropsparser.add_argument('--pdffile', required=True) oxpropsparser.add_argument('--sanitycheck', action='store_true') oxpropsparser.add_argument('--sanitycheckonly', action='store_true') args = oxpropsparser.parse_args() propsfile = tempfile.mkstemp(suffix='txt') propsfilename = propsfile[1] retcode = subprocess.call(["pdftotext", "-nopgbrk", "-layout", args.pdffile, propsfilename]) if retcode != 0: print "Could not convert file to text:", retcode sys.exit(retcode) fix_problems(propsfilename) make_properties_list(propsfilename) if args.sanitycheck or args.sanitycheckonly: check_properties_list() # uses global variable # dump_areas_count() if args.sanitycheckonly == False: make_mapi_properties_file() make_mapi_named_properties_file() if __name__ == "__main__": main() openchange-2.0/script/mapi_object_init.prop000066400000000000000000000015321223057412600211720ustar00rootroot00000000000000void uno_check(void) { /* warning, named args to select() are currently not supported */ if (select("mapi_object_init", FCALL, NONE)) /* unmarked symbols of type function call */ { if (select("", USE, NONE)) /* unmarked symbols USEd in those stmnts */ { if (match(1, DEF, NONE)) /* are there matching symbols with mark 1? */ error("mapi_object_init follows mapi_object_init"); else mark(1); /* mark 1 */ } } if (select("mapi_object_release", FCALL, NONE)) { if (select("", USE, NONE)) { if (match(1, USE, NONE)) unmark(); /* remove mark */ else error("mapi_object_release without mapi_object_init"); } else error("no argument to mapi_object_release"); } if (path_ends()) { if (marked(1, ANY, NONE)) { if (known_zero()) no_error(); else error("mapi_object_init without mapi_object_release"); } } } openchange-2.0/script/mkproto.pl000077500000000000000000000162001223057412600170220ustar00rootroot00000000000000#!/usr/bin/perl # Simple script for generating prototypes for C functions # Written by Jelmer Vernooij # based on the original mkproto.sh by Andrew Tridgell use strict; # don't use warnings module as it is not portable enough # use warnings; use Getopt::Long; ##################################################################### # read a file into a string my $public_file = undef; my $private_file = undef; my $public_define = undef; my $private_define = undef; my $_public = ""; my $_private = ""; my $public_data = \$_public; my $private_data = \$_private; sub public($) { my ($d) = @_; $$public_data .= $d; } sub private($) { my ($d) = @_; $$private_data .= $d; } sub usage() { print "Usage: mkproto.pl [options] [c files]\n"; print "OPTIONS:\n"; print " --public=FILE Write prototypes for public functions to FILE\n"; print " --private=FILE Write prototypes for private functions to FILE\n"; print " --define=DEF Use DEF to check whether header was already included\n"; print " --public-define=DEF Same as --define, but just for public header\n"; print " --private-define=DEF Same as --define, but just for private header\n"; print " --help Print this help message\n\n"; exit 0; } GetOptions( 'public=s' => sub { my ($f,$v) = @_; $public_file = $v; }, 'private=s' => sub { my ($f,$v) = @_; $private_file = $v; }, 'define=s' => sub { my ($f,$v) = @_; $public_define = $v; $private_define = "$v\_PRIVATE"; }, 'public-define=s' => \$public_define, 'private-define=s' => \$private_define, 'help' => \&usage ) or exit(1); if (not defined($public_define) and defined($public_file)) { $public_define = ".." . uc($public_file) . "__"; $public_define =~ tr{./}{__}; } elsif (not defined($public_define)) { $public_define = '_PROTO_H_'; } if (not defined($private_define) and defined($private_file)) { $private_define = "__" . uc($private_file) . "__"; $private_define =~ tr{./}{__}; } elsif (not defined($public_define)) { $public_define = '_PROTO_H_'; } if ((defined($private_file) and defined($public_file) and ($private_file eq $public_file)) or (not defined($private_file) and not defined($public_file))) { $private_data = $public_data; } sub file_load($) { my($filename) = shift; local(*INPUTFILE); open(INPUTFILE, $filename) || return undef; my($saved_delim) = $/; undef $/; my($data) = ; close(INPUTFILE); $/ = $saved_delim; return $data; } sub print_header($$) { my ($file, $header_name) = @_; $file->("#ifndef $header_name\n"); $file->("#define $header_name\n\n"); $file->("#undef _PRINTF_ATTRIBUTE\n"); $file->("#define _PRINTF_ATTRIBUTE(a1, a2) PRINTF_ATTRIBUTE(a1, a2)\n\n"); $file->("#ifndef __BEGIN_DECLS\n"); $file->("#ifdef __cplusplus\n"); $file->("#define __BEGIN_DECLS extern \"C\" {\n"); $file->("#define __END_DECLS }\n"); $file->("#else\n"); $file->("#define __BEGIN_DECLS\n"); $file->("#define __END_DECLS\n"); $file->("#endif\n"); $file->("#endif\n"); $file->("\n__BEGIN_DECLS\n\n"); $file->("/* This file was automatically generated by mkproto.pl. DO NOT EDIT */\n\n"); } sub print_footer($$) { my ($file, $header_name) = @_; $file->("\n__END_DECLS\n\n"); $file->("#undef _PRINTF_ATTRIBUTE\n"); $file->("#define _PRINTF_ATTRIBUTE(a1, a2)\n"); $file->("\n#endif /* $header_name */\n\n"); } sub handle_loadparm($$) { my ($file,$line) = @_; if ($line =~ /^_PUBLIC_ FN_(GLOBAL|LOCAL)_(CONST_STRING|STRING|bool|CHAR|INTEGER|LIST)\((\w+),.*\)/o) { my $scope = $1; my $type = $2; my $name = $3; my %tmap = ( "bool" => "bool ", "CONST_STRING" => "const char *", "STRING" => "const char *", "INTEGER" => "int ", "CHAR" => "char ", "LIST" => "const char **", ); my %smap = ( "GLOBAL" => "void", "LOCAL" => "int " ); $file->("$tmap{$type}$name($smap{$scope});\n"); } } sub delete_arguments($) { my ($proto) = @_; chomp($proto); # If function with void argument do not process it return $proto if ($proto =~ /\(void\)/); # Remove the argument name $proto =~ s/([\w],[\s])*([\*]*)(\w)*([\,\)])/$1$2$4/g; # Remove extra space between type and sep $proto =~ s/([\w]+)([\s]+)([\,\)])/$1$3/g; # Remove any spaces between , and the next char $proto =~ s/([\,])(^[\w]+)([\w\)]+)/$1 $3/g; # Remove tabulations $proto =~ s/[\s]{2,}//g; # Remove \n $proto =~ s/[\n]+/ /g; return $proto; } sub process_file($$$) { my ($public_file, $private_file, $filename) = @_; $filename =~ s/\.o$/\.c/g; open(FH, "< $filename") || die "Failed to open $filename"; $private_file->("\n/* The following definitions come from $filename */\n\n"); while (my $line = ) { my $target = \&private; my $is_public = 0; # these are ordered for maximum speed next if ($line =~ /^\s/); next unless ($line =~ /\(/); next if ($line =~ /^\/|[;]/); if ($line =~ /^_PUBLIC_ FN_/) { handle_loadparm($public_file, $line); next; } if ($line =~ /^_PUBLIC_[\t ]/) { $target = \&public; $is_public = 1; } next unless ( $is_public || $line =~ / ^void|^bool|^int|^struct|^char|^const|^\w+_[tT]\s|^uint|^unsigned|^long| ^NTSTATUS|^ADS_STATUS|^enum\s.*\(|^DATA_BLOB|^WERROR|^XFILE|^FILE|^DIR| ^double|^TDB_CONTEXT|^TDB_DATA|^TALLOC_CTX|^NTTIME|^FN_|^init_module| ^GtkWidget|^GType|^smb_ucs2_t /xo); next if ($line =~ /^int\s*main/); if ( $line =~ /\(.*\)\s*$/o ) { chomp $line; $line = delete_arguments($line); $target->("$line;\n"); next; } $line = delete_arguments($line); $target->($line); while ($line = ) { if ($line =~ /\)\s*$/o) { chomp $line; $line = delete_arguments($line); $target->("$line;\n"); last; } $target->($line); } } close(FH); } print_header(\&public, $public_define); if ($public_file ne $private_file) { print_header(\&private, $private_define); private("/* this file contains prototypes for functions that " . "are private \n * to this subsystem or library. These functions " . "should not be \n * used outside this particular subsystem! */\n\n"); public("/* this file contains prototypes for functions that " . "are part of \n * the public API of this subsystem or library. */\n\n"); } public("#ifndef _PUBLIC_\n#define _PUBLIC_\n#endif\n\n"); process_file(\&public, \&private, $_) foreach (@ARGV); print_footer(\&public, $public_define); if ($public_file ne $private_file) { print_footer(\&private, $private_define); } if (not defined($public_file)) { print STDOUT $$public_data; } if (not defined($private_file) and defined($public_file)) { print STDOUT $$private_data; } my $old_public_data = file_load($public_file); my $old_private_data = file_load($private_file); if (not defined($old_public_data) or ($old_public_data ne $$public_data)) { open(PUBLIC, ">$public_file") or die("Can't open `$public_file': $!"); print PUBLIC "$$public_data"; close(PUBLIC); } if (($public_file ne $private_file) and ( not defined($old_private_data) or ($old_private_data ne $$private_data))) { open(PRIVATE, ">$private_file") or die("Can't open `$private_file': $!"); print PRIVATE "$$private_data"; close(PRIVATE); } openchange-2.0/script/mkrelease.sh000077500000000000000000000021251223057412600172770ustar00rootroot00000000000000#!/bin/sh # # ./script/mkrelease.sh VERSION NICKNAME NICKNAME2 FIRST_REVISION # ./script/mkrelease.sh 0.7 PHASER Phaser 308 # TMPDIR=`mktemp openchange-XXXXX` rm $TMPDIR || exit 1 svn export . $TMPDIR || exit 1 svn log -r$4:HEAD > $TMPDIR/CHANGELOG || exit 1 ( cd $TMPDIR/ ./autogen.sh || exit 1 ./configure || exit 1 make || exit 1 sed -i "s/^OPENCHANGE_VERSION_IS_SVN_SNAPSHOT=yes/OPENCHANGE_VERSION_IS_SVN_SNAPSHOT=no/g" VERSION || exit 1 sed -i "s/^OPENCHANGE_VERSION_RELEASE_NICKNAME=.*/OPENCHANGE_VERSION_RELEASE_NICKNAME=$3/g" VERSION || exit 1 sed -i "s/^OPENCHANGE_VERSION_RELEASE_NUMBER=.*/OPENCHANGE_VERSION_RELEASE_NUMBER=$1/g" VERSION || exit 1 ./autogen.sh || exit 1 ./configure || exit 1 make doxygen || exit 1 make distclean || exit 1 rm .bzrignore ) || exit 1 VERSION=$1-$2 mv $TMPDIR openchange-$VERSION || exit 1 tar -cf openchange-$VERSION.tar openchange-$VERSION || exit 1 echo "Now run: " echo "gpg --detach-sign --armor openchange-$VERSION.tar" echo "gzip openchange-$VERSION.tar" echo "And then upload " echo "openchange-$VERSION.tar.gz openchange-$VERSION.tar.asc" openchange-2.0/script/mkversion.sh000077500000000000000000000060051223057412600173450ustar00rootroot00000000000000#!/bin/sh VERSION_FILE=$1 OUTPUT_FILE=$2 if test -z "$VERSION_FILE";then $VERSION_FILE="VERSION" fi if test -z "$OUTPUT_FILE";then $OUTPUT_FILE="libmapi/version.h" fi OPENCHANGE_VERSION_STRING=$3 SOURCE_DIR=$4 OPENCHANGE_MAJOR_RELEASE=`echo ${OPENCHANGE_VERSION_STRING} | cut -d. -f1` OPENCHANGE_MINOR_RELEASE=`echo ${OPENCHANGE_VERSION_STRING} | cut -d. -f2` OPENCHANGE_VERSION_IS_SVN_SNAPSHOT=`sed -n 's/^OPENCHANGE_VERSION_IS_SVN_SNAPSHOT=//p' $SOURCE_DIR$VERSION_FILE` OPENCHANGE_VERSION_RELEASE_NICKNAME=`sed -n 's/^OPENCHANGE_VERSION_RELEASE_NICKNAME=//p' $SOURCE_DIR$VERSION_FILE` OPENCHANGE_VERSION_RELEASE_NUMBER=`sed -n 's/^OPENCHANGE_VERSION_RELEASE_NUMBER=//p' $SOURCE_DIR$VERSION_FILE` TMPFILE=`mktemp` echo "/* Autogenerated by script/mkversion.h */" >> $TMPFILE echo "#define OPENCHANGE_MAJOR_RELEASE ${OPENCHANGE_MAJOR_RELEASE}" >> $TMPFILE echo "#define OPENCHANGE_MINOR_RELEASE ${OPENCHANGE_MINOR_RELEASE}" >> $TMPFILE # # SVN revision number # if test x"${OPENCHANGE_VERSION_IS_SVN_SNAPSHOT}" = x"yes";then _SAVE_LANG=${LANG} LANG="" HAVEVER="no" if test x"${HAVEVER}" != x"yes";then HAVESVN=no SVN_INFO=`svn info ${SOURCE_DIR} 2>/dev/null` TMP_REVISION=`echo -e "${SVN_INFO}" | grep 'Last Changed Rev.*:' |sed -e 's/Last Changed Rev.*: \([0-9]*\).*/\1/'` if test -n "$TMP_REVISION"; then HAVESVN=yes HAVEVER=yes fi fi if test x"${HAVESVN}" = x"yes";then OPENCHANGE_VERSION_STRING="${OPENCHANGE_VERSION_STRING}-SVN-build-${TMP_REVISION}" echo "#define OPENCHANGE_VERSION_SVN_REVISION ${TMP_REVISION}" >> $TMPFILE fi LANG=${_SAVE_LANG} fi if test -z "${OPENCHANGE_VERSION_RELEASE_NUMBER}";then echo "#define OPENCHANGE_VERSION_OFFICIAL_STRING \"${OPENCHANGE_VERSION_STRING}\"" >> $TMPFILE else OPENCHANGE_VERSION_STRING="${OPENCHANGE_VERSION_RELEASE_NUMBER}" echo "#define OPENCHANGE_VERSION_OFFICIAL_STRING \"${OPENCHANGE_VERSION_RELEASE_NUMBER}\"" >> $TMPFILE fi ## ## Add a release nickname ## if test -n "${OPENCHANGE_VERSION_RELEASE_NICKNAME}";then echo "#define OPENCHANGE_VERSION_RELEASE_NICKNAME ${OPENCHANGE_VERSION_RELEASE_NICKNAME}" >> $TMPFILE OPENCHANGE_VERSION_STRING="${OPENCHANGE_VERSION_STRING} (${OPENCHANGE_VERSION_RELEASE_NICKNAME})" fi echo "#define OPENCHANGE_VERSION_STRING \"${OPENCHANGE_VERSION_STRING}\"" >> $TMPFILE ## ## Add some System related information (useful for debug and report) ## echo "" >> $TMPFILE echo "/* System related information */" >> $TMPFILE OPENCHANGE_SYS_KERNEL_NAME=`uname -s` OPENCHANGE_SYS_KERNEL_RELEASE=`uname -r` OPENCHANGE_SYS_PROCESSOR=`uname -p` echo "#define OPENCHANGE_SYS_KERNEL_NAME \"${OPENCHANGE_SYS_KERNEL_NAME}\"" >> $TMPFILE echo "#define OPENCHANGE_SYS_KERNEL_RELEASE \"${OPENCHANGE_SYS_KERNEL_RELEASE}\"" >> $TMPFILE echo "#define OPENCHANGE_SYS_PROCESSOR \"${OPENCHANGE_SYS_PROCESSOR}\"" >> $TMPFILE mv "$TMPFILE" "$OUTPUT_FILE" echo "$0: '$OUTPUT_FILE' created for OpenChange libmapi(\"${OPENCHANGE_VERSION_STRING}\")" exit 0 openchange-2.0/script/samba4_ver.sh000066400000000000000000000000731223057412600173470ustar00rootroot00000000000000SAMBA4_GIT_REV= SAMBA4_GIT_VER=4.0.1 SAMBA4_RELEASE=4.0.1 openchange-2.0/script/smoketest.sh000077500000000000000000000140711223057412600173500ustar00rootroot00000000000000#!/bin/sh ADMIN_USERNAME=Administrator ADMIN_PASSWORD=YeahWhatever TEST1_USERNAME=testuser1 TEST1_USERPASS=testuser1 TEST1_PROFILENAME=testuser1 TEST2_USERNAME= TEST2_USERPASS= TEST2_PROFILENAME= SERVER1_NAME= SERVER2_NAME= SERVER1_IP=192.168.244.20 SERVER1_DOMAIN=OPENCHANGETEST ######################################################################## # Support functions # # You shouldn't need to modify anything after this ######################################################################## declare -i TESTCOUNT=0 declare -i TESTPOINTCOUNT=0 TEST() { TESTPOINTCOUNT=0 TESTCOUNT=$TESTCOUNT+1 echo "##############################################################" echo "Test $TESTCOUNT: $1" echo "##############################################################" } TESTPOINT() { TESTPOINTCOUNT=$TESTPOINTCOUNT+1 echo "# Testpoint $TESTCOUNT.$TESTPOINTCOUNT: $1" res=eval $1 echo $res echo "" } TESTPOINT_VERSION() { TOOL=$1 TESTPOINT "$TOOL --version" TESTPOINT "$TOOL -V" } TESTPOINT_USAGE() { TOOL=$1 TESTPOINT "$TOOL --help" TESTPOINT "$TOOL -?" TESTPOINT "$TOOL --usage" } ######################################################################## TEST "Verify mapiprofile" ######################################################################## TESTPOINT_VERSION "./bin/mapiprofile" TESTPOINT_USAGE "./bin/mapiprofile" ## Create a test profile database PROFILEDB=`mktemp -u profiles.XXXXXXXXXXXXXXXXXXXXX` TESTPOINT "./bin/mapiprofile --database=$PROFILEDB --newdb" ## Check we are OK if there is no entries in the database TESTPOINT "./bin/mapiprofile --database=$PROFILEDB --list" ## Check that the languages list stuff works TESTPOINT "./bin/mapiprofile --listlangs" ## Test point - Create an admin account profile ## Test point - Set the admin account as the default ## List the accounts TESTPOINT "./bin/mapiprofile --database=$PROFILEDB --list" ## Get the default account TESTPOINT "./bin/mapiprofile --database=$PROFILEDB --getdefault" ## Create a (test) user account using NTLM TESTPOINT "./bin/mapiprofile --database=$PROFILEDB --username=$TEST1_USERNAME --password=$TEST1_USERPASS --profile=$TEST1_PROFILENAME --address=$SERVER1_IP --domain=$SERVER1_DOMAIN --create" ## Test point - Create another (test) user account using Kerberos ## Set the user account as the default TESTPOINT "./bin/mapiprofile --database=$PROFILEDB --profile=$TEST1_PROFILENAME --default" ## Dump a profile's contents TESTPOINT "./bin/mapiprofile --database=$PROFILEDB --profile=$TEST1_PROFILENAME --dump" ## Test point - Delete a profile ######################################################################## TEST "Verify openchangeclient basic functions" ######################################################################## TESTPOINT_VERSION "./bin/openchangeclient --database=$PROFILEDB --profile=$TEST1_PROFILENAME" TESTPOINT_USAGE "./bin/openchangeclient --database=$PROFILEDB --profile=$TEST1_PROFILENAME" ######################################################################## TEST "Verify openchangeclient admin functions" ######################################################################## ######################################################################## TEST "Verify openchangeclient user functions" ######################################################################## ## Verify that we can get a basic mailbox list TESTPOINT "./bin/openchangeclient --database=$PROFILEDB --profile=$TEST1_PROFILENAME --mailbox" ## Verify that we can list the users TESTPOINT "./bin/openchangeclient --database=$PROFILEDB --profile=$TEST1_PROFILENAME --userlist" ## Verify that we can download mail TESTPOINT "./bin/openchangeclient --database=$PROFILEDB --profile=$TEST1_PROFILENAME --fetchmail" ## Test point - verify we can send plain text mail ## Test point - verify we can send HTML mail ## Test point - verify we can add an attachment to a mail ######################################################################## TEST "Verify openchangeclient OCPF functions" ######################################################################## ######################################################################## TEST "Run the mapitest suite" ######################################################################## TESTPOINT_VERSION "./bin/mapitest" TESTPOINT_USAGE "./bin/mapitest" TESTPOINT ./bin/mapitest --database=$PROFILEDB --no-server ## Test point - Run just one step from mapitest ## Run mapitest as a specified user TESTPOINT "./bin/mapitest --database=$PROFILEDB --profile=$TEST1_PROFILENAME" ######################################################################## TEST "Verify exchange2mbox" ######################################################################## TESTPOINT_VERSION "./bin/exchange2mbox" TESTPOINT_USAGE "./bin/exchange2mbox" ######################################################################## TEST "Verify exchange2ical" ######################################################################## TESTPOINT_VERSION "./bin/exchange2ical" TESTPOINT_USAGE "./bin/exchange2ical" ## Verify basic dump of calendar TESTPOINT "./bin/exchange2ical --database=$PROFILEDB --profile=$TEST1_PROFILENAME" ######################################################################## TEST "Verify locale_codepage" ######################################################################## TESTPOINT_VERSION "./bin/locale_codepage" TESTPOINT_USAGE "./bin/locale_codepage" ## Check a locale ID TESTPOINT "./bin/locale_codepage --locale_id=0x0c09" ## Verify the group listing works TESTPOINT "./bin/locale_codepage --list-groups" ## Check a codepage TESTPOINT "./bin/locale_codepage --codepage=0x4B0" ######################################################################## TEST "Verify openchangepfadmin" ######################################################################## TESTPOINT_VERSION "./bin/openchangepfadmin" TESTPOINT_USAGE "./bin/openchangepfadmin" ## Get the list of public folders TESTPOINT "./bin/openchangepfadmin --database=$PROFILEDB --profile=$TEST1_PROFILENAME --list" ############# # Cleanup stuff ############# rm $PROFILEDB openchange-2.0/script/uninstallman.sh000077500000000000000000000013511223057412600200340ustar00rootroot00000000000000#!/bin/sh # 4 July 96 Dan.Shearer@UniSA.edu.au # Updated for Samba4 by Jelmer Vernooij MANDIR=$1 shift 1 MANPAGES=$* for I in $MANPAGES do SECTION=`echo $I | grep -o '.$'` MAN=`echo $I | grep -o '[a-zA-Z_]*\.[0-9]'` FNAME=$MANDIR/man$SECTION/$MAN if test -f $FNAME; then echo Deleting $FNAME rm -f $FNAME test -f $FNAME && echo Cannot remove $FNAME... does $USER have privileges? fi done cat << EOF ====================================================================== The man pages have been uninstalled. You may install them again using the command "make installman" or make "install" to install binaries, man pages and shell scripts. ====================================================================== EOF exit 0 openchange-2.0/script/uno.dfn000066400000000000000000000000171223057412600162600ustar00rootroot00000000000000UnoType _Bool; openchange-2.0/setup/000077500000000000000000000000001223057412600146245ustar00rootroot00000000000000openchange-2.0/setup/AD/000077500000000000000000000000001223057412600151105ustar00rootroot00000000000000openchange-2.0/setup/AD/oc_provision_configuration.ldif000066400000000000000000001653041223057412600234210ustar00rootroot00000000000000################################################################ # CN=Services,${CONFIGDN} records ################################################################ # # Exchange configuration information object # This object stores configuration information for the Exchange Server # dn: CN=Microsoft Exchange,CN=Services,${CONFIGDN} objectClass: top objectClass: container objectClass: msExchConfigurationContainer cn: Microsoft Exchange distinguishedName: CN=Microsoft Exchange,CN=Services,${CONFIGDN} showInAdvancedViewOnly: TRUE adminDisplayName: Microsoft Exchange name: Microsoft Exchange objectCategory: CN=ms-Exch-Configuration-Container,${SCHEMADN} #msExchPolicyRoots: CN=System Policies,${FIRSTORGDN} #msExchPolicyRoots: CN=Recipient Policies,${FIRSTORGDN} # # First Organization # dn: ${FIRSTORGDN} objectClass: top objectClass: container objectClass: msExchOrganizationContainer cn: First Organization distinguishedName: ${FIRSTORGDN} showInAdvancedViewOnly: TRUE adminDisplayName: {335A1087-5131-4D45-BE3E-3C6C7F76F5EC} name: ${FIRSTORG} legacyExchangeDN: /o=${FIRSTORG} objectCategory: CN=ms-Exch-Organization-Container,${SCHEMADN} # # Administrative Groups # dn: CN=Administrative Groups,${FIRSTORGDN} objectClass: top objectClass: container objectClass: msExchAdminGroupContainer cn: Administrative Groups distinguishedName: CN=Administrative Groups,${FIRSTORGDN} displayName: Administrative Groups showInAdvancedViewOnly: TRUE name: Administrative Groups objectCategory: CN=ms-Exch-Admin-Group-Container,${SCHEMADN} # # First Administrative Group # dn: CN=First Administrative Group,CN=Administrative Groups,${FIRSTORGDN} objectClass: top objectClass: msExchAdminGroup cn: First Administrative Group distinguishedName: CN=First Administrative Group,CN=Administrative Groups,${FIRSTORGDN} displayName: First Administrative Group showInAdvancedViewOnly: TRUE siteFolderGUID: 4b2d197b-1cb3-486a-b8c3-42e8c5c08e27 name: First Administrative Group legacyExchangeDN: /o=${FIRSTORG}/ou=First Administrative Group objectCategory: CN=ms-Exch-Admin-Group,${SCHEMADN} msExchAdminGroupMode: 0 msExchDefaultAdminGroup: TRUE # # Servers # dn: CN=Servers,CN=First Administrative Group,CN=Administrative Groups,${FIRSTORGDN} objectClass: top objectClass: container objectClass: msExchServersContainer cn: Servers distinguishedName: CN=Servers,CN=First Administrative Group,CN=Administrative Groups,${FIRSTORGDN} showInAdvancedViewOnly: TRUE adminDisplayName: Servers containerInfo: 8 name: Servers objectCategory: CN=ms-Exch-Servers-Container,${SCHEMADN} # # The OpenChange Server object # dn: CN=${NETBIOSNAME},CN=Servers,CN=First Administrative Group,CN=Administrative Groups,${FIRSTORGDN} objectClass: top objectClass: server objectClass: msExchExchangeServer cn: ${NETBIOSNAME} serialNumber: Version 6.5 (Build 6944.4) distinguishedName: CN=${NETBIOSNAME},CN=Servers,CN=First Administrative Group,CN=Administrative Groups,${FIRSTORGDN} showInAdvancedViewOnly: TRUE adminDisplayName: ${NETBIOSNAME} messageTrackingEnabled: FALSE networkAddress: ncacn_vns_spp:${NETBIOSNAME} networkAddress: netbios:${NETBIOSNAME} networkAddress: ncacn_np:${NETBIOSNAME} networkAddress: ncacn_spx:${NETBIOSNAME} networkAddress: ncacn_ip_tcp:${HOSTNAME}.${DNSDOMAIN} networkAddress: ncalrpc:${NETBIOSNAME} name: ${NETBIOSNAME} versionNumber: 6944 serverRole: 0 legacyExchangeDN: /o=${FIRSTORG}/ou=First Administrative Group/cn=Configuration/cn=Servers/cn=${NETBIOSNAME} objectCategory: CN=ms-Exch-Exchange-Server,${SCHEMADN} #msExchHomeRoutingGroup: CN=First Routing Group,CN=Routing Groups,CN=First Administrative Group,CN=Administrative Groups,${FIRSTORGDN} msExchMessageTrackLogFilter: -262145 msExchTrkLogCleaningInterval: 7 #msExchResponsibleMTAServer: CN=Microsoft MTA,CN=${NETBIOSNAME},CN=Servers,CN=First Administrative Group,CN=Administrative Groups,${FIRSTORGDN} msExchMailboxManagerActivationStyle: 0 msExchMailboxManagerAdminMode: 2 # # Information Store # dn: CN=InformationStore,CN=${NETBIOSNAME},CN=Servers,CN=First Administrative Group,CN=Administrative Groups,${FIRSTORGDN} objectClass: top objectClass: container objectClass: msExchInformationStore cn: InformationStore distinguishedName: CN=InformationStore,CN=${NETBIOSNAME},CN=Servers,CN=First Administrative Group,CN=Administrative Groups,${FIRSTORGDN} showInAdvancedViewOnly: TRUE adminDisplayName: InformationStore name: InformationStore objectCategory: CN=ms-Exch-Information-Store,${SCHEMADN} # # First Storage Group # dn: CN=First Storage Group,CN=InformationStore,CN=${NETBIOSNAME},CN=Servers,CN=First Administrative Group,CN=Administrative Groups,${FIRSTORGDN} objectClass: top objectClass: container objectClass: msExchStorageGroup cn: First Storage Group distinguishedName: CN=First Storage Group,CN=InformationStore,CN=${NETBIOSNAME},CN=Servers,CN=First Administrative Group,CN=Administrative Groups,${FIRSTORGDN} showInAdvancedViewOnly: TRUE adminDisplayName: First Storage Group name: First Storage Group systemFlags: 1610612736 objectCategory: CN=ms-Exch-Storage-Group,${SCHEMADN} # # Public Folder Store (${NETBIOSNAME}) # dn: CN=Public Folder Store (${NETBIOSNAME}),CN=First Storage Group,CN=InformationStore,CN=${NETBIOSNAME},CN=Servers,CN=First Administrative Group,CN=Administrative Groups,${FIRSTORGDN} objectClass: top objectClass: msExchMDB objectClass: msExchPublicMDB cn: Public Folder Store (${NETBIOSNAME}) distinguishedName: CN=Public Folder Store (${NETBIOSNAME}),CN=First Storage Group,CN=InformationStore,CN=${NETBIOSNAME},CN=Servers,CN=First Administrative Group,CN=Administrative Groups,${FIRSTORGDN} displayName: Public Folder Store (${NETBIOSNAME}) activationStyle: 1 messageSizeLimit: 10240 showInAdvancedViewOnly: TRUE # finalize? homeMTA: CN=Microsoft MTA,CN=${NETBIOSNAME},CN=Servers,CN=First Administrative Group,CN=Administrative Groups,${FIRSTORGDN} adminDisplayName: Public Folder Store (${NETBIOSNAME}) proxyAddresses: SMTP:${NETBIOSNAME}-IS@${DNSDOMAIN} proxyAddresses: X400:c=US;a= ;p=First Organizati;o=Exchange;s=EXCH2K3-IS; deliveryMechanism: 1 garbageCollPeriod: 604800 quotaNotificationStyle: 1 # TODO: determine if this needs to go back in, and overcome the linked attribute issue. # See http://tracker.openchange.org/issues/252 # homeMDBBL: CN=SMTP (${NETBIOSNAME}-{E95EE010-3E8A-425B-806F-15ED60887F6B}),CN=Connections,${FIRSTORGDN} mailNickname: ${NETBIOSNAME}-IS name: Public Folder Store (${NETBIOSNAME}) systemFlags: 1610612736 legacyExchangeDN: /o=${FIRSTORG}/ou=First Administrative Group/cn=Configuration/cn=Servers/cn=${NETBIOSNAME}/cn=Microsoft Public MDB objectCategory: CN=ms-Exch-Public-MDB,${SCHEMADN} textEncodedORAddress: c=US;a= ;p=First Organizati;o=Exchange;s=${NETBIOSNAME}-IS; mail: ${NETBIOSNAME}-IS@${DNSDOMAIN} msExchOwningServer: CN=${NETBIOSNAME},CN=Servers,CN=First Administrative Group,CN=Administrative Groups,${FIRSTORGDN} #msExchOwningPFTree: CN=Public Folders,CN=Folder Hierarchies,CN=First Administrative Group,CN=Administrative Groups,${FIRSTORGDN} msExchMaxCachedViews: 11 msExchDatabaseCreated: TRUE msExchPoliciesIncluded: {627410A4-E1A9-4DD0-9568-FA22DEACB6B8},{26491CFC-9E50- 4857-861B-0CB8DF22B5D7} # # Mailbox Store (${NETBIOSNAME}) # dn: CN=Mailbox Store (${NETBIOSNAME}),CN=First Storage Group,CN=InformationStore,CN=${NETBIOSNAME},CN=Servers,CN=First Administrative Group,CN=Administrative Groups,${FIRSTORGDN} objectClass: top objectClass: msExchMDB objectClass: msExchPrivateMDB cn: Mailbox Store (${NETBIOSNAME}) distinguishedName: CN=Mailbox Store (${NETBIOSNAME}),CN=First Storage Group,CN=InformationStore,CN=${NETBIOSNAME},CN=Servers,CN=First Administrative Group,CN=Administrative Groups,${FIRSTORGDN} displayName: Mailbox Store (${NETBIOSNAME}) activationStyle: 1 deletedItemFlags: 5 showInAdvancedViewOnly: TRUE adminDisplayName: Mailbox Store (${NETBIOSNAME}) deliveryMechanism: 1 garbageCollPeriod: 604800 quotaNotificationStyle: 1 name: Mailbox Store (${NETBIOSNAME}) systemFlags: 1610612736 legacyExchangeDN: /o=${FIRSTORG}/ou=First Administrative Group/cn=Configuration/cn=Servers/cn=${NETBIOSNAME}/cn=Microsoft Private MDB objectCategory: CN=ms-Exch-Private-MDB,${SCHEMADN} msExchMailboxRetentionPeriod: 2592000 msExchMaxCachedViews: 11 msExchDatabaseCreated: TRUE # # Address Lists Containers # description: Address book root container # dn: CN=Address Lists Container,${FIRSTORGDN} objectClass: top objectClass: container objectClass: msExchContainer cn: Address Lists Container distinguishedName: CN=Address Lists Container,${FIRSTORGDN} instanceType: 4 displayName: Address Lists Container showInAdvancedViewOnly: TRUE name: Address Lists Container objectCategory: CN=ms-Exch-Container,${SCHEMADN} # # Offline Address Lists # dn: CN=Offline Address Lists,CN=Address Lists Container,${FIRSTORGDN} objectClass: top objectClass: container objectClass: msExchContainer cn: Offline Address Lists distinguishedName: CN=Offline Address Lists,CN=Address Lists Container,${FIRSTORGDN} displayName: Offline Address Lists showInAdvancedViewOnly: TRUE name: Offline Address Lists objectCategory: CN=ms-Exch-Container,${SCHEMADN} # disabled because CN=ms-Exch-OAB,${SCHEMADN} is not provisioned # # Default Offline Address List # # dn: CN=Default Offline Address List,CN=Offline Address Lists,CN=Address Lists Container,${FIRSTORGDN} # objectClass: top # objectClass: msExchOAB # cn: Default Offline Address List # distinguishedName: CN=Default Offline Address List,CN=Offline Address Lists,CN=Address Lists Container,${FIRSTORGDN} # showInAdvancedViewOnly: TRUE # offLineABStyle: 1 # offLineABContainers: CN=Default Global Address List,CN=All Global Address Lists,CN=Address Lists Container,${FIRSTORGDN} # offLineABSchedule:: AAAAAAAAgAAAAAAAAAAAAAAAgAAAAAAAAAAAAAAAgAAAAAAAAAAAAAAAgAAAAAAAAAAAAAAAgAAAAAAAAAAAAAAAgAAAAAAAAAAAAAAAgAAAAAAA # offLineABServer: CN=${NETBIOSNAME},CN=Servers,CN=First Administrative Group,CN=Administrative Groups,${FIRSTORGDN} # siteFolderGUID: e72eae5f-ee8e-4908-becb-fb58af7c62aa # siteFolderServer: CN=Public Folder Store (${NETBIOSNAME}),CN=First Storage Group,CN=InformationStore,CN=${NETBIOSNAME},CN=Servers,${FIRSTORGDN} # doOABVersion: 0 # name: Default Offline Address List # systemFlags: 1610612736 # legacyExchangeDN: /o=${FIRSTORG}/cn=addrlists/cn=oabs/cn=Default Offline Address List # objectCategory: CN=ms-Exch-OAB,${SCHEMADN} # objectGUID: f4d2ff48-0a08-4f96-8cfc-967401492989 # msExchOABDefault: TRUE # msExchOABFolder: AA== # # All Address Lists # description: Address book recipient # dn: CN=All Address Lists,CN=Address Lists Container,${FIRSTORGDN} objectClass: top objectClass: addressBookContainer cn: All Address Lists distinguishedName: CN=All Address Lists,CN=Address Lists Container,${FIRSTORGDN} displayName: All Address Lists showInAdvancedViewOnly: TRUE name: All Address Lists systemFlags: 1610612736 objectCategory: CN=Address-Book-Container,${SCHEMADN} # # All Global Address Lists # dn: CN=All Global Address Lists,CN=Address Lists Container,${FIRSTORGDN} objectClass: top objectClass: addressBookContainer cn: All Global Address Lists distinguishedName: CN=All Global Address Lists,CN=Address Lists Container,${FIRSTORGDN} displayName: All Global Address Lists showInAdvancedViewOnly: TRUE name: All Global Address Lists systemFlags: 1610612736 objectCategory: CN=Address-Book-Container,${SCHEMADN} # # Default global Address List # dn: CN=Default Global Address List,CN=All Global Address Lists,CN=Address Lists Container,${FIRSTORGDN} objectClass: top objectClass: addressBookContainer cn: Default Global Address List distinguishedName: CN=Default Global Address List,CN=All Global Address Lists,CN=Address Lists Container,${FIRSTORGDN} displayName: Default Global Address List showInAdvancedViewOnly: TRUE name: Default Global Address List systemFlags: 1610612736 objectCategory: CN=Address-Book-Container,${SCHEMADN} purportedSearch: (& (mailnickname=*) (| (&(objectCategory=person)(objectClass=user)(!(homeMDB=*))(!(msExchHomeServerName=*)))(&(objectCategory=person)(objectClass=user)(|(homeMDB=*)(msExchHomeServerName=*)))(&(objectCategory=person)(objectClass=contact))(objectCategory=group)(objectCategory=publicFolder)(objectCategory=msExchDynamicDistributionList) )) # # Recipient Update Services # dn: CN=Recipient Update Services,CN=Address Lists Container,${FIRSTORGDN} objectClass: top objectClass: container objectClass: msExchContainer cn: Recipient Update Services distinguishedName: CN=Recipient Update Services,CN=Address Lists Container,${FIRSTORGDN} displayName: Recipient Update Services showInAdvancedViewOnly: TRUE name: Recipient Update Services objectCategory: CN=ms-Exch-Container,${SCHEMADN} # # Recipient Update Service (${DOMAIN}) # dn: CN=Recipient Update Service (${DOMAIN}),CN=Recipient Update Services,CN=Address Lists Container,${FIRSTORGDN} objectClass: top objectClass: msExchAddressListService cn: Recipient Update Service (${DOMAIN}) distinguishedName: CN=Recipient Update Service (${DOMAIN}),CN=Recipient Update Services,CN=Address Lists Container,${FIRSTORGDN} activationStyle: 2 showInAdvancedViewOnly: TRUE name: Recipient Update Service (${DOMAIN}) systemFlags: 1073741824 objectCategory: CN=ms-Exch-Address-List-Service,${SCHEMADN} msExchServer1NetworkAddress: ${HOSTNAME} msExchServer1PageSize: 20 msExchDoFullReplication: FALSE msExchReplicateNow: FALSE msExchPollInterval: 60 msExchAddressListServiceLink: CN=${NETBIOSNAME},CN=Servers,CN=First Administrative Group,CN=Administrative Groups,${FIRSTORGDN} msExchDomainLink: ${DOMAINDN} msExchServer1HighestUSNVector: ${NETBIOSNAME}:53500 msExchDomainLocalGroupGuid: {D9CA41A1-5041-4FBF-8635-23B4D0BA8A48} msExchDomainGlobalGroupGuid: {1E2B98D3-4FAC-4FAE-B16F-A26AB09AAE34} msExchDomainLocalGroupSid: S-1-5-21-1226241484-1028146065-4277480997-1110 msExchDomainGlobalGroupSid: S-1-5-21-1226241484-1028146065-4277480997-1109 # # Recipient Update Service (Enterprise Configuration) # #dn: CN=Recipient Update Service (Enterprise Configuration),CN=Recipient Update Services,CN=Address Lists Container,${FIRSTORGDN} #objectClass: top #objectClass: msExchAddressListService #cn: Recipient Update Service (Enterprise Configuration) #distinguishedName: CN=Recipient Update Service (Enterprise Configuration),CN=Recipient Update Services,CN=Address Lists Container,${FIRSTORGDN} #activationStyle: 2 #showInAdvancedViewOnly: TRUE #name: Recipient Update Service (Enterprise Configuration) #systemFlags: 1073741824 #objectCategory: CN=ms-Exch-Address-List-Service,CN=Schema,CN=Configuration,DC=openchange2003,DC=local #msExchServer1NetworkAddress: ${HOSTNAME} #msExchServer1PageSize: 20 #msExchDoFullReplication: FALSE #msExchReplicateNow: FALSE #msExchPollInterval: 60 #msExchAddressListServiceLink: CN=${NETBIOSNAME},CN=Servers,CN=First Administrative Group,CN=Administrative Groups,${FIRSTORGDN} #msExchDomainLink: CN=Configuration,${DOMAINDN} # # All Users # dn: CN=All Users,CN=All Address Lists,CN=Address Lists Container,${FIRSTORGDN} objectClass: top objectClass: addressBookContainer cn: All Users distinguishedName: CN=All Users,CN=All Address Lists,CN=Address Lists Container,${FIRSTORGDN} displayName: All Users showInAdvancedViewOnly: TRUE name: All Users systemFlags: 1610612736 objectCategory: CN=Address-Book-Container,${SCHEMADN} purportedSearch: (& (mailnickname=*) (| (&(objectCategory=person)(objectClass=user)(!(homeMDB=*))(!(msExchHomeServerName=*)))(&(objectCategory=person)(objectClass=user)(|(homeMDB=*)(msExchHomeServerName=*))) )) # # All Groups # dn: CN=All Groups,CN=All Address Lists,CN=Address Lists Container,${FIRSTORGDN} objectClass: top objectClass: addressBookContainer cn: All Groups distinguishedName: CN=All Groups,CN=All Address Lists,CN=Address Lists Container,${FIRSTORGDN} displayName: All Groups showInAdvancedViewOnly: TRUE name: All Groups systemFlags: 1610612736 objectCategory: CN=Address-Book-Container,${SCHEMADN} purportedSearch: (& (mailnickname=*) (| (objectCategory=group) )) # # All Contacts # description: Address book recipient # dn: CN=All Contacts,CN=All Address Lists,CN=Address Lists Container,${FIRSTORGDN} objectClass: top objectClass: addressBookContainer cn: All Contacts distinguishedName: CN=All Contacts,CN=All Address Lists,CN=Address Lists Container,${FIRSTORGDN} displayName: All Contacts showInAdvancedViewOnly: TRUE name: All Contacts systemFlags: 1610612736 objectCategory: CN=Address-Book-Container,${SCHEMADN} purportedSearch: (& (mailnickname=*) (| (&(objectCategory=person)(objectClass=contact)) )) # # Public Folders # description: Address book recipient # dn: CN=Public Folders,CN=All Address Lists,CN=Address Lists Container,${FIRSTORGDN} objectClass: top objectClass: addressBookContainer cn: Public Folders distinguishedName: CN=Public Folders,CN=All Address Lists,CN=Address Lists Container,${FIRSTORGDN} displayName: Public Folders showInAdvancedViewOnly: TRUE name: Public Folders systemFlags: 1610612736 objectCategory: CN=Address-Book-Container,${SCHEMADN} purportedSearch: (& (mailnickname=*) (| (objectCategory=publicFolder) )) # # Addressing # description: Address container # dn: CN=Addressing,${FIRSTORGDN} objectClass: top objectClass: container objectClass: msExchContainer cn: Addressing distinguishedName: CN=Addressing,${FIRSTORGDN} instanceType: 4 showInAdvancedViewOnly: TRUE adminDisplayName: Addressing containerInfo: 16 name: Addressing legacyExchangeDN: /o=${FIRSTORG}/cn=Configuration/cn=Addressing objectCategory: CN=ms-Exch-Container,${SCHEMADN} # # Address-Templates # description: Specifies information for a Display Template # dn: CN=Address-Templates,CN=Addressing,${FIRSTORGDN} objectClass: top objectClass: container objectClass: msExchContainer cn: Address-Templates distinguishedName: CN=Address-Templates,CN=Addressing,${FIRSTORGDN} instanceType: 4 showInAdvancedViewOnly: TRUE adminDisplayName: One-Off Address Templates containerInfo: 32 name: Address-Templates legacyExchangeDN: /o=${FIRSTORG}/cn=Configuration/cn=Addressing/cn=Address-Templates objectCategory: CN=ms-Exch-Container,${SCHEMADN} msExchTemplateRDNs: 81A msExchTemplateRDNs: 403 msExchTemplateRDNs: 422 msExchTemplateRDNs: 427 msExchTemplateRDNs: 426 msExchTemplateRDNs: 425 msExchTemplateRDNs: 402 msExchTemplateRDNs: 424 msExchTemplateRDNs: 41b msExchTemplateRDNs: 418 msExchTemplateRDNs: 41a msExchTemplateRDNs: 42d msExchTemplateRDNs: 41e msExchTemplateRDNs: 40e msExchTemplateRDNs: 41f msExchTemplateRDNs: 419 msExchTemplateRDNs: 414 msExchTemplateRDNs: 406 msExchTemplateRDNs: 405 msExchTemplateRDNs: 41d msExchTemplateRDNs: 816 msExchTemplateRDNs: 415 msExchTemplateRDNs: 408 msExchTemplateRDNs: 40b msExchTemplateRDNs: 413 msExchTemplateRDNs: 416 msExchTemplateRDNs: 40d msExchTemplateRDNs: 401 msExchTemplateRDNs: 410 msExchTemplateRDNs: C0A msExchTemplateRDNs: 404 msExchTemplateRDNs: 804 msExchTemplateRDNs: 412 msExchTemplateRDNs: 40c msExchTemplateRDNs: c0c msExchTemplateRDNs: 407 msExchTemplateRDNs: 411 msExchTemplateRDNs: 409 # # Address-Types # description: E-Mail Address Generators # dn: CN=Address-Types,CN=Addressing,${FIRSTORGDN} objectClass: top objectClass: container objectClass: msExchContainer cn: Address-Types distinguishedName: CN=Address-Types,CN=Addressing,${FIRSTORGDN} instanceType: 4 showInAdvancedViewOnly: TRUE adminDisplayName: E-Mail Address Generators containerInfo: 128 name: Address-Types objectCategory: CN=ms-Exch-Container,${SCHEMADN} # # Display-Templates # # dn: CN=Display-Templates,CN=Addressing,${FIRSTORGDN} objectClass: top objectClass: container objectClass: msExchContainer cn: Display-Templates distinguishedName: CN=Display-Templates,CN=Addressing,${FIRSTORGDN} instanceType: 4 showInAdvancedViewOnly: TRUE adminDisplayName: Details Templates containerInfo: 64 name: Display-Templates legacyExchangeDN: /o=${FIRSTORG}/cn=Configuration/cn=Addressing/cn=Display-Templates objectCategory: CN=ms-Exch-Container,${SCHEMADN} # # Arabic Address-Templates # dn: CN=401,CN=Address-Templates,CN=Addressing,${FIRSTORGDN} objectClass: top objectClass: container cn: 401 distinguishedName: CN=401,CN=Address-Templates,CN=Addressing,${FIRSTORGDN} instanceType: 4 displayName: Arabic showInAdvancedViewOnly: TRUE adminDisplayName: Arabic name: 401 legacyExchangeDN: /o=${FIRSTORG}/CN=Configuration/CN=Addressing/CN=Address-Templates/CN=401 objectCategory: CN=Container,${SCHEMADN} msExchTemplateRDNs: EX msExchTemplateRDNs: SMTP msExchTemplateRDNs: CCMAIL msExchTemplateRDNs: MSA msExchTemplateRDNs: MS msExchTemplateRDNs: x400 # # Bulgarian Address-Templates # dn: CN=402,CN=Address-Templates,CN=Addressing,${FIRSTORGDN} objectClass: top objectClass: container cn: 402 distinguishedName: CN=402,CN=Address-Templates,CN=Addressing,${FIRSTORGDN} instanceType: 4 displayName: Bulgarian showInAdvancedViewOnly: TRUE adminDisplayName: Bulgarian name: 402 legacyExchangeDN: /o=${FIRSTORG}/CN=Configuration/CN=Addressing/CN=Address-Templates/CN=402 objectCategory: CN=Container,${SCHEMADN} msExchTemplateRDNs: EX msExchTemplateRDNs: SMTP msExchTemplateRDNs: CCMAIL msExchTemplateRDNs: MSA msExchTemplateRDNs: MS msExchTemplateRDNs: x400 # # Catalan Address-Templates # dn: CN=403,CN=Address-Templates,CN=Addressing,${FIRSTORGDN} objectClass: top objectClass: container cn: 403 distinguishedName: CN=403,CN=Address-Templates,CN=Addressing,${FIRSTORGDN} instanceType: 4 displayName: Catalan showInAdvancedViewOnly: TRUE adminDisplayName: Catalan name: 403 legacyExchangeDN: /o=${FIRSTORG}/CN=Configuration/CN=Addressing/CN=Address-Templates/CN=403 objectCategory: CN=Container,${SCHEMADN} msExchTemplateRDNs: EX msExchTemplateRDNs: SMTP msExchTemplateRDNs: CCMAIL msExchTemplateRDNs: MSA msExchTemplateRDNs: MS msExchTemplateRDNs: x400 # # Chinese Traditional Address-Templates # dn: CN=404,CN=Address-Templates,CN=Addressing,${FIRSTORGDN} objectClass: top objectClass: container cn: 404 distinguishedName: CN=404,CN=Address-Templates,CN=Addressing,${FIRSTORGDN} instanceType: 4 displayName: Chinese Traditional showInAdvancedViewOnly: TRUE adminDisplayName: Chinese Traditional name: 404 legacyExchangeDN: /o=${FIRSTORG}/CN=Configuration/CN=Addressing/CN=Address-Templates/CN=404 objectCategory: CN=Container,${SCHEMADN} msExchTemplateRDNs: EX msExchTemplateRDNs: SMTP msExchTemplateRDNs: CCMAIL msExchTemplateRDNs: MSA msExchTemplateRDNs: MS msExchTemplateRDNs: x400 # # Czech Address-Templates # dn: CN=405,CN=Address-Templates,CN=Addressing,${FIRSTORGDN} objectClass: top objectClass: container cn: 405 distinguishedName: CN=405,CN=Address-Templates,CN=Addressing,${FIRSTORGDN} instanceType: 4 displayName: Czech showInAdvancedViewOnly: TRUE adminDisplayName: Czech name: 405 legacyExchangeDN: /o=${FIRSTORG}/CN=Configuration/CN=Addressing/CN=Address-Templates/CN=405 objectCategory: CN=Container,${SCHEMADN} msExchTemplateRDNs: EX msExchTemplateRDNs: SMTP msExchTemplateRDNs: CCMAIL msExchTemplateRDNs: MSA msExchTemplateRDNs: MS msExchTemplateRDNs: x400 # # Danish Address-Templates # dn: CN=406,CN=Address-Templates,CN=Addressing,${FIRSTORGDN} objectClass: top objectClass: container cn: 406 distinguishedName: CN=406,CN=Address-Templates,CN=Addressing,${FIRSTORGDN} instanceType: 4 displayName: Danish showInAdvancedViewOnly: TRUE adminDisplayName: Danish name: 406 legacyExchangeDN: /o=${FIRSTORG}/CN=Configuration/CN=Addressing/CN=Address-Templates/CN=406 objectCategory: CN=Container,${SCHEMADN} msExchTemplateRDNs: EX msExchTemplateRDNs: SMTP msExchTemplateRDNs: CCMAIL msExchTemplateRDNs: MSA msExchTemplateRDNs: MS msExchTemplateRDNs: x400 # # German Address-Templates # dn: CN=407,CN=Address-Templates,CN=Addressing,${FIRSTORGDN} objectClass: top objectClass: container cn: 407 distinguishedName: CN=407,CN=Address-Templates,CN=Addressing,${FIRSTORGDN} instanceType: 4 displayName: German showInAdvancedViewOnly: TRUE adminDisplayName: German name: 407 legacyExchangeDN: /o=${FIRSTORG}/CN=Configuration/CN=Addressing/CN=Address-Templates/CN=407 objectCategory: CN=Container,${SCHEMADN} msExchTemplateRDNs: EX msExchTemplateRDNs: SMTP msExchTemplateRDNs: CCMAIL msExchTemplateRDNs: MSA msExchTemplateRDNs: MS msExchTemplateRDNs: x400 # # Greek Address-Templates # dn: CN=408,CN=Address-Templates,CN=Addressing,${FIRSTORGDN} objectClass: top objectClass: container cn: 408 distinguishedName: CN=408,CN=Address-Templates,CN=Addressing,${FIRSTORGDN} instanceType: 4 displayName: Greek showInAdvancedViewOnly: TRUE adminDisplayName: Greek name: 408 legacyExchangeDN: /o=${FIRSTORG}/CN=Configuration/CN=Addressing/CN=Address-Templates/CN=408 objectCategory: CN=Container,${SCHEMADN} msExchTemplateRDNs: EX msExchTemplateRDNs: SMTP msExchTemplateRDNs: CCMAIL msExchTemplateRDNs: MSA msExchTemplateRDNs: MS msExchTemplateRDNs: x400 # # English Address-Templates # dn: CN=409,CN=Address-Templates,CN=Addressing,${FIRSTORGDN} objectClass: top objectClass: container cn: 409 distinguishedName: CN=409,CN=Address-Templates,CN=Addressing,${FIRSTORGDN} instanceType: 4 displayName: English showInAdvancedViewOnly: TRUE adminDisplayName: English name: 409 legacyExchangeDN: /o=${FIRSTORG}/CN=Configuration/CN=Addressing/CN=Address-Templates/CN=409 objectCategory: CN=Container,${SCHEMADN} msExchTemplateRDNs: EX msExchTemplateRDNs: SMTP msExchTemplateRDNs: CCMAIL msExchTemplateRDNs: MSA msExchTemplateRDNs: MS msExchTemplateRDNs: x400 # # Finish Address-Templates # dn: CN=40b,CN=Address-Templates,CN=Addressing,${FIRSTORGDN} objectClass: top objectClass: container cn: 40b distinguishedName: CN=40b,CN=Address-Templates,CN=Addressing,${FIRSTORGDN} instanceType: 4 displayName: Finnish showInAdvancedViewOnly: TRUE adminDisplayName: Finnish name: 40b legacyExchangeDN: /o=${FIRSTORG}/CN=Configuration/CN=Addressing/CN=Address-Templates/CN=40b objectCategory: CN=Container,${SCHEMADN} msExchTemplateRDNs: EX msExchTemplateRDNs: SMTP msExchTemplateRDNs: CCMAIL msExchTemplateRDNs: MSA msExchTemplateRDNs: MS msExchTemplateRDNs: x400 # # French Address-Templates (cocorico) # dn: CN=40c,CN=Address-Templates,CN=Addressing,${FIRSTORGDN} objectClass: top objectClass: container cn: 40c distinguishedName: CN=40c,CN=Address-Templates,CN=Addressing,${FIRSTORGDN} instanceType: 4 displayName: French showInAdvancedViewOnly: TRUE adminDisplayName: French name: 40c legacyExchangeDN: /o=${FIRSTORG}/CN=Configuration/CN=Addressing/CN=Address-Templates/CN=40c objectCategory: CN=Container,${SCHEMADN} msExchTemplateRDNs: EX msExchTemplateRDNs: SMTP msExchTemplateRDNs: CCMAIL msExchTemplateRDNs: MSA msExchTemplateRDNs: MS msExchTemplateRDNs: x400 # # French (Canada) Address-Templates # dn: CN=c0c,CN=Address-Templates,CN=Addressing,${FIRSTORGDN} objectClass: top objectClass: container cn: c0c distinguishedName: CN=c0c,CN=Address-Templates,CN=Addressing,${FIRSTORGDN} instanceType: 4 displayName: French showInAdvancedViewOnly: TRUE adminDisplayName: French (Canada) name: c0c legacyExchangeDN: /o=${FIRSTORG}/CN=Configuration/CN=Addressing/CN=Address-Templates/CN=c0c objectCategory: CN=Container,${SCHEMADN} msExchTemplateRDNs: EX msExchTemplateRDNs: SMTP msExchTemplateRDNs: CCMAIL msExchTemplateRDNs: MSA msExchTemplateRDNs: MS msExchTemplateRDNs: x400 # # Hebrew Address-Templates # dn: CN=40d,CN=Address-Templates,CN=Addressing,${FIRSTORGDN} objectClass: top objectClass: container cn: 40d distinguishedName: CN=40d,CN=Address-Templates,CN=Addressing,${FIRSTORGDN} instanceType: 4 displayName: Hebrew showInAdvancedViewOnly: TRUE adminDisplayName: Hebrew name: 40d legacyExchangeDN: /o=${FIRSTORG}/CN=Configuration/CN=Addressing/CN=Address-Templates/CN=40d objectCategory: CN=Container,${SCHEMADN} msExchTemplateRDNs: EX msExchTemplateRDNs: SMTP msExchTemplateRDNs: CCMAIL msExchTemplateRDNs: MSA msExchTemplateRDNs: MS msExchTemplateRDNs: x400 # # Hungarian Address-Templates # dn: CN=40e,CN=Address-Templates,CN=Addressing,${FIRSTORGDN} objectClass: top objectClass: container cn: 40e distinguishedName: CN=40e,CN=Address-Templates,CN=Addressing,${FIRSTORGDN} instanceType: 4 displayName: Hungarian showInAdvancedViewOnly: TRUE adminDisplayName: Hungarian name: 40e legacyExchangeDN: /o=${FIRSTORG}/CN=Configuration/CN=Addressing/CN=Address-Templates/CN=40e objectCategory: CN=Container,${SCHEMADN} msExchTemplateRDNs: EX msExchTemplateRDNs: SMTP msExchTemplateRDNs: CCMAIL msExchTemplateRDNs: MSA msExchTemplateRDNs: MS msExchTemplateRDNs: x400 # # Italian Address-Templates # dn: CN=410,CN=Address-Templates,CN=Addressing,${FIRSTORGDN} objectClass: top objectClass: container cn: 410 distinguishedName: CN=410,CN=Address-Templates,CN=Addressing,${FIRSTORGDN} instanceType: 4 displayName: Italian showInAdvancedViewOnly: TRUE adminDisplayName: Italian name: 410 legacyExchangeDN: /o=${FIRSTORG}/CN=Configuration/CN=Addressing/CN=Address-Templates/CN=410 objectCategory: CN=Container,${SCHEMADN} msExchTemplateRDNs: EX msExchTemplateRDNs: SMTP msExchTemplateRDNs: CCMAIL msExchTemplateRDNs: MSA msExchTemplateRDNs: MS msExchTemplateRDNs: x400 # # Japanese Address-Templates # dn: CN=411,CN=Address-Templates,CN=Addressing,${FIRSTORGDN} objectClass: top objectClass: container cn: 411 distinguishedName: CN=411,CN=Address-Templates,CN=Addressing,${FIRSTORGDN} instanceType: 4 displayName: Japanese showInAdvancedViewOnly: TRUE adminDisplayName: Japanese name: 411 legacyExchangeDN: /o=${FIRSTORG}/CN=Configuration/CN=Addressing/CN=Address-Templates/CN=411 objectCategory: CN=Container,${SCHEMADN} msExchTemplateRDNs: EX msExchTemplateRDNs: SMTP msExchTemplateRDNs: CCMAIL msExchTemplateRDNs: MSA msExchTemplateRDNs: MS msExchTemplateRDNs: x400 # # Korean Address-Templates # dn: CN=412,CN=Address-Templates,CN=Addressing,${FIRSTORGDN} objectClass: top objectClass: container cn: 412 distinguishedName: CN=412,CN=Address-Templates,CN=Addressing,${FIRSTORGDN} instanceType: 4 displayName: Korean showInAdvancedViewOnly: TRUE adminDisplayName: Korean name: 412 legacyExchangeDN: /o=${FIRSTORG}/CN=Configuration/CN=Addressing/CN=Address-Templates/CN=412 objectCategory: CN=Container,${SCHEMADN} msExchTemplateRDNs: EX msExchTemplateRDNs: SMTP msExchTemplateRDNs: CCMAIL msExchTemplateRDNs: MSA msExchTemplateRDNs: MS msExchTemplateRDNs: x400 # # Dutch Address-Templates # dn: CN=413,CN=Address-Templates,CN=Addressing,${FIRSTORGDN} objectClass: top objectClass: container cn: 413 distinguishedName: CN=413,CN=Address-Templates,CN=Addressing,${FIRSTORGDN} instanceType: 4 displayName: Dutch showInAdvancedViewOnly: TRUE adminDisplayName: Dutch name: 413 legacyExchangeDN: /o=${FIRSTORG}/CN=Configuration/CN=Addressing/CN=Address-Templates/CN=413 objectCategory: CN=Container,${SCHEMADN} msExchTemplateRDNs: EX msExchTemplateRDNs: SMTP msExchTemplateRDNs: CCMAIL msExchTemplateRDNs: MSA msExchTemplateRDNs: MS msExchTemplateRDNs: x400 # # Norwegian Address-Templates # dn: CN=414,CN=Address-Templates,CN=Addressing,${FIRSTORGDN} objectClass: top objectClass: container cn: 414 distinguishedName: CN=414,CN=Address-Templates,CN=Addressing,${FIRSTORGDN} instanceType: 4 displayName: Norwegian showInAdvancedViewOnly: TRUE adminDisplayName: Norwegian name: 414 legacyExchangeDN: /o=${FIRSTORG}/CN=Configuration/CN=Addressing/CN=Address-Templates/CN=414 objectCategory: CN=Container,${SCHEMADN} msExchTemplateRDNs: EX msExchTemplateRDNs: SMTP msExchTemplateRDNs: CCMAIL msExchTemplateRDNs: MSA msExchTemplateRDNs: MS msExchTemplateRDNs: x400 # # Polish Address-Templates # dn: CN=415,CN=Address-Templates,CN=Addressing,${FIRSTORGDN} objectClass: top objectClass: container cn: 415 distinguishedName: CN=415,CN=Address-Templates,CN=Addressing,${FIRSTORGDN} instanceType: 4 displayName: Polish showInAdvancedViewOnly: TRUE adminDisplayName: Polish name: 415 legacyExchangeDN: /o=${FIRSTORG}/CN=Configuration/CN=Addressing/CN=Address-Templates/CN=415 objectCategory: CN=Container,${SCHEMADN} msExchTemplateRDNs: EX msExchTemplateRDNs: SMTP msExchTemplateRDNs: CCMAIL msExchTemplateRDNs: MSA msExchTemplateRDNs: MS msExchTemplateRDNs: x400 # # Brazilian Address-Templates (Samba) # dn: CN=416,CN=Address-Templates,CN=Addressing,${FIRSTORGDN} objectClass: top objectClass: container cn: 416 distinguishedName: CN=416,CN=Address-Templates,CN=Addressing,${FIRSTORGDN} instanceType: 4 displayName: Brazilian showInAdvancedViewOnly: TRUE adminDisplayName: Brazilian name: 416 legacyExchangeDN: /o=${FIRSTORG}/CN=Configuration/CN=Addressing/CN=Address-Templates/CN=416 objectCategory: CN=Container,${SCHEMADN} msExchTemplateRDNs: EX msExchTemplateRDNs: SMTP msExchTemplateRDNs: CCMAIL msExchTemplateRDNs: MSA msExchTemplateRDNs: MS msExchTemplateRDNs: x400 # # Romanian Address-Templates # dn: CN=418,CN=Address-Templates,CN=Addressing,${FIRSTORGDN} objectClass: top objectClass: container cn: 418 distinguishedName: CN=418,CN=Address-Templates,CN=Addressing,${FIRSTORGDN} instanceType: 4 displayName: Romanian showInAdvancedViewOnly: TRUE adminDisplayName: Romanian name: 418 legacyExchangeDN: /o=${FIRSTORG}/CN=Configuration/CN=Addressing/CN=Address-Templates/CN=418 objectCategory: CN=Container,${SCHEMADN} msExchTemplateRDNs: EX msExchTemplateRDNs: SMTP msExchTemplateRDNs: CCMAIL msExchTemplateRDNs: MSA msExchTemplateRDNs: MS msExchTemplateRDNs: x400 # # Russian Address-Templates # dn: CN=419,CN=Address-Templates,CN=Addressing,${FIRSTORGDN} objectClass: top objectClass: container cn: 419 distinguishedName: CN=419,CN=Address-Templates,CN=Addressing,${FIRSTORGDN} instanceType: 4 displayName: Russian showInAdvancedViewOnly: TRUE adminDisplayName: Russian name: 419 legacyExchangeDN: /o=${FIRSTORG}/CN=Configuration/CN=Addressing/CN=Address-Templates/CN=419 objectCategory: CN=Container,${SCHEMADN} msExchTemplateRDNs: EX msExchTemplateRDNs: SMTP msExchTemplateRDNs: CCMAIL msExchTemplateRDNs: MSA msExchTemplateRDNs: MS msExchTemplateRDNs: x400 # # Croatian Address-Templates # dn: CN=41a,CN=Address-Templates,CN=Addressing,${FIRSTORGDN} objectClass: top objectClass: container cn: 41a distinguishedName: CN=41a,CN=Address-Templates,CN=Addressing,${FIRSTORGDN} instanceType: 4 displayName: Croatian showInAdvancedViewOnly: TRUE adminDisplayName: Croatian name: 41a legacyExchangeDN: /o=${FIRSTORG}/CN=Configuration/CN=Addressing/CN=Address-Templates/CN=41a objectCategory: CN=Container,${SCHEMADN} msExchTemplateRDNs: EX msExchTemplateRDNs: SMTP msExchTemplateRDNs: CCMAIL msExchTemplateRDNs: MSA msExchTemplateRDNs: MS msExchTemplateRDNs: x400 # # Slovak Address-Templates # dn: CN=41b,CN=Address-Templates,CN=Addressing,${FIRSTORGDN} objectClass: top objectClass: container cn: 41b distinguishedName: CN=41b,CN=Address-Templates,CN=Addressing,${FIRSTORGDN} instanceType: 4 displayName: Slovak showInAdvancedViewOnly: TRUE adminDisplayName: Slovak name: 41b legacyExchangeDN: /o=${FIRSTORG}/CN=Configuration/CN=Addressing/CN=Address-Templates/CN=41b objectCategory: CN=Container,${SCHEMADN} msExchTemplateRDNs: EX msExchTemplateRDNs: SMTP msExchTemplateRDNs: CCMAIL msExchTemplateRDNs: MSA msExchTemplateRDNs: MS msExchTemplateRDNs: x400 # # Swedish Address-Templates # dn: CN=41d,CN=Address-Templates,CN=Addressing,${FIRSTORGDN} objectClass: top objectClass: container cn: 41d distinguishedName: CN=41d,CN=Address-Templates,CN=Addressing,${FIRSTORGDN} instanceType: 4 displayName: Swedish showInAdvancedViewOnly: TRUE adminDisplayName: Swedish name: 41d legacyExchangeDN: /o=${FIRSTORG}/CN=Configuration/CN=Addressing/CN=Address-Templates/CN=41d objectCategory: CN=Container,${SCHEMADN} msExchTemplateRDNs: EX msExchTemplateRDNs: SMTP msExchTemplateRDNs: CCMAIL msExchTemplateRDNs: MSA msExchTemplateRDNs: MS msExchTemplateRDNs: x400 # # Thai Address-Templates # dn: CN=41e,CN=Address-Templates,CN=Addressing,${FIRSTORGDN} objectClass: top objectClass: container cn: 41e distinguishedName: CN=41e,CN=Address-Templates,CN=Addressing,${FIRSTORGDN} instanceType: 4 displayName: Thai showInAdvancedViewOnly: TRUE adminDisplayName: Thai name: 41e legacyExchangeDN: /o=${FIRSTORG}/CN=Configuration/CN=Addressing/CN=Address-Templates/CN=41e objectCategory: CN=Container,${SCHEMADN} msExchTemplateRDNs: EX msExchTemplateRDNs: SMTP msExchTemplateRDNs: CCMAIL msExchTemplateRDNs: MSA msExchTemplateRDNs: MS msExchTemplateRDNs: x400 # # Turkish Address-Templates # dn: CN=41f,CN=Address-Templates,CN=Addressing,${FIRSTORGDN} objectClass: top objectClass: container cn: 41f distinguishedName: CN=41f,CN=Address-Templates,CN=Addressing,${FIRSTORGDN} instanceType: 4 displayName: Turkish showInAdvancedViewOnly: TRUE adminDisplayName: Turkish name: 41f legacyExchangeDN: /o=${FIRSTORG}/CN=Configuration/CN=Addressing/CN=Address-Templates/CN=41f objectCategory: CN=Container,${SCHEMADN} msExchTemplateRDNs: EX msExchTemplateRDNs: SMTP msExchTemplateRDNs: CCMAIL msExchTemplateRDNs: MSA msExchTemplateRDNs: MS msExchTemplateRDNs: x400 # # Ukrainian Address-Templates # dn: CN=422,CN=Address-Templates,CN=Addressing,${FIRSTORGDN} objectClass: top objectClass: container cn: 422 distinguishedName: CN=422,CN=Address-Templates,CN=Addressing,${FIRSTORGDN} instanceType: 4 displayName: Ukrainian showInAdvancedViewOnly: TRUE adminDisplayName: Ukrainian name: 422 legacyExchangeDN: /o=${FIRSTORG}/CN=Configuration/CN=Addressing/CN=Address-Templates/CN=422 objectCategory: CN=Container,${SCHEMADN} msExchTemplateRDNs: EX msExchTemplateRDNs: SMTP msExchTemplateRDNs: CCMAIL msExchTemplateRDNs: MSA msExchTemplateRDNs: MS msExchTemplateRDNs: x400 # # Slovenian Address-Templates # dn: CN=424,CN=Address-Templates,CN=Addressing,${FIRSTORGDN} objectClass: top objectClass: container cn: 424 distinguishedName: CN=424,CN=Address-Templates,CN=Addressing,${FIRSTORGDN} instanceType: 4 displayName: Slovenian showInAdvancedViewOnly: TRUE adminDisplayName: Slovenian name: 424 legacyExchangeDN: /o=${FIRSTORG}/CN=Configuration/CN=Addressing/CN=Address-Templates/CN=424 objectCategory: CN=Container,${SCHEMADN} msExchTemplateRDNs: EX msExchTemplateRDNs: SMTP msExchTemplateRDNs: CCMAIL msExchTemplateRDNs: MSA msExchTemplateRDNs: MS msExchTemplateRDNs: x400 # # Estonian Address-Templates # dn: CN=425,CN=Address-Templates,CN=Addressing,${FIRSTORGDN} objectClass: top objectClass: container cn: 425 distinguishedName: CN=425,CN=Address-Templates,CN=Addressing,${FIRSTORGDN} instanceType: 4 displayName: Estonian showInAdvancedViewOnly: TRUE adminDisplayName: Estonian name: 425 legacyExchangeDN: /o=${FIRSTORG}/CN=Configuration/CN=Addressing/CN=Address-Templates/CN=425 objectCategory: CN=Container,${SCHEMADN} msExchTemplateRDNs: EX msExchTemplateRDNs: SMTP msExchTemplateRDNs: CCMAIL msExchTemplateRDNs: MSA msExchTemplateRDNs: MS msExchTemplateRDNs: x400 # # Latvian Address-Templates # dn: CN=426,CN=Address-Templates,CN=Addressing,${FIRSTORGDN} objectClass: top objectClass: container cn: 426 distinguishedName: CN=426,CN=Address-Templates,CN=Addressing,${FIRSTORGDN} instanceType: 4 displayName: Latvian showInAdvancedViewOnly: TRUE adminDisplayName: Latvian name: 426 legacyExchangeDN: /o=${FIRSTORG}/CN=Configuration/CN=Addressing/CN=Address-Templates/CN=426 objectCategory: CN=Container,${SCHEMADN} msExchTemplateRDNs: EX msExchTemplateRDNs: SMTP msExchTemplateRDNs: CCMAIL msExchTemplateRDNs: MSA msExchTemplateRDNs: MS msExchTemplateRDNs: x400 # # Lithuanian Address-Templates # dn: CN=427,CN=Address-Templates,CN=Addressing,${FIRSTORGDN} objectClass: top objectClass: container cn: 427 distinguishedName: CN=427,CN=Address-Templates,CN=Addressing,${FIRSTORGDN} instanceType: 4 displayName: Lithuanian showInAdvancedViewOnly: TRUE adminDisplayName: Lithuanian name: 427 legacyExchangeDN: /o=${FIRSTORG}/CN=Configuration/CN=Addressing/CN=Address-Templates/CN=427 objectCategory: CN=Container,${SCHEMADN} msExchTemplateRDNs: EX msExchTemplateRDNs: SMTP msExchTemplateRDNs: CCMAIL msExchTemplateRDNs: MSA msExchTemplateRDNs: MS msExchTemplateRDNs: x400 # # Basque Address-Templates # dn: CN=42d,CN=Address-Templates,CN=Addressing,${FIRSTORGDN} objectClass: top objectClass: container cn: 42d distinguishedName: CN=42d,CN=Address-Templates,CN=Addressing,${FIRSTORGDN} instanceType: 4 displayName: Basque showInAdvancedViewOnly: TRUE adminDisplayName: Basque name: 42d legacyExchangeDN: /o=${FIRSTORG}/CN=Configuration/CN=Addressing/CN=Address-Templates/CN=42d objectCategory: CN=Container,${SCHEMADN} msExchTemplateRDNs: EX msExchTemplateRDNs: SMTP msExchTemplateRDNs: CCMAIL msExchTemplateRDNs: MSA msExchTemplateRDNs: MS msExchTemplateRDNs: x400 # # Chinese Simplified Address-Templates # dn: CN=804,CN=Address-Templates,CN=Addressing,${FIRSTORGDN} objectClass: top objectClass: container cn: 804 distinguishedName: CN=804,CN=Address-Templates,CN=Addressing,${FIRSTORGDN} instanceType: 4 displayName: Chinese Simplified showInAdvancedViewOnly: TRUE adminDisplayName: Chinese Simplified name: 804 legacyExchangeDN: /o=${FIRSTORG}/CN=Configuration/CN=Addressing/CN=Address-Templates/CN=804 objectCategory: CN=Container,${SCHEMADN} msExchTemplateRDNs: EX msExchTemplateRDNs: SMTP msExchTemplateRDNs: CCMAIL msExchTemplateRDNs: MSA msExchTemplateRDNs: MS msExchTemplateRDNs: x400 # # Portuguese Address-Templates # dn: CN=816,CN=Address-Templates,CN=Addressing,${FIRSTORGDN} objectClass: top objectClass: container cn: 816 distinguishedName: CN=816,CN=Address-Templates,CN=Addressing,${FIRSTORGDN} instanceType: 4 displayName: Portuguese showInAdvancedViewOnly: TRUE adminDisplayName: Portuguese name: 816 legacyExchangeDN: /o=${FIRSTORG}/CN=Configuration/CN=Addressing/CN=Address-Templates/CN=816 objectCategory: CN=Container,${SCHEMADN} msExchTemplateRDNs: EX msExchTemplateRDNs: SMTP msExchTemplateRDNs: CCMAIL msExchTemplateRDNs: MSA msExchTemplateRDNs: MS msExchTemplateRDNs: x400 # # Serbian Address-Templates # dn: CN=81A,CN=Address-Templates,CN=Addressing,${FIRSTORGDN} objectClass: top objectClass: container cn: 81A distinguishedName: CN=81A,CN=Address-Templates,CN=Addressing,${FIRSTORGDN} instanceType: 4 displayName: Serbian showInAdvancedViewOnly: TRUE adminDisplayName: Serbian name: 81A legacyExchangeDN: /o=${FIRSTORG}/CN=Configuration/CN=Addressing/CN=Address-Templates/CN=81A objectCategory: CN=Container,${SCHEMADN} msExchTemplateRDNs: EX msExchTemplateRDNs: SMTP msExchTemplateRDNs: CCMAIL msExchTemplateRDNs: MSA msExchTemplateRDNs: MS msExchTemplateRDNs: x400 # # Spanish Address-Templates # dn: CN=C0A,CN=Address-Templates,CN=Addressing,${FIRSTORGDN} objectClass: top objectClass: container cn: C0A distinguishedName: CN=C0A,CN=Address-Templates,CN=Addressing,${FIRSTORGDN} instanceType: 4 displayName: Spanish showInAdvancedViewOnly: TRUE adminDisplayName: Spanish name: C0A legacyExchangeDN: /o=${FIRSTORG}/CN=Configuration/CN=Addressing/CN=Address-Templates/CN=C0A objectCategory: CN=Container,${SCHEMADN} msExchTemplateRDNs: EX msExchTemplateRDNs: SMTP msExchTemplateRDNs: CCMAIL msExchTemplateRDNs: MSA msExchTemplateRDNs: MS msExchTemplateRDNs: x400 # # Arabic Display-Templates # dn: CN=401,CN=Display-Templates,CN=Addressing,${FIRSTORGDN} objectClass: top objectClass: container cn: 401 distinguishedName: CN=401,CN=Display-Templates,CN=Addressing,${FIRSTORGDN} instanceType: 4 displayName: Arabic showInAdvancedViewOnly: TRUE adminDisplayName: Arabic name: 401 legacyExchangeDN: /o=${FIRSTORG}/CN=Configuration/CN=Addressing/CN=Display-Templates/CN=401 objectCategory: CN=Container,${SCHEMADN} # # Bulgarian Display-Templates # dn: CN=402,CN=Display-Templates,CN=Addressing,${FIRSTORGDN} objectClass: top objectClass: container cn: 402 distinguishedName: CN=402,CN=Display-Templates,CN=Addressing,${FIRSTORGDN} instanceType: 4 displayName: Bulgarian showInAdvancedViewOnly: TRUE adminDisplayName: Bulgarian name: 402 legacyExchangeDN: /o=${FIRSTORG}/CN=Configuration/CN=Addressing/CN=Display-Templates/CN=402 objectCategory: CN=Container,${SCHEMADN} # # Catalan Display-Templates # dn: CN=403,CN=Display-Templates,CN=Addressing,${FIRSTORGDN} objectClass: top objectClass: container cn: 403 distinguishedName: CN=403,CN=Display-Templates,CN=Addressing,${FIRSTORGDN} instanceType: 4 displayName: Catalan showInAdvancedViewOnly: TRUE adminDisplayName: Catalan name: 403 legacyExchangeDN: /o=${FIRSTORG}/CN=Configuration/CN=Addressing/CN=Display-Templates/CN=403 objectCategory: CN=Container,${SCHEMADN} # # Chinese Traditional Display-Templates # dn: CN=404,CN=Display-Templates,CN=Addressing,${FIRSTORGDN} objectClass: top objectClass: container cn: 404 distinguishedName: CN=404,CN=Display-Templates,CN=Addressing,${FIRSTORGDN} instanceType: 4 displayName: Chinese Traditional showInAdvancedViewOnly: TRUE adminDisplayName: Chinese Traditional name: 404 legacyExchangeDN: /o=${FIRSTORG}/CN=Configuration/CN=Addressing/CN=Display-Templates/CN=404 objectCategory: CN=Container,${SCHEMADN} # # Czech Display-Templates # dn: CN=405,CN=Display-Templates,CN=Addressing,${FIRSTORGDN} objectClass: top objectClass: container cn: 405 distinguishedName: CN=405,CN=Display-Templates,CN=Addressing,${FIRSTORGDN} instanceType: 4 displayName: Czech showInAdvancedViewOnly: TRUE adminDisplayName: Czech name: 405 legacyExchangeDN: /o=${FIRSTORG}/CN=Configuration/CN=Addressing/CN=Display-Templates/CN=405 objectCategory: CN=Container,${SCHEMADN} # # Danish Display-Templates # dn: CN=406,CN=Display-Templates,CN=Addressing,${FIRSTORGDN} objectClass: top objectClass: container cn: 406 distinguishedName: CN=406,CN=Display-Templates,CN=Addressing,${FIRSTORGDN} instanceType: 4 displayName: Danish showInAdvancedViewOnly: TRUE adminDisplayName: Danish name: 406 legacyExchangeDN: /o=${FIRSTORG}/CN=Configuration/CN=Addressing/CN=Display-Templates/CN=406 objectCategory: CN=Container,${SCHEMADN} # # German Display-Templtes # dn: CN=407,CN=Display-Templates,CN=Addressing,${FIRSTORGDN} objectClass: top objectClass: container cn: 407 distinguishedName: CN=407,CN=Display-Templates,CN=Addressing,${FIRSTORGDN} instanceType: 4 displayName: German showInAdvancedViewOnly: TRUE adminDisplayName: German name: 407 legacyExchangeDN: /o=${FIRSTORG}/CN=Configuration/CN=Addressing/CN=Display-Templates/CN=407 objectCategory: CN=Container,${SCHEMADN} # # Greek Display-Templates # dn: CN=408,CN=Display-Templates,CN=Addressing,${FIRSTORGDN} objectClass: top objectClass: container cn: 408 distinguishedName: CN=408,CN=Display-Templates,CN=Addressing,${FIRSTORGDN} instanceType: 4 displayName: Greek showInAdvancedViewOnly: TRUE adminDisplayName: Greek name: 408 legacyExchangeDN: /o=${FIRSTORG}/CN=Configuration/CN=Addressing/CN=Display-Templates/CN=408 objectCategory: CN=Container,${SCHEMADN} # # English Display-Templates # dn: CN=409,CN=Display-Templates,CN=Addressing,${FIRSTORGDN} objectClass: top objectClass: container cn: 409 distinguishedName: CN=409,CN=Display-Templates,CN=Addressing,${FIRSTORGDN} instanceType: 4 displayName: English showInAdvancedViewOnly: TRUE adminDisplayName: English name: 409 legacyExchangeDN: /o=${FIRSTORG}/CN=Configuration/CN=Addressing/CN=Display-Templates/CN=409 objectCategory: CN=Container,${SCHEMADN} # # Finish Display-Templates # dn: CN=40b,CN=Display-Templates,CN=Addressing,${FIRSTORGDN} objectClass: top objectClass: container cn: 40b distinguishedName: CN=40b,CN=Display-Templates,CN=Addressing,${FIRSTORGDN} instanceType: 4 displayName: Finnish showInAdvancedViewOnly: TRUE adminDisplayName: Finnish name: 40b legacyExchangeDN: /o=${FIRSTORG}/CN=Configuration/CN=Addressing/CN=Display-Templates/CN=40b objectCategory: CN=Container,${SCHEMADN} # # French Display-Templates (cocorico) # dn: CN=40c,CN=Display-Templates,CN=Addressing,${FIRSTORGDN} objectClass: top objectClass: container cn: 40c distinguishedName: CN=40c,CN=Display-Templates,CN=Addressing,${FIRSTORGDN} instanceType: 4 displayName: French showInAdvancedViewOnly: TRUE adminDisplayName: French name: 40c legacyExchangeDN: /o=${FIRSTORG}/CN=Configuration/CN=Addressing/CN=Display-Templates/CN=40c objectCategory: CN=Container,${SCHEMADN} # # French (Canada) Display-Templates (cocorico) # dn: CN=c0c,CN=Display-Templates,CN=Addressing,${FIRSTORGDN} objectClass: top objectClass: container cn: c0c distinguishedName: CN=c0c,CN=Display-Templates,CN=Addressing,${FIRSTORGDN} instanceType: 4 displayName: French (Canada) showInAdvancedViewOnly: TRUE adminDisplayName: French (Canada) name: c0c legacyExchangeDN: /o=${FIRSTORG}/CN=Configuration/CN=Addressing/CN=Display-Templates/CN=c0c objectCategory: CN=Container,${SCHEMADN} # # Hebrew Display-Templates # dn: CN=40d,CN=Display-Templates,CN=Addressing,${FIRSTORGDN} objectClass: top objectClass: container cn: 40d distinguishedName: CN=40d,CN=Display-Templates,CN=Addressing,${FIRSTORGDN} instanceType: 4 displayName: Hebrew showInAdvancedViewOnly: TRUE adminDisplayName: Hebrew name: 40d legacyExchangeDN: /o=${FIRSTORG}/CN=Configuration/CN=Addressing/CN=Display-Templates/CN=40d objectCategory: CN=Container,${SCHEMADN} # # Hungarian Display-Templates # dn: CN=40e,CN=Display-Templates,CN=Addressing,${FIRSTORGDN} objectClass: top objectClass: container cn: 40e distinguishedName: CN=40e,CN=Display-Templates,CN=Addressing,${FIRSTORGDN} instanceType: 4 displayName: Hungarian showInAdvancedViewOnly: TRUE adminDisplayName: Hungarian name: 40e legacyExchangeDN: /o=${FIRSTORG}/CN=Configuration/CN=Addressing/CN=Display-Templates/CN=40e objectCategory: CN=Container,${SCHEMADN} # # Italian Display-Templates # dn: CN=410,CN=Display-Templates,CN=Addressing,${FIRSTORGDN} objectClass: top objectClass: container cn: 410 distinguishedName: CN=410,CN=Display-Templates,CN=Addressing,${FIRSTORGDN} instanceType: 4 displayName: Italian showInAdvancedViewOnly: TRUE adminDisplayName: Italian name: 410 legacyExchangeDN: /o=${FIRSTORG}/CN=Configuration/CN=Addressing/CN=Display-Templates/CN=410 objectCategory: CN=Container,${SCHEMADN} # # Japanese Display-Templates # dn: CN=411,CN=Display-Templates,CN=Addressing,${FIRSTORGDN} objectClass: top objectClass: container cn: 411 distinguishedName: CN=411,CN=Display-Templates,CN=Addressing,${FIRSTORGDN} instanceType: 4 displayName: Japanese showInAdvancedViewOnly: TRUE adminDisplayName: Japanese name: 411 legacyExchangeDN: /o=${FIRSTORG}/CN=Configuration/CN=Addressing/CN=Display-Templates/CN=411 objectCategory: CN=Container,${SCHEMADN} # # Korean Display-Templates # dn: CN=412,CN=Display-Templates,CN=Addressing,${FIRSTORGDN} objectClass: top objectClass: container cn: 412 distinguishedName: CN=412,CN=Display-Templates,CN=Addressing,${FIRSTORGDN} instanceType: 4 displayName: Korean showInAdvancedViewOnly: TRUE adminDisplayName: Korean name: 412 legacyExchangeDN: /o=${FIRSTORG}/CN=Configuration/CN=Addressing/CN=Display-Templates/CN=412 objectCategory: CN=Container,${SCHEMADN} # # Dutch Display-Templates # dn: CN=413,CN=Display-Templates,CN=Addressing,${FIRSTORGDN} objectClass: top objectClass: container cn: 413 distinguishedName: CN=413,CN=Display-Templates,CN=Addressing,${FIRSTORGDN} instanceType: 4 displayName: Dutch showInAdvancedViewOnly: TRUE adminDisplayName: Dutch name: 413 legacyExchangeDN: /o=${FIRSTORG}/CN=Configuration/CN=Addressing/CN=Display-Templates/CN=413 objectCategory: CN=Container,${SCHEMADN} # # Norwegian Display-Templates # dn: CN=414,CN=Display-Templates,CN=Addressing,${FIRSTORGDN} objectClass: top objectClass: container cn: 414 distinguishedName: CN=414,CN=Display-Templates,CN=Addressing,${FIRSTORGDN} instanceType: 4 displayName: Norwegian showInAdvancedViewOnly: TRUE adminDisplayName: Norwegian name: 414 legacyExchangeDN: /o=${FIRSTORG}/CN=Configuration/CN=Addressing/CN=Display-Templates/CN=414 objectCategory: CN=Container,${SCHEMADN} # # Polish Display-Templates # dn: CN=415,CN=Display-Templates,CN=Addressing,${FIRSTORGDN} objectClass: top objectClass: container cn: 415 distinguishedName: CN=415,CN=Display-Templates,CN=Addressing,${FIRSTORGDN} instanceType: 4 displayName: Polish showInAdvancedViewOnly: TRUE adminDisplayName: Polish name: 415 legacyExchangeDN: /o=${FIRSTORG}/CN=Configuration/CN=Addressing/CN=Display-Templates/CN=415 objectCategory: CN=Container,${SCHEMADN} # # Brazilian Display-Templates (Samba) # dn: CN=416,CN=Display-Templates,CN=Addressing,${FIRSTORGDN} objectClass: top objectClass: container cn: 416 distinguishedName: CN=416,CN=Display-Templates,CN=Addressing,${FIRSTORGDN} instanceType: 4 displayName: Brazilian showInAdvancedViewOnly: TRUE adminDisplayName: Brazilian name: 416 legacyExchangeDN: /o=${FIRSTORG}/CN=Configuration/CN=Addressing/CN=Display-Templates/CN=416 objectCategory: CN=Container,${SCHEMADN} # # Romanian Display-Templates # dn: CN=418,CN=Display-Templates,CN=Addressing,${FIRSTORGDN} objectClass: top objectClass: container cn: 418 distinguishedName: CN=418,CN=Display-Templates,CN=Addressing,${FIRSTORGDN} instanceType: 4 displayName: Romanian showInAdvancedViewOnly: TRUE adminDisplayName: Romanian name: 418 legacyExchangeDN: /o=${FIRSTORG}/CN=Configuration/CN=Addressing/CN=Display-Templates/CN=418 objectCategory: CN=Container,${SCHEMADN} # # Russian Display-Templates # dn: CN=419,CN=Display-Templates,CN=Addressing,${FIRSTORGDN} objectClass: top objectClass: container cn: 419 distinguishedName: CN=419,CN=Display-Templates,CN=Addressing,${FIRSTORGDN} instanceType: 4 displayName: Russian showInAdvancedViewOnly: TRUE adminDisplayName: Russian name: 419 legacyExchangeDN: /o=${FIRSTORG}/CN=Configuration/CN=Addressing/CN=Display-Templates/CN=419 objectCategory: CN=Container,${SCHEMADN} # # Croatian Display-Templates # dn: CN=41a,CN=Display-Templates,CN=Addressing,${FIRSTORGDN} objectClass: top objectClass: container cn: 41a distinguishedName: CN=41a,CN=Display-Templates,CN=Addressing,${FIRSTORGDN} instanceType: 4 displayName: Croatian showInAdvancedViewOnly: TRUE adminDisplayName: Croatian name: 41a legacyExchangeDN: /o=${FIRSTORG}/CN=Configuration/CN=Addressing/CN=Display-Templates/CN=41a objectCategory: CN=Container,${SCHEMADN} # # Slovak Display-Templates # dn: CN=41b,CN=Display-Templates,CN=Addressing,${FIRSTORGDN} objectClass: top objectClass: container cn: 41b distinguishedName: CN=41b,CN=Display-Templates,CN=Addressing,${FIRSTORGDN} instanceType: 4 displayName: Slovak showInAdvancedViewOnly: TRUE adminDisplayName: Slovak name: 41b legacyExchangeDN: /o=${FIRSTORG}/CN=Configuration/CN=Addressing/CN=Display-Templates/CN=41b objectCategory: CN=Container,${SCHEMADN} # # Swedish Display-Templates # dn: CN=41d,CN=Display-Templates,CN=Addressing,${FIRSTORGDN} objectClass: top objectClass: container cn: 41d distinguishedName: CN=41d,CN=Display-Templates,CN=Addressing,${FIRSTORGDN} instanceType: 4 displayName: Swedish showInAdvancedViewOnly: TRUE adminDisplayName: Swedish name: 41d legacyExchangeDN: /o=${FIRSTORG}/CN=Configuration/CN=Addressing/CN=Display-Templates/CN=41d objectCategory: CN=Container,${SCHEMADN} # # Thai Display-Templates # dn: CN=41e,CN=Display-Templates,CN=Addressing,${FIRSTORGDN} objectClass: top objectClass: container cn: 41e distinguishedName: CN=41e,CN=Display-Templates,CN=Addressing,${FIRSTORGDN} instanceType: 4 displayName: Thai showInAdvancedViewOnly: TRUE adminDisplayName: Thai name: 41e legacyExchangeDN: /o=${FIRSTORG}/CN=Configuration/CN=Addressing/CN=Display-Templates/CN=41e objectCategory: CN=Container,${SCHEMADN} # # Turkish Display-Templates # dn: CN=41f,CN=Display-Templates,CN=Addressing,${FIRSTORGDN} objectClass: top objectClass: container cn: 41f distinguishedName: CN=41f,CN=Display-Templates,CN=Addressing,${FIRSTORGDN} instanceType: 4 displayName: Turkish showInAdvancedViewOnly: TRUE adminDisplayName: Turkish name: 41f legacyExchangeDN: /o=${FIRSTORG}/CN=Configuration/CN=Addressing/CN=Display-Templates/CN=41f objectCategory: CN=Container,${SCHEMADN} # # Ukrainian Display-Templates # dn: CN=422,CN=Display-Templates,CN=Addressing,${FIRSTORGDN} objectClass: top objectClass: container cn: 422 distinguishedName: CN=422,CN=Display-Templates,CN=Addressing,${FIRSTORGDN} instanceType: 4 displayName: Ukrainian showInAdvancedViewOnly: TRUE adminDisplayName: Ukrainian name: 422 legacyExchangeDN: /o=${FIRSTORG}/CN=Configuration/CN=Addressing/CN=Display-Templates/CN=422 objectCategory: CN=Container,${SCHEMADN} # # Slovenian Display-Templates # dn: CN=424,CN=Display-Templates,CN=Addressing,${FIRSTORGDN} objectClass: top objectClass: container cn: 424 distinguishedName: CN=424,CN=Display-Templates,CN=Addressing,${FIRSTORGDN} instanceType: 4 displayName: Slovenian showInAdvancedViewOnly: TRUE adminDisplayName: Slovenian name: 424 legacyExchangeDN: /o=${FIRSTORG}/CN=Configuration/CN=Addressing/CN=Display-Templates/CN=424 objectCategory: CN=Container,${SCHEMADN} # # Estonian Display-Templates # dn: CN=425,CN=Display-Templates,CN=Addressing,${FIRSTORGDN} objectClass: top objectClass: container cn: 425 distinguishedName: CN=425,CN=Display-Templates,CN=Addressing,${FIRSTORGDN} instanceType: 4 displayName: Estonian showInAdvancedViewOnly: TRUE adminDisplayName: Estonian name: 425 legacyExchangeDN: /o=${FIRSTORG}/CN=Configuration/CN=Addressing/CN=Display-Templates/CN=425 objectCategory: CN=Container,${SCHEMADN} # # Latvian Display-Templates # dn: CN=426,CN=Display-Templates,CN=Addressing,${FIRSTORGDN} objectClass: top objectClass: container cn: 426 distinguishedName: CN=426,CN=Display-Templates,CN=Addressing,${FIRSTORGDN} instanceType: 4 displayName: Latvian showInAdvancedViewOnly: TRUE adminDisplayName: Latvian name: 426 legacyExchangeDN: /o=${FIRSTORG}/CN=Configuration/CN=Addressing/CN=Display-Templates/CN=426 objectCategory: CN=Container,${SCHEMADN} # # Lithuanian Display-Templates # dn: CN=427,CN=Display-Templates,CN=Addressing,${FIRSTORGDN} objectClass: top objectClass: container cn: 427 distinguishedName: CN=427,CN=Display-Templates,CN=Addressing,${FIRSTORGDN} instanceType: 4 displayName: Lithuanian showInAdvancedViewOnly: TRUE adminDisplayName: Lithuanian name: 427 legacyExchangeDN: /o=${FIRSTORG}/CN=Configuration/CN=Addressing/CN=Display-Templates/CN=427 objectCategory: CN=Container,${SCHEMADN} # # Basque Display-Templates # dn: CN=42d,CN=Display-Templates,CN=Addressing,${FIRSTORGDN} objectClass: top objectClass: container cn: 42d distinguishedName: CN=42d,CN=Display-Templates,CN=Addressing,${FIRSTORGDN} instanceType: 4 displayName: Basque showInAdvancedViewOnly: TRUE adminDisplayName: Basque name: 42d legacyExchangeDN: /o=${FIRSTORG}/CN=Configuration/CN=Addressing/CN=Display-Templates/CN=42d objectCategory: CN=Container,${SCHEMADN} # # Chinese Simplified Display-Templates # dn: CN=804,CN=Display-Templates,CN=Addressing,${FIRSTORGDN} objectClass: top objectClass: container cn: 804 distinguishedName: CN=804,CN=Display-Templates,CN=Addressing,${FIRSTORGDN} instanceType: 4 displayName: Chinese Simplified showInAdvancedViewOnly: TRUE adminDisplayName: Chinese Simplified name: 804 legacyExchangeDN: /o=${FIRSTORG}/CN=Configuration/CN=Addressing/CN=Display-Templates/CN=804 objectCategory: CN=Container,${SCHEMADN} # # Portuguese Display-Templates # dn: CN=816,CN=Display-Templates,CN=Addressing,${FIRSTORGDN} objectClass: top objectClass: container cn: 816 distinguishedName: CN=816,CN=Display-Templates,CN=Addressing,${FIRSTORGDN} instanceType: 4 displayName: Portuguese showInAdvancedViewOnly: TRUE adminDisplayName: Portuguese name: 816 legacyExchangeDN: /o=${FIRSTORG}/CN=Configuration/CN=Addressing/CN=Display-Templates/CN=816 objectCategory: CN=Container,${SCHEMADN} # # Serbian Display-Templates # dn: CN=81A,CN=Display-Templates,CN=Addressing,${FIRSTORGDN} objectClass: top objectClass: container cn: 81A distinguishedName: CN=81A,CN=Display-Templates,CN=Addressing,${FIRSTORGDN} instanceType: 4 displayName: Serbian showInAdvancedViewOnly: TRUE adminDisplayName: Serbian name: 81A legacyExchangeDN: /o=${FIRSTORG}/CN=Configuration/CN=Addressing/CN=Display-Templates/CN=81A objectCategory: CN=Container,${SCHEMADN} # # Spanish Display-Templates # dn: CN=C0A,CN=Display-Templates,CN=Addressing,${FIRSTORGDN} objectClass: top objectClass: container cn: C0A distinguishedName: CN=C0A,CN=Display-Templates,CN=Addressing,${FIRSTORGDN} instanceType: 4 displayName: Spanish showInAdvancedViewOnly: TRUE adminDisplayName: Spanish name: C0A legacyExchangeDN: /o=${FIRSTORG}/CN=Configuration/CN=Addressing/CN=Display-Templates/CN=C0A objectCategory: CN=Container,${SCHEMADN} openchange-2.0/setup/AD/oc_provision_configuration_finalize.ldif000066400000000000000000000027721223057412600253010ustar00rootroot00000000000000 # # Finalize First Administrative Group # dn: CN=First Administrative Group,CN=Administrative Groups,${FIRSTORGDN} changetype: modify add: siteFolderServer siteFolderServer: CN=Public Folder Store (${NETBIOSNAME}),CN=First Storage Group,CN=InformationStore,CN=${NETBIOSNAME},CN=Servers,CN=First Administrative Group,CN=Administrative Groups,${FIRSTORGDN} # # Finalize root Exchange service # dn: CN=Microsoft Exchange,CN=Services,${CONFIGDN} changetype: modify add: addressBookRoots addressBookRoots: CN=All Address Lists,CN=Address Lists Container,${FIRSTORGDN} add: globalAddressList globalAddressList: CN=Default Global Address List,CN=All Global Address Lists,CN=Address Lists Container,${FIRSTORGDN} add: templateRoots templateRoots: CN=Addressing,${FIRSTORGDN} # # Finalize Mailbox Store (${NETBIOSNAME}) # dn: CN=Mailbox Store (${NETBIOSNAME}),CN=First Storage Group,CN=InformationStore,CN=${NETBIOSNAME},CN=Servers,CN=First Administrative Group,CN=Administrative Groups,${FIRSTORGDN} changetype: modify # (disabled, see previous ldif) msExchUseOAB: CN=Default Offline Address List,CN=Offline Address Lists,CN=Address Lists Container,${FIRSTORGDN} add: msExchOwningServer msExchOwningServer: CN=${NETBIOSNAME},CN=Servers,CN=First Administrative Group,CN=Administrative Groups,${FIRSTORGDN} add: msExchHomePublicMDB msExchHomePublicMDB: CN=Public Folder Store (${NETBIOSNAME}),CN=First Storage Group,CN=InformationStore,CN=${NETBIOSNAME},CN=Servers,CN=First Administrative Group,CN=Administrative Groups,${FIRSTORGDN} openchange-2.0/setup/AD/oc_provision_schema.ldif000066400000000000000000002647071223057412600220210ustar00rootroot00000000000000############################################################################## # Classes added ############################################################################## dn: CN=ms-Exch-Addressing-Policy,${SCHEMADN} objectClass: top objectClass: classSchema cn: ms-Exch-Addressing-Policy distinguishedName: CN=ms-Exch-Addressing-Policy,${SCHEMADN} possSuperiors: container subClassOf: top governsID: 1.2.840.113556.1.5.7000.62.50008 mayContain: msExchPolicyLastAppliedTime mayContain: msExchProxyGenServer mayContain: msExchPolicyLockDown mayContain: msExchPolicyListBL mayContain: msExchPolicyDefault mayContain: gatewayProxy mayContain: disabledGatewayProxy mayContain: msExchAliasGenUniqueness mayContain: msExchAliasGenType mayContain: msExchAliasGenFormat rDNAttID: cn uSNChanged: 16956 showInAdvancedViewOnly: TRUE adminDisplayName: ms-Exch-Addressing-Policy adminDescription: ms-Exch-Addressing-Policy auxiliaryClass: msExchBaseClass objectClassCategory: 1 lDAPDisplayName: msExchAddressingPolicy name: ms-Exch-Addressing-Policy schemaIDGUID: e7211f02-a980-11d2-a9ff-00c04f8eedd8 systemOnly: FALSE defaultSecurityDescriptor: D:S: defaultHidingValue: TRUE objectCategory: CN=Class-Schema,${SCHEMADN} defaultObjectCategory: CN=ms-Exch-Addressing-Policy,${SCHEMADN} # # ms-Exch-Address-List-Service # Domain-wide configuration object for the Address List Service. # dn: CN=ms-Exch-Address-List-Service,${SCHEMADN} objectClass: top objectClass: classSchema cn: ms-Exch-Address-List-Service distinguishedName: CN=ms-Exch-Address-List-Service,${SCHEMADN} possSuperiors: exchangeAdminService possSuperiors: container subClassOf: top governsID: 1.2.840.113556.1.5.7000.62.2 mayContain: msExchMinAdminVersion mayContain: msExchDomainLocalGroupSid mayContain: msExchDomainLocalGroupGuid mayContain: msExchDomainGlobalGroupSid mayContain: msExchDomainGlobalGroupGuid mayContain: msExchProcessedSids mayContain: gatewayProxy mayContain: msExchEncryptedPassword mayContain: msExchServer2LastUpdateTime mayContain: msExchServer2HighestUSNVector mayContain: msExchServer2HighestUSN mayContain: msExchServer2Flags mayContain: msExchServer1HighestUSNVector mayContain: msExchServer1AuthenticationPassword mayContain: msExchServer1AuthenticationCredentials mayContain: msExchMasterServiceBL mayContain: exportContainers mayContain: msExchServer1SearchFilter mayContain: msExchServer1NetworkAddress mayContain: msExchServer1PageSize mayContain: msExchServer1LastUpdateTime mayContain: msExchServer1HighestUSN mayContain: msExchServer1Flags mayContain: msExchReplicateNow mayContain: msExchPollInterval mayContain: msExchDomainLink mayContain: msExchDoFullReplication mayContain: msExchAddressListServiceLink mayContain: activationStyle mayContain: activationSchedule rDNAttID: cn showInAdvancedViewOnly: TRUE adminDisplayName: ms-Exch-Address-List-Service adminDescription: ms-Exch-Address-List-Service auxiliaryClass: msExchBaseClass objectClassCategory: 1 lDAPDisplayName: msExchAddressListService name: ms-Exch-Address-List-Service schemaIDGUID: e6a2c260-a980-11d2-a9ff-00c04f8eedd8 systemOnly: FALSE defaultSecurityDescriptor: D:S: defaultHidingValue: TRUE objectCategory: CN=Class-Schema,${SCHEMADN} defaultObjectCategory: CN=ms-Exch-Address-List-Service,${SCHEMADN} # # ms-Exch-Address-List-Service-Container # Container for Recipient Update Service (RUS) objects # dn: CN=ms-Exch-Address-List-Service-Container,${SCHEMADN} objectClass: top objectClass: classSchema cn: ms-Exch-Address-List-Service-Container distinguishedName: CN=ms-Exch-Address-List-Service-Container,${SCHEMADN} possSuperiors: msExchContainer subClassOf: container governsID: 1.2.840.113556.1.5.7000.62.13 rDNAttID: cn showInAdvancedViewOnly: TRUE adminDisplayName: ms-Exch-Address-List-Service-Container adminDescription: ms-Exch-Address-List-Service-Container auxiliaryClass: msExchBaseClass objectClassCategory: 1 lDAPDisplayName: msExchAddressListServiceContainer name: ms-Exch-Address-List-Service-Container schemaIDGUID: b1fce95a-1d44-11d3-aa5e-00c04f8eedd8 systemOnly: FALSE defaultSecurityDescriptor: D:S: defaultHidingValue: TRUE objectCategory: CN=Class-Schema,${SCHEMADN} defaultObjectCategory: CN=ms-Exch-Address-List-Service-Container,${SCHEMADN} # # ms-Exch-Addr-Type # Specifies an EMS Address type, such as SMTP, MHS, or PROFS. # dn: CN=ms-Exch-Addr-Type,${SCHEMADN} objectClass: top objectClass: classSchema cn: ms-Exch-Addr-Type distinguishedName: CN=ms-Exch-Addr-Type,${SCHEMADN} possSuperiors: container subClassOf: top governsID: 1.2.840.113556.1.3.57 mustContain: proxyGeneratorDLL mustContain: fileVersion mustContain: cn mayContain: msExchMinAdminVersion mayContain: proxyGenerationEnabled rDNAttID: cn showInAdvancedViewOnly: TRUE adminDisplayName: ms-Exch-Addr-Type adminDescription: ms-Exch-Addr-Type auxiliaryClass: msExchBaseClass objectClassCategory: 1 lDAPDisplayName: addrType name: ms-Exch-Addr-Type schemaIDGUID: a8df74ab-c5ea-11d1-bbcb-0080c76670c0 systemOnly: FALSE defaultSecurityDescriptor: D:S: defaultHidingValue: TRUE objectCategory: CN=Class-Schema,${SCHEMADN} defaultObjectCategory: CN=ms-Exch-Addr-Type,${SCHEMADN} # # ms-Exch-Add-In # dn: CN=ms-Exch-Add-In,${SCHEMADN} objectClass: top objectClass: classSchema cn: ms-Exch-Add-In distinguishedName: CN=ms-Exch-Add-In,${SCHEMADN} possSuperiors: container subClassOf: top governsID: 1.2.840.113556.1.3.36 mustContain: computerName mustContain: cn mayContain: owner mayContain: activationStyle mayContain: activationSchedule rDNAttID: cn showInAdvancedViewOnly: TRUE adminDisplayName: ms-Exch-Add-In adminDescription: ms-Exch-Add-In auxiliaryClass: msExchBaseClass objectClassCategory: 1 lDAPDisplayName: addIn name: ms-Exch-Add-In schemaIDGUID: a8df74aa-c5ea-11d1-bbcb-0080c76670c0 systemOnly: FALSE defaultSecurityDescriptor: D:S: defaultHidingValue: TRUE objectCategory: CN=Class-Schema,${SCHEMADN} defaultObjectCategory: CN=ms-Exch-Add-In,${SCHEMADN} # # ms-Exch-Admin-Extension # Specifies a remote X.400 message transfer agent (MTA). # dn: CN=ms-Exch-Admin-Extension,${SCHEMADN} objectClass: top objectClass: classSchema cn: ms-Exch-Admin-Extension distinguishedName: CN=ms-Exch-Admin-Extension,${SCHEMADN} possSuperiors: container subClassOf: top governsID: 1.2.840.113556.1.3.21 mustContain: fileVersion mustContain: adminExtensionDLL mustContain: cn rDNAttID: cn showInAdvancedViewOnly: TRUE adminDisplayName: ms-Exch-Admin-Extension adminDescription: ms-Exch-Admin-Extension auxiliaryClass: msExchBaseClass objectClassCategory: 1 lDAPDisplayName: adminExtension name: ms-Exch-Admin-Extension schemaIDGUID: a8df74ac-c5ea-11d1-bbcb-0080c76670c0 systemOnly: FALSE defaultSecurityDescriptor: D:S: defaultHidingValue: TRUE objectCategory: CN=Class-Schema,${SCHEMADN} defaultObjectCategory: CN=ms-Exch-Admin-Extension,${SCHEMADN} # # ms-Exch-Admin-Group # objectCategory for cn=First Administrative Group # description: An administrative group. # # # ms-Exch-Admin-Role # dn: CN=ms-Exch-Admin-Role,${SCHEMADN} objectClass: top objectClass: classSchema cn: ms-Exch-Admin-Role distinguishedName: CN=ms-Exch-Admin-Role,${SCHEMADN} possSuperiors: msExchContainer possSuperiors: container subClassOf: top governsID: 1.2.840.113556.1.5.7000.62.50017 mustContain: msExchRoleRights mayContain: msExchRoleLocalizedNames mayContain: msExchRoleIncludes rDNAttID: cn showInAdvancedViewOnly: TRUE adminDisplayName: ms-Exch-Admin-Role adminDescription: ms-Exch-Admin-Role auxiliaryClass: msExchBaseClass objectClassCategory: 1 lDAPDisplayName: msExchAdminRole name: ms-Exch-Admin-Role schemaIDGUID: e7f2edf2-a980-11d2-a9ff-00c04f8eedd8 systemOnly: FALSE defaultSecurityDescriptor: D:S: defaultHidingValue: TRUE objectCategory: CN=Class-Schema,${SCHEMADN} defaultObjectCategory: CN=ms-Exch-Admin-Role,${SCHEMADN} # # ms-Exch-Chat-Ban # A Chat Service Ban Object # dn: CN=ms-Exch-Chat-Ban,${SCHEMADN} objectClass: top objectClass: classSchema cn: ms-Exch-Chat-Ban distinguishedName: CN=ms-Exch-Chat-Ban,${SCHEMADN} #possSuperiors: msExchChatVirtualNetwork possSuperiors: msExchChatNetwork subClassOf: top governsID: 1.2.840.113556.1.5.7000.62.8004 mayContain: msExchChatStartTime mayContain: msExchChatDuration mayContain: msExchChatBanReason mayContain: msExchChatBanMask rDNAttID: cn showInAdvancedViewOnly: TRUE adminDisplayName: ms-Exch-Chat-Ban adminDescription: ms-Exch-Chat-Ban auxiliaryClass: msExchBaseClass objectClassCategory: 1 lDAPDisplayName: msExchChatBan name: ms-Exch-Chat-Ban schemaIDGUID: e8d0a8a4-a980-11d2-a9ff-00c04f8eedd8 systemOnly: FALSE defaultSecurityDescriptor: D:S: defaultHidingValue: TRUE objectCategory: CN=Class-Schema,${SCHEMADN} defaultObjectCategory: CN=ms-Exch-Chat-Ban,${SCHEMADN} # # ms-Exch-Chat-Channel # A Chat Service channel (room) object # dn: CN=ms-Exch-Chat-Channel,${SCHEMADN} objectClass: top objectClass: classSchema cn: ms-Exch-Chat-Channel distinguishedName: CN=ms-Exch-Chat-Channel,${SCHEMADN} #possSuperiors: msExchChatVirtualNetwork possSuperiors: msExchChatNetwork subClassOf: top governsID: 1.2.840.113556.1.5.7000.62.8003 mayContain: msExchChatAccess mayContain: msExchChatChannelTopic mayContain: msExchChatChannelSubject mayContain: msExchChatChannelPICS mayContain: msExchChatChannelPartMessage mayContain: msExchChatChannelOwnerKey mayContain: msExchChatChannelName mayContain: msExchChatChannelMode mayContain: msExchChatChannelLimit mayContain: msExchChatChannelLCID mayContain: msExchChatChannelLanguage mayContain: msExchChatChannelKey mayContain: msExchChatChannelJoinMessage mayContain: msExchChatChannelHostKey mayContain: msExchChatChannelFlags mayContain: msExchChatChannelAutoCreate rDNAttID: cn showInAdvancedViewOnly: TRUE adminDisplayName: ms-Exch-Chat-Channel adminDescription: ms-Exch-Chat-Channel auxiliaryClass: msExchBaseClass objectClassCategory: 1 lDAPDisplayName: msExchChatChannel name: ms-Exch-Chat-Channel schemaIDGUID: e902ba06-a980-11d2-a9ff-00c04f8eedd8 systemOnly: FALSE defaultSecurityDescriptor: D:S: defaultHidingValue: TRUE objectCategory: CN=Class-Schema,${SCHEMADN} defaultObjectCategory: CN=ms-Exch-Chat-Channel,${SCHEMADN} # # ms-Exch-Chat-User-Class # dn: CN=ms-Exch-Chat-User-Class,${SCHEMADN} objectClass: top objectClass: classSchema cn: ms-Exch-Chat-User-Class distinguishedName: CN=ms-Exch-Chat-User-Class,${SCHEMADN} #possSuperiors: msExchChatVirtualNetwork possSuperiors: msExchChatProtocol possSuperiors: msExchChatNetwork subClassOf: top governsID: 1.2.840.113556.1.5.7000.62.8006 mayContain: msExchChatMaxOctetsToMask mayContain: msExchChatMaxConnectionsPerIP mayContain: msExchChatClassScopeType mayContain: msExchChatClassRestrictions mayContain: msExchChatStartTime mayContain: msExchChatProtectionLevel mayContain: msExchChatPingDelay mayContain: msExchChatOutputSaturation mayContain: msExchChatNickDelay mayContain: msExchChatMessageLag mayContain: msExchChatMaxMemberships mayContain: msExchChatMaxConnections mayContain: msExchChatInputFloodLimit #mayContain: msExchChatEnableAuthenticated mayContain: msExchChatEnableAnonymous mayContain: msExchChatDuration mayContain: msExchChatClassIP mayContain: msExchChatClassIdentMask rDNAttID: cn showInAdvancedViewOnly: TRUE adminDisplayName: ms-Exch-Chat-User-Class adminDescription: ms-Exch-Chat-User-Class auxiliaryClass: msExchBaseClass objectClassCategory: 1 lDAPDisplayName: msExchChatUserClass name: ms-Exch-Chat-User-Class schemaIDGUID: e9a0153a-a980-11d2-a9ff-00c04f8eedd8 systemOnly: FALSE defaultSecurityDescriptor: D:S: defaultHidingValue: TRUE objectCategory: CN=Class-Schema,${SCHEMADN} defaultObjectCategory: CN=ms-Exch-Chat-User-Class,${SCHEMADN} # # ms-Exch-Chat-Virtual-Network # An instance of a Chat community on a physical server. # dn: CN=ms-Exch-Chat-Virtual-Network,${SCHEMADN} objectClass: top objectClass: classSchema cn: ms-Exch-Chat-Virtual-Network distinguishedName: CN=ms-Exch-Chat-Virtual-Network,${SCHEMADN} possSuperiors: msExchChatProtocol possSuperiors: msExchChatNetwork subClassOf: container governsID: 1.2.840.113556.1.5.7000.62.8002 mayContain: msExchChatExtensions mayContain: msExchServerBindings mayContain: msExchChatTitle mayContain: msExchChatMaxConnections mayContain: msExchChatClientPort mayContain: Enabled rDNAttID: cn showInAdvancedViewOnly: TRUE adminDisplayName: ms-Exch-Chat-Virtual-Network adminDescription: ms-Exch-Chat-Virtual-Network auxiliaryClass: msExchBaseClass objectClassCategory: 1 lDAPDisplayName: msExchChatVirtualNetwork name: ms-Exch-Chat-Virtual-Network schemaIDGUID: ea5ed15a-a980-11d2-a9ff-00c04f8eedd8 systemOnly: FALSE defaultSecurityDescriptor: D:S: defaultHidingValue: TRUE objectCategory: CN=Class-Schema,${SCHEMADN} defaultObjectCategory: CN=ms-Exch-Chat-Virtual-Network,${SCHEMADN} # # ms-Exch-Computer-Policy # dn: CN=ms-Exch-Computer-Policy,${SCHEMADN} objectClass: top objectClass: classSchema cn: ms-Exch-Computer-Policy distinguishedName: CN=ms-Exch-Computer-Policy,${SCHEMADN} possSuperiors: container subClassOf: computer governsID: 1.2.840.113556.1.5.7000.62.50007 mayContain: msExchPolicyLastAppliedTime mayContain: msExchPolicyOptionList mayContain: msExchPolicyLockDown mayContain: msExchPolicyListBL mayContain: msExchPolicyDefault rDNAttID: cn showInAdvancedViewOnly: TRUE adminDisplayName: ms-Exch-Computer-Policy adminDescription: ms-Exch-Computer-Policy auxiliaryClass: msExchBaseClass objectClassCategory: 1 lDAPDisplayName: msExchComputerPolicy name: ms-Exch-Computer-Policy schemaIDGUID: ed2c752c-a980-11d2-a9ff-00c04f8eedd8 systemOnly: FALSE defaultSecurityDescriptor: D:S: defaultHidingValue: TRUE objectCategory: CN=Class-Schema,${SCHEMADN} defaultObjectCategory: CN=ms-Exch-Computer-Policy,${SCHEMADN} # # ms-Exch-Connection-Agreement # Used to store synchronization information. # dn: CN=ms-Exch-Connection-Agreement,${SCHEMADN} objectClass: top objectClass: classSchema cn: ms-Exch-Connection-Agreement distinguishedName: CN=ms-Exch-Connection-Agreement,${SCHEMADN} possSuperiors: organizationalUnit possSuperiors: container subClassOf: top governsID: 1.2.840.113556.1.5.7000.62.3 mayContain: msExchIsConfigCA mayContain: msExchInterOrgAddressType mayContain: msExchMoveToLSA mayContain: msExchServer2HighestUSNVector mayContain: msExchServer1HighestUSNVector mayContain: msExchExchangeSite mayContain: msExchADCObjectType mayContain: msExchServer2IsBridgehead mayContain: msExchServer1IsBridgehead mayContain: versionNumber mayContain: msExchSynchronizationDirection mayContain: msExchServer2Type mayContain: msExchServer2SSLPort mayContain: msExchServer2SearchFilter mayContain: msExchServer2SchemaMap mayContain: msExchServer2Port mayContain: msExchServer2PageSize mayContain: msExchServer2NTAccountDomain mayContain: msExchServer2NetworkAddress mayContain: msExchServer2LastUpdateTime mayContain: msExchServer2ImportContainer mayContain: msExchServer2HighestUSN mayContain: msExchServer2Flags mayContain: msExchServer2ExportContainers mayContain: msExchServer2DeletionOption mayContain: msExchServer2AuthenticationType mayContain: msExchServer2AuthenticationPassword mayContain: msExchServer2AuthenticationCredentials mayContain: msExchServer2AlwaysCreateAs mayContain: msExchServer1Type mayContain: msExchServer1SSLPort mayContain: msExchServer1SearchFilter mayContain: msExchServer1SchemaMap mayContain: msExchServer1Port mayContain: msExchServer1PageSize mayContain: msExchServer1NTAccountDomain mayContain: msExchServer1NetworkAddress mayContain: msExchServer1LastUpdateTime mayContain: msExchServer1ImportContainer mayContain: msExchServer1HighestUSN mayContain: msExchServer1Flags mayContain: msExchServer1ExportContainers mayContain: msExchServer1DeletionOption mayContain: msExchServer1AuthenticationType mayContain: msExchServer1AuthenticationPassword mayContain: msExchServer1AuthenticationCredentials mayContain: msExchServer1AlwaysCreateAs mayContain: msExchReplicateNow mayContain: msExchRemoteServerList mayContain: msExchRemotePrivateISList mayContain: msExchNtdsImportContainer mayContain: msExchNtdsExportContainers mayContain: msExchNTAccountOptions mayContain: msExchIsBridgeheadSite mayContain: msExchHomeSyncService mayContain: msExchHomeServerName mayContain: msExchDoFullReplication mayContain: msExchDereferenceAliases mayContain: msExchCorrelationAttribute mayContain: msExchCASchemaPolicy mayContain: msExchAdditionalDNMap mayContain: msExchADCOptions mayContain: activationStyle mayContain: activationSchedule mayContain: displayName rDNAttID: cn showInAdvancedViewOnly: TRUE adminDisplayName: ms-Exch-Connection-Agreement adminDescription: ms-Exch-Connection-Agreement auxiliaryClass: msExchBaseClass objectClassCategory: 1 lDAPDisplayName: msExchConnectionAgreement name: ms-Exch-Connection-Agreement schemaIDGUID: ee64c93a-a980-11d2-a9ff-00c04f8eedd8 systemOnly: FALSE defaultSecurityDescriptor: D:S: defaultHidingValue: TRUE objectCategory: CN=Class-Schema,${SCHEMADN} defaultObjectCategory: CN=ms-Exch-Connection-Agreement,${SCHEMADN} # # ms-Exch-Domain-Content-Config # dn: CN=ms-Exch-Domain-Content-Config,${SCHEMADN} objectClass: top objectClass: classSchema cn: ms-Exch-Domain-Content-Config distinguishedName: CN=ms-Exch-Domain-Content-Config,${SCHEMADN} possSuperiors: msExchContentConfigContainer subClassOf: top governsID: 1.2.840.113556.1.5.7000.62.50027 mayContain: msExchMinAdminVersion mayContain: versionNumber mayContain: msExchRoutingAcceptMessageType mayContain: msExchResolveP2 mayContain: msExchNonMIMECharacterSet mayContain: msExchEncodeSMTPRelay mayContain: sendTNEF mayContain: msExchRoutingDisplaySenderEnabled mayContain: lineWrap mayContain: domainName mayContain: contentType mayContain: characterSet rDNAttID: cn showInAdvancedViewOnly: TRUE adminDisplayName: ms-Exch-Domain-Content-Config adminDescription: ms-Exch-Domain-Content-Config auxiliaryClass: msExchBaseClass objectClassCategory: 1 lDAPDisplayName: msExchDomainContentConfig name: ms-Exch-Domain-Content-Config schemaIDGUID: ab3a1ad1-1df5-11d3-aa5e-00c04f8eedd8 systemOnly: FALSE defaultSecurityDescriptor: D:S: defaultHidingValue: TRUE objectCategory: CN=Class-Schema,${SCHEMADN} defaultObjectCategory: CN=ms-Exch-Domain-Content-Config,${SCHEMADN} # # ms-Exch-DX-Requestor # The remote directory exchange agent (DXA) requestor. # dn: CN=ms-Exch-DX-Requestor,${SCHEMADN} objectClass: top objectClass: classSchema cn: ms-Exch-DX-Requestor distinguishedName: CN=ms-Exch-DX-Requestor,${SCHEMADN} possSuperiors: container subClassOf: remoteDXA governsID: 1.2.840.113556.1.3.19 mayContain: activationStyle mayContain: activationSchedule rDNAttID: cn showInAdvancedViewOnly: TRUE adminDisplayName: ms-Exch-DX-Requestor adminDescription: ms-Exch-DX-Requestor auxiliaryClass: msExchBaseClass objectClassCategory: 1 lDAPDisplayName: dXRequestor name: ms-Exch-DX-Requestor schemaIDGUID: a8df74ae-c5ea-11d1-bbcb-0080c76670c0 systemOnly: FALSE defaultSecurityDescriptor: D:S: defaultHidingValue: TRUE objectCategory: CN=Class-Schema,${SCHEMADN} defaultObjectCategory: CN=ms-Exch-DX-Requestor,${SCHEMADN} # # ms-Exch-DX-Server-Conn # The remote directory exchange agent (DXA) server. # dn: CN=ms-Exch-DX-Server-Conn,${SCHEMADN} objectClass: top objectClass: classSchema cn: ms-Exch-DX-Server-Conn distinguishedName: CN=ms-Exch-DX-Server-Conn,${SCHEMADN} possSuperiors: dXASiteServer subClassOf: remoteDXA governsID: 1.2.840.113556.1.3.20 rDNAttID: cn showInAdvancedViewOnly: TRUE adminDisplayName: ms-Exch-DX-Server-Conn adminDescription: ms-Exch-DX-Server-Conn auxiliaryClass: msExchBaseClass objectClassCategory: 1 lDAPDisplayName: dXServerConn name: ms-Exch-DX-Server-Conn schemaIDGUID: a8df74af-c5ea-11d1-bbcb-0080c76670c0 systemOnly: FALSE defaultSecurityDescriptor: D:S: defaultHidingValue: TRUE objectCategory: CN=Class-Schema,${SCHEMADN} defaultObjectCategory: CN=ms-Exch-DX-Server-Conn,${SCHEMADN} # # ms-Exch-Dynamic-Distribution-List # dn: CN=ms-Exch-Dynamic-Distribution-List,${SCHEMADN} objectClass: top objectClass: classSchema cn: ms-Exch-Dynamic-Distribution-List distinguishedName: CN=ms-Exch-Dynamic-Distribution-List,${SCHEMADN} possSuperiors: organizationalUnit possSuperiors: domainDNS possSuperiors: builtinDomain possSuperiors: container subClassOf: top governsID: 1.2.840.113556.1.5.7000.62.12006 mayContain: msExchPurportedSearchUI mayContain: msExchDynamicDLFilter mayContain: msExchDynamicDLBaseDN mayContain: managedBy mayContain: reportToOwner mayContain: reportToOriginator mayContain: oOFReplyToOriginator mayContain: msExchMemberFilter mayContain: msExchMemberBaseDN mayContain: hideDLMembership mayContain: mail rDNAttID: cn showInAdvancedViewOnly: TRUE adminDisplayName: ms-Exch-Dynamic-Distribution-List adminDescription: ms-Exch-Dynamic-Distribution-List auxiliaryClass: msExchCustomAttributes auxiliaryClass: msExchBaseClass auxiliaryClass: mailRecipient objectClassCategory: 1 lDAPDisplayName: msExchDynamicDistributionList name: ms-Exch-Dynamic-Distribution-List schemaIDGUID: 018849b0-a981-11d2-a9ff-00c04f8eedd8 systemOnly: FALSE defaultSecurityDescriptor: D:(A;;RP;;;AU) defaultHidingValue: FALSE objectCategory: CN=Class-Schema,${SCHEMADN} defaultObjectCategory: CN=ms-Exch-Dynamic-Distribution-List,${SCHEMADN} # # ms-Exch-Encryption-Cfg # Contains attributes that configure security policies for each # Administrative group. # dn: CN=ms-Exch-Encryption-Cfg,${SCHEMADN} objectClass: top objectClass: classSchema cn: ms-Exch-Encryption-Cfg distinguishedName: CN=ms-Exch-Encryption-Cfg,${SCHEMADN} possSuperiors: msExchAdvancedSecurityContainer subClassOf: top governsID: 1.2.840.113556.1.3.16 mustContain: cn mayContain: msExchMinAdminVersion mayContain: sMIMEAlgSelectedOther mayContain: sMIMEAlgSelectedNA mayContain: sMIMEAlgListOther mayContain: sMIMEAlgListNA mayContain: kMServer mayContain: encryptAlgSelectedOther mayContain: encryptAlgSelectedNA mayContain: encryptAlgListOther mayContain: encryptAlgListNA mayContain: defaultMessageFormat rDNAttID: cn showInAdvancedViewOnly: TRUE adminDisplayName: ms-Exch-Encryption-Cfg adminDescription: ms-Exch-Encryption-Cfg auxiliaryClass: msExchBaseClass objectClassCategory: 1 lDAPDisplayName: encryptionCfg name: ms-Exch-Encryption-Cfg schemaIDGUID: a8df74b1-c5ea-11d1-bbcb-0080c76670c0 systemOnly: FALSE defaultSecurityDescriptor: D:(A;;RP;;;AU) defaultHidingValue: TRUE objectCategory: CN=Class-Schema,${SCHEMADN} defaultObjectCategory: CN=ms-Exch-Encryption-Cfg,${SCHEMADN} # # ms-Exch-Exchange-Server-Policy # The Exchange server policy. # dn: CN=ms-Exch-Exchange-Server-Policy,${SCHEMADN} objectClass: top objectClass: classSchema cn: ms-Exch-Exchange-Server-Policy distinguishedName: CN=ms-Exch-Exchange-Server-Policy,${SCHEMADN} possSuperiors: container subClassOf: msExchExchangeServer governsID: 1.2.840.113556.1.5.7000.62.50025 mayContain: msExchPolicyOptionList mayContain: msExchPolicyLockDown mayContain: msExchPolicyListBL mayContain: msExchPolicyLastAppliedTime mayContain: msExchPolicyDefault rDNAttID: cn showInAdvancedViewOnly: TRUE adminDisplayName: ms-Exch-Exchange-Server-Policy adminDescription: ms-Exch-Exchange-Server-Policy auxiliaryClass: msExchBaseClass objectClassCategory: 1 lDAPDisplayName: msExchExchangeServerPolicy name: ms-Exch-Exchange-Server-Policy schemaIDGUID: e497942f-1d42-11d3-aa5e-00c04f8eedd8 systemOnly: FALSE defaultSecurityDescriptor: D:S: defaultHidingValue: TRUE objectCategory: CN=Class-Schema,${SCHEMADN} defaultObjectCategory: CN=ms-Exch-Exchange-Server-Policy,${SCHEMADN} # # ms-Exch-IM-Firewall # The Instant Messaging representation of firewalls. # dn: CN=ms-Exch-IM-Firewall,${SCHEMADN} objectClass: top objectClass: classSchema cn: ms-Exch-IM-Firewall distinguishedName: CN=ms-Exch-IM-Firewall,${SCHEMADN} possSuperiors: msExchIMGlobalSettingsContainer subClassOf: top governsID: 1.2.840.113556.1.5.7000.62.7015 mustContain: msExchIMFirewallType mayContain: portNumber mayContain: msExchIMProxy mayContain: msExchIMIPRange mayContain: flags rDNAttID: cn showInAdvancedViewOnly: TRUE adminDisplayName: ms-Exch-IM-Firewall adminDescription: ms-Exch-IM-Firewall auxiliaryClass: msExchBaseClass objectClassCategory: 1 lDAPDisplayName: msExchIMFirewall name: ms-Exch-IM-Firewall schemaIDGUID: 9f116ebe-284e-11d3-aa68-00c04f8eedd8 systemOnly: FALSE defaultSecurityDescriptor: D:S: defaultHidingValue: TRUE objectCategory: CN=Class-Schema,${SCHEMADN} defaultObjectCategory: CN=ms-Exch-IM-Firewall,${SCHEMADN} # # ms-Exch-Information-Store # The Information Store configuration. # dn: CN=ms-Exch-Information-Store,${SCHEMADN} objectClass: top objectClass: classSchema cn: ms-Exch-Information-Store distinguishedName: CN=ms-Exch-Information-Store,${SCHEMADN} possSuperiors: msExchExchangeServer subClassOf: container governsID: 1.2.840.113556.1.5.7000.62.11001 mustContain: cn mayContain: msExchMinAdminVersion mayContain: msExchMaxRestoreStorageGroups mayContain: msExchRecovery mayContain: msExchESEParamZeroDatabaseDuringBackup mayContain: msExchESEParamPageTempDBMin mayContain: msExchESEParamPageFragment mayContain: msExchESEParamLogFileSize mayContain: msExchESEParamLogCheckpointPeriod mayContain: msExchESEParamLogBuffers mayContain: msExchESEParamGlobalMinVerPages mayContain: msExchESEParamEventSource mayContain: msExchESEParamEnableSortedRetrieveColumns mayContain: msExchESEParamEnableOnlineDefrag mayContain: msExchESEParamEnableIndexChecking mayContain: msExchESEParamDbExtensionSize mayContain: msExchESEParamCommitDefault mayContain: msExchESEParamCircularLog mayContain: msExchESEParamCacheSizeMin mayContain: msExchESEParamBaseName mayContain: msExchESEParamAssertAction mayContain: msExchESEParamStopFlushThreshold mayContain: msExchESEParamStartFlushThreshold mayContain: msExchQueuingMDB mayContain: msExchOwningOrg mayContain: msExchMinimumThreads mayContain: msExchMaxThreads mayContain: msExchMaxStoresPerGroup mayContain: msExchMaxStorageGroups mayContain: msExchMaxPoolThreads mayContain: msExchIFSPublicName mayContain: msExchIFSPublicEnabled mayContain: msExchIFSPrivateName mayContain: msExchIFSPrivateEnabled mayContain: msExchESEParamCacheSizeMax mayContain: msExchESEParamCacheSize mayContain: msExchDatabaseSessionIncrement mayContain: msExchDatabaseSessionAddend mayContain: msExchBackgroundThreads rDNAttID: cn showInAdvancedViewOnly: TRUE adminDisplayName: ms-Exch-Information-Store adminDescription: ms-Exch-Information-Store auxiliaryClass: msExchBaseClass objectClassCategory: 1 lDAPDisplayName: msExchInformationStore name: ms-Exch-Information-Store schemaIDGUID: 031b371a-a981-11d2-a9ff-00c04f8eedd8 systemOnly: FALSE defaultSecurityDescriptor: D:S: defaultHidingValue: TRUE objectCategory: CN=Class-Schema,${SCHEMADN} defaultObjectCategory: CN=ms-Exch-Information-Store,${SCHEMADN} # # ms-Exch-Ip-Conf-Container # The Exchange Video Conferencing container. # dn: CN=ms-Exch-Ip-Conf-Container,${SCHEMADN} objectClass: top objectClass: classSchema cn: ms-Exch-Ip-Conf-Container distinguishedName: CN=ms-Exch-Ip-Conf-Container,${SCHEMADN} possSuperiors: msExchConferenceSite subClassOf: msExchCTP governsID: 1.2.840.113556.1.5.7000.62.9006 mayContain: msExchMaxParticipants mayContain: msExchMaxExtensionTime rDNAttID: cn showInAdvancedViewOnly: TRUE adminDisplayName: ms-Exch-Ip-Conf-Container adminDescription: ms-Exch-Ip-Conf-Container auxiliaryClass: msExchBaseClass objectClassCategory: 1 lDAPDisplayName: msExchIpConfContainer name: ms-Exch-Ip-Conf-Container schemaIDGUID: 99f5866d-12e8-11d3-aa58-00c04f8eedd8 systemOnly: FALSE defaultSecurityDescriptor: D:S: defaultHidingValue: TRUE objectCategory: CN=Class-Schema,${SCHEMADN} defaultObjectCategory: CN=ms-Exch-Ip-Conf-Container,${SCHEMADN} # # ms-Exch-Key-Management-Server # Holds configuration attributes for each Key Management Service. # dn: CN=ms-Exch-Key-Management-Server,${SCHEMADN} objectClass: top objectClass: classSchema cn: ms-Exch-Key-Management-Server distinguishedName: CN=ms-Exch-Key-Management-Server,${SCHEMADN} possSuperiors: msExchAdvancedSecurityContainer subClassOf: certificationAuthority governsID: 1.2.840.113556.1.5.7000.62.13002 mayContain: sendEMailMessage mayContain: securityPolicy mayContain: kMServer mayContain: kCCStatus mayContain: expirationTime mayContain: enableCompatibility mayContain: dXAPrevTypes mayContain: dXAAdminForward mayContain: domainDefAltRecip mayContain: crossCertificateCRL mayContain: compromisedKeyList mayContain: certificateRevocationListV3 mayContain: certificateRevocationListV1 mayContain: certificateChainV3 rDNAttID: cn showInAdvancedViewOnly: TRUE adminDisplayName: ms-Exch-Key-Management-Server adminDescription: ms-Exch-Key-Management-Server auxiliaryClass: msExchBaseClass objectClassCategory: 1 lDAPDisplayName: msExchKeyManagementServer name: ms-Exch-Key-Management-Server schemaIDGUID: 8ce334ec-b09e-11d2-aa06-00c04f8eedd8 systemOnly: FALSE defaultSecurityDescriptor: D:(A;;RP;;;AU) defaultHidingValue: TRUE objectCategory: CN=Class-Schema,${SCHEMADN} defaultObjectCategory: CN=ms-Exch-Key-Management-Server,${SCHEMADN} # # ms-Exch-Local-DXA # Represents the directory exchange agent (DXA) process. # dn: CN=ms-Exch-Local-DXA,${SCHEMADN} objectClass: top objectClass: classSchema cn: ms-Exch-Local-DXA distinguishedName: CN=ms-Exch-Local-DXA,${SCHEMADN} possSuperiors: msExchExchangeServer possSuperiors: container possSuperiors: computer subClassOf: top governsID: 1.2.840.113556.1.3.1 mustContain: deliveryMechanism mayContain: msExchServer1NetworkAddress mayContain: msExchServer1AlwaysCreateAs mayContain: delivEITs mayContain: dXATemplateTimeStamp mayContain: dXAOutTemplateMap mayContain: dXAInTemplateMap mayContain: dXAAdminUpdate mayContain: diagnosticRegKey rDNAttID: cn showInAdvancedViewOnly: TRUE adminDisplayName: ms-Exch-Local-DXA adminDescription: ms-Exch-Local-DXA auxiliaryClass: msExchBaseClass auxiliaryClass: mailRecipient objectClassCategory: 1 lDAPDisplayName: localDXA name: ms-Exch-Local-DXA schemaIDGUID: a8df74b5-c5ea-11d1-bbcb-0080c76670c0 systemOnly: FALSE defaultSecurityDescriptor: D:S: defaultHidingValue: TRUE objectCategory: CN=Class-Schema,${SCHEMADN} defaultObjectCategory: CN=ms-Exch-Local-DXA,${SCHEMADN} # # ms-Exch-MCU # The Exchange Conferencing Multipoint Control Unit (MCU) Configuration # Interface . CN=MachineName. # dn: CN=ms-Exch-MCU,${SCHEMADN} objectClass: top objectClass: classSchema cn: ms-Exch-MCU distinguishedName: CN=ms-Exch-MCU,${SCHEMADN} #possSuperiors: msExchMCUContainer subClassOf: top governsID: 1.2.840.113556.1.5.7000.62.9004 mayContain: msExchMCUHostsSites mayContain: msExchVisibilityMask mayContain: msExchScopeMask mayContain: msExchProxyName mayContain: msExchLocalName mayContain: msExchInternetName mayContain: enabledConnection rDNAttID: cn showInAdvancedViewOnly: TRUE adminDisplayName: ms-Exch-MCU adminDescription: ms-Exch-MCU auxiliaryClass: msExchBaseClass objectClassCategory: 1 lDAPDisplayName: msExchMCU name: ms-Exch-MCU schemaIDGUID: 038680ec-a981-11d2-a9ff-00c04f8eedd8 systemOnly: FALSE defaultSecurityDescriptor: D:S: defaultHidingValue: TRUE objectCategory: CN=Class-Schema,${SCHEMADN} defaultObjectCategory: CN=ms-Exch-MCU,${SCHEMADN} # # ms-Exch-MCU-Container # The Exchange Data Conference Service class. CN=Exchange Data # Conferencing Service. # dn: CN=ms-Exch-MCU-Container,${SCHEMADN} objectClass: top objectClass: classSchema cn: ms-Exch-MCU-Container distinguishedName: CN=ms-Exch-MCU-Container,${SCHEMADN} possSuperiors: msExchConferenceSite subClassOf: msExchCTP governsID: 1.2.840.113556.1.5.7000.62.9003 mayContain: rangeUpper mayContain: rangeLower mayContain: msExchMaxConnections mayContain: msExchListPublic mayContain: msExchCertificate mayContain: msExchAuditFlags rDNAttID: cn showInAdvancedViewOnly: TRUE adminDisplayName: ms-Exch-MCU-Container adminDescription: ms-Exch-MCU-Container auxiliaryClass: msExchBaseClass objectClassCategory: 1 lDAPDisplayName: msExchMCUContainer name: ms-Exch-MCU-Container schemaIDGUID: 03aa4432-a981-11d2-a9ff-00c04f8eedd8 systemOnly: FALSE defaultSecurityDescriptor: D:S: defaultHidingValue: TRUE objectCategory: CN=Class-Schema,${SCHEMADN} defaultObjectCategory: CN=ms-Exch-MCU-Container,${SCHEMADN} # # ms-Exch-MHS-Link-Monitoring-Config # The EMS saved Linked Monitoring configuration. # dn: CN=ms-Exch-MHS-Link-Monitoring-Config,${SCHEMADN} objectClass: top objectClass: classSchema cn: ms-Exch-MHS-Link-Monitoring-Config distinguishedName: CN=ms-Exch-MHS-Link-Monitoring-Config,${SCHEMADN} possSuperiors: container subClassOf: mHSMonitoringConfig governsID: 1.2.840.113556.1.3.12 mayContain: monitoringWarningUnits mayContain: monitoringWarningDelay mayContain: monitoringRecipientsNDR mayContain: monitoringRecipients mayContain: monitoringAlertUnits mayContain: monitoringAlertDelay mayContain: monitorServers rDNAttID: cn showInAdvancedViewOnly: TRUE adminDisplayName: ms-Exch-MHS-Link-Monitoring-Config adminDescription: ms-Exch-MHS-Link-Monitoring-Config auxiliaryClass: msExchBaseClass objectClassCategory: 1 lDAPDisplayName: mHSLinkMonitoringConfig name: ms-Exch-MHS-Link-Monitoring-Config schemaIDGUID: a8df74b9-c5ea-11d1-bbcb-0080c76670c0 systemOnly: FALSE defaultSecurityDescriptor: D:S: defaultHidingValue: TRUE objectCategory: CN=Class-Schema,${SCHEMADN} defaultObjectCategory: CN=ms-Exch-MHS-Link-Monitoring-Config,${SCHEMADN} # # ms-Exch-MHS-Server-Monitoring-Config # The EMS saved Server Monitoring configuration. # dn: CN=ms-Exch-MHS-Server-Monitoring-Config,${SCHEMADN} objectClass: top objectClass: classSchema cn: ms-Exch-MHS-Server-Monitoring-Config distinguishedName: CN=ms-Exch-MHS-Server-Monitoring-Config,${SCHEMADN} possSuperiors: container subClassOf: mHSMonitoringConfig governsID: 1.2.840.113556.1.3.7 mayContain: serviceRestartMessage mayContain: serviceRestartDelay mayContain: serviceActionSecond mayContain: serviceActionOther mayContain: serviceActionFirst mayContain: monitorServices mayContain: monitorClock mayContain: clockWarningRepair mayContain: clockWarningOffset mayContain: clockAlertRepair mayContain: clockAlertOffset rDNAttID: cn showInAdvancedViewOnly: TRUE adminDisplayName: ms-Exch-MHS-Server-Monitoring-Config adminDescription: ms-Exch-MHS-Server-Monitoring-Config auxiliaryClass: msExchBaseClass objectClassCategory: 1 lDAPDisplayName: mHSServerMonitoringConfig name: ms-Exch-MHS-Server-Monitoring-Config schemaIDGUID: a8df74bd-c5ea-11d1-bbcb-0080c76670c0 systemOnly: FALSE defaultSecurityDescriptor: D:S: defaultHidingValue: TRUE objectCategory: CN=Class-Schema,${SCHEMADN} defaultObjectCategory: CN=ms-Exch-MHS-Server-Monitoring-Config,${SCHEMADN} # # ms-Exch-MTA-Cfg # dn: CN=ms-Exch-MTA-Cfg,${SCHEMADN} objectClass: top objectClass: classSchema cn: ms-Exch-MTA-Cfg distinguishedName: CN=ms-Exch-MTA-Cfg,${SCHEMADN} possSuperiors: container subClassOf: top governsID: 1.2.840.113556.1.3.3 mustContain: cn mayContain: xMITTimeoutUrgent mayContain: xMITTimeoutNormal mayContain: xMITTimeoutNonUrgent mayContain: transportExpeditedData mayContain: transferTimeoutUrgent mayContain: transferTimeoutNormal mayContain: transferTimeoutNonUrgent mayContain: transferRetryInterval mayContain: tempAssocThreshold mayContain: sessionDisconnectTimer mayContain: rTSWindowSize mayContain: rTSRecoveryTimeout mayContain: rTSCheckpointSize mayContain: openRetryInterval mayContain: numOfTransferRetries mayContain: numOfOpenRetries mayContain: messageTrackingEnabled mayContain: domainDefAltRecip mayContain: associationLifetime rDNAttID: cn showInAdvancedViewOnly: TRUE adminDisplayName: ms-Exch-MTA-Cfg adminDescription: ms-Exch-MTA-Cfg auxiliaryClass: msExchBaseClass objectClassCategory: 1 lDAPDisplayName: mTACfg name: ms-Exch-MTA-Cfg schemaIDGUID: a8df74a8-c5ea-11d1-bbcb-0080c76670c0 systemOnly: FALSE defaultSecurityDescriptor: D:S: defaultHidingValue: TRUE objectCategory: CN=Class-Schema,${SCHEMADN} defaultObjectCategory: CN=ms-Exch-MTA-Cfg,${SCHEMADN} # # ms-Exch-Multi-Media-User # Contains attributes for voice mailbox configuration. The attributes # can be updated by the mailbox owner. # dn: CN=ms-Exch-Multi-Media-User,${SCHEMADN} objectClass: top objectClass: classSchema cn: ms-Exch-Multi-Media-User distinguishedName: CN=ms-Exch-Multi-Media-User,${SCHEMADN} subClassOf: top governsID: 1.2.840.113556.1.5.7000.62.17002 mayContain: msExchVoiceMailboxID mayContain: msExchTUIVolume mayContain: msExchTUISpeed mayContain: msExchTUIPassword rDNAttID: cn showInAdvancedViewOnly: TRUE adminDisplayName: ms-Exch-Multi-Media-User adminDescription: ms-Exch-Multi-Media-User objectClassCategory: 3 lDAPDisplayName: msExchMultiMediaUser name: ms-Exch-Multi-Media-User schemaIDGUID: 1529cf7a-2fdb-11d3-aa6d-00c04f8eedd8 systemOnly: FALSE defaultHidingValue: TRUE objectCategory: CN=Class-Schema,${SCHEMADN} defaultObjectCategory: CN=ms-Exch-Multi-Media-User,${SCHEMADN} # # ms-Exch-OAB # The offline address book (OAB) configuration object. # dn: CN=ms-Exch-OAB,${SCHEMADN} objectClass: top objectClass: classSchema cn: ms-Exch-OAB distinguishedName: CN=ms-Exch-OAB,${SCHEMADN} possSuperiors: container subClassOf: top governsID: 1.2.840.113556.1.5.7000.62.9 mustContain: offLineABStyle mustContain: offLineABServer mustContain: offLineABSchedule mustContain: offLineABContainers mustContain: msExchOABFolder mustContain: doOABVersion mayContain: siteFolderServer mayContain: siteFolderGUID mayContain: msExchUseOABBL mayContain: msExchOABDefault rDNAttID: cn showInAdvancedViewOnly: TRUE adminDisplayName: ms-Exch-OAB adminDescription: ms-Exch-OAB auxiliaryClass: msExchBaseClass objectClassCategory: 1 lDAPDisplayName: msExchOAB name: ms-Exch-OAB schemaIDGUID: 3686cdd4-a982-11d2-a9ff-00c04f8eedd8 systemOnly: FALSE defaultSecurityDescriptor: D:S: defaultHidingValue: TRUE objectCategory: CN=Class-Schema,${SCHEMADN} defaultObjectCategory: CN=ms-Exch-OAB,${SCHEMADN} # # ms-Exch-Oma-Carrier # Contains wireless carrier information. # dn: CN=ms-Exch-Oma-Carrier,${SCHEMADN} objectClass: top objectClass: classSchema cn: ms-Exch-Oma-Carrier distinguishedName: CN=ms-Exch-Oma-Carrier,${SCHEMADN} subClassOf: container governsID: 1.2.840.113556.1.6.20.2.37 mayContain: msExchMinAdminVersion mayContain: msExchOmaTranslator mayContain: msExchOmaExtendedProperties mayContain: msExchOmaDeliveryProviderDN mayContain: msExchOmaConfiguration mayContain: msExchOmaCarrierUrl mayContain: msExchOmaCarrierType mayContain: msExchOmaCarrierAddress rDNAttID: cn showInAdvancedViewOnly: TRUE adminDisplayName: ms-Exch-Oma-Carrier adminDescription: ms-Exch-Oma-Carrier objectClassCategory: 1 lDAPDisplayName: msExchOmaCarrier name: ms-Exch-Oma-Carrier schemaIDGUID: 8712d34c-27e5-41b2-976e-482ad8c954e7 systemOnly: FALSE defaultSecurityDescriptor: D:(A;;LCLORPRC;;;AU) defaultHidingValue: TRUE objectCategory: CN=Class-Schema,${SCHEMADN} defaultObjectCategory: CN=ms-Exch-Oma-Carrier,${SCHEMADN} # # ms-Exch-Oma-Configuration-Container # The parent container for all OMA configuration data. # dn: CN=ms-Exch-Oma-Configuration-Container,${SCHEMADN} objectClass: top objectClass: classSchema cn: ms-Exch-Oma-Configuration-Container distinguishedName: CN=ms-Exch-Oma-Configuration-Container,${SCHEMADN} subClassOf: container governsID: 1.2.840.113556.1.6.20.2.32 mayContain: msExchMinAdminVersion mayContain: msExchOmaExtendedProperties mayContain: msExchOmaAdminWirelessEnable rDNAttID: cn showInAdvancedViewOnly: TRUE adminDisplayName: ms-Exch-Oma-Configuration-Container adminDescription: ms-Exch-Oma-Configuration-Container objectClassCategory: 1 lDAPDisplayName: msExchOmaConfigurationContainer name: ms-Exch-Oma-Configuration-Container schemaIDGUID: db0f9abb-0770-4f09-ba64-7993d91517b7 systemOnly: FALSE defaultSecurityDescriptor: D:(A;;LCLORPRC;;;AU) defaultHidingValue: TRUE objectCategory: CN=Class-Schema,${SCHEMADN} defaultObjectCategory: CN=ms-Exch-Oma-Configuration-Container,${SCHEMADN} # # ms-Exch-Oma-Container # The parent container for OMA device types. # dn: CN=ms-Exch-Oma-Container,${SCHEMADN} objectClass: top objectClass: classSchema cn: ms-Exch-Oma-Container distinguishedName: CN=ms-Exch-Oma-Container,${SCHEMADN} subClassOf: container governsID: 1.2.840.113556.1.6.20.2.38 mayContain: msExchMinAdminVersion mayContain: msExchOmaExtendedProperties rDNAttID: cn showInAdvancedViewOnly: TRUE adminDisplayName: ms-Exch-Oma-Container adminDescription: ms-Exch-Oma-Container objectClassCategory: 1 lDAPDisplayName: msExchOmaContainer name: ms-Exch-Oma-Container schemaIDGUID: 863dab20-fb40-43a4-a5e1-825b2071050f systemOnly: FALSE defaultSecurityDescriptor: D:S: defaultHidingValue: TRUE objectCategory: CN=Class-Schema,${SCHEMADN} defaultObjectCategory: CN=ms-Exch-Oma-Container,${SCHEMADN} # # ms-Exch-Oma-Data-Source # Contains information about business logic that can validate a push # notification. # dn: CN=ms-Exch-Oma-Data-Source,${SCHEMADN} objectClass: top objectClass: classSchema cn: ms-Exch-Oma-Data-Source distinguishedName: CN=ms-Exch-Oma-Data-Source,${SCHEMADN} subClassOf: container governsID: 1.2.840.113556.1.6.20.2.35 mayContain: msExchOmaValidater mayContain: msExchOmaExtendedProperties mayContain: msExchOmaDeviceCapabilityDN mayContain: msExchOmaDeliveryProviderDN mayContain: msExchOmaConfiguration rDNAttID: cn showInAdvancedViewOnly: TRUE adminDisplayName: ms-Exch-Oma-Data-Source adminDescription: ms-Exch-Oma-Data-Source objectClassCategory: 1 lDAPDisplayName: msExchOmaDataSource name: ms-Exch-Oma-Data-Source schemaIDGUID: dda38a4d-972a-44a2-9244-0acb4b1d34d1 systemOnly: FALSE defaultSecurityDescriptor: D:(A;;LCLORPRC;;;AU) defaultHidingValue: TRUE objectCategory: CN=Class-Schema,${SCHEMADN} defaultObjectCategory: CN=ms-Exch-Oma-Data-Source,${SCHEMADN} # # ms-Exch-Oma-Delivery-Provider # Contains delivery protocol information. # dn: CN=ms-Exch-Oma-Delivery-Provider,${SCHEMADN} objectClass: top objectClass: classSchema cn: ms-Exch-Oma-Delivery-Provider distinguishedName: CN=ms-Exch-Oma-Delivery-Provider,${SCHEMADN} subClassOf: container governsID: 1.2.840.113556.1.6.20.2.36 mayContain: msExchOmaExtendedProperties mayContain: msExchOmaDeviceCapabilityDN mayContain: msExchOmaDeliverer mayContain: msExchOmaConfiguration rDNAttID: cn showInAdvancedViewOnly: TRUE adminDisplayName: ms-Exch-Oma-Delivery-Provider adminDescription: ms-Exch-Oma-Delivery-Provider objectClassCategory: 1 lDAPDisplayName: msExchOmaDeliveryProvider name: ms-Exch-Oma-Delivery-Provider schemaIDGUID: cdbf130d-c7e2-4572-94b0-fc9be7eef953 systemOnly: FALSE defaultSecurityDescriptor: D:S: defaultHidingValue: TRUE objectCategory: CN=Class-Schema,${SCHEMADN} defaultObjectCategory: CN=ms-Exch-Oma-Delivery-Provider,${SCHEMADN} # # ms-Exch-Oma-Device-Capability # Device support for an application (such as SMS Text). # dn: CN=ms-Exch-Oma-Device-Capability,${SCHEMADN} objectClass: top objectClass: classSchema cn: ms-Exch-Oma-Device-Capability distinguishedName: CN=ms-Exch-Oma-Device-Capability,${SCHEMADN} subClassOf: container governsID: 1.2.840.113556.1.6.20.2.34 mayContain: msExchOmaFormatter mayContain: msExchOmaExtendedProperties rDNAttID: cn showInAdvancedViewOnly: TRUE adminDisplayName: ms-Exch-Oma-Device-Capability adminDescription: ms-Exch-Oma-Device-Capability objectClassCategory: 1 lDAPDisplayName: msExchOmaDeviceCapability name: ms-Exch-Oma-Device-Capability schemaIDGUID: df7af4df-f318-4e2c-ac43-be5b4894711c systemOnly: FALSE defaultSecurityDescriptor: D:(A;;LCLORPRC;;;AU) defaultHidingValue: TRUE objectCategory: CN=Class-Schema,${SCHEMADN} defaultObjectCategory: CN=ms-Exch-Oma-Device-Capability,${SCHEMADN} # # ms-Exch-Oma-Device-Type # Contains the make and model of a wireless device with # characteristics. # dn: CN=ms-Exch-Oma-Device-Type,${SCHEMADN} objectClass: top objectClass: classSchema cn: ms-Exch-Oma-Device-Type distinguishedName: CN=ms-Exch-Oma-Device-Type,${SCHEMADN} subClassOf: container governsID: 1.2.840.113556.1.6.20.2.33 mayContain: msExchOmaExtendedProperties mayContain: msExchOmaDeviceCapabilityDN rDNAttID: cn showInAdvancedViewOnly: TRUE adminDisplayName: ms-Exch-Oma-Device-Type adminDescription: ms-Exch-Oma-Device-Type objectClassCategory: 1 lDAPDisplayName: msExchOmaDeviceType name: ms-Exch-Oma-Device-Type schemaIDGUID: ca7a8fb3-21d0-4ea7-af3f-d15c6df7c094 systemOnly: FALSE defaultSecurityDescriptor: D:(A;;LCLORPRC;;;AU) defaultHidingValue: TRUE objectCategory: CN=Class-Schema,${SCHEMADN} defaultObjectCategory: CN=ms-Exch-Oma-Device-Type,${SCHEMADN} # # ms-Exch-Oma-User # Extends the Active Directory User. # dn: CN=ms-Exch-Oma-User,${SCHEMADN} objectClass: top objectClass: classSchema cn: ms-Exch-Oma-User distinguishedName: CN=ms-Exch-Oma-User,${SCHEMADN} subClassOf: top governsID: 1.2.840.113556.1.6.20.2.31 mayContain: msExchOmaAdminWirelessEnable mayContain: msExchOmaAdminExtendedSettings rDNAttID: cn showInAdvancedViewOnly: TRUE adminDisplayName: ms-Exch-Oma-User adminDescription: ms-Exch-Oma-User objectClassCategory: 3 lDAPDisplayName: msExchOmaUser name: ms-Exch-Oma-User schemaIDGUID: 36a0a976-dd8d-4aad-81fd-a1b5d4016ca8 systemOnly: FALSE defaultSecurityDescriptor: D:S: defaultHidingValue: TRUE objectCategory: CN=Class-Schema,${SCHEMADN} defaultObjectCategory: CN=ms-Exch-Oma-User,${SCHEMADN} # # ms-Exch-PF-Tree # dn: CN=ms-Exch-PF-Tree,${SCHEMADN} objectClass: top objectClass: classSchema cn: ms-Exch-PF-Tree distinguishedName: CN=ms-Exch-PF-Tree,${SCHEMADN} possSuperiors: container subClassOf: top governsID: 1.2.840.113556.1.5.7000.62.11003 mayContain: msExchMinAdminVersion mayContain: msExchPfCreation mayContain: msExchAllowEnhancedSecurity mayContain: msExchOwningPFTreeBL mayContain: msExchPFDefaultAdminACL mayContain: msExchPFTreeType mayContain: msExchPFDSContainer mayContain: displayName mayContain: description rDNAttID: cn showInAdvancedViewOnly: TRUE adminDisplayName: ms-Exch-PF-Tree adminDescription: ms-Exch-PF-Tree auxiliaryClass: msExchBaseClass objectClassCategory: 1 lDAPDisplayName: msExchPFTree name: ms-Exch-PF-Tree schemaIDGUID: 364d9564-a982-11d2-a9ff-00c04f8eedd8 systemOnly: FALSE defaultSecurityDescriptor: D:S: defaultHidingValue: TRUE objectCategory: CN=Class-Schema,${SCHEMADN} defaultObjectCategory: CN=ms-Exch-PF-Tree,${SCHEMADN} # # ms-Exch-Private-MDB-Policy # dn: CN=ms-Exch-Private-MDB-Policy,${SCHEMADN} objectClass: top objectClass: classSchema cn: ms-Exch-Private-MDB-Policy distinguishedName: CN=ms-Exch-Private-MDB-Policy,${SCHEMADN} possSuperiors: container subClassOf: msExchPrivateMDB governsID: 1.2.840.113556.1.5.7000.62.50003 mayContain: msExchPolicyLastAppliedTime mayContain: msExchPolicyOptionList mayContain: msExchPolicyLockDown mayContain: msExchPolicyListBL mayContain: msExchPolicyDefault rDNAttID: cn showInAdvancedViewOnly: TRUE adminDisplayName: ms-Exch-Private-MDB-Policy adminDescription: ms-Exch-Private-MDB-Policy auxiliaryClass: msExchBaseClass objectClassCategory: 1 lDAPDisplayName: msExchPrivateMDBPolicy name: ms-Exch-Private-MDB-Policy schemaIDGUID: 35db2484-a982-11d2-a9ff-00c04f8eedd8 systemOnly: FALSE defaultSecurityDescriptor: D:S: defaultHidingValue: TRUE objectCategory: CN=Class-Schema,${SCHEMADN} defaultObjectCategory: CN=ms-Exch-Private-MDB-Policy,${SCHEMADN} # # ms-Exch-Private-MDB-Proxy # dn: CN=ms-Exch-Private-MDB-Proxy,${SCHEMADN} objectClass: top objectClass: classSchema cn: ms-Exch-Private-MDB-Proxy distinguishedName: CN=ms-Exch-Private-MDB-Proxy,${SCHEMADN} possSuperiors: msExchContainer subClassOf: top governsID: 1.2.840.113556.1.5.7000.62.11007 rDNAttID: cn showInAdvancedViewOnly: TRUE adminDisplayName: ms-Exch-Private-MDB-Proxy adminDescription: ms-Exch-Private-MDB-Proxy auxiliaryClass: msExchMailStorage auxiliaryClass: msExchBaseClass auxiliaryClass: mailRecipient objectClassCategory: 1 lDAPDisplayName: msExchPrivateMDBProxy name: ms-Exch-Private-MDB-Proxy schemaIDGUID: b8d47e54-4b78-11d3-aa75-00c04f8eedd8 systemOnly: FALSE defaultSecurityDescriptor: D:S: defaultHidingValue: TRUE objectCategory: CN=Class-Schema,${SCHEMADN} defaultObjectCategory: CN=ms-Exch-Private-MDB-Proxy,${SCHEMADN} # # ms-Exch-Protocol-Cfg-HTTP-Filter # The Exchange HTTP service filters. # dn: CN=ms-Exch-Protocol-Cfg-HTTP-Filter,${SCHEMADN} objectClass: top objectClass: classSchema cn: ms-Exch-Protocol-Cfg-HTTP-Filter distinguishedName: CN=ms-Exch-Protocol-Cfg-HTTP-Filter,${SCHEMADN} possSuperiors: msExchProtocolCfgHTTPFilters subClassOf: top governsID: 1.2.840.113556.1.5.7000.62.15003 rDNAttID: cn showInAdvancedViewOnly: TRUE adminDisplayName: ms-Exch-Protocol-Cfg-HTTP-Filter adminDescription: ms-Exch-Protocol-Cfg-HTTP-Filter auxiliaryClass: msExchBaseClass objectClassCategory: 1 lDAPDisplayName: msExchProtocolCfgHTTPFilter name: ms-Exch-Protocol-Cfg-HTTP-Filter schemaIDGUID: 8c7588c0-b09e-11d2-aa06-00c04f8eedd8 systemOnly: FALSE defaultSecurityDescriptor: D:S: defaultHidingValue: TRUE objectCategory: CN=Class-Schema,${SCHEMADN} defaultObjectCategory: CN=ms-Exch-Protocol-Cfg-HTTP-Filter,${SCHEMADN} # # ms-Exch-Protocol-Cfg-HTTP-Site # dn: CN=ms-Exch-Protocol-Cfg-HTTP-Site,${SCHEMADN} objectClass: top objectClass: classSchema cn: ms-Exch-Protocol-Cfg-HTTP-Site distinguishedName: CN=ms-Exch-Protocol-Cfg-HTTP-Site,${SCHEMADN} possSuperiors: protocolCfgSharedSite subClassOf: protocolCfgHTTP governsID: 1.2.840.113556.1.3.81 rDNAttID: cn showInAdvancedViewOnly: TRUE adminDisplayName: ms-Exch-Protocol-Cfg-HTTP-Site adminDescription: ms-Exch-Protocol-Cfg-HTTP-Site auxiliaryClass: msExchBaseClass objectClassCategory: 1 lDAPDisplayName: protocolCfgHTTPSite name: ms-Exch-Protocol-Cfg-HTTP-Site schemaIDGUID: a8df74c3-c5ea-11d1-bbcb-0080c76670c0 systemOnly: FALSE defaultSecurityDescriptor: D:S: defaultHidingValue: TRUE objectCategory: CN=Class-Schema,${SCHEMADN} defaultObjectCategory: CN=ms-Exch-Protocol-Cfg-HTTP-Site,${SCHEMADN} # # ms-Exch-Protocol-Cfg-HTTP-Virtual-Directory # The Exchange HTTP virtual directory configuration. # dn: CN=ms-Exch-Protocol-Cfg-HTTP-Virtual-Directory,${SCHEMADN} objectClass: top objectClass: classSchema cn: ms-Exch-Protocol-Cfg-HTTP-Virtual-Directory distinguishedName: CN=ms-Exch-Protocol-Cfg-HTTP-Virtual-Directory,${SCHEMADN} possSuperiors: protocolCfgHTTPServer subClassOf: protocolCfgHTTPServer governsID: 1.2.840.113556.1.5.7000.62.15001 mayContain: msExchBackEndVDirURL rDNAttID: cn showInAdvancedViewOnly: TRUE adminDisplayName: ms-Exch-Protocol-Cfg-HTTP-Virtual-Directory adminDescription: ms-Exch-Protocol-Cfg-HTTP-Virtual-Directory auxiliaryClass: msExchBaseClass objectClassCategory: 1 lDAPDisplayName: msExchProtocolCfgHTTPVirtualDirectory name: ms-Exch-Protocol-Cfg-HTTP-Virtual-Directory schemaIDGUID: 8c3c5050-b09e-11d2-aa06-00c04f8eedd8 systemOnly: FALSE defaultSecurityDescriptor: D:S: defaultHidingValue: TRUE objectCategory: CN=Class-Schema,${SCHEMADN} defaultObjectCategory: CN=ms-Exch-Protocol-Cfg-HTTP-Virtual-Directory,${SCHEMADN} # # ms-Exch-Protocol-Cfg-IMAP-Policy # dn: CN=ms-Exch-Protocol-Cfg-IMAP-Policy,${SCHEMADN} objectClass: top objectClass: classSchema cn: ms-Exch-Protocol-Cfg-IMAP-Policy distinguishedName: CN=ms-Exch-Protocol-Cfg-IMAP-Policy,${SCHEMADN} possSuperiors: container subClassOf: protocolCfgIMAP governsID: 1.2.840.113556.1.5.7000.62.50004 mayContain: msExchPolicyLastAppliedTime mayContain: msExchPolicyOptionList mayContain: msExchPolicyLockDown mayContain: msExchPolicyListBL mayContain: msExchPolicyDefault rDNAttID: cn showInAdvancedViewOnly: TRUE adminDisplayName: ms-Exch-Protocol-Cfg-IMAP-Policy adminDescription: ms-Exch-Protocol-Cfg-IMAP-Policy auxiliaryClass: msExchBaseClass objectClassCategory: 1 lDAPDisplayName: msExchProtocolCfgIMAPPolicy name: ms-Exch-Protocol-Cfg-IMAP-Policy schemaIDGUID: 35f7c0bc-a982-11d2-a9ff-00c04f8eedd8 systemOnly: FALSE defaultSecurityDescriptor: D:S: defaultHidingValue: TRUE objectCategory: CN=Class-Schema,${SCHEMADN} defaultObjectCategory: CN=ms-Exch-Protocol-Cfg-IMAP-Policy,${SCHEMADN} # # ms-Exch-Protocol-Cfg-IMAP-Sessions # dn: CN=ms-Exch-Protocol-Cfg-IMAP-Sessions,${SCHEMADN} objectClass: top objectClass: classSchema cn: ms-Exch-Protocol-Cfg-IMAP-Sessions distinguishedName: CN=ms-Exch-Protocol-Cfg-IMAP-Sessions,${SCHEMADN} possSuperiors: protocolCfgIMAPServer subClassOf: top governsID: 1.2.840.113556.1.5.7000.62.3002 rDNAttID: cn showInAdvancedViewOnly: TRUE adminDisplayName: ms-Exch-Protocol-Cfg-IMAP-Sessions adminDescription: ms-Exch-Protocol-Cfg-IMAP-Sessions auxiliaryClass: msExchBaseClass objectClassCategory: 1 lDAPDisplayName: msExchProtocolCfgIMAPSessions name: ms-Exch-Protocol-Cfg-IMAP-Sessions schemaIDGUID: 99f58672-12e8-11d3-aa58-00c04f8eedd8 systemOnly: FALSE defaultSecurityDescriptor: D:S: defaultHidingValue: TRUE objectCategory: CN=Class-Schema,${SCHEMADN} defaultObjectCategory: CN=ms-Exch-Protocol-Cfg-IMAP-Sessions,${SCHEMADN} # # ms-Exch-Protocol-Cfg-IMAP-Site # dn: CN=ms-Exch-Protocol-Cfg-IMAP-Site,${SCHEMADN} objectClass: top objectClass: classSchema cn: ms-Exch-Protocol-Cfg-IMAP-Site distinguishedName: CN=ms-Exch-Protocol-Cfg-IMAP-Site,${SCHEMADN} possSuperiors: protocolCfgSharedSite subClassOf: protocolCfgIMAP governsID: 1.2.840.113556.1.3.86 rDNAttID: cn showInAdvancedViewOnly: TRUE adminDisplayName: ms-Exch-Protocol-Cfg-IMAP-Site adminDescription: ms-Exch-Protocol-Cfg-IMAP-Site auxiliaryClass: msExchBaseClass objectClassCategory: 1 lDAPDisplayName: protocolCfgIMAPSite name: ms-Exch-Protocol-Cfg-IMAP-Site schemaIDGUID: a8df74c6-c5ea-11d1-bbcb-0080c76670c0 systemOnly: FALSE defaultSecurityDescriptor: D:S: defaultHidingValue: TRUE objectCategory: CN=Class-Schema,${SCHEMADN} defaultObjectCategory: CN=ms-Exch-Protocol-Cfg-IMAP-Site,${SCHEMADN} # # ms-Exch-Protocol-Cfg-IM-Virtual-Server # Contains the attributes that represent an Instant Messaging virtual # server. # dn: CN=ms-Exch-Protocol-Cfg-IM-Virtual-Server,${SCHEMADN} objectClass: top objectClass: classSchema cn: ms-Exch-Protocol-Cfg-IM-Virtual-Server distinguishedName: CN=ms-Exch-Protocol-Cfg-IM-Virtual-Server,${SCHEMADN} possSuperiors: msExchProtocolCfgIMContainer subClassOf: msExchProtocolCfgIM governsID: 1.2.840.113556.1.5.7000.62.7013 mustContain: msExchIMServerIISId mayContain: msExchIMHostName mayContain: flags mayContain: msExchIMServerName mayContain: msExchIMServerHostsUsers rDNAttID: cn showInAdvancedViewOnly: TRUE adminDisplayName: ms-Exch-Protocol-Cfg-IM-Virtual-Server adminDescription: ms-Exch-Protocol-Cfg-IM-Virtual-Server auxiliaryClass: msExchBaseClass objectClassCategory: 1 lDAPDisplayName: msExchProtocolCfgIMVirtualServer name: ms-Exch-Protocol-Cfg-IM-Virtual-Server schemaIDGUID: 9f116eb4-284e-11d3-aa68-00c04f8eedd8 systemOnly: FALSE defaultSecurityDescriptor: D:S: defaultHidingValue: TRUE objectCategory: CN=Class-Schema,${SCHEMADN} defaultObjectCategory: CN=ms-Exch-Protocol-Cfg-IM-Virtual-Server,${SCHEMADN} # # ms-Exch-Protocol-Cfg-LDAP-Server # dn: CN=ms-Exch-Protocol-Cfg-LDAP-Server,${SCHEMADN} objectClass: top objectClass: classSchema cn: ms-Exch-Protocol-Cfg-LDAP-Server distinguishedName: CN=ms-Exch-Protocol-Cfg-LDAP-Server,${SCHEMADN} possSuperiors: msExchProtocolCfgProtocolContainer possSuperiors: protocolCfgSharedServer subClassOf: protocolCfgLDAP governsID: 1.2.840.113556.1.3.77 mayContain: referralList rDNAttID: cn showInAdvancedViewOnly: TRUE adminDisplayName: ms-Exch-Protocol-Cfg-LDAP-Server adminDescription: ms-Exch-Protocol-Cfg-LDAP-Server auxiliaryClass: msExchBaseClass objectClassCategory: 1 lDAPDisplayName: protocolCfgLDAPServer name: ms-Exch-Protocol-Cfg-LDAP-Server schemaIDGUID: a8df74c8-c5ea-11d1-bbcb-0080c76670c0 systemOnly: FALSE defaultSecurityDescriptor: D:S: defaultHidingValue: TRUE objectCategory: CN=Class-Schema,${SCHEMADN} defaultObjectCategory: CN=ms-Exch-Protocol-Cfg-LDAP-Server,${SCHEMADN} # # ms-Exch-Protocol-Cfg-LDAP-Site # dn: CN=ms-Exch-Protocol-Cfg-LDAP-Site,${SCHEMADN} objectClass: top objectClass: classSchema cn: ms-Exch-Protocol-Cfg-LDAP-Site distinguishedName: CN=ms-Exch-Protocol-Cfg-LDAP-Site,${SCHEMADN} possSuperiors: protocolCfgSharedSite subClassOf: protocolCfgLDAP governsID: 1.2.840.113556.1.3.76 mayContain: referralList rDNAttID: cn showInAdvancedViewOnly: TRUE adminDisplayName: ms-Exch-Protocol-Cfg-LDAP-Site adminDescription: ms-Exch-Protocol-Cfg-LDAP-Site auxiliaryClass: msExchBaseClass objectClassCategory: 1 lDAPDisplayName: protocolCfgLDAPSite name: ms-Exch-Protocol-Cfg-LDAP-Site schemaIDGUID: a8df74c9-c5ea-11d1-bbcb-0080c76670c0 systemOnly: FALSE defaultSecurityDescriptor: D:S: defaultHidingValue: TRUE objectCategory: CN=Class-Schema,${SCHEMADN} defaultObjectCategory: CN=ms-Exch-Protocol-Cfg-LDAP-Site,${SCHEMADN} # # ms-Exch-Protocol-Cfg-NNTP-Server # dn: CN=ms-Exch-Protocol-Cfg-NNTP-Server,${SCHEMADN} objectClass: top objectClass: classSchema cn: ms-Exch-Protocol-Cfg-NNTP-Server distinguishedName: CN=ms-Exch-Protocol-Cfg-NNTP-Server,${SCHEMADN} possSuperiors: msExchProtocolCfgNNTPContainer subClassOf: protocolCfgNNTP governsID: 1.2.840.113556.1.3.74 rDNAttID: cn showInAdvancedViewOnly: TRUE adminDisplayName: ms-Exch-Protocol-Cfg-NNTP-Server adminDescription: ms-Exch-Protocol-Cfg-NNTP-Server auxiliaryClass: msExchBaseClass objectClassCategory: 1 lDAPDisplayName: protocolCfgNNTPServer name: ms-Exch-Protocol-Cfg-NNTP-Server schemaIDGUID: a8df74cb-c5ea-11d1-bbcb-0080c76670c0 systemOnly: FALSE defaultSecurityDescriptor: D:S: defaultHidingValue: TRUE objectCategory: CN=Class-Schema,${SCHEMADN} defaultObjectCategory: CN=ms-Exch-Protocol-Cfg-NNTP-Server,${SCHEMADN} # # ms-Exch-Protocol-Cfg-NNTP-Site # dn: CN=ms-Exch-Protocol-Cfg-NNTP-Site,${SCHEMADN} objectClass: top objectClass: classSchema cn: ms-Exch-Protocol-Cfg-NNTP-Site distinguishedName: CN=ms-Exch-Protocol-Cfg-NNTP-Site,${SCHEMADN} possSuperiors: protocolCfgSharedSite subClassOf: protocolCfgNNTP governsID: 1.2.840.113556.1.3.73 rDNAttID: cn showInAdvancedViewOnly: TRUE adminDisplayName: ms-Exch-Protocol-Cfg-NNTP-Site adminDescription: ms-Exch-Protocol-Cfg-NNTP-Site auxiliaryClass: msExchBaseClass objectClassCategory: 1 lDAPDisplayName: protocolCfgNNTPSite name: ms-Exch-Protocol-Cfg-NNTP-Site schemaIDGUID: a8df74cc-c5ea-11d1-bbcb-0080c76670c0 systemOnly: FALSE defaultSecurityDescriptor: D:S: defaultHidingValue: TRUE objectCategory: CN=Class-Schema,${SCHEMADN} defaultObjectCategory: CN=ms-Exch-Protocol-Cfg-NNTP-Site,${SCHEMADN} # # ms-Exch-Protocol-Cfg-POP # dn: CN=ms-Exch-Protocol-Cfg-POP,${SCHEMADN} objectClass: top objectClass: classSchema cn: ms-Exch-Protocol-Cfg-POP distinguishedName: CN=ms-Exch-Protocol-Cfg-POP,${SCHEMADN} possSuperiors: protocolCfgSharedSite possSuperiors: protocolCfgSharedServer subClassOf: protocolCfg governsID: 1.2.840.113556.1.3.69 mayContain: msExchLogonACL mayContain: msExchServerBindings mayContain: msExchSecureBindings mayContain: oWAServer mayContain: formData mayContain: folderPathname mayContain: helpData32 rDNAttID: cn showInAdvancedViewOnly: TRUE adminDisplayName: ms-Exch-Protocol-Cfg-POP adminDescription: ms-Exch-Protocol-Cfg-POP auxiliaryClass: msExchBaseClass objectClassCategory: 1 lDAPDisplayName: protocolCfgPOP name: ms-Exch-Protocol-Cfg-POP schemaIDGUID: a8df74cd-c5ea-11d1-bbcb-0080c76670c0 systemOnly: FALSE defaultSecurityDescriptor: D:S: defaultHidingValue: TRUE objectCategory: CN=Class-Schema,${SCHEMADN} defaultObjectCategory: CN=ms-Exch-Protocol-Cfg-POP,${SCHEMADN} # # ms-Exch-Protocol-Cfg-SMTP-Domain # Contains domain level settings under an SMTP virtual server. # dn: CN=ms-Exch-Protocol-Cfg-SMTP-Domain,${SCHEMADN} objectClass: top objectClass: classSchema cn: ms-Exch-Protocol-Cfg-SMTP-Domain distinguishedName: CN=ms-Exch-Protocol-Cfg-SMTP-Domain,${SCHEMADN} possSuperiors: protocolCfgSMTPDomainContainer subClassOf: top governsID: 1.2.840.113556.1.5.7000.62.5006 mayContain: msExchEncryptedPassword mayContain: msExchSecurityPassword mayContain: msExchSmtpSmartHost mayContain: msExchSmtpOutboundSecurityUserName mayContain: msExchSmtpOutboundSecurityPassword mayContain: msExchSmtpOutboundSecurityFlag mayContain: msExchSmtpDropDirectory mayContain: msExchSmtpDomainString mayContain: msExchSmtpAuthorizedTRNAccounts mayContain: sendTNEF mayContain: msExchRoutingDisplaySenderEnabled mayContain: msExchRoutingAcceptMessageType mayContain: msExchDefaultDomain mayContain: contentType mayContain: characterSet rDNAttID: cn showInAdvancedViewOnly: TRUE adminDisplayName: ms-Exch-Protocol-Cfg-SMTP-Domain adminDescription: ms-Exch-Protocol-Cfg-SMTP-Domain auxiliaryClass: msExchBaseClass objectClassCategory: 1 lDAPDisplayName: protocolCfgSMTPDomain name: ms-Exch-Protocol-Cfg-SMTP-Domain schemaIDGUID: 33d82894-a982-11d2-a9ff-00c04f8eedd8 systemOnly: FALSE defaultSecurityDescriptor: D:S: defaultHidingValue: TRUE objectCategory: CN=Class-Schema,${SCHEMADN} defaultObjectCategory: CN=ms-Exch-Protocol-Cfg-SMTP-Domain,${SCHEMADN} # # ms-Exch-Protocol-Cfg-SMTP-IP-Address # dn: CN=ms-Exch-Protocol-Cfg-SMTP-IP-Address,${SCHEMADN} objectClass: top objectClass: classSchema cn: ms-Exch-Protocol-Cfg-SMTP-IP-Address distinguishedName: CN=ms-Exch-Protocol-Cfg-SMTP-IP-Address,${SCHEMADN} possSuperiors: msExchProtocolCfgSMTPIPAddressContainer subClassOf: top governsID: 1.2.840.113556.1.5.7000.62.5009 mayContain: msExchTurfList mayContain: msExchIPAddress rDNAttID: cn showInAdvancedViewOnly: TRUE adminDisplayName: ms-Exch-Protocol-Cfg-SMTP-IP-Address adminDescription: ms-Exch-Protocol-Cfg-SMTP-IP-Address auxiliaryClass: msExchBaseClass objectClassCategory: 1 lDAPDisplayName: msExchProtocolCfgSMTPIPAddress name: ms-Exch-Protocol-Cfg-SMTP-IP-Address schemaIDGUID: 8b7b31d6-b09e-11d2-aa06-00c04f8eedd8 systemOnly: FALSE defaultSecurityDescriptor: D:S: defaultHidingValue: TRUE objectCategory: CN=Class-Schema,${SCHEMADN} defaultObjectCategory: CN=ms-Exch-Protocol-Cfg-SMTP-IP-Address,${SCHEMADN} # # ms-Exch-Protocol-Cfg-SMTP-Policy # dn: CN=ms-Exch-Protocol-Cfg-SMTP-Policy,${SCHEMADN} objectClass: top objectClass: classSchema cn: ms-Exch-Protocol-Cfg-SMTP-Policy distinguishedName: CN=ms-Exch-Protocol-Cfg-SMTP-Policy,${SCHEMADN} possSuperiors: container subClassOf: protocolCfgSMTP governsID: 1.2.840.113556.1.5.7000.62.50006 mayContain: msExchPolicyLastAppliedTime mayContain: msExchPolicyOptionList mayContain: msExchPolicyLockDown mayContain: msExchPolicyListBL mayContain: msExchPolicyDefault rDNAttID: cn showInAdvancedViewOnly: TRUE adminDisplayName: ms-Exch-Protocol-Cfg-SMTP-Policy adminDescription: ms-Exch-Protocol-Cfg-SMTP-Policy auxiliaryClass: msExchBaseClass objectClassCategory: 1 lDAPDisplayName: msExchProtocolCfgSMTPPolicy name: ms-Exch-Protocol-Cfg-SMTP-Policy schemaIDGUID: 359f89ba-a982-11d2-a9ff-00c04f8eedd8 systemOnly: FALSE defaultSecurityDescriptor: D:S: defaultHidingValue: TRUE objectCategory: CN=Class-Schema,${SCHEMADN} defaultObjectCategory: CN=ms-Exch-Protocol-Cfg-SMTP-Policy,${SCHEMADN} # # ms-Exch-Protocol-Cfg-SMTP-Routing-Sources # Contains information about the unused sources for routing outbound # mail. # dn: CN=ms-Exch-Protocol-Cfg-SMTP-Routing-Sources,${SCHEMADN} objectClass: top objectClass: classSchema cn: ms-Exch-Protocol-Cfg-SMTP-Routing-Sources distinguishedName: CN=ms-Exch-Protocol-Cfg-SMTP-Routing-Sources,${SCHEMADN} possSuperiors: protocolCfgSMTPServer subClassOf: top governsID: 1.2.840.113556.1.5.7000.62.5005 mayContain: msExchMinAdminVersion mayContain: msExchSmtpRoutingTableType mayContain: msExchSmtpLdapSchemaType mayContain: msExchSmtpLdapPassword mayContain: msExchSmtpLdapNamingContext mayContain: msExchSmtpLdapBindType mayContain: msExchSmtpLdapAccount mayContain: msExchSmtpEnableLdapRouting mayContain: msExchSmtpDsPort mayContain: msExchSmtpDsHost mayContain: msExchSmtpDsFlags mayContain: msExchSmtpDsDomain mayContain: msExchSmtpDsDefaultMailRoot mayContain: msExchSmtpDsDataDirectory rDNAttID: cn showInAdvancedViewOnly: TRUE adminDisplayName: ms-Exch-Protocol-Cfg-SMTP-Routing-Sources adminDescription: ms-Exch-Protocol-Cfg-SMTP-Routing-Sources auxiliaryClass: msExchBaseClass objectClassCategory: 1 lDAPDisplayName: protocolCfgSMTPRoutingSources name: ms-Exch-Protocol-Cfg-SMTP-Routing-Sources schemaIDGUID: 3397c916-a982-11d2-a9ff-00c04f8eedd8 systemOnly: FALSE defaultSecurityDescriptor: D:S: defaultHidingValue: TRUE objectCategory: CN=Class-Schema,${SCHEMADN} defaultObjectCategory: CN=ms-Exch-Protocol-Cfg-SMTP-Routing-Sources,${SCHEMADN} # # ms-Exch-Protocol-Cfg-SMTP-Sessions # dn: CN=ms-Exch-Protocol-Cfg-SMTP-Sessions,${SCHEMADN} objectClass: top objectClass: classSchema cn: ms-Exch-Protocol-Cfg-SMTP-Sessions distinguishedName: CN=ms-Exch-Protocol-Cfg-SMTP-Sessions,${SCHEMADN} possSuperiors: protocolCfgSMTPServer subClassOf: top governsID: 1.2.840.113556.1.5.7000.62.5007 mayContain: msExchMinAdminVersion rDNAttID: cn showInAdvancedViewOnly: TRUE adminDisplayName: ms-Exch-Protocol-Cfg-SMTP-Sessions adminDescription: ms-Exch-Protocol-Cfg-SMTP-Sessions auxiliaryClass: msExchBaseClass objectClassCategory: 1 lDAPDisplayName: protocolCfgSMTPSessions name: ms-Exch-Protocol-Cfg-SMTP-Sessions schemaIDGUID: 8ef628c6-b093-11d2-aa06-00c04f8eedd8 systemOnly: FALSE defaultSecurityDescriptor: D:S: defaultHidingValue: TRUE objectCategory: CN=Class-Schema,${SCHEMADN} defaultObjectCategory: CN=ms-Exch-Protocol-Cfg-SMTP-Sessions,${SCHEMADN} # # ms-Exch-Protocol-Cfg-SMTP-Site # Contains settings for legacy site SMTP settings. # dn: CN=ms-Exch-Protocol-Cfg-SMTP-Site,${SCHEMADN} objectClass: top objectClass: classSchema cn: ms-Exch-Protocol-Cfg-SMTP-Site distinguishedName: CN=ms-Exch-Protocol-Cfg-SMTP-Site,${SCHEMADN} possSuperiors: protocolCfgSharedSite subClassOf: protocolCfgSMTP governsID: 1.2.840.113556.1.5.7000.62.5003 rDNAttID: cn showInAdvancedViewOnly: TRUE adminDisplayName: ms-Exch-Protocol-Cfg-SMTP-Site adminDescription: ms-Exch-Protocol-Cfg-SMTP-Site auxiliaryClass: msExchBaseClass objectClassCategory: 1 lDAPDisplayName: protocolCfgSMTPSite name: ms-Exch-Protocol-Cfg-SMTP-Site schemaIDGUID: 32f0e47a-a982-11d2-a9ff-00c04f8eedd8 systemOnly: FALSE defaultSecurityDescriptor: D:S: defaultHidingValue: TRUE objectCategory: CN=Class-Schema,${SCHEMADN} defaultObjectCategory: CN=ms-Exch-Protocol-Cfg-SMTP-Site,${SCHEMADN} # # ms-Exch-Pseudo-PF # Used internally by the store. # dn: CN=ms-Exch-Pseudo-PF,${SCHEMADN} objectClass: top objectClass: classSchema cn: ms-Exch-Pseudo-PF distinguishedName: CN=ms-Exch-Pseudo-PF,${SCHEMADN} subClassOf: top governsID: 1.2.840.113556.1.5.7000.62.50030 rDNAttID: cn showInAdvancedViewOnly: TRUE adminDisplayName: ms-Exch-Pseudo-PF adminDescription: ms-Exch-Pseudo-PF auxiliaryClass: msExchBaseClass objectClassCategory: 1 lDAPDisplayName: msExchPseudoPF name: ms-Exch-Pseudo-PF schemaIDGUID: cec4472b-22ae-11d3-aa62-00c04f8eedd8 systemOnly: FALSE defaultSecurityDescriptor: D:S: defaultHidingValue: TRUE objectCategory: CN=Class-Schema,${SCHEMADN} defaultObjectCategory: CN=ms-Exch-Pseudo-PF,${SCHEMADN} # # ms-Exch-Pseudo-PF-Admin # Used internally by the store. # dn: CN=ms-Exch-Pseudo-PF-Admin,${SCHEMADN} objectClass: top objectClass: classSchema cn: ms-Exch-Pseudo-PF-Admin distinguishedName: CN=ms-Exch-Pseudo-PF-Admin,${SCHEMADN} subClassOf: top governsID: 1.2.840.113556.1.5.7000.62.50029 rDNAttID: cn showInAdvancedViewOnly: TRUE adminDisplayName: ms-Exch-Pseudo-PF-Admin adminDescription: ms-Exch-Pseudo-PF-Admin auxiliaryClass: msExchBaseClass objectClassCategory: 1 lDAPDisplayName: msExchPseudoPFAdmin name: ms-Exch-Pseudo-PF-Admin schemaIDGUID: 9ae2fa1b-22b0-11d3-aa62-00c04f8eedd8 systemOnly: FALSE defaultSecurityDescriptor: D:S: defaultHidingValue: TRUE objectCategory: CN=Class-Schema,${SCHEMADN} defaultObjectCategory: CN=ms-Exch-Pseudo-PF-Admin,${SCHEMADN} # # ms-Exch-Public-Folder # A representation of a public folder. # dn: CN=ms-Exch-Public-Folder,${SCHEMADN} objectClass: top objectClass: classSchema cn: ms-Exch-Public-Folder distinguishedName: CN=ms-Exch-Public-Folder,${SCHEMADN} possSuperiors: msExchSystemObjectsContainer possSuperiors: organizationalUnit possSuperiors: domainDNS possSuperiors: container subClassOf: top governsID: 1.2.840.113556.1.3.15 mayContain: pFContacts mayContain: msExchPFTreeType mayContain: title mayContain: co mayContain: st mayContain: physicalDeliveryOfficeName mayContain: l mayContain: department mayContain: company rDNAttID: cn showInAdvancedViewOnly: TRUE adminDisplayName: ms-Exch-Public-Folder adminDescription: ms-Exch-Public-Folder auxiliaryClass: msExchBaseClass auxiliaryClass: msExchMailStorage auxiliaryClass: msExchCustomAttributes auxiliaryClass: mailRecipient objectClassCategory: 1 lDAPDisplayName: publicFolder name: ms-Exch-Public-Folder schemaIDGUID: f0f8ffac-1191-11d0-a060-00aa006c33ed systemOnly: FALSE defaultSecurityDescriptor: D:(OA;;RP;59ba2f42-79a2-11d0-9020-00c04fc2d3cf;;AU) defaultHidingValue: TRUE objectCategory: CN=Class-Schema,${SCHEMADN} defaultObjectCategory: CN=ms-Exch-Public-Folder,${SCHEMADN} # # ms-Exch-Public-Folder-Tree-Container # A container used to hold public folders. Used for extended rights and # roles. # dn: CN=ms-Exch-Public-Folder-Tree-Container,${SCHEMADN} objectClass: top objectClass: classSchema cn: ms-Exch-Public-Folder-Tree-Container distinguishedName: CN=ms-Exch-Public-Folder-Tree-Container,${SCHEMADN} possSuperiors: msExchAdminGroup subClassOf: container governsID: 1.2.840.113556.1.5.7000.62.50015 rDNAttID: cn showInAdvancedViewOnly: TRUE adminDisplayName: ms-Exch-Public-Folder-Tree-Container adminDescription: ms-Exch-Public-Folder-Tree-Container auxiliaryClass: msExchBaseClass objectClassCategory: 1 lDAPDisplayName: msExchPublicFolderTreeContainer name: ms-Exch-Public-Folder-Tree-Container schemaIDGUID: 3582ed82-a982-11d2-a9ff-00c04f8eedd8 systemOnly: FALSE defaultSecurityDescriptor: D:S: defaultHidingValue: TRUE objectCategory: CN=Class-Schema,${SCHEMADN} defaultObjectCategory: CN=ms-Exch-Public-Folder-Tree-Container,${SCHEMADN} # # ms-Exch-Public-MDB-Policy # dn: CN=ms-Exch-Public-MDB-Policy,${SCHEMADN} objectClass: top objectClass: classSchema cn: ms-Exch-Public-MDB-Policy distinguishedName: CN=ms-Exch-Public-MDB-Policy,${SCHEMADN} possSuperiors: container subClassOf: msExchPublicMDB governsID: 1.2.840.113556.1.5.7000.62.50002 mayContain: msExchPolicyLastAppliedTime mayContain: msExchPolicyOptionList mayContain: msExchPolicyLockDown mayContain: msExchPolicyListBL mayContain: msExchPolicyDefault rDNAttID: cn showInAdvancedViewOnly: TRUE adminDisplayName: ms-Exch-Public-MDB-Policy adminDescription: ms-Exch-Public-MDB-Policy auxiliaryClass: msExchBaseClass objectClassCategory: 1 lDAPDisplayName: msExchPublicMDBPolicy name: ms-Exch-Public-MDB-Policy schemaIDGUID: 354c176c-a982-11d2-a9ff-00c04f8eedd8 systemOnly: FALSE defaultSecurityDescriptor: D:S: defaultHidingValue: TRUE objectCategory: CN=Class-Schema,${SCHEMADN} defaultObjectCategory: CN=ms-Exch-Public-MDB-Policy,${SCHEMADN} # # ms-Exch-RAS-Stack # The Remote Access Service (RAS) Transport Stack for the MTA. # dn: CN=ms-Exch-RAS-Stack,${SCHEMADN} objectClass: top objectClass: classSchema cn: ms-Exch-RAS-Stack distinguishedName: CN=ms-Exch-RAS-Stack,${SCHEMADN} possSuperiors: mTA possSuperiors: container possSuperiors: computer subClassOf: transportStack governsID: 1.2.840.113556.1.3.26 mayContain: rASCallbackNumber mayContain: encrypt rDNAttID: cn showInAdvancedViewOnly: TRUE adminDisplayName: ms-Exch-RAS-Stack adminDescription: ms-Exch-RAS-Stack auxiliaryClass: msExchBaseClass objectClassCategory: 1 lDAPDisplayName: rASStack name: ms-Exch-RAS-Stack schemaIDGUID: a8df74d3-c5ea-11d1-bbcb-0080c76670c0 systemOnly: FALSE defaultSecurityDescriptor: D:S: defaultHidingValue: TRUE objectCategory: CN=Class-Schema,${SCHEMADN} defaultObjectCategory: CN=ms-Exch-RAS-Stack,${SCHEMADN} # # ms-Exch-RAS-X400-Link # Specifies a remote X.400 MTA using a RAS Transport. # dn: CN=ms-Exch-RAS-X400-Link,${SCHEMADN} objectClass: top objectClass: classSchema cn: ms-Exch-RAS-X400-Link distinguishedName: CN=ms-Exch-RAS-X400-Link,${SCHEMADN} possSuperiors: container subClassOf: x400Link governsID: 1.2.840.113556.1.3.34 mayContain: rASRemoteSRVRName mayContain: rASPhonebookEntryName mayContain: rASPhoneNumber mayContain: rASCallbackNumber mayContain: authorizedUser mayContain: authorizedPassword mayContain: authorizedDomain rDNAttID: cn showInAdvancedViewOnly: TRUE adminDisplayName: ms-Exch-RAS-X400-Link adminDescription: ms-Exch-RAS-X400-Link auxiliaryClass: msExchBaseClass objectClassCategory: 1 lDAPDisplayName: rASX400Link name: ms-Exch-RAS-X400-Link schemaIDGUID: a8df74d4-c5ea-11d1-bbcb-0080c76670c0 systemOnly: FALSE defaultSecurityDescriptor: D:S: defaultHidingValue: TRUE objectCategory: CN=Class-Schema,${SCHEMADN} defaultObjectCategory: CN=ms-Exch-RAS-X400-Link,${SCHEMADN} # # ms-Exch-Recipient-Policy # dn: CN=ms-Exch-Recipient-Policy,${SCHEMADN} objectClass: top objectClass: classSchema cn: ms-Exch-Recipient-Policy distinguishedName: CN=ms-Exch-Recipient-Policy,${SCHEMADN} possSuperiors: msExchRecipientPolicyContainer subClassOf: msExchGenericPolicy governsID: 1.2.840.113556.1.5.7000.62.50024 mayContain: msExchMinAdminVersion mayContain: msExchAddressListOU mayContain: msExchNonAuthoritativeDomains mayContain: msExchAppliesToSmtpVS mayContain: msExchProxyGenOptions mayContain: msExchPolicyOrder mayContain: gatewayProxy mayContain: disabledGatewayProxy mayContain: msExchAssociatedAG rDNAttID: cn showInAdvancedViewOnly: TRUE adminDisplayName: ms-Exch-Recipient-Policy adminDescription: ms-Exch-Recipient-Policy auxiliaryClass: msExchMailboxManagerPolicy auxiliaryClass: msExchBaseClass auxiliaryClass: msExchMailStorage auxiliaryClass: msExchCustomAttributes auxiliaryClass: mailRecipient objectClassCategory: 1 lDAPDisplayName: msExchRecipientPolicy name: ms-Exch-Recipient-Policy schemaIDGUID: e32977d8-1d31-11d3-aa5e-00c04f8eedd8 systemOnly: FALSE defaultSecurityDescriptor: D:S: defaultHidingValue: TRUE objectCategory: CN=Class-Schema,${SCHEMADN} defaultObjectCategory: CN=ms-Exch-Recipient-Policy,${SCHEMADN} # # ms-Exch-Replication-Connector # dn: CN=ms-Exch-Replication-Connector,${SCHEMADN} objectClass: top objectClass: classSchema cn: ms-Exch-Replication-Connector distinguishedName: CN=ms-Exch-Replication-Connector,${SCHEMADN} possSuperiors: msExchReplicationConnectorContainer subClassOf: msExchConnector governsID: 1.2.840.113556.1.5.7000.62.11 mayContain: trustLevel mayContain: replicationStagger mayContain: replicationMailMsgSize mayContain: remoteSite mayContain: remoteBridgeHeadAddress mayContain: remoteBridgeHead mayContain: outboundSites mayContain: localBridgeHeadAddress mayContain: localBridgeHead mayContain: kCCStatus mayContain: inboundSites mayContain: activationStyle mayContain: activationSchedule mayContain: addressType rDNAttID: cn showInAdvancedViewOnly: TRUE adminDisplayName: ms-Exch-Replication-Connector adminDescription: ms-Exch-Replication-Connector auxiliaryClass: msExchBaseClass objectClassCategory: 1 lDAPDisplayName: msExchReplicationConnector name: ms-Exch-Replication-Connector schemaIDGUID: 99f58682-12e8-11d3-aa58-00c04f8eedd8 systemOnly: FALSE defaultSecurityDescriptor: D:S: defaultHidingValue: TRUE objectCategory: CN=Class-Schema,${SCHEMADN} defaultObjectCategory: CN=ms-Exch-Replication-Connector,${SCHEMADN} # # ms-Exch-RFC1006-Stack # The RFC 1006 (TCP/IP) Transport Stack for the MTA. # dn: CN=ms-Exch-RFC1006-Stack,${SCHEMADN} objectClass: top objectClass: classSchema cn: ms-Exch-RFC1006-Stack distinguishedName: CN=ms-Exch-RFC1006-Stack,${SCHEMADN} possSuperiors: mTA subClassOf: transportStack governsID: 1.2.840.113556.1.3.24 rDNAttID: cn showInAdvancedViewOnly: TRUE adminDisplayName: ms-Exch-RFC1006-Stack adminDescription: ms-Exch-RFC1006-Stack auxiliaryClass: msExchBaseClass objectClassCategory: 1 lDAPDisplayName: rFC1006Stack name: ms-Exch-RFC1006-Stack schemaIDGUID: a8df74d7-c5ea-11d1-bbcb-0080c76670c0 systemOnly: FALSE defaultSecurityDescriptor: D:S: defaultHidingValue: TRUE objectCategory: CN=Class-Schema,${SCHEMADN} defaultObjectCategory: CN=ms-Exch-RFC1006-Stack,${SCHEMADN} # # ms-Exch-RFC1006-X400-Link # Specifies a remote X.400 MTA using an RFC 1006 (TCP/IP) Transport. # dn: CN=ms-Exch-RFC1006-X400-Link,${SCHEMADN} objectClass: top objectClass: classSchema cn: ms-Exch-RFC1006-X400-Link distinguishedName: CN=ms-Exch-RFC1006-X400-Link,${SCHEMADN} subClassOf: x400Link governsID: 1.2.840.113556.1.3.32 rDNAttID: cn showInAdvancedViewOnly: TRUE adminDisplayName: ms-Exch-RFC1006-X400-Link adminDescription: ms-Exch-RFC1006-X400-Link auxiliaryClass: msExchBaseClass objectClassCategory: 1 lDAPDisplayName: rFC1006X400Link name: ms-Exch-RFC1006-X400-Link schemaIDGUID: a8df74d8-c5ea-11d1-bbcb-0080c76670c0 systemOnly: FALSE defaultSecurityDescriptor: D:S: defaultHidingValue: TRUE objectCategory: CN=Class-Schema,${SCHEMADN} defaultObjectCategory: CN=ms-Exch-RFC1006-X400-Link,${SCHEMADN} # # ms-Exch-Routing-Group # Container used to hold routing group information. # dn: CN=ms-Exch-Routing-Group,${SCHEMADN} objectClass: top objectClass: classSchema cn: ms-Exch-Routing-Group distinguishedName: CN=ms-Exch-Routing-Group,${SCHEMADN} possSuperiors: msExchRoutingGroupContainer subClassOf: container governsID: 1.2.840.113556.1.5.7000.62.12002 mayContain: msExchMinAdminVersion mayContain: msExchRoutingGroupMembersBL mayContain: msExchInconsistentState mayContain: msExchRoutingMasterDN mayContain: msExchRoutingGroupMembersDN rDNAttID: cn showInAdvancedViewOnly: TRUE adminDisplayName: ms-Exch-Routing-Group adminDescription: ms-Exch-Routing-Group auxiliaryClass: msExchBaseClass objectClassCategory: 1 lDAPDisplayName: msExchRoutingGroup name: ms-Exch-Routing-Group schemaIDGUID: 35154156-a982-11d2-a9ff-00c04f8eedd8 systemOnly: FALSE defaultSecurityDescriptor: D:S: defaultHidingValue: TRUE objectCategory: CN=Class-Schema,${SCHEMADN} defaultObjectCategory: CN=ms-Exch-Routing-Group,${SCHEMADN} # # ms-Exch-Routing-Group-Connector # dn: CN=ms-Exch-Routing-Group-Connector,${SCHEMADN} objectClass: top objectClass: classSchema cn: ms-Exch-Routing-Group-Connector distinguishedName: CN=ms-Exch-Routing-Group-Connector,${SCHEMADN} possSuperiors: msExchConnectors subClassOf: msExchConnector governsID: 1.2.840.113556.1.5.7000.62.12007 mayContain: msExchEncryptedPassword mayContain: targetMTAs mayContain: homeMTA mayContain: domainName mayContain: authorizedUser mayContain: authorizedPassword mayContain: authorizedDomain mayContain: cost rDNAttID: cn showInAdvancedViewOnly: TRUE adminDisplayName: ms-Exch-Routing-Group-Connector adminDescription: ms-Exch-Routing-Group-Connector auxiliaryClass: msExchBaseClass objectClassCategory: 1 lDAPDisplayName: msExchRoutingGroupConnector name: ms-Exch-Routing-Group-Connector schemaIDGUID: 899e5b86-b09e-11d2-aa06-00c04f8eedd8 systemOnly: FALSE defaultSecurityDescriptor: D:S: defaultHidingValue: TRUE objectCategory: CN=Class-Schema,${SCHEMADN} defaultObjectCategory: CN=ms-Exch-Routing-Group-Connector,${SCHEMADN} # # ms-Exch-Routing-SMTP-Connector # dn: CN=ms-Exch-Routing-SMTP-Connector,${SCHEMADN} objectClass: top objectClass: classSchema cn: ms-Exch-Routing-SMTP-Connector distinguishedName: CN=ms-Exch-Routing-SMTP-Connector,${SCHEMADN} possSuperiors: msExchConnectors subClassOf: mailGateway governsID: 1.2.840.113556.1.5.7000.62.12008 mayContain: msExchSmtpTRNSmartHost mayContain: msExchSecurityPassword mayContain: msExchRoutingETRNDomains mayContain: msExchSmtpSmartHost mayContain: msExchSmtpOutboundSecurityUserName mayContain: msExchSmtpOutboundSecurityPassword mayContain: msExchSmtpOutboundSecurityFlag mayContain: msExchSmtpAuthorizedTRNAccounts rDNAttID: cn showInAdvancedViewOnly: TRUE adminDisplayName: ms-Exch-Routing-SMTP-Connector adminDescription: ms-Exch-Routing-SMTP-Connector auxiliaryClass: msExchBaseClass objectClassCategory: 1 lDAPDisplayName: msExchRoutingSMTPConnector name: ms-Exch-Routing-SMTP-Connector schemaIDGUID: 89baf7be-b09e-11d2-aa06-00c04f8eedd8 systemOnly: FALSE defaultSecurityDescriptor: D:S: defaultHidingValue: TRUE objectCategory: CN=Class-Schema,${SCHEMADN} defaultObjectCategory: CN=ms-Exch-Routing-SMTP-Connector,${SCHEMADN} # # ms-Exch-Schedule-Plus-Connector # dn: CN=ms-Exch-Schedule-Plus-Connector,${SCHEMADN} objectClass: top objectClass: classSchema cn: ms-Exch-Schedule-Plus-Connector distinguishedName: CN=ms-Exch-Schedule-Plus-Connector,${SCHEMADN} possSuperiors: container subClassOf: exchangeAdminService governsID: 1.2.840.113556.1.5.7000.62.1008 mayContain: computerName mayContain: transferRetryInterval mayContain: msExchSchedPlusSchedist mayContain: msExchSchedPlusFullUpdate mayContain: msExchSchedPlusAGOnly mayContain: msExchAdminMailbox rDNAttID: cn showInAdvancedViewOnly: TRUE adminDisplayName: ms-Exch-Schedule-Plus-Connector adminDescription: ms-Exch-Schedule-Plus-Connector auxiliaryClass: msExchBaseClass objectClassCategory: 1 lDAPDisplayName: msExchSchedulePlusConnector name: ms-Exch-Schedule-Plus-Connector schemaIDGUID: b1fce946-1d44-11d3-aa5e-00c04f8eedd8 systemOnly: FALSE defaultSecurityDescriptor: D:S: defaultHidingValue: TRUE objectCategory: CN=Class-Schema,${SCHEMADN} defaultObjectCategory: CN=ms-Exch-Schedule-Plus-Connector,${SCHEMADN} # # ms-Exch-Schema-Map-Policy # The policy object for connection agreements. # dn: CN=ms-Exch-Schema-Map-Policy,${SCHEMADN} objectClass: top objectClass: classSchema cn: ms-Exch-Schema-Map-Policy distinguishedName: CN=ms-Exch-Schema-Map-Policy,${SCHEMADN} possSuperiors: organizationalUnit possSuperiors: container subClassOf: top governsID: 1.2.840.113556.1.5.7000.62.1 mayContain: msExchADCObjectType mayContain: versionNumber mayContain: msExchServer2SchemaMap mayContain: msExchServer2ObjectMatch mayContain: msExchServer2Flags mayContain: msExchServer1SchemaMap mayContain: msExchServer1ObjectMatch mayContain: msExchServer1Flags mayContain: msExchSchemaPolicyConsumers mayContain: msExchAccessControlMap mayContain: displayName rDNAttID: cn showInAdvancedViewOnly: TRUE adminDisplayName: ms-Exch-Schema-Map-Policy adminDescription: ms-Exch-Schema-Map-Policy auxiliaryClass: msExchBaseClass objectClassCategory: 1 lDAPDisplayName: msExchSchemaMapPolicy name: ms-Exch-Schema-Map-Policy schemaIDGUID: 348af8f2-a982-11d2-a9ff-00c04f8eedd8 systemOnly: FALSE defaultSecurityDescriptor: D:S: defaultHidingValue: TRUE objectCategory: CN=Class-Schema,${SCHEMADN} defaultObjectCategory: CN=ms-Exch-Schema-Map-Policy,${SCHEMADN} # # ms-Exch-Site-Addressing # Represents the messaging domain. # dn: CN=ms-Exch-Site-Addressing,${SCHEMADN} objectClass: top objectClass: classSchema cn: ms-Exch-Site-Addressing distinguishedName: CN=ms-Exch-Site-Addressing,${SCHEMADN} possSuperiors: msExchAdminGroup possSuperiors: container subClassOf: top governsID: 1.2.840.113556.1.3.0 mustContain: cn mayContain: spaceLastComputed mayContain: siteProxySpace mayContain: routingList mayContain: ridServer mayContain: gWARTLastModified mayContain: gatewayRoutingTree mayContain: gatewayProxy mayContain: filterLocalAddresses mayContain: disabledGatewayProxy mayContain: activationStyle mayContain: activationSchedule rDNAttID: cn showInAdvancedViewOnly: TRUE adminDisplayName: ms-Exch-Site-Addressing adminDescription: ms-Exch-Site-Addressing auxiliaryClass: msExchBaseClass objectClassCategory: 1 lDAPDisplayName: siteAddressing name: ms-Exch-Site-Addressing schemaIDGUID: a8df74d9-c5ea-11d1-bbcb-0080c76670c0 systemOnly: FALSE defaultSecurityDescriptor: D:S: defaultHidingValue: TRUE objectCategory: CN=Class-Schema,${SCHEMADN} defaultObjectCategory: CN=ms-Exch-Site-Addressing,${SCHEMADN} # # ms-Exch-Site-Connector # A symbolic link to another domain's message transfer agents (MTAs). # dn: CN=ms-Exch-Site-Connector,${SCHEMADN} objectClass: top objectClass: classSchema cn: ms-Exch-Site-Connector distinguishedName: CN=ms-Exch-Site-Connector,${SCHEMADN} possSuperiors: container subClassOf: msExchConnector governsID: 1.2.840.113556.1.3.50 mustContain: cn mayContain: targetMTAs mayContain: msExchTargetBridgeheadServersDN mayContain: msExchSourceBridgeheadServersDN mayContain: msExchSourceBHAddress mayContain: routingList mayContain: homeMTA mayContain: domainName mayContain: msExchDestinationRGDN mayContain: msExchDestBHAddress mayContain: msExchConnectorType mayContain: bridgeheadServers mayContain: authorizedUser mayContain: authorizedPassword mayContain: authorizedDomain mayContain: cost rDNAttID: cn showInAdvancedViewOnly: TRUE adminDisplayName: ms-Exch-Site-Connector adminDescription: ms-Exch-Site-Connector auxiliaryClass: msExchBaseClass objectClassCategory: 1 lDAPDisplayName: siteConnector name: ms-Exch-Site-Connector schemaIDGUID: a8df74da-c5ea-11d1-bbcb-0080c76670c0 systemOnly: FALSE defaultSecurityDescriptor: D:S: defaultHidingValue: TRUE objectCategory: CN=Class-Schema,${SCHEMADN} defaultObjectCategory: CN=ms-Exch-Site-Connector,${SCHEMADN} # # ms-Exch-Site-Replication-Service # dn: CN=ms-Exch-Site-Replication-Service,${SCHEMADN} objectClass: top objectClass: classSchema cn: ms-Exch-Site-Replication-Service distinguishedName: CN=ms-Exch-Site-Replication-Service,${SCHEMADN} possSuperiors: msExchExchangeServer subClassOf: top governsID: 1.2.840.113556.1.5.7000.62.10 rDNAttID: cn showInAdvancedViewOnly: TRUE adminDisplayName: ms-Exch-Site-Replication-Service adminDescription: ms-Exch-Site-Replication-Service auxiliaryClass: msExchBaseClass auxiliaryClass: msExchMailStorage auxiliaryClass: mailRecipient objectClassCategory: 1 lDAPDisplayName: msExchSiteReplicationService name: ms-Exch-Site-Replication-Service schemaIDGUID: 99f5867b-12e8-11d3-aa58-00c04f8eedd8 systemOnly: FALSE defaultSecurityDescriptor: D:S: defaultHidingValue: TRUE objectCategory: CN=Class-Schema,${SCHEMADN} defaultObjectCategory: CN=ms-Exch-Site-Replication-Service,${SCHEMADN} # # ms-Exch-Smtp-Connection-Turf-List-Rule # dn: CN=ms-Exch-Smtp-Connection-Turf-List-Rule,${SCHEMADN} objectClass: top objectClass: classSchema cn: ms-Exch-Smtp-Connection-Turf-List-Rule distinguishedName: CN=ms-Exch-Smtp-Connection-Turf-List-Rule,${SCHEMADN} possSuperiors: msExchSmtpConnectionTurfList subClassOf: top governsID: 1.2.840.113556.1.5.7000.62.12011 mayContain: msExchSmtpConnectionTurfListResponse mayContain: msExchSmtpConnectionTurfListOptions mayContain: msExchSmtpConnectionTurfListMask mayContain: msExchSmtpConnectionTurfListDNS mayContain: msExchSmtpConnectionTurfListDisplay rDNAttID: cn showInAdvancedViewOnly: TRUE adminDisplayName: ms-Exch-Smtp-Connection-Turf-List-Rule adminDescription: ms-Exch-Smtp-Connection-Turf-List-Rule objectClassCategory: 1 lDAPDisplayName: msExchSmtpConnectionTurfListRule name: ms-Exch-Smtp-Connection-Turf-List-Rule schemaIDGUID: 6abadfad-e2f6-4ddb-9820-0da9c47da32c systemOnly: FALSE defaultSecurityDescriptor: D:S: defaultHidingValue: TRUE objectCategory: CN=Class-Schema,${SCHEMADN} defaultObjectCategory: CN=ms-Exch-Smtp-Connection-Turf-List-Rule,${SCHEMADN} # # ms-Exch-SNADS-Connector # The SNA Distribution System (SNADS) Connector. # dn: CN=ms-Exch-SNADS-Connector,${SCHEMADN} objectClass: top objectClass: classSchema cn: ms-Exch-SNADS-Connector distinguishedName: CN=ms-Exch-SNADS-Connector,${SCHEMADN} possSuperiors: container subClassOf: mailGateway governsID: 1.2.840.113556.1.5.7000.62.1003 rDNAttID: cn showInAdvancedViewOnly: TRUE adminDisplayName: ms-Exch-SNADS-Connector adminDescription: ms-Exch-SNADS-Connector auxiliaryClass: msExchBaseClass objectClassCategory: 1 lDAPDisplayName: msExchSNADSConnector name: ms-Exch-SNADS-Connector schemaIDGUID: 91b17254-b09e-11d2-aa06-00c04f8eedd8 systemOnly: FALSE defaultSecurityDescriptor: D:S: defaultHidingValue: TRUE objectCategory: CN=Class-Schema,${SCHEMADN} defaultObjectCategory: CN=ms-Exch-SNADS-Connector,${SCHEMADN} # # ms-Exch-System-Policy # The internal system policy. # dn: CN=ms-Exch-System-Policy,${SCHEMADN} objectClass: top objectClass: classSchema cn: ms-Exch-System-Policy distinguishedName: CN=ms-Exch-System-Policy,${SCHEMADN} possSuperiors: msExchSystemPolicyContainer subClassOf: msExchGenericPolicy governsID: 1.2.840.113556.1.5.7000.62.16 mayContain: msExchMinAdminVersion mayContain: heuristics rDNAttID: cn showInAdvancedViewOnly: TRUE adminDisplayName: ms-Exch-System-Policy adminDescription: ms-Exch-System-Policy auxiliaryClass: msExchBaseClass objectClassCategory: 1 lDAPDisplayName: msExchSystemPolicy name: ms-Exch-System-Policy schemaIDGUID: ba085a33-8807-4c6c-9522-2cf5a2a5e9c2 systemOnly: FALSE defaultSecurityDescriptor: D:S: defaultHidingValue: TRUE objectCategory: CN=Class-Schema,${SCHEMADN} defaultObjectCategory: CN=ms-Exch-System-Policy,${SCHEMADN} # # ms-Exch-TP4-Stack # The TP4 Transport Stack for the MTA. # dn: CN=ms-Exch-TP4-Stack,${SCHEMADN} objectClass: top objectClass: classSchema cn: ms-Exch-TP4-Stack distinguishedName: CN=ms-Exch-TP4-Stack,${SCHEMADN} possSuperiors: mTA possSuperiors: container possSuperiors: computer subClassOf: transportStack governsID: 1.2.840.113556.1.3.25 rDNAttID: cn showInAdvancedViewOnly: TRUE adminDisplayName: ms-Exch-TP4-Stack adminDescription: ms-Exch-TP4-Stack auxiliaryClass: msExchBaseClass objectClassCategory: 1 lDAPDisplayName: tP4Stack name: ms-Exch-TP4-Stack schemaIDGUID: a8df74db-c5ea-11d1-bbcb-0080c76670c0 systemOnly: FALSE defaultSecurityDescriptor: D:S: defaultHidingValue: TRUE objectCategory: CN=Class-Schema,${SCHEMADN} defaultObjectCategory: CN=ms-Exch-TP4-Stack,${SCHEMADN} # # ms-Exch-TP4-X400-Link # Specifies a remote X.400 MTA using a TP4 Transport. # dn: CN=ms-Exch-TP4-X400-Link,${SCHEMADN} objectClass: top objectClass: classSchema cn: ms-Exch-TP4-X400-Link distinguishedName: CN=ms-Exch-TP4-X400-Link,${SCHEMADN} possSuperiors: container subClassOf: x400Link governsID: 1.2.840.113556.1.3.33 rDNAttID: cn showInAdvancedViewOnly: TRUE adminDisplayName: ms-Exch-TP4-X400-Link adminDescription: ms-Exch-TP4-X400-Link auxiliaryClass: msExchBaseClass objectClassCategory: 1 lDAPDisplayName: tP4X400Link name: ms-Exch-TP4-X400-Link schemaIDGUID: a8df74dc-c5ea-11d1-bbcb-0080c76670c0 systemOnly: FALSE defaultSecurityDescriptor: D:S: defaultHidingValue: TRUE objectCategory: CN=Class-Schema,${SCHEMADN} defaultObjectCategory: CN=ms-Exch-TP4-X400-Link,${SCHEMADN} # # ms-Exch-Uce # Reserved. # dn: CN=ms-Exch-Uce,${SCHEMADN} objectClass: top objectClass: classSchema cn: ms-Exch-Uce distinguishedName: CN=ms-Exch-Uce,${SCHEMADN} possSuperiors: msExchMessageDeliveryConfig subClassOf: top governsID: 1.2.840.113556.1.5.7000.62.50037 mayContain: msExchUceStoreActionThreshold mayContain: msExchUceEnabled mayContain: msExchUceBlockThreshold rDNAttID: cn showInAdvancedViewOnly: TRUE adminDisplayName: ms-Exch-Uce adminDescription: ms-Exch-Uce objectClassCategory: 1 lDAPDisplayName: msExchUce name: ms-Exch-Uce schemaIDGUID: c5ccdce1-b399-405f-8ab7-bc6434d2e422 systemOnly: FALSE defaultSecurityDescriptor: D:S: defaultHidingValue: TRUE objectCategory: CN=Class-Schema,${SCHEMADN} defaultObjectCategory: CN=ms-Exch-Uce,${SCHEMADN} # # ms-Exch-X25-Stack # The X.25 Transport Stack for the MTA. # dn: CN=ms-Exch-X25-Stack,${SCHEMADN} objectClass: top objectClass: classSchema cn: ms-Exch-X25-Stack distinguishedName: CN=ms-Exch-X25-Stack,${SCHEMADN} possSuperiors: mTA possSuperiors: container possSuperiors: computer subClassOf: transportStack governsID: 1.2.840.113556.1.3.27 mustContain: x25LeasedLinePort mayContain: x25LeasedOrSwitched mayContain: x25FacilitiesDataIncoming mayContain: x25CallUserDataIncoming rDNAttID: cn showInAdvancedViewOnly: TRUE adminDisplayName: ms-Exch-X25-Stack adminDescription: ms-Exch-X25-Stack auxiliaryClass: msExchBaseClass objectClassCategory: 1 lDAPDisplayName: x25Stack name: ms-Exch-X25-Stack schemaIDGUID: a8df74de-c5ea-11d1-bbcb-0080c76670c0 systemOnly: FALSE defaultSecurityDescriptor: D:S: defaultHidingValue: TRUE objectCategory: CN=Class-Schema,${SCHEMADN} defaultObjectCategory: CN=ms-Exch-X25-Stack,${SCHEMADN} # # ms-Exch-X25-X400-Link # Specifies a remote X.400 MTA using an X.25 Transport. # dn: CN=ms-Exch-X25-X400-Link,${SCHEMADN} objectClass: top objectClass: classSchema cn: ms-Exch-X25-X400-Link distinguishedName: CN=ms-Exch-X25-X400-Link,${SCHEMADN} possSuperiors: container subClassOf: x400Link governsID: 1.2.840.113556.1.3.35 mayContain: x25RemoteMTAPhone mayContain: x25FacilitiesDataOutgoing mayContain: x25FacilitiesDataIncoming mayContain: x25CallUserDataOutgoing mayContain: x25CallUserDataIncoming rDNAttID: cn showInAdvancedViewOnly: TRUE adminDisplayName: ms-Exch-X25-X400-Link adminDescription: ms-Exch-X25-X400-Link auxiliaryClass: msExchBaseClass objectClassCategory: 1 lDAPDisplayName: x25X400Link name: ms-Exch-X25-X400-Link schemaIDGUID: a8df74df-c5ea-11d1-bbcb-0080c76670c0 systemOnly: FALSE defaultSecurityDescriptor: D:S: defaultHidingValue: TRUE objectCategory: CN=Class-Schema,${SCHEMADN} defaultObjectCategory: CN=ms-Exch-X25-X400-Link,${SCHEMADN} openchange-2.0/setup/AD/oc_provision_schema_attributes.ldif000066400000000000000000024253001223057412600242550ustar00rootroot00000000000000############################################################################## # AttributeSchema added ############################################################################## # # ms-Exch-Access-Control-Map # Contains the mapping for the access controls. # dn: CN=ms-Exch-Access-Control-Map,${SCHEMADN} objectClass: top objectClass: attributeSchema cn: ms-Exch-Access-Control-Map distinguishedName: CN=ms-Exch-Access-Control-Map,${SCHEMADN} attributeID: 1.2.840.113556.1.4.7000.102.64 attributeSyntax: 2.5.5.12 isSingleValued: TRUE showInAdvancedViewOnly: TRUE adminDisplayName: ms-Exch-Access-Control-Map adminDescription: ms-Exch-Access-Control-Map oMSyntax: 64 searchFlags: 0 lDAPDisplayName: msExchAccessControlMap name: ms-Exch-Access-Control-Map schemaIDGUID: 8ff54464-b093-11d2-aa06-00c04f8eedd8 isMemberOfPartialAttributeSet: FALSE objectCategory: CN=Attribute-Schema,${SCHEMADN} # # ms-Exch-Access-Flags # The authentication method to use. # dn: CN=ms-Exch-Access-Flags,${SCHEMADN} objectClass: top objectClass: attributeSchema cn: ms-Exch-Access-Flags distinguishedName: CN=ms-Exch-Access-Flags,${SCHEMADN} attributeID: 1.2.840.113556.1.4.7000.102.2016 attributeSyntax: 2.5.5.9 isSingleValued: TRUE showInAdvancedViewOnly: TRUE adminDisplayName: ms-Exch-Access-Flags adminDescription: ms-Exch-Access-Flags oMSyntax: 2 searchFlags: 0 lDAPDisplayName: msExchAccessFlags name: ms-Exch-Access-Flags schemaIDGUID: 901b6a04-b093-11d2-aa06-00c04f8eedd8 isMemberOfPartialAttributeSet: FALSE objectCategory: CN=Attribute-Schema,${SCHEMADN} # # ms-Exch-Access-SSL-Flags # The type of encrypted channel that this resource supports. # dn: CN=ms-Exch-Access-SSL-Flags,${SCHEMADN} objectClass: top objectClass: attributeSchema cn: ms-Exch-Access-SSL-Flags distinguishedName: CN=ms-Exch-Access-SSL-Flags,${SCHEMADN} attributeID: 1.2.840.113556.1.4.7000.102.2006 attributeSyntax: 2.5.5.9 isSingleValued: TRUE showInAdvancedViewOnly: TRUE adminDisplayName: ms-Exch-Access-SSL-Flags adminDescription: ms-Exch-Access-SSL-Flags oMSyntax: 2 searchFlags: 0 lDAPDisplayName: msExchAccessSSLFlags name: ms-Exch-Access-SSL-Flags schemaIDGUID: 903f2d4a-b093-11d2-aa06-00c04f8eedd8 isMemberOfPartialAttributeSet: FALSE objectCategory: CN=Attribute-Schema,${SCHEMADN} # # ms-Exch-Activation-Schedule # This is the schedule if "scheduled times" is selected. # dn: CN=ms-Exch-Activation-Schedule,${SCHEMADN} objectClass: top objectClass: attributeSchema cn: ms-Exch-Activation-Schedule distinguishedName: CN=ms-Exch-Activation-Schedule,${SCHEMADN} attributeID: 1.2.840.113556.1.2.213 attributeSyntax: 2.5.5.10 isSingleValued: TRUE rangeLower: 84 rangeUpper: 84 mAPIID: 32837 showInAdvancedViewOnly: TRUE adminDisplayName: ms-Exch-Activation-Schedule adminDescription: ms-Exch-Activation-Schedule oMSyntax: 4 searchFlags: 0 lDAPDisplayName: activationSchedule name: ms-Exch-Activation-Schedule schemaIDGUID: bf967916-0de6-11d0-a285-00aa003049e2 isMemberOfPartialAttributeSet: FALSE objectCategory: CN=Attribute-Schema,${SCHEMADN} # # ms-Exch-Activation-Style # dn: CN=ms-Exch-Activation-Style,${SCHEMADN} objectClass: top objectClass: attributeSchema cn: ms-Exch-Activation-Style distinguishedName: CN=ms-Exch-Activation-Style,${SCHEMADN} attributeID: 1.2.840.113556.1.2.73 attributeSyntax: 2.5.5.9 isSingleValued: TRUE rangeLower: 0 rangeUpper: 3 mAPIID: 32838 showInAdvancedViewOnly: TRUE adminDisplayName: ms-Exch-Activation-Style adminDescription: ms-Exch-Activation-Style oMSyntax: 2 searchFlags: 0 lDAPDisplayName: activationStyle name: ms-Exch-Activation-Style schemaIDGUID: bf967917-0de6-11d0-a285-00aa003049e2 isMemberOfPartialAttributeSet: FALSE objectCategory: CN=Attribute-Schema,${SCHEMADN} # # ms-Exch-ADC-Global-Names # dn: CN=ms-Exch-ADC-Global-Names,${SCHEMADN} objectClass: top objectClass: attributeSchema cn: ms-Exch-ADC-Global-Names distinguishedName: CN=ms-Exch-ADC-Global-Names,${SCHEMADN} attributeID: 1.2.840.113556.1.4.7000.102.63 attributeSyntax: 2.5.5.12 isSingleValued: FALSE showInAdvancedViewOnly: TRUE adminDisplayName: ms-Exch-ADC-Global-Names adminDescription: ms-Exch-ADC-Global-Names oMSyntax: 64 searchFlags: 1 lDAPDisplayName: msExchADCGlobalNames name: ms-Exch-ADC-Global-Names schemaIDGUID: 9062f090-b093-11d2-aa06-00c04f8eedd8 attributeSecurityGUID: e48d0154-bcf8-11d1-8702-00c04fb96050 isMemberOfPartialAttributeSet: TRUE objectCategory: CN=Attribute-Schema,${SCHEMADN} # # ms-Exch-ADC-Object-Type # A bit used to distinguish the type of connection agreement. # dn: CN=ms-Exch-ADC-Object-Type,${SCHEMADN} objectClass: top objectClass: attributeSchema cn: ms-Exch-ADC-Object-Type distinguishedName: CN=ms-Exch-ADC-Object-Type,${SCHEMADN} attributeID: 1.2.840.113556.1.4.7000.102.84 attributeSyntax: 2.5.5.9 isSingleValued: TRUE showInAdvancedViewOnly: TRUE adminDisplayName: ms-Exch-ADC-Object-Type adminDescription: ms-Exch-ADC-Object-Type oMSyntax: 2 searchFlags: 0 lDAPDisplayName: msExchADCObjectType name: ms-Exch-ADC-Object-Type schemaIDGUID: 4859fb55-1924-11d3-aa59-00c04f8eedd8 isMemberOfPartialAttributeSet: FALSE objectCategory: CN=Attribute-Schema,${SCHEMADN} # # ms-Exch-ADC-Options # The options bitstring. # dn: CN=ms-Exch-ADC-Options,${SCHEMADN} objectClass: top objectClass: attributeSchema cn: ms-Exch-ADC-Options distinguishedName: CN=ms-Exch-ADC-Options,${SCHEMADN} attributeID: 1.2.840.113556.1.4.7000.102.41 attributeSyntax: 2.5.5.9 isSingleValued: TRUE showInAdvancedViewOnly: TRUE adminDisplayName: ms-Exch-ADC-Options adminDescription: ms-Exch-ADC-Options oMSyntax: 2 searchFlags: 0 lDAPDisplayName: msExchADCOptions name: ms-Exch-ADC-Options schemaIDGUID: 90891630-b093-11d2-aa06-00c04f8eedd8 isMemberOfPartialAttributeSet: FALSE objectCategory: CN=Attribute-Schema,${SCHEMADN} # # ms-Exch-Additional-DN-Map # Additional source-target pairs for straight distinguished name (DN) # mapping. # dn: CN=ms-Exch-Additional-DN-Map,${SCHEMADN} objectClass: top objectClass: attributeSchema cn: ms-Exch-Additional-DN-Map distinguishedName: CN=ms-Exch-Additional-DN-Map,${SCHEMADN} attributeID: 1.2.840.113556.1.4.7000.102.42 attributeSyntax: 2.5.5.12 isSingleValued: FALSE showInAdvancedViewOnly: TRUE adminDisplayName: ms-Exch-Additional-DN-Map adminDescription: ms-Exch-Additional-DN-Map oMSyntax: 64 searchFlags: 0 lDAPDisplayName: msExchAdditionalDNMap name: ms-Exch-Additional-DN-Map schemaIDGUID: 90a814c2-b093-11d2-aa06-00c04f8eedd8 isMemberOfPartialAttributeSet: FALSE objectCategory: CN=Attribute-Schema,${SCHEMADN} # # ms-Exch-Address-List-OU # dn: CN=ms-Exch-Address-List-OU,${SCHEMADN} objectClass: top objectClass: attributeSchema cn: ms-Exch-Address-List-OU distinguishedName: CN=ms-Exch-Address-List-OU,${SCHEMADN} attributeID: 1.2.840.113556.1.4.7000.102.112 attributeSyntax: 2.5.5.12 isSingleValued: FALSE showInAdvancedViewOnly: TRUE adminDisplayName: ms-Exch-Address-List-OU adminDescription: ms-Exch-Address-List-OU oMSyntax: 64 searchFlags: 0 lDAPDisplayName: msExchAddressListOU name: ms-Exch-Address-List-OU schemaIDGUID: f4b93a0d-f30c-44ff-aa47-e74806dbced2 isMemberOfPartialAttributeSet: FALSE objectCategory: CN=Attribute-Schema,${SCHEMADN} # # ms-Exch-Address-List-Service-BL # The link from the Exchange server to the address list service # running on it. # dn: CN=ms-Exch-Address-List-Service-BL,${SCHEMADN} objectClass: top objectClass: attributeSchema cn: ms-Exch-Address-List-Service-BL distinguishedName: CN=ms-Exch-Address-List-Service-BL,${SCHEMADN} attributeID: 1.2.840.113556.1.4.7000.102.74 attributeSyntax: 2.5.5.1 isSingleValued: TRUE linkID: 1017 showInAdvancedViewOnly: TRUE adminDisplayName: ms-Exch-Address-List-Service-BL oMObjectClass:: KwwCh3McAIVK adminDescription: ms-Exch-Address-List-Service-BL oMSyntax: 127 searchFlags: 0 lDAPDisplayName: msExchAddressListServiceBL name: ms-Exch-Address-List-Service-BL schemaIDGUID: 8a407b6e-b09e-11d2-aa06-00c04f8eedd8 systemFlags: 1 isMemberOfPartialAttributeSet: FALSE objectCategory: CN=Attribute-Schema,${SCHEMADN} # # ms-Exch-Address-List-Service-Link # A link from the address list service to the Exchange server it # should be running on. # dn: CN=ms-Exch-Address-List-Service-Link,${SCHEMADN} objectClass: top objectClass: attributeSchema cn: ms-Exch-Address-List-Service-Link distinguishedName: CN=ms-Exch-Address-List-Service-Link,${SCHEMADN} attributeID: 1.2.840.113556.1.4.7000.102.75 attributeSyntax: 2.5.5.1 isSingleValued: TRUE linkID: 1016 showInAdvancedViewOnly: TRUE adminDisplayName: ms-Exch-Address-List-Service-Link oMObjectClass:: KwwCh3McAIVK adminDescription: ms-Exch-Address-List-Service-Link oMSyntax: 127 searchFlags: 0 lDAPDisplayName: msExchAddressListServiceLink name: ms-Exch-Address-List-Service-Link schemaIDGUID: 9b6e9584-b093-11d2-aa06-00c04f8eedd8 isMemberOfPartialAttributeSet: FALSE objectCategory: CN=Attribute-Schema,${SCHEMADN} # # ms-Exch-Add-Groups-To-Token # dn: CN=ms-Exch-Add-Groups-To-Token,${SCHEMADN} objectClass: top objectClass: attributeSchema cn: ms-Exch-Add-Groups-To-Token distinguishedName: CN=ms-Exch-Add-Groups-To-Token,${SCHEMADN} attributeID: 1.2.840.113556.1.4.7000.102.95 attributeSyntax: 2.5.5.8 isSingleValued: TRUE showInAdvancedViewOnly: TRUE adminDisplayName: ms-Exch-Add-Groups-To-Token adminDescription: ms-Exch-Add-Groups-To-Token oMSyntax: 1 searchFlags: 0 lDAPDisplayName: msExchAddGroupsToToken name: ms-Exch-Add-Groups-To-Token schemaIDGUID: 9c4d7592-ef4a-4c69-8f30-6f18ca1ec370 isMemberOfPartialAttributeSet: TRUE objectCategory: CN=Attribute-Schema,${SCHEMADN} # # ms-Exch-ADMD # Used by the message transfer agent (MTA) to determine if Internal # Trace Information should be stripped. dn: CN=ms-Exch-ADMD,${SCHEMADN} objectClass: top objectClass: attributeSchema cn: ms-Exch-ADMD distinguishedName: CN=ms-Exch-ADMD,${SCHEMADN} attributeID: 1.2.840.113556.1.2.232 attributeSyntax: 2.5.5.5 isSingleValued: TRUE rangeLower: 1 rangeUpper: 16 mAPIID: 32841 showInAdvancedViewOnly: TRUE adminDisplayName: ms-Exch-ADMD adminDescription: ms-Exch-ADMD oMSyntax: 19 searchFlags: 0 lDAPDisplayName: aDMD name: ms-Exch-ADMD schemaIDGUID: a8df7390-c5ea-11d1-bbcb-0080c76670c0 isMemberOfPartialAttributeSet: FALSE objectCategory: CN=Attribute-Schema,${SCHEMADN} # # ms-Exch-Admins # A link to all Exchange administrators within the organization along # with the appropriate permissions. # dn: CN=ms-Exch-Admins,${SCHEMADN} objectClass: top objectClass: attributeSchema cn: ms-Exch-Admins distinguishedName: CN=ms-Exch-Admins,${SCHEMADN} attributeID: 1.2.840.113556.1.4.7000.102.50064 attributeSyntax: 2.5.5.12 isSingleValued: FALSE showInAdvancedViewOnly: TRUE adminDisplayName: ms-Exch-Admins adminDescription: ms-Exch-Admins oMSyntax: 64 searchFlags: 0 lDAPDisplayName: msExchAdmins name: ms-Exch-Admins schemaIDGUID: b644c27a-a419-40b6-a62e-180930df5610 isMemberOfPartialAttributeSet: FALSE objectCategory: CN=Attribute-Schema,${SCHEMADN} # # ms-Exch-Admin-ACL # The access control list (ACL). # dn: CN=ms-Exch-Admin-ACL,${SCHEMADN} objectClass: top objectClass: attributeSchema cn: ms-Exch-Admin-ACL distinguishedName: CN=ms-Exch-Admin-ACL,${SCHEMADN} attributeID: 1.2.840.113556.1.4.7000.102.2011 attributeSyntax: 2.5.5.12 isSingleValued: TRUE showInAdvancedViewOnly: TRUE adminDisplayName: ms-Exch-Admin-ACL adminDescription: ms-Exch-Admin-ACL oMSyntax: 64 searchFlags: 0 lDAPDisplayName: msExchAdminACL name: ms-Exch-Admin-ACL schemaIDGUID: 90c975ae-b093-11d2-aa06-00c04f8eedd8 isMemberOfPartialAttributeSet: FALSE objectCategory: CN=Attribute-Schema,${SCHEMADN} # # ms-Exch-Admin-Extension-DLL # dn: CN=ms-Exch-Admin-Extension-DLL,${SCHEMADN} objectClass: top objectClass: attributeSchema cn: ms-Exch-Admin-Extension-DLL distinguishedName: CN=ms-Exch-Admin-Extension-DLL,${SCHEMADN} attributeID: 1.2.840.113556.1.2.95 attributeSyntax: 2.5.5.12 isSingleValued: TRUE rangeLower: 1 rangeUpper: 255 mAPIID: 32844 showInAdvancedViewOnly: TRUE adminDisplayName: ms-Exch-Admin-Extension-DLL adminDescription: ms-Exch-Admin-Extension-DLL oMSyntax: 64 searchFlags: 0 lDAPDisplayName: adminExtensionDLL name: ms-Exch-Admin-Extension-DLL schemaIDGUID: a8df7391-c5ea-11d1-bbcb-0080c76670c0 isMemberOfPartialAttributeSet: FALSE objectCategory: CN=Attribute-Schema,${SCHEMADN} # # ms-Exch-Admin-Groups-Enabled # Used by the user interface (UI) to determine whether to display # Administrator Groups. # dn: CN=ms-Exch-Admin-Groups-Enabled,${SCHEMADN} objectClass: top objectClass: attributeSchema cn: ms-Exch-Admin-Groups-Enabled distinguishedName: CN=ms-Exch-Admin-Groups-Enabled,${SCHEMADN} attributeID: 1.2.840.113556.1.4.7000.102.50026 attributeSyntax: 2.5.5.8 isSingleValued: TRUE showInAdvancedViewOnly: TRUE adminDisplayName: ms-Exch-Admin-Groups-Enabled adminDescription: ms-Exch-Admin-Groups-Enabled oMSyntax: 1 searchFlags: 0 lDAPDisplayName: msExchAdminGroupsEnabled name: ms-Exch-Admin-Groups-Enabled schemaIDGUID: e32977ae-1d31-11d3-aa5e-00c04f8eedd8 isMemberOfPartialAttributeSet: FALSE objectCategory: CN=Attribute-Schema,${SCHEMADN} # # ms-Exch-Admin-Group-Mode # The type of servers that are in the Administrator Group. # dn: CN=ms-Exch-Admin-Group-Mode,${SCHEMADN} objectClass: top objectClass: attributeSchema cn: ms-Exch-Admin-Group-Mode distinguishedName: CN=ms-Exch-Admin-Group-Mode,${SCHEMADN} attributeID: 1.2.840.113556.1.4.7000.102.50014 attributeSyntax: 2.5.5.9 isSingleValued: TRUE showInAdvancedViewOnly: TRUE adminDisplayName: ms-Exch-Admin-Group-Mode adminDescription: ms-Exch-Admin-Group-Mode oMSyntax: 2 searchFlags: 0 lDAPDisplayName: msExchAdminGroupMode name: ms-Exch-Admin-Group-Mode schemaIDGUID: 90ead69a-b093-11d2-aa06-00c04f8eedd8 isMemberOfPartialAttributeSet: FALSE objectCategory: CN=Attribute-Schema,${SCHEMADN} # # ms-Exch-Admin-Mailbox # A link to the administrator mailbox of the cc:Mail Connector. # dn: CN=ms-Exch-Admin-Mailbox,${SCHEMADN} objectClass: top objectClass: attributeSchema cn: ms-Exch-Admin-Mailbox distinguishedName: CN=ms-Exch-Admin-Mailbox,${SCHEMADN} attributeID: 1.2.840.113556.1.4.7000.102.1034 attributeSyntax: 2.5.5.1 isSingleValued: TRUE showInAdvancedViewOnly: TRUE adminDisplayName: ms-Exch-Admin-Mailbox oMObjectClass:: KwwCh3McAIVK adminDescription: ms-Exch-Admin-Mailbox oMSyntax: 127 searchFlags: 0 lDAPDisplayName: msExchAdminMailbox name: ms-Exch-Admin-Mailbox schemaIDGUID: 94e9a76c-b093-11d2-aa06-00c04f8eedd8 isMemberOfPartialAttributeSet: FALSE objectCategory: CN=Attribute-Schema,${SCHEMADN} # # ms-Exch-Aging-Keep-Time # The time value used to determine when to remove indexes, views, and # categorizations. The default is 8 days. # dn: CN=ms-Exch-Aging-Keep-Time,${SCHEMADN} objectClass: top objectClass: attributeSchema cn: ms-Exch-Aging-Keep-Time distinguishedName: CN=ms-Exch-Aging-Keep-Time,${SCHEMADN} attributeID: 1.2.840.113556.1.4.7000.102.11059 attributeSyntax: 2.5.5.9 isSingleValued: TRUE showInAdvancedViewOnly: TRUE adminDisplayName: ms-Exch-Aging-Keep-Time adminDescription: ms-Exch-Aging-Keep-Time oMSyntax: 2 searchFlags: 0 lDAPDisplayName: msExchAgingKeepTime name: ms-Exch-Aging-Keep-Time schemaIDGUID: 5872299f-123a-11d3-aa58-00c04f8eedd8 isMemberOfPartialAttributeSet: FALSE objectCategory: CN=Attribute-Schema,${SCHEMADN} # # ms-Exch-Alias-Gen-Format # The time/date that this policy was applied. # dn: CN=ms-Exch-Alias-Gen-Format,${SCHEMADN} objectClass: top objectClass: attributeSchema cn: ms-Exch-Alias-Gen-Format distinguishedName: CN=ms-Exch-Alias-Gen-Format,${SCHEMADN} attributeID: 1.2.840.113556.1.4.7000.102.50010 attributeSyntax: 2.5.5.10 isSingleValued: TRUE showInAdvancedViewOnly: TRUE adminDisplayName: ms-Exch-Alias-Gen-Format adminDescription: ms-Exch-Alias-Gen-Format oMSyntax: 4 searchFlags: 0 lDAPDisplayName: msExchAliasGenFormat name: ms-Exch-Alias-Gen-Format schemaIDGUID: 912b3618-b093-11d2-aa06-00c04f8eedd8 isMemberOfPartialAttributeSet: FALSE objectCategory: CN=Attribute-Schema,${SCHEMADN} # # ms-Exch-Alias-Gen-Type # The time/date that this policy was applied. # dn: CN=ms-Exch-Alias-Gen-Type,${SCHEMADN} objectClass: top objectClass: attributeSchema cn: ms-Exch-Alias-Gen-Type distinguishedName: CN=ms-Exch-Alias-Gen-Type,${SCHEMADN} attributeID: 1.2.840.113556.1.4.7000.102.50011 attributeSyntax: 2.5.5.10 isSingleValued: TRUE showInAdvancedViewOnly: TRUE adminDisplayName: ms-Exch-Alias-Gen-Type adminDescription: ms-Exch-Alias-Gen-Type oMSyntax: 4 searchFlags: 0 lDAPDisplayName: msExchAliasGenType name: ms-Exch-Alias-Gen-Type schemaIDGUID: 914ef95e-b093-11d2-aa06-00c04f8eedd8 isMemberOfPartialAttributeSet: FALSE objectCategory: CN=Attribute-Schema,${SCHEMADN} # # ms-Exch-Alias-Gen-Uniqueness # The time/date that this policy was applied. # dn: CN=ms-Exch-Alias-Gen-Uniqueness,${SCHEMADN} objectClass: top objectClass: attributeSchema cn: ms-Exch-Alias-Gen-Uniqueness distinguishedName: CN=ms-Exch-Alias-Gen-Uniqueness,${SCHEMADN} attributeID: 1.2.840.113556.1.4.7000.102.50012 attributeSyntax: 2.5.5.10 isSingleValued: TRUE showInAdvancedViewOnly: TRUE adminDisplayName: ms-Exch-Alias-Gen-Uniqueness adminDescription: ms-Exch-Alias-Gen-Uniqueness oMSyntax: 4 searchFlags: 0 lDAPDisplayName: msExchAliasGenUniqueness name: ms-Exch-Alias-Gen-Uniqueness schemaIDGUID: 91705a4a-b093-11d2-aa06-00c04f8eedd8 isMemberOfPartialAttributeSet: FALSE objectCategory: CN=Attribute-Schema,${SCHEMADN} # # ms-Exch-Allow-Additional-Resources # Allows conference resource extension requests. # dn: CN=ms-Exch-Allow-Additional-Resources,${SCHEMADN} objectClass: top objectClass: attributeSchema cn: ms-Exch-Allow-Additional-Resources distinguishedName: CN=ms-Exch-Allow-Additional-Resources,${SCHEMADN} attributeID: 1.2.840.113556.1.4.7000.102.9006 attributeSyntax: 2.5.5.8 isSingleValued: TRUE showInAdvancedViewOnly: TRUE adminDisplayName: ms-Exch-Allow-Additional-Resources adminDescription: ms-Exch-Allow-Additional-Resources oMSyntax: 1 searchFlags: 0 lDAPDisplayName: msExchAllowAdditionalResources name: ms-Exch-Allow-Additional-Resources schemaIDGUID: 91941d90-b093-11d2-aa06-00c04f8eedd8 isMemberOfPartialAttributeSet: FALSE objectCategory: CN=Attribute-Schema,${SCHEMADN} # # ms-Exch-Allow-Enhanced-Security # dn: CN=ms-Exch-Allow-Enhanced-Security,${SCHEMADN} objectClass: top objectClass: attributeSchema cn: ms-Exch-Allow-Enhanced-Security distinguishedName: CN=ms-Exch-Allow-Enhanced-Security,${SCHEMADN} attributeID: 1.2.840.113556.1.4.7000.102.11087 attributeSyntax: 2.5.5.8 isSingleValued: TRUE showInAdvancedViewOnly: TRUE adminDisplayName: ms-Exch-Allow-Enhanced-Security adminDescription: ms-Exch-Allow-Enhanced-Security oMSyntax: 1 searchFlags: 0 lDAPDisplayName: msExchAllowEnhancedSecurity name: ms-Exch-Allow-Enhanced-Security schemaIDGUID: 63b79cf2-1f4b-4766-ba5b-814b6077640f isMemberOfPartialAttributeSet: FALSE objectCategory: CN=Attribute-Schema,${SCHEMADN} # # ms-Exch-Allow-Time-Extensions # Allows conference time extension requests. # dn: CN=ms-Exch-Allow-Time-Extensions,${SCHEMADN} objectClass: top objectClass: attributeSchema cn: ms-Exch-Allow-Time-Extensions distinguishedName: CN=ms-Exch-Allow-Time-Extensions,${SCHEMADN} attributeID: 1.2.840.113556.1.4.7000.102.9005 attributeSyntax: 2.5.5.8 isSingleValued: TRUE showInAdvancedViewOnly: TRUE adminDisplayName: ms-Exch-Allow-Time-Extensions adminDescription: ms-Exch-Allow-Time-Extensions oMSyntax: 1 searchFlags: 0 lDAPDisplayName: msExchAllowTimeExtensions name: ms-Exch-Allow-Time-Extensions schemaIDGUID: 91b7e0d6-b093-11d2-aa06-00c04f8eedd8 isMemberOfPartialAttributeSet: FALSE objectCategory: CN=Attribute-Schema,${SCHEMADN} # # ms-Exch-Alternate-Server # Contains the host name of an alternate server that accepts mail for # the default domain. dn: CN=ms-Exch-Alternate-Server,${SCHEMADN} objectClass: top objectClass: attributeSchema cn: ms-Exch-Alternate-Server distinguishedName: CN=ms-Exch-Alternate-Server,${SCHEMADN} attributeID: 1.2.840.113556.1.4.7000.102.12532 attributeSyntax: 2.5.5.5 isSingleValued: TRUE showInAdvancedViewOnly: TRUE adminDisplayName: ms-Exch-Alternate-Server adminDescription: ms-Exch-Alternate-Server oMSyntax: 19 searchFlags: 0 lDAPDisplayName: msExchAlternateServer name: ms-Exch-Alternate-Server schemaIDGUID: 974c99f9-33fc-11d3-aa6e-00c04f8eedd8 isMemberOfPartialAttributeSet: FALSE objectCategory: CN=Attribute-Schema,${SCHEMADN} # # ms-Exch-Alt-Recipient # Delivers to this recipient if a specified recipient cannot be # delivered to. # dn: CN=ms-Exch-Alt-Recipient,${SCHEMADN} objectClass: top objectClass: attributeSchema cn: ms-Exch-Alt-Recipient distinguishedName: CN=ms-Exch-Alt-Recipient,${SCHEMADN} attributeID: 1.2.840.113556.1.2.126 attributeSyntax: 2.5.5.1 isSingleValued: TRUE mAPIID: 32846 linkID: 12 showInAdvancedViewOnly: TRUE adminDisplayName: ms-Exch-Alt-Recipient oMObjectClass:: KwwCh3McAIVK adminDescription: ms-Exch-Alt-Recipient oMSyntax: 127 searchFlags: 16 lDAPDisplayName: altRecipient name: ms-Exch-Alt-Recipient schemaIDGUID: bf96791e-0de6-11d0-a285-00aa003049e2 attributeSecurityGUID: e48d0154-bcf8-11d1-8702-00c04fb96050 isMemberOfPartialAttributeSet: TRUE objectCategory: CN=Attribute-Schema,${SCHEMADN} # # ms-Exch-Alt-Recipient-BL # A backlink to ms-Exch-Alt-Recipient. # dn: CN=ms-Exch-Alt-Recipient-BL,${SCHEMADN} objectClass: top objectClass: attributeSchema cn: ms-Exch-Alt-Recipient-BL distinguishedName: CN=ms-Exch-Alt-Recipient-BL,${SCHEMADN} attributeID: 1.2.840.113556.1.2.294 attributeSyntax: 2.5.5.1 isSingleValued: FALSE mAPIID: 32847 linkID: 13 showInAdvancedViewOnly: TRUE adminDisplayName: ms-Exch-Alt-Recipient-BL oMObjectClass:: KwwCh3McAIVK adminDescription: ms-Exch-Alt-Recipient-BL oMSyntax: 127 searchFlags: 0 lDAPDisplayName: altRecipientBL name: ms-Exch-Alt-Recipient-BL schemaIDGUID: bf96791f-0de6-11d0-a285-00aa003049e2 attributeSecurityGUID: e48d0154-bcf8-11d1-8702-00c04fb96050 systemFlags: 1 isMemberOfPartialAttributeSet: FALSE objectCategory: CN=Attribute-Schema,${SCHEMADN} # # ms-Exch-AL-Object-Version # dn: CN=ms-Exch-AL-Object-Version,${SCHEMADN} objectClass: top objectClass: attributeSchema cn: ms-Exch-AL-Object-Version distinguishedName: CN=ms-Exch-AL-Object-Version,${SCHEMADN} attributeID: 1.2.840.113556.1.4.7000.102.59 attributeSyntax: 2.5.5.9 isSingleValued: TRUE showInAdvancedViewOnly: TRUE adminDisplayName: ms-Exch-AL-Object-Version adminDescription: ms-Exch-AL-Object-Version oMSyntax: 2 searchFlags: 0 lDAPDisplayName: msExchALObjectVersion name: ms-Exch-AL-Object-Version schemaIDGUID: 910c3786-b093-11d2-aa06-00c04f8eedd8 attributeSecurityGUID: e48d0154-bcf8-11d1-8702-00c04fb96050 isMemberOfPartialAttributeSet: FALSE objectCategory: CN=Attribute-Schema,${SCHEMADN} # # ms-Exch-Anonymous-Access # Determines whether or not anonymous access is allowed via this # protocol. # dn: CN=ms-Exch-Anonymous-Access,${SCHEMADN} objectClass: top objectClass: attributeSchema cn: ms-Exch-Anonymous-Access distinguishedName: CN=ms-Exch-Anonymous-Access,${SCHEMADN} attributeID: 1.2.840.113556.1.2.482 attributeSyntax: 2.5.5.8 isSingleValued: TRUE mAPIID: 33159 showInAdvancedViewOnly: TRUE adminDisplayName: ms-Exch-Anonymous-Access adminDescription: ms-Exch-Anonymous-Access oMSyntax: 1 searchFlags: 0 lDAPDisplayName: anonymousAccess name: ms-Exch-Anonymous-Access schemaIDGUID: a8df7392-c5ea-11d1-bbcb-0080c76670c0 isMemberOfPartialAttributeSet: FALSE objectCategory: CN=Attribute-Schema,${SCHEMADN} # # ms-Exch-Anonymous-Account # dn: CN=ms-Exch-Anonymous-Account,${SCHEMADN} objectClass: top objectClass: attributeSchema cn: ms-Exch-Anonymous-Account distinguishedName: CN=ms-Exch-Anonymous-Account,${SCHEMADN} attributeID: 1.2.840.113556.1.2.561 attributeSyntax: 2.5.5.12 isSingleValued: TRUE rangeLower: 1 rangeUpper: 256 mAPIID: 35878 showInAdvancedViewOnly: TRUE adminDisplayName: ms-Exch-Anonymous-Account adminDescription: ms-Exch-Anonymous-Account oMSyntax: 64 searchFlags: 0 lDAPDisplayName: anonymousAccount name: ms-Exch-Anonymous-Account schemaIDGUID: a8df7393-c5ea-11d1-bbcb-0080c76670c0 isMemberOfPartialAttributeSet: FALSE objectCategory: CN=Attribute-Schema,${SCHEMADN} # # ms-Exch-Applies-To-Smtp-VS # dn: CN=ms-Exch-Applies-To-Smtp-VS,${SCHEMADN} objectClass: top objectClass: attributeSchema cn: ms-Exch-Applies-To-Smtp-VS distinguishedName: CN=ms-Exch-Applies-To-Smtp-VS,${SCHEMADN} attributeID: 1.2.840.113556.1.4.7000.102.5058 attributeSyntax: 2.5.5.1 isSingleValued: FALSE linkID: 1034 showInAdvancedViewOnly: TRUE adminDisplayName: ms-Exch-Applies-To-Smtp-VS oMObjectClass:: KwwCh3McAIVK adminDescription: ms-Exch-Applies-To-Smtp-VS oMSyntax: 127 searchFlags: 0 lDAPDisplayName: msExchAppliesToSmtpVS name: ms-Exch-Applies-To-Smtp-VS schemaIDGUID: 2925413e-fa41-4d01-945d-a15b5d6bb965 isMemberOfPartialAttributeSet: FALSE objectCategory: CN=Attribute-Schema,${SCHEMADN} # # ms-Exch-Applies-To-Smtp-VS-BL # dn: CN=ms-Exch-Applies-To-Smtp-VS-BL,${SCHEMADN} objectClass: top objectClass: attributeSchema cn: ms-Exch-Applies-To-Smtp-VS-BL distinguishedName: CN=ms-Exch-Applies-To-Smtp-VS-BL,${SCHEMADN} attributeID: 1.2.840.113556.1.4.7000.102.5059 attributeSyntax: 2.5.5.1 isSingleValued: FALSE linkID: 1035 showInAdvancedViewOnly: TRUE adminDisplayName: ms-Exch-Applies-To-Smtp-VS-BL oMObjectClass:: KwwCh3McAIVK adminDescription: ms-Exch-Applies-To-Smtp-VS-BL oMSyntax: 127 searchFlags: 0 lDAPDisplayName: msExchAppliesToSmtpVSBL name: ms-Exch-Applies-To-Smtp-VS-BL schemaIDGUID: f7d091b1-1ced-446a-b521-563a01eaf22c systemFlags: 1 isMemberOfPartialAttributeSet: FALSE objectCategory: CN=Attribute-Schema,${SCHEMADN} # # ms-Exch-Assistant-Name # #dn: CN=ms-Exch-Assistant-Name,${SCHEMADN} #objectClass: top #objectClass: attributeSchema #cn: ms-Exch-Assistant-Name #distinguishedName: CN=ms-Exch-Assistant-Name,${SCHEMADN} #attributeID: 1.2.840.113556.1.2.444 #attributeSyntax: 2.5.5.12 #isSingleValued: TRUE #rangeLower: 1 #rangeUpper: 256 #mAPIID: 14896 #adminDisplayName: ms-Exch-Assistant-Name #adminDescription: ms-Exch-Assistant-Name #oMSyntax: 64 #searchFlags: 0 #lDAPDisplayName: msExchAssistantName #name: ms-Exch-Assistant-Name #schemaIDGUID: a8df7394-c5ea-11d1-bbcb-0080c76670c0 #attributeSecurityGUID: e48d0154-bcf8-11d1-8702-00c04fb96050 #objectCategory: CN=Attribute-Schema,${SCHEMADN} # # ms-Exch-Associated-AG # dn: CN=ms-Exch-Associated-AG,${SCHEMADN} objectClass: top objectClass: attributeSchema cn: ms-Exch-Associated-AG distinguishedName: CN=ms-Exch-Associated-AG,${SCHEMADN} attributeID: 1.2.840.113556.1.4.7000.102.50031 attributeSyntax: 2.5.5.1 isSingleValued: TRUE showInAdvancedViewOnly: TRUE adminDisplayName: ms-Exch-Associated-AG oMObjectClass:: KwwCh3McAIVK adminDescription: ms-Exch-Associated-AG oMSyntax: 127 searchFlags: 0 lDAPDisplayName: msExchAssociatedAG name: ms-Exch-Associated-AG schemaIDGUID: e5971321-1d3e-11d3-aa5e-00c04f8eedd8 isMemberOfPartialAttributeSet: FALSE objectCategory: CN=Attribute-Schema,${SCHEMADN} # # ms-Exch-Association-Lifetime # The length of time a connection can be idle before it is closed. # dn: CN=ms-Exch-Association-Lifetime,${SCHEMADN} objectClass: top objectClass: attributeSchema cn: ms-Exch-Association-Lifetime distinguishedName: CN=ms-Exch-Association-Lifetime,${SCHEMADN} attributeID: 1.2.840.113556.1.2.149 attributeSyntax: 2.5.5.9 isSingleValued: TRUE rangeLower: 0 rangeUpper: 32767 mAPIID: 32850 showInAdvancedViewOnly: TRUE adminDisplayName: ms-Exch-Association-Lifetime adminDescription: ms-Exch-Association-Lifetime oMSyntax: 2 searchFlags: 0 lDAPDisplayName: associationLifetime name: ms-Exch-Association-Lifetime schemaIDGUID: a8df7396-c5ea-11d1-bbcb-0080c76670c0 isMemberOfPartialAttributeSet: FALSE objectCategory: CN=Attribute-Schema,${SCHEMADN} # # ms-Exch-Assoc-Remote-DXA # dn: CN=ms-Exch-Assoc-Remote-DXA,${SCHEMADN} objectClass: top objectClass: attributeSchema cn: ms-Exch-Assoc-Remote-DXA distinguishedName: CN=ms-Exch-Assoc-Remote-DXA,${SCHEMADN} attributeID: 1.2.840.113556.1.2.299 attributeSyntax: 2.5.5.1 isSingleValued: FALSE mAPIID: 32849 linkID: 123 showInAdvancedViewOnly: TRUE adminDisplayName: ms-Exch-Assoc-Remote-DXA oMObjectClass:: KwwCh3McAIVK adminDescription: ms-Exch-Assoc-Remote-DXA oMSyntax: 127 searchFlags: 0 lDAPDisplayName: assocRemoteDXA name: ms-Exch-Assoc-Remote-DXA schemaIDGUID: 16775789-47f3-11d1-a9c3-0000f80367c1 systemFlags: 1 isMemberOfPartialAttributeSet: FALSE objectCategory: CN=Attribute-Schema,${SCHEMADN} # # ms-Exch-Attribute-Certificate # dn: CN=ms-Exch-Attribute-Certificate,${SCHEMADN} objectClass: top objectClass: attributeSchema cn: ms-Exch-Attribute-Certificate distinguishedName: CN=ms-Exch-Attribute-Certificate,${SCHEMADN} attributeID: 1.2.840.113556.1.2.587 attributeSyntax: 2.5.5.10 isSingleValued: FALSE rangeLower: 1 rangeUpper: 32767 mAPIID: 35909 showInAdvancedViewOnly: TRUE adminDisplayName: ms-Exch-Attribute-Certificate adminDescription: ms-Exch-Attribute-Certificate oMSyntax: 4 searchFlags: 0 lDAPDisplayName: attributeCertificate name: ms-Exch-Attribute-Certificate schemaIDGUID: 1677578b-47f3-11d1-a9c3-0000f80367c1 attributeSecurityGUID: e48d0154-bcf8-11d1-8702-00c04fb96050 isMemberOfPartialAttributeSet: TRUE objectCategory: CN=Attribute-Schema,${SCHEMADN} # # ms-Exch-Audit-Flags # A bitmap indicating the events to log. # dn: CN=ms-Exch-Audit-Flags,${SCHEMADN} objectClass: top objectClass: attributeSchema cn: ms-Exch-Audit-Flags distinguishedName: CN=ms-Exch-Audit-Flags,${SCHEMADN} attributeID: 1.2.840.113556.1.4.7000.102.9004 attributeSyntax: 2.5.5.9 isSingleValued: TRUE showInAdvancedViewOnly: TRUE adminDisplayName: ms-Exch-Audit-Flags adminDescription: ms-Exch-Audit-Flags oMSyntax: 2 searchFlags: 0 lDAPDisplayName: msExchAuditFlags name: ms-Exch-Audit-Flags schemaIDGUID: 91d47d0e-b093-11d2-aa06-00c04f8eedd8 isMemberOfPartialAttributeSet: FALSE objectCategory: CN=Attribute-Schema,${SCHEMADN} # # ms-Exch-Authentication-Flags # Indicates which type of authentication this resource accepts. # dn: CN=ms-Exch-Authentication-Flags,${SCHEMADN} objectClass: top objectClass: attributeSchema cn: ms-Exch-Authentication-Flags distinguishedName: CN=ms-Exch-Authentication-Flags,${SCHEMADN} attributeID: 1.2.840.113556.1.4.7000.102.2003 attributeSyntax: 2.5.5.9 isSingleValued: TRUE showInAdvancedViewOnly: TRUE adminDisplayName: ms-Exch-Authentication-Flags adminDescription: ms-Exch-Authentication-Flags oMSyntax: 2 searchFlags: 0 lDAPDisplayName: msExchAuthenticationFlags name: ms-Exch-Authentication-Flags schemaIDGUID: 91f5ddfa-b093-11d2-aa06-00c04f8eedd8 isMemberOfPartialAttributeSet: FALSE objectCategory: CN=Attribute-Schema,${SCHEMADN} # # ms-Exch-AuthMailDisposition # dn: CN=ms-Exch-AuthMailDisposition,${SCHEMADN} objectClass: top objectClass: attributeSchema cn: ms-Exch-AuthMailDisposition distinguishedName: CN=ms-Exch-AuthMailDisposition,${SCHEMADN} attributeID: 1.2.840.113556.1.4.5061 attributeSyntax: 2.5.5.9 isSingleValued: TRUE showInAdvancedViewOnly: TRUE adminDisplayName: ms-Exch-AuthMailDisposition adminDescription: ms-Exch-AuthMailDisposition oMSyntax: 2 searchFlags: 0 lDAPDisplayName: msExchAuthMailDisposition name: ms-Exch-AuthMailDisposition schemaIDGUID: 57cfb6f7-1e2c-4d3e-96df-40208624baff isMemberOfPartialAttributeSet: FALSE objectCategory: CN=Attribute-Schema,${SCHEMADN} # # ms-Exch-Authorization-Persistence # dn: CN=ms-Exch-Authorization-Persistence,${SCHEMADN} objectClass: top objectClass: attributeSchema cn: ms-Exch-Authorization-Persistence distinguishedName: CN=ms-Exch-Authorization-Persistence,${SCHEMADN} attributeID: 1.2.840.113556.1.4.7000.102.15011 attributeSyntax: 2.5.5.9 isSingleValued: TRUE showInAdvancedViewOnly: TRUE adminDisplayName: ms-Exch-Authorization-Persistence adminDescription: ms-Exch-Authorization-Persistence oMSyntax: 2 searchFlags: 0 lDAPDisplayName: msExchAuthorizationPersistence name: ms-Exch-Authorization-Persistence schemaIDGUID: d6ae616b-16c5-44ce-b272-8b923aebe335 isMemberOfPartialAttributeSet: FALSE objectCategory: CN=Attribute-Schema,${SCHEMADN} # # ms-Exch-Authorized-Domain # The domain name of the authentication account to be used when # connecting to the other side of the connector. # dn: CN=ms-Exch-Authorized-Domain,${SCHEMADN} objectClass: top objectClass: attributeSchema cn: ms-Exch-Authorized-Domain distinguishedName: CN=ms-Exch-Authorized-Domain,${SCHEMADN} attributeID: 1.2.840.113556.1.2.202 attributeSyntax: 2.5.5.12 isSingleValued: TRUE rangeLower: 1 rangeUpper: 15 mAPIID: 32852 showInAdvancedViewOnly: TRUE adminDisplayName: ms-Exch-Authorized-Domain adminDescription: ms-Exch-Authorized-Domain oMSyntax: 64 searchFlags: 0 lDAPDisplayName: authorizedDomain name: ms-Exch-Authorized-Domain schemaIDGUID: a8df739a-c5ea-11d1-bbcb-0080c76670c0 isMemberOfPartialAttributeSet: FALSE objectCategory: CN=Attribute-Schema,${SCHEMADN} # # ms-Exch-Authorized-Password # The password of the authentication account to be used when connecting # to the other side of the connector. # dn: CN=ms-Exch-Authorized-Password,${SCHEMADN} objectClass: top objectClass: attributeSchema cn: ms-Exch-Authorized-Password distinguishedName: CN=ms-Exch-Authorized-Password,${SCHEMADN} attributeID: 1.2.840.113556.1.2.193 attributeSyntax: 2.5.5.10 isSingleValued: TRUE rangeLower: 1 rangeUpper: 512 mAPIID: 32853 showInAdvancedViewOnly: TRUE adminDisplayName: ms-Exch-Authorized-Password adminDescription: ms-Exch-Authorized-Password oMSyntax: 4 searchFlags: 0 lDAPDisplayName: authorizedPassword name: ms-Exch-Authorized-Password schemaIDGUID: a8df739b-c5ea-11d1-bbcb-0080c76670c0 isMemberOfPartialAttributeSet: FALSE objectCategory: CN=Attribute-Schema,${SCHEMADN} # # ms-Exch-Authorized-User # The user name of the authentication account to be used when connecting # to the other side of the connector. # dn: CN=ms-Exch-Authorized-User,${SCHEMADN} objectClass: top objectClass: attributeSchema cn: ms-Exch-Authorized-User distinguishedName: CN=ms-Exch-Authorized-User,${SCHEMADN} attributeID: 1.2.840.113556.1.2.276 attributeSyntax: 2.5.5.12 isSingleValued: TRUE rangeLower: 1 rangeUpper: 512 mAPIID: 32854 showInAdvancedViewOnly: TRUE adminDisplayName: ms-Exch-Authorized-User adminDescription: ms-Exch-Authorized-User oMSyntax: 64 searchFlags: 0 lDAPDisplayName: authorizedUser name: ms-Exch-Authorized-User schemaIDGUID: a8df739d-c5ea-11d1-bbcb-0080c76670c0 isMemberOfPartialAttributeSet: FALSE objectCategory: CN=Attribute-Schema,${SCHEMADN} # # ms-Exch-Auth-Orig # The users who are allowed to send mail to this recipient. # dn: CN=ms-Exch-Auth-Orig,${SCHEMADN} objectClass: top objectClass: attributeSchema cn: ms-Exch-Auth-Orig distinguishedName: CN=ms-Exch-Auth-Orig,${SCHEMADN} attributeID: 1.2.840.113556.1.2.129 attributeSyntax: 2.5.5.7 isSingleValued: FALSE linkID: 110 showInAdvancedViewOnly: TRUE adminDisplayName: ms-Exch-Auth-Orig oMObjectClass:: VgYBAgULHQ== adminDescription: ms-Exch-Auth-Orig oMSyntax: 127 searchFlags: 16 lDAPDisplayName: authOrig name: ms-Exch-Auth-Orig schemaIDGUID: a8df7397-c5ea-11d1-bbcb-0080c76670c0 attributeSecurityGUID: e48d0154-bcf8-11d1-8702-00c04fb96050 isMemberOfPartialAttributeSet: TRUE objectCategory: CN=Attribute-Schema,${SCHEMADN} # # ms-Exch-Auth-Orig-BL # A backlink to ms-Exch-Auth-Orig. # dn: CN=ms-Exch-Auth-Orig-BL,${SCHEMADN} objectClass: top objectClass: attributeSchema cn: ms-Exch-Auth-Orig-BL distinguishedName: CN=ms-Exch-Auth-Orig-BL,${SCHEMADN} attributeID: 1.2.840.113556.1.2.290 attributeSyntax: 2.5.5.1 isSingleValued: FALSE mAPIID: 32851 linkID: 111 showInAdvancedViewOnly: TRUE adminDisplayName: ms-Exch-Auth-Orig-BL oMObjectClass:: KwwCh3McAIVK adminDescription: ms-Exch-Auth-Orig-BL oMSyntax: 127 searchFlags: 0 lDAPDisplayName: authOrigBL name: ms-Exch-Auth-Orig-BL schemaIDGUID: a8df7398-c5ea-11d1-bbcb-0080c76670c0 attributeSecurityGUID: e48d0154-bcf8-11d1-8702-00c04fb96050 systemFlags: 1 isMemberOfPartialAttributeSet: TRUE objectCategory: CN=Attribute-Schema,${SCHEMADN} # # ms-Exch-AutoReply # dn: CN=ms-Exch-AutoReply,${SCHEMADN} objectClass: top objectClass: attributeSchema cn: ms-Exch-AutoReply distinguishedName: CN=ms-Exch-AutoReply,${SCHEMADN} attributeID: 1.2.840.113556.1.2.286 attributeSyntax: 2.5.5.8 isSingleValued: TRUE mAPIID: 32779 showInAdvancedViewOnly: TRUE adminDisplayName: ms-Exch-AutoReply adminDescription: ms-Exch-AutoReply oMSyntax: 1 searchFlags: 0 lDAPDisplayName: autoReply name: ms-Exch-AutoReply schemaIDGUID: bf967929-0de6-11d0-a285-00aa003049e2 attributeSecurityGUID: e48d0154-bcf8-11d1-8702-00c04fb96050 isMemberOfPartialAttributeSet: TRUE objectCategory: CN=Attribute-Schema,${SCHEMADN} # # ms-Exch-AutoReply-Message # Contains Internet Locator Service (ILS) settings in the form # SERVER/ACCOUNT. # dn: CN=ms-Exch-AutoReply-Message,${SCHEMADN} objectClass: top objectClass: attributeSchema cn: ms-Exch-AutoReply-Message distinguishedName: CN=ms-Exch-AutoReply-Message,${SCHEMADN} attributeID: 1.2.840.113556.1.2.287 attributeSyntax: 2.5.5.12 isSingleValued: TRUE rangeLower: 1 rangeUpper: 1024 mAPIID: 32778 showInAdvancedViewOnly: TRUE adminDisplayName: ms-Exch-AutoReply-Message adminDescription: ms-Exch-AutoReply-Message oMSyntax: 64 searchFlags: 0 lDAPDisplayName: autoReplyMessage name: ms-Exch-AutoReply-Message schemaIDGUID: bf96792a-0de6-11d0-a285-00aa003049e2 attributeSecurityGUID: e48d0154-bcf8-11d1-8702-00c04fb96050 isMemberOfPartialAttributeSet: FALSE objectCategory: CN=Attribute-Schema,${SCHEMADN} # # ms-Exch-Available-Authorization-Packages # dn: CN=ms-Exch-Available-Authorization-Packages,${SCHEMADN} objectClass: top objectClass: attributeSchema cn: ms-Exch-Available-Authorization-Packages distinguishedName: CN=ms-Exch-Available-Authorization-Packages,${SCHEMADN} attributeID: 1.2.840.113556.1.2.476 attributeSyntax: 2.5.5.12 isSingleValued: FALSE rangeLower: 1 rangeUpper: 512 mAPIID: 33153 showInAdvancedViewOnly: TRUE adminDisplayName: ms-Exch-Available-Authorization-Packages adminDescription: ms-Exch-Available-Authorization-Packages oMSyntax: 64 searchFlags: 0 lDAPDisplayName: availableAuthorizationPackages name: ms-Exch-Available-Authorization-Packages schemaIDGUID: a8df739e-c5ea-11d1-bbcb-0080c76670c0 isMemberOfPartialAttributeSet: FALSE objectCategory: CN=Attribute-Schema,${SCHEMADN} # # ms-Exch-Available-Distributions # dn: CN=ms-Exch-Available-Distributions,${SCHEMADN} objectClass: top objectClass: attributeSchema cn: ms-Exch-Available-Distributions distinguishedName: CN=ms-Exch-Available-Distributions,${SCHEMADN} attributeID: 1.2.840.113556.1.2.486 attributeSyntax: 2.5.5.5 isSingleValued: TRUE rangeLower: 1 rangeUpper: 10240 mAPIID: 33163 showInAdvancedViewOnly: TRUE adminDisplayName: ms-Exch-Available-Distributions adminDescription: ms-Exch-Available-Distributions oMSyntax: 19 searchFlags: 0 lDAPDisplayName: availableDistributions name: ms-Exch-Available-Distributions schemaIDGUID: a8df739f-c5ea-11d1-bbcb-0080c76670c0 isMemberOfPartialAttributeSet: FALSE objectCategory: CN=Attribute-Schema,${SCHEMADN} # # ms-Exch-Available-Servers # The installed conferencing servers. # dn: CN=ms-Exch-Available-Servers,${SCHEMADN} objectClass: top objectClass: attributeSchema cn: ms-Exch-Available-Servers distinguishedName: CN=ms-Exch-Available-Servers,${SCHEMADN} attributeID: 1.2.840.113556.1.4.7000.102.9020 attributeSyntax: 2.5.5.12 isSingleValued: FALSE showInAdvancedViewOnly: TRUE adminDisplayName: ms-Exch-Available-Servers adminDescription: ms-Exch-Available-Servers oMSyntax: 64 searchFlags: 0 lDAPDisplayName: msExchAvailableServers name: ms-Exch-Available-Servers schemaIDGUID: 923b022c-b093-11d2-aa06-00c04f8eedd8 isMemberOfPartialAttributeSet: FALSE objectCategory: CN=Attribute-Schema,${SCHEMADN} # # ms-Exch-BackEnd-VDir-URL # dn: CN=ms-Exch-BackEnd-VDir-URL,${SCHEMADN} objectClass: top objectClass: attributeSchema cn: ms-Exch-BackEnd-VDir-URL distinguishedName: CN=ms-Exch-BackEnd-VDir-URL,${SCHEMADN} attributeID: 1.2.840.113556.1.4.7000.102.15012 attributeSyntax: 2.5.5.12 isSingleValued: TRUE showInAdvancedViewOnly: TRUE adminDisplayName: ms-Exch-BackEnd-VDir-URL adminDescription: ms-Exch-BackEnd-VDir-URL oMSyntax: 64 searchFlags: 0 lDAPDisplayName: msExchBackEndVDirURL name: ms-Exch-BackEnd-VDir-URL schemaIDGUID: b4b283b6-0c3f-4a59-9e50-be9026228231 isMemberOfPartialAttributeSet: FALSE objectCategory: CN=Attribute-Schema,${SCHEMADN} # # ms-Exch-Background-Threads # The maximum number of background threads per server. # dn: CN=ms-Exch-Background-Threads,${SCHEMADN} objectClass: top objectClass: attributeSchema cn: ms-Exch-Background-Threads distinguishedName: CN=ms-Exch-Background-Threads,${SCHEMADN} attributeID: 1.2.840.113556.1.4.7000.102.11038 attributeSyntax: 2.5.5.9 isSingleValued: TRUE showInAdvancedViewOnly: TRUE adminDisplayName: ms-Exch-Background-Threads adminDescription: ms-Exch-Background-Threads oMSyntax: 2 searchFlags: 0 lDAPDisplayName: msExchBackgroundThreads name: ms-Exch-Background-Threads schemaIDGUID: 93d051f0-b093-11d2-aa06-00c04f8eedd8 isMemberOfPartialAttributeSet: FALSE objectCategory: CN=Attribute-Schema,${SCHEMADN} # # ms-Exch-Bar-Message-Class # dn: CN=ms-Exch-Bar-Message-Class,${SCHEMADN} objectClass: top objectClass: attributeSchema cn: ms-Exch-Bar-Message-Class distinguishedName: CN=ms-Exch-Bar-Message-Class,${SCHEMADN} attributeID: 1.2.840.113556.1.4.7000.102.1064 attributeSyntax: 2.5.5.12 isSingleValued: FALSE showInAdvancedViewOnly: TRUE adminDisplayName: ms-Exch-Bar-Message-Class adminDescription: ms-Exch-Bar-Message-Class oMSyntax: 64 searchFlags: 0 lDAPDisplayName: msExchBarMessageClass name: ms-Exch-Bar-Message-Class schemaIDGUID: cf43e549-2ae1-410f-b896-02e40b934373 isMemberOfPartialAttributeSet: FALSE objectCategory: CN=Attribute-Schema,${SCHEMADN} # # ms-Exch-Basic-Authentication-Domain # The default domain name for incoming basic authentication. # dn: CN=ms-Exch-Basic-Authentication-Domain,${SCHEMADN} objectClass: top objectClass: attributeSchema cn: ms-Exch-Basic-Authentication-Domain distinguishedName: CN=ms-Exch-Basic-Authentication-Domain,${SCHEMADN} attributeID: 1.2.840.113556.1.4.7000.102.2010 attributeSyntax: 2.5.5.12 isSingleValued: TRUE showInAdvancedViewOnly: TRUE adminDisplayName: ms-Exch-Basic-Authentication-Domain adminDescription: ms-Exch-Basic-Authentication-Domain oMSyntax: 64 searchFlags: 0 lDAPDisplayName: msExchBasicAuthenticationDomain name: ms-Exch-Basic-Authentication-Domain schemaIDGUID: 94262698-b093-11d2-aa06-00c04f8eedd8 isMemberOfPartialAttributeSet: FALSE objectCategory: CN=Attribute-Schema,${SCHEMADN} # # ms-Exch-Bridgeheaded-Local-Connectors-DN-BL # A list of connectors (in the VSI's routing group) that this VSI is # the bridgehead for. # dn: CN=ms-Exch-Bridgeheaded-Local-Connectors-DN-BL,${SCHEMADN} objectClass: top objectClass: attributeSchema cn: ms-Exch-Bridgeheaded-Local-Connectors-DN-BL distinguishedName: CN=ms-Exch-Bridgeheaded-Local-Connectors-DN-BL,${SCHEMADN} attributeID: 1.2.840.113556.1.4.7000.102.12515 attributeSyntax: 2.5.5.1 isSingleValued: TRUE linkID: 1003 showInAdvancedViewOnly: TRUE adminDisplayName: ms-Exch-Bridgeheaded-Local-Connectors-DN-BL oMObjectClass:: KwwCh3McAIVK adminDescription: ms-Exch-Bridgeheaded-Local-Connectors-DN-BL oMSyntax: 127 searchFlags: 0 lDAPDisplayName: msExchBridgeheadedLocalConnectorsDNBL name: ms-Exch-Bridgeheaded-Local-Connectors-DN-BL schemaIDGUID: 944c4c38-b093-11d2-aa06-00c04f8eedd8 systemFlags: 1 isMemberOfPartialAttributeSet: FALSE objectCategory: CN=Attribute-Schema,${SCHEMADN} # # ms-Exch-Bridgeheaded-Remote-Connectors-DN-BL # A list of connectors (in a remote routing group) that this VSI is # the bridgehead for. # dn: CN=ms-Exch-Bridgeheaded-Remote-Connectors-DN-BL,${SCHEMADN} objectClass: top objectClass: attributeSchema cn: ms-Exch-Bridgeheaded-Remote-Connectors-DN-BL distinguishedName: CN=ms-Exch-Bridgeheaded-Remote-Connectors-DN-BL,${SCHEMADN} attributeID: 1.2.840.113556.1.4.7000.102.12516 attributeSyntax: 2.5.5.1 isSingleValued: TRUE linkID: 1005 showInAdvancedViewOnly: TRUE adminDisplayName: ms-Exch-Bridgeheaded-Remote-Connectors-DN-BL oMObjectClass:: KwwCh3McAIVK adminDescription: ms-Exch-Bridgeheaded-Remote-Connectors-DN-BL oMSyntax: 127 searchFlags: 0 lDAPDisplayName: msExchBridgeheadedRemoteConnectorsDNBL name: ms-Exch-Bridgeheaded-Remote-Connectors-DN-BL schemaIDGUID: 946dad24-b093-11d2-aa06-00c04f8eedd8 systemFlags: 1 isMemberOfPartialAttributeSet: FALSE objectCategory: CN=Attribute-Schema,${SCHEMADN} # # ms-Exch-Bridgehead-Servers # dn: CN=ms-Exch-Bridgehead-Servers,${SCHEMADN} objectClass: top objectClass: attributeSchema cn: ms-Exch-Bridgehead-Servers distinguishedName: CN=ms-Exch-Bridgehead-Servers,${SCHEMADN} attributeID: 1.2.840.113556.1.2.463 attributeSyntax: 2.5.5.1 isSingleValued: FALSE mAPIID: 33140 showInAdvancedViewOnly: TRUE adminDisplayName: ms-Exch-Bridgehead-Servers oMObjectClass:: KwwCh3McAIVK adminDescription: ms-Exch-Bridgehead-Servers oMSyntax: 127 searchFlags: 0 lDAPDisplayName: bridgeheadServers name: ms-Exch-Bridgehead-Servers schemaIDGUID: a8df73a0-c5ea-11d1-bbcb-0080c76670c0 isMemberOfPartialAttributeSet: FALSE objectCategory: CN=Attribute-Schema,${SCHEMADN} # # ms-Exch-Business-Roles # dn: CN=ms-Exch-Business-Roles,${SCHEMADN} objectClass: top objectClass: attributeSchema cn: ms-Exch-Business-Roles distinguishedName: CN=ms-Exch-Business-Roles,${SCHEMADN} attributeID: 1.2.840.113556.1.2.105 attributeSyntax: 2.5.5.10 isSingleValued: TRUE rangeLower: 1 rangeUpper: 4096 mAPIID: 32803 showInAdvancedViewOnly: TRUE adminDisplayName: ms-Exch-Business-Roles adminDescription: ms-Exch-Business-Roles oMSyntax: 4 searchFlags: 0 lDAPDisplayName: businessRoles name: ms-Exch-Business-Roles schemaIDGUID: f0f8ff87-1191-11d0-a060-00aa006c33ed isMemberOfPartialAttributeSet: FALSE objectCategory: CN=Attribute-Schema,${SCHEMADN} # # ms-Exch-CalCon-Client-Wait # dn: CN=ms-Exch-CalCon-Client-Wait,${SCHEMADN} objectClass: top objectClass: attributeSchema cn: ms-Exch-CalCon-Client-Wait distinguishedName: CN=ms-Exch-CalCon-Client-Wait,${SCHEMADN} attributeID: 1.2.840.113556.1.4.7000.102.1043 attributeSyntax: 2.5.5.9 isSingleValued: TRUE showInAdvancedViewOnly: TRUE adminDisplayName: ms-Exch-CalCon-Client-Wait adminDescription: ms-Exch-CalCon-Client-Wait oMSyntax: 2 searchFlags: 0 lDAPDisplayName: msExchCalConClientWait name: ms-Exch-CalCon-Client-Wait schemaIDGUID: 75447978-3752-4256-a89f-b4dfebae9a32 isMemberOfPartialAttributeSet: FALSE objectCategory: CN=Attribute-Schema,${SCHEMADN} # # ms-Exch-CalCon-Providers # dn: CN=ms-Exch-CalCon-Providers,${SCHEMADN} objectClass: top objectClass: attributeSchema cn: ms-Exch-CalCon-Providers distinguishedName: CN=ms-Exch-CalCon-Providers,${SCHEMADN} attributeID: 1.2.840.113556.1.4.7000.102.1042 attributeSyntax: 2.5.5.12 isSingleValued: FALSE showInAdvancedViewOnly: TRUE adminDisplayName: ms-Exch-CalCon-Providers adminDescription: ms-Exch-CalCon-Providers oMSyntax: 64 searchFlags: 0 lDAPDisplayName: msExchCalConProviders name: ms-Exch-CalCon-Providers schemaIDGUID: 73b41a3e-68b0-45a1-9e30-697b6d19aee6 isMemberOfPartialAttributeSet: FALSE objectCategory: CN=Attribute-Schema,${SCHEMADN} # # ms-Exch-CalCon-Query-Window # dn: CN=ms-Exch-CalCon-Query-Window,${SCHEMADN} objectClass: top objectClass: attributeSchema cn: ms-Exch-CalCon-Query-Window distinguishedName: CN=ms-Exch-CalCon-Query-Window,${SCHEMADN} attributeID: 1.2.840.113556.1.4.7000.102.1040 attributeSyntax: 2.5.5.9 isSingleValued: TRUE showInAdvancedViewOnly: TRUE adminDisplayName: ms-Exch-CalCon-Query-Window adminDescription: ms-Exch-CalCon-Query-Window oMSyntax: 2 searchFlags: 0 lDAPDisplayName: msExchCalConQueryWindow name: ms-Exch-CalCon-Query-Window schemaIDGUID: 5ebb881a-19d4-4526-b6f7-cc46d9aa1869 isMemberOfPartialAttributeSet: FALSE objectCategory: CN=Attribute-Schema,${SCHEMADN} # # ms-Exch-CalCon-Refresh-Interval # dn: CN=ms-Exch-CalCon-Refresh-Interval,${SCHEMADN} objectClass: top objectClass: attributeSchema cn: ms-Exch-CalCon-Refresh-Interval distinguishedName: CN=ms-Exch-CalCon-Refresh-Interval,${SCHEMADN} attributeID: 1.2.840.113556.1.4.7000.102.1041 attributeSyntax: 2.5.5.9 isSingleValued: TRUE showInAdvancedViewOnly: TRUE adminDisplayName: ms-Exch-CalCon-Refresh-Interval adminDescription: ms-Exch-CalCon-Refresh-Interval oMSyntax: 2 searchFlags: 0 lDAPDisplayName: msExchCalConRefreshInterval name: ms-Exch-CalCon-Refresh-Interval schemaIDGUID: 22bf39b6-7528-412c-b277-aa268db43960 isMemberOfPartialAttributeSet: FALSE objectCategory: CN=Attribute-Schema,${SCHEMADN} # # ms-Exch-CalCon-Target-SiteDN # dn: CN=ms-Exch-CalCon-Target-SiteDN,${SCHEMADN} objectClass: top objectClass: attributeSchema cn: ms-Exch-CalCon-Target-SiteDN distinguishedName: CN=ms-Exch-CalCon-Target-SiteDN,${SCHEMADN} attributeID: 1.2.840.113556.1.4.7000.102.1044 attributeSyntax: 2.5.5.12 isSingleValued: TRUE showInAdvancedViewOnly: TRUE adminDisplayName: ms-Exch-CalCon-Target-SiteDN adminDescription: ms-Exch-CalCon-Target-SiteDN oMSyntax: 64 searchFlags: 0 lDAPDisplayName: msExchCalConTargetSiteDN name: ms-Exch-CalCon-Target-SiteDN schemaIDGUID: 33b45526-8e8b-4679-97c3-4eeff39c7fbd isMemberOfPartialAttributeSet: FALSE objectCategory: CN=Attribute-Schema,${SCHEMADN} # # ms-Exch-Can-Preserve-DNs # dn: CN=ms-Exch-Can-Preserve-DNs,${SCHEMADN} objectClass: top objectClass: attributeSchema cn: ms-Exch-Can-Preserve-DNs distinguishedName: CN=ms-Exch-Can-Preserve-DNs,${SCHEMADN} attributeID: 1.2.840.113556.1.2.455 attributeSyntax: 2.5.5.8 isSingleValued: TRUE mAPIID: 32864 showInAdvancedViewOnly: TRUE adminDisplayName: ms-Exch-Can-Preserve-DNs adminDescription: ms-Exch-Can-Preserve-DNs oMSyntax: 1 searchFlags: 0 lDAPDisplayName: canPreserveDNs name: ms-Exch-Can-Preserve-DNs schemaIDGUID: a8df73a9-c5ea-11d1-bbcb-0080c76670c0 isMemberOfPartialAttributeSet: FALSE objectCategory: CN=Attribute-Schema,${SCHEMADN} # # ms-Exch-Catalog # The globally unique identifier (GUID) of the catalog for this message # database (MDB). # dn: CN=ms-Exch-Catalog,${SCHEMADN} objectClass: top objectClass: attributeSchema cn: ms-Exch-Catalog distinguishedName: CN=ms-Exch-Catalog,${SCHEMADN} attributeID: 1.2.840.113556.1.4.7000.102.11052 attributeSyntax: 2.5.5.10 isSingleValued: TRUE showInAdvancedViewOnly: TRUE adminDisplayName: ms-Exch-Catalog adminDescription: ms-Exch-Catalog oMSyntax: 4 searchFlags: 0 lDAPDisplayName: msExchCatalog name: ms-Exch-Catalog schemaIDGUID: 94abaa48-b093-11d2-aa06-00c04f8eedd8 isMemberOfPartialAttributeSet: FALSE objectCategory: CN=Attribute-Schema,${SCHEMADN} # # ms-Exch-CA-Schema-Policy # A link to a schema policy that this certification authority (CA) # uses. # dn: CN=ms-Exch-CA-Schema-Policy,${SCHEMADN} objectClass: top objectClass: attributeSchema cn: ms-Exch-CA-Schema-Policy distinguishedName: CN=ms-Exch-CA-Schema-Policy,${SCHEMADN} attributeID: 1.2.840.113556.1.4.7000.102.56 attributeSyntax: 2.5.5.1 isSingleValued: TRUE linkID: 1006 showInAdvancedViewOnly: TRUE adminDisplayName: ms-Exch-CA-Schema-Policy oMObjectClass:: KwwCh3McAIVK adminDescription: ms-Exch-CA-Schema-Policy oMSyntax: 127 searchFlags: 0 lDAPDisplayName: msExchCASchemaPolicy name: ms-Exch-CA-Schema-Policy schemaIDGUID: 948f0e10-b093-11d2-aa06-00c04f8eedd8 isMemberOfPartialAttributeSet: FALSE objectCategory: CN=Attribute-Schema,${SCHEMADN} # # ms-Exch-ccMail-ADE-Prop # Allows the Automatic Directory Exchange (ADE) to propagate # synchronized entries to downstream cc:Mail post offices. # dn: CN=ms-Exch-ccMail-ADE-Prop,${SCHEMADN} objectClass: top objectClass: attributeSchema cn: ms-Exch-ccMail-ADE-Prop distinguishedName: CN=ms-Exch-ccMail-ADE-Prop,${SCHEMADN} attributeID: 1.2.840.113556.1.4.7000.102.1036 attributeSyntax: 2.5.5.8 isSingleValued: TRUE showInAdvancedViewOnly: TRUE adminDisplayName: ms-Exch-ccMail-ADE-Prop adminDescription: ms-Exch-ccMail-ADE-Prop oMSyntax: 1 searchFlags: 0 lDAPDisplayName: msExchccMailADEProp name: ms-Exch-ccMail-ADE-Prop schemaIDGUID: 94caa8da-b093-11d2-aa06-00c04f8eedd8 isMemberOfPartialAttributeSet: FALSE objectCategory: CN=Attribute-Schema,${SCHEMADN} # # ms-Exch-ccMail-Connect-As-Password # dn: CN=ms-Exch-ccMail-Connect-As-Password,${SCHEMADN} objectClass: top objectClass: attributeSchema cn: ms-Exch-ccMail-Connect-As-Password distinguishedName: CN=ms-Exch-ccMail-Connect-As-Password,${SCHEMADN} attributeID: 1.2.840.113556.1.4.7000.102.1207 attributeSyntax: 2.5.5.10 isSingleValued: TRUE showInAdvancedViewOnly: TRUE adminDisplayName: ms-Exch-ccMail-Connect-As-Password adminDescription: ms-Exch-ccMail-Connect-As-Password oMSyntax: 4 searchFlags: 0 lDAPDisplayName: msExchccMailConnectAsPassword name: ms-Exch-ccMail-Connect-As-Password schemaIDGUID: b8d47e43-4b78-11d3-aa75-00c04f8eedd8 isMemberOfPartialAttributeSet: FALSE objectCategory: CN=Attribute-Schema,${SCHEMADN} # # ms-Exch-ccMail-Connect-As-Userid # dn: CN=ms-Exch-ccMail-Connect-As-Userid,${SCHEMADN} objectClass: top objectClass: attributeSchema cn: ms-Exch-ccMail-Connect-As-Userid distinguishedName: CN=ms-Exch-ccMail-Connect-As-Userid,${SCHEMADN} attributeID: 1.2.840.113556.1.4.7000.102.1206 attributeSyntax: 2.5.5.12 isSingleValued: TRUE showInAdvancedViewOnly: TRUE adminDisplayName: ms-Exch-ccMail-Connect-As-Userid adminDescription: ms-Exch-ccMail-Connect-As-Userid oMSyntax: 64 searchFlags: 0 lDAPDisplayName: msExchccMailConnectAsUserid name: ms-Exch-ccMail-Connect-As-Userid schemaIDGUID: b8d47e3c-4b78-11d3-aa75-00c04f8eedd8 isMemberOfPartialAttributeSet: FALSE objectCategory: CN=Attribute-Schema,${SCHEMADN} # # ms-Exch-ccMail-Password # The Administrator password to the cc:Mail post office. # dn: CN=ms-Exch-ccMail-Password,${SCHEMADN} objectClass: top objectClass: attributeSchema cn: ms-Exch-ccMail-Password distinguishedName: CN=ms-Exch-ccMail-Password,${SCHEMADN} attributeID: 1.2.840.113556.1.4.7000.102.1039 attributeSyntax: 2.5.5.10 isSingleValued: TRUE showInAdvancedViewOnly: TRUE adminDisplayName: ms-Exch-ccMail-Password adminDescription: ms-Exch-ccMail-Password oMSyntax: 4 searchFlags: 0 lDAPDisplayName: msExchccMailPassword name: ms-Exch-ccMail-Password schemaIDGUID: 4634194c-4a93-11d3-aa73-00c04f8eedd8 isMemberOfPartialAttributeSet: FALSE objectCategory: CN=Attribute-Schema,${SCHEMADN} # # ms-Exch-ccMail-PO-Name # The name of the cc:Mail post office where the connector exports and # imports mail. # dn: CN=ms-Exch-ccMail-PO-Name,${SCHEMADN} objectClass: top objectClass: attributeSchema cn: ms-Exch-ccMail-PO-Name distinguishedName: CN=ms-Exch-ccMail-PO-Name,${SCHEMADN} attributeID: 1.2.840.113556.1.4.7000.102.1031 attributeSyntax: 2.5.5.12 isSingleValued: TRUE showInAdvancedViewOnly: TRUE adminDisplayName: ms-Exch-ccMail-PO-Name adminDescription: ms-Exch-ccMail-PO-Name oMSyntax: 64 searchFlags: 0 lDAPDisplayName: msExchccMailPOName name: ms-Exch-ccMail-PO-Name schemaIDGUID: 95633f5a-b093-11d2-aa06-00c04f8eedd8 isMemberOfPartialAttributeSet: FALSE objectCategory: CN=Attribute-Schema,${SCHEMADN} # # ms-Exch-ccMail-PO-Path # The file path to the cc:Mail post office. # dn: CN=ms-Exch-ccMail-PO-Path,${SCHEMADN} objectClass: top objectClass: attributeSchema cn: ms-Exch-ccMail-PO-Path distinguishedName: CN=ms-Exch-ccMail-PO-Path,${SCHEMADN} attributeID: 1.2.840.113556.1.4.7000.102.1033 attributeSyntax: 2.5.5.12 isSingleValued: TRUE showInAdvancedViewOnly: TRUE adminDisplayName: ms-Exch-ccMail-PO-Path adminDescription: ms-Exch-ccMail-PO-Path oMSyntax: 64 searchFlags: 0 lDAPDisplayName: msExchccMailPOPath name: ms-Exch-ccMail-PO-Path schemaIDGUID: 98ed3cf2-b093-11d2-aa06-00c04f8eedd8 isMemberOfPartialAttributeSet: FALSE objectCategory: CN=Attribute-Schema,${SCHEMADN} # # ms-Exch-Certificate # Reserved. # dn: CN=ms-Exch-Certificate,${SCHEMADN} objectClass: top objectClass: attributeSchema cn: ms-Exch-Certificate distinguishedName: CN=ms-Exch-Certificate,${SCHEMADN} attributeID: 1.2.840.113556.1.4.7000.102.9012 attributeSyntax: 2.5.5.12 isSingleValued: TRUE showInAdvancedViewOnly: TRUE adminDisplayName: ms-Exch-Certificate adminDescription: ms-Exch-Certificate oMSyntax: 64 searchFlags: 0 lDAPDisplayName: msExchCertificate name: ms-Exch-Certificate schemaIDGUID: 98ce3e60-b093-11d2-aa06-00c04f8eedd8 isMemberOfPartialAttributeSet: FALSE objectCategory: CN=Attribute-Schema,${SCHEMADN} # # ms-Exch-Certificate-Chain-V3 # dn: CN=ms-Exch-Certificate-Chain-V3,${SCHEMADN} objectClass: top objectClass: attributeSchema cn: ms-Exch-Certificate-Chain-V3 distinguishedName: CN=ms-Exch-Certificate-Chain-V3,${SCHEMADN} attributeID: 1.2.840.113556.1.2.562 attributeSyntax: 2.5.5.10 isSingleValued: TRUE mAPIID: 35879 showInAdvancedViewOnly: TRUE adminDisplayName: ms-Exch-Certificate-Chain-V3 adminDescription: ms-Exch-Certificate-Chain-V3 oMSyntax: 4 searchFlags: 0 lDAPDisplayName: certificateChainV3 name: ms-Exch-Certificate-Chain-V3 schemaIDGUID: a8df73aa-c5ea-11d1-bbcb-0080c76670c0 isMemberOfPartialAttributeSet: FALSE objectCategory: CN=Attribute-Schema,${SCHEMADN} # # ms-Exch-Certificate-Revocation-List-V1 # dn: CN=ms-Exch-Certificate-Revocation-List-V1,${SCHEMADN} objectClass: top objectClass: attributeSchema cn: ms-Exch-Certificate-Revocation-List-V1 distinguishedName: CN=ms-Exch-Certificate-Revocation-List-V1,${SCHEMADN} attributeID: 1.2.840.113556.1.2.564 attributeSyntax: 2.5.5.10 isSingleValued: TRUE mAPIID: 35881 showInAdvancedViewOnly: TRUE adminDisplayName: ms-Exch-Certificate-Revocation-List-V1 adminDescription: ms-Exch-Certificate-Revocation-List-V1 oMSyntax: 4 searchFlags: 0 lDAPDisplayName: certificateRevocationListV1 name: ms-Exch-Certificate-Revocation-List-V1 schemaIDGUID: a8df73ab-c5ea-11d1-bbcb-0080c76670c0 isMemberOfPartialAttributeSet: FALSE objectCategory: CN=Attribute-Schema,${SCHEMADN} # # ms-Exch-Certificate-Revocation-List-V3 # dn: CN=ms-Exch-Certificate-Revocation-List-V3,${SCHEMADN} objectClass: top objectClass: attributeSchema cn: ms-Exch-Certificate-Revocation-List-V3 distinguishedName: CN=ms-Exch-Certificate-Revocation-List-V3,${SCHEMADN} attributeID: 1.2.840.113556.1.2.563 attributeSyntax: 2.5.5.10 isSingleValued: TRUE mAPIID: 35880 showInAdvancedViewOnly: TRUE adminDisplayName: ms-Exch-Certificate-Revocation-List-V3 adminDescription: ms-Exch-Certificate-Revocation-List-V3 oMSyntax: 4 searchFlags: 0 lDAPDisplayName: certificateRevocationListV3 name: ms-Exch-Certificate-Revocation-List-V3 schemaIDGUID: a8df73ac-c5ea-11d1-bbcb-0080c76670c0 isMemberOfPartialAttributeSet: FALSE objectCategory: CN=Attribute-Schema,${SCHEMADN} # # ms-Exch-Character-Set # The Multipurpose Internet Mail Extensions (MIME) tag of the # character set used by the client. # dn: CN=ms-Exch-Character-Set,${SCHEMADN} objectClass: top objectClass: attributeSchema cn: ms-Exch-Character-Set distinguishedName: CN=ms-Exch-Character-Set,${SCHEMADN} attributeID: 1.2.840.113556.1.2.480 attributeSyntax: 2.5.5.12 isSingleValued: TRUE rangeLower: 1 rangeUpper: 64 mAPIID: 33157 showInAdvancedViewOnly: TRUE adminDisplayName: ms-Exch-Character-Set adminDescription: ms-Exch-Character-Set oMSyntax: 64 searchFlags: 0 lDAPDisplayName: characterSet name: ms-Exch-Character-Set schemaIDGUID: a8df73ad-c5ea-11d1-bbcb-0080c76670c0 isMemberOfPartialAttributeSet: FALSE objectCategory: CN=Attribute-Schema,${SCHEMADN} # # ms-Exch-Character-Set-List # dn: CN=ms-Exch-Character-Set-List,${SCHEMADN} objectClass: top objectClass: attributeSchema cn: ms-Exch-Character-Set-List distinguishedName: CN=ms-Exch-Character-Set-List,${SCHEMADN} attributeID: 1.2.840.113556.1.2.477 attributeSyntax: 2.5.5.12 isSingleValued: FALSE rangeLower: 1 rangeUpper: 128 mAPIID: 33154 showInAdvancedViewOnly: TRUE adminDisplayName: ms-Exch-Character-Set-List adminDescription: ms-Exch-Character-Set-List oMSyntax: 64 searchFlags: 0 lDAPDisplayName: characterSetList name: ms-Exch-Character-Set-List schemaIDGUID: a8df73ae-c5ea-11d1-bbcb-0080c76670c0 isMemberOfPartialAttributeSet: FALSE objectCategory: CN=Attribute-Schema,${SCHEMADN} # # ms-Exch-Chat-Access # An ACL string representing security on this object. # dn: CN=ms-Exch-Chat-Access,${SCHEMADN} objectClass: top objectClass: attributeSchema cn: ms-Exch-Chat-Access distinguishedName: CN=ms-Exch-Chat-Access,${SCHEMADN} attributeID: 1.2.840.113556.1.4.7000.102.8044 attributeSyntax: 2.5.5.12 isSingleValued: TRUE showInAdvancedViewOnly: TRUE adminDisplayName: ms-Exch-Chat-Access adminDescription: ms-Exch-Chat-Access oMSyntax: 64 searchFlags: 0 lDAPDisplayName: msExchChatAccess name: ms-Exch-Chat-Access schemaIDGUID: 8cac5ed6-b09e-11d2-aa06-00c04f8eedd8 isMemberOfPartialAttributeSet: FALSE objectCategory: CN=Attribute-Schema,${SCHEMADN} # # ms-Exch-Chat-Admin-Message # The message that will be displayed to Chat administrators. # dn: CN=ms-Exch-Chat-Admin-Message,${SCHEMADN} objectClass: top objectClass: attributeSchema cn: ms-Exch-Chat-Admin-Message distinguishedName: CN=ms-Exch-Chat-Admin-Message,${SCHEMADN} attributeID: 1.2.840.113556.1.4.7000.102.8003 attributeSyntax: 2.5.5.12 isSingleValued: TRUE showInAdvancedViewOnly: TRUE adminDisplayName: ms-Exch-Chat-Admin-Message adminDescription: ms-Exch-Chat-Admin-Message oMSyntax: 64 searchFlags: 0 lDAPDisplayName: msExchChatAdminMessage name: ms-Exch-Chat-Admin-Message schemaIDGUID: 98af3fce-b093-11d2-aa06-00c04f8eedd8 isMemberOfPartialAttributeSet: FALSE objectCategory: CN=Attribute-Schema,${SCHEMADN} # # ms-Exch-Chat-Ban-Mask # The mask determines the scope of the ban. # dn: CN=ms-Exch-Chat-Ban-Mask,${SCHEMADN} objectClass: top objectClass: attributeSchema cn: ms-Exch-Chat-Ban-Mask distinguishedName: CN=ms-Exch-Chat-Ban-Mask,${SCHEMADN} attributeID: 1.2.840.113556.1.4.7000.102.8040 attributeSyntax: 2.5.5.12 isSingleValued: TRUE showInAdvancedViewOnly: TRUE adminDisplayName: ms-Exch-Chat-Ban-Mask adminDescription: ms-Exch-Chat-Ban-Mask oMSyntax: 64 searchFlags: 0 lDAPDisplayName: msExchChatBanMask name: ms-Exch-Chat-Ban-Mask schemaIDGUID: 9890413c-b093-11d2-aa06-00c04f8eedd8 isMemberOfPartialAttributeSet: FALSE objectCategory: CN=Attribute-Schema,${SCHEMADN} # # ms-Exch-Chat-Ban-Reason # The reason for the ban is sent to the banned user when a connection # is attempted. # dn: CN=ms-Exch-Chat-Ban-Reason,${SCHEMADN} objectClass: top objectClass: attributeSchema cn: ms-Exch-Chat-Ban-Reason distinguishedName: CN=ms-Exch-Chat-Ban-Reason,${SCHEMADN} attributeID: 1.2.840.113556.1.4.7000.102.8043 attributeSyntax: 2.5.5.12 isSingleValued: TRUE showInAdvancedViewOnly: TRUE adminDisplayName: ms-Exch-Chat-Ban-Reason adminDescription: ms-Exch-Chat-Ban-Reason oMSyntax: 64 searchFlags: 0 lDAPDisplayName: msExchChatBanReason name: ms-Exch-Chat-Ban-Reason schemaIDGUID: 959c77ca-b093-11d2-aa06-00c04f8eedd8 isMemberOfPartialAttributeSet: FALSE objectCategory: CN=Attribute-Schema,${SCHEMADN} # # ms-Exch-Chat-Broadcast-Address # dn: CN=ms-Exch-Chat-Broadcast-Address,${SCHEMADN} objectClass: top objectClass: attributeSchema cn: ms-Exch-Chat-Broadcast-Address distinguishedName: CN=ms-Exch-Chat-Broadcast-Address,${SCHEMADN} attributeID: 1.2.840.113556.1.4.7000.102.8009 attributeSyntax: 2.5.5.12 isSingleValued: TRUE showInAdvancedViewOnly: TRUE adminDisplayName: ms-Exch-Chat-Broadcast-Address adminDescription: ms-Exch-Chat-Broadcast-Address oMSyntax: 64 searchFlags: 0 lDAPDisplayName: msExchChatBroadcastAddress name: ms-Exch-Chat-Broadcast-Address schemaIDGUID: 95b91402-b093-11d2-aa06-00c04f8eedd8 isMemberOfPartialAttributeSet: FALSE objectCategory: CN=Attribute-Schema,${SCHEMADN} # # ms-Exch-Chat-Channel-Auto-Create # Determines if the registered channel will be started automatically # when the service loads. # dn: CN=ms-Exch-Chat-Channel-Auto-Create,${SCHEMADN} objectClass: top objectClass: attributeSchema cn: ms-Exch-Chat-Channel-Auto-Create distinguishedName: CN=ms-Exch-Chat-Channel-Auto-Create,${SCHEMADN} attributeID: 1.2.840.113556.1.4.7000.102.8020 attributeSyntax: 2.5.5.8 isSingleValued: TRUE showInAdvancedViewOnly: TRUE adminDisplayName: ms-Exch-Chat-Channel-Auto-Create adminDescription: ms-Exch-Chat-Channel-Auto-Create oMSyntax: 1 searchFlags: 0 lDAPDisplayName: msExchChatChannelAutoCreate name: ms-Exch-Chat-Channel-Auto-Create schemaIDGUID: 95d81294-b093-11d2-aa06-00c04f8eedd8 isMemberOfPartialAttributeSet: FALSE objectCategory: CN=Attribute-Schema,${SCHEMADN} # # ms-Exch-Chat-Channel-Flags # Flags that determine the IRC/IRCX modes of the channel. # dn: CN=ms-Exch-Chat-Channel-Flags,${SCHEMADN} objectClass: top objectClass: attributeSchema cn: ms-Exch-Chat-Channel-Flags distinguishedName: CN=ms-Exch-Chat-Channel-Flags,${SCHEMADN} attributeID: 1.2.840.113556.1.4.7000.102.8026 attributeSyntax: 2.5.5.9 isSingleValued: TRUE showInAdvancedViewOnly: TRUE adminDisplayName: ms-Exch-Chat-Channel-Flags adminDescription: ms-Exch-Chat-Channel-Flags oMSyntax: 2 searchFlags: 0 lDAPDisplayName: msExchChatChannelFlags name: ms-Exch-Chat-Channel-Flags schemaIDGUID: 95f4aecc-b093-11d2-aa06-00c04f8eedd8 isMemberOfPartialAttributeSet: FALSE objectCategory: CN=Attribute-Schema,${SCHEMADN} # # ms-Exch-Chat-Channel-Host-Key # The keyword used by a host to access a restricted channel. # dn: CN=ms-Exch-Chat-Channel-Host-Key,${SCHEMADN} objectClass: top objectClass: attributeSchema cn: ms-Exch-Chat-Channel-Host-Key distinguishedName: CN=ms-Exch-Chat-Channel-Host-Key,${SCHEMADN} attributeID: 1.2.840.113556.1.4.7000.102.8023 attributeSyntax: 2.5.5.12 isSingleValued: TRUE showInAdvancedViewOnly: TRUE adminDisplayName: ms-Exch-Chat-Channel-Host-Key adminDescription: ms-Exch-Chat-Channel-Host-Key oMSyntax: 64 searchFlags: 0 lDAPDisplayName: msExchChatChannelHostKey name: ms-Exch-Chat-Channel-Host-Key schemaIDGUID: 96114b04-b093-11d2-aa06-00c04f8eedd8 isMemberOfPartialAttributeSet: FALSE objectCategory: CN=Attribute-Schema,${SCHEMADN} # # ms-Exch-Chat-Channel-Join-Message # The message sent to users when they join the channel. # dn: CN=ms-Exch-Chat-Channel-Join-Message,${SCHEMADN} objectClass: top objectClass: attributeSchema cn: ms-Exch-Chat-Channel-Join-Message distinguishedName: CN=ms-Exch-Chat-Channel-Join-Message,${SCHEMADN} attributeID: 1.2.840.113556.1.4.7000.102.8030 attributeSyntax: 2.5.5.12 isSingleValued: TRUE showInAdvancedViewOnly: TRUE adminDisplayName: ms-Exch-Chat-Channel-Join-Message adminDescription: ms-Exch-Chat-Channel-Join-Message oMSyntax: 64 searchFlags: 0 lDAPDisplayName: msExchChatChannelJoinMessage name: ms-Exch-Chat-Channel-Join-Message schemaIDGUID: 962de73c-b093-11d2-aa06-00c04f8eedd8 isMemberOfPartialAttributeSet: FALSE objectCategory: CN=Attribute-Schema,${SCHEMADN} # # ms-Exch-Chat-Channel-Key # The keyword used by a user to access a restricted channel. # dn: CN=ms-Exch-Chat-Channel-Key,${SCHEMADN} objectClass: top objectClass: attributeSchema cn: ms-Exch-Chat-Channel-Key distinguishedName: CN=ms-Exch-Chat-Channel-Key,${SCHEMADN} attributeID: 1.2.840.113556.1.4.7000.102.8021 attributeSyntax: 2.5.5.12 isSingleValued: TRUE showInAdvancedViewOnly: TRUE adminDisplayName: ms-Exch-Chat-Channel-Key adminDescription: ms-Exch-Chat-Channel-Key oMSyntax: 64 searchFlags: 0 lDAPDisplayName: msExchChatChannelKey name: ms-Exch-Chat-Channel-Key schemaIDGUID: 964a8374-b093-11d2-aa06-00c04f8eedd8 isMemberOfPartialAttributeSet: FALSE objectCategory: CN=Attribute-Schema,${SCHEMADN} # # ms-Exch-Chat-Channel-Language # The language used in a channel. # dn: CN=ms-Exch-Chat-Channel-Language,${SCHEMADN} objectClass: top objectClass: attributeSchema cn: ms-Exch-Chat-Channel-Language distinguishedName: CN=ms-Exch-Chat-Channel-Language,${SCHEMADN} attributeID: 1.2.840.113556.1.4.7000.102.8028 attributeSyntax: 2.5.5.12 isSingleValued: TRUE showInAdvancedViewOnly: TRUE adminDisplayName: ms-Exch-Chat-Channel-Language adminDescription: ms-Exch-Chat-Channel-Language oMSyntax: 64 searchFlags: 0 lDAPDisplayName: msExchChatChannelLanguage name: ms-Exch-Chat-Channel-Language schemaIDGUID: 96671fac-b093-11d2-aa06-00c04f8eedd8 isMemberOfPartialAttributeSet: FALSE objectCategory: CN=Attribute-Schema,${SCHEMADN} # # ms-Exch-Chat-Channel-LCID # dn: CN=ms-Exch-Chat-Channel-LCID,${SCHEMADN} objectClass: top objectClass: attributeSchema cn: ms-Exch-Chat-Channel-LCID distinguishedName: CN=ms-Exch-Chat-Channel-LCID,${SCHEMADN} attributeID: 1.2.840.113556.1.4.7000.102.8029 attributeSyntax: 2.5.5.9 isSingleValued: TRUE showInAdvancedViewOnly: TRUE adminDisplayName: ms-Exch-Chat-Channel-LCID adminDescription: ms-Exch-Chat-Channel-LCID oMSyntax: 2 searchFlags: 0 lDAPDisplayName: msExchChatChannelLCID name: ms-Exch-Chat-Channel-LCID schemaIDGUID: 9683bbe4-b093-11d2-aa06-00c04f8eedd8 isMemberOfPartialAttributeSet: FALSE objectCategory: CN=Attribute-Schema,${SCHEMADN} # # ms-Exch-Chat-Channel-Limit # The number of users allowed to join this channel. # dn: CN=ms-Exch-Chat-Channel-Limit,${SCHEMADN} objectClass: top objectClass: attributeSchema cn: ms-Exch-Chat-Channel-Limit distinguishedName: CN=ms-Exch-Chat-Channel-Limit,${SCHEMADN} attributeID: 1.2.840.113556.1.4.7000.102.8010 attributeSyntax: 2.5.5.9 isSingleValued: TRUE showInAdvancedViewOnly: TRUE adminDisplayName: ms-Exch-Chat-Channel-Limit adminDescription: ms-Exch-Chat-Channel-Limit oMSyntax: 2 searchFlags: 0 lDAPDisplayName: msExchChatChannelLimit name: ms-Exch-Chat-Channel-Limit schemaIDGUID: 96a0581c-b093-11d2-aa06-00c04f8eedd8 isMemberOfPartialAttributeSet: FALSE objectCategory: CN=Attribute-Schema,${SCHEMADN} # # ms-Exch-Chat-Channel-Mode # The modes of a channel. # dn: CN=ms-Exch-Chat-Channel-Mode,${SCHEMADN} objectClass: top objectClass: attributeSchema cn: ms-Exch-Chat-Channel-Mode distinguishedName: CN=ms-Exch-Chat-Channel-Mode,${SCHEMADN} attributeID: 1.2.840.113556.1.4.7000.102.8006 attributeSyntax: 2.5.5.9 isSingleValued: TRUE showInAdvancedViewOnly: TRUE adminDisplayName: ms-Exch-Chat-Channel-Mode adminDescription: ms-Exch-Chat-Channel-Mode oMSyntax: 2 searchFlags: 0 lDAPDisplayName: msExchChatChannelMode name: ms-Exch-Chat-Channel-Mode schemaIDGUID: 96ba91fa-b093-11d2-aa06-00c04f8eedd8 isMemberOfPartialAttributeSet: FALSE objectCategory: CN=Attribute-Schema,${SCHEMADN} # # ms-Exch-Chat-Channel-Name # The IRC/IRCX style name of the channel. # dn: CN=ms-Exch-Chat-Channel-Name,${SCHEMADN} objectClass: top objectClass: attributeSchema cn: ms-Exch-Chat-Channel-Name distinguishedName: CN=ms-Exch-Chat-Channel-Name,${SCHEMADN} attributeID: 1.2.840.113556.1.4.7000.102.8019 attributeSyntax: 2.5.5.12 isSingleValued: TRUE showInAdvancedViewOnly: TRUE adminDisplayName: ms-Exch-Chat-Channel-Name adminDescription: ms-Exch-Chat-Channel-Name oMSyntax: 64 searchFlags: 0 lDAPDisplayName: msExchChatChannelName name: ms-Exch-Chat-Channel-Name schemaIDGUID: 96d72e32-b093-11d2-aa06-00c04f8eedd8 isMemberOfPartialAttributeSet: FALSE objectCategory: CN=Attribute-Schema,${SCHEMADN} # # ms-Exch-Chat-Channel-Owner-Key # The keyword used by an owner to access a restricted channel. # dn: CN=ms-Exch-Chat-Channel-Owner-Key,${SCHEMADN} objectClass: top objectClass: attributeSchema cn: ms-Exch-Chat-Channel-Owner-Key distinguishedName: CN=ms-Exch-Chat-Channel-Owner-Key,${SCHEMADN} attributeID: 1.2.840.113556.1.4.7000.102.8022 attributeSyntax: 2.5.5.12 isSingleValued: TRUE showInAdvancedViewOnly: TRUE adminDisplayName: ms-Exch-Chat-Channel-Owner-Key adminDescription: ms-Exch-Chat-Channel-Owner-Key oMSyntax: 64 searchFlags: 0 lDAPDisplayName: msExchChatChannelOwnerKey name: ms-Exch-Chat-Channel-Owner-Key schemaIDGUID: 96f3ca6a-b093-11d2-aa06-00c04f8eedd8 isMemberOfPartialAttributeSet: FALSE objectCategory: CN=Attribute-Schema,${SCHEMADN} # # ms-Exch-Chat-Channel-Part-Message # The message sent to a user when they leave the channel. # dn: CN=ms-Exch-Chat-Channel-Part-Message,${SCHEMADN} objectClass: top objectClass: attributeSchema cn: ms-Exch-Chat-Channel-Part-Message distinguishedName: CN=ms-Exch-Chat-Channel-Part-Message,${SCHEMADN} attributeID: 1.2.840.113556.1.4.7000.102.8031 attributeSyntax: 2.5.5.12 isSingleValued: TRUE showInAdvancedViewOnly: TRUE adminDisplayName: ms-Exch-Chat-Channel-Part-Message adminDescription: ms-Exch-Chat-Channel-Part-Message oMSyntax: 64 searchFlags: 0 lDAPDisplayName: msExchChatChannelPartMessage name: ms-Exch-Chat-Channel-Part-Message schemaIDGUID: 9712c8fc-b093-11d2-aa06-00c04f8eedd8 isMemberOfPartialAttributeSet: FALSE objectCategory: CN=Attribute-Schema,${SCHEMADN} # # ms-Exch-Chat-Channel-PICS # The Platform for Internet Content Selection (PICS) rating for the channel. # dn: CN=ms-Exch-Chat-Channel-PICS,${SCHEMADN} objectClass: top objectClass: attributeSchema cn: ms-Exch-Chat-Channel-PICS distinguishedName: CN=ms-Exch-Chat-Channel-PICS,${SCHEMADN} attributeID: 1.2.840.113556.1.4.7000.102.8027 attributeSyntax: 2.5.5.12 isSingleValued: TRUE showInAdvancedViewOnly: TRUE adminDisplayName: ms-Exch-Chat-Channel-PICS adminDescription: ms-Exch-Chat-Channel-PICS oMSyntax: 64 searchFlags: 0 lDAPDisplayName: msExchChatChannelPICS name: ms-Exch-Chat-Channel-PICS schemaIDGUID: 972d02da-b093-11d2-aa06-00c04f8eedd8 isMemberOfPartialAttributeSet: FALSE objectCategory: CN=Attribute-Schema,${SCHEMADN} # # ms-Exch-Chat-Channel-Subject # The subject of the channel. # dn: CN=ms-Exch-Chat-Channel-Subject,${SCHEMADN} objectClass: top objectClass: attributeSchema cn: ms-Exch-Chat-Channel-Subject distinguishedName: CN=ms-Exch-Chat-Channel-Subject,${SCHEMADN} attributeID: 1.2.840.113556.1.4.7000.102.8025 attributeSyntax: 2.5.5.12 isSingleValued: TRUE showInAdvancedViewOnly: TRUE adminDisplayName: ms-Exch-Chat-Channel-Subject adminDescription: ms-Exch-Chat-Channel-Subject oMSyntax: 64 searchFlags: 0 lDAPDisplayName: msExchChatChannelSubject name: ms-Exch-Chat-Channel-Subject schemaIDGUID: 97499f12-b093-11d2-aa06-00c04f8eedd8 isMemberOfPartialAttributeSet: FALSE objectCategory: CN=Attribute-Schema,${SCHEMADN} # # ms-Exch-Chat-Channel-Topic # The topic of the channel. # dn: CN=ms-Exch-Chat-Channel-Topic,${SCHEMADN} objectClass: top objectClass: attributeSchema cn: ms-Exch-Chat-Channel-Topic distinguishedName: CN=ms-Exch-Chat-Channel-Topic,${SCHEMADN} attributeID: 1.2.840.113556.1.4.7000.102.8024 attributeSyntax: 2.5.5.12 isSingleValued: TRUE showInAdvancedViewOnly: TRUE adminDisplayName: ms-Exch-Chat-Channel-Topic adminDescription: ms-Exch-Chat-Channel-Topic oMSyntax: 64 searchFlags: 0 lDAPDisplayName: msExchChatChannelTopic name: ms-Exch-Chat-Channel-Topic schemaIDGUID: 97663b4a-b093-11d2-aa06-00c04f8eedd8 isMemberOfPartialAttributeSet: FALSE objectCategory: CN=Attribute-Schema,${SCHEMADN} # # ms-Exch-Chat-Class-Ident-Mask # Determines the scope of the Chat # class. ms-Exch-Chat-Class-Scope-Type Attribute determines if this # property is used, or if the Internet Protocol (IP) # ms-Exch-Chat-Class-IP Attribute property is used to scope the class. # dn: CN=ms-Exch-Chat-Class-Ident-Mask,${SCHEMADN} objectClass: top objectClass: attributeSchema cn: ms-Exch-Chat-Class-Ident-Mask distinguishedName: CN=ms-Exch-Chat-Class-Ident-Mask,${SCHEMADN} attributeID: 1.2.840.113556.1.4.7000.102.8032 attributeSyntax: 2.5.5.12 isSingleValued: TRUE showInAdvancedViewOnly: TRUE adminDisplayName: ms-Exch-Chat-Class-Ident-Mask adminDescription: ms-Exch-Chat-Class-Ident-Mask oMSyntax: 64 searchFlags: 0 lDAPDisplayName: msExchChatClassIdentMask name: ms-Exch-Chat-Class-Ident-Mask schemaIDGUID: 9782d782-b093-11d2-aa06-00c04f8eedd8 isMemberOfPartialAttributeSet: FALSE objectCategory: CN=Attribute-Schema,${SCHEMADN} # # ms-Exch-Chat-Class-IP # Determines the scope of the Chat class specified by an IP # address. ms-Exch-Chat-Class-Scope-Type Attribute determines if this # property is used, or if the IP ms-Exch-Chat-Class-Ident-Mask # Attribute property is used to scope the class. # dn: CN=ms-Exch-Chat-Class-IP,${SCHEMADN} objectClass: top objectClass: attributeSchema cn: ms-Exch-Chat-Class-IP distinguishedName: CN=ms-Exch-Chat-Class-IP,${SCHEMADN} attributeID: 1.2.840.113556.1.4.7000.102.8033 attributeSyntax: 2.5.5.12 isSingleValued: TRUE showInAdvancedViewOnly: TRUE adminDisplayName: ms-Exch-Chat-Class-IP adminDescription: ms-Exch-Chat-Class-IP oMSyntax: 64 searchFlags: 0 lDAPDisplayName: msExchChatClassIP name: ms-Exch-Chat-Class-IP schemaIDGUID: 97a1d614-b093-11d2-aa06-00c04f8eedd8 isMemberOfPartialAttributeSet: FALSE objectCategory: CN=Attribute-Schema,${SCHEMADN} # # ms-Exch-Chat-Class-Restrictions # The Chat user class restrictions. # dn: CN=ms-Exch-Chat-Class-Restrictions,${SCHEMADN} objectClass: top objectClass: attributeSchema cn: ms-Exch-Chat-Class-Restrictions distinguishedName: CN=ms-Exch-Chat-Class-Restrictions,${SCHEMADN} attributeID: 1.2.840.113556.1.4.7000.102.8046 attributeSyntax: 2.5.5.9 isSingleValued: TRUE showInAdvancedViewOnly: TRUE adminDisplayName: ms-Exch-Chat-Class-Restrictions adminDescription: ms-Exch-Chat-Class-Restrictions oMSyntax: 2 searchFlags: 0 lDAPDisplayName: msExchChatClassRestrictions name: ms-Exch-Chat-Class-Restrictions schemaIDGUID: 8090a000-1234-11d3-aa58-00c04f8eedd8 isMemberOfPartialAttributeSet: FALSE objectCategory: CN=Attribute-Schema,${SCHEMADN} # # ms-Exch-Chat-Class-Scope-Type # The Chat user class identification scope type. # dn: CN=ms-Exch-Chat-Class-Scope-Type,${SCHEMADN} objectClass: top objectClass: attributeSchema cn: ms-Exch-Chat-Class-Scope-Type distinguishedName: CN=ms-Exch-Chat-Class-Scope-Type,${SCHEMADN} attributeID: 1.2.840.113556.1.4.7000.102.8047 attributeSyntax: 2.5.5.8 isSingleValued: TRUE showInAdvancedViewOnly: TRUE adminDisplayName: ms-Exch-Chat-Class-Scope-Type adminDescription: ms-Exch-Chat-Class-Scope-Type oMSyntax: 1 searchFlags: 0 lDAPDisplayName: msExchChatClassScopeType name: ms-Exch-Chat-Class-Scope-Type schemaIDGUID: 8090a006-1234-11d3-aa58-00c04f8eedd8 isMemberOfPartialAttributeSet: FALSE objectCategory: CN=Attribute-Schema,${SCHEMADN} # # ms-Exch-Chat-Client-Port # dn: CN=ms-Exch-Chat-Client-Port,${SCHEMADN} objectClass: top objectClass: attributeSchema cn: ms-Exch-Chat-Client-Port distinguishedName: CN=ms-Exch-Chat-Client-Port,${SCHEMADN} attributeID: 1.2.840.113556.1.4.7000.102.8007 attributeSyntax: 2.5.5.9 isSingleValued: TRUE showInAdvancedViewOnly: TRUE adminDisplayName: ms-Exch-Chat-Client-Port adminDescription: ms-Exch-Chat-Client-Port oMSyntax: 2 searchFlags: 0 lDAPDisplayName: msExchChatClientPort name: ms-Exch-Chat-Client-Port schemaIDGUID: 97be724c-b093-11d2-aa06-00c04f8eedd8 isMemberOfPartialAttributeSet: FALSE objectCategory: CN=Attribute-Schema,${SCHEMADN} # # ms-Exch-Chat-DNS-Reverse-Mode # Determines whether Domain Name System (DNS) reverse lookups are # performed on incoming client connections. # dn: CN=ms-Exch-Chat-DNS-Reverse-Mode,${SCHEMADN} objectClass: top objectClass: attributeSchema cn: ms-Exch-Chat-DNS-Reverse-Mode distinguishedName: CN=ms-Exch-Chat-DNS-Reverse-Mode,${SCHEMADN} attributeID: 1.2.840.113556.1.4.7000.102.8013 attributeSyntax: 2.5.5.9 isSingleValued: TRUE showInAdvancedViewOnly: TRUE adminDisplayName: ms-Exch-Chat-DNS-Reverse-Mode adminDescription: ms-Exch-Chat-DNS-Reverse-Mode oMSyntax: 2 searchFlags: 0 lDAPDisplayName: msExchChatDNSReverseMode name: ms-Exch-Chat-DNS-Reverse-Mode schemaIDGUID: 97db0e84-b093-11d2-aa06-00c04f8eedd8 isMemberOfPartialAttributeSet: FALSE objectCategory: CN=Attribute-Schema,${SCHEMADN} # # ms-Exch-Chat-Duration # The amount of time this item is active starting from the value of # ms-Exch-Chat-Start-Time Attribute. # dn: CN=ms-Exch-Chat-Duration,${SCHEMADN} objectClass: top objectClass: attributeSchema cn: ms-Exch-Chat-Duration distinguishedName: CN=ms-Exch-Chat-Duration,${SCHEMADN} attributeID: 1.2.840.113556.1.4.7000.102.8042 attributeSyntax: 2.5.5.16 isSingleValued: TRUE showInAdvancedViewOnly: TRUE adminDisplayName: ms-Exch-Chat-Duration adminDescription: ms-Exch-Chat-Duration oMSyntax: 65 searchFlags: 0 lDAPDisplayName: msExchChatDuration name: ms-Exch-Chat-Duration schemaIDGUID: 97fa0d16-b093-11d2-aa06-00c04f8eedd8 isMemberOfPartialAttributeSet: FALSE objectCategory: CN=Attribute-Schema,${SCHEMADN} # # ms-Exch-Chat-Enable-Anonymous # Determines whether anonymous client connections are allowed to this # Chat co to this Chat community. # dn: CN=ms-Exch-Chat-Enable-Anonymous,${SCHEMADN} objectClass: top objectClass: attributeSchema cn: ms-Exch-Chat-Enable-Anonymous distinguishedName: CN=ms-Exch-Chat-Enable-Anonymous,${SCHEMADN} attributeID: 1.2.840.113556.1.4.7000.102.8011 attributeSyntax: 2.5.5.8 isSingleValued: TRUE showInAdvancedViewOnly: TRUE adminDisplayName: ms-Exch-Chat-Enable-Anonymous adminDescription: ms-Exch-Chat-Enable-Anonymous oMSyntax: 1 searchFlags: 0 lDAPDisplayName: msExchChatEnableAnonymous name: ms-Exch-Chat-Enable-Anonymous schemaIDGUID: 98190ba8-b093-11d2-aa06-00c04f8eedd8 isMemberOfPartialAttributeSet: FALSE objectCategory: CN=Attribute-Schema,${SCHEMADN} # # ms-Exch-Chat-Extensions # A multivalued list of the Chat service extensions for this Chat # community on this server. # dn: CN=ms-Exch-Chat-Extensions,${SCHEMADN} objectClass: top objectClass: attributeSchema cn: ms-Exch-Chat-Extensions distinguishedName: CN=ms-Exch-Chat-Extensions,${SCHEMADN} attributeID: 1.2.840.113556.1.4.7000.102.8048 attributeSyntax: 2.5.5.12 isSingleValued: FALSE showInAdvancedViewOnly: TRUE adminDisplayName: ms-Exch-Chat-Extensions adminDescription: ms-Exch-Chat-Extensions oMSyntax: 64 searchFlags: 0 lDAPDisplayName: msExchChatExtensions name: ms-Exch-Chat-Extensions schemaIDGUID: 3b9d8de5-2d93-11d3-aa6b-00c04f8eedd8 isMemberOfPartialAttributeSet: FALSE objectCategory: CN=Attribute-Schema,${SCHEMADN} # # ms-Exch-Chat-Input-Flood-Limit # Determines the maximum acceptable message rate allowed by the Chat # server from clients. # dn: CN=ms-Exch-Chat-Input-Flood-Limit,${SCHEMADN} objectClass: top objectClass: attributeSchema cn: ms-Exch-Chat-Input-Flood-Limit distinguishedName: CN=ms-Exch-Chat-Input-Flood-Limit,${SCHEMADN} attributeID: 1.2.840.113556.1.4.7000.102.8038 attributeSyntax: 2.5.5.9 isSingleValued: TRUE showInAdvancedViewOnly: TRUE adminDisplayName: ms-Exch-Chat-Input-Flood-Limit adminDescription: ms-Exch-Chat-Input-Flood-Limit oMSyntax: 2 searchFlags: 0 lDAPDisplayName: msExchChatInputFloodLimit name: ms-Exch-Chat-Input-Flood-Limit schemaIDGUID: 987142aa-b093-11d2-aa06-00c04f8eedd8 isMemberOfPartialAttributeSet: FALSE objectCategory: CN=Attribute-Schema,${SCHEMADN} # # ms-Exch-Chat-Max-Anonymous # The maximum anonymous client connections that are allowed. # dn: CN=ms-Exch-Chat-Max-Anonymous,${SCHEMADN} objectClass: top objectClass: attributeSchema cn: ms-Exch-Chat-Max-Anonymous distinguishedName: CN=ms-Exch-Chat-Max-Anonymous,${SCHEMADN} attributeID: 1.2.840.113556.1.4.7000.102.8015 attributeSyntax: 2.5.5.9 isSingleValued: TRUE showInAdvancedViewOnly: TRUE adminDisplayName: ms-Exch-Chat-Max-Anonymous adminDescription: ms-Exch-Chat-Max-Anonymous oMSyntax: 2 searchFlags: 0 lDAPDisplayName: msExchChatMaxAnonymous name: ms-Exch-Chat-Max-Anonymous schemaIDGUID: 9969373a-b093-11d2-aa06-00c04f8eedd8 isMemberOfPartialAttributeSet: FALSE objectCategory: CN=Attribute-Schema,${SCHEMADN} # # ms-Exch-Chat-Max-Connections # The maximum number of client connections allowed. # dn: CN=ms-Exch-Chat-Max-Connections,${SCHEMADN} objectClass: top objectClass: attributeSchema cn: ms-Exch-Chat-Max-Connections distinguishedName: CN=ms-Exch-Chat-Max-Connections,${SCHEMADN} attributeID: 1.2.840.113556.1.4.7000.102.8014 attributeSyntax: 2.5.5.9 isSingleValued: TRUE showInAdvancedViewOnly: TRUE adminDisplayName: ms-Exch-Chat-Max-Connections adminDescription: ms-Exch-Chat-Max-Connections oMSyntax: 2 searchFlags: 0 lDAPDisplayName: msExchChatMaxConnections name: ms-Exch-Chat-Max-Connections schemaIDGUID: 9985d372-b093-11d2-aa06-00c04f8eedd8 isMemberOfPartialAttributeSet: FALSE objectCategory: CN=Attribute-Schema,${SCHEMADN} # # ms-Exch-Chat-Max-Connections-Per-IP # dn: CN=ms-Exch-Chat-Max-Connections-Per-IP,${SCHEMADN} objectClass: top objectClass: attributeSchema cn: ms-Exch-Chat-Max-Connections-Per-IP distinguishedName: CN=ms-Exch-Chat-Max-Connections-Per-IP,${SCHEMADN} attributeID: 1.2.840.113556.1.4.7000.102.8049 attributeSyntax: 2.5.5.9 isSingleValued: TRUE showInAdvancedViewOnly: TRUE adminDisplayName: ms-Exch-Chat-Max-Connections-Per-IP adminDescription: ms-Exch-Chat-Max-Connections-Per-IP oMSyntax: 2 searchFlags: 0 lDAPDisplayName: msExchChatMaxConnectionsPerIP name: ms-Exch-Chat-Max-Connections-Per-IP schemaIDGUID: 2ac57e6b-f737-4e41-8386-7295ddbe05e6 isMemberOfPartialAttributeSet: FALSE objectCategory: CN=Attribute-Schema,${SCHEMADN} # # ms-Exch-Chat-Max-Memberships # The maximum number of channels that a Chat client may join at one # time. # dn: CN=ms-Exch-Chat-Max-Memberships,${SCHEMADN} objectClass: top objectClass: attributeSchema cn: ms-Exch-Chat-Max-Memberships distinguishedName: CN=ms-Exch-Chat-Max-Memberships,${SCHEMADN} attributeID: 1.2.840.113556.1.4.7000.102.8016 attributeSyntax: 2.5.5.9 isSingleValued: TRUE showInAdvancedViewOnly: TRUE adminDisplayName: ms-Exch-Chat-Max-Memberships adminDescription: ms-Exch-Chat-Max-Memberships oMSyntax: 2 searchFlags: 0 lDAPDisplayName: msExchChatMaxMemberships name: ms-Exch-Chat-Max-Memberships schemaIDGUID: 99a4d204-b093-11d2-aa06-00c04f8eedd8 isMemberOfPartialAttributeSet: FALSE objectCategory: CN=Attribute-Schema,${SCHEMADN} # # ms-Exch-Chat-Max-Octets-To-Mask # dn: CN=ms-Exch-Chat-Max-Octets-To-Mask,${SCHEMADN} objectClass: top objectClass: attributeSchema cn: ms-Exch-Chat-Max-Octets-To-Mask distinguishedName: CN=ms-Exch-Chat-Max-Octets-To-Mask,${SCHEMADN} attributeID: 1.2.840.113556.1.4.7000.102.8050 attributeSyntax: 2.5.5.9 isSingleValued: TRUE showInAdvancedViewOnly: TRUE adminDisplayName: ms-Exch-Chat-Max-Octets-To-Mask adminDescription: ms-Exch-Chat-Max-Octets-To-Mask oMSyntax: 2 searchFlags: 0 lDAPDisplayName: msExchChatMaxOctetsToMask name: ms-Exch-Chat-Max-Octets-To-Mask schemaIDGUID: 3de37b23-2789-4df7-b51f-f920ce544458 isMemberOfPartialAttributeSet: FALSE objectCategory: CN=Attribute-Schema,${SCHEMADN} # # ms-Exch-Chat-Message-Lag # The amount of lag imparted to all messages to prevent flooding. # dn: CN=ms-Exch-Chat-Message-Lag,${SCHEMADN} objectClass: top objectClass: attributeSchema cn: ms-Exch-Chat-Message-Lag distinguishedName: CN=ms-Exch-Chat-Message-Lag,${SCHEMADN} attributeID: 1.2.840.113556.1.4.7000.102.8034 attributeSyntax: 2.5.5.9 isSingleValued: TRUE showInAdvancedViewOnly: TRUE adminDisplayName: ms-Exch-Chat-Message-Lag adminDescription: ms-Exch-Chat-Message-Lag oMSyntax: 2 searchFlags: 0 lDAPDisplayName: msExchChatMessageLag name: ms-Exch-Chat-Message-Lag schemaIDGUID: 99e2cf28-b093-11d2-aa06-00c04f8eedd8 isMemberOfPartialAttributeSet: FALSE objectCategory: CN=Attribute-Schema,${SCHEMADN} # # ms-Exch-Chat-MOTD # The message sent to users when they connect to a Chat community. # dn: CN=ms-Exch-Chat-MOTD,${SCHEMADN} objectClass: top objectClass: attributeSchema cn: ms-Exch-Chat-MOTD distinguishedName: CN=ms-Exch-Chat-MOTD,${SCHEMADN} attributeID: 1.2.840.113556.1.4.7000.102.8004 attributeSyntax: 2.5.5.12 isSingleValued: TRUE showInAdvancedViewOnly: TRUE adminDisplayName: ms-Exch-Chat-MOTD adminDescription: ms-Exch-Chat-MOTD oMSyntax: 64 searchFlags: 0 lDAPDisplayName: msExchChatMOTD name: ms-Exch-Chat-MOTD schemaIDGUID: 99ff6b60-b093-11d2-aa06-00c04f8eedd8 isMemberOfPartialAttributeSet: FALSE objectCategory: CN=Attribute-Schema,${SCHEMADN} # # ms-Exch-Chat-Network-Mode # The Chat network settings for channel creation and defaults. # dn: CN=ms-Exch-Chat-Network-Mode,${SCHEMADN} objectClass: top objectClass: attributeSchema cn: ms-Exch-Chat-Network-Mode distinguishedName: CN=ms-Exch-Chat-Network-Mode,${SCHEMADN} attributeID: 1.2.840.113556.1.4.7000.102.8045 attributeSyntax: 2.5.5.9 isSingleValued: TRUE showInAdvancedViewOnly: TRUE adminDisplayName: ms-Exch-Chat-Network-Mode adminDescription: ms-Exch-Chat-Network-Mode oMSyntax: 2 searchFlags: 0 lDAPDisplayName: msExchChatNetworkMode name: ms-Exch-Chat-Network-Mode schemaIDGUID: 917cfe98-b09e-11d2-aa06-00c04f8eedd8 isMemberOfPartialAttributeSet: FALSE objectCategory: CN=Attribute-Schema,${SCHEMADN} # # ms-Exch-Chat-Network-Name # dn: CN=ms-Exch-Chat-Network-Name,${SCHEMADN} objectClass: top objectClass: attributeSchema cn: ms-Exch-Chat-Network-Name distinguishedName: CN=ms-Exch-Chat-Network-Name,${SCHEMADN} attributeID: 1.2.840.113556.1.4.7000.102.8001 attributeSyntax: 2.5.5.12 isSingleValued: TRUE showInAdvancedViewOnly: TRUE adminDisplayName: ms-Exch-Chat-Network-Name adminDescription: ms-Exch-Chat-Network-Name oMSyntax: 64 searchFlags: 0 lDAPDisplayName: msExchChatNetworkName name: ms-Exch-Chat-Network-Name schemaIDGUID: 9a1e69f2-b093-11d2-aa06-00c04f8eedd8 isMemberOfPartialAttributeSet: FALSE objectCategory: CN=Attribute-Schema,${SCHEMADN} # # ms-Exch-Chat-Nick-Delay # The amount of delay imparted on a user between changing # nicknames. Used for flood control. # dn: CN=ms-Exch-Chat-Nick-Delay,${SCHEMADN} objectClass: top objectClass: attributeSchema cn: ms-Exch-Chat-Nick-Delay distinguishedName: CN=ms-Exch-Chat-Nick-Delay,${SCHEMADN} attributeID: 1.2.840.113556.1.4.7000.102.8036 attributeSyntax: 2.5.5.9 isSingleValued: TRUE showInAdvancedViewOnly: TRUE adminDisplayName: ms-Exch-Chat-Nick-Delay adminDescription: ms-Exch-Chat-Nick-Delay oMSyntax: 2 searchFlags: 0 lDAPDisplayName: msExchChatNickDelay name: ms-Exch-Chat-Nick-Delay schemaIDGUID: 9a3d6884-b093-11d2-aa06-00c04f8eedd8 isMemberOfPartialAttributeSet: FALSE objectCategory: CN=Attribute-Schema,${SCHEMADN} # # ms-Exch-Chat-Output-Saturation # The maximum level of buffering allowed before a client connection is # terminated. # dn: CN=ms-Exch-Chat-Output-Saturation,${SCHEMADN} objectClass: top objectClass: attributeSchema cn: ms-Exch-Chat-Output-Saturation distinguishedName: CN=ms-Exch-Chat-Output-Saturation,${SCHEMADN} attributeID: 1.2.840.113556.1.4.7000.102.8039 attributeSyntax: 2.5.5.9 isSingleValued: TRUE showInAdvancedViewOnly: TRUE adminDisplayName: ms-Exch-Chat-Output-Saturation adminDescription: ms-Exch-Chat-Output-Saturation oMSyntax: 2 searchFlags: 0 lDAPDisplayName: msExchChatOutputSaturation name: ms-Exch-Chat-Output-Saturation schemaIDGUID: 9a5c6716-b093-11d2-aa06-00c04f8eedd8 isMemberOfPartialAttributeSet: FALSE objectCategory: CN=Attribute-Schema,${SCHEMADN} # # ms-Exch-Chat-Ping-Delay # The frequency of keep-alive pings from the Chat server. # dn: CN=ms-Exch-Chat-Ping-Delay,${SCHEMADN} objectClass: top objectClass: attributeSchema cn: ms-Exch-Chat-Ping-Delay distinguishedName: CN=ms-Exch-Chat-Ping-Delay,${SCHEMADN} attributeID: 1.2.840.113556.1.4.7000.102.8037 attributeSyntax: 2.5.5.9 isSingleValued: TRUE showInAdvancedViewOnly: TRUE adminDisplayName: ms-Exch-Chat-Ping-Delay adminDescription: ms-Exch-Chat-Ping-Delay oMSyntax: 2 searchFlags: 0 lDAPDisplayName: msExchChatPingDelay name: ms-Exch-Chat-Ping-Delay schemaIDGUID: 9a7b65a8-b093-11d2-aa06-00c04f8eedd8 isMemberOfPartialAttributeSet: FALSE objectCategory: CN=Attribute-Schema,${SCHEMADN} # # ms-Exch-Chat-Protection-Level # The general attack protection level used by the Chat server. # dn: CN=ms-Exch-Chat-Protection-Level,${SCHEMADN} objectClass: top objectClass: attributeSchema cn: ms-Exch-Chat-Protection-Level distinguishedName: CN=ms-Exch-Chat-Protection-Level,${SCHEMADN} attributeID: 1.2.840.113556.1.4.7000.102.8035 attributeSyntax: 2.5.5.9 isSingleValued: TRUE showInAdvancedViewOnly: TRUE adminDisplayName: ms-Exch-Chat-Protection-Level adminDescription: ms-Exch-Chat-Protection-Level oMSyntax: 2 searchFlags: 0 lDAPDisplayName: msExchChatProtectionLevel name: ms-Exch-Chat-Protection-Level schemaIDGUID: 9a9a643a-b093-11d2-aa06-00c04f8eedd8 isMemberOfPartialAttributeSet: FALSE objectCategory: CN=Attribute-Schema,${SCHEMADN} # # ms-Exch-Chat-Server-Port # dn: CN=ms-Exch-Chat-Server-Port,${SCHEMADN} objectClass: top objectClass: attributeSchema cn: ms-Exch-Chat-Server-Port distinguishedName: CN=ms-Exch-Chat-Server-Port,${SCHEMADN} attributeID: 1.2.840.113556.1.4.7000.102.8008 attributeSyntax: 2.5.5.9 isSingleValued: TRUE showInAdvancedViewOnly: TRUE adminDisplayName: ms-Exch-Chat-Server-Port adminDescription: ms-Exch-Chat-Server-Port oMSyntax: 2 searchFlags: 0 lDAPDisplayName: msExchChatServerPort name: ms-Exch-Chat-Server-Port schemaIDGUID: 9ab70072-b093-11d2-aa06-00c04f8eedd8 isMemberOfPartialAttributeSet: FALSE objectCategory: CN=Attribute-Schema,${SCHEMADN} # # ms-Exch-Chat-Start-Time # The time at which this item becomes active. The duration for which # it is active is determined by the value of ms-Exch-Chat-Duration # Attribute. # dn: CN=ms-Exch-Chat-Start-Time,${SCHEMADN} objectClass: top objectClass: attributeSchema cn: ms-Exch-Chat-Start-Time distinguishedName: CN=ms-Exch-Chat-Start-Time,${SCHEMADN} attributeID: 1.2.840.113556.1.4.7000.102.8041 attributeSyntax: 2.5.5.11 isSingleValued: TRUE showInAdvancedViewOnly: TRUE adminDisplayName: ms-Exch-Chat-Start-Time adminDescription: ms-Exch-Chat-Start-Time oMSyntax: 23 searchFlags: 0 lDAPDisplayName: msExchChatStartTime name: ms-Exch-Chat-Start-Time schemaIDGUID: 9ad39caa-b093-11d2-aa06-00c04f8eedd8 isMemberOfPartialAttributeSet: FALSE objectCategory: CN=Attribute-Schema,${SCHEMADN} # # ms-Exch-Chat-Title # A description of the Chat community displayed to users when they # connect. # dn: CN=ms-Exch-Chat-Title,${SCHEMADN} objectClass: top objectClass: attributeSchema cn: ms-Exch-Chat-Title distinguishedName: CN=ms-Exch-Chat-Title,${SCHEMADN} attributeID: 1.2.840.113556.1.4.7000.102.8002 attributeSyntax: 2.5.5.12 isSingleValued: TRUE showInAdvancedViewOnly: TRUE adminDisplayName: ms-Exch-Chat-Title adminDescription: ms-Exch-Chat-Title oMSyntax: 64 searchFlags: 0 lDAPDisplayName: msExchChatTitle name: ms-Exch-Chat-Title schemaIDGUID: 9af29b3c-b093-11d2-aa06-00c04f8eedd8 isMemberOfPartialAttributeSet: FALSE objectCategory: CN=Attribute-Schema,${SCHEMADN} # # ms-Exch-Child-Sync-Agreements # A backlink to the connection agreements from the service. # dn: CN=ms-Exch-Child-Sync-Agreements,${SCHEMADN} objectClass: top objectClass: attributeSchema cn: ms-Exch-Child-Sync-Agreements distinguishedName: CN=ms-Exch-Child-Sync-Agreements,${SCHEMADN} attributeID: 1.2.840.113556.1.4.7000.102.37 attributeSyntax: 2.5.5.1 isSingleValued: FALSE linkID: 147 showInAdvancedViewOnly: TRUE adminDisplayName: ms-Exch-Child-Sync-Agreements oMObjectClass:: KwwCh3McAIVK adminDescription: ms-Exch-Child-Sync-Agreements oMSyntax: 127 searchFlags: 0 lDAPDisplayName: msExchChildSyncAgreements name: ms-Exch-Child-Sync-Agreements schemaIDGUID: 9b309860-b093-11d2-aa06-00c04f8eedd8 systemFlags: 1 isMemberOfPartialAttributeSet: FALSE objectCategory: CN=Attribute-Schema,${SCHEMADN} # # ms-Exch-CI-Available # dn: CN=ms-Exch-CI-Available,${SCHEMADN} objectClass: top objectClass: attributeSchema cn: ms-Exch-CI-Available distinguishedName: CN=ms-Exch-CI-Available,${SCHEMADN} attributeID: 1.2.840.113556.1.4.7000.102.11066 attributeSyntax: 2.5.5.8 isSingleValued: TRUE showInAdvancedViewOnly: TRUE adminDisplayName: ms-Exch-CI-Available adminDescription: ms-Exch-CI-Available oMSyntax: 1 searchFlags: 0 lDAPDisplayName: msExchCIAvailable name: ms-Exch-CI-Available schemaIDGUID: 035da50e-1a9e-11d3-aa59-00c04f8eedd8 isMemberOfPartialAttributeSet: FALSE objectCategory: CN=Attribute-Schema,${SCHEMADN} # # ms-Exch-CI-Location # Stores the location of the index. # dn: CN=ms-Exch-CI-Location,${SCHEMADN} objectClass: top objectClass: attributeSchema cn: ms-Exch-CI-Location distinguishedName: CN=ms-Exch-CI-Location,${SCHEMADN} attributeID: 1.2.840.113556.1.4.7000.102.11068 attributeSyntax: 2.5.5.12 isSingleValued: TRUE showInAdvancedViewOnly: TRUE adminDisplayName: ms-Exch-CI-Location adminDescription: ms-Exch-CI-Location oMSyntax: 64 searchFlags: 0 lDAPDisplayName: msExchCILocation name: ms-Exch-CI-Location schemaIDGUID: cec44725-22ae-11d3-aa62-00c04f8eedd8 isMemberOfPartialAttributeSet: FALSE objectCategory: CN=Attribute-Schema,${SCHEMADN} # # ms-Exch-CI-Rebuild-Schedule # dn: CN=ms-Exch-CI-Rebuild-Schedule,${SCHEMADN} objectClass: top objectClass: attributeSchema cn: ms-Exch-CI-Rebuild-Schedule distinguishedName: CN=ms-Exch-CI-Rebuild-Schedule,${SCHEMADN} attributeID: 1.2.840.113556.1.4.7000.102.11063 attributeSyntax: 2.5.5.10 isSingleValued: TRUE rangeLower: 84 rangeUpper: 84 showInAdvancedViewOnly: TRUE adminDisplayName: ms-Exch-CI-Rebuild-Schedule adminDescription: ms-Exch-CI-Rebuild-Schedule oMSyntax: 4 searchFlags: 0 lDAPDisplayName: msExchCIRebuildSchedule name: ms-Exch-CI-Rebuild-Schedule schemaIDGUID: 035da4fd-1a9e-11d3-aa59-00c04f8eedd8 isMemberOfPartialAttributeSet: FALSE objectCategory: CN=Attribute-Schema,${SCHEMADN} # # ms-Exch-CI-Rebuild-Style # dn: CN=ms-Exch-CI-Rebuild-Style,${SCHEMADN} objectClass: top objectClass: attributeSchema cn: ms-Exch-CI-Rebuild-Style distinguishedName: CN=ms-Exch-CI-Rebuild-Style,${SCHEMADN} attributeID: 1.2.840.113556.1.4.7000.102.11065 attributeSyntax: 2.5.5.9 isSingleValued: TRUE rangeLower: 0 rangeUpper: 3 showInAdvancedViewOnly: TRUE adminDisplayName: ms-Exch-CI-Rebuild-Style adminDescription: ms-Exch-CI-Rebuild-Style oMSyntax: 2 searchFlags: 0 lDAPDisplayName: msExchCIRebuildStyle name: ms-Exch-CI-Rebuild-Style schemaIDGUID: 035da507-1a9e-11d3-aa59-00c04f8eedd8 isMemberOfPartialAttributeSet: FALSE objectCategory: CN=Attribute-Schema,${SCHEMADN} # # ms-Exch-CI-Update-Schedule # dn: CN=ms-Exch-CI-Update-Schedule,${SCHEMADN} objectClass: top objectClass: attributeSchema cn: ms-Exch-CI-Update-Schedule distinguishedName: CN=ms-Exch-CI-Update-Schedule,${SCHEMADN} attributeID: 1.2.840.113556.1.4.7000.102.11062 attributeSyntax: 2.5.5.10 isSingleValued: TRUE rangeLower: 84 rangeUpper: 84 showInAdvancedViewOnly: TRUE adminDisplayName: ms-Exch-CI-Update-Schedule adminDescription: ms-Exch-CI-Update-Schedule oMSyntax: 4 searchFlags: 0 lDAPDisplayName: msExchCIUpdateSchedule name: ms-Exch-CI-Update-Schedule schemaIDGUID: 035da4f8-1a9e-11d3-aa59-00c04f8eedd8 isMemberOfPartialAttributeSet: FALSE objectCategory: CN=Attribute-Schema,${SCHEMADN} # # ms-Exch-CI-Update-Style # dn: CN=ms-Exch-CI-Update-Style,${SCHEMADN} objectClass: top objectClass: attributeSchema cn: ms-Exch-CI-Update-Style distinguishedName: CN=ms-Exch-CI-Update-Style,${SCHEMADN} attributeID: 1.2.840.113556.1.4.7000.102.11064 attributeSyntax: 2.5.5.9 isSingleValued: TRUE rangeLower: 0 rangeUpper: 3 showInAdvancedViewOnly: TRUE adminDisplayName: ms-Exch-CI-Update-Style adminDescription: ms-Exch-CI-Update-Style oMSyntax: 2 searchFlags: 0 lDAPDisplayName: msExchCIUpdateStyle name: ms-Exch-CI-Update-Style schemaIDGUID: 035da502-1a9e-11d3-aa59-00c04f8eedd8 isMemberOfPartialAttributeSet: FALSE objectCategory: CN=Attribute-Schema,${SCHEMADN} # # ms-Exch-Client-Access-Enabled # dn: CN=ms-Exch-Client-Access-Enabled,${SCHEMADN} objectClass: top objectClass: attributeSchema cn: ms-Exch-Client-Access-Enabled distinguishedName: CN=ms-Exch-Client-Access-Enabled,${SCHEMADN} attributeID: 1.2.840.113556.1.2.559 attributeSyntax: 2.5.5.8 isSingleValued: TRUE mAPIID: 35876 showInAdvancedViewOnly: TRUE adminDisplayName: ms-Exch-Client-Access-Enabled adminDescription: ms-Exch-Client-Access-Enabled oMSyntax: 1 searchFlags: 0 lDAPDisplayName: clientAccessEnabled name: ms-Exch-Client-Access-Enabled schemaIDGUID: a8df73af-c5ea-11d1-bbcb-0080c76670c0 isMemberOfPartialAttributeSet: FALSE objectCategory: CN=Attribute-Schema,${SCHEMADN} # # ms-Exch-Clock-Alert-Offset # dn: CN=ms-Exch-Clock-Alert-Offset,${SCHEMADN} objectClass: top objectClass: attributeSchema cn: ms-Exch-Clock-Alert-Offset distinguishedName: CN=ms-Exch-Clock-Alert-Offset,${SCHEMADN} attributeID: 1.2.840.113556.1.2.165 attributeSyntax: 2.5.5.9 isSingleValued: TRUE mAPIID: 32865 showInAdvancedViewOnly: TRUE adminDisplayName: ms-Exch-Clock-Alert-Offset adminDescription: ms-Exch-Clock-Alert-Offset oMSyntax: 2 searchFlags: 0 lDAPDisplayName: clockAlertOffset name: ms-Exch-Clock-Alert-Offset schemaIDGUID: a8df73b0-c5ea-11d1-bbcb-0080c76670c0 isMemberOfPartialAttributeSet: FALSE objectCategory: CN=Attribute-Schema,${SCHEMADN} # # ms-Exch-Clock-Alert-Repair # dn: CN=ms-Exch-Clock-Alert-Repair,${SCHEMADN} objectClass: top objectClass: attributeSchema cn: ms-Exch-Clock-Alert-Repair distinguishedName: CN=ms-Exch-Clock-Alert-Repair,${SCHEMADN} attributeID: 1.2.840.113556.1.2.164 attributeSyntax: 2.5.5.8 isSingleValued: TRUE mAPIID: 32866 showInAdvancedViewOnly: TRUE adminDisplayName: ms-Exch-Clock-Alert-Repair adminDescription: ms-Exch-Clock-Alert-Repair oMSyntax: 1 searchFlags: 0 lDAPDisplayName: clockAlertRepair name: ms-Exch-Clock-Alert-Repair schemaIDGUID: a8df73b1-c5ea-11d1-bbcb-0080c76670c0 isMemberOfPartialAttributeSet: FALSE objectCategory: CN=Attribute-Schema,${SCHEMADN} # # ms-Exch-Clock-Warning-Offset # dn: CN=ms-Exch-Clock-Warning-Offset,${SCHEMADN} objectClass: top objectClass: attributeSchema cn: ms-Exch-Clock-Warning-Offset distinguishedName: CN=ms-Exch-Clock-Warning-Offset,${SCHEMADN} attributeID: 1.2.840.113556.1.2.177 attributeSyntax: 2.5.5.9 isSingleValued: TRUE mAPIID: 32867 showInAdvancedViewOnly: TRUE adminDisplayName: ms-Exch-Clock-Warning-Offset adminDescription: ms-Exch-Clock-Warning-Offset oMSyntax: 2 searchFlags: 0 lDAPDisplayName: clockWarningOffset name: ms-Exch-Clock-Warning-Offset schemaIDGUID: a8df73b2-c5ea-11d1-bbcb-0080c76670c0 isMemberOfPartialAttributeSet: FALSE objectCategory: CN=Attribute-Schema,${SCHEMADN} # # ms-Exch-Clock-Warning-Repair # dn: CN=ms-Exch-Clock-Warning-Repair,${SCHEMADN} objectClass: top objectClass: attributeSchema cn: ms-Exch-Clock-Warning-Repair distinguishedName: CN=ms-Exch-Clock-Warning-Repair,${SCHEMADN} attributeID: 1.2.840.113556.1.2.166 attributeSyntax: 2.5.5.8 isSingleValued: TRUE mAPIID: 32868 showInAdvancedViewOnly: TRUE adminDisplayName: ms-Exch-Clock-Warning-Repair adminDescription: ms-Exch-Clock-Warning-Repair oMSyntax: 1 searchFlags: 0 lDAPDisplayName: clockWarningRepair name: ms-Exch-Clock-Warning-Repair schemaIDGUID: a8df73b3-c5ea-11d1-bbcb-0080c76670c0 isMemberOfPartialAttributeSet: FALSE objectCategory: CN=Attribute-Schema,${SCHEMADN} # # ms-Exch-Compromised-Key-List # dn: CN=ms-Exch-Compromised-Key-List,${SCHEMADN} objectClass: top objectClass: attributeSchema cn: ms-Exch-Compromised-Key-List distinguishedName: CN=ms-Exch-Compromised-Key-List,${SCHEMADN} attributeID: 1.2.840.113556.1.2.542 attributeSyntax: 2.5.5.10 isSingleValued: TRUE mAPIID: 33220 showInAdvancedViewOnly: TRUE adminDisplayName: ms-Exch-Compromised-Key-List adminDescription: ms-Exch-Compromised-Key-List oMSyntax: 4 searchFlags: 0 lDAPDisplayName: compromisedKeyList name: ms-Exch-Compromised-Key-List schemaIDGUID: 167757a9-47f3-11d1-a9c3-0000f80367c1 isMemberOfPartialAttributeSet: FALSE objectCategory: CN=Attribute-Schema,${SCHEMADN} # # ms-Exch-Computer-Link # A link from the computer to the Exchange server. # dn: CN=ms-Exch-Computer-Link,${SCHEMADN} objectClass: top objectClass: attributeSchema cn: ms-Exch-Computer-Link distinguishedName: CN=ms-Exch-Computer-Link,${SCHEMADN} attributeID: 1.2.840.113556.1.4.7000.102.72 attributeSyntax: 2.5.5.1 isSingleValued: TRUE linkID: 1018 showInAdvancedViewOnly: TRUE adminDisplayName: ms-Exch-Computer-Link oMObjectClass:: KwwCh3McAIVK adminDescription: ms-Exch-Computer-Link oMSyntax: 127 searchFlags: 0 lDAPDisplayName: msExchComputerLink name: ms-Exch-Computer-Link schemaIDGUID: 8a5852f2-b09e-11d2-aa06-00c04f8eedd8 isMemberOfPartialAttributeSet: FALSE objectCategory: CN=Attribute-Schema,${SCHEMADN} # # ms-Exch-Computer-Name # dn: CN=ms-Exch-Computer-Name,${SCHEMADN} objectClass: top objectClass: attributeSchema cn: ms-Exch-Computer-Name distinguishedName: CN=ms-Exch-Computer-Name,${SCHEMADN} attributeID: 1.2.840.113556.1.2.20 attributeSyntax: 2.5.5.4 isSingleValued: TRUE rangeLower: 1 rangeUpper: 256 mAPIID: 32869 showInAdvancedViewOnly: TRUE adminDisplayName: ms-Exch-Computer-Name adminDescription: ms-Exch-Computer-Name oMSyntax: 20 searchFlags: 0 lDAPDisplayName: computerName name: ms-Exch-Computer-Name schemaIDGUID: a8df73b4-c5ea-11d1-bbcb-0080c76670c0 isMemberOfPartialAttributeSet: FALSE objectCategory: CN=Attribute-Schema,${SCHEMADN} # # ms-Exch-Conference-Mailbox # The forward link to the Exchange Conferencing Service conference # calendar mailbox. # dn: CN=ms-Exch-Conference-Mailbox,${SCHEMADN} objectClass: top objectClass: attributeSchema cn: ms-Exch-Conference-Mailbox distinguishedName: CN=ms-Exch-Conference-Mailbox,${SCHEMADN} attributeID: 1.2.840.113556.1.4.7000.102.9029 attributeSyntax: 2.5.5.1 isSingleValued: TRUE linkID: 1036 showInAdvancedViewOnly: TRUE adminDisplayName: ms-Exch-Conference-Mailbox oMObjectClass:: KwwCh3McAIVK adminDescription: ms-Exch-Conference-Mailbox oMSyntax: 127 searchFlags: 0 lDAPDisplayName: msExchConferenceMailbox name: ms-Exch-Conference-Mailbox schemaIDGUID: 628f0513-88f6-4cef-9de4-b367eb7e8383 isMemberOfPartialAttributeSet: FALSE objectCategory: CN=Attribute-Schema,${SCHEMADN} # # ms-Exch-Conference-Mailbox-BL # The backlink to the Exchange Conferencing Service conference # calendar mailbox. # dn: CN=ms-Exch-Conference-Mailbox-BL,${SCHEMADN} objectClass: top objectClass: attributeSchema cn: ms-Exch-Conference-Mailbox-BL distinguishedName: CN=ms-Exch-Conference-Mailbox-BL,${SCHEMADN} attributeID: 1.2.840.113556.1.4.7000.102.9030 attributeSyntax: 2.5.5.1 isSingleValued: TRUE linkID: 1037 showInAdvancedViewOnly: TRUE adminDisplayName: ms-Exch-Conference-Mailbox-BL oMObjectClass:: KwwCh3McAIVK adminDescription: ms-Exch-Conference-Mailbox-BL oMSyntax: 127 searchFlags: 0 lDAPDisplayName: msExchConferenceMailboxBL name: ms-Exch-Conference-Mailbox-BL schemaIDGUID: 9423ec2c-383b-44b2-8913-ab79ac609bd4 attributeSecurityGUID: e48d0154-bcf8-11d1-8702-00c04fb96050 systemFlags: 1 isMemberOfPartialAttributeSet: FALSE objectCategory: CN=Attribute-Schema,${SCHEMADN} # # ms-Exch-Conference-Zone # The Exchange Conferencing Service site forward link. # dn: CN=ms-Exch-Conference-Zone,${SCHEMADN} objectClass: top objectClass: attributeSchema cn: ms-Exch-Conference-Zone distinguishedName: CN=ms-Exch-Conference-Zone,${SCHEMADN} attributeID: 1.2.840.113556.1.4.7000.102.9015 attributeSyntax: 2.5.5.1 isSingleValued: TRUE linkID: 1020 showInAdvancedViewOnly: TRUE adminDisplayName: ms-Exch-Conference-Zone oMObjectClass:: KwwCh3McAIVK adminDescription: ms-Exch-Conference-Zone oMSyntax: 127 searchFlags: 0 lDAPDisplayName: msExchConferenceZone name: ms-Exch-Conference-Zone schemaIDGUID: 8cfd6eca-b09e-11d2-aa06-00c04f8eedd8 isMemberOfPartialAttributeSet: FALSE objectCategory: CN=Attribute-Schema,${SCHEMADN} # # ms-Exch-Conference-Zone-BL # The Exchange Conferencing Service site backlink. # dn: CN=ms-Exch-Conference-Zone-BL,${SCHEMADN} objectClass: top objectClass: attributeSchema cn: ms-Exch-Conference-Zone-BL distinguishedName: CN=ms-Exch-Conference-Zone-BL,${SCHEMADN} attributeID: 1.2.840.113556.1.4.7000.102.9024 attributeSyntax: 2.5.5.1 isSingleValued: TRUE linkID: 1021 showInAdvancedViewOnly: TRUE adminDisplayName: ms-Exch-Conference-Zone-BL oMObjectClass:: KwwCh3McAIVK adminDescription: ms-Exch-Conference-Zone-BL oMSyntax: 127 searchFlags: 0 lDAPDisplayName: msExchConferenceZoneBL name: ms-Exch-Conference-Zone-BL schemaIDGUID: 8d1a0b02-b09e-11d2-aa06-00c04f8eedd8 systemFlags: 1 isMemberOfPartialAttributeSet: FALSE objectCategory: CN=Attribute-Schema,${SCHEMADN} # # ms-Exch-Connected-Domains # The sites or AGs that are connected using this connector. # dn: CN=ms-Exch-Connected-Domains,${SCHEMADN} objectClass: top objectClass: attributeSchema cn: ms-Exch-Connected-Domains distinguishedName: CN=ms-Exch-Connected-Domains,${SCHEMADN} attributeID: 1.2.840.113556.1.2.211 attributeSyntax: 2.5.5.4 isSingleValued: FALSE rangeLower: 1 rangeUpper: 1243 mAPIID: 32870 showInAdvancedViewOnly: TRUE adminDisplayName: ms-Exch-Connected-Domains adminDescription: ms-Exch-Connected-Domains oMSyntax: 20 searchFlags: 0 lDAPDisplayName: connectedDomains name: ms-Exch-Connected-Domains schemaIDGUID: a8df73b5-c5ea-11d1-bbcb-0080c76670c0 isMemberOfPartialAttributeSet: FALSE objectCategory: CN=Attribute-Schema,${SCHEMADN} # # ms-Exch-Connection-List-Filter # dn: CN=ms-Exch-Connection-List-Filter,${SCHEMADN} objectClass: top objectClass: attributeSchema cn: ms-Exch-Connection-List-Filter distinguishedName: CN=ms-Exch-Connection-List-Filter,${SCHEMADN} attributeID: 1.2.840.113556.1.2.475 attributeSyntax: 2.5.5.10 isSingleValued: TRUE rangeLower: 1 rangeUpper: 10240 mAPIID: 33152 showInAdvancedViewOnly: TRUE adminDisplayName: ms-Exch-Connection-List-Filter adminDescription: ms-Exch-Connection-List-Filter oMSyntax: 4 searchFlags: 0 lDAPDisplayName: connectionListFilter name: ms-Exch-Connection-List-Filter schemaIDGUID: a8df73b6-c5ea-11d1-bbcb-0080c76670c0 isMemberOfPartialAttributeSet: FALSE objectCategory: CN=Attribute-Schema,${SCHEMADN} # # ms-Exch-Connection-List-Filter-Type # dn: CN=ms-Exch-Connection-List-Filter-Type,${SCHEMADN} objectClass: top objectClass: attributeSchema cn: ms-Exch-Connection-List-Filter-Type distinguishedName: CN=ms-Exch-Connection-List-Filter-Type,${SCHEMADN} attributeID: 1.2.840.113556.1.2.526 attributeSyntax: 2.5.5.9 isSingleValued: TRUE rangeLower: 0 rangeUpper: 2 mAPIID: 33204 showInAdvancedViewOnly: TRUE adminDisplayName: ms-Exch-Connection-List-Filter-Type adminDescription: ms-Exch-Connection-List-Filter-Type oMSyntax: 10 searchFlags: 0 lDAPDisplayName: connectionListFilterType name: ms-Exch-Connection-List-Filter-Type schemaIDGUID: a8df73b7-c5ea-11d1-bbcb-0080c76670c0 isMemberOfPartialAttributeSet: FALSE objectCategory: CN=Attribute-Schema,${SCHEMADN} # # ms-Exch-Connector-Type # The type of Exchange connector. # dn: CN=ms-Exch-Connector-Type,${SCHEMADN} objectClass: top objectClass: attributeSchema cn: ms-Exch-Connector-Type distinguishedName: CN=ms-Exch-Connector-Type,${SCHEMADN} attributeID: 1.2.840.113556.1.4.7000.102.12508 attributeSyntax: 2.5.5.4 isSingleValued: TRUE rangeLower: 0 rangeUpper: 255 showInAdvancedViewOnly: TRUE adminDisplayName: ms-Exch-Connector-Type adminDescription: ms-Exch-Connector-Type oMSyntax: 20 searchFlags: 0 lDAPDisplayName: msExchConnectorType name: ms-Exch-Connector-Type schemaIDGUID: 9b8d9416-b093-11d2-aa06-00c04f8eedd8 isMemberOfPartialAttributeSet: FALSE objectCategory: CN=Attribute-Schema,${SCHEMADN} # # ms-Exch-Container-Info # dn: CN=ms-Exch-Container-Info,${SCHEMADN} objectClass: top objectClass: attributeSchema cn: ms-Exch-Container-Info distinguishedName: CN=ms-Exch-Container-Info,${SCHEMADN} attributeID: 1.2.840.113556.1.2.296 attributeSyntax: 2.5.5.9 isSingleValued: TRUE mAPIID: 32871 showInAdvancedViewOnly: TRUE adminDisplayName: ms-Exch-Container-Info adminDescription: ms-Exch-Container-Info oMSyntax: 2 searchFlags: 0 lDAPDisplayName: containerInfo name: ms-Exch-Container-Info schemaIDGUID: bf967942-0de6-11d0-a285-00aa003049e2 isMemberOfPartialAttributeSet: FALSE objectCategory: CN=Attribute-Schema,${SCHEMADN} # # ms-Exch-Content-Type # Contains information about MIME versus Unix-to-Unix encode # (UUENCODE) and Rich Text Format (RTF) for a domain content # configuration. # dn: CN=ms-Exch-Content-Type,${SCHEMADN} objectClass: top objectClass: attributeSchema cn: ms-Exch-Content-Type distinguishedName: CN=ms-Exch-Content-Type,${SCHEMADN} attributeID: 1.2.840.113556.1.2.481 attributeSyntax: 2.5.5.9 isSingleValued: TRUE rangeLower: 0 rangeUpper: 4 mAPIID: 33158 showInAdvancedViewOnly: TRUE adminDisplayName: ms-Exch-Content-Type adminDescription: ms-Exch-Content-Type oMSyntax: 10 searchFlags: 0 lDAPDisplayName: contentType name: ms-Exch-Content-Type schemaIDGUID: a8df73b9-c5ea-11d1-bbcb-0080c76670c0 isMemberOfPartialAttributeSet: FALSE objectCategory: CN=Attribute-Schema,${SCHEMADN} # # ms-Exch-Controlling-Zone # The forward link to the Exchange Conferencing Service resource # mailbox. # dn: CN=ms-Exch-Controlling-Zone,${SCHEMADN} objectClass: top objectClass: attributeSchema cn: ms-Exch-Controlling-Zone distinguishedName: CN=ms-Exch-Controlling-Zone,${SCHEMADN} attributeID: 1.2.840.113556.1.4.7000.102.9026 attributeSyntax: 2.5.5.1 isSingleValued: TRUE showInAdvancedViewOnly: TRUE adminDisplayName: ms-Exch-Controlling-Zone oMObjectClass:: KwwCh3McAIVK adminDescription: ms-Exch-Controlling-Zone oMSyntax: 127 searchFlags: 16 lDAPDisplayName: msExchControllingZone name: ms-Exch-Controlling-Zone schemaIDGUID: 91462882-b09e-11d2-aa06-00c04f8eedd8 attributeSecurityGUID: e48d0154-bcf8-11d1-8702-00c04fb96050 isMemberOfPartialAttributeSet: FALSE objectCategory: CN=Attribute-Schema,${SCHEMADN} # # ms-Exch-Control-Msg-Folder-ID # dn: CN=ms-Exch-Control-Msg-Folder-ID,${SCHEMADN} objectClass: top objectClass: attributeSchema cn: ms-Exch-Control-Msg-Folder-ID distinguishedName: CN=ms-Exch-Control-Msg-Folder-ID,${SCHEMADN} attributeID: 1.2.840.113556.1.2.483 attributeSyntax: 2.5.5.10 isSingleValued: TRUE rangeLower: 1 rangeUpper: 1024 mAPIID: 33160 showInAdvancedViewOnly: TRUE adminDisplayName: ms-Exch-Control-Msg-Folder-ID adminDescription: ms-Exch-Control-Msg-Folder-ID oMSyntax: 4 searchFlags: 0 lDAPDisplayName: controlMsgFolderID name: ms-Exch-Control-Msg-Folder-ID schemaIDGUID: a8df73ba-c5ea-11d1-bbcb-0080c76670c0 isMemberOfPartialAttributeSet: FALSE objectCategory: CN=Attribute-Schema,${SCHEMADN} # # ms-Exch-Control-Msg-Rules # dn: CN=ms-Exch-Control-Msg-Rules,${SCHEMADN} objectClass: top objectClass: attributeSchema cn: ms-Exch-Control-Msg-Rules distinguishedName: CN=ms-Exch-Control-Msg-Rules,${SCHEMADN} attributeID: 1.2.840.113556.1.2.485 attributeSyntax: 2.5.5.10 isSingleValued: TRUE rangeLower: 1 rangeUpper: 32767 mAPIID: 33162 showInAdvancedViewOnly: TRUE adminDisplayName: ms-Exch-Control-Msg-Rules adminDescription: ms-Exch-Control-Msg-Rules oMSyntax: 4 searchFlags: 0 lDAPDisplayName: controlMsgRules name: ms-Exch-Control-Msg-Rules schemaIDGUID: a8df73bb-c5ea-11d1-bbcb-0080c76670c0 isMemberOfPartialAttributeSet: FALSE objectCategory: CN=Attribute-Schema,${SCHEMADN} # # ms-Exch-Convert-To-Fixed-Font # If True, the store configures IMAIL to convert Internet messages to # fixed font for RTF clients. The default is False. # dn: CN=ms-Exch-Convert-To-Fixed-Font,${SCHEMADN} objectClass: top objectClass: attributeSchema cn: ms-Exch-Convert-To-Fixed-Font distinguishedName: CN=ms-Exch-Convert-To-Fixed-Font,${SCHEMADN} attributeID: 1.2.840.113556.1.4.7000.102.11021 attributeSyntax: 2.5.5.8 isSingleValued: TRUE showInAdvancedViewOnly: TRUE adminDisplayName: ms-Exch-Convert-To-Fixed-Font adminDescription: ms-Exch-Convert-To-Fixed-Font oMSyntax: 1 searchFlags: 0 lDAPDisplayName: msExchConvertToFixedFont name: ms-Exch-Convert-To-Fixed-Font schemaIDGUID: 9bac92a8-b093-11d2-aa06-00c04f8eedd8 isMemberOfPartialAttributeSet: FALSE objectCategory: CN=Attribute-Schema,${SCHEMADN} # # ms-Exch-Correlation-Attribute # The LDAP display name of the attribute used to correlate # entries. This is not used for replication between Exchange and # Microsoft® Windows®. # dn: CN=ms-Exch-Correlation-Attribute,${SCHEMADN} objectClass: top objectClass: attributeSchema cn: ms-Exch-Correlation-Attribute distinguishedName: CN=ms-Exch-Correlation-Attribute,${SCHEMADN} attributeID: 1.2.840.113556.1.4.7000.102.43 attributeSyntax: 2.5.5.12 isSingleValued: TRUE showInAdvancedViewOnly: TRUE adminDisplayName: ms-Exch-Correlation-Attribute adminDescription: ms-Exch-Correlation-Attribute oMSyntax: 64 searchFlags: 0 lDAPDisplayName: msExchCorrelationAttribute name: ms-Exch-Correlation-Attribute schemaIDGUID: 9c098e5e-b093-11d2-aa06-00c04f8eedd8 isMemberOfPartialAttributeSet: FALSE objectCategory: CN=Attribute-Schema,${SCHEMADN} # # ms-Exch-Cross-Certificate-CRL # dn: CN=ms-Exch-Cross-Certificate-CRL,${SCHEMADN} objectClass: top objectClass: attributeSchema cn: ms-Exch-Cross-Certificate-CRL distinguishedName: CN=ms-Exch-Cross-Certificate-CRL,${SCHEMADN} attributeID: 1.2.840.113556.1.2.565 attributeSyntax: 2.5.5.10 isSingleValued: FALSE mAPIID: 35888 showInAdvancedViewOnly: TRUE adminDisplayName: ms-Exch-Cross-Certificate-CRL adminDescription: ms-Exch-Cross-Certificate-CRL oMSyntax: 4 searchFlags: 0 lDAPDisplayName: crossCertificateCRL name: ms-Exch-Cross-Certificate-CRL schemaIDGUID: a8df73bc-c5ea-11d1-bbcb-0080c76670c0 isMemberOfPartialAttributeSet: FALSE objectCategory: CN=Attribute-Schema,${SCHEMADN} # # ms-Exch-CTP-Class-GUID # The component implementation GUID for the conference technology # provider (CTP). # dn: CN=ms-Exch-CTP-Class-GUID,${SCHEMADN} objectClass: top objectClass: attributeSchema cn: ms-Exch-CTP-Class-GUID distinguishedName: CN=ms-Exch-CTP-Class-GUID,${SCHEMADN} attributeID: 1.2.840.113556.1.4.7000.102.9008 attributeSyntax: 2.5.5.12 isSingleValued: TRUE showInAdvancedViewOnly: TRUE adminDisplayName: ms-Exch-CTP-Class-GUID adminDescription: ms-Exch-CTP-Class-GUID oMSyntax: 64 searchFlags: 0 lDAPDisplayName: msExchCTPClassGUID name: ms-Exch-CTP-Class-GUID schemaIDGUID: 9c288cf0-b093-11d2-aa06-00c04f8eedd8 isMemberOfPartialAttributeSet: FALSE objectCategory: CN=Attribute-Schema,${SCHEMADN} # # ms-Exch-CTP-Frame-Hint # The frame hint size. # dn: CN=ms-Exch-CTP-Frame-Hint,${SCHEMADN} objectClass: top objectClass: attributeSchema cn: ms-Exch-CTP-Frame-Hint distinguishedName: CN=ms-Exch-CTP-Frame-Hint,${SCHEMADN} attributeID: 1.2.840.113556.1.4.7000.102.9010 attributeSyntax: 2.5.5.9 isSingleValued: TRUE showInAdvancedViewOnly: TRUE adminDisplayName: ms-Exch-CTP-Frame-Hint adminDescription: ms-Exch-CTP-Frame-Hint oMSyntax: 2 searchFlags: 0 lDAPDisplayName: msExchCTPFrameHint name: ms-Exch-CTP-Frame-Hint schemaIDGUID: 9c478b82-b093-11d2-aa06-00c04f8eedd8 isMemberOfPartialAttributeSet: FALSE objectCategory: CN=Attribute-Schema,${SCHEMADN} # # ms-Exch-CTP-Property-Schema # The CTP property schema. This attribute is obsolete. # dn: CN=ms-Exch-CTP-Property-Schema,${SCHEMADN} objectClass: top objectClass: attributeSchema cn: ms-Exch-CTP-Property-Schema distinguishedName: CN=ms-Exch-CTP-Property-Schema,${SCHEMADN} attributeID: 1.2.840.113556.1.4.7000.102.9022 attributeSyntax: 2.5.5.12 isSingleValued: FALSE showInAdvancedViewOnly: TRUE adminDisplayName: ms-Exch-CTP-Property-Schema adminDescription: ms-Exch-CTP-Property-Schema oMSyntax: 64 searchFlags: 0 lDAPDisplayName: msExchCTPPropertySchema name: ms-Exch-CTP-Property-Schema schemaIDGUID: 9c6427ba-b093-11d2-aa06-00c04f8eedd8 isMemberOfPartialAttributeSet: FALSE objectCategory: CN=Attribute-Schema,${SCHEMADN} # # ms-Exch-CTP-Provider-GUID # The CTP GUID. # dn: CN=ms-Exch-CTP-Provider-GUID,${SCHEMADN} objectClass: top objectClass: attributeSchema cn: ms-Exch-CTP-Provider-GUID distinguishedName: CN=ms-Exch-CTP-Provider-GUID,${SCHEMADN} attributeID: 1.2.840.113556.1.4.7000.102.9007 attributeSyntax: 2.5.5.12 isSingleValued: TRUE showInAdvancedViewOnly: TRUE adminDisplayName: ms-Exch-CTP-Provider-GUID adminDescription: ms-Exch-CTP-Provider-GUID oMSyntax: 64 searchFlags: 0 lDAPDisplayName: msExchCTPProviderGUID name: ms-Exch-CTP-Provider-GUID schemaIDGUID: 9c8588a6-b093-11d2-aa06-00c04f8eedd8 isMemberOfPartialAttributeSet: FALSE objectCategory: CN=Attribute-Schema,${SCHEMADN} # # ms-Exch-CTP-Provider-Name # The CTP internal name. # dn: CN=ms-Exch-CTP-Provider-Name,${SCHEMADN} objectClass: top objectClass: attributeSchema cn: ms-Exch-CTP-Provider-Name distinguishedName: CN=ms-Exch-CTP-Provider-Name,${SCHEMADN} attributeID: 1.2.840.113556.1.4.7000.102.9021 attributeSyntax: 2.5.5.12 isSingleValued: TRUE showInAdvancedViewOnly: TRUE adminDisplayName: ms-Exch-CTP-Provider-Name adminDescription: ms-Exch-CTP-Provider-Name oMSyntax: 64 searchFlags: 0 lDAPDisplayName: msExchCTPProviderName name: ms-Exch-CTP-Provider-Name schemaIDGUID: 9ca48738-b093-11d2-aa06-00c04f8eedd8 isMemberOfPartialAttributeSet: FALSE objectCategory: CN=Attribute-Schema,${SCHEMADN} # # ms-Exch-CTP-Require-CMS-Authentication # Indicates whether authentication is required to join the selected # conference. # dn: CN=ms-Exch-CTP-Require-CMS-Authentication,${SCHEMADN} objectClass: top objectClass: attributeSchema cn: ms-Exch-CTP-Require-CMS-Authentication distinguishedName: CN=ms-Exch-CTP-Require-CMS-Authentication,${SCHEMADN} attributeID: 1.2.840.113556.1.4.7000.102.9023 attributeSyntax: 2.5.5.8 isSingleValued: TRUE showInAdvancedViewOnly: TRUE adminDisplayName: ms-Exch-CTP-Require-CMS-Authentication adminDescription: ms-Exch-CTP-Require-CMS-Authentication oMSyntax: 1 searchFlags: 0 lDAPDisplayName: msExchCTPRequireCMSAuthentication name: ms-Exch-CTP-Require-CMS-Authentication schemaIDGUID: 8aa962e6-b09e-11d2-aa06-00c04f8eedd8 isMemberOfPartialAttributeSet: FALSE objectCategory: CN=Attribute-Schema,${SCHEMADN} # # ms-Exch-CTP-Snapin-GUID # The Microsoft Management Console (MMC) snap-in implementation GUID # for the CTP. # dn: CN=ms-Exch-CTP-Snapin-GUID,${SCHEMADN} objectClass: top objectClass: attributeSchema cn: ms-Exch-CTP-Snapin-GUID distinguishedName: CN=ms-Exch-CTP-Snapin-GUID,${SCHEMADN} attributeID: 1.2.840.113556.1.4.7000.102.9009 attributeSyntax: 2.5.5.12 isSingleValued: TRUE showInAdvancedViewOnly: TRUE adminDisplayName: ms-Exch-CTP-Snapin-GUID adminDescription: ms-Exch-CTP-Snapin-GUID oMSyntax: 64 searchFlags: 0 lDAPDisplayName: msExchCTPSnapinGUID name: ms-Exch-CTP-Snapin-GUID schemaIDGUID: 9cc385ca-b093-11d2-aa06-00c04f8eedd8 isMemberOfPartialAttributeSet: FALSE objectCategory: CN=Attribute-Schema,${SCHEMADN} # # ms-Exch-Custom-Proxy-Addresses # dn: CN=ms-Exch-Custom-Proxy-Addresses,${SCHEMADN} objectClass: top objectClass: attributeSchema cn: ms-Exch-Custom-Proxy-Addresses distinguishedName: CN=ms-Exch-Custom-Proxy-Addresses,${SCHEMADN} attributeID: 1.2.840.113556.1.4.7000.102.50049 attributeSyntax: 2.5.5.12 isSingleValued: FALSE showInAdvancedViewOnly: TRUE adminDisplayName: ms-Exch-Custom-Proxy-Addresses adminDescription: ms-Exch-Custom-Proxy-Addresses oMSyntax: 64 searchFlags: 0 lDAPDisplayName: msExchCustomProxyAddresses name: ms-Exch-Custom-Proxy-Addresses schemaIDGUID: e24d7a90-439d-11d3-aa72-00c04f8eedd8 attributeSecurityGUID: e48d0154-bcf8-11d1-8702-00c04fb96050 isMemberOfPartialAttributeSet: TRUE objectCategory: CN=Attribute-Schema,${SCHEMADN} # # ms-Exch-Database-Being-Restored # Prevents any mount to the database. This is set during a restore. # dn: CN=ms-Exch-Database-Being-Restored,${SCHEMADN} objectClass: top objectClass: attributeSchema cn: ms-Exch-Database-Being-Restored distinguishedName: CN=ms-Exch-Database-Being-Restored,${SCHEMADN} attributeID: 1.2.840.113556.1.4.7000.102.11085 attributeSyntax: 2.5.5.8 isSingleValued: TRUE showInAdvancedViewOnly: TRUE adminDisplayName: ms-Exch-Database-Being-Restored adminDescription: ms-Exch-Database-Being-Restored oMSyntax: 1 searchFlags: 0 lDAPDisplayName: msExchDatabaseBeingRestored name: ms-Exch-Database-Being-Restored schemaIDGUID: 372fadff-d0b6-4552-8057-f3a0d2c706a7 isMemberOfPartialAttributeSet: FALSE objectCategory: CN=Attribute-Schema,${SCHEMADN} # # ms-Exch-Database-Created # Indicates to the store whether or not the database is to be created. # dn: CN=ms-Exch-Database-Created,${SCHEMADN} objectClass: top objectClass: attributeSchema cn: ms-Exch-Database-Created distinguishedName: CN=ms-Exch-Database-Created,${SCHEMADN} attributeID: 1.2.840.113556.1.4.7000.102.11084 attributeSyntax: 2.5.5.8 isSingleValued: TRUE showInAdvancedViewOnly: TRUE adminDisplayName: ms-Exch-Database-Created adminDescription: ms-Exch-Database-Created oMSyntax: 1 searchFlags: 0 lDAPDisplayName: msExchDatabaseCreated name: ms-Exch-Database-Created schemaIDGUID: 14f27149-ba76-4aee-bac8-fced38fdff9d isMemberOfPartialAttributeSet: FALSE objectCategory: CN=Attribute-Schema,${SCHEMADN} # # ms-Exch-Database-Session-Addend # The accumulator for sessions. # dn: CN=ms-Exch-Database-Session-Addend,${SCHEMADN} objectClass: top objectClass: attributeSchema cn: ms-Exch-Database-Session-Addend distinguishedName: CN=ms-Exch-Database-Session-Addend,${SCHEMADN} attributeID: 1.2.840.113556.1.4.7000.102.11039 attributeSyntax: 2.5.5.9 isSingleValued: TRUE showInAdvancedViewOnly: TRUE adminDisplayName: ms-Exch-Database-Session-Addend adminDescription: ms-Exch-Database-Session-Addend oMSyntax: 2 searchFlags: 0 lDAPDisplayName: msExchDatabaseSessionAddend name: ms-Exch-Database-Session-Addend schemaIDGUID: 9ce2845c-b093-11d2-aa06-00c04f8eedd8 isMemberOfPartialAttributeSet: FALSE objectCategory: CN=Attribute-Schema,${SCHEMADN} # # ms-Exch-Database-Session-Increment # Number of Microsoft Jet sessions to allocate when more Jet sessions # are needed. # dn: CN=ms-Exch-Database-Session-Increment,${SCHEMADN} objectClass: top objectClass: attributeSchema cn: ms-Exch-Database-Session-Increment distinguishedName: CN=ms-Exch-Database-Session-Increment,${SCHEMADN} attributeID: 1.2.840.113556.1.4.7000.102.11040 attributeSyntax: 2.5.5.9 isSingleValued: TRUE showInAdvancedViewOnly: TRUE adminDisplayName: ms-Exch-Database-Session-Increment adminDescription: ms-Exch-Database-Session-Increment oMSyntax: 2 searchFlags: 0 lDAPDisplayName: msExchDatabaseSessionIncrement name: ms-Exch-Database-Session-Increment schemaIDGUID: 9d0647a2-b093-11d2-aa06-00c04f8eedd8 isMemberOfPartialAttributeSet: FALSE objectCategory: CN=Attribute-Schema,${SCHEMADN} # # ms-Exch-Data-Path # dn: CN=ms-Exch-Data-Path,${SCHEMADN} objectClass: top objectClass: attributeSchema cn: ms-Exch-Data-Path distinguishedName: CN=ms-Exch-Data-Path,${SCHEMADN} attributeID: 1.2.840.113556.1.4.7000.102.50052 attributeSyntax: 2.5.5.12 isSingleValued: TRUE showInAdvancedViewOnly: TRUE adminDisplayName: ms-Exch-Data-Path adminDescription: ms-Exch-Data-Path oMSyntax: 64 searchFlags: 0 lDAPDisplayName: msExchDataPath name: ms-Exch-Data-Path schemaIDGUID: 61c47260-454e-11d3-aa72-00c04f8eedd8 isMemberOfPartialAttributeSet: FALSE objectCategory: CN=Attribute-Schema,${SCHEMADN} # # ms-Exch-Default-Admin-Group # A flag indicating whether this administrator group is the default. # dn: CN=ms-Exch-Default-Admin-Group,${SCHEMADN} objectClass: top objectClass: attributeSchema cn: ms-Exch-Default-Admin-Group distinguishedName: CN=ms-Exch-Default-Admin-Group,${SCHEMADN} attributeID: 1.2.840.113556.1.4.7000.102.50015 attributeSyntax: 2.5.5.8 isSingleValued: TRUE showInAdvancedViewOnly: TRUE adminDisplayName: ms-Exch-Default-Admin-Group adminDescription: ms-Exch-Default-Admin-Group oMSyntax: 1 searchFlags: 0 lDAPDisplayName: msExchDefaultAdminGroup name: ms-Exch-Default-Admin-Group schemaIDGUID: 847584c2-b09e-11d2-aa06-00c04f8eedd8 isMemberOfPartialAttributeSet: FALSE objectCategory: CN=Attribute-Schema,${SCHEMADN} # # ms-Exch-Default-Domain # The domain used for basic authentication. # dn: CN=ms-Exch-Default-Domain,${SCHEMADN} objectClass: top objectClass: attributeSchema cn: ms-Exch-Default-Domain distinguishedName: CN=ms-Exch-Default-Domain,${SCHEMADN} attributeID: 1.2.840.113556.1.4.7000.102.2012 attributeSyntax: 2.5.5.12 isSingleValued: TRUE showInAdvancedViewOnly: TRUE adminDisplayName: ms-Exch-Default-Domain adminDescription: ms-Exch-Default-Domain oMSyntax: 64 searchFlags: 0 lDAPDisplayName: msExchDefaultDomain name: ms-Exch-Default-Domain schemaIDGUID: 9d22e3da-b093-11d2-aa06-00c04f8eedd8 isMemberOfPartialAttributeSet: FALSE objectCategory: CN=Attribute-Schema,${SCHEMADN} # # ms-Exch-Default-Load-File # dn: CN=ms-Exch-Default-Load-File,${SCHEMADN} objectClass: top objectClass: attributeSchema cn: ms-Exch-Default-Load-File distinguishedName: CN=ms-Exch-Default-Load-File,${SCHEMADN} attributeID: 1.2.840.113556.1.4.7000.102.15010 attributeSyntax: 2.5.5.12 isSingleValued: TRUE showInAdvancedViewOnly: TRUE adminDisplayName: ms-Exch-Default-Load-File adminDescription: ms-Exch-Default-Load-File oMSyntax: 64 searchFlags: 0 lDAPDisplayName: msExchDefaultLoadFile name: ms-Exch-Default-Load-File schemaIDGUID: 6267667c-cf34-407d-ba11-7cc8cc68ca1b isMemberOfPartialAttributeSet: FALSE objectCategory: CN=Attribute-Schema,${SCHEMADN} # # ms-Exch-Default-Logon-Domain # Specifies the default domain for logon. dn: CN=ms-Exch-Default-Logon-Domain,${SCHEMADN} objectClass: top objectClass: attributeSchema cn: ms-Exch-Default-Logon-Domain distinguishedName: CN=ms-Exch-Default-Logon-Domain,${SCHEMADN} attributeID: 1.2.840.113556.1.4.7000.102.15001 attributeSyntax: 2.5.5.12 isSingleValued: TRUE showInAdvancedViewOnly: TRUE adminDisplayName: ms-Exch-Default-Logon-Domain adminDescription: ms-Exch-Default-Logon-Domain oMSyntax: 64 searchFlags: 0 lDAPDisplayName: msExchDefaultLogonDomain name: ms-Exch-Default-Logon-Domain schemaIDGUID: 8bb46a46-b09e-11d2-aa06-00c04f8eedd8 isMemberOfPartialAttributeSet: FALSE objectCategory: CN=Attribute-Schema,${SCHEMADN} # # ms-Exch-Default-Message-Format # dn: CN=ms-Exch-Default-Message-Format,${SCHEMADN} objectClass: top objectClass: attributeSchema cn: ms-Exch-Default-Message-Format distinguishedName: CN=ms-Exch-Default-Message-Format,${SCHEMADN} attributeID: 1.2.840.113556.1.2.572 attributeSyntax: 2.5.5.8 isSingleValued: TRUE mAPIID: 35895 showInAdvancedViewOnly: TRUE adminDisplayName: ms-Exch-Default-Message-Format adminDescription: ms-Exch-Default-Message-Format oMSyntax: 1 searchFlags: 0 lDAPDisplayName: defaultMessageFormat name: ms-Exch-Default-Message-Format schemaIDGUID: a8df73bd-c5ea-11d1-bbcb-0080c76670c0 isMemberOfPartialAttributeSet: FALSE objectCategory: CN=Attribute-Schema,${SCHEMADN} # # ms-Exch-Delegate-User # dn: CN=ms-Exch-Delegate-User,${SCHEMADN} objectClass: top objectClass: attributeSchema cn: ms-Exch-Delegate-User distinguishedName: CN=ms-Exch-Delegate-User,${SCHEMADN} attributeID: 1.2.840.113556.1.2.591 attributeSyntax: 2.5.5.8 isSingleValued: TRUE mAPIID: 35913 showInAdvancedViewOnly: TRUE adminDisplayName: ms-Exch-Delegate-User adminDescription: ms-Exch-Delegate-User oMSyntax: 1 searchFlags: 0 lDAPDisplayName: delegateUser name: ms-Exch-Delegate-User schemaIDGUID: a8df73be-c5ea-11d1-bbcb-0080c76670c0 isMemberOfPartialAttributeSet: FALSE objectCategory: CN=Attribute-Schema,${SCHEMADN} # # ms-Exch-Deleted-Item-Flags # Controls deleted item retention settings. # dn: CN=ms-Exch-Deleted-Item-Flags,${SCHEMADN} objectClass: top objectClass: attributeSchema cn: ms-Exch-Deleted-Item-Flags distinguishedName: CN=ms-Exch-Deleted-Item-Flags,${SCHEMADN} attributeID: 1.2.840.113556.1.2.106 attributeSyntax: 2.5.5.9 isSingleValued: TRUE mAPIID: 32898 showInAdvancedViewOnly: TRUE adminDisplayName: ms-Exch-Deleted-Item-Flags adminDescription: ms-Exch-Deleted-Item-Flags oMSyntax: 2 searchFlags: 16 lDAPDisplayName: deletedItemFlags name: ms-Exch-Deleted-Item-Flags schemaIDGUID: 167757c7-47f3-11d1-a9c3-0000f80367c1 attributeSecurityGUID: e48d0154-bcf8-11d1-8702-00c04fb96050 isMemberOfPartialAttributeSet: TRUE objectCategory: CN=Attribute-Schema,${SCHEMADN} # # ms-Exch-Delivery-Mechanism # dn: CN=ms-Exch-Delivery-Mechanism,${SCHEMADN} objectClass: top objectClass: attributeSchema cn: ms-Exch-Delivery-Mechanism distinguishedName: CN=ms-Exch-Delivery-Mechanism,${SCHEMADN} attributeID: 1.2.840.113556.1.2.241 attributeSyntax: 2.5.5.9 isSingleValued: TRUE rangeLower: 0 rangeUpper: 3 mAPIID: 32878 showInAdvancedViewOnly: TRUE adminDisplayName: ms-Exch-Delivery-Mechanism adminDescription: ms-Exch-Delivery-Mechanism oMSyntax: 10 searchFlags: 0 lDAPDisplayName: deliveryMechanism name: ms-Exch-Delivery-Mechanism schemaIDGUID: bf96794e-0de6-11d0-a285-00aa003049e2 attributeSecurityGUID: e48d0154-bcf8-11d1-8702-00c04fb96050 isMemberOfPartialAttributeSet: TRUE objectCategory: CN=Attribute-Schema,${SCHEMADN} # # ms-Exch-Delivery-Order # Determines the order of processing messages in the connector's # queue. Options are: FIFO, Priority (default), and Size. # dn: CN=ms-Exch-Delivery-Order,${SCHEMADN} objectClass: top objectClass: attributeSchema cn: ms-Exch-Delivery-Order distinguishedName: CN=ms-Exch-Delivery-Order,${SCHEMADN} attributeID: 1.2.840.113556.1.4.7000.102.1003 attributeSyntax: 2.5.5.12 isSingleValued: TRUE showInAdvancedViewOnly: TRUE adminDisplayName: ms-Exch-Delivery-Order adminDescription: ms-Exch-Delivery-Order oMSyntax: 64 searchFlags: 0 lDAPDisplayName: msExchDeliveryOrder name: ms-Exch-Delivery-Order schemaIDGUID: 9d41e26c-b093-11d2-aa06-00c04f8eedd8 isMemberOfPartialAttributeSet: FALSE objectCategory: CN=Attribute-Schema,${SCHEMADN} # # ms-Exch-Deliver-And-Redirect # Used with ms-Exch-Alt-Recipient. If True, delivers to the mailbox and # also redirects. # dn: CN=ms-Exch-Deliver-And-Redirect,${SCHEMADN} objectClass: top objectClass: attributeSchema cn: ms-Exch-Deliver-And-Redirect distinguishedName: CN=ms-Exch-Deliver-And-Redirect,${SCHEMADN} attributeID: 1.2.840.113556.1.2.190 attributeSyntax: 2.5.5.8 isSingleValued: TRUE mAPIID: 32877 showInAdvancedViewOnly: TRUE adminDisplayName: ms-Exch-Deliver-And-Redirect adminDescription: ms-Exch-Deliver-And-Redirect oMSyntax: 1 searchFlags: 16 lDAPDisplayName: deliverAndRedirect name: ms-Exch-Deliver-And-Redirect schemaIDGUID: bf96794d-0de6-11d0-a285-00aa003049e2 attributeSecurityGUID: e48d0154-bcf8-11d1-8702-00c04fb96050 isMemberOfPartialAttributeSet: TRUE objectCategory: CN=Attribute-Schema,${SCHEMADN} # # ms-Exch-Deliv-Cont-Length # For recipients, the maximum message size, in kilobytes (KB), that # they can receive. For a connector, the maximum message size, in KB, # that can be sent over the connector. # dn: CN=ms-Exch-Deliv-Cont-Length,${SCHEMADN} objectClass: top objectClass: attributeSchema cn: ms-Exch-Deliv-Cont-Length distinguishedName: CN=ms-Exch-Deliv-Cont-Length,${SCHEMADN} attributeID: 1.2.840.113556.1.2.138 attributeSyntax: 2.5.5.9 isSingleValued: TRUE mAPIID: 32874 showInAdvancedViewOnly: TRUE adminDisplayName: ms-Exch-Deliv-Cont-Length adminDescription: ms-Exch-Deliv-Cont-Length oMSyntax: 2 searchFlags: 16 lDAPDisplayName: delivContLength name: ms-Exch-Deliv-Cont-Length schemaIDGUID: bf96794a-0de6-11d0-a285-00aa003049e2 attributeSecurityGUID: e48d0154-bcf8-11d1-8702-00c04fb96050 isMemberOfPartialAttributeSet: TRUE objectCategory: CN=Attribute-Schema,${SCHEMADN} # # ms-Exch-Deliv-EITs # dn: CN=ms-Exch-Deliv-EITs,${SCHEMADN} objectClass: top objectClass: attributeSchema cn: ms-Exch-Deliv-EITs distinguishedName: CN=ms-Exch-Deliv-EITs,${SCHEMADN} attributeID: 1.2.840.113556.1.2.139 attributeSyntax: 2.5.5.10 isSingleValued: FALSE rangeLower: 1 rangeUpper: 4096 mAPIID: 32875 showInAdvancedViewOnly: TRUE adminDisplayName: ms-Exch-Deliv-EITs adminDescription: ms-Exch-Deliv-EITs oMSyntax: 4 searchFlags: 0 lDAPDisplayName: delivEITs name: ms-Exch-Deliv-EITs schemaIDGUID: bf96794b-0de6-11d0-a285-00aa003049e2 isMemberOfPartialAttributeSet: FALSE objectCategory: CN=Attribute-Schema,${SCHEMADN} # # ms-Exch-Deliv-Ext-Cont-Types # dn: CN=ms-Exch-Deliv-Ext-Cont-Types,${SCHEMADN} objectClass: top objectClass: attributeSchema cn: ms-Exch-Deliv-Ext-Cont-Types distinguishedName: CN=ms-Exch-Deliv-Ext-Cont-Types,${SCHEMADN} attributeID: 1.2.840.113556.1.2.140 attributeSyntax: 2.5.5.10 isSingleValued: FALSE rangeLower: 1 rangeUpper: 4096 mAPIID: 32876 showInAdvancedViewOnly: TRUE adminDisplayName: ms-Exch-Deliv-Ext-Cont-Types adminDescription: ms-Exch-Deliv-Ext-Cont-Types oMSyntax: 4 searchFlags: 0 lDAPDisplayName: delivExtContTypes name: ms-Exch-Deliv-Ext-Cont-Types schemaIDGUID: bf96794c-0de6-11d0-a285-00aa003049e2 attributeSecurityGUID: e48d0154-bcf8-11d1-8702-00c04fb96050 isMemberOfPartialAttributeSet: TRUE objectCategory: CN=Attribute-Schema,${SCHEMADN} # # ms-Exch-Dereference-Aliases # Determines if x.500 aliases should be dereferenced. This is # applicable when replicating with x.500/LDAP directories that support # aliases. # dn: CN=ms-Exch-Dereference-Aliases,${SCHEMADN} objectClass: top objectClass: attributeSchema cn: ms-Exch-Dereference-Aliases distinguishedName: CN=ms-Exch-Dereference-Aliases,${SCHEMADN} attributeID: 1.2.840.113556.1.4.7000.102.2 attributeSyntax: 2.5.5.8 isSingleValued: TRUE showInAdvancedViewOnly: TRUE adminDisplayName: ms-Exch-Dereference-Aliases adminDescription: ms-Exch-Dereference-Aliases oMSyntax: 1 searchFlags: 0 lDAPDisplayName: msExchDereferenceAliases name: ms-Exch-Dereference-Aliases schemaIDGUID: 9d60e0fe-b093-11d2-aa06-00c04f8eedd8 isMemberOfPartialAttributeSet: FALSE objectCategory: CN=Attribute-Schema,${SCHEMADN} # # ms-Exch-Destination-RG-DN # The routing group (RG) on the other side of an Exchange Connector. # dn: CN=ms-Exch-Destination-RG-DN,${SCHEMADN} objectClass: top objectClass: attributeSchema cn: ms-Exch-Destination-RG-DN distinguishedName: CN=ms-Exch-Destination-RG-DN,${SCHEMADN} attributeID: 1.2.840.113556.1.4.7000.102.12507 attributeSyntax: 2.5.5.1 isSingleValued: TRUE showInAdvancedViewOnly: TRUE adminDisplayName: ms-Exch-Destination-RG-DN oMObjectClass:: KwwCh3McAIVK adminDescription: ms-Exch-Destination-RG-DN oMSyntax: 127 searchFlags: 0 lDAPDisplayName: msExchDestinationRGDN name: ms-Exch-Destination-RG-DN schemaIDGUID: 9d9ede22-b093-11d2-aa06-00c04f8eedd8 isMemberOfPartialAttributeSet: FALSE objectCategory: CN=Attribute-Schema,${SCHEMADN} # # ms-Exch-Dest-BH-Address # This attribute is obsolete. # dn: CN=ms-Exch-Dest-BH-Address,${SCHEMADN} objectClass: top objectClass: attributeSchema cn: ms-Exch-Dest-BH-Address distinguishedName: CN=ms-Exch-Dest-BH-Address,${SCHEMADN} attributeID: 1.2.840.113556.1.4.7000.102.12510 attributeSyntax: 2.5.5.4 isSingleValued: TRUE rangeLower: 0 rangeUpper: 255 showInAdvancedViewOnly: TRUE adminDisplayName: ms-Exch-Dest-BH-Address adminDescription: ms-Exch-Dest-BH-Address oMSyntax: 20 searchFlags: 0 lDAPDisplayName: msExchDestBHAddress name: ms-Exch-Dest-BH-Address schemaIDGUID: 9d8241ea-b093-11d2-aa06-00c04f8eedd8 isMemberOfPartialAttributeSet: FALSE objectCategory: CN=Attribute-Schema,${SCHEMADN} # # ms-Exch-Diagnostic-Reg-Key # The location of the diagnostic registry key. # dn: CN=ms-Exch-Diagnostic-Reg-Key,${SCHEMADN} objectClass: top objectClass: attributeSchema cn: ms-Exch-Diagnostic-Reg-Key distinguishedName: CN=ms-Exch-Diagnostic-Reg-Key,${SCHEMADN} attributeID: 1.2.840.113556.1.2.189 attributeSyntax: 2.5.5.12 isSingleValued: TRUE rangeLower: 1 rangeUpper: 256 mAPIID: 32881 showInAdvancedViewOnly: TRUE adminDisplayName: ms-Exch-Diagnostic-Reg-Key adminDescription: ms-Exch-Diagnostic-Reg-Key oMSyntax: 64 searchFlags: 0 lDAPDisplayName: diagnosticRegKey name: ms-Exch-Diagnostic-Reg-Key schemaIDGUID: bf967952-0de6-11d0-a285-00aa003049e2 isMemberOfPartialAttributeSet: FALSE objectCategory: CN=Attribute-Schema,${SCHEMADN} # # ms-Exch-Dirsync-Filters # A list of relational expressions that determine which directory # entries are propagated from Lotus Notes to Exchange during directory # synchronization. # dn: CN=ms-Exch-Dirsync-Filters,${SCHEMADN} objectClass: top objectClass: attributeSchema cn: ms-Exch-Dirsync-Filters distinguishedName: CN=ms-Exch-Dirsync-Filters,${SCHEMADN} attributeID: 1.2.840.113556.1.4.7000.102.1005 attributeSyntax: 2.5.5.12 isSingleValued: FALSE showInAdvancedViewOnly: TRUE adminDisplayName: ms-Exch-Dirsync-Filters adminDescription: ms-Exch-Dirsync-Filters oMSyntax: 64 searchFlags: 0 lDAPDisplayName: msExchDirsyncFilters name: ms-Exch-Dirsync-Filters schemaIDGUID: 9dbddcb4-b093-11d2-aa06-00c04f8eedd8 isMemberOfPartialAttributeSet: FALSE objectCategory: CN=Attribute-Schema,${SCHEMADN} # # ms-Exch-Dirsync-Schedule # dn: CN=ms-Exch-Dirsync-Schedule,${SCHEMADN} objectClass: top objectClass: attributeSchema cn: ms-Exch-Dirsync-Schedule distinguishedName: CN=ms-Exch-Dirsync-Schedule,${SCHEMADN} attributeID: 1.2.840.113556.1.4.7000.102.1008 attributeSyntax: 2.5.5.10 isSingleValued: TRUE rangeLower: 84 rangeUpper: 84 showInAdvancedViewOnly: TRUE adminDisplayName: ms-Exch-Dirsync-Schedule adminDescription: ms-Exch-Dirsync-Schedule oMSyntax: 4 searchFlags: 0 lDAPDisplayName: msExchDirsyncSchedule name: ms-Exch-Dirsync-Schedule schemaIDGUID: 8e11ff92-b09e-11d2-aa06-00c04f8eedd8 isMemberOfPartialAttributeSet: FALSE objectCategory: CN=Attribute-Schema,${SCHEMADN} # # ms-Exch-Dirsync-Style # dn: CN=ms-Exch-Dirsync-Style,${SCHEMADN} objectClass: top objectClass: attributeSchema cn: ms-Exch-Dirsync-Style distinguishedName: CN=ms-Exch-Dirsync-Style,${SCHEMADN} attributeID: 1.2.840.113556.1.4.7000.102.1009 attributeSyntax: 2.5.5.9 isSingleValued: TRUE rangeLower: 0 rangeUpper: 3 showInAdvancedViewOnly: TRUE adminDisplayName: ms-Exch-Dirsync-Style adminDescription: ms-Exch-Dirsync-Style oMSyntax: 2 searchFlags: 0 lDAPDisplayName: msExchDirsyncStyle name: ms-Exch-Dirsync-Style schemaIDGUID: 8e2e9bca-b09e-11d2-aa06-00c04f8eedd8 isMemberOfPartialAttributeSet: FALSE objectCategory: CN=Attribute-Schema,${SCHEMADN} # # ms-Exch-Dir-Browse-Flags # Contains the directory browsing flags. # dn: CN=ms-Exch-Dir-Browse-Flags,${SCHEMADN} objectClass: top objectClass: attributeSchema cn: ms-Exch-Dir-Browse-Flags distinguishedName: CN=ms-Exch-Dir-Browse-Flags,${SCHEMADN} attributeID: 1.2.840.113556.1.4.7000.102.15005 attributeSyntax: 2.5.5.9 isSingleValued: TRUE showInAdvancedViewOnly: TRUE adminDisplayName: ms-Exch-Dir-Browse-Flags adminDescription: ms-Exch-Dir-Browse-Flags oMSyntax: 2 searchFlags: 0 lDAPDisplayName: msExchDirBrowseFlags name: ms-Exch-Dir-Browse-Flags schemaIDGUID: 8c221672-b09e-11d2-aa06-00c04f8eedd8 isMemberOfPartialAttributeSet: FALSE objectCategory: CN=Attribute-Schema,${SCHEMADN} # # ms-Exch-Disabled-Gateway-Proxy # dn: CN=ms-Exch-Disabled-Gateway-Proxy,${SCHEMADN} objectClass: top objectClass: attributeSchema cn: ms-Exch-Disabled-Gateway-Proxy distinguishedName: CN=ms-Exch-Disabled-Gateway-Proxy,${SCHEMADN} attributeID: 1.2.840.113556.1.2.541 attributeSyntax: 2.5.5.12 isSingleValued: FALSE rangeLower: 0 rangeUpper: 1024 mAPIID: 33219 showInAdvancedViewOnly: TRUE adminDisplayName: ms-Exch-Disabled-Gateway-Proxy adminDescription: ms-Exch-Disabled-Gateway-Proxy oMSyntax: 64 searchFlags: 0 lDAPDisplayName: disabledGatewayProxy name: ms-Exch-Disabled-Gateway-Proxy schemaIDGUID: a8df73c0-c5ea-11d1-bbcb-0080c76670c0 isMemberOfPartialAttributeSet: FALSE objectCategory: CN=Attribute-Schema,${SCHEMADN} # # ms-Exch-Disable-UDG-Conversion # If set, this disables the conversion of universal distribution # groups to universal security groups. # dn: CN=ms-Exch-Disable-UDG-Conversion,${SCHEMADN} objectClass: top objectClass: attributeSchema cn: ms-Exch-Disable-UDG-Conversion distinguishedName: CN=ms-Exch-Disable-UDG-Conversion,${SCHEMADN} attributeID: 1.2.840.113556.1.4.7000.102.11088 attributeSyntax: 2.5.5.9 isSingleValued: TRUE showInAdvancedViewOnly: TRUE adminDisplayName: ms-Exch-Disable-UDG-Conversion adminDescription: ms-Exch-Disable-UDG-Conversion oMSyntax: 2 searchFlags: 0 lDAPDisplayName: msExchDisableUDGConversion name: ms-Exch-Disable-UDG-Conversion schemaIDGUID: 372d6cde-38c7-47b6-a3da-be4648124ec0 isMemberOfPartialAttributeSet: FALSE objectCategory: CN=Attribute-Schema,${SCHEMADN} # # ms-Exch-Discussion-Folder # dn: CN=ms-Exch-Discussion-Folder,${SCHEMADN} objectClass: top objectClass: attributeSchema cn: ms-Exch-Discussion-Folder distinguishedName: CN=ms-Exch-Discussion-Folder,${SCHEMADN} attributeID: 1.2.840.113556.1.4.7000.102.14002 attributeSyntax: 2.5.5.12 isSingleValued: TRUE showInAdvancedViewOnly: TRUE adminDisplayName: ms-Exch-Discussion-Folder adminDescription: ms-Exch-Discussion-Folder oMSyntax: 64 searchFlags: 0 lDAPDisplayName: msExchDiscussionFolder name: ms-Exch-Discussion-Folder schemaIDGUID: 3df30250-38a7-11d3-aa6e-00c04f8eedd8 isMemberOfPartialAttributeSet: FALSE objectCategory: CN=Attribute-Schema,${SCHEMADN} # # ms-Exch-DL-Member-Rule # This attribute is not used by Exchange. # dn: CN=ms-Exch-DL-Member-Rule,${SCHEMADN} objectClass: top objectClass: attributeSchema cn: ms-Exch-DL-Member-Rule distinguishedName: CN=ms-Exch-DL-Member-Rule,${SCHEMADN} attributeID: 1.2.840.113556.1.2.330 attributeSyntax: 2.5.5.10 isSingleValued: FALSE rangeLower: 1 rangeUpper: 4096 mAPIID: 32884 showInAdvancedViewOnly: TRUE adminDisplayName: ms-Exch-DL-Member-Rule adminDescription: ms-Exch-DL-Member-Rule oMSyntax: 4 searchFlags: 0 lDAPDisplayName: dLMemberRule name: ms-Exch-DL-Member-Rule schemaIDGUID: a8df73c6-c5ea-11d1-bbcb-0080c76670c0 attributeSecurityGUID: e48d0154-bcf8-11d1-8702-00c04fb96050 isMemberOfPartialAttributeSet: TRUE objectCategory: CN=Attribute-Schema,${SCHEMADN} # # ms-Exch-DL-Mem-Default # dn: CN=ms-Exch-DL-Mem-Default,${SCHEMADN} objectClass: top objectClass: attributeSchema cn: ms-Exch-DL-Mem-Default distinguishedName: CN=ms-Exch-DL-Mem-Default,${SCHEMADN} attributeID: 1.2.840.113556.1.4.7000.102.12527 attributeSyntax: 2.5.5.9 isSingleValued: TRUE showInAdvancedViewOnly: TRUE adminDisplayName: ms-Exch-DL-Mem-Default adminDescription: ms-Exch-DL-Mem-Default oMSyntax: 2 searchFlags: 0 lDAPDisplayName: dLMemDefault name: ms-Exch-DL-Mem-Default schemaIDGUID: 89d5319c-b09e-11d2-aa06-00c04f8eedd8 attributeSecurityGUID: e48d0154-bcf8-11d1-8702-00c04fb96050 isMemberOfPartialAttributeSet: TRUE objectCategory: CN=Attribute-Schema,${SCHEMADN} # # ms-Exch-DL-Mem-Reject-Perms # A distribution list (DL) whose members may not send to this # recipient or send messages over this connector. # dn: CN=ms-Exch-DL-Mem-Reject-Perms,${SCHEMADN} objectClass: top objectClass: attributeSchema cn: ms-Exch-DL-Mem-Reject-Perms distinguishedName: CN=ms-Exch-DL-Mem-Reject-Perms,${SCHEMADN} attributeID: 1.2.840.113556.1.2.47 attributeSyntax: 2.5.5.7 isSingleValued: FALSE linkID: 116 showInAdvancedViewOnly: TRUE adminDisplayName: ms-Exch-DL-Mem-Reject-Perms oMObjectClass:: VgYBAgULHQ== adminDescription: ms-Exch-DL-Mem-Reject-Perms oMSyntax: 127 searchFlags: 16 lDAPDisplayName: dLMemRejectPerms name: ms-Exch-DL-Mem-Reject-Perms schemaIDGUID: a8df73c2-c5ea-11d1-bbcb-0080c76670c0 attributeSecurityGUID: e48d0154-bcf8-11d1-8702-00c04fb96050 isMemberOfPartialAttributeSet: TRUE objectCategory: CN=Attribute-Schema,${SCHEMADN} # # ms-Exch-DL-Mem-Reject-Perms-BL # Backlink to ms-Exch-DL-Mem-Reject-Perms. # dn: CN=ms-Exch-DL-Mem-Reject-Perms-BL,${SCHEMADN} objectClass: top objectClass: attributeSchema cn: ms-Exch-DL-Mem-Reject-Perms-BL distinguishedName: CN=ms-Exch-DL-Mem-Reject-Perms-BL,${SCHEMADN} attributeID: 1.2.840.113556.1.2.293 attributeSyntax: 2.5.5.1 isSingleValued: FALSE mAPIID: 32882 linkID: 117 showInAdvancedViewOnly: TRUE adminDisplayName: ms-Exch-DL-Mem-Reject-Perms-BL oMObjectClass:: KwwCh3McAIVK adminDescription: ms-Exch-DL-Mem-Reject-Perms-BL oMSyntax: 127 searchFlags: 0 lDAPDisplayName: dLMemRejectPermsBL name: ms-Exch-DL-Mem-Reject-Perms-BL schemaIDGUID: a8df73c3-c5ea-11d1-bbcb-0080c76670c0 attributeSecurityGUID: e48d0154-bcf8-11d1-8702-00c04fb96050 systemFlags: 1 isMemberOfPartialAttributeSet: TRUE objectCategory: CN=Attribute-Schema,${SCHEMADN} # # ms-Exch-DL-Mem-Submit-Perms # A DL whose members may send to this recipient or send messages over # this connector. # dn: CN=ms-Exch-DL-Mem-Submit-Perms,${SCHEMADN} objectClass: top objectClass: attributeSchema cn: ms-Exch-DL-Mem-Submit-Perms distinguishedName: CN=ms-Exch-DL-Mem-Submit-Perms,${SCHEMADN} attributeID: 1.2.840.113556.1.2.144 attributeSyntax: 2.5.5.7 isSingleValued: FALSE linkID: 112 showInAdvancedViewOnly: TRUE adminDisplayName: ms-Exch-DL-Mem-Submit-Perms oMObjectClass:: VgYBAgULHQ== adminDescription: ms-Exch-DL-Mem-Submit-Perms oMSyntax: 127 searchFlags: 16 lDAPDisplayName: dLMemSubmitPerms name: ms-Exch-DL-Mem-Submit-Perms schemaIDGUID: a8df73c4-c5ea-11d1-bbcb-0080c76670c0 attributeSecurityGUID: e48d0154-bcf8-11d1-8702-00c04fb96050 isMemberOfPartialAttributeSet: TRUE objectCategory: CN=Attribute-Schema,${SCHEMADN} # # ms-Exch-DL-Mem-Submit-Perms-BL # Backlink to ms-Exch-DL-Mem-Submit-Perms. # dn: CN=ms-Exch-DL-Mem-Submit-Perms-BL,${SCHEMADN} objectClass: top objectClass: attributeSchema cn: ms-Exch-DL-Mem-Submit-Perms-BL distinguishedName: CN=ms-Exch-DL-Mem-Submit-Perms-BL,${SCHEMADN} attributeID: 1.2.840.113556.1.2.291 attributeSyntax: 2.5.5.1 isSingleValued: FALSE mAPIID: 32883 linkID: 113 showInAdvancedViewOnly: TRUE adminDisplayName: ms-Exch-DL-Mem-Submit-Perms-BL oMObjectClass:: KwwCh3McAIVK adminDescription: ms-Exch-DL-Mem-Submit-Perms-BL oMSyntax: 127 searchFlags: 0 lDAPDisplayName: dLMemSubmitPermsBL name: ms-Exch-DL-Mem-Submit-Perms-BL schemaIDGUID: a8df73c5-c5ea-11d1-bbcb-0080c76670c0 attributeSecurityGUID: e48d0154-bcf8-11d1-8702-00c04fb96050 systemFlags: 1 isMemberOfPartialAttributeSet: TRUE objectCategory: CN=Attribute-Schema,${SCHEMADN} # # ms-Exch-Domain-Def-Alt-Recip # dn: CN=ms-Exch-Domain-Def-Alt-Recip,${SCHEMADN} objectClass: top objectClass: attributeSchema cn: ms-Exch-Domain-Def-Alt-Recip distinguishedName: CN=ms-Exch-Domain-Def-Alt-Recip,${SCHEMADN} attributeID: 1.2.840.113556.1.2.145 attributeSyntax: 2.5.5.1 isSingleValued: TRUE mAPIID: 32885 showInAdvancedViewOnly: TRUE adminDisplayName: ms-Exch-Domain-Def-Alt-Recip oMObjectClass:: KwwCh3McAIVK adminDescription: ms-Exch-Domain-Def-Alt-Recip oMSyntax: 127 searchFlags: 0 lDAPDisplayName: domainDefAltRecip name: ms-Exch-Domain-Def-Alt-Recip schemaIDGUID: 167757bb-47f3-11d1-a9c3-0000f80367c1 isMemberOfPartialAttributeSet: FALSE objectCategory: CN=Attribute-Schema,${SCHEMADN} # # ms-Exch-Domain-Global-Group-Guid # Contains the stringized GUID of the domain local group within the # Recipient Update Service (RUS) domain. # dn: CN=ms-Exch-Domain-Global-Group-Guid,${SCHEMADN} objectClass: top objectClass: attributeSchema cn: ms-Exch-Domain-Global-Group-Guid distinguishedName: CN=ms-Exch-Domain-Global-Group-Guid,${SCHEMADN} attributeID: 1.2.840.113556.1.4.7000.102.50089 attributeSyntax: 2.5.5.12 isSingleValued: TRUE showInAdvancedViewOnly: TRUE adminDisplayName: ms-Exch-Domain-Global-Group-Guid adminDescription: ms-Exch-Domain-Global-Group-Guid oMSyntax: 64 searchFlags: 0 lDAPDisplayName: msExchDomainGlobalGroupGuid name: ms-Exch-Domain-Global-Group-Guid schemaIDGUID: 0d5aaba3-b593-4256-88dc-a0db2d2ffeec isMemberOfPartialAttributeSet: FALSE objectCategory: CN=Attribute-Schema,${SCHEMADN} # # ms-Exch-Domain-Global-Group-Sid # Contains the stringized security identifier (SID) of the domain # global group within the RUS domain. # dn: CN=ms-Exch-Domain-Global-Group-Sid,${SCHEMADN} objectClass: top objectClass: attributeSchema cn: ms-Exch-Domain-Global-Group-Sid distinguishedName: CN=ms-Exch-Domain-Global-Group-Sid,${SCHEMADN} attributeID: 1.2.840.113556.1.4.7000.102.50091 attributeSyntax: 2.5.5.12 isSingleValued: TRUE showInAdvancedViewOnly: TRUE adminDisplayName: ms-Exch-Domain-Global-Group-Sid adminDescription: ms-Exch-Domain-Global-Group-Sid oMSyntax: 64 searchFlags: 0 lDAPDisplayName: msExchDomainGlobalGroupSid name: ms-Exch-Domain-Global-Group-Sid schemaIDGUID: d059b789-3e9e-4b8f-befe-db62bb580885 isMemberOfPartialAttributeSet: FALSE objectCategory: CN=Attribute-Schema,${SCHEMADN} # # ms-Exch-Domain-Link # A link to the root of the domain. # dn: CN=ms-Exch-Domain-Link,${SCHEMADN} objectClass: top objectClass: attributeSchema cn: ms-Exch-Domain-Link distinguishedName: CN=ms-Exch-Domain-Link,${SCHEMADN} attributeID: 1.2.840.113556.1.4.7000.102.76 attributeSyntax: 2.5.5.1 isSingleValued: TRUE showInAdvancedViewOnly: TRUE adminDisplayName: ms-Exch-Domain-Link oMObjectClass:: KwwCh3McAIVK adminDescription: ms-Exch-Domain-Link oMSyntax: 127 searchFlags: 0 lDAPDisplayName: msExchDomainLink name: ms-Exch-Domain-Link schemaIDGUID: 8ac39cc4-b09e-11d2-aa06-00c04f8eedd8 isMemberOfPartialAttributeSet: FALSE objectCategory: CN=Attribute-Schema,${SCHEMADN} # # ms-Exch-Domain-Local-Group-Guid # Contains the stringized GUID of the domain local group within the RUS domain. # dn: CN=ms-Exch-Domain-Local-Group-Guid,${SCHEMADN} objectClass: top objectClass: attributeSchema cn: ms-Exch-Domain-Local-Group-Guid distinguishedName: CN=ms-Exch-Domain-Local-Group-Guid,${SCHEMADN} attributeID: 1.2.840.113556.1.4.7000.102.50088 attributeSyntax: 2.5.5.12 isSingleValued: TRUE showInAdvancedViewOnly: TRUE adminDisplayName: ms-Exch-Domain-Local-Group-Guid adminDescription: ms-Exch-Domain-Local-Group-Guid oMSyntax: 64 searchFlags: 0 lDAPDisplayName: msExchDomainLocalGroupGuid name: ms-Exch-Domain-Local-Group-Guid schemaIDGUID: 3bf8ffc0-6492-4af4-b2bf-4f9fdb423425 isMemberOfPartialAttributeSet: FALSE objectCategory: CN=Attribute-Schema,${SCHEMADN} # # ms-Exch-Domain-Local-Group-Sid # Contains the stringized SID of the domain local group within the RUS # domain. dn: CN=ms-Exch-Domain-Local-Group-Sid,${SCHEMADN} objectClass: top objectClass: attributeSchema cn: ms-Exch-Domain-Local-Group-Sid distinguishedName: CN=ms-Exch-Domain-Local-Group-Sid,${SCHEMADN} attributeID: 1.2.840.113556.1.4.7000.102.50090 attributeSyntax: 2.5.5.12 isSingleValued: TRUE showInAdvancedViewOnly: TRUE adminDisplayName: ms-Exch-Domain-Local-Group-Sid adminDescription: ms-Exch-Domain-Local-Group-Sid oMSyntax: 64 searchFlags: 0 lDAPDisplayName: msExchDomainLocalGroupSid name: ms-Exch-Domain-Local-Group-Sid schemaIDGUID: d27eb1e5-a06c-4151-b789-59eabba8edca isMemberOfPartialAttributeSet: FALSE objectCategory: CN=Attribute-Schema,${SCHEMADN} # # ms-Exch-Domain-Name # Stores the domain name that a Domain Content Configuration object # applies to. # dn: CN=ms-Exch-Domain-Name,${SCHEMADN} objectClass: top objectClass: attributeSchema cn: ms-Exch-Domain-Name distinguishedName: CN=ms-Exch-Domain-Name,${SCHEMADN} attributeID: 1.2.840.113556.1.2.147 attributeSyntax: 2.5.5.4 isSingleValued: TRUE rangeLower: 1 rangeUpper: 362 mAPIID: 32886 showInAdvancedViewOnly: TRUE adminDisplayName: ms-Exch-Domain-Name adminDescription: ms-Exch-Domain-Name oMSyntax: 20 searchFlags: 0 lDAPDisplayName: domainName name: ms-Exch-Domain-Name schemaIDGUID: a8df73c8-c5ea-11d1-bbcb-0080c76670c0 isMemberOfPartialAttributeSet: FALSE objectCategory: CN=Attribute-Schema,${SCHEMADN} # # ms-Exch-DownGrade-Multipart-Signed # If True, the store configures IMAIL to convert a multipart/signed # message to a normal message and discard the signature. The default # is False. # dn: CN=ms-Exch-DownGrade-Multipart-Signed,${SCHEMADN} objectClass: top objectClass: attributeSchema cn: ms-Exch-DownGrade-Multipart-Signed distinguishedName: CN=ms-Exch-DownGrade-Multipart-Signed,${SCHEMADN} attributeID: 1.2.840.113556.1.4.7000.102.11020 attributeSyntax: 2.5.5.8 isSingleValued: TRUE showInAdvancedViewOnly: TRUE adminDisplayName: ms-Exch-DownGrade-Multipart-Signed adminDescription: ms-Exch-DownGrade-Multipart-Signed oMSyntax: 1 searchFlags: 0 lDAPDisplayName: msExchDownGradeMultipartSigned name: ms-Exch-DownGrade-Multipart-Signed schemaIDGUID: 9e39d6fc-b093-11d2-aa06-00c04f8eedd8 isMemberOfPartialAttributeSet: FALSE objectCategory: CN=Attribute-Schema,${SCHEMADN} # # ms-Exch-Do-Full-Replication # A flag used to signal the service to do a full synchronization of # the directories. # dn: CN=ms-Exch-Do-Full-Replication,${SCHEMADN} objectClass: top objectClass: attributeSchema cn: ms-Exch-Do-Full-Replication distinguishedName: CN=ms-Exch-Do-Full-Replication,${SCHEMADN} attributeID: 1.2.840.113556.1.4.7000.102.38 attributeSyntax: 2.5.5.8 isSingleValued: TRUE showInAdvancedViewOnly: TRUE adminDisplayName: ms-Exch-Do-Full-Replication adminDescription: ms-Exch-Do-Full-Replication oMSyntax: 1 searchFlags: 0 lDAPDisplayName: msExchDoFullReplication name: ms-Exch-Do-Full-Replication schemaIDGUID: 9e1ad86a-b093-11d2-aa06-00c04f8eedd8 isMemberOfPartialAttributeSet: FALSE objectCategory: CN=Attribute-Schema,${SCHEMADN} # # ms-Exch-Do-OAB-Version # dn: CN=ms-Exch-Do-OAB-Version,${SCHEMADN} objectClass: top objectClass: attributeSchema cn: ms-Exch-Do-OAB-Version distinguishedName: CN=ms-Exch-Do-OAB-Version,${SCHEMADN} attributeID: 1.2.840.113556.1.2.575 attributeSyntax: 2.5.5.9 isSingleValued: TRUE mAPIID: 35898 showInAdvancedViewOnly: TRUE adminDisplayName: ms-Exch-Do-OAB-Version adminDescription: ms-Exch-Do-OAB-Version oMSyntax: 2 searchFlags: 0 lDAPDisplayName: doOABVersion name: ms-Exch-Do-OAB-Version schemaIDGUID: a8df73c7-c5ea-11d1-bbcb-0080c76670c0 isMemberOfPartialAttributeSet: FALSE objectCategory: CN=Attribute-Schema,${SCHEMADN} # # ms-Exch-DS2MB-Options # dn: CN=ms-Exch-DS2MB-Options,${SCHEMADN} objectClass: top objectClass: attributeSchema cn: ms-Exch-DS2MB-Options distinguishedName: CN=ms-Exch-DS2MB-Options,${SCHEMADN} attributeID: 1.2.840.113556.1.4.7000.102.14001 attributeSyntax: 2.5.5.9 isSingleValued: TRUE showInAdvancedViewOnly: TRUE adminDisplayName: ms-Exch-DS2MB-Options adminDescription: ms-Exch-DS2MB-Options oMSyntax: 2 searchFlags: 0 lDAPDisplayName: msExchDS2MBOptions name: ms-Exch-DS2MB-Options schemaIDGUID: 974c99da-33fc-11d3-aa6e-00c04f8eedd8 isMemberOfPartialAttributeSet: FALSE objectCategory: CN=Attribute-Schema,${SCHEMADN} # # ms-Exch-DXA-Admin-Copy # dn: CN=ms-Exch-DXA-Admin-Copy,${SCHEMADN} objectClass: top objectClass: attributeSchema cn: ms-Exch-DXA-Admin-Copy distinguishedName: CN=ms-Exch-DXA-Admin-Copy,${SCHEMADN} attributeID: 1.2.840.113556.1.2.378 attributeSyntax: 2.5.5.8 isSingleValued: TRUE mAPIID: 32888 showInAdvancedViewOnly: TRUE adminDisplayName: ms-Exch-DXA-Admin-Copy adminDescription: ms-Exch-DXA-Admin-Copy oMSyntax: 1 searchFlags: 0 lDAPDisplayName: dXAAdminCopy name: ms-Exch-DXA-Admin-Copy schemaIDGUID: a8df73c9-c5ea-11d1-bbcb-0080c76670c0 isMemberOfPartialAttributeSet: FALSE objectCategory: CN=Attribute-Schema,${SCHEMADN} # # ms-Exch-DXA-Admin-Forward # dn: CN=ms-Exch-DXA-Admin-Forward,${SCHEMADN} objectClass: top objectClass: attributeSchema cn: ms-Exch-DXA-Admin-Forward distinguishedName: CN=ms-Exch-DXA-Admin-Forward,${SCHEMADN} attributeID: 1.2.840.113556.1.2.379 attributeSyntax: 2.5.5.8 isSingleValued: TRUE mAPIID: 32889 showInAdvancedViewOnly: TRUE adminDisplayName: ms-Exch-DXA-Admin-Forward adminDescription: ms-Exch-DXA-Admin-Forward oMSyntax: 1 searchFlags: 0 lDAPDisplayName: dXAAdminForward name: ms-Exch-DXA-Admin-Forward schemaIDGUID: 167757be-47f3-11d1-a9c3-0000f80367c1 isMemberOfPartialAttributeSet: FALSE objectCategory: CN=Attribute-Schema,${SCHEMADN} # # ms-Exch-DXA-Admin-Update # dn: CN=ms-Exch-DXA-Admin-Update,${SCHEMADN} objectClass: top objectClass: attributeSchema cn: ms-Exch-DXA-Admin-Update distinguishedName: CN=ms-Exch-DXA-Admin-Update,${SCHEMADN} attributeID: 1.2.840.113556.1.2.381 attributeSyntax: 2.5.5.9 isSingleValued: TRUE mAPIID: 32890 showInAdvancedViewOnly: TRUE adminDisplayName: ms-Exch-DXA-Admin-Update adminDescription: ms-Exch-DXA-Admin-Update oMSyntax: 2 searchFlags: 0 lDAPDisplayName: dXAAdminUpdate name: ms-Exch-DXA-Admin-Update schemaIDGUID: a8df73ca-c5ea-11d1-bbcb-0080c76670c0 isMemberOfPartialAttributeSet: FALSE objectCategory: CN=Attribute-Schema,${SCHEMADN} # # ms-Exch-DXA-Append-ReqCN # dn: CN=ms-Exch-DXA-Append-ReqCN,${SCHEMADN} objectClass: top objectClass: attributeSchema cn: ms-Exch-DXA-Append-ReqCN distinguishedName: CN=ms-Exch-DXA-Append-ReqCN,${SCHEMADN} attributeID: 1.2.840.113556.1.2.174 attributeSyntax: 2.5.5.8 isSingleValued: TRUE mAPIID: 32891 showInAdvancedViewOnly: TRUE adminDisplayName: ms-Exch-DXA-Append-ReqCN adminDescription: ms-Exch-DXA-Append-ReqCN oMSyntax: 1 searchFlags: 0 lDAPDisplayName: dXAAppendReqCN name: ms-Exch-DXA-Append-ReqCN schemaIDGUID: a8df73cb-c5ea-11d1-bbcb-0080c76670c0 isMemberOfPartialAttributeSet: FALSE objectCategory: CN=Attribute-Schema,${SCHEMADN} # # ms-Exch-DXA-Conf-Container-List # dn: CN=ms-Exch-DXA-Conf-Container-List,${SCHEMADN} objectClass: top objectClass: attributeSchema cn: ms-Exch-DXA-Conf-Container-List distinguishedName: CN=ms-Exch-DXA-Conf-Container-List,${SCHEMADN} attributeID: 1.2.840.113556.1.2.180 attributeSyntax: 2.5.5.1 isSingleValued: FALSE mAPIID: 32892 showInAdvancedViewOnly: TRUE adminDisplayName: ms-Exch-DXA-Conf-Container-List oMObjectClass:: KwwCh3McAIVK adminDescription: ms-Exch-DXA-Conf-Container-List oMSyntax: 127 searchFlags: 0 lDAPDisplayName: dXAConfContainerList name: ms-Exch-DXA-Conf-Container-List schemaIDGUID: a8df73cc-c5ea-11d1-bbcb-0080c76670c0 isMemberOfPartialAttributeSet: FALSE objectCategory: CN=Attribute-Schema,${SCHEMADN} # # ms-Exch-DXA-Conf-Req-Time # dn: CN=ms-Exch-DXA-Conf-Req-Time,${SCHEMADN} objectClass: top objectClass: attributeSchema cn: ms-Exch-DXA-Conf-Req-Time distinguishedName: CN=ms-Exch-DXA-Conf-Req-Time,${SCHEMADN} attributeID: 1.2.840.113556.1.2.122 attributeSyntax: 2.5.5.11 isSingleValued: TRUE mAPIID: 32893 showInAdvancedViewOnly: TRUE adminDisplayName: ms-Exch-DXA-Conf-Req-Time adminDescription: ms-Exch-DXA-Conf-Req-Time oMSyntax: 23 searchFlags: 0 lDAPDisplayName: dXAConfReqTime name: ms-Exch-DXA-Conf-Req-Time schemaIDGUID: a8df73cd-c5ea-11d1-bbcb-0080c76670c0 isMemberOfPartialAttributeSet: FALSE objectCategory: CN=Attribute-Schema,${SCHEMADN} # # ms-Exch-DXA-Conf-Seq # dn: CN=ms-Exch-DXA-Conf-Seq,${SCHEMADN} objectClass: top objectClass: attributeSchema cn: ms-Exch-DXA-Conf-Seq distinguishedName: CN=ms-Exch-DXA-Conf-Seq,${SCHEMADN} attributeID: 1.2.840.113556.1.2.184 attributeSyntax: 2.5.5.5 isSingleValued: TRUE rangeLower: 1 rangeUpper: 32 mAPIID: 32894 showInAdvancedViewOnly: TRUE adminDisplayName: ms-Exch-DXA-Conf-Seq adminDescription: ms-Exch-DXA-Conf-Seq oMSyntax: 19 searchFlags: 0 lDAPDisplayName: dXAConfSeq name: ms-Exch-DXA-Conf-Seq schemaIDGUID: a8df73ce-c5ea-11d1-bbcb-0080c76670c0 isMemberOfPartialAttributeSet: FALSE objectCategory: CN=Attribute-Schema,${SCHEMADN} # # ms-Exch-DXA-Conf-Seq-USN # dn: CN=ms-Exch-DXA-Conf-Seq-USN,${SCHEMADN} objectClass: top objectClass: attributeSchema cn: ms-Exch-DXA-Conf-Seq-USN distinguishedName: CN=ms-Exch-DXA-Conf-Seq-USN,${SCHEMADN} attributeID: 1.2.840.113556.1.2.45 attributeSyntax: 2.5.5.9 isSingleValued: TRUE mAPIID: 32895 showInAdvancedViewOnly: TRUE adminDisplayName: ms-Exch-DXA-Conf-Seq-USN adminDescription: ms-Exch-DXA-Conf-Seq-USN oMSyntax: 2 searchFlags: 0 lDAPDisplayName: dXAConfSeqUSN name: ms-Exch-DXA-Conf-Seq-USN schemaIDGUID: a8df73cf-c5ea-11d1-bbcb-0080c76670c0 isMemberOfPartialAttributeSet: FALSE objectCategory: CN=Attribute-Schema,${SCHEMADN} # # ms-Exch-DXA-Exchange-Options # dn: CN=ms-Exch-DXA-Exchange-Options,${SCHEMADN} objectClass: top objectClass: attributeSchema cn: ms-Exch-DXA-Exchange-Options distinguishedName: CN=ms-Exch-DXA-Exchange-Options,${SCHEMADN} attributeID: 1.2.840.113556.1.2.359 attributeSyntax: 2.5.5.9 isSingleValued: TRUE rangeLower: 0 rangeUpper: 3 mAPIID: 32896 showInAdvancedViewOnly: TRUE adminDisplayName: ms-Exch-DXA-Exchange-Options adminDescription: ms-Exch-DXA-Exchange-Options oMSyntax: 10 searchFlags: 0 lDAPDisplayName: dXAExchangeOptions name: ms-Exch-DXA-Exchange-Options schemaIDGUID: a8df73d0-c5ea-11d1-bbcb-0080c76670c0 isMemberOfPartialAttributeSet: FALSE objectCategory: CN=Attribute-Schema,${SCHEMADN} # # ms-Exch-DXA-Export-Now # dn: CN=ms-Exch-DXA-Export-Now,${SCHEMADN} objectClass: top objectClass: attributeSchema cn: ms-Exch-DXA-Export-Now distinguishedName: CN=ms-Exch-DXA-Export-Now,${SCHEMADN} attributeID: 1.2.840.113556.1.2.377 attributeSyntax: 2.5.5.8 isSingleValued: TRUE mAPIID: 32897 showInAdvancedViewOnly: TRUE adminDisplayName: ms-Exch-DXA-Export-Now adminDescription: ms-Exch-DXA-Export-Now oMSyntax: 1 searchFlags: 0 lDAPDisplayName: dXAExportNow name: ms-Exch-DXA-Export-Now schemaIDGUID: a8df73d1-c5ea-11d1-bbcb-0080c76670c0 isMemberOfPartialAttributeSet: FALSE objectCategory: CN=Attribute-Schema,${SCHEMADN} # # ms-Exch-DXA-Import-Now # dn: CN=ms-Exch-DXA-Import-Now,${SCHEMADN} objectClass: top objectClass: attributeSchema cn: ms-Exch-DXA-Import-Now distinguishedName: CN=ms-Exch-DXA-Import-Now,${SCHEMADN} attributeID: 1.2.840.113556.1.2.376 attributeSyntax: 2.5.5.8 isSingleValued: TRUE mAPIID: 32902 showInAdvancedViewOnly: TRUE adminDisplayName: ms-Exch-DXA-Import-Now adminDescription: ms-Exch-DXA-Import-Now oMSyntax: 1 searchFlags: 0 lDAPDisplayName: dXAImportNow name: ms-Exch-DXA-Import-Now schemaIDGUID: a8df73d5-c5ea-11d1-bbcb-0080c76670c0 isMemberOfPartialAttributeSet: FALSE objectCategory: CN=Attribute-Schema,${SCHEMADN} # # ms-Exch-DXA-Imp-Seq # dn: CN=ms-Exch-DXA-Imp-Seq,${SCHEMADN} objectClass: top objectClass: attributeSchema cn: ms-Exch-DXA-Imp-Seq distinguishedName: CN=ms-Exch-DXA-Imp-Seq,${SCHEMADN} attributeID: 1.2.840.113556.1.2.116 attributeSyntax: 2.5.5.5 isSingleValued: TRUE rangeLower: 1 rangeUpper: 32 mAPIID: 32899 showInAdvancedViewOnly: TRUE adminDisplayName: ms-Exch-DXA-Imp-Seq adminDescription: ms-Exch-DXA-Imp-Seq oMSyntax: 19 searchFlags: 0 lDAPDisplayName: dXAImpSeq name: ms-Exch-DXA-Imp-Seq schemaIDGUID: a8df73d2-c5ea-11d1-bbcb-0080c76670c0 isMemberOfPartialAttributeSet: FALSE objectCategory: CN=Attribute-Schema,${SCHEMADN} # # ms-Exch-DXA-Imp-Seq-Time # dn: CN=ms-Exch-DXA-Imp-Seq-Time,${SCHEMADN} objectClass: top objectClass: attributeSchema cn: ms-Exch-DXA-Imp-Seq-Time distinguishedName: CN=ms-Exch-DXA-Imp-Seq-Time,${SCHEMADN} attributeID: 1.2.840.113556.1.2.117 attributeSyntax: 2.5.5.11 isSingleValued: TRUE mAPIID: 32900 showInAdvancedViewOnly: TRUE adminDisplayName: ms-Exch-DXA-Imp-Seq-Time adminDescription: ms-Exch-DXA-Imp-Seq-Time oMSyntax: 23 searchFlags: 0 lDAPDisplayName: dXAImpSeqTime name: ms-Exch-DXA-Imp-Seq-Time schemaIDGUID: a8df73d3-c5ea-11d1-bbcb-0080c76670c0 isMemberOfPartialAttributeSet: FALSE objectCategory: CN=Attribute-Schema,${SCHEMADN} # # ms-Exch-DXA-Imp-Seq-USN # dn: CN=ms-Exch-DXA-Imp-Seq-USN,${SCHEMADN} objectClass: top objectClass: attributeSchema cn: ms-Exch-DXA-Imp-Seq-USN distinguishedName: CN=ms-Exch-DXA-Imp-Seq-USN,${SCHEMADN} attributeID: 1.2.840.113556.1.2.86 attributeSyntax: 2.5.5.9 isSingleValued: TRUE mAPIID: 32901 showInAdvancedViewOnly: TRUE adminDisplayName: ms-Exch-DXA-Imp-Seq-USN adminDescription: ms-Exch-DXA-Imp-Seq-USN oMSyntax: 2 searchFlags: 0 lDAPDisplayName: dXAImpSeqUSN name: ms-Exch-DXA-Imp-Seq-USN schemaIDGUID: a8df73d4-c5ea-11d1-bbcb-0080c76670c0 isMemberOfPartialAttributeSet: FALSE objectCategory: CN=Attribute-Schema,${SCHEMADN} # # ms-Exch-DXA-In-Template-Map # dn: CN=ms-Exch-DXA-In-Template-Map,${SCHEMADN} objectClass: top objectClass: attributeSchema cn: ms-Exch-DXA-In-Template-Map distinguishedName: CN=ms-Exch-DXA-In-Template-Map,${SCHEMADN} attributeID: 1.2.840.113556.1.2.363 attributeSyntax: 2.5.5.12 isSingleValued: FALSE rangeLower: 1 rangeUpper: 128 mAPIID: 32903 showInAdvancedViewOnly: TRUE adminDisplayName: ms-Exch-DXA-In-Template-Map adminDescription: ms-Exch-DXA-In-Template-Map oMSyntax: 64 searchFlags: 0 lDAPDisplayName: dXAInTemplateMap name: ms-Exch-DXA-In-Template-Map schemaIDGUID: a8df73d6-c5ea-11d1-bbcb-0080c76670c0 isMemberOfPartialAttributeSet: FALSE objectCategory: CN=Attribute-Schema,${SCHEMADN} # # ms-Exch-DXA-Local-Admin # dn: CN=ms-Exch-DXA-Local-Admin,${SCHEMADN} objectClass: top objectClass: attributeSchema cn: ms-Exch-DXA-Local-Admin distinguishedName: CN=ms-Exch-DXA-Local-Admin,${SCHEMADN} attributeID: 1.2.840.113556.1.2.113 attributeSyntax: 2.5.5.1 isSingleValued: TRUE mAPIID: 32904 showInAdvancedViewOnly: TRUE adminDisplayName: ms-Exch-DXA-Local-Admin oMObjectClass:: KwwCh3McAIVK adminDescription: ms-Exch-DXA-Local-Admin oMSyntax: 127 searchFlags: 0 lDAPDisplayName: dXALocalAdmin name: ms-Exch-DXA-Local-Admin schemaIDGUID: a8df73d7-c5ea-11d1-bbcb-0080c76670c0 isMemberOfPartialAttributeSet: FALSE objectCategory: CN=Attribute-Schema,${SCHEMADN} # # ms-Exch-DXA-Native-Address-Type # dn: CN=ms-Exch-DXA-Native-Address-Type,${SCHEMADN} objectClass: top objectClass: attributeSchema cn: ms-Exch-DXA-Native-Address-Type distinguishedName: CN=ms-Exch-DXA-Native-Address-Type,${SCHEMADN} attributeID: 1.2.840.113556.1.2.331 attributeSyntax: 2.5.5.5 isSingleValued: TRUE rangeLower: 1 rangeUpper: 32 mAPIID: 32906 showInAdvancedViewOnly: TRUE adminDisplayName: ms-Exch-DXA-Native-Address-Type adminDescription: ms-Exch-DXA-Native-Address-Type oMSyntax: 19 searchFlags: 0 lDAPDisplayName: dXANativeAddressType name: ms-Exch-DXA-Native-Address-Type schemaIDGUID: a8df73d9-c5ea-11d1-bbcb-0080c76670c0 isMemberOfPartialAttributeSet: FALSE objectCategory: CN=Attribute-Schema,${SCHEMADN} # # ms-Exch-DXA-Out-Template-Map # dn: CN=ms-Exch-DXA-Out-Template-Map,${SCHEMADN} objectClass: top objectClass: attributeSchema cn: ms-Exch-DXA-Out-Template-Map distinguishedName: CN=ms-Exch-DXA-Out-Template-Map,${SCHEMADN} attributeID: 1.2.840.113556.1.2.364 attributeSyntax: 2.5.5.12 isSingleValued: FALSE rangeLower: 1 rangeUpper: 128 mAPIID: 32907 showInAdvancedViewOnly: TRUE adminDisplayName: ms-Exch-DXA-Out-Template-Map adminDescription: ms-Exch-DXA-Out-Template-Map oMSyntax: 64 searchFlags: 0 lDAPDisplayName: dXAOutTemplateMap name: ms-Exch-DXA-Out-Template-Map schemaIDGUID: a8df73da-c5ea-11d1-bbcb-0080c76670c0 isMemberOfPartialAttributeSet: FALSE objectCategory: CN=Attribute-Schema,${SCHEMADN} # # ms-Exch-DXA-Password # dn: CN=ms-Exch-DXA-Password,${SCHEMADN} objectClass: top objectClass: attributeSchema cn: ms-Exch-DXA-Password distinguishedName: CN=ms-Exch-DXA-Password,${SCHEMADN} attributeID: 1.2.840.113556.1.2.305 attributeSyntax: 2.5.5.12 isSingleValued: TRUE rangeLower: 1 rangeUpper: 12 mAPIID: 32908 showInAdvancedViewOnly: TRUE adminDisplayName: ms-Exch-DXA-Password adminDescription: ms-Exch-DXA-Password oMSyntax: 64 searchFlags: 0 lDAPDisplayName: dXAPassword name: ms-Exch-DXA-Password schemaIDGUID: a8df73db-c5ea-11d1-bbcb-0080c76670c0 isMemberOfPartialAttributeSet: FALSE objectCategory: CN=Attribute-Schema,${SCHEMADN} # # ms-Exch-DXA-Prev-Exchange-Options # dn: CN=ms-Exch-DXA-Prev-Exchange-Options,${SCHEMADN} objectClass: top objectClass: attributeSchema cn: ms-Exch-DXA-Prev-Exchange-Options distinguishedName: CN=ms-Exch-DXA-Prev-Exchange-Options,${SCHEMADN} attributeID: 1.2.840.113556.1.2.216 attributeSyntax: 2.5.5.9 isSingleValued: TRUE rangeLower: 0 rangeUpper: 3 mAPIID: 32909 showInAdvancedViewOnly: TRUE adminDisplayName: ms-Exch-DXA-Prev-Exchange-Options adminDescription: ms-Exch-DXA-Prev-Exchange-Options oMSyntax: 10 searchFlags: 0 lDAPDisplayName: dXAPrevExchangeOptions name: ms-Exch-DXA-Prev-Exchange-Options schemaIDGUID: a8df73dc-c5ea-11d1-bbcb-0080c76670c0 isMemberOfPartialAttributeSet: FALSE objectCategory: CN=Attribute-Schema,${SCHEMADN} # # ms-Exch-DXA-Prev-Export-Native-Only # dn: CN=ms-Exch-DXA-Prev-Export-Native-Only,${SCHEMADN} objectClass: top objectClass: attributeSchema cn: ms-Exch-DXA-Prev-Export-Native-Only distinguishedName: CN=ms-Exch-DXA-Prev-Export-Native-Only,${SCHEMADN} attributeID: 1.2.840.113556.1.2.203 attributeSyntax: 2.5.5.8 isSingleValued: TRUE mAPIID: 32910 showInAdvancedViewOnly: TRUE adminDisplayName: ms-Exch-DXA-Prev-Export-Native-Only adminDescription: ms-Exch-DXA-Prev-Export-Native-Only oMSyntax: 1 searchFlags: 0 lDAPDisplayName: dXAPrevExportNativeOnly name: ms-Exch-DXA-Prev-Export-Native-Only schemaIDGUID: a8df73dd-c5ea-11d1-bbcb-0080c76670c0 isMemberOfPartialAttributeSet: FALSE objectCategory: CN=Attribute-Schema,${SCHEMADN} # # ms-Exch-DXA-Prev-In-Exchange-Sensitivity # dn: CN=ms-Exch-DXA-Prev-In-Exchange-Sensitivity,${SCHEMADN} objectClass: top objectClass: attributeSchema cn: ms-Exch-DXA-Prev-In-Exchange-Sensitivity distinguishedName: CN=ms-Exch-DXA-Prev-In-Exchange-Sensitivity,${SCHEMADN} attributeID: 1.2.840.113556.1.2.90 attributeSyntax: 2.5.5.9 isSingleValued: TRUE mAPIID: 32911 showInAdvancedViewOnly: TRUE adminDisplayName: ms-Exch-DXA-Prev-In-Exchange-Sensitivity adminDescription: ms-Exch-DXA-Prev-In-Exchange-Sensitivity oMSyntax: 2 searchFlags: 0 lDAPDisplayName: dXAPrevInExchangeSensitivity name: ms-Exch-DXA-Prev-In-Exchange-Sensitivity schemaIDGUID: a8df73de-c5ea-11d1-bbcb-0080c76670c0 isMemberOfPartialAttributeSet: FALSE objectCategory: CN=Attribute-Schema,${SCHEMADN} # # ms-Exch-DXA-Prev-Remote-Entries # dn: CN=ms-Exch-DXA-Prev-Remote-Entries,${SCHEMADN} objectClass: top objectClass: attributeSchema cn: ms-Exch-DXA-Prev-Remote-Entries distinguishedName: CN=ms-Exch-DXA-Prev-Remote-Entries,${SCHEMADN} attributeID: 1.2.840.113556.1.2.265 attributeSyntax: 2.5.5.1 isSingleValued: TRUE mAPIID: 32912 showInAdvancedViewOnly: TRUE adminDisplayName: ms-Exch-DXA-Prev-Remote-Entries oMObjectClass:: KwwCh3McAIVK adminDescription: ms-Exch-DXA-Prev-Remote-Entries oMSyntax: 127 searchFlags: 0 lDAPDisplayName: dXAPrevRemoteEntries name: ms-Exch-DXA-Prev-Remote-Entries schemaIDGUID: a8df73df-c5ea-11d1-bbcb-0080c76670c0 isMemberOfPartialAttributeSet: FALSE objectCategory: CN=Attribute-Schema,${SCHEMADN} # # ms-Exch-DXA-Prev-Replication-Sensitivity # dn: CN=ms-Exch-DXA-Prev-Replication-Sensitivity,${SCHEMADN} objectClass: top objectClass: attributeSchema cn: ms-Exch-DXA-Prev-Replication-Sensitivity distinguishedName: CN=ms-Exch-DXA-Prev-Replication-Sensitivity,${SCHEMADN} attributeID: 1.2.840.113556.1.2.215 attributeSyntax: 2.5.5.9 isSingleValued: TRUE mAPIID: 32913 showInAdvancedViewOnly: TRUE adminDisplayName: ms-Exch-DXA-Prev-Replication-Sensitivity adminDescription: ms-Exch-DXA-Prev-Replication-Sensitivity oMSyntax: 2 searchFlags: 0 lDAPDisplayName: dXAPrevReplicationSensitivity name: ms-Exch-DXA-Prev-Replication-Sensitivity schemaIDGUID: a8df73e0-c5ea-11d1-bbcb-0080c76670c0 isMemberOfPartialAttributeSet: FALSE objectCategory: CN=Attribute-Schema,${SCHEMADN} # # ms-Exch-DXA-Prev-Template-Options # dn: CN=ms-Exch-DXA-Prev-Template-Options,${SCHEMADN} objectClass: top objectClass: attributeSchema cn: ms-Exch-DXA-Prev-Template-Options distinguishedName: CN=ms-Exch-DXA-Prev-Template-Options,${SCHEMADN} attributeID: 1.2.840.113556.1.2.395 attributeSyntax: 2.5.5.9 isSingleValued: TRUE rangeLower: 0 rangeUpper: 3 mAPIID: 32914 showInAdvancedViewOnly: TRUE adminDisplayName: ms-Exch-DXA-Prev-Template-Options adminDescription: ms-Exch-DXA-Prev-Template-Options oMSyntax: 10 searchFlags: 0 lDAPDisplayName: dXAPrevTemplateOptions name: ms-Exch-DXA-Prev-Template-Options schemaIDGUID: a8df73e1-c5ea-11d1-bbcb-0080c76670c0 isMemberOfPartialAttributeSet: FALSE objectCategory: CN=Attribute-Schema,${SCHEMADN} # # ms-Exch-DXA-Prev-Types # dn: CN=ms-Exch-DXA-Prev-Types,${SCHEMADN} objectClass: top objectClass: attributeSchema cn: ms-Exch-DXA-Prev-Types distinguishedName: CN=ms-Exch-DXA-Prev-Types,${SCHEMADN} attributeID: 1.2.840.113556.1.2.217 attributeSyntax: 2.5.5.9 isSingleValued: TRUE mAPIID: 32915 showInAdvancedViewOnly: TRUE adminDisplayName: ms-Exch-DXA-Prev-Types adminDescription: ms-Exch-DXA-Prev-Types oMSyntax: 2 searchFlags: 0 lDAPDisplayName: dXAPrevTypes name: ms-Exch-DXA-Prev-Types schemaIDGUID: 167757d8-47f3-11d1-a9c3-0000f80367c1 isMemberOfPartialAttributeSet: FALSE objectCategory: CN=Attribute-Schema,${SCHEMADN} # # ms-Exch-DXA-Recipient-CP # dn: CN=ms-Exch-DXA-Recipient-CP,${SCHEMADN} objectClass: top objectClass: attributeSchema cn: ms-Exch-DXA-Recipient-CP distinguishedName: CN=ms-Exch-DXA-Recipient-CP,${SCHEMADN} attributeID: 1.2.840.113556.1.2.384 attributeSyntax: 2.5.5.12 isSingleValued: TRUE rangeLower: 1 rangeUpper: 24 mAPIID: 32916 showInAdvancedViewOnly: TRUE adminDisplayName: ms-Exch-DXA-Recipient-CP adminDescription: ms-Exch-DXA-Recipient-CP oMSyntax: 64 searchFlags: 0 lDAPDisplayName: dXARecipientCP name: ms-Exch-DXA-Recipient-CP schemaIDGUID: a8df73e2-c5ea-11d1-bbcb-0080c76670c0 isMemberOfPartialAttributeSet: FALSE objectCategory: CN=Attribute-Schema,${SCHEMADN} # # ms-Exch-DXA-Remote-Client # dn: CN=ms-Exch-DXA-Remote-Client,${SCHEMADN} objectClass: top objectClass: attributeSchema cn: ms-Exch-DXA-Remote-Client distinguishedName: CN=ms-Exch-DXA-Remote-Client,${SCHEMADN} attributeID: 1.2.840.113556.1.2.112 attributeSyntax: 2.5.5.1 isSingleValued: TRUE mAPIID: 32917 showInAdvancedViewOnly: TRUE adminDisplayName: ms-Exch-DXA-Remote-Client oMObjectClass:: KwwCh3McAIVK adminDescription: ms-Exch-DXA-Remote-Client oMSyntax: 127 searchFlags: 0 lDAPDisplayName: dXARemoteClient name: ms-Exch-DXA-Remote-Client schemaIDGUID: a8df73e3-c5ea-11d1-bbcb-0080c76670c0 isMemberOfPartialAttributeSet: FALSE objectCategory: CN=Attribute-Schema,${SCHEMADN} # # ms-Exch-DXA-ReqName # dn: CN=ms-Exch-DXA-ReqName,${SCHEMADN} objectClass: top objectClass: attributeSchema cn: ms-Exch-DXA-ReqName distinguishedName: CN=ms-Exch-DXA-ReqName,${SCHEMADN} attributeID: 1.2.840.113556.1.2.446 attributeSyntax: 2.5.5.12 isSingleValued: TRUE rangeLower: 1 rangeUpper: 64 mAPIID: 32921 showInAdvancedViewOnly: TRUE adminDisplayName: ms-Exch-DXA-ReqName adminDescription: ms-Exch-DXA-ReqName oMSyntax: 64 searchFlags: 0 lDAPDisplayName: dXAReqName name: ms-Exch-DXA-ReqName schemaIDGUID: a8df73e7-c5ea-11d1-bbcb-0080c76670c0 isMemberOfPartialAttributeSet: FALSE objectCategory: CN=Attribute-Schema,${SCHEMADN} # # ms-Exch-DXA-Req-Seq # dn: CN=ms-Exch-DXA-Req-Seq,${SCHEMADN} objectClass: top objectClass: attributeSchema cn: ms-Exch-DXA-Req-Seq distinguishedName: CN=ms-Exch-DXA-Req-Seq,${SCHEMADN} attributeID: 1.2.840.113556.1.2.101 attributeSyntax: 2.5.5.5 isSingleValued: TRUE rangeLower: 1 rangeUpper: 32 mAPIID: 32918 showInAdvancedViewOnly: TRUE adminDisplayName: ms-Exch-DXA-Req-Seq adminDescription: ms-Exch-DXA-Req-Seq oMSyntax: 19 searchFlags: 0 lDAPDisplayName: dXAReqSeq name: ms-Exch-DXA-Req-Seq schemaIDGUID: a8df73e4-c5ea-11d1-bbcb-0080c76670c0 isMemberOfPartialAttributeSet: FALSE objectCategory: CN=Attribute-Schema,${SCHEMADN} # # ms-Exch-DXA-Req-Seq-Time # dn: CN=ms-Exch-DXA-Req-Seq-Time,${SCHEMADN} objectClass: top objectClass: attributeSchema cn: ms-Exch-DXA-Req-Seq-Time distinguishedName: CN=ms-Exch-DXA-Req-Seq-Time,${SCHEMADN} attributeID: 1.2.840.113556.1.2.114 attributeSyntax: 2.5.5.11 isSingleValued: TRUE mAPIID: 32919 showInAdvancedViewOnly: TRUE adminDisplayName: ms-Exch-DXA-Req-Seq-Time adminDescription: ms-Exch-DXA-Req-Seq-Time oMSyntax: 23 searchFlags: 0 lDAPDisplayName: dXAReqSeqTime name: ms-Exch-DXA-Req-Seq-Time schemaIDGUID: a8df73e5-c5ea-11d1-bbcb-0080c76670c0 isMemberOfPartialAttributeSet: FALSE objectCategory: CN=Attribute-Schema,${SCHEMADN} # # ms-Exch-DXA-Req-Seq-USN # dn: CN=ms-Exch-DXA-Req-Seq-USN,${SCHEMADN} objectClass: top objectClass: attributeSchema cn: ms-Exch-DXA-Req-Seq-USN distinguishedName: CN=ms-Exch-DXA-Req-Seq-USN,${SCHEMADN} attributeID: 1.2.840.113556.1.2.182 attributeSyntax: 2.5.5.9 isSingleValued: TRUE mAPIID: 32920 showInAdvancedViewOnly: TRUE adminDisplayName: ms-Exch-DXA-Req-Seq-USN adminDescription: ms-Exch-DXA-Req-Seq-USN oMSyntax: 2 searchFlags: 0 lDAPDisplayName: dXAReqSeqUSN name: ms-Exch-DXA-Req-Seq-USN schemaIDGUID: a8df73e6-c5ea-11d1-bbcb-0080c76670c0 isMemberOfPartialAttributeSet: FALSE objectCategory: CN=Attribute-Schema,${SCHEMADN} # # ms-Exch-DXA-Svr-Seq # dn: CN=ms-Exch-DXA-Svr-Seq,${SCHEMADN} objectClass: top objectClass: attributeSchema cn: ms-Exch-DXA-Svr-Seq distinguishedName: CN=ms-Exch-DXA-Svr-Seq,${SCHEMADN} attributeID: 1.2.840.113556.1.2.360 attributeSyntax: 2.5.5.5 isSingleValued: TRUE rangeLower: 1 rangeUpper: 32 mAPIID: 32922 showInAdvancedViewOnly: TRUE adminDisplayName: ms-Exch-DXA-Svr-Seq adminDescription: ms-Exch-DXA-Svr-Seq oMSyntax: 19 searchFlags: 0 lDAPDisplayName: dXASvrSeq name: ms-Exch-DXA-Svr-Seq schemaIDGUID: a8df73e8-c5ea-11d1-bbcb-0080c76670c0 isMemberOfPartialAttributeSet: FALSE objectCategory: CN=Attribute-Schema,${SCHEMADN} # # ms-Exch-DXA-Svr-Seq-Time # dn: CN=ms-Exch-DXA-Svr-Seq-Time,${SCHEMADN} objectClass: top objectClass: attributeSchema cn: ms-Exch-DXA-Svr-Seq-Time distinguishedName: CN=ms-Exch-DXA-Svr-Seq-Time,${SCHEMADN} attributeID: 1.2.840.113556.1.2.361 attributeSyntax: 2.5.5.11 isSingleValued: TRUE mAPIID: 32923 showInAdvancedViewOnly: TRUE adminDisplayName: ms-Exch-DXA-Svr-Seq-Time adminDescription: ms-Exch-DXA-Svr-Seq-Time oMSyntax: 23 searchFlags: 0 lDAPDisplayName: dXASvrSeqTime name: ms-Exch-DXA-Svr-Seq-Time schemaIDGUID: a8df73e9-c5ea-11d1-bbcb-0080c76670c0 isMemberOfPartialAttributeSet: FALSE objectCategory: CN=Attribute-Schema,${SCHEMADN} # # ms-Exch-DXA-Svr-Seq-USN # dn: CN=ms-Exch-DXA-Svr-Seq-USN,${SCHEMADN} objectClass: top objectClass: attributeSchema cn: ms-Exch-DXA-Svr-Seq-USN distinguishedName: CN=ms-Exch-DXA-Svr-Seq-USN,${SCHEMADN} attributeID: 1.2.840.113556.1.2.124 attributeSyntax: 2.5.5.9 isSingleValued: TRUE mAPIID: 32924 showInAdvancedViewOnly: TRUE adminDisplayName: ms-Exch-DXA-Svr-Seq-USN adminDescription: ms-Exch-DXA-Svr-Seq-USN oMSyntax: 2 searchFlags: 0 lDAPDisplayName: dXASvrSeqUSN name: ms-Exch-DXA-Svr-Seq-USN schemaIDGUID: a8df73ea-c5ea-11d1-bbcb-0080c76670c0 isMemberOfPartialAttributeSet: FALSE objectCategory: CN=Attribute-Schema,${SCHEMADN} # # ms-Exch-DXA-Template-Options # dn: CN=ms-Exch-DXA-Template-Options,${SCHEMADN} objectClass: top objectClass: attributeSchema cn: ms-Exch-DXA-Template-Options distinguishedName: CN=ms-Exch-DXA-Template-Options,${SCHEMADN} attributeID: 1.2.840.113556.1.2.358 attributeSyntax: 2.5.5.9 isSingleValued: TRUE rangeLower: 0 rangeUpper: 3 mAPIID: 32926 showInAdvancedViewOnly: TRUE adminDisplayName: ms-Exch-DXA-Template-Options adminDescription: ms-Exch-DXA-Template-Options oMSyntax: 10 searchFlags: 0 lDAPDisplayName: dXATemplateOptions name: ms-Exch-DXA-Template-Options schemaIDGUID: a8df73eb-c5ea-11d1-bbcb-0080c76670c0 isMemberOfPartialAttributeSet: FALSE objectCategory: CN=Attribute-Schema,${SCHEMADN} # # ms-Exch-DXA-Template-TimeStamp # dn: CN=ms-Exch-DXA-Template-TimeStamp,${SCHEMADN} objectClass: top objectClass: attributeSchema cn: ms-Exch-DXA-Template-TimeStamp distinguishedName: CN=ms-Exch-DXA-Template-TimeStamp,${SCHEMADN} attributeID: 1.2.840.113556.1.2.365 attributeSyntax: 2.5.5.11 isSingleValued: TRUE mAPIID: 32927 showInAdvancedViewOnly: TRUE adminDisplayName: ms-Exch-DXA-Template-TimeStamp adminDescription: ms-Exch-DXA-Template-TimeStamp oMSyntax: 23 searchFlags: 0 lDAPDisplayName: dXATemplateTimeStamp name: ms-Exch-DXA-Template-TimeStamp schemaIDGUID: a8df73ec-c5ea-11d1-bbcb-0080c76670c0 isMemberOfPartialAttributeSet: FALSE objectCategory: CN=Attribute-Schema,${SCHEMADN} # # ms-Exch-DXA-Types # dn: CN=ms-Exch-DXA-Types,${SCHEMADN} objectClass: top objectClass: attributeSchema cn: ms-Exch-DXA-Types distinguishedName: CN=ms-Exch-DXA-Types,${SCHEMADN} attributeID: 1.2.840.113556.1.2.119 attributeSyntax: 2.5.5.9 isSingleValued: TRUE mAPIID: 32928 showInAdvancedViewOnly: TRUE adminDisplayName: ms-Exch-DXA-Types adminDescription: ms-Exch-DXA-Types oMSyntax: 2 searchFlags: 0 lDAPDisplayName: dXATypes name: ms-Exch-DXA-Types schemaIDGUID: a8df73ed-c5ea-11d1-bbcb-0080c76670c0 isMemberOfPartialAttributeSet: FALSE objectCategory: CN=Attribute-Schema,${SCHEMADN} # # ms-Exch-DXA-UnConf-Container-List # dn: CN=ms-Exch-DXA-UnConf-Container-List,${SCHEMADN} objectClass: top objectClass: attributeSchema cn: ms-Exch-DXA-UnConf-Container-List distinguishedName: CN=ms-Exch-DXA-UnConf-Container-List,${SCHEMADN} attributeID: 1.2.840.113556.1.2.181 attributeSyntax: 2.5.5.1 isSingleValued: FALSE mAPIID: 32929 showInAdvancedViewOnly: TRUE adminDisplayName: ms-Exch-DXA-UnConf-Container-List oMObjectClass:: KwwCh3McAIVK adminDescription: ms-Exch-DXA-UnConf-Container-List oMSyntax: 127 searchFlags: 0 lDAPDisplayName: dXAUnConfContainerList name: ms-Exch-DXA-UnConf-Container-List schemaIDGUID: a8df73ee-c5ea-11d1-bbcb-0080c76670c0 isMemberOfPartialAttributeSet: FALSE objectCategory: CN=Attribute-Schema,${SCHEMADN} # # ms-Exch-Dynamic-DL-BaseDN # dn: CN=ms-Exch-Dynamic-DL-BaseDN,${SCHEMADN} objectClass: top objectClass: attributeSchema cn: ms-Exch-Dynamic-DL-BaseDN distinguishedName: CN=ms-Exch-Dynamic-DL-BaseDN,${SCHEMADN} attributeID: 1.2.840.113556.1.4.7000.102.12543 attributeSyntax: 2.5.5.1 isSingleValued: TRUE showInAdvancedViewOnly: TRUE adminDisplayName: ms-Exch-Dynamic-DL-BaseDN oMObjectClass:: KwwCh3McAIVK adminDescription: ms-Exch-Dynamic-DL-BaseDN oMSyntax: 127 searchFlags: 0 lDAPDisplayName: msExchDynamicDLBaseDN name: ms-Exch-Dynamic-DL-BaseDN schemaIDGUID: 763d0ef9-bd92-41f9-ab34-7e329db76ee3 isMemberOfPartialAttributeSet: TRUE objectCategory: CN=Attribute-Schema,${SCHEMADN} # # ms-Exch-Dynamic-DL-Filter # dn: CN=ms-Exch-Dynamic-DL-Filter,${SCHEMADN} objectClass: top objectClass: attributeSchema cn: ms-Exch-Dynamic-DL-Filter distinguishedName: CN=ms-Exch-Dynamic-DL-Filter,${SCHEMADN} attributeID: 1.2.840.113556.1.4.7000.102.12544 attributeSyntax: 2.5.5.12 isSingleValued: TRUE showInAdvancedViewOnly: TRUE adminDisplayName: ms-Exch-Dynamic-DL-Filter adminDescription: ms-Exch-Dynamic-DL-Filter oMSyntax: 64 searchFlags: 0 lDAPDisplayName: msExchDynamicDLFilter name: ms-Exch-Dynamic-DL-Filter schemaIDGUID: e1b6d32c-6bac-48da-a313-2b58ae1c45ce isMemberOfPartialAttributeSet: TRUE objectCategory: CN=Attribute-Schema,${SCHEMADN} # # ms-Exch-EDB-File # The database file location for this store. # dn: CN=ms-Exch-EDB-File,${SCHEMADN} objectClass: top objectClass: attributeSchema cn: ms-Exch-EDB-File distinguishedName: CN=ms-Exch-EDB-File,${SCHEMADN} attributeID: 1.2.840.113556.1.4.7000.102.11001 attributeSyntax: 2.5.5.4 isSingleValued: TRUE showInAdvancedViewOnly: TRUE adminDisplayName: ms-Exch-EDB-File adminDescription: ms-Exch-EDB-File oMSyntax: 20 searchFlags: 0 lDAPDisplayName: msExchEDBFile name: ms-Exch-EDB-File schemaIDGUID: 9e58d58e-b093-11d2-aa06-00c04f8eedd8 isMemberOfPartialAttributeSet: FALSE objectCategory: CN=Attribute-Schema,${SCHEMADN} # # ms-Exch-EDB-Offline # If TRUE, the MDB is offline. The default is FALSE. # dn: CN=ms-Exch-EDB-Offline,${SCHEMADN} objectClass: top objectClass: attributeSchema cn: ms-Exch-EDB-Offline distinguishedName: CN=ms-Exch-EDB-Offline,${SCHEMADN} attributeID: 1.2.840.113556.1.4.7000.102.11007 attributeSyntax: 2.5.5.8 isSingleValued: TRUE showInAdvancedViewOnly: TRUE adminDisplayName: ms-Exch-EDB-Offline adminDescription: ms-Exch-EDB-Offline oMSyntax: 1 searchFlags: 0 lDAPDisplayName: msExchEDBOffline name: ms-Exch-EDB-Offline schemaIDGUID: 9e7a367a-b093-11d2-aa06-00c04f8eedd8 isMemberOfPartialAttributeSet: FALSE objectCategory: CN=Attribute-Schema,${SCHEMADN} # # ms-Exch-Enabled-Authorization-Packages # A list of authorization packages enabled for this protocol. # dn: CN=ms-Exch-Enabled-Authorization-Packages,${SCHEMADN} objectClass: top objectClass: attributeSchema cn: ms-Exch-Enabled-Authorization-Packages distinguishedName: CN=ms-Exch-Enabled-Authorization-Packages,${SCHEMADN} attributeID: 1.2.840.113556.1.2.479 attributeSyntax: 2.5.5.12 isSingleValued: FALSE rangeLower: 1 rangeUpper: 128 mAPIID: 33156 showInAdvancedViewOnly: TRUE adminDisplayName: ms-Exch-Enabled-Authorization-Packages adminDescription: ms-Exch-Enabled-Authorization-Packages oMSyntax: 64 searchFlags: 0 lDAPDisplayName: enabledAuthorizationPackages name: ms-Exch-Enabled-Authorization-Packages schemaIDGUID: a8df73f3-c5ea-11d1-bbcb-0080c76670c0 isMemberOfPartialAttributeSet: FALSE objectCategory: CN=Attribute-Schema,${SCHEMADN} # # ms-Exch-Enabled-Protocols # dn: CN=ms-Exch-Enabled-Protocols,${SCHEMADN} objectClass: top objectClass: attributeSchema cn: ms-Exch-Enabled-Protocols distinguishedName: CN=ms-Exch-Enabled-Protocols,${SCHEMADN} attributeID: 1.2.840.113556.1.2.474 attributeSyntax: 2.5.5.9 isSingleValued: TRUE mAPIID: 33151 showInAdvancedViewOnly: TRUE adminDisplayName: ms-Exch-Enabled-Protocols adminDescription: ms-Exch-Enabled-Protocols oMSyntax: 2 searchFlags: 0 lDAPDisplayName: enabledProtocols name: ms-Exch-Enabled-Protocols schemaIDGUID: f0f8ff8c-1191-11d0-a060-00aa006c33ed attributeSecurityGUID: e48d0154-bcf8-11d1-8702-00c04fb96050 isMemberOfPartialAttributeSet: TRUE objectCategory: CN=Attribute-Schema,${SCHEMADN} # # ms-Exch-Enabled-Protocol-Cfg # Determines whether this protocol is enabled or not. dn: CN=ms-Exch-Enabled-Protocol-Cfg,${SCHEMADN} objectClass: top objectClass: attributeSchema cn: ms-Exch-Enabled-Protocol-Cfg distinguishedName: CN=ms-Exch-Enabled-Protocol-Cfg,${SCHEMADN} attributeID: 1.2.840.113556.1.2.515 attributeSyntax: 2.5.5.8 isSingleValued: TRUE mAPIID: 33192 showInAdvancedViewOnly: TRUE adminDisplayName: ms-Exch-Enabled-Protocol-Cfg adminDescription: ms-Exch-Enabled-Protocol-Cfg oMSyntax: 1 searchFlags: 0 lDAPDisplayName: enabledProtocolCfg name: ms-Exch-Enabled-Protocol-Cfg schemaIDGUID: a8df73f4-c5ea-11d1-bbcb-0080c76670c0 isMemberOfPartialAttributeSet: FALSE objectCategory: CN=Attribute-Schema,${SCHEMADN} # # ms-Exch-Enable-Compatibility # dn: CN=ms-Exch-Enable-Compatibility,${SCHEMADN} objectClass: top objectClass: attributeSchema cn: ms-Exch-Enable-Compatibility distinguishedName: CN=ms-Exch-Enable-Compatibility,${SCHEMADN} attributeID: 1.2.840.113556.1.2.567 attributeSyntax: 2.5.5.8 isSingleValued: TRUE mAPIID: 35890 showInAdvancedViewOnly: TRUE adminDisplayName: ms-Exch-Enable-Compatibility adminDescription: ms-Exch-Enable-Compatibility oMSyntax: 1 searchFlags: 0 lDAPDisplayName: enableCompatibility name: ms-Exch-Enable-Compatibility schemaIDGUID: a8df73f1-c5ea-11d1-bbcb-0080c76670c0 isMemberOfPartialAttributeSet: FALSE objectCategory: CN=Attribute-Schema,${SCHEMADN} # # ms-Exch-Enable-Internal-Evaluator # dn: CN=ms-Exch-Enable-Internal-Evaluator,${SCHEMADN} objectClass: top objectClass: attributeSchema cn: ms-Exch-Enable-Internal-Evaluator distinguishedName: CN=ms-Exch-Enable-Internal-Evaluator,${SCHEMADN} attributeID: 1.2.840.113556.1.4.7000.102.99 attributeSyntax: 2.5.5.8 isSingleValued: TRUE showInAdvancedViewOnly: TRUE adminDisplayName: ms-Exch-Enable-Internal-Evaluator adminDescription: ms-Exch-Enable-Internal-Evaluator oMSyntax: 1 searchFlags: 0 lDAPDisplayName: msExchEnableInternalEvaluator name: ms-Exch-Enable-Internal-Evaluator schemaIDGUID: 9a56980f-283c-4f86-8395-23011350600c isMemberOfPartialAttributeSet: FALSE objectCategory: CN=Attribute-Schema,${SCHEMADN} # # ms-Exch-Encapsulation-Method # This is present only on X.400 connectors. # dn: CN=ms-Exch-Encapsulation-Method,${SCHEMADN} objectClass: top objectClass: attributeSchema cn: ms-Exch-Encapsulation-Method distinguishedName: CN=ms-Exch-Encapsulation-Method,${SCHEMADN} attributeID: 1.2.840.113556.1.2.448 attributeSyntax: 2.5.5.9 isSingleValued: TRUE mAPIID: 32930 showInAdvancedViewOnly: TRUE adminDisplayName: ms-Exch-Encapsulation-Method adminDescription: ms-Exch-Encapsulation-Method oMSyntax: 10 searchFlags: 0 lDAPDisplayName: encapsulationMethod name: ms-Exch-Encapsulation-Method schemaIDGUID: a8df73f5-c5ea-11d1-bbcb-0080c76670c0 isMemberOfPartialAttributeSet: FALSE objectCategory: CN=Attribute-Schema,${SCHEMADN} # # ms-Exch-Encode-SMTP-Relay # Determines whether or not messages submitted to this domain will be # encoded using the content configuration settings. # dn: CN=ms-Exch-Encode-SMTP-Relay,${SCHEMADN} objectClass: top objectClass: attributeSchema cn: ms-Exch-Encode-SMTP-Relay distinguishedName: CN=ms-Exch-Encode-SMTP-Relay,${SCHEMADN} attributeID: 1.2.840.113556.1.4.7000.102.5053 attributeSyntax: 2.5.5.8 isSingleValued: TRUE showInAdvancedViewOnly: TRUE adminDisplayName: ms-Exch-Encode-SMTP-Relay adminDescription: ms-Exch-Encode-SMTP-Relay oMSyntax: 1 searchFlags: 0 lDAPDisplayName: msExchEncodeSMTPRelay name: ms-Exch-Encode-SMTP-Relay schemaIDGUID: 3a633f17-5194-11d3-aa77-00c04f8eedd8 isMemberOfPartialAttributeSet: FALSE objectCategory: CN=Attribute-Schema,${SCHEMADN} # # ms-Exch-Encrypt # dn: CN=ms-Exch-Encrypt,${SCHEMADN} objectClass: top objectClass: attributeSchema cn: ms-Exch-Encrypt distinguishedName: CN=ms-Exch-Encrypt,${SCHEMADN} attributeID: 1.2.840.113556.1.2.236 attributeSyntax: 2.5.5.8 isSingleValued: TRUE mAPIID: 32931 showInAdvancedViewOnly: TRUE adminDisplayName: ms-Exch-Encrypt adminDescription: ms-Exch-Encrypt oMSyntax: 1 searchFlags: 0 lDAPDisplayName: encrypt name: ms-Exch-Encrypt schemaIDGUID: a8df73f6-c5ea-11d1-bbcb-0080c76670c0 isMemberOfPartialAttributeSet: FALSE objectCategory: CN=Attribute-Schema,${SCHEMADN} # # ms-Exch-Encrypted-Anonymous-Password # dn: CN=ms-Exch-Encrypted-Anonymous-Password,${SCHEMADN} objectClass: top objectClass: attributeSchema cn: ms-Exch-Encrypted-Anonymous-Password distinguishedName: CN=ms-Exch-Encrypted-Anonymous-Password,${SCHEMADN} attributeID: 1.2.840.113556.1.4.7000.102.15009 attributeSyntax: 2.5.5.10 isSingleValued: TRUE showInAdvancedViewOnly: TRUE adminDisplayName: ms-Exch-Encrypted-Anonymous-Password adminDescription: ms-Exch-Encrypted-Anonymous-Password oMSyntax: 4 searchFlags: 0 lDAPDisplayName: msExchEncryptedAnonymousPassword name: ms-Exch-Encrypted-Anonymous-Password schemaIDGUID: 5dc055fc-5c3f-4a6f-a34a-4dbcb68e2ad0 isMemberOfPartialAttributeSet: FALSE objectCategory: CN=Attribute-Schema,${SCHEMADN} # # ms-Exch-Encrypted-Password # dn: CN=ms-Exch-Encrypted-Password,${SCHEMADN} objectClass: top objectClass: attributeSchema cn: ms-Exch-Encrypted-Password distinguishedName: CN=ms-Exch-Encrypted-Password,${SCHEMADN} attributeID: 1.2.840.113556.1.4.7000.102.50062 attributeSyntax: 2.5.5.10 isSingleValued: TRUE showInAdvancedViewOnly: TRUE adminDisplayName: ms-Exch-Encrypted-Password adminDescription: ms-Exch-Encrypted-Password oMSyntax: 4 searchFlags: 0 lDAPDisplayName: msExchEncryptedPassword name: ms-Exch-Encrypted-Password schemaIDGUID: 08c63250-0df6-405d-8907-0312dd1aa145 isMemberOfPartialAttributeSet: FALSE objectCategory: CN=Attribute-Schema,${SCHEMADN} # # ms-Exch-Encrypted-Password-2 # dn: CN=ms-Exch-Encrypted-Password-2,${SCHEMADN} objectClass: top objectClass: attributeSchema cn: ms-Exch-Encrypted-Password-2 distinguishedName: CN=ms-Exch-Encrypted-Password-2,${SCHEMADN} attributeID: 1.2.840.113556.1.4.7000.102.50065 attributeSyntax: 2.5.5.10 isSingleValued: TRUE showInAdvancedViewOnly: TRUE adminDisplayName: ms-Exch-Encrypted-Password-2 adminDescription: ms-Exch-Encrypted-Password-2 oMSyntax: 4 searchFlags: 0 lDAPDisplayName: msExchEncryptedPassword2 name: ms-Exch-Encrypted-Password-2 schemaIDGUID: dcbc61e9-9279-44d1-b494-25562659db75 isMemberOfPartialAttributeSet: FALSE objectCategory: CN=Attribute-Schema,${SCHEMADN} # # ms-Exch-Encrypt-Alg-List-NA # dn: CN=ms-Exch-Encrypt-Alg-List-NA,${SCHEMADN} objectClass: top objectClass: attributeSchema cn: ms-Exch-Encrypt-Alg-List-NA distinguishedName: CN=ms-Exch-Encrypt-Alg-List-NA,${SCHEMADN} attributeID: 1.2.840.113556.1.2.130 attributeSyntax: 2.5.5.5 isSingleValued: FALSE rangeLower: 1 rangeUpper: 32 mAPIID: 32832 showInAdvancedViewOnly: TRUE adminDisplayName: ms-Exch-Encrypt-Alg-List-NA adminDescription: ms-Exch-Encrypt-Alg-List-NA oMSyntax: 19 searchFlags: 0 lDAPDisplayName: encryptAlgListNA name: ms-Exch-Encrypt-Alg-List-NA schemaIDGUID: a8df73f7-c5ea-11d1-bbcb-0080c76670c0 isMemberOfPartialAttributeSet: FALSE objectCategory: CN=Attribute-Schema,${SCHEMADN} # # ms-Exch-Encrypt-Alg-List-Other # dn: CN=ms-Exch-Encrypt-Alg-List-Other,${SCHEMADN} objectClass: top objectClass: attributeSchema cn: ms-Exch-Encrypt-Alg-List-Other distinguishedName: CN=ms-Exch-Encrypt-Alg-List-Other,${SCHEMADN} attributeID: 1.2.840.113556.1.2.399 attributeSyntax: 2.5.5.5 isSingleValued: FALSE rangeLower: 1 rangeUpper: 32 mAPIID: 32833 showInAdvancedViewOnly: TRUE adminDisplayName: ms-Exch-Encrypt-Alg-List-Other adminDescription: ms-Exch-Encrypt-Alg-List-Other oMSyntax: 19 searchFlags: 0 lDAPDisplayName: encryptAlgListOther name: ms-Exch-Encrypt-Alg-List-Other schemaIDGUID: a8df73f8-c5ea-11d1-bbcb-0080c76670c0 isMemberOfPartialAttributeSet: FALSE objectCategory: CN=Attribute-Schema,${SCHEMADN} # # ms-Exch-Encrypt-Alg-Selected-NA # dn: CN=ms-Exch-Encrypt-Alg-Selected-NA,${SCHEMADN} objectClass: top objectClass: attributeSchema cn: ms-Exch-Encrypt-Alg-Selected-NA distinguishedName: CN=ms-Exch-Encrypt-Alg-Selected-NA,${SCHEMADN} attributeID: 1.2.840.113556.1.2.401 attributeSyntax: 2.5.5.5 isSingleValued: TRUE rangeLower: 1 rangeUpper: 32 mAPIID: 32835 showInAdvancedViewOnly: TRUE adminDisplayName: ms-Exch-Encrypt-Alg-Selected-NA adminDescription: ms-Exch-Encrypt-Alg-Selected-NA oMSyntax: 19 searchFlags: 0 lDAPDisplayName: encryptAlgSelectedNA name: ms-Exch-Encrypt-Alg-Selected-NA schemaIDGUID: a8df73f9-c5ea-11d1-bbcb-0080c76670c0 isMemberOfPartialAttributeSet: FALSE objectCategory: CN=Attribute-Schema,${SCHEMADN} # # ms-Exch-Encrypt-Alg-Selected-Other # dn: CN=ms-Exch-Encrypt-Alg-Selected-Other,${SCHEMADN} objectClass: top objectClass: attributeSchema cn: ms-Exch-Encrypt-Alg-Selected-Other distinguishedName: CN=ms-Exch-Encrypt-Alg-Selected-Other,${SCHEMADN} attributeID: 1.2.840.113556.1.2.397 attributeSyntax: 2.5.5.5 isSingleValued: TRUE rangeLower: 1 rangeUpper: 32 mAPIID: 32829 showInAdvancedViewOnly: TRUE adminDisplayName: ms-Exch-Encrypt-Alg-Selected-Other adminDescription: ms-Exch-Encrypt-Alg-Selected-Other oMSyntax: 19 searchFlags: 0 lDAPDisplayName: encryptAlgSelectedOther name: ms-Exch-Encrypt-Alg-Selected-Other schemaIDGUID: a8df73fa-c5ea-11d1-bbcb-0080c76670c0 isMemberOfPartialAttributeSet: FALSE objectCategory: CN=Attribute-Schema,${SCHEMADN} # # ms-Exch-ESE-Param-Assert-Action # The action on assert. dn: CN=ms-Exch-ESE-Param-Assert-Action,${SCHEMADN} objectClass: top objectClass: attributeSchema cn: ms-Exch-ESE-Param-Assert-Action distinguishedName: CN=ms-Exch-ESE-Param-Assert-Action,${SCHEMADN} attributeID: 1.2.840.113556.1.4.7000.102.11074 attributeSyntax: 2.5.5.9 isSingleValued: TRUE showInAdvancedViewOnly: TRUE adminDisplayName: ms-Exch-ESE-Param-Assert-Action adminDescription: ms-Exch-ESE-Param-Assert-Action oMSyntax: 2 searchFlags: 0 lDAPDisplayName: msExchESEParamAssertAction name: ms-Exch-ESE-Param-Assert-Action schemaIDGUID: 2d09783d-2b54-11d3-aa6b-00c04f8eedd8 isMemberOfPartialAttributeSet: FALSE objectCategory: CN=Attribute-Schema,${SCHEMADN} # # ms-Exch-ESE-Param-Base-Name # The base name for all Database Management System (DBMS) object names. # dn: CN=ms-Exch-ESE-Param-Base-Name,${SCHEMADN} objectClass: top objectClass: attributeSchema cn: ms-Exch-ESE-Param-Base-Name distinguishedName: CN=ms-Exch-ESE-Param-Base-Name,${SCHEMADN} attributeID: 1.2.840.113556.1.4.7000.102.11076 attributeSyntax: 2.5.5.4 isSingleValued: TRUE showInAdvancedViewOnly: TRUE adminDisplayName: ms-Exch-ESE-Param-Base-Name adminDescription: ms-Exch-ESE-Param-Base-Name oMSyntax: 20 searchFlags: 0 lDAPDisplayName: msExchESEParamBaseName name: ms-Exch-ESE-Param-Base-Name schemaIDGUID: 2d097845-2b54-11d3-aa6b-00c04f8eedd8 isMemberOfPartialAttributeSet: FALSE objectCategory: CN=Attribute-Schema,${SCHEMADN} # # ms-Exch-ESE-Param-Cached-Closed-Tables # dn: CN=ms-Exch-ESE-Param-Cached-Closed-Tables,${SCHEMADN} objectClass: top objectClass: attributeSchema cn: ms-Exch-ESE-Param-Cached-Closed-Tables distinguishedName: CN=ms-Exch-ESE-Param-Cached-Closed-Tables,${SCHEMADN} attributeID: 1.2.840.113556.1.4.7000.102.11096 attributeSyntax: 2.5.5.9 isSingleValued: TRUE showInAdvancedViewOnly: TRUE adminDisplayName: ms-Exch-ESE-Param-Cached-Closed-Tables adminDescription: ms-Exch-ESE-Param-Cached-Closed-Tables oMSyntax: 2 searchFlags: 0 lDAPDisplayName: msExchESEParamCachedClosedTables name: ms-Exch-ESE-Param-Cached-Closed-Tables schemaIDGUID: d19c67f8-a0eb-432a-bedd-af10cd7da25c isMemberOfPartialAttributeSet: FALSE objectCategory: CN=Attribute-Schema,${SCHEMADN} # # ms-Exch-ESE-Param-Cache-Size # dn: CN=ms-Exch-ESE-Param-Cache-Size,${SCHEMADN} objectClass: top objectClass: attributeSchema cn: ms-Exch-ESE-Param-Cache-Size distinguishedName: CN=ms-Exch-ESE-Param-Cache-Size,${SCHEMADN} attributeID: 1.2.840.113556.1.4.7000.102.11002 attributeSyntax: 2.5.5.9 isSingleValued: TRUE showInAdvancedViewOnly: TRUE adminDisplayName: ms-Exch-ESE-Param-Cache-Size adminDescription: ms-Exch-ESE-Param-Cache-Size oMSyntax: 2 searchFlags: 0 lDAPDisplayName: msExchESEParamCacheSize name: ms-Exch-ESE-Param-Cache-Size schemaIDGUID: 9eb8339e-b093-11d2-aa06-00c04f8eedd8 isMemberOfPartialAttributeSet: FALSE objectCategory: CN=Attribute-Schema,${SCHEMADN} # # ms-Exch-ESE-Param-Cache-Size-Max # dn: CN=ms-Exch-ESE-Param-Cache-Size-Max,${SCHEMADN} objectClass: top objectClass: attributeSchema cn: ms-Exch-ESE-Param-Cache-Size-Max distinguishedName: CN=ms-Exch-ESE-Param-Cache-Size-Max,${SCHEMADN} attributeID: 1.2.840.113556.1.4.7000.102.11003 attributeSyntax: 2.5.5.9 isSingleValued: TRUE showInAdvancedViewOnly: TRUE adminDisplayName: ms-Exch-ESE-Param-Cache-Size-Max adminDescription: ms-Exch-ESE-Param-Cache-Size-Max oMSyntax: 2 searchFlags: 0 lDAPDisplayName: msExchESEParamCacheSizeMax name: ms-Exch-ESE-Param-Cache-Size-Max schemaIDGUID: 9ed73230-b093-11d2-aa06-00c04f8eedd8 isMemberOfPartialAttributeSet: FALSE objectCategory: CN=Attribute-Schema,${SCHEMADN} # # ms-Exch-ESE-Param-Cache-Size-Min # The minimum cache size in pages. # dn: CN=ms-Exch-ESE-Param-Cache-Size-Min,${SCHEMADN} objectClass: top objectClass: attributeSchema cn: ms-Exch-ESE-Param-Cache-Size-Min distinguishedName: CN=ms-Exch-ESE-Param-Cache-Size-Min,${SCHEMADN} attributeID: 1.2.840.113556.1.4.7000.102.11075 attributeSyntax: 2.5.5.9 isSingleValued: TRUE showInAdvancedViewOnly: TRUE adminDisplayName: ms-Exch-ESE-Param-Cache-Size-Min adminDescription: ms-Exch-ESE-Param-Cache-Size-Min oMSyntax: 2 searchFlags: 0 lDAPDisplayName: msExchESEParamCacheSizeMin name: ms-Exch-ESE-Param-Cache-Size-Min schemaIDGUID: 2d097841-2b54-11d3-aa6b-00c04f8eedd8 isMemberOfPartialAttributeSet: FALSE objectCategory: CN=Attribute-Schema,${SCHEMADN} # # ms-Exch-ESE-Param-Checkpoint-Depth-Max # The maximum checkpoint depth in bytes. # dn: CN=ms-Exch-ESE-Param-Checkpoint-Depth-Max,${SCHEMADN} objectClass: top objectClass: attributeSchema cn: ms-Exch-ESE-Param-Checkpoint-Depth-Max distinguishedName: CN=ms-Exch-ESE-Param-Checkpoint-Depth-Max,${SCHEMADN} attributeID: 1.2.840.113556.1.4.7000.102.11081 attributeSyntax: 2.5.5.9 isSingleValued: TRUE showInAdvancedViewOnly: TRUE adminDisplayName: ms-Exch-ESE-Param-Checkpoint-Depth-Max adminDescription: ms-Exch-ESE-Param-Checkpoint-Depth-Max oMSyntax: 2 searchFlags: 0 lDAPDisplayName: msExchESEParamCheckpointDepthMax name: ms-Exch-ESE-Param-Checkpoint-Depth-Max schemaIDGUID: 2d09785a-2b54-11d3-aa6b-00c04f8eedd8 isMemberOfPartialAttributeSet: FALSE objectCategory: CN=Attribute-Schema,${SCHEMADN} # # ms-Exch-ESE-Param-Circular-Log # A Boolean flag for circular logging. # dn: CN=ms-Exch-ESE-Param-Circular-Log,${SCHEMADN} objectClass: top objectClass: attributeSchema cn: ms-Exch-ESE-Param-Circular-Log distinguishedName: CN=ms-Exch-ESE-Param-Circular-Log,${SCHEMADN} attributeID: 1.2.840.113556.1.4.7000.102.11005 attributeSyntax: 2.5.5.9 isSingleValued: TRUE showInAdvancedViewOnly: TRUE adminDisplayName: ms-Exch-ESE-Param-Circular-Log adminDescription: ms-Exch-ESE-Param-Circular-Log oMSyntax: 2 searchFlags: 0 lDAPDisplayName: msExchESEParamCircularLog name: ms-Exch-ESE-Param-Circular-Log schemaIDGUID: 9ef8931c-b093-11d2-aa06-00c04f8eedd8 isMemberOfPartialAttributeSet: FALSE objectCategory: CN=Attribute-Schema,${SCHEMADN} # # ms-Exch-ESE-Param-Commit-Default # The default grbit for JetCommitTransaction. # dn: CN=ms-Exch-ESE-Param-Commit-Default,${SCHEMADN} objectClass: top objectClass: attributeSchema cn: ms-Exch-ESE-Param-Commit-Default distinguishedName: CN=ms-Exch-ESE-Param-Commit-Default,${SCHEMADN} attributeID: 1.2.840.113556.1.4.7000.102.11077 attributeSyntax: 2.5.5.9 isSingleValued: TRUE showInAdvancedViewOnly: TRUE adminDisplayName: ms-Exch-ESE-Param-Commit-Default adminDescription: ms-Exch-ESE-Param-Commit-Default oMSyntax: 2 searchFlags: 0 lDAPDisplayName: msExchESEParamCommitDefault name: ms-Exch-ESE-Param-Commit-Default schemaIDGUID: 2d097849-2b54-11d3-aa6b-00c04f8eedd8 isMemberOfPartialAttributeSet: FALSE objectCategory: CN=Attribute-Schema,${SCHEMADN} # # ms-Exch-ESE-Param-Db-Extension-Size # The database extension size in pages. # dn: CN=ms-Exch-ESE-Param-Db-Extension-Size,${SCHEMADN} objectClass: top objectClass: attributeSchema cn: ms-Exch-ESE-Param-Db-Extension-Size distinguishedName: CN=ms-Exch-ESE-Param-Db-Extension-Size,${SCHEMADN} attributeID: 1.2.840.113556.1.4.7000.102.11078 attributeSyntax: 2.5.5.9 isSingleValued: TRUE showInAdvancedViewOnly: TRUE adminDisplayName: ms-Exch-ESE-Param-Db-Extension-Size adminDescription: ms-Exch-ESE-Param-Db-Extension-Size oMSyntax: 2 searchFlags: 0 lDAPDisplayName: msExchESEParamDbExtensionSize name: ms-Exch-ESE-Param-Db-Extension-Size schemaIDGUID: 2d09784d-2b54-11d3-aa6b-00c04f8eedd8 isMemberOfPartialAttributeSet: FALSE objectCategory: CN=Attribute-Schema,${SCHEMADN} # # ms-Exch-ESE-Param-Enable-Index-Checking # Enables checking the operating system version for indexes. The # default is False. # dn: CN=ms-Exch-ESE-Param-Enable-Index-Checking,${SCHEMADN} objectClass: top objectClass: attributeSchema cn: ms-Exch-ESE-Param-Enable-Index-Checking distinguishedName: CN=ms-Exch-ESE-Param-Enable-Index-Checking,${SCHEMADN} attributeID: 1.2.840.113556.1.4.7000.102.11073 attributeSyntax: 2.5.5.8 isSingleValued: TRUE showInAdvancedViewOnly: TRUE adminDisplayName: ms-Exch-ESE-Param-Enable-Index-Checking adminDescription: ms-Exch-ESE-Param-Enable-Index-Checking oMSyntax: 1 searchFlags: 0 lDAPDisplayName: msExchESEParamEnableIndexChecking name: ms-Exch-ESE-Param-Enable-Index-Checking schemaIDGUID: 2d097838-2b54-11d3-aa6b-00c04f8eedd8 isMemberOfPartialAttributeSet: FALSE objectCategory: CN=Attribute-Schema,${SCHEMADN} # # ms-Exch-ESE-Param-Enable-Online-Defrag # Enables online defragmentation. The default is True. # dn: CN=ms-Exch-ESE-Param-Enable-Online-Defrag,${SCHEMADN} objectClass: top objectClass: attributeSchema cn: ms-Exch-ESE-Param-Enable-Online-Defrag distinguishedName: CN=ms-Exch-ESE-Param-Enable-Online-Defrag,${SCHEMADN} attributeID: 1.2.840.113556.1.4.7000.102.11072 attributeSyntax: 2.5.5.8 isSingleValued: TRUE showInAdvancedViewOnly: TRUE adminDisplayName: ms-Exch-ESE-Param-Enable-Online-Defrag adminDescription: ms-Exch-ESE-Param-Enable-Online-Defrag oMSyntax: 1 searchFlags: 0 lDAPDisplayName: msExchESEParamEnableOnlineDefrag name: ms-Exch-ESE-Param-Enable-Online-Defrag schemaIDGUID: 2d097833-2b54-11d3-aa6b-00c04f8eedd8 isMemberOfPartialAttributeSet: FALSE objectCategory: CN=Attribute-Schema,${SCHEMADN} # # ms-Exch-ESE-Param-Enable-Sorted-Retrieve-Columns # Internally sorts (in a dynamically allocated parallel array) # JET_RETRIEVECOLUMN structures passed to JetRetrieveColumns(). The # default is False. # dn: CN=ms-Exch-ESE-Param-Enable-Sorted-Retrieve-Columns,${SCHEMADN} objectClass: top objectClass: attributeSchema cn: ms-Exch-ESE-Param-Enable-Sorted-Retrieve-Columns distinguishedName: CN=ms-Exch-ESE-Param-Enable-Sorted-Retrieve-Columns,CN=Sche attributeID: 1.2.840.113556.1.4.7000.102.11069 attributeSyntax: 2.5.5.8 isSingleValued: TRUE showInAdvancedViewOnly: TRUE adminDisplayName: ms-Exch-ESE-Param-Enable-Sorted-Retrieve-Columns adminDescription: ms-Exch-ESE-Param-Enable-Sorted-Retrieve-Columns oMSyntax: 1 searchFlags: 0 lDAPDisplayName: msExchESEParamEnableSortedRetrieveColumns name: ms-Exch-ESE-Param-Enable-Sorted-Retrieve-Columns schemaIDGUID: 2d097828-2b54-11d3-aa6b-00c04f8eedd8 objectCategory: CN=Attribute-Schema,${SCHEMADN} # # ms-Exch-ESE-Param-Event-Source # A language-independent process descriptor string. # dn: CN=ms-Exch-ESE-Param-Event-Source,${SCHEMADN} objectClass: top objectClass: attributeSchema cn: ms-Exch-ESE-Param-Event-Source distinguishedName: CN=ms-Exch-ESE-Param-Event-Source,${SCHEMADN} attributeID: 1.2.840.113556.1.4.7000.102.11008 attributeSyntax: 2.5.5.4 isSingleValued: TRUE showInAdvancedViewOnly: TRUE adminDisplayName: ms-Exch-ESE-Param-Event-Source adminDescription: ms-Exch-ESE-Param-Event-Source oMSyntax: 20 searchFlags: 0 lDAPDisplayName: msExchESEParamEventSource name: ms-Exch-ESE-Param-Event-Source schemaIDGUID: 9f19f408-b093-11d2-aa06-00c04f8eedd8 isMemberOfPartialAttributeSet: FALSE objectCategory: CN=Attribute-Schema,${SCHEMADN} # # ms-Exch-ESE-Param-Global-Min-Ver-Pages # The global minimum version page size in 16-kilobyte (KB) units. # dn: CN=ms-Exch-ESE-Param-Global-Min-Ver-Pages,${SCHEMADN} objectClass: top objectClass: attributeSchema cn: ms-Exch-ESE-Param-Global-Min-Ver-Pages distinguishedName: CN=ms-Exch-ESE-Param-Global-Min-Ver-Pages,${SCHEMADN} attributeID: 1.2.840.113556.1.4.7000.102.11082 attributeSyntax: 2.5.5.9 isSingleValued: TRUE showInAdvancedViewOnly: TRUE adminDisplayName: ms-Exch-ESE-Param-Global-Min-Ver-Pages adminDescription: ms-Exch-ESE-Param-Global-Min-Ver-Pages oMSyntax: 2 searchFlags: 0 lDAPDisplayName: msExchESEParamGlobalMinVerPages name: ms-Exch-ESE-Param-Global-Min-Ver-Pages schemaIDGUID: 02e831da-2f29-11d3-aa6c-00c04f8eedd8 isMemberOfPartialAttributeSet: FALSE objectCategory: CN=Attribute-Schema,${SCHEMADN} # # ms-Exch-ESE-Param-Log-Buffers # Log buffers in 512 bytes. # dn: CN=ms-Exch-ESE-Param-Log-Buffers,${SCHEMADN} objectClass: top objectClass: attributeSchema cn: ms-Exch-ESE-Param-Log-Buffers distinguishedName: CN=ms-Exch-ESE-Param-Log-Buffers,${SCHEMADN} attributeID: 1.2.840.113556.1.4.7000.102.11009 attributeSyntax: 2.5.5.9 isSingleValued: TRUE showInAdvancedViewOnly: TRUE adminDisplayName: ms-Exch-ESE-Param-Log-Buffers adminDescription: ms-Exch-ESE-Param-Log-Buffers oMSyntax: 2 searchFlags: 0 lDAPDisplayName: msExchESEParamLogBuffers name: ms-Exch-ESE-Param-Log-Buffers schemaIDGUID: 9f38f29a-b093-11d2-aa06-00c04f8eedd8 isMemberOfPartialAttributeSet: FALSE objectCategory: CN=Attribute-Schema,${SCHEMADN} # # ms-Exch-ESE-Param-Log-Checkpoint-Period # dn: CN=ms-Exch-ESE-Param-Log-Checkpoint-Period,${SCHEMADN} objectClass: top objectClass: attributeSchema cn: ms-Exch-ESE-Param-Log-Checkpoint-Period distinguishedName: CN=ms-Exch-ESE-Param-Log-Checkpoint-Period,${SCHEMADN} attributeID: 1.2.840.113556.1.4.7000.102.11010 attributeSyntax: 2.5.5.9 isSingleValued: TRUE showInAdvancedViewOnly: TRUE adminDisplayName: ms-Exch-ESE-Param-Log-Checkpoint-Period adminDescription: ms-Exch-ESE-Param-Log-Checkpoint-Period oMSyntax: 2 searchFlags: 0 lDAPDisplayName: msExchESEParamLogCheckpointPeriod name: ms-Exch-ESE-Param-Log-Checkpoint-Period schemaIDGUID: 9f5a5386-b093-11d2-aa06-00c04f8eedd8 isMemberOfPartialAttributeSet: FALSE objectCategory: CN=Attribute-Schema,${SCHEMADN} # # ms-Exch-ESE-Param-Log-File-Path # The path to the log file directory. # dn: CN=ms-Exch-ESE-Param-Log-File-Path,${SCHEMADN} objectClass: top objectClass: attributeSchema cn: ms-Exch-ESE-Param-Log-File-Path distinguishedName: CN=ms-Exch-ESE-Param-Log-File-Path,${SCHEMADN} attributeID: 1.2.840.113556.1.4.7000.102.11011 attributeSyntax: 2.5.5.4 isSingleValued: TRUE showInAdvancedViewOnly: TRUE adminDisplayName: ms-Exch-ESE-Param-Log-File-Path adminDescription: ms-Exch-ESE-Param-Log-File-Path oMSyntax: 20 searchFlags: 0 lDAPDisplayName: msExchESEParamLogFilePath name: ms-Exch-ESE-Param-Log-File-Path schemaIDGUID: 9f795218-b093-11d2-aa06-00c04f8eedd8 isMemberOfPartialAttributeSet: FALSE objectCategory: CN=Attribute-Schema,${SCHEMADN} # # ms-Exch-ESE-Param-Log-File-Size # The log file size in KB. dn: CN=ms-Exch-ESE-Param-Log-File-Size,${SCHEMADN} objectClass: top objectClass: attributeSchema cn: ms-Exch-ESE-Param-Log-File-Size distinguishedName: CN=ms-Exch-ESE-Param-Log-File-Size,${SCHEMADN} attributeID: 1.2.840.113556.1.4.7000.102.11012 attributeSyntax: 2.5.5.9 isSingleValued: TRUE showInAdvancedViewOnly: TRUE adminDisplayName: ms-Exch-ESE-Param-Log-File-Size adminDescription: ms-Exch-ESE-Param-Log-File-Size oMSyntax: 2 searchFlags: 0 lDAPDisplayName: msExchESEParamLogFileSize name: ms-Exch-ESE-Param-Log-File-Size schemaIDGUID: 9f9ab304-b093-11d2-aa06-00c04f8eedd8 isMemberOfPartialAttributeSet: FALSE objectCategory: CN=Attribute-Schema,${SCHEMADN} # # ms-Exch-ESE-Param-Log-Waiting-User-Max # The maximum sessions waiting on log flush. # dn: CN=ms-Exch-ESE-Param-Log-Waiting-User-Max,${SCHEMADN} objectClass: top objectClass: attributeSchema cn: ms-Exch-ESE-Param-Log-Waiting-User-Max distinguishedName: CN=ms-Exch-ESE-Param-Log-Waiting-User-Max,${SCHEMADN} attributeID: 1.2.840.113556.1.4.7000.102.11013 attributeSyntax: 2.5.5.9 isSingleValued: TRUE showInAdvancedViewOnly: TRUE adminDisplayName: ms-Exch-ESE-Param-Log-Waiting-User-Max adminDescription: ms-Exch-ESE-Param-Log-Waiting-User-Max oMSyntax: 2 searchFlags: 0 lDAPDisplayName: msExchESEParamLogWaitingUserMax name: ms-Exch-ESE-Param-Log-Waiting-User-Max schemaIDGUID: 9fbe764a-b093-11d2-aa06-00c04f8eedd8 isMemberOfPartialAttributeSet: FALSE objectCategory: CN=Attribute-Schema,${SCHEMADN} # # ms-Exch-ESE-Param-Max-Cursors # The maximum number of open cursors. # dn: CN=ms-Exch-ESE-Param-Max-Cursors,${SCHEMADN} objectClass: top objectClass: attributeSchema cn: ms-Exch-ESE-Param-Max-Cursors distinguishedName: CN=ms-Exch-ESE-Param-Max-Cursors,${SCHEMADN} attributeID: 1.2.840.113556.1.4.7000.102.11071 attributeSyntax: 2.5.5.9 isSingleValued: TRUE showInAdvancedViewOnly: TRUE adminDisplayName: ms-Exch-ESE-Param-Max-Cursors adminDescription: ms-Exch-ESE-Param-Max-Cursors oMSyntax: 2 searchFlags: 0 lDAPDisplayName: msExchESEParamMaxCursors name: ms-Exch-ESE-Param-Max-Cursors schemaIDGUID: 2d097830-2b54-11d3-aa6b-00c04f8eedd8 isMemberOfPartialAttributeSet: FALSE objectCategory: CN=Attribute-Schema,${SCHEMADN} # # ms-Exch-ESE-Param-Max-Open-Tables # The maximum number of open directories. # dn: CN=ms-Exch-ESE-Param-Max-Open-Tables,${SCHEMADN} objectClass: top objectClass: attributeSchema cn: ms-Exch-ESE-Param-Max-Open-Tables distinguishedName: CN=ms-Exch-ESE-Param-Max-Open-Tables,${SCHEMADN} attributeID: 1.2.840.113556.1.4.7000.102.11014 attributeSyntax: 2.5.5.9 isSingleValued: TRUE showInAdvancedViewOnly: TRUE adminDisplayName: ms-Exch-ESE-Param-Max-Open-Tables adminDescription: ms-Exch-ESE-Param-Max-Open-Tables oMSyntax: 2 searchFlags: 0 lDAPDisplayName: msExchESEParamMaxOpenTables name: ms-Exch-ESE-Param-Max-Open-Tables schemaIDGUID: 9fdfd736-b093-11d2-aa06-00c04f8eedd8 isMemberOfPartialAttributeSet: FALSE objectCategory: CN=Attribute-Schema,${SCHEMADN} # # ms-Exch-ESE-Param-Max-Sessions # The maximum number of sessions. # dn: CN=ms-Exch-ESE-Param-Max-Sessions,${SCHEMADN} objectClass: top objectClass: attributeSchema cn: ms-Exch-ESE-Param-Max-Sessions distinguishedName: CN=ms-Exch-ESE-Param-Max-Sessions,${SCHEMADN} attributeID: 1.2.840.113556.1.4.7000.102.11015 attributeSyntax: 2.5.5.9 isSingleValued: TRUE showInAdvancedViewOnly: TRUE adminDisplayName: ms-Exch-ESE-Param-Max-Sessions adminDescription: ms-Exch-ESE-Param-Max-Sessions oMSyntax: 2 searchFlags: 0 lDAPDisplayName: msExchESEParamMaxSessions name: ms-Exch-ESE-Param-Max-Sessions schemaIDGUID: 9ffed5c8-b093-11d2-aa06-00c04f8eedd8 isMemberOfPartialAttributeSet: FALSE objectCategory: CN=Attribute-Schema,${SCHEMADN} # # ms-Exch-ESE-Param-Max-Temporary-Tables # The maximum concurrent open temporary table/index creation. # dn: CN=ms-Exch-ESE-Param-Max-Temporary-Tables,${SCHEMADN} objectClass: top objectClass: attributeSchema cn: ms-Exch-ESE-Param-Max-Temporary-Tables distinguishedName: CN=ms-Exch-ESE-Param-Max-Temporary-Tables,${SCHEMADN} attributeID: 1.2.840.113556.1.4.7000.102.11070 attributeSyntax: 2.5.5.9 isSingleValued: TRUE showInAdvancedViewOnly: TRUE adminDisplayName: ms-Exch-ESE-Param-Max-Temporary-Tables adminDescription: ms-Exch-ESE-Param-Max-Temporary-Tables oMSyntax: 2 searchFlags: 0 lDAPDisplayName: msExchESEParamMaxTemporaryTables name: ms-Exch-ESE-Param-Max-Temporary-Tables schemaIDGUID: 2d09782c-2b54-11d3-aa6b-00c04f8eedd8 isMemberOfPartialAttributeSet: FALSE objectCategory: CN=Attribute-Schema,${SCHEMADN} # # ms-Exch-ESE-Param-Max-Ver-Pages # The maximum version store size in 16-KB units. # dn: CN=ms-Exch-ESE-Param-Max-Ver-Pages,${SCHEMADN} objectClass: top objectClass: attributeSchema cn: ms-Exch-ESE-Param-Max-Ver-Pages distinguishedName: CN=ms-Exch-ESE-Param-Max-Ver-Pages,${SCHEMADN} attributeID: 1.2.840.113556.1.4.7000.102.11017 attributeSyntax: 2.5.5.9 isSingleValued: TRUE showInAdvancedViewOnly: TRUE adminDisplayName: ms-Exch-ESE-Param-Max-Ver-Pages adminDescription: ms-Exch-ESE-Param-Max-Ver-Pages oMSyntax: 2 searchFlags: 0 lDAPDisplayName: msExchESEParamMaxVerPages name: ms-Exch-ESE-Param-Max-Ver-Pages schemaIDGUID: a02036b4-b093-11d2-aa06-00c04f8eedd8 isMemberOfPartialAttributeSet: FALSE objectCategory: CN=Attribute-Schema,${SCHEMADN} # # ms-Exch-ESE-Param-Page-Fragment # The maximum disk extent considered fragment, in pages. # dn: CN=ms-Exch-ESE-Param-Page-Fragment,${SCHEMADN} objectClass: top objectClass: attributeSchema cn: ms-Exch-ESE-Param-Page-Fragment distinguishedName: CN=ms-Exch-ESE-Param-Page-Fragment,${SCHEMADN} attributeID: 1.2.840.113556.1.4.7000.102.11080 attributeSyntax: 2.5.5.9 isSingleValued: TRUE showInAdvancedViewOnly: TRUE adminDisplayName: ms-Exch-ESE-Param-Page-Fragment adminDescription: ms-Exch-ESE-Param-Page-Fragment oMSyntax: 2 searchFlags: 0 lDAPDisplayName: msExchESEParamPageFragment name: ms-Exch-ESE-Param-Page-Fragment schemaIDGUID: 2d097855-2b54-11d3-aa6b-00c04f8eedd8 isMemberOfPartialAttributeSet: FALSE objectCategory: CN=Attribute-Schema,${SCHEMADN} # # ms-Exch-ESE-Param-Page-Temp-DB-Min # The minimum size of a temporary database, in pages. # dn: CN=ms-Exch-ESE-Param-Page-Temp-DB-Min,${SCHEMADN} objectClass: top objectClass: attributeSchema cn: ms-Exch-ESE-Param-Page-Temp-DB-Min distinguishedName: CN=ms-Exch-ESE-Param-Page-Temp-DB-Min,${SCHEMADN} attributeID: 1.2.840.113556.1.4.7000.102.11079 attributeSyntax: 2.5.5.9 isSingleValued: TRUE showInAdvancedViewOnly: TRUE adminDisplayName: ms-Exch-ESE-Param-Page-Temp-DB-Min adminDescription: ms-Exch-ESE-Param-Page-Temp-DB-Min oMSyntax: 2 searchFlags: 0 lDAPDisplayName: msExchESEParamPageTempDBMin name: ms-Exch-ESE-Param-Page-Temp-DB-Min schemaIDGUID: 2d097851-2b54-11d3-aa6b-00c04f8eedd8 isMemberOfPartialAttributeSet: FALSE objectCategory: CN=Attribute-Schema,${SCHEMADN} # # ms-Exch-ESE-Param-Preferred-Max-Open-Tables # The preferred maximum number of open directories. dn: CN=ms-Exch-ESE-Param-Preferred-Max-Open-Tables,${SCHEMADN} objectClass: top objectClass: attributeSchema cn: ms-Exch-ESE-Param-Preferred-Max-Open-Tables distinguishedName: CN=ms-Exch-ESE-Param-Preferred-Max-Open-Tables,${SCHEMADN} attributeID: 1.2.840.113556.1.4.7000.102.11018 attributeSyntax: 2.5.5.9 isSingleValued: TRUE showInAdvancedViewOnly: TRUE adminDisplayName: ms-Exch-ESE-Param-Preferred-Max-Open-Tables adminDescription: ms-Exch-ESE-Param-Preferred-Max-Open-Tables oMSyntax: 2 searchFlags: 0 lDAPDisplayName: msExchESEParamPreferredMaxOpenTables name: ms-Exch-ESE-Param-Preferred-Max-Open-Tables schemaIDGUID: a04197a0-b093-11d2-aa06-00c04f8eedd8 isMemberOfPartialAttributeSet: FALSE objectCategory: CN=Attribute-Schema,${SCHEMADN} # # ms-Exch-ESE-Param-Preferred-Ver-Pages # The preferred version store size in 16-KB units. # dn: CN=ms-Exch-ESE-Param-Preferred-Ver-Pages,${SCHEMADN} objectClass: top objectClass: attributeSchema cn: ms-Exch-ESE-Param-Preferred-Ver-Pages distinguishedName: CN=ms-Exch-ESE-Param-Preferred-Ver-Pages,${SCHEMADN} attributeID: 1.2.840.113556.1.4.7000.102.11019 attributeSyntax: 2.5.5.9 isSingleValued: TRUE showInAdvancedViewOnly: TRUE adminDisplayName: ms-Exch-ESE-Param-Preferred-Ver-Pages adminDescription: ms-Exch-ESE-Param-Preferred-Ver-Pages oMSyntax: 2 searchFlags: 0 lDAPDisplayName: msExchESEParamPreferredVerPages name: ms-Exch-ESE-Param-Preferred-Ver-Pages schemaIDGUID: a062f88c-b093-11d2-aa06-00c04f8eedd8 isMemberOfPartialAttributeSet: FALSE objectCategory: CN=Attribute-Schema,${SCHEMADN} # # ms-Exch-ESE-Param-Start-Flush-Threshold # dn: CN=ms-Exch-ESE-Param-Start-Flush-Threshold,${SCHEMADN} objectClass: top objectClass: attributeSchema cn: ms-Exch-ESE-Param-Start-Flush-Threshold distinguishedName: CN=ms-Exch-ESE-Param-Start-Flush-Threshold,${SCHEMADN} attributeID: 1.2.840.113556.1.4.7000.102.11056 attributeSyntax: 2.5.5.9 isSingleValued: TRUE showInAdvancedViewOnly: TRUE adminDisplayName: ms-Exch-ESE-Param-Start-Flush-Threshold adminDescription: ms-Exch-ESE-Param-Start-Flush-Threshold oMSyntax: 2 searchFlags: 0 lDAPDisplayName: msExchESEParamStartFlushThreshold name: ms-Exch-ESE-Param-Start-Flush-Threshold schemaIDGUID: 92abc93e-b09e-11d2-aa06-00c04f8eedd8 isMemberOfPartialAttributeSet: FALSE objectCategory: CN=Attribute-Schema,${SCHEMADN} # # ms-Exch-ESE-Param-Stop-Flush-Threshold # dn: CN=ms-Exch-ESE-Param-Stop-Flush-Threshold,${SCHEMADN} objectClass: top objectClass: attributeSchema cn: ms-Exch-ESE-Param-Stop-Flush-Threshold distinguishedName: CN=ms-Exch-ESE-Param-Stop-Flush-Threshold,${SCHEMADN} attributeID: 1.2.840.113556.1.4.7000.102.11057 attributeSyntax: 2.5.5.9 isSingleValued: TRUE showInAdvancedViewOnly: TRUE adminDisplayName: ms-Exch-ESE-Param-Stop-Flush-Threshold adminDescription: ms-Exch-ESE-Param-Stop-Flush-Threshold oMSyntax: 2 searchFlags: 0 lDAPDisplayName: msExchESEParamStopFlushThreshold name: ms-Exch-ESE-Param-Stop-Flush-Threshold schemaIDGUID: 92c6031c-b09e-11d2-aa06-00c04f8eedd8 isMemberOfPartialAttributeSet: FALSE objectCategory: CN=Attribute-Schema,${SCHEMADN} # # ms-Exch-ESE-Param-System-Path # The path to check point file. dn: CN=ms-Exch-ESE-Param-System-Path,${SCHEMADN} objectClass: top objectClass: attributeSchema cn: ms-Exch-ESE-Param-System-Path distinguishedName: CN=ms-Exch-ESE-Param-System-Path,${SCHEMADN} attributeID: 1.2.840.113556.1.4.7000.102.11022 attributeSyntax: 2.5.5.4 isSingleValued: TRUE showInAdvancedViewOnly: TRUE adminDisplayName: ms-Exch-ESE-Param-System-Path adminDescription: ms-Exch-ESE-Param-System-Path oMSyntax: 20 searchFlags: 0 lDAPDisplayName: msExchESEParamSystemPath name: ms-Exch-ESE-Param-System-Path schemaIDGUID: a086bbd2-b093-11d2-aa06-00c04f8eedd8 isMemberOfPartialAttributeSet: FALSE objectCategory: CN=Attribute-Schema,${SCHEMADN} # # ms-Exch-ESE-Param-Temp-Path # The path to the temporary database. # dn: CN=ms-Exch-ESE-Param-Temp-Path,${SCHEMADN} objectClass: top objectClass: attributeSchema cn: ms-Exch-ESE-Param-Temp-Path distinguishedName: CN=ms-Exch-ESE-Param-Temp-Path,${SCHEMADN} attributeID: 1.2.840.113556.1.4.7000.102.11023 attributeSyntax: 2.5.5.4 isSingleValued: TRUE showInAdvancedViewOnly: TRUE adminDisplayName: ms-Exch-ESE-Param-Temp-Path adminDescription: ms-Exch-ESE-Param-Temp-Path oMSyntax: 20 searchFlags: 0 lDAPDisplayName: msExchESEParamTempPath name: ms-Exch-ESE-Param-Temp-Path schemaIDGUID: a0a5ba64-b093-11d2-aa06-00c04f8eedd8 isMemberOfPartialAttributeSet: FALSE objectCategory: CN=Attribute-Schema,${SCHEMADN} # # ms-Exch-ESE-Param-Wait-Log-Flush # The wait time in milliseconds. # dn: CN=ms-Exch-ESE-Param-Wait-Log-Flush,${SCHEMADN} objectClass: top objectClass: attributeSchema cn: ms-Exch-ESE-Param-Wait-Log-Flush distinguishedName: CN=ms-Exch-ESE-Param-Wait-Log-Flush,${SCHEMADN} attributeID: 1.2.840.113556.1.4.7000.102.11016 attributeSyntax: 2.5.5.9 isSingleValued: TRUE showInAdvancedViewOnly: TRUE adminDisplayName: ms-Exch-ESE-Param-Wait-Log-Flush adminDescription: ms-Exch-ESE-Param-Wait-Log-Flush oMSyntax: 2 searchFlags: 0 lDAPDisplayName: msExchESEParamWaitLogFlush name: ms-Exch-ESE-Param-Wait-Log-Flush schemaIDGUID: a0c71b50-b093-11d2-aa06-00c04f8eedd8 isMemberOfPartialAttributeSet: FALSE objectCategory: CN=Attribute-Schema,${SCHEMADN} # # ms-Exch-ESE-Param-Zero-Database-During-Backup # Overwrites deleted records/long values during backup. # dn: CN=ms-Exch-ESE-Param-Zero-Database-During-Backup,${SCHEMADN} objectClass: top objectClass: attributeSchema cn: ms-Exch-ESE-Param-Zero-Database-During-Backup distinguishedName: CN=ms-Exch-ESE-Param-Zero-Database-During-Backup,${SCHEMADN} attributeID: 1.2.840.113556.1.4.7000.102.11026 attributeSyntax: 2.5.5.9 isSingleValued: TRUE showInAdvancedViewOnly: TRUE adminDisplayName: ms-Exch-ESE-Param-Zero-Database-During-Backup adminDescription: ms-Exch-ESE-Param-Zero-Database-During-Backup oMSyntax: 2 searchFlags: 0 lDAPDisplayName: msExchESEParamZeroDatabaseDuringBackup name: ms-Exch-ESE-Param-Zero-Database-During-Backup schemaIDGUID: a0e619e2-b093-11d2-aa06-00c04f8eedd8 isMemberOfPartialAttributeSet: FALSE objectCategory: CN=Attribute-Schema,${SCHEMADN} # # ms-Exch-Exchange-Server-Link # A link to an Exchange server that this object corresponds to. # dn: CN=ms-Exch-Exchange-Server-Link,${SCHEMADN} objectClass: top objectClass: attributeSchema cn: ms-Exch-Exchange-Server-Link distinguishedName: CN=ms-Exch-Exchange-Server-Link,${SCHEMADN} attributeID: 1.2.840.113556.1.4.7000.102.71 attributeSyntax: 2.5.5.1 isSingleValued: TRUE linkID: 1019 showInAdvancedViewOnly: TRUE adminDisplayName: ms-Exch-Exchange-Server-Link oMObjectClass:: KwwCh3McAIVK adminDescription: ms-Exch-Exchange-Server-Link oMSyntax: 127 searchFlags: 0 lDAPDisplayName: msExchExchangeServerLink name: ms-Exch-Exchange-Server-Link schemaIDGUID: a1051874-b093-11d2-aa06-00c04f8eedd8 systemFlags: 1 isMemberOfPartialAttributeSet: FALSE objectCategory: CN=Attribute-Schema,${SCHEMADN} # # ms-Exch-Exchange-Site # Contains the DN to the site that this connection agreement is for. # dn: CN=ms-Exch-Exchange-Site,${SCHEMADN} objectClass: top objectClass: attributeSchema cn: ms-Exch-Exchange-Site distinguishedName: CN=ms-Exch-Exchange-Site,${SCHEMADN} attributeID: 1.2.840.113556.1.4.7000.102.85 attributeSyntax: 2.5.5.12 isSingleValued: TRUE showInAdvancedViewOnly: TRUE adminDisplayName: ms-Exch-Exchange-Site adminDescription: ms-Exch-Exchange-Site oMSyntax: 64 searchFlags: 0 lDAPDisplayName: msExchExchangeSite name: ms-Exch-Exchange-Site schemaIDGUID: 24d808f5-2439-11d3-aa66-00c04f8eedd8 isMemberOfPartialAttributeSet: FALSE objectCategory: CN=Attribute-Schema,${SCHEMADN} # # ms-Exch-Expand-DLs-Locally # dn: CN=ms-Exch-Expand-DLs-Locally,${SCHEMADN} objectClass: top objectClass: attributeSchema cn: ms-Exch-Expand-DLs-Locally distinguishedName: CN=ms-Exch-Expand-DLs-Locally,${SCHEMADN} attributeID: 1.2.840.113556.1.2.201 attributeSyntax: 2.5.5.8 isSingleValued: TRUE mAPIID: 32932 showInAdvancedViewOnly: TRUE adminDisplayName: ms-Exch-Expand-DLs-Locally adminDescription: ms-Exch-Expand-DLs-Locally oMSyntax: 1 searchFlags: 0 lDAPDisplayName: expandDLsLocally name: ms-Exch-Expand-DLs-Locally schemaIDGUID: a8df73fb-c5ea-11d1-bbcb-0080c76670c0 isMemberOfPartialAttributeSet: FALSE objectCategory: CN=Attribute-Schema,${SCHEMADN} # # ms-Exch-Expansion-Server-Name # dn: CN=ms-Exch-Expansion-Server-Name,${SCHEMADN} objectClass: top objectClass: attributeSchema cn: ms-Exch-Expansion-Server-Name distinguishedName: CN=ms-Exch-Expansion-Server-Name,${SCHEMADN} attributeID: 1.2.840.113556.1.4.7000.102.49 attributeSyntax: 2.5.5.12 isSingleValued: TRUE showInAdvancedViewOnly: TRUE adminDisplayName: ms-Exch-Expansion-Server-Name adminDescription: ms-Exch-Expansion-Server-Name oMSyntax: 64 searchFlags: 0 lDAPDisplayName: msExchExpansionServerName name: ms-Exch-Expansion-Server-Name schemaIDGUID: a1241706-b093-11d2-aa06-00c04f8eedd8 attributeSecurityGUID: e48d0154-bcf8-11d1-8702-00c04fb96050 isMemberOfPartialAttributeSet: TRUE objectCategory: CN=Attribute-Schema,${SCHEMADN} # # ms-Exch-Expiration-Time # dn: CN=ms-Exch-Expiration-Time,${SCHEMADN} objectClass: top objectClass: attributeSchema cn: ms-Exch-Expiration-Time distinguishedName: CN=ms-Exch-Expiration-Time,${SCHEMADN} attributeID: 1.2.840.113556.1.2.394 attributeSyntax: 2.5.5.11 isSingleValued: TRUE mAPIID: 32808 showInAdvancedViewOnly: TRUE adminDisplayName: ms-Exch-Expiration-Time adminDescription: ms-Exch-Expiration-Time oMSyntax: 23 searchFlags: 1 lDAPDisplayName: expirationTime name: ms-Exch-Expiration-Time schemaIDGUID: bf967965-0de6-11d0-a285-00aa003049e2 attributeSecurityGUID: e48d0154-bcf8-11d1-8702-00c04fb96050 isMemberOfPartialAttributeSet: FALSE objectCategory: CN=Attribute-Schema,${SCHEMADN} # # ms-Exch-Export-Containers # dn: CN=ms-Exch-Export-Containers,${SCHEMADN} objectClass: top objectClass: attributeSchema cn: ms-Exch-Export-Containers distinguishedName: CN=ms-Exch-Export-Containers,${SCHEMADN} attributeID: 1.2.840.113556.1.2.111 attributeSyntax: 2.5.5.1 isSingleValued: FALSE mAPIID: 32933 showInAdvancedViewOnly: TRUE adminDisplayName: ms-Exch-Export-Containers oMObjectClass:: KwwCh3McAIVK adminDescription: ms-Exch-Export-Containers oMSyntax: 127 searchFlags: 0 lDAPDisplayName: exportContainers name: ms-Exch-Export-Containers schemaIDGUID: a8df73fc-c5ea-11d1-bbcb-0080c76670c0 isMemberOfPartialAttributeSet: FALSE objectCategory: CN=Attribute-Schema,${SCHEMADN} # # ms-Exch-Export-Containers-BL # dn: CN=ms-Exch-Export-Containers-BL,${SCHEMADN} objectClass: top objectClass: attributeSchema cn: ms-Exch-Export-Containers-BL distinguishedName: CN=ms-Exch-Export-Containers-BL,${SCHEMADN} attributeID: 1.2.840.113556.1.4.7000.102.1027 attributeSyntax: 2.5.5.1 isSingleValued: TRUE linkID: 1029 showInAdvancedViewOnly: TRUE adminDisplayName: ms-Exch-Export-Containers-BL oMObjectClass:: KwwCh3McAIVK adminDescription: ms-Exch-Export-Containers-BL oMSyntax: 127 searchFlags: 0 lDAPDisplayName: msExchExportContainersBL name: ms-Exch-Export-Containers-BL schemaIDGUID: 2436ac3e-1d4e-11d3-aa5e-00c04f8eedd8 systemFlags: 1 isMemberOfPartialAttributeSet: FALSE objectCategory: CN=Attribute-Schema,${SCHEMADN} # # ms-Exch-Export-Containers-Linked # dn: CN=ms-Exch-Export-Containers-Linked,${SCHEMADN} objectClass: top objectClass: attributeSchema cn: ms-Exch-Export-Containers-Linked distinguishedName: CN=ms-Exch-Export-Containers-Linked,${SCHEMADN} attributeID: 1.2.840.113556.1.4.7000.102.1026 attributeSyntax: 2.5.5.1 isSingleValued: FALSE linkID: 1028 showInAdvancedViewOnly: TRUE adminDisplayName: ms-Exch-Export-Containers-Linked oMObjectClass:: KwwCh3McAIVK adminDescription: ms-Exch-Export-Containers-Linked oMSyntax: 127 searchFlags: 0 lDAPDisplayName: msExchExportContainersLinked name: ms-Exch-Export-Containers-Linked schemaIDGUID: 3b7ea364-1d4d-11d3-aa5e-00c04f8eedd8 isMemberOfPartialAttributeSet: FALSE objectCategory: CN=Attribute-Schema,${SCHEMADN} # # ms-Exch-Export-Custom-Recipients # dn: CN=ms-Exch-Export-Custom-Recipients,${SCHEMADN} objectClass: top objectClass: attributeSchema cn: ms-Exch-Export-Custom-Recipients distinguishedName: CN=ms-Exch-Export-Custom-Recipients,${SCHEMADN} attributeID: 1.2.840.113556.1.2.307 attributeSyntax: 2.5.5.8 isSingleValued: TRUE mAPIID: 32934 showInAdvancedViewOnly: TRUE adminDisplayName: ms-Exch-Export-Custom-Recipients adminDescription: ms-Exch-Export-Custom-Recipients oMSyntax: 1 searchFlags: 0 lDAPDisplayName: exportCustomRecipients name: ms-Exch-Export-Custom-Recipients schemaIDGUID: a8df73fd-c5ea-11d1-bbcb-0080c76670c0 isMemberOfPartialAttributeSet: FALSE objectCategory: CN=Attribute-Schema,${SCHEMADN} # # ms-Exch-Export-DLs # A flag indicating whether distribution list (DL) names are # propagated to foreign systems via directory synchronization. # dn: CN=ms-Exch-Export-DLs,${SCHEMADN} objectClass: top objectClass: attributeSchema cn: ms-Exch-Export-DLs distinguishedName: CN=ms-Exch-Export-DLs,${SCHEMADN} attributeID: 1.2.840.113556.1.4.7000.102.1004 attributeSyntax: 2.5.5.8 isSingleValued: TRUE showInAdvancedViewOnly: TRUE adminDisplayName: ms-Exch-Export-DLs adminDescription: ms-Exch-Export-DLs oMSyntax: 1 searchFlags: 0 lDAPDisplayName: msExchExportDLs name: ms-Exch-Export-DLs schemaIDGUID: a14577f2-b093-11d2-aa06-00c04f8eedd8 isMemberOfPartialAttributeSet: FALSE objectCategory: CN=Attribute-Schema,${SCHEMADN} # # ms-Exch-Extension-Attribute-1 # dn: CN=ms-Exch-Extension-Attribute-1,${SCHEMADN} objectClass: top objectClass: attributeSchema cn: ms-Exch-Extension-Attribute-1 distinguishedName: CN=ms-Exch-Extension-Attribute-1,${SCHEMADN} attributeID: 1.2.840.113556.1.2.423 attributeSyntax: 2.5.5.12 isSingleValued: TRUE rangeLower: 1 rangeUpper: 1024 mAPIID: 32813 showInAdvancedViewOnly: TRUE adminDisplayName: ms-Exch-Extension-Attribute-1 adminDescription: ms-Exch-Extension-Attribute-1 oMSyntax: 64 searchFlags: 16 lDAPDisplayName: extensionAttribute1 name: ms-Exch-Extension-Attribute-1 schemaIDGUID: bf967967-0de6-11d0-a285-00aa003049e2 attributeSecurityGUID: e48d0154-bcf8-11d1-8702-00c04fb96050 isMemberOfPartialAttributeSet: TRUE objectCategory: CN=Attribute-Schema,${SCHEMADN} # # ms-Exch-Extension-Attribute-10 # dn: CN=ms-Exch-Extension-Attribute-10,${SCHEMADN} objectClass: top objectClass: attributeSchema cn: ms-Exch-Extension-Attribute-10 distinguishedName: CN=ms-Exch-Extension-Attribute-10,${SCHEMADN} attributeID: 1.2.840.113556.1.2.432 attributeSyntax: 2.5.5.12 isSingleValued: TRUE rangeLower: 1 rangeUpper: 1024 mAPIID: 32822 showInAdvancedViewOnly: TRUE adminDisplayName: ms-Exch-Extension-Attribute-10 adminDescription: ms-Exch-Extension-Attribute-10 oMSyntax: 64 searchFlags: 16 lDAPDisplayName: extensionAttribute10 name: ms-Exch-Extension-Attribute-10 schemaIDGUID: bf967968-0de6-11d0-a285-00aa003049e2 attributeSecurityGUID: e48d0154-bcf8-11d1-8702-00c04fb96050 isMemberOfPartialAttributeSet: TRUE objectCategory: CN=Attribute-Schema,${SCHEMADN} # # ms-Exch-Extension-Attribute-11 # dn: CN=ms-Exch-Extension-Attribute-11,${SCHEMADN} objectClass: top objectClass: attributeSchema cn: ms-Exch-Extension-Attribute-11 distinguishedName: CN=ms-Exch-Extension-Attribute-11,${SCHEMADN} attributeID: 1.2.840.113556.1.2.599 attributeSyntax: 2.5.5.12 isSingleValued: TRUE rangeLower: 1 rangeUpper: 2048 mAPIID: 35927 showInAdvancedViewOnly: TRUE adminDisplayName: ms-Exch-Extension-Attribute-11 adminDescription: ms-Exch-Extension-Attribute-11 oMSyntax: 64 searchFlags: 16 lDAPDisplayName: extensionAttribute11 name: ms-Exch-Extension-Attribute-11 schemaIDGUID: 167757f6-47f3-11d1-a9c3-0000f80367c1 attributeSecurityGUID: e48d0154-bcf8-11d1-8702-00c04fb96050 isMemberOfPartialAttributeSet: TRUE objectCategory: CN=Attribute-Schema,${SCHEMADN} # # ms-Exch-Extension-Attribute-12 # dn: CN=ms-Exch-Extension-Attribute-12,${SCHEMADN} objectClass: top objectClass: attributeSchema cn: ms-Exch-Extension-Attribute-12 distinguishedName: CN=ms-Exch-Extension-Attribute-12,${SCHEMADN} attributeID: 1.2.840.113556.1.2.600 attributeSyntax: 2.5.5.12 isSingleValued: TRUE rangeLower: 1 rangeUpper: 2048 mAPIID: 35928 showInAdvancedViewOnly: TRUE adminDisplayName: ms-Exch-Extension-Attribute-12 adminDescription: ms-Exch-Extension-Attribute-12 oMSyntax: 64 searchFlags: 16 lDAPDisplayName: extensionAttribute12 name: ms-Exch-Extension-Attribute-12 schemaIDGUID: 167757f7-47f3-11d1-a9c3-0000f80367c1 attributeSecurityGUID: e48d0154-bcf8-11d1-8702-00c04fb96050 isMemberOfPartialAttributeSet: TRUE objectCategory: CN=Attribute-Schema,${SCHEMADN} # # ms-Exch-Extension-Attribute-13 # dn: CN=ms-Exch-Extension-Attribute-13,${SCHEMADN} objectClass: top objectClass: attributeSchema cn: ms-Exch-Extension-Attribute-13 distinguishedName: CN=ms-Exch-Extension-Attribute-13,${SCHEMADN} attributeID: 1.2.840.113556.1.2.601 attributeSyntax: 2.5.5.12 isSingleValued: TRUE rangeLower: 1 rangeUpper: 2048 mAPIID: 35929 showInAdvancedViewOnly: TRUE adminDisplayName: ms-Exch-Extension-Attribute-13 adminDescription: ms-Exch-Extension-Attribute-13 oMSyntax: 64 searchFlags: 16 lDAPDisplayName: extensionAttribute13 name: ms-Exch-Extension-Attribute-13 schemaIDGUID: 167757f8-47f3-11d1-a9c3-0000f80367c1 attributeSecurityGUID: e48d0154-bcf8-11d1-8702-00c04fb96050 isMemberOfPartialAttributeSet: TRUE objectCategory: CN=Attribute-Schema,${SCHEMADN} # # ms-Exch-Extension-Attribute-14 Attribut # # # ms-Exch-Extension-Attribute-15 # dn: CN=ms-Exch-Extension-Attribute-15,${SCHEMADN} objectClass: top objectClass: attributeSchema cn: ms-Exch-Extension-Attribute-15 distinguishedName: CN=ms-Exch-Extension-Attribute-15,${SCHEMADN} attributeID: 1.2.840.113556.1.2.603 attributeSyntax: 2.5.5.12 isSingleValued: TRUE rangeLower: 1 rangeUpper: 2048 mAPIID: 35937 showInAdvancedViewOnly: TRUE adminDisplayName: ms-Exch-Extension-Attribute-15 adminDescription: ms-Exch-Extension-Attribute-15 oMSyntax: 64 searchFlags: 16 lDAPDisplayName: extensionAttribute15 name: ms-Exch-Extension-Attribute-15 schemaIDGUID: 167757fa-47f3-11d1-a9c3-0000f80367c1 attributeSecurityGUID: e48d0154-bcf8-11d1-8702-00c04fb96050 isMemberOfPartialAttributeSet: TRUE objectCategory: CN=Attribute-Schema,${SCHEMADN} # # ms-Exch-Extension-Attribute-2 # dn: CN=ms-Exch-Extension-Attribute-2,${SCHEMADN} objectClass: top objectClass: attributeSchema cn: ms-Exch-Extension-Attribute-2 distinguishedName: CN=ms-Exch-Extension-Attribute-2,${SCHEMADN} attributeID: 1.2.840.113556.1.2.424 attributeSyntax: 2.5.5.12 isSingleValued: TRUE rangeLower: 1 rangeUpper: 1024 mAPIID: 32814 showInAdvancedViewOnly: TRUE adminDisplayName: ms-Exch-Extension-Attribute-2 adminDescription: ms-Exch-Extension-Attribute-2 oMSyntax: 64 searchFlags: 16 lDAPDisplayName: extensionAttribute2 name: ms-Exch-Extension-Attribute-2 schemaIDGUID: bf967969-0de6-11d0-a285-00aa003049e2 attributeSecurityGUID: e48d0154-bcf8-11d1-8702-00c04fb96050 isMemberOfPartialAttributeSet: TRUE objectCategory: CN=Attribute-Schema,${SCHEMADN} # # ms-Exch-Extension-Attribute-3 # dn: CN=ms-Exch-Extension-Attribute-3,${SCHEMADN} objectClass: top objectClass: attributeSchema cn: ms-Exch-Extension-Attribute-3 distinguishedName: CN=ms-Exch-Extension-Attribute-3,${SCHEMADN} attributeID: 1.2.840.113556.1.2.425 attributeSyntax: 2.5.5.12 isSingleValued: TRUE rangeLower: 1 rangeUpper: 1024 mAPIID: 32815 showInAdvancedViewOnly: TRUE adminDisplayName: ms-Exch-Extension-Attribute-3 adminDescription: ms-Exch-Extension-Attribute-3 oMSyntax: 64 searchFlags: 16 lDAPDisplayName: extensionAttribute3 name: ms-Exch-Extension-Attribute-3 schemaIDGUID: bf96796a-0de6-11d0-a285-00aa003049e2 attributeSecurityGUID: e48d0154-bcf8-11d1-8702-00c04fb96050 isMemberOfPartialAttributeSet: TRUE objectCategory: CN=Attribute-Schema,${SCHEMADN} # # ms-Exch-Extension-Attribute-4 # dn: CN=ms-Exch-Extension-Attribute-4,${SCHEMADN} objectClass: top objectClass: attributeSchema cn: ms-Exch-Extension-Attribute-4 distinguishedName: CN=ms-Exch-Extension-Attribute-4,${SCHEMADN} attributeID: 1.2.840.113556.1.2.426 attributeSyntax: 2.5.5.12 isSingleValued: TRUE rangeLower: 1 rangeUpper: 1024 mAPIID: 32816 showInAdvancedViewOnly: TRUE adminDisplayName: ms-Exch-Extension-Attribute-4 adminDescription: ms-Exch-Extension-Attribute-4 oMSyntax: 64 searchFlags: 16 lDAPDisplayName: extensionAttribute4 name: ms-Exch-Extension-Attribute-4 schemaIDGUID: bf96796b-0de6-11d0-a285-00aa003049e2 attributeSecurityGUID: e48d0154-bcf8-11d1-8702-00c04fb96050 isMemberOfPartialAttributeSet: TRUE objectCategory: CN=Attribute-Schema,${SCHEMADN} # # ms-Exch-Extension-Attribute-5 # dn: CN=ms-Exch-Extension-Attribute-5,${SCHEMADN} objectClass: top objectClass: attributeSchema cn: ms-Exch-Extension-Attribute-5 distinguishedName: CN=ms-Exch-Extension-Attribute-5,${SCHEMADN} attributeID: 1.2.840.113556.1.2.427 attributeSyntax: 2.5.5.12 isSingleValued: TRUE rangeLower: 1 rangeUpper: 1024 mAPIID: 32817 showInAdvancedViewOnly: TRUE adminDisplayName: ms-Exch-Extension-Attribute-5 adminDescription: ms-Exch-Extension-Attribute-5 oMSyntax: 64 searchFlags: 16 lDAPDisplayName: extensionAttribute5 name: ms-Exch-Extension-Attribute-5 schemaIDGUID: bf96796c-0de6-11d0-a285-00aa003049e2 attributeSecurityGUID: e48d0154-bcf8-11d1-8702-00c04fb96050 isMemberOfPartialAttributeSet: TRUE objectCategory: CN=Attribute-Schema,${SCHEMADN} # # ms-Exch-Extension-Attribute-6 # dn: CN=ms-Exch-Extension-Attribute-6,${SCHEMADN} objectClass: top objectClass: attributeSchema cn: ms-Exch-Extension-Attribute-6 distinguishedName: CN=ms-Exch-Extension-Attribute-6,${SCHEMADN} attributeID: 1.2.840.113556.1.2.428 attributeSyntax: 2.5.5.12 isSingleValued: TRUE rangeLower: 1 rangeUpper: 1024 mAPIID: 32818 showInAdvancedViewOnly: TRUE adminDisplayName: ms-Exch-Extension-Attribute-6 adminDescription: ms-Exch-Extension-Attribute-6 oMSyntax: 64 searchFlags: 16 lDAPDisplayName: extensionAttribute6 name: ms-Exch-Extension-Attribute-6 schemaIDGUID: bf96796d-0de6-11d0-a285-00aa003049e2 attributeSecurityGUID: e48d0154-bcf8-11d1-8702-00c04fb96050 isMemberOfPartialAttributeSet: TRUE objectCategory: CN=Attribute-Schema,${SCHEMADN} # # ms-Exch-Extension-Attribute-7 # dn: CN=ms-Exch-Extension-Attribute-7,${SCHEMADN} objectClass: top objectClass: attributeSchema cn: ms-Exch-Extension-Attribute-7 distinguishedName: CN=ms-Exch-Extension-Attribute-7,${SCHEMADN} attributeID: 1.2.840.113556.1.2.429 attributeSyntax: 2.5.5.12 isSingleValued: TRUE rangeLower: 1 rangeUpper: 1024 mAPIID: 32819 showInAdvancedViewOnly: TRUE adminDisplayName: ms-Exch-Extension-Attribute-7 adminDescription: ms-Exch-Extension-Attribute-7 oMSyntax: 64 searchFlags: 16 lDAPDisplayName: extensionAttribute7 name: ms-Exch-Extension-Attribute-7 schemaIDGUID: bf96796e-0de6-11d0-a285-00aa003049e2 attributeSecurityGUID: e48d0154-bcf8-11d1-8702-00c04fb96050 isMemberOfPartialAttributeSet: TRUE objectCategory: CN=Attribute-Schema,${SCHEMADN} # # ms-Exch-Extension-Attribute-8 # dn: CN=ms-Exch-Extension-Attribute-8,${SCHEMADN} objectClass: top objectClass: attributeSchema cn: ms-Exch-Extension-Attribute-8 distinguishedName: CN=ms-Exch-Extension-Attribute-8,${SCHEMADN} attributeID: 1.2.840.113556.1.2.430 attributeSyntax: 2.5.5.12 isSingleValued: TRUE rangeLower: 1 rangeUpper: 1024 mAPIID: 32820 showInAdvancedViewOnly: TRUE adminDisplayName: ms-Exch-Extension-Attribute-8 adminDescription: ms-Exch-Extension-Attribute-8 oMSyntax: 64 searchFlags: 16 lDAPDisplayName: extensionAttribute8 name: ms-Exch-Extension-Attribute-8 schemaIDGUID: bf96796f-0de6-11d0-a285-00aa003049e2 attributeSecurityGUID: e48d0154-bcf8-11d1-8702-00c04fb96050 isMemberOfPartialAttributeSet: TRUE objectCategory: CN=Attribute-Schema,${SCHEMADN} # # ms-Exch-Extension-Attribute-9 # dn: CN=ms-Exch-Extension-Attribute-9,${SCHEMADN} objectClass: top objectClass: attributeSchema cn: ms-Exch-Extension-Attribute-9 distinguishedName: CN=ms-Exch-Extension-Attribute-9,${SCHEMADN} attributeID: 1.2.840.113556.1.2.431 attributeSyntax: 2.5.5.12 isSingleValued: TRUE rangeLower: 1 rangeUpper: 1024 mAPIID: 32821 showInAdvancedViewOnly: TRUE adminDisplayName: ms-Exch-Extension-Attribute-9 adminDescription: ms-Exch-Extension-Attribute-9 oMSyntax: 64 searchFlags: 16 lDAPDisplayName: extensionAttribute9 name: ms-Exch-Extension-Attribute-9 schemaIDGUID: bf967970-0de6-11d0-a285-00aa003049e2 attributeSecurityGUID: e48d0154-bcf8-11d1-8702-00c04fb96050 isMemberOfPartialAttributeSet: TRUE objectCategory: CN=Attribute-Schema,${SCHEMADN} # # ms-Exch-Extension-Data # dn: CN=ms-Exch-Extension-Data,${SCHEMADN} objectClass: top objectClass: attributeSchema cn: ms-Exch-Extension-Data distinguishedName: CN=ms-Exch-Extension-Data,${SCHEMADN} attributeID: 1.2.840.113556.1.2.228 attributeSyntax: 2.5.5.10 isSingleValued: FALSE rangeLower: 1 rangeUpper: 32768 mAPIID: 32936 showInAdvancedViewOnly: TRUE adminDisplayName: ms-Exch-Extension-Data adminDescription: ms-Exch-Extension-Data oMSyntax: 4 searchFlags: 0 lDAPDisplayName: extensionData name: ms-Exch-Extension-Data schemaIDGUID: bf967971-0de6-11d0-a285-00aa003049e2 attributeSecurityGUID: e48d0154-bcf8-11d1-8702-00c04fb96050 isMemberOfPartialAttributeSet: FALSE objectCategory: CN=Attribute-Schema,${SCHEMADN} # # ms-Exch-FB-URL # dn: CN=ms-Exch-FB-URL,${SCHEMADN} objectClass: top objectClass: attributeSchema cn: ms-Exch-FB-URL distinguishedName: CN=ms-Exch-FB-URL,${SCHEMADN} attributeID: 1.2.840.113556.1.4.7000.102.10001 attributeSyntax: 2.5.5.12 isSingleValued: TRUE mAPIID: 35966 showInAdvancedViewOnly: TRUE adminDisplayName: ms-Exch-FB-URL adminDescription: ms-Exch-FB-URL oMSyntax: 64 searchFlags: 1 lDAPDisplayName: msExchFBURL name: ms-Exch-FB-URL schemaIDGUID: a166d8de-b093-11d2-aa06-00c04f8eedd8 attributeSecurityGUID: e48d0154-bcf8-11d1-8702-00c04fb96050 isMemberOfPartialAttributeSet: TRUE objectCategory: CN=Attribute-Schema,${SCHEMADN} # # ms-Exch-File-Version # dn: CN=ms-Exch-File-Version,${SCHEMADN} objectClass: top objectClass: attributeSchema cn: ms-Exch-File-Version distinguishedName: CN=ms-Exch-File-Version,${SCHEMADN} attributeID: 1.2.840.113556.1.2.178 attributeSyntax: 2.5.5.10 isSingleValued: TRUE rangeLower: 1 rangeUpper: 8 mAPIID: 32940 showInAdvancedViewOnly: TRUE adminDisplayName: ms-Exch-File-Version adminDescription: ms-Exch-File-Version oMSyntax: 4 searchFlags: 0 lDAPDisplayName: fileVersion name: ms-Exch-File-Version schemaIDGUID: 167757fb-47f3-11d1-a9c3-0000f80367c1 isMemberOfPartialAttributeSet: FALSE objectCategory: CN=Attribute-Schema,${SCHEMADN} # # ms-Exch-Filter-Local-Addresses # dn: CN=ms-Exch-Filter-Local-Addresses,${SCHEMADN} objectClass: top objectClass: attributeSchema cn: ms-Exch-Filter-Local-Addresses distinguishedName: CN=ms-Exch-Filter-Local-Addresses,${SCHEMADN} attributeID: 1.2.840.113556.1.2.44 attributeSyntax: 2.5.5.8 isSingleValued: TRUE mAPIID: 32941 showInAdvancedViewOnly: TRUE adminDisplayName: ms-Exch-Filter-Local-Addresses adminDescription: ms-Exch-Filter-Local-Addresses oMSyntax: 1 searchFlags: 0 lDAPDisplayName: filterLocalAddresses name: ms-Exch-Filter-Local-Addresses schemaIDGUID: a8df73fe-c5ea-11d1-bbcb-0080c76670c0 isMemberOfPartialAttributeSet: FALSE objectCategory: CN=Attribute-Schema,${SCHEMADN} # # ms-Exch-First-Instance # dn: CN=ms-Exch-First-Instance,${SCHEMADN} objectClass: top objectClass: attributeSchema cn: ms-Exch-First-Instance distinguishedName: CN=ms-Exch-First-Instance,${SCHEMADN} attributeID: 1.2.840.113556.1.4.7000.102.11053 attributeSyntax: 2.5.5.8 isSingleValued: TRUE showInAdvancedViewOnly: TRUE adminDisplayName: ms-Exch-First-Instance adminDescription: ms-Exch-First-Instance oMSyntax: 1 searchFlags: 0 lDAPDisplayName: msExchFirstInstance name: ms-Exch-First-Instance schemaIDGUID: 8a8f2908-b09e-11d2-aa06-00c04f8eedd8 isMemberOfPartialAttributeSet: FALSE objectCategory: CN=Attribute-Schema,${SCHEMADN} # # ms-Exch-Folder-Affinity-Custom # dn: CN=ms-Exch-Folder-Affinity-Custom,${SCHEMADN} objectClass: top objectClass: attributeSchema cn: ms-Exch-Folder-Affinity-Custom distinguishedName: CN=ms-Exch-Folder-Affinity-Custom,${SCHEMADN} attributeID: 1.2.840.113556.1.4.7000.102.11090 attributeSyntax: 2.5.5.9 isSingleValued: TRUE showInAdvancedViewOnly: TRUE adminDisplayName: ms-Exch-Folder-Affinity-Custom adminDescription: ms-Exch-Folder-Affinity-Custom oMSyntax: 2 searchFlags: 0 lDAPDisplayName: msExchFolderAffinityCustom name: ms-Exch-Folder-Affinity-Custom schemaIDGUID: 5070257a-85b7-4ed4-b2e2-51f726684c58 isMemberOfPartialAttributeSet: FALSE objectCategory: CN=Attribute-Schema,${SCHEMADN} # # ms-Exch-Folder-Affinity-List # dn: CN=ms-Exch-Folder-Affinity-List,${SCHEMADN} objectClass: top objectClass: attributeSchema cn: ms-Exch-Folder-Affinity-List distinguishedName: CN=ms-Exch-Folder-Affinity-List,${SCHEMADN} attributeID: 1.2.840.113556.1.4.7000.102.11089 attributeSyntax: 2.5.5.12 isSingleValued: FALSE showInAdvancedViewOnly: TRUE adminDisplayName: ms-Exch-Folder-Affinity-List adminDescription: ms-Exch-Folder-Affinity-List oMSyntax: 64 searchFlags: 0 lDAPDisplayName: msExchFolderAffinityList name: ms-Exch-Folder-Affinity-List schemaIDGUID: 3592bc80-1117-4962-aa50-38c6e69bbb91 isMemberOfPartialAttributeSet: FALSE objectCategory: CN=Attribute-Schema,${SCHEMADN} # # ms-Exch-Folder-Pathname # dn: CN=ms-Exch-Folder-Pathname,${SCHEMADN} objectClass: top objectClass: attributeSchema cn: ms-Exch-Folder-Pathname distinguishedName: CN=ms-Exch-Folder-Pathname,${SCHEMADN} attributeID: 1.2.840.113556.1.2.337 attributeSyntax: 2.5.5.12 isSingleValued: TRUE rangeLower: 1 rangeUpper: 1024 mAPIID: 32772 showInAdvancedViewOnly: TRUE adminDisplayName: ms-Exch-Folder-Pathname adminDescription: ms-Exch-Folder-Pathname oMSyntax: 64 searchFlags: 0 lDAPDisplayName: folderPathname name: ms-Exch-Folder-Pathname schemaIDGUID: f0f8ff8d-1191-11d0-a060-00aa006c33ed attributeSecurityGUID: e48d0154-bcf8-11d1-8702-00c04fb96050 isMemberOfPartialAttributeSet: TRUE objectCategory: CN=Attribute-Schema,${SCHEMADN} # # ms-Exch-Form-Data # dn: CN=ms-Exch-Form-Data,${SCHEMADN} objectClass: top objectClass: attributeSchema cn: ms-Exch-Form-Data distinguishedName: CN=ms-Exch-Form-Data,${SCHEMADN} attributeID: 1.2.840.113556.1.2.607 attributeSyntax: 2.5.5.10 isSingleValued: TRUE mAPIID: 35941 showInAdvancedViewOnly: TRUE adminDisplayName: ms-Exch-Form-Data adminDescription: ms-Exch-Form-Data oMSyntax: 4 searchFlags: 0 lDAPDisplayName: formData name: ms-Exch-Form-Data schemaIDGUID: a8df7400-c5ea-11d1-bbcb-0080c76670c0 attributeSecurityGUID: e48d0154-bcf8-11d1-8702-00c04fb96050 isMemberOfPartialAttributeSet: FALSE objectCategory: CN=Attribute-Schema,${SCHEMADN} # # ms-Exch-Forwarding-Address # Contains an SMTP address that should be used as the mail forwarding # address of the object. # dn: CN=ms-Exch-Forwarding-Address,${SCHEMADN} objectClass: top objectClass: attributeSchema cn: ms-Exch-Forwarding-Address distinguishedName: CN=ms-Exch-Forwarding-Address,${SCHEMADN} attributeID: 1.2.840.113556.1.2.606 attributeSyntax: 2.5.5.12 isSingleValued: TRUE rangeLower: 1 rangeUpper: 256 mAPIID: 35940 showInAdvancedViewOnly: TRUE adminDisplayName: ms-Exch-Forwarding-Address adminDescription: ms-Exch-Forwarding-Address oMSyntax: 64 searchFlags: 0 lDAPDisplayName: forwardingAddress name: ms-Exch-Forwarding-Address schemaIDGUID: 167757ff-47f3-11d1-a9c3-0000f80367c1 attributeSecurityGUID: e48d0154-bcf8-11d1-8702-00c04fb96050 isMemberOfPartialAttributeSet: FALSE objectCategory: CN=Attribute-Schema,${SCHEMADN} # # ms-Exch-Gateway-Local-Cred # dn: CN=ms-Exch-Gateway-Local-Cred,${SCHEMADN} objectClass: top objectClass: attributeSchema cn: ms-Exch-Gateway-Local-Cred distinguishedName: CN=ms-Exch-Gateway-Local-Cred,${SCHEMADN} attributeID: 1.2.840.113556.1.2.37 attributeSyntax: 2.5.5.5 isSingleValued: TRUE rangeLower: 1 rangeUpper: 64 mAPIID: 32944 showInAdvancedViewOnly: TRUE adminDisplayName: ms-Exch-Gateway-Local-Cred adminDescription: ms-Exch-Gateway-Local-Cred oMSyntax: 22 searchFlags: 0 lDAPDisplayName: gatewayLocalCred name: ms-Exch-Gateway-Local-Cred schemaIDGUID: a8df7401-c5ea-11d1-bbcb-0080c76670c0 isMemberOfPartialAttributeSet: FALSE objectCategory: CN=Attribute-Schema,${SCHEMADN} # # ms-Exch-Gateway-Local-Desig # dn: CN=ms-Exch-Gateway-Local-Desig,${SCHEMADN} objectClass: top objectClass: attributeSchema cn: ms-Exch-Gateway-Local-Desig distinguishedName: CN=ms-Exch-Gateway-Local-Desig,${SCHEMADN} attributeID: 1.2.840.113556.1.2.29 attributeSyntax: 2.5.5.5 isSingleValued: TRUE rangeLower: 1 rangeUpper: 32 mAPIID: 32945 showInAdvancedViewOnly: TRUE adminDisplayName: ms-Exch-Gateway-Local-Desig adminDescription: ms-Exch-Gateway-Local-Desig oMSyntax: 22 searchFlags: 0 lDAPDisplayName: gatewayLocalDesig name: ms-Exch-Gateway-Local-Desig schemaIDGUID: a8df7402-c5ea-11d1-bbcb-0080c76670c0 isMemberOfPartialAttributeSet: FALSE objectCategory: CN=Attribute-Schema,${SCHEMADN} # # ms-Exch-Gateway-Proxy # dn: CN=ms-Exch-Gateway-Proxy,${SCHEMADN} objectClass: top objectClass: attributeSchema cn: ms-Exch-Gateway-Proxy distinguishedName: CN=ms-Exch-Gateway-Proxy,${SCHEMADN} attributeID: 1.2.840.113556.1.2.302 attributeSyntax: 2.5.5.12 isSingleValued: FALSE rangeLower: 1 rangeUpper: 1123 mAPIID: 32946 showInAdvancedViewOnly: TRUE adminDisplayName: ms-Exch-Gateway-Proxy adminDescription: ms-Exch-Gateway-Proxy oMSyntax: 64 searchFlags: 0 lDAPDisplayName: gatewayProxy name: ms-Exch-Gateway-Proxy schemaIDGUID: 16775802-47f3-11d1-a9c3-0000f80367c1 isMemberOfPartialAttributeSet: FALSE objectCategory: CN=Attribute-Schema,${SCHEMADN} # # ms-Exch-Gateway-Routing-Tree # Contains the Gateway Address Resolution Table (GWART) for the site. # dn: CN=ms-Exch-Gateway-Routing-Tree,${SCHEMADN} objectClass: top objectClass: attributeSchema cn: ms-Exch-Gateway-Routing-Tree distinguishedName: CN=ms-Exch-Gateway-Routing-Tree,${SCHEMADN} attributeID: 1.2.840.113556.1.2.167 attributeSyntax: 2.5.5.10 isSingleValued: TRUE mAPIID: 32947 showInAdvancedViewOnly: TRUE adminDisplayName: ms-Exch-Gateway-Routing-Tree adminDescription: ms-Exch-Gateway-Routing-Tree oMSyntax: 4 searchFlags: 0 lDAPDisplayName: gatewayRoutingTree name: ms-Exch-Gateway-Routing-Tree schemaIDGUID: a8df7403-c5ea-11d1-bbcb-0080c76670c0 isMemberOfPartialAttributeSet: FALSE objectCategory: CN=Attribute-Schema,${SCHEMADN} # # ms-Exch-Grace-Period-After # Defines a period, in seconds, for which the conference allows # attendees to continue after the scheduled termination. # dn: CN=ms-Exch-Grace-Period-After,${SCHEMADN} objectClass: top objectClass: attributeSchema cn: ms-Exch-Grace-Period-After distinguishedName: CN=ms-Exch-Grace-Period-After,${SCHEMADN} attributeID: 1.2.840.113556.1.4.7000.102.9003 attributeSyntax: 2.5.5.9 isSingleValued: TRUE showInAdvancedViewOnly: TRUE adminDisplayName: ms-Exch-Grace-Period-After adminDescription: ms-Exch-Grace-Period-After oMSyntax: 2 searchFlags: 0 lDAPDisplayName: msExchGracePeriodAfter name: ms-Exch-Grace-Period-After schemaIDGUID: a1d6e764-b093-11d2-aa06-00c04f8eedd8 isMemberOfPartialAttributeSet: FALSE objectCategory: CN=Attribute-Schema,${SCHEMADN} # # ms-Exch-Grace-Period-Prior # Defines a period, in seconds, for which clients are accepted into a # conference prior to the scheduled start time. # dn: CN=ms-Exch-Grace-Period-Prior,${SCHEMADN} objectClass: top objectClass: attributeSchema cn: ms-Exch-Grace-Period-Prior distinguishedName: CN=ms-Exch-Grace-Period-Prior,${SCHEMADN} attributeID: 1.2.840.113556.1.4.7000.102.9002 attributeSyntax: 2.5.5.9 isSingleValued: TRUE showInAdvancedViewOnly: TRUE adminDisplayName: ms-Exch-Grace-Period-Prior adminDescription: ms-Exch-Grace-Period-Prior oMSyntax: 2 searchFlags: 0 lDAPDisplayName: msExchGracePeriodPrior name: ms-Exch-Grace-Period-Prior schemaIDGUID: a1f84850-b093-11d2-aa06-00c04f8eedd8 isMemberOfPartialAttributeSet: FALSE objectCategory: CN=Attribute-Schema,${SCHEMADN} # # ms-Exch-GWART-Last-Modified # Contains the time the Gateway Address Resolution Table (GWART) was # last modified. # dn: CN=ms-Exch-GWART-Last-Modified,${SCHEMADN} objectClass: top objectClass: attributeSchema cn: ms-Exch-GWART-Last-Modified distinguishedName: CN=ms-Exch-GWART-Last-Modified,${SCHEMADN} attributeID: 1.2.840.113556.1.2.260 attributeSyntax: 2.5.5.11 isSingleValued: TRUE mAPIID: 32948 showInAdvancedViewOnly: TRUE adminDisplayName: ms-Exch-GWART-Last-Modified adminDescription: ms-Exch-GWART-Last-Modified oMSyntax: 23 searchFlags: 0 lDAPDisplayName: gWARTLastModified name: ms-Exch-GWART-Last-Modified schemaIDGUID: 8fa43470-b093-11d2-aa06-00c04f8eedd8 isMemberOfPartialAttributeSet: FALSE objectCategory: CN=Attribute-Schema,${SCHEMADN} # # ms-Exch-GWise-API-Gateway # dn: CN=ms-Exch-GWise-API-Gateway,${SCHEMADN} objectClass: top objectClass: attributeSchema cn: ms-Exch-GWise-API-Gateway distinguishedName: CN=ms-Exch-GWise-API-Gateway,${SCHEMADN} attributeID: 1.2.840.113556.1.4.7000.102.1045 attributeSyntax: 2.5.5.12 isSingleValued: TRUE showInAdvancedViewOnly: TRUE adminDisplayName: ms-Exch-GWise-API-Gateway adminDescription: ms-Exch-GWise-API-Gateway oMSyntax: 64 searchFlags: 0 lDAPDisplayName: msExchGWiseAPIGateway name: ms-Exch-GWise-API-Gateway schemaIDGUID: c7e96933-bd80-44a2-a535-ec744ea5f54f isMemberOfPartialAttributeSet: FALSE objectCategory: CN=Attribute-Schema,${SCHEMADN} # # ms-Exch-GWise-API-Gateway-Path # dn: CN=ms-Exch-GWise-API-Gateway-Path,${SCHEMADN} objectClass: top objectClass: attributeSchema cn: ms-Exch-GWise-API-Gateway-Path distinguishedName: CN=ms-Exch-GWise-API-Gateway-Path,${SCHEMADN} attributeID: 1.2.840.113556.1.4.7000.102.1201 attributeSyntax: 2.5.5.12 isSingleValued: TRUE showInAdvancedViewOnly: TRUE adminDisplayName: ms-Exch-GWise-API-Gateway-Path adminDescription: ms-Exch-GWise-API-Gateway-Path oMSyntax: 64 searchFlags: 0 lDAPDisplayName: msExchGWiseAPIGatewayPath name: ms-Exch-GWise-API-Gateway-Path schemaIDGUID: 3b9d8dea-2d93-11d3-aa6b-00c04f8eedd8 isMemberOfPartialAttributeSet: FALSE objectCategory: CN=Attribute-Schema,${SCHEMADN} # # ms-Exch-GWise-Filter-Type # dn: CN=ms-Exch-GWise-Filter-Type,${SCHEMADN} objectClass: top objectClass: attributeSchema cn: ms-Exch-GWise-Filter-Type distinguishedName: CN=ms-Exch-GWise-Filter-Type,${SCHEMADN} attributeID: 1.2.840.113556.1.4.7000.102.1205 attributeSyntax: 2.5.5.9 isSingleValued: TRUE showInAdvancedViewOnly: TRUE adminDisplayName: ms-Exch-GWise-Filter-Type adminDescription: ms-Exch-GWise-Filter-Type oMSyntax: 2 searchFlags: 0 lDAPDisplayName: msExchGWiseFilterType name: ms-Exch-GWise-Filter-Type schemaIDGUID: 3b9d8dee-2d93-11d3-aa6b-00c04f8eedd8 isMemberOfPartialAttributeSet: FALSE objectCategory: CN=Attribute-Schema,${SCHEMADN} # # ms-Exch-GWise-Foreign-Domain # dn: CN=ms-Exch-GWise-Foreign-Domain,${SCHEMADN} objectClass: top objectClass: attributeSchema cn: ms-Exch-GWise-Foreign-Domain distinguishedName: CN=ms-Exch-GWise-Foreign-Domain,${SCHEMADN} attributeID: 1.2.840.113556.1.4.7000.102.1204 attributeSyntax: 2.5.5.12 isSingleValued: TRUE showInAdvancedViewOnly: TRUE adminDisplayName: ms-Exch-GWise-Foreign-Domain adminDescription: ms-Exch-GWise-Foreign-Domain oMSyntax: 64 searchFlags: 0 lDAPDisplayName: msExchGWiseForeignDomain name: ms-Exch-GWise-Foreign-Domain schemaIDGUID: 3b9d8df3-2d93-11d3-aa6b-00c04f8eedd8 isMemberOfPartialAttributeSet: FALSE objectCategory: CN=Attribute-Schema,${SCHEMADN} # # ms-Exch-GWise-Password # dn: CN=ms-Exch-GWise-Password,${SCHEMADN} objectClass: top objectClass: attributeSchema cn: ms-Exch-GWise-Password distinguishedName: CN=ms-Exch-GWise-Password,${SCHEMADN} attributeID: 1.2.840.113556.1.4.7000.102.1203 attributeSyntax: 2.5.5.10 isSingleValued: TRUE showInAdvancedViewOnly: TRUE adminDisplayName: ms-Exch-GWise-Password adminDescription: ms-Exch-GWise-Password oMSyntax: 4 searchFlags: 0 lDAPDisplayName: msExchGWisePassword name: ms-Exch-GWise-Password schemaIDGUID: 3b9d8df9-2d93-11d3-aa6b-00c04f8eedd8 isMemberOfPartialAttributeSet: FALSE objectCategory: CN=Attribute-Schema,${SCHEMADN} # # ms-Exch-GWise-User-Id # dn: CN=ms-Exch-GWise-User-Id,${SCHEMADN} objectClass: top objectClass: attributeSchema cn: ms-Exch-GWise-User-Id distinguishedName: CN=ms-Exch-GWise-User-Id,${SCHEMADN} attributeID: 1.2.840.113556.1.4.7000.102.1202 attributeSyntax: 2.5.5.12 isSingleValued: TRUE showInAdvancedViewOnly: TRUE adminDisplayName: ms-Exch-GWise-User-Id adminDescription: ms-Exch-GWise-User-Id oMSyntax: 64 searchFlags: 0 lDAPDisplayName: msExchGWiseUserId name: ms-Exch-GWise-User-Id schemaIDGUID: 3b9d8e00-2d93-11d3-aa6b-00c04f8eedd8 isMemberOfPartialAttributeSet: FALSE objectCategory: CN=Attribute-Schema,${SCHEMADN} # # ms-Exch-Heuristics # Contains special connector attributes, such as "allow system # messages". # dn: CN=ms-Exch-Heuristics,${SCHEMADN} objectClass: top objectClass: attributeSchema cn: ms-Exch-Heuristics distinguishedName: CN=ms-Exch-Heuristics,${SCHEMADN} attributeID: 1.2.840.113556.1.2.452 attributeSyntax: 2.5.5.9 isSingleValued: TRUE mAPIID: 32951 showInAdvancedViewOnly: TRUE adminDisplayName: ms-Exch-Heuristics adminDescription: ms-Exch-Heuristics oMSyntax: 2 searchFlags: 0 lDAPDisplayName: heuristics name: ms-Exch-Heuristics schemaIDGUID: bf967983-0de6-11d0-a285-00aa003049e2 attributeSecurityGUID: e48d0154-bcf8-11d1-8702-00c04fb96050 isMemberOfPartialAttributeSet: TRUE objectCategory: CN=Attribute-Schema,${SCHEMADN} # # ms-Exch-Hide-DL-Membership # dn: CN=ms-Exch-Hide-DL-Membership,${SCHEMADN} objectClass: top objectClass: attributeSchema cn: ms-Exch-Hide-DL-Membership distinguishedName: CN=ms-Exch-Hide-DL-Membership,${SCHEMADN} attributeID: 1.2.840.113556.1.2.297 attributeSyntax: 2.5.5.8 isSingleValued: TRUE mAPIID: 32952 showInAdvancedViewOnly: TRUE adminDisplayName: ms-Exch-Hide-DL-Membership adminDescription: ms-Exch-Hide-DL-Membership oMSyntax: 1 searchFlags: 0 lDAPDisplayName: hideDLMembership name: ms-Exch-Hide-DL-Membership schemaIDGUID: a8df7405-c5ea-11d1-bbcb-0080c76670c0 attributeSecurityGUID: e48d0154-bcf8-11d1-8702-00c04fb96050 isMemberOfPartialAttributeSet: TRUE objectCategory: CN=Attribute-Schema,${SCHEMADN} # # ms-Exch-Hide-From-Address-Lists # Determines if the recipient appears in address lists. # dn: CN=ms-Exch-Hide-From-Address-Lists,${SCHEMADN} objectClass: top objectClass: attributeSchema cn: ms-Exch-Hide-From-Address-Lists distinguishedName: CN=ms-Exch-Hide-From-Address-Lists,${SCHEMADN} attributeID: 1.2.840.113556.1.4.7000.102.73 attributeSyntax: 2.5.5.8 isSingleValued: TRUE showInAdvancedViewOnly: TRUE adminDisplayName: ms-Exch-Hide-From-Address-Lists adminDescription: ms-Exch-Hide-From-Address-Lists oMSyntax: 1 searchFlags: 16 lDAPDisplayName: msExchHideFromAddressLists name: ms-Exch-Hide-From-Address-Lists schemaIDGUID: a21c0b96-b093-11d2-aa06-00c04f8eedd8 attributeSecurityGUID: e48d0154-bcf8-11d1-8702-00c04fb96050 isMemberOfPartialAttributeSet: TRUE objectCategory: CN=Attribute-Schema,${SCHEMADN} # # ms-Exch-Home-MDB # The distinguished name of the MDB for this mailbox. # dn: CN=ms-Exch-Home-MDB,${SCHEMADN} objectClass: top objectClass: attributeSchema cn: ms-Exch-Home-MDB distinguishedName: CN=ms-Exch-Home-MDB,${SCHEMADN} attributeID: 1.2.840.113556.1.2.244 attributeSyntax: 2.5.5.1 isSingleValued: TRUE mAPIID: 32774 linkID: 32 showInAdvancedViewOnly: TRUE adminDisplayName: ms-Exch-Home-MDB oMObjectClass:: KwwCh3McAIVK adminDescription: ms-Exch-Home-MDB oMSyntax: 127 searchFlags: 0 lDAPDisplayName: homeMDB name: ms-Exch-Home-MDB schemaIDGUID: bf967987-0de6-11d0-a285-00aa003049e2 attributeSecurityGUID: e48d0154-bcf8-11d1-8702-00c04fb96050 isMemberOfPartialAttributeSet: TRUE objectCategory: CN=Attribute-Schema,${SCHEMADN} # # ms-Exch-Home-MDB-BL # dn: CN=ms-Exch-Home-MDB-BL,${SCHEMADN} objectClass: top objectClass: attributeSchema cn: ms-Exch-Home-MDB-BL distinguishedName: CN=ms-Exch-Home-MDB-BL,${SCHEMADN} attributeID: 1.2.840.113556.1.2.393 attributeSyntax: 2.5.5.1 isSingleValued: FALSE mAPIID: 32788 linkID: 33 showInAdvancedViewOnly: TRUE adminDisplayName: ms-Exch-Home-MDB-BL oMObjectClass:: KwwCh3McAIVK adminDescription: ms-Exch-Home-MDB-BL oMSyntax: 127 searchFlags: 0 lDAPDisplayName: homeMDBBL name: ms-Exch-Home-MDB-BL schemaIDGUID: bf967988-0de6-11d0-a285-00aa003049e2 systemFlags: 1 isMemberOfPartialAttributeSet: TRUE objectCategory: CN=Attribute-Schema,${SCHEMADN} # # ms-Exch-Home-MTA # Points to the MTA that services this object. # dn: CN=ms-Exch-Home-MTA,${SCHEMADN} objectClass: top objectClass: attributeSchema cn: ms-Exch-Home-MTA distinguishedName: CN=ms-Exch-Home-MTA,${SCHEMADN} attributeID: 1.2.840.113556.1.2.171 attributeSyntax: 2.5.5.1 isSingleValued: TRUE mAPIID: 32775 showInAdvancedViewOnly: TRUE adminDisplayName: ms-Exch-Home-MTA oMObjectClass:: KwwCh3McAIVK adminDescription: ms-Exch-Home-MTA oMSyntax: 127 searchFlags: 0 lDAPDisplayName: homeMTA name: ms-Exch-Home-MTA schemaIDGUID: bf967989-0de6-11d0-a285-00aa003049e2 attributeSecurityGUID: e48d0154-bcf8-11d1-8702-00c04fb96050 isMemberOfPartialAttributeSet: TRUE objectCategory: CN=Attribute-Schema,${SCHEMADN} # # ms-Exch-Home-Public-MDB # The DN of the object for the home public MDB. # dn: CN=ms-Exch-Home-Public-MDB,${SCHEMADN} objectClass: top objectClass: attributeSchema cn: ms-Exch-Home-Public-MDB distinguishedName: CN=ms-Exch-Home-Public-MDB,${SCHEMADN} attributeID: 1.2.840.113556.1.4.7000.102.11044 attributeSyntax: 2.5.5.1 isSingleValued: TRUE showInAdvancedViewOnly: TRUE adminDisplayName: ms-Exch-Home-Public-MDB oMObjectClass:: KwwCh3McAIVK adminDescription: ms-Exch-Home-Public-MDB oMSyntax: 127 searchFlags: 0 lDAPDisplayName: msExchHomePublicMDB name: ms-Exch-Home-Public-MDB schemaIDGUID: a23fcedc-b093-11d2-aa06-00c04f8eedd8 isMemberOfPartialAttributeSet: FALSE objectCategory: CN=Attribute-Schema,${SCHEMADN} # # ms-Exch-Home-Routing-Group # dn: CN=ms-Exch-Home-Routing-Group,${SCHEMADN} objectClass: top objectClass: attributeSchema cn: ms-Exch-Home-Routing-Group distinguishedName: CN=ms-Exch-Home-Routing-Group,${SCHEMADN} attributeID: 1.2.840.113556.1.4.7000.102.12539 attributeSyntax: 2.5.5.1 isSingleValued: TRUE linkID: 1050 showInAdvancedViewOnly: TRUE adminDisplayName: ms-Exch-Home-Routing-Group oMObjectClass:: KwwCh3McAIVK adminDescription: ms-Exch-Home-Routing-Group oMSyntax: 127 searchFlags: 1 lDAPDisplayName: msExchHomeRoutingGroup name: ms-Exch-Home-Routing-Group schemaIDGUID: f649deed-1c26-4ed4-b639-f333a4850bc2 isMemberOfPartialAttributeSet: FALSE objectCategory: CN=Attribute-Schema,${SCHEMADN} # # ms-Exch-Home-Routing-Group-DN-BL # A backlink to the routing group that this object is a member of. # dn: CN=ms-Exch-Home-Routing-Group-DN-BL,${SCHEMADN} objectClass: top objectClass: attributeSchema cn: ms-Exch-Home-Routing-Group-DN-BL distinguishedName: CN=ms-Exch-Home-Routing-Group-DN-BL,${SCHEMADN} attributeID: 1.2.840.113556.1.4.7000.102.12513 attributeSyntax: 2.5.5.1 isSingleValued: TRUE linkID: 1001 showInAdvancedViewOnly: TRUE adminDisplayName: ms-Exch-Home-Routing-Group-DN-BL oMObjectClass:: KwwCh3McAIVK adminDescription: ms-Exch-Home-Routing-Group-DN-BL oMSyntax: 127 searchFlags: 0 lDAPDisplayName: msExchHomeRoutingGroupDNBL name: ms-Exch-Home-Routing-Group-DN-BL schemaIDGUID: a2612fc8-b093-11d2-aa06-00c04f8eedd8 systemFlags: 1 isMemberOfPartialAttributeSet: FALSE objectCategory: CN=Attribute-Schema,${SCHEMADN} # # ms-Exch-Home-Server-Name # dn: CN=ms-Exch-Home-Server-Name,${SCHEMADN} objectClass: top objectClass: attributeSchema cn: ms-Exch-Home-Server-Name distinguishedName: CN=ms-Exch-Home-Server-Name,${SCHEMADN} attributeID: 1.2.840.113556.1.4.7000.102.47 attributeSyntax: 2.5.5.12 isSingleValued: TRUE showInAdvancedViewOnly: TRUE adminDisplayName: ms-Exch-Home-Server-Name adminDescription: ms-Exch-Home-Server-Name oMSyntax: 64 searchFlags: 25 lDAPDisplayName: msExchHomeServerName name: ms-Exch-Home-Server-Name schemaIDGUID: a284f30e-b093-11d2-aa06-00c04f8eedd8 attributeSecurityGUID: e48d0154-bcf8-11d1-8702-00c04fb96050 isMemberOfPartialAttributeSet: TRUE objectCategory: CN=Attribute-Schema,${SCHEMADN} # # ms-Exch-Home-Sync-Service # Link to the Active Directory Connector (ADC) for this connection # agreement. # dn: CN=ms-Exch-Home-Sync-Service,${SCHEMADN} objectClass: top objectClass: attributeSchema cn: ms-Exch-Home-Sync-Service distinguishedName: CN=ms-Exch-Home-Sync-Service,${SCHEMADN} attributeID: 1.2.840.113556.1.4.7000.102.36 attributeSyntax: 2.5.5.1 isSingleValued: TRUE linkID: 146 showInAdvancedViewOnly: TRUE adminDisplayName: ms-Exch-Home-Sync-Service oMObjectClass:: KwwCh3McAIVK adminDescription: ms-Exch-Home-Sync-Service oMSyntax: 127 searchFlags: 0 lDAPDisplayName: msExchHomeSyncService name: ms-Exch-Home-Sync-Service schemaIDGUID: a2a3f1a0-b093-11d2-aa06-00c04f8eedd8 isMemberOfPartialAttributeSet: FALSE objectCategory: CN=Attribute-Schema,${SCHEMADN} # # ms-Exch-House-Identifier # #dn: CN=ms-Exch-House-Identifier,${SCHEMADN} #objectClass: top #objectClass: attributeSchema #cn: ms-Exch-House-Identifier #distinguishedName: CN=ms-Exch-House-Identifier,${SCHEMADN} #attributeID: 1.2.840.113556.1.2.596 #attributeSyntax: 2.5.5.12 #isSingleValued: TRUE #rangeLower: 1 #rangeUpper: 128 #mAPIID: 35924 #adminDisplayName: ms-Exch-House-Identifier #adminDescription: ms-Exch-House-Identifier #oMSyntax: 64 #searchFlags: 0 #lDAPDisplayName: msExchHouseIdentifier #name: ms-Exch-House-Identifier #schemaIDGUID: a8df7407-c5ea-11d1-bbcb-0080c76670c0 #objectCategory: CN=Attribute-Schema,${SCHEMADN} # # ms-Exch-HTTP-Pub-AB-Attributes # dn: CN=ms-Exch-HTTP-Pub-AB-Attributes,${SCHEMADN} objectClass: top objectClass: attributeSchema cn: ms-Exch-HTTP-Pub-AB-Attributes distinguishedName: CN=ms-Exch-HTTP-Pub-AB-Attributes,${SCHEMADN} attributeID: 1.2.840.113556.1.2.516 attributeSyntax: 2.5.5.12 isSingleValued: FALSE rangeLower: 1 rangeUpper: 128 mAPIID: 33193 showInAdvancedViewOnly: TRUE adminDisplayName: ms-Exch-HTTP-Pub-AB-Attributes adminDescription: ms-Exch-HTTP-Pub-AB-Attributes oMSyntax: 64 searchFlags: 0 lDAPDisplayName: hTTPPubABAttributes name: ms-Exch-HTTP-Pub-AB-Attributes schemaIDGUID: a8df7408-c5ea-11d1-bbcb-0080c76670c0 isMemberOfPartialAttributeSet: FALSE objectCategory: CN=Attribute-Schema,${SCHEMADN} # # ms-Exch-HTTP-Pub-GAL # dn: CN=ms-Exch-HTTP-Pub-GAL,${SCHEMADN} objectClass: top objectClass: attributeSchema cn: ms-Exch-HTTP-Pub-GAL distinguishedName: CN=ms-Exch-HTTP-Pub-GAL,${SCHEMADN} attributeID: 1.2.840.113556.1.2.502 attributeSyntax: 2.5.5.8 isSingleValued: TRUE mAPIID: 33179 showInAdvancedViewOnly: TRUE adminDisplayName: ms-Exch-HTTP-Pub-GAL adminDescription: ms-Exch-HTTP-Pub-GAL oMSyntax: 1 searchFlags: 0 lDAPDisplayName: hTTPPubGAL name: ms-Exch-HTTP-Pub-GAL schemaIDGUID: a8df7409-c5ea-11d1-bbcb-0080c76670c0 isMemberOfPartialAttributeSet: FALSE objectCategory: CN=Attribute-Schema,${SCHEMADN} # # ms-Exch-HTTP-Pub-GAL-Limit # dn: CN=ms-Exch-HTTP-Pub-GAL-Limit,${SCHEMADN} objectClass: top objectClass: attributeSchema cn: ms-Exch-HTTP-Pub-GAL-Limit distinguishedName: CN=ms-Exch-HTTP-Pub-GAL-Limit,${SCHEMADN} attributeID: 1.2.840.113556.1.2.503 attributeSyntax: 2.5.5.9 isSingleValued: TRUE mAPIID: 33180 showInAdvancedViewOnly: TRUE adminDisplayName: ms-Exch-HTTP-Pub-GAL-Limit adminDescription: ms-Exch-HTTP-Pub-GAL-Limit oMSyntax: 2 searchFlags: 0 lDAPDisplayName: hTTPPubGALLimit name: ms-Exch-HTTP-Pub-GAL-Limit schemaIDGUID: a8df740a-c5ea-11d1-bbcb-0080c76670c0 isMemberOfPartialAttributeSet: FALSE objectCategory: CN=Attribute-Schema,${SCHEMADN} # # ms-Exch-HTTP-Pub-PF # dn: CN=ms-Exch-HTTP-Pub-PF,${SCHEMADN} objectClass: top objectClass: attributeSchema cn: ms-Exch-HTTP-Pub-PF distinguishedName: CN=ms-Exch-HTTP-Pub-PF,${SCHEMADN} attributeID: 1.2.840.113556.1.2.505 attributeSyntax: 2.5.5.10 isSingleValued: FALSE rangeLower: 1 rangeUpper: 1024 mAPIID: 33182 showInAdvancedViewOnly: TRUE adminDisplayName: ms-Exch-HTTP-Pub-PF adminDescription: ms-Exch-HTTP-Pub-PF oMSyntax: 4 searchFlags: 0 lDAPDisplayName: hTTPPubPF name: ms-Exch-HTTP-Pub-PF schemaIDGUID: a8df740b-c5ea-11d1-bbcb-0080c76670c0 isMemberOfPartialAttributeSet: FALSE objectCategory: CN=Attribute-Schema,${SCHEMADN} # # ms-Exch-HTTP-Servers # dn: CN=ms-Exch-HTTP-Servers,${SCHEMADN} objectClass: top objectClass: attributeSchema cn: ms-Exch-HTTP-Servers distinguishedName: CN=ms-Exch-HTTP-Servers,${SCHEMADN} attributeID: 1.2.840.113556.1.2.517 attributeSyntax: 2.5.5.12 isSingleValued: FALSE rangeLower: 1 rangeUpper: 256 mAPIID: 33195 showInAdvancedViewOnly: TRUE adminDisplayName: ms-Exch-HTTP-Servers adminDescription: ms-Exch-HTTP-Servers oMSyntax: 64 searchFlags: 0 lDAPDisplayName: hTTPServers name: ms-Exch-HTTP-Servers schemaIDGUID: a8df740c-c5ea-11d1-bbcb-0080c76670c0 isMemberOfPartialAttributeSet: FALSE objectCategory: CN=Attribute-Schema,${SCHEMADN} # # ms-Exch-IFS-Private-Enabled # Determines whether private mailboxes are shared. dn: CN=ms-Exch-IFS-Private-Enabled,${SCHEMADN} objectClass: top objectClass: attributeSchema cn: ms-Exch-IFS-Private-Enabled distinguishedName: CN=ms-Exch-IFS-Private-Enabled,${SCHEMADN} attributeID: 1.2.840.113556.1.4.7000.102.11029 attributeSyntax: 2.5.5.8 isSingleValued: TRUE showInAdvancedViewOnly: TRUE adminDisplayName: ms-Exch-IFS-Private-Enabled adminDescription: ms-Exch-IFS-Private-Enabled oMSyntax: 1 searchFlags: 0 lDAPDisplayName: msExchIFSPrivateEnabled name: ms-Exch-IFS-Private-Enabled schemaIDGUID: a2e915d2-b093-11d2-aa06-00c04f8eedd8 isMemberOfPartialAttributeSet: FALSE objectCategory: CN=Attribute-Schema,${SCHEMADN} # # ms-Exch-IFS-Private-Name # The name of the private share. # dn: CN=ms-Exch-IFS-Private-Name,${SCHEMADN} objectClass: top objectClass: attributeSchema cn: ms-Exch-IFS-Private-Name distinguishedName: CN=ms-Exch-IFS-Private-Name,${SCHEMADN} attributeID: 1.2.840.113556.1.4.7000.102.11033 attributeSyntax: 2.5.5.4 isSingleValued: TRUE showInAdvancedViewOnly: TRUE adminDisplayName: ms-Exch-IFS-Private-Name adminDescription: ms-Exch-IFS-Private-Name oMSyntax: 20 searchFlags: 0 lDAPDisplayName: msExchIFSPrivateName name: ms-Exch-IFS-Private-Name schemaIDGUID: a30a76be-b093-11d2-aa06-00c04f8eedd8 isMemberOfPartialAttributeSet: FALSE objectCategory: CN=Attribute-Schema,${SCHEMADN} # # ms-Exch-IFS-Public-Enabled # Determines whether public folders are shared. # dn: CN=ms-Exch-IFS-Public-Enabled,${SCHEMADN} objectClass: top objectClass: attributeSchema cn: ms-Exch-IFS-Public-Enabled distinguishedName: CN=ms-Exch-IFS-Public-Enabled,${SCHEMADN} attributeID: 1.2.840.113556.1.4.7000.102.11050 attributeSyntax: 2.5.5.8 isSingleValued: TRUE showInAdvancedViewOnly: TRUE adminDisplayName: ms-Exch-IFS-Public-Enabled adminDescription: ms-Exch-IFS-Public-Enabled oMSyntax: 1 searchFlags: 0 lDAPDisplayName: msExchIFSPublicEnabled name: ms-Exch-IFS-Public-Enabled schemaIDGUID: a32bd7aa-b093-11d2-aa06-00c04f8eedd8 isMemberOfPartialAttributeSet: FALSE objectCategory: CN=Attribute-Schema,${SCHEMADN} # # ms-Exch-IFS-Public-Name # The name of the public share. # dn: CN=ms-Exch-IFS-Public-Name,${SCHEMADN} objectClass: top objectClass: attributeSchema cn: ms-Exch-IFS-Public-Name distinguishedName: CN=ms-Exch-IFS-Public-Name,${SCHEMADN} attributeID: 1.2.840.113556.1.4.7000.102.11051 attributeSyntax: 2.5.5.4 isSingleValued: TRUE showInAdvancedViewOnly: TRUE adminDisplayName: ms-Exch-IFS-Public-Name adminDescription: ms-Exch-IFS-Public-Name oMSyntax: 20 searchFlags: 0 lDAPDisplayName: msExchIFSPublicName name: ms-Exch-IFS-Public-Name schemaIDGUID: a34d3896-b093-11d2-aa06-00c04f8eedd8 isMemberOfPartialAttributeSet: FALSE objectCategory: CN=Attribute-Schema,${SCHEMADN} # # ms-Exch-IMAP-OWA-URL-Prefix-Override # dn: CN=ms-Exch-IMAP-OWA-URL-Prefix-Override,${SCHEMADN} objectClass: top objectClass: attributeSchema cn: ms-Exch-IMAP-OWA-URL-Prefix-Override distinguishedName: CN=ms-Exch-IMAP-OWA-URL-Prefix-Override,${SCHEMADN} attributeID: 1.2.840.113556.1.4.7000.102.50213 attributeSyntax: 2.5.5.12 isSingleValued: TRUE showInAdvancedViewOnly: TRUE adminDisplayName: ms-Exch-IMAP-OWA-URL-Prefix-Override adminDescription: ms-Exch-IMAP-OWA-URL-Prefix-Override oMSyntax: 64 searchFlags: 0 lDAPDisplayName: msExchIMAPOWAURLPrefixOverride name: ms-Exch-IMAP-OWA-URL-Prefix-Override schemaIDGUID: 5e26dd2a-9b0a-4219-8183-20ad44f5cbdf attributeSecurityGUID: e48d0154-bcf8-11d1-8702-00c04fb96050 isMemberOfPartialAttributeSet: TRUE objectCategory: CN=Attribute-Schema,${SCHEMADN} # # ms-Exch-Imported-From # Contains the DN to the connecter from which this object is imported. # dn: CN=ms-Exch-Imported-From,${SCHEMADN} objectClass: top objectClass: attributeSchema cn: ms-Exch-Imported-From distinguishedName: CN=ms-Exch-Imported-From,${SCHEMADN} attributeID: 1.2.840.113556.1.2.263 attributeSyntax: 2.5.5.12 isSingleValued: TRUE rangeLower: 1 rangeUpper: 1024 mAPIID: 32834 showInAdvancedViewOnly: TRUE adminDisplayName: ms-Exch-Imported-From adminDescription: ms-Exch-Imported-From oMSyntax: 64 searchFlags: 9 lDAPDisplayName: importedFrom name: ms-Exch-Imported-From schemaIDGUID: bf96798a-0de6-11d0-a285-00aa003049e2 attributeSecurityGUID: e48d0154-bcf8-11d1-8702-00c04fb96050 isMemberOfPartialAttributeSet: TRUE objectCategory: CN=Attribute-Schema,${SCHEMADN} # # ms-Exch-Import-Container # dn: CN=ms-Exch-Import-Container,${SCHEMADN} objectClass: top objectClass: attributeSchema cn: ms-Exch-Import-Container distinguishedName: CN=ms-Exch-Import-Container,${SCHEMADN} attributeID: 1.2.840.113556.1.2.110 attributeSyntax: 2.5.5.1 isSingleValued: TRUE mAPIID: 32954 showInAdvancedViewOnly: TRUE adminDisplayName: ms-Exch-Import-Container oMObjectClass:: KwwCh3McAIVK adminDescription: ms-Exch-Import-Container oMSyntax: 127 searchFlags: 0 lDAPDisplayName: importContainer name: ms-Exch-Import-Container schemaIDGUID: a8df740d-c5ea-11d1-bbcb-0080c76670c0 isMemberOfPartialAttributeSet: FALSE objectCategory: CN=Attribute-Schema,${SCHEMADN} # # ms-Exch-Import-Container-Linked # dn: CN=ms-Exch-Import-Container-Linked,${SCHEMADN} objectClass: top objectClass: attributeSchema cn: ms-Exch-Import-Container-Linked distinguishedName: CN=ms-Exch-Import-Container-Linked,${SCHEMADN} attributeID: 1.2.840.113556.1.4.7000.102.1028 attributeSyntax: 2.5.5.1 isSingleValued: TRUE linkID: 1032 showInAdvancedViewOnly: TRUE adminDisplayName: ms-Exch-Import-Container-Linked oMObjectClass:: KwwCh3McAIVK adminDescription: ms-Exch-Import-Container-Linked oMSyntax: 127 searchFlags: 0 lDAPDisplayName: msExchImportContainerLinked name: ms-Exch-Import-Container-Linked schemaIDGUID: 9ff15c4c-1ec9-11d3-aa5e-00c04f8eedd8 isMemberOfPartialAttributeSet: FALSE objectCategory: CN=Attribute-Schema,${SCHEMADN} # # ms-Exch-IM-ACL # A multivalued list of access control entries (ACEs) for Instant # Messaging. # dn: CN=ms-Exch-IM-ACL,${SCHEMADN} objectClass: top objectClass: attributeSchema cn: ms-Exch-IM-ACL distinguishedName: CN=ms-Exch-IM-ACL,${SCHEMADN} attributeID: 1.2.840.113556.1.4.7000.102.7031 attributeSyntax: 2.5.5.10 isSingleValued: FALSE showInAdvancedViewOnly: TRUE adminDisplayName: ms-Exch-IM-ACL adminDescription: ms-Exch-IM-ACL oMSyntax: 4 searchFlags: 0 lDAPDisplayName: msExchIMACL name: ms-Exch-IM-ACL schemaIDGUID: 06551010-2845-11d3-aa68-00c04f8eedd8 attributeSecurityGUID: e48d0154-bcf8-11d1-8702-00c04fb96050 isMemberOfPartialAttributeSet: TRUE objectCategory: CN=Attribute-Schema,${SCHEMADN} # # ms-Exch-IM-Address # A representation (resembling e-mail) of the public URL for a user # that is enabled for Instant Messaging. # dn: CN=ms-Exch-IM-Address,${SCHEMADN} objectClass: top objectClass: attributeSchema cn: ms-Exch-IM-Address distinguishedName: CN=ms-Exch-IM-Address,${SCHEMADN} attributeID: 1.2.840.113556.1.4.7000.102.7038 attributeSyntax: 2.5.5.5 isSingleValued: TRUE showInAdvancedViewOnly: TRUE adminDisplayName: ms-Exch-IM-Address adminDescription: ms-Exch-IM-Address oMSyntax: 19 searchFlags: 1 lDAPDisplayName: msExchIMAddress name: ms-Exch-IM-Address schemaIDGUID: cbbd3752-b8d8-47dc-92ee-ab488c1af969 attributeSecurityGUID: e48d0154-bcf8-11d1-8702-00c04fb96050 isMemberOfPartialAttributeSet: TRUE objectCategory: CN=Attribute-Schema,${SCHEMADN} # # ms-Exch-IM-DB-Log-Path # States the directory path root for all database transaction log # files. # dn: CN=ms-Exch-IM-DB-Log-Path,${SCHEMADN} objectClass: top objectClass: attributeSchema cn: ms-Exch-IM-DB-Log-Path distinguishedName: CN=ms-Exch-IM-DB-Log-Path,${SCHEMADN} attributeID: 1.2.840.113556.1.4.7000.102.7016 attributeSyntax: 2.5.5.12 isSingleValued: TRUE rangeLower: 0 rangeUpper: 1024 showInAdvancedViewOnly: TRUE adminDisplayName: ms-Exch-IM-DB-Log-Path adminDescription: ms-Exch-IM-DB-Log-Path oMSyntax: 64 searchFlags: 0 lDAPDisplayName: msExchIMDBLogPath name: ms-Exch-IM-DB-Log-Path schemaIDGUID: a4394164-b093-11d2-aa06-00c04f8eedd8 isMemberOfPartialAttributeSet: FALSE objectCategory: CN=Attribute-Schema,${SCHEMADN} # # ms-Exch-IM-DB-Path # States the directory path root for all database files for a # particular server. # dn: CN=ms-Exch-IM-DB-Path,${SCHEMADN} objectClass: top objectClass: attributeSchema cn: ms-Exch-IM-DB-Path distinguishedName: CN=ms-Exch-IM-DB-Path,${SCHEMADN} attributeID: 1.2.840.113556.1.4.7000.102.7015 attributeSyntax: 2.5.5.12 isSingleValued: TRUE rangeLower: 0 rangeUpper: 1024 showInAdvancedViewOnly: TRUE adminDisplayName: ms-Exch-IM-DB-Path adminDescription: ms-Exch-IM-DB-Path oMSyntax: 64 searchFlags: 0 lDAPDisplayName: msExchIMDBPath name: ms-Exch-IM-DB-Path schemaIDGUID: a45aa250-b093-11d2-aa06-00c04f8eedd8 isMemberOfPartialAttributeSet: FALSE objectCategory: CN=Attribute-Schema,${SCHEMADN} # # ms-Exch-IM-Firewall-Type # Describes the type of firewall entry for this firewall object. # dn: CN=ms-Exch-IM-Firewall-Type,${SCHEMADN} objectClass: top objectClass: attributeSchema cn: ms-Exch-IM-Firewall-Type distinguishedName: CN=ms-Exch-IM-Firewall-Type,${SCHEMADN} attributeID: 1.2.840.113556.1.4.7000.102.7028 attributeSyntax: 2.5.5.9 isSingleValued: TRUE showInAdvancedViewOnly: TRUE adminDisplayName: ms-Exch-IM-Firewall-Type adminDescription: ms-Exch-IM-Firewall-Type oMSyntax: 2 searchFlags: 0 lDAPDisplayName: msExchIMFirewallType name: ms-Exch-IM-Firewall-Type schemaIDGUID: 06550ffc-2845-11d3-aa68-00c04f8eedd8 isMemberOfPartialAttributeSet: FALSE objectCategory: CN=Attribute-Schema,${SCHEMADN} # # ms-Exch-IM-Host-Name # The host name for the Instant Messaging virtual server. # dn: CN=ms-Exch-IM-Host-Name,${SCHEMADN} objectClass: top objectClass: attributeSchema cn: ms-Exch-IM-Host-Name distinguishedName: CN=ms-Exch-IM-Host-Name,${SCHEMADN} attributeID: 1.2.840.113556.1.4.7000.102.7034 attributeSyntax: 2.5.5.10 isSingleValued: TRUE showInAdvancedViewOnly: TRUE adminDisplayName: ms-Exch-IM-Host-Name adminDescription: ms-Exch-IM-Host-Name oMSyntax: 4 searchFlags: 0 lDAPDisplayName: msExchIMHostName name: ms-Exch-IM-Host-Name schemaIDGUID: 807b6084-439b-11d3-aa72-00c04f8eedd8 isMemberOfPartialAttributeSet: FALSE objectCategory: CN=Attribute-Schema,${SCHEMADN} # # ms-Exch-IM-IP-Range # A multivalued attribute that lists IP ranges that are valid for the # Instant Messaging firewall. dn: CN=ms-Exch-IM-IP-Range,${SCHEMADN} objectClass: top objectClass: attributeSchema cn: ms-Exch-IM-IP-Range distinguishedName: CN=ms-Exch-IM-IP-Range,${SCHEMADN} attributeID: 1.2.840.113556.1.4.7000.102.7030 attributeSyntax: 2.5.5.16 isSingleValued: FALSE showInAdvancedViewOnly: TRUE adminDisplayName: ms-Exch-IM-IP-Range adminDescription: ms-Exch-IM-IP-Range oMSyntax: 65 searchFlags: 0 lDAPDisplayName: msExchIMIPRange name: ms-Exch-IM-IP-Range schemaIDGUID: 0655100b-2845-11d3-aa68-00c04f8eedd8 isMemberOfPartialAttributeSet: FALSE objectCategory: CN=Attribute-Schema,${SCHEMADN} # # ms-Exch-IM-Meta-Physical-URL # The public URL for a user that is enabled for Instant Messaging. # dn: CN=ms-Exch-IM-Meta-Physical-URL,${SCHEMADN} objectClass: top objectClass: attributeSchema cn: ms-Exch-IM-Meta-Physical-URL distinguishedName: CN=ms-Exch-IM-Meta-Physical-URL,${SCHEMADN} attributeID: 1.2.840.113556.1.4.7000.102.7035 attributeSyntax: 2.5.5.5 isSingleValued: TRUE showInAdvancedViewOnly: TRUE adminDisplayName: ms-Exch-IM-Meta-Physical-URL adminDescription: ms-Exch-IM-Meta-Physical-URL oMSyntax: 19 searchFlags: 1 lDAPDisplayName: msExchIMMetaPhysicalURL name: ms-Exch-IM-Meta-Physical-URL schemaIDGUID: 8e7a93a3-5a7c-11d3-aa78-00c04f8eedd8 attributeSecurityGUID: e48d0154-bcf8-11d1-8702-00c04fb96050 isMemberOfPartialAttributeSet: TRUE objectCategory: CN=Attribute-Schema,${SCHEMADN} # # ms-Exch-IM-Physical-URL # The private URL for a user that is enabled for Instant Messaging. # dn: CN=ms-Exch-IM-Physical-URL,${SCHEMADN} objectClass: top objectClass: attributeSchema cn: ms-Exch-IM-Physical-URL distinguishedName: CN=ms-Exch-IM-Physical-URL,${SCHEMADN} attributeID: 1.2.840.113556.1.4.7000.102.7036 attributeSyntax: 2.5.5.5 isSingleValued: TRUE showInAdvancedViewOnly: TRUE adminDisplayName: ms-Exch-IM-Physical-URL adminDescription: ms-Exch-IM-Physical-URL oMSyntax: 19 searchFlags: 1 lDAPDisplayName: msExchIMPhysicalURL name: ms-Exch-IM-Physical-URL schemaIDGUID: 8e7a93a8-5a7c-11d3-aa78-00c04f8eedd8 attributeSecurityGUID: e48d0154-bcf8-11d1-8702-00c04fb96050 isMemberOfPartialAttributeSet: TRUE objectCategory: CN=Attribute-Schema,${SCHEMADN} # # ms-Exch-IM-Proxy # The proxy name for the Instant Messaging firewall. # dn: CN=ms-Exch-IM-Proxy,${SCHEMADN} objectClass: top objectClass: attributeSchema cn: ms-Exch-IM-Proxy distinguishedName: CN=ms-Exch-IM-Proxy,${SCHEMADN} attributeID: 1.2.840.113556.1.4.7000.102.7029 attributeSyntax: 2.5.5.10 isSingleValued: TRUE showInAdvancedViewOnly: TRUE adminDisplayName: ms-Exch-IM-Proxy adminDescription: ms-Exch-IM-Proxy oMSyntax: 4 searchFlags: 0 lDAPDisplayName: msExchIMProxy name: ms-Exch-IM-Proxy schemaIDGUID: 06551002-2845-11d3-aa68-00c04f8eedd8 isMemberOfPartialAttributeSet: FALSE objectCategory: CN=Attribute-Schema,${SCHEMADN} # # ms-Exch-IM-Server-Hosts-Users # States whether an Instant Messaging virtual server can host users. # dn: CN=ms-Exch-IM-Server-Hosts-Users,${SCHEMADN} objectClass: top objectClass: attributeSchema cn: ms-Exch-IM-Server-Hosts-Users distinguishedName: CN=ms-Exch-IM-Server-Hosts-Users,${SCHEMADN} attributeID: 1.2.840.113556.1.4.7000.102.7025 attributeSyntax: 2.5.5.8 isSingleValued: TRUE showInAdvancedViewOnly: TRUE adminDisplayName: ms-Exch-IM-Server-Hosts-Users adminDescription: ms-Exch-IM-Server-Hosts-Users oMSyntax: 1 searchFlags: 0 lDAPDisplayName: msExchIMServerHostsUsers name: ms-Exch-IM-Server-Hosts-Users schemaIDGUID: 8d6b1af6-b09e-11d2-aa06-00c04f8eedd8 isMemberOfPartialAttributeSet: FALSE objectCategory: CN=Attribute-Schema,${SCHEMADN} # # ms-Exch-IM-Server-IIS-Id # The Microsoft Internet Information Services (IIS) Web Server # Instance in the metabase. # dn: CN=ms-Exch-IM-Server-IIS-Id,${SCHEMADN} objectClass: top objectClass: attributeSchema cn: ms-Exch-IM-Server-IIS-Id distinguishedName: CN=ms-Exch-IM-Server-IIS-Id,${SCHEMADN} attributeID: 1.2.840.113556.1.4.7000.102.7023 attributeSyntax: 2.5.5.9 isSingleValued: TRUE rangeLower: 1 showInAdvancedViewOnly: TRUE adminDisplayName: ms-Exch-IM-Server-IIS-Id adminDescription: ms-Exch-IM-Server-IIS-Id oMSyntax: 2 searchFlags: 0 lDAPDisplayName: msExchIMServerIISId name: ms-Exch-IM-Server-IIS-Id schemaIDGUID: 8d3444e0-b09e-11d2-aa06-00c04f8eedd8 isMemberOfPartialAttributeSet: FALSE objectCategory: CN=Attribute-Schema,${SCHEMADN} # # ms-Exch-IM-Server-Name # dn: CN=ms-Exch-IM-Server-Name,${SCHEMADN} objectClass: top objectClass: attributeSchema cn: ms-Exch-IM-Server-Name distinguishedName: CN=ms-Exch-IM-Server-Name,${SCHEMADN} attributeID: 1.2.840.113556.1.4.7000.102.7024 attributeSyntax: 2.5.5.12 isSingleValued: TRUE rangeLower: 1 rangeUpper: 1024 showInAdvancedViewOnly: TRUE adminDisplayName: ms-Exch-IM-Server-Name adminDescription: ms-Exch-IM-Server-Name oMSyntax: 64 searchFlags: 1 lDAPDisplayName: msExchIMServerName name: ms-Exch-IM-Server-Name schemaIDGUID: 8d4e7ebe-b09e-11d2-aa06-00c04f8eedd8 isMemberOfPartialAttributeSet: FALSE objectCategory: CN=Attribute-Schema,${SCHEMADN} # # ms-Exch-IM-Virtual-Server # The DN of the Instant Messaging home server. # dn: CN=ms-Exch-IM-Virtual-Server,${SCHEMADN} objectClass: top objectClass: attributeSchema cn: ms-Exch-IM-Virtual-Server distinguishedName: CN=ms-Exch-IM-Virtual-Server,${SCHEMADN} attributeID: 1.2.840.113556.1.4.7000.102.7037 attributeSyntax: 2.5.5.1 isSingleValued: TRUE showInAdvancedViewOnly: TRUE adminDisplayName: ms-Exch-IM-Virtual-Server oMObjectClass:: KwwCh3McAIVK adminDescription: ms-Exch-IM-Virtual-Server oMSyntax: 127 searchFlags: 1 lDAPDisplayName: msExchIMVirtualServer name: ms-Exch-IM-Virtual-Server schemaIDGUID: 41e8fd82-8f37-4e56-a44a-33a3e6b7526c attributeSecurityGUID: e48d0154-bcf8-11d1-8702-00c04fb96050 isMemberOfPartialAttributeSet: TRUE objectCategory: CN=Attribute-Schema,${SCHEMADN} # # ms-Exch-Inbound-Sites # dn: CN=ms-Exch-Inbound-Sites,${SCHEMADN} objectClass: top objectClass: attributeSchema cn: ms-Exch-Inbound-Sites distinguishedName: CN=ms-Exch-Inbound-Sites,${SCHEMADN} attributeID: 1.2.840.113556.1.2.71 attributeSyntax: 2.5.5.1 isSingleValued: FALSE mAPIID: 32956 showInAdvancedViewOnly: TRUE adminDisplayName: ms-Exch-Inbound-Sites oMObjectClass:: KwwCh3McAIVK adminDescription: ms-Exch-Inbound-Sites oMSyntax: 127 searchFlags: 0 lDAPDisplayName: inboundSites name: ms-Exch-Inbound-Sites schemaIDGUID: a8df7414-c5ea-11d1-bbcb-0080c76670c0 isMemberOfPartialAttributeSet: FALSE objectCategory: CN=Attribute-Schema,${SCHEMADN} # # ms-Exch-Incoming-Connection-Timeout # The maximum length of time for incoming connections. # dn: CN=ms-Exch-Incoming-Connection-Timeout,${SCHEMADN} objectClass: top objectClass: attributeSchema cn: ms-Exch-Incoming-Connection-Timeout distinguishedName: CN=ms-Exch-Incoming-Connection-Timeout,${SCHEMADN} attributeID: 1.2.840.113556.1.4.7000.102.2015 attributeSyntax: 2.5.5.9 isSingleValued: TRUE showInAdvancedViewOnly: TRUE adminDisplayName: ms-Exch-Incoming-Connection-Timeout adminDescription: ms-Exch-Incoming-Connection-Timeout oMSyntax: 2 searchFlags: 0 lDAPDisplayName: msExchIncomingConnectionTimeout name: ms-Exch-Incoming-Connection-Timeout schemaIDGUID: a64cedca-b093-11d2-aa06-00c04f8eedd8 isMemberOfPartialAttributeSet: FALSE objectCategory: CN=Attribute-Schema,${SCHEMADN} # # ms-Exch-Incoming-Msg-Size-Limit # dn: CN=ms-Exch-Incoming-Msg-Size-Limit,${SCHEMADN} objectClass: top objectClass: attributeSchema cn: ms-Exch-Incoming-Msg-Size-Limit distinguishedName: CN=ms-Exch-Incoming-Msg-Size-Limit,${SCHEMADN} attributeID: 1.2.840.113556.1.2.491 attributeSyntax: 2.5.5.9 isSingleValued: TRUE mAPIID: 33168 showInAdvancedViewOnly: TRUE adminDisplayName: ms-Exch-Incoming-Msg-Size-Limit adminDescription: ms-Exch-Incoming-Msg-Size-Limit oMSyntax: 2 searchFlags: 0 lDAPDisplayName: incomingMsgSizeLimit name: ms-Exch-Incoming-Msg-Size-Limit schemaIDGUID: 1677581a-47f3-11d1-a9c3-0000f80367c1 isMemberOfPartialAttributeSet: FALSE objectCategory: CN=Attribute-Schema,${SCHEMADN} # # ms-Exch-Inconsistent-State # dn: CN=ms-Exch-Inconsistent-State,${SCHEMADN} objectClass: top objectClass: attributeSchema cn: ms-Exch-Inconsistent-State distinguishedName: CN=ms-Exch-Inconsistent-State,${SCHEMADN} attributeID: 1.2.840.113556.1.4.7000.102.96 attributeSyntax: 2.5.5.9 isSingleValued: TRUE showInAdvancedViewOnly: TRUE adminDisplayName: ms-Exch-Inconsistent-State adminDescription: ms-Exch-Inconsistent-State oMSyntax: 2 searchFlags: 0 lDAPDisplayName: msExchInconsistentState name: ms-Exch-Inconsistent-State schemaIDGUID: 1d80475f-e7b4-4005-af4d-82bcbf407c3c attributeSecurityGUID: e48d0154-bcf8-11d1-8702-00c04fb96050 isMemberOfPartialAttributeSet: FALSE objectCategory: CN=Attribute-Schema,${SCHEMADN} # # ms-Exch-INSAdmin # dn: CN=ms-Exch-INSAdmin,${SCHEMADN} objectClass: top objectClass: attributeSchema cn: ms-Exch-INSAdmin distinguishedName: CN=ms-Exch-INSAdmin,${SCHEMADN} attributeID: 1.2.840.113556.1.2.543 attributeSyntax: 2.5.5.1 isSingleValued: TRUE mAPIID: 33221 showInAdvancedViewOnly: TRUE adminDisplayName: ms-Exch-INSAdmin oMObjectClass:: KwwCh3McAIVK adminDescription: ms-Exch-INSAdmin oMSyntax: 127 searchFlags: 0 lDAPDisplayName: iNSAdmin name: ms-Exch-INSAdmin schemaIDGUID: a8df7416-c5ea-11d1-bbcb-0080c76670c0 isMemberOfPartialAttributeSet: FALSE objectCategory: CN=Attribute-Schema,${SCHEMADN} # # ms-Exch-Installed-Components # Contains a list of installed components on a given server. # dn: CN=ms-Exch-Installed-Components,${SCHEMADN} objectClass: top objectClass: attributeSchema cn: ms-Exch-Installed-Components distinguishedName: CN=ms-Exch-Installed-Components,${SCHEMADN} attributeID: 1.2.840.113556.1.4.7000.102.50024 attributeSyntax: 2.5.5.10 isSingleValued: FALSE showInAdvancedViewOnly: TRUE adminDisplayName: ms-Exch-Installed-Components adminDescription: ms-Exch-Installed-Components oMSyntax: 4 searchFlags: 0 lDAPDisplayName: msExchInstalledComponents name: ms-Exch-Installed-Components schemaIDGUID: 99f5865d-12e8-11d3-aa58-00c04f8eedd8 isMemberOfPartialAttributeSet: FALSE objectCategory: CN=Attribute-Schema,${SCHEMADN} # # ms-Exch-Install-Path # dn: CN=ms-Exch-Install-Path,${SCHEMADN} objectClass: top objectClass: attributeSchema cn: ms-Exch-Install-Path distinguishedName: CN=ms-Exch-Install-Path,${SCHEMADN} attributeID: 1.2.840.113556.1.4.7000.102.50019 attributeSyntax: 2.5.5.12 isSingleValued: TRUE showInAdvancedViewOnly: TRUE adminDisplayName: ms-Exch-Install-Path adminDescription: ms-Exch-Install-Path oMSyntax: 64 searchFlags: 0 lDAPDisplayName: msExchInstallPath name: ms-Exch-Install-Path schemaIDGUID: 8a23df36-b09e-11d2-aa06-00c04f8eedd8 isMemberOfPartialAttributeSet: FALSE objectCategory: CN=Attribute-Schema,${SCHEMADN} # # ms-Exch-Internet-Encoding # dn: CN=ms-Exch-Internet-Encoding,${SCHEMADN} objectClass: top objectClass: attributeSchema cn: ms-Exch-Internet-Encoding distinguishedName: CN=ms-Exch-Internet-Encoding,${SCHEMADN} attributeID: 1.2.840.113556.1.2.551 attributeSyntax: 2.5.5.9 isSingleValued: TRUE mAPIID: 14961 showInAdvancedViewOnly: TRUE adminDisplayName: ms-Exch-Internet-Encoding adminDescription: ms-Exch-Internet-Encoding oMSyntax: 2 searchFlags: 0 lDAPDisplayName: internetEncoding name: ms-Exch-Internet-Encoding schemaIDGUID: 1677581d-47f3-11d1-a9c3-0000f80367c1 attributeSecurityGUID: e48d0154-bcf8-11d1-8702-00c04fb96050 isMemberOfPartialAttributeSet: TRUE objectCategory: CN=Attribute-Schema,${SCHEMADN} # # ms-Exch-Internet-Name # The data conference Internet name. # dn: CN=ms-Exch-Internet-Name,${SCHEMADN} objectClass: top objectClass: attributeSchema cn: ms-Exch-Internet-Name distinguishedName: CN=ms-Exch-Internet-Name,${SCHEMADN} attributeID: 1.2.840.113556.1.4.7000.102.9019 attributeSyntax: 2.5.5.12 isSingleValued: TRUE showInAdvancedViewOnly: TRUE adminDisplayName: ms-Exch-Internet-Name adminDescription: ms-Exch-Internet-Name oMSyntax: 64 searchFlags: 0 lDAPDisplayName: msExchInternetName name: ms-Exch-Internet-Name schemaIDGUID: a670b110-b093-11d2-aa06-00c04f8eedd8 isMemberOfPartialAttributeSet: FALSE objectCategory: CN=Attribute-Schema,${SCHEMADN} # # ms-Exch-Inter-Org-Address-Type # # dn: CN=ms-Exch-Inter-Org-Address-Type,${SCHEMADN} objectClass: top objectClass: attributeSchema cn: ms-Exch-Inter-Org-Address-Type distinguishedName: CN=ms-Exch-Inter-Org-Address-Type,${SCHEMADN} attributeID: 1.2.840.113556.1.4.7000.102.94 attributeSyntax: 2.5.5.12 isSingleValued: TRUE showInAdvancedViewOnly: TRUE adminDisplayName: ms-Exch-Inter-Org-Address-Type adminDescription: ms-Exch-Inter-Org-Address-Type oMSyntax: 64 searchFlags: 0 lDAPDisplayName: msExchInterOrgAddressType name: ms-Exch-Inter-Org-Address-Type schemaIDGUID: 3836c80b-8cee-4413-9e65-e937c1aed10f isMemberOfPartialAttributeSet: FALSE objectCategory: CN=Attribute-Schema,${SCHEMADN} # # ms-Exch-IP-Address # dn: CN=ms-Exch-IP-Address,${SCHEMADN} objectClass: top objectClass: attributeSchema cn: ms-Exch-IP-Address distinguishedName: CN=ms-Exch-IP-Address,${SCHEMADN} attributeID: 1.2.840.113556.1.4.7000.102.5050 attributeSyntax: 2.5.5.9 isSingleValued: TRUE showInAdvancedViewOnly: TRUE adminDisplayName: ms-Exch-IP-Address adminDescription: ms-Exch-IP-Address oMSyntax: 2 searchFlags: 0 lDAPDisplayName: msExchIPAddress name: ms-Exch-IP-Address schemaIDGUID: 8b46be1a-b09e-11d2-aa06-00c04f8eedd8 isMemberOfPartialAttributeSet: FALSE objectCategory: CN=Attribute-Schema,${SCHEMADN} # # ms-Exch-IP-Security # Restricts IP connections to this resource. # dn: CN=ms-Exch-IP-Security,${SCHEMADN} objectClass: top objectClass: attributeSchema cn: ms-Exch-IP-Security distinguishedName: CN=ms-Exch-IP-Security,${SCHEMADN} attributeID: 1.2.840.113556.1.4.7000.102.2013 attributeSyntax: 2.5.5.10 isSingleValued: TRUE showInAdvancedViewOnly: TRUE adminDisplayName: ms-Exch-IP-Security adminDescription: ms-Exch-IP-Security oMSyntax: 4 searchFlags: 0 lDAPDisplayName: msExchIPSecurity name: ms-Exch-IP-Security schemaIDGUID: a68fafa2-b093-11d2-aa06-00c04f8eedd8 isMemberOfPartialAttributeSet: FALSE objectCategory: CN=Attribute-Schema,${SCHEMADN} # # ms-Exch-Is-Bridgehead-Site # A flag to determine whether non-mailbox associated objects are # replicated over this particular connection agreement. # dn: CN=ms-Exch-Is-Bridgehead-Site,${SCHEMADN} objectClass: top objectClass: attributeSchema cn: ms-Exch-Is-Bridgehead-Site distinguishedName: CN=ms-Exch-Is-Bridgehead-Site,${SCHEMADN} attributeID: 1.2.840.113556.1.4.7000.102.35 attributeSyntax: 2.5.5.8 isSingleValued: TRUE showInAdvancedViewOnly: TRUE adminDisplayName: ms-Exch-Is-Bridgehead-Site adminDescription: ms-Exch-Is-Bridgehead-Site oMSyntax: 1 searchFlags: 0 lDAPDisplayName: msExchIsBridgeheadSite name: ms-Exch-Is-Bridgehead-Site schemaIDGUID: a6b1108e-b093-11d2-aa06-00c04f8eedd8 isMemberOfPartialAttributeSet: FALSE objectCategory: CN=Attribute-Schema,${SCHEMADN} # # ms-Exch-Is-Config-CA # Determines if this is a configuration Connection Agreement. # dn: CN=ms-Exch-Is-Config-CA,${SCHEMADN} objectClass: top objectClass: attributeSchema cn: ms-Exch-Is-Config-CA distinguishedName: CN=ms-Exch-Is-Config-CA,${SCHEMADN} attributeID: 1.2.840.113556.1.4.7000.102.79 attributeSyntax: 2.5.5.8 isSingleValued: TRUE showInAdvancedViewOnly: TRUE adminDisplayName: ms-Exch-Is-Config-CA adminDescription: ms-Exch-Is-Config-CA oMSyntax: 1 searchFlags: 0 lDAPDisplayName: msExchIsConfigCA name: ms-Exch-Is-Config-CA schemaIDGUID: 910f526c-b09e-11d2-aa06-00c04f8eedd8 isMemberOfPartialAttributeSet: FALSE objectCategory: CN=Attribute-Schema,${SCHEMADN} # # ms-Exch-KCC-Status # dn: CN=ms-Exch-KCC-Status,${SCHEMADN} objectClass: top objectClass: attributeSchema cn: ms-Exch-KCC-Status distinguishedName: CN=ms-Exch-KCC-Status,${SCHEMADN} attributeID: 1.2.840.113556.1.2.237 attributeSyntax: 2.5.5.10 isSingleValued: FALSE mAPIID: 32962 showInAdvancedViewOnly: TRUE adminDisplayName: ms-Exch-KCC-Status adminDescription: ms-Exch-KCC-Status oMSyntax: 4 searchFlags: 0 lDAPDisplayName: kCCStatus name: ms-Exch-KCC-Status schemaIDGUID: 5fd424ae-1262-11d0-a060-00aa006c33ed isMemberOfPartialAttributeSet: FALSE objectCategory: CN=Attribute-Schema,${SCHEMADN} # # ms-Exch-KM-Server # dn: CN=ms-Exch-KM-Server,${SCHEMADN} objectClass: top objectClass: attributeSchema cn: ms-Exch-KM-Server distinguishedName: CN=ms-Exch-KM-Server,${SCHEMADN} attributeID: 1.2.840.113556.1.2.440 attributeSyntax: 2.5.5.1 isSingleValued: TRUE mAPIID: 32781 showInAdvancedViewOnly: TRUE adminDisplayName: ms-Exch-KM-Server oMObjectClass:: KwwCh3McAIVK adminDescription: ms-Exch-KM-Server oMSyntax: 127 searchFlags: 0 lDAPDisplayName: kMServer name: ms-Exch-KM-Server schemaIDGUID: 1677581e-47f3-11d1-a9c3-0000f80367c1 attributeSecurityGUID: e48d0154-bcf8-11d1-8702-00c04fb96050 isMemberOfPartialAttributeSet: FALSE objectCategory: CN=Attribute-Schema,${SCHEMADN} # # ms-Exch-LabeledURI # #dn: CN=ms-Exch-LabeledURI,${SCHEMADN} #objectClass: top #objectClass: attributeSchema #cn: ms-Exch-LabeledURI #distinguishedName: CN=ms-Exch-LabeledURI,${SCHEMADN} #attributeID: 1.2.840.113556.1.2.593 #attributeSyntax: 2.5.5.12 #isSingleValued: FALSE #rangeLower: 1 #rangeUpper: 1024 #mAPIID: 35921 #adminDisplayName: ms-Exch-LabeledURI #adminDescription: ms-Exch-LabeledURI #oMSyntax: 64 #searchFlags: 0 #lDAPDisplayName: msExchLabeledURI #name: ms-Exch-LabeledURI #schemaIDGUID: 16775820-47f3-11d1-a9c3-0000f80367c1 #attributeSecurityGUID: e48d0154-bcf8-11d1-8702-00c04fb96050 #objectCategory: CN=Attribute-Schema,${SCHEMADN} # # ms-Exch-Language # dn: CN=ms-Exch-Language,${SCHEMADN} objectClass: top objectClass: attributeSchema cn: ms-Exch-Language distinguishedName: CN=ms-Exch-Language,${SCHEMADN} attributeID: 1.2.840.113556.1.2.467 attributeSyntax: 2.5.5.9 isSingleValued: TRUE mAPIID: 33144 showInAdvancedViewOnly: TRUE adminDisplayName: ms-Exch-Language adminDescription: ms-Exch-Language oMSyntax: 2 searchFlags: 0 lDAPDisplayName: languageCode name: ms-Exch-Language schemaIDGUID: bf967994-0de6-11d0-a285-00aa003049e2 attributeSecurityGUID: e48d0154-bcf8-11d1-8702-00c04fb96050 isMemberOfPartialAttributeSet: FALSE objectCategory: CN=Attribute-Schema,${SCHEMADN} # # ms-Exch-Language-ISO639 # The ISO-639 language code identifying a user's language. # dn: CN=ms-Exch-Language-ISO639,${SCHEMADN} objectClass: top objectClass: attributeSchema cn: ms-Exch-Language-ISO639 distinguishedName: CN=ms-Exch-Language-ISO639,${SCHEMADN} attributeID: 1.2.840.113556.1.2.616 attributeSyntax: 2.5.5.12 isSingleValued: TRUE rangeLower: 1 rangeUpper: 64 mAPIID: 35948 showInAdvancedViewOnly: TRUE adminDisplayName: ms-Exch-Language-ISO639 adminDescription: ms-Exch-Language-ISO639 oMSyntax: 64 searchFlags: 0 lDAPDisplayName: language name: ms-Exch-Language-ISO639 schemaIDGUID: 16775821-47f3-11d1-a9c3-0000f80367c1 attributeSecurityGUID: e48d0154-bcf8-11d1-8702-00c04fb96050 isMemberOfPartialAttributeSet: FALSE objectCategory: CN=Attribute-Schema,${SCHEMADN} # # ms-Exch-LDAP-Search-Cfg # dn: CN=ms-Exch-LDAP-Search-Cfg,${SCHEMADN} objectClass: top objectClass: attributeSchema cn: ms-Exch-LDAP-Search-Cfg distinguishedName: CN=ms-Exch-LDAP-Search-Cfg,${SCHEMADN} attributeID: 1.2.840.113556.1.2.552 attributeSyntax: 2.5.5.9 isSingleValued: TRUE rangeLower: 0 rangeUpper: 2 mAPIID: 35869 showInAdvancedViewOnly: TRUE adminDisplayName: ms-Exch-LDAP-Search-Cfg adminDescription: ms-Exch-LDAP-Search-Cfg oMSyntax: 10 searchFlags: 0 lDAPDisplayName: lDAPSearchCfg name: ms-Exch-LDAP-Search-Cfg schemaIDGUID: a8df7417-c5ea-11d1-bbcb-0080c76670c0 isMemberOfPartialAttributeSet: FALSE objectCategory: CN=Attribute-Schema,${SCHEMADN} # # ms-Exch-Legacy-Account # dn: CN=ms-Exch-Legacy-Account,${SCHEMADN} objectClass: top objectClass: attributeSchema cn: ms-Exch-Legacy-Account distinguishedName: CN=ms-Exch-Legacy-Account,${SCHEMADN} attributeID: 1.2.840.113556.1.4.7000.102.50040 attributeSyntax: 2.5.5.12 isSingleValued: TRUE showInAdvancedViewOnly: TRUE adminDisplayName: ms-Exch-Legacy-Account adminDescription: ms-Exch-Legacy-Account oMSyntax: 64 searchFlags: 0 lDAPDisplayName: msExchLegacyAccount name: ms-Exch-Legacy-Account schemaIDGUID: 974c99e1-33fc-11d3-aa6e-00c04f8eedd8 isMemberOfPartialAttributeSet: FALSE objectCategory: CN=Attribute-Schema,${SCHEMADN} # # ms-Exch-Legacy-Domain # dn: CN=ms-Exch-Legacy-Domain,${SCHEMADN} objectClass: top objectClass: attributeSchema cn: ms-Exch-Legacy-Domain distinguishedName: CN=ms-Exch-Legacy-Domain,${SCHEMADN} attributeID: 1.2.840.113556.1.4.7000.102.50041 attributeSyntax: 2.5.5.12 isSingleValued: TRUE showInAdvancedViewOnly: TRUE adminDisplayName: ms-Exch-Legacy-Domain adminDescription: ms-Exch-Legacy-Domain oMSyntax: 64 searchFlags: 0 lDAPDisplayName: msExchLegacyDomain name: ms-Exch-Legacy-Domain schemaIDGUID: 974c99ea-33fc-11d3-aa6e-00c04f8eedd8 isMemberOfPartialAttributeSet: FALSE objectCategory: CN=Attribute-Schema,${SCHEMADN} # # ms-Exch-Legacy-PW # dn: CN=ms-Exch-Legacy-PW,${SCHEMADN} objectClass: top objectClass: attributeSchema cn: ms-Exch-Legacy-PW distinguishedName: CN=ms-Exch-Legacy-PW,${SCHEMADN} attributeID: 1.2.840.113556.1.4.7000.102.50042 attributeSyntax: 2.5.5.12 isSingleValued: TRUE showInAdvancedViewOnly: TRUE adminDisplayName: ms-Exch-Legacy-PW adminDescription: ms-Exch-Legacy-PW oMSyntax: 64 searchFlags: 0 lDAPDisplayName: msExchLegacyPW name: ms-Exch-Legacy-PW schemaIDGUID: 974c99f2-33fc-11d3-aa6e-00c04f8eedd8 isMemberOfPartialAttributeSet: FALSE objectCategory: CN=Attribute-Schema,${SCHEMADN} # # ms-Exch-Line-Wrap # dn: CN=ms-Exch-Line-Wrap,${SCHEMADN} objectClass: top objectClass: attributeSchema cn: ms-Exch-Line-Wrap distinguishedName: CN=ms-Exch-Line-Wrap,${SCHEMADN} attributeID: 1.2.840.113556.1.2.449 attributeSyntax: 2.5.5.9 isSingleValued: TRUE mAPIID: 32964 showInAdvancedViewOnly: TRUE adminDisplayName: ms-Exch-Line-Wrap adminDescription: ms-Exch-Line-Wrap oMSyntax: 2 searchFlags: 0 lDAPDisplayName: lineWrap name: ms-Exch-Line-Wrap schemaIDGUID: a8df7418-c5ea-11d1-bbcb-0080c76670c0 isMemberOfPartialAttributeSet: FALSE objectCategory: CN=Attribute-Schema,${SCHEMADN} # # ms-Exch-List-Public # Lists public data conferences. # dn: CN=ms-Exch-List-Public,${SCHEMADN} objectClass: top objectClass: attributeSchema cn: ms-Exch-List-Public distinguishedName: CN=ms-Exch-List-Public,${SCHEMADN} attributeID: 1.2.840.113556.1.4.7000.102.9011 attributeSyntax: 2.5.5.8 isSingleValued: TRUE showInAdvancedViewOnly: TRUE adminDisplayName: ms-Exch-List-Public adminDescription: ms-Exch-List-Public oMSyntax: 1 searchFlags: 0 lDAPDisplayName: msExchListPublic name: ms-Exch-List-Public schemaIDGUID: a6f634c0-b093-11d2-aa06-00c04f8eedd8 isMemberOfPartialAttributeSet: FALSE objectCategory: CN=Attribute-Schema,${SCHEMADN} # # ms-Exch-List-Public-Folders # dn: CN=ms-Exch-List-Public-Folders,${SCHEMADN} objectClass: top objectClass: attributeSchema cn: ms-Exch-List-Public-Folders distinguishedName: CN=ms-Exch-List-Public-Folders,${SCHEMADN} attributeID: 1.2.840.113556.1.2.592 attributeSyntax: 2.5.5.8 isSingleValued: TRUE mAPIID: 35920 showInAdvancedViewOnly: TRUE adminDisplayName: ms-Exch-List-Public-Folders adminDescription: ms-Exch-List-Public-Folders oMSyntax: 1 searchFlags: 0 lDAPDisplayName: listPublicFolders name: ms-Exch-List-Public-Folders schemaIDGUID: a8df7419-c5ea-11d1-bbcb-0080c76670c0 isMemberOfPartialAttributeSet: FALSE objectCategory: CN=Attribute-Schema,${SCHEMADN} # # ms-Exch-Locales # The set of locales that determine client sort order. # dn: CN=ms-Exch-Locales,${SCHEMADN} objectClass: top objectClass: attributeSchema cn: ms-Exch-Locales distinguishedName: CN=ms-Exch-Locales,${SCHEMADN} attributeID: 1.2.840.113556.1.4.7000.102.50017 attributeSyntax: 2.5.5.9 isSingleValued: FALSE showInAdvancedViewOnly: TRUE adminDisplayName: ms-Exch-Locales adminDescription: ms-Exch-Locales oMSyntax: 2 searchFlags: 0 lDAPDisplayName: msExchLocales name: ms-Exch-Locales schemaIDGUID: a738f698-b093-11d2-aa06-00c04f8eedd8 isMemberOfPartialAttributeSet: FALSE objectCategory: CN=Attribute-Schema,${SCHEMADN} # # ms-Exch-Local-Bridge-Head # dn: CN=ms-Exch-Local-Bridge-Head,${SCHEMADN} objectClass: top objectClass: attributeSchema cn: ms-Exch-Local-Bridge-Head distinguishedName: CN=ms-Exch-Local-Bridge-Head,${SCHEMADN} attributeID: 1.2.840.113556.1.2.311 attributeSyntax: 2.5.5.4 isSingleValued: TRUE rangeLower: 1 rangeUpper: 64 mAPIID: 32966 showInAdvancedViewOnly: TRUE adminDisplayName: ms-Exch-Local-Bridge-Head adminDescription: ms-Exch-Local-Bridge-Head oMSyntax: 20 searchFlags: 0 lDAPDisplayName: localBridgeHead name: ms-Exch-Local-Bridge-Head schemaIDGUID: a8df741a-c5ea-11d1-bbcb-0080c76670c0 isMemberOfPartialAttributeSet: FALSE objectCategory: CN=Attribute-Schema,${SCHEMADN} # # ms-Exch-Local-Bridge-Head-Address # dn: CN=ms-Exch-Local-Bridge-Head-Address,${SCHEMADN} objectClass: top objectClass: attributeSchema cn: ms-Exch-Local-Bridge-Head-Address distinguishedName: CN=ms-Exch-Local-Bridge-Head-Address,${SCHEMADN} attributeID: 1.2.840.113556.1.2.225 attributeSyntax: 2.5.5.4 isSingleValued: TRUE rangeLower: 0 rangeUpper: 1118 mAPIID: 32967 showInAdvancedViewOnly: TRUE adminDisplayName: ms-Exch-Local-Bridge-Head-Address adminDescription: ms-Exch-Local-Bridge-Head-Address oMSyntax: 20 searchFlags: 0 lDAPDisplayName: localBridgeHeadAddress name: ms-Exch-Local-Bridge-Head-Address schemaIDGUID: a8df741b-c5ea-11d1-bbcb-0080c76670c0 isMemberOfPartialAttributeSet: FALSE objectCategory: CN=Attribute-Schema,${SCHEMADN} # # ms-Exch-Local-Domains # dn: CN=ms-Exch-Local-Domains,${SCHEMADN} objectClass: top objectClass: attributeSchema cn: ms-Exch-Local-Domains distinguishedName: CN=ms-Exch-Local-Domains,${SCHEMADN} attributeID: 1.2.840.113556.1.4.7000.102.50032 attributeSyntax: 2.5.5.12 isSingleValued: FALSE showInAdvancedViewOnly: TRUE adminDisplayName: ms-Exch-Local-Domains adminDescription: ms-Exch-Local-Domains oMSyntax: 64 searchFlags: 0 lDAPDisplayName: msExchLocalDomains name: ms-Exch-Local-Domains schemaIDGUID: ab3a1ac7-1df5-11d3-aa5e-00c04f8eedd8 isMemberOfPartialAttributeSet: FALSE objectCategory: CN=Attribute-Schema,${SCHEMADN} # # ms-Exch-Local-Initial-Turn # dn: CN=ms-Exch-Local-Initial-Turn,${SCHEMADN} objectClass: top objectClass: attributeSchema cn: ms-Exch-Local-Initial-Turn distinguishedName: CN=ms-Exch-Local-Initial-Turn,${SCHEMADN} attributeID: 1.2.840.113556.1.2.39 attributeSyntax: 2.5.5.8 isSingleValued: TRUE mAPIID: 32968 showInAdvancedViewOnly: TRUE adminDisplayName: ms-Exch-Local-Initial-Turn adminDescription: ms-Exch-Local-Initial-Turn oMSyntax: 1 searchFlags: 0 lDAPDisplayName: localInitialTurn name: ms-Exch-Local-Initial-Turn schemaIDGUID: a8df741c-c5ea-11d1-bbcb-0080c76670c0 isMemberOfPartialAttributeSet: FALSE objectCategory: CN=Attribute-Schema,${SCHEMADN} # # ms-Exch-Local-Name # The data conference local name. # dn: CN=ms-Exch-Local-Name,${SCHEMADN} objectClass: top objectClass: attributeSchema cn: ms-Exch-Local-Name distinguishedName: CN=ms-Exch-Local-Name,${SCHEMADN} attributeID: 1.2.840.113556.1.4.7000.102.9017 attributeSyntax: 2.5.5.12 isSingleValued: TRUE showInAdvancedViewOnly: TRUE adminDisplayName: ms-Exch-Local-Name adminDescription: ms-Exch-Local-Name oMSyntax: 64 searchFlags: 0 lDAPDisplayName: msExchLocalName name: ms-Exch-Local-Name schemaIDGUID: a7153352-b093-11d2-aa06-00c04f8eedd8 isMemberOfPartialAttributeSet: FALSE objectCategory: CN=Attribute-Schema,${SCHEMADN} # # ms-Exch-Logon-ACL # dn: CN=ms-Exch-Logon-ACL,${SCHEMADN} objectClass: top objectClass: attributeSchema cn: ms-Exch-Logon-ACL distinguishedName: CN=ms-Exch-Logon-ACL,${SCHEMADN} attributeID: 1.2.840.113556.1.4.7000.102.5057 attributeSyntax: 2.5.5.15 isSingleValued: TRUE showInAdvancedViewOnly: TRUE adminDisplayName: ms-Exch-Logon-ACL adminDescription: ms-Exch-Logon-ACL oMSyntax: 66 searchFlags: 0 lDAPDisplayName: msExchLogonACL name: ms-Exch-Logon-ACL schemaIDGUID: 7acf216d-1f42-48ec-b1bb-6ca281fe5b00 isMemberOfPartialAttributeSet: FALSE objectCategory: CN=Attribute-Schema,${SCHEMADN} # # ms-Exch-Logon-Method # Specifies the logon method for clear text logons. # dn: CN=ms-Exch-Logon-Method,${SCHEMADN} objectClass: top objectClass: attributeSchema cn: ms-Exch-Logon-Method distinguishedName: CN=ms-Exch-Logon-Method,${SCHEMADN} attributeID: 1.2.840.113556.1.4.7000.102.15002 attributeSyntax: 2.5.5.9 isSingleValued: TRUE showInAdvancedViewOnly: TRUE adminDisplayName: ms-Exch-Logon-Method adminDescription: ms-Exch-Logon-Method oMSyntax: 2 searchFlags: 0 lDAPDisplayName: msExchLogonMethod name: ms-Exch-Logon-Method schemaIDGUID: 8bcc41ca-b09e-11d2-aa06-00c04f8eedd8 isMemberOfPartialAttributeSet: FALSE objectCategory: CN=Attribute-Schema,${SCHEMADN} # # ms-Exch-Log-Filename # dn: CN=ms-Exch-Log-Filename,${SCHEMADN} objectClass: top objectClass: attributeSchema cn: ms-Exch-Log-Filename distinguishedName: CN=ms-Exch-Log-Filename,${SCHEMADN} attributeID: 1.2.840.113556.1.2.192 attributeSyntax: 2.5.5.12 isSingleValued: TRUE rangeLower: 1 rangeUpper: 256 mAPIID: 32970 showInAdvancedViewOnly: TRUE adminDisplayName: ms-Exch-Log-Filename adminDescription: ms-Exch-Log-Filename oMSyntax: 64 searchFlags: 0 lDAPDisplayName: logFilename name: ms-Exch-Log-Filename schemaIDGUID: a8df741d-c5ea-11d1-bbcb-0080c76670c0 isMemberOfPartialAttributeSet: FALSE objectCategory: CN=Attribute-Schema,${SCHEMADN} # # ms-Exch-Log-Rollover-Interval # dn: CN=ms-Exch-Log-Rollover-Interval,${SCHEMADN} objectClass: top objectClass: attributeSchema cn: ms-Exch-Log-Rollover-Interval distinguishedName: CN=ms-Exch-Log-Rollover-Interval,${SCHEMADN} attributeID: 1.2.840.113556.1.2.348 attributeSyntax: 2.5.5.9 isSingleValued: TRUE mAPIID: 32971 showInAdvancedViewOnly: TRUE adminDisplayName: ms-Exch-Log-Rollover-Interval adminDescription: ms-Exch-Log-Rollover-Interval oMSyntax: 2 searchFlags: 0 lDAPDisplayName: logRolloverInterval name: ms-Exch-Log-Rollover-Interval schemaIDGUID: bf9679a7-0de6-11d0-a285-00aa003049e2 isMemberOfPartialAttributeSet: FALSE objectCategory: CN=Attribute-Schema,${SCHEMADN} # # ms-Exch-Log-Type # The log formats that this resource writes to. dn: CN=ms-Exch-Log-Type,${SCHEMADN} objectClass: top objectClass: attributeSchema cn: ms-Exch-Log-Type distinguishedName: CN=ms-Exch-Log-Type,${SCHEMADN} attributeID: 1.2.840.113556.1.4.7000.102.2005 attributeSyntax: 2.5.5.9 isSingleValued: TRUE showInAdvancedViewOnly: TRUE adminDisplayName: ms-Exch-Log-Type adminDescription: ms-Exch-Log-Type oMSyntax: 2 searchFlags: 0 lDAPDisplayName: msExchLogType name: ms-Exch-Log-Type schemaIDGUID: a75a5784-b093-11d2-aa06-00c04f8eedd8 isMemberOfPartialAttributeSet: FALSE objectCategory: CN=Attribute-Schema,${SCHEMADN} # # ms-Exch-Mailbox-Folder-Set # dn: CN=ms-Exch-Mailbox-Folder-Set,${SCHEMADN} objectClass: top objectClass: attributeSchema cn: ms-Exch-Mailbox-Folder-Set distinguishedName: CN=ms-Exch-Mailbox-Folder-Set,${SCHEMADN} attributeID: 1.2.840.113556.1.4.7000.102.11091 attributeSyntax: 2.5.5.9 isSingleValued: TRUE showInAdvancedViewOnly: TRUE adminDisplayName: ms-Exch-Mailbox-Folder-Set adminDescription: ms-Exch-Mailbox-Folder-Set oMSyntax: 2 searchFlags: 0 lDAPDisplayName: msExchMailboxFolderSet name: ms-Exch-Mailbox-Folder-Set schemaIDGUID: d72941ba-ffd0-4d8e-bb85-97713440c8a3 attributeSecurityGUID: e48d0154-bcf8-11d1-8702-00c04fb96050 isMemberOfPartialAttributeSet: TRUE objectCategory: CN=Attribute-Schema,${SCHEMADN} # # ms-Exch-Mailbox-Guid # The GUID of the user's mailbox. # dn: CN=ms-Exch-Mailbox-Guid,${SCHEMADN} objectClass: top objectClass: attributeSchema cn: ms-Exch-Mailbox-Guid distinguishedName: CN=ms-Exch-Mailbox-Guid,${SCHEMADN} attributeID: 1.2.840.113556.1.4.7000.102.11058 attributeSyntax: 2.5.5.10 isSingleValued: TRUE rangeLower: 16 rangeUpper: 16 mAPIID: 35955 showInAdvancedViewOnly: TRUE adminDisplayName: ms-Exch-Mailbox-Guid adminDescription: ms-Exch-Mailbox-Guid oMSyntax: 4 searchFlags: 9 lDAPDisplayName: msExchMailboxGuid name: ms-Exch-Mailbox-Guid schemaIDGUID: 9333af48-b09e-11d2-aa06-00c04f8eedd8 attributeSecurityGUID: e48d0154-bcf8-11d1-8702-00c04fb96050 isMemberOfPartialAttributeSet: TRUE objectCategory: CN=Attribute-Schema,${SCHEMADN} # # ms-Exch-Mailbox-Manager-Activation-Schedule # When the mailbox clean process should be started. # dn: CN=ms-Exch-Mailbox-Manager-Activation-Schedule,${SCHEMADN} objectClass: top objectClass: attributeSchema cn: ms-Exch-Mailbox-Manager-Activation-Schedule distinguishedName: CN=ms-Exch-Mailbox-Manager-Activation-Schedule,${SCHEMADN} attributeID: 1.2.840.113556.1.4.7000.102.50067 attributeSyntax: 2.5.5.10 isSingleValued: TRUE rangeLower: 84 rangeUpper: 84 showInAdvancedViewOnly: TRUE adminDisplayName: ms-Exch-Mailbox-Manager-Activation-Schedule adminDescription: ms-Exch-Mailbox-Manager-Activation-Schedule oMSyntax: 4 searchFlags: 0 lDAPDisplayName: msExchMailboxManagerActivationSchedule name: ms-Exch-Mailbox-Manager-Activation-Schedule schemaIDGUID: 829122d7-25b1-4be6-a2e3-d8453c950938 isMemberOfPartialAttributeSet: FALSE objectCategory: CN=Attribute-Schema,${SCHEMADN} # # ms-Exch-Mailbox-Manager-Activation-Style # dn: CN=ms-Exch-Mailbox-Manager-Activation-Style,${SCHEMADN} objectClass: top objectClass: attributeSchema cn: ms-Exch-Mailbox-Manager-Activation-Style distinguishedName: CN=ms-Exch-Mailbox-Manager-Activation-Style,${SCHEMADN} attributeID: 1.2.840.113556.1.4.7000.102.50068 attributeSyntax: 2.5.5.9 isSingleValued: TRUE rangeLower: 0 rangeUpper: 3 showInAdvancedViewOnly: TRUE adminDisplayName: ms-Exch-Mailbox-Manager-Activation-Style adminDescription: ms-Exch-Mailbox-Manager-Activation-Style oMSyntax: 2 searchFlags: 0 lDAPDisplayName: msExchMailboxManagerActivationStyle name: ms-Exch-Mailbox-Manager-Activation-Style schemaIDGUID: 9ea95949-7d74-49cd-af09-3db0870e535e isMemberOfPartialAttributeSet: FALSE objectCategory: CN=Attribute-Schema,${SCHEMADN} # # ms-Exch-Mailbox-Manager-Admin-Mode # The summary mode for this policy (MCASM_NONE, MCASM_SUMMARY_ONLY, # MCASM_DETAILED_REPORT). # dn: CN=ms-Exch-Mailbox-Manager-Admin-Mode,${SCHEMADN} objectClass: top objectClass: attributeSchema cn: ms-Exch-Mailbox-Manager-Admin-Mode distinguishedName: CN=ms-Exch-Mailbox-Manager-Admin-Mode,${SCHEMADN} attributeID: 1.2.840.113556.1.4.7000.102.50077 attributeSyntax: 2.5.5.9 isSingleValued: TRUE showInAdvancedViewOnly: TRUE adminDisplayName: ms-Exch-Mailbox-Manager-Admin-Mode adminDescription: ms-Exch-Mailbox-Manager-Admin-Mode oMSyntax: 2 searchFlags: 0 lDAPDisplayName: msExchMailboxManagerAdminMode name: ms-Exch-Mailbox-Manager-Admin-Mode schemaIDGUID: 9a6b371e-a3e7-4266-9b7b-2ce454336f90 isMemberOfPartialAttributeSet: FALSE objectCategory: CN=Attribute-Schema,${SCHEMADN} # # ms-Exch-Mailbox-Manager-Age-Limit # The age at which messages larger than the specified size limit are # deleted. # dn: CN=ms-Exch-Mailbox-Manager-Age-Limit,${SCHEMADN} objectClass: top objectClass: attributeSchema cn: ms-Exch-Mailbox-Manager-Age-Limit distinguishedName: CN=ms-Exch-Mailbox-Manager-Age-Limit,${SCHEMADN} attributeID: 1.2.840.113556.1.4.7000.102.50081 attributeSyntax: 2.5.5.9 isSingleValued: TRUE showInAdvancedViewOnly: TRUE adminDisplayName: ms-Exch-Mailbox-Manager-Age-Limit adminDescription: ms-Exch-Mailbox-Manager-Age-Limit oMSyntax: 2 searchFlags: 0 lDAPDisplayName: msExchMailboxManagerAgeLimit name: ms-Exch-Mailbox-Manager-Age-Limit schemaIDGUID: cd63db2c-8aa9-4a14-941b-1b59fdcaafbd isMemberOfPartialAttributeSet: FALSE objectCategory: CN=Attribute-Schema,${SCHEMADN} # # ms-Exch-Mailbox-Manager-Custom-Message # Indicates that a custom message is being used. # dn: CN=ms-Exch-Mailbox-Manager-Custom-Message,${SCHEMADN} objectClass: top objectClass: attributeSchema cn: ms-Exch-Mailbox-Manager-Custom-Message distinguishedName: CN=ms-Exch-Mailbox-Manager-Custom-Message,${SCHEMADN} attributeID: 1.2.840.113556.1.4.7000.102.50070 attributeSyntax: 2.5.5.8 isSingleValued: TRUE showInAdvancedViewOnly: TRUE adminDisplayName: ms-Exch-Mailbox-Manager-Custom-Message adminDescription: ms-Exch-Mailbox-Manager-Custom-Message oMSyntax: 1 searchFlags: 0 lDAPDisplayName: msExchMailboxManagerCustomMessage name: ms-Exch-Mailbox-Manager-Custom-Message schemaIDGUID: 8681f0bc-24d6-4d58-bc16-62f73cd5bedb isMemberOfPartialAttributeSet: FALSE objectCategory: CN=Attribute-Schema,${SCHEMADN} # # ms-Exch-Mailbox-Manager-Folder-Settings # Settings for each folder or store (Enabled, Folder-Name, Age-Limit, # Size-Limit). A limit of -1 should be interpreted as "Any". # dn: CN=ms-Exch-Mailbox-Manager-Folder-Settings,${SCHEMADN} objectClass: top objectClass: attributeSchema cn: ms-Exch-Mailbox-Manager-Folder-Settings distinguishedName: CN=ms-Exch-Mailbox-Manager-Folder-Settings,${SCHEMADN} attributeID: 1.2.840.113556.1.4.7000.102.50078 attributeSyntax: 2.5.5.12 isSingleValued: FALSE showInAdvancedViewOnly: TRUE adminDisplayName: ms-Exch-Mailbox-Manager-Folder-Settings adminDescription: ms-Exch-Mailbox-Manager-Folder-Settings oMSyntax: 64 searchFlags: 0 lDAPDisplayName: msExchMailboxManagerFolderSettings name: ms-Exch-Mailbox-Manager-Folder-Settings schemaIDGUID: a57cf645-4b12-4ee4-a6eb-fce022068ffd isMemberOfPartialAttributeSet: FALSE objectCategory: CN=Attribute-Schema,${SCHEMADN} # # ms-Exch-Mailbox-Manager-Keep-Message-Classes # The message classes that should not be deleted. # dn: CN=ms-Exch-Mailbox-Manager-Keep-Message-Classes,${SCHEMADN} objectClass: top objectClass: attributeSchema cn: ms-Exch-Mailbox-Manager-Keep-Message-Classes distinguishedName: CN=ms-Exch-Mailbox-Manager-Keep-Message-Classes,${SCHEMADN} attributeID: 1.2.840.113556.1.4.7000.102.50074 attributeSyntax: 2.5.5.12 isSingleValued: FALSE showInAdvancedViewOnly: TRUE adminDisplayName: ms-Exch-Mailbox-Manager-Keep-Message-Classes adminDescription: ms-Exch-Mailbox-Manager-Keep-Message-Classes oMSyntax: 64 searchFlags: 0 lDAPDisplayName: msExchMailboxManagerKeepMessageClasses name: ms-Exch-Mailbox-Manager-Keep-Message-Classes schemaIDGUID: 0044d40c-6a24-4b57-abce-f555cc724c8e isMemberOfPartialAttributeSet: FALSE objectCategory: CN=Attribute-Schema,${SCHEMADN} # # ms-Exch-Mailbox-Manager-Mode # Cleanup mode for this policy (MCACM_AUDIT, # MCACM_CLEANMCADM_DELETED_ITEMS, MCADM_SYSTEM_CLEANUP, # MCADM_JUST_DELETE). # dn: CN=ms-Exch-Mailbox-Manager-Mode,${SCHEMADN} objectClass: top objectClass: attributeSchema cn: ms-Exch-Mailbox-Manager-Mode distinguishedName: CN=ms-Exch-Mailbox-Manager-Mode,${SCHEMADN} attributeID: 1.2.840.113556.1.4.7000.102.50075 attributeSyntax: 2.5.5.9 isSingleValued: TRUE showInAdvancedViewOnly: TRUE adminDisplayName: ms-Exch-Mailbox-Manager-Mode adminDescription: ms-Exch-Mailbox-Manager-Mode oMSyntax: 2 searchFlags: 0 lDAPDisplayName: msExchMailboxManagerMode name: ms-Exch-Mailbox-Manager-Mode schemaIDGUID: 9bd7499b-282b-4eb6-a40e-7d044d896741 isMemberOfPartialAttributeSet: FALSE objectCategory: CN=Attribute-Schema,${SCHEMADN} # # ms-Exch-Mailbox-Manager-Report-Recipient # The recipient of summary reports. # dn: CN=ms-Exch-Mailbox-Manager-Report-Recipient,${SCHEMADN} objectClass: top objectClass: attributeSchema cn: ms-Exch-Mailbox-Manager-Report-Recipient distinguishedName: CN=ms-Exch-Mailbox-Manager-Report-Recipient,${SCHEMADN} attributeID: 1.2.840.113556.1.4.7000.102.50076 attributeSyntax: 2.5.5.1 isSingleValued: TRUE showInAdvancedViewOnly: TRUE adminDisplayName: ms-Exch-Mailbox-Manager-Report-Recipient oMObjectClass:: KwwCh3McAIVK adminDescription: ms-Exch-Mailbox-Manager-Report-Recipient oMSyntax: 127 searchFlags: 0 lDAPDisplayName: msExchMailboxManagerReportRecipient name: ms-Exch-Mailbox-Manager-Report-Recipient schemaIDGUID: 445791fb-e6fc-48dd-aad5-32e32c9059d9 isMemberOfPartialAttributeSet: FALSE objectCategory: CN=Attribute-Schema,${SCHEMADN} # # ms-Exch-Mailbox-Manager-Send-User-Notification-Mail # Sends a notification to the user after a clean operation. # dn: CN=ms-Exch-Mailbox-Manager-Send-User-Notification-Mail,${SCHEMADN} objectClass: top objectClass: attributeSchema cn: ms-Exch-Mailbox-Manager-Send-User-Notification-Mail distinguishedName: CN=ms-Exch-Mailbox-Manager-Send-User-Notification-Mail,CN=S attributeID: 1.2.840.113556.1.4.7000.102.50069 attributeSyntax: 2.5.5.8 isSingleValued: TRUE showInAdvancedViewOnly: TRUE adminDisplayName: ms-Exch-Mailbox-Manager-Send-User-Notification-Mail adminDescription: ms-Exch-Mailbox-Manager-Send-User-Notification-Mail oMSyntax: 1 searchFlags: 0 lDAPDisplayName: msExchMailboxManagerSendUserNotificationMail name: ms-Exch-Mailbox-Manager-Send-User-Notification-Mail schemaIDGUID: d2888db3-2b0d-4d6a-831e-4efdfc036584 isMemberOfPartialAttributeSet: FALSE objectCategory: CN=Attribute-Schema,${SCHEMADN} # # ms-Exch-Mailbox-Manager-Size-Limit # Messages larger than this size will be deleted automatically when # their age exceeds the age limit. # dn: CN=ms-Exch-Mailbox-Manager-Size-Limit,${SCHEMADN} objectClass: top objectClass: attributeSchema cn: ms-Exch-Mailbox-Manager-Size-Limit distinguishedName: CN=ms-Exch-Mailbox-Manager-Size-Limit,${SCHEMADN} attributeID: 1.2.840.113556.1.4.7000.102.50080 attributeSyntax: 2.5.5.9 isSingleValued: TRUE showInAdvancedViewOnly: TRUE adminDisplayName: ms-Exch-Mailbox-Manager-Size-Limit adminDescription: ms-Exch-Mailbox-Manager-Size-Limit oMSyntax: 2 searchFlags: 0 lDAPDisplayName: msExchMailboxManagerSizeLimit name: ms-Exch-Mailbox-Manager-Size-Limit schemaIDGUID: 92d9302b-76bd-4156-95a1-f5b6a1463eb4 isMemberOfPartialAttributeSet: FALSE objectCategory: CN=Attribute-Schema,${SCHEMADN} # # ms-Exch-Mailbox-Manager-Size-Limit-Enabled # Determines if a size limit is in effect. # dn: CN=ms-Exch-Mailbox-Manager-Size-Limit-Enabled,${SCHEMADN} objectClass: top objectClass: attributeSchema cn: ms-Exch-Mailbox-Manager-Size-Limit-Enabled distinguishedName: CN=ms-Exch-Mailbox-Manager-Size-Limit-Enabled,${SCHEMADN} attributeID: 1.2.840.113556.1.4.7000.102.50079 attributeSyntax: 2.5.5.8 isSingleValued: TRUE showInAdvancedViewOnly: TRUE adminDisplayName: ms-Exch-Mailbox-Manager-Size-Limit-Enabled adminDescription: ms-Exch-Mailbox-Manager-Size-Limit-Enabled oMSyntax: 1 searchFlags: 0 lDAPDisplayName: msExchMailboxManagerSizeLimitEnabled name: ms-Exch-Mailbox-Manager-Size-Limit-Enabled schemaIDGUID: 1563eae5-3ac1-4274-9e59-7d2fcc836f82 isMemberOfPartialAttributeSet: FALSE objectCategory: CN=Attribute-Schema,${SCHEMADN} # # ms-Exch-Mailbox-Manager-User-Message-Body # The mail notification message body. # dn: CN=ms-Exch-Mailbox-Manager-User-Message-Body,${SCHEMADN} objectClass: top objectClass: attributeSchema cn: ms-Exch-Mailbox-Manager-User-Message-Body distinguishedName: CN=ms-Exch-Mailbox-Manager-User-Message-Body,${SCHEMADN} attributeID: 1.2.840.113556.1.4.7000.102.50072 attributeSyntax: 2.5.5.12 isSingleValued: TRUE showInAdvancedViewOnly: TRUE adminDisplayName: ms-Exch-Mailbox-Manager-User-Message-Body adminDescription: ms-Exch-Mailbox-Manager-User-Message-Body oMSyntax: 64 searchFlags: 0 lDAPDisplayName: msExchMailboxManagerUserMessageBody name: ms-Exch-Mailbox-Manager-User-Message-Body schemaIDGUID: 9ec3ccac-09fa-4a22-869f-9144258d230d isMemberOfPartialAttributeSet: FALSE objectCategory: CN=Attribute-Schema,${SCHEMADN} # # ms-Exch-Mailbox-Manager-User-Message-Footer # The mail notification message footer. # dn: CN=ms-Exch-Mailbox-Manager-User-Message-Footer,${SCHEMADN} objectClass: top objectClass: attributeSchema cn: ms-Exch-Mailbox-Manager-User-Message-Footer distinguishedName: CN=ms-Exch-Mailbox-Manager-User-Message-Footer,${SCHEMADN} attributeID: 1.2.840.113556.1.4.7000.102.50073 attributeSyntax: 2.5.5.12 isSingleValued: TRUE showInAdvancedViewOnly: TRUE adminDisplayName: ms-Exch-Mailbox-Manager-User-Message-Footer adminDescription: ms-Exch-Mailbox-Manager-User-Message-Footer oMSyntax: 64 searchFlags: 0 lDAPDisplayName: msExchMailboxManagerUserMessageFooter name: ms-Exch-Mailbox-Manager-User-Message-Footer schemaIDGUID: 33795abb-57ba-43ec-9f7e-a4601c2e4d4f isMemberOfPartialAttributeSet: FALSE objectCategory: CN=Attribute-Schema,${SCHEMADN} # # ms-Exch-Mailbox-Manager-User-Message-Header # The mail notification message header. # dn: CN=ms-Exch-Mailbox-Manager-User-Message-Header,${SCHEMADN} objectClass: top objectClass: attributeSchema cn: ms-Exch-Mailbox-Manager-User-Message-Header distinguishedName: CN=ms-Exch-Mailbox-Manager-User-Message-Header,${SCHEMADN} attributeID: 1.2.840.113556.1.4.7000.102.50071 attributeSyntax: 2.5.5.12 isSingleValued: TRUE showInAdvancedViewOnly: TRUE adminDisplayName: ms-Exch-Mailbox-Manager-User-Message-Header adminDescription: ms-Exch-Mailbox-Manager-User-Message-Header oMSyntax: 64 searchFlags: 0 lDAPDisplayName: msExchMailboxManagerUserMessageHeader name: ms-Exch-Mailbox-Manager-User-Message-Header schemaIDGUID: fbcffefe-8916-4ce6-ac76-eab226fe5440 isMemberOfPartialAttributeSet: FALSE objectCategory: CN=Attribute-Schema,${SCHEMADN} # # ms-Exch-Mailbox-Retention-Period # The number of days to retain deleted mailboxes before purging them. # dn: CN=ms-Exch-Mailbox-Retention-Period,${SCHEMADN} objectClass: top objectClass: attributeSchema cn: ms-Exch-Mailbox-Retention-Period distinguishedName: CN=ms-Exch-Mailbox-Retention-Period,${SCHEMADN} attributeID: 1.2.840.113556.1.4.7000.102.11060 attributeSyntax: 2.5.5.9 isSingleValued: TRUE showInAdvancedViewOnly: TRUE adminDisplayName: ms-Exch-Mailbox-Retention-Period adminDescription: ms-Exch-Mailbox-Retention-Period oMSyntax: 2 searchFlags: 0 lDAPDisplayName: msExchMailboxRetentionPeriod name: ms-Exch-Mailbox-Retention-Period schemaIDGUID: 7b4a7a8a-1876-11d3-aa59-00c04f8eedd8 isMemberOfPartialAttributeSet: FALSE objectCategory: CN=Attribute-Schema,${SCHEMADN} # # ms-Exch-Mailbox-Security-Descriptor # The security descriptor of the user's mailbox. # dn: CN=ms-Exch-Mailbox-Security-Descriptor,${SCHEMADN} objectClass: top objectClass: attributeSchema cn: ms-Exch-Mailbox-Security-Descriptor distinguishedName: CN=ms-Exch-Mailbox-Security-Descriptor,${SCHEMADN} attributeID: 1.2.840.113556.1.4.7000.102.80 attributeSyntax: 2.5.5.15 isSingleValued: TRUE rangeLower: 0 rangeUpper: 65535 mAPIID: 35956 showInAdvancedViewOnly: TRUE adminDisplayName: ms-Exch-Mailbox-Security-Descriptor adminDescription: ms-Exch-Mailbox-Security-Descriptor oMSyntax: 66 searchFlags: 8 lDAPDisplayName: msExchMailboxSecurityDescriptor name: ms-Exch-Mailbox-Security-Descriptor schemaIDGUID: 934de926-b09e-11d2-aa06-00c04f8eedd8 attributeSecurityGUID: e48d0154-bcf8-11d1-8702-00c04fb96050 isMemberOfPartialAttributeSet: TRUE objectCategory: CN=Attribute-Schema,${SCHEMADN} # # ms-Exch-Mailbox-Url # The URL to a user's mailbox. # dn: CN=ms-Exch-Mailbox-Url,${SCHEMADN} objectClass: top objectClass: attributeSchema cn: ms-Exch-Mailbox-Url distinguishedName: CN=ms-Exch-Mailbox-Url,${SCHEMADN} attributeID: 1.2.840.113556.1.4.7000.102.50085 attributeSyntax: 2.5.5.12 isSingleValued: TRUE mAPIID: 35967 showInAdvancedViewOnly: TRUE adminDisplayName: ms-Exch-Mailbox-Url adminDescription: ms-Exch-Mailbox-Url oMSyntax: 64 searchFlags: 0 lDAPDisplayName: msExchMailboxUrl name: ms-Exch-Mailbox-Url schemaIDGUID: fc1ffd10-ae3f-466c-87c7-518b91dadbd0 attributeSecurityGUID: e48d0154-bcf8-11d1-8702-00c04fb96050 isMemberOfPartialAttributeSet: TRUE objectCategory: CN=Attribute-Schema,${SCHEMADN} # # ms-Exch-Mail-Nickname # dn: CN=ms-Exch-Mail-Nickname,${SCHEMADN} objectClass: top objectClass: attributeSchema cn: ms-Exch-Mail-Nickname distinguishedName: CN=ms-Exch-Mail-Nickname,${SCHEMADN} attributeID: 1.2.840.113556.1.2.447 attributeSyntax: 2.5.5.12 isSingleValued: TRUE rangeLower: 1 rangeUpper: 64 mAPIID: 14848 showInAdvancedViewOnly: TRUE adminDisplayName: ms-Exch-Mail-Nickname adminDescription: ms-Exch-Mail-Nickname oMSyntax: 64 searchFlags: 5 lDAPDisplayName: mailNickname name: ms-Exch-Mail-Nickname schemaIDGUID: bf9679b3-0de6-11d0-a285-00aa003049e2 attributeSecurityGUID: e48d0154-bcf8-11d1-8702-00c04fb96050 isMemberOfPartialAttributeSet: TRUE objectCategory: CN=Attribute-Schema,${SCHEMADN} # # ms-Exch-Maintenance-Schedule # dn: CN=ms-Exch-Maintenance-Schedule,${SCHEMADN} objectClass: top objectClass: attributeSchema cn: ms-Exch-Maintenance-Schedule distinguishedName: CN=ms-Exch-Maintenance-Schedule,${SCHEMADN} attributeID: 1.2.840.113556.1.4.7000.102.1029 attributeSyntax: 2.5.5.10 isSingleValued: TRUE rangeLower: 84 rangeUpper: 84 showInAdvancedViewOnly: TRUE adminDisplayName: ms-Exch-Maintenance-Schedule adminDescription: ms-Exch-Maintenance-Schedule oMSyntax: 4 searchFlags: 0 lDAPDisplayName: msExchMaintenanceSchedule name: ms-Exch-Maintenance-Schedule schemaIDGUID: 8fa76ef0-25d7-11d3-aa68-00c04f8eedd8 isMemberOfPartialAttributeSet: FALSE objectCategory: CN=Attribute-Schema,${SCHEMADN} # # ms-Exch-Maintenance-Style # dn: CN=ms-Exch-Maintenance-Style,${SCHEMADN} objectClass: top objectClass: attributeSchema cn: ms-Exch-Maintenance-Style distinguishedName: CN=ms-Exch-Maintenance-Style,${SCHEMADN} attributeID: 1.2.840.113556.1.4.7000.102.1030 attributeSyntax: 2.5.5.9 isSingleValued: TRUE rangeLower: 0 rangeUpper: 3 showInAdvancedViewOnly: TRUE adminDisplayName: ms-Exch-Maintenance-Style adminDescription: ms-Exch-Maintenance-Style oMSyntax: 2 searchFlags: 0 lDAPDisplayName: msExchMaintenanceStyle name: ms-Exch-Maintenance-Style schemaIDGUID: 8fa76ef6-25d7-11d3-aa68-00c04f8eedd8 isMemberOfPartialAttributeSet: FALSE objectCategory: CN=Attribute-Schema,${SCHEMADN} # # ms-Exch-Mandatory-Attributes # dn: CN=ms-Exch-Mandatory-Attributes,${SCHEMADN} objectClass: top objectClass: attributeSchema cn: ms-Exch-Mandatory-Attributes distinguishedName: CN=ms-Exch-Mandatory-Attributes,${SCHEMADN} attributeID: 1.2.840.113556.1.4.7000.102.50029 attributeSyntax: 2.5.5.12 isSingleValued: FALSE showInAdvancedViewOnly: TRUE adminDisplayName: ms-Exch-Mandatory-Attributes adminDescription: ms-Exch-Mandatory-Attributes oMSyntax: 64 searchFlags: 0 lDAPDisplayName: msExchMandatoryAttributes name: ms-Exch-Mandatory-Attributes schemaIDGUID: e32977be-1d31-11d3-aa5e-00c04f8eedd8 isMemberOfPartialAttributeSet: FALSE objectCategory: CN=Attribute-Schema,${SCHEMADN} # # ms-Exch-MAPI-Recipient # dn: CN=ms-Exch-MAPI-Recipient,${SCHEMADN} objectClass: top objectClass: attributeSchema cn: ms-Exch-MAPI-Recipient distinguishedName: CN=ms-Exch-MAPI-Recipient,${SCHEMADN} attributeID: 1.2.840.113556.1.2.371 attributeSyntax: 2.5.5.8 isSingleValued: TRUE mAPIID: 14912 showInAdvancedViewOnly: TRUE adminDisplayName: ms-Exch-MAPI-Recipient adminDescription: ms-Exch-MAPI-Recipient oMSyntax: 1 searchFlags: 16 lDAPDisplayName: mAPIRecipient name: ms-Exch-MAPI-Recipient schemaIDGUID: bf9679b8-0de6-11d0-a285-00aa003049e2 attributeSecurityGUID: e48d0154-bcf8-11d1-8702-00c04fb96050 isMemberOfPartialAttributeSet: TRUE objectCategory: CN=Attribute-Schema,${SCHEMADN} # # ms-Exch-Master-Account-Sid # dn: CN=ms-Exch-Master-Account-Sid,${SCHEMADN} objectClass: top objectClass: attributeSchema cn: ms-Exch-Master-Account-Sid distinguishedName: CN=ms-Exch-Master-Account-Sid,${SCHEMADN} attributeID: 1.2.840.113556.1.4.7000.102.81 attributeSyntax: 2.5.5.17 isSingleValued: TRUE rangeLower: 0 rangeUpper: 28 mAPIID: 35957 showInAdvancedViewOnly: TRUE adminDisplayName: ms-Exch-Master-Account-Sid adminDescription: ms-Exch-Master-Account-Sid oMSyntax: 4 searchFlags: 9 lDAPDisplayName: msExchMasterAccountSid name: ms-Exch-Master-Account-Sid schemaIDGUID: 936a855e-b09e-11d2-aa06-00c04f8eedd8 attributeSecurityGUID: e48d0154-bcf8-11d1-8702-00c04fb96050 isMemberOfPartialAttributeSet: TRUE objectCategory: CN=Attribute-Schema,${SCHEMADN} # # ms-Exch-Master-Service # The Address List Service master server. # dn: CN=ms-Exch-Master-Service,${SCHEMADN} objectClass: top objectClass: attributeSchema cn: ms-Exch-Master-Service distinguishedName: CN=ms-Exch-Master-Service,${SCHEMADN} attributeID: 1.2.840.113556.1.4.7000.102.82 attributeSyntax: 2.5.5.1 isSingleValued: TRUE linkID: 1022 showInAdvancedViewOnly: TRUE adminDisplayName: ms-Exch-Master-Service oMObjectClass:: KwwCh3McAIVK adminDescription: ms-Exch-Master-Service oMSyntax: 127 searchFlags: 0 lDAPDisplayName: msExchMasterService name: ms-Exch-Master-Service schemaIDGUID: 944d04c4-b09e-11d2-aa06-00c04f8eedd8 isMemberOfPartialAttributeSet: FALSE objectCategory: CN=Attribute-Schema,${SCHEMADN} # # ms-Exch-Master-Service-BL # A backlink to the Address List Service master server. # dn: CN=ms-Exch-Master-Service-BL,${SCHEMADN} objectClass: top objectClass: attributeSchema cn: ms-Exch-Master-Service-BL distinguishedName: CN=ms-Exch-Master-Service-BL,${SCHEMADN} attributeID: 1.2.840.113556.1.4.7000.102.83 attributeSyntax: 2.5.5.1 isSingleValued: TRUE linkID: 1023 showInAdvancedViewOnly: TRUE adminDisplayName: ms-Exch-Master-Service-BL oMObjectClass:: KwwCh3McAIVK adminDescription: ms-Exch-Master-Service-BL oMSyntax: 127 searchFlags: 0 lDAPDisplayName: msExchMasterServiceBL name: ms-Exch-Master-Service-BL schemaIDGUID: 946c0356-b09e-11d2-aa06-00c04f8eedd8 systemFlags: 1 isMemberOfPartialAttributeSet: FALSE objectCategory: CN=Attribute-Schema,${SCHEMADN} # # ms-Exch-Maximum-Object-ID # dn: CN=ms-Exch-Maximum-Object-ID,${SCHEMADN} objectClass: top objectClass: attributeSchema cn: ms-Exch-Maximum-Object-ID distinguishedName: CN=ms-Exch-Maximum-Object-ID,${SCHEMADN} attributeID: 1.2.840.113556.1.2.458 attributeSyntax: 2.5.5.10 isSingleValued: TRUE rangeLower: 1 rangeUpper: 22 mAPIID: 33129 showInAdvancedViewOnly: TRUE adminDisplayName: ms-Exch-Maximum-Object-ID adminDescription: ms-Exch-Maximum-Object-ID oMSyntax: 4 searchFlags: 0 lDAPDisplayName: maximumObjectID name: ms-Exch-Maximum-Object-ID schemaIDGUID: a8df741e-c5ea-11d1-bbcb-0080c76670c0 isMemberOfPartialAttributeSet: FALSE objectCategory: CN=Attribute-Schema,${SCHEMADN} # # ms-Exch-Maximum-Recurring-Instances # The maximum number of instances generated per day. # dn: CN=ms-Exch-Maximum-Recurring-Instances,${SCHEMADN} objectClass: top objectClass: attributeSchema cn: ms-Exch-Maximum-Recurring-Instances distinguishedName: CN=ms-Exch-Maximum-Recurring-Instances,${SCHEMADN} attributeID: 1.2.840.113556.1.4.7000.102.10014 attributeSyntax: 2.5.5.9 isSingleValued: TRUE showInAdvancedViewOnly: TRUE adminDisplayName: ms-Exch-Maximum-Recurring-Instances adminDescription: ms-Exch-Maximum-Recurring-Instances oMSyntax: 2 searchFlags: 0 lDAPDisplayName: msExchMaximumRecurringInstances name: ms-Exch-Maximum-Recurring-Instances schemaIDGUID: a8b8d132-b093-11d2-aa06-00c04f8eedd8 isMemberOfPartialAttributeSet: FALSE objectCategory: CN=Attribute-Schema,${SCHEMADN} # # ms-Exch-Maximum-Recurring-Instances-Months # The maximum window of instances (months) generated by the store # expansion agent. # dn: CN=ms-Exch-Maximum-Recurring-Instances-Months,${SCHEMADN} objectClass: top objectClass: attributeSchema cn: ms-Exch-Maximum-Recurring-Instances-Months distinguishedName: CN=ms-Exch-Maximum-Recurring-Instances-Months,${SCHEMADN} attributeID: 1.2.840.113556.1.4.7000.102.10015 attributeSyntax: 2.5.5.9 isSingleValued: TRUE showInAdvancedViewOnly: TRUE adminDisplayName: ms-Exch-Maximum-Recurring-Instances-Months adminDescription: ms-Exch-Maximum-Recurring-Instances-Months oMSyntax: 2 searchFlags: 0 lDAPDisplayName: msExchMaximumRecurringInstancesMonths name: ms-Exch-Maximum-Recurring-Instances-Months schemaIDGUID: a8da321e-b093-11d2-aa06-00c04f8eedd8 isMemberOfPartialAttributeSet: FALSE objectCategory: CN=Attribute-Schema,${SCHEMADN} # # ms-Exch-Max-Cached-Views # The maximum number of restricted views cached for any given folder # in the MDB. # dn: CN=ms-Exch-Max-Cached-Views,${SCHEMADN} objectClass: top objectClass: attributeSchema cn: ms-Exch-Max-Cached-Views distinguishedName: CN=ms-Exch-Max-Cached-Views,${SCHEMADN} attributeID: 1.2.840.113556.1.4.7000.102.11083 attributeSyntax: 2.5.5.9 isSingleValued: TRUE showInAdvancedViewOnly: TRUE adminDisplayName: ms-Exch-Max-Cached-Views adminDescription: ms-Exch-Max-Cached-Views oMSyntax: 2 searchFlags: 0 lDAPDisplayName: msExchMaxCachedViews name: ms-Exch-Max-Cached-Views schemaIDGUID: 1529cf69-2fdb-11d3-aa6d-00c04f8eedd8 isMemberOfPartialAttributeSet: FALSE objectCategory: CN=Attribute-Schema,${SCHEMADN} # # ms-Exch-Max-Connections # Defines the maximum allowed connections. # dn: CN=ms-Exch-Max-Connections,${SCHEMADN} objectClass: top objectClass: attributeSchema cn: ms-Exch-Max-Connections distinguishedName: CN=ms-Exch-Max-Connections,${SCHEMADN} attributeID: 1.2.840.113556.1.4.7000.102.9013 attributeSyntax: 2.5.5.9 isSingleValued: TRUE showInAdvancedViewOnly: TRUE adminDisplayName: ms-Exch-Max-Connections adminDescription: ms-Exch-Max-Connections oMSyntax: 2 searchFlags: 0 lDAPDisplayName: msExchMaxConnections name: ms-Exch-Max-Connections schemaIDGUID: a7c33efc-b093-11d2-aa06-00c04f8eedd8 isMemberOfPartialAttributeSet: FALSE objectCategory: CN=Attribute-Schema,${SCHEMADN} # # ms-Exch-Max-Extension-Time # The maximum minutes a video conference can be extended. # dn: CN=ms-Exch-Max-Extension-Time,${SCHEMADN} objectClass: top objectClass: attributeSchema cn: ms-Exch-Max-Extension-Time distinguishedName: CN=ms-Exch-Max-Extension-Time,${SCHEMADN} attributeID: 1.2.840.113556.1.4.7000.102.9028 attributeSyntax: 2.5.5.9 isSingleValued: TRUE showInAdvancedViewOnly: TRUE adminDisplayName: ms-Exch-Max-Extension-Time adminDescription: ms-Exch-Max-Extension-Time oMSyntax: 2 searchFlags: 0 lDAPDisplayName: msExchMaxExtensionTime name: ms-Exch-Max-Extension-Time schemaIDGUID: 99f58668-12e8-11d3-aa58-00c04f8eedd8 isMemberOfPartialAttributeSet: FALSE objectCategory: CN=Attribute-Schema,${SCHEMADN} # # ms-Exch-Max-Incoming-Connections # The maximum number of incoming connections allowed for this # resource. # dn: CN=ms-Exch-Max-Incoming-Connections,${SCHEMADN} objectClass: top objectClass: attributeSchema cn: ms-Exch-Max-Incoming-Connections distinguishedName: CN=ms-Exch-Max-Incoming-Connections,${SCHEMADN} attributeID: 1.2.840.113556.1.4.7000.102.2004 attributeSyntax: 2.5.5.9 isSingleValued: TRUE showInAdvancedViewOnly: TRUE adminDisplayName: ms-Exch-Max-Incoming-Connections adminDescription: ms-Exch-Max-Incoming-Connections oMSyntax: 2 searchFlags: 0 lDAPDisplayName: msExchMaxIncomingConnections name: ms-Exch-Max-Incoming-Connections schemaIDGUID: a808632e-b093-11d2-aa06-00c04f8eedd8 isMemberOfPartialAttributeSet: FALSE objectCategory: CN=Attribute-Schema,${SCHEMADN} # # ms-Exch-Max-Participants # The maximum number of participants allowed in a video conference. # dn: CN=ms-Exch-Max-Participants,${SCHEMADN} objectClass: top objectClass: attributeSchema cn: ms-Exch-Max-Participants distinguishedName: CN=ms-Exch-Max-Participants,${SCHEMADN} attributeID: 1.2.840.113556.1.4.7000.102.9027 attributeSyntax: 2.5.5.9 isSingleValued: TRUE showInAdvancedViewOnly: TRUE adminDisplayName: ms-Exch-Max-Participants adminDescription: ms-Exch-Max-Participants oMSyntax: 2 searchFlags: 0 lDAPDisplayName: msExchMaxParticipants name: ms-Exch-Max-Participants schemaIDGUID: 99f58663-12e8-11d3-aa58-00c04f8eedd8 isMemberOfPartialAttributeSet: FALSE objectCategory: CN=Attribute-Schema,${SCHEMADN} # # ms-Exch-Max-Pool-Threads # dn: CN=ms-Exch-Max-Pool-Threads,${SCHEMADN} objectClass: top objectClass: attributeSchema cn: ms-Exch-Max-Pool-Threads distinguishedName: CN=ms-Exch-Max-Pool-Threads,${SCHEMADN} attributeID: 1.2.840.113556.1.4.7000.102.11041 attributeSyntax: 2.5.5.9 isSingleValued: TRUE showInAdvancedViewOnly: TRUE adminDisplayName: ms-Exch-Max-Pool-Threads adminDescription: ms-Exch-Max-Pool-Threads oMSyntax: 2 searchFlags: 0 lDAPDisplayName: msExchMaxPoolThreads name: ms-Exch-Max-Pool-Threads schemaIDGUID: a82e88ce-b093-11d2-aa06-00c04f8eedd8 isMemberOfPartialAttributeSet: FALSE objectCategory: CN=Attribute-Schema,${SCHEMADN} # # ms-Exch-Max-Restore-Storage-Groups # dn: CN=ms-Exch-Max-Restore-Storage-Groups,${SCHEMADN} objectClass: top objectClass: attributeSchema cn: ms-Exch-Max-Restore-Storage-Groups distinguishedName: CN=ms-Exch-Max-Restore-Storage-Groups,${SCHEMADN} attributeID: 1.2.840.113556.1.4.7000.102.11095 attributeSyntax: 2.5.5.9 isSingleValued: TRUE showInAdvancedViewOnly: TRUE adminDisplayName: ms-Exch-Max-Restore-Storage-Groups adminDescription: ms-Exch-Max-Restore-Storage-Groups oMSyntax: 2 searchFlags: 0 lDAPDisplayName: msExchMaxRestoreStorageGroups name: ms-Exch-Max-Restore-Storage-Groups schemaIDGUID: 3ef2a80e-ea82-421b-8a62-a12543c34141 isMemberOfPartialAttributeSet: FALSE objectCategory: CN=Attribute-Schema,${SCHEMADN} # # ms-Exch-Max-Storage-Groups # The maximum number of Jet instances allowed on this computer. # dn: CN=ms-Exch-Max-Storage-Groups,${SCHEMADN} objectClass: top objectClass: attributeSchema cn: ms-Exch-Max-Storage-Groups distinguishedName: CN=ms-Exch-Max-Storage-Groups,${SCHEMADN} attributeID: 1.2.840.113556.1.4.7000.102.11027 attributeSyntax: 2.5.5.9 isSingleValued: TRUE showInAdvancedViewOnly: TRUE adminDisplayName: ms-Exch-Max-Storage-Groups adminDescription: ms-Exch-Max-Storage-Groups oMSyntax: 2 searchFlags: 0 lDAPDisplayName: msExchMaxStorageGroups name: ms-Exch-Max-Storage-Groups schemaIDGUID: a84fe9ba-b093-11d2-aa06-00c04f8eedd8 isMemberOfPartialAttributeSet: FALSE objectCategory: CN=Attribute-Schema,${SCHEMADN} # # ms-Exch-Max-Stores-Per-Group # The maximum number of stores allowed per Jet instance on this # computer. # dn: CN=ms-Exch-Max-Stores-Per-Group,${SCHEMADN} objectClass: top objectClass: attributeSchema cn: ms-Exch-Max-Stores-Per-Group distinguishedName: CN=ms-Exch-Max-Stores-Per-Group,${SCHEMADN} attributeID: 1.2.840.113556.1.4.7000.102.11028 attributeSyntax: 2.5.5.9 isSingleValued: TRUE showInAdvancedViewOnly: TRUE adminDisplayName: ms-Exch-Max-Stores-Per-Group adminDescription: ms-Exch-Max-Stores-Per-Group oMSyntax: 2 searchFlags: 0 lDAPDisplayName: msExchMaxStoresPerGroup name: ms-Exch-Max-Stores-Per-Group schemaIDGUID: a8714aa6-b093-11d2-aa06-00c04f8eedd8 isMemberOfPartialAttributeSet: FALSE objectCategory: CN=Attribute-Schema,${SCHEMADN} # # ms-Exch-Max-Threads # The maximum remote procedure call (RPC) threads for the server. # dn: CN=ms-Exch-Max-Threads,${SCHEMADN} objectClass: top objectClass: attributeSchema cn: ms-Exch-Max-Threads distinguishedName: CN=ms-Exch-Max-Threads,${SCHEMADN} attributeID: 1.2.840.113556.1.4.7000.102.11042 attributeSyntax: 2.5.5.9 isSingleValued: TRUE showInAdvancedViewOnly: TRUE adminDisplayName: ms-Exch-Max-Threads adminDescription: ms-Exch-Max-Threads oMSyntax: 2 searchFlags: 0 lDAPDisplayName: msExchMaxThreads name: ms-Exch-Max-Threads schemaIDGUID: a8950dec-b093-11d2-aa06-00c04f8eedd8 isMemberOfPartialAttributeSet: FALSE objectCategory: CN=Attribute-Schema,${SCHEMADN} # # ms-Exch-MCU-Hosts-Sites # A forward link to Microsoft® Windows® sites supported by the # specified multipoint control unit (MCU). # dn: CN=ms-Exch-MCU-Hosts-Sites,${SCHEMADN} objectClass: top objectClass: attributeSchema cn: ms-Exch-MCU-Hosts-Sites distinguishedName: CN=ms-Exch-MCU-Hosts-Sites,${SCHEMADN} attributeID: 1.2.840.113556.1.4.7000.102.9031 attributeSyntax: 2.5.5.1 isSingleValued: FALSE linkID: 1038 showInAdvancedViewOnly: TRUE adminDisplayName: ms-Exch-MCU-Hosts-Sites oMObjectClass:: KwwCh3McAIVK adminDescription: ms-Exch-MCU-Hosts-Sites oMSyntax: 127 searchFlags: 0 lDAPDisplayName: msExchMCUHostsSites name: ms-Exch-MCU-Hosts-Sites schemaIDGUID: bd062bc7-ce32-4690-8b8e-5c63b816b516 isMemberOfPartialAttributeSet: FALSE objectCategory: CN=Attribute-Schema,${SCHEMADN} # # ms-Exch-MCU-Hosts-Sites-BL # A backlink to Microsoft® Windows® sites supported by the specified multipoint control unit (MCU). # dn: CN=ms-Exch-MCU-Hosts-Sites-BL,${SCHEMADN} objectClass: top objectClass: attributeSchema cn: ms-Exch-MCU-Hosts-Sites-BL distinguishedName: CN=ms-Exch-MCU-Hosts-Sites-BL,${SCHEMADN} attributeID: 1.2.840.113556.1.4.7000.102.9032 attributeSyntax: 2.5.5.1 isSingleValued: FALSE linkID: 1039 showInAdvancedViewOnly: TRUE adminDisplayName: ms-Exch-MCU-Hosts-Sites-BL oMObjectClass:: KwwCh3McAIVK adminDescription: ms-Exch-MCU-Hosts-Sites-BL oMSyntax: 127 searchFlags: 0 lDAPDisplayName: msExchMCUHostsSitesBL name: ms-Exch-MCU-Hosts-Sites-BL schemaIDGUID: b0ab8d77-2486-467d-a331-3e3524438a57 systemFlags: 1 isMemberOfPartialAttributeSet: FALSE objectCategory: CN=Attribute-Schema,${SCHEMADN} # # ms-Exch-MDB-Backoff-Interval # dn: CN=ms-Exch-MDB-Backoff-Interval,${SCHEMADN} objectClass: top objectClass: attributeSchema cn: ms-Exch-MDB-Backoff-Interval distinguishedName: CN=ms-Exch-MDB-Backoff-Interval,${SCHEMADN} attributeID: 1.2.840.113556.1.2.72 attributeSyntax: 2.5.5.9 isSingleValued: TRUE mAPIID: 32975 showInAdvancedViewOnly: TRUE adminDisplayName: ms-Exch-MDB-Backoff-Interval adminDescription: ms-Exch-MDB-Backoff-Interval oMSyntax: 2 searchFlags: 0 lDAPDisplayName: mDBBackoffInterval name: ms-Exch-MDB-Backoff-Interval schemaIDGUID: a8df741f-c5ea-11d1-bbcb-0080c76670c0 isMemberOfPartialAttributeSet: FALSE objectCategory: CN=Attribute-Schema,${SCHEMADN} # # ms-Exch-MDB-Msg-Time-Out-Period # dn: CN=ms-Exch-MDB-Msg-Time-Out-Period,${SCHEMADN} objectClass: top objectClass: attributeSchema cn: ms-Exch-MDB-Msg-Time-Out-Period distinguishedName: CN=ms-Exch-MDB-Msg-Time-Out-Period,${SCHEMADN} attributeID: 1.2.840.113556.1.2.64 attributeSyntax: 2.5.5.9 isSingleValued: TRUE mAPIID: 32976 showInAdvancedViewOnly: TRUE adminDisplayName: ms-Exch-MDB-Msg-Time-Out-Period adminDescription: ms-Exch-MDB-Msg-Time-Out-Period oMSyntax: 2 searchFlags: 0 lDAPDisplayName: mDBMsgTimeOutPeriod name: ms-Exch-MDB-Msg-Time-Out-Period schemaIDGUID: a8df7420-c5ea-11d1-bbcb-0080c76670c0 isMemberOfPartialAttributeSet: FALSE objectCategory: CN=Attribute-Schema,${SCHEMADN} # # ms-Exch-MDB-Over-Hard-Quota-Limit # The default size limit after which messages can no longer be sent or # received. # dn: CN=ms-Exch-MDB-Over-Hard-Quota-Limit,${SCHEMADN} objectClass: top objectClass: attributeSchema cn: ms-Exch-MDB-Over-Hard-Quota-Limit distinguishedName: CN=ms-Exch-MDB-Over-Hard-Quota-Limit,${SCHEMADN} attributeID: 1.2.840.113556.1.4.7000.102.11037 attributeSyntax: 2.5.5.9 isSingleValued: TRUE showInAdvancedViewOnly: TRUE adminDisplayName: ms-Exch-MDB-Over-Hard-Quota-Limit adminDescription: ms-Exch-MDB-Over-Hard-Quota-Limit oMSyntax: 2 searchFlags: 16 lDAPDisplayName: mDBOverHardQuotaLimit name: ms-Exch-MDB-Over-Hard-Quota-Limit schemaIDGUID: 8fcf1ec4-b093-11d2-aa06-00c04f8eedd8 attributeSecurityGUID: e48d0154-bcf8-11d1-8702-00c04fb96050 isMemberOfPartialAttributeSet: TRUE objectCategory: CN=Attribute-Schema,${SCHEMADN} # # ms-Exch-MDB-Over-Quota-Limit # dn: CN=ms-Exch-MDB-Over-Quota-Limit,${SCHEMADN} objectClass: top objectClass: attributeSchema cn: ms-Exch-MDB-Over-Quota-Limit distinguishedName: CN=ms-Exch-MDB-Over-Quota-Limit,${SCHEMADN} attributeID: 1.2.840.113556.1.2.272 attributeSyntax: 2.5.5.9 isSingleValued: TRUE mAPIID: 32977 showInAdvancedViewOnly: TRUE adminDisplayName: ms-Exch-MDB-Over-Quota-Limit adminDescription: ms-Exch-MDB-Over-Quota-Limit oMSyntax: 2 searchFlags: 16 lDAPDisplayName: mDBOverQuotaLimit name: ms-Exch-MDB-Over-Quota-Limit schemaIDGUID: f0f8ff91-1191-11d0-a060-00aa006c33ed attributeSecurityGUID: e48d0154-bcf8-11d1-8702-00c04fb96050 isMemberOfPartialAttributeSet: TRUE objectCategory: CN=Attribute-Schema,${SCHEMADN} # # ms-Exch-MDB-Storage-Quota # dn: CN=ms-Exch-MDB-Storage-Quota,${SCHEMADN} objectClass: top objectClass: attributeSchema cn: ms-Exch-MDB-Storage-Quota distinguishedName: CN=ms-Exch-MDB-Storage-Quota,${SCHEMADN} attributeID: 1.2.840.113556.1.2.266 attributeSyntax: 2.5.5.9 isSingleValued: TRUE mAPIID: 32978 showInAdvancedViewOnly: TRUE adminDisplayName: ms-Exch-MDB-Storage-Quota adminDescription: ms-Exch-MDB-Storage-Quota oMSyntax: 2 searchFlags: 16 lDAPDisplayName: mDBStorageQuota name: ms-Exch-MDB-Storage-Quota schemaIDGUID: f0f8ff92-1191-11d0-a060-00aa006c33ed attributeSecurityGUID: e48d0154-bcf8-11d1-8702-00c04fb96050 isMemberOfPartialAttributeSet: TRUE objectCategory: CN=Attribute-Schema,${SCHEMADN} # # ms-Exch-MDB-Unread-Limit # dn: CN=ms-Exch-MDB-Unread-Limit,${SCHEMADN} objectClass: top objectClass: attributeSchema cn: ms-Exch-MDB-Unread-Limit distinguishedName: CN=ms-Exch-MDB-Unread-Limit,${SCHEMADN} attributeID: 1.2.840.113556.1.2.69 attributeSyntax: 2.5.5.9 isSingleValued: TRUE mAPIID: 32979 showInAdvancedViewOnly: TRUE adminDisplayName: ms-Exch-MDB-Unread-Limit adminDescription: ms-Exch-MDB-Unread-Limit oMSyntax: 2 searchFlags: 0 lDAPDisplayName: mDBUnreadLimit name: ms-Exch-MDB-Unread-Limit schemaIDGUID: a8df7421-c5ea-11d1-bbcb-0080c76670c0 isMemberOfPartialAttributeSet: FALSE objectCategory: CN=Attribute-Schema,${SCHEMADN} # # ms-Exch-MDB-Use-Defaults # dn: CN=ms-Exch-MDB-Use-Defaults,${SCHEMADN} objectClass: top objectClass: attributeSchema cn: ms-Exch-MDB-Use-Defaults distinguishedName: CN=ms-Exch-MDB-Use-Defaults,${SCHEMADN} attributeID: 1.2.840.113556.1.2.309 attributeSyntax: 2.5.5.8 isSingleValued: TRUE mAPIID: 32980 showInAdvancedViewOnly: TRUE adminDisplayName: ms-Exch-MDB-Use-Defaults adminDescription: ms-Exch-MDB-Use-Defaults oMSyntax: 1 searchFlags: 16 lDAPDisplayName: mDBUseDefaults name: ms-Exch-MDB-Use-Defaults schemaIDGUID: f0f8ff93-1191-11d0-a060-00aa006c33ed attributeSecurityGUID: e48d0154-bcf8-11d1-8702-00c04fb96050 isMemberOfPartialAttributeSet: TRUE objectCategory: CN=Attribute-Schema,${SCHEMADN} # # ms-Exch-Member-Base-DN # Contains the base of the LDAP search that should be used to compute # this dynamic DL. # dn: CN=ms-Exch-Member-Base-DN,${SCHEMADN} objectClass: top objectClass: attributeSchema cn: ms-Exch-Member-Base-DN distinguishedName: CN=ms-Exch-Member-Base-DN,${SCHEMADN} attributeID: 1.2.840.113556.1.4.7000.102.12524 attributeSyntax: 2.5.5.4 isSingleValued: TRUE showInAdvancedViewOnly: TRUE adminDisplayName: ms-Exch-Member-Base-DN adminDescription: ms-Exch-Member-Base-DN oMSyntax: 20 searchFlags: 0 lDAPDisplayName: msExchMemberBaseDN name: ms-Exch-Member-Base-DN schemaIDGUID: a921b8aa-b093-11d2-aa06-00c04f8eedd8 isMemberOfPartialAttributeSet: TRUE objectCategory: CN=Attribute-Schema,${SCHEMADN} # # ms-Exch-Member-Filter # The LDAP search filter used to generate this dynamic DL. # dn: CN=ms-Exch-Member-Filter,${SCHEMADN} objectClass: top objectClass: attributeSchema cn: ms-Exch-Member-Filter distinguishedName: CN=ms-Exch-Member-Filter,${SCHEMADN} attributeID: 1.2.840.113556.1.4.7000.102.12522 attributeSyntax: 2.5.5.4 isSingleValued: TRUE showInAdvancedViewOnly: TRUE adminDisplayName: ms-Exch-Member-Filter adminDescription: ms-Exch-Member-Filter oMSyntax: 20 searchFlags: 0 lDAPDisplayName: msExchMemberFilter name: ms-Exch-Member-Filter schemaIDGUID: a9457bf0-b093-11d2-aa06-00c04f8eedd8 isMemberOfPartialAttributeSet: TRUE objectCategory: CN=Attribute-Schema,${SCHEMADN} # # ms-Exch-Message-Journal-Recipient # A pointer to the mailbox that should get a journal (copy) of all # messages sent on this mailbox store. # dn: CN=ms-Exch-Message-Journal-Recipient,${SCHEMADN} objectClass: top objectClass: attributeSchema cn: ms-Exch-Message-Journal-Recipient distinguishedName: CN=ms-Exch-Message-Journal-Recipient,${SCHEMADN} attributeID: 1.2.840.113556.1.4.7000.102.5055 attributeSyntax: 2.5.5.1 isSingleValued: TRUE showInAdvancedViewOnly: TRUE adminDisplayName: ms-Exch-Message-Journal-Recipient oMObjectClass:: KwwCh3McAIVK adminDescription: ms-Exch-Message-Journal-Recipient oMSyntax: 127 searchFlags: 0 lDAPDisplayName: msExchMessageJournalRecipient name: ms-Exch-Message-Journal-Recipient schemaIDGUID: a95fee9d-b634-41e9-8f8c-d3d9ac1d5941 isMemberOfPartialAttributeSet: FALSE objectCategory: CN=Attribute-Schema,${SCHEMADN} # # ms-Exch-Message-Size-Limit # dn: CN=ms-Exch-Message-Size-Limit,${SCHEMADN} objectClass: top objectClass: attributeSchema cn: ms-Exch-Message-Size-Limit distinguishedName: CN=ms-Exch-Message-Size-Limit,${SCHEMADN} attributeID: 1.2.840.113556.1.2.100 attributeSyntax: 2.5.5.9 isSingleValued: TRUE mAPIID: 32925 showInAdvancedViewOnly: TRUE adminDisplayName: ms-Exch-Message-Size-Limit adminDescription: ms-Exch-Message-Size-Limit oMSyntax: 2 searchFlags: 0 lDAPDisplayName: messageSizeLimit name: ms-Exch-Message-Size-Limit schemaIDGUID: 167757e2-47f3-11d1-a9c3-0000f80367c1 isMemberOfPartialAttributeSet: FALSE objectCategory: CN=Attribute-Schema,${SCHEMADN} # # ms-Exch-Message-Tracking-Enabled # dn: CN=ms-Exch-Message-Tracking-Enabled,${SCHEMADN} objectClass: top objectClass: attributeSchema cn: ms-Exch-Message-Tracking-Enabled distinguishedName: CN=ms-Exch-Message-Tracking-Enabled,${SCHEMADN} attributeID: 1.2.840.113556.1.2.453 attributeSyntax: 2.5.5.8 isSingleValued: TRUE mAPIID: 32981 showInAdvancedViewOnly: TRUE adminDisplayName: ms-Exch-Message-Tracking-Enabled adminDescription: ms-Exch-Message-Tracking-Enabled oMSyntax: 1 searchFlags: 0 lDAPDisplayName: messageTrackingEnabled name: ms-Exch-Message-Tracking-Enabled schemaIDGUID: a8df7422-c5ea-11d1-bbcb-0080c76670c0 isMemberOfPartialAttributeSet: FALSE objectCategory: CN=Attribute-Schema,${SCHEMADN} # # ms-Exch-Message-Track-Log-Filter # Defines the filter for the fields in the message tracking log. Each # bit controls a field. # dn: CN=ms-Exch-Message-Track-Log-Filter,${SCHEMADN} objectClass: top objectClass: attributeSchema cn: ms-Exch-Message-Track-Log-Filter distinguishedName: CN=ms-Exch-Message-Track-Log-Filter,${SCHEMADN} attributeID: 1.2.840.113556.1.4.7000.102.50001 attributeSyntax: 2.5.5.9 isSingleValued: TRUE showInAdvancedViewOnly: TRUE adminDisplayName: ms-Exch-Message-Track-Log-Filter adminDescription: ms-Exch-Message-Track-Log-Filter oMSyntax: 2 searchFlags: 0 lDAPDisplayName: msExchMessageTrackLogFilter name: ms-Exch-Message-Track-Log-Filter schemaIDGUID: a9647a82-b093-11d2-aa06-00c04f8eedd8 isMemberOfPartialAttributeSet: FALSE objectCategory: CN=Attribute-Schema,${SCHEMADN} # # ms-Exch-Mime-Types # dn: CN=ms-Exch-Mime-Types,${SCHEMADN} objectClass: top objectClass: attributeSchema cn: ms-Exch-Mime-Types distinguishedName: CN=ms-Exch-Mime-Types,${SCHEMADN} attributeID: 1.2.840.113556.1.4.7000.102.550 attributeSyntax: 2.5.5.10 isSingleValued: TRUE rangeLower: 1 rangeUpper: 10240 mAPIID: 35868 showInAdvancedViewOnly: TRUE adminDisplayName: ms-Exch-Mime-Types adminDescription: ms-Exch-Mime-Types oMSyntax: 4 searchFlags: 0 lDAPDisplayName: msExchMimeTypes name: ms-Exch-Mime-Types schemaIDGUID: 8addd6a2-b09e-11d2-aa06-00c04f8eedd8 isMemberOfPartialAttributeSet: FALSE objectCategory: CN=Attribute-Schema,${SCHEMADN} # # ms-Exch-Minimum-Threads # The minimum RPC threads for the server. # dn: CN=ms-Exch-Minimum-Threads,${SCHEMADN} objectClass: top objectClass: attributeSchema cn: ms-Exch-Minimum-Threads distinguishedName: CN=ms-Exch-Minimum-Threads,${SCHEMADN} attributeID: 1.2.840.113556.1.4.7000.102.11043 attributeSyntax: 2.5.5.9 isSingleValued: TRUE showInAdvancedViewOnly: TRUE adminDisplayName: ms-Exch-Minimum-Threads adminDescription: ms-Exch-Minimum-Threads oMSyntax: 2 searchFlags: 0 lDAPDisplayName: msExchMinimumThreads name: ms-Exch-Minimum-Threads schemaIDGUID: a9883dc8-b093-11d2-aa06-00c04f8eedd8 isMemberOfPartialAttributeSet: FALSE objectCategory: CN=Attribute-Schema,${SCHEMADN} # # ms-Exch-Min-Admin-Version # dn: CN=ms-Exch-Min-Admin-Version,${SCHEMADN} objectClass: top objectClass: attributeSchema cn: ms-Exch-Min-Admin-Version distinguishedName: CN=ms-Exch-Min-Admin-Version,${SCHEMADN} attributeID: 1.2.840.113556.1.4.7000.102.50093 attributeSyntax: 2.5.5.9 isSingleValued: TRUE showInAdvancedViewOnly: TRUE adminDisplayName: ms-Exch-Min-Admin-Version adminDescription: ms-Exch-Min-Admin-Version oMSyntax: 2 searchFlags: 0 lDAPDisplayName: msExchMinAdminVersion name: ms-Exch-Min-Admin-Version schemaIDGUID: 8fca497d-4ac7-4df4-b180-eec0bfef27df isMemberOfPartialAttributeSet: FALSE objectCategory: CN=Attribute-Schema,${SCHEMADN} # # ms-Exch-Mixed-Mode # dn: CN=ms-Exch-Mixed-Mode,${SCHEMADN} objectClass: top objectClass: attributeSchema cn: ms-Exch-Mixed-Mode distinguishedName: CN=ms-Exch-Mixed-Mode,${SCHEMADN} attributeID: 1.2.840.113556.1.4.7000.102.50022 attributeSyntax: 2.5.5.8 isSingleValued: TRUE showInAdvancedViewOnly: TRUE adminDisplayName: ms-Exch-Mixed-Mode adminDescription: ms-Exch-Mixed-Mode oMSyntax: 1 searchFlags: 0 lDAPDisplayName: msExchMixedMode name: ms-Exch-Mixed-Mode schemaIDGUID: 8ddb297c-b09e-11d2-aa06-00c04f8eedd8 isMemberOfPartialAttributeSet: FALSE objectCategory: CN=Attribute-Schema,${SCHEMADN} # # ms-Exch-Monitored-Configurations # dn: CN=ms-Exch-Monitored-Configurations,${SCHEMADN} objectClass: top objectClass: attributeSchema cn: ms-Exch-Monitored-Configurations distinguishedName: CN=ms-Exch-Monitored-Configurations,${SCHEMADN} attributeID: 1.2.840.113556.1.2.198 attributeSyntax: 2.5.5.1 isSingleValued: FALSE mAPIID: 32985 showInAdvancedViewOnly: TRUE adminDisplayName: ms-Exch-Monitored-Configurations oMObjectClass:: KwwCh3McAIVK adminDescription: ms-Exch-Monitored-Configurations oMSyntax: 127 searchFlags: 0 lDAPDisplayName: monitoredConfigurations name: ms-Exch-Monitored-Configurations schemaIDGUID: bf9679c9-0de6-11d0-a285-00aa003049e2 isMemberOfPartialAttributeSet: FALSE objectCategory: CN=Attribute-Schema,${SCHEMADN} # # ms-Exch-Monitored-Servers # dn: CN=ms-Exch-Monitored-Servers,${SCHEMADN} objectClass: top objectClass: attributeSchema cn: ms-Exch-Monitored-Servers distinguishedName: CN=ms-Exch-Monitored-Servers,${SCHEMADN} attributeID: 1.2.840.113556.1.2.179 attributeSyntax: 2.5.5.1 isSingleValued: FALSE mAPIID: 32986 showInAdvancedViewOnly: TRUE adminDisplayName: ms-Exch-Monitored-Servers oMObjectClass:: KwwCh3McAIVK adminDescription: ms-Exch-Monitored-Servers oMSyntax: 127 searchFlags: 0 lDAPDisplayName: monitoredServers name: ms-Exch-Monitored-Servers schemaIDGUID: a8df7426-c5ea-11d1-bbcb-0080c76670c0 isMemberOfPartialAttributeSet: FALSE objectCategory: CN=Attribute-Schema,${SCHEMADN} # # ms-Exch-Monitored-Services # dn: CN=ms-Exch-Monitored-Services,${SCHEMADN} objectClass: top objectClass: attributeSchema cn: ms-Exch-Monitored-Services distinguishedName: CN=ms-Exch-Monitored-Services,${SCHEMADN} attributeID: 1.2.840.113556.1.2.199 attributeSyntax: 2.5.5.12 isSingleValued: FALSE rangeLower: 1 rangeUpper: 256 mAPIID: 32987 showInAdvancedViewOnly: TRUE adminDisplayName: ms-Exch-Monitored-Services adminDescription: ms-Exch-Monitored-Services oMSyntax: 64 searchFlags: 0 lDAPDisplayName: monitoredServices name: ms-Exch-Monitored-Services schemaIDGUID: bf9679ca-0de6-11d0-a285-00aa003049e2 isMemberOfPartialAttributeSet: FALSE objectCategory: CN=Attribute-Schema,${SCHEMADN} # # ms-Exch-Monitoring-Alert-Delay # dn: CN=ms-Exch-Monitoring-Alert-Delay,${SCHEMADN} objectClass: top objectClass: attributeSchema cn: ms-Exch-Monitoring-Alert-Delay distinguishedName: CN=ms-Exch-Monitoring-Alert-Delay,${SCHEMADN} attributeID: 1.2.840.113556.1.2.158 attributeSyntax: 2.5.5.9 isSingleValued: TRUE mAPIID: 32988 showInAdvancedViewOnly: TRUE adminDisplayName: ms-Exch-Monitoring-Alert-Delay adminDescription: ms-Exch-Monitoring-Alert-Delay oMSyntax: 2 searchFlags: 0 lDAPDisplayName: monitoringAlertDelay name: ms-Exch-Monitoring-Alert-Delay schemaIDGUID: a8df7427-c5ea-11d1-bbcb-0080c76670c0 isMemberOfPartialAttributeSet: FALSE objectCategory: CN=Attribute-Schema,${SCHEMADN} # # ms-Exch-Monitoring-Alert-Units # dn: CN=ms-Exch-Monitoring-Alert-Units,${SCHEMADN} objectClass: top objectClass: attributeSchema cn: ms-Exch-Monitoring-Alert-Units distinguishedName: CN=ms-Exch-Monitoring-Alert-Units,${SCHEMADN} attributeID: 1.2.840.113556.1.2.57 attributeSyntax: 2.5.5.9 isSingleValued: TRUE rangeLower: 0 rangeUpper: 2 mAPIID: 32989 showInAdvancedViewOnly: TRUE adminDisplayName: ms-Exch-Monitoring-Alert-Units adminDescription: ms-Exch-Monitoring-Alert-Units oMSyntax: 10 searchFlags: 0 lDAPDisplayName: monitoringAlertUnits name: ms-Exch-Monitoring-Alert-Units schemaIDGUID: a8df7428-c5ea-11d1-bbcb-0080c76670c0 isMemberOfPartialAttributeSet: FALSE objectCategory: CN=Attribute-Schema,${SCHEMADN} # # ms-Exch-Monitoring-Availability-Style # dn: CN=ms-Exch-Monitoring-Availability-Style,${SCHEMADN} objectClass: top objectClass: attributeSchema cn: ms-Exch-Monitoring-Availability-Style distinguishedName: CN=ms-Exch-Monitoring-Availability-Style,${SCHEMADN} attributeID: 1.2.840.113556.1.2.450 attributeSyntax: 2.5.5.9 isSingleValued: TRUE rangeLower: 0 rangeUpper: 3 mAPIID: 32990 showInAdvancedViewOnly: TRUE adminDisplayName: ms-Exch-Monitoring-Availability-Style adminDescription: ms-Exch-Monitoring-Availability-Style oMSyntax: 2 searchFlags: 0 lDAPDisplayName: monitoringAvailabilityStyle name: ms-Exch-Monitoring-Availability-Style schemaIDGUID: bf9679cb-0de6-11d0-a285-00aa003049e2 isMemberOfPartialAttributeSet: FALSE objectCategory: CN=Attribute-Schema,${SCHEMADN} # # ms-Exch-Monitoring-Availability-Window # dn: CN=ms-Exch-Monitoring-Availability-Window,${SCHEMADN} objectClass: top objectClass: attributeSchema cn: ms-Exch-Monitoring-Availability-Window distinguishedName: CN=ms-Exch-Monitoring-Availability-Window,${SCHEMADN} attributeID: 1.2.840.113556.1.2.200 attributeSyntax: 2.5.5.10 isSingleValued: TRUE rangeLower: 1 rangeUpper: 84 mAPIID: 32991 showInAdvancedViewOnly: TRUE adminDisplayName: ms-Exch-Monitoring-Availability-Window adminDescription: ms-Exch-Monitoring-Availability-Window oMSyntax: 4 searchFlags: 0 lDAPDisplayName: monitoringAvailabilityWindow name: ms-Exch-Monitoring-Availability-Window schemaIDGUID: bf9679cc-0de6-11d0-a285-00aa003049e2 isMemberOfPartialAttributeSet: FALSE objectCategory: CN=Attribute-Schema,${SCHEMADN} # # ms-Exch-Monitoring-Cached-Via-Mail # dn: CN=ms-Exch-Monitoring-Cached-Via-Mail,${SCHEMADN} objectClass: top objectClass: attributeSchema cn: ms-Exch-Monitoring-Cached-Via-Mail distinguishedName: CN=ms-Exch-Monitoring-Cached-Via-Mail,${SCHEMADN} attributeID: 1.2.840.113556.1.2.196 attributeSyntax: 2.5.5.1 isSingleValued: FALSE mAPIID: 32992 showInAdvancedViewOnly: TRUE adminDisplayName: ms-Exch-Monitoring-Cached-Via-Mail oMObjectClass:: KwwCh3McAIVK adminDescription: ms-Exch-Monitoring-Cached-Via-Mail oMSyntax: 127 searchFlags: 0 lDAPDisplayName: monitoringCachedViaMail name: ms-Exch-Monitoring-Cached-Via-Mail schemaIDGUID: bf9679cd-0de6-11d0-a285-00aa003049e2 isMemberOfPartialAttributeSet: FALSE objectCategory: CN=Attribute-Schema,${SCHEMADN} # # ms-Exch-Monitoring-Cached-Via-RPC # dn: CN=ms-Exch-Monitoring-Cached-Via-RPC,${SCHEMADN} objectClass: top objectClass: attributeSchema cn: ms-Exch-Monitoring-Cached-Via-RPC distinguishedName: CN=ms-Exch-Monitoring-Cached-Via-RPC,${SCHEMADN} attributeID: 1.2.840.113556.1.2.197 attributeSyntax: 2.5.5.1 isSingleValued: FALSE mAPIID: 32993 showInAdvancedViewOnly: TRUE adminDisplayName: ms-Exch-Monitoring-Cached-Via-RPC oMObjectClass:: KwwCh3McAIVK adminDescription: ms-Exch-Monitoring-Cached-Via-RPC oMSyntax: 127 searchFlags: 0 lDAPDisplayName: monitoringCachedViaRPC name: ms-Exch-Monitoring-Cached-Via-RPC schemaIDGUID: bf9679ce-0de6-11d0-a285-00aa003049e2 isMemberOfPartialAttributeSet: FALSE objectCategory: CN=Attribute-Schema,${SCHEMADN} # # ms-Exch-Monitoring-Disk-Space # dn: CN=ms-Exch-Monitoring-Disk-Space,${SCHEMADN} objectClass: top objectClass: attributeSchema cn: ms-Exch-Monitoring-Disk-Space distinguishedName: CN=ms-Exch-Monitoring-Disk-Space,${SCHEMADN} attributeID: 1.2.840.113556.1.4.7000.102.50046 attributeSyntax: 2.5.5.12 isSingleValued: FALSE showInAdvancedViewOnly: TRUE adminDisplayName: ms-Exch-Monitoring-Disk-Space adminDescription: ms-Exch-Monitoring-Disk-Space oMSyntax: 64 searchFlags: 0 lDAPDisplayName: msExchMonitoringDiskSpace name: ms-Exch-Monitoring-Disk-Space schemaIDGUID: 0210cc37-34cf-11d3-aa6e-00c04f8eedd8 isMemberOfPartialAttributeSet: FALSE objectCategory: CN=Attribute-Schema,${SCHEMADN} # # ms-Exch-Monitoring-Escalation-Procedure # dn: CN=ms-Exch-Monitoring-Escalation-Procedure,${SCHEMADN} objectClass: top objectClass: attributeSchema cn: ms-Exch-Monitoring-Escalation-Procedure distinguishedName: CN=ms-Exch-Monitoring-Escalation-Procedure,${SCHEMADN} attributeID: 1.2.840.113556.1.2.188 attributeSyntax: 2.5.5.10 isSingleValued: FALSE rangeLower: 1 rangeUpper: 1064 mAPIID: 32994 showInAdvancedViewOnly: TRUE adminDisplayName: ms-Exch-Monitoring-Escalation-Procedure adminDescription: ms-Exch-Monitoring-Escalation-Procedure oMSyntax: 4 searchFlags: 0 lDAPDisplayName: monitoringEscalationProcedure name: ms-Exch-Monitoring-Escalation-Procedure schemaIDGUID: a8df7429-c5ea-11d1-bbcb-0080c76670c0 isMemberOfPartialAttributeSet: FALSE objectCategory: CN=Attribute-Schema,${SCHEMADN} # # ms-Exch-Monitoring-Hotsite-Poll-Interval # dn: CN=ms-Exch-Monitoring-Hotsite-Poll-Interval,${SCHEMADN} objectClass: top objectClass: attributeSchema cn: ms-Exch-Monitoring-Hotsite-Poll-Interval distinguishedName: CN=ms-Exch-Monitoring-Hotsite-Poll-Interval,${SCHEMADN} attributeID: 1.2.840.113556.1.2.186 attributeSyntax: 2.5.5.9 isSingleValued: TRUE mAPIID: 32995 showInAdvancedViewOnly: TRUE adminDisplayName: ms-Exch-Monitoring-Hotsite-Poll-Interval adminDescription: ms-Exch-Monitoring-Hotsite-Poll-Interval oMSyntax: 2 searchFlags: 0 lDAPDisplayName: monitoringHotsitePollInterval name: ms-Exch-Monitoring-Hotsite-Poll-Interval schemaIDGUID: a8df742a-c5ea-11d1-bbcb-0080c76670c0 isMemberOfPartialAttributeSet: FALSE objectCategory: CN=Attribute-Schema,${SCHEMADN} # # ms-Exch-Monitoring-Hotsite-Poll-Units # dn: CN=ms-Exch-Monitoring-Hotsite-Poll-Units,${SCHEMADN} objectClass: top objectClass: attributeSchema cn: ms-Exch-Monitoring-Hotsite-Poll-Units distinguishedName: CN=ms-Exch-Monitoring-Hotsite-Poll-Units,${SCHEMADN} attributeID: 1.2.840.113556.1.2.87 attributeSyntax: 2.5.5.9 isSingleValued: TRUE rangeLower: 0 rangeUpper: 2 mAPIID: 32996 showInAdvancedViewOnly: TRUE adminDisplayName: ms-Exch-Monitoring-Hotsite-Poll-Units adminDescription: ms-Exch-Monitoring-Hotsite-Poll-Units oMSyntax: 10 searchFlags: 0 lDAPDisplayName: monitoringHotsitePollUnits name: ms-Exch-Monitoring-Hotsite-Poll-Units schemaIDGUID: a8df742b-c5ea-11d1-bbcb-0080c76670c0 isMemberOfPartialAttributeSet: FALSE objectCategory: CN=Attribute-Schema,${SCHEMADN} # # ms-Exch-Monitoring-Mail-Update-Interval # dn: CN=ms-Exch-Monitoring-Mail-Update-Interval,${SCHEMADN} objectClass: top objectClass: attributeSchema cn: ms-Exch-Monitoring-Mail-Update-Interval distinguishedName: CN=ms-Exch-Monitoring-Mail-Update-Interval,${SCHEMADN} attributeID: 1.2.840.113556.1.2.195 attributeSyntax: 2.5.5.9 isSingleValued: TRUE mAPIID: 32997 showInAdvancedViewOnly: TRUE adminDisplayName: ms-Exch-Monitoring-Mail-Update-Interval adminDescription: ms-Exch-Monitoring-Mail-Update-Interval oMSyntax: 2 searchFlags: 0 lDAPDisplayName: monitoringMailUpdateInterval name: ms-Exch-Monitoring-Mail-Update-Interval schemaIDGUID: bf9679cf-0de6-11d0-a285-00aa003049e2 isMemberOfPartialAttributeSet: FALSE objectCategory: CN=Attribute-Schema,${SCHEMADN} # # ms-Exch-Monitoring-Mail-Update-Units # dn: CN=ms-Exch-Monitoring-Mail-Update-Units,${SCHEMADN} objectClass: top objectClass: attributeSchema cn: ms-Exch-Monitoring-Mail-Update-Units distinguishedName: CN=ms-Exch-Monitoring-Mail-Update-Units,${SCHEMADN} attributeID: 1.2.840.113556.1.2.93 attributeSyntax: 2.5.5.9 isSingleValued: TRUE rangeLower: 0 rangeUpper: 2 mAPIID: 32998 showInAdvancedViewOnly: TRUE adminDisplayName: ms-Exch-Monitoring-Mail-Update-Units adminDescription: ms-Exch-Monitoring-Mail-Update-Units oMSyntax: 10 searchFlags: 0 lDAPDisplayName: monitoringMailUpdateUnits name: ms-Exch-Monitoring-Mail-Update-Units schemaIDGUID: bf9679d0-0de6-11d0-a285-00aa003049e2 isMemberOfPartialAttributeSet: FALSE objectCategory: CN=Attribute-Schema,${SCHEMADN} # # ms-Exch-Monitoring-Mode # dn: CN=ms-Exch-Monitoring-Mode,${SCHEMADN} objectClass: top objectClass: attributeSchema cn: ms-Exch-Monitoring-Mode distinguishedName: CN=ms-Exch-Monitoring-Mode,${SCHEMADN} attributeID: 1.2.840.113556.1.4.7000.102.50060 attributeSyntax: 2.5.5.9 isSingleValued: TRUE showInAdvancedViewOnly: TRUE adminDisplayName: ms-Exch-Monitoring-Mode adminDescription: ms-Exch-Monitoring-Mode oMSyntax: 2 searchFlags: 0 lDAPDisplayName: msExchMonitoringMode name: ms-Exch-Monitoring-Mode schemaIDGUID: e520be0a-d2ea-449b-9177-caaadec1a4c6 isMemberOfPartialAttributeSet: FALSE objectCategory: CN=Attribute-Schema,${SCHEMADN} # # ms-Exch-Monitoring-Monitored-Services # dn: CN=ms-Exch-Monitoring-Monitored-Services,${SCHEMADN} objectClass: top objectClass: attributeSchema cn: ms-Exch-Monitoring-Monitored-Services distinguishedName: CN=ms-Exch-Monitoring-Monitored-Services,${SCHEMADN} attributeID: 1.2.840.113556.1.4.7000.102.50045 attributeSyntax: 2.5.5.12 isSingleValued: FALSE showInAdvancedViewOnly: TRUE adminDisplayName: ms-Exch-Monitoring-Monitored-Services adminDescription: ms-Exch-Monitoring-Monitored-Services oMSyntax: 64 searchFlags: 0 lDAPDisplayName: msExchMonitoringMonitoredServices name: ms-Exch-Monitoring-Monitored-Services schemaIDGUID: 0210cc30-34cf-11d3-aa6e-00c04f8eedd8 isMemberOfPartialAttributeSet: FALSE objectCategory: CN=Attribute-Schema,${SCHEMADN} # # ms-Exch-Monitoring-Normal-Poll-Interval # dn: CN=ms-Exch-Monitoring-Normal-Poll-Interval,${SCHEMADN} objectClass: top objectClass: attributeSchema cn: ms-Exch-Monitoring-Normal-Poll-Interval distinguishedName: CN=ms-Exch-Monitoring-Normal-Poll-Interval,${SCHEMADN} attributeID: 1.2.840.113556.1.2.187 attributeSyntax: 2.5.5.9 isSingleValued: TRUE mAPIID: 32999 showInAdvancedViewOnly: TRUE adminDisplayName: ms-Exch-Monitoring-Normal-Poll-Interval adminDescription: ms-Exch-Monitoring-Normal-Poll-Interval oMSyntax: 2 searchFlags: 0 lDAPDisplayName: monitoringNormalPollInterval name: ms-Exch-Monitoring-Normal-Poll-Interval schemaIDGUID: a8df742c-c5ea-11d1-bbcb-0080c76670c0 isMemberOfPartialAttributeSet: FALSE objectCategory: CN=Attribute-Schema,${SCHEMADN} # # ms-Exch-Monitoring-Normal-Poll-Units # dn: CN=ms-Exch-Monitoring-Normal-Poll-Units,${SCHEMADN} objectClass: top objectClass: attributeSchema cn: ms-Exch-Monitoring-Normal-Poll-Units distinguishedName: CN=ms-Exch-Monitoring-Normal-Poll-Units,${SCHEMADN} attributeID: 1.2.840.113556.1.2.88 attributeSyntax: 2.5.5.9 isSingleValued: TRUE rangeLower: 0 rangeUpper: 2 mAPIID: 33000 showInAdvancedViewOnly: TRUE adminDisplayName: ms-Exch-Monitoring-Normal-Poll-Units adminDescription: ms-Exch-Monitoring-Normal-Poll-Units oMSyntax: 10 searchFlags: 0 lDAPDisplayName: monitoringNormalPollUnits name: ms-Exch-Monitoring-Normal-Poll-Units schemaIDGUID: a8df742d-c5ea-11d1-bbcb-0080c76670c0 isMemberOfPartialAttributeSet: FALSE objectCategory: CN=Attribute-Schema,${SCHEMADN} # # ms-Exch-Monitoring-Notification-Rate # How frequently the MAD should check whether a notification (such as # a mail or page) should be sent. # dn: CN=ms-Exch-Monitoring-Notification-Rate,${SCHEMADN} objectClass: top objectClass: attributeSchema cn: ms-Exch-Monitoring-Notification-Rate distinguishedName: CN=ms-Exch-Monitoring-Notification-Rate,${SCHEMADN} attributeID: 1.2.840.113556.1.4.7000.102.50057 attributeSyntax: 2.5.5.9 isSingleValued: TRUE showInAdvancedViewOnly: TRUE adminDisplayName: ms-Exch-Monitoring-Notification-Rate adminDescription: ms-Exch-Monitoring-Notification-Rate oMSyntax: 2 searchFlags: 0 lDAPDisplayName: msExchMonitoringNotificationRate name: ms-Exch-Monitoring-Notification-Rate schemaIDGUID: 8bf11686-fb18-4147-95e4-f43f8c9de87d isMemberOfPartialAttributeSet: FALSE objectCategory: CN=Attribute-Schema,${SCHEMADN} # # ms-Exch-Monitoring-Polling-Rate # The set of polling rates for each of the types of monitored # resources (such as queues, CPU, and disk). The syntax of each of the # entries will be: [TYPE],[RATE as Seconds]. # dn: CN=ms-Exch-Monitoring-Polling-Rate,${SCHEMADN} objectClass: top objectClass: attributeSchema cn: ms-Exch-Monitoring-Polling-Rate distinguishedName: CN=ms-Exch-Monitoring-Polling-Rate,${SCHEMADN} attributeID: 1.2.840.113556.1.4.7000.102.50058 attributeSyntax: 2.5.5.12 isSingleValued: FALSE showInAdvancedViewOnly: TRUE adminDisplayName: ms-Exch-Monitoring-Polling-Rate adminDescription: ms-Exch-Monitoring-Polling-Rate oMSyntax: 64 searchFlags: 0 lDAPDisplayName: msExchMonitoringPollingRate name: ms-Exch-Monitoring-Polling-Rate schemaIDGUID: a3af17a5-b2bf-442c-bd04-83dcedb19ea4 isMemberOfPartialAttributeSet: FALSE objectCategory: CN=Attribute-Schema,${SCHEMADN} # # ms-Exch-Monitoring-Queue-Polling-Frequency # dn: CN=ms-Exch-Monitoring-Queue-Polling-Frequency,${SCHEMADN} objectClass: top objectClass: attributeSchema cn: ms-Exch-Monitoring-Queue-Polling-Frequency distinguishedName: CN=ms-Exch-Monitoring-Queue-Polling-Frequency,${SCHEMADN} attributeID: 1.2.840.113556.1.4.7000.102.50038 attributeSyntax: 2.5.5.9 isSingleValued: TRUE showInAdvancedViewOnly: TRUE adminDisplayName: ms-Exch-Monitoring-Queue-Polling-Frequency adminDescription: ms-Exch-Monitoring-Queue-Polling-Frequency oMSyntax: 2 searchFlags: 0 lDAPDisplayName: msExchMonitoringQueuePollingFrequency name: ms-Exch-Monitoring-Queue-Polling-Frequency schemaIDGUID: 501b8818-29ae-11d3-aa69-00c04f8eedd8 isMemberOfPartialAttributeSet: FALSE objectCategory: CN=Attribute-Schema,${SCHEMADN} # # ms-Exch-Monitoring-Queue-Polling-Interval # dn: CN=ms-Exch-Monitoring-Queue-Polling-Interval,${SCHEMADN} objectClass: top objectClass: attributeSchema cn: ms-Exch-Monitoring-Queue-Polling-Interval distinguishedName: CN=ms-Exch-Monitoring-Queue-Polling-Interval,${SCHEMADN} attributeID: 1.2.840.113556.1.4.7000.102.50037 attributeSyntax: 2.5.5.9 isSingleValued: TRUE showInAdvancedViewOnly: TRUE adminDisplayName: ms-Exch-Monitoring-Queue-Polling-Interval adminDescription: ms-Exch-Monitoring-Queue-Polling-Interval oMSyntax: 2 searchFlags: 0 lDAPDisplayName: msExchMonitoringQueuePollingInterval name: ms-Exch-Monitoring-Queue-Polling-Interval schemaIDGUID: 501b880f-29ae-11d3-aa69-00c04f8eedd8 isMemberOfPartialAttributeSet: FALSE objectCategory: CN=Attribute-Schema,${SCHEMADN} # # ms-Exch-Monitoring-Recipients # dn: CN=ms-Exch-Monitoring-Recipients,${SCHEMADN} objectClass: top objectClass: attributeSchema cn: ms-Exch-Monitoring-Recipients distinguishedName: CN=ms-Exch-Monitoring-Recipients,${SCHEMADN} attributeID: 1.2.840.113556.1.2.159 attributeSyntax: 2.5.5.1 isSingleValued: FALSE mAPIID: 33001 showInAdvancedViewOnly: TRUE adminDisplayName: ms-Exch-Monitoring-Recipients oMObjectClass:: KwwCh3McAIVK adminDescription: ms-Exch-Monitoring-Recipients oMSyntax: 127 searchFlags: 0 lDAPDisplayName: monitoringRecipients name: ms-Exch-Monitoring-Recipients schemaIDGUID: a8df742e-c5ea-11d1-bbcb-0080c76670c0 isMemberOfPartialAttributeSet: FALSE objectCategory: CN=Attribute-Schema,${SCHEMADN} # # ms-Exch-Monitoring-Recipients-NDR # dn: CN=ms-Exch-Monitoring-Recipients-NDR,${SCHEMADN} objectClass: top objectClass: attributeSchema cn: ms-Exch-Monitoring-Recipients-NDR distinguishedName: CN=ms-Exch-Monitoring-Recipients-NDR,${SCHEMADN} attributeID: 1.2.840.113556.1.2.387 attributeSyntax: 2.5.5.1 isSingleValued: FALSE mAPIID: 33002 showInAdvancedViewOnly: TRUE adminDisplayName: ms-Exch-Monitoring-Recipients-NDR oMObjectClass:: KwwCh3McAIVK adminDescription: ms-Exch-Monitoring-Recipients-NDR oMSyntax: 127 searchFlags: 0 lDAPDisplayName: monitoringRecipientsNDR name: ms-Exch-Monitoring-Recipients-NDR schemaIDGUID: a8df742f-c5ea-11d1-bbcb-0080c76670c0 isMemberOfPartialAttributeSet: FALSE objectCategory: CN=Attribute-Schema,${SCHEMADN} # # ms-Exch-Monitoring-Resources # The set of monitored resources (such as queues, CPU, and disk). The # general syntax of each of the entries will be: TYPE, ID, [Warning # value], [Error value]. Some TYPEs may need different formats. # dn: CN=ms-Exch-Monitoring-Resources,${SCHEMADN} objectClass: top objectClass: attributeSchema cn: ms-Exch-Monitoring-Resources distinguishedName: CN=ms-Exch-Monitoring-Resources,${SCHEMADN} attributeID: 1.2.840.113556.1.4.7000.102.50059 attributeSyntax: 2.5.5.12 isSingleValued: FALSE showInAdvancedViewOnly: TRUE adminDisplayName: ms-Exch-Monitoring-Resources adminDescription: ms-Exch-Monitoring-Resources oMSyntax: 64 searchFlags: 0 lDAPDisplayName: msExchMonitoringResources name: ms-Exch-Monitoring-Resources schemaIDGUID: c1293ac0-b228-4b41-9409-2ca7d0c19459 isMemberOfPartialAttributeSet: FALSE objectCategory: CN=Attribute-Schema,${SCHEMADN} # # ms-Exch-Monitoring-Responses # dn: CN=ms-Exch-Monitoring-Responses,${SCHEMADN} objectClass: top objectClass: attributeSchema cn: ms-Exch-Monitoring-Responses distinguishedName: CN=ms-Exch-Monitoring-Responses,${SCHEMADN} attributeID: 1.2.840.113556.1.4.7000.102.50047 attributeSyntax: 2.5.5.12 isSingleValued: FALSE showInAdvancedViewOnly: TRUE adminDisplayName: ms-Exch-Monitoring-Responses adminDescription: ms-Exch-Monitoring-Responses oMSyntax: 64 searchFlags: 0 lDAPDisplayName: msExchMonitoringResponses name: ms-Exch-Monitoring-Responses schemaIDGUID: 0210cc43-34cf-11d3-aa6e-00c04f8eedd8 isMemberOfPartialAttributeSet: FALSE objectCategory: CN=Attribute-Schema,${SCHEMADN} # # ms-Exch-Monitoring-RPC-Update-Interval # dn: CN=ms-Exch-Monitoring-RPC-Update-Interval,${SCHEMADN} objectClass: top objectClass: attributeSchema cn: ms-Exch-Monitoring-RPC-Update-Interval distinguishedName: CN=ms-Exch-Monitoring-RPC-Update-Interval,${SCHEMADN} attributeID: 1.2.840.113556.1.2.92 attributeSyntax: 2.5.5.9 isSingleValued: TRUE mAPIID: 33003 showInAdvancedViewOnly: TRUE adminDisplayName: ms-Exch-Monitoring-RPC-Update-Interval adminDescription: ms-Exch-Monitoring-RPC-Update-Interval oMSyntax: 2 searchFlags: 0 lDAPDisplayName: monitoringRPCUpdateInterval name: ms-Exch-Monitoring-RPC-Update-Interval schemaIDGUID: bf9679d1-0de6-11d0-a285-00aa003049e2 isMemberOfPartialAttributeSet: FALSE objectCategory: CN=Attribute-Schema,${SCHEMADN} # # ms-Exch-Monitoring-RPC-Update-Units # dn: CN=ms-Exch-Monitoring-RPC-Update-Units,${SCHEMADN} objectClass: top objectClass: attributeSchema cn: ms-Exch-Monitoring-RPC-Update-Units distinguishedName: CN=ms-Exch-Monitoring-RPC-Update-Units,${SCHEMADN} attributeID: 1.2.840.113556.1.2.89 attributeSyntax: 2.5.5.9 isSingleValued: TRUE rangeLower: 0 rangeUpper: 2 mAPIID: 33004 showInAdvancedViewOnly: TRUE adminDisplayName: ms-Exch-Monitoring-RPC-Update-Units adminDescription: ms-Exch-Monitoring-RPC-Update-Units oMSyntax: 10 searchFlags: 0 lDAPDisplayName: monitoringRPCUpdateUnits name: ms-Exch-Monitoring-RPC-Update-Units schemaIDGUID: bf9679d2-0de6-11d0-a285-00aa003049e2 isMemberOfPartialAttributeSet: FALSE objectCategory: CN=Attribute-Schema,${SCHEMADN} # # ms-Exch-Monitoring-Warning-Delay # dn: CN=ms-Exch-Monitoring-Warning-Delay,${SCHEMADN} objectClass: top objectClass: attributeSchema cn: ms-Exch-Monitoring-Warning-Delay distinguishedName: CN=ms-Exch-Monitoring-Warning-Delay,${SCHEMADN} attributeID: 1.2.840.113556.1.2.157 attributeSyntax: 2.5.5.9 isSingleValued: TRUE mAPIID: 33005 showInAdvancedViewOnly: TRUE adminDisplayName: ms-Exch-Monitoring-Warning-Delay adminDescription: ms-Exch-Monitoring-Warning-Delay oMSyntax: 2 searchFlags: 0 lDAPDisplayName: monitoringWarningDelay name: ms-Exch-Monitoring-Warning-Delay schemaIDGUID: a8df7430-c5ea-11d1-bbcb-0080c76670c0 isMemberOfPartialAttributeSet: FALSE objectCategory: CN=Attribute-Schema,${SCHEMADN} # # ms-Exch-Monitoring-Warning-Units # dn: CN=ms-Exch-Monitoring-Warning-Units,${SCHEMADN} objectClass: top objectClass: attributeSchema cn: ms-Exch-Monitoring-Warning-Units distinguishedName: CN=ms-Exch-Monitoring-Warning-Units,${SCHEMADN} attributeID: 1.2.840.113556.1.2.56 attributeSyntax: 2.5.5.9 isSingleValued: TRUE rangeLower: 0 rangeUpper: 2 mAPIID: 33006 showInAdvancedViewOnly: TRUE adminDisplayName: ms-Exch-Monitoring-Warning-Units adminDescription: ms-Exch-Monitoring-Warning-Units oMSyntax: 10 searchFlags: 0 lDAPDisplayName: monitoringWarningUnits name: ms-Exch-Monitoring-Warning-Units schemaIDGUID: a8df7431-c5ea-11d1-bbcb-0080c76670c0 isMemberOfPartialAttributeSet: FALSE objectCategory: CN=Attribute-Schema,${SCHEMADN} # # ms-Exch-Monitor-Clock # dn: CN=ms-Exch-Monitor-Clock,${SCHEMADN} objectClass: top objectClass: attributeSchema cn: ms-Exch-Monitor-Clock distinguishedName: CN=ms-Exch-Monitor-Clock,${SCHEMADN} attributeID: 1.2.840.113556.1.2.163 attributeSyntax: 2.5.5.8 isSingleValued: TRUE mAPIID: 32982 showInAdvancedViewOnly: TRUE adminDisplayName: ms-Exch-Monitor-Clock adminDescription: ms-Exch-Monitor-Clock oMSyntax: 1 searchFlags: 0 lDAPDisplayName: monitorClock name: ms-Exch-Monitor-Clock schemaIDGUID: a8df7423-c5ea-11d1-bbcb-0080c76670c0 isMemberOfPartialAttributeSet: FALSE objectCategory: CN=Attribute-Schema,${SCHEMADN} # # ms-Exch-Monitor-Servers # dn: CN=ms-Exch-Monitor-Servers,${SCHEMADN} objectClass: top objectClass: attributeSchema cn: ms-Exch-Monitor-Servers distinguishedName: CN=ms-Exch-Monitor-Servers,${SCHEMADN} attributeID: 1.2.840.113556.1.2.156 attributeSyntax: 2.5.5.8 isSingleValued: TRUE mAPIID: 32983 showInAdvancedViewOnly: TRUE adminDisplayName: ms-Exch-Monitor-Servers adminDescription: ms-Exch-Monitor-Servers oMSyntax: 1 searchFlags: 0 lDAPDisplayName: monitorServers name: ms-Exch-Monitor-Servers schemaIDGUID: a8df7424-c5ea-11d1-bbcb-0080c76670c0 isMemberOfPartialAttributeSet: FALSE objectCategory: CN=Attribute-Schema,${SCHEMADN} # # ms-Exch-Monitor-Services # dn: CN=ms-Exch-Monitor-Services,${SCHEMADN} objectClass: top objectClass: attributeSchema cn: ms-Exch-Monitor-Services distinguishedName: CN=ms-Exch-Monitor-Services,${SCHEMADN} attributeID: 1.2.840.113556.1.2.160 attributeSyntax: 2.5.5.8 isSingleValued: TRUE mAPIID: 32984 showInAdvancedViewOnly: TRUE adminDisplayName: ms-Exch-Monitor-Services adminDescription: ms-Exch-Monitor-Services oMSyntax: 1 searchFlags: 0 lDAPDisplayName: monitorServices name: ms-Exch-Monitor-Services schemaIDGUID: a8df7425-c5ea-11d1-bbcb-0080c76670c0 isMemberOfPartialAttributeSet: FALSE objectCategory: CN=Attribute-Schema,${SCHEMADN} # # ms-Exch-Move-To-LSA # dn: CN=ms-Exch-Move-To-LSA,${SCHEMADN} objectClass: top objectClass: attributeSchema cn: ms-Exch-Move-To-LSA distinguishedName: CN=ms-Exch-Move-To-LSA,${SCHEMADN} attributeID: 1.2.840.113556.1.4.7000.102.88 attributeSyntax: 2.5.5.8 isSingleValued: TRUE showInAdvancedViewOnly: TRUE adminDisplayName: ms-Exch-Move-To-LSA adminDescription: ms-Exch-Move-To-LSA oMSyntax: 1 searchFlags: 0 lDAPDisplayName: msExchMoveToLSA name: ms-Exch-Move-To-LSA schemaIDGUID: ab4cc53c-4ba4-11d3-aa75-00c04f8eedd8 isMemberOfPartialAttributeSet: FALSE objectCategory: CN=Attribute-Schema,${SCHEMADN} # # ms-Exch-MTA-Database-Path # dn: CN=ms-Exch-MTA-Database-Path,${SCHEMADN} objectClass: top objectClass: attributeSchema cn: ms-Exch-MTA-Database-Path distinguishedName: CN=ms-Exch-MTA-Database-Path,${SCHEMADN} attributeID: 1.2.840.113556.1.4.7000.102.18001 attributeSyntax: 2.5.5.12 isSingleValued: TRUE showInAdvancedViewOnly: TRUE adminDisplayName: ms-Exch-MTA-Database-Path adminDescription: ms-Exch-MTA-Database-Path oMSyntax: 64 searchFlags: 0 lDAPDisplayName: msExchMTADatabasePath name: ms-Exch-MTA-Database-Path schemaIDGUID: 2f2dc2a4-242e-11d3-aa66-00c04f8eedd8 isMemberOfPartialAttributeSet: FALSE objectCategory: CN=Attribute-Schema,${SCHEMADN} # # ms-Exch-MTA-Local-Cred # dn: CN=ms-Exch-MTA-Local-Cred,${SCHEMADN} objectClass: top objectClass: attributeSchema cn: ms-Exch-MTA-Local-Cred distinguishedName: CN=ms-Exch-MTA-Local-Cred,${SCHEMADN} attributeID: 1.2.840.113556.1.2.270 attributeSyntax: 2.5.5.5 isSingleValued: TRUE rangeLower: 1 rangeUpper: 64 mAPIID: 33007 showInAdvancedViewOnly: TRUE adminDisplayName: ms-Exch-MTA-Local-Cred adminDescription: ms-Exch-MTA-Local-Cred oMSyntax: 22 searchFlags: 0 lDAPDisplayName: mTALocalCred name: ms-Exch-MTA-Local-Cred schemaIDGUID: a8df7432-c5ea-11d1-bbcb-0080c76670c0 isMemberOfPartialAttributeSet: FALSE objectCategory: CN=Attribute-Schema,${SCHEMADN} # # ms-Exch-MTA-Local-Desig # dn: CN=ms-Exch-MTA-Local-Desig,${SCHEMADN} objectClass: top objectClass: attributeSchema cn: ms-Exch-MTA-Local-Desig distinguishedName: CN=ms-Exch-MTA-Local-Desig,${SCHEMADN} attributeID: 1.2.840.113556.1.2.271 attributeSyntax: 2.5.5.5 isSingleValued: TRUE rangeLower: 1 rangeUpper: 32 mAPIID: 33008 showInAdvancedViewOnly: TRUE adminDisplayName: ms-Exch-MTA-Local-Desig adminDescription: ms-Exch-MTA-Local-Desig oMSyntax: 22 searchFlags: 0 lDAPDisplayName: mTALocalDesig name: ms-Exch-MTA-Local-Desig schemaIDGUID: a8df7433-c5ea-11d1-bbcb-0080c76670c0 isMemberOfPartialAttributeSet: FALSE objectCategory: CN=Attribute-Schema,${SCHEMADN} # # ms-Exch-Non-Authoritative-Domains # dn: CN=ms-Exch-Non-Authoritative-Domains,${SCHEMADN} objectClass: top objectClass: attributeSchema cn: ms-Exch-Non-Authoritative-Domains distinguishedName: CN=ms-Exch-Non-Authoritative-Domains,${SCHEMADN} attributeID: 1.2.840.113556.1.4.7000.102.50084 attributeSyntax: 2.5.5.12 isSingleValued: FALSE rangeLower: 1 rangeUpper: 1123 showInAdvancedViewOnly: TRUE adminDisplayName: ms-Exch-Non-Authoritative-Domains adminDescription: ms-Exch-Non-Authoritative-Domains oMSyntax: 64 searchFlags: 0 lDAPDisplayName: msExchNonAuthoritativeDomains name: ms-Exch-Non-Authoritative-Domains schemaIDGUID: ef2c7c70-f874-4280-8643-2334f2d3340c isMemberOfPartialAttributeSet: FALSE objectCategory: CN=Attribute-Schema,${SCHEMADN} # # ms-Exch-Non-MIME-Character-Set # dn: CN=ms-Exch-Non-MIME-Character-Set,${SCHEMADN} objectClass: top objectClass: attributeSchema cn: ms-Exch-Non-MIME-Character-Set distinguishedName: CN=ms-Exch-Non-MIME-Character-Set,${SCHEMADN} attributeID: 1.2.840.113556.1.4.7000.102.50043 attributeSyntax: 2.5.5.12 isSingleValued: TRUE rangeLower: 1 rangeUpper: 64 showInAdvancedViewOnly: TRUE adminDisplayName: ms-Exch-Non-MIME-Character-Set adminDescription: ms-Exch-Non-MIME-Character-Set oMSyntax: 64 searchFlags: 0 lDAPDisplayName: msExchNonMIMECharacterSet name: ms-Exch-Non-MIME-Character-Set schemaIDGUID: 974c99fe-33fc-11d3-aa6e-00c04f8eedd8 isMemberOfPartialAttributeSet: FALSE objectCategory: CN=Attribute-Schema,${SCHEMADN} # # ms-Exch-Notes-Connector-Mailbox # Name of the Lotus Notes mailbox where the connector picks up mail # from Notes for delivery into Exchange. # dn: CN=ms-Exch-Notes-Connector-Mailbox,${SCHEMADN} objectClass: top objectClass: attributeSchema cn: ms-Exch-Notes-Connector-Mailbox distinguishedName: CN=ms-Exch-Notes-Connector-Mailbox,${SCHEMADN} attributeID: 1.2.840.113556.1.4.7000.102.1014 attributeSyntax: 2.5.5.12 isSingleValued: TRUE showInAdvancedViewOnly: TRUE adminDisplayName: ms-Exch-Notes-Connector-Mailbox adminDescription: ms-Exch-Notes-Connector-Mailbox oMSyntax: 64 searchFlags: 0 lDAPDisplayName: msExchNotesConnectorMailbox name: ms-Exch-Notes-Connector-Mailbox schemaIDGUID: aa5a0cb8-b093-11d2-aa06-00c04f8eedd8 isMemberOfPartialAttributeSet: FALSE objectCategory: CN=Attribute-Schema,${SCHEMADN} # # ms-Exch-Notes-Exclude-Groups # A list of Lotus Notes groups to exclude from directory # synchronization. # dn: CN=ms-Exch-Notes-Exclude-Groups,${SCHEMADN} objectClass: top objectClass: attributeSchema cn: ms-Exch-Notes-Exclude-Groups distinguishedName: CN=ms-Exch-Notes-Exclude-Groups,${SCHEMADN} attributeID: 1.2.840.113556.1.4.7000.102.1022 attributeSyntax: 2.5.5.12 isSingleValued: FALSE showInAdvancedViewOnly: TRUE adminDisplayName: ms-Exch-Notes-Exclude-Groups adminDescription: ms-Exch-Notes-Exclude-Groups oMSyntax: 64 searchFlags: 0 lDAPDisplayName: msExchNotesExcludeGroups name: ms-Exch-Notes-Exclude-Groups schemaIDGUID: 0c74acba-b098-11d2-aa06-00c04f8eedd8 isMemberOfPartialAttributeSet: FALSE objectCategory: CN=Attribute-Schema,${SCHEMADN} # # ms-Exch-Notes-Export-Groups # A flag indicating whether Lotus Notes groups should be exported to # Exchange during directory synchronization. # dn: CN=ms-Exch-Notes-Export-Groups,${SCHEMADN} objectClass: top objectClass: attributeSchema cn: ms-Exch-Notes-Export-Groups distinguishedName: CN=ms-Exch-Notes-Export-Groups,${SCHEMADN} attributeID: 1.2.840.113556.1.4.7000.102.1021 attributeSyntax: 2.5.5.8 isSingleValued: TRUE showInAdvancedViewOnly: TRUE adminDisplayName: ms-Exch-Notes-Export-Groups adminDescription: ms-Exch-Notes-Export-Groups oMSyntax: 1 searchFlags: 0 lDAPDisplayName: msExchNotesExportGroups name: ms-Exch-Notes-Export-Groups schemaIDGUID: 0eb5a5ce-b098-11d2-aa06-00c04f8eedd8 isMemberOfPartialAttributeSet: FALSE objectCategory: CN=Attribute-Schema,${SCHEMADN} # # ms-Exch-Notes-Foreign-Domain # The name of the Lotus Notes foreign domain that represents Exchange. # dn: CN=ms-Exch-Notes-Foreign-Domain,${SCHEMADN} objectClass: top objectClass: attributeSchema cn: ms-Exch-Notes-Foreign-Domain distinguishedName: CN=ms-Exch-Notes-Foreign-Domain,${SCHEMADN} attributeID: 1.2.840.113556.1.4.7000.102.1012 attributeSyntax: 2.5.5.12 isSingleValued: TRUE showInAdvancedViewOnly: TRUE adminDisplayName: ms-Exch-Notes-Foreign-Domain adminDescription: ms-Exch-Notes-Foreign-Domain oMSyntax: 64 searchFlags: 0 lDAPDisplayName: msExchNotesForeignDomain name: ms-Exch-Notes-Foreign-Domain schemaIDGUID: 137332c0-b098-11d2-aa06-00c04f8eedd8 isMemberOfPartialAttributeSet: FALSE objectCategory: CN=Attribute-Schema,${SCHEMADN} # # ms-Exch-Notes-Letterhead # The name of the Lotus Notes letterhead style used for messages # delivered into Notes from Exchange. # dn: CN=ms-Exch-Notes-Letterhead,${SCHEMADN} objectClass: top objectClass: attributeSchema cn: ms-Exch-Notes-Letterhead distinguishedName: CN=ms-Exch-Notes-Letterhead,${SCHEMADN} attributeID: 1.2.840.113556.1.4.7000.102.1015 attributeSyntax: 2.5.5.12 isSingleValued: TRUE showInAdvancedViewOnly: TRUE adminDisplayName: ms-Exch-Notes-Letterhead adminDescription: ms-Exch-Notes-Letterhead oMSyntax: 64 searchFlags: 0 lDAPDisplayName: msExchNotesLetterhead name: ms-Exch-Notes-Letterhead schemaIDGUID: 141552a8-b098-11d2-aa06-00c04f8eedd8 isMemberOfPartialAttributeSet: FALSE objectCategory: CN=Attribute-Schema,${SCHEMADN} # # ms-Exch-Notes-Notes-INI # The full path and file name of the Lotus Notes client INI file used # by the connector to log on to the Notes server. # dn: CN=ms-Exch-Notes-Notes-INI,${SCHEMADN} objectClass: top objectClass: attributeSchema cn: ms-Exch-Notes-Notes-INI distinguishedName: CN=ms-Exch-Notes-Notes-INI,${SCHEMADN} attributeID: 1.2.840.113556.1.4.7000.102.1017 attributeSyntax: 2.5.5.12 isSingleValued: TRUE showInAdvancedViewOnly: TRUE adminDisplayName: ms-Exch-Notes-Notes-INI adminDescription: ms-Exch-Notes-Notes-INI oMSyntax: 64 searchFlags: 0 lDAPDisplayName: msExchNotesNotesINI name: ms-Exch-Notes-Notes-INI schemaIDGUID: 13d02e76-b098-11d2-aa06-00c04f8eedd8 isMemberOfPartialAttributeSet: FALSE objectCategory: CN=Attribute-Schema,${SCHEMADN} # # ms-Exch-Notes-Notes-Links # Determines how Lotus Notes doclinks are converted in messages to # Exchange. Options are RTF, OLE, or URL. # dn: CN=ms-Exch-Notes-Notes-Links,${SCHEMADN} objectClass: top objectClass: attributeSchema cn: ms-Exch-Notes-Notes-Links distinguishedName: CN=ms-Exch-Notes-Notes-Links,${SCHEMADN} attributeID: 1.2.840.113556.1.4.7000.102.1016 attributeSyntax: 2.5.5.12 isSingleValued: TRUE showInAdvancedViewOnly: TRUE adminDisplayName: ms-Exch-Notes-Notes-Links adminDescription: ms-Exch-Notes-Notes-Links oMSyntax: 64 searchFlags: 0 lDAPDisplayName: msExchNotesNotesLinks name: ms-Exch-Notes-Notes-Links schemaIDGUID: aa7dcffe-b093-11d2-aa06-00c04f8eedd8 isMemberOfPartialAttributeSet: FALSE objectCategory: CN=Attribute-Schema,${SCHEMADN} # # ms-Exch-Notes-Notes-Server # The name of the Lotus Notes server to which the Connector # attaches. Notes format name, not server name. # dn: CN=ms-Exch-Notes-Notes-Server,${SCHEMADN} objectClass: top objectClass: attributeSchema cn: ms-Exch-Notes-Notes-Server distinguishedName: CN=ms-Exch-Notes-Notes-Server,${SCHEMADN} attributeID: 1.2.840.113556.1.4.7000.102.1011 attributeSyntax: 2.5.5.12 isSingleValued: TRUE showInAdvancedViewOnly: TRUE adminDisplayName: ms-Exch-Notes-Notes-Server adminDescription: ms-Exch-Notes-Notes-Server oMSyntax: 64 searchFlags: 0 lDAPDisplayName: msExchNotesNotesServer name: ms-Exch-Notes-Notes-Server schemaIDGUID: 14b51036-b098-11d2-aa06-00c04f8eedd8 isMemberOfPartialAttributeSet: FALSE objectCategory: CN=Attribute-Schema,${SCHEMADN} # # ms-Exch-Notes-Password # dn: CN=ms-Exch-Notes-Password,${SCHEMADN} objectClass: top objectClass: attributeSchema cn: ms-Exch-Notes-Password distinguishedName: CN=ms-Exch-Notes-Password,${SCHEMADN} attributeID: 1.2.840.113556.1.4.7000.102.1010 attributeSyntax: 2.5.5.10 isSingleValued: TRUE showInAdvancedViewOnly: TRUE adminDisplayName: ms-Exch-Notes-Password adminDescription: ms-Exch-Notes-Password oMSyntax: 4 searchFlags: 0 lDAPDisplayName: msExchNotesPassword name: ms-Exch-Notes-Password schemaIDGUID: 593fa28d-2862-11d3-aa68-00c04f8eedd8 isMemberOfPartialAttributeSet: FALSE objectCategory: CN=Attribute-Schema,${SCHEMADN} # # ms-Exch-Notes-Routable-Domains # dn: CN=ms-Exch-Notes-Routable-Domains,${SCHEMADN} objectClass: top objectClass: attributeSchema cn: ms-Exch-Notes-Routable-Domains distinguishedName: CN=ms-Exch-Notes-Routable-Domains,${SCHEMADN} attributeID: 1.2.840.113556.1.4.7000.102.1023 attributeSyntax: 2.5.5.12 isSingleValued: FALSE showInAdvancedViewOnly: TRUE adminDisplayName: ms-Exch-Notes-Routable-Domains adminDescription: ms-Exch-Notes-Routable-Domains oMSyntax: 64 searchFlags: 0 lDAPDisplayName: msExchNotesRoutableDomains name: ms-Exch-Notes-Routable-Domains schemaIDGUID: 90804554-b09e-11d2-aa06-00c04f8eedd8 isMemberOfPartialAttributeSet: FALSE objectCategory: CN=Attribute-Schema,${SCHEMADN} # # ms-Exch-Notes-Rtr-Mailbox # The name of the mailbox used by the Lotus Notes mail router. This is # usually MAIL.BOX. # dn: CN=ms-Exch-Notes-Rtr-Mailbox,${SCHEMADN} objectClass: top objectClass: attributeSchema cn: ms-Exch-Notes-Rtr-Mailbox distinguishedName: CN=ms-Exch-Notes-Rtr-Mailbox,${SCHEMADN} attributeID: 1.2.840.113556.1.4.7000.102.1013 attributeSyntax: 2.5.5.12 isSingleValued: TRUE showInAdvancedViewOnly: TRUE adminDisplayName: ms-Exch-Notes-Rtr-Mailbox adminDescription: ms-Exch-Notes-Rtr-Mailbox oMSyntax: 64 searchFlags: 0 lDAPDisplayName: msExchNotesRtrMailbox name: ms-Exch-Notes-Rtr-Mailbox schemaIDGUID: 144c28be-b098-11d2-aa06-00c04f8eedd8 isMemberOfPartialAttributeSet: FALSE objectCategory: CN=Attribute-Schema,${SCHEMADN} # # ms-Exch-Notes-Source-Books # A list of the Lotus Notes Name and Address Books exported to # Exchange for directory synchronization. # dn: CN=ms-Exch-Notes-Source-Books,${SCHEMADN} objectClass: top objectClass: attributeSchema cn: ms-Exch-Notes-Source-Books distinguishedName: CN=ms-Exch-Notes-Source-Books,${SCHEMADN} attributeID: 1.2.840.113556.1.4.7000.102.1020 attributeSyntax: 2.5.5.12 isSingleValued: FALSE showInAdvancedViewOnly: TRUE adminDisplayName: ms-Exch-Notes-Source-Books adminDescription: ms-Exch-Notes-Source-Books oMSyntax: 64 searchFlags: 0 lDAPDisplayName: msExchNotesSourceBooks name: ms-Exch-Notes-Source-Books schemaIDGUID: 12b6d8fa-b098-11d2-aa06-00c04f8eedd8 isMemberOfPartialAttributeSet: FALSE objectCategory: CN=Attribute-Schema,${SCHEMADN} # # ms-Exch-Notes-Target-Book # The name of the default Name and Address Book into which Exchange # users are imported. # dn: CN=ms-Exch-Notes-Target-Book,${SCHEMADN} objectClass: top objectClass: attributeSchema cn: ms-Exch-Notes-Target-Book distinguishedName: CN=ms-Exch-Notes-Target-Book,${SCHEMADN} attributeID: 1.2.840.113556.1.4.7000.102.1018 attributeSyntax: 2.5.5.12 isSingleValued: TRUE showInAdvancedViewOnly: TRUE adminDisplayName: ms-Exch-Notes-Target-Book adminDescription: ms-Exch-Notes-Target-Book oMSyntax: 64 searchFlags: 0 lDAPDisplayName: msExchNotesTargetBook name: ms-Exch-Notes-Target-Book schemaIDGUID: 13a07f6e-b098-11d2-aa06-00c04f8eedd8 isMemberOfPartialAttributeSet: FALSE objectCategory: CN=Attribute-Schema,${SCHEMADN} # # ms-Exch-Notes-Target-Books # A list of domain-specific Lotus Notes Name and Address Books for # directory import. # dn: CN=ms-Exch-Notes-Target-Books,${SCHEMADN} objectClass: top objectClass: attributeSchema cn: ms-Exch-Notes-Target-Books distinguishedName: CN=ms-Exch-Notes-Target-Books,${SCHEMADN} attributeID: 1.2.840.113556.1.4.7000.102.1019 attributeSyntax: 2.5.5.12 isSingleValued: FALSE showInAdvancedViewOnly: TRUE adminDisplayName: ms-Exch-Notes-Target-Books adminDescription: ms-Exch-Notes-Target-Books oMSyntax: 64 searchFlags: 0 lDAPDisplayName: msExchNotesTargetBooks name: ms-Exch-Notes-Target-Books schemaIDGUID: aad1424c-b093-11d2-aa06-00c04f8eedd8 isMemberOfPartialAttributeSet: FALSE objectCategory: CN=Attribute-Schema,${SCHEMADN} # # ms-Exch-No-PF-Connection # Boolean state to determine if (MAPI) clients are allowed to connect # to public folder content in the target routing group. By default, if # not set, public folder referrals will be allowed over this # connector. # dn: CN=ms-Exch-No-PF-Connection,${SCHEMADN} objectClass: top objectClass: attributeSchema cn: ms-Exch-No-PF-Connection distinguishedName: CN=ms-Exch-No-PF-Connection,${SCHEMADN} attributeID: 1.2.840.113556.1.4.7000.102.11067 attributeSyntax: 2.5.5.8 isSingleValued: TRUE showInAdvancedViewOnly: TRUE adminDisplayName: ms-Exch-No-PF-Connection adminDescription: ms-Exch-No-PF-Connection oMSyntax: 1 searchFlags: 0 lDAPDisplayName: msExchNoPFConnection name: ms-Exch-No-PF-Connection schemaIDGUID: 9ff15c41-1ec9-11d3-aa5e-00c04f8eedd8 isMemberOfPartialAttributeSet: FALSE objectCategory: CN=Attribute-Schema,${SCHEMADN} # # ms-Exch-Ntds-Export-Containers # The GUID of NTDS containers or OUs to search in for objects to be # synchronized. # dn: CN=ms-Exch-Ntds-Export-Containers,${SCHEMADN} objectClass: top objectClass: attributeSchema cn: ms-Exch-Ntds-Export-Containers distinguishedName: CN=ms-Exch-Ntds-Export-Containers,${SCHEMADN} attributeID: 1.2.840.113556.1.4.7000.102.33 attributeSyntax: 2.5.5.1 isSingleValued: FALSE showInAdvancedViewOnly: TRUE adminDisplayName: ms-Exch-Ntds-Export-Containers oMObjectClass:: KwwCh3McAIVK adminDescription: ms-Exch-Ntds-Export-Containers oMSyntax: 127 searchFlags: 0 lDAPDisplayName: msExchNtdsExportContainers name: ms-Exch-Ntds-Export-Containers schemaIDGUID: 155bf4d2-b098-11d2-aa06-00c04f8eedd8 isMemberOfPartialAttributeSet: FALSE objectCategory: CN=Attribute-Schema,${SCHEMADN} # # ms-Exch-Ntds-Import-Container # The GUID of NTDS containers or OUs to write synchronized objects to. # dn: CN=ms-Exch-Ntds-Import-Container,${SCHEMADN} objectClass: top objectClass: attributeSchema cn: ms-Exch-Ntds-Import-Container distinguishedName: CN=ms-Exch-Ntds-Import-Container,${SCHEMADN} attributeID: 1.2.840.113556.1.4.7000.102.34 attributeSyntax: 2.5.5.1 isSingleValued: TRUE showInAdvancedViewOnly: TRUE adminDisplayName: ms-Exch-Ntds-Import-Container oMObjectClass:: KwwCh3McAIVK adminDescription: ms-Exch-Ntds-Import-Container oMSyntax: 127 searchFlags: 0 lDAPDisplayName: msExchNtdsImportContainer name: ms-Exch-Ntds-Import-Container schemaIDGUID: 1592cae8-b098-11d2-aa06-00c04f8eedd8 isMemberOfPartialAttributeSet: FALSE objectCategory: CN=Attribute-Schema,${SCHEMADN} # # ms-Exch-NT-Account-Options # dn: CN=ms-Exch-NT-Account-Options,${SCHEMADN} objectClass: top objectClass: attributeSchema cn: ms-Exch-NT-Account-Options distinguishedName: CN=ms-Exch-NT-Account-Options,${SCHEMADN} attributeID: 1.2.840.113556.1.4.7000.102.44 attributeSyntax: 2.5.5.9 isSingleValued: TRUE showInAdvancedViewOnly: TRUE adminDisplayName: ms-Exch-NT-Account-Options adminDescription: ms-Exch-NT-Account-Options oMSyntax: 10 searchFlags: 0 lDAPDisplayName: msExchNTAccountOptions name: ms-Exch-NT-Account-Options schemaIDGUID: 14ebe64c-b098-11d2-aa06-00c04f8eedd8 isMemberOfPartialAttributeSet: FALSE objectCategory: CN=Attribute-Schema,${SCHEMADN} # # ms-Exch-NT-Authentication-Providers # A list of Security Support Provider Interface (SSPI) packages that # may be used to authenticate to this resource. # dn: CN=ms-Exch-NT-Authentication-Providers,${SCHEMADN} objectClass: top objectClass: attributeSchema cn: ms-Exch-NT-Authentication-Providers distinguishedName: CN=ms-Exch-NT-Authentication-Providers,${SCHEMADN} attributeID: 1.2.840.113556.1.4.7000.102.2009 attributeSyntax: 2.5.5.12 isSingleValued: TRUE showInAdvancedViewOnly: TRUE adminDisplayName: ms-Exch-NT-Authentication-Providers adminDescription: ms-Exch-NT-Authentication-Providers oMSyntax: 64 searchFlags: 0 lDAPDisplayName: msExchNTAuthenticationProviders name: ms-Exch-NT-Authentication-Providers schemaIDGUID: 15278116-b098-11d2-aa06-00c04f8eedd8 isMemberOfPartialAttributeSet: FALSE objectCategory: CN=Attribute-Schema,${SCHEMADN} # # ms-Exch-Num-Of-Open-Retries # dn: CN=ms-Exch-Num-Of-Open-Retries,${SCHEMADN} objectClass: top objectClass: attributeSchema cn: ms-Exch-Num-Of-Open-Retries distinguishedName: CN=ms-Exch-Num-Of-Open-Retries,${SCHEMADN} attributeID: 1.2.840.113556.1.2.148 attributeSyntax: 2.5.5.9 isSingleValued: TRUE rangeLower: 0 rangeUpper: 32767 mAPIID: 33012 showInAdvancedViewOnly: TRUE adminDisplayName: ms-Exch-Num-Of-Open-Retries adminDescription: ms-Exch-Num-Of-Open-Retries oMSyntax: 2 searchFlags: 0 lDAPDisplayName: numOfOpenRetries name: ms-Exch-Num-Of-Open-Retries schemaIDGUID: a8df743a-c5ea-11d1-bbcb-0080c76670c0 isMemberOfPartialAttributeSet: FALSE objectCategory: CN=Attribute-Schema,${SCHEMADN} # # ms-Exch-Num-Of-Transfer-Retries # dn: CN=ms-Exch-Num-Of-Transfer-Retries,${SCHEMADN} objectClass: top objectClass: attributeSchema cn: ms-Exch-Num-Of-Transfer-Retries distinguishedName: CN=ms-Exch-Num-Of-Transfer-Retries,${SCHEMADN} attributeID: 1.2.840.113556.1.2.134 attributeSyntax: 2.5.5.9 isSingleValued: TRUE rangeLower: 0 rangeUpper: 32767 mAPIID: 33013 showInAdvancedViewOnly: TRUE adminDisplayName: ms-Exch-Num-Of-Transfer-Retries adminDescription: ms-Exch-Num-Of-Transfer-Retries oMSyntax: 2 searchFlags: 0 lDAPDisplayName: numOfTransferRetries name: ms-Exch-Num-Of-Transfer-Retries schemaIDGUID: a8df743b-c5ea-11d1-bbcb-0080c76670c0 isMemberOfPartialAttributeSet: FALSE objectCategory: CN=Attribute-Schema,${SCHEMADN} # # ms-Exch-N-Address # dn: CN=ms-Exch-N-Address,${SCHEMADN} objectClass: top objectClass: attributeSchema cn: ms-Exch-N-Address distinguishedName: CN=ms-Exch-N-Address,${SCHEMADN} attributeID: 1.2.840.113556.1.2.282 attributeSyntax: 2.5.5.10 isSingleValued: TRUE rangeLower: 1 rangeUpper: 50 mAPIID: 33009 showInAdvancedViewOnly: TRUE adminDisplayName: ms-Exch-N-Address adminDescription: ms-Exch-N-Address oMSyntax: 4 searchFlags: 0 lDAPDisplayName: nAddress name: ms-Exch-N-Address schemaIDGUID: a8df7434-c5ea-11d1-bbcb-0080c76670c0 isMemberOfPartialAttributeSet: FALSE objectCategory: CN=Attribute-Schema,${SCHEMADN} # # ms-Exch-N-Address-Type # dn: CN=ms-Exch-N-Address-Type,${SCHEMADN} objectClass: top objectClass: attributeSchema cn: ms-Exch-N-Address-Type distinguishedName: CN=ms-Exch-N-Address-Type,${SCHEMADN} attributeID: 1.2.840.113556.1.2.222 attributeSyntax: 2.5.5.9 isSingleValued: TRUE mAPIID: 33010 showInAdvancedViewOnly: TRUE adminDisplayName: ms-Exch-N-Address-Type adminDescription: ms-Exch-N-Address-Type oMSyntax: 10 searchFlags: 0 lDAPDisplayName: nAddressType name: ms-Exch-N-Address-Type schemaIDGUID: a8df7435-c5ea-11d1-bbcb-0080c76670c0 isMemberOfPartialAttributeSet: FALSE objectCategory: CN=Attribute-Schema,${SCHEMADN} # # ms-Exch-OAB-Default # dn: CN=ms-Exch-OAB-Default,${SCHEMADN} objectClass: top objectClass: attributeSchema cn: ms-Exch-OAB-Default distinguishedName: CN=ms-Exch-OAB-Default,${SCHEMADN} attributeID: 1.2.840.113556.1.4.7000.102.67 attributeSyntax: 2.5.5.8 isSingleValued: TRUE showInAdvancedViewOnly: TRUE adminDisplayName: ms-Exch-OAB-Default adminDescription: ms-Exch-OAB-Default oMSyntax: 1 searchFlags: 0 lDAPDisplayName: msExchOABDefault name: ms-Exch-OAB-Default schemaIDGUID: 15c279f0-b098-11d2-aa06-00c04f8eedd8 isMemberOfPartialAttributeSet: FALSE objectCategory: CN=Attribute-Schema,${SCHEMADN} # # ms-Exch-OAB-Folder # The entry ID of the public folder that this offline address book # (OAB) is stored in. # dn: CN=ms-Exch-OAB-Folder,${SCHEMADN} objectClass: top objectClass: attributeSchema cn: ms-Exch-OAB-Folder distinguishedName: CN=ms-Exch-OAB-Folder,${SCHEMADN} attributeID: 1.2.840.113556.1.4.7000.102.68 attributeSyntax: 2.5.5.10 isSingleValued: TRUE showInAdvancedViewOnly: TRUE adminDisplayName: ms-Exch-OAB-Folder adminDescription: ms-Exch-OAB-Folder oMSyntax: 4 searchFlags: 0 lDAPDisplayName: msExchOABFolder name: ms-Exch-OAB-Folder schemaIDGUID: 15f6edac-b098-11d2-aa06-00c04f8eedd8 isMemberOfPartialAttributeSet: FALSE objectCategory: CN=Attribute-Schema,${SCHEMADN} # # ms-Exch-Obj-View-Containers # dn: CN=ms-Exch-Obj-View-Containers,${SCHEMADN} objectClass: top objectClass: attributeSchema cn: ms-Exch-Obj-View-Containers distinguishedName: CN=ms-Exch-Obj-View-Containers,${SCHEMADN} attributeID: 1.2.840.113556.1.2.545 attributeSyntax: 2.5.5.1 isSingleValued: FALSE mAPIID: 33223 showInAdvancedViewOnly: TRUE adminDisplayName: ms-Exch-Obj-View-Containers oMObjectClass:: KwwCh3McAIVK adminDescription: ms-Exch-Obj-View-Containers oMSyntax: 127 searchFlags: 0 lDAPDisplayName: objViewContainers name: ms-Exch-Obj-View-Containers schemaIDGUID: 16775847-47f3-11d1-a9c3-0000f80367c1 isMemberOfPartialAttributeSet: FALSE objectCategory: CN=Attribute-Schema,${SCHEMADN} # # ms-Exch-Off-Line-AB-Containers # dn: CN=ms-Exch-Off-Line-AB-Containers,${SCHEMADN} objectClass: top objectClass: attributeSchema cn: ms-Exch-Off-Line-AB-Containers distinguishedName: CN=ms-Exch-Off-Line-AB-Containers,${SCHEMADN} attributeID: 1.2.840.113556.1.2.391 attributeSyntax: 2.5.5.1 isSingleValued: FALSE mAPIID: 33016 showInAdvancedViewOnly: TRUE adminDisplayName: ms-Exch-Off-Line-AB-Containers oMObjectClass:: KwwCh3McAIVK adminDescription: ms-Exch-Off-Line-AB-Containers oMSyntax: 127 searchFlags: 0 lDAPDisplayName: offLineABContainers name: ms-Exch-Off-Line-AB-Containers schemaIDGUID: a8df743c-c5ea-11d1-bbcb-0080c76670c0 isMemberOfPartialAttributeSet: FALSE objectCategory: CN=Attribute-Schema,${SCHEMADN} # # ms-Exch-Off-Line-AB-Schedule # dn: CN=ms-Exch-Off-Line-AB-Schedule,${SCHEMADN} objectClass: top objectClass: attributeSchema cn: ms-Exch-Off-Line-AB-Schedule distinguishedName: CN=ms-Exch-Off-Line-AB-Schedule,${SCHEMADN} attributeID: 1.2.840.113556.1.2.389 attributeSyntax: 2.5.5.10 isSingleValued: TRUE rangeLower: 84 rangeUpper: 84 mAPIID: 33017 showInAdvancedViewOnly: TRUE adminDisplayName: ms-Exch-Off-Line-AB-Schedule adminDescription: ms-Exch-Off-Line-AB-Schedule oMSyntax: 4 searchFlags: 0 lDAPDisplayName: offLineABSchedule name: ms-Exch-Off-Line-AB-Schedule schemaIDGUID: a8df743d-c5ea-11d1-bbcb-0080c76670c0 isMemberOfPartialAttributeSet: FALSE objectCategory: CN=Attribute-Schema,${SCHEMADN} # # ms-Exch-Off-Line-AB-Server # dn: CN=ms-Exch-Off-Line-AB-Server,${SCHEMADN} objectClass: top objectClass: attributeSchema cn: ms-Exch-Off-Line-AB-Server distinguishedName: CN=ms-Exch-Off-Line-AB-Server,${SCHEMADN} attributeID: 1.2.840.113556.1.2.392 attributeSyntax: 2.5.5.1 isSingleValued: TRUE mAPIID: 33018 showInAdvancedViewOnly: TRUE adminDisplayName: ms-Exch-Off-Line-AB-Server oMObjectClass:: KwwCh3McAIVK adminDescription: ms-Exch-Off-Line-AB-Server oMSyntax: 127 searchFlags: 0 lDAPDisplayName: offLineABServer name: ms-Exch-Off-Line-AB-Server schemaIDGUID: a8df743e-c5ea-11d1-bbcb-0080c76670c0 isMemberOfPartialAttributeSet: FALSE objectCategory: CN=Attribute-Schema,${SCHEMADN} # # ms-Exch-Off-Line-AB-Style # dn: CN=ms-Exch-Off-Line-AB-Style,${SCHEMADN} objectClass: top objectClass: attributeSchema cn: ms-Exch-Off-Line-AB-Style distinguishedName: CN=ms-Exch-Off-Line-AB-Style,${SCHEMADN} attributeID: 1.2.840.113556.1.2.390 attributeSyntax: 2.5.5.9 isSingleValued: TRUE mAPIID: 33019 showInAdvancedViewOnly: TRUE adminDisplayName: ms-Exch-Off-Line-AB-Style adminDescription: ms-Exch-Off-Line-AB-Style oMSyntax: 2 searchFlags: 0 lDAPDisplayName: offLineABStyle name: ms-Exch-Off-Line-AB-Style schemaIDGUID: a8df743f-c5ea-11d1-bbcb-0080c76670c0 isMemberOfPartialAttributeSet: FALSE objectCategory: CN=Attribute-Schema,${SCHEMADN} # # ms-Exch-Oma-Admin-Extended-Settings # dn: CN=ms-Exch-Oma-Admin-Extended-Settings,${SCHEMADN} objectClass: top objectClass: attributeSchema cn: ms-Exch-Oma-Admin-Extended-Settings distinguishedName: CN=ms-Exch-Oma-Admin-Extended-Settings,${SCHEMADN} attributeID: 1.2.840.113556.1.6.20.1.126 attributeSyntax: 2.5.5.12 isSingleValued: FALSE showInAdvancedViewOnly: TRUE adminDisplayName: ms-Exch-Oma-Admin-Extended-Settings adminDescription: ms-Exch-Oma-Admin-Extended-Settings oMSyntax: 64 searchFlags: 0 lDAPDisplayName: msExchOmaAdminExtendedSettings name: ms-Exch-Oma-Admin-Extended-Settings schemaIDGUID: e60ae80d-7ac9-4e61-9bc3-98cbc0726a99 attributeSecurityGUID: e48d0154-bcf8-11d1-8702-00c04fb96050 isMemberOfPartialAttributeSet: TRUE objectCategory: CN=Attribute-Schema,${SCHEMADN} # # ms-Exch-Oma-Admin-Wireless-Enable # dn: CN=ms-Exch-Oma-Admin-Wireless-Enable,${SCHEMADN} objectClass: top objectClass: attributeSchema cn: ms-Exch-Oma-Admin-Wireless-Enable distinguishedName: CN=ms-Exch-Oma-Admin-Wireless-Enable,${SCHEMADN} attributeID: 1.2.840.113556.1.6.20.1.124 attributeSyntax: 2.5.5.9 isSingleValued: TRUE showInAdvancedViewOnly: TRUE adminDisplayName: ms-Exch-Oma-Admin-Wireless-Enable adminDescription: ms-Exch-Oma-Admin-Wireless-Enable oMSyntax: 2 searchFlags: 0 lDAPDisplayName: msExchOmaAdminWirelessEnable name: ms-Exch-Oma-Admin-Wireless-Enable schemaIDGUID: c1a7bfbe-116b-4737-8cd9-d29ef5b3690e attributeSecurityGUID: e48d0154-bcf8-11d1-8702-00c04fb96050 isMemberOfPartialAttributeSet: TRUE objectCategory: CN=Attribute-Schema,${SCHEMADN} # # ms-Exch-Oma-Carrier-Address # dn: CN=ms-Exch-Oma-Carrier-Address,${SCHEMADN} objectClass: top objectClass: attributeSchema cn: ms-Exch-Oma-Carrier-Address distinguishedName: CN=ms-Exch-Oma-Carrier-Address,${SCHEMADN} attributeID: 1.2.840.113556.1.6.20.1.139 attributeSyntax: 2.5.5.12 isSingleValued: TRUE showInAdvancedViewOnly: TRUE adminDisplayName: ms-Exch-Oma-Carrier-Address adminDescription: ms-Exch-Oma-Carrier-Address oMSyntax: 64 searchFlags: 0 lDAPDisplayName: msExchOmaCarrierAddress name: ms-Exch-Oma-Carrier-Address schemaIDGUID: abe858b8-3daf-407e-b1a6-3a323ed3334b isMemberOfPartialAttributeSet: FALSE objectCategory: CN=Attribute-Schema,${SCHEMADN} # # ms-Exch-Oma-Carrier-Type # dn: CN=ms-Exch-Oma-Carrier-Type,${SCHEMADN} objectClass: top objectClass: attributeSchema cn: ms-Exch-Oma-Carrier-Type distinguishedName: CN=ms-Exch-Oma-Carrier-Type,${SCHEMADN} attributeID: 1.2.840.113556.1.6.20.1.145 attributeSyntax: 2.5.5.12 isSingleValued: TRUE showInAdvancedViewOnly: TRUE adminDisplayName: ms-Exch-Oma-Carrier-Type adminDescription: ms-Exch-Oma-Carrier-Type oMSyntax: 64 searchFlags: 0 lDAPDisplayName: msExchOmaCarrierType name: ms-Exch-Oma-Carrier-Type schemaIDGUID: 1fb324ad-2da3-4548-8f5a-f34457f8af4a isMemberOfPartialAttributeSet: FALSE objectCategory: CN=Attribute-Schema,${SCHEMADN} # # ms-Exch-Oma-Carrier-Url # dn: CN=ms-Exch-Oma-Carrier-Url,${SCHEMADN} objectClass: top objectClass: attributeSchema cn: ms-Exch-Oma-Carrier-Url distinguishedName: CN=ms-Exch-Oma-Carrier-Url,${SCHEMADN} attributeID: 1.2.840.113556.1.6.20.1.146 attributeSyntax: 2.5.5.12 isSingleValued: TRUE showInAdvancedViewOnly: TRUE adminDisplayName: ms-Exch-Oma-Carrier-Url adminDescription: ms-Exch-Oma-Carrier-Url oMSyntax: 64 searchFlags: 0 lDAPDisplayName: msExchOmaCarrierUrl name: ms-Exch-Oma-Carrier-Url schemaIDGUID: aca0878d-89f1-45f5-a48f-680b7e550573 isMemberOfPartialAttributeSet: FALSE objectCategory: CN=Attribute-Schema,${SCHEMADN} # # ms-Exch-Oma-Configuration # dn: CN=ms-Exch-Oma-Configuration,${SCHEMADN} objectClass: top objectClass: attributeSchema cn: ms-Exch-Oma-Configuration distinguishedName: CN=ms-Exch-Oma-Configuration,${SCHEMADN} attributeID: 1.2.840.113556.1.6.20.1.137 attributeSyntax: 2.5.5.12 isSingleValued: TRUE showInAdvancedViewOnly: TRUE adminDisplayName: ms-Exch-Oma-Configuration adminDescription: ms-Exch-Oma-Configuration oMSyntax: 64 searchFlags: 0 lDAPDisplayName: msExchOmaConfiguration name: ms-Exch-Oma-Configuration schemaIDGUID: d7e12bc7-4288-4866-bc91-f0ee18965c15 isMemberOfPartialAttributeSet: FALSE objectCategory: CN=Attribute-Schema,${SCHEMADN} # # ms-Exch-Oma-Deliverer # dn: CN=ms-Exch-Oma-Deliverer,${SCHEMADN} objectClass: top objectClass: attributeSchema cn: ms-Exch-Oma-Deliverer distinguishedName: CN=ms-Exch-Oma-Deliverer,${SCHEMADN} attributeID: 1.2.840.113556.1.6.20.1.144 attributeSyntax: 2.5.5.12 isSingleValued: FALSE showInAdvancedViewOnly: TRUE adminDisplayName: ms-Exch-Oma-Deliverer adminDescription: ms-Exch-Oma-Deliverer oMSyntax: 64 searchFlags: 0 lDAPDisplayName: msExchOmaDeliverer name: ms-Exch-Oma-Deliverer schemaIDGUID: a231009f-9df2-403d-9fbd-99809049722d isMemberOfPartialAttributeSet: FALSE objectCategory: CN=Attribute-Schema,${SCHEMADN} # # ms-Exch-Oma-Delivery-Provider-DN # dn: CN=ms-Exch-Oma-Delivery-Provider-DN,${SCHEMADN} objectClass: top objectClass: attributeSchema cn: ms-Exch-Oma-Delivery-Provider-DN distinguishedName: CN=ms-Exch-Oma-Delivery-Provider-DN,${SCHEMADN} attributeID: 1.2.840.113556.1.6.20.1.138 attributeSyntax: 2.5.5.1 isSingleValued: TRUE showInAdvancedViewOnly: TRUE adminDisplayName: ms-Exch-Oma-Delivery-Provider-DN oMObjectClass:: KwwCh3McAIVK adminDescription: ms-Exch-Oma-Delivery-Provider-DN oMSyntax: 127 searchFlags: 0 lDAPDisplayName: msExchOmaDeliveryProviderDN name: ms-Exch-Oma-Delivery-Provider-DN schemaIDGUID: 1f0e1a69-d62c-4105-991d-acaff4b07d71 isMemberOfPartialAttributeSet: FALSE objectCategory: CN=Attribute-Schema,${SCHEMADN} # # ms-Exch-Oma-Device-Capability-DN # dn: CN=ms-Exch-Oma-Device-Capability-DN,${SCHEMADN} objectClass: top objectClass: attributeSchema cn: ms-Exch-Oma-Device-Capability-DN distinguishedName: CN=ms-Exch-Oma-Device-Capability-DN,${SCHEMADN} attributeID: 1.2.840.113556.1.6.20.1.133 attributeSyntax: 2.5.5.1 isSingleValued: FALSE showInAdvancedViewOnly: TRUE adminDisplayName: ms-Exch-Oma-Device-Capability-DN oMObjectClass:: KwwCh3McAIVK adminDescription: ms-Exch-Oma-Device-Capability-DN oMSyntax: 127 searchFlags: 0 lDAPDisplayName: msExchOmaDeviceCapabilityDN name: ms-Exch-Oma-Device-Capability-DN schemaIDGUID: 0510bdc4-9b19-4d67-93a1-8dda04c15568 isMemberOfPartialAttributeSet: FALSE objectCategory: CN=Attribute-Schema,${SCHEMADN} # # ms-Exch-Oma-Extended-Properties # dn: CN=ms-Exch-Oma-Extended-Properties,${SCHEMADN} objectClass: top objectClass: attributeSchema cn: ms-Exch-Oma-Extended-Properties distinguishedName: CN=ms-Exch-Oma-Extended-Properties,${SCHEMADN} attributeID: 1.2.840.113556.1.6.20.1.143 attributeSyntax: 2.5.5.12 isSingleValued: FALSE showInAdvancedViewOnly: TRUE adminDisplayName: ms-Exch-Oma-Extended-Properties adminDescription: ms-Exch-Oma-Extended-Properties oMSyntax: 64 searchFlags: 0 lDAPDisplayName: msExchOmaExtendedProperties name: ms-Exch-Oma-Extended-Properties schemaIDGUID: 9ebe537c-f882-473d-980b-ce52202a75d8 isMemberOfPartialAttributeSet: FALSE objectCategory: CN=Attribute-Schema,${SCHEMADN} # # ms-Exch-Oma-Formatter # dn: CN=ms-Exch-Oma-Formatter,${SCHEMADN} objectClass: top objectClass: attributeSchema cn: ms-Exch-Oma-Formatter distinguishedName: CN=ms-Exch-Oma-Formatter,${SCHEMADN} attributeID: 1.2.840.113556.1.6.20.1.135 attributeSyntax: 2.5.5.12 isSingleValued: FALSE showInAdvancedViewOnly: TRUE adminDisplayName: ms-Exch-Oma-Formatter adminDescription: ms-Exch-Oma-Formatter oMSyntax: 64 searchFlags: 0 lDAPDisplayName: msExchOmaFormatter name: ms-Exch-Oma-Formatter schemaIDGUID: e827cd6a-b63c-4d44-961a-781a67949a36 isMemberOfPartialAttributeSet: FALSE objectCategory: CN=Attribute-Schema,${SCHEMADN} # # ms-Exch-Oma-Translator # dn: CN=ms-Exch-Oma-Translator,${SCHEMADN} objectClass: top objectClass: attributeSchema cn: ms-Exch-Oma-Translator distinguishedName: CN=ms-Exch-Oma-Translator,${SCHEMADN} attributeID: 1.2.840.113556.1.6.20.1.136 attributeSyntax: 2.5.5.12 isSingleValued: FALSE showInAdvancedViewOnly: TRUE adminDisplayName: ms-Exch-Oma-Translator adminDescription: ms-Exch-Oma-Translator oMSyntax: 64 searchFlags: 0 lDAPDisplayName: msExchOmaTranslator name: ms-Exch-Oma-Translator schemaIDGUID: d0f2588a-701e-4649-9379-062c62b93ef6 isMemberOfPartialAttributeSet: FALSE objectCategory: CN=Attribute-Schema,${SCHEMADN} # # ms-Exch-Oma-Validater # dn: CN=ms-Exch-Oma-Validater,${SCHEMADN} objectClass: top objectClass: attributeSchema cn: ms-Exch-Oma-Validater distinguishedName: CN=ms-Exch-Oma-Validater,${SCHEMADN} attributeID: 1.2.840.113556.1.6.20.1.134 attributeSyntax: 2.5.5.12 isSingleValued: FALSE showInAdvancedViewOnly: TRUE adminDisplayName: ms-Exch-Oma-Validater adminDescription: ms-Exch-Oma-Validater oMSyntax: 64 searchFlags: 0 lDAPDisplayName: msExchOmaValidater name: ms-Exch-Oma-Validater schemaIDGUID: a87d0c40-cbbd-4da1-ba2e-704832fca5b1 isMemberOfPartialAttributeSet: FALSE objectCategory: CN=Attribute-Schema,${SCHEMADN} # # ms-Exch-OOF-Reply-To-Originator # Governs whether or not Out-Of-Office notifications should be sent to # a sender of a message to this DL. # dn: CN=ms-Exch-OOF-Reply-To-Originator,${SCHEMADN} objectClass: top objectClass: attributeSchema cn: ms-Exch-OOF-Reply-To-Originator distinguishedName: CN=ms-Exch-OOF-Reply-To-Originator,${SCHEMADN} attributeID: 1.2.840.113556.1.2.438 attributeSyntax: 2.5.5.8 isSingleValued: TRUE mAPIID: 33023 showInAdvancedViewOnly: TRUE adminDisplayName: ms-Exch-OOF-Reply-To-Originator adminDescription: ms-Exch-OOF-Reply-To-Originator oMSyntax: 1 searchFlags: 0 lDAPDisplayName: oOFReplyToOriginator name: ms-Exch-OOF-Reply-To-Originator schemaIDGUID: a8df7440-c5ea-11d1-bbcb-0080c76670c0 attributeSecurityGUID: e48d0154-bcf8-11d1-8702-00c04fb96050 isMemberOfPartialAttributeSet: TRUE objectCategory: CN=Attribute-Schema,${SCHEMADN} # # ms-Exch-Open-Retry-Interval # dn: CN=ms-Exch-Open-Retry-Interval,${SCHEMADN} objectClass: top objectClass: attributeSchema cn: ms-Exch-Open-Retry-Interval distinguishedName: CN=ms-Exch-Open-Retry-Interval,${SCHEMADN} attributeID: 1.2.840.113556.1.2.143 attributeSyntax: 2.5.5.9 isSingleValued: TRUE mAPIID: 33024 showInAdvancedViewOnly: TRUE adminDisplayName: ms-Exch-Open-Retry-Interval adminDescription: ms-Exch-Open-Retry-Interval oMSyntax: 2 searchFlags: 0 lDAPDisplayName: openRetryInterval name: ms-Exch-Open-Retry-Interval schemaIDGUID: a8df7441-c5ea-11d1-bbcb-0080c76670c0 isMemberOfPartialAttributeSet: FALSE objectCategory: CN=Attribute-Schema,${SCHEMADN} # # ms-Exch-Originating-Forest # dn: CN=ms-Exch-Originating-Forest,${SCHEMADN} objectClass: top objectClass: attributeSchema cn: ms-Exch-Originating-Forest distinguishedName: CN=ms-Exch-Originating-Forest,${SCHEMADN} attributeID: 1.2.840.113556.1.4.7000.102.50300 attributeSyntax: 2.5.5.12 isSingleValued: FALSE showInAdvancedViewOnly: TRUE adminDisplayName: ms-Exch-Originating-Forest adminDescription: ms-Exch-Originating-Forest oMSyntax: 64 searchFlags: 0 lDAPDisplayName: msExchOriginatingForest name: ms-Exch-Originating-Forest schemaIDGUID: 16671de6-9753-47bf-9a12-be31abe0af08 attributeSecurityGUID: e48d0154-bcf8-11d1-8702-00c04fb96050 isMemberOfPartialAttributeSet: TRUE objectCategory: CN=Attribute-Schema,${SCHEMADN} # # ms-Exch-Orig-MDB # dn: CN=ms-Exch-Orig-MDB,${SCHEMADN} objectClass: top objectClass: attributeSchema cn: ms-Exch-Orig-MDB distinguishedName: CN=ms-Exch-Orig-MDB,${SCHEMADN} attributeID: 1.2.840.113556.1.4.7000.102.11093 attributeSyntax: 2.5.5.1 isSingleValued: TRUE showInAdvancedViewOnly: TRUE adminDisplayName: ms-Exch-Orig-MDB oMObjectClass:: KwwCh3McAIVK adminDescription: ms-Exch-Orig-MDB oMSyntax: 127 searchFlags: 0 lDAPDisplayName: msExchOrigMDB name: ms-Exch-Orig-MDB schemaIDGUID: f7b66927-7726-4e66-9ea8-efdf48d65201 isMemberOfPartialAttributeSet: FALSE objectCategory: CN=Attribute-Schema,${SCHEMADN} # # ms-Exch-Other-Authentication-Flags # dn: CN=ms-Exch-Other-Authentication-Flags,${SCHEMADN} objectClass: top objectClass: attributeSchema cn: ms-Exch-Other-Authentication-Flags distinguishedName: CN=ms-Exch-Other-Authentication-Flags,${SCHEMADN} attributeID: 1.2.840.113556.1.4.7000.102.2017 attributeSyntax: 2.5.5.9 isSingleValued: TRUE showInAdvancedViewOnly: TRUE adminDisplayName: ms-Exch-Other-Authentication-Flags adminDescription: ms-Exch-Other-Authentication-Flags oMSyntax: 2 searchFlags: 0 lDAPDisplayName: msExchOtherAuthenticationFlags name: ms-Exch-Other-Authentication-Flags schemaIDGUID: b4c7fe67-b523-4d2e-b56e-ac57b686c7e3 isMemberOfPartialAttributeSet: FALSE objectCategory: CN=Attribute-Schema,${SCHEMADN} # # ms-Exch-Outbound-Sites # dn: CN=ms-Exch-Outbound-Sites,${SCHEMADN} objectClass: top objectClass: attributeSchema cn: ms-Exch-Outbound-Sites distinguishedName: CN=ms-Exch-Outbound-Sites,${SCHEMADN} attributeID: 1.2.840.113556.1.2.0 attributeSyntax: 2.5.5.1 isSingleValued: FALSE mAPIID: 33029 showInAdvancedViewOnly: TRUE adminDisplayName: ms-Exch-Outbound-Sites oMObjectClass:: KwwCh3McAIVK adminDescription: ms-Exch-Outbound-Sites oMSyntax: 127 searchFlags: 0 lDAPDisplayName: outboundSites name: ms-Exch-Outbound-Sites schemaIDGUID: a8df7445-c5ea-11d1-bbcb-0080c76670c0 isMemberOfPartialAttributeSet: FALSE objectCategory: CN=Attribute-Schema,${SCHEMADN} # # ms-Exch-Outgoing-Msg-Size-Limit # dn: CN=ms-Exch-Outgoing-Msg-Size-Limit,${SCHEMADN} objectClass: top objectClass: attributeSchema cn: ms-Exch-Outgoing-Msg-Size-Limit distinguishedName: CN=ms-Exch-Outgoing-Msg-Size-Limit,${SCHEMADN} attributeID: 1.2.840.113556.1.2.490 attributeSyntax: 2.5.5.9 isSingleValued: TRUE mAPIID: 33167 showInAdvancedViewOnly: TRUE adminDisplayName: ms-Exch-Outgoing-Msg-Size-Limit adminDescription: ms-Exch-Outgoing-Msg-Size-Limit oMSyntax: 2 searchFlags: 0 lDAPDisplayName: outgoingMsgSizeLimit name: ms-Exch-Outgoing-Msg-Size-Limit schemaIDGUID: a8df7446-c5ea-11d1-bbcb-0080c76670c0 isMemberOfPartialAttributeSet: FALSE objectCategory: CN=Attribute-Schema,${SCHEMADN} # # ms-Exch-Overall-Age-Limit # Overall age limit for messages in public message databases # (MDBs). This is a store-wide setting. # dn: CN=ms-Exch-Overall-Age-Limit,${SCHEMADN} objectClass: top objectClass: attributeSchema cn: ms-Exch-Overall-Age-Limit distinguishedName: CN=ms-Exch-Overall-Age-Limit,${SCHEMADN} attributeID: 1.2.840.113556.1.4.7000.102.11055 attributeSyntax: 2.5.5.9 isSingleValued: TRUE showInAdvancedViewOnly: TRUE adminDisplayName: ms-Exch-Overall-Age-Limit adminDescription: ms-Exch-Overall-Age-Limit oMSyntax: 2 searchFlags: 0 lDAPDisplayName: msExchOverallAgeLimit name: ms-Exch-Overall-Age-Limit schemaIDGUID: 9162c4ba-b09e-11d2-aa06-00c04f8eedd8 isMemberOfPartialAttributeSet: FALSE objectCategory: CN=Attribute-Schema,${SCHEMADN} # # ms-Exch-OWA-Server # dn: CN=ms-Exch-OWA-Server,${SCHEMADN} objectClass: top objectClass: attributeSchema cn: ms-Exch-OWA-Server distinguishedName: CN=ms-Exch-OWA-Server,${SCHEMADN} attributeID: 1.2.840.113556.1.2.608 attributeSyntax: 2.5.5.12 isSingleValued: TRUE rangeLower: 0 rangeUpper: 128 mAPIID: 35942 showInAdvancedViewOnly: TRUE adminDisplayName: ms-Exch-OWA-Server adminDescription: ms-Exch-OWA-Server oMSyntax: 64 searchFlags: 0 lDAPDisplayName: oWAServer name: ms-Exch-OWA-Server schemaIDGUID: a8df7447-c5ea-11d1-bbcb-0080c76670c0 isMemberOfPartialAttributeSet: FALSE objectCategory: CN=Attribute-Schema,${SCHEMADN} # # ms-Exch-Owning-Org # dn: CN=ms-Exch-Owning-Org,${SCHEMADN} objectClass: top objectClass: attributeSchema cn: ms-Exch-Owning-Org distinguishedName: CN=ms-Exch-Owning-Org,${SCHEMADN} attributeID: 1.2.840.113556.1.4.7000.102.11030 attributeSyntax: 2.5.5.1 isSingleValued: TRUE showInAdvancedViewOnly: TRUE adminDisplayName: ms-Exch-Owning-Org oMObjectClass:: KwwCh3McAIVK adminDescription: ms-Exch-Owning-Org oMSyntax: 127 searchFlags: 0 lDAPDisplayName: msExchOwningOrg name: ms-Exch-Owning-Org schemaIDGUID: 16f86ba4-b098-11d2-aa06-00c04f8eedd8 isMemberOfPartialAttributeSet: FALSE objectCategory: CN=Attribute-Schema,${SCHEMADN} # # ms-Exch-Owning-PF-Tree # The GUID of the public folder tree that is replicated to this store. # dn: CN=ms-Exch-Owning-PF-Tree,${SCHEMADN} objectClass: top objectClass: attributeSchema cn: ms-Exch-Owning-PF-Tree distinguishedName: CN=ms-Exch-Owning-PF-Tree,${SCHEMADN} attributeID: 1.2.840.113556.1.4.7000.102.11031 attributeSyntax: 2.5.5.1 isSingleValued: TRUE linkID: 1008 showInAdvancedViewOnly: TRUE adminDisplayName: ms-Exch-Owning-PF-Tree oMObjectClass:: KwwCh3McAIVK adminDescription: ms-Exch-Owning-PF-Tree oMSyntax: 127 searchFlags: 0 lDAPDisplayName: msExchOwningPFTree name: ms-Exch-Owning-PF-Tree schemaIDGUID: 172a7d06-b098-11d2-aa06-00c04f8eedd8 isMemberOfPartialAttributeSet: FALSE objectCategory: CN=Attribute-Schema,${SCHEMADN} # # ms-Exch-Owning-PF-Tree-BL # A read-only multivalued GUID list of public MDB instances of this # TLH. # dn: CN=ms-Exch-Owning-PF-Tree-BL,${SCHEMADN} objectClass: top objectClass: attributeSchema cn: ms-Exch-Owning-PF-Tree-BL distinguishedName: CN=ms-Exch-Owning-PF-Tree-BL,${SCHEMADN} attributeID: 1.2.840.113556.1.4.7000.102.11032 attributeSyntax: 2.5.5.1 isSingleValued: FALSE linkID: 1009 showInAdvancedViewOnly: TRUE adminDisplayName: ms-Exch-Owning-PF-Tree-BL oMObjectClass:: KwwCh3McAIVK adminDescription: ms-Exch-Owning-PF-Tree-BL oMSyntax: 127 searchFlags: 0 lDAPDisplayName: msExchOwningPFTreeBL name: ms-Exch-Owning-PF-Tree-BL schemaIDGUID: 175a2c0e-b098-11d2-aa06-00c04f8eedd8 systemFlags: 1 isMemberOfPartialAttributeSet: FALSE objectCategory: CN=Attribute-Schema,${SCHEMADN} # # ms-Exch-Owning-Server # The DN of the Directory Service (DS) object for the server # containing this MDB. # dn: CN=ms-Exch-Owning-Server,${SCHEMADN} objectClass: top objectClass: attributeSchema cn: ms-Exch-Owning-Server distinguishedName: CN=ms-Exch-Owning-Server,${SCHEMADN} attributeID: 1.2.840.113556.1.4.7000.102.11004 attributeSyntax: 2.5.5.1 isSingleValued: TRUE showInAdvancedViewOnly: TRUE adminDisplayName: ms-Exch-Owning-Server oMObjectClass:: KwwCh3McAIVK adminDescription: ms-Exch-Owning-Server oMSyntax: 127 searchFlags: 0 lDAPDisplayName: msExchOwningServer name: ms-Exch-Owning-Server schemaIDGUID: 17910224-b098-11d2-aa06-00c04f8eedd8 isMemberOfPartialAttributeSet: FALSE objectCategory: CN=Attribute-Schema,${SCHEMADN} # # ms-Exch-Partner-CP # dn: CN=ms-Exch-Partner-CP,${SCHEMADN} objectClass: top objectClass: attributeSchema cn: ms-Exch-Partner-CP distinguishedName: CN=ms-Exch-Partner-CP,${SCHEMADN} attributeID: 1.2.840.113556.1.4.7000.102.1007 attributeSyntax: 2.5.5.9 isSingleValued: TRUE showInAdvancedViewOnly: TRUE adminDisplayName: ms-Exch-Partner-CP adminDescription: ms-Exch-Partner-CP oMSyntax: 2 searchFlags: 0 lDAPDisplayName: msExchPartnerCP name: ms-Exch-Partner-CP schemaIDGUID: 8a0c07b2-b09e-11d2-aa06-00c04f8eedd8 isMemberOfPartialAttributeSet: FALSE objectCategory: CN=Attribute-Schema,${SCHEMADN} # # ms-Exch-Partner-Language # The language (code page) of the connected foreign post office or # domain. # dn: CN=ms-Exch-Partner-Language,${SCHEMADN} objectClass: top objectClass: attributeSchema cn: ms-Exch-Partner-Language distinguishedName: CN=ms-Exch-Partner-Language,${SCHEMADN} attributeID: 1.2.840.113556.1.4.7000.102.1006 attributeSyntax: 2.5.5.9 isSingleValued: TRUE showInAdvancedViewOnly: TRUE adminDisplayName: ms-Exch-Partner-Language adminDescription: ms-Exch-Partner-Language oMSyntax: 2 searchFlags: 0 lDAPDisplayName: msExchPartnerLanguage name: ms-Exch-Partner-Language schemaIDGUID: 17c7d83a-b098-11d2-aa06-00c04f8eedd8 isMemberOfPartialAttributeSet: FALSE objectCategory: CN=Attribute-Schema,${SCHEMADN} # # ms-Exch-Patch-MDB # dn: CN=ms-Exch-Patch-MDB,${SCHEMADN} objectClass: top objectClass: attributeSchema cn: ms-Exch-Patch-MDB distinguishedName: CN=ms-Exch-Patch-MDB,${SCHEMADN} attributeID: 1.2.840.113556.1.4.7000.102.11086 attributeSyntax: 2.5.5.8 isSingleValued: TRUE showInAdvancedViewOnly: TRUE adminDisplayName: ms-Exch-Patch-MDB adminDescription: ms-Exch-Patch-MDB oMSyntax: 1 searchFlags: 0 lDAPDisplayName: msExchPatchMDB name: ms-Exch-Patch-MDB schemaIDGUID: bbdf5f8c-02d5-45ff-bab7-464d5452ebf4 isMemberOfPartialAttributeSet: FALSE objectCategory: CN=Attribute-Schema,${SCHEMADN} # # ms-Exch-PF-Contacts # dn: CN=ms-Exch-PF-Contacts,${SCHEMADN} objectClass: top objectClass: attributeSchema cn: ms-Exch-PF-Contacts distinguishedName: CN=ms-Exch-PF-Contacts,${SCHEMADN} attributeID: 1.2.840.113556.1.2.75 attributeSyntax: 2.5.5.1 isSingleValued: FALSE mAPIID: 32824 showInAdvancedViewOnly: TRUE adminDisplayName: ms-Exch-PF-Contacts oMObjectClass:: KwwCh3McAIVK adminDescription: ms-Exch-PF-Contacts oMSyntax: 127 searchFlags: 0 lDAPDisplayName: pFContacts name: ms-Exch-PF-Contacts schemaIDGUID: f0f8ff98-1191-11d0-a060-00aa006c33ed isMemberOfPartialAttributeSet: TRUE objectCategory: CN=Attribute-Schema,${SCHEMADN} # # ms-Exch-Pf-Creation # dn: CN=ms-Exch-Pf-Creation,${SCHEMADN} objectClass: top objectClass: attributeSchema cn: ms-Exch-Pf-Creation distinguishedName: CN=ms-Exch-Pf-Creation,${SCHEMADN} attributeID: 1.2.840.113556.1.4.7000.102.100 attributeSyntax: 2.5.5.12 isSingleValued: FALSE showInAdvancedViewOnly: TRUE adminDisplayName: ms-Exch-Pf-Creation adminDescription: ms-Exch-Pf-Creation oMSyntax: 64 searchFlags: 0 lDAPDisplayName: msExchPfCreation name: ms-Exch-Pf-Creation schemaIDGUID: ed1161ed-5d1e-4bb3-993f-11956d680ef6 isMemberOfPartialAttributeSet: FALSE objectCategory: CN=Attribute-Schema,${SCHEMADN} # # ms-Exch-PF-Default-Admin-ACL # On the TLH, this is the default set of rights for new Top Level # Folders. On the administrative group, this is the set of rights for # public folders that are homed on Exchange Server 5.5 that are # associated to this administrative group or site. # dn: CN=ms-Exch-PF-Default-Admin-ACL,${SCHEMADN} objectClass: top objectClass: attributeSchema cn: ms-Exch-PF-Default-Admin-ACL distinguishedName: CN=ms-Exch-PF-Default-Admin-ACL,${SCHEMADN} attributeID: 1.2.840.113556.1.4.7000.102.50035 attributeSyntax: 2.5.5.15 isSingleValued: TRUE showInAdvancedViewOnly: TRUE adminDisplayName: ms-Exch-PF-Default-Admin-ACL adminDescription: ms-Exch-PF-Default-Admin-ACL oMSyntax: 66 searchFlags: 0 lDAPDisplayName: msExchPFDefaultAdminACL name: ms-Exch-PF-Default-Admin-ACL schemaIDGUID: 3de926b2-22af-11d3-aa62-00c04f8eedd8 isMemberOfPartialAttributeSet: FALSE objectCategory: CN=Attribute-Schema,${SCHEMADN} # # ms-Exch-PF-DS-Container # The DN of the container into which message databases (MDBs) in this # domain will create folder objects. # dn: CN=ms-Exch-PF-DS-Container,${SCHEMADN} objectClass: top objectClass: attributeSchema cn: ms-Exch-PF-DS-Container distinguishedName: CN=ms-Exch-PF-DS-Container,${SCHEMADN} attributeID: 1.2.840.113556.1.4.7000.102.11034 attributeSyntax: 2.5.5.1 isSingleValued: TRUE showInAdvancedViewOnly: TRUE adminDisplayName: ms-Exch-PF-DS-Container oMObjectClass:: KwwCh3McAIVK adminDescription: ms-Exch-PF-DS-Container oMSyntax: 127 searchFlags: 0 lDAPDisplayName: msExchPFDSContainer name: ms-Exch-PF-DS-Container schemaIDGUID: 17feae50-b098-11d2-aa06-00c04f8eedd8 isMemberOfPartialAttributeSet: FALSE objectCategory: CN=Attribute-Schema,${SCHEMADN} # # ms-Exch-Pf-Root-Url # The URL to a user's public folder root. # dn: CN=ms-Exch-Pf-Root-Url,${SCHEMADN} objectClass: top objectClass: attributeSchema cn: ms-Exch-Pf-Root-Url distinguishedName: CN=ms-Exch-Pf-Root-Url,${SCHEMADN} attributeID: 1.2.840.113556.1.4.7000.102.50086 attributeSyntax: 2.5.5.12 isSingleValued: TRUE mAPIID: 35970 showInAdvancedViewOnly: TRUE adminDisplayName: ms-Exch-Pf-Root-Url adminDescription: ms-Exch-Pf-Root-Url oMSyntax: 64 searchFlags: 0 lDAPDisplayName: msExchPfRootUrl name: ms-Exch-Pf-Root-Url schemaIDGUID: 3f50d651-bc97-47b3-aadc-c836d7fec446 attributeSecurityGUID: e48d0154-bcf8-11d1-8702-00c04fb96050 isMemberOfPartialAttributeSet: TRUE objectCategory: CN=Attribute-Schema,${SCHEMADN} # # ms-Exch-PF-Tree-Type # dn: CN=ms-Exch-PF-Tree-Type,${SCHEMADN} objectClass: top objectClass: attributeSchema cn: ms-Exch-PF-Tree-Type distinguishedName: CN=ms-Exch-PF-Tree-Type,${SCHEMADN} attributeID: 1.2.840.113556.1.4.7000.102.11035 attributeSyntax: 2.5.5.9 isSingleValued: TRUE showInAdvancedViewOnly: TRUE adminDisplayName: ms-Exch-PF-Tree-Type adminDescription: ms-Exch-PF-Tree-Type oMSyntax: 2 searchFlags: 0 lDAPDisplayName: msExchPFTreeType name: ms-Exch-PF-Tree-Type schemaIDGUID: 1830bfb2-b098-11d2-aa06-00c04f8eedd8 attributeSecurityGUID: e48d0154-bcf8-11d1-8702-00c04fb96050 isMemberOfPartialAttributeSet: TRUE objectCategory: CN=Attribute-Schema,${SCHEMADN} # # ms-Exch-Policies-Excluded # dn: CN=ms-Exch-Policies-Excluded,${SCHEMADN} objectClass: top objectClass: attributeSchema cn: ms-Exch-Policies-Excluded distinguishedName: CN=ms-Exch-Policies-Excluded,${SCHEMADN} attributeID: 1.2.840.113556.1.4.7000.102.50051 attributeSyntax: 2.5.5.12 isSingleValued: FALSE showInAdvancedViewOnly: TRUE adminDisplayName: ms-Exch-Policies-Excluded adminDescription: ms-Exch-Policies-Excluded oMSyntax: 64 searchFlags: 0 lDAPDisplayName: msExchPoliciesExcluded name: ms-Exch-Policies-Excluded schemaIDGUID: 61c47258-454e-11d3-aa72-00c04f8eedd8 attributeSecurityGUID: e48d0154-bcf8-11d1-8702-00c04fb96050 isMemberOfPartialAttributeSet: FALSE objectCategory: CN=Attribute-Schema,${SCHEMADN} # # ms-Exch-Policies-Included # dn: CN=ms-Exch-Policies-Included,${SCHEMADN} objectClass: top objectClass: attributeSchema cn: ms-Exch-Policies-Included distinguishedName: CN=ms-Exch-Policies-Included,${SCHEMADN} attributeID: 1.2.840.113556.1.4.7000.102.50050 attributeSyntax: 2.5.5.12 isSingleValued: FALSE showInAdvancedViewOnly: TRUE adminDisplayName: ms-Exch-Policies-Included adminDescription: ms-Exch-Policies-Included oMSyntax: 64 searchFlags: 0 lDAPDisplayName: msExchPoliciesIncluded name: ms-Exch-Policies-Included schemaIDGUID: 61c47253-454e-11d3-aa72-00c04f8eedd8 attributeSecurityGUID: e48d0154-bcf8-11d1-8702-00c04fb96050 isMemberOfPartialAttributeSet: FALSE objectCategory: CN=Attribute-Schema,${SCHEMADN} # # ms-Exch-Policy-Default # dn: CN=ms-Exch-Policy-Default,${SCHEMADN} objectClass: top objectClass: attributeSchema cn: ms-Exch-Policy-Default distinguishedName: CN=ms-Exch-Policy-Default,${SCHEMADN} attributeID: 1.2.840.113556.1.4.7000.102.50007 attributeSyntax: 2.5.5.8 isSingleValued: TRUE showInAdvancedViewOnly: TRUE adminDisplayName: ms-Exch-Policy-Default adminDescription: ms-Exch-Policy-Default oMSyntax: 1 searchFlags: 0 lDAPDisplayName: msExchPolicyDefault name: ms-Exch-Policy-Default schemaIDGUID: 1865336e-b098-11d2-aa06-00c04f8eedd8 isMemberOfPartialAttributeSet: FALSE objectCategory: CN=Attribute-Schema,${SCHEMADN} # # ms-Exch-Policy-Enabled # Specifies whether or not policies should be applied to this recipient. # dn: CN=ms-Exch-Policy-Enabled,${SCHEMADN} objectClass: top objectClass: attributeSchema cn: ms-Exch-Policy-Enabled distinguishedName: CN=ms-Exch-Policy-Enabled,${SCHEMADN} attributeID: 1.2.840.113556.1.4.7000.102.50030 attributeSyntax: 2.5.5.8 isSingleValued: TRUE showInAdvancedViewOnly: TRUE adminDisplayName: ms-Exch-Policy-Enabled adminDescription: ms-Exch-Policy-Enabled oMSyntax: 1 searchFlags: 0 lDAPDisplayName: msExchPolicyEnabled name: ms-Exch-Policy-Enabled schemaIDGUID: e32977dc-1d31-11d3-aa5e-00c04f8eedd8 attributeSecurityGUID: e48d0154-bcf8-11d1-8702-00c04fb96050 isMemberOfPartialAttributeSet: FALSE objectCategory: CN=Attribute-Schema,${SCHEMADN} # # ms-Exch-Policy-Last-Applied-Time # The time/date that this policy was applied. # dn: CN=ms-Exch-Policy-Last-Applied-Time,${SCHEMADN} objectClass: top objectClass: attributeSchema cn: ms-Exch-Policy-Last-Applied-Time distinguishedName: CN=ms-Exch-Policy-Last-Applied-Time,${SCHEMADN} attributeID: 1.2.840.113556.1.4.7000.102.50023 attributeSyntax: 2.5.5.11 isSingleValued: TRUE showInAdvancedViewOnly: TRUE adminDisplayName: ms-Exch-Policy-Last-Applied-Time adminDescription: ms-Exch-Policy-Last-Applied-Time oMSyntax: 24 searchFlags: 0 lDAPDisplayName: msExchPolicyLastAppliedTime name: ms-Exch-Policy-Last-Applied-Time schemaIDGUID: 92407f6c-b09e-11d2-aa06-00c04f8eedd8 isMemberOfPartialAttributeSet: FALSE objectCategory: CN=Attribute-Schema,${SCHEMADN} # # ms-Exch-Policy-List # The list of policies a leaf object uses. # dn: CN=ms-Exch-Policy-List,${SCHEMADN} objectClass: top objectClass: attributeSchema cn: ms-Exch-Policy-List distinguishedName: CN=ms-Exch-Policy-List,${SCHEMADN} attributeID: 1.2.840.113556.1.4.7000.102.50004 attributeSyntax: 2.5.5.1 isSingleValued: FALSE linkID: 1012 showInAdvancedViewOnly: TRUE adminDisplayName: ms-Exch-Policy-List oMObjectClass:: KwwCh3McAIVK adminDescription: ms-Exch-Policy-List oMSyntax: 127 searchFlags: 0 lDAPDisplayName: msExchPolicyList name: ms-Exch-Policy-List schemaIDGUID: 18cbb88c-b098-11d2-aa06-00c04f8eedd8 isMemberOfPartialAttributeSet: FALSE objectCategory: CN=Attribute-Schema,${SCHEMADN} # # ms-Exch-Policy-List-BL # A backlink to objects that use this policy. # dn: CN=ms-Exch-Policy-List-BL,${SCHEMADN} objectClass: top objectClass: attributeSchema cn: ms-Exch-Policy-List-BL distinguishedName: CN=ms-Exch-Policy-List-BL,${SCHEMADN} attributeID: 1.2.840.113556.1.4.7000.102.50005 attributeSyntax: 2.5.5.1 isSingleValued: FALSE linkID: 1013 showInAdvancedViewOnly: TRUE adminDisplayName: ms-Exch-Policy-List-BL oMObjectClass:: KwwCh3McAIVK adminDescription: ms-Exch-Policy-List-BL oMSyntax: 127 searchFlags: 0 lDAPDisplayName: msExchPolicyListBL name: ms-Exch-Policy-List-BL schemaIDGUID: 19028ea2-b098-11d2-aa06-00c04f8eedd8 systemFlags: 1 isMemberOfPartialAttributeSet: FALSE objectCategory: CN=Attribute-Schema,${SCHEMADN} # # ms-Exch-Policy-LockDown # If this is set, this policy cannot be removed from the object this # policy applies to. # dn: CN=ms-Exch-Policy-LockDown,${SCHEMADN} objectClass: top objectClass: attributeSchema cn: ms-Exch-Policy-LockDown distinguishedName: CN=ms-Exch-Policy-LockDown,${SCHEMADN} attributeID: 1.2.840.113556.1.4.7000.102.50008 attributeSyntax: 2.5.5.8 isSingleValued: TRUE showInAdvancedViewOnly: TRUE adminDisplayName: ms-Exch-Policy-LockDown adminDescription: ms-Exch-Policy-LockDown oMSyntax: 1 searchFlags: 0 lDAPDisplayName: msExchPolicyLockDown name: ms-Exch-Policy-LockDown schemaIDGUID: 1934a004-b098-11d2-aa06-00c04f8eedd8 isMemberOfPartialAttributeSet: FALSE objectCategory: CN=Attribute-Schema,${SCHEMADN} # # ms-Exch-Policy-Option-List # The list that defines the set of property pages that are exposed on # this policy. Every property page (that will be policied) will be # assigned a GUID to uniquely identify it in this list. # dn: CN=ms-Exch-Policy-Option-List,${SCHEMADN} objectClass: top objectClass: attributeSchema cn: ms-Exch-Policy-Option-List distinguishedName: CN=ms-Exch-Policy-Option-List,${SCHEMADN} attributeID: 1.2.840.113556.1.4.7000.102.50006 attributeSyntax: 2.5.5.10 isSingleValued: FALSE showInAdvancedViewOnly: TRUE adminDisplayName: ms-Exch-Policy-Option-List adminDescription: ms-Exch-Policy-Option-List oMSyntax: 4 searchFlags: 0 lDAPDisplayName: msExchPolicyOptionList name: ms-Exch-Policy-Option-List schemaIDGUID: 1966b166-b098-11d2-aa06-00c04f8eedd8 attributeSecurityGUID: e48d0154-bcf8-11d1-8702-00c04fb96050 isMemberOfPartialAttributeSet: FALSE objectCategory: CN=Attribute-Schema,${SCHEMADN} # # ms-Exch-Policy-Order # The order in which policies will be evaluated. # dn: CN=ms-Exch-Policy-Order,${SCHEMADN} objectClass: top objectClass: attributeSchema cn: ms-Exch-Policy-Order distinguishedName: CN=ms-Exch-Policy-Order,${SCHEMADN} attributeID: 1.2.840.113556.1.4.7000.102.50027 attributeSyntax: 2.5.5.9 isSingleValued: TRUE showInAdvancedViewOnly: TRUE adminDisplayName: ms-Exch-Policy-Order adminDescription: ms-Exch-Policy-Order oMSyntax: 2 searchFlags: 0 lDAPDisplayName: msExchPolicyOrder name: ms-Exch-Policy-Order schemaIDGUID: e32977b1-1d31-11d3-aa5e-00c04f8eedd8 isMemberOfPartialAttributeSet: FALSE objectCategory: CN=Attribute-Schema,${SCHEMADN} # # ms-Exch-Policy-Roots # The list of distinguished names (DNs) of containers where policy # objects reside that the AL service will process. # dn: CN=ms-Exch-Policy-Roots,${SCHEMADN} objectClass: top objectClass: attributeSchema cn: ms-Exch-Policy-Roots distinguishedName: CN=ms-Exch-Policy-Roots,${SCHEMADN} attributeID: 1.2.840.113556.1.4.7000.102.50028 attributeSyntax: 2.5.5.1 isSingleValued: FALSE showInAdvancedViewOnly: TRUE adminDisplayName: ms-Exch-Policy-Roots oMObjectClass:: KwwCh3McAIVK adminDescription: ms-Exch-Policy-Roots oMSyntax: 127 searchFlags: 0 lDAPDisplayName: msExchPolicyRoots name: ms-Exch-Policy-Roots schemaIDGUID: e36ef110-1d40-11d3-aa5e-00c04f8eedd8 isMemberOfPartialAttributeSet: FALSE objectCategory: CN=Attribute-Schema,${SCHEMADN} # # ms-Exch-Poll-Interval # The polling interval between scheduled runs if "Always" is selected. # dn: CN=ms-Exch-Poll-Interval,${SCHEMADN} objectClass: top objectClass: attributeSchema cn: ms-Exch-Poll-Interval distinguishedName: CN=ms-Exch-Poll-Interval,${SCHEMADN} attributeID: 1.2.840.113556.1.4.7000.102.58 attributeSyntax: 2.5.5.9 isSingleValued: TRUE showInAdvancedViewOnly: TRUE adminDisplayName: ms-Exch-Poll-Interval adminDescription: ms-Exch-Poll-Interval oMSyntax: 2 searchFlags: 0 lDAPDisplayName: msExchPollInterval name: ms-Exch-Poll-Interval schemaIDGUID: 1998c2c8-b098-11d2-aa06-00c04f8eedd8 isMemberOfPartialAttributeSet: FALSE objectCategory: CN=Attribute-Schema,${SCHEMADN} # # ms-Exch-POP-Character-Set # dn: CN=ms-Exch-POP-Character-Set,${SCHEMADN} objectClass: top objectClass: attributeSchema cn: ms-Exch-POP-Character-Set distinguishedName: CN=ms-Exch-POP-Character-Set,${SCHEMADN} attributeID: 1.2.840.113556.1.2.468 attributeSyntax: 2.5.5.12 isSingleValued: TRUE rangeLower: 1 rangeUpper: 64 mAPIID: 33145 showInAdvancedViewOnly: TRUE adminDisplayName: ms-Exch-POP-Character-Set adminDescription: ms-Exch-POP-Character-Set oMSyntax: 64 searchFlags: 0 lDAPDisplayName: pOPCharacterSet name: ms-Exch-POP-Character-Set schemaIDGUID: bf9679f8-0de6-11d0-a285-00aa003049e2 attributeSecurityGUID: e48d0154-bcf8-11d1-8702-00c04fb96050 isMemberOfPartialAttributeSet: FALSE objectCategory: CN=Attribute-Schema,${SCHEMADN} # # ms-Exch-POP-Content-Format # dn: CN=ms-Exch-POP-Content-Format,${SCHEMADN} objectClass: top objectClass: attributeSchema cn: ms-Exch-POP-Content-Format distinguishedName: CN=ms-Exch-POP-Content-Format,${SCHEMADN} attributeID: 1.2.840.113556.1.2.466 attributeSyntax: 2.5.5.12 isSingleValued: TRUE rangeLower: 1 rangeUpper: 64 mAPIID: 33143 showInAdvancedViewOnly: TRUE adminDisplayName: ms-Exch-POP-Content-Format adminDescription: ms-Exch-POP-Content-Format oMSyntax: 64 searchFlags: 0 lDAPDisplayName: pOPContentFormat name: ms-Exch-POP-Content-Format schemaIDGUID: bf9679f9-0de6-11d0-a285-00aa003049e2 attributeSecurityGUID: e48d0154-bcf8-11d1-8702-00c04fb96050 isMemberOfPartialAttributeSet: FALSE objectCategory: CN=Attribute-Schema,${SCHEMADN} # # ms-Exch-Port-Number # dn: CN=ms-Exch-Port-Number,${SCHEMADN} objectClass: top objectClass: attributeSchema cn: ms-Exch-Port-Number distinguishedName: CN=ms-Exch-Port-Number,${SCHEMADN} attributeID: 1.2.840.113556.1.2.527 attributeSyntax: 2.5.5.9 isSingleValued: TRUE rangeLower: 0 rangeUpper: 65535 mAPIID: 33205 showInAdvancedViewOnly: TRUE adminDisplayName: ms-Exch-Port-Number adminDescription: ms-Exch-Port-Number oMSyntax: 2 searchFlags: 0 lDAPDisplayName: portNumber name: ms-Exch-Port-Number schemaIDGUID: a8df744a-c5ea-11d1-bbcb-0080c76670c0 isMemberOfPartialAttributeSet: FALSE objectCategory: CN=Attribute-Schema,${SCHEMADN} # # ms-Exch-Preferred-Backfill-Source # dn: CN=ms-Exch-Preferred-Backfill-Source,${SCHEMADN} objectClass: top objectClass: attributeSchema cn: ms-Exch-Preferred-Backfill-Source distinguishedName: CN=ms-Exch-Preferred-Backfill-Source,${SCHEMADN} attributeID: 1.2.840.113556.1.4.7000.102.11094 attributeSyntax: 2.5.5.1 isSingleValued: TRUE showInAdvancedViewOnly: TRUE adminDisplayName: ms-Exch-Preferred-Backfill-Source oMObjectClass:: KwwCh3McAIVK adminDescription: ms-Exch-Preferred-Backfill-Source oMSyntax: 127 searchFlags: 0 lDAPDisplayName: msExchPreferredBackfillSource name: ms-Exch-Preferred-Backfill-Source schemaIDGUID: 5e03e654-d85d-4908-83a1-6141048c5c62 isMemberOfPartialAttributeSet: FALSE objectCategory: CN=Attribute-Schema,${SCHEMADN} # # ms-Exch-Preserve-Internet-Content # dn: CN=ms-Exch-Preserve-Internet-Content,${SCHEMADN} objectClass: top objectClass: attributeSchema cn: ms-Exch-Preserve-Internet-Content distinguishedName: CN=ms-Exch-Preserve-Internet-Content,${SCHEMADN} attributeID: 1.2.840.113556.1.2.556 attributeSyntax: 2.5.5.8 isSingleValued: TRUE mAPIID: 35874 showInAdvancedViewOnly: TRUE adminDisplayName: ms-Exch-Preserve-Internet-Content adminDescription: ms-Exch-Preserve-Internet-Content oMSyntax: 1 searchFlags: 0 lDAPDisplayName: preserveInternetContent name: ms-Exch-Preserve-Internet-Content schemaIDGUID: a8df744c-c5ea-11d1-bbcb-0080c76670c0 isMemberOfPartialAttributeSet: FALSE objectCategory: CN=Attribute-Schema,${SCHEMADN} # # ms-Exch-Previous-Account-Sid # dn: CN=ms-Exch-Previous-Account-Sid,${SCHEMADN} objectClass: top objectClass: attributeSchema cn: ms-Exch-Previous-Account-Sid distinguishedName: CN=ms-Exch-Previous-Account-Sid,${SCHEMADN} attributeID: 1.2.840.113556.1.4.7000.102.93 attributeSyntax: 2.5.5.17 isSingleValued: TRUE rangeLower: 0 rangeUpper: 28 showInAdvancedViewOnly: TRUE adminDisplayName: ms-Exch-Previous-Account-Sid adminDescription: ms-Exch-Previous-Account-Sid oMSyntax: 4 searchFlags: 9 lDAPDisplayName: msExchPreviousAccountSid name: ms-Exch-Previous-Account-Sid schemaIDGUID: 9f7f4160-8942-4e87-a3fd-165b7711e433 attributeSecurityGUID: e48d0154-bcf8-11d1-8702-00c04fb96050 isMemberOfPartialAttributeSet: TRUE objectCategory: CN=Attribute-Schema,${SCHEMADN} # # ms-Exch-Prev-Export-DLs # A flag indicating whether DL names are propagated to foreign systems # via directory synchronization. # dn: CN=ms-Exch-Prev-Export-DLs,${SCHEMADN} objectClass: top objectClass: attributeSchema cn: ms-Exch-Prev-Export-DLs distinguishedName: CN=ms-Exch-Prev-Export-DLs,${SCHEMADN} attributeID: 1.2.840.113556.1.4.7000.102.1002 attributeSyntax: 2.5.5.8 isSingleValued: TRUE showInAdvancedViewOnly: TRUE adminDisplayName: ms-Exch-Prev-Export-DLs adminDescription: ms-Exch-Prev-Export-DLs oMSyntax: 1 searchFlags: 0 lDAPDisplayName: msExchPrevExportDLs name: ms-Exch-Prev-Export-DLs schemaIDGUID: 48464774-30ca-11d3-aa6d-00c04f8eedd8 isMemberOfPartialAttributeSet: FALSE objectCategory: CN=Attribute-Schema,${SCHEMADN} # # ms-Exch-PRMD # dn: CN=ms-Exch-PRMD,${SCHEMADN} objectClass: top objectClass: attributeSchema cn: ms-Exch-PRMD distinguishedName: CN=ms-Exch-PRMD,${SCHEMADN} attributeID: 1.2.840.113556.1.2.224 attributeSyntax: 2.5.5.5 isSingleValued: TRUE rangeLower: 1 rangeUpper: 16 mAPIID: 33038 showInAdvancedViewOnly: TRUE adminDisplayName: ms-Exch-PRMD adminDescription: ms-Exch-PRMD oMSyntax: 19 searchFlags: 0 lDAPDisplayName: pRMD name: ms-Exch-PRMD schemaIDGUID: a8df744d-c5ea-11d1-bbcb-0080c76670c0 isMemberOfPartialAttributeSet: FALSE objectCategory: CN=Attribute-Schema,${SCHEMADN} # # ms-Exch-Processed-Sids # A list of security identifiers (SIDs) that have already been # processed. # dn: CN=ms-Exch-Processed-Sids,${SCHEMADN} objectClass: top objectClass: attributeSchema cn: ms-Exch-Processed-Sids distinguishedName: CN=ms-Exch-Processed-Sids,${SCHEMADN} attributeID: 1.2.840.113556.1.4.7000.102.89 attributeSyntax: 2.5.5.17 isSingleValued: FALSE showInAdvancedViewOnly: TRUE adminDisplayName: ms-Exch-Processed-Sids adminDescription: ms-Exch-Processed-Sids oMSyntax: 4 searchFlags: 0 lDAPDisplayName: msExchProcessedSids name: ms-Exch-Processed-Sids schemaIDGUID: 5ab6a4b0-7d6c-4e84-848e-10d52b1eb735 isMemberOfPartialAttributeSet: FALSE objectCategory: CN=Attribute-Schema,${SCHEMADN} # # ms-Exch-Promo-Expiration # dn: CN=ms-Exch-Promo-Expiration,${SCHEMADN} objectClass: top objectClass: attributeSchema cn: ms-Exch-Promo-Expiration distinguishedName: CN=ms-Exch-Promo-Expiration,${SCHEMADN} attributeID: 1.2.840.113556.1.2.540 attributeSyntax: 2.5.5.11 isSingleValued: TRUE mAPIID: 33218 showInAdvancedViewOnly: TRUE adminDisplayName: ms-Exch-Promo-Expiration adminDescription: ms-Exch-Promo-Expiration oMSyntax: 23 searchFlags: 0 lDAPDisplayName: promoExpiration name: ms-Exch-Promo-Expiration schemaIDGUID: 1677585d-47f3-11d1-a9c3-0000f80367c1 isMemberOfPartialAttributeSet: TRUE objectCategory: CN=Attribute-Schema,${SCHEMADN} # # ms-Exch-Protocol-Settings # Exchange Internet protocol settings. # dn: CN=ms-Exch-Protocol-Settings,${SCHEMADN} objectClass: top objectClass: attributeSchema cn: ms-Exch-Protocol-Settings distinguishedName: CN=ms-Exch-Protocol-Settings,${SCHEMADN} attributeID: 1.2.840.113556.1.2.528 attributeSyntax: 2.5.5.12 isSingleValued: FALSE rangeLower: 0 rangeUpper: 256 mAPIID: 33206 showInAdvancedViewOnly: TRUE adminDisplayName: ms-Exch-Protocol-Settings adminDescription: ms-Exch-Protocol-Settings oMSyntax: 64 searchFlags: 16 lDAPDisplayName: protocolSettings name: ms-Exch-Protocol-Settings schemaIDGUID: 1677585e-47f3-11d1-a9c3-0000f80367c1 attributeSecurityGUID: e48d0154-bcf8-11d1-8702-00c04fb96050 isMemberOfPartialAttributeSet: TRUE objectCategory: CN=Attribute-Schema,${SCHEMADN} # # ms-Exch-Proxy-Custom-Proxy # dn: CN=ms-Exch-Proxy-Custom-Proxy,${SCHEMADN} objectClass: top objectClass: attributeSchema cn: ms-Exch-Proxy-Custom-Proxy distinguishedName: CN=ms-Exch-Proxy-Custom-Proxy,${SCHEMADN} attributeID: 1.2.840.113556.1.4.7000.102.50048 attributeSyntax: 2.5.5.12 isSingleValued: FALSE showInAdvancedViewOnly: TRUE adminDisplayName: ms-Exch-Proxy-Custom-Proxy adminDescription: ms-Exch-Proxy-Custom-Proxy oMSyntax: 64 searchFlags: 0 lDAPDisplayName: msExchProxyCustomProxy name: ms-Exch-Proxy-Custom-Proxy schemaIDGUID: 47bc3aa6-3634-11d3-aa6e-00c04f8eedd8 attributeSecurityGUID: e48d0154-bcf8-11d1-8702-00c04fb96050 isMemberOfPartialAttributeSet: FALSE objectCategory: CN=Attribute-Schema,${SCHEMADN} # # ms-Exch-Proxy-Gen-Options # dn: CN=msExch-Proxy-Gen-Options,${SCHEMADN} objectClass: top objectClass: attributeSchema cn: msExch-Proxy-Gen-Options attributeID: 1.2.840.113556.1.4.7000.102.50044 attributeSyntax: 2.5.5.9 isSingleValued: TRUE showInAdvancedViewOnly: TRUE adminDisplayName: msExch-Proxy-Gen-Options adminDescription: msExch-Proxy-Gen-Options oMSyntax: 2 searchFlags: 0 lDAPDisplayName: msExchProxyGenOptions name: msExch-Proxy-Gen-Options schemaIDGUID: 974c9a02-33fc-11d3-aa6e-00c04f8eedd8 isMemberOfPartialAttributeSet: FALSE objectCategory: CN=Attribute-Schema,${SCHEMADN} # # ms-Exch-Proxy-Generator-DLL # dn: CN=ms-Exch-Proxy-Generator-DLL,${SCHEMADN} objectClass: top objectClass: attributeSchema cn: ms-Exch-Proxy-Generator-DLL distinguishedName: CN=ms-Exch-Proxy-Generator-DLL,${SCHEMADN} attributeID: 1.2.840.113556.1.2.328 attributeSyntax: 2.5.5.12 isSingleValued: TRUE rangeLower: 1 rangeUpper: 255 mAPIID: 33039 showInAdvancedViewOnly: TRUE adminDisplayName: ms-Exch-Proxy-Generator-DLL adminDescription: ms-Exch-Proxy-Generator-DLL oMSyntax: 64 searchFlags: 0 lDAPDisplayName: proxyGeneratorDLL name: ms-Exch-Proxy-Generator-DLL schemaIDGUID: a8df744e-c5ea-11d1-bbcb-0080c76670c0 isMemberOfPartialAttributeSet: FALSE objectCategory: CN=Attribute-Schema,${SCHEMADN} # # ms-Exch-Proxy-Gen-Server # The time/date that this policy was applied. # dn: CN=ms-Exch-Proxy-Gen-Server,${SCHEMADN} objectClass: top objectClass: attributeSchema cn: ms-Exch-Proxy-Gen-Server distinguishedName: CN=ms-Exch-Proxy-Gen-Server,${SCHEMADN} attributeID: 1.2.840.113556.1.4.7000.102.50013 attributeSyntax: 2.5.5.10 isSingleValued: TRUE showInAdvancedViewOnly: TRUE adminDisplayName: ms-Exch-Proxy-Gen-Server adminDescription: ms-Exch-Proxy-Gen-Server oMSyntax: 4 searchFlags: 0 lDAPDisplayName: msExchProxyGenServer name: ms-Exch-Proxy-Gen-Server schemaIDGUID: 1a2a323a-b098-11d2-aa06-00c04f8eedd8 isMemberOfPartialAttributeSet: FALSE objectCategory: CN=Attribute-Schema,${SCHEMADN} # # ms-Exch-Proxy-Name # The data conference proxy name. # dn: CN=ms-Exch-Proxy-Name,${SCHEMADN} objectClass: top objectClass: attributeSchema cn: ms-Exch-Proxy-Name distinguishedName: CN=ms-Exch-Proxy-Name,${SCHEMADN} attributeID: 1.2.840.113556.1.4.7000.102.9018 attributeSyntax: 2.5.5.12 isSingleValued: TRUE showInAdvancedViewOnly: TRUE adminDisplayName: ms-Exch-Proxy-Name adminDescription: ms-Exch-Proxy-Name oMSyntax: 64 searchFlags: 0 lDAPDisplayName: msExchProxyName name: ms-Exch-Proxy-Name schemaIDGUID: 1a610850-b098-11d2-aa06-00c04f8eedd8 isMemberOfPartialAttributeSet: FALSE objectCategory: CN=Attribute-Schema,${SCHEMADN} # # ms-Exch-Public-Delegates # The DN of other mailboxes that can send on behalf of this mailbox. # dn: CN=ms-Exch-Public-Delegates,${SCHEMADN} objectClass: top objectClass: attributeSchema cn: ms-Exch-Public-Delegates distinguishedName: CN=ms-Exch-Public-Delegates,${SCHEMADN} attributeID: 1.2.840.113556.1.2.238 attributeSyntax: 2.5.5.1 isSingleValued: FALSE mAPIID: 32789 linkID: 14 showInAdvancedViewOnly: TRUE adminDisplayName: ms-Exch-Public-Delegates oMObjectClass:: KwwCh3McAIVK adminDescription: ms-Exch-Public-Delegates oMSyntax: 127 searchFlags: 16 lDAPDisplayName: publicDelegates name: ms-Exch-Public-Delegates schemaIDGUID: f0f8ff9a-1191-11d0-a060-00aa006c33ed attributeSecurityGUID: 77b5b886-944a-11d1-aebd-0000f80367c1 isMemberOfPartialAttributeSet: TRUE objectCategory: CN=Attribute-Schema,${SCHEMADN} # # ms-Exch-Public-Delegates-BL # dn: CN=ms-Exch-Public-Delegates-BL,${SCHEMADN} objectClass: top objectClass: attributeSchema cn: ms-Exch-Public-Delegates-BL distinguishedName: CN=ms-Exch-Public-Delegates-BL,${SCHEMADN} attributeID: 1.2.840.113556.1.2.295 attributeSyntax: 2.5.5.1 isSingleValued: FALSE mAPIID: 33040 linkID: 15 showInAdvancedViewOnly: TRUE adminDisplayName: ms-Exch-Public-Delegates-BL oMObjectClass:: KwwCh3McAIVK adminDescription: ms-Exch-Public-Delegates-BL oMSyntax: 127 searchFlags: 0 lDAPDisplayName: publicDelegatesBL name: ms-Exch-Public-Delegates-BL schemaIDGUID: bf967a08-0de6-11d0-a285-00aa003049e2 attributeSecurityGUID: e48d0154-bcf8-11d1-8702-00c04fb96050 systemFlags: 1 isMemberOfPartialAttributeSet: FALSE objectCategory: CN=Attribute-Schema,${SCHEMADN} # # ms-Exch-Purported-Search-UI # Stores the UI settings that set the purported search attribute. # dn: CN=ms-Exch-Purported-Search-UI,${SCHEMADN} objectClass: top objectClass: attributeSchema cn: ms-Exch-Purported-Search-UI distinguishedName: CN=ms-Exch-Purported-Search-UI,${SCHEMADN} attributeID: 1.2.840.113556.1.4.7000.102.66 attributeSyntax: 2.5.5.12 isSingleValued: FALSE showInAdvancedViewOnly: TRUE adminDisplayName: ms-Exch-Purported-Search-UI adminDescription: ms-Exch-Purported-Search-UI oMSyntax: 64 searchFlags: 0 lDAPDisplayName: msExchPurportedSearchUI name: ms-Exch-Purported-Search-UI schemaIDGUID: 1d86e324-b098-11d2-aa06-00c04f8eedd8 isMemberOfPartialAttributeSet: FALSE objectCategory: CN=Attribute-Schema,${SCHEMADN} # # ms-Exch-P-Selector # dn: CN=ms-Exch-P-Selector,${SCHEMADN} objectClass: top objectClass: attributeSchema cn: ms-Exch-P-Selector distinguishedName: CN=ms-Exch-P-Selector,${SCHEMADN} attributeID: 1.2.840.113556.1.2.285 attributeSyntax: 2.5.5.10 isSingleValued: TRUE rangeLower: 1 rangeUpper: 16 mAPIID: 33030 showInAdvancedViewOnly: TRUE adminDisplayName: ms-Exch-P-Selector adminDescription: ms-Exch-P-Selector oMSyntax: 4 searchFlags: 0 lDAPDisplayName: pSelector name: ms-Exch-P-Selector schemaIDGUID: a8df7448-c5ea-11d1-bbcb-0080c76670c0 isMemberOfPartialAttributeSet: FALSE objectCategory: CN=Attribute-Schema,${SCHEMADN} # # ms-Exch-P-Selector-Inbound # dn: CN=ms-Exch-P-Selector-Inbound,${SCHEMADN} objectClass: top objectClass: attributeSchema cn: ms-Exch-P-Selector-Inbound distinguishedName: CN=ms-Exch-P-Selector-Inbound,${SCHEMADN} attributeID: 1.2.840.113556.1.2.52 attributeSyntax: 2.5.5.10 isSingleValued: TRUE rangeLower: 1 rangeUpper: 16 mAPIID: 33031 showInAdvancedViewOnly: TRUE adminDisplayName: ms-Exch-P-Selector-Inbound adminDescription: ms-Exch-P-Selector-Inbound oMSyntax: 4 searchFlags: 0 lDAPDisplayName: pSelectorInbound name: ms-Exch-P-Selector-Inbound schemaIDGUID: a8df7449-c5ea-11d1-bbcb-0080c76670c0 isMemberOfPartialAttributeSet: FALSE objectCategory: CN=Attribute-Schema,${SCHEMADN} # # ms-Exch-Query-Base-DN # Defines the scope for client queries on address lists. # dn: CN=ms-Exch-Query-Base-DN,${SCHEMADN} objectClass: top objectClass: attributeSchema cn: ms-Exch-Query-Base-DN distinguishedName: CN=ms-Exch-Query-Base-DN,${SCHEMADN} attributeID: 1.2.840.113556.1.4.7000.102.15008 attributeSyntax: 2.5.5.1 isSingleValued: TRUE showInAdvancedViewOnly: TRUE adminDisplayName: ms-Exch-Query-Base-DN oMObjectClass:: KwwCh3McAIVK adminDescription: ms-Exch-Query-Base-DN oMSyntax: 127 searchFlags: 0 lDAPDisplayName: msExchQueryBaseDN name: ms-Exch-Query-Base-DN schemaIDGUID: 399eb12c-e120-473c-b0f7-97ae7ca4988b attributeSecurityGUID: e48d0154-bcf8-11d1-8702-00c04fb96050 isMemberOfPartialAttributeSet: TRUE objectCategory: CN=Attribute-Schema,${SCHEMADN} # # ms-Exch-Queuing-MDB # dn: CN=ms-Exch-Queuing-MDB,${SCHEMADN} objectClass: top objectClass: attributeSchema cn: ms-Exch-Queuing-MDB distinguishedName: CN=ms-Exch-Queuing-MDB,${SCHEMADN} attributeID: 1.2.840.113556.1.4.7000.102.11054 attributeSyntax: 2.5.5.1 isSingleValued: TRUE showInAdvancedViewOnly: TRUE adminDisplayName: ms-Exch-Queuing-MDB oMObjectClass:: KwwCh3McAIVK adminDescription: ms-Exch-Queuing-MDB oMSyntax: 127 searchFlags: 0 lDAPDisplayName: msExchQueuingMDB name: ms-Exch-Queuing-MDB schemaIDGUID: 8afa72da-b09e-11d2-aa06-00c04f8eedd8 isMemberOfPartialAttributeSet: FALSE objectCategory: CN=Attribute-Schema,${SCHEMADN} # # ms-Exch-Quota-Notification-Schedule # dn: CN=ms-Exch-Quota-Notification-Schedule,${SCHEMADN} objectClass: top objectClass: attributeSchema cn: ms-Exch-Quota-Notification-Schedule distinguishedName: CN=ms-Exch-Quota-Notification-Schedule,${SCHEMADN} attributeID: 1.2.840.113556.1.2.98 attributeSyntax: 2.5.5.10 isSingleValued: TRUE rangeLower: 84 rangeUpper: 84 mAPIID: 33041 showInAdvancedViewOnly: TRUE adminDisplayName: ms-Exch-Quota-Notification-Schedule adminDescription: ms-Exch-Quota-Notification-Schedule oMSyntax: 4 searchFlags: 0 lDAPDisplayName: quotaNotificationSchedule name: ms-Exch-Quota-Notification-Schedule schemaIDGUID: a8df744f-c5ea-11d1-bbcb-0080c76670c0 isMemberOfPartialAttributeSet: FALSE objectCategory: CN=Attribute-Schema,${SCHEMADN} # # ms-Exch-Quota-Notification-Style # dn: CN=ms-Exch-Quota-Notification-Style,${SCHEMADN} objectClass: top objectClass: attributeSchema cn: ms-Exch-Quota-Notification-Style distinguishedName: CN=ms-Exch-Quota-Notification-Style,${SCHEMADN} attributeID: 1.2.840.113556.1.2.388 attributeSyntax: 2.5.5.9 isSingleValued: TRUE rangeLower: 0 rangeUpper: 2 mAPIID: 33042 showInAdvancedViewOnly: TRUE adminDisplayName: ms-Exch-Quota-Notification-Style adminDescription: ms-Exch-Quota-Notification-Style oMSyntax: 2 searchFlags: 0 lDAPDisplayName: quotaNotificationStyle name: ms-Exch-Quota-Notification-Style schemaIDGUID: a8df7450-c5ea-11d1-bbcb-0080c76670c0 isMemberOfPartialAttributeSet: FALSE objectCategory: CN=Attribute-Schema,${SCHEMADN} # # ms-Exch-RAS-Callback-Number # dn: CN=ms-Exch-RAS-Callback-Number,${SCHEMADN} objectClass: top objectClass: attributeSchema cn: ms-Exch-RAS-Callback-Number distinguishedName: CN=ms-Exch-RAS-Callback-Number,${SCHEMADN} attributeID: 1.2.840.113556.1.2.315 attributeSyntax: 2.5.5.12 isSingleValued: TRUE rangeLower: 1 rangeUpper: 48 mAPIID: 33045 showInAdvancedViewOnly: TRUE adminDisplayName: ms-Exch-RAS-Callback-Number adminDescription: ms-Exch-RAS-Callback-Number oMSyntax: 64 searchFlags: 0 lDAPDisplayName: rASCallbackNumber name: ms-Exch-RAS-Callback-Number schemaIDGUID: a8df7452-c5ea-11d1-bbcb-0080c76670c0 isMemberOfPartialAttributeSet: FALSE objectCategory: CN=Attribute-Schema,${SCHEMADN} # # ms-Exch-RAS-Phonebook-Entry-Name # dn: CN=ms-Exch-RAS-Phonebook-Entry-Name,${SCHEMADN} objectClass: top objectClass: attributeSchema cn: ms-Exch-RAS-Phonebook-Entry-Name distinguishedName: CN=ms-Exch-RAS-Phonebook-Entry-Name,${SCHEMADN} attributeID: 1.2.840.113556.1.2.313 attributeSyntax: 2.5.5.12 isSingleValued: TRUE rangeLower: 1 rangeUpper: 256 mAPIID: 33047 showInAdvancedViewOnly: TRUE adminDisplayName: ms-Exch-RAS-Phonebook-Entry-Name adminDescription: ms-Exch-RAS-Phonebook-Entry-Name oMSyntax: 64 searchFlags: 0 lDAPDisplayName: rASPhonebookEntryName name: ms-Exch-RAS-Phonebook-Entry-Name schemaIDGUID: a8df7455-c5ea-11d1-bbcb-0080c76670c0 isMemberOfPartialAttributeSet: FALSE objectCategory: CN=Attribute-Schema,${SCHEMADN} # # ms-Exch-RAS-Phone-Number # dn: CN=ms-Exch-RAS-Phone-Number,${SCHEMADN} objectClass: top objectClass: attributeSchema cn: ms-Exch-RAS-Phone-Number distinguishedName: CN=ms-Exch-RAS-Phone-Number,${SCHEMADN} attributeID: 1.2.840.113556.1.2.314 attributeSyntax: 2.5.5.12 isSingleValued: TRUE rangeLower: 1 rangeUpper: 128 mAPIID: 33046 showInAdvancedViewOnly: TRUE adminDisplayName: ms-Exch-RAS-Phone-Number adminDescription: ms-Exch-RAS-Phone-Number oMSyntax: 64 searchFlags: 0 lDAPDisplayName: rASPhoneNumber name: ms-Exch-RAS-Phone-Number schemaIDGUID: a8df7454-c5ea-11d1-bbcb-0080c76670c0 isMemberOfPartialAttributeSet: FALSE objectCategory: CN=Attribute-Schema,${SCHEMADN} # # ms-Exch-RAS-Remote-SRVR-Name # dn: CN=ms-Exch-RAS-Remote-SRVR-Name,${SCHEMADN} objectClass: top objectClass: attributeSchema cn: ms-Exch-RAS-Remote-SRVR-Name distinguishedName: CN=ms-Exch-RAS-Remote-SRVR-Name,${SCHEMADN} attributeID: 1.2.840.113556.1.2.78 attributeSyntax: 2.5.5.4 isSingleValued: TRUE rangeLower: 1 rangeUpper: 15 mAPIID: 33048 showInAdvancedViewOnly: TRUE adminDisplayName: ms-Exch-RAS-Remote-SRVR-Name adminDescription: ms-Exch-RAS-Remote-SRVR-Name oMSyntax: 20 searchFlags: 0 lDAPDisplayName: rASRemoteSRVRName name: ms-Exch-RAS-Remote-SRVR-Name schemaIDGUID: a8df7456-c5ea-11d1-bbcb-0080c76670c0 isMemberOfPartialAttributeSet: FALSE objectCategory: CN=Attribute-Schema,${SCHEMADN} # # ms-Exch-Recip-Limit # The maximum number of recipients this user may send to, or a global # maximum for the organization. # dn: CN=ms-Exch-Recip-Limit,${SCHEMADN} objectClass: top objectClass: attributeSchema cn: ms-Exch-Recip-Limit distinguishedName: CN=ms-Exch-Recip-Limit,${SCHEMADN} attributeID: 1.2.840.113556.1.4.7000.102.12523 attributeSyntax: 2.5.5.9 isSingleValued: TRUE showInAdvancedViewOnly: TRUE adminDisplayName: ms-Exch-Recip-Limit adminDescription: ms-Exch-Recip-Limit oMSyntax: 2 searchFlags: 16 lDAPDisplayName: msExchRecipLimit name: ms-Exch-Recip-Limit schemaIDGUID: 1dd7f318-b098-11d2-aa06-00c04f8eedd8 attributeSecurityGUID: e48d0154-bcf8-11d1-8702-00c04fb96050 isMemberOfPartialAttributeSet: TRUE objectCategory: CN=Attribute-Schema,${SCHEMADN} # # ms-Exch-Recip-Turf-List-Names # dn: CN=ms-Exch-Recip-Turf-List-Names,${SCHEMADN} objectClass: top objectClass: attributeSchema cn: ms-Exch-Recip-Turf-List-Names distinguishedName: CN=ms-Exch-Recip-Turf-List-Names,${SCHEMADN} attributeID: 1.2.840.113556.1.4.7000.102.5070 attributeSyntax: 2.5.5.12 isSingleValued: FALSE showInAdvancedViewOnly: TRUE adminDisplayName: ms-Exch-Recip-Turf-List-Names adminDescription: ms-Exch-Recip-Turf-List-Names oMSyntax: 64 searchFlags: 0 lDAPDisplayName: msExchRecipTurfListNames name: ms-Exch-Recip-Turf-List-Names schemaIDGUID: 2e0a68e1-bdd7-4899-8bb2-d6ea007558c7 isMemberOfPartialAttributeSet: FALSE objectCategory: CN=Attribute-Schema,${SCHEMADN} # # ms-Exch-Recip-Turf-List-Options # dn: CN=ms-Exch-Recip-Turf-List-Options,${SCHEMADN} objectClass: top objectClass: attributeSchema cn: ms-Exch-Recip-Turf-List-Options distinguishedName: CN=ms-Exch-Recip-Turf-List-Options,${SCHEMADN} attributeID: 1.2.840.113556.1.4.7000.102.5071 attributeSyntax: 2.5.5.9 isSingleValued: TRUE showInAdvancedViewOnly: TRUE adminDisplayName: ms-Exch-Recip-Turf-List-Options adminDescription: ms-Exch-Recip-Turf-List-Options oMSyntax: 2 searchFlags: 0 lDAPDisplayName: msExchRecipTurfListOptions name: ms-Exch-Recip-Turf-List-Options schemaIDGUID: 870b36b3-d035-402d-b873-ced07b173763 isMemberOfPartialAttributeSet: FALSE objectCategory: CN=Attribute-Schema,${SCHEMADN} # # ms-Exch-Recovery # If recovery is on, log files are generated. # dn: CN=ms-Exch-Recovery,${SCHEMADN} objectClass: top objectClass: attributeSchema cn: ms-Exch-Recovery distinguishedName: CN=ms-Exch-Recovery,${SCHEMADN} attributeID: 1.2.840.113556.1.4.7000.102.11046 attributeSyntax: 2.5.5.8 isSingleValued: TRUE showInAdvancedViewOnly: TRUE adminDisplayName: ms-Exch-Recovery adminDescription: ms-Exch-Recovery oMSyntax: 1 searchFlags: 0 lDAPDisplayName: msExchRecovery name: ms-Exch-Recovery schemaIDGUID: 1e007b12-b098-11d2-aa06-00c04f8eedd8 isMemberOfPartialAttributeSet: FALSE objectCategory: CN=Attribute-Schema,${SCHEMADN} # # ms-Exch-Referral-List # dn: CN=ms-Exch-Referral-List,${SCHEMADN} objectClass: top objectClass: attributeSchema cn: ms-Exch-Referral-List distinguishedName: CN=ms-Exch-Referral-List,${SCHEMADN} attributeID: 1.2.840.113556.1.2.510 attributeSyntax: 2.5.5.12 isSingleValued: FALSE rangeLower: 1 rangeUpper: 1024 mAPIID: 33187 showInAdvancedViewOnly: TRUE adminDisplayName: ms-Exch-Referral-List adminDescription: ms-Exch-Referral-List oMSyntax: 64 searchFlags: 0 lDAPDisplayName: referralList name: ms-Exch-Referral-List schemaIDGUID: a8df7457-c5ea-11d1-bbcb-0080c76670c0 isMemberOfPartialAttributeSet: FALSE objectCategory: CN=Attribute-Schema,${SCHEMADN} # # ms-Exch-Remote-Bridge-Head # dn: CN=ms-Exch-Remote-Bridge-Head,${SCHEMADN} objectClass: top objectClass: attributeSchema cn: ms-Exch-Remote-Bridge-Head distinguishedName: CN=ms-Exch-Remote-Bridge-Head,${SCHEMADN} attributeID: 1.2.840.113556.1.2.191 attributeSyntax: 2.5.5.4 isSingleValued: TRUE rangeLower: 1 rangeUpper: 64 mAPIID: 33050 showInAdvancedViewOnly: TRUE adminDisplayName: ms-Exch-Remote-Bridge-Head adminDescription: ms-Exch-Remote-Bridge-Head oMSyntax: 20 searchFlags: 0 lDAPDisplayName: remoteBridgeHead name: ms-Exch-Remote-Bridge-Head schemaIDGUID: a8df7458-c5ea-11d1-bbcb-0080c76670c0 isMemberOfPartialAttributeSet: FALSE objectCategory: CN=Attribute-Schema,${SCHEMADN} # # ms-Exch-Remote-Bridge-Head-Address # dn: CN=ms-Exch-Remote-Bridge-Head-Address,${SCHEMADN} objectClass: top objectClass: attributeSchema cn: ms-Exch-Remote-Bridge-Head-Address distinguishedName: CN=ms-Exch-Remote-Bridge-Head-Address,${SCHEMADN} attributeID: 1.2.840.113556.1.2.94 attributeSyntax: 2.5.5.4 isSingleValued: TRUE rangeLower: 0 rangeUpper: 1118 mAPIID: 33051 showInAdvancedViewOnly: TRUE adminDisplayName: ms-Exch-Remote-Bridge-Head-Address adminDescription: ms-Exch-Remote-Bridge-Head-Address oMSyntax: 20 searchFlags: 0 lDAPDisplayName: remoteBridgeHeadAddress name: ms-Exch-Remote-Bridge-Head-Address schemaIDGUID: a8df7459-c5ea-11d1-bbcb-0080c76670c0 isMemberOfPartialAttributeSet: FALSE objectCategory: CN=Attribute-Schema,${SCHEMADN} # # ms-Exch-Remote-Private-IS-List # A flat delimited set of distinguished names (DNs) of remote Exchange # private stores. Used to set home-mdb on user objects. # dn: CN=ms-Exch-Remote-Private-IS-List,${SCHEMADN} objectClass: top objectClass: attributeSchema cn: ms-Exch-Remote-Private-IS-List distinguishedName: CN=ms-Exch-Remote-Private-IS-List,${SCHEMADN} attributeID: 1.2.840.113556.1.4.7000.102.46 attributeSyntax: 2.5.5.12 isSingleValued: TRUE showInAdvancedViewOnly: TRUE adminDisplayName: ms-Exch-Remote-Private-IS-List adminDescription: ms-Exch-Remote-Private-IS-List oMSyntax: 64 searchFlags: 0 lDAPDisplayName: msExchRemotePrivateISList name: ms-Exch-Remote-Private-IS-List schemaIDGUID: 1e29030c-b098-11d2-aa06-00c04f8eedd8 isMemberOfPartialAttributeSet: FALSE objectCategory: CN=Attribute-Schema,${SCHEMADN} # # ms-Exch-Remote-Server-List # A flat delimited set of distinguished names (DNs) of remote Exchange # servers. Used to set home-mta on DL objects. # dn: CN=ms-Exch-Remote-Server-List,${SCHEMADN} objectClass: top objectClass: attributeSchema cn: ms-Exch-Remote-Server-List distinguishedName: CN=ms-Exch-Remote-Server-List,${SCHEMADN} attributeID: 1.2.840.113556.1.4.7000.102.45 attributeSyntax: 2.5.5.12 isSingleValued: TRUE showInAdvancedViewOnly: TRUE adminDisplayName: ms-Exch-Remote-Server-List adminDescription: ms-Exch-Remote-Server-List oMSyntax: 64 searchFlags: 0 lDAPDisplayName: msExchRemoteServerList name: ms-Exch-Remote-Server-List schemaIDGUID: 1e58b214-b098-11d2-aa06-00c04f8eedd8 isMemberOfPartialAttributeSet: FALSE objectCategory: CN=Attribute-Schema,${SCHEMADN} # # ms-Exch-Remote-Site # dn: CN=ms-Exch-Remote-Site,${SCHEMADN} objectClass: top objectClass: attributeSchema cn: ms-Exch-Remote-Site distinguishedName: CN=ms-Exch-Remote-Site,${SCHEMADN} attributeID: 1.2.840.113556.1.2.27 attributeSyntax: 2.5.5.1 isSingleValued: TRUE mAPIID: 33053 showInAdvancedViewOnly: TRUE adminDisplayName: ms-Exch-Remote-Site oMObjectClass:: KwwCh3McAIVK adminDescription: ms-Exch-Remote-Site oMSyntax: 127 searchFlags: 0 lDAPDisplayName: remoteSite name: ms-Exch-Remote-Site schemaIDGUID: a8df745b-c5ea-11d1-bbcb-0080c76670c0 isMemberOfPartialAttributeSet: FALSE objectCategory: CN=Attribute-Schema,${SCHEMADN} # # ms-Exch-Replicated-Object-Version # dn: CN=ms-Exch-Replicated-Object-Version,${SCHEMADN} objectClass: top objectClass: attributeSchema cn: ms-Exch-Replicated-Object-Version distinguishedName: CN=ms-Exch-Replicated-Object-Version,${SCHEMADN} attributeID: 1.2.840.113556.1.2.604 attributeSyntax: 2.5.5.9 isSingleValued: TRUE mAPIID: 35938 showInAdvancedViewOnly: TRUE adminDisplayName: ms-Exch-Replicated-Object-Version adminDescription: ms-Exch-Replicated-Object-Version oMSyntax: 2 searchFlags: 0 lDAPDisplayName: replicatedObjectVersion name: ms-Exch-Replicated-Object-Version schemaIDGUID: 1677586c-47f3-11d1-a9c3-0000f80367c1 attributeSecurityGUID: e48d0154-bcf8-11d1-8702-00c04fb96050 isMemberOfPartialAttributeSet: TRUE objectCategory: CN=Attribute-Schema,${SCHEMADN} # # ms-Exch-Replicate-Now # A flag that notifies the service to replicate this connection # agreement immediately. # dn: CN=ms-Exch-Replicate-Now,${SCHEMADN} objectClass: top objectClass: attributeSchema cn: ms-Exch-Replicate-Now distinguishedName: CN=ms-Exch-Replicate-Now,${SCHEMADN} attributeID: 1.2.840.113556.1.4.7000.102.53 attributeSyntax: 2.5.5.8 isSingleValued: TRUE showInAdvancedViewOnly: TRUE adminDisplayName: ms-Exch-Replicate-Now adminDescription: ms-Exch-Replicate-Now oMSyntax: 1 searchFlags: 0 lDAPDisplayName: msExchReplicateNow name: ms-Exch-Replicate-Now schemaIDGUID: 1eac2462-b098-11d2-aa06-00c04f8eedd8 isMemberOfPartialAttributeSet: FALSE objectCategory: CN=Attribute-Schema,${SCHEMADN} # # ms-Exch-Replication-Mail-Msg-Size # dn: CN=ms-Exch-Replication-Mail-Msg-Size,${SCHEMADN} objectClass: top objectClass: attributeSchema cn: ms-Exch-Replication-Mail-Msg-Size distinguishedName: CN=ms-Exch-Replication-Mail-Msg-Size,${SCHEMADN} attributeID: 1.2.840.113556.1.2.103 attributeSyntax: 2.5.5.9 isSingleValued: TRUE mAPIID: 33128 showInAdvancedViewOnly: TRUE adminDisplayName: ms-Exch-Replication-Mail-Msg-Size adminDescription: ms-Exch-Replication-Mail-Msg-Size oMSyntax: 2 searchFlags: 0 lDAPDisplayName: replicationMailMsgSize name: ms-Exch-Replication-Mail-Msg-Size schemaIDGUID: a8df745c-c5ea-11d1-bbcb-0080c76670c0 isMemberOfPartialAttributeSet: FALSE objectCategory: CN=Attribute-Schema,${SCHEMADN} # # ms-Exch-Replication-Msg-Size # The replication message size limit. dn: CN=ms-Exch-Replication-Msg-Size,${SCHEMADN} objectClass: top objectClass: attributeSchema cn: ms-Exch-Replication-Msg-Size distinguishedName: CN=ms-Exch-Replication-Msg-Size,${SCHEMADN} attributeID: 1.2.840.113556.1.4.7000.102.11047 attributeSyntax: 2.5.5.9 isSingleValued: TRUE showInAdvancedViewOnly: TRUE adminDisplayName: ms-Exch-Replication-Msg-Size adminDescription: ms-Exch-Replication-Msg-Size oMSyntax: 2 searchFlags: 0 lDAPDisplayName: msExchReplicationMsgSize name: ms-Exch-Replication-Msg-Size schemaIDGUID: 1ed70eb6-b098-11d2-aa06-00c04f8eedd8 isMemberOfPartialAttributeSet: FALSE objectCategory: CN=Attribute-Schema,${SCHEMADN} # # ms-Exch-Replication-Schedule # The schedule of when to replicate public folder changes. # dn: CN=ms-Exch-Replication-Schedule,${SCHEMADN} objectClass: top objectClass: attributeSchema cn: ms-Exch-Replication-Schedule distinguishedName: CN=ms-Exch-Replication-Schedule,${SCHEMADN} attributeID: 1.2.840.113556.1.4.7000.102.11048 attributeSyntax: 2.5.5.10 isSingleValued: TRUE showInAdvancedViewOnly: TRUE adminDisplayName: ms-Exch-Replication-Schedule adminDescription: ms-Exch-Replication-Schedule oMSyntax: 4 searchFlags: 0 lDAPDisplayName: msExchReplicationSchedule name: ms-Exch-Replication-Schedule schemaIDGUID: 1f01f90a-b098-11d2-aa06-00c04f8eedd8 isMemberOfPartialAttributeSet: FALSE objectCategory: CN=Attribute-Schema,${SCHEMADN} # # ms-Exch-Replication-Sensitivity # Used by Exchange on legacy Exchange Server 5.5 connectors to govern # their use by replication. # dn: CN=ms-Exch-Replication-Sensitivity,${SCHEMADN} objectClass: top objectClass: attributeSchema cn: ms-Exch-Replication-Sensitivity distinguishedName: CN=ms-Exch-Replication-Sensitivity,${SCHEMADN} attributeID: 1.2.840.113556.1.2.223 attributeSyntax: 2.5.5.9 isSingleValued: TRUE rangeLower: 0 rangeUpper: 100 mAPIID: 33054 showInAdvancedViewOnly: TRUE adminDisplayName: ms-Exch-Replication-Sensitivity adminDescription: ms-Exch-Replication-Sensitivity oMSyntax: 2 searchFlags: 0 lDAPDisplayName: replicationSensitivity name: ms-Exch-Replication-Sensitivity schemaIDGUID: bf967a1b-0de6-11d0-a285-00aa003049e2 attributeSecurityGUID: e48d0154-bcf8-11d1-8702-00c04fb96050 isMemberOfPartialAttributeSet: FALSE objectCategory: CN=Attribute-Schema,${SCHEMADN} # # ms-Exch-Replication-Signature # Signature used for replication purposes by the Active Directory Connector. # dn: CN=ms-Exch-Replication-Signature,${SCHEMADN} objectClass: top objectClass: attributeSchema cn: ms-Exch-Replication-Signature distinguishedName: CN=ms-Exch-Replication-Signature,${SCHEMADN} attributeID: 1.2.840.113556.1.4.7000.102.52 attributeSyntax: 2.5.5.10 isSingleValued: TRUE showInAdvancedViewOnly: TRUE adminDisplayName: ms-Exch-Replication-Signature adminDescription: ms-Exch-Replication-Signature oMSyntax: 4 searchFlags: 0 lDAPDisplayName: replicationSignature name: ms-Exch-Replication-Signature schemaIDGUID: 9909d92a-b093-11d2-aa06-00c04f8eedd8 attributeSecurityGUID: e48d0154-bcf8-11d1-8702-00c04fb96050 isMemberOfPartialAttributeSet: TRUE objectCategory: CN=Attribute-Schema,${SCHEMADN} # # ms-Exch-Replication-Stagger # dn: CN=ms-Exch-Replication-Stagger,${SCHEMADN} objectClass: top objectClass: attributeSchema cn: ms-Exch-Replication-Stagger distinguishedName: CN=ms-Exch-Replication-Stagger,${SCHEMADN} attributeID: 1.2.840.113556.1.2.349 attributeSyntax: 2.5.5.9 isSingleValued: TRUE mAPIID: 33055 showInAdvancedViewOnly: TRUE adminDisplayName: ms-Exch-Replication-Stagger adminDescription: ms-Exch-Replication-Stagger oMSyntax: 2 searchFlags: 0 lDAPDisplayName: replicationStagger name: ms-Exch-Replication-Stagger schemaIDGUID: a8df745d-c5ea-11d1-bbcb-0080c76670c0 isMemberOfPartialAttributeSet: FALSE objectCategory: CN=Attribute-Schema,${SCHEMADN} # # ms-Exch-Replication-Style # The style for replicating public folder changes, such as Always or Never. # dn: CN=ms-Exch-Replication-Style,${SCHEMADN} objectClass: top objectClass: attributeSchema cn: ms-Exch-Replication-Style distinguishedName: CN=ms-Exch-Replication-Style,${SCHEMADN} attributeID: 1.2.840.113556.1.4.7000.102.11049 attributeSyntax: 2.5.5.9 isSingleValued: TRUE showInAdvancedViewOnly: TRUE adminDisplayName: ms-Exch-Replication-Style adminDescription: ms-Exch-Replication-Style oMSyntax: 2 searchFlags: 0 lDAPDisplayName: msExchReplicationStyle name: ms-Exch-Replication-Style schemaIDGUID: 1f2ce35e-b098-11d2-aa06-00c04f8eedd8 isMemberOfPartialAttributeSet: FALSE objectCategory: CN=Attribute-Schema,${SCHEMADN} # # ms-Exch-Report-To-Originator # dn: CN=ms-Exch-Report-To-Originator,${SCHEMADN} objectClass: top objectClass: attributeSchema cn: ms-Exch-Report-To-Originator distinguishedName: CN=ms-Exch-Report-To-Originator,${SCHEMADN} attributeID: 1.2.840.113556.1.2.206 attributeSyntax: 2.5.5.8 isSingleValued: TRUE mAPIID: 33056 showInAdvancedViewOnly: TRUE adminDisplayName: ms-Exch-Report-To-Originator adminDescription: ms-Exch-Report-To-Originator oMSyntax: 1 searchFlags: 0 lDAPDisplayName: reportToOriginator name: ms-Exch-Report-To-Originator schemaIDGUID: a8df745e-c5ea-11d1-bbcb-0080c76670c0 attributeSecurityGUID: e48d0154-bcf8-11d1-8702-00c04fb96050 isMemberOfPartialAttributeSet: TRUE objectCategory: CN=Attribute-Schema,${SCHEMADN} # # ms-Exch-Report-To-Owner # Governs whether or not read receipts and delivery receipts will be sent to the sender of messages sent to this DL. # dn: CN=ms-Exch-Report-To-Owner,${SCHEMADN} objectClass: top objectClass: attributeSchema cn: ms-Exch-Report-To-Owner distinguishedName: CN=ms-Exch-Report-To-Owner,${SCHEMADN} attributeID: 1.2.840.113556.1.2.207 attributeSyntax: 2.5.5.8 isSingleValued: TRUE mAPIID: 33057 showInAdvancedViewOnly: TRUE adminDisplayName: ms-Exch-Report-To-Owner adminDescription: ms-Exch-Report-To-Owner oMSyntax: 1 searchFlags: 0 lDAPDisplayName: reportToOwner name: ms-Exch-Report-To-Owner schemaIDGUID: a8df745f-c5ea-11d1-bbcb-0080c76670c0 attributeSecurityGUID: e48d0154-bcf8-11d1-8702-00c04fb96050 isMemberOfPartialAttributeSet: TRUE objectCategory: CN=Attribute-Schema,${SCHEMADN} # # ms-Exch-RequireAuthToSendTo # dn: CN=ms-Exch-RequireAuthToSendTo,${SCHEMADN} objectClass: top objectClass: attributeSchema cn: ms-Exch-RequireAuthToSendTo distinguishedName: CN=ms-Exch-RequireAuthToSendTo,${SCHEMADN} attributeID: 1.2.840.113556.1.4.5062 attributeSyntax: 2.5.5.8 isSingleValued: TRUE showInAdvancedViewOnly: TRUE adminDisplayName: ms-Exch-RequireAuthToSendTo adminDescription: ms-Exch-RequireAuthToSendTo oMSyntax: 1 searchFlags: 0 lDAPDisplayName: msExchRequireAuthToSendTo name: ms-Exch-RequireAuthToSendTo schemaIDGUID: f533eb3b-f75b-4fb3-b2fb-08cd537a84d1 attributeSecurityGUID: e48d0154-bcf8-11d1-8702-00c04fb96050 isMemberOfPartialAttributeSet: TRUE objectCategory: CN=Attribute-Schema,${SCHEMADN} # # ms-Exch-Require-SSL # dn: CN=ms-Exch-Require-SSL,${SCHEMADN} objectClass: top objectClass: attributeSchema cn: ms-Exch-Require-SSL distinguishedName: CN=ms-Exch-Require-SSL,${SCHEMADN} attributeID: 1.2.840.113556.1.2.560 attributeSyntax: 2.5.5.8 isSingleValued: TRUE mAPIID: 35877 showInAdvancedViewOnly: TRUE adminDisplayName: ms-Exch-Require-SSL adminDescription: ms-Exch-Require-SSL oMSyntax: 1 searchFlags: 0 lDAPDisplayName: requireSSL name: ms-Exch-Require-SSL schemaIDGUID: a8df7461-c5ea-11d1-bbcb-0080c76670c0 isMemberOfPartialAttributeSet: FALSE objectCategory: CN=Attribute-Schema,${SCHEMADN} # # ms-Exch-Req-Seq # dn: CN=ms-Exch-Req-Seq,${SCHEMADN} objectClass: top objectClass: attributeSchema cn: ms-Exch-Req-Seq distinguishedName: CN=ms-Exch-Req-Seq,${SCHEMADN} attributeID: 1.2.840.113556.1.2.173 attributeSyntax: 2.5.5.9 isSingleValued: TRUE mAPIID: 33058 showInAdvancedViewOnly: TRUE adminDisplayName: ms-Exch-Req-Seq adminDescription: ms-Exch-Req-Seq oMSyntax: 2 searchFlags: 0 lDAPDisplayName: reqSeq name: ms-Exch-Req-Seq schemaIDGUID: a8df7460-c5ea-11d1-bbcb-0080c76670c0 isMemberOfPartialAttributeSet: FALSE objectCategory: CN=Attribute-Schema,${SCHEMADN} # # ms-Exch-Resolve-P2 # dn: CN=ms-Exch-Resolve-P2,${SCHEMADN} objectClass: top objectClass: attributeSchema cn: ms-Exch-Resolve-P2 distinguishedName: CN=ms-Exch-Resolve-P2,${SCHEMADN} attributeID: 1.2.840.113556.1.4.7000.102.12538 attributeSyntax: 2.5.5.9 isSingleValued: TRUE showInAdvancedViewOnly: TRUE adminDisplayName: ms-Exch-Resolve-P2 adminDescription: ms-Exch-Resolve-P2 oMSyntax: 2 searchFlags: 0 lDAPDisplayName: msExchResolveP2 name: ms-Exch-Resolve-P2 schemaIDGUID: e24d7aa1-439d-11d3-aa72-00c04f8eedd8 isMemberOfPartialAttributeSet: FALSE objectCategory: CN=Attribute-Schema,${SCHEMADN} # # ms-Exch-Resource-GUID # The CTP GUID. # dn: CN=ms-Exch-Resource-GUID,${SCHEMADN} objectClass: top objectClass: attributeSchema cn: ms-Exch-Resource-GUID distinguishedName: CN=ms-Exch-Resource-GUID,${SCHEMADN} attributeID: 1.2.840.113556.1.4.7000.102.9001 attributeSyntax: 2.5.5.12 isSingleValued: FALSE showInAdvancedViewOnly: TRUE adminDisplayName: ms-Exch-Resource-GUID adminDescription: ms-Exch-Resource-GUID oMSyntax: 64 searchFlags: 17 lDAPDisplayName: msExchResourceGUID name: ms-Exch-Resource-GUID schemaIDGUID: 1f57cdb2-b098-11d2-aa06-00c04f8eedd8 attributeSecurityGUID: e48d0154-bcf8-11d1-8702-00c04fb96050 isMemberOfPartialAttributeSet: TRUE objectCategory: CN=Attribute-Schema,${SCHEMADN} # # ms-Exch-Resource-Properties # Resource values specific to the CTP. # dn: CN=ms-Exch-Resource-Properties,${SCHEMADN} objectClass: top objectClass: attributeSchema cn: ms-Exch-Resource-Properties distinguishedName: CN=ms-Exch-Resource-Properties,${SCHEMADN} attributeID: 1.2.840.113556.1.4.7000.102.9025 attributeSyntax: 2.5.5.12 isSingleValued: FALSE showInAdvancedViewOnly: TRUE adminDisplayName: ms-Exch-Resource-Properties adminDescription: ms-Exch-Resource-Properties oMSyntax: 64 searchFlags: 16 lDAPDisplayName: msExchResourceProperties name: ms-Exch-Resource-Properties schemaIDGUID: 912beea4-b09e-11d2-aa06-00c04f8eedd8 attributeSecurityGUID: e48d0154-bcf8-11d1-8702-00c04fb96050 isMemberOfPartialAttributeSet: FALSE objectCategory: CN=Attribute-Schema,${SCHEMADN} # # ms-Exch-Responsible-Local-DXA # dn: CN=ms-Exch-Responsible-Local-DXA,${SCHEMADN} objectClass: top objectClass: attributeSchema cn: ms-Exch-Responsible-Local-DXA distinguishedName: CN=ms-Exch-Responsible-Local-DXA,${SCHEMADN} attributeID: 1.2.840.113556.1.2.298 attributeSyntax: 2.5.5.1 isSingleValued: TRUE mAPIID: 33059 linkID: 122 showInAdvancedViewOnly: TRUE adminDisplayName: ms-Exch-Responsible-Local-DXA oMObjectClass:: KwwCh3McAIVK adminDescription: ms-Exch-Responsible-Local-DXA oMSyntax: 127 searchFlags: 0 lDAPDisplayName: responsibleLocalDXA name: ms-Exch-Responsible-Local-DXA schemaIDGUID: a8df7462-c5ea-11d1-bbcb-0080c76670c0 isMemberOfPartialAttributeSet: FALSE objectCategory: CN=Attribute-Schema,${SCHEMADN} # # ms-Exch-Responsible-MTA-Server # dn: CN=ms-Exch-Responsible-MTA-Server,${SCHEMADN} objectClass: top objectClass: attributeSchema cn: ms-Exch-Responsible-MTA-Server distinguishedName: CN=ms-Exch-Responsible-MTA-Server,${SCHEMADN} attributeID: 1.2.840.113556.1.4.7000.102.50033 attributeSyntax: 2.5.5.1 isSingleValued: TRUE linkID: 1030 showInAdvancedViewOnly: TRUE adminDisplayName: ms-Exch-Responsible-MTA-Server oMObjectClass:: KwwCh3McAIVK adminDescription: ms-Exch-Responsible-MTA-Server oMSyntax: 127 searchFlags: 0 lDAPDisplayName: msExchResponsibleMTAServer name: ms-Exch-Responsible-MTA-Server schemaIDGUID: 9ff15c37-1ec9-11d3-aa5e-00c04f8eedd8 isMemberOfPartialAttributeSet: FALSE objectCategory: CN=Attribute-Schema,${SCHEMADN} # # ms-Exch-Responsible-MTA-Server-BL # dn: CN=ms-Exch-Responsible-MTA-Server-BL,${SCHEMADN} objectClass: top objectClass: attributeSchema cn: ms-Exch-Responsible-MTA-Server-BL distinguishedName: CN=ms-Exch-Responsible-MTA-Server-BL,${SCHEMADN} attributeID: 1.2.840.113556.1.4.7000.102.50034 attributeSyntax: 2.5.5.1 isSingleValued: FALSE linkID: 1031 showInAdvancedViewOnly: TRUE adminDisplayName: ms-Exch-Responsible-MTA-Server-BL oMObjectClass:: KwwCh3McAIVK adminDescription: ms-Exch-Responsible-MTA-Server-BL oMSyntax: 127 searchFlags: 0 lDAPDisplayName: msExchResponsibleMTAServerBL name: ms-Exch-Responsible-MTA-Server-BL schemaIDGUID: 9ff15c3c-1ec9-11d3-aa5e-00c04f8eedd8 systemFlags: 1 isMemberOfPartialAttributeSet: FALSE objectCategory: CN=Attribute-Schema,${SCHEMADN} # # ms-Exch-Restore # dn: CN=ms-Exch-Restore,${SCHEMADN} objectClass: top objectClass: attributeSchema cn: ms-Exch-Restore distinguishedName: CN=ms-Exch-Restore,${SCHEMADN} attributeID: 1.2.840.113556.1.4.7000.102.11092 attributeSyntax: 2.5.5.8 isSingleValued: TRUE showInAdvancedViewOnly: TRUE adminDisplayName: ms-Exch-Restore adminDescription: ms-Exch-Restore oMSyntax: 1 searchFlags: 0 lDAPDisplayName: msExchRestore name: ms-Exch-Restore schemaIDGUID: a1edcb4c-5c45-4d4a-b128-880392e9dcc6 isMemberOfPartialAttributeSet: TRUE objectCategory: CN=Attribute-Schema,${SCHEMADN} # # ms-Exch-Return-Exact-Msg-Size # dn: CN=ms-Exch-Return-Exact-Msg-Size,${SCHEMADN} objectClass: top objectClass: attributeSchema cn: ms-Exch-Return-Exact-Msg-Size distinguishedName: CN=ms-Exch-Return-Exact-Msg-Size,${SCHEMADN} attributeID: 1.2.840.113556.1.2.594 attributeSyntax: 2.5.5.8 isSingleValued: TRUE mAPIID: 35922 showInAdvancedViewOnly: TRUE adminDisplayName: ms-Exch-Return-Exact-Msg-Size adminDescription: ms-Exch-Return-Exact-Msg-Size oMSyntax: 1 searchFlags: 0 lDAPDisplayName: returnExactMsgSize name: ms-Exch-Return-Exact-Msg-Size schemaIDGUID: a8df7463-c5ea-11d1-bbcb-0080c76670c0 isMemberOfPartialAttributeSet: FALSE objectCategory: CN=Attribute-Schema,${SCHEMADN} # # ms-Exch-Rid-Server # A pointer to the server that maintains the Gateway Address # Resolution Table (GWART) for this site or administrative group. # dn: CN=ms-Exch-Rid-Server,${SCHEMADN} objectClass: top objectClass: attributeSchema cn: ms-Exch-Rid-Server distinguishedName: CN=ms-Exch-Rid-Server,${SCHEMADN} attributeID: 1.2.840.113556.1.2.346 attributeSyntax: 2.5.5.1 isSingleValued: TRUE mAPIID: 33060 showInAdvancedViewOnly: TRUE adminDisplayName: ms-Exch-Rid-Server oMObjectClass:: KwwCh3McAIVK adminDescription: ms-Exch-Rid-Server oMSyntax: 127 searchFlags: 0 lDAPDisplayName: ridServer name: ms-Exch-Rid-Server schemaIDGUID: a8df7464-c5ea-11d1-bbcb-0080c76670c0 isMemberOfPartialAttributeSet: FALSE objectCategory: CN=Attribute-Schema,${SCHEMADN} # # ms-Exch-Role-Includes # The set of other roles that this role includes. # dn: CN=ms-Exch-Role-Includes,${SCHEMADN} objectClass: top objectClass: attributeSchema cn: ms-Exch-Role-Includes distinguishedName: CN=ms-Exch-Role-Includes,${SCHEMADN} attributeID: 1.2.840.113556.1.4.7000.102.50020 attributeSyntax: 2.5.5.1 isSingleValued: FALSE showInAdvancedViewOnly: TRUE adminDisplayName: ms-Exch-Role-Includes oMObjectClass:: KwwCh3McAIVK adminDescription: ms-Exch-Role-Includes oMSyntax: 127 searchFlags: 0 lDAPDisplayName: msExchRoleIncludes name: ms-Exch-Role-Includes schemaIDGUID: 1f8055ac-b098-11d2-aa06-00c04f8eedd8 isMemberOfPartialAttributeSet: FALSE objectCategory: CN=Attribute-Schema,${SCHEMADN} # # ms-Exch-Role-Localized-Names # The OAB that this mailbox store or this user uses. # dn: CN=ms-Exch-Role-Localized-Names,${SCHEMADN} objectClass: top objectClass: attributeSchema cn: ms-Exch-Role-Localized-Names distinguishedName: CN=ms-Exch-Role-Localized-Names,${SCHEMADN} attributeID: 1.2.840.113556.1.4.7000.102.50021 attributeSyntax: 2.5.5.10 isSingleValued: FALSE showInAdvancedViewOnly: TRUE adminDisplayName: ms-Exch-Role-Localized-Names adminDescription: ms-Exch-Role-Localized-Names oMSyntax: 4 searchFlags: 0 lDAPDisplayName: msExchRoleLocalizedNames name: ms-Exch-Role-Localized-Names schemaIDGUID: 1fa8dda6-b098-11d2-aa06-00c04f8eedd8 isMemberOfPartialAttributeSet: FALSE objectCategory: CN=Attribute-Schema,${SCHEMADN} # # ms-Exch-Role-Rights # The set of rights, per objectClass, that this role includes. # dn: CN=ms-Exch-Role-Rights,${SCHEMADN} objectClass: top objectClass: attributeSchema cn: ms-Exch-Role-Rights distinguishedName: CN=ms-Exch-Role-Rights,${SCHEMADN} attributeID: 1.2.840.113556.1.4.7000.102.50018 attributeSyntax: 2.5.5.10 isSingleValued: FALSE showInAdvancedViewOnly: TRUE adminDisplayName: ms-Exch-Role-Rights adminDescription: ms-Exch-Role-Rights oMSyntax: 4 searchFlags: 0 lDAPDisplayName: msExchRoleRights name: ms-Exch-Role-Rights schemaIDGUID: 1fd165a0-b098-11d2-aa06-00c04f8eedd8 isMemberOfPartialAttributeSet: FALSE objectCategory: CN=Attribute-Schema,${SCHEMADN} # # ms-Exch-Root-Newsgroups-Folder-ID # dn: CN=ms-Exch-Root-Newsgroups-Folder-ID,${SCHEMADN} objectClass: top objectClass: attributeSchema cn: ms-Exch-Root-Newsgroups-Folder-ID distinguishedName: CN=ms-Exch-Root-Newsgroups-Folder-ID,${SCHEMADN} attributeID: 1.2.840.113556.1.2.524 attributeSyntax: 2.5.5.10 isSingleValued: TRUE rangeLower: 1 rangeUpper: 1024 mAPIID: 33202 showInAdvancedViewOnly: TRUE adminDisplayName: ms-Exch-Root-Newsgroups-Folder-ID adminDescription: ms-Exch-Root-Newsgroups-Folder-ID oMSyntax: 4 searchFlags: 0 lDAPDisplayName: rootNewsgroupsFolderID name: ms-Exch-Root-Newsgroups-Folder-ID schemaIDGUID: a8df7466-c5ea-11d1-bbcb-0080c76670c0 isMemberOfPartialAttributeSet: FALSE objectCategory: CN=Attribute-Schema,${SCHEMADN} # # ms-Exch-Routing-Accept-Message-Type # dn: CN=ms-Exch-Routing-Accept-Message-Type,${SCHEMADN} objectClass: top objectClass: attributeSchema cn: ms-Exch-Routing-Accept-Message-Type distinguishedName: CN=ms-Exch-Routing-Accept-Message-Type,${SCHEMADN} attributeID: 1.2.840.113556.1.4.7000.102.12517 attributeSyntax: 2.5.5.9 isSingleValued: TRUE showInAdvancedViewOnly: TRUE adminDisplayName: ms-Exch-Routing-Accept-Message-Type adminDescription: ms-Exch-Routing-Accept-Message-Type oMSyntax: 2 searchFlags: 0 lDAPDisplayName: msExchRoutingAcceptMessageType name: ms-Exch-Routing-Accept-Message-Type schemaIDGUID: 881759de-b09e-11d2-aa06-00c04f8eedd8 isMemberOfPartialAttributeSet: FALSE objectCategory: CN=Attribute-Schema,${SCHEMADN} # # ms-Exch-Routing-Disallow-Priority # dn: CN=ms-Exch-Routing-Disallow-Priority,${SCHEMADN} objectClass: top objectClass: attributeSchema cn: ms-Exch-Routing-Disallow-Priority distinguishedName: CN=ms-Exch-Routing-Disallow-Priority,${SCHEMADN} attributeID: 1.2.840.113556.1.4.7000.102.12529 attributeSyntax: 2.5.5.9 isSingleValued: TRUE showInAdvancedViewOnly: TRUE adminDisplayName: ms-Exch-Routing-Disallow-Priority adminDescription: ms-Exch-Routing-Disallow-Priority oMSyntax: 2 searchFlags: 0 lDAPDisplayName: msExchRoutingDisallowPriority name: ms-Exch-Routing-Disallow-Priority schemaIDGUID: 909a7f32-b09e-11d2-aa06-00c04f8eedd8 isMemberOfPartialAttributeSet: FALSE objectCategory: CN=Attribute-Schema,${SCHEMADN} # # ms-Exch-Routing-Display-Sender-Enabled # dn: CN=ms-Exch-Routing-Display-Sender-Enabled,${SCHEMADN} objectClass: top objectClass: attributeSchema cn: ms-Exch-Routing-Display-Sender-Enabled distinguishedName: CN=ms-Exch-Routing-Display-Sender-Enabled,${SCHEMADN} attributeID: 1.2.840.113556.1.4.7000.102.12519 attributeSyntax: 2.5.5.8 isSingleValued: TRUE showInAdvancedViewOnly: TRUE adminDisplayName: ms-Exch-Routing-Display-Sender-Enabled adminDescription: ms-Exch-Routing-Display-Sender-Enabled oMSyntax: 1 searchFlags: 0 lDAPDisplayName: msExchRoutingDisplaySenderEnabled name: ms-Exch-Routing-Display-Sender-Enabled schemaIDGUID: 88dadab2-b09e-11d2-aa06-00c04f8eedd8 isMemberOfPartialAttributeSet: FALSE objectCategory: CN=Attribute-Schema,${SCHEMADN} # # ms-Exch-Routing-Enabled # This flag enables or disables the routing for the entire # organization. # dn: CN=ms-Exch-Routing-Enabled,${SCHEMADN} objectClass: top objectClass: attributeSchema cn: ms-Exch-Routing-Enabled distinguishedName: CN=ms-Exch-Routing-Enabled,${SCHEMADN} attributeID: 1.2.840.113556.1.4.7000.102.12528 attributeSyntax: 2.5.5.8 isSingleValued: TRUE showInAdvancedViewOnly: TRUE adminDisplayName: ms-Exch-Routing-Enabled adminDescription: ms-Exch-Routing-Enabled oMSyntax: 1 searchFlags: 0 lDAPDisplayName: msExchRoutingEnabled name: ms-Exch-Routing-Enabled schemaIDGUID: 89f1cdd4-b09e-11d2-aa06-00c04f8eedd8 isMemberOfPartialAttributeSet: FALSE objectCategory: CN=Attribute-Schema,${SCHEMADN} # # ms-Exch-Routing-ETRN-Domains # Contains the list of domain names (such as example.com) for which an # ETRN command should be issued. # dn: CN=ms-Exch-Routing-ETRN-Domains,${SCHEMADN} objectClass: top objectClass: attributeSchema cn: ms-Exch-Routing-ETRN-Domains distinguishedName: CN=ms-Exch-Routing-ETRN-Domains,${SCHEMADN} attributeID: 1.2.840.113556.1.4.7000.102.12530 attributeSyntax: 2.5.5.12 isSingleValued: FALSE showInAdvancedViewOnly: TRUE adminDisplayName: ms-Exch-Routing-ETRN-Domains adminDescription: ms-Exch-Routing-ETRN-Domains oMSyntax: 64 searchFlags: 0 lDAPDisplayName: msExchRoutingETRNDomains name: ms-Exch-Routing-ETRN-Domains schemaIDGUID: 62a383c0-2d9d-11d3-aa6b-00c04f8eedd8 isMemberOfPartialAttributeSet: FALSE objectCategory: CN=Attribute-Schema,${SCHEMADN} # # ms-Exch-Routing-Group-Members-BL # dn: CN=ms-Exch-Routing-Group-Members-BL,${SCHEMADN} objectClass: top objectClass: attributeSchema cn: ms-Exch-Routing-Group-Members-BL distinguishedName: CN=ms-Exch-Routing-Group-Members-BL,${SCHEMADN} attributeID: 1.2.840.113556.1.4.7000.102.12540 attributeSyntax: 2.5.5.1 isSingleValued: FALSE linkID: 1051 showInAdvancedViewOnly: TRUE adminDisplayName: ms-Exch-Routing-Group-Members-BL oMObjectClass:: KwwCh3McAIVK adminDescription: ms-Exch-Routing-Group-Members-BL oMSyntax: 127 searchFlags: 0 lDAPDisplayName: msExchRoutingGroupMembersBL name: ms-Exch-Routing-Group-Members-BL schemaIDGUID: fa9635c0-4acb-47de-ad00-1880b590481b systemFlags: 1 isMemberOfPartialAttributeSet: FALSE objectCategory: CN=Attribute-Schema,${SCHEMADN} # # ms-Exch-Routing-Group-Members-DN # Pointers to virtual servers of servers in a Exchange Routing Group. # dn: CN=ms-Exch-Routing-Group-Members-DN,${SCHEMADN} objectClass: top objectClass: attributeSchema cn: ms-Exch-Routing-Group-Members-DN distinguishedName: CN=ms-Exch-Routing-Group-Members-DN,${SCHEMADN} attributeID: 1.2.840.113556.1.4.7000.102.12506 attributeSyntax: 2.5.5.1 isSingleValued: FALSE linkID: 1000 showInAdvancedViewOnly: TRUE adminDisplayName: ms-Exch-Routing-Group-Members-DN oMObjectClass:: KwwCh3McAIVK adminDescription: ms-Exch-Routing-Group-Members-DN oMSyntax: 127 searchFlags: 1 lDAPDisplayName: msExchRoutingGroupMembersDN name: ms-Exch-Routing-Group-Members-DN schemaIDGUID: 1ff9ed9a-b098-11d2-aa06-00c04f8eedd8 isMemberOfPartialAttributeSet: FALSE objectCategory: CN=Attribute-Schema,${SCHEMADN} # # ms-Exch-Routing-List # The address space of addresses allowed to be used on the connector. # dn: CN=ms-Exch-Routing-List,${SCHEMADN} objectClass: top objectClass: attributeSchema cn: ms-Exch-Routing-List distinguishedName: CN=ms-Exch-Routing-List,${SCHEMADN} attributeID: 1.2.840.113556.1.2.354 attributeSyntax: 2.5.5.4 isSingleValued: FALSE rangeLower: 1 rangeUpper: 2243 mAPIID: 33062 showInAdvancedViewOnly: TRUE adminDisplayName: ms-Exch-Routing-List adminDescription: ms-Exch-Routing-List oMSyntax: 20 searchFlags: 0 lDAPDisplayName: routingList name: ms-Exch-Routing-List schemaIDGUID: a8df7467-c5ea-11d1-bbcb-0080c76670c0 isMemberOfPartialAttributeSet: FALSE objectCategory: CN=Attribute-Schema,${SCHEMADN} # # ms-Exch-Routing-Master-DN # A pointer to the virtual server of the master of the Exchange # Routing Group. # dn: CN=ms-Exch-Routing-Master-DN,${SCHEMADN} objectClass: top objectClass: attributeSchema cn: ms-Exch-Routing-Master-DN distinguishedName: CN=ms-Exch-Routing-Master-DN,${SCHEMADN} attributeID: 1.2.840.113556.1.4.7000.102.12505 attributeSyntax: 2.5.5.1 isSingleValued: TRUE showInAdvancedViewOnly: TRUE adminDisplayName: ms-Exch-Routing-Master-DN oMObjectClass:: KwwCh3McAIVK adminDescription: ms-Exch-Routing-Master-DN oMSyntax: 127 searchFlags: 0 lDAPDisplayName: msExchRoutingMasterDN name: ms-Exch-Routing-Master-DN schemaIDGUID: 2024d7ee-b098-11d2-aa06-00c04f8eedd8 isMemberOfPartialAttributeSet: FALSE objectCategory: CN=Attribute-Schema,${SCHEMADN} # # ms-Exch-Routing-Oversized-Schedule # dn: CN=ms-Exch-Routing-Oversized-Schedule,${SCHEMADN} objectClass: top objectClass: attributeSchema cn: ms-Exch-Routing-Oversized-Schedule distinguishedName: CN=ms-Exch-Routing-Oversized-Schedule,${SCHEMADN} attributeID: 1.2.840.113556.1.4.7000.102.12520 attributeSyntax: 2.5.5.10 isSingleValued: TRUE showInAdvancedViewOnly: TRUE adminDisplayName: ms-Exch-Routing-Oversized-Schedule adminDescription: ms-Exch-Routing-Oversized-Schedule oMSyntax: 4 searchFlags: 0 lDAPDisplayName: msExchRoutingOversizedSchedule name: ms-Exch-Routing-Oversized-Schedule schemaIDGUID: 88f51490-b09e-11d2-aa06-00c04f8eedd8 isMemberOfPartialAttributeSet: FALSE objectCategory: CN=Attribute-Schema,${SCHEMADN} # # ms-Exch-Routing-Oversized-Style # dn: CN=ms-Exch-Routing-Oversized-Style,${SCHEMADN} objectClass: top objectClass: attributeSchema cn: ms-Exch-Routing-Oversized-Style distinguishedName: CN=ms-Exch-Routing-Oversized-Style,${SCHEMADN} attributeID: 1.2.840.113556.1.4.7000.102.12521 attributeSyntax: 2.5.5.9 isSingleValued: TRUE showInAdvancedViewOnly: TRUE adminDisplayName: ms-Exch-Routing-Oversized-Style adminDescription: ms-Exch-Routing-Oversized-Style oMSyntax: 2 searchFlags: 0 lDAPDisplayName: msExchRoutingOversizedStyle name: ms-Exch-Routing-Oversized-Style schemaIDGUID: 89141322-b09e-11d2-aa06-00c04f8eedd8 isMemberOfPartialAttributeSet: FALSE objectCategory: CN=Attribute-Schema,${SCHEMADN} # # ms-Exch-Routing-Triggered-Schedule # dn: CN=ms-Exch-Routing-Triggered-Schedule,${SCHEMADN} objectClass: top objectClass: attributeSchema cn: ms-Exch-Routing-Triggered-Schedule distinguishedName: CN=ms-Exch-Routing-Triggered-Schedule,${SCHEMADN} attributeID: 1.2.840.113556.1.4.7000.102.12526 attributeSyntax: 2.5.5.10 isSingleValued: TRUE showInAdvancedViewOnly: TRUE adminDisplayName: ms-Exch-Routing-Triggered-Schedule adminDescription: ms-Exch-Routing-Triggered-Schedule oMSyntax: 4 searchFlags: 0 lDAPDisplayName: msExchRoutingTriggeredSchedule name: ms-Exch-Routing-Triggered-Schedule schemaIDGUID: 892e4d00-b09e-11d2-aa06-00c04f8eedd8 isMemberOfPartialAttributeSet: FALSE objectCategory: CN=Attribute-Schema,${SCHEMADN} # # ms-Exch-Routing-Triggered-Style # dn: CN=ms-Exch-Routing-Triggered-Style,${SCHEMADN} objectClass: top objectClass: attributeSchema cn: ms-Exch-Routing-Triggered-Style distinguishedName: CN=ms-Exch-Routing-Triggered-Style,${SCHEMADN} attributeID: 1.2.840.113556.1.4.7000.102.12525 attributeSyntax: 2.5.5.9 isSingleValued: TRUE showInAdvancedViewOnly: TRUE adminDisplayName: ms-Exch-Routing-Triggered-Style adminDescription: ms-Exch-Routing-Triggered-Style oMSyntax: 2 searchFlags: 0 lDAPDisplayName: msExchRoutingTriggeredStyle name: ms-Exch-Routing-Triggered-Style schemaIDGUID: 894ae938-b09e-11d2-aa06-00c04f8eedd8 isMemberOfPartialAttributeSet: FALSE objectCategory: CN=Attribute-Schema,${SCHEMADN} # # ms-Exch-RTS-Checkpoint-Size # dn: CN=ms-Exch-RTS-Checkpoint-Size,${SCHEMADN} objectClass: top objectClass: attributeSchema cn: ms-Exch-RTS-Checkpoint-Size distinguishedName: CN=ms-Exch-RTS-Checkpoint-Size,${SCHEMADN} attributeID: 1.2.840.113556.1.2.152 attributeSyntax: 2.5.5.9 isSingleValued: TRUE rangeLower: 0 rangeUpper: 100 mAPIID: 33063 showInAdvancedViewOnly: TRUE adminDisplayName: ms-Exch-RTS-Checkpoint-Size adminDescription: ms-Exch-RTS-Checkpoint-Size oMSyntax: 2 searchFlags: 0 lDAPDisplayName: rTSCheckpointSize name: ms-Exch-RTS-Checkpoint-Size schemaIDGUID: a8df7468-c5ea-11d1-bbcb-0080c76670c0 isMemberOfPartialAttributeSet: FALSE objectCategory: CN=Attribute-Schema,${SCHEMADN} # # ms-Exch-RTS-Recovery-Timeout # dn: CN=ms-Exch-RTS-Recovery-Timeout,${SCHEMADN} objectClass: top objectClass: attributeSchema cn: ms-Exch-RTS-Recovery-Timeout distinguishedName: CN=ms-Exch-RTS-Recovery-Timeout,${SCHEMADN} attributeID: 1.2.840.113556.1.2.151 attributeSyntax: 2.5.5.9 isSingleValued: TRUE rangeLower: 0 rangeUpper: 32767 mAPIID: 33064 showInAdvancedViewOnly: TRUE adminDisplayName: ms-Exch-RTS-Recovery-Timeout adminDescription: ms-Exch-RTS-Recovery-Timeout oMSyntax: 2 searchFlags: 0 lDAPDisplayName: rTSRecoveryTimeout name: ms-Exch-RTS-Recovery-Timeout schemaIDGUID: a8df7469-c5ea-11d1-bbcb-0080c76670c0 isMemberOfPartialAttributeSet: FALSE objectCategory: CN=Attribute-Schema,${SCHEMADN} # # ms-Exch-RTS-Window-Size # dn: CN=ms-Exch-RTS-Window-Size,${SCHEMADN} objectClass: top objectClass: attributeSchema cn: ms-Exch-RTS-Window-Size distinguishedName: CN=ms-Exch-RTS-Window-Size,${SCHEMADN} attributeID: 1.2.840.113556.1.2.153 attributeSyntax: 2.5.5.9 isSingleValued: TRUE rangeLower: 0 rangeUpper: 10 mAPIID: 33065 showInAdvancedViewOnly: TRUE adminDisplayName: ms-Exch-RTS-Window-Size adminDescription: ms-Exch-RTS-Window-Size oMSyntax: 2 searchFlags: 0 lDAPDisplayName: rTSWindowSize name: ms-Exch-RTS-Window-Size schemaIDGUID: a8df746a-c5ea-11d1-bbcb-0080c76670c0 isMemberOfPartialAttributeSet: FALSE objectCategory: CN=Attribute-Schema,${SCHEMADN} # # ms-Exch-Runs-On # dn: CN=ms-Exch-Runs-On,${SCHEMADN} objectClass: top objectClass: attributeSchema cn: ms-Exch-Runs-On distinguishedName: CN=ms-Exch-Runs-On,${SCHEMADN} attributeID: 1.2.840.113556.1.2.185 attributeSyntax: 2.5.5.1 isSingleValued: FALSE mAPIID: 33066 showInAdvancedViewOnly: TRUE adminDisplayName: ms-Exch-Runs-On oMObjectClass:: KwwCh3McAIVK adminDescription: ms-Exch-Runs-On oMSyntax: 127 searchFlags: 0 lDAPDisplayName: runsOn name: ms-Exch-Runs-On schemaIDGUID: a8df746b-c5ea-11d1-bbcb-0080c76670c0 isMemberOfPartialAttributeSet: FALSE objectCategory: CN=Attribute-Schema,${SCHEMADN} # # ms-Exch-Sasl-Logon-Domain # The logon domain used for SASL. dn: CN=ms-Exch-Sasl-Logon-Domain,${SCHEMADN} objectClass: top objectClass: attributeSchema cn: ms-Exch-Sasl-Logon-Domain distinguishedName: CN=ms-Exch-Sasl-Logon-Domain,${SCHEMADN} attributeID: 1.2.840.113556.1.4.7000.102.2008 attributeSyntax: 2.5.5.12 isSingleValued: TRUE showInAdvancedViewOnly: TRUE adminDisplayName: ms-Exch-Sasl-Logon-Domain adminDescription: ms-Exch-Sasl-Logon-Domain oMSyntax: 64 searchFlags: 0 lDAPDisplayName: msExchSaslLogonDomain name: ms-Exch-Sasl-Logon-Domain schemaIDGUID: 209c0d82-b098-11d2-aa06-00c04f8eedd8 isMemberOfPartialAttributeSet: FALSE objectCategory: CN=Attribute-Schema,${SCHEMADN} # # ms-Exch-SASL-Mechanisms # dn: CN=ms-Exch-SASL-Mechanisms,${SCHEMADN} objectClass: top objectClass: attributeSchema cn: ms-Exch-SASL-Mechanisms distinguishedName: CN=ms-Exch-SASL-Mechanisms,${SCHEMADN} attributeID: 1.2.840.113556.1.4.7000.102.2018 attributeSyntax: 2.5.5.12 isSingleValued: FALSE showInAdvancedViewOnly: TRUE adminDisplayName: ms-Exch-SASL-Mechanisms adminDescription: ms-Exch-SASL-Mechanisms oMSyntax: 64 searchFlags: 0 lDAPDisplayName: msExchSASLMechanisms name: ms-Exch-SASL-Mechanisms schemaIDGUID: d93571b4-c99a-4cfc-aaba-2d809fd68e79 isMemberOfPartialAttributeSet: FALSE objectCategory: CN=Attribute-Schema,${SCHEMADN} # # ms-Exch-Sched-Plus-AG-Only # dn: CN=ms-Exch-Sched-Plus-AG-Only,${SCHEMADN} objectClass: top objectClass: attributeSchema cn: ms-Exch-Sched-Plus-AG-Only distinguishedName: CN=ms-Exch-Sched-Plus-AG-Only,${SCHEMADN} attributeID: 1.2.840.113556.1.4.7000.102.1191 attributeSyntax: 2.5.5.8 isSingleValued: TRUE showInAdvancedViewOnly: TRUE adminDisplayName: ms-Exch-Sched-Plus-AG-Only adminDescription: ms-Exch-Sched-Plus-AG-Only oMSyntax: 1 searchFlags: 0 lDAPDisplayName: msExchSchedPlusAGOnly name: ms-Exch-Sched-Plus-AG-Only schemaIDGUID: b1fce956-1d44-11d3-aa5e-00c04f8eedd8 isMemberOfPartialAttributeSet: FALSE objectCategory: CN=Attribute-Schema,${SCHEMADN} # # ms-Exch-Sched-Plus-Full-Update # dn: CN=ms-Exch-Sched-Plus-Full-Update,${SCHEMADN} objectClass: top objectClass: attributeSchema cn: ms-Exch-Sched-Plus-Full-Update distinguishedName: CN=ms-Exch-Sched-Plus-Full-Update,${SCHEMADN} attributeID: 1.2.840.113556.1.4.7000.102.1190 attributeSyntax: 2.5.5.8 isSingleValued: TRUE showInAdvancedViewOnly: TRUE adminDisplayName: ms-Exch-Sched-Plus-Full-Update adminDescription: ms-Exch-Sched-Plus-Full-Update oMSyntax: 1 searchFlags: 0 lDAPDisplayName: msExchSchedPlusFullUpdate name: ms-Exch-Sched-Plus-Full-Update schemaIDGUID: b1fce950-1d44-11d3-aa5e-00c04f8eedd8 isMemberOfPartialAttributeSet: FALSE objectCategory: CN=Attribute-Schema,${SCHEMADN} # # ms-Exch-Sched-Plus-Schedist # dn: CN=ms-Exch-Sched-Plus-Schedist,${SCHEMADN} objectClass: top objectClass: attributeSchema cn: ms-Exch-Sched-Plus-Schedist distinguishedName: CN=ms-Exch-Sched-Plus-Schedist,${SCHEMADN} attributeID: 1.2.840.113556.1.4.7000.102.1192 attributeSyntax: 2.5.5.1 isSingleValued: TRUE showInAdvancedViewOnly: TRUE adminDisplayName: ms-Exch-Sched-Plus-Schedist oMObjectClass:: KwwCh3McAIVK adminDescription: ms-Exch-Sched-Plus-Schedist oMSyntax: 127 searchFlags: 0 lDAPDisplayName: msExchSchedPlusSchedist name: ms-Exch-Sched-Plus-Schedist schemaIDGUID: b1fce94c-1d44-11d3-aa5e-00c04f8eedd8 isMemberOfPartialAttributeSet: FALSE objectCategory: CN=Attribute-Schema,${SCHEMADN} # # ms-Exch-Schema-Policy-Consumers # A link to all CAs that use this schema policy. # dn: CN=ms-Exch-Schema-Policy-Consumers,${SCHEMADN} objectClass: top objectClass: attributeSchema cn: ms-Exch-Schema-Policy-Consumers distinguishedName: CN=ms-Exch-Schema-Policy-Consumers,${SCHEMADN} attributeID: 1.2.840.113556.1.4.7000.102.57 attributeSyntax: 2.5.5.1 isSingleValued: FALSE linkID: 1007 showInAdvancedViewOnly: TRUE adminDisplayName: ms-Exch-Schema-Policy-Consumers oMObjectClass:: KwwCh3McAIVK adminDescription: ms-Exch-Schema-Policy-Consumers oMSyntax: 127 searchFlags: 0 lDAPDisplayName: msExchSchemaPolicyConsumers name: ms-Exch-Schema-Policy-Consumers schemaIDGUID: 20c6f7d6-b098-11d2-aa06-00c04f8eedd8 systemFlags: 1 isMemberOfPartialAttributeSet: FALSE objectCategory: CN=Attribute-Schema,${SCHEMADN} # # ms-Exch-Schema-Version-Adc # dn: CN=ms-Exch-Schema-Version-Adc,${SCHEMADN} objectClass: top objectClass: attributeSchema cn: ms-Exch-Schema-Version-Adc distinguishedName: CN=ms-Exch-Schema-Version-Adc,${SCHEMADN} attributeID: 1.2.840.113556.1.4.7000.102.98 attributeSyntax: 2.5.5.9 isSingleValued: TRUE rangeLower: 1 rangeUpper: 4197 showInAdvancedViewOnly: TRUE adminDisplayName: ms-Exch-Schema-Version-Adc adminDescription: ms-Exch-Schema-Version-Adc oMSyntax: 2 searchFlags: 0 lDAPDisplayName: msExchSchemaVersionAdc name: ms-Exch-Schema-Version-Adc schemaIDGUID: 60735c93-c60e-405e-b5ea-cb31f68ad548 isMemberOfPartialAttributeSet: FALSE objectCategory: CN=Attribute-Schema,${SCHEMADN} # # ms-Exch-Schema-Version-Pt # dn: CN=ms-Exch-Schema-Version-Pt,${SCHEMADN} objectClass: top objectClass: attributeSchema cn: ms-Exch-Schema-Version-Pt distinguishedName: CN=ms-Exch-Schema-Version-Pt,${SCHEMADN} attributeID: 1.2.840.113556.1.4.7000.102.97 attributeSyntax: 2.5.5.9 isSingleValued: TRUE rangeLower: 1 rangeUpper: 6870 showInAdvancedViewOnly: TRUE adminDisplayName: ms-Exch-Schema-Version-Pt adminDescription: ms-Exch-Schema-Version-Pt oMSyntax: 2 searchFlags: 0 lDAPDisplayName: msExchSchemaVersionPt name: ms-Exch-Schema-Version-Pt schemaIDGUID: 5f8198d5-e7c9-4560-b166-08dc7cfc17c1 isMemberOfPartialAttributeSet: FALSE objectCategory: CN=Attribute-Schema,${SCHEMADN} # # ms-Exch-Scope-Mask # Defines the networks that will accept and send client connections. # dn: CN=ms-Exch-Scope-Mask,${SCHEMADN} objectClass: top objectClass: attributeSchema cn: ms-Exch-Scope-Mask distinguishedName: CN=ms-Exch-Scope-Mask,${SCHEMADN} attributeID: 1.2.840.113556.1.4.7000.102.9014 attributeSyntax: 2.5.5.12 isSingleValued: FALSE showInAdvancedViewOnly: TRUE adminDisplayName: ms-Exch-Scope-Mask adminDescription: ms-Exch-Scope-Mask oMSyntax: 64 searchFlags: 0 lDAPDisplayName: msExchScopeMask name: ms-Exch-Scope-Mask schemaIDGUID: 20fb6b92-b098-11d2-aa06-00c04f8eedd8 isMemberOfPartialAttributeSet: FALSE objectCategory: CN=Attribute-Schema,${SCHEMADN} # # ms-Exch-Search-Base # dn: CN=ms-Exch-Search-Base,${SCHEMADN} objectClass: top objectClass: attributeSchema cn: ms-Exch-Search-Base distinguishedName: CN=ms-Exch-Search-Base,${SCHEMADN} attributeID: 1.2.840.113556.1.4.7000.102.91 attributeSyntax: 2.5.5.1 isSingleValued: FALSE showInAdvancedViewOnly: TRUE adminDisplayName: ms-Exch-Search-Base oMObjectClass:: KwwCh3McAIVK adminDescription: ms-Exch-Search-Base oMSyntax: 127 searchFlags: 0 lDAPDisplayName: msExchSearchBase name: ms-Exch-Search-Base schemaIDGUID: 1884a3fe-efcb-47b0-bbd4-a91ef8cd4cb4 isMemberOfPartialAttributeSet: FALSE objectCategory: CN=Attribute-Schema,${SCHEMADN} # # ms-Exch-Search-Scope # dn: CN=ms-Exch-Search-Scope,${SCHEMADN} objectClass: top objectClass: attributeSchema cn: ms-Exch-Search-Scope distinguishedName: CN=ms-Exch-Search-Scope,${SCHEMADN} attributeID: 1.2.840.113556.1.4.7000.102.92 attributeSyntax: 2.5.5.9 isSingleValued: TRUE showInAdvancedViewOnly: TRUE adminDisplayName: ms-Exch-Search-Scope adminDescription: ms-Exch-Search-Scope oMSyntax: 2 searchFlags: 0 lDAPDisplayName: msExchSearchScope name: ms-Exch-Search-Scope schemaIDGUID: 05ed1e50-31c8-4ed2-b01e-732dbf6dd344 isMemberOfPartialAttributeSet: FALSE objectCategory: CN=Attribute-Schema,${SCHEMADN} # # ms-Exch-Secure-Bindings # The IP port binding for non-secure connections. # dn: CN=ms-Exch-Secure-Bindings,${SCHEMADN} objectClass: top objectClass: attributeSchema cn: ms-Exch-Secure-Bindings distinguishedName: CN=ms-Exch-Secure-Bindings,${SCHEMADN} attributeID: 1.2.840.113556.1.4.7000.102.2002 attributeSyntax: 2.5.5.12 isSingleValued: FALSE rangeLower: 1 rangeUpper: 512 showInAdvancedViewOnly: TRUE adminDisplayName: ms-Exch-Secure-Bindings adminDescription: ms-Exch-Secure-Bindings oMSyntax: 64 searchFlags: 0 lDAPDisplayName: msExchSecureBindings name: ms-Exch-Secure-Bindings schemaIDGUID: 216ddc72-b098-11d2-aa06-00c04f8eedd8 isMemberOfPartialAttributeSet: FALSE objectCategory: CN=Attribute-Schema,${SCHEMADN} # # ms-Exch-Security-Password # Password for outbound security. # dn: CN=ms-Exch-Security-Password,${SCHEMADN} objectClass: top objectClass: attributeSchema cn: ms-Exch-Security-Password distinguishedName: CN=ms-Exch-Security-Password,${SCHEMADN} attributeID: 1.2.840.113556.1.4.7000.102.5052 attributeSyntax: 2.5.5.10 isSingleValued: TRUE showInAdvancedViewOnly: TRUE adminDisplayName: ms-Exch-Security-Password adminDescription: ms-Exch-Security-Password oMSyntax: 4 searchFlags: 0 lDAPDisplayName: msExchSecurityPassword name: ms-Exch-Security-Password schemaIDGUID: b8d47e4e-4b78-11d3-aa75-00c04f8eedd8 isMemberOfPartialAttributeSet: FALSE objectCategory: CN=Attribute-Schema,${SCHEMADN} # # ms-Exch-Security-Policy # dn: CN=ms-Exch-Security-Policy,${SCHEMADN} objectClass: top objectClass: attributeSchema cn: ms-Exch-Security-Policy distinguishedName: CN=ms-Exch-Security-Policy,${SCHEMADN} attributeID: 1.2.840.113556.1.2.589 attributeSyntax: 2.5.5.10 isSingleValued: FALSE rangeLower: 1 rangeUpper: 32767 mAPIID: 35911 showInAdvancedViewOnly: TRUE adminDisplayName: ms-Exch-Security-Policy adminDescription: ms-Exch-Security-Policy oMSyntax: 4 searchFlags: 0 lDAPDisplayName: securityPolicy name: ms-Exch-Security-Policy schemaIDGUID: 1677587b-47f3-11d1-a9c3-0000f80367c1 isMemberOfPartialAttributeSet: FALSE objectCategory: CN=Attribute-Schema,${SCHEMADN} # # ms-Exch-Security-Protocol # dn: CN=ms-Exch-Security-Protocol,${SCHEMADN} objectClass: top objectClass: attributeSchema cn: ms-Exch-Security-Protocol distinguishedName: CN=ms-Exch-Security-Protocol,${SCHEMADN} attributeID: 1.2.840.113556.1.2.82 attributeSyntax: 2.5.5.10 isSingleValued: FALSE rangeLower: 1 rangeUpper: 1024 mAPIID: 32823 showInAdvancedViewOnly: TRUE adminDisplayName: ms-Exch-Security-Protocol adminDescription: ms-Exch-Security-Protocol oMSyntax: 4 searchFlags: 16 lDAPDisplayName: securityProtocol name: ms-Exch-Security-Protocol schemaIDGUID: bf967a30-0de6-11d0-a285-00aa003049e2 attributeSecurityGUID: e48d0154-bcf8-11d1-8702-00c04fb96050 isMemberOfPartialAttributeSet: TRUE objectCategory: CN=Attribute-Schema,${SCHEMADN} # # ms-Exch-Send-EMail-Message # dn: CN=ms-Exch-Send-EMail-Message,${SCHEMADN} objectClass: top objectClass: attributeSchema cn: ms-Exch-Send-EMail-Message distinguishedName: CN=ms-Exch-Send-EMail-Message,${SCHEMADN} attributeID: 1.2.840.113556.1.2.566 attributeSyntax: 2.5.5.8 isSingleValued: TRUE mAPIID: 35889 showInAdvancedViewOnly: TRUE adminDisplayName: ms-Exch-Send-EMail-Message adminDescription: ms-Exch-Send-EMail-Message oMSyntax: 1 searchFlags: 0 lDAPDisplayName: sendEMailMessage name: ms-Exch-Send-EMail-Message schemaIDGUID: a8df746e-c5ea-11d1-bbcb-0080c76670c0 isMemberOfPartialAttributeSet: FALSE objectCategory: CN=Attribute-Schema,${SCHEMADN} # # ms-Exch-Send-TNEF # Determines whether or not Exchange Rich Text is sent to the domain # specified in the domain content configuration object. # dn: CN=ms-Exch-Send-TNEF,${SCHEMADN} objectClass: top objectClass: attributeSchema cn: ms-Exch-Send-TNEF distinguishedName: CN=ms-Exch-Send-TNEF,${SCHEMADN} attributeID: 1.2.840.113556.1.2.492 attributeSyntax: 2.5.5.8 isSingleValued: TRUE mAPIID: 33169 showInAdvancedViewOnly: TRUE adminDisplayName: ms-Exch-Send-TNEF adminDescription: ms-Exch-Send-TNEF oMSyntax: 1 searchFlags: 0 lDAPDisplayName: sendTNEF name: ms-Exch-Send-TNEF schemaIDGUID: a8df746f-c5ea-11d1-bbcb-0080c76670c0 isMemberOfPartialAttributeSet: FALSE objectCategory: CN=Attribute-Schema,${SCHEMADN} # # ms-Exch-Server1-Always-Create-As # How X.500 objects are synchronized to this directory. # dn: CN=ms-Exch-Server1-Always-Create-As,${SCHEMADN} objectClass: top objectClass: attributeSchema cn: ms-Exch-Server1-Always-Create-As distinguishedName: CN=ms-Exch-Server1-Always-Create-As,${SCHEMADN} attributeID: 1.2.840.113556.1.4.7000.102.27 attributeSyntax: 2.5.5.9 isSingleValued: TRUE rangeLower: 0 rangeUpper: 2 showInAdvancedViewOnly: TRUE adminDisplayName: ms-Exch-Server1-Always-Create-As adminDescription: ms-Exch-Server1-Always-Create-As oMSyntax: 10 searchFlags: 0 lDAPDisplayName: msExchServer1AlwaysCreateAs name: ms-Exch-Server1-Always-Create-As schemaIDGUID: 222efaec-b098-11d2-aa06-00c04f8eedd8 isMemberOfPartialAttributeSet: FALSE objectCategory: CN=Attribute-Schema,${SCHEMADN} # # ms-Exch-Server1-Authentication-Credentials # The user name to use to log on to the server for this directory. # dn: CN=ms-Exch-Server1-Authentication-Credentials,${SCHEMADN} objectClass: top objectClass: attributeSchema cn: ms-Exch-Server1-Authentication-Credentials distinguishedName: CN=ms-Exch-Server1-Authentication-Credentials,${SCHEMADN} attributeID: 1.2.840.113556.1.4.7000.102.9 attributeSyntax: 2.5.5.12 isSingleValued: TRUE showInAdvancedViewOnly: TRUE adminDisplayName: ms-Exch-Server1-Authentication-Credentials adminDescription: ms-Exch-Server1-Authentication-Credentials oMSyntax: 64 searchFlags: 0 lDAPDisplayName: msExchServer1AuthenticationCredentials name: ms-Exch-Server1-Authentication-Credentials schemaIDGUID: 225ea9f4-b098-11d2-aa06-00c04f8eedd8 isMemberOfPartialAttributeSet: FALSE objectCategory: CN=Attribute-Schema,${SCHEMADN} # # ms-Exch-Server1-Authentication-Password # The password for the credentials specified for this directory. # dn: CN=ms-Exch-Server1-Authentication-Password,${SCHEMADN} objectClass: top objectClass: attributeSchema cn: ms-Exch-Server1-Authentication-Password distinguishedName: CN=ms-Exch-Server1-Authentication-Password,${SCHEMADN} attributeID: 1.2.840.113556.1.4.7000.102.11 attributeSyntax: 2.5.5.10 isSingleValued: TRUE showInAdvancedViewOnly: TRUE adminDisplayName: ms-Exch-Server1-Authentication-Password adminDescription: ms-Exch-Server1-Authentication-Password oMSyntax: 4 searchFlags: 0 lDAPDisplayName: msExchServer1AuthenticationPassword name: ms-Exch-Server1-Authentication-Password schemaIDGUID: 228bf6a2-b098-11d2-aa06-00c04f8eedd8 isMemberOfPartialAttributeSet: FALSE objectCategory: CN=Attribute-Schema,${SCHEMADN} # # ms-Exch-Server1-Authentication-Type # The type of authentication to the server for this directory. # dn: CN=ms-Exch-Server1-Authentication-Type,${SCHEMADN} objectClass: top objectClass: attributeSchema cn: ms-Exch-Server1-Authentication-Type distinguishedName: CN=ms-Exch-Server1-Authentication-Type,${SCHEMADN} attributeID: 1.2.840.113556.1.4.7000.102.7 attributeSyntax: 2.5.5.9 isSingleValued: TRUE rangeLower: 0 rangeUpper: 5 showInAdvancedViewOnly: TRUE adminDisplayName: ms-Exch-Server1-Authentication-Type adminDescription: ms-Exch-Server1-Authentication-Type oMSyntax: 10 searchFlags: 0 lDAPDisplayName: msExchServer1AuthenticationType name: ms-Exch-Server1-Authentication-Type schemaIDGUID: 22b94350-b098-11d2-aa06-00c04f8eedd8 isMemberOfPartialAttributeSet: FALSE objectCategory: CN=Attribute-Schema,${SCHEMADN} # # ms-Exch-Server1-Deletion-Option # A flag used to determine how deletions are synchronized into this directory. # dn: CN=ms-Exch-Server1-Deletion-Option,${SCHEMADN} objectClass: top objectClass: attributeSchema cn: ms-Exch-Server1-Deletion-Option distinguishedName: CN=ms-Exch-Server1-Deletion-Option,${SCHEMADN} attributeID: 1.2.840.113556.1.4.7000.102.21 attributeSyntax: 2.5.5.9 isSingleValued: TRUE showInAdvancedViewOnly: TRUE adminDisplayName: ms-Exch-Server1-Deletion-Option adminDescription: ms-Exch-Server1-Deletion-Option oMSyntax: 10 searchFlags: 0 lDAPDisplayName: msExchServer1DeletionOption name: ms-Exch-Server1-Deletion-Option schemaIDGUID: 22edb70c-b098-11d2-aa06-00c04f8eedd8 isMemberOfPartialAttributeSet: FALSE objectCategory: CN=Attribute-Schema,${SCHEMADN} # # ms-Exch-Server1-Export-Containers # The DN of the default container to search for objects to synchronize. # dn: CN=ms-Exch-Server1-Export-Containers,${SCHEMADN} objectClass: top objectClass: attributeSchema cn: ms-Exch-Server1-Export-Containers distinguishedName: CN=ms-Exch-Server1-Export-Containers,${SCHEMADN} attributeID: 1.2.840.113556.1.4.7000.102.13 attributeSyntax: 2.5.5.12 isSingleValued: FALSE showInAdvancedViewOnly: TRUE adminDisplayName: ms-Exch-Server1-Export-Containers adminDescription: ms-Exch-Server1-Export-Containers oMSyntax: 64 searchFlags: 0 lDAPDisplayName: msExchServer1ExportContainers name: ms-Exch-Server1-Export-Containers schemaIDGUID: 231b03ba-b098-11d2-aa06-00c04f8eedd8 isMemberOfPartialAttributeSet: FALSE objectCategory: CN=Attribute-Schema,${SCHEMADN} # # ms-Exch-Server1-Flags # Flags used for transitive replication work. # dn: CN=ms-Exch-Server1-Flags,${SCHEMADN} objectClass: top objectClass: attributeSchema cn: ms-Exch-Server1-Flags distinguishedName: CN=ms-Exch-Server1-Flags,${SCHEMADN} attributeID: 1.2.840.113556.1.4.7000.102.61 attributeSyntax: 2.5.5.9 isSingleValued: TRUE showInAdvancedViewOnly: TRUE adminDisplayName: ms-Exch-Server1-Flags adminDescription: ms-Exch-Server1-Flags oMSyntax: 2 searchFlags: 0 lDAPDisplayName: msExchServer1Flags name: ms-Exch-Server1-Flags schemaIDGUID: 234d151c-b098-11d2-aa06-00c04f8eedd8 isMemberOfPartialAttributeSet: FALSE objectCategory: CN=Attribute-Schema,${SCHEMADN} # # ms-Exch-Server1-Highest-USN # The highwater mark update sequence number (USN) from the last # successful synchronization from this directory. # dn: CN=ms-Exch-Server1-Highest-USN,${SCHEMADN} objectClass: top objectClass: attributeSchema cn: ms-Exch-Server1-Highest-USN distinguishedName: CN=ms-Exch-Server1-Highest-USN,${SCHEMADN} attributeID: 1.2.840.113556.1.4.7000.102.29 attributeSyntax: 2.5.5.16 isSingleValued: TRUE showInAdvancedViewOnly: TRUE adminDisplayName: ms-Exch-Server1-Highest-USN adminDescription: ms-Exch-Server1-Highest-USN oMSyntax: 65 searchFlags: 0 lDAPDisplayName: msExchServer1HighestUSN name: ms-Exch-Server1-Highest-USN schemaIDGUID: 237f267e-b098-11d2-aa06-00c04f8eedd8 isMemberOfPartialAttributeSet: FALSE objectCategory: CN=Attribute-Schema,${SCHEMADN} # # ms-Exch-Server1-Highest-USN-Vector # Stores the vectors of update sequence numbers (USNs) and servers for # a given naming context (NC). # dn: CN=ms-Exch-Server1-Highest-USN-Vector,${SCHEMADN} objectClass: top objectClass: attributeSchema cn: ms-Exch-Server1-Highest-USN-Vector distinguishedName: CN=ms-Exch-Server1-Highest-USN-Vector,${SCHEMADN} attributeID: 1.2.840.113556.1.4.7000.102.86 attributeSyntax: 2.5.5.12 isSingleValued: FALSE showInAdvancedViewOnly: TRUE adminDisplayName: ms-Exch-Server1-Highest-USN-Vector adminDescription: ms-Exch-Server1-Highest-USN-Vector oMSyntax: 64 searchFlags: 0 lDAPDisplayName: msExchServer1HighestUSNVector name: ms-Exch-Server1-Highest-USN-Vector schemaIDGUID: 7fb58cd4-2a6e-11d3-aa6b-00c04f8eedd8 isMemberOfPartialAttributeSet: FALSE objectCategory: CN=Attribute-Schema,${SCHEMADN} # # ms-Exch-Server1-Import-Container # The DN of the default container to write synchronized objects to. # dn: CN=ms-Exch-Server1-Import-Container,${SCHEMADN} objectClass: top objectClass: attributeSchema cn: ms-Exch-Server1-Import-Container distinguishedName: CN=ms-Exch-Server1-Import-Container,${SCHEMADN} attributeID: 1.2.840.113556.1.4.7000.102.15 attributeSyntax: 2.5.5.12 isSingleValued: TRUE showInAdvancedViewOnly: TRUE adminDisplayName: ms-Exch-Server1-Import-Container adminDescription: ms-Exch-Server1-Import-Container oMSyntax: 64 searchFlags: 0 lDAPDisplayName: msExchServer1ImportContainer name: ms-Exch-Server1-Import-Container schemaIDGUID: 23aed586-b098-11d2-aa06-00c04f8eedd8 isMemberOfPartialAttributeSet: FALSE objectCategory: CN=Attribute-Schema,${SCHEMADN} # # ms-Exch-Server1-Is-Bridgehead # A flag to determine whether non-mailbox associated objects are # replicated over this particular connection agreement. # dn: CN=ms-Exch-Server1-Is-Bridgehead,${SCHEMADN} objectClass: top objectClass: attributeSchema cn: ms-Exch-Server1-Is-Bridgehead distinguishedName: CN=ms-Exch-Server1-Is-Bridgehead,${SCHEMADN} attributeID: 1.2.840.113556.1.4.7000.102.77 attributeSyntax: 2.5.5.8 isSingleValued: TRUE showInAdvancedViewOnly: TRUE adminDisplayName: ms-Exch-Server1-Is-Bridgehead adminDescription: ms-Exch-Server1-Is-Bridgehead oMSyntax: 1 searchFlags: 0 lDAPDisplayName: msExchServer1IsBridgehead name: ms-Exch-Server1-Is-Bridgehead schemaIDGUID: 90b71b6a-b09e-11d2-aa06-00c04f8eedd8 isMemberOfPartialAttributeSet: FALSE objectCategory: CN=Attribute-Schema,${SCHEMADN} # # ms-Exch-Server1-Last-Update-Time # The time of the most recent update from the last successful # synchronization from this directory. # dn: CN=ms-Exch-Server1-Last-Update-Time,${SCHEMADN} objectClass: top objectClass: attributeSchema cn: ms-Exch-Server1-Last-Update-Time distinguishedName: CN=ms-Exch-Server1-Last-Update-Time,${SCHEMADN} attributeID: 1.2.840.113556.1.4.7000.102.31 attributeSyntax: 2.5.5.11 isSingleValued: TRUE showInAdvancedViewOnly: TRUE adminDisplayName: ms-Exch-Server1-Last-Update-Time adminDescription: ms-Exch-Server1-Last-Update-Time oMSyntax: 24 searchFlags: 0 lDAPDisplayName: msExchServer1LastUpdateTime name: ms-Exch-Server1-Last-Update-Time schemaIDGUID: 23e34942-b098-11d2-aa06-00c04f8eedd8 isMemberOfPartialAttributeSet: FALSE objectCategory: CN=Attribute-Schema,${SCHEMADN} # # ms-Exch-Server1-Network-Address # The network address of the server participating in this connection # agreement. # dn: CN=ms-Exch-Server1-Network-Address,${SCHEMADN} objectClass: top objectClass: attributeSchema cn: ms-Exch-Server1-Network-Address distinguishedName: CN=ms-Exch-Server1-Network-Address,${SCHEMADN} attributeID: 1.2.840.113556.1.4.7000.102.3 attributeSyntax: 2.5.5.12 isSingleValued: TRUE rangeLower: 0 rangeUpper: 65535 showInAdvancedViewOnly: TRUE adminDisplayName: ms-Exch-Server1-Network-Address adminDescription: ms-Exch-Server1-Network-Address oMSyntax: 64 searchFlags: 0 lDAPDisplayName: msExchServer1NetworkAddress name: ms-Exch-Server1-Network-Address schemaIDGUID: 2412f84a-b098-11d2-aa06-00c04f8eedd8 isMemberOfPartialAttributeSet: FALSE objectCategory: CN=Attribute-Schema,${SCHEMADN} # # ms-Exch-Server1-NT-Account-Domain # Domain in which Active Directory accounts should be created. # dn: CN=ms-Exch-Server1-NT-Account-Domain,${SCHEMADN} objectClass: top objectClass: attributeSchema cn: ms-Exch-Server1-NT-Account-Domain distinguishedName: CN=ms-Exch-Server1-NT-Account-Domain,${SCHEMADN} attributeID: 1.2.840.113556.1.4.7000.102.50 attributeSyntax: 2.5.5.12 isSingleValued: TRUE showInAdvancedViewOnly: TRUE adminDisplayName: ms-Exch-Server1-NT-Account-Domain adminDescription: ms-Exch-Server1-NT-Account-Domain oMSyntax: 64 searchFlags: 0 lDAPDisplayName: msExchServer1NTAccountDomain name: ms-Exch-Server1-NT-Account-Domain schemaIDGUID: 2449ce60-b098-11d2-aa06-00c04f8eedd8 isMemberOfPartialAttributeSet: FALSE objectCategory: CN=Attribute-Schema,${SCHEMADN} # # ms-Exch-Server1-Object-Match # Contains the matching rules for this server. # dn: CN=ms-Exch-Server1-Object-Match,${SCHEMADN} objectClass: top objectClass: attributeSchema cn: ms-Exch-Server1-Object-Match distinguishedName: CN=ms-Exch-Server1-Object-Match,${SCHEMADN} attributeID: 1.2.840.113556.1.4.7000.102.54 attributeSyntax: 2.5.5.12 isSingleValued: TRUE showInAdvancedViewOnly: TRUE adminDisplayName: ms-Exch-Server1-Object-Match adminDescription: ms-Exch-Server1-Object-Match oMSyntax: 64 searchFlags: 0 lDAPDisplayName: msExchServer1ObjectMatch name: ms-Exch-Server1-Object-Match schemaIDGUID: 247bdfc2-b098-11d2-aa06-00c04f8eedd8 isMemberOfPartialAttributeSet: FALSE objectCategory: CN=Attribute-Schema,${SCHEMADN} # # ms-Exch-Server1-Page-Size # The page size to request when searching this directory. # dn: CN=ms-Exch-Server1-Page-Size,${SCHEMADN} objectClass: top objectClass: attributeSchema cn: ms-Exch-Server1-Page-Size distinguishedName: CN=ms-Exch-Server1-Page-Size,${SCHEMADN} attributeID: 1.2.840.113556.1.4.7000.102.25 attributeSyntax: 2.5.5.9 isSingleValued: TRUE rangeLower: 0 rangeUpper: 65535 showInAdvancedViewOnly: TRUE adminDisplayName: ms-Exch-Server1-Page-Size adminDescription: ms-Exch-Server1-Page-Size oMSyntax: 2 searchFlags: 0 lDAPDisplayName: msExchServer1PageSize name: ms-Exch-Server1-Page-Size schemaIDGUID: 24b0537e-b098-11d2-aa06-00c04f8eedd8 isMemberOfPartialAttributeSet: FALSE objectCategory: CN=Attribute-Schema,${SCHEMADN} # # ms-Exch-Server1-Port # The LDAP port of the server for this directory. # dn: CN=ms-Exch-Server1-Port,${SCHEMADN} objectClass: top objectClass: attributeSchema cn: ms-Exch-Server1-Port distinguishedName: CN=ms-Exch-Server1-Port,${SCHEMADN} attributeID: 1.2.840.113556.1.4.7000.102.5 attributeSyntax: 2.5.5.9 isSingleValued: TRUE rangeLower: 0 rangeUpper: 65535 showInAdvancedViewOnly: TRUE adminDisplayName: ms-Exch-Server1-Port adminDescription: ms-Exch-Server1-Port oMSyntax: 2 searchFlags: 0 lDAPDisplayName: msExchServer1Port name: ms-Exch-Server1-Port schemaIDGUID: 24e264e0-b098-11d2-aa06-00c04f8eedd8 isMemberOfPartialAttributeSet: FALSE objectCategory: CN=Attribute-Schema,${SCHEMADN} # # ms-Exch-Server1-Schema-Map # The schema map to use when mapping from Active Directory to the # Exchange Directory Service (DS). # dn: CN=ms-Exch-Server1-Schema-Map,${SCHEMADN} objectClass: top objectClass: attributeSchema cn: ms-Exch-Server1-Schema-Map distinguishedName: CN=ms-Exch-Server1-Schema-Map,${SCHEMADN} attributeID: 1.2.840.113556.1.4.7000.102.17 attributeSyntax: 2.5.5.12 isSingleValued: TRUE showInAdvancedViewOnly: TRUE adminDisplayName: ms-Exch-Server1-Schema-Map adminDescription: ms-Exch-Server1-Schema-Map oMSyntax: 64 searchFlags: 0 lDAPDisplayName: msExchServer1SchemaMap name: ms-Exch-Server1-Schema-Map schemaIDGUID: 25193af6-b098-11d2-aa06-00c04f8eedd8 isMemberOfPartialAttributeSet: FALSE objectCategory: CN=Attribute-Schema,${SCHEMADN} # # ms-Exch-Server1-Search-Filter # The search filter to use when searching this directory. # dn: CN=ms-Exch-Server1-Search-Filter,${SCHEMADN} objectClass: top objectClass: attributeSchema cn: ms-Exch-Server1-Search-Filter distinguishedName: CN=ms-Exch-Server1-Search-Filter,${SCHEMADN} attributeID: 1.2.840.113556.1.4.7000.102.19 attributeSyntax: 2.5.5.12 isSingleValued: TRUE showInAdvancedViewOnly: TRUE adminDisplayName: ms-Exch-Server1-Search-Filter adminDescription: ms-Exch-Server1-Search-Filter oMSyntax: 64 searchFlags: 0 lDAPDisplayName: msExchServer1SearchFilter name: ms-Exch-Server1-Search-Filter schemaIDGUID: 254daeb2-b098-11d2-aa06-00c04f8eedd8 isMemberOfPartialAttributeSet: FALSE objectCategory: CN=Attribute-Schema,${SCHEMADN} # # ms-Exch-Server1-SSL-Port # The port to connect to for Secure Sockets Layer (SSL) connections. # dn: CN=ms-Exch-Server1-SSL-Port,${SCHEMADN} objectClass: top objectClass: attributeSchema cn: ms-Exch-Server1-SSL-Port distinguishedName: CN=ms-Exch-Server1-SSL-Port,${SCHEMADN} attributeID: 1.2.840.113556.1.4.7000.102.39 attributeSyntax: 2.5.5.9 isSingleValued: TRUE rangeLower: 0 rangeUpper: 65535 showInAdvancedViewOnly: TRUE adminDisplayName: ms-Exch-Server1-SSL-Port adminDescription: ms-Exch-Server1-SSL-Port oMSyntax: 2 searchFlags: 0 lDAPDisplayName: msExchServer1SSLPort name: ms-Exch-Server1-SSL-Port schemaIDGUID: 258484c8-b098-11d2-aa06-00c04f8eedd8 isMemberOfPartialAttributeSet: FALSE objectCategory: CN=Attribute-Schema,${SCHEMADN} # # ms-Exch-Server1-Type # Identifies the type of server being connected to. # dn: CN=ms-Exch-Server1-Type,${SCHEMADN} objectClass: top objectClass: attributeSchema cn: ms-Exch-Server1-Type distinguishedName: CN=ms-Exch-Server1-Type,${SCHEMADN} attributeID: 1.2.840.113556.1.4.7000.102.23 attributeSyntax: 2.5.5.9 isSingleValued: TRUE rangeLower: 0 rangeUpper: 5 showInAdvancedViewOnly: TRUE adminDisplayName: ms-Exch-Server1-Type adminDescription: ms-Exch-Server1-Type oMSyntax: 10 searchFlags: 0 lDAPDisplayName: msExchServer1Type name: ms-Exch-Server1-Type schemaIDGUID: 25bb5ade-b098-11d2-aa06-00c04f8eedd8 isMemberOfPartialAttributeSet: FALSE objectCategory: CN=Attribute-Schema,${SCHEMADN} # # ms-Exch-Server2-Always-Create-As # How X.500 objects are synchronized to this directory. # dn: CN=ms-Exch-Server2-Always-Create-As,${SCHEMADN} objectClass: top objectClass: attributeSchema cn: ms-Exch-Server2-Always-Create-As distinguishedName: CN=ms-Exch-Server2-Always-Create-As,${SCHEMADN} attributeID: 1.2.840.113556.1.4.7000.102.28 attributeSyntax: 2.5.5.9 isSingleValued: TRUE rangeLower: 0 rangeUpper: 2 showInAdvancedViewOnly: TRUE adminDisplayName: ms-Exch-Server2-Always-Create-As adminDescription: ms-Exch-Server2-Always-Create-As oMSyntax: 10 searchFlags: 0 lDAPDisplayName: msExchServer2AlwaysCreateAs name: ms-Exch-Server2-Always-Create-As schemaIDGUID: 25f95802-b098-11d2-aa06-00c04f8eedd8 isMemberOfPartialAttributeSet: FALSE objectCategory: CN=Attribute-Schema,${SCHEMADN} # # ms-Exch-Server2-Authentication-Credentials # The user name to use to log on to the server for this directory. dn: CN=ms-Exch-Server2-Authentication-Credentials,${SCHEMADN} objectClass: top objectClass: attributeSchema cn: ms-Exch-Server2-Authentication-Credentials distinguishedName: CN=ms-Exch-Server2-Authentication-Credentials,${SCHEMADN} attributeID: 1.2.840.113556.1.4.7000.102.10 attributeSyntax: 2.5.5.12 isSingleValued: TRUE showInAdvancedViewOnly: TRUE adminDisplayName: ms-Exch-Server2-Authentication-Credentials adminDescription: ms-Exch-Server2-Authentication-Credentials oMSyntax: 64 searchFlags: 0 lDAPDisplayName: msExchServer2AuthenticationCredentials name: ms-Exch-Server2-Authentication-Credentials schemaIDGUID: 26329072-b098-11d2-aa06-00c04f8eedd8 isMemberOfPartialAttributeSet: FALSE objectCategory: CN=Attribute-Schema,${SCHEMADN} # # ms-Exch-Server2-Authentication-Password # The password for the credentials specified for this directory. dn: CN=ms-Exch-Server2-Authentication-Password,${SCHEMADN} objectClass: top objectClass: attributeSchema cn: ms-Exch-Server2-Authentication-Password distinguishedName: CN=ms-Exch-Server2-Authentication-Password,${SCHEMADN} attributeID: 1.2.840.113556.1.4.7000.102.12 attributeSyntax: 2.5.5.10 isSingleValued: TRUE showInAdvancedViewOnly: TRUE adminDisplayName: ms-Exch-Server2-Authentication-Password adminDescription: ms-Exch-Server2-Authentication-Password oMSyntax: 4 searchFlags: 0 lDAPDisplayName: msExchServer2AuthenticationPassword name: ms-Exch-Server2-Authentication-Password schemaIDGUID: 266bc8e2-b098-11d2-aa06-00c04f8eedd8 isMemberOfPartialAttributeSet: FALSE objectCategory: CN=Attribute-Schema,${SCHEMADN} # # ms-Exch-Server2-Authentication-Type # The type of authentication to the server for this directory. # dn: CN=ms-Exch-Server2-Authentication-Type,${SCHEMADN} objectClass: top objectClass: attributeSchema cn: ms-Exch-Server2-Authentication-Type distinguishedName: CN=ms-Exch-Server2-Authentication-Type,${SCHEMADN} attributeID: 1.2.840.113556.1.4.7000.102.8 attributeSyntax: 2.5.5.9 isSingleValued: TRUE rangeLower: 0 rangeUpper: 5 showInAdvancedViewOnly: TRUE adminDisplayName: ms-Exch-Server2-Authentication-Type adminDescription: ms-Exch-Server2-Authentication-Type oMSyntax: 10 searchFlags: 0 lDAPDisplayName: msExchServer2AuthenticationType name: ms-Exch-Server2-Authentication-Type schemaIDGUID: 26a50152-b098-11d2-aa06-00c04f8eedd8 isMemberOfPartialAttributeSet: FALSE objectCategory: CN=Attribute-Schema,${SCHEMADN} # # ms-Exch-Server2-Deletion-Option # A flag used to determine how deletions are synchronized into this # directory. # dn: CN=ms-Exch-Server2-Deletion-Option,${SCHEMADN} objectClass: top objectClass: attributeSchema cn: ms-Exch-Server2-Deletion-Option distinguishedName: CN=ms-Exch-Server2-Deletion-Option,${SCHEMADN} attributeID: 1.2.840.113556.1.4.7000.102.22 attributeSyntax: 2.5.5.9 isSingleValued: TRUE showInAdvancedViewOnly: TRUE adminDisplayName: ms-Exch-Server2-Deletion-Option adminDescription: ms-Exch-Server2-Deletion-Option oMSyntax: 10 searchFlags: 0 lDAPDisplayName: msExchServer2DeletionOption name: ms-Exch-Server2-Deletion-Option schemaIDGUID: 26e09c1c-b098-11d2-aa06-00c04f8eedd8 isMemberOfPartialAttributeSet: FALSE objectCategory: CN=Attribute-Schema,${SCHEMADN} # # ms-Exch-Server2-Export-Containers # The DN of the default container to search for objects to # synchronize. # dn: CN=ms-Exch-Server2-Export-Containers,${SCHEMADN} objectClass: top objectClass: attributeSchema cn: ms-Exch-Server2-Export-Containers distinguishedName: CN=ms-Exch-Server2-Export-Containers,${SCHEMADN} attributeID: 1.2.840.113556.1.4.7000.102.14 attributeSyntax: 2.5.5.12 isSingleValued: FALSE showInAdvancedViewOnly: TRUE adminDisplayName: ms-Exch-Server2-Export-Containers adminDescription: ms-Exch-Server2-Export-Containers oMSyntax: 64 searchFlags: 0 lDAPDisplayName: msExchServer2ExportContainers name: ms-Exch-Server2-Export-Containers schemaIDGUID: 27cca4ea-b098-11d2-aa06-00c04f8eedd8 isMemberOfPartialAttributeSet: FALSE objectCategory: CN=Attribute-Schema,${SCHEMADN} # # ms-Exch-Server2-Flags # Flags for transitive replication work. # dn: CN=ms-Exch-Server2-Flags,${SCHEMADN} objectClass: top objectClass: attributeSchema cn: ms-Exch-Server2-Flags distinguishedName: CN=ms-Exch-Server2-Flags,${SCHEMADN} attributeID: 1.2.840.113556.1.4.7000.102.62 attributeSyntax: 2.5.5.9 isSingleValued: TRUE showInAdvancedViewOnly: TRUE adminDisplayName: ms-Exch-Server2-Flags adminDescription: ms-Exch-Server2-Flags oMSyntax: 2 searchFlags: 0 lDAPDisplayName: msExchServer2Flags name: ms-Exch-Server2-Flags schemaIDGUID: 28083fb4-b098-11d2-aa06-00c04f8eedd8 isMemberOfPartialAttributeSet: FALSE objectCategory: CN=Attribute-Schema,${SCHEMADN} # # ms-Exch-Server2-Highest-USN # The highwater mark update sequence number (USN) from the last # successful synchronization from this directory. # dn: CN=ms-Exch-Server2-Highest-USN,${SCHEMADN} objectClass: top objectClass: attributeSchema cn: ms-Exch-Server2-Highest-USN distinguishedName: CN=ms-Exch-Server2-Highest-USN,${SCHEMADN} attributeID: 1.2.840.113556.1.4.7000.102.30 attributeSyntax: 2.5.5.16 isSingleValued: TRUE showInAdvancedViewOnly: TRUE adminDisplayName: ms-Exch-Server2-Highest-USN adminDescription: ms-Exch-Server2-Highest-USN oMSyntax: 65 searchFlags: 0 lDAPDisplayName: msExchServer2HighestUSN name: ms-Exch-Server2-Highest-USN schemaIDGUID: 283a5116-b098-11d2-aa06-00c04f8eedd8 isMemberOfPartialAttributeSet: FALSE objectCategory: CN=Attribute-Schema,${SCHEMADN} # # ms-Exch-Server2-Highest-USN-Vector # Stores the vectors of update sequence numbers (USNs) and servers for # a given naming context (NC). # dn: CN=ms-Exch-Server2-Highest-USN-Vector,${SCHEMADN} objectClass: top objectClass: attributeSchema cn: ms-Exch-Server2-Highest-USN-Vector distinguishedName: CN=ms-Exch-Server2-Highest-USN-Vector,${SCHEMADN} attributeID: 1.2.840.113556.1.4.7000.102.87 attributeSyntax: 2.5.5.12 isSingleValued: FALSE showInAdvancedViewOnly: TRUE adminDisplayName: ms-Exch-Server2-Highest-USN-Vector adminDescription: ms-Exch-Server2-Highest-USN-Vector oMSyntax: 64 searchFlags: 0 lDAPDisplayName: msExchServer2HighestUSNVector name: ms-Exch-Server2-Highest-USN-Vector schemaIDGUID: 7fb58cda-2a6e-11d3-aa6b-00c04f8eedd8 isMemberOfPartialAttributeSet: FALSE objectCategory: CN=Attribute-Schema,${SCHEMADN} # # ms-Exch-Server2-Import-Container # The DN of the default container to write syncronized objects to. # dn: CN=ms-Exch-Server2-Import-Container,${SCHEMADN} objectClass: top objectClass: attributeSchema cn: ms-Exch-Server2-Import-Container distinguishedName: CN=ms-Exch-Server2-Import-Container,${SCHEMADN} attributeID: 1.2.840.113556.1.4.7000.102.16 attributeSyntax: 2.5.5.12 isSingleValued: TRUE showInAdvancedViewOnly: TRUE adminDisplayName: ms-Exch-Server2-Import-Container adminDescription: ms-Exch-Server2-Import-Container oMSyntax: 64 searchFlags: 0 lDAPDisplayName: msExchServer2ImportContainer name: ms-Exch-Server2-Import-Container schemaIDGUID: 286c6278-b098-11d2-aa06-00c04f8eedd8 isMemberOfPartialAttributeSet: FALSE objectCategory: CN=Attribute-Schema,${SCHEMADN} # # ms-Exch-Server2-Is-Bridgehead # A flag to determine whether non-mailbox associated objects are # replicated over this particular connection agreement. # dn: CN=ms-Exch-Server2-Is-Bridgehead,${SCHEMADN} objectClass: top objectClass: attributeSchema cn: ms-Exch-Server2-Is-Bridgehead distinguishedName: CN=ms-Exch-Server2-Is-Bridgehead,${SCHEMADN} attributeID: 1.2.840.113556.1.4.7000.102.78 attributeSyntax: 2.5.5.8 isSingleValued: TRUE showInAdvancedViewOnly: TRUE adminDisplayName: ms-Exch-Server2-Is-Bridgehead adminDescription: ms-Exch-Server2-Is-Bridgehead oMSyntax: 1 searchFlags: 0 lDAPDisplayName: msExchServer2IsBridgehead name: ms-Exch-Server2-Is-Bridgehead schemaIDGUID: 90d619fc-b09e-11d2-aa06-00c04f8eedd8 isMemberOfPartialAttributeSet: FALSE objectCategory: CN=Attribute-Schema,${SCHEMADN} # # ms-Exch-Server2-Last-Update-Time # The time of the most recent update from last successful # syncronization from this directory. # dn: CN=ms-Exch-Server2-Last-Update-Time,${SCHEMADN} objectClass: top objectClass: attributeSchema cn: ms-Exch-Server2-Last-Update-Time distinguishedName: CN=ms-Exch-Server2-Last-Update-Time,${SCHEMADN} attributeID: 1.2.840.113556.1.4.7000.102.32 attributeSyntax: 2.5.5.11 isSingleValued: TRUE showInAdvancedViewOnly: TRUE adminDisplayName: ms-Exch-Server2-Last-Update-Time adminDescription: ms-Exch-Server2-Last-Update-Time oMSyntax: 24 searchFlags: 0 lDAPDisplayName: msExchServer2LastUpdateTime name: ms-Exch-Server2-Last-Update-Time schemaIDGUID: 28a3388e-b098-11d2-aa06-00c04f8eedd8 isMemberOfPartialAttributeSet: FALSE objectCategory: CN=Attribute-Schema,${SCHEMADN} # # ms-Exch-Server2-Network-Address # The network address of the server participating in the connection # agreement. # dn: CN=ms-Exch-Server2-Network-Address,${SCHEMADN} objectClass: top objectClass: attributeSchema cn: ms-Exch-Server2-Network-Address distinguishedName: CN=ms-Exch-Server2-Network-Address,${SCHEMADN} attributeID: 1.2.840.113556.1.4.7000.102.4 attributeSyntax: 2.5.5.12 isSingleValued: TRUE rangeLower: 0 rangeUpper: 65535 showInAdvancedViewOnly: TRUE adminDisplayName: ms-Exch-Server2-Network-Address adminDescription: ms-Exch-Server2-Network-Address oMSyntax: 64 searchFlags: 0 lDAPDisplayName: msExchServer2NetworkAddress name: ms-Exch-Server2-Network-Address schemaIDGUID: 28d549f0-b098-11d2-aa06-00c04f8eedd8 isMemberOfPartialAttributeSet: FALSE objectCategory: CN=Attribute-Schema,${SCHEMADN} # # ms-Exch-Server2-NT-Account-Domain # The domain in which Active Directory accounts should be created. # dn: CN=ms-Exch-Server2-NT-Account-Domain,${SCHEMADN} objectClass: top objectClass: attributeSchema cn: ms-Exch-Server2-NT-Account-Domain distinguishedName: CN=ms-Exch-Server2-NT-Account-Domain,${SCHEMADN} attributeID: 1.2.840.113556.1.4.7000.102.51 attributeSyntax: 2.5.5.12 isSingleValued: TRUE showInAdvancedViewOnly: TRUE adminDisplayName: ms-Exch-Server2-NT-Account-Domain adminDescription: ms-Exch-Server2-NT-Account-Domain oMSyntax: 64 searchFlags: 0 lDAPDisplayName: msExchServer2NTAccountDomain name: ms-Exch-Server2-NT-Account-Domain schemaIDGUID: 2909bdac-b098-11d2-aa06-00c04f8eedd8 isMemberOfPartialAttributeSet: FALSE objectCategory: CN=Attribute-Schema,${SCHEMADN} # # ms-Exch-Server2-Object-Match # Contains the matching rules for this server. # dn: CN=ms-Exch-Server2-Object-Match,${SCHEMADN} objectClass: top objectClass: attributeSchema cn: ms-Exch-Server2-Object-Match distinguishedName: CN=ms-Exch-Server2-Object-Match,${SCHEMADN} attributeID: 1.2.840.113556.1.4.7000.102.55 attributeSyntax: 2.5.5.12 isSingleValued: TRUE showInAdvancedViewOnly: TRUE adminDisplayName: ms-Exch-Server2-Object-Match adminDescription: ms-Exch-Server2-Object-Match oMSyntax: 64 searchFlags: 0 lDAPDisplayName: msExchServer2ObjectMatch name: ms-Exch-Server2-Object-Match schemaIDGUID: 293e3168-b098-11d2-aa06-00c04f8eedd8 isMemberOfPartialAttributeSet: FALSE objectCategory: CN=Attribute-Schema,${SCHEMADN} # # ms-Exch-Server2-Page-Size # The page size to request when searching this directory. # dn: CN=ms-Exch-Server2-Page-Size,${SCHEMADN} objectClass: top objectClass: attributeSchema cn: ms-Exch-Server2-Page-Size distinguishedName: CN=ms-Exch-Server2-Page-Size,${SCHEMADN} attributeID: 1.2.840.113556.1.4.7000.102.26 attributeSyntax: 2.5.5.9 isSingleValued: TRUE rangeLower: 0 rangeUpper: 65535 showInAdvancedViewOnly: TRUE adminDisplayName: ms-Exch-Server2-Page-Size adminDescription: ms-Exch-Server2-Page-Size oMSyntax: 2 searchFlags: 0 lDAPDisplayName: msExchServer2PageSize name: ms-Exch-Server2-Page-Size schemaIDGUID: 296de070-b098-11d2-aa06-00c04f8eedd8 isMemberOfPartialAttributeSet: FALSE objectCategory: CN=Attribute-Schema,${SCHEMADN} # # ms-Exch-Server2-Port # The LDAP port of the server for this directory. # dn: CN=ms-Exch-Server2-Port,${SCHEMADN} objectClass: top objectClass: attributeSchema cn: ms-Exch-Server2-Port distinguishedName: CN=ms-Exch-Server2-Port,${SCHEMADN} attributeID: 1.2.840.113556.1.4.7000.102.6 attributeSyntax: 2.5.5.9 isSingleValued: TRUE rangeLower: 0 rangeUpper: 65535 showInAdvancedViewOnly: TRUE adminDisplayName: ms-Exch-Server2-Port adminDescription: ms-Exch-Server2-Port oMSyntax: 2 searchFlags: 0 lDAPDisplayName: msExchServer2Port name: ms-Exch-Server2-Port schemaIDGUID: 29a4b686-b098-11d2-aa06-00c04f8eedd8 isMemberOfPartialAttributeSet: FALSE objectCategory: CN=Attribute-Schema,${SCHEMADN} # # ms-Exch-Server2-Schema-Map # The schema map to use when mapping from the Exchange Directory # Service (DS) to Active Directory. # dn: CN=ms-Exch-Server2-Schema-Map,${SCHEMADN} objectClass: top objectClass: attributeSchema cn: ms-Exch-Server2-Schema-Map distinguishedName: CN=ms-Exch-Server2-Schema-Map,${SCHEMADN} attributeID: 1.2.840.113556.1.4.7000.102.18 attributeSyntax: 2.5.5.12 isSingleValued: TRUE showInAdvancedViewOnly: TRUE adminDisplayName: ms-Exch-Server2-Schema-Map adminDescription: ms-Exch-Server2-Schema-Map oMSyntax: 64 searchFlags: 0 lDAPDisplayName: msExchServer2SchemaMap name: ms-Exch-Server2-Schema-Map schemaIDGUID: 29d6c7e8-b098-11d2-aa06-00c04f8eedd8 isMemberOfPartialAttributeSet: FALSE objectCategory: CN=Attribute-Schema,${SCHEMADN} # # ms-Exch-Server2-Search-Filter # The search filter to use when searching this directory. # dn: CN=ms-Exch-Server2-Search-Filter,${SCHEMADN} objectClass: top objectClass: attributeSchema cn: ms-Exch-Server2-Search-Filter distinguishedName: CN=ms-Exch-Server2-Search-Filter,${SCHEMADN} attributeID: 1.2.840.113556.1.4.7000.102.20 attributeSyntax: 2.5.5.12 isSingleValued: TRUE showInAdvancedViewOnly: TRUE adminDisplayName: ms-Exch-Server2-Search-Filter adminDescription: ms-Exch-Server2-Search-Filter oMSyntax: 64 searchFlags: 0 lDAPDisplayName: msExchServer2SearchFilter name: ms-Exch-Server2-Search-Filter schemaIDGUID: 2a0b3ba4-b098-11d2-aa06-00c04f8eedd8 isMemberOfPartialAttributeSet: FALSE objectCategory: CN=Attribute-Schema,${SCHEMADN} # # ms-Exch-Server2-SSL-Port # The port to connect to for SSL connections. # dn: CN=ms-Exch-Server2-SSL-Port,${SCHEMADN} objectClass: top objectClass: attributeSchema cn: ms-Exch-Server2-SSL-Port distinguishedName: CN=ms-Exch-Server2-SSL-Port,${SCHEMADN} attributeID: 1.2.840.113556.1.4.7000.102.40 attributeSyntax: 2.5.5.9 isSingleValued: TRUE rangeLower: 0 rangeUpper: 65535 showInAdvancedViewOnly: TRUE adminDisplayName: ms-Exch-Server2-SSL-Port adminDescription: ms-Exch-Server2-SSL-Port oMSyntax: 2 searchFlags: 0 lDAPDisplayName: msExchServer2SSLPort name: ms-Exch-Server2-SSL-Port schemaIDGUID: 2a3faf60-b098-11d2-aa06-00c04f8eedd8 isMemberOfPartialAttributeSet: FALSE objectCategory: CN=Attribute-Schema,${SCHEMADN} # # ms-Exch-Server2-Type # Identifies the type of server being connected to. # dn: CN=ms-Exch-Server2-Type,${SCHEMADN} objectClass: top objectClass: attributeSchema cn: ms-Exch-Server2-Type distinguishedName: CN=ms-Exch-Server2-Type,${SCHEMADN} attributeID: 1.2.840.113556.1.4.7000.102.24 attributeSyntax: 2.5.5.9 isSingleValued: TRUE rangeLower: 0 rangeUpper: 5 showInAdvancedViewOnly: TRUE adminDisplayName: ms-Exch-Server2-Type adminDescription: ms-Exch-Server2-Type oMSyntax: 10 searchFlags: 0 lDAPDisplayName: msExchServer2Type name: ms-Exch-Server2-Type schemaIDGUID: 2a74231c-b098-11d2-aa06-00c04f8eedd8 isMemberOfPartialAttributeSet: FALSE objectCategory: CN=Attribute-Schema,${SCHEMADN} # # ms-Exch-Server-Auto-Start # Starts the service when the operating system is booted. dn: CN=ms-Exch-Server-Auto-Start,${SCHEMADN} objectClass: top objectClass: attributeSchema cn: ms-Exch-Server-Auto-Start distinguishedName: CN=ms-Exch-Server-Auto-Start,${SCHEMADN} attributeID: 1.2.840.113556.1.4.7000.102.2007 attributeSyntax: 2.5.5.8 isSingleValued: TRUE showInAdvancedViewOnly: TRUE adminDisplayName: ms-Exch-Server-Auto-Start adminDescription: ms-Exch-Server-Auto-Start oMSyntax: 1 searchFlags: 0 lDAPDisplayName: msExchServerAutoStart name: ms-Exch-Server-Auto-Start schemaIDGUID: 21cf9cdc-b098-11d2-aa06-00c04f8eedd8 isMemberOfPartialAttributeSet: FALSE objectCategory: CN=Attribute-Schema,${SCHEMADN} # # ms-Exch-Server-Bindings # The IP port binding for SSL connections. # dn: CN=ms-Exch-Server-Bindings,${SCHEMADN} objectClass: top objectClass: attributeSchema cn: ms-Exch-Server-Bindings distinguishedName: CN=ms-Exch-Server-Bindings,${SCHEMADN} attributeID: 1.2.840.113556.1.4.7000.102.2001 attributeSyntax: 2.5.5.12 isSingleValued: FALSE rangeLower: 1 rangeUpper: 512 showInAdvancedViewOnly: TRUE adminDisplayName: ms-Exch-Server-Bindings adminDescription: ms-Exch-Server-Bindings oMSyntax: 64 searchFlags: 0 lDAPDisplayName: msExchServerBindings name: ms-Exch-Server-Bindings schemaIDGUID: 2201ae3e-b098-11d2-aa06-00c04f8eedd8 isMemberOfPartialAttributeSet: FALSE objectCategory: CN=Attribute-Schema,${SCHEMADN} # # ms-Exch-Server-Bindings-Filtering # dn: CN=ms-Exch-Server-Bindings-Filtering,${SCHEMADN} objectClass: top objectClass: attributeSchema cn: ms-Exch-Server-Bindings-Filtering distinguishedName: CN=ms-Exch-Server-Bindings-Filtering,${SCHEMADN} attributeID: 1.2.840.113556.1.4.7000.102.5072 attributeSyntax: 2.5.5.12 isSingleValued: FALSE showInAdvancedViewOnly: TRUE adminDisplayName: ms-Exch-Server-Bindings-Filtering adminDescription: ms-Exch-Server-Bindings-Filtering oMSyntax: 64 searchFlags: 0 lDAPDisplayName: msExchServerBindingsFiltering name: ms-Exch-Server-Bindings-Filtering schemaIDGUID: 61aedffa-34b4-4170-8bab-b8794e1cb4f4 isMemberOfPartialAttributeSet: FALSE objectCategory: CN=Attribute-Schema,${SCHEMADN} # # ms-Exch-Server-Bindings-Turflist # dn: CN=ms-Exch-Server-Bindings-Turflist,${SCHEMADN} objectClass: top objectClass: attributeSchema cn: ms-Exch-Server-Bindings-Turflist distinguishedName: CN=ms-Exch-Server-Bindings-Turflist,${SCHEMADN} attributeID: 1.2.840.113556.1.4.7000.102.12533 attributeSyntax: 2.5.5.12 isSingleValued: FALSE showInAdvancedViewOnly: TRUE adminDisplayName: ms-Exch-Server-Bindings-Turflist adminDescription: ms-Exch-Server-Bindings-Turflist oMSyntax: 64 searchFlags: 0 lDAPDisplayName: msExchServerBindingsTurflist name: ms-Exch-Server-Bindings-Turflist schemaIDGUID: 0b836d98-3b20-11d3-aa6f-00c04f8eedd8 isMemberOfPartialAttributeSet: FALSE objectCategory: CN=Attribute-Schema,${SCHEMADN} # # ms-Exch-Server-Global-Groups # dn: CN=ms-Exch-Server-Global-Groups,${SCHEMADN} objectClass: top objectClass: attributeSchema cn: ms-Exch-Server-Global-Groups distinguishedName: CN=ms-Exch-Server-Global-Groups,${SCHEMADN} attributeID: 1.2.840.113556.1.4.7000.102.50083 attributeSyntax: 2.5.5.12 isSingleValued: FALSE showInAdvancedViewOnly: TRUE adminDisplayName: ms-Exch-Server-Global-Groups adminDescription: ms-Exch-Server-Global-Groups oMSyntax: 64 searchFlags: 0 lDAPDisplayName: msExchServerGlobalGroups name: ms-Exch-Server-Global-Groups schemaIDGUID: 419f00f6-fb22-4ea9-8113-ed928767baa5 isMemberOfPartialAttributeSet: FALSE objectCategory: CN=Attribute-Schema,${SCHEMADN} # # ms-Exch-Server-Groups # A link to all Exchange server groups within the organization. # dn: CN=ms-Exch-Server-Groups,${SCHEMADN} objectClass: top objectClass: attributeSchema cn: ms-Exch-Server-Groups distinguishedName: CN=ms-Exch-Server-Groups,${SCHEMADN} attributeID: 1.2.840.113556.1.4.7000.102.50055 attributeSyntax: 2.5.5.1 isSingleValued: FALSE showInAdvancedViewOnly: TRUE adminDisplayName: ms-Exch-Server-Groups oMObjectClass:: KwwCh3McAIVK adminDescription: ms-Exch-Server-Groups oMSyntax: 127 searchFlags: 0 lDAPDisplayName: msExchServerGroups name: ms-Exch-Server-Groups schemaIDGUID: 5fd75fb9-3819-4d25-b18e-7bce391d4767 isMemberOfPartialAttributeSet: FALSE objectCategory: CN=Attribute-Schema,${SCHEMADN} # # ms-Exch-Server-Local-Groups # Contains the domain local groups for each prepared domain. # dn: CN=ms-Exch-Server-Local-Groups,${SCHEMADN} objectClass: top objectClass: attributeSchema cn: ms-Exch-Server-Local-Groups distinguishedName: CN=ms-Exch-Server-Local-Groups,${SCHEMADN} attributeID: 1.2.840.113556.1.4.7000.102.50082 attributeSyntax: 2.5.5.1 isSingleValued: FALSE showInAdvancedViewOnly: TRUE adminDisplayName: ms-Exch-Server-Local-Groups oMObjectClass:: KwwCh3McAIVK adminDescription: ms-Exch-Server-Local-Groups oMSyntax: 127 searchFlags: 0 lDAPDisplayName: msExchServerLocalGroups name: ms-Exch-Server-Local-Groups schemaIDGUID: 924a0b14-ea4f-4627-abd1-adbc801c4b0b isMemberOfPartialAttributeSet: FALSE objectCategory: CN=Attribute-Schema,${SCHEMADN} # # ms-Exch-Server-Public-Key # dn: CN=ms-Exch-Server-Public-Key,${SCHEMADN} objectClass: top objectClass: attributeSchema cn: ms-Exch-Server-Public-Key distinguishedName: CN=ms-Exch-Server-Public-Key,${SCHEMADN} attributeID: 1.2.840.113556.1.4.7000.102.50063 attributeSyntax: 2.5.5.10 isSingleValued: TRUE showInAdvancedViewOnly: TRUE adminDisplayName: ms-Exch-Server-Public-Key adminDescription: ms-Exch-Server-Public-Key oMSyntax: 4 searchFlags: 0 lDAPDisplayName: msExchServerPublicKey name: ms-Exch-Server-Public-Key schemaIDGUID: b83df2df-c304-4563-90fd-d38ec81b04cb isMemberOfPartialAttributeSet: FALSE objectCategory: CN=Attribute-Schema,${SCHEMADN} # # ms-Exch-Server-Role # Determines if this server is a front-end or back-end server. dn: CN=ms-Exch-Server-Role,${SCHEMADN} objectClass: top objectClass: attributeSchema cn: ms-Exch-Server-Role distinguishedName: CN=ms-Exch-Server-Role,${SCHEMADN} attributeID: 1.2.840.113556.1.4.7000.102.15006 attributeSyntax: 2.5.5.9 isSingleValued: TRUE showInAdvancedViewOnly: TRUE adminDisplayName: ms-Exch-Server-Role adminDescription: ms-Exch-Server-Role oMSyntax: 2 searchFlags: 0 lDAPDisplayName: msExchServerRole name: ms-Exch-Server-Role schemaIDGUID: 8c8fc29e-b09e-11d2-aa06-00c04f8eedd8 isMemberOfPartialAttributeSet: FALSE objectCategory: CN=Attribute-Schema,${SCHEMADN} # # ms-Exch-Service-Action-First # dn: CN=ms-Exch-Service-Action-First,${SCHEMADN} objectClass: top objectClass: attributeSchema cn: ms-Exch-Service-Action-First distinguishedName: CN=ms-Exch-Service-Action-First,${SCHEMADN} attributeID: 1.2.840.113556.1.2.161 attributeSyntax: 2.5.5.9 isSingleValued: TRUE rangeLower: 0 rangeUpper: 2 mAPIID: 33073 showInAdvancedViewOnly: TRUE adminDisplayName: ms-Exch-Service-Action-First adminDescription: ms-Exch-Service-Action-First oMSyntax: 10 searchFlags: 0 lDAPDisplayName: serviceActionFirst name: ms-Exch-Service-Action-First schemaIDGUID: a8df7470-c5ea-11d1-bbcb-0080c76670c0 isMemberOfPartialAttributeSet: FALSE objectCategory: CN=Attribute-Schema,${SCHEMADN} # # ms-Exch-Service-Action-Other # dn: CN=ms-Exch-Service-Action-Other,${SCHEMADN} objectClass: top objectClass: attributeSchema cn: ms-Exch-Service-Action-Other distinguishedName: CN=ms-Exch-Service-Action-Other,${SCHEMADN} attributeID: 1.2.840.113556.1.2.59 attributeSyntax: 2.5.5.9 isSingleValued: TRUE rangeLower: 0 rangeUpper: 2 mAPIID: 33074 showInAdvancedViewOnly: TRUE adminDisplayName: ms-Exch-Service-Action-Other adminDescription: ms-Exch-Service-Action-Other oMSyntax: 10 searchFlags: 0 lDAPDisplayName: serviceActionOther name: ms-Exch-Service-Action-Other schemaIDGUID: a8df7471-c5ea-11d1-bbcb-0080c76670c0 isMemberOfPartialAttributeSet: FALSE objectCategory: CN=Attribute-Schema,${SCHEMADN} # # ms-Exch-Service-Action-Second # dn: CN=ms-Exch-Service-Action-Second,${SCHEMADN} objectClass: top objectClass: attributeSchema cn: ms-Exch-Service-Action-Second distinguishedName: CN=ms-Exch-Service-Action-Second,${SCHEMADN} attributeID: 1.2.840.113556.1.2.60 attributeSyntax: 2.5.5.9 isSingleValued: TRUE rangeLower: 0 rangeUpper: 2 mAPIID: 33075 showInAdvancedViewOnly: TRUE adminDisplayName: ms-Exch-Service-Action-Second adminDescription: ms-Exch-Service-Action-Second oMSyntax: 10 searchFlags: 0 lDAPDisplayName: serviceActionSecond name: ms-Exch-Service-Action-Second schemaIDGUID: a8df7472-c5ea-11d1-bbcb-0080c76670c0 isMemberOfPartialAttributeSet: FALSE objectCategory: CN=Attribute-Schema,${SCHEMADN} # # ms-Exch-Service-Restart-Delay # dn: CN=ms-Exch-Service-Restart-Delay,${SCHEMADN} objectClass: top objectClass: attributeSchema cn: ms-Exch-Service-Restart-Delay distinguishedName: CN=ms-Exch-Service-Restart-Delay,${SCHEMADN} attributeID: 1.2.840.113556.1.2.162 attributeSyntax: 2.5.5.9 isSingleValued: TRUE mAPIID: 33076 showInAdvancedViewOnly: TRUE adminDisplayName: ms-Exch-Service-Restart-Delay adminDescription: ms-Exch-Service-Restart-Delay oMSyntax: 2 searchFlags: 0 lDAPDisplayName: serviceRestartDelay name: ms-Exch-Service-Restart-Delay schemaIDGUID: a8df7473-c5ea-11d1-bbcb-0080c76670c0 isMemberOfPartialAttributeSet: FALSE objectCategory: CN=Attribute-Schema,${SCHEMADN} # # ms-Exch-Service-Restart-Message # dn: CN=ms-Exch-Service-Restart-Message,${SCHEMADN} objectClass: top objectClass: attributeSchema cn: ms-Exch-Service-Restart-Message distinguishedName: CN=ms-Exch-Service-Restart-Message,${SCHEMADN} attributeID: 1.2.840.113556.1.2.58 attributeSyntax: 2.5.5.12 isSingleValued: TRUE rangeLower: 1 rangeUpper: 120 mAPIID: 33077 showInAdvancedViewOnly: TRUE adminDisplayName: ms-Exch-Service-Restart-Message adminDescription: ms-Exch-Service-Restart-Message oMSyntax: 64 searchFlags: 0 lDAPDisplayName: serviceRestartMessage name: ms-Exch-Service-Restart-Message schemaIDGUID: a8df7474-c5ea-11d1-bbcb-0080c76670c0 isMemberOfPartialAttributeSet: FALSE objectCategory: CN=Attribute-Schema,${SCHEMADN} # # ms-Exch-Session-Disconnect-Timer # dn: CN=ms-Exch-Session-Disconnect-Timer,${SCHEMADN} objectClass: top objectClass: attributeSchema cn: ms-Exch-Session-Disconnect-Timer distinguishedName: CN=ms-Exch-Session-Disconnect-Timer,${SCHEMADN} attributeID: 1.2.840.113556.1.2.154 attributeSyntax: 2.5.5.9 isSingleValued: TRUE rangeLower: 0 rangeUpper: 32767 mAPIID: 33078 showInAdvancedViewOnly: TRUE adminDisplayName: ms-Exch-Session-Disconnect-Timer adminDescription: ms-Exch-Session-Disconnect-Timer oMSyntax: 2 searchFlags: 0 lDAPDisplayName: sessionDisconnectTimer name: ms-Exch-Session-Disconnect-Timer schemaIDGUID: a8df7475-c5ea-11d1-bbcb-0080c76670c0 isMemberOfPartialAttributeSet: FALSE objectCategory: CN=Attribute-Schema,${SCHEMADN} # # ms-Exch-Site-Folder-GUID # Contains a random unused GUID which is used by the store when # creating the public folder for this OAB. # dn: CN=ms-Exch-Site-Folder-GUID,${SCHEMADN} objectClass: top objectClass: attributeSchema cn: ms-Exch-Site-Folder-GUID distinguishedName: CN=ms-Exch-Site-Folder-GUID,${SCHEMADN} attributeID: 1.2.840.113556.1.2.456 attributeSyntax: 2.5.5.10 isSingleValued: TRUE mAPIID: 33126 showInAdvancedViewOnly: TRUE adminDisplayName: ms-Exch-Site-Folder-GUID adminDescription: ms-Exch-Site-Folder-GUID oMSyntax: 4 searchFlags: 0 lDAPDisplayName: siteFolderGUID name: ms-Exch-Site-Folder-GUID schemaIDGUID: a8df7477-c5ea-11d1-bbcb-0080c76670c0 isMemberOfPartialAttributeSet: FALSE objectCategory: CN=Attribute-Schema,${SCHEMADN} # # ms-Exch-Site-Folder-Server # dn: CN=ms-Exch-Site-Folder-Server,${SCHEMADN} objectClass: top objectClass: attributeSchema cn: ms-Exch-Site-Folder-Server distinguishedName: CN=ms-Exch-Site-Folder-Server,${SCHEMADN} attributeID: 1.2.840.113556.1.2.457 attributeSyntax: 2.5.5.1 isSingleValued: TRUE mAPIID: 33127 showInAdvancedViewOnly: TRUE adminDisplayName: ms-Exch-Site-Folder-Server oMObjectClass:: KwwCh3McAIVK adminDescription: ms-Exch-Site-Folder-Server oMSyntax: 127 searchFlags: 0 lDAPDisplayName: siteFolderServer name: ms-Exch-Site-Folder-Server schemaIDGUID: a8df7478-c5ea-11d1-bbcb-0080c76670c0 isMemberOfPartialAttributeSet: FALSE objectCategory: CN=Attribute-Schema,${SCHEMADN} # # ms-Exch-Site-Proxy-Space # dn: CN=ms-Exch-Site-Proxy-Space,${SCHEMADN} objectClass: top objectClass: attributeSchema cn: ms-Exch-Site-Proxy-Space distinguishedName: CN=ms-Exch-Site-Proxy-Space,${SCHEMADN} attributeID: 1.2.840.113556.1.2.385 attributeSyntax: 2.5.5.12 isSingleValued: FALSE rangeLower: 1 rangeUpper: 1123 mAPIID: 33080 showInAdvancedViewOnly: TRUE adminDisplayName: ms-Exch-Site-Proxy-Space adminDescription: ms-Exch-Site-Proxy-Space oMSyntax: 64 searchFlags: 0 lDAPDisplayName: siteProxySpace name: ms-Exch-Site-Proxy-Space schemaIDGUID: a8df7479-c5ea-11d1-bbcb-0080c76670c0 isMemberOfPartialAttributeSet: FALSE objectCategory: CN=Attribute-Schema,${SCHEMADN} # # ms-Exch-SLV-File # The database file location for this store. dn: CN=ms-Exch-SLV-File,${SCHEMADN} objectClass: top objectClass: attributeSchema cn: ms-Exch-SLV-File distinguishedName: CN=ms-Exch-SLV-File,${SCHEMADN} attributeID: 1.2.840.113556.1.4.7000.102.11036 attributeSyntax: 2.5.5.4 isSingleValued: TRUE showInAdvancedViewOnly: TRUE adminDisplayName: ms-Exch-SLV-File adminDescription: ms-Exch-SLV-File oMSyntax: 20 searchFlags: 0 lDAPDisplayName: msExchSLVFile name: ms-Exch-SLV-File schemaIDGUID: 2aaaf932-b098-11d2-aa06-00c04f8eedd8 isMemberOfPartialAttributeSet: FALSE objectCategory: CN=Attribute-Schema,${SCHEMADN} # # ms-Exch-SMIME-Alg-List-NA # The list of supported algorithms in North America by Microsoft # Outlook clients. This list should never be modified. # dn: CN=ms-Exch-SMIME-Alg-List-NA,${SCHEMADN} objectClass: top objectClass: attributeSchema cn: ms-Exch-SMIME-Alg-List-NA distinguishedName: CN=ms-Exch-SMIME-Alg-List-NA,${SCHEMADN} attributeID: 1.2.840.113556.1.2.568 attributeSyntax: 2.5.5.12 isSingleValued: FALSE rangeLower: 1 rangeUpper: 64 mAPIID: 35891 showInAdvancedViewOnly: TRUE adminDisplayName: ms-Exch-SMIME-Alg-List-NA adminDescription: ms-Exch-SMIME-Alg-List-NA oMSyntax: 64 searchFlags: 0 lDAPDisplayName: sMIMEAlgListNA name: ms-Exch-SMIME-Alg-List-NA schemaIDGUID: a8df747a-c5ea-11d1-bbcb-0080c76670c0 isMemberOfPartialAttributeSet: FALSE objectCategory: CN=Attribute-Schema,${SCHEMADN} # # ms-Exch-SMIME-Alg-List-Other # The list of non-North America algorithms supported by Outlook. # dn: CN=ms-Exch-SMIME-Alg-List-Other,${SCHEMADN} objectClass: top objectClass: attributeSchema cn: ms-Exch-SMIME-Alg-List-Other distinguishedName: CN=ms-Exch-SMIME-Alg-List-Other,${SCHEMADN} attributeID: 1.2.840.113556.1.2.569 attributeSyntax: 2.5.5.12 isSingleValued: FALSE rangeLower: 1 rangeUpper: 64 mAPIID: 35892 showInAdvancedViewOnly: TRUE adminDisplayName: ms-Exch-SMIME-Alg-List-Other adminDescription: ms-Exch-SMIME-Alg-List-Other oMSyntax: 64 searchFlags: 0 lDAPDisplayName: sMIMEAlgListOther name: ms-Exch-SMIME-Alg-List-Other schemaIDGUID: a8df747b-c5ea-11d1-bbcb-0080c76670c0 isMemberOfPartialAttributeSet: FALSE objectCategory: CN=Attribute-Schema,${SCHEMADN} # # ms-Exch-SMIME-Alg-Selected-NA # The currently-selected algorithm for North America Outlook users. # dn: CN=ms-Exch-SMIME-Alg-Selected-NA,${SCHEMADN} objectClass: top objectClass: attributeSchema cn: ms-Exch-SMIME-Alg-Selected-NA distinguishedName: CN=ms-Exch-SMIME-Alg-Selected-NA,${SCHEMADN} attributeID: 1.2.840.113556.1.2.570 attributeSyntax: 2.5.5.12 isSingleValued: TRUE rangeLower: 1 rangeUpper: 64 mAPIID: 35893 showInAdvancedViewOnly: TRUE adminDisplayName: ms-Exch-SMIME-Alg-Selected-NA adminDescription: ms-Exch-SMIME-Alg-Selected-NA oMSyntax: 64 searchFlags: 0 lDAPDisplayName: sMIMEAlgSelectedNA name: ms-Exch-SMIME-Alg-Selected-NA schemaIDGUID: a8df747c-c5ea-11d1-bbcb-0080c76670c0 isMemberOfPartialAttributeSet: FALSE objectCategory: CN=Attribute-Schema,${SCHEMADN} # # ms-Exch-SMIME-Alg-Selected-Other # The selected algorithm for non-North America Outlook users. # dn: CN=ms-Exch-SMIME-Alg-Selected-Other,${SCHEMADN} objectClass: top objectClass: attributeSchema cn: ms-Exch-SMIME-Alg-Selected-Other distinguishedName: CN=ms-Exch-SMIME-Alg-Selected-Other,${SCHEMADN} attributeID: 1.2.840.113556.1.2.571 attributeSyntax: 2.5.5.12 isSingleValued: TRUE rangeLower: 1 rangeUpper: 64 mAPIID: 35894 showInAdvancedViewOnly: TRUE adminDisplayName: ms-Exch-SMIME-Alg-Selected-Other adminDescription: ms-Exch-SMIME-Alg-Selected-Other oMSyntax: 64 searchFlags: 0 lDAPDisplayName: sMIMEAlgSelectedOther name: ms-Exch-SMIME-Alg-Selected-Other schemaIDGUID: a8df747d-c5ea-11d1-bbcb-0080c76670c0 isMemberOfPartialAttributeSet: FALSE objectCategory: CN=Attribute-Schema,${SCHEMADN} # # ms-Exch-Smtp-Authorized-TRN-Accounts # The list of all accounts that are authorized to use TRN. # dn: CN=ms-Exch-Smtp-Authorized-TRN-Accounts,${SCHEMADN} objectClass: top objectClass: attributeSchema cn: ms-Exch-Smtp-Authorized-TRN-Accounts distinguishedName: CN=ms-Exch-Smtp-Authorized-TRN-Accounts,${SCHEMADN} attributeID: 1.2.840.113556.1.4.7000.102.5047 attributeSyntax: 2.5.5.12 isSingleValued: FALSE showInAdvancedViewOnly: TRUE adminDisplayName: ms-Exch-Smtp-Authorized-TRN-Accounts adminDescription: ms-Exch-Smtp-Authorized-TRN-Accounts oMSyntax: 64 searchFlags: 0 lDAPDisplayName: msExchSmtpAuthorizedTRNAccounts name: ms-Exch-Smtp-Authorized-TRN-Accounts schemaIDGUID: 2b164304-b098-11d2-aa06-00c04f8eedd8 isMemberOfPartialAttributeSet: FALSE objectCategory: CN=Attribute-Schema,${SCHEMADN} # # ms-Exch-Smtp-Bad-Mail-Directory # Location where bad mail messages are stored. # dn: CN=ms-Exch-Smtp-Bad-Mail-Directory,${SCHEMADN} objectClass: top objectClass: attributeSchema cn: ms-Exch-Smtp-Bad-Mail-Directory distinguishedName: CN=ms-Exch-Smtp-Bad-Mail-Directory,${SCHEMADN} attributeID: 1.2.840.113556.1.4.7000.102.5025 attributeSyntax: 2.5.5.12 isSingleValued: TRUE showInAdvancedViewOnly: TRUE adminDisplayName: ms-Exch-Smtp-Bad-Mail-Directory adminDescription: ms-Exch-Smtp-Bad-Mail-Directory oMSyntax: 64 searchFlags: 0 lDAPDisplayName: msExchSmtpBadMailDirectory name: ms-Exch-Smtp-Bad-Mail-Directory schemaIDGUID: 2b5904dc-b098-11d2-aa06-00c04f8eedd8 isMemberOfPartialAttributeSet: FALSE objectCategory: CN=Attribute-Schema,${SCHEMADN} # # ms-Exch-Smtp-Connection-Rules-Priority # dn: CN=ms-Exch-Smtp-Connection-Rules-Priority,${SCHEMADN} objectClass: top objectClass: attributeSchema cn: ms-Exch-Smtp-Connection-Rules-Priority distinguishedName: CN=ms-Exch-Smtp-Connection-Rules-Priority,${SCHEMADN} attributeID: 1.2.840.113556.1.4.7000.102.5064 attributeSyntax: 2.5.5.10 isSingleValued: TRUE showInAdvancedViewOnly: TRUE adminDisplayName: ms-Exch-Smtp-Connection-Rules-Priority adminDescription: ms-Exch-Smtp-Connection-Rules-Priority oMSyntax: 4 searchFlags: 0 lDAPDisplayName: msExchSmtpConnectionRulesPriority name: ms-Exch-Smtp-Connection-Rules-Priority schemaIDGUID: 86c24f8c-259b-4f19-88b9-9c9445936121 isMemberOfPartialAttributeSet: FALSE objectCategory: CN=Attribute-Schema,${SCHEMADN} # # ms-Exch-Smtp-Connection-Turf-List-Display # dn: CN=ms-Exch-Smtp-Connection-Turf-List-Display,${SCHEMADN} objectClass: top objectClass: attributeSchema cn: ms-Exch-Smtp-Connection-Turf-List-Display distinguishedName: CN=ms-Exch-Smtp-Connection-Turf-List-Display,${SCHEMADN} attributeID: 1.2.840.113556.1.4.7000.102.5065 attributeSyntax: 2.5.5.12 isSingleValued: TRUE showInAdvancedViewOnly: TRUE adminDisplayName: ms-Exch-Smtp-Connection-Turf-List-Display adminDescription: ms-Exch-Smtp-Connection-Turf-List-Display oMSyntax: 64 searchFlags: 0 lDAPDisplayName: msExchSmtpConnectionTurfListDisplay name: ms-Exch-Smtp-Connection-Turf-List-Display schemaIDGUID: 73fb04ac-b2d4-4a4d-8520-757dd3c9261a isMemberOfPartialAttributeSet: FALSE objectCategory: CN=Attribute-Schema,${SCHEMADN} # # ms-Exch-Smtp-Connection-Turf-List-DNS # dn: CN=ms-Exch-Smtp-Connection-Turf-List-DNS,${SCHEMADN} objectClass: top objectClass: attributeSchema cn: ms-Exch-Smtp-Connection-Turf-List-DNS distinguishedName: CN=ms-Exch-Smtp-Connection-Turf-List-DNS,${SCHEMADN} attributeID: 1.2.840.113556.1.4.7000.102.5067 attributeSyntax: 2.5.5.12 isSingleValued: TRUE showInAdvancedViewOnly: TRUE adminDisplayName: ms-Exch-Smtp-Connection-Turf-List-DNS adminDescription: ms-Exch-Smtp-Connection-Turf-List-DNS oMSyntax: 64 searchFlags: 0 lDAPDisplayName: msExchSmtpConnectionTurfListDNS name: ms-Exch-Smtp-Connection-Turf-List-DNS schemaIDGUID: 3fee7de6-d3e5-43cb-8459-f7a072ae3789 isMemberOfPartialAttributeSet: FALSE objectCategory: CN=Attribute-Schema,${SCHEMADN} # # ms-Exch-Smtp-Connection-Turf-List-Mask # dn: CN=ms-Exch-Smtp-Connection-Turf-List-Mask,${SCHEMADN} objectClass: top objectClass: attributeSchema cn: ms-Exch-Smtp-Connection-Turf-List-Mask distinguishedName: CN=ms-Exch-Smtp-Connection-Turf-List-Mask,${SCHEMADN} attributeID: 1.2.840.113556.1.4.7000.102.5069 attributeSyntax: 2.5.5.12 isSingleValued: TRUE showInAdvancedViewOnly: TRUE adminDisplayName: ms-Exch-Smtp-Connection-Turf-List-Mask adminDescription: ms-Exch-Smtp-Connection-Turf-List-Mask oMSyntax: 64 searchFlags: 0 lDAPDisplayName: msExchSmtpConnectionTurfListMask name: ms-Exch-Smtp-Connection-Turf-List-Mask schemaIDGUID: bc0241af-9d38-4c40-842e-51d802506de5 isMemberOfPartialAttributeSet: FALSE objectCategory: CN=Attribute-Schema,${SCHEMADN} # # ms-Exch-Smtp-Connection-Turf-List-Options # dn: CN=ms-Exch-Smtp-Connection-Turf-List-Options,${SCHEMADN} objectClass: top objectClass: attributeSchema cn: ms-Exch-Smtp-Connection-Turf-List-Options distinguishedName: CN=ms-Exch-Smtp-Connection-Turf-List-Options,${SCHEMADN} attributeID: 1.2.840.113556.1.4.7000.102.5066 attributeSyntax: 2.5.5.9 isSingleValued: TRUE showInAdvancedViewOnly: TRUE adminDisplayName: ms-Exch-Smtp-Connection-Turf-List-Options adminDescription: ms-Exch-Smtp-Connection-Turf-List-Options oMSyntax: 2 searchFlags: 0 lDAPDisplayName: msExchSmtpConnectionTurfListOptions name: ms-Exch-Smtp-Connection-Turf-List-Options schemaIDGUID: 5ae62360-1105-4d8b-8a1e-a2c793b4d57d isMemberOfPartialAttributeSet: FALSE objectCategory: CN=Attribute-Schema,${SCHEMADN} # # ms-Exch-Smtp-Connection-Turf-List-Response # dn: CN=ms-Exch-Smtp-Connection-Turf-List-Response,${SCHEMADN} objectClass: top objectClass: attributeSchema cn: ms-Exch-Smtp-Connection-Turf-List-Response distinguishedName: CN=ms-Exch-Smtp-Connection-Turf-List-Response,${SCHEMADN} attributeID: 1.2.840.113556.1.4.7000.102.5068 attributeSyntax: 2.5.5.12 isSingleValued: TRUE showInAdvancedViewOnly: TRUE adminDisplayName: ms-Exch-Smtp-Connection-Turf-List-Response adminDescription: ms-Exch-Smtp-Connection-Turf-List-Response oMSyntax: 64 searchFlags: 0 lDAPDisplayName: msExchSmtpConnectionTurfListResponse name: ms-Exch-Smtp-Connection-Turf-List-Response schemaIDGUID: eeddd98f-da01-4ecb-a65e-5f016f1d8032 isMemberOfPartialAttributeSet: FALSE objectCategory: CN=Attribute-Schema,${SCHEMADN} # # ms-Exch-Smtp-Connection-Whitelist # dn: CN=ms-Exch-Smtp-Connection-Whitelist,${SCHEMADN} objectClass: top objectClass: attributeSchema cn: ms-Exch-Smtp-Connection-Whitelist distinguishedName: CN=ms-Exch-Smtp-Connection-Whitelist,${SCHEMADN} attributeID: 1.2.840.113556.1.4.7000.102.5063 attributeSyntax: 2.5.5.12 isSingleValued: FALSE showInAdvancedViewOnly: TRUE adminDisplayName: ms-Exch-Smtp-Connection-Whitelist adminDescription: ms-Exch-Smtp-Connection-Whitelist oMSyntax: 64 searchFlags: 0 lDAPDisplayName: msExchSmtpConnectionWhitelist name: ms-Exch-Smtp-Connection-Whitelist schemaIDGUID: 87cf463a-561e-45ce-a0ba-6d528f111d23 isMemberOfPartialAttributeSet: FALSE objectCategory: CN=Attribute-Schema,${SCHEMADN} # # ms-Exch-Smtp-Domain-String # The drop directory of the domain or route domain. # dn: CN=ms-Exch-Smtp-Domain-String,${SCHEMADN} objectClass: top objectClass: attributeSchema cn: ms-Exch-Smtp-Domain-String distinguishedName: CN=ms-Exch-Smtp-Domain-String,${SCHEMADN} attributeID: 1.2.840.113556.1.4.7000.102.5033 attributeSyntax: 2.5.5.12 isSingleValued: TRUE showInAdvancedViewOnly: TRUE adminDisplayName: ms-Exch-Smtp-Domain-String adminDescription: ms-Exch-Smtp-Domain-String oMSyntax: 64 searchFlags: 0 lDAPDisplayName: msExchSmtpDomainString name: ms-Exch-Smtp-Domain-String schemaIDGUID: 2bd03a70-b098-11d2-aa06-00c04f8eedd8 isMemberOfPartialAttributeSet: FALSE objectCategory: CN=Attribute-Schema,${SCHEMADN} # # ms-Exch-Smtp-Do-Masquerade # If set, use the Masquerade domain. # dn: CN=ms-Exch-Smtp-Do-Masquerade,${SCHEMADN} objectClass: top objectClass: attributeSchema cn: ms-Exch-Smtp-Do-Masquerade distinguishedName: CN=ms-Exch-Smtp-Do-Masquerade,${SCHEMADN} attributeID: 1.2.840.113556.1.4.7000.102.5022 attributeSyntax: 2.5.5.8 isSingleValued: TRUE showInAdvancedViewOnly: TRUE adminDisplayName: ms-Exch-Smtp-Do-Masquerade adminDescription: ms-Exch-Smtp-Do-Masquerade oMSyntax: 1 searchFlags: 0 lDAPDisplayName: msExchSmtpDoMasquerade name: ms-Exch-Smtp-Do-Masquerade schemaIDGUID: 2b949fa6-b098-11d2-aa06-00c04f8eedd8 isMemberOfPartialAttributeSet: FALSE objectCategory: CN=Attribute-Schema,${SCHEMADN} # # ms-Exch-Smtp-Drop-Directory # The directory where mail messages are being dropped. # dn: CN=ms-Exch-Smtp-Drop-Directory,${SCHEMADN} objectClass: top objectClass: attributeSchema cn: ms-Exch-Smtp-Drop-Directory distinguishedName: CN=ms-Exch-Smtp-Drop-Directory,${SCHEMADN} attributeID: 1.2.840.113556.1.4.7000.102.5032 attributeSyntax: 2.5.5.12 isSingleValued: TRUE showInAdvancedViewOnly: TRUE adminDisplayName: ms-Exch-Smtp-Drop-Directory adminDescription: ms-Exch-Smtp-Drop-Directory oMSyntax: 64 searchFlags: 0 lDAPDisplayName: msExchSmtpDropDirectory name: ms-Exch-Smtp-Drop-Directory schemaIDGUID: 2c260f18-b098-11d2-aa06-00c04f8eedd8 isMemberOfPartialAttributeSet: FALSE objectCategory: CN=Attribute-Schema,${SCHEMADN} # # ms-Exch-Smtp-Ds-Data-Directory # The data directory for DSAccess. # dn: CN=ms-Exch-Smtp-Ds-Data-Directory,${SCHEMADN} objectClass: top objectClass: attributeSchema cn: ms-Exch-Smtp-Ds-Data-Directory distinguishedName: CN=ms-Exch-Smtp-Ds-Data-Directory,${SCHEMADN} attributeID: 1.2.840.113556.1.4.7000.102.5036 attributeSyntax: 2.5.5.12 isSingleValued: TRUE showInAdvancedViewOnly: TRUE adminDisplayName: ms-Exch-Smtp-Ds-Data-Directory adminDescription: ms-Exch-Smtp-Ds-Data-Directory oMSyntax: 64 searchFlags: 0 lDAPDisplayName: msExchSmtpDsDataDirectory name: ms-Exch-Smtp-Ds-Data-Directory schemaIDGUID: 2c6d95a4-b098-11d2-aa06-00c04f8eedd8 isMemberOfPartialAttributeSet: FALSE objectCategory: CN=Attribute-Schema,${SCHEMADN} # # ms-Exch-Smtp-Ds-Default-Mail-Root # The default mail root for DSAccess. # dn: CN=ms-Exch-Smtp-Ds-Default-Mail-Root,${SCHEMADN} objectClass: top objectClass: attributeSchema cn: ms-Exch-Smtp-Ds-Default-Mail-Root distinguishedName: CN=ms-Exch-Smtp-Ds-Default-Mail-Root,${SCHEMADN} attributeID: 1.2.840.113556.1.4.7000.102.5037 attributeSyntax: 2.5.5.12 isSingleValued: TRUE showInAdvancedViewOnly: TRUE adminDisplayName: ms-Exch-Smtp-Ds-Default-Mail-Root adminDescription: ms-Exch-Smtp-Ds-Default-Mail-Root oMSyntax: 64 searchFlags: 0 lDAPDisplayName: msExchSmtpDsDefaultMailRoot name: ms-Exch-Smtp-Ds-Default-Mail-Root schemaIDGUID: 2cadf522-b098-11d2-aa06-00c04f8eedd8 isMemberOfPartialAttributeSet: FALSE objectCategory: CN=Attribute-Schema,${SCHEMADN} # # ms-Exch-Smtp-Ds-Domain # The default mail root for DSAccess. # dn: CN=ms-Exch-Smtp-Ds-Domain,${SCHEMADN} objectClass: top objectClass: attributeSchema cn: ms-Exch-Smtp-Ds-Domain distinguishedName: CN=ms-Exch-Smtp-Ds-Domain,${SCHEMADN} attributeID: 1.2.840.113556.1.4.7000.102.5038 attributeSyntax: 2.5.5.12 isSingleValued: TRUE showInAdvancedViewOnly: TRUE adminDisplayName: ms-Exch-Smtp-Ds-Domain adminDescription: ms-Exch-Smtp-Ds-Domain oMSyntax: 64 searchFlags: 0 lDAPDisplayName: msExchSmtpDsDomain name: ms-Exch-Smtp-Ds-Domain schemaIDGUID: 2ce72d92-b098-11d2-aa06-00c04f8eedd8 isMemberOfPartialAttributeSet: FALSE objectCategory: CN=Attribute-Schema,${SCHEMADN} # # ms-Exch-Smtp-Ds-Flags # dn: CN=ms-Exch-Smtp-Ds-Flags,${SCHEMADN} objectClass: top objectClass: attributeSchema cn: ms-Exch-Smtp-Ds-Flags distinguishedName: CN=ms-Exch-Smtp-Ds-Flags,${SCHEMADN} attributeID: 1.2.840.113556.1.4.7000.102.5049 attributeSyntax: 2.5.5.9 isSingleValued: TRUE showInAdvancedViewOnly: TRUE adminDisplayName: ms-Exch-Smtp-Ds-Flags adminDescription: ms-Exch-Smtp-Ds-Flags oMSyntax: 2 searchFlags: 0 lDAPDisplayName: msExchSmtpDsFlags name: ms-Exch-Smtp-Ds-Flags schemaIDGUID: 2d206602-b098-11d2-aa06-00c04f8eedd8 isMemberOfPartialAttributeSet: FALSE objectCategory: CN=Attribute-Schema,${SCHEMADN} # # ms-Exch-Smtp-Ds-Host # The host to connect in DSAccess. # dn: CN=ms-Exch-Smtp-Ds-Host,${SCHEMADN} objectClass: top objectClass: attributeSchema cn: ms-Exch-Smtp-Ds-Host distinguishedName: CN=ms-Exch-Smtp-Ds-Host,${SCHEMADN} attributeID: 1.2.840.113556.1.4.7000.102.5042 attributeSyntax: 2.5.5.12 isSingleValued: TRUE showInAdvancedViewOnly: TRUE adminDisplayName: ms-Exch-Smtp-Ds-Host adminDescription: ms-Exch-Smtp-Ds-Host oMSyntax: 64 searchFlags: 0 lDAPDisplayName: msExchSmtpDsHost name: ms-Exch-Smtp-Ds-Host schemaIDGUID: 2d599e72-b098-11d2-aa06-00c04f8eedd8 isMemberOfPartialAttributeSet: FALSE objectCategory: CN=Attribute-Schema,${SCHEMADN} # # ms-Exch-Smtp-Ds-Port # The port to use in DSAccess. # dn: CN=ms-Exch-Smtp-Ds-Port,${SCHEMADN} objectClass: top objectClass: attributeSchema cn: ms-Exch-Smtp-Ds-Port distinguishedName: CN=ms-Exch-Smtp-Ds-Port,${SCHEMADN} attributeID: 1.2.840.113556.1.4.7000.102.5017 attributeSyntax: 2.5.5.9 isSingleValued: TRUE showInAdvancedViewOnly: TRUE adminDisplayName: ms-Exch-Smtp-Ds-Port adminDescription: ms-Exch-Smtp-Ds-Port oMSyntax: 2 searchFlags: 0 lDAPDisplayName: msExchSmtpDsPort name: ms-Exch-Smtp-Ds-Port schemaIDGUID: 2d92d6e2-b098-11d2-aa06-00c04f8eedd8 isMemberOfPartialAttributeSet: FALSE objectCategory: CN=Attribute-Schema,${SCHEMADN} # # ms-Exch-Smtp-Enable-EXPN # dn: CN=ms-Exch-Smtp-Enable-EXPN,${SCHEMADN} objectClass: top objectClass: attributeSchema cn: ms-Exch-Smtp-Enable-EXPN distinguishedName: CN=ms-Exch-Smtp-Enable-EXPN,${SCHEMADN} attributeID: 1.2.840.113556.1.4.7000.102.12537 attributeSyntax: 2.5.5.8 isSingleValued: TRUE showInAdvancedViewOnly: TRUE adminDisplayName: ms-Exch-Smtp-Enable-EXPN adminDescription: ms-Exch-Smtp-Enable-EXPN oMSyntax: 1 searchFlags: 0 lDAPDisplayName: msExchSmtpEnableEXPN name: ms-Exch-Smtp-Enable-EXPN schemaIDGUID: e24d7a86-439d-11d3-aa72-00c04f8eedd8 isMemberOfPartialAttributeSet: FALSE objectCategory: CN=Attribute-Schema,${SCHEMADN} # # ms-Exch-Smtp-Enable-Ldap-Routing # Configures the directory that this resource uses to route mail. # dn: CN=ms-Exch-Smtp-Enable-Ldap-Routing,${SCHEMADN} objectClass: top objectClass: attributeSchema cn: ms-Exch-Smtp-Enable-Ldap-Routing distinguishedName: CN=ms-Exch-Smtp-Enable-Ldap-Routing,${SCHEMADN} attributeID: 1.2.840.113556.1.4.7000.102.5019 attributeSyntax: 2.5.5.9 isSingleValued: TRUE showInAdvancedViewOnly: TRUE adminDisplayName: ms-Exch-Smtp-Enable-Ldap-Routing adminDescription: ms-Exch-Smtp-Enable-Ldap-Routing oMSyntax: 2 searchFlags: 0 lDAPDisplayName: msExchSmtpEnableLdapRouting name: ms-Exch-Smtp-Enable-Ldap-Routing schemaIDGUID: 2dce71ac-b098-11d2-aa06-00c04f8eedd8 isMemberOfPartialAttributeSet: FALSE objectCategory: CN=Attribute-Schema,${SCHEMADN} # # ms-Exch-Smtp-Enable-VRFY # dn: CN=ms-Exch-Smtp-Enable-VRFY,${SCHEMADN} objectClass: top objectClass: attributeSchema cn: ms-Exch-Smtp-Enable-VRFY distinguishedName: CN=ms-Exch-Smtp-Enable-VRFY,${SCHEMADN} attributeID: 1.2.840.113556.1.4.7000.102.12536 attributeSyntax: 2.5.5.8 isSingleValued: TRUE showInAdvancedViewOnly: TRUE adminDisplayName: ms-Exch-Smtp-Enable-VRFY adminDescription: ms-Exch-Smtp-Enable-VRFY oMSyntax: 1 searchFlags: 0 lDAPDisplayName: msExchSmtpEnableVRFY name: ms-Exch-Smtp-Enable-VRFY schemaIDGUID: e24d7a80-439d-11d3-aa72-00c04f8eedd8 isMemberOfPartialAttributeSet: FALSE objectCategory: CN=Attribute-Schema,${SCHEMADN} # # ms-Exch-Smtp-External-DNS-Servers # Contains the IP addresses of DNS servers that should be used by this # SMTP virtual server. # dn: CN=ms-Exch-Smtp-External-DNS-Servers,${SCHEMADN} objectClass: top objectClass: attributeSchema cn: ms-Exch-Smtp-External-DNS-Servers distinguishedName: CN=ms-Exch-Smtp-External-DNS-Servers,${SCHEMADN} attributeID: 1.2.840.113556.1.4.7000.102.5056 attributeSyntax: 2.5.5.12 isSingleValued: TRUE showInAdvancedViewOnly: TRUE adminDisplayName: ms-Exch-Smtp-External-DNS-Servers adminDescription: ms-Exch-Smtp-External-DNS-Servers oMSyntax: 64 searchFlags: 0 lDAPDisplayName: msExchSmtpExternalDNSServers name: ms-Exch-Smtp-External-DNS-Servers schemaIDGUID: a1826432-f85e-42b6-b55d-1249ed2f78a3 isMemberOfPartialAttributeSet: FALSE objectCategory: CN=Attribute-Schema,${SCHEMADN} # # ms-Exch-Smtp-Fully-Qualified-Domain-Name # The Fully Qualified Domain Name for this virtual server. # dn: CN=ms-Exch-Smtp-Fully-Qualified-Domain-Name,${SCHEMADN} objectClass: top objectClass: attributeSchema cn: ms-Exch-Smtp-Fully-Qualified-Domain-Name distinguishedName: CN=ms-Exch-Smtp-Fully-Qualified-Domain-Name,${SCHEMADN} attributeID: 1.2.840.113556.1.4.7000.102.5029 attributeSyntax: 2.5.5.12 isSingleValued: TRUE showInAdvancedViewOnly: TRUE adminDisplayName: ms-Exch-Smtp-Fully-Qualified-Domain-Name adminDescription: ms-Exch-Smtp-Fully-Qualified-Domain-Name oMSyntax: 64 searchFlags: 0 lDAPDisplayName: msExchSmtpFullyQualifiedDomainName name: ms-Exch-Smtp-Fully-Qualified-Domain-Name schemaIDGUID: 2e0547c2-b098-11d2-aa06-00c04f8eedd8 isMemberOfPartialAttributeSet: FALSE objectCategory: CN=Attribute-Schema,${SCHEMADN} # # ms-Exch-SMTP-Global-IP-Accept-List # dn: CN=ms-Exch-SMTP-Global-IP-Accept-List,${SCHEMADN} objectClass: top objectClass: attributeSchema cn: ms-Exch-SMTP-Global-IP-Accept-List distinguishedName: CN=ms-Exch-SMTP-Global-IP-Accept-List,${SCHEMADN} attributeID: 1.2.840.113556.1.4.7000.102.5073 attributeSyntax: 2.5.5.10 isSingleValued: TRUE showInAdvancedViewOnly: TRUE adminDisplayName: ms-Exch-SMTP-Global-IP-Accept-List adminDescription: ms-Exch-SMTP-Global-IP-Accept-List oMSyntax: 4 searchFlags: 0 lDAPDisplayName: msExchSMTPGlobalIPAcceptList name: ms-Exch-SMTP-Global-IP-Accept-List schemaIDGUID: 752cd028-a935-40aa-8f8b-14aeb4433c93 isMemberOfPartialAttributeSet: FALSE objectCategory: CN=Attribute-Schema,${SCHEMADN} # # ms-Exch-SMTP-Global-IP-Deny-List # dn: CN=ms-Exch-SMTP-Global-IP-Deny-List,${SCHEMADN} objectClass: top objectClass: attributeSchema cn: ms-Exch-SMTP-Global-IP-Deny-List distinguishedName: CN=ms-Exch-SMTP-Global-IP-Deny-List,${SCHEMADN} attributeID: 1.2.840.113556.1.4.7000.102.5074 attributeSyntax: 2.5.5.10 isSingleValued: TRUE showInAdvancedViewOnly: TRUE adminDisplayName: ms-Exch-SMTP-Global-IP-Deny-List adminDescription: ms-Exch-SMTP-Global-IP-Deny-List oMSyntax: 4 searchFlags: 0 lDAPDisplayName: msExchSMTPGlobalIPDenyList name: ms-Exch-SMTP-Global-IP-Deny-List schemaIDGUID: 61e731dc-484d-4566-8aac-c54747f13cc4 isMemberOfPartialAttributeSet: FALSE objectCategory: CN=Attribute-Schema,${SCHEMADN} # # ms-Exch-Smtp-Inbound-Command-Support-Options # The TLF encryption flag used for basic authentication. # dn: CN=ms-Exch-Smtp-Inbound-Command-Support-Options,${SCHEMADN} objectClass: top objectClass: attributeSchema cn: ms-Exch-Smtp-Inbound-Command-Support-Options distinguishedName: CN=ms-Exch-Smtp-Inbound-Command-Support-Options,${SCHEMADN} attributeID: 1.2.840.113556.1.4.7000.102.5018 attributeSyntax: 2.5.5.9 isSingleValued: TRUE showInAdvancedViewOnly: TRUE adminDisplayName: ms-Exch-Smtp-Inbound-Command-Support-Options adminDescription: ms-Exch-Smtp-Inbound-Command-Support-Options oMSyntax: 2 searchFlags: 0 lDAPDisplayName: msExchSmtpInboundCommandSupportOptions name: ms-Exch-Smtp-Inbound-Command-Support-Options schemaIDGUID: 2e40e28c-b098-11d2-aa06-00c04f8eedd8 isMemberOfPartialAttributeSet: FALSE objectCategory: CN=Attribute-Schema,${SCHEMADN} # # ms-Exch-Smtp-Ldap-Account # The LDAP account to use in DSAccess. dn: CN=ms-Exch-Smtp-Ldap-Account,${SCHEMADN} objectClass: top objectClass: attributeSchema cn: ms-Exch-Smtp-Ldap-Account distinguishedName: CN=ms-Exch-Smtp-Ldap-Account,${SCHEMADN} attributeID: 1.2.840.113556.1.4.7000.102.5044 attributeSyntax: 2.5.5.12 isSingleValued: TRUE showInAdvancedViewOnly: TRUE adminDisplayName: ms-Exch-Smtp-Ldap-Account adminDescription: ms-Exch-Smtp-Ldap-Account oMSyntax: 64 searchFlags: 0 lDAPDisplayName: msExchSmtpLdapAccount name: ms-Exch-Smtp-Ldap-Account schemaIDGUID: 2e7c7d56-b098-11d2-aa06-00c04f8eedd8 isMemberOfPartialAttributeSet: FALSE objectCategory: CN=Attribute-Schema,${SCHEMADN} # # ms-Exch-Smtp-Ldap-Bind-Type # The bind type to use in DSAccess. dn: CN=ms-Exch-Smtp-Ldap-Bind-Type,${SCHEMADN} objectClass: top objectClass: attributeSchema cn: ms-Exch-Smtp-Ldap-Bind-Type distinguishedName: CN=ms-Exch-Smtp-Ldap-Bind-Type,${SCHEMADN} attributeID: 1.2.840.113556.1.4.7000.102.5040 attributeSyntax: 2.5.5.12 isSingleValued: TRUE showInAdvancedViewOnly: TRUE adminDisplayName: ms-Exch-Smtp-Ldap-Bind-Type adminDescription: ms-Exch-Smtp-Ldap-Bind-Type oMSyntax: 64 searchFlags: 0 lDAPDisplayName: msExchSmtpLdapBindType name: ms-Exch-Smtp-Ldap-Bind-Type schemaIDGUID: 2ebcdcd4-b098-11d2-aa06-00c04f8eedd8 isMemberOfPartialAttributeSet: FALSE objectCategory: CN=Attribute-Schema,${SCHEMADN} # # ms-Exch-Smtp-Ldap-Naming-Context # The naming context to use in DSAccess. # dn: CN=ms-Exch-Smtp-Ldap-Naming-Context,${SCHEMADN} objectClass: top objectClass: attributeSchema cn: ms-Exch-Smtp-Ldap-Naming-Context distinguishedName: CN=ms-Exch-Smtp-Ldap-Naming-Context,${SCHEMADN} attributeID: 1.2.840.113556.1.4.7000.102.5043 attributeSyntax: 2.5.5.12 isSingleValued: TRUE showInAdvancedViewOnly: TRUE adminDisplayName: ms-Exch-Smtp-Ldap-Naming-Context adminDescription: ms-Exch-Smtp-Ldap-Naming-Context oMSyntax: 64 searchFlags: 0 lDAPDisplayName: msExchSmtpLdapNamingContext name: ms-Exch-Smtp-Ldap-Naming-Context schemaIDGUID: 2ef61544-b098-11d2-aa06-00c04f8eedd8 isMemberOfPartialAttributeSet: FALSE objectCategory: CN=Attribute-Schema,${SCHEMADN} # # ms-Exch-Smtp-Ldap-Password # The LDAP password to use in DSAccess. # dn: CN=ms-Exch-Smtp-Ldap-Password,${SCHEMADN} objectClass: top objectClass: attributeSchema cn: ms-Exch-Smtp-Ldap-Password distinguishedName: CN=ms-Exch-Smtp-Ldap-Password,${SCHEMADN} attributeID: 1.2.840.113556.1.4.7000.102.5045 attributeSyntax: 2.5.5.12 isSingleValued: TRUE showInAdvancedViewOnly: TRUE adminDisplayName: ms-Exch-Smtp-Ldap-Password adminDescription: ms-Exch-Smtp-Ldap-Password oMSyntax: 64 searchFlags: 0 lDAPDisplayName: msExchSmtpLdapPassword name: ms-Exch-Smtp-Ldap-Password schemaIDGUID: 2f2f4db4-b098-11d2-aa06-00c04f8eedd8 isMemberOfPartialAttributeSet: FALSE objectCategory: CN=Attribute-Schema,${SCHEMADN} # # ms-Exch-Smtp-Ldap-Schema-Type # The schema type to use in DSAccess. dn: CN=ms-Exch-Smtp-Ldap-Schema-Type,${SCHEMADN} objectClass: top objectClass: attributeSchema cn: ms-Exch-Smtp-Ldap-Schema-Type distinguishedName: CN=ms-Exch-Smtp-Ldap-Schema-Type,${SCHEMADN} attributeID: 1.2.840.113556.1.4.7000.102.5041 attributeSyntax: 2.5.5.12 isSingleValued: TRUE showInAdvancedViewOnly: TRUE adminDisplayName: ms-Exch-Smtp-Ldap-Schema-Type adminDescription: ms-Exch-Smtp-Ldap-Schema-Type oMSyntax: 64 searchFlags: 0 lDAPDisplayName: msExchSmtpLdapSchemaType name: ms-Exch-Smtp-Ldap-Schema-Type schemaIDGUID: 2f688624-b098-11d2-aa06-00c04f8eedd8 isMemberOfPartialAttributeSet: FALSE objectCategory: CN=Attribute-Schema,${SCHEMADN} # # ms-Exch-Smtp-Local-Queue-Delay-Notification # The time at which this resource should send a notification regarding # a local undelivered message. # dn: CN=ms-Exch-Smtp-Local-Queue-Delay-Notification,${SCHEMADN} objectClass: top objectClass: attributeSchema cn: ms-Exch-Smtp-Local-Queue-Delay-Notification distinguishedName: CN=ms-Exch-Smtp-Local-Queue-Delay-Notification,${SCHEMADN} attributeID: 1.2.840.113556.1.4.7000.102.5011 attributeSyntax: 2.5.5.9 isSingleValued: TRUE showInAdvancedViewOnly: TRUE adminDisplayName: ms-Exch-Smtp-Local-Queue-Delay-Notification adminDescription: ms-Exch-Smtp-Local-Queue-Delay-Notification oMSyntax: 2 searchFlags: 0 lDAPDisplayName: msExchSmtpLocalQueueDelayNotification name: ms-Exch-Smtp-Local-Queue-Delay-Notification schemaIDGUID: 2f9f5c3a-b098-11d2-aa06-00c04f8eedd8 isMemberOfPartialAttributeSet: FALSE objectCategory: CN=Attribute-Schema,${SCHEMADN} # # ms-Exch-Smtp-Local-Queue-Expiration-Timeout # The time at which this resource should expire a local undelivered message. # dn: CN=ms-Exch-Smtp-Local-Queue-Expiration-Timeout,${SCHEMADN} objectClass: top objectClass: attributeSchema cn: ms-Exch-Smtp-Local-Queue-Expiration-Timeout distinguishedName: CN=ms-Exch-Smtp-Local-Queue-Expiration-Timeout,${SCHEMADN} attributeID: 1.2.840.113556.1.4.7000.102.5010 attributeSyntax: 2.5.5.9 isSingleValued: TRUE showInAdvancedViewOnly: TRUE adminDisplayName: ms-Exch-Smtp-Local-Queue-Expiration-Timeout adminDescription: ms-Exch-Smtp-Local-Queue-Expiration-Timeout oMSyntax: 2 searchFlags: 0 lDAPDisplayName: msExchSmtpLocalQueueExpirationTimeout name: ms-Exch-Smtp-Local-Queue-Expiration-Timeout schemaIDGUID: 40bd7e66-b098-11d2-aa06-00c04f8eedd8 isMemberOfPartialAttributeSet: FALSE objectCategory: CN=Attribute-Schema,${SCHEMADN} # # ms-Exch-Smtp-Masquerade-Domain # The domain that mail outbound from this resource is masqueraded as. # dn: CN=ms-Exch-Smtp-Masquerade-Domain,${SCHEMADN} objectClass: top objectClass: attributeSchema cn: ms-Exch-Smtp-Masquerade-Domain distinguishedName: CN=ms-Exch-Smtp-Masquerade-Domain,${SCHEMADN} attributeID: 1.2.840.113556.1.4.7000.102.5026 attributeSyntax: 2.5.5.12 isSingleValued: TRUE showInAdvancedViewOnly: TRUE adminDisplayName: ms-Exch-Smtp-Masquerade-Domain adminDescription: ms-Exch-Smtp-Masquerade-Domain oMSyntax: 64 searchFlags: 0 lDAPDisplayName: msExchSmtpMasqueradeDomain name: ms-Exch-Smtp-Masquerade-Domain schemaIDGUID: 40eacb14-b098-11d2-aa06-00c04f8eedd8 isMemberOfPartialAttributeSet: FALSE objectCategory: CN=Attribute-Schema,${SCHEMADN} # # ms-Exch-Smtp-Max-Hop-Count # The maximum number of hops that the message transported by this # resource can take. # dn: CN=ms-Exch-Smtp-Max-Hop-Count,${SCHEMADN} objectClass: top objectClass: attributeSchema cn: ms-Exch-Smtp-Max-Hop-Count distinguishedName: CN=ms-Exch-Smtp-Max-Hop-Count,${SCHEMADN} attributeID: 1.2.840.113556.1.4.7000.102.5006 attributeSyntax: 2.5.5.9 isSingleValued: TRUE showInAdvancedViewOnly: TRUE adminDisplayName: ms-Exch-Smtp-Max-Hop-Count adminDescription: ms-Exch-Smtp-Max-Hop-Count oMSyntax: 2 searchFlags: 0 lDAPDisplayName: msExchSmtpMaxHopCount name: ms-Exch-Smtp-Max-Hop-Count schemaIDGUID: 411817c2-b098-11d2-aa06-00c04f8eedd8 isMemberOfPartialAttributeSet: FALSE objectCategory: CN=Attribute-Schema,${SCHEMADN} # # ms-Exch-Smtp-Max-Message-Size # The maximum size that a message delivered by this resource can be. # dn: CN=ms-Exch-Smtp-Max-Message-Size,${SCHEMADN} objectClass: top objectClass: attributeSchema cn: ms-Exch-Smtp-Max-Message-Size distinguishedName: CN=ms-Exch-Smtp-Max-Message-Size,${SCHEMADN} attributeID: 1.2.840.113556.1.4.7000.102.5007 attributeSyntax: 2.5.5.9 isSingleValued: TRUE showInAdvancedViewOnly: TRUE adminDisplayName: ms-Exch-Smtp-Max-Message-Size adminDescription: ms-Exch-Smtp-Max-Message-Size oMSyntax: 2 searchFlags: 0 lDAPDisplayName: msExchSmtpMaxMessageSize name: ms-Exch-Smtp-Max-Message-Size schemaIDGUID: 4147c6ca-b098-11d2-aa06-00c04f8eedd8 isMemberOfPartialAttributeSet: FALSE objectCategory: CN=Attribute-Schema,${SCHEMADN} # # ms-Exch-Smtp-Max-Outbound-Msg-Per-Domain # The maximum number of messages delivered for connections outgoing # from each domain of this resource. # dn: CN=ms-Exch-Smtp-Max-Outbound-Msg-Per-Domain,${SCHEMADN} objectClass: top objectClass: attributeSchema cn: ms-Exch-Smtp-Max-Outbound-Msg-Per-Domain distinguishedName: CN=ms-Exch-Smtp-Max-Outbound-Msg-Per-Domain,${SCHEMADN} attributeID: 1.2.840.113556.1.4.7000.102.5015 attributeSyntax: 2.5.5.9 isSingleValued: TRUE showInAdvancedViewOnly: TRUE adminDisplayName: ms-Exch-Smtp-Max-Outbound-Msg-Per-Domain adminDescription: ms-Exch-Smtp-Max-Outbound-Msg-Per-Domain oMSyntax: 2 searchFlags: 0 lDAPDisplayName: msExchSmtpMaxOutboundMsgPerDomain name: ms-Exch-Smtp-Max-Outbound-Msg-Per-Domain schemaIDGUID: 417775d2-b098-11d2-aa06-00c04f8eedd8 isMemberOfPartialAttributeSet: FALSE objectCategory: CN=Attribute-Schema,${SCHEMADN} # # ms-Exch-Smtp-Max-Outbound-Msg-Per-Domain-Flag # The maximum number of outbound messages per domain. # dn: CN=ms-Exch-Smtp-Max-Outbound-Msg-Per-Domain-Flag,${SCHEMADN} objectClass: top objectClass: attributeSchema cn: ms-Exch-Smtp-Max-Outbound-Msg-Per-Domain-Flag distinguishedName: CN=ms-Exch-Smtp-Max-Outbound-Msg-Per-Domain-Flag,${SCHEMADN} attributeID: 1.2.840.113556.1.4.7000.102.5023 attributeSyntax: 2.5.5.8 isSingleValued: TRUE showInAdvancedViewOnly: TRUE adminDisplayName: ms-Exch-Smtp-Max-Outbound-Msg-Per-Domain-Flag adminDescription: ms-Exch-Smtp-Max-Outbound-Msg-Per-Domain-Flag oMSyntax: 1 searchFlags: 0 lDAPDisplayName: msExchSmtpMaxOutboundMsgPerDomainFlag name: ms-Exch-Smtp-Max-Outbound-Msg-Per-Domain-Flag schemaIDGUID: 41a724da-b098-11d2-aa06-00c04f8eedd8 isMemberOfPartialAttributeSet: FALSE objectCategory: CN=Attribute-Schema,${SCHEMADN} # # ms-Exch-Smtp-Max-Outgoing-Connections # The maximum number of connections outgoing from this resource. # dn: CN=ms-Exch-Smtp-Max-Outgoing-Connections,${SCHEMADN} objectClass: top objectClass: attributeSchema cn: ms-Exch-Smtp-Max-Outgoing-Connections distinguishedName: CN=ms-Exch-Smtp-Max-Outgoing-Connections,${SCHEMADN} attributeID: 1.2.840.113556.1.4.7000.102.5001 attributeSyntax: 2.5.5.9 isSingleValued: TRUE showInAdvancedViewOnly: TRUE adminDisplayName: ms-Exch-Smtp-Max-Outgoing-Connections adminDescription: ms-Exch-Smtp-Max-Outgoing-Connections oMSyntax: 2 searchFlags: 0 lDAPDisplayName: msExchSmtpMaxOutgoingConnections name: ms-Exch-Smtp-Max-Outgoing-Connections schemaIDGUID: 41d9363c-b098-11d2-aa06-00c04f8eedd8 isMemberOfPartialAttributeSet: FALSE objectCategory: CN=Attribute-Schema,${SCHEMADN} # # ms-Exch-Smtp-Max-Outgoing-Connections-Per-Domain # The maximum length of time for connections outgoing from each domain # of this resource. # dn: CN=ms-Exch-Smtp-Max-Outgoing-Connections-Per-Domain,${SCHEMADN} objectClass: top objectClass: attributeSchema cn: ms-Exch-Smtp-Max-Outgoing-Connections-Per-Domain distinguishedName: CN=ms-Exch-Smtp-Max-Outgoing-Connections-Per-Domain,CN=Sche attributeID: 1.2.840.113556.1.4.7000.102.5003 attributeSyntax: 2.5.5.9 isSingleValued: TRUE showInAdvancedViewOnly: TRUE adminDisplayName: ms-Exch-Smtp-Max-Outgoing-Connections-Per-Domain adminDescription: ms-Exch-Smtp-Max-Outgoing-Connections-Per-Domain oMSyntax: 2 searchFlags: 0 lDAPDisplayName: msExchSmtpMaxOutgoingConnectionsPerDomain name: ms-Exch-Smtp-Max-Outgoing-Connections-Per-Domain schemaIDGUID: 420b479e-b098-11d2-aa06-00c04f8eedd8 isMemberOfPartialAttributeSet: FALSE objectCategory: CN=Attribute-Schema,${SCHEMADN} # # ms-Exch-Smtp-Max-Recipients # The maximum number of recipients allowed on a message transferred by # this resource. # dn: CN=ms-Exch-Smtp-Max-Recipients,${SCHEMADN} objectClass: top objectClass: attributeSchema cn: ms-Exch-Smtp-Max-Recipients distinguishedName: CN=ms-Exch-Smtp-Max-Recipients,${SCHEMADN} attributeID: 1.2.840.113556.1.4.7000.102.5009 attributeSyntax: 2.5.5.9 isSingleValued: TRUE showInAdvancedViewOnly: TRUE adminDisplayName: ms-Exch-Smtp-Max-Recipients adminDescription: ms-Exch-Smtp-Max-Recipients oMSyntax: 2 searchFlags: 0 lDAPDisplayName: msExchSmtpMaxRecipients name: ms-Exch-Smtp-Max-Recipients schemaIDGUID: 423af6a6-b098-11d2-aa06-00c04f8eedd8 isMemberOfPartialAttributeSet: FALSE objectCategory: CN=Attribute-Schema,${SCHEMADN} # # ms-Exch-Smtp-Max-Session-Size # dn: CN=ms-Exch-Smtp-Max-Session-Size,${SCHEMADN} objectClass: top objectClass: attributeSchema cn: ms-Exch-Smtp-Max-Session-Size distinguishedName: CN=ms-Exch-Smtp-Max-Session-Size,${SCHEMADN} attributeID: 1.2.840.113556.1.4.7000.102.5008 attributeSyntax: 2.5.5.9 isSingleValued: TRUE showInAdvancedViewOnly: TRUE adminDisplayName: ms-Exch-Smtp-Max-Session-Size adminDescription: ms-Exch-Smtp-Max-Session-Size oMSyntax: 2 searchFlags: 0 lDAPDisplayName: msExchSmtpMaxSessionSize name: ms-Exch-Smtp-Max-Session-Size schemaIDGUID: 426aa5ae-b098-11d2-aa06-00c04f8eedd8 isMemberOfPartialAttributeSet: FALSE objectCategory: CN=Attribute-Schema,${SCHEMADN} # # ms-Exch-Smtp-Outbound-Security-Flag # Configures which authentication is used when connecting outbound # from this resource. # dn: CN=ms-Exch-Smtp-Outbound-Security-Flag,${SCHEMADN} objectClass: top objectClass: attributeSchema cn: ms-Exch-Smtp-Outbound-Security-Flag distinguishedName: CN=ms-Exch-Smtp-Outbound-Security-Flag,${SCHEMADN} attributeID: 1.2.840.113556.1.4.7000.102.5016 attributeSyntax: 2.5.5.9 isSingleValued: TRUE showInAdvancedViewOnly: TRUE adminDisplayName: ms-Exch-Smtp-Outbound-Security-Flag adminDescription: ms-Exch-Smtp-Outbound-Security-Flag oMSyntax: 2 searchFlags: 0 lDAPDisplayName: msExchSmtpOutboundSecurityFlag name: ms-Exch-Smtp-Outbound-Security-Flag schemaIDGUID: 429cb710-b098-11d2-aa06-00c04f8eedd8 isMemberOfPartialAttributeSet: FALSE objectCategory: CN=Attribute-Schema,${SCHEMADN} # # ms-Exch-Smtp-Outbound-Security-Password # The password for outbound security. # dn: CN=ms-Exch-Smtp-Outbound-Security-Password,${SCHEMADN} objectClass: top objectClass: attributeSchema cn: ms-Exch-Smtp-Outbound-Security-Password distinguishedName: CN=ms-Exch-Smtp-Outbound-Security-Password,${SCHEMADN} attributeID: 1.2.840.113556.1.4.7000.102.5035 attributeSyntax: 2.5.5.12 isSingleValued: TRUE showInAdvancedViewOnly: TRUE adminDisplayName: ms-Exch-Smtp-Outbound-Security-Password adminDescription: ms-Exch-Smtp-Outbound-Security-Password oMSyntax: 64 searchFlags: 0 lDAPDisplayName: msExchSmtpOutboundSecurityPassword name: ms-Exch-Smtp-Outbound-Security-Password schemaIDGUID: 42edc704-b098-11d2-aa06-00c04f8eedd8 isMemberOfPartialAttributeSet: FALSE objectCategory: CN=Attribute-Schema,${SCHEMADN} # # ms-Exch-Smtp-Outbound-Security-User-Name # User name for outbound security. # dn: CN=ms-Exch-Smtp-Outbound-Security-User-Name,${SCHEMADN} objectClass: top objectClass: attributeSchema cn: ms-Exch-Smtp-Outbound-Security-User-Name distinguishedName: CN=ms-Exch-Smtp-Outbound-Security-User-Name,${SCHEMADN} attributeID: 1.2.840.113556.1.4.7000.102.5034 attributeSyntax: 2.5.5.12 isSingleValued: TRUE showInAdvancedViewOnly: TRUE adminDisplayName: ms-Exch-Smtp-Outbound-Security-User-Name adminDescription: ms-Exch-Smtp-Outbound-Security-User-Name oMSyntax: 64 searchFlags: 0 lDAPDisplayName: msExchSmtpOutboundSecurityUserName name: ms-Exch-Smtp-Outbound-Security-User-Name schemaIDGUID: 43249d1a-b098-11d2-aa06-00c04f8eedd8 isMemberOfPartialAttributeSet: FALSE objectCategory: CN=Attribute-Schema,${SCHEMADN} # # ms-Exch-Smtp-Outgoing-Connection-Timeout # The maximum length of time for connections outgoing from this resource. # dn: CN=ms-Exch-Smtp-Outgoing-Connection-Timeout,${SCHEMADN} objectClass: top objectClass: attributeSchema cn: ms-Exch-Smtp-Outgoing-Connection-Timeout distinguishedName: CN=ms-Exch-Smtp-Outgoing-Connection-Timeout,${SCHEMADN} attributeID: 1.2.840.113556.1.4.7000.102.5002 attributeSyntax: 2.5.5.9 isSingleValued: TRUE showInAdvancedViewOnly: TRUE adminDisplayName: ms-Exch-Smtp-Outgoing-Connection-Timeout adminDescription: ms-Exch-Smtp-Outgoing-Connection-Timeout oMSyntax: 2 searchFlags: 0 lDAPDisplayName: msExchSmtpOutgoingConnectionTimeout name: ms-Exch-Smtp-Outgoing-Connection-Timeout schemaIDGUID: 436037e4-b098-11d2-aa06-00c04f8eedd8 isMemberOfPartialAttributeSet: FALSE objectCategory: CN=Attribute-Schema,${SCHEMADN} # # ms-Exch-Smtp-Outgoing-Port # The outbound connection port number. # dn: CN=ms-Exch-Smtp-Outgoing-Port,${SCHEMADN} objectClass: top objectClass: attributeSchema cn: ms-Exch-Smtp-Outgoing-Port distinguishedName: CN=ms-Exch-Smtp-Outgoing-Port,${SCHEMADN} attributeID: 1.2.840.113556.1.4.7000.102.5004 attributeSyntax: 2.5.5.9 isSingleValued: TRUE showInAdvancedViewOnly: TRUE adminDisplayName: ms-Exch-Smtp-Outgoing-Port adminDescription: ms-Exch-Smtp-Outgoing-Port oMSyntax: 2 searchFlags: 0 lDAPDisplayName: msExchSmtpOutgoingPort name: ms-Exch-Smtp-Outgoing-Port schemaIDGUID: 43b3aa32-b098-11d2-aa06-00c04f8eedd8 isMemberOfPartialAttributeSet: FALSE objectCategory: CN=Attribute-Schema,${SCHEMADN} # # ms-Exch-Smtp-Outgoing-Secure-Port # The outbound connection SSL port number. # dn: CN=ms-Exch-Smtp-Outgoing-Secure-Port,${SCHEMADN} objectClass: top objectClass: attributeSchema cn: ms-Exch-Smtp-Outgoing-Secure-Port distinguishedName: CN=ms-Exch-Smtp-Outgoing-Secure-Port,${SCHEMADN} attributeID: 1.2.840.113556.1.4.7000.102.5005 attributeSyntax: 2.5.5.9 isSingleValued: TRUE showInAdvancedViewOnly: TRUE adminDisplayName: ms-Exch-Smtp-Outgoing-Secure-Port adminDescription: ms-Exch-Smtp-Outgoing-Secure-Port oMSyntax: 2 searchFlags: 0 lDAPDisplayName: msExchSmtpOutgoingSecurePort name: ms-Exch-Smtp-Outgoing-Secure-Port schemaIDGUID: 43f1a756-b098-11d2-aa06-00c04f8eedd8 isMemberOfPartialAttributeSet: FALSE objectCategory: CN=Attribute-Schema,${SCHEMADN} # # ms-Exch-Smtp-Perform-Reverse-Dns-Lookup # Performs reverse DNS lookup for delivery. # dn: CN=ms-Exch-Smtp-Perform-Reverse-Dns-Lookup,${SCHEMADN} objectClass: top objectClass: attributeSchema cn: ms-Exch-Smtp-Perform-Reverse-Dns-Lookup distinguishedName: CN=ms-Exch-Smtp-Perform-Reverse-Dns-Lookup,${SCHEMADN} attributeID: 1.2.840.113556.1.4.7000.102.5021 attributeSyntax: 2.5.5.8 isSingleValued: TRUE showInAdvancedViewOnly: TRUE adminDisplayName: ms-Exch-Smtp-Perform-Reverse-Dns-Lookup adminDescription: ms-Exch-Smtp-Perform-Reverse-Dns-Lookup oMSyntax: 1 searchFlags: 0 lDAPDisplayName: msExchSmtpPerformReverseDnsLookup name: ms-Exch-Smtp-Perform-Reverse-Dns-Lookup schemaIDGUID: 441ef404-b098-11d2-aa06-00c04f8eedd8 isMemberOfPartialAttributeSet: FALSE objectCategory: CN=Attribute-Schema,${SCHEMADN} # # ms-Exch-Smtp-Pickup-Directory # The directory from which mail messages are being picked up. # dn: CN=ms-Exch-Smtp-Pickup-Directory,${SCHEMADN} objectClass: top objectClass: attributeSchema cn: ms-Exch-Smtp-Pickup-Directory distinguishedName: CN=ms-Exch-Smtp-Pickup-Directory,${SCHEMADN} attributeID: 1.2.840.113556.1.4.7000.102.5030 attributeSyntax: 2.5.5.12 isSingleValued: TRUE showInAdvancedViewOnly: TRUE adminDisplayName: ms-Exch-Smtp-Pickup-Directory adminDescription: ms-Exch-Smtp-Pickup-Directory oMSyntax: 64 searchFlags: 0 lDAPDisplayName: msExchSmtpPickupDirectory name: ms-Exch-Smtp-Pickup-Directory schemaIDGUID: 444054f0-b098-11d2-aa06-00c04f8eedd8 isMemberOfPartialAttributeSet: FALSE objectCategory: CN=Attribute-Schema,${SCHEMADN} # # ms-Exch-Smtp-Queue-Directory # The directory where mail messages are being queued. # dn: CN=ms-Exch-Smtp-Queue-Directory,${SCHEMADN} objectClass: top objectClass: attributeSchema cn: ms-Exch-Smtp-Queue-Directory distinguishedName: CN=ms-Exch-Smtp-Queue-Directory,${SCHEMADN} attributeID: 1.2.840.113556.1.4.7000.102.5031 attributeSyntax: 2.5.5.12 isSingleValued: TRUE showInAdvancedViewOnly: TRUE adminDisplayName: ms-Exch-Smtp-Queue-Directory adminDescription: ms-Exch-Smtp-Queue-Directory oMSyntax: 64 searchFlags: 0 lDAPDisplayName: msExchSmtpQueueDirectory name: ms-Exch-Smtp-Queue-Directory schemaIDGUID: 4468dcea-b098-11d2-aa06-00c04f8eedd8 isMemberOfPartialAttributeSet: FALSE objectCategory: CN=Attribute-Schema,${SCHEMADN} # # ms-Exch-Smtp-Relay-For-Auth # Checks if the relay IP requires authentication. # dn: CN=ms-Exch-Smtp-Relay-For-Auth,${SCHEMADN} objectClass: top objectClass: attributeSchema cn: ms-Exch-Smtp-Relay-For-Auth distinguishedName: CN=ms-Exch-Smtp-Relay-For-Auth,${SCHEMADN} attributeID: 1.2.840.113556.1.4.7000.102.5020 attributeSyntax: 2.5.5.8 isSingleValued: TRUE showInAdvancedViewOnly: TRUE adminDisplayName: ms-Exch-Smtp-Relay-For-Auth adminDescription: ms-Exch-Smtp-Relay-For-Auth oMSyntax: 1 searchFlags: 0 lDAPDisplayName: msExchSmtpRelayForAuth name: ms-Exch-Smtp-Relay-For-Auth schemaIDGUID: 449164e4-b098-11d2-aa06-00c04f8eedd8 isMemberOfPartialAttributeSet: FALSE objectCategory: CN=Attribute-Schema,${SCHEMADN} # # ms-Exch-Smtp-Relay-Ip-List # List of Internet Protocols (IPs) for relay restriction. # dn: CN=ms-Exch-Smtp-Relay-Ip-List,${SCHEMADN} objectClass: top objectClass: attributeSchema cn: ms-Exch-Smtp-Relay-Ip-List distinguishedName: CN=ms-Exch-Smtp-Relay-Ip-List,${SCHEMADN} attributeID: 1.2.840.113556.1.4.7000.102.5048 attributeSyntax: 2.5.5.10 isSingleValued: TRUE showInAdvancedViewOnly: TRUE adminDisplayName: ms-Exch-Smtp-Relay-Ip-List adminDescription: ms-Exch-Smtp-Relay-Ip-List oMSyntax: 4 searchFlags: 0 lDAPDisplayName: msExchSmtpRelayIpList name: ms-Exch-Smtp-Relay-Ip-List schemaIDGUID: 44b5282a-b098-11d2-aa06-00c04f8eedd8 isMemberOfPartialAttributeSet: FALSE objectCategory: CN=Attribute-Schema,${SCHEMADN} # # ms-Exch-Smtp-Remote-Queue-Delay-Notification # The time at which this resource should send a notification regarding # an undelivered outbound message. # dn: CN=ms-Exch-Smtp-Remote-Queue-Delay-Notification,${SCHEMADN} objectClass: top objectClass: attributeSchema cn: ms-Exch-Smtp-Remote-Queue-Delay-Notification distinguishedName: CN=ms-Exch-Smtp-Remote-Queue-Delay-Notification,${SCHEMADN} attributeID: 1.2.840.113556.1.4.7000.102.5013 attributeSyntax: 2.5.5.9 isSingleValued: TRUE showInAdvancedViewOnly: TRUE adminDisplayName: ms-Exch-Smtp-Remote-Queue-Delay-Notification adminDescription: ms-Exch-Smtp-Remote-Queue-Delay-Notification oMSyntax: 2 searchFlags: 0 lDAPDisplayName: msExchSmtpRemoteQueueDelayNotification name: ms-Exch-Smtp-Remote-Queue-Delay-Notification schemaIDGUID: 44ddb024-b098-11d2-aa06-00c04f8eedd8 isMemberOfPartialAttributeSet: FALSE objectCategory: CN=Attribute-Schema,${SCHEMADN} # # ms-Exch-Smtp-Remote-Queue-Expiration-Timeout # The time at which this resource should expire an undelivered # outbound message. # dn: CN=ms-Exch-Smtp-Remote-Queue-Expiration-Timeout,${SCHEMADN} objectClass: top objectClass: attributeSchema cn: ms-Exch-Smtp-Remote-Queue-Expiration-Timeout distinguishedName: CN=ms-Exch-Smtp-Remote-Queue-Expiration-Timeout,${SCHEMADN} attributeID: 1.2.840.113556.1.4.7000.102.5012 attributeSyntax: 2.5.5.9 isSingleValued: TRUE showInAdvancedViewOnly: TRUE adminDisplayName: ms-Exch-Smtp-Remote-Queue-Expiration-Timeout adminDescription: ms-Exch-Smtp-Remote-Queue-Expiration-Timeout oMSyntax: 2 searchFlags: 0 lDAPDisplayName: msExchSmtpRemoteQueueExpirationTimeout name: ms-Exch-Smtp-Remote-Queue-Expiration-Timeout schemaIDGUID: 4501736a-b098-11d2-aa06-00c04f8eedd8 isMemberOfPartialAttributeSet: FALSE objectCategory: CN=Attribute-Schema,${SCHEMADN} # # ms-Exch-Smtp-Remote-Queue-Retries # The first, second, third, and subsequent retries for remote mail # delivery. # dn: CN=ms-Exch-Smtp-Remote-Queue-Retries,${SCHEMADN} objectClass: top objectClass: attributeSchema cn: ms-Exch-Smtp-Remote-Queue-Retries distinguishedName: CN=ms-Exch-Smtp-Remote-Queue-Retries,${SCHEMADN} attributeID: 1.2.840.113556.1.4.7000.102.5046 attributeSyntax: 2.5.5.12 isSingleValued: TRUE showInAdvancedViewOnly: TRUE adminDisplayName: ms-Exch-Smtp-Remote-Queue-Retries adminDescription: ms-Exch-Smtp-Remote-Queue-Retries oMSyntax: 64 searchFlags: 0 lDAPDisplayName: msExchSmtpRemoteQueueRetries name: ms-Exch-Smtp-Remote-Queue-Retries schemaIDGUID: 4527990a-b098-11d2-aa06-00c04f8eedd8 isMemberOfPartialAttributeSet: FALSE objectCategory: CN=Attribute-Schema,${SCHEMADN} # # ms-Exch-Smtp-Routing-Table-Type # The routing table type for DSAccess. # dn: CN=ms-Exch-Smtp-Routing-Table-Type,${SCHEMADN} objectClass: top objectClass: attributeSchema cn: ms-Exch-Smtp-Routing-Table-Type distinguishedName: CN=ms-Exch-Smtp-Routing-Table-Type,${SCHEMADN} attributeID: 1.2.840.113556.1.4.7000.102.5039 attributeSyntax: 2.5.5.12 isSingleValued: TRUE showInAdvancedViewOnly: TRUE adminDisplayName: ms-Exch-Smtp-Routing-Table-Type adminDescription: ms-Exch-Smtp-Routing-Table-Type oMSyntax: 64 searchFlags: 0 lDAPDisplayName: msExchSmtpRoutingTableType name: ms-Exch-Smtp-Routing-Table-Type schemaIDGUID: 454dbeaa-b098-11d2-aa06-00c04f8eedd8 isMemberOfPartialAttributeSet: FALSE objectCategory: CN=Attribute-Schema,${SCHEMADN} # # ms-Exch-Smtp-Send-Badmail-To # The address to send bad mail to. # dn: CN=ms-Exch-Smtp-Send-Badmail-To,${SCHEMADN} objectClass: top objectClass: attributeSchema cn: ms-Exch-Smtp-Send-Badmail-To distinguishedName: CN=ms-Exch-Smtp-Send-Badmail-To,${SCHEMADN} attributeID: 1.2.840.113556.1.4.7000.102.5028 attributeSyntax: 2.5.5.12 isSingleValued: TRUE showInAdvancedViewOnly: TRUE adminDisplayName: ms-Exch-Smtp-Send-Badmail-To adminDescription: ms-Exch-Smtp-Send-Badmail-To oMSyntax: 64 searchFlags: 0 lDAPDisplayName: msExchSmtpSendBadmailTo name: ms-Exch-Smtp-Send-Badmail-To schemaIDGUID: 4586f71a-b098-11d2-aa06-00c04f8eedd8 isMemberOfPartialAttributeSet: FALSE objectCategory: CN=Attribute-Schema,${SCHEMADN} # # ms-Exch-Smtp-Send-NDR-To # The address to send a non-delivery report to. # dn: CN=ms-Exch-Smtp-Send-NDR-To,${SCHEMADN} objectClass: top objectClass: attributeSchema cn: ms-Exch-Smtp-Send-NDR-To distinguishedName: CN=ms-Exch-Smtp-Send-NDR-To,${SCHEMADN} attributeID: 1.2.840.113556.1.4.7000.102.5027 attributeSyntax: 2.5.5.12 isSingleValued: TRUE showInAdvancedViewOnly: TRUE adminDisplayName: ms-Exch-Smtp-Send-NDR-To adminDescription: ms-Exch-Smtp-Send-NDR-To oMSyntax: 64 searchFlags: 0 lDAPDisplayName: msExchSmtpSendNDRTo name: ms-Exch-Smtp-Send-NDR-To schemaIDGUID: 45bb6ad6-b098-11d2-aa06-00c04f8eedd8 isMemberOfPartialAttributeSet: FALSE objectCategory: CN=Attribute-Schema,${SCHEMADN} # # ms-Exch-Smtp-Smart-Host # Sets a Smart Host route domain for mail outbound from this resource. # dn: CN=ms-Exch-Smtp-Smart-Host,${SCHEMADN} objectClass: top objectClass: attributeSchema cn: ms-Exch-Smtp-Smart-Host distinguishedName: CN=ms-Exch-Smtp-Smart-Host,${SCHEMADN} attributeID: 1.2.840.113556.1.4.7000.102.5024 attributeSyntax: 2.5.5.12 isSingleValued: TRUE showInAdvancedViewOnly: TRUE adminDisplayName: ms-Exch-Smtp-Smart-Host adminDescription: ms-Exch-Smtp-Smart-Host oMSyntax: 64 searchFlags: 0 lDAPDisplayName: msExchSmtpSmartHost name: ms-Exch-Smtp-Smart-Host schemaIDGUID: 45e19076-b098-11d2-aa06-00c04f8eedd8 isMemberOfPartialAttributeSet: FALSE objectCategory: CN=Attribute-Schema,${SCHEMADN} # # ms-Exch-Smtp-Smart-Host-Type # The Smart Host type. # dn: CN=ms-Exch-Smtp-Smart-Host-Type,${SCHEMADN} objectClass: top objectClass: attributeSchema cn: ms-Exch-Smtp-Smart-Host-Type distinguishedName: CN=ms-Exch-Smtp-Smart-Host-Type,${SCHEMADN} attributeID: 1.2.840.113556.1.4.7000.102.5014 attributeSyntax: 2.5.5.9 isSingleValued: TRUE showInAdvancedViewOnly: TRUE adminDisplayName: ms-Exch-Smtp-Smart-Host-Type adminDescription: ms-Exch-Smtp-Smart-Host-Type oMSyntax: 2 searchFlags: 0 lDAPDisplayName: msExchSmtpSmartHostType name: ms-Exch-Smtp-Smart-Host-Type schemaIDGUID: 46008f08-b098-11d2-aa06-00c04f8eedd8 isMemberOfPartialAttributeSet: FALSE objectCategory: CN=Attribute-Schema,${SCHEMADN} # # ms-Exch-Smtp-TRN-Smart-Host # Contains an alternate Smart Host to which the server should issue # the TURN or ETRN command. # dn: CN=ms-Exch-Smtp-TRN-Smart-Host,${SCHEMADN} objectClass: top objectClass: attributeSchema cn: ms-Exch-Smtp-TRN-Smart-Host distinguishedName: CN=ms-Exch-Smtp-TRN-Smart-Host,${SCHEMADN} attributeID: 1.2.840.113556.1.4.7000.102.12531 attributeSyntax: 2.5.5.12 isSingleValued: TRUE showInAdvancedViewOnly: TRUE adminDisplayName: ms-Exch-Smtp-TRN-Smart-Host adminDescription: ms-Exch-Smtp-TRN-Smart-Host oMSyntax: 64 searchFlags: 0 lDAPDisplayName: msExchSmtpTRNSmartHost name: ms-Exch-Smtp-TRN-Smart-Host schemaIDGUID: be41789c-2da8-11d3-aa6b-00c04f8eedd8 isMemberOfPartialAttributeSet: FALSE objectCategory: CN=Attribute-Schema,${SCHEMADN} # # ms-Exch-Source-BH-Address # dn: CN=ms-Exch-Source-BH-Address,${SCHEMADN} objectClass: top objectClass: attributeSchema cn: ms-Exch-Source-BH-Address distinguishedName: CN=ms-Exch-Source-BH-Address,${SCHEMADN} attributeID: 1.2.840.113556.1.4.7000.102.12509 attributeSyntax: 2.5.5.4 isSingleValued: TRUE rangeLower: 0 rangeUpper: 255 showInAdvancedViewOnly: TRUE adminDisplayName: ms-Exch-Source-BH-Address adminDescription: ms-Exch-Source-BH-Address oMSyntax: 20 searchFlags: 0 lDAPDisplayName: msExchSourceBHAddress name: ms-Exch-Source-BH-Address schemaIDGUID: 203d2f32-b099-11d2-aa06-00c04f8eedd8 isMemberOfPartialAttributeSet: FALSE objectCategory: CN=Attribute-Schema,${SCHEMADN} # # ms-Exch-Source-Bridgehead-Servers-DN # Pointers to SMTP virtual servers of servers in bridgehead on the # local side of Exchange Connector. # dn: CN=ms-Exch-Source-Bridgehead-Servers-DN,${SCHEMADN} objectClass: top objectClass: attributeSchema cn: ms-Exch-Source-Bridgehead-Servers-DN distinguishedName: CN=ms-Exch-Source-Bridgehead-Servers-DN,${SCHEMADN} attributeID: 1.2.840.113556.1.4.7000.102.12511 attributeSyntax: 2.5.5.1 isSingleValued: FALSE linkID: 1002 showInAdvancedViewOnly: TRUE adminDisplayName: ms-Exch-Source-Bridgehead-Servers-DN oMObjectClass:: KwwCh3McAIVK adminDescription: ms-Exch-Source-Bridgehead-Servers-DN oMSyntax: 127 searchFlags: 0 lDAPDisplayName: msExchSourceBridgeheadServersDN name: ms-Exch-Source-Bridgehead-Servers-DN schemaIDGUID: 206f4094-b099-11d2-aa06-00c04f8eedd8 isMemberOfPartialAttributeSet: FALSE objectCategory: CN=Attribute-Schema,${SCHEMADN} # # ms-Exch-Space-Last-Computed # The time at which the site-proxy-space was last computed. # dn: CN=ms-Exch-Space-Last-Computed,${SCHEMADN} objectClass: top objectClass: attributeSchema cn: ms-Exch-Space-Last-Computed distinguishedName: CN=ms-Exch-Space-Last-Computed,${SCHEMADN} attributeID: 1.2.840.113556.1.2.386 attributeSyntax: 2.5.5.11 isSingleValued: TRUE mAPIID: 33081 showInAdvancedViewOnly: TRUE adminDisplayName: ms-Exch-Space-Last-Computed adminDescription: ms-Exch-Space-Last-Computed oMSyntax: 23 searchFlags: 0 lDAPDisplayName: spaceLastComputed name: ms-Exch-Space-Last-Computed schemaIDGUID: 9928d7bc-b093-11d2-aa06-00c04f8eedd8 isMemberOfPartialAttributeSet: FALSE objectCategory: CN=Attribute-Schema,${SCHEMADN} # # ms-Exch-Submission-Cont-Length # Contains the maximum size message allowed to be submitted, either # globally or by this user. # dn: CN=ms-Exch-Submission-Cont-Length,${SCHEMADN} objectClass: top objectClass: attributeSchema cn: ms-Exch-Submission-Cont-Length distinguishedName: CN=ms-Exch-Submission-Cont-Length,${SCHEMADN} attributeID: 1.2.840.113556.1.2.280 attributeSyntax: 2.5.5.9 isSingleValued: TRUE mAPIID: 33084 showInAdvancedViewOnly: TRUE adminDisplayName: ms-Exch-Submission-Cont-Length adminDescription: ms-Exch-Submission-Cont-Length oMSyntax: 2 searchFlags: 16 lDAPDisplayName: submissionContLength name: ms-Exch-Submission-Cont-Length schemaIDGUID: bf967a3e-0de6-11d0-a285-00aa003049e2 attributeSecurityGUID: e48d0154-bcf8-11d1-8702-00c04fb96050 isMemberOfPartialAttributeSet: TRUE objectCategory: CN=Attribute-Schema,${SCHEMADN} # # ms-Exch-SubmitRelaySD # dn: CN=ms-Exch-SubmitRelaySD,${SCHEMADN} objectClass: top objectClass: attributeSchema cn: ms-Exch-SubmitRelaySD distinguishedName: CN=ms-Exch-SubmitRelaySD,${SCHEMADN} attributeID: 1.2.840.113556.1.4.5060 attributeSyntax: 2.5.5.15 isSingleValued: TRUE showInAdvancedViewOnly: TRUE adminDisplayName: ms-Exch-SubmitRelaySD adminDescription: ms-Exch-SubmitRelaySD oMSyntax: 66 searchFlags: 0 lDAPDisplayName: msExchSubmitRelaySD name: ms-Exch-SubmitRelaySD schemaIDGUID: e2cefbcc-dcc1-45a5-bab8-d5f4bd78884d isMemberOfPartialAttributeSet: FALSE objectCategory: CN=Attribute-Schema,${SCHEMADN} # # ms-Exch-Supported-Algorithms # dn: CN=ms-Exch-Supported-Algorithms,${SCHEMADN} objectClass: top objectClass: attributeSchema cn: ms-Exch-Supported-Algorithms distinguishedName: CN=ms-Exch-Supported-Algorithms,${SCHEMADN} attributeID: 1.2.840.113556.1.2.597 attributeSyntax: 2.5.5.10 isSingleValued: TRUE rangeLower: 1 rangeUpper: 32767 mAPIID: 35925 showInAdvancedViewOnly: TRUE adminDisplayName: ms-Exch-Supported-Algorithms adminDescription: ms-Exch-Supported-Algorithms oMSyntax: 4 searchFlags: 0 lDAPDisplayName: supportedAlgorithms name: ms-Exch-Supported-Algorithms schemaIDGUID: 1677588e-47f3-11d1-a9c3-0000f80367c1 attributeSecurityGUID: e48d0154-bcf8-11d1-8702-00c04fb96050 isMemberOfPartialAttributeSet: TRUE objectCategory: CN=Attribute-Schema,${SCHEMADN} # # ms-Exch-Supporting-Stack # dn: CN=ms-Exch-Supporting-Stack,${SCHEMADN} objectClass: top objectClass: attributeSchema cn: ms-Exch-Supporting-Stack distinguishedName: CN=ms-Exch-Supporting-Stack,${SCHEMADN} attributeID: 1.2.840.113556.1.2.28 attributeSyntax: 2.5.5.1 isSingleValued: FALSE mAPIID: 33086 linkID: 132 showInAdvancedViewOnly: TRUE adminDisplayName: ms-Exch-Supporting-Stack oMObjectClass:: KwwCh3McAIVK adminDescription: ms-Exch-Supporting-Stack oMSyntax: 127 searchFlags: 0 lDAPDisplayName: supportingStack name: ms-Exch-Supporting-Stack schemaIDGUID: a8df7480-c5ea-11d1-bbcb-0080c76670c0 isMemberOfPartialAttributeSet: FALSE objectCategory: CN=Attribute-Schema,${SCHEMADN} # # ms-Exch-Supporting-Stack-BL # dn: CN=ms-Exch-Supporting-Stack-BL,${SCHEMADN} objectClass: top objectClass: attributeSchema cn: ms-Exch-Supporting-Stack-BL distinguishedName: CN=ms-Exch-Supporting-Stack-BL,${SCHEMADN} attributeID: 1.2.840.113556.1.2.357 attributeSyntax: 2.5.5.1 isSingleValued: FALSE mAPIID: 33087 linkID: 133 showInAdvancedViewOnly: TRUE adminDisplayName: ms-Exch-Supporting-Stack-BL oMObjectClass:: KwwCh3McAIVK adminDescription: ms-Exch-Supporting-Stack-BL oMSyntax: 127 searchFlags: 0 lDAPDisplayName: supportingStackBL name: ms-Exch-Supporting-Stack-BL schemaIDGUID: 16775891-47f3-11d1-a9c3-0000f80367c1 systemFlags: 1 isMemberOfPartialAttributeSet: FALSE objectCategory: CN=Attribute-Schema,${SCHEMADN} # # ms-Exch-Support-SMIME-Signatures # dn: CN=ms-Exch-Support-SMIME-Signatures,${SCHEMADN} objectClass: top objectClass: attributeSchema cn: ms-Exch-Support-SMIME-Signatures distinguishedName: CN=ms-Exch-Support-SMIME-Signatures,${SCHEMADN} attributeID: 1.2.840.113556.1.2.590 attributeSyntax: 2.5.5.8 isSingleValued: TRUE mAPIID: 35912 showInAdvancedViewOnly: TRUE adminDisplayName: ms-Exch-Support-SMIME-Signatures adminDescription: ms-Exch-Support-SMIME-Signatures oMSyntax: 1 searchFlags: 0 lDAPDisplayName: supportSMIMESignatures name: ms-Exch-Support-SMIME-Signatures schemaIDGUID: a8df747f-c5ea-11d1-bbcb-0080c76670c0 isMemberOfPartialAttributeSet: FALSE objectCategory: CN=Attribute-Schema,${SCHEMADN} # # ms-Exch-Synchronization-Direction # The direction in which the directories will be synchronized. # dn: CN=ms-Exch-Synchronization-Direction,${SCHEMADN} objectClass: top objectClass: attributeSchema cn: ms-Exch-Synchronization-Direction distinguishedName: CN=ms-Exch-Synchronization-Direction,${SCHEMADN} attributeID: 1.2.840.113556.1.4.7000.102.1 attributeSyntax: 2.5.5.9 isSingleValued: TRUE rangeLower: 0 rangeUpper: 2 showInAdvancedViewOnly: TRUE adminDisplayName: ms-Exch-Synchronization-Direction adminDescription: ms-Exch-Synchronization-Direction oMSyntax: 10 searchFlags: 0 lDAPDisplayName: msExchSynchronizationDirection name: ms-Exch-Synchronization-Direction schemaIDGUID: 20a151f6-b099-11d2-aa06-00c04f8eedd8 isMemberOfPartialAttributeSet: FALSE objectCategory: CN=Attribute-Schema,${SCHEMADN} # # ms-Exch-S-Selector # dn: CN=ms-Exch-S-Selector,${SCHEMADN} objectClass: top objectClass: attributeSchema cn: ms-Exch-S-Selector distinguishedName: CN=ms-Exch-S-Selector,${SCHEMADN} attributeID: 1.2.840.113556.1.2.284 attributeSyntax: 2.5.5.10 isSingleValued: TRUE rangeLower: 1 rangeUpper: 16 mAPIID: 33067 showInAdvancedViewOnly: TRUE adminDisplayName: ms-Exch-S-Selector adminDescription: ms-Exch-S-Selector oMSyntax: 4 searchFlags: 0 lDAPDisplayName: sSelector name: ms-Exch-S-Selector schemaIDGUID: a8df746c-c5ea-11d1-bbcb-0080c76670c0 isMemberOfPartialAttributeSet: TRUE objectCategory: CN=Attribute-Schema,${SCHEMADN} # # ms-Exch-S-Selector-Inbound # dn: CN=ms-Exch-S-Selector-Inbound,${SCHEMADN} objectClass: top objectClass: attributeSchema cn: ms-Exch-S-Selector-Inbound distinguishedName: CN=ms-Exch-S-Selector-Inbound,${SCHEMADN} attributeID: 1.2.840.113556.1.2.46 attributeSyntax: 2.5.5.10 isSingleValued: TRUE rangeLower: 1 rangeUpper: 16 mAPIID: 33068 showInAdvancedViewOnly: TRUE adminDisplayName: ms-Exch-S-Selector-Inbound adminDescription: ms-Exch-S-Selector-Inbound oMSyntax: 4 searchFlags: 0 lDAPDisplayName: sSelectorInbound name: ms-Exch-S-Selector-Inbound schemaIDGUID: a8df746d-c5ea-11d1-bbcb-0080c76670c0 isMemberOfPartialAttributeSet: TRUE objectCategory: CN=Attribute-Schema,${SCHEMADN} # # ms-Exch-Target-Address # Contains the destination address for this object. dn: CN=ms-Exch-Target-Address,${SCHEMADN} objectClass: top objectClass: attributeSchema cn: ms-Exch-Target-Address distinguishedName: CN=ms-Exch-Target-Address,${SCHEMADN} attributeID: 1.2.840.113556.1.2.352 attributeSyntax: 2.5.5.12 isSingleValued: TRUE rangeLower: 1 rangeUpper: 1123 mAPIID: 32785 showInAdvancedViewOnly: TRUE adminDisplayName: ms-Exch-Target-Address adminDescription: ms-Exch-Target-Address oMSyntax: 64 searchFlags: 1 lDAPDisplayName: targetAddress name: ms-Exch-Target-Address schemaIDGUID: f0f8ff9f-1191-11d0-a060-00aa006c33ed attributeSecurityGUID: e48d0154-bcf8-11d1-8702-00c04fb96050 isMemberOfPartialAttributeSet: TRUE objectCategory: CN=Attribute-Schema,${SCHEMADN} # # ms-Exch-Target-Bridgehead-Servers-DN # Pointers to bridgehead SMTP virtual servers in the connector target # routing group (RG). # dn: CN=ms-Exch-Target-Bridgehead-Servers-DN,${SCHEMADN} objectClass: top objectClass: attributeSchema cn: ms-Exch-Target-Bridgehead-Servers-DN distinguishedName: CN=ms-Exch-Target-Bridgehead-Servers-DN,${SCHEMADN} attributeID: 1.2.840.113556.1.4.7000.102.12514 attributeSyntax: 2.5.5.1 isSingleValued: FALSE linkID: 1004 showInAdvancedViewOnly: TRUE adminDisplayName: ms-Exch-Target-Bridgehead-Servers-DN oMObjectClass:: KwwCh3McAIVK adminDescription: ms-Exch-Target-Bridgehead-Servers-DN oMSyntax: 127 searchFlags: 0 lDAPDisplayName: msExchTargetBridgeheadServersDN name: ms-Exch-Target-Bridgehead-Servers-DN schemaIDGUID: 20da8a66-b099-11d2-aa06-00c04f8eedd8 isMemberOfPartialAttributeSet: FALSE objectCategory: CN=Attribute-Schema,${SCHEMADN} # # ms-Exch-Target-MTAs # Used by Exchange Server 5.5 to indicate the message transfer agents # (MTAs) on the remote side of a connector. # dn: CN=ms-Exch-Target-MTAs,${SCHEMADN} objectClass: top objectClass: attributeSchema cn: ms-Exch-Target-MTAs distinguishedName: CN=ms-Exch-Target-MTAs,${SCHEMADN} attributeID: 1.2.840.113556.1.2.259 attributeSyntax: 2.5.5.4 isSingleValued: FALSE rangeLower: 1 rangeUpper: 36 mAPIID: 33090 showInAdvancedViewOnly: TRUE adminDisplayName: ms-Exch-Target-MTAs adminDescription: ms-Exch-Target-MTAs oMSyntax: 20 searchFlags: 0 lDAPDisplayName: targetMTAs name: ms-Exch-Target-MTAs schemaIDGUID: a8df7483-c5ea-11d1-bbcb-0080c76670c0 isMemberOfPartialAttributeSet: FALSE objectCategory: CN=Attribute-Schema,${SCHEMADN} # # ms-Exch-Telephone-Assistant # The telephone number of the assistant that corresponds to this user. # dn: CN=ms-Exch-Telephone-Assistant,${SCHEMADN} objectClass: top objectClass: attributeSchema cn: ms-Exch-Telephone-Assistant distinguishedName: CN=ms-Exch-Telephone-Assistant,${SCHEMADN} attributeID: 1.2.840.113556.1.2.79 attributeSyntax: 2.5.5.12 isSingleValued: TRUE rangeLower: 1 rangeUpper: 64 mAPIID: 14894 showInAdvancedViewOnly: TRUE adminDisplayName: ms-Exch-Telephone-Assistant adminDescription: ms-Exch-Telephone-Assistant oMSyntax: 64 searchFlags: 0 lDAPDisplayName: telephoneAssistant name: ms-Exch-Telephone-Assistant schemaIDGUID: a8df7484-c5ea-11d1-bbcb-0080c76670c0 attributeSecurityGUID: e48d0154-bcf8-11d1-8702-00c04fb96050 isMemberOfPartialAttributeSet: FALSE objectCategory: CN=Attribute-Schema,${SCHEMADN} # # ms-Exch-Telephone-Personal-Pager # dn: CN=ms-Exch-Telephone-Personal-Pager,${SCHEMADN} objectClass: top objectClass: attributeSchema cn: ms-Exch-Telephone-Personal-Pager distinguishedName: CN=ms-Exch-Telephone-Personal-Pager,${SCHEMADN} attributeID: 1.2.840.113556.1.2.612 attributeSyntax: 2.5.5.12 isSingleValued: TRUE rangeLower: 1 rangeUpper: 128 mAPIID: 35944 showInAdvancedViewOnly: TRUE adminDisplayName: ms-Exch-Telephone-Personal-Pager adminDescription: ms-Exch-Telephone-Personal-Pager oMSyntax: 64 searchFlags: 0 lDAPDisplayName: personalPager name: ms-Exch-Telephone-Personal-Pager schemaIDGUID: a8df7487-c5ea-11d1-bbcb-0080c76670c0 isMemberOfPartialAttributeSet: FALSE objectCategory: CN=Attribute-Schema,${SCHEMADN} # # ms-Exch-Template-RDNs # The Relative Distinguished Names (RDNs) to the child template # objects. # dn: CN=ms-Exch-Template-RDNs,${SCHEMADN} objectClass: top objectClass: attributeSchema cn: ms-Exch-Template-RDNs distinguishedName: CN=ms-Exch-Template-RDNs,${SCHEMADN} attributeID: 1.2.840.113556.1.4.7000.102.65 attributeSyntax: 2.5.5.4 isSingleValued: FALSE mAPIID: 65528 showInAdvancedViewOnly: TRUE adminDisplayName: ms-Exch-Template-RDNs adminDescription: ms-Exch-Template-RDNs oMSyntax: 20 searchFlags: 0 lDAPDisplayName: msExchTemplateRDNs name: ms-Exch-Template-RDNs schemaIDGUID: 211fae98-b099-11d2-aa06-00c04f8eedd8 isMemberOfPartialAttributeSet: FALSE objectCategory: CN=Attribute-Schema,${SCHEMADN} # # ms-Exch-Temp-Assoc-Threshold # dn: CN=ms-Exch-Temp-Assoc-Threshold,${SCHEMADN} objectClass: top objectClass: attributeSchema cn: ms-Exch-Temp-Assoc-Threshold distinguishedName: CN=ms-Exch-Temp-Assoc-Threshold,${SCHEMADN} attributeID: 1.2.840.113556.1.2.329 attributeSyntax: 2.5.5.9 isSingleValued: TRUE rangeLower: 1 rangeUpper: 32767 mAPIID: 33092 showInAdvancedViewOnly: TRUE adminDisplayName: ms-Exch-Temp-Assoc-Threshold adminDescription: ms-Exch-Temp-Assoc-Threshold oMSyntax: 2 searchFlags: 0 lDAPDisplayName: tempAssocThreshold name: ms-Exch-Temp-Assoc-Threshold schemaIDGUID: a8df7488-c5ea-11d1-bbcb-0080c76670c0 isMemberOfPartialAttributeSet: FALSE objectCategory: CN=Attribute-Schema,${SCHEMADN} # # ms-Exch-Tracking-Log-Path-Name # dn: CN=ms-Exch-Tracking-Log-Path-Name,${SCHEMADN} objectClass: top objectClass: attributeSchema cn: ms-Exch-Tracking-Log-Path-Name distinguishedName: CN=ms-Exch-Tracking-Log-Path-Name,${SCHEMADN} attributeID: 1.2.840.113556.1.2.347 attributeSyntax: 2.5.5.12 isSingleValued: TRUE rangeLower: 0 rangeUpper: 256 mAPIID: 33094 showInAdvancedViewOnly: TRUE adminDisplayName: ms-Exch-Tracking-Log-Path-Name adminDescription: ms-Exch-Tracking-Log-Path-Name oMSyntax: 64 searchFlags: 0 lDAPDisplayName: trackingLogPathName name: ms-Exch-Tracking-Log-Path-Name schemaIDGUID: bf967a57-0de6-11d0-a285-00aa003049e2 isMemberOfPartialAttributeSet: FALSE objectCategory: CN=Attribute-Schema,${SCHEMADN} # # ms-Exch-Track-Duplicates # The number of hours for which information about received messages # will be kept and duplicates will be eliminated. # dn: CN=ms-Exch-Track-Duplicates,${SCHEMADN} objectClass: top objectClass: attributeSchema cn: ms-Exch-Track-Duplicates distinguishedName: CN=ms-Exch-Track-Duplicates,${SCHEMADN} attributeID: 1.2.840.113556.1.4.7000.102.11006 attributeSyntax: 2.5.5.9 isSingleValued: TRUE showInAdvancedViewOnly: TRUE adminDisplayName: ms-Exch-Track-Duplicates adminDescription: ms-Exch-Track-Duplicates oMSyntax: 2 searchFlags: 0 lDAPDisplayName: msExchTrackDuplicates name: ms-Exch-Track-Duplicates schemaIDGUID: 2196e42c-b099-11d2-aa06-00c04f8eedd8 isMemberOfPartialAttributeSet: FALSE objectCategory: CN=Attribute-Schema,${SCHEMADN} # # ms-Exch-Transfer-Retry-Interval # dn: CN=ms-Exch-Transfer-Retry-Interval,${SCHEMADN} objectClass: top objectClass: attributeSchema cn: ms-Exch-Transfer-Retry-Interval distinguishedName: CN=ms-Exch-Transfer-Retry-Interval,${SCHEMADN} attributeID: 1.2.840.113556.1.2.133 attributeSyntax: 2.5.5.9 isSingleValued: TRUE rangeLower: 0 rangeUpper: 32767 mAPIID: 33097 showInAdvancedViewOnly: TRUE adminDisplayName: ms-Exch-Transfer-Retry-Interval adminDescription: ms-Exch-Transfer-Retry-Interval oMSyntax: 2 searchFlags: 0 lDAPDisplayName: transferRetryInterval name: ms-Exch-Transfer-Retry-Interval schemaIDGUID: a8df748c-c5ea-11d1-bbcb-0080c76670c0 isMemberOfPartialAttributeSet: FALSE objectCategory: CN=Attribute-Schema,${SCHEMADN} # # ms-Exch-Transfer-Timeout-Non-Urgent # dn: CN=ms-Exch-Transfer-Timeout-Non-Urgent,${SCHEMADN} objectClass: top objectClass: attributeSchema cn: ms-Exch-Transfer-Timeout-Non-Urgent distinguishedName: CN=ms-Exch-Transfer-Timeout-Non-Urgent,${SCHEMADN} attributeID: 1.2.840.113556.1.2.136 attributeSyntax: 2.5.5.9 isSingleValued: TRUE rangeLower: 0 rangeUpper: 32767 mAPIID: 33098 showInAdvancedViewOnly: TRUE adminDisplayName: ms-Exch-Transfer-Timeout-Non-Urgent adminDescription: ms-Exch-Transfer-Timeout-Non-Urgent oMSyntax: 2 searchFlags: 0 lDAPDisplayName: transferTimeoutNonUrgent name: ms-Exch-Transfer-Timeout-Non-Urgent schemaIDGUID: a8df748d-c5ea-11d1-bbcb-0080c76670c0 isMemberOfPartialAttributeSet: FALSE objectCategory: CN=Attribute-Schema,${SCHEMADN} # # ms-Exch-Transfer-Timeout-Normal # dn: CN=ms-Exch-Transfer-Timeout-Normal,${SCHEMADN} objectClass: top objectClass: attributeSchema cn: ms-Exch-Transfer-Timeout-Normal distinguishedName: CN=ms-Exch-Transfer-Timeout-Normal,${SCHEMADN} attributeID: 1.2.840.113556.1.2.137 attributeSyntax: 2.5.5.9 isSingleValued: TRUE rangeLower: 0 rangeUpper: 32767 mAPIID: 33099 showInAdvancedViewOnly: TRUE adminDisplayName: ms-Exch-Transfer-Timeout-Normal adminDescription: ms-Exch-Transfer-Timeout-Normal oMSyntax: 2 searchFlags: 0 lDAPDisplayName: transferTimeoutNormal name: ms-Exch-Transfer-Timeout-Normal schemaIDGUID: a8df748e-c5ea-11d1-bbcb-0080c76670c0 isMemberOfPartialAttributeSet: FALSE objectCategory: CN=Attribute-Schema,${SCHEMADN} # # ms-Exch-Transfer-Timeout-Urgent # dn: CN=ms-Exch-Transfer-Timeout-Urgent,${SCHEMADN} objectClass: top objectClass: attributeSchema cn: ms-Exch-Transfer-Timeout-Urgent distinguishedName: CN=ms-Exch-Transfer-Timeout-Urgent,${SCHEMADN} attributeID: 1.2.840.113556.1.2.142 attributeSyntax: 2.5.5.9 isSingleValued: TRUE rangeLower: 0 rangeUpper: 32767 mAPIID: 33100 showInAdvancedViewOnly: TRUE adminDisplayName: ms-Exch-Transfer-Timeout-Urgent adminDescription: ms-Exch-Transfer-Timeout-Urgent oMSyntax: 2 searchFlags: 0 lDAPDisplayName: transferTimeoutUrgent name: ms-Exch-Transfer-Timeout-Urgent schemaIDGUID: a8df748f-c5ea-11d1-bbcb-0080c76670c0 isMemberOfPartialAttributeSet: FALSE objectCategory: CN=Attribute-Schema,${SCHEMADN} # # ms-Exch-Translation-Table-Used # dn: CN=ms-Exch-Translation-Table-Used,${SCHEMADN} objectClass: top objectClass: attributeSchema cn: ms-Exch-Translation-Table-Used distinguishedName: CN=ms-Exch-Translation-Table-Used,${SCHEMADN} attributeID: 1.2.840.113556.1.2.396 attributeSyntax: 2.5.5.9 isSingleValued: TRUE rangeLower: 0 rangeUpper: 32767 mAPIID: 33101 showInAdvancedViewOnly: TRUE adminDisplayName: ms-Exch-Translation-Table-Used adminDescription: ms-Exch-Translation-Table-Used oMSyntax: 10 searchFlags: 0 lDAPDisplayName: translationTableUsed name: ms-Exch-Translation-Table-Used schemaIDGUID: a8df7490-c5ea-11d1-bbcb-0080c76670c0 isMemberOfPartialAttributeSet: FALSE objectCategory: CN=Attribute-Schema,${SCHEMADN} # # ms-Exch-Transport-Expedited-Data # dn: CN=ms-Exch-Transport-Expedited-Data,${SCHEMADN} objectClass: top objectClass: attributeSchema cn: ms-Exch-Transport-Expedited-Data distinguishedName: CN=ms-Exch-Transport-Expedited-Data,${SCHEMADN} attributeID: 1.2.840.113556.1.2.150 attributeSyntax: 2.5.5.8 isSingleValued: TRUE mAPIID: 33102 showInAdvancedViewOnly: TRUE adminDisplayName: ms-Exch-Transport-Expedited-Data adminDescription: ms-Exch-Transport-Expedited-Data oMSyntax: 1 searchFlags: 0 lDAPDisplayName: transportExpeditedData name: ms-Exch-Transport-Expedited-Data schemaIDGUID: a8df7491-c5ea-11d1-bbcb-0080c76670c0 isMemberOfPartialAttributeSet: FALSE objectCategory: CN=Attribute-Schema,${SCHEMADN} # # ms-Exch-Trans-Retry-Mins # dn: CN=ms-Exch-Trans-Retry-Mins,${SCHEMADN} objectClass: top objectClass: attributeSchema cn: ms-Exch-Trans-Retry-Mins distinguishedName: CN=ms-Exch-Trans-Retry-Mins,${SCHEMADN} attributeID: 1.2.840.113556.1.2.219 attributeSyntax: 2.5.5.9 isSingleValued: TRUE mAPIID: 33095 showInAdvancedViewOnly: TRUE adminDisplayName: ms-Exch-Trans-Retry-Mins adminDescription: ms-Exch-Trans-Retry-Mins oMSyntax: 2 searchFlags: 0 lDAPDisplayName: transRetryMins name: ms-Exch-Trans-Retry-Mins schemaIDGUID: a8df748a-c5ea-11d1-bbcb-0080c76670c0 isMemberOfPartialAttributeSet: FALSE objectCategory: CN=Attribute-Schema,${SCHEMADN} # # ms-Exch-Trans-Timeout-Mins # dn: CN=ms-Exch-Trans-Timeout-Mins,${SCHEMADN} objectClass: top objectClass: attributeSchema cn: ms-Exch-Trans-Timeout-Mins distinguishedName: CN=ms-Exch-Trans-Timeout-Mins,${SCHEMADN} attributeID: 1.2.840.113556.1.2.220 attributeSyntax: 2.5.5.9 isSingleValued: TRUE mAPIID: 33096 showInAdvancedViewOnly: TRUE adminDisplayName: ms-Exch-Trans-Timeout-Mins adminDescription: ms-Exch-Trans-Timeout-Mins oMSyntax: 2 searchFlags: 0 lDAPDisplayName: transTimeoutMins name: ms-Exch-Trans-Timeout-Mins schemaIDGUID: a8df748b-c5ea-11d1-bbcb-0080c76670c0 isMemberOfPartialAttributeSet: FALSE objectCategory: CN=Attribute-Schema,${SCHEMADN} # # ms-Exch-Trk-Log-Cleaning-Interval # The number of days after which to remove a tracking log file. # dn: CN=ms-Exch-Trk-Log-Cleaning-Interval,${SCHEMADN} objectClass: top objectClass: attributeSchema cn: ms-Exch-Trk-Log-Cleaning-Interval distinguishedName: CN=ms-Exch-Trk-Log-Cleaning-Interval,${SCHEMADN} attributeID: 1.2.840.113556.1.4.7000.102.50016 attributeSyntax: 2.5.5.9 isSingleValued: TRUE showInAdvancedViewOnly: TRUE adminDisplayName: ms-Exch-Trk-Log-Cleaning-Interval adminDescription: ms-Exch-Trk-Log-Cleaning-Interval oMSyntax: 2 searchFlags: 0 lDAPDisplayName: msExchTrkLogCleaningInterval name: ms-Exch-Trk-Log-Cleaning-Interval schemaIDGUID: 21d27ef6-b099-11d2-aa06-00c04f8eedd8 isMemberOfPartialAttributeSet: FALSE objectCategory: CN=Attribute-Schema,${SCHEMADN} # # ms-Exch-Trust-Level # dn: CN=ms-Exch-Trust-Level,${SCHEMADN} objectClass: top objectClass: attributeSchema cn: ms-Exch-Trust-Level distinguishedName: CN=ms-Exch-Trust-Level,${SCHEMADN} attributeID: 1.2.840.113556.1.2.70 attributeSyntax: 2.5.5.9 isSingleValued: TRUE rangeLower: 0 rangeUpper: 100 mAPIID: 33103 showInAdvancedViewOnly: TRUE adminDisplayName: ms-Exch-Trust-Level adminDescription: ms-Exch-Trust-Level oMSyntax: 2 searchFlags: 0 lDAPDisplayName: trustLevel name: ms-Exch-Trust-Level schemaIDGUID: a8df7492-c5ea-11d1-bbcb-0080c76670c0 isMemberOfPartialAttributeSet: FALSE objectCategory: CN=Attribute-Schema,${SCHEMADN} # # ms-Exch-TUI-Password # The user logon authentication password when accessed by phone. # dn: CN=ms-Exch-TUI-Password,${SCHEMADN} objectClass: top objectClass: attributeSchema cn: ms-Exch-TUI-Password distinguishedName: CN=ms-Exch-TUI-Password,${SCHEMADN} attributeID: 1.2.840.113556.1.4.7000.102.17025 attributeSyntax: 2.5.5.10 isSingleValued: TRUE showInAdvancedViewOnly: TRUE adminDisplayName: ms-Exch-TUI-Password adminDescription: ms-Exch-TUI-Password oMSyntax: 4 searchFlags: 0 lDAPDisplayName: msExchTUIPassword name: ms-Exch-TUI-Password schemaIDGUID: 567d521f-2f6a-11d3-aa6c-00c04f8eedd8 attributeSecurityGUID: e48d0154-bcf8-11d1-8702-00c04fb96050 isMemberOfPartialAttributeSet: TRUE objectCategory: CN=Attribute-Schema,${SCHEMADN} # # ms-Exch-TUI-Speed # The speed at which to play text to speech. # dn: CN=ms-Exch-TUI-Speed,${SCHEMADN} objectClass: top objectClass: attributeSchema cn: ms-Exch-TUI-Speed distinguishedName: CN=ms-Exch-TUI-Speed,${SCHEMADN} attributeID: 1.2.840.113556.1.4.7000.102.17027 attributeSyntax: 2.5.5.9 isSingleValued: TRUE showInAdvancedViewOnly: TRUE adminDisplayName: ms-Exch-TUI-Speed adminDescription: ms-Exch-TUI-Speed oMSyntax: 2 searchFlags: 0 lDAPDisplayName: msExchTUISpeed name: ms-Exch-TUI-Speed schemaIDGUID: 567d522a-2f6a-11d3-aa6c-00c04f8eedd8 attributeSecurityGUID: e48d0154-bcf8-11d1-8702-00c04fb96050 isMemberOfPartialAttributeSet: TRUE objectCategory: CN=Attribute-Schema,${SCHEMADN} # # ms-Exch-TUI-Volume # The volume at which to play voice mail and text-to-speech mail via # Telephone User Interface (TUI). # dn: CN=ms-Exch-TUI-Volume,${SCHEMADN} objectClass: top objectClass: attributeSchema cn: ms-Exch-TUI-Volume distinguishedName: CN=ms-Exch-TUI-Volume,${SCHEMADN} attributeID: 1.2.840.113556.1.4.7000.102.17026 attributeSyntax: 2.5.5.9 isSingleValued: TRUE showInAdvancedViewOnly: TRUE adminDisplayName: ms-Exch-TUI-Volume adminDescription: ms-Exch-TUI-Volume oMSyntax: 2 searchFlags: 0 lDAPDisplayName: msExchTUIVolume name: ms-Exch-TUI-Volume schemaIDGUID: 567d5225-2f6a-11d3-aa6c-00c04f8eedd8 attributeSecurityGUID: e48d0154-bcf8-11d1-8702-00c04fb96050 isMemberOfPartialAttributeSet: TRUE objectCategory: CN=Attribute-Schema,${SCHEMADN} # # ms-Exch-Turf-List # dn: CN=ms-Exch-Turf-List,${SCHEMADN} objectClass: top objectClass: attributeSchema cn: ms-Exch-Turf-List distinguishedName: CN=ms-Exch-Turf-List,${SCHEMADN} attributeID: 1.2.840.113556.1.4.7000.102.5051 attributeSyntax: 2.5.5.5 isSingleValued: FALSE showInAdvancedViewOnly: TRUE adminDisplayName: ms-Exch-Turf-List adminDescription: ms-Exch-Turf-List oMSyntax: 19 searchFlags: 0 lDAPDisplayName: msExchTurfList name: ms-Exch-Turf-List schemaIDGUID: 8b60f7f8-b09e-11d2-aa06-00c04f8eedd8 isMemberOfPartialAttributeSet: FALSE objectCategory: CN=Attribute-Schema,${SCHEMADN} # # ms-Exch-Turf-List-Action # dn: CN=ms-Exch-Turf-List-Action,${SCHEMADN} objectClass: top objectClass: attributeSchema cn: ms-Exch-Turf-List-Action distinguishedName: CN=ms-Exch-Turf-List-Action,${SCHEMADN} attributeID: 1.2.840.113556.1.4.7000.102.12535 attributeSyntax: 2.5.5.12 isSingleValued: TRUE showInAdvancedViewOnly: TRUE adminDisplayName: ms-Exch-Turf-List-Action adminDescription: ms-Exch-Turf-List-Action oMSyntax: 64 searchFlags: 0 lDAPDisplayName: msExchTurfListAction name: ms-Exch-Turf-List-Action schemaIDGUID: 0b836daa-3b20-11d3-aa6f-00c04f8eedd8 isMemberOfPartialAttributeSet: FALSE objectCategory: CN=Attribute-Schema,${SCHEMADN} # # ms-Exch-Turf-List-Names # dn: CN=ms-Exch-Turf-List-Names,${SCHEMADN} objectClass: top objectClass: attributeSchema cn: ms-Exch-Turf-List-Names distinguishedName: CN=ms-Exch-Turf-List-Names,${SCHEMADN} attributeID: 1.2.840.113556.1.4.7000.102.12534 attributeSyntax: 2.5.5.12 isSingleValued: FALSE showInAdvancedViewOnly: TRUE adminDisplayName: ms-Exch-Turf-List-Names adminDescription: ms-Exch-Turf-List-Names oMSyntax: 64 searchFlags: 0 lDAPDisplayName: msExchTurfListNames name: ms-Exch-Turf-List-Names schemaIDGUID: 0b836da0-3b20-11d3-aa6f-00c04f8eedd8 isMemberOfPartialAttributeSet: FALSE objectCategory: CN=Attribute-Schema,${SCHEMADN} # # ms-Exch-Turf-List-Options # dn: CN=ms-Exch-Turf-List-Options,${SCHEMADN} objectClass: top objectClass: attributeSchema cn: ms-Exch-Turf-List-Options distinguishedName: CN=ms-Exch-Turf-List-Options,${SCHEMADN} attributeID: 1.2.840.113556.1.4.7000.102.5054 attributeSyntax: 2.5.5.9 isSingleValued: TRUE showInAdvancedViewOnly: TRUE adminDisplayName: ms-Exch-Turf-List-Options adminDescription: ms-Exch-Turf-List-Options oMSyntax: 2 searchFlags: 0 lDAPDisplayName: msExchTurfListOptions name: ms-Exch-Turf-List-Options schemaIDGUID: 01dbe64c-bfeb-47cd-9939-8911946bdd6d isMemberOfPartialAttributeSet: FALSE objectCategory: CN=Attribute-Schema,${SCHEMADN} # # ms-Exch-Turn-Request-Threshold # dn: CN=ms-Exch-Turn-Request-Threshold,${SCHEMADN} objectClass: top objectClass: attributeSchema cn: ms-Exch-Turn-Request-Threshold distinguishedName: CN=ms-Exch-Turn-Request-Threshold,${SCHEMADN} attributeID: 1.2.840.113556.1.2.38 attributeSyntax: 2.5.5.9 isSingleValued: TRUE rangeLower: 0 rangeUpper: 32767 mAPIID: 33104 showInAdvancedViewOnly: TRUE adminDisplayName: ms-Exch-Turn-Request-Threshold adminDescription: ms-Exch-Turn-Request-Threshold oMSyntax: 2 searchFlags: 0 lDAPDisplayName: turnRequestThreshold name: ms-Exch-Turn-Request-Threshold schemaIDGUID: a8df7493-c5ea-11d1-bbcb-0080c76670c0 isMemberOfPartialAttributeSet: FALSE objectCategory: CN=Attribute-Schema,${SCHEMADN} # # ms-Exch-Two-Way-Alternate-Facility # dn: CN=ms-Exch-Two-Way-Alternate-Facility,${SCHEMADN} objectClass: top objectClass: attributeSchema cn: ms-Exch-Two-Way-Alternate-Facility distinguishedName: CN=ms-Exch-Two-Way-Alternate-Facility,${SCHEMADN} attributeID: 1.2.840.113556.1.2.40 attributeSyntax: 2.5.5.8 isSingleValued: TRUE mAPIID: 33105 showInAdvancedViewOnly: TRUE adminDisplayName: ms-Exch-Two-Way-Alternate-Facility adminDescription: ms-Exch-Two-Way-Alternate-Facility oMSyntax: 1 searchFlags: 0 lDAPDisplayName: twoWayAlternateFacility name: ms-Exch-Two-Way-Alternate-Facility schemaIDGUID: a8df7494-c5ea-11d1-bbcb-0080c76670c0 isMemberOfPartialAttributeSet: FALSE objectCategory: CN=Attribute-Schema,${SCHEMADN} # # ms-Exch-Type # dn: CN=ms-Exch-Type,${SCHEMADN} objectClass: top objectClass: attributeSchema cn: ms-Exch-Type distinguishedName: CN=ms-Exch-Type,${SCHEMADN} attributeID: 1.2.840.113556.1.2.573 attributeSyntax: 2.5.5.12 isSingleValued: TRUE rangeLower: 1 rangeUpper: 1024 mAPIID: 35896 showInAdvancedViewOnly: TRUE adminDisplayName: ms-Exch-Type adminDescription: ms-Exch-Type oMSyntax: 64 searchFlags: 0 lDAPDisplayName: type name: ms-Exch-Type schemaIDGUID: 167758aa-47f3-11d1-a9c3-0000f80367c1 isMemberOfPartialAttributeSet: TRUE objectCategory: CN=Attribute-Schema,${SCHEMADN} # # ms-Exch-T-Selector # dn: CN=ms-Exch-T-Selector,${SCHEMADN} objectClass: top objectClass: attributeSchema cn: ms-Exch-T-Selector distinguishedName: CN=ms-Exch-T-Selector,${SCHEMADN} attributeID: 1.2.840.113556.1.2.283 attributeSyntax: 2.5.5.10 isSingleValued: TRUE rangeLower: 1 rangeUpper: 32 mAPIID: 33088 showInAdvancedViewOnly: TRUE adminDisplayName: ms-Exch-T-Selector adminDescription: ms-Exch-T-Selector oMSyntax: 4 searchFlags: 0 lDAPDisplayName: tSelector name: ms-Exch-T-Selector schemaIDGUID: a8df7481-c5ea-11d1-bbcb-0080c76670c0 isMemberOfPartialAttributeSet: FALSE objectCategory: CN=Attribute-Schema,${SCHEMADN} # # ms-Exch-Uce-Block-Threshold # dn: CN=ms-Exch-Uce-Block-Threshold,${SCHEMADN} objectClass: top objectClass: attributeSchema cn: ms-Exch-Uce-Block-Threshold distinguishedName: CN=ms-Exch-Uce-Block-Threshold,${SCHEMADN} attributeID: 1.2.840.113556.1.4.7000.102.12601 attributeSyntax: 2.5.5.12 isSingleValued: TRUE showInAdvancedViewOnly: TRUE adminDisplayName: ms-Exch-Uce-Block-Threshold adminDescription: ms-Exch-Uce-Block-Threshold oMSyntax: 64 searchFlags: 0 lDAPDisplayName: msExchUceBlockThreshold name: ms-Exch-Uce-Block-Threshold schemaIDGUID: 9f297c14-d715-4631-a259-bf51dc52eac1 isMemberOfPartialAttributeSet: FALSE objectCategory: CN=Attribute-Schema,${SCHEMADN} # # ms-Exch-Uce-Enabled # dn: CN=ms-Exch-Uce-Enabled,${SCHEMADN} objectClass: top objectClass: attributeSchema cn: ms-Exch-Uce-Enabled distinguishedName: CN=ms-Exch-Uce-Enabled,${SCHEMADN} attributeID: 1.2.840.113556.1.4.7000.102.12600 attributeSyntax: 2.5.5.9 isSingleValued: TRUE showInAdvancedViewOnly: TRUE adminDisplayName: ms-Exch-Uce-Enabled adminDescription: ms-Exch-Uce-Enabled oMSyntax: 2 searchFlags: 0 lDAPDisplayName: msExchUceEnabled name: ms-Exch-Uce-Enabled schemaIDGUID: 15e2db2e-7206-4109-9b94-830f4def1b05 isMemberOfPartialAttributeSet: FALSE objectCategory: CN=Attribute-Schema,${SCHEMADN} # # ms-Exch-Uce-Store-Action-Threshold # dn: CN=ms-Exch-Uce-Store-Action-Threshold,${SCHEMADN} objectClass: top objectClass: attributeSchema cn: ms-Exch-Uce-Store-Action-Threshold distinguishedName: CN=ms-Exch-Uce-Store-Action-Threshold,${SCHEMADN} attributeID: 1.2.840.113556.1.4.7000.102.12602 attributeSyntax: 2.5.5.9 isSingleValued: TRUE showInAdvancedViewOnly: TRUE adminDisplayName: ms-Exch-Uce-Store-Action-Threshold adminDescription: ms-Exch-Uce-Store-Action-Threshold oMSyntax: 2 searchFlags: 0 lDAPDisplayName: msExchUceStoreActionThreshold name: ms-Exch-Uce-Store-Action-Threshold schemaIDGUID: 44ccbd60-6ede-46f0-8f13-931a9bb5b8e8 isMemberOfPartialAttributeSet: FALSE objectCategory: CN=Attribute-Schema,${SCHEMADN} # # ms-Exch-Unauth-Orig # Contains objects that may not send to this recipient. # dn: CN=ms-Exch-Unauth-Orig,${SCHEMADN} objectClass: top objectClass: attributeSchema cn: ms-Exch-Unauth-Orig distinguishedName: CN=ms-Exch-Unauth-Orig,${SCHEMADN} attributeID: 1.2.840.113556.1.2.221 attributeSyntax: 2.5.5.7 isSingleValued: FALSE linkID: 114 showInAdvancedViewOnly: TRUE adminDisplayName: ms-Exch-Unauth-Orig oMObjectClass:: VgYBAgULHQ== adminDescription: ms-Exch-Unauth-Orig oMSyntax: 127 searchFlags: 16 lDAPDisplayName: unauthOrig name: ms-Exch-Unauth-Orig schemaIDGUID: a8df7495-c5ea-11d1-bbcb-0080c76670c0 attributeSecurityGUID: e48d0154-bcf8-11d1-8702-00c04fb96050 isMemberOfPartialAttributeSet: TRUE objectCategory: CN=Attribute-Schema,${SCHEMADN} # # ms-Exch-Unauth-Orig-BL # A backlink to ms-Exch-Unauth-Orig. # dn: CN=ms-Exch-Unauth-Orig-BL,${SCHEMADN} objectClass: top objectClass: attributeSchema cn: ms-Exch-Unauth-Orig-BL distinguishedName: CN=ms-Exch-Unauth-Orig-BL,${SCHEMADN} attributeID: 1.2.840.113556.1.2.292 attributeSyntax: 2.5.5.1 isSingleValued: FALSE mAPIID: 33106 linkID: 115 showInAdvancedViewOnly: TRUE adminDisplayName: ms-Exch-Unauth-Orig-BL oMObjectClass:: KwwCh3McAIVK adminDescription: ms-Exch-Unauth-Orig-BL oMSyntax: 127 searchFlags: 0 lDAPDisplayName: unauthOrigBL name: ms-Exch-Unauth-Orig-BL schemaIDGUID: a8df7496-c5ea-11d1-bbcb-0080c76670c0 attributeSecurityGUID: e48d0154-bcf8-11d1-8702-00c04fb96050 systemFlags: 1 isMemberOfPartialAttributeSet: TRUE objectCategory: CN=Attribute-Schema,${SCHEMADN} # # ms-Exch-UNC-Password # Specifies the encrypted password used to gain access to Universal # Naming Convention (UNC) virtual roots. # dn: CN=ms-Exch-UNC-Password,${SCHEMADN} objectClass: top objectClass: attributeSchema cn: ms-Exch-UNC-Password distinguishedName: CN=ms-Exch-UNC-Password,${SCHEMADN} attributeID: 1.2.840.113556.1.4.7000.102.15004 attributeSyntax: 2.5.5.12 isSingleValued: TRUE showInAdvancedViewOnly: TRUE adminDisplayName: ms-Exch-UNC-Password adminDescription: ms-Exch-UNC-Password oMSyntax: 64 searchFlags: 0 lDAPDisplayName: msExchUNCPassword name: ms-Exch-UNC-Password schemaIDGUID: 8c07dc94-b09e-11d2-aa06-00c04f8eedd8 isMemberOfPartialAttributeSet: FALSE objectCategory: CN=Attribute-Schema,${SCHEMADN} # # ms-Exch-UNC-Username # Specifies the user name for UNC virtual roots. # dn: CN=ms-Exch-UNC-Username,${SCHEMADN} objectClass: top objectClass: attributeSchema cn: ms-Exch-UNC-Username distinguishedName: CN=ms-Exch-UNC-Username,${SCHEMADN} attributeID: 1.2.840.113556.1.4.7000.102.15003 attributeSyntax: 2.5.5.12 isSingleValued: TRUE showInAdvancedViewOnly: TRUE adminDisplayName: ms-Exch-UNC-Username adminDescription: ms-Exch-UNC-Username oMSyntax: 64 searchFlags: 0 lDAPDisplayName: msExchUNCUsername name: ms-Exch-UNC-Username schemaIDGUID: 8be8de02-b09e-11d2-aa06-00c04f8eedd8 isMemberOfPartialAttributeSet: FALSE objectCategory: CN=Attribute-Schema,${SCHEMADN} # # ms-Exch-Unmerged-Atts # A set of DN syntax attribute values that were not set on the target # object because the object they pointed to was not found in the # target directory. # dn: CN=ms-Exch-Unmerged-Atts,${SCHEMADN} objectClass: top objectClass: attributeSchema cn: ms-Exch-Unmerged-Atts distinguishedName: CN=ms-Exch-Unmerged-Atts,${SCHEMADN} attributeID: 1.2.840.113556.1.4.7000.102.48 attributeSyntax: 2.5.5.10 isSingleValued: TRUE showInAdvancedViewOnly: TRUE adminDisplayName: ms-Exch-Unmerged-Atts adminDescription: ms-Exch-Unmerged-Atts oMSyntax: 4 searchFlags: 1 lDAPDisplayName: unmergedAtts name: ms-Exch-Unmerged-Atts schemaIDGUID: 9947d64e-b093-11d2-aa06-00c04f8eedd8 attributeSecurityGUID: e48d0154-bcf8-11d1-8702-00c04fb96050 isMemberOfPartialAttributeSet: FALSE objectCategory: CN=Attribute-Schema,${SCHEMADN} # # ms-Exch-Unmerged-Atts-Pt # Exchange-specific unmerged attributes. # dn: CN=ms-Exch-Unmerged-Atts-Pt,${SCHEMADN} objectClass: top objectClass: attributeSchema cn: ms-Exch-Unmerged-Atts-Pt distinguishedName: CN=ms-Exch-Unmerged-Atts-Pt,${SCHEMADN} attributeID: 1.2.840.113556.1.4.7000.102.90 attributeSyntax: 2.5.5.10 isSingleValued: TRUE showInAdvancedViewOnly: TRUE adminDisplayName: ms-Exch-Unmerged-Atts-Pt adminDescription: ms-Exch-Unmerged-Atts-Pt oMSyntax: 4 searchFlags: 1 lDAPDisplayName: msExchUnmergedAttsPt name: ms-Exch-Unmerged-Atts-Pt schemaIDGUID: a5924ad4-c597-4db1-8f9d-1799909dc166 attributeSecurityGUID: e48d0154-bcf8-11d1-8702-00c04fb96050 isMemberOfPartialAttributeSet: FALSE objectCategory: CN=Attribute-Schema,${SCHEMADN} # # ms-Exch-Usenet-Site-Name # dn: CN=ms-Exch-Usenet-Site-Name,${SCHEMADN} objectClass: top objectClass: attributeSchema cn: ms-Exch-Usenet-Site-Name distinguishedName: CN=ms-Exch-Usenet-Site-Name,${SCHEMADN} attributeID: 1.2.840.113556.1.2.484 attributeSyntax: 2.5.5.5 isSingleValued: TRUE rangeLower: 1 rangeUpper: 1024 mAPIID: 33161 showInAdvancedViewOnly: TRUE adminDisplayName: ms-Exch-Usenet-Site-Name adminDescription: ms-Exch-Usenet-Site-Name oMSyntax: 19 searchFlags: 0 lDAPDisplayName: usenetSiteName name: ms-Exch-Usenet-Site-Name schemaIDGUID: f0f8ffa8-1191-11d0-a060-00aa006c33ed isMemberOfPartialAttributeSet: FALSE objectCategory: CN=Attribute-Schema,${SCHEMADN} # # ms-Exch-User-Account-Control # dn: CN=ms-Exch-User-Account-Control,${SCHEMADN} objectClass: top objectClass: attributeSchema cn: ms-Exch-User-Account-Control distinguishedName: CN=ms-Exch-User-Account-Control,${SCHEMADN} attributeID: 1.2.840.113556.1.4.7000.102.101 attributeSyntax: 2.5.5.9 isSingleValued: TRUE showInAdvancedViewOnly: TRUE adminDisplayName: ms-Exch-User-Account-Control adminDescription: ms-Exch-User-Account-Control oMSyntax: 2 searchFlags: 25 lDAPDisplayName: msExchUserAccountControl name: ms-Exch-User-Account-Control schemaIDGUID: 07c31f12-a3e8-4fa0-af8e-4932c75b2241 attributeSecurityGUID: e48d0154-bcf8-11d1-8702-00c04fb96050 isMemberOfPartialAttributeSet: TRUE objectCategory: CN=Attribute-Schema,${SCHEMADN} # # ms-Exch-Use-OAB # The OAB that this mailbox store or this user uses. # dn: CN=ms-Exch-Use-OAB,${SCHEMADN} objectClass: top objectClass: attributeSchema cn: ms-Exch-Use-OAB distinguishedName: CN=ms-Exch-Use-OAB,${SCHEMADN} attributeID: 1.2.840.113556.1.4.7000.102.69 attributeSyntax: 2.5.5.1 isSingleValued: TRUE linkID: 1014 showInAdvancedViewOnly: TRUE adminDisplayName: ms-Exch-Use-OAB oMObjectClass:: KwwCh3McAIVK adminDescription: ms-Exch-Use-OAB oMSyntax: 127 searchFlags: 16 lDAPDisplayName: msExchUseOAB name: ms-Exch-Use-OAB schemaIDGUID: 2209550c-b099-11d2-aa06-00c04f8eedd8 attributeSecurityGUID: e48d0154-bcf8-11d1-8702-00c04fb96050 isMemberOfPartialAttributeSet: TRUE objectCategory: CN=Attribute-Schema,${SCHEMADN} # # ms-Exch-Use-OAB-BL # dn: CN=ms-Exch-Use-OAB-BL,${SCHEMADN} objectClass: top objectClass: attributeSchema cn: ms-Exch-Use-OAB-BL distinguishedName: CN=ms-Exch-Use-OAB-BL,${SCHEMADN} attributeID: 1.2.840.113556.1.4.7000.102.70 attributeSyntax: 2.5.5.1 isSingleValued: FALSE linkID: 1015 showInAdvancedViewOnly: TRUE adminDisplayName: ms-Exch-Use-OAB-BL oMObjectClass:: KwwCh3McAIVK adminDescription: ms-Exch-Use-OAB-BL oMSyntax: 127 searchFlags: 0 lDAPDisplayName: msExchUseOABBL name: ms-Exch-Use-OAB-BL schemaIDGUID: 22428d7c-b099-11d2-aa06-00c04f8eedd8 systemFlags: 1 isMemberOfPartialAttributeSet: FALSE objectCategory: CN=Attribute-Schema,${SCHEMADN} # # ms-Exch-Use-Site-Values # dn: CN=ms-Exch-Use-Site-Values,${SCHEMADN} objectClass: top objectClass: attributeSchema cn: ms-Exch-Use-Site-Values distinguishedName: CN=ms-Exch-Use-Site-Values,${SCHEMADN} attributeID: 1.2.840.113556.1.2.478 attributeSyntax: 2.5.5.8 isSingleValued: TRUE mAPIID: 33155 showInAdvancedViewOnly: TRUE adminDisplayName: ms-Exch-Use-Site-Values adminDescription: ms-Exch-Use-Site-Values oMSyntax: 1 searchFlags: 0 lDAPDisplayName: useSiteValues name: ms-Exch-Use-Site-Values schemaIDGUID: a8df7497-c5ea-11d1-bbcb-0080c76670c0 isMemberOfPartialAttributeSet: FALSE objectCategory: CN=Attribute-Schema,${SCHEMADN} # # ms-Exch-Visibility-Mask # The data conference visibility mask. dn: CN=ms-Exch-Visibility-Mask,${SCHEMADN} objectClass: top objectClass: attributeSchema cn: ms-Exch-Visibility-Mask distinguishedName: CN=ms-Exch-Visibility-Mask,${SCHEMADN} attributeID: 1.2.840.113556.1.4.7000.102.9016 attributeSyntax: 2.5.5.9 isSingleValued: TRUE showInAdvancedViewOnly: TRUE adminDisplayName: ms-Exch-Visibility-Mask adminDescription: ms-Exch-Visibility-Mask oMSyntax: 2 searchFlags: 0 lDAPDisplayName: msExchVisibilityMask name: ms-Exch-Visibility-Mask schemaIDGUID: 22770138-b099-11d2-aa06-00c04f8eedd8 isMemberOfPartialAttributeSet: FALSE objectCategory: CN=Attribute-Schema,${SCHEMADN} # # ms-Exch-Voice-Mailbox-ID # The telephone extension of a user's mailbox ID when accessed by phone. # dn: CN=ms-Exch-Voice-Mailbox-ID,${SCHEMADN} objectClass: top objectClass: attributeSchema cn: ms-Exch-Voice-Mailbox-ID distinguishedName: CN=ms-Exch-Voice-Mailbox-ID,${SCHEMADN} attributeID: 1.2.840.113556.1.4.7000.102.17019 attributeSyntax: 2.5.5.12 isSingleValued: TRUE showInAdvancedViewOnly: TRUE adminDisplayName: ms-Exch-Voice-Mailbox-ID adminDescription: ms-Exch-Voice-Mailbox-ID oMSyntax: 64 searchFlags: 1 lDAPDisplayName: msExchVoiceMailboxID name: ms-Exch-Voice-Mailbox-ID schemaIDGUID: 567d5200-2f6a-11d3-aa6c-00c04f8eedd8 attributeSecurityGUID: e48d0154-bcf8-11d1-8702-00c04fb96050 isMemberOfPartialAttributeSet: TRUE objectCategory: CN=Attribute-Schema,${SCHEMADN} # # ms-Exch-VPIM-Convert-Inbound # Convert inbound Voice Profile for Internet Mail (VPIM) messages via # SMTP to Multimedia Message format. # dn: CN=ms-Exch-VPIM-Convert-Inbound,${SCHEMADN} objectClass: top objectClass: attributeSchema cn: ms-Exch-VPIM-Convert-Inbound distinguishedName: CN=ms-Exch-VPIM-Convert-Inbound,${SCHEMADN} attributeID: 1.2.840.113556.1.4.7000.102.17008 attributeSyntax: 2.5.5.8 isSingleValued: TRUE showInAdvancedViewOnly: TRUE adminDisplayName: ms-Exch-VPIM-Convert-Inbound adminDescription: ms-Exch-VPIM-Convert-Inbound oMSyntax: 1 searchFlags: 0 lDAPDisplayName: msExchVPIMConvertInbound name: ms-Exch-VPIM-Convert-Inbound schemaIDGUID: 2d0977eb-2b54-11d3-aa6b-00c04f8eedd8 isMemberOfPartialAttributeSet: FALSE objectCategory: CN=Attribute-Schema,${SCHEMADN} # # ms-Exch-VPIM-Convert-Outbound # Convert outbound Multimedia Message format to Voice Profile for # Internet Mail (VPIM) based on address or non-delivery report (NDR). # dn: CN=ms-Exch-VPIM-Convert-Outbound,${SCHEMADN} objectClass: top objectClass: attributeSchema cn: ms-Exch-VPIM-Convert-Outbound distinguishedName: CN=ms-Exch-VPIM-Convert-Outbound,${SCHEMADN} attributeID: 1.2.840.113556.1.4.7000.102.17009 attributeSyntax: 2.5.5.8 isSingleValued: TRUE showInAdvancedViewOnly: TRUE adminDisplayName: ms-Exch-VPIM-Convert-Outbound adminDescription: ms-Exch-VPIM-Convert-Outbound oMSyntax: 1 searchFlags: 0 lDAPDisplayName: msExchVPIMConvertOutbound name: ms-Exch-VPIM-Convert-Outbound schemaIDGUID: 2d0977f1-2b54-11d3-aa6b-00c04f8eedd8 isMemberOfPartialAttributeSet: FALSE objectCategory: CN=Attribute-Schema,${SCHEMADN} # # ms-Exch-Web-Access-Name # The name through which users will access Exchange data via HTTP. # dn: CN=ms-Exch-Web-Access-Name,${SCHEMADN} objectClass: top objectClass: attributeSchema cn: ms-Exch-Web-Access-Name distinguishedName: CN=ms-Exch-Web-Access-Name,${SCHEMADN} attributeID: 1.2.840.113556.1.4.7000.102.15007 attributeSyntax: 2.5.5.12 isSingleValued: TRUE showInAdvancedViewOnly: TRUE adminDisplayName: ms-Exch-Web-Access-Name adminDescription: ms-Exch-Web-Access-Name oMSyntax: 64 searchFlags: 0 lDAPDisplayName: msExchWebAccessName name: ms-Exch-Web-Access-Name schemaIDGUID: 8df7c5b4-b09e-11d2-aa06-00c04f8eedd8 isMemberOfPartialAttributeSet: FALSE objectCategory: CN=Attribute-Schema,${SCHEMADN} # # ms-Exch-X25-Call-User-Data-Incoming # dn: CN=ms-Exch-X25-Call-User-Data-Incoming,${SCHEMADN} objectClass: top objectClass: attributeSchema cn: ms-Exch-X25-Call-User-Data-Incoming distinguishedName: CN=ms-Exch-X25-Call-User-Data-Incoming,${SCHEMADN} attributeID: 1.2.840.113556.1.2.316 attributeSyntax: 2.5.5.10 isSingleValued: TRUE rangeLower: 1 rangeUpper: 128 mAPIID: 33113 showInAdvancedViewOnly: TRUE adminDisplayName: ms-Exch-X25-Call-User-Data-Incoming adminDescription: ms-Exch-X25-Call-User-Data-Incoming oMSyntax: 4 searchFlags: 0 lDAPDisplayName: x25CallUserDataIncoming name: ms-Exch-X25-Call-User-Data-Incoming schemaIDGUID: a8df749b-c5ea-11d1-bbcb-0080c76670c0 isMemberOfPartialAttributeSet: FALSE objectCategory: CN=Attribute-Schema,${SCHEMADN} # # ms-Exch-X25-Call-User-Data-Outgoing # dn: CN=ms-Exch-X25-Call-User-Data-Outgoing,${SCHEMADN} objectClass: top objectClass: attributeSchema cn: ms-Exch-X25-Call-User-Data-Outgoing distinguishedName: CN=ms-Exch-X25-Call-User-Data-Outgoing,${SCHEMADN} attributeID: 1.2.840.113556.1.2.317 attributeSyntax: 2.5.5.10 isSingleValued: TRUE rangeLower: 1 rangeUpper: 128 mAPIID: 33114 showInAdvancedViewOnly: TRUE adminDisplayName: ms-Exch-X25-Call-User-Data-Outgoing adminDescription: ms-Exch-X25-Call-User-Data-Outgoing oMSyntax: 4 searchFlags: 0 lDAPDisplayName: x25CallUserDataOutgoing name: ms-Exch-X25-Call-User-Data-Outgoing schemaIDGUID: a8df749c-c5ea-11d1-bbcb-0080c76670c0 isMemberOfPartialAttributeSet: FALSE objectCategory: CN=Attribute-Schema,${SCHEMADN} # # ms-Exch-X25-Facilities-Data-Incoming # dn: CN=ms-Exch-X25-Facilities-Data-Incoming,${SCHEMADN} objectClass: top objectClass: attributeSchema cn: ms-Exch-X25-Facilities-Data-Incoming distinguishedName: CN=ms-Exch-X25-Facilities-Data-Incoming,${SCHEMADN} attributeID: 1.2.840.113556.1.2.318 attributeSyntax: 2.5.5.10 isSingleValued: TRUE rangeLower: 1 rangeUpper: 109 mAPIID: 33115 showInAdvancedViewOnly: TRUE adminDisplayName: ms-Exch-X25-Facilities-Data-Incoming adminDescription: ms-Exch-X25-Facilities-Data-Incoming oMSyntax: 4 searchFlags: 0 lDAPDisplayName: x25FacilitiesDataIncoming name: ms-Exch-X25-Facilities-Data-Incoming schemaIDGUID: a8df749d-c5ea-11d1-bbcb-0080c76670c0 isMemberOfPartialAttributeSet: FALSE objectCategory: CN=Attribute-Schema,${SCHEMADN} # # ms-Exch-X25-Facilities-Data-Outgoing # dn: CN=ms-Exch-X25-Facilities-Data-Outgoing,${SCHEMADN} objectClass: top objectClass: attributeSchema cn: ms-Exch-X25-Facilities-Data-Outgoing distinguishedName: CN=ms-Exch-X25-Facilities-Data-Outgoing,${SCHEMADN} attributeID: 1.2.840.113556.1.2.319 attributeSyntax: 2.5.5.10 isSingleValued: TRUE rangeLower: 1 rangeUpper: 109 mAPIID: 33116 showInAdvancedViewOnly: TRUE adminDisplayName: ms-Exch-X25-Facilities-Data-Outgoing adminDescription: ms-Exch-X25-Facilities-Data-Outgoing oMSyntax: 4 searchFlags: 0 lDAPDisplayName: x25FacilitiesDataOutgoing name: ms-Exch-X25-Facilities-Data-Outgoing schemaIDGUID: a8df749e-c5ea-11d1-bbcb-0080c76670c0 isMemberOfPartialAttributeSet: FALSE objectCategory: CN=Attribute-Schema,${SCHEMADN} # # ms-Exch-X25-Leased-Line-Port # dn: CN=ms-Exch-X25-Leased-Line-Port,${SCHEMADN} objectClass: top objectClass: attributeSchema cn: ms-Exch-X25-Leased-Line-Port distinguishedName: CN=ms-Exch-X25-Leased-Line-Port,${SCHEMADN} attributeID: 1.2.840.113556.1.2.321 attributeSyntax: 2.5.5.10 isSingleValued: TRUE rangeLower: 1 rangeUpper: 3 mAPIID: 33117 showInAdvancedViewOnly: TRUE adminDisplayName: ms-Exch-X25-Leased-Line-Port adminDescription: ms-Exch-X25-Leased-Line-Port oMSyntax: 4 searchFlags: 0 lDAPDisplayName: x25LeasedLinePort name: ms-Exch-X25-Leased-Line-Port schemaIDGUID: a8df749f-c5ea-11d1-bbcb-0080c76670c0 isMemberOfPartialAttributeSet: FALSE objectCategory: CN=Attribute-Schema,${SCHEMADN} # # ms-Exch-X25-Leased-Or-Switched # dn: CN=ms-Exch-X25-Leased-Or-Switched,${SCHEMADN} objectClass: top objectClass: attributeSchema cn: ms-Exch-X25-Leased-Or-Switched distinguishedName: CN=ms-Exch-X25-Leased-Or-Switched,${SCHEMADN} attributeID: 1.2.840.113556.1.2.372 attributeSyntax: 2.5.5.8 isSingleValued: TRUE mAPIID: 33118 showInAdvancedViewOnly: TRUE adminDisplayName: ms-Exch-X25-Leased-Or-Switched adminDescription: ms-Exch-X25-Leased-Or-Switched oMSyntax: 1 searchFlags: 0 lDAPDisplayName: x25LeasedOrSwitched name: ms-Exch-X25-Leased-Or-Switched schemaIDGUID: a8df74a0-c5ea-11d1-bbcb-0080c76670c0 isMemberOfPartialAttributeSet: FALSE objectCategory: CN=Attribute-Schema,${SCHEMADN} # # ms-Exch-X25-Remote-MTA-Phone # dn: CN=ms-Exch-X25-Remote-MTA-Phone,${SCHEMADN} objectClass: top objectClass: attributeSchema cn: ms-Exch-X25-Remote-MTA-Phone distinguishedName: CN=ms-Exch-X25-Remote-MTA-Phone,${SCHEMADN} attributeID: 1.2.840.113556.1.2.373 attributeSyntax: 2.5.5.5 isSingleValued: TRUE rangeLower: 1 rangeUpper: 55 mAPIID: 33119 showInAdvancedViewOnly: TRUE adminDisplayName: ms-Exch-X25-Remote-MTA-Phone adminDescription: ms-Exch-X25-Remote-MTA-Phone oMSyntax: 19 searchFlags: 0 lDAPDisplayName: x25RemoteMTAPhone name: ms-Exch-X25-Remote-MTA-Phone schemaIDGUID: a8df74a1-c5ea-11d1-bbcb-0080c76670c0 isMemberOfPartialAttributeSet: FALSE objectCategory: CN=Attribute-Schema,${SCHEMADN} # # ms-Exch-X400-Attachment-Type # dn: CN=ms-Exch-X400-Attachment-Type,${SCHEMADN} objectClass: top objectClass: attributeSchema cn: ms-Exch-X400-Attachment-Type distinguishedName: CN=ms-Exch-X400-Attachment-Type,${SCHEMADN} attributeID: 1.2.840.113556.1.2.99 attributeSyntax: 2.5.5.10 isSingleValued: TRUE mAPIID: 33120 showInAdvancedViewOnly: TRUE adminDisplayName: ms-Exch-X400-Attachment-Type adminDescription: ms-Exch-X400-Attachment-Type oMSyntax: 4 searchFlags: 0 lDAPDisplayName: x400AttachmentType name: ms-Exch-X400-Attachment-Type schemaIDGUID: a8df74a2-c5ea-11d1-bbcb-0080c76670c0 isMemberOfPartialAttributeSet: FALSE objectCategory: CN=Attribute-Schema,${SCHEMADN} # # ms-Exch-X400-Selector-Syntax # dn: CN=ms-Exch-X400-Selector-Syntax,${SCHEMADN} objectClass: top objectClass: attributeSchema cn: ms-Exch-X400-Selector-Syntax distinguishedName: CN=ms-Exch-X400-Selector-Syntax,${SCHEMADN} attributeID: 1.2.840.113556.1.2.443 attributeSyntax: 2.5.5.9 isSingleValued: TRUE rangeLower: 0 rangeUpper: 1 mAPIID: 33121 showInAdvancedViewOnly: TRUE adminDisplayName: ms-Exch-X400-Selector-Syntax adminDescription: ms-Exch-X400-Selector-Syntax oMSyntax: 10 searchFlags: 0 lDAPDisplayName: x400SelectorSyntax name: ms-Exch-X400-Selector-Syntax schemaIDGUID: a8df74a3-c5ea-11d1-bbcb-0080c76670c0 isMemberOfPartialAttributeSet: FALSE objectCategory: CN=Attribute-Schema,${SCHEMADN} # # ms-Exch-X500-NC # dn: CN=ms-Exch-X500-NC,${SCHEMADN} objectClass: top objectClass: attributeSchema cn: ms-Exch-X500-NC distinguishedName: CN=ms-Exch-X500-NC,${SCHEMADN} attributeID: 1.2.840.113556.1.2.509 attributeSyntax: 2.5.5.12 isSingleValued: TRUE rangeLower: 1 rangeUpper: 1024 mAPIID: 33186 showInAdvancedViewOnly: TRUE adminDisplayName: ms-Exch-X500-NC adminDescription: ms-Exch-X500-NC oMSyntax: 64 searchFlags: 0 lDAPDisplayName: dnQualifier name: ms-Exch-X500-NC schemaIDGUID: 167758c6-47f3-11d1-a9c3-0000f80367c1 attributeSecurityGUID: e48d0154-bcf8-11d1-8702-00c04fb96050 isMemberOfPartialAttributeSet: FALSE objectCategory: CN=Attribute-Schema,${SCHEMADN} # # ms-Exch-X500-RDN # dn: CN=ms-Exch-X500-RDN,${SCHEMADN} objectClass: top objectClass: attributeSchema cn: ms-Exch-X500-RDN distinguishedName: CN=ms-Exch-X500-RDN,${SCHEMADN} attributeID: 1.2.840.113556.1.2.508 attributeSyntax: 2.5.5.12 isSingleValued: TRUE rangeLower: 1 rangeUpper: 256 mAPIID: 33185 showInAdvancedViewOnly: TRUE adminDisplayName: ms-Exch-X500-RDN adminDescription: ms-Exch-X500-RDN oMSyntax: 64 searchFlags: 0 lDAPDisplayName: x500RDN name: ms-Exch-X500-RDN schemaIDGUID: bf967a7d-0de6-11d0-a285-00aa003049e2 isMemberOfPartialAttributeSet: FALSE objectCategory: CN=Attribute-Schema,${SCHEMADN} # # ms-Exch-XMIT-Timeout-Non-Urgent # dn: CN=ms-Exch-XMIT-Timeout-Non-Urgent,${SCHEMADN} objectClass: top objectClass: attributeSchema cn: ms-Exch-XMIT-Timeout-Non-Urgent distinguishedName: CN=ms-Exch-XMIT-Timeout-Non-Urgent,${SCHEMADN} attributeID: 1.2.840.113556.1.2.84 attributeSyntax: 2.5.5.9 isSingleValued: TRUE rangeLower: 0 rangeUpper: 32767 mAPIID: 33123 showInAdvancedViewOnly: TRUE adminDisplayName: ms-Exch-XMIT-Timeout-Non-Urgent adminDescription: ms-Exch-XMIT-Timeout-Non-Urgent oMSyntax: 2 searchFlags: 0 lDAPDisplayName: xMITTimeoutNonUrgent name: ms-Exch-XMIT-Timeout-Non-Urgent schemaIDGUID: a8df74a4-c5ea-11d1-bbcb-0080c76670c0 isMemberOfPartialAttributeSet: FALSE objectCategory: CN=Attribute-Schema,${SCHEMADN} # # ms-Exch-XMIT-Timeout-Normal # dn: CN=ms-Exch-XMIT-Timeout-Normal,${SCHEMADN} objectClass: top objectClass: attributeSchema cn: ms-Exch-XMIT-Timeout-Normal distinguishedName: CN=ms-Exch-XMIT-Timeout-Normal,${SCHEMADN} attributeID: 1.2.840.113556.1.2.67 attributeSyntax: 2.5.5.9 isSingleValued: TRUE rangeLower: 0 rangeUpper: 32767 mAPIID: 33124 showInAdvancedViewOnly: TRUE adminDisplayName: ms-Exch-XMIT-Timeout-Normal adminDescription: ms-Exch-XMIT-Timeout-Normal oMSyntax: 2 searchFlags: 0 lDAPDisplayName: xMITTimeoutNormal name: ms-Exch-XMIT-Timeout-Normal schemaIDGUID: a8df74a5-c5ea-11d1-bbcb-0080c76670c0 isMemberOfPartialAttributeSet: FALSE objectCategory: CN=Attribute-Schema,${SCHEMADN} # # ms-Exch-XMIT-Timeout-Urgent # dn: CN=ms-Exch-XMIT-Timeout-Urgent,${SCHEMADN} objectClass: top objectClass: attributeSchema cn: ms-Exch-XMIT-Timeout-Urgent distinguishedName: CN=ms-Exch-XMIT-Timeout-Urgent,${SCHEMADN} attributeID: 1.2.840.113556.1.2.53 attributeSyntax: 2.5.5.9 isSingleValued: TRUE rangeLower: 0 rangeUpper: 32767 mAPIID: 33125 showInAdvancedViewOnly: TRUE adminDisplayName: ms-Exch-XMIT-Timeout-Urgent adminDescription: ms-Exch-XMIT-Timeout-Urgent oMSyntax: 2 searchFlags: 0 lDAPDisplayName: xMITTimeoutUrgent name: ms-Exch-XMIT-Timeout-Urgent schemaIDGUID: 1482fed4-b098-11d2-aa06-00c04f8eedd8 isMemberOfPartialAttributeSet: FALSE objectCategory: CN=Attribute-Schema,${SCHEMADN} openchange-2.0/setup/AD/oc_provision_schema_auxiliary_class.ldif000066400000000000000000000155101223057412600252570ustar00rootroot00000000000000############################################################################## # Auxiliary classes added ############################################################################## # # ms-Exch-Base-Class # description: The base auxiliary class that is applied to all classes # that are extended by CDO for Exchange 2000 Server (CDOEX) and the base # Microsoft Windows classes that are used. # dn: CN=ms-Exch-Base-Class,${SCHEMADN} objectClass: top objectClass: classSchema cn: ms-Exch-Base-Class distinguishedName: CN=ms-Exch-Base-Class,${SCHEMADN} subClassOf: top governsID: 1.2.840.113556.1.5.7000.62.14 mayContain: msExchInconsistentState mayContain: heuristics mayContain: auxiliaryClass mayContain: msExchUserAccountControl mayContain: msExchALObjectVersion mayContain: msExchUnmergedAttsPt mayContain: showInAddressBook mayContain: unmergedAtts mayContain: replicationSignature mayContain: replicatedObjectVersion mayContain: msExchHideFromAddressLists mayContain: msExchADCGlobalNames mayContain: legacyExchangeDN rDNAttID: cn showInAdvancedViewOnly: TRUE adminDisplayName: ms-Exch-Base-Class adminDescription: ms-Exch-Base-Class objectClassCategory: 3 lDAPDisplayName: msExchBaseClass schemaIDGUID: d8782c34-46ca-11d3-aa72-00c04f8eedd8 systemOnly: FALSE defaultHidingValue: TRUE defaultObjectCategory: CN=ms-Exch-Base-Class,${SCHEMADN} # # ms-Exch-Certificate-Information # The auxiliary class of users and contacts that contains all # certificates and certificate information. Users publish their # certificates to attributes located on this object. # dn: CN=ms-Exch-Certificate-Information,${SCHEMADN} objectClass: top objectClass: classSchema cn: ms-Exch-Certificate-Information distinguishedName: CN=ms-Exch-Certificate-Information,${SCHEMADN} subClassOf: top governsID: 1.2.840.113556.1.5.7000.62.7 mayContain: userCertificate mayContain: userSMIMECertificate mayContain: userCert mayContain: supportedAlgorithms mayContain: attributeCertificate rDNAttID: cn showInAdvancedViewOnly: TRUE adminDisplayName: ms-Exch-Certificate-Information adminDescription: ms-Exch-Certificate-Information objectClassCategory: 3 lDAPDisplayName: msExchCertificateInformation name: ms-Exch-Certificate-Information schemaIDGUID: e8977034-a980-11d2-a9ff-00c04f8eedd8 systemOnly: FALSE defaultHidingValue: TRUE objectCategory: CN=Class-Schema,${SCHEMADN} defaultObjectCategory: CN=ms-Exch-Certificate-Information,${SCHEMADN} # # ms-Exch-Custom-Attributes # The auxiliary class for objects that require custom attributes. # dn: CN=ms-Exch-Custom-Attributes,${SCHEMADN} objectClass: top objectClass: classSchema cn: ms-Exch-Custom-Attributes distinguishedName: CN=ms-Exch-Custom-Attributes,${SCHEMADN} subClassOf: top governsID: 1.2.840.113556.1.5.7000.62.6 #mayContain: extensionAttribute9 #mayContain: extensionAttribute8 #mayContain: extensionAttribute7 #mayContain: extensionAttribute6 #mayContain: extensionAttribute5 #mayContain: extensionAttribute4 #mayContain: extensionAttribute3 #mayContain: extensionAttribute2 #mayContain: extensionAttribute15 #mayContain: extensionAttribute14 #mayContain: extensionAttribute13 #mayContain: extensionAttribute12 #mayContain: extensionAttribute11 #mayContain: extensionAttribute10 #mayContain: extensionAttribute1 rDNAttID: cn showInAdvancedViewOnly: TRUE adminDisplayName: ms-Exch-Custom-Attributes adminDescription: ms-Exch-Custom-Attributes objectClassCategory: 3 lDAPDisplayName: msExchCustomAttributes name: ms-Exch-Custom-Attributes schemaIDGUID: 00e629c8-a981-11d2-a9ff-00c04f8eedd8 systemOnly: FALSE defaultHidingValue: TRUE objectCategory: CN=Class-Schema,${SCHEMADN} defaultObjectCategory: CN=ms-Exch-Custom-Attributes,${SCHEMADN} # # ms-Exch-IM-Recipient # The auxiliary class for all objects that will be enabled for Instant # Messaging. # dn: CN=ms-Exch-IM-Recipient,${SCHEMADN} objectClass: top objectClass: classSchema cn: ms-Exch-IM-Recipient distinguishedName: CN=ms-Exch-IM-Recipient,${SCHEMADN} subClassOf: top governsID: 1.2.840.113556.1.5.7000.62.7008 mayContain: msExchIMVirtualServer mayContain: msExchIMAddress mayContain: msExchIMPhysicalURL mayContain: msExchIMMetaPhysicalURL mayContain: msExchIMACL rDNAttID: cn showInAdvancedViewOnly: TRUE adminDisplayName: ms-Exch-IM-Recipient adminDescription: ms-Exch-IM-Recipient objectClassCategory: 3 lDAPDisplayName: msExchIMRecipient name: ms-Exch-IM-Recipient schemaIDGUID: 028502f4-a981-11d2-a9ff-00c04f8eedd8 systemOnly: FALSE defaultHidingValue: TRUE objectCategory: CN=Class-Schema,${SCHEMADN} defaultObjectCategory: CN=ms-Exch-IM-Recipient,${SCHEMADN} # # ms-Exch-Mail-Storage # The auxiliary class for objects that require store-specific information. # dn: CN=ms-Exch-Mail-Storage,${SCHEMADN} objectClass: top objectClass: classSchema cn: ms-Exch-Mail-Storage distinguishedName: CN=ms-Exch-Mail-Storage,${SCHEMADN} subClassOf: top governsID: 1.2.840.113556.1.5.7000.62.5 mayContain: msExchPfRootUrl mayContain: msExchMailboxUrl mayContain: msExchUseOAB mayContain: msExchMailboxGuid mayContain: mDBUseDefaults mayContain: mDBStorageQuota mayContain: mDBOverQuotaLimit mayContain: mDBOverHardQuotaLimit mayContain: msExchHomeServerName mayContain: homeMDB mayContain: deletedItemFlags mayContain: autoReply mayContain: garbageCollPeriod rDNAttID: cn showInAdvancedViewOnly: TRUE adminDisplayName: ms-Exch-Mail-Storage adminDescription: ms-Exch-Mail-Storage objectClassCategory: 3 lDAPDisplayName: msExchMailStorage name: ms-Exch-Mail-Storage schemaIDGUID: 03652000-a981-11d2-a9ff-00c04f8eedd8 systemOnly: FALSE defaultHidingValue: TRUE objectCategory: CN=Class-Schema,${SCHEMADN} defaultObjectCategory: CN=ms-Exch-Mail-Storage,${SCHEMADN} # # ms-Exch-Mailbox-Manager-Policy # dn: CN=ms-Exch-Mailbox-Manager-Policy,${SCHEMADN} objectClass: top objectClass: classSchema cn: ms-Exch-Mailbox-Manager-Policy distinguishedName: CN=ms-Exch-Mailbox-Manager-Policy,${SCHEMADN} possSuperiors: container subClassOf: top governsID: 1.2.840.113556.1.5.7000.62.50033 mayContain: msExchMailboxManagerUserMessageHeader mayContain: msExchMailboxManagerUserMessageFooter mayContain: msExchMailboxManagerUserMessageBody mayContain: msExchMailboxManagerSizeLimitEnabled mayContain: msExchMailboxManagerSizeLimit mayContain: msExchMailboxManagerSendUserNotificationMail mayContain: msExchMailboxManagerMode mayContain: msExchMailboxManagerKeepMessageClasses mayContain: msExchMailboxManagerFolderSettings mayContain: msExchMailboxManagerCustomMessage mayContain: msExchMailboxManagerAgeLimit rDNAttID: cn showInAdvancedViewOnly: TRUE adminDisplayName: ms-Exch-Mailbox-Manager-Policy adminDescription: ms-Exch-Mailbox-Manager-Policy objectClassCategory: 3 lDAPDisplayName: msExchMailboxManagerPolicy name: ms-Exch-Mailbox-Manager-Policy schemaIDGUID: 36f94fcc-ebbb-4a32-b721-1cae42b2dbab systemOnly: FALSE defaultSecurityDescriptor: D:S: defaultHidingValue: TRUE objectCategory: CN=Class-Schema,${SCHEMADN} defaultObjectCategory: CN=ms-Exch-Mailbox-Manager-Policy,${SCHEMADN} openchange-2.0/setup/AD/oc_provision_schema_container.ldif000066400000000000000000000755271223057412600240630ustar00rootroot00000000000000# # ms-Exch-Container # An Exchange container. Used for extended rights and roles. # dn: CN=ms-Exch-Container,${SCHEMADN} objectClass: top objectClass: classSchema cn: ms-Exch-Container distinguishedName: CN=ms-Exch-Container,${SCHEMADN} possSuperiors: msExchAdminGroup subClassOf: container governsID: 1.2.840.113556.1.5.7000.62.50010 mayContain: msExchMinAdminVersion mayContain: msExchAdminGroupMode rDNAttID: cn showInAdvancedViewOnly: TRUE adminDisplayName: ms-Exch-Container adminDescription: ms-Exch-Container auxiliaryClass: msExchBaseClass objectClassCategory: 1 lDAPDisplayName: msExchContainer name: ms-Exch-Container schemaIDGUID: 006c91da-a981-11d2-a9ff-00c04f8eedd8 systemOnly: FALSE defaultSecurityDescriptor: D:S: defaultHidingValue: TRUE objectCategory: CN=Class-Schema,${SCHEMADN} defaultObjectCategory: CN=ms-Exch-Container,${SCHEMADN} # # ms-Exch-Admin-Group-Container # description: An administrative group container. Used for extended rights and roles. # dn: CN=ms-Exch-Admin-Group-Container,${SCHEMADN} objectClass: top objectClass: classSchema cn: ms-Exch-Admin-Group-Container distinguishedName: CN=ms-Exch-Admin-Group-Container,${SCHEMADN} subClassOf: container governsID: 1.2.840.113556.1.5.7000.62.50019 rDNAttID: cn showInAdvancedViewOnly: TRUE adminDisplayName: ms-Exch-Admin-Group-Container adminDescription: ms-Exch-Admin-Group-Container auxiliaryClass: msExchBaseClass objectClassCategory: 1 lDAPDisplayName: msExchAdminGroupContainer name: ms-Exch-Admin-Group-Container schemaIDGUID: e7a44058-a980-11d2-a9ff-00c04f8eedd8 systemOnly: FALSE defaultSecurityDescriptor: D:S: defaultHidingValue: TRUE objectCategory: CN=Class-Schema,${SCHEMADN} defaultObjectCategory: CN=ms-Exch-Admin-Group-Container,${SCHEMADN} # # ms-Exch-Advanced-Security-Container # A container object to hold the Encryption Configuration and Key # Manager objects # dn: CN=ms-Exch-Advanced-Security-Container,${SCHEMADN} objectClass: top objectClass: classSchema cn: ms-Exch-Advanced-Security-Container distinguishedName: CN=ms-Exch-Advanced-Security-Container,${SCHEMADN} possSuperiors: msExchAdminGroup subClassOf: container governsID: 1.2.840.113556.1.5.7000.62.13001 mayContain: msExchMinAdminVersion rDNAttID: cn showInAdvancedViewOnly: TRUE adminDisplayName: ms-Exch-Advanced-Security-Container adminDescription: ms-Exch-Advanced-Security-Container auxiliaryClass: msExchBaseClass objectClassCategory: 1 lDAPDisplayName: msExchAdvancedSecurityContainer name: ms-Exch-Advanced-Security-Container schemaIDGUID: 8cc8fb0e-b09e-11d2-aa06-00c04f8eedd8 systemOnly: FALSE defaultSecurityDescriptor: D:(A;;LC;;;AU) defaultHidingValue: TRUE objectCategory: CN=Class-Schema,${SCHEMADN} defaultObjectCategory: CN=ms-Exch-Advanced-Security-Container,${SCHEMADN} # # ms-Exch-Conference-Container # A conferencing container. Used for extended rights and # roles. CN=Exchange Conferencing. # dn: CN=ms-Exch-Conference-Container,${SCHEMADN} objectClass: top objectClass: classSchema cn: ms-Exch-Conference-Container distinguishedName: CN=ms-Exch-Conference-Container,${SCHEMADN} possSuperiors: msExchAdminGroup subClassOf: container governsID: 1.2.840.113556.1.5.7000.62.9005 mayContain: objectCount rDNAttID: cn showInAdvancedViewOnly: TRUE adminDisplayName: ms-Exch-Conference-Container adminDescription: ms-Exch-Conference-Container auxiliaryClass: msExchBaseClass objectClassCategory: 1 lDAPDisplayName: msExchConferenceContainer name: ms-Exch-Conference-Container schemaIDGUID: ed7fe77a-a980-11d2-a9ff-00c04f8eedd8 systemOnly: FALSE defaultSecurityDescriptor: D:(A;CI;LCLORPRC;;;WD) defaultHidingValue: TRUE objectCategory: CN=Class-Schema,${SCHEMADN} defaultObjectCategory: CN=ms-Exch-Conference-Container,${SCHEMADN} # # ms-Exch-Content-Config-Container # dn: CN=ms-Exch-Content-Config-Container,${SCHEMADN} objectClass: top objectClass: classSchema cn: ms-Exch-Content-Config-Container distinguishedName: CN=ms-Exch-Content-Config-Container,${SCHEMADN} possSuperiors: container subClassOf: container governsID: 1.2.840.113556.1.5.7000.62.50026 mayContain: msExchMinAdminVersion mayContain: msExchMimeTypes rDNAttID: cn showInAdvancedViewOnly: TRUE adminDisplayName: ms-Exch-Content-Config-Container adminDescription: ms-Exch-Content-Config-Container auxiliaryClass: msExchBaseClass objectClassCategory: 1 lDAPDisplayName: msExchContentConfigContainer name: ms-Exch-Content-Config-Container schemaIDGUID: ab3a1acc-1df5-11d3-aa5e-00c04f8eedd8 systemOnly: FALSE defaultSecurityDescriptor: D:S: defaultHidingValue: TRUE objectCategory: CN=Class-Schema,${SCHEMADN} defaultObjectCategory: CN=ms-Exch-Content-Config-Container,${SCHEMADN} # # ms-Exch-Monitors-Container # A container used to hold monitors. Used for extended rights and roles. # dn: CN=ms-Exch-Monitors-Container,${SCHEMADN} objectClass: top objectClass: classSchema cn: ms-Exch-Monitors-Container distinguishedName: CN=ms-Exch-Monitors-Container,${SCHEMADN} possSuperiors: msExchAdminGroup subClassOf: container governsID: 1.2.840.113556.1.5.7000.62.50012 rDNAttID: cn showInAdvancedViewOnly: TRUE adminDisplayName: ms-Exch-Monitors-Container adminDescription: ms-Exch-Monitors-Container auxiliaryClass: msExchBaseClass objectClassCategory: 1 lDAPDisplayName: msExchMonitorsContainer name: ms-Exch-Monitors-Container schemaIDGUID: 03f68f72-a981-11d2-a9ff-00c04f8eedd8 systemOnly: FALSE defaultSecurityDescriptor: D:S: defaultHidingValue: TRUE objectCategory: CN=Class-Schema,${SCHEMADN} defaultObjectCategory: CN=ms-Exch-Monitors-Container,${SCHEMADN} # # ms-Exch-Organization-Container # An organization container. Used for extended rights and roles. # dn: CN=ms-Exch-Organization-Container,${SCHEMADN} objectClass: top objectClass: classSchema cn: ms-Exch-Organization-Container distinguishedName: CN=ms-Exch-Organization-Container,${SCHEMADN} subClassOf: container governsID: 1.2.840.113556.1.5.7000.62.50020 mayContain: msExchMinAdminVersion mayContain: heuristics mayContain: msExchDisableUDGConversion mayContain: msExchServerLocalGroups mayContain: msExchServerGroups mayContain: msExchServerGlobalGroups mayContain: msExchAdmins mayContain: msExchAdminGroupsEnabled mayContain: msExchWebAccessName mayContain: submissionContLength mayContain: msExchMixedMode mayContain: msExchMimeTypes mayContain: delivContLength mayContain: msExchRoutingEnabled mayContain: msExchRecipLimit rDNAttID: cn showInAdvancedViewOnly: TRUE adminDisplayName: ms-Exch-Organization-Container adminDescription: ms-Exch-Organization-Container auxiliaryClass: msExchBaseClass objectClassCategory: 1 lDAPDisplayName: msExchOrganizationContainer name: ms-Exch-Organization-Container schemaIDGUID: 366a319c-a982-11d2-a9ff-00c04f8eedd8 systemOnly: FALSE defaultSecurityDescriptor: D:S: defaultHidingValue: TRUE objectCategory: CN=Class-Schema,${SCHEMADN} defaultObjectCategory: CN=ms-Exch-Organization-Container,${SCHEMADN} # # ms-Exch-Generic-Policy-Container # dn: CN=ms-Exch-Generic-Policy-Container,${SCHEMADN} objectClass: top objectClass: classSchema cn: ms-Exch-Generic-Policy-Container distinguishedName: CN=ms-Exch-Generic-Policy-Container,${SCHEMADN} subClassOf: top governsID: 1.2.840.113556.1.5.7000.62.50021 mayContain: msExchADCOptions rDNAttID: cn showInAdvancedViewOnly: TRUE adminDisplayName: ms-Exch-Generic-Policy-Container adminDescription: ms-Exch-Generic-Policy-Container auxiliaryClass: msExchBaseClass objectClassCategory: 1 lDAPDisplayName: msExchGenericPolicyContainer name: ms-Exch-Generic-Policy-Container schemaIDGUID: e32977c3-1d31-11d3-aa5e-00c04f8eedd8 systemOnly: FALSE defaultSecurityDescriptor: D:S: defaultHidingValue: TRUE objectCategory: CN=Class-Schema,${SCHEMADN} defaultObjectCategory: CN=ms-Exch-Generic-Policy-Container,${SCHEMADN} # # ms-Exch-Policies-Container # A container used to hold policies. Used for extended rights and # roles. # dn: CN=ms-Exch-Policies-Container,${SCHEMADN} objectClass: top objectClass: classSchema cn: ms-Exch-Policies-Container distinguishedName: CN=ms-Exch-Policies-Container,${SCHEMADN} possSuperiors: msExchAdminGroup subClassOf: container governsID: 1.2.840.113556.1.5.7000.62.50014 rDNAttID: cn showInAdvancedViewOnly: TRUE adminDisplayName: ms-Exch-Policies-Container adminDescription: ms-Exch-Policies-Container auxiliaryClass: msExchBaseClass objectClassCategory: 1 lDAPDisplayName: msExchPoliciesContainer name: ms-Exch-Policies-Container schemaIDGUID: 3630f92c-a982-11d2-a9ff-00c04f8eedd8 systemOnly: FALSE defaultSecurityDescriptor: D:S: defaultHidingValue: TRUE objectCategory: CN=Class-Schema,${SCHEMADN} defaultObjectCategory: CN=ms-Exch-Policies-Container,${SCHEMADN} # # ms-Exch-Servers-Container # A container used to hold servers. Used for extended rights and roles. # dn: CN=ms-Exch-Servers-Container,${SCHEMADN} objectClass: top objectClass: classSchema cn: ms-Exch-Servers-Container distinguishedName: CN=ms-Exch-Servers-Container,${SCHEMADN} possSuperiors: msExchAdminGroup subClassOf: container governsID: 1.2.840.113556.1.5.7000.62.50013 mayContain: msExchMinAdminVersion rDNAttID: cn showInAdvancedViewOnly: TRUE adminDisplayName: ms-Exch-Servers-Container adminDescription: ms-Exch-Servers-Container auxiliaryClass: msExchBaseClass objectClassCategory: 1 lDAPDisplayName: msExchServersContainer name: ms-Exch-Servers-Container schemaIDGUID: 346e5cba-a982-11d2-a9ff-00c04f8eedd8 systemOnly: FALSE defaultSecurityDescriptor: D:(A;;LC;;;AU) defaultHidingValue: TRUE objectCategory: CN=Class-Schema,${SCHEMADN} defaultObjectCategory: CN=ms-Exch-Servers-Container,${SCHEMADN} # # ms-Exch-IM-Global-Settings-Container # A container for global objects. # dn: CN=ms-Exch-IM-Global-Settings-Container,${SCHEMADN} objectClass: top objectClass: classSchema cn: ms-Exch-IM-Global-Settings-Container distinguishedName: CN=ms-Exch-IM-Global-Settings-Container,${SCHEMADN} possSuperiors: container subClassOf: container governsID: 1.2.840.113556.1.5.7000.62.7014 rDNAttID: cn showInAdvancedViewOnly: TRUE adminDisplayName: ms-Exch-IM-Global-Settings-Container adminDescription: ms-Exch-IM-Global-Settings-Container auxiliaryClass: msExchBaseClass objectClassCategory: 1 lDAPDisplayName: msExchIMGlobalSettingsContainer name: ms-Exch-IM-Global-Settings-Container schemaIDGUID: 9f116eb8-284e-11d3-aa68-00c04f8eedd8 systemOnly: FALSE defaultSecurityDescriptor: D:S: defaultHidingValue: TRUE objectCategory: CN=Class-Schema,${SCHEMADN} defaultObjectCategory: CN=ms-Exch-IM-Global-Settings-Container,${SCHEMADN} # # ms-Exch-MHS-Monitoring-Config # The EMS saved Monitoring configuration. # dn: CN=ms-Exch-MHS-Monitoring-Config,${SCHEMADN} objectClass: top objectClass: classSchema cn: ms-Exch-MHS-Monitoring-Config distinguishedName: CN=ms-Exch-MHS-Monitoring-Config,${SCHEMADN} possSuperiors: container subClassOf: top governsID: 1.2.840.113556.1.3.6 mustContain: cn mayContain: runsOn mayContain: monitoringNormalPollUnits mayContain: monitoringNormalPollInterval mayContain: monitoringHotsitePollUnits mayContain: monitoringHotsitePollInterval mayContain: monitoringEscalationProcedure mayContain: monitoringAvailabilityWindow mayContain: monitoringAvailabilityStyle mayContain: monitoredServers mayContain: logFilename rDNAttID: cn showInAdvancedViewOnly: TRUE adminDisplayName: ms-Exch-MHS-Monitoring-Config adminDescription: ms-Exch-MHS-Monitoring-Config auxiliaryClass: msExchBaseClass objectClassCategory: 1 lDAPDisplayName: mHSMonitoringConfig name: ms-Exch-MHS-Monitoring-Config schemaIDGUID: a8df74bb-c5ea-11d1-bbcb-0080c76670c0 systemOnly: FALSE defaultSecurityDescriptor: D:S: defaultHidingValue: TRUE objectCategory: CN=Class-Schema,${SCHEMADN} defaultObjectCategory: CN=ms-Exch-MHS-Monitoring-Config,${SCHEMADN} # # ms-Exch-Protocol-Cfg # dn: CN=ms-Exch-Protocol-Cfg,${SCHEMADN} objectClass: top objectClass: classSchema cn: ms-Exch-Protocol-Cfg distinguishedName: CN=ms-Exch-Protocol-Cfg,${SCHEMADN} possSuperiors: container subClassOf: top governsID: 1.2.840.113556.1.3.68 mustContain: cn mayContain: msExchMinAdminVersion mayContain: msExchDS2MBOptions mayContain: heuristics mayContain: useSiteValues mayContain: sendTNEF mayContain: requireSSL mayContain: preserveInternetContent mayContain: portNumber mayContain: incomingMsgSizeLimit mayContain: enabledProtocolCfg mayContain: enabledAuthorizationPackages mayContain: diagnosticRegKey mayContain: contentType mayContain: clientAccessEnabled mayContain: characterSet mayContain: associationLifetime mayContain: anonymousAccess rDNAttID: cn showInAdvancedViewOnly: TRUE adminDisplayName: ms-Exch-Protocol-Cfg adminDescription: ms-Exch-Protocol-Cfg auxiliaryClass: msExchBaseClass objectClassCategory: 1 lDAPDisplayName: protocolCfg name: ms-Exch-Protocol-Cfg schemaIDGUID: a8df74c0-c5ea-11d1-bbcb-0080c76670c0 systemOnly: FALSE defaultSecurityDescriptor: D:S: defaultHidingValue: TRUE objectCategory: CN=Class-Schema,${SCHEMADN} defaultObjectCategory: CN=ms-Exch-Protocol-Cfg,${SCHEMADN} # # ms-Exch-Protocol-Cfg-Shared-Container # dn: CN=ms-Exch-Protocol-Cfg-Shared-Container,${SCHEMADN} objectClass: top objectClass: classSchema cn: ms-Exch-Protocol-Cfg-Shared-Container distinguishedName: CN=ms-Exch-Protocol-Cfg-Shared-Container,${SCHEMADN} #possSuperiors: protocolCfgSharedServer subClassOf: container governsID: 1.2.840.113556.1.5.7000.62.2001 mayContain: msExchMinAdminVersion rDNAttID: cn showInAdvancedViewOnly: TRUE adminDisplayName: ms-Exch-Protocol-Cfg-Shared-Container adminDescription: ms-Exch-Protocol-Cfg-Shared-Container auxiliaryClass: msExchBaseClass objectClassCategory: 1 lDAPDisplayName: msExchProtocolCfgSharedContainer name: ms-Exch-Protocol-Cfg-Shared-Container schemaIDGUID: 939ef91a-b09e-11d2-aa06-00c04f8eedd8 systemOnly: FALSE defaultSecurityDescriptor: D:S: defaultHidingValue: TRUE objectCategory: CN=Class-Schema,${SCHEMADN} defaultObjectCategory: CN=ms-Exch-Protocol-Cfg-Shared-Container,${SCHEMADN} dn: CN=ms-Exch-Protocol-Cfg-Shared-Server,${SCHEMADN} objectClass: top objectClass: classSchema cn: ms-Exch-Protocol-Cfg-Shared-Server distinguishedName: CN=ms-Exch-Protocol-Cfg-Shared-Server,${SCHEMADN} instanceType: 4 possSuperiors: msExchExchangeServer possSuperiors: container possSuperiors: computer subClassOf: protocolCfgShared governsID: 1.2.840.113556.1.3.67 rDNAttID: cn showInAdvancedViewOnly: TRUE adminDisplayName: ms-Exch-Protocol-Cfg-Shared-Server adminDescription: ms-Exch-Protocol-Cfg-Shared-Server auxiliaryClass: msExchBaseClass objectClassCategory: 1 lDAPDisplayName: protocolCfgSharedServer name: ms-Exch-Protocol-Cfg-Shared-Server schemaIDGUID: a8df74d1-c5ea-11d1-bbcb-0080c76670c0 systemOnly: FALSE defaultSecurityDescriptor: D:S: defaultHidingValue: TRUE objectCategory: CN=Class-Schema,${SCHEMADN} defaultObjectCategory: CN=ms-Exch-Protocol-Cfg-Shared-Server,${SCHEMADN} # # ms-Exch-Protocol-Cfg-Shared-Site # dn: CN=ms-Exch-Protocol-Cfg-Shared-Site,${SCHEMADN} objectClass: top objectClass: classSchema cn: ms-Exch-Protocol-Cfg-Shared-Site distinguishedName: CN=ms-Exch-Protocol-Cfg-Shared-Site,${SCHEMADN} instanceType: 4 possSuperiors: container subClassOf: protocolCfgShared governsID: 1.2.840.113556.1.3.66 rDNAttID: cn showInAdvancedViewOnly: TRUE adminDisplayName: ms-Exch-Protocol-Cfg-Shared-Site adminDescription: ms-Exch-Protocol-Cfg-Shared-Site auxiliaryClass: msExchBaseClass objectClassCategory: 1 lDAPDisplayName: protocolCfgSharedSite name: ms-Exch-Protocol-Cfg-Shared-Site schemaIDGUID: a8df74d2-c5ea-11d1-bbcb-0080c76670c0 systemOnly: FALSE defaultSecurityDescriptor: D:S: defaultHidingValue: TRUE objectCategory: CN=Class-Schema,${SCHEMADN} defaultObjectCategory: CN=ms-Exch-Protocol-Cfg-Shared-Site,${SCHEMADN} # # ms-Exch-Protocol-Cfg-Protocol-Container # dn: CN=ms-Exch-Protocol-Cfg-Protocol-Container,${SCHEMADN} objectClass: top objectClass: classSchema cn: ms-Exch-Protocol-Cfg-Protocol-Container distinguishedName: CN=ms-Exch-Protocol-Cfg-Protocol-Container,${SCHEMADN} instanceType: 4 #possSuperiors: protocolCfgSharedServer subClassOf: container governsID: 1.2.840.113556.1.5.7000.62.2000 rDNAttID: cn showInAdvancedViewOnly: TRUE adminDisplayName: ms-Exch-Protocol-Cfg-Protocol-Container adminDescription: ms-Exch-Protocol-Cfg-Protocol-Container auxiliaryClass: msExchBaseClass objectClassCategory: 1 lDAPDisplayName: msExchProtocolCfgProtocolContainer name: ms-Exch-Protocol-Cfg-Protocol-Container schemaIDGUID: 90f2b634-b09e-11d2-aa06-00c04f8eedd8 systemOnly: FALSE defaultSecurityDescriptor: D:S: defaultHidingValue: TRUE objectCategory: CN=Class-Schema,${SCHEMADN} defaultObjectCategory: CN=ms-Exch-Protocol-Cfg-Protocol-Container,${SCHEMADN} # # ms-Exch-System-Objects-Container # The Exchange container for system-related objects, such as public # folder proxies. # dn: CN=ms-Exch-System-Objects-Container,${SCHEMADN} objectClass: top objectClass: classSchema cn: ms-Exch-System-Objects-Container distinguishedName: CN=ms-Exch-System-Objects-Container,${SCHEMADN} possSuperiors: domainDNS subClassOf: container governsID: 1.2.840.113556.1.5.7000.62.50034 rDNAttID: cn showInAdvancedViewOnly: TRUE adminDisplayName: ms-Exch-System-Objects-Container adminDescription: ms-Exch-System-Objects-Container objectClassCategory: 1 lDAPDisplayName: msExchSystemObjectsContainer name: ms-Exch-System-Objects-Container schemaIDGUID: 0bffa04c-7d8e-44cd-968a-b2cac11d17e1 systemOnly: FALSE defaultSecurityDescriptor: D:(A;;RPLCLORC;;;AU) defaultHidingValue: TRUE objectCategory: CN=Class-Schema,${SCHEMADN} defaultObjectCategory: CN=ms-Exch-System-Objects-Container,${SCHEMADN} # # ms-Exch-Storage-Group # The list of stores for this Microsoft Jet instance. # dn: CN=ms-Exch-Storage-Group,${SCHEMADN} objectClass: top objectClass: classSchema cn: ms-Exch-Storage-Group distinguishedName: CN=ms-Exch-Storage-Group,${SCHEMADN} possSuperiors: computer subClassOf: container governsID: 1.2.840.113556.1.5.7000.62.11006 mustContain: cn mayContain: msExchMinAdminVersion mayContain: msExchESEParamCachedClosedTables mayContain: msExchRestore mayContain: msExchESEParamPageTempDBMin mayContain: msExchESEParamPageFragment mayContain: msExchESEParamMaxTemporaryTables mayContain: msExchESEParamMaxCursors mayContain: msExchESEParamEnableOnlineDefrag mayContain: msExchESEParamEnableIndexChecking mayContain: msExchESEParamDbExtensionSize mayContain: msExchESEParamCommitDefault mayContain: msExchESEParamCheckpointDepthMax mayContain: msExchESEParamBaseName mayContain: msExchRecovery mayContain: msExchESEParamZeroDatabaseDuringBackup mayContain: msExchESEParamWaitLogFlush mayContain: msExchESEParamTempPath mayContain: msExchESEParamSystemPath mayContain: msExchESEParamPreferredVerPages mayContain: msExchESEParamPreferredMaxOpenTables mayContain: msExchESEParamMaxVerPages mayContain: msExchESEParamMaxSessions mayContain: msExchESEParamMaxOpenTables mayContain: msExchESEParamLogWaitingUserMax mayContain: msExchESEParamLogFileSize mayContain: msExchESEParamLogFilePath mayContain: msExchESEParamLogCheckpointPeriod mayContain: msExchESEParamLogBuffers mayContain: msExchESEParamEventSource mayContain: msExchESEParamCircularLog mayContain: displayName mayContain: description rDNAttID: cn showInAdvancedViewOnly: TRUE adminDisplayName: ms-Exch-Storage-Group adminDescription: ms-Exch-Storage-Group auxiliaryClass: msExchBaseClass objectClassCategory: 1 lDAPDisplayName: msExchStorageGroup name: ms-Exch-Storage-Group schemaIDGUID: 3435244a-a982-11d2-a9ff-00c04f8eedd8 systemOnly: FALSE defaultSecurityDescriptor: D:S: defaultHidingValue: TRUE objectCategory: CN=Class-Schema,${SCHEMADN} defaultObjectCategory: CN=ms-Exch-Storage-Group,${SCHEMADN} # # ms-Exch-MDB # Used for generic database configuration. # dn: CN=ms-Exch-MDB,${SCHEMADN} objectClass: top objectClass: classSchema cn: ms-Exch-MDB distinguishedName: CN=ms-Exch-MDB,${SCHEMADN} #possSuperiors: msExchStorageGroup possSuperiors: msExchExchangeServer possSuperiors: container possSuperiors: computer subClassOf: top governsID: 1.2.840.113556.1.5.7000.62.11002 mustContain: deliveryMechanism mustContain: cn mayContain: msExchMinAdminVersion mayContain: msExchPatchMDB mayContain: msExchDatabaseCreated mayContain: msExchDatabaseBeingRestored mayContain: msExchAllowEnhancedSecurity mayContain: msExchMaxCachedViews mayContain: msExchCIUpdateStyle mayContain: msExchCIUpdateSchedule mayContain: msExchCIRebuildStyle mayContain: msExchCIRebuildSchedule mayContain: msExchCILocation mayContain: msExchCIAvailable mayContain: msExchAgingKeepTime mayContain: homeMDBBL mayContain: msExchTrackDuplicates mayContain: msExchSLVFile mayContain: quotaNotificationStyle mayContain: quotaNotificationSchedule mayContain: msExchPolicyOptionList mayContain: msExchPolicyList mayContain: msExchOwningServer mayContain: messageTrackingEnabled mayContain: mDBStorageQuota mayContain: mDBOverQuotaLimit mayContain: mDBOverHardQuotaLimit mayContain: maximumObjectID mayContain: msExchEDBOffline mayContain: msExchEDBFile mayContain: msExchDownGradeMultipartSigned mayContain: diagnosticRegKey mayContain: deletedItemFlags mayContain: msExchConvertToFixedFont mayContain: msExchCatalog mayContain: activationStyle mayContain: activationSchedule mayContain: garbageCollPeriod mayContain: displayName mayContain: description mayContain: adminDisplayName rDNAttID: cn showInAdvancedViewOnly: TRUE adminDisplayName: ms-Exch-MDB adminDescription: ms-Exch-MDB auxiliaryClass: msExchBaseClass objectClassCategory: 1 lDAPDisplayName: msExchMDB name: ms-Exch-MDB schemaIDGUID: 03d069d2-a981-11d2-a9ff-00c04f8eedd8 systemOnly: FALSE defaultSecurityDescriptor: D:S: defaultHidingValue: TRUE objectCategory: CN=Class-Schema,${SCHEMADN} defaultObjectCategory: CN=ms-Exch-MDB,${SCHEMADN} # # ms-Exch-MTA # Represents the message transfer agent (MTA) process on the computer. # dn: CN=ms-Exch-MTA,${SCHEMADN} objectClass: top objectClass: classSchema cn: ms-Exch-MTA distinguishedName: CN=ms-Exch-MTA,${SCHEMADN} possSuperiors: msExchExchangeServer possSuperiors: container possSuperiors: computer subClassOf: top governsID: 1.2.840.113556.1.3.49 mustContain: transTimeoutMins mustContain: transRetryMins mustContain: mTALocalDesig mustContain: cn mayContain: msExchMinAdminVersion mayContain: msExchEncryptedPassword mayContain: msExchResponsibleMTAServerBL mayContain: msExchMTADatabasePath mayContain: xMITTimeoutUrgent mayContain: xMITTimeoutNormal mayContain: xMITTimeoutNonUrgent mayContain: transportExpeditedData mayContain: transferTimeoutUrgent mayContain: transferTimeoutNormal mayContain: transferTimeoutNonUrgent mayContain: transferRetryInterval mayContain: tempAssocThreshold mayContain: sessionDisconnectTimer mayContain: rTSWindowSize mayContain: rTSRecoveryTimeout mayContain: rTSCheckpointSize mayContain: openRetryInterval mayContain: numOfTransferRetries mayContain: numOfOpenRetries mayContain: messageTrackingEnabled mayContain: domainDefAltRecip mayContain: associationLifetime mayContain: mTALocalCred mayContain: msExchHomeRoutingGroupDNBL mayContain: expandDLsLocally mayContain: diagnosticRegKey mayContain: delivExtContTypes mayContain: delivEITs mayContain: delivContLength mayContain: msExchBridgeheadedRemoteConnectorsDNBL mayContain: msExchBridgeheadedLocalConnectorsDNBL rDNAttID: cn showInAdvancedViewOnly: TRUE adminDisplayName: ms-Exch-MTA adminDescription: ms-Exch-MTA auxiliaryClass: msExchBaseClass objectClassCategory: 1 lDAPDisplayName: mTA name: ms-Exch-MTA schemaIDGUID: a8df74a7-c5ea-11d1-bbcb-0080c76670c0 systemOnly: FALSE defaultSecurityDescriptor: D:S: defaultHidingValue: TRUE objectCategory: CN=Class-Schema,${SCHEMADN} defaultObjectCategory: CN=ms-Exch-MTA,${SCHEMADN} # # ms-Exch-DXA-Site-Server # The hub for all of the directory exchange agent (DXA) server # connections. # dn: CN=ms-Exch-DXA-Site-Server,${SCHEMADN} objectClass: top objectClass: classSchema cn: ms-Exch-DXA-Site-Server distinguishedName: CN=ms-Exch-DXA-Site-Server,${SCHEMADN} possSuperiors: container subClassOf: top governsID: 1.2.840.113556.1.3.60 mustContain: cn mayContain: versionNumber mayContain: assocRemoteDXA mayContain: responsibleLocalDXA mayContain: dXALocalAdmin mayContain: dXAAdminForward mayContain: dXAAdminCopy mayContain: activationStyle mayContain: activationSchedule rDNAttID: cn showInAdvancedViewOnly: TRUE adminDisplayName: ms-Exch-DXA-Site-Server adminDescription: ms-Exch-DXA-Site-Server auxiliaryClass: msExchBaseClass objectClassCategory: 1 lDAPDisplayName: dXASiteServer name: ms-Exch-DXA-Site-Server schemaIDGUID: a8df74b0-c5ea-11d1-bbcb-0080c76670c0 systemOnly: FALSE defaultSecurityDescriptor: D:S: defaultHidingValue: TRUE objectCategory: CN=Class-Schema,${SCHEMADN} defaultObjectCategory: CN=ms-Exch-DXA-Site-Server,${SCHEMADN} # # ms-Exch-Replication-Connector-Container # dn: CN=ms-Exch-Replication-Connector-Container,${SCHEMADN} objectClass: top objectClass: classSchema cn: ms-Exch-Replication-Connector-Container distinguishedName: CN=ms-Exch-Replication-Connector-Container,${SCHEMADN} possSuperiors: msExchAdminGroup subClassOf: container governsID: 1.2.840.113556.1.5.7000.62.12 rDNAttID: cn showInAdvancedViewOnly: TRUE adminDisplayName: ms-Exch-Replication-Connector-Container adminDescription: ms-Exch-Replication-Connector-Container auxiliaryClass: msExchBaseClass objectClassCategory: 1 lDAPDisplayName: msExchReplicationConnectorContainer name: ms-Exch-Replication-Connector-Container schemaIDGUID: 99f5867e-12e8-11d3-aa58-00c04f8eedd8 systemOnly: FALSE defaultSecurityDescriptor: D:S: defaultHidingValue: TRUE objectCategory: CN=Class-Schema,${SCHEMADN} defaultObjectCategory: CN=ms-Exch-Replication-Connector-Container,${SCHEMADN} # # ms-Exch-Routing-Group-Container # Container used to hold routing groups. # dn: CN=ms-Exch-Routing-Group-Container,${SCHEMADN} objectClass: top objectClass: classSchema cn: ms-Exch-Routing-Group-Container distinguishedName: CN=ms-Exch-Routing-Group-Container,${SCHEMADN} possSuperiors: msExchAdminGroup subClassOf: container governsID: 1.2.840.113556.1.5.7000.62.12001 mayContain: msExchMinAdminVersion rDNAttID: cn showInAdvancedViewOnly: TRUE adminDisplayName: ms-Exch-Routing-Group-Container adminDescription: ms-Exch-Routing-Group-Container auxiliaryClass: msExchBaseClass objectClassCategory: 1 lDAPDisplayName: msExchRoutingGroupContainer name: ms-Exch-Routing-Group-Container schemaIDGUID: 34de6b40-a982-11d2-a9ff-00c04f8eedd8 systemOnly: FALSE defaultSecurityDescriptor: D:S: defaultHidingValue: TRUE objectCategory: CN=Class-Schema,${SCHEMADN} defaultObjectCategory: CN=ms-Exch-Routing-Group-Container,${SCHEMADN} # # ms-Exch-Connectors # Container used to hold connection objects. # dn: CN=ms-Exch-Connectors,${SCHEMADN} objectClass: top objectClass: classSchema cn: ms-Exch-Connectors distinguishedName: CN=ms-Exch-Connectors,${SCHEMADN} #possSuperiors: msExchRoutingGroup subClassOf: container governsID: 1.2.840.113556.1.5.7000.62.12003 mayContain: msExchMinAdminVersion rDNAttID: cn showInAdvancedViewOnly: TRUE adminDisplayName: ms-Exch-Connectors adminDescription: ms-Exch-Connectors auxiliaryClass: msExchBaseClass objectClassCategory: 1 lDAPDisplayName: msExchConnectors name: ms-Exch-Connectors schemaIDGUID: eee325dc-a980-11d2-a9ff-00c04f8eedd8 systemOnly: FALSE defaultSecurityDescriptor: D:S: defaultHidingValue: TRUE objectCategory: CN=Class-Schema,${SCHEMADN} defaultObjectCategory: CN=ms-Exch-Connectors,${SCHEMADN} # # ms-Exch-Exchange-Admin-Service # The MAD process. # dn: CN=ms-Exch-Exchange-Admin-Service,${SCHEMADN} objectClass: top objectClass: classSchema cn: ms-Exch-Exchange-Admin-Service distinguishedName: CN=ms-Exch-Exchange-Admin-Service,${SCHEMADN} possSuperiors: msExchExchangeServer possSuperiors: container possSuperiors: computer subClassOf: top governsID: 1.2.840.113556.1.3.62 mustContain: deliveryMechanism mayContain: msExchMinAdminVersion mayContain: diagnosticRegKey rDNAttID: cn showInAdvancedViewOnly: TRUE adminDisplayName: ms-Exch-Exchange-Admin-Service adminDescription: ms-Exch-Exchange-Admin-Service auxiliaryClass: msExchBaseClass auxiliaryClass: msExchMailStorage auxiliaryClass: mailRecipient objectClassCategory: 1 lDAPDisplayName: exchangeAdminService name: ms-Exch-Exchange-Admin-Service schemaIDGUID: a8df74b2-c5ea-11d1-bbcb-0080c76670c0 systemOnly: FALSE defaultSecurityDescriptor: D:S: defaultHidingValue: TRUE objectCategory: CN=Class-Schema,${SCHEMADN} defaultObjectCategory: CN=ms-Exch-Exchange-Admin-Service,${SCHEMADN} # # ms-Exch-Message-Delivery-Config # dn: CN=ms-Exch-Message-Delivery-Config,${SCHEMADN} objectClass: top objectClass: classSchema cn: ms-Exch-Message-Delivery-Config distinguishedName: CN=ms-Exch-Message-Delivery-Config,${SCHEMADN} possSuperiors: container subClassOf: top governsID: 1.2.840.113556.1.5.7000.62.50028 mayContain: msExchMinAdminVersion mayContain: msExchTurfListAction mayContain: submissionContLength mayContain: msExchRecipLimit mayContain: msExchLocalDomains mayContain: delivContLength mayContain: msExchAdminMailbox rDNAttID: cn showInAdvancedViewOnly: TRUE adminDisplayName: ms-Exch-Message-Delivery-Config adminDescription: ms-Exch-Message-Delivery-Config auxiliaryClass: msExchBaseClass objectClassCategory: 1 lDAPDisplayName: msExchMessageDeliveryConfig name: ms-Exch-Message-Delivery-Config schemaIDGUID: ab3a1ad7-1df5-11d3-aa5e-00c04f8eedd8 systemOnly: FALSE defaultSecurityDescriptor: D:S: defaultHidingValue: TRUE objectCategory: CN=Class-Schema,${SCHEMADN} defaultObjectCategory: CN=ms-Exch-Message-Delivery-Config,${SCHEMADN} # # ms-Exch-Smtp-Connection-Turf-List # Contains the attributes for Accept and Deny Internet Protocol (IP) # lists. # dn: CN=ms-Exch-Smtp-Connection-Turf-List,${SCHEMADN} objectClass: top objectClass: classSchema cn: ms-Exch-Smtp-Connection-Turf-List distinguishedName: CN=ms-Exch-Smtp-Connection-Turf-List,${SCHEMADN} possSuperiors: msExchSMTPTurfList subClassOf: top governsID: 1.2.840.113556.1.5.7000.62.12010 mayContain: msExchSMTPGlobalIPDenyList mayContain: msExchSMTPGlobalIPAcceptList mayContain: msExchMinAdminVersion mayContain: msExchSmtpConnectionWhitelist mayContain: msExchSmtpConnectionRulesPriority rDNAttID: cn showInAdvancedViewOnly: TRUE adminDisplayName: ms-Exch-Smtp-Connection-Turf-List adminDescription: ms-Exch-Smtp-Connection-Turf-List objectClassCategory: 1 lDAPDisplayName: msExchSmtpConnectionTurfList name: ms-Exch-Smtp-Connection-Turf-List schemaIDGUID: 7eea7de9-319e-408a-8460-e35e2c9da389 systemOnly: FALSE defaultSecurityDescriptor: D:S: defaultHidingValue: TRUE objectCategory: CN=Class-Schema,${SCHEMADN} defaultObjectCategory: CN=ms-Exch-Smtp-Connection-Turf-List,${SCHEMADN} # # ms-Exch-CTP # An Exchange conference technology provider (CTP) # template. CN=Exchange Data Conferencing Service. # dn: CN=ms-Exch-CTP,${SCHEMADN} objectClass: top objectClass: classSchema cn: ms-Exch-CTP distinguishedName: CN=ms-Exch-CTP,${SCHEMADN} possSuperiors: msExchConferenceSite subClassOf: top governsID: 1.2.840.113556.1.5.7000.62.9002 mayContain: objectCount mayContain: msExchCTPSnapinGUID mayContain: msExchCTPRequireCMSAuthentication mayContain: msExchCTPProviderName mayContain: msExchCTPProviderGUID mayContain: msExchCTPPropertySchema mayContain: msExchCTPFrameHint mayContain: msExchCTPClassGUID rDNAttID: cn showInAdvancedViewOnly: TRUE adminDisplayName: ms-Exch-CTP adminDescription: ms-Exch-CTP auxiliaryClass: msExchBaseClass objectClassCategory: 1 lDAPDisplayName: msExchCTP name: ms-Exch-CTP schemaIDGUID: 00aa8efe-a981-11d2-a9ff-00c04f8eedd8 systemOnly: FALSE defaultSecurityDescriptor: D:S: defaultHidingValue: TRUE objectCategory: CN=Class-Schema,${SCHEMADN} defaultObjectCategory: CN=ms-Exch-CTP,${SCHEMADN} openchange-2.0/setup/AD/oc_provision_schema_modify.ldif000066400000000000000000000335411223057412600233560ustar00rootroot00000000000000# # ms-Exch-Configuration-Container class: see oc_provision_schema.ldif # dn: CN=Address-Book-Container,${SCHEMADN} changetype: modify add: mayContain mayContain: msExchMinAdminVersion mayContain: msExchAddressListOU mayContain: msExchSearchScope mayContain: msExchSearchBase mayContain: msExchEnableInternalEvaluator mayContain: msExchPurportedSearchUI add: possSuperiors possSuperiors: msExchConfigurationContainer possSuperiors: container # # Computer class # Represents a computer account in the domain # dn: CN=Computer,${SCHEMADN} changetype: modify add: mayContain mayContain: msExchExchangeServerLink mayContain: logRolloverInterval mayContain: monitoredConfigurations mayContain: monitoredServices mayContain: monitoringAvailabilityStyle mayContain: monitoringAvailabilityWindow mayContain: monitoringCachedViaMail mayContain: monitoringCachedViaRPC mayContain: monitoringMailUpdateInterval mayContain: monitoringMailUpdateUnits mayContain: monitoringRPCUpdateInterval mayContain: monitoringRPCUpdateUnits #mayContain: ms-Exch-Policy-List Attribute #mayContain: ms-Exch-Policy-Option-List Attribute mayContain: promoExpiration mayContain: securityProtocol mayContain: trackingLogPathName mayContain: type # # Container Class # Used to hold other classes dn: CN=Container,${SCHEMADN} changetype: modify add: auxiliaryClass auxiliaryClass: msExchBaseClass add: possSuperiors possSuperiors: protocolCfgSharedServer add: mayContain mayContain: containerInfo mayContain: msExchPolicyList mayContain: msExchTemplateRDNs mayContain: x500RDN mayContain: msExchExportContainersBL # # Domain-DNS # Windows NT domain with DNS-based (DC=) naming. # dn: CN=Domain-DNS,${SCHEMADN} changetype: modify add: mayContain mayContain: msExchPolicyList # # Group # Stores a list of user names. Used to apply security principals on # resources. # dn: CN=Group,${SCHEMADN} changetype: modify add: auxiliaryClass auxiliaryClass: msExchCustomAttributes auxiliaryClass: msExchBaseClass auxiliaryClass: msExchIMRecipient add: mayContain mayContain: hideDLMembership mayContain: oOFReplyToOriginator mayContain: reportToOriginator mayContain: reportToOwner mayContain: dLMemberRule mayContain: owner mayContain: msExchOriginatingForest # # Mail-Recipient # Stores e-mail configuration information. # dn: CN=Mail-Recipient,${SCHEMADN} changetype: modify add: mayContain mayContain: assistant mayContain: altRecipient mayContain: authOrig mayContain: autoReplyMessage mayContain: delivContLength mayContain: deliverAndRedirect mayContain: dLMemRejectPerms mayContain: dLMemSubmitPerms mayContain: enabledProtocols mayContain: msExchExpansionServerName mayContain: expirationTime mayContain: folderPathname mayContain: formData mayContain: forwardingAddress mayContain: homeMTA mayContain: internetEncoding mayContain: languageCode mayContain: language mayContain: mailNickname mayContain: mAPIRecipient mayContain: pOPCharacterSet mayContain: pOPContentFormat mayContain: protocolSettings mayContain: publicDelegates mayContain: replicationSensitivity mayContain: securityProtocol mayContain: submissionContLength mayContain: targetAddress mayContain: unauthOrig mayContain: dnQualifier mayContain: msExchMailboxSecurityDescriptor mayContain: msExchMasterAccountSid mayContain: importedFrom mayContain: versionNumber mayContain: msExchPreviousAccountSid mayContain: msExchCustomProxyAddresses mayContain: dLMemDefault mayContain: mail mayContain: deliveryMechanism mayContain: extensionData mayContain: delivExtContTypes mayContain: msExchFBURL mayContain: msExchRecipLimit mayContain: altRecipientBL mayContain: authOrigBL mayContain: dLMemRejectPermsBL mayContain: dLMemSubmitPermsBL mayContain: publicDelegatesBL mayContain: unauthOrigBL mayContain: msExchPoliciesExcluded mayContain: msExchPoliciesIncluded mayContain: msExchPolicyEnabled mayContain: msExchPolicyOptionList #dn: CN=Mail-Recipient,${SCHEMADN} #changetype: modify #add: mayContain #mayContain: msExchUserAccountControl #mayContain: msExchProxyCustomProxy #mayContain: msExchMailboxFolderSet #mayContain: msExchRequireAuthToSendTo # # NTDS-DSA # Represents the Active Directory DSA process on the server. # dn: CN=NTDS-DSA,${SCHEMADN} changetype: modify add: mayContain mayContain: deliveryMechanism mayContain: diagnosticRegKey # # Organizational-Person # Contains organizational information about a user. # dn: CN=Organizational-Person,${SCHEMADN} changetype: modify add: mayContain mayContain: employeeType mayContain: businessRoles mayContain: telephoneAssistant mayContain: personalPager mayContain: employeeNumber # # Organizational-Unit # A container for storing users, computers, and other account objects. # dn: CN=Organizational-Unit,${SCHEMADN} changetype: modify add: auxiliaryClass auxiliaryClass: msExchBaseClass add: mayContain mayContain: msExchPolicyList # # Sam-Domain # Auxiliary class holding common properties for Windows NT domains. # dn: CN=Sam-Domain,${SCHEMADN} changetype: modify add: mayContain mayContain: msExchAddGroupsToToken # # Server # Represents a server computer within a site. # dn: CN=Server,${SCHEMADN} changetype: modify add: mayContain mayContain: activationSchedule mayContain: activationStyle mayContain: type mayContain: networkAddress # # Site # A container for storing server objects. Represents a physical # location containing computers. Used to manage replication. # dn: CN=Site,${SCHEMADN} changetype: modify add: mayContain mayContain: msExchConferenceZoneBL mayContain: msExchMCUHostsSitesBL # # User # Used to store information about an employee or contractor who works # for an organization. Can also be applied to long-term visitors. # dn: CN=User,${SCHEMADN} changetype: modify add: auxiliaryClass auxiliaryClass: msExchCustomAttributes auxiliaryClass: msExchMailStorage auxiliaryClass: msExchBaseClass auxiliaryClass: msExchMultiMediaUser auxiliaryClass: msExchCertificateInformation auxiliaryClass: msExchIMRecipient auxiliaryClass: msExchOmaUser add: possSuperiors possSuperiors: msExchSystemObjectsContainer add: mayContain mayContain: msExchQueryBaseDN mayContain: msExchControllingZone mayContain: msExchResourceGUID mayContain: msExchResourceProperties mayContain: msExchConferenceMailboxBL mayContain: kMServer mayContain: msExchIMAPOWAURLPrefixOverride mayContain: msExchOriginatingForest ################################################################## # Attributes ################################################################## # # Address # The user's address # dn: CN=Address,${SCHEMADN} changetype: modify add: isMemberOfPartialAttributeSet isMemberOfPartialAttributeSet: TRUE # # Admin-Display-Name # The name to be displayed on administrator screens. # dn: CN=Admin-Display-Name,${SCHEMADN} changetype: modify add: isMemberOfPartialAttributeSet isMemberOfPartialAttributeSet: TRUE # # Attribute-Syntax # The object identifier (OID) for the syntax for this attribute. # dn: CN=Attribute-Syntax,${SCHEMADN} changetype: modify add: isMemberOfPartialAttributeSet isMemberOfPartialAttributeSet: TRUE # # Comment # The user's comments. Can be a null string. # dn: CN=Comment,${SCHEMADN} changetype: modify add: isMemberOfPartialAttributeSet isMemberOfPartialAttributeSet: TRUE # # Company # The user's company name. # dn: CN=Company,${SCHEMADN} changetype: modify add: isMemberOfPartialAttributeSet isMemberOfPartialAttributeSet: TRUE # # Department # Contains the name for the department in which the user works. # dn: CN=Department,${SCHEMADN} changetype: modify add: isMemberOfPartialAttributeSet isMemberOfPartialAttributeSet: TRUE # # Display-Name-Printable # The name displayed in the address book for a particular # user. Usually the combination of the user's first name, middle # initial, and last name. # dn: CN=Display-Name-Printable,${SCHEMADN} changetype: modify add: isMemberOfPartialAttributeSet isMemberOfPartialAttributeSet: TRUE # # E-mail-Addresses # The list of e-mail addresses for a contact. # dn: CN=E-mail-Addresses,${SCHEMADN} changetype: modify replace: searchFlags searchFlags: 5 # # Facsimile-Telephone-Number # Contains the telephone number of the user's business fax machine. # dn: CN=Facsimile-Telephone-Number,${SCHEMADN} changetype: modify add: isMemberOfPartialAttributeSet isMemberOfPartialAttributeSet: TRUE # # Garbage-Coll-Period # Located on the CN=Directory Service,CN=Windows # NT,CN=Services,CN=Configuration,... object. Represents the period in # hours between Directory Service (DS) garbage collection runs. # dn: CN=Garbage-Coll-Period,${SCHEMADN} changetype: modify add: isMemberOfPartialAttributeSet isMemberOfPartialAttributeSet: TRUE replace: searchFlags searchFlags: 16 # # Given-Name # Contains the given name (first name) of the user. # #dn: CN=Given-Name,${SCHEMADN} #changetype: modify #add: isMemberOfPartialAttributeSet #isMemberOfPartialAttributeSet: TRUE # # Initials # Contains the initials for parts of the user's full name. May be used # as the middle initial in the Windows Address Book. # dn: CN=Initials,${SCHEMADN} changetype: modify add: isMemberOfPartialAttributeSet isMemberOfPartialAttributeSet: TRUE # # Managed-By # The distinguished name of the user that is assigned to manage this # object. # dn: CN=Managed-By,${SCHEMADN} changetype: modify add: isMemberOfPartialAttributeSet isMemberOfPartialAttributeSet: TRUE # # Network-Address # The TCP/IP address for a network segment. Also called the subnet # address. # dn: CN=Network-Address,${SCHEMADN} changetype: modify add: isMemberOfPartialAttributeSet isMemberOfPartialAttributeSet: TRUE # # NT-Mixed-Domain # Indicates that the domain is in native mode or mixed mode. Found in # the domainDNS (head) object for the domain. # dn: CN=NT-Mixed-Domain,${SCHEMADN} changetype: modify add: isMemberOfPartialAttributeSet isMemberOfPartialAttributeSet: TRUE # # OM-Syntax # A number representing the OM type for the attribute. # dn: CN=OM-Syntax,${SCHEMADN} changetype: modify add: isMemberOfPartialAttributeSet isMemberOfPartialAttributeSet: TRUE # # Phone-Fax-Other # A list of alternate facsimile numbers. # dn: CN=Phone-Fax-Other,${SCHEMADN} changetype: modify add: isMemberOfPartialAttributeSet isMemberOfPartialAttributeSet: TRUE # # Phone-Home-Other # A list of alternate home phone numbers. # dn: CN=Phone-Home-Other,${SCHEMADN} changetype: modify add: isMemberOfPartialAttributeSet isMemberOfPartialAttributeSet: TRUE # # Phone-Mobile-Other # A list of alternate cell phone numbers. # dn: CN=Phone-Mobile-Other,${SCHEMADN} changetype: modify add: isMemberOfPartialAttributeSet isMemberOfPartialAttributeSet: TRUE # # Phone-Mobile-Primary # The primary cell phone number # dn: CN=Phone-Mobile-Primary,${SCHEMADN} changetype: modify add: isMemberOfPartialAttributeSet isMemberOfPartialAttributeSet: TRUE # # Phone-Office-Other # A list of alternate office phone numbers # dn: CN=Phone-Office-Other,${SCHEMADN} changetype: modify add: isMemberOfPartialAttributeSet isMemberOfPartialAttributeSet: TRUE # # Phone-Pager-Other # A list of alternate pager numbers # dn: CN=Phone-Pager-Other,${SCHEMADN} changetype: modify add: isMemberOfPartialAttributeSet isMemberOfPartialAttributeSet: TRUE # # Phone-Pager-Primary # The primary pager number # dn: CN=Phone-Pager-Primary,${SCHEMADN} changetype: modify add: isMemberOfPartialAttributeSet isMemberOfPartialAttributeSet: TRUE # # Physical-Delivery-Office-Name # Contains the office location of the user's place of business. # dn: CN=Physical-Delivery-Office-Name,${SCHEMADN} changetype: modify add: isMemberOfPartialAttributeSet isMemberOfPartialAttributeSet: TRUE # # Postal-Code # The postal or zip code for mail delivery. # dn: CN=Postal-Code,${SCHEMADN} changetype: modify add: isMemberOfPartialAttributeSet isMemberOfPartialAttributeSet: TRUE # # Post-Office-Box # The post office box number for this object. # dn: CN=Post-Office-Box,${SCHEMADN} changetype: modify add: isMemberOfPartialAttributeSet isMemberOfPartialAttributeSet: TRUE # # Proxy-Addresses # Address by which a Microsoft Exchange Server recipient object is # recognized in a foreign mail system. Required not just for users, # but for all recipient objects such as custom recipients and # distribution lists. # dn: CN=Proxy-Addresses,${SCHEMADN} changetype: modify add: isMemberOfPartialAttributeSet isMemberOfPartialAttributeSet: TRUE replace: searchFlags searchFlags: 13 # # Show-In-Address-Book # dn: CN=Show-In-Address-Book,${SCHEMADN} changetype: modify add: isMemberOfPartialAttributeSet isMemberOfPartialAttributeSet: TRUE # # Sub-Class-Of # The parent class of a class # dn: CN=Sub-Class-Of,${SCHEMADN} changetype: modify add: isMemberOfPartialAttributeSet isMemberOfPartialAttributeSet: TRUE # # Text-Country # The country/region in which the user is located. # dn: CN=Text-Country,${SCHEMADN} changetype: modify add: isMemberOfPartialAttributeSet isMemberOfPartialAttributeSet: TRUE # # Text-Encoded-Or-Address # dn: CN=Text-Encoded-Or-Address,${SCHEMADN} changetype: modify add: isMemberOfPartialAttributeSet isMemberOfPartialAttributeSet: TRUE replace: searchFlags searchFlags: 1 replace: attributeSecurityGuid attributeSecurityGuid: e48d0154-bcf8-11d1-8702-00c04fb96050 # # Title # Contains the user's job title. Property commonly used to indicate # the formal job title, such as Senior Programmer, rather than # occupational class, such as programmer. Not typically used for # suffix titles such as Esq. or D.D.S. # dn: CN=Title,${SCHEMADN} changetype: modify add: isMemberOfPartialAttributeSet isMemberOfPartialAttributeSet: TRUE replace: searchFlags searchFlags: 16 # # Version-Number # A general-purpose version number. # dn: CN=Version-Number,${SCHEMADN} changetype: modify replace: searchFlags searchFlags: 8 # # WWW-Home-Page # The primary Web page # dn: CN=WWW-Home-Page,${SCHEMADN} changetype: modify add: isMemberOfPartialAttributeSet isMemberOfPartialAttributeSet: TRUE # # WWW-Page-Other # A list of alternate Web pages # dn: CN=WWW-Page-Other,${SCHEMADN} changetype: modify add: isMemberOfPartialAttributeSet isMemberOfPartialAttributeSet: TRUE openchange-2.0/setup/AD/oc_provision_schema_objectCategory.ldif000066400000000000000000000223631223057412600250330ustar00rootroot00000000000000############################################################################## # objectCategory added ############################################################################## # # ms-Exch-Admin-Group # objectCategory for cn=First Administrative Group # description: An administrative group. # dn: CN=ms-Exch-Admin-Group,${SCHEMADN} objectClass: top objectClass: classSchema cn: ms-Exch-Admin-Group distinguishedName: CN=ms-Exch-Admin-Group,${SCHEMADN} #possSuperiors: msExchAdminGroupContainer subClassOf: top governsID: 1.2.840.113556.1.5.7000.62.50011 mayContain: msExchMinAdminVersion mayContain: domainDefAltRecip mayContain: msExchPfCreation mayContain: msExchEncryptedPassword mayContain: msExchAdmins mayContain: msExchPFDefaultAdminACL mayContain: msExchLegacyPW mayContain: msExchLegacyDomain mayContain: msExchLegacyAccount mayContain: siteFolderServer mayContain: siteFolderGUID mayContain: msExchDefaultAdminGroup mayContain: msExchAdminGroupMode rDNAttID: cn showInAdvancedViewOnly: TRUE adminDisplayName: ms-Exch-Admin-Group adminDescription: ms-Exch-Admin-Group auxiliaryClass: msExchBaseClass objectClassCategory: 1 lDAPDisplayName: msExchAdminGroup name: ms-Exch-Admin-Group schemaIDGUID: e768a58e-a980-11d2-a9ff-00c04f8eedd8 systemOnly: FALSE defaultSecurityDescriptor: D:S: defaultHidingValue: TRUE objectCategory: CN=Class-Schema,${SCHEMADN} defaultObjectCategory: CN=ms-Exch-Admin-Group,${SCHEMADN} # # ms-Exch-Exchange-Server # A representation of an Exchange server object. # dn: CN=ms-Exch-Exchange-Server,${SCHEMADN} objectClass: top objectClass: classSchema cn: ms-Exch-Exchange-Server distinguishedName: CN=ms-Exch-Exchange-Server,${SCHEMADN} #possSuperiors: msExchServersContainer subClassOf: server governsID: 1.2.840.113556.1.5.7000.62.50009 mayContain: msExchMinAdminVersion mayContain: msExchFolderAffinityList mayContain: msExchFolderAffinityCustom mayContain: msExchHomeRoutingGroupDNBL mayContain: msExchHomeRoutingGroup mayContain: msExchVPIMConvertOutbound mayContain: msExchVPIMConvertInbound mayContain: msExchServerPublicKey mayContain: msExchMonitoringResources mayContain: msExchMonitoringPollingRate mayContain: msExchMonitoringNotificationRate mayContain: msExchMonitoringMode mayContain: msExchMailboxManagerReportRecipient mayContain: msExchMailboxManagerAdminMode mayContain: msExchMailboxManagerActivationStyle mayContain: msExchMailboxManagerActivationSchedule mayContain: msExchResponsibleMTAServer mayContain: msExchPolicyOptionList mayContain: msExchPolicyList mayContain: msExchMonitoringResponses mayContain: msExchMonitoringQueuePollingInterval mayContain: msExchMonitoringQueuePollingFrequency mayContain: msExchMonitoringMonitoredServices mayContain: msExchMonitoringDiskSpace mayContain: monitoredServices mayContain: msExchInstalledComponents mayContain: msExchDataPath mayContain: msExchServerRole mayContain: msExchMessageTrackLogFilter mayContain: versionNumber mayContain: serverRole mayContain: serialNumber mayContain: msExchTrkLogCleaningInterval mayContain: messageTrackingEnabled mayContain: msExchLocales mayContain: msExchInstallPath mayContain: heuristics mayContain: msExchComputerLink mayContain: msExchAddressListServiceBL rDNAttID: cn showInAdvancedViewOnly: TRUE adminDisplayName: ms-Exch-Exchange-Server adminDescription: ms-Exch-Exchange-Server auxiliaryClass: msExchBaseClass objectClassCategory: 1 lDAPDisplayName: msExchExchangeServer name: ms-Exch-Exchange-Server schemaIDGUID: 01a9aa9c-a981-11d2-a9ff-00c04f8eedd8 systemOnly: FALSE defaultSecurityDescriptor: D:(A;;RP;;;AU) defaultHidingValue: TRUE objectCategory: CN=Class-Schema,${SCHEMADN} defaultObjectCategory: CN=ms-Exch-Exchange-Server,${SCHEMADN} # # ms-Exch-Protocol-Cfg-Shared # dn: CN=ms-Exch-Protocol-Cfg-Shared,${SCHEMADN} objectClass: top objectClass: classSchema cn: ms-Exch-Protocol-Cfg-Shared distinguishedName: CN=ms-Exch-Protocol-Cfg-Shared,${SCHEMADN} instanceType: 4 possSuperiors: container possSuperiors: computer subClassOf: top governsID: 1.2.840.113556.1.3.65 mustContain: cn mayContain: msExchMinAdminVersion mayContain: useSiteValues mayContain: oWAServer mayContain: formData mayContain: folderPathname mayContain: connectionListFilterType mayContain: connectionListFilter mayContain: characterSetList mayContain: availableAuthorizationPackages mayContain: helpData32 rDNAttID: cn showInAdvancedViewOnly: TRUE adminDisplayName: ms-Exch-Protocol-Cfg-Shared adminDescription: ms-Exch-Protocol-Cfg-Shared auxiliaryClass: msExchBaseClass objectClassCategory: 1 lDAPDisplayName: protocolCfgShared name: ms-Exch-Protocol-Cfg-Shared schemaIDGUID: a8df74d0-c5ea-11d1-bbcb-0080c76670c0 systemOnly: FALSE defaultSecurityDescriptor: D:S: defaultHidingValue: TRUE objectCategory: CN=Class-Schema,${SCHEMADN} defaultObjectCategory: CN=ms-Exch-Protocol-Cfg-Shared,${SCHEMADN} # # ms-Exch-Connector # dn: CN=ms-Exch-Connector,${SCHEMADN} objectClass: top objectClass: classSchema cn: ms-Exch-Connector distinguishedName: CN=ms-Exch-Connector,${SCHEMADN} #possSuperiors: msExchConnectors subClassOf: top governsID: 1.2.840.113556.1.5.7000.62.12004 mayContain: msExchMinAdminVersion mayContain: msExchInconsistentState mayContain: delivContLength mayContain: msExchNoPFConnection mayContain: versionNumber mayContain: msExchMasterAccountSid mayContain: msExchMailboxSecurityDescriptor mayContain: msExchMailboxGuid mayContain: msExchRoutingDisallowPriority mayContain: unauthOrig mayContain: msExchTargetBridgeheadServersDN mayContain: msExchSourceBridgeheadServersDN mayContain: msExchRoutingTriggeredStyle mayContain: msExchRoutingTriggeredSchedule mayContain: msExchRoutingOversizedStyle mayContain: msExchRoutingOversizedSchedule mayContain: routingList mayContain: messageSizeLimit mayContain: dLMemSubmitPerms mayContain: dLMemRejectPerms mayContain: dLMemDefault mayContain: msExchDestinationRGDN mayContain: msExchConnectorType mayContain: connectedDomains mayContain: authOrig mayContain: activationStyle mayContain: activationSchedule rDNAttID: cn showInAdvancedViewOnly: TRUE adminDisplayName: ms-Exch-Connector adminDescription: ms-Exch-Connector auxiliaryClass: msExchBaseClass objectClassCategory: 1 lDAPDisplayName: msExchConnector name: ms-Exch-Connector schemaIDGUID: 89652316-b09e-11d2-aa06-00c04f8eedd8 systemOnly: FALSE defaultSecurityDescriptor: D:S: defaultHidingValue: TRUE objectCategory: CN=Class-Schema,${SCHEMADN} defaultObjectCategory: CN=ms-Exch-Connector,${SCHEMADN} # # ms-Exch-Generic-Policy # dn: CN=ms-Exch-Generic-Policy,${SCHEMADN} objectClass: top objectClass: classSchema cn: ms-Exch-Generic-Policy distinguishedName: CN=ms-Exch-Generic-Policy,${SCHEMADN} subClassOf: top governsID: 1.2.840.113556.1.5.7000.62.50022 mayContain: purportedSearch mayContain: msExchPurportedSearchUI rDNAttID: cn showInAdvancedViewOnly: TRUE adminDisplayName: ms-Exch-Generic-Policy adminDescription: ms-Exch-Generic-Policy auxiliaryClass: msExchBaseClass objectClassCategory: 1 lDAPDisplayName: msExchGenericPolicy name: ms-Exch-Generic-Policy schemaIDGUID: e32977cd-1d31-11d3-aa5e-00c04f8eedd8 systemOnly: FALSE defaultSecurityDescriptor: D:S: defaultHidingValue: TRUE objectCategory: CN=Class-Schema,${SCHEMADN} defaultObjectCategory: CN=ms-Exch-Generic-Policy,${SCHEMADN} # # ms-Exch-SMTP-Turf-List # dn: CN=ms-Exch-SMTP-Turf-List,${SCHEMADN} objectClass: top objectClass: classSchema cn: ms-Exch-SMTP-Turf-List distinguishedName: CN=ms-Exch-SMTP-Turf-List,${SCHEMADN} #possSuperiors: msExchMessageDeliveryConfig subClassOf: top governsID: 1.2.840.113556.1.5.7000.62.12009 mayContain: msExchMinAdminVersion mayContain: msExchRecipTurfListOptions mayContain: msExchRecipTurfListNames mayContain: msExchTurfListOptions mayContain: versionNumber mayContain: msExchTurfListNames rDNAttID: cn showInAdvancedViewOnly: TRUE adminDisplayName: ms-Exch-SMTP-Turf-List adminDescription: ms-Exch-SMTP-Turf-List auxiliaryClass: msExchBaseClass objectClassCategory: 1 lDAPDisplayName: msExchSMTPTurfList name: ms-Exch-SMTP-Turf-List schemaIDGUID: 0b836da5-3b20-11d3-aa6f-00c04f8eedd8 systemOnly: FALSE defaultSecurityDescriptor: D:S: defaultHidingValue: TRUE objectCategory: CN=Class-Schema,${SCHEMADN} defaultObjectCategory: CN=ms-Exch-SMTP-Turf-List,${SCHEMADN} # # ms-Exch-Conference-Site # An Exchange Conferencing-Zone Configuration Interface Class. # dn: CN=ms-Exch-Conference-Site,${SCHEMADN} objectClass: top objectClass: classSchema cn: ms-Exch-Conference-Site distinguishedName: CN=ms-Exch-Conference-Site,${SCHEMADN} #possSuperiors: msExchConferenceContainer subClassOf: top governsID: 1.2.840.113556.1.5.7000.62.9001 mayContain: msExchConferenceMailbox mayContain: msExchConferenceZone mayContain: displayName mayContain: wWWHomePage mayContain: serverName mayContain: objectCount mayContain: msExchGracePeriodPrior mayContain: msExchGracePeriodAfter mayContain: msExchAvailableServers mayContain: msExchAuditFlags mayContain: msExchAllowTimeExtensions mayContain: msExchAllowAdditionalResources rDNAttID: cn showInAdvancedViewOnly: TRUE adminDisplayName: ms-Exch-Conference-Site adminDescription: ms-Exch-Conference-Site auxiliaryClass: msExchBaseClass objectClassCategory: 1 lDAPDisplayName: msExchConferenceSite name: ms-Exch-Conference-Site schemaIDGUID: eddce330-a980-11d2-a9ff-00c04f8eedd8 systemOnly: FALSE defaultSecurityDescriptor: D:S: defaultHidingValue: TRUE objectCategory: CN=Class-Schema,${SCHEMADN} defaultObjectCategory: CN=ms-Exch-Conference-Site,${SCHEMADN}openchange-2.0/setup/AD/oc_provision_schema_possSuperior.ldif000066400000000000000000000034341223057412600246020ustar00rootroot00000000000000dn: CN=ms-Exch-Admin-Group,${SCHEMADN} changetype: modify add: possSuperiors possSuperiors: msExchAdminGroupContainer dn: CN=ms-Exch-Exchange-Server,${SCHEMADN} changetype: modify add: possSuperiors possSuperiors: msExchServersContainer dn: CN=ms-Exch-Connector,${SCHEMADN} changetype: modify add: possSuperiors possSuperiors: msExchConnectors dn: CN=ms-Exch-SMTP-Turf-List,${SCHEMADN} changetype: modify add: possSuperiors possSuperiors: msExchMessageDeliveryConfig dn: CN=ms-Exch-Conference-Site,${SCHEMADN} changetype: modify add: possSuperiors possSuperiors: msExchConferenceContainer dn: CN=ms-Exch-Protocol-Cfg-Shared-Container,${SCHEMADN} changetype: modify add: possSuperiors possSuperiors: protocolCfgSharedServer dn: CN=ms-Exch-Protocol-Cfg-Protocol-Container,${SCHEMADN} changetype: modify add: possSuperiors possSuperiors: protocolCfgSharedServer dn: CN=ms-Exch-MDB,${SCHEMADN} changetype: modify add: possSuperiors possSuperiors: msExchStorageGroup dn: CN=ms-Exch-Connectors,${SCHEMADN} changetype: modify add: possSuperiors possSuperiors: msExchRoutingGroup dn: CN=ms-Exch-Protocol-Cfg-SMTP-Domain-Container,${SCHEMADN} changetype: modify add: possSuperiors possSuperiors: protocolCfgSMTPServer dn: CN=ms-Exch-Protocol-Cfg-SMTP-IP-Address-Container,${SCHEMADN} changetype: modify add: possSuperiors possSuperiors: protocolCfgSMTPServer dn: CN=ms-Exch-Chat-Ban,${SCHEMADN} changetype: modify add: possSuperiors possSuperiors: msExchChatVirtualNetwork dn: CN=ms-Exch-Chat-Channel,${SCHEMADN} changetype: modify add: possSuperiors possSuperiors: msExchChatVirtualNetwork dn: CN=ms-Exch-Chat-User-Class,${SCHEMADN} changetype: modify add: possSuperiors possSuperiors: msExchChatVirtualNetwork dn: CN=ms-Exch-MCU,${SCHEMADN} changetype: modify add: possSuperiors possSuperiors: msExchMCUContainer openchange-2.0/setup/AD/oc_provision_schema_sub_CfgProtocol.ldif000066400000000000000000000145451223057412600251640ustar00rootroot00000000000000# # ms-Exch-Protocol-Cfg-HTTP-Server # The Exchange HTTP virtual server configuration. # dn: CN=ms-Exch-Protocol-Cfg-HTTP-Server,${SCHEMADN} objectClass: top objectClass: classSchema cn: ms-Exch-Protocol-Cfg-HTTP-Server distinguishedName: CN=ms-Exch-Protocol-Cfg-HTTP-Server,${SCHEMADN} possSuperiors: msExchProtocolCfgHTTPContainer subClassOf: protocolCfgHTTP governsID: 1.2.840.113556.1.3.80 mayContain: msExchEncryptedAnonymousPassword mayContain: msExchDefaultLoadFile mayContain: msExchAuthorizationPersistence mayContain: msExchServerAutoStart mayContain: msExchServerRole mayContain: msExchDiscussionFolder mayContain: msExchDefaultDomain mayContain: msExchUNCUsername mayContain: msExchUNCPassword mayContain: msExchServerBindings mayContain: msExchSecureBindings mayContain: msExchMaxIncomingConnections mayContain: msExchLogonMethod mayContain: msExchLogType mayContain: msExchIncomingConnectionTimeout mayContain: folderPathname mayContain: msExchDirBrowseFlags mayContain: msExchDefaultLogonDomain mayContain: msExchBasicAuthenticationDomain mayContain: msExchAuthenticationFlags mayContain: anonymousAccount mayContain: msExchAccessFlags rDNAttID: cn showInAdvancedViewOnly: TRUE adminDisplayName: ms-Exch-Protocol-Cfg-HTTP-Server adminDescription: ms-Exch-Protocol-Cfg-HTTP-Server auxiliaryClass: msExchBaseClass objectClassCategory: 1 lDAPDisplayName: protocolCfgHTTPServer name: ms-Exch-Protocol-Cfg-HTTP-Server schemaIDGUID: a8df74c2-c5ea-11d1-bbcb-0080c76670c0 systemOnly: FALSE defaultSecurityDescriptor: D:S: defaultHidingValue: TRUE objectCategory: CN=Class-Schema,${SCHEMADN} defaultObjectCategory: CN=ms-Exch-Protocol-Cfg-HTTP-Server,${SCHEMADN} # # ms-Exch-Protocol-Cfg-SMTP-Server # Contains the settings for an SMTP virtual server. # dn: CN=ms-Exch-Protocol-Cfg-SMTP-Server,${SCHEMADN} objectClass: top objectClass: classSchema cn: ms-Exch-Protocol-Cfg-SMTP-Server distinguishedName: CN=ms-Exch-Protocol-Cfg-SMTP-Server,${SCHEMADN} possSuperiors: msExchProtocolCfgSMTPContainer subClassOf: protocolCfgSMTP governsID: 1.2.840.113556.1.5.7000.62.5002 mayContain: msExchSubmitRelaySD mayContain: msExchServerBindingsFiltering mayContain: msExchAuthMailDisposition mayContain: msExchSmtpExternalDNSServers mayContain: msExchEncryptedPassword mayContain: msExchAppliesToSmtpVSBL mayContain: msExchSmtpEnableVRFY mayContain: msExchSmtpEnableEXPN mayContain: msExchServerBindingsTurflist mayContain: msExchSecurityPassword mayContain: msExchAlternateServer mayContain: msExchSmtpSmartHostType mayContain: msExchSmtpSmartHost mayContain: msExchSmtpSendNDRTo mayContain: msExchSmtpSendBadmailTo mayContain: msExchSmtpRemoteQueueRetries mayContain: msExchSmtpRemoteQueueExpirationTimeout mayContain: msExchSmtpRemoteQueueDelayNotification mayContain: msExchSmtpRelayIpList mayContain: msExchSmtpRelayForAuth mayContain: msExchSmtpQueueDirectory mayContain: msExchSmtpPickupDirectory mayContain: msExchSmtpPerformReverseDnsLookup mayContain: msExchSmtpOutgoingSecurePort mayContain: msExchSmtpOutgoingPort mayContain: msExchSmtpOutgoingConnectionTimeout mayContain: msExchSmtpOutboundSecurityUserName mayContain: msExchSmtpOutboundSecurityPassword mayContain: msExchSmtpOutboundSecurityFlag mayContain: msExchSmtpMaxSessionSize mayContain: msExchSmtpMaxRecipients mayContain: msExchSmtpMaxOutgoingConnectionsPerDomain mayContain: msExchSmtpMaxOutgoingConnections mayContain: msExchSmtpMaxOutboundMsgPerDomainFlag mayContain: msExchSmtpMaxOutboundMsgPerDomain mayContain: msExchSmtpMaxMessageSize mayContain: msExchSmtpMaxHopCount mayContain: msExchSmtpMasqueradeDomain mayContain: msExchSmtpLocalQueueExpirationTimeout mayContain: msExchSmtpLocalQueueDelayNotification mayContain: msExchSmtpInboundCommandSupportOptions mayContain: msExchSmtpFullyQualifiedDomainName mayContain: msExchSmtpDropDirectory mayContain: msExchSmtpDoMasquerade mayContain: msExchSmtpBadMailDirectory mayContain: msExchServerBindings mayContain: msExchServerAutoStart mayContain: msExchSecureBindings mayContain: msExchSaslLogonDomain mayContain: msExchNTAuthenticationProviders mayContain: msExchMaxIncomingConnections mayContain: msExchLogType mayContain: msExchIPSecurity mayContain: msExchIncomingConnectionTimeout mayContain: msExchHomeRoutingGroupDNBL mayContain: msExchDefaultDomain mayContain: msExchBridgeheadedRemoteConnectorsDNBL mayContain: msExchBridgeheadedLocalConnectorsDNBL mayContain: msExchAuthenticationFlags mayContain: msExchAdminACL mayContain: msExchAccessSSLFlags mayContain: msExchAccessFlags rDNAttID: cn showInAdvancedViewOnly: TRUE adminDisplayName: ms-Exch-Protocol-Cfg-SMTP-Server adminDescription: ms-Exch-Protocol-Cfg-SMTP-Server auxiliaryClass: msExchBaseClass objectClassCategory: 1 lDAPDisplayName: protocolCfgSMTPServer name: ms-Exch-Protocol-Cfg-SMTP-Server schemaIDGUID: 3378ca84-a982-11d2-a9ff-00c04f8eedd8 systemOnly: FALSE defaultSecurityDescriptor: D:S: defaultHidingValue: TRUE objectCategory: CN=Class-Schema,${SCHEMADN} defaultObjectCategory: CN=ms-Exch-Protocol-Cfg-SMTP-Server,${SCHEMADN} # # ms-Exch-Protocol-Cfg-IMAP-Server # dn: CN=ms-Exch-Protocol-Cfg-IMAP-Server,${SCHEMADN} objectClass: top objectClass: classSchema cn: ms-Exch-Protocol-Cfg-IMAP-Server distinguishedName: CN=ms-Exch-Protocol-Cfg-IMAP-Server,${SCHEMADN} possSuperiors: msExchProtocolCfgIMAPContainer subClassOf: protocolCfgIMAP governsID: 1.2.840.113556.1.3.85 mayContain: msExchOtherAuthenticationFlags mayContain: msExchServerRole mayContain: msExchDefaultLogonDomain mayContain: msExchServerBindings mayContain: msExchServerAutoStart mayContain: msExchSecureBindings mayContain: msExchNTAuthenticationProviders mayContain: msExchMaxIncomingConnections mayContain: msExchLogType mayContain: msExchIPSecurity mayContain: msExchIncomingConnectionTimeout mayContain: msExchDefaultDomain mayContain: msExchBasicAuthenticationDomain mayContain: msExchAuthenticationFlags mayContain: msExchAdminACL mayContain: msExchAccessSSLFlags mayContain: msExchAccessFlags rDNAttID: cn showInAdvancedViewOnly: TRUE adminDisplayName: ms-Exch-Protocol-Cfg-IMAP-Server adminDescription: ms-Exch-Protocol-Cfg-IMAP-Server auxiliaryClass: msExchBaseClass objectClassCategory: 1 lDAPDisplayName: protocolCfgIMAPServer name: ms-Exch-Protocol-Cfg-IMAP-Server schemaIDGUID: a8df74c5-c5ea-11d1-bbcb-0080c76670c0 systemOnly: FALSE defaultSecurityDescriptor: D:S: defaultHidingValue: TRUE objectCategory: CN=Class-Schema,${SCHEMADN} defaultObjectCategory: CN=ms-Exch-Protocol-Cfg-IMAP-Server,${SCHEMADN} openchange-2.0/setup/AD/oc_provision_schema_sub_mailGateway.ldif000066400000000000000000000245501223057412600252040ustar00rootroot00000000000000# # ms-Exch-ccMail-Connector # The ccMail connector # dn: CN=ms-Exch-ccMail-Connector,${SCHEMADN} objectClass: top objectClass: classSchema cn: ms-Exch-ccMail-Connector distinguishedName: CN=ms-Exch-ccMail-Connector,${SCHEMADN} possSuperiors: container subClassOf: mailGateway governsID: 1.2.840.113556.1.5.7000.62.1001 mayContain: msExchccMailPassword mayContain: msExchccMailConnectAsUserid mayContain: msExchccMailConnectAsPassword mayContain: objViewContainers mayContain: msExchccMailPOPath mayContain: msExchccMailPOName #mayContain: msExchccMailKeepForwardHistory #mayContain: msExchccMailImportExportVersion #mayContain: msExchccMailFilterType mayContain: msExchccMailADEProp rDNAttID: cn showInAdvancedViewOnly: TRUE adminDisplayName: ms-Exch-ccMail-Connector adminDescription: ms-Exch-ccMail-Connector auxiliaryClass: msExchBaseClass objectClassCategory: 1 lDAPDisplayName: msExchccMailConnector name: ms-Exch-ccMail-Connector schemaIDGUID: e85710b6-a980-11d2-a9ff-00c04f8eedd8 systemOnly: FALSE defaultSecurityDescriptor: D:S: defaultHidingValue: TRUE objectCategory: CN=Class-Schema,${SCHEMADN} defaultObjectCategory: CN=ms-Exch-ccMail-Connector,${SCHEMADN} # # ms-Exch-Calendar-Connector # The calendar connector # dn: CN=ms-Exch-Calendar-Connector,${SCHEMADN} objectClass: top objectClass: classSchema cn: ms-Exch-Calendar-Connector distinguishedName: CN=ms-Exch-Calendar-Connector,${SCHEMADN} possSuperiors: container subClassOf: mailGateway governsID: 1.2.840.113556.1.5.7000.62.1007 mayContain: msExchNotesNotesServer mayContain: msExchNotesNotesINI mayContain: msExchEncryptedPassword mayContain: msExchGWiseAPIGateway mayContain: msExchCalConTargetSiteDN mayContain: msExchCalConRefreshInterval mayContain: msExchCalConQueryWindow mayContain: msExchCalConProviders mayContain: msExchCalConClientWait rDNAttID: cn showInAdvancedViewOnly: TRUE adminDisplayName: ms-Exch-Calendar-Connector adminDescription: ms-Exch-Calendar-Connector auxiliaryClass: msExchBaseClass objectClassCategory: 1 lDAPDisplayName: msExchCalendarConnector name: ms-Exch-Calendar-Connector schemaIDGUID: 922180da-b09e-11d2-aa06-00c04f8eedd8 systemOnly: FALSE defaultSecurityDescriptor: D:S: defaultHidingValue: TRUE objectCategory: CN=Class-Schema,${SCHEMADN} defaultObjectCategory: CN=ms-Exch-Calendar-Connector,${SCHEMADN} # # ms-Exch-GroupWise-Connector # The GroupWise Connector. # dn: CN=ms-Exch-GroupWise-Connector,${SCHEMADN} objectClass: top objectClass: classSchema cn: ms-Exch-GroupWise-Connector distinguishedName: CN=ms-Exch-GroupWise-Connector,${SCHEMADN} possSuperiors: container subClassOf: mailGateway governsID: 1.2.840.113556.1.5.7000.62.1005 mayContain: msExchGWiseUserId mayContain: msExchGWisePassword mayContain: msExchGWiseForeignDomain mayContain: msExchGWiseFilterType mayContain: msExchGWiseAPIGatewayPath rDNAttID: cn showInAdvancedViewOnly: TRUE adminDisplayName: ms-Exch-GroupWise-Connector adminDescription: ms-Exch-GroupWise-Connector auxiliaryClass: msExchBaseClass objectClassCategory: 1 lDAPDisplayName: msExchGroupWiseConnector name: ms-Exch-GroupWise-Connector schemaIDGUID: 91eaaac4-b09e-11d2-aa06-00c04f8eedd8 systemOnly: FALSE defaultSecurityDescriptor: D:S: defaultHidingValue: TRUE objectCategory: CN=Class-Schema,${SCHEMADN} defaultObjectCategory: CN=ms-Exch-GroupWise-Connector,${SCHEMADN} # # ms-Exch-Active-Directory-Connector # Represents the service that synchronizes information between the # Exchange Server 5.5 directory and Active Directory. # dn: CN=ms-Exch-Active-Directory-Connector,${SCHEMADN} objectClass: top objectClass: classSchema cn: ms-Exch-Active-Directory-Connector distinguishedName: CN=ms-Exch-Active-Directory-Connector,${SCHEMADN} possSuperiors: organizationalUnit possSuperiors: container subClassOf: top governsID: 1.2.840.113556.1.5.7000.62.4 mayContain: versionNumberHi mayContain: versionNumber mayContain: msExchServer2SchemaMap mayContain: msExchServer1SchemaMap mayContain: msExchChildSyncAgreements mayContain: displayName rDNAttID: cn showInAdvancedViewOnly: TRUE adminDisplayName: ms-Exch-Active-Directory-Connector adminDescription: ms-Exch-Active-Directory-Connector auxiliaryClass: msExchBaseClass objectClassCategory: 1 lDAPDisplayName: msExchActiveDirectoryConnector name: ms-Exch-Active-Directory-Connector schemaIDGUID: e605672c-a980-11d2-a9ff-00c04f8eedd8 systemOnly: FALSE defaultSecurityDescriptor: D:S: defaultHidingValue: TRUE objectCategory: CN=Class-Schema,${SCHEMADN} defaultObjectCategory: CN=ms-Exch-Active-Directory-Connector,${SCHEMADN} # # ms-Exch-MS-Mail-Connector # The Microsoft Mail Connector object. # dn: CN=ms-Exch-MS-Mail-Connector,${SCHEMADN} objectClass: top objectClass: classSchema cn: ms-Exch-MS-Mail-Connector distinguishedName: CN=ms-Exch-MS-Mail-Connector,${SCHEMADN} possSuperiors: container subClassOf: mailGateway governsID: 1.2.840.113556.1.3.31 rDNAttID: cn showInAdvancedViewOnly: TRUE adminDisplayName: ms-Exch-MS-Mail-Connector adminDescription: ms-Exch-MS-Mail-Connector auxiliaryClass: msExchBaseClass objectClassCategory: 1 lDAPDisplayName: mSMailConnector name: ms-Exch-MS-Mail-Connector schemaIDGUID: a8df74be-c5ea-11d1-bbcb-0080c76670c0 systemOnly: FALSE defaultSecurityDescriptor: D:S: defaultHidingValue: TRUE objectCategory: CN=Class-Schema,${SCHEMADN} defaultObjectCategory: CN=ms-Exch-MS-Mail-Connector,${SCHEMADN} # # ms-Exch-Notes-Connector # The Lotus Notes Connector object. # dn: CN=ms-Exch-Notes-Connector,${SCHEMADN} objectClass: top objectClass: classSchema cn: ms-Exch-Notes-Connector distinguishedName: CN=ms-Exch-Notes-Connector,${SCHEMADN} possSuperiors: container subClassOf: mailGateway governsID: 1.2.840.113556.1.5.7000.62.1002 mayContain: msExchNotesPassword mayContain: msExchNotesTargetBooks mayContain: msExchNotesTargetBook mayContain: msExchNotesSourceBooks mayContain: msExchNotesRtrMailbox mayContain: msExchNotesRoutableDomains mayContain: msExchNotesNotesServer mayContain: msExchNotesNotesLinks mayContain: msExchNotesNotesINI mayContain: msExchNotesLetterhead mayContain: msExchNotesForeignDomain mayContain: msExchNotesExportGroups mayContain: msExchNotesExcludeGroups mayContain: msExchNotesConnectorMailbox rDNAttID: cn showInAdvancedViewOnly: TRUE adminDisplayName: ms-Exch-Notes-Connector adminDescription: ms-Exch-Notes-Connector auxiliaryClass: msExchBaseClass objectClassCategory: 1 lDAPDisplayName: msExchNotesConnector name: ms-Exch-Notes-Connector schemaIDGUID: 04c85e62-a981-11d2-a9ff-00c04f8eedd8 systemOnly: FALSE defaultSecurityDescriptor: D:S: defaultHidingValue: TRUE objectCategory: CN=Class-Schema,${SCHEMADN} defaultObjectCategory: CN=ms-Exch-Notes-Connector,${SCHEMADN} # # ms-Exch-Oma-Connector # dn: CN=ms-Exch-Oma-Connector,${SCHEMADN} objectClass: top objectClass: classSchema cn: ms-Exch-Oma-Connector distinguishedName: CN=ms-Exch-Oma-Connector,${SCHEMADN} subClassOf: msExchConnector governsID: 1.2.840.113556.1.6.20.2.39 mayContain: msExchSourceBridgeheadServersDN mayContain: msExchOmaCarrierUrl mayContain: deliveryMechanism mayContain: legacyExchangeDN rDNAttID: cn showInAdvancedViewOnly: TRUE adminDisplayName: ms-Exch-Oma-Connector adminDescription: ms-Exch-Oma-Connector objectClassCategory: 1 lDAPDisplayName: msExchOmaConnector name: ms-Exch-Oma-Connector schemaIDGUID: 4dc9d0b1-594c-407e-a7d2-426e6c20dabb systemOnly: FALSE defaultSecurityDescriptor: D:S: defaultHidingValue: TRUE objectCategory: CN=Class-Schema,${SCHEMADN} defaultObjectCategory: CN=ms-Exch-Oma-Connector,${SCHEMADN} # # ms-Exch-OVVM-Connector # The OVVM Connector. # dn: CN=ms-Exch-OVVM-Connector,${SCHEMADN} objectClass: top objectClass: classSchema cn: ms-Exch-OVVM-Connector distinguishedName: CN=ms-Exch-OVVM-Connector,${SCHEMADN} possSuperiors: container subClassOf: mailGateway governsID: 1.2.840.113556.1.5.7000.62.1004 rDNAttID: cn showInAdvancedViewOnly: TRUE adminDisplayName: ms-Exch-OVVM-Connector adminDescription: ms-Exch-OVVM-Connector auxiliaryClass: msExchBaseClass objectClassCategory: 1 lDAPDisplayName: msExchOVVMConnector name: ms-Exch-OVVM-Connector schemaIDGUID: 91ce0e8c-b09e-11d2-aa06-00c04f8eedd8 systemOnly: FALSE defaultSecurityDescriptor: D:S: defaultHidingValue: TRUE objectCategory: CN=Class-Schema,${SCHEMADN} defaultObjectCategory: CN=ms-Exch-OVVM-Connector,${SCHEMADN} # # ms-Exch-Mail-Connector # The Microsoft Mail Connector object. # dn: CN=ms-Exch-Mail-Connector,${SCHEMADN} objectClass: top objectClass: classSchema cn: ms-Exch-Mail-Connector distinguishedName: CN=ms-Exch-Mail-Connector,${SCHEMADN} possSuperiors: container subClassOf: mailGateway governsID: 1.2.840.113556.1.3.61 rDNAttID: cn showInAdvancedViewOnly: TRUE adminDisplayName: ms-Exch-Mail-Connector adminDescription: ms-Exch-Mail-Connector auxiliaryClass: msExchBaseClass objectClassCategory: 1 lDAPDisplayName: mailConnector name: ms-Exch-Mail-Connector schemaIDGUID: a8df74b6-c5ea-11d1-bbcb-0080c76670c0 systemOnly: FALSE defaultSecurityDescriptor: D:S: defaultHidingValue: TRUE objectCategory: CN=Class-Schema,${SCHEMADN} defaultObjectCategory: CN=ms-Exch-Mail-Connector,${SCHEMADN} # # ms-Exch-X400-Link # Specifies a remote X.400 MTA. # dn: CN=ms-Exch-X400-Link,${SCHEMADN} objectClass: top objectClass: classSchema cn: ms-Exch-X400-Link distinguishedName: CN=ms-Exch-X400-Link,${SCHEMADN} possSuperiors: container subClassOf: mailGateway governsID: 1.2.840.113556.1.3.29 mayContain: x400SelectorSyntax mayContain: x400AttachmentType mayContain: twoWayAlternateFacility mayContain: turnRequestThreshold mayContain: transportExpeditedData mayContain: tempAssocThreshold mayContain: tSelector mayContain: supportingStack mayContain: sessionDisconnectTimer mayContain: sSelectorInbound mayContain: sSelector mayContain: rTSWindowSize mayContain: rTSRecoveryTimeout mayContain: rTSCheckpointSize mayContain: pSelectorInbound mayContain: pSelector mayContain: openRetryInterval mayContain: numOfTransferRetries mayContain: numOfOpenRetries mayContain: nAddressType mayContain: nAddress mayContain: mTALocalDesig mayContain: mTALocalCred mayContain: localInitialTurn mayContain: gatewayLocalDesig mayContain: gatewayLocalCred mayContain: associationLifetime rDNAttID: cn showInAdvancedViewOnly: TRUE adminDisplayName: ms-Exch-X400-Link adminDescription: ms-Exch-X400-Link auxiliaryClass: msExchBaseClass objectClassCategory: 1 lDAPDisplayName: x400Link name: ms-Exch-X400-Link schemaIDGUID: a8df74e0-c5ea-11d1-bbcb-0080c76670c0 systemOnly: FALSE defaultSecurityDescriptor: D:S: defaultHidingValue: TRUE objectCategory: CN=Class-Schema,${SCHEMADN} defaultObjectCategory: CN=ms-Exch-X400-Link,${SCHEMADN} openchange-2.0/setup/AD/oc_provision_schema_subcontainer.ldif000066400000000000000000000614131223057412600245620ustar00rootroot00000000000000# # ms-Exch-Protocol-Cfg-HTTP-Container # dn: CN=ms-Exch-Protocol-Cfg-HTTP-Container,${SCHEMADN} objectClass: top objectClass: classSchema cn: ms-Exch-Protocol-Cfg-HTTP-Container distinguishedName: CN=ms-Exch-Protocol-Cfg-HTTP-Container,${SCHEMADN} subClassOf: msExchProtocolCfgSharedContainer governsID: 1.2.840.113556.1.5.7000.62.14001 rDNAttID: cn showInAdvancedViewOnly: TRUE adminDisplayName: ms-Exch-Protocol-Cfg-HTTP-Container adminDescription: ms-Exch-Protocol-Cfg-HTTP-Container auxiliaryClass: msExchBaseClass objectClassCategory: 1 lDAPDisplayName: msExchProtocolCfgHTTPContainer name: ms-Exch-Protocol-Cfg-HTTP-Container schemaIDGUID: 9432cae6-b09e-11d2-aa06-00c04f8eedd8 systemOnly: FALSE defaultSecurityDescriptor: D:S: defaultHidingValue: TRUE objectCategory: CN=Class-Schema,${SCHEMADN} defaultObjectCategory: CN=ms-Exch-Protocol-Cfg-HTTP-Container,${SCHEMADN} # # ms-Exch-Recipient-Policy-Container # dn: CN=ms-Exch-Recipient-Policy-Container,${SCHEMADN} objectClass: top objectClass: classSchema cn: ms-Exch-Recipient-Policy-Container distinguishedName: CN=ms-Exch-Recipient-Policy-Container,${SCHEMADN} possSuperiors: msExchOrganizationContainer subClassOf: msExchGenericPolicyContainer governsID: 1.2.840.113556.1.5.7000.62.50023 mayContain: msExchMinAdminVersion rDNAttID: cn showInAdvancedViewOnly: TRUE adminDisplayName: ms-Exch-Recipient-Policy-Container adminDescription: ms-Exch-Recipient-Policy-Container auxiliaryClass: msExchBaseClass objectClassCategory: 1 lDAPDisplayName: msExchRecipientPolicyContainer name: ms-Exch-Recipient-Policy-Container schemaIDGUID: e32977d2-1d31-11d3-aa5e-00c04f8eedd8 systemOnly: FALSE defaultSecurityDescriptor: D:S: defaultHidingValue: TRUE objectCategory: CN=Class-Schema,${SCHEMADN} defaultObjectCategory: CN=ms-Exch-Recipient-Policy-Container,${SCHEMADN} # # ms-Exch-Protocol-Cfg-HTTP # dn: CN=ms-Exch-Protocol-Cfg-HTTP,${SCHEMADN} objectClass: top objectClass: classSchema cn: ms-Exch-Protocol-Cfg-HTTP distinguishedName: CN=ms-Exch-Protocol-Cfg-HTTP,${SCHEMADN} possSuperiors: protocolCfgSharedSite possSuperiors: protocolCfgSharedServer subClassOf: protocolCfg governsID: 1.2.840.113556.1.3.79 mustContain: hTTPPubGAL mayContain: hTTPServers mayContain: hTTPPubPF mayContain: hTTPPubGALLimit mayContain: hTTPPubABAttributes rDNAttID: cn showInAdvancedViewOnly: TRUE adminDisplayName: ms-Exch-Protocol-Cfg-HTTP adminDescription: ms-Exch-Protocol-Cfg-HTTP auxiliaryClass: msExchBaseClass objectClassCategory: 1 lDAPDisplayName: protocolCfgHTTP name: ms-Exch-Protocol-Cfg-HTTP schemaIDGUID: a8df74c1-c5ea-11d1-bbcb-0080c76670c0 systemOnly: FALSE defaultSecurityDescriptor: D:S: defaultHidingValue: TRUE objectCategory: CN=Class-Schema,${SCHEMADN} defaultObjectCategory: CN=ms-Exch-Protocol-Cfg-HTTP,${SCHEMADN} # # ms-Exch-Protocol-Cfg-IM-Container # dn: CN=ms-Exch-Protocol-Cfg-IM-Container,${SCHEMADN} objectClass: top objectClass: classSchema cn: ms-Exch-Protocol-Cfg-IM-Container distinguishedName: CN=ms-Exch-Protocol-Cfg-IM-Container,${SCHEMADN} subClassOf: msExchProtocolCfgSharedContainer governsID: 1.2.840.113556.1.5.7000.62.7011 mayContain: msExchIMDBPath mayContain: msExchIMDBLogPath rDNAttID: cn showInAdvancedViewOnly: TRUE adminDisplayName: ms-Exch-Protocol-Cfg-IM-Container adminDescription: ms-Exch-Protocol-Cfg-IM-Container auxiliaryClass: msExchBaseClass objectClassCategory: 1 lDAPDisplayName: msExchProtocolCfgIMContainer name: ms-Exch-Protocol-Cfg-IM-Container schemaIDGUID: 9f116ea3-284e-11d3-aa68-00c04f8eedd8 systemOnly: FALSE defaultSecurityDescriptor: D:S: defaultHidingValue: TRUE objectCategory: CN=Class-Schema,${SCHEMADN} defaultObjectCategory: CN=ms-Exch-Protocol-Cfg-IM-Container,${SCHEMADN} # # ms-Exch-Protocol-Cfg-IM # dn: CN=ms-Exch-Protocol-Cfg-IM,${SCHEMADN} objectClass: top objectClass: classSchema cn: ms-Exch-Protocol-Cfg-IM distinguishedName: CN=ms-Exch-Protocol-Cfg-IM,${SCHEMADN} possSuperiors: protocolCfgSharedSite possSuperiors: protocolCfgSharedServer subClassOf: protocolCfg governsID: 1.2.840.113556.1.5.7000.62.7012 rDNAttID: cn showInAdvancedViewOnly: TRUE adminDisplayName: ms-Exch-Protocol-Cfg-IM adminDescription: ms-Exch-Protocol-Cfg-IM auxiliaryClass: msExchBaseClass objectClassCategory: 1 lDAPDisplayName: msExchProtocolCfgIM name: ms-Exch-Protocol-Cfg-IM schemaIDGUID: 9f116ea7-284e-11d3-aa68-00c04f8eedd8 systemOnly: FALSE defaultSecurityDescriptor: D:S: defaultHidingValue: TRUE objectCategory: CN=Class-Schema,${SCHEMADN} defaultObjectCategory: CN=ms-Exch-Protocol-Cfg-IM,${SCHEMADN} # # ms-Exch-Protocol-Cfg-IMAP-Container # dn: CN=ms-Exch-Protocol-Cfg-IMAP-Container,${SCHEMADN} objectClass: top objectClass: classSchema cn: ms-Exch-Protocol-Cfg-IMAP-Container distinguishedName: CN=ms-Exch-Protocol-Cfg-IMAP-Container,${SCHEMADN} subClassOf: msExchProtocolCfgSharedContainer governsID: 1.2.840.113556.1.5.7000.62.3001 mayContain: msExchSASLMechanisms rDNAttID: cn showInAdvancedViewOnly: TRUE adminDisplayName: ms-Exch-Protocol-Cfg-IMAP-Container adminDescription: ms-Exch-Protocol-Cfg-IMAP-Container auxiliaryClass: msExchBaseClass objectClassCategory: 1 lDAPDisplayName: msExchProtocolCfgIMAPContainer name: ms-Exch-Protocol-Cfg-IMAP-Container schemaIDGUID: 93da93e4-b09e-11d2-aa06-00c04f8eedd8 systemOnly: FALSE defaultSecurityDescriptor: D:S: defaultHidingValue: TRUE objectCategory: CN=Class-Schema,${SCHEMADN} defaultObjectCategory: CN=ms-Exch-Protocol-Cfg-IMAP-Container,${SCHEMADN} # # ms-Exch-Protocol-Cfg-IMAP # dn: CN=ms-Exch-Protocol-Cfg-IMAP,${SCHEMADN} objectClass: top objectClass: classSchema cn: ms-Exch-Protocol-Cfg-IMAP distinguishedName: CN=ms-Exch-Protocol-Cfg-IMAP,${SCHEMADN} possSuperiors: protocolCfgSharedSite possSuperiors: protocolCfgSharedServer subClassOf: protocolCfg governsID: 1.2.840.113556.1.3.84 mayContain: msExchLogonACL mayContain: msExchServerBindings mayContain: msExchSecureBindings mayContain: returnExactMsgSize mayContain: msExchPolicyOptionList mayContain: msExchPolicyList mayContain: oWAServer mayContain: listPublicFolders mayContain: formData mayContain: folderPathname mayContain: delegateUser mayContain: anonymousAccount mayContain: helpData32 rDNAttID: cn showInAdvancedViewOnly: TRUE adminDisplayName: ms-Exch-Protocol-Cfg-IMAP adminDescription: ms-Exch-Protocol-Cfg-IMAP auxiliaryClass: msExchBaseClass objectClassCategory: 1 lDAPDisplayName: protocolCfgIMAP name: ms-Exch-Protocol-Cfg-IMAP schemaIDGUID: a8df74c4-c5ea-11d1-bbcb-0080c76670c0 systemOnly: FALSE defaultSecurityDescriptor: D:S: defaultHidingValue: TRUE objectCategory: CN=Class-Schema,${SCHEMADN} defaultObjectCategory: CN=ms-Exch-Protocol-Cfg-IMAP,${SCHEMADN} # # ms-Exch-Protocol-Cfg-LDAP # dn: CN=ms-Exch-Protocol-Cfg-LDAP,${SCHEMADN} objectClass: top objectClass: classSchema cn: ms-Exch-Protocol-Cfg-LDAP distinguishedName: CN=ms-Exch-Protocol-Cfg-LDAP,${SCHEMADN} possSuperiors: protocolCfgSharedSite possSuperiors: protocolCfgSharedServer subClassOf: protocolCfg governsID: 1.2.840.113556.1.3.75 mayContain: outgoingMsgSizeLimit mayContain: lDAPSearchCfg rDNAttID: cn showInAdvancedViewOnly: TRUE adminDisplayName: ms-Exch-Protocol-Cfg-LDAP adminDescription: ms-Exch-Protocol-Cfg-LDAP auxiliaryClass: msExchBaseClass objectClassCategory: 1 lDAPDisplayName: protocolCfgLDAP name: ms-Exch-Protocol-Cfg-LDAP schemaIDGUID: a8df74c7-c5ea-11d1-bbcb-0080c76670c0 systemOnly: FALSE defaultSecurityDescriptor: D:S: defaultHidingValue: TRUE objectCategory: CN=Class-Schema,${SCHEMADN} defaultObjectCategory: CN=ms-Exch-Protocol-Cfg-LDAP,${SCHEMADN} # # ms-Exch-Protocol-Cfg-NNTP # dn: CN=ms-Exch-Protocol-Cfg-NNTP,${SCHEMADN} objectClass: top objectClass: classSchema cn: ms-Exch-Protocol-Cfg-NNTP distinguishedName: CN=ms-Exch-Protocol-Cfg-NNTP,${SCHEMADN} possSuperiors: protocolCfgSharedSite possSuperiors: protocolCfgSharedServer subClassOf: protocolCfg governsID: 1.2.840.113556.1.3.72 mayContain: usenetSiteName mayContain: supportSMIMESignatures mayContain: rootNewsgroupsFolderID mayContain: iNSAdmin mayContain: controlMsgRules mayContain: controlMsgFolderID mayContain: availableDistributions rDNAttID: cn showInAdvancedViewOnly: TRUE adminDisplayName: ms-Exch-Protocol-Cfg-NNTP adminDescription: ms-Exch-Protocol-Cfg-NNTP auxiliaryClass: msExchBaseClass objectClassCategory: 1 lDAPDisplayName: protocolCfgNNTP name: ms-Exch-Protocol-Cfg-NNTP schemaIDGUID: a8df74ca-c5ea-11d1-bbcb-0080c76670c0 systemOnly: FALSE defaultSecurityDescriptor: D:S: defaultHidingValue: TRUE objectCategory: CN=Class-Schema,${SCHEMADN} defaultObjectCategory: CN=ms-Exch-Protocol-Cfg-NNTP,${SCHEMADN} # # ms-Exch-Protocol-Cfg-NNTP-Container # dn: CN=ms-Exch-Protocol-Cfg-NNTP-Container,${SCHEMADN} objectClass: top objectClass: classSchema cn: ms-Exch-Protocol-Cfg-NNTP-Container distinguishedName: CN=ms-Exch-Protocol-Cfg-NNTP-Container,${SCHEMADN} subClassOf: msExchProtocolCfgSharedContainer governsID: 1.2.840.113556.1.5.7000.62.6001 rDNAttID: cn showInAdvancedViewOnly: TRUE adminDisplayName: ms-Exch-Protocol-Cfg-NNTP-Container adminDescription: ms-Exch-Protocol-Cfg-NNTP-Container auxiliaryClass: msExchBaseClass objectClassCategory: 1 lDAPDisplayName: msExchProtocolCfgNNTPContainer name: ms-Exch-Protocol-Cfg-NNTP-Container schemaIDGUID: 94162eae-b09e-11d2-aa06-00c04f8eedd8 systemOnly: FALSE defaultSecurityDescriptor: D:S: defaultHidingValue: TRUE objectCategory: CN=Class-Schema,${SCHEMADN} defaultObjectCategory: CN=ms-Exch-Protocol-Cfg-NNTP-Container,${SCHEMADN} # # ms-Exch-Protocol-Cfg-SMTP # dn: CN=ms-Exch-Protocol-Cfg-SMTP,${SCHEMADN} objectClass: top objectClass: classSchema cn: ms-Exch-Protocol-Cfg-SMTP distinguishedName: CN=ms-Exch-Protocol-Cfg-SMTP,${SCHEMADN} possSuperiors: protocolCfgSharedSite possSuperiors: protocolCfgSharedServer subClassOf: protocolCfg governsID: 1.2.840.113556.1.5.7000.62.5001 mayContain: msExchLogonACL mayContain: msExchPolicyOptionList mayContain: msExchPolicyList rDNAttID: cn showInAdvancedViewOnly: TRUE adminDisplayName: ms-Exch-Protocol-Cfg-SMTP adminDescription: ms-Exch-Protocol-Cfg-SMTP auxiliaryClass: msExchBaseClass objectClassCategory: 1 lDAPDisplayName: protocolCfgSMTP name: ms-Exch-Protocol-Cfg-SMTP schemaIDGUID: 33f98980-a982-11d2-a9ff-00c04f8eedd8 systemOnly: FALSE defaultSecurityDescriptor: D:S: defaultHidingValue: TRUE objectCategory: CN=Class-Schema,${SCHEMADN} defaultObjectCategory: CN=ms-Exch-Protocol-Cfg-SMTP,${SCHEMADN} # # ms-Exch-Protocol-Cfg-SMTP-Container # dn: CN=ms-Exch-Protocol-Cfg-SMTP-Container,${SCHEMADN} objectClass: top objectClass: classSchema cn: ms-Exch-Protocol-Cfg-SMTP-Container distinguishedName: CN=ms-Exch-Protocol-Cfg-SMTP-Container,${SCHEMADN} subClassOf: msExchProtocolCfgSharedContainer governsID: 1.2.840.113556.1.5.7000.62.5010 mayContain: versionNumber rDNAttID: cn showInAdvancedViewOnly: TRUE adminDisplayName: ms-Exch-Protocol-Cfg-SMTP-Container adminDescription: ms-Exch-Protocol-Cfg-SMTP-Container auxiliaryClass: msExchBaseClass objectClassCategory: 1 lDAPDisplayName: msExchProtocolCfgSMTPContainer name: ms-Exch-Protocol-Cfg-SMTP-Container schemaIDGUID: 93bb9552-b09e-11d2-aa06-00c04f8eedd8 systemOnly: FALSE defaultSecurityDescriptor: D:S: defaultHidingValue: TRUE objectCategory: CN=Class-Schema,${SCHEMADN} defaultObjectCategory: CN=ms-Exch-Protocol-Cfg-SMTP-Container,${SCHEMADN} # # ms-Exch-Protocol-Cfg-SMTP-Domain-Container # Contains superior domain level settings under an SMTP virtual # server. # dn: CN=ms-Exch-Protocol-Cfg-SMTP-Domain-Container,${SCHEMADN} objectClass: top objectClass: classSchema cn: ms-Exch-Protocol-Cfg-SMTP-Domain-Container distinguishedName: CN=ms-Exch-Protocol-Cfg-SMTP-Domain-Container,${SCHEMADN} #possSuperiors: protocolCfgSMTPServer subClassOf: top governsID: 1.2.840.113556.1.5.7000.62.5004 mayContain: msExchMinAdminVersion rDNAttID: cn showInAdvancedViewOnly: TRUE adminDisplayName: ms-Exch-Protocol-Cfg-SMTP-Domain-Container adminDescription: ms-Exch-Protocol-Cfg-SMTP-Domain-Container auxiliaryClass: msExchBaseClass objectClassCategory: 1 lDAPDisplayName: protocolCfgSMTPDomainContainer name: ms-Exch-Protocol-Cfg-SMTP-Domain-Container schemaIDGUID: 33bb8c5c-a982-11d2-a9ff-00c04f8eedd8 systemOnly: FALSE defaultSecurityDescriptor: D:S: defaultHidingValue: TRUE objectCategory: CN=Class-Schema,${SCHEMADN} defaultObjectCategory: CN=ms-Exch-Protocol-Cfg-SMTP-Domain-Container,${SCHEMADN} # # ms-Exch-Protocol-Cfg-SMTP-IP-Address-Container # dn: CN=ms-Exch-Protocol-Cfg-SMTP-IP-Address-Container,${SCHEMADN} objectClass: top objectClass: classSchema cn: ms-Exch-Protocol-Cfg-SMTP-IP-Address-Container distinguishedName: CN=ms-Exch-Protocol-Cfg-SMTP-IP-Address-Container,${SCHEMADN} #possSuperiors: protocolCfgSMTPServer subClassOf: container governsID: 1.2.840.113556.1.5.7000.62.5008 rDNAttID: cn showInAdvancedViewOnly: TRUE adminDisplayName: ms-Exch-Protocol-Cfg-SMTP-IP-Address-Container adminDescription: ms-Exch-Protocol-Cfg-SMTP-IP-Address-Container auxiliaryClass: msExchBaseClass objectClassCategory: 1 lDAPDisplayName: msExchProtocolCfgSMTPIPAddressContainer name: ms-Exch-Protocol-Cfg-SMTP-IP-Address-Container schemaIDGUID: 8b2c843c-b09e-11d2-aa06-00c04f8eedd8 systemOnly: FALSE defaultSecurityDescriptor: D:S: defaultHidingValue: TRUE objectCategory: CN=Class-Schema,${SCHEMADN} defaultObjectCategory: CN=ms-Exch-Protocol-Cfg-SMTP-IP-Address-Container,${SCHEMADN} # # ms-Exch-Public-MDB # A public database configuration. # dn: CN=ms-Exch-Public-MDB,${SCHEMADN} objectClass: top objectClass: classSchema cn: ms-Exch-Public-MDB distinguishedName: CN=ms-Exch-Public-MDB,${SCHEMADN} possSuperiors: container possSuperiors: computer subClassOf: msExchMDB governsID: 1.2.840.113556.1.5.7000.62.11005 mayContain: msExchPreferredBackfillSource mayContain: messageSizeLimit mayContain: msExchOverallAgeLimit mayContain: msExchReplicationStyle mayContain: msExchReplicationSchedule mayContain: msExchReplicationMsgSize mayContain: msExchPollInterval mayContain: msExchOwningPFTree mayContain: msExchFirstInstance rDNAttID: cn showInAdvancedViewOnly: TRUE adminDisplayName: ms-Exch-Public-MDB adminDescription: ms-Exch-Public-MDB auxiliaryClass: msExchBaseClass auxiliaryClass: mailRecipient objectClassCategory: 1 lDAPDisplayName: msExchPublicMDB name: ms-Exch-Public-MDB schemaIDGUID: 3568b3a4-a982-11d2-a9ff-00c04f8eedd8 systemOnly: FALSE defaultSecurityDescriptor: D:S: defaultHidingValue: TRUE objectCategory: CN=Class-Schema,${SCHEMADN} defaultObjectCategory: CN=ms-Exch-Public-MDB,${SCHEMADN} # # ms-Exch-Transport-Stack # Represents the X.400 Transport Stacks. # dn: CN=ms-Exch-Transport-Stack,${SCHEMADN} objectClass: top objectClass: classSchema cn: ms-Exch-Transport-Stack distinguishedName: CN=ms-Exch-Transport-Stack,${SCHEMADN} possSuperiors: mTA possSuperiors: container possSuperiors: computer subClassOf: top governsID: 1.2.840.113556.1.3.18 mustContain: cn mayContain: supportingStackBL mayContain: x400SelectorSyntax mayContain: tSelector mayContain: sSelector mayContain: pSelector mayContain: nAddressType mayContain: nAddress rDNAttID: cn showInAdvancedViewOnly: TRUE adminDisplayName: ms-Exch-Transport-Stack adminDescription: ms-Exch-Transport-Stack auxiliaryClass: msExchBaseClass objectClassCategory: 1 lDAPDisplayName: transportStack name: ms-Exch-Transport-Stack schemaIDGUID: a8df74dd-c5ea-11d1-bbcb-0080c76670c0 systemOnly: FALSE defaultSecurityDescriptor: D:S: defaultHidingValue: TRUE objectCategory: CN=Class-Schema,${SCHEMADN} defaultObjectCategory: CN=ms-Exch-Transport-Stack,${SCHEMADN} # # ms-Exch-Mail-Gateway # The main Gateway class. # dn: CN=ms-Exch-Mail-Gateway,${SCHEMADN} objectClass: top objectClass: classSchema cn: ms-Exch-Mail-Gateway distinguishedName: CN=ms-Exch-Mail-Gateway,${SCHEMADN} possSuperiors: container subClassOf: msExchConnector governsID: 1.2.840.113556.1.3.51 mustContain: homeMTA mustContain: deliveryMechanism mustContain: cn mayContain: msExchBarMessageClass mayContain: msExchEncryptedPassword2 mayContain: msExchEncryptedPassword mayContain: msExchServer1NetworkAddress mayContain: msExchMaintenanceStyle mayContain: msExchMaintenanceSchedule mayContain: msExchImportContainerLinked mayContain: msExchExportContainersLinked mayContain: msExchServer1AlwaysCreateAs mayContain: msExchDirsyncStyle mayContain: msExchDirsyncSchedule mayContain: supportedApplicationContext mayContain: translationTableUsed mayContain: transferTimeoutUrgent mayContain: transferTimeoutNormal mayContain: transferTimeoutNonUrgent mayContain: transferRetryInterval mayContain: msExchSourceBHAddress mayContain: replicationSensitivity mayContain: pRMD mayContain: msExchPartnerLanguage mayContain: msExchPartnerCP mayContain: mDBUnreadLimit mayContain: mDBStorageQuota mayContain: mDBMsgTimeOutPeriod mayContain: mDBBackoffInterval mayContain: lineWrap mayContain: importContainer mayContain: homeMDB mayContain: msExchExportDLs mayContain: exportCustomRecipients mayContain: exportContainers mayContain: encapsulationMethod mayContain: msExchDirsyncFilters mayContain: diagnosticRegKey mayContain: msExchDestinationRGDN mayContain: msExchDestBHAddress mayContain: msExchDeliveryOrder mayContain: delivExtContTypes mayContain: delivEITs mayContain: delivContLength mayContain: msExchConnectorType mayContain: computerName mayContain: canPreserveDNs mayContain: msExchAdminMailbox mayContain: aDMD mayContain: c rDNAttID: cn showInAdvancedViewOnly: TRUE adminDisplayName: ms-Exch-Mail-Gateway adminDescription: ms-Exch-Mail-Gateway auxiliaryClass: msExchBaseClass objectClassCategory: 1 lDAPDisplayName: mailGateway name: ms-Exch-Mail-Gateway schemaIDGUID: a8df74b7-c5ea-11d1-bbcb-0080c76670c0 systemOnly: FALSE defaultSecurityDescriptor: D:S: defaultHidingValue: TRUE objectCategory: CN=Class-Schema,${SCHEMADN} defaultObjectCategory: CN=ms-Exch-Mail-Gateway,${SCHEMADN} # # ms-Exch-System-Policy-Container # dn: CN=ms-Exch-System-Policy-Container,${SCHEMADN} objectClass: top objectClass: classSchema cn: ms-Exch-System-Policy-Container distinguishedName: CN=ms-Exch-System-Policy-Container,${SCHEMADN} possSuperiors: msExchOrganizationContainer subClassOf: msExchGenericPolicyContainer governsID: 1.2.840.113556.1.5.7000.62.15 mayContain: msExchMinAdminVersion rDNAttID: cn showInAdvancedViewOnly: TRUE adminDisplayName: ms-Exch-System-Policy-Container adminDescription: ms-Exch-System-Policy-Container auxiliaryClass: msExchBaseClass objectClassCategory: 1 lDAPDisplayName: msExchSystemPolicyContainer name: ms-Exch-System-Policy-Container schemaIDGUID: 32412a7a-22af-479c-a444-624c0137122e systemOnly: FALSE defaultSecurityDescriptor: D:S: defaultHidingValue: TRUE objectCategory: CN=Class-Schema,${SCHEMADN} defaultObjectCategory: CN=ms-Exch-System-Policy-Container,${SCHEMADN} # # ms-Exch-Remote-DXA # The remote directory Exchange objects (requester and server). # dn: CN=ms-Exch-Remote-DXA,${SCHEMADN} objectClass: top objectClass: classSchema cn: ms-Exch-Remote-DXA distinguishedName: CN=ms-Exch-Remote-DXA,${SCHEMADN} possSuperiors: dXASiteServer possSuperiors: container subClassOf: top governsID: 1.2.840.113556.1.3.2 mustContain: exportCustomRecipients mustContain: dXARemoteClient mustContain: cn mayContain: versionNumber mayContain: msExchServer1AlwaysCreateAs mayContain: msExchPrevExportDLs mayContain: msExchImportContainerLinked mayContain: msExchExportDLs mayContain: msExchExportContainersLinked mayContain: assocRemoteDXA mayContain: deletedItemFlags mayContain: responsibleLocalDXA mayContain: reqSeq mayContain: replicationSensitivity mayContain: messageSizeLimit mayContain: importContainer mayContain: exportContainers mayContain: dXAUnConfContainerList mayContain: dXATypes mayContain: dXATemplateOptions mayContain: dXASvrSeqUSN mayContain: dXASvrSeqTime mayContain: dXASvrSeq mayContain: dXAReqName mayContain: dXAReqSeqUSN mayContain: dXAReqSeqTime mayContain: dXAReqSeq mayContain: dXARecipientCP mayContain: dXAPrevTypes mayContain: dXAPrevTemplateOptions mayContain: dXAPrevReplicationSensitivity mayContain: dXAPrevRemoteEntries mayContain: dXAPrevInExchangeSensitivity mayContain: dXAPrevExportNativeOnly mayContain: dXAPrevExchangeOptions mayContain: dXAPassword mayContain: dXANativeAddressType mayContain: dXALocalAdmin mayContain: dXAImportNow mayContain: dXAImpSeqUSN mayContain: dXAImpSeqTime mayContain: dXAImpSeq mayContain: dXAExportNow mayContain: dXAExchangeOptions mayContain: dXAConfSeqUSN mayContain: dXAConfSeq mayContain: dXAConfReqTime mayContain: dXAConfContainerList mayContain: dXAAppendReqCN rDNAttID: cn showInAdvancedViewOnly: TRUE adminDisplayName: ms-Exch-Remote-DXA adminDescription: ms-Exch-Remote-DXA auxiliaryClass: msExchBaseClass objectClassCategory: 1 lDAPDisplayName: remoteDXA name: ms-Exch-Remote-DXA schemaIDGUID: a8df74d5-c5ea-11d1-bbcb-0080c76670c0 systemOnly: FALSE defaultSecurityDescriptor: D:S: defaultHidingValue: TRUE objectCategory: CN=Class-Schema,${SCHEMADN} defaultObjectCategory: CN=ms-Exch-Remote-DXA,${SCHEMADN} # # ms-Exch-Private-MDB # A private database configuration. # dn: CN=ms-Exch-Private-MDB,${SCHEMADN} objectClass: top objectClass: classSchema cn: ms-Exch-Private-MDB distinguishedName: CN=ms-Exch-Private-MDB,${SCHEMADN} possSuperiors: container possSuperiors: computer subClassOf: msExchMDB governsID: 1.2.840.113556.1.5.7000.62.11004 mayContain: msExchRestore mayContain: msExchOrigMDB mayContain: msExchMessageJournalRecipient mayContain: msExchUseOAB mayContain: msExchMailboxRetentionPeriod mayContain: msExchMaximumRecurringInstancesMonths mayContain: msExchMaximumRecurringInstances mayContain: msExchHomePublicMDB rDNAttID: cn showInAdvancedViewOnly: TRUE adminDisplayName: ms-Exch-Private-MDB adminDescription: ms-Exch-Private-MDB auxiliaryClass: msExchBaseClass objectClassCategory: 1 lDAPDisplayName: msExchPrivateMDB name: ms-Exch-Private-MDB schemaIDGUID: 36145cf4-a982-11d2-a9ff-00c04f8eedd8 systemOnly: FALSE defaultSecurityDescriptor: D:S: defaultHidingValue: TRUE objectCategory: CN=Class-Schema,${SCHEMADN} defaultObjectCategory: CN=ms-Exch-Private-MDB,${SCHEMADN} # # ms-Exch-Chat-Protocol # A Chat Service user class. # dn: CN=ms-Exch-Chat-Protocol,${SCHEMADN} objectClass: top objectClass: classSchema cn: ms-Exch-Chat-Protocol distinguishedName: CN=ms-Exch-Chat-Protocol,${SCHEMADN} possSuperiors: protocolCfgSharedServer subClassOf: top governsID: 1.2.840.113556.1.5.7000.62.8005 mayContain: msExchServerBindings mayContain: msExchChatServerPort mayContain: msExchChatBroadcastAddress mayContain: msExchChatAccess mayContain: msExchChatNetworkName rDNAttID: cn showInAdvancedViewOnly: TRUE adminDisplayName: ms-Exch-Chat-Protocol adminDescription: ms-Exch-Chat-Protocol auxiliaryClass: msExchBaseClass objectClassCategory: 1 lDAPDisplayName: msExchChatProtocol name: ms-Exch-Chat-Protocol schemaIDGUID: e9621816-a980-11d2-a9ff-00c04f8eedd8 systemOnly: FALSE defaultSecurityDescriptor: D:S: defaultHidingValue: TRUE objectCategory: CN=Class-Schema,${SCHEMADN} defaultObjectCategory: CN=ms-Exch-Chat-Protocol,${SCHEMADN} # # ms-Exch-Chat-Network # A Chat Service community object. # dn: CN=ms-Exch-Chat-Network,${SCHEMADN} objectClass: top objectClass: classSchema cn: ms-Exch-Chat-Network distinguishedName: CN=ms-Exch-Chat-Network,${SCHEMADN} possSuperiors: msExchAdminGroup subClassOf: container governsID: 1.2.840.113556.1.5.7000.62.8001 mayContain: msExchBasicAuthenticationDomain mayContain: msExchAuthenticationFlags mayContain: msExchChatNetworkMode mayContain: msExchChatAccess mayContain: msExchChatTitle mayContain: msExchChatMOTD mayContain: msExchChatMaxMemberships mayContain: msExchChatMaxConnections mayContain: msExchChatMaxAnonymous #mayContain: msExchChatEnableAuthenticated mayContain: msExchChatEnableAnonymous mayContain: msExchChatDNSReverseMode mayContain: msExchChatClientPort mayContain: msExchChatChannelMode mayContain: msExchChatChannelLimit mayContain: msExchChatChannelLCID mayContain: msExchChatChannelLanguage mayContain: msExchChatAdminMessage mayContain: Enabled rDNAttID: cn showInAdvancedViewOnly: TRUE adminDisplayName: ms-Exch-Chat-Network adminDescription: ms-Exch-Chat-Network auxiliaryClass: msExchBaseClass objectClassCategory: 1 lDAPDisplayName: msExchChatNetwork name: ms-Exch-Chat-Network schemaIDGUID: e934cb68-a980-11d2-a9ff-00c04f8eedd8 systemOnly: FALSE defaultSecurityDescriptor: D:S: defaultHidingValue: TRUE objectCategory: CN=Class-Schema,${SCHEMADN} defaultObjectCategory: CN=ms-Exch-Chat-Network,${SCHEMADN} # # ms-Exch-Protocol-Cfg-HTTP-Filters # The Exchange HTTP service filters container. # dn: CN=ms-Exch-Protocol-Cfg-HTTP-Filters,${SCHEMADN} objectClass: top objectClass: classSchema cn: ms-Exch-Protocol-Cfg-HTTP-Filters distinguishedName: CN=ms-Exch-Protocol-Cfg-HTTP-Filters,${SCHEMADN} possSuperiors: protocolCfgSharedServer subClassOf: container governsID: 1.2.840.113556.1.5.7000.62.15002 rDNAttID: cn showInAdvancedViewOnly: TRUE adminDisplayName: ms-Exch-Protocol-Cfg-HTTP-Filters adminDescription: ms-Exch-Protocol-Cfg-HTTP-Filters auxiliaryClass: msExchBaseClass objectClassCategory: 1 lDAPDisplayName: msExchProtocolCfgHTTPFilters name: ms-Exch-Protocol-Cfg-HTTP-Filters schemaIDGUID: 8c58ec88-b09e-11d2-aa06-00c04f8eedd8 systemOnly: FALSE defaultSecurityDescriptor: D:S: defaultHidingValue: TRUE objectCategory: CN=Class-Schema,${SCHEMADN} defaultObjectCategory: CN=ms-Exch-Protocol-Cfg-HTTP-Filters,${SCHEMADN} openchange-2.0/setup/AD/prefixMap.txt000066400000000000000000000017671223057412600176170ustar00rootroot000000000000000:2.5.4 1:2.5.6 2:1.2.840.113556.1.2 3:1.2.840.113556.1.3 4:2.16.840.1.101.2.2.1 5:2.16.840.1.101.2.2.3 6:2.16.840.1.101.2.1.5 7:2.16.840.1.101.2.1.4 8:2.5.5 9:1.2.840.113556.1.4 10:1.2.840.113556.1.5 19:0.9.2342.19200300.100 20:2.16.840.1.113730.3 21:0.9.2342.19200300.100.1 22:2.16.840.1.113730.3.1 23:1.2.840.113556.1.5.7000 24:2.5.21 25:2.5.18 26:2.5.20 11:1.2.840.113556.1.4.260 12:1.2.840.113556.1.5.56 13:1.2.840.113556.1.4.262 14:1.2.840.113556.1.5.57 15:1.2.840.113556.1.4.263 16:1.2.840.113556.1.5.58 17:1.2.840.113556.1.5.73 18:1.2.840.113556.1.4.305 27:1.3.6.1.4.1.1466.101.119 28:2.16.840.1.113730.3.2 29:1.3.6.1.4.1.250.1 30:1.2.840.113549.1.9 31:0.9.2342.19200300.100.4 32:1.2.840.113556.1.6.23 33:1.2.840.113556.1.6.18.1 34:1.2.840.113556.1.6.18.2 35:1.2.840.113556.1.6.13.3 36:1.2.840.113556.1.6.13.4 37:1.3.6.1.1.1.1 38:1.3.6.1.1.1.2 39:1.3.6.1.4.1.7165.4.1 40:1.3.6.1.4.1.7165.4.2 41:1.2.840.113556.1.5.7000.62 42:1.2.840.113556.1.4.7000.102 43:1.2.840.113556.1.6.20.1 44:1.2.840.113556.1.6.20.2 openchange-2.0/setup/AD/provision_schema_basedn_modify.ldif000066400000000000000000000004341223057412600242040ustar00rootroot00000000000000############################### # Schema Naming Context ############################### dn: ${SCHEMADN} changetype: modify replace: fSMORoleOwner fSMORoleOwner: CN=NTDS Settings,${SERVERDN} - replace: objectVersion objectVersion: 30 - replace: prefixMap prefixMap:: ${PREFIXMAP_B64} openchange-2.0/setup/openchange_newuser000077500000000000000000000043231223057412600204330ustar00rootroot00000000000000#!/usr/bin/python # OpenChange provision script # # Copyright (C) Jelmer Vernooij 2008 # # This program is free software; you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by # the Free Software Foundation; either version 3 of the License, or # (at your option) any later version. # # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program. If not, see . # import optparse import os,sys # To allow running from the source directory sys.path.append("python") import openchange import samba import samba.getopt as options import openchange.provision as openchange parser = optparse.OptionParser("openchange_newuser [options] ") sambaopts = options.SambaOptions(parser) parser.add_option_group(sambaopts) credopts = options.CredentialsOptions(parser) parser.add_option_group(credopts) parser.add_option("--enable", action="store_true", metavar="ENABLE", help="Enable access to OpenChange server") parser.add_option("--disable", action="store_true", metavar="DISABLE", help="Disable access to OpenChange server") parser.add_option("--create", action="store_true", metavar="CREATE", help="Create the OpenChange user account") parser.add_option("--mailbox", action="store_true", metavar="MAILBOX", help="Create the OpenChange user mailbox") opts, args = parser.parse_args() if len(args) == 0: parser.print_usage() sys.exit(1) lp = sambaopts.get_loadparm() creds = credopts.get_credentials(lp) def setup_path(*args): return os.path.join(os.path.dirname(__file__), *args) if opts.enable == True: openchange.accountcontrol(lp, creds, username=args[0], value=0) if opts.disable == True: openchange.accountcontrol(lp, creds, username=args[0], value=2) if opts.create == True: openchange.newuser(lp, creds, username=args[0]) if opts.mailbox == True: print "Mailbox provisioning is now performed automatically at user logon" openchange-2.0/setup/openchange_provision000077500000000000000000000046331223057412600207770ustar00rootroot00000000000000#!/usr/bin/python # OpenChange provision script # # Copyright (C) Jelmer Vernooij 2008 # # This program is free software; you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by # the Free Software Foundation; either version 3 of the License, or # (at your option) any later version. # # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program. If not, see . # import optparse import os,sys # To allow running from the source directory sys.path.append("python") import openchange import samba import samba.getopt as options import openchange.provision as openchange parser = optparse.OptionParser("openchange_provision [options]") sambaopts = options.SambaOptions(parser) parser.add_option_group(sambaopts) credopts = options.CredentialsOptions(parser) parser.add_option_group(credopts) parser.add_option("--firstorg", type="string", metavar="FIRSTORG", help="set OpenChange First Organization (otherwise First Organization)") parser.add_option("--firstou", type="string", metavar="FIRSTOU", help="set OpenChange First Organization Unit (otherwise First Organization Unit)") parser.add_option("--openchangedb", action="store_true", help="Initialize OpenChange dispatcher database") parser.add_option("--deprovision", action="store_true", help="Uninstall the Exchange schema and objects from AD") opts,args = parser.parse_args() if len(args) != 0: parser.print_usage() sys.exit(1) lp = sambaopts.get_loadparm() creds = credopts.get_credentials(lp) _setupdir = os.path.dirname(__file__) if not os.path.exists(os.path.join(_setupdir, "AD")): _setupdir = samba.param.setup_dir() def setup_path(*args): global _setupdir return os.path.join(_setupdir, *args) if not opts.openchangedb: if opts.deprovision: openchange.deprovision(setup_path, lp, creds, firstorg=opts.firstorg, firstou=opts.firstou) else: openchange.provision(setup_path, lp, creds, firstorg=opts.firstorg, firstou=opts.firstou) else: openchange.openchangedb_provision(lp, firstorg=opts.firstorg, firstou=opts.firstou) openchange-2.0/setup/openchangedb/000077500000000000000000000000001223057412600172415ustar00rootroot00000000000000openchange-2.0/setup/openchangedb/oc_provision_openchange_init.ldif000066400000000000000000000001741223057412600260260ustar00rootroot00000000000000dn: @OPTIONS checkBaseOnSearch: TRUE dn: @INDEXLIST @IDXATTR: cn dn: @ATTRIBUTES cn: CASE_INSENSITIVE dn: CASE_INSENSITIVEopenchange-2.0/setup/openchangedb/oc_provision_openchange_mailbox.ldif000066400000000000000000000001221223057412600265070ustar00rootroot00000000000000dn: CN=${FOLDER_IDX},${USERDN} cn: ${FOLDER_IDX} fid: ${FOLDER_IDX} name: ${NAME} openchange-2.0/setup/profiles/000077500000000000000000000000001223057412600164475ustar00rootroot00000000000000openchange-2.0/setup/profiles/oc_profiles_init.ldif000066400000000000000000000002401223057412600226320ustar00rootroot00000000000000dn: @ATTRIBUTES dnsDomain: CASE_INSENSITIVE cn: CASE_INSENSITIVE dc: CASE_INSENSITIVE name: CASE_INSENSITIVE dn: CASE_INSENSITIVE objectClass: CASE_INSENSITIVE openchange-2.0/setup/profiles/oc_profiles_schema.ldif000066400000000000000000000072031223057412600231350ustar00rootroot00000000000000# # Exchange organization # dn: CN=Organization objectClass: top objectClass: attributeSchema name: Organization CN: Organization description: Exchange Organization isSingleValued: TRUE # # Exchange organization unit # dn: CN=OrganizationUnit objectClass: top objectClass: attributeSchema name: OrganizationUnit CN: OrganizationUnit description: Exchange Organization Unit isSingleValued: TRUE # # User display name # dn: CN=DisplayName objectClass: top objectClass: attributeSchema name: DisplayName CN: DisplayName description: User display name isSingleValued: TRUE # # Office Telephone Number # dn: CN=OfficeTelephoneNumber objectClass: top objectClass: attributeSchema name: OfficeTelephoneNumber CN: OfficeTelephoneNumber description: Office Telephone Number isSingleValued: TRUE # # Office Location # dn: CN=OfficeLocation objectClass: top objectClass: attributeSchema name: OfficeLocation CN: OfficeLocation description: Office Location isSingleValued: TRUE # # User title # dn: CN=Title objectClass: top objectClass: attributeSchema name: Title CN: Title description: User Title isSingleValued: TRUE # # Company Name # dn: CN=CompanyName objectClass: top objectClass: attributeSchema name: CompanyName CN: CompanyName description: Company Name isSingleValued: TRUE # # User account name # dn: CN=AccountName objectClass: top objectClass: attributeSchema name: AccountName CN: AccountName description: User account name isSingleValued: TRUE # # User email address # dn: CN=EmailAddress objectClass: top objectClass: attributeSchema name: EmailAddress CN: EmailAddress description: User email address isSingleValued: TRUE # # Email Address type # dn: CN=AddrType objectClass: top objectClass: attributeSchema name: AddrType CN: AddrType description: User Email Address Type isSingleValued: TRUE # # Entry ID # dn: CN=EntryID objectClass: top objectClass: attributeSchema name: EntryID CN: ENtryID description: Unique identifier for the given object isSingleValued: TRUE # # Object Type # dn: CN=ObjectType objectClass: top objectClass: attributeSchema name: ObjectType CN: ObjectType description: Object Type isSingleValued: TRUE # # Home MDB # dn: CN=HomeMDB objectClass: top objectClass: attributeSchema name: HomeMDB CN: HomeMDB description: Path to the user Mailbox isSingleValued: TRUE # # User Proxy addresses for different connectors # dn: CN=ProxyAddress objectClass: top objectClass: attributeSchema name: ProxyAddress CN: ProxyAddress description: Proxy addresses for other connectors isSingleValued: FALSE # # PR_DEFAULT_PROFILE # dn: CN=PR_DEFAULT_PROFILE objectClass: top objectClass: attributeSchema name: PR_DEFAULT_PROFILE CN: PR_DEFAULT_PROFILE description: Indicates if the profile is the default one isSingleValued: TRUE ######################################################## # Attributes for Exchange Servers containers ######################################################## # # Exchange server binding strings # dn: CN=NetworkAddress objectClass: top objectClass: attributeSchema name: NetworkAddress CN: NetworkAddress description: binding string we can use to connect to the Exchange Server isSingleValued: FALSE # # Container flags # dn: CN=ContainerFlags objectClass: top objectClass: attributeSchema name: ContainerFlags CN: ContainerFlags isSingleValued: TRUE # # Depth # dn: CN=Depth objectClass: top objectClass: attributeSchema name: Depth CN: Depth isSingleValued: TRUE # # AB Container ID # dn: CN=ABContainerID objectClass: top objectClass: attributeSchema name: ABContainerID CN: ABContainerID isSingleValued: TRUE # # AB is Master # dn: CN=ABIsMaster objectClass: top objectClass: attributeSchema name: ABIsMaster CN: ABIsMaster isSingleValued: TRUEopenchange-2.0/testprogs/000077500000000000000000000000001223057412600155165ustar00rootroot00000000000000openchange-2.0/testprogs/blackbox/000077500000000000000000000000001223057412600173035ustar00rootroot00000000000000openchange-2.0/testprogs/blackbox/expected_output--help.txt000066400000000000000000000062221223057412600242720ustar00rootroot00000000000000Usage: openchangeclient [OPTION...] -f, --database=STRING set the profile database path --pf access public folders instead of mailbox -p, --profile=STRING set the profile name -P, --password=STRING set the profile password -S, --sendmail send a mail --sendappointment send an appointment --sendcontact send a contact --sendtask send a task --sendnote send a note -F, --fetchmail fetch user INBOX mails --fetchsummary fetch message summaries only -G, --storemail=STRING retrieve a mail on the filesystem -i, --fetch-items=STRING fetch specified user INBOX items --freebusy=STRING display free / busy information for the specified user --force force openchangeclient behavior in some circumstances --delete=STRING delete a message given its unique ID -u, --update=STRING update the specified item -m, --mailbox list mailbox folder summary -D, --deletemail delete a mail from user INBOX -A, --attachments=STRING send a list of attachments -I, --html-inline=STRING send PR_HTML content -W, --html-file=STRING use HTML file as content -t, --to=STRING set the To recipients -c, --cc=STRING set the Cc recipients -b, --bcc=STRING set the Bcc recipients -s, --subject=STRING set the mail subject -B, --body=STRING set the mail body --location=STRING set the item location --label=STRING set the event label --dtstart=STRING set the event start date --dtend=STRING set the event end date --busystatus=STRING set the item busy status --taskstatus=STRING set the task status --importance=STRING Set the item importance --email=STRING set the email address --fullname=STRING set the full name --cardname=STRING set a contact card name --color=STRING set the note color --notifications monitor INBOX newmail notifications --folder=STRING set the folder to use instead of inbox --mkdir create a folder --rmdir delete a folder --userlist list Address Book entries --folder-name=STRING set the folder name --folder-comment=STRING set the folder comment -d, --debuglevel=STRING set Debug Level --dump-data dump the hex data --private set the private flag on messages --ocpf-file=STRING set OCPF file --ocpf-dump=STRING dump message into OCPF file --ocpf-syntax check OCPF files syntax --ocpf-sender send message using OCPF files contents Help options: -?, --help Show this help message --usage Display brief usage message Common openchange options: -V, --version Print version openchange-2.0/testprogs/blackbox/expected_output--ocpf-syntax1.txt000066400000000000000000000015641223057412600257020ustar00rootroot00000000000000 TYPE: ===== * IPM.Appointment FOLDER: ======= * 0x9 OLEGUID: ======== PS_PUBLIC_STRINGS : 00020329-0000-0000-c000-000000000046 PSETID_Common : 00062008-0000-0000-c000-000000000046 PSETID_Appointment : 00062002-0000-0000-c000-000000000046 RECIPIENTS: =========== * To: * Cc: * Bcc: VARIABLE: ========= wrong private keywords reminder end_date start_date subject PROPERTIES: =========== 0x00360003 = PR_SENSITIVITY 0x00610040 = PR_END_DATE 0x00600040 = PR_START_DATE 0x1000001e = PR_BODY 0x0e1d001e = PR_NORMALIZED_SUBJECT 0x0070001e = PR_CONVERSATION_TOPIC NAMED PROPERTIES: ================= OOM: ---- * Private * Location * CommonEnd * ApptEndDate * CommonStart * ApptStartDate * BusyStatus MNID_ID: -------- * 0x8501 * 0x8217 MNID_STRING: ------------ * Keywords openchange-2.0/testprogs/blackbox/expected_output--ocpf-syntax2.txt000066400000000000000000000016111223057412600256740ustar00rootroot00000000000000../../libocpf/examples/sample_task.ocpf:46: Unknown OOM ../../libocpf/examples/sample_task.ocpf:47: Unknown OOM ../../libocpf/examples/sample_task.ocpf:48: Unknown OOM TYPE: ===== * IPM.Task FOLDER: ======= * 0xd OLEGUID: ======== PS_PUBLIC_STRINGS : 00020329-0000-0000-c000-000000000046 PSETID_Common : 00062008-0000-0000-c000-000000000046 PSETID_Task : 00062003-0000-0000-c000-000000000046 RECIPIENTS: =========== * To: * Cc: * Bcc: VARIABLE: ========= task_status importance end_date start_date body subject PROPERTIES: =========== 0x00360003 = PR_SENSITIVITY 0x00170003 = PR_IMPORTANCE 0x1000001e = PR_BODY 0x0e1d001e = PR_NORMALIZED_SUBJECT 0x0070001e = PR_CONVERSATION_TOPIC NAMED PROPERTIES: ================= OOM: ---- * Private * Companies MNID_ID: -------- MNID_STRING: ------------ * Keywords openchange-2.0/testprogs/blackbox/expected_output--usage.txt000066400000000000000000000022231223057412600244430ustar00rootroot00000000000000Usage: openchangeclient [-?SFmDV] [-?|--help] [--usage] [-f|--database STRING] [--pf] [-p|--profile STRING] [-P|--password STRING] [-S|--sendmail] [--sendappointment] [--sendcontact] [--sendtask] [--sendnote] [-F|--fetchmail] [--fetchsummary] [-G|--storemail STRING] [-i|--fetch-items STRING] [--freebusy=STRING] [--force] [--delete=STRING] [-u|--update STRING] [-m|--mailbox] [-D|--deletemail] [-A|--attachments STRING] [-I|--html-inline STRING] [-W|--html-file STRING] [-t|--to STRING] [-c|--cc STRING] [-b|--bcc STRING] [-s|--subject STRING] [-B|--body STRING] [--location=STRING] [--label=STRING] [--dtstart=STRING] [--dtend=STRING] [--busystatus=STRING] [--taskstatus=STRING] [--importance=STRING] [--email=STRING] [--fullname=STRING] [--cardname=STRING] [--color=STRING] [--notifications] [--folder=STRING] [--mkdir] [--rmdir] [--userlist] [--folder-name=STRING] [--folder-comment=STRING] [-d|--debuglevel STRING] [--dump-data] [--private] [--ocpf-file=STRING] [--ocpf-dump=STRING] [--ocpf-syntax] [--ocpf-sender] [-V|--version] openchange-2.0/testprogs/blackbox/expected_output--version.txt000066400000000000000000000000251223057412600250220ustar00rootroot00000000000000Version 0.10 (Nomad) openchange-2.0/testprogs/blackbox/subunit.sh000077500000000000000000000036721223057412600213430ustar00rootroot00000000000000# # subunit.sh: shell functions to report test status via the subunit protocol. # Copyright (C) 2006 Robert Collins # Copyright (C) 2008 Jelmer Vernooij # # This program is free software; you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by # the Free Software Foundation; either version 2 of the License, or # (at your option) any later version. # # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program; if not, write to the Free Software # Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA # subunit_start_test () { # emit the current protocol start-marker for test $1 echo "test: $1" } subunit_pass_test () { # emit the current protocol test passed marker for test $1 echo "success: $1" } subunit_fail_test () { # emit the current protocol fail-marker for test $1, and emit stdin as # the error text. # we use stdin because the failure message can be arbitrarily long, and this # makes it convenient to write in scripts (using <&1` status=$? if [ x$status = x0 ]; then subunit_pass_test "$name" else echo "$output" | subunit_fail_test "$name" fi return $status } openchange-2.0/testprogs/blackbox/test_mapiprofile.sh000077500000000000000000000036741223057412600232220ustar00rootroot00000000000000#!/bin/sh # Black tests for mapiprofile # Copyright (C) 2009 Julien Kerihuel if [ $# -lt 4 ]; then cat < 2010 This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see . */ #include "libmapi/libmapi.h" #include "mapiproxy/libmapistore/mapistore.h" #include "mapiproxy/libmapistore/mapistore_errors.h" #include #include #include #include static void popt_openchange_version_callback(poptContext con, enum poptCallbackReason reason, const struct poptOption *opt, const char *arg, const void *data) { switch (opt->val) { case 'V': printf("Version %s\n", OPENCHANGE_VERSION_STRING); exit (0); } } struct poptOption popt_openchange_version[] = { { NULL, '\0', POPT_ARG_CALLBACK, (void *)popt_openchange_version_callback, '\0', NULL, NULL }, { "version", 'V', POPT_ARG_NONE, NULL, 'V', "Print version ", NULL }, POPT_TABLEEND }; #define POPT_OPENCHANGE_VERSION { NULL, 0, POPT_ARG_INCLUDE_TABLE, popt_openchange_version, 0, "Common openchange options:", NULL }, #define DEFAULT_PROFDB "%s/.openchange/profiles.ldb" /* These callbacks are for deserialising the fast transfer stream to a mapistore instance */ struct parent_fid { struct parent_fid *prev; struct parent_fid *next; uint64_t fid; }; struct mapistore_output_ctx { struct mapistore_context *mstore_ctx; uint32_t mapistore_context_id; uint64_t root_fid; void *root_folder; struct parent_fid *parent_fids; /* stack */ uint64_t current_id; uint8_t current_output_type; struct SRow *proplist; /* the properties on the "current" object */ }; static enum MAPISTATUS mapistore_marker(uint32_t marker, void *priv) { struct mapistore_output_ctx *mapistore = priv; /* TALLOC_CTX *mem_ctx; */ /* void *message; */ if (mapistore->proplist) { struct parent_fid *it; printf("parent_fids: "); for (it = mapistore->parent_fids; it->next; it = it->next) { printf("0x%016"PRIx64",", it->fid); } printf("\n"); if (mapistore->current_id == mapistore->root_fid) { /* This is the top level folder */ abort(); /* obsolete code: */ /* mapistore_setprops(mapistore->mstore_ctx, mapistore->mapistore_context_id, */ /* mapistore->root_fid, mapistore->current_output_type, */ /* mapistore->proplist); */ } else if (mapistore->current_output_type == MAPISTORE_FOLDER) { abort(); /* obsolete code: */ /* struct parent_fid *element = talloc_zero(mapistore->mstore_ctx, struct parent_fid); */ /* mapistore_folder_create_folder(mapistore->mstore_ctx, mapistore->mapistore_context_id, */ /* mapistore->parent_fids->fid, mapistore->current_id, */ /* mapistore->proplist); */ /* element->fid = mapistore->current_id; */ /* DLIST_ADD(mapistore->parent_fids, element); */ } else { abort(); /* obsolete code: */ /* mem_ctx = talloc_zero(NULL, TALLOC_CTX); */ /* mapistore_folder_create_message(mapistore->mstore_ctx, mapistore->mapistore_context_id, */ /* mem_ctx, mapistore->parent_fids->fid, mapistore->current_id, false, */ /* &message); */ /* mapistore_properties_set_properties(mapistore->mstore_ctx, mapistore->mapistore_context_id, */ /* message, mapistore->proplist); */ /* mapistore_message_save(mapistore->mstore_ctx, mapistore->mapistore_context_id, */ /* message); */ /* talloc_free(mem_ctx); */ } talloc_free(mapistore->proplist); mapistore->proplist = 0; (mapistore->current_id)++; } switch (marker) { case PidTagStartTopFld: { /* start collecting properties */ struct SPropValue one_prop; struct parent_fid *element = talloc_zero(mapistore->mstore_ctx, struct parent_fid); mapistore->proplist = talloc_zero(mapistore->mstore_ctx, struct SRow); one_prop.ulPropTag = PR_FID; one_prop.dwAlignPad = 0; one_prop.value.d = mapistore->root_fid; SRow_addprop(mapistore->proplist, one_prop); one_prop.ulPropTag = PR_FOLDER_TYPE; one_prop.value.l = MAPISTORE_FOLDER; SRow_addprop(mapistore->proplist, one_prop); mapistore->current_id = mapistore->root_fid; mapistore->parent_fids = talloc_zero(mapistore->mstore_ctx, struct parent_fid); element->fid = mapistore->current_id; DLIST_ADD(mapistore->parent_fids, element); mapistore->current_output_type = MAPISTORE_FOLDER; break; } case PidTagStartSubFld: mapistore->proplist = talloc_zero(mapistore->mstore_ctx, struct SRow); mapistore->current_output_type = MAPISTORE_FOLDER; break; case PidTagStartMessage: mapistore->proplist = talloc_zero(mapistore->mstore_ctx, struct SRow); mapistore->current_output_type = MAPISTORE_MESSAGE; break; case PidTagStartFAIMsg: case PidTagStartRecip: case PidTagStartEmbed: case PidTagNewAttach: break; case PidTagEndFolder: DLIST_REMOVE(mapistore->parent_fids, mapistore->parent_fids); break; case PidTagEndMessage: case PidTagEndToRecip: case PidTagEndAttach: case PidTagEndEmbed: break; default: printf("***unhandled *** TODO: Marker: %s (0x%08x)\n", get_proptag_name(marker), marker); } return MAPI_E_SUCCESS; } static enum MAPISTATUS mapistore_delprop(uint32_t proptag, void *priv) { printf("TODO: DelProps: 0x%08x (%s)\n", proptag, get_proptag_name(proptag)); return MAPI_E_SUCCESS; } static enum MAPISTATUS mapistore_namedprop(uint32_t proptag, struct MAPINAMEID nameid, void *priv) { TALLOC_CTX *mem_ctx; // struct mapistore_output_ctx *mapistore = priv; mem_ctx = talloc_init("process_namedprop"); printf("TODO: Named Property: 0x%08x has GUID %s and ", proptag, GUID_string(mem_ctx, &(nameid.lpguid))); if (nameid.ulKind == MNID_ID) { printf("dispId 0x%08x\n", nameid.kind.lid); } else if (nameid.ulKind == MNID_STRING) { printf("name %s\n", nameid.kind.lpwstr.Name); } talloc_free(mem_ctx); return MAPI_E_SUCCESS; } static enum MAPISTATUS mapistore_property(struct SPropValue prop, void *priv) { struct mapistore_output_ctx *mapistore = priv; SRow_addprop(mapistore->proplist, prop); return MAPI_E_SUCCESS; } /* These callbacks are for the "dump-data" mode, so they don't do much */ static enum MAPISTATUS dump_marker(uint32_t marker, void *priv) { printf("Marker: %s (0x%08x)\n", get_proptag_name(marker), marker); return MAPI_E_SUCCESS; } static enum MAPISTATUS dump_delprop(uint32_t proptag, void *priv) { printf("DelProps: 0x%08x (%s)\n", proptag, get_proptag_name(proptag)); return MAPI_E_SUCCESS; } static enum MAPISTATUS dump_namedprop(uint32_t proptag, struct MAPINAMEID nameid, void *priv) { TALLOC_CTX *mem_ctx; mem_ctx = talloc_init("process_namedprop"); printf("Named Property: 0x%08x has GUID %s and ", proptag, GUID_string(mem_ctx, &(nameid.lpguid))); if (nameid.ulKind == MNID_ID) { printf("dispId 0x%08x\n", nameid.kind.lid); } else if (nameid.ulKind == MNID_STRING) { printf("name %s\n", nameid.kind.lpwstr.Name); } talloc_free(mem_ctx); return MAPI_E_SUCCESS; } static enum MAPISTATUS dump_property(struct SPropValue prop, void *priv) { mapidump_SPropValue(prop, "\t"); return MAPI_E_SUCCESS; } int main(int argc, const char *argv[]) { TALLOC_CTX *mem_ctx; enum MAPISTATUS retval; enum mapistore_error mretval; struct mapi_context *mapi_ctx; struct mapi_session *session = NULL; mapi_object_t obj_store; mapi_object_t obj_folder; mapi_object_t obj_fx_context; mapi_id_t id_folder; uint16_t progressCount; uint16_t totalStepCount; int transfers = 0; enum TransferStatus fxTransferStatus; DATA_BLOB transferdata; struct fx_parser_context *parser; struct loadparm_context *lp_ctx; struct mapistore_output_ctx output_ctx; poptContext pc; int opt; const char *opt_profdb = NULL; char *opt_profname = NULL; const char *opt_password = NULL; uint32_t opt_maxsize = 0; const char *opt_mapistore = NULL; bool opt_showprogress = false; bool opt_dumpdata = false; const char *opt_debug = NULL; enum {OPT_PROFILE_DB=1000, OPT_PROFILE, OPT_PASSWORD, OPT_MAXDATA, OPT_SHOWPROGRESS, OPT_MAPISTORE, OPT_DEBUG, OPT_DUMPDATA}; struct poptOption long_options[] = { POPT_AUTOHELP {"database", 'f', POPT_ARG_STRING, NULL, OPT_PROFILE_DB, "set the profile database path", "PATH"}, {"profile", 'p', POPT_ARG_STRING, NULL, OPT_PROFILE, "set the profile name", "PROFILE"}, {"password", 'P', POPT_ARG_STRING, NULL, OPT_PASSWORD, "set the profile password", "PASSWORD"}, {"maxdata", 0, POPT_ARG_INT, NULL, OPT_MAXDATA, "the maximum transfer data size", "SIZE"}, {"showprogress", 0, POPT_ARG_NONE, NULL, OPT_SHOWPROGRESS, "enable progress display", NULL}, {"mapistore", 0, POPT_ARG_STRING, NULL, OPT_MAPISTORE, "serialise to mapistore", "FILESYSTEM_PATH"}, {"debuglevel", 'd', POPT_ARG_STRING, NULL, OPT_DEBUG, "set the debug level", "LEVEL"}, {"dump-data", 0, POPT_ARG_NONE, NULL, OPT_DUMPDATA, "dump the transfer data", NULL}, POPT_OPENCHANGE_VERSION { NULL, 0, POPT_ARG_NONE, NULL, 0, NULL, NULL } }; mem_ctx = talloc_named(NULL, 0, "check_fasttransfer"); pc = poptGetContext("check_fasttransfer", argc, argv, long_options, 0); while ((opt = poptGetNextOpt(pc)) != -1) { switch (opt) { case OPT_PROFILE_DB: opt_profdb = poptGetOptArg(pc); break; case OPT_PROFILE: opt_profname = talloc_strdup(mem_ctx, (char *)poptGetOptArg(pc)); break; case OPT_PASSWORD: opt_password = poptGetOptArg(pc); break; case OPT_MAXDATA: opt_maxsize = *poptGetOptArg(pc); break; case OPT_SHOWPROGRESS: opt_showprogress = true; break; case OPT_MAPISTORE: opt_mapistore = poptGetOptArg(pc); break; case OPT_DEBUG: opt_debug = poptGetOptArg(pc); break; case OPT_DUMPDATA: opt_dumpdata = true; break; } } /** * Sanity checks */ if (!opt_profdb) { opt_profdb = talloc_asprintf(mem_ctx, DEFAULT_PROFDB, getenv("HOME")); } /** * Initialize MAPI subsystem */ retval = MAPIInitialize(&mapi_ctx, opt_profdb); if (retval != MAPI_E_SUCCESS) { mapi_errstr("MAPIInitialize", retval); exit (1); } /* debug options */ SetMAPIDumpData(mapi_ctx, opt_dumpdata); if (opt_debug) { SetMAPIDebugLevel(mapi_ctx, atoi(opt_debug)); } /* if no profile is supplied use the default one */ if (!opt_profname) { retval = GetDefaultProfile(mapi_ctx, &opt_profname); if (retval != MAPI_E_SUCCESS) { printf("No profile specified and no default profile found\n"); exit (1); } } retval = MapiLogonEx(mapi_ctx, &session, opt_profname, opt_password); talloc_free(opt_profname); if (retval != MAPI_E_SUCCESS) { mapi_errstr("MapiLogonEx", retval); exit (1); } /* Open the default message store */ mapi_object_init(&obj_store); mapi_object_init(&obj_folder); /* mapi_object_init(&obj_table); */ mapi_object_init(&obj_fx_context); retval = OpenMsgStore(session, &obj_store); if (retval != MAPI_E_SUCCESS) { mapi_errstr("OpenMsgStore", retval); exit (1); } /* Open the top level folder */ retval = GetDefaultFolder(&obj_store, &id_folder, olFolderTopInformationStore); if (retval != MAPI_E_SUCCESS) { mapi_errstr("GetReceiveFolder", retval); exit (1); } retval = OpenFolder(&obj_store, id_folder, &obj_folder); if (retval != MAPI_E_SUCCESS) { mapi_errstr("OpenFolder", retval); exit (1); } retval = FXCopyFolder(&obj_folder, FastTransferCopyFolder_CopySubfolders, FastTransfer_Unicode, &obj_fx_context); if (retval != MAPI_E_SUCCESS) { mapi_errstr("FXCopyFolder", retval); exit (1); } if (opt_mapistore) { char *root_folder; // TODO: check the path is valid / exists / can be opened, etc. // TODO: maybe allow a URI instead of path. output_ctx.root_fid = 0x0000000000010001; output_ctx.current_id = output_ctx.root_fid; root_folder = talloc_asprintf(mem_ctx, "fsocpf://%s/0x%016"PRIx64, opt_mapistore, output_ctx.root_fid); parser = fxparser_init(mem_ctx, &output_ctx); mretval = mapistore_set_mapping_path(opt_mapistore); if (mretval != MAPISTORE_SUCCESS) { mapi_errstr("mapistore_set_mapping_path", retval); exit (1); } /* Initialize configuration */ lp_ctx = loadparm_init(mem_ctx); lpcfg_load_default(lp_ctx); output_ctx.mstore_ctx = mapistore_init(mem_ctx, lp_ctx, NULL); if (!(output_ctx.mstore_ctx)) { mapi_errstr("mapistore_init", retval); exit (1); } mretval = mapistore_add_context(output_ctx.mstore_ctx, "openchange", root_folder, output_ctx.root_fid, &(output_ctx.mapistore_context_id), &output_ctx.root_folder); if (mretval != MAPISTORE_SUCCESS) { DEBUG(0, ("%s\n", mapistore_errstr(mretval))); exit (1); } output_ctx.proplist = 0; fxparser_set_marker_callback(parser, mapistore_marker); fxparser_set_delprop_callback(parser, mapistore_delprop); fxparser_set_namedprop_callback(parser, mapistore_namedprop); fxparser_set_property_callback(parser, mapistore_property); } else if (opt_dumpdata) { parser = fxparser_init(mem_ctx, NULL); fxparser_set_marker_callback(parser, dump_marker); fxparser_set_delprop_callback(parser, dump_delprop); fxparser_set_namedprop_callback(parser, dump_namedprop); fxparser_set_property_callback(parser, dump_property); } else { parser = fxparser_init(mem_ctx, NULL); } do { retval = FXGetBuffer(&obj_fx_context, opt_maxsize, &fxTransferStatus, &progressCount, &totalStepCount, &transferdata); transfers++; if (retval != MAPI_E_SUCCESS) { mapi_errstr("FXGetBuffer", retval); exit (1); } if (opt_showprogress) { printf("progress: (%d/%d)\n", progressCount, totalStepCount); printf("status: 0x%04x\n", fxTransferStatus); } fxparser_parse(parser, &transferdata); } while ((fxTransferStatus == TransferStatus_Partial) || (fxTransferStatus == TransferStatus_NoRoom)); printf("total transfers: %i\n", transfers); if (opt_mapistore) { mretval = mapistore_del_context(output_ctx.mstore_ctx, output_ctx.mapistore_context_id); if (mretval != MAPISTORE_SUCCESS) { mapi_errstr("mapistore_del_context", mretval); exit (1); } mretval = mapistore_release(output_ctx.mstore_ctx); if (mretval != MAPISTORE_SUCCESS) { mapi_errstr("mapistore_release", mretval); exit (1); } } talloc_free(parser); mapi_object_release(&obj_fx_context); mapi_object_release(&obj_folder); mapi_object_release(&obj_store); MAPIUninitialize(mapi_ctx); talloc_free(mem_ctx); return 0; } openchange-2.0/testprogs/check_mbox.py000077500000000000000000000016451223057412600202030ustar00rootroot00000000000000#!/usr/bin/env python import argparse import mailbox import os import shutil import subprocess import tempfile mboxparser = argparse.ArgumentParser(description='Test an mbox file for general compatibility') mboxparser.add_argument('--mbox', required=True) args = mboxparser.parse_args() ###----------------------- print "Internal (python mailbox) parser:" print "\tmessage count", len(mailbox.mbox(args.mbox)) ###----------------------- print "mbox2eml:" emldir = tempfile.mkdtemp() print "\treturn code:", subprocess.call(["mbox2eml", "--input-file", args.mbox, "--output-dir", emldir]) print "\tmessage count", len(os.listdir(emldir)) shutil.rmtree(emldir, ignore_errors=True) ###----------------------- print "mailx:" p1 = subprocess.Popen(["mailx", "-H", "-f", args.mbox,], stdout=subprocess.PIPE) p2 = subprocess.Popen(["wc", "-l"], stdin=p1.stdout, stdout=subprocess.PIPE) print "\tmessage count", p2.communicate()[0] openchange-2.0/testprogs/fetch-nameid.c000066400000000000000000000132371223057412600202140ustar00rootroot00000000000000/* Fetch the nameid of a named property OpenChange Project Copyright (C) Wolfgang Sourdeau 2011 This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see . */ /* gcc fetch-nameid.c -o fetch-nameid -I /usr/local/samba/include * -L/usr/local/samba/lib -lmapi -ltalloc -lpopt -lndr */ #include #include #include "gen_ndr/exchange.h" #include "libmapi/libmapi.h" #include #include #include static void popt_openchange_version_callback(poptContext con, enum poptCallbackReason reason, const struct poptOption *opt, const char *arg, const void *data) { switch (opt->val) { case 'V': printf("Version %s\n", OPENCHANGE_VERSION_STRING); exit (0); } } struct poptOption popt_openchange_version[] = { { NULL, '\0', POPT_ARG_CALLBACK, (void *)popt_openchange_version_callback, '\0', NULL, NULL }, { "version", 'V', POPT_ARG_NONE, NULL, 'V', "Print version ", NULL }, POPT_TABLEEND }; #define DEFAULT_PROFDB "%s/.openchange/profiles.ldb" int main(int argc, const char *argv[]) { TALLOC_CTX *mem_ctx; enum MAPISTATUS retval; struct mapi_context *mapi_ctx; struct mapi_session *session = NULL; mapi_object_t obj_store, obj_folder; uint32_t prop_id; uint64_t query_fid = 0; poptContext pc; int opt; const char *prop_id_str; const char *opt_profdb = NULL; char *opt_profname = NULL; const char *opt_password = NULL; const char *opt_folder_id = NULL; enum {OPT_PROFILE_DB=1000, OPT_PROFILE, OPT_PASSWORD, OPT_FOLDER_ID}; struct poptOption long_options[] = { POPT_AUTOHELP {"database", 0, POPT_ARG_STRING, NULL, OPT_PROFILE_DB, "set the profile database path", "PATH"}, {"profile", 'p', POPT_ARG_STRING, NULL, OPT_PROFILE, "set the profile name", "PROFILE"}, {"password", 'P', POPT_ARG_STRING, NULL, OPT_PASSWORD, "set the profile password", "PASSWORD"}, {"folder-id", 'F', POPT_ARG_STRING, NULL, OPT_FOLDER_ID, "folder id to query (mandatory)", "FOLDER_ID"}, { NULL, 0, POPT_ARG_INCLUDE_TABLE, popt_openchange_version, 0, "Common openchange options:", NULL }, { NULL, 0, POPT_ARG_NONE, NULL, 0, NULL, NULL } }; mem_ctx = talloc_named(NULL, 0, "test-folders"); pc = poptGetContext("fetch-nameid", argc, argv, long_options, 0); while ((opt = poptGetNextOpt(pc)) != -1) { switch (opt) { case OPT_PROFILE_DB: opt_profdb = poptGetOptArg(pc); break; case OPT_PROFILE: opt_profname = talloc_strdup(mem_ctx, (char *)poptGetOptArg(pc)); break; case OPT_PASSWORD: opt_password = poptGetOptArg(pc); break; case OPT_FOLDER_ID: opt_folder_id = poptGetOptArg(pc); break; } } /** * Sanity checks */ if (!opt_profdb) { opt_profdb = talloc_asprintf(mem_ctx, DEFAULT_PROFDB, getenv("HOME")); } /** * Initialize MAPI subsystem */ retval = MAPIInitialize(&mapi_ctx, opt_profdb); if (retval != MAPI_E_SUCCESS) { mapi_errstr("MAPIInitialize", retval); exit (1); } /* if no profile is supplied use the default one */ if (!opt_profname) { retval = GetDefaultProfile(mapi_ctx, &opt_profname); if (retval != MAPI_E_SUCCESS) { printf("No profile specified and no default profile found\n"); exit (1); } } retval = MapiLogonEx(mapi_ctx, &session, opt_profname, opt_password); talloc_free(opt_profname); if (retval != MAPI_E_SUCCESS) { mapi_errstr("MapiLogonEx", retval); exit (1); } if (!opt_folder_id) { fprintf (stderr, "Folder ID parameter is required.\n"); exit (1); } query_fid = strtoull(opt_folder_id, NULL, 0); prop_id_str = poptGetArg(pc); if (!prop_id_str) { fprintf (stderr, "Property ID parameter is required.\n"); exit (1); } prop_id = strtol(prop_id_str, NULL, 0); if ((prop_id & 0xffff) == prop_id) { prop_id <<= 16; } /* Open the default message store */ mapi_object_init(&obj_store); retval = OpenMsgStore(session, &obj_store); if (retval != MAPI_E_SUCCESS) { mapi_errstr("OpenMsgStore", retval); exit (1); } mapi_object_init(&obj_folder); retval = OpenFolder(&obj_store, query_fid, &obj_folder); if (retval != MAPI_E_SUCCESS) { mapi_errstr("OpenFolder", retval); exit (1); } { uint16_t pcount; struct MAPINAMEID *nameid; GetNamesFromIDs(&obj_folder, prop_id, &pcount, &nameid); if (pcount) { char *guid; printf ("type: %s\n", (nameid->ulKind == MNID_ID ? "id" : "string")); guid = GUID_string2(mem_ctx, &nameid->lpguid); printf ("guid: %s\n", guid); switch(nameid->ulKind) { case MNID_ID: printf ("lid: %.8x\n", nameid->kind.lid); break; case MNID_STRING: printf ("name: %*s\n", nameid->kind.lpwstr.NameSize, nameid->kind.lpwstr.Name); break; }; } else { printf ("property not found\n"); } } Release(&obj_folder); /* mapi_object_release(&obj_msg2); */ mapi_object_release(&obj_folder); mapi_object_release(&obj_store); MAPIUninitialize(mapi_ctx); talloc_free(mem_ctx); return 0; } openchange-2.0/testprogs/globset.py000066400000000000000000000110511223057412600175250ustar00rootroot00000000000000class GLOBSetRunner: def __init__(self, buffer, pos): self.buffer = buffer self.start_pos = pos self.pos = pos self.end = False self.stack = [] self.stackByteLength = 0 self.ranges = [] def _doPush1(self): self._doPush(1) def _doPush2(self): self._doPush(2) def _doPush3(self): self._doPush(3) def _doPush4(self): self._doPush(4) def _doPush5(self): self._doPush(5) def _doPush6(self): self._doPush(6) def _doPush(self, nbr): bytes = self.buffer[self.pos:self.pos+nbr] # print "push %d bytes: (%s)" % (nbr, ", ".join(["0x%.2x" % ord(x) for x in bytes])) self.stack.append(bytes) self.stackByteLength = self.stackByteLength + nbr self.pos = self.pos + nbr if self.stackByteLength == 6: # print " buffer filled" self._doRange() self._doPop() def _doPop(self): bytes = self.stack.pop() nbr = len(bytes) # print "popped %d bytes" % nbr self.stackByteLength = self.stackByteLength - nbr def _doBitmask(self): combined = self._rangeValue("".join(self.stack) + self.buffer[self.pos]) mask = ord(self.buffer[self.pos+1]) self.pos = self.pos + 2 blank = False lowValue = combined highValue = lowValue # print "doBitmask: start (start: %x)" % lowValue for x in xrange(8): bit = 1 << x # print "mask: %s; bit: %s" % (bin(mask), bin(bit)) if blank: if (mask & bit) != 0: blank = False lowValue = combined + ((x + 1) << 40) highValue = lowValue # print "doBitmask: new record (ends: %x)" % lowValue else: if (mask & bit) == 0: # print "doBitmask: commit: [%.12x:%.12x]" % (lowValue, highValue) self.ranges.append((lowValue, highValue)) blank = True else: highValue = combined + ((x + 1) << 40) # print "doBitmask: extending range (highValue: %x)" % highValue if not blank: self.ranges.append((lowValue, highValue)) def _doRange(self): nbr = 6 - self.stackByteLength combined = "".join(self.stack) if nbr > 0: # print "pair covering %d bytes" % nbr lowValue = self._rangeValue(combined + self.buffer[self.pos:self.pos+nbr]) self.pos = self.pos + nbr highValue = self._rangeValue(combined + self.buffer[self.pos:self.pos+nbr]) self.pos = self.pos + nbr elif nbr == 0: # print "singleton (implied)" lowValue = self._rangeValue(combined) highValue = lowValue else: raise Exception, "reached negative range count" # print "doRange: [%.12x:%.12x]" % (lowValue, highValue) self.ranges.append((lowValue, highValue)) def _rangeValue(self, bytes): value = 0 base = 1 for x in bytes: value = value + ord(x) * base base = base * 256 return value def _doEnd(self): # print "end reached" self.end = True if len(self.stack) > 0: raise Exception, "stack should be empty" def run(self): command_methods = { 0x01: self._doPush1, 0x02: self._doPush2, 0x03: self._doPush3, 0x04: self._doPush4, 0x05: self._doPush5, 0x06: self._doPush6, 0x50: self._doPop, 0x42: self._doBitmask, 0x52: self._doRange, 0x00: self._doEnd } while not self.end: command = ord(self.buffer[self.pos]) if command_methods.has_key(command): self.pos = self.pos + 1 command_method = command_methods[command] command_method() else: # print "buffer: %s..." % ["%.2x" % ord(x) for x in self.buffer[self.start_pos:self.pos]] # for x in self.ranges: # print "[%.12x:%.12x]" % x raise Exception, "unknown command: %x at pos %d" % (command, self.pos) return (self.pos - self.start_pos) openchange-2.0/testprogs/list-folders.c000066400000000000000000000261271223057412600203010ustar00rootroot00000000000000/* List the system and special folders for the user mailbox OpenChange Project Copyright (C) Wolfgang Sourdeau 2011 This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see . */ /* gcc list-folders.c -o list-folders -I /usr/local/samba/include -L /usr/local/samba/lib -lmapi -ltalloc -lpopt */ #include #include #include "gen_ndr/exchange.h" #include "libmapi/libmapi.h" #include #include #include static void popt_openchange_version_callback(poptContext con, enum poptCallbackReason reason, const struct poptOption *opt, const char *arg, const void *data) { switch (opt->val) { case 'V': printf("Version %s\n", OPENCHANGE_VERSION_STRING); exit (0); } } struct poptOption popt_openchange_version[] = { { NULL, '\0', POPT_ARG_CALLBACK, (void *)popt_openchange_version_callback, '\0', NULL, NULL }, { "version", 'V', POPT_ARG_NONE, NULL, 'V', "Print version ", NULL }, POPT_TABLEEND }; #define DEFAULT_PROFDB "%s/.openchange/profiles.ldb" static uint64_t GetGlobalCounter(uint8_t *ptr) { uint64_t id, base; uint8_t i; id = 0; base = 1; for (i = 0; i < 6; i++) { id += *(ptr + i) * base; base <<= 8; } return id; } static void ShowBinaryEntryId(struct Binary_r *bin) { uint64_t id; id = GetGlobalCounter(bin->lpb + 38); printf("0x%.12"PRIx64"\n", id); } static void ShowSimpleEntryId(const char *label, struct SPropValue *value) { printf("%25s: ", label); if ((value->ulPropTag & 0xffff) == PT_BINARY) { ShowBinaryEntryId(&value->value.bin); } else { printf("(not available)\n"); } } static void ShowAdditionalRenEntryIds(struct SPropValue *value) { struct BinaryArray_r *mbin; struct Binary_r *bin; uint8_t i; const char *names[] = { "Conflicts", "Sync Issues", "Local Failures", "Server Failures", "Junk E-mail" }; if ((value->ulPropTag & 0xffff) == PT_MV_BINARY) { mbin = &value->value.MVbin; for (i = 0; i < mbin->cValues; i++) { if (i < 5) { printf("%25s: ", names[i]); bin = mbin->lpbin + i; if (bin->cb == 46) { ShowBinaryEntryId(mbin->lpbin + i); } else { printf("skipped\n"); } } } } else { printf("'AdditionalRenEntryIds' not available\n"); } } struct PersistDataArray { struct PersistData *data; uint16_t PersistDataCount; }; struct PersistData { uint16_t PersistID; uint16_t DataElementsSize; struct PersistElement *DataElements; uint16_t DataElementsCount; struct PersistData *next; struct PersistData *prev; }; struct PersistElement { uint16_t ElementID; uint16_t ElementDataSize; uint8_t *ElementData; struct PersistElement *next; struct PersistElement *prev; }; static inline uint16_t ReadWord(const uint8_t *ptr) { uint16_t w; w = *ptr; w += *(ptr + 1) << 8; return w; } static uint8_t *ReadPersistElement(TALLOC_CTX *mem_ctx, struct PersistElement **elementp, uint8_t *ptr, uint16_t max_size) { uint8_t *newptr; uint16_t size; struct PersistElement *element = NULL; if (max_size > 4) { size = max_size; newptr = ptr; element = talloc_zero(mem_ctx, struct PersistElement); element->ElementID = ReadWord(newptr); newptr += 2; element->ElementDataSize = ReadWord(newptr); newptr += 2; size = element->ElementDataSize; if (size > 0) { element->ElementData = talloc_memdup(element, newptr, size); } } else { newptr = NULL; } *elementp = element; return newptr; } static uint8_t *ReadPersistData(TALLOC_CTX *mem_ctx, struct PersistData **datap, uint8_t *ptr, uint16_t max_size) { uint8_t *newptr, *newnewptr; uint16_t size; struct PersistData *data = NULL; struct PersistElement *element; if (max_size > 4) { size = max_size; newptr = ptr; data = talloc_zero(mem_ctx, struct PersistData); data->PersistID = 0; data->PersistID = ReadWord(newptr); newptr += 2; data->DataElementsSize = ReadWord(newptr); newptr += 2; size = data->DataElementsSize; while (size > 0) { newnewptr = ReadPersistElement(data, &element, newptr, size); if (newnewptr) { size -= (newnewptr - newptr); newptr = newnewptr; DLIST_ADD_END(data->DataElements, element, void); data->DataElementsCount++; } else { size = 0; } } } else { newptr = NULL; } *datap = data; return newptr; } static struct PersistDataArray *BinToPersistData(TALLOC_CTX *mem_ctx, struct Binary_r *bin) { struct PersistDataArray *array; struct PersistData *data; uint8_t *ptr, *newptr; uint16_t size; size = bin->cb; ptr = bin->lpb; if (size > 0) { array = talloc_zero(mem_ctx, struct PersistDataArray); while (size > 0) { newptr = ReadPersistData(array, &data, ptr, size); if (newptr) { size -= (newptr - ptr); ptr = newptr; DLIST_ADD_END(array->data, data, void); array->PersistDataCount++; } else { size = 0; } } } else { array = NULL; } return array; } static void ShowAdditionalRenEntryIdsEx(struct SPropValue *value) { struct Binary_r *bin; struct PersistDataArray *array; bin = &value->value.bin; if (value->ulPropTag == PidTagAdditionalRenEntryIdsEx && bin->cb > 0) { bin = &value->value.bin; array = BinToPersistData(NULL, bin); talloc_free(array); } else { printf("'AdditionalRenEntryIdsEx' not available\n"); } } int main(int argc, const char *argv[]) { TALLOC_CTX *mem_ctx; enum MAPISTATUS retval; struct mapi_context *mapi_ctx; struct mapi_session *session = NULL; mapi_object_t obj_store, obj_folder; struct mapi_obj_store *store; struct SPropTagArray folder_props; enum MAPITAGS folder_properties[] = { PidTagIpmAppointmentEntryId, PidTagIpmContactEntryId, PidTagIpmJournalEntryId, PidTagIpmNoteEntryId, PidTagIpmTaskEntryId, PidTagRemindersOnlineEntryId, PidTagRemindersOfflineEntryId, PidTagIpmDraftsEntryId, PidTagAdditionalRenEntryIds, PidTagAdditionalRenEntryIdsEx }; struct SPropValue *folder_values; uint32_t folder_value_count; poptContext pc; int opt; const char *opt_profdb = NULL; char *opt_profname = NULL; const char *opt_password = NULL; enum {OPT_PROFILE_DB=1000, OPT_PROFILE, OPT_PASSWORD}; struct poptOption long_options[] = { POPT_AUTOHELP {"database", 'f', POPT_ARG_STRING, NULL, OPT_PROFILE_DB, "set the profile database path", "PATH"}, {"profile", 'p', POPT_ARG_STRING, NULL, OPT_PROFILE, "set the profile name", "PROFILE"}, {"password", 'P', POPT_ARG_STRING, NULL, OPT_PASSWORD, "set the profile password", "PASSWORD"}, { NULL, 0, POPT_ARG_INCLUDE_TABLE, popt_openchange_version, 0, "Common openchange options:", NULL }, { NULL, 0, POPT_ARG_NONE, NULL, 0, NULL, NULL } }; mem_ctx = talloc_named(NULL, 0, "list-folders"); pc = poptGetContext("list-folders", argc, argv, long_options, 0); while ((opt = poptGetNextOpt(pc)) != -1) { switch (opt) { case OPT_PROFILE_DB: opt_profdb = poptGetOptArg(pc); break; case OPT_PROFILE: opt_profname = talloc_strdup(mem_ctx, (char *)poptGetOptArg(pc)); break; case OPT_PASSWORD: opt_password = poptGetOptArg(pc); break; } } /** * Sanity checks */ if (!opt_profdb) { opt_profdb = talloc_asprintf(mem_ctx, DEFAULT_PROFDB, getenv("HOME")); } /** * Initialize MAPI subsystem */ retval = MAPIInitialize(&mapi_ctx, opt_profdb); if (retval != MAPI_E_SUCCESS) { mapi_errstr("MAPIInitialize", retval); exit (1); } /* if no profile is supplied use the default one */ if (!opt_profname) { retval = GetDefaultProfile(mapi_ctx, &opt_profname); if (retval != MAPI_E_SUCCESS) { printf("No profile specified and no default profile found\n"); exit (1); } } retval = MapiLogonEx(mapi_ctx, &session, opt_profname, opt_password); talloc_free(opt_profname); if (retval != MAPI_E_SUCCESS) { mapi_errstr("MapiLogonEx", retval); exit (1); } /* Open the default message store */ mapi_object_init(&obj_store); retval = OpenMsgStore(session, &obj_store); if (retval != MAPI_E_SUCCESS) { mapi_errstr("OpenMsgStore", retval); exit (1); } store = (struct mapi_obj_store *)obj_store.private_data; printf("System folders (RopLogon):\n"); printf("%25s: 0x%.12"PRIx64"\n", "Inbox", store->fid_inbox >> 16); printf("%25s: 0x%.12"PRIx64"\n", "Root", store->fid_mailbox_root >> 16); printf("%25s: 0x%.12"PRIx64"\n", "Deferred Actions", store->fid_deferred_actions >> 16); printf("%25s: 0x%.12"PRIx64"\n", "Spooler Queue", store->fid_spooler_queue >> 16); printf("%25s: 0x%.12"PRIx64"\n", "Top Information Store", store->fid_top_information_store >> 16); printf("%25s: 0x%.12"PRIx64"\n", "Outbox", store->fid_outbox >> 16); printf("%25s: 0x%.12"PRIx64"\n", "Sent Items", store->fid_sent_items >> 16); printf("%25s: 0x%.12"PRIx64"\n", "Deleted Items", store->fid_deleted_items >> 16); printf("%25s: 0x%.12"PRIx64"\n", "Common Views", store->fid_common_views >> 16); printf("%25s: 0x%.12"PRIx64"\n", "Schedule", store->fid_schedule >> 16); printf("%25s: 0x%.12"PRIx64"\n", "Search", store->fid_search >> 16); printf("%25s: 0x%.12"PRIx64"\n", "Views", store->fid_views >> 16); printf("%25s: 0x%.12"PRIx64"\n", "Shortcuts", store->fid_shortcuts >> 16); mapi_object_init(&obj_folder); retval = OpenFolder(&obj_store, store->fid_inbox, &obj_folder); if (retval != MAPI_E_SUCCESS) { mapi_errstr("OpenFolder", retval); exit (1); } folder_props.cValues = sizeof(folder_properties) / sizeof(enum MAPITAGS); folder_props.aulPropTag = folder_properties; retval = GetProps(&obj_folder, 0, &folder_props, &folder_values, &folder_value_count); if (retval != MAPI_E_SUCCESS) { mapi_errstr("GetProps", retval); exit (1); } printf("\n"); printf("Folder entries:\n"); ShowSimpleEntryId("Calendar", folder_values + 0); ShowSimpleEntryId("Contacts", folder_values + 1); ShowSimpleEntryId("Journal", folder_values + 2); ShowSimpleEntryId("Note", folder_values + 3); ShowSimpleEntryId("Tasks", folder_values + 4); ShowSimpleEntryId("Reminders (online)", folder_values + 5); ShowSimpleEntryId("Reminders (offline)", folder_values + 6); ShowSimpleEntryId("Drafts", folder_values + 7); printf("\n"); printf("Additional entries:\n"); ShowAdditionalRenEntryIds(folder_values + 8); /* FIXME: buggy code should be reviewed */ /* printf("\n"); */ /* printf("Extended additional entries:\n"); */ /* ShowAdditionalRenEntryIdsEx(folder_values + 9); */ Release(&obj_folder); /* mapi_object_release(&obj_msg2); */ mapi_object_release(&obj_folder); mapi_object_release(&obj_store); MAPIUninitialize(mapi_ctx); talloc_free(mem_ctx); return 0; } openchange-2.0/testprogs/parse-getprops.py000077500000000000000000000221121223057412600210440ustar00rootroot00000000000000#!/usr/bin/python # # parse-getprops.py # # Copyright (C) Wolfgang Sourdeau 2010 # # This program is free software; you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by # the Free Software Foundation; either version 3 of the License, or # (at your option) any later version. # # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program. If not, see . # this script parses a debugging samba log and displays the replies to # RopGetProps in human readable form # usage: ./parse-getprops.py output.log import struct import sys import time PARSER_START, PARSER_PREREQUEST, PARSER_REQUEST, PARSER_BETWEEN, PARSER_PRERESPONSE, PARSER_RESPONSE, PARSER_DONE = range(7) class GetPropsParser: def __init__(self, lines, pos = 0): self.lines = lines self.columns = [] self.state = PARSER_START self.pos = pos self.layout = False self.response = None self.responses = [] def run(self): while self.pos < len(self.lines) and self.state != PARSER_DONE: line = self.lines[self.pos] if self.state == PARSER_START: if line.find("mapi_GetProps: struct GetProps_req") > -1: self.state = PARSER_PREREQUEST elif self.state == PARSER_PREREQUEST: if line.find("properties: ARRAY(") > -1: self.state = PARSER_REQUEST elif self.state == PARSER_REQUEST: match = "properties : "; matchIdx = line.find(match) if matchIdx > -1: propIdx = matchIdx + len(match) self._registerColumn(line[propIdx:]) else: self.state = PARSER_BETWEEN elif self.state == PARSER_BETWEEN: if line.find("mapi_GetProps: struct GetProps_repl") > -1: self.state = PARSER_PRERESPONSE elif self.state == PARSER_PRERESPONSE: if line.find("prop_data") > -1: self.state = PARSER_RESPONSE self.response = "" elif line.find("layout") > -1: self.layout = (line.find(": 0x01") > -1) elif self.state == PARSER_RESPONSE: if line.find("[") == 0: # print "appending %s" % line[0:-1] self._appendResponse(line) else: self._printResponse() self.response = None self.layout = False self.state = PARSER_DONE self.pos = self.pos + 1 if self.state != PARSER_DONE: self.pos = -1 return self.pos def _registerColumn(self, remain): spaceIdx = remain.find(" ") propName = remain[0:spaceIdx] parenCloseIdx = remain.find(")") propTag = remain[spaceIdx+2:parenCloseIdx] propTagInt = int(propTag, 16) if propName == "UNKNOWN_ENUM_VALUE": propName = propTag newColumn = { "name": propName, "tag": propTagInt } self.columns.append(newColumn) def _appendResponse(self, line): pos = 6; maxLength = 56 done = False while not done: it = 0 while it < 8 and not done: responseByte = line[pos+1:pos+3] if pos > maxLength or responseByte.strip() == "": done = True else: self._appendResponseByte(responseByte) it = it + 1 pos = pos + 3 pos = pos + 2 def _appendResponseByte(self, byteData): charValue = chr(int(byteData, 16)) self.response = self.response + charValue def _printResponse(self): length = len(self.response) pos = 0 for column in self.columns: pos = pos + self._printResponseColumn(column, pos) if self.layout: pos = pos + 1 def _printResponseColumn(self, column, pos): colType = column["tag"] & 0xffff; print "pos: %d" % pos if self.layout: flag = ord(self.response[pos]) pos = pos + 1 if flag == 0x0a: colType = 0x0a elif flag != 0x00: raise Exception, "Unhandled flag value: %d" % flag else: flag = 0 print "%s:" % column["name"], return self._printValue(pos, colType) def _printValue(self, pos, colType): if colType == 0xb: consumed = self._printBool(pos) elif colType == 0x2: consumed = self._printShort(pos) elif colType == 0x3: consumed = self._printLong(pos, False) elif colType == 0x5: consumed = self._printDouble(pos) elif colType == 0x0a: consumed = self._printLong(pos, True) elif colType == 0x14: consumed = self._printLong8(pos) elif colType == 0x1f: consumed = self._printString(pos) elif colType == 0x40: consumed = self._printSysTime(pos) elif (colType == 0x0102 or colType == 0xfb): consumed = self._printBinary(pos) elif (colType & 0x1000): consumed = self._printMultiValue(pos, colType) else: raise Exception, "Unhandled column type: 0x%.4x" % colType return consumed def _printBool(self, pos): print "(PT_BOOL)", if self.response[pos] == "\0": print "false" else: print "true" return 1 def _printShort(self, pos): shortValue = struct.unpack_from(" 8: deltaSpace = "" delta = 8 else: deltaSpace = " " * (8 - delta) codes = [] chars = "" for x in xrange(delta): ordX = ord(self.response[pos + x]) codes.append("%.2x" % ordX) if ordX > 31 and ordX < 128: chars = chars + "%3s " % self.response[pos + x] else: chars = chars + "\\x%.2x " % ordX print "%s %s| %s" % (" ".join(codes), deltaSpace, chars) pos = pos + delta return 2 + length def _printMultiValue(self, pos, colType): length = struct.unpack_from(" 1: logfile = open(sys.argv[1], "r") lines = logfile.readlines() logfile.close() pos = 0 while pos < len(lines) and pos != -1: print "parsing getprops" p = GetPropsParser(lines, pos) pos = p.run() print "" openchange-2.0/testprogs/parse-syncbuffer.py000077500000000000000000000430061223057412600213540ustar00rootroot00000000000000#!/usr/bin/python # # parse-syncbuffer.py # # Copyright (C) Wolfgang Sourdeau 2011 # # This program is free software; you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by # the Free Software Foundation; either version 3 of the License, or # (at your option) any later version. # # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program. If not, see . # this script parses a debugging samba log and displays the replies to # RopFastTransferSourceGetBuffer in human readable form # usage: ./parse-syncbuffer.py output.log # warning: 'PropFile' should be adjusted below import codecs import struct import sys import time from globset import GLOBSetRunner PARSER_START, PARSER_PRERESPONSE, PARSER_RESPONSE, PARSER_DONE = range(4) MarkerTags = { 0x40090003: "PidTagStartTopFld", 0x400B0003: "PidTagEndFolder", 0x400A0003: "PidTagStartSubFld", 0x400C0003: "PidTagStartMessage", 0x400D0003: "PidTagEndMessage", 0x40100003: "PidTagStartFAIMsg", 0x40010003: "PidTagStartEmbed", 0x40020003: "PidTagEndEmbed", 0x40030003: "PidTagStartRecip", 0x40040003: "PidTagEndToRecip", 0x40000003: "PidTagNewAttach", 0x400E0003: "PidTagEndAttach", 0x40120003: "PidTagIncrSyncChg", 0x407D0003: "PidTagIncrSyncChgPartial", 0x40130003: "PidTagIncrSyncDel", 0x40140003: "PidTagIncrSyncEnd", 0x402F0003: "PidTagIncrSyncRead", 0x403A0003: "PidTagIncrSyncStateBegin", 0x403B0003: "PidTagIncrSyncStateEnd", 0x4074000B: "PidTagIncrSyncProgressMode", 0x4075000B: "PidTagIncrSyncProgressPerMsg", 0x40150003: "PidTagIncrSyncMessage", 0x407B0102: "PidTagIncrSyncGroupInfo", 0x40180003: "PidTagFXErrorInfo" } ICSStateProperties = { 0x40170003: "PidTagIdsetGiven", 0x67960102: "PidTagCnsetSeen", 0x67da0102: "PidTagCnsetSeenFAI", 0x67d20102: "PidTagCnsetRead" } DeltaStateProperties = { 0x67e50102: "PidTagIdsetDeleted", 0x40210102: "PidTagIdsetNoLongerInScope", 0x67930102: "PidTagIdsetExpired", 0x402d0102: "PidTagIdsetRead", 0x402e0102: "PidTagIdsetUnread" } PropFile = "/home/wsourdeau/src/openchange/libmapi/conf/mapi-properties" Properties = None PropertyTypes = { 0x0000: "PT_UNSPECIFIED", 0x0001: "PT_NULL", 0x0002: "PT_SHORT", 0x0003: "PT_LONG", 0x0005: "PT_DOUBLE", 0x000a: "PT_ERROR", 0x000b: "PT_BOOL", 0x0014: "PT_LONG8", 0x001e: "PT_STRING", 0x001f: "PT_UNICODE", 0x0040: "PT_SYSTIME", 0x0048: "PT_CLSID", 0x00fb: "PT_SVREID", 0x0102: "PT_BINARY" } def ReadProperties(filename): props = {} pFile = open(PropFile, "r") pLines = pFile.readlines() for line in pLines: if line.startswith("0x"): idx = line.find(" ") propTag = int(line[0:idx], 16) while line[idx] == " ": idx = idx + 1 nameEndIdx = line.find(" ", idx) if nameEndIdx < 0: nameEndIdx = line.find("\t", idx) if nameEndIdx < 0: nameEndIdx = len(line) - 1 propName = line[idx:nameEndIdx] props[propTag] = propName propType = propTag & 0xffff if propType == 0x1e: propTag = (propTag & 0xffff0000 | 0x1f) propName = propName + "_UNICODE" props[propTag] = propName return props class SyncBufferParser: def __init__(self, lines, pos = 0): self.lines = lines self.state = PARSER_START self.pos = pos self.lastBlock = False self.buffer = None self.bufferLines = None def run(self): self.bufferLines = [] state_methods = { PARSER_START: self._doParserStart, PARSER_PRERESPONSE: self._doParserPreResponse, PARSER_RESPONSE: self._doParserResponse } while self.pos < len(self.lines) and self.state != PARSER_DONE: state_methods[self.state](self.lines[self.pos]) self.pos = self.pos + 1 if self.state == PARSER_DONE: self.buffer = ''.join(self.bufferLines) else: self.pos = -1 return self.pos def force(self): self.buffer = ''.join(self.bufferLines) def _doParserStart(self, line): if line.find("mapi_FastTransferSourceGetBuffer: struct FastTransferSourceGetBuffer_repl") > -1: self.state = PARSER_PRERESPONSE def _doParserPreResponse(self, line): if line.find("TransferStatus") > -1: if line.find("TransferStatus_Done") > -1: self.lastBlock = True elif line.find("DATA_BLOB") > -1: self.state = PARSER_RESPONSE def _doParserResponse(self, line): if line.find("[") == 0: # print "appending %s" % line[0:-1] self._appendResponse(line) else: if self.lastBlock: self.state = PARSER_DONE else: self.state = PARSER_START def _appendResponse(self, line): pos = 6; maxLength = 56 done = False parsed = [] while not done: it = 0 while it < 8 and not done: responseByte = line[pos+1:pos+3] if pos > maxLength or responseByte.strip() == "": done = True else: charValue = chr(int(responseByte, 16)) parsed.append(charValue) it = it + 1 pos = pos + 3 pos = pos + 2 self.bufferLines.append(''.join(parsed)) class SyncBufferPrinter: def __init__(self, data): self.data = data def run(self): length = len(self.data) pos = 0 while pos < length: tagstr = self.data[pos:pos+4] tag = struct.unpack(" 0x80000000: consumed = self._printNamedPropValue(pos, multiState | colType) else: consumed = self._printValue(pos, multiState | colType) return consumed def _printPredecessorChangeList(self, pos): length = struct.unpack_from(" 0: print "XID (%d):" % length self._printXID(pos + 4, length) else: print "(length: %d, skipped)" % length return 4 + length def _printXID(self, pos, size): print " namespace GUID:", pos = pos + self._printGUID(pos) if size > 16: localid = "" remain = size - 16 while remain > 0: remain = remain - 1 localid = localid + "%.2x" % ord(self.data[pos+remain]) print " localid: 0x%s" % localid else: print "(size: %d, skipped)" % size def _printNamedPropValue(self, pos, colType): print "\n named prop\n guid:", consumed = self._printGUID(pos) namedPropType = ord(self.data[pos + consumed]) consumed = consumed + 1 if namedPropType == 0x00: print " dispid:", consumed = consumed + self._printValue(pos + consumed, 0x0003) elif namedPropType == 0x01: print " name:", consumed = consumed + self._printNamedPropName(pos + consumed) else: raise Exception, "Invalid named prop type: %d" % namedPropType print " ", consumed = consumed + self._printValue(pos + consumed, colType) return consumed def _printNamedPropName(self, pos): length = 0 byteValue = "" while (ord(self.data[pos + length]) != 0 or ord(self.data[pos + 1 + length]) != 0): byteValue = (byteValue + self.data[pos + length] + self.data[pos + length + 1]) length = length + 2 stringValue = byteValue.decode("utf-16") stringLength = len(stringValue) print "(%d chars): \"%s\"" % (stringLength, stringValue) return length + 2 def _printValue(self, pos, colType): base_methods = { 0x0002: self._printShort, 0x0003: self._printLong, 0x0005: self._printDouble, 0x000a: self._printLong, 0x000b: self._printBool, 0x0014: self._printLong8, 0x001e: self._printString, 0x001f: self._printUnicode, 0x0040: self._printSysTime, 0x0048: self._printGUID, 0x00fb: self._printBinary, 0x0102: self._printBinary } if base_methods.has_key(colType): method = base_methods[colType] consumed = method(pos) elif (colType & 0x1000): consumed = self._printMultiValue(pos, colType) else: raise Exception, "Unhandled column type: 0x%.4x" % colType return consumed def _printShort(self, pos): shortValue = struct.unpack_from(" 0: seconds = (nano100Seconds / 10000000) if (seconds > 11644473600): print time.strftime("%a, %d %b %Y %T %z", time.localtime(seconds - 11644473600)) else: print "%d seconds" % seconds else: print "empty time" return 8 def _printGUID(self, pos): start = struct.unpack_from("HHL", self.data, pos + 8) print "{%.8x-%.4x-%.4x-%.4x-%.4x%.8x}" % (start + final) return 16 def _printBinary(self, pos): length = struct.unpack_from(" 8: deltaSpace = "" delta = 8 else: deltaSpace = " " * (8 - delta) codes = [] chars = "" for x in xrange(delta): value = self.data[pos + x] ordValue = ord(value) codes.append("%.2x" % ordValue) if ordValue > 31 and ordValue < 128: chars = chars + "%3s " % value else: chars = chars + "\\x%.2x " % ordValue print " %s %s| %s" % (" ".join(codes), deltaSpace, chars) pos = pos + delta return 4 + length def _printMultiValue(self, pos, colType): length = struct.unpack_from("" % x, consumed = consumed + self._printValue(pos + consumed, subType) return consumed def _printIDSet(self, pos, short = False): length = struct.unpack_from(" 1: if not sys.stdout.isatty(): streamWriter = codecs.getwriter('utf8') sys.stdout = streamWriter(sys.stdout) if not sys.stderr.isatty(): streamWriter = codecs.getwriter('utf8') sys.stderr = streamWriter(sys.stderr) Properties = ReadProperties(PropFile) logfile = open(sys.argv[1], "r") lines = logfile.readlines() logfile.close() pos = 0 while pos < len(lines) and pos != -1: parser = SyncBufferParser(lines, pos) pos = parser.run() if pos == -1 and len(parser.bufferLines) > 0: parser.force() pos = 0xffffffff print "(forced parser)" if pos != -1: p = SyncBufferPrinter(parser.buffer) p.run() print "" openchange-2.0/testprogs/parse-uploadstream.py000077500000000000000000000072161223057412600217110ustar00rootroot00000000000000#!/usr/bin/python # # parse-uploadstream.py # # Copyright (C) Wolfgang Sourdeau 2011 # # This program is free software; you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by # the Free Software Foundation; either version 3 of the License, or # (at your option) any later version. # # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program. If not, see . # this script parses a debugging samba log and displays the replies to # RopSyncUploadStateStream* in human readable form # usage: ./parse-uploadstream.py output.log import struct import sys from globset import GLOBSetRunner PARSER_START,\ PARSER_START_BEGINSTREAM,\ PARSER_END_BEGINSTREAM,\ PARSER_START_CONTINUESTREAM,\ PARSER_CONTINUE_CONTINUESTREAM,\ PARSER_END_CONTINUESTREAM,\ PARSER_DONE = range(7) class UploadStreamBufferParser: def __init__(self): self.bytes = [] self.property = None self.state = PARSER_START def run(self, lines): count = 0 maxlines = len(lines) methods = [ self._doStart, self._doStartBeginStream, self._doEndBeginStream, self._doStartContinueStream, self._doContinueContinueStream ] while self.state != PARSER_DONE: line = lines[count] methods[self.state](line) count = count + 1 return "".join(self.bytes) def _doStart(self, line): if line.find("struct SyncUploadStateStreamBegin_req") > -1: self.state = PARSER_START_BEGINSTREAM def _doStartBeginStream(self, line): if line.find("StateProperty") > -1: col_idx = line.find(":") property_end_idx = line.find(" ", col_idx + 2) self.property = line[col_idx+2:property_end_idx] print "property: %s" % self.property self.state = PARSER_END_BEGINSTREAM def _doEndBeginStream(self, line): if line.find("struct SyncUploadStateStreamContinue_req") > -1: self.state = PARSER_START_CONTINUESTREAM def _doStartContinueStream(self, line): if line.find("StreamData: ARRAY") > -1: self.state = PARSER_CONTINUE_CONTINUESTREAM def _doContinueContinueStream(self, line): bIdx = line.find("[") if bIdx > -1: byteIdx = line.find("0x", bIdx) ebIdx = line.find(" ", byteIdx) byteValue = int(line[byteIdx+2:ebIdx], 16) self.bytes.append(chr(byteValue)) else: self.state = PARSER_DONE def PrintUploadStream(data): dataLen = len(data) if dataLen < 16: raise Exception, "Data buffer is only %d bytes long" % dataLen start = struct.unpack_from("HHL", data, 8) print "{%.8x-%.4x-%.4x-%.4x-%.4x%.8x}" % (start + final) runner = GLOBSetRunner(data, 16) consumed = runner.run() count = 0 for r in runner.ranges: print " %d: [0x%.12x:0x%.12x]" % ((count,) + r) count = count + 1 if __name__ == "__main__": if len(sys.argv) > 1: logfile = open(sys.argv[1], "r") lines = logfile.readlines() logfile.close() parser = UploadStreamBufferParser() data = parser.run(lines) if data is not None: PrintUploadStream(data) print "" openchange-2.0/testprogs/syncstream-compare.py000077500000000000000000000151271223057412600217150ustar00rootroot00000000000000#!/usr/bin/python # # syncstream-compare.py # # Copyright (C) Wolfgang Sourdeau 2012 # # This program is free software; you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by # the Free Software Foundation; either version 3 of the License, or # (at your option) any later version. # # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program. If not, see . # This script compare two chunks of the output from parse-syncbuffer and # report the differences on stdout, in order to help in property-related # mistakes. import string import sys def compare_dict_keys(left_dict, right_dict, label): common_keys = [x for x in left_dict if x in right_dict] missing_keys = [x for x in left_dict if x not in right_dict] if len(missing_keys) > 0: print("< %s keys found in the left dict but not in the right one: %s" % (label, ", ".join(missing_keys))) missing_keys = [x for x in right_dict if x not in left_dict] if len(missing_keys) > 0: print("> %s keys found in the right dict but not in the left one: %s" % (label, ", ".join(missing_keys))) return common_keys class StreamSection(object): def __init__(self): self.properties = {} self.named_properties = {} def compare(self, other_section): self._compare_property_dicts(self.properties, other_section.properties, "property") self._compare_property_dicts(self.named_properties, other_section.named_properties, "named property") @staticmethod def _compare_property_dicts(left_dict, right_dict, label): common_keys = compare_dict_keys(left_dict, right_dict, label) for key in common_keys: self_value = left_dict[key] other_value = right_dict[key] if self_value == other_value: print "= values for %s '%s' are the same" % (label, key) else: print "! values for %s '%s' differ:" % (label, key) print " left has: '%s'" % self_value.strip() print " right has: '%s'" % other_value.strip() class SyncStream(object): def __init__(self, filename): self.filename = filename self.sections = None def _parse(self): sections = {} section_name = None current_section = None current_prop_data = [] inf = open(self.filename) line = inf.readline() if line != "": len_line = len(line) if len_line > 0 and line[-1] == "\n": line = line[:-1] len_line = len_line - 1 if len_line > 0 and line[-1] == "\r": line = line[:-1] len_line = len_line - 1 if len_line > 0: if line[0] == "*": if current_section is not None: if len(current_prop_data) > 0: self._push_prop_data(current_section, current_prop_data) current_prop_data = [] section_name = line[11:] current_section = StreamSection() sections[section_name] = current_section else: if current_section is not None: if len_line >= 10 and line[0:2] == " ": # line is the start of a new property? prop_id = line[2:10].translate(None, string.hexdigits) if len(prop_id) == 0: if len(current_prop_data) > 0: self._push_prop_data(current_section, current_prop_data) current_prop_data = [] current_prop_data.append(line) line = inf.readline() if current_section is not None and len(current_prop_data) > 0: self._push_prop_data(current_section, current_prop_data) self.sections = sections @staticmethod def _push_prop_data(section, prop_data): line0 = prop_data[0] if line0[0:2] != " ": raise ValueError("'prop_data' does not start as a property: %s" % line0) prop_id_str = line0[2:10] if len(prop_id_str.translate(None, string.hexdigits)) != 0: raise ValueError("8 first characters in 'prop_data' are" " not hex digits: '%s'" % prop_id_str) prop_id = int(prop_id_str, 16) if prop_id > 0x80000000: guid = prop_data[2][10:] line3 = prop_data[3] proptype = line3[4:8] if proptype == "name": col_idx = line3.find(":", 9) dispid = line3[col_idx+2:] else: dispid = line3[14:] value = prop_data[4:] section.named_properties[guid+dispid] = "\n".join(value) else: # non-named properties are identified by their property value = [line0[11:]] if len(prop_data) > 1: value.extend(prop_data[1:]) section.properties["%.8x" % prop_id] = "\n".join(value) def compare(self, other_stream): if not isinstance(other_stream, SyncStream): raise TypeError("'other_stream' must be a SyncStream") # ensure streams have been parsed if self.sections is None: self._parse() if other_stream.sections is None: other_stream._parse() # only fetch the sections that are common to both streams common_sections = compare_dict_keys(self.sections, other_stream.sections, "section") for section_name in common_sections: print "* comparing sections '%s'" % section_name self.sections[section_name].compare(other_stream.sections[section_name]) if __name__ == "__main__": SyncStream(sys.argv[1]).compare(SyncStream (sys.argv[2])) openchange-2.0/testprogs/test_asyncnotif.c000066400000000000000000000230131223057412600210750ustar00rootroot00000000000000/* Test asynchronous notifications OpenChange Project Copyright (C) Brad Hards 2010 This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see . */ #include "libmapi/libmapi.h" #include #include static void popt_openchange_version_callback(poptContext con, enum poptCallbackReason reason, const struct poptOption *opt, const char *arg, const void *data) { switch (opt->val) { case 'V': printf("Version %s\n", OPENCHANGE_VERSION_STRING); exit (0); } } struct poptOption popt_openchange_version[] = { { NULL, '\0', POPT_ARG_CALLBACK, (void *)popt_openchange_version_callback, '\0', NULL, NULL }, { "version", 'V', POPT_ARG_NONE, NULL, 'V', "Print version ", NULL }, POPT_TABLEEND }; #define POPT_OPENCHANGE_VERSION { NULL, 0, POPT_ARG_INCLUDE_TABLE, popt_openchange_version, 0, "Common openchange options:", NULL }, #define DEFAULT_PROFDB "%s/.openchange/profiles.ldb" #if 0 static int callback(uint16_t NotificationType, void *NotificationData, void *private_data) { struct HierarchyTableChange *htable; struct ContentsTableChange *ctable; struct ContentsTableChange *stable; switch(NotificationType) { case fnevNewMail: case fnevNewMail|fnevMbit: DEBUG(0, ("[+] New mail Received\n")); break; case fnevObjectCreated: DEBUG(0, ("[+] Folder Created\n")); break; case fnevObjectDeleted: DEBUG(0, ("[+] Folder Deleted\n")); break; case fnevObjectModified: case fnevTbit|fnevObjectModified: case fnevUbit|fnevObjectModified: case fnevTbit|fnevUbit|fnevObjectModified: DEBUG(0, ("[+] Folder Modified\n")); break; case fnevObjectMoved: DEBUG(0, ("[+] Folder Moved\n")); break; case fnevObjectCopied: DEBUG(0, ("[+] Folder Copied\n")); break; case fnevSearchComplete: DEBUG(0, ("[+] Search complete in search folder\n")); break; case fnevTableModified: htable = (struct HierarchyTableChange *) NotificationData; DEBUG(0, ("[+] Hierarchy Table: ")); switch (htable->TableEvent) { case TABLE_CHANGED: DEBUG(0, (" changed\n")); break; case TABLE_ROW_ADDED: DEBUG(0, ("row added\n")); break; case TABLE_ROW_DELETED: DEBUG(0, ("row deleted\n")); break; case TABLE_ROW_MODIFIED: DEBUG(0, ("row modified\n")); break; case TABLE_RESTRICT_DONE: DEBUG(0, ("restriction done\n")); break; default: DEBUG(0, ("\n")); break; } break; case fnevStatusObjectModified: DEBUG(0, ("[+] ICS Notification\n")); break; case fnevMbit|fnevObjectCreated: DEBUG(0, ("[+] Message created\n")); break; case fnevMbit|fnevObjectDeleted: DEBUG(0, ("[+] Message deleted\n")); case fnevMbit|fnevObjectModified: DEBUG(0, ("[+] Message modified\n")); case fnevMbit|fnevObjectMoved: DEBUG(0, ("[+] Message moved\n")); case fnevMbit|fnevObjectCopied: DEBUG(0, ("[+] Message copied\n")); case fnevMbit|fnevTableModified: ctable = (struct ContentsTableChange *) NotificationData; DEBUG(0, ("[+] Contents Table: ")); switch (ctable->TableEvent) { case TABLE_CHANGED: DEBUG(0, (" changed\n")); break; case TABLE_ROW_ADDED: DEBUG(0, ("row added\n")); break; case TABLE_ROW_DELETED: DEBUG(0, ("row deleted\n")); break; case TABLE_ROW_MODIFIED: DEBUG(0, ("row modified\n")); break; case TABLE_RESTRICT_DONE: DEBUG(0, ("restriction done\n")); break; default: DEBUG(0, ("\n")); break; } break; case fnevMbit|fnevSbit|fnevObjectDeleted: DEBUG(0, ("[+] A message is no longer part of a search folder\n")); break; case fnevMbit|fnevSbit|fnevObjectModified: DEBUG(0, ("[+] A property on a message in a search folder has changed\n")); case fnevMbit|fnevSbit|fnevTableModified: stable = (struct ContentsTableChange *) NotificationData; DEBUG(0, ("[+] Search Table: ")); switch (stable->TableEvent) { case TABLE_CHANGED: DEBUG(0, (" changed\n")); break; case TABLE_ROW_ADDED: DEBUG(0, ("row added\n")); break; case TABLE_ROW_DELETED: DEBUG(0, ("row deleted\n")); break; case TABLE_ROW_MODIFIED: DEBUG(0, ("row modified\n")); break; case TABLE_RESTRICT_DONE: DEBUG(0, ("restriction done\n")); break; default: DEBUG(0, ("\n")); break; } break; default: printf("[+] Unsupported notification (0x%x)\n", NotificationType); break; } return 0; } #endif int main(int argc, const char *argv[]) { TALLOC_CTX *mem_ctx; enum MAPISTATUS retval; struct mapi_session *session = NULL; struct mapi_context *mapi_ctx; mapi_object_t obj_store; mapi_object_t obj_inbox; mapi_object_t obj_contentstable; uint32_t count; mapi_id_t fid; poptContext pc; int opt; const char *opt_profdb = NULL; char *opt_profname = NULL; const char *opt_password = NULL; bool opt_dumpdata = false; const char *opt_debug = NULL; int exit_code = 0; uint32_t notificationFlag = 0; enum {OPT_PROFILE_DB=1000, OPT_PROFILE, OPT_PASSWORD, OPT_DEBUG, OPT_DUMPDATA}; struct poptOption long_options[] = { POPT_AUTOHELP {"database", 'f', POPT_ARG_STRING, NULL, OPT_PROFILE_DB, "set the profile database path", "PATH"}, {"profile", 'p', POPT_ARG_STRING, NULL, OPT_PROFILE, "set the profile name", "PROFILE"}, {"password", 'P', POPT_ARG_STRING, NULL, OPT_PASSWORD, "set the profile password", "PASSWORD"}, {"debuglevel", 'd', POPT_ARG_STRING, NULL, OPT_DEBUG, "set the debug level", "LEVEL"}, {"dump-data", 0, POPT_ARG_NONE, NULL, OPT_DUMPDATA, "dump the transfer data", NULL}, POPT_OPENCHANGE_VERSION { NULL, 0, POPT_ARG_NONE, NULL, 0, NULL, NULL } }; mem_ctx = talloc_named(NULL, 0, "check_fasttransfer"); pc = poptGetContext("check_fasttransfer", argc, argv, long_options, 0); while ((opt = poptGetNextOpt(pc)) != -1) { switch (opt) { case OPT_PROFILE_DB: opt_profdb = poptGetOptArg(pc); break; case OPT_PROFILE: opt_profname = talloc_strdup(mem_ctx, (char *)poptGetOptArg(pc)); break; case OPT_PASSWORD: opt_password = poptGetOptArg(pc); break; case OPT_DEBUG: opt_debug = poptGetOptArg(pc); break; case OPT_DUMPDATA: opt_dumpdata = true; break; } } /** * Sanity checks */ if (!opt_profdb) { opt_profdb = talloc_asprintf(mem_ctx, DEFAULT_PROFDB, getenv("HOME")); } /** * Initialize MAPI subsystem */ retval = MAPIInitialize(&mapi_ctx, opt_profdb); if (retval != MAPI_E_SUCCESS) { mapi_errstr("MAPIInitialize", retval); exit (1); } /* debug options */ SetMAPIDumpData(mapi_ctx, opt_dumpdata); if (opt_debug) { SetMAPIDebugLevel(mapi_ctx, atoi(opt_debug)); } /* if no profile is supplied use the default one */ if (!opt_profname) { retval = GetDefaultProfile(mapi_ctx, &opt_profname); if (retval != MAPI_E_SUCCESS) { printf("No profile specified and no default profile found\n"); exit_code = 1; goto cleanup; } } retval = MapiLogonEx(mapi_ctx, &session, opt_profname, opt_password); talloc_free(opt_profname); if (retval != MAPI_E_SUCCESS) { mapi_errstr("MapiLogonEx", retval); exit_code = 1; goto cleanup; } /* Open the default message store */ mapi_object_init(&obj_store); retval = OpenMsgStore(session, &obj_store); if (retval != MAPI_E_SUCCESS) { mapi_errstr("OpenMsgStore", retval); exit_code = 1; goto cleanup; } retval = GetReceiveFolder(&obj_store, &fid, NULL); MAPI_RETVAL_IF(retval, retval, mem_ctx); mapi_object_init(&obj_inbox); retval = OpenFolder(&obj_store, fid, &obj_inbox); MAPI_RETVAL_IF(retval, retval, mem_ctx); mapi_object_init(&obj_contentstable); retval = GetContentsTable(&obj_inbox, &obj_contentstable, 0, &count); printf("mailbox contains %i messages\n", count); #if 0 ulEventMask = fnevNewMail|fnevObjectCreated|fnevObjectDeleted|fnevObjectModified|fnevObjectMoved|fnevObjectCopied|fnevSearchComplete|fnevTableModified|fnevStatusObjectModified; retval = Subscribe(&obj_store, &ulConnection, ulEventMask, true, (mapi_notify_callback_t)callback, (void*) (&obj_store)); if (retval != MAPI_E_SUCCESS) { mapi_errstr("Subscribe", retval); exit_code = 2; goto cleanup; } #endif printf("about to start a long wait\n"); while ((retval = RegisterAsyncNotification(session, ¬ificationFlag)) == MAPI_E_SUCCESS) { if (notificationFlag != 0x00000000) { printf("Got a Notification: 0x%08x, woo hoo!\n", notificationFlag); mapi_object_release(&obj_contentstable); mapi_object_init(&obj_contentstable); retval = GetContentsTable(&obj_inbox, &obj_contentstable, 0, &count); printf("\tNew inbox count is %i\n", count); } else { printf("going around again, ^C to break out\n"); } } if (retval != MAPI_E_SUCCESS) { mapi_errstr("RegisterAsyncNotification", retval); exit_code = 2; goto cleanup; } cleanup: mapi_object_release(&obj_contentstable); mapi_object_release(&obj_inbox); mapi_object_release(&obj_store); MAPIUninitialize(mapi_ctx); talloc_free(mem_ctx); exit(exit_code); } openchange-2.0/utils/000077500000000000000000000000001223057412600146245ustar00rootroot00000000000000openchange-2.0/utils/backup/000077500000000000000000000000001223057412600160715ustar00rootroot00000000000000openchange-2.0/utils/backup/openchangebackup.c000066400000000000000000000177711223057412600215470ustar00rootroot00000000000000/* MAPI Backup application suite OpenChange Project Copyright (C) Julien Kerihuel 2007 This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see . */ #include "openchangebackup.h" #include "libmapi/libmapi_private.h" /** * Initialize OCB (OpenChange Backup) subsystem * and open a pointer on the LDB database */ struct ocb_context *ocb_init(TALLOC_CTX *mem_ctx, const char *dbpath) { struct ocb_context *ocb_ctx = NULL; char *url = NULL; int ret; struct tevent_context *ev; /* sanity check */ OCB_RETVAL_IF_CODE(!mem_ctx, "invalid memory context", NULL, NULL); OCB_RETVAL_IF_CODE(!dbpath, "dbpath not set", NULL, NULL); ocb_ctx = talloc_zero(mem_ctx, struct ocb_context); ev = tevent_context_init(ocb_ctx); if (!ev) goto failed; /* init ldb store */ ocb_ctx->ldb_ctx = ldb_init((TALLOC_CTX *)ocb_ctx, ev); if (!ocb_ctx->ldb_ctx) goto failed; url = talloc_asprintf(mem_ctx, "tdb://%s", dbpath); ret = ldb_connect(ocb_ctx->ldb_ctx, url, 0, NULL); talloc_free(url); if (ret != LDB_SUCCESS) goto failed; return ocb_ctx; failed: ocb_release(ocb_ctx); return NULL; } /** * Release OCB subsystem */ uint32_t ocb_release(struct ocb_context *ocb_ctx) { OCB_RETVAL_IF(!ocb_ctx, "subsystem not initialized\n", NULL); talloc_free(ocb_ctx); return 0; } /** * init and prepare a record */ int ocb_record_init(struct ocb_context *ocb_ctx, const char *objclass, const char *dn, const char *id, struct mapi_SPropValue_array *props) { TALLOC_CTX *mem_ctx; struct ldb_context *ldb_ctx; struct ldb_result *res; enum ldb_scope scope = LDB_SCOPE_SUBTREE; struct ldb_dn *basedn; const char * const attrs[] = { "*", NULL }; /* sanity check */ OCB_RETVAL_IF(!ocb_ctx, "Subsystem not initialized", NULL); OCB_RETVAL_IF(!dn, "Not a valid DN", NULL); OCB_RETVAL_IF(!id, "Not a valid ID", NULL); mem_ctx = (TALLOC_CTX *)ocb_ctx; ldb_ctx = ocb_ctx->ldb_ctx; /* Check if the record already exists */ ldb_search(ldb_ctx, mem_ctx, &res, ldb_get_default_basedn(ldb_ctx), scope, attrs, "%s", dn); OCB_RETVAL_IF(res->msgs, "Record already exists", NULL); /* Retrieve the record basedn */ basedn = ldb_dn_new(ldb_ctx, ldb_ctx, dn); OCB_RETVAL_IF(!ldb_dn_validate(basedn), "Invalid DN", NULL); ocb_ctx->msg = ldb_msg_new(mem_ctx); ocb_ctx->msg->dn = ldb_dn_copy(mem_ctx, basedn); /* add records for cn */ ldb_msg_add_string(ocb_ctx->msg, "cn", id); /* add filters attributes */ ldb_msg_add_string(ocb_ctx->msg, "objectClass", objclass); talloc_free(basedn); return 0; } /** * Commit the record with all its attributes: single transaction */ uint32_t ocb_record_commit(struct ocb_context *ocb_ctx) { int ret; /* sanity checks */ OCB_RETVAL_IF(!ocb_ctx, "Subsystem not initialized", NULL); OCB_RETVAL_IF(!ocb_ctx->ldb_ctx, "LDB context not initialized", NULL); OCB_RETVAL_IF(!ocb_ctx->msg, "Message not initialized", NULL); ret = ldb_add(ocb_ctx->ldb_ctx, ocb_ctx->msg); if (ret != LDB_SUCCESS) { DEBUG(3, ("LDB operation failed: %s\n", ldb_errstring(ocb_ctx->ldb_ctx))); return -1; } talloc_free(ocb_ctx->msg); return 0; } /** * Add a property (attr, value) couple to the current record */ uint32_t ocb_record_add_property(struct ocb_context *ocb_ctx, struct mapi_SPropValue *lpProp) { TALLOC_CTX *mem_ctx; uint32_t i; char *attr; char *value = NULL; const char *tag; /* sanity checks */ OCB_RETVAL_IF(!ocb_ctx, "Subsystem not initialized", NULL); OCB_RETVAL_IF(!ocb_ctx->ldb_ctx, "LDB context not initialized", NULL); OCB_RETVAL_IF(!ocb_ctx->msg, "Message not initialized", NULL); mem_ctx = (TALLOC_CTX *)ocb_ctx->msg; tag = get_proptag_name(lpProp->ulPropTag); if (tag) { attr = talloc_asprintf(mem_ctx, "%s", tag); } else { attr = talloc_asprintf(mem_ctx, "PR-x%.8x", lpProp->ulPropTag); } for (i = 0; attr[i]; i++) { if (attr[i] == '_') attr[i] = '-'; } switch (lpProp->ulPropTag & 0xFFFF) { case PT_SHORT: ldb_msg_add_fmt(ocb_ctx->msg, attr, "%hd", lpProp->value.i); break; case PT_STRING8: ldb_msg_add_string(ocb_ctx->msg, attr, lpProp->value.lpszA); break; case PT_UNICODE: ldb_msg_add_string(ocb_ctx->msg, attr, lpProp->value.lpszW); break; case PT_ERROR: /* We shouldn't need to backup error properties */ return 0; case PT_LONG: ldb_msg_add_fmt(ocb_ctx->msg, attr, "%d", lpProp->value.l); break; case PT_BOOLEAN: ldb_msg_add_fmt(ocb_ctx->msg, attr, "%s", ((lpProp->value.b == true) ? "true" : "false")); break; case PT_I8: ldb_msg_add_fmt(ocb_ctx->msg, attr, "%"PRId64, lpProp->value.d); break; case PT_SYSTIME: value = ocb_ldb_timestring(mem_ctx, &lpProp->value.ft); ldb_msg_add_string(ocb_ctx->msg, attr, value); break; case 0xFB: case PT_BINARY: if (lpProp->value.bin.cb) { value = ldb_base64_encode(mem_ctx, (char *)lpProp->value.bin.lpb, lpProp->value.bin.cb); ldb_msg_add_string(ocb_ctx->msg, attr, value); } break; case PT_MV_LONG: for (i = 0; i < lpProp->value.MVl.cValues; i++) { ldb_msg_add_fmt(ocb_ctx->msg, attr, "%d", lpProp->value.MVl.lpl[i]); } break; case PT_MV_BINARY: for (i = 0; i < lpProp->value.MVbin.cValues; i++) { struct SBinary_short bin; bin = lpProp->value.MVbin.bin[i]; if (bin.cb) { value = ldb_base64_encode(mem_ctx, (char *)bin.lpb, bin.cb); ldb_msg_add_string(ocb_ctx->msg, attr, value); } } break; case PT_MV_STRING8: for (i = 0; i < lpProp->value.MVszA.cValues; i++) { ldb_msg_add_string(ocb_ctx->msg, attr, lpProp->value.MVszA.strings[i].lppszA); } break; default: printf("%s case %d not supported\n", attr, lpProp->ulPropTag & 0xFFFF); break; } talloc_free(attr); return 0; } /** * Retrieve UUID from Sbinary_short struct * Generally used to map PR_STORE_KEY to a string * Used for attachments */ char *get_record_uuid(TALLOC_CTX *mem_ctx, const struct SBinary_short *bin) { uint32_t i; char *lpb; OCB_RETVAL_IF_CODE(!bin, "Invalid PR_RECORD_KEY val", NULL, NULL); lpb = talloc_asprintf(mem_ctx, "%.2X", bin->lpb[0]); for (i = 1; i < bin->cb; i++) { lpb = talloc_asprintf_append(lpb, "%.2X", bin->lpb[i]); } return lpb; } /** * Extract MAPI object unique ID from PR_SOURCE_KEY Sbinary_short data: * PR_SOURCE_KEY = 22 bytes field * - 16 first bytes = MAPI Store GUID * - 6 last bytes = MAPI object unique ID */ char *get_MAPI_uuid(TALLOC_CTX *mem_ctx, const struct SBinary_short *bin) { uint32_t i; char *ab; OCB_RETVAL_IF_CODE(!bin || bin->cb != 22, "Invalid SBinary", NULL, NULL); ab = talloc_asprintf(mem_ctx, "%.2X", bin->lpb[16]); for (i = 17; i < bin->cb; i++) { ab = talloc_asprintf_append(ab, "%.2X", bin->lpb[i]); } return ab; } /** * Retrieve the store GUID from a given record. * This GUID should be unique for each store and identical for all * objects belonging to this store */ char *get_MAPI_store_guid(TALLOC_CTX *mem_ctx, const struct SBinary_short *bin) { int i; char *ab; OCB_RETVAL_IF_CODE(!bin || bin->cb != 22, "Invalid SBinary", NULL, NULL); ab = talloc_asprintf(mem_ctx, "%.2X", bin->lpb[0]); for (i = 1; i < 16; i++) { ab = talloc_asprintf_append(ab, "%.2X", bin->lpb[i]); } return ab; } /** * Convert date from MAPI property to ldb format * Easier to manipulate */ char *ocb_ldb_timestring(TALLOC_CTX *mem_ctx, struct FILETIME *ft) { NTTIME time; time_t t; OCB_RETVAL_IF_CODE(!ft, "Invalid FILTIME", NULL, NULL); time = ft->dwHighDateTime; time = time << 32; time |= ft->dwLowDateTime; t = nt_time_to_unix(time); return ldb_timestring(mem_ctx, t); } openchange-2.0/utils/backup/openchangebackup.h000066400000000000000000000052441223057412600215440ustar00rootroot00000000000000/* MAPI Backup application suite OpenChange Project Copyright (C) Julien Kerihuel 2007 This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see . */ #ifndef __OPENCHANGEBACKUP_H__ #define __OPENCHANGEBACKUP_H__ #include "libmapi/libmapi.h" #include #include #include #include #include #include #include /* Samba4 includes */ #include #include #include #include /* Data structures */ struct ocb_context { struct ldb_context *ldb_ctx; /* ldb database context */ struct ldb_message *msg; /* pointer on record msg */ }; /* Prototypes */ #ifndef __BEGIN_DECLS #ifdef __cplusplus #define __BEGIN_DECLS extern "C" { #define __END_DECLS } #else #define __BEGIN_DECLS #define __END_DECLS #endif #endif __BEGIN_DECLS struct ocb_context *ocb_init(TALLOC_CTX *, const char *); uint32_t ocb_release(struct ocb_context *); int ocb_record_init(struct ocb_context *, const char *, const char *, const char *, struct mapi_SPropValue_array *); uint32_t ocb_record_commit(struct ocb_context *); uint32_t ocb_record_add_property(struct ocb_context *, struct mapi_SPropValue *); char *get_record_uuid(TALLOC_CTX *, const struct SBinary_short *); char *get_MAPI_uuid(TALLOC_CTX *, const struct SBinary_short *); char *get_MAPI_store_guid(TALLOC_CTX *, const struct SBinary_short *); char *ocb_ldb_timestring(TALLOC_CTX *, struct FILETIME *); __END_DECLS #define OCB_RETVAL_IF_CODE(x, m, c, r) \ do { \ if (x) { \ DEBUG(3, ("[OCB] %s\n", m)); \ if (c) { \ talloc_free(c); \ } \ return r; \ } \ } while (0); #define OCB_RETVAL_IF(x, m, c) OCB_RETVAL_IF_CODE(x, m, c, -1) #define DEFAULT_PROFDB "%s/.openchange/profiles.ldb" #define DEFAULT_OCBCONF "%s/.openchange/openchangebackup.conf" #define DEFAULT_OCBDB "%s/.openchange/openchangebackup_%s.ldb" /* objectClass */ #define OCB_OBJCLASS_CONTAINER "container" #define OCB_OBJCLASS_MESSAGE "message" #define OCB_OBJCLASS_ATTACHMENT "attachment" #endif /* __OPENCHANGEBACKUP_H__ */ openchange-2.0/utils/backup/openchangemapidump.c000066400000000000000000000334531223057412600221110ustar00rootroot00000000000000/* MAPI Backup application suite Dump a Mailbox store in a database OpenChange Project Copyright (C) Julien Kerihuel 2007 This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see . */ #include "libmapi/libmapi.h" #include #include #include "openchangebackup.h" #include "utils/openchange-tools.h" #include #include #include #include /** * write attachment to the database */ static enum MAPISTATUS mapidump_write_attachment(struct ocb_context *ocb_ctx, struct mapi_SPropValue_array *props, const char *contentdn, const char *uuid) { int ret; uint32_t i; ret = ocb_record_init(ocb_ctx, OCB_OBJCLASS_ATTACHMENT, contentdn, uuid, props); if (ret == -1) return MAPI_E_SUCCESS; for (i = 0; i < props->cValues; i++) { ret = ocb_record_add_property(ocb_ctx, &props->lpProps[i]); } ret = ocb_record_commit(ocb_ctx); return MAPI_E_SUCCESS; } /** * write message to the database (email, appointment, contact, task, note etc.) */ static enum MAPISTATUS mapidump_write_message(struct ocb_context *ocb_ctx, struct mapi_SPropValue_array *props, const char *contentdn, const char *uuid) { int ret; uint32_t i; ret = ocb_record_init(ocb_ctx, OCB_OBJCLASS_MESSAGE, contentdn, uuid, props); if (ret == -1) return MAPI_E_SUCCESS; for (i = 0; i < props->cValues; i++) { ret = ocb_record_add_property(ocb_ctx, &props->lpProps[i]); } ret = ocb_record_commit(ocb_ctx); return MAPI_E_SUCCESS; } /** * write containers to the database (folders) */ static enum MAPISTATUS mapidump_write_container(struct ocb_context *ocb_ctx, struct mapi_SPropValue_array *props, const char *containerdn, const char *uuid) { int ret; uint32_t i; ret = ocb_record_init(ocb_ctx, OCB_OBJCLASS_CONTAINER, containerdn, uuid, props); if (ret == -1) return MAPI_E_SUCCESS; for (i = 0; i < props->cValues; i++) { ret = ocb_record_add_property(ocb_ctx, &props->lpProps[i]); } ret = ocb_record_commit(ocb_ctx); return MAPI_E_SUCCESS; } /** * Retrieve all the attachments for a given message */ static enum MAPISTATUS mapidump_walk_attachment(TALLOC_CTX *mem_ctx, struct ocb_context *ocb_ctx, mapi_object_t *obj_message, const char *messagedn) { enum MAPISTATUS retval; struct SPropTagArray *SPropTagArray; struct SRowSet rowset; struct mapi_SPropValue_array props; mapi_object_t obj_atable; mapi_object_t obj_attach; uint32_t Numerator = 0; uint32_t Denominator = 0; uint32_t i; const uint32_t *attach_num; const struct SBinary_short *sbin; char *uuid; char *contentdn; /* Get attachment table */ mapi_object_init(&obj_atable); retval = GetAttachmentTable(obj_message, &obj_atable); MAPI_RETVAL_IF(retval, GetLastError(), NULL); /* Customize the table view */ SPropTagArray = set_SPropTagArray(mem_ctx, 0x1, PR_ATTACH_NUM); retval = SetColumns(&obj_atable, SPropTagArray); MAPIFreeBuffer(SPropTagArray); MAPI_RETVAL_IF(retval, GetLastError(), NULL); /* Walk through the table */ retval = QueryPosition(&obj_atable, &Numerator, &Denominator); while ((retval = QueryRows(&obj_atable, Denominator, TBL_ADVANCE, &rowset)) != MAPI_E_NOT_FOUND && rowset.cRows) { for (i = 0; i < rowset.cRows; i++) { attach_num = (const uint32_t *)find_SPropValue_data(&(rowset.aRow[i]), PR_ATTACH_NUM); /* Open attachment */ mapi_object_init(&obj_attach); retval = OpenAttach(obj_message, *attach_num, &obj_attach); if (retval == MAPI_E_SUCCESS) { retval = GetPropsAll(&obj_attach, MAPI_UNICODE, &props); if (retval == MAPI_E_SUCCESS) { /* extract unique identifier from PR_RECORD_KEY */ sbin = (const struct SBinary_short *)find_mapi_SPropValue_data(&props, PR_RECORD_KEY); uuid = get_record_uuid(mem_ctx, sbin); contentdn = talloc_asprintf(mem_ctx, "cn=%s,%s", uuid, messagedn); mapidump_write_attachment(ocb_ctx, &props, contentdn, uuid); /* free allocated strings */ talloc_free(uuid); talloc_free(contentdn); } } mapi_object_release(&obj_attach); } } mapi_object_release(&obj_atable); return MAPI_E_SUCCESS; } /** * Retrieve all the content within a folder */ static enum MAPISTATUS mapidump_walk_content(TALLOC_CTX *mem_ctx, struct ocb_context *ocb_ctx, mapi_object_t *obj_folder, const char *containerdn) { enum MAPISTATUS retval; struct SPropTagArray *SPropTagArray; struct mapi_SPropValue_array props; struct SRowSet rowset; mapi_object_t obj_ctable; mapi_object_t obj_message; uint32_t count = 0; uint32_t i; const mapi_id_t *fid; const mapi_id_t *mid; char *uuid; const struct SBinary_short *sbin; const uint8_t *has_attach; char *contentdn; /* Get Contents Table */ mapi_object_init(&obj_ctable); retval = GetContentsTable(obj_folder, &obj_ctable, 0, &count); MAPI_RETVAL_IF(retval, GetLastError(), NULL); /* Customize the table view */ SPropTagArray = set_SPropTagArray(mem_ctx, 0x5, PR_FID, PR_MID, PR_INST_ID, PR_INSTANCE_NUM, PR_SUBJECT); retval = SetColumns(&obj_ctable, SPropTagArray); MAPIFreeBuffer(SPropTagArray); MAPI_RETVAL_IF(retval, GetLastError(), NULL); while ((retval = QueryRows(&obj_ctable, count, TBL_ADVANCE, &rowset)) != MAPI_E_NOT_FOUND && rowset.cRows) { for (i = 0; i < rowset.cRows; i++) { mapi_object_init(&obj_message); fid = (const uint64_t *) get_SPropValue_SRow_data(&rowset.aRow[i], PR_FID); mid = (const uint64_t *) get_SPropValue_SRow_data(&rowset.aRow[i], PR_MID); /* Open Message */ retval = OpenMessage(obj_folder, *fid, *mid, &obj_message, 0); if (GetLastError() == MAPI_E_SUCCESS) { retval = GetPropsAll(&obj_message, MAPI_UNICODE, &props); if (GetLastError() == MAPI_E_SUCCESS) { /* extract unique identifier from PR_SOURCE_KEY */ sbin = (const struct SBinary_short *)find_mapi_SPropValue_data(&props, PR_SOURCE_KEY); uuid = get_MAPI_uuid(mem_ctx, sbin); contentdn = talloc_asprintf(mem_ctx, "cn=%s,%s", uuid, containerdn); mapidump_write_message(ocb_ctx, &props, contentdn, uuid); /* If Message has attachments then process them */ has_attach = (const uint8_t *)find_mapi_SPropValue_data(&props, PR_HASATTACH); if (has_attach && *has_attach) { mapidump_walk_attachment(mem_ctx, ocb_ctx, &obj_message, contentdn); } /* free allocated strings */ talloc_free(uuid); talloc_free(contentdn); } } mapi_object_release(&obj_message); } } mapi_object_release(&obj_ctable); return MAPI_E_SUCCESS; } /** * Recursively retrieve folders */ static enum MAPISTATUS mapidump_walk_container(TALLOC_CTX *mem_ctx, struct ocb_context *ocb_ctx, mapi_object_t *obj_parent, mapi_id_t folder_id, char *parentdn, int count) { enum MAPISTATUS retval; struct SPropTagArray *SPropTagArray; struct SRowSet rowset; struct mapi_SPropValue_array props; mapi_object_t obj_folder; mapi_object_t obj_htable; const uint32_t *child_content; const uint32_t *child_folder; char *containerdn; char *uuid; const mapi_id_t *fid; uint32_t rcount; uint32_t i; const struct SBinary_short *sbin; /* Open folder */ mapi_object_init(&obj_folder); retval = OpenFolder(obj_parent, folder_id, &obj_folder); MAPI_RETVAL_IF(retval, GetLastError(), NULL); /* Retrieve all its properties */ retval = GetPropsAll(&obj_folder, MAPI_UNICODE, &props); MAPI_RETVAL_IF(retval, GetLastError(), NULL); child_content = (const uint32_t *)find_mapi_SPropValue_data(&props, PR_CONTENT_COUNT); child_folder = (const uint32_t *)find_mapi_SPropValue_data(&props, PR_FOLDER_CHILD_COUNT); /* extract unique identifier from PR_SOURCE_KEY */ sbin = (const struct SBinary_short *)find_mapi_SPropValue_data(&props, PR_SOURCE_KEY); uuid = get_MAPI_uuid(mem_ctx, sbin); if (parentdn == NULL && count == 0) { parentdn = talloc_asprintf(mem_ctx, "cn=%s", get_MAPI_store_guid(mem_ctx, sbin)); } containerdn = talloc_asprintf(mem_ctx, "cn=%s,%s", uuid, parentdn); /* Write entry for container */ mapidump_write_container(ocb_ctx, &props, containerdn, uuid); talloc_free(uuid); /* Get Contents Table if PR_CONTENT_COUNT >= 1 */ if (child_content && *child_content >= 1) { retval = mapidump_walk_content(mem_ctx, ocb_ctx, &obj_folder, containerdn); } /* Get Container Table if PR_FOLDER_CHILD_COUNT >= 1 */ if (child_folder && *child_folder >= 1) { mapi_object_init(&obj_htable); retval = GetHierarchyTable(&obj_folder, &obj_htable, 0, &rcount); MAPI_RETVAL_IF(retval, GetLastError(), NULL); SPropTagArray = set_SPropTagArray(mem_ctx, 0x3, PR_FID, PR_CONTENT_COUNT, PR_FOLDER_CHILD_COUNT); retval = SetColumns(&obj_htable, SPropTagArray); MAPIFreeBuffer(SPropTagArray); MAPI_RETVAL_IF(retval, GetLastError(), NULL); while ((retval = QueryRows(&obj_htable, rcount, TBL_ADVANCE, &rowset) != MAPI_E_NOT_FOUND) && rowset.cRows) { for (i = 0; i < rowset.cRows; i++) { fid = (const uint64_t *)find_SPropValue_data(&rowset.aRow[i], PR_FID); retval = mapidump_walk_container(mem_ctx, ocb_ctx, &obj_folder, *fid, containerdn, count + 1); } } } talloc_free(containerdn); mapi_object_release(&obj_folder); return MAPI_E_SUCCESS; } /** * Walk through known mapi folders */ static enum MAPISTATUS mapidump_walk(TALLOC_CTX *mem_ctx, struct ocb_context *ocb_ctx, mapi_object_t *obj_store) { enum MAPISTATUS retval; mapi_id_t id_mailbox; retval = GetDefaultFolder(obj_store, &id_mailbox, olFolderTopInformationStore); MAPI_RETVAL_IF(retval, GetLastError(), NULL); return mapidump_walk_container(mem_ctx, ocb_ctx, obj_store, id_mailbox, NULL, 0); } int main(int argc, const char *argv[]) { TALLOC_CTX *mem_ctx; enum MAPISTATUS retval; struct ocb_context *ocb_ctx = NULL; struct mapi_context *mapi_ctx; struct mapi_session *session = NULL; mapi_object_t obj_store; poptContext pc; int opt; /* command line options */ const char *opt_profdb = NULL; char *opt_profname = NULL; const char *opt_password = NULL; const char *opt_backupdb = NULL; const char *opt_debug = NULL; bool opt_dumpdata = false; enum {OPT_PROFILE_DB=1000, OPT_PROFILE, OPT_PASSWORD, OPT_MAILBOX, OPT_CONFIG, OPT_BACKUPDB, OPT_PF, OPT_DEBUG, OPT_DUMPDATA}; struct poptOption long_options[] = { POPT_AUTOHELP {"database", 'f', POPT_ARG_STRING, NULL, OPT_PROFILE_DB, "set the profile database path", NULL}, {"profile", 'p', POPT_ARG_STRING, NULL, OPT_PROFILE, "set the profile name", NULL}, {"password", 'P', POPT_ARG_STRING, NULL, OPT_PASSWORD, "set the profile password", NULL}, {"backup-db", 'b', POPT_ARG_STRING, NULL, OPT_BACKUPDB, "set the openchangebackup store path", NULL}, {"debuglevel", 0, POPT_ARG_STRING, NULL, OPT_DEBUG, "set the debug level", NULL}, {"dump-data", 0, POPT_ARG_NONE, NULL, OPT_DUMPDATA, "dump the hex data", NULL}, POPT_OPENCHANGE_VERSION { NULL, 0, 0, NULL, 0, NULL, NULL } }; mem_ctx = talloc_named(NULL, 0, "openchangemapidump"); pc = poptGetContext("openchangemapidump", argc, argv, long_options, 0); while ((opt = poptGetNextOpt(pc)) != -1) { switch (opt) { case OPT_DEBUG: opt_debug = poptGetOptArg(pc); break; case OPT_DUMPDATA: opt_dumpdata = true; break; case OPT_PROFILE_DB: opt_profdb = poptGetOptArg(pc); break; case OPT_PROFILE: opt_profname = talloc_strdup(mem_ctx, (char *)poptGetOptArg(pc)); break; case OPT_PASSWORD: opt_password = poptGetOptArg(pc); break; case OPT_BACKUPDB: opt_backupdb = poptGetOptArg(pc); break; } } /* Sanity check on options */ if (!opt_profdb) { opt_profdb = talloc_asprintf(mem_ctx, DEFAULT_PROFDB, getenv("HOME")); } /* Initialize MAPI subsystem */ retval = MAPIInitialize(&mapi_ctx, opt_profdb); if (retval != MAPI_E_SUCCESS) { mapi_errstr("MAPIInitialize", GetLastError()); exit (1); } /* debug options */ SetMAPIDumpData(mapi_ctx, opt_dumpdata); if (opt_debug) { SetMAPIDebugLevel(mapi_ctx, atoi(opt_debug)); } /* If no profile is specified try to load the default one from * the database */ if (!opt_profname) { retval = GetDefaultProfile(mapi_ctx, &opt_profname); if (retval != MAPI_E_SUCCESS) { mapi_errstr("GetDefaultProfile", GetLastError()); exit (1); } } if (!opt_backupdb) { opt_backupdb = talloc_asprintf(mem_ctx, DEFAULT_OCBDB, getenv("HOME"), opt_profname); } /* Initialize OpenChange Backup subsystem */ if (!(ocb_ctx = ocb_init(mem_ctx, opt_backupdb))) { talloc_free(mem_ctx); exit(-1); } /* We only need to log on EMSMDB to backup Mailbox store or Public Folders */ retval = MapiLogonProvider(mapi_ctx, &session, opt_profname, opt_password, PROVIDER_ID_EMSMDB); talloc_free(opt_profname); if (retval != MAPI_E_SUCCESS) { mapi_errstr("MapiLogonEx", GetLastError()); exit (1); } /* Open default message store */ mapi_object_init(&obj_store); retval = OpenMsgStore(session, &obj_store); if (retval != MAPI_E_SUCCESS) { mapi_errstr("OpenMsgStore", GetLastError()); exit (1); } retval = mapidump_walk(mem_ctx, ocb_ctx, &obj_store); /* Uninitialize MAPI and OCB subsystem */ mapi_object_release(&obj_store); MAPIUninitialize(mapi_ctx); ocb_release(ocb_ctx); talloc_free(mem_ctx); return 0; } openchange-2.0/utils/exchange2ical_tool.c000066400000000000000000000150701223057412600205250ustar00rootroot00000000000000/* Convert Exchange appointments and meetings to ICAL files OpenChange Project Copyright (C) Julien Kerihuel 2008 This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see . */ #include "libexchange2ical/libexchange2ical.h" static void getRange(const char *range, struct tm *start, struct tm *end) { char *startString; char *endString; startString = strtok((char *) range, "-"); endString = strtok(NULL, "-"); end->tm_mon = atoi(strtok(endString, "/"))-1; end->tm_mday = atoi(strtok(NULL, "/")); end->tm_year = atoi(strtok(NULL, "/"))-1900; end->tm_min = 0; end->tm_hour = 0; end->tm_sec = 0; start->tm_mon = atoi(strtok(startString, "/"))-1; start->tm_mday = atoi(strtok(NULL, "/")); start->tm_year = atoi(strtok(NULL, "/"))-1900; start->tm_min = 0; start->tm_hour = 0; start->tm_sec = 0; return; } static char* read_stream(char *s, size_t size, void *d) { char *c = fgets(s, size, (FILE*)d); return c; } int main(int argc, const char *argv[]) { enum MAPISTATUS retval; poptContext pc; int opt; mapi_object_t obj_store; mapi_object_t obj_folder; const char *opt_profdb = NULL; const char *opt_profname = NULL; const char *opt_password = NULL; const char *opt_debug = NULL; const char *opt_filename = NULL; const char *opt_icalsync = NULL; const char *opt_range = NULL; bool opt_dumpdata = false; FILE *fp = NULL; mapi_id_t fid; struct mapi_context *mapi_ctx; struct mapi_session *session = NULL; icalcomponent *vcal; struct tm start; struct tm end; icalparser *parser; icalcomponent *ical; icalcomponent *vevent; TALLOC_CTX *mem_ctx; enum { OPT_PROFILE_DB=1000, OPT_PROFILE, OPT_PASSWORD, OPT_DEBUG, OPT_DUMPDATA, OPT_FILENAME, OPT_RANGE, OPT_ICALSYNC }; struct poptOption long_options[] = { POPT_AUTOHELP { "database", 'f', POPT_ARG_STRING, NULL, OPT_PROFILE_DB, "set the profile database path", NULL }, { "profile", 'p', POPT_ARG_STRING, NULL, OPT_PROFILE, "set the profile name", NULL }, { "password", 'P', POPT_ARG_STRING, NULL, OPT_PASSWORD, "set the profile password", NULL }, { "icalsync", 'i', POPT_ARG_STRING, NULL, OPT_ICALSYNC, "set the icalendar to convert to exchange", NULL }, { "filename", 'o', POPT_ARG_STRING, NULL, OPT_FILENAME, "set the output iCalendar filename", NULL }, { "range", 'R', POPT_ARG_STRING, NULL, OPT_RANGE, "set the range of accepted start dates", NULL }, { "debuglevel", 'd', POPT_ARG_STRING, NULL, OPT_DEBUG, "set the debug level", NULL }, { "dump-data", 0, POPT_ARG_NONE, NULL, OPT_DUMPDATA, "dump the hex data", NULL }, POPT_OPENCHANGE_VERSION { NULL, 0, 0, NULL, 0, NULL, NULL } }; pc = poptGetContext("exchange2ical", argc, argv, long_options, 0); while ((opt = poptGetNextOpt(pc)) != -1) { switch (opt) { case OPT_PROFILE_DB: opt_profdb = poptGetOptArg(pc); break; case OPT_FILENAME: opt_filename = poptGetOptArg(pc); break; case OPT_ICALSYNC: opt_icalsync = poptGetOptArg(pc); break; case OPT_RANGE: opt_range = poptGetOptArg(pc); break; case OPT_PROFILE: opt_profname = poptGetOptArg(pc); break; case OPT_PASSWORD: opt_password = poptGetOptArg(pc); break; case OPT_DEBUG: opt_debug = poptGetOptArg(pc); break; case OPT_DUMPDATA: opt_dumpdata = true; break; } } mem_ctx = talloc_named(NULL, 0, "exchange2ical_tool"); /* Sanity Checks */ if (!opt_profdb) { opt_profdb = talloc_asprintf(mem_ctx, DEFAULT_PROFDB, getenv("HOME")); } /* Initialize MAPI subsystem */ retval = MAPIInitialize(&mapi_ctx, opt_profdb); if (retval != MAPI_E_SUCCESS) { mapi_errstr("MAPIInitialize", GetLastError()); return 1; } /* debug options */ if (opt_debug) { SetMAPIDebugLevel(mapi_ctx, atoi(opt_debug)); } SetMAPIDumpData(mapi_ctx, opt_dumpdata); session = octool_init_mapi(mapi_ctx, opt_profname, opt_password, 0); if(!session){ mapi_errstr("Session", GetLastError()); return 1; } /* Open Mailbox */ mapi_object_init(&obj_store); retval = OpenMsgStore(session, &obj_store); if (retval != MAPI_E_SUCCESS) { mapi_errstr("OpenMsgStore", GetLastError()); return 1; } /* Get default calendar folder */ retval = GetDefaultFolder(&obj_store, &fid, olFolderCalendar); if (retval != MAPI_E_SUCCESS) { mapi_errstr("GetDefaultFolder", GetLastError()); return 1; } /* Open default calendar folder */ mapi_object_init(&obj_folder); retval = OpenFolder(&obj_store, fid, &obj_folder); if (retval != MAPI_E_SUCCESS) { mapi_errstr("OpenFolder", GetLastError()); return 1; } /*Ical2exchange*/ if(opt_icalsync){ if ((fp = fopen(opt_icalsync, "r")) == NULL) { perror("Can not open Icalendar file"); } else { parser = icalparser_new(); icalparser_set_gen_data(parser,fp); ical = icalparser_parse(parser, read_stream); printf("\n\nICAL file:\n%s\n", icalcomponent_as_ical_string(ical)); icalcomponent_strip_errors(ical); vevent = icalcomponent_get_first_component(ical, ICAL_VEVENT_COMPONENT); while(vevent){ _IcalEvent2Exchange(&obj_folder, vevent); vevent = icalcomponent_get_next_component(ical, ICAL_VEVENT_COMPONENT); } icalcomponent_free(ical); icalparser_free(parser); fclose(fp); fp = NULL; } } if(opt_range){ getRange(opt_range, &start, &end); vcal = Exchange2IcalRange(&obj_folder, &start, &end); } else { vcal = Exchange2Ical(&obj_folder); } if(vcal){ /* Icalendar save or print to console */ char *cal = icalcomponent_as_ical_string(vcal); if (!opt_filename) { printf("\n\nICAL file:\n%s\n", cal); } else { size_t bytesWritten; if ((fp = fopen(opt_filename, "w")) == NULL) { perror("fopen"); exit (1); } bytesWritten = fwrite(cal, strlen(cal), 1, fp); if (bytesWritten < 1) { printf("BOGUS write length: %zi", bytesWritten); } fclose(fp); } free(cal); icalcomponent_free(vcal); } poptFreeContext(pc); mapi_object_release(&obj_folder); mapi_object_release(&obj_store); MAPIUninitialize(mapi_ctx); talloc_free(mem_ctx); return 0; } openchange-2.0/utils/exchange2mbox.c000066400000000000000000001042001223057412600175170ustar00rootroot00000000000000/* Convert Exchange mails to mbox OpenChange Project Copyright (C) Julien Kerihuel 2007 This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see . */ #include "libmapi/libmapi.h" #include #include #include #include #include #include #include #include #include #include #include #include #include "openchange-tools.h" /* Ugly and lazy but working ... */ #define DEFAULT_BOUNDARY_BASE "DocE+STaALJfprDB" #define MESSAGEID "Message-ID: " #define MESSAGEID_LEN 11 /* * how much to request at a time, and it's complex :-( * This was 4096 - was getting NT_STATUS_BUFFER_TOO_SMALL loading large * attachments * It must be less than 16K (Windows API is a signed short) * If you ask for more than windows allows you get nothing. * Asking for too little just dogs the performance * * found the NTSTATUS error by adding debug to the ReadStream code. */ #define MAX_READ_SIZE 12000 static int message_error = 0; /* did we get an error processing message */ static bool opt_test = false; static char boundary_base[128] = DEFAULT_BOUNDARY_BASE; static time_t start_time; static char *boundary(int index) { snprintf(boundary_base, sizeof(boundary_base), "%s_%lu_%d", DEFAULT_BOUNDARY_BASE, (unsigned long) start_time, index); return boundary_base; } static void fix_froms(unsigned char *cp, int len) { unsigned char *ep = cp + len; for (; cp + 6 < ep; cp++) { if (*cp != '\n') continue; if (strncmp((char *)cp, "\nFrom ", 6) == 0) { cp[1] = 'f'; cp += 5; } } } /* * find a Header at the start of a line (or the start of the text) */ static char *find_header(char *cp, char *hdr) { char *ep; while ((ep = strcasestr(cp, hdr))) { if (ep == cp || ep[-1] == '\n') return ep; cp = ep + 1; } return NULL; } /** * delete a message on the exchange server */ static bool delete_messages( TALLOC_CTX *mem_ctx, struct mapi_session *session, char **del_msgid, int del_count) { enum MAPISTATUS retval; mapi_object_t obj_store; mapi_object_t obj_inbox; mapi_object_t obj_table; mapi_id_t id_inbox; struct SPropTagArray *SPropTagArray; struct SRowSet SRowSet; uint32_t i, j; uint64_t id_message; struct mapi_profile *profile; if (!del_count || !del_msgid) { return false; } profile = session->profile; /* Open the default message store */ mapi_object_init(&obj_store); retval = OpenMsgStore(session, &obj_store); if (retval != MAPI_E_SUCCESS) return false; /* Open Inbox */ retval = GetReceiveFolder(&obj_store, &id_inbox, NULL); if (retval != MAPI_E_SUCCESS) return false; mapi_object_init(&obj_inbox); retval = OpenFolder(&obj_store, id_inbox, &obj_inbox); if (retval != MAPI_E_SUCCESS) return false; mapi_object_init(&obj_table); retval = GetContentsTable(&obj_inbox, &obj_table, 0, NULL); if (retval != MAPI_E_SUCCESS) return false; SPropTagArray = set_SPropTagArray(mem_ctx, 0x3, PR_FID, PR_MID, PR_INTERNET_MESSAGE_ID); retval = SetColumns(&obj_table, SPropTagArray); MAPIFreeBuffer(SPropTagArray); if (retval != MAPI_E_SUCCESS) return false; while ((retval = QueryRows(&obj_table, 0xa, TBL_ADVANCE, &SRowSet)) == MAPI_E_SUCCESS) { if (!SRowSet.cRows) break; for (i = 0; i < SRowSet.cRows; i++) { const char *message_id; message_id = (const char *)find_SPropValue_data(&(SRowSet.aRow[i]), PR_INTERNET_MESSAGE_ID); if (!message_id) continue; for (j = 0; j < del_count; j++) { if (strcmp(message_id, del_msgid[j]) == 0) { id_message = SRowSet.aRow[i].lpProps[1].value.d; retval = DeleteMessage(&obj_inbox, &id_message, 1); if (retval == MAPI_E_SUCCESS) { printf("%s deleted from the Exchange server\n", del_msgid[j]); retval = mapi_profile_delete_string_attr(profile->mapi_ctx, profile->profname, "Message-ID", del_msgid[j]); if (retval) printf("%s not deleted from profile %s: err=0x%x\n", del_msgid[j], profile->profname, retval); } else { printf("%s NOT deleted from the Exchange server\n", del_msgid[j]); } } } } } mapi_object_release(&obj_table); mapi_object_release(&obj_inbox); mapi_object_release(&obj_store); return true; } /** * Fetch message ids from the existing mbox */ static uint32_t update( TALLOC_CTX *mem_ctx, FILE *fp, struct mapi_session *session) { enum MAPISTATUS retval; struct mapi_profile *profile; size_t read_size; char *line = NULL; #if !defined(__FreeBSD__) ssize_t size; #endif const char *msgid; char *id; char **mbox_msgids; char **prof_msgids; unsigned int mbox_count = 0; unsigned int count; unsigned int i, j; bool found = false; char **del_msgids; unsigned int del_count = 0; profile = session->profile; mbox_msgids = talloc_zero(mem_ctx, char *); /* Add Message-ID attribute to the profile if it is missing */ #if defined(__FreeBSD__) while ((line = fgetln(fp, &read_size)) != NULL) { #else while ((size = getline(&line, &read_size, fp)) != -1) { #endif if (line && !strncmp(line, MESSAGEID, strlen(MESSAGEID))) { msgid = strstr(line, MESSAGEID); id = talloc_strdup(mem_ctx, msgid + strlen(MESSAGEID)); id[strlen(id) - 1] = 0; mbox_msgids = talloc_realloc(mem_ctx, mbox_msgids, char *, mbox_count + 2); mbox_msgids[mbox_count] = talloc_strdup(mem_ctx, id); mbox_count++; retval = FindProfileAttr(profile, "Message-ID", id); if (GetLastError() == MAPI_E_NOT_FOUND) { errno = 0; printf("[+] Adding %s to %s\n", id, profile->profname); retval = mapi_profile_add_string_attr(profile->mapi_ctx, profile->profname, "Message-ID", id); if (retval != MAPI_E_SUCCESS) { mapi_errstr("mapi_profile_add_string_attr", GetLastError()); #if 0 talloc_free(profname); MAPIUninitialize(profile->mapi_ctx); #endif return -1; } } talloc_free(id); } } if (line) free(line); /* Remove Message-ID and update Exchange mailbox if a * Message-ID is missing in mbox */ retval = GetProfileAttr(profile, "Message-ID", &count, &prof_msgids); if (retval == MAPI_E_NOT_FOUND) { printf("No Synchonizing is needed at all\n"); return MAPI_E_SUCCESS; } else if (retval) { fprintf(stderr, "GetProfileAttr failed - %x\n", retval); return retval; } if (count != mbox_count) { printf("{+] Synchonizing mbox with Exchange mailbox\n"); del_msgids = talloc_zero(mem_ctx, char *); del_count = 0; for (i = 0; i < count; i++) { found = false; for (j = 0; j < mbox_count; j++) { if (!strcmp(prof_msgids[i], mbox_msgids[j])) { found = true; } } if (found == false) { del_msgids = talloc_realloc(mem_ctx, del_msgids, char *, del_count + 2); del_msgids[del_count] = talloc_strdup(mem_ctx, prof_msgids[i]); del_count++; } } delete_messages(mem_ctx, session, del_msgids, del_count); talloc_free(del_msgids); del_count = 0; } else { printf("[+] mbox already synchronized with Exchange Mailbox\n"); } talloc_free(prof_msgids); talloc_free(mbox_msgids); return MAPI_E_SUCCESS; } static const char *get_filename(const char *filename) { const char *substr; if (!filename) return NULL; substr = rindex(filename, '/'); if (substr) return substr; return filename; } static char *get_base64_attachment(TALLOC_CTX *mem_ctx, mapi_object_t *obj_attach, const uint32_t size, char **magic) { enum MAPISTATUS retval; const char *tmp; char *ret; mapi_object_t obj_stream; uint32_t stream_size; uint16_t read_size; DATA_BLOB data; magic_t cookie = NULL; mapi_object_init(&obj_stream); retval = OpenStream(obj_attach, PR_ATTACH_DATA_BIN, 0, &obj_stream); if (retval != MAPI_E_SUCCESS) { fprintf(stderr, "OpenStream failed %x\n", retval); return NULL; } data.length = 0; data.data = talloc_zero_size(mem_ctx, size); for (stream_size = 0; stream_size < size; ) { /* * exchange can only handle about 4K chunks at a time, and don't * ask for more or you get none */ retval = ReadStream(&obj_stream, data.data + stream_size, (stream_size + MAX_READ_SIZE < size) ? MAX_READ_SIZE : (size - stream_size), &read_size); if ((retval != MAPI_E_SUCCESS) || read_size == 0) break; stream_size += read_size; } if (retval != MAPI_E_SUCCESS) { fprintf(stderr, "ReadStream failed retval=%x read_size=%d " "stream_size=%d size=%d\n", retval, read_size, stream_size, size); talloc_free(data.data); mapi_object_release(&obj_stream); return NULL; } data.length = stream_size; if (magic) { /* if they want a mime magic string try and autodetect one */ cookie = magic_open(MAGIC_MIME); if (cookie == NULL) { fprintf(stderr, "%s,%d - NULL\n", __FILE__, __LINE__); printf("%s\n", magic_error(cookie)); talloc_free(data.data); mapi_object_release(&obj_stream); return NULL; } if (magic_load(cookie, NULL) == -1) { fprintf(stderr, "%s,%d - NULL\n", __FILE__, __LINE__); printf("%s\n", magic_error(cookie)); talloc_free(data.data); mapi_object_release(&obj_stream); return NULL; } tmp = magic_buffer(cookie, (void *)data.data, data.length); *magic = talloc_strdup(mem_ctx, tmp); magic_close(cookie); } /* convert attachment to base64 */ ret = ldb_base64_encode(mem_ctx, (const char *)data.data, data.length); talloc_free(data.data); mapi_object_release(&obj_stream); return ret; } #define WRAP_LINES_AT 76 static void write_base64_data(FILE *fp, const char *buf) { int len = strlen(buf); size_t n; while (len > 0) { int chunk = len > WRAP_LINES_AT ? WRAP_LINES_AT : len; n = fwrite(buf, len > WRAP_LINES_AT ? WRAP_LINES_AT : len, 1, fp); if (n != 1) fprintf(stderr, "Error writing %d bytes of base64 attachment: %d\n", chunk, ferror(fp)); len -= chunk; buf += chunk; fwrite("\n", 1, 1, fp); } } /* * Read a stream and store it in a DATA_BLOB */ static enum MAPISTATUS get_stream(TALLOC_CTX *mem_ctx, mapi_object_t *obj_stream, DATA_BLOB *body) { enum MAPISTATUS retval; uint16_t read_size; uint8_t buf[MAX_READ_SIZE]; body->length = 0; body->data = talloc_zero(mem_ctx, uint8_t); do { retval = ReadStream(obj_stream, buf, MAX_READ_SIZE, &read_size); MAPI_RETVAL_IF(retval, GetLastError(), body->data); if (read_size) { body->data = talloc_realloc(mem_ctx, body->data, uint8_t, body->length + read_size); memcpy(&(body->data[body->length]), buf, read_size); body->length += read_size; } } while (read_size); errno = 0; return MAPI_E_SUCCESS; } typedef struct { DATA_BLOB body; char *body_header; } body_stuff_t; /* Fetch the body, no fancy junk */ static enum MAPISTATUS get_body(TALLOC_CTX *mem_ctx, mapi_object_t *obj_message, struct SRow *aRow, body_stuff_t body[3], int *body_count) { mapi_object_t obj_stream; enum MAPISTATUS retval; char *data; const struct SBinary_short *bin; *body_count = 0; memset(body, 0, sizeof(body)); data = octool_get_propval(aRow, PR_BODY); if (data && strlen(data)) { body[*body_count].body.data = talloc_memdup(mem_ctx, data, strlen(data)); body[*body_count].body.length = strlen(data); body[*body_count].body_header = "Content-Type: text/plain; charset=us-ascii\n"; (*body_count)++; } bin = (const struct SBinary_short *) octool_get_propval(aRow, PR_HTML); if (bin && bin->cb) { body[*body_count].body.data = talloc_memdup(mem_ctx, bin->lpb, bin->cb); body[*body_count].body.length = bin->cb; body[*body_count].body_header = "Content-Type: text/html\n"; (*body_count)++; } #if 0 bin = (const struct SBinary_short *) octool_get_propval(aRow, PR_RTF_COMPRESSED); if (bin && bin->cb) { body[*body_count].body.data = talloc_memdup(mem_ctx, bin->lpb, bin->cb); body[*body_count].body.length = bin->cb; body[*body_count].body_header = "Content-Type: text/rtf\n"; (*body_count)++; } #endif if (*body_count <= 0) { printf("No HTML or TEXT, generating TEXT body\n"); /* generate a body for us ? */ mapi_object_init(&obj_stream); retval = OpenStream(obj_message, PR_BODY, 0, &obj_stream); if (retval) { fprintf(stderr, "Failed to get a message body, making empty one: %x\n", retval); //message_error = 1; body[*body_count].body.data = talloc_zero(mem_ctx, uint8_t); body[*body_count].body.length = 0; body[*body_count].body_header = "Content-Type: text/plain; charset=us-ascii\n"; (*body_count)++; body[*body_count].body.length = 0; } else { retval = get_stream(mem_ctx, &obj_stream, &body[*body_count].body); if (retval) { body[*body_count].body.length = 0; fprintf(stderr, "HTML ERROR1 %x\n", retval); } } mapi_object_release(&obj_stream); if (body[*body_count].body.length) { body[*body_count].body_header = "Content-Type: text/plain; charset=us-ascii\n"; (*body_count)++; } } return MAPI_E_SUCCESS; } /** Sample mbox mail: From Administrator Mon Apr 23 14:43:01 2007 Date: Mon Apr 23 14:43:01 2007 From: Administrator To: Julien Kerihuel Subject: This is the subject This is a sample mail **/ static bool message2mbox(TALLOC_CTX *mem_ctx, FILE *fp, struct SRow *aRow, mapi_object_t *obj_message, int base_level) { enum MAPISTATUS retval; mapi_object_t obj_tb_attach; mapi_object_t obj_attach; const uint64_t *delivery_date; const char *date = NULL; const char *to = NULL; const char *cc = NULL; const char *bcc = NULL; const char *from = NULL; const char *subject = NULL; const char *msgid; const char *msgheaders = NULL; const char *attach_filename; const uint32_t *attach_size; char *attachment_data; const uint8_t *has_attach = NULL; const uint32_t *attach_num = NULL; char *magic; char *line = NULL; struct SPropTagArray *SPropTagArray = NULL; struct SPropValue *lpProps; struct SRow aRow2; struct SRowSet rowset_attach; uint32_t count; unsigned int i; int header_done = 0; body_stuff_t body[3]; int body_count = 0; has_attach = (const uint8_t *) octool_get_propval(aRow, PR_HASATTACH); to = (const char *) octool_get_propval(aRow, PR_DISPLAY_TO); cc = (const char *) octool_get_propval(aRow, PR_DISPLAY_CC); bcc = (const char *) octool_get_propval(aRow, PR_DISPLAY_BCC); delivery_date = (const uint64_t *)octool_get_propval(aRow, PR_MESSAGE_DELIVERY_TIME); if (delivery_date) { date = nt_time_string(mem_ctx, *delivery_date); } else { date = "None"; } from = (const char *) octool_get_propval(aRow, PR_SENT_REPRESENTING_NAME); if (from == NULL) { from = "unknown"; } subject = (const char*) octool_get_propval(aRow, PR_SUBJECT); msgid = (const char *) octool_get_propval(aRow, PR_INTERNET_MESSAGE_ID); msgheaders = (const char *) octool_get_propval(aRow, PR_TRANSPORT_MESSAGE_HEADERS); retval = get_body(mem_ctx, obj_message, aRow, body, &body_count); /* First line From - but only if base_level == 0 */ if (base_level == 0) { char *f, *p; f = talloc_strdup(mem_ctx, from); /* strip out all '"'s, ugly but works */ for (p = f; p && *p; ) { if (*p == '"') { memmove(p, p+1, strlen(p)); /* gets NUL */ continue; } p++; } fprintf(fp, "From \"%s\" %s\n", f, date); talloc_free(f); } if (msgheaders) { char *mhalloc, *mhclean, *mhend, *mhp, *mht; mhalloc = talloc_strdup(mem_ctx, msgheaders); mhclean = mhalloc; do { /* Skip past the comment Exchange adds to the beginning */ mhclean = strchr(mhclean, '\n'); if (!mhclean) goto old_code; mhclean++; } while (isspace(*mhclean)); /* Trim off the empty mime parts that Exchange leaves after the end of the headers */ mhend = strstr(mhclean, "\n------="); if (mhend) { mhend++; *mhend = '\0'; } /* strip CR/NL */ while ((mhend = strchr(mhclean, '\r'))) memmove(mhend, mhend+1, strlen(mhend) /* gets NUL */); /* * strip Content-* headers (we make our own), be sure to get * and extended (indented parts) of this header */ while (1) { /* * strip some bad-for-us headers (poor mans lookup table below :-) */ mhend = find_header(mhclean, "Content-"); if (!mhend) mhend = find_header(mhclean, "X-MS-"); if (!mhend) mhend = find_header(mhclean, "Lines:"); if (!mhend) break; mhp = NULL; if (mhend) { mht = mhend; while ((mhp = strchr(mht, '\n'))) { mhp++; if (!*mhp || !isspace(*mhp)) break; mht = mhp; } } if (mhp) { /* match was in the middle of other headers */ memmove(mhend, mhp, strlen(mhp) + 1); } else if (mhend) { /* match was at the end of the headers, truncate it */ *mhend = '\0'; } } /* remove any NL's at end of headers */ mhp = mhclean + strlen(mhclean); while (mhp > mhclean && mhp[-1] == '\n') *--mhp = '\0'; line = talloc_asprintf(mem_ctx, "%s\n", mhclean); if (line) fwrite(line, strlen(line), 1, fp); talloc_free(line); talloc_free(mhalloc); } old_code: if (!msgheaders) { /* Second line: Date */ line = talloc_asprintf(mem_ctx, "Date: %s\n", date); if (line) { fwrite(line, strlen(line), 1, fp); } talloc_free(line); /* Third line From */ line = talloc_asprintf(mem_ctx, "From: %s\n", from); if (line) { fwrite(line, strlen(line), 1, fp); } talloc_free(line); /* To, Cc, Bcc */ if (to) { line = talloc_asprintf(mem_ctx, "To: %s\n", to); if (line) { fwrite(line, strlen(line), 1, fp); } talloc_free(line); } if (cc) { line = talloc_asprintf(mem_ctx, "Cc: %s\n", cc); if (line) { fwrite(line, strlen(line), 1, fp); } talloc_free(line); } if (bcc) { line = talloc_asprintf(mem_ctx, "Bcc: %s\n", bcc); if (line) { fwrite(line, strlen(line), 1, fp); } talloc_free(line); } /* Subject */ if (subject) { line = talloc_asprintf(mem_ctx, "Subject: %s\n", subject); if (line) { fwrite(line, strlen(line), 1, fp); } talloc_free(line); } if (msgid) { line = talloc_asprintf(mem_ctx, "Message-ID: %s\n", msgid); if (line) { fwrite(line, strlen(line), 1, fp); } talloc_free(line); } } /* Set multi-type if we have attachment mixed for all things/alternative * for just bodies */ if (has_attach && *has_attach) { fprintf(fp, "Content-Type: multipart/mixed; boundary=\"%s\"\n", boundary(base_level+0)); } else if (body_count > 1) { fprintf(fp, "Content-Type: multipart/alternative; boundary=\"%s\"\n", boundary(base_level+0)); } /* body */ if (body_count > 0) { if ((has_attach && *has_attach) || body_count > 1) { /* blank line before content */ if (!header_done) { fwrite("\n", 1, 1, fp); header_done = 1; } fprintf(fp, "--%s\n", boundary(base_level+0)); } /* * if we have more than 1 body we need to do a multipart alternative * within the first attachment */ if ((has_attach && *has_attach) && body_count > 1) { fprintf(fp, "Content-Type: multipart/alternative; boundary=\"%s\"\n", boundary(base_level+1)); fwrite("\n", 1, 1, fp); fprintf(fp, "\n\n--%s\n", boundary(base_level+1)); } /* * output content type */ fwrite(body[0].body_header, strlen(body[0].body_header), 1, fp); fprintf(fp, "Content-Disposition: inline\n"); /* blank after header */ fwrite("\n", 1, 1, fp); header_done = 1; fix_froms(body[0].body.data, body[0].body.length); fwrite(body[0].body.data, body[0].body.length, 1, fp); talloc_free(body[0].body.data); } /* blank line before content */ if (!header_done) { fwrite("\n", 1, 1, fp); header_done = 1; } /* do the other bodies before attachments */ for (i = 1; i < body_count && i < 3; i++) { if (has_attach && *has_attach) { fprintf(fp, "\n\n--%s\n", boundary(base_level+1)); } else { fprintf(fp, "\n\n--%s\n", boundary(base_level+0)); } fwrite(body[i].body_header, strlen(body[i].body_header), 1, fp); fprintf(fp, "Content-Disposition: inline\n"); fwrite("\n", 1, 1, fp); fix_froms(body[i].body.data, body[i].body.length); fwrite(body[i].body.data, body[i].body.length, 1, fp); } if (has_attach && *has_attach) { /* close body attachments */ if (body_count > 1) { fprintf(fp, "\n\n--%s--\n", boundary(base_level+1)); } mapi_object_init(&obj_tb_attach); retval = GetAttachmentTable(obj_message, &obj_tb_attach); if (retval == MAPI_E_SUCCESS) { SPropTagArray = set_SPropTagArray(mem_ctx, 0x1, PR_ATTACH_NUM); retval = SetColumns(&obj_tb_attach, SPropTagArray); MAPIFreeBuffer(SPropTagArray); MAPI_RETVAL_IF(retval, retval, NULL); retval = QueryRows(&obj_tb_attach, 0xa, TBL_ADVANCE, &rowset_attach); MAPI_RETVAL_IF(retval, retval, NULL); for (i = 0; i < rowset_attach.cRows; i++) { //attach_num = (const uint32_t *)find_SPropValue_data(&(rowset_attach.aRow[i]), PR_ATTACH_NUM); uint32_t n = rowset_attach.aRow[i].lpProps[0].value.l; attach_num = &n; retval = OpenAttach(obj_message, *attach_num, &obj_attach); if (retval == MAPI_E_SUCCESS) { SPropTagArray = set_SPropTagArray(mem_ctx, 0x5, PR_ATTACH_FILENAME, PR_ATTACH_LONG_FILENAME, PR_ATTACH_SIZE, PR_ATTACH_MIME_TAG, PR_ATTACH_METHOD); lpProps = NULL; retval = GetProps(&obj_attach, MAPI_UNICODE, SPropTagArray, &lpProps, &count); MAPIFreeBuffer(SPropTagArray); if (retval == MAPI_E_SUCCESS) { uint32_t *mp, method = -1; aRow2.ulAdrEntryPad = 0; aRow2.cValues = count; aRow2.lpProps = lpProps; mp = (uint32_t *) octool_get_propval(&aRow2, PR_ATTACH_METHOD); if (mp) method = *mp; attach_filename = get_filename(octool_get_propval(&aRow2, PR_ATTACH_LONG_FILENAME)); if (!attach_filename || (attach_filename && !strcmp(attach_filename, ""))) { attach_filename = get_filename(octool_get_propval(&aRow2, PR_ATTACH_FILENAME)); } attach_size = (const uint32_t *) octool_get_propval(&aRow2, PR_ATTACH_SIZE); attachment_data = NULL; switch (method) { case ATTACH_BY_VALUE: magic = (char *) octool_get_propval(&aRow2, PR_ATTACH_MIME_TAG); if (magic) magic = talloc_strdup(mem_ctx, magic); attachment_data = get_base64_attachment(mem_ctx, &obj_attach, *attach_size, magic ? NULL : &magic); if (attachment_data == NULL) { message_error = 1; fprintf(stderr, "Failed to read attachment for message %s\n", msgid ? msgid : "unknown"); break; } fprintf(fp, "\n\n--%s\n", boundary(base_level+0)); fprintf(fp, "Content-Disposition: attachment; filename=\"%s\"\n", attach_filename); fprintf(fp, "Content-Type: %s\n", magic); fprintf(fp, "Content-Transfer-Encoding: base64\n\n"); write_base64_data(fp, attachment_data); talloc_free(attachment_data); talloc_free(magic); break; case ATTACH_BY_REFERENCE: fprintf(stderr,"ATTACH_BY_REFERENCE unsupported\n"); message_error = 1; break; case ATTACH_BY_REF_RESOLVE: fprintf(stderr,"ATTACH_BY_REF_RESOLVE unsupported\n"); message_error = 1; break; case ATTACH_BY_REF_ONLY: fprintf(stderr,"ATTACH_BY_REF_ONLY unsupported\n"); message_error = 1; break; case ATTACH_EMBEDDED_MSG: { mapi_object_t obj_embeddedmsg; struct SPropTagArray *embTagArray = NULL; struct SPropValue *embProps; struct SRow eRow; uint32_t emb_count = 0; mapi_object_init(&obj_embeddedmsg); retval = OpenEmbeddedMessage(&obj_attach, &obj_embeddedmsg, MAPI_READONLY); if (retval != MAPI_E_SUCCESS) { fprintf(stderr, "Failed to open Embedded msg: %x\n", retval); message_error = 1; break; } embTagArray = set_SPropTagArray(mem_ctx, 0x15, PR_INTERNET_MESSAGE_ID, PR_INTERNET_MESSAGE_ID_UNICODE, PR_CONVERSATION_TOPIC, PR_CONVERSATION_TOPIC_UNICODE, PR_MESSAGE_DELIVERY_TIME, PR_MSG_EDITOR_FORMAT, PR_BODY, PR_BODY_UNICODE, PR_HTML, PR_RTF_COMPRESSED, PR_RTF_IN_SYNC, PR_SENT_REPRESENTING_NAME, PR_SENT_REPRESENTING_NAME_UNICODE, PR_DISPLAY_TO, PR_DISPLAY_TO_UNICODE, PR_DISPLAY_CC, PR_DISPLAY_CC_UNICODE, PR_DISPLAY_BCC, PR_DISPLAY_BCC_UNICODE, PR_HASATTACH, PR_TRANSPORT_MESSAGE_HEADERS); retval = GetProps(&obj_embeddedmsg, MAPI_UNICODE, embTagArray, &embProps, &emb_count); MAPIFreeBuffer(embTagArray); if (retval != MAPI_E_SUCCESS) { fprintf(stderr, "Failed to get Embedded msg props: %x\n", retval); message_error = 1; break; } /* Build a SRow structure */ eRow.ulAdrEntryPad = 0; eRow.cValues = emb_count; eRow.lpProps = embProps; fprintf(fp, "\n\n--%s\n", boundary(base_level+0)); fprintf(fp, "Content-Type: message/rfc822\n"); fprintf(fp, "Content-Disposition: inline\n"); fprintf(fp, "\n"); message2mbox(mem_ctx, fp, &eRow, &obj_embeddedmsg, base_level + 2 /* 0 = main, 1 = alt */); talloc_free(embProps); } break; case ATTACH_OLE: fprintf(stderr,"ATTACH_OLE unsupported - " "allowing message through anyway\n"); // message_error = 1; break; default: fprintf(stderr, "Unsupported attach method = %d\n", method); message_error = 1; break; } } MAPIFreeBuffer(lpProps); } } line = talloc_asprintf(mem_ctx, "\n\n--%s--\n\n\n", boundary(base_level+0)); if (line) { fwrite(line, strlen(line), 1, fp); } talloc_free(line); } } else if (body_count > 1) { /* close body attachments */ fprintf(fp, "\n\n--%s--\n", boundary(base_level+0)); } fwrite("\n\n\n", 3, 1, fp); return true; } int main(int argc, const char *argv[]) { TALLOC_CTX *mem_ctx = NULL; enum MAPISTATUS retval; struct mapi_context *mapi_ctx = NULL; struct mapi_session *session = NULL; struct mapi_profile *profile = NULL; mapi_object_t obj_store; mapi_object_t obj_inbox; mapi_object_t obj_table; mapi_object_t obj_message; mapi_id_t id_inbox; uint32_t count; struct SPropTagArray *SPropTagArray = NULL; struct SPropValue *lpProps; struct SRow aRow; struct SRowSet rowset; poptContext pc; int opt; FILE *fp; unsigned int i; const char *opt_profdb = NULL; char *opt_profname = NULL; const char *opt_password = NULL; const char *opt_mbox = NULL; bool opt_update = false; bool opt_dumpdata = false; const char *opt_debug = NULL; const char *msgid; enum {OPT_PROFILE_DB=1000, OPT_PROFILE, OPT_PASSWORD, OPT_MBOX, OPT_UPDATE, OPT_DEBUG, OPT_DUMPDATA, OPT_TEST}; struct poptOption long_options[] = { POPT_AUTOHELP {"test", 't', POPT_ARG_NONE, 0, OPT_TEST, "Do not update server, just download messages to mbox", NULL}, {"database", 'f', POPT_ARG_STRING, NULL, OPT_PROFILE_DB, "set the profile database path", "PATH"}, {"profile", 'p', POPT_ARG_STRING, NULL, OPT_PROFILE, "set the profile name", "PROFILE"}, {"password", 'P', POPT_ARG_STRING, NULL, OPT_PASSWORD, "set the profile password", "PASSWORD"}, {"mbox", 'm', POPT_ARG_STRING, NULL, OPT_MBOX, "set the mbox file", "FILENAME"}, {"update", 'u', POPT_ARG_NONE, 0, OPT_UPDATE, "mirror mbox changes back to the Exchange server", NULL}, {"debuglevel", 'd', POPT_ARG_STRING, NULL, OPT_DEBUG, "set the debug level", "LEVEL"}, {"dump-data", 0, POPT_ARG_NONE, NULL, OPT_DUMPDATA, "dump the hex data", NULL}, POPT_OPENCHANGE_VERSION { NULL, 0, POPT_ARG_NONE, NULL, 0, NULL, NULL } }; start_time = time(0); mem_ctx = talloc_named(NULL, 0, "exchange2mbox"); pc = poptGetContext("exchange2mbox", argc, argv, long_options, 0); while ((opt = poptGetNextOpt(pc)) != -1) { switch (opt) { case OPT_PROFILE_DB: opt_profdb = poptGetOptArg(pc); break; case OPT_PROFILE: opt_profname = talloc_strdup(mem_ctx, (char *)poptGetOptArg(pc)); break; case OPT_PASSWORD: opt_password = poptGetOptArg(pc); break; case OPT_MBOX: opt_mbox = poptGetOptArg(pc); break; case OPT_UPDATE: opt_update = true; break; case OPT_TEST: opt_test = true; break; case OPT_DEBUG: opt_debug = poptGetOptArg(pc); break; case OPT_DUMPDATA: opt_dumpdata = true; break; } } /** * Sanity checks */ if (!opt_profdb) { opt_profdb = talloc_asprintf(mem_ctx, DEFAULT_PROFDB, getenv("HOME")); } if (!opt_mbox) { opt_mbox = talloc_asprintf(mem_ctx, DEFAULT_MBOX, getenv("HOME")); } /** * Open the MBOX */ if ((fp = fopen(opt_mbox, "a+")) == NULL) { perror("fopen"); exit (1); } /** * Initialize MAPI subsystem */ retval = MAPIInitialize(&mapi_ctx, opt_profdb); if (retval != MAPI_E_SUCCESS) { mapi_errstr("MAPIInitialize", GetLastError()); exit (1); } /* debug options */ SetMAPIDumpData(mapi_ctx, opt_dumpdata); if (opt_debug) { SetMAPIDebugLevel(mapi_ctx, atoi(opt_debug)); } /* if no profile is supplied use the default one */ if (!opt_profname) { retval = GetDefaultProfile(mapi_ctx, &opt_profname); if (retval != MAPI_E_SUCCESS) { printf("No profile specified and no default profile found\n"); exit (1); } } retval = MapiLogonEx(mapi_ctx, &session, opt_profname, opt_password); talloc_free(opt_profname); if (retval != MAPI_E_SUCCESS) { mapi_errstr("MapiLogonEx", GetLastError()); exit (1); } profile = session->profile; /* not sure about this, but it works and it's nice to have it there */ profile->mapi_ctx = mapi_ctx; /* do the updates now */ if (opt_update == true) { retval = update(mem_ctx, fp, session); if (retval != MAPI_E_SUCCESS) { printf("Problem encountered during update: %d\n", retval); exit (1); } } /* Open the default message store */ mapi_object_init(&obj_store); retval = OpenMsgStore(session, &obj_store); if (retval != MAPI_E_SUCCESS) { mapi_errstr("OpenMsgStore", GetLastError()); exit (1); } /* Open Inbox */ retval = GetReceiveFolder(&obj_store, &id_inbox, NULL); MAPI_RETVAL_IF(retval, retval, mem_ctx); mapi_object_init(&obj_inbox); retval = OpenFolder(&obj_store, id_inbox, &obj_inbox); MAPI_RETVAL_IF(retval, retval, mem_ctx); mapi_object_init(&obj_table); retval = GetContentsTable(&obj_inbox, &obj_table, 0, &count); MAPI_RETVAL_IF(retval, retval, mem_ctx); SPropTagArray = set_SPropTagArray(mem_ctx, 0x5, PR_FID, PR_MID, PR_INST_ID, PR_INSTANCE_NUM, PR_INTERNET_MESSAGE_ID); retval = SetColumns(&obj_table, SPropTagArray); MAPIFreeBuffer(SPropTagArray); MAPI_RETVAL_IF(retval, retval, mem_ctx); while ((retval = QueryRows(&obj_table, 0xa, TBL_ADVANCE, &rowset)) != MAPI_E_NOT_FOUND && rowset.cRows) { for (i = 0; i < rowset.cRows; i++) { mapi_object_init(&obj_message); retval = OpenMessage(&obj_store, rowset.aRow[i].lpProps[0].value.d, rowset.aRow[i].lpProps[1].value.d, &obj_message, 0); if (retval == MAPI_E_SUCCESS) { SPropTagArray = set_SPropTagArray(mem_ctx, 0x1b, PR_INTERNET_MESSAGE_ID, PR_INTERNET_MESSAGE_ID_UNICODE, PR_CONVERSATION_TOPIC, PR_CONVERSATION_TOPIC_UNICODE, PR_MESSAGE_DELIVERY_TIME, PR_MSG_EDITOR_FORMAT, PR_BODY, PR_BODY_UNICODE, PR_HTML, PR_RTF_COMPRESSED, PR_RTF_IN_SYNC, PR_SENT_REPRESENTING_NAME, PR_SENT_REPRESENTING_NAME_UNICODE, PR_DISPLAY_TO, PR_DISPLAY_TO_UNICODE, PR_DISPLAY_CC, PR_DISPLAY_CC_UNICODE, PR_DISPLAY_BCC, PR_DISPLAY_BCC_UNICODE, PR_HASATTACH, PR_TRANSPORT_MESSAGE_HEADERS, PR_SUBJECT_PREFIX, PR_SUBJECT_PREFIX_UNICODE, PR_NORMALIZED_SUBJECT, PR_NORMALIZED_SUBJECT_UNICODE, PR_SUBJECT, PR_SUBJECT_UNICODE); retval = GetProps(&obj_message, MAPI_UNICODE, SPropTagArray, &lpProps, &count); MAPIFreeBuffer(SPropTagArray); if (retval != MAPI_E_SUCCESS) { fprintf(stderr, "Badness getting row %d attrs\n", i); exit (1); } /* Build a SRow structure */ aRow.ulAdrEntryPad = 0; aRow.cValues = count; aRow.lpProps = lpProps; msgid = (const char *) octool_get_propval(&aRow, PR_INTERNET_MESSAGE_ID); if (msgid) { retval = FindProfileAttr(profile, "Message-ID", msgid); if (GetLastError() == MAPI_E_NOT_FOUND) { bool ok; message_error = 0; ok = message2mbox(mem_ctx, fp, &aRow, &obj_message, 0); if (!ok) { printf("Message-ID: %s error, not added to %s\n", msgid, profile->profname); } else if (message_error) { printf("Message-ID: %s error, ignoring\n", msgid); fprintf(stderr, "Message-ID: %s error, ignoring message (check with OWA if you can, will retry next time)\n", msgid); } else if (opt_test) { printf("Message-ID: %s saved but not updated in %s\n", msgid, profile->profname); } else if (mapi_profile_add_string_attr(profile->mapi_ctx, profile->profname, "Message-ID", msgid) != MAPI_E_SUCCESS) { mapi_errstr("mapi_profile_add_string_attr", GetLastError()); } else { printf("Message-ID: %s added to profile %s\n", msgid, profile->profname); } } else { printf("Message-ID: %s already in profile %s\n", msgid, profile->profname); } } else { fprintf(stderr, "%s: message with no msgid cannot be downloaded\n", profile->profname); } talloc_free(lpProps); } else { fprintf(stderr, "could not open row %d: retval=%d GetLastError=%d\n", i, retval, GetLastError()); } mapi_object_release(&obj_message); errno = 0; } } fclose(fp); mapi_object_release(&obj_table); mapi_object_release(&obj_inbox); mapi_object_release(&obj_store); MAPIUninitialize(mapi_ctx); talloc_free(mem_ctx); return 0; } openchange-2.0/utils/mapiprofile.c000066400000000000000000000577131223057412600173140ustar00rootroot00000000000000/* Wrapper over the MAPI Profile API OpenChange Project Copyright (C) Julien Kerihuel 2007-2009 This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see . */ #include "libmapi/libmapi.h" #include #include #include "openchange-tools.h" #include #include #include #include #define DEFAULT_DIR "%s/.openchange" #define DEFAULT_PROFDB "%s/.openchange/profiles.ldb" #define DEFAULT_EXCHANGE_VERSION "2000" /** MAPI version: #- 0: use EcDoConnect (0x0) / EcDoRpc (0x2) RPC calls #- 1: use EcDoConnectEx (0xA) / EcDoRpcExt2 (0xB) RPC calls #- 2: Same as 1, but require sealed pipe */ struct exchange_version { const char *name; uint8_t version; }; static const struct exchange_version exchange_version[] = { { DEFAULT_EXCHANGE_VERSION, 0 }, { "2003", 1 }, { "2007", 1 }, { "2010", 2 }, { NULL, 0 } }; static bool mapiprofile_createdb(const char *profdb, const char *ldif_path) { enum MAPISTATUS retval; if (access(profdb, F_OK) == 0) { fprintf(stderr, "[ERROR] mapiprofile: %s already exists\n", profdb); return false; } retval = CreateProfileStore(profdb, ldif_path); if (retval != MAPI_E_SUCCESS) { mapi_errstr("CreateProfileStore", retval); return false; } return true; } static uint32_t callback(struct SRowSet *rowset, void *private) { uint32_t i; struct SPropValue *lpProp; FILE *fd; uint32_t index; char entry[10]; const char *label = (const char *)private; printf("%s:\n", label); for (i = 0; i < rowset->cRows; i++) { lpProp = get_SPropValue_SRow(&(rowset->aRow[i]), PR_DISPLAY_NAME); if (lpProp && lpProp->value.lpszA) { printf("\t[%u] %s\n", i, lpProp->value.lpszA); } } printf("\t[%u] cancel operation\n", i); fd = fdopen(0, "r"); getentry: printf("Enter username id [0]: "); if (fgets(entry, 10, fd) == NULL) { printf("Failed to read string\n"); exit(1); } index = atoi(entry); if (index > i) { printf("Invalid id - Must be a value between 0 and %u\n", i); goto getentry; } fclose(fd); return (index); } const char *g_profname; struct mapi_context *g_mapi_ctx; static void signal_delete_profile(void) { enum MAPISTATUS retval; fprintf(stderr, "CTRL-C caught ... Deleting profile\n"); if ((retval = DeleteProfile(g_mapi_ctx, g_profname)) != MAPI_E_SUCCESS) { mapi_errstr("DeleteProfile", retval); } (void) signal(SIGINT, SIG_DFL); exit (1); } static bool mapiprofile_create(struct mapi_context *mapi_ctx, const char *profdb, const char *profname, const char *pattern, const char *username, const char *password, const char *address, const char *language, const char *workstation, const char *domain, const char *realm, uint32_t flags, bool seal, bool opt_dumpdata, const char *opt_debuglevel, uint8_t exchange_version, const char *kerberos) { enum MAPISTATUS retval; struct mapi_session *session = NULL; TALLOC_CTX *mem_ctx; struct mapi_profile profile; const char *locale; uint32_t cpid = 0; uint32_t lcid = 0; char *exchange_version_str; char *cpid_str; char *lcid_str; mem_ctx = talloc_named(mapi_ctx->mem_ctx, 0, "mapiprofile_create"); /* catch CTRL-C */ g_profname = profname; g_mapi_ctx = mapi_ctx; #if defined (__FreeBSD__) (void) signal(SIGINT, (sig_t) signal_delete_profile); #elif defined (__SunOS) (void) signal(SIGINT, signal_delete_profile); #else (void) signal(SIGINT, (sighandler_t) signal_delete_profile); #endif /* debug options */ SetMAPIDumpData(mapi_ctx, opt_dumpdata); if (opt_debuglevel) { SetMAPIDebugLevel(mapi_ctx, atoi(opt_debuglevel)); } /* Sanity check */ retval = OpenProfile(mapi_ctx, &profile, profname, NULL); if (retval == MAPI_E_SUCCESS) { fprintf(stderr, "[ERROR] mapiprofile: profile \"%s\" already exists\n", profname); talloc_free(mem_ctx); return false; } retval = CreateProfile(mapi_ctx, profname, username, password, flags); if (retval != MAPI_E_SUCCESS) { mapi_errstr("CreateProfile", retval); talloc_free(mem_ctx); return false; } mapi_profile_add_string_attr(mapi_ctx, profname, "binding", address); mapi_profile_add_string_attr(mapi_ctx, profname, "workstation", workstation); mapi_profile_add_string_attr(mapi_ctx, profname, "domain", domain); mapi_profile_add_string_attr(mapi_ctx, profname, "seal", (seal == true) ? "true" : "false"); exchange_version_str = talloc_asprintf(mem_ctx, "%d", exchange_version); mapi_profile_add_string_attr(mapi_ctx, profname, "exchange_version", exchange_version_str); talloc_free(exchange_version_str); if (realm) { mapi_profile_add_string_attr(mapi_ctx, profname, "realm", realm); } locale = (const char *) (language) ? mapi_get_locale_from_language(language) : mapi_get_system_locale(); if (locale) { cpid = mapi_get_cpid_from_locale(locale); lcid = mapi_get_lcid_from_locale(locale); } if (!locale || !cpid || !lcid) { printf("Invalid Language supplied or unknown system language '%s\n'", language); printf("Deleting profile\n"); if ((retval = DeleteProfile(mapi_ctx, profname)) != MAPI_E_SUCCESS) { mapi_errstr("DeleteProfile", retval); } talloc_free(mem_ctx); return false; } cpid_str = talloc_asprintf(mem_ctx, "%d", cpid); lcid_str = talloc_asprintf(mem_ctx, "%d", lcid); mapi_profile_add_string_attr(mapi_ctx, profname, "codepage", cpid_str); mapi_profile_add_string_attr(mapi_ctx, profname, "language", lcid_str); mapi_profile_add_string_attr(mapi_ctx, profname, "method", lcid_str); talloc_free(cpid_str); talloc_free(lcid_str); if (kerberos) { mapi_profile_add_string_attr(mapi_ctx, profname, "kerberos", kerberos); } retval = MapiLogonProvider(mapi_ctx, &session, profname, password, PROVIDER_ID_NSPI); if (retval != MAPI_E_SUCCESS) { mapi_errstr("MapiLogonProvider", retval); printf("Deleting profile\n"); if ((retval = DeleteProfile(mapi_ctx, profname)) != MAPI_E_SUCCESS) { mapi_errstr("DeleteProfile", retval); } talloc_free(mem_ctx); return false; } if (pattern) { username = pattern; } retval = ProcessNetworkProfile(session, username, (mapi_profile_callback_t) callback, "Select a user id"); if (retval != MAPI_E_SUCCESS && retval != 0x1) { mapi_errstr("ProcessNetworkProfile", retval); printf("Deleting profile\n"); if ((retval = DeleteProfile(mapi_ctx, profname)) != MAPI_E_SUCCESS) { mapi_errstr("DeleteProfile", retval); } talloc_free(mem_ctx); return false; } printf("Profile %s completed and added to database %s\n", profname, profdb); talloc_free(mem_ctx); return true; } static void mapiprofile_delete(struct mapi_context *mapi_ctx, const char *profdb, const char *profname) { enum MAPISTATUS retval; if ((retval = DeleteProfile(mapi_ctx, profname)) != MAPI_E_SUCCESS) { mapi_errstr("DeleteProfile", retval); exit (1); } printf("Profile %s deleted from database %s\n", profname, profdb); } static void mapiprofile_rename(struct mapi_context *mapi_ctx, const char *profdb, const char *old_profname, const char *new_profname) { TALLOC_CTX *mem_ctx; enum MAPISTATUS retval; char *profname; mem_ctx = talloc_named(mapi_ctx->mem_ctx, 0, "mapiprofile_rename"); if (!old_profname) { if ((retval = GetDefaultProfile(mapi_ctx, &profname)) != MAPI_E_SUCCESS) { mapi_errstr("GetDefaultProfile", retval); talloc_free(mem_ctx); exit (1); } } else { profname = talloc_strdup(mem_ctx, old_profname); } if ((retval = RenameProfile(mapi_ctx, profname, new_profname)) != MAPI_E_SUCCESS) { mapi_errstr("RenameProfile", retval); talloc_free(profname); talloc_free(mem_ctx); exit (1); } talloc_free(profname); talloc_free(mem_ctx); } static void mapiprofile_set_default(struct mapi_context *mapi_ctx, const char *profdb, const char *profname) { enum MAPISTATUS retval; if ((retval = SetDefaultProfile(mapi_ctx, profname)) != MAPI_E_SUCCESS) { mapi_errstr("SetDefaultProfile", retval); exit (1); } printf("Profile %s is now set the default one\n", profname); } static void mapiprofile_get_default(struct mapi_context *mapi_ctx, const char *profdb) { enum MAPISTATUS retval; char *profname; if ((retval = GetDefaultProfile(mapi_ctx, &profname)) != MAPI_E_SUCCESS) { mapi_errstr("GetDefaultProfile", retval); exit (1); } printf("Default profile is set to %s\n", profname); talloc_free(profname); } static void mapiprofile_get_fqdn(struct mapi_context *mapi_ctx, const char *profdb, const char *opt_profname, const char *password, bool opt_dumpdata) { TALLOC_CTX *mem_ctx; enum MAPISTATUS retval; struct mapi_session *session = NULL; const char *serverFQDN; char *profname; SetMAPIDumpData(mapi_ctx, opt_dumpdata); mem_ctx = talloc_named(mapi_ctx->mem_ctx, 0, "mapiprofile_get_fqdn"); if (!opt_profname) { if ((retval = GetDefaultProfile(mapi_ctx, &profname)) != MAPI_E_SUCCESS) { mapi_errstr("GetDefaultProfile", retval); talloc_free(mem_ctx); exit (1); } } else { profname = talloc_strdup(mem_ctx, (char *)opt_profname); } retval = MapiLogonProvider(mapi_ctx, &session, profname, password, PROVIDER_ID_NSPI); talloc_free(profname); talloc_free(mem_ctx); if (retval != MAPI_E_SUCCESS) { mapi_errstr("MapiLogonProvider", retval); exit (1); } retval = RfrGetFQDNFromLegacyDN(mapi_ctx, session, &serverFQDN); if (retval != MAPI_E_SUCCESS) { mapi_errstr("RfrGetFQDNFromLegacyDN", retval); exit (1); } printf("%s is at %s\n", mapi_ctx->session->profile->homemdb, serverFQDN); } static void mapiprofile_list(struct mapi_context *mapi_ctx, const char *profdb) { enum MAPISTATUS retval; struct SRowSet proftable; uint32_t count = 0; memset(&proftable, 0, sizeof (struct SRowSet)); if ((retval = GetProfileTable(mapi_ctx, &proftable)) != MAPI_E_SUCCESS) { mapi_errstr("GetProfileTable", retval); exit (1); } printf("We have %u profiles in the database:\n", proftable.cRows); for (count = 0; count != proftable.cRows; count++) { const char *name = NULL; uint32_t dflt = 0; name = proftable.aRow[count].lpProps[0].value.lpszA; dflt = proftable.aRow[count].lpProps[1].value.l; if (dflt) { printf("\tProfile = %s [default]\n", name); } else { printf("\tProfile = %s\n", name); } } } static void mapiprofile_dump(struct mapi_context *mapi_ctx, const char *profdb, const char *opt_profname) { TALLOC_CTX *mem_ctx; enum MAPISTATUS retval; struct mapi_profile *profile; char *profname; char *exchange_version = NULL; mem_ctx = talloc_named(mapi_ctx->mem_ctx, 0, "mapiprofile_dump"); profile = talloc(mem_ctx, struct mapi_profile); if (!opt_profname) { if ((retval = GetDefaultProfile(mapi_ctx, &profname)) != MAPI_E_SUCCESS) { mapi_errstr("GetDefaultProfile", retval); talloc_free(mem_ctx); exit (1); } } else { profname = talloc_strdup(mem_ctx, (const char *)opt_profname); } retval = OpenProfile(mapi_ctx, profile, profname, NULL); talloc_free(profname); if (retval && (retval != MAPI_E_INVALID_PARAMETER)) { talloc_free(mem_ctx); mapi_errstr("OpenProfile", retval); exit (1); } switch (profile->exchange_version) { case 0x0: exchange_version = talloc_strdup(mem_ctx, "exchange 2000"); break; case 0x1: exchange_version = talloc_strdup(mem_ctx, "exchange 2003/2007"); break; case 0x2: exchange_version = talloc_strdup(mem_ctx, "exchange 2010"); break; default: printf("Error: unknown Exchange server\n"); goto end; } printf("Profile: %s\n", profile->profname); printf("\texchange server == %s\n", exchange_version); printf("\tencryption == %s\n", (profile->seal == true) ? "yes" : "no"); printf("\tusername == %s\n", profile->username); printf("\tpassword == %s\n", profile->password); printf("\tmailbox == %s\n", profile->mailbox); printf("\tworkstation == %s\n", profile->workstation); printf("\tdomain == %s\n", profile->domain); printf("\tserver == %s\n", profile->server); end: talloc_free(mem_ctx); } static void mapiprofile_attribute(struct mapi_context *mapi_ctx, const char *profdb, const char *opt_profname, const char *attribute) { TALLOC_CTX *mem_ctx; enum MAPISTATUS retval; struct mapi_profile *profile; char *profname = NULL; char **value = NULL; unsigned int count = 0; unsigned int i; mem_ctx = talloc_named(mapi_ctx->mem_ctx, 0, "mapiprofile_attribute"); profile = talloc(mem_ctx, struct mapi_profile); if (!opt_profname) { if ((retval = GetDefaultProfile(mapi_ctx, &profname)) != MAPI_E_SUCCESS) { mapi_errstr("GetDefaultProfile", retval); exit (1); } } else { profname = talloc_strdup(mem_ctx, (const char *)opt_profname); } retval = OpenProfile(mapi_ctx, profile, profname, NULL); if (retval && (retval != MAPI_E_INVALID_PARAMETER)) { mapi_errstr("OpenProfile", retval); talloc_free(profname); talloc_free(mem_ctx); exit (1); } if ((retval = GetProfileAttr(profile, attribute, &count, &value))) { mapi_errstr("ProfileGetAttr", retval); talloc_free(profname); talloc_free(mem_ctx); exit (1); } printf("Profile %s: results(%u)\n", profname, count); for (i = 0; i < count; i++) { printf("\t%s = %s\n", attribute, value[i]); } MAPIFreeBuffer(value); talloc_free(profname); talloc_free(mem_ctx); } static void show_help(poptContext pc, const char *param) { printf("%s argument missing\n", param); poptPrintUsage(pc, stderr, 0); exit (1); } int main(int argc, const char *argv[]) { TALLOC_CTX *mem_ctx; struct mapi_context *mapi_ctx = NULL; int error; poptContext pc; int opt; int i; char *default_path; bool found = false; bool create = false; bool delete = false; bool list = false; bool listlangs = false; bool dump = false; bool newdb = false; bool setdflt = false; bool getdflt = false; bool getfqdn = false; bool opt_dumpdata = false; bool opt_seal = false; const char *opt_debuglevel = NULL; const char *ldif = NULL; const char *address = NULL; const char *workstation = NULL; const char *domain = NULL; const char *realm = NULL; const char *username = NULL; const char *language = NULL; const char *pattern = NULL; const char *password = NULL; const char *profdb = NULL; const char *profname = NULL; const char *rename = NULL; const char *attribute = NULL; const char *opt_tmp = NULL; const char *opt_krb = NULL; const char *version = NULL; uint32_t nopass = 0; char hostname[256]; int retcode = EXIT_SUCCESS; enum {OPT_PROFILE_DB=1000, OPT_PROFILE, OPT_ADDRESS, OPT_WORKSTATION, OPT_DOMAIN, OPT_REALM, OPT_USERNAME, OPT_LANGUAGE, OPT_PASSWORD, OPT_CREATE_PROFILE, OPT_DELETE_PROFILE, OPT_LIST_PROFILE, OPT_DUMP_PROFILE, OPT_DUMP_ATTR, OPT_PROFILE_NEWDB, OPT_PROFILE_LDIF, OPT_LIST_LANGS, OPT_PROFILE_SET_DFLT, OPT_PROFILE_GET_DFLT, OPT_PATTERN, OPT_GETFQDN, OPT_NOPASS, OPT_RENAME_PROFILE, OPT_DUMPDATA, OPT_DEBUGLEVEL, OPT_ENCRYPT_CONN, OPT_EXCHANGE_VERSION, OPT_KRB}; struct poptOption long_options[] = { POPT_AUTOHELP {"ldif", 'L', POPT_ARG_STRING, NULL, OPT_PROFILE_LDIF, "set the ldif path", "PATH"}, {"getdefault", 'G', POPT_ARG_NONE, NULL, OPT_PROFILE_GET_DFLT, "get the default profile", NULL}, {"default", 'S', POPT_ARG_NONE, NULL, OPT_PROFILE_SET_DFLT, "set the default profile", NULL}, {"newdb", 'n', POPT_ARG_NONE, NULL, OPT_PROFILE_NEWDB, "create a new profile store", NULL}, {"database", 'f', POPT_ARG_STRING, NULL, OPT_PROFILE_DB, "set the profile database path", "PATH"}, {"profile", 'P', POPT_ARG_STRING, NULL, OPT_PROFILE, "set the profile name", "PROFILE"}, {"address", 'I', POPT_ARG_STRING, NULL, OPT_ADDRESS, "set the exchange server IP address", "xxx.xxx.xxx.xxx"}, {"workstation", 'M', POPT_ARG_STRING, NULL, OPT_WORKSTATION, "set the workstation", "WORKSTATION_NAME"}, {"domain", 'D', POPT_ARG_STRING, NULL, OPT_DOMAIN, "set the domain/workgroup", "DOMAIN"}, {"realm", 'R', POPT_ARG_STRING, NULL, OPT_REALM, "set the realm", "REALM"}, {"encrypt", 'E', POPT_ARG_NONE, NULL, OPT_ENCRYPT_CONN, "enable encryption with Exchange server", NULL }, {"exchange-version", 'v', POPT_ARG_STRING, NULL, OPT_EXCHANGE_VERSION, "specify Exchange server version", "2000" }, {"username", 'u', POPT_ARG_STRING, NULL, OPT_USERNAME, "set the profile username", "USERNAME"}, {"language", 'C', POPT_ARG_STRING, NULL, OPT_LANGUAGE, "set the user's language (if different from system one)", "LANGUAGE"}, {"pattern", 's', POPT_ARG_STRING, NULL, OPT_PATTERN, "username to search for", "USERNAME"}, {"password", 'p', POPT_ARG_STRING, NULL, OPT_PASSWORD, "set the profile password", "PASSWORD"}, {"nopass", 0, POPT_ARG_NONE, NULL, OPT_NOPASS, "do not save password in the profile", NULL}, {"create", 'c', POPT_ARG_NONE, NULL, OPT_CREATE_PROFILE, "create a profile in the database", NULL}, {"delete", 'r', POPT_ARG_NONE, NULL, OPT_DELETE_PROFILE, "delete a profile in the database", NULL}, {"rename", 'R', POPT_ARG_STRING, NULL, OPT_RENAME_PROFILE, "rename a profile in the database", NULL}, {"list", 'l', POPT_ARG_NONE, NULL, OPT_LIST_PROFILE, "list existing profiles in the database", NULL}, {"listlangs", 0, POPT_ARG_NONE, NULL, OPT_LIST_LANGS, "list all recognised languages", NULL}, {"dump", 0, POPT_ARG_NONE, NULL, OPT_DUMP_PROFILE, "dump a profile entry", NULL}, {"attr", 'a', POPT_ARG_STRING, NULL, OPT_DUMP_ATTR, "print an attribute value", "VALUE"}, {"dump-data", 0, POPT_ARG_NONE, NULL, OPT_DUMPDATA, "dump the hex data", NULL}, {"debuglevel", 'd', POPT_ARG_STRING, NULL, OPT_DEBUGLEVEL, "set the debug level", "LEVEL"}, {"getfqdn", 0, POPT_ARG_NONE, NULL, OPT_GETFQDN, "returns the DNS FQDN of the NSPI server matching the legacyDN", NULL}, {"kerberos", 'k', POPT_ARG_STRING, NULL, OPT_KRB, "specify kerberos behavior (guess by default)", "{yes|no}"}, POPT_OPENCHANGE_VERSION { NULL, 0, POPT_ARG_NONE, NULL, 0, NULL, NULL } }; mem_ctx = talloc_named(NULL, 0, "mapiprofile"); pc = poptGetContext("mapiprofile", argc, argv, long_options, 0); while ((opt = poptGetNextOpt(pc)) != -1) { switch(opt) { case OPT_DUMPDATA: opt_dumpdata = true; break; case OPT_DEBUGLEVEL: opt_debuglevel = poptGetOptArg(pc); break; case OPT_PROFILE_LDIF: opt_tmp = poptGetOptArg(pc); ldif = talloc_strdup(mem_ctx, opt_tmp); free((void*)opt_tmp); opt_tmp = NULL; break; case OPT_PROFILE_NEWDB: newdb = true; break; case OPT_PROFILE_SET_DFLT: setdflt = true; break; case OPT_PROFILE_GET_DFLT: getdflt = true; break; case OPT_PROFILE_DB: opt_tmp = poptGetOptArg(pc); profdb = talloc_strdup(mem_ctx, opt_tmp); free((void*)opt_tmp); opt_tmp = NULL; break; case OPT_PROFILE: profname = poptGetOptArg(pc); break; case OPT_ADDRESS: address = poptGetOptArg(pc); break; case OPT_WORKSTATION: opt_tmp = poptGetOptArg(pc); workstation = talloc_strdup(mem_ctx, opt_tmp); free((void*)opt_tmp); opt_tmp = NULL; break; case OPT_DOMAIN: domain = poptGetOptArg(pc); break; case OPT_REALM: realm = poptGetOptArg(pc); break; case OPT_ENCRYPT_CONN: opt_seal = true; break; case OPT_EXCHANGE_VERSION: opt_tmp = poptGetOptArg(pc); version = talloc_strdup(mem_ctx, opt_tmp); free((void *)opt_tmp); opt_tmp = NULL; break; case OPT_USERNAME: username = poptGetOptArg(pc); break; case OPT_LANGUAGE: opt_tmp = poptGetOptArg(pc); language = talloc_strdup(mem_ctx, opt_tmp); free((void*)opt_tmp); opt_tmp = NULL; break; case OPT_PATTERN: pattern = poptGetOptArg(pc); break; case OPT_PASSWORD: password = poptGetOptArg(pc); break; case OPT_NOPASS: nopass = 1; break; case OPT_CREATE_PROFILE: create = true; break; case OPT_DELETE_PROFILE: delete = true; break; case OPT_RENAME_PROFILE: rename = poptGetOptArg(pc); break; case OPT_LIST_PROFILE: list = true; break; case OPT_LIST_LANGS: listlangs = true; break; case OPT_DUMP_PROFILE: dump = true; break; case OPT_DUMP_ATTR: attribute = poptGetOptArg(pc); break; case OPT_GETFQDN: getfqdn = true; break; case OPT_KRB: opt_krb = poptGetOptArg(pc); break; } } /* Sanity check on options */ if (!profdb) { default_path = talloc_asprintf(mem_ctx, DEFAULT_DIR, getenv("HOME")); error = mkdir(default_path, 0700); talloc_free(default_path); if ((error == -1) && (errno != EEXIST)) { perror("mkdir"); retcode = EXIT_FAILURE; goto cleanup; } profdb = talloc_asprintf(mem_ctx, DEFAULT_PROFDB, getenv("HOME")); } if ((list == false) && (getfqdn == false) && (newdb == false) && (listlangs == false) && (getdflt == false) && (dump == false) && (rename == NULL) && (!attribute) && (!profname || !profdb)) { poptPrintUsage(pc, stderr, 0); retcode = EXIT_FAILURE; goto cleanup; } if (newdb == true) { if (!ldif) { ldif = talloc_strdup(mem_ctx, mapi_profile_get_ldif_path()); } if (!ldif) show_help(pc, "ldif"); if (!mapiprofile_createdb(profdb, ldif)) { retcode = EXIT_FAILURE; goto cleanup; } } if (MAPIInitialize(&mapi_ctx, profdb) != MAPI_E_SUCCESS) { mapi_errstr("MAPIInitialize", GetLastError()); exit (1); } if (opt_krb) { if (strncmp(opt_krb, "yes", 3) && strncmp(opt_krb, "no", 2)) { fprintf(stderr, "kerberos value must be 'yes' or 'no'\n"); poptPrintUsage(pc, stderr, 0); retcode = EXIT_FAILURE; goto cleanup; } } /* Process the code here */ if (!workstation) { gethostname(hostname, sizeof(hostname) - 1); hostname[sizeof(hostname) - 1] = 0; workstation = hostname; } if (create == true) { if (!profname) show_help(pc, "profile"); if (!password && !nopass) show_help(pc, "password"); if (!username) show_help(pc, "username"); if (!address) show_help(pc, "address"); if (!version) { version = talloc_strdup(mem_ctx, DEFAULT_EXCHANGE_VERSION); } for (i = 0; exchange_version[i].name; i++) { if (!strcasecmp(version, exchange_version[i].name)) { version = talloc_strdup(mem_ctx, exchange_version[i].name); found = true; break; } } if (found == false) { printf("Invalid Exchange server version. Possible values are:\n"); for (i = 0; exchange_version[i].name; i++) { printf("\t[*] %s\n", exchange_version[i].name); } goto cleanup; } /* Force encrypt parameter if exchange2010 is specified */ if (!strcasecmp(version, "2010")) { opt_seal = true; } talloc_free((void *)version); if (! mapiprofile_create(mapi_ctx, profdb, profname, pattern, username, password, address, language, workstation, domain, realm, nopass, opt_seal, opt_dumpdata, opt_debuglevel, exchange_version[i].version, opt_krb)) { retcode = EXIT_FAILURE; goto cleanup; } } if (rename) { mapiprofile_rename(mapi_ctx, profdb, profname, rename); } if (getfqdn == true) { mapiprofile_get_fqdn(mapi_ctx, profdb, profname, password, opt_dumpdata); } if (listlangs == true) { mapidump_languages_list(); } if (setdflt == true) { mapiprofile_set_default(mapi_ctx, profdb, profname); } if (getdflt == true) { mapiprofile_get_default(mapi_ctx, profdb); } if (delete == true) { mapiprofile_delete(mapi_ctx, profdb, profname); } if (list == true) { mapiprofile_list(mapi_ctx, profdb); } if (dump == true) { mapiprofile_dump(mapi_ctx, profdb, profname); } if (attribute) { mapiprofile_attribute(mapi_ctx, profdb, profname, attribute); } cleanup: free((void*)opt_debuglevel); free((void*)profname); free((void*)address); free((void*)domain); free((void*)realm); free((void*)username); free((void*)pattern); free((void*)password); free((void*)rename); free((void*)attribute); if (mapi_ctx) MAPIUninitialize(mapi_ctx); poptFreeContext(pc); talloc_free(mem_ctx); return retcode; } openchange-2.0/utils/mapitest/000077500000000000000000000000001223057412600164525ustar00rootroot00000000000000openchange-2.0/utils/mapitest/Doxyfile.in000066400000000000000000001463711223057412600206010ustar00rootroot00000000000000# Doxyfile 1.5.2 # This file describes the settings to be used by the documentation system # doxygen (www.doxygen.org) for a project # # All text after a hash (#) is considered a comment and will be ignored # The format is: # TAG = value [value, ...] # For lists items can also be appended using: # TAG += value [value, ...] # Values that contain spaces should be placed between quotes (" ") #--------------------------------------------------------------------------- # Project related configuration options #--------------------------------------------------------------------------- # This tag specifies the encoding used for all characters in the config file that # follow. The default is UTF-8 which is also the encoding used for all text before # the first occurrence of this tag. Doxygen uses libiconv (or the iconv built into # libc) for the transcoding. See http://www.gnu.org/software/libiconv for the list of # possible encodings. DOXYFILE_ENCODING = UTF-8 # The PROJECT_NAME tag is a single word (or a sequence of words surrounded # by quotes) that should identify the project. PROJECT_NAME = MAPI Tests # The PROJECT_NUMBER tag can be used to enter a project or revision number. # This could be handy for archiving the generated documentation or # if some version control system is used. PROJECT_NUMBER = @PACKAGE_VERSION@ # The OUTPUT_DIRECTORY tag is used to specify the (relative or absolute) # base path where the generated documentation will be put. # If a relative path is entered, it will be relative to the location # where doxygen was started. If left blank the current directory will be used. OUTPUT_DIRECTORY = apidocs # If the CREATE_SUBDIRS tag is set to YES, then doxygen will create # 4096 sub-directories (in 2 levels) under the output directory of each output # format and will distribute the generated files over these directories. # Enabling this option can be useful when feeding doxygen a huge amount of # source files, where putting all generated files in the same directory would # otherwise cause performance problems for the file system. CREATE_SUBDIRS = NO # The OUTPUT_LANGUAGE tag is used to specify the language in which all # documentation generated by doxygen is written. Doxygen will use this # information to generate all constant output in the proper language. # The default language is English, other supported languages are: # Afrikaans, Arabic, Brazilian, Catalan, Chinese, Chinese-Traditional, # Croatian, Czech, Danish, Dutch, Finnish, French, German, Greek, Hungarian, # Italian, Japanese, Japanese-en (Japanese with English messages), Korean, # Korean-en, Lithuanian, Norwegian, Polish, Portuguese, Romanian, Russian, # Serbian, Slovak, Slovene, Spanish, Swedish, and Ukrainian. OUTPUT_LANGUAGE = English # If the BRIEF_MEMBER_DESC tag is set to YES (the default) Doxygen will # include brief member descriptions after the members that are listed in # the file and class documentation (similar to JavaDoc). # Set to NO to disable this. BRIEF_MEMBER_DESC = YES # If the REPEAT_BRIEF tag is set to YES (the default) Doxygen will prepend # the brief description of a member or function before the detailed description. # Note: if both HIDE_UNDOC_MEMBERS and BRIEF_MEMBER_DESC are set to NO, the # brief descriptions will be completely suppressed. REPEAT_BRIEF = YES # This tag implements a quasi-intelligent brief description abbreviator # that is used to form the text in various listings. Each string # in this list, if found as the leading text of the brief description, will be # stripped from the text and the result after processing the whole list, is # used as the annotated text. Otherwise, the brief description is used as-is. # If left blank, the following values are used ("$name" is automatically # replaced with the name of the entity): "The $name class" "The $name widget" # "The $name file" "is" "provides" "specifies" "contains" # "represents" "a" "an" "the" ABBREVIATE_BRIEF = # If the ALWAYS_DETAILED_SEC and REPEAT_BRIEF tags are both set to YES then # Doxygen will generate a detailed section even if there is only a brief # description. ALWAYS_DETAILED_SEC = NO # If the INLINE_INHERITED_MEMB tag is set to YES, doxygen will show all # inherited members of a class in the documentation of that class as if those # members were ordinary class members. Constructors, destructors and assignment # operators of the base classes will not be shown. INLINE_INHERITED_MEMB = NO # If the FULL_PATH_NAMES tag is set to YES then Doxygen will prepend the full # path before files name in the file list and in the header files. If set # to NO the shortest path that makes the file name unique will be used. FULL_PATH_NAMES = YES # If the FULL_PATH_NAMES tag is set to YES then the STRIP_FROM_PATH tag # can be used to strip a user-defined part of the path. Stripping is # only done if one of the specified strings matches the left-hand part of # the path. The tag can be used to show relative paths in the file list. # If left blank the directory from which doxygen is run is used as the # path to strip. STRIP_FROM_PATH = # The STRIP_FROM_INC_PATH tag can be used to strip a user-defined part of # the path mentioned in the documentation of a class, which tells # the reader which header file to include in order to use a class. # If left blank only the name of the header file containing the class # definition is used. Otherwise one should specify the include paths that # are normally passed to the compiler using the -I flag. STRIP_FROM_INC_PATH = # If the SHORT_NAMES tag is set to YES, doxygen will generate much shorter # (but less readable) file names. This can be useful is your file systems # doesn't support long names like on DOS, Mac, or CD-ROM. SHORT_NAMES = NO # If the JAVADOC_AUTOBRIEF tag is set to YES then Doxygen # will interpret the first line (until the first dot) of a JavaDoc-style # comment as the brief description. If set to NO, the JavaDoc # comments will behave just like the Qt-style comments (thus requiring an # explicit @brief command for a brief description. JAVADOC_AUTOBRIEF = YES # The MULTILINE_CPP_IS_BRIEF tag can be set to YES to make Doxygen # treat a multi-line C++ special comment block (i.e. a block of //! or /// # comments) as a brief description. This used to be the default behaviour. # The new default is to treat a multi-line C++ comment block as a detailed # description. Set this tag to YES if you prefer the old behaviour instead. MULTILINE_CPP_IS_BRIEF = NO # If the INHERIT_DOCS tag is set to YES (the default) then an undocumented # member inherits the documentation from any documented member that it # re-implements. INHERIT_DOCS = YES # If the SEPARATE_MEMBER_PAGES tag is set to YES, then doxygen will produce # a new page for each member. If set to NO, the documentation of a member will # be part of the file/class/namespace that contains it. SEPARATE_MEMBER_PAGES = NO # The TAB_SIZE tag can be used to set the number of spaces in a tab. # Doxygen uses this value to replace tabs by spaces in code fragments. TAB_SIZE = 8 # This tag can be used to specify a number of aliases that acts # as commands in the documentation. An alias has the form "name=value". # For example adding "sideeffect=\par Side Effects:\n" will allow you to # put the command \sideeffect (or @sideeffect) in the documentation, which # will result in a user-defined paragraph with heading "Side Effects:". # You can put \n's in the value part of an alias to insert newlines. ALIASES = # Set the OPTIMIZE_OUTPUT_FOR_C tag to YES if your project consists of C # sources only. Doxygen will then generate output that is more tailored for C. # For instance, some of the names that are used will be different. The list # of all members will be omitted, etc. OPTIMIZE_OUTPUT_FOR_C = YES # Set the OPTIMIZE_OUTPUT_JAVA tag to YES if your project consists of Java # sources only. Doxygen will then generate output that is more tailored for Java. # For instance, namespaces will be presented as packages, qualified scopes # will look different, etc. OPTIMIZE_OUTPUT_JAVA = NO # If you use STL classes (i.e. std::string, std::vector, etc.) but do not want to # include (a tag file for) the STL sources as input, then you should # set this tag to YES in order to let doxygen match functions declarations and # definitions whose arguments contain STL classes (e.g. func(std::string); v.s. # func(std::string) {}). This also make the inheritance and collaboration # diagrams that involve STL classes more complete and accurate. BUILTIN_STL_SUPPORT = NO # If you use Microsoft's C++/CLI language, you should set this option to YES to # enable parsing support. CPP_CLI_SUPPORT = NO # If member grouping is used in the documentation and the DISTRIBUTE_GROUP_DOC # tag is set to YES, then doxygen will reuse the documentation of the first # member in the group (if any) for the other members of the group. By default # all members of a group must be documented explicitly. DISTRIBUTE_GROUP_DOC = NO # Set the SUBGROUPING tag to YES (the default) to allow class member groups of # the same type (for instance a group of public functions) to be put as a # subgroup of that type (e.g. under the Public Functions section). Set it to # NO to prevent subgrouping. Alternatively, this can be done per class using # the \nosubgrouping command. SUBGROUPING = YES #--------------------------------------------------------------------------- # Build related configuration options #--------------------------------------------------------------------------- # If the EXTRACT_ALL tag is set to YES doxygen will assume all entities in # documentation are documented, even if no documentation was available. # Private class members and static file members will be hidden unless # the EXTRACT_PRIVATE and EXTRACT_STATIC tags are set to YES EXTRACT_ALL = NO # If the EXTRACT_PRIVATE tag is set to YES all private members of a class # will be included in the documentation. EXTRACT_PRIVATE = NO # If the EXTRACT_STATIC tag is set to YES all static members of a file # will be included in the documentation. EXTRACT_STATIC = NO # If the EXTRACT_LOCAL_CLASSES tag is set to YES classes (and structs) # defined locally in source files will be included in the documentation. # If set to NO only classes defined in header files are included. EXTRACT_LOCAL_CLASSES = NO # This flag is only useful for Objective-C code. When set to YES local # methods, which are defined in the implementation section but not in # the interface are included in the documentation. # If set to NO (the default) only methods in the interface are included. EXTRACT_LOCAL_METHODS = NO # If the HIDE_UNDOC_MEMBERS tag is set to YES, Doxygen will hide all # undocumented members of documented classes, files or namespaces. # If set to NO (the default) these members will be included in the # various overviews, but no documentation section is generated. # This option has no effect if EXTRACT_ALL is enabled. HIDE_UNDOC_MEMBERS = YES # If the HIDE_UNDOC_CLASSES tag is set to YES, Doxygen will hide all # undocumented classes that are normally visible in the class hierarchy. # If set to NO (the default) these classes will be included in the various # overviews. This option has no effect if EXTRACT_ALL is enabled. HIDE_UNDOC_CLASSES = YES # If the HIDE_FRIEND_COMPOUNDS tag is set to YES, Doxygen will hide all # friend (class|struct|union) declarations. # If set to NO (the default) these declarations will be included in the # documentation. HIDE_FRIEND_COMPOUNDS = YES # If the HIDE_IN_BODY_DOCS tag is set to YES, Doxygen will hide any # documentation blocks found inside the body of a function. # If set to NO (the default) these blocks will be appended to the # function's detailed documentation block. HIDE_IN_BODY_DOCS = NO # The INTERNAL_DOCS tag determines if documentation # that is typed after a \internal command is included. If the tag is set # to NO (the default) then the documentation will be excluded. # Set it to YES to include the internal documentation. INTERNAL_DOCS = NO # If the CASE_SENSE_NAMES tag is set to NO then Doxygen will only generate # file names in lower-case letters. If set to YES upper-case letters are also # allowed. This is useful if you have classes or files whose names only differ # in case and if your file system supports case sensitive file names. Windows # and Mac users are advised to set this option to NO. CASE_SENSE_NAMES = YES # If the HIDE_SCOPE_NAMES tag is set to NO (the default) then Doxygen # will show members with their full class and namespace scopes in the # documentation. If set to YES the scope will be hidden. HIDE_SCOPE_NAMES = NO # If the SHOW_INCLUDE_FILES tag is set to YES (the default) then Doxygen # will put a list of the files that are included by a file in the documentation # of that file. SHOW_INCLUDE_FILES = YES # If the INLINE_INFO tag is set to YES (the default) then a tag [inline] # is inserted in the documentation for inline members. INLINE_INFO = YES # If the SORT_MEMBER_DOCS tag is set to YES (the default) then doxygen # will sort the (detailed) documentation of file and class members # alphabetically by member name. If set to NO the members will appear in # declaration order. SORT_MEMBER_DOCS = YES # If the SORT_BRIEF_DOCS tag is set to YES then doxygen will sort the # brief documentation of file, namespace and class members alphabetically # by member name. If set to NO (the default) the members will appear in # declaration order. SORT_BRIEF_DOCS = YES # If the SORT_BY_SCOPE_NAME tag is set to YES, the class list will be # sorted by fully-qualified names, including namespaces. If set to # NO (the default), the class list will be sorted only by class name, # not including the namespace part. # Note: This option is not very useful if HIDE_SCOPE_NAMES is set to YES. # Note: This option applies only to the class list, not to the # alphabetical list. SORT_BY_SCOPE_NAME = NO # The GENERATE_TODOLIST tag can be used to enable (YES) or # disable (NO) the todo list. This list is created by putting \todo # commands in the documentation. GENERATE_TODOLIST = YES # The GENERATE_TESTLIST tag can be used to enable (YES) or # disable (NO) the test list. This list is created by putting \test # commands in the documentation. GENERATE_TESTLIST = YES # The GENERATE_BUGLIST tag can be used to enable (YES) or # disable (NO) the bug list. This list is created by putting \bug # commands in the documentation. GENERATE_BUGLIST = YES # The GENERATE_DEPRECATEDLIST tag can be used to enable (YES) or # disable (NO) the deprecated list. This list is created by putting # \deprecated commands in the documentation. GENERATE_DEPRECATEDLIST= YES # The ENABLED_SECTIONS tag can be used to enable conditional # documentation sections, marked by \if sectionname ... \endif. ENABLED_SECTIONS = # The MAX_INITIALIZER_LINES tag determines the maximum number of lines # the initial value of a variable or define consists of for it to appear in # the documentation. If the initializer consists of more lines than specified # here it will be hidden. Use a value of 0 to hide initializers completely. # The appearance of the initializer of individual variables and defines in the # documentation can be controlled using \showinitializer or \hideinitializer # command in the documentation regardless of this setting. MAX_INITIALIZER_LINES = 30 # Set the SHOW_USED_FILES tag to NO to disable the list of files generated # at the bottom of the documentation of classes and structs. If set to YES the # list will mention the files that were used to generate the documentation. SHOW_USED_FILES = YES # If the sources in your project are distributed over multiple directories # then setting the SHOW_DIRECTORIES tag to YES will show the directory hierarchy # in the documentation. The default is NO. SHOW_DIRECTORIES = NO # The FILE_VERSION_FILTER tag can be used to specify a program or script that # doxygen should invoke to get the current version for each file (typically from the # version control system). Doxygen will invoke the program by executing (via # popen()) the command , where is the value of # the FILE_VERSION_FILTER tag, and is the name of an input file # provided by doxygen. Whatever the program writes to standard output # is used as the file version. See the manual for examples. FILE_VERSION_FILTER = #--------------------------------------------------------------------------- # configuration options related to warning and progress messages #--------------------------------------------------------------------------- # The QUIET tag can be used to turn on/off the messages that are generated # by doxygen. Possible values are YES and NO. If left blank NO is used. QUIET = NO # The WARNINGS tag can be used to turn on/off the warning messages that are # generated by doxygen. Possible values are YES and NO. If left blank # NO is used. WARNINGS = YES # If WARN_IF_UNDOCUMENTED is set to YES, then doxygen will generate warnings # for undocumented members. If EXTRACT_ALL is set to YES then this flag will # automatically be disabled. WARN_IF_UNDOCUMENTED = YES # If WARN_IF_DOC_ERROR is set to YES, doxygen will generate warnings for # potential errors in the documentation, such as not documenting some # parameters in a documented function, or documenting parameters that # don't exist or using markup commands wrongly. WARN_IF_DOC_ERROR = YES # This WARN_NO_PARAMDOC option can be abled to get warnings for # functions that are documented, but have no documentation for their parameters # or return value. If set to NO (the default) doxygen will only warn about # wrong or incomplete parameter documentation, but not about the absence of # documentation. WARN_NO_PARAMDOC = NO # The WARN_FORMAT tag determines the format of the warning messages that # doxygen can produce. The string should contain the $file, $line, and $text # tags, which will be replaced by the file and line number from which the # warning originated and the warning text. Optionally the format may contain # $version, which will be replaced by the version of the file (if it could # be obtained via FILE_VERSION_FILTER) WARN_FORMAT = "$file:$line: $text" # The WARN_LOGFILE tag can be used to specify a file to which warning # and error messages should be written. If left blank the output is written # to stderr. WARN_LOGFILE = #--------------------------------------------------------------------------- # configuration options related to the input files #--------------------------------------------------------------------------- # The INPUT tag can be used to specify the files and/or directories that contain # documented source files. You may enter file names like "myfile.cpp" or # directories like "/usr/src/myproject". Separate the files or directories # with spaces. INPUT = utils/mapitest utils/mapitest/modules # This tag can be used to specify the character encoding of the source files that # doxygen parses. Internally doxygen uses the UTF-8 encoding, which is also the default # input encoding. Doxygen uses libiconv (or the iconv built into libc) for the transcoding. # See http://www.gnu.org/software/libiconv for the list of possible encodings. INPUT_ENCODING = UTF-8 # If the value of the INPUT tag contains directories, you can use the # FILE_PATTERNS tag to specify one or more wildcard pattern (like *.cpp # and *.h) to filter out the source-files in the directories. If left # blank the following patterns are tested: # *.c *.cc *.cxx *.cpp *.c++ *.java *.ii *.ixx *.ipp *.i++ *.inl *.h *.hh *.hxx # *.hpp *.h++ *.idl *.odl *.cs *.php *.php3 *.inc *.m *.mm *.py FILE_PATTERNS = *.h *.c *.doxy # The RECURSIVE tag can be used to turn specify whether or not subdirectories # should be searched for input files as well. Possible values are YES and NO. # If left blank NO is used. RECURSIVE = NO # The EXCLUDE tag can be used to specify files and/or directories that should # excluded from the INPUT source files. This way you can easily exclude a # subdirectory from a directory tree whose root is specified with the INPUT tag. EXCLUDE = *_private.h # The EXCLUDE_SYMLINKS tag can be used select whether or not files or # directories that are symbolic links (a Unix filesystem feature) are excluded # from the input. EXCLUDE_SYMLINKS = NO # If the value of the INPUT tag contains directories, you can use the # EXCLUDE_PATTERNS tag to specify one or more wildcard patterns to exclude # certain files from those directories. Note that the wildcards are matched # against the file with absolute path, so to exclude all test directories # for example use the pattern */test/* EXCLUDE_PATTERNS = *.yy.c *_private.h # The EXCLUDE_SYMBOLS tag can be used to specify one or more symbol names # (namespaces, classes, functions, etc.) that should be excluded from the output. # The symbol name can be a fully qualified name, a word, or if the wildcard * is used, # a substring. Examples: ANamespace, AClass, AClass::ANamespace, ANamespace::*Test EXCLUDE_SYMBOLS = # The EXAMPLE_PATH tag can be used to specify one or more files or # directories that contain example code fragments that are included (see # the \include command). EXAMPLE_PATH = # If the value of the EXAMPLE_PATH tag contains directories, you can use the # EXAMPLE_PATTERNS tag to specify one or more wildcard pattern (like *.cpp # and *.h) to filter out the source-files in the directories. If left # blank all files are included. EXAMPLE_PATTERNS = # If the EXAMPLE_RECURSIVE tag is set to YES then subdirectories will be # searched for input files to be used with the \include or \dontinclude # commands irrespective of the value of the RECURSIVE tag. # Possible values are YES and NO. If left blank NO is used. EXAMPLE_RECURSIVE = NO # The IMAGE_PATH tag can be used to specify one or more files or # directories that contain image that are included in the documentation (see # the \image command). IMAGE_PATH = doc/doxygen/pictures/ # The INPUT_FILTER tag can be used to specify a program that doxygen should # invoke to filter for each input file. Doxygen will invoke the filter program # by executing (via popen()) the command , where # is the value of the INPUT_FILTER tag, and is the name of an # input file. Doxygen will then use the output that the filter program writes # to standard output. If FILTER_PATTERNS is specified, this tag will be # ignored. INPUT_FILTER = "sed \ -e '20,40s/.*\//' \ -e '20,40s/.*\//' \ -e '20,40s/.*\//' \ -e '20,40s/.*\//' \ -e '20,40s/.*\//' \ -e '20,40s/.*\//' \ -e '20,40s/.*\//' \ -e '20,40s/.*\//' \ -e '20,40s/.*\//' \ -e '20,40s/.*\//' \ -e '20,40s/.*\//' \ -e 's/_PUBLIC_//'" # The FILTER_PATTERNS tag can be used to specify filters on a per file pattern # basis. Doxygen will compare the file name with each pattern and apply the # filter if there is a match. The filters are a list of the form: # pattern=filter (like *.cpp=my_cpp_filter). See INPUT_FILTER for further # info on how filters are used. If FILTER_PATTERNS is empty, INPUT_FILTER # is applied to all files. FILTER_PATTERNS = # If the FILTER_SOURCE_FILES tag is set to YES, the input filter (if set using # INPUT_FILTER) will be used to filter the input files when producing source # files to browse (i.e. when SOURCE_BROWSER is set to YES). FILTER_SOURCE_FILES = NO #--------------------------------------------------------------------------- # configuration options related to source browsing #--------------------------------------------------------------------------- # If the SOURCE_BROWSER tag is set to YES then a list of source files will # be generated. Documented entities will be cross-referenced with these sources. # Note: To get rid of all source code in the generated output, make sure also # VERBATIM_HEADERS is set to NO. SOURCE_BROWSER = NO # Setting the INLINE_SOURCES tag to YES will include the body # of functions and classes directly in the documentation. INLINE_SOURCES = NO # Setting the STRIP_CODE_COMMENTS tag to YES (the default) will instruct # doxygen to hide any special comment blocks from generated source code # fragments. Normal C and C++ comments will always remain visible. STRIP_CODE_COMMENTS = YES # If the REFERENCED_BY_RELATION tag is set to YES (the default) # then for each documented function all documented # functions referencing it will be listed. REFERENCED_BY_RELATION = YES # If the REFERENCES_RELATION tag is set to YES (the default) # then for each documented function all documented entities # called/used by that function will be listed. REFERENCES_RELATION = YES # If the REFERENCES_LINK_SOURCE tag is set to YES (the default) # and SOURCE_BROWSER tag is set to YES, then the hyperlinks from # functions in REFERENCES_RELATION and REFERENCED_BY_RELATION lists will # link to the source code. Otherwise they will link to the documentstion. REFERENCES_LINK_SOURCE = YES # If the USE_HTAGS tag is set to YES then the references to source code # will point to the HTML generated by the htags(1) tool instead of doxygen # built-in source browser. The htags tool is part of GNU's global source # tagging system (see http://www.gnu.org/software/global/global.html). You # will need version 4.8.6 or higher. USE_HTAGS = NO # If the VERBATIM_HEADERS tag is set to YES (the default) then Doxygen # will generate a verbatim copy of the header file for each class for # which an include is specified. Set to NO to disable this. VERBATIM_HEADERS = NO #--------------------------------------------------------------------------- # configuration options related to the alphabetical class index #--------------------------------------------------------------------------- # If the ALPHABETICAL_INDEX tag is set to YES, an alphabetical index # of all compounds will be generated. Enable this if the project # contains a lot of classes, structs, unions or interfaces. ALPHABETICAL_INDEX = NO # If the alphabetical index is enabled (see ALPHABETICAL_INDEX) then # the COLS_IN_ALPHA_INDEX tag can be used to specify the number of columns # in which this list will be split (can be a number in the range [1..20]) COLS_IN_ALPHA_INDEX = 5 # In case all classes in a project start with a common prefix, all # classes will be put under the same header in the alphabetical index. # The IGNORE_PREFIX tag can be used to specify one or more prefixes that # should be ignored while generating the index headers. IGNORE_PREFIX = #--------------------------------------------------------------------------- # configuration options related to the HTML output #--------------------------------------------------------------------------- # If the GENERATE_HTML tag is set to YES (the default) Doxygen will # generate HTML output. GENERATE_HTML = YES # The HTML_OUTPUT tag is used to specify where the HTML docs will be put. # If a relative path is entered the value of OUTPUT_DIRECTORY will be # put in front of it. If left blank `html' will be used as the default path. HTML_OUTPUT = html/mapitest # The HTML_FILE_EXTENSION tag can be used to specify the file extension for # each generated HTML page (for example: .htm,.php,.asp). If it is left blank # doxygen will generate files with .html extension. HTML_FILE_EXTENSION = .html # The HTML_HEADER tag can be used to specify a personal HTML header for # each generated HTML page. If it is left blank doxygen will generate a # standard header. HTML_HEADER = doc/doxygen/header.html # The HTML_FOOTER tag can be used to specify a personal HTML footer for # each generated HTML page. If it is left blank doxygen will generate a # standard footer. HTML_FOOTER = doc/doxygen/footer.html # The HTML_STYLESHEET tag can be used to specify a user-defined cascading # style sheet that is used by each HTML page. It can be used to # fine-tune the look of the HTML output. If the tag is left blank doxygen # will generate a default style sheet. Note that doxygen will try to copy # the style sheet file to the HTML output directory, so don't put your own # stylesheet in the HTML output directory as well, or it will be erased! HTML_STYLESHEET = doc/doxygen/apidocs.css # If the HTML_ALIGN_MEMBERS tag is set to YES, the members of classes, # files or namespaces will be aligned in HTML using tables. If set to # NO a bullet list will be used. HTML_ALIGN_MEMBERS = YES # If the GENERATE_HTMLHELP tag is set to YES, additional index files # will be generated that can be used as input for tools like the # Microsoft HTML help workshop to generate a compressed HTML help file (.chm) # of the generated HTML documentation. GENERATE_HTMLHELP = NO # If the GENERATE_HTMLHELP tag is set to YES, the CHM_FILE tag can # be used to specify the file name of the resulting .chm file. You # can add a path in front of the file if the result should not be # written to the html output directory. CHM_FILE = # If the GENERATE_HTMLHELP tag is set to YES, the HHC_LOCATION tag can # be used to specify the location (absolute path including file name) of # the HTML help compiler (hhc.exe). If non-empty doxygen will try to run # the HTML help compiler on the generated index.hhp. HHC_LOCATION = # If the GENERATE_HTMLHELP tag is set to YES, the GENERATE_CHI flag # controls if a separate .chi index file is generated (YES) or that # it should be included in the master .chm file (NO). GENERATE_CHI = NO # If the GENERATE_HTMLHELP tag is set to YES, the BINARY_TOC flag # controls whether a binary table of contents is generated (YES) or a # normal table of contents (NO) in the .chm file. BINARY_TOC = NO # The TOC_EXPAND flag can be set to YES to add extra items for group members # to the contents of the HTML help documentation and to the tree view. TOC_EXPAND = NO # The DISABLE_INDEX tag can be used to turn on/off the condensed index at # top of each HTML page. The value NO (the default) enables the index and # the value YES disables it. DISABLE_INDEX = NO # This tag can be used to set the number of enum values (range [1..20]) # that doxygen will group on one line in the generated HTML documentation. ENUM_VALUES_PER_LINE = 4 # If the GENERATE_TREEVIEW tag is set to YES, a side panel will be # generated containing a tree-like index structure (just like the one that # is generated for HTML Help). For this to work a browser that supports # JavaScript, DHTML, CSS and frames is required (for instance Mozilla 1.0+, # Netscape 6.0+, Internet explorer 5.0+, or Konqueror). Windows users are # probably better off using the HTML help feature. GENERATE_TREEVIEW = NO # If the treeview is enabled (see GENERATE_TREEVIEW) then this tag can be # used to set the initial width (in pixels) of the frame in which the tree # is shown. TREEVIEW_WIDTH = 250 #--------------------------------------------------------------------------- # configuration options related to the LaTeX output #--------------------------------------------------------------------------- # If the GENERATE_LATEX tag is set to YES (the default) Doxygen will # generate Latex output. GENERATE_LATEX = NO # The LATEX_OUTPUT tag is used to specify where the LaTeX docs will be put. # If a relative path is entered the value of OUTPUT_DIRECTORY will be # put in front of it. If left blank `latex' will be used as the default path. LATEX_OUTPUT = latex # The LATEX_CMD_NAME tag can be used to specify the LaTeX command name to be # invoked. If left blank `latex' will be used as the default command name. LATEX_CMD_NAME = latex # The MAKEINDEX_CMD_NAME tag can be used to specify the command name to # generate index for LaTeX. If left blank `makeindex' will be used as the # default command name. MAKEINDEX_CMD_NAME = makeindex # If the COMPACT_LATEX tag is set to YES Doxygen generates more compact # LaTeX documents. This may be useful for small projects and may help to # save some trees in general. COMPACT_LATEX = NO # The PAPER_TYPE tag can be used to set the paper type that is used # by the printer. Possible values are: a4, a4wide, letter, legal and # executive. If left blank a4wide will be used. PAPER_TYPE = letter # The EXTRA_PACKAGES tag can be to specify one or more names of LaTeX # packages that should be included in the LaTeX output. EXTRA_PACKAGES = # The LATEX_HEADER tag can be used to specify a personal LaTeX header for # the generated latex document. The header should contain everything until # the first chapter. If it is left blank doxygen will generate a # standard header. Notice: only use this tag if you know what you are doing! LATEX_HEADER = # If the PDF_HYPERLINKS tag is set to YES, the LaTeX that is generated # is prepared for conversion to pdf (using ps2pdf). The pdf file will # contain links (just like the HTML output) instead of page references # This makes the output suitable for online browsing using a pdf viewer. PDF_HYPERLINKS = YES # If the USE_PDFLATEX tag is set to YES, pdflatex will be used instead of # plain latex in the generated Makefile. Set this option to YES to get a # higher quality PDF documentation. USE_PDFLATEX = YES # If the LATEX_BATCHMODE tag is set to YES, doxygen will add the \\batchmode. # command to the generated LaTeX files. This will instruct LaTeX to keep # running if errors occur, instead of asking the user for help. # This option is also used when generating formulas in HTML. LATEX_BATCHMODE = NO # If LATEX_HIDE_INDICES is set to YES then doxygen will not # include the index chapters (such as File Index, Compound Index, etc.) # in the output. LATEX_HIDE_INDICES = NO #--------------------------------------------------------------------------- # configuration options related to the RTF output #--------------------------------------------------------------------------- # If the GENERATE_RTF tag is set to YES Doxygen will generate RTF output # The RTF output is optimized for Word 97 and may not look very pretty with # other RTF readers or editors. GENERATE_RTF = NO # The RTF_OUTPUT tag is used to specify where the RTF docs will be put. # If a relative path is entered the value of OUTPUT_DIRECTORY will be # put in front of it. If left blank `rtf' will be used as the default path. RTF_OUTPUT = rtf # If the COMPACT_RTF tag is set to YES Doxygen generates more compact # RTF documents. This may be useful for small projects and may help to # save some trees in general. COMPACT_RTF = NO # If the RTF_HYPERLINKS tag is set to YES, the RTF that is generated # will contain hyperlink fields. The RTF file will # contain links (just like the HTML output) instead of page references. # This makes the output suitable for online browsing using WORD or other # programs which support those fields. # Note: wordpad (write) and others do not support links. RTF_HYPERLINKS = NO # Load stylesheet definitions from file. Syntax is similar to doxygen's # config file, i.e. a series of assignments. You only have to provide # replacements, missing definitions are set to their default value. RTF_STYLESHEET_FILE = # Set optional variables used in the generation of an rtf document. # Syntax is similar to doxygen's config file. RTF_EXTENSIONS_FILE = #--------------------------------------------------------------------------- # configuration options related to the man page output #--------------------------------------------------------------------------- # If the GENERATE_MAN tag is set to YES (the default) Doxygen will # generate man pages GENERATE_MAN = NO # The MAN_OUTPUT tag is used to specify where the man pages will be put. # If a relative path is entered the value of OUTPUT_DIRECTORY will be # put in front of it. If left blank `man' will be used as the default path. MAN_OUTPUT = man # The MAN_EXTENSION tag determines the extension that is added to # the generated man pages (default is the subroutine's section .3) MAN_EXTENSION = .3 # If the MAN_LINKS tag is set to YES and Doxygen generates man output, # then it will generate one additional man file for each entity # documented in the real man page(s). These additional files # only source the real man page, but without them the man command # would be unable to find the correct page. The default is NO. MAN_LINKS = YES #--------------------------------------------------------------------------- # configuration options related to the XML output #--------------------------------------------------------------------------- # If the GENERATE_XML tag is set to YES Doxygen will # generate an XML file that captures the structure of # the code including all documentation. GENERATE_XML = NO # The XML_OUTPUT tag is used to specify where the XML pages will be put. # If a relative path is entered the value of OUTPUT_DIRECTORY will be # put in front of it. If left blank `xml' will be used as the default path. XML_OUTPUT = xml # The XML_SCHEMA tag can be used to specify an XML schema, # which can be used by a validating XML parser to check the # syntax of the XML files. XML_SCHEMA = # The XML_DTD tag can be used to specify an XML DTD, # which can be used by a validating XML parser to check the # syntax of the XML files. XML_DTD = # If the XML_PROGRAMLISTING tag is set to YES Doxygen will # dump the program listings (including syntax highlighting # and cross-referencing information) to the XML output. Note that # enabling this will significantly increase the size of the XML output. XML_PROGRAMLISTING = YES #--------------------------------------------------------------------------- # configuration options for the AutoGen Definitions output #--------------------------------------------------------------------------- # If the GENERATE_AUTOGEN_DEF tag is set to YES Doxygen will # generate an AutoGen Definitions (see autogen.sf.net) file # that captures the structure of the code including all # documentation. Note that this feature is still experimental # and incomplete at the moment. GENERATE_AUTOGEN_DEF = NO #--------------------------------------------------------------------------- # configuration options related to the Perl module output #--------------------------------------------------------------------------- # If the GENERATE_PERLMOD tag is set to YES Doxygen will # generate a Perl module file that captures the structure of # the code including all documentation. Note that this # feature is still experimental and incomplete at the # moment. GENERATE_PERLMOD = NO # If the PERLMOD_LATEX tag is set to YES Doxygen will generate # the necessary Makefile rules, Perl scripts and LaTeX code to be able # to generate PDF and DVI output from the Perl module output. PERLMOD_LATEX = NO # If the PERLMOD_PRETTY tag is set to YES the Perl module output will be # nicely formatted so it can be parsed by a human reader. This is useful # if you want to understand what is going on. On the other hand, if this # tag is set to NO the size of the Perl module output will be much smaller # and Perl will parse it just the same. PERLMOD_PRETTY = YES # The names of the make variables in the generated doxyrules.make file # are prefixed with the string contained in PERLMOD_MAKEVAR_PREFIX. # This is useful so different doxyrules.make files included by the same # Makefile don't overwrite each other's variables. PERLMOD_MAKEVAR_PREFIX = #--------------------------------------------------------------------------- # Configuration options related to the preprocessor #--------------------------------------------------------------------------- # If the ENABLE_PREPROCESSING tag is set to YES (the default) Doxygen will # evaluate all C-preprocessor directives found in the sources and include # files. ENABLE_PREPROCESSING = YES # If the MACRO_EXPANSION tag is set to YES Doxygen will expand all macro # names in the source code. If set to NO (the default) only conditional # compilation will be performed. Macro expansion can be done in a controlled # way by setting EXPAND_ONLY_PREDEF to YES. MACRO_EXPANSION = NO # If the EXPAND_ONLY_PREDEF and MACRO_EXPANSION tags are both set to YES # then the macro expansion is limited to the macros specified with the # PREDEFINED and EXPAND_AS_DEFINED tags. EXPAND_ONLY_PREDEF = NO # If the SEARCH_INCLUDES tag is set to YES (the default) the includes files # in the INCLUDE_PATH (see below) will be search if a #include is found. SEARCH_INCLUDES = YES # The INCLUDE_PATH tag can be used to specify one or more directories that # contain include files that are not input files but should be processed by # the preprocessor. INCLUDE_PATH = # You can use the INCLUDE_FILE_PATTERNS tag to specify one or more wildcard # patterns (like *.h and *.hpp) to filter out the header-files in the # directories. If left blank, the patterns specified with FILE_PATTERNS will # be used. INCLUDE_FILE_PATTERNS = # The PREDEFINED tag can be used to specify one or more macro names that # are defined before the preprocessor is started (similar to the -D option of # gcc). The argument of the tag is a list of macros of the form: name # or name=definition (no spaces). If the definition and the = are # omitted =1 is assumed. To prevent a macro definition from being # undefined via #undef or recursively expanded use the := operator # instead of the = operator. PREDEFINED = _PUBLIC_ # If the MACRO_EXPANSION and EXPAND_ONLY_PREDEF tags are set to YES then # this tag can be used to specify a list of macro names that should be expanded. # The macro definition that is found in the sources will be used. # Use the PREDEFINED tag if you want to use a different macro definition. EXPAND_AS_DEFINED = # If the SKIP_FUNCTION_MACROS tag is set to YES (the default) then # doxygen's preprocessor will remove all function-like macros that are alone # on a line, have an all uppercase name, and do not end with a semicolon. Such # function macros are typically used for boiler-plate code, and will confuse # the parser if not removed. SKIP_FUNCTION_MACROS = YES #--------------------------------------------------------------------------- # Configuration::additions related to external references #--------------------------------------------------------------------------- # The TAGFILES option can be used to specify one or more tagfiles. # Optionally an initial location of the external documentation # can be added for each tagfile. The format of a tag file without # this location is as follows: # TAGFILES = file1 file2 ... # Adding location for the tag files is done as follows: # TAGFILES = file1=loc1 "file2 = loc2" ... # where "loc1" and "loc2" can be relative or absolute paths or # URLs. If a location is present for each tag, the installdox tool # does not have to be run to correct the links. # Note that each tag file must have a unique name # (where the name does NOT include the path) # If a tag file is not located in the directory in which doxygen # is run, you must also specify the path to the tagfile here. TAGFILES = # When a file name is specified after GENERATE_TAGFILE, doxygen will create # a tag file that is based on the input files it reads. GENERATE_TAGFILE = # If the ALLEXTERNALS tag is set to YES all external classes will be listed # in the class index. If set to NO only the inherited external classes # will be listed. ALLEXTERNALS = NO # If the EXTERNAL_GROUPS tag is set to YES all external groups will be listed # in the modules index. If set to NO, only the current project's groups will # be listed. EXTERNAL_GROUPS = YES # The PERL_PATH should be the absolute path and name of the perl script # interpreter (i.e. the result of `which perl'). PERL_PATH = /usr/bin/perl #--------------------------------------------------------------------------- # Configuration options related to the dot tool #--------------------------------------------------------------------------- # If the CLASS_DIAGRAMS tag is set to YES (the default) Doxygen will # generate a inheritance diagram (in HTML, RTF and LaTeX) for classes with base # or super classes. Setting the tag to NO turns the diagrams off. Note that # this option is superseded by the HAVE_DOT option below. This is only a # fallback. It is recommended to install and use dot, since it yields more # powerful graphs. CLASS_DIAGRAMS = YES # You can define message sequence charts within doxygen comments using the \msc # command. Doxygen will then run the mscgen tool (see http://www.mcternan.me.uk/mscgen/) to # produce the chart and insert it in the documentation. The MSCGEN_PATH tag allows you to # specify the directory where the mscgen tool resides. If left empty the tool is assumed to # be found in the default search path. MSCGEN_PATH = # If set to YES, the inheritance and collaboration graphs will hide # inheritance and usage relations if the target is undocumented # or is not a class. HIDE_UNDOC_RELATIONS = YES # If you set the HAVE_DOT tag to YES then doxygen will assume the dot tool is # available from the path. This tool is part of Graphviz, a graph visualization # toolkit from AT&T and Lucent Bell Labs. The other options in this section # have no effect if this option is set to NO (the default) HAVE_DOT = NO # If the CLASS_GRAPH and HAVE_DOT tags are set to YES then doxygen # will generate a graph for each documented class showing the direct and # indirect inheritance relations. Setting this tag to YES will force the # the CLASS_DIAGRAMS tag to NO. CLASS_GRAPH = YES # If the COLLABORATION_GRAPH and HAVE_DOT tags are set to YES then doxygen # will generate a graph for each documented class showing the direct and # indirect implementation dependencies (inheritance, containment, and # class references variables) of the class with other documented classes. COLLABORATION_GRAPH = YES # If the GROUP_GRAPHS and HAVE_DOT tags are set to YES then doxygen # will generate a graph for groups, showing the direct groups dependencies GROUP_GRAPHS = YES # If the UML_LOOK tag is set to YES doxygen will generate inheritance and # collaboration diagrams in a style similar to the OMG's Unified Modeling # Language. UML_LOOK = NO # If set to YES, the inheritance and collaboration graphs will show the # relations between templates and their instances. TEMPLATE_RELATIONS = NO # If the ENABLE_PREPROCESSING, SEARCH_INCLUDES, INCLUDE_GRAPH, and HAVE_DOT # tags are set to YES then doxygen will generate a graph for each documented # file showing the direct and indirect include dependencies of the file with # other documented files. INCLUDE_GRAPH = YES # If the ENABLE_PREPROCESSING, SEARCH_INCLUDES, INCLUDED_BY_GRAPH, and # HAVE_DOT tags are set to YES then doxygen will generate a graph for each # documented header file showing the documented files that directly or # indirectly include this file. INCLUDED_BY_GRAPH = YES # If the CALL_GRAPH and HAVE_DOT tags are set to YES then doxygen will # generate a call dependency graph for every global function or class method. # Note that enabling this option will significantly increase the time of a run. # So in most cases it will be better to enable call graphs for selected # functions only using the \callgraph command. CALL_GRAPH = NO # If the CALLER_GRAPH and HAVE_DOT tags are set to YES then doxygen will # generate a caller dependency graph for every global function or class method. # Note that enabling this option will significantly increase the time of a run. # So in most cases it will be better to enable caller graphs for selected # functions only using the \callergraph command. CALLER_GRAPH = NO # If the GRAPHICAL_HIERARCHY and HAVE_DOT tags are set to YES then doxygen # will graphical hierarchy of all classes instead of a textual one. GRAPHICAL_HIERARCHY = YES # If the DIRECTORY_GRAPH, SHOW_DIRECTORIES and HAVE_DOT tags are set to YES # then doxygen will show the dependencies a directory has on other directories # in a graphical way. The dependency relations are determined by the #include # relations between the files in the directories. DIRECTORY_GRAPH = YES # The DOT_IMAGE_FORMAT tag can be used to set the image format of the images # generated by dot. Possible values are png, jpg, or gif # If left blank png will be used. DOT_IMAGE_FORMAT = png # The tag DOT_PATH can be used to specify the path where the dot tool can be # found. If left blank, it is assumed the dot tool can be found in the path. DOT_PATH = # The DOTFILE_DIRS tag can be used to specify one or more directories that # contain dot files that are included in the documentation (see the # \dotfile command). DOTFILE_DIRS = # The MAX_DOT_GRAPH_MAX_NODES tag can be used to set the maximum number of # nodes that will be shown in the graph. If the number of nodes in a graph # becomes larger than this value, doxygen will truncate the graph, which is # visualized by representing a node as a red box. Note that doxygen will always # show the root nodes and its direct children regardless of this setting. DOT_GRAPH_MAX_NODES = 50 # Set the DOT_TRANSPARENT tag to YES to generate images with a transparent # background. This is disabled by default, which results in a white background. # Warning: Depending on the platform used, enabling this option may lead to # badly anti-aliased labels on the edges of a graph (i.e. they become hard to # read). DOT_TRANSPARENT = NO # Set the DOT_MULTI_TARGETS tag to YES allow dot to generate multiple output # files in one run (i.e. multiple -o and -T options on the command line). This # makes dot run faster, but since only newer versions of dot (>1.8.10) # support this, this feature is disabled by default. DOT_MULTI_TARGETS = NO # If the GENERATE_LEGEND tag is set to YES (the default) Doxygen will # generate a legend page explaining the meaning of the various boxes and # arrows in the dot generated graphs. GENERATE_LEGEND = YES # If the DOT_CLEANUP tag is set to YES (the default) Doxygen will # remove the intermediate dot files that are used to generate # the various graphs. DOT_CLEANUP = YES #--------------------------------------------------------------------------- # Configuration::additions related to the search engine #--------------------------------------------------------------------------- # The SEARCHENGINE tag specifies whether or not a search engine should be # used. If set to NO the values of all tags below this one will be ignored. SEARCHENGINE = NO openchange-2.0/utils/mapitest/data/000077500000000000000000000000001223057412600173635ustar00rootroot00000000000000openchange-2.0/utils/mapitest/data/lzfu/000077500000000000000000000000001223057412600203435ustar00rootroot00000000000000openchange-2.0/utils/mapitest/data/lzfu/testcase.rtf000066400000000000000000000317141223057412600227010ustar00rootroot00000000000000{\rtf1\ansi\ansicpg1252\uc1 \deff0\deflang1033\deflangfe1033 {\fonttbl {\f0\froman\fcharset0\fprq2{\*\panose 02020603050405020304}Times New Roman;} {\f1\fswiss\fcharset0\fprq2{\*\panose 020b0604020202020204}Arial;} {\f2\fmodern\fcharset0\fprq1{\*\panose 02070309020205020404}Courier New;} {\f3\froman\fcharset2\fprq2{\*\panose 05050102010706020507}Symbol;} } {\colortbl;\red0\green0\blue0;\red0\green0\blue255;\red0\green255\blue255;\red0\green255\blue0;\red255\green0\blue255;\red255\green0\blue0;\red255\green255\blue0;\red255\green255\blue255;\red0\green0\blue128;\red0\green128\blue128;\red0\green128\blue0;\red128\green0\blue128;\red128\green0\blue0;\red128\green128\blue0;\red128\green128\blue128;\red192\green192\blue192;} {\stylesheet {\widctlpar\adjustright \fs20\cgrid \snext0 Normal;} {\s1\sb240\sa60\keepn\widctlpar\adjustright \b\f1\fs36\kerning36\cgrid \sbasedon0 \snext0 heading 1;} {\s2\sb240\sa60\keepn\widctlpar\adjustright \b\f1\fs28\kerning28\cgrid \sbasedon0 \snext0 heading 2;} {\s3\sb240\sa60\keepn\widctlpar\adjustright \b\f1\cgrid \sbasedon0 \snext0 heading 3;} {\s4\sb240\sa60\keepn\widctlpar\adjustright \b\f1\fs20\cgrid \sbasedon0 \snext0 heading 4;}{\*\cs10 \additive Default Paragraph Font;} {\s5\sb90\sa30\keepn\widctlpar\adjustright \b\f1\fs20\cgrid \sbasedon0 \snext0 heading 5;}{\*\cs10 \additive Default Paragraph Font;} {\s15\qc\sb240\sa60\widctlpar\outlinelevel0\adjustright \b\f1\fs32\kerning28\cgrid \sbasedon0 \snext15 Title;} {\s16\qc\sa60\widctlpar\outlinelevel1\adjustright \f1\cgrid \sbasedon0 \snext16 Subtitle;} {\s17\sa60\sb30\widctlpar\qj \fs22\cgrid \sbasedon0 \snext17 BodyText;} {\s18\widctlpar\fs22\cgrid \sbasedon0 \snext18 DenseText;} {\s28\widctlpar\tqc\tx4320\tqr\tx8640\adjustright \fs20\cgrid \sbasedon0 \snext28 header;} {\s29\widctlpar\tqc\tx4320\tqr\tx8640\qr\adjustright \fs20\cgrid \sbasedon0 \snext29 footer;} {\s30\li360\sa60\sb120\keepn\widctlpar\adjustright \b\f1\fs20\cgrid \sbasedon0 \snext30 GroupHeader;} {\s40\li0\widctlpar\adjustright \shading1000\cbpat8 \f2\fs16\cgrid \sbasedon0 \snext41 Code Example 0;} {\s41\li360\widctlpar\adjustright \shading1000\cbpat8 \f2\fs16\cgrid \sbasedon0 \snext42 Code Example 1;} {\s42\li720\widctlpar\adjustright \shading1000\cbpat8 \f2\fs16\cgrid \sbasedon0 \snext43 Code Example 2;} {\s43\li1080\widctlpar\adjustright \shading1000\cbpat8 \f2\fs16\cgrid \sbasedon0 \snext44 Code Example 3;} {\s44\li1440\widctlpar\adjustright \shading1000\cbpat8 \f2\fs16\cgrid \sbasedon0 \snext45 Code Example 4;} {\s45\li1800\widctlpar\adjustright \shading1000\cbpat8 \f2\fs16\cgrid \sbasedon0 \snext46 Code Example 5;} {\s46\li2160\widctlpar\adjustright \shading1000\cbpat8 \f2\fs16\cgrid \sbasedon0 \snext47 Code Example 6;} {\s47\li2520\widctlpar\adjustright \shading1000\cbpat8 \f2\fs16\cgrid \sbasedon0 \snext48 Code Example 7;} {\s48\li2880\widctlpar\adjustright \shading1000\cbpat8 \f2\fs16\cgrid \sbasedon0 \snext49 Code Example 8;} {\s49\li3240\widctlpar\adjustright \shading1000\cbpat8 \f2\fs16\cgrid \sbasedon0 \snext49 Code Example 9;} {\s50\li0\sa60\sb30\qj\widctlpar\qj\adjustright \fs20\cgrid \sbasedon0 \snext51 List Continue 0;} {\s51\li360\sa60\sb30\qj\widctlpar\qj\adjustright \fs20\cgrid \sbasedon0 \snext52 List Continue 1;} {\s52\li720\sa60\sb30\qj\widctlpar\qj\adjustright \fs20\cgrid \sbasedon0 \snext53 List Continue 2;} {\s53\li1080\sa60\sb30\qj\widctlpar\qj\adjustright \fs20\cgrid \sbasedon0 \snext54 List Continue 3;} {\s54\li1440\sa60\sb30\qj\widctlpar\qj\adjustright \fs20\cgrid \sbasedon0 \snext55 List Continue 4;} {\s55\li1800\sa60\sb30\qj\widctlpar\qj\adjustright \fs20\cgrid \sbasedon0 \snext56 List Continue 5;} {\s56\li2160\sa60\sb30\qj\widctlpar\qj\adjustright \fs20\cgrid \sbasedon0 \snext57 List Continue 6;} {\s57\li2520\sa60\sb30\qj\widctlpar\qj\adjustright \fs20\cgrid \sbasedon0 \snext58 List Continue 7;} {\s58\li2880\sa60\sb30\qj\widctlpar\qj\adjustright \fs20\cgrid \sbasedon0 \snext59 List Continue 8;} {\s59\li3240\sa60\sb30\qj\widctlpar\qj\adjustright \fs20\cgrid \sbasedon0 \snext59 List Continue 9;} {\s60\li0\widctlpar\ql\adjustright \fs20\cgrid \sbasedon0 \snext61 DescContinue 0;} {\s61\li360\widctlpar\ql\adjustright \fs20\cgrid \sbasedon0 \snext62 DescContinue 1;} {\s62\li720\widctlpar\ql\adjustright \fs20\cgrid \sbasedon0 \snext63 DescContinue 2;} {\s63\li1080\widctlpar\ql\adjustright \fs20\cgrid \sbasedon0 \snext64 DescContinue 3;} {\s64\li1440\widctlpar\ql\adjustright \fs20\cgrid \sbasedon0 \snext65 DescContinue 4;} {\s65\li1800\widctlpar\ql\adjustright \fs20\cgrid \sbasedon0 \snext66 DescContinue 5;} {\s66\li2160\widctlpar\ql\adjustright \fs20\cgrid \sbasedon0 \snext67 DescContinue 6;} {\s67\li2520\widctlpar\ql\adjustright \fs20\cgrid \sbasedon0 \snext68 DescContinue 7;} {\s68\li2880\widctlpar\ql\adjustright \fs20\cgrid \sbasedon0 \snext69 DescContinue 8;} {\s69\li3240\widctlpar\ql\adjustright \fs20\cgrid \sbasedon0 \snext69 DescContinue 9;} {\s70\li0\sa30\sb30\widctlpar\tqr\tldot\tx8640\adjustright \fs20\cgrid \sbasedon0 \snext81 LatexTOC 0;} {\s71\li360\sa27\sb27\widctlpar\tqr\tldot\tx8640\adjustright \fs20\cgrid \sbasedon0 \snext82 LatexTOC 1;} {\s72\li720\sa24\sb24\widctlpar\tqr\tldot\tx8640\adjustright \fs20\cgrid \sbasedon0 \snext83 LatexTOC 2;} {\s73\li1080\sa21\sb21\widctlpar\tqr\tldot\tx8640\adjustright \fs20\cgrid \sbasedon0 \snext84 LatexTOC 3;} {\s74\li1440\sa18\sb18\widctlpar\tqr\tldot\tx8640\adjustright \fs20\cgrid \sbasedon0 \snext85 LatexTOC 4;} {\s75\li1800\sa15\sb15\widctlpar\tqr\tldot\tx8640\adjustright \fs20\cgrid \sbasedon0 \snext86 LatexTOC 5;} {\s76\li2160\sa12\sb12\widctlpar\tqr\tldot\tx8640\adjustright \fs20\cgrid \sbasedon0 \snext87 LatexTOC 6;} {\s77\li2520\sa9\sb9\widctlpar\tqr\tldot\tx8640\adjustright \fs20\cgrid \sbasedon0 \snext88 LatexTOC 7;} {\s78\li2880\sa6\sb6\widctlpar\tqr\tldot\tx8640\adjustright \fs20\cgrid \sbasedon0 \snext89 LatexTOC 8;} {\s79\li3240\sa3\sb3\widctlpar\tqr\tldot\tx8640\adjustright \fs20\cgrid \sbasedon0 \snext89 LatexTOC 9;} {\s80\fi-360\li360\widctlpar\jclisttab\tx360{\*\pn \pnlvlbody\ilvl0\ls1\pnrnot0\pndec }\ls1\adjustright \fs20\cgrid \sbasedon0 \snext81 \sautoupd List Bullet 0;} {\s81\fi-360\li720\widctlpar\jclisttab\tx720{\*\pn \pnlvlbody\ilvl0\ls2\pnrnot0\pndec }\ls2\adjustright \fs20\cgrid \sbasedon0 \snext82 \sautoupd List Bullet 1;} {\s82\fi-360\li1080\widctlpar\jclisttab\tx1080{\*\pn \pnlvlbody\ilvl0\ls3\pnrnot0\pndec }\ls3\adjustright \fs20\cgrid \sbasedon0 \snext83 \sautoupd List Bullet 2;} {\s83\fi-360\li1440\widctlpar\jclisttab\tx1440{\*\pn \pnlvlbody\ilvl0\ls4\pnrnot0\pndec }\ls4\adjustright \fs20\cgrid \sbasedon0 \snext84 \sautoupd List Bullet 3;} {\s84\fi-360\li1800\widctlpar\jclisttab\tx1800{\*\pn \pnlvlbody\ilvl0\ls5\pnrnot0\pndec }\ls5\adjustright \fs20\cgrid \sbasedon0 \snext85 \sautoupd List Bullet 4;} {\s85\fi-360\li2160\widctlpar\jclisttab\tx2160{\*\pn \pnlvlbody\ilvl0\ls6\pnrnot0\pndec }\ls6\adjustright \fs20\cgrid \sbasedon0 \snext86 \sautoupd List Bullet 5;} {\s86\fi-360\li2520\widctlpar\jclisttab\tx2520{\*\pn \pnlvlbody\ilvl0\ls7\pnrnot0\pndec }\ls7\adjustright \fs20\cgrid \sbasedon0 \snext87 \sautoupd List Bullet 6;} {\s87\fi-360\li2880\widctlpar\jclisttab\tx2880{\*\pn \pnlvlbody\ilvl0\ls8\pnrnot0\pndec }\ls8\adjustright \fs20\cgrid \sbasedon0 \snext88 \sautoupd List Bullet 7;} {\s88\fi-360\li3240\widctlpar\jclisttab\tx3240{\*\pn \pnlvlbody\ilvl0\ls9\pnrnot0\pndec }\ls9\adjustright \fs20\cgrid \sbasedon0 \snext89 \sautoupd List Bullet 8;} {\s89\fi-360\li3600\widctlpar\jclisttab\tx3600{\*\pn \pnlvlbody\ilvl0\ls10\pnrnot0\pndec }\ls10\adjustright \fs20\cgrid \sbasedon0 \snext89 \sautoupd List Bullet 9;} {\s90\fi-360\li360\widctlpar\fs20\cgrid \sbasedon0 \snext91 \sautoupd List Enum 0;} {\s91\fi-360\li720\widctlpar\fs20\cgrid \sbasedon0 \snext92 \sautoupd List Enum 1;} {\s92\fi-360\li1080\widctlpar\fs20\cgrid \sbasedon0 \snext93 \sautoupd List Enum 2;} {\s93\fi-360\li1440\widctlpar\fs20\cgrid \sbasedon0 \snext94 \sautoupd List Enum 3;} {\s94\fi-360\li1800\widctlpar\fs20\cgrid \sbasedon0 \snext95 \sautoupd List Enum 4;} {\s95\fi-360\li2160\widctlpar\fs20\cgrid \sbasedon0 \snext96 \sautoupd List Enum 5;} {\s96\fi-360\li2520\widctlpar\fs20\cgrid \sbasedon0 \snext96 \sautoupd List Enum 5;} {\s97\fi-360\li2880\widctlpar\fs20\cgrid \sbasedon0 \snext98 \sautoupd List Enum 7;} {\s98\fi-360\li3240\widctlpar\fs20\cgrid \sbasedon0 \snext99 \sautoupd List Enum 8;} {\s99\fi-360\li3600\widctlpar\fs20\cgrid \sbasedon0 \snext99 \sautoupd List Enum 9;} } {\comment begin body} {\info {\title {\comment OpenChange {\s17\sa60\sb30\widctlpar\qj \fs22\cgrid 0.11 \par }}OpenChange} {\comment Generated byDoxgyen. } {\creatim \yr2010\mo11\dy22\hr11\min7\sec59} }\pard\plain \sectd\pgnlcrm {\footer \s29\widctlpar\tqc\tx4320\tqr\tx8640\qr\adjustright \fs20\cgrid {\chpgn}} \pard\plain \s16\qc\sa60\widctlpar\outlinelevel1\adjustright \f1\cgrid \vertalc\qc\par\par\par\par\par\par\par \pard\plain \s15\qc\sb240\sa60\widctlpar\outlinelevel0\adjustright \b\f1\fs32\kerning28\cgrid {\field\fldedit {\*\fldinst TITLE \\*MERGEFORMAT}{\fldrslt TITLE}}\par \pard\plain \s16\qc\sa60\widctlpar\outlinelevel1\adjustright \f1\cgrid \par \par\par\par\par\par\par\par\par\par\par\par\par \pard\plain \s16\qc\sa60\widctlpar\outlinelevel1\adjustright \f1\cgrid {\field\fldedit {\*\fldinst AUTHOR \\*MERGEFORMAT}{\fldrslt AUTHOR}}\par Version 0.11\par{\field\fldedit {\*\fldinst CREATEDATE \\*MERGEFORMAT}{\fldrslt CREATEDATE}}\par \page\page\vertalt \pard\plain \s1\sb240\sa60\keepn\widctlpar\adjustright \b\f1\fs36\kerning36\cgrid Table of Contents\par \pard\plain \par {\field\fldedit {\*\fldinst TOC \\f \\*MERGEFORMAT}{\fldrslt Table of contents}}\par \pard\plain \sect \sbkpage \pgndec \pgnrestart \sect \sectd \sbknone {\footer \s29\widctlpar\tqc\tx4320\tqr\tx8640\qr\adjustright \fs20\cgrid {\chpgn}} \pard\plain \sect\sbkpage \s1\sb240\sa60\keepn\widctlpar\adjustright \b\f1\fs36\kerning36\cgrid The OpenChange Library API Reference\par \pard\plain {\tc \v The OpenChange Library API Reference} { \pard\plain \s17\sa60\sb30\widctlpar\qj \fs22\cgrid {\s17\sa60\sb30\widctlpar\qj \fs22\cgrid This is the online reference for developing with the OpenChange client libraries.Among other things, the OpenChange client libraries provide:{ \par \pard\plain \s80\fi-360\li360\widctlpar\jclisttab\tx360{\*\pn \pnlvlbody\ilvl0\ls1\pnrnot0\pndec }\ls1\adjustright \fs20\cgrid MAPI client library ({\f2 libmapi})\par \pard\plain \s80\fi-360\li360\widctlpar\jclisttab\tx360{\*\pn \pnlvlbody\ilvl0\ls1\pnrnot0\pndec }\ls1\adjustright \fs20\cgrid MAPI administration libraries ({\f2 libmapiadmin})\par \pard\plain \s80\fi-360\li360\widctlpar\jclisttab\tx360{\*\pn \pnlvlbody\ilvl0\ls1\pnrnot0\pndec }\ls1\adjustright \fs20\cgrid OpenChange Property Files ({\f2 libocpf})\par \pard\plain \s80\fi-360\li360\widctlpar\jclisttab\tx360{\*\pn \pnlvlbody\ilvl0\ls1\pnrnot0\pndec }\ls1\adjustright \fs20\cgrid A regression test framework ({\f2 mapitest})\par \pard\plain \s80\fi-360\li360\widctlpar\jclisttab\tx360{\*\pn \pnlvlbody\ilvl0\ls1\pnrnot0\pndec }\ls1\adjustright \fs20\cgrid MAPIProxy project ({\f2 mapiproxy})\par \pard\plain \s80\fi-360\li360\widctlpar\jclisttab\tx360{\*\pn \pnlvlbody\ilvl0\ls1\pnrnot0\pndec }\ls1\adjustright \fs20\cgrid C++ bindings for libmapi ({\f2 libmapi++})\par} {\pard\plain \s4\sb240\sa60\keepn\widctlpar\adjustright \b\f1\fs20\cgrid {\tc\tcl \v 4}OpenChange Project Goals\par} The OpenChange Project aims to provide a portable Open Source implementation of Microsoft Exchange Server and Exchange protocols. Exchange is a groupware server designed to work with Microsoft Outlook, and providing features such as a messaging server, shared calendars, contact databases, public folders, notes and tasks.\par The OpenChange project has three goals:\par { \par \pard\plain \s80\fi-360\li360\widctlpar\jclisttab\tx360{\*\pn \pnlvlbody\ilvl0\ls1\pnrnot0\pndec }\ls1\adjustright \fs20\cgrid To provide a library for interoperability with Exchange protocols, and to assist implementors to use this to create groupware that interoperates with both Exchange and other OpenChange-based software.\par} { \par \pard\plain \s80\fi-360\li360\widctlpar\jclisttab\tx360{\*\pn \pnlvlbody\ilvl0\ls1\pnrnot0\pndec }\ls1\adjustright \fs20\cgrid To provide an alternative to Microsoft Exchange Server which uses native Exchange protocols and provides exactly equivalent functionality when viewed from Microsoft Outlook clients.\par} { \par \pard\plain \s80\fi-360\li360\widctlpar\jclisttab\tx360{\*\pn \pnlvlbody\ilvl0\ls1\pnrnot0\pndec }\ls1\adjustright \fs20\cgrid To develop a body of knowledge about the most popular groupware protocols in use commercially today in order to promote development of a documented and unencumbered standard, with all the benefits that standards bring.\par} {\pard\plain \s4\sb240\sa60\keepn\widctlpar\adjustright \b\f1\fs20\cgrid {\tc\tcl \v 4}More information\par} Visit the {\f2 OpenChange web site} for other useful information. \par }} \pard\plain \sect\sbkpage \s1\sb240\sa60\keepn\widctlpar\adjustright \b\f1\fs36\kerning36\cgrid \s1\sb240\sa60\keepn\widctlpar\adjustright \b\f1\fs36\kerning36\cgrid Index\par \pard\plain {\tc \v Index} {\field\fldedit {\*\fldinst INDEX \\c2 \\*MERGEFORMAT}{\fldrslt INDEX}} }openchange-2.0/utils/mapitest/data/lzxpress/000077500000000000000000000000001223057412600212555ustar00rootroot00000000000000openchange-2.0/utils/mapitest/data/lzxpress/001_Outlook_2007_in_ModifyRecipients_comp.dat000066400000000000000000000006601223057412600314760ustar00rootroot00000000000000'V Ðr H¸Z'D)ý@?MEË@Ç  þ9ÿþ9q:À:ÿ_Þý_ö_÷Xß_ÁðTQEUJkerihuelJulien K8rhh¨e¸ˆ*8jkŸÇ j÷Ÿè@opc˜a8gh203. ¯oÈaê¯9§kJܧ@ÈÀB´¹+/á‚ /o=First Organization/ou¬Administr`€¸ve Group/cn=Recipientsij  P=`tHsth2ÕâeEM€0((­¥¤¤¤¥¥µ¥¤©ã¥¥¥¥¥¥¥¥¥¥µ¥¤©ë¥¥¥ë¥¥¥¥¥¥0ˆopenchange-2.0/utils/mapitest/data/lzxpress/002_Outlook_2007_in_Tables_operations_comp.dat000066400000000000000000000006641223057412600317030ustar00rootroot00000000000000'V Ðr H¸Z'D)ý@?RJ|d HgJMgNg7 4hH3hp:h8AhBh@0OȘ IPM.icrosft ‚¨ ˜FHlde¸D(sgnÈNamˆdV˜ew°z)òHã:h¹¹ø9M‚s@gJPq… 3Q ab';)xè}¡pI0ôA@rfå6æ066 ˜6x?@EUÞ8ßàXá8Ú8-gu ÿq<ÿÿÿÿÿÿÿÿR€0((­¥¤¤¤¥¹¥µ¥¤©÷¥¥¥¥¥¥¥¾¥¥¥µ¥¤©ê¥¥¥ë¥¥¥¾¥¥¥0ˆopenchange-2.0/utils/mapitest/mapitest.c000066400000000000000000000240061223057412600204460ustar00rootroot00000000000000/* Stand-alone MAPI testsuite OpenChange Project Copyright (C) Julien Kerihuel 2008 This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see . */ #include "utils/mapitest/mapitest.h" #include "utils/openchange-tools.h" #include #include #include "config.h" /** \file Core of %mapitest implementation */ /** Initialize %mapitest structure */ static void mapitest_init(TALLOC_CTX *mem_ctx, struct mapitest *mt) { mt->mem_ctx = mem_ctx; mt->stream = NULL; memset(&mt->info, 0, sizeof (mt->info)); mt->session = NULL; mt->session = NULL; mt->mapi_all = true; mt->confidential = false; mt->no_server = false; mt->color = false; mt->online = false; mt->mapi_suite = false; mt->cmdline_calls = NULL; mt->cmdline_suite = NULL; mt->subunit_output = false; } /** Initialize %mapitest output stream \param mt pointer to mapitest context \param filename filename to write to (can be null, for output to stdout) */ static void mapitest_init_stream(struct mapitest *mt, const char *filename) { if (filename == NULL) { mt->stream = fdopen(STDOUT_FILENO, "a"); } else { mt->stream = fopen(filename, "w+"); } if (mt->stream == NULL) { err(errno, "fdopen/fopen"); } } /** Clean up %mapitest output stream \param mt pointer to mapitest context */ static void mapitest_cleanup_stream(struct mapitest *mt) { fclose(mt->stream); } static bool mapitest_get_testnames(TALLOC_CTX *mem_ctx, struct mapitest *mt, const char *parameter) { struct mapitest_unit *el = NULL; char *temptok = NULL; if ((temptok = strtok((char *)parameter, ";")) == NULL) { fprintf(stderr, "Invalid testname list [;]\n"); return false; } el = talloc_zero(mem_ctx, struct mapitest_unit); el->name = talloc_strdup(mem_ctx, temptok); DLIST_ADD(mt->cmdline_calls, el); while ((temptok = strtok(NULL, ";")) != NULL) { el = talloc_zero(mem_ctx, struct mapitest_unit); el->name = talloc_strdup(mem_ctx, temptok); DLIST_ADD_END(mt->cmdline_calls, el, struct mapitest_unit *); } return true; } static void mapitest_list(struct mapitest *mt, const char *name) { struct mapitest_suite *sel; struct mapitest_test *el; /* List all tests */ if (!name) { for (sel = mt->mapi_suite; sel; sel = sel->next) { printf("[*] Suite %s\n", sel->name); printf("===================================\n"); printf(" * %-15s %s\n", "Name:", sel->name); printf(" * %-15s %5s\n", "Description:", sel->description); printf(" * Running Tests:\n"); for (el = sel->tests; el; el = el->next) { printf("\t - %-35s: %-10s\n", el->name, el->description); } printf("\n\n"); } } } /** * Retrieve server specific information */ static bool mapitest_get_server_info(struct mapitest *mt, char *opt_profname, const char *password, bool opt_dumpdata, const char *opt_debug) { TALLOC_CTX *mem_ctx; enum MAPISTATUS retval; struct emsmdb_info *info = NULL; struct mapi_session *session = NULL; /* if the user explicitly asked for just the no-server tests to be run, then we're done here */ if (mt->no_server == true) return 0; mem_ctx = talloc_named(NULL, 0, "mapitest_get_server_info"); /* if no profile was specified, get the default */ if (!opt_profname) { retval = GetDefaultProfile(mt->mapi_ctx, &opt_profname); if (retval != MAPI_E_SUCCESS) { mapi_errstr("GetDefaultProfile", retval); talloc_free(mem_ctx); return false; } } /* debug options */ SetMAPIDumpData(mt->mapi_ctx, opt_dumpdata); if (opt_debug) { SetMAPIDebugLevel(mt->mapi_ctx, atoi(opt_debug)); } retval = MapiLogonEx(mt->mapi_ctx, &session, opt_profname, password); MAPIFreeBuffer(opt_profname); talloc_free(mem_ctx); if (retval != MAPI_E_SUCCESS) { mapi_errstr("MapiLogonEx", retval); return false; } mt->session = session; mt->profile = session->profile; info = emsmdb_get_info(session); memcpy(&mt->info, info, sizeof (struct emsmdb_info)); /* extract org and org_unit from info.mailbox */ mt->org = x500_get_dn_element(mt->mem_ctx, info->szDNPrefix, "/o="); mt->org_unit = x500_get_dn_element(mt->mem_ctx, info->szDNPrefix, "/ou="); return true; } /** * main program */ int main(int argc, const char *argv[]) { enum MAPISTATUS retval; int32_t num_tests_failed; TALLOC_CTX *mem_ctx; struct mapitest mt; poptContext pc; int opt; bool ret; bool opt_dumpdata = false; const char *opt_debug = NULL; const char *opt_profdb = NULL; char *opt_profname = NULL; const char *opt_password = NULL; const char *opt_outfile = NULL; char *prof_tmp = NULL; bool opt_leak_report = false; bool opt_leak_report_full = false; enum { OPT_PROFILE_DB=1000, OPT_PROFILE, OPT_PASSWORD, OPT_CONFIDENTIAL, OPT_OUTFILE, OPT_MAPI_CALLS, OPT_NO_SERVER, OPT_LIST_ALL, OPT_DUMP_DATA, OPT_DEBUG, OPT_COLOR, OPT_SUBUNIT, OPT_LEAK_REPORT, OPT_LEAK_REPORT_FULL }; struct poptOption long_options[] = { POPT_AUTOHELP { "database", 'f', POPT_ARG_STRING, NULL, OPT_PROFILE_DB, "set the profile database", NULL }, { "profile", 'p', POPT_ARG_STRING, NULL, OPT_PROFILE, "set the profile name", NULL }, { "password", 'p', POPT_ARG_STRING, NULL, OPT_PASSWORD, "set the profile or account password", NULL }, { "confidential", 0, POPT_ARG_NONE, NULL, OPT_CONFIDENTIAL, "remove any sensitive data from the report", NULL }, { "color", 0, POPT_ARG_NONE, NULL, OPT_COLOR, "color MAPI retval", NULL }, #if HAVE_SUBUNIT { "subunit", 0, POPT_ARG_NONE, NULL, OPT_SUBUNIT, "output in subunit protocol format", NULL }, #endif { "outfile", 'o', POPT_ARG_STRING, NULL, OPT_OUTFILE, "set the report output file", NULL }, { "mapi-calls", 0, POPT_ARG_STRING, NULL, OPT_MAPI_CALLS, "test custom ExchangeRPC tests", NULL }, { "list-all", 0, POPT_ARG_NONE, NULL, OPT_LIST_ALL, "list suite and tests - names and description", NULL }, { "no-server", 0, POPT_ARG_NONE, NULL, OPT_NO_SERVER, "only run tests that do not require server connection", NULL }, { "dump-data", 0, POPT_ARG_NONE, NULL, OPT_DUMP_DATA, "dump the hex data", NULL }, { "debuglevel", 'd', POPT_ARG_STRING, NULL, OPT_DEBUG, "set debug level", NULL }, { "leak-report", 0, POPT_ARG_NONE, NULL, OPT_LEAK_REPORT, "enable talloc leak reporting on exit", NULL }, { "leak-report-full", 0, POPT_ARG_NONE, NULL, OPT_LEAK_REPORT_FULL, "enable full talloc leak reporting on exit", NULL }, POPT_OPENCHANGE_VERSION { NULL, 0, 0, NULL, 0, NULL, NULL } }; mem_ctx = talloc_named(NULL, 0, "mapitest"); mapitest_init(mem_ctx, &mt); mapitest_register_modules(&mt); pc = poptGetContext("mapitest", argc, argv, long_options, 0); while ((opt = poptGetNextOpt(pc)) != -1) { switch (opt) { case OPT_DUMP_DATA: opt_dumpdata = true; break; case OPT_DEBUG: opt_debug = poptGetOptArg(pc); break; case OPT_PROFILE_DB: opt_profdb = poptGetOptArg(pc); break; case OPT_PROFILE: prof_tmp = poptGetOptArg(pc); opt_profname = talloc_strdup(mem_ctx, prof_tmp); free(prof_tmp); prof_tmp = NULL; break; case OPT_PASSWORD: opt_password = poptGetOptArg(pc); break; case OPT_CONFIDENTIAL: mt.confidential = true; break; case OPT_OUTFILE: opt_outfile = poptGetOptArg(pc); break; case OPT_MAPI_CALLS: ret = mapitest_get_testnames(mem_ctx, &mt, poptGetOptArg(pc)); if (ret == false) exit (-1); mt.mapi_all = false; break; case OPT_NO_SERVER: mt.no_server = true; break; case OPT_COLOR: mt.color = true; break; case OPT_SUBUNIT: mt.subunit_output = true; break; case OPT_LIST_ALL: mapitest_list(&mt, NULL); talloc_free(mem_ctx); poptFreeContext(pc); return 0; break; case OPT_LEAK_REPORT: opt_leak_report = true; talloc_enable_leak_report(); break; case OPT_LEAK_REPORT_FULL: opt_leak_report_full = true; talloc_enable_leak_report_full(); break; } } poptFreeContext(pc); /* Sanity check */ if (mt.cmdline_calls && (mt.mapi_all == true)) { fprintf(stderr, "mapi-calls and mapi-all can't be set at the same time\n"); return -1; } /* Initialize MAPI subsystem */ if (!opt_profdb) { opt_profdb = talloc_asprintf(mem_ctx, DEFAULT_PROFDB, getenv("HOME")); } retval = MAPIInitialize(&(mt.mapi_ctx), opt_profdb); if (retval != MAPI_E_SUCCESS) { mapi_errstr("MAPIInitialize", retval); return -2; } mapitest_init_stream(&mt, opt_outfile); mt.online = mapitest_get_server_info(&mt, opt_profname, opt_password, opt_dumpdata, opt_debug); mapitest_print_headers(&mt); /* Do not run any tests if we couldn't find a profile or if * server is offline and connection to server was implicitly * specified */ if (!opt_profname && mt.online == false && mt.no_server == false) { fprintf(stderr, "No MAPI profile found for online tests\n"); return -2; } /* Run custom tests */ if (mt.cmdline_calls) { struct mapitest_unit *el; for (el = mt.cmdline_calls; el; el = el->next) { printf("[*] %s\n", el->name); mapitest_run_test(&mt, el->name); } } else { mapitest_run_all(&mt); } num_tests_failed = mapitest_stat_dump(&mt); mapitest_cleanup_stream(&mt); /* Uninitialize and free memory */ MAPIUninitialize(mt.mapi_ctx); talloc_free(mt.mem_ctx); if (opt_leak_report) { talloc_report(NULL, stdout); } if (opt_leak_report_full) { talloc_report_full(NULL, stdout); } return num_tests_failed; } openchange-2.0/utils/mapitest/mapitest.h000066400000000000000000000176071223057412600204640ustar00rootroot00000000000000/* Stand-alone MAPI testsuite OpenChange Project Copyright (C) Julien Kerihuel 2008 This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see . */ #ifndef __MAPITEST_H__ #define __MAPITEST_H__ #include "libmapi/libmapi.h" #include "libmapi/mapi_nameid.h" #include #include /* forward declaration */ struct mapitest; struct mapitest_suite; /** \file mapitest.h Data structures for %mapitest */ /** Flags for changing test applicability If you add values here, you also need to add a matching description to applicabilityFlagsDescription and suitable logic to mapitest_suite_test_is_applicable(). */ enum TestApplicabilityFlags { ApplicableToAllVersions = 0, /*!< This test is always applicable */ NotInExchange2010 = 0x1, /*!< This test is not applicable to Exchange 2010 */ NotInExchange2010SP0 = 0x2, /*!< This test is not applicable to Exchange 2010 Service Pack 0, but is applicable to later versions */ ExpectedFail = 0x8000, /*!< This test is expected to fail */ LastTestApplicabilityFlag = 0xFFFF }; /** List of possible test results */ enum TestResult { Pass, /*!< The test was expected to pass, and it did */ Fail, /*!< The test was expected to pass, but it failed */ UnexpectedPass, /*!< The test was expected to fail, but it passed instead */ ExpectedFailure /*!< The test was expected to fail, and it did */ }; #include "utils/mapitest/proto.h" /** A list of %mapitest tests %mapitest tests are grouped into test suites. This linked list data structure represents the various tests as a list of tests (i.e. the linked list is a suite of tests). The function that executes the test is pointed to by the fn element (i.e. fn is a function pointer). */ struct mapitest_test { struct mapitest_test *prev; /*!< The previous test in the list */ struct mapitest_test *next; /*!< The next test in the list */ char *name; /*!< The name of this test */ char *description; /*!< The description of this test */ void *fn; /*!< pointer to the test function */ enum TestApplicabilityFlags flags; /*!< any applicability for this test */ }; /** List of test names This linked list data structure has a list of names of tests. It is used with mapitest_stat to record the failed tests. */ struct mapitest_unit { struct mapitest_unit *prev; /*!< The previous test in the list */ struct mapitest_unit *next; /*!< The next test in the list */ char *name; /*!< The name of the test */ char *reason; /*!< Why this test was skipped or failed (if applicable) */ }; /** %mapitest statistics During a %mapitest run, %mapitest collects statistics on each test suite. This data structure records the results for one run of a test suite. There should be one entry in the failure_info list for each failure. */ struct mapitest_stat { uint32_t success; /*!< Number of tests in this suite that passed */ uint32_t failure; /*!< Number of tests in this suite that failed */ uint32_t skipped; /*!< Number of tests in this suite that were skipped */ uint32_t x_fail; /*!< Number of tests in this suite that were expected failures */ struct mapitest_unit *failure_info; /*!< List of names of the tests that failed */ struct mapitest_unit *skip_info; /*!< List of names of the tests that were skipped, and why */ bool enabled; /*!< Whether this statistics structure is valid */ }; /** A list of test suites %mapitest executes a set of tests. Those tests are grouped into suites of related tests (e.g. all tests that do not require a server are in one suite, the tests for NSPI are in another suite, and so on). This linked list data structure represents the various test suites to be executed. */ struct mapitest_suite { struct mapitest_suite *prev; /*!< Pointer to the previous test suite */ struct mapitest_suite *next; /*!< Pointer to the next test suite */ char *name; /*!< The name of the test suite */ char *description; /*!< Description of the test suite */ bool online; /*!< Whether this suite requires a server */ struct mapitest_test *tests; /*!< The tests in this suite */ struct mapitest_stat *stat; /*!< Results of running this test */ }; /** The context structure for a %mapitest run */ struct mapitest { TALLOC_CTX *mem_ctx; /*!< talloc memory context for memory allocations */ struct mapi_context *mapi_ctx; /*!< mapi context */ struct mapi_session *session; bool confidential; /*!< true if confidential information should be omitted */ bool no_server; /*!< true if only non-server tests should be run */ bool mapi_all; /*!< true if all tests should be run */ bool online; /*!< true if the server could be accessed */ bool color; /*!< true if the output should be colored */ bool subunit_output; /*!< true if we should write output in subunit protocol format */ struct emsmdb_info info; struct mapi_profile *profile; struct mapitest_suite *mapi_suite; /*!< the various test suites */ struct mapitest_unit *cmdline_calls; struct mapitest_unit *cmdline_suite; const char *org; const char *org_unit; FILE *stream; void *priv; }; struct mapitest_module { char *name; }; /** Context for %mapitest test folder */ struct mt_common_tf_ctx { mapi_object_t obj_store; mapi_object_t obj_top_folder; mapi_object_t obj_test_folder; mapi_object_t obj_test_msg[10]; }; /* * Defines */ #define MAPITEST_SUCCESS 0 #define MAPITEST_ERROR -1 #define MT_STREAM_MAX_SIZE 0x3000 #define MT_YES "[yes]" #define MT_NO "[no]" #define MT_CONFIDENTIAL "[Confidential]" #define MT_HDR_START "#############################[mapitest report]#################################\n" #define MT_HDR_END "###############################################################################\n" #define MT_HDR_FMT "[*] %-25s: %-20s\n" #define MT_HDR_FMT_DATE "[*] %-25s: %-20s" #define MT_HDR_FMT_SECTION "[*] %-25s:\n" #define MT_HDR_FMT_SUBSECTION "%-21s: %-10s\n" #define MT_HDR_FMT_VER_NORM "%-21s: %02d.%02d.%04d.%04d\n" #define MT_DIRNAME_TOP "MT Top of Mailbox" #define MT_DIRNAME_APPOINTMENT "MT Calendar" #define MT_DIRNAME_CONTACT "MT Contact" #define MT_DIRNAME_JOURNAL "MT Journal" #define MT_DIRNAME_POST "MT Post" #define MT_DIRNAME_NOTE "MT Note" #define MT_DIRNAME_STICKYNOTE "MT Sticky Notes" #define MT_DIRNAME_TASK "MT Tasks" #define MT_DIRNAME_TEST "MT Test Folder1" #define MT_MAIL_SUBJECT "MT Sample E-MAIL" #define MT_MAIL_ATTACH "Attach1.txt" #define MT_MAIL_ATTACH2 "Attach2.txt" #define MODULE_TITLE "[MODULE] %s\n" #define MODULE_TITLE_DELIM '#' #define MODULE_TITLE_NEWLINE 2 #define MODULE_TITLE_LINELEN 80 #define MODULE_TEST_TITLE "[TEST] %s\n" #define MODULE_TEST_RESULT "[RESULT] %s: %s\n" #define MODULE_TEST_DELIM '-' #define MODULE_TEST_DELIM2 '=' #define MODULE_TEST_LINELEN 72 #define MODULE_TEST_NEWLINE 1 #define MODULE_TEST_SUCCESS "[SUCCESS]" #define MODULE_TEST_FAILURE "[FAILURE]" #define MT_ERROR "[ERROR]: %s\n" #define MT_STAT_FAILED_TITLE "[STAT] FAILED TEST CASES\n" #define MT_STAT_RESULT "* %-35s: %s (%s)\n" #define MT_STAT_SKIPPED_TITLE "[STAT] SKIPPED TEST CASES\n" #define MT_SUMMARY_TITLE "[STAT] TEST SUMMARY\n" #define MT_WHITE "\033[0;29m" #define MT_RED "\033[1;31m" #define MT_GREEN "\033[1;32m" #define Exchange2010SP0Version 0x0E00 #endif /* !__MAPITEST_H__ */ openchange-2.0/utils/mapitest/mapitest_common.c000066400000000000000000000375671223057412600220360ustar00rootroot00000000000000/* Stand-alone MAPI testsuite OpenChange Project Copyright (C) Julien Kerihuel 2008-2013 This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see . */ #include "utils/mapitest/mapitest.h" #include /** \file Support functions for %mapitest modules These functions implement commonly needed functionality that would otherwise be copied into each module implementation */ /** Opens a default folder This function opens one of the default (standard) folders, returning the folder as obj_child. olNum may be one of: - olFolderTopInformationStore - olFolderDeletedItems - olFolderOutbox - olFolderSentMail - olFolderInbox - olFolderCalendar - olFolderContacts - olFolderJournal - olFolderNotes - olFolderTasks - olFolderDrafts \param mt pointer to the top level mapitest structure \param obj_parent parent folder (usually the message store, must be opened) \param obj_child the folder that has been opened \param olNum the folder identifier (see list above) \return true on success, false on failure */ _PUBLIC_ bool mapitest_common_folder_open(struct mapitest *mt, mapi_object_t *obj_parent, mapi_object_t *obj_child, uint32_t olNum) { mapi_id_t id_child; GetDefaultFolder(obj_parent, &id_child, olNum); if (GetLastError() != MAPI_E_SUCCESS) { mapitest_print(mt, "* %-35s: 0x%.8x\n", "GetDefaultFolder", GetLastError()); return false; } OpenFolder(obj_parent, id_child, obj_child); if (GetLastError() != MAPI_E_SUCCESS) { mapitest_print(mt, "* %-35s: 0x%.8x\n", "OpenFolder", GetLastError()); return false; } return true; } /** This function deletes messages in a folder, based on matching the subject name. This is meant to clean up a folder after a test has been run. \param mt pointer to the top level mapitest structure \param obj_folder the folder to search through \param subject the message subject to match */ _PUBLIC_ bool mapitest_common_message_delete_by_subject(struct mapitest *mt, mapi_object_t *obj_folder, const char *subject) { enum MAPISTATUS retval; mapi_object_t obj_ctable; mapi_id_t msgids[1]; struct SPropTagArray *SPropTagArray; struct SRowSet SRowSet; uint32_t count; const char *msubject = NULL; uint32_t i; /* Sanity checks */ if (subject == NULL) return false; /* Retrieve the contents table */ mapi_object_init(&obj_ctable); retval = GetContentsTable(obj_folder, &obj_ctable, 0, &count); if (retval != MAPI_E_SUCCESS) { mapitest_print(mt, "* %-35s: 0x%.8x\n", "GetContentsTable", GetLastError()); mapi_object_release(&obj_ctable); return false; } /* Customize the content table view */ SPropTagArray = set_SPropTagArray(mt->mem_ctx, 0x2, PR_MID, PR_SUBJECT); retval = SetColumns(&obj_ctable, SPropTagArray); MAPIFreeBuffer(SPropTagArray); if (retval != MAPI_E_SUCCESS) { mapitest_print(mt, "* %-35s: 0x%.8x\n", "SetColumns", GetLastError()); mapi_object_release(&obj_ctable); return false; } while (((retval = QueryRows(&obj_ctable, count, TBL_ADVANCE, &SRowSet)) != MAPI_E_NOT_FOUND) && !retval && SRowSet.cRows) { for (i = 0; i < SRowSet.cRows; i++) { if (retval == MAPI_E_SUCCESS) { msgids[0] = SRowSet.aRow[i].lpProps[0].value.d; msubject = (const char *)find_SPropValue_data(&SRowSet.aRow[i], PR_SUBJECT); if (msubject && !strncmp(subject, msubject, strlen(subject))) { retval = DeleteMessage(obj_folder, msgids, 1); if (retval != MAPI_E_SUCCESS) { mapitest_print_retval(mt, "DeleteMessage"); mapi_object_release(&obj_ctable); return false; } } } } } mapi_object_release(&obj_ctable); return false; } /** Find a folder within a container */ _PUBLIC_ bool mapitest_common_find_folder(struct mapitest *mt, mapi_object_t *obj_parent, mapi_object_t *obj_child, const char *name) { enum MAPISTATUS retval; struct SPropTagArray *SPropTagArray; struct SRowSet rowset; mapi_object_t obj_htable; const char *newname; const uint64_t *fid; uint32_t count; uint32_t index; mapi_object_init(&obj_htable); retval = GetHierarchyTable(obj_parent, &obj_htable, 0, &count); if (retval != MAPI_E_SUCCESS) { mapi_object_release(&obj_htable); return false; } SPropTagArray = set_SPropTagArray(mt->mem_ctx, 0x2, PR_DISPLAY_NAME, PR_FID); retval = SetColumns(&obj_htable, SPropTagArray); MAPIFreeBuffer(SPropTagArray); if (retval != MAPI_E_SUCCESS) { mapi_object_release(&obj_htable); return false; } while (((retval = QueryRows(&obj_htable, count, TBL_ADVANCE, &rowset)) != MAPI_E_NOT_FOUND) && rowset.cRows) { for (index = 0; index < rowset.cRows; index++) { fid = (const uint64_t *)find_SPropValue_data(&rowset.aRow[index], PR_FID); newname = (const char *)find_SPropValue_data(&rowset.aRow[index], PR_DISPLAY_NAME); if (newname && fid && !strcmp(newname, name)) { retval = OpenFolder(obj_parent, *fid, obj_child); mapi_object_release(&obj_htable); return true; } } } mapi_object_release(&obj_htable); return false; } /** * Create a message ready to submit */ _PUBLIC_ bool mapitest_common_message_create(struct mapitest *mt, mapi_object_t *obj_folder, mapi_object_t *obj_message, const char *subject) { enum MAPISTATUS retval; /* Create the message */ retval = CreateMessage(obj_folder, obj_message); if (retval != MAPI_E_SUCCESS) { mapitest_print_retval(mt, "(Common) CreateMessage"); return false; } return mapitest_common_message_fill(mt, obj_message, subject); } /** * Create a message ready to submit */ _PUBLIC_ bool mapitest_common_message_fill(struct mapitest *mt, mapi_object_t *obj_message, const char *subject) { enum MAPISTATUS retval; struct SPropTagArray *SPropTagArray; struct PropertyRowSet_r *RowSet = NULL; struct SRowSet *SRowSet = NULL; struct PropertyTagArray_r *flaglist = NULL; struct PropertyValue_r value; struct SPropValue lpProps[4]; const char *username[2]; const char *body; uint32_t msgflag; uint32_t format; uint32_t ret; /* Sanity checks */ if (subject == NULL) return false; /* Resolve recipients */ SPropTagArray = set_SPropTagArray(mt->mem_ctx, 0xA, PR_ENTRYID, PR_DISPLAY_NAME_UNICODE, PR_OBJECT_TYPE, PR_DISPLAY_TYPE, PR_TRANSMITTABLE_DISPLAY_NAME_UNICODE, PR_EMAIL_ADDRESS_UNICODE, PR_ADDRTYPE_UNICODE, PR_SEND_RICH_INFO, PR_7BIT_DISPLAY_NAME_UNICODE, PR_SMTP_ADDRESS_UNICODE); username[0] = (char *)mt->profile->mailbox; username[1] = NULL; RowSet = talloc_zero(mt->mem_ctx, struct PropertyRowSet_r); flaglist = talloc_zero(mt->mem_ctx, struct PropertyTagArray_r); retval = ResolveNames(mapi_object_get_session(obj_message), username, SPropTagArray, &RowSet, &flaglist, MAPI_UNICODE); MAPIFreeBuffer(SPropTagArray); if (retval != MAPI_E_SUCCESS) { mapitest_print_retval(mt, "(Common) ResolveNames"); talloc_free(RowSet); talloc_free(flaglist); return false; } value.ulPropTag = PR_SEND_INTERNET_ENCODING; value.value.l = 0; ret = PropertyRowSet_propcpy(mt->mem_ctx, RowSet, value); if (ret) return false; SRowSet = talloc_zero(RowSet, struct SRowSet); cast_PropertyRowSet_to_SRowSet(SRowSet, RowSet, SRowSet); /* Set Recipients */ SetRecipientType(&(SRowSet->aRow[0]), MAPI_TO); retval = ModifyRecipients(obj_message, SRowSet); MAPIFreeBuffer(RowSet); MAPIFreeBuffer(flaglist); if (retval != MAPI_E_SUCCESS) { mapitest_print_retval(mt, "(Common) ModifyRecipients"); return false; } /* Set message properties */ msgflag = MSGFLAG_SUBMIT; set_SPropValue_proptag(&lpProps[0], PR_SUBJECT, (const void *) subject); set_SPropValue_proptag(&lpProps[1], PR_MESSAGE_FLAGS, (const void *)&msgflag); body = talloc_asprintf(mt->mem_ctx, "Body of message with subject: %s", subject); set_SPropValue_proptag(&lpProps[2], PR_BODY, (const void *)body); format = EDITOR_FORMAT_PLAINTEXT; set_SPropValue_proptag(&lpProps[3], PR_MSG_EDITOR_FORMAT, (const void *)&format); retval = SetProps(obj_message, 0, lpProps, 4); if (retval != MAPI_E_SUCCESS) { mapitest_print_retval(mt, "(Common) SetProps"); return false; } errno = 0; return true; } /** Generate a random blob of readable data \param mem_ctx the talloc memory context to create the blob in \param len the length of the blob to create \return random blob of readable data, of length len bytes, with a null terminator. \note the data is from 0..len, and the null terminator is at position len+1. So the returned array is actually len+1 bytes in total. */ _PUBLIC_ char *mapitest_common_genblob(TALLOC_CTX *mem_ctx, size_t len) { int fd; int ret; unsigned int i; char *retstr; const char *list = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+_-#.,"; int list_len = strlen(list); /* Sanity check */ if (!mem_ctx || (len == 0)) { return NULL; } fd = open("/dev/urandom", O_RDONLY, 0); if (fd == -1) { return NULL; } retstr = talloc_array(mem_ctx, char, len + 1); if ((ret = read(fd, retstr, len)) == -1) { close(fd); talloc_free(retstr); return NULL; } for (i = 0; i < len; i++) { retstr[i] = list[retstr[i] % list_len]; if (!retstr[i]) { retstr[i] = 'X'; } } retstr[i] = '\0'; close(fd); return retstr; } /** Create a test folder, and fill with 10 sample messages This function creates a test folder (name set by the MT_DIRNAME_TEST define), and fills it with 5 messages with the same subject and 5 messages with the same sender. \param mt pointer to the mapitest context */ _PUBLIC_ bool mapitest_common_create_filled_test_folder(struct mapitest *mt) { struct mt_common_tf_ctx *context; enum MAPISTATUS retval; const char *from = NULL; const char *subject = NULL; const char *body = NULL; struct SPropValue lpProp[3]; int i; uint32_t format; bool ret; context = mt->priv; /* Create test folder */ mapi_object_init(&(context->obj_test_folder)); retval = CreateFolder(&(context->obj_top_folder), FOLDER_GENERIC, MT_DIRNAME_TEST, NULL, OPEN_IF_EXISTS, &(context->obj_test_folder)); if (retval != MAPI_E_SUCCESS) { mapitest_print_retval(mt, "Create the test folder"); return false; } /* Create 5 test messages in the test folder with the same subject */ for (i = 0; i < 5; ++i) { mapi_object_init(&(context->obj_test_msg[i])); ret = mapitest_common_message_create(mt, &(context->obj_test_folder), &(context->obj_test_msg[i]), MT_MAIL_SUBJECT); if (! ret) { mapitest_print(mt, "* %-35s\n", "Failed to create test message"); return false; } from = talloc_asprintf(mt->mem_ctx, "MT Dummy%i", i); set_SPropValue_proptag(&lpProp[0], PR_SENDER_NAME, (const void *)from); body = talloc_asprintf(mt->mem_ctx, "Body of message %i", i); set_SPropValue_proptag(&lpProp[1], PR_BODY, (const void *)body); format = EDITOR_FORMAT_PLAINTEXT; set_SPropValue_proptag(&lpProp[2], PR_MSG_EDITOR_FORMAT, (const void *)&format); retval = SetProps(&(context->obj_test_msg[i]), 0, lpProp, 3); MAPIFreeBuffer((void *)from); MAPIFreeBuffer((void *)body); if (retval != MAPI_E_SUCCESS) { mapitest_print(mt, "* %-35s: 0x%.8x\n", "Set props on message", GetLastError()); return false; } retval = SaveChangesMessage(&(context->obj_test_folder), &(context->obj_test_msg[i]), KeepOpenReadWrite); if (retval != MAPI_E_SUCCESS) { mapitest_print(mt, "* %-35s: 0x%.8x\n", "Save changes to message", GetLastError()); return false; } } /* Create 5 test messages in the test folder with the same sender */ for (i = 5; i < 10; ++i) { mapi_object_init(&(context->obj_test_msg[i])); subject = talloc_asprintf(mt->mem_ctx, "MT Subject%i", i); ret = mapitest_common_message_create(mt, &(context->obj_test_folder), &(context->obj_test_msg[i]), subject); if (! ret){ mapitest_print(mt, "* %-35s\n", "Failed to create test message"); return false; } from = talloc_asprintf(mt->mem_ctx, "MT Dummy From"); set_SPropValue_proptag(&lpProp[0], PR_SENDER_NAME, (const void *)from); body = talloc_asprintf(mt->mem_ctx, "Body of message %i", i); set_SPropValue_proptag(&lpProp[1], PR_BODY, (const void *)body); format = EDITOR_FORMAT_PLAINTEXT; set_SPropValue_proptag(&lpProp[2], PR_MSG_EDITOR_FORMAT, (const void *)&format); retval = SetProps(&(context->obj_test_msg[i]), 0, lpProp, 3); MAPIFreeBuffer((void *)from); MAPIFreeBuffer((void *)body); if (retval != MAPI_E_SUCCESS) { mapitest_print(mt, "* %-35s: 0x%.8x\n", "Set props on message", GetLastError()); return false; } retval = SaveChangesMessage(&(context->obj_test_folder), &(context->obj_test_msg[i]), KeepOpenReadWrite); if (retval != MAPI_E_SUCCESS) { return false; } } return true; } /** Convenience function to login to the server This functions logs into the server, gets the top level store, and gets the hierarchy table for the top level store (which is returned as obj_htable). It also creates a test folder with 10 test messages. \param mt pointer to the top-level mapitest structure \param obj_htable the hierarchy table for the top level store \param count the number of rows in the top level hierarchy table \return true on success, otherwise false */ _PUBLIC_ bool mapitest_common_setup(struct mapitest *mt, mapi_object_t *obj_htable, uint32_t *count) { bool ret = false; struct mt_common_tf_ctx *context; enum MAPISTATUS retval; context = talloc(mt->mem_ctx, struct mt_common_tf_ctx); mt->priv = context; mapi_object_init(&(context->obj_store)); retval = OpenMsgStore(mt->session, &(context->obj_store)); if (retval != MAPI_E_SUCCESS) { mapitest_print_retval(mt, "Failed OpenMsgStore"); return false; } mapi_object_init(&(context->obj_top_folder)); ret = mapitest_common_folder_open(mt, &(context->obj_store), &(context->obj_top_folder), olFolderTopInformationStore); if (ret == false) { return false; } /* We do this before getting the hierarchy table, because otherwise the new test folder will be omitted, and the count will be wrong */ ret = mapitest_common_create_filled_test_folder(mt); if (ret == false) { return false; } mapi_object_init(obj_htable); retval = GetHierarchyTable(&(context->obj_top_folder), obj_htable, 0, count); if (retval != MAPI_E_SUCCESS) { mapitest_print_retval(mt, "Failed GetHierarchyTable"); return false; } return true; } /** Convenience function to clean up after logging into the server This functions cleans up after a mapitest_common_setup() call \param mt pointer to the top-level mapitest structure */ _PUBLIC_ void mapitest_common_cleanup(struct mapitest *mt) { struct mt_common_tf_ctx *context; enum MAPISTATUS retval; int i; context = mt->priv; for (i = 0; i<10; ++i) { mapi_object_release(&(context->obj_test_msg[i])); } retval = EmptyFolder(&(context->obj_test_folder)); if (retval != MAPI_E_SUCCESS) { mapitest_print(mt, "* %-35s: 0x%.8x\n", "Empty test folder", GetLastError()); } retval = DeleteFolder(&(context->obj_top_folder), mapi_object_get_id(&(context->obj_test_folder)), DEL_FOLDERS | DEL_MESSAGES | DELETE_HARD_DELETE, NULL); if (retval != MAPI_E_SUCCESS) { mapitest_print(mt, "* %-35s: 0x%.8x\n", "Delete test folder", GetLastError()); } mapi_object_release(&(context->obj_test_folder)); mapi_object_release(&(context->obj_top_folder)); mapi_object_release(&(context->obj_store)); talloc_free(mt->priv); } openchange-2.0/utils/mapitest/mapitest_print.c000066400000000000000000000426431223057412600216710ustar00rootroot00000000000000/* Stand-alone MAPI testsuite OpenChange Project Copyright (C) Julien Kerihuel 2008 This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see . */ #include #include "utils/mapitest/mapitest.h" #include "config.h" #ifdef HAVE_SUBUNIT #include #endif #include static int count = 0; #define CNT_INDENT() { count++; } #define CNT_DEINDENT() { count--; if (count < 0) count = 0; } #define CNT_PRINT(s) { int i; for (i = 0; i < count; i++) { fprintf(s, "\t"); } } /** \file Print / display functions for %mapitest output */ /** \details Indent the mapitest_print tabulation counter */ _PUBLIC_ void mapitest_indent(void) { CNT_INDENT(); } /** \details Deindent the mapitest_print tabulation counter */ _PUBLIC_ void mapitest_deindent(void) { CNT_DEINDENT(); } /** \details Print tabulations given the internal counter \param mt pointer to the top-level mapitest structure */ _PUBLIC_ void mapitest_print_tab(struct mapitest *mt) { CNT_PRINT(mt->stream); } /** \details Print a string in the stream \param mt pointer to the top-level mapitest structure \param format the format string \param ... the format string parameters */ _PUBLIC_ void mapitest_print(struct mapitest *mt, const char *format, ...) { va_list ap; char *s = NULL; if (mt->subunit_output) { return; } va_start(ap, format); vasprintf(&s, format, ap); va_end(ap); mapitest_print_tab(mt); fprintf(mt->stream, s, strlen(s)); free(s); } /** \details Print newline characters \param mt pointer to the top-level mapitest structure \param count number of newline characters to print */ _PUBLIC_ void mapitest_print_newline(struct mapitest *mt, int count) { int i; if (mt->subunit_output) { return; } for (i = 0; i < count; i++) { fprintf(mt->stream, "\n"); } } /** \details Print a line using a delimiter \param mt pointer to the top-level mapitest structure \param len the length of the line to print \param delim the line delimiter */ _PUBLIC_ void mapitest_print_line(struct mapitest *mt, int len, char delim) { int i; if (mt->subunit_output) { return; } for (i = 0; i < len; i++) { fprintf(mt->stream, "%c", delim); } mapitest_print_newline(mt, 1); } /** \details Underline a string \param mt pointer to the top-level mapitest structure \param str string to underline \param delim the line delimiter */ _PUBLIC_ void mapitest_underline(struct mapitest *mt, const char *str, char delim) { if (!str) return; /* print str */ mapitest_print_tab(mt); fprintf(mt->stream, "%s", str); /* underline str using delim */ mapitest_print_tab(mt); mapitest_print_line(mt, strlen(str), delim); } /** \details Private general routine used to print a title Avoid code redundancy over the API \param mt pointer to the top-level mapitest structure \param str the title \param delim the underline delimiter */ _PUBLIC_ void mapitest_print_title(struct mapitest *mt, const char *str, char delim) { /* we handle this outside mapitest if we're using subunit */ if (mt->subunit_output) { return; } mapitest_underline(mt, str, delim); mapitest_indent(); } /** \details Print the module title \param mt pointer to the top-level mapitest structure \param str the module title string */ _PUBLIC_ void mapitest_print_module_title_start(struct mapitest *mt, const char *str) { char *title = NULL; if (!str) return; title = talloc_asprintf(mt->mem_ctx, MODULE_TITLE, str); mapitest_print(mt, "%s", title); mapitest_print_tab(mt); mapitest_print_line(mt, MODULE_TITLE_LINELEN, MODULE_TITLE_DELIM); mapitest_indent(); talloc_free(title); } /** \details Print the content at the end of the module \param mt pointer to the top-level mapitest structure */ _PUBLIC_ void mapitest_print_module_title_end(struct mapitest *mt) { mapitest_deindent(); mapitest_print_tab(mt); mapitest_print_line(mt, MODULE_TITLE_LINELEN, MODULE_TITLE_DELIM); mapitest_print_newline(mt, MODULE_TITLE_NEWLINE); } /** \details print the test title \param mt pointer to the top-level mapitest structure \param str the test title */ _PUBLIC_ void mapitest_print_test_title_start(struct mapitest *mt, const char *str) { char *title = NULL; if (!str) return; #ifdef HAVE_SUBUNIT if (mt->subunit_output) { subunit_test_start(str); return; } #endif title = talloc_asprintf(mt->mem_ctx, MODULE_TEST_TITLE, str); mapitest_print(mt, "%s", title); mapitest_print_tab(mt); mapitest_print_line(mt, MODULE_TEST_LINELEN, MODULE_TEST_DELIM); mapitest_indent(); talloc_free(title); } /** \details Write the content at the end of a test \param mt pointer to the top-level mapitest structure */ _PUBLIC_ void mapitest_print_test_title_end(struct mapitest *mt) { mapitest_deindent(); mapitest_print_tab(mt); mapitest_print_line(mt, MODULE_TEST_LINELEN, MODULE_TEST_DELIM); } /** \details Starts the header output \param mt pointer on the top-level mapitest structure */ static void mapitest_print_headers_start(struct mapitest *mt) { mapitest_print(mt, MT_HDR_START); } /** \details Ends the header output */ static void mapitest_print_headers_end(struct mapitest *mt) { mapitest_print(mt, MT_HDR_END); } /** \details Print mapitest report headers information \param mt pointer to the top-level mapitest structure */ _PUBLIC_ void mapitest_print_headers_info(struct mapitest *mt) { time_t t; char *date; time (&t); date = ctime(&t); mapitest_print(mt, MT_HDR_FMT_DATE, "Date", date); mapitest_print(mt, MT_HDR_FMT, "Confidential mode", (mt->confidential == true) ? MT_YES : MT_NO); mapitest_print(mt, MT_HDR_FMT, "Samba Information", SAMBA_VERSION_STRING); mapitest_print(mt, MT_HDR_FMT, "OpenChange Information", OPENCHANGE_VERSION_STRING); mapitest_print_newline(mt, 1); mapitest_print(mt, MT_HDR_FMT_SECTION, "System Information"); mapitest_indent(); mapitest_print(mt, MT_HDR_FMT_SUBSECTION, "Kernel name", OPENCHANGE_SYS_KERNEL_NAME); mapitest_print(mt, MT_HDR_FMT_SUBSECTION, "Kernel release", OPENCHANGE_SYS_KERNEL_RELEASE); mapitest_print(mt, MT_HDR_FMT_SUBSECTION, "Processor", OPENCHANGE_SYS_PROCESSOR); mapitest_deindent(); } /** \details Print out a normalized version number for a client or server. \param mt pointer to the top level mapitest structure \param label label for the version (e.g. "Store Version" or "Client Version") \param word0 highest order word for the version \param word1 middle word for the version \param word2 low word for the version */ static void mapitest_print_version_normalised(struct mapitest *mt, const char* label, const uint16_t word0, const uint16_t word1, const uint16_t word2) { /* See MS-OXRPC Section 3.1.9 to understand this */ uint16_t normalisedword0; uint16_t normalisedword1; uint16_t normalisedword2; uint16_t normalisedword3; if (word1 & 0x8000) { /* new format */ normalisedword0 = (word0 & 0xFF00) >> 8; normalisedword1 = (word0 & 0x00FF); normalisedword2 = (word1 & 0x7FFF); normalisedword3 = word2; } else { normalisedword0 = word0; normalisedword1 = 0; normalisedword2 = word1; normalisedword3 = word2; } mapitest_print(mt, MT_HDR_FMT_VER_NORM, label, normalisedword0, normalisedword1, normalisedword2, normalisedword3); } /** \details Print a report of the Exchange server and account information \param mt pointer to the top-level mapitest structure */ _PUBLIC_ void mapitest_print_headers_server_info(struct mapitest *mt) { if (mt->online == false) { return; } mapitest_print_newline(mt, 1); mapitest_print(mt, MT_HDR_FMT_SECTION, "Exchange Server"); mapitest_indent(); mapitest_print_version_normalised(mt, "Store Version", mt->info.rgwServerVersion[0], mt->info.rgwServerVersion[1], mt->info.rgwServerVersion[2]); mapitest_print(mt, MT_HDR_FMT_SUBSECTION, "Username", (mt->confidential == true) ? MT_CONFIDENTIAL : mt->info.szDisplayName); mapitest_print(mt, MT_HDR_FMT_SUBSECTION, "Organization", (mt->confidential == true) ? MT_CONFIDENTIAL : mt->org); mapitest_print(mt, MT_HDR_FMT_SUBSECTION, "Organization Unit", (mt->confidential == true) ? MT_CONFIDENTIAL : mt->org_unit); mapitest_deindent(); } /** \details Print mapitest report headers \param mt pointer to the top-level mapitest structure */ _PUBLIC_ void mapitest_print_headers(struct mapitest *mt) { if (mt->subunit_output) { return; } mapitest_print_headers_start(mt); mapitest_indent(); mapitest_print_headers_info(mt); if (mt->no_server == false) { mapitest_print_headers_server_info(mt); } mapitest_deindent(); mapitest_print_headers_end(mt); mapitest_print_newline(mt, 2); } /** \details Print %mapitest test result \param mt pointer to the top-level mapitest structure \param name the test name \param ret boolean value with the test result */ _PUBLIC_ void mapitest_print_test_result(struct mapitest *mt, char *name, bool ret) { #ifdef HAVE_SUBUNIT if (mt->subunit_output) { if (ret == true) { subunit_test_pass(name); } else { subunit_test_fail(name, "failed"); } } else #endif { mapitest_print(mt, MODULE_TEST_RESULT, name, (ret == true) ? MODULE_TEST_SUCCESS : MODULE_TEST_FAILURE); mapitest_print_tab(mt); mapitest_print_line(mt, MODULE_TEST_LINELEN, MODULE_TEST_DELIM2); mapitest_print_newline(mt, MODULE_TEST_NEWLINE); } } /** \details Print %mapitest return value \param mt pointer to the top-level mapitest structure \param name the test name \sa mapitest_print_retval_fmt for a version providing an additional format string \sa mapitest_print_retval_clean for a version that doesn't rely on GetLastError() */ _PUBLIC_ void mapitest_print_retval(struct mapitest *mt, char *name) { const char *retstr = NULL; if (mt->subunit_output) { return; } retstr = mapi_get_errstr(GetLastError()); if (mt->color == true) { if (retstr) { mapitest_print(mt, "* %-35s: %s %s %s \n", name, (GetLastError() ? MT_RED : MT_GREEN), retstr, MT_WHITE); } else { mapitest_print(mt, "* %-35s: %s Unknown Error (0x%.8x) %s\n", name, MT_RED, GetLastError(), MT_WHITE); } } else { if (retstr) { mapitest_print(mt, "* %-35s: %s\n", name, retstr); } else { mapitest_print(mt, "* %-35s: Unknown Error (0x%.8x)\n", name, GetLastError()); } } } /** \details Print %mapitest return value This version takes an explicit return status value \param mt pointer to the top-level mapitest structure \param name the test name \param retval the return value to output \sa mapitest_print_retval_fmt_clean for a version providing an additional format string */ _PUBLIC_ void mapitest_print_retval_clean(struct mapitest *mt, char *name, enum MAPISTATUS retval) { const char *retstr = NULL; if (mt->subunit_output) { return; } retstr = mapi_get_errstr(retval); if (mt->color == true) { if (retstr) { mapitest_print(mt, "* %-35s: %s %s %s \n", name, (retval ? MT_RED : MT_GREEN), retstr, MT_WHITE); } else { mapitest_print(mt, "* %-35s: %s Unknown Error (0x%.8x) %s\n", name, MT_RED, retval, MT_WHITE); } } else { if (retstr) { mapitest_print(mt, "* %-35s: %s\n", name, retstr); } else { mapitest_print(mt, "* %-35s: Unknown Error (0x%.8x)\n", name, retval); } } } /** \details Print %mapitest return value with additional format string \param mt pointer to the top-level mapitest structure \param name the test name \param format the format string \param ... the format string parameters */ _PUBLIC_ void mapitest_print_retval_fmt(struct mapitest *mt, char *name, const char *format, ...) { const char *retstr = NULL; va_list ap; char *s = NULL; va_start(ap, format); vasprintf(&s, format, ap); va_end(ap); retstr = mapi_get_errstr(GetLastError()); if (mt->color == true) { if (retstr) { mapitest_print(mt, "* %-35s: %s %s %s %s\n", name, (GetLastError() ? MT_RED: MT_GREEN), retstr, MT_WHITE, s); } else { mapitest_print(mt, "* %-35s: %s Unknown Error (0x%.8x) %s %s\n", name, MT_RED, GetLastError(), MT_WHITE, s); } } else { if (retstr) { mapitest_print(mt, "* %-35s: %s %s\n", name, retstr, s); } else { mapitest_print(mt, "* %-35s: Unknown Error (0x%.8x) %s\n", name, GetLastError(), s); } } free(s); } /** \details Print %mapitest return value with additional format string \param mt pointer to the top-level mapitest structure \param name the test name \param retval the return value to output \param format the format string \param ... the format string parameters */ _PUBLIC_ void mapitest_print_retval_fmt_clean(struct mapitest *mt, char *name, enum MAPISTATUS retval, const char *format, ...) { const char *retstr = NULL; va_list ap; char *s = NULL; va_start(ap, format); vasprintf(&s, format, ap); va_end(ap); retstr = mapi_get_errstr(retval); if (mt->color == true) { if (retstr) { mapitest_print(mt, "* %-35s: %s %s %s %s\n", name, (retval ? MT_RED: MT_GREEN), retstr, MT_WHITE, s); } else { mapitest_print(mt, "* %-35s: %s Unknown Error (0x%.8x) %s %s\n", name, MT_RED, retval, MT_WHITE, s); } } else { if (retstr) { mapitest_print(mt, "* %-35s: %s %s\n", name, retstr, s); } else { mapitest_print(mt, "* %-35s: Unknown Error (0x%.8x) %s\n", name, retval, s); } } free(s); } /** \details Print %mapitest return value for a given step \param mt pointer to the top-level mapitest structure \param step the test step \param name the test name \param retval the return value \sa mapitest_print_retval_step_fmt for a version providing an additional format string */ _PUBLIC_ void mapitest_print_retval_step(struct mapitest *mt, char *step, char *name, enum MAPISTATUS retval) { const char *retstr = NULL; retstr = mapi_get_errstr(retval); if (mt->color == true) { if (retstr) { mapitest_print(mt, "* Step %-5s %-35s: %s %s %s\n", step, name, (retval ? MT_RED : MT_GREEN), retstr, MT_WHITE); } else { mapitest_print(mt, "* Step %-5s %-35s: %s Unknown Error (0x%.8x) %s\n", step, name, MT_RED, retval, MT_WHITE); } } else { if (retstr) { mapitest_print(mt, "* Step %-5s %-35s: %s\n", step, name, retstr); } else { mapitest_print(mt, "* Step %-5s %-35s: Unknown Error (0x%.8x)\n", step, name, retval); } } } /** \details Print %mapitest return value for a given step with additional format string \param mt pointer to the top-level mapitest structure \param step the test step \param name the test name \param format the format string \param ... the format string parameters */ _PUBLIC_ void mapitest_print_retval_step_fmt(struct mapitest *mt, char *step, char *name, const char *format, ...) { const char *retstr = NULL; va_list ap; char *s = NULL; va_start(ap, format); vasprintf(&s, format, ap); va_end(ap); retstr = mapi_get_errstr(GetLastError()); if (mt->color == true) { if (retstr) { mapitest_print(mt, "* Step %-5s %-35s: %s %s %s %s\n", step, name, (GetLastError() ? MT_RED : MT_GREEN), retstr, MT_WHITE, s); } else { mapitest_print(mt, "* Step %-5s %-35s: %s Unknown Error (0x%.8x) %s %s\n", step, name, MT_RED, GetLastError(), MT_WHITE, s); } } else { if (retstr) { mapitest_print(mt, "* Step %-5s %-35s: %s %s\n", step, name, retstr, s); } else { mapitest_print(mt, "* Step %-5s %-35s: Unknown Error (0x%.8x) %s\n", step, name, GetLastError(), s); } } free(s); } /** Output a set of rows from a table \param mt pointer to the top-level mapitest structure \param rowset the rows to output \param sep a separator / spacer to insert in front of the label \note this is a simple wrapper for mapidump_SRowSet(), only for use in mapitest. */ _PUBLIC_ void mapitest_print_SRowSet(struct mapitest *mt, struct SRowSet *rowset, const char *sep) { if (mt->subunit_output) { return; } mapidump_SRowSet(rowset, sep); } /** Output a row of the public address book \param mt pointer to the top-level mapitest structure \param lpProp the property to print \param sep a separator / spacer to insert in front of the label \note this is a simple wrapper for mapidump_SPropValue(), only for use in mapitest. */ _PUBLIC_ void mapitest_print_SPropValue(struct mapitest *mt, struct SPropValue lpProp, const char *sep) { if (mt->subunit_output) { return; } mapidump_SPropValue(lpProp, sep); } /** Output a row of the public address book \param mt pointer to the top-level mapitest structure \param aRow one row of the public address book (Global Address List) This function is usually used with GetGALTable, which can obtain several rows at once - you'll need to iterate over the rows. The SRow is assumed to contain entries for PR_ADDRTYPE_UNICODE, PR_DISPLAY_NAME_UNICODE, PR_EMAIL_ADDRESS_UNICODE and PR_ACCOUNT_UNICODE. \note this is a simple wrapper for mapidump_PAB_entry(), only for use in mapitest. */ _PUBLIC_ void mapitest_print_PAB_entry(struct mapitest *mt, struct PropertyRow_r *aRow) { if (mt->subunit_output) { return; } mapidump_PAB_entry(aRow); } openchange-2.0/utils/mapitest/mapitest_proto.h000066400000000000000000000047011223057412600216760ustar00rootroot00000000000000#ifndef __UTILS_MAPITEST_MAPITEST_PROTO_H__ #define __UTILS_MAPITEST_MAPITEST_PROTO_H__ #undef _PRINTF_ATTRIBUTE #define _PRINTF_ATTRIBUTE(a1, a2) PRINTF_ATTRIBUTE(a1, a2) #ifndef __BEGIN_DECLS #ifdef __cplusplus #define __BEGIN_DECLS extern "C" { #define __END_DECLS } #else #define __BEGIN_DECLS #define __END_DECLS #endif #endif __BEGIN_DECLS /* This file was automatically generated by mkproto.pl. DO NOT EDIT */ /* this file contains prototypes for functions that are private * to this subsystem or library. These functions should not be * used outside this particular subsystem! */ /* The following definitions come from utils/mapitest/mapitest_suite.c */ /* The following definitions come from utils/mapitest/mapitest_print.c */ /* The following definitions come from utils/mapitest/mapitest_stat.c */ /* The following definitions come from utils/mapitest/mapitest_common.c */ /* The following definitions come from utils/mapitest/module.c */ /* The following definitions come from utils/mapitest/modules/module_oxcstor.c */ /* The following definitions come from utils/mapitest/modules/module_oxcfold.c */ /* The following definitions come from utils/mapitest/modules/module_oxcfxics.c */ /* The following definitions come from utils/mapitest/modules/module_oxomsg.c */ /* The following definitions come from utils/mapitest/modules/module_oxcmsg.c */ /* The following definitions come from utils/mapitest/modules/module_oxcprpt.c */ /* The following definitions come from utils/mapitest/modules/module_oxctable.c */ /* The following definitions come from utils/mapitest/modules/module_oxorule.c */ /* The following definitions come from utils/mapitest/modules/module_oxcnotif.c */ int cb(uint16_t, void* , void* ); /* The following definitions come from utils/mapitest/modules/module_oxcperm.c */ /* The following definitions come from utils/mapitest/modules/module_nspi.c */ /* The following definitions come from utils/mapitest/modules/module_noserver.c */ /* The following definitions come from utils/mapitest/modules/module_errorchecks.c */ /* The following definitions come from utils/mapitest/modules/module_lcid.c */ /* The following definitions come from utils/mapitest/modules/module_mapidump.c */ /* The following definitions come from utils/mapitest/modules/module_lzxpress.c */ __END_DECLS #undef _PRINTF_ATTRIBUTE #define _PRINTF_ATTRIBUTE(a1, a2) #endif /* __UTILS_MAPITEST_MAPITEST_PROTO_H__ */ openchange-2.0/utils/mapitest/mapitest_stat.c000066400000000000000000000150611223057412600215020ustar00rootroot00000000000000/* Stand-alone MAPI testsuite OpenChange Project Copyright (C) Julien Kerihuel 2008 This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see . */ #include "utils/mapitest/mapitest.h" #include /** \file mapitest statistics functions mapitest records and prints the results of each test using these functions */ /** Descriptions of TestApplicabilityFlags */ struct TestApplicabilityDescription { enum TestApplicabilityFlags flags; /*!< The flag value */ char* description; /*!< A user-visible string equivalent */ } applicabilityFlagsDescription[] = { { ApplicableToAllVersions, "Applicable to all server versions" }, { NotInExchange2010, "Not applicable to Exchange 2010" }, { NotInExchange2010SP0, "Not applicable to Exchange 2010 SP0" }, { LastTestApplicabilityFlag, "Sentinel Value" } }; /** \details Initialize the mapitest statistic structure \param mem_ctx memory allocation context \return Allocated stat structure on success, otherwise NULL */ _PUBLIC_ struct mapitest_stat *mapitest_stat_init(TALLOC_CTX *mem_ctx) { struct mapitest_stat *stat = NULL; /* Sanity check */ if (!mem_ctx) return NULL; stat = talloc_zero(mem_ctx, struct mapitest_stat); stat->success = 0; stat->failure = 0; stat->skipped = 0; stat->x_fail = 0; stat->failure_info = NULL; stat->skip_info = NULL; stat->enabled = false; return stat; } /** \details Add test result to the suite statistic parameter \param suite the suite container \param name the test name \param testresult the test result \return MAPITEST_SUCCESS on success, otherwise MAPITEST_ERROR */ _PUBLIC_ uint32_t mapitest_stat_add_result(struct mapitest_suite *suite, const char *name, enum TestResult testresult) { struct mapitest_unit *el = NULL; /* Sanity check */ if (!suite || !suite->stat || !name) return MAPITEST_ERROR; if (testresult == Pass) { suite->stat->success++; } else { el = talloc_zero((TALLOC_CTX *) suite->stat, struct mapitest_unit); el->name = talloc_strdup((TALLOC_CTX *)el, (char *)name); if (testresult == Fail) { suite->stat->failure++; el->reason = talloc_strdup((TALLOC_CTX *) el, "Unexpected Fail"); } else if ((int)testresult == (int)ExpectedFailure) { suite->stat->x_fail++; el->reason = talloc_strdup((TALLOC_CTX *) el, "Expected Fail"); } else if (testresult == UnexpectedPass) { suite->stat->failure++; el->reason = talloc_strdup((TALLOC_CTX *) el, "Unexpected Pass"); } else { assert(0); /* this indicates that we're passing a bad enum into this function */ } DLIST_ADD_END(suite->stat->failure_info, el, struct mapitest_unit *); } suite->stat->enabled = true; return MAPITEST_SUCCESS; } static void mapitest_stat_add_skipped_test_reason(struct mapitest_unit *stat_unit, enum TestApplicabilityFlags flags) { int i; for (i = 0; applicabilityFlagsDescription[i].flags != LastTestApplicabilityFlag; ++i) { if (flags & applicabilityFlagsDescription[i].flags) { if (!stat_unit->reason) { stat_unit->reason = talloc_strdup((TALLOC_CTX *)stat_unit, applicabilityFlagsDescription[i].description); } else { stat_unit->reason = talloc_asprintf_append(stat_unit->reason, ", %s", applicabilityFlagsDescription[i].description); } } } if (!stat_unit->reason) { stat_unit->reason = talloc_strdup((TALLOC_CTX *)stat_unit, "Unknown reason"); } } /** \details Add a skipped test to the suite statistic parameters \param suite the suite container \param name the test name \param flags flags to indicate the reason why the test was skipped \return MAPITEST_SUCCESS on success, otherwise MAPITEST_ERROR */ _PUBLIC_ uint32_t mapitest_stat_add_skipped_test(struct mapitest_suite *suite, const char *name, enum TestApplicabilityFlags flags) { struct mapitest_unit *el = NULL; /* Sanity check */ if (!suite || !suite->stat || !name) return MAPITEST_ERROR; suite->stat->skipped++; el = talloc_zero((TALLOC_CTX *) suite->stat, struct mapitest_unit); el->name = talloc_strdup((TALLOC_CTX *)el, (char *)name); mapitest_stat_add_skipped_test_reason(el, flags); DLIST_ADD_END(suite->stat->skip_info, el, struct mapitest_unit *); suite->stat->enabled = true; return MAPITEST_SUCCESS; } /** \details Dump mapitest statistics about test failures \param mt the global mapitest structure \return the number of test steps that failed (i.e. 0 for all success) */ _PUBLIC_ int32_t mapitest_stat_dump(struct mapitest *mt) { struct mapitest_suite *suite; struct mapitest_unit *el; int32_t num_passed_tests = 0; int32_t num_failed_tests = 0; int32_t num_skipped_tests = 0; int32_t num_xfail_tests = 0; mapitest_print_title(mt, MT_STAT_SKIPPED_TITLE, MODULE_TITLE_DELIM); for (suite = mt->mapi_suite; suite; suite = suite->next) { if (suite->stat->enabled == true) { num_skipped_tests += suite->stat->skipped; if (suite->stat->skipped) { for (el = suite->stat->skip_info; el; el = el->next) { mapitest_print(mt, MT_STAT_RESULT, suite->name, el->name, el->reason); } } } } mapitest_print_test_title_end(mt); mapitest_print_title(mt, MT_STAT_FAILED_TITLE, MODULE_TITLE_DELIM); for (suite = mt->mapi_suite; suite; suite = suite->next) { if (suite->stat->enabled == true) { num_passed_tests += suite->stat->success; num_failed_tests += suite->stat->failure; num_xfail_tests += suite->stat->x_fail; if (suite->stat->failure || suite->stat->x_fail) { for (el = suite->stat->failure_info; el; el = el->next) { mapitest_print(mt, MT_STAT_RESULT, suite->name, el->name, el->reason); } } } } mapitest_print_test_title_end(mt); mapitest_print_title(mt, MT_SUMMARY_TITLE, MODULE_TITLE_DELIM); mapitest_print(mt, "Number of passing tests: %i\n", num_passed_tests); mapitest_print(mt, "Number of failing tests: %i\n", num_failed_tests); mapitest_print(mt, "Number of skipped tests: %i\n", num_skipped_tests); mapitest_print(mt, "Number of expected fails: %i\n", num_xfail_tests); mapitest_print_test_title_end(mt); return num_failed_tests; } openchange-2.0/utils/mapitest/mapitest_suite.c000066400000000000000000000241371223057412600216640ustar00rootroot00000000000000/* Stand-alone MAPI testsuite OpenChange Project Copyright (C) Julien Kerihuel 2008 This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see . */ #include "utils/mapitest/mapitest.h" /** \file mapitest test suite functions */ /** \details Initialize a mapitest suite \param mt the top-level mapitest structure \param name the suite name \param description the suite description \param online whether this suite requires online (server) access \return An allocated mapitest_suite pointer, otherwise NULL. */ _PUBLIC_ struct mapitest_suite *mapitest_suite_init(struct mapitest *mt, const char *name, const char *description, bool online) { struct mapitest_suite *suite = NULL; /* Sanity check */ if (!mt || !mt->mem_ctx) return NULL; if (!name) return NULL; suite = talloc_zero(mt->mem_ctx, struct mapitest_suite); suite->tests = NULL; suite->stat = mapitest_stat_init((TALLOC_CTX *)suite); suite->name = talloc_strdup((TALLOC_CTX *) suite, name); if (!description) { suite->description = NULL; } else { suite->description = talloc_strdup((TALLOC_CTX *)suite, description); } suite->online = online; return suite; } /** \details Register a mapitest suite \param mt the top-level mapitest structure \param suite the mapitest suite we want to add \return MAPITEST_SUCCESS on success, otherwise MAPITEST_ERROR \sa mapitest_suite_init */ _PUBLIC_ uint32_t mapitest_suite_register(struct mapitest *mt, struct mapitest_suite *suite) { struct mapitest_suite *el = NULL; /* Sanity check */ if (!mt || !mt->mem_ctx) return MAPITEST_ERROR; if (!suite) return MAPITEST_ERROR; /* Ensure the name is not yet registered */ for (el = mt->mapi_suite; el; el = el->next) { if (el->name && !strcmp(el->name, suite->name)) { fprintf(stderr, "Suite already registered\n"); return MAPITEST_ERROR; } } DLIST_ADD_END(mt->mapi_suite, suite, struct mapitest_suite *); return MAPITEST_SUCCESS; } /** \details add a test to the mapitest suite with description \param suite pointer on the parent suite \param name the test name \param description the test description \param run the test function \return MAPITEST_SUCCESS on success, otherwise MAPITEST_ERROR \sa mapitest_suite_init, mapitest_suite_register \sa mapitest_suite_add_test_flagged for an alternative function allowing the test to only be run under some conditions. */ _PUBLIC_ uint32_t mapitest_suite_add_test(struct mapitest_suite *suite, const char *name, const char *description, bool (*run) (struct mapitest *test)) { return mapitest_suite_add_test_flagged(suite, name, description, run, ApplicableToAllVersions); } /** \details add a test to the mapitest suite with description and flags This is very similar to mapitest_suite_add_test(), except it allows a test to have special applicability (e.g. to only run when a particular server configuration is available). \param suite pointer to the parent test suite \param name the test name \param description the test description \param run the test function \param applicability a set of applicability flags \return MAPITEST_SUCCESS on success, otherwise MAPITEST_ERROR \sa mapitest_suite_init, mapitest_suite_register, mapitest_suite_add_test */ _PUBLIC_ uint32_t mapitest_suite_add_test_flagged(struct mapitest_suite *suite, const char *name, const char *description, bool (*run) (struct mapitest *test), enum TestApplicabilityFlags applicability) { struct mapitest_test *el = NULL; /* Sanity check */ if (!suite || !name || !run || !description) return MAPITEST_ERROR; /* Ensure the test is not yet registered */ for (el = suite->tests; el; el = el->next) { if (el->name && !strcmp(el->name, name)) { return MAPITEST_ERROR; } } el = talloc_zero((TALLOC_CTX *) suite, struct mapitest_test); el->name = talloc_asprintf((TALLOC_CTX *)suite, "%s-%s", suite->name, name); el->description = talloc_strdup((TALLOC_CTX *)suite, description); el->fn = run; el->flags = applicability; DLIST_ADD_END(suite->tests, el, struct mapitest_test *); return MAPITEST_SUCCESS; } /** \details Find a suite given its name \param mt top-level mapitest structure \param name the suite name to be searched \return Pointer on a suite on success, otherwise NULL */ _PUBLIC_ struct mapitest_suite *mapitest_suite_find(struct mapitest *mt, const char *name) { struct mapitest_suite *suite = NULL; if (!name) return NULL; for (suite = mt->mapi_suite; suite; suite = suite->next) { if (!strcmp(name, suite->name)) { return suite; } } return NULL; } /** \details test whether a particular test is applicable \param mt pointer to the top-level mapitest structure \param el the test to check \return true if the test should be run, otherwise false */ static bool mapitest_suite_test_is_applicable(struct mapitest *mt, struct mapitest_test *test) { uint16_t actualServerVer = mt->info.rgwServerVersion[0]; if ((test->flags & NotInExchange2010) && (actualServerVer >= Exchange2010SP0Version)) { return false; } if ((test->flags & NotInExchange2010SP0) && (actualServerVer == Exchange2010SP0Version)) { return false; } return true; } static bool run_test(struct mapitest *mt, struct mapitest_suite *suite, struct mapitest_test *el) { bool (*fn)(struct mapitest *); bool ret = false; if (!mapitest_suite_test_is_applicable(mt, el)) { mapitest_stat_add_skipped_test(suite, el->name, el->flags); } else { errno = 0; mapitest_print_test_title_start(mt, el->name); fn = el->fn; ret = fn(mt); if (el->flags & ExpectedFail) { if (ret) { mapitest_stat_add_result(suite, el->name, UnexpectedPass); } else { mapitest_stat_add_result(suite, el->name, ExpectedFailure); } } else { if (ret) { mapitest_stat_add_result(suite, el->name, Pass); } else { mapitest_stat_add_result(suite, el->name, Fail); } } mapitest_print_test_title_end(mt); mapitest_print_test_result(mt, el->name, ret); } return ret; } /** \details run a test from a suite given its name \param mt pointer on the top-level mapitest structure \param suite pointer on the mapitest suite \param name the name of the test to be run \return true on success, otherwise false */ _PUBLIC_ bool mapitest_suite_run_test(struct mapitest *mt, struct mapitest_suite *suite, const char *name) { struct mapitest_test *el; bool ret; if (!suite || !name) return false; for (el = suite->tests; el; el = el->next) { if (!strcmp(el->name, name)) { ret = run_test(mt, suite, el); return ret; } } fprintf(stderr, "[ERROR] %s test doesn't exist\n", name); return false; } /** \details run the special SUITE-ALL test \param mt the top-level mapitest structure \param name the mapitest test name \return true on success, otherwise -1 */ static bool mapitest_run_test_all(struct mapitest *mt, const char *name) { char *test_name; char *sname; char *tmp; struct mapitest_test *el; struct mapitest_suite *suite; bool ret = false; test_name = talloc_strdup(mt->mem_ctx, name); if ((tmp = strtok(test_name, "-")) == NULL) { talloc_free(test_name); } sname = talloc_strdup(mt->mem_ctx, tmp); if ((tmp = strtok(NULL, "-")) == NULL) { talloc_free(test_name); talloc_free(sname); return false; } if (!strcmp(tmp,"ALL")) { suite = mapitest_suite_find(mt, sname); if ((suite && (suite->online == mt->online)) || (suite && (suite->online == false))) { for (el = suite->tests; el; el = el->next) { if (mapitest_suite_test_is_applicable(mt, el)) { mapitest_suite_run_test(mt, suite, el->name); ret = true; } else { printf("test is not applicable: %s\n", el->name); return true; } } } } talloc_free(sname); talloc_free(test_name); return ret; } /** \details run a specific test from a particular suite \param mt the top-level mapitest structure \param name the mapitest test name \return true on success, otherwise -1 */ _PUBLIC_ bool mapitest_run_test(struct mapitest *mt, const char *name) { struct mapitest_suite *suite; struct mapitest_test *el; bool ret; /* sanity check */ if (!mt || !name) return false; /* try to find the test */ for (suite = mt->mapi_suite; suite; suite = suite->next) { for (el = suite->tests; el; el = el->next) { if (!strcmp(name, el->name)) { if (((mt->online == suite->online) && mt->session) || (suite->online == false)) { errno = 0; ret = mapitest_suite_run_test(mt, suite, name); return ret; } else { fprintf(stderr, "Server is offline, skipping test: \"%s\"\n", name); return true; } } } } /* if no name matches, look it it matches ALL */ ret = mapitest_run_test_all(mt, name); if (ret != true) { fprintf(stderr, "[ERROR] Unknown test: \"%s\"\n", name); } return ret; } static void run_tests_in_suite(struct mapitest *mt, struct mapitest_suite *suite) { struct mapitest_test *el; for (el = suite->tests; el; el = el->next) { run_test(mt, suite, el); } } /** \details all tests from all suites \param mt the top-level mapitest structure \return true on success, otherwise -1 */ _PUBLIC_ void mapitest_run_all(struct mapitest *mt) { struct mapitest_suite *suite; for (suite = mt->mapi_suite; suite; suite = suite->next) { if (((mt->online == suite->online) && mt->session) || (suite->online == false)) { mapitest_print_module_title_start(mt, suite->name); run_tests_in_suite(mt, suite); mapitest_print_module_title_end(mt); } } } openchange-2.0/utils/mapitest/module.c000066400000000000000000000572401223057412600201130ustar00rootroot00000000000000/* Stand-alone MAPI testsuite OpenChange Project Copyright (C) Julien Kerihuel 2008 This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see . */ #include "utils/mapitest/mapitest.h" #include "utils/mapitest/proto.h" _PUBLIC_ uint32_t mapitest_register_modules(struct mapitest *mt) { uint32_t ret; ret = module_oxcstor_init(mt); ret += module_oxcfold_init(mt); ret += module_oxctable_init(mt); ret += module_oxomsg_init(mt); ret += module_oxcmsg_init(mt); ret += module_oxcprpt_init(mt); ret += module_oxorule_init(mt); ret += module_oxcnotif_init(mt); ret += module_oxcfxics_init(mt); ret += module_oxcperm_init(mt); ret += module_nspi_init(mt); ret += module_noserver_init(mt); ret += module_errorchecks_init(mt); ret += module_lcid_init(mt); ret += module_mapidump_init(mt); ret += module_lzxpress_init(mt); return ret; } /** \details Register the Store Object Protocol test suite \param mt pointer on the top-level mapitest structure \return MAPITEST_SUCCESS on success, otherwise MAPITEST_ERROR */ _PUBLIC_ uint32_t module_oxcstor_init(struct mapitest *mt) { struct mapitest_suite *suite = NULL; suite = mapitest_suite_init(mt, "OXCSTOR", "Store Object Protocol", true); mapitest_suite_add_test(suite, "LOGON", "Logon operation", mapitest_oxcstor_Logon); mapitest_suite_add_test(suite, "GET-RECEIVE-FOLDER", "Retrieve the receive folder ID", mapitest_oxcstor_GetReceiveFolder); mapitest_suite_add_test(suite, "SET-RECEIVE-FOLDER", "Set the receive folder", mapitest_oxcstor_SetReceiveFolder); mapitest_suite_add_test(suite, "GET-RECEIVE-FOLDER-TABLE", "Retrieve the Receive Folder Table", mapitest_oxcstor_GetReceiveFolderTable); mapitest_suite_add_test(suite, "PUBLICFOLDER-ISGHOSTED", "Determine if a public folder is ghosted", mapitest_oxcstor_PublicFolderIsGhosted); mapitest_suite_add_test(suite, "GETOWNINGSERVERS", "Get the list of servers that host replicas of a given public folder", mapitest_oxcstor_GetOwningServers); mapitest_suite_add_test(suite, "LONGTERMID", "Map to / from a Long Term ID", mapitest_oxcstor_LongTermId); mapitest_suite_add_test_flagged(suite, "GETSTORESTATE", "Retrieve the store state", mapitest_oxcstor_GetStoreState, NotInExchange2010); mapitest_suite_add_test(suite, "ISMAILBOXFOLDER", "Get the standard folder for a given folder ID", mapitest_oxcstor_IsMailboxFolder); mapitest_suite_register(mt, suite); return MAPITEST_SUCCESS; } /** \details Register the Folder Object Protocol test suite \param mt the top-level mapitest structure \return MAPITEST_SUCCESS on success, otherwise MAPITEST_ERROR */ _PUBLIC_ uint32_t module_oxcfold_init(struct mapitest *mt) { struct mapitest_suite *suite = NULL; suite = mapitest_suite_init(mt, "OXCFOLD", "Folder Object Protocol", true); mapitest_suite_add_test(suite, "OPEN", "Open a folder", mapitest_oxcfold_OpenFolder); mapitest_suite_add_test(suite, "CREATE-DELETE", "Do a basic create / delete cycle on a folder", mapitest_oxcfold_CreateDeleteFolder); mapitest_suite_add_test(suite, "CREATE", "Create a folder", mapitest_oxcfold_CreateFolder); mapitest_suite_add_test(suite, "CREATE-VARIANTS", "More folder creation variations", mapitest_oxcfold_CreateFolderVariants); mapitest_suite_add_test(suite, "GET-HIERARCHY-TABLE", "Retrieve the hierarchy table", mapitest_oxcfold_GetHierarchyTable); mapitest_suite_add_test(suite, "GET-CONTENTS-TABLE", "Retrieve the contents table", mapitest_oxcfold_GetContentsTable); mapitest_suite_add_test(suite, "SET-SEARCHCRITERIA", "Set a search criteria on a container", mapitest_oxcfold_SetSearchCriteria); mapitest_suite_add_test(suite, "GET-SEARCHCRITERIA", "Retrieve a search criteria associated to a container", mapitest_oxcfold_GetSearchCriteria); mapitest_suite_add_test(suite, "MOVECOPY-MESSAGES", "Move or copy messages from a source to destination folder", mapitest_oxcfold_MoveCopyMessages); mapitest_suite_add_test(suite, "MOVEFOLDER", "Move folder from source to destination", mapitest_oxcfold_MoveFolder); mapitest_suite_add_test(suite, "COPYFOLDER", "Copy folder from source to destination", mapitest_oxcfold_CopyFolder); mapitest_suite_add_test(suite, "HARDDELETEMESSAGES", "Hard delete messages", mapitest_oxcfold_HardDeleteMessages); mapitest_suite_add_test(suite, "HARDDELETEMESSAGESANDSUBFOLDERS", "Hard delete messages and subfolders", mapitest_oxcfold_HardDeleteMessagesAndSubfolders); mapitest_suite_add_test(suite, "DELETEMESSAGES", "Soft delete messages", mapitest_oxcfold_DeleteMessages); mapitest_suite_register(mt, suite); return MAPITEST_SUCCESS; } /** \details Register the E-mail Object Protocol test suite \param mt pointer on the top-level mapitest structure \return MAPITEST_SUCCESS on success, otherwise MAPITEST_ERROR */ _PUBLIC_ uint32_t module_oxomsg_init(struct mapitest *mt) { struct mapitest_suite *suite = NULL; suite = mapitest_suite_init(mt, "OXOMSG", "E-mail Object Protocol", true); mapitest_suite_add_test(suite, "ADDRESS-TYPES", "Address Types", mapitest_oxomsg_AddressTypes); mapitest_suite_add_test(suite, "SUBMIT-MESSAGE", "Submit message", mapitest_oxomsg_SubmitMessage); mapitest_suite_add_test(suite, "ABORT-SUBMIT", "Abort submitted message", mapitest_oxomsg_AbortSubmit); mapitest_suite_add_test(suite, "SET-SPOOLER", "Client intends to act as a mail spooler", mapitest_oxomsg_SetSpooler); mapitest_suite_add_test(suite, "SPOOLER-LOCK-MESSAGE", "Lock the specified message for spooling", mapitest_oxomsg_SpoolerLockMessage); mapitest_suite_add_test(suite, "TRANSPORT-SEND", "Sends the specified message object out for message delivery", mapitest_oxomsg_TransportSend); mapitest_suite_add_test(suite, "TRANSPORT-NEW-MAIL", "Submit a new message for processing", mapitest_oxomsg_TransportNewMail); mapitest_suite_add_test(suite, "GET-TRANSPORT-FOLDER", "Retrieve the temporary transport folder ID", mapitest_oxomsg_GetTransportFolder); mapitest_suite_register(mt, suite); return MAPITEST_SUCCESS; } /** \details Register the Message and Attachment Object Protocol test suite \param mt pointer on the top-level mapitest structure \return MAPITEST_SUCCESS on success, otherwise MAPITEST_ERROR */ _PUBLIC_ uint32_t module_oxcmsg_init(struct mapitest *mt) { struct mapitest_suite *suite = NULL; suite = mapitest_suite_init(mt, "OXCMSG", "Message and Attachment Object Protocol", true); mapitest_suite_add_test(suite, "CREATE-MESSAGE", "Create message", mapitest_oxcmsg_CreateMessage); mapitest_suite_add_test(suite, "SET-MESSAGE-READ-FLAGS", "Set message read flag", mapitest_oxcmsg_SetMessageReadFlag); mapitest_suite_add_test(suite, "SET-READ-FLAGS", "Set read flag on multiple messages", mapitest_oxcmsg_SetReadFlags); mapitest_suite_add_test(suite, "MODIFY-RECIPIENTS", "Add new recipients", mapitest_oxcmsg_ModifyRecipients); mapitest_suite_add_test(suite, "READ-RECIPIENTS", "Read recipients from a message", mapitest_oxcmsg_ReadRecipients); mapitest_suite_add_test(suite, "REMOVE-ALL-RECIPIENTS", "Remove all recipients from a message", mapitest_oxcmsg_RemoveAllRecipients); mapitest_suite_add_test(suite, "SAVE-CHANGES-MESSAGE", "Save changes on message", mapitest_oxcmsg_SaveChangesMessage); mapitest_suite_add_test(suite, "GET-MESSAGE-STATUS", "Get message status", mapitest_oxcmsg_GetMessageStatus); mapitest_suite_add_test(suite, "SET-MESSAGE-STATUS", "Set message status", mapitest_oxcmsg_SetMessageStatus); mapitest_suite_add_test(suite, "OPEN-EMBEDDED-MESSAGE", "Open a message embedded in another message", mapitest_oxcmsg_OpenEmbeddedMessage); mapitest_suite_add_test_flagged(suite, "GET-VALID-ATTACHMENTS", "Get valid attachment IDs for a message", mapitest_oxcmsg_GetValidAttachments, NotInExchange2010); mapitest_suite_add_test(suite, "RELOAD-CACHED-INFORMATION", "Reload cached information for a message", mapitest_oxcmsg_ReloadCachedInformation); mapitest_suite_register(mt, suite); return MAPITEST_SUCCESS; } /** \details Register the Table Object Protocol test suite \param mt pointer on the top-level mapitest structure \return MAPITEST_SUCCESS on success, otherwise MAPITEST_ERROR */ _PUBLIC_ uint32_t module_oxctable_init(struct mapitest *mt) { struct mapitest_suite *suite = NULL; suite = mapitest_suite_init(mt, "OXCTABLE", "Table Object Protocol", true); mapitest_suite_add_test(suite, "SETCOLUMNS", "Set Table Columns", mapitest_oxctable_SetColumns); mapitest_suite_add_test(suite, "QUERYCOLUMNS", "Query Table Columns", mapitest_oxctable_QueryColumns); mapitest_suite_add_test(suite, "QUERYROWS", "Query Table Rows", mapitest_oxctable_QueryRows); mapitest_suite_add_test_flagged(suite, "GETSTATUS", "Get Table Status", mapitest_oxctable_GetStatus, NotInExchange2010); mapitest_suite_add_test(suite, "SEEKROW", "Seek a row", mapitest_oxctable_SeekRow); mapitest_suite_add_test(suite, "RESTRICT", "Apply filters to a table", mapitest_oxctable_Restrict); mapitest_suite_add_test_flagged(suite, "SEEKROW-APPROX", "Seek an approximate row", mapitest_oxctable_SeekRowApprox, NotInExchange2010); mapitest_suite_add_test(suite, "CREATE-BOOKMARK", "Create a table bookmark", mapitest_oxctable_CreateBookmark); mapitest_suite_add_test(suite, "SEEKROW-BOOKMARK", "Seek a row given a bookmark", mapitest_oxctable_SeekRowBookmark); mapitest_suite_add_test(suite, "CATEGORY", "Expand/collapse category rows", mapitest_oxctable_Category); mapitest_suite_register(mt, suite); return MAPITEST_SUCCESS; } /** \details Register the Property and Stream Object Protocol test suite \param mt pointer on the top-level mapitest structure \return MAPITEST_SUCCESS on success, otherwise MAPITEST_ERROR */ _PUBLIC_ uint32_t module_oxcprpt_init(struct mapitest *mt) { struct mapitest_suite *suite = NULL; suite = mapitest_suite_init(mt, "OXCPRPT", "Property and Stream Object Protocol", true); mapitest_suite_add_test(suite, "GET-PROPS", "Retrieve a specific set of properties", mapitest_oxcprpt_GetProps); mapitest_suite_add_test(suite, "GET-PROPSALL", "Retrieve the whole property array", mapitest_oxcprpt_GetPropsAll); mapitest_suite_add_test(suite, "GET-PROPLIST", "Retrieve the property list", mapitest_oxcprpt_GetPropList); mapitest_suite_add_test(suite, "SET-PROPS", "Set a specific set of properties", mapitest_oxcprpt_SetProps); mapitest_suite_add_test(suite, "DELETE-PROPS", "Delete a specific set of properties", mapitest_oxcprpt_DeleteProps); mapitest_suite_add_test(suite, "PROPS-NOREPLICATE", "Set / delete a specific set of properties (no replicate)", mapitest_oxcprpt_NoReplicate); mapitest_suite_add_test(suite, "COPY-PROPS", "Copy a specified set of properties", mapitest_oxcprpt_CopyProps); mapitest_suite_add_test(suite, "STREAM", "Test stream operations", mapitest_oxcprpt_Stream); mapitest_suite_add_test(suite, "COPYTO", "Copy or move properties", mapitest_oxcprpt_CopyTo); mapitest_suite_add_test_flagged(suite, "WRITE-COMMIT-STREAM", "Test atomic Write / Commit operation", mapitest_oxcprpt_WriteAndCommitStream, NotInExchange2010); mapitest_suite_add_test_flagged(suite, "COPYTO-STREAM", "Copy stream from source to destination stream", mapitest_oxcprpt_CopyToStream, NotInExchange2010SP0); mapitest_suite_add_test(suite, "NAME-ID", "Convert between Names and IDs", mapitest_oxcprpt_NameId); mapitest_suite_add_test(suite, "PSMAPI-NAME-ID", "Convert between Names and IDs for PS_MAPI namespace", mapitest_oxcprpt_NameId_PSMAPI); mapitest_suite_register(mt, suite); return MAPITEST_SUCCESS; } /** \details Register the E-Mail Rules Protocol test suite \param mt pointer on the top-level mapitest structure \return MAPITEST_SUCCESS on success, otherwise MAPITEST_ERROR */ _PUBLIC_ uint32_t module_oxorule_init(struct mapitest *mt) { struct mapitest_suite *suite = NULL; suite = mapitest_suite_init(mt, "OXORULE", "E-Mail Rules Protocol", true); mapitest_suite_add_test(suite, "GET-RULES-TABLE", "Retrieve the rules table associated to a folder", mapitest_oxorule_GetRulesTable); mapitest_suite_register(mt, suite); return MAPITEST_SUCCESS; } /** \details Register the Core Notification Protocol test suite \param mt pointer on the top-level mapitest structure \return MAPITEST_SUCCESS on success, otherwise MAPITEST_ERROR */ _PUBLIC_ uint32_t module_oxcnotif_init(struct mapitest *mt) { struct mapitest_suite *suite = NULL; suite = mapitest_suite_init(mt, "OXCNOTIF", "Core Notification Protocol", true); // mapitest_suite_add_test(suite, "REGISTER-NOTIFICATION", "Subscribe to notifications", mapitest_oxcnotif_RegisterNotification); mapitest_suite_add_test_flagged(suite, "SYNC-OPEN-ADVISOR", "Test the SyncOpenAdvisor ROP", mapitest_oxcnotif_SyncOpenAdvisor, NotInExchange2010); mapitest_suite_register(mt, suite); return MAPITEST_SUCCESS; } /** \details Register the Bulk Data Transfer Protocol test suite \param mt pointer on the top-level mapitest structure \return MAPITEST_SUCCESS on success, otherwise MAPITEST_ERROR */ _PUBLIC_ uint32_t module_oxcfxics_init(struct mapitest *mt) { struct mapitest_suite *suite = NULL; suite = mapitest_suite_init(mt, "OXCFXICS", "Bulk Data Transfer Protocol", true); mapitest_suite_add_test(suite, "GET-LOCAL-REPLICA-IDS", "Reserve a range of IDs for local replica", mapitest_oxcfxics_GetLocalReplicaIds); mapitest_suite_add_test(suite, "COPYFOLDER", "Test CopyFolder operation", mapitest_oxcfxics_CopyFolder); mapitest_suite_add_test(suite, "COPYMESSAGES", "Test CopyMessages operation", mapitest_oxcfxics_CopyMessages); mapitest_suite_add_test(suite, "COPYTO", "Test CopyTo operation", mapitest_oxcfxics_CopyTo); mapitest_suite_add_test(suite, "COPYPROPS", "Test CopyProperties operation", mapitest_oxcfxics_CopyProperties); mapitest_suite_add_test(suite, "DEST-CONFIGURE", "Test Destination Configure operation", mapitest_oxcfxics_DestConfigure); mapitest_suite_add_test(suite, "SYNC-CONFIGURE", "Configure ICS context for download", mapitest_oxcfxics_SyncConfigure); mapitest_suite_add_test(suite, "SET-LOCAL-REPLICA-MIDSET-DELETED", "Reserve a range of local replica IDs", mapitest_oxcfxics_SetLocalReplicaMidsetDeleted); mapitest_suite_add_test(suite, "SYNC-OPEN-COLLECTOR", "Test opening ICS upload collector", mapitest_oxcfxics_SyncOpenCollector); mapitest_suite_register(mt, suite); return MAPITEST_SUCCESS; } /** \details Register the Permissions Protocol test suite \param mt pointer to the top-level mapitest structure \return MAPITEST_SUCCESS on success, otherwise MAPITEST_ERROR */ _PUBLIC_ uint32_t module_oxcperm_init(struct mapitest *mt) { struct mapitest_suite *suite = NULL; suite = mapitest_suite_init(mt, "OXCPERM", "Permissions Protocol", true); mapitest_suite_add_test(suite, "GET-PERMISSIONS-TABLE", "Get handle to the Permissions table", mapitest_oxcperm_GetPermissionsTable); mapitest_suite_add_test(suite, "MODIFY-PERMISSIONS", "Modify access permissions on a folder", mapitest_oxcperm_ModifyPermissions); mapitest_suite_register(mt, suite); return MAPITEST_SUCCESS; } /** \details Register the NSPI test suite \param mt pointer on the top-level mapitest structure \return MAPITEST_SUCCESS on success, otherwise MAPITEST_ERROR */ _PUBLIC_ uint32_t module_nspi_init(struct mapitest *mt) { struct mapitest_suite *suite = NULL; suite = mapitest_suite_init(mt, "NSPI", "Name Service Provider Interface", true); mapitest_suite_add_test(suite, "UPDATESTAT", "Update the STAT structure", mapitest_nspi_UpdateStat); mapitest_suite_add_test(suite, "QUERYROWS", "Returns a number of rows from a specified table", mapitest_nspi_QueryRows); mapitest_suite_add_test(suite, "SEEKENTRIES", "Searches for and sets the logical position in a specific table", mapitest_nspi_SeekEntries); mapitest_suite_add_test(suite, "GETMATCHES", "Returns an explicit table", mapitest_nspi_GetMatches); mapitest_suite_add_test(suite, "RESORTRESTRICTION", "Apply a sort order to the objects in a restricted address book container", mapitest_nspi_ResortRestriction); mapitest_suite_add_test(suite, "DNTOMID", "Maps a set of DN to a set of MId", mapitest_nspi_DNToMId); mapitest_suite_add_test(suite, "GETPROPLIST", "Retrieve the list of properties associated to an object", mapitest_nspi_GetPropList); mapitest_suite_add_test(suite, "GETPROPS", "Returns a row containing a set of the properties and values", mapitest_nspi_GetProps); mapitest_suite_add_test(suite, "COMPAREMIDS", "Compare the position in an AB container of two objects", mapitest_nspi_CompareMIds); mapitest_suite_add_test(suite, "MODPROPS", "Modify an address book object", mapitest_nspi_ModProps); mapitest_suite_add_test(suite, "GETSPECIALTABLE", "Returns the rows of a special table to the client", mapitest_nspi_GetSpecialTable); mapitest_suite_add_test(suite, "GETTEMPLATEINFO", "Returns information about template objects", mapitest_nspi_GetTemplateInfo); mapitest_suite_add_test(suite, "MODLINKATT", "Modifies the values of a specific property of a specific row", mapitest_nspi_ModLinkAtt); mapitest_suite_add_test(suite, "QUERYCOLUMNS", "Returns a list of all the properties the NSPI server is aware of", mapitest_nspi_QueryColumns); mapitest_suite_add_test(suite, "GETNAMESFROMIDS", "Returns a list of property names for a set of proptags", mapitest_nspi_GetNamesFromIDs); mapitest_suite_add_test(suite, "GETIDSFROMNAMES", "Returns the property IDs associated with property names", mapitest_nspi_GetIDsFromNames); mapitest_suite_add_test(suite, "RESOLVENAMES", "Resolve usernames", mapitest_nspi_ResolveNames); mapitest_suite_add_test(suite, "GETGALTABLE", "Fetches the Global Address List", mapitest_nspi_GetGALTable); mapitest_suite_register(mt, suite); return MAPITEST_SUCCESS; } /** \details Return the no server test suite \param mt pointer on the top-level mapitest structure \return MAPITEST_SUCCESS on success, otherwise MAPITEST_ERROR */ _PUBLIC_ uint32_t module_noserver_init(struct mapitest *mt) { struct mapitest_suite *suite = NULL; suite = mapitest_suite_init(mt, "NOSERVER", "No server operations", false); mapitest_suite_add_test(suite, "LZFU-DECOMPRESS", "Test Compressed RTF decompression operations", mapitest_noserver_lzfu); mapitest_suite_add_test(suite, "LZFU-COMPRESS", "Test Compressed RTF compression operations", mapitest_noserver_rtfcp); mapitest_suite_add_test(suite, "LZFU-COMPRESS-LARGE", "Test RTF (de)compression operations on larger file", mapitest_noserver_rtfcp_large); mapitest_suite_add_test(suite, "SROWSET", "Test SRowSet parsing", mapitest_noserver_srowset); mapitest_suite_add_test(suite, "GETSETPROPS", "Test Property handling", mapitest_noserver_properties); mapitest_suite_add_test(suite, "MAPIPROPS", "Test MAPI Property handling", mapitest_noserver_mapi_properties); mapitest_suite_add_test(suite, "PROPTAGVALUE", "Test MAPI PropTag value handling", mapitest_noserver_proptagvalue); mapitest_suite_register(mt, suite); return MAPITEST_SUCCESS; } /** \details Initialise the error / sanity-check test suite \param mt pointer to the top-level mapitest structure \return MAPITEST_SUCCESS on success, otherwise MAPITEST_ERROR */ _PUBLIC_ uint32_t module_errorchecks_init(struct mapitest *mt) { struct mapitest_suite *suite = NULL; suite = mapitest_suite_init(mt, "ERRORCHECKS", "Error / sanity-check operations", false); mapitest_suite_add_test(suite, "SIMPLEMAPI", "Test failure paths for simplemapi.c", mapitest_errorchecks_simplemapi_c); mapitest_suite_register(mt, suite); return MAPITEST_SUCCESS; } /** \details Initialise the language code / ID test suite \param mt pointer to the top-level mapitest structure \return MAPITEST_SUCCESS on success, otherwise MAPITEST_ERROR */ _PUBLIC_ uint32_t module_lcid_init(struct mapitest *mt) { struct mapitest_suite *suite = NULL; suite = mapitest_suite_init(mt, "LCID", "Language code / ID operations", false); mapitest_suite_add_test(suite, "CODE2TAG", "Tests for lcid_langcode2langtag", mapitest_lcid_langcode2langtag); mapitest_suite_register(mt, suite); return MAPITEST_SUCCESS; } /** \details Initialise the mapidump test suite \param mt pointer to the top-level mapitest structure \return MAPITEST_SUCCESS on success, otherwise MAPITEST_ERROR */ _PUBLIC_ uint32_t module_mapidump_init(struct mapitest *mt) { struct mapitest_suite *suite = NULL; suite = mapitest_suite_init(mt, "MAPIDUMP", "mapidump test suite", false); mapitest_suite_add_test(suite, "SPROPVALUE", "Test dump of SPropValue", mapitest_mapidump_spropvalue); mapitest_suite_add_test(suite, "SPROPTAGARRAY", "Test dump of SPropTagArray", mapitest_mapidump_sproptagarray); mapitest_suite_add_test(suite, "SROWSET", "Test dump of SRowSet", mapitest_mapidump_srowset); mapitest_suite_add_test(suite, "PABENTRY", "Test dump of PAB Entry", mapitest_mapidump_pabentry); mapitest_suite_add_test(suite, "NOTE", "Test dump of a note message", mapitest_mapidump_note); mapitest_suite_add_test(suite, "TASK", "Test dump of a task message", mapitest_mapidump_task); mapitest_suite_add_test(suite, "CONTACT", "Test dump of a contact message", mapitest_mapidump_contact); mapitest_suite_add_test(suite, "APPOINTMENT", "Test dump of an appointment message", mapitest_mapidump_appointment); mapitest_suite_add_test(suite, "MESSAGE", "Test dump of an email message", mapitest_mapidump_message); mapitest_suite_add_test(suite, "NEWMAIL", "Test dump of a new mail notification", mapitest_mapidump_newmail); mapitest_suite_add_test(suite, "FREEBUSY", "Test dump of a free/busy event", mapitest_mapidump_freebusy); mapitest_suite_add_test(suite, "RECIPIENTS", "Test dump of a free/busy event", mapitest_mapidump_recipients); mapitest_suite_add_test(suite, "FOLDERCREATEDNOTIF", "Test dump of a folder created notification", mapitest_mapidump_foldercreated); mapitest_suite_add_test(suite, "FOLDERDELETEDNOTIF", "Test dump of a folder deleted notification", mapitest_mapidump_folderdeleted); mapitest_suite_add_test(suite, "FOLDERMOVEDNOTIF", "Test dump of a folder move notification", mapitest_mapidump_foldermoved); mapitest_suite_add_test(suite, "FOLDERCOPYNOTIF", "Test dump of a folder copy notification", mapitest_mapidump_foldercopied); mapitest_suite_add_test(suite, "MESSAGECREATEDNOTIF", "Test dump of a message created notification", mapitest_mapidump_messagecreated); mapitest_suite_add_test(suite, "MESSAGEDELETEDNOTIF", "Test dump of a message deleted notification", mapitest_mapidump_messagedeleted); mapitest_suite_add_test(suite, "MESSAGEMOVEDNOTIF", "Test dump of a message move notification", mapitest_mapidump_messagemoved); mapitest_suite_add_test(suite, "MESSAGECOPYNOTIF", "Test dump of a message copy notification", mapitest_mapidump_messagecopied); mapitest_suite_add_test(suite, "MESSAGEMODIFIEDNOTIF", "Test dump of a message modification notification", mapitest_mapidump_messagemodified); mapitest_suite_register(mt, suite); return MAPITEST_SUCCESS; } /** \details Initialise the language code / ID test suite \param mt pointer to the top-level mapitest structure \return MAPITEST_SUCCESS on success, otherwise MAPITEST_ERROR */ _PUBLIC_ uint32_t module_lzxpress_init(struct mapitest *mt) { struct mapitest_suite *suite = NULL; suite = mapitest_suite_init(mt, "LZXPRESS", "lzxpress algorithm test suite", false); mapitest_suite_add_test_flagged(suite, "VALIDATE-001", "Validate LZXPRESS implementation using sample file 001", mapitest_lzxpress_validate_test_001, ExpectedFail); mapitest_suite_register(mt, suite); return MAPITEST_SUCCESS; } openchange-2.0/utils/mapitest/modules/000077500000000000000000000000001223057412600201225ustar00rootroot00000000000000openchange-2.0/utils/mapitest/modules/mapitest.doxy000066400000000000000000000006531223057412600226610ustar00rootroot00000000000000/** \mainpage %mapitest documentation %mapitest acts as stand-alone torture test of a range of MAPI function calls. It is intended to validate the implementation of various functions, and to ensure that existing functionality does not suffer regression between releases. As a general principle, %mapitest calls should leave the system in the same state at the end as at the start - it is meant to clean up after itself. */ openchange-2.0/utils/mapitest/modules/module_errorchecks.c000066400000000000000000000175351223057412600241600ustar00rootroot00000000000000/* Stand-alone MAPI testsuite OpenChange Project - Error / sanity-check path tests Copyright (C) Brad Hards 2008 This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see . */ #include "utils/mapitest/mapitest.h" #include "utils/mapitest/proto.h" /** \file module_errorchecks.c \brief Error / sanity-check path tests \note These tests do not show how to use libmapi properly, and should not be used as a programming reference. */ /** \details Verify simplemapi.c functions This function: -# Tests the sanity checks in GetDefaultPublicFolder -# Tests the sanity checks in GetDefaultFolder \param mt pointer to the top-level mapitest structure \return true on success, otherwise false */ _PUBLIC_ bool mapitest_errorchecks_simplemapi_c(struct mapitest *mt) { enum MAPISTATUS status; mapi_object_t *obj_store = 0; mapi_object_t *obj_folder = 0; mapi_object_t *obj_message = 0; mapi_object_t tmp; uint64_t *folder = 0; uint32_t id = 0x99; uint32_t arg; // an all purpose argument... status = GetDefaultPublicFolder(obj_store, folder, id); if ( ( status != MAPI_E_INVALID_PARAMETER ) || (GetLastError() != MAPI_E_INVALID_PARAMETER) ) { mapitest_print(mt, "* %-35s: [FAILURE] - 0x%x\n", "Step 1 - MAPI_E_INVALID_PARAMETER", status); return false; } else { mapitest_print(mt, "* %-35s: [SUCCESS]\n", "Step 1 - MAPI_E_INVALID_PARAMETER"); } obj_store = &tmp; status = GetDefaultPublicFolder(obj_store, folder, id); if ( ( status != MAPI_E_NOT_FOUND ) || (GetLastError() != MAPI_E_NOT_FOUND) ) { mapitest_print(mt, "* %-35s: [FAILURE] - 0x%x\n", "Step 2 - MAPI_E_NOT_FOUND", status); return false; } else { mapitest_print(mt, "* %-35s: [SUCCESS]\n", "Step 2 - MAPI_E_NOT_FOUND"); } obj_store = 0; status = GetDefaultFolder(obj_store, folder, id); if ( ( status != MAPI_E_INVALID_PARAMETER ) || (GetLastError() != MAPI_E_INVALID_PARAMETER) ) { mapitest_print(mt, "* %-35s: [FAILURE] - 0x%x\n", "Step 3 - MAPI_E_INVALID_PARAMETER", status); return false; } else { mapitest_print(mt, "* %-35s: [SUCCESS]\n", "Step 3 - MAPI_E_INVALID_PARAMETER"); } obj_store = &tmp; obj_store->private_data = 0; status = GetDefaultFolder(obj_store, folder, id); if ( (status != MAPI_E_INVALID_PARAMETER) || (GetLastError() != MAPI_E_INVALID_PARAMETER) ) { mapitest_print(mt, "* %-35s: [FAILURE] - 0x%x\n", "Step 4 - MAPI_E_INVALID_PARAMETER", status); return false; } else { mapitest_print(mt, "* %-35s: [SUCCESS]\n", "Step 4 - MAPI_E_INVALID_PARAMETER"); } obj_store = 0; status = GetFolderItemsCount(obj_folder, 0, 0); if ( ( status != MAPI_E_INVALID_PARAMETER ) || (GetLastError() != MAPI_E_INVALID_PARAMETER) ) { mapitest_print(mt, "* %-35s: [FAILURE] - 0x%x\n", "Step 5 - MAPI_E_INVALID_PARAMETER", status); return false; } else { mapitest_print(mt, "* %-35s: [SUCCESS]\n", "Step 5 - MAPI_E_INVALID_PARAMETER"); } obj_folder = &tmp; status = GetFolderItemsCount(obj_folder, 0, 0); if ( ( status != MAPI_E_INVALID_PARAMETER ) || (GetLastError() != MAPI_E_INVALID_PARAMETER) ) { mapitest_print(mt, "* %-35s: [FAILURE] - 0x%x\n", "Step 6 - MAPI_E_INVALID_PARAMETER", status); return false; } else { mapitest_print(mt, "* %-35s: [SUCCESS]\n", "Step 6 - MAPI_E_INVALID_PARAMETER"); } status = GetFolderItemsCount(obj_folder, &arg, 0); if ( ( status != MAPI_E_INVALID_PARAMETER ) || (GetLastError() != MAPI_E_INVALID_PARAMETER) ) { mapitest_print(mt, "* %-35s: [FAILURE] - 0x%x\n", "Step 7 - MAPI_E_INVALID_PARAMETER", status); return false; } else { mapitest_print(mt, "* %-35s: [SUCCESS]\n", "Step 7 - MAPI_E_INVALID_PARAMETER"); } obj_folder = 0; /************************************************************************************** Testing AddUserPermission(mapi_object_t *obj_folder, const char *username, enum ACLRIGHTS role) */ status = AddUserPermission(obj_folder, 0, RightsNone); if ( ( status != MAPI_E_INVALID_PARAMETER ) || (GetLastError() != MAPI_E_INVALID_PARAMETER) ) { mapitest_print(mt, "* %-35s: [FAILURE] - 0x%x\n", "Step 8 - MAPI_E_INVALID_PARAMETER", status); return false; } else { mapitest_print(mt, "* %-35s: [SUCCESS]\n", "Step 8 - MAPI_E_INVALID_PARAMETER"); } obj_folder = &tmp; status = AddUserPermission(obj_folder, 0, RightsNone); if ( ( status != MAPI_E_INVALID_PARAMETER ) || (GetLastError() != MAPI_E_INVALID_PARAMETER) ) { mapitest_print(mt, "* %-35s: [FAILURE] - 0x%x\n", "Step 9 - MAPI_E_INVALID_PARAMETER", status); return false; } else { mapitest_print(mt, "* %-35s: [SUCCESS]\n", "Step 9 - MAPI_E_INVALID_PARAMETER"); } obj_folder = 0; /************************************************************************************** Testing ModifyUserPermission(mapi_object_t *obj_folder, const char *username, enum ACLRIGHTS role) */ status = ModifyUserPermission(obj_folder, 0, RightsNone); if ( ( status != MAPI_E_INVALID_PARAMETER ) || (GetLastError() != MAPI_E_INVALID_PARAMETER) ) { mapitest_print(mt, "* %-35s: [FAILURE] - 0x%x\n", "Step 10 - MAPI_E_INVALID_PARAMETER", status); return false; } else { mapitest_print(mt, "* %-35s: [SUCCESS]\n", "Step 10 - MAPI_E_INVALID_PARAMETER"); } obj_folder = &tmp; status = ModifyUserPermission(obj_folder, 0, RightsNone); if ( ( status != MAPI_E_INVALID_PARAMETER ) || (GetLastError() != MAPI_E_INVALID_PARAMETER) ) { mapitest_print(mt, "* %-35s: [FAILURE] - 0x%x\n", "Step 11 - MAPI_E_INVALID_PARAMETER", status); return false; } else { mapitest_print(mt, "* %-35s: [SUCCESS]\n", "Step 11 - MAPI_E_INVALID_PARAMETER"); } obj_folder = 0; /************************************************************************************** Testing RemoveUserPermission(mapi_object_t *obj_folder, const char *username) */ status = RemoveUserPermission(obj_folder, 0); if ( ( status != MAPI_E_INVALID_PARAMETER ) || (GetLastError() != MAPI_E_INVALID_PARAMETER) ) { mapitest_print(mt, "* %-35s: [FAILURE] - 0x%x\n", "Step 12 - MAPI_E_INVALID_PARAMETER", status); return false; } else { mapitest_print(mt, "* %-35s: [SUCCESS]\n", "Step 12 - MAPI_E_INVALID_PARAMETER"); } obj_folder = &tmp; status = RemoveUserPermission(obj_folder, 0); if ( ( status != MAPI_E_INVALID_PARAMETER ) || (GetLastError() != MAPI_E_INVALID_PARAMETER) ) { mapitest_print(mt, "* %-35s: [FAILURE] - 0x%x\n", "Step 13 - MAPI_E_INVALID_PARAMETER", status); return false; } else { mapitest_print(mt, "* %-35s: [SUCCESS]\n", "Step 13 - MAPI_E_INVALID_PARAMETER"); } obj_folder = 0; /************************************************************************************** Testing GetBestBody(mapi_object_t *obj_message, uint8_t *format) */ status = GetBestBody(obj_message, 0); if ( ( status != MAPI_E_INVALID_PARAMETER ) || (GetLastError() != MAPI_E_INVALID_PARAMETER) ) { mapitest_print(mt, "* %-35s: [FAILURE] - 0x%x\n", "Step 14 - MAPI_E_INVALID_PARAMETER", status); return false; } else { mapitest_print(mt, "* %-35s: [SUCCESS]\n", "Step 14 - MAPI_E_INVALID_PARAMETER"); } obj_message = &tmp; status = GetBestBody(obj_message, 0); if ( ( status != MAPI_E_INVALID_PARAMETER ) || (GetLastError() != MAPI_E_INVALID_PARAMETER) ) { mapitest_print(mt, "* %-35s: [FAILURE] - 0x%x\n", "Step 15 - MAPI_E_INVALID_PARAMETER", status); return false; } else { mapitest_print(mt, "* %-35s: [SUCCESS]\n", "Step 15 - MAPI_E_INVALID_PARAMETER"); } obj_message = 0; return true; } openchange-2.0/utils/mapitest/modules/module_lcid.c000066400000000000000000000044751223057412600225600ustar00rootroot00000000000000/* Stand-alone MAPI testsuite OpenChange Project - MS-LCID tests Copyright (C) Brad Hards 2009 This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see . */ #include "utils/mapitest/mapitest.h" #include "utils/mapitest/proto.h" /** \file module_lcid.c \brief Language Code checks (MS-LCID) \note This is low level (internal) checking, and application programmers do not normally need to deal with the functions checked in this test suite. */ /** \details Verify libmapi/util/lcid.c functions This function: -# exercises lcid_langcode2langtag() \param mt pointer to the top-level mapitest structure \return true on success, otherwise false */ _PUBLIC_ bool mapitest_lcid_langcode2langtag(struct mapitest *mt) { const char *locale; locale = mapi_get_locale_from_lcid(0x0409); if (strcmp(locale, "en_US") != 0) { mapitest_print(mt, "* %-35s: [FAILURE] - %s\n", "Step 1 - mismatch", locale); return false; } else { mapitest_print(mt, "* %-35s: [SUCCESS]\n", "Step 1"); } locale = mapi_get_locale_from_lcid(0x0439); if (strcmp(locale, "hi_IN") != 0) { mapitest_print(mt, "* %-35s: [FAILURE] - %s\n", "Step 2 - mismatch", locale); return false; } else { mapitest_print(mt, "* %-35s: [SUCCESS]\n", "Step 2"); } locale = mapi_get_locale_from_lcid(0x1401); if (strcmp(locale, "ar_DZ") != 0) { mapitest_print(mt, "* %-35s: [FAILURE] - %s\n", "Step 3 - mismatch", locale); return false; } else { mapitest_print(mt, "* %-35s: [SUCCESS]\n", "Step 3"); } locale = mapi_get_locale_from_lcid(0x0); if (locale != NULL) { mapitest_print(mt, "* %-35s: [FAILURE] - %s\n", "Step 4 - expected NULL", locale); return false; } else { mapitest_print(mt, "* %-35s: [SUCCESS]\n", "Step 4"); } return true; } openchange-2.0/utils/mapitest/modules/module_lzxpress.c000066400000000000000000000122721223057412600235310ustar00rootroot00000000000000/* Stand-alone MAPI testsuite OpenChange Project - LZXPRESS compression/decompression Copyright (C) Julien Kerihuel 2010 This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see . */ #include "utils/mapitest/mapitest.h" #include "utils/mapitest/proto.h" #include "gen_ndr/ndr_exchange.h" #include "libmapi/libmapi_private.h" /** \file module_lzxpress.c \brief LZXPRESS compression and decompression test suite */ _PUBLIC_ bool mapitest_lzxpress_validate_test_001(struct mapitest *mt) { bool ret = false; char *filename = NULL; DATA_BLOB blob; uint8_t *data; size_t size; struct ndr_print *ndr_print; struct ndr_pull *ndr_pull; struct ndr_push *ndr_push; struct ndr_push *ndr_comp; struct ndr_push *ndr_rgbIn; struct RPC_HEADER_EXT RPC_HEADER_EXT; struct EcDoRpcExt2 r; struct mapi2k7_request request; NTSTATUS status; enum ndr_err_code ndr_err; /* Step 1. Load Test File 001_Outlook_2007_in_ModifyRecipients_comp.dat */ filename = talloc_asprintf(mt->mem_ctx, "%s/001_Outlook_2007_in_ModifyRecipients_comp.dat", LZXPRESS_DATADIR); /* filename = talloc_asprintf(mt->mem_ctx, "%s/002_Outlook_2007_in_Tables_operations_comp.dat", LZXPRESS_DATADIR); */ data = (uint8_t *)file_load(filename, &size, 0, mt->mem_ctx); if (!data) { perror(filename); mapitest_print_retval_fmt(mt, "lzxpress_validate", "Error while loading %s", filename); talloc_free(filename); return false; } blob.data = data; blob.length = size; mapitest_print_retval_step(mt, "1", "Loading 001_Outlook_2007_in_ModifyRecipients_comp.dat", MAPI_E_SUCCESS); ndr_print = talloc_zero(mt->mem_ctx, struct ndr_print); ndr_print->print = ndr_print_debug_helper; ndr_print->depth = 1; /* Step 2. Pull 001_Outlook_2007_in_ModifyRecipients_comp.dat data */ ndr_pull = ndr_pull_init_blob(&blob, mt->mem_ctx); ndr_pull->flags |= LIBNDR_FLAG_REF_ALLOC; ndr_err = ndr_pull_EcDoRpcExt2(ndr_pull, NDR_IN, &r); talloc_free(ndr_pull); status = ndr_map_error2ntstatus(ndr_err); if (NT_STATUS_IS_OK(status)) { mapitest_print_retval_step(mt, "2", "001_Outlook_2007_in_ModifyRecipients_comp.dat", MAPI_E_SUCCESS); } else { mapitest_print_retval_step(mt, "2", "Pulling 001_Outlook_2007_in_ModifyRecipients_comp.dat", MAPI_E_CALL_FAILED); return false; } /* Step 4. Decompress data */ blob.data = talloc_memdup(mt->mem_ctx, r.in.rgbIn, r.in.cbIn); blob.length = r.in.cbIn; ndr_pull = ndr_pull_init_blob(&blob, mt->mem_ctx); ndr_set_flags(&ndr_pull->flags, LIBNDR_FLAG_NOALIGN|LIBNDR_FLAG_REF_ALLOC); ndr_err = ndr_pull_mapi2k7_request(ndr_pull, NDR_SCALARS|NDR_BUFFERS, &request); talloc_free(blob.data); talloc_free(ndr_pull); status = ndr_map_error2ntstatus(ndr_err); if (NT_STATUS_IS_OK(status)) { DEBUG(0, ("Success\n")); } /* Step 5. Recompress data */ ndr_push = ndr_push_init_ctx(mt->mem_ctx); ndr_set_flags(&ndr_push->flags, LIBNDR_FLAG_NOALIGN|LIBNDR_FLAG_REF_ALLOC); ndr_push_mapi_request(ndr_push, NDR_SCALARS|NDR_BUFFERS, request.mapi_request); ndr_comp = ndr_push_init_ctx(mt->mem_ctx); ndr_push_lzxpress_compress(ndr_comp, ndr_push); /* Recreate complete blob */ ndr_rgbIn = ndr_push_init_ctx(mt->mem_ctx); ndr_set_flags(&ndr_rgbIn->flags, LIBNDR_FLAG_NOALIGN|LIBNDR_FLAG_REF_ALLOC); RPC_HEADER_EXT.Version = 0x0000; RPC_HEADER_EXT.Flags = RHEF_Compressed|RHEF_Last; RPC_HEADER_EXT.Size = ndr_comp->offset; RPC_HEADER_EXT.SizeActual = ndr_push->offset; ndr_push_RPC_HEADER_EXT(ndr_rgbIn, NDR_SCALARS|NDR_BUFFERS, &RPC_HEADER_EXT); ndr_push_bytes(ndr_rgbIn, ndr_comp->data, ndr_comp->offset); talloc_free(ndr_comp); /* Compare Outlook and openchange rgbIn compressed blob */ DEBUG(0, ("Outlook compressed blob size = 0x%x\n", r.in.cbIn)); DEBUG(0, ("OpenChange compressed blob size = 0x%x\n", ndr_rgbIn->offset)); ret = true; { int i; int min; min = (ndr_rgbIn->offset >= r.in.cbIn) ? r.in.cbIn : ndr_rgbIn->offset; DEBUG(0, ("Comparing Outlook and OpenChange blobs on 0x%x bytes\n", min)); for (i = 0; i < min; i++) { if (r.in.rgbIn[i] != ndr_rgbIn->data[i]) { DEBUG(0, ("Bytes differs at offset 0x%x: Outlook (0x%.2x) OpenChange (0x%.2x)\n", i, r.in.rgbIn[i], ndr_rgbIn->data[i])); ret = false; } } } mapitest_print(mt, "Compressed rgbIn by Outlook\n"); mapitest_print(mt, "==============================\n"); dump_data(0, r.in.rgbIn, r.in.cbIn); mapitest_print(mt, "==============================\n"); mapitest_print(mt, "Compressed rgbIn by OpenChange\n"); mapitest_print(mt, "==============================\n"); dump_data(0, ndr_rgbIn->data, ndr_rgbIn->offset); mapitest_print(mt, "==============================\n"); talloc_free(ndr_rgbIn); return ret; } openchange-2.0/utils/mapitest/modules/module_mapidump.c000066400000000000000000001036041223057412600234530ustar00rootroot00000000000000/* Stand-alone MAPI testsuite OpenChange Project - mapidump function tests Copyright (C) Brad Hards 2009 This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see . */ #include "utils/mapitest/mapitest.h" #include "utils/mapitest/proto.h" /** \file module_mapidump.c \brief mapidump function tests \note These tests do not show how to use libmapi properly, and should not be used as a programming reference. */ /** \details Test dump using mapidump_SPropValue This function: -# Tests the mapidump_SPropValue() function \param mt pointer to the top-level mapitest structure \return true on success, otherwise false \note This currently doesn't check the results are sane, so manual inspection is required */ _PUBLIC_ bool mapitest_mapidump_spropvalue(struct mapitest *mt) { struct SPropValue propvalue; struct FILETIME ft; struct Binary_r bin; struct StringArray_r mvstr; uint32_t i; propvalue.ulPropTag = PR_GENDER; /* enum MAPITAGS */ propvalue.dwAlignPad = 0; propvalue.value.i = 3; /* union SPropValue_CTR */ mapidump_SPropValue(propvalue, "[sep]"); propvalue.ulPropTag = PR_SENSITIVITY; /* enum MAPITAGS */ propvalue.dwAlignPad = 0; propvalue.value.l = 68000; /* union SPropValue_CTR */ mapidump_SPropValue(propvalue, "[sep]"); propvalue.ulPropTag = PR_REPLY_REQUESTED; /* enum MAPITAGS */ propvalue.dwAlignPad = 0; propvalue.value.b = 1; /* union SPropValue_CTR */ mapidump_SPropValue(propvalue, "[sep]"); propvalue.ulPropTag = PidTagMemberId; /* enum MAPITAGS */ propvalue.dwAlignPad = 0; propvalue.value.d = 0x3DEADBEEFCAFE124LL; /* union SPropValue_CTR */ mapidump_SPropValue(propvalue, "[sep]"); propvalue.ulPropTag = PR_SENDER_NAME; /* enum MAPITAGS */ propvalue.dwAlignPad = 0; propvalue.value.lpszA = "Mr. The Sender"; /* union SPropValue_CTR */ mapidump_SPropValue(propvalue, "[sep]"); propvalue.ulPropTag = PR_REPORT_TAG; /* enum MAPITAGS */ propvalue.dwAlignPad = 0; bin.cb = 12; bin.lpb = talloc_array(mt->mem_ctx, uint8_t, bin.cb); for (i = 0; i < bin.cb; ++i) { bin.lpb[i] = 0xF0 + i; } propvalue.value.bin = bin; /* union SPropValue_CTR */ mapidump_SPropValue(propvalue, "[sep]"); propvalue.ulPropTag = PidTagOriginalDeliveryTime ; /* enum MAPITAGS */ propvalue.dwAlignPad = 0; ft.dwLowDateTime = 0x12345678; ft.dwHighDateTime = 0x01CA6AE4; propvalue.value.ft = ft; /* union SPropValue_CTR */ mapidump_SPropValue(propvalue, "[sep]"); propvalue.ulPropTag = PR_REPLY_TIME_ERROR; /* enum MAPITAGS */ propvalue.dwAlignPad = 0; propvalue.value.err = MAPI_E_UNKNOWN_CPID; /* union SPropValue_CTR */ mapidump_SPropValue(propvalue, "[sep]"); propvalue.ulPropTag = PidTagScheduleInfoDelegateNames; propvalue.dwAlignPad = 0; mvstr.cValues = 3; mvstr.lppszA = talloc_array(mt->mem_ctx, const char *, mvstr.cValues); mvstr.lppszA[0] = talloc_strdup(mt->mem_ctx, "Foo"); mvstr.lppszA[1] = talloc_strdup(mt->mem_ctx, "A longer string"); mvstr.lppszA[2] = talloc_strdup(mt->mem_ctx, "All strung out on bugs"); propvalue.value.MVszA = mvstr; mapidump_SPropValue(propvalue, "[sep]"); #if 0 /* Types TODO */ // int64_t dbl;/* [case(0x0005)] */ // const char *lpszW;/* [unique,charset(UTF16),case(0x001f)] */ // struct FlatUID_r *lpguid;/* [unique,case(0x0048)] */ // struct ShortArray_r MVi;/* [case(0x1002)] */ // struct LongArray_r MVl;/* [case(0x1003)] */ // struct BinaryArray_r MVbin;/* [case(0x1102)] */ // struct FlatUIDArray_r MVguid;/* [case(0x1048)] */ // struct StringArrayW_r MVszW;/* [case(0x101f)] */ // struct DateTimeArray_r MVft;/* [case(0x1040)] */ // uint32_t object;/* [case(0x000d)] */ #endif propvalue.ulPropTag = 0xDDDD << 16 | PT_LONG; /* This isn't a real tag, just a test case */ propvalue.dwAlignPad = 0; propvalue.value.l = 68020; mapidump_SPropValue(propvalue, "[sep]"); return true; } /** \details Test dump using mapidump_SPropTagArray This function: -# Tests the mapidump_SPropTagArray() function \param mt pointer to the top-level mapitest structure \return true on success, otherwise false \note This currently doesn't check the results are sane, so manual inspection is required */ _PUBLIC_ bool mapitest_mapidump_sproptagarray(struct mapitest *mt) { struct SPropTagArray *tagarray; tagarray = set_SPropTagArray(mt->mem_ctx, 5, PR_SENDER_NAME, PR_BODY, PR_PERSONAL_HOME_PAGE, PR_OTHER_ADDRESS_CITY, (0xDDDD << 16 | PT_LONG)); mapidump_SPropTagArray(tagarray); return true; } /** \details Test dump using mapidump_SRowSet This function: -# Tests the mapidump_SRowSet() function -# Indirectly tests the mapidump_SRow() function \param mt pointer to the top-level mapitest structure \return true on success, otherwise false \note This currently doesn't check the results are sane, so manual inspection is required */ _PUBLIC_ bool mapitest_mapidump_srowset(struct mapitest *mt) { struct SRowSet srowset; struct SPropValue SPropValue; srowset.cRows = 2; srowset.aRow = talloc_array(mt->mem_ctx, struct SRow, srowset.cRows); srowset.aRow[0].cValues = 0; srowset.aRow[0].lpProps = talloc_zero(mt->mem_ctx, struct SPropValue); SPropValue.ulPropTag = PR_OBJECT_TYPE; SPropValue.value.l = MAPI_MAILUSER; SRow_addprop(&(srowset.aRow[0]), SPropValue); SPropValue.ulPropTag = PR_DISPLAY_TYPE; SPropValue.value.l = 0; SRow_addprop(&(srowset.aRow[0]), SPropValue); SPropValue.ulPropTag = PR_GIVEN_NAME; SPropValue.value.lpszA = "gname"; SRow_addprop(&(srowset.aRow[0]), SPropValue); srowset.aRow[1].cValues = 0; srowset.aRow[1].lpProps = talloc_zero(mt->mem_ctx, struct SPropValue); SPropValue.ulPropTag = PR_GIVEN_NAME; SPropValue.value.lpszA = "kname"; SRow_addprop(&(srowset.aRow[1]), SPropValue); SPropValue.ulPropTag = PR_7BIT_DISPLAY_NAME; SPropValue.value.lpszA = "lname"; SRow_addprop(&(srowset.aRow[1]), SPropValue); mapidump_SRowSet(&srowset, "[sep]"); return true; } /** \details Test dump using mapidump_pabentry This function: -# Tests the mapidump_PAB_entry() function \param mt pointer to the top-level mapitest structure \return true on success, otherwise false \note This currently doesn't check the results are sane, so manual inspection is required */ _PUBLIC_ bool mapitest_mapidump_pabentry(struct mapitest *mt) { struct PropertyRow_r pabentry; struct PropertyValue_r value; pabentry.cValues = 0; pabentry.lpProps = talloc_zero(mt->mem_ctx, struct PropertyValue_r); value.ulPropTag = PR_ADDRTYPE_UNICODE; value.value.lpszA = "dummy addrtype"; PropertyRow_addprop(&(pabentry), value); value.ulPropTag = PR_DISPLAY_NAME_UNICODE; value.value.lpszA = "dummy display name"; PropertyRow_addprop(&(pabentry), value); value.ulPropTag = PR_EMAIL_ADDRESS_UNICODE; value.value.lpszA = "dummy@example.com"; PropertyRow_addprop(&(pabentry), value); value.ulPropTag = PR_ACCOUNT_UNICODE; value.value.lpszA = "dummy account"; PropertyRow_addprop(&(pabentry), value); mapidump_PAB_entry(&pabentry); return true; } /** \details Test dump using mapidump_note This function: -# Tests the mapidump_note() function on a plain text message -# Tests the mapidump_note() function on a HTML message \param mt pointer to the top-level mapitest structure \return true on success, otherwise false \note This currently doesn't check the results are sane, so manual inspection is required */ _PUBLIC_ bool mapitest_mapidump_note(struct mapitest *mt) { struct mapi_SPropValue_array props; props.cValues = 3; props.lpProps = talloc_array(mt->mem_ctx, struct mapi_SPropValue, props.cValues); props.lpProps[0].ulPropTag = PR_CONVERSATION_TOPIC; props.lpProps[0].value.lpszA = "Topic of the Note"; props.lpProps[1].ulPropTag = PR_BODY; props.lpProps[1].value.lpszA = "This is the body of the note. It has two sentences."; props.lpProps[2].ulPropTag = PR_CLIENT_SUBMIT_TIME; props.lpProps[2].value.ft.dwLowDateTime = 0x12345678; props.lpProps[2].value.ft.dwHighDateTime = 0x01CA6BE4; mapidump_note(&props, "[dummy ID]"); props.lpProps[1].ulPropTag = PR_BODY_HTML; props.lpProps[1].value.lpszA = "

Heading for the Note

\n

This is the body of the note. It has two sentences.

"; mapidump_note(&props, "[dummy ID]"); return true; } /** \details Test dump using mapidump_task This function: -# Tests the mapidump_task() function -# modifies the task to be completed -# Tests the associated get_importance() function -# Tests the associated get_task_status() function \param mt pointer to the top-level mapitest structure \return true on success, otherwise false \note This currently doesn't check the results are sane, so manual inspection is required */ _PUBLIC_ bool mapitest_mapidump_task(struct mapitest *mt) { struct mapi_SPropValue_array props; props.cValues = 9; props.lpProps = talloc_array(mt->mem_ctx, struct mapi_SPropValue, props.cValues); props.lpProps[0].ulPropTag = PR_CONVERSATION_TOPIC; props.lpProps[0].value.lpszA = "Topic of the Task"; props.lpProps[1].ulPropTag = PR_BODY; props.lpProps[1].value.lpszA = "This is the body of the task. It has two sentences."; props.lpProps[2].ulPropTag = PidLidTaskDueDate; props.lpProps[2].value.ft.dwLowDateTime = 0x12345678; props.lpProps[2].value.ft.dwHighDateTime = 0x01CA6CE4; props.lpProps[3].ulPropTag = PidLidPrivate; props.lpProps[3].value.b = 0; props.lpProps[4].ulPropTag = PR_IMPORTANCE; props.lpProps[4].value.l = IMPORTANCE_HIGH; props.lpProps[5].ulPropTag = PidLidPercentComplete; props.lpProps[5].value.dbl = 0.78; props.lpProps[6].ulPropTag = PidLidTaskStartDate; props.lpProps[6].value.ft.dwLowDateTime = 0x09876543; props.lpProps[6].value.ft.dwHighDateTime = 0x01CA6AE4; props.lpProps[7].ulPropTag = PidLidTaskStatus; props.lpProps[7].value.l = olTaskWaiting; props.lpProps[8].ulPropTag = PidLidContacts; props.lpProps[8].value.MVszA.cValues = 2; props.lpProps[8].value.MVszA.strings = talloc_array(mt->mem_ctx, struct mapi_LPSTR, 2); props.lpProps[8].value.MVszA.strings[0].lppszA = "Contact One"; props.lpProps[8].value.MVszA.strings[1].lppszA = "Contact Two Jr."; mapidump_task(&props, "[dummy ID]"); props.lpProps[7].ulPropTag = PidLidTaskStatus; props.lpProps[7].value.l = olTaskComplete; props.lpProps[3].ulPropTag = PidLidTaskDateCompleted; props.lpProps[3].value.ft.dwLowDateTime = 0x22345678; props.lpProps[3].value.ft.dwHighDateTime = 0x01CA6CB4; mapidump_task(&props, "[dummy ID]"); if (strcmp("Low", get_importance(IMPORTANCE_LOW)) != 0) { mapitest_print(mt, "* %-40s: bad result IMPORTANCE_LOW\n", "mapidump_task"); return false; } if (strcmp("Normal", get_importance(IMPORTANCE_NORMAL)) != 0) { mapitest_print(mt, "* %-40s: bad result IMPORTANCE_NORMAL\n", "mapidump_task"); return false; } if (strcmp("High", get_importance(IMPORTANCE_HIGH)) != 0) { mapitest_print(mt, "* %-40s: bad result IMPORTANCE_HIGH\n", "mapidump_task"); return false; } if (get_importance(IMPORTANCE_HIGH+1) != 0) { mapitest_print(mt, "* %-40s: bad result OUT_OF_RANGE\n", "mapidump_task"); return false; } if (strcmp("Not Started", get_task_status(olTaskNotStarted)) != 0) { mapitest_print(mt, "* %-40s: bad result olTaskNotStarted\n", "mapidump_task"); return false; } if (strcmp("In Progress", get_task_status(olTaskInProgress)) != 0) { mapitest_print(mt, "* %-40s: bad result olTaskInProgress\n", "mapidump_task"); return false; } if (strcmp("Completed", get_task_status(olTaskComplete)) != 0) { mapitest_print(mt, "* %-40s: bad result olTaskCompleted\n", "mapidump_task"); return false; } if (strcmp("Waiting on someone else", get_task_status(olTaskWaiting)) != 0) { mapitest_print(mt, "* %-40s: bad result olTaskWaiting\n", "mapidump_task"); return false; } if (strcmp("Deferred", get_task_status(olTaskDeferred)) != 0) { mapitest_print(mt, "* %-40s: bad result olTaskDeferred\n", "mapidump_task"); return false; } if (get_task_status(olTaskDeferred+1) != 0) { mapitest_print(mt, "* %-40s: bad result OUT_OF_RANGE\n", "mapidump_task"); return false; } return true; } /** \details Test dump using mapidump_contact This function: -# Tests the mapidump_contact() function \param mt pointer to the top-level mapitest structure \return true on success, otherwise false \note This currently doesn't check the results are sane, so manual inspection is required */ _PUBLIC_ bool mapitest_mapidump_contact(struct mapitest *mt) { struct mapi_SPropValue_array props; props.cValues = 8; props.lpProps = talloc_array(mt->mem_ctx, struct mapi_SPropValue, props.cValues); props.lpProps[0].ulPropTag = PR_POSTAL_ADDRESS; props.lpProps[0].value.lpszA = "P.O. Box 543, KTown"; props.lpProps[1].ulPropTag = PR_STREET_ADDRESS; props.lpProps[1].value.lpszA = "1 My Street, KTown"; props.lpProps[2].ulPropTag = PR_COMPANY_NAME; props.lpProps[2].value.lpszA = "Dummy Company Pty Ltd"; props.lpProps[3].ulPropTag = PR_TITLE; props.lpProps[3].value.lpszA = "Ms."; props.lpProps[4].ulPropTag = PR_COUNTRY; props.lpProps[4].value.lpszA = "Australia"; props.lpProps[5].ulPropTag = PR_GIVEN_NAME; props.lpProps[5].value.lpszA = "Konq."; props.lpProps[6].ulPropTag = PR_SURNAME; props.lpProps[6].value.lpszA = "Dragoon"; props.lpProps[7].ulPropTag = PR_DEPARTMENT_NAME; props.lpProps[7].value.lpszA = "Research and Marketing"; mapidump_contact(&props, "[dummy ID]"); props.lpProps[1].ulPropTag = PR_CONVERSATION_TOPIC; props.lpProps[1].value.lpszA = "Contact Topic"; mapidump_contact(&props, "[dummy ID]"); props.lpProps[0].ulPropTag = PidLidFileUnder; props.lpProps[0].value.lpszA = "Card Label"; props.lpProps[4].ulPropTag = PR_DISPLAY_NAME; props.lpProps[4].value.lpszA = "Konqi Dragon"; mapidump_contact(&props, "[dummy ID]"); return true; } /** \details Test message dump using mapidump_appointment This function: -# Tests the mapidump_appointment() function \param mt pointer to the top-level mapitest structure \return true on success, otherwise false \note This currently doesn't check the results are sane, so manual inspection is required */ _PUBLIC_ bool mapitest_mapidump_appointment(struct mapitest *mt) { struct mapi_SPropValue_array props; props.cValues = 8; props.lpProps = talloc_array(mt->mem_ctx, struct mapi_SPropValue, props.cValues); props.lpProps[0].ulPropTag = PidLidContacts; props.lpProps[0].value.MVszA.cValues = 2; props.lpProps[0].value.MVszA.strings = talloc_array(mt->mem_ctx, struct mapi_LPSTR, 2); props.lpProps[0].value.MVszA.strings[0].lppszA = "Contact One"; props.lpProps[0].value.MVszA.strings[1].lppszA = "Contact Two Jr."; props.lpProps[1].ulPropTag = PR_CONVERSATION_TOPIC; props.lpProps[1].value.lpszA = "Dummy Appointment topic"; props.lpProps[2].ulPropTag = PidLidTimeZoneDescription; props.lpProps[2].value.lpszA = "AEDT"; props.lpProps[3].ulPropTag = PidLidLocation; props.lpProps[3].value.lpszA = "OpenChange Conference Room #3"; props.lpProps[4].ulPropTag = PidLidBusyStatus; props.lpProps[4].value.l = olTaskNotStarted; props.lpProps[5].ulPropTag = PidLidPrivate; props.lpProps[5].ulPropTag = true; props.lpProps[6].ulPropTag = PR_END_DATE; props.lpProps[6].value.ft.dwLowDateTime = 0x12345678; props.lpProps[6].value.ft.dwHighDateTime = 0x01CA6CE4; props.lpProps[7].ulPropTag = PR_START_DATE; props.lpProps[7].value.ft.dwLowDateTime = 0x09876543; props.lpProps[7].value.ft.dwHighDateTime = 0x01CA6AE4; mapidump_appointment(&props, "[dummy ID]"); return true; } /** \details Test dump of an email message using mapidump_message This function: -# Builds an indicative email using mapi_SPropValues (sets no codepage) -# Calls the mapidump_appointment() function \param mt pointer to the top-level mapitest structure \return true on success, otherwise false \note This currently doesn't check the results are sane, so manual inspection is required */ _PUBLIC_ bool mapitest_mapidump_message(struct mapitest *mt) { struct mapi_SPropValue_array props; props.cValues = 9; props.lpProps = talloc_array(mt->mem_ctx, struct mapi_SPropValue, props.cValues); props.lpProps[0].ulPropTag = PR_INTERNET_MESSAGE_ID; props.lpProps[0].value.lpszA = "dummy-3535395fds@example.com"; props.lpProps[1].ulPropTag = PR_CONVERSATION_TOPIC; props.lpProps[1].value.lpszA = "Dummy Email Subject"; props.lpProps[2].ulPropTag = PR_BODY; props.lpProps[2].value.lpszA = "This is the body of the email. It has two sentences.\n"; props.lpProps[3].ulPropTag = PR_SENT_REPRESENTING_NAME; props.lpProps[3].value.lpszA = "The Sender "; props.lpProps[4].ulPropTag = PR_DISPLAY_TO; props.lpProps[4].value.lpszA = "The Recipient "; props.lpProps[5].ulPropTag = PR_DISPLAY_CC; props.lpProps[5].value.lpszA = "Other Recipient "; props.lpProps[6].ulPropTag = PR_DISPLAY_BCC; props.lpProps[6].value.lpszA = "Ms. Anonymous "; props.lpProps[7].ulPropTag = PidTagPriority; props.lpProps[7].value.l = 0; props.lpProps[8].ulPropTag = PR_HASATTACH; props.lpProps[8].value.b = false; mapidump_message(&props, "[dummy ID]", NULL); props.lpProps[7].ulPropTag = PR_MESSAGE_CODEPAGE; props.lpProps[7].value.l = CP_USASCII; mapidump_message(&props, "[dummy ID]", NULL); props.lpProps[7].ulPropTag = PR_MESSAGE_CODEPAGE; props.lpProps[7].value.l = CP_UNICODE; mapidump_message(&props, "[dummy ID]", NULL); props.lpProps[7].ulPropTag = PR_MESSAGE_CODEPAGE; props.lpProps[7].value.l = CP_JAUTODETECT; mapidump_message(&props, "[dummy ID]", NULL); props.lpProps[7].ulPropTag = PR_MESSAGE_CODEPAGE; props.lpProps[7].value.l = CP_KAUTODETECT; mapidump_message(&props, "[dummy ID]", NULL); props.lpProps[7].ulPropTag = PR_MESSAGE_CODEPAGE; props.lpProps[7].value.l = CP_ISO2022JPESC; mapidump_message(&props, "[dummy ID]", NULL); props.lpProps[7].ulPropTag = PR_MESSAGE_CODEPAGE; props.lpProps[7].value.l = CP_ISO2022JPSIO; mapidump_message(&props, "[dummy ID]", NULL); return true; } /** \details Test dump of an new mail notification This function: -# Tests the mapidump_msgflags function with no bits set -# Tests the mapidump_msgflags function with one bit set -# Tests the mapidump_msgflags function with all bits set -# Builds an indicative new mail notification -# Calls the mapidump_newmail function to test dumping of that new mail notification \param mt pointer to the top-level mapitest structure \return true on success, otherwise false \note This currently doesn't check the results are sane, so manual inspection is required */ _PUBLIC_ bool mapitest_mapidump_newmail(struct mapitest *mt) { struct NewMailNotification notif; mapidump_msgflags(0x0, "[sep]"); mapidump_msgflags(0x100, "[sep]"); mapidump_msgflags(0x1|0x2|0x4|0x8|0x10|0x20|0x40|0x80|0x100|0x200, "[sep]"); notif.FID = 0xFEDCBA9876543210LL; notif.MID = 0xBADCAFEBEEF87625LL; notif.MessageFlags = 0x20|0x2; notif.UnicodeFlag = false; notif.MessageClass.lpszA = "Dummy class"; mapidump_newmail(¬if, "[sep]"); return true; } /** \details Test dump of a free/busy event This function: -# builds a freebusy binary event -# tests dumping it using mapidump_freebusy_event() -# modifies the event, and dumps it again -# modifies the event, and dumps it again -# tests dumping a date using mapidump_freebusy_date() -# tests each months for mapidump_freebusy_month() \param mt pointer to the top-level mapitest structure \return true on success, otherwise false \note This currently doesn't check the results are sane, so manual inspection is required */ _PUBLIC_ bool mapitest_mapidump_freebusy(struct mapitest *mt) { struct Binary_r bin; bin.cb = 4; bin.lpb = talloc_array(mt->mem_ctx, uint8_t, bin.cb); /* this example from MS-OXOPFFB Section 4.4.3 */ bin.lpb[0] = 0x50; bin.lpb[1] = 0x0A; bin.lpb[2] = 0xC8; bin.lpb[3] = 0x0A; mapidump_freebusy_event(&bin, 2009*16+11, 2008, "[sep]"); /* this example adapted from MS-OXOPFFB Section 4.4.3 */ bin.lpb[0] = 0x50; bin.lpb[1] = 0x0A; bin.lpb[2] = 0xCA; bin.lpb[3] = 0x0A; mapidump_freebusy_event(&bin, 2009*16+11, 2009, "[sep]"); /* this example adapted from MS-OXOPFFB Section 4.4.3 */ bin.lpb[0] = 0x50; bin.lpb[1] = 0x0A; bin.lpb[2] = 0x80; bin.lpb[3] = 0x0A; mapidump_freebusy_event(&bin, 2009*16+11, 2009, "[sep]"); mapidump_freebusy_date(0x0CD18345, "[sep]"); if (strcmp("January", mapidump_freebusy_month(2009*16+1, 2009)) != 0) { mapitest_print(mt, "* %-40s: bad result January\n", "mapidump_freebusy"); return false; } if (strcmp("February", mapidump_freebusy_month(2009*16+2, 2009)) != 0) { mapitest_print(mt, "* %-40s: bad result February\n", "mapidump_freebusy"); return false; } if (strcmp("March", mapidump_freebusy_month(2009*16+3, 2009)) != 0) { mapitest_print(mt, "* %-40s: bad result March\n", "mapidump_freebusy"); return false; } if (strcmp("April", mapidump_freebusy_month(2009*16+4, 2009)) != 0) { mapitest_print(mt, "* %-40s: bad result April\n", "mapidump_freebusy"); return false; } if (strcmp("May", mapidump_freebusy_month(2009*16+5, 2009)) != 0) { mapitest_print(mt, "* %-40s: bad result May\n", "mapidump_freebusy"); return false; } if (strcmp("June", mapidump_freebusy_month(2009*16+6, 2009)) != 0) { mapitest_print(mt, "* %-40s: bad result June\n", "mapidump_freebusy"); return false; } if (strcmp("July", mapidump_freebusy_month(2009*16+7, 2009)) != 0) { mapitest_print(mt, "* %-40s: bad result July\n", "mapidump_freebusy"); return false; } if (strcmp("August", mapidump_freebusy_month(2009*16+8, 2009)) != 0) { mapitest_print(mt, "* %-40s: bad result August\n", "mapidump_freebusy"); return false; } if (strcmp("September", mapidump_freebusy_month(2009*16+9, 2009)) != 0) { mapitest_print(mt, "* %-40s: bad result September\n", "mapidump_freebusy"); return false; } if (strcmp("October", mapidump_freebusy_month(2009*16+10, 2009)) != 0) { mapitest_print(mt, "* %-40s: bad result October\n", "mapidump_freebusy"); return false; } if (strcmp("November", mapidump_freebusy_month(2009*16+11, 2009)) != 0) { mapitest_print(mt, "* %-40s: bad result November\n", "mapidump_freebusy"); return false; } if (strcmp("December", mapidump_freebusy_month(2009*16+12, 2009)) != 0) { mapitest_print(mt, "* %-40s: bad result December\n", "mapidump_freebusy"); return false; } if (mapidump_freebusy_month(2009*16+0, 2009) != 0) { mapitest_print(mt, "* %-40s: bad result underrange\n", "mapidump_freebusy"); return false; } if (mapidump_freebusy_month(2009*16+13, 2009) != 0) { mapitest_print(mt, "* %-40s: bad result overrange\n", "mapidump_freebusy"); return false; } return true; } /** \details Test dump of a set of recipients This function: -# builds a recipient list -# dumps out the recipient list using mapidump_Recipients() \param mt pointer to the top-level mapitest structure \return true on success, otherwise false \note This currently doesn't check the results are sane, so manual inspection is required */ _PUBLIC_ bool mapitest_mapidump_recipients(struct mapitest *mt) { const char **userlist; struct SRowSet resolved; struct PropertyTagArray_r flaglist; struct SPropValue SPropValue; userlist = talloc_array(mt->mem_ctx, const char*, 3); userlist[0] = "Mr. Unresolved"; userlist[1] = "Mr/Ms. Ambiguous"; userlist[2] = "Mrs. Resolved"; resolved.cRows = 1; resolved.aRow = talloc_array(mt->mem_ctx, struct SRow, resolved.cRows); resolved.aRow[0].cValues = 0; resolved.aRow[0].lpProps = talloc_zero(mt->mem_ctx, struct SPropValue); SPropValue.ulPropTag = PR_OBJECT_TYPE; SPropValue.value.l = MAPI_MAILUSER; SRow_addprop(&(resolved.aRow[0]), SPropValue); SPropValue.ulPropTag = PR_GIVEN_NAME; SPropValue.value.lpszA = "gname"; SRow_addprop(&(resolved.aRow[0]), SPropValue); flaglist.cValues = 3; flaglist.aulPropTag = talloc_zero_array(mt->mem_ctx, uint32_t, flaglist.cValues); flaglist.aulPropTag[0] = MAPI_UNRESOLVED; flaglist.aulPropTag[1] = MAPI_AMBIGUOUS; flaglist.aulPropTag[2] = MAPI_RESOLVED; mapidump_Recipients(userlist, &resolved, &flaglist); talloc_free(flaglist.aulPropTag); return true; } /** \details Test dump of a Folder deletion notification This function: -# Creates a FolderDeletedNotification structure -# Dumps that structure out using mapidump_folderdeleted() -# Tests mapidump_folderdeleted() with a null argument \param mt pointer to the top-level mapitest structure \return true on success, otherwise false \note This currently doesn't check the results are sane, so manual inspection is required */ _PUBLIC_ bool mapitest_mapidump_folderdeleted(struct mapitest *mt) { struct FolderDeletedNotification folderdeletednotification; folderdeletednotification.ParentFID = 0x9876CAFE432LL; folderdeletednotification.FID = 0x1234ABCDLL; mapidump_folderdeleted(&folderdeletednotification, "[sep]"); mapidump_folderdeleted(0, "[sep]"); return true; } /** \details Test dump of a folder move notification This function: -# Creates a FolderMoveCopyNotification structure -# Dumps that structure out using mapidump_foldermoved() -# Tests mapidump_foldermoved() with a null argument \param mt pointer to the top-level mapitest structure \return true on success, otherwise false \note This currently doesn't check the results are sane, so manual inspection is required */ _PUBLIC_ bool mapitest_mapidump_foldermoved(struct mapitest *mt) { struct FolderMoveCopyNotification foldermovecopynotification; foldermovecopynotification.ParentFID = 0x9876CAFE432LL; foldermovecopynotification.FID = 0x1234ABCDLL; foldermovecopynotification.OldParentFID = 0x9876CAFE43201DLL; foldermovecopynotification.OldFID = 0x1234ABCD01DLL; mapidump_foldermoved(&foldermovecopynotification, "[sep]"); mapidump_foldermoved(0, "[sep]"); return true; } /** \details Test dump of a folder copy notification This function: -# Creates a FolderMoveCopyNotification structure -# Dumps that structure out using mapidump_foldercopy() -# Tests mapidump_foldercopy() with a null argument \param mt pointer to the top-level mapitest structure \return true on success, otherwise false \note This currently doesn't check the results are sane, so manual inspection is required */ _PUBLIC_ bool mapitest_mapidump_foldercopied(struct mapitest *mt) { struct FolderMoveCopyNotification foldermovecopynotification; foldermovecopynotification.ParentFID = 0x9876CAFE432LL; foldermovecopynotification.FID = 0x1234ABCDLL; foldermovecopynotification.OldParentFID = 0x9876CAFE43201DLL; foldermovecopynotification.OldFID = 0x1234ABCD01DLL; mapidump_foldercopied(&foldermovecopynotification, "[sep]"); mapidump_foldercopied(0, "[sep]"); return true; } /** \details Test dump of a Folder creation notification This function: -# Creates a FolderCreatedNotification structure with a null tag set -# Dumps that structure out using mapidump_foldercreated() -# Adds a set of tags to the FolderCreatedNotification -# Dumps the modified FolderCreatedNotification structure using mapidump_foldercreated() -# Tests mapidump_foldercreated() with a null argument \param mt pointer to the top-level mapitest structure \return true on success, otherwise false \note This currently doesn't check the results are sane, so manual inspection is required */ _PUBLIC_ bool mapitest_mapidump_foldercreated(struct mapitest *mt) { struct FolderCreatedNotification foldercreatednotification; foldercreatednotification.ParentFID = 0x9876CAFE432LL; foldercreatednotification.FID = 0x1234ABCDLL; foldercreatednotification.NotificationTags.Tags = 0; foldercreatednotification.TagCount = 0; mapidump_foldercreated(&foldercreatednotification, "[sep]"); foldercreatednotification.TagCount = 3; foldercreatednotification.NotificationTags.Tags = talloc_array(mt->mem_ctx, enum MAPITAGS, foldercreatednotification.TagCount); foldercreatednotification.NotificationTags.Tags[0] = PidTagTemplateData; foldercreatednotification.NotificationTags.Tags[1] = PR_URL_COMP_NAME; foldercreatednotification.NotificationTags.Tags[2] = PidTagEndAttach; mapidump_foldercreated(&foldercreatednotification, "[sep]"); mapidump_foldercreated(0, "[sep]"); return true; } /** \details Test dump of a Message deletion notification This function: -# Creates a MessageDeletedNotification structure -# Dumps that structure out using mapidump_messagedeleted() -# Tests mapidump_messagedeleted() with a null argument \param mt pointer to the top-level mapitest structure \return true on success, otherwise false \note This currently doesn't check the results are sane, so manual inspection is required */ _PUBLIC_ bool mapitest_mapidump_messagedeleted(struct mapitest *mt) { struct MessageDeletedNotification messagedeletednotification; messagedeletednotification.FID = 0x1234ABCDLL; messagedeletednotification.MID = 0x9876FEALL; mapidump_messagedeleted(&messagedeletednotification, "[sep]"); mapidump_messagedeleted(0, "[sep]"); return true; } /** \details Test dump of a Message creation notification This function: -# Creates a MessageCreatedNotification structure -# Dumps that structure out using mapidump_messagecreated() -# Adds tags to the MessageCreatedNotification structure -# Dumps the structure again. -# Tests mapidump_messagecreated() with a null argument \param mt pointer to the top-level mapitest structure \return true on success, otherwise false \note This currently doesn't check the results are sane, so manual inspection is required */ _PUBLIC_ bool mapitest_mapidump_messagecreated(struct mapitest *mt) { struct MessageCreatedNotification messagecreatednotification; messagecreatednotification.FID = 0x1234ABCDLL; messagecreatednotification.MID = 0x9876FEALL; messagecreatednotification.NotificationTags.Tags = 0; messagecreatednotification.TagCount = 0; mapidump_messagecreated(&messagecreatednotification, "[sep]"); messagecreatednotification.TagCount = 3; messagecreatednotification.NotificationTags.Tags = talloc_array(mt->mem_ctx, enum MAPITAGS, messagecreatednotification.TagCount); messagecreatednotification.NotificationTags.Tags[0] = PR_DISPLAY_NAME; messagecreatednotification.NotificationTags.Tags[1] = PR_DISPLAY_NAME_UNICODE; messagecreatednotification.NotificationTags.Tags[2] = PR_COMPANY_NAME; mapidump_messagecreated(0, "[sep]"); return true; } /** \details Test dump of a Message moved notification This function: -# Creates a MessageMovedNotification structure -# Dumps that structure out using mapidump_messagemoved() -# Tests mapidump_messagemoved() with a null argument \param mt pointer to the top-level mapitest structure \return true on success, otherwise false \note This currently doesn't check the results are sane, so manual inspection is required */ _PUBLIC_ bool mapitest_mapidump_messagemoved(struct mapitest *mt) { struct MessageMoveCopyNotification messagemovednotification; messagemovednotification.FID = 0x1234ABCDLL; messagemovednotification.MID = 0x9876FEALL; messagemovednotification.OldFID = 0x1234ABCD01dLL; messagemovednotification.OldMID = 0x9876FEA01dLL; mapidump_messagemoved(&messagemovednotification, "[sep]"); mapidump_messagemoved(0, "[sep]"); return true; } /** \details Test dump of a Message copied notification This function: -# Creates a MessageCopiedNotification structure -# Dumps that structure out using mapidump_messagecopied() -# Tests mapidump_messagecopied() with a null argument \param mt pointer to the top-level mapitest structure \return true on success, otherwise false \note This currently doesn't check the results are sane, so manual inspection is required */ _PUBLIC_ bool mapitest_mapidump_messagecopied(struct mapitest *mt) { struct MessageMoveCopyNotification messagecopiednotification; messagecopiednotification.FID = 0x1234ABCDLL; messagecopiednotification.MID = 0x9876FEALL; messagecopiednotification.OldFID = 0x1234ABCD01dLL; messagecopiednotification.OldMID = 0x9876FEA01dLL; mapidump_messagecopied(&messagecopiednotification, "[sep]"); mapidump_messagecopied(0, "[sep]"); return true; } /** \details Test dump of a Message modification notification This function: -# Creates a MessageModifiedNotification structure -# Dumps that structure out using mapidump_messagemodified() -# Adds tags to the MessageModifiedNotification structure -# Dumps the structure again. -# Tests mapidump_messagemodified() with a null argument \param mt pointer to the top-level mapitest structure \return true on success, otherwise false \note This currently doesn't check the results are sane, so manual inspection is required */ _PUBLIC_ bool mapitest_mapidump_messagemodified(struct mapitest *mt) { struct MessageModifiedNotification messagemodifiednotification; messagemodifiednotification.FID = 0x1234ABCDLL; messagemodifiednotification.MID = 0x9876FEALL; messagemodifiednotification.NotificationTags.Tags = 0; messagemodifiednotification.TagCount = 0; mapidump_messagemodified(&messagemodifiednotification, "[sep]"); messagemodifiednotification.TagCount = 3; messagemodifiednotification.NotificationTags.Tags = talloc_array(mt->mem_ctx, enum MAPITAGS, messagemodifiednotification.TagCount); messagemodifiednotification.NotificationTags.Tags[0] = PR_DISPLAY_NAME; messagemodifiednotification.NotificationTags.Tags[1] = PR_DISPLAY_NAME_UNICODE; messagemodifiednotification.NotificationTags.Tags[2] = PR_COMPANY_NAME; mapidump_messagemodified(0, "[sep]"); return true; } openchange-2.0/utils/mapitest/modules/module_noserver.c000066400000000000000000001265211223057412600235050ustar00rootroot00000000000000/* Stand-alone MAPI testsuite OpenChange Project - Non connection oriented tests Copyright (C) Brad Hards 2008-2009 This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see . */ #include "utils/mapitest/mapitest.h" #include "utils/mapitest/proto.h" /** \file module_noserver.c \brief Non connection oriented tests */ /* From MS-OXRTFCP, Section 4.1.1 */ #define RTF_COMPRESSED1_HEX "2d0000002b0000004c5a4675f1c5c7a703000a007263706731323542320af32068656c090020627705b06c647d0a800fa0" #define RTF_UNCOMPRESSED1 "{\\rtf1\\ansi\\ansicpg1252\\pard hello world}\r\n" /* From MS-OXRTFCP, Section 4.1.2 */ #define RTF_COMPRESSED2_HEX "1a0000001c0000004c5a4675e2d44b51410004205758595a0d6e7d010eb0" #define RTF_UNCOMPRESSED2 "{\\rtf1 WXYZWXYZWXYZWXYZWXYZ}" /** \details Test the Compressed RTF decompression routine. This function: -# Loads some test data and checks it -# Decompresses the test data -# Checks that the decompressed data matches the expected result \param mt pointer on the top-level mapitest structure \return true on success, otherwise false */ _PUBLIC_ bool mapitest_noserver_lzfu(struct mapitest *mt) { enum MAPISTATUS retval; DATA_BLOB uncompressed1; DATA_BLOB uncompressed2; uint8_t compressed_hex[1024]; uint8_t *compressed; uint32_t compressed_length; compressed = talloc_array(mt->mem_ctx, uint8_t, 1024); memcpy(compressed_hex, RTF_COMPRESSED1_HEX, 98); compressed_length = strhex_to_str((char*)compressed, 1024, (char*)compressed_hex, 98); if (compressed_length != 49) { mapitest_print(mt, "* %-40s: uncompress RTF - Bad length\n", "LZFU"); return false; } uint32_t crc = calculateCRC(compressed, 0x10, (49-0x10)); if (crc == 0xA7C7C5F1) { mapitest_print(mt, "* CRC pass\n"); } else { mapitest_print(mt, "* CRC failure, expected 0xA7C7C5F1, but got 0x%08X\n", crc); } retval = uncompress_rtf(mt->mem_ctx, compressed, compressed_length, &uncompressed1); if (retval != MAPI_E_SUCCESS) { mapitest_print_retval(mt, "uncompress_rtf - step 1 (bad retval)"); return false; } if (sizeof(RTF_UNCOMPRESSED1) != uncompressed1.length) { mapitest_print(mt, "* %-40s: FAILED (bad length: %i vs %i)\n", "uncompress_rtf - step 1", sizeof(RTF_UNCOMPRESSED1), uncompressed1.length); return false; } if (!strncmp((char*)uncompressed1.data, RTF_UNCOMPRESSED1, uncompressed1.length)) { mapitest_print(mt, "* %-40s: PASSED\n", "uncompress_rtf - step 1"); } else { mapitest_print(mt, "* %-40s: FAILED - %s\n", "uncompress_rtf - step 1", (char*)uncompressed1.data); return false; } memcpy(compressed_hex, RTF_COMPRESSED2_HEX, 60); compressed_length = strhex_to_str((char*)compressed, 1024, (char*)compressed_hex, 60); if (compressed_length != 30) { mapitest_print(mt, "* %-40s: uncompress RTF - Bad length\n", "LZFU"); return false; } retval = uncompress_rtf(mt->mem_ctx, compressed, compressed_length, &uncompressed2); if (retval != MAPI_E_SUCCESS) { mapitest_print_retval(mt, "uncompress_rtf - step 2 (bad retval)"); return false; } if (!strncmp((char*)uncompressed2.data, RTF_UNCOMPRESSED2, uncompressed2.length)) { mapitest_print(mt, "* %-40s: PASSED\n", "uncompress_rtf - step 2"); } else { mapitest_print(mt, "* %-40s: FAILED - %s\n", "uncompress_rtf - step 2", (char*)uncompressed2.data); return false; } /* TODO: add an uncompressed test here */ return true; } /** \details Test the Compressed RTF compression routine. This function: -# Loads some test data and checks it -# Compresses the test data -# Checks that the compressed data matches the expected result \param mt pointer to the top-level mapitest structure \return true on success, otherwise false */ _PUBLIC_ bool mapitest_noserver_rtfcp(struct mapitest *mt) { enum MAPISTATUS retval; uint8_t *compressed; size_t compressed_length; char *compressed_hex; /* compress the test data */ retval = compress_rtf(mt->mem_ctx, RTF_UNCOMPRESSED1, sizeof(RTF_UNCOMPRESSED1) - 1, &compressed, &compressed_length); if (retval != MAPI_E_SUCCESS) { mapitest_print_retval(mt, "compress_rtf - step 1 (bad retval)"); return false; } /* Check the compressed result matches the compressed array */ compressed_hex = hex_encode_talloc(mt->mem_ctx, compressed, compressed_length); if (strncasecmp(compressed_hex, RTF_COMPRESSED1_HEX, (size_t)98) != 0) { mapitest_print(mt, "* %-40s: compare results RTF_COMPRESSED1 - mismatch\n", "RTFCP"); mapitest_print(mt, "- %s\n", RTF_COMPRESSED1_HEX); mapitest_print(mt, "- %s\n", compressed_hex); return false; } else { mapitest_print(mt, "* %-40s: compare results RTF_COMPRESSED1 - match\n", "RTFCP"); mapitest_print(mt, "- %s\n", RTF_COMPRESSED1_HEX); mapitest_print(mt, "- %s\n", compressed_hex); } talloc_free(compressed_hex); talloc_free(compressed); /* compress the test data */ retval = compress_rtf(mt->mem_ctx, RTF_UNCOMPRESSED2, sizeof(RTF_UNCOMPRESSED2) - 1, &compressed, &compressed_length); if (retval != MAPI_E_SUCCESS) { mapitest_print_retval(mt, "compress_rtf - step 2 (bad retval)"); return false; } // Check the compressed result matches the compressed array. compressed_hex = hex_encode_talloc(mt->mem_ctx, compressed, compressed_length); if (strncasecmp(compressed_hex, RTF_COMPRESSED2_HEX, sizeof(RTF_COMPRESSED2_HEX)) != 0) { mapitest_print(mt, "* %-40s: compare results RTF_COMPRESSED2 - mismatch\n", "RTFCP"); mapitest_print(mt, "- %s\n", RTF_COMPRESSED2_HEX); mapitest_print(mt, "- %s\n", compressed_hex); return false; } else { mapitest_print(mt, "* %-40s: compare results RTF_COMPRESSED2 - match\n", "RTFCP"); mapitest_print(mt, "- %s\n", RTF_COMPRESSED2_HEX); mapitest_print(mt, "- %s\n", compressed_hex); } talloc_free(compressed_hex); talloc_free(compressed); return true; } /** \details Test the Compressed RTF compression / decompression routines on a larger file \param mt pointer to the top-level mapitest structure \return true on success, otherwise false */ _PUBLIC_ bool mapitest_noserver_rtfcp_large(struct mapitest *mt) { enum MAPISTATUS retval; char *filename = NULL; char *original_uncompressed_data; size_t original_uncompressed_length; char *original_uncompressed_hex; uint8_t *compressed; size_t compressed_length; DATA_BLOB decompressed; char *decompressed_hex; /* load the test file */ filename = talloc_asprintf(mt->mem_ctx, "%s/testcase.rtf", LZFU_DATADIR); original_uncompressed_data = file_load(filename, &original_uncompressed_length, 0, mt->mem_ctx); if (!original_uncompressed_data) { perror(filename); mapitest_print(mt, "%s: Error while loading %s\n", __FUNCTION__, filename); talloc_free(filename); return false; } talloc_free(filename); original_uncompressed_hex = hex_encode_talloc(mt->mem_ctx, (const unsigned char*)original_uncompressed_data, original_uncompressed_length); /* compress it */ retval = compress_rtf(mt->mem_ctx, original_uncompressed_data, original_uncompressed_length, &compressed, &compressed_length); if (retval != MAPI_E_SUCCESS) { mapitest_print_retval_clean(mt, "mapitest_noserver_rtfcp_large - step 1 (bad retval)", retval); return false; } /* decompress it */ retval = uncompress_rtf(mt->mem_ctx, compressed, compressed_length, &decompressed); if (retval != MAPI_E_SUCCESS) { mapitest_print_retval_clean(mt, "mapitest_noserver_rtfcp_large - step 2 (bad retval)", retval); return false; } mapitest_print(mt, "Original data size = 0x%zx\n", original_uncompressed_length); mapitest_print(mt, "Decompressed size = 0x%zx\n", decompressed.length); { int i; int min; min = (original_uncompressed_length >= decompressed.length) ? decompressed.length : original_uncompressed_length; mapitest_print(mt, "Comparing data over 0x%x bytes\n", min); for (i = 0; i < min; i++) { if (decompressed.data[i] != original_uncompressed_data[i]) { mapitest_print(mt, "Bytes differ at offset 0x%x: original (0x%.2x) decompressed (0x%.2x)\n", i, original_uncompressed_data[i], decompressed.data[i]); } } } /* check the uncompressed version (less trailing null) matches the original test file contents */ decompressed_hex = hex_encode_talloc(mt->mem_ctx, decompressed.data, decompressed.length -1); if (strncasecmp(original_uncompressed_hex, decompressed_hex, original_uncompressed_length) != 0) { mapitest_print(mt, "* %-40s: compare results - mismatch\n", "RTFCP_LARGE"); return false; } else { mapitest_print(mt, "* %-40s: compare results - match\n", "RTFCP_LARGE"); // mapitest_print(mt, "- %s\n", original_uncompressed_hex); // mapitest_print(mt, "- %s\n", decompressed_hex); } /* clean up */ talloc_free(decompressed_hex); talloc_free(compressed); talloc_free(original_uncompressed_hex); return true; } #define SROWSET_UNTAGGED "004d542044756d6d792046726f6d00426f6479206f66206d657373616765203800004d542044756d6d792046726f6d00426f6479206f66206d657373616765203900004d542044756d6d792046726f6d00426f6479206f66206d657373616765203700004d542044756d6d792046726f6d00426f6479206f66206d657373616765203600004d542044756d6d793400426f6479206f66206d657373616765203400004d542044756d6d792046726f6d00426f6479206f66206d657373616765203500004d542044756d6d793300426f6479206f66206d657373616765203300004d542044756d6d793100426f6479206f66206d657373616765203100004d542044756d6d793200426f6479206f66206d657373616765203200004d542044756d6d793000426f6479206f66206d657373616765203000" #define SROWSET_UNTAGGED_LEN 310 static bool mapitest_noserver_srowset_untagged(struct mapitest *mt) { enum MAPISTATUS retval; struct loadparm_context *lp_ctx = NULL; DATA_BLOB rawData; uint8_t rawDataHex[1024]; struct SRowSet rowSet; struct SRowSet referenceRowSet; struct SPropTagArray *proptags; uint32_t rowNum; retval = GetLoadparmContext(mt->mapi_ctx, &lp_ctx); if (retval != MAPI_E_SUCCESS) return false; rawData.data = talloc_array(mt->mem_ctx, uint8_t, 1024); memcpy(rawDataHex, SROWSET_UNTAGGED, 2*SROWSET_UNTAGGED_LEN); rawData.length = strhex_to_str((char*)rawData.data, 1024, (char*)rawDataHex, 2*SROWSET_UNTAGGED_LEN); if (rawData.length != SROWSET_UNTAGGED_LEN) { mapitest_print(mt, "* %-40s: untagged - Bad length\n", "SRowSet"); return false; } proptags = set_SPropTagArray(mt->mem_ctx, 2, PR_SENDER_NAME, PR_BODY); rowSet.cRows = 10; rowSet.aRow = talloc_array(mt->mem_ctx, struct SRow, 10); emsmdb_get_SRowSet(mt->mem_ctx, &rowSet, proptags, &rawData); /* Check the resulting SRowSet */ if (rowSet.cRows != 10) { mapitest_print(mt, "* %-40s: unexpected row count: %i\n", "SRowSet", rowSet.cRows); return false; } /* Build reference RowSet */ referenceRowSet.cRows = rowSet.cRows; referenceRowSet.aRow = talloc_array(mt->mem_ctx, struct SRow, rowSet.cRows); for (rowNum = 0; rowNum < rowSet.cRows; ++rowNum) { referenceRowSet.aRow[rowNum].ulAdrEntryPad = 0; referenceRowSet.aRow[rowNum].cValues = 2; referenceRowSet.aRow[rowNum].lpProps = talloc_array(mt->mem_ctx, struct SPropValue, 2); referenceRowSet.aRow[rowNum].lpProps[0].ulPropTag = PR_SENDER_NAME; referenceRowSet.aRow[rowNum].lpProps[0].dwAlignPad = 0; referenceRowSet.aRow[rowNum].lpProps[1].ulPropTag = PR_BODY; referenceRowSet.aRow[rowNum].lpProps[1].dwAlignPad = 0; } referenceRowSet.aRow[0].lpProps[0].value.lpszA = "MT Dummy From"; referenceRowSet.aRow[0].lpProps[1].value.lpszA = "Body of message 8"; referenceRowSet.aRow[1].lpProps[0].value.lpszA = "MT Dummy From"; referenceRowSet.aRow[1].lpProps[1].value.lpszA = "Body of message 9"; referenceRowSet.aRow[2].lpProps[0].value.lpszA = "MT Dummy From"; referenceRowSet.aRow[2].lpProps[1].value.lpszA = "Body of message 7"; referenceRowSet.aRow[3].lpProps[0].value.lpszA = "MT Dummy From"; referenceRowSet.aRow[3].lpProps[1].value.lpszA = "Body of message 6"; referenceRowSet.aRow[4].lpProps[0].value.lpszA = "MT Dummy4"; referenceRowSet.aRow[4].lpProps[1].value.lpszA = "Body of message 4"; referenceRowSet.aRow[5].lpProps[0].value.lpszA = "MT Dummy From"; referenceRowSet.aRow[5].lpProps[1].value.lpszA = "Body of message 5"; referenceRowSet.aRow[6].lpProps[0].value.lpszA = "MT Dummy3"; referenceRowSet.aRow[6].lpProps[1].value.lpszA = "Body of message 3"; referenceRowSet.aRow[7].lpProps[0].value.lpszA = "MT Dummy1"; referenceRowSet.aRow[7].lpProps[1].value.lpszA = "Body of message 1"; referenceRowSet.aRow[8].lpProps[0].value.lpszA = "MT Dummy2"; referenceRowSet.aRow[8].lpProps[1].value.lpszA = "Body of message 2"; referenceRowSet.aRow[9].lpProps[0].value.lpszA = "MT Dummy0"; referenceRowSet.aRow[9].lpProps[1].value.lpszA = "Body of message 0"; /* compare result with reference rowset */ for (rowNum = 0; rowNum < rowSet.cRows; ++rowNum) { uint32_t i; /* check each row has expected number of properties */ if (rowSet.aRow[rowNum].cValues != referenceRowSet.aRow[rowNum].cValues) { mapitest_print(mt, "* %-40s: unexpected props count, row %i: %i\n", "SRowSet", rowSet.aRow[rowNum].cValues, rowNum); return false; } for (i=0; i < rowSet.aRow[rowNum].cValues; ++i) { /* check property tags are as expected */ if (rowSet.aRow[rowNum].lpProps[i].ulPropTag != referenceRowSet.aRow[rowNum].lpProps[i].ulPropTag) { mapitest_print(mt, "* %-40s: unexpected proptag (%i/%i): 0x%08x\n", "SRowSet", rowNum, i, rowSet.aRow[rowNum].lpProps[i].ulPropTag); return false; } /* check property values are as expected */ if (strcmp(rowSet.aRow[rowNum].lpProps[i].value.lpszA, referenceRowSet.aRow[rowNum].lpProps[i].value.lpszA) != 0) { mapitest_print(mt, "* %-40s: unexpected property value (%i/%i): %s\n", "SRowSet", rowNum, i, rowSet.aRow[rowNum].lpProps[i].value.lpszA); return false; } } } return true; } #define SROWSET_TAGGED "01004d542044756d6d792046726f6d000a0f010480004d542044756d6d792046726f6d00426f6479206f66206d657373616765203500004d542044756d6d792046726f6d00426f6479206f66206d657373616765203600004d542044756d6d792046726f6d00426f6479206f66206d657373616765203700004d542044756d6d792046726f6d00426f6479206f66206d657373616765203800004d542044756d6d792046726f6d00426f6479206f66206d65737361676520390001004d542044756d6d7930000a0f010480004d542044756d6d793000426f6479206f66206d65737361676520300001004d542044756d6d7931000a0f010480004d542044756d6d793100426f6479206f66206d65737361676520310001004d542044756d6d7932000a0f010480004d542044756d6d793200426f6479206f66206d65737361676520320001004d542044756d6d7933000a0f010480004d542044756d6d793300426f6479206f66206d65737361676520330001004d542044756d6d7934000a0f010480004d542044756d6d793400426f6479206f66206d657373616765203400" #define SROWSET_TAGGED_LEN 416 static bool mapitest_noserver_srowset_tagged(struct mapitest *mt) { enum MAPISTATUS retval; struct loadparm_context *lp_ctx = NULL; DATA_BLOB rawData; uint8_t rawDataHex[1024]; struct SRowSet rowSet; struct SRowSet referenceRowSet; struct SPropTagArray *proptags; uint32_t rowNum; retval = GetLoadparmContext(mt->mapi_ctx, &lp_ctx); if (retval != MAPI_E_SUCCESS) return false; rawData.data = talloc_array(mt->mem_ctx, uint8_t, 1024); memcpy(rawDataHex, SROWSET_TAGGED, 2*SROWSET_TAGGED_LEN); rawData.length = strhex_to_str((char*)rawData.data, 1024, (char*)rawDataHex, 2*SROWSET_TAGGED_LEN); if (rawData.length != SROWSET_TAGGED_LEN) { mapitest_print(mt, "* %-40s: tagged - Bad length\n", "SRowSet"); return false; } proptags = set_SPropTagArray(mt->mem_ctx, 2, PR_SENDER_NAME, PR_BODY); rowSet.cRows = 16; rowSet.aRow = talloc_array(mt->mem_ctx, struct SRow, 16); emsmdb_get_SRowSet(mt->mem_ctx, &rowSet, proptags, &rawData); /* Check the resulting SRowSet */ if (rowSet.cRows != 16) { mapitest_print(mt, "* %-40s: unexpected row count: %i\n", "SRowSet", rowSet.cRows); return false; } /* Build reference RowSet */ referenceRowSet.cRows = rowSet.cRows; referenceRowSet.aRow = talloc_array(mt->mem_ctx, struct SRow, rowSet.cRows); for (rowNum = 0; rowNum < rowSet.cRows; ++rowNum) { referenceRowSet.aRow[rowNum].ulAdrEntryPad = 0; referenceRowSet.aRow[rowNum].cValues = 2; referenceRowSet.aRow[rowNum].lpProps = talloc_array(mt->mem_ctx, struct SPropValue, 2); referenceRowSet.aRow[rowNum].lpProps[0].ulPropTag = PR_SENDER_NAME; referenceRowSet.aRow[rowNum].lpProps[0].dwAlignPad = 0; referenceRowSet.aRow[rowNum].lpProps[1].ulPropTag = PR_BODY; referenceRowSet.aRow[rowNum].lpProps[1].dwAlignPad = 0; } referenceRowSet.aRow[0].lpProps[0].value.lpszA = "MT Dummy From"; referenceRowSet.aRow[0].lpProps[1].ulPropTag = PR_BODY_ERROR; referenceRowSet.aRow[0].lpProps[1].value.err = MAPI_E_NOT_FOUND; referenceRowSet.aRow[1].lpProps[0].value.lpszA = "MT Dummy From"; referenceRowSet.aRow[1].lpProps[1].value.lpszA = "Body of message 5"; referenceRowSet.aRow[2].lpProps[0].value.lpszA = "MT Dummy From"; referenceRowSet.aRow[2].lpProps[1].value.lpszA = "Body of message 6"; referenceRowSet.aRow[3].lpProps[0].value.lpszA = "MT Dummy From"; referenceRowSet.aRow[3].lpProps[1].value.lpszA = "Body of message 7"; referenceRowSet.aRow[4].lpProps[0].value.lpszA = "MT Dummy From"; referenceRowSet.aRow[4].lpProps[1].value.lpszA = "Body of message 8"; referenceRowSet.aRow[5].lpProps[0].value.lpszA = "MT Dummy From"; referenceRowSet.aRow[5].lpProps[1].value.lpszA = "Body of message 9"; referenceRowSet.aRow[6].lpProps[0].value.lpszA = "MT Dummy0"; referenceRowSet.aRow[6].lpProps[1].ulPropTag = PR_BODY_ERROR; referenceRowSet.aRow[6].lpProps[1].value.err = MAPI_E_NOT_FOUND; referenceRowSet.aRow[7].lpProps[0].value.lpszA = "MT Dummy0"; referenceRowSet.aRow[7].lpProps[1].value.lpszA = "Body of message 0"; referenceRowSet.aRow[8].lpProps[0].value.lpszA = "MT Dummy1"; referenceRowSet.aRow[8].lpProps[1].ulPropTag = PR_BODY_ERROR; referenceRowSet.aRow[8].lpProps[1].value.err = MAPI_E_NOT_FOUND; referenceRowSet.aRow[9].lpProps[0].value.lpszA = "MT Dummy1"; referenceRowSet.aRow[9].lpProps[1].value.lpszA = "Body of message 1"; referenceRowSet.aRow[10].lpProps[0].value.lpszA = "MT Dummy2"; referenceRowSet.aRow[10].lpProps[1].ulPropTag = PR_BODY_ERROR; referenceRowSet.aRow[10].lpProps[1].value.err = MAPI_E_NOT_FOUND; referenceRowSet.aRow[11].lpProps[0].value.lpszA = "MT Dummy2"; referenceRowSet.aRow[11].lpProps[1].value.lpszA = "Body of message 2"; referenceRowSet.aRow[12].lpProps[0].value.lpszA = "MT Dummy3"; referenceRowSet.aRow[12].lpProps[1].ulPropTag = PR_BODY_ERROR; referenceRowSet.aRow[12].lpProps[1].value.err = MAPI_E_NOT_FOUND; referenceRowSet.aRow[13].lpProps[0].value.lpszA = "MT Dummy3"; referenceRowSet.aRow[13].lpProps[1].value.lpszA = "Body of message 3"; referenceRowSet.aRow[14].lpProps[0].value.lpszA = "MT Dummy4"; referenceRowSet.aRow[14].lpProps[1].ulPropTag = PR_BODY_ERROR; referenceRowSet.aRow[14].lpProps[1].value.err = MAPI_E_NOT_FOUND; referenceRowSet.aRow[15].lpProps[0].value.lpszA = "MT Dummy4"; referenceRowSet.aRow[15].lpProps[1].value.lpszA = "Body of message 4"; /* compare result with reference rowset */ for (rowNum = 0; rowNum < rowSet.cRows; ++rowNum) { uint32_t i; /* check each row has expected number of properties */ if (rowSet.aRow[rowNum].cValues != referenceRowSet.aRow[rowNum].cValues) { mapitest_print(mt, "* %-40s: unexpected props count, row %i: %i\n", "SRowSet", rowSet.aRow[rowNum].cValues, rowNum); return false; } for (i=0; i < rowSet.aRow[rowNum].cValues; ++i) { /* check property tags are as expected */ if (rowSet.aRow[rowNum].lpProps[i].ulPropTag != referenceRowSet.aRow[rowNum].lpProps[i].ulPropTag) { mapitest_print(mt, "* %-40s: unexpected proptag (%i/%i): 0x%08x\n", "SRowSet", rowNum, i, rowSet.aRow[rowNum].lpProps[i].ulPropTag); return false; } /* check property values are as expected */ if ((rowSet.aRow[rowNum].lpProps[i].ulPropTag & 0xFFFF) == PT_ERROR) { if (rowSet.aRow[rowNum].lpProps[i].value.err != referenceRowSet.aRow[rowNum].lpProps[i].value.err) { mapitest_print(mt, "* %-40s: unexpected property error value (%i/%i): 0x%04x\n", "SRowSet", rowNum, i, rowSet.aRow[rowNum].lpProps[i].value.err); return false; } } else { if (strcmp(rowSet.aRow[rowNum].lpProps[i].value.lpszA, referenceRowSet.aRow[rowNum].lpProps[i].value.lpszA) != 0) { mapitest_print(mt, "* %-40s: unexpected property value (%i/%i): %s\n", "SRowSet", rowNum, i, rowSet.aRow[rowNum].lpProps[i].value.lpszA); return false; } } } } return true; } /** \details Test the SRowSet parsing / assembly code This function: -# Loads some test data and checks it -# Parses the test data -# Checks that the parsed data matches the expected result \param mt pointer on the top-level mapitest structure \return true on success, otherwise false */ _PUBLIC_ bool mapitest_noserver_srowset(struct mapitest *mt) { bool result; result = mapitest_noserver_srowset_untagged(mt); if (result == false) { /* failure */ mapitest_print(mt, "* %-40s: [FAILURE]\n", "SRowSet Untagged"); return false; } mapitest_print(mt, "* %-40s: [SUCCESS]\n", "SRowSet Untagged"); result = mapitest_noserver_srowset_tagged(mt); if (result == false) { /* failure */ mapitest_print(mt, "* %-40s: [FAILURE]\n", "SRowSet Tagged"); return false; } mapitest_print(mt, "* %-40s: [SUCCESS]\n", "SRowSet Tagged"); return true; } static bool mapitest_no_server_props_i2(struct mapitest *mt) { struct SPropValue propvalue; uint16_t i2 = 0x5693; /* just a random, not zero value */ const uint16_t *i2get; set_SPropValue_proptag(&propvalue, PT_SHORT, &i2); i2get = (const uint16_t*)get_SPropValue_data(&propvalue); if (!i2get || (*i2get != i2)) { /* failure */ mapitest_print(mt, "* %-40s: [FAILURE]\n", "SPropValue get/set with PT_SHORT"); return false; } mapitest_print(mt, "* %-40s: [SUCCESS]\n", "SPropValue get/set with PT_SHORT"); return true; } static bool mapitest_no_server_props_i4(struct mapitest *mt) { struct SPropValue propvalue; uint32_t i4 = 0x33870911; const uint32_t *i4get; set_SPropValue_proptag(&propvalue, PT_LONG, &i4); i4get = (const uint32_t*)get_SPropValue_data(&propvalue); if (!i4get || (*i4get != i4)) { /* failure */ mapitest_print(mt, "* %-40s: [FAILURE]\n", "SPropValue get/set with PT_LONG"); return false; } mapitest_print(mt, "* %-40s: [SUCCESS]\n", "SPropValue get/set with PT_LONG"); return true; } static bool mapitest_no_server_props_i8(struct mapitest *mt) { struct SPropValue propvalue; uint64_t i8 = 0x098763aa; const uint64_t *i8get; set_SPropValue_proptag(&propvalue, PT_I8, &i8); i8get = (const uint64_t*)get_SPropValue_data(&propvalue); if (!i8get || (*i8get != i8)) { /* failure */ mapitest_print(mt, "* %-40s: [FAILURE]\n", "SPropValue get/set with PT_I8"); return false; } mapitest_print(mt, "* %-40s: [SUCCESS]\n", "SPropValue get/set with PT_I8"); return true; } static bool mapitest_no_server_props_bool(struct mapitest *mt) { struct SPropValue propvalue; bool b = false; const bool *boolget; set_SPropValue_proptag(&propvalue, PT_BOOLEAN, &b); boolget = (const bool*)get_SPropValue_data(&propvalue); if (!boolget || (*boolget != b)) { /* failure */ mapitest_print(mt, "* %-40s: [FAILURE]\n", "SPropValue get/set with PT_BOOLEAN"); return false; } mapitest_print(mt, "* %-40s: [SUCCESS]\n", "SPropValue get/set with PT_BOOLEAN"); return true; } static bool mapitest_no_server_props_err(struct mapitest *mt) { struct SPropValue propvalue; enum MAPISTATUS err = MAPI_E_NOT_ME; enum MAPISTATUS *errget; set_SPropValue_proptag(&propvalue, PT_ERROR, &err); errget = (enum MAPISTATUS*)get_SPropValue_data(&propvalue); if (!errget || (*errget != err)) { /* failure */ mapitest_print(mt, "* %-40s: [FAILURE]\n", "SPropValue get/set with PT_ERROR"); return false; } mapitest_print(mt, "* %-40s: [SUCCESS]\n", "SPropValue get/set with PT_ERROR"); return true; } /* this seems strange... */ static bool mapitest_no_server_props_null(struct mapitest *mt) { struct SPropValue propvalue; uint32_t nullval = 0; const uint32_t *nullget; set_SPropValue_proptag(&propvalue, PT_NULL, &nullval); nullget = (const uint32_t*)get_SPropValue_data(&propvalue); if (!nullget) { printf("null nullget\n"); } if (!nullget || (*nullget != nullval)) { /* failure */ mapitest_print(mt, "* %-40s: [FAILURE]\n", "SPropValue get/set with PT_NULL"); return false; } mapitest_print(mt, "* %-40s: [SUCCESS]\n", "SPropValue get/set with PT_NULL"); return true; } static bool mapitest_no_server_props_string8(struct mapitest *mt) { struct SPropValue propvalue; char *string = "OpenChange Project"; const char **stringget; set_SPropValue_proptag(&propvalue, PT_STRING8, &string); stringget = (const char**)get_SPropValue_data(&propvalue); if (!stringget || (strncmp(*stringget, string, strlen(*stringget)) != 0)) { /* failure */ mapitest_print(mt, "* %-40s: [FAILURE]\n", "SPropValue get/set with PT_STRING8"); return false; } mapitest_print(mt, "* %-40s: [SUCCESS]\n", "SPropValue get/set with PT_STRING8"); return true; } static bool mapitest_no_server_props_unicode(struct mapitest *mt) { struct SPropValue propvalue; char *string = "OpenChange Project"; /* OK, so it probably isn't valid UTF16.. */ const char **stringget; set_SPropValue_proptag(&propvalue, PT_UNICODE, &string); stringget = (const char**)get_SPropValue_data(&propvalue); if (!stringget || (strncmp(*stringget, string, strlen(*stringget)) != 0)) { /* failure */ mapitest_print(mt, "* %-40s: [FAILURE]\n", "SPropValue get/set with PT_UNICODE"); return false; } mapitest_print(mt, "* %-40s: [SUCCESS]\n", "SPropValue get/set with PT_UNICODE"); return true; } static bool mapitest_no_server_props_filetime(struct mapitest *mt) { struct SPropValue propvalue; struct FILETIME ft; const struct FILETIME *ftget; ft.dwLowDateTime = 0x12345678; ft.dwHighDateTime = 0x87653491; set_SPropValue_proptag(&propvalue, PT_SYSTIME, &ft); ftget = (const struct FILETIME *)get_SPropValue_data(&propvalue); if (!ftget || (ft.dwLowDateTime != ftget->dwLowDateTime) || (ft.dwHighDateTime != ftget->dwHighDateTime)) { /* failure */ mapitest_print(mt, "* %-40s: [FAILURE]\n", "SPropValue get/set with PT_SYSTIME"); return false; } mapitest_print(mt, "* %-40s: [SUCCESS]\n", "SPropValue get/set with PT_SYSTIME"); return true; } #if 0 static bool mapitest_no_server_props_flatuid(struct mapitest *mt) { bool res; struct SPropValue propvalue; struct FlatUID_r uid; const struct FlatUID_r *uidget; int i; // initialise uid for (i = 0; i < 16; ++i) { uid.ab[i] = 0x40 + i; } printf("uid:"); for (i = 0; i < 16; ++i) { printf("%c", uid.ab[i]); } printf("\n"); res = set_SPropValue_proptag(&propvalue, PT_CLSID, &uid); if (res == false) { /* failure */ mapitest_print(mt, "* %-40s: [FAILURE]\n", "SPropValue set with PT_CLSID"); return false; } uidget = (const struct FlatUID_r*)get_SPropValue_data(&propvalue); if (!uidget) { printf("null uidget\n"); return false; } printf("uidget:"); for (i = 0; i < 16; ++i) { printf("%c", uidget->ab[i]); } printf("\n"); if (!uidget || (memcmp(uid.ab, uidget->ab, 16))) { /* failure */ mapitest_print(mt, "* %-40s: [FAILURE]\n", "SPropValue get/set with PT_CLSID"); return false; } mapitest_print(mt, "* %-40s: [SUCCESS]\n", "SPropValue get/set with PT_CLSID"); return true; } #endif static bool mapitest_no_server_props_bin(struct mapitest *mt) { bool res; struct SPropValue propvalue; struct Binary_r bin; const struct Binary_r *binget; uint32_t i; // initialise bin bin.cb = 8; bin.lpb = talloc_array(mt->mem_ctx, uint8_t, bin.cb); for (i = 0; i < bin.cb; ++i) { bin.lpb[i] = 0xF0 + i; } res = set_SPropValue_proptag(&propvalue, PT_BINARY, &bin); if (res == false) { /* failure */ mapitest_print(mt, "* %-40s: [FAILURE]\n", "SPropValue set with PT_BINARY"); return false; } binget = (const struct Binary_r *)get_SPropValue_data(&propvalue); if (!binget || (bin.cb != binget->cb) || (bin.lpb != binget->lpb)) { /* failure */ mapitest_print(mt, "* %-40s: [FAILURE]\n", "SPropValue get/set with PT_BINARY"); return false; } mapitest_print(mt, "* %-40s: [SUCCESS]\n", "SPropValue get/set with PT_BINARY"); talloc_free(bin.lpb); return true; } static bool mapitest_no_server_props_mv_i2(struct mapitest *mt) { bool res; struct SPropValue propvalue; struct ShortArray_r shortarray; const struct ShortArray_r *shortarrayget; // create and initialise shortarray shortarray.cValues = 3; shortarray.lpi = talloc_array(mt->mem_ctx, uint16_t, shortarray.cValues); shortarray.lpi[0] = 0x1245; shortarray.lpi[1] = 0x3498; shortarray.lpi[2] = 0x5675; res = set_SPropValue_proptag(&propvalue, PT_MV_SHORT, &shortarray); if (res == false) { /* failure */ mapitest_print(mt, "* %-40s: [FAILURE]\n", "SPropValue set with PT_MV_SHORT"); return false; } shortarrayget = (const struct ShortArray_r *)get_SPropValue_data(&propvalue); if (!shortarrayget || (shortarray.cValues != shortarrayget->cValues) || (shortarray.lpi != shortarrayget->lpi)) { /* failure */ mapitest_print(mt, "* %-40s: [FAILURE]\n", "SPropValue get/set with PT_MV_SHORT"); return false; } mapitest_print(mt, "* %-40s: [SUCCESS]\n", "SPropValue get/set with PT_MV_SHORT"); talloc_free(shortarray.lpi); return true; } static bool mapitest_no_server_props_mv_i4(struct mapitest *mt) { bool res; struct SPropValue propvalue; struct LongArray_r longarray; const struct LongArray_r *longarrayget; // create and initialise longarray longarray.cValues = 2; longarray.lpl = talloc_array(mt->mem_ctx, uint32_t, longarray.cValues); longarray.lpl[0] = 0x34124543; longarray.lpl[1] = 0x88567576; res = set_SPropValue_proptag(&propvalue, PT_MV_LONG, &longarray); if (res == false) { /* failure */ mapitest_print(mt, "* %-40s: [FAILURE]\n", "SPropValue set with PT_MV_LONG"); return false; } longarrayget = (const struct LongArray_r *)get_SPropValue_data(&propvalue); if (!longarrayget || (longarray.cValues != longarrayget->cValues) || (longarray.lpl != longarrayget->lpl)) { /* failure */ mapitest_print(mt, "* %-40s: [FAILURE]\n", "SPropValue get/set with PT_MV_LONG"); return false; } mapitest_print(mt, "* %-40s: [SUCCESS]\n", "SPropValue get/set with PT_MV_LONG"); talloc_free(longarray.lpl); return true; } static bool mapitest_no_server_props_mv_bin(struct mapitest *mt) { bool res; struct SPropValue propvalue; struct BinaryArray_r binarray; const struct BinaryArray_r *binarrayget; // create and initialise binarray struct Binary_r bin1, bin2; uint32_t i; // initialise bin bin1.cb = 8; bin1.lpb = talloc_array(mt->mem_ctx, uint8_t, bin1.cb); for (i = 0; i < bin1.cb; ++i) { bin1.lpb[i] = 0xC0 + i; } bin2.cb = 12; bin2.lpb = talloc_array(mt->mem_ctx, uint8_t, bin2.cb); for (i = 0; i < bin2.cb; ++i) { bin2.lpb[i] = 0xA0 + i; } binarray.cValues = 2; binarray.lpbin = talloc_array(mt->mem_ctx, struct Binary_r, binarray.cValues); binarray.lpbin[0] = bin1; binarray.lpbin[1] = bin2; res = set_SPropValue_proptag(&propvalue, PT_MV_BINARY, &binarray); if (res == false) { /* failure */ mapitest_print(mt, "* %-40s: [FAILURE]\n", "SPropValue set with PT_MV_BINARY"); return false; } binarrayget = (const struct BinaryArray_r *)get_SPropValue_data(&propvalue); if (!binarrayget || (binarray.cValues != binarrayget->cValues) || (binarray.lpbin != binarrayget->lpbin)) { /* failure */ mapitest_print(mt, "* %-40s: [FAILURE]\n", "SPropValue get/set with PT_MV_BINARY"); return false; } mapitest_print(mt, "* %-40s: [SUCCESS]\n", "SPropValue get/set with PT_MV_BINARY"); talloc_free(binarray.lpbin); talloc_free(bin1.lpb); talloc_free(bin2.lpb); return true; } static bool mapitest_no_server_props_mv_string8(struct mapitest *mt) { bool res; struct SPropValue propvalue; struct StringArray_r stringarray; const struct StringArray_r *stringarrayget; // create and initialise stringarray stringarray.cValues = 4; stringarray.lppszA = talloc_array(mt->mem_ctx, const char*, stringarray.cValues); stringarray.lppszA[0] = "Fedora"; stringarray.lppszA[1] = "FreeBSD"; stringarray.lppszA[2] = "OpenSolaris"; stringarray.lppszA[3] = "Debian"; res = set_SPropValue_proptag(&propvalue, PT_MV_STRING8, &stringarray); if (res == false) { /* failure */ mapitest_print(mt, "* %-40s: [FAILURE]\n", "SPropValue set with PT_MV_STRING8"); return false; } stringarrayget = (const struct StringArray_r *)get_SPropValue_data(&propvalue); if (!stringarrayget || (stringarray.cValues != stringarrayget->cValues) || (stringarray.lppszA != stringarrayget->lppszA)) { /* failure */ mapitest_print(mt, "* %-40s: [FAILURE]\n", "SPropValue get/set with PT_MV_STRING8"); return false; } mapitest_print(mt, "* %-40s: [SUCCESS]\n", "SPropValue get/set with PT_MV_STRING8"); talloc_free(stringarray.lppszA); return true; } static bool mapitest_no_server_props_mv_unicode(struct mapitest *mt) { bool res; struct SPropValue propvalue; struct StringArrayW_r unicodearray; const struct StringArrayW_r *unicodearrayget; // create and initialise unicodearray unicodearray.cValues = 4; unicodearray.lppszW = talloc_array(mt->mem_ctx, const char*, unicodearray.cValues); unicodearray.lppszW[0] = "Fedora"; /* not valid UTF16, but should still be OK */ unicodearray.lppszW[1] = "FreeBSD"; unicodearray.lppszW[2] = "OpenSolaris"; unicodearray.lppszW[3] = "Debian"; res = set_SPropValue_proptag(&propvalue, PT_MV_UNICODE, &unicodearray); if (res == false) { /* failure */ mapitest_print(mt, "* %-40s: [FAILURE]\n", "SPropValue set with PT_MV_UNICODE"); return false; } unicodearrayget = (const struct StringArrayW_r *)get_SPropValue_data(&propvalue); if (!unicodearrayget || (unicodearray.cValues != unicodearrayget->cValues) || (unicodearray.lppszW != unicodearrayget->lppszW)) { /* failure */ mapitest_print(mt, "* %-40s: [FAILURE]\n", "SPropValue get/set with PT_MV_UNICODE"); return false; } mapitest_print(mt, "* %-40s: [SUCCESS]\n", "SPropValue get/set with PT_MV_UNICODE"); talloc_free(unicodearray.lppszW); return true; } static bool mapitest_no_server_props_mv_filetime(struct mapitest *mt) { struct SPropValue propvalue; struct FILETIME ft1, ft2, ft3; struct DateTimeArray_r ftarray; const struct DateTimeArray_r *ftarrayget; ft1.dwLowDateTime = 0x12345678; ft1.dwHighDateTime = 0x87653491; ft2.dwLowDateTime = 0x10234324; ft2.dwHighDateTime = 0x98748756; ft3.dwLowDateTime = 0x53245324; ft3.dwHighDateTime = 0x54324633; ftarray.cValues = 3; ftarray.lpft = talloc_array(mt->mem_ctx, struct FILETIME, ftarray.cValues); ftarray.lpft[0] = ft1; ftarray.lpft[1] = ft2; ftarray.lpft[2] = ft3; set_SPropValue_proptag(&propvalue, PT_MV_SYSTIME, &ftarray); ftarrayget = (const struct DateTimeArray_r *)get_SPropValue_data(&propvalue); if (!ftarrayget || (ftarray.cValues != ftarrayget->cValues) || (ftarray.lpft != ftarrayget->lpft)) { /* failure */ mapitest_print(mt, "* %-40s: [FAILURE]\n", "SPropValue get/set with PT_MV_SYSTIME"); return false; } mapitest_print(mt, "* %-40s: [SUCCESS]\n", "SPropValue get/set with PT_MV_SYSTIME"); talloc_free(ftarray.lpft); return true; } /** \details Test the property setter / getter code This function: -# Checks setting / getting on an SPropValue \param mt pointer on the top-level mapitest structure \return true on success, otherwise false */ _PUBLIC_ bool mapitest_noserver_properties(struct mapitest *mt) { if (! mapitest_no_server_props_i2(mt)) { return false; } if (! mapitest_no_server_props_i4(mt)) { return false; } if (! mapitest_no_server_props_i8(mt)) { return false; } if (! mapitest_no_server_props_bool(mt)) { return false; } if (! mapitest_no_server_props_err(mt)) { return false; } if (! mapitest_no_server_props_null(mt)) { return false; } if (! mapitest_no_server_props_string8(mt)) { return false; } if (! mapitest_no_server_props_unicode(mt)) { return false; } if (! mapitest_no_server_props_filetime(mt)) { return false; } #if 0 if (! mapitest_no_server_props_flatuid(mt)) { return false; } #endif if (! mapitest_no_server_props_bin(mt)) { return false; } if (! mapitest_no_server_props_mv_i2(mt)) { return false; } if (! mapitest_no_server_props_mv_i4(mt)) { return false; } if (! mapitest_no_server_props_mv_string8(mt)) { return false; } if (! mapitest_no_server_props_mv_unicode(mt)) { return false; } if (! mapitest_no_server_props_mv_filetime(mt)) { return false; } if (! mapitest_no_server_props_mv_bin(mt)) { return false; } /* Types we don't test yet: */ // should this be a double_t? // int64_t dbl;/* [case(0x0005)] */ // struct FlatUID_r *lpguid;/* [unique,case(0x0048)] */ // struct FlatUIDArray_r MVguid;/* [case(0x1048)] */ // uint32_t object;/* [case(0x000d)] */ return true; } /** \details Test the mapi_SPropValue_array handling This function: -# Builds a mapi_SPropValue_array -# Checks that appropriate values can be retrieved \param mt pointer on the top-level mapitest structure \return true on success, otherwise false */ _PUBLIC_ bool mapitest_noserver_mapi_properties(struct mapitest *mt) { struct mapi_SPropValue_array valarray; const uint16_t *i2get; const uint32_t *i4get; const uint32_t *i8get; const uint8_t *boolget; const char *stringget; const struct FILETIME *ftget; const struct SBinary_short *binget; const struct mapi_MV_LONG_STRUCT *mvi4get; valarray.cValues = 8; valarray.lpProps = talloc_array(mt->mem_ctx, struct mapi_SPropValue, valarray.cValues); valarray.lpProps[0].ulPropTag = PR_GENDER; valarray.lpProps[0].value.i = 0x0001; /* Female */ valarray.lpProps[1].ulPropTag = PR_ORIGINAL_SENSITIVITY; valarray.lpProps[1].value.l = 0x00000002; /* Private */ valarray.lpProps[2].ulPropTag = PR_ALTERNATE_RECIPIENT_ALLOWED; valarray.lpProps[2].value.b = false; valarray.lpProps[3].ulPropTag = PR_CONVERSATION_TOPIC; valarray.lpProps[3].value.lpszA = "Elizabeth's Birthday"; valarray.lpProps[4].ulPropTag = PR_MESSAGE_SIZE_EXTENDED; valarray.lpProps[4].value.d = 43857; valarray.lpProps[5].ulPropTag = PR_RECORD_KEY; valarray.lpProps[5].value.bin.cb = 4; valarray.lpProps[5].value.bin.lpb = talloc_array(mt->mem_ctx, uint8_t, 4); valarray.lpProps[5].value.bin.lpb[0] = 0x44; valarray.lpProps[5].value.bin.lpb[1] = 0x00; valarray.lpProps[5].value.bin.lpb[2] = 0x20; valarray.lpProps[5].value.bin.lpb[3] = 0x00; valarray.lpProps[6].ulPropTag = PR_SCHDINFO_MONTHS_BUSY; valarray.lpProps[6].value.MVl.cValues = 2; valarray.lpProps[6].value.MVl.lpl = talloc_array(mt->mem_ctx, uint32_t, 2); valarray.lpProps[6].value.MVl.lpl[0] = 32130; valarray.lpProps[6].value.MVl.lpl[1] = 32131; valarray.lpProps[7].ulPropTag = PidLidAppointmentEndWhole; valarray.lpProps[7].value.ft.dwLowDateTime = 0x12975909; valarray.lpProps[7].value.ft.dwHighDateTime = 0x98989204; /* now start pulling the values back out */ i2get = find_mapi_SPropValue_data(&valarray, PR_GENDER); if (!i2get || (*i2get != 0x0001)) { /* failure */ mapitest_print(mt, "* %-40s: [FAILURE]\n", "mapi_SPropValue find with PT_SHORT"); return false; } mapitest_print(mt, "* %-40s: [SUCCESS]\n", "mapi_SPropValue find with PT_SHORT"); i4get = find_mapi_SPropValue_data(&valarray, PR_ORIGINAL_SENSITIVITY); if (!i4get || (*i4get != 0x00000002)) { /* failure */ mapitest_print(mt, "* %-40s: [FAILURE]\n", "mapi_SPropValue find with PT_LONG"); return false; } mapitest_print(mt, "* %-40s: [SUCCESS]\n", "mapi_SPropValue find with PT_LONG"); i8get = find_mapi_SPropValue_data(&valarray, PR_MESSAGE_SIZE_EXTENDED); if (!i8get || (*i8get != 43857)) { /* failure */ mapitest_print(mt, "* %-40s: [FAILURE]\n", "mapi_SPropValue find with PT_I8"); return false; } mapitest_print(mt, "* %-40s: [SUCCESS]\n", "mapi_SPropValue find with PT_I8"); boolget = find_mapi_SPropValue_data(&valarray, PR_ALTERNATE_RECIPIENT_ALLOWED); if (!boolget || (*boolget != false)) { /* failure */ mapitest_print(mt, "* %-40s: [FAILURE]\n", "mapi_SPropValue find with PT_BOOLEAN"); return false; } mapitest_print(mt, "* %-40s: [SUCCESS]\n", "mapi_SPropValue find with PT_BOOLEAN"); stringget = find_mapi_SPropValue_data(&valarray, PR_CONVERSATION_TOPIC); if (!stringget || (strcmp(stringget, "Elizabeth's Birthday") !=0 )) { /* failure */ mapitest_print(mt, "* %-40s: [FAILURE]\n", "mapi_SPropValue find with PT_STRING"); return false; } mapitest_print(mt, "* %-40s: [SUCCESS]\n", "mapi_SPropValue find with PT_STRING"); ftget = find_mapi_SPropValue_data(&valarray, PidLidAppointmentEndWhole); if (!ftget || (ftget->dwLowDateTime != 0x12975909) || (ftget->dwHighDateTime != 0x98989204)) { /* failure */ mapitest_print(mt, "* %-40s: [FAILURE]\n", "mapi_SPropValue find with PT_FILETIME"); return false; } mapitest_print(mt, "* %-40s: [SUCCESS]\n", "mapi_SPropValue find with PT_FILETIME"); binget = find_mapi_SPropValue_data(&valarray, PR_RECORD_KEY); if (!binget || (binget->cb != 4 ) || (binget->lpb[0] != 0x44) || (binget->lpb[1] != 0x00) || (binget->lpb[2] != 0x20) || (binget->lpb[3] != 0x00)) { /* failure */ mapitest_print(mt, "* %-40s: [FAILURE]\n", "mapi_SPropValue find with PT_BINARY"); return false; } mapitest_print(mt, "* %-40s: [SUCCESS]\n", "mapi_SPropValue find with PT_BINARY"); mvi4get = find_mapi_SPropValue_data(&valarray, PR_SCHDINFO_MONTHS_BUSY); if (!mvi4get || (mvi4get->cValues != 2 ) || (mvi4get->lpl[0] != 32130) || (mvi4get->lpl[1] != 32131)) { /* failure */ mapitest_print(mt, "* %-40s: [FAILURE]\n", "mapi_SPropValue find with PT_MV_LONG"); return false; } mapitest_print(mt, "* %-40s: [SUCCESS]\n", "mapi_SPropValue find with PT_MV_LONG"); #if 0 // Types to still to test: int64_t dbl;/* [case(0x0005)] */ uint32_t err;/* [case(0x000a)] */ const char * lpszW;/* [flag(LIBNDR_FLAG_STR_NULLTERM),case(0x001f)] */ struct GUID lpguid;/* [case(0x0048)] */ struct mapi_SRestriction_wrap Restrictions;/* [case(0x00fd)] */ struct RuleAction RuleAction;/* [case(0x00fe)] */ struct mapi_SLPSTRArray MVszA;/* [case(0x101e)] */ struct mapi_SPLSTRArrayW MVszW;/* [case(0x101f)] */ struct mapi_SGuidArray MVguid;/* [case(0x1048)] */ struct mapi_SBinaryArray MVbin;/* [case(0x1102)] */ #endif return true; } /** \details Test the get_proptag_value() function This function: -# Checks the first value in the list -# Checks a random value from the list -# Checks the last value in the list -# Checks a value that doesn't exist \param mt pointer on the top-level mapitest structure \return true on success, otherwise false */ _PUBLIC_ bool mapitest_noserver_proptagvalue(struct mapitest *mt) { uint32_t proptag; proptag = get_proptag_value("PidTagTemplateData"); if (proptag != PidTagTemplateData) { mapitest_print(mt, "* %-40s: [FAILURE]\n", "get_proptag_value with PidTagTemplateData"); return false; } proptag = get_proptag_value("PidTagDelegatedByRule"); if (proptag != PidTagDelegatedByRule) { mapitest_print(mt, "* %-40s: [FAILURE]\n", "get_proptag_value with PidTagDelegatedByRule"); return false; } proptag = get_proptag_value("PidTagAddressBookContainerId_Error"); if (proptag != PidTagAddressBookContainerId_Error) { mapitest_print(mt, "* %-40s: [FAILURE]\n", "get_proptag_value with PidTagAddressBookContainerId_Error"); return false; } proptag = get_proptag_value("No such tag, ok?"); if (proptag != 0) { mapitest_print(mt, "* %-40s: [FAILURE]\n", "get_proptag_value with non-existent tag"); return false; } return true; } openchange-2.0/utils/mapitest/modules/module_nspi.c000066400000000000000000000772541223057412600226230ustar00rootroot00000000000000/* Stand-alone MAPI testsuite OpenChange Project - NSPI tests Copyright (C) Julien Kerihuel 2008 This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see . */ #include "utils/mapitest/mapitest.h" #include "utils/mapitest/proto.h" /** \file module_nspi.c \brief NSPI tests */ /** \details Test the NspiUpdateStat RPC operation (0x02) \param mt pointer on the top-level mapitest structure \return true on success, otherwise false */ _PUBLIC_ bool mapitest_nspi_UpdateStat(struct mapitest *mt) { TALLOC_CTX *mem_ctx; enum MAPISTATUS retval; struct nspi_context *nspi_ctx; uint32_t plDelta = 1; struct PropertyRowSet_r *RowSet; mem_ctx = talloc_named(NULL, 0, "mapitest_nspi_UpdateStat"); nspi_ctx = (struct nspi_context *) mt->session->nspi->ctx; RowSet = talloc_zero(mem_ctx, struct PropertyRowSet_r); retval = nspi_GetSpecialTable(nspi_ctx, mem_ctx, 0x2, &RowSet); MAPIFreeBuffer(RowSet); if (retval != MAPI_E_SUCCESS) { talloc_free(mem_ctx); return false; } retval = nspi_UpdateStat(nspi_ctx, mem_ctx, &plDelta); mapitest_print_retval(mt, "NspiUpdateStat"); if (retval != MAPI_E_SUCCESS) { talloc_free(mem_ctx); return false; } mapitest_print(mt, "* %-35s: %d\n", "plDelta", plDelta); talloc_free(mem_ctx); return true; } /** \details Test the NspiQueryRows RPC operation (0x3) \param mt pointer on the top-level mapitest structure \return true on success, otherwise false */ _PUBLIC_ bool mapitest_nspi_QueryRows(struct mapitest *mt) { TALLOC_CTX *mem_ctx; enum MAPISTATUS retval; struct nspi_context *nspi_ctx; struct PropertyTagArray_r *MIds; struct PropertyRowSet_r *RowSet; struct SPropTagArray *SPropTagArray; struct PropertyValue_r *lpProp; struct Restriction_r Filter; mem_ctx = talloc_named(NULL, 0, "mapitest_nspi_QueryRows"); nspi_ctx = (struct nspi_context *) mt->session->nspi->ctx; /* Build the array of columns we want to retrieve */ SPropTagArray = set_SPropTagArray(mem_ctx, 0x2, PR_DISPLAY_NAME, PR_DISPLAY_TYPE); /* Build the restriction we want for NspiGetMatches */ lpProp = talloc_zero(mem_ctx, struct PropertyValue_r); lpProp->ulPropTag = PR_ACCOUNT; lpProp->dwAlignPad = 0; lpProp->value.lpszA = mt->mapi_ctx->session->profile->username; Filter.rt = RES_PROPERTY; Filter.res.resProperty.relop = RES_PROPERTY; Filter.res.resProperty.ulPropTag = PR_ACCOUNT; Filter.res.resProperty.lpProp = lpProp; RowSet = talloc_zero(mem_ctx, struct PropertyRowSet_r); MIds = talloc_zero(mem_ctx, struct PropertyTagArray_r); retval = nspi_GetMatches(nspi_ctx, mem_ctx, SPropTagArray, &Filter, 5000, &RowSet, &MIds); MAPIFreeBuffer(lpProp); MAPIFreeBuffer(RowSet); MAPIFreeBuffer(SPropTagArray); mapitest_print_retval_clean(mt, "NspiGetMatches", retval); if (retval != MAPI_E_SUCCESS) { MAPIFreeBuffer(MIds); talloc_free(mem_ctx); return false; } /* Query the rows */ RowSet = talloc_zero(mem_ctx, struct PropertyRowSet_r); retval = nspi_QueryRows(nspi_ctx, mem_ctx, NULL, MIds, 1, &RowSet); MAPIFreeBuffer(RowSet); mapitest_print_retval_clean(mt, "NspiQueryRows", retval); if (retval != MAPI_E_SUCCESS) { MAPIFreeBuffer(MIds); talloc_free(mem_ctx); return false; } talloc_free(mem_ctx); return true; } /** \details Test the NspiSeekEntries RPC operation (0x04) \param mt pointer on the top-level mapitest structure \return true on success, otherwise false */ _PUBLIC_ bool mapitest_nspi_SeekEntries(struct mapitest *mt) { TALLOC_CTX *mem_ctx; enum MAPISTATUS retval; struct nspi_context *nspi_ctx; struct PropertyValue_r pTarget; struct SPropTagArray *pPropTags; struct PropertyRowSet_r *RowSet; struct emsmdb_context *emsmdb; bool ret = true; mem_ctx = talloc_named(NULL, 0, "mapitest_nspi_SeekEntries"); nspi_ctx = (struct nspi_context *) mt->session->nspi->ctx; emsmdb = (struct emsmdb_context *) mt->session->emsmdb->ctx; RowSet = talloc_zero(mem_ctx, struct PropertyRowSet_r); pTarget.ulPropTag = PR_DISPLAY_NAME; pTarget.dwAlignPad = 0x0; pTarget.value.lpszA = emsmdb->info.szDisplayName; pPropTags = set_SPropTagArray(mem_ctx, 0x1, PR_ACCOUNT); retval = nspi_SeekEntries(nspi_ctx, mem_ctx, SortTypeDisplayName, &pTarget, pPropTags, NULL, &RowSet); if (retval != MAPI_E_SUCCESS) { ret = false; } mapitest_print_retval_clean(mt, "NspiSeekEntries", retval); MAPIFreeBuffer(RowSet); MAPIFreeBuffer(pPropTags); RowSet = talloc_zero(mem_ctx, struct PropertyRowSet_r); pTarget.ulPropTag = PR_DISPLAY_NAME_UNICODE; pTarget.dwAlignPad = 0x0; pTarget.value.lpszA = emsmdb->info.szDisplayName; pPropTags = set_SPropTagArray(mem_ctx, 0x1, PR_ACCOUNT); retval = nspi_SeekEntries(nspi_ctx, mem_ctx, SortTypeDisplayName, &pTarget, pPropTags, NULL, &RowSet); if (retval != MAPI_E_SUCCESS) { ret = false; } mapitest_print_retval_clean(mt, "NspiSeekEntries", retval); MAPIFreeBuffer(RowSet); MAPIFreeBuffer(pPropTags); talloc_free(mem_ctx); return ret; } /** \details Test the NspiGetMatches RPC operation (0x5) \param mt pointer on the top-level mapitest structure \return true on success, otherwise false */ _PUBLIC_ bool mapitest_nspi_GetMatches(struct mapitest *mt) { TALLOC_CTX *mem_ctx; enum MAPISTATUS retval; struct nspi_context *nspi_ctx; struct PropertyTagArray_r *MIds; struct PropertyRowSet_r *RowSet; struct SPropTagArray *SPropTagArray; struct PropertyValue_r *lpProp; struct Restriction_r Filter; bool ret = true; mem_ctx = talloc_named(NULL, 0, "mapitest_nspi_GetMatches"); nspi_ctx = (struct nspi_context *) mt->session->nspi->ctx; /* Build the array of columns we want to retrieve */ SPropTagArray = set_SPropTagArray(mem_ctx, 0x2, PR_DISPLAY_NAME, PR_DISPLAY_TYPE); /* Build the restriction we want for NspiGetMatches */ lpProp = talloc_zero(mem_ctx, struct PropertyValue_r); lpProp->ulPropTag = PR_ACCOUNT; lpProp->dwAlignPad = 0; lpProp->value.lpszA = mt->mapi_ctx->session->profile->username; Filter.rt = RES_PROPERTY; Filter.res.resProperty.relop = RES_PROPERTY; Filter.res.resProperty.ulPropTag = PR_ACCOUNT; Filter.res.resProperty.lpProp = lpProp; RowSet = talloc_zero(mem_ctx, struct PropertyRowSet_r); MIds = talloc_zero(mem_ctx, struct PropertyTagArray_r); retval = nspi_GetMatches(nspi_ctx, mem_ctx, SPropTagArray, &Filter, 5000, &RowSet, &MIds); MAPIFreeBuffer(lpProp); MAPIFreeBuffer(RowSet); MAPIFreeBuffer(SPropTagArray); MAPIFreeBuffer(MIds); mapitest_print_retval_clean(mt, "NspiGetMatches", retval); if (retval != MAPI_E_SUCCESS) { ret = false; } talloc_free(mem_ctx); return ret; } /** \details Test the NspiResortRestriction RPC operation (0x6) \param mt pointer on the top-level mapitest structure \return true on success, otherwise false */ _PUBLIC_ bool mapitest_nspi_ResortRestriction(struct mapitest *mt) { TALLOC_CTX *mem_ctx; enum MAPISTATUS retval; struct nspi_context *nspi_ctx; struct Restriction_r Filter; struct PropertyRowSet_r *RowSet = NULL; struct SPropTagArray *SPropTagArray = NULL; struct PropertyValue_r *lpProp = NULL; struct PropertyTagArray_r *MIds = NULL; struct PropertyTagArray_r *ppMIds = NULL; bool ret = true; mem_ctx = talloc_named(NULL, 0, "mapitest_nspi_ResortRestriction"); nspi_ctx = (struct nspi_context *) mt->session->nspi->ctx; /* Build the array of columns we want to retrieve */ SPropTagArray = set_SPropTagArray(mem_ctx, 0xb, PR_DISPLAY_NAME, PR_OFFICE_TELEPHONE_NUMBER, PR_OFFICE_LOCATION, PR_TITLE, PR_COMPANY_NAME, PR_ACCOUNT, PR_ADDRTYPE, PR_ENTRYID, PR_DISPLAY_TYPE, PR_INSTANCE_KEY, PR_EMAIL_ADDRESS ); /* Build the restriction we want for NspiGetMatches */ lpProp = talloc_zero(mem_ctx, struct PropertyValue_r); lpProp->ulPropTag = PR_OBJECT_TYPE; lpProp->dwAlignPad = 0; lpProp->value.l = 6; Filter.rt = RES_PROPERTY; Filter.res.resProperty.relop = RES_PROPERTY; Filter.res.resProperty.ulPropTag = PR_OBJECT_TYPE; Filter.res.resProperty.lpProp = lpProp; RowSet = talloc_zero(mem_ctx, struct PropertyRowSet_r); MIds = talloc_zero(mem_ctx, struct PropertyTagArray_r); retval = nspi_GetMatches(nspi_ctx, mem_ctx, SPropTagArray, &Filter, 5000, &RowSet, &MIds); MAPIFreeBuffer(lpProp); MAPIFreeBuffer(SPropTagArray); MAPIFreeBuffer(RowSet); mapitest_print_retval_clean(mt, "NspiGetMatches", retval); if (retval != MAPI_E_SUCCESS) { MAPIFreeBuffer(MIds); talloc_free(mem_ctx); return false; } ppMIds = talloc_zero(mem_ctx, struct PropertyTagArray_r); retval = nspi_ResortRestriction(nspi_ctx, mem_ctx, SortTypeDisplayName, MIds, &ppMIds); mapitest_print_retval_clean(mt, "NspiResortRestriction", retval); if (retval != MAPI_E_SUCCESS) { ret = false; } MAPIFreeBuffer(MIds); MAPIFreeBuffer(ppMIds); talloc_free(mem_ctx); return ret; } /** \details Test the NspiDNToMId RPC operation (0x7) \param mt pointer on the top-level mapitest structure \return true on success, otherwise false */ _PUBLIC_ bool mapitest_nspi_DNToMId(struct mapitest *mt) { TALLOC_CTX *mem_ctx; enum MAPISTATUS retval; struct nspi_context *nspi_ctx; struct StringsArray_r pNames; struct PropertyTagArray_r *MId; mem_ctx = talloc_named(NULL, 0, "mapitest_nspi_DNToMId"); nspi_ctx = (struct nspi_context *) mt->session->nspi->ctx; pNames.Count = 0x1; pNames.Strings = (const char **) talloc_array(mem_ctx, char *, 1); pNames.Strings[0] = mt->mapi_ctx->session->profile->homemdb; MId = talloc_zero(mem_ctx, struct PropertyTagArray_r); retval = nspi_DNToMId(nspi_ctx, mem_ctx, &pNames, &MId); MAPIFreeBuffer((char **)pNames.Strings); MAPIFreeBuffer(MId); talloc_free(mem_ctx); mapitest_print_retval_clean(mt, "NspiDNToMId", retval); if (retval == MAPI_E_SUCCESS) { return true; } else { return false; } } /** \details Test the NspiGetPropList RPC operation (0x08) \param mt pointer on the top-level mapitest structure \return true on success, otherwise false */ _PUBLIC_ bool mapitest_nspi_GetPropList(struct mapitest *mt) { TALLOC_CTX *mem_ctx; enum MAPISTATUS retval; struct nspi_context *nspi_ctx; struct SPropTagArray *pPropTags = 0; struct PropertyTagArray_r *MIds; struct PropertyValue_r *lpProp; struct Restriction_r Filter; struct SPropTagArray *SPropTagArray; struct PropertyRowSet_r *RowSet; mem_ctx = talloc_named(NULL, 0, "mapitest_nspi_GetPropList"); nspi_ctx = (struct nspi_context *) mt->session->nspi->ctx; /* Step 1. Query for current profile username */ SPropTagArray = set_SPropTagArray(mem_ctx, 0x1, PR_DISPLAY_NAME); lpProp = talloc_zero(mem_ctx, struct PropertyValue_r); lpProp->ulPropTag = PR_ANR_UNICODE; lpProp->dwAlignPad = 0; lpProp->value.lpszW = mt->mapi_ctx->session->profile->username; Filter.rt = RES_PROPERTY; Filter.res.resProperty.relop = RES_PROPERTY; Filter.res.resProperty.ulPropTag = PR_ANR_UNICODE; Filter.res.resProperty.lpProp = lpProp; RowSet = talloc_zero(mem_ctx, struct PropertyRowSet_r); MIds = talloc_zero(mem_ctx, struct PropertyTagArray_r); retval = nspi_GetMatches(nspi_ctx, mem_ctx, SPropTagArray, &Filter, 5000, &RowSet, &MIds); MAPIFreeBuffer(SPropTagArray); MAPIFreeBuffer(lpProp); MAPIFreeBuffer(RowSet); if (retval != MAPI_E_SUCCESS) { MAPIFreeBuffer(MIds); talloc_free(mem_ctx); return retval; } /* Step 2. Call NspiGetPropList using the MId returned by NspiGetMatches */ pPropTags = talloc_zero(mt->mem_ctx, struct SPropTagArray); retval = nspi_GetPropList(nspi_ctx, mem_ctx, 0, MIds->aulPropTag[0], &pPropTags); MAPIFreeBuffer(MIds); mapitest_print_retval(mt, "NspiGetPropList"); if (retval != MAPI_E_SUCCESS) { MAPIFreeBuffer(pPropTags); talloc_free(mem_ctx); return false; } if (pPropTags) { mapitest_print(mt, "* %-35s: %d\n", "Properties number", pPropTags->cValues); MAPIFreeBuffer(pPropTags); } talloc_free(mem_ctx); return true; } /** \details Test the NspiGetProps RPC operation (0x09) \param mt pointer to the top-level mapitest structure \return true on success, otherwise false */ _PUBLIC_ bool mapitest_nspi_GetProps(struct mapitest *mt) { TALLOC_CTX *mem_ctx; enum MAPISTATUS retval; struct nspi_context *nspi_ctx; struct StringsArray_r pNames; struct PropertyTagArray_r *MId; struct SPropTagArray *SPropTagArray; struct PropertyRowSet_r *RowSet; mem_ctx = talloc_named(NULL, 0, "mapitest_nspi_GetProps"); nspi_ctx = (struct nspi_context *) mt->session->nspi->ctx; pNames.Count = 0x1; pNames.Strings = (const char **) talloc_array(mem_ctx, char *, 1); pNames.Strings[0] = mt->mapi_ctx->session->profile->homemdb; MId = talloc_zero(mem_ctx, struct PropertyTagArray_r); retval = nspi_DNToMId(nspi_ctx, mem_ctx, &pNames, &MId); MAPIFreeBuffer((char **)pNames.Strings); mapitest_print_retval(mt, "NspiDNToMId"); if (retval != MAPI_E_SUCCESS) { MAPIFreeBuffer(MId); talloc_free(mem_ctx); return false; } RowSet = talloc_zero(mem_ctx, struct PropertyRowSet_r); SPropTagArray = set_SPropTagArray(mem_ctx, 0x1, PR_EMS_AB_NETWORK_ADDRESS); retval = nspi_GetProps(nspi_ctx, mem_ctx, SPropTagArray, MId, &RowSet); mapitest_print_retval_clean(mt, "NspiGetProps", retval); MAPIFreeBuffer(SPropTagArray); MAPIFreeBuffer(MId); MAPIFreeBuffer(RowSet); talloc_free(mem_ctx); if (retval == MAPI_E_SUCCESS) { return true; } else { return false; } } /** \details Test the NspiCompareMIds RPC operation (0x0a) \param mt pointer to the top-level mapitest structure \return true on success, otherwise false */ _PUBLIC_ bool mapitest_nspi_CompareMIds(struct mapitest *mt) { TALLOC_CTX *mem_ctx; enum MAPISTATUS retval; struct nspi_context *nspi_ctx; uint32_t plResult; struct PropertyTagArray_r *MIds; struct PropertyRowSet_r *RowSet; struct SPropTagArray *SPropTagArray; struct PropertyValue_r *lpProp; struct Restriction_r Filter; mem_ctx = talloc_named(NULL, 0, "mapitest_nspi_CompareMIds"); nspi_ctx = (struct nspi_context *) mt->session->nspi->ctx; /* Build the array of columns we want to retrieve */ SPropTagArray = set_SPropTagArray(mem_ctx, 0x1, PR_DISPLAY_NAME); /* Build the restriction we want for NspiGetMatches */ lpProp = talloc_zero(mem_ctx, struct PropertyValue_r); lpProp->ulPropTag = PR_OBJECT_TYPE; lpProp->dwAlignPad = 0; lpProp->value.l = 6; Filter.rt = RES_PROPERTY; Filter.res.resProperty.relop = RES_PROPERTY; Filter.res.resProperty.ulPropTag = PR_OBJECT_TYPE; Filter.res.resProperty.lpProp = lpProp; RowSet = talloc_zero(mem_ctx, struct PropertyRowSet_r); MIds = talloc_zero(mem_ctx, struct PropertyTagArray_r); retval = nspi_GetMatches(nspi_ctx, mem_ctx, SPropTagArray, &Filter, 5000, &RowSet, &MIds); MAPIFreeBuffer(lpProp); MAPIFreeBuffer(SPropTagArray); MAPIFreeBuffer(RowSet); mapitest_print_retval_clean(mt, "NspiGetMatches", retval); if (retval != MAPI_E_SUCCESS) { MAPIFreeBuffer(MIds); talloc_free(mem_ctx); return false; } /* Ensure we have at least two result to compare */ if (MIds->cValues < 2) { mapitest_print(mt, "* Only one result found, can't compare\n"); MAPIFreeBuffer(MIds); talloc_free(mem_ctx); return false; } retval = nspi_CompareMIds(nspi_ctx, mem_ctx, MIds->aulPropTag[0], MIds->aulPropTag[1], &plResult); mapitest_print_retval_clean(mt, "NspiCompareMIds", retval); MAPIFreeBuffer(MIds); if (retval != MAPI_E_SUCCESS) { talloc_free(mem_ctx); return false; } mapitest_print(mt, "* %-35s: %d\n", "value of the comparison", plResult); talloc_free(mem_ctx); return true; } /** \details Test the NspiModProps RPC operation (0xb) \param mt pointer on the top-level mapitest structure \return true on success, otherwise false */ _PUBLIC_ bool mapitest_nspi_ModProps(struct mapitest *mt) { TALLOC_CTX *mem_ctx; enum MAPISTATUS retval; struct nspi_context *nspi_ctx; struct PropertyRow_r *pRow; struct SPropTagArray *pPropTags; struct PropertyValue_r modProp; struct PropertyTagArray_r *MIds; struct PropertyRowSet_r *RowSet; struct SPropTagArray *SPropTagArray; struct PropertyValue_r *lpProp; struct Restriction_r Filter; const char *original_office_location; bool ret = true; mem_ctx = talloc_named(NULL, 0, "mapitest_nspi_ModProps"); nspi_ctx = (struct nspi_context *) mt->session->nspi->ctx; /* Build the array of columns we want to retrieve */ SPropTagArray = set_SPropTagArray(mem_ctx, 0x2, PR_DISPLAY_NAME, PR_DISPLAY_TYPE); /* Build the restriction we want for NspiGetMatches */ lpProp = talloc_zero(mem_ctx, struct PropertyValue_r); lpProp->ulPropTag = PR_ACCOUNT; lpProp->dwAlignPad = 0; lpProp->value.lpszA = mt->mapi_ctx->session->profile->username; Filter.rt = RES_PROPERTY; Filter.res.resProperty.relop = RES_PROPERTY; Filter.res.resProperty.ulPropTag = PR_ACCOUNT; Filter.res.resProperty.lpProp = lpProp; RowSet = talloc_zero(mem_ctx, struct PropertyRowSet_r); MIds = talloc_zero(mem_ctx, struct PropertyTagArray_r); retval = nspi_GetMatches(nspi_ctx, mem_ctx, SPropTagArray, &Filter, 5000, &RowSet, &MIds); MAPIFreeBuffer(lpProp); MAPIFreeBuffer(RowSet); MAPIFreeBuffer(SPropTagArray); mapitest_print_retval_clean(mt, "nspi_GetMatches", retval); if (retval != MAPI_E_SUCCESS) { MAPIFreeBuffer(MIds); talloc_free(mem_ctx); return false; } /* Query the rows */ RowSet = talloc_zero(mem_ctx, struct PropertyRowSet_r); retval = nspi_QueryRows(nspi_ctx, mem_ctx, NULL, MIds, 1, &RowSet); mapitest_print_retval_clean(mt, "nspi_QueryRows", retval); if (retval != MAPI_E_SUCCESS) { MAPIFreeBuffer(MIds); MAPIFreeBuffer(RowSet); talloc_free(mem_ctx); return false; } if (RowSet->cRows != 1) { mapitest_print(mem_ctx, "unexpected number of rows: %i\n", RowSet->cRows); MAPIFreeBuffer(MIds); MAPIFreeBuffer(RowSet); talloc_free(mem_ctx); return false; } original_office_location = (const char *)find_PropertyValue_data(&(RowSet->aRow[0]), PR_OFFICE_LOCATION); mapitest_print(mt, "original PR_OFFICE_LOCATION value: %s\n", original_office_location); /* Build the SRow and SPropTagArray for NspiModProps */ pRow = talloc_zero(mem_ctx, struct PropertyRow_r); modProp.ulPropTag = PR_OFFICE_LOCATION; modProp.value.lpszA = "MT office location"; PropertyRow_addprop(pRow, modProp); pPropTags = set_SPropTagArray(mem_ctx, 0x1, PR_OFFICE_LOCATION); retval = nspi_ModProps(nspi_ctx, mem_ctx, MIds->aulPropTag[0], pPropTags, pRow); mapitest_print_retval_clean(mt, "nspi_ModProps", retval); MAPIFreeBuffer(pRow); if (retval != MAPI_E_SUCCESS) { MAPIFreeBuffer(MIds); MAPIFreeBuffer(pPropTags); talloc_free(mem_ctx); return false; } /* Check that the property was set correctly */ RowSet = talloc_zero(mem_ctx, struct PropertyRowSet_r); retval = nspi_QueryRows(nspi_ctx, mem_ctx, NULL, MIds, 1, &RowSet); mapitest_print_retval_clean(mt, "nspi_QueryRows", retval); if (retval != MAPI_E_SUCCESS) { MAPIFreeBuffer(MIds); MAPIFreeBuffer(RowSet); talloc_free(mem_ctx); return false; } if (RowSet->cRows != 1) { mapitest_print(mem_ctx, "unexpected number of rows: %i\n", RowSet->cRows); MAPIFreeBuffer(MIds); MAPIFreeBuffer(RowSet); talloc_free(mem_ctx); return false; } if (strcmp((const char *)find_PropertyValue_data(&(RowSet->aRow[0]), PR_OFFICE_LOCATION), "MT office location") != 0) { mapitest_print(mt, "PR_OFFICE_LOCATION string value mismatch: %s", (const char *)find_PropertyValue_data(&(RowSet->aRow[0]), PR_OFFICE_LOCATION)); ret = false; } else { mapitest_print(mt, "correctly set PR_OFFICE_LOCATION\n"); } /* try to reset the office location back to the original value */ pRow = talloc_zero(mem_ctx, struct PropertyRow_r); modProp.ulPropTag = PR_OFFICE_LOCATION; modProp.value.lpszA = original_office_location; PropertyRow_addprop(pRow, modProp); retval = nspi_ModProps(nspi_ctx, mem_ctx, MIds->aulPropTag[0], pPropTags, pRow); mapitest_print_retval_clean(mt, "nspi_ModProps (reset original value)", retval); if (retval != MAPI_E_SUCCESS) { ret = false; } MAPIFreeBuffer(MIds); MAPIFreeBuffer(pPropTags); MAPIFreeBuffer(pRow); talloc_free(mem_ctx); return ret; } /** \details Test the NspiGetSpecialTable RPC operation (0x0c) \param mt pointer on the top-level mapitest structure \return true on success, otherwise false */ _PUBLIC_ bool mapitest_nspi_GetSpecialTable(struct mapitest *mt) { TALLOC_CTX *mem_ctx; enum MAPISTATUS retval; struct nspi_context *nspi_ctx; struct PropertyRowSet_r *RowSet; mem_ctx = talloc_named(NULL, 0, "mapitest_nspi_GetSpecialTable"); nspi_ctx = (struct nspi_context *) mt->session->nspi->ctx; RowSet = talloc_zero(mem_ctx, struct PropertyRowSet_r); retval = nspi_GetSpecialTable(nspi_ctx, mem_ctx, 0x0, &RowSet); MAPIFreeBuffer(RowSet); mapitest_print_retval_clean(mt, "NspiGetSpecialTable (Hierarchy Table)", retval); if (retval != MAPI_E_SUCCESS) { talloc_free(mem_ctx); return false; } RowSet = talloc_zero(mt->mem_ctx, struct PropertyRowSet_r); retval = nspi_GetSpecialTable(nspi_ctx, mem_ctx, 0x2, &RowSet); MAPIFreeBuffer(RowSet); mapitest_print_retval_clean(mt, "NspiGetSpecialTable (Address Creation Template)", retval); talloc_free(mem_ctx); if (retval == MAPI_E_SUCCESS) { return true; } else { return false; } } /** \details Test the NspiGetTemplateInfo RPC operation (0x0d) \param mt pointer on the top-level mapitest structure \return true on success, otherwise false */ _PUBLIC_ bool mapitest_nspi_GetTemplateInfo(struct mapitest *mt) { TALLOC_CTX *mem_ctx; enum MAPISTATUS retval; struct nspi_context *nspi_ctx; struct PropertyRow_r *ppData = NULL; mem_ctx = talloc_named(NULL, 0, "mapitest_nspi_GetTemplateInfo"); nspi_ctx = (struct nspi_context *) mt->session->nspi->ctx; ppData = talloc_zero(mem_ctx, struct PropertyRow_r); retval = nspi_GetTemplateInfo(nspi_ctx, mem_ctx, TI_TEMPLATE|TI_SCRIPT|TI_EMT|TI_HELPFILE_NAME|TI_HELPFILE_CONTENTS, 0, NULL, &ppData); mapitest_print_retval_clean(mt, "NspiGetTemplateInfo", retval); MAPIFreeBuffer(ppData); talloc_free(mem_ctx); if (retval == MAPI_E_SUCCESS) { return true; } else { return false; } } /** \details Test the NspiModLinkAtt RPC operation (0x0e) \param mt pointer on the top-level mapitest structure \return true on success, otherwise false */ _PUBLIC_ bool mapitest_nspi_ModLinkAtt(struct mapitest *mt) { enum MAPISTATUS retval; struct nspi_context *nspi_ctx; /* struct SPropTagArray *MIds; */ struct BinaryArray_r *lpEntryIds; nspi_ctx = (struct nspi_context *) mt->session->nspi->ctx; lpEntryIds = talloc_zero(mt->mem_ctx, struct BinaryArray_r); lpEntryIds->cValues = 0; lpEntryIds->lpbin = NULL; retval = nspi_ModLinkAtt(nspi_ctx, false, PR_EMS_AB_REPORTS, 0x0, lpEntryIds); mapitest_print_retval_clean(mt, "NspiModLinkAtt", retval); MAPIFreeBuffer(lpEntryIds); if (retval == MAPI_E_SUCCESS) { return true; } else { return false; } } /** \details Test the NspiQueryColumns RPC operation (0x10) \param mt pointer on the top-level mapitest structure \return true on success, otherwise false */ _PUBLIC_ bool mapitest_nspi_QueryColumns(struct mapitest *mt) { TALLOC_CTX *mem_ctx; enum MAPISTATUS retval; struct nspi_context *nspi_ctx; struct SPropTagArray *SPropTagArray = NULL; mem_ctx = talloc_named(NULL, 0, "mapitest_nspi_QueryColumns"); nspi_ctx = (struct nspi_context *) mt->session->nspi->ctx; SPropTagArray = talloc_zero(mem_ctx, struct SPropTagArray); retval = nspi_QueryColumns(nspi_ctx, mem_ctx, true, &SPropTagArray); if (retval != MAPI_E_SUCCESS) { mapitest_print_retval_clean(mt, "NspiQueryColumns", retval); MAPIFreeBuffer(SPropTagArray); talloc_free(mem_ctx); return false; } if (SPropTagArray) { mapitest_print(mt, "* %d columns returned\n", SPropTagArray->cValues); mapitest_print_retval_clean(mt, "NspiQueryColumns", retval); MAPIFreeBuffer(SPropTagArray); } talloc_free(mem_ctx); return true; } /** \details Test the NspiGetNamesFromIDs RPC operation (0x11) \param mt pointer on the top-level mapitest structure \return true on success, otherwise false */ _PUBLIC_ bool mapitest_nspi_GetNamesFromIDs(struct mapitest *mt) { TALLOC_CTX *mem_ctx; enum MAPISTATUS retval; struct nspi_context *nspi_ctx; struct SPropTagArray *ppReturnedPropTags; struct PropertyNameSet_r *ppNames; mem_ctx = talloc_named(NULL, 0, "mapitest_nspi_GetNamesFromIDs"); nspi_ctx = (struct nspi_context *) mt->session->nspi->ctx; ppReturnedPropTags = talloc_zero(mem_ctx, struct SPropTagArray); ppNames = talloc_zero(mem_ctx, struct PropertyNameSet_r); retval = nspi_GetNamesFromIDs(nspi_ctx, mem_ctx, NULL, NULL, &ppReturnedPropTags, &ppNames); mapitest_print_retval_clean(mt, "NspiGetNamesFromIDs", retval); MAPIFreeBuffer(ppReturnedPropTags); MAPIFreeBuffer(ppNames); talloc_free(mem_ctx); if (retval == MAPI_E_SUCCESS) { return true; } else { return false; } } /** \details Test the NspiGetIDsFromNames RPC operation (0x12) \param mt pointer on the top-level mapitest structure \return true on success, otherwise false */ _PUBLIC_ bool mapitest_nspi_GetIDsFromNames(struct mapitest *mt) { TALLOC_CTX *mem_ctx; enum MAPISTATUS retval; struct nspi_context *nspi_ctx; struct SPropTagArray *ppReturnedPropTags; struct PropertyNameSet_r *ppNames; mem_ctx = talloc_named(NULL, 0, "mapitest_nspi_GetIDsFromNames"); nspi_ctx = (struct nspi_context *) mt->session->nspi->ctx; ppReturnedPropTags = talloc_zero(mem_ctx, struct SPropTagArray); ppNames = talloc_zero(mem_ctx, struct PropertyNameSet_r); retval = nspi_GetNamesFromIDs(nspi_ctx, mem_ctx, NULL, NULL, &ppReturnedPropTags, &ppNames); mapitest_print_retval_clean(mt, "NspiGetNamesFromIDs", retval); MAPIFreeBuffer(ppReturnedPropTags); if ( (retval != MAPI_E_SUCCESS) || !ppNames ) { MAPIFreeBuffer(ppNames); talloc_free(mem_ctx); return false; } ppReturnedPropTags = talloc_zero(mem_ctx, struct SPropTagArray); retval = nspi_GetIDsFromNames(nspi_ctx, mem_ctx, true, ppNames->cNames, ppNames->aNames, &ppReturnedPropTags); mapitest_print_retval_clean(mt, "NspiGetIDsFromNames", retval); MAPIFreeBuffer(ppReturnedPropTags); MAPIFreeBuffer(ppNames); talloc_free(mem_ctx); if (retval == MAPI_E_SUCCESS) { return true; } else { return false; } } /** \details Test the NspiResolveNames and NspiResolveNamesW RPC operations (0x13 and 0x14) \param mt pointer on the top-level mapitest structure \return true on success, otherwise false */ _PUBLIC_ bool mapitest_nspi_ResolveNames(struct mapitest *mt) { enum MAPISTATUS retval; struct SPropTagArray *SPropTagArray = NULL; struct PropertyRowSet_r *RowSet = NULL; struct PropertyTagArray_r *flaglist = NULL; const char *username[2]; const char *username_err[2]; /* Build the username array */ username[0] = (const char *)mt->profile->mailbox; username[1] = NULL; /* Build the err username array */ username_err[0] = talloc_asprintf(mt->mem_ctx, "%s%s", mt->info.szDNPrefix, "nspi_resolve_testcase"); username_err[1] = NULL; SPropTagArray = set_SPropTagArray(mt->mem_ctx, 0xd, PR_ENTRYID, PR_DISPLAY_NAME, PR_ADDRTYPE, PR_GIVEN_NAME, PR_SMTP_ADDRESS, PR_OBJECT_TYPE, PR_DISPLAY_TYPE, PR_EMAIL_ADDRESS, PR_SEND_INTERNET_ENCODING, PR_SEND_RICH_INFO, PR_SEARCH_KEY, PR_TRANSMITTABLE_DISPLAY_NAME, PR_7BIT_DISPLAY_NAME); /* Test with existing username */ /* NspiResolveNames (0x13) */ retval = ResolveNames(mt->session, (const char **)username, SPropTagArray, &RowSet, &flaglist, 0); mapitest_print_retval_clean(mt, "NspiResolveNames - existing", retval); if (retval != MAPI_E_SUCCESS) { MAPIFreeBuffer(SPropTagArray); return false; } if ( ! flaglist) { mapitest_print(mt, "\tNULL flaglist, which wasn't expected\n"); MAPIFreeBuffer(SPropTagArray); return false; } if (flaglist->aulPropTag[0] != MAPI_RESOLVED) { mapitest_print(mt, "Expected 2 (MAPI_RESOLVED), but NspiResolveNames returned: %i\n", flaglist->aulPropTag[0]); } else { mapitest_print(mt, "\tGot expected resolution flag\n"); } talloc_free(flaglist); talloc_free(RowSet); /* NspiResolveNamesW (0x14) */ retval = ResolveNames(mt->session, (const char **)username, SPropTagArray, &RowSet, &flaglist, MAPI_UNICODE); mapitest_print_retval_clean(mt, "NspiResolveNamesW - existing", retval); if (flaglist->aulPropTag[0] != MAPI_RESOLVED) { mapitest_print(mt, "Expected 2 (MAPI_RESOLVED), but NspiResolveNamesW returned: %i\n", flaglist->aulPropTag[0]); } else { mapitest_print(mt, "\tGot expected resolution flag\n"); } talloc_free(flaglist); talloc_free(RowSet); if (retval != MAPI_E_SUCCESS) { MAPIFreeBuffer(SPropTagArray); return false; } /* Test with non-existant username */ /* NspiResolveNames (0x13) */ retval = ResolveNames(mt->session, (const char **)username_err, SPropTagArray, &RowSet, &flaglist, 0); mapitest_print_retval_clean(mt, "NspiResolveNames - non existant user name", retval); if (flaglist->aulPropTag[0] != MAPI_UNRESOLVED) { mapitest_print(mt, "Expected 0 (MAPI_UNRESOLVED), but NspiResolveNames returned: %i\n", flaglist->aulPropTag[0]); } else { mapitest_print(mt, "\tGot expected resolution flag\n"); } talloc_free(flaglist); talloc_free(RowSet); if (retval != MAPI_E_SUCCESS) { MAPIFreeBuffer(SPropTagArray); return false; } /* NspiResolveNamesW (0x14) */ retval = ResolveNames(mt->session, (const char **)username_err, SPropTagArray, &RowSet, &flaglist, MAPI_UNICODE); mapitest_print_retval_clean(mt, "NspiResolveNamesW - non existant user name", retval); if (flaglist->aulPropTag[0] != MAPI_UNRESOLVED) { mapitest_print(mt, "Expected 0 (MAPI_UNRESOLVED), but NspiResolveNamesW returned: %i\n", flaglist->aulPropTag[0]); } else { mapitest_print(mt, "\tGot expected resolution flag\n"); } talloc_free(flaglist); talloc_free(RowSet); if (retval != MAPI_E_SUCCESS) { MAPIFreeBuffer(SPropTagArray); return false; } MAPIFreeBuffer(SPropTagArray); return true; } /** \details Test the GetGALTable function \param mt pointer to the top-level mapitest structure \return true on success, otherwise false */ _PUBLIC_ bool mapitest_nspi_GetGALTable(struct mapitest *mt) { struct SPropTagArray *SPropTagArray; struct PropertyRowSet_r *RowSet; enum MAPISTATUS retval; uint32_t i; uint32_t count; uint8_t ulFlags; uint32_t rowsFetched = 0; uint32_t totalRowsFetched = 0; bool ret = true; SPropTagArray = set_SPropTagArray(mt->mem_ctx, 0xc, PR_INSTANCE_KEY, PR_ENTRYID, PR_DISPLAY_NAME_UNICODE, PR_EMAIL_ADDRESS_UNICODE, PR_DISPLAY_TYPE, PR_OBJECT_TYPE, PR_ADDRTYPE_UNICODE, PR_OFFICE_TELEPHONE_NUMBER_UNICODE, PR_OFFICE_LOCATION_UNICODE, PR_TITLE_UNICODE, PR_COMPANY_NAME_UNICODE, PR_ACCOUNT_UNICODE); count = 0x20; ulFlags = TABLE_START; do { retval = GetGALTable(mt->session, SPropTagArray, &RowSet, count, ulFlags); mapitest_print_retval_clean(mt, "GetGALTable", retval); if ((!RowSet) || (!(RowSet->aRow))) { ret = false; goto cleanup; } rowsFetched = RowSet->cRows; totalRowsFetched += rowsFetched; if (rowsFetched) { for (i = 0; i < rowsFetched; i++) { mapitest_print_PAB_entry(mt, &RowSet->aRow[i]); } } ulFlags = TABLE_CUR; MAPIFreeBuffer(RowSet); } while (rowsFetched == count); if (totalRowsFetched < 1) { /* We should always have at least ourselves in the list */ /* So if we got no rows at all, there is a problem */ ret = false; } cleanup: MAPIFreeBuffer(SPropTagArray); return ret; } openchange-2.0/utils/mapitest/modules/module_oxcfold.c000066400000000000000000001350261223057412600233000ustar00rootroot00000000000000/* Stand-alone MAPI testsuite OpenChange Project - FOLDER OBJECT PROTOCOL operations Copyright (C) Julien Kerihuel 2008 Copyright (C) Brad Hards 2009-2010 This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see . */ #include "utils/mapitest/mapitest.h" #include "utils/mapitest/proto.h" /** \file module_oxcfold.c \brief Folder Object Protocol test suite */ struct folders { uint32_t id; uint64_t fid; const char *name; }; static struct folders top_folders[] = { { 0x0, 0x0, "Mailbox Root Folder" }, { 0x1, 0x0, "Deferred Actions" }, { 0x2, 0x0, "Spooler Queue" }, { 0x3, 0x0, "Top of Information Store" }, { 0x4, 0x0, "Inbox" }, { 0x5, 0x0, "Outbox" }, { 0x6, 0x0, "Sent Items" }, { 0x7, 0x0, "Deleted Items" }, { 0x8, 0x0, "Common Views" }, { 0x9, 0x0, "Schedule" }, { 0xa, 0x0, "Search" }, { 0xb, 0x0, "Views" }, { 0xc, 0x0, "Shortcuts" }, { 0xd, 0x0, NULL } }; static struct folders inbox_folders[] = { { olFolderCalendar, 0x0, "Calendar" }, { olFolderContacts, 0x0, "Contacts" }, { olFolderJournal, 0x0, "Journal" }, { olFolderNotes, 0x0, "Notes" }, { olFolderTasks, 0x0, "Tasks" }, { olFolderDrafts, 0x0, "Drafts" }, { 0x0, 0x0, NULL } }; struct test_folders { const char *name; const char *class; }; static struct test_folders subfolders[] = { { MT_DIRNAME_APPOINTMENT, IPF_APPOINTMENT }, { MT_DIRNAME_CONTACT, IPF_CONTACT }, { MT_DIRNAME_JOURNAL, IPF_JOURNAL }, { MT_DIRNAME_POST, IPF_POST }, { MT_DIRNAME_NOTE, IPF_NOTE }, { MT_DIRNAME_STICKYNOTE, IPF_STICKYNOTE }, { MT_DIRNAME_TASK, IPF_TASK }, { NULL, NULL } }; /** \details Test the OpenFolder (0x2) operation This function: -# Log on the user private mailbox -# Open folders located within the top information store folder -# Open folders located within the Inbox folder \param mt the top-level mapitest structure \return true on success, otherwise false */ _PUBLIC_ bool mapitest_oxcfold_OpenFolder(struct mapitest *mt) { enum MAPISTATUS retval; mapi_object_t obj_store; mapi_object_t obj_folder; mapi_object_store_t *store; mapi_id_t id_folder; int i; /* Step 1. Logon */ mapi_object_init(&obj_store); retval = OpenMsgStore(mt->session, &obj_store); mapitest_print_retval(mt, "OpenMsgStore"); if (GetLastError() != MAPI_E_SUCCESS) { return false; } /* Prepare the top folder check */ store = (mapi_object_store_t *) obj_store.private_data; top_folders[0].fid = store->fid_mailbox_root; top_folders[1].fid = store->fid_deferred_actions; top_folders[2].fid = store->fid_spooler_queue; top_folders[3].fid = store->fid_top_information_store; top_folders[4].fid = store->fid_inbox; top_folders[5].fid = store->fid_outbox; top_folders[6].fid = store->fid_sent_items; top_folders[7].fid = store->fid_deleted_items; top_folders[8].fid = store->fid_common_views; top_folders[9].fid = store->fid_schedule; top_folders[10].fid = store->fid_search; top_folders[11].fid = store->fid_views; top_folders[12].fid = store->fid_shortcuts; /* Step2. Check top folders (Private mailbox) */ mapitest_print(mt, "* Private Mailbox - Message Store (Owner)\n"); mapitest_indent(); for (i = 0; top_folders[i].name; i++) { mapi_object_init(&obj_folder); retval = OpenFolder(&obj_store, top_folders[i].fid, &obj_folder); mapitest_print_retval_fmt(mt, "OpenFolder", "(%s)", top_folders[i].name); if (retval != MAPI_E_SUCCESS) { return false; } mapi_object_release(&obj_folder); } mapitest_deindent(); /* Step3. Check for Inbox folders */ mapitest_print(mt, "* Private Mailbox - Mailbox (Owner)\n"); mapitest_indent(); for (i = 0; inbox_folders[i].name; i++) { mapi_object_init(&obj_folder); retval = GetDefaultFolder(&obj_store, &id_folder, inbox_folders[i].id); mapitest_print_retval_fmt(mt, "GetDefaultFolder", "(%s)", inbox_folders[i].name); if (retval != MAPI_E_SUCCESS) { return false; } retval = OpenFolder(&obj_store, id_folder, &obj_folder); mapitest_print_retval_fmt(mt, "OpenFolder", "(%s)", inbox_folders[i].name); if (retval != MAPI_E_SUCCESS) { return false; } mapi_object_release(&obj_folder); } mapitest_deindent(); /* Release */ mapi_object_release(&obj_store); return true; } /** \details Test the CreateFolder (0x1c) and DeleteFolder (0x1d) operations This is a simpler version of the CreateFolder test below. This function: -# Log on the user private mailbox -# Open the top information folder -# Create a test directory -# Delete the folder \param mt the top-level mapitest structure \return true on success, otherwise false */ _PUBLIC_ bool mapitest_oxcfold_CreateDeleteFolder(struct mapitest *mt) { enum MAPISTATUS retval; mapi_object_t obj_store; mapi_object_t obj_folder; mapi_object_t obj_top; mapi_object_t obj_child; mapi_object_t obj_grandchild; mapi_id_t id_folder; bool ret = true; mapi_object_init(&obj_store); mapi_object_init(&obj_folder); mapi_object_init(&obj_top); mapi_object_init(&obj_child); mapi_object_init(&obj_grandchild); /* Step 1. Logon */ retval = OpenMsgStore(mt->session, &obj_store); mapitest_print_retval(mt, "OpenMsgStore"); if (retval != MAPI_E_SUCCESS) { ret = false; goto cleanup; } /* Step 2. Open Top Information Store folder */ retval = GetDefaultFolder(&obj_store, &id_folder, olFolderTopInformationStore); mapitest_print_retval(mt, "GetDefaultFolder"); if (retval != MAPI_E_SUCCESS) { ret = false; goto cleanup; } retval = OpenFolder(&obj_store, id_folder, &obj_folder); mapitest_print_retval(mt, "OpenFolder"); if (retval != MAPI_E_SUCCESS) { ret = false; goto cleanup; } /* Step 3. Create the top test folder */ mapitest_print(mt, "* Create GENERIC \"%s\" folder\n", MT_DIRNAME_TOP); retval = CreateFolder(&obj_folder, FOLDER_GENERIC, MT_DIRNAME_TOP, NULL, OPEN_IF_EXISTS, &obj_top); mapitest_print_retval(mt, "CreateFolder - top"); if (retval != MAPI_E_SUCCESS) { ret = false; goto cleanup; } /* Step 4. Create child folder */ mapitest_print(mt, "* Create GENERIC child folder\n"); retval = CreateFolder(&obj_top, FOLDER_GENERIC, "MT Child folder", NULL, OPEN_IF_EXISTS, &obj_child); mapitest_print_retval(mt, "CreateFolder - child"); if (retval != MAPI_E_SUCCESS) { ret = false; goto cleanup; } /* Step 5. Create child of the child (grandchild) folder */ mapitest_print(mt, "* Create GENERIC grandchild folder\n"); retval = CreateFolder(&obj_child, FOLDER_GENERIC, "MT grandchild folder", NULL, OPEN_IF_EXISTS, &obj_grandchild); mapitest_print_retval(mt, "CreateFolder - grandchild"); if (retval != MAPI_E_SUCCESS) { ret = false; goto cleanup; } /* Step 6. DeleteFolder on the child (and recurse to grandchild) */ retval = DeleteFolder(&obj_top, mapi_object_get_id(&obj_child), DEL_MESSAGES|DEL_FOLDERS|DELETE_HARD_DELETE, NULL); mapitest_print_retval(mt, "DeleteFolder - child"); if (retval != MAPI_E_SUCCESS) { ret = false; } /* Step 7. DeleteFolder on the top folder */ retval = DeleteFolder(&obj_folder, mapi_object_get_id(&obj_top), DELETE_HARD_DELETE, NULL); mapitest_print_retval(mt, "DeleteFolder - top"); if (retval != MAPI_E_SUCCESS) { ret = false; } cleanup: /* Release */ mapi_object_release(&obj_grandchild); mapi_object_release(&obj_child); mapi_object_release(&obj_top); mapi_object_release(&obj_folder); mapi_object_release(&obj_store); return ret; } /** \details Test the CreateFolder (0x1c) operation This function: -# Log on the user private mailbox -# Open the top information folder -# Create a test directory -# Create sub directories with different container classes -# Empty the folder -# Delete the folder \param mt the top-level mapitest structure \return true on success, otherwise false */ _PUBLIC_ bool mapitest_oxcfold_CreateFolder(struct mapitest *mt) { enum MAPISTATUS retval; struct SPropValue lpProp[1]; mapi_object_t obj_store; mapi_object_t obj_folder; mapi_object_t obj_top; mapi_object_t obj_child; mapi_id_t id_folder; int i; bool ret = true; /* Step 1. Logon */ mapi_object_init(&obj_store); mapi_object_init(&obj_folder); mapi_object_init(&obj_top); retval = OpenMsgStore(mt->session, &obj_store); mapitest_print_retval(mt, "OpenMsgStore"); if (retval != MAPI_E_SUCCESS) { ret = false; goto cleanup; } /* Step 2. Open Top Information Store folder */ retval = GetDefaultFolder(&obj_store, &id_folder, olFolderTopInformationStore); if (retval != MAPI_E_SUCCESS) { ret = false; goto cleanup; } retval = OpenFolder(&obj_store, id_folder, &obj_folder); if (retval != MAPI_E_SUCCESS) { ret = false; goto cleanup; } /* Step 3. Create the top test folder */ mapitest_print(mt, "* Create GENERIC \"%s\" folder\n", MT_DIRNAME_TOP); retval = CreateFolder(&obj_folder, FOLDER_GENERIC, MT_DIRNAME_TOP, NULL, OPEN_IF_EXISTS, &obj_top); mapitest_print_retval(mt, "CreateFolder"); if (retval != MAPI_E_SUCCESS) { ret = false; goto cleanup; } /* Step 4. Create sub directories */ mapitest_print(mt, "* Creating sub directories\n"); mapitest_indent(); for (i = 0; subfolders[i].name; i++) { /* Step 4.1. Create the sub folder */ mapi_object_init(&obj_child); retval = CreateFolder(&obj_top, FOLDER_GENERIC, subfolders[i].name, NULL, OPEN_IF_EXISTS, &obj_child); mapitest_print_retval_fmt(mt, "CreateFolder", "(%s)", subfolders[i].name); if (retval != MAPI_E_SUCCESS) { mapitest_deindent(); mapi_object_release(&obj_child); ret = false; goto cleanup; } /* Step 4.2. Set its container class */ set_SPropValue_proptag(&lpProp[0], PR_CONTAINER_CLASS, (const void *) subfolders[i].class); retval = SetProps(&obj_child, 0, lpProp, 1); mapitest_print_retval_fmt(mt, "SetProps", "(%s)", subfolders[i].name); if (retval != MAPI_E_SUCCESS) { mapitest_deindent(); mapi_object_release(&obj_child); ret = false; goto cleanup; } mapi_object_release(&obj_child); } mapitest_deindent(); /* Step 5. Empty Folder */ retval = EmptyFolder(&obj_top); mapitest_print_retval(mt, "EmptyFolder"); if (retval != MAPI_E_SUCCESS) { ret = false; goto cleanup; } /* Step 6. DeleteFolder */ retval = DeleteFolder(&obj_folder, mapi_object_get_id(&obj_top), DEL_MESSAGES|DEL_FOLDERS|DELETE_HARD_DELETE, NULL); mapitest_print_retval(mt, "DeleteFolder"); if (retval != MAPI_E_SUCCESS) { ret = false; goto cleanup; } cleanup: /* Release */ mapi_object_release(&obj_top); mapi_object_release(&obj_folder); mapi_object_release(&obj_store); return ret; } /** \details Test the CreateFolder (0x1c) operations This tests different combinations of folder creation. This function: -# Log on the user private mailbox -# Open the top information folder -# Create a test directory (or open the directory if it already exists) -# Delete the test directory -# Create the test directory again (it should not exist) -# Try to create another directory with the same name (should error out) -# Try to create another directory with the same name, but use open if exists -# Create a generic subfolder -# Try to create another generic subfolder with the same name (should error out) -# Try to create another generic subfolder with the same name, but use open if exists -# Delete the generic subfolder -# Delete the test directory \param mt the top-level mapitest structure \return true on success, otherwise false */ _PUBLIC_ bool mapitest_oxcfold_CreateFolderVariants(struct mapitest *mt) { enum MAPISTATUS retval; mapi_object_t obj_store; mapi_object_t obj_folder; mapi_object_t obj_top1, obj_top2, obj_top3; mapi_object_t obj_child1, obj_child2, obj_child3; mapi_id_t id_folder; bool ret = true; mapi_object_init(&obj_store); mapi_object_init(&obj_folder); mapi_object_init(&obj_top1); mapi_object_init(&obj_top2); mapi_object_init(&obj_top3); mapi_object_init(&obj_child1); mapi_object_init(&obj_child2); mapi_object_init(&obj_child3); /* Step 1. Logon */ retval = OpenMsgStore(mt->session, &obj_store); mapitest_print_retval_clean(mt, "OpenMsgStore", retval); if (retval != MAPI_E_SUCCESS) { ret = false; goto cleanup; } /* Step 2. Open Top Information Store folder */ retval = GetDefaultFolder(&obj_store, &id_folder, olFolderTopInformationStore); mapitest_print_retval_clean(mt, "GetDefaultFolder", retval); if (retval != MAPI_E_SUCCESS) { ret = false; goto cleanup; } retval = OpenFolder(&obj_store, id_folder, &obj_folder); mapitest_print_retval_clean(mt, "OpenFolder", retval); if (retval != MAPI_E_SUCCESS) { ret = false; goto cleanup; } /* Step 3. Create the top test folder */ mapitest_print(mt, "* Create GENERIC \"%s\" folder\n", MT_DIRNAME_TOP); retval = CreateFolder(&obj_folder, FOLDER_GENERIC, MT_DIRNAME_TOP, NULL, OPEN_IF_EXISTS, &obj_top1); mapitest_print_retval_clean(mt, "CreateFolder - top", retval); if (retval != MAPI_E_SUCCESS) { ret = false; goto cleanup; } /* Step 4. DeleteFolder on the top folder */ retval = DeleteFolder(&obj_folder, mapi_object_get_id(&obj_top1), DEL_MESSAGES|DEL_FOLDERS|DELETE_HARD_DELETE, NULL); mapitest_print_retval_clean(mt, "DeleteFolder - top", retval); if (retval != MAPI_E_SUCCESS) { ret = false; goto cleanup; } /* Step 5. Create the top test folder (again) */ mapitest_print(mt, "* Create GENERIC \"%s\" folder\n", MT_DIRNAME_TOP); retval = CreateFolder(&obj_folder, FOLDER_GENERIC, MT_DIRNAME_TOP, NULL, 0, &obj_top1); mapitest_print_retval_clean(mt, "CreateFolder - top", retval); if (retval != MAPI_E_SUCCESS) { ret = false; goto cleanup; } /* Step 6. Create the top test folder (again) - should error out*/ mapitest_print(mt, "* Create GENERIC \"%s\" folder (duplicate name - expect collision)\n", MT_DIRNAME_TOP); retval = CreateFolder(&obj_folder, FOLDER_GENERIC, MT_DIRNAME_TOP, NULL, 0, &obj_top2); mapitest_print_retval_clean(mt, "CreateFolder - top", retval); if (retval != MAPI_E_COLLISION) { ret = false; goto cleanup; } /* Step 7. Create the top test folder (again), using OPEN_IF_EXISTS */ mapitest_print(mt, "* Create GENERIC \"%s\" folder (open if exists)\n", MT_DIRNAME_TOP); retval = CreateFolder(&obj_folder, FOLDER_GENERIC, MT_DIRNAME_TOP, NULL, OPEN_IF_EXISTS, &obj_top3); mapitest_print_retval_clean(mt, "CreateFolder - top", retval); if (retval != MAPI_E_SUCCESS) { ret = false; goto cleanup; } /* Step 8. Create child folder */ mapitest_print(mt, "* Create GENERIC child folder\n"); retval = CreateFolder(&obj_top3, FOLDER_GENERIC, "MT Child folder", NULL, 0, &obj_child1); mapitest_print_retval_clean(mt, "CreateFolder - child", retval); if (retval != MAPI_E_SUCCESS) { ret = false; goto cleanup; } /* Step 9. Create the child test folder (again) - should error out*/ mapitest_print(mt, "* Create GENERIC child folder (duplicate name - expect collision)\n"); retval = CreateFolder(&obj_top3, FOLDER_GENERIC, "MT Child folder", NULL, 0, &obj_child2); mapitest_print_retval_clean(mt, "CreateFolder - child", retval); if (retval != MAPI_E_COLLISION) { ret = false; goto cleanup; } /* Step 10. Create the child test folder (again), using OPEN_IF_EXISTS */ mapitest_print(mt, "* Create GENERIC child folder (open if exists)\n"); retval = CreateFolder(&obj_top3, FOLDER_GENERIC, MT_DIRNAME_TOP, NULL, OPEN_IF_EXISTS, &obj_child3); mapitest_print_retval_clean(mt, "CreateFolder - child", retval); if (retval != MAPI_E_SUCCESS) { ret = false; goto cleanup; } /* Step 11. DeleteFolder on the child */ retval = DeleteFolder(&obj_top3, mapi_object_get_id(&obj_child3), DELETE_HARD_DELETE, NULL); mapitest_print_retval_clean(mt, "DeleteFolder - child", retval); if (retval != MAPI_E_SUCCESS) { ret = false; /* we want to fall through on the off-chance this fails */ } /* Step 12. DeleteFolder on the top folder */ retval = DeleteFolder(&obj_folder, mapi_object_get_id(&obj_top3), DEL_MESSAGES|DEL_FOLDERS|DELETE_HARD_DELETE, NULL); mapitest_print_retval_clean(mt, "DeleteFolder - top", retval); if (retval != MAPI_E_SUCCESS) { ret = false; goto cleanup; } cleanup: /* Release */ mapi_object_release(&obj_child3); mapi_object_release(&obj_child2); mapi_object_release(&obj_child1); mapi_object_release(&obj_top3); mapi_object_release(&obj_top2); mapi_object_release(&obj_top1); mapi_object_release(&obj_folder); mapi_object_release(&obj_store); return ret; } /** \details Test the GetHierarchyTable (0x4) operation This function: -# Log on the user private mailbox -# Open the top information folder -# Call the GetHierarchyTable operation \param mt pointer on the top-level mapitest structure \return true on success, otherwise false */ _PUBLIC_ bool mapitest_oxcfold_GetHierarchyTable(struct mapitest *mt) { mapi_object_t obj_store; mapi_object_t obj_folder; mapi_object_t obj_htable; mapi_id_t id_folder; uint32_t RowCount; /* Step 1. Logon */ mapi_object_init(&obj_store); OpenMsgStore(mt->session, &obj_store); mapitest_print_retval(mt, "OpenMsgStore"); if (GetLastError() != MAPI_E_SUCCESS) { return false; } /* Step 2. Open Top Information Store folder */ mapi_object_init(&obj_folder); GetDefaultFolder(&obj_store, &id_folder, olFolderTopInformationStore); mapitest_print_retval(mt, "GetDefaultFolder"); OpenFolder(&obj_store, id_folder, &obj_folder); mapitest_print_retval(mt, "OpenFolder"); if (GetLastError() != MAPI_E_SUCCESS) { return false; } /* Step 3. Get the Hierarchy Table */ mapi_object_init(&obj_htable); GetHierarchyTable(&obj_folder, &obj_htable, 0, &RowCount); mapitest_print_retval_fmt(mt, "GetHierarchyTable", "(%d rows)", RowCount); if (GetLastError() != MAPI_E_SUCCESS) { return false; } /* Release */ mapi_object_release(&obj_htable); mapi_object_release(&obj_folder); mapi_object_release(&obj_store); return true; } /** \details Test the GetContentsTable (0x5) operation This function: -# Log on the user private mailbox -# Open the top information folder -# Call the GetContentsTable operation \param mt pointer on the top-level mapitest structure \return true on success, otherwise false */ _PUBLIC_ bool mapitest_oxcfold_GetContentsTable(struct mapitest *mt) { mapi_object_t obj_store; mapi_object_t obj_folder; mapi_object_t obj_ctable; mapi_id_t id_folder; uint32_t RowCount; /* Step 1. Logon */ mapi_object_init(&obj_store); OpenMsgStore(mt->session, &obj_store); mapitest_print_retval(mt, "OpenMsgStore"); if (GetLastError() != MAPI_E_SUCCESS) { return false; } /* Step 2. Open Top Information Store folder */ mapi_object_init(&obj_folder); GetDefaultFolder(&obj_store, &id_folder, olFolderTopInformationStore); mapitest_print_retval(mt, "GetDefaultFolder"); OpenFolder(&obj_store, id_folder, &obj_folder); mapitest_print_retval(mt, "OpenFolder"); if (GetLastError() != MAPI_E_SUCCESS) { return false; } /* Step 3. Get the Contents Table */ mapi_object_init(&obj_ctable); GetContentsTable(&obj_folder, &obj_ctable, 0, &RowCount); mapitest_print_retval_fmt(mt, "GetContentsTable", "(%d rows)", RowCount); if (GetLastError() != MAPI_E_SUCCESS) { return false; } /* Release */ mapi_object_release(&obj_ctable); mapi_object_release(&obj_folder); mapi_object_release(&obj_store); return true; } /** \details Test the SetSearchCriteria (0x30) operation This function: -# Log on the user private mailbox -# Retrieve the inbox folder ID -# Open the default search folder -# Create a search folder within this folder -# Set the message class property on this container -# Set a restriction criteria -# Call SetSearchCriteria -# Delete the test search folder \param mt pointer on the top-level mapitest structure \return true on success, otherwise false */ _PUBLIC_ bool mapitest_oxcfold_SetSearchCriteria(struct mapitest *mt) { bool ret = true; mapi_object_t obj_store; mapi_object_t obj_search; mapi_object_t obj_searchdir; mapi_id_t id_inbox; mapi_id_t id_search; mapi_id_array_t id; struct SPropValue lpProps[1]; struct mapi_SRestriction res; /* Step 1. Logon */ mapi_object_init(&obj_store); OpenMsgStore(mt->session, &obj_store); mapitest_print_retval(mt, "OpenMsgStore"); if (GetLastError() != MAPI_E_SUCCESS) { return false; } /* Open Inbox folder */ GetDefaultFolder(&obj_store, &id_inbox, olFolderInbox); mapitest_print_retval(mt, "GetDefaultFolder"); if (GetLastError() != MAPI_E_SUCCESS) { return false; } /* Step 3. Open Search folder */ GetDefaultFolder(&obj_store, &id_search, olFolderFinder); mapitest_print_retval(mt, "GetDefaultFolder"); if (GetLastError() != MAPI_E_SUCCESS) { return false; } mapi_object_init(&obj_search); OpenFolder(&obj_store, id_search, &obj_search); mapitest_print_retval(mt, "OpenFolder"); if (GetLastError() != MAPI_E_SUCCESS) { return false; } /* Step 4. Create a search folder */ mapi_object_init(&obj_searchdir); CreateFolder(&obj_search, FOLDER_SEARCH, "mapitest", "mapitest search folder", OPEN_IF_EXISTS, &obj_searchdir); mapitest_print_retval(mt, "CreateFolder"); if (GetLastError() != MAPI_E_SUCCESS) { return false; } /* Step 5. Set properties on this search folder */ lpProps[0].ulPropTag = PR_CONTAINER_CLASS; lpProps[0].value.lpszA = IPF_NOTE; SetProps(&obj_searchdir, 0, lpProps, 1); mapitest_print_retval(mt, "SetProps"); if (GetLastError() != MAPI_E_SUCCESS) { ret = false; goto error; } /* Step 6. Search criteria on this folder */ mapi_id_array_init(mt->mapi_ctx->mem_ctx, &id); mapi_id_array_add_id(&id, id_inbox); res.rt = RES_CONTENT; res.res.resContent.fuzzy = FL_SUBSTRING; res.res.resContent.ulPropTag = PR_SUBJECT; res.res.resContent.lpProp.ulPropTag = PR_SUBJECT; res.res.resContent.lpProp.value.lpszA = "MT"; SetSearchCriteria(&obj_searchdir, &res, BACKGROUND_SEARCH|RECURSIVE_SEARCH, &id); mapitest_print_retval(mt, "SetSearchCriteria"); mapi_id_array_release(&id); if (GetLastError() != MAPI_E_SUCCESS) { ret = false; } error: DeleteFolder(&obj_search, mapi_object_get_id(&obj_searchdir), DEL_MESSAGES|DEL_FOLDERS|DELETE_HARD_DELETE, NULL); mapitest_print_retval(mt, "DeleteFolder"); mapi_object_release(&obj_searchdir); mapi_object_release(&obj_search); mapi_object_release(&obj_store); return ret; } /** \details Test the GetSearchCriteria (0x31) operation This function: -# Log on the user private mailbox -# Retrieve the inbox folder ID -# Open the default search folder -# Create a search folder within this folder -# Set the message class property on this container -# Set a restriction criteria -# Call SetSearchCriteria -# Call GetSearchCriteria -# Delete the test search folder \param mt pointer on the top-level mapitest structure \return true on success, otherwise false */ _PUBLIC_ bool mapitest_oxcfold_GetSearchCriteria(struct mapitest *mt) { bool ret = true; mapi_object_t obj_store; mapi_object_t obj_search; mapi_object_t obj_searchdir; mapi_id_t id_inbox; mapi_id_t id_search; mapi_id_array_t id; struct SPropValue lpProps[1]; struct mapi_SRestriction res; uint32_t ulSearchFlags; uint16_t count; mapi_id_t *fid; /* Step 1. Logon */ mapi_object_init(&obj_store); OpenMsgStore(mt->session, &obj_store); mapitest_print_retval(mt, "OpenMsgStore"); if (GetLastError() != MAPI_E_SUCCESS) { return false; } /* Open Inbox folder */ GetDefaultFolder(&obj_store, &id_inbox, olFolderInbox); mapitest_print_retval(mt, "GetDefaultFolder"); if (GetLastError() != MAPI_E_SUCCESS) { return false; } /* Step 3. Open Search folder */ GetDefaultFolder(&obj_store, &id_search, olFolderFinder); mapitest_print_retval(mt, "GetDefaultFolder"); if (GetLastError() != MAPI_E_SUCCESS) { return false; } mapi_object_init(&obj_search); OpenFolder(&obj_store, id_search, &obj_search); mapitest_print_retval(mt, "OpenFolder"); if (GetLastError() != MAPI_E_SUCCESS) { return false; } /* Step 4. Create a search folder */ mapi_object_init(&obj_searchdir); CreateFolder(&obj_search, FOLDER_SEARCH, "mapitest", "mapitest search folder", OPEN_IF_EXISTS, &obj_searchdir); mapitest_print_retval(mt, "CreateFolder"); if (GetLastError() != MAPI_E_SUCCESS) { return false; } /* Step 5. Set properties on this search folder */ lpProps[0].ulPropTag = PR_CONTAINER_CLASS; lpProps[0].value.lpszA = IPF_NOTE; SetProps(&obj_searchdir, 0, lpProps, 1); mapitest_print_retval(mt, "SetProps"); if (GetLastError() != MAPI_E_SUCCESS) { ret = false; goto error; } /* Step 6. Search criteria on this folder */ mapi_id_array_init(mt->mapi_ctx->mem_ctx, &id); mapi_id_array_add_id(&id, id_inbox); res.rt = RES_CONTENT; res.res.resContent.fuzzy = FL_SUBSTRING; res.res.resContent.ulPropTag = PR_SUBJECT; res.res.resContent.lpProp.ulPropTag = PR_SUBJECT; res.res.resContent.lpProp.value.lpszA = "MT"; SetSearchCriteria(&obj_searchdir, &res, BACKGROUND_SEARCH|RECURSIVE_SEARCH, &id); mapitest_print_retval(mt, "SetSearchCriteria"); mapi_id_array_release(&id); if (GetLastError() != MAPI_E_SUCCESS) { ret = false; goto error; } /* Step 7. Call GetSearchCriteria */ GetSearchCriteria(&obj_searchdir, &res, &ulSearchFlags, &count, &fid); mapitest_print_retval(mt, "GetSearchCriteria"); if (GetLastError() != MAPI_E_SUCCESS) { ret = false; goto error; } error: DeleteFolder(&obj_search, mapi_object_get_id(&obj_searchdir), DEL_MESSAGES|DEL_FOLDERS|DELETE_HARD_DELETE, NULL); mapitest_print_retval(mt, "DeleteFolder"); mapi_object_release(&obj_searchdir); mapi_object_release(&obj_search); mapi_object_release(&obj_store); return ret; } /** \details Test the MoveCopyMessages (0x33) operation. This function: -# Log on the user private mailbox -# Open the Inbox folder (source) -# Open the Deleted Items folder (destination) -# Creates 3 sample messages -# Move messages from source to destination \param mt pointer on the top-level mapitest structure \return true on success, otherwise false */ _PUBLIC_ bool mapitest_oxcfold_MoveCopyMessages(struct mapitest *mt) { enum MAPISTATUS retval; bool common_result; bool ret = true; mapi_object_t obj_store; mapi_object_t obj_folder_src; mapi_object_t obj_folder_dst; mapi_object_t obj_message; mapi_object_t dst_contents; uint32_t dst_count; struct mapi_SRestriction res; struct SPropTagArray *SPropTagArray; struct SRowSet SRowSet; mapi_id_array_t msg_id_array; mapi_id_t msgid[20]; mapi_id_t id_folder; uint32_t i; /* Step 1. Logon */ mapi_object_init(&obj_store); retval = OpenMsgStore(mt->session, &obj_store); mapitest_print_retval(mt, "OpenMsgStore"); if (retval != MAPI_E_SUCCESS) { return false; } /* Step 2. Open Source Inbox folder */ mapi_object_init(&obj_folder_src); retval = GetDefaultFolder(&obj_store, &id_folder, olFolderInbox); mapitest_print_retval(mt, "GetDefaultFolder"); retval = OpenFolder(&obj_store, id_folder, &obj_folder_src); mapitest_print_retval(mt, "OpenFolder"); if (retval != MAPI_E_SUCCESS) { return false; } /* Step 3. Open Destination Deleted Items folder */ mapi_object_init(&obj_folder_dst); retval = GetDefaultFolder(&obj_store, &id_folder, olFolderDeletedItems); mapitest_print_retval(mt, "GetDefaultFolder"); retval = OpenFolder(&obj_store, id_folder, &obj_folder_dst); mapitest_print_retval(mt, "OpenFolder"); if (retval != MAPI_E_SUCCESS) { return false; } mapi_object_init(&(dst_contents)); retval = GetContentsTable(&(obj_folder_dst), &(dst_contents), 0, &dst_count); mapitest_print_retval(mt, "GetContentsTable"); if (retval != MAPI_E_SUCCESS) { ret = false; goto release; } /* Step 4. Create sample messages */ mapi_id_array_init(mt->mapi_ctx->mem_ctx, &msg_id_array); for (i = 0; i < 3; i++) { mapi_object_init(&obj_message); common_result = mapitest_common_message_create(mt, &obj_folder_src, &obj_message, MT_MAIL_SUBJECT); if (!common_result) { mapitest_print(mt, "* mapitest_common_message_create() failed\n"); ret = false; goto release; } retval = SaveChangesMessage(&obj_folder_src, &obj_message, KeepOpenReadOnly); mapitest_print_retval(mt, "SaveChangesMessage"); if (retval != MAPI_E_SUCCESS) { ret = false; goto release; } mapi_id_array_add_obj(&msg_id_array, &obj_message); mapi_object_release(&obj_message); } /* Step 5. Move messages from source to destination */ retval = MoveCopyMessages(&obj_folder_src, &obj_folder_dst, &msg_id_array, 0); mapitest_print_retval(mt, "MoveCopyMessages"); if (retval != MAPI_E_SUCCESS) { ret = false; goto release; } mapi_id_array_release(&msg_id_array); /* Step 6. Apply a filter */ res.rt = RES_PROPERTY; res.res.resProperty.relop = RES_PROPERTY; res.res.resProperty.ulPropTag = PR_SUBJECT; res.res.resProperty.lpProp.ulPropTag = PR_SUBJECT; res.res.resProperty.lpProp.value.lpszA = MT_MAIL_SUBJECT; retval = Restrict(&(dst_contents), &res, NULL); mapitest_print_retval(mt, "Restrict"); if (retval != MAPI_E_SUCCESS) { ret = false; goto release; } /* Step 7. Get the filtered row */ SPropTagArray = set_SPropTagArray(mt->mem_ctx, 0x1, PR_MID); retval = SetColumns(&(dst_contents), SPropTagArray); mapitest_print_retval(mt, "SetColumns"); MAPIFreeBuffer(SPropTagArray); if (retval != MAPI_E_SUCCESS) { ret = false; goto release; } retval = QueryRows(&(dst_contents), 20, TBL_NOADVANCE, &SRowSet); mapitest_print_retval(mt, "QueryRows"); if ( (retval == MAPI_E_SUCCESS) && (SRowSet.cRows > 0) ) { for (i = 0; i < SRowSet.cRows; ++i) { msgid[i] = SRowSet.aRow[i].lpProps[0].value.d; } } /* Step 8. Delete Messages */ retval = DeleteMessage(&obj_folder_dst, msgid, i); mapitest_print_retval(mt, "DeleteMessage"); release: /* Release */ mapi_object_release(&dst_contents); mapi_object_release(&obj_folder_src); mapi_object_release(&obj_folder_dst); mapi_object_release(&obj_store); return ret; } /** \details Test the MoveFolder (0x35) operation. This function: -# Log on the user private mailbox -# Open the Inbox folder (source) -# Create a temporary folder -# Create 1 message in this new folder -# Open the Deleted Items folder (destination) -# Move the temporary folder from Inbox to DeletedItems -# Empty and delete the moved temporary folder \param mt pointer on the top-level mapitest structure \return true on success, otherwise false */ _PUBLIC_ bool mapitest_oxcfold_MoveFolder(struct mapitest *mt) { enum MAPISTATUS retval; mapi_object_t obj_store; mapi_object_t obj_folder; mapi_object_t obj_src; mapi_object_t obj_dst; mapi_object_t obj_message; bool ret = true; /* Step 1. Logon */ mapi_object_init(&obj_store); retval = OpenMsgStore(mt->session, &obj_store); mapitest_print_retval(mt, "OpenMsgStore"); if (retval != MAPI_E_SUCCESS) { return false; } /* Step 2. Open the inbox folder */ mapi_object_init(&obj_src); ret = mapitest_common_folder_open(mt, &obj_store, &obj_src, olFolderInbox); if (ret == false) return ret; /* Step 3. Create temporary folder */ mapi_object_init(&obj_folder); retval = CreateFolder(&obj_src, FOLDER_GENERIC, MT_DIRNAME_TOP, NULL, OPEN_IF_EXISTS, &obj_folder); mapitest_print_retval(mt, "CreateFolder"); if (GetLastError() != MAPI_E_SUCCESS) { return false; } /* Step 4. Create message within this temporary folder */ mapi_object_init(&obj_message); ret = mapitest_common_message_create(mt, &obj_folder, &obj_message, MT_MAIL_SUBJECT); mapitest_print_retval(mt, "mapitest_common_message_create"); retval = SaveChangesMessage(&obj_folder, &obj_message, KeepOpenReadOnly); mapitest_print_retval(mt, "SaveChangesMessage"); if (retval != MAPI_E_SUCCESS) { ret = false; } mapi_object_release(&obj_message); /* Step 5. Open the Deleted items folder */ mapi_object_init(&obj_dst); ret = mapitest_common_folder_open(mt, &obj_store, &obj_dst, olFolderDeletedItems); /* Step 6. MoveFolder */ retval = MoveFolder(&obj_folder, &obj_src, &obj_dst, MT_DIRNAME_TOP, false); mapitest_print_retval(mt, "MoveFolder"); if (GetLastError() != MAPI_E_SUCCESS) { ret = false; } mapi_object_release(&obj_folder); /* Step 7. Delete the moved folder */ mapi_object_init(&obj_folder); ret = mapitest_common_find_folder(mt, &obj_dst, &obj_folder, MT_DIRNAME_TOP); mapitest_print(mt, "* %-35s: %s\n", "mapitest_common_find_folder", (ret == true) ? "true" : "false"); if (ret == true) { retval = EmptyFolder(&obj_folder); mapitest_print_retval(mt, "EmptyFolder"); if (retval != MAPI_E_SUCCESS) { ret = false; } retval = DeleteFolder(&obj_dst, mapi_object_get_id(&obj_folder), DEL_MESSAGES|DEL_FOLDERS|DELETE_HARD_DELETE, NULL); mapitest_print_retval(mt, "DeleteFolder"); if (retval != MAPI_E_SUCCESS) { ret = false; } } /* Release */ mapi_object_release(&obj_folder); mapi_object_release(&obj_src); mapi_object_release(&obj_dst); mapi_object_release(&obj_store); return true; } /** \details Test the CopyFolder (0x36) operation. This function: -# Log on the user private mailbox -# Open the Inbox folder (source) -# Create a temporary folder -# Create a subdirectory -# Open the Deleted Items folder (destination) -# Copy the temporary folder from Inbox to DeletedItems -# Empty and delete the original and copied folder \param mt pointer on the top-level mapitest structure \return true on success, otherwise false */ _PUBLIC_ bool mapitest_oxcfold_CopyFolder(struct mapitest *mt) { enum MAPISTATUS retval; mapi_object_t obj_store; mapi_object_t obj_folder; mapi_object_t obj_subfolder; mapi_object_t obj_src; mapi_object_t obj_dst; bool ret = true; /* Step 1. Logon */ mapi_object_init(&obj_store); retval = OpenMsgStore(mt->session, &obj_store); mapitest_print_retval(mt, "OpenMsgStore"); if (retval != MAPI_E_SUCCESS) { return false; } /* Step 2. Open the inbox folder */ mapi_object_init(&obj_src); ret = mapitest_common_folder_open(mt, &obj_store, &obj_src, olFolderInbox); if (ret == false) return ret; /* Step 3. Create temporary folder */ mapi_object_init(&obj_folder); retval = CreateFolder(&obj_src, FOLDER_GENERIC, MT_DIRNAME_TOP, NULL, OPEN_IF_EXISTS, &obj_folder); mapitest_print_retval(mt, "CreateFolder"); if (GetLastError() != MAPI_E_SUCCESS) { return false; } /* Step 4. Create the sub folder */ mapi_object_init(&obj_subfolder); retval = CreateFolder(&obj_folder, FOLDER_GENERIC, MT_DIRNAME_NOTE, NULL, OPEN_IF_EXISTS, &obj_subfolder); mapitest_print_retval(mt, "CreateFolder"); if (GetLastError() != MAPI_E_SUCCESS) { ret = false; } mapi_object_release(&obj_subfolder); /* Step 5. Open the Deleted items folder */ mapi_object_init(&obj_dst); ret = mapitest_common_folder_open(mt, &obj_store, &obj_dst, olFolderDeletedItems); /* Step 6. CopyFolder */ retval = CopyFolder(&obj_folder, &obj_src, &obj_dst, MT_DIRNAME_TOP, false, false); mapitest_print_retval(mt, "CopyFolder"); if (GetLastError() != MAPI_E_SUCCESS) { ret = false; } /* Step 7. Delete the original and copied folder */ retval = EmptyFolder(&obj_folder); mapitest_print_retval(mt, "EmptyFolder"); if (retval != MAPI_E_SUCCESS) { ret = false; } retval = DeleteFolder(&obj_src, mapi_object_get_id(&obj_folder), DEL_MESSAGES|DEL_FOLDERS|DELETE_HARD_DELETE, NULL); mapitest_print_retval(mt, "DeleteFolder"); if (retval != MAPI_E_SUCCESS) { ret = false; } mapi_object_release(&obj_folder); mapi_object_init(&obj_folder); ret = mapitest_common_find_folder(mt, &obj_dst, &obj_folder, MT_DIRNAME_TOP); mapitest_print(mt, "* %-35s: %s\n", "mapitest_common_find_folder", (ret == true) ? "true" : "false"); if (ret == true) { retval = EmptyFolder(&obj_folder); mapitest_print_retval(mt, "EmptyFolder"); if (retval != MAPI_E_SUCCESS) { ret = false; } retval = DeleteFolder(&obj_dst, mapi_object_get_id(&obj_folder), DEL_MESSAGES|DEL_FOLDERS|DELETE_HARD_DELETE, NULL); mapitest_print_retval(mt, "DeleteFolder"); if (retval != MAPI_E_SUCCESS) { ret = false; } } /* Release */ mapi_object_release(&obj_folder); mapi_object_release(&obj_src); mapi_object_release(&obj_dst); mapi_object_release(&obj_store); return ret; } /** \details Test the HardDeleteMessages (0x91) operation. This function: -# Log on the user private mailbox -# Open the Inbox folder (source) -# Creates 3 sample messages -# Hard delete the sample messages \param mt pointer to the top-level mapitest structure \return true on success, otherwise false */ _PUBLIC_ bool mapitest_oxcfold_HardDeleteMessages(struct mapitest *mt) { enum MAPISTATUS retval; bool ret = true; mapi_object_t obj_store; mapi_object_t obj_folder; mapi_object_t obj_message; mapi_object_t contents; struct mapi_SRestriction res; struct SPropTagArray *SPropTagArray; struct SRowSet SRowSet; mapi_id_array_t msg_id_array; mapi_id_t msgid[50]; mapi_id_t id_folder; uint32_t i; uint32_t count = 0; /* Step 1. Logon */ mapi_object_init(&obj_store); mapi_object_init(&obj_folder); mapi_object_init(&contents); retval = OpenMsgStore(mt->session, &obj_store); mapitest_print_retval(mt, "OpenMsgStore"); if (retval != MAPI_E_SUCCESS) { ret = false; goto cleanup; } /* Step 2. Open Source Inbox folder */ retval = GetDefaultFolder(&obj_store, &id_folder, olFolderInbox); mapitest_print_retval(mt, "GetDefaultFolder"); if (retval != MAPI_E_SUCCESS) { ret = false; goto cleanup; } retval = OpenFolder(&obj_store, id_folder, &obj_folder); mapitest_print_retval(mt, "OpenFolder"); if (retval != MAPI_E_SUCCESS) { ret = false; goto cleanup; } retval = GetContentsTable(&(obj_folder), &(contents), 0, &count); mapitest_print_retval(mt, "GetContentsTable"); if (retval != MAPI_E_SUCCESS) { ret = false; goto cleanup; } /* Step 3. Create sample messages */ mapi_id_array_init(mt->mapi_ctx->mem_ctx, &msg_id_array); for (i = 0; i < 3; i++) { mapi_object_init(&obj_message); ret = mapitest_common_message_create(mt, &obj_folder, &obj_message, MT_MAIL_SUBJECT); if (!ret) { mapitest_print(mt, "failed to create message %i\n", i); ret = false; goto cleanup; } retval = SaveChangesMessage(&obj_folder, &obj_message, KeepOpenReadOnly); mapitest_print_retval(mt, "SaveChangesMessage"); if (retval != MAPI_E_SUCCESS) { ret = false; goto cleanup; } mapi_id_array_add_obj(&msg_id_array, &obj_message); mapi_object_release(&obj_message); } /* Step 4. Apply a filter */ res.rt = RES_PROPERTY; res.res.resProperty.relop = RES_PROPERTY; res.res.resProperty.ulPropTag = PR_SUBJECT; res.res.resProperty.lpProp.ulPropTag = PR_SUBJECT; res.res.resProperty.lpProp.value.lpszA = MT_MAIL_SUBJECT; retval = Restrict(&(contents), &res, NULL); mapitest_print_retval(mt, "Restrict"); if (retval != MAPI_E_SUCCESS) { ret = false; goto cleanup; } /* Step 5. Get the filtered rows */ SPropTagArray = set_SPropTagArray(mt->mem_ctx, 0x1, PR_MID); SetColumns(&(contents), SPropTagArray); mapitest_print_retval(mt, "SetColumns"); MAPIFreeBuffer(SPropTagArray); retval = QueryRows(&(contents), 50, TBL_NOADVANCE, &SRowSet); mapitest_print_retval(mt, "QueryRows"); if (retval == MAPI_E_SUCCESS) { for (i = 0; i < SRowSet.cRows; ++i) { msgid[i] = SRowSet.aRow[i].lpProps[0].value.d; } mapitest_print(mt, "%i Messages created successfully\n", SRowSet.cRows); } /* Step 6. Delete Messages */ retval = HardDeleteMessage(&obj_folder, msgid, i); mapitest_print_retval(mt, "HardDeleteMessage"); if (retval != MAPI_E_SUCCESS) { ret = false; goto cleanup; } /* Step 7. Check the restriction again */ retval = QueryRows(&(contents), 50, TBL_NOADVANCE, &SRowSet); mapitest_print_retval(mt, "QueryRows"); if ( retval != MAPI_E_SUCCESS ) { ret = false; goto cleanup; } if (SRowSet.cRows == 0) { mapitest_print(mt, "successfully deleted messages\n"); } else { mapitest_print(mt, "failed to delete messages\n"); ret = false; } cleanup: /* Release */ mapi_object_release(&contents); mapi_object_release(&obj_folder); mapi_object_release(&obj_store); return ret; } /** \details Test the HardDeleteMessagesAndSubfolder (0x92) operation. This function: -# Creates a filled test folder -# Creates 2 subdirectories in the test folder -# Hard deletes the sample messages and subdirectories \param mt pointer to the top-level mapitest structure \return true on success, otherwise false */ _PUBLIC_ bool mapitest_oxcfold_HardDeleteMessagesAndSubfolders(struct mapitest *mt) { struct mt_common_tf_ctx *context; enum MAPISTATUS retval; bool ret = true; mapi_object_t obj_htable; mapi_object_t subfolder1; mapi_object_t subfolder2; uint32_t unread = 0; uint32_t total = 0; /* Step 1. Logon and create a filled test folder */ if (! mapitest_common_setup(mt, &obj_htable, NULL)) { return false; } context = mt->priv; /* Step 2. Create two subfolders */ mapi_object_init(&subfolder1); retval = CreateFolder(&(context->obj_test_folder), FOLDER_GENERIC, "SubFolder1", NULL /*folder comment*/, OPEN_IF_EXISTS, &subfolder1); mapi_object_release(&subfolder1); mapitest_print_retval(mt, "Create Subfolder1"); if (retval != MAPI_E_SUCCESS) { ret = false; goto cleanup; } mapi_object_init(&subfolder2); retval = CreateFolder(&(context->obj_test_folder), FOLDER_GENERIC, "SubFolder2", NULL /*folder comment*/, OPEN_IF_EXISTS, &subfolder2); mapi_object_release(&subfolder2); mapitest_print_retval(mt, "Create Subfolder2"); if (retval != MAPI_E_SUCCESS) { ret = false; goto cleanup; } retval = GetFolderItemsCount(&(context->obj_test_folder), &unread, &total); mapitest_print_retval(mt, "GetFolderItemsCount"); if (retval != MAPI_E_SUCCESS) { ret = false; goto cleanup; } mapitest_print(mt, "* Folder count: %i (%i unread)\n", total, unread); /* Step 3. Hard delete contents */ retval = HardDeleteMessagesAndSubfolders(&(context->obj_test_folder)); mapitest_print_retval(mt, "HardDeleteMessagesAndSubfolders"); if (retval != MAPI_E_SUCCESS) { ret = false; goto cleanup; } /* Step 4. Check successful deletion */ retval = GetFolderItemsCount(&(context->obj_test_folder), &unread, &total); mapitest_print_retval(mt, "GetFolderItemsCount"); if (retval != MAPI_E_SUCCESS) { ret = false; goto cleanup; } mapitest_print(mt, "* Folder count: %i (%i unread)\n", total, unread); if (total != 0 || unread != 0) { ret = false; } cleanup: /* Cleanup and release */ mapi_object_release(&obj_htable); mapitest_common_cleanup(mt); return ret; } /** \details Test the DeleteMessages (0x1e) operation This function: -# Log on the user private mailbox -# Open the top of information store -# Create a test folder -# Create and save three messages -# Save the messages -# Delete the messages -# Delete the test folder \param mt pointer on the top-level mapitest structure \return true on success, otherwise false */ _PUBLIC_ bool mapitest_oxcfold_DeleteMessages(struct mapitest *mt) { enum MAPISTATUS retval; mapi_object_t obj_store; mapi_id_t id_folder; mapi_object_t obj_folder; mapi_object_t obj_top; mapi_object_t obj_message1; mapi_object_t obj_message2; mapi_object_t obj_message3; mapi_id_t id_msgs[3]; bool ret = true; /* success */ mapi_object_init(&obj_store); mapi_object_init(&obj_folder); mapi_object_init(&obj_top); mapi_object_init(&obj_message1); mapi_object_init(&obj_message2); mapi_object_init(&obj_message3); /* Step 1. Logon */ retval = OpenMsgStore(mt->session, &obj_store); mapitest_print_retval_clean(mt, "OpenMsgStore", retval); if (retval != MAPI_E_SUCCESS) { ret = false; goto cleanup; } /* Step 2. Open Top Information Store folder */ retval = GetDefaultFolder(&obj_store, &id_folder, olFolderTopInformationStore); if (retval != MAPI_E_SUCCESS) { ret = false; goto cleanup; } retval = OpenFolder(&obj_store, id_folder, &obj_folder); if (retval != MAPI_E_SUCCESS) { ret = false; goto cleanup; } /* Step 3. Create the top test folder */ mapitest_print(mt, "* Create GENERIC \"%s\" folder\n", MT_DIRNAME_TOP); retval = CreateFolder(&obj_folder, FOLDER_GENERIC, MT_DIRNAME_TOP, NULL, OPEN_IF_EXISTS, &obj_top); mapitest_print_retval_clean(mt, "CreateFolder", retval); if (retval != MAPI_E_SUCCESS) { ret = false; goto cleanup; } /* Step 4. Create the messages */ retval = CreateMessage(&obj_top, &obj_message1); mapitest_print_retval_clean(mt, "CreateMessage - 1", retval); if (retval != MAPI_E_SUCCESS) { ret = false; goto cleanup; } retval = CreateMessage(&obj_top, &obj_message2); mapitest_print_retval_clean(mt, "CreateMessage - 2", retval); if (retval != MAPI_E_SUCCESS) { ret = false; goto cleanup; } retval = CreateMessage(&obj_top, &obj_message3); mapitest_print_retval_clean(mt, "CreateMessage - 3", retval); if (retval != MAPI_E_SUCCESS) { ret = false; goto cleanup; } /* Step 5. Save the messages */ retval = SaveChangesMessage(&obj_top, &obj_message1, KeepOpenReadOnly); mapitest_print_retval_clean(mt, "SaveChangesMessage - 1", retval); if (retval != MAPI_E_SUCCESS) { ret = false; goto cleanup; } retval = SaveChangesMessage(&obj_top, &obj_message2, KeepOpenReadOnly); mapitest_print_retval_clean(mt, "SaveChangesMessage - 2", retval); if (retval != MAPI_E_SUCCESS) { ret = false; goto cleanup; } retval = SaveChangesMessage(&obj_top, &obj_message3, KeepOpenReadOnly); mapitest_print_retval_clean(mt, "SaveChangesMessage - 3", retval); if (retval != MAPI_E_SUCCESS) { ret = false; goto cleanup; } /* Step 6. Delete the saved messages */ id_msgs[0] = mapi_object_get_id(&obj_message1); id_msgs[1] = mapi_object_get_id(&obj_message2); id_msgs[2] = mapi_object_get_id(&obj_message3); retval = DeleteMessage(&obj_top, id_msgs, 3); mapitest_print_retval_clean(mt, "DeleteMessage", retval); if (retval != MAPI_E_SUCCESS) { ret = false; goto cleanup; } /* Step 7. DeleteFolder on the top folder */ retval = DeleteFolder(&obj_folder, mapi_object_get_id(&obj_top), DEL_MESSAGES|DEL_FOLDERS|DELETE_HARD_DELETE, NULL); mapitest_print_retval_clean(mt, "DeleteFolder - top", retval); if (retval != MAPI_E_SUCCESS) { ret = false; goto cleanup; } /* Release */ cleanup: mapi_object_release(&obj_message3); mapi_object_release(&obj_message2); mapi_object_release(&obj_message1); mapi_object_release(&obj_top); mapi_object_release(&obj_folder); mapi_object_release(&obj_store); return ret; } openchange-2.0/utils/mapitest/modules/module_oxcfxics.c000066400000000000000000000525631223057412600234740ustar00rootroot00000000000000/* Stand-alone MAPI testsuite OpenChange Project - BULK DATA TRANSFER PROTOCOL operations Copyright (C) Julien Kerihuel 2008 Copyright (C) Brad Hards 2010-2011 This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see . */ #include "utils/mapitest/mapitest.h" #include "utils/mapitest/proto.h" /** \file module_oxcfxics.c \brief Bulk Data Transfer Protocol test suite */ /** \details Test the GetLocalReplicaIds (0x7f) operation This function: -# Log on private message store -# Reserve a range of Ids */ _PUBLIC_ bool mapitest_oxcfxics_GetLocalReplicaIds(struct mapitest *mt) { enum MAPISTATUS retval; mapi_object_t obj_store; struct GUID ReplGuid; uint8_t GlobalCount[6]; char *guid; /* Step 1. Logon */ mapi_object_init(&obj_store); retval = OpenMsgStore(mt->session, &obj_store); mapitest_print_retval(mt, "OpenMsgStore"); if (retval != MAPI_E_SUCCESS) { return false; } /* Step 2. Reserve a range of IDs */ retval = GetLocalReplicaIds(&obj_store, 0x1000, &ReplGuid, GlobalCount); mapitest_print_retval(mt, "GetLocalReplicaIds"); if (retval != MAPI_E_SUCCESS) { return false; } guid = GUID_string(mt->mem_ctx, &ReplGuid); mapitest_print(mt, "* %-35s: %s\n", "ReplGuid", guid); mapitest_print(mt, "* %-35s: %02x %02x %02x %02x %02x %02x\n", "GlobalCount", GlobalCount[0], GlobalCount[1], GlobalCount[2], GlobalCount[3], GlobalCount[4], GlobalCount[5]); talloc_free(guid); mapi_object_release(&obj_store); return true; } /** \details Test the FastTransferDestinationConfigure (0x53), TellVersion (0x86) and FastTransferDestinationPutBuffer (0x54) operations This function: -# Log on private message store -# Creates a test folder -# Setup destination -# Sends the "server version" */ _PUBLIC_ bool mapitest_oxcfxics_DestConfigure(struct mapitest *mt) { enum MAPISTATUS retval; struct mt_common_tf_ctx *context; mapi_object_t obj_htable; mapi_object_t obj_context; mapi_object_t destfolder; DATA_BLOB put_buffer_data; uint16_t usedSize; bool ret = true; /* Logon */ if (! mapitest_common_setup(mt, &obj_htable, NULL)) { return false; } context = mt->priv; /* Create destfolder */ mapi_object_init(&destfolder); mapi_object_init(&obj_context); retval = CreateFolder(&(context->obj_test_folder), FOLDER_GENERIC, "DestFolder", NULL /*folder comment*/, OPEN_IF_EXISTS, &destfolder); mapitest_print_retval_clean(mt, "Create DestFolder", retval); if (retval != MAPI_E_SUCCESS) { ret = false; goto cleanup; } retval = FXDestConfigure(&(context->obj_test_folder), FastTransferDest_CopyTo, &obj_context); mapitest_print_retval_clean(mt, "FXDestConfigure", retval); if (retval != MAPI_E_SUCCESS) { ret = false; goto cleanup; } /* Send server version */ retval = TellVersion(&obj_context, mt->info.rgwServerVersion); mapitest_print_retval_clean(mt, "TellVersion", retval); if (retval != MAPI_E_SUCCESS) { ret = false; goto cleanup; } /* start top folder, followed by end folder */ put_buffer_data = data_blob_named("\x03\x00\x09\x40\x03\x00\x0b\x40", 8, "putbuffer"); retval = FXPutBuffer(&obj_context, &put_buffer_data, &usedSize); mapitest_print_retval_clean(mt, "FXPutBuffer", retval); if (retval != MAPI_E_SUCCESS) { ret = false; goto cleanup; } data_blob_free(&put_buffer_data); if (usedSize != 8) { mapitest_print(mt, "unexpected used count 0x%04x\n", usedSize); ret = false; goto cleanup; } cleanup: /* Cleanup and release */ mapi_object_release(&obj_context); mapi_object_release(&destfolder); mapi_object_release(&obj_htable); mapitest_common_cleanup(mt); return ret; } /** \details Test the FastTransferCopyFolder (0x4C), FastTransferGetBuffer (0x4E) and TellVersion (0x86) operations This function: -# Log on private message store -# Creates a test folder -# Setup source -# Sends the "server version" */ _PUBLIC_ bool mapitest_oxcfxics_CopyFolder(struct mapitest *mt) { enum MAPISTATUS retval; struct mt_common_tf_ctx *context; mapi_object_t obj_htable; mapi_object_t obj_context; mapi_object_t sourcefolder; bool ret = true; enum TransferStatus transferStatus; uint16_t progress; uint16_t totalSteps; DATA_BLOB transferdata; struct fx_parser_context *parser; /* Logon */ if (! mapitest_common_setup(mt, &obj_htable, NULL)) { return false; } context = mt->priv; /* Create source folder */ mapi_object_init(&sourcefolder); mapi_object_init(&obj_context); retval = CreateFolder(&(context->obj_test_folder), FOLDER_GENERIC, "SourceCopyFolder", NULL /*folder comment*/, OPEN_IF_EXISTS, &sourcefolder); mapitest_print_retval_clean(mt, "Create SourceCopyFolder", retval); if (retval != MAPI_E_SUCCESS) { ret = false; goto cleanup; } retval = FXCopyFolder(&(context->obj_test_folder), FastTransferCopyFolder_CopySubfolders, FastTransfer_Unicode, &obj_context); mapitest_print_retval_clean(mt, "FXCopyFolder", retval); if (retval != MAPI_E_SUCCESS) { ret = false; goto cleanup; } /* Send server version */ retval = TellVersion(&obj_context, mt->info.rgwServerVersion); mapitest_print_retval_clean(mt, "TellVersion", retval); if (retval != MAPI_E_SUCCESS) { ret = false; goto cleanup; } retval = FXGetBuffer(&obj_context, 0, &transferStatus, &progress, &totalSteps, &transferdata); mapitest_print_retval_clean(mt, "FXGetBuffer", retval); if (retval != MAPI_E_SUCCESS) { ret = false; goto cleanup; } if (transferStatus != TransferStatus_Done) { mapitest_print(mt, "unexpected transferStatus 0x%04x\n", transferStatus); ret = false; goto cleanup; } if (progress != totalSteps) { mapitest_print(mt, "unexpected final step count, progress 0x%04x, total 0x%04x\n", progress, totalSteps); ret = false; goto cleanup; } parser = fxparser_init(mt->mem_ctx, NULL); fxparser_parse(parser, &transferdata); talloc_free(parser); // TODO: verify that the buffer is as expected cleanup: /* Cleanup and release */ mapi_object_release(&obj_context); mapi_object_release(&sourcefolder); mapi_object_release(&obj_htable); mapitest_common_cleanup(mt); return ret; } /** \details Test the FastTransferCopyMessages (0x4B) and FastTransferGetBuffer (0x4E) operations This function: -# Log on private message store -# Cremapidump_fx_bufferates a test folder -# Setup source -# Get data */ _PUBLIC_ bool mapitest_oxcfxics_CopyMessages(struct mapitest *mt) { enum MAPISTATUS retval; struct mt_common_tf_ctx *context; mapi_object_t obj_htable; mapi_object_t obj_context; mapi_object_t sourcefolder; mapi_id_array_t mids; int i; bool ret = true; enum TransferStatus transferStatus; uint16_t progress; uint16_t totalSteps; DATA_BLOB transferdata; struct fx_parser_context *parser; /* Logon */ if (! mapitest_common_setup(mt, &obj_htable, NULL)) { return false; } context = mt->priv; /* Create source folder */ mapi_object_init(&sourcefolder); mapi_object_init(&obj_context); retval = CreateFolder(&(context->obj_test_folder), FOLDER_GENERIC, "SourceCopyMessages", NULL /*folder comment*/, OPEN_IF_EXISTS, &sourcefolder); mapitest_print_retval_clean(mt, "Create SourceCopyMessages", retval); if (retval != MAPI_E_SUCCESS) { ret = false; goto cleanup; } retval = mapi_id_array_init(mt->mapi_ctx->mem_ctx, &mids); if (retval != MAPI_E_SUCCESS) { mapitest_print_retval_clean(mt, "mapi_id_array_init", retval); ret = false; goto cleanup; } for (i = 0; i < 5; ++i) { retval = mapi_id_array_add_obj(&mids, &(context->obj_test_msg[i])); if (retval != MAPI_E_SUCCESS) { mapitest_print_retval_clean(mt, "mapi_id_array_add_obj", retval); ret = false; goto cleanup; } } retval = FXCopyMessages(&(context->obj_test_folder), &mids, FastTransferCopyMessage_BestBody, FastTransfer_Unicode, &obj_context); mapitest_print_retval_clean(mt, "FXCopyMessages", retval); if (retval != MAPI_E_SUCCESS) { ret = false; goto cleanup; } retval = FXGetBuffer(&obj_context, 0, &transferStatus, &progress, &totalSteps, &transferdata); mapitest_print_retval_clean(mt, "FXGetBuffer", retval); if (retval != MAPI_E_SUCCESS) { ret = false; goto cleanup; } if (transferStatus != TransferStatus_Done) { mapitest_print(mt, "unexpected transferStatus 0x%04x\n", transferStatus); ret = false; goto cleanup; } if (progress != totalSteps) { mapitest_print(mt, "unexpected final step count, progress 0x%04x, total 0x%04x\n", progress, totalSteps); ret = false; goto cleanup; } parser = fxparser_init(mt->mem_ctx, NULL); fxparser_parse(parser, &transferdata); talloc_free(parser); // TODO: verify that the buffer is as expected cleanup: /* Cleanup and release */ mapi_object_release(&obj_context); mapi_object_release(&sourcefolder); mapi_object_release(&obj_htable); mapitest_common_cleanup(mt); return ret; } /** \details Test the FastTransferCopyTo (0x4D) and FastTransferGetBuffer (0x4E) operations This function: -# Log on private message store -# Creates a test folder -# Setup source -# Get data */ _PUBLIC_ bool mapitest_oxcfxics_CopyTo(struct mapitest *mt) { enum MAPISTATUS retval; struct mt_common_tf_ctx *context; mapi_object_t obj_htable; mapi_object_t obj_context; mapi_object_t sourcefolder; mapi_id_array_t mids; struct SPropTagArray *propsToExclude; int i; bool ret = true; enum TransferStatus transferStatus; uint16_t progress; uint16_t totalSteps; DATA_BLOB transferdata; struct fx_parser_context *parser; /* Logon */ if (! mapitest_common_setup(mt, &obj_htable, NULL)) { return false; } context = mt->priv; /* Create source folder */ mapi_object_init(&sourcefolder); mapi_object_init(&obj_context); retval = CreateFolder(&(context->obj_test_folder), FOLDER_GENERIC, "SourceCopyTo", NULL /*folder comment*/, OPEN_IF_EXISTS, &sourcefolder); mapitest_print_retval_clean(mt, "Create SourceCopyTo", retval); if (retval != MAPI_E_SUCCESS) { ret = false; goto cleanup; } retval = mapi_id_array_init(mt->mapi_ctx->mem_ctx, &mids); if (retval != MAPI_E_SUCCESS) { mapitest_print_retval_clean(mt, "mapi_id_array_init", retval); ret = false; goto cleanup; } for (i = 0; i < 5; ++i) { retval = mapi_id_array_add_obj(&mids, &(context->obj_test_msg[i])); if (retval != MAPI_E_SUCCESS) { mapitest_print_retval_clean(mt, "mapi_id_array_add_obj", retval); ret = false; goto cleanup; } } propsToExclude = talloc_zero(mt->mem_ctx, struct SPropTagArray); retval = FXCopyTo(&(context->obj_test_folder), 0, FastTransferCopyTo_BestBody, FastTransfer_Unicode, propsToExclude, &obj_context); mapitest_print_retval_clean(mt, "FXCopyTo", retval); if (retval != MAPI_E_SUCCESS) { ret = false; goto cleanup; } retval = FXGetBuffer(&obj_context, 0, &transferStatus, &progress, &totalSteps, &transferdata); mapitest_print_retval_clean(mt, "FXGetBuffer", retval); if (retval != MAPI_E_SUCCESS) { ret = false; goto cleanup; } if (transferStatus != TransferStatus_Done) { mapitest_print(mt, "unexpected transferStatus 0x%04x\n", transferStatus); ret = false; goto cleanup; } if (progress != totalSteps) { mapitest_print(mt, "unexpected final step count, progress 0x%04x, total 0x%04x\n", progress, totalSteps); ret = false; goto cleanup; } parser = fxparser_init(mt->mem_ctx, NULL); fxparser_parse(parser, &transferdata); talloc_free(parser); // TODO: verify that the buffer is as expected cleanup: /* Cleanup and release */ mapi_object_release(&obj_context); mapi_object_release(&sourcefolder); mapi_object_release(&obj_htable); mapitest_common_cleanup(mt); return ret; } /** \details Test the FastTransferCopyProperties (0x69) and FastTransferSourceGetBuffer (0x4e) operations This function: -# Log on private message store -# Creates a test folder -# Setup source -# Get data */ _PUBLIC_ bool mapitest_oxcfxics_CopyProperties(struct mapitest *mt) { enum MAPISTATUS retval; struct mt_common_tf_ctx *context; mapi_object_t obj_htable; mapi_object_t obj_context; mapi_object_t sourcefolder; struct SPropTagArray *props; bool ret = true; enum TransferStatus transferStatus; uint16_t progress; uint16_t totalSteps; DATA_BLOB transferdata; struct fx_parser_context *parser; /* Logon */ if (! mapitest_common_setup(mt, &obj_htable, NULL)) { return false; } context = mt->priv; /* Create source folder */ mapi_object_init(&sourcefolder); mapi_object_init(&obj_context); retval = CreateFolder(&(context->obj_test_folder), FOLDER_GENERIC, "SourceCopyProperties", NULL /*folder comment*/, OPEN_IF_EXISTS, &sourcefolder); mapitest_print_retval_clean(mt, "Create SourceCopyProperties", retval); if (retval != MAPI_E_SUCCESS) { ret = false; goto cleanup; } props = set_SPropTagArray(mt->mem_ctx, 0x3, PR_DISPLAY_NAME, PR_FOLDER_TYPE, PidTagLastModificationTime); retval = FXCopyProperties(&(context->obj_test_folder), 0 /* level */, 0 /*copyflags */, FastTransfer_Unicode, props, &obj_context); mapitest_print_retval_clean(mt, "FXCopyProperties", retval); if (retval != MAPI_E_SUCCESS) { ret = false; goto cleanup; } retval = FXGetBuffer(&obj_context, 0, &transferStatus, &progress, &totalSteps, &transferdata); mapitest_print_retval_clean(mt, "FXGetBuffer", retval); if (retval != MAPI_E_SUCCESS) { ret = false; goto cleanup; } if (transferStatus != TransferStatus_Done) { mapitest_print(mt, "unexpected transferStatus 0x%04x\n", transferStatus); ret = false; goto cleanup; } if (progress != totalSteps) { mapitest_print(mt, "unexpected final step count, progress 0x%04x, total 0x%04x\n", progress, totalSteps); ret = false; goto cleanup; } parser = fxparser_init(mt->mem_ctx, NULL); fxparser_parse(parser, &transferdata); talloc_free(parser); // TODO: verify that the buffer is as expected cleanup: /* Cleanup and release */ mapi_object_release(&obj_context); mapi_object_release(&sourcefolder); mapi_object_release(&obj_htable); mapitest_common_cleanup(mt); return ret; } /** \details Test the RopSynchronizationConfigure (0x70), RopSynchronizationUploadStateStreamBegin (0x75), RopSynchronizationUploadStateStreamContinue (0x76), RopSynchronizationUploadStateStreamEnd (0x77) and RopSynchronizationGetTransferState (0x82) operations This function: -# Log on private message store -# Creates a test folder -# Sets up sync configure context -# Uploads an empty ICS state -# cleans up. */ _PUBLIC_ bool mapitest_oxcfxics_SyncConfigure(struct mapitest *mt) { enum MAPISTATUS retval; struct mt_common_tf_ctx *context; mapi_object_t obj_htable; mapi_object_t obj_sync_context; mapi_object_t download_folder; mapi_object_t obj_transfer_state; DATA_BLOB restriction; DATA_BLOB ics_state; struct SPropTagArray *property_tags; bool ret = true; /* Logon */ if (! mapitest_common_setup(mt, &obj_htable, NULL)) { return false; } context = mt->priv; /* Create destfolder */ mapi_object_init(&download_folder); mapi_object_init(&obj_sync_context); mapi_object_init(&obj_transfer_state); retval = CreateFolder(&(context->obj_test_folder), FOLDER_GENERIC, "ICSDownloadFolder", NULL /*folder comment*/, OPEN_IF_EXISTS, &download_folder); mapitest_print_retval_clean(mt, "Create ICS Download Folder", retval); if (retval != MAPI_E_SUCCESS) { ret = false; goto cleanup; } property_tags = set_SPropTagArray(mt->mem_ctx, 0x0); restriction.length = 0; restriction.data = NULL; retval = ICSSyncConfigure(&download_folder, Hierarchy, FastTransfer_Unicode, SynchronizationFlag_Unicode, Eid | Cn, restriction, property_tags, &obj_sync_context); mapitest_print_retval_clean(mt, "ICSSyncConfigure", retval); if (retval != MAPI_E_SUCCESS) { ret = false; goto cleanup; } ics_state.length = 0; ics_state.data = NULL; retval = ICSSyncUploadStateBegin(&obj_sync_context, PidTagIdsetGiven, ics_state.length); mapitest_print_retval_clean(mt, "ICSSyncUploadStateBegin", retval); if (retval != MAPI_E_SUCCESS) { ret = false; goto cleanup; } retval = ICSSyncUploadStateContinue(&obj_sync_context, ics_state); mapitest_print_retval_clean(mt, "ICSSyncUploadStateContinue", retval); if (retval != MAPI_E_SUCCESS) { ret = false; goto cleanup; } retval = ICSSyncUploadStateEnd(&obj_sync_context); mapitest_print_retval_clean(mt, "ICSSyncUploadStateEnd", retval); if (retval != MAPI_E_SUCCESS) { ret = false; goto cleanup; } retval = ICSSyncGetTransferState(&obj_sync_context, &obj_transfer_state); mapitest_print_retval_clean(mt, "ICSSyncGetTransferState", retval); if (retval != MAPI_E_SUCCESS) { ret = false; goto cleanup; } cleanup: /* Cleanup and release */ mapi_object_release(&obj_transfer_state); mapi_object_release(&obj_sync_context); mapi_object_release(&download_folder); mapi_object_release(&obj_htable); mapitest_common_cleanup(mt); return ret; } /** \details Test the GetLocalReplicaId (0x7f) and SetLocalReplicaMidsetDeleted (0x93) operations This function: -# Log on private message store -# Creates a test folder -# Gets a local replica ID range -# Sets the local replica ID range as deleted (on the test folder) -# cleans up */ _PUBLIC_ bool mapitest_oxcfxics_SetLocalReplicaMidsetDeleted(struct mapitest *mt) { enum MAPISTATUS retval; struct mt_common_tf_ctx *context; mapi_object_t obj_htable; struct GUID ReplGuid; uint8_t GlobalCount[6]; uint8_t GlobalCountHigh[6]; char *guid; mapi_object_t testfolder; bool ret = true; /* Logon */ if (! mapitest_common_setup(mt, &obj_htable, NULL)) { return false; } context = mt->priv; /* Create test folder */ mapi_object_init(&testfolder); retval = CreateFolder(&(context->obj_test_folder), FOLDER_GENERIC, "ReplicaTestFolder", NULL /*folder comment*/, OPEN_IF_EXISTS, &testfolder); mapitest_print_retval_clean(mt, "Create ReplicaTestFolder", retval); if (retval != MAPI_E_SUCCESS) { ret = false; goto cleanup; } /* Get the local ID range */ retval = GetLocalReplicaIds(&(context->obj_store), 0x101, &ReplGuid, GlobalCount); mapitest_print_retval_clean(mt, "GetLocalReplicaIds", retval); if (retval != MAPI_E_SUCCESS) { ret = false; goto cleanup; } guid = GUID_string(mt->mem_ctx, &ReplGuid); mapitest_print(mt, "* %-35s: %s\n", "ReplGuid", guid); mapitest_print(mt, "* %-35s: %02x %02x %02x %02x %02x %02x\n", "GlobalCount", GlobalCount[0], GlobalCount[1], GlobalCount[2], GlobalCount[3], GlobalCount[4], GlobalCount[5]); talloc_free(guid); /* copy the returned global count range, and increment it by the range we asked for, less 1, since these ranges are inclusive */ memcpy(GlobalCountHigh, GlobalCount, 6); GlobalCountHigh[4] += 1; /* 0x100 */ /* delete the local ID range */ retval = SetLocalReplicaMidsetDeleted(&testfolder, ReplGuid, GlobalCount, GlobalCountHigh); mapitest_print_retval_clean(mt, "SetLocalReplicaMidsetDeleted", retval); if (retval != MAPI_E_SUCCESS) { ret = false; goto cleanup; } cleanup: /* Cleanup and release */ mapi_object_release(&testfolder); mapi_object_release(&obj_htable); mapitest_common_cleanup(mt); return ret; } /** \details Test the RopSynchronizationOpenCollector (0x7e), operation. This function: -# Log on private message store -# Creates a test folder -# Opens a sync collector context for content -# Opens a sync collector context for hierachy -# cleans up. */ _PUBLIC_ bool mapitest_oxcfxics_SyncOpenCollector(struct mapitest *mt) { enum MAPISTATUS retval; struct mt_common_tf_ctx *context; mapi_object_t obj_htable; mapi_object_t obj_sync_collector; mapi_object_t obj_sync_hierachy_collector; mapi_object_t collector_folder; bool ret = true; /* Logon */ if (! mapitest_common_setup(mt, &obj_htable, NULL)) { return false; } context = mt->priv; /* Create destfolder */ mapi_object_init(&collector_folder); mapi_object_init(&obj_sync_collector); mapi_object_init(&obj_sync_hierachy_collector); retval = CreateFolder(&(context->obj_test_folder), FOLDER_GENERIC, "ICSSyncCollector", NULL /*folder comment*/, OPEN_IF_EXISTS, &collector_folder); mapitest_print_retval_clean(mt, "Create ICS SyncCollector Folder", retval); if (retval != MAPI_E_SUCCESS) { ret = false; goto cleanup; } retval = ICSSyncOpenCollector(&collector_folder, true, &obj_sync_collector); mapitest_print_retval_clean(mt, "ICSSyncOpenCollector - Contents", retval); if (retval != MAPI_E_SUCCESS) { ret = false; goto cleanup; } retval = ICSSyncOpenCollector(&collector_folder, false, &obj_sync_hierachy_collector); mapitest_print_retval_clean(mt, "ICSSyncOpenCollector - Hierachy", retval); if (retval != MAPI_E_SUCCESS) { ret = false; goto cleanup; } cleanup: /* Cleanup and release */ mapi_object_release(&obj_sync_hierachy_collector); mapi_object_release(&obj_sync_collector); mapi_object_release(&collector_folder); mapi_object_release(&obj_htable); mapitest_common_cleanup(mt); return ret; } openchange-2.0/utils/mapitest/modules/module_oxcmsg.c000066400000000000000000001404251223057412600231410ustar00rootroot00000000000000/* Stand-alone MAPI testsuite OpenChange Project - E-MAIL OBJECT PROTOCOL operations Copyright (C) Julien Kerihuel 2008 Copyright (C) Brad Hards 2009 This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see . */ #include "utils/mapitest/mapitest.h" #include "utils/mapitest/proto.h" /** \file module_oxcmsg.c \brief Message and Attachment Object Protocol test suite */ /** \details Test the CreateMessage (0x6) operation This function: -# Log on the user private mailbox -# Open the Outbox folder -# Create the message -# Delete the message \param mt pointer on the top-level mapitest structure \return true on success, otherwise false */ _PUBLIC_ bool mapitest_oxcmsg_CreateMessage(struct mapitest *mt) { bool ret; mapi_object_t obj_store; mapi_object_t obj_folder; mapi_object_t obj_message; mapi_id_t id_msgs[1]; /* Step 1. Logon */ mapi_object_init(&obj_store); OpenMsgStore(mt->session, &obj_store); mapitest_print_retval(mt, "OpenMsgStore"); if (GetLastError() != MAPI_E_SUCCESS) { return false; } /* Step 2. Open Outbox folder */ mapi_object_init(&obj_folder); ret = mapitest_common_folder_open(mt, &obj_store, &obj_folder, olFolderOutbox); if (ret == false) return ret; /* Step 3. Create the message */ mapi_object_init(&obj_message); CreateMessage(&obj_folder, &obj_message); mapitest_print_retval(mt, "CreateMessage"); if (GetLastError() != MAPI_E_SUCCESS) { return false; } /* Step 4. Delete the message */ id_msgs[0] = mapi_object_get_id(&obj_message); DeleteMessage(&obj_folder, id_msgs, 1); mapitest_print_retval(mt, "DeleteMessage"); if (GetLastError() != MAPI_E_SUCCESS) { return false; } /* Release */ mapi_object_release(&obj_message); mapi_object_release(&obj_folder); mapi_object_release(&obj_store); return true; } #define OXCMSG_SETREADFLAGS "[OXCMSG] SetMessageReadFlag" /** \details Test the SetMessageReadFlag (0x11) operation This function: -# Log on the user private mailbox -# Open the Inbox folder -# Create a tmp message -# Play with SetMessageReadFlag -# Delete the message Note: We can test either SetMessageReadFlag was effective by checking its old/new value with GetProps on PR_MESSAGE_FLAGS property. \param mt pointer on the top-level mapitest structure \return true on success, otherwise false */ _PUBLIC_ bool mapitest_oxcmsg_SetMessageReadFlag(struct mapitest *mt) { bool ret; mapi_object_t obj_store; mapi_object_t obj_folder; mapi_object_t obj_message; struct SPropTagArray *SPropTagArray; struct SPropValue *lpProps; uint32_t cValues; mapi_id_t id_msgs[1]; uint32_t status= 0; /* Step 1. Logon */ mapi_object_init(&obj_store); OpenMsgStore(mt->session, &obj_store); mapitest_print_retval(mt, "OpenMsgStore"); if (GetLastError() != MAPI_E_SUCCESS) { return false; } /* Step 2. Open Outbox folder */ mapi_object_init(&obj_folder); ret = mapitest_common_folder_open(mt, &obj_store, &obj_folder, olFolderOutbox); if (ret == false) return ret; /* Step 3. Create the tmp message and save it */ mapi_object_init(&obj_message); ret = mapitest_common_message_create(mt, &obj_folder, &obj_message, OXCMSG_SETREADFLAGS); if (ret == false) return ret; SaveChangesMessage(&obj_folder, &obj_message, KeepOpenReadWrite); mapitest_print_retval(mt, "SaveChangesMessage"); if (GetLastError() != MAPI_E_SUCCESS) { return false; } /* Step 4. Play with SetMessageReadFlag */ SPropTagArray = set_SPropTagArray(mt->mem_ctx, 0x2, PR_MID, PR_MESSAGE_FLAGS); ret = true; /* 1. Retrieve and Save the original PR_MESSAGE_FLAGS value */ GetProps(&obj_message, 0, SPropTagArray, &lpProps, &cValues); if (GetLastError() != MAPI_E_SUCCESS) { return false; } if (cValues > 1) { status = lpProps[1].value.l; } MAPIFreeBuffer(lpProps); /* Set message flags as read */ SetMessageReadFlag(&obj_folder, &obj_message, MSGFLAG_READ); mapitest_print_retval_fmt(mt, "SetMessageReadFlag", "(%s)", "MSGFLAG_READ"); /* Check if the operation was successful */ GetProps(&obj_message, 0, SPropTagArray, &lpProps, &cValues); mapitest_print_retval(mt, "GetProps"); if (GetLastError() != MAPI_E_SUCCESS) { return false; } if (cValues > 1 && status != lpProps[1].value.l) { mapitest_print(mt, "* %-35s: PR_MESSAGE_FLAGS changed\n", "SetMessageReadFlag"); status = lpProps[1].value.l; } else { mapitest_print(mt, "* %-35s: PR_MESSAGE_FLAGS failed\n", "SetMessageReadFlag"); return false; } MAPIFreeBuffer(lpProps); /* Set the message flags as submitted */ SetMessageReadFlag(&obj_folder, &obj_message, MSGFLAG_SUBMIT); mapitest_print_retval_fmt(mt, "SetMessageReadFlag", "(%s)", "MSGFLAG_SUBMIT"); /* Check if the operation was successful */ GetProps(&obj_message, 0, SPropTagArray, &lpProps, &cValues); if (GetLastError() != MAPI_E_SUCCESS) { return false; } if (cValues > 1 && status != lpProps[1].value.l) { mapitest_print(mt, "* %-35s: PR_MESSAGE_FLAGS changed\n", "SetMessageReadFlag"); status = lpProps[1].value.l; } else { mapitest_print(mt, "* %-35s: PR_MESSAGE_FLAGS failed\n", "SetMessageReadFlag"); return false; } /* Step 5. Delete the message */ id_msgs[0] = mapi_object_get_id(&obj_message); DeleteMessage(&obj_folder, id_msgs, 1); mapitest_print_retval(mt, "DeleteMessage"); if (GetLastError() != MAPI_E_SUCCESS) { return false; } /* Release */ mapi_object_release(&obj_message); mapi_object_release(&obj_folder); mapi_object_release(&obj_store); MAPIFreeBuffer(SPropTagArray); return true; } /** \details Test the ModifyRecipients (0xe) operation This function: -# Log on the user private mailbox -# Open the Outbox folder -# Create the message -# Resolve recipients names -# Call ModifyRecipients operation for MAPI_TO, MAPI_CC, MAPI_BCC -# Delete the message \param mt pointer on the top-level mapitest structure \return true on success, otherwise false */ _PUBLIC_ bool mapitest_oxcmsg_ModifyRecipients(struct mapitest *mt) { enum MAPISTATUS retval; mapi_object_t obj_store; mapi_object_t obj_folder; mapi_object_t obj_message; mapi_id_t id_folder; char **username = NULL; struct SPropTagArray *SPropTagArray = NULL; struct PropertyValue_r value; struct PropertyRowSet_r *RowSet = NULL; struct SRowSet *SRowSet = NULL; struct PropertyTagArray_r *flaglist = NULL; mapi_id_t id_msgs[1]; /* Step 1. Logon */ mapi_object_init(&obj_store); retval = OpenMsgStore(mt->session, &obj_store); mapitest_print_retval(mt, "OpenMsgStore"); if (GetLastError() != MAPI_E_SUCCESS) { return false; } /* Step 2. Open Outbox folder */ retval = GetDefaultFolder(&obj_store, &id_folder, olFolderOutbox); mapitest_print_retval(mt, "GetDefaultFolder"); if (GetLastError() != MAPI_E_SUCCESS) { return false; } mapi_object_init(&obj_folder); retval = OpenFolder(&obj_store, id_folder, &obj_folder); mapitest_print_retval(mt, "OpenFolder"); if (GetLastError() != MAPI_E_SUCCESS) { return false; } /* Step 3. Create the message */ mapi_object_init(&obj_message); retval = CreateMessage(&obj_folder, &obj_message); mapitest_print_retval(mt, "CreateMessage"); if (GetLastError() != MAPI_E_SUCCESS) { return false; } /* Step 4. Resolve the recipients and call ModifyRecipients */ SPropTagArray = set_SPropTagArray(mt->mem_ctx, 0xA, PR_ENTRYID, PR_DISPLAY_NAME_UNICODE, PR_OBJECT_TYPE, PR_DISPLAY_TYPE, PR_TRANSMITTABLE_DISPLAY_NAME_UNICODE, PR_EMAIL_ADDRESS_UNICODE, PR_ADDRTYPE_UNICODE, PR_SEND_RICH_INFO, PR_7BIT_DISPLAY_NAME_UNICODE, PR_SMTP_ADDRESS_UNICODE); username = talloc_array(mt->mem_ctx, char *, 2); username[0] = (char *)mt->profile->mailbox; username[1] = NULL; retval = ResolveNames(mapi_object_get_session(&obj_message), (const char **)username, SPropTagArray, &RowSet, &flaglist, MAPI_UNICODE); mapitest_print_retval_clean(mt, "ResolveNames", retval); if (retval != MAPI_E_SUCCESS) { return false; } if (!RowSet) { mapitest_print(mt, "Null RowSet\n"); return false; } if (!RowSet->cRows) { mapitest_print(mt, "No values in RowSet\n"); MAPIFreeBuffer(RowSet); return false; } value.ulPropTag = PR_SEND_INTERNET_ENCODING; value.value.l = 0; PropertyRowSet_propcpy(mt->mem_ctx, RowSet, value); SRowSet = talloc_zero(RowSet, struct SRowSet); cast_PropertyRowSet_to_SRowSet(SRowSet, RowSet, SRowSet); SetRecipientType(&(SRowSet->aRow[0]), MAPI_TO); mapitest_print_retval(mt, "SetRecipientType"); retval = ModifyRecipients(&obj_message, SRowSet); mapitest_print_retval_fmt(mt, "ModifyRecipients", "(%s)", "MAPI_TO"); if (retval != MAPI_E_SUCCESS) { MAPIFreeBuffer(RowSet); MAPIFreeBuffer(flaglist); return false; } SetRecipientType(&(SRowSet->aRow[0]), MAPI_CC); mapitest_print_retval(mt, "SetRecipientType"); retval = ModifyRecipients(&obj_message, SRowSet); mapitest_print_retval_fmt(mt, "ModifyRecipients", "(%s)", "MAPI_CC"); if (retval != MAPI_E_SUCCESS) { MAPIFreeBuffer(RowSet); MAPIFreeBuffer(flaglist); return false; } SetRecipientType(&(SRowSet->aRow[0]), MAPI_BCC); mapitest_print_retval(mt, "SetRecipientType"); retval = ModifyRecipients(&obj_message, SRowSet); mapitest_print_retval_fmt(mt, "ModifyRecipients", "(%s)", "MAPI_BCC"); if (retval != MAPI_E_SUCCESS) { MAPIFreeBuffer(RowSet); MAPIFreeBuffer(flaglist); return false; } /* Step 5. Delete the message */ id_msgs[0] = mapi_object_get_id(&obj_message); retval = DeleteMessage(&obj_folder, id_msgs, 1); mapitest_print_retval(mt, "DeleteMessage"); if (retval != MAPI_E_SUCCESS) { MAPIFreeBuffer(RowSet); MAPIFreeBuffer(flaglist); return false; } /* Release */ MAPIFreeBuffer(RowSet); MAPIFreeBuffer(flaglist); mapi_object_release(&obj_message); mapi_object_release(&obj_folder); mapi_object_release(&obj_store); return true; } /** \details Test the RemoveAllRecipients (0xd) operation This function: -# Log on the use private mailbox -# Open the Outbox folder -# Create the message, set recipients -# Save the message -# Remove all recipients -# Delete the message \param mt point on the top-level mapitest structure \return true on success, otherwise false */ _PUBLIC_ bool mapitest_oxcmsg_RemoveAllRecipients(struct mapitest *mt) { enum MAPISTATUS retval; bool ret = false; mapi_object_t obj_store; mapi_object_t obj_folder; mapi_object_t obj_message; mapi_id_t id_folder; char **username = NULL; struct SPropTagArray *SPropTagArray = NULL; struct PropertyValue_r value; struct PropertyRowSet_r *RowSet = NULL; struct SRowSet *SRowSet = NULL; struct PropertyTagArray_r *flaglist = NULL; mapi_id_t id_msgs[1]; /* Step 1. Logon */ mapi_object_init(&obj_store); retval = OpenMsgStore(mt->session, &obj_store); mapitest_print_retval(mt, "OpenMsgStore"); if (GetLastError() != MAPI_E_SUCCESS) { return false; } /* Step 2. Open Outbox folder */ retval = GetDefaultFolder(&obj_store, &id_folder, olFolderInbox); mapitest_print_retval(mt, "GetDefaultFolder"); if (GetLastError() != MAPI_E_SUCCESS) { return false; } mapi_object_init(&obj_folder); retval = OpenFolder(&obj_store, id_folder, &obj_folder); mapitest_print_retval(mt, "OpenFolder"); if (GetLastError() != MAPI_E_SUCCESS) { return false; } /* Step 3. Create the message */ mapi_object_init(&obj_message); retval = CreateMessage(&obj_folder, &obj_message); mapitest_print_retval(mt, "CreateMessage"); if (GetLastError() != MAPI_E_SUCCESS) { return false; } SPropTagArray = set_SPropTagArray(mt->mem_ctx, 0xA, PR_ENTRYID, PR_DISPLAY_NAME_UNICODE, PR_OBJECT_TYPE, PR_DISPLAY_TYPE, PR_TRANSMITTABLE_DISPLAY_NAME_UNICODE, PR_EMAIL_ADDRESS_UNICODE, PR_ADDRTYPE_UNICODE, PR_SEND_RICH_INFO, PR_7BIT_DISPLAY_NAME_UNICODE, PR_SMTP_ADDRESS_UNICODE); username = talloc_array(mt->mem_ctx, char *, 2); username[0] = (char *)mt->profile->mailbox; username[1] = NULL; retval = ResolveNames(mapi_object_get_session(&obj_message), (const char **)username, SPropTagArray, &RowSet, &flaglist, MAPI_UNICODE); mapitest_print_retval_clean(mt, "ResolveNames", retval); if (retval != MAPI_E_SUCCESS) { return false; } if (!RowSet) { mapitest_print(mt, "Null RowSet\n"); return false; } if (!RowSet->cRows) { mapitest_print(mt, "No values in RowSet\n"); MAPIFreeBuffer(RowSet); return false; } value.ulPropTag = PR_SEND_INTERNET_ENCODING; value.value.l = 0; PropertyRowSet_propcpy(mt->mem_ctx, RowSet, value); SRowSet = talloc_zero(RowSet, struct SRowSet); cast_PropertyRowSet_to_SRowSet(SRowSet, RowSet, SRowSet); SetRecipientType(&(SRowSet->aRow[0]), MAPI_TO); retval = ModifyRecipients(&obj_message, SRowSet); mapitest_print_retval_fmt(mt, "ModifyRecipients", "(%s)", "MAPI_TO"); if (GetLastError() != MAPI_E_SUCCESS) { MAPIFreeBuffer(RowSet); MAPIFreeBuffer(flaglist); return false; } SetRecipientType(&(SRowSet->aRow[0]), MAPI_CC); retval = ModifyRecipients(&obj_message, SRowSet); mapitest_print_retval_fmt(mt, "ModifyRecipients", "(%s)", "MAPI_CC"); if (GetLastError() != MAPI_E_SUCCESS) { MAPIFreeBuffer(RowSet); MAPIFreeBuffer(flaglist); return false; } SetRecipientType(&(SRowSet->aRow[0]), MAPI_BCC); retval = ModifyRecipients(&obj_message, SRowSet); mapitest_print_retval_fmt(mt, "ModifyRecipients", "(%s)", "MAPI_BCC"); if (GetLastError() != MAPI_E_SUCCESS) { MAPIFreeBuffer(RowSet); MAPIFreeBuffer(flaglist); return false; } ret = true; /* Step 4. Remove all recipients */ retval = RemoveAllRecipients(&obj_message); mapitest_print_retval(mt, "RemoveAllRecipients"); if (GetLastError() != MAPI_E_SUCCESS) { MAPIFreeBuffer(RowSet); MAPIFreeBuffer(flaglist); ret = false; } /* Step 5. Save the message */ retval = SaveChangesMessage(&obj_folder, &obj_message, KeepOpenReadOnly); mapitest_print_retval(mt, "SaveChangesMessage"); if (GetLastError() != MAPI_E_SUCCESS) { MAPIFreeBuffer(RowSet); MAPIFreeBuffer(flaglist); return false; } /* Step 6. Delete the message */ errno = 0; id_msgs[0] = mapi_object_get_id(&obj_message); retval = DeleteMessage(&obj_folder, id_msgs, 1); mapitest_print_retval(mt, "DeleteMessage"); if (GetLastError() != MAPI_E_SUCCESS) { MAPIFreeBuffer(RowSet); MAPIFreeBuffer(flaglist); ret = false; } /* Release */ MAPIFreeBuffer(RowSet); MAPIFreeBuffer(flaglist); mapi_object_release(&obj_message); mapi_object_release(&obj_folder); mapi_object_release(&obj_store); return ret; } /** \details Test the ReadRecipients (0xf) operation This function: -# Log on the use private mailbox -# Open the Outbox folder -# Create the message, set recipients -# Save the message -# Read message recipients -# Delete the message \param mt point on the top-level mapitest structure \return true on success, otherwise false */ _PUBLIC_ bool mapitest_oxcmsg_ReadRecipients(struct mapitest *mt) { enum MAPISTATUS retval; mapi_object_t obj_store; mapi_object_t obj_folder; mapi_object_t obj_message; mapi_id_t id_folder; char **username = NULL; struct SPropTagArray *SPropTagArray = NULL; struct PropertyValue_r value; struct PropertyRowSet_r *RowSet = NULL; struct SRowSet *SRowSet = NULL; struct PropertyTagArray_r *flaglist = NULL; struct ReadRecipientRow *RecipientRows; uint8_t count; mapi_id_t id_msgs[1]; /* Step 1. Logon */ mapi_object_init(&obj_store); retval = OpenMsgStore(mt->session, &obj_store); mapitest_print_retval(mt, "OpenMsgStore"); if (GetLastError() != MAPI_E_SUCCESS) { return false; } /* Step 2. Open Outbox folder */ retval = GetDefaultFolder(&obj_store, &id_folder, olFolderInbox); mapitest_print_retval(mt, "GetDefaultFolder"); if (GetLastError() != MAPI_E_SUCCESS) { return false; } mapi_object_init(&obj_folder); retval = OpenFolder(&obj_store, id_folder, &obj_folder); mapitest_print_retval(mt, "OpenFolder"); if (GetLastError() != MAPI_E_SUCCESS) { return false; } /* Step 3. Create the message */ mapi_object_init(&obj_message); retval = CreateMessage(&obj_folder, &obj_message); mapitest_print_retval(mt, "CreateMessage"); if (GetLastError() != MAPI_E_SUCCESS) { return false; } SPropTagArray = set_SPropTagArray(mt->mem_ctx, 0xA, PR_ENTRYID, PR_DISPLAY_NAME_UNICODE, PR_OBJECT_TYPE, PR_DISPLAY_TYPE, PR_TRANSMITTABLE_DISPLAY_NAME_UNICODE, PR_EMAIL_ADDRESS_UNICODE, PR_ADDRTYPE_UNICODE, PR_SEND_RICH_INFO, PR_7BIT_DISPLAY_NAME_UNICODE, PR_SMTP_ADDRESS_UNICODE); username = talloc_array(mt->mem_ctx, char *, 2); username[0] = (char *)mt->profile->mailbox; username[1] = NULL; retval = ResolveNames(mapi_object_get_session(&obj_message), (const char **)username, SPropTagArray, &RowSet, &flaglist, MAPI_UNICODE); mapitest_print_retval_clean(mt, "ResolveNames", retval); if (retval != MAPI_E_SUCCESS) { return false; } if (!RowSet) { mapitest_print(mt, "Null RowSet\n"); return false; } if (!RowSet->cRows) { mapitest_print(mt, "No values in RowSet\n"); MAPIFreeBuffer(RowSet); return false; } value.ulPropTag = PR_SEND_INTERNET_ENCODING; value.value.l = 0; PropertyRowSet_propcpy(mt->mem_ctx, RowSet, value); SRowSet = talloc_zero(RowSet, struct SRowSet); cast_PropertyRowSet_to_SRowSet(SRowSet, RowSet, SRowSet); retval = SetRecipientType(&(SRowSet->aRow[0]), MAPI_TO); mapitest_print_retval_clean(mt, "SetRecipientType", retval); if (retval != MAPI_E_SUCCESS) { MAPIFreeBuffer(RowSet); MAPIFreeBuffer(flaglist); return false; } retval = ModifyRecipients(&obj_message, SRowSet); mapitest_print_retval_fmt(mt, "ModifyRecipients", "(%s)", "MAPI_TO"); if (retval != MAPI_E_SUCCESS) { MAPIFreeBuffer(RowSet); MAPIFreeBuffer(flaglist); return false; } SetRecipientType(&(SRowSet->aRow[0]), MAPI_CC); mapitest_print_retval(mt, "SetRecipientType"); retval = ModifyRecipients(&obj_message, SRowSet); mapitest_print_retval_fmt(mt, "ModifyRecipients", "(%s)", "MAPI_CC"); if (retval != MAPI_E_SUCCESS) { MAPIFreeBuffer(RowSet); MAPIFreeBuffer(flaglist); return false; } SetRecipientType(&(SRowSet->aRow[0]), MAPI_BCC); mapitest_print_retval(mt, "SetRecipientType"); retval = ModifyRecipients(&obj_message, SRowSet); mapitest_print_retval_fmt(mt, "ModifyRecipients", "(%s)", "MAPI_BCC"); if (retval != MAPI_E_SUCCESS) { MAPIFreeBuffer(RowSet); MAPIFreeBuffer(flaglist); return false; } /* Step 4. Save the message */ retval = SaveChangesMessage(&obj_folder, &obj_message, KeepOpenReadOnly); mapitest_print_retval(mt, "SaveChangesMessage"); if (retval != MAPI_E_SUCCESS) { MAPIFreeBuffer(RowSet); MAPIFreeBuffer(flaglist); return false; } /* Step 5. Read recipients */ RecipientRows = talloc_zero(mt->mem_ctx, struct ReadRecipientRow); retval = ReadRecipients(&obj_message, 0, &count, &RecipientRows); mapitest_print_retval(mt, "ReadRecipients"); MAPIFreeBuffer(RecipientRows); if (retval != MAPI_E_SUCCESS) { MAPIFreeBuffer(RowSet); MAPIFreeBuffer(flaglist); return false; } /* Step 6. Delete the message */ errno = 0; id_msgs[0] = mapi_object_get_id(&obj_message); retval = DeleteMessage(&obj_folder, id_msgs, 1); mapitest_print_retval(mt, "DeleteMessage"); if (retval != MAPI_E_SUCCESS) { MAPIFreeBuffer(RowSet); MAPIFreeBuffer(flaglist); return false; } /* Release */ MAPIFreeBuffer(RowSet); MAPIFreeBuffer(flaglist); mapi_object_release(&obj_message); mapi_object_release(&obj_folder); mapi_object_release(&obj_store); return true; } /** \details Test the SaveChangesMessage (0xc) operation This function: -# Log on the user private mailbox -# Open the Outbox folder -# Create the message -# Save the message -# Delete the message \param mt pointer on the top-level mapitest structure \return true on success, otherwise false */ _PUBLIC_ bool mapitest_oxcmsg_SaveChangesMessage(struct mapitest *mt) { mapi_object_t obj_store; mapi_object_t obj_folder; mapi_object_t obj_message; mapi_id_t id_folder; mapi_id_t id_msgs[1]; /* Step 1. Logon */ mapi_object_init(&obj_store); OpenMsgStore(mt->session, &obj_store); mapitest_print_retval(mt, "OpenMsgStore"); if (GetLastError() != MAPI_E_SUCCESS) { return false; } /* Step 2. Open Outbox folder */ GetDefaultFolder(&obj_store, &id_folder, olFolderOutbox); mapitest_print_retval(mt, "GetDefaultFolder"); if (GetLastError() != MAPI_E_SUCCESS) { return false; } mapi_object_init(&obj_folder); OpenFolder(&obj_store, id_folder, &obj_folder); mapitest_print_retval(mt, "OpenFolder"); if (GetLastError() != MAPI_E_SUCCESS) { return false; } /* Step 3. Create the message */ mapi_object_init(&obj_message); CreateMessage(&obj_folder, &obj_message); mapitest_print_retval(mt, "CreateMessage"); if (GetLastError() != MAPI_E_SUCCESS) { return false; } /* Step 4. Save the message */ SaveChangesMessage(&obj_folder, &obj_message, KeepOpenReadOnly); mapitest_print_retval(mt, "SaveChangesMessage"); if (GetLastError() != MAPI_E_SUCCESS) { return false; } /* Step 5. Delete the saved message */ id_msgs[0] = mapi_object_get_id(&obj_message); DeleteMessage(&obj_folder, id_msgs, 1); mapitest_print_retval(mt, "DeleteMessage"); if (GetLastError() != MAPI_E_SUCCESS) { return false; } /* Release */ mapi_object_release(&obj_message); mapi_object_release(&obj_folder); mapi_object_release(&obj_store); return true; } /** \details Test the GetMessageStatus (0x1f) operation This function: -# Log on the user private mailbox -# Open the outbox folder -# Create the message -# Save the message -# Get outbox contents table -# Get messages status -# Delete the message \param mt pointer on the top-level mapitest structure \return true on success, otherwise false */ _PUBLIC_ bool mapitest_oxcmsg_GetMessageStatus(struct mapitest *mt) { enum MAPISTATUS retval; mapi_object_t obj_store; mapi_object_t obj_folder; mapi_object_t obj_message; mapi_object_t obj_ctable; mapi_id_t id_folder; mapi_id_t id_msgs[1]; struct SPropTagArray *SPropTagArray; struct SRowSet SRowSet; uint32_t count; uint32_t status; uint32_t i; /* Step 1. Logon */ mapi_object_init(&obj_store); mapi_object_init(&obj_folder); mapi_object_init(&obj_message); mapi_object_init(&obj_ctable); retval = OpenMsgStore(mt->session, &obj_store); mapitest_print_retval_clean(mt, "OpenMsgStore", retval); if (retval != MAPI_E_SUCCESS) { return false; } /* Step 2. Open Outbox folder */ retval = GetDefaultFolder(&obj_store, &id_folder, olFolderOutbox); mapitest_print_retval_clean(mt, "GetDefaultFolder", retval); if (retval != MAPI_E_SUCCESS) { return false; } retval = OpenFolder(&obj_store, id_folder, &obj_folder); mapitest_print_retval_clean(mt, "OpenFolder", retval); if (retval != MAPI_E_SUCCESS) { return false; } /* Step 3. Create the message */ retval = CreateMessage(&obj_folder, &obj_message); mapitest_print_retval_clean(mt, "CreateMessage", retval); if (retval != MAPI_E_SUCCESS) { return false; } /* Step 4. Save the message */ retval = SaveChangesMessage(&obj_folder, &obj_message, KeepOpenReadOnly); mapitest_print_retval_clean(mt, "SaveChangesMessage", retval); if (retval != MAPI_E_SUCCESS) { return false; } /* Step 5. Get outbox contents table */ retval = GetContentsTable(&obj_folder, &obj_ctable, 0, &count); mapitest_print_retval_clean(mt, "GetContentsTable", retval); if (retval != MAPI_E_SUCCESS) { return false; } SPropTagArray = set_SPropTagArray(mt->mem_ctx, 0x2, PR_MID, PR_MSG_STATUS); retval = SetColumns(&obj_ctable, SPropTagArray); MAPIFreeBuffer(SPropTagArray); mapitest_print_retval_clean(mt, "GetMessageStatus", retval); if (retval != MAPI_E_SUCCESS) { return false; } /* Step 6. Get Message Status */ while (((retval = QueryRows(&obj_ctable, count, TBL_ADVANCE, &SRowSet)) != MAPI_E_NOT_FOUND) && SRowSet.cRows) { count -= SRowSet.cRows; for (i = 0; i < SRowSet.cRows; i++) { retval = GetMessageStatus(&obj_folder, SRowSet.aRow[i].lpProps[0].value.d, &status); mapitest_print_retval_clean(mt, "GetMessageStatus", retval); if (retval != MAPI_E_SUCCESS) { return false; } } } /* Step 7. Delete the saved message */ id_msgs[0] = mapi_object_get_id(&obj_message); retval = DeleteMessage(&obj_folder, id_msgs, 1); mapitest_print_retval_clean(mt, "DeleteMessage", retval); if (retval != MAPI_E_SUCCESS) { return false; } /* Release */ mapi_object_release(&obj_ctable); mapi_object_release(&obj_message); mapi_object_release(&obj_folder); mapi_object_release(&obj_store); return true; } struct msgstatus { uint32_t status; const char *name; }; static struct msgstatus msgstatus[] = { {MSGSTATUS_HIDDEN, "MSGSTATUS_HIDDEN"}, {MSGSTATUS_HIGHLIGHTED, "MSGSTATUS_HIGHLIGHTED"}, {MSGSTATUS_TAGGED, "MSGSTATUS_TAGGED"}, {MSGSTATUS_REMOTE_DOWNLOAD, "MSGSTATUS_REMOTE_DOWNLOAD"}, {MSGSTATUS_REMOTE_DELETE, "MSGSTATUS_REMOTE_DELETE"}, {MSGSTATUS_DELMARKED, "MSGSTATUS_DELMARKED"}, {0, NULL} }; /** \details Test the GetMessageStatus (0x1f) operation This function: -# Log on the user private mailbox -# Open the outbox folder -# Create the message -# Save the message -# Get outbox contents table -# Set different messages status, then get them and compare values -# Delete the message \param mt pointer on the top-level mapitest structure \return true on success, otherwise false */ _PUBLIC_ bool mapitest_oxcmsg_SetMessageStatus(struct mapitest *mt) { enum MAPISTATUS retval; mapi_object_t obj_store; mapi_object_t obj_folder; mapi_object_t obj_message; mapi_object_t obj_ctable; mapi_id_t id_folder; mapi_id_t id_msgs[1]; struct SPropTagArray *SPropTagArray; struct SRowSet SRowSet; uint32_t count; uint32_t i; uint32_t ulOldStatus = 0; uint32_t ulOldStatus2 = 0; bool ret = true; /* Step 1. Logon */ mapi_object_init(&obj_store); mapi_object_init(&obj_folder); mapi_object_init(&obj_message); mapi_object_init(&obj_ctable); retval = OpenMsgStore(mt->session, &obj_store); mapitest_print_retval_clean(mt, "OpenMsgStore", retval); if (retval != MAPI_E_SUCCESS) { ret = false; goto release; } /* Step 2. Open Outbox folder */ retval = GetDefaultFolder(&obj_store, &id_folder, olFolderOutbox); mapitest_print_retval_clean(mt, "GetDefaultFolder", retval); if (retval != MAPI_E_SUCCESS) { ret = false; goto release; } retval = OpenFolder(&obj_store, id_folder, &obj_folder); mapitest_print_retval_clean(mt, "OpenFolder", retval); if (retval != MAPI_E_SUCCESS) { ret = false; goto release; } /* Step 3. Create the message */ retval = CreateMessage(&obj_folder, &obj_message); mapitest_print_retval_clean(mt, "CreateMessage", retval); if (retval != MAPI_E_SUCCESS) { ret = false; goto release; } /* Step 4. Save the message */ retval = SaveChangesMessage(&obj_folder, &obj_message, KeepOpenReadOnly); mapitest_print_retval_clean(mt, "SaveChangesMessage", retval); if (retval != MAPI_E_SUCCESS) { ret = false; goto release; } /* Step 5. Get outbox contents table */ retval = GetContentsTable(&obj_folder, &obj_ctable, 0, &count); mapitest_print_retval_clean(mt, "GetContentsTable", retval); if (retval != MAPI_E_SUCCESS) { ret = false; goto release; } SPropTagArray = set_SPropTagArray(mt->mem_ctx, 0x2, PR_MID, PR_MSG_STATUS); retval = SetColumns(&obj_ctable, SPropTagArray); mapitest_print_retval_clean(mt, "SetColumns", retval); MAPIFreeBuffer(SPropTagArray); if (retval != MAPI_E_SUCCESS) { ret = false; goto release; } /* Fetch the first email */ retval = QueryRows(&obj_ctable, 1, TBL_NOADVANCE, &SRowSet); mapitest_print_retval_clean(mt, "QueryRows", retval); if (retval != MAPI_E_SUCCESS || SRowSet.cRows == 0) { ret = false; goto release; } /* Step 6. SetMessageStatus + GetMessageStatus + Comparison */ for (i = 0; msgstatus[i].name; i++) { retval = SetMessageStatus(&obj_folder, SRowSet.aRow[0].lpProps[0].value.d, msgstatus[i].status, msgstatus[i].status, &ulOldStatus2); mapitest_print_retval_clean(mt, "SetMessageStatus", retval); if (retval != MAPI_E_SUCCESS) { ret = false; goto release; } retval = GetMessageStatus(&obj_folder, SRowSet.aRow[0].lpProps[0].value.d, &ulOldStatus); mapitest_print_retval_clean(mt, "GetMessageStatus", retval); if (retval != MAPI_E_SUCCESS) { ret = false; goto release; } if ((ulOldStatus != ulOldStatus2) && (ulOldStatus & msgstatus[i].status)) { errno = 0; mapitest_print(mt, "* %-35s: %s 0x%.8x\n", "Comparison", msgstatus[i].name, GetLastError()); } } /* Step 7. Delete the saved message */ id_msgs[0] = mapi_object_get_id(&obj_message); DeleteMessage(&obj_folder, id_msgs, 1); mapitest_print_retval(mt, "DeleteMessage"); if (GetLastError() != MAPI_E_SUCCESS) { return false; } release: /* Release */ mapi_object_release(&obj_ctable); mapi_object_release(&obj_message); mapi_object_release(&obj_folder); mapi_object_release(&obj_store); return ret; } /** \details Test the SetReadFlags (0x66) operation This function: -# Opens the Inbox folder and creates some test content -# Checks that the PR_MESSAGE_FLAGS property on each message is 0x0 -# Apply SetReadFlags() on every second messages -# Check the results are as expected -# Apply SetReadFlags() again -# Check the results are as expected -# Cleanup \param mt pointer on the top-level mapitest structure \return true on success, otherwise false */ _PUBLIC_ bool mapitest_oxcmsg_SetReadFlags(struct mapitest *mt) { enum MAPISTATUS retval; bool ret = true; mapi_object_t obj_htable; mapi_object_t obj_test_folder; struct SPropTagArray *SPropTagArray; struct SRowSet SRowSet; struct mt_common_tf_ctx *context; int i; uint64_t messageIds[5]; /* Step 1. Logon */ if (! mapitest_common_setup(mt, &obj_htable, NULL)) { return false; } /* Fetch the contents table for the test folder */ context = mt->priv; mapi_object_init(&(obj_test_folder)); retval = GetContentsTable(&(context->obj_test_folder), &(obj_test_folder), 0, NULL); mapitest_print_retval_clean(mt, "GetContentsTable", retval); if (retval != MAPI_E_SUCCESS) { ret = false; goto cleanup; } SPropTagArray = set_SPropTagArray(mt->mem_ctx, 0x2, PR_MID, PR_MESSAGE_FLAGS); retval = SetColumns(&obj_test_folder, SPropTagArray); mapitest_print_retval_clean(mt, "SetColumns", retval); MAPIFreeBuffer(SPropTagArray); if (retval != MAPI_E_SUCCESS) { ret = false; goto cleanup; } retval = QueryRows(&obj_test_folder, 10, TBL_NOADVANCE, &SRowSet); mapitest_print_retval_clean(mt, "QueryRows", retval); if (retval != MAPI_E_SUCCESS) { ret = false; goto cleanup; } /* 0x0400 is mfEverRead - the message has been read at least once. We see this on Exchange 2010 */ for (i = 0; i < 10; ++i) { if ((*(const uint32_t *)get_SPropValue_data(&(SRowSet.aRow[i].lpProps[1])) & ~0x0400) != 0x0) { mapitest_print(mt, "* %-35s: unexpected flag at %i 0x%x\n", "QueryRows", i, (*(const uint32_t *)get_SPropValue_data(&(SRowSet.aRow[i].lpProps[1])))); ret = false; goto cleanup; } } for (i = 0; i < 5; ++i) { messageIds[i] = (*(const uint64_t *)get_SPropValue_data(&(SRowSet.aRow[i*2].lpProps[0]))); } retval = SetReadFlags(&(context->obj_test_folder), 0x0, 5, messageIds); mapitest_print_retval_clean(mt, "SetReadFlags", retval); if (retval != MAPI_E_SUCCESS) { ret = false; goto cleanup; } retval = QueryRows(&obj_test_folder, 10, TBL_NOADVANCE, &SRowSet); mapitest_print_retval_clean(mt, "QueryRows", retval); if (retval != MAPI_E_SUCCESS) { ret = false; goto cleanup; } for (i = 0; i < 10; i+=2) { if ((*(const uint32_t *)get_SPropValue_data(&(SRowSet.aRow[i].lpProps[1])) & ~0x0400) != MSGFLAG_READ) { mapitest_print(mt, "* %-35s: unexpected flag (0) at %i 0x%x\n", "QueryRows", i, (*(const uint32_t *)get_SPropValue_data(&(SRowSet.aRow[i].lpProps[1])))); ret = false; goto cleanup; } if ((*(const uint32_t *)get_SPropValue_data(&(SRowSet.aRow[i+1].lpProps[1])) & ~0x0400) != 0x0) { mapitest_print(mt, "* %-35s: unexpected flag (1) at %i 0x%x\n", "QueryRows", i, (*(const uint32_t *)get_SPropValue_data(&(SRowSet.aRow[i+1].lpProps[1])))); ret = false; goto cleanup; } } SetReadFlags(&(context->obj_test_folder), CLEAR_READ_FLAG, 5, messageIds); retval = QueryRows(&obj_test_folder, 10, TBL_NOADVANCE, &SRowSet); mapitest_print_retval_clean(mt, "QueryRows", retval); if (retval != MAPI_E_SUCCESS) { ret = false; goto cleanup; } for (i = 0; i < 10; ++i) { if ((*(const uint32_t *)get_SPropValue_data(&(SRowSet.aRow[i].lpProps[1])) & ~0x0400) != 0x0) { mapitest_print(mt, "* %-35s: unexpected flag (3) at %i 0x%x\n", "QueryRows", i, (*(const uint32_t *)get_SPropValue_data(&(SRowSet.aRow[i].lpProps[1])))); ret = false; goto cleanup; } } cleanup: /* Cleanup and release */ talloc_free(SRowSet.aRow); mapi_object_release(&obj_htable); mapitest_common_cleanup(mt); return ret; } /** \details Test the OpenEmbeddedMessage (0x46) and CreateAttach (0x23) operations This function: -# Logs on the user private mailbox -# Open the Inbox folder -# Create a test message -# Embed a message in the test message -# Delete the test message \param mt pointer to the top-level mapitest structure \return true on success, otherwise false */ _PUBLIC_ bool mapitest_oxcmsg_OpenEmbeddedMessage(struct mapitest *mt) { enum MAPISTATUS retval; bool ret; mapi_object_t obj_store; mapi_object_t obj_folder; mapi_object_t obj_message; mapi_object_t obj_attach; mapi_object_t obj_embeddedmsg; mapi_id_t id_msgs[1]; struct SPropValue attach[2]; struct SRowSet SRowSet; struct SPropTagArray SPropTagArray; /* Step 1. Logon */ mapi_object_init(&obj_store); retval = OpenMsgStore(mt->session, &obj_store); if (retval != MAPI_E_SUCCESS) { mapi_object_release(&obj_store); return false; } /* Step 2. Open Inbox folder */ mapi_object_init(&obj_folder); ret = mapitest_common_folder_open(mt, &obj_store, &obj_folder, olFolderInbox); if (ret == false) { mapi_object_release(&obj_folder); mapi_object_release(&obj_store); return false; } /* Step 3. Create the tmp message and save it */ mapi_object_init(&obj_message); ret = mapitest_common_message_create(mt, &obj_folder, &obj_message, OXCMSG_SETREADFLAGS); if (ret == false) return ret; retval = SaveChangesMessage(&obj_folder, &obj_message, KeepOpenReadWrite); mapitest_print(mt, "* %-35s: 0x%.8x\n", "SaveChangesMessage", retval); if (retval != MAPI_E_SUCCESS) { mapi_object_release(&obj_message); mapi_object_release(&obj_folder); mapi_object_release(&obj_store); return false; } /* Step 4. Embed another message in the message */ mapi_object_init(&obj_attach); retval = CreateAttach(&obj_message, &obj_attach); mapitest_print(mt, "* %-35s: 0x%.8x\n", "CreateAttach", retval); if (retval != MAPI_E_SUCCESS) { mapi_object_release(&obj_attach); mapi_object_release(&obj_message); mapi_object_release(&obj_folder); mapi_object_release(&obj_store); return false; } /* use SetProps() to set the attachment up */ attach[0].ulPropTag = PR_ATTACH_METHOD; attach[0].value.l = ATTACH_EMBEDDED_MSG; attach[1].ulPropTag = PR_RENDERING_POSITION; attach[1].value.l = 0; retval = SetProps(&obj_attach, 0, attach, 2); mapitest_print(mt, "* %-35s: 0x%.8x\n", "SetProps", retval); if (retval != MAPI_E_SUCCESS) { mapi_object_release(&obj_attach); mapi_object_release(&obj_message); mapi_object_release(&obj_folder); mapi_object_release(&obj_store); return false; } mapi_object_init(&obj_embeddedmsg); retval = OpenEmbeddedMessage(&obj_attach, &obj_embeddedmsg, MAPI_CREATE); mapitest_print(mt, "* %-35s: 0x%.8x\n", "OpenEmbeddedMessage", retval); if (retval != MAPI_E_SUCCESS) { mapi_object_release(&obj_embeddedmsg); mapi_object_release(&obj_attach); mapi_object_release(&obj_message); mapi_object_release(&obj_folder); mapi_object_release(&obj_store); return false; } ret = mapitest_common_message_fill(mt, &obj_embeddedmsg, "MT EmbeddedMessage"); if (ret == false) { mapi_object_release(&obj_embeddedmsg); mapi_object_release(&obj_attach); mapi_object_release(&obj_message); mapi_object_release(&obj_folder); mapi_object_release(&obj_store); return false; } // Save the changes to the embedded message retval = SaveChangesMessage(&obj_message, &obj_embeddedmsg, KeepOpenReadOnly); mapitest_print(mt, "* %-35s: 0x%.8x\n", "SaveChangesMessage", retval); if (retval != MAPI_E_SUCCESS) { mapi_object_release(&obj_embeddedmsg); mapi_object_release(&obj_attach); mapi_object_release(&obj_message); mapi_object_release(&obj_folder); mapi_object_release(&obj_store); return false; } // Save the changes to the attachment and then the message retval = SaveChangesAttachment(&obj_message, &obj_attach, KeepOpenReadOnly); mapitest_print(mt, "* %-35s: 0x%.8x\n", "SaveChangesAttachment", retval); if (retval != MAPI_E_SUCCESS) { mapi_object_release(&obj_embeddedmsg); mapi_object_release(&obj_attach); mapi_object_release(&obj_message); mapi_object_release(&obj_folder); mapi_object_release(&obj_store); return false; } retval = SaveChangesMessage(&obj_folder, &obj_message, KeepOpenReadOnly); mapitest_print(mt, "* %-35s: 0x%.8x\n", "SaveChangesMessage", retval); if (retval != MAPI_E_SUCCESS) { mapi_object_release(&obj_embeddedmsg); mapi_object_release(&obj_attach); mapi_object_release(&obj_message); mapi_object_release(&obj_folder); mapi_object_release(&obj_store); return false; } /* Step 5. Open the embedded message */ mapi_object_init(&obj_attach); retval = OpenAttach(&obj_message, 0, &obj_attach); mapitest_print(mt, "* %-35s: 0x%.8x\n", "OpenAttach", retval); if (retval != MAPI_E_SUCCESS) { mapi_object_release(&obj_embeddedmsg); mapi_object_release(&obj_attach); mapi_object_release(&obj_message); mapi_object_release(&obj_folder); mapi_object_release(&obj_store); return false; } retval = OpenEmbeddedMessage(&obj_attach, &obj_embeddedmsg, MAPI_READONLY); mapitest_print(mt, "* %-35s: 0x%.8x\n", "OpenEmbeddedMessage", retval); if (retval != MAPI_E_SUCCESS) { mapi_object_release(&obj_embeddedmsg); mapi_object_release(&obj_attach); mapi_object_release(&obj_message); mapi_object_release(&obj_folder); mapi_object_release(&obj_store); return false; } /* Step 6. Get the recipient table */ retval = GetRecipientTable(&obj_embeddedmsg, &SRowSet, &SPropTagArray); mapitest_print(mt, "* %-35s: 0x%.8x\n", "GetRecipientTable", retval); mapitest_print_SRowSet(mt, &SRowSet, "\t * "); mapi_object_release(&obj_embeddedmsg); /* Step 7. Delete the message */ id_msgs[0] = mapi_object_get_id(&obj_message); retval = DeleteMessage(&obj_folder, id_msgs, 1); mapitest_print(mt, "* %-35s: 0x%.8x\n", "DeleteMessage", GetLastError()); if (GetLastError() != MAPI_E_SUCCESS) { mapi_object_release(&obj_attach); mapi_object_release(&obj_message); mapi_object_release(&obj_folder); mapi_object_release(&obj_store); return false; } /* Release */ mapi_object_release(&obj_attach); mapi_object_release(&obj_message); mapi_object_release(&obj_folder); mapi_object_release(&obj_store); return true; } /** \details Test the GetValidAttachments (0x52) and CreateAttach (0x23) operations This function: -# Logs on the user private mailbox -# Open the Inbox folder -# Create a test message -# Check the number of valid attachments is zero -# Create two attachments -# Check the number of valid attachments is two (numbered 0 and 1) -# Delete the first attachment -# Check the number of valid attachments is one (numbered 1) -# Delete the test message \param mt pointer to the top-level mapitest structure \return true on success, otherwise false */ _PUBLIC_ bool mapitest_oxcmsg_GetValidAttachments(struct mapitest *mt) { enum MAPISTATUS retval; bool ret; mapi_object_t obj_store; mapi_object_t obj_folder; mapi_object_t obj_message; mapi_object_t obj_attach0; mapi_object_t obj_attach1; mapi_id_t id_msgs[1]; struct SPropValue attach[3]; uint16_t numAttach; uint32_t *attachmentIds; /* Step 1. Logon */ mapi_object_init(&obj_store); retval = OpenMsgStore(mt->session, &obj_store); if (retval != MAPI_E_SUCCESS) { mapi_object_release(&obj_store); return false; } /* Step 2. Open Inbox folder */ mapi_object_init(&obj_folder); ret = mapitest_common_folder_open(mt, &obj_store, &obj_folder, olFolderInbox); if (ret == false) { mapi_object_release(&obj_folder); mapi_object_release(&obj_store); return false; } /* Step 3. Create the test message and save it */ mapi_object_init(&obj_message); ret = mapitest_common_message_create(mt, &obj_folder, &obj_message, OXCMSG_SETREADFLAGS); if (ret == false) return ret; retval = SaveChangesMessage(&obj_folder, &obj_message, KeepOpenReadWrite); mapitest_print_retval_clean(mt, "SaveChangesMessage", retval); if (retval != MAPI_E_SUCCESS) { mapi_object_release(&obj_message); mapi_object_release(&obj_folder); mapi_object_release(&obj_store); return false; } ret = true; /* Step 4. Check the number of valid attachments */ numAttach = 99; retval = GetValidAttach(&obj_message, &numAttach, &attachmentIds); mapitest_print_retval_fmt_clean(mt, "GetValidAttach", retval, "%i", numAttach); if (numAttach != 0) { ret = false; goto cleanup_wo_attach; } if (retval != MAPI_E_SUCCESS) { ret = false; goto cleanup_wo_attach; } /* Step 5. Create two attachments to the message */ mapi_object_init(&obj_attach0); mapi_object_init(&obj_attach1); retval = CreateAttach(&obj_message, &obj_attach0); mapitest_print_retval_clean(mt, "CreateAttach", retval); if (retval != MAPI_E_SUCCESS) { ret = false; goto cleanup; } /* use SetProps() to set the attachment up */ attach[0].ulPropTag = PR_ATTACH_METHOD; attach[0].value.l = ATTACH_BY_VALUE; attach[1].ulPropTag = PR_RENDERING_POSITION; attach[1].value.l = 0; attach[2].ulPropTag = PR_ATTACH_FILENAME; attach[2].value.lpszA = "Attachment 0"; retval = SetProps(&obj_attach0, 0, attach, 3); mapitest_print_retval_clean(mt, "SetProps", retval); if (retval != MAPI_E_SUCCESS) { ret = false; goto cleanup; } /* Save the changes to the attachment and then the message */ retval = SaveChangesAttachment(&obj_message, &obj_attach0, KeepOpenReadOnly); mapitest_print_retval_clean(mt, "SaveChangesAttachment", retval); if (retval != MAPI_E_SUCCESS) { ret = false; goto cleanup; } retval = CreateAttach(&obj_message, &obj_attach1); mapitest_print_retval_clean(mt, "CreateAttach", retval); if (retval != MAPI_E_SUCCESS) { ret = false; goto cleanup; } /* use SetProps() to set the attachment up */ attach[0].ulPropTag = PR_ATTACH_METHOD; attach[0].value.l = ATTACH_BY_VALUE; attach[1].ulPropTag = PR_RENDERING_POSITION; attach[1].value.l = 0; attach[2].ulPropTag = PR_ATTACH_FILENAME; attach[2].value.lpszA = "Attachment 1"; retval = SetProps(&obj_attach1, 0, attach, 3); mapitest_print_retval_clean(mt, "SetProps", retval); if (retval != MAPI_E_SUCCESS) { ret = false; goto cleanup; } /* Save the changes to the attachment and then the message */ retval = SaveChangesAttachment(&obj_message, &obj_attach1, KeepOpenReadOnly); mapitest_print_retval_clean(mt, "SaveChangesAttachment", retval); if (retval != MAPI_E_SUCCESS) { ret = false; goto cleanup; } retval = SaveChangesMessage(&obj_folder, &obj_message, KeepOpenReadWrite); mapitest_print_retval_clean(mt, "SaveChangesMessage", retval); if (retval != MAPI_E_SUCCESS) { ret = false; goto cleanup; } /* Step 6. Check the number of valid attachments */ numAttach = 99; retval = GetValidAttach(&obj_message, &numAttach, &attachmentIds); mapitest_print_retval_fmt_clean(mt, "GetValidAttach", retval, "%i", numAttach); if (numAttach != 2) { ret = false; goto cleanup; } mapitest_print(mt, "IDs: %d, %d\n", attachmentIds[0], attachmentIds[1]); if ( (attachmentIds[0] != 0) || (attachmentIds[1] != 1) ) { ret = false; goto cleanup; } if (retval != MAPI_E_SUCCESS) { ret = false; goto cleanup; } /* Step 7. Delete the first attachment */ retval = DeleteAttach(&obj_message, attachmentIds[0]); mapitest_print_retval_clean(mt, "DeleteAttach", retval); if (retval != MAPI_E_SUCCESS) { ret = false; goto cleanup; } /* Step 8. Check the number of valid attachments */ numAttach = 99; retval = GetValidAttach(&obj_message, &numAttach, &attachmentIds); mapitest_print_retval_fmt_clean(mt, "GetValidAttach", retval, "%i", numAttach); if (numAttach != 1) { ret = false; goto cleanup; } mapitest_print(mt, "IDs: %d\n", attachmentIds[0]); if ( (attachmentIds[0] != 1) ) { ret = false; goto cleanup; } if (retval != MAPI_E_SUCCESS) { ret = false; goto cleanup; } /* Step 9. Delete the message */ id_msgs[0] = mapi_object_get_id(&obj_message); retval = DeleteMessage(&obj_folder, id_msgs, 1); mapitest_print_retval_clean(mt, "DeleteMessage", retval); if (retval != MAPI_E_SUCCESS) { ret = false; goto cleanup; } cleanup: /* Release */ mapi_object_release(&obj_attach0); mapi_object_release(&obj_attach1); cleanup_wo_attach: mapi_object_release(&obj_message); mapi_object_release(&obj_folder); mapi_object_release(&obj_store); return ret; } /** \details Test the ReloadCachedInformation (0x10) operation This function: -# Logs on to the user private mailbox -# Open the outbox folder -# Create the message -# Save the message -# Reloads the cached message information -# Delete the message \param mt pointer to the top-level mapitest structure \return true on success, otherwise false */ _PUBLIC_ bool mapitest_oxcmsg_ReloadCachedInformation(struct mapitest *mt) { enum MAPISTATUS retval; mapi_object_t obj_store; mapi_object_t obj_folder; mapi_object_t obj_message; mapi_id_t id_folder; mapi_id_t id_msgs[1]; bool ret; ret = true; mapi_object_init(&obj_folder); mapi_object_init(&obj_message); /* Step 1. Logon */ mapi_object_init(&obj_store); retval = OpenMsgStore(mt->session, &obj_store); mapitest_print_retval(mt, "OpenMsgStore"); if (retval != MAPI_E_SUCCESS) { ret = false; goto cleanup; } /* Step 2. Open Outbox folder */ retval = GetDefaultFolder(&obj_store, &id_folder, olFolderOutbox); mapitest_print_retval(mt, "GetDefaultFolder"); if (retval != MAPI_E_SUCCESS) { ret = false; goto cleanup; } retval = OpenFolder(&obj_store, id_folder, &obj_folder); mapitest_print_retval(mt, "OpenFolder"); if (retval != MAPI_E_SUCCESS) { ret = false; goto cleanup; } /* Step 3. Create the message */ retval = CreateMessage(&obj_folder, &obj_message); mapitest_print_retval(mt, "CreateMessage"); if (retval != MAPI_E_SUCCESS) { ret = false; goto cleanup; } /* Step 4. Save the message */ retval = SaveChangesMessage(&obj_folder, &obj_message, KeepOpenReadOnly); mapitest_print_retval(mt, "SaveChangesMessage"); if (retval != MAPI_E_SUCCESS) { ret = false; goto cleanup; } /* Step 5. Reload cached information */ retval = ReloadCachedInformation(&obj_message); mapitest_print_retval(mt, "ReloadCachedInformation"); if (retval != MAPI_E_SUCCESS) { ret = false; goto cleanup; } /* Step 6. Delete the saved message */ id_msgs[0] = mapi_object_get_id(&obj_message); retval = DeleteMessage(&obj_folder, id_msgs, 1); mapitest_print_retval(mt, "DeleteMessage"); if (retval != MAPI_E_SUCCESS) { ret = false; goto cleanup; } cleanup: /* Release */ mapi_object_release(&obj_message); mapi_object_release(&obj_folder); mapi_object_release(&obj_store); return ret; } openchange-2.0/utils/mapitest/modules/module_oxcnotif.c000066400000000000000000000074651223057412600235000ustar00rootroot00000000000000/* Stand-alone MAPI testsuite OpenChange Project - Core Notifications Protocol operation tests Copyright (C) Brad Hards 2009 - 2011 This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see . */ #include "utils/mapitest/mapitest.h" #include "utils/mapitest/proto.h" /** \file module_oxcnotif.c \brief Core Notifications Protocol test suite */ /* Internal callback functions */ int cb(uint16_t, void*, void*); int cb(uint16_t type, void* data, void* priv) { return 0; } /** \details Test the RegisterNotification (0x29) operation This function: -# \param mt pointer on the top-level mapitest structure \return true on success, otherwise false */ _PUBLIC_ bool mapitest_oxcnotif_RegisterNotification(struct mapitest *mt) { enum MAPISTATUS retval; bool ret; mapi_object_t obj_store; mapi_object_t obj_folder; struct mapi_session *session; uint32_t tcon; /* Step 1. Logon */ mapi_object_init(&obj_store); retval = OpenMsgStore(mt->session, &obj_store); mapitest_print_retval(mt, "OpenMsgStore"); if (retval != MAPI_E_SUCCESS) { return false; } /* Step 2. Open Inbox folder */ mapi_object_init(&obj_folder); ret = mapitest_common_folder_open(mt, &obj_store, &obj_folder, olFolderInbox); if (!ret) { return ret; } /* Step 3. Register notification */ session = mapi_object_get_session(&obj_store); retval = RegisterNotification(session); mapitest_print_retval(mt, "RegisterNotification"); if ( retval != MAPI_E_SUCCESS) { return false; } /* Step 4. Subscribe for notifications */ retval = Subscribe(&obj_store, &tcon, fnevObjectCopied, true, cb, NULL); mapitest_print_retval(mt, "Subscribe"); if (retval != MAPI_E_SUCCESS) { return false; } /* Step 5. Unsubscribe for notifications */ retval = Unsubscribe(mt->session, tcon); mapitest_print_retval(mt, "Unsubscribe"); if (retval != MAPI_E_SUCCESS) { return false; } /* Step 6. Cleanup */ mapi_object_release(&obj_folder); mapi_object_release(&obj_store); return true; } /** \details Test the SyncOpenAdvisor (0x83) and SetSyncNotificationGuid (0x88) operations This function: -# logs on -# creates a notification advisor -# sets a GUID on the advisor -# cleans up \param mt pointer on the top-level mapitest structure \return true on success, otherwise false */ _PUBLIC_ bool mapitest_oxcnotif_SyncOpenAdvisor(struct mapitest *mt) { enum MAPISTATUS retval; bool ret = true; mapi_object_t obj_store; mapi_object_t obj_notifier; mapi_object_init(&obj_store); mapi_object_init(&obj_notifier); /* Logon */ retval = OpenMsgStore(mt->session, &obj_store); mapitest_print_retval_clean(mt, "OpenMsgStore", retval); if (retval != MAPI_E_SUCCESS) { ret = false; goto cleanup; } /* Create advisor */ retval = SyncOpenAdvisor(&obj_store, &obj_notifier); mapitest_print_retval_clean(mt, "SyncOpenAdvisor", retval); if (retval != MAPI_E_SUCCESS) { ret = false; goto cleanup; } /* Set GUID */ retval = SetSyncNotificationGuid(&obj_notifier, GUID_random()); mapitest_print_retval_clean(mt, "SetSyncNotificationGuid", retval); if (retval != MAPI_E_SUCCESS) { ret = false; goto cleanup; } /* Cleanup */ cleanup: mapi_object_release(&obj_notifier); mapi_object_release(&obj_store); return ret; } openchange-2.0/utils/mapitest/modules/module_oxcperm.c000066400000000000000000000216121223057412600233120ustar00rootroot00000000000000/* Stand-alone MAPI testsuite OpenChange Project - Permissions operations Copyright (C) Brad Hards 2010 This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see . */ #include "utils/mapitest/mapitest.h" #include "utils/mapitest/proto.h" /** \file module_oxcperm.c \brief Permissions Protocol test suite */ /* Utility function to dump out the permissions This depends on PR_ENTRYID being the first property returned */ static void mapitest_dump_permissions_SRowSet(struct mapitest *mt, struct SRowSet *SRowSet, const char *sep) { uint32_t i, j; /* Sanity checks */ if (!SRowSet) return; if (!SRowSet->cRows) return; for (i = 0; i < SRowSet->cRows; i++) { struct SRow *thisRow = &(SRowSet->aRow[i]); if ((thisRow->lpProps[0].value.d) == 0x0) { /* this is the "default" user id - ignore this */ continue; } for (j = 0; j < thisRow->cValues; j++) { mapitest_print_SPropValue(mt, thisRow->lpProps[j], sep); } } } /** \details Test the GetPermissionsTable (0x3e) operation This function: -# Log on private message store -# Open the top store folder -# Gets the permissions table handle -# Fetches properties from the permissions table */ _PUBLIC_ bool mapitest_oxcperm_GetPermissionsTable(struct mapitest *mt) { enum MAPISTATUS retval; mapi_object_t obj_store; mapi_object_t obj_permtable; mapi_object_t obj_folder; mapi_id_t id_folder; struct SPropTagArray *SPropTagArray; struct SRowSet SRowSet; bool ret = true; /* Step 1. Logon */ mapi_object_init(&obj_store); mapi_object_init(&obj_folder); mapi_object_init(&obj_permtable); retval = OpenMsgStore(mt->session, &obj_store); mapitest_print_retval(mt, "OpenMsgStore"); if (retval != MAPI_E_SUCCESS) { ret = false; goto cleanup; } /* Step 2. Open Top Information Store folder */ retval = GetDefaultFolder(&obj_store, &id_folder, olFolderTopInformationStore); mapitest_print_retval(mt, "GetDefaultFolder"); retval = OpenFolder(&obj_store, id_folder, &obj_folder); mapitest_print_retval(mt, "OpenFolder"); if (retval != MAPI_E_SUCCESS) { ret = false; goto cleanup; } /* Step 3. Get the permissions table handle */ retval = GetPermissionsTable(&obj_folder, 0x00, &obj_permtable); mapitest_print_retval(mt, "GetPermissionsTable"); if (retval != MAPI_E_SUCCESS) { ret = false; goto cleanup; } /* Step 4. Fetch some properties from the permissions and dump them out */ SPropTagArray = set_SPropTagArray(mt->mem_ctx, 0x3, PR_MEMBER_ID, PR_MEMBER_NAME_UNICODE, PR_MEMBER_RIGHTS); retval = SetColumns(&obj_permtable, SPropTagArray); MAPIFreeBuffer(SPropTagArray); if (retval != MAPI_E_SUCCESS) { mapitest_print_retval(mt, "SetColumns"); ret = false; goto cleanup; } retval = QueryRows(&obj_permtable, 0x20, TBL_ADVANCE, &SRowSet); if (retval != MAPI_E_SUCCESS) { mapitest_print_retval(mt, "QueryRows"); ret = false; goto cleanup; } mapitest_dump_permissions_SRowSet(mt, &SRowSet, "\t"); cleanup: mapi_object_release(&obj_permtable); mapi_object_release(&obj_folder); mapi_object_release(&obj_store); return ret; } /** \details Test the ModifyPermissions (0x40) operation This function: -# Log on private message store -# Open the top store folder -# Creates a temporary folder -# Adds permissions for the admin user, and checks them -# Modifies permissions for the admin user, and checks them -# Removes permissions for the admin user, and checks them -# Deletes the folder */ _PUBLIC_ bool mapitest_oxcperm_ModifyPermissions(struct mapitest *mt) { enum MAPISTATUS retval; mapi_object_t obj_store; mapi_object_t obj_permtable; mapi_object_t obj_top_folder; mapi_object_t obj_temp_folder; mapi_id_t id_top_folder; struct SPropTagArray *SPropTagArray; struct SRowSet SRowSet; bool ret = true; /* Step 1. Logon */ mapi_object_init(&obj_store); mapi_object_init(&obj_top_folder); mapi_object_init(&obj_temp_folder); mapi_object_init(&obj_permtable); retval = OpenMsgStore(mt->session, &obj_store); mapitest_print_retval(mt, "OpenMsgStore"); if (retval != MAPI_E_SUCCESS) { ret = false; goto cleanup; } /* Step 2. Open Top Information Store folder */ retval = GetDefaultFolder(&obj_store, &id_top_folder, olFolderTopInformationStore); mapitest_print_retval(mt, "GetDefaultFolder"); retval = OpenFolder(&obj_store, id_top_folder, &obj_top_folder); mapitest_print_retval(mt, "OpenFolder"); if (retval != MAPI_E_SUCCESS) { ret = false; goto cleanup; } /* Step 3. Create a temporary folder */ retval = CreateFolder(&obj_top_folder, FOLDER_GENERIC, "MAPITEST_TEST_FOLDER", NULL, OPEN_IF_EXISTS, &obj_temp_folder); mapitest_print_retval(mt, "CreateFolder"); if (retval != MAPI_E_SUCCESS) { ret = false; goto cleanup; } /* Step 4. Add user permissions on the folder, and check it */ retval = AddUserPermission(&obj_temp_folder, "Administrator", RightsReadItems); mapitest_print_retval(mt, "AddUserPermission"); if (retval != MAPI_E_SUCCESS) { ret = false; goto cleanup; } retval = GetPermissionsTable(&obj_temp_folder, 0x00, &obj_permtable); mapitest_print_retval(mt, "GetPermissionsTable"); if (retval != MAPI_E_SUCCESS) { ret = false; goto cleanup; } SPropTagArray = set_SPropTagArray(mt->mem_ctx, 0x3, PR_MEMBER_ID, PR_MEMBER_NAME_UNICODE, PR_MEMBER_RIGHTS); retval = SetColumns(&obj_permtable, SPropTagArray); MAPIFreeBuffer(SPropTagArray); if (retval != MAPI_E_SUCCESS) { mapitest_print_retval(mt, "SetColumns"); ret = false; goto cleanup; } retval = QueryRows(&obj_permtable, 0x20, TBL_ADVANCE, &SRowSet); if (retval != MAPI_E_SUCCESS) { mapitest_print_retval(mt, "QueryRows"); ret = false; goto cleanup; } mapitest_dump_permissions_SRowSet(mt, &SRowSet, "\t"); /* Step 5. Modify user permissions on the folder, and check it */ retval = ModifyUserPermission(&obj_temp_folder, "Administrator", RightsAll); mapitest_print_retval(mt, "ModifyUserPermission"); if (retval != MAPI_E_SUCCESS) { ret = false; goto cleanup; } retval = GetPermissionsTable(&obj_temp_folder, 0x00, &obj_permtable); mapitest_print_retval(mt, "GetPermissionsTable"); if (retval != MAPI_E_SUCCESS) { ret = false; goto cleanup; } SPropTagArray = set_SPropTagArray(mt->mem_ctx, 0x3, PR_MEMBER_ID, PR_MEMBER_NAME_UNICODE, PR_MEMBER_RIGHTS); retval = SetColumns(&obj_permtable, SPropTagArray); MAPIFreeBuffer(SPropTagArray); if (retval != MAPI_E_SUCCESS) { mapitest_print_retval(mt, "SetColumns"); ret = false; goto cleanup; } retval = QueryRows(&obj_permtable, 0x20, TBL_ADVANCE, &SRowSet); if (retval != MAPI_E_SUCCESS) { mapitest_print_retval(mt, "QueryRows"); ret = false; goto cleanup; } mapitest_dump_permissions_SRowSet(mt, &SRowSet, "\t"); /* Step 6. Remove user permissions on the folder, and check it */ retval = RemoveUserPermission(&obj_temp_folder, "Administrator"); mapitest_print_retval(mt, "RemoveUserPermission"); if (retval != MAPI_E_SUCCESS) { ret = false; goto cleanup; } retval = GetPermissionsTable(&obj_temp_folder, 0x00, &obj_permtable); mapitest_print_retval(mt, "GetPermissionsTable"); if (retval != MAPI_E_SUCCESS) { ret = false; goto cleanup; } SPropTagArray = set_SPropTagArray(mt->mem_ctx, 0x3, PR_MEMBER_ID, PR_MEMBER_NAME_UNICODE, PR_MEMBER_RIGHTS); retval = SetColumns(&obj_permtable, SPropTagArray); MAPIFreeBuffer(SPropTagArray); if (retval != MAPI_E_SUCCESS) { mapitest_print_retval(mt, "SetColumns"); ret = false; goto cleanup; } retval = QueryRows(&obj_permtable, 0x20, TBL_ADVANCE, &SRowSet); if (retval != MAPI_E_SUCCESS) { mapitest_print_retval(mt, "QueryRows"); ret = false; goto cleanup; } mapitest_dump_permissions_SRowSet(mt, &SRowSet, "\t"); /* Step 7. Delete the folder */ retval = EmptyFolder(&obj_temp_folder); mapitest_print_retval(mt, "EmptyFolder"); if (retval != MAPI_E_SUCCESS) { ret = false; goto cleanup; } retval = DeleteFolder(&obj_top_folder, mapi_object_get_id(&obj_temp_folder), DEL_MESSAGES|DEL_FOLDERS|DELETE_HARD_DELETE, NULL); mapitest_print_retval(mt, "DeleteFolder"); if (retval != MAPI_E_SUCCESS) { ret = false; goto cleanup; } cleanup: mapi_object_release(&obj_permtable); mapi_object_release(&obj_temp_folder); mapi_object_release(&obj_top_folder); mapi_object_release(&obj_store); return ret; } openchange-2.0/utils/mapitest/modules/module_oxcprpt.c000066400000000000000000002614541223057412600233460ustar00rootroot00000000000000/* Stand-alone MAPI testsuite OpenChange Project - PROPERTY AND STREAM OBJECT PROTOCOL operations Copyright (C) Julien Kerihuel 2008 Copyright (C) Brad Hards 2008-2009 This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see . */ #include "utils/mapitest/mapitest.h" #include "utils/mapitest/proto.h" /** \file module_oxcprpt.c \brief Property and Stream Object Protocol test suite */ /** \details Test the GetProps (0x7) operation This function: -# Log on the user private mailbox -# Retrieve the properties list using GetPropList -# Retrieve their associated values using the GetProps operation \param mt pointer on the top-level mapitest structure \return true on success, otherwise false */ _PUBLIC_ bool mapitest_oxcprpt_GetProps(struct mapitest *mt) { enum MAPISTATUS retval; mapi_object_t obj_store; struct SPropTagArray *SPropTagArray; struct SPropValue *lpProps; uint32_t cValues; /* Step 1. Logon Private Mailbox */ mapi_object_init(&obj_store); retval = OpenMsgStore(mt->session, &obj_store); mapitest_print_retval(mt, "OpenMsgStore"); if (retval != MAPI_E_SUCCESS) { return false; } /* Step 2. Retrieve the properties list using GetPropList */ SPropTagArray = talloc_zero(mt->mem_ctx, struct SPropTagArray); retval = GetPropList(&obj_store, SPropTagArray); mapitest_print_retval(mt, "GetPropList"); if (retval != MAPI_E_SUCCESS) { MAPIFreeBuffer(SPropTagArray); return false; } /* Step 3. Call the GetProps operation */ retval = GetProps(&obj_store, 0, SPropTagArray, &lpProps, &cValues); mapitest_print_retval(mt, "GetProps"); if (retval != MAPI_E_SUCCESS) { MAPIFreeBuffer(SPropTagArray); return false; } MAPIFreeBuffer(SPropTagArray); /* Release */ mapi_object_release(&obj_store); return true; } /** \details Test the GetPropsAll (0x8) operation This function: -# Log on the user private mailbox -# Retrieve the whole set of properties and values associated to the store object \param mt pointer on the top-level mapitest structure \return true on success, otherwise false */ _PUBLIC_ bool mapitest_oxcprpt_GetPropsAll(struct mapitest *mt) { enum MAPISTATUS retval; mapi_object_t obj_store; struct mapi_SPropValue_array properties_array; /* Step 1. Logon Private Mailbox */ mapi_object_init(&obj_store); retval = OpenMsgStore(mt->session, &obj_store); mapitest_print_retval(mt, "OpenMsgStore"); if (retval != MAPI_E_SUCCESS) { return false; } /* Step 2. GetPropsAll operation */ retval = GetPropsAll(&obj_store, 0, &properties_array); mapitest_print_retval(mt, "GetPropsAll"); if (retval != MAPI_E_SUCCESS) { return false; } MAPIFreeBuffer(properties_array.lpProps); /* Release */ mapi_object_release(&obj_store); return true; } /** \details Test the GetPropList (0x9) operation This function: -# Log on the user private mailbox -# Retrieve the list of properties associated to the store object object \param mt pointer on the top-level mapitest structure \return true on success, otherwise false */ _PUBLIC_ bool mapitest_oxcprpt_GetPropList(struct mapitest *mt) { enum MAPISTATUS retval; mapi_object_t obj_store; struct SPropTagArray *SPropTagArray; /* Step 1. Logon Private Mailbox */ mapi_object_init(&obj_store); retval = OpenMsgStore(mt->session, &obj_store); mapitest_print_retval(mt, "OpenMsgStore"); if (retval != MAPI_E_SUCCESS) { return false; } /* Step 2. GetPropList operation */ SPropTagArray = talloc_zero(mt->mem_ctx, struct SPropTagArray); retval = GetPropList(&obj_store, SPropTagArray); mapitest_print_retval(mt, "GetPropList"); MAPIFreeBuffer(SPropTagArray); if (retval != MAPI_E_SUCCESS) { return false; } /* Release */ mapi_object_release(&obj_store); return true; } /** \details Test the SetProps (0xa) operation This function: -# Logon Private mailbox -# Use GetProps to retrieve the mailbox name -# Change it using SetProps -# Reset the mailbox name to its original value \param mt pointer to the top-level mapitest structure \return true on success, otherwise false */ _PUBLIC_ bool mapitest_oxcprpt_SetProps(struct mapitest *mt) { enum MAPISTATUS retval; mapi_object_t obj_store; struct SPropValue *lpProps; struct SPropValue lpProp[1]; struct SPropTagArray *SPropTagArray; const char *mailbox = NULL; const char *new_mailbox = NULL; uint32_t cValues; /* Step 1. Logon Private Mailbox */ mapi_object_init(&obj_store); retval = OpenMsgStore(mt->session, &obj_store); mapitest_print_retval_step_fmt(mt, "1.", "OpenMsgStore", "(%s)", "Logon Private Mailbox"); if (retval != MAPI_E_SUCCESS) { return false; } /* Step 2: GetProps, retrieve mailbox name */ SPropTagArray = set_SPropTagArray(mt->mem_ctx, 0x1, PR_DISPLAY_NAME); retval = GetProps(&obj_store, 0, SPropTagArray, &lpProps, &cValues); mapitest_print_retval_step_fmt(mt, "2.", "GetProps", "(%s)", "Retrieve the mailbox name"); if (retval != MAPI_E_SUCCESS) { return false; } MAPIFreeBuffer(SPropTagArray); if (cValues && lpProps[0].value.lpszA) { mailbox = lpProps[0].value.lpszA; mapitest_print(mt, "* Step 2. Mailbox name = %s\n", mailbox); } else { mapitest_print(mt, MT_ERROR, "* Step 2 - GetProps: No mailbox name\n"); return false; } /* Step 2.1: SetProps with new value */ cValues = 1; new_mailbox = talloc_asprintf(mt->mem_ctx, "%s [MAPITEST]", mailbox); set_SPropValue_proptag(&lpProp[0], PR_DISPLAY_NAME, (const void *) new_mailbox); retval = SetProps(&obj_store, 0, lpProp, cValues); mapitest_print_retval_step_fmt(mt, "2.1.", "SetProps", "(%s)", "NEW mailbox name"); /* Step 2.2: Double check with GetProps */ SPropTagArray = set_SPropTagArray(mt->mem_ctx, 0x1, PR_DISPLAY_NAME); retval = GetProps(&obj_store, 0, SPropTagArray, &lpProps, &cValues); MAPIFreeBuffer(SPropTagArray); if (lpProps[0].value.lpszA) { if (!strncmp(new_mailbox, lpProps[0].value.lpszA, strlen(lpProps[0].value.lpszA))) { mapitest_print(mt, "* Step 2.2 - Check: NEW mailbox name - [SUCCESS] (%s)\n", lpProps[0].value.lpszA); } else { mapitest_print(mt, "* Step 2.2 - Check: NEW mailbox name [FAILURE]\n"); } } MAPIFreeBuffer((void *)new_mailbox); /* Step 3.1: Reset mailbox to its original value */ cValues = 1; set_SPropValue_proptag(&lpProp[0], PR_DISPLAY_NAME, (const void *)mailbox); retval = SetProps(&obj_store, 0, lpProp, cValues); mapitest_print_retval_step_fmt(mt, "3.1.", "SetProps", "(%s)", "OLD mailbox name"); /* Step 3.2: Double check with GetProps */ SPropTagArray = set_SPropTagArray(mt->mem_ctx, 0x1, PR_DISPLAY_NAME); retval = GetProps(&obj_store, 0, SPropTagArray, &lpProps, &cValues); MAPIFreeBuffer(SPropTagArray); if (lpProps[0].value.lpszA) { if (!strncmp(mailbox, lpProps[0].value.lpszA, strlen(lpProps[0].value.lpszA))) { mapitest_print(mt, "* Step 3.2 - Check: OLD mailbox name [SUCCESS]\n"); } else { mapitest_print(mt, "* Step 3.2 - Check: OLD mailbox name, [FAILURE]\n"); } } /* Release */ mapi_object_release(&obj_store); return true; } /** \details Test the DeleteProps (0xb) operation) This function: -# Opens the mailbox -# Create a test folder -# Creates a reference email, and sets some properties on it -# Delete properties from this message -# Checks that properties got deleted -# Deletes both email and the test folder \todo It would be useful to test the problem return values \param mt pointer to the top-level mapitest structure \return true on success, otherwise false */ _PUBLIC_ bool mapitest_oxcprpt_DeleteProps(struct mapitest *mt) { enum MAPISTATUS retval; mapi_object_t obj_store; mapi_object_t obj_top_folder; mapi_id_t id_top_folder; mapi_object_t obj_ref_folder; mapi_object_t obj_ref_message; const char *name = NULL; const char *subject = NULL; struct SPropValue lpProp[3]; struct SPropTagArray *SPropTagArray; struct SPropValue *lpProps; uint32_t cValues; bool result; /* Step 1. Logon Private Mailbox */ mapi_object_init(&obj_store); retval = OpenMsgStore(mt->session, &obj_store); mapitest_print_retval_step_fmt(mt, "1.", "OpenMsgStore", "(%s)", "Logon Private Mailbox"); if (retval != MAPI_E_SUCCESS) { return false; } mapi_object_init(&obj_top_folder); retval = GetDefaultFolder(&obj_store, &id_top_folder, olFolderTopInformationStore); retval = OpenFolder(&obj_store, id_top_folder, &obj_top_folder); if (retval != MAPI_E_SUCCESS) { return false; } /* Step 2: Create reference folder */ mapi_object_init(&obj_ref_folder); retval = CreateFolder(&obj_top_folder, FOLDER_GENERIC, MT_DIRNAME_TOP, NULL, OPEN_IF_EXISTS, &obj_ref_folder); mapitest_print_retval_step_fmt(mt, "2.", "CreateFolder", "(%s)", "Create the test folder"); if (retval != MAPI_E_SUCCESS) { return false; } /* Step 3: Create reference message */ mapi_object_init(&obj_ref_message); result = mapitest_common_message_create(mt, &obj_ref_folder, &obj_ref_message, MT_MAIL_SUBJECT); mapitest_print_retval_step_fmt(mt, "3.1.", "mapitest_common_message_create", "(%s)", "Create a reference email"); if (result != true) { return false; } retval = SaveChangesMessage(&obj_ref_folder, &obj_ref_message, KeepOpenReadWrite); if (retval != MAPI_E_SUCCESS) { return false; } name = talloc_asprintf(mt->mem_ctx, "Reference: %s", "display name"); subject = talloc_asprintf(mt->mem_ctx, "Reference: %s", "subject"); set_SPropValue_proptag(&lpProp[0], PR_DISPLAY_NAME, (const void *)name); set_SPropValue_proptag(&lpProp[1], PR_CONVERSATION_TOPIC, (const void *)subject); retval = SetProps(&obj_ref_message, 0, lpProp, 2); mapitest_print_retval_step_fmt(mt, "3.2.", "SetProps", "(%s)", "Set email properties"); if (retval != MAPI_E_SUCCESS) { return false; } /* Step 4: Double check with GetProps */ SPropTagArray = set_SPropTagArray(mt->mem_ctx, 0x2, PR_DISPLAY_NAME, PR_CONVERSATION_TOPIC); retval = GetProps(&obj_ref_message, 0, SPropTagArray, &lpProps, &cValues); MAPIFreeBuffer(SPropTagArray); if (lpProps[0].value.lpszA) { if (!strncmp(name, lpProps[0].value.lpszA, strlen(lpProps[0].value.lpszA))) { mapitest_print(mt, "* Step 4.1. - Check: Reference props set - [SUCCESS] (%s)\n", lpProps[0].value.lpszA); } else { mapitest_print(mt, "* Step 4.1. - Check: Reference props set [FAILURE] (%s)\n", lpProps[0].value.lpszA); } } if (lpProps[1].value.lpszA) { if (!strncmp(subject, lpProps[1].value.lpszA, strlen(lpProps[1].value.lpszA))) { mapitest_print(mt, "* Step 4.2. - Check: Reference props set - [SUCCESS] (%s)\n", lpProps[1].value.lpszA); } else { mapitest_print(mt, "* Step 4.2. - Check: Reference props set [FAILURE] (%s)\n", lpProps[1].value.lpszA); } } MAPIFreeBuffer(lpProps); /* Step 5. Delete Properties */ SPropTagArray = set_SPropTagArray(mt->mem_ctx, 0x1, PR_CONVERSATION_TOPIC); retval = DeleteProps(&obj_ref_message, SPropTagArray); MAPIFreeBuffer(SPropTagArray); mapitest_print_retval_step_fmt(mt, "5.", "DeleteProps", "PR_CONVERSATION_TOPIC"); /* Step 6. Double check with GetProps */ SPropTagArray = set_SPropTagArray(mt->mem_ctx, 0x1, PR_CONVERSATION_TOPIC); retval = GetProps(&obj_ref_message, 0, SPropTagArray, &lpProps, &cValues); MAPIFreeBuffer(SPropTagArray); if (get_SPropValue(lpProps, PR_CONVERSATION_TOPIC) == NULL) { mapitest_print(mt, "* Step 5.1. - GetProps verifier [SUCCESS]\n"); } else { mapitest_print(mt, "* Step 5.1. - GetProps verifier [FAILURE]:\n"); } MAPIFreeBuffer(lpProps); /* Step 7: cleanup folders */ retval = DeleteFolder(&obj_top_folder, mapi_object_get_id(&obj_ref_folder), DEL_FOLDERS | DEL_MESSAGES | DELETE_HARD_DELETE, NULL); mapitest_print_retval_step(mt, "6.", "DeleteFolder", retval); /* Release */ mapi_object_release(&obj_ref_message); mapi_object_release(&obj_ref_folder); mapi_object_release(&obj_top_folder); mapi_object_release(&obj_store); return true; } /** \details Test the CopyProps (0x67) operation This function: -# Opens the mailbox -# Creates a test folder -# Creates a reference email, and sets some properties on it -# Checks those properties are set correctly -# Creates a second email, and sets some (different) properties on it -# Checks those properties on the second folder are set correctly -# Copies properties from the reference email to the second email (no overwrite) -# Checks that properties on both emails are correct -# Copies properties again, but with overwrite -# Checks that properties on both emails are correct -# Moves properties from the original email to the second email (no overwrite) -# Checks that properties on both emails are correct -# Deletes both emails and the test folder \todo It would be useful to test the problem return values \param mt pointer to the top-level mapitest structure \return true on success, otherwise false */ _PUBLIC_ bool mapitest_oxcprpt_CopyProps(struct mapitest *mt) { enum MAPISTATUS retval; mapi_object_t obj_store; mapi_object_t obj_top_folder; mapi_id_t id_top_folder; mapi_object_t obj_ref_folder; mapi_object_t obj_ref_message; const char *name = NULL; const char *subject = NULL; struct SPropValue lpProp[3]; struct SPropTagArray *SPropTagArray; struct SPropValue *lpProps; uint32_t cValues; mapi_object_t obj_target_message; const char *targ_name = NULL; const char *targ_dept = NULL; uint16_t problem_count = 999; struct PropertyProblem *problems = NULL; bool result; /* Step 1. Logon Private Mailbox */ mapi_object_init(&obj_store); retval = OpenMsgStore(mt->session, &obj_store); mapitest_print_retval_step_fmt(mt, "1.", "OpenMsgStore", "(%s)", "Logon Private Mailbox"); if (retval != MAPI_E_SUCCESS) { return false; } mapi_object_init(&obj_top_folder); retval = GetDefaultFolder(&obj_store, &id_top_folder, olFolderTopInformationStore); retval = OpenFolder(&obj_store, id_top_folder, &obj_top_folder); if (retval != MAPI_E_SUCCESS) { return false; } /* Step 2: Create reference folder */ mapi_object_init(&obj_ref_folder); retval = CreateFolder(&obj_top_folder, FOLDER_GENERIC, MT_DIRNAME_TOP, NULL, OPEN_IF_EXISTS, &obj_ref_folder); mapitest_print_retval_step_fmt(mt, "2.", "CreateFolder", "(%s)", "Create the test folder"); if (retval != MAPI_E_SUCCESS) { return false; } /* Step 3: Create reference message */ mapi_object_init(&obj_ref_message); result = mapitest_common_message_create(mt, &obj_ref_folder, &obj_ref_message, MT_MAIL_SUBJECT); mapitest_print_retval_step_fmt(mt, "3.1.", "mapitest_common_message_create", "(%s)", "Create a reference email"); if (result != true) { return false; } retval = SaveChangesMessage(&obj_ref_folder, &obj_ref_message, KeepOpenReadWrite); if (retval != MAPI_E_SUCCESS) { return false; } name = talloc_asprintf(mt->mem_ctx, "Reference: %s", "display name"); subject = talloc_asprintf(mt->mem_ctx, "Reference: %s", "subject"); set_SPropValue_proptag(&lpProp[0], PR_DISPLAY_NAME, (const void *)name); set_SPropValue_proptag(&lpProp[1], PR_CONVERSATION_TOPIC, (const void *)subject); retval = SetProps(&obj_ref_message, 0, lpProp, 2); mapitest_print_retval_step_fmt(mt, "3.2.", "SetProps", "(%s)", "Set email properties"); if (retval != MAPI_E_SUCCESS) { return false; } /* Step 4: Double check with GetProps */ SPropTagArray = set_SPropTagArray(mt->mem_ctx, 0x2, PR_DISPLAY_NAME, PR_CONVERSATION_TOPIC); retval = GetProps(&obj_ref_message, 0, SPropTagArray, &lpProps, &cValues); MAPIFreeBuffer(SPropTagArray); if (lpProps[0].value.lpszA) { if (!strncmp(name, lpProps[0].value.lpszA, strlen(lpProps[0].value.lpszA))) { mapitest_print(mt, "* Step 4.1. - Check: Reference props set - [SUCCESS] (%s)\n", lpProps[0].value.lpszA); } else { mapitest_print(mt, "* Step 4.1. - Check: Reference props set [FAILURE] (%s)\n", lpProps[0].value.lpszA); } } if (lpProps[1].value.lpszA) { if (!strncmp(subject, lpProps[1].value.lpszA, strlen(lpProps[1].value.lpszA))) { mapitest_print(mt, "* Step 4.2. - Check: Reference props set - [SUCCESS] (%s)\n", lpProps[1].value.lpszA); } else { mapitest_print(mt, "* Step 4.2. - Check: Reference props set [FAILURE] (%s)\n", lpProps[1].value.lpszA); } } /* Step 5: Create target message */ mapi_object_init(&obj_target_message); result = mapitest_common_message_create(mt, &obj_ref_folder, &obj_target_message, MT_MAIL_SUBJECT); mapitest_print_retval_step_fmt(mt, "5.1.", "mapitest_common_message_create", "(%s)", "Create target email"); if (result != true) { return false; } retval = SaveChangesMessage(&obj_ref_folder, &obj_target_message, KeepOpenReadWrite); if (retval != MAPI_E_SUCCESS) { return false; } targ_name = talloc_asprintf(mt->mem_ctx, "Target: %s", "display name"); targ_dept = talloc_asprintf(mt->mem_ctx, "Target: %s", "department"); set_SPropValue_proptag(&lpProp[0], PR_DISPLAY_NAME, (const void *)targ_name); set_SPropValue_proptag(&lpProp[1], PR_DEPARTMENT_NAME, (const void *)targ_dept); retval = SetProps(&obj_target_message, 0, lpProp, 2); mapitest_print_retval_step_fmt(mt, "5.2.", "SetProps", "(%s)", "set properties on target email"); if (retval != MAPI_E_SUCCESS) { return false; } /* Step 6: Double check with GetProps */ SPropTagArray = set_SPropTagArray(mt->mem_ctx, 0x2, PR_DISPLAY_NAME, PR_DEPARTMENT_NAME); retval = GetProps(&obj_target_message, 0, SPropTagArray, &lpProps, &cValues); MAPIFreeBuffer(SPropTagArray); if (lpProps[0].value.lpszA) { if (!strncmp(targ_name, lpProps[0].value.lpszA, strlen(lpProps[0].value.lpszA))) { mapitest_print(mt, "* Step 6A - Check: Reference props set - [SUCCESS] (%s)\n", lpProps[0].value.lpszA); } else { mapitest_print(mt, "* Step 6A - Check: Reference props set [FAILURE] (%s)\n", lpProps[0].value.lpszA); } } if (lpProps[1].value.lpszA) { if (!strncmp(targ_dept, lpProps[1].value.lpszA, strlen(lpProps[1].value.lpszA))) { mapitest_print(mt, "* Step 6B - Check: Reference props set - [SUCCESS] (%s)\n", lpProps[1].value.lpszA); } else { mapitest_print(mt, "* Step 6B - Check: Reference props set [FAILURE] (%s)\n", lpProps[1].value.lpszA); } } /* Step 7: Copy properties, no overwrite */ SPropTagArray = set_SPropTagArray(mt->mem_ctx, 0x2, PR_DISPLAY_NAME, PR_CONVERSATION_TOPIC); retval = CopyProps(&obj_ref_message, &obj_target_message, SPropTagArray, CopyFlagsNoOverwrite, &problem_count, &problems); mapitest_print_retval_step_fmt(mt, "7.", "CopyProps", "(%s)", "no overwrite"); MAPIFreeBuffer(problems); if (retval != MAPI_E_SUCCESS) { return false; } MAPIFreeBuffer(SPropTagArray); /* Step 8: Double check with GetProps */ SPropTagArray = set_SPropTagArray(mt->mem_ctx, 0x2, PR_DISPLAY_NAME, PR_CONVERSATION_TOPIC); retval = GetProps(&obj_ref_message, 0, SPropTagArray, &lpProps, &cValues); MAPIFreeBuffer(SPropTagArray); if (lpProps[0].value.lpszA) { if (!strncmp(name, lpProps[0].value.lpszA, strlen(lpProps[0].value.lpszA))) { mapitest_print(mt, "* Step 8A - Check: Reference props still good - [SUCCESS] (%s)\n", lpProps[0].value.lpszA); } else { mapitest_print(mt, "* Step 8A - Check: Reference props still good [FAILURE] (%s)\n", lpProps[0].value.lpszA); } } if (lpProps[1].value.lpszA) { if (!strncmp(subject, lpProps[1].value.lpszA, strlen(lpProps[1].value.lpszA))) { mapitest_print(mt, "* Step 8B - Check: Reference props still good - [SUCCESS] (%s)\n", lpProps[1].value.lpszA); } else { mapitest_print(mt, "* Step 8B - Check: Reference props still good [FAILURE] (%s)\n", lpProps[1].value.lpszA); } } SPropTagArray = set_SPropTagArray(mt->mem_ctx, 0x3, PR_DISPLAY_NAME, PR_CONVERSATION_TOPIC, PR_DEPARTMENT_NAME); retval = GetProps(&obj_target_message, 0, SPropTagArray, &lpProps, &cValues); MAPIFreeBuffer(SPropTagArray); /* this one shouldn't be overwritten */ if (lpProps[0].value.lpszA) { if (!strncmp(targ_name, lpProps[0].value.lpszA, strlen(lpProps[0].value.lpszA))) { mapitest_print(mt, "* Step 8C - Check: Reference props copy - [SUCCESS] (%s)\n", lpProps[0].value.lpszA); } else { mapitest_print(mt, "* Step 8C - Check: Reference props copy [FAILURE] (%s)\n", lpProps[0].value.lpszA); } } /* this one should be copied */ if (lpProps[1].value.lpszA) { if (!strncmp(subject, lpProps[1].value.lpszA, strlen(lpProps[1].value.lpszA))) { mapitest_print(mt, "* Step 8D - Check: Reference props copy - [SUCCESS] (%s)\n", lpProps[1].value.lpszA); } else { mapitest_print(mt, "* Step 8D - Check: Reference props copy [FAILURE] (%s)\n", lpProps[1].value.lpszA); } } /* this one should be unchanged */ if (lpProps[2].value.lpszA) { if (!strncmp(targ_dept, lpProps[2].value.lpszA, strlen(lpProps[2].value.lpszA))) { mapitest_print(mt, "* Step 8E - Check: Reference props copy - [SUCCESS] (%s)\n", lpProps[2].value.lpszA); } else { mapitest_print(mt, "* Step 8E - Check: Reference props copy [FAILURE] (%s)\n", lpProps[2].value.lpszA); } } /* Step 9: Copy properties, with overwrite */ SPropTagArray = set_SPropTagArray(mt->mem_ctx, 0x2, PR_DISPLAY_NAME, PR_CONVERSATION_TOPIC); retval = CopyProps(&obj_ref_message, &obj_target_message, SPropTagArray, 0x0, &problem_count, &problems); MAPIFreeBuffer(SPropTagArray); MAPIFreeBuffer(problems); mapitest_print_retval_step_fmt(mt, "9.", "CopyProps", "(%s)", "with overwrite"); if (retval != MAPI_E_SUCCESS) { return false; } /* Step 10: Double check with GetProps */ SPropTagArray = set_SPropTagArray(mt->mem_ctx, 0x2, PR_DISPLAY_NAME, PR_CONVERSATION_TOPIC); retval = GetProps(&obj_ref_message, 0, SPropTagArray, &lpProps, &cValues); MAPIFreeBuffer(SPropTagArray); if (lpProps[0].value.lpszA) { if (!strncmp(name, lpProps[0].value.lpszA, strlen(lpProps[0].value.lpszA))) { mapitest_print(mt, "* Step 10A - Check: Reference props still good - [SUCCESS] (%s)\n", lpProps[0].value.lpszA); } else { mapitest_print(mt, "* Step 10A - Check: Reference props still good [FAILURE] (%s)\n", lpProps[0].value.lpszA); } } if (lpProps[1].value.lpszA) { if (!strncmp(subject, lpProps[1].value.lpszA, strlen(lpProps[1].value.lpszA))) { mapitest_print(mt, "* Step 10B - Check: Reference props still good - [SUCCESS] (%s)\n", lpProps[1].value.lpszA); } else { mapitest_print(mt, "* Step 10B - Check: Reference props still good [FAILURE] (%s)\n", lpProps[1].value.lpszA); } } SPropTagArray = set_SPropTagArray(mt->mem_ctx, 0x3, PR_DISPLAY_NAME, PR_CONVERSATION_TOPIC, PR_DEPARTMENT_NAME); retval = GetProps(&obj_target_message, 0, SPropTagArray, &lpProps, &cValues); MAPIFreeBuffer(SPropTagArray); /* this one should now be overwritten */ if (lpProps[0].value.lpszA) { if (!strncmp(name, lpProps[0].value.lpszA, strlen(lpProps[0].value.lpszA))) { mapitest_print(mt, "* Step 10C - Check: Reference props copy - [SUCCESS] (%s)\n", lpProps[0].value.lpszA); } else { mapitest_print(mt, "* Step 10C - Check: Reference props copy [FAILURE] (%s)\n", lpProps[0].value.lpszA); } } /* this one should be copied */ if (lpProps[1].value.lpszA) { if (!strncmp(subject, lpProps[1].value.lpszA, strlen(lpProps[1].value.lpszA))) { mapitest_print(mt, "* Step 10D - Check: Reference props copy - [SUCCESS] (%s)\n", lpProps[1].value.lpszA); } else { mapitest_print(mt, "* Step 10D - Check: Reference props copy [FAILURE] (%s)\n", lpProps[1].value.lpszA); } } /* this one should be unchanged */ if (lpProps[2].value.lpszA) { if (!strncmp(targ_dept, lpProps[2].value.lpszA, strlen(lpProps[2].value.lpszA))) { mapitest_print(mt, "* Step 10E - Check: Reference props copy - [SUCCESS] (%s)\n", lpProps[2].value.lpszA); } else { mapitest_print(mt, "* Step 10E - Check: Reference props copy [FAILURE] (%s)\n", lpProps[2].value.lpszA); } } if ( mt->info.rgwServerVersion[0] >= Exchange2010SP0Version ) { /* the combination of CopyFlagsNoOverwrite|CopyFlagsMove isn't support in Exchange2010 */ goto cleanup; } /* Step 11: Move properties, no overwrite */ SPropTagArray = set_SPropTagArray(mt->mem_ctx, 0x2, PR_DISPLAY_NAME, PR_CONVERSATION_TOPIC); retval = CopyProps(&obj_ref_message, &obj_target_message, SPropTagArray, CopyFlagsNoOverwrite|CopyFlagsMove, &problem_count, &problems); MAPIFreeBuffer(SPropTagArray); if (problem_count) { MAPIFreeBuffer(problems); } mapitest_print_retval_step_fmt(mt, "11.", "CopyProps", "(%s)", "move"); if (retval != MAPI_E_SUCCESS) { return false; } /* Step 12: Double check with GetProps */ SPropTagArray = set_SPropTagArray(mt->mem_ctx, 0x2, PR_DISPLAY_NAME, PR_CONVERSATION_TOPIC); retval = GetProps(&obj_ref_message, 0, SPropTagArray, &lpProps, &cValues); MAPIFreeBuffer(SPropTagArray); if (cValues == 2) { mapitest_print(mt, "* Step 12A - Properties removed [SUCCESS]\n"); } else { mapitest_print(mt, "* Step 12A - Properties removed [FAILURE]\n"); } SPropTagArray = set_SPropTagArray(mt->mem_ctx, 0x3, PR_DISPLAY_NAME, PR_CONVERSATION_TOPIC, PR_DEPARTMENT_NAME); retval = GetProps(&obj_target_message, 0, SPropTagArray, &lpProps, &cValues); MAPIFreeBuffer(SPropTagArray); if (lpProps[0].value.lpszA) { if (!strncmp(name, lpProps[0].value.lpszA, strlen(lpProps[0].value.lpszA))) { mapitest_print(mt, "* Step 12B - Check: Reference props move - [SUCCESS] (%s)\n", lpProps[0].value.lpszA); } else { mapitest_print(mt, "* Step 12B - Check: Reference props move [FAILURE] (%s)\n", lpProps[0].value.lpszA); } } if (lpProps[1].value.lpszA) { if (!strncmp(subject, lpProps[1].value.lpszA, strlen(lpProps[1].value.lpszA))) { mapitest_print(mt, "* Step 12C - Check: Reference props move - [SUCCESS] (%s)\n", lpProps[1].value.lpszA); } else { mapitest_print(mt, "* Step 12C - Check: Reference props move [FAILURE] (%s)\n", lpProps[1].value.lpszA); } } if (lpProps[2].value.lpszA) { if (!strncmp(targ_dept, lpProps[2].value.lpszA, strlen(lpProps[2].value.lpszA))) { mapitest_print(mt, "* Step 12D - Check: Reference props move - [SUCCESS] (%s)\n", lpProps[2].value.lpszA); } else { mapitest_print(mt, "* Step 12D - Check: Reference props move [FAILURE] (%s)\n", lpProps[2].value.lpszA); } } cleanup: /* Cleanup reference strings */ MAPIFreeBuffer((void *)subject); MAPIFreeBuffer((void *)name); MAPIFreeBuffer((void *)targ_name); MAPIFreeBuffer((void *)targ_dept); /* Step 13: cleanup folders */ retval = DeleteFolder(&obj_top_folder, mapi_object_get_id(&obj_ref_folder), DEL_FOLDERS | DEL_MESSAGES | DELETE_HARD_DELETE, NULL); mapitest_print_retval_step(mt, "13.1.", "DeleteFolder", retval); /* Release */ mapi_object_release(&obj_ref_message); mapi_object_release(&obj_ref_folder); mapi_object_release(&obj_top_folder); mapi_object_release(&obj_store); return true; } /** \details Test Stream operations. This test uses related stream operations: OpenStream (0x2b), SetStreamSize (0x2f), WriteStream (0x2d), CommitStream (0x5d), ReadStream (0x2c), SeekStream (0x2e), LockRegionStream (0x5b), UnlockRegionStream (0x5c), CloneStream (0x3b) This function: -# Logon -# Open Outbox folder -# Create message -# Create attachment and set properties -# Open the stream -# Set the stream size -# Write into the stream -# Commit the stream -# Save the message -# Get stream size and compare values -# Open the stream again with different permissions -# Read the stream and compare buffers -# SeekStream at 0x1000 from the end of the stream -# Read the 0x1000 last bytes and check if it matches -# Lock a range of the stream -# TODO: test if the locking works -# Unlock a range of the stream -# Clone the stream -# Delete the message; \param mt pointer to the top-level mapitest structure \return true on success, otherwise -1 */ _PUBLIC_ bool mapitest_oxcprpt_Stream(struct mapitest *mt) { enum MAPISTATUS retval; bool ret = true; mapi_object_t obj_store; mapi_object_t obj_folder; mapi_object_t obj_message; mapi_object_t obj_attach; mapi_object_t obj_stream; mapi_object_t obj_stream_clone; mapi_id_t id_folder; DATA_BLOB data; struct SPropValue attach[3]; char *stream = NULL; char *out_stream = NULL; uint32_t stream_len = 0x32146; unsigned char buf[MT_STREAM_MAX_SIZE]; uint32_t StreamSize = 0; uint16_t read_size = 0; uint16_t write_len = 0; uint32_t len = 0; uint32_t offset = 0; mapi_id_t id_msgs[1]; uint32_t i; uint64_t NewPosition; stream = mapitest_common_genblob(mt->mem_ctx, stream_len); if (stream == NULL) { return false; } /* Step 1. Logon */ mapi_object_init(&obj_store); retval = OpenMsgStore(mt->session, &obj_store); mapitest_print_retval(mt, "OpenMsgStore"); if (retval != MAPI_E_SUCCESS) { return false; } /* Step 2. Open Inbox folder */ retval = GetDefaultFolder(&obj_store, &id_folder, olFolderInbox); mapitest_print_retval(mt, "GetDefaultFolder"); if (retval != MAPI_E_SUCCESS) { return false; } mapi_object_init(&obj_folder); retval = OpenFolder(&obj_store, id_folder, &obj_folder); mapitest_print_retval(mt, "OpenFolder"); if (retval != MAPI_E_SUCCESS) { return false; } /* Step 3. Create the message */ mapi_object_init(&obj_message); ret = mapitest_common_message_create(mt, &obj_folder, &obj_message, MT_MAIL_SUBJECT); mapitest_print_retval(mt, "Message Creation"); if (ret != true) { return false; } /* Step 4. Create the attachment */ mapi_object_init(&obj_attach); retval = CreateAttach(&obj_message, &obj_attach); mapitest_print_retval(mt, "CreateAttach"); if (retval != MAPI_E_SUCCESS) { ret = false; } attach[0].ulPropTag = PR_ATTACH_METHOD; attach[0].value.l = ATTACH_BY_VALUE; attach[1].ulPropTag = PR_RENDERING_POSITION; attach[1].value.l = 0; attach[2].ulPropTag = PR_ATTACH_FILENAME; attach[2].value.lpszA = MT_MAIL_ATTACH; retval = SetProps(&obj_attach, 0, attach, 3); if (retval != MAPI_E_SUCCESS) { ret = false; } /* Step 5. Open the stream */ mapi_object_init(&obj_stream); retval = OpenStream(&obj_attach, PR_ATTACH_DATA_BIN, 2, &obj_stream); mapitest_print_retval(mt, "OpenStream"); if (retval != MAPI_E_SUCCESS) { ret = false; } /* Step 6. Set the stream size */ retval = SetStreamSize(&obj_stream, (uint64_t) stream_len); mapitest_print_retval(mt, "SetStreamSize"); if (retval != MAPI_E_SUCCESS) { ret = false; } /* Step 7. Write the stream */ write_len = 0; StreamSize = stream_len; for (offset = 0, len = MT_STREAM_MAX_SIZE, i = 0; StreamSize; i++) { data.length = len; data.data = (uint8_t *)stream + offset; retval = WriteStream(&obj_stream, &data, &write_len); mapitest_print_retval_fmt(mt, "WriteStream", "[%d] (0x%x bytes written)", i, write_len); if (retval != MAPI_E_SUCCESS) { ret = false; break; } StreamSize -= write_len; if (StreamSize > MT_STREAM_MAX_SIZE) { offset += MT_STREAM_MAX_SIZE; } else { offset += write_len; len = StreamSize; } } /* Step 8. Commit the stream */ retval = CommitStream(&obj_stream); mapitest_print_retval(mt, "CommitStream"); if (retval != MAPI_E_SUCCESS) { ret = false; } /* Step 9. Save the attachment */ retval = SaveChangesAttachment(&obj_message, &obj_attach, KeepOpenReadOnly); mapitest_print_retval(mt, "SaveChangesAttachment"); if (retval != MAPI_E_SUCCESS) { ret = false; } retval = SaveChangesMessage(&obj_folder, &obj_message, KeepOpenReadOnly); mapitest_print_retval(mt, "SaveChangesMessage"); if (retval != MAPI_E_SUCCESS) { ret = false; } /* Step 10. Get stream size */ retval = GetStreamSize(&obj_stream, &StreamSize); mapitest_print_retval(mt, "GetStreamSize"); if (retval != MAPI_E_SUCCESS) { ret = false; } mapitest_print(mt, "* %-35s: %s\n", "StreamSize comparison", (StreamSize == stream_len) ? "[PASSED]" : "[FAILURE]"); /* Step 11. Read the stream */ mapi_object_release(&obj_stream); mapi_object_init(&obj_stream); retval = OpenStream(&obj_attach, PR_ATTACH_DATA_BIN, 0, &obj_stream); mapitest_print_retval(mt, "OpenStream"); if (retval != MAPI_E_SUCCESS) { ret = false; } offset = 0; out_stream = talloc_size(mt->mem_ctx, StreamSize + 1); do { retval = ReadStream(&obj_stream, buf, MT_STREAM_MAX_SIZE, &read_size); mapitest_print_retval_fmt(mt, "ReadStream", "(0x%x bytes read)", read_size); memcpy(out_stream + offset, buf, read_size); offset += read_size; if (retval != MAPI_E_SUCCESS) { ret = false; break; } } while (read_size && (offset != StreamSize)); out_stream[offset] = '\0'; if (offset) { if (!strcmp(stream, out_stream)) { mapitest_print(mt, "* %-35s: [IN,OUT] stream [PASSED]\n", "Comparison"); } else { mapitest_print(mt, "* %-35s: [IN,OUT] stream [FAILURE]\n", "Comparison"); } } /* Step 12. SeekStream from the end of the stream */ retval = SeekStream(&obj_stream, 0x2, (uint64_t) -0x1000, &NewPosition); mapitest_print_retval(mt, "SeekStream"); if (retval != MAPI_E_SUCCESS) { ret = false; } talloc_free(out_stream); out_stream = talloc_size(mt->mem_ctx, 0x1001); retval = ReadStream(&obj_stream, (uint8_t *)out_stream, 0x1000, &read_size); out_stream[read_size] = '\0'; mapitest_print_retval_fmt(mt, "ReadStream", "(0x%x bytes read)", read_size); if (retval != MAPI_E_SUCCESS) { ret = false; } if (read_size && !strcmp(out_stream, stream + StreamSize - read_size)) { mapitest_print(mt, "* %-35s: [SUCCESS]\n", "Comparison"); } else { mapitest_print(mt, "* %-35s: [FAILURE]\n", "Comparison"); } mapi_object_init(&obj_stream_clone); if (mt->info.rgwServerVersion[0] >= Exchange2010SP0Version) { mapitest_print(mt, "* SKIPPING test for LockRegionStream, UnlockRegionStream and CloneStream\n"); } else { /* Step 13. Lock a region */ retval = LockRegionStream(&obj_stream, 0x2000, 0x1000, 0x0); mapitest_print_retval(mt, "LockRegionStream"); if (retval != MAPI_E_SUCCESS) { ret = false; } /* TODO: Step 14. Test the locking */ /* Step 15. Unlock the region */ retval = UnlockRegionStream(&obj_stream, 0x2000, 0x1000, 0x0); mapitest_print_retval(mt, "UnlockRegionStream"); if (retval != MAPI_E_SUCCESS) { ret = false; } /* Step 16. Clone the stream */ retval = CloneStream(&obj_stream, &obj_stream_clone); mapitest_print_retval(mt, "CloneStream"); if (retval != MAPI_E_SUCCESS) { ret = false; } /* Step 17. Test the clone */ retval = SeekStream(&obj_stream_clone, 0x0, 0, &NewPosition); mapitest_print_retval(mt, "SeekStream"); if (retval != MAPI_E_SUCCESS) { ret = false; } retval = ReadStream(&obj_stream_clone, buf, MT_STREAM_MAX_SIZE, &read_size); mapitest_print_retval_fmt(mt, "ReadStream", "(0x%x bytes read)", read_size); if (retval != MAPI_E_SUCCESS) { ret = false; } } /* Delete the message */ errno = 0; id_msgs[0] = mapi_object_get_id(&obj_message); retval = DeleteMessage(&obj_folder, id_msgs, 1); mapitest_print_retval(mt, "DeleteMessage"); if (retval != MAPI_E_SUCCESS) { ret = false; } /* Release */ mapi_object_release(&obj_stream_clone); mapi_object_release(&obj_stream); mapi_object_release(&obj_attach); mapi_object_release(&obj_message); mapi_object_release(&obj_folder); mapi_object_release(&obj_store); talloc_free(stream); talloc_free(out_stream); return ret; } /** \details Test the CopyToStream (0x3a) operation This function: -# Logon the mailbox -# Open the inbox folder -# Create a sample messages with an attachment -# Create 2 streams -# Fill the first stream with random data -# Seek stream positions to the beginning -# CopyToStream data from first stream to the second stream -# Read dst stream and compare with src stream -# Delete the message \param mt pointer to the top-level mapitest structure \return true on success, otherwise false */ _PUBLIC_ bool mapitest_oxcprpt_CopyToStream(struct mapitest *mt) { enum MAPISTATUS retval; bool ret = true; mapi_object_t obj_store; mapi_object_t obj_folder; mapi_object_t obj_message; mapi_object_t obj_attach; mapi_object_t obj_attach2; mapi_object_t obj_stream; mapi_object_t obj_stream2; mapi_id_t id_folder; mapi_id_t id_msgs[1]; struct SPropValue attach[3]; DATA_BLOB data; char *stream = NULL; char *dst_stream = NULL; uint32_t stream_len = 0x32146; unsigned char buf[MT_STREAM_MAX_SIZE]; uint32_t StreamSize = 0; uint16_t write_len = 0; uint16_t read_size = 0; uint32_t len = 0; uint32_t offset = 0; uint32_t i; uint64_t ReadByteCount = 0; uint64_t WrittenByteCount = 0; uint64_t NewPosition = 0; stream = mapitest_common_genblob(mt->mem_ctx, stream_len); if (stream == NULL) { return false; } /* Step 1. Logon */ mapi_object_init(&obj_store); retval = OpenMsgStore(mt->session, &obj_store); mapitest_print_retval(mt, "OpenMsgStore"); if (retval != MAPI_E_SUCCESS) { return false; } /* Step 2. Open Inbox folder */ retval = GetDefaultFolder(&obj_store, &id_folder, olFolderInbox); mapitest_print_retval(mt, "GetDefaultFolder"); if (retval != MAPI_E_SUCCESS) { return false; } mapi_object_init(&obj_folder); retval = OpenFolder(&obj_store, id_folder, &obj_folder); mapitest_print_retval(mt, "OpenFolder"); if (retval != MAPI_E_SUCCESS) { return false; } /* Step 3. Create the message */ mapi_object_init(&obj_message); ret = mapitest_common_message_create(mt, &obj_folder, &obj_message, MT_MAIL_SUBJECT); mapitest_print_retval(mt, "Message Creation"); if (ret != true) { return false; } /* Step 4. Create the first attachment */ mapi_object_init(&obj_attach); retval = CreateAttach(&obj_message, &obj_attach); mapitest_print_retval(mt, "CreateAttach"); if (retval != MAPI_E_SUCCESS) { ret = false; } attach[0].ulPropTag = PR_ATTACH_METHOD; attach[0].value.l = ATTACH_BY_VALUE; attach[1].ulPropTag = PR_RENDERING_POSITION; attach[1].value.l = 0; attach[2].ulPropTag = PR_ATTACH_FILENAME; attach[2].value.lpszA = MT_MAIL_ATTACH; retval = SetProps(&obj_attach, 0, attach, 3); if (retval != MAPI_E_SUCCESS) { ret = false; } /* Step 5. Open the stream */ mapi_object_init(&obj_stream); retval = OpenStream(&obj_attach, PR_ATTACH_DATA_BIN, 2, &obj_stream); mapitest_print_retval(mt, "OpenStream"); if (retval != MAPI_E_SUCCESS) { ret = false; } /* Step 6. Set the stream size */ retval = SetStreamSize(&obj_stream, (uint64_t) stream_len); mapitest_print_retval(mt, "SetStreamSize"); if (retval != MAPI_E_SUCCESS) { ret = false; } /* Step 7. Write the stream */ write_len = 0; StreamSize = stream_len; for (offset = 0, len = MT_STREAM_MAX_SIZE, i = 0; StreamSize; i++) { data.length = len; data.data = (uint8_t *)stream + offset; retval = WriteStream(&obj_stream, &data, &write_len); mapitest_print_retval_fmt(mt, "WriteStream", "[%d] (0x%x bytes written)", i, write_len); StreamSize -= write_len; if (StreamSize > MT_STREAM_MAX_SIZE) { offset += MT_STREAM_MAX_SIZE; } else { offset += write_len; len = StreamSize; } } /* Step 8. Commit the stream */ retval = CommitStream(&obj_stream); mapitest_print_retval(mt, "CommitStream"); if (retval != MAPI_E_SUCCESS) { ret = false; } /* Step 9. Save the attachment */ retval = SaveChangesAttachment(&obj_message, &obj_attach, KeepOpenReadOnly); mapitest_print_retval(mt, "SaveChangesAttachment"); /* Step 10. Create the second attachment */ mapi_object_init(&obj_attach2); retval = CreateAttach(&obj_message, &obj_attach2); mapitest_print_retval(mt, "CreateAttach"); if (retval != MAPI_E_SUCCESS) { ret = false; } attach[0].ulPropTag = PR_ATTACH_METHOD; attach[0].value.l = ATTACH_BY_VALUE; attach[1].ulPropTag = PR_RENDERING_POSITION; attach[1].value.l = 0; attach[2].ulPropTag = PR_ATTACH_FILENAME; attach[2].value.lpszA = MT_MAIL_ATTACH2; retval = SetProps(&obj_attach2, 0, attach, 3); if (retval != MAPI_E_SUCCESS) { ret = false; } /* Step 11. Open the dst stream */ mapi_object_init(&obj_stream2); retval = OpenStream(&obj_attach2, PR_ATTACH_DATA_BIN, 2, &obj_stream2); mapitest_print_retval(mt, "OpenStream"); if (retval != MAPI_E_SUCCESS) { ret = false; } /* Step 12. Get src stream size */ retval = GetStreamSize(&obj_stream, &StreamSize); mapitest_print_retval_fmt(mt, "GetStreamSize", "(%s: 0x%x)", "Src", StreamSize); if (retval != MAPI_E_SUCCESS) { ret = false; } /* Step 13. Reset streams positions to the beginning */ retval = SeekStream(&obj_stream, 0, 0, &NewPosition); mapitest_print_retval_fmt(mt, "SeekStream", "(%s)", "Src"); if (retval != MAPI_E_SUCCESS) { ret = false; } retval = SeekStream(&obj_stream2, 0, 0, &NewPosition); mapitest_print_retval_fmt(mt, "SeekStream", "(%s)", "Dst"); if (retval != MAPI_E_SUCCESS) { ret = false; } /* Step 14. Copy src to dst stream */ retval = CopyToStream(&obj_stream, &obj_stream2, StreamSize, &ReadByteCount, &WrittenByteCount); mapitest_print_retval(mt, "CopyToStream"); if (retval != MAPI_E_SUCCESS) { ret = false; } /* Step 14. Save the attachment */ retval = SaveChangesAttachment(&obj_message, &obj_attach2, KeepOpenReadOnly); mapitest_print_retval(mt, "SaveChangesAttachment"); retval = SaveChangesMessage(&obj_folder, &obj_message, KeepOpenReadOnly); mapitest_print_retval(mt, "SaveChangesMessage"); if (retval != MAPI_E_SUCCESS) { ret = false; } /* Step 15. Compare values */ mapitest_print(mt, "* %-35s: 0x%llx - 0x%llx %s\n", "Read/Write bytes comparison", ReadByteCount, WrittenByteCount, (ReadByteCount == WrittenByteCount) ? "[SUCCESS]" : "[FAILURE]"); /* Step 16. Get dst stream size */ retval = GetStreamSize(&obj_stream2, &StreamSize); mapitest_print_retval_fmt(mt, "GetStreamSize", "(%s: 0x%x)", "Dst", StreamSize); if (retval != MAPI_E_SUCCESS) { ret = false; } retval = SeekStream(&obj_stream2, 0, 0, &NewPosition); mapitest_print_retval_fmt(mt, "SeekStream", "(%s)", "Dst"); if (retval != MAPI_E_SUCCESS) { ret = false; } /* Step 17. Read the dst stream */ offset = 0; dst_stream = talloc_size(mt->mem_ctx, StreamSize + 1); do { retval = ReadStream(&obj_stream2, buf, MT_STREAM_MAX_SIZE, &read_size); mapitest_print_retval_fmt(mt, "ReadStream", "(0x%x bytes read)", read_size); memcpy(dst_stream + offset, buf, read_size); offset += read_size; if (retval != MAPI_E_SUCCESS) { ret = false; break; } } while (read_size || offset != StreamSize); dst_stream[offset] = '\0'; /* Step 18. Compare streams */ if (!strcmp(stream, dst_stream)) { mapitest_print(mt, "* %-35s: [SUCCESS]\n", "Comparison"); } else { mapitest_print(mt, "* %-35s: [FAILURE]\n", "Comparison"); } /* Step 19. Delete Message */ errno = 0; id_msgs[0] = mapi_object_get_id(&obj_message); retval = DeleteMessage(&obj_folder, id_msgs, 1); mapitest_print_retval(mt, "DeleteMessage"); if (retval != MAPI_E_SUCCESS) { ret = false; } /* Release */ mapi_object_release(&obj_stream2); mapi_object_release(&obj_stream); mapi_object_release(&obj_attach2); mapi_object_release(&obj_attach); mapi_object_release(&obj_message); mapi_object_release(&obj_folder); mapi_object_release(&obj_store); talloc_free(stream); talloc_free(dst_stream); return ret; } /** \details Test the CopyTo (0x39) operation This function: -# Opens the mailbox -# Creates a test folder -# Creates a reference email, and sets some properties on it -# Checks those properties are set correctly -# Creates a second email, and sets some (different) properties on it -# Checks those properties on the second folder are set correctly -# Copies properties from the reference email to the second email (no overwrite) -# Checks that properties on both emails are correct -# Copies properties again, but with overwrite -# Checks that properties on both emails are correct -# Moves properties from the original email to the second email (no overwrite) -# Checks that properties on both emails are correct -# Creates an attachment (with properties) on the reference email -# Creates an attachment (with different properties) on the target email -# Copies the properties on the reference email to the target -# Checks the properties on both attachments are correct -# Creates another folder -# Copies properties from the test folder to the new folder -# Checks that the properties on both folders are correct -# Deletes both emails and the test folders \todo It would be useful to test the problem return values \param mt pointer to the top-level mapitest structure \return true on success, otherwise false */ _PUBLIC_ bool mapitest_oxcprpt_CopyTo(struct mapitest *mt) { enum MAPISTATUS retval; mapi_object_t obj_store; mapi_object_t obj_top_folder; mapi_id_t id_top_folder; mapi_object_t obj_ref_folder; mapi_object_t obj_targ_folder; mapi_object_t obj_ref_message; mapi_object_t obj_target_message; mapi_object_t obj_ref_attach; mapi_object_t obj_targ_attach; const char *name = NULL; const char *subject = NULL; const char *dept = NULL; struct SPropValue lpProp[3]; struct SPropTagArray *exclude; struct SPropTagArray *SPropTagArray; struct SPropValue *lpProps; uint32_t cValues; const char *targ_name = NULL; const char *targ_dept = NULL; uint16_t problem_count = 999; struct PropertyProblem *problems = NULL; bool result; bool ret = true; /* Step 1. Logon Private Mailbox */ mapi_object_init(&obj_store); mapi_object_init(&obj_top_folder); mapi_object_init(&obj_ref_folder); mapi_object_init(&obj_targ_folder); mapi_object_init(&obj_ref_message); mapi_object_init(&obj_target_message); mapi_object_init(&obj_ref_attach); mapi_object_init(&obj_targ_attach); retval = OpenMsgStore(mt->session, &obj_store); mapitest_print_retval(mt, "OpenMsgStore"); if (retval != MAPI_E_SUCCESS) { return false; } retval = GetDefaultFolder(&obj_store, &id_top_folder, olFolderTopInformationStore); mapitest_print_retval(mt, "GetDefaultFolder"); retval = OpenFolder(&obj_store, id_top_folder, &obj_top_folder); mapitest_print_retval(mt, "OpenFolder"); if (retval != MAPI_E_SUCCESS) { ret = false; goto cleanup; } /* Step 2: Create reference folder */ retval = CreateFolder(&obj_top_folder, FOLDER_GENERIC, MT_DIRNAME_TOP, NULL, OPEN_IF_EXISTS, &obj_ref_folder); mapitest_print_retval_fmt(mt, "CreateFolder", "(Create test folder)"); if (retval != MAPI_E_SUCCESS) { ret = false; goto cleanup; } lpProp[0].ulPropTag = PR_CONTAINER_CLASS; lpProp[0].value.lpszA = "IPF.Note"; retval = SetProps(&obj_ref_folder, 0, lpProp, 1); mapitest_print_retval(mt, "SetProps"); if (retval != MAPI_E_SUCCESS) { ret = false; goto cleanup; } /* Step 3: Create reference message */ result = mapitest_common_message_create(mt, &obj_ref_folder, &obj_ref_message, MT_MAIL_SUBJECT); mapitest_print_retval(mt, "mapitest_common_message_create"); if (result != true) { ret = false; goto cleanup; } retval = SaveChangesMessage(&obj_ref_folder, &obj_ref_message, KeepOpenReadWrite); mapitest_print_retval(mt, "SaveChangesMessage"); if (retval != MAPI_E_SUCCESS) { ret = false; goto cleanup; } name = talloc_asprintf(mt->mem_ctx, "Reference: %s", "display name"); subject = talloc_asprintf(mt->mem_ctx, "Reference: %s", "subject"); dept = talloc_asprintf(mt->mem_ctx, "Reference: %s", "dept"); set_SPropValue_proptag(&lpProp[0], PR_DISPLAY_NAME, (const void *)name); set_SPropValue_proptag(&lpProp[1], PR_SUBJECT, (const void *)subject); set_SPropValue_proptag(&lpProp[2], PR_DEPARTMENT_NAME, (const void *)dept); retval = SetProps(&obj_ref_message, 0, lpProp, 3); mapitest_print_retval(mt, "SetProps"); if (retval != MAPI_E_SUCCESS) { ret = false; goto cleanup; } /* Step 4: Double check with GetProps */ SPropTagArray = set_SPropTagArray(mt->mem_ctx, 0x3, PR_DISPLAY_NAME, PR_SUBJECT, PR_DEPARTMENT_NAME); retval = GetProps(&obj_ref_message, 0, SPropTagArray, &lpProps, &cValues); MAPIFreeBuffer(SPropTagArray); if (lpProps[0].value.lpszA) { if (!strncmp(name, lpProps[0].value.lpszA, strlen(lpProps[0].value.lpszA))) { mapitest_print(mt, "* Step 4A - Check: Reference props set - [SUCCESS] (%s)\n", lpProps[0].value.lpszA); } else { mapitest_print(mt, "* Step 4A - Check: Reference props set [FAILURE] (%s)\n", lpProps[0].value.lpszA); ret = false; goto cleanup; } } if (lpProps[1].value.lpszA) { if (!strncmp(subject, lpProps[1].value.lpszA, strlen(lpProps[1].value.lpszA))) { mapitest_print(mt, "* Step 4B - Check: Reference props set - [SUCCESS] (%s)\n", lpProps[1].value.lpszA); } else { mapitest_print(mt, "* Step 4B - Check: Reference props set [FAILURE] (%s)\n", lpProps[1].value.lpszA); ret = false; goto cleanup; } } if (lpProps[2].value.lpszA) { if (!strncmp(dept, lpProps[2].value.lpszA, strlen(lpProps[2].value.lpszA))) { mapitest_print(mt, "* Step 4C - Check: Reference props set - [SUCCESS] (%s)\n", lpProps[2].value.lpszA); } else { mapitest_print(mt, "* Step 4C - Check: Reference props set [FAILURE] (%s)\n", lpProps[2].value.lpszA); ret = false; goto cleanup; } } /* Step 5: Create target message */ result = mapitest_common_message_create(mt, &obj_ref_folder, &obj_target_message, MT_MAIL_SUBJECT); mapitest_print_retval(mt, "mapitest_common_message_create"); if (result != true) { ret = false; goto cleanup; } retval = SaveChangesMessage(&obj_ref_folder, &obj_target_message, KeepOpenReadWrite); mapitest_print_retval_clean(mt, "5A. SaveChangesMessage", retval); if (retval != MAPI_E_SUCCESS) { ret = false; goto cleanup; } SPropTagArray = set_SPropTagArray(mt->mem_ctx, 0x1, PR_SUBJECT); retval = DeleteProps(&obj_target_message, SPropTagArray); MAPIFreeBuffer(SPropTagArray); mapitest_print_retval_clean(mt, "5B. DeleteProps - PR_SUBJECT", retval); targ_name = talloc_asprintf(mt->mem_ctx, "Target: %s", "display name"); targ_dept = talloc_asprintf(mt->mem_ctx, "Target: %s", "department"); set_SPropValue_proptag(&lpProp[0], PR_DISPLAY_NAME, (const void *)targ_name); set_SPropValue_proptag(&lpProp[1], PR_DEPARTMENT_NAME, (const void *)targ_dept); retval = SetProps(&obj_target_message, 0, lpProp, 2); mapitest_print_retval_clean(mt, "SetProps", retval); if (retval != MAPI_E_SUCCESS) { ret = false; goto cleanup; } /* Step 6: Double check with GetProps */ SPropTagArray = set_SPropTagArray(mt->mem_ctx, 0x2, PR_DISPLAY_NAME, PR_DEPARTMENT_NAME); retval = GetProps(&obj_target_message, 0, SPropTagArray, &lpProps, &cValues); MAPIFreeBuffer(SPropTagArray); if (lpProps[0].value.lpszA) { if (!strncmp(targ_name, lpProps[0].value.lpszA, strlen(lpProps[0].value.lpszA))) { mapitest_print(mt, "* Step 6A - Check: Reference props set - [SUCCESS] (%s)\n", lpProps[0].value.lpszA); } else { mapitest_print(mt, "* Step 6A - Check: Reference props set [FAILURE] (%s)\n", lpProps[0].value.lpszA); ret = false; goto cleanup; } } if (lpProps[1].value.lpszA) { if (!strncmp(targ_dept, lpProps[1].value.lpszA, strlen(lpProps[1].value.lpszA))) { mapitest_print(mt, "* Step 6B - Check: Reference props set - [SUCCESS] (%s)\n", lpProps[1].value.lpszA); } else { mapitest_print(mt, "* Step 6B - Check: Reference props set [FAILURE] (%s)\n", lpProps[1].value.lpszA); ret = false; goto cleanup; } } /* Step 7: Copy properties, no overwrite */ exclude = set_SPropTagArray(mt->mem_ctx, 0x0); retval = CopyTo(&obj_ref_message, &obj_target_message, exclude, CopyFlagsNoOverwrite, &problem_count, &problems); MAPIFreeBuffer(exclude); MAPIFreeBuffer(problems); mapitest_print_retval_fmt(mt, "CopyTo", "(no overwrite)"); if (retval != MAPI_E_SUCCESS) { ret = false; goto cleanup; } /* Step 8: Double check with GetProps */ SPropTagArray = set_SPropTagArray(mt->mem_ctx, 0x2, PR_DISPLAY_NAME, PR_SUBJECT); retval = GetProps(&obj_ref_message, 0, SPropTagArray, &lpProps, &cValues); MAPIFreeBuffer(SPropTagArray); if (lpProps[0].value.lpszA) { if (!strncmp(name, lpProps[0].value.lpszA, strlen(lpProps[0].value.lpszA))) { mapitest_print(mt, "* Step 8A - Check: Reference props still good - [SUCCESS] (%s)\n", lpProps[0].value.lpszA); } else { mapitest_print(mt, "* Step 8A - Check: Reference props still good [FAILURE] (%s)\n", lpProps[0].value.lpszA); ret = false; goto cleanup; } } if (lpProps[1].value.lpszA) { if (!strncmp(subject, lpProps[1].value.lpszA, strlen(lpProps[1].value.lpszA))) { mapitest_print(mt, "* Step 8B - Check: Reference props still good - [SUCCESS] (%s)\n", lpProps[1].value.lpszA); } else { mapitest_print(mt, "* Step 8B - Check: Reference props still good [FAILURE] (%s, %s)\n", subject, lpProps[1].value.lpszA); ret = false; goto cleanup; } } SPropTagArray = set_SPropTagArray(mt->mem_ctx, 0x3, PR_DISPLAY_NAME, PR_SUBJECT, PR_DEPARTMENT_NAME); retval = GetProps(&obj_target_message, 0, SPropTagArray, &lpProps, &cValues); MAPIFreeBuffer(SPropTagArray); /* this one shouldn't be overwritten */ if (lpProps[0].value.lpszA) { if (!strncmp(targ_name, lpProps[0].value.lpszA, strlen(lpProps[0].value.lpszA))) { mapitest_print(mt, "* Step 8C - Check: Reference props copy - [SUCCESS] (%s)\n", lpProps[0].value.lpszA); } else { mapitest_print(mt, "* Step 8C - Check: Reference props copy [FAILURE] (%s)\n", lpProps[0].value.lpszA); ret = false; goto cleanup; } } /* this one should be copied */ if (lpProps[1].value.lpszA) { if (!strncmp(subject, lpProps[1].value.lpszA, strlen(lpProps[1].value.lpszA))) { mapitest_print(mt, "* Step 8D - Check: Reference props copy - [SUCCESS] (%s)\n", lpProps[1].value.lpszA); } else { mapitest_print(mt, "* Step 8D - Check: Reference props copy [FAILURE] (%s)\n", lpProps[1].value.lpszA); ret = false; goto cleanup; } } /* this one should be unchanged */ if (lpProps[2].value.lpszA) { if (!strncmp(targ_dept, lpProps[2].value.lpszA, strlen(lpProps[2].value.lpszA))) { mapitest_print(mt, "* Step 8E - Check: Reference props copy - [SUCCESS] (%s)\n", lpProps[2].value.lpszA); } else { mapitest_print(mt, "* Step 8E - Check: Reference props copy [FAILURE] (%s)\n", lpProps[2].value.lpszA); ret = false; goto cleanup; } } /* Step 9: Copy properties, with overwrite */ exclude = set_SPropTagArray(mt->mem_ctx, 0x1, PR_DEPARTMENT_NAME); retval = CopyTo(&obj_ref_message, &obj_target_message, exclude, 0x0, &problem_count, &problems); MAPIFreeBuffer(exclude); MAPIFreeBuffer(problems); mapitest_print_retval_fmt(mt, "CopyTo", "(with overwrite)"); if (retval != MAPI_E_SUCCESS) { return false; } /* Step 10: Double check with GetProps */ SPropTagArray = set_SPropTagArray(mt->mem_ctx, 0x2, PR_DISPLAY_NAME, PR_SUBJECT); retval = GetProps(&obj_ref_message, 0, SPropTagArray, &lpProps, &cValues); MAPIFreeBuffer(SPropTagArray); if (lpProps[0].value.lpszA) { if (!strncmp(name, lpProps[0].value.lpszA, strlen(lpProps[0].value.lpszA))) { mapitest_print(mt, "* Step 10A - Check: Reference props still good - [SUCCESS] (%s)\n", lpProps[0].value.lpszA); } else { mapitest_print(mt, "* Step 10A - Check: Reference props still good [FAILURE] (%s)\n", lpProps[0].value.lpszA); ret = false; goto cleanup; } } if (lpProps[1].value.lpszA) { if (!strncmp(subject, lpProps[1].value.lpszA, strlen(lpProps[1].value.lpszA))) { mapitest_print(mt, "* Step 10B - Check: Reference props still good - [SUCCESS] (%s)\n", lpProps[1].value.lpszA); } else { mapitest_print(mt, "* Step 10B - Check: Reference props still good [FAILURE] (%s)\n", lpProps[1].value.lpszA); ret = false; goto cleanup; } } SPropTagArray = set_SPropTagArray(mt->mem_ctx, 0x3, PR_DISPLAY_NAME, PR_SUBJECT, PR_DEPARTMENT_NAME); retval = GetProps(&obj_target_message, 0, SPropTagArray, &lpProps, &cValues); MAPIFreeBuffer(SPropTagArray); /* this one should now be overwritten */ if (lpProps[0].value.lpszA) { if (!strncmp(name, lpProps[0].value.lpszA, strlen(lpProps[0].value.lpszA))) { mapitest_print(mt, "* Step 10C - Check: Reference props copy - [SUCCESS] (%s)\n", lpProps[0].value.lpszA); } else { mapitest_print(mt, "* Step 10C - Check: Reference props copy [FAILURE] (%s)\n", lpProps[0].value.lpszA); ret = false; goto cleanup; } } /* this one should be copied */ if (lpProps[1].value.lpszA) { if (!strncmp(subject, lpProps[1].value.lpszA, strlen(lpProps[1].value.lpszA))) { mapitest_print(mt, "* Step 10D - Check: Reference props copy - [SUCCESS] (%s)\n", lpProps[1].value.lpszA); } else { mapitest_print(mt, "* Step 10D - Check: Reference props copy [FAILURE] (%s)\n", lpProps[1].value.lpszA); ret = false; goto cleanup; } } /* this one should be unchanged */ if (lpProps[2].value.lpszA) { if (!strncmp(targ_dept, lpProps[2].value.lpszA, strlen(lpProps[2].value.lpszA))) { mapitest_print(mt, "* Step 10E - Check: Reference props copy - [SUCCESS] (%s)\n", lpProps[2].value.lpszA); } else { mapitest_print(mt, "* Step 10E - Check: Reference props copy [FAILURE] (%s)\n", lpProps[2].value.lpszA); ret = false; goto cleanup; } } /* Step 11: Move properties, with overwrite */ exclude = set_SPropTagArray(mt->mem_ctx, 0x0); retval = CopyTo(&obj_ref_message, &obj_target_message, exclude, CopyFlagsMove, &problem_count, &problems); MAPIFreeBuffer(exclude); MAPIFreeBuffer(problems); mapitest_print_retval_clean(mt, "* Step 11 - CopyTo (move)", retval); if (retval != MAPI_E_SUCCESS) { ret = false; goto cleanup; } /* Step 12: Double check with GetProps */ SPropTagArray = set_SPropTagArray(mt->mem_ctx, 0x2, PR_DISPLAY_NAME, PR_SUBJECT); retval = GetProps(&obj_ref_message, 0, SPropTagArray, &lpProps, &cValues); MAPIFreeBuffer(SPropTagArray); if (cValues == 2) { mapitest_print(mt, "* Step 12A - Properties removed [SUCCESS]\n"); } else { mapitest_print(mt, "* Step 12A - Properties removed [FAILURE]\n"); ret = false; goto cleanup; } SPropTagArray = set_SPropTagArray(mt->mem_ctx, 0x3, PR_DISPLAY_NAME, PR_SUBJECT, PR_DEPARTMENT_NAME); retval = GetProps(&obj_target_message, 0, SPropTagArray, &lpProps, &cValues); MAPIFreeBuffer(SPropTagArray); if (lpProps[0].value.lpszA) { if (!strncmp(name, lpProps[0].value.lpszA, strlen(lpProps[0].value.lpszA))) { mapitest_print(mt, "* Step 12B - Check: Reference props move - [SUCCESS] (%s)\n", lpProps[0].value.lpszA); } else { mapitest_print(mt, "* Step 12B - Check: Reference props move [FAILURE] (%s)\n", lpProps[0].value.lpszA); ret = false; goto cleanup; } } if (lpProps[1].value.lpszA) { if (!strncmp(subject, lpProps[1].value.lpszA, strlen(lpProps[1].value.lpszA))) { mapitest_print(mt, "* Step 12C - Check: Reference props move - [SUCCESS] (%s)\n", lpProps[1].value.lpszA); } else { mapitest_print(mt, "* Step 12C - Check: Reference props move [FAILURE] (%s)\n", lpProps[1].value.lpszA); ret = false; goto cleanup; } } if (lpProps[2].value.lpszA) { if (!strncmp(dept, lpProps[2].value.lpszA, strlen(lpProps[2].value.lpszA))) { mapitest_print(mt, "* Step 12D - Check: Reference props move - [SUCCESS] (%s)\n", lpProps[2].value.lpszA); } else { mapitest_print(mt, "* Step 12D - Check: Reference props move [FAILURE] (%s)\n", lpProps[2].value.lpszA); ret = false; goto cleanup; } } /* Step 13: Create attachment on reference email, and set properties */ retval = CreateAttach(&obj_ref_message, &obj_ref_attach); mapitest_print_retval(mt, "CreateAttach"); if (retval != MAPI_E_SUCCESS) { ret = false; goto cleanup; } lpProp[0].ulPropTag = PR_ATTACH_METHOD; lpProp[0].value.l = ATTACH_BY_VALUE; lpProp[1].ulPropTag = PR_RENDERING_POSITION; lpProp[1].value.l = 0; lpProp[2].ulPropTag = PR_ATTACH_FILENAME; lpProp[2].value.lpszA = MT_MAIL_ATTACH; retval = SetProps(&obj_ref_attach, 0, lpProp, 3); mapitest_print_retval(mt, "SetProps"); if (retval != MAPI_E_SUCCESS) { ret = false; goto cleanup; } SaveChangesAttachment(&obj_ref_message, &obj_ref_attach, KeepOpenReadWrite); mapitest_print_retval(mt, "SaveChangesAttachment"); /* Step 14: Create attachment on target email */ retval = CreateAttach(&obj_target_message, &obj_targ_attach); mapitest_print_retval(mt, "CreateAttach"); if (retval != MAPI_E_SUCCESS) { ret = false; goto cleanup; } lpProp[0].ulPropTag = PR_ATTACH_METHOD; lpProp[0].value.l = ATTACH_BY_VALUE; lpProp[1].ulPropTag = PR_RENDERING_POSITION; lpProp[1].value.l = 0; lpProp[2].ulPropTag = PR_ATTACH_FILENAME; lpProp[2].value.lpszA = MT_MAIL_ATTACH2; retval = SetProps(&obj_targ_attach, 0, lpProp, 3); mapitest_print_retval(mt, "SetProps"); if (retval != MAPI_E_SUCCESS) { ret = false; goto cleanup; } retval = SaveChangesAttachment(&obj_target_message, &obj_targ_attach, KeepOpenReadWrite); mapitest_print_retval_clean(mt, "SaveChangesAttachment", retval); /* Step 15: Copy props from reference email attachment to target email attachment */ exclude = set_SPropTagArray(mt->mem_ctx, 0x0); retval = CopyTo(&obj_ref_attach, &obj_targ_attach, exclude, 0x0, &problem_count, &problems); MAPIFreeBuffer(exclude); MAPIFreeBuffer(problems); mapitest_print_retval_fmt(mt, "CopyTo", "(attachments)"); if (retval != MAPI_E_SUCCESS) { ret = false; goto cleanup; } retval = SaveChangesAttachment(&obj_target_message, &obj_targ_attach, KeepOpenReadWrite); mapitest_print_retval_clean(mt, "SaveChangesAttachment 2", retval); /* Step 16: Check properties on both attachments are correct */ SPropTagArray = set_SPropTagArray(mt->mem_ctx, 0x1, PR_ATTACH_FILENAME); retval = GetProps(&obj_ref_attach, 0, SPropTagArray, &lpProps, &cValues); mapitest_print_retval(mt, "GetProps"); if (retval != MAPI_E_SUCCESS) { ret = false; goto cleanup; } MAPIFreeBuffer(SPropTagArray); if (lpProps[0].value.lpszA) { if (!strncmp(MT_MAIL_ATTACH, lpProps[0].value.lpszA, strlen(lpProps[0].value.lpszA))) { mapitest_print(mt, "* Step 16B - Check: Reference attachment props - [SUCCESS] (%s)\n", lpProps[0].value.lpszA); } else { mapitest_print(mt, "* Step 16B - Check: Reference attachment props [FAILURE] (%s, %s)\n", lpProps[0].value.lpszA, MT_MAIL_ATTACH); ret = false; goto cleanup; } } SPropTagArray = set_SPropTagArray(mt->mem_ctx, 0x1, PR_ATTACH_FILENAME); retval = GetProps(&obj_targ_attach, 0, SPropTagArray, &lpProps, &cValues); mapitest_print_retval(mt, "GetProps"); if (retval != MAPI_E_SUCCESS) { ret = false; goto cleanup; } MAPIFreeBuffer(SPropTagArray); if (lpProps[0].value.lpszA) { if (!strncmp(MT_MAIL_ATTACH, lpProps[0].value.lpszA, strlen(lpProps[0].value.lpszA))) { mapitest_print(mt, "* Step 16D - Check: Target attachment props - [SUCCESS] (%s)\n", lpProps[0].value.lpszA); } else { mapitest_print(mt, "* Step 16D - Check: Target attachment props [FAILURE] (%s)\n", lpProps[0].value.lpszA); ret = false; goto cleanup; } } /* Create another folder */ retval = CreateFolder(&obj_top_folder, FOLDER_GENERIC, "MT Target Folder", NULL, OPEN_IF_EXISTS, &obj_targ_folder); mapitest_print_retval(mt, "CreateFolder"); if (retval != MAPI_E_SUCCESS) { ret = false; goto cleanup; } lpProp[0].ulPropTag = PR_CONTAINER_CLASS; lpProp[0].value.lpszA = "IPF.Journal"; retval = SetProps(&obj_targ_folder, 0, lpProp, 1); mapitest_print_retval(mt, "SetProps"); if (retval != MAPI_E_SUCCESS) { ret = false; goto cleanup; } /* Copy properties from the test folder to the new folder */ exclude = set_SPropTagArray(mt->mem_ctx, 0x1, PR_DISPLAY_NAME); retval = CopyTo(&obj_ref_folder, &obj_targ_folder, exclude, 0x0, &problem_count, &problems); MAPIFreeBuffer(exclude); MAPIFreeBuffer(problems); mapitest_print_retval_fmt(mt, "CopyTo", "(folder)"); if (retval != MAPI_E_SUCCESS) { ret = false; goto cleanup; } /* Check that the properties on both folders are correct */ SPropTagArray = set_SPropTagArray(mt->mem_ctx, 0x2, PR_DISPLAY_NAME, PR_CONTAINER_CLASS); retval = GetProps(&obj_ref_folder, 0, SPropTagArray, &lpProps, &cValues); mapitest_print_retval(mt, "GetProps"); if (retval != MAPI_E_SUCCESS) { ret = false; goto cleanup; } MAPIFreeBuffer(SPropTagArray); if (lpProps[0].value.lpszA) { if (!strncmp(MT_DIRNAME_TOP, lpProps[0].value.lpszA, strlen(lpProps[0].value.lpszA))) { mapitest_print(mt, "* Step 19B - Check: Reference folder props - [SUCCESS] (%s)\n", lpProps[0].value.lpszA); } else { mapitest_print(mt, "* Step 19B - Check: Reference folder props [FAILURE] (%s)\n", lpProps[0].value.lpszA); ret = false; goto cleanup; } } if (lpProps[1].value.lpszA) { if (!strncmp("IPF.Note", lpProps[1].value.lpszA, strlen(lpProps[1].value.lpszA))) { mapitest_print(mt, "* Step 19C - Check: Reference folder props - [SUCCESS] (%s)\n", lpProps[1].value.lpszA); } else { mapitest_print(mt, "* Step 19C - Check: Reference folder props [FAILURE] (%s)\n", lpProps[1].value.lpszA); ret = false; goto cleanup; } } SPropTagArray = set_SPropTagArray(mt->mem_ctx, 0x2, PR_DISPLAY_NAME, PR_CONTAINER_CLASS); retval = GetProps(&obj_targ_folder, 0, SPropTagArray, &lpProps, &cValues); mapitest_print_retval(mt, "GetProps"); if (retval != MAPI_E_SUCCESS) { ret = false; goto cleanup; } MAPIFreeBuffer(SPropTagArray); if (lpProps[0].value.lpszA) { if (!strncmp("MT Target Folder", lpProps[0].value.lpszA, strlen(lpProps[0].value.lpszA))) { mapitest_print(mt, "* Step 19E - Check: Target folder props - [SUCCESS] (%s)\n", lpProps[0].value.lpszA); } else { mapitest_print(mt, "* Step 19E - Check: Target folder props [FAILURE] (%s)\n", lpProps[0].value.lpszA); ret = false; goto cleanup; } } if (lpProps[1].value.lpszA) { if (!strncmp("IPF.Note", lpProps[1].value.lpszA, strlen(lpProps[1].value.lpszA))) { mapitest_print(mt, "* Step 19F - Check: Target folder props - [SUCCESS] (%s)\n", lpProps[1].value.lpszA); } else { mapitest_print(mt, "* Step 19F - Check: Target folder props [FAILURE] (%s)\n", lpProps[1].value.lpszA); ret = false; goto cleanup; } } cleanup: /* Cleanup reference strings */ MAPIFreeBuffer((void *)subject); MAPIFreeBuffer((void *)name); MAPIFreeBuffer((void *)targ_name); MAPIFreeBuffer((void *)targ_dept); /* Cleanup folders */ retval = DeleteFolder(&obj_top_folder, mapi_object_get_id(&obj_targ_folder), DEL_FOLDERS | DEL_MESSAGES | DELETE_HARD_DELETE, NULL); mapitest_print_retval(mt, "DeleteFolder"); retval = DeleteFolder(&obj_top_folder, mapi_object_get_id(&obj_ref_folder), DEL_FOLDERS | DEL_MESSAGES | DELETE_HARD_DELETE, NULL); mapitest_print_retval(mt, "DeleteFolder"); /* Release */ mapi_object_release(&obj_targ_attach); mapi_object_release(&obj_ref_attach); mapi_object_release(&obj_ref_message); mapi_object_release(&obj_ref_folder); mapi_object_release(&obj_top_folder); mapi_object_release(&obj_store); return ret; } #define NAMEDPROP_NAME "mapitest_namedprop" #define NAMEDPROP_IDNUM 0xDB /** \details Test the GetPropertyIdsFromNames (0x56), GetNamesFromPropertyIds (0x55) and QueryNamesFromIDs (0x5f) operations This function: -# Logs into the server -# Create a test folder and test message -# Creates one MNID_ID property -# Creates one MNID_STRING property -# Builds a table of Name, ID pairs using QueryNamesFromIDs() -# Iterates over names, and calls GetIDsFromNames() on each name -# Iterates over IDs, and calls GetNamesFromIDs() on each ID -# Cleans up \param mt pointer to the top-level mapitest structure \return true on success, otherwise false */ _PUBLIC_ bool mapitest_oxcprpt_NameId(struct mapitest *mt) { enum MAPISTATUS retval; mapi_object_t obj_store; mapi_object_t obj_top_folder; mapi_id_t id_top_folder; mapi_object_t obj_ref_folder; mapi_object_t obj_ref_message; struct mapi_nameid *nameid; struct mapi_nameid *nameid2; struct MAPINAMEID checknameid; struct SPropTagArray *SPropTagArray; uint32_t propID; uint16_t *propIDs; bool ret = true; int i; bool result; /* Log into the server */ mapi_object_init(&obj_store); mapi_object_init(&obj_top_folder); mapi_object_init(&obj_ref_folder); mapi_object_init(&obj_ref_message); retval = OpenMsgStore(mt->session, &obj_store); mapitest_print_retval(mt, "OpenMsgStore"); if (retval != MAPI_E_SUCCESS) { return false; } retval = GetDefaultFolder(&obj_store, &id_top_folder, olFolderTopInformationStore); mapitest_print_retval(mt, "GetDefaultFolder"); if (retval != MAPI_E_SUCCESS) { ret = false; goto cleanup; } retval = OpenFolder(&obj_store, id_top_folder, &obj_top_folder); mapitest_print_retval(mt, "OpenFolder"); if (retval != MAPI_E_SUCCESS) { ret = false; goto cleanup; } /* Step 2: Create test folder */ retval = CreateFolder(&obj_top_folder, FOLDER_GENERIC, MT_DIRNAME_TOP, NULL, OPEN_IF_EXISTS, &obj_ref_folder); mapitest_print_retval(mt, "CreateFolder"); if (retval != MAPI_E_SUCCESS) { ret = false; goto cleanup; } result = mapitest_common_message_create(mt, &obj_ref_folder, &obj_ref_message, MT_MAIL_SUBJECT); if (result != true) { mapitest_print_retval(mt, "mapitest_common_message_create failed"); ret = false; goto cleanup; } retval = SaveChangesMessage(&obj_ref_folder, &obj_ref_message, KeepOpenReadWrite); mapitest_print_retval(mt, "SaveChangesMessage"); if (retval != MAPI_E_SUCCESS) { ret = false; goto cleanup; } /* Step 3: Create and Retrieve one MNID_ID property */ /* Build the list of named properties we want to create */ nameid = mapi_nameid_new(mt->mem_ctx); mapi_nameid_custom_lid_add(nameid, NAMEDPROP_IDNUM, PT_STRING8, PS_PUBLIC_STRINGS); /* GetIDsFromNames and map property types */ SPropTagArray = talloc_zero(mt->mem_ctx, struct SPropTagArray); retval = GetIDsFromNames(&obj_ref_message, nameid->count, nameid->nameid, MAPI_CREATE, &SPropTagArray); mapitest_print_retval(mt, "GetIDsFromNames"); if (retval != MAPI_E_SUCCESS) { ret = false; MAPIFreeBuffer(nameid); goto cleanup; } mapi_nameid_SPropTagArray(nameid, SPropTagArray); MAPIFreeBuffer(nameid); propID = SPropTagArray->aulPropTag[0]; MAPIFreeBuffer(SPropTagArray); nameid = mapi_nameid_new(mt->mem_ctx); retval = GetNamesFromIDs(&obj_ref_message, propID, &nameid->count, &nameid->nameid); mapitest_print_retval(mt, "GetNamesFromIDs"); if (retval != MAPI_E_SUCCESS) { MAPIFreeBuffer(nameid); ret = false; goto cleanup; } if ((nameid->nameid[0].ulKind != MNID_ID) || (nameid->nameid[0].kind.lid != NAMEDPROP_IDNUM)) { errno = MAPI_E_RESERVED; mapitest_print_retval_fmt(mt, "GetNamesFromIDs", "Unexpected result: ulKind: %x mapped to 0x%.4x", nameid->nameid[0].ulKind, nameid->nameid[0].kind.lid); ret = false; goto cleanup; } MAPIFreeBuffer(nameid); /* Step 4: Create one MNID_STRING property */ nameid = mapi_nameid_new(mt->mem_ctx); SPropTagArray = talloc_zero(mt->mem_ctx, struct SPropTagArray); mapi_nameid_custom_string_add(nameid, NAMEDPROP_NAME, PT_STRING8, PS_PUBLIC_STRINGS); retval = GetIDsFromNames(&obj_ref_folder, nameid->count, nameid->nameid, MAPI_CREATE, &SPropTagArray); mapitest_print_retval(mt, "GetIDsFromNames"); if (retval != MAPI_E_SUCCESS) { MAPIFreeBuffer(nameid); ret = false; goto cleanup; } mapi_nameid_SPropTagArray(nameid, SPropTagArray); MAPIFreeBuffer(nameid); propID = SPropTagArray->aulPropTag[0]; MAPIFreeBuffer(SPropTagArray); /* Builds an array of Name,ID pairs using QueryNamesFromIDs() */ nameid = mapi_nameid_new(mt->mem_ctx); retval = QueryNamedProperties(&obj_ref_message, 0x1, NULL, &nameid->count, &propIDs, &nameid->nameid); nameid->nameid = talloc_steal((TALLOC_CTX *)nameid, nameid->nameid); mapitest_print_retval(mt, "QueryNamedProperties"); if (retval != MAPI_E_SUCCESS) { MAPIFreeBuffer(nameid); talloc_free(propIDs); ret = false; goto cleanup; } /* Iterate over names and call GetIDsFromNames() on each name */ for (i = 0; i < nameid->count; i++) { checknameid.lpguid = nameid->nameid[i].lpguid; checknameid.ulKind = nameid->nameid[i].ulKind; switch (nameid->nameid[i].ulKind) { case MNID_ID: checknameid.kind.lid = nameid->nameid[i].kind.lid; break; case MNID_STRING: checknameid.kind.lpwstr.Name = nameid->nameid[i].kind.lpwstr.Name; checknameid.kind.lpwstr.NameSize = nameid->nameid[i].kind.lpwstr.NameSize; break; } SPropTagArray = talloc_zero(mt->mem_ctx, struct SPropTagArray); retval = GetIDsFromNames(&obj_ref_folder, 1, &checknameid, 0, &SPropTagArray); if (retval != MAPI_E_SUCCESS) { mapitest_print_retval(mt, "GetIDsFromNames"); MAPIFreeBuffer(nameid); MAPIFreeBuffer(SPropTagArray); ret = false; goto cleanup; } /* check we got the right number of IDs */ if (SPropTagArray->cValues != 1) { errno = MAPI_E_RESERVED; mapitest_print_retval_fmt(mt, "GetIDsFromNames", "Unexpected ID count (%i)", SPropTagArray->cValues); MAPIFreeBuffer(nameid); MAPIFreeBuffer(SPropTagArray); ret = false; goto cleanup; } /* check if the ID is the one we expected */ if (SPropTagArray->aulPropTag[0] != (propIDs[i] << 16)) { errno = MAPI_E_RESERVED; mapitest_print_retval_fmt(mt, "GetIDsFromNames", "Unexpected ID (0x%x, expected 0x%x)", SPropTagArray->aulPropTag[0], (propIDs[i] << 16)); MAPIFreeBuffer(nameid); MAPIFreeBuffer(SPropTagArray); ret = false; goto cleanup; } MAPIFreeBuffer(SPropTagArray); } mapitest_print(mt, "* Step 6: All IDs matched [SUCCESS]\n"); /* Iterates over IDs, and call GetNamesFromIDs() on each ID */ for (i = 0; i < nameid->count; i++) { nameid2 = mapi_nameid_new(mt->mem_ctx); retval = GetNamesFromIDs(&obj_ref_folder, (propIDs[i] << 16), &nameid2->count, &nameid2->nameid); if (retval != MAPI_E_SUCCESS) { mapitest_print_retval(mt, "GetNamesFromIDs"); MAPIFreeBuffer(nameid2); ret = false; goto cleanup; } /* Check we got the right number of names */ if (nameid2->count != 1) { mapitest_print_retval_fmt(mt, "GetNamesFromIDs", "Unexpected name count (%i)", nameid2->count); MAPIFreeBuffer(nameid); MAPIFreeBuffer(nameid2); ret = false; goto cleanup; } /* Check we got the right kind of name */ if (nameid2->nameid[0].ulKind != nameid->nameid[i].ulKind) { mapitest_print_retval_fmt(mt, "GetIDsFromNames", "Unexpected kind (0x%x, expected 0x%x)", nameid2->nameid[0].ulKind, nameid->nameid[i].ulKind); MAPIFreeBuffer(nameid); MAPIFreeBuffer(nameid2); ret = false; goto cleanup; } switch (nameid->nameid[i].ulKind) { case MNID_ID: if (nameid2->nameid[0].kind.lid != nameid->nameid[i].kind.lid) { mapitest_print_retval_fmt(mt, "GetIDsFromNames", "Unexpected hex name (0x%x, expected 0x%x)", nameid2->nameid[0].kind.lid, nameid->nameid[i].kind.lid); MAPIFreeBuffer(nameid); MAPIFreeBuffer(nameid2); ret = false; goto cleanup; } break; case MNID_STRING: if (nameid2->nameid[0].kind.lpwstr.NameSize != nameid->nameid[i].kind.lpwstr.NameSize) { mapitest_print_retval_fmt(mt, "GetIDsFromNames", "Unexpected name length (0x%x, expected 0x%x)", nameid2->nameid[0].kind.lpwstr.NameSize, nameid->nameid[i].kind.lpwstr.NameSize); MAPIFreeBuffer(nameid); MAPIFreeBuffer(nameid2); ret = false; goto cleanup; } if (strncmp(nameid2->nameid[0].kind.lpwstr.Name, nameid->nameid[i].kind.lpwstr.Name, nameid->nameid[i].kind.lpwstr.NameSize) != 0) { mapitest_print_retval_fmt(mt, "GetIDsFromNames", "Unexpected name (%s, expected %s)", nameid2->nameid[0].kind.lpwstr.Name, nameid->nameid[i].kind.lpwstr.Name); MAPIFreeBuffer(nameid); MAPIFreeBuffer(nameid2); ret = false; goto cleanup; } break; } MAPIFreeBuffer(nameid2); } MAPIFreeBuffer(nameid); MAPIFreeBuffer(propIDs); cleanup: errno = 0; /* Clean up */ DeleteFolder(&obj_top_folder, mapi_object_get_id(&obj_ref_folder), DEL_FOLDERS | DEL_MESSAGES | DELETE_HARD_DELETE, NULL); mapitest_print_retval(mt, "DeleteFolder"); /* Release */ mapi_object_release(&obj_ref_message); mapi_object_release(&obj_ref_folder); mapi_object_release(&obj_top_folder); mapi_object_release(&obj_store); return ret; } /** \details Test the GetPropertyIdsFromNames (0x56) and GetNamesFromPropertyIds (0x55) operations for the special case of the PS_MAPI namespace This function: -# Logs into the server -# Gets a property ID for a known property name -# Gets a property name for a known property ID -# Cleans up Refer to MS-OXPROPS for the list of properties \param mt pointer to the top-level mapitest structure \return true on success, otherwise false */ _PUBLIC_ bool mapitest_oxcprpt_NameId_PSMAPI(struct mapitest *mt) { enum MAPISTATUS retval; mapi_object_t obj_store; struct mapi_nameid *nameid; struct SPropTagArray *SPropTagArray; bool ret = true; /* Log into the server */ mapi_object_init(&obj_store); retval = OpenMsgStore(mt->session, &obj_store); mapitest_print_retval_clean(mt, "OpenMsgStore", retval); if (retval != MAPI_E_SUCCESS) { ret = false; goto cleanup; } /* Build the list of named properties we want to get */ nameid = mapi_nameid_new(mt->mem_ctx); mapi_nameid_custom_lid_add(nameid, (PR_ACCESS>>16), PT_LONG, PS_MAPI); // 0x0FF4 mapi_nameid_custom_lid_add(nameid, (PR_ATTACHMENT_HIDDEN>>16), PT_BOOLEAN, PS_MAPI); /* GetIDsFromNames and map property types */ SPropTagArray = talloc_zero(mt->mem_ctx, struct SPropTagArray); retval = GetIDsFromNames(&obj_store, nameid->count, nameid->nameid, 0, &SPropTagArray); mapitest_print_retval_clean(mt, "GetIDsFromNames", retval); if (retval != MAPI_E_SUCCESS) { ret = false; MAPIFreeBuffer(nameid); goto cleanup; } mapi_nameid_SPropTagArray(nameid, SPropTagArray); MAPIFreeBuffer(nameid); if (SPropTagArray->aulPropTag[0] == PR_ACCESS) { mapitest_print(mt, "Comparison [0] matched\n"); } else { mapitest_print(mt, "Comparison [0] failed : 0x%08x\n", SPropTagArray->aulPropTag[0]); } if (SPropTagArray->aulPropTag[1] == PR_ATTACHMENT_HIDDEN) { mapitest_print(mt, "Comparison [1] matched\n"); } else { mapitest_print(mt, "Comparison [1] failed : 0x%08x\n", SPropTagArray->aulPropTag[1]); } MAPIFreeBuffer(SPropTagArray); nameid = mapi_nameid_new(mt->mem_ctx); retval = GetNamesFromIDs(&obj_store, PR_ATTACHMENT_HIDDEN, &nameid->count, &nameid->nameid); mapitest_print_retval_clean(mt, "GetNamesFromIDs", retval); if (retval != MAPI_E_SUCCESS) { MAPIFreeBuffer(nameid); ret = false; goto cleanup; } if (nameid->count != 1) { mapitest_print(mt, "Unexpected count from GetNamesFromIDs: %i", nameid->count); MAPIFreeBuffer(nameid); ret = false; goto cleanup; } if (nameid->nameid[0].ulKind != MNID_ID) { mapitest_print(mt, "Unexpected kind from GetNamesFromIDs: %i", nameid->nameid[0].ulKind); MAPIFreeBuffer(nameid); ret = false; goto cleanup; } if (nameid->nameid[0].kind.lid == (PR_ATTACHMENT_HIDDEN >> 16)) { mapitest_print(mt, "Comparision of values matches\n"); } else { mapitest_print(mt, "Comparison of values mismatch (nameid->lid: 0x%04x)\n", nameid->nameid[0].kind.lid); } cleanup: mapi_object_release(&obj_store); return ret; } /** \details Test the SetPropertiesNoReplicate (0x79) and DeletePropertiesNoReplicate (0x7a) operations This function: -# Opens the mailbox -# Create a test folder -# Sets some properties on the test folder -# Delete properties from the test folder -# Deletes the test folder \todo It would be useful to test the problem return values \param mt pointer to the top-level mapitest structure \return true on success, otherwise false */ _PUBLIC_ bool mapitest_oxcprpt_NoReplicate(struct mapitest *mt) { enum MAPISTATUS retval; mapi_object_t obj_store; mapi_object_t obj_top_folder; mapi_id_t id_top_folder; mapi_object_t obj_ref_folder; const char *name = NULL; const char *comment = NULL; struct SPropValue lpProp[3]; struct SPropTagArray *SPropTagArray; struct SPropValue *lpProps; uint32_t cValues; bool ret = true; /* Step 1. Logon Private Mailbox */ mapi_object_init(&obj_store); mapi_object_init(&obj_top_folder); mapi_object_init(&obj_ref_folder); retval = OpenMsgStore(mt->session, &obj_store); mapitest_print_retval_step_fmt(mt, "1.", "OpenMsgStore", "(%s)", "Logon Private Mailbox"); if (retval != MAPI_E_SUCCESS) { ret = false; goto cleanup; } retval = GetDefaultFolder(&obj_store, &id_top_folder, olFolderTopInformationStore); if (retval != MAPI_E_SUCCESS) { ret = false; goto cleanup; } retval = OpenFolder(&obj_store, id_top_folder, &obj_top_folder); if (retval != MAPI_E_SUCCESS) { ret = false; goto cleanup; } /* Step 2: Create test folder */ retval = CreateFolder(&obj_top_folder, FOLDER_GENERIC, MT_DIRNAME_TOP, NULL, OPEN_IF_EXISTS, &obj_ref_folder); mapitest_print_retval_step_fmt(mt, "2.", "CreateFolder", "(%s)", "Create the test folder"); if (retval != MAPI_E_SUCCESS) { ret = false; goto cleanup; } /* Step 3: Set properties on the test folder */ name = talloc_asprintf(mt->mem_ctx, "Reference: %s", "new name"); comment = talloc_asprintf(mt->mem_ctx, "Reference: %s", "the folder comment"); set_SPropValue_proptag(&lpProp[0], PR_DISPLAY_NAME, (const void *)name); set_SPropValue_proptag(&lpProp[1], PR_COMMENT, (const void *)comment); retval = SetPropertiesNoReplicate(&obj_ref_folder, 0, lpProp, 2); mapitest_print_retval_step_fmt(mt, "3.", "SetProps", "(%s)", "Set folder properties"); if (retval != MAPI_E_SUCCESS) { ret = false; goto cleanup; } /* Step 4: Double check with GetProps */ SPropTagArray = set_SPropTagArray(mt->mem_ctx, 0x2, PR_DISPLAY_NAME, PR_COMMENT); retval = GetProps(&obj_ref_folder, 0, SPropTagArray, &lpProps, &cValues); MAPIFreeBuffer(SPropTagArray); if (lpProps[0].value.lpszA) { if (!strncmp(name, lpProps[0].value.lpszA, strlen(lpProps[0].value.lpszA))) { mapitest_print(mt, "* Step 4.1. - Check: Reference props set - [SUCCESS] (%s)\n", lpProps[0].value.lpszA); } else { mapitest_print(mt, "* Step 4.1. - Check: Reference props set [FAILURE] (%s)\n", lpProps[0].value.lpszA); ret = false; goto cleanup; } } if (lpProps[1].value.lpszA) { if (!strncmp(comment, lpProps[1].value.lpszA, strlen(lpProps[1].value.lpszA))) { mapitest_print(mt, "* Step 4.2. - Check: Reference props set - [SUCCESS] (%s)\n", lpProps[1].value.lpszA); } else { mapitest_print(mt, "* Step 4.2. - Check: Reference props set [FAILURE] (%s)\n", lpProps[1].value.lpszA); ret = false; goto cleanup; } } /* Step 5. Delete Properties */ SPropTagArray = set_SPropTagArray(mt->mem_ctx, 0x1, PR_COMMENT); retval = DeletePropertiesNoReplicate(&obj_ref_folder, SPropTagArray); MAPIFreeBuffer(SPropTagArray); mapitest_print_retval_step_fmt(mt, "5.", "DeletePropertiesNoReplicate", "PR_COMMENT"); /* Step 6. Double check with GetProps */ SPropTagArray = set_SPropTagArray(mt->mem_ctx, 0x1, PR_COMMENT); retval = GetProps(&obj_ref_folder, 0, SPropTagArray, &lpProps, &cValues); MAPIFreeBuffer(SPropTagArray); if (get_SPropValue(lpProps, PR_COMMENT) == NULL) { mapitest_print(mt, "* Step 6.1. - GetProps verifier [SUCCESS]\n"); } else { mapitest_print(mt, "* Step 6.1. - GetProps verifier [FAILURE]:\n"); } /* Cleanup and release */ cleanup: retval = DeleteFolder(&obj_top_folder, mapi_object_get_id(&obj_ref_folder), DEL_FOLDERS | DEL_MESSAGES | DELETE_HARD_DELETE, NULL); mapitest_print_retval_step(mt, "7.", "DeleteFolder", retval); mapi_object_release(&obj_ref_folder); mapi_object_release(&obj_top_folder); mapi_object_release(&obj_store); return ret; } /** \details Test WriteAndCommitStream (0x90) operation. This function: -# Logs in -# Opens the Outbox folder -# Creates a test message -# Creates an attachment on the test messages and set properties on the attachment -# Opens a stream on the attachment -# Sets the stream size -# Write and commits into the stream -# Saves the message -# Gets stream size and compare values -# Opens the stream again with different permissions -# Reads the stream and compares buffers -# Deletes the test message \param mt pointer to the top-level mapitest structure \return true on success, otherwise -1 */ _PUBLIC_ bool mapitest_oxcprpt_WriteAndCommitStream(struct mapitest *mt) { enum MAPISTATUS retval; bool ret = true; mapi_object_t obj_store; mapi_object_t obj_folder; mapi_object_t obj_message; mapi_object_t obj_attach; mapi_object_t obj_stream; mapi_id_t id_folder; DATA_BLOB data; struct SPropValue attach[3]; char *stream = NULL; char *out_stream = NULL; const uint32_t stream_len = 0x1000; unsigned char buf[0x1000]; uint32_t StreamSize = 0; uint16_t read_size = 0; uint16_t write_len = 0; uint32_t offset = 0; stream = mapitest_common_genblob(mt->mem_ctx, stream_len); if (stream == NULL) { return false; } /* Step 1. Logon */ mapi_object_init(&obj_store); retval = OpenMsgStore(mt->session, &obj_store); mapitest_print_retval(mt, "OpenMsgStore"); if (retval != MAPI_E_SUCCESS) { return false; } /* Step 2. Open Inbox folder */ retval = GetDefaultFolder(&obj_store, &id_folder, olFolderInbox); mapitest_print_retval(mt, "GetDefaultFolder"); if (retval != MAPI_E_SUCCESS) { return false; } mapi_object_init(&obj_folder); retval = OpenFolder(&obj_store, id_folder, &obj_folder); mapitest_print_retval(mt, "OpenFolder"); if (retval != MAPI_E_SUCCESS) { return false; } /* Step 3. Create the message */ mapi_object_init(&obj_message); ret = mapitest_common_message_create(mt, &obj_folder, &obj_message, MT_MAIL_SUBJECT); mapitest_print_retval(mt, "Message Creation"); if (ret != true) { return false; } /* Step 4. Create the attachment */ mapi_object_init(&obj_attach); retval = CreateAttach(&obj_message, &obj_attach); mapitest_print_retval(mt, "CreateAttach"); if (retval != MAPI_E_SUCCESS) { ret = false; } attach[0].ulPropTag = PR_ATTACH_METHOD; attach[0].value.l = ATTACH_BY_VALUE; attach[1].ulPropTag = PR_RENDERING_POSITION; attach[1].value.l = 0; attach[2].ulPropTag = PR_ATTACH_FILENAME; attach[2].value.lpszA = MT_MAIL_ATTACH; retval = SetProps(&obj_attach, 0, attach, 3); if (retval != MAPI_E_SUCCESS) { ret = false; } /* Step 5. Open the stream */ mapi_object_init(&obj_stream); retval = OpenStream(&obj_attach, PR_ATTACH_DATA_BIN, 2, &obj_stream); mapitest_print_retval(mt, "OpenStream"); if (retval != MAPI_E_SUCCESS) { ret = false; } /* Step 6. Set the stream size */ retval = SetStreamSize(&obj_stream, (uint64_t) stream_len); mapitest_print_retval(mt, "SetStreamSize"); if (retval != MAPI_E_SUCCESS) { ret = false; } /* Step 7. Write the stream */ write_len = 0; data.length = stream_len; data.data = (uint8_t *) stream; retval = WriteAndCommitStream(&obj_stream, &data, &write_len); mapitest_print_retval_fmt_clean(mt, "WriteAndCommitStream", retval, "(0x%x bytes written)", write_len); if (retval != MAPI_E_SUCCESS) { ret = false; } /* Step 8. Save the attachment */ retval = SaveChangesAttachment(&obj_message, &obj_attach, KeepOpenReadOnly); mapitest_print_retval_clean(mt, "SaveChangesAttachment", retval); if (retval != MAPI_E_SUCCESS) { ret = false; } retval = SaveChangesMessage(&obj_folder, &obj_message, KeepOpenReadOnly); mapitest_print_retval_clean(mt, "SaveChangesMessage", retval); if (retval != MAPI_E_SUCCESS) { ret = false; } /* Step 9. Get stream size */ retval = GetStreamSize(&obj_stream, &StreamSize); mapitest_print_retval_clean(mt, "GetStreamSize", retval); if (retval != MAPI_E_SUCCESS) { ret = false; } mapitest_print(mt, "* %-35s: %s\n", "StreamSize comparison", (StreamSize == stream_len) ? "[PASSED]" : "[FAILURE]"); /* Step 10. Read the stream */ mapi_object_release(&obj_stream); mapi_object_init(&obj_stream); retval = OpenStream(&obj_attach, PR_ATTACH_DATA_BIN, 0, &obj_stream); mapitest_print_retval_clean(mt, "OpenStream", retval); if (retval != MAPI_E_SUCCESS) { ret = false; } offset = 0; out_stream = talloc_size(mt->mem_ctx, StreamSize + 1); do { retval = ReadStream(&obj_stream, buf, MT_STREAM_MAX_SIZE, &read_size); mapitest_print_retval_fmt_clean(mt, "ReadStream", retval, "(0x%x bytes read)", read_size); memcpy(out_stream + offset, buf, read_size); offset += read_size; if (retval != MAPI_E_SUCCESS) { ret = false; break; } } while (read_size && (offset != StreamSize)); out_stream[offset] = '\0'; if (offset) { if (!strcmp(stream, out_stream)) { mapitest_print(mt, "* %-35s: [IN,OUT] stream [PASSED]\n", "Comparison"); } else { mapitest_print(mt, "* %-35s: [IN,OUT] stream [FAILURE]\n", "Comparison"); } } /* Release */ mapi_object_release(&obj_stream); mapi_object_release(&obj_attach); mapi_object_release(&obj_message); mapi_object_release(&obj_folder); mapi_object_release(&obj_store); talloc_free(stream); talloc_free(out_stream); return ret; } openchange-2.0/utils/mapitest/modules/module_oxcstor.c000066400000000000000000000615731223057412600233500ustar00rootroot00000000000000/* Stand-alone MAPI testsuite OpenChange Project - STORE OBJECT PROTOCOL operations Copyright (C) Julien Kerihuel 2008 This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see . */ #include "utils/mapitest/mapitest.h" #include "utils/mapitest/proto.h" #include "libmapi/libmapi_private.h" /** \file module_oxcstor.c \brief Store Object Protocol test suite */ /** \details Test the Logon (0xFE) operation This function: -# Log on the user private mailbox -# Log on the public folder store \param mt pointer on the top-level mapitest structure \return true on success, otherwise false */ _PUBLIC_ bool mapitest_oxcstor_Logon(struct mapitest *mt) { mapi_object_t obj_store; /* Step 1. Logon Private Mailbox */ mapi_object_init(&obj_store); OpenMsgStore(mt->session, &obj_store); mapitest_print_retval(mt, "OpenMsgStore"); if (GetLastError() != MAPI_E_SUCCESS) { return false; } mapi_object_release(&obj_store); /* Step 2. Logon Public Folder store */ mapi_object_init(&obj_store); OpenPublicFolder(mt->session, &obj_store); mapitest_print_retval(mt, "OpenPublicFolder"); if (GetLastError() != MAPI_E_SUCCESS) { return false; } mapi_object_release(&obj_store); return true; } /** \details Test the GetReceiveFolder (0x27) operation This function: -# Log on the user private mailbox -# Call the GetReceiveFolder operation -# Call the GetReceiveFolder with different explicit message class values \param mt the top-level mapitest structure \return true on success, otherwise false */ _PUBLIC_ bool mapitest_oxcstor_GetReceiveFolder(struct mapitest *mt) { enum MAPISTATUS retval; mapi_object_t obj_store; mapi_id_t receivefolder = 0; bool ret = true; /* Step 1. Logon */ mapi_object_init(&obj_store); retval = OpenMsgStore(mt->session, &obj_store); mapitest_print_retval_clean(mt, "OpenMsgStore", retval); if (retval != MAPI_E_SUCCESS) { ret = false; goto release; } /* Step 2. Call the GetReceiveFolder operation */ retval = GetReceiveFolder(&obj_store, &receivefolder, NULL); mapitest_print_retval_clean(mt, "GetReceiveFolder for All target", retval); mapitest_print(mt, "FID: 0x%016"PRIx64"\n", receivefolder); if (retval != MAPI_E_SUCCESS) { ret = false; goto release; } /* Step 3. Call GetReceiveFolder again, with an explicit message class */ retval = GetReceiveFolder(&obj_store, &receivefolder, "IPC"); mapitest_print_retval_clean(mt, "GetReceiveFolder for IPC", retval); mapitest_print(mt, "FID: 0x%016"PRIx64"\n", receivefolder); if (retval != MAPI_E_SUCCESS) { ret = false; goto release; } /* Step 4. Call GetReceiveFolder again, with an explicit message class */ retval = GetReceiveFolder(&obj_store, &receivefolder, "IPM.FooBarBaz"); mapitest_print_retval_clean(mt, "GetReceiveFolder for IPM.FooBarBaz", retval); mapitest_print(mt, "FID: 0x%016"PRIx64"\n", receivefolder); if (retval != MAPI_E_SUCCESS) { ret = false; goto release; } /* Step 5. Call GetReceiveFolder again, with an explicit message class */ retval = GetReceiveFolder(&obj_store, &receivefolder, "MT.Mapitest.tc"); mapitest_print_retval_clean(mt, "GetReceiveFolder for MT.Mapitest.tc", retval); mapitest_print(mt, "FID: 0x%016"PRIx64"\n", receivefolder); if (retval != MAPI_E_SUCCESS) { ret = false; goto release; } release: mapi_object_release(&obj_store); return ret; } /** \details Test the SetReceiveFolder (0x26) operation This function: -# Log on the user private mailbox -# Call the SetReceiveFolder operations -# Clean up \param mt the top-level mapitest structure \return true on success, otherwise false */ _PUBLIC_ bool mapitest_oxcstor_SetReceiveFolder(struct mapitest *mt) { enum MAPISTATUS retval; mapi_object_t obj_store; mapi_id_t id_inbox; mapi_id_t id_tis; mapi_object_t obj_tis; mapi_object_t obj_inbox; mapi_object_t obj_folder; bool ret = true; mapi_object_init(&obj_store); mapi_object_init(&obj_inbox); mapi_object_init(&obj_tis); mapi_object_init(&obj_folder); /* Step 1. Logon */ retval = OpenMsgStore(mt->session, &obj_store); mapitest_print_retval_step(mt, "1.", "Logon", retval); if (retval != MAPI_E_SUCCESS) { ret = false; goto cleanup; } /* Step 2. Get the original ReceiveFolder */ retval = GetReceiveFolder(&obj_store, &id_inbox, NULL); mapitest_print_retval_step(mt, "2.", "GetReceiveFolder", retval); if (retval != MAPI_E_SUCCESS) { ret = false; goto cleanup; } /* Step 3. Open the ReceiveFolder */ retval = OpenFolder(&obj_store, id_inbox, &obj_inbox); mapitest_print_retval_step(mt, "3.", "OpenFolder", retval); if (retval != MAPI_E_SUCCESS) { ret = false; goto cleanup; } /* Step 4. Open the Top Information Store folder */ retval = GetDefaultFolder(&obj_store, &id_tis, olFolderTopInformationStore); mapitest_print_retval_step(mt, "4.", "GetDefaultFolder", retval); if (retval != MAPI_E_SUCCESS) { ret = false; goto cleanup; } retval = OpenFolder(&obj_store, id_tis, &obj_tis); mapitest_print_retval_step(mt, "4.1.", "OpenFolder", retval); if (retval != MAPI_E_SUCCESS) { ret = false; goto cleanup; } /* Create the New Inbox folder under Top Information Store */ retval = CreateFolder(&obj_tis, FOLDER_GENERIC, "New Inbox", NULL, OPEN_IF_EXISTS, &obj_folder); mapitest_print_retval_step(mt, "5.", "CreateFolder", retval); if (retval != MAPI_E_SUCCESS) { ret = false; goto cleanup; } /* Set IPM.Note receive folder to New Inbox */ retval = SetReceiveFolder(&obj_store, &obj_folder, "IPM.Note"); mapitest_print_retval_step_fmt(mt, "6.", "SetReceiveFolder", "%s", "(New Inbox)", retval); if (retval != MAPI_E_SUCCESS) { ret = false; goto cleanup; } /* Reset receive folder to Inbox */ retval = SetReceiveFolder(&obj_store, &obj_inbox, "IPM.Note"); mapitest_print_retval_step_fmt(mt, "6.1.", "SetReceiveFolder", "%s", "(original folder)", retval); if (retval != MAPI_E_SUCCESS) { ret = false; goto cleanup; } /* Set a test message class */ retval = SetReceiveFolder(&obj_store, &obj_folder, "MT.Mapitest.ta"); mapitest_print_retval_step_fmt(mt, "7.", "SetReceiveFolder", "%s", "(MT.Mapitest.ta)", retval); if (retval != MAPI_E_SUCCESS) { ret = false; goto cleanup; } /* Delete New Inbox folder */ retval = EmptyFolder(&obj_folder); mapitest_print_retval_step(mt, "8.", "EmptyFolder", retval); if (retval != MAPI_E_SUCCESS) { ret = false; goto cleanup; } retval = DeleteFolder(&obj_tis, mapi_object_get_id(&obj_folder), DEL_FOLDERS | DEL_MESSAGES | DELETE_HARD_DELETE, NULL); mapitest_print_retval_step(mt, "9.", "DeleteFolder", retval); if (retval != MAPI_E_SUCCESS) { ret = false; goto cleanup; } cleanup: /* Release */ mapi_object_release(&obj_folder); mapi_object_release(&obj_tis); mapi_object_release(&obj_inbox); mapi_object_release(&obj_store); return ret; } /** \details Test the GetOwningServers (0x42) operation This function: -# Log on the public folders store -# Open a public folder -# Call the GetOwningServers operation \param mt the top-level mapitest structure \return true on success, otherwise false */ _PUBLIC_ bool mapitest_oxcstor_GetOwningServers(struct mapitest *mt) { bool ret = true; mapi_object_t obj_store; mapi_object_t obj_folder; uint64_t folderId; uint16_t OwningServersCount; uint16_t CheapServersCount; char *OwningServers; /* Step 1. Logon */ mapi_object_init(&obj_store); OpenPublicFolder(mt->session, &obj_store); mapitest_print_retval(mt, "OpenPublicFolder"); if (GetLastError() != MAPI_E_SUCCESS) { return false; } /* Step 2. Open IPM Subtree folder */ GetDefaultPublicFolder(&obj_store, &folderId, olFolderPublicIPMSubtree); mapitest_print_retval(mt, "GetDefaultPublicFolder"); if (GetLastError() != MAPI_E_SUCCESS) { ret = false; goto cleanup; } mapi_object_init(&obj_folder); OpenFolder(&obj_store, folderId, &obj_folder); mapitest_print_retval(mt, "OpenFolder"); if (GetLastError() != MAPI_E_SUCCESS) { ret = false; goto cleanup; } /* Step 3. Call GetOwningServers */ GetOwningServers(&obj_store, &obj_folder, &OwningServersCount, &CheapServersCount, &OwningServers); mapitest_print_retval(mt, "GetOwningServers"); if (GetLastError() != MAPI_E_SUCCESS && GetLastError() != ecNoReplicaAvailable) { ret = false; } else if (GetLastError() == ecNoReplicaAvailable) { mapitest_print(mt, "* %-35s: No active replica for the folder\n", "GetOwningServers"); } else { mapitest_print(mt, "* %-35s: OwningServersCount: %d\n", "PublicFolderIsGhosted", OwningServersCount); if (OwningServersCount) { uint16_t i; for (i = 0; i < OwningServersCount; i++) { mapitest_print(mt, "* %-35s: OwningServers: %s\n", "GetOwningServers", &OwningServers[i]); } talloc_free(&OwningServers); } } /* cleanup objects */ mapi_object_release(&obj_folder); cleanup: mapi_object_release(&obj_store); return ret; } /** \details Test the PublicFolderIsGhosted (0x45) operation This function: -# Log on the public folders store -# Open a public folder -# Call the PublicFolderIsGhosted operation \param mt the top-level mapitest structure \return true on success, otherwise false */ _PUBLIC_ bool mapitest_oxcstor_PublicFolderIsGhosted(struct mapitest *mt) { bool ret = true; mapi_object_t obj_store; mapi_object_t obj_folder; uint64_t folderId; bool IsGhosted; /* Step 1. Logon */ mapi_object_init(&obj_store); mapi_object_init(&obj_folder); OpenPublicFolder(mt->session, &obj_store); mapitest_print_retval(mt, "OpenPublicFolder"); if (GetLastError() != MAPI_E_SUCCESS) { return false; } /* Step 2. Open IPM Subtree folder */ GetDefaultPublicFolder(&obj_store, &folderId, olFolderPublicIPMSubtree); mapitest_print_retval(mt, "GetDefaultPublicFolder"); if (GetLastError() != MAPI_E_SUCCESS) { ret = false; goto cleanup; } OpenFolder(&obj_store, folderId, &obj_folder); mapitest_print_retval(mt, "OpenFolder"); if (GetLastError() != MAPI_E_SUCCESS) { ret = false; goto cleanup; } /* Step 3. Call PublicFolderIsGhosted */ PublicFolderIsGhosted(&obj_store, &obj_folder, &IsGhosted); mapitest_print_retval(mt, "PublicFolderIsGhosted"); if (GetLastError() != MAPI_E_SUCCESS) { ret = false; goto cleanup; } mapitest_print(mt, "* %-35s: IsGhosted is set to %s\n", "PublicFolderIsGhosted", ((IsGhosted) ? "true" : "false")); cleanup: mapi_object_release(&obj_folder); mapi_object_release(&obj_store); return ret; } /** \details Test the GetReceiveFolderTable (0x68) operation This function: -# Log on the user private mailbox -# Call the GetReceiveFolderTable operation \param mt the top-level mapitest structure \return true on success, otherwise false */ _PUBLIC_ bool mapitest_oxcstor_GetReceiveFolderTable(struct mapitest *mt) { mapi_object_t obj_store; struct SRowSet SRowSet; /* Step 1. Logon */ mapi_object_init(&obj_store); OpenMsgStore(mt->session, &obj_store); mapitest_print_retval(mt, "OpenMsgStore"); if (GetLastError() != MAPI_E_SUCCESS) { return false; } /* Step 2. Call the GetReceiveFolderTable operation */ GetReceiveFolderTable(&obj_store, &SRowSet); mapitest_print_retval(mt, "GetReceiveFolderTable"); if (GetLastError() != MAPI_E_SUCCESS) { return false; } mapitest_print_SRowSet(mt, &SRowSet, "\t\t[*]"); MAPIFreeBuffer(SRowSet.aRow); /* Release */ mapi_object_release(&obj_store); return true; } /** \details Test the LongTermIdFromId (0x43) and IdFromLongTermId (0x44) operations This function: -# Logs into the user private mailbox -# Open the Receive Folder -# Looks up the long term id for the receive folder FID -# Looks up the short term id for the long term id -# Checks the id matches the original FID \param mt pointer on the top-level mapitest structure \return true on success, otherwise false */ _PUBLIC_ bool mapitest_oxcstor_LongTermId(struct mapitest *mt) { mapi_object_t obj_store; mapi_id_t id_inbox; struct LongTermId long_term_id; mapi_id_t id_check; bool ret = true; /* Step 1. Logon Private Mailbox */ mapi_object_init(&obj_store); OpenMsgStore(mt->session, &obj_store); mapitest_print_retval(mt, "OpenMsgStore"); if (GetLastError() != MAPI_E_SUCCESS) { ret = false; goto cleanup; } /* Step 2. Call the GetReceiveFolder operation */ GetReceiveFolder(&obj_store, &id_inbox, "IPF.Post"); mapitest_print_retval(mt, "GetReceiveFolder"); if (GetLastError() != MAPI_E_SUCCESS) { ret = false; goto cleanup; } /* Step 3. Call GetLongTermIdFromId on Folder ID */ GetLongTermIdFromId(&obj_store, id_inbox, &long_term_id); mapitest_print_retval(mt, "GetLongTermIdFromId"); if (GetLastError() != MAPI_E_SUCCESS) { ret = false; goto cleanup; } /* Step 4. Call GetIdFromLongTermId on LongTermId from previous step*/ GetIdFromLongTermId(&obj_store, long_term_id, &id_check); mapitest_print_retval(mt, "GetIdFromLongTermId"); if (GetLastError() != MAPI_E_SUCCESS) { ret = false; goto cleanup; } /* Step 5. Check whether ids are the same */ if ( id_check == id_inbox ) { mapitest_print(mt, "* Check: IDs match - [SUCCESS]\n" ); } else { mapitest_print(mt, "* Check: IDs do not match - [SUCCESS] (0x%x, expected 0x%x)\n", id_check, id_inbox); ret=false; goto cleanup; } cleanup: /* Release */ mapi_object_release(&obj_store); return ret; } /** \details Test the GetStoreState (0x7b) operation This function: -# Logs into the user private mailbox -# Retrieve the store state \param mt pointer on the top-level mapitest structure \return true on success, otherwise false */ _PUBLIC_ bool mapitest_oxcstor_GetStoreState(struct mapitest *mt) { mapi_object_t obj_store; uint32_t StoreState = 0; bool ret = true; /* Step 1. Logon Private Mailbox */ mapi_object_init(&obj_store); OpenMsgStore(mt->session, &obj_store); mapitest_print_retval(mt, "OpenMsgStore"); if (GetLastError() != MAPI_E_SUCCESS) { return false; } /* Step 2. Get the store state */ GetStoreState(&obj_store, &StoreState); mapitest_print_retval(mt, "GetStoreState"); if (GetLastError() != MAPI_E_SUCCESS) { ret = false; } mapi_object_release(&obj_store); return ret; } /** \details Test the IsMailboxFolder convenience function This function: -# Logs into the user private mailbox \param mt pointer on the top-level mapitest structure \return true on success, otherwise false */ _PUBLIC_ bool mapitest_oxcstor_IsMailboxFolder(struct mapitest *mt) { mapi_object_t obj_store; mapi_object_t obj_pf_store; bool ret = true; mapi_object_store_t * store; mapi_object_store_t * pf_store; uint32_t olFolderNumber; bool callResult; enum MAPISTATUS retval; mapi_object_init(&obj_store); mapi_object_init(&obj_pf_store); /* Step 1. Logon Private Mailbox */ retval = OpenMsgStore(mt->session, &obj_store); mapitest_print_retval(mt, "OpenMsgStore"); if (retval != MAPI_E_SUCCESS) { ret = false; goto cleanup; } store = (mapi_object_store_t *) obj_store.private_data; if (! store) { mapitest_print(mt, "* FAILED to get store private_data\n" ); ret = false; goto cleanup; } callResult = IsMailboxFolder(&obj_store, store->fid_top_information_store, &olFolderNumber); if (! callResult) { mapitest_print(mt, "* FAILED to get folder number for top_information_store\n"); ret = false; goto cleanup; } if (olFolderNumber != olFolderTopInformationStore) { mapitest_print(mt, "* FAILED - wrong folder number for top_information_store\n"); ret = false; goto cleanup; } callResult = IsMailboxFolder(&obj_store, store->fid_deleted_items, &olFolderNumber); if (! callResult) { mapitest_print(mt, "* FAILED to get folder number for deleted_items\n"); ret = false; goto cleanup; } if (olFolderNumber != olFolderDeletedItems) { mapitest_print(mt, "* FAILED - wrong folder number for deleted_items\n"); ret = false; goto cleanup; } callResult = IsMailboxFolder(&obj_store, store->fid_outbox, &olFolderNumber); if (! callResult) { mapitest_print(mt, "* FAILED to get folder number for outbox\n"); ret = false; goto cleanup; } if (olFolderNumber != olFolderOutbox) { mapitest_print(mt, "* FAILED - wrong folder number for outbox\n"); ret = false; goto cleanup; } callResult = IsMailboxFolder(&obj_store, store->fid_sent_items, &olFolderNumber); if (! callResult) { mapitest_print(mt, "* FAILED to get folder number for sent items\n"); ret = false; goto cleanup; } if (olFolderNumber != olFolderSentMail) { mapitest_print(mt, "* FAILED - wrong folder number for sent items\n"); ret = false; goto cleanup; } callResult = IsMailboxFolder(&obj_store, store->fid_inbox, &olFolderNumber); if (! callResult) { mapitest_print(mt, "* FAILED to get folder number for inbox\n"); ret = false; goto cleanup; } if (olFolderNumber != olFolderInbox) { mapitest_print(mt, "* FAILED - wrong folder number for inbox\n"); ret = false; goto cleanup; } callResult = IsMailboxFolder(&obj_store, store->fid_common_views, &olFolderNumber); if (! callResult) { mapitest_print(mt, "* FAILED to get folder number for views\n"); ret = false; goto cleanup; } if (olFolderNumber != olFolderCommonView) { mapitest_print(mt, "* FAILED - wrong folder number for views\n"); ret = false; goto cleanup; } callResult = IsMailboxFolder(&obj_store, store->fid_calendar, &olFolderNumber); if (! callResult) { mapitest_print(mt, "* FAILED to get folder number for calendar\n"); ret = false; goto cleanup; } if (olFolderNumber != olFolderCalendar) { mapitest_print(mt, "* FAILED - wrong folder number for calendar\n"); ret = false; goto cleanup; } callResult = IsMailboxFolder(&obj_store, store->fid_contact, &olFolderNumber); if (! callResult) { mapitest_print(mt, "* FAILED to get folder number for contacts\n"); ret = false; goto cleanup; } if (olFolderNumber != olFolderContacts) { mapitest_print(mt, "* FAILED - wrong folder number for contacts\n"); ret = false; goto cleanup; } callResult = IsMailboxFolder(&obj_store, store->fid_journal, &olFolderNumber); if (! callResult) { mapitest_print(mt, "* FAILED to get folder number for journal\n"); ret = false; goto cleanup; } if (olFolderNumber != olFolderJournal) { mapitest_print(mt, "* FAILED - wrong folder number for journal\n"); ret = false; goto cleanup; } callResult = IsMailboxFolder(&obj_store, store->fid_note, &olFolderNumber); if (! callResult) { mapitest_print(mt, "* FAILED to get folder number for notes\n"); ret = false; goto cleanup; } if (olFolderNumber != olFolderNotes) { mapitest_print(mt, "* FAILED - wrong folder number for note\n"); ret = false; goto cleanup; } callResult = IsMailboxFolder(&obj_store, store->fid_task, &olFolderNumber); if (! callResult) { mapitest_print(mt, "* FAILED to get folder number for tasks\n"); ret = false; goto cleanup; } if (olFolderNumber != olFolderTasks) { mapitest_print(mt, "* FAILED - wrong folder number for tasks\n"); ret = false; goto cleanup; } callResult = IsMailboxFolder(&obj_store, store->fid_drafts, &olFolderNumber); if (! callResult) { mapitest_print(mt, "* FAILED to get folder number for drafts\n"); ret = false; goto cleanup; } if (olFolderNumber != olFolderDrafts) { mapitest_print(mt, "* FAILED - wrong folder number for drafts\n"); ret = false; goto cleanup; } callResult = IsMailboxFolder(&obj_store, store->fid_search, &olFolderNumber); if (! callResult) { mapitest_print(mt, "* FAILED to get folder number for search\n"); ret = false; goto cleanup; } if (olFolderNumber != olFolderFinder) { mapitest_print(mt, "* FAILED - wrong folder number for search\n"); ret = false; goto cleanup; } retval = OpenPublicFolder(mt->session, &obj_pf_store); mapitest_print_retval(mt, "OpenPublicFolder"); if (retval != MAPI_E_SUCCESS) { ret = false; goto cleanup; } pf_store = (mapi_object_store_t *) obj_pf_store.private_data; callResult = IsMailboxFolder(&obj_pf_store, pf_store->fid_pf_OfflineAB, &olFolderNumber); if (! callResult) { mapitest_print(mt, "* FAILED to get folder number for offline address book\n"); ret = false; goto cleanup; } if (olFolderNumber != olFolderPublicOfflineAB) { mapitest_print(mt, "* FAILED - wrong folder number for offline address book\n"); ret = false; goto cleanup; } callResult = IsMailboxFolder(&obj_pf_store, pf_store->fid_pf_FreeBusyRoot, &olFolderNumber); if (! callResult) { mapitest_print(mt, "* FAILED to get folder number for free-busy root\n"); ret = false; goto cleanup; } if (olFolderNumber != olFolderPublicFreeBusyRoot) { mapitest_print(mt, "* FAILED - wrong folder number for free-busy root\n"); ret = false; goto cleanup; } callResult = IsMailboxFolder(&obj_pf_store, pf_store->fid_pf_EFormsRegistryRoot, &olFolderNumber); if (! callResult) { mapitest_print(mt, "* FAILED to get folder number for EForms root\n"); ret = false; goto cleanup; } if (olFolderNumber != olFolderPublicEFormsRoot) { mapitest_print(mt, "* FAILED - wrong folder number for EForms root\n"); ret = false; goto cleanup; } /* this one is a bit sensitive. sometimes the EFormsRegistry is null */ callResult = IsMailboxFolder(&obj_pf_store, pf_store->fid_pf_EFormsRegistry, &olFolderNumber); if (pf_store->fid_pf_EFormsRegistry != 0) { if (! callResult) { mapitest_print(mt, "* FAILED to get folder number for EForms registry\n"); ret = false; goto cleanup; } if (olFolderNumber != olFolderPublicEFormsRegistry) { mapitest_print(mt, "* FAILED - wrong folder number for EForms registry\n"); ret = false; goto cleanup; } } callResult = IsMailboxFolder(&obj_pf_store, pf_store->fid_pf_public_root, &olFolderNumber); if (! callResult) { mapitest_print(mt, "* FAILED to get folder number for Public root\n"); ret = false; goto cleanup; } if (olFolderNumber != olFolderPublicRoot) { mapitest_print(mt, "* FAILED - wrong folder number for Public root\n"); ret = false; goto cleanup; } callResult = IsMailboxFolder(&obj_pf_store, pf_store->fid_pf_ipm_subtree, &olFolderNumber); if (! callResult) { mapitest_print(mt, "* FAILED to get folder number for IPM subtree\n"); ret = false; goto cleanup; } if (olFolderNumber != olFolderPublicIPMSubtree) { mapitest_print(mt, "* FAILED - wrong folder number for IPM subtree\n"); ret = false; goto cleanup; } callResult = IsMailboxFolder(&obj_pf_store, pf_store->fid_pf_non_ipm_subtree, &olFolderNumber); if (! callResult) { mapitest_print(mt, "* FAILED to get folder number for non-IPM subtree\n"); ret = false; goto cleanup; } if (olFolderNumber != olFolderPublicNonIPMSubtree) { mapitest_print(mt, "* FAILED - wrong folder number for non-IPM subtree\n"); ret = false; goto cleanup; } callResult = IsMailboxFolder(&obj_pf_store, pf_store->fid_pf_LocalSiteFreeBusy, &olFolderNumber); if (! callResult) { mapitest_print(mt, "* FAILED to get folder number for local free busy folder\n"); ret = false; goto cleanup; } if (olFolderNumber != olFolderPublicLocalFreeBusy) { mapitest_print(mt, "* FAILED - wrong folder number for local free busy folder\n"); ret = false; goto cleanup; } callResult = IsMailboxFolder(&obj_pf_store, pf_store->fid_pf_LocalSiteOfflineAB, &olFolderNumber); if (! callResult) { mapitest_print(mt, "* FAILED to get folder number for local offline address book\n"); ret = false; goto cleanup; } if (olFolderNumber != olFolderPublicLocalOfflineAB) { mapitest_print(mt, "* FAILED - wrong folder number for local offline address folder\n"); ret = false; goto cleanup; } /* this one is a bit sensitive. sometimes the NNTP Articles Folder ID is null */ callResult = IsMailboxFolder(&obj_pf_store, pf_store->fid_pf_NNTPArticle, &olFolderNumber); if (pf_store->fid_pf_NNTPArticle != 0) { if (! callResult) { mapitest_print(mt, "* FAILED to get folder number for NNTP Articles\n"); ret = false; goto cleanup; } if (olFolderNumber != olFolderPublicNNTPArticle) { mapitest_print(mt, "* FAILED - wrong folder number for NNTP Articles\n"); ret = false; goto cleanup; } } /* this is meant to break */ callResult = IsMailboxFolder(&obj_store, 0xFFEEDDCC, &olFolderNumber); if (callResult) { mapitest_print(mt, "* FAILED - expected no folder number\n"); ret = false; goto cleanup; } if (olFolderNumber != 0xFFFFFFFF) { mapitest_print(mt, "* FAILED - wrong folder number for bad folder id\n"); ret = false; goto cleanup; } mapitest_print(mt, "* All PASSED\n"); cleanup: mapi_object_release(&obj_store); mapi_object_release(&obj_pf_store); return ret; } openchange-2.0/utils/mapitest/modules/module_oxctable.c000066400000000000000000000575571223057412600234570ustar00rootroot00000000000000/* Stand-alone MAPI testsuite OpenChange Project - TABLE OBJECT PROTOCOL operations Copyright (C) Julien Kerihuel 2008 Copyright (C) Brad Hards 2008 This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see . */ #include "utils/mapitest/mapitest.h" #include "utils/mapitest/proto.h" /** \file module_oxctable.c \brief Table Object Protocol test suite */ /** \details Test the SetColumns (0x12) operation This function: -# Opens the Inbox folder and gets the hierarchy table -# Calls the SetColumns operation -# Cleans up \param mt pointer to the top-level mapitest structure \return true on success, otherwise false */ _PUBLIC_ bool mapitest_oxctable_SetColumns(struct mapitest *mt) { mapi_object_t obj_htable; struct SPropTagArray *SPropTagArray; /* Step 1. Logon */ if (! mapitest_common_setup(mt, &obj_htable, NULL)) { return false; } /* Step 2. SetColumns */ SPropTagArray = set_SPropTagArray(mt->mem_ctx, 0x3, PR_DISPLAY_NAME, PR_FID, PR_FOLDER_CHILD_COUNT); SetColumns(&obj_htable, SPropTagArray); MAPIFreeBuffer(SPropTagArray); mapitest_print_retval(mt, "SetColumns"); if (GetLastError() != MAPI_E_SUCCESS) { return false; } /* Step 3. Release */ mapi_object_release(&obj_htable); mapitest_common_cleanup(mt); return true; } /** \details Test the QueryColumns (0x37) operation This function: -# Opens the Inbox folder and gets the hierarchy table -# Calls the QueryColumn operation -# Calls SetColumns on the test folder -# Checks that QueryColumns on the test folder is correct -# Cleans up \param mt pointer to the top-level mapitest structure \return true on success, otherwise false */ _PUBLIC_ bool mapitest_oxctable_QueryColumns(struct mapitest *mt) { mapi_object_t obj_htable; mapi_object_t obj_test_folder; struct SPropTagArray columns; struct mt_common_tf_ctx *context; uint32_t count; /* Step 1. Logon */ if (! mapitest_common_setup(mt, &obj_htable, NULL)) { return false; } /* Step 2. QueryColumns */ QueryColumns(&obj_htable, &columns); mapitest_print_retval(mt, "QueryColumns"); if (GetLastError() != MAPI_E_SUCCESS) { return false; } /* Step 3. Get the test folder */ context = mt->priv; mapi_object_init(&(obj_test_folder)); GetContentsTable(&(context->obj_test_folder), &(obj_test_folder), 0, &count); mapitest_print_retval(mt, "GetContentsTable"); if (GetLastError() != MAPI_E_SUCCESS) { return false; } if (count != 10) { mapitest_print(mt, "* %-35s: unexpected count (%i)\n", "GetContentsTable", count); /* This isn't a hard error for this test though, because it might be from a previous test failure. Clean up and try again */ } /* Step 4. QueryColumns on a contents folder */ QueryColumns(&(obj_test_folder), &columns); mapitest_print_retval(mt, "QueryColumns"); if (GetLastError() != MAPI_E_SUCCESS) { return false; } /* TODO: check the return count against something */ mapitest_print(mt, "column count: %i\n", columns.cValues); /* Step 6. Release */ mapi_object_release(&obj_htable); mapi_object_release(&(obj_test_folder)); mapitest_common_cleanup(mt); return true; } /** \details Test the Restrict (0x14) operation This function: -# Opens the Inbox folder and creates some test content -# Checks that the content is OK -# Applies a filter -# Checks the results are as expected. -# Resets the table -# Checks the results are as expected. -# Cleans up \param mt pointer on the top-level mapitest structure \return true on success, otherwise false */ _PUBLIC_ bool mapitest_oxctable_Restrict(struct mapitest *mt) { mapi_object_t obj_htable; mapi_object_t obj_test_folder; struct mt_common_tf_ctx *context; uint32_t count = 0; uint32_t origcount = 0; uint32_t Numerator = 0; uint32_t Denominator = 0; struct mapi_SRestriction res; bool ret = true; /* Step 1. Logon */ if (! mapitest_common_setup(mt, &obj_htable, &count)) { return false; } /* Step 2. Get the test folder */ context = mt->priv; mapi_object_init(&(obj_test_folder)); GetContentsTable(&(context->obj_test_folder), &(obj_test_folder), 0, &origcount); if (GetLastError() != MAPI_E_SUCCESS) { mapitest_print_retval(mt, "GetContentsTable"); ret = false; goto cleanup; } if (origcount != 10) { mapitest_print(mt, "* %-35s: unexpected count (%i)\n", "GetContentsTable", count); /* This isn't a hard error for this test though, because it might be from a previous test failure. Clean up and try again */ } /* Apply a filter */ res.rt = RES_PROPERTY; res.res.resProperty.relop = RES_PROPERTY; res.res.resProperty.ulPropTag = PR_SUBJECT; res.res.resProperty.lpProp.ulPropTag = PR_SUBJECT; res.res.resProperty.lpProp.value.lpszA = MT_MAIL_SUBJECT; Restrict(&(obj_test_folder), &res, NULL); mapitest_print_retval(mt, "Restrict"); if (GetLastError() != MAPI_E_SUCCESS) { ret = false; goto cleanup; } /* Checks the results are as expected */ context = mt->priv; QueryPosition(&(obj_test_folder), &Numerator, &Denominator); if (GetLastError() != MAPI_E_SUCCESS) { mapitest_print_retval(mt, "QueryPosition"); ret = false; goto cleanup; } if (Denominator != origcount/2) { mapitest_print(mt, "* %-35s: unexpected filtered count (%i)\n", "QueryPosition", Denominator); ret = false; goto cleanup; } /* Resets the table */ Reset(&(obj_test_folder)); mapitest_print_retval(mt, "Reset"); if (GetLastError() != MAPI_E_SUCCESS) { ret = false; goto cleanup; } /* Checks the results are as expected */ context = mt->priv; QueryPosition(&(obj_test_folder), &Numerator, &Denominator); if (GetLastError() != MAPI_E_SUCCESS) { mapitest_print_retval(mt, "QueryPosition"); ret = false; goto cleanup; } if (Denominator != origcount) { mapitest_print(mt, "* %-35s: unexpected reset count (%i)\n", "QueryPosition", Denominator); ret = false; goto cleanup; } cleanup: /* Release */ mapi_object_release(&obj_htable); mapi_object_release(&(obj_test_folder)); mapitest_common_cleanup(mt); return ret; } /** \details Test the QueryRows (0x15) operation This function: -# Opens the Inbox folder and gets the hierarchy table -# Set the required columns -# Calls QueryRows until the end of the table -# Open the test folder, and get its contents -# Calls QueryRows until the end of the test folder -# Checks the results are as expected. -# Cleans up \param mt pointer on the top-level mapitest structure \return true on success, otherwise false */ _PUBLIC_ bool mapitest_oxctable_QueryRows(struct mapitest *mt) { enum MAPISTATUS retval; mapi_object_t obj_htable; mapi_object_t obj_test_folder; struct SRowSet SRowSet; struct SPropTagArray *SPropTagArray; struct SPropValue lpProp; struct mt_common_tf_ctx *context; uint32_t idx = 0; uint32_t count = 0; const char* data; /* Step 1. Logon */ if (! mapitest_common_setup(mt, &obj_htable, &count)) { return false; } /* Step 2. Set Table Columns */ SPropTagArray = set_SPropTagArray(mt->mem_ctx, 0x3, PR_DISPLAY_NAME, PR_FID, PR_FOLDER_CHILD_COUNT); retval = SetColumns(&obj_htable, SPropTagArray); MAPIFreeBuffer(SPropTagArray); if (GetLastError() != MAPI_E_SUCCESS) { mapitest_print_retval(mt, "SetColumns"); return false; } /* Step 3. QueryRows */ do { retval = QueryRows(&obj_htable, 0x2, TBL_ADVANCE, &SRowSet); if (SRowSet.cRows > 0) { idx += SRowSet.cRows; if (retval == MAPI_E_SUCCESS) { mapitest_print(mt, "* %-35s: %.2d/%.2d [PASSED]\n", "QueryRows", idx, count); } else { mapitest_print(mt, "* %-35s: %.2d/%.2d [FAILED]\n", "QueryRows", idx, count); } } } while (retval == MAPI_E_SUCCESS && SRowSet.cRows > 0); /* Step 4. Get the test folder */ context = mt->priv; mapi_object_init(&(obj_test_folder)); GetContentsTable(&(context->obj_test_folder), &(obj_test_folder), 0, &count); if (GetLastError() != MAPI_E_SUCCESS) { mapitest_print_retval(mt, "GetContentsTable"); return false; } if (count != 10) { mapitest_print(mt, "* %-35s: unexpected count (%i)\n", "GetContentsTable", count); /* This isn't a hard error for this test though, because it might be from a previous test failure. Clean up and try again */ } /* Step 5. Set Table Columns on the test folder */ SPropTagArray = set_SPropTagArray(mt->mem_ctx, 0x2, PR_BODY, PR_MESSAGE_CLASS); retval = SetColumns(&obj_test_folder, SPropTagArray); MAPIFreeBuffer(SPropTagArray); if (GetLastError() != MAPI_E_SUCCESS) { mapitest_print_retval(mt, "SetColumns"); return false; } /* Step 6. QueryRows on test folder contents */ idx = 0; do { retval = QueryRows(&(obj_test_folder), 0x2, TBL_ADVANCE, &SRowSet); if (SRowSet.cRows > 0) { idx += SRowSet.cRows; if (retval == MAPI_E_SUCCESS) { uint32_t i; mapitest_print(mt, "* %-35s: %.2d/%.2d [PASSED]\n", "QueryRows", idx, count); for (i = 0; i < SRowSet.cRows; ++i) { lpProp = SRowSet.aRow[i].lpProps[0]; if (lpProp.ulPropTag != PR_BODY) { mapitest_print(mt, "* %-35s: Bad proptag0 (0x%x)\n", "QueryRows", lpProp.ulPropTag); return false; } data = get_SPropValue_data(&lpProp); if (0 != strncmp(data, "Body of message", 15)) { mapitest_print(mt, "* %-35s: Bad propval0 (%s)\n", "QueryRows", data); return false; } lpProp = SRowSet.aRow[i].lpProps[1]; if (lpProp.ulPropTag != PR_MESSAGE_CLASS) { mapitest_print(mt, "* %-35s: Bad proptag1 (0x%x)\n", "QueryRows", lpProp.ulPropTag); return false; } data = get_SPropValue_data(&lpProp); if (0 != strncmp(data, "IPM.Note", 8)) { mapitest_print(mt, "* %-35s: Bad propval1 (%s)\n", "QueryRows", data); return false; } } } else { mapitest_print(mt, "* %-35s: %.2d/%.2d [FAILED]\n", "QueryRows", idx, count); } } } while (retval == MAPI_E_SUCCESS && SRowSet.cRows > 0); /* Release */ mapi_object_release(&obj_htable); mapi_object_release(&(obj_test_folder)); mapitest_common_cleanup(mt); return true; } /** \details Test the GetStatus (0x16) operation This function: -# Opens the Inbox folder and gets the hierarchy table -# Call GetStatus -# Cleans up */ _PUBLIC_ bool mapitest_oxctable_GetStatus(struct mapitest *mt) { bool ret = true; mapi_object_t obj_htable; uint8_t TableStatus; /* Step 1. Logon */ if (! mapitest_common_setup(mt, &obj_htable, NULL)) { return false; } /* Step 2. GetStatus */ GetStatus(&obj_htable, &TableStatus); mapitest_print_retval(mt, "GetStatus"); if (GetLastError() != MAPI_E_SUCCESS) { ret = false; } else { mapitest_print(mt, "* %-35s: TableStatus: %d\n", "GetStatus", TableStatus); } /* Step 3. Release */ mapi_object_release(&obj_htable); mapitest_common_cleanup(mt); return ret; } /** \details Test the SeekRow (0x18) operation This function: -# Opens the Inbox folder and gets the hierarchy table -# SeekRow with BOOKMARK_BEGINNING -# SeekRow with BOOKMARK_END -# SeekRow with BOOKMARK_CURRENT -# Cleans up \param mt pointer on the top-level mapitest structure \return true on success, otherwise false */ _PUBLIC_ bool mapitest_oxctable_SeekRow(struct mapitest *mt) { mapi_object_t obj_htable; uint32_t count; /* Step 1. Logon */ if (! mapitest_common_setup(mt, &obj_htable, NULL)) { return false; } /* Step 2. SeekRow */ SeekRow(&obj_htable, BOOKMARK_BEGINNING, 0, &count); mapitest_print_retval_fmt(mt, "SeekRow", "(BOOKMARK_BEGINNING)"); if (GetLastError() != MAPI_E_SUCCESS) { return false; } SeekRow(&obj_htable, BOOKMARK_END, 0, &count); mapitest_print_retval_fmt(mt, "SeekRow", "(BOOKMARK_END)"); if (GetLastError() != MAPI_E_SUCCESS) { return false; } SeekRow(&obj_htable, BOOKMARK_CURRENT, 0, &count); mapitest_print_retval_fmt(mt, "SeekRow", "(BOOKMARK_CURRENT)"); if (GetLastError() != MAPI_E_SUCCESS) { return false; } /* Release */ mapi_object_release(&obj_htable); mapitest_common_cleanup(mt); return true; } /** \details Test the SeekRowApprox (0x1a) operation This function: -# Opens the Inbox folder and gets the hierarchy table -# SeekRowApprox with 0/1, 1/1 and 1/2 fractional values -# Cleans up \param mt pointer on the top-level mapitest structure \return true on success, otherwise false */ _PUBLIC_ bool mapitest_oxctable_SeekRowApprox(struct mapitest *mt) { mapi_object_t obj_htable; /* Step 1. Logon */ if (! mapitest_common_setup(mt, &obj_htable, NULL)) { return false; } /* Step 2. SeekRowApprox */ SeekRowApprox(&obj_htable, 0, 1); mapitest_print_retval_fmt(mt, "SeekRowApprox", "0/1"); if (GetLastError() != MAPI_E_SUCCESS) { return false; } SeekRowApprox(&obj_htable, 1, 1); mapitest_print_retval_fmt(mt, "SeekRowApprox", "1/1"); if (GetLastError() != MAPI_E_SUCCESS) { return false; } SeekRowApprox(&obj_htable, 1, 2); mapitest_print_retval_fmt(mt, "SeekRowApprox", "1/2"); if (GetLastError() != MAPI_E_SUCCESS) { return false; } /* Step 3. Release */ mapi_object_release(&obj_htable); mapitest_common_cleanup(mt); return true; } /** \details Test the CreateBookmark (0x1b) operation This function: -# Opens the Inbox folder and gets the hierarchy table -# Customize the MAPI table view -# CreateBookmark for each table's row -# Free Bookmark for each created bookmark -# Cleans up \param mt pointer on the top-level mapitest structure \return true on success, otherwise false */ _PUBLIC_ bool mapitest_oxctable_CreateBookmark(struct mapitest *mt) { enum MAPISTATUS retval; mapi_object_t obj_htable; uint32_t *bkPosition; uint32_t count; uint32_t i; struct SPropTagArray *SPropTagArray; struct SRowSet SRowSet; /* Step 1. Logon */ if (! mapitest_common_setup(mt, &obj_htable, &count)) { return false; } /* Step 2. Customize the table view */ SPropTagArray = set_SPropTagArray(mt->mem_ctx, 0x3, PR_DISPLAY_NAME, PR_FID, PR_FOLDER_CHILD_COUNT); retval = SetColumns(&obj_htable, SPropTagArray); MAPIFreeBuffer(SPropTagArray); if (retval != MAPI_E_SUCCESS) { return false; } /* Step 3. Create Bookmarks */ bkPosition = talloc_array(mt->mem_ctx, uint32_t, 1); retval = QueryRows(&obj_htable, 100, TBL_ADVANCE, &SRowSet); for (i = 0; i < SRowSet.cRows; i++) { bkPosition = talloc_realloc(mt->mem_ctx, bkPosition, uint32_t, i + 2); retval = CreateBookmark(&obj_htable, &(bkPosition[i])); mapitest_print_retval_fmt_clean(mt, "CreateBookmark", retval, "(%.2d)", i); if (retval != MAPI_E_SUCCESS) { return false; } } retval = mapi_object_bookmark_get_count(&obj_htable, &count); /* Step 4. Free Bookmarks */ for (i = 0; i < count; i++) { retval = FreeBookmark(&obj_htable, bkPosition[i]); mapitest_print_retval_fmt_clean(mt, "FreeBookmark", retval, "(%.2d)", i); if (retval != MAPI_E_SUCCESS) { return false; } } /* Step 5. Release */ mapi_object_release(&obj_htable); mapitest_common_cleanup(mt); talloc_free(bkPosition); return true; } /** \details Test the SeekRowBookmark (0x19) operation This function: -# Open the Inbox folder and retrieve the hierarchy table -# Customize the MAPI table view -# SeekBookmark for each table's row -# Free Bookmark for each created bookmark \param mt pointer on the top-level mapitest structure \return true on success, otherwise false */ _PUBLIC_ bool mapitest_oxctable_SeekRowBookmark(struct mapitest *mt) { enum MAPISTATUS retval; mapi_object_t obj_htable; uint32_t *bkPosition; uint32_t count; uint32_t row; uint32_t i; struct SPropTagArray *SPropTagArray; struct SRowSet SRowSet; /* Step 1. Logon */ if (! mapitest_common_setup(mt, &obj_htable, &count)) { return false; } /* Step 2. Customize the table view */ SPropTagArray = set_SPropTagArray(mt->mem_ctx, 0x3, PR_DISPLAY_NAME, PR_FID, PR_FOLDER_CHILD_COUNT); retval = SetColumns(&obj_htable, SPropTagArray); MAPIFreeBuffer(SPropTagArray); if (retval != MAPI_E_SUCCESS) { return false; } /* Step 3. Create Bookmarks */ bkPosition = talloc_array(mt->mem_ctx, uint32_t, 1); retval = QueryRows(&obj_htable, 100, TBL_ADVANCE, &SRowSet); for (i = 0; i < SRowSet.cRows; i++) { bkPosition = talloc_realloc(mt->mem_ctx, bkPosition, uint32_t, i + 2); retval = CreateBookmark(&obj_htable, &(bkPosition[i])); mapitest_print_retval_fmt_clean(mt, "CreateBookmark", retval, "(%.2d)", i); if (retval != MAPI_E_SUCCESS) { return false; } } mapitest_print_retval(mt, "CreateBookmark"); retval = mapi_object_bookmark_get_count(&obj_htable, &count); /* Step 4. SeekRowBookmark */ for (i = 0; i < SRowSet.cRows; i++) { retval = SeekRowBookmark(&obj_htable, bkPosition[i], 0, &row); mapitest_print_retval_fmt_clean(mt, "SeekRowBookmark", retval, "(%.2d)", i); } /* Step 5. Free Bookmarks */ for (i = 0; i < SRowSet.cRows; i++) { retval = FreeBookmark(&obj_htable, bkPosition[i]); mapitest_print_retval_fmt_clean(mt, "FreeBookmark", retval, "(%.2d)", i); if (retval != MAPI_E_SUCCESS) { return false; } } /* Step 6. Release */ mapi_object_release(&obj_htable); mapitest_common_cleanup(mt); talloc_free(bkPosition); return true; } /** \details Test the SortTable (0x13), ExpandRow (0x59), CollapseRow(0x5a), GetCollapseState(0x6b) and SetCollapseState (0x6c) operations This function: -# Opens the Inbox folder and creates some test content -# Checks that the content is OK -# Applies a sort and categorisation -# Checks the results are as expected. -# Save away the Row ID and Insatnce Number for the first header -# Collapse the first category -# Checks the results are as expected. -# Save the "collapse state" -# Expand the first category again -# Checks the results are as expected -# Restore the saved "collapse state" -# Checks the results are as expected -# Cleans up \param mt pointer on the top-level mapitest structure \return true on success, otherwise false */ _PUBLIC_ bool mapitest_oxctable_Category(struct mapitest *mt) { mapi_object_t obj_htable; mapi_object_t obj_test_folder; struct mt_common_tf_ctx *context; uint32_t count = 0; uint32_t origcount = 0; bool ret = true; struct SSortOrderSet criteria; uint64_t inst_id = 0; uint64_t inst_num = 0; struct SPropTagArray *SPropTagArray; struct SRowSet SRowSet; uint32_t rowcount = 0; uint32_t Numerator = 0; uint32_t Denominator = 0; struct SBinary_short collapseState; /* Step 1. Logon */ if (! mapitest_common_setup(mt, &obj_htable, &count)) { return false; } /* Step 2. Get the test folder */ context = mt->priv; mapi_object_init(&(obj_test_folder)); GetContentsTable(&(context->obj_test_folder), &(obj_test_folder), 0, &origcount); if (GetLastError() != MAPI_E_SUCCESS) { mapitest_print_retval(mt, "GetContentsTable"); ret = false; goto cleanup; } if (origcount != 10) { mapitest_print(mt, "* %-35s: unexpected count (%i)\n", "GetContentsTable", count); /* This isn't a hard error for this test though, because it might be from a previous test failure. Clean up and try again */ } /* We need the header row InstanceId to fold/unfold the headers */ SPropTagArray = set_SPropTagArray(mt->mem_ctx, 0x6, PR_SENDER_NAME, PR_BODY, PR_LAST_MODIFICATION_TIME, PR_SUBJECT, PR_INST_ID, PR_INSTANCE_NUM); SetColumns(&(obj_test_folder), SPropTagArray); MAPIFreeBuffer(SPropTagArray); mapitest_print_retval(mt, "SetColumns"); if (GetLastError() != MAPI_E_SUCCESS) { ret = false; goto cleanup; } /* Apply a categorised sort */ memset(&criteria, 0x0, sizeof (struct SSortOrderSet)); criteria.cSorts = 1; criteria.cCategories = 1; criteria.cExpanded = 1; criteria.aSort = talloc_array(mt->mem_ctx, struct SSortOrder, criteria.cSorts); criteria.aSort[0].ulPropTag = PR_SENDER_NAME; criteria.aSort[0].ulOrder = TABLE_SORT_ASCEND; SortTable(&(obj_test_folder), &criteria); mapitest_print_retval(mt, "SortTable"); if (GetLastError() != MAPI_E_SUCCESS) { ret = false; goto cleanup; } rowcount = 2 * origcount; QueryRows(&(obj_test_folder), rowcount, TBL_ADVANCE, &SRowSet); mapitest_print_retval(mt, "QueryRows"); if (GetLastError() != MAPI_E_SUCCESS) { ret = false; goto cleanup; } /* Checks the results are as expected */ QueryPosition(&(obj_test_folder), &Numerator, &Denominator); mapitest_print_retval(mt, "QueryPosition"); if (GetLastError() != MAPI_E_SUCCESS) { ret = false; goto cleanup; } /* the categories are expanded, and there are six unique senders, so there are six extra rows - one for each header row */ if (Denominator != origcount + 6) { mapitest_print(mt, "* %-35s: unexpected count (%i)\n", "QueryPosition", Numerator); ret = false; goto cleanup; } /* save away ID/instance values for first row header */ inst_id = (*(const uint64_t *)get_SPropValue_data(&(SRowSet.aRow[0].lpProps[4]))); inst_num = (*(const uint32_t *)get_SPropValue_data(&(SRowSet.aRow[0].lpProps[5]))); /* Collapse a row header */ CollapseRow(&(obj_test_folder), inst_id, &rowcount); mapitest_print_retval(mt, "CollapseRow"); if (GetLastError() != MAPI_E_SUCCESS) { ret = false; goto cleanup; } /* Checks the results are as expected */ QueryPosition(&(obj_test_folder), &Numerator, &Denominator); mapitest_print_retval(mt, "QueryPosition"); if (GetLastError() != MAPI_E_SUCCESS) { ret = false; goto cleanup; } /* there are still six unique headers, but half of the real entries are under the first header (usually 10, unless we have some other rubbish hanging around), and when we collapse the first header row, that half disappear */ if (Denominator != origcount/2 + 6) { mapitest_print(mt, "* %-35s: unexpected count (%i)\n", "QueryPosition", Denominator); ret = false; goto cleanup; } /* Save the table collapse state */ GetCollapseState(&(obj_test_folder), inst_id, inst_num, &collapseState); mapitest_print_retval(mt, "GetCollapseState"); if (GetLastError() != MAPI_E_SUCCESS) { ret = false; goto cleanup; } /* Expand a category */ ExpandRow(&(obj_test_folder), inst_id, 20, &SRowSet, &rowcount); mapitest_print_retval(mt, "ExpandRow"); if (GetLastError() != MAPI_E_SUCCESS) { ret = false; goto cleanup; } /* Checks the results are as expected */ QueryPosition(&(obj_test_folder), &Numerator, &Denominator); mapitest_print_retval(mt, "QueryPosition"); if (GetLastError() != MAPI_E_SUCCESS) { ret = false; goto cleanup; } /* we've expanded the first header row, so we now get all the entries plus the 6 headers */ if (Denominator != origcount + 6) { mapitest_print(mt, "* %-35s: unexpected count (%i)\n", "QueryPosition", Denominator); ret = false; goto cleanup; } /* Restore the collapse state */ SetCollapseState(&(obj_test_folder), &collapseState); mapitest_print_retval(mt, "SetCollapseState"); if (GetLastError() != MAPI_E_SUCCESS) { ret = false; goto cleanup; } /* Checks the results are as expected */ QueryPosition(&(obj_test_folder), &Numerator, &Denominator); mapitest_print_retval(mt, "QueryPosition"); if (GetLastError() != MAPI_E_SUCCESS) { ret = false; goto cleanup; } /* back to the situation with the first heading collapsed */ if (Denominator != origcount/2 + 6) { mapitest_print(mt, "* %-35s: unexpected count (%i)\n", "QueryPosition", Denominator); ret = false; goto cleanup; } cleanup: /* Release */ mapi_object_release(&obj_htable); mapi_object_release(&(obj_test_folder)); mapitest_common_cleanup(mt); return ret; } openchange-2.0/utils/mapitest/modules/module_oxomsg.c000066400000000000000000000402141223057412600231500ustar00rootroot00000000000000/* Stand-alone MAPI testsuite OpenChange Project - E-MAIL OBJECT PROTOCOL operations Copyright (C) Julien Kerihuel 2008 This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see . */ #include "utils/mapitest/mapitest.h" #include "utils/mapitest/proto.h" /** \file module_oxomsg.c \brief E-Mail Object Protocol test suite */ /** \details Test the AddressTypes (0x49) and OptionsData (0x6f) operations This function: -# Log on the user private mailbox -# Call the AddressTypes operation -# Call the OptionsData operation on each address type \param mt pointer on the top-level mapitest structure \return true on success, otherwise false */ _PUBLIC_ bool mapitest_oxomsg_AddressTypes(struct mapitest *mt) { enum MAPISTATUS retval; mapi_object_t obj_store; uint16_t cValues; struct mapi_LPSTR *transport = NULL; uint32_t i; uint8_t *optData; uint16_t OptionsDataLength; uint8_t *helpData; uint16_t HelpFileLength; const char* HelpFileName; bool result = true; /* uint8_t txt[1024]; uint32_t j; */ /* Step 1. Logon */ mapi_object_init(&obj_store); retval = OpenMsgStore(mt->session, &obj_store); if (GetLastError() != MAPI_E_SUCCESS) { return false; } /* Step2. AddressTypes operation */ retval = AddressTypes(&obj_store, &cValues, &transport); if (GetLastError() != MAPI_E_SUCCESS) { return false; } for (i = 0; i < cValues; i++) { mapitest_print(mt, "* Recipient Type: %s\n", transport[i].lppszA); retval = OptionsData(&obj_store, transport[i].lppszA, &optData, &OptionsDataLength, &helpData, &HelpFileLength, &HelpFileName); mapitest_print_retval(mt, "OptionsData"); if (retval != MAPI_E_SUCCESS) { result = false; } mapitest_print(mt, "** Size of Options Data: %i\n", OptionsDataLength); /* Just noise to print this out */ /* for (j = 0; j < OptionsDataLength; ++j) { printf("0x%02x ", optData[j]); if (isprint(optData[j])) { txt[j%16] = optData[j]; } else { txt[j%16] = '.'; } txt[16] = '\0'; if (((j+1) % 16) == 0) { printf(" %s\n", txt); } } txt[(j%16)+1] = '\0'; printf(" %s\n", txt); */ mapitest_print(mt, "** Size of Help Data: %i\n", HelpFileLength); mapitest_print(mt, "** Help Data file name: %s\n", HelpFileName); } /* Release */ mapi_object_release(&obj_store); return result; } /** \details Test the SubmitMessage (0x32) operation This function: -# Log on the user private mailbox -# Open the Outbox folder -# Create a sample message -# Submit the message -# Delete the message -# Clean up folders \param mt pointer on the top-level mapitest structure \return true on success, otherwise false */ _PUBLIC_ bool mapitest_oxomsg_SubmitMessage(struct mapitest *mt) { mapi_object_t obj_store; mapi_object_t obj_folder; mapi_object_t obj_message; mapi_id_t id_folder; mapi_id_t id_msgs[1]; bool ret; /* Step 1. Logon */ mapi_object_init(&obj_store); OpenMsgStore(mt->session, &obj_store); if (GetLastError() != MAPI_E_SUCCESS) { return false; } /* Step 2. Open Outbox folder */ GetDefaultFolder(&obj_store, &id_folder, olFolderOutbox); if (GetLastError() != MAPI_E_SUCCESS) { return false; } mapi_object_init(&obj_folder); OpenFolder(&obj_store, id_folder, &obj_folder); if (GetLastError() != MAPI_E_SUCCESS) { return false; } /* Step 3. Create the sample message */ mapi_object_init(&obj_message); ret = mapitest_common_message_create(mt, &obj_folder, &obj_message, MT_MAIL_SUBJECT); if (ret == false) { return ret; } /* Step 4. Submit Message */ SubmitMessage(&obj_message); mapitest_print_retval(mt, "SubmitMessage"); if (GetLastError() != MAPI_E_SUCCESS) { return false; } /* Step 5. Delete Message */ id_msgs[0] = mapi_object_get_id(&obj_message); DeleteMessage(&obj_folder, id_msgs, 1); mapitest_print_retval(mt, "DeleteMessage"); if (GetLastError() != MAPI_E_SUCCESS) { return false; } /* Step 6. Clean up anything else */ mapitest_common_message_delete_by_subject(mt, &obj_folder, MT_MAIL_SUBJECT); GetDefaultFolder(&obj_store, &id_folder, olFolderInbox); OpenFolder(&obj_store, id_folder, &obj_folder); if (GetLastError() != MAPI_E_SUCCESS) { return false; } mapitest_common_message_delete_by_subject(mt, &obj_folder, MT_MAIL_SUBJECT); /* Release */ mapi_object_release(&obj_message); mapi_object_release(&obj_folder); mapi_object_release(&obj_store); return true; } /** \details Test the AbortSubmit (0x34) operation This function: -# Log on the user private mailbox -# Open the Outbox folder -# Create a sample message -# Submit the message -# Abort the submit operation -# Delete the message -# Clean up folders Note: This operation may fail since it depends on how busy the server is when we submit the message. It is possible the message gets already processed before we have time to abort the message. From preliminary tests, AbortSubmit returns MAPI_E_SUCCESS when we call SubmitMessage with SubmitFlags set to 0x2. \param mt pointer on the top-level mapitest structure \return true on success, otherwise false */ _PUBLIC_ bool mapitest_oxomsg_AbortSubmit(struct mapitest *mt) { enum MAPISTATUS retval; mapi_object_t obj_store; mapi_object_t obj_folder; mapi_object_t obj_message; mapi_id_t id_folder; mapi_id_t id_msgs[1]; bool ret = true; /* Step 1. Logon */ mapi_object_init(&obj_store); mapi_object_init(&obj_folder); mapi_object_init(&obj_message); retval = OpenMsgStore(mt->session, &obj_store); if (GetLastError() != MAPI_E_SUCCESS) { ret = false; goto cleanup; } /* Step 2. Open Outbox folder */ retval = GetDefaultFolder(&obj_store, &id_folder, olFolderOutbox); if (GetLastError() != MAPI_E_SUCCESS) { ret = false; goto cleanup; } retval = OpenFolder(&obj_store, id_folder, &obj_folder); if (GetLastError() != MAPI_E_SUCCESS) { ret = false; goto cleanup; } /* Step 3. Create the sample message */ ret = mapitest_common_message_create(mt, &obj_folder, &obj_message, MT_MAIL_SUBJECT); if (ret == false) { goto cleanup; } retval = SaveChangesMessage(&obj_folder, &obj_message, KeepOpenReadWrite); if (GetLastError() != MAPI_E_SUCCESS) { ret = false; goto cleanup; } /* Step 4. Submit Message */ retval = SubmitMessage(&obj_message); retval = AbortSubmit(&obj_store, &obj_folder, &obj_message); mapitest_print_retval(mt, "AbortSubmit"); if ((GetLastError() != MAPI_E_SUCCESS) && (GetLastError() != MAPI_E_UNABLE_TO_ABORT) && (GetLastError() != MAPI_E_NOT_IN_QUEUE)) { ret = false; } /* Step 5. Delete Message */ cleanup: id_msgs[0] = mapi_object_get_id(&obj_message); retval = DeleteMessage(&obj_folder, id_msgs, 1); mapitest_print_retval(mt, "DeleteMessage"); if ((retval != MAPI_E_SUCCESS) && (retval != ecNoDelSubmitMsg)) { ret = false; goto mapitest_oxomsg_AbortSubmit_bailout; } /* Step 6. Clean up anything else */ mapitest_common_message_delete_by_subject(mt, &obj_folder, MT_MAIL_SUBJECT); retval = GetDefaultFolder(&obj_store, &id_folder, olFolderInbox); if (retval != MAPI_E_SUCCESS) { ret = false; goto mapitest_oxomsg_AbortSubmit_bailout; } retval = OpenFolder(&obj_store, id_folder, &obj_folder); if (retval != MAPI_E_SUCCESS) { ret = false; } else { mapitest_common_message_delete_by_subject(mt, &obj_folder, MT_MAIL_SUBJECT); } mapitest_oxomsg_AbortSubmit_bailout: /* Release */ mapi_object_release(&obj_message); mapi_object_release(&obj_folder); mapi_object_release(&obj_store); return ret; } /** \details Test the SetSpooler (0x47) operation This function: -# Log on the user private mailbox -# Informs the server it will acts as an email spooler \param mt pointer on the top-level mapitest structure \return true on success, otherwise false */ _PUBLIC_ bool mapitest_oxomsg_SetSpooler(struct mapitest *mt) { mapi_object_t obj_store; /* Step 1. Logon */ mapi_object_init(&obj_store); OpenMsgStore(mt->session, &obj_store); if (GetLastError() != MAPI_E_SUCCESS) { return false; } /* Step 2. SetSpooler */ SetSpooler(&obj_store); mapitest_print_retval(mt, "SetSpooler"); if (GetLastError() != MAPI_E_SUCCESS) { return false; } /* Release */ mapi_object_release(&obj_store); return true; } /** \details Test the SpoolerLockMessage (0x48) operation This function: -# Log on the user private mailbox -# Informs the server it will acts as an email spooler -# Create a message in the outbox folder -# Save message changes and Submit the message -# Lock the message -# Unlock-Finish the message -# Deletes the message \param mt pointer on the top-level mapitest structure \return true on success, otherwise false */ _PUBLIC_ bool mapitest_oxomsg_SpoolerLockMessage(struct mapitest *mt) { enum MAPISTATUS retval; bool ret = true; mapi_object_t obj_store; mapi_object_t obj_folder; mapi_object_t obj_message; mapi_id_t id_msgs[1]; /* Step 1. Logon */ mapi_object_init(&obj_store); retval = OpenMsgStore(mt->session, &obj_store); if (GetLastError() != MAPI_E_SUCCESS) { return false; } /* Step 2. SetSpooler */ retval = SetSpooler(&obj_store); mapitest_print_retval(mt, "SetSpooler"); if (GetLastError() != MAPI_E_SUCCESS) { return false; } /* Step 3. Open the outbox folder */ mapi_object_init(&obj_folder); ret = mapitest_common_folder_open(mt, &obj_store, &obj_folder, olFolderOutbox); if (ret == false) return ret; /* Step 4. Create the message */ mapi_object_init(&obj_message); ret = mapitest_common_message_create(mt, &obj_folder, &obj_message, MT_MAIL_SUBJECT); mapitest_print(mt, "* %-35s: %s\n", "mapitest_common_message_create", ret == true ? "TRUE" : "FALSE"); if (ret == false) return ret; /* Step 5. Save changes on message */ retval = SaveChangesMessage(&obj_folder, &obj_message, KeepOpenReadWrite); mapitest_print_retval(mt, "SaveChangesMessage"); if (GetLastError() != MAPI_E_SUCCESS) { ret = false; } /* Step 6. Submit the message */ retval = SubmitMessage(&obj_message); mapitest_print_retval(mt, "SubmitMessage"); if (GetLastError() != MAPI_E_SUCCESS) { ret = false; } /* Step 7. Lock the message */ retval = SpoolerLockMessage(&obj_store, &obj_message, LockState_1stLock); mapitest_print_retval_fmt(mt, "SpoolerLockMessage", "1stLock"); if (retval != MAPI_E_SUCCESS) { ret = false; } /* Step 8. finish locking the message */ retval = SpoolerLockMessage(&obj_store, &obj_message, LockState_1stFinished); mapitest_print_retval_fmt(mt, "SpoolerLockMessage", "1stFinished"); if (retval != MAPI_E_SUCCESS) { ret = false; } /* Step 9. Delete Message */ id_msgs[0] = mapi_object_get_id(&obj_message); retval = DeleteMessage(&obj_folder, id_msgs, 1); mapitest_print_retval(mt, "DeleteMessage"); /* Release */ mapi_object_release(&obj_message); mapi_object_release(&obj_folder); mapi_object_release(&obj_store); return ret; } /** \details Test the TransportSend (0x4a) operation This function: -# Logs on to the user private mailbox -# Opens the outbox folder -# Create the test message -# Save changes to the message -# Perform the TransportSend operation -# Dump the properties -# Clean up folders \param mt pointer on the top-level mapitest structure \return true on success, otherwise false */ _PUBLIC_ bool mapitest_oxomsg_TransportSend(struct mapitest *mt) { enum MAPISTATUS retval; bool ret = true; mapi_object_t obj_store; mapi_object_t obj_folder; mapi_object_t obj_message; struct mapi_SPropValue_array lpProps; mapi_id_t id_folder; /* Step 1. Logon */ mapi_object_init(&obj_store); retval = OpenMsgStore(mt->session, &obj_store); if (GetLastError() != MAPI_E_SUCCESS) { return false; } /* Step 2. Open the outbox folder */ mapi_object_init(&obj_folder); ret = mapitest_common_folder_open(mt, &obj_store, &obj_folder, olFolderOutbox); if (ret == false) return ret; /* Step 3. Create the message */ mapi_object_init(&obj_message); ret = mapitest_common_message_create(mt, &obj_folder, &obj_message, MT_MAIL_SUBJECT); mapitest_print(mt, "* %-35s: %s\n", "mapitest_common_message_create", ret == true ? "TRUE" : "FALSE"); if (ret == false) return ret; /* Step 4. Save changes on message */ retval = SaveChangesMessage(&obj_folder, &obj_message, KeepOpenReadWrite); mapitest_print_retval(mt, "SaveChangesMessage"); if (GetLastError() != MAPI_E_SUCCESS) { ret = false; goto mapitest_oxomsg_TransportSend_bailout; } /* Step 5. TransportSend */ retval = TransportSend(&obj_message, &lpProps); mapitest_print_retval(mt, "TransportSend"); if (GetLastError() != MAPI_E_SUCCESS) { ret = false; goto mapitest_oxomsg_TransportSend_bailout; } /* Step 6. Dump the properties */ if (lpProps.lpProps != NULL) { uint32_t i; struct SPropValue lpProp; lpProp.dwAlignPad = 0; for (i = 0; i < lpProps.cValues; i++) { cast_SPropValue(mt->mem_ctx, &lpProps.lpProps[i], &lpProp); mapitest_print_SPropValue(mt, lpProp, "\t* "); } MAPIFreeBuffer(lpProps.lpProps); } /* Step 6. Clean up anything else */ mapitest_common_message_delete_by_subject(mt, &obj_folder, MT_MAIL_SUBJECT); retval = GetDefaultFolder(&obj_store, &id_folder, olFolderInbox); if (retval != MAPI_E_SUCCESS) { ret = false; goto mapitest_oxomsg_TransportSend_bailout; } retval = OpenFolder(&obj_store, id_folder, &obj_folder); if (retval != MAPI_E_SUCCESS) { ret = false; } else { mapitest_common_message_delete_by_subject(mt, &obj_folder, MT_MAIL_SUBJECT); } mapitest_oxomsg_TransportSend_bailout: /* Release */ mapi_object_release(&obj_message); mapi_object_release(&obj_folder); mapi_object_release(&obj_store); return ret; } /** \details Test the TransportNewMail (0x51) operation This function: -# Logs on to the user private mailbox -# Create a filled test folder, and open it. -# Perform the TransportNewMail operation -# Clean up test environment \param mt pointer on the top-level mapitest structure \return true on success, otherwise false */ _PUBLIC_ bool mapitest_oxomsg_TransportNewMail(struct mapitest *mt) { enum MAPISTATUS retval; mapi_object_t obj_htable; bool ret = true; struct mt_common_tf_ctx *context; int i; /* Logon and create filled test folder*/ if (! mapitest_common_setup(mt, &obj_htable, NULL)) { return false; } context = mt->priv; retval = SetSpooler(&(context->obj_store)); /* Perform the TransportNewMail operation */ for (i = 0; i<10; ++i) { retval = TransportNewMail(&(context->obj_store), &(context->obj_test_folder), &(context->obj_test_msg[i]), "IPM.Note", 0x00000008); mapitest_print_retval_clean(mt, "TransportNewMail", retval); if (retval != MAPI_E_SUCCESS) { ret = false; } } /* Clean up */ mapi_object_release(&obj_htable); mapitest_common_cleanup(mt); return ret; } /** \details Test the GetTransportFolder (0x6d) operation This function: -# Log on the user private mailbox -# Retrieves the folder ID of temporary transport folder \param mt pointer on the top-level mapitest structure \return true on success, otherwise false */ _PUBLIC_ bool mapitest_oxomsg_GetTransportFolder(struct mapitest *mt) { enum MAPISTATUS retval; mapi_object_t obj_store; mapi_id_t folder_id = 0; /* Step 1. Logon */ mapi_object_init(&obj_store); retval = OpenMsgStore(mt->session, &obj_store); if (retval != MAPI_E_SUCCESS) { mapi_object_release(&obj_store); return false; } /* Step 2. Get the transport folder */ retval = GetTransportFolder(&obj_store, &folder_id); mapitest_print_retval_fmt(mt, "GetTransportFolder", "(0x%llx)", folder_id); if (retval != MAPI_E_SUCCESS) { mapi_object_release(&obj_store); return false; } return true; } openchange-2.0/utils/mapitest/modules/module_oxorule.c000066400000000000000000000041771223057412600233410ustar00rootroot00000000000000/* Stand-alone MAPI testsuite OpenChange Project - E-MAIL RULES PROTOCOL operations Copyright (C) Julien Kerihuel 2008 This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see . */ #include "utils/mapitest/mapitest.h" #include "utils/mapitest/proto.h" /** \file module_oxorule.c \brief E-Mail Rules Protocol test suite */ /** \details Test the GetRulesTable (0x3f) operation This function: -# Log on the user private mailbox -# Open the inbox folder -# Retrieve the rules table \param mt pointer on the top-level mapitest structure \return true on success, otherwise false */ _PUBLIC_ bool mapitest_oxorule_GetRulesTable(struct mapitest *mt) { enum MAPISTATUS retval; bool ret = true; mapi_object_t obj_store; mapi_object_t obj_folder; mapi_object_t obj_rtable; /* Step 1. Logon */ mapi_object_init(&obj_store); mapi_object_init(&obj_folder); mapi_object_init(&obj_rtable); retval = OpenMsgStore(mt->session, &obj_store); if (retval != MAPI_E_SUCCESS) { ret = false; goto cleanup; } /* Step 2. Open the Inbox folder */ ret = mapitest_common_folder_open(mt, &obj_store, &obj_folder, olFolderInbox); if (ret == false) { goto cleanup; } /* Step 3. Retrieve the rules table */ retval = GetRulesTable(&obj_folder, &obj_rtable, RulesTableFlags_Unicode); mapitest_print_retval(mt, "GetRulesTable"); if (retval != MAPI_E_SUCCESS) { ret = false; goto cleanup; } cleanup: /* Release */ mapi_object_release(&obj_rtable); mapi_object_release(&obj_folder); mapi_object_release(&obj_store); return ret; } openchange-2.0/utils/mapitest/proto.h000066400000000000000000000333441223057412600177750ustar00rootroot00000000000000#ifndef __UTILS_MAPITEST_PROTO_H__ #define __UTILS_MAPITEST_PROTO_H__ #undef _PRINTF_ATTRIBUTE #define _PRINTF_ATTRIBUTE(a1, a2) PRINTF_ATTRIBUTE(a1, a2) #ifndef __BEGIN_DECLS #ifdef __cplusplus #define __BEGIN_DECLS extern "C" { #define __END_DECLS } #else #define __BEGIN_DECLS #define __END_DECLS #endif #endif __BEGIN_DECLS /* This file was automatically generated by mkproto.pl. DO NOT EDIT */ /* this file contains prototypes for functions that are part of * the public API of this subsystem or library. */ #ifndef _PUBLIC_ #define _PUBLIC_ #endif _PUBLIC_ struct mapitest_suite *mapitest_suite_init(struct mapitest *, const char *name, const char *description, bool); _PUBLIC_ uint32_t mapitest_suite_register(struct mapitest *, struct mapitest_suite *); _PUBLIC_ uint32_t mapitest_suite_add_test(struct mapitest_suite *, const char *name, const char *description, bool (*) (struct mapitest *)); _PUBLIC_ uint32_t mapitest_suite_add_test_flagged(struct mapitest_suite *, const char *name, const char *description, bool (*run) (struct mapitest *test), enum TestApplicabilityFlags); _PUBLIC_ struct mapitest_suite *mapitest_suite_find(struct mapitest *, const char *); _PUBLIC_ bool mapitest_suite_run_test(struct mapitest *, struct mapitest_suite *suite, const char *); _PUBLIC_ bool mapitest_run_test(struct mapitest *, const char *); _PUBLIC_ void mapitest_run_all(struct mapitest *); _PUBLIC_ void mapitest_indent(void); _PUBLIC_ void mapitest_deindent(void); _PUBLIC_ void mapitest_print_tab(struct mapitest *); _PUBLIC_ void mapitest_print(struct mapitest *, const char *, ...); _PUBLIC_ void mapitest_print_newline(struct mapitest *, int); _PUBLIC_ void mapitest_print_line(struct mapitest *, int, char); _PUBLIC_ void mapitest_underline(struct mapitest *, const char *, char); _PUBLIC_ void mapitest_print_title(struct mapitest *, const char *, char); _PUBLIC_ void mapitest_print_module_title_start(struct mapitest *, const char *); _PUBLIC_ void mapitest_print_module_title_end(struct mapitest *); _PUBLIC_ void mapitest_print_test_title_start(struct mapitest *, const char *); _PUBLIC_ void mapitest_print_test_title_end(struct mapitest *); _PUBLIC_ void mapitest_print_headers_info(struct mapitest *); _PUBLIC_ void mapitest_print_headers_server_info(struct mapitest *); _PUBLIC_ void mapitest_print_headers(struct mapitest *); _PUBLIC_ void mapitest_print_test_result(struct mapitest *, char *, bool); _PUBLIC_ void mapitest_print_retval(struct mapitest *, char *); _PUBLIC_ void mapitest_print_retval_clean(struct mapitest *, char *, enum MAPISTATUS); _PUBLIC_ void mapitest_print_retval_fmt(struct mapitest *, char *, const char *, ...); _PUBLIC_ void mapitest_print_retval_fmt_clean(struct mapitest *, char *, enum MAPISTATUS, const char *, ...); _PUBLIC_ void mapitest_print_retval_step(struct mapitest *, char *, char *, enum MAPISTATUS); _PUBLIC_ void mapitest_print_retval_step_fmt(struct mapitest *, char *, char *, const char *, ...); _PUBLIC_ void mapitest_print_SRowSet(struct mapitest *, struct SRowSet *, const char *); _PUBLIC_ void mapitest_print_SPropValue(struct mapitest *, struct SPropValue, const char *); _PUBLIC_ void mapitest_print_PAB_entry(struct mapitest *, struct PropertyRow_r *); _PUBLIC_ struct mapitest_stat *mapitest_stat_init(TALLOC_CTX *); _PUBLIC_ uint32_t mapitest_stat_add_result(struct mapitest_suite *, const char *name, enum TestResult); _PUBLIC_ uint32_t mapitest_stat_add_skipped_test(struct mapitest_suite *, const char *name, enum TestApplicabilityFlags); _PUBLIC_ int32_t mapitest_stat_dump(struct mapitest *); _PUBLIC_ bool mapitest_common_folder_open(struct mapitest *, mapi_object_t *obj_parent, mapi_object_t *obj_child, uint32_t); _PUBLIC_ bool mapitest_common_message_delete_by_subject(struct mapitest *, mapi_object_t *obj_folder, const char *); _PUBLIC_ bool mapitest_common_find_folder(struct mapitest *, mapi_object_t *obj_parent, mapi_object_t *obj_child, const char *); _PUBLIC_ bool mapitest_common_message_create(struct mapitest *, mapi_object_t *obj_folder, mapi_object_t *obj_message, const char *); _PUBLIC_ bool mapitest_common_message_fill(struct mapitest *, mapi_object_t *obj_message, const char *); _PUBLIC_ char *mapitest_common_genblob(TALLOC_CTX *, size_t); _PUBLIC_ bool mapitest_common_create_filled_test_folder(struct mapitest *); _PUBLIC_ bool mapitest_common_setup(struct mapitest *, mapi_object_t *, uint32_t *); _PUBLIC_ void mapitest_common_cleanup(struct mapitest *); _PUBLIC_ uint32_t mapitest_register_modules(struct mapitest *); _PUBLIC_ uint32_t module_oxcstor_init(struct mapitest *); _PUBLIC_ uint32_t module_oxcfold_init(struct mapitest *); _PUBLIC_ uint32_t module_oxomsg_init(struct mapitest *); _PUBLIC_ uint32_t module_oxcmsg_init(struct mapitest *); _PUBLIC_ uint32_t module_oxctable_init(struct mapitest *); _PUBLIC_ uint32_t module_oxcprpt_init(struct mapitest *); _PUBLIC_ uint32_t module_oxorule_init(struct mapitest *); _PUBLIC_ uint32_t module_oxcnotif_init(struct mapitest *); _PUBLIC_ uint32_t module_oxcfxics_init(struct mapitest *); _PUBLIC_ uint32_t module_oxcperm_init(struct mapitest *); _PUBLIC_ uint32_t module_nspi_init(struct mapitest *); _PUBLIC_ uint32_t module_noserver_init(struct mapitest *); _PUBLIC_ uint32_t module_errorchecks_init(struct mapitest *); _PUBLIC_ uint32_t module_lcid_init(struct mapitest *); _PUBLIC_ uint32_t module_mapidump_init(struct mapitest *); _PUBLIC_ uint32_t module_lzxpress_init(struct mapitest *); _PUBLIC_ bool mapitest_oxcstor_Logon(struct mapitest *); _PUBLIC_ bool mapitest_oxcstor_GetReceiveFolder(struct mapitest *); _PUBLIC_ bool mapitest_oxcstor_SetReceiveFolder(struct mapitest *); _PUBLIC_ bool mapitest_oxcstor_GetOwningServers(struct mapitest *); _PUBLIC_ bool mapitest_oxcstor_PublicFolderIsGhosted(struct mapitest *); _PUBLIC_ bool mapitest_oxcstor_GetReceiveFolderTable(struct mapitest *); _PUBLIC_ bool mapitest_oxcstor_LongTermId(struct mapitest *); _PUBLIC_ bool mapitest_oxcstor_GetStoreState(struct mapitest *); _PUBLIC_ bool mapitest_oxcstor_IsMailboxFolder(struct mapitest *); _PUBLIC_ bool mapitest_oxcfold_OpenFolder(struct mapitest *); _PUBLIC_ bool mapitest_oxcfold_CreateDeleteFolder(struct mapitest *); _PUBLIC_ bool mapitest_oxcfold_CreateFolder(struct mapitest *); _PUBLIC_ bool mapitest_oxcfold_CreateFolderVariants(struct mapitest *); _PUBLIC_ bool mapitest_oxcfold_GetHierarchyTable(struct mapitest *); _PUBLIC_ bool mapitest_oxcfold_GetContentsTable(struct mapitest *); _PUBLIC_ bool mapitest_oxcfold_SetSearchCriteria(struct mapitest *); _PUBLIC_ bool mapitest_oxcfold_GetSearchCriteria(struct mapitest *); _PUBLIC_ bool mapitest_oxcfold_MoveCopyMessages(struct mapitest *); _PUBLIC_ bool mapitest_oxcfold_MoveFolder(struct mapitest *); _PUBLIC_ bool mapitest_oxcfold_CopyFolder(struct mapitest *); _PUBLIC_ bool mapitest_oxcfold_HardDeleteMessages(struct mapitest *); _PUBLIC_ bool mapitest_oxcfold_HardDeleteMessagesAndSubfolders(struct mapitest *); _PUBLIC_ bool mapitest_oxcfold_DeleteMessages(struct mapitest *); _PUBLIC_ bool mapitest_oxcfxics_GetLocalReplicaIds(struct mapitest *); _PUBLIC_ bool mapitest_oxcfxics_DestConfigure(struct mapitest *); _PUBLIC_ bool mapitest_oxcfxics_CopyFolder(struct mapitest *); _PUBLIC_ bool mapitest_oxcfxics_CopyMessages(struct mapitest *); _PUBLIC_ bool mapitest_oxcfxics_CopyTo(struct mapitest *); _PUBLIC_ bool mapitest_oxcfxics_CopyProperties(struct mapitest *); _PUBLIC_ bool mapitest_oxcfxics_SyncConfigure(struct mapitest *); _PUBLIC_ bool mapitest_oxcfxics_SetLocalReplicaMidsetDeleted(struct mapitest *); _PUBLIC_ bool mapitest_oxcfxics_SyncOpenCollector(struct mapitest *); _PUBLIC_ bool mapitest_oxomsg_AddressTypes(struct mapitest *); _PUBLIC_ bool mapitest_oxomsg_SubmitMessage(struct mapitest *); _PUBLIC_ bool mapitest_oxomsg_AbortSubmit(struct mapitest *); _PUBLIC_ bool mapitest_oxomsg_SetSpooler(struct mapitest *); _PUBLIC_ bool mapitest_oxomsg_SpoolerLockMessage(struct mapitest *); _PUBLIC_ bool mapitest_oxomsg_TransportSend(struct mapitest *); _PUBLIC_ bool mapitest_oxomsg_TransportNewMail(struct mapitest *); _PUBLIC_ bool mapitest_oxomsg_GetTransportFolder(struct mapitest *); _PUBLIC_ bool mapitest_oxcmsg_CreateMessage(struct mapitest *); _PUBLIC_ bool mapitest_oxcmsg_SetMessageReadFlag(struct mapitest *); _PUBLIC_ bool mapitest_oxcmsg_ModifyRecipients(struct mapitest *); _PUBLIC_ bool mapitest_oxcmsg_RemoveAllRecipients(struct mapitest *); _PUBLIC_ bool mapitest_oxcmsg_ReadRecipients(struct mapitest *); _PUBLIC_ bool mapitest_oxcmsg_SaveChangesMessage(struct mapitest *); _PUBLIC_ bool mapitest_oxcmsg_GetMessageStatus(struct mapitest *); _PUBLIC_ bool mapitest_oxcmsg_SetMessageStatus(struct mapitest *); _PUBLIC_ bool mapitest_oxcmsg_SetReadFlags(struct mapitest *); _PUBLIC_ bool mapitest_oxcmsg_OpenEmbeddedMessage(struct mapitest *); _PUBLIC_ bool mapitest_oxcmsg_GetValidAttachments(struct mapitest *); _PUBLIC_ bool mapitest_oxcmsg_ReloadCachedInformation(struct mapitest *); _PUBLIC_ bool mapitest_oxcprpt_GetProps(struct mapitest *); _PUBLIC_ bool mapitest_oxcprpt_GetPropsAll(struct mapitest *); _PUBLIC_ bool mapitest_oxcprpt_GetPropList(struct mapitest *); _PUBLIC_ bool mapitest_oxcprpt_SetProps(struct mapitest *); _PUBLIC_ bool mapitest_oxcprpt_DeleteProps(struct mapitest *); _PUBLIC_ bool mapitest_oxcprpt_CopyProps(struct mapitest *); _PUBLIC_ bool mapitest_oxcprpt_Stream(struct mapitest *); _PUBLIC_ bool mapitest_oxcprpt_CopyToStream(struct mapitest *); _PUBLIC_ bool mapitest_oxcprpt_CopyTo(struct mapitest *); _PUBLIC_ bool mapitest_oxcprpt_NameId(struct mapitest *); _PUBLIC_ bool mapitest_oxcprpt_NameId_PSMAPI(struct mapitest *); _PUBLIC_ bool mapitest_oxcprpt_NoReplicate(struct mapitest *); _PUBLIC_ bool mapitest_oxcprpt_WriteAndCommitStream(struct mapitest *); _PUBLIC_ bool mapitest_oxctable_SetColumns(struct mapitest *); _PUBLIC_ bool mapitest_oxctable_QueryColumns(struct mapitest *); _PUBLIC_ bool mapitest_oxctable_Restrict(struct mapitest *); _PUBLIC_ bool mapitest_oxctable_QueryRows(struct mapitest *); _PUBLIC_ bool mapitest_oxctable_GetStatus(struct mapitest *); _PUBLIC_ bool mapitest_oxctable_SeekRow(struct mapitest *); _PUBLIC_ bool mapitest_oxctable_SeekRowApprox(struct mapitest *); _PUBLIC_ bool mapitest_oxctable_CreateBookmark(struct mapitest *); _PUBLIC_ bool mapitest_oxctable_SeekRowBookmark(struct mapitest *); _PUBLIC_ bool mapitest_oxctable_Category(struct mapitest *); _PUBLIC_ bool mapitest_oxorule_GetRulesTable(struct mapitest *); _PUBLIC_ bool mapitest_oxcnotif_RegisterNotification(struct mapitest *); _PUBLIC_ bool mapitest_oxcnotif_SyncOpenAdvisor(struct mapitest *); _PUBLIC_ bool mapitest_oxcperm_GetPermissionsTable(struct mapitest *); _PUBLIC_ bool mapitest_oxcperm_ModifyPermissions(struct mapitest *); _PUBLIC_ bool mapitest_nspi_UpdateStat(struct mapitest *); _PUBLIC_ bool mapitest_nspi_QueryRows(struct mapitest *); _PUBLIC_ bool mapitest_nspi_SeekEntries(struct mapitest *); _PUBLIC_ bool mapitest_nspi_GetMatches(struct mapitest *); _PUBLIC_ bool mapitest_nspi_ResortRestriction(struct mapitest *); _PUBLIC_ bool mapitest_nspi_DNToMId(struct mapitest *); _PUBLIC_ bool mapitest_nspi_GetPropList(struct mapitest *); _PUBLIC_ bool mapitest_nspi_GetProps(struct mapitest *); _PUBLIC_ bool mapitest_nspi_CompareMIds(struct mapitest *); _PUBLIC_ bool mapitest_nspi_ModProps(struct mapitest *); _PUBLIC_ bool mapitest_nspi_GetSpecialTable(struct mapitest *); _PUBLIC_ bool mapitest_nspi_GetTemplateInfo(struct mapitest *); _PUBLIC_ bool mapitest_nspi_ModLinkAtt(struct mapitest *); _PUBLIC_ bool mapitest_nspi_QueryColumns(struct mapitest *); _PUBLIC_ bool mapitest_nspi_GetNamesFromIDs(struct mapitest *); _PUBLIC_ bool mapitest_nspi_GetIDsFromNames(struct mapitest *); _PUBLIC_ bool mapitest_nspi_ResolveNames(struct mapitest *); _PUBLIC_ bool mapitest_nspi_GetGALTable(struct mapitest *); _PUBLIC_ bool mapitest_noserver_lzfu(struct mapitest *); _PUBLIC_ bool mapitest_noserver_rtfcp(struct mapitest *); _PUBLIC_ bool mapitest_noserver_rtfcp_large(struct mapitest *); _PUBLIC_ bool mapitest_noserver_srowset(struct mapitest *) ; _PUBLIC_ bool mapitest_noserver_properties(struct mapitest *) ; _PUBLIC_ bool mapitest_noserver_mapi_properties(struct mapitest *) ; _PUBLIC_ bool mapitest_noserver_proptagvalue(struct mapitest *) ; _PUBLIC_ bool mapitest_errorchecks_simplemapi_c(struct mapitest *); _PUBLIC_ bool mapitest_lcid_langcode2langtag(struct mapitest *); _PUBLIC_ bool mapitest_mapidump_spropvalue(struct mapitest *); _PUBLIC_ bool mapitest_mapidump_sproptagarray(struct mapitest *); _PUBLIC_ bool mapitest_mapidump_srowset(struct mapitest *); _PUBLIC_ bool mapitest_mapidump_pabentry(struct mapitest *); _PUBLIC_ bool mapitest_mapidump_note(struct mapitest *); _PUBLIC_ bool mapitest_mapidump_task(struct mapitest *); _PUBLIC_ bool mapitest_mapidump_contact(struct mapitest *); _PUBLIC_ bool mapitest_mapidump_appointment(struct mapitest *); _PUBLIC_ bool mapitest_mapidump_message(struct mapitest *); _PUBLIC_ bool mapitest_mapidump_newmail(struct mapitest *); _PUBLIC_ bool mapitest_mapidump_freebusy(struct mapitest *); _PUBLIC_ bool mapitest_mapidump_recipients(struct mapitest *); _PUBLIC_ bool mapitest_mapidump_folderdeleted(struct mapitest *); _PUBLIC_ bool mapitest_mapidump_foldermoved(struct mapitest *); _PUBLIC_ bool mapitest_mapidump_foldercopied(struct mapitest *); _PUBLIC_ bool mapitest_mapidump_foldercreated(struct mapitest *); _PUBLIC_ bool mapitest_mapidump_messagedeleted(struct mapitest *); _PUBLIC_ bool mapitest_mapidump_messagecreated(struct mapitest *); _PUBLIC_ bool mapitest_mapidump_messagemoved(struct mapitest *); _PUBLIC_ bool mapitest_mapidump_messagecopied(struct mapitest *); _PUBLIC_ bool mapitest_mapidump_messagemodified(struct mapitest *); _PUBLIC_ bool mapitest_lzxpress_validate_test_001(struct mapitest *); __END_DECLS #undef _PRINTF_ATTRIBUTE #define _PRINTF_ATTRIBUTE(a1, a2) #endif /* __UTILS_MAPITEST_PROTO_H__ */ openchange-2.0/utils/mapitrace/000077500000000000000000000000001223057412600165715ustar00rootroot00000000000000openchange-2.0/utils/mapitrace/Makefile.PL000066400000000000000000000002551223057412600205450ustar00rootroot00000000000000use ExtUtils::MakeMaker; WriteMakefile( 'NAME' => 'MAPI::Mapitrace', 'VERSION_FROM' => 'lib/MAPI/EcDoRpc.pm', 'EXE_FILES' => [ 'mapitrace' ], ); openchange-2.0/utils/mapitrace/lib/000077500000000000000000000000001223057412600173375ustar00rootroot00000000000000openchange-2.0/utils/mapitrace/lib/MAPI/000077500000000000000000000000001223057412600200655ustar00rootroot00000000000000openchange-2.0/utils/mapitrace/lib/MAPI/Dump_EcDoRpc.pm000066400000000000000000000123311223057412600226670ustar00rootroot00000000000000############################################# # EcDoRpc Dump utility for mapitrace tool # Copyright Julien Kerihuel 2007 # # # released under the GNU GPL v3 or later # package MAPI::Dump_EcDoRpc; require Exporter; @ISA = qw(Exporter); @EXPORT = qw(); use vars qw($AUTOLOAD $VERSION); $VERSION = '0.01'; use strict; use Data::Dumper; ####################################################### # convenient sort functions # ####################################################### sub pkt_number { my ($aa) = $a =~ /(\d+)/; my($bb) = $b =~ /(\d+)/; ($aa) <=> ($bb); } sub asc_num { hex($a) <=> hex($b); } ####################################################### # BRACE DUMPING FUNCTIONS ####################################################### sub dump_error_brace { my $_self = shift; my $self = shift; foreach my $key (sort asc_num (keys(%{$self->{BRACES_ERROR}}))) { my $inout = $self->{BRACES_ERROR}->{$key}->{error}; if ($inout) { print "[mapitrace] error in [$inout]: "; print $self->{BRACES_ERROR}->{$key}->{$inout}->{filename} . "\n"; } } } sub dump_brace_start { my $_self = shift; my $in = shift; my $out = shift; print MAPI::EcDoRpc->get_filename($in->{filename}); print " / "; print MAPI::EcDoRpc->get_filename($out->{filename}); print "\n"; print "----------------------------------------------\n"; } sub dump_brace_end { print "\n\n"; } ####################################################### # DUMP FUNCTIONS FOR THE ANALYZE PART ####################################################### # # Dump the handles array from a request or response # sub dump_handles { my $_self = shift; my $self = shift; my @handles = @_; print $self->{filename} . " :\n"; print "handles array (" . ($#handles + 1) . "):\n"; print "\t$_\n" foreach (@handles); print "\n"; } # # Provides a dual dump view for the handle array # both in request and response # # MAPI Semantic tells that request and response have the same # number of handles elements # sub dump_brace_handles { my $_self = shift; my $mapi_call = shift; my @handles_in = @{$mapi_call->{handles_in}}; my @handles_out = @{$mapi_call->{handles_out}}; print "handles array (" . ($#handles_in + 1) . "):\n"; for (my $i = 0; $handles_in[$i]; $i++) { printf "\t[%.2x] %s -> %s\n", $i, $handles_in[$i], $handles_out[$i]; } } # # Print a call # # sub dump_call { my $mapi_call = shift; my $key = shift; my $call_idx = shift; my $space = shift; my $in = $mapi_call->{calls}->{REQ}; my $out = $mapi_call->{calls}->{REPL}; my $new_idx; if ($call_idx) { $new_idx = MAPI::EcDoRpc->get_call_index($mapi_call, $call_idx); printf "\t%s+-- [0x%.2x] [%s] (opnum = %s) %15s (handle_idx = %s) (child of %s)\n", $space, hex($call_idx), (exists $out->{$new_idx}->{retval}) ? $out->{$new_idx}->{retval}:'', $in->{$call_idx}->{opnum}, $in->{$call_idx}->{opname}, $in->{$call_idx}->{handle_idx}, $in->{$key}->{opname}; } else { $new_idx = MAPI::EcDoRpc->get_call_index($mapi_call, $key); printf "\t[0x%.2x] [%s] (opnum = %s) %25s (handle_idx = %s) (self_handle_idx = %s)\n", hex($key), (exists $out->{$new_idx}->{retval}) ? $out->{$new_idx}->{retval} : '', $in->{$key}->{opnum}, $in->{$key}->{opname}, $in->{$key}->{handle_idx}, $in->{$key}->{self_handle_idx}; } } # # Dump mapi calls # # Since calls with self_handles have a smaller index than other calls relying on them # When a parent value is > than the current idx, we can skip display the call. # It should have normally been printing earlier when checking for call children # Return -1 if we have an error # sub dump_mapi_calls { my $_self = shift; my $mapi_call = shift; my $in = $mapi_call->{calls}->{REQ}; my $out = $mapi_call->{calls}->{REPL}; my $in_call_count = MAPI::EcDoRpc->get_mapi_calls_request_count($in); if ($in_call_count != keys(%{$out})) { print "[mapitrace] error: Oops seems like we have some trouble ...\n"; print "[mapitrace] error: Mismatch call count between request ($in_call_count) and response (". keys(%{$out}) .")\n"; return -1; } printf "serialized mapi calls (count = %.2d):\n", $in_call_count; foreach my $key (sort asc_num (keys(%{$in}))) { if ($in->{$key}->{self_handle_idx}) { # If this self_handle call has a child ;p my $space = " "; if (exists $in->{$key}->{parent}) { $space .= " "; } else { dump_call($mapi_call, $key, 0, 0); } # Check if the call with self_handle_idx has children # The dump will fail if we have Release call. # In order to avoid this problem we use out instead if ($in->{$key}->{children}) { foreach my $call_idx (sort asc_num @{$in->{$key}->{children}}) { dump_call($mapi_call, $key, $call_idx, $space); } } } else { if (exists $in->{$key}->{parent} && hex($in->{$key}->{parent}) < hex($key)) { } else { printf "\t[0x%.2x] [%s] (opnum = %s) %25s (handle_idx = %s)\n", hex($key), (exists $out->{$key}->{retval}) ? $out->{$key}->{retval}: '', $in->{$key}->{opnum}, $in->{$key}->{opname}, $in->{$key}->{handle_idx}; } } } print "\n"; return 0; } 1; openchange-2.0/utils/mapitrace/lib/MAPI/EcDoRpc.pm000066400000000000000000000464571223057412600217220ustar00rootroot00000000000000############################################# # EcDoRpc package for mapitrace tool # Copyright Julien Kerihuel 2007 # # # released under the GNU GPL v3 or later # package MAPI::EcDoRpc; require Exporter; @ISA = qw(Exporter); @EXPORT = qw(); use vars qw($AUTOLOAD $VERSION); $VERSION = '0.03'; use strict; use File::Basename; use MAPI::Dump_EcDoRpc; use MAPI::Graph; use MAPI::Regression; use MAPI::Statistic; use Data::Dumper; ####################################################### # CONVENIENT SORT FUNCTIONS ####################################################### sub pkt_number { my ($aa) = $a =~ /(\d+)/; my($bb) = $b =~ /(\d+)/; ($aa) <=> ($bb); } sub asc_num { hex($a) <=> hex($b); } sub sort_packets { my $garbage = 0; my @file1 = split(/\_/, get_filename($garbage, $a)); my @file2 = split(/\_/, get_filename($garbage, $b)); hex($file1[0]) <=> hex($file2[0]); } ####################################################### # CONVENIENT GET FUNCTIONS ####################################################### # # Dump the filename from a pathname # sub get_filename { my $_self = shift; my $pathname = shift; my @parts = split(/\//, $pathname); return $parts[$#parts]; } ####################################################### # INIT PART ####################################################### # # index packets by ascending numeric order # brace packets {in,out} # ndrdump files in the output field # sub new { my $_self = shift; my $path = shift; my $outputdir = shift; my $verbose = shift; my $counter = -1; my $self = {}; $self->{CONF} = {}; $self->{CONF}->{stdout} = 1; $self->{CONF}->{outputdir} = $outputdir; $self->{CONF}->{path} = $path; $self->{CONF}->{verbose} = $verbose; $self->{CONF}->{name} = $_self->get_filename($path); $self->{ECDORPC} = {}; $self->{ECDORPC}->{braces_count} = 0; $self->{ECDORPC}->{braces} = {}; $self->{ECDORPC_ERROR} = {}; $self->{ECDORPC_ERROR}->{in} = {}; $self->{ECDORPC_ERROR}->{out} = {}; ############# Should disappear ################ $self->{BRACES_ERROR} = {}; $self->{SKIPPED_FILES} = {}; $self->{SKIPPED_FILES}->{REQ} = {}; $self->{SKIPPED_FILES}->{REQ}->{count} = 0; $self->{SKIPPED_FILES}->{REQ}->{files} = {}; $self->{SKIPPED_FILES}->{REPL} = {}; $self->{SKIPPED_FILES}->{REPL}->{count} = 0; $self->{SKIPPED_FILES}->{REPL}->{files} = {}; ############# /Should disappear ################ my @files = <$path/*_Mapi_EcDoRpc>; my @ndrdump_files = sort sort_packets @files; $self->{STATISTIC} = MAPI::Statistic->new($_self->get_filename($path), @ndrdump_files); my $in_filename = 0; my $out_filename = 0; foreach(@ndrdump_files) { chomp($_); if ($_ =~ /in/) { if ($in_filename) { print "[1] Skipping $in_filename\n" if $self->{CONF}->{verbose}; $in_filename = $_; add_skipped_file($self, $in_filename, "REQ"); } else { $in_filename = $_ if (!$in_filename); } } if ($_ =~ /out/) { if (!$in_filename) { print "[2] Skipping $_\n" if $self->{CONF}->{verbose}; add_skipped_file($self, $_, "REPL"); } else { $out_filename = $_; $counter++; add_brace($self, $counter, $in_filename, $out_filename); $out_filename = $in_filename = 0; } } $self->{ECDORPC}->{braces_count} = $counter; } bless($self); return $self; } ####################################################### # ERROR RELATED FUNCTIONS ####################################################### sub add_bad_packet { my $self = shift; my $inout = shift; my $filename = shift; my $output = shift; $self->{STATISTIC}->failure_request_counter() if ($inout eq "in"); $self->{STATISTIC}->failure_response_counter() if ($inout eq "out"); $self->{ECDORPC_ERROR}->{$inout}->{$filename} = {}; my $packet = $self->{ECDORPC_ERROR}->{$inout}->{$filename}; $packet->{output} = $output; } sub error_report { my $self = shift; my $inout = shift; if ($inout ne "in" && $inout ne "out") { print "[mapitrace]: Wrong parameter, must be in or out\n"; return -1; } print "\n[$inout" . "put error_report]:\n\n"; foreach my $key (sort sort_packets keys (%{$self->{ECDORPC_ERROR}->{$inout}})) { print $key . "\n"; } } ####################################################### # NDRDUMP + BRACES + STORAGE OPERATIONS ####################################################### # # Initialize and add a brace to the hash # sub add_brace { my $self = shift; my $idx = shift; my $in_filename = shift; my $out_filename = shift; $self->{ECDORPC}->{braces}->{$idx} = {}; $self->{ECDORPC}->{braces}->{$idx}->{in} = {}; $self->{ECDORPC}->{braces}->{$idx}->{out} = {}; $self->{ECDORPC}->{braces}->{$idx}->{in}->{filename} = $in_filename; $self->{ECDORPC}->{braces}->{$idx}->{in}->{output} = ''; $self->{ECDORPC}->{braces}->{$idx}->{out}->{filename} = $out_filename; $self->{ECDORPC}->{braces}->{$idx}->{out}->{output} = ''; $self->{STATISTIC}->increment_brace_counter(); } # # Store the error brace in the BRACES_ERROR hash and # Delete the brace from the ECDORPC hash # sub delete_brace { my $self = shift; my $idx = shift; $self->{BRACES_ERROR}->{$idx} = {}; $self->{BRACES_ERROR}->{$idx} = $self->{ECDORPC}->{braces}->{$idx}; $self->{ECDORPC}->{braces_count}--; delete($self->{ECDORPC}->{braces}->{$idx}); $self->{STATISTIC}->increment_brace_error_counter(); } # # ndrdump a brace and check in the output # if we have an error (segfault) # sub ndrdump_brace { my $self = shift; my $idx = shift; my $inout = shift; my $filename = $self->{ECDORPC}->{braces}->{$idx}->{$inout}->{filename}; my $output = `ndrdump -l libmapi.so exchange_emsmdb 0x2 $inout $filename`; $self->{ECDORPC}->{braces}->{$idx}->{$inout}->{output} = $output; if ($output =~ /INTERNAL ERROR:/) { $self->add_bad_packet($inout, $filename, $output); $self->{ECDORPC}->{braces}->{$idx}->{error} = $inout; return $idx; } $self->{STATISTIC}->success_request_counter() if ($inout eq "in"); $self->{STATISTIC}->success_response_counter() if ($inout eq "out"); return 0; } # # ndrdump the files in the list and clean the hash # if incorrect braces are found # sub ndrdump { my $self = shift; my @invalid_braces = (); my $idx; foreach my $key (sort asc_num (keys(%{$self->{ECDORPC}->{braces}}))) { push(@invalid_braces, $idx) if ($idx = ndrdump_brace($self, $key, "in")); push(@invalid_braces, $idx) if ($idx = ndrdump_brace($self, $key, "out")); } # $self->{STATISTIC}->{} foreach(@invalid_braces) { delete_brace($self, $_); } # MAPI::Dump_EcDoRpc->dump_error_brace($self); } ############################################################ # ANALYZE PART ############################################################ # # Retrieve the handles array (in,out) from a given packet # sub get_pkt_handles { my $self = shift; my $mapi_call = shift; my $inout = shift; my $output = shift; my @lines = split(/\n/, $output); my $count_marker = 0; foreach(@lines) { if ($count_marker) { $_ =~ /: (\w+) \(/i; push(@{$mapi_call->{handles_in}}, $1) if ($inout eq "REQ"); push(@{$mapi_call->{handles_out}}, $1) if ($inout eq "REPL"); $count_marker--; } if (!$count_marker && $_ =~ /\(handles\)/) { $_ =~/number=(\d+)/i; $count_marker = $1; } } } # # Reset mapi_call markers # sub mapi_call_reset_markers { my $mapi_call = shift; $mapi_call->{marker}->{opnum} = 0; $mapi_call->{marker}->{opname} = 0; $mapi_call->{marker}->{handle_idx} = 0; $mapi_call->{marker}->{sub_handles} = 0; $mapi_call->{marker}->{store} = 0; } # # Initialize the mapi call parsing structure # sub init_mapi_call { my $mapi_call = {}; # Initialize markers $mapi_call->{marker} = {}; mapi_call_reset_markers($mapi_call); $mapi_call->{marker}->{call_idx} = -1; # Initialize the call serialization hash $mapi_call->{calls} = {}; # Initialize handles $mapi_call->{handles_in} = (); $mapi_call->{handles_out} = (); bless($mapi_call); return ($mapi_call); } # # Get the start of a mapi call # sub get_mapi_call_start { my $mapi_call = shift; my $line = shift; my $inout = shift; if ($line =~ /EcDoRpc_MAPI_$inout$/) { mapi_call_reset_markers($mapi_call); $mapi_call->{marker}->{opnum} = 1; $mapi_call->{marker}->{call_idx}++; } } # # Get mapi call opnum # sub get_mapi_call_opnum { my $mapi_call = shift; my $line = shift; my $inout = shift; if ($mapi_call->{marker}->{opnum} && $line =~ /opnum\s+:/) { $line =~ /(0x\w{2})/i; my $idx = $mapi_call->{marker}->{call_idx}; $mapi_call->{calls}->{$inout}->{$idx}->{opnum} = $1; $mapi_call->{marker}->{opnum} = 0; $mapi_call->{marker}->{handle_idx} = 1; $mapi_call->{marker}->{retval} = 1; } } # # Get mapi call opname # sub get_mapi_call_opname { my $mapi_call = shift; my $line = shift; my $inout = shift; if ($mapi_call->{marker}->{opname} && $line =~ /mapi_\w+: struct/) { $line =~ /mapi_(\w+):/i; my $idx = $mapi_call->{marker}->{call_idx}; $mapi_call->{calls}->{$inout}->{$idx}->{opname} = $1; $mapi_call->{marker}->{opname} = 0; $mapi_call->{marker}->{sub_handles} = 1; } } # # Get mapi call error code # sub get_mapi_call_retval { my $mapi_call = shift; my $line = shift; my $inout = shift; if ($mapi_call->{marker}->{retval} && $line =~ /error_code/) { $line =~ /error_code\s+:\s+(\w+)/i; my $idx = $mapi_call->{marker}->{call_idx}; $mapi_call->{calls}->{$inout}->{$idx}->{retval} = $1; $mapi_call->{marker}->{retval} = 0; } } # # Get mapi call handle idx # sub get_mapi_call_handle_idx { my $mapi_call = shift; my $line = shift; my $inout = shift; if ($mapi_call->{marker}->{handle_idx} && $line =~ /handle_idx\s+:/) { $line =~ /(0x\w{2})/i; my $idx = $mapi_call->{marker}->{call_idx}; $mapi_call->{calls}->{$inout}->{$idx}->{handle_idx} = $1; $mapi_call->{marker}->{handle_idx} = 0; $mapi_call->{marker}->{opname} = 1; } } # # Get sub handles idx within mapi_call specific dump # sub get_mapi_call_sub_handle_idx { my $mapi_call = shift; my $line = shift; my $inout = shift; if ($mapi_call->{marker}->{sub_handles} && $line =~ /handle_idx/) { $line =~ /(0x\w{2})/i; my $idx = $mapi_call->{marker}->{call_idx}; $mapi_call->{calls}->{$inout}->{$idx}->{self_handle_idx} = $1; } } # # Retrieve MAPI calls for a given packet: # - opnum # - handle_idx # - opname # - sub handles # sub get_mapi_calls { my $self = shift; my $mapi_call = shift; my $inout = shift; # Reset the mapi call counter $mapi_call->{marker}->{call_idx} = -1; my @lines = split(/\n/, $self->{output}); foreach my $line (@lines) { chomp($line); get_mapi_call_start($mapi_call, $line, $inout); get_mapi_call_opnum($mapi_call, $line, $inout); get_mapi_call_handle_idx($mapi_call, $line, $inout); get_mapi_call_retval($mapi_call, $line, $inout); get_mapi_call_opname($mapi_call, $line, $inout); get_mapi_call_sub_handle_idx($mapi_call, $line, $inout); } # We do not need anymore the markers delete($mapi_call->{marker}); } # # When checking mapi calls number consistency between in and out, # we have to remove Release calls count from request cause Release # doesn't produce any call in out (until now). # sub get_mapi_calls_request_count { my $_self = shift; my $in = shift; my $counter = keys(%{$in}); foreach my $key (keys(%{$in})) { if (hex($in->{$key}->{opnum}) == 0x1) { $counter--; } } return $counter; } # # Get the call index for a given call in the response # This hack fixes the Release issue # Note: MAPI serialize calls in such way we can predict # the response call index with reasonable confidence # sub get_call_index { my $self = shift; my $mapi_call = shift; my $call_idx = shift; my $in = $mapi_call->{calls}->{REQ}; return $call_idx if (keys(%{$in}) == $self->get_mapi_calls_request_count($in)); # If count mismatches case return $call_idx if ($call_idx == 0); for (my $idx = 0; $idx <= $call_idx; $idx++) { $call_idx-- if (hex($in->{$idx}->{opnum}) == 0x1); } return $call_idx; } # # Analyze EcDoRpc braces output and extract the information # we need to create the object hierarchy # sub analyze { my $self = shift; my $trace_opt = shift; foreach my $key (sort asc_num (keys(%{$self->{ECDORPC}->{braces}}))) { my $in = $self->{ECDORPC}->{braces}->{$key}->{in}; my $out = $self->{ECDORPC}->{braces}->{$key}->{out}; MAPI::Dump_EcDoRpc->dump_brace_start($in, $out) if ($trace_opt); $self->{ECDORPC}->{braces}->{$key}->{mapi_calls} = init_mapi_call(); my $mapi_call = $self->{ECDORPC}->{braces}->{$key}->{mapi_calls}; get_mapi_calls($in, $mapi_call, "REQ"); get_mapi_calls($out, $mapi_call, "REPL"); # Add the request/response handle array in the element hash $self->get_pkt_handles($mapi_call, "REQ", $in->{output}); $self->get_pkt_handles($mapi_call, "REPL", $out->{output}); $self->get_mapi_call_hierarchy($in, $out, $mapi_call, $key); if ($trace_opt) { if (MAPI::Dump_EcDoRpc->dump_mapi_calls($mapi_call)) { $self->delete_brace($key); } else { MAPI::Dump_EcDoRpc->dump_brace_handles($mapi_call); MAPI::Dump_EcDoRpc->dump_brace_end(); } } } } ############################################################ # ANALYZE PART FOR HANDLES ############################################################ # # Get mapi_call hierarchy within a serialized request # # Explanations: # * If the call has a handle_idx set to 0xffffffff but this handle_idx is # already referenced by a previous call in its self_handle_idx field, then # the call is a child of the one with the set_handle_idx # # * In MAPI Semantic, a self handle is unique and can't be set twice # sub get_mapi_call_hierarchy { my $self = shift; my $request = shift; my $response = shift; my $mapi_call = shift; my $key = shift; ## WARNING: This is the nasty hack that should be removed if (!defined $mapi_call->{handles_in} || !defined $mapi_call->{handles_out}) { $self->delete_brace($key); return ; } my @handles_in = @{$mapi_call->{handles_in}}; my @handles_out = @{$mapi_call->{handles_out}}; my $self_handles = {}; my $in = $mapi_call->{calls}->{REQ}; # If we don't have multi calls, no need to go further return if (keys(%{$in}) == 1); # Retrieve calls with self_handle foreach my $key (sort pkt_number keys(%{$in})) { if ($in->{$key}->{self_handle_idx}) { my $self_handle_idx = $in->{$key}->{self_handle_idx}; $self_handles->{$self_handle_idx} = $key; $in->{$key}->{children} = (); } } # If we don't have any self handles, no need to go further return if (keys(%{$in}) == 0); # We now retrieve calls again # check for handle_idx referring handles value 0xffffffff # and check if their handle idx is already indexed in %self_handles # which means it is a child of this call foreach my $key (sort pkt_number keys(%{$in})) { if ($handles_in[hex($in->{$key}->{handle_idx})] && $handles_in[hex($in->{$key}->{handle_idx})] eq "0xffffffff") { my $call_handle_idx = $in->{$key}->{handle_idx}; if (exists $self_handles->{$call_handle_idx}) { my $parent_call_idx = $self_handles->{$call_handle_idx}; $in->{$key}->{parent} = $self_handles->{$call_handle_idx}; push(@{$in->{$parent_call_idx}->{children}}, $key); } } } } ############################################################ # WRAPPER FUNCTIONS ON THE GRAPHVIZ MODULE ############################################################ # # process the call hierarchy and prepare the nodes for graph output # sub graph_calls { my $self = shift; my $g = shift; my $brace_key = shift; my $brace = $self->{ECDORPC}->{braces}->{$brace_key}; my $mapi_call = $brace->{mapi_calls}; return if (!exists $mapi_call->{handles_out}); # Get the request and response handles my @handles_out = @{$mapi_call->{handles_out}}; # Get the request mapi_call serialization hash my $in = $mapi_call->{calls}->{REQ}; # Check if we are in a serialized call # if (@handles_out == 1) { # $g->add_node($mapi_call, 0); # return ; # } # Process the serialized # We first check for self_handle packets only # Next we process self_handle packets with children # Finally we check normal calls foreach my $key (sort asc_num (keys(%{$in}))) { if ($in->{$key}->{self_handle_idx}) { $g->add_node($mapi_call, $key); if (exists $in->{$key}->{children}) { foreach my $call_idx (@{$in->{$key}->{children}}) { $g->add_node($mapi_call, $call_idx); } } } else { $g->add_node($mapi_call, $key); } } } sub graph { my $self = shift; my $dir = shift; my $highlight = shift; my $png = $dir . "/" . $self->get_filename($self->{CONF}->{path}) . ".png"; # mkdir output directory if it doesn't exist mkdir $dir; # my $g = MAPI::Graph_EcDoRpc->new($png); my $g = MAPI::Graph->new($png, $highlight); # Dump the hierarchy $self->graph_calls($g, $_) foreach (sort asc_num (keys(%{$self->{ECDORPC}->{braces}}))); $g->render(); } ############################################################ # WRAPPER FUNCTIONS ON THE STATS MODULE ############################################################ # # Add skipped files # sub add_skipped_file { my $self = shift; my $filename = shift; my $inout = shift; my $count = $self->{SKIPPED_FILES}->{$inout}->{count}; my $files = $self->{SKIPPED_FILES}->{$inout}->{files}; # Initiate and add the new entry $files->{$count} = {}; $files->{$count}->{filename} = $filename; # Increment the counter $self->{SKIPPED_FILES}->{$inout}->{count}++; } # # # sub stats { my $self = shift; $self->{STATISTIC}->scenario(); # print Dumper($self->{SKIPPED_FILES}); } ############################################################ # SEARCH FUNCTIONS PART ############################################################ # # Trace a call through the scenario # sub search_call { my $self = shift; my $callname = shift; my $dump_opt = shift; my $inout = shift; my $search = {}; my $count = 0; my @results = (); my $find_marker = 0; # We loop through mapi calls REQ calls and search for the given call foreach my $brace_key (sort pkt_number keys(%{$self->{ECDORPC}->{braces}})) { my $brace = $self->{ECDORPC}->{braces}->{$brace_key}; foreach my $call_key (sort pkt_number keys(%{$brace->{mapi_calls}->{calls}->{REQ}})) { my $call = $brace->{mapi_calls}->{calls}->{REQ}->{$call_key}; if ($call->{opname} && $call->{opname} eq $callname) { $find_marker = 1; $search->{$count}->{brace_key} = $brace_key; $count++; print $brace->{$inout}->{output} if ($dump_opt && $inout); push(@results, $call->{opname} . ": " . $self->get_filename($brace->{in}->{filename}) . " / " . $self->get_filename($brace->{out}->{filename}) . "\n"); } } } if ($#results >= 0) { print "[X] Call found in [ " . $self->{CONF}->{name} . " ]:\n"; print "\t$_" foreach (@results); } else { print "[O] No call found in [ " . $self->{CONF}->{name} . " ]\n"; } # We are now looking for the call in problematic packets } 1; openchange-2.0/utils/mapitrace/lib/MAPI/Graph.pm000066400000000000000000000154751223057412600215000ustar00rootroot00000000000000################################################## # EcDoRpc GraphViz Dump package for mapitrace tool # Copyright Julien Kerihuel 2007 # # # released under the GNU GPL # package MAPI::Graph; require Exporter; @ISA = qw(Exporter); @EXPORT = qw(); use vars qw($AUTOLOAD $VERSION); $VERSION = '0.01'; use strict; use GraphViz; use Data::Dumper; # # Init the MAPI::Graph object # sub new { my $_self = shift; my $output_file = shift; my $highlight = shift; my $self = {}; $self->{graph} = GraphViz->new(node => {shape => 'box'}); $self->{nodelist} = {}; $self->{output_file} = $output_file; $self->{highlight} = $highlight; bless($self); return $self; } # # Render the graph # sub render { my $self = shift; print "Dumping graph in ." . $self->{output_file} . "\n"; $self->{graph}->as_png($self->{output_file}); } # # Init a new node in the general nodelist hash # A node is a set of queue each of them composed of children # sub node_init { my $self = shift; my $node_id = shift; my $nodelist = $self->{nodelist}; print "[node_init]: Adding node: $node_id\n"; $nodelist->{$node_id} = {}; $nodelist->{$node_id}->{children} = {}; $nodelist->{$node_id}->{count} = 1; @{$nodelist->{$node_id}->{children}->{1}} = (); } # # If a release occur on a node we need to increment # the depth so we can start a new hierarchy # sub add_depth { my $self = shift; my $node_id = shift; my $node = $self->{nodelist}->{$node_id}; $node->{count} += 1; my $count = $node->{count}; $node->{children}->{$count} = (); } # # Get the last child id for the given node_id # sub get_last_nodelist_child { my $self = shift; my $node_id = shift; my $node = $self->{nodelist}->{$node_id}; return 0 if (!$node); my $count = $node->{count}; my $child_id = @{$node->{children}->{$count}}; # If the node doesn't have children return the parent one return $node_id if (!$child_id); # Otherwise return the last child my @hierarchy = @{$node->{children}->{$count}}; $child_id -= 1; my $last_child = $hierarchy[$child_id]; return $last_child; } # # add a child to an existing node in the nodelist hash # sub nodelist_add_child { my $self = shift; my $node_id = shift; # get the node in the hash my $node = $self->{nodelist}->{$node_id}; # get the number of hierarchy array my $count = $node->{count}; # get the number of children for the given hierarchy my $child_count = @{$node->{children}->{$count}}; # we increment the child counter $child_count += 1; my $child_name = "$node_id:$count:$child_count"; print "Adding node: $child_name\n"; push(@{$node->{children}->{$count}}, $child_name); return $child_name; } # # add a node in the general nodelist hash # it can be a node or the child of an existing node # sub nodelist_add { my $self = shift; my $node_id = shift; my $nodelist = $self->{nodelist}; # Add the node directly if not referenced in the nodelist hash if (!exists $nodelist->{$node_id}) { $self->node_init($node_id); return $node_id; } # If the node already exists, add a child for the correct one my $last_child = $self->nodelist_add_child($node_id); return $last_child; } # # Add edge between two nodes # sub add_edge { my $self = shift; my $parent_handle = shift; my $self_handle = shift; my $g = $self->{graph}; # If self_handle exists add an edge between # the last parent's child and the self_handle my $last_child = $self->get_last_nodelist_child($parent_handle); if ($self_handle) { print "[add_edge] $last_child -> $self_handle\n"; $g->add_edge($last_child, $self_handle); } else { # if this is a root element we shouldn't add edge if ($parent_handle ne $last_child) { print "[add_edge] $parent_handle -> $last_child\n"; $g->add_edge($parent_handle, $last_child); } else { print "[add_edge]: no edge for $parent_handle\n"; } } } # # Add a node to the graph # sub add_node { my $self = shift; my $mapi_call = shift; my $key = shift; my $g = $self->{graph}; my $parent_handle = $self->get_parent_handle($mapi_call, $key); my $self_handle = $self->get_self_handle($mapi_call, $key); # If we do not have a self handle if (!$self_handle) { my $last_child = $self->get_last_nodelist_child($parent_handle); my $node_id = $self->nodelist_add($parent_handle); my $label = $self->get_node_label($mapi_call, $key); if ($self->{highlight} && !$self->node_highlight($label)) { print "############ HERE ##############\n"; $g->add_node($node_id, label => $label, style => "filled", color => "green"); } else { $g->add_node($node_id, label => $label); } # If there is already a child, link against it if ($last_child && $last_child ne $parent_handle) { $g->add_edge($last_child => $node_id); } else { # Otherwise, just link it to the parent node $self->add_edge($parent_handle); } } # If we do have a self handle if ($self_handle) { my $node_id = $self->nodelist_add($self_handle); my $label = $self->get_node_label($mapi_call, $key); if ($self->{highlight} && !$self->node_highlight($label)) { print "############ HERE ##############\n"; $g->add_node($node_id, label => $label, style => "filled", color => "green"); } else { $g->add_node($node_id, label => $label); } $self->add_edge($parent_handle, $node_id); } } sub get_node_label { my $self = shift; my $mapi_call = shift; my $key = shift; my $in = $mapi_call->{calls}->{REQ}->{$key}; my $label = ''; $label = sprintf "%s (%s)", $in->{opname}, $in->{opnum}; return $label; } sub node_highlight { my $self = shift; my $label = shift; return -1 if !$self->{highlight}; my $label2 = substr($label, 0, length($self->{highlight})); if ($self->{highlight} eq $label2) { print "WE CAN HIGHLIGHT THE CALL\n"; return 0; } return -1; } ######################################### # HANDLE CONVENIENT FUNCTIONS ######################################### # # get the parent handle (handle_idx field) # sub get_parent_handle { my $self = shift; my $mapi_call = shift; my $key = shift; my $in = $mapi_call->{calls}->{REQ}->{$key}; my @handles = @{$mapi_call->{handles_out}}; my $parent_handle = $in->{handle_idx}; return $handles[hex($parent_handle)]; } # # get the self handle (self_handle_idx field) # sub get_self_handle { my $self = shift; my $mapi_call = shift; my $key = shift; my $in = $mapi_call->{calls}->{REQ}->{$key}; my @handles = @{$mapi_call->{handles_out}}; return 0 if (!exists $in->{self_handle_idx}); my $self_handle = $in->{self_handle_idx}; return $handles[hex($self_handle)]; } openchange-2.0/utils/mapitrace/lib/MAPI/Regression.pm000066400000000000000000000005261223057412600225460ustar00rootroot00000000000000############################################# # EcDoRpc package for mapitrace tool # Copyright Julien Kerihuel 2007 # # # released under the GNU GPL v3 or later # package MAPI::Regression; require Exporter; @ISA = qw(Exporter); @EXPORT = qw(); use vars qw($AUTOLOAD $VERSION); $VERSION = '0.01'; use strict; 1; openchange-2.0/utils/mapitrace/lib/MAPI/Statistic.pm000066400000000000000000000104751223057412600224010ustar00rootroot00000000000000############################################## # EcDoRpc Statistic package for mapitrace tool # Copyright Julien Kerihuel 2007 # # # released under the GNU GPL v3 or later # package MAPI::Statistic; require Exporter; @ISA = qw(Exporter); @EXPORT = qw(); use vars qw($AUTOLOAD $VERSION); $VERSION = '0.01'; use strict; use Data::Dumper; ####################################################### # INIT PART ####################################################### # # Initiate the statistic object # sub new { my $_self = shift; my ($scenario) = shift; my (@files) = @_; my $self = {}; $self->{SCENARIO} = {}; $self->{SCENARIO}->{name} = $scenario; $self->{SCENARIO}->{total} = $#files + 1; $self->{SCENARIO}->{BRACES}->{total} = 0; $self->{SCENARIO}->{BRACES}->{failure} = 0; $self->{SCENARIO}->{REQUEST}->{total} = 0; $self->{SCENARIO}->{REQUEST}->{success} = 0; $self->{SCENARIO}->{REQUEST}->{failure} = 0; $self->{SCENARIO}->{RESPONSE}->{total} = 0; $self->{SCENARIO}->{RESPONSE}->{success} = 0; $self->{SCENARIO}->{RESPONSE}->{failure} = 0; count_total_packets_type($self, @files); $self->{SCENARIO}->{CALLS} = {}; bless($self); return $self; } ####################################################### # COUNT FUNCTION PART ####################################################### # # Count the full number of requests and replies # sub count_total_packets_type { my $self = shift; my (@files) = @_; foreach (@files) { $self->{SCENARIO}->{REQUEST}->{total}++ if ($_ =~ /in/); $self->{SCENARIO}->{RESPONSE}->{total}++ if ($_ =~ /out/); } } # # # sub increment_brace_counter { my $self = shift; $self->{SCENARIO}->{BRACES}->{total}++; } sub increment_brace_error_counter { my $self = shift; $self->{SCENARIO}->{BRACES}->{failure}++; } # # # sub count_packet_inc { my $self = shift; my $inout = shift; my $state = shift; return -1 if (!$state || !$inout); $self->{SCENARIO}->{REQUEST}->{$state}++ if ($inout eq "in"); $self->{SCENARIO}->{RESPONSE}->{$state}++ if ($inout eq "out"); } # # Accessors # sub success_request_counter { my $self = shift; $self->increment_counter("REQUEST", "success"); } sub failure_request_counter { my $self = shift; $self->increment_counter("REQUEST", "failure"); } sub success_response_counter { my $self = shift; $self->increment_counter("RESPONSE", "success"); } sub failure_response_counter { my $self = shift; $self->increment_counter("RESPONSE", "failure"); } sub increment_counter { my $self = shift; my $type = shift; my $case = shift; $self->{SCENARIO}->{$type}->{$case}++; } ####################################################### # DUMP PART ####################################################### sub percent { my $obj = shift; my $type = shift; return ($obj->{$type}->{total} / $obj->{total}) * 100; } sub scenario { my $self = shift; my $request_percent = percent($self->{SCENARIO}, "REQUEST"); my $response_percent = percent($self->{SCENARIO}, "RESPONSE"); print "+-----[ Scenario: " . $self->{SCENARIO}->{name} . " ]-----+\n"; print "[statistic]: We have " . $self->{SCENARIO}->{total} . " packets "; print "(request: " . $request_percent . "%, "; print "response: " . $response_percent . "%)\n"; my $success_req_rate = ($self->{SCENARIO}->{REQUEST}->{success} / $self->{SCENARIO}->{REQUEST}->{total}) * 100; my $success_repl_rate = ($self->{SCENARIO}->{RESPONSE}->{success} / $self->{SCENARIO}->{RESPONSE}->{total}) * 100; print "[statistic]: request success rate: " . $success_req_rate . "\n"; print "[statistic]: response success rate: " . $success_repl_rate . "\n"; my $braces_count = $self->{SCENARIO}->{BRACES}->{total}; my $braces_failure = $self->{SCENARIO}->{BRACES}->{failure}; if ($braces_failure) { print "[statistic]: success brace analysis rate: " . ((1 - ($braces_failure/$braces_count)) * 100) . "\n"; print "[statistic]: braces skipped: " . $braces_failure . "/" . $braces_count . "\n"; } else { print "[statistic]: success brace analysis rate: 100%\n"; print "[statistic]: no braces skipped\n"; } print "+--------------------------------------------------------------+\n"; } sub dump { my $self = shift; } 1; openchange-2.0/utils/mapitrace/mapitrace000077500000000000000000000054511223057412600204710ustar00rootroot00000000000000#!/usr/bin/perl -w ############################################## # package to dump the mapi call hierarchy and # add IDL regression support # # Copyright Julien Kerihuel 2007. # # # released under GNU GPL v3 or later use strict; use FindBin qw($RealBin $Script); use lib "$RealBin"; use lib "$RealBin/lib"; #use lib "lib"; use MAPI::EcDoRpc; use Getopt::Long; my ($opt_help) = 0; my ($opt_outputdir) = '.'; my ($opt_graph) = 0; my ($opt_highlight) = 0; my ($opt_trace) = 0; my ($opt_search_call) = 0; my ($opt_dump_call) = 0; my ($opt_inout) = 0; my ($opt_error) = 0; my ($opt_stats) = 0; my ($opt_verbose) = 0; ############################################ # display help text sub ShowHelp() { print "mapi call hierarchy tracing tool and IDL regression support Copyright (C) Julien Kerihuel Usage: $Script [options] Generic Options: --help this help page --outputdir=OUTDIR put output in OUTDIR/ [] --graph create a png graph --trace dump the mapi call hierarchy on command line --verbose verbose output Tracing Options: --search-call=CALL trace a single call through a scenario --dump-call dump all the packets containing the call specified --highlight=CALL highlight a call in the generated graph --inout=INOUT filter either requests (in) or response (out) Regression Options: --error_report=in,out Investigate invalid packets --stats Display statistics for a given scenario \n"; exit (0); } # main program my $result = GetOptions ( 'help|h|?' => \$opt_help, 'outputdir=s' => \$opt_outputdir, 'graph|g' => \$opt_graph, 'highlight=s'=> \$opt_highlight, 'trace|t' => \$opt_trace, 'search-call=s' => \$opt_search_call, 'dump-call|d' => \$opt_dump_call, 'inout=s' => \$opt_inout, 'error_report=s' => \$opt_error, 'stats|s' => \$opt_stats, 'verbose|v' => \$opt_verbose ); if (not $result) { exit (1); } if ($opt_help) { ShowHelp(); exit (0); } sub process_tracing($) { my $directory = shift; my $outputdir = $opt_outputdir; opendir(DIR,$directory) or die "Unable to process $directory"; closedir(DIR); my $EcDoRpc = MAPI::EcDoRpc->new($directory, $outputdir, $opt_verbose); $EcDoRpc->ndrdump(); $EcDoRpc->analyze($opt_trace); if ($opt_error) { my @inout = split(/,/, $opt_error); foreach (sort @inout) { $EcDoRpc->error_report($_); } } $EcDoRpc->stats() if ($opt_stats); $EcDoRpc->search_call($opt_search_call, $opt_dump_call, $opt_inout) if ($opt_search_call); $EcDoRpc->graph($outputdir, $opt_highlight) if ($opt_graph); } if (scalar(@ARGV) == 0) { print "$Script: no input directory\n"; exit (1); } process_tracing($_) foreach (@ARGV); openchange-2.0/utils/openchange-tools.c000066400000000000000000000217751223057412600202510ustar00rootroot00000000000000/* Convenient functions for openchange tools OpenChange Project Copyright (C) Julien Kerihuel 2007-2013 This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see . */ #include "libmapi/libmapi.h" #include "openchange-tools.h" static void popt_openchange_version_callback(poptContext con, enum poptCallbackReason reason, const struct poptOption *opt, const char *arg, const void *data) { switch (opt->val) { case 'V': printf("Version %s\n", OPENCHANGE_VERSION_STRING); exit (0); } } struct poptOption popt_openchange_version[] = { { NULL, '\0', POPT_ARG_CALLBACK, (void *)popt_openchange_version_callback, '\0', NULL, NULL }, { "version", 'V', POPT_ARG_NONE, NULL, 'V', "Print version ", NULL }, POPT_TABLEEND }; /* * Retrieve the property value for a given SRow and property tag. * * If the property type is a string: fetch PT_UNICODE then PT_STRING8 * in case the desired property is not available in first choice. * * Fetch property normally for any others properties */ _PUBLIC_ void *octool_get_propval(struct SRow *aRow, uint32_t proptag) { const char *str; if (((proptag & 0xFFFF) == PT_STRING8) || ((proptag & 0xFFFF) == PT_UNICODE)) { proptag = (proptag & 0xFFFF0000) | PT_UNICODE; str = (const char *) find_SPropValue_data(aRow, proptag); if (str) return (void *)str; proptag = (proptag & 0xFFFF0000) | PT_STRING8; str = (const char *) find_SPropValue_data(aRow, proptag); return (void *)str; } return (void *)find_SPropValue_data(aRow, proptag); } /* * Read a stream and store it in a DATA_BLOB */ _PUBLIC_ enum MAPISTATUS octool_get_stream(TALLOC_CTX *mem_ctx, mapi_object_t *obj_stream, DATA_BLOB *body) { enum MAPISTATUS retval; uint16_t read_size; uint8_t buf[0x1000]; body->length = 0; body->data = talloc_zero(mem_ctx, uint8_t); do { retval = ReadStream(obj_stream, buf, 0x1000, &read_size); MAPI_RETVAL_IF(retval, GetLastError(), body->data); if (read_size) { body->data = talloc_realloc(mem_ctx, body->data, uint8_t, body->length + read_size); memcpy(&(body->data[body->length]), buf, read_size); body->length += read_size; } } while (read_size); errno = 0; return MAPI_E_SUCCESS; } /* * Fetch the body given PR_MSG_EDITOR_FORMAT property value */ _PUBLIC_ enum MAPISTATUS octool_get_body(TALLOC_CTX *mem_ctx, mapi_object_t *obj_message, struct SRow *aRow, DATA_BLOB *body) { enum MAPISTATUS retval; const struct SBinary_short *bin; mapi_object_t obj_stream; char *data; uint8_t format; /* Sanity checks */ MAPI_RETVAL_IF(!obj_message, MAPI_E_INVALID_PARAMETER, NULL); /* initialize body DATA_BLOB */ body->data = NULL; body->length = 0; retval = GetBestBody(obj_message, &format); MAPI_RETVAL_IF(retval, retval, NULL); switch (format) { case olEditorText: data = octool_get_propval(aRow, PR_BODY_UNICODE); if (data) { body->data = talloc_memdup(mem_ctx, data, strlen(data)); body->length = strlen(data); } else { mapi_object_init(&obj_stream); retval = OpenStream(obj_message, PR_BODY_UNICODE, 0, &obj_stream); MAPI_RETVAL_IF(retval, GetLastError(), NULL); retval = octool_get_stream(mem_ctx, &obj_stream, body); MAPI_RETVAL_IF(retval, GetLastError(), NULL); mapi_object_release(&obj_stream); } break; case olEditorHTML: bin = (const struct SBinary_short *) octool_get_propval(aRow, PR_HTML); if (bin) { body->data = talloc_memdup(mem_ctx, bin->lpb, bin->cb); body->length = bin->cb; } else { mapi_object_init(&obj_stream); retval = OpenStream(obj_message, PR_HTML, 0, &obj_stream); MAPI_RETVAL_IF(retval, GetLastError(), NULL); retval = octool_get_stream(mem_ctx, &obj_stream, body); MAPI_RETVAL_IF(retval, GetLastError(), NULL); mapi_object_release(&obj_stream); } break; case olEditorRTF: mapi_object_init(&obj_stream); retval = OpenStream(obj_message, PR_RTF_COMPRESSED, 0, &obj_stream); MAPI_RETVAL_IF(retval, GetLastError(), NULL); retval = WrapCompressedRTFStream(&obj_stream, body); MAPI_RETVAL_IF(retval, GetLastError(), NULL); mapi_object_release(&obj_stream); break; default: DEBUG(0, ("Undefined Body\n")); break; } return MAPI_E_SUCCESS; } /* * Optimized dump message routine (use GetProps rather than GetPropsAll) */ _PUBLIC_ enum MAPISTATUS octool_message(TALLOC_CTX *mem_ctx, mapi_object_t *obj_message) { enum MAPISTATUS retval; struct SPropTagArray *SPropTagArray; struct SPropValue *lpProps; struct SRow aRow; uint32_t count; /* common email fields */ const char *msgid; const char *from, *to, *cc, *bcc; const char *subject; DATA_BLOB body; const uint8_t *has_attach; const uint32_t *cp; const char *codepage; /* Build the array of properties we want to fetch */ SPropTagArray = set_SPropTagArray(mem_ctx, 0x13, PR_INTERNET_MESSAGE_ID, PR_INTERNET_MESSAGE_ID_UNICODE, PR_CONVERSATION_TOPIC, PR_CONVERSATION_TOPIC_UNICODE, PR_MSG_EDITOR_FORMAT, PR_BODY_UNICODE, PR_HTML, PR_RTF_IN_SYNC, PR_RTF_COMPRESSED, PR_SENT_REPRESENTING_NAME, PR_SENT_REPRESENTING_NAME_UNICODE, PR_DISPLAY_TO, PR_DISPLAY_TO_UNICODE, PR_DISPLAY_CC, PR_DISPLAY_CC_UNICODE, PR_DISPLAY_BCC, PR_DISPLAY_BCC_UNICODE, PR_HASATTACH, PR_MESSAGE_CODEPAGE); lpProps = NULL; retval = GetProps(obj_message, MAPI_UNICODE, SPropTagArray, &lpProps, &count); MAPIFreeBuffer(SPropTagArray); MAPI_RETVAL_IF(retval, retval, NULL); /* Build a SRow structure */ aRow.ulAdrEntryPad = 0; aRow.cValues = count; aRow.lpProps = lpProps; msgid = (const char *) octool_get_propval(&aRow, PR_INTERNET_MESSAGE_ID); subject = (const char *) octool_get_propval(&aRow, PR_CONVERSATION_TOPIC); retval = octool_get_body(mem_ctx, obj_message, &aRow, &body); if (retval != MAPI_E_SUCCESS) { printf("Invalid Message: %s\n", msgid ? msgid : ""); return GetLastError(); } from = (const char *) octool_get_propval(&aRow, PR_SENT_REPRESENTING_NAME); to = (const char *) octool_get_propval(&aRow, PR_DISPLAY_TO_UNICODE); cc = (const char *) octool_get_propval(&aRow, PR_DISPLAY_CC_UNICODE); bcc = (const char *) octool_get_propval(&aRow, PR_DISPLAY_BCC_UNICODE); has_attach = (const uint8_t *) octool_get_propval(&aRow, PR_HASATTACH); cp = (const uint32_t *) octool_get_propval(&aRow, PR_MESSAGE_CODEPAGE); switch (cp ? *cp : 0) { case CP_USASCII: codepage = "CP_USASCII"; break; case CP_UNICODE: codepage = "CP_UNICODE"; break; case CP_JAUTODETECT: codepage = "CP_JAUTODETECT"; break; case CP_KAUTODETECT: codepage = "CP_KAUTODETECT"; break; case CP_ISO2022JPESC: codepage = "CP_ISO2022JPESC"; break; case CP_ISO2022JPSIO: codepage = "CP_ISO2022JPSIO"; break; default: codepage = ""; break; } printf("+-------------------------------------+\n"); printf("message id: %s\n", msgid ? msgid : ""); printf("subject: %s\n", subject ? subject : ""); printf("From: %s\n", from ? from : ""); printf("To: %s\n", to ? to : ""); printf("Cc: %s\n", cc ? cc : ""); printf("Bcc: %s\n", bcc ? bcc : ""); if (has_attach) { printf("Attachment: %s\n", *has_attach ? "True" : "False"); } printf("Codepage: %s\n", codepage); printf("Body:\n"); fflush(0); if (body.length) { write(1, body.data, body.length); write(1, "\n", 1); fflush(0); talloc_free(body.data); } return MAPI_E_SUCCESS; } /* * OpenChange MAPI programs initialization routine */ _PUBLIC_ struct mapi_session *octool_init_mapi(struct mapi_context *mapi_ctx, const char *opt_profname, const char *opt_password, uint32_t provider) { enum MAPISTATUS retval; char *profname = NULL; struct mapi_session *session = NULL; TALLOC_CTX *mem_ctx = NULL; mem_ctx = talloc_named(NULL, 0, "octool_init_mapi"); if (opt_profname) { profname = talloc_strdup(mem_ctx, (char *)opt_profname); } else { retval = GetDefaultProfile(mapi_ctx, &profname); if (retval != MAPI_E_SUCCESS) { mapi_errstr("GetDefaultProfile", GetLastError()); talloc_free(mem_ctx); return NULL; } } if (!provider) { retval = MapiLogonEx(mapi_ctx, &session, profname, opt_password); } else { retval = MapiLogonProvider(mapi_ctx, &session, profname, opt_password, provider); } MAPIFreeBuffer((char *)profname); if (retval != MAPI_E_SUCCESS) { mapi_errstr("MapiLogonEx", GetLastError()); talloc_free(mem_ctx); return NULL; } talloc_free(mem_ctx); return session; } openchange-2.0/utils/openchange-tools.h000066400000000000000000000040061223057412600202420ustar00rootroot00000000000000/* OpenChange Tools includes OpenChange Project Copyright (C) Julien Kerihuel 2007 This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see . */ #ifndef __OPENCHANGETOOLS_H__ #define __OPENCHANGETOOLS_H__ #include #define DEFAULT_PROFDB "%s/.openchange/profiles.ldb" #define DEFAULT_TDB "%s/.openchange/index.tdb" #define DEFAULT_MBOX "%s/.openchange/mbox" #define DEFAULT_ICAL "%s/.openchange/ical" #define DEFAULT_VCF "%s/.openchange/vcf" #define DEFAULT_DIR "%s/.openchange" #ifndef __BEGIN_DECLS #ifdef __cplusplus #define __BEGIN_DECLS extern "C" { #define __END_DECLS } #else #define __BEGIN_DECLS #define __END_DECLS #endif #endif /* Common popt structures for tool */ extern struct poptOption popt_openchange_version[]; #define POPT_OPENCHANGE_VERSION { NULL, 0, POPT_ARG_INCLUDE_TABLE, popt_openchange_version, 0, "Common openchange options:", NULL }, #ifndef _PUBLIC_ #define _PUBLIC_ #endif __BEGIN_DECLS _PUBLIC_ enum MAPISTATUS octool_message(TALLOC_CTX *, mapi_object_t *); _PUBLIC_ void *octool_get_propval(struct SRow *, uint32_t); _PUBLIC_ enum MAPISTATUS octool_get_body(TALLOC_CTX *, mapi_object_t *, struct SRow *, DATA_BLOB *); _PUBLIC_ enum MAPISTATUS octool_get_stream(TALLOC_CTX *mem_ctx, mapi_object_t *obj_stream, DATA_BLOB *body); _PUBLIC_ struct mapi_session *octool_init_mapi(struct mapi_context *, const char *, const char *, uint32_t); __END_DECLS #endif /*!__OPENCHANGETOOLS_H__ */ openchange-2.0/utils/openchangeclient.c000066400000000000000000003153071223057412600203070ustar00rootroot00000000000000/* Stand-alone MAPI application OpenChange Project Copyright (C) Julien Kerihuel 2007-2013 This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see . */ #include "libmapi/libmapi.h" #include "libmapi/libmapi_private.h" #include "libmapi/mapi_nameid.h" #include "libocpf/ocpf.h" #include #include #include "openchangeclient.h" #include "openchange-tools.h" #include #include #include #include #include #include /** * init sendmail struct */ static void init_oclient(struct oclient *oclient) { oclient->mapi_ctx = NULL; /* update and delete parameter */ oclient->update = NULL; oclient->delete = NULL; /* properties list */ oclient->props = NULL; /* email related parameter */ oclient->subject = NULL; oclient->pr_body = NULL; oclient->pr_html_inline = NULL; oclient->attach = NULL; oclient->attach_num = 0; oclient->store_folder = NULL; /* appointment related parameters */ oclient->location = NULL; oclient->dtstart = NULL; oclient->dtend = NULL; oclient->busystatus = -1; oclient->label = -1; oclient->private = false; oclient->freebusy = NULL; oclient->force = false; oclient->summary = false; /* contact related parameters */ oclient->email = NULL; oclient->full_name = NULL; oclient->card_name = NULL; /* task related parameters */ oclient->importance = -1; oclient->taskstatus = -1; /* note related parameters */ oclient->color = -1; oclient->width = -1; oclient->height = -1; /* pf related parameters */ oclient->pf = false; /* folder related parameters */ oclient->folder = NULL; oclient->folder_name = NULL; oclient->folder_comment = NULL; /* ocpf related parameters */ oclient->ocpf_files = NULL; oclient->ocpf_dump = NULL; } static enum MAPISTATUS openchangeclient_getdir(TALLOC_CTX *mem_ctx, mapi_object_t *obj_container, mapi_object_t *obj_child, const char *path) { enum MAPISTATUS retval; struct SPropTagArray *SPropTagArray = NULL; struct SRowSet SRowSet; mapi_object_t obj_htable; mapi_object_t obj_folder; char **folder = NULL; const char *name; const uint64_t *fid; bool found = false; uint32_t index; uint32_t i; /* Step 1. Extract the folder list from full path */ folder = str_list_make(mem_ctx, path, "/"); mapi_object_copy(&obj_folder, obj_container); for (i = 0; folder[i]; i++) { found = false; mapi_object_init(&obj_htable); retval = GetHierarchyTable(&obj_folder, &obj_htable, 0, NULL); MAPI_RETVAL_IF(retval, GetLastError(), folder); SPropTagArray = set_SPropTagArray(mem_ctx, 0x2, PR_DISPLAY_NAME_UNICODE, PR_FID); retval = SetColumns(&obj_htable, SPropTagArray); MAPIFreeBuffer(SPropTagArray); MAPI_RETVAL_IF(retval, retval, folder); while (((retval = QueryRows(&obj_htable, 0x32, TBL_ADVANCE, &SRowSet)) != MAPI_E_NOT_FOUND) && SRowSet.cRows) { for (index = 0; (index < SRowSet.cRows) && (found == false); index++) { fid = (const uint64_t *)find_SPropValue_data(&SRowSet.aRow[index], PR_FID); name = (const char *)find_SPropValue_data(&SRowSet.aRow[index], PR_DISPLAY_NAME_UNICODE); if (name && fid && !strcmp(name, folder[i])) { retval = OpenFolder(&obj_folder, *fid, obj_child); MAPI_RETVAL_IF(retval, retval, folder); found = true; mapi_object_copy(&obj_folder, obj_child); } } } mapi_object_release(&obj_htable); } talloc_free(folder); MAPI_RETVAL_IF(found == false, MAPI_E_NOT_FOUND, NULL); return MAPI_E_SUCCESS; } static enum MAPISTATUS openchangeclient_getpfdir(TALLOC_CTX *mem_ctx, mapi_object_t *obj_store, mapi_object_t *obj_child, const char *name) { enum MAPISTATUS retval; mapi_object_t obj_pf; mapi_id_t id_pf; retval = GetDefaultPublicFolder(obj_store, &id_pf, olFolderPublicIPMSubtree); if (retval != MAPI_E_SUCCESS) return retval; mapi_object_init(&obj_pf); retval = OpenFolder(obj_store, id_pf, &obj_pf); if (retval != MAPI_E_SUCCESS) return retval; retval = openchangeclient_getdir(mem_ctx, &obj_pf, obj_child, name); if (retval != MAPI_E_SUCCESS) return retval; return MAPI_E_SUCCESS; } /** * read a file and store it in the appropriate structure element */ static bool oclient_read_file(TALLOC_CTX *mem_ctx, const char *filename, struct oclient *oclient, uint32_t mapitag) { struct stat sb; int fd; if ((fd = open(filename, O_RDONLY)) == -1) { printf("Error while opening %s\n", filename); return false; } /* stat the file */ if (fstat(fd, &sb) != 0) { close(fd); return false; } switch (mapitag) { case PR_HTML: oclient->pr_html.lpb = talloc_size(mem_ctx, sb.st_size); oclient->pr_html.cb = read(fd, oclient->pr_html.lpb, sb.st_size); close(fd); break; case PR_ATTACH_DATA_BIN: oclient->attach[oclient->attach_num].filename = talloc_strdup(mem_ctx, filename); oclient->attach[oclient->attach_num].bin.lpb = talloc_size(mem_ctx, sb.st_size); oclient->attach[oclient->attach_num].bin.cb = sb.st_size; if ((oclient->attach[oclient->attach_num].bin.lpb = mmap(NULL, sb.st_size, PROT_READ, MAP_SHARED, fd, 0)) == (void *) -1) { perror("mmap"); close(fd); return false; } oclient->attach[oclient->attach_num].fd = fd; printf("filename = %s (size = %u / %u)\n", filename, oclient->attach[oclient->attach_num].bin.cb, (uint32_t)sb.st_size); close(fd); break; default: printf("unsupported MAPITAG: %s\n", get_proptag_name(mapitag)); close(fd); return false; break; } return true; } /** * Parse attachments and load their content */ static bool oclient_parse_attachments(TALLOC_CTX *mem_ctx, const char *filename, struct oclient *oclient) { char **filenames; char *tmp = NULL; uint32_t j; if ((tmp = strtok((char *)filename, ";")) == NULL) { printf("Invalid string format [;]\n"); return false; } filenames = talloc_array(mem_ctx, char *, 2); filenames[0] = strdup(tmp); for (j = 1; (tmp = strtok(NULL, ";")) != NULL; j++) { filenames = talloc_realloc(mem_ctx, filenames, char *, j+2); filenames[j] = strdup(tmp); } filenames[j] = 0; oclient->attach = talloc_array(mem_ctx, struct attach, j); for (j = 0; filenames[j]; j++) { oclient->attach_num = j; if (oclient_read_file(mem_ctx, filenames[j], oclient, PR_ATTACH_DATA_BIN) == false) { return false; } } return true; } static const char *get_filename(const char *filename) { const char *substr; if (!filename) return NULL; substr = rindex(filename, '/'); if (substr) return substr + 1; return filename; } /** * build unique ID from folder and message */ static char *build_uniqueID(TALLOC_CTX *mem_ctx, mapi_object_t *obj_folder, mapi_object_t *obj_message) { char *id; struct SPropTagArray *SPropTagArray; struct SPropValue *lpProps; uint32_t count; const uint64_t *mid; const uint64_t *fid; /* retrieve the folder ID */ SPropTagArray = set_SPropTagArray(mem_ctx, 0x1, PR_FID); GetProps(obj_folder, 0, SPropTagArray, &lpProps, &count); MAPIFreeBuffer(SPropTagArray); if (GetLastError() != MAPI_E_SUCCESS) return NULL; fid = (const uint64_t *)get_SPropValue_data(lpProps); /* retrieve the message ID */ SPropTagArray = set_SPropTagArray(mem_ctx, 0x1, PR_MID); GetProps(obj_message, 0, SPropTagArray, &lpProps, &count); MAPIFreeBuffer(SPropTagArray); if (GetLastError() != MAPI_E_SUCCESS) return NULL; mid = (const uint64_t *)get_SPropValue_data(lpProps); if (!fid || !mid) return NULL; id = talloc_asprintf(mem_ctx, "%"PRIX64"/%"PRIX64, *fid, *mid); return id; } /** * fetch the user INBOX */ #define MAX_READ_SIZE 0x1000 static bool store_attachment(mapi_object_t obj_attach, const char *filename, uint32_t size, struct oclient *oclient) { TALLOC_CTX *mem_ctx; bool ret = true; enum MAPISTATUS retval; char *path; mapi_object_t obj_stream; uint16_t read_size; int fd; DIR *dir; unsigned char buf[MAX_READ_SIZE]; if (!filename || !size) return false; mapi_object_init(&obj_stream); mem_ctx = talloc_named(NULL, 0, "store_attachment"); if (!(dir = opendir(oclient->store_folder))) { if (mkdir(oclient->store_folder, 0700) == -1) { ret = false; goto error_close; } } else { closedir(dir); } path = talloc_asprintf(mem_ctx, "%s/%s", oclient->store_folder, filename); if ((fd = open(path, O_CREAT|O_WRONLY, S_IWUSR|S_IRUSR)) == -1) { ret = false; talloc_free(path); goto error_close; } talloc_free(path); retval = OpenStream(&obj_attach, PR_ATTACH_DATA_BIN, 0, &obj_stream); if (retval != MAPI_E_SUCCESS) { ret = false; goto error; } read_size = 0; do { retval = ReadStream(&obj_stream, buf, MAX_READ_SIZE, &read_size); if (retval != MAPI_E_SUCCESS) { ret = false; goto error; } write(fd, buf, read_size); } while (read_size); error: close(fd); error_close: mapi_object_release(&obj_stream); talloc_free(mem_ctx); return ret; } static enum MAPISTATUS openchangeclient_fetchmail(mapi_object_t *obj_store, struct oclient *oclient) { enum MAPISTATUS retval; bool status; TALLOC_CTX *mem_ctx; mapi_object_t obj_tis; mapi_object_t obj_inbox; mapi_object_t obj_message; mapi_object_t obj_table; mapi_object_t obj_tb_attach; mapi_object_t obj_attach; uint64_t id_inbox; struct SPropTagArray *SPropTagArray; struct SRowSet rowset; struct SRowSet rowset_attach; uint32_t i, j; uint32_t count; const uint8_t *has_attach; const uint32_t *attach_num; const char *attach_filename; const uint32_t *attach_size; mem_ctx = talloc_named(NULL, 0, "openchangeclient_fetchmail"); mapi_object_init(&obj_tis); mapi_object_init(&obj_inbox); mapi_object_init(&obj_table); if (oclient->pf == true) { retval = openchangeclient_getpfdir(mem_ctx, obj_store, &obj_inbox, oclient->folder); MAPI_RETVAL_IF(retval, GetLastError(), mem_ctx); } else { if (oclient->folder) { retval = GetDefaultFolder(obj_store, &id_inbox, olFolderTopInformationStore); MAPI_RETVAL_IF(retval, retval, mem_ctx); retval = OpenFolder(obj_store, id_inbox, &obj_tis); MAPI_RETVAL_IF(retval, retval, mem_ctx); retval = openchangeclient_getdir(mem_ctx, &obj_tis, &obj_inbox, oclient->folder); MAPI_RETVAL_IF(retval, retval, mem_ctx); } else { retval = GetReceiveFolder(obj_store, &id_inbox, NULL); MAPI_RETVAL_IF(retval, retval, mem_ctx); retval = OpenFolder(obj_store, id_inbox, &obj_inbox); MAPI_RETVAL_IF(retval, retval, mem_ctx); } } retval = GetContentsTable(&obj_inbox, &obj_table, 0, &count); MAPI_RETVAL_IF(retval, retval, mem_ctx); printf("MAILBOX (%u messages)\n", count); if (!count) goto end; SPropTagArray = set_SPropTagArray(mem_ctx, 0x5, PR_FID, PR_MID, PR_INST_ID, PR_INSTANCE_NUM, PR_SUBJECT_UNICODE); retval = SetColumns(&obj_table, SPropTagArray); MAPIFreeBuffer(SPropTagArray); MAPI_RETVAL_IF(retval, retval, mem_ctx); while ((retval = QueryRows(&obj_table, count, TBL_ADVANCE, &rowset)) != MAPI_E_NOT_FOUND && rowset.cRows) { count -= rowset.cRows; for (i = 0; i < rowset.cRows; i++) { mapi_object_init(&obj_message); retval = OpenMessage(obj_store, rowset.aRow[i].lpProps[0].value.d, rowset.aRow[i].lpProps[1].value.d, &obj_message, 0); if (GetLastError() == MAPI_E_SUCCESS) { if (oclient->summary) { mapidump_message_summary(&obj_message); } else { struct SPropValue *lpProps; struct SRow aRow; SPropTagArray = set_SPropTagArray(mem_ctx, 0x1, PR_HASATTACH); lpProps = NULL; retval = GetProps(&obj_message, 0, SPropTagArray, &lpProps, &count); MAPIFreeBuffer(SPropTagArray); if (retval != MAPI_E_SUCCESS) return retval; aRow.ulAdrEntryPad = 0; aRow.cValues = count; aRow.lpProps = lpProps; retval = octool_message(mem_ctx, &obj_message); has_attach = (const uint8_t *) get_SPropValue_SRow_data(&aRow, PR_HASATTACH); /* If we have attachments, retrieve them */ if (has_attach && *has_attach) { mapi_object_init(&obj_tb_attach); retval = GetAttachmentTable(&obj_message, &obj_tb_attach); if (retval == MAPI_E_SUCCESS) { SPropTagArray = set_SPropTagArray(mem_ctx, 0x1, PR_ATTACH_NUM); retval = SetColumns(&obj_tb_attach, SPropTagArray); if (retval != MAPI_E_SUCCESS) return retval; MAPIFreeBuffer(SPropTagArray); retval = QueryRows(&obj_tb_attach, 0xa, TBL_ADVANCE, &rowset_attach); if (retval != MAPI_E_SUCCESS) return retval; for (j = 0; j < rowset_attach.cRows; j++) { attach_num = (const uint32_t *)find_SPropValue_data(&(rowset_attach.aRow[j]), PR_ATTACH_NUM); retval = OpenAttach(&obj_message, *attach_num, &obj_attach); if (retval == MAPI_E_SUCCESS) { struct SPropValue *lpProps2; uint32_t count2; SPropTagArray = set_SPropTagArray(mem_ctx, 0x4, PR_ATTACH_FILENAME, PR_ATTACH_LONG_FILENAME, PR_ATTACH_SIZE, PR_ATTACH_CONTENT_ID); lpProps2 = NULL; retval = GetProps(&obj_attach, MAPI_UNICODE, SPropTagArray, &lpProps2, &count2); MAPIFreeBuffer(SPropTagArray); if (retval != MAPI_E_SUCCESS) return retval; aRow.ulAdrEntryPad = 0; aRow.cValues = count2; aRow.lpProps = lpProps2; attach_filename = get_filename(octool_get_propval(&aRow, PR_ATTACH_LONG_FILENAME)); if (!attach_filename || (attach_filename && !strcmp(attach_filename, ""))) { attach_filename = get_filename(octool_get_propval(&aRow, PR_ATTACH_FILENAME)); } attach_size = (const uint32_t *) octool_get_propval(&aRow, PR_ATTACH_SIZE); printf("[%u] %s (%u Bytes)\n", j, attach_filename, attach_size ? *attach_size : 0); fflush(0); if (oclient->store_folder) { status = store_attachment(obj_attach, attach_filename, attach_size ? *attach_size : 0, oclient); if (status == false) { printf("A Problem was encountered while storing attachments on the filesystem\n"); talloc_free(mem_ctx); return MAPI_E_UNABLE_TO_COMPLETE; } } MAPIFreeBuffer(lpProps2); } } errno = 0; } MAPIFreeBuffer(lpProps); } } } mapi_object_release(&obj_message); } } end: mapi_object_release(&obj_table); mapi_object_release(&obj_inbox); mapi_object_release(&obj_tis); talloc_free(mem_ctx); errno = 0; return MAPI_E_SUCCESS; } /** * send a mail to a user whom belongs to the Exchange organization */ static char **get_cmdline_recipients(TALLOC_CTX *mem_ctx, const char *recipients) { char **usernames; char *tmp = NULL; uint32_t j = 0; /* no recipients */ if (!recipients) { return NULL; } if ((tmp = strtok((char *)recipients, ",")) == NULL) { DEBUG(2, ("Invalid recipient string format\n")); return NULL; } usernames = talloc_array(mem_ctx, char *, 2); usernames[0] = strdup(tmp); for (j = 1; (tmp = strtok(NULL, ",")) != NULL; j++) { usernames = talloc_realloc(mem_ctx, usernames, char *, j+2); usernames[j] = strdup(tmp); } usernames[j] = 0; return (usernames); } /** * We set external recipients at the end of aRow */ static bool set_external_recipients(TALLOC_CTX *mem_ctx, struct SRowSet *SRowSet, const char *username, enum ulRecipClass RecipClass) { uint32_t last; struct SPropValue SPropValue; SRowSet->aRow = talloc_realloc(mem_ctx, SRowSet->aRow, struct SRow, SRowSet->cRows + 1); last = SRowSet->cRows; SRowSet->aRow[last].cValues = 0; SRowSet->aRow[last].lpProps = talloc_zero(mem_ctx, struct SPropValue); /* PR_OBJECT_TYPE */ SPropValue.ulPropTag = PR_OBJECT_TYPE; SPropValue.value.l = MAPI_MAILUSER; SRow_addprop(&(SRowSet->aRow[last]), SPropValue); /* PR_DISPLAY_TYPE */ SPropValue.ulPropTag = PR_DISPLAY_TYPE; SPropValue.value.l = 0; SRow_addprop(&(SRowSet->aRow[last]), SPropValue); /* PR_GIVEN_NAME */ SPropValue.ulPropTag = PR_GIVEN_NAME_UNICODE; SPropValue.value.lpszA = username; SRow_addprop(&(SRowSet->aRow[last]), SPropValue); /* PR_DISPLAY_NAME */ SPropValue.ulPropTag = PR_DISPLAY_NAME_UNICODE; SPropValue.value.lpszA = username; SRow_addprop(&(SRowSet->aRow[last]), SPropValue); /* PR_7BIT_DISPLAY_NAME */ SPropValue.ulPropTag = PR_7BIT_DISPLAY_NAME_UNICODE; SPropValue.value.lpszA = username; SRow_addprop(&(SRowSet->aRow[last]), SPropValue); /* PR_SMTP_ADDRESS */ SPropValue.ulPropTag = PR_SMTP_ADDRESS_UNICODE; SPropValue.value.lpszA = username; SRow_addprop(&(SRowSet->aRow[last]), SPropValue); /* PR_ADDRTYPE */ SPropValue.ulPropTag = PR_ADDRTYPE_UNICODE; SPropValue.value.lpszA = "SMTP"; SRow_addprop(&(SRowSet->aRow[last]), SPropValue); SetRecipientType(&(SRowSet->aRow[last]), RecipClass); SRowSet->cRows += 1; return true; } static bool set_usernames_RecipientType(TALLOC_CTX *mem_ctx, uint32_t *index, struct SRowSet *rowset, char **usernames, struct PropertyTagArray_r *flaglist, enum ulRecipClass RecipClass) { uint32_t i; uint32_t count = *index; static uint32_t counter = 0; if (count == 0) counter = 0; if (!usernames) return false; for (i = 0; usernames[i]; i++) { if (flaglist->aulPropTag[count] == MAPI_UNRESOLVED) { set_external_recipients(mem_ctx, rowset, usernames[i], RecipClass); } if (flaglist->aulPropTag[count] == MAPI_RESOLVED) { SetRecipientType(&(rowset->aRow[counter]), RecipClass); counter++; } count++; } *index = count; return true; } static char **collapse_recipients(TALLOC_CTX *mem_ctx, struct oclient *oclient) { uint32_t count; uint32_t i; char **usernames; if (!oclient->mapi_to && !oclient->mapi_cc && !oclient->mapi_bcc) return NULL; count = 0; for (i = 0; oclient->mapi_to && oclient->mapi_to[i]; i++, count++); for (i = 0; oclient->mapi_cc && oclient->mapi_cc[i]; i++, count++); for (i = 0; oclient->mapi_bcc && oclient->mapi_bcc[i]; i++, count++); usernames = talloc_array(mem_ctx, char *, count + 1); count = 0; for (i = 0; oclient->mapi_to && oclient->mapi_to[i]; i++, count++) { usernames[count] = talloc_strdup(mem_ctx, oclient->mapi_to[i]); } for (i = 0; oclient->mapi_cc && oclient->mapi_cc[i]; i++, count++) { usernames[count] = talloc_strdup(mem_ctx, oclient->mapi_cc[i]); } for (i = 0; oclient->mapi_bcc && oclient->mapi_bcc[i]; i++, count++) { usernames[count] = talloc_strdup(mem_ctx, oclient->mapi_bcc[i]); } usernames[count++] = 0; return usernames; } /** * Write a stream with MAX_READ_SIZE chunks */ #define MAX_READ_SIZE 0x1000 static bool openchangeclient_stream(TALLOC_CTX *mem_ctx, mapi_object_t obj_parent, mapi_object_t obj_stream, uint32_t mapitag, uint32_t access_flags, struct Binary_r bin) { enum MAPISTATUS retval; DATA_BLOB stream; uint32_t size; uint32_t offset; uint16_t read_size; /* Open a stream on the parent for the given property */ retval = OpenStream(&obj_parent, mapitag, access_flags, &obj_stream); fprintf (stderr, "openstream: retval = %s (0x%.8x)\n", mapi_get_errstr (retval), retval); if (retval != MAPI_E_SUCCESS) return false; /* WriteStream operation */ printf("We are about to write %u bytes in the stream\n", bin.cb); size = MAX_READ_SIZE; offset = 0; while (offset <= bin.cb) { stream.length = size; stream.data = talloc_size(mem_ctx, size); memcpy(stream.data, bin.lpb + offset, size); retval = WriteStream(&obj_stream, &stream, &read_size); talloc_free(stream.data); if (retval != MAPI_E_SUCCESS) return false; printf("."); fflush(0); /* Exit when there is nothing left to write */ if (!read_size) { mapi_object_release(&obj_stream); return true; } offset += read_size; if ((offset + size) > bin.cb) { size = bin.cb - offset; } } mapi_object_release(&obj_stream); return true; } #define SETPROPS_COUNT 4 /** * Send a mail */ static enum MAPISTATUS openchangeclient_sendmail(TALLOC_CTX *mem_ctx, mapi_object_t *obj_store, struct oclient *oclient) { enum MAPISTATUS retval; struct SPropTagArray *SPropTagArray; struct SPropValue SPropValue; struct SRowSet *SRowSet = NULL; struct PropertyRowSet_r *RowSet = NULL; struct PropertyTagArray_r *flaglist = NULL; mapi_id_t id_outbox; mapi_object_t obj_outbox; mapi_object_t obj_message; mapi_object_t obj_stream; uint32_t index = 0; uint32_t msgflag; struct SPropValue props[SETPROPS_COUNT]; uint32_t prop_count = 0; uint32_t editor = 0; mapi_object_init(&obj_outbox); mapi_object_init(&obj_message); if (oclient->pf == true) { retval = openchangeclient_getpfdir(mem_ctx, obj_store, &obj_outbox, oclient->folder); if (retval != MAPI_E_SUCCESS) return retval; } else { /* Get Sent Items folder but should be using olFolderOutbox */ retval = GetDefaultFolder(obj_store, &id_outbox, olFolderOutbox); if (retval != MAPI_E_SUCCESS) return retval; /* Open outbox folder */ retval = OpenFolder(obj_store, id_outbox, &obj_outbox); if (retval != MAPI_E_SUCCESS) return retval; } /* Create the message */ retval = CreateMessage(&obj_outbox, &obj_message); if (retval != MAPI_E_SUCCESS) return retval; /* Recipients operations */ SPropTagArray = set_SPropTagArray(mem_ctx, 0xA, PR_ENTRYID, PR_DISPLAY_NAME_UNICODE, PR_OBJECT_TYPE, PR_DISPLAY_TYPE, PR_TRANSMITTABLE_DISPLAY_NAME_UNICODE, PR_EMAIL_ADDRESS_UNICODE, PR_ADDRTYPE_UNICODE, PR_SEND_RICH_INFO, PR_7BIT_DISPLAY_NAME_UNICODE, PR_SMTP_ADDRESS_UNICODE); oclient->usernames = collapse_recipients(mem_ctx, oclient); /* ResolveNames */ retval = ResolveNames(mapi_object_get_session(&obj_message), (const char **)oclient->usernames, SPropTagArray, &RowSet, &flaglist, MAPI_UNICODE); MAPIFreeBuffer(SPropTagArray); if (retval != MAPI_E_SUCCESS) return retval; SRowSet = talloc_zero(mem_ctx, struct SRowSet); if (RowSet) { cast_PropertyRowSet_to_SRowSet(mem_ctx, RowSet, SRowSet); } set_usernames_RecipientType(mem_ctx, &index, SRowSet, oclient->mapi_to, flaglist, MAPI_TO); set_usernames_RecipientType(mem_ctx, &index, SRowSet, oclient->mapi_cc, flaglist, MAPI_CC); set_usernames_RecipientType(mem_ctx, &index, SRowSet, oclient->mapi_bcc, flaglist, MAPI_BCC); SPropValue.ulPropTag = PR_SEND_INTERNET_ENCODING; SPropValue.value.l = 0; SRowSet_propcpy(mem_ctx, SRowSet, SPropValue); /* ModifyRecipients operation */ retval = ModifyRecipients(&obj_message, SRowSet); MAPIFreeBuffer(SRowSet); MAPIFreeBuffer(flaglist); if (retval != MAPI_E_SUCCESS) return retval; /* set message properties */ msgflag = MSGFLAG_UNSENT; oclient->subject = (!oclient->subject) ? "" : oclient->subject; set_SPropValue_proptag(&props[0], PR_SUBJECT_UNICODE, (const void *)oclient->subject); set_SPropValue_proptag(&props[1], PR_MESSAGE_FLAGS, (const void *)&msgflag); prop_count = 2; /* Set PR_BODY or PR_HTML or inline PR_HTML */ if (oclient->pr_body) { editor = EDITOR_FORMAT_PLAINTEXT; set_SPropValue_proptag(&props[3], PR_MSG_EDITOR_FORMAT, (const void *)&editor); if (strlen(oclient->pr_body) > MAX_READ_SIZE) { struct Binary_r bin; bin.lpb = (uint8_t *)oclient->pr_body; bin.cb = strlen(oclient->pr_body); openchangeclient_stream(mem_ctx, obj_message, obj_stream, PR_BODY, 2, bin); } else { set_SPropValue_proptag(&props[2], PR_BODY_UNICODE, (const void *)oclient->pr_body); prop_count++; } } else if (oclient->pr_html_inline) { editor = EDITOR_FORMAT_HTML; set_SPropValue_proptag(&props[3], PR_MSG_EDITOR_FORMAT, (const void *)&editor); if (strlen(oclient->pr_html_inline) > MAX_READ_SIZE) { struct Binary_r bin; bin.lpb = (uint8_t *)oclient->pr_html_inline; bin.cb = strlen(oclient->pr_html_inline); openchangeclient_stream(mem_ctx, obj_message, obj_stream, PR_HTML, 2, bin); } else { struct SBinary_short bin; bin.cb = strlen(oclient->pr_html_inline); bin.lpb = (uint8_t *)oclient->pr_html_inline; set_SPropValue_proptag(&props[2], PR_HTML, (void *)&bin); prop_count++; } } else if (&oclient->pr_html) { editor = EDITOR_FORMAT_HTML; set_SPropValue_proptag(&props[3], PR_MSG_EDITOR_FORMAT, (const void *)&editor); if (oclient->pr_html.cb <= MAX_READ_SIZE) { struct SBinary_short bin; bin.cb = oclient->pr_html.cb; bin.lpb = oclient->pr_html.lpb; set_SPropValue_proptag(&props[2], PR_HTML, (void *)&bin); prop_count++; } else { mapi_object_init(&obj_stream); openchangeclient_stream(mem_ctx, obj_message, obj_stream, PR_HTML, 2, oclient->pr_html); } } retval = SetProps(&obj_message, 0, props, prop_count); if (retval != MAPI_E_SUCCESS) return retval; /* attachment related code */ if (oclient->attach) { uint32_t i; for (i = 0; oclient->attach[i].filename; i++) { mapi_object_t obj_attach; mapi_object_t obj_stream; struct SPropValue props_attach[4]; uint32_t count_props_attach; mapi_object_init(&obj_attach); retval = CreateAttach(&obj_message, &obj_attach); if (retval != MAPI_E_SUCCESS) return retval; props_attach[0].ulPropTag = PR_ATTACH_METHOD; props_attach[0].value.l = ATTACH_BY_VALUE; props_attach[1].ulPropTag = PR_RENDERING_POSITION; props_attach[1].value.l = 0; props_attach[2].ulPropTag = PR_ATTACH_FILENAME; printf("Sending %s:\n", oclient->attach[i].filename); props_attach[2].value.lpszA = get_filename(oclient->attach[i].filename); props_attach[3].ulPropTag = PR_ATTACH_CONTENT_ID; props_attach[3].value.lpszA = get_filename(oclient->attach[i].filename); count_props_attach = 4; /* SetProps */ retval = SetProps(&obj_attach, 0, props_attach, count_props_attach); if (retval != MAPI_E_SUCCESS) return retval; /* Stream operations */ mapi_object_init(&obj_stream); openchangeclient_stream(mem_ctx, obj_attach, obj_stream, PR_ATTACH_DATA_BIN, 2, oclient->attach[i].bin); /* Save changes on attachment */ retval = SaveChangesAttachment(&obj_message, &obj_attach, KeepOpenReadWrite); if (retval != MAPI_E_SUCCESS) return retval; mapi_object_release(&obj_attach); } } if (oclient->pf) { retval = SaveChangesMessage(&obj_outbox, &obj_message, KeepOpenReadOnly); if (retval != MAPI_E_SUCCESS) return retval; } else { /* Submit the message */ retval = SubmitMessage(&obj_message); if (retval != MAPI_E_SUCCESS) return retval; } mapi_object_release(&obj_message); mapi_object_release(&obj_outbox); return MAPI_E_SUCCESS; } /** * delete a mail from user INBOX */ static bool openchangeclient_deletemail(TALLOC_CTX *mem_ctx, mapi_object_t *obj_store, struct oclient *oclient) { enum MAPISTATUS retval; struct SPropTagArray *SPropTagArray; struct SRowSet SRowSet; mapi_id_t id_inbox; mapi_id_t *id_messages; uint32_t count_messages; uint32_t count_rows; mapi_object_t obj_inbox; mapi_object_t obj_table; uint32_t len; uint32_t i; if (!oclient->subject) { printf("You need to specify at least a message subject pattern\n"); MAPI_RETVAL_IF(!oclient->subject, MAPI_E_INVALID_PARAMETER, NULL); } mapi_object_init(&obj_inbox); mapi_object_init(&obj_table); if (oclient->pf == true) { retval = openchangeclient_getpfdir(mem_ctx, obj_store, &obj_inbox, oclient->folder); if (retval != MAPI_E_SUCCESS) return retval; } else { retval = GetReceiveFolder(obj_store, &id_inbox, NULL); if (retval != MAPI_E_SUCCESS) return false; retval = OpenFolder(obj_store, id_inbox, &obj_inbox); if (retval != MAPI_E_SUCCESS) return false; } retval = GetContentsTable(&obj_inbox, &obj_table, 0, NULL); if (retval != MAPI_E_SUCCESS) return false; SPropTagArray = set_SPropTagArray(mem_ctx, 0x5, PR_FID, PR_MID, PR_INST_ID, PR_INSTANCE_NUM, PR_SUBJECT_UNICODE); retval = SetColumns(&obj_table, SPropTagArray); if (retval != MAPI_E_SUCCESS) return false; while ((retval = QueryRows(&obj_table, 0x10, TBL_ADVANCE, &SRowSet)) == MAPI_E_SUCCESS) { count_rows = SRowSet.cRows; if (!count_rows) break; id_messages = talloc_array(mem_ctx, uint64_t, count_rows); count_messages = 0; len = strlen(oclient->subject); for (i = 0; i < count_rows; i++) { if (!strncmp(SRowSet.aRow[i].lpProps[4].value.lpszA, oclient->subject, len)) { id_messages[count_messages] = SRowSet.aRow[i].lpProps[1].value.d; count_messages++; } } if (count_messages) { retval = DeleteMessage(&obj_inbox, id_messages, count_messages); if (retval != MAPI_E_SUCCESS) return false; } } mapi_object_release(&obj_table); mapi_object_release(&obj_inbox); return true; } static enum MAPISTATUS check_conflict_date(struct oclient *oclient, mapi_object_t *obj, struct FILETIME *ft) { enum MAPISTATUS retval; mapi_object_t obj_store; struct mapi_session *session; struct mapi_session *session2; bool conflict; session = mapi_object_get_session(obj); retval = MapiLogonEx(oclient->mapi_ctx, &session2, session->profile->profname, session->profile->password); MAPI_RETVAL_IF(retval, retval, NULL); mapi_object_init(&obj_store); retval = OpenPublicFolder(session2, &obj_store); MAPI_RETVAL_IF(retval, retval, NULL); retval = IsFreeBusyConflict(&obj_store, ft, &conflict); Logoff(&obj_store); if (conflict == true) { printf("[WARNING]: This start date conflicts with another appointment\n"); return MAPI_E_INVALID_PARAMETER; } return MAPI_E_SUCCESS; } /** * Send appointment */ static enum MAPISTATUS appointment_SetProps(TALLOC_CTX *mem_ctx, mapi_object_t *obj_folder, mapi_object_t *obj_message, struct oclient *oclient) { enum MAPISTATUS retval; struct SPropValue *lpProps; struct FILETIME *start_date; struct FILETIME *end_date; uint32_t cValues = 0; NTTIME nt; struct tm tm; uint32_t flag; uint8_t flag2; cValues = 0; lpProps = talloc_array(mem_ctx, struct SPropValue, 2); if (oclient->subject) { lpProps = add_SPropValue(mem_ctx, lpProps, &cValues, PR_CONVERSATION_TOPIC_UNICODE, (const void *) oclient->subject); lpProps = add_SPropValue(mem_ctx, lpProps, &cValues, PR_NORMALIZED_SUBJECT_UNICODE, (const void *) oclient->subject); } if (oclient->pr_body) { lpProps = add_SPropValue(mem_ctx, lpProps, &cValues, PR_BODY_UNICODE, (const void *)oclient->pr_body); } if (oclient->location) { lpProps = add_SPropValue(mem_ctx, lpProps, &cValues, PidLidLocation, (const void *)oclient->location); } if (oclient->dtstart) { if (!strptime(oclient->dtstart, DATE_FORMAT, &tm)) { printf("Invalid date format: yyyy-mm-dd hh:mm:ss (e.g.: 2007-09-17 10:00:00)\n"); return MAPI_E_INVALID_PARAMETER; } unix_to_nt_time(&nt, mktime(&tm)); start_date = talloc(mem_ctx, struct FILETIME); start_date->dwLowDateTime = (nt << 32) >> 32; start_date->dwHighDateTime = (nt >> 32); retval = check_conflict_date(oclient, obj_folder, start_date); if (oclient->force == false) { MAPI_RETVAL_IF(retval, retval, NULL); } lpProps = add_SPropValue(mem_ctx, lpProps, &cValues, PR_START_DATE, (const void *)start_date); lpProps = add_SPropValue(mem_ctx, lpProps, &cValues, PidLidCommonStart, (const void *)start_date); lpProps = add_SPropValue(mem_ctx, lpProps, &cValues, PidLidAppointmentStartWhole, (const void *) start_date); } if (oclient->dtend) { if (!strptime(oclient->dtend, DATE_FORMAT, &tm)) { printf("Invalid date format: yyyy-mm-dd hh:mm:ss (e.g.:2007-09-17 18:30:00)\n"); return MAPI_E_INVALID_PARAMETER; } unix_to_nt_time(&nt, mktime(&tm)); end_date = talloc(mem_ctx, struct FILETIME); end_date->dwLowDateTime = (nt << 32) >> 32; end_date->dwHighDateTime = (nt >> 32); retval = check_conflict_date(oclient, obj_folder, end_date); if (oclient->force == false) { MAPI_RETVAL_IF(retval, retval, NULL); } lpProps = add_SPropValue(mem_ctx, lpProps, &cValues, PR_END_DATE, (const void *) end_date); lpProps = add_SPropValue(mem_ctx, lpProps, &cValues, PidLidCommonEnd, (const void *) end_date); lpProps = add_SPropValue(mem_ctx, lpProps, &cValues, PidLidAppointmentEndWhole, (const void *) end_date); } if (!oclient->update) { lpProps = add_SPropValue(mem_ctx, lpProps, &cValues, PR_MESSAGE_CLASS_UNICODE, (const void *)"IPM.Appointment"); flag = 1; lpProps = add_SPropValue(mem_ctx, lpProps, &cValues, PR_MESSAGE_FLAGS, (const void *)&flag); flag= MEETING_STATUS_NONMEETING; lpProps = add_SPropValue(mem_ctx, lpProps, &cValues, PidLidAppointmentStateFlags, (const void *) &flag); flag = 30; lpProps = add_SPropValue(mem_ctx, lpProps, &cValues, PidLidReminderDelta, (const void *)&flag); /* WARNING needs to replace private */ flag2 = oclient->private; lpProps = add_SPropValue(mem_ctx, lpProps, &cValues, PidLidPrivate, (const void *)&flag2); oclient->label = (oclient->label == -1) ? 0 : oclient->label; lpProps = add_SPropValue(mem_ctx, lpProps, &cValues, PidLidAppointmentColor, (const void *) &oclient->label); oclient->busystatus = (oclient->busystatus == -1) ? 0 : oclient->busystatus; lpProps = add_SPropValue(mem_ctx, lpProps, &cValues, PidLidBusyStatus, (const void *) &oclient->busystatus); } else { if (oclient->busystatus != -1) { lpProps = add_SPropValue(mem_ctx, lpProps, &cValues, PidLidBusyStatus, (const void *) &oclient->busystatus); } if (oclient->label != -1) { lpProps = add_SPropValue(mem_ctx, lpProps, &cValues, PidLidAppointmentColor, (const void *) &oclient->label); } } flag = (oclient->private == true) ? 2 : 0; lpProps = add_SPropValue(mem_ctx, lpProps, &cValues, PR_SENSITIVITY, (const void *)&flag); retval = SetProps(obj_message, 0, lpProps, cValues); MAPIFreeBuffer(lpProps); MAPI_RETVAL_IF(retval, retval, NULL); return MAPI_E_SUCCESS; } static bool openchangeclient_sendappointment(TALLOC_CTX *mem_ctx, mapi_object_t *obj_store, struct oclient *oclient) { enum MAPISTATUS retval; mapi_object_t obj_calendar; mapi_object_t obj_message; mapi_id_t id_calendar; char *uniq_id; mapi_object_init(&obj_calendar); if (oclient->pf == true) { retval = openchangeclient_getpfdir(mem_ctx, obj_store, &obj_calendar, oclient->folder); if (retval != MAPI_E_SUCCESS) return false; } else { /* Open Calendar default folder */ retval = GetDefaultFolder(obj_store, &id_calendar, olFolderCalendar); if (retval != MAPI_E_SUCCESS) return false; retval = OpenFolder(obj_store, id_calendar, &obj_calendar); if (retval != MAPI_E_SUCCESS) return false; } /* Create calendar message */ mapi_object_init(&obj_message); retval = CreateMessage(&obj_calendar, &obj_message); if (retval != MAPI_E_SUCCESS) return false; /* Set calendar message properties */ retval = appointment_SetProps(mem_ctx, &obj_calendar, &obj_message, oclient); if (retval != MAPI_E_SUCCESS) return false; retval = SaveChangesMessage(&obj_calendar, &obj_message, KeepOpenReadOnly); if (retval != MAPI_E_SUCCESS) return false; /* Fetch and Display the message unique ID */ uniq_id = build_uniqueID(mem_ctx, &obj_calendar, &obj_message); printf(" %-25s: %s\n", "Unique ID", uniq_id); fflush(0); talloc_free(uniq_id); mapi_object_release(&obj_message); mapi_object_release(&obj_calendar); return true; } /** * Create a contact */ static enum MAPISTATUS contact_SetProps(TALLOC_CTX *mem_ctx, mapi_object_t *obj_folder, mapi_object_t *obj_message, struct oclient *oclient) { enum MAPISTATUS retval; struct SPropValue *lpProps; struct mapi_nameid *nameid; struct SPropTagArray *SPropTagArray; uint32_t cValues = 0; /* Build the list of named properties we want to set */ nameid = mapi_nameid_new(mem_ctx); retval = mapi_nameid_string_add(nameid, "urn:schemas:contacts:fileas", PS_PUBLIC_STRINGS); if (retval != MAPI_E_SUCCESS) { talloc_free(nameid); return retval; } /* GetIDsFromNames and map property types */ SPropTagArray = talloc_zero(mem_ctx, struct SPropTagArray); retval = GetIDsFromNames(obj_folder, nameid->count, nameid->nameid, 0, &SPropTagArray); if (retval != MAPI_E_SUCCESS) { talloc_free(nameid); return retval; } mapi_nameid_SPropTagArray(nameid, SPropTagArray); MAPIFreeBuffer(nameid); cValues = 0; lpProps = talloc_array(mem_ctx, struct SPropValue, 2); if (oclient->card_name) { lpProps = add_SPropValue(mem_ctx, lpProps, &cValues, PR_NORMALIZED_SUBJECT_UNICODE, (const void *)oclient->card_name); lpProps = add_SPropValue(mem_ctx, lpProps, &cValues, PidLidFileUnder, (const void *)oclient->card_name); lpProps = add_SPropValue(mem_ctx, lpProps, &cValues, SPropTagArray->aulPropTag[0], (const void *)oclient->card_name); } if (oclient->full_name) { lpProps = add_SPropValue(mem_ctx, lpProps, &cValues, PR_DISPLAY_NAME_UNICODE, (const void *)oclient->full_name); } if (oclient->email) { lpProps = add_SPropValue(mem_ctx, lpProps, &cValues, PidLidEmail1OriginalDisplayName, (const void *)oclient->email); lpProps = add_SPropValue(mem_ctx, lpProps, &cValues, PidLidEmail1EmailAddress, (const void *)oclient->email); } if (!oclient->update) { lpProps = add_SPropValue(mem_ctx, lpProps, &cValues, PR_MESSAGE_CLASS_UNICODE, (const void *)"IPM.Contact"); } retval = SetProps(obj_message, 0, lpProps, cValues); MAPIFreeBuffer(SPropTagArray); MAPIFreeBuffer(lpProps); MAPI_RETVAL_IF(retval, retval, NULL); return MAPI_E_SUCCESS; } static bool openchangeclient_sendcontact(TALLOC_CTX *mem_ctx, mapi_object_t *obj_store, struct oclient *oclient) { enum MAPISTATUS retval; mapi_object_t obj_contact; mapi_object_t obj_message; mapi_id_t id_contact; char *uniq_id; mapi_object_init(&obj_contact); if (oclient->pf == true) { retval = openchangeclient_getpfdir(mem_ctx, obj_store, &obj_contact, oclient->folder); if (retval != MAPI_E_SUCCESS) return retval; } else { /* Open Contact default folder */ retval = GetDefaultFolder(obj_store, &id_contact, olFolderContacts); if (retval != MAPI_E_SUCCESS) return false; retval = OpenFolder(obj_store, id_contact, &obj_contact); if (retval != MAPI_E_SUCCESS) return false; } /* Create contact message */ mapi_object_init(&obj_message); retval = CreateMessage(&obj_contact, &obj_message); if (retval != MAPI_E_SUCCESS) return false; /* Set contact message properties */ retval = contact_SetProps(mem_ctx, &obj_contact, &obj_message, oclient); if (retval != MAPI_E_SUCCESS) return false; retval = SaveChangesMessage(&obj_contact, &obj_message, KeepOpenReadOnly); if (retval != MAPI_E_SUCCESS) return false; /* Fetch and Display the message unique ID */ uniq_id = build_uniqueID(mem_ctx, &obj_contact, &obj_message); printf(" %-25s: %s\n", "Unique ID", uniq_id); fflush(0); talloc_free(uniq_id); mapi_object_release(&obj_message); mapi_object_release(&obj_contact); return true; } /** * Create task */ static enum MAPISTATUS task_SetProps(TALLOC_CTX *mem_ctx, mapi_object_t *obj_message, struct oclient *oclient) { enum MAPISTATUS retval; struct SPropValue *lpProps; struct FILETIME *start_date; struct FILETIME *end_date; uint32_t cValues = 0; NTTIME nt; struct tm tm; cValues = 0; lpProps = talloc_array(mem_ctx, struct SPropValue, 2); if (oclient->card_name) { lpProps = add_SPropValue(mem_ctx, lpProps, &cValues, PR_CONVERSATION_TOPIC_UNICODE, (const void *)oclient->card_name); lpProps = add_SPropValue(mem_ctx, lpProps, &cValues, PR_NORMALIZED_SUBJECT_UNICODE, (const void *)oclient->card_name); } if (oclient->dtstart) { if (!strptime(oclient->dtstart, DATE_FORMAT, &tm)) { printf("Invalid date format (e.g.: 2007-06-01 22:30:00)\n"); return MAPI_E_INVALID_PARAMETER; } unix_to_nt_time(&nt, mktime(&tm)); start_date = talloc(mem_ctx, struct FILETIME); start_date->dwLowDateTime = (nt << 32) >> 32; start_date->dwHighDateTime = (nt >> 32); lpProps = add_SPropValue(mem_ctx, lpProps, &cValues, PidLidTaskStartDate, (const void *)start_date); } if (oclient->dtend) { if (!strptime(oclient->dtend, DATE_FORMAT, &tm)) { printf("Invalid date format (e.g.: 2007-06-01 22:30:00)\n"); return MAPI_E_INVALID_PARAMETER; } unix_to_nt_time(&nt, mktime(&tm)); end_date = talloc(mem_ctx, struct FILETIME); end_date->dwLowDateTime = (nt << 32) >> 32; end_date->dwHighDateTime = (nt >> 32); lpProps = add_SPropValue(mem_ctx, lpProps, &cValues, PidLidTaskDueDate, (const void *)end_date); } if (oclient->pr_body) { lpProps = add_SPropValue(mem_ctx, lpProps, &cValues, PR_BODY_UNICODE, (const void *)oclient->pr_body); } if (!oclient->update) { lpProps = add_SPropValue(mem_ctx, lpProps, &cValues, PR_MESSAGE_CLASS_UNICODE, (const void *)"IPM.Task"); oclient->importance = (oclient->importance == -1) ? 1 : oclient->importance; lpProps = add_SPropValue(mem_ctx, lpProps, &cValues, PR_IMPORTANCE, (const void *)&oclient->importance); oclient->taskstatus = (oclient->taskstatus == -1) ? 0 : oclient->taskstatus; lpProps = add_SPropValue(mem_ctx, lpProps, &cValues, PidLidTaskStatus, (const void *)&oclient->taskstatus); } else { if (oclient->importance != -1) { lpProps = add_SPropValue(mem_ctx, lpProps, &cValues, PR_IMPORTANCE, (const void *)&oclient->importance); } if (oclient->taskstatus != -1) { lpProps = add_SPropValue(mem_ctx, lpProps, &cValues, PidLidTaskStatus, (const void *)&oclient->taskstatus); } } retval = SetProps(obj_message, 0, lpProps, cValues); MAPIFreeBuffer(lpProps); MAPI_RETVAL_IF(retval, retval, NULL); return MAPI_E_SUCCESS; } static bool openchangeclient_sendtask(TALLOC_CTX *mem_ctx, mapi_object_t *obj_store, struct oclient *oclient) { enum MAPISTATUS retval; mapi_object_t obj_task; mapi_object_t obj_message; mapi_id_t id_task; char *uniq_id; mapi_object_init(&obj_task); if (oclient->pf == true) { retval = openchangeclient_getpfdir(mem_ctx, obj_store, &obj_task, oclient->folder); if (retval != MAPI_E_SUCCESS) return retval; } else { /* Open Contact default folder */ retval = GetDefaultFolder(obj_store, &id_task, olFolderTasks); if (retval != MAPI_E_SUCCESS) return false; retval = OpenFolder(obj_store, id_task, &obj_task); if (retval != MAPI_E_SUCCESS) return false; } /* Create contact message */ mapi_object_init(&obj_message); retval = CreateMessage(&obj_task, &obj_message); if (retval != MAPI_E_SUCCESS) return false; /* Set contact properties */ retval = task_SetProps(mem_ctx, &obj_message, oclient); retval = SaveChangesMessage(&obj_task, &obj_message, KeepOpenReadOnly); if (retval != MAPI_E_SUCCESS) return false; /* Fetch and Display the message unique ID */ uniq_id = build_uniqueID(mem_ctx, &obj_task, &obj_message); printf(" %-25s: %s\n", "Unique ID", uniq_id); fflush(0); talloc_free(uniq_id); mapi_object_release(&obj_message); mapi_object_release(&obj_task); return true; } /** * Send notes */ static enum MAPISTATUS note_SetProps(TALLOC_CTX *mem_ctx, mapi_object_t *obj_message, struct oclient *oclient) { enum MAPISTATUS retval; struct SPropValue *lpProps; uint32_t cValues = 0; uint32_t value; cValues = 0; lpProps = talloc_array(mem_ctx, struct SPropValue, 2); if (oclient->card_name) { lpProps = add_SPropValue(mem_ctx, lpProps, &cValues, PR_CONVERSATION_TOPIC_UNICODE, (const void *)oclient->card_name); lpProps = add_SPropValue(mem_ctx, lpProps, &cValues, PR_SUBJECT_UNICODE, (const void *)oclient->card_name); lpProps = add_SPropValue(mem_ctx, lpProps, &cValues, PR_NORMALIZED_SUBJECT_UNICODE, (const void *)oclient->card_name); lpProps = add_SPropValue(mem_ctx, lpProps, &cValues, PR_BODY_UNICODE, (const void *)oclient->card_name); } if (!oclient->update) { lpProps = add_SPropValue(mem_ctx, lpProps, &cValues, PR_MESSAGE_CLASS_UNICODE, (const void *)"IPM.StickyNote"); value = 1; lpProps = add_SPropValue(mem_ctx, lpProps, &cValues, PR_MESSAGE_FLAGS, (const void *)&value); value = 768; lpProps = add_SPropValue(mem_ctx, lpProps, &cValues, PR_ICON_INDEX, (const void *)&value); value = 272; lpProps = add_SPropValue(mem_ctx, lpProps, &cValues, PidLidSideEffects, (const void *)&value); oclient->color = (oclient->color == -1) ? olYellow : oclient->color; lpProps = add_SPropValue(mem_ctx, lpProps, &cValues, PidLidNoteColor, (const void *)&oclient->color); oclient->width = (oclient->width == -1) ? 166 : oclient->width; lpProps = add_SPropValue(mem_ctx, lpProps, &cValues, PidLidNoteWidth, (const void *)&oclient->width); oclient->height = (oclient->height == -1) ? 200 : oclient->height; lpProps = add_SPropValue(mem_ctx, lpProps, &cValues, PidLidNoteHeight, (const void *)&oclient->height); } else { if (oclient->color != -1) { lpProps = add_SPropValue(mem_ctx, lpProps, &cValues, PidLidNoteColor, (const void *)&oclient->color); } if (oclient->width != -1) { lpProps = add_SPropValue(mem_ctx, lpProps, &cValues, PidLidNoteWidth, (const void *)&oclient->width); } if (oclient->height != -1) { lpProps = add_SPropValue(mem_ctx, lpProps, &cValues, PidLidNoteHeight, (const void *)&oclient->height); } } retval = SetProps(obj_message, 0, lpProps, cValues); MAPIFreeBuffer(lpProps); MAPI_RETVAL_IF(retval, retval, NULL); return MAPI_E_SUCCESS; } static bool openchangeclient_sendnote(TALLOC_CTX *mem_ctx, mapi_object_t *obj_store, struct oclient *oclient) { enum MAPISTATUS retval; mapi_object_t obj_note; mapi_object_t obj_message; mapi_id_t id_note; char *uniq_id; mapi_object_init(&obj_note); if (oclient->pf == true) { retval = openchangeclient_getpfdir(mem_ctx, obj_store, &obj_note, oclient->folder); if (retval != MAPI_E_SUCCESS) return retval; } else { /* Open Contact default folder */ retval = GetDefaultFolder(obj_store, &id_note, olFolderNotes); if (retval != MAPI_E_SUCCESS) return false; retval = OpenFolder(obj_store, id_note, &obj_note); if (retval != MAPI_E_SUCCESS) return false; } /* Create contact message */ mapi_object_init(&obj_message); retval = CreateMessage(&obj_note, &obj_message); if (retval != MAPI_E_SUCCESS) return false; /* Set Note message properties */ retval = note_SetProps(mem_ctx, &obj_message, oclient); if (retval != MAPI_E_SUCCESS) return false; retval = SaveChangesMessage(&obj_note, &obj_message, KeepOpenReadOnly); if (retval != MAPI_E_SUCCESS) return false; /* Fetch and Display the message unique ID */ uniq_id = build_uniqueID(mem_ctx, &obj_note, &obj_message); printf(" %-25s: %s\n", "Unique ID", uniq_id); fflush(0); talloc_free(uniq_id); mapi_object_release(&obj_message); mapi_object_release(&obj_note); return true; } static const char *get_container_class(TALLOC_CTX *mem_ctx, mapi_object_t *parent, mapi_id_t folder_id) { enum MAPISTATUS retval; mapi_object_t obj_folder; struct SPropTagArray *SPropTagArray; struct SPropValue *lpProps; uint32_t count; mapi_object_init(&obj_folder); retval = OpenFolder(parent, folder_id, &obj_folder); if (retval != MAPI_E_SUCCESS) return false; SPropTagArray = set_SPropTagArray(mem_ctx, 0x1, PR_CONTAINER_CLASS); retval = GetProps(&obj_folder, MAPI_UNICODE, SPropTagArray, &lpProps, &count); MAPIFreeBuffer(SPropTagArray); mapi_object_release(&obj_folder); if ((lpProps[0].ulPropTag != PR_CONTAINER_CLASS) || (retval != MAPI_E_SUCCESS)) { errno = 0; return IPF_NOTE; } return lpProps[0].value.lpszA; } static bool get_child_folders(TALLOC_CTX *mem_ctx, mapi_object_t *parent, mapi_id_t folder_id, int count) { enum MAPISTATUS retval; bool ret; mapi_object_t obj_folder; mapi_object_t obj_htable; struct SPropTagArray *SPropTagArray; struct SRowSet rowset; const char *name; const char *comment; const uint32_t *total; const uint32_t *unread; const uint32_t *child; uint32_t index; const uint64_t *fid; int i; mapi_object_init(&obj_folder); retval = OpenFolder(parent, folder_id, &obj_folder); if (retval != MAPI_E_SUCCESS) return false; mapi_object_init(&obj_htable); retval = GetHierarchyTable(&obj_folder, &obj_htable, 0, NULL); if (retval != MAPI_E_SUCCESS) return false; SPropTagArray = set_SPropTagArray(mem_ctx, 0x6, PR_DISPLAY_NAME_UNICODE, PR_FID, PR_COMMENT_UNICODE, PR_CONTENT_UNREAD, PR_CONTENT_COUNT, PR_FOLDER_CHILD_COUNT); retval = SetColumns(&obj_htable, SPropTagArray); MAPIFreeBuffer(SPropTagArray); if (retval != MAPI_E_SUCCESS) return false; while (((retval = QueryRows(&obj_htable, 0x32, TBL_ADVANCE, &rowset)) != MAPI_E_NOT_FOUND) && rowset.cRows) { for (index = 0; index < rowset.cRows; index++) { fid = (const uint64_t *)find_SPropValue_data(&rowset.aRow[index], PR_FID); name = (const char *)find_SPropValue_data(&rowset.aRow[index], PR_DISPLAY_NAME_UNICODE); comment = (const char *)find_SPropValue_data(&rowset.aRow[index], PR_COMMENT_UNICODE); total = (const uint32_t *)find_SPropValue_data(&rowset.aRow[index], PR_CONTENT_COUNT); unread = (const uint32_t *)find_SPropValue_data(&rowset.aRow[index], PR_CONTENT_UNREAD); child = (const uint32_t *)find_SPropValue_data(&rowset.aRow[index], PR_FOLDER_CHILD_COUNT); for (i = 0; i < count; i++) { printf("| "); } printf("|---+ %-15s : %-20s (Total: %u / Unread: %u - Container class: %s) [FID: 0x%016"PRIx64"]\n", name, comment?comment:"", total?*total:0, unread?*unread:0, get_container_class(mem_ctx, parent, *fid), *fid); if (child && *child) { ret = get_child_folders(mem_ctx, &obj_folder, *fid, count + 1); if (ret == false) return ret; } } } mapi_object_release(&obj_htable); mapi_object_release(&obj_folder); return true; } static bool get_child_folders_pf(TALLOC_CTX *mem_ctx, mapi_object_t *parent, mapi_id_t folder_id, int count) { enum MAPISTATUS retval; bool ret; mapi_object_t obj_folder; mapi_object_t obj_htable; struct SPropTagArray *SPropTagArray; struct SRowSet rowset; const char *name; const uint32_t *child; uint32_t index; const uint64_t *fid; int i; mapi_object_init(&obj_folder); retval = OpenFolder(parent, folder_id, &obj_folder); if (retval != MAPI_E_SUCCESS) return false; mapi_object_init(&obj_htable); retval = GetHierarchyTable(&obj_folder, &obj_htable, 0, NULL); if (retval != MAPI_E_SUCCESS) return false; SPropTagArray = set_SPropTagArray(mem_ctx, 0x3, PR_DISPLAY_NAME_UNICODE, PR_FID, PR_FOLDER_CHILD_COUNT); retval = SetColumns(&obj_htable, SPropTagArray); MAPIFreeBuffer(SPropTagArray); if (retval != MAPI_E_SUCCESS) return false; while (((retval = QueryRows(&obj_htable, 0x32, TBL_ADVANCE, &rowset)) != MAPI_E_NOT_FOUND) && rowset.cRows) { for (index = 0; index < rowset.cRows; index++) { fid = (const uint64_t *)find_SPropValue_data(&rowset.aRow[index], PR_FID); name = (const char *)find_SPropValue_data(&rowset.aRow[index], PR_DISPLAY_NAME_UNICODE); child = (const uint32_t *)find_SPropValue_data(&rowset.aRow[index], PR_FOLDER_CHILD_COUNT); for (i = 0; i < count; i++) { printf("| "); } printf("|---+ %-15s [FID: 0x%016"PRIx64"]\n", name, *fid); if (*child) { ret = get_child_folders_pf(mem_ctx, &obj_folder, *fid, count + 1); if (ret == false) return ret; } } } return true; } static bool openchangeclient_pf(TALLOC_CTX *mem_ctx, mapi_object_t *obj_store) { enum MAPISTATUS retval; mapi_id_t id_pubroot; retval = GetDefaultPublicFolder(obj_store, &id_pubroot, olFolderPublicRoot); if (retval != MAPI_E_SUCCESS) return false; return get_child_folders_pf(mem_ctx, obj_store, id_pubroot, 0); } static bool openchangeclient_mailbox(TALLOC_CTX *mem_ctx, mapi_object_t *obj_store) { enum MAPISTATUS retval; mapi_id_t id_mailbox; struct SPropTagArray *SPropTagArray; struct SPropValue *lpProps; uint32_t cValues; const char *mailbox_name; /* Retrieve the mailbox folder name */ SPropTagArray = set_SPropTagArray(mem_ctx, 0x1, PR_DISPLAY_NAME_UNICODE); retval = GetProps(obj_store, MAPI_UNICODE, SPropTagArray, &lpProps, &cValues); MAPIFreeBuffer(SPropTagArray); if (retval != MAPI_E_SUCCESS) return false; if (lpProps[0].value.lpszW) { mailbox_name = lpProps[0].value.lpszW; } else { return false; } /* Prepare the directory listing */ retval = GetDefaultFolder(obj_store, &id_mailbox, olFolderTopInformationStore); if (retval != MAPI_E_SUCCESS) return false; printf("+ %s\n", mailbox_name); return get_child_folders(mem_ctx, obj_store, id_mailbox, 0); } static bool openchangeclient_fetchitems(TALLOC_CTX *mem_ctx, mapi_object_t *obj_store, const char *item, struct oclient *oclient) { enum MAPISTATUS retval; mapi_object_t obj_tis; mapi_object_t obj_folder; mapi_object_t obj_table; mapi_object_t obj_message; mapi_id_t fid; uint32_t olFolder = 0; struct SRowSet SRowSet; struct SPropTagArray *SPropTagArray; struct mapi_SPropValue_array properties_array; uint32_t count; uint32_t i; char *id; if (!item) return false; mapi_object_init(&obj_tis); mapi_object_init(&obj_folder); for (i = 0; defaultFolders[i].olFolder; i++) { if (!strncasecmp(defaultFolders[i].container_class, item, strlen(defaultFolders[i].container_class))) { olFolder = defaultFolders[i].olFolder; } } if (!olFolder) return false; if (oclient->pf == true) { retval = openchangeclient_getpfdir(mem_ctx, obj_store, &obj_folder, oclient->folder); if (retval != MAPI_E_SUCCESS) return retval; } else { if (oclient->folder) { retval = GetDefaultFolder(obj_store, &fid, olFolderTopInformationStore); MAPI_RETVAL_IF(retval, retval, mem_ctx); retval = OpenFolder(obj_store, fid, &obj_tis); MAPI_RETVAL_IF(retval, retval, mem_ctx); retval = openchangeclient_getdir(mem_ctx, &obj_tis, &obj_folder, oclient->folder); MAPI_RETVAL_IF(retval, retval, mem_ctx); } else { retval = GetDefaultFolder(obj_store, &fid, olFolder); if (retval != MAPI_E_SUCCESS) return false; /* We now open the folder */ retval = OpenFolder(obj_store, fid, &obj_folder); if (retval != MAPI_E_SUCCESS) return false; } } /* Operations on the folder */ mapi_object_init(&obj_table); retval = GetContentsTable(&obj_folder, &obj_table, 0, &count); if (retval != MAPI_E_SUCCESS) return false; printf("MAILBOX (%u messages)\n", count); if (!count) { mapi_object_release(&obj_table); mapi_object_release(&obj_folder); mapi_object_release(&obj_tis); return true; } SPropTagArray = set_SPropTagArray(mem_ctx, 0x8, PR_FID, PR_MID, PR_INST_ID, PR_INSTANCE_NUM, PR_SUBJECT_UNICODE, PR_MESSAGE_CLASS_UNICODE, PR_RULE_MSG_PROVIDER, PR_RULE_MSG_NAME); retval = SetColumns(&obj_table, SPropTagArray); MAPIFreeBuffer(SPropTagArray); if (retval != MAPI_E_SUCCESS) return false; while ((retval = QueryRows(&obj_table, count, TBL_ADVANCE, &SRowSet)) != MAPI_E_NOT_FOUND && SRowSet.cRows) { count -= SRowSet.cRows; for (i = 0; i < SRowSet.cRows; i++) { mapi_object_init(&obj_message); retval = OpenMessage(&obj_folder, SRowSet.aRow[i].lpProps[0].value.d, SRowSet.aRow[i].lpProps[1].value.d, &obj_message, 0); if (retval != MAPI_E_NOT_FOUND) { if (oclient->summary) { mapidump_message_summary(&obj_message); } else { retval = GetPropsAll(&obj_message, MAPI_UNICODE, &properties_array); if (retval == MAPI_E_SUCCESS) { id = talloc_asprintf(mem_ctx, ": %"PRIX64"/%"PRIX64, SRowSet.aRow[i].lpProps[0].value.d, SRowSet.aRow[i].lpProps[1].value.d); mapi_SPropValue_array_named(&obj_message, &properties_array); switch (olFolder) { case olFolderInbox: mapidump_message(&properties_array, id, NULL); break; case olFolderCalendar: mapidump_appointment(&properties_array, id); break; case olFolderContacts: mapidump_contact(&properties_array, id); break; case olFolderTasks: mapidump_task(&properties_array, id); break; case olFolderNotes: mapidump_note(&properties_array, id); break; } talloc_free(id); } } mapi_object_release(&obj_message); } } } mapi_object_release(&obj_table); mapi_object_release(&obj_folder); mapi_object_release(&obj_tis); return true; } /** * Update Item * * Edit the existing item specified on command line. * The function first loops over the mailbox, looking for the folder * ID, then it looks for the particular message ID. It finally opens * it, set properties and save the message. * */ static enum MAPISTATUS folder_lookup(TALLOC_CTX *mem_ctx, uint64_t sfid, mapi_object_t *obj_parent, mapi_id_t folder_id, mapi_object_t *obj_ret) { enum MAPISTATUS retval; mapi_object_t obj_folder; mapi_object_t obj_htable; struct SPropTagArray *SPropTagArray; struct SRowSet SRowSet; uint32_t i; const uint64_t *fid; mapi_object_init(&obj_folder); retval = OpenFolder(obj_parent, folder_id, &obj_folder); if (retval != MAPI_E_SUCCESS) return retval; mapi_object_init(&obj_htable); retval = GetHierarchyTable(&obj_folder, &obj_htable, 0, NULL); if (retval != MAPI_E_SUCCESS) return retval; SPropTagArray = set_SPropTagArray(mem_ctx, 0x1, PR_FID); retval = SetColumns(&obj_htable, SPropTagArray); MAPIFreeBuffer(SPropTagArray); if (retval != MAPI_E_SUCCESS) return retval; while (((retval = QueryRows(&obj_htable, 0x32, TBL_ADVANCE, &SRowSet)) != MAPI_E_NOT_FOUND && SRowSet.cRows)) { for (i = 0; i < SRowSet.cRows; i++) { fid = (const uint64_t *)find_SPropValue_data(&SRowSet.aRow[i], PR_FID); if (fid && *fid == sfid) { retval = OpenFolder(&obj_folder, *fid, obj_ret); mapi_object_release(&obj_htable); mapi_object_release(&obj_folder); return MAPI_E_SUCCESS; } else if (fid) { retval = folder_lookup(mem_ctx, sfid, &obj_folder, *fid, obj_ret); if (retval == MAPI_E_SUCCESS) { mapi_object_release(&obj_htable); mapi_object_release(&obj_folder); return MAPI_E_SUCCESS; } } } } mapi_object_release(&obj_htable); mapi_object_release(&obj_folder); errno = MAPI_E_NOT_FOUND; return MAPI_E_NOT_FOUND; } static enum MAPISTATUS message_lookup(TALLOC_CTX *mem_ctx, uint64_t smid, mapi_object_t *obj_folder, mapi_object_t *obj_message) { enum MAPISTATUS retval; mapi_object_t obj_htable; struct SPropTagArray *SPropTagArray; struct SRowSet SRowSet; uint32_t i; const uint64_t *fid; const uint64_t *mid; mapi_object_init(&obj_htable); retval = GetContentsTable(obj_folder, &obj_htable, 0, NULL); if (retval != MAPI_E_SUCCESS) return retval; SPropTagArray = set_SPropTagArray(mem_ctx, 0x2, PR_FID, PR_MID); retval = SetColumns(&obj_htable, SPropTagArray); MAPIFreeBuffer(SPropTagArray); if (retval != MAPI_E_SUCCESS) return retval; while (((retval = QueryRows(&obj_htable, 0x32, TBL_ADVANCE, &SRowSet)) != MAPI_E_NOT_FOUND) && SRowSet.cRows) { for (i = 0; i < SRowSet.cRows; i++) { fid = (const uint64_t *)find_SPropValue_data(&SRowSet.aRow[i], PR_FID); mid = (const uint64_t *)find_SPropValue_data(&SRowSet.aRow[i], PR_MID); if (mid && *mid == smid) { retval = OpenMessage(obj_folder, *fid, *mid, obj_message, ReadWrite); mapi_object_release(&obj_htable); return retval; } } } mapi_object_release(&obj_htable); errno = MAPI_E_NOT_FOUND; return MAPI_E_NOT_FOUND; } static bool openchangeclient_updateitem(TALLOC_CTX *mem_ctx, mapi_object_t *obj_store, struct oclient *oclient, const char *container_class) { enum MAPISTATUS retval; mapi_object_t obj_folder; mapi_object_t obj_message; mapi_id_t id_tis; char *fid_str; uint64_t fid; uint64_t mid; const char *item = NULL; item = oclient->update; if (!item) { DEBUG(0, ("Missing ID\n")); errno = MAPI_E_INVALID_PARAMETER; return false; } if (!container_class) { DEBUG(0, ("Missing container class\n")); errno = MAPI_E_INVALID_PARAMETER; return false; } fid_str = strsep((char **)&item, "/"); if (!fid_str || !item) { DEBUG(0, (" Invalid ID: %s\n", fid_str ? fid_str : "null")); errno = MAPI_E_INVALID_PARAMETER; return false; } fid = strtoull(fid_str, NULL, 16); mid = strtoull(item, NULL, 16); /* Step 1: search the folder from Top Information Store */ mapi_object_init(&obj_folder); retval = GetDefaultFolder(obj_store, &id_tis, olFolderTopInformationStore); if (retval != MAPI_E_SUCCESS) return false; retval = folder_lookup(mem_ctx, fid, obj_store, id_tis, &obj_folder); if (retval != MAPI_E_SUCCESS) return false; /* Step 2: search the message */ mapi_object_init(&obj_message); retval = message_lookup(mem_ctx, mid, &obj_folder, &obj_message); if (retval != MAPI_E_SUCCESS) return false; /* Step 3: edit the message */ if (!strcmp(container_class, IPF_APPOINTMENT)) { retval = appointment_SetProps(mem_ctx, &obj_folder, &obj_message, oclient); } else if (!strcmp(container_class, IPF_CONTACT)) { retval = contact_SetProps(mem_ctx, &obj_folder, &obj_message, oclient); } else if (!strcmp(container_class, IPF_TASK)) { retval = task_SetProps(mem_ctx, &obj_message, oclient); } else if (!strcmp(container_class, IPF_STICKYNOTE)) { retval = note_SetProps(mem_ctx, &obj_message, oclient); } if (retval != MAPI_E_SUCCESS) return false; /* Step 4: save the message */ retval = SaveChangesMessage(&obj_folder, &obj_message, KeepOpenReadOnly); if (retval != MAPI_E_SUCCESS) return false; mapi_object_release(&obj_message); mapi_object_release(&obj_folder); return true; } /** * Delete an item given its unique ID */ static bool openchangeclient_deleteitems(TALLOC_CTX *mem_ctx, mapi_object_t *obj_store, struct oclient *oclient) { enum MAPISTATUS retval; mapi_object_t obj_folder; mapi_object_t obj_message; mapi_id_t id_tis; char *fid_str; uint64_t fid; uint64_t mid; const char *item = NULL; item = oclient->delete; if (!item) { DEBUG(0, ("Missing ID\n")); errno = MAPI_E_INVALID_PARAMETER; return false; } fid_str = strsep((char **)&item, "/"); if (!fid_str || !item) { DEBUG(0, (" Invalid ID: %s\n", fid_str ? fid_str : "null")); errno = MAPI_E_INVALID_PARAMETER; return false; } fid = strtoull(fid_str, NULL, 16); mid = strtoull(item, NULL, 16); /* Step 1: search the folder from Top Information Store */ mapi_object_init(&obj_folder); retval = GetDefaultFolder(obj_store, &id_tis, olFolderTopInformationStore); if (retval != MAPI_E_SUCCESS) return false; retval = folder_lookup(mem_ctx, fid, obj_store, id_tis, &obj_folder); if (retval != MAPI_E_SUCCESS) return false; /* Step 2: search the message within returned folder */ mapi_object_init(&obj_message); retval = message_lookup(mem_ctx, mid, &obj_folder, &obj_message); if (retval != MAPI_E_SUCCESS) return false; /* Step 3: delete the message */ retval = DeleteMessage(&obj_folder, &mid, 1); if (retval != MAPI_E_SUCCESS) return false; mapi_object_release(&obj_message); mapi_object_release(&obj_folder); return true; } /** * Dump email * * Assume msg is received in Inbox folder since we only register * notifications for this folder. * */ static enum MAPISTATUS openchangeclient_findmail(mapi_object_t *obj_store, mapi_id_t msgid) { enum MAPISTATUS retval; TALLOC_CTX *mem_ctx; struct SRowSet SRowSet; struct SPropValue *lpProp; struct mapi_SPropValue_array properties_array; mapi_id_t fid; const mapi_id_t *mid; mapi_object_t obj_inbox; mapi_object_t obj_table; mapi_object_t obj_message; struct SPropTagArray *SPropTagArray = NULL; uint32_t count; uint32_t i; char *id; mem_ctx = talloc_named(NULL, 0, "openchangeclient_findmail"); /* Get Inbox folder */ retval = GetDefaultFolder(obj_store, &fid, olFolderInbox); MAPI_RETVAL_IF(retval, GetLastError(), mem_ctx); /* Open Inbox */ mapi_object_init(&obj_inbox); retval = OpenFolder(obj_store, fid, &obj_inbox); MAPI_RETVAL_IF(retval, GetLastError(), mem_ctx); /* Retrieve contents table */ mapi_object_init(&obj_table); retval = GetContentsTable(&obj_inbox, &obj_table, 0, &count); MAPI_RETVAL_IF(retval, GetLastError(), mem_ctx); SPropTagArray = set_SPropTagArray(mem_ctx, 0x2, PR_FID, PR_MID); retval = SetColumns(&obj_table, SPropTagArray); MAPIFreeBuffer(SPropTagArray); MAPI_RETVAL_IF(retval, GetLastError(), mem_ctx); while ((retval = QueryRows(&obj_table, 0xa, TBL_ADVANCE, &SRowSet)) != MAPI_E_NOT_FOUND && SRowSet.cRows) { for (i = 0; i < SRowSet.cRows; i++) { lpProp = get_SPropValue_SRowSet(&SRowSet, PR_MID); if (lpProp != NULL) { mid = (const uint64_t *)get_SPropValue(lpProp, PR_MID); if (*mid == msgid) { mapi_object_init(&obj_message); retval = OpenMessage(obj_store, SRowSet.aRow[i].lpProps[0].value.d, SRowSet.aRow[i].lpProps[1].value.d, &obj_message, 0); if (GetLastError() == MAPI_E_SUCCESS) { retval = GetPropsAll(&obj_message, MAPI_UNICODE, &properties_array); if (retval != MAPI_E_SUCCESS) return retval; id = talloc_asprintf(mem_ctx, ": %"PRIX64"/%"PRIX64, SRowSet.aRow[i].lpProps[0].value.d, SRowSet.aRow[i].lpProps[1].value.d); mapidump_message(&properties_array, id, NULL); mapi_object_release(&obj_message); talloc_free(id); goto end; } mapi_object_release(&obj_message); } } } } end: mapi_object_release(&obj_table); mapi_object_release(&obj_inbox); talloc_free(mem_ctx); return MAPI_E_SUCCESS; } static int callback(uint16_t NotificationType, void *NotificationData, void *private_data) { struct NewMailNotification *newmail; struct HierarchyTableChange *htable; struct ContentsTableChange *ctable; struct ContentsTableChange *stable; switch(NotificationType) { case fnevNewMail: case fnevNewMail|fnevMbit: DEBUG(0, ("[+] New mail Received\n")); newmail = (struct NewMailNotification *) NotificationData; mapidump_newmail(newmail, "\t"); openchangeclient_findmail((mapi_object_t *)private_data, newmail->MID); mapi_errstr("openchangeclient_findmail", GetLastError()); break; case fnevObjectCreated: DEBUG(0, ("[+] Folder Created\n")); break; case fnevObjectDeleted: DEBUG(0, ("[+] Folder Deleted\n")); break; case fnevObjectModified: case fnevTbit|fnevObjectModified: case fnevUbit|fnevObjectModified: case fnevTbit|fnevUbit|fnevObjectModified: DEBUG(0, ("[+] Folder Modified\n")); break; case fnevObjectMoved: DEBUG(0, ("[+] Folder Moved\n")); break; case fnevObjectCopied: DEBUG(0, ("[+] Folder Copied\n")); break; case fnevSearchComplete: DEBUG(0, ("[+] Search complete in search folder\n")); break; case fnevTableModified: htable = (struct HierarchyTableChange *) NotificationData; DEBUG(0, ("[+] Hierarchy Table: ")); switch (htable->TableEvent) { case TABLE_CHANGED: DEBUG(0, (" changed\n")); break; case TABLE_ROW_ADDED: DEBUG(0, ("row added\n")); break; case TABLE_ROW_DELETED: DEBUG(0, ("row deleted\n")); break; case TABLE_ROW_MODIFIED: DEBUG(0, ("row modified\n")); break; case TABLE_RESTRICT_DONE: DEBUG(0, ("restriction done\n")); break; default: DEBUG(0, ("\n")); break; } break; case fnevStatusObjectModified: DEBUG(0, ("[+] ICS Notification\n")); break; case fnevMbit|fnevObjectCreated: DEBUG(0, ("[+] Message created\n")); break; case fnevMbit|fnevObjectDeleted: DEBUG(0, ("[+] Message deleted\n")); break; case fnevMbit|fnevObjectModified: DEBUG(0, ("[+] Message modified\n")); break; case fnevMbit|fnevObjectMoved: DEBUG(0, ("[+] Message moved\n")); break; case fnevMbit|fnevObjectCopied: DEBUG(0, ("[+] Message copied\n")); break; case fnevMbit|fnevTableModified: ctable = (struct ContentsTableChange *) NotificationData; DEBUG(0, ("[+] Contents Table: ")); switch (ctable->TableEvent) { case TABLE_CHANGED: DEBUG(0, (" changed\n")); break; case TABLE_ROW_ADDED: DEBUG(0, ("row added\n")); break; case TABLE_ROW_DELETED: DEBUG(0, ("row deleted\n")); break; case TABLE_ROW_MODIFIED: DEBUG(0, ("row modified\n")); break; case TABLE_RESTRICT_DONE: DEBUG(0, ("restriction done\n")); break; default: DEBUG(0, ("\n")); break; } break; case fnevMbit|fnevSbit|fnevObjectDeleted: DEBUG(0, ("[+] A message is no longer part of a search folder\n")); break; case fnevMbit|fnevSbit|fnevObjectModified: DEBUG(0, ("[+] A property on a message in a search folder has changed\n")); break; case fnevMbit|fnevSbit|fnevTableModified: stable = (struct ContentsTableChange *) NotificationData; DEBUG(0, ("[+] Search Table: ")); switch (stable->TableEvent) { case TABLE_CHANGED: DEBUG(0, (" changed\n")); break; case TABLE_ROW_ADDED: DEBUG(0, ("row added\n")); break; case TABLE_ROW_DELETED: DEBUG(0, ("row deleted\n")); break; case TABLE_ROW_MODIFIED: DEBUG(0, ("row modified\n")); break; case TABLE_RESTRICT_DONE: DEBUG(0, ("restriction done\n")); break; default: DEBUG(0, ("\n")); break; } break; default: printf("[+] Unsupported notification (0x%x)\n", NotificationType); break; } return 0; } static bool openchangeclient_notifications(TALLOC_CTX *mem_ctx, mapi_object_t *obj_store, struct oclient *oclient) { enum MAPISTATUS retval; mapi_object_t obj_inbox; mapi_id_t fid; uint32_t ulConnection; uint16_t ulEventMask; uint32_t notification = 0; struct mapi_session *session; /* Register notification */ session = mapi_object_get_session(obj_store); retval = RegisterNotification(session); if (retval != MAPI_E_SUCCESS) return false; if (oclient->pf == true) { retval = openchangeclient_getpfdir(mem_ctx, obj_store, &obj_inbox, oclient->folder); if (retval != MAPI_E_SUCCESS) return retval; } else { /* Retrieve Inbox folder ID */ retval = GetDefaultFolder(obj_store, &fid, olFolderInbox); if (retval != MAPI_E_SUCCESS) return false; /* Open Inbox folder */ mapi_object_init(&obj_inbox); retval = OpenFolder(obj_store, fid, &obj_inbox); if (retval != MAPI_E_SUCCESS) return false; } /* subscribe Inbox to receive newmail notifications */ ulEventMask = fnevNewMail|fnevObjectCreated|fnevObjectDeleted| fnevObjectModified|fnevObjectMoved|fnevObjectCopied| fnevSearchComplete|fnevTableModified|fnevStatusObjectModified; retval = Subscribe(obj_store, &ulConnection, ulEventMask, true, (mapi_notify_callback_t)callback, (void*) obj_store); retval = Subscribe(&obj_inbox, &ulConnection, ulEventMask, true, (mapi_notify_callback_t)callback, (void*) obj_store); if (retval != MAPI_E_SUCCESS) return false; /* wait for notifications: infinite loop */ retval = RegisterAsyncNotification(mapi_object_get_session(obj_store), ¬ification); if( retval == MAPI_E_NOT_INITIALIZED ) { retval = MonitorNotification(mapi_object_get_session(obj_store), (void *)obj_store, NULL); } if (retval != MAPI_E_SUCCESS) return false; retval = Unsubscribe(mapi_object_get_session(obj_store), ulConnection); if (retval != MAPI_E_SUCCESS) return false; mapi_object_release(&obj_inbox); return true; } static bool openchangeclient_mkdir(TALLOC_CTX *mem_ctx, mapi_object_t *obj_store, struct oclient *oclient) { enum MAPISTATUS retval; mapi_object_t obj_folder; mapi_object_t obj_child; mapi_object_t obj_tis; mapi_id_t id_inbox; mapi_object_init(&obj_tis); mapi_object_init(&obj_folder); mapi_object_init(&obj_child); if (oclient->folder) { retval = GetDefaultFolder(obj_store, &id_inbox, olFolderTopInformationStore); if (retval != MAPI_E_SUCCESS) return false; retval = OpenFolder(obj_store, id_inbox, &obj_tis); if (retval != MAPI_E_SUCCESS) return false; retval = openchangeclient_getdir(mem_ctx, &obj_tis, &obj_folder, oclient->folder); if (retval != MAPI_E_SUCCESS) return false; } else { retval = GetDefaultFolder(obj_store, &id_inbox, olFolderInbox); if (retval != MAPI_E_SUCCESS) return false; retval = OpenFolder(obj_store, id_inbox, &obj_folder); if (retval != MAPI_E_SUCCESS) return false; } retval = CreateFolder(&obj_folder, FOLDER_GENERIC, oclient->folder_name, oclient->folder_comment, OPEN_IF_EXISTS, &obj_child); if (retval != MAPI_E_SUCCESS) return false; mapi_object_release(&obj_child); mapi_object_release(&obj_folder); mapi_object_release(&obj_tis); return true; } static bool openchangeclient_rmdir(TALLOC_CTX *mem_ctx, mapi_object_t *obj_store, struct oclient *oclient) { enum MAPISTATUS retval; mapi_object_t obj_folder; mapi_object_t obj_child; mapi_object_t obj_tis; mapi_id_t id_inbox; mapi_object_init(&obj_tis); mapi_object_init(&obj_folder); mapi_object_init(&obj_child); if (oclient->folder) { printf("Removing folder within %s\n", oclient->folder); retval = GetDefaultFolder(obj_store, &id_inbox, olFolderTopInformationStore); if (retval != MAPI_E_SUCCESS) return false; retval = OpenFolder(obj_store, id_inbox, &obj_tis); if (retval != MAPI_E_SUCCESS) return false; retval = openchangeclient_getdir(mem_ctx, &obj_tis, &obj_folder, oclient->folder); if (retval != MAPI_E_SUCCESS) return false; } else { retval = GetDefaultFolder(obj_store, &id_inbox, olFolderInbox); if (retval != MAPI_E_SUCCESS) return false; retval = OpenFolder(obj_store, id_inbox, &obj_folder); if (retval != MAPI_E_SUCCESS) return false; } retval = openchangeclient_getdir(mem_ctx, &obj_folder, &obj_child, oclient->folder_name); if (retval != MAPI_E_SUCCESS) return false; retval = EmptyFolder(&obj_child); if (retval != MAPI_E_SUCCESS) return false; printf("obj_child fid = 0x%"PRIx64"\n", mapi_object_get_id(&obj_child)); retval = DeleteFolder(&obj_folder, mapi_object_get_id(&obj_child), DEL_FOLDERS, NULL); if (retval != MAPI_E_SUCCESS) return false; mapi_object_release(&obj_child); mapi_object_release(&obj_folder); mapi_object_release(&obj_tis); return true; } static bool openchangeclient_userlist(TALLOC_CTX *mem_ctx, struct mapi_session *session) { struct SPropTagArray *SPropTagArray; struct PropertyRowSet_r *RowSet; uint32_t i; uint32_t count; uint8_t ulFlags; uint32_t rowsFetched = 0; uint32_t totalRecs = 0; GetGALTableCount(session, &totalRecs); printf("Total Number of entries in GAL: %d\n", totalRecs); SPropTagArray = set_SPropTagArray(mem_ctx, 0xc, PR_INSTANCE_KEY, PR_ENTRYID, PR_DISPLAY_NAME_UNICODE, PR_EMAIL_ADDRESS_UNICODE, PR_DISPLAY_TYPE, PR_OBJECT_TYPE, PR_ADDRTYPE_UNICODE, PR_OFFICE_TELEPHONE_NUMBER_UNICODE, PR_OFFICE_LOCATION_UNICODE, PR_TITLE_UNICODE, PR_COMPANY_NAME_UNICODE, PR_ACCOUNT_UNICODE); count = 0x7; ulFlags = TABLE_START; do { count += 0x2; GetGALTable(session, SPropTagArray, &RowSet, count, ulFlags); if ((!RowSet) || (!(RowSet->aRow))) { return false; } rowsFetched = RowSet->cRows; if (rowsFetched) { for (i = 0; i < rowsFetched; i++) { mapidump_PAB_entry(&RowSet->aRow[i]); } } ulFlags = TABLE_CUR; MAPIFreeBuffer(RowSet); } while (rowsFetched == count); mapi_errstr("GetPABTable", GetLastError()); MAPIFreeBuffer(SPropTagArray); return true; } static bool openchangeclient_ocpf_syntax(struct oclient *oclient) { int ret; struct ocpf_file *element; uint32_t context_id; /* Sanity checks */ if (!oclient->ocpf_files || !oclient->ocpf_files->next) { errno = MAPI_E_INVALID_PARAMETER; return false; } /* Step 1. Initialize OCPF context */ ret = ocpf_init(); if (ret == -1) { errno = MAPI_E_CALL_FAILED; return false; } /* Step2. Parse OCPF files */ for (element = oclient->ocpf_files; element->next; element = element->next) { ret = ocpf_new_context(element->filename, &context_id, OCPF_FLAGS_READ); if (ret == -1) { errno = MAPI_E_INVALID_PARAMETER; return false; } ret = ocpf_parse(context_id); if (ret == -1) { DEBUG(0, ("ocpf_parse failed ...\n")); errno = MAPI_E_INVALID_PARAMETER; return false; } /* Dump OCPF contents */ ocpf_dump(context_id); ret = ocpf_del_context(context_id); } /* Step4. Release OCPF context */ ret = ocpf_release(); if (ret == -1) { errno = MAPI_E_CALL_FAILED; return false; } return true; } static bool openchangeclient_ocpf_sender(TALLOC_CTX *mem_ctx, mapi_object_t *obj_store, struct oclient *oclient) { enum MAPISTATUS retval; int ret; struct ocpf_file *element; mapi_object_t obj_folder; mapi_object_t obj_message; uint32_t cValues = 0; struct SPropValue *lpProps; uint32_t context_id; /* Sanity Check */ if (!oclient->ocpf_files || !oclient->ocpf_files->next) { errno = MAPI_E_INVALID_PARAMETER; return false; } /* Step1. Initialize OCPF context */ ret = ocpf_init(); if (ret == -1) { errno = MAPI_E_CALL_FAILED; return false; } /* Step2. Parse OCPF files */ for (element = oclient->ocpf_files; element->next; element = element->next) { ret = ocpf_new_context(element->filename, &context_id, OCPF_FLAGS_READ); ret = ocpf_parse(context_id); if (ret == -1) { errno = MAPI_E_INVALID_PARAMETER; return false; } } /* Step3. Open destination folder using ocpf API */ mapi_object_init(&obj_folder); retval = ocpf_OpenFolder(context_id, obj_store, &obj_folder); if (retval != MAPI_E_SUCCESS) return false; /* Step4. Create the message */ mapi_object_init(&obj_message); retval = CreateMessage(&obj_folder, &obj_message); if (retval != MAPI_E_SUCCESS) return false; /* Step5, Set message recipients */ retval = ocpf_set_Recipients(mem_ctx, context_id, &obj_message); if (retval != MAPI_E_SUCCESS && GetLastError() != MAPI_E_NOT_FOUND) return false; errno = MAPI_E_SUCCESS; /* Step6. Set message properties */ retval = ocpf_set_SPropValue(mem_ctx, context_id, &obj_folder, &obj_message); if (retval != MAPI_E_SUCCESS) return false; /* Step7. Set message properties */ lpProps = ocpf_get_SPropValue(context_id, &cValues); retval = SetProps(&obj_message, 0, lpProps, cValues); MAPIFreeBuffer(lpProps); if (retval != MAPI_E_SUCCESS) return false; /* Step8. Save message */ retval = SaveChangesMessage(&obj_folder, &obj_message, KeepOpenReadOnly); if (retval != MAPI_E_SUCCESS) return false; mapi_object_release(&obj_message); mapi_object_release(&obj_folder); ocpf_del_context(context_id); return true; } static bool openchangeclient_ocpf_dump(TALLOC_CTX *mem_ctx, mapi_object_t *obj_store, struct oclient *oclient) { enum MAPISTATUS retval; int ret; mapi_object_t obj_folder; mapi_object_t obj_message; mapi_id_t id_tis; const char *fid_str; uint64_t fid; uint64_t mid; const char *item = NULL; char *filename = NULL; struct mapi_SPropValue_array lpProps; uint32_t context_id; /* retrieve the FID/MID for ocpf_dump parameter */ item = oclient->ocpf_dump; fid_str = strsep((char **)&item, "/"); if (!fid_str || !item) { DEBUG(0, (" Invalid ID: %s\n", fid_str ? fid_str : "null")); errno = MAPI_E_INVALID_PARAMETER; return false; } fid = strtoull(fid_str, NULL, 16); mid = strtoull(item, NULL, 16); /* Step 1. search the folder from Top Information Store */ mapi_object_init(&obj_folder); retval = GetDefaultFolder(obj_store, &id_tis, olFolderTopInformationStore); if (retval != MAPI_E_SUCCESS) return false; retval = folder_lookup(mem_ctx, fid, obj_store, id_tis, &obj_folder); if (retval != MAPI_E_SUCCESS) return false; /* Step 2. search the message */ mapi_object_init(&obj_message); retval = message_lookup(mem_ctx, mid, &obj_folder, &obj_message); if (retval != MAPI_E_SUCCESS) return false; /* Step 3. retrieve all message properties */ retval = GetPropsAll(&obj_message, MAPI_UNICODE, &lpProps); /* Step 4. save the message */ ret = ocpf_init(); filename = talloc_asprintf(mem_ctx, "%"PRIx64".ocpf", mid); DEBUG(0, ("OCPF output file: %s\n", filename)); ret = ocpf_new_context(filename, &context_id, OCPF_FLAGS_CREATE); talloc_free(filename); ret = ocpf_write_init(context_id, fid); ret = ocpf_write_auto(context_id, &obj_message, &lpProps); if (ret == OCPF_SUCCESS) { ret = ocpf_write_commit(context_id); } ret = ocpf_del_context(context_id); ret = ocpf_release(); mapi_object_release(&obj_message); mapi_object_release(&obj_folder); return true; } static bool openchangeclient_freebusy(mapi_object_t *obj_store, struct oclient *oclient) { enum MAPISTATUS retval; struct SRow aRow; const char *message_name; uint32_t i; const uint32_t *publish_start; const uint32_t *publish_end; const struct LongArray_r *busy_months; const struct BinaryArray_r *busy_events; const struct LongArray_r *tentative_months; const struct BinaryArray_r *tentative_events; const struct LongArray_r *oof_months; const struct BinaryArray_r *oof_events; uint32_t year; uint32_t event_year; /* Step 1. Retrieve FreeBusy data for the given user */ retval = GetUserFreeBusyData(obj_store, oclient->freebusy, &aRow); if (retval != MAPI_E_SUCCESS) return false; /* Step 2. Dump properties */ message_name = (const char *) find_SPropValue_data(&aRow, PR_NORMALIZED_SUBJECT); publish_start = (const uint32_t *) find_SPropValue_data(&aRow, PR_FREEBUSY_PUBLISH_START); publish_end = (const uint32_t *) find_SPropValue_data(&aRow, PR_FREEBUSY_PUBLISH_END); busy_months = (const struct LongArray_r *) find_SPropValue_data(&aRow, PR_SCHDINFO_MONTHS_BUSY); busy_events = (const struct BinaryArray_r *) find_SPropValue_data(&aRow, PR_SCHDINFO_FREEBUSY_BUSY); tentative_months = (const struct LongArray_r *) find_SPropValue_data(&aRow, PR_SCHDINFO_MONTHS_TENTATIVE); tentative_events = (const struct BinaryArray_r *) find_SPropValue_data(&aRow, PR_SCHDINFO_FREEBUSY_TENTATIVE); oof_months = (const struct LongArray_r *) find_SPropValue_data(&aRow, PR_SCHDINFO_MONTHS_OOF); oof_events = (const struct BinaryArray_r *) find_SPropValue_data(&aRow, PR_SCHDINFO_FREEBUSY_OOF); year = GetFreeBusyYear(publish_start); DEBUG(0, ("FreeBusy (%s):\n", message_name)); mapidump_date_SPropValue(aRow.lpProps[1], "* FreeBusy Last Modification Time", "\t"); mapidump_freebusy_date(*publish_start, "\t* FreeBusy Publishing Start:"); mapidump_freebusy_date(*publish_end, "\t *FreeBusy Publishing End: "); if (busy_months && ((*(const uint32_t *) busy_months) != MAPI_E_NOT_FOUND) && busy_events && ((*(const uint32_t *) busy_events) != MAPI_E_NOT_FOUND)) { DEBUG(0, ("\t* Busy Events:\n")); for (i = 0; i < busy_months->cValues; i++) { event_year = mapidump_freebusy_year(busy_months->lpl[i], year); DEBUG(0, ("\t\t* %s %u:\n", mapidump_freebusy_month(busy_months->lpl[i], event_year), event_year)); mapidump_freebusy_event(&busy_events->lpbin[i], busy_months->lpl[i], event_year, "\t\t\t* "); } } if (tentative_months && ((*(const uint32_t *) tentative_months) != MAPI_E_NOT_FOUND) && tentative_events && ((*(const uint32_t *) tentative_events) != MAPI_E_NOT_FOUND)) { DEBUG(0, ("\t* Tentative Events:\n")); for (i = 0; i < tentative_months->cValues; i++) { event_year = mapidump_freebusy_year(tentative_months->lpl[i], year); DEBUG(0, ("\t\t* %s %u:\n", mapidump_freebusy_month(tentative_months->lpl[i], event_year), event_year)); mapidump_freebusy_event(&tentative_events->lpbin[i], tentative_months->lpl[i], event_year, "\t\t\t* "); } } if (oof_months && ((*(const uint32_t *) oof_months) != MAPI_E_NOT_FOUND) && oof_events && ((*(const uint32_t *) oof_events) != MAPI_E_NOT_FOUND)) { DEBUG(0, ("\t* Out Of Office Events:\n")); for (i = 0; i < oof_months->cValues; i++) { event_year = mapidump_freebusy_year(oof_months->lpl[i], year); DEBUG(0, ("\t\t* %s %u:\n", mapidump_freebusy_month(oof_months->lpl[i], event_year), event_year)); mapidump_freebusy_event(&oof_events->lpbin[i], oof_months->lpl[i], event_year, "\t\t\t* "); } } MAPIFreeBuffer(aRow.lpProps); return true; } static void list_argument(const char *label, struct oc_element *oc_items) { uint32_t i; printf("Use one of the following %s values:\n", label); for (i = 0; oc_items[i].status; i++) { printf("%s\n", oc_items[i].status); } } static uint32_t oc_get_argument(const char *name, struct oc_element *oc_items, const char *label) { uint32_t i; for (i = 0; oc_items[i].status; i++) { if (!strncasecmp(oc_items[i].status, name, strlen(oc_items[i].status))) { return oc_items[i].index; } } list_argument(label, oc_items); exit (1); } int main(int argc, const char *argv[]) { TALLOC_CTX *mem_ctx; enum MAPISTATUS retval; struct mapi_session *session = NULL; mapi_object_t obj_store; struct oclient oclient; poptContext pc; int opt; bool opt_sendmail = false; bool opt_sendappointment = false; bool opt_sendcontact = false; bool opt_sendtask = false; bool opt_sendnote = false; bool opt_fetchmail = false; bool opt_deletemail = false; bool opt_mailbox = false; bool opt_dumpdata = false; bool opt_notifications = false; bool opt_mkdir = false; bool opt_rmdir = false; bool opt_userlist = false; bool opt_ocpf_syntax = false; bool opt_ocpf_sender = false; const char *opt_profdb = NULL; char *opt_profname = NULL; const char *opt_username = NULL; const char *opt_password = NULL; const char *opt_attachments = NULL; const char *opt_fetchitems = NULL; const char *opt_html_file = NULL; const char *opt_mapi_to = NULL; const char *opt_mapi_cc = NULL; const char *opt_mapi_bcc = NULL; const char *opt_debug = NULL; enum {OPT_PROFILE_DB=1000, OPT_PROFILE, OPT_SENDMAIL, OPT_PASSWORD, OPT_SENDAPPOINTMENT, OPT_SENDCONTACT, OPT_SENDTASK, OPT_FETCHMAIL, OPT_STOREMAIL, OPT_DELETEMAIL, OPT_ATTACH, OPT_HTML_INLINE, OPT_HTML_FILE, OPT_MAPI_TO, OPT_MAPI_CC, OPT_MAPI_BCC, OPT_MAPI_SUBJECT, OPT_MAPI_BODY, OPT_MAILBOX, OPT_FETCHITEMS, OPT_MAPI_LOCATION, OPT_MAPI_STARTDATE, OPT_MAPI_ENDDATE, OPT_MAPI_BUSYSTATUS, OPT_NOTIFICATIONS, OPT_DEBUG, OPT_DUMPDATA, OPT_MAPI_EMAIL, OPT_MAPI_FULLNAME, OPT_MAPI_CARDNAME, OPT_MAPI_TASKSTATUS, OPT_MAPI_IMPORTANCE, OPT_MAPI_LABEL, OPT_PF, OPT_FOLDER, OPT_MAPI_COLOR, OPT_SENDNOTE, OPT_MKDIR, OPT_RMDIR, OPT_FOLDER_NAME, OPT_FOLDER_COMMENT, OPT_USERLIST, OPT_MAPI_PRIVATE, OPT_UPDATE, OPT_DELETEITEMS, OPT_OCPF_FILE, OPT_OCPF_SYNTAX, OPT_OCPF_SENDER, OPT_OCPF_DUMP, OPT_FREEBUSY, OPT_FORCE, OPT_FETCHSUMMARY, OPT_USERNAME }; struct poptOption long_options[] = { POPT_AUTOHELP {"database", 'f', POPT_ARG_STRING, NULL, OPT_PROFILE_DB, "set the profile database path", NULL }, {"pf", 0, POPT_ARG_NONE, NULL, OPT_PF, "access public folders instead of mailbox", NULL }, {"profile", 'p', POPT_ARG_STRING, NULL, OPT_PROFILE, "set the profile name", NULL }, {"password", 'P', POPT_ARG_STRING, NULL, OPT_PASSWORD, "set the profile password", NULL }, {"username", 0, POPT_ARG_STRING, NULL, OPT_USERNAME, "set the username of the mailbox to use", NULL }, {"sendmail", 'S', POPT_ARG_NONE, NULL, OPT_SENDMAIL, "send a mail", NULL }, {"sendappointment", 0, POPT_ARG_NONE, NULL, OPT_SENDAPPOINTMENT, "send an appointment", NULL }, {"sendcontact", 0, POPT_ARG_NONE, NULL, OPT_SENDCONTACT, "send a contact", NULL }, {"sendtask", 0, POPT_ARG_NONE, NULL, OPT_SENDTASK, "send a task", NULL }, {"sendnote", 0, POPT_ARG_NONE, NULL, OPT_SENDNOTE, "send a note", NULL }, {"fetchmail", 'F', POPT_ARG_NONE, NULL, OPT_FETCHMAIL, "fetch user INBOX mails", NULL }, {"fetchsummary", 0, POPT_ARG_NONE, NULL, OPT_FETCHSUMMARY, "fetch message summaries only", NULL }, {"storemail", 'G', POPT_ARG_STRING, NULL, OPT_STOREMAIL, "retrieve a mail on the filesystem", NULL }, {"fetch-items", 'i', POPT_ARG_STRING, NULL, OPT_FETCHITEMS, "fetch specified user INBOX items", NULL }, {"freebusy", 0, POPT_ARG_STRING, NULL, OPT_FREEBUSY, "display free / busy information for the specified user", NULL }, {"force", 0, POPT_ARG_NONE, NULL, OPT_FORCE, "force openchangeclient behavior in some circumstances", NULL }, {"delete", 0, POPT_ARG_STRING, NULL, OPT_DELETEITEMS, "delete a message given its unique ID", NULL }, {"update", 'u', POPT_ARG_STRING, NULL, OPT_UPDATE, "update the specified item", NULL }, {"mailbox", 'm', POPT_ARG_NONE, NULL, OPT_MAILBOX, "list mailbox folder summary", NULL }, {"deletemail", 'D', POPT_ARG_NONE, NULL, OPT_DELETEMAIL, "delete a mail from user INBOX", NULL }, {"attachments", 'A', POPT_ARG_STRING, NULL, OPT_ATTACH, "send a list of attachments", NULL }, {"html-inline", 'I', POPT_ARG_STRING, NULL, OPT_HTML_INLINE, "send PR_HTML content", NULL }, {"html-file", 'W', POPT_ARG_STRING, NULL, OPT_HTML_FILE, "use HTML file as content", NULL }, {"to", 't', POPT_ARG_STRING, NULL, OPT_MAPI_TO, "set the To recipients", NULL }, {"cc", 'c', POPT_ARG_STRING, NULL, OPT_MAPI_CC, "set the Cc recipients", NULL }, {"bcc", 'b', POPT_ARG_STRING, NULL, OPT_MAPI_BCC, "set the Bcc recipients", NULL }, {"subject", 's', POPT_ARG_STRING, NULL, OPT_MAPI_SUBJECT, "set the mail subject", NULL }, {"body", 'B', POPT_ARG_STRING, NULL, OPT_MAPI_BODY, "set the mail body", NULL }, {"location", 0, POPT_ARG_STRING, NULL, OPT_MAPI_LOCATION, "set the item location", NULL }, {"label", 0, POPT_ARG_STRING, NULL, OPT_MAPI_LABEL, "set the event label", NULL }, {"dtstart", 0, POPT_ARG_STRING, NULL, OPT_MAPI_STARTDATE, "set the event start date", NULL }, {"dtend", 0, POPT_ARG_STRING, NULL, OPT_MAPI_ENDDATE, "set the event end date", NULL }, {"busystatus", 0, POPT_ARG_STRING, NULL, OPT_MAPI_BUSYSTATUS, "set the item busy status", NULL }, {"taskstatus", 0, POPT_ARG_STRING, NULL, OPT_MAPI_TASKSTATUS, "set the task status", NULL }, {"importance", 0, POPT_ARG_STRING, NULL, OPT_MAPI_IMPORTANCE, "Set the item importance", NULL }, {"email", 0, POPT_ARG_STRING, NULL, OPT_MAPI_EMAIL, "set the email address", NULL }, {"fullname", 0, POPT_ARG_STRING, NULL, OPT_MAPI_FULLNAME, "set the full name", NULL }, {"cardname", 0, POPT_ARG_STRING, NULL, OPT_MAPI_CARDNAME, "set a contact card name", NULL }, {"color", 0, POPT_ARG_STRING, NULL, OPT_MAPI_COLOR, "set the note color", NULL }, {"notifications", 0, POPT_ARG_NONE, NULL, OPT_NOTIFICATIONS, "monitor INBOX newmail notifications", NULL }, {"folder", 0, POPT_ARG_STRING, NULL, OPT_FOLDER, "set the folder to use instead of inbox", NULL }, {"mkdir", 0, POPT_ARG_NONE, NULL, OPT_MKDIR, "create a folder", NULL }, {"rmdir", 0, POPT_ARG_NONE, NULL, OPT_RMDIR, "delete a folder", NULL }, {"userlist", 0, POPT_ARG_NONE, NULL, OPT_USERLIST, "list Address Book entries", NULL }, {"folder-name", 0, POPT_ARG_STRING, NULL, OPT_FOLDER_NAME, "set the folder name", NULL }, {"folder-comment", 0, POPT_ARG_STRING, NULL, OPT_FOLDER_COMMENT, "set the folder comment", NULL }, {"debuglevel", 'd', POPT_ARG_STRING, NULL, OPT_DEBUG, "set Debug Level", NULL }, {"dump-data", 0, POPT_ARG_NONE, NULL, OPT_DUMPDATA, "dump the hex data", NULL }, {"private", 0, POPT_ARG_NONE, NULL, OPT_MAPI_PRIVATE, "set the private flag on messages", NULL }, {"ocpf-file", 0, POPT_ARG_STRING, NULL, OPT_OCPF_FILE, "set OCPF file", NULL }, {"ocpf-dump", 0, POPT_ARG_STRING, NULL, OPT_OCPF_DUMP, "dump message into OCPF file", NULL }, {"ocpf-syntax", 0, POPT_ARG_NONE, NULL, OPT_OCPF_SYNTAX, "check OCPF files syntax", NULL }, {"ocpf-sender", 0, POPT_ARG_NONE, NULL, OPT_OCPF_SENDER, "send message using OCPF files contents", NULL }, POPT_OPENCHANGE_VERSION {NULL, 0, 0, NULL, 0, NULL, NULL} }; mem_ctx = talloc_named(NULL, 0, "openchangeclient"); init_oclient(&oclient); pc = poptGetContext("openchangeclient", argc, argv, long_options, 0); while ((opt = poptGetNextOpt(pc)) != -1) { switch (opt) { case OPT_PF: oclient.pf = true; break; case OPT_FOLDER: oclient.folder = poptGetOptArg(pc); break; case OPT_DEBUG: opt_debug = poptGetOptArg(pc); break; case OPT_DUMPDATA: opt_dumpdata = true; break; case OPT_USERLIST: opt_userlist = true; break; case OPT_MKDIR: opt_mkdir = true; break; case OPT_RMDIR: opt_rmdir = true; break; case OPT_FOLDER_NAME: oclient.folder_name = poptGetOptArg(pc); break; case OPT_FOLDER_COMMENT: oclient.folder_comment = poptGetOptArg(pc); break; case OPT_NOTIFICATIONS: opt_notifications = true; break; case OPT_PROFILE_DB: opt_profdb = poptGetOptArg(pc); break; case OPT_PROFILE: opt_profname = talloc_strdup(mem_ctx, poptGetOptArg(pc)); break; case OPT_PASSWORD: opt_password = poptGetOptArg(pc); break; case OPT_USERNAME: opt_username = talloc_strdup(mem_ctx, poptGetOptArg(pc)); break; case OPT_MAILBOX: opt_mailbox = true; break; case OPT_FETCHITEMS: opt_fetchitems = poptGetOptArg(pc); break; case OPT_FETCHSUMMARY: oclient.summary = true; break; case OPT_DELETEITEMS: oclient.delete = poptGetOptArg(pc); break; case OPT_FREEBUSY: oclient.freebusy = poptGetOptArg(pc); break; case OPT_UPDATE: oclient.update = poptGetOptArg(pc); break; case OPT_SENDMAIL: opt_sendmail = true; break; case OPT_SENDAPPOINTMENT: opt_sendappointment = true; break; case OPT_SENDCONTACT: opt_sendcontact = true; break; case OPT_SENDTASK: opt_sendtask = true; break; case OPT_SENDNOTE: opt_sendnote = true; break; case OPT_FETCHMAIL: opt_fetchmail = true; break; case OPT_STOREMAIL: oclient.store_folder = poptGetOptArg(pc); break; case OPT_DELETEMAIL: opt_deletemail = true; break; case OPT_ATTACH: opt_attachments = poptGetOptArg(pc); break; case OPT_HTML_INLINE: oclient.pr_html_inline = poptGetOptArg(pc); break; case OPT_HTML_FILE: opt_html_file = poptGetOptArg(pc); break; case OPT_MAPI_TO: opt_mapi_to = poptGetOptArg(pc); break; case OPT_MAPI_CC: opt_mapi_cc = poptGetOptArg(pc); break; case OPT_MAPI_BCC: opt_mapi_bcc = poptGetOptArg(pc); break; case OPT_MAPI_SUBJECT: oclient.subject = poptGetOptArg(pc); break; case OPT_MAPI_BODY: oclient.pr_body = poptGetOptArg(pc); break; case OPT_MAPI_LOCATION: oclient.location = poptGetOptArg(pc); break; case OPT_MAPI_STARTDATE: oclient.dtstart = poptGetOptArg(pc); break; case OPT_MAPI_ENDDATE: oclient.dtend = poptGetOptArg(pc); break; case OPT_MAPI_BUSYSTATUS: oclient.busystatus = oc_get_argument(poptGetOptArg(pc), oc_busystatus, "busystatus"); break; case OPT_MAPI_LABEL: oclient.label = oc_get_argument(poptGetOptArg(pc), oc_label, "label"); break; case OPT_MAPI_IMPORTANCE: oclient.importance = oc_get_argument(poptGetOptArg(pc), oc_importance, "importance"); break; case OPT_MAPI_TASKSTATUS: oclient.taskstatus = oc_get_argument(poptGetOptArg(pc), oc_taskstatus, "taskstatus"); break; case OPT_MAPI_COLOR: oclient.color = oc_get_argument(poptGetOptArg(pc), oc_color, "color"); break; case OPT_MAPI_EMAIL: oclient.email = poptGetOptArg(pc); break; case OPT_MAPI_FULLNAME: oclient.full_name = poptGetOptArg(pc); break; case OPT_MAPI_CARDNAME: oclient.card_name = poptGetOptArg(pc); break; case OPT_MAPI_PRIVATE: oclient.private = true; break; case OPT_OCPF_FILE: { struct ocpf_file *element; if (!oclient.ocpf_files) { oclient.ocpf_files = talloc_zero(mem_ctx, struct ocpf_file); } element = talloc_zero(mem_ctx, struct ocpf_file); element->filename = talloc_strdup(mem_ctx, poptGetOptArg(pc)); DLIST_ADD(oclient.ocpf_files, element); break; } case OPT_OCPF_SYNTAX: opt_ocpf_syntax = true; break; case OPT_OCPF_SENDER: opt_ocpf_sender = true; break; case OPT_OCPF_DUMP: oclient.ocpf_dump = poptGetOptArg(pc); break; case OPT_FORCE: oclient.force = true; break; } } /* Sanity check on options */ if (!opt_profdb) { opt_profdb = talloc_asprintf(mem_ctx, DEFAULT_PROFDB, getenv("HOME")); } if (opt_sendmail && !opt_mapi_to && !opt_mapi_cc && !opt_mapi_bcc) { printf("You need to specify at least one recipient\n"); exit (1); } if (opt_sendmail && (!oclient.pr_body && !oclient.pr_html_inline && !opt_html_file)) { printf("No body specified (body, html-inline or html-file)\n"); exit (1); } if ((opt_sendmail && oclient.pf == true && !oclient.folder) || (oclient.pf == true && !oclient.folder && !opt_mailbox && !oclient.freebusy)) { printf("--folder option is mandatory\n"); exit (1); } if (opt_html_file && oclient.pr_body) { printf("PR_BODY and PR_HTML can't be set at the same time\n"); exit (1); } if (oclient.pr_body && oclient.pr_html_inline) { printf("Inline HTML and PR_BODY content can't be set simulteanously\n"); exit (1); } if (opt_html_file && oclient.pr_html_inline) { printf("PR_HTML from file and stdin can't be specified at the same time\n"); exit (1); } if (opt_html_file) { oclient_read_file(mem_ctx, opt_html_file, &oclient, PR_HTML); } if (opt_attachments) { if (oclient_parse_attachments(mem_ctx, opt_attachments, &oclient) == false) { printf("Unable to parse one of the specified attachments\n"); exit (1); } } if (opt_mkdir && !oclient.folder_name) { printf("mkdir requires --folder-name to be defined\n"); exit (1); } /* One of the rare options which doesn't require MAPI to get * initialized */ if (opt_ocpf_syntax) { bool ret = openchangeclient_ocpf_syntax(&oclient); mapi_errstr("OCPF Syntax", GetLastError()); if (ret != true) { exit(1); } exit (0); } /** * Initialize MAPI subsystem */ retval = MAPIInitialize(&oclient.mapi_ctx, opt_profdb); if (retval != MAPI_E_SUCCESS) { mapi_errstr("MAPIInitialize", GetLastError()); exit (1); } /* debug options */ SetMAPIDumpData(oclient.mapi_ctx, opt_dumpdata); if (opt_debug) { SetMAPIDebugLevel(oclient.mapi_ctx, atoi(opt_debug)); } /* If no profile is specified try to load the default one from * the database */ if (!opt_profname) { retval = GetDefaultProfile(oclient.mapi_ctx, &opt_profname); if (retval != MAPI_E_SUCCESS) { mapi_errstr("GetDefaultProfile", GetLastError()); exit (1); } } retval = MapiLogonEx(oclient.mapi_ctx, &session, opt_profname, opt_password); talloc_free(opt_profname); if (retval != MAPI_E_SUCCESS) { mapi_errstr("MapiLogonEx", GetLastError()); exit (1); } if (opt_userlist) { if (false == openchangeclient_userlist(mem_ctx, session)) { exit(1); } else { exit(0); } } /** * Open Default Message Store */ mapi_object_init(&obj_store); if (oclient.pf == true) { retval = OpenPublicFolder(session, &obj_store); if (retval != MAPI_E_SUCCESS) { mapi_errstr("OpenPublicFolder", GetLastError()); exit (1); } } else if (opt_username) { retval = OpenUserMailbox(session, opt_username, &obj_store); if (retval != MAPI_E_SUCCESS) { mapi_errstr("OpenUserMailbox", GetLastError()); exit (1); } } else { retval = OpenMsgStore(session, &obj_store); if (retval != MAPI_E_SUCCESS) { mapi_errstr("OpenMsgStore", GetLastError()); exit (1); } } /** * OCPF sending command */ if (opt_ocpf_sender) { bool ret = openchangeclient_ocpf_sender(mem_ctx, &obj_store, &oclient); mapi_errstr("OCPF Sender", GetLastError()); if (ret != true) { goto end; } } if (oclient.ocpf_dump) { bool ret = openchangeclient_ocpf_dump(mem_ctx, &obj_store, &oclient); mapi_errstr("OCPF Dump", GetLastError()); if (ret != true) { goto end; } } if (opt_fetchitems) { bool ret = openchangeclient_fetchitems(mem_ctx, &obj_store, opt_fetchitems, &oclient); mapi_errstr("fetchitems", GetLastError()); if (ret != true) { goto end; } } if (oclient.delete) { bool ret = openchangeclient_deleteitems(mem_ctx, &obj_store, &oclient); mapi_errstr("deleteitems", GetLastError()); if (ret != true) { goto end; } } if (opt_mailbox) { if (oclient.pf == true) { bool ret = openchangeclient_pf(mem_ctx, &obj_store); mapi_errstr("public folder", GetLastError()); if (ret != true) { goto end; } } else { bool ret = openchangeclient_mailbox(mem_ctx, &obj_store); mapi_errstr("mailbox", GetLastError()); if (ret != true) { goto end; } } } /* MAPI email operations */ if (opt_sendmail) { /* recipients management */ oclient.mapi_to = get_cmdline_recipients(mem_ctx, opt_mapi_to); oclient.mapi_cc = get_cmdline_recipients(mem_ctx, opt_mapi_cc); oclient.mapi_bcc = get_cmdline_recipients(mem_ctx, opt_mapi_bcc); retval = openchangeclient_sendmail(mem_ctx, &obj_store, &oclient); mapi_errstr("sendmail", GetLastError()); if (retval != true) { goto end; } } if (opt_fetchmail) { retval = openchangeclient_fetchmail(&obj_store, &oclient); mapi_errstr("fetchmail", GetLastError()); if (retval != true) { goto end; } } if (opt_deletemail) { bool ret = openchangeclient_deletemail(mem_ctx, &obj_store, &oclient); mapi_errstr("deletemail", GetLastError()); if (ret != true) { goto end; } } /* MAPI calendar operations */ if (opt_sendappointment) { bool ret; if (!oclient.dtstart && !oclient.update) { printf("You need to specify a start date (e.g: 2007-06-01 22:30:00)\n"); goto end; } if (!oclient.dtend && !oclient.update) { printf("Setting default end date\n"); oclient.dtend = oclient.dtstart; } if (!oclient.update) { ret = openchangeclient_sendappointment(mem_ctx, &obj_store, &oclient); mapi_errstr("sendappointment", GetLastError()); } else { ret = openchangeclient_updateitem(mem_ctx, &obj_store, &oclient, IPF_APPOINTMENT); mapi_errstr("update appointment", GetLastError()); } if (ret != true) { goto end; } } if (oclient.freebusy) { bool ret = openchangeclient_freebusy(&obj_store, &oclient); mapi_errstr("freebusy", GetLastError()); if (ret != true) { goto end; } } /* MAPI contact operations */ if (opt_sendcontact) { bool ret; if (!oclient.update) { ret = openchangeclient_sendcontact(mem_ctx, &obj_store, &oclient); mapi_errstr("sendcontact", GetLastError()); } else { ret = openchangeclient_updateitem(mem_ctx, &obj_store, &oclient, IPF_CONTACT); mapi_errstr("update contact", GetLastError()); } if (ret != true) { goto end; } } /* MAPI task operations */ if (opt_sendtask) { bool ret; if (!oclient.dtstart && !oclient.update) { printf("You need to specify a start date (e.g: 2007-06-01 22:30:00)\n"); goto end; } if (!oclient.dtend && !oclient.update) { printf("Setting default end date\n"); oclient.dtend = oclient.dtstart; } if (!oclient.update) { ret = openchangeclient_sendtask(mem_ctx, &obj_store, &oclient); mapi_errstr("sendtask", GetLastError()); } else { ret = openchangeclient_updateitem(mem_ctx, &obj_store, &oclient, IPF_TASK); mapi_errstr("update task", GetLastError()); } if (ret != true) { goto end; } } /* MAPI note operations */ if (opt_sendnote) { bool ret; if (!oclient.update) { ret = openchangeclient_sendnote(mem_ctx, &obj_store, &oclient); mapi_errstr("sendnote", GetLastError()); } else { ret = openchangeclient_updateitem(mem_ctx, &obj_store, &oclient, IPF_STICKYNOTE); mapi_errstr("update note", GetLastError()); } if (ret != true) { goto end; } } /* Monitor newmail notifications */ if (opt_notifications) { openchangeclient_notifications(mem_ctx, &obj_store, &oclient); mapi_errstr("notifications", GetLastError()); if (retval != true) { goto end; } } /* Folder operations */ if (opt_mkdir) { openchangeclient_mkdir(mem_ctx, &obj_store, &oclient); mapi_errstr("mkdir", GetLastError()); if (retval != true) { goto end; } } if (opt_rmdir) { openchangeclient_rmdir(mem_ctx, &obj_store, &oclient); mapi_errstr("rmdir", GetLastError()); if (retval != true) { goto end; } } /* Uninitialize MAPI subsystem */ end: poptFreeContext(pc); mapi_object_release(&obj_store); MAPIUninitialize(oclient.mapi_ctx); talloc_free(mem_ctx); return 0; } openchange-2.0/utils/openchangeclient.h000066400000000000000000000066071223057412600203140ustar00rootroot00000000000000/* Stand-alone MAPI application OpenChange Project Copyright (C) Julien Kerihuel 2007 This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see . */ #ifndef __OPENCHANGECLIENT_H__ #define __OPENCHANGECLIENT_H__ struct oc_property { struct oc_property *prev; struct oc_property *next; uint32_t ulPropTag; const void *data; bool named; }; struct ocpf_file { struct ocpf_file *prev; struct ocpf_file *next; const char *filename; }; struct attach { const char *filename; struct Binary_r bin; int fd; }; struct oclient { struct mapi_context *mapi_ctx; struct oc_property *props; const char *update; const char *delete; const char *subject; const char *pr_body; const char *pr_html_inline; char **usernames; char **mapi_to; char **mapi_cc; char **mapi_bcc; struct Binary_r pr_html; struct attach *attach; uint32_t attach_num; const char *store_folder; const char *location; const char *dtstart; const char *dtend; int busystatus; int taskstatus; int label; bool private; int importance; int color; int width; int height; const char *email; const char *full_name; const char *card_name; const char *folder_name; const char *folder_comment; const char *freebusy; bool force; bool summary; /* PF related options */ bool pf; const char *folder; /* OCPF related options */ struct ocpf_file *ocpf_files; const char *ocpf_dump; }; struct itemfolder { const uint32_t olFolder; const char *container_class; }; struct itemfolder defaultFolders[] = { {olFolderInbox, "Mail"}, {olFolderCalendar, "Appointment"}, {olFolderContacts, "Contact"}, {olFolderTasks, "Task"}, {olFolderNotes, "Note"}, {0 , NULL} }; struct oc_element { uint8_t index; const char *status; }; struct oc_element oc_busystatus[] = { {BUSY_STATUS_FREE, "FREE"}, {BUSY_STATUS_TENTATIVE, "TENTATIVE"}, {BUSY_STATUS_BUSY, "BUSY"}, {BUSY_STATUS_OUTOFOFFICE, "OUTOFOFFICE"}, {0 , NULL} }; struct oc_element oc_importance[] = { {IMPORTANCE_LOW, "LOW"}, {IMPORTANCE_NORMAL, "NORMAL"}, {IMPORTANCE_HIGH, "HIGH"}, {0, NULL} }; struct oc_element oc_taskstatus[] = { {olTaskNotStarted, "NOTSTARTED"}, {olTaskInProgress, "PROGRESS"}, {olTaskComplete, "COMPLETED"}, {olTaskWaiting, "WAITING"}, {olTaskDeferred, "DEFERRED"}, {0, NULL} }; struct oc_element oc_label[] = { {0, "NONE"}, {1, "IMPORTANT"}, {2, "BUSINESS"}, {3, "PERSONAL"}, {4, "VACATION"}, {5, "MUST_ATTEND"}, {6, "TRAVEL_REQUIRED"}, {7, "NEEDS_PREPARATION"}, {8, "BIRTHDAY"}, {9, "ANNIVERSARY"}, {10, "PHONE_CALL"}, {0, NULL} }; struct oc_element oc_color[] = { {olBlue, "Blue"}, {olGreen, "Green"}, {olPink, "Pink"}, {olYellow, "Yellow"}, {olWhite, "White"}, {0, NULL} }; #define DATE_FORMAT "%Y-%m-%d %H:%M:%S" #endif /* !__OPENCHANGECLIENT_H__ */ openchange-2.0/utils/openchangepfadmin.c000066400000000000000000000410351223057412600204410ustar00rootroot00000000000000/* Public Folders Administration Tool OpenChange Project Copyright (C) Julien Kerihuel 2007 This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see . */ #include "libmapi/libmapi.h" #include "libmapiadmin/libmapiadmin.h" #include #include #include "openchangepfadmin.h" #include "openchange-tools.h" static int32_t get_aclrights(const char *permission) { uint32_t i; if (!permission) return -1; for (i = 0; aclrights[i].name != NULL; i++) { if (!strcmp(permission, aclrights[i].name)) { return aclrights[i].value; } } return -1; } static void list_aclrights(void) { uint32_t i; printf("Valid permissions:\n"); for (i = 0; aclrights[i].name != NULL; i++) { printf("\t%s\n", aclrights[i].name); } } static int32_t check_IPF_class(const char *dirclass) { uint32_t i; if (!dirclass) return -1; for (i = 0; IPF_class[i]; i++) { if (!strcmp(dirclass, IPF_class[i])) { return 0; } } return -1; } static void list_IPF_class(void) { uint32_t i; printf("Valid IPF Classes:\n"); for (i = 0; IPF_class[i] != NULL; i++) { printf("\t%s\n", IPF_class[i]); } } static bool get_child_folders_pf(TALLOC_CTX *mem_ctx, mapi_object_t *parent, mapi_id_t folder_id, int count) { enum MAPISTATUS retval; bool ret; mapi_object_t obj_folder; mapi_object_t obj_htable; struct SPropTagArray *SPropTagArray; struct SRowSet rowset; const char *name; const uint32_t *child; uint32_t index; const uint64_t *fid; int i; mapi_object_init(&obj_folder); retval = OpenFolder(parent, folder_id, &obj_folder); if (retval != MAPI_E_SUCCESS) return false; mapi_object_init(&obj_htable); retval = GetHierarchyTable(&obj_folder, &obj_htable, 0, NULL); if (retval != MAPI_E_SUCCESS) return false; SPropTagArray = set_SPropTagArray(mem_ctx, 0x3, PR_DISPLAY_NAME_UNICODE, PR_FID, PR_FOLDER_CHILD_COUNT); retval = SetColumns(&obj_htable, SPropTagArray); MAPIFreeBuffer(SPropTagArray); if (retval != MAPI_E_SUCCESS) return false; while (((retval = QueryRows(&obj_htable, 0x32, TBL_ADVANCE, &rowset)) != MAPI_E_NOT_FOUND) && rowset.cRows) { for (index = 0; index < rowset.cRows; index++) { fid = (const uint64_t *)find_SPropValue_data(&rowset.aRow[index], PR_FID); name = (const char *)find_SPropValue_data(&rowset.aRow[index], PR_DISPLAY_NAME_UNICODE); child = (const uint32_t *)find_SPropValue_data(&rowset.aRow[index], PR_FOLDER_CHILD_COUNT); for (i = 0; i < count; i++) { printf("| "); } printf("|---+ %-15s\n", name); if (*child) { ret = get_child_folders_pf(mem_ctx, &obj_folder, *fid, count + 1); if (ret == false) return ret; } } } return true; } static enum MAPISTATUS openchangepfadmin_getdir(TALLOC_CTX *mem_ctx, mapi_object_t *obj_container, mapi_object_t *obj_child, const char *folder) { enum MAPISTATUS retval; struct SPropTagArray *SPropTagArray; struct SRowSet rowset; mapi_object_t obj_htable; const char *name; const uint64_t *fid; uint32_t index; mapi_object_init(&obj_htable); retval = GetHierarchyTable(obj_container, &obj_htable, 0, NULL); MAPI_RETVAL_IF(retval, GetLastError(), NULL); SPropTagArray = set_SPropTagArray(mem_ctx, 0x2, PR_DISPLAY_NAME_UNICODE, PR_FID); retval = SetColumns(&obj_htable, SPropTagArray); MAPIFreeBuffer(SPropTagArray); if (retval != MAPI_E_SUCCESS) return MAPI_E_NOT_FOUND; while (((retval = QueryRows(&obj_htable, 0x32, TBL_ADVANCE, &rowset)) != MAPI_E_NOT_FOUND) && rowset.cRows) { for (index = 0; index < rowset.cRows; index++) { fid = (const uint64_t *)find_SPropValue_data(&rowset.aRow[index], PR_FID); name = (const char *)find_SPropValue_data(&rowset.aRow[index], PR_DISPLAY_NAME_UNICODE); if (name && fid && !strcmp(name, folder)) { retval = OpenFolder(obj_container, *fid, obj_child); MAPI_RETVAL_IF(retval, GetLastError(), NULL); return MAPI_E_SUCCESS; } } } errno = MAPI_E_NOT_FOUND; return MAPI_E_NOT_FOUND; } static enum MAPISTATUS openchangepfadmin_mkdir(mapi_object_t *obj_container, const char *name, const char *comment, const char *type) { enum MAPISTATUS retval; mapi_object_t obj_folder; struct SPropValue props[1]; uint32_t prop_count = 0; mapi_object_init(&obj_folder); retval = CreateFolder(obj_container, FOLDER_GENERIC, name, comment, OPEN_IF_EXISTS, &obj_folder); MAPI_RETVAL_IF(retval, GetLastError(), NULL); if (type) { set_SPropValue_proptag(&props[0], PR_CONTAINER_CLASS, (const void *) type); prop_count++; retval = SetProps(&obj_folder, 0, props, prop_count); mapi_object_release(&obj_folder); MAPI_RETVAL_IF(retval, GetLastError(), NULL); } return MAPI_E_SUCCESS; } static enum MAPISTATUS openchangepfadmin_rmdir(TALLOC_CTX *mem_ctx, mapi_object_t *obj_container, const char *name) { enum MAPISTATUS retval; mapi_object_t obj_folder; mapi_object_init(&obj_folder); retval = openchangepfadmin_getdir(mem_ctx, obj_container, &obj_folder, name); MAPI_RETVAL_IF(retval, GetLastError(), NULL); retval = EmptyFolder(&obj_folder); MAPI_RETVAL_IF(retval, GetLastError(), NULL); retval = DeleteFolder(obj_container, mapi_object_get_id(&obj_folder), DEL_FOLDERS, NULL); MAPI_RETVAL_IF(retval, GetLastError(), NULL); mapi_object_release(&obj_folder); return MAPI_E_SUCCESS; } int main(int argc, const char *argv[]) { TALLOC_CTX *mem_ctx; enum MAPISTATUS retval; struct mapi_context *mapi_ctx; struct mapi_session *session = NULL; mapi_object_t obj_store; mapi_object_t obj_ipm_subtree; mapi_object_t obj_folder; mapi_id_t id_pf; poptContext pc; int opt; const char *opt_profdb = NULL; char *opt_profname = NULL; const char *opt_password = NULL; const char *opt_comment = NULL; const char *opt_dirclass = NULL; const char *opt_adduser = NULL; const char *opt_rmuser = NULL; const char *opt_apassword = NULL; const char *opt_adesc = NULL; const char *opt_acomment = NULL; const char *opt_afullname = NULL; const char *opt_addright = NULL; bool opt_rmright = false; const char *opt_modright = NULL; const char *opt_folder = NULL; const char *opt_debug = NULL; const char *opt_username = NULL; int32_t opt_permission = -1; bool opt_ipm_list = false; bool opt_mkdir = false; bool opt_rmdir = false; bool opt_dumpdata = false; enum {OPT_PROFILE_DB=1000, OPT_PROFILE, OPT_PASSWORD, OPT_IPM_LIST, OPT_MKDIR, OPT_RMDIR, OPT_COMMENT, OPT_DIRCLASS, OPT_ACL, OPT_ADDUSER, OPT_RMUSER, OPT_DEBUG, OPT_APASSWORD, OPT_ADESC, OPT_ACOMMENT, OPT_AFULLNAME, OPT_ADDRIGHT, OPT_RMRIGHT, OPT_MODRIGHT, OPT_USERNAME, OPT_FOLDER, OPT_DUMPDATA}; struct poptOption long_options[] = { POPT_AUTOHELP {"database", 'f', POPT_ARG_STRING, NULL, OPT_PROFILE_DB, "set the profile database path", "PATH"}, {"profile", 'p', POPT_ARG_STRING, NULL, OPT_PROFILE, "set the profile name", "PROFILE"}, {"password", 'P', POPT_ARG_STRING, NULL, OPT_PASSWORD, "set the profile password", "PASSWORD"}, {"apassword", 0, POPT_ARG_STRING, NULL, OPT_APASSWORD, "set the account password", "PASSWORD"}, {"adesc", 0, POPT_ARG_STRING, NULL, OPT_ADESC, "set the account description", "DESCRIPTION"}, {"acomment", 0, POPT_ARG_STRING, NULL, OPT_ACOMMENT, "set the account comment", "COMMENT"}, {"afullname", 0, POPT_ARG_STRING, NULL, OPT_AFULLNAME, "set the account full name", "NAME"}, {"list",0, POPT_ARG_NONE, NULL, OPT_IPM_LIST, "list IPM subtree directories", NULL}, {"mkdir", 0, POPT_ARG_NONE, NULL, OPT_MKDIR, "create a Public Folder directory", NULL}, {"rmdir", 0, POPT_ARG_NONE, NULL, OPT_RMDIR, "delete a Public Folder directory", NULL}, {"comment", 0, POPT_ARG_STRING, NULL, OPT_COMMENT, "set the folder comment", "COMMENT"}, {"dirclass", 0, POPT_ARG_STRING, NULL, OPT_DIRCLASS, "set the folder class", "CLASS"}, {"adduser", 0, POPT_ARG_STRING, NULL, OPT_ADDUSER, "add Exchange user", "USERNAME"}, {"rmuser", 0, POPT_ARG_STRING, NULL, OPT_RMUSER, "delete Exchange user", "USERNAME"}, {"addright", 0, POPT_ARG_STRING, NULL, OPT_ADDRIGHT, "add MAPI permissions to PF folder", "RIGHT"}, {"rmright", 0, POPT_ARG_NONE, NULL, OPT_RMRIGHT, "remove MAPI permissions to PF folder", NULL}, {"modright", 0, POPT_ARG_STRING, NULL, OPT_MODRIGHT, "modify MAPI permissions to PF folder", "RIGHT"}, {"debuglevel", 0, POPT_ARG_STRING, NULL, OPT_DEBUG, "set debug level", "LEVEL"}, {"dump-data", 0, POPT_ARG_NONE, NULL, OPT_DUMPDATA, "Dump the hex data", NULL}, {"folder", 0, POPT_ARG_STRING, NULL, OPT_FOLDER, "specify the Public Folder directory", "FOLDER"}, {"username", 0, POPT_ARG_STRING, NULL, OPT_USERNAME, "specify the username to use", "USERNAME"}, POPT_OPENCHANGE_VERSION { NULL, 0, POPT_ARG_NONE, NULL, 0, NULL, NULL } }; mem_ctx = talloc_named(NULL, 0, "openchangepfadmin"); pc = poptGetContext("openchangepfadmin", argc, argv, long_options, 0); while ((opt = poptGetNextOpt(pc)) != -1) { switch (opt) { case OPT_DEBUG: opt_debug = poptGetOptArg(pc); break; case OPT_DUMPDATA: opt_dumpdata = true; break; case OPT_PROFILE_DB: opt_profdb = poptGetOptArg(pc); break; case OPT_PROFILE: opt_profname = talloc_strdup(mem_ctx, poptGetOptArg(pc)); break; case OPT_PASSWORD: opt_password = poptGetOptArg(pc); break; case OPT_IPM_LIST: opt_ipm_list = true; break; case OPT_MKDIR: opt_mkdir = true; break; case OPT_RMDIR: opt_rmdir = true; break; case OPT_COMMENT: opt_comment = poptGetOptArg(pc); break; case OPT_DIRCLASS: opt_dirclass = poptGetOptArg(pc); break; case OPT_ADDUSER: opt_adduser = poptGetOptArg(pc); break; case OPT_RMUSER: opt_rmuser = poptGetOptArg(pc); break; case OPT_APASSWORD: opt_apassword = poptGetOptArg(pc); break; case OPT_ADESC: opt_adesc = poptGetOptArg(pc); break; case OPT_ACOMMENT: opt_acomment = poptGetOptArg(pc); break; case OPT_AFULLNAME: opt_afullname = poptGetOptArg(pc); break; case OPT_ADDRIGHT: opt_addright = poptGetOptArg(pc); break; case OPT_RMRIGHT: opt_rmright = true; break; case OPT_MODRIGHT: opt_modright = poptGetOptArg(pc); break; case OPT_FOLDER: opt_folder = poptGetOptArg(pc); break; case OPT_USERNAME: opt_username = poptGetOptArg(pc); break; default: break; }; } /* Sanity check on options */ if ((opt_mkdir == true && !opt_folder) || (opt_rmdir == true && !opt_folder) || (opt_addright && !opt_folder) || (opt_rmright == true && !opt_folder) || (opt_modright && !opt_folder)) { printf("You need to specify a directory with --folder option\n"); return (-1); } if ((opt_addright && !opt_username) || (opt_rmright == true && !opt_username) || (opt_modright && !opt_username)) { printf("You need to specify a username with --username option\n"); return (-1); } /* dirclass sanity check */ if (opt_dirclass) { if (check_IPF_class(opt_dirclass) == -1) { list_IPF_class(); return (-1); } } if (!opt_profdb) { opt_profdb = talloc_asprintf(mem_ctx, DEFAULT_PROFDB, getenv("HOME")); } /** * Initialize MAPI subsystem */ retval = MAPIInitialize(&mapi_ctx, opt_profdb); if (retval != MAPI_E_SUCCESS) { mapi_errstr("MAPIInitialize", GetLastError()); exit (1); } /* debug options */ SetMAPIDumpData(mapi_ctx, opt_dumpdata); if (opt_debug) { SetMAPIDebugLevel(mapi_ctx, atoi(opt_debug)); } /** * If no profile is specified, try to load the default one * from the database */ if (!opt_profname) { retval = GetDefaultProfile(mapi_ctx, &opt_profname); if (retval != MAPI_E_SUCCESS) { mapi_errstr("GetDefaultProfile", GetLastError()); exit (1); } } retval = MapiLogonEx(mapi_ctx, &session, opt_profname, opt_password); talloc_free(opt_profname); if (retval != MAPI_E_SUCCESS) { mapi_errstr("MapiLogonEx", GetLastError()); exit (1); } /** * User management operations */ if (opt_adduser) { struct mapiadmin_ctx *mapiadmin_ctx; mapiadmin_ctx = mapiadmin_init(session); mapiadmin_ctx->username = opt_adduser; mapiadmin_ctx->password = opt_apassword; mapiadmin_ctx->description = opt_adesc; mapiadmin_ctx->comment = opt_acomment; mapiadmin_ctx->fullname = opt_afullname; retval = mapiadmin_user_add(mapiadmin_ctx); mapi_errstr("mapiadmin_user_add", GetLastError()); if (retval != MAPI_E_SUCCESS) { exit (1); } printf("username: %s\n", mapiadmin_ctx->username); printf("password: %s\n", mapiadmin_ctx->password); } if (opt_rmuser) { struct mapiadmin_ctx *mapiadmin_ctx; mapiadmin_ctx = mapiadmin_init(session); mapiadmin_ctx->username = opt_rmuser; retval = mapiadmin_user_del(mapiadmin_ctx); mapi_errstr("mapiadmin_user_del", GetLastError()); } /** * Open Public Folder Store */ mapi_object_init(&obj_store); retval = OpenPublicFolder(session, &obj_store); if (retval != MAPI_E_SUCCESS) { mapi_errstr("OpenPublicFolder", GetLastError()); goto end; } /* Open IPM Subtree (All Public Folders) */ retval = GetDefaultPublicFolder(&obj_store, &id_pf, olFolderPublicIPMSubtree); if (retval != MAPI_E_SUCCESS) { goto end; } mapi_object_init(&obj_ipm_subtree); retval = OpenFolder(&obj_store, id_pf, &obj_ipm_subtree); if (retval != MAPI_E_SUCCESS) { mapi_errstr("OpenFolder", GetLastError()); goto end; } /* create directory */ if (opt_mkdir == true) { retval = openchangepfadmin_mkdir(&obj_ipm_subtree, opt_folder, opt_comment, opt_dirclass); if (retval != MAPI_E_SUCCESS) { mapi_errstr("mkdir", GetLastError()); goto end; } } /* remove directory */ if (opt_rmdir == true) { retval = openchangepfadmin_rmdir(mem_ctx, &obj_ipm_subtree, opt_folder); if (retval != MAPI_E_SUCCESS) { mapi_errstr("rmdir", GetLastError()); goto end; } } /* add permissions */ if (opt_addright) { if ((opt_permission = get_aclrights(opt_addright)) == -1) { printf("Invalid permission\n"); list_aclrights(); goto end; } else { mapi_object_init(&obj_folder); retval = openchangepfadmin_getdir(mem_ctx, &obj_ipm_subtree, &obj_folder, opt_folder); if (retval != MAPI_E_SUCCESS) { printf("Invalid directory\n"); goto end; } retval = AddUserPermission(&obj_folder, opt_username, opt_permission); if (retval != MAPI_E_SUCCESS) { mapi_errstr("AddUserPermission", GetLastError()); mapi_object_release(&obj_folder); goto end; } mapi_object_release(&obj_folder); } printf("Permission %s added for %s on folder %s\n", opt_addright, opt_username, opt_folder); } /* remove permissions */ if (opt_rmright == true) { mapi_object_init(&obj_folder); retval = openchangepfadmin_getdir(mem_ctx, &obj_ipm_subtree, &obj_folder, opt_folder); if (retval != MAPI_E_SUCCESS) { printf("Invalid directory\n"); goto end; } retval = RemoveUserPermission(&obj_folder, opt_username); if (retval != MAPI_E_SUCCESS) { mapi_errstr("RemoveUserPermission", GetLastError()); mapi_object_release(&obj_folder); goto end; } mapi_object_release(&obj_folder); printf("Permission removed for %s on folder %s\n", opt_username, opt_folder); } /* modify permissions */ if (opt_modright) { opt_permission = get_aclrights(opt_modright); if (opt_permission == -1) { printf("Invalid permission\n"); list_aclrights(); goto end; } else { mapi_object_init(&obj_folder); retval = openchangepfadmin_getdir(mem_ctx, &obj_ipm_subtree, &obj_folder, opt_folder); if (retval != MAPI_E_SUCCESS) { printf("Invalid directory\n"); goto end; } retval = ModifyUserPermission(&obj_folder, opt_username, opt_permission); if (retval != MAPI_E_SUCCESS) { mapi_errstr("ModifyUserPermission", GetLastError()); mapi_object_release(&obj_folder); goto end; } mapi_object_release(&obj_folder); } printf("Permission changed to %s for %s on folder %s\n", opt_modright, opt_username, opt_folder); } /* list directories */ if (opt_ipm_list == true) { printf("+ All Public Folders\n"); get_child_folders_pf(mem_ctx, &obj_ipm_subtree, id_pf, 0); } /** * Uninitialize MAPI subsystem */ end: mapi_object_release(&obj_store); MAPIUninitialize(mapi_ctx); talloc_free(mem_ctx); return 0; } openchange-2.0/utils/openchangepfadmin.h000066400000000000000000000037621223057412600204530ustar00rootroot00000000000000/* Public Folders Administration Tool OpenChange Project Copyright (C) Julien Kerihuel 2007 This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see . */ #ifndef __OPENCHANGEPFADMIN_H__ #define __OPENCHANGEPFADMIN_H__ #define DEFAULT_PROFDB "%s/.openchange/profiles.ldb" struct aclrights { const char *name; uint32_t value; }; const struct aclrights aclrights[] = { {"RightsNone", 0x00000000}, {"RightsReadItems", 0x00000001}, {"RightsCreateItems", 0x00000002}, {"RightsEditOwn", 0x00000008}, {"RightsDeleteOwn", 0x00000010}, {"RightsEditAll", 0x00000020}, {"RightsDeleteAll", 0x00000040}, {"RightsCreateSubfolders", 0x00000080}, {"RightsFolderOwner", 0x00000100}, {"RightsFolderContact", 0x00000200}, {"RoleNone", 0x00000400}, {"RoleReviewer", 0x00000401}, {"RoleContributor", 0x00000402}, {"RoleNoneditingAuthor", 0x00000413}, {"RoleAuthor", 0x0000041B}, {"RoleEditor", 0x0000047B}, {"RolePublishAuthor", 0x0000049B}, {"RolePublishEditor", 0x000004FB}, {"RightsAll", 0x000005FB}, {"RoleOwner", 0x000007FB}, {NULL, 0} }; const char * IPF_class[] = { IPF_APPOINTMENT, IPF_CONTACT, IPF_JOURNAL, IPF_NOTE, IPF_STICKYNOTE, IPF_TASK, IPF_POST, NULL}; #endif /* __OPENCHANGEPFADMIN_H__ */ openchange-2.0/utils/schemaIDGUID.c000066400000000000000000000024401223057412600171160ustar00rootroot00000000000000/* MAPI Implementation OpenChange Project Copyright (C) Julien Kerihuel 2006 This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see . */ #include "libmapi/libmapi.h" #include static void usage(void) { printf("schemaIDGUID \n"); exit(0); } int main(int argc, char *argv[]) { TALLOC_CTX *mem_ctx; DATA_BLOB blob; struct GUID *guid; char *schemaIDGUID; if (argc != 2) { usage(); } mem_ctx = talloc_named(NULL, 0, "SchemaIDGUID"); blob = data_blob_talloc(mem_ctx, argv[1], strlen(argv[1])+1); blob.length = ldb_base64_decode((char *)blob.data); guid = (struct GUID *) blob.data; schemaIDGUID = GUID_string(mem_ctx, guid); printf("%s\n", schemaIDGUID); return (0); }